diff --git a/PROMS/DotNetBar Source Code/AdvPropertyGrid.ico b/PROMS/DotNetBar Source Code/AdvPropertyGrid.ico new file mode 100644 index 00000000..3c3bd614 Binary files /dev/null and b/PROMS/DotNetBar Source Code/AdvPropertyGrid.ico differ diff --git a/PROMS/DotNetBar Source Code/AdvTree.ico b/PROMS/DotNetBar Source Code/AdvTree.ico new file mode 100644 index 00000000..32a570b6 Binary files /dev/null and b/PROMS/DotNetBar Source Code/AdvTree.ico differ diff --git a/PROMS/DotNetBar Source Code/AdvTree/AdvTree.cs b/PROMS/DotNetBar Source Code/AdvTree/AdvTree.cs new file mode 100644 index 00000000..1433f472 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/AdvTree.cs @@ -0,0 +1,9872 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.AdvTree.Display; +using DevComponents.AdvTree.Layout; +using System.Xml; +using System.IO; +using DevComponents.DotNetBar; +using System.Runtime.Serialization; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +#if FRAMEWORK20 +using System.Collections.Generic; +using System.Text; +using System.Globalization; +using System.Security; +#endif + +namespace DevComponents.AdvTree +{ + /// + /// Represents advanced multi-column Tree control. + /// + [ToolboxItem(true), DefaultEvent("Click"), System.Runtime.InteropServices.ComVisible(false), Designer("DevComponents.AdvTree.Design.AdvTreeDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), ToolboxBitmap(typeof(ToolboxIconResFinder), "AdvTree.ico")] + public class AdvTree : System.Windows.Forms.ScrollableControl, INodeNotify, ISupportInitialize + { + #region Private Variables + private bool _DisposeNodes = true; + private ElementStyleCollection m_Styles = new ElementStyleCollection(); + private ColumnHeaderCollection m_Columns = new ColumnHeaderCollection(); + private NodeCollection m_Nodes = new NodeCollection(); + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + private ElementStyle m_CellStyleDefault = null; + private ElementStyle m_CellStyleMouseDown = null; + private ElementStyle m_CellStyleMouseOver = null; + private ElementStyle m_CellStyleSelected = null; + private ElementStyle m_CellStyleDisabled = null; + private ElementStyle m_NodeStyleExpanded = null; + private ElementStyle m_NodeStyle = null; + private ElementStyle m_NodeStyleSelected = null; + private ElementStyle m_NodeStyleMouseOver = null; + + private ElementStyle m_ColumnStyleNormal = null; + private ElementStyle m_ColumnStyleMouseOver = null; + private ElementStyle m_ColumnStyleMouseDown = null; + + private Layout.NodeLayout m_NodeLayout = null; + private NodeDisplay m_NodeDisplay = null; + + private HeadersCollection m_Headers = null; + + private string m_PathSeparator = System.IO.Path.PathSeparator.ToString(); + + private int m_UpdateSuspended = 0; + private bool m_PendingLayout = false; + private bool m_SuspendPaint = false; + + private Node m_SelectedNode = null; + private SelectedNodesCollection m_SelectedNodes = new SelectedNodesCollection(); + //private Cell m_SelectedCell=null; + private Node m_MouseOverNode = null; + private Cell m_MouseOverCell = null; + private int m_CellMouseDownCounter = 0; + + private ImageList m_ImageList = null; + private int m_ImageIndex = -1; + private bool m_AntiAlias = true; + + //private NodeConnector m_RootConnector=null; + private NodeConnector m_NodesConnector = null; + private NodeConnector m_LinkConnector = null; + private NodeConnector m_SelectedPathConnector = null; + private eCellLayout m_CellLayout = eCellLayout.Default; + private eCellPartLayout m_CellPartLayout = eCellPartLayout.Default; + private Cursor m_OriginalCursor = null; + private Cursor m_DefaultCellCursor = null; + private ColorScheme m_ColorScheme = null; + private bool m_CenterContent = true; + + // Selection box properties + private bool m_SelectionBox = true; + private int m_SelectionBoxSize = 4; + //private Color m_SelectionBoxBorderColor=Color.Empty; + //private Color m_SelectionBoxFillColor=Color.Empty; + + // Expand Part Properties + private Size m_DefaultExpandPartSize = new Size(8, 8); + private Size m_ExpandButtonSize = Size.Empty; + private Color m_ExpandBorderColor = Color.Empty; + private eColorSchemePart m_ExpandBorderColorSchemePart = eColorSchemePart.None; + private Color m_ExpandBackColor = Color.Empty; + private eColorSchemePart m_ExpandBackColorSchemePart = eColorSchemePart.None; + private Color m_ExpandBackColor2 = Color.Empty; + private eColorSchemePart m_ExpandBackColor2SchemePart = eColorSchemePart.None; + private int m_ExpandBackColorGradientAngle = 0; + private Color m_ExpandLineColor = Color.Empty; + private eColorSchemePart m_ExpandLineColorSchemePart = eColorSchemePart.None; + private Image m_ExpandImage = null; + private Image m_ExpandImageCollapse = null; + private eExpandButtonType m_ExpandButtonType = eExpandButtonType.Rectangle; + + private Node m_DisplayRootNode = null; + + // Command button properties + private int m_CommandWidth = 10; + private Color m_CommandBackColor = Color.Empty; + private eColorSchemePart m_CommandBackColorSchemePart = eColorSchemePart.CustomizeBackground; + private Color m_CommandBackColor2 = Color.Empty; + private eColorSchemePart m_CommandBackColor2SchemePart = eColorSchemePart.CustomizeBackground2; + private Color m_CommandForeColor = Color.Empty; + private eColorSchemePart m_CommandForeColorSchemePart = eColorSchemePart.CustomizeText; + private int m_CommandBackColorGradientAngle = 90; + private Color m_CommandMouseOverBackColor = Color.Empty; + private eColorSchemePart m_CommandMouseOverBackColorSchemePart = eColorSchemePart.ItemHotBackground; + private Color m_CommandMouseOverBackColor2 = Color.Empty; + private eColorSchemePart m_CommandMouseOverBackColor2SchemePart = eColorSchemePart.ItemHotBackground2; + private Color m_CommandMouseOverForeColor = Color.Empty; + private eColorSchemePart m_CommandMouseOverForeColorSchemePart = eColorSchemePart.ItemHotText; + private int m_CommandMouseOverBackColorGradientAngle = 90; + + // Cell editing support + private bool m_CellEdit = false; + private bool m_CellEditing = false; + private Cell m_EditedCell = null; + private TextBoxEx m_EditTextBox = null; + + // Drag & Drop + private bool m_DragDropEnabled = true; + private Node m_DragNode = null; + private Point m_MouseDownLocation = Point.Empty; + + // Layout + private eNodeLayout m_Layout = eNodeLayout.Map; + private int m_NodeHorizontalSpacing = 32; + private int m_NodeVerticalSpacing = 32; + private eDiagramFlow m_DiagramLayoutFlow = eDiagramFlow.LeftToRight; + private eMapFlow m_MapLayoutFlow = eMapFlow.Spread; + + private ElementStyle m_BackgroundStyle = new ElementStyle(); + private eNodeRenderMode m_RenderMode = eNodeRenderMode.Default; + private TreeRenderer m_NodeRenderer = null; + + private ArrayList m_HostedControlCells = new ArrayList(); + private float m_ZoomFactor = 1f; + private object m_DotNetBarManager = null; + + private DevComponents.DotNetBar.VScrollBarAdv _VScrollBar = null; + private DevComponents.DotNetBar.ScrollBar.HScrollBarAdv _HScrollBar = null; + private Control _Thumb = null; + private ColumnHeaderControl _ColumnHeader = null; + private ArrayList _FullRowBackgroundNodes = null; + private DevComponents.AdvTree.Layout.LayoutSettings _LayoutSettings = new DevComponents.AdvTree.Layout.LayoutSettings(); + #endregion + + #region Events + /// + /// Occurs just before cell editor is released for editing. It allows you to customize any properties on edit control. + /// + [Description(" Occurs just before cell editor is released for editing. It allows you to customize any properties on edit control.")] + public event PrepareCellEditorEventHandler PrepareCellEditorControl; + /// + /// Occurs when mouse button is pressed over the column header. + /// + public event MouseEventHandler ColumnHeaderMouseDown; + /// + /// Occurs when mouse button is released over the column header. + /// + public event MouseEventHandler ColumnHeaderMouseUp; + /// + /// Occurs after the cell check box is checked. + /// + public event AdvTreeCellEventHandler AfterCheck; + + /// + /// Occurs before the cell check box is checked and provides opportunity to cancel the event. + /// + public event AdvTreeCellBeforeCheckEventHandler BeforeCheck; + + /// + /// Occurs after the tree node is collapsed. + /// + public event AdvTreeNodeEventHandler AfterCollapse; + + /// + /// Occurs before the tree node is collapsed. + /// + public event AdvTreeNodeCancelEventHandler BeforeCollapse; + + /// + /// Occurs after the tree node is expanded. + /// + public event AdvTreeNodeEventHandler AfterExpand; + + /// + /// Occurs before the tree node is expanded. + /// + public event AdvTreeNodeCancelEventHandler BeforeExpand; + + /// + /// Occurs when command button on node is clicked. + /// + public event CommandButtonEventHandler CommandButtonClick; + + /// + /// Occurs before cell is edited. The order of the cell editing events is as follows: + /// BeforeCellEdit, CellEditEnding, AfterCellEdit, AfterCellEditComplete. + /// + public event CellEditEventHandler BeforeCellEdit; + /// + /// Occurs just before the cell editing is ended. The text box for editing is still visible and you can cancel + /// the exit out of editing mode at this point. The order of the cell editing events is as follows: + /// BeforeCellEdit, CellEditEnding, AfterCellEdit, AfterCellEditComplete. + /// + public event CellEditEventHandler CellEditEnding; + /// + /// Occurs after cell editing has ended and before the new text entered by the user is assigned to the cell. You can abort the edits in this event. + /// The order of the cell editing events is as follows: + /// BeforeCellEdit, CellEditEnding, AfterCellEdit, AfterCellEditComplete. + /// + public event CellEditEventHandler AfterCellEdit; + + /// + /// Occurs after cell editing has been completed. This event cannot be canceled. + /// + public event CellEditEventHandler AfterCellEditComplete; + /// + /// Occurs after node selection has changed. + /// + public event EventHandler SelectionChanged; + /// + /// Occurs before Node has been selected by user or through the SelectedNode property. Event can be cancelled. + /// + public event AdvTreeNodeCancelEventHandler BeforeNodeSelect; + + /// + /// Occurs after node has been selected by user or through the SelectedNode property. + /// + public event AdvTreeNodeEventHandler AfterNodeSelect; + + /// + /// Occurs after node has been deselected by user or through the SelectedNode or SelectedNodes properties. + /// + public event AdvTreeNodeEventHandler AfterNodeDeselect; + + /// + /// Occurs before node has been removed from its parent. + /// + public event TreeNodeCollectionEventHandler BeforeNodeRemove; + + /// + /// Occurs after node has been removed from its parent. + /// + public event TreeNodeCollectionEventHandler AfterNodeRemove; + + /// + /// Occurs before node is inserted or added as child node to parent node. + /// + public event TreeNodeCollectionEventHandler BeforeNodeInsert; + + /// + /// Occurs after node is inserted or added as child node. + /// + public event TreeNodeCollectionEventHandler AfterNodeInsert; + + /// + /// Occurs when node drag & drop operation is initiated. + /// + [Description("Occurs when node drag & drop operation is initiated.")] + public event EventHandler NodeDragStart; + /// + /// Occurs before internal node drag & drop support is initiated and allows you to cancel the drag & drop. + /// + public event AdvTreeNodeCancelEventHandler BeforeNodeDragStart; + /// + /// Occurs before Drag-Drop of a node is completed and gives you information about new parent of the node that is being dragged + /// as well as opportunity to cancel the operation. + /// + public event TreeDragDropEventHandler BeforeNodeDrop; + + /// + /// Occurs while node is being dragged. You can handle this event to disable the drop at specific nodes or to even change the + /// drop location for the node by modifying event arguments. + /// + public event TreeDragFeedbackEventHander NodeDragFeedback; + + /// + /// Occurs after Drag-Drop of a node is completed. This operation cannot be cancelled. + /// + public event TreeDragDropEventHandler AfterNodeDrop; + + /// + /// Occurs when the mouse pointer is over the node and a mouse button is pressed. + /// + public event TreeNodeMouseEventHandler NodeMouseDown; + + /// + /// Occurs when the mouse pointer is over the node and a mouse button is released. + /// + public event TreeNodeMouseEventHandler NodeMouseUp; + + /// + /// Occurs when the mouse pointer is moved over the node. + /// + public event TreeNodeMouseEventHandler NodeMouseMove; + + /// + /// Occurs when the mouse enters the node. + /// + public event TreeNodeMouseEventHandler NodeMouseEnter; + + /// + /// Occurs when the mouse leaves the node. + /// + public event TreeNodeMouseEventHandler NodeMouseLeave; + + /// + /// Occurs when the mouse hovers over the node. + /// + public event TreeNodeMouseEventHandler NodeMouseHover; + + /// + /// Occurs when the node is clicked with left mouse button. If you need to know more information like if another mouse button is clicked etc. use + /// NodeMouseDown event. + /// + public event TreeNodeMouseEventHandler NodeClick; + + /// + /// Occurs when the node is double-clicked. + /// + public event TreeNodeMouseEventHandler NodeDoubleClick; + + /// + /// Occurs after an node has been serialized to XmlElement and provides you with opportunity to add any custom data + /// to serialized XML. This allows you to serialize any data associated with the node and load it back up in DeserializeNode event. + /// + /// + /// To serialize custom data to XML definition control creates handle this event and use CustomXmlElement + /// property on SerializeNodeEventArgs to add new nodes or set attributes with custom data you want saved. + /// + public event SerializeNodeEventHandler SerializeNode; + + /// + /// Occurs after an node has been de-serialized (loaded) from XmlElement and provides you with opportunity to load any custom data + /// you have serialized during SerializeItem event. + /// + /// + /// To de-serialize custom data from XML definition handle this event and use CustomXmlElement + /// property on SerializeItemEventArgs to retrieve any data you saved in SerializeNode event. + /// + public event SerializeNodeEventHandler DeserializeNode; + + /// + /// Occurs when hyperlink in text-markup is clicked. + /// + public event MarkupLinkClickEventHandler MarkupLinkClick; + + /// + /// Occurs when cell with custom editor type is about to be edited by user. Handle this event to provide + /// custom editors. + /// + public event CustomCellEditorEventHandler ProvideCustomCellEditor; + +#if FRAMEWORK20 + /// + /// Occurs when the DataSource changes. + /// + [Description("Occurs when the DataSource changes.")] + public event EventHandler DataSourceChanged; + /// + /// Occurs when the DisplayMembers property changes. + /// + [Description("Occurs when the DisplayMembers property changes")] + public event EventHandler DisplayMembersChanged; + /// + /// Occurs when the control is bound to a data value that need to be converted. + /// + [Description("Occurs when the control is bound to a data value that need to be converted.")] + public event DevComponents.DotNetBar.Controls.TreeConvertEventHandler Format; + /// + /// Occurs when FormattingEnabled property changes. + /// + [Description("Occurs when FormattingEnabled property changes.")] + public event EventHandler FormattingEnabledChanged; + /// + /// Occurs when FormatString property changes. + /// + [Description("Occurs when FormatString property changes.")] + public event EventHandler FormatStringChanged; + /// + /// Occurs when FormatInfo property has changed. + /// + [Description("Occurs when FormatInfo property has changed.")] + public event EventHandler FormatInfoChanged; + /// + /// Occurs when a Node for an data-bound object item has been created and provides you with opportunity to modify the node. + /// + [Description("Occurs when a Node for an data-bound object item has been created and provides you with opportunity to modify the node")] + public event DevComponents.DotNetBar.Controls.DataNodeEventHandler DataNodeCreated; + /// + /// Occurs when a group Node is created as result of GroupingMembers property setting and provides you with opportunity to modify the node. + /// + [Description("Occurs when a group Node is created as result of GroupingMembers property setting and provides you with opportunity to modify the node")] + public event DevComponents.DotNetBar.Controls.DataNodeEventHandler GroupNodeCreated; + /// + /// Occurs when value of ValueMember property has changed. + /// + [Description("Occurs when value of ValueMember property has changed.")] + public event EventHandler ValueMemberChanged; + /// + /// Occurs when value of SelectedValue property has changed. + /// + [Description("Occurs when value of SelectedValue property has changed.")] + public event EventHandler SelectedValueChanged; + /// + /// Occurs when value of SelectedIndex property has changed. + /// + [Description("Occurs when value of SelectedValue property has changed.")] + public event EventHandler SelectedIndexChanged; + /// + /// Occurs when ColumnHeader is automatically created by control as result of data binding and provides you with opportunity to modify it. + /// + [Description("Occurs when ColumnHeader is automatically created by control as result of data binding and provides you with opportunity to modify it.")] + public event DevComponents.DotNetBar.Controls.DataColumnEventHandler DataColumnCreated; +#endif + /// + /// Occurs after column has been resized by end-user. + /// + [Description("Occurs after column has been resized by end-user")] + public event EventHandler ColumnResized; + /// + /// Occurs while column is being resized by end-user. + /// + [Description("Occurs while column is being resized by end-user.")] + public event EventHandler ColumnResizing; + + /// + /// Occurs after cell has been selected. + /// + [Description("Occurs after cell has been selected.")] + public event AdvTreeCellEventHandler CellSelected; + /// + /// Occurs after cell has been unselected. + /// + [Description("Occurs after cell has been unselected.")] + public event AdvTreeCellEventHandler CellUnselected; + /// + /// Occurs after users has moved the column. + /// + [Description("Occurs after users has moved the column.")] + public event ColumnMovedHandler ColumnMoved; + /// + /// Occurs while tree control is being rendered. + /// + [Description("Occurs while tree control is being rendered.")] + public event AdvTreeRenderEventHandler Render; + /// + /// Raises Render event. + /// + /// Provides event arguments. + protected virtual void OnRender(AdvTreeRenderEventArgs e) + { + AdvTreeRenderEventHandler handler = Render; + if (handler != null) + handler(this, e); + } + internal void InvokeRenderEvent(AdvTreeRenderEventArgs e) + { + OnRender(e); + } + #endregion + + #region Constructor/Dispose + /// Creates new instance of the class. + public AdvTree() + { + if (!ColorFunctions.ColorsLoaded) + { + NativeFunctions.RefreshSettings(); + NativeFunctions.OnDisplayChange(); + ColorFunctions.LoadColors(); + } + m_SelectedNodes.TreeSelectionControl = this; + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(ControlStyles.DoubleBuffer, true); + this.SetStyle(ControlStyles.Selectable, true); + + // This call is required by the Windows.Forms Form Designer. + InitializeComponent(); + + m_BackgroundStyle.StyleChanged += new EventHandler(ElementStyleChanged); + m_BackgroundStyle.TreeControl = this; + + m_Columns.Parent = this; + + // Setup layout helper + m_NodeLayout = new NodeTreeLayout(this, this.ClientRectangle, _LayoutSettings); + _LayoutSettings.NodeVerticalSpacing = _NodeSpacing; + + m_NodeLayout.LeftRight = this.RtlTranslateLeftRight(LeftRightAlignment.Left); + +#if TRIAL + NodeOperations.ColorExpAlt(); +#endif + // Setup display helper + m_NodeDisplay = new NodeTreeDisplay(this); + + m_Headers = new HeadersCollection(); + + m_Nodes.TreeControl = this; + m_Styles.TreeControl = this; + + m_ColorScheme = new ColorScheme(eColorSchemeStyle.Office2007); + + //m_SelectionBoxBorderColor=GetDefaultSelectionBoxBorderColor(); + //m_SelectionBoxFillColor=GetDefaultSelectionBoxFillColor(); + + m_ExpandButtonSize = GetDefaultExpandButtonSize(); + + this.AllowDrop = true; + this.IsAccessible = true; + + if (BarFunctions.IsWindows7 && DevComponents.DotNetBar.Touch.TouchHandler.IsTouchEnabled) + { + _TouchHandler = new DevComponents.DotNetBar.Touch.TouchHandler(this, DevComponents.DotNetBar.Touch.eTouchHandlerType.Gesture); + _TouchHandler.PanBegin += new EventHandler(TouchHandlerPanBegin); + _TouchHandler.Pan += new EventHandler(TouchHandlerPan); + _TouchHandler.PanEnd += new EventHandler(TouchHandlerPanEnd); + } + } + + private bool _Disposed = false; + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + _Disposed = true; + if (disposing) + { + if (components != null) + components.Dispose(); + + System.Windows.Forms.Timer timer = _SearchBufferExpireTimer; + _SearchBufferExpireTimer = null; + if (timer != null) + { + timer.Stop(); + timer.Dispose(); + } + } + + if (BarUtilities.DisposeItemImages && !this.DesignMode) + { + BarUtilities.DisposeImage(ref _CheckBoxImageChecked); + BarUtilities.DisposeImage(ref _CheckBoxImageIndeterminate); + BarUtilities.DisposeImage(ref _CheckBoxImageUnChecked); + BarUtilities.DisposeImage(ref m_ExpandImage); + BarUtilities.DisposeImage(ref m_ExpandImageCollapse); + } + + if (m_Nodes != null && disposing && _DisposeNodes) + { + Node[] nodes = new Node[m_Nodes.Count]; + m_Nodes.CopyTo(nodes); + foreach (Node node in nodes) + node.Dispose(); + //m_Nodes.Clear(); + } + + base.Dispose(disposing); + } + /// + /// Indicates whether nodes are disposed when control is disposed. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool DisposeNodes + { + get { return _DisposeNodes; } + set + { + _DisposeNodes = value; + } + } + + #endregion + + #region Component Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + #endregion + + #region Properties + [DefaultValue(true)] + public override bool AllowDrop { + get { return base.AllowDrop; } + set { base.AllowDrop = value; } + } + + private bool _DeepSort = false; + /// + /// Indicates whether sorting of node collection sorts child nodes as well. Default value is false. + /// + [Browsable(false), DefaultValue(false), Category("Behavior"), Description("Indicates whether sorting of node collection sorts child nodes as well. Default value is false.")] + public bool DeepSort + { + get { return _DeepSort; } + set + { + _DeepSort = value; + } + } + + private bool _ShowToolTips = true; + /// + /// Gets or sets whether tooltips are shown when mouse is over the cell when Tooltip property is set. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether tooltips are shown when mouse is over the cell when Tooltip property is set.")] + public bool ShowToolTips + { + get { return _ShowToolTips; } + set + { + _ShowToolTips = value; + } + } + + /// + /// Gets the column header control which renderes the columns. + /// + internal ColumnHeaderControl ColumnHeaderControl + { + get { return _ColumnHeader; } + } + private eScrollBarAppearance _ScrollBarAppearance = eScrollBarAppearance.Default; + /// + /// Gets or sets the scroll-bar visual style. + /// + [DefaultValue(eScrollBarAppearance.Default), Category("Appearance"), Description("Gets or sets the scroll-bar visual style.")] + public eScrollBarAppearance ScrollBarAppearance + { + get { return _ScrollBarAppearance; } + set + { + _ScrollBarAppearance = value; + OnScrollBarAppearanceChanged(); + } + } + private void OnScrollBarAppearanceChanged() + { + if (_VScrollBar != null) _VScrollBar.Appearance = _ScrollBarAppearance; + if (_HScrollBar != null) _HScrollBar.Appearance = _ScrollBarAppearance; + } + + private Size _TileSize = new Size(184, 30); + /// + /// Gets or sets the proposed size of the tile in Tile view. The size of the tile might be larger than specified if Style assigned to node, cells adds padding, margins etc. or if Node.Image or font is greater than width or height specified here. + /// + [Category("Appearance"), Description("Indicates size of the tile in Tile view.")] + public Size TileSize + { + get { return _TileSize; } + set + { + if (value != _TileSize) + { + Size oldValue = _TileSize; + _TileSize = value; + OnTileSizeChanged(oldValue, value); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTileSize() + { + return _TileSize.Width != 184 || _TileSize.Height != 30; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTileSize() + { + TileSize = new Size(184, 30); + } + private void OnTileSizeChanged(Size oldValue, Size newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TileSize")); + if (_View == eView.Tile) + { + InvalidateNodesSize(); + this.RecalcLayout(); + } + } + + private bool _HideSelection = false; + /// + /// Gets or sets a value indicating whether the selected tree node remains highlighted even when the tree control has lost the focus. + /// + [DefaultValue(false), Category("Selection"), Description("Indicates whether the selected tree node remains highlighted even when the tree control has lost the focus.")] + public bool HideSelection + { + get { return _HideSelection; } + set + { + _HideSelection = value; + if (this.SelectedNode != null && !this.IsKeyboardFocusWithin) + this.Invalidate(); + } + } + + private bool _IsKeyboardFocusWithin = false; + /// + /// Gets whether keyboard focus is within the control. + /// + [Browsable(false)] + public bool IsKeyboardFocusWithin + { + get { return _IsKeyboardFocusWithin; } +#if FRAMEWORK20 + internal set +#else + set +#endif + { + _IsKeyboardFocusWithin = value; + OnIsKeyboardFocusWithinChanged(); + } + } + protected virtual void OnIsKeyboardFocusWithinChanged() + { + if (_IsKeyboardFocusWithin) + { + if (_MultiSelect) + { + foreach (Node node in m_SelectedNodes) + { + InvalidateNode(node); + } + } + else if (this.SelectedNode != null) + InvalidateNode(this.SelectedNode); + } + else + { + if (_MultiSelect) + { + foreach (Node node in m_SelectedNodes) + { + InvalidateNode(node); + } + } + else if (this.SelectedNode != null) + InvalidateNode(this.SelectedNode); + + if (m_CellEditing && _EndCellEditingOnLostFocus) + EndCellEditing(eTreeAction.Keyboard); + } + } + + private bool _EndCellEditingOnLostFocus = true; + /// + /// Gets or sets whether cell editing is completed when control loses input focus. Default value is true. + /// + [DefaultValue(true), Category("Editing"), Description("Indicates whether cell editing is completed when control loses input focus. Default value is true.")] + public bool EndCellEditingOnLostFocus + { + get { return _EndCellEditingOnLostFocus; } + set + { + _EndCellEditingOnLostFocus = value; + } + } + + protected override void OnEnter(EventArgs e) + { + this.IsKeyboardFocusWithin = true; + base.OnEnter(e); + } + protected override void OnLeave(EventArgs e) + { + this.IsKeyboardFocusWithin = false; + base.OnLeave(e); + } + + internal ArrayList FullRowBackgroundNodes + { + get + { + return _FullRowBackgroundNodes; + } + set + { + _FullRowBackgroundNodes = value; + } + } + + private ContextMenuBar _ContextMenuBar = null; + /// + /// Gets or sets the reference to DotNetBar ContextMenuBar component which is used to provide context menu for nodes. This property + /// is automatically maintained by AdvTree. + /// + [EditorBrowsable(EditorBrowsableState.Never), DefaultValue(null), Browsable(false)] + public ContextMenuBar ContextMenuBar + { + get { return _ContextMenuBar; } + set { _ContextMenuBar = value; } + } + + /// + /// Gets or sets zoom factor for the control. Default value is 1. To zoom display of the nodes for 20% set zoom factor to 1.2 + /// To zoom view 2 times set zoom factor to 2. Value must be greater than 0. Zoom is supported only when non-column tree setup is used. + /// Please note that Zoom functionality is designed only for very special use cases and only for + /// plain tree control setup which does not use editing, alternating row colors, drag & drop or any other + /// advanced functionality. + /// + [Browsable(false), DefaultValue(1f), Category("Layout"), Description("Indicates zoom factor for the control.")] + public float Zoom + { + get { return m_ZoomFactor; } + set + { + if (value <= 0.1) + return; + m_ZoomFactor = value; + this.RecalcLayout(); + } + } + + /// + /// Gets the size of the tree. + /// + [Browsable(false)] + public Size TreeSize + { + get + { + return new Size(m_NodeLayout.Width, m_NodeLayout.Height); + } + } + + /// + /// Gets or sets custom node renderer. You can set this property to your custom renderer. When set the RenderMode should be set to Custom to enable + /// your custom renderer. To choose one of the system renderer use RenderMode property. Default value is null. + /// + [Browsable(false), Category("Style"), DefaultValue(null), Description("Indicates render mode used to render the node.")] + internal TreeRenderer NodeRenderer + { + get { return m_NodeRenderer; } + set + { + m_NodeRenderer = value; + OnDisplayChanged(); + } + } + /// + /// Gets or sets the render mode used to render all nodes. Default value is eNodeRenderMode.Default which indicates that system default renderer is used. + /// Note that if you specify custom renderer you need to set AdvTree.NodeRenderer property to your custom renderer. + /// + [Browsable(true), Category("Style"), DefaultValue(eNodeRenderMode.Default), Description("Indicates render mode used to render the node.")] + internal eNodeRenderMode RenderMode + { + get { return m_RenderMode; } + set + { + m_RenderMode = value; + OnDisplayChanged(); + } + } + + /// + /// Gets the style for the background of the control. + /// + [Browsable(true), Category("Appearance"), Description("Gets the style for the background of the control."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return m_BackgroundStyle; } + } + + /// + /// Gets the current renderer used by the control. + /// + /// Reference to the TreeRenderer used by the control. + public TreeRenderer GetRenderer() + { + if (m_RenderMode == eNodeRenderMode.Default) + { + if (m_NodeDisplay is NodeTreeDisplay) + return ((NodeTreeDisplay)m_NodeDisplay).SystemRenderer; + return null; + } + else + return m_NodeRenderer; + } + + /// + /// Gets or sets internal layout cell horizontal spacing. This property is for advanced internal use and you should not set it. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Advanced)] + public int CellHorizontalSpacing + { + get + { + return _LayoutSettings.CellHorizontalSpacing; + } + set + { + _LayoutSettings.CellHorizontalSpacing = value; + } + } + + ///// + ///// Gets or sets the flow of nodes when Diagram layout is used. Note that this setting applies only to Diagram layout type. + ///// + //[Browsable(true),Category("Layout"),DefaultValue(eDiagramFlow.LeftToRight),Description("Indicates flow of nodes when Diagram layout is used.")] + //public eDiagramFlow DiagramLayoutFlow + //{ + // get {return m_DiagramLayoutFlow;} + // set + // { + // m_DiagramLayoutFlow=value; + // OnLayoutChanged(); + // } + //} + + ///// + ///// Gets or sets the flow of nodes when Map layout is used. Note that this setting applies only to Map layout type. + ///// + //[Browsable(true),Category("Layout"),DefaultValue(eMapFlow.Spread),Description("Indicates flow of nodes when Map layout is used.")] + //public eMapFlow MapLayoutFlow + //{ + // get {return m_MapLayoutFlow;} + // set + // { + // m_MapLayoutFlow=value; + // OnLayoutChanged(); + // } + //} + + ///// + ///// Gets or sets the horizontal spacing in pixels between nodes. Default value is 32. + ///// + //[Browsable(true),Category("Layout"),DefaultValue(32),Description("Indicates horizontal spacing in pixels between nodes.")] + //public int NodeHorizontalSpacing + //{ + // get {return m_NodeHorizontalSpacing;} + // set + // { + // m_NodeHorizontalSpacing=value; + // OnLayoutChanged(); + // } + //} + + ///// + ///// Gets or sets the vertical spacing in pixels between nodes. Default value is 16. + ///// + //[Browsable(true),Category("Layout"),DefaultValue(32),Description("Indicates vertical spacing in pixels between nodes.")] + //public int NodeVerticalSpacing + //{ + // get {return m_NodeVerticalSpacing;} + // set + // { + // m_NodeVerticalSpacing=value; + // OnLayoutChanged(); + // } + //} + + ///// + ///// Gets or sets the layout type for the nodes. + ///// + //[Browsable(true),Category("Layout"),DefaultValue(eNodeLayout.Map),Description("Indicates layout type for the nodes.")] + //public eNodeLayout LayoutType + //{ + // get {return m_Layout;} + // set + // { + // if(m_Layout!=value) + // { + // SetLayout(value); + // } + // } + //} + + /// + /// Gets or sets whether automatic drag and drop is enabled. Default value is true. + /// + [Browsable(true), Category("Behavior"), Description("Indicates whether automatic drag and drop is enabled."), DefaultValue(true)] + public bool DragDropEnabled + { + get { return m_DragDropEnabled; } + set { m_DragDropEnabled = value; } + } + + /// + /// Creates the Graphics object for the control. + /// + /// The Graphics object for the control. + public new Graphics CreateGraphics() + { + Graphics g = base.CreateGraphics(); + if (m_AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; +#if FRAMEWORK20 + if (!SystemInformation.IsFontSmoothingEnabled) +#endif + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + return g; + } + + /// + /// Gets or sets whether anti-alias smoothing is used while painting the tree. + /// + [DefaultValue(true), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting the tree.")] + public bool AntiAlias + { + get { return m_AntiAlias; } + set + { + if (m_AntiAlias != value) + { + m_AntiAlias = value; + this.Refresh(); + } + } + } + + /// + /// Gets or sets the delimiter string that the tree node path uses. + /// + [DefaultValue("\\"), Browsable(false), Description("Indicates the delimiter string that the tree node path uses.")] + public string PathSeparator + { + get { return m_PathSeparator; } + set { m_PathSeparator = value; } + } + + private bool _AllowUserToResizeColumns = true; + /// + /// Gets or sets whether user can resize the columns. Default value is true. + /// + [DefaultValue(true), Category("Columns"), Description("Indicates whether user can resize the columns.")] + public bool AllowUserToResizeColumns + { + get { return _AllowUserToResizeColumns; } + set + { + _AllowUserToResizeColumns = value; + } + } + + private bool _AllowUserToReorderColumns = false; + /// + /// Gets or sets whether user can reorder the columns. Default value is false. + /// + [DefaultValue(false), Category("Columns"), Description("Indicates whether user can reorder the columns.")] + public bool AllowUserToReorderColumns + { + get { return _AllowUserToReorderColumns; } + set + { + _AllowUserToReorderColumns = value; + } + } + + + /// + /// Gets the collection of column headers that appear in the tree. + /// + /// + /// By default there are no column headers defined. In that case tree control + /// functions as regular tree control where text has unrestricted width. + /// If you want to restrict the horizontal width of the text but not display + /// column header you can create one column and set its width to the width desired and + /// set its Visible property to false. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Columns"), Description("Gets collection of column headers that appear in the tree.")] + public ColumnHeaderCollection Columns + { + get + { + return m_Columns; + } + } + + private bool _ColumnsVisible = true; + /// + /// Gets or sets whether column headers are visible if they are defined through Columns collection. Default value is true. + /// + [DefaultValue(true), Category("Columns"), Description("Indicates whether column headers are visible if they are defined through Columns collection.")] + public bool ColumnsVisible + { + get { return _ColumnsVisible; } + set + { + if (_ColumnsVisible != value) + { + _ColumnsVisible = value; + if (m_Columns.Count > 0) RecalcLayout(); + } + } + } + + internal void SetColumnHeaderControlVisibility(bool visible) + { + if (visible) + { + if (_ColumnHeader == null) + { + _ColumnHeader = new ColumnHeaderControl(); + _ColumnHeader.Columns = this.Columns; + this.Controls.Add(_ColumnHeader); + } + } + else if (_ColumnHeader != null) + { + _ColumnHeader.Columns = null; + this.Controls.Remove(_ColumnHeader); + _ColumnHeader.Dispose(); + _ColumnHeader = null; + } + RepositionColumnHeader(); + } + + internal bool CanResizeColumnAt(int x, int y) + { + if (!m_Columns.Bounds.Contains(x, y)) return false; + + ColumnHeader col = GetColumnForResizeAt(x, y, m_Columns, false); + return col != null; + } + + internal ColumnHeader GetColumnAt(int x, int y, ColumnHeaderCollection columns) + { + Point p = new Point(x, y); + Point offset = Point.Empty; + if (AutoScroll) + { + offset = GetAutoScrollPositionOffset(); + if (columns.ParentNode == null) + offset.Y = 0; + } + + Rectangle columnsBounds = columns.Bounds; + columnsBounds.Offset(offset); + if (!columnsBounds.Contains(p)) return null; + + foreach (ColumnHeader item in columns) + { + if (!item.Visible) continue; + Rectangle r = item.Bounds; + r.Offset(offset); + if (r.Contains(p)) + return item; + } + return null; + } + + private ColumnHeader GetColumnForResizeAt(int x, int y, ColumnHeaderCollection columns, bool ignoreY) + { + return GetColumnForResizeAt(x, y, columns, ignoreY, false); + } + private ColumnHeader GetColumnForResizeAt(int x, int y, ColumnHeaderCollection columns, bool ignoreY, bool ignoreLastColumn) + { + Point p = new Point(x, y); + Point offset = Point.Empty; + if (AutoScroll) + { + offset = GetAutoScrollPositionOffset(); + if (columns.ParentNode == null) + offset.Y = 0; + } + + Rectangle columnsBounds = columns.Bounds; + columnsBounds.Offset(offset); + if (!columnsBounds.Contains(p) && !ignoreY) return null; + + int count = columns.Count - (ignoreLastColumn ? 1 : 0); + for (int i = 0; i < count; i++) + { + ColumnHeader item = columns[i]; + Rectangle r = new Rectangle(item.Bounds.Right - 4, item.Bounds.Y, 6, item.Bounds.Height); + r.Offset(offset); + if (r.Contains(p) || ignoreY && p.X >= r.X && p.X <= r.Right) + return item; + } + return null; + } + + private ColumnHeader _ColumnReorder = null; + private Cursor _OldCursor = null; + private int _ColumnMoveMarkerIndex = -1; + private int ColumnMoveMarkerIndex + { + get + { + return _ColumnMoveMarkerIndex; + } + set + { + if (_ColumnReorder == null) throw new ArgumentException("Column is not being reordered"); + _ColumnMoveMarkerIndex = value; + if (_ColumnReorder.Parent == m_Columns) + _ColumnHeader.ColumnMoveMarkerIndex = value; + else + { + this.Invalidate(_ColumnReorder.Parent.Bounds); + } + } + } + internal void StartColumnReorder(int x, int y) + { + StartColumnReorder(x, y, m_Columns); + } + private void StartColumnReorder(int x, int y, ColumnHeaderCollection columns) + { + ColumnHeader col = GetColumnAt(x, y, columns); + if (col == null) return; + EndCellEditing(eTreeAction.Mouse); + _OldCursor = this.Cursor; + this.Cursor = Cursors.Hand; + this.Capture = true; + _ColumnReorder = col; + this.ColumnMoveMarkerIndex = columns.IndexOf(col); + this.Invalidate(); + } + + private ColumnHeader _ColumnResize = null; + internal void StartColumnResize(int x, int y) + { + StartColumnResize(x, y, m_Columns); + } + + private void StartColumnResize(int x, int y, ColumnHeaderCollection columns) + { + ColumnHeader col = GetColumnForResizeAt(x, y, columns, _GridColumnLineResizeEnabled, false); + if (col == null) return; + + this.Capture = true; + _ColumnResize = col; + } + + /// + /// Gets the collection of all style elements created for the tree. + /// + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyleCollection Styles + { + get { return m_Styles; } + } + + /// + /// Gets or sets default style for the node cell. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates default style for the node cell.")] + public ElementStyle CellStyleDefault + { + get { return m_CellStyleDefault; } + set + { + if (m_CellStyleDefault != value) + { + if (m_CellStyleDefault != null) + m_CellStyleDefault.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_CellStyleDefault = value; + this.OnCellStyleChanged(); + } + } + } + + /// + /// Gets or sets default style for the node cell when mouse is pressed. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates default style for the node cell when mouse is pressed.")] + public ElementStyle CellStyleMouseDown + { + get { return m_CellStyleMouseDown; } + set + { + if (m_CellStyleMouseDown != value) + { + if (m_CellStyleMouseDown != null) + m_CellStyleMouseDown.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_CellStyleMouseDown = value; + this.OnCellStyleChanged(); + } + } + } + + /// + /// Gets or sets default style for the node cell when mouse is over the cell. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates default style for the node cell when mouse is over the cell.")] + public ElementStyle CellStyleMouseOver + { + get { return m_CellStyleMouseOver; } + set + { + if (m_CellStyleMouseOver != value) + { + if (m_CellStyleMouseOver != null) + m_CellStyleMouseOver.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_CellStyleMouseOver = value; + this.OnCellStyleChanged(); + } + } + } + + /// + /// Gets or sets default style for the node cell when cell is selected. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates default style for the node cell when cell is selected.")] + public ElementStyle CellStyleSelected + { + get { return m_CellStyleSelected; } + set + { + if (m_CellStyleSelected != value) + { + if (m_CellStyleSelected != null) + m_CellStyleSelected.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_CellStyleSelected = value; + this.OnCellStyleChanged(); + } + } + } + + /// + /// Gets or sets default style for the node cell when cell is disabled. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates default style for the node cell when cell is disabled.")] + public ElementStyle CellStyleDisabled + { + get { return m_CellStyleDisabled; } + set + { + if (m_CellStyleDisabled != value) + { + if (m_CellStyleDisabled != null) + m_CellStyleDisabled.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_CellStyleDisabled = value; + this.OnCellStyleChanged(); + } + } + } + + /// + /// Gets or sets default style for the node when node is expanded. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Gets or sets default style for the node cell when node that cell belongs to is expanded.")] + public ElementStyle NodeStyleExpanded + { + get { return m_NodeStyleExpanded; } + set + { + if (m_NodeStyleExpanded != value) + { + if (m_NodeStyleExpanded != null) + m_NodeStyleExpanded.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_NodeStyleExpanded = value; + this.OnCellStyleChanged(); + } + } + } + + /// + /// Gets or sets default style for all nodes where style is not specified + /// explicity. + /// + /// + /// Name of the style assigned or null value indicating that no style is used. + /// Default value is null. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Gets or sets default style for the node.")] + public ElementStyle NodeStyle + { + get { return m_NodeStyle; } + set + { + if (m_NodeStyle != value) + { + if (m_NodeStyle != null) + m_NodeStyle.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_NodeStyle = value; + this.OnCellStyleChanged(); + } + } + } + /// + /// Gets or sets style for the node when node is selected. Note that this style is applied to the default node style. + /// + /// + /// Reference to the style assigned or null value indicating that no style is used. + /// Default value is null. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Gets or sets style of the node when node is selected.")] + public ElementStyle NodeStyleSelected + { + get { return m_NodeStyleSelected; } + set + { + if (m_NodeStyleSelected != value) + { + if (m_NodeStyleSelected != null) + m_NodeStyleSelected.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_NodeStyleSelected = value; + this.OnCellStyleChanged(); + } + } + } + + /// + /// Gets or sets style for the node when mouse is over node. Note that this style is applied to the default node style. + /// + /// + /// Reference to the style assigned or null value indicating that no style is used. + /// Default value is null. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Gets or sets style of the node when mouse is over node.")] + public ElementStyle NodeStyleMouseOver + { + get { return m_NodeStyleMouseOver; } + set + { + if (m_NodeStyleMouseOver != value) + { + if (m_NodeStyleMouseOver != null) + m_NodeStyleMouseOver.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_NodeStyleMouseOver = value; + this.OnCellStyleChanged(); + } + } + } + + + /// + /// Gets the collection of tree nodes that are assigned to the tree view control. + /// + /// + /// A NodeCollection that represents the tree nodes + /// assigned to the tree control. + /// + /// + /// The Nodes property holds a collection of Node objects, each of which has a + /// Nodes property that can contain its own NodeCollection. + /// + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Description("Gets the collection of tree nodes that are assigned to the tree control.")] + public NodeCollection Nodes + { + get { return m_Nodes; } + } + + private int _NodeSpacing = 3; + /// + /// Gets or sets the vertical spacing between nodes in pixels. Default value is 3. + /// + [DefaultValue(3), Description("Indicates vertical spacing between nodes in pixels."), Category("Layout")] + public int NodeSpacing + { + get { return _NodeSpacing; } + set + { + _NodeSpacing = value; + _LayoutSettings.NodeVerticalSpacing = value; + this.InvalidateNodesSize(); + this.RecalcLayout(); + } + } + /// + /// Gets or sets the horizontal spacing between nodes in pixels when control is in Tile layout. Default value is 4. + /// + [DefaultValue(4), Description("Indicates horizontal spacing between nodes in pixels when control is in Tile layout."), Category("Layout")] + public int NodeHorizontalSpacing + { + get { return _LayoutSettings.NodeHorizontalSpacing; } + set + { + if (value != _LayoutSettings.NodeHorizontalSpacing) + { + _LayoutSettings.NodeHorizontalSpacing = value; + this.InvalidateNodesSize(); + this.RecalcLayout(); + } + } + } + + private bool _GridRowLines = false; + /// + /// Gets or sets whether horizontal grid lines between each row are displayed. Default value is false. + /// + [DefaultValue(false), Category("Columns"), Description("")] + public bool GridRowLines + { + get { return _GridRowLines; } + set + { + if (_GridRowLines != value) + { + _GridRowLines = value; + this.Invalidate(); + } + } + } + + private bool _GridColumnLineResizeEnabled = false; + /// + /// Gets or sets whether column can be resized when mouse is over the column grid line and outside of the column header. + /// GridColumnLines must be set to true to make column lines visible. + /// + [DefaultValue(false), Category("Columns"), Description("Indicates whether column can be resized when mouse is over the column grid line and outside of the column header.")] + public bool GridColumnLineResizeEnabled + { + get { return _GridColumnLineResizeEnabled; } + set + { + _GridColumnLineResizeEnabled = value; + } + } + + private bool _GridLines = true; + /// + /// Gets or sets whether grid lines are displayed when columns are defined. Default value is true. + /// + [DefaultValue(true), Category("Columns"), Description("Indicates whether grid lines are displayed when columns are defined.")] + public bool GridColumnLines + { + get { return _GridLines; } + set + { + if (_GridLines != value) + { + _GridLines = value; + if (m_Columns.Count > 0 && _ColumnsVisible) + this.Invalidate(); + } + } + } + + private Color _GridLinesColor = Color.Empty; + /// + /// Gets or sets the grid lines color. + /// + [Category("Columns"), Description("Indicates grid lines color.")] + public Color GridLinesColor + { + get { return _GridLinesColor; } + set { _GridLinesColor = value; this.Invalidate(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeGridLinesColor() + { + return !_GridLinesColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetGridLinesColor() + { + this.GridLinesColor = Color.Empty; + } + + private Color _AlternateRowColor = Color.Empty; + /// + /// Gets or sets the alternate row color applied to every other row. Default value is Color.Empty. + /// + [Category("Columns"), Description("Indicates alternate row color applied to every other row.")] + public Color AlternateRowColor + { + get { return _AlternateRowColor; } + set + { + _AlternateRowColor = value; + this.Invalidate(); + } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAlternateRowColor() + { + return !_AlternateRowColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAlternateRowColor() + { + this.AlternateRowColor = Color.Empty; + } + + private ElementStyle _NodesColumnsBackgroundStyle = null; + /// + /// Gets or sets the background style for the child nodes columns. Background style defines the appearance of the column header background. + /// + /// + /// Reference to the style assigned to the column header. + /// + [Browsable(true), DefaultValue(null), Category("Column Header Style"), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the style class assigned to the child nodes columns.")] + public ElementStyle NodesColumnsBackgroundStyle + { + get { return _NodesColumnsBackgroundStyle; } + set + { + if (_NodesColumnsBackgroundStyle != null) + _NodesColumnsBackgroundStyle.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + _NodesColumnsBackgroundStyle = value; + } + } + + private ElementStyle _ColumnsBackgroundStyle = null; + /// + /// Gets or sets the background style for the columns. Background style defines the appearance of the column header background. + /// + /// + /// Reference to the style assigned to the column header. + /// + /// ColumnStyleNormal Property + /// ColumnStyleMouseDown Property + /// ColumnStyleMouseOver Property + [Browsable(true), DefaultValue(null), Category("Column Header Style"), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the style class assigned to the column.")] + public ElementStyle ColumnsBackgroundStyle + { + get { return _ColumnsBackgroundStyle; } + set + { + if (_ColumnsBackgroundStyle != null) + _ColumnsBackgroundStyle.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + _ColumnsBackgroundStyle = value; + } + } + + /// + /// Gets or sets the default style class assigned to the column headers. + /// + /// + /// Reference to the style assigned to the column header. + /// + /// + /// When style is not set on ColumnHeader objects then style setting from this property is used instead. + /// + /// ColumnStyleMouseDown Property + /// ColumnStyleMouseOver Property + [Browsable(true), DefaultValue(null), Category("Column Header Style"), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the style class assigned to the column.")] + public ElementStyle ColumnStyleNormal + { + get { return m_ColumnStyleNormal; } + set + { + if (m_ColumnStyleNormal != null) + m_ColumnStyleNormal.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_ColumnStyleNormal = value; + } + } + + /// + /// Gets or sets default style class assigned to the column which is applied when mouse + /// button is pressed over the header. + /// + /// + /// Name of the style assigned to the column. + /// + /// + /// When style is not set on ColumnHeader objects then style setting from this property is used instead. + /// + /// ColumnStyleNormal Property + /// ColumnStyleMouseOver Property + [Browsable(true), DefaultValue(null), Category("Column Header Style"), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the style class assigned to the column when mouse is down.")] + public ElementStyle ColumnStyleMouseDown + { + get { return m_ColumnStyleMouseDown; } + set + { + if (m_ColumnStyleMouseDown != null) + m_ColumnStyleMouseDown.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_ColumnStyleMouseDown = value; + } + } + + /// + /// Gets or sets default style class assigned to the column which is applied when mouse is + /// over the column. + /// + /// + /// Name of the style assigned to the column. + /// + /// + /// When style is not set on ColumnHeader objects then style setting from this property is used instead. + /// + /// ColumnStyleNormal Property + /// ColumnStyleMouseDown Property + [Browsable(true), DefaultValue(null), Category("Column Header Style"), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the style class assigned to the cell when mouse is over the column.")] + public ElementStyle ColumnStyleMouseOver + { + get { return m_ColumnStyleMouseOver; } + set + { + if (m_ColumnStyleMouseOver != null) + m_ColumnStyleMouseOver.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_ColumnStyleMouseOver = value; + } + } + + /// + /// Gets collection that holds definition of column headers associated with nodes. + /// + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Description("Collection that holds definition of column headers associated with nodes.")] + internal HeadersCollection Headers + { + get { return m_Headers; } + } + + /// + /// Gets or sets the tree node that is currently selected in the tree control. + /// + /// + /// If no Node is currently selected, the + /// SelectedNode property is a null reference (Nothing in Visual + /// Basic). + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Node SelectedNode + { + get + { + if (_MultiSelect && m_SelectedNodes.Count > 0) + return m_SelectedNodes[m_SelectedNodes.Count - 1]; + return m_SelectedNode; + } + set + { + if (m_SelectedNode != value) + { + SelectNode(value, eTreeAction.Code); + } + } + } + + /// + /// Gets or sets the collection of currently selected nodes in tree control. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public NodeCollection SelectedNodes + { + get + { + return m_SelectedNodes; + } + } + + private bool _MultiSelect = false; + /// + /// Gets or sets whether multi-node selection is enabled. Default value is false. When + /// multi-selection is enabled use SelectedNodes property to retrive collection of selected nodes. + /// Use MultiSelectRule property to change the multi-node selection rule. + /// + [DefaultValue(false), Category("Selection"), Description("Indicates whether multi-node selection is enabled.")] + public bool MultiSelect + { + get { return _MultiSelect; } + set + { + if (_MultiSelect != value) + { + if (_MultiSelect) + m_SelectedNodes.Clear(); + _MultiSelect = value; + } + } + } + + private eMultiSelectRule _MultiSelectRule = eMultiSelectRule.SameParent; + /// + /// Gets or sets the rule that governs the multiple node selection. Default value indicates that only nodes + /// belonging to same parent can be multi-selected. + /// + [DefaultValue(eMultiSelectRule.SameParent), Category("Selection"), Description("Indicates rule that governs the multiple node selection.")] + public eMultiSelectRule MultiSelectRule + { + get { return _MultiSelectRule; } + set { _MultiSelectRule = value; } + } + + /// + /// Invalidates node bounds on canvas. + /// + /// Reference node. + internal void InvalidateNode(Node[] nodes) + { + foreach (Node node in nodes) + { + InvalidateNode(node); + } + } + + /// + /// Invalidates node bounds on canvas. + /// + /// Reference node. + internal void InvalidateNode(Node node) + { + if (node == null) + return; + + Rectangle r; + if (node == m_DragNode && m_DragNode.Parent == null) + r = m_DragNode.BoundsRelative; + else + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, node, m_NodeDisplay.Offset); + if (node.FullRowBackground) + { + r.Width = this.Width; + r.X = 0; + } + + //if (m_SelectionBox) + { + r.Inflate(m_SelectionBoxSize, m_SelectionBoxSize); + if (_SelectionBoxStyle == eSelectionStyle.FullRowSelect) + { + r.X = this.ClientRectangle.X; + r.Width = this.ClientRectangle.Width; + } + } + + if (this.NodeStyleMouseOver != null || this.CellStyleMouseOver != null || node.StyleMouseOver != null || this.NodeStyleMouseOver != null || _HotTracking) + r.Inflate(1, 1); + + r = GetScreenRectangle(r); + + this.Invalidate(r); + } + + /// + /// Finds the node based on the Node.Name property. + /// + /// Name of the node to find. + /// Reference to a node with given name or null if node cannot be found. + public Node FindNodeByName(string name) + { + return NodeOperations.FindNodeByName(this, name); + } + + /// + /// Finds the node based on the Node.DataKey property. + /// + /// Data key to look for. + /// Reference to a node with given key or null if node cannot be found. + public Node FindNodeByDataKey(object key) + { + return NodeOperations.FindNodeByDataKey(this, key); + } + + /// + /// Finds the node based on the Node.BindingIndex property. + /// + /// Index to look for. + /// Reference to a node with given key or null if node cannot be found. + public Node FindNodeByBindingIndex(int bindingIndex) + { + return NodeOperations.FindNodeByBindingIndex(this, bindingIndex); + } + + /// + /// Finds the first node that starts with the specified text. Node.Text property is searched. + /// + /// Partial text to look for + /// Reference to a node or null if no node is found. + public Node FindNodeByText(string text) + { + return NodeOperations.FindNodeByText(this, text, null, true); + } + + /// + /// Finds the first node where each Node.Cell[0:n].Text value starts with the + /// respective value found in the comma delimited 'text' string. + /// + /// Comma delimited partial text to look for + /// Reference to a node or null if no node is found. + public Node FindNodeByCellText(string text) + { + return NodeOperations.FindNodeByCellText(this, text, null, true); + } + + /// + /// Finds the first node that starts with the specified text. Node.Text property is searched. + /// + /// Partial text to look for + /// Controls whether case insensitive search is performed + /// Reference to a node or null if no node is found. + public Node FindNodeByText(string text, bool ignoreCase) + { + return NodeOperations.FindNodeByText(this, text, null, ignoreCase); + } + + /// + /// Finds the first node where each Node.Cell[0:n].Text value starts with the + /// respective value found in the comma delimited 'text' string. + /// + /// Comma delimited partial text to look for + /// Controls whether case insensitive search is performed + /// Reference to a node or null if no node is found. + public Node FindNodeByCellText(string text, bool ignoreCase) + { + return NodeOperations.FindNodeByCellText(this, text, null, ignoreCase); + } + + /// + /// Finds the first node that starts with the specified text. Node.Text property is searched. + /// + /// Partial text to look for + /// Reference node to start searching from + /// Controls whether case insensitive search is performed + /// Reference to a node or null if no node is found. + public Node FindNodeByText(string text, Node startFromNode, bool ignoreCase) + { + return NodeOperations.FindNodeByText(this, text, startFromNode, ignoreCase); + } + + /// + /// Finds the first node where each Node.Cell[0:n].Text value starts with the + /// respective value found in the comma delimited 'text' string. + /// + /// Comma delimited partial text to look for + /// Reference node to start searching from + /// Controls whether case insensitive search is performed + /// Reference to a node or null if no node is found. + public Node FindNodeByCellText(string text, Node startFromNode, bool ignoreCase) + { + return NodeOperations.FindNodeByCellText(this, text, startFromNode, ignoreCase); + } + + /// + /// Returns reference to node layout object. + /// + internal Layout.NodeLayout NodeLayout + { + get { return m_NodeLayout; } + } + + /// + /// Returns reference to node display object. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)] + public NodeDisplay NodeDisplay + { + get { return m_NodeDisplay; } + } + + /// + /// Gets whether layout is suspended for tree control. Layout is suspended after + /// call to BeginUpdate method and it is resumed after the + /// call to EndUpdate method. + /// + [Browsable(false)] + public bool IsUpdateSuspended + { + get { return (m_UpdateSuspended > 0); } + } + + internal void SetPendingLayout() + { + m_PendingLayout = true; + } + + /// + /// Gets whether control has layout operation pending on next paint or update. + /// + [Browsable(false)] + public bool IsLayoutPending + { + get { return m_PendingLayout; } + } + + + /// + /// Gets or sets whether paint operations are suspended for the control. You should use this method + /// if you need the RecalcLayout operations to proceed but you want to stop painting of the control. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool SuspendPaint + { + get { return m_SuspendPaint; } + set { m_SuspendPaint = value; } + } + + /// + /// Gets or sets the ImageList that contains the Image objects used by the tree nodes. + /// + [Browsable(true), DefaultValue(null), Category("Images"), Description("Indicates the ImageList that contains the Image objects used by the tree nodes.")] + public ImageList ImageList + { + get + { + return m_ImageList; + } + set + { + if (m_ImageList != null) + m_ImageList.Disposed -= new EventHandler(this.ImageListDisposed); + m_ImageList = value; + if (m_ImageList != null) + m_ImageList.Disposed += new EventHandler(this.ImageListDisposed); + } + } + + /// + /// Gets or sets the image-list index value of the default image that is displayed by the tree nodes. + /// + [Browsable(true), Category("Images"), Description("Indicates the image-list index value of the default image that is displayed by the tree nodes."), Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), TypeConverter(typeof(ImageIndexConverter)), DefaultValue(-1)] + public int ImageIndex + { + get { return m_ImageIndex; } + set + { + if (m_ImageIndex != value) + { + m_ImageIndex = value; + } + } + } + + private Image _CheckBoxImageChecked = null; + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box in cell is checked. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box in cell is checked")] + public Image CheckBoxImageChecked + { + get { return _CheckBoxImageChecked; } + set + { + _CheckBoxImageChecked = value; + OnCheckBoxImageChanged(); + } + } + private Image _CheckBoxImageUnChecked = null; + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box in cell is unchecked. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box in cell is unchecked")] + public Image CheckBoxImageUnChecked + { + get { return _CheckBoxImageUnChecked; } + set + { + _CheckBoxImageUnChecked = value; + OnCheckBoxImageChanged(); + } + } + private Image _CheckBoxImageIndeterminate = null; + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box in cell is in indeterminate state. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box in cell is in indeterminate state")] + public Image CheckBoxImageIndeterminate + { + get { return _CheckBoxImageIndeterminate; } + set + { + _CheckBoxImageIndeterminate = value; + OnCheckBoxImageChanged(); + } + } + private void OnCheckBoxImageChanged() + { + InvalidateNodesSize(); + SetPendingLayout(); + Invalidate(); + } + + ///// + ///// Gets or sets the NodeConnector object that describes the type of the connector used for + ///// displaying connection between root node and it's nested nodes. The root node is defined as + ///// the top level node i.e. which belongs directly to AdvTree.Nodes collection. Default value is null. + ///// + ///// + ///// You can use + ///// Node.ParentConnector + ///// property to specify per node connectors. + ///// + //[Browsable(true),Category("Connectors"),DefaultValue(null),Editor("DevComponents.AdvTree.Design.NodeConnectorTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf",typeof(System.Drawing.Design.UITypeEditor)),Description("Indicates the root node connector.")] + //public NodeConnector RootConnector + //{ + // get {return m_RootConnector;} + // set + // { + // if(m_RootConnector!=value) + // { + // if(m_RootConnector!=null) + // m_RootConnector.AppearanceChanged-=new EventHandler(this.ConnectorAppearanceChanged); + // if(value!=null) + // value.AppearanceChanged+=new EventHandler(this.ConnectorAppearanceChanged); + // m_RootConnector=value; + // this.OnDisplayChanged(); + // } + // } + //} + + /// + /// Gets or sets the NodeConnector object that describes the type of the connector used for + /// displaying connection between nested nodes. RootConnector property specifies the connector + /// between root node and it's imidate nested nodes. This property specifies connector for all other nested levels. + /// Default value is null. + /// + /// + /// You can use + /// Node.ParentConnector + /// property to specify per node connectors. + /// + [Browsable(true), Category("Connectors"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.NodeConnectorTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the nested nodes connector.")] + public NodeConnector NodesConnector + { + get { return m_NodesConnector; } + set + { + if (m_NodesConnector != value) + { + if (m_NodesConnector != null) + m_NodesConnector.AppearanceChanged -= new EventHandler(this.ConnectorAppearanceChanged); + if (value != null) + value.AppearanceChanged += new EventHandler(this.ConnectorAppearanceChanged); + m_NodesConnector = value; + this.OnDisplayChanged(); + } + } + } + + ///// + ///// Gets or sets the NodeConnector object that describes the type of the connector used for + ///// displaying connection between linked nodes. This property specifies connector for all linked nodes. + ///// Default value is null. + ///// + //[Browsable(true),Category("Connectors"),DefaultValue(null),Editor("DevComponents.AdvTree.Design.NodeConnectorTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf",typeof(System.Drawing.Design.UITypeEditor)),Description("Indicates the linked nodes connector.")] + //public NodeConnector LinkConnector + //{ + // get {return m_LinkConnector;} + // set + // { + // if(m_LinkConnector!=value) + // { + // if(m_LinkConnector!=null) + // m_LinkConnector.AppearanceChanged-=new EventHandler(this.ConnectorAppearanceChanged); + // if(value!=null) + // value.AppearanceChanged+=new EventHandler(this.ConnectorAppearanceChanged); + // m_LinkConnector=value; + // this.OnDisplayChanged(); + // } + // } + //} + + /// + /// Gets or sets the NodeConnector object that describes the type of the connector used for + /// displaying connection between linked nodes. Connector specified here is used to display the connection + /// between nodes that are on the path to the selected node. When set you can use it to visually indicate the path to the currently selected node. + /// Default value is null. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), Category("Connectors"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.NodeConnectorTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the linked nodes connector.")] + public NodeConnector SelectedPathConnector + { + get { return m_SelectedPathConnector; } + set + { + if (m_SelectedPathConnector != value) + { + if (m_SelectedPathConnector != null) + m_SelectedPathConnector.AppearanceChanged -= new EventHandler(this.ConnectorAppearanceChanged); + if (value != null) + value.AppearanceChanged += new EventHandler(this.ConnectorAppearanceChanged); + m_SelectedPathConnector = value; + this.OnDisplayChanged(); + } + } + } + + /// + /// Gets or sets the layout of the cells inside the node. Default value is Horizontal layout which + /// means that cell are positioned horizontally next to each other. + /// + /// + /// You can specify cell layout on each node by using + /// Node.CellLayout + /// property. + /// + [Browsable(true), DefaultValue(eCellLayout.Default), Category("Appearance"), Description("Indicates layout of the cells inside the node.")] + public eCellLayout CellLayout + { + get { return m_CellLayout; } + set + { + m_CellLayout = value; + InvalidateNodesSize(); + this.Invalidate(); + } + } + + /// + /// Gets or sets the layout of the cells inside the node. Default value is Horizontal layout which + /// means that cell are positioned horizontally next to each other. + /// + /// + /// You can specify cell layout on each node by using + /// Node.CellLayout + /// property. + /// + [Browsable(true), DefaultValue(eCellPartLayout.Default), Category("Appearance"), Description("Indicates layout of the cells inside the node.")] + public eCellPartLayout CellPartLayout + { + get { return m_CellPartLayout; } + set + { + m_CellPartLayout = value; + InvalidateNodesSize(); + this.Invalidate(); + } + } + + /// + /// Gets or sets the color scheme style. Color scheme provides predefined colors based on popular visual styles. + /// We recommend that you use "SchemePart" color settings since they maintain consistant look that is + /// based on target system color scheme setting. + /// + [Browsable(true), DefaultValue(eColorSchemeStyle.Office2007), Category("Appearance"), Description("Indicates the color scheme style.")] + public eColorSchemeStyle ColorSchemeStyle + { + get { return MapStyle(m_ColorScheme.Style); } + set + { + m_ColorScheme.Style = MapStyle(value); + if (this.DesignMode) + this.Refresh(); + } + } + + internal static eDotNetBarStyle MapStyle(eColorSchemeStyle style) + { + if (style == eColorSchemeStyle.Office2003) + return eDotNetBarStyle.Office2003; + else if (style == eColorSchemeStyle.VS2005) + return eDotNetBarStyle.VS2005; + return eDotNetBarStyle.Office2007; + } + internal static eColorSchemeStyle MapStyle(eDotNetBarStyle style) + { + if (style == eDotNetBarStyle.Office2003) + return eColorSchemeStyle.Office2003; + else if (style == eDotNetBarStyle.VS2005) + return eColorSchemeStyle.VS2005; + + return eColorSchemeStyle.Office2007; + } + + /// + /// Gets the reference to the color scheme object. + /// + internal ColorScheme ColorScheme + { + get + { + if (ColorSchemeStyle == eColorSchemeStyle.Office2007 && DevComponents.DotNetBar.Rendering.GlobalManager.Renderer is DevComponents.DotNetBar.Rendering.Office2007Renderer) + { + return ((DevComponents.DotNetBar.Rendering.Office2007Renderer)DevComponents.DotNetBar.Rendering.GlobalManager.Renderer).ColorTable.LegacyColors; + } + return m_ColorScheme; + } + } + + /// + /// Gets or sets whether the content of the control is centered within the bounds of control. Default value is true. + /// + [Browsable(true), DefaultValue(true), Description("Indicates whether the content of the control is centered within the bounds of control."), Category("Layout")] + internal bool CenterContent + { + get { return m_CenterContent; } + set + { + m_CenterContent = value; + OnLayoutChanged(); + } + } + + private bool _SelectionPerCell = false; + /// + /// Gets or sets whether per cell selection mode is enabled. In cell selection mode the selection box is drawn over selected cell only + /// instead of all cells in the node. + /// Default value is false. + /// + [DefaultValue(false), Category("Selection"), Description("Indicates whether selection is drawn for selected cell only instead of all cells inside of node")] + public bool SelectionPerCell + { + get { return _SelectionPerCell; } + set + { + if (_SelectionPerCell != value) + { + _SelectionPerCell = value; + if (this.SelectedNode != null) + { + InvalidateNode(this.SelectedNode); + } + } + } + } + + private bool _SelectionFocusAware = true; + /// + /// Gets or sets whether selection appearance changes depending on whether control has input focus. Default value is true. Setting this value to false causes selection box to be rendered as if control has focus all the time. + /// + [DefaultValue(true), Category("Selection"), Description("Indicates whether selection appearance changes depending on whether control has input focus.")] + public bool SelectionFocusAware + { + get { return _SelectionFocusAware; } + set + { + if (_SelectionFocusAware != value) + { + _SelectionFocusAware = value; + this.Invalidate(); + } + } + } + + + private eSelectionStyle _SelectionBoxStyle = eSelectionStyle.HighlightCells; + /// + /// Gets or sets the node selection box style. + /// + /// SelectionBox Property + /// SelectionBoxSize Property + /// SelectionBoxFillColor Property + /// SelectionBoxBorderColor Property + [DefaultValue(eSelectionStyle.HighlightCells), Category("Selection"), Description("Indicates node selection box style.")] + public eSelectionStyle SelectionBoxStyle + { + get { return _SelectionBoxStyle; } + set { _SelectionBoxStyle = value; } + } + + /// + /// Gets or sets the value that indicates whether selection box is drawn around the + /// selected node. Default value is true. Another way to provide the visual indication that + /// node is selected is by using selected state style properties like + /// NodeStyleSelected + /// and + /// CellStyleSelected. + /// + /// CellStyleSelected Property + /// NodeStyleSelected Property + [Browsable(true), DefaultValue(true), Category("Selection"), Description("Indicates whether selection box is drawn around selected node.")] + public bool SelectionBox + { + get { return m_SelectionBox; } + set + { + if (m_SelectionBox != value) + { + m_SelectionBox = value; + this.OnSelectionBoxChanged(); + } + } + } + + /// + /// Gets or sets the size/thickness in pixel of the selection box drawn around selected + /// node. + /// + [Browsable(true), DefaultValue(4), Category("Selection"), Description("Indicates the size in pixels of the selection box drawn around selected node.")] + internal int SelectionBoxSize + { + get { return m_SelectionBoxSize; } + set + { + if (m_SelectionBoxSize != value) + { + m_SelectionBoxSize = value; + this.OnSelectionBoxChanged(); + } + } + } + + private bool _FullRowSelect = true; + /// + /// Gets or sets whether node is selected when mouse is pressed anywhere within node vertical bounds. Default value is true. + /// + /// + /// When set to false the node is selected only when mouse is pressed over the node content. + /// + [DefaultValue(true), Description("Indicates whether node is selected when mouse is pressed anywhere within node vertical bounds."), Category("Selection")] + public bool FullRowSelect + { + get { return _FullRowSelect; } + set + { + _FullRowSelect = value; + } + } + + + ///// + ///// Gets or sets the selection box border color. + ///// + //[Browsable(true),Category("Selection"),Description("Indicates the selection box border color.")] + //public Color SelectionBoxBorderColor + //{ + // get {return m_SelectionBoxBorderColor;} + // set + // { + // if(m_SelectionBoxBorderColor!=value) + // { + // m_SelectionBoxBorderColor=value; + // this.OnSelectionBoxChanged(); + // } + // } + + //} + ///// + ///// Indicates whether SelectionBoxBorderColor should be serialized. Used by windows forms designer design-time support. + ///// + //[EditorBrowsable(EditorBrowsableState.Never)] + //public bool ShouldSerializeSelectionBoxBorderColor() + //{return (m_SelectionBoxBorderColor!=GetDefaultSelectionBoxBorderColor());} + ///// + ///// Resets SelectionBoxBorderColor to it's default value. Used by windows forms designer design-time support. + ///// + //[EditorBrowsable(EditorBrowsableState.Never)] + //public void ResetSelectionBoxBorderColor() + //{ + // m_SelectionBoxBorderColor=GetDefaultSelectionBoxBorderColor(); + //} + + ///// + ///// Gets or sets the selection box fill color. + ///// + //[Browsable(true),Category("Selection"),Description("Indicates the selection box fill color.")] + //public Color SelectionBoxFillColor + //{ + // get {return m_SelectionBoxFillColor;} + // set + // { + // if(m_SelectionBoxFillColor!=value) + // { + // m_SelectionBoxFillColor=value; + // this.OnSelectionBoxChanged(); + // } + // } + + //} + ///// + ///// Indicates whether SelectionBoxFillColor should be serialized. Used by windows forms designer design-time support. + ///// + //[EditorBrowsable(EditorBrowsableState.Never)] + //public bool ShouldSerializeSelectionBoxFillColor() + //{return (m_SelectionBoxFillColor!=GetDefaultSelectionBoxFillColor());} + ///// + ///// Resets SelectionBoxFillColor to it's default value. Used by windows forms designer design-time support. + ///// + //[EditorBrowsable(EditorBrowsableState.Never)] + //public void ResetSelectionBoxFillColor() + //{ + // m_SelectionBoxFillColor=GetDefaultSelectionBoxFillColor(); + //} + + private int _ExpandWidth = 24; + /// + /// Gets or sets the total node expand area width in pixels. The expand button with ExpandButtonSize is fitted into this area. Default value is 24. + /// + [DefaultValue(24), Category("Expand Button"), Description("Indicates total node expand area width in pixels.")] + public int ExpandWidth + { + get { return _ExpandWidth; } + set + { + if (_ExpandWidth != value) + { + _ExpandWidth = value; + _LayoutSettings.ExpandAreaWidth = value; + this.InvalidateNodesSize(); + this.Invalidate(); + } + } + } + + + /// + /// Gets or sets the size of the expand button that is used to expand/collapse node. Default value is 8,8. + /// + [Browsable(true), Category("Expand Button"), Description("Indicates size of the expand button that is used to expand/collapse node.")] + public Size ExpandButtonSize + { + get { return m_ExpandButtonSize; } + set + { + if (m_ExpandButtonSize != value) + { + m_ExpandButtonSize = value; + this.OnExpandButtonChanged(); + } + } + } + /// + /// Indicates whether SelectionBoxFillColor should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeExpandButtonSize() + { return (m_ExpandButtonSize != GetDefaultExpandButtonSize()); } + /// + /// Resets SelectionBoxFillColor to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetExpandButtonSize() + { + this.ExpandButtonSize = GetDefaultExpandButtonSize(); + } + + /// + /// Gets or sets expand button border color. Note that setting ExpandBorderColorSchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Expand Button"), Description("Indicates expand button border color.")] + public Color ExpandBorderColor + { + get { return m_ExpandBorderColor; } + set + { + m_ExpandBorderColor = value; + this.OnExpandButtonChanged(); + } + } + /// + /// Indicates whether ExpandBorderColor should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeExpandBorderColor() + { return (!m_ExpandBorderColor.IsEmpty && m_ExpandBorderColorSchemePart == eColorSchemePart.None); } + /// + /// Resets ExpandBorderColor to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetExpandBorderColor() + { + this.ExpandBorderColor = Color.Empty; + } + /// + /// Gets or sets expand button color scheme border color. Setting + /// this property overrides the setting of the corresponding ExpandBorderColor property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through ExpandBorderColor property. + /// + [Browsable(true), Category("Expand Button"), DefaultValue(eColorSchemePart.None), Description("Indicates expand button border color.")] + public eColorSchemePart ExpandBorderColorSchemePart + { + get { return m_ExpandBorderColorSchemePart; } + set + { + m_ExpandBorderColorSchemePart = value; + this.OnExpandButtonChanged(); + } + } + + /// + /// Gets or sets expand button back color. Note that setting ExpandBackColorSchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Expand Button"), Description("Indicates expand button back color.")] + public Color ExpandBackColor + { + get { return m_ExpandBackColor; } + set + { + m_ExpandBackColor = value; + this.OnExpandButtonChanged(); + } + } + /// + /// Indicates whether ExpandBackColor should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeExpandBackColor() + { return (!m_ExpandBackColor.IsEmpty && m_ExpandBackColorSchemePart == eColorSchemePart.None); } + /// + /// Resets ExpandBackColor to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetExpandBackColor() + { + this.ExpandBackColor = Color.Empty; + } + /// + /// Gets or sets expand button color scheme back color. Setting + /// this property overrides the setting of the corresponding ExpandBackColor property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through ExpandBackColor property. + /// + [Browsable(true), Category("Expand Button"), DefaultValue(eColorSchemePart.None), Description("Indicates expand button back color.")] + public eColorSchemePart ExpandBackColorSchemePart + { + get { return m_ExpandBackColorSchemePart; } + set + { + m_ExpandBackColorSchemePart = value; + this.OnExpandButtonChanged(); + } + } + + /// + /// Gets or sets expand button target gradientback color. Note that setting ExpandBackColor2SchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Expand Button"), Description("Indicates expand button target gradient back color.")] + public Color ExpandBackColor2 + { + get { return m_ExpandBackColor2; } + set + { + m_ExpandBackColor2 = value; + this.OnExpandButtonChanged(); + } + } + /// + /// Indicates whether ExpandBackColor2 should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeExpandBackColor2() + { return (!m_ExpandBackColor2.IsEmpty && m_ExpandBackColor2SchemePart == eColorSchemePart.None); } + /// + /// Resets ExpandBackColor2 to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetExpandBackColor2() + { + this.ExpandBackColor2 = Color.Empty; + } + /// + /// Gets or sets expand button color scheme target gradient back color. Setting + /// this property overrides the setting of the corresponding ExpandBackColor2 property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through ExpandBackColor2 property. + /// + [Browsable(true), Category("Expand Button"), DefaultValue(eColorSchemePart.None), Description("Indicates expand button target gradient back color.")] + public eColorSchemePart ExpandBackColor2SchemePart + { + get { return m_ExpandBackColor2SchemePart; } + set + { + m_ExpandBackColor2SchemePart = value; + this.OnExpandButtonChanged(); + } + } + + /// + /// Gets or sets expand button line color. Note that setting ExpandLineColorSchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Expand Button"), Description("Indicates expand button line color.")] + public Color ExpandLineColor + { + get { return m_ExpandLineColor; } + set + { + m_ExpandLineColor = value; + this.OnExpandButtonChanged(); + } + } + /// + /// Indicates whether ExpandLineColor should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeExpandLineColor() + { return (!m_ExpandLineColor.IsEmpty && m_ExpandLineColorSchemePart == eColorSchemePart.None); } + /// + /// Resets ExpandLineColor to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetExpandLineColor() + { + this.ExpandLineColor = Color.Empty; + } + /// + /// Gets or sets expand button color scheme line color. Setting + /// this property overrides the setting of the corresponding ExpandLineColor property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through ExpandLineColor property. + /// + [Browsable(true), Category("Expand Button"), DefaultValue(eColorSchemePart.None), Description("Indicates expand button line color.")] + public eColorSchemePart ExpandLineColorSchemePart + { + get { return m_ExpandLineColorSchemePart; } + set + { + m_ExpandLineColorSchemePart = value; + this.OnExpandButtonChanged(); + } + } + + /// + /// Gets or sets the expand button background gradient angle. + /// + [Browsable(true), Category("Expand Button"), DefaultValue(0), Description("Indicates expand button background gradient angle.")] + public int ExpandBackColorGradientAngle + { + get + { + return m_ExpandBackColorGradientAngle; + } + set + { + if (m_ExpandBackColorGradientAngle != value) + { + m_ExpandBackColorGradientAngle = value; + this.OnExpandButtonChanged(); + + } + } + } + + /// + /// Gets or sets the expand button image which is used to indicate that node will be expanded. To use images as expand buttons you also need to set ExpandButtonType=eExpandButtonType.Image. + /// + [Browsable(true), DefaultValue(null), Description("Indicates expand button image which is used to indicate that node will be expanded."), Category("Expand Button")] + public Image ExpandImage + { + get { return m_ExpandImage; } + set + { + if (m_ExpandImage != value) + { + m_ExpandImage = value; + if (m_ExpandButtonType == eExpandButtonType.Image) + this.OnExpandButtonChanged(); + } + } + } + + /// + /// Gets or sets the expand button image which is used to indicate that node will be collapsed. To use images as expand buttons you also need to set ExpandButtonType=eExpandButtonType.Image. + /// + [Browsable(true), DefaultValue(null), Description("Indicates expand button image which is used to indicate that node will be collapsed."), Category("Expand Button")] + public Image ExpandImageCollapse + { + get { return m_ExpandImageCollapse; } + set + { + if (m_ExpandImageCollapse != value) + { + m_ExpandImageCollapse = value; + if (m_ExpandButtonType == eExpandButtonType.Image) + this.OnExpandButtonChanged(); + } + } + } + + /// + /// Gets or sets the type of the expand button used to expand/collapse nodes. + /// + [Browsable(true), DefaultValue(eExpandButtonType.Rectangle), Category("Expand Button"), Description("Indicates type of the expand button used to expand/collapse nodes.")] + public eExpandButtonType ExpandButtonType + { + get { return m_ExpandButtonType; } + set + { + if (m_ExpandButtonType != value) + { + m_ExpandButtonType = value; + this.OnExpandButtonChanged(); + } + } + } + + /// + /// Gets or sets the display root node. Setting this property allows you to use any + /// Node as root display node. Default value is Null which means that first node from + /// AdvTree.Nodes collection is used as display root node. + /// + [Browsable(true), DefaultValue(null), Category("Appearance"), Description("Indicates display root node.")] + public Node DisplayRootNode + { + get { return m_DisplayRootNode; } + set + { + if (m_DisplayRootNode != value) + { + m_DisplayRootNode = value; + if (m_NodeDisplay != null) m_NodeDisplay.PaintedNodes.Clear(); + InvalidateNodesSize(); + this.RecalcLayout(); + this.Refresh(); + } + } + } + + /// + /// Gets or sets the width of the command button. Default value is 10 pixels. + /// + [Browsable(true), Category("Command Button"), DefaultValue(10), Description("Indicates width of the command button.")] + internal int CommandWidth + { + get { return m_CommandWidth; } + set + { + m_CommandWidth = value; + OnCommandButtonChanged(); + } + } + + /// + /// Gets or sets command button back color. Note that setting CommandBackColorSchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Command Button"), Description("Indicates command button back color.")] + internal Color CommandBackColor + { + get { return m_CommandBackColor; } + set + { + m_CommandBackColor = value; + this.OnCommandButtonChanged(); + } + } + /// + /// Indicates whether CommandBackColor should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeCommandBackColor() + { return (!m_CommandBackColor.IsEmpty && m_CommandBackColorSchemePart == eColorSchemePart.None); } + /// + /// Resets CommandBackColor to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetCommandBackColor() + { + this.CommandBackColor = Color.Empty; + } + /// + /// Gets or sets command button color scheme back color. Setting + /// this property overrides the setting of the corresponding CommandBackColor property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through CommandBackColor property. + /// + [Browsable(true), Category("Command Button"), DefaultValue(eColorSchemePart.CustomizeBackground), Description("Indicates command button back color.")] + internal eColorSchemePart CommandBackColorSchemePart + { + get { return m_CommandBackColorSchemePart; } + set + { + m_CommandBackColorSchemePart = value; + this.OnCommandButtonChanged(); + } + } + + /// + /// Gets or sets command button target gradient back color. Note that setting CommandBackColor2SchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Command Button"), Description("Indicates command button target gradient back color.")] + internal Color CommandBackColor2 + { + get { return m_CommandBackColor2; } + set + { + m_CommandBackColor2 = value; + this.OnCommandButtonChanged(); + } + } + /// + /// Indicates whether CommandBackColor2 should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeCommandBackColor2() + { return (!m_CommandBackColor2.IsEmpty && m_CommandBackColor2SchemePart == eColorSchemePart.None); } + /// + /// Resets CommandBackColor2 to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetCommandBackColor2() + { + this.CommandBackColor2 = Color.Empty; + } + /// + /// Gets or sets command button color scheme target gradient back color. Setting + /// this property overrides the setting of the corresponding CommandBackColor2 property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through CommandBackColor2 property. + /// + [Browsable(true), Category("Command Button"), DefaultValue(eColorSchemePart.CustomizeBackground2), Description("Indicates command button target gradient back color.")] + internal eColorSchemePart CommandBackColor2SchemePart + { + get { return m_CommandBackColor2SchemePart; } + set + { + m_CommandBackColor2SchemePart = value; + this.OnCommandButtonChanged(); + } + } + + /// + /// Gets or sets command button foreground color. Note that setting CommandForeColorSchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Command Button"), Description("Indicates command button fore color.")] + internal Color CommandForeColor + { + get { return m_CommandForeColor; } + set + { + m_CommandForeColor = value; + this.OnCommandButtonChanged(); + } + } + /// + /// Indicates whether CommandForeColor should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeCommandForeColor() + { return (!m_CommandForeColor.IsEmpty && m_CommandForeColorSchemePart == eColorSchemePart.None); } + /// + /// Resets CommandForeColor to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetCommandForeColor() + { + this.CommandForeColor = Color.Empty; + } + /// + /// Gets or sets command button color scheme foreground color. Setting + /// this property overrides the setting of the corresponding CommandForeColor property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through CommandForeColor property. + /// + [Browsable(true), Category("Command Button"), DefaultValue(eColorSchemePart.CustomizeText), Description("Indicates command button foreground color.")] + internal eColorSchemePart CommandForeColorSchemePart + { + get { return m_CommandForeColorSchemePart; } + set + { + m_CommandForeColorSchemePart = value; + this.OnCommandButtonChanged(); + } + } + + /// + /// Gets or sets the command button background gradient angle. + /// + [Browsable(true), Category("Expand Button"), DefaultValue(0), Description("Indicates command button background gradient angle.")] + internal int CommandBackColorGradientAngle + { + get + { + return m_CommandBackColorGradientAngle; + } + set + { + if (m_CommandBackColorGradientAngle != value) + { + m_CommandBackColorGradientAngle = value; + this.OnExpandButtonChanged(); + + } + } + } + + /// + /// Gets or sets command button mouse over back color. Note that setting CommandMouseOverBackColorSchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Command Button"), Description("Indicates command button mouse over back color.")] + internal Color CommandMouseOverBackColor + { + get { return m_CommandMouseOverBackColor; } + set + { + m_CommandMouseOverBackColor = value; + this.OnCommandButtonChanged(); + } + } + /// + /// Indicates whether CommandMouseOverBackColor should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeCommandMouseOverBackColor() + { return (!m_CommandMouseOverBackColor.IsEmpty && m_CommandMouseOverBackColorSchemePart == eColorSchemePart.None); } + /// + /// Resets CommandMouseOverBackColor to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetCommandMouseOverBackColor() + { + this.CommandMouseOverBackColor = Color.Empty; + } + /// + /// Gets or sets command button color scheme mouse over back color. Setting + /// this property overrides the setting of the corresponding CommandMouseOverBackColor property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through CommandMouseOverBackColor property. + /// + [Browsable(true), Category("Command Button"), DefaultValue(eColorSchemePart.ItemHotBackground), Description("Indicates command button mouse over back color.")] + internal eColorSchemePart CommandMouseOverBackColorSchemePart + { + get { return m_CommandMouseOverBackColorSchemePart; } + set + { + m_CommandMouseOverBackColorSchemePart = value; + this.OnCommandButtonChanged(); + } + } + + /// + /// Gets or sets command button mouse over target gradient back color. Note that setting CommandMouseOverBackColor2SchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Command Button"), Description("Indicates command button mouse over target gradient back color.")] + internal Color CommandMouseOverBackColor2 + { + get { return m_CommandMouseOverBackColor2; } + set + { + m_CommandMouseOverBackColor2 = value; + this.OnCommandButtonChanged(); + } + } + /// + /// Indicates whether CommandMouseOverBackColor2 should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeCommandMouseOverBackColor2() + { return (!m_CommandMouseOverBackColor2.IsEmpty && m_CommandMouseOverBackColor2SchemePart == eColorSchemePart.None); } + /// + /// Resets CommandMouseOverBackColor2 to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetCommandMouseOverBackColor2() + { + this.CommandMouseOverBackColor2 = Color.Empty; + } + /// + /// Gets or sets command button mouse over color scheme target gradient back color. Setting + /// this property overrides the setting of the corresponding CommandMouseOverBackColor2 property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through CommandMouseOverBackColor2 property. + /// + [Browsable(true), Category("Command Button"), DefaultValue(eColorSchemePart.ItemPressedBackground2), Description("Indicates command button mouse over target gradient back color.")] + internal eColorSchemePart CommandMouseOverBackColor2SchemePart + { + get { return m_CommandMouseOverBackColor2SchemePart; } + set + { + m_CommandMouseOverBackColor2SchemePart = value; + this.OnCommandButtonChanged(); + } + } + + /// + /// Gets or sets command button mouse over foreground color. Note that setting CommandMouseOverForeColorSchemePart property will override the value that you set here. + /// + [Browsable(true), Category("Command Button"), Description("Indicates command button mouse over fore color.")] + internal Color CommandMouseOverForeColor + { + get { return m_CommandMouseOverForeColor; } + set + { + m_CommandMouseOverForeColor = value; + this.OnCommandButtonChanged(); + } + } + /// + /// Indicates whether CommandMouseOverForeColor should be serialized. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeCommandMouseOverForeColor() + { return (!m_CommandMouseOverForeColor.IsEmpty && m_CommandMouseOverForeColorSchemePart == eColorSchemePart.None); } + /// + /// Resets CommandMouseOverForeColor to it's default value. Used by windows forms designer design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetCommandMouseOverForeColor() + { + this.CommandMouseOverForeColor = Color.Empty; + } + /// + /// Gets or sets command button mouse over color scheme foreground color. Setting + /// this property overrides the setting of the corresponding CommandMouseOverForeColor property. + /// Color scheme colors are automatically managed and are based on current system colors. + /// That means if colors on the system change the color scheme will ensure that it's colors + /// are changed as well to fit in the color scheme of target system. Set this property to + /// eColorSchemePart.None to + /// specify explicit color to use through CommandMouseOverForeColor property. + /// + [Browsable(true), Category("Command Button"), DefaultValue(eColorSchemePart.ItemHotText), Description("Indicates command button mouse over foreground color.")] + internal eColorSchemePart CommandMouseOverForeColorSchemePart + { + get { return m_CommandMouseOverForeColorSchemePart; } + set + { + m_CommandMouseOverForeColorSchemePart = value; + this.OnCommandButtonChanged(); + } + } + + /// + /// Gets or sets the command button mouse over background gradient angle. + /// + [Browsable(true), Category("Expand Button"), DefaultValue(0), Description("Indicates command button mouse over background gradient angle.")] + internal int CommandMouseOverBackColorGradientAngle + { + get + { + return m_CommandMouseOverBackColorGradientAngle; + } + set + { + if (m_CommandMouseOverBackColorGradientAngle != value) + { + m_CommandMouseOverBackColorGradientAngle = value; + this.OnExpandButtonChanged(); + + } + } + } + + /// + /// Gets or sets a value indicating whether the label text of the node cells can be edited. Default value is false. + /// + [Browsable(true), DefaultValue(false), Description("Indicates whether the label text of the node cells can be edited."), Category("Editing")] + public bool CellEdit + { + get { return m_CellEdit; } + set { m_CellEdit = value; } + } + + /// + /// Returns whether cell editing is in progress. + /// + [Browsable(false)] + public bool IsCellEditing + { + get { return m_CellEditing; } + } + + /// + /// Returns the zero based flat index of the node. Flat index is the index of the node as if tree structure + /// has been flattened into the list. + /// + /// Reference to the node to return index for. + /// Zero based node index or -1 if index cannot be determined. + public int GetNodeFlatIndex(Node node) + { + return NodeOperations.GetNodeFlatIndex(this, node); + } + + /// + /// Returns node based on the flat index. Flat index is the index of the node as if tree structure + /// has been flattened into the list. + /// + /// Index to return node for. + /// Reference to a node or null if node at specified index cannot be found. + public Node GetNodeByFlatIndex(int index) + { + return NodeOperations.GetNodeByFlatIndex(this, index); + } + #endregion + + #region Private implementation + private bool _AccessibleObjectCreated = false; + protected override AccessibleObject CreateAccessibilityInstance() + { + _AccessibleObjectCreated = true; + return new AdvTreeAccessibleObject(this); + } + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + if (Dpi.RecordScalePerControl) + Dpi.SetScaling(factor); + ScaleHostedControls(factor); + this.InvalidateNodesSize(); + if (_VScrollBar != null) _VScrollBar.UpdateScaling(factor); + if (_HScrollBar != null) _HScrollBar.UpdateScaling(factor); + base.ScaleControl(factor, specified); + } + + private void ScaleHostedControls(SizeF factor) + { + foreach (Cell cell in m_HostedControlCells) + { + System.Windows.Forms.Control cellHostedControl = cell.HostedControl; + if (cellHostedControl == null) continue; + cellHostedControl.Scale(factor); + } + } + + protected override bool ScaleChildren + { + get { return false; } + } + + /// + /// Returns color scheme part color if set otherwise returns color passed in. + /// + /// Color. + /// Color scheme part. + /// Color. + internal Color GetColor(Color color, eColorSchemePart p) + { + if (p == eColorSchemePart.None || p == eColorSchemePart.Custom) + return color; + ColorScheme cs = this.ColorScheme; + if (cs == null) + return color; + return (Color)cs.GetType().GetProperty(p.ToString()).GetValue(cs, null); + } + private void OnExpandButtonChanged() + { + _LayoutSettings.ExpandPartSize = m_ExpandButtonSize; + this.InvalidateNodesSize(); + this.RecalcLayout(); + this.Refresh(); + } + private Size GetDefaultExpandButtonSize() + { + return m_DefaultExpandPartSize; + } + private void ElementStyleChanged(object sender, EventArgs e) + { + this.InvalidateNodesSize(); + if (this.DesignMode) + this.RecalcLayout(); + this.OnDisplayChanged(); + } + private void OnDisplayChanged() + { + if (this.DesignMode) + this.Refresh(); + } + private void OnLayoutChanged() + { + _LayoutSettings.NodeHorizontalSpacing = m_NodeHorizontalSpacing; + _LayoutSettings.NodeVerticalSpacing = m_NodeVerticalSpacing; + + //// Layout specific properties + //if (m_Layout == eNodeLayout.Diagram) + //{ + // Layout.NodeDiagramLayout nd = m_NodeLayout as Layout.NodeDiagramLayout; + // nd.DiagramFlow = m_DiagramLayoutFlow; + //} + //else if (m_Layout == eNodeLayout.Map) + //{ + // NodeMapLayout nd = m_NodeLayout as NodeMapLayout; + // nd.MapFlow = m_MapLayoutFlow; + //} + + this.RecalcLayout(); + OnDisplayChanged(); + } + private void ConnectorAppearanceChanged(object sender, EventArgs e) + { + OnDisplayChanged(); + } + //private void SetLayout(eNodeLayout layout) + //{ + // m_Layout=layout; + // if(m_Layout==eNodeLayout.Map) + // { + // m_NodeLayout=new NodeMapLayout(this,this.ClientRectangle); + // } + // else if(m_Layout==eNodeLayout.Diagram) + // { + // m_NodeLayout=new Layout.NodeDiagramLayout(this,this.ClientRectangle); + // } + // InvalidateNodesSize(); + // OnLayoutChanged(); + //} + + /// + /// Collapses all nodes in a tree. + /// + public void CollapseAll() + { + this.BeginUpdate(); + try + { + foreach (Node item in this.Nodes) + { + item.CollapseAll(); + } + } + finally + { + this.EndUpdate(true); + } + } + + /// + /// Expands all the tree nodes. + /// + public void ExpandAll() + { + this.BeginUpdate(); + try + { + foreach (Node item in this.Nodes) + { + item.Expand(); + item.ExpandAll(); + } + } + finally + { + this.EndUpdate(true); + } + } + + private void PaintStyleBackground(Graphics g) + { + Display.TreeRenderer renderer = this.NodeRenderer; + if (renderer != null) + { + this.NodeRenderer.DrawTreeBackground(new TreeBackgroundRendererEventArgs(g, this)); + return; + } + + if (!this.BackColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(this.BackColor)) + g.FillRectangle(brush, this.DisplayRectangle); + } + + ElementStyleDisplayInfo info = new ElementStyleDisplayInfo(); + info.Bounds = this.DisplayRectangle; + info.Graphics = g; + bool disposeStyle = false; + ElementStyle style = ElementStyleDisplay.GetElementStyle(m_BackgroundStyle, out disposeStyle); + info.Style = style; + ElementStyleDisplay.Paint(info); + if (disposeStyle) + style.Dispose(); + } + + protected override void OnPaint(PaintEventArgs e) + { + if (this.SuspendPaint) + return; + + try + { + if (m_PendingLayout) + { + this.RecalcLayout(); + } + + if (this.BackColor.A < 255) + { + base.OnPaintBackground(e); + } + + Graphics g = e.Graphics; + + PaintStyleBackground(g); + Point offset = Point.Empty; + bool setOffset = false; + if (this.AutoScroll) + { + offset = GetAutoScrollPositionOffset(); + setOffset = true; + } + else if (this.SelectionBoxStyle == eSelectionStyle.NodeMarker) + { + offset.X += this.SelectionBoxSize; + offset.Y += this.SelectionBoxSize; + setOffset = true; + } + + SmoothingMode sm = g.SmoothingMode; + TextRenderingHint th = g.TextRenderingHint; + if (m_AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + Rectangle clipRect = GetInnerRectangle(); + if (_VScrollBar != null) clipRect.Width -= _VScrollBar.Width; + if (_HScrollBar != null) clipRect.Height -= _HScrollBar.Height; + g.SetClip(clipRect); + + PaintTree(g, e.ClipRectangle, offset, setOffset, m_ZoomFactor); + + if (_ColumnMoveMarkerIndex >= 0 && _ColumnReorder != null && _ColumnReorder.Parent != m_Columns) + DevComponents.AdvTree.Display.ColumnHeaderDisplay.PaintColumnMoveMarker(g, this, _ColumnMoveMarkerIndex, _ColumnReorder.Parent); + + if (m_AntiAlias) + { + g.SmoothingMode = sm; + g.TextRenderingHint = th; + } + } + finally + { + base.OnPaint(e); + } + } + + internal Rectangle GetInnerRectangle() + { + Rectangle r = ElementStyleLayout.GetInnerRect(this.BackgroundStyle, this.ClientRectangle); + return r; + } + + internal Point GetAutoScrollPositionOffset() + { + Point p = this.AutoScrollPosition; + if (this.SelectionBoxStyle == eSelectionStyle.NodeMarker) + { + p.Y += this.SelectionBoxSize; + p.X += this.SelectionBoxSize; + } + return p; + } + + private void PaintTree(Graphics g, Rectangle clipRectangle, Point offset, bool setOffset, float zoomFactor) + { + +#if TRIAL + if(NodeOperations.ColorExpAlt()) + { + StringFormat format=new StringFormat(StringFormat.GenericDefault); + format.Alignment=StringAlignment.Center; + format.FormatFlags=format.FormatFlags & ~(format.FormatFlags & StringFormatFlags.NoWrap); + g.DrawString("Thank you very much for trying AdvTree. Unfortunately your trial period is over. To continue using AdvTree you should purchase license at http://www.devcomponents.com",new Font(this.Font.FontFamily,12),SystemBrushes.Highlight,this.ClientRectangle,format); + format.Dispose(); + return; + } +#else + if (NodeOperations.keyValidated2 != 114) + { + Font trial = new Font(this.Font.FontFamily, 7); + SolidBrush brushTrial = new SolidBrush(Color.FromArgb(200, SystemColors.Highlight)); + StringFormat format = new StringFormat(StringFormat.GenericDefault); + format.Alignment = StringAlignment.Center; + g.DrawString("DotNetBar AdvTree license not found. Please purchase license at http://www.devcomponents.com", + trial, brushTrial, this.DisplayRectangle.X + this.DisplayRectangle.Width / 2, this.DisplayRectangle.Bottom - 14, format); + brushTrial.Dispose(); + format.Dispose(); + trial.Dispose(); + } +#endif + + //Creates the drawing matrix with the right zoom; + if (zoomFactor != 1) + { + System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix(zoomFactor); + //use it for drawing + g.Transform = mx; + + // Translate ClipRectangle + clipRectangle = GetLayoutRectangle(clipRectangle); + } + + if (setOffset) + { + m_NodeDisplay.Offset = offset; + } + OnRender(new AdvTreeRenderEventArgs(eAdvTreeRenderType.Background, g)); + m_NodeDisplay.Paint(g, clipRectangle); + +#if TRIAL + Font trial=new Font(this.Font.FontFamily,7); + SolidBrush brushTrial = new SolidBrush(Color.FromArgb(220, SystemColors.Highlight)); + StringFormat formatTrial=new StringFormat(StringFormat.GenericDefault); + formatTrial.Alignment=StringAlignment.Center; + g.DrawString("Thank you for trying AdvTree. Please purchase license at http://www.devcomponents.com", + trial, brushTrial, this.DisplayRectangle.X+this.DisplayRectangle.Width/2, this.DisplayRectangle.Bottom - 14, formatTrial); + brushTrial.Dispose(); + formatTrial.Dispose(); + trial.Dispose(); +#endif + } + + /// + /// Paints control to canvas. This method might be used for print output. + /// + /// Graphics object to paint control to. + /// Indicates whether to paint control background. + public void PaintTo(Graphics g, bool background) + { + PaintTo(g, background, Rectangle.Empty); + } + + /// + /// Paints control to canvas. This method might be used for print output. + /// + /// Graphics object to paint control to. + /// Indicates whether to paint control background. + /// Indicates clipping rectangle. Nodes outside of clipping rectangle will not be painted. You can pass Rectangle.Empty and all nodes will be painted. + public void PaintTo(Graphics g, bool background, Rectangle clipRectangle) + { + if (background) + PaintStyleBackground(g); + Point lockedOffset = m_NodeDisplay.GetLockedOffset(); + Point offsetDisplay = m_NodeDisplay.Offset; + Point offset = Point.Empty; + + m_NodeLayout.Graphics = g; + try + { + m_NodeLayout.PerformLayout(); + } + finally + { + m_NodeLayout.Graphics = null; + } + + Node displayNode = this.GetDisplayRootNode(); + + //if(displayNode!=null) + //{ + // if(this.NodeLayout is NodeMapLayout) + // { + // offset = new Point(Math.Abs(displayNode.ChildNodesBounds.Left),Math.Abs(displayNode.ChildNodesBounds.Top)); + // } + //} + + m_NodeDisplay.SetLockedOffset(offset); + + try + { + PaintTree(g, clipRectangle, Point.Empty, true, 1f); + } + finally + { + m_NodeLayout.PerformLayout(); + m_NodeDisplay.SetLockedOffset(lockedOffset); + if (lockedOffset.IsEmpty) + m_NodeDisplay.Offset = offsetDisplay; + } + } + + protected override void OnRightToLeftChanged(EventArgs e) + { + this.RecalcLayout(); + base.OnRightToLeftChanged(e); + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); +#if TRIAL + if(!this.DesignMode) + { + RemindForm f = new RemindForm(); + //Design.ComponentNotLicensed f = new Design.ComponentNotLicensed(); + f.ShowDialog(); + f.Dispose(); + } +#endif + } + + protected override void OnHandleDestroyed(EventArgs e) + { + DestroyDragScrollTimer(); + base.OnHandleDestroyed(e); + } + + private int _IsLayoutOrResize = 0; + protected override void OnResize(EventArgs e) + { + _IsLayoutOrResize++; + try + { + base.OnResize(e); + if (this.Size.Width == 0 || this.Size.Height == 0) + return; + RepositionScrollBars(); // Reposition scrollbars for appearance reasons so the do not "lag" behind when resizing + if ((m_Columns.Count > 0 && m_Columns.UsesRelativeSize || _View == eView.Tile) && !_FirstLayout) + { + this.InvalidateNodesSize(); + if (this.Nodes.Count == 0 && m_Columns.UsesRelativeSize) + SetPendingLayout(); + } + else + SetPendingLayout(); + + //this.RecalcLayout(); + UpdateControlBorderPanel(); + } + finally + { + _IsLayoutOrResize--; + } + + } + + protected override void OnLayout(LayoutEventArgs levent) + { + try + { + _IsLayoutOrResize++; + base.OnLayout(levent); + } + finally + { + _IsLayoutOrResize--; + } + } + + protected override void OnKeyPress(KeyPressEventArgs e) + { + if (_KeyboardSearchEnabled && char.IsLetterOrDigit(e.KeyChar)) + { + Node node = this.SelectedNode; + if (!(node != null && node.CheckBoxVisible && node.Enabled && e.KeyChar == ' ') || node == null) + e.Handled = ProcessKeyboardCharacter(e.KeyChar); + } + base.OnKeyPress(e); + } + + private bool _KeyboardSearchEnabled = true; + /// + /// Gets or sets whether keyboard incremental search through Node.Text property is enabled. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether keyboard incremental search is enabled.")] + public bool KeyboardSearchEnabled + { + get { return _KeyboardSearchEnabled; } + set + { + _KeyboardSearchEnabled = value; + } + } + + private System.Windows.Forms.Timer _SearchBufferExpireTimer = null; + /// + /// Processes the keyboard character and executes the search through the nodes. + /// + /// Character to process. + /// + public virtual bool ProcessKeyboardCharacter(char p) + { + string searchString = UpdateSearchBuffer(p.ToString()); + Node node = FindNodeByText(searchString, SelectedNode, true); + if (node == null && SelectedNode != null) + { + // Try from top searching + node = FindNodeByText(searchString, true); + } + else + { + while (node != null && !node.Selectable) + { + node = FindNodeByText(searchString, node, true); + } + } + if (node != null) + SelectNode(node, eTreeAction.Keyboard); + else + { + if (searchString.Length > 1 && _SearchBufferAutoClearNotFound) + { + searchString = p.ToString(); + _SearchBuffer = searchString; + node = FindNodeByText(searchString, SelectedNode, true); + if (node == null && SelectedNode != null) + node = FindNodeByText(searchString, true); + if (node != null) + SelectNode(node, eTreeAction.Keyboard); + } + } + + return false; + } + + private int _SearchBufferExpireTimeout = 1000; + /// + /// Gets or sets the keyboard search buffer expiration timeout. Default value is 1000 which indicates that + /// key pressed within 1 second will add to the search buffer and control will be searched for node text + /// that begins with resulting string. Setting this value to 0 will disable the search buffer. + /// + [DefaultValue(1000), Category("Behavior"), Description("Indicates keyboard search buffer expiration timeout.")] + public int SearchBufferExpireTimeout + { + get { return _SearchBufferExpireTimeout; } + set + { + if (value < 0) value = 0; + _SearchBufferExpireTimeout = value; + } + } + private bool _SearchBufferAutoClearNotFound = true; + /// + /// Indicates whether search buffer is auto-cleared regardless of the expiration timeout if node is not found using current buffer content. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether search buffer is auto-cleared regardless of the expiration timeout if node is not found using current buffer content.")] + public bool SearchBufferAutoClearNotFound + { + get { return _SearchBufferAutoClearNotFound; } + set + { + _SearchBufferAutoClearNotFound = value; + } + } + + + private string _SearchBuffer = ""; + private string UpdateSearchBuffer(string s) + { + if (_SearchBufferExpireTimeout <= 0) + return s; + + if (_SearchBufferExpireTimer == null) + { + _SearchBufferExpireTimer = new System.Windows.Forms.Timer(); + _SearchBufferExpireTimer.Interval = _SearchBufferExpireTimeout; + _SearchBufferExpireTimer.Tick += new EventHandler(SearchBufferExpireTimerTick); + _SearchBufferExpireTimer.Start(); + } + else + _SearchBufferExpireTimer.Start(); + _SearchBuffer += s; + return _SearchBuffer; + } + + private void SearchBufferExpireTimerTick(object sender, EventArgs e) + { + _SearchBufferExpireTimer.Stop(); + _SearchBuffer = ""; + } + + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + if (!e.Handled) + KeyNavigation.KeyDown(this, e); + } + + protected override bool IsInputChar(char charCode) + { + if (char.IsLetterOrDigit(charCode)) + return true; + return base.IsInputChar(charCode); + } + + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (this.IsKeyboardFocusWithin && !this.Focused) + { + foreach (Cell item in m_HostedControlCells) + { + if (item.HostedControl != null && (item.HostedControl.Focused || item.HostedControl.ContainsFocus)) + return base.ProcessCmdKey(ref msg, keyData); + } + } + + if (!m_CellEditing) + { + if (this.AutoScroll && this.AutoScrollMinSize.Height > this.ClientRectangle.Height && _VScrollBar != null) + { + if (keyData == (Keys.Down | Keys.Control)) + { + // Scroll UP + AutoScrollPosition = new Point(AutoScrollPosition.X, Math.Max(AutoScrollPosition.Y - _VScrollBar.SmallChange, -(_VScrollBar.Maximum - _VScrollBar.LargeChange))); + return true; + } + else if (keyData == (Keys.Up | Keys.Control)) + { + // Scroll Down + AutoScrollPosition = new Point(AutoScrollPosition.X, Math.Min(0, AutoScrollPosition.Y + _VScrollBar.SmallChange)); + return true; + } + } + + if (keyData == Keys.Left || keyData == Keys.Right || + keyData == Keys.Up || keyData == (Keys.Up | Keys.Shift) || + keyData == Keys.Down || keyData == (Keys.Down | Keys.Shift) || keyData == Keys.End || keyData == Keys.Home || + keyData == Keys.PageDown || keyData == Keys.PageUp) + { + return KeyNavigation.NavigateKeyDown(this, new KeyEventArgs(keyData)); + } + } + return base.ProcessCmdKey(ref msg, keyData); + } + + private ColumnHeader _MouseDownColumnHeader = null; + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + if (!this.Focused) + this.Focus(); + + _AutoScrollPositionChange = Point.Empty; // Reset scroll change tracking see notes elsewhere in code for what this does + + Point mousePos = GetLayoutPosition(e); + if (m_CellEditing) + { + m_CellMouseDownCounter = 0; + if (!EndCellEditing(eTreeAction.Mouse)) + return; + } + + NodeHitTestInfo info = e.Button == MouseButtons.Left && _FullRowSelect && _View != eView.Tile ? NodeOperations.GetNodeAt(this, mousePos.Y, false, true) : NodeOperations.GetNodeAt(this, mousePos.X, mousePos.Y, false, true); + + if (_MouseOverColumnHeader != null && e.Button == MouseButtons.Left && AllowUserToResizeColumns) + { + if (info.ColumnsAt != null) + { + StartColumnResize(mousePos.X, mousePos.Y, info.ColumnsAt); + } + else if (_GridColumnLineResizeEnabled) + { + StartColumnResize(mousePos.X, mousePos.Y, m_Columns); + } + } + else if (info.ColumnsAt != null) + { + ColumnHeader ch = GetColumnAt(mousePos.X, mousePos.Y, info.ColumnsAt); + if (ch != null) + { + _MouseDownColumnHeader = ch; + ch.OnMouseDown(e); + } + } + + Node node = info.NodeAt; // e.Button == MouseButtons.Left && _FullRowSelect ? this.GetNodeAt(mousePos.Y) : this.GetNodeAt(mousePos.X, mousePos.Y); + if (node != null) + OnNodeMouseDown(node, e, m_NodeDisplay.Offset); + else if (_MultiSelect && this.SelectedNodes.Count > 1 && (Control.ModifierKeys & (Keys.Control | Keys.Shift)) == Keys.None) + SelectNode(null, eTreeAction.Mouse); + m_MouseDownLocation = mousePos; + +#if !TRIAL + if (NodeOperations.keyValidated2 != 114 && !m_DialogDisplayed) + { + RemindForm f = new RemindForm(); + f.ShowDialog(); + f.Dispose(); + m_DialogDisplayed = true; + } +#endif + } + + private DateTime _LastMouseUpTime = DateTime.MinValue; + private DateTime _IgnoreDoubleClickTime = DateTime.MinValue; + private bool _MovingColumn = false; + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + if (_MouseDownColumnHeader != null) + _MouseDownColumnHeader.OnMouseUp(e); + _MouseDownColumnHeader = null; + + if (_ColumnResize != null) + { + DateTime now = DateTime.Now; + ColumnHeader header = _ColumnResize; + _ColumnResize = null; + this.Capture = false; + if (_LastMouseUpTime == DateTime.MinValue || now.Subtract(_LastMouseUpTime).TotalMilliseconds > SystemInformation.DoubleClickTime) + _LastMouseUpTime = DateTime.Now; + else if (now.Subtract(_LastMouseUpTime).TotalMilliseconds <= SystemInformation.DoubleClickTime) + { + _LastMouseUpTime = DateTime.MinValue; + header.OnDoubleClick(EventArgs.Empty); + if (header.DoubleClickAutoSize) header.AutoSize(); + if (header.Parent != null && header.Parent.ParentNode == null) + { + if (_ColumnHeader != null) + _ColumnHeader.IgnoreDoubleClickTime = now; + } + else if (header.Parent != null && header.Parent.Parent != null) + _IgnoreDoubleClickTime = now; + else + _IgnoreDoubleClickTime = DateTime.MinValue; + + } + else + _LastMouseUpTime = DateTime.MinValue; + OnColumnResized(header, EventArgs.Empty); + InvalidateNodesSize(); + return; + } + else + { + ColumnHeader columnToMove = _ColumnReorder; + if (columnToMove != null) + { + this.Cursor = _OldCursor; + _OldCursor = null; + ColumnHeaderCollection columnsCollection = columnToMove.Parent; + if (columnToMove.Parent == columnsCollection) + { + int moveToPosition = this.ColumnMoveMarkerIndex; + int newDisplayIndex = -1; + this.ColumnMoveMarkerIndex = -1; + if (moveToPosition >= -1) + { + _MovingColumn = true; + this.EndCellEditing(eTreeAction.Mouse); + if (moveToPosition == columnsCollection.Count) + newDisplayIndex = columnsCollection.GetDisplayIndex(columnsCollection.LastVisibleColumn) + 1; + else if (moveToPosition >= 0) + { + int displayIndex = columnsCollection.GetDisplayIndex(columnsCollection[moveToPosition]); + if (displayIndex >= 0) + newDisplayIndex = displayIndex; + else + newDisplayIndex = 0; + } + List displayIndexMap = columnsCollection.DisplayIndexMap; + int oldDisplayIndex = columnsCollection.GetDisplayIndex(columnToMove); + displayIndexMap.RemoveAt(oldDisplayIndex); + if (oldDisplayIndex < newDisplayIndex) newDisplayIndex--; + displayIndexMap.Insert(newDisplayIndex, columnsCollection.IndexOf(columnToMove)); + columnsCollection.UpdatingDisplayIndexes = true; + for (int i = 0; i < displayIndexMap.Count; i++) + { + columnsCollection[displayIndexMap[i]].DisplayIndex = i; + } + columnsCollection.UpdatingDisplayIndexes = false; + _MovingColumn = false; + OnColumnMoved(new ColumnMovedEventArgs(columnToMove, oldDisplayIndex, newDisplayIndex)); + InvalidateNodesSize(); + Invalidate(); + this.RecalcLayout(); + } + } + _ColumnReorder = null; + } + } + + _LastMouseUpTime = DateTime.MinValue; + + ReleaseMouseOverColumnHeader(); + + OnNodeMouseUp(e); + } + /// + /// Raises ColumnResized event. + /// + /// ColumnHeader that was resized. + /// Event arguments + protected virtual void OnColumnResized(ColumnHeader header, EventArgs e) + { + EventHandler handler = ColumnResized; + if (handler != null) + handler(header, e); + } + + /// + /// Raises ColumnMoved event. + /// + /// ColumnHeader that was moved. + /// Provides event arguments. + protected virtual void OnColumnMoved(ColumnMovedEventArgs e) + { + ColumnMovedHandler handler = ColumnMoved; + if (handler != null) + handler(this, e); + } + protected override void OnClick(EventArgs e) + { + base.OnClick(e); + + OnNodeMouseClick(e); + } + + protected override void OnDoubleClick(EventArgs e) + { + base.OnDoubleClick(e); + MouseEventArgs sourceArgs = e as MouseEventArgs; + + Node selectedNode = this.SelectedNode; + if (selectedNode != null) + { + Point p = this.PointToClient(Control.MousePosition); + p = GetLayoutPosition(p); + if (selectedNode.Bounds.Contains(p) || _SelectionBoxStyle == eSelectionStyle.FullRowSelect && p.Y>=selectedNode.Bounds.Y && p.Y<=selectedNode.Bounds.Bottom) + { + Cell cell = GetCellAt(p); + bool toggle = true; + if (cell != null) + { + Rectangle r = NodeDisplay.GetCellRectangle(eCellRectanglePart.CheckBoxBounds, cell, m_NodeDisplay.Offset); + if (!r.IsEmpty && r.Contains(p)) + toggle = false; + } + Node node = selectedNode; + if (_DoubleClickTogglesNode && toggle && (node.HasChildNodes || node.ExpandVisibility == eNodeExpandVisibility.Visible)) + node.Toggle(eTreeAction.Mouse); + + InvokeNodeDoubleClick(new TreeNodeMouseEventArgs(node, + (sourceArgs != null ? sourceArgs.Button : MouseButtons.Left), + 2, + 0, + p.X, + p.Y)); + } + + if (selectedNode.HasColumns && selectedNode.NodesColumnsHeaderVisible && selectedNode.CommandBounds.Contains(p)) + { + ColumnHeader ch = GetColumnAt(p.X, p.Y, selectedNode.NodesColumns); + if (ch != null) + { + DateTime now = DateTime.Now; + if (_IgnoreDoubleClickTime != DateTime.MinValue && now.Subtract(_IgnoreDoubleClickTime).TotalMilliseconds <= SystemInformation.DoubleClickTime) + { + _IgnoreDoubleClickTime = DateTime.MinValue; + return; + } + _IgnoreDoubleClickTime = DateTime.MinValue; + ch.OnDoubleClick(e); + } + } + } + } + + private bool _DoubleClickTogglesNode = true; + /// + /// Gets or sets whether double-clicking the node will toggle its expanded state. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether double-clicking the node will toggle its expanded state.")] + public bool DoubleClickTogglesNode + { + get { return _DoubleClickTogglesNode; } + set + { + _DoubleClickTogglesNode = value; + } + } + + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + + if (m_MouseOverNode != null) + this.SetMouseOverNode(null); + } + + protected override void OnMouseHover(EventArgs e) + { + base.OnMouseHover(e); + if (m_MouseOverNode != null && (FireHoverEvent || m_MouseOverNode.FireHoverEvent)) + { + Point p = this.PointToClient(Control.MousePosition); + p = GetLayoutPosition(p); + InvokeNodeMouseHover(new TreeNodeMouseEventArgs(m_MouseOverNode, Control.MouseButtons, 0, 0, p.X, p.Y)); + } + } + + private ColumnHeader _MouseOverColumnHeader = null; + private ColumnHeaderCollection _MouseOverColumsHeaderCollection = null; + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + bool bUpdate = false; + + if (m_MouseOverNode != null && m_MouseOverNode.Parent == null && m_MouseOverNode.TreeControl == null) // Node has been removed + SetMouseOverNode(null); + + Point mousePos = GetLayoutPosition(e); + + if (_MouseDownColumnHeader != null && _ColumnReorder == null && Math.Abs(mousePos.X - m_MouseDownLocation.X) >= 2 && _AllowUserToReorderColumns) + { + StartColumnReorder(e.X, e.Y, _MouseDownColumnHeader.Parent); + return; + } + + if (_ColumnResize != null) + { + Point offset = Point.Empty; + if (AutoScroll) + { + offset = GetAutoScrollPositionOffset(); + if (_MouseOverColumsHeaderCollection == null) // Main column header resize + offset.Y = 0; + } + Rectangle columnBounds = _ColumnResize.Bounds; + if (m_BackgroundStyle.PaddingLeft > 0 || m_BackgroundStyle.MarginLeft > 0) + columnBounds.X += m_BackgroundStyle.PaddingLeft + m_BackgroundStyle.MarginLeft; + columnBounds.Offset(offset); + columnBounds = GetScreenRectangle(columnBounds); + int columnWidth = Math.Max(Math.Max(2, _ColumnResize.MinimumWidth), mousePos.X - columnBounds.X); + + if (columnWidth != _ColumnResize.Width.Absolute) + { + _ColumnResize.Width.AutoSize = false; + _ColumnResize.Width.Absolute = columnWidth; + OnColumnResizing(_ColumnResize, EventArgs.Empty); + if (_MouseOverColumsHeaderCollection != null) InvalidateNodeSize(_MouseOverColumsHeaderCollection.ParentNode); + this.Update(); + if (_ColumnHeader != null) _ColumnHeader.Refresh(); + if (m_CellEditing && _CellEditControl is Control) + { + Control editControl = (Control)_CellEditControl; + Rectangle rCell = NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds, m_EditedCell, m_NodeDisplay.Offset); + rCell = GetScreenRectangle(rCell); + editControl.Bounds = rCell; + } + } + return; + } + else if (_ColumnReorder != null) + { + ColumnHeader col = GetColumnAt(mousePos.X, mousePos.Y, _ColumnReorder.Parent); + int columnIndex = -1; + if (col != null) + columnIndex = col.Parent.IndexOf(col); + else if (col == null) + { + ColumnHeader lastVisible = _ColumnReorder.Parent.LastVisibleColumn; + if (lastVisible != null && mousePos.X >= lastVisible.Bounds.Right) + columnIndex = _ColumnReorder.Parent.Count; + } + if (columnIndex >= 0) + { + this.ColumnMoveMarkerIndex = columnIndex; + } + return; + } + + if (e.Button == MouseButtons.Left && !m_CellEditing && m_DragDropEnabled && m_MouseOverNode != null && m_DragNode == null && m_MouseOverNode.DragDropEnabled && m_MouseOverNode.IsSelected && + (Math.Abs(m_MouseDownLocation.X - mousePos.X) > SystemInformation.DragSize.Width || Math.Abs(m_MouseDownLocation.Y - mousePos.Y) > SystemInformation.DragSize.Height)) + { + StartDragDrop(); + } + + Rectangle r = Rectangle.Empty; + if (m_MouseOverNode != null) + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, m_MouseOverNode, m_NodeDisplay.Offset); + + bool checkColumns = true; + if (_AllowUserToResizeColumns && _GridLines && _GridColumnLineResizeEnabled && m_Columns.Count > 0) + { + ColumnHeader mouseOverHeader = GetColumnForResizeAt(mousePos.X, mousePos.Y, m_Columns, true, false); + if (mouseOverHeader != null) + { + if (_MouseOverColumnHeader == null) + { + m_OriginalCursor = this.Cursor; + this.Cursor = Cursors.VSplit; + } + _MouseOverColumnHeader = mouseOverHeader; + checkColumns = false; + } + else + ReleaseMouseOverColumnHeader(); + } + + if (!r.IsEmpty && r.Contains(mousePos)) + bUpdate = OnNodeMouseMove(m_MouseOverNode, e, m_NodeDisplay.Offset); + else + { + Node node = null; + NodeHitTestInfo info = null; + if (_FullRowSelect && _View == eView.Tree) + info = NodeOperations.GetNodeAt(this, mousePos.Y, true); + else + info = NodeOperations.GetNodeAt(this, mousePos.X, mousePos.Y, true); + node = info.NodeAt; + if (node != m_MouseOverNode) + bUpdate = SetMouseOverNode(node); + + if (checkColumns) + { + // Check for mouse over Columns + if (node == null && info.ColumnsAt != null && _AllowUserToResizeColumns) + { + ColumnHeader mouseOverHeader = GetColumnForResizeAt(mousePos.X, mousePos.Y, info.ColumnsAt, false); + if (mouseOverHeader != null) + { + if (_MouseOverColumnHeader == null) + { + m_OriginalCursor = this.Cursor; + this.Cursor = Cursors.VSplit; + } + _MouseOverColumnHeader = mouseOverHeader; + _MouseOverColumsHeaderCollection = info.ColumnsAt; + } + else + ReleaseMouseOverColumnHeader(); + } + else + ReleaseMouseOverColumnHeader(); + } + + if (m_MouseOverNode != null) + bUpdate = bUpdate | OnNodeMouseMove(m_MouseOverNode, e, m_NodeDisplay.Offset); + } + + if (bUpdate) + this.Update(); + } + /// + /// Raises ColumnResizing event. + /// + /// Column being resized + /// Event arguments + protected virtual void OnColumnResizing(ColumnHeader column, EventArgs e) + { + EventHandler handler = ColumnResizing; + if (handler != null) handler(column, e); + } + private void ReleaseMouseOverColumnHeader() + { + if (_MouseOverColumnHeader != null) + { + _MouseOverColumnHeader = null; + if (m_OriginalCursor != null) + this.Cursor = m_OriginalCursor; + else + this.Cursor = null; + m_OriginalCursor = null; + } + _MouseOverColumsHeaderCollection = null; + } + + protected override void OnMouseWheel(MouseEventArgs e) + { + if (this.AutoScroll && _VScrollBar != null && !this.IsCellEditing) + { + if (e.Delta < 0) + { + AutoScrollPosition = new Point(AutoScrollPosition.X, Math.Max(AutoScrollPosition.Y - _VScrollBar.SmallChange * SystemInformation.MouseWheelScrollLines, -(_VScrollBar.Maximum - _VScrollBar.LargeChange))); + } + else + { + AutoScrollPosition = new Point(AutoScrollPosition.X, Math.Min(0, AutoScrollPosition.Y + _VScrollBar.SmallChange * SystemInformation.MouseWheelScrollLines)); + + } + } + base.OnMouseWheel(e); + } + + /// + /// Deselect specified node. Use this method when multiple node selection is enabled to deselect single node or all nodes. + /// + /// Reference to node to select or null to deselect all selected nodes. + /// Action that is selecting the node. + public void DeselectNode(Node node, eTreeAction action) + { + if (!_MultiSelect || node == null) + { + SelectNode(null, action); + return; + } + + if (!node.IsSelected) return; + m_SelectedNodes.Remove(node, action); + } + + internal void InvokeSelectionChanged(EventArgs e) + { + OnSelectionChanged(e); + } + + /// + /// Raises SelectionChanged event. + /// + /// Event arguments + protected virtual void OnSelectionChanged(EventArgs e) + { + EventHandler handler = SelectionChanged; + if (handler != null) handler(this, e); + } + + internal void InvokeCellSelected(AdvTreeCellEventArgs e) + { + OnCellSelected(e); + } + /// + /// Raises CellSelected event. + /// + /// Event arguments. + protected virtual void OnCellSelected(AdvTreeCellEventArgs e) + { + AdvTreeCellEventHandler handler = CellSelected; + if (handler != null) handler(this, e); + } + internal void InvokeCellUnselected(AdvTreeCellEventArgs e) + { + OnCellUnselected(e); + } + /// + /// Raises CellUnselected event. + /// + /// Event arguments. + protected virtual void OnCellUnselected(AdvTreeCellEventArgs e) + { + AdvTreeCellEventHandler handler = CellUnselected; + if (handler != null) handler(this, e); + } + + /// + /// Selected specified node. + /// + /// Node to select. + /// Action that is selecting the node. + public void SelectNode(Node node, eTreeAction action) + { + if (node != null && !node.Selectable && !this.DesignMode) return; + if (!_MultiSelect && node == m_SelectedNode) return; + + AdvTreeNodeCancelEventArgs cancelArgs = new AdvTreeNodeCancelEventArgs(action, node); + OnBeforeNodeSelect(cancelArgs); + if (cancelArgs.Cancel) + return; + + // Reset change tracking since if node is partially covered by scroll-bars and is scrolled into the view + // the NodeClick event does not get fired since mouse at that time points to different node due to scrolling. + // This offset is used to offset mouse position so correct node is found and NodeClick event is fired. + _AutoScrollPositionChange = Point.Empty; + if (_MultiSelect && !this.DesignMode) + { + if (m_SelectedNodes.Count > 0) + { + //m_SelectedNodes.SuspendClearEvents = true; + m_SelectedNodes.SourceAction = action; + m_SelectedNodes.Clear(); + m_SelectedNodes.SourceAction = eTreeAction.Code; + //m_SelectedNodes.SuspendClearEvents = false; + } + bool fireSelection = false; + if (node != null) + { + m_SelectedNodes.SuspendEvents = true; + try + { + if (m_SelectedNodes.Add(node, action) != -1) + { + node.EnsureVisible(); + fireSelection = true; + } + } + finally + { + m_SelectedNodes.SuspendEvents = false; + } + } + else + OnSelectionChanged(EventArgs.Empty); + this.Invalidate(); + //OnSelectionChanged(EventArgs.Empty); // Fired from SelectedNodes collection + return; + } + + //bool bUpdate=false; + + if (m_CellEditing) + { + if (!EndCellEditing(eTreeAction.Code)) + return; + } + +#if !TRIAL + if (NodeOperations.keyValidated2 < 114) + { + NodeDisplay.keyInvalid = true; + NodeOperations.keyValidated2 = NodeOperations.keyValidated2 + 124; + } + else if (NodeOperations.keyValidated2 > 114) + return; +#endif + Node oldSelected = m_SelectedNode; + m_SelectedNode = node; + + if (oldSelected != null) + { + oldSelected.IsSelected = false; + InvalidateNode(oldSelected); + //bUpdate = true; + if (oldSelected.GetSelectedCell() != null && oldSelected != node) + oldSelected.SetSelectedCell(null, action); // SelectedCell.SetSelected(false); + if (m_SelectedNodes.Contains(oldSelected)) + m_SelectedNodes.Remove(oldSelected); + OnAfterNodeDeselect(new AdvTreeNodeEventArgs(action, oldSelected)); + oldSelected.InternalDeselected(action); + } + + if (m_SelectedNode != null) + { + m_SelectedNode.IsSelected = true; + m_SelectedNodes.Add(m_SelectedNode); + InvalidateNode(m_SelectedNode); + //bUpdate = true; + if (m_SelectedNode.SelectedCell == null) + { + m_SelectedNode.SelectFirstCell(action); + } + m_SelectedNode.EnsureVisible(); + } + + if (this.SelectedPathConnector != null) + this.Invalidate(); + + if (_DataManager != null && _EnableDataPositionChange) + { + if (node != null && node.BindingIndex > -1 && _DataManager.Position != node.BindingIndex) + { + _DataManager.Position = node.BindingIndex; + } + //else if (node == null && !_LoadingDataSource) + // _DataManager.Position = -1; + } + + AdvTreeNodeEventArgs args = new AdvTreeNodeEventArgs(action, node); + OnAfterNodeSelect(args); + + if (m_SelectedNode != null) + { + m_SelectedNode.InternalSelected(action); + } + + OnSelectedIndexChanged(EventArgs.Empty); + if (!string.IsNullOrEmpty(this.ValueMember)) + this.OnSelectedValueChanged(EventArgs.Empty); + OnSelectionChanged(EventArgs.Empty); + } + + private void OnCellStyleChanged() + { + InvalidateNodesSize(); + if (this.DesignMode) + { + this.RecalcLayout(); + this.Refresh(); + } + } + + private void SetSizeChanged(Node node) + { + node.SizeChanged = true; + foreach (Node c in node.Nodes) + SetSizeChanged(c); + } + + + /// + /// Invalidates the size for all top-level nodes and their sub-nodes. + /// + public void InvalidateNodesSize() + { + if (_ColumnResize != null) + { + // To optimize perormace when resizing columns just invalidate visible columns + ArrayList paintedNodes = this.NodeDisplay.PaintedNodes; + foreach (Node paintedNode in paintedNodes) + { + SetSizeChanged(paintedNode); + } + } + else + { + foreach (Node node in m_Nodes) + SetSizeChanged(node); + } + } + + /// + /// Invalidates the size for a node and its sub-nodes. + /// + /// Node to invalidate size for. + public void InvalidateNodeSize(Node node) + { + SetSizeChanged(node); + } + + private void ImageListDisposed(object sender, EventArgs e) + { + if (sender == m_ImageList) + { + this.ImageList = null; + } + } + + /// + /// Ensures that selected node is visible i.e. that all parents of the selected node are expanded. If not selects the first parent node not expanded. + /// + internal void ValidateSelectedNode() + { + Node node = this.SelectedNode; + Node nodeSelected = node; + if (node == null) + return; + if (node.TreeControl != this) + { + nodeSelected = null; + } + else + { + while (node != null) + { + node = node.Parent; + if (node != null && !node.Expanded && node.Selectable) + nodeSelected = node; + } + } + if (nodeSelected == null || !nodeSelected.IsVisible) + { + if (!SelectFirstNode(eTreeAction.Code)) + this.SelectedNode = null; + } + else + { + if (_MultiSelect) + { + if (!this.SelectedNodes.Contains(nodeSelected)) + this.SelectedNode = nodeSelected; + } + else + { + if (this.SelectedNode != nodeSelected) + this.SelectedNode = nodeSelected; + } + } + } + + private bool SetMouseOverCell(Cell mouseOverCell) + { + bool bUpdate = false; + if (mouseOverCell == m_MouseOverCell) + return bUpdate; + + if (m_MouseOverCell != null && m_MouseOverCell != mouseOverCell) + { + if (this.CellStyleMouseOver != null || m_MouseOverCell.StyleMouseOver != null || m_RenderMode != eNodeRenderMode.Default || m_MouseOverCell.Parent != null && m_MouseOverCell.Parent.RenderMode != eNodeRenderMode.Default) + bUpdate = true; + m_MouseOverCell.SetMouseOver(false); + if (m_MouseOverCell.Tooltip != null) + Interop.WinApi.ResetHover(this); + } + + m_MouseOverCell = mouseOverCell; + if (m_MouseOverCell != null) + { + m_MouseOverCell.SetMouseOver(true); + if (this.CellStyleMouseOver != null || m_MouseOverCell.StyleMouseOver != null || m_RenderMode != eNodeRenderMode.Default || m_MouseOverCell.Parent != null && m_MouseOverCell.Parent.RenderMode != eNodeRenderMode.Default) + bUpdate = true; + } + + UpdateTreeCursor(); + + return bUpdate; + } + + private bool SetMouseOverNode(Node mouseOverNode) + { + bool bUpdate = false; + if (m_MouseOverNode != null) + { + bUpdate = bUpdate | SetMouseOverCell(null); + if (m_MouseOverNode.MouseOverNodePart == eMouseOverNodePart.Expand) + bUpdate = true; + m_MouseOverNode.MouseOverNodePart = eMouseOverNodePart.None; + if (this.NodeStyleMouseOver != null || this.CellStyleMouseOver != null || m_MouseOverNode.StyleMouseOver != null || this.NodeStyleMouseOver != null || + m_RenderMode != eNodeRenderMode.Default || m_MouseOverNode.RenderMode != eNodeRenderMode.Default || m_MouseOverNode.CommandButton || bUpdate || _HotTracking) + { + InvalidateNode(m_MouseOverNode); + bUpdate = true; + } + + if (m_MouseOverNode != mouseOverNode && m_MouseOverNode != null) + { + Point p = this.PointToClient(Control.MousePosition); + InvokeNodeMouseLeave(new TreeNodeMouseEventArgs(m_MouseOverNode, Control.MouseButtons, 0, 0, p.X, p.Y)); + } + } + + bool mouseOverNodeChanged = m_MouseOverNode != mouseOverNode; + m_MouseOverNode = mouseOverNode; + + if (mouseOverNode != null) + { + mouseOverNode.MouseOverNodePart = eMouseOverNodePart.Node; + if (mouseOverNode.StyleMouseOver != null || this.NodeStyleMouseOver != null || + m_RenderMode != eNodeRenderMode.Default || mouseOverNode.RenderMode != eNodeRenderMode.Default || mouseOverNode.CommandButton || _HotTracking) + { + InvalidateNode(mouseOverNode); + bUpdate = true; + } + + Point p = this.PointToClient(Control.MousePosition); + InvokeNodeMouseEnter(new TreeNodeMouseEventArgs(mouseOverNode, Control.MouseButtons, 0, 0, p.X, p.Y)); + + if (mouseOverNodeChanged && (FireHoverEvent || mouseOverNode.FireHoverEvent)) + { + Interop.WinApi.ResetHover(this); + } + } + + return bUpdate; + } + private static readonly string DotNetBarPrefix = "DotNetBar."; + private void OnNodeMouseDown(Node node, MouseEventArgs e, Point offset) + { + Point mousePos = GetLayoutPosition(e); + + InvokeNodeMouseDown(new TreeNodeMouseEventArgs(node, e.Button, e.Clicks, e.Delta, mousePos.X, mousePos.Y)); + + if (e.Button == MouseButtons.Left) + { + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandHitTestBounds, node, offset); + + if (r.Contains(mousePos) && e.Clicks == 1 && node.ExpandVisibility != eNodeExpandVisibility.Hidden) + { + m_CellMouseDownCounter = 0; + node.Toggle(eTreeAction.Mouse); + return; + } + + if (node.CommandButton) + { + m_CellMouseDownCounter = 0; + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.CommandBounds, node, offset); + if (r.Contains(mousePos)) + { + InvokeCommandButtonClick(node, new CommandButtonEventArgs(eTreeAction.Mouse, node)); + return; + } + } + + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, node, offset); + if ((r.Contains(mousePos) || _FullRowSelect && mousePos.Y >= r.Y && mousePos.Y <= r.Bottom) && node.TreeControl != null) + { + if (node.TreeControl.SelectedNode != node) + m_CellMouseDownCounter = 0; + + if (node.Selectable) + { + if (_MultiSelect && m_SelectedNodes.Count > 0 && Control.ModifierKeys == Keys.None && e.Button == MouseButtons.Left) // Deselect all + _SelectOnMouseUp = true; + else + _SelectOnMouseUp = false; + + if (_MultiSelect && m_SelectedNodes.Count > 0 && (Control.ModifierKeys == Keys.Shift || Control.ModifierKeys == Keys.Control)) + { + m_CellMouseDownCounter = 0; + if (_MultiSelectRule == eMultiSelectRule.SameParent && m_SelectedNodes[0].Parent != node.Parent) return; + if (Control.ModifierKeys == Keys.Shift && m_SelectedNodes.Count > 0) + { + // Range selection + Node startNode = m_SelectedNodes[0]; + Node currentNode = node; + bool selectionChanged = false; + m_SelectedNodes.MultiNodeOperation = true; + try + { + while (m_SelectedNodes.Count > 1) + { + m_SelectedNodes.Remove(m_SelectedNodes[m_SelectedNodes.Count - 1], eTreeAction.Mouse); + selectionChanged = true; + } + } + finally + { + m_SelectedNodes.MultiNodeOperation = false; + } + if (currentNode != startNode) + { + if (currentNode.Bounds.Y > startNode.Bounds.Y) + { + // Selecting down + m_SelectedNodes.MultiNodeOperation = true; + try + { + do + { + if (!currentNode.IsSelected && currentNode.Selectable) + { + if (_MultiSelectRule == eMultiSelectRule.AnyNode || + _MultiSelectRule == eMultiSelectRule.SameParent && m_SelectedNodes.Count > 0 && m_SelectedNodes[0].Parent == currentNode.Parent) + m_SelectedNodes.Add(currentNode, eTreeAction.Mouse); + } + currentNode = NodeOperations.GetPreviousVisibleNode(currentNode); + + } while (startNode != currentNode && currentNode != null); + } + finally + { + m_SelectedNodes.MultiNodeOperation = false; + InvokeSelectionChanged(EventArgs.Empty); + } + } + else + { + // Selecting upwards + m_SelectedNodes.MultiNodeOperation = true; + try + { + do + { + if (!currentNode.IsSelected && currentNode.Selectable) + { + if (_MultiSelectRule == eMultiSelectRule.AnyNode || + _MultiSelectRule == eMultiSelectRule.SameParent && m_SelectedNodes.Count > 0 && m_SelectedNodes[0].Parent == currentNode.Parent) + m_SelectedNodes.Add(currentNode, eTreeAction.Mouse); + } + currentNode = NodeOperations.GetNextVisibleNode(currentNode); + + } while (startNode != currentNode && currentNode != null); + } + finally + { + m_SelectedNodes.MultiNodeOperation = false; + InvokeSelectionChanged(EventArgs.Empty); + } + } + } + else if (selectionChanged) + InvokeSelectionChanged(EventArgs.Empty); + } + else + { + if (node.IsSelected) + m_SelectedNodes.Remove(node, eTreeAction.Mouse); + else + m_SelectedNodes.Add(node, eTreeAction.Mouse); + } + //OnSelectionChanged(EventArgs.Empty); + return; + } + else if (!node.IsSelected) + { + SelectNode(node, eTreeAction.Mouse); + if (node.TreeControl == null || node.TreeControl.SelectedNode != node) // Action cancelled + return; + } + } + + Cell cell = GetCellAt(node, mousePos.X, mousePos.Y, offset); + if (cell != null) + { + bool checkBoxSelection = false; + if (cell.CheckBoxVisible && cell.GetEnabled()) + { + Rectangle rCheckBox = cell.CheckBoxBoundsRelative; + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, node, offset); + rCheckBox.Offset(r.Location); + if (rCheckBox.Contains(mousePos)) + { + + if (cell.CheckBoxThreeState) + { + if (cell.CheckState == CheckState.Checked) + cell.SetChecked(CheckState.Indeterminate, eTreeAction.Mouse); + else if (cell.CheckState == CheckState.Unchecked) + cell.SetChecked(CheckState.Checked, eTreeAction.Mouse); + else if (cell.CheckState == CheckState.Indeterminate) + cell.SetChecked(CheckState.Unchecked, eTreeAction.Mouse); + } + else + cell.SetChecked(!cell.Checked, eTreeAction.Mouse); + checkBoxSelection = true; + m_CellMouseDownCounter = 0; + } + } + if (node.SelectedCell != cell) + { + m_CellMouseDownCounter = 1; + } + else if (!checkBoxSelection) + m_CellMouseDownCounter++; + node.SetSelectedCell(cell, eTreeAction.Mouse); + cell.SetMouseDown(true); + } + } + else + m_CellMouseDownCounter = 0; + } + else if (e.Button == MouseButtons.Right) + { + if (node.TreeControl == null) return; + if (!node.IsSelected) + SelectNode(node, eTreeAction.Mouse); + if (!this.MultiSelect && node.TreeControl.SelectedNode != node) // Action cancelled + return; + if (node.ContextMenu != null) + { + if (node.ContextMenu is ContextMenu) + { + ContextMenu cm = node.ContextMenu as ContextMenu; + cm.Show(this, new Point(e.X, e.Y)); + } + else if (node.ContextMenu.GetType().FullName == "System.Windows.Forms.ContextMenuStrip") + { + node.ContextMenu.GetType().InvokeMember("Show", System.Reflection.BindingFlags.InvokeMethod, null, + node.ContextMenu, new object[] { this, new Point(e.X, e.Y) }); + } + else if (node.ContextMenu.GetType().FullName == "DevComponents.DotNetBar.ButtonItem") + { + Point p = this.PointToScreen(new Point(e.X, e.Y)); + ((PopupItem)node.ContextMenu).SetSourceControl(this); + node.ContextMenu.GetType().InvokeMember("Popup", System.Reflection.BindingFlags.InvokeMethod, + null, node.ContextMenu, new object[] { p }); + } + else if (node.ContextMenu.ToString().StartsWith(DotNetBarPrefix) && m_DotNetBarManager != null) + { + string menuName = node.ContextMenu.ToString().Substring(DotNetBarPrefix.Length); + object contextMenus = m_DotNetBarManager.GetType().InvokeMember("ContextMenus", + System.Reflection.BindingFlags.GetProperty, null, m_DotNetBarManager, null); + int index = (int)contextMenus.GetType().InvokeMember("IndexOf", System.Reflection.BindingFlags.InvokeMethod, + null, contextMenus, new string[] { menuName }); + if (index >= 0) + { + IList list = contextMenus as IList; + object popup = list[index]; + // Older version of DotNetBar do not have this method exposed so ignore the error... + try + { + popup.GetType().InvokeMember("SetSourceControl", System.Reflection.BindingFlags.InvokeMethod, + null, popup, new object[] { this }); + } + catch { } + + Point p = this.PointToScreen(new Point(e.X, e.Y)); + popup.GetType().InvokeMember("Popup", System.Reflection.BindingFlags.InvokeMethod, + null, popup, new object[] { p }); + } + } + } + } + } + + private bool _SelectOnMouseUp = false; + private void OnNodeMouseUp(MouseEventArgs e) + { + bool bUpdate = false; + Point mousePos = GetLayoutPosition(e); + + if (this.SelectedNode != null) + { + if (this.SelectedNode.SelectedCell != null && this.SelectedNode.SelectedCell.IsMouseDown) + { + this.SelectedNode.SelectedCell.SetMouseDown(false); + this.InvalidateNode(this.SelectedNode); + bUpdate = true; + } + } + + if (bUpdate) + this.Update(); + + Node node = null; + if (this.SelectedNode != null && this.SelectedNode.Bounds.Contains(mousePos)) + node = this.SelectedNode; + else + node = NodeOperations.GetNodeAt(this, mousePos.X, mousePos.Y, true).NodeAt; //this.GetNodeAt(mousePos); + + if (_SelectOnMouseUp && node != null && node.IsSelected && _MultiSelect && m_SelectedNodes.Count > 1 && Control.ModifierKeys == Keys.None) // Deselect all + SelectNode(node, eTreeAction.Mouse); + _SelectOnMouseUp = false; + if (node != null) + { + InvokeNodeMouseUp(new TreeNodeMouseEventArgs(node, e.Button, e.Clicks, e.Delta, mousePos.X, mousePos.Y)); + } + } + + private void OnNodeMouseClick(EventArgs e) + { + if (this.SelectedNode == null) + return; + MouseEventArgs me = e as MouseEventArgs; + if (me == null) + { + Point p = this.PointToClient(Control.MousePosition); + me = new MouseEventArgs(MouseButtons.Left, 1, p.X, p.Y, 0); + } + + Point mousePos = GetLayoutPosition(me); + NodeHitTestInfo info = (me.Button == MouseButtons.Left && _FullRowSelect && _View == eView.Tree) ? NodeOperations.GetNodeAt(this, mousePos.Y + _AutoScrollPositionChange.Y, true, true) : NodeOperations.GetNodeAt(this, mousePos.X, mousePos.Y, true, true); + _AutoScrollPositionChange = Point.Empty; + if (info.NodeAt != null && (info.NodeAt == this.SelectedNode || info.NodeAt.IsSelected && me.Button == System.Windows.Forms.MouseButtons.Right) && !info.NodeAt.ExpandPartRectangle.Contains(mousePos)) + { + InvokeNodeClick(new TreeNodeMouseEventArgs(this.SelectedNode, me.Button, me.Clicks, me.Delta, me.X, me.Y)); + if (m_CellMouseDownCounter > 1 && me.Button == MouseButtons.Left) + EditSelectedCell(eTreeAction.Mouse); + } + + if (info.ColumnsAt != null) + { + ColumnHeader ch = GetColumnAt(mousePos.X, mousePos.Y, info.ColumnsAt); + if (ch != null) + { + ch.OnClick(e); + } + } + + } + + internal bool EditSelectedCell(eTreeAction actionSource) + { + // Start editing if allowed + if (this.CellEdit && this.SelectedNode != null && this.SelectedNode.SelectedCell != null && this.SelectedNode.SelectedCell.IsEditable) + { + EditCell(this.SelectedNode.SelectedCell, actionSource); + return true; + } + return false; + } + + private bool _HotTracking = false; + /// + /// Gets or sets whether node is highlighted when mouse enters the node. Default value is false. + /// + /// + /// There are two ways to enable the node hot-tracking. You can set the HotTracking property to true in which case the + /// mouse tracking is enabled using system colors specified in TreeColorTable. You can also define the NodeStyleMouseOver + /// style which gets applied to the node when mouse is over the node. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether node is highlighted when mouse enters the node.")] + public bool HotTracking + { + get { return _HotTracking; } + set + { + _HotTracking = value; + this.Invalidate(); + } + } + + /// + /// Starts editing specified cell, places the cell into the edit mode. + /// + /// Cell to start editing. + /// Action that is a cause for the edit. + internal void EditCell(Cell cell, eTreeAction action) + { + EditCell(cell, action, null); + } + + private ICellEditControl _CellEditControl = null; + /// + /// Starts editing specified cell, places the cell into the edit mode. + /// + /// Cell to start editing. + /// Action that is a cause for the edit. + /// Specifies the text to be edited instead of the text of the cell. Passing the NULL value will edit the text of the cell. + internal void EditCell(Cell cell, eTreeAction action, string initialText) + { + if (cell == null || !cell.GetEnabled()) return; + + if (m_CellEditing) + { + if (!EndCellEditing(action)) + return; + } + + if (_MovingColumn) + throw new InvalidOperationException("Cannot initiate cell edit while column is being moved."); + + CellEditEventArgs e = new CellEditEventArgs(cell, action, ""); + OnBeforeCellEdit(e); + if (e.Cancel) + return; + // No editing on non-data nodes + if (_DataManager != null && cell.Parent.DataKey == null) return; + + ICellEditControl editControl = GetCellEditor(cell); + if (editControl == null) return; + + NodeOperations.EnsureVisible(cell); + this.Update(); + + TextBoxEx textBox = editControl as TextBoxEx; + Control control = editControl as Control; + + Rectangle rCell = NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds, cell, m_NodeDisplay.Offset); + if (rCell.IsEmpty) + { + rCell = NodeDisplay.GetCellRectangle(eCellRectanglePart.CellBounds, cell, m_NodeDisplay.Offset); + if (string.IsNullOrEmpty(cell.Text)) // Move edit box so its next to the actual cell + rCell.X += rCell.Width; + } + rCell = GetScreenRectangle(rCell); + // It is important that text is assigned first or textbox will be resized to different size otherwise + editControl.CurrentValue = cell.Text; + editControl.EditWordWrap = cell.WordWrap; + + Font font = CellDisplay.GetCellFont(this, cell); + if (m_ZoomFactor != 1 && font != null) + { + font = new Font(font.FontFamily, font.SizeInPoints * m_ZoomFactor); + } + + control.Font = font; + control.Location = rCell.Location; + control.Size = rCell.Size; + control.Visible = true; + control.Focus(); + + if (textBox != null) + { + //if initial text is null then follow default behaviour of selecting all text + //if initial text is not null, set that as the default text and set the caret to the end of the text + if (initialText == null) + { + textBox.SelectAll(); + } + else + { + textBox.Text = initialText; + textBox.Select(textBox.Text.Length, 0); + } + } + + PrepareCellEditor(cell, editControl); + + cell.Parent.SetEditing(true); + m_EditedCell = cell; + m_CellEditing = true; + _CellEditControl = editControl; + editControl.BeginEdit(); + } + + /// + /// Gets whether tree is in process of moving the column in response to user finishing the column move action. + /// + [Browsable(false)] + public bool IsMovingColumn + { + get { return _MovingColumn; } + } + + /// + /// Called just before cell editor is released for editing. + /// + /// Reference to the cell being edited. + /// Reference to the editor control. + protected virtual void PrepareCellEditor(Cell cell, ICellEditControl editControl) + { + OnPrepareCellEditorControl(new PrepareCellEditorEventArgs(cell, editControl)); + } + + protected virtual void OnPrepareCellEditorControl(PrepareCellEditorEventArgs e) + { + PrepareCellEditorEventHandler h = PrepareCellEditorControl; + if (h != null) h(this, e); + } + + /// + /// Raises the ProvideCustomCellEditor event. + /// + /// Event arguments. + protected virtual void OnProvideCustomCellEditor(CustomCellEditorEventArgs e) + { + CustomCellEditorEventHandler handler = ProvideCustomCellEditor; + if (handler != null) + handler(this, e); + } + + /// + /// Ends cell editing. + /// + /// Specifies which action is cause for end of the editing. + /// Returns true if edits were applied to the cell or false otherwise. + internal bool EndCellEditing(eTreeAction action) + { + return EndCellEditing(action, false); + } + + private bool _CellEditEnding = false; + /// + /// Ends cell editing. + /// + /// Specifies which action is cause for end of the editing. + /// Returns true if edits were applied to the cell or false otherwise. + internal bool EndCellEditing(eTreeAction action, bool cancelEdit) + { + Cell editedCell = m_EditedCell; + if (editedCell == null || _CellEditControl == null) + { + m_CellEditing = false; + return true; + } + ICellEditControl editControl = _CellEditControl; + Control control = editControl as Control; + + string text = editControl.CurrentValue.ToString(); + + CellEditEventArgs e = new CellEditEventArgs(editedCell, action, text, cancelEdit, editControl); + InvokeCellEditEnding(e); + if (e.Cancel) + return false; + this.Focus(); + control.Visible = false; + + text = e.NewText; + InvokeAfterCellEdit(e); + text = e.NewText; + + if (!e.Cancel && editedCell.Text != text && !cancelEdit) + { + if (this.DesignMode && editedCell.Parent.Cells[0] == editedCell) + TypeDescriptor.GetProperties(editedCell.Parent)["Text"].SetValue(editedCell.Parent, text); + else + TypeDescriptor.GetProperties(editedCell)["Text"].SetValue(editedCell, text); + this.BeginUpdate(); + this.RecalcLayout(); + this.EndUpdate(); + } + + editedCell.Parent.SetEditing(false); + + // Try to apply to data-binding + if (_DataSource != null) + { + object item = editedCell.Parent.DataKey; + string fieldName = this.Columns[editedCell.Parent.Cells.IndexOf(editedCell)].DataFieldName; + if (item != null) + { + IEditableObject editableObject = item as IEditableObject; + PropertyDescriptor descriptor; + if (_DataManager != null) + descriptor = _DataManager.GetItemProperties().Find(fieldName, true); + else + descriptor = TypeDescriptor.GetProperties(item).Find(fieldName, true); + + if (descriptor != null) + { + if (_EnableDataPositionChange && _DataManager != null && _DataManager.Position != editedCell.Parent.BindingIndex) + _DataManager.Position = editedCell.Parent.BindingIndex; + if (editableObject != null) + editableObject.BeginEdit(); + + descriptor.SetValue(item, text); + + if (editableObject != null) + editableObject.EndEdit(); + } + } + } + + m_EditedCell = null; + m_CellEditing = false; + + OnAfterCellEditComplete(e); + + if (editControl != m_EditTextBox) + { + this.Controls.Remove(control); + editControl.EditComplete -= new EventHandler(EditControlEndEdit); + editControl.CancelEdit -= new EventHandler(EditControlCancelEdit); + } + editControl.EndEdit(); + + return true; + } + + /// + /// Raises the AfterCellEditComplete event. + /// + /// Provides information about event. + protected virtual void OnAfterCellEditComplete(CellEditEventArgs e) + { + CellEditEventHandler eh = AfterCellEditComplete; + if (eh != null) eh(this, e); + } + + /// + /// Cancels the cell editing if it is in progress. + /// + /// Specifies which action is cause for canceling of editing. + internal void CancelCellEdit(eTreeAction action) + { + if (m_EditedCell == null) + return; + + if (m_EditTextBox != null) + m_EditTextBox.Text = m_EditedCell.Text; + else + { + ICellEditControl editControl = _CellEditControl; + if (editControl != null) + editControl.CurrentValue = m_EditedCell.Text; + } + this.EndCellEditing(action, true); + } + + private ICellEditControl GetCellEditor(Cell cell) + { + eCellEditorType editorType = cell.GetEffectiveEditorType(); + ICellEditControl editor = null; + + if (editorType == eCellEditorType.Default) + { + editor = GetTextBoxEditor(); + if (editor is TextBox) + { + ColumnHeader header = NodeOperations.GetCellColumnHeader(this, cell); + if (header != null) + ((TextBox)editor).MaxLength = header.MaxInputLength; + else + ((TextBox)editor).MaxLength = 0; + } + } +#if FRAMEWORK20 + else if (editorType == eCellEditorType.NumericInteger) + { + IntegerCellEditor edit = new IntegerCellEditor(); + edit.ShowUpDown = true; + editor = edit; + } + else if (editorType == eCellEditorType.NumericDouble) + { + DoubleCellEditor edit = new DoubleCellEditor(); + edit.ShowUpDown = true; + editor = edit; + } + else if (editorType == eCellEditorType.NumericCurrency) + { + DoubleCellEditor edit = new DoubleCellEditor(); + edit.DisplayFormat = "C"; + edit.ShowUpDown = true; + editor = edit; + } + else if (editorType == eCellEditorType.Date) + { + DateTimeCellEditor edit = new DateTimeCellEditor(); + edit.Format = DevComponents.Editors.eDateTimePickerFormat.Short; + edit.ButtonDropDown.Visible = true; + editor = edit; + } + else if (editorType == eCellEditorType.Time) + { + DateTimeCellEditor edit = new DateTimeCellEditor(); + edit.Format = DevComponents.Editors.eDateTimePickerFormat.ShortTime; + edit.ButtonDropDown.Visible = true; + editor = edit; + } + else if (editorType == eCellEditorType.DateTime) + { + DateTimeCellEditor edit = new DateTimeCellEditor(); + edit.Format = DevComponents.Editors.eDateTimePickerFormat.Custom; + CultureInfo currentCulture = DevComponents.Editors.DateTimeAdv.DateTimeInput.GetActiveCulture(); + edit.CustomFormat = currentCulture.DateTimeFormat.ShortDatePattern + " " + currentCulture.DateTimeFormat.ShortTimePattern; + edit.DateTimeSelectorVisibility = DevComponents.Editors.DateTimeAdv.eDateTimeSelectorVisibility.Both; + edit.ButtonDropDown.Visible = true; + editor = edit; + } +#endif + else if (editorType == eCellEditorType.Custom) + { + CustomCellEditorEventArgs e = new CustomCellEditorEventArgs(cell); + OnProvideCustomCellEditor(e); + if (e.EditControl == null) + throw new ArgumentNullException("CustomCellEditorEventArgs.EditControl must be set to the custom cell editor."); + + editor = e.EditControl; + } + + if (editor == null) + throw new NotImplementedException("Editor type " + editorType.ToString() + " not implemented."); + + if (((Control)editor).Parent != this) + { + this.Controls.Add((Control)editor); + editor.EditComplete += new EventHandler(EditControlEndEdit); + editor.CancelEdit += new EventHandler(EditControlCancelEdit); + } + + return editor; + } + + private TextBoxEx GetTextBoxEditor() + { + if (m_EditTextBox == null) + { + m_EditTextBox = new TextBoxEx(); + m_EditTextBox.Name = "DefaultCellEditor"; + m_EditTextBox.AutoSize = false; + m_EditTextBox.PreventEnterBeep = true; + this.Controls.Add(m_EditTextBox); + m_EditTextBox.EditComplete += new EventHandler(EditControlEndEdit); + m_EditTextBox.CancelEdit += new EventHandler(EditControlCancelEdit); + } + return m_EditTextBox; + } + + private void EditControlEndEdit(object sender, EventArgs e) + { + if (m_EditedCell == null) + return; + + this.EndCellEditing(eTreeAction.Keyboard); + } + + private void EditControlCancelEdit(object sender, EventArgs e) + { + CancelCellEdit(eTreeAction.Keyboard); + } + + private void UpdateTreeCursor() + { + if (m_MouseOverCell != null) + { + if (m_MouseOverCell.Cursor != null && this.Cursor != m_MouseOverCell.Cursor) + { + if (m_OriginalCursor == null) + m_OriginalCursor = this.Cursor; + this.Cursor = m_MouseOverCell.Cursor; + } + else if (m_DefaultCellCursor != null && this.Cursor != m_DefaultCellCursor) + { + if (m_OriginalCursor == null) + m_OriginalCursor = this.Cursor; + this.Cursor = m_DefaultCellCursor; + } + } + else if (m_OriginalCursor != null) + { + this.Cursor = m_OriginalCursor; + m_OriginalCursor = null; + } + } + + private Cell GetCellAt(Node node, int x, int y, Point offset) + { + Cell cellAt = null; + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, node, offset); + foreach (Cell cell in node.Cells) + { + if (!cell.IsVisible) continue; + Rectangle rCell = cell.BoundsRelative; + //rCell.Offset(offset); + rCell.Offset(r.Location); + if (rCell.Contains(x, y)) + { + cellAt = cell; + break; + } + } + return cellAt; + } + + private bool OnNodeMouseMove(Node node, MouseEventArgs e, Point offset) + { + Point mousePos = GetLayoutPosition(e); + InvokeNodeMouseMove(new TreeNodeMouseEventArgs(node, e.Button, e.Clicks, e.Delta, mousePos.X, mousePos.Y)); + + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandHitTestBounds, node, offset); + bool bUpdate = false; + if (r.Contains(mousePos) && node.ExpandVisibility != eNodeExpandVisibility.Hidden) + { + node.MouseOverNodePart = eMouseOverNodePart.Expand; + if (m_MouseOverCell != null) + { + bUpdate |= SetMouseOverCell(null); + } + bUpdate = true; + } + else if (node.MouseOverNodePart == eMouseOverNodePart.Expand) + { + node.MouseOverNodePart = eMouseOverNodePart.Node; + bUpdate = true; + } + + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.CommandBounds, node, offset); + if (r.Contains(mousePos)) + { + node.MouseOverNodePart = eMouseOverNodePart.Command; + if (m_MouseOverCell != null) + { + bUpdate |= SetMouseOverCell(null); + } + bUpdate = true; + } + else if (node.MouseOverNodePart != eMouseOverNodePart.Expand) + { + if (node.MouseOverNodePart != eMouseOverNodePart.Node) + { + node.MouseOverNodePart = eMouseOverNodePart.Node; + bUpdate = true; + } + Cell cell = GetCellAt(node, mousePos.X, mousePos.Y, offset); + + if (cell != null) + { + bUpdate |= SetMouseOverCell(cell); + } + } + + if (bUpdate) + InvalidateNode(node); + return bUpdate; + } + // + // private class MouseOverInfo + // { + // public DevComponents.AdvTree.Node Node=null; + // public DevComponents.AdvTree.Cell Cell=null; + // MouseOverInfo() + // { + // this.Node=null; + // this.Cell=null; + // } + // } + + private void OnSelectionBoxChanged() + { + if (this.SelectedNode != null) + { + InvalidateNode(this.SelectedNode); + this.Update(); + } + } + + //private Color GetDefaultSelectionBoxBorderColor() + //{ + // return Color.FromArgb(96,SystemColors.Highlight); + //} + + //private Color GetDefaultSelectionBoxFillColor() + //{ + // return Color.FromArgb(64,SystemColors.Highlight); + //} + + private void OnCommandButtonChanged() + { + _LayoutSettings.CommandAreaWidth = m_CommandWidth; + this.RecalcLayout(); + } + + private void InvokeCellEditEnding(CellEditEventArgs e) + { + if (CellEditEnding != null) + CellEditEnding(this, e); + } + + private void InvokeAfterCellEdit(CellEditEventArgs e) + { + if (AfterCellEdit != null) + AfterCellEdit(this, e); + } + + /// + /// Raises BeforeNodeInsert event + /// + /// Node that is about to be inserted + /// Source of the event + internal protected virtual void InvokeBeforeNodeInsert(eTreeAction action, Node node, Node parentNode) + { + if (BeforeNodeInsert != null) + { + TreeNodeCollectionEventArgs e = new TreeNodeCollectionEventArgs(action, node, parentNode); + BeforeNodeInsert(this, e); + } + } + + /// + /// Raises AfterNodeInsert event + /// + /// Node that is inserted + /// Source of the event + internal protected virtual void InvokeAfterNodeInsert(eTreeAction action, Node node, Node parentNode) + { + if (AfterNodeInsert != null) + { + TreeNodeCollectionEventArgs e = new TreeNodeCollectionEventArgs(action, node, parentNode); + AfterNodeInsert(this, e); + } + } + + /// + /// Raises BeforeNodeRemove event + /// + /// Node that is about to be removed + /// Source of the event + internal protected virtual void InvokeBeforeNodeRemove(eTreeAction action, Node node, Node parentNode) + { + if (BeforeNodeRemove != null) + { + TreeNodeCollectionEventArgs e = new TreeNodeCollectionEventArgs(action, node, parentNode); + BeforeNodeRemove(this, e); + } + } + + /// + /// Raises AfterNodeRemove event + /// + /// Node that is removed + /// Source of the event + internal protected virtual void InvokeAfterNodeRemove(eTreeAction action, Node node, Node parentNode) + { + if (AfterNodeRemove != null) + { + TreeNodeCollectionEventArgs e = new TreeNodeCollectionEventArgs(action, node, parentNode); + AfterNodeRemove(this, e); + } + } + + /// + /// Called after node has been removed + /// + /// Node that is removed + /// Source of the event + internal protected virtual void NodeRemoved(eTreeAction action, Node node, Node parentNode, int indexOfRemovedNode) + { + InvokeAfterNodeRemove(action, node, parentNode); + + if (m_NodeDisplay != null) m_NodeDisplay.PaintedNodes.Clear(); + + if (!this.IsDisposed) + RecalcLayout(); + + if (!this.IsUpdateSuspended) + { + bool updateSelection = false; + if (node.IsSelected) + updateSelection = true; + else + { + Node n = this.SelectedNode; + while (n != null) + { + if (n != null && n == node) + { + updateSelection = true; + break; + } + n = n.Parent; + } + } + + if (updateSelection) + { + Node refNode = parentNode; + bool selectFirst = true; + if (parentNode != null) + { + if (parentNode.Nodes.Count > 0) + { + if (indexOfRemovedNode >= parentNode.Nodes.Count) + indexOfRemovedNode = parentNode.Nodes.Count - 1; + refNode = parentNode.Nodes[indexOfRemovedNode]; + if (refNode.CanSelect) + { + this.SelectNode(refNode, action); + selectFirst = false; + refNode = null; + } + } + else + { + if (refNode.CanSelect) + { + this.SelectNode(refNode, action); + selectFirst = false; + refNode = null; + } + } + + if (refNode != null) + { + while (refNode != null) + { + refNode = NodeOperations.GetPreviousVisibleNode(refNode); + if (refNode != null && refNode.CanSelect) + { + this.SelectNode(refNode, action); + selectFirst = false; + break; + } + } + } + } + else + { + int startIndex = indexOfRemovedNode; + if (this.Nodes.Count == indexOfRemovedNode) startIndex--; + if (startIndex > 0 && this.Nodes.Count > startIndex) + { + for (int i = startIndex; i >= 0; i--) + { + refNode = this.Nodes[i]; + if (refNode.CanSelect && refNode.Visible && refNode.Enabled) + { + this.SelectNode(refNode, action); + selectFirst = false; + break; + } + } + } + } + + if (selectFirst && !SelectFirstNode(action)) + this.SelectNode(null, action); + } + this.Invalidate(); + } + else + { + if (node.IsSelected) + { + if (MultiSelect) + this.SelectedNodes.Remove(node, action); + else + this.SelectNode(null, action); + } + } + } + + private bool SelectFirstNode(eTreeAction action) + { + bool selected = false; + foreach (Node node in this.Nodes) + { + if (node.Selectable && node.Visible && node.Enabled) + { + this.SelectNode(node, action); + if (this.SelectedNode == node) + { + return true; + } + } + } + return false; + } + + /// + /// Invokes BeforeNodeDrop event. If overriden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeBeforeNodeDrop(TreeDragDropEventArgs e) + { + if (BeforeNodeDrop != null) + BeforeNodeDrop(this, e); + } + + /// + /// Invokes AfterNodeDrop event. If overridden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeAfterNodeDrop(TreeDragDropEventArgs e) + { + if (AfterNodeDrop != null) + AfterNodeDrop(this, e); + } + + /// + /// Invokes NodeMouseDown event. If overridden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeNodeMouseDown(TreeNodeMouseEventArgs e) + { + if (e.Node != null) + e.Node.InvokeNodeMouseDown(this, new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta)); + + if (NodeMouseDown != null) + NodeMouseDown(this, e); + } + + /// + /// Invokes NodeMouseUp event. If overridden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeNodeMouseUp(TreeNodeMouseEventArgs e) + { + if (e.Node != null) + e.Node.InvokeNodeMouseUp(this, new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta)); + + if (NodeMouseUp != null) + NodeMouseUp(this, e); + } + + /// + /// Invokes NodeMouseMove event. If overridden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeNodeMouseMove(TreeNodeMouseEventArgs e) + { + if (e.Node != null) + e.Node.InvokeNodeMouseMove(this, new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta)); + + if (NodeMouseMove != null) + NodeMouseMove(this, e); + } + + internal void InternalInvokeNodeClick(TreeNodeMouseEventArgs e) + { + InvokeNodeClick(e); + } + /// + /// Invokes NodeClick event. If overridden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeNodeClick(TreeNodeMouseEventArgs e) + { + if (e.Node != null) + e.Node.InvokeNodeClick(this, e); + + if (NodeClick != null) + NodeClick(this, e); + } + + /// + /// Invokes NodeDoubleClick event. If overridden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeNodeDoubleClick(TreeNodeMouseEventArgs e) + { + if (e.Node != null) + e.Node.InvokeNodeDoubleClick(this, e); + + if (NodeDoubleClick != null) + NodeDoubleClick(this, e); + } + + /// + /// Invokes NodeMouseEnter event. If overriden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeNodeMouseEnter(TreeNodeMouseEventArgs e) + { + if (e.Node != null) + e.Node.InvokeNodeMouseEnter(this, e); + + if (NodeMouseEnter != null) + NodeMouseEnter(this, e); + } + + /// + /// Invokes NodeMouseLeave event. If overriden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeNodeMouseLeave(TreeNodeMouseEventArgs e) + { + if (e.Node != null) + e.Node.InvokeNodeMouseLeave(this, e); + + if (NodeMouseLeave != null) + NodeMouseLeave(this, e); + } + + /// + /// Invokes NodeMouseHover event. If overriden base implementation must be called in order for event to fire. + /// + /// Provides information about event + protected virtual void InvokeNodeMouseHover(TreeNodeMouseEventArgs e) + { + if (e.Node != null) + e.Node.InvokeNodeMouseHover(this, e); + + if (NodeMouseHover != null) + NodeMouseHover(this, e); + } + + private bool FireHoverEvent + { + get { return NodeMouseHover != null; } + } + #endregion + + #region INodeNotify + void INodeNotify.ExpandedChanged(Node node) + { + if (!node.Expanded) + ValidateSelectedNode(); + if (!this.IsUpdateSuspended) + { + this.RecalcLayout(); + this.Refresh(); + } + } + + #endregion + + #region Public Interface + private eView _View = eView.Tree; + /// + /// Gets or sets how control positions the items. Default value is standard TreeView layout. + /// + [DefaultValue(eView.Tree), Category("Appearance"), Description("Indicates how control positions the items.")] + public eView View + { + get { return _View; } + set + { + if (value != _View) + { + eView oldValue = _View; + _View = value; + OnViewChanged(oldValue, value); + } + } + } + private void OnViewChanged(eView oldValue, eView newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("View")); + if (newValue == eView.Tree) + { + m_NodeLayout = new NodeTreeLayout(this, this.ClientRectangle, _LayoutSettings); + //m_NodeLayout.NodeVerticalSpacing = _NodeSpacing; + } + else if (newValue == eView.Tile) + { + m_NodeLayout = new NodeTileLayout(this, this.ClientRectangle, _LayoutSettings); + //m_NodeLayout.NodeHorizontalSpacing = 8; + //m_NodeLayout.NodeVerticalSpacing = 8; + //m_NodeLayout.NodeVerticalSpacing = _NodeSpacing; + } + InvalidateNodesSize(); + RecalcLayout(); + } + + private static readonly Color DefaultTileGroupLineColor = ColorScheme.GetColor(0xE2E2E2); + private Color _TileGroupLineColor = DefaultTileGroupLineColor; + /// + /// Gets or sets the color of the group divider line when in tile view. + /// + [Category("Columns"), Description("Indicates color of the group divider line when in tile view.")] + public Color TileGroupLineColor + { + get { return _TileGroupLineColor; } + set + { + _TileGroupLineColor = value; + if (_View == eView.Tile) + this.Invalidate(); + } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTileGroupLineColor() + { + return !ColorFunctions.IsEqual(DefaultTileGroupLineColor, _TileGroupLineColor); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTileGroupLineColor() + { + this.TileGroupLineColor = DefaultTileGroupLineColor; + } + + /// + /// Save nodes to XmlDocument. New Node AdvTree is created and nodes are serialized into it. + /// + /// Reference to an instance of XmlDocument object + public void Save(XmlDocument document) + { + TreeSerializer.Save(this, document); + } + + /// + /// Saves nodes to a file. + /// + /// File name to save nodes to. + public void Save(string fileName) + { + TreeSerializer.Save(this, fileName); + } + + /// + /// Saves nodes to specified stream. + /// + /// Stream to save nodes to. + public void Save(Stream outStream) + { + TreeSerializer.Save(this, outStream); + } + + /// + /// Saves nodes to specified writer. + /// + /// Writer to save nodes to. + public void Save(TextWriter writer) + { + TreeSerializer.Save(this, writer); + } + + /// + /// Saves nodes to specified writer. + /// + /// Writer to save nodes to. + public void Save(XmlWriter writer) + { + TreeSerializer.Save(this, writer); + } + + /// + /// Load nodes from file. + /// + /// File to load nodes from + public void Load(string fileName) + { + TreeSerializer.Load(this, fileName); + } + + /// + /// Load nodes from stream. + /// + /// Stream to load from + public void Load(Stream inStream) + { + TreeSerializer.Load(this, inStream); + } + + /// + /// Load nodes from reader. + /// + /// Reader to load from. + public void Load(XmlReader reader) + { + TreeSerializer.Load(this, reader); + } + + /// + /// Load nodes from reader. + /// + /// Reader to load from. + public void Load(TextReader reader) + { + TreeSerializer.Load(this, reader); + } + + /// + /// Load nodes from an XmlDocument object. + /// + /// Document to load Nodes from. + public void Load(XmlDocument document) + { + TreeSerializer.Load(this, document); + } + + /// + /// Forces the control to invalidate its client area and immediately redraw itself + /// and any child controls. Note however that this method will node do anything if refresh + /// is suspended as result of call to BeginUpdate method without corresponding EndUpdate + /// call or if SuspendPaint property is set to true. + /// + public override void Refresh() + { + if (!this.IsUpdateSuspended && !this.SuspendPaint) + base.Refresh(); + } + + ///// + ///// Sets the node map position when tree is in Map layout mode. The node's position + ///// can be set only for the sub-root nodes, i.e. nodes that are parented directly to + ///// top-level root node. Setting map position for any other node does not have any effect. + ///// + ///// + ///// Note that setting map position explicitly can change the position for other + ///// nodes that are on the same level as the node that you pass into this method. Since + ///// Map mode layouts the nodes clock-wise, setting the node position to Near will cause + ///// all nodes that are in collection after the reference node to be + ///// positioned Near as well. + ///// Similarly, setting the node position to Far will cause all nodes that are in + ///// collection before the reference node to be positioned Far as + ///// well. + ///// + ///// Sub-root node to set layout position for. + ///// The position relative to the root node should take + //public void SetNodeMapPosition(Node node, eMapPosition position) + //{ + // if(node==null || node.Parent==null) + // return; + + // if(position==eMapPosition.Default) + // { + // node.SetMapSubRootPosition(position); + // } + // else if(position==eMapPosition.Near) + // { + // int start=node.Parent.Nodes.IndexOf(node); + // int end=node.Parent.Nodes.Count; + // for(int i=start;i=0;i--) + // node.Parent.Nodes[i].SetMapSubRootPosition(position); + // } + //} + + private bool _ProcessingSortRequests = false; + private void ProcessSortRequests() + { + if (_ProcessingSortRequests) return; + _ProcessingSortRequests = true; + try + { + if (_TopLevelSortRequest) + { + _TopLevelSortRequest = false; + if (m_Columns.IsSorted) + m_Columns.UpdateSort(); + } + if (_SortRequestNodes.Count > 0) + { + foreach (Node sortRequestNode in _SortRequestNodes) + { + if (sortRequestNode.NodesColumns.IsSorted) + sortRequestNode.NodesColumns.UpdateSort(); + } + _SortRequestNodes.Clear(); + } + } + finally + { + _ProcessingSortRequests = false; + } + } + + private List _SortRequestNodes = new List(); + private bool _TopLevelSortRequest = false; + internal void PushSortRequest() + { + PushSortRequest(null); + } + internal void PushSortRequest(Node parentNode) + { + if (parentNode == null) + _TopLevelSortRequest = true; + else if (!_SortRequestNodes.Contains(parentNode)) + _SortRequestNodes.Add(parentNode); + } + + /// + /// Disables any redrawing of the tree control. To maintain performance while items + /// are added one at a time to the control, call the BeginUpdate method. The BeginUpdate + /// method prevents the control from painting until the + /// EndUpdate method is called. + /// + public void BeginUpdate() + { + m_UpdateSuspended++; + } + + /// + /// Enables the redrawing of the tree view. To maintain performance while items are + /// added one at a time to the control, call the BeginUpdate + /// method. The BeginUpdate method prevents the control from painting until the EndUpdate + /// method is called. + /// + /// + /// Call to EndUpdate will enable the layout and painting in tree control. If there + /// are any pending layouts the EndUpdate will call + /// RecalcLayout method to perform the layout and it will + /// repaint the control. + /// + public void EndUpdate() + { + EndUpdate(true); + } + + /// + /// Enables the redrawing of the tree view. To maintain performance while items are + /// added one at a time to the control, call the BeginUpdate + /// method. The BeginUpdate method prevents the control from painting until the EndUpdate + /// method is called. + /// + /// Gets or sets whether layout and refresh of control is performed if there are no other update blocks pending. + public void EndUpdate(bool performLayoutAndRefresh) + { + if (m_UpdateSuspended > 0) m_UpdateSuspended--; + if (m_UpdateSuspended == 0 && performLayoutAndRefresh) + { + this.RecalcLayout(); + this.Invalidate(true); + } + } + + /// + /// Retrieves the tree node that is at the specified location. + /// + /// The Node at the specified point, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// The Point to evaluate and retrieve the node from. + public Node GetNodeAt(Point p) + { + return GetNodeAt(p.X, p.Y); + } + + /// + /// Retrieves the tree node that is at the specified location. + /// + /// The TreeNode at the specified location, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// The X position to evaluate and retrieve the node from. + /// The Y position to evaluate and retrieve the node from. + public Node GetNodeAt(int x, int y) + { + return NodeOperations.GetNodeAt(this, x, y).NodeAt; + } + + /// + /// Retrieves the tree node that is at the specified location. + /// + /// The TreeNode at the specified location, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// The X position to evaluate and retrieve the node from. + /// The Y position to evaluate and retrieve the node from. + /// Whether to enumerated displayed nodes only. + public Node GetNodeAt(int x, int y, bool displayedOnly) + { + return NodeOperations.GetNodeAt(this, x, y, displayedOnly).NodeAt; + } + + /// + /// Retrieves the tree node that is at the specified vertical location. + /// + /// The TreeNode at the specified location, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.Y coordinates of the + /// MouseDown event as the y parameter. + /// + /// The Y position to evaluate and retrieve the node from. + public Node GetNodeAt(int y) + { + return NodeOperations.GetNodeAt(this, y).NodeAt; + } + + /// + /// Retrieves the node cell that is at the specified location. + /// + /// The Point to evaluate and retrieve the cell from. + /// The Cell at the specified point, in tree view coordinates. + public Cell GetCellAt(Point p) + { + return GetCellAt(p.X, p.Y); + } + + /// + /// Retrieves the node cell that is at the specified location. + /// + /// The X position to evaluate and retrieve the cell from. + /// The Y position to evaluate and retrieve the cell from. + /// The Cell at the specified point, in tree view coordinates. + public Cell GetCellAt(int x, int y) + { + return GetCellAt(x, y, false); + } + + /// + /// Retrieves the node cell that is at the specified location. + /// + /// The X position to evaluate and retrieve the cell from. + /// The Y position to evaluate and retrieve the cell from. + /// Whether to enumerated displayed nodes only. + /// The Cell at the specified point, in tree view coordinates. + public Cell GetCellAt(int x, int y, bool displayedOnly) + { + Node node = GetNodeAt(x, y, displayedOnly); + if (node != null) + { + return GetCellAt(node, x, y, m_NodeDisplay.Offset); + } + return null; + } + + /// + /// Returns the reference to the node mouse is currently over or null (Nothing) if mouse is not over any node in tree. + /// + [Browsable(false)] + public Node MouseOverNode + { + get + { + return m_MouseOverNode; + } + } + + /// + /// Specifies the mouse cursor displayed when mouse is over the cell. Default value + /// is null which means that default control cursor is used. + /// + /// + /// To specify cursor for each individual cell use + /// Cell.Cursor property. + /// + [Browsable(true), DefaultValue(null), Category("Appearance"), Description("Specifies the default mouse cursor displayed when mouse is over the cell.")] + public Cursor DefaultCellCursor + { + get + { + return m_DefaultCellCursor; + } + set + { + if (m_DefaultCellCursor != value) + { + m_DefaultCellCursor = value; + } + } + } + + /// Applies any layout changes to the tree control. + /// + /// Layout will not be performed if BeginUpdate is called. Any calls to the + /// RecalcLayout will return without executing requested layout operation. + /// + public void RecalcLayout() + { + if (this.IsUpdateSuspended) + { + m_PendingLayout = true; + return; + } + RecalcLayoutInternal(); + } + + protected override void OnFontChanged(EventArgs e) + { + InvalidateNodesSize(); + RecalcLayout(); + base.OnFontChanged(e); + } + + /// + /// Gets reference to array of Cell objects that have HostedControl property set. + /// + internal ArrayList HostedControlCells + { + get { return m_HostedControlCells; } + } + + private bool _FirstLayout = true; + private delegate void NoArgumentsDelegate(); + /// + /// Recalculates layout for the tree control. Not affected by BeginUpdate call. + /// + internal void RecalcLayoutInternal() + { + if (this.Bounds.IsEmpty || this.IsDisposed) return; + if (this.InvokeRequired) + { + this.Invoke(new NoArgumentsDelegate(RecalcLayoutInternal)); + return; + } + + _FirstLayout = false; + + // Process any pending sorting requests first + ProcessSortRequests(); + + Rectangle clientArea = Rectangle.Empty, controlRect = Rectangle.Empty; + GetClientAndControlRectangles(ref clientArea, ref controlRect); + + m_NodeLayout.ClientArea = clientArea; + m_NodeLayout.LeftRight = this.RtlTranslateLeftRight(LeftRightAlignment.Left); + m_NodeLayout.PerformLayout(); + m_PendingLayout = false; + + UpdateScrollState(clientArea, controlRect); + + if (_InvalidControlBorder) + UpdateControlBorderPanel(); + RepositionHostedControls(true); + RepositionColumnHeader(); + UpdateScrollBars(); + this.Invalidate(true); + } + private void GetClientAndControlRectangles(ref Rectangle clientArea, ref Rectangle controlRect) + { + clientArea = GetInnerRectangle(); + if ((m_Columns.Count > 0 && m_Columns.UsesRelativeSize || _View == eView.Tile) && _VScrollBar != null) + clientArea.Width -= _VScrollBar.Width; + controlRect = clientArea; + + if (this.SelectionBoxStyle == eSelectionStyle.NodeMarker) + clientArea.Inflate(-this.SelectionBoxSize, -this.SelectionBoxSize); + else + { + if (this.DisplayRootNode != null && !this.DisplayRootNode.Selectable || this.Nodes.Count > 0 && !this.Nodes[0].Selectable) + clientArea.Height -= 2; + else + clientArea.Inflate(-1, -2); + } + } + private void UpdateScrollState() + { + Rectangle clientArea = Rectangle.Empty, controlRect = Rectangle.Empty; + GetClientAndControlRectangles(ref clientArea, ref controlRect); + UpdateScrollState(clientArea, controlRect); + } + private void UpdateScrollState(Rectangle clientArea, Rectangle controlRect) + { + Rectangle screenRect = GetScreenRectangle(new Rectangle(0, 0, m_NodeLayout.Width, m_NodeLayout.Height)); + Size nodeLayoutSize = screenRect.Size; + if (nodeLayoutSize.Width > controlRect.Width || nodeLayoutSize.Height > controlRect.Height) + { + Size autoScrollMinSize = nodeLayoutSize; + if (this.SelectionBoxStyle == eSelectionStyle.NodeMarker) + { + autoScrollMinSize.Width += this.SelectionBoxSize * 2; + autoScrollMinSize.Height += this.SelectionBoxSize * 2; + } + else + { + //autoScrollMinSize.Width += 2; + autoScrollMinSize.Height += 2; + } + Rectangle inner = clientArea; //GetInnerRectangle(); + + if (nodeLayoutSize.Height > inner.Height && _VScrollBarVisible || + nodeLayoutSize.Width > inner.Width && nodeLayoutSize.Height > inner.Height - SystemInformation.HorizontalScrollBarHeight) + autoScrollMinSize.Width += SystemInformation.VerticalScrollBarWidth; + + if (_HScrollBarVisible) + autoScrollMinSize.Height += SystemInformation.HorizontalScrollBarHeight; + + if (!this.AutoScroll) + { + this.BeginUpdate(); + this.Invalidate(); + this.AutoScroll = true; + this.AutoScrollMinSize = autoScrollMinSize; + this.AutoScrollPosition = m_NodeDisplay.DefaultOffset; + if (m_Columns.Count > 0 && m_Columns.UsesRelativeSize || _View == eView.Tile) + { + InvalidateNodesSize(); + SetPendingLayout(); + } + this.EndUpdate(false); + } + else if (this.AutoScrollMinSize != autoScrollMinSize) + { + this.BeginUpdate(); + this.AutoScrollMinSize = autoScrollMinSize; + if (nodeLayoutSize.Width <= this.Bounds.Width && this.AutoScrollPosition.X != 0) + { + this.AutoScrollPosition = new Point(0, this.AutoScrollPosition.Y); + } + Point asp = this.AutoScrollPosition; + if (Math.Abs(asp.Y) > autoScrollMinSize.Height) + { + if (autoScrollMinSize.Height > inner.Height) + asp.Y = -(autoScrollMinSize.Height - inner.Height); + else + asp.Y = 0; + } + else if (nodeLayoutSize.Height <= this.Bounds.Height) + asp.Y = 0; + else if (asp.Y<0 && autoScrollMinSize.Height - Math.Abs(asp.Y) < clientArea.Height) // Overscroll test + { + asp.Y = -(autoScrollMinSize.Height - inner.Height); + } + + if (Math.Abs(asp.X) > autoScrollMinSize.Width) + { + asp.X = -(autoScrollMinSize.Width - inner.Width); + } + else if (nodeLayoutSize.Width <= this.Bounds.Width) + asp.X = 0; + if (this.AutoScrollPosition != asp) this.AutoScrollPosition = asp; + this.EndUpdate(false); + } + else if(_AutoScrollPosition.X != 0 && nodeLayoutSize.Width <= controlRect.Width) + this.AutoScrollPosition = new Point(0, this.AutoScrollPosition.Y); + } + else if (this.AutoScroll) + { + this.BeginUpdate(); + bool updateColumnsWidth = false; + if (m_Columns.Count > 0 && _VScrollBar != null) + { + if (m_Columns.UsesRelativeSize) + InvalidateNodesSize(); + else + updateColumnsWidth = true; + } + + this.AutoScroll = false; + m_NodeDisplay.Offset = m_NodeDisplay.DefaultOffset; + if (updateColumnsWidth) m_NodeLayout.UpdateTopLevelColumnsWidth(); + this.EndUpdate(false); + } + else + m_NodeDisplay.Offset = m_NodeDisplay.DefaultOffset; + } + private bool _ClipHostedControls = true; + /// + /// Gets or sets whether hosted controls are clipped so they don't overlap the control borders. Default value is true. + /// + [Browsable(false), DefaultValue(true)] + public bool ClipHostedControls + { + get { return _ClipHostedControls; } + set + { + _ClipHostedControls = value; + UpdateControlBorderPanel(); + } + } + + internal bool IsRepositioningControls + { + get + { + return _IsRepositioningControls; + } + } + private bool _IsRepositioningControls = false; + private PanelControl _ControlBorderPanel = null; + private void RemoveControlBorderPanel() + { + if (_ControlBorderPanel == null) return; + + if (_IsLayoutOrResize > 0) + { + if (_IsUpdateControlBorderPanelPending) return; + + // Delay this due to http://support.microsoft.com/kb/949458 bug in WinForms and MDI-Child Forms + _IsUpdateControlBorderPanelPending = true; + InvokeDelayed(new MethodInvoker(delegate { this.RemoveControlBorderPanel(); })); + return; + } + _IsUpdateControlBorderPanelPending = false; + + PanelControl control = _ControlBorderPanel; + _ControlBorderPanel = null; + this.Controls.Remove(control); + control.Dispose(); + } + + private bool _InvalidControlBorder = true; + /// + /// Gets or sets whether control border needs to be updated by calling UpdateControlBorderPanel() + /// + internal bool InvalidControlBorder + { + get { return _InvalidControlBorder; } + set + { + _InvalidControlBorder = value; + } + } + private bool _IsUpdateControlBorderPanelPending = false; + private void UpdateControlBorderPanel() + { + if (!_ClipHostedControls) + { + RemoveControlBorderPanel(); + return; + } + if (m_HostedControlCells.Count > 0) + { + Rectangle innerRect = GetInnerRectangle(); + Rectangle cr = this.ClientRectangle; + if (cr.Contains(innerRect) && innerRect != cr && + innerRect.X > cr.X && innerRect.Right < cr.Right && innerRect.Y > cr.Y && innerRect.Bottom < cr.Bottom) + { + if (_ControlBorderPanel == null) + { + if (_IsLayoutOrResize > 0) + { + if (_IsUpdateControlBorderPanelPending) return; + + // Delay this due to http://support.microsoft.com/kb/949458 bug in WinForms and MDI-Child Forms + _IsUpdateControlBorderPanelPending = true; + InvokeDelayed(new MethodInvoker(delegate { this.UpdateControlBorderPanel(); })); + return; + } + _IsUpdateControlBorderPanelPending = false; + _ControlBorderPanel = new PanelControl(); + _ControlBorderPanel.CanSetRegion = false; + _ControlBorderPanel.Style.ApplyStyle(this.BackgroundStyle); + _ControlBorderPanel.Style.Class = this.BackgroundStyle.Class; + this.Controls.Add(_ControlBorderPanel); + } + _ControlBorderPanel.Bounds = cr; + Region region = new Region(cr); + region.Exclude(innerRect); + _ControlBorderPanel.Region = region; + _ControlBorderPanel.BringToFront(); + } + else + { + RemoveControlBorderPanel(); + } + } + else + RemoveControlBorderPanel(); + _InvalidControlBorder = false; + } + private void RepositionHostedControls(bool performLayout) + { + if (_IsRepositioningControls) return; + try + { + _IsRepositioningControls = true; + if (m_HostedControlCells.Count > 0) + { + this.SuspendLayout(); + if (this.AutoScroll) + m_NodeDisplay.Offset = GetAutoScrollPositionOffset(); + m_NodeDisplay.MoveHostedControls(); + + this.ResumeLayout(performLayout); + } + else if (_ControlBorderPanel != null) + { + RemoveControlBorderPanel(); + } + + if (m_CellEditing && _CellEditControl is Control && m_EditedCell != null) + { + Point offset = m_NodeDisplay.Offset; + if (this.AutoScroll) + offset = GetAutoScrollPositionOffset(); + Control editControl = (Control)_CellEditControl; + Rectangle rCell = NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds, m_EditedCell, offset); + rCell = GetScreenRectangle(rCell); + editControl.Location = rCell.Location; + } + + + } + finally + { + _IsRepositioningControls = false; + } + } + + /// + /// Gets the reference to internal vertical scroll-bar control if one is created or null if no scrollbar is visible. + /// + [Browsable(false)] + public DevComponents.DotNetBar.VScrollBarAdv VScrollBar + { + get + { + return _VScrollBar; + } + } + + private bool _VScrollBarVisible = true; + /// + /// Gets or sets whether Vertical Scroll-bar is shown if needed because content of the control exceeds available height. Default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether Vertical Scroll-bar is shown if needed because content of the control exceeds available height.")] + public bool VScrollBarVisible + { + get { return _VScrollBarVisible; } + set + { + _VScrollBarVisible = value; + if (!_VScrollBarVisible && _VScrollBar != null) _VScrollBar.Visible = false; + } + } + + private bool _HScrollBarVisible = true; + /// + /// Gets or sets whether Horizontal Scroll-bar is shown if needed because content of the control exceeds available width. Default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether Vertical Scroll-bar is shown if needed because content of the control exceeds available height.")] + public bool HScrollBarVisible + { + get { return _HScrollBarVisible; } + set + { + _HScrollBarVisible = value; + if (!_HScrollBarVisible && _HScrollBar != null) _HScrollBar.Visible = false; + } + } + + + /// + /// Gets the reference to internal horizontal scroll-bar control if one is created or null if no scrollbar is visible. + /// + [Browsable(false)] + public DevComponents.DotNetBar.ScrollBar.HScrollBarAdv HScrollBar + { + get + { + return _HScrollBar; + } + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMargin + { + get { return base.AutoScrollMargin; } + set { base.AutoScrollMargin = value; } + } + + private bool _AutoScroll = false; + /// + /// Gets or sets a value indicating whether the tree control enables the user to scroll to any nodes placed outside of its visible boundaries. + /// This property is managed internally by AdvTree control and should not be modified. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool AutoScroll + { + get { return _AutoScroll; } + set + { + if (_AutoScroll != value) + { + _AutoScroll = value; + UpdateScrollBars(); + } + } + } + + private Size _AutoScrollMinSize = Size.Empty; + /// + /// Gets or sets the minimum size of the auto-scroll. Returns a Size that represents the minimum height and width of the scrolling area in pixels. + /// This property is managed internally by AdvTree control and should not be modified. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMinSize + { + get { return _AutoScrollMinSize; } + set + { + _AutoScrollMinSize = value; + UpdateScrollBars(); + } + } + + private Point _AutoScrollPositionChange = Point.Empty; + private Point _AutoScrollPosition = Point.Empty; + /// + /// Gets or sets the location of the auto-scroll position. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false), Description("Indicates location of the auto-scroll position.")] + public new Point AutoScrollPosition + { + get + { + return _AutoScrollPosition; + } + set + { + //if (value.X > 0) value.X = -value.X; + //if (value.Y > 0) value.Y = -value.Y; + if (_AutoScrollPosition != value) + { + _AutoScrollPositionChange = new Point(value.X - _AutoScrollPosition.X, value.Y - _AutoScrollPosition.Y); + _AutoScrollPosition = value; + if (_AutoScroll) + { + if (_VScrollBar != null && _VScrollBar.Value != -_AutoScrollPosition.Y) + _VScrollBar.Value = Math.Min(_VScrollBar.Maximum, Math.Max(_VScrollBar.Minimum, -_AutoScrollPosition.Y)); + if (_HScrollBar != null && _HScrollBar.Value != -_AutoScrollPosition.X) + _HScrollBar.Value = Math.Min(_HScrollBar.Maximum, Math.Max(_HScrollBar.Minimum, -_AutoScrollPosition.X)); + RepositionHostedControls(false); + Invalidate(); + m_NodeDisplay.Offset = Point.Empty; // Reset render offset + if (_ColumnHeader != null) _ColumnHeader.Invalidate(); + } + } + } + } + + private void InvokeDelayed(MethodInvoker method) + { + Timer delayedInvokeTimer = new Timer(); + delayedInvokeTimer = new Timer(); + delayedInvokeTimer.Tag = method; + delayedInvokeTimer.Interval = 10; + delayedInvokeTimer.Tick += new EventHandler(DelayedInvokeTimerTick); + delayedInvokeTimer.Start(); + } + void DelayedInvokeTimerTick(object sender, EventArgs e) + { + Timer timer = (Timer)sender; + MethodInvoker method = (MethodInvoker)timer.Tag; + timer.Stop(); + timer.Dispose(); + method.Invoke(); + } + + private bool _IsUpdateScrollBarsPending = false; + private void UpdateScrollBars() + { + if (_IsLayoutOrResize > 0) + { + //Form form = this.FindForm(); + //if (form != null && form.IsMdiChild) + { + if (_IsUpdateScrollBarsPending) return; + + // Delay this due to http://support.microsoft.com/kb/949458 bug in WinForms and MDI-Child Forms + _IsUpdateScrollBarsPending = true; + InvokeDelayed(new MethodInvoker(delegate { this.UpdateScrollBars(); })); + return; + } + } + + _IsUpdateScrollBarsPending = false; + if (!_AutoScroll) + { + bool update = _HScrollBar != null || _VScrollBar != null; + RemoveHScrollBar(); + RemoveVScrollBar(); + if (_Thumb != null) + { + this.Controls.Remove(_Thumb); + _Thumb.Dispose(); + _Thumb = null; + } + if (update) + this.Update(); + return; + } + + //Node root = GetDisplayRootNode(); + Rectangle innerBounds = ElementStyleLayout.GetInnerRect(this.BackgroundStyle, this.ClientRectangle); + // Check do we need vertical scrollbar + Size scrollSize = _AutoScrollMinSize; + if (_VScrollBarVisible && scrollSize.Height > innerBounds.Height) + { + if (_VScrollBar == null) + { + _VScrollBar = new DevComponents.DotNetBar.VScrollBarAdv(); + _VScrollBar.Appearance = _ScrollBarAppearance; + _VScrollBar.Width = GetVerticalScrollBarWidth(); + this.Controls.Add(_VScrollBar); + _VScrollBar.BringToFront(); + _VScrollBar.Scroll += new ScrollEventHandler(VScrollBarScroll); + } + if (_VScrollBar.Minimum != 0) + _VScrollBar.Minimum = 0; + int innerHeight = innerBounds.Height - 12; + if (_ColumnHeader != null && _ColumnHeader.Visible) + innerHeight -= _ColumnHeader.Height + 2; + if (_VScrollBar.LargeChange != innerHeight && innerHeight > 0) + _VScrollBar.LargeChange = innerHeight; + //if (root != null && root.Bounds.Height > 0) + // _VScrollBar.SmallChange = root.Bounds.Height; + //else + // _VScrollBar.SmallChange = 22; + _VScrollBar.SmallChange = (int)Math.Ceiling(this.Font.GetHeight()); + if (_VScrollBar.Maximum != _AutoScrollMinSize.Height) + _VScrollBar.Maximum = _AutoScrollMinSize.Height; + if (_VScrollBar.Value != -_AutoScrollPosition.Y) + _VScrollBar.Value = (Math.Min(_VScrollBar.Maximum, Math.Abs(_AutoScrollPosition.Y))); + } + else + RemoveVScrollBar(); + + // Check horizontal scrollbar + if (_HScrollBarVisible && scrollSize.Width > innerBounds.Width) + { + if (_HScrollBar == null) + { + _HScrollBar = new DevComponents.DotNetBar.ScrollBar.HScrollBarAdv(); + _HScrollBar.Appearance = _ScrollBarAppearance; + _HScrollBar.Height = GetHorizontalScrollBarHeight(); + this.Controls.Add(_HScrollBar); + _HScrollBar.BringToFront(); + _HScrollBar.Scroll += new ScrollEventHandler(HScrollBarScroll); + } + if (_HScrollBar.Minimum != 0) + _HScrollBar.Minimum = 0; + if (_HScrollBar.LargeChange != innerBounds.Width && innerBounds.Width > 0) + _HScrollBar.LargeChange = innerBounds.Width; + if (_HScrollBar.Maximum != _AutoScrollMinSize.Width) + _HScrollBar.Maximum = _AutoScrollMinSize.Width; + if (_HScrollBar.Value != -_AutoScrollPosition.X) + _HScrollBar.Value = (Math.Min(_HScrollBar.Maximum, Math.Abs(_AutoScrollPosition.X))); + //if (root != null && root.Bounds.Height > 0) + // _HScrollBar.SmallChange = root.Bounds.Height; + //else + // _HScrollBar.SmallChange = 22; + _HScrollBar.SmallChange = (int)Math.Ceiling(this.Font.GetHeight()); + } + else + RemoveHScrollBar(); + + RepositionScrollBars(); + + if (_Thumb != null) + _Thumb.BringToFront(); + } + + private static int GetHorizontalScrollBarHeight() + { + return SystemInformation.HorizontalScrollBarHeight; + } + + private static int GetVerticalScrollBarWidth() + { + return SystemInformation.VerticalScrollBarWidth; + } + + private void VScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.NewValue != e.OldValue) + { + _AutoScrollPosition.Y = -e.NewValue; + RepositionHostedControls(false); + this.Invalidate(); + if (_ColumnHeader != null) _ColumnHeader.Invalidate(); + if (e.Type == ScrollEventType.ThumbTrack && m_HostedControlCells.Count > 0) + this.Update(); + } + OnScroll(new ScrollEventArgs(e.Type, e.OldValue, e.NewValue, ScrollOrientation.VerticalScroll)); + } + private void HScrollBarScroll(object sender, ScrollEventArgs e) + { + _AutoScrollPosition.X = -e.NewValue; + RepositionHostedControls(false); + this.Invalidate(); + if (_ColumnHeader != null) _ColumnHeader.Invalidate(); + if (e.Type == ScrollEventType.ThumbTrack && m_HostedControlCells.Count > 0) + this.Update(); + + OnScroll(new ScrollEventArgs(e.Type, e.OldValue, e.NewValue, ScrollOrientation.HorizontalScroll)); + } + + private void RepositionScrollBars() + { + Rectangle innerBounds = ElementStyleLayout.GetInnerRect(this.BackgroundStyle, this.ClientRectangle); + if (_HScrollBar != null) + { + int width = innerBounds.Width; + if (_VScrollBar != null) + width -= _VScrollBar.Width; + _HScrollBar.Bounds = new Rectangle(innerBounds.X, innerBounds.Height - GetHorizontalScrollBarHeight() + 1, width, GetHorizontalScrollBarHeight()); + } + + if (_VScrollBar != null) + { + int height = innerBounds.Height; + if (_HScrollBar != null) + height -= _HScrollBar.Height; + _VScrollBar.Bounds = new Rectangle(innerBounds.Right - GetVerticalScrollBarWidth(), innerBounds.Y, GetVerticalScrollBarWidth(), height); + } + + if (_VScrollBar != null && _HScrollBar != null) + { + if (_Thumb == null) + { + _Thumb = new Control(); + _Thumb.BackColor = this.BackColor; + this.Controls.Add(_Thumb); + } + _Thumb.Bounds = new Rectangle(_HScrollBar.Bounds.Right, _VScrollBar.Bounds.Bottom, _VScrollBar.Width, _HScrollBar.Height); + } + else if (_Thumb != null) + { + this.Controls.Remove(_Thumb); + _Thumb.Dispose(); + _Thumb = null; + } + RepositionColumnHeader(); + } + + internal int ColumnHeaderHeight + { + get + { + return _ColumnHeader != null ? _ColumnHeader.Height : 0; + } + } + + private void RepositionColumnHeader() + { + Rectangle innerBounds = ElementStyleLayout.GetInnerRect(this.BackgroundStyle, this.ClientRectangle); + if (_ColumnHeader != null) + { + Rectangle r = GetScreenRectangle(new Rectangle(innerBounds.X, innerBounds.Y, + innerBounds.Width - (_VScrollBar != null ? _VScrollBar.Width : 0), _ColumnHeader.Columns.Bounds.Height)); + r.X = innerBounds.X; + r.Y = innerBounds.Y; + r.Width = Math.Max(0, innerBounds.Width - (_VScrollBar != null ? _VScrollBar.Width : 0)); + r.Height = Math.Max(0, r.Height); + _ColumnHeader.Bounds = r; + _ColumnHeader.BringToFront(); + } + } + + private void RemoveHScrollBar() + { + if (_HScrollBar != null) + { + Rectangle r = _HScrollBar.Bounds; + this.Controls.Remove(_HScrollBar); + _HScrollBar.Dispose(); + _HScrollBar = null; + this.Invalidate(r); + } + } + + private void RemoveVScrollBar() + { + if (_VScrollBar != null) + { + Rectangle r = _VScrollBar.Bounds; + this.Controls.Remove(_VScrollBar); + _VScrollBar.Dispose(); + _VScrollBar = null; + this.Invalidate(r); + } + } + + private System.Drawing.Drawing2D.Matrix GetTranslationMatrix(float zoom) + { + System.Drawing.Drawing2D.Matrix mx = new System.Drawing.Drawing2D.Matrix(zoom, 0, 0, zoom, 0, 0); + if (this.CenterContent) + { + float offsetX = 0, offsetY = 0; + if (this.AutoScroll) + { + if (this.Width > this.NodeLayout.Width) + { + if (this.Width < this.NodeLayout.Width * zoom) + offsetX = -(this.Width - this.NodeLayout.Width) / 2; + else + offsetX = (this.Width * (1.0f / zoom) - this.Width) / 2; + } + + if (this.Height > this.NodeLayout.Height) + { + if (this.Height < this.NodeLayout.Height * zoom) + offsetY = -(this.Height - this.NodeLayout.Height) / 2; + else + offsetY = (this.Height * (1.0f / zoom) - this.Height) / 2; + } + } + else + { + offsetX = (this.Width * (1.0f / zoom) - this.Width) / 2; + offsetY = (this.Height * (1.0f / zoom) - this.Height) / 2; + } + + mx.Translate(offsetX, offsetY); + } + return mx; + } + + /// + /// Returns translation matrix for current Zoom. Translation matrix is used to translate internal node coordinates to screen + /// coordinates when Zoom is not set to 1. + /// + /// Returns new instance of Matrix object. + public System.Drawing.Drawing2D.Matrix GetTranslationMatrix() + { + return GetTranslationMatrix(m_ZoomFactor); + } + + /// + /// Returns layout based rectangle from screen rectangle. Layout based rectangle will be different + /// from screen rectangle when Zoom is not set to 1. This method will translate the screen rectangle enlarged by Zoom + /// to layout rectangle which does not have Zoom applied. + /// + /// Screen rectangle + /// Layout rectangle + public virtual Rectangle GetLayoutRectangle(Rectangle r) + { + if (m_ZoomFactor == 1) + return r; + + Point[] p = new Point[] { new Point(r.X, r.Y), new Point(r.Right, r.Bottom) }; + using (System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix()) + { + mx.Invert(); + mx.TransformPoints(p); + } + return new Rectangle(p[0].X, p[0].Y, p[1].X - p[0].X, p[1].Y - p[0].Y); + } + + /// + /// Returns mouse position which is translated if control Zoom is not equal 1 + /// + /// Mouse event arguments + /// Returns translated position + protected virtual Point GetLayoutPosition(MouseEventArgs e) + { + return GetLayoutPosition(e.X, e.Y); + } + + /// + /// Returns mouse position which is translated if control Zoom is not equal 1 + /// + /// Mouse position + /// Returns translated position + public virtual Point GetLayoutPosition(Point mousePosition) + { + return GetLayoutPosition(mousePosition.X, mousePosition.Y); + } + + /// + /// Returns mouse position which is translated if control Zoom is not equal 1 + /// + /// X coordinate + /// Y coordinate + /// + public virtual Point GetLayoutPosition(int x, int y) + { + if (m_ZoomFactor == 1) + return new Point(x, y); + Point[] p = new Point[] { new Point(x, y) }; + using (System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix()) + { + mx.Invert(); + mx.TransformPoints(p); + } + return p[0]; + } + + /// + /// Returns rectangle translated to screen rectangle if Zoom is not equal 1. + /// + /// Rectangle to translate + /// Screen Rectangle + public virtual Rectangle GetScreenRectangle(Rectangle r) + { + if (m_ZoomFactor == 1) + return r; + Point[] p = new Point[] { new Point(r.X, r.Y), new Point(r.Right, r.Bottom) }; + using (System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix()) + { + mx.TransformPoints(p); + } + return new Rectangle(p[0].X, p[0].Y, p[1].X - p[0].X, p[1].Y - p[0].Y); + } + + /// + /// Returns size translated to screen dimension if Zoom is not equal 1. + /// + /// Size to translate + /// Screen Size + public virtual Size GetScreenSize(Size s) + { + return GetScreenRectangle(new Rectangle(Point.Empty, s)).Size; + } + + internal void InvokeColumnHeaderMouseUp(object sender, MouseEventArgs e) + { + OnColumnHeaderMouseUp(sender, e); + } + /// + /// Raises ColumnHeaderMouseUp event. + /// + /// Reference to ColumnHeader + /// Event arguments + protected virtual void OnColumnHeaderMouseUp(object sender, MouseEventArgs e) + { + if (ColumnHeaderMouseUp != null) + ColumnHeaderMouseUp(sender, e); + } + + internal void InvokeColumnHeaderMouseDown(object sender, MouseEventArgs e) + { + OnColumnHeaderMouseDown(sender, e); + } + /// + /// Raises ColumnHeaderMouseDown event. + /// + /// Reference to ColumnHeader + /// Event arguments + protected virtual void OnColumnHeaderMouseDown(object sender, MouseEventArgs e) + { + if (ColumnHeaderMouseDown != null) + ColumnHeaderMouseDown(sender, e); + } + + /// + /// Gets the list of all checked nodes in tree including child nodes. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public System.Collections.Generic.List CheckedNodes + { + get + { + System.Collections.Generic.List items = new System.Collections.Generic.List(); + NodeCollection itemsCollection = this.Nodes; + GetSelectedNodes(items, itemsCollection); + return items; + } + } + + private static void GetSelectedNodes(System.Collections.Generic.List items, NodeCollection itemsCollection) + { + foreach (Node item in itemsCollection) + { + if (item.Checked) + items.Add(item); + + if (item.HasChildNodes) + { + GetSelectedNodes(items, item.Nodes); + } + } + } + #endregion + + #region Event Invocation + /// + /// Calls OnBeforeCheck method which fired + /// OnBeforeCheck event. + /// + /// Event arguments. + internal void InvokeBeforeCheck(AdvTreeCellBeforeCheckEventArgs e) + { + OnBeforeCheck(e); + } + + /// Raises the BeforeCheck event. + /// + /// A AdvTreeCellBeforeCheckEventArgs that contains the event + /// data. + /// + protected virtual void OnBeforeCheck(AdvTreeCellBeforeCheckEventArgs e) + { + if (BeforeCheck != null) + BeforeCheck(this, e); + } + + /// + /// Calls OnAfterCheck method which fired + /// AfterCheck event. + /// + /// Event arguments. + internal void InvokeAfterCheck(AdvTreeCellEventArgs e) + { + OnAfterCheck(e); + } + + /// Raises the AfterCheck event. + /// + /// A AdvTreeEventArgs that contains the event + /// data. + /// + protected virtual void OnAfterCheck(AdvTreeCellEventArgs e) + { + if (AfterCheck != null) + AfterCheck(this, e); + } + + /// + /// Invokes CommandButtonClick event. + /// + /// Context node. + /// Event arguments. + internal void InvokeCommandButtonClick(Node node, CommandButtonEventArgs e) + { + if (CommandButtonClick != null) + CommandButtonClick(node, e); + } + + protected virtual void OnBeforeCellEdit(CellEditEventArgs e) + { + if (BeforeCellEdit != null) + BeforeCellEdit(this, e); + } + + void INodeNotify.OnBeforeCollapse(AdvTreeNodeCancelEventArgs e) + { + if (BeforeCollapse != null) + BeforeCollapse(this, e); + } + + void INodeNotify.OnAfterCollapse(AdvTreeNodeEventArgs e) + { + if (AfterCollapse != null) + AfterCollapse(this, e); + } + + void INodeNotify.OnBeforeExpand(AdvTreeNodeCancelEventArgs e) + { + if (BeforeExpand != null) + BeforeExpand(this, e); + } + + void INodeNotify.OnAfterExpand(AdvTreeNodeEventArgs e) + { + if (AfterExpand != null) + AfterExpand(this, e); + } + + internal void InvokeOnAfterNodeDeselect(AdvTreeNodeEventArgs args) + { + OnAfterNodeDeselect(args); + } + protected virtual void OnAfterNodeDeselect(AdvTreeNodeEventArgs args) + { + if (AfterNodeDeselect != null) + AfterNodeDeselect(this, args); + } + + internal void InvokeOnAfterNodeSelect(AdvTreeNodeEventArgs args) + { + OnAfterNodeSelect(args); + } + protected virtual void OnAfterNodeSelect(AdvTreeNodeEventArgs args) + { + if (AfterNodeSelect != null) + AfterNodeSelect(this, args); + } + + internal void InvokeOnBeforeNodeSelect(AdvTreeNodeCancelEventArgs args) + { + OnBeforeNodeSelect(args); + } + protected virtual void OnBeforeNodeSelect(AdvTreeNodeCancelEventArgs args) + { + if (BeforeNodeSelect != null) + BeforeNodeSelect(this, args); + } + + /// + /// Invokes DeserializeNode event. + /// + /// Provides more information about the event + protected virtual void OnDeserializeNode(SerializeNodeEventArgs e) + { + if (DeserializeNode != null) + DeserializeNode(this, e); + } + + /// + /// Invokes SerializeNode event. + /// + /// Provides more information about the event + protected virtual void OnSerializeNode(SerializeNodeEventArgs e) + { + if (SerializeNode != null) + SerializeNode(this, e); + } + + internal void InvokeSerializeNode(SerializeNodeEventArgs e) + { + OnSerializeNode(e); + } + + internal void InvokeDeserializeNode(SerializeNodeEventArgs e) + { + OnDeserializeNode(e); + } + + internal bool HasSerializeNodeHandlers + { + get { return (SerializeNode != null); } + } + + internal bool HasDeserializeNodeHandlers + { + get { return (DeserializeNode != null); } + } + + internal void InvokeMarkupLinkClick(object sender, MarkupLinkClickEventArgs e) + { + OnMarkupLinkClick(sender, e); + m_CellMouseDownCounter = 0; + } + + /// + /// Invokes the MarkupLinkClick evcent. + /// + /// Sender of the event, usually instance Cell object. + /// Event arguments + protected virtual void OnMarkupLinkClick(object sender, MarkupLinkClickEventArgs e) + { + if (MarkupLinkClick != null) + MarkupLinkClick(sender, e); + } + #endregion + + #region Drag & Drop Support + [DllImport("user32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool SetCursorPos(int X, int Y); + + protected override void OnDragDrop(DragEventArgs drgevent) + { + base.OnDragDrop(drgevent); + InternalDragDrop(drgevent); + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void InternalDragDrop(DragEventArgs drgevent) + { + ReleaseDragNode(true); + } + + protected override void OnDragLeave(EventArgs e) + { + base.OnDragLeave(e); + InternalDragLeave(); + } + + private Timer _DragScrollTimer = null; + [EditorBrowsable(EditorBrowsableState.Never)] + public void InternalDragLeave() + { + ReleaseDragNode(false); + if (AutoScroll && _DragScrollTimer == null) + { + _DragScrollTimer = new Timer(); + _DragScrollTimer.Interval = 100; + _DragScrollTimer.Tick += new EventHandler(DragScrollTimerTick); + _DragScrollTimer.Start(); + } + } + + private void DestroyDragScrollTimer() + { + Timer t = _DragScrollTimer; + if (t == null) return; + _DragScrollTimer = null; + t.Stop(); + t.Tick -= new EventHandler(DragScrollTimerTick); + t.Dispose(); + } + + private void DragScrollTimerTick(object sender, EventArgs e) + { + if (Control.MouseButtons == MouseButtons.Left && this.IsHandleCreated && this.AutoScroll) + { + Point p = this.PointToClient(Control.MousePosition); + Rectangle temp = this.ClientRectangle; + temp.Inflate(32, 32); + if (!temp.Contains(p)) return; + + if (p.Y < 0 && this.AutoScrollPosition.Y != 0 && _VScrollBar != null) + this.AutoScrollPosition = new Point(this.AutoScrollPosition.X, Math.Min(0, this.AutoScrollPosition.Y + _VScrollBar.SmallChange)); + else if (_VScrollBar != null && p.Y > this.ClientRectangle.Bottom && -(this.AutoScrollPosition.Y - _VScrollBar.SmallChange) < (_VScrollBar.Maximum - _VScrollBar.LargeChange)) + { + this.AutoScrollPosition = new Point(this.AutoScrollPosition.X, Math.Min(0, this.AutoScrollPosition.Y - _VScrollBar.SmallChange)); + } + } + else + DestroyDragScrollTimer(); + } + + protected override void OnDragEnter(DragEventArgs drgevent) + { + DestroyDragScrollTimer(); + base.OnDragEnter(drgevent); + } + + protected override void OnDragOver(DragEventArgs drgevent) + { + base.OnDragOver(drgevent); + InternalDragOver(drgevent); + } + + /// + /// Raises the NodeDragFeedback event. + /// + /// Provides event arguments. + protected virtual void OnNodeDragFeedback(TreeDragFeedbackEventArgs e) + { + TreeDragFeedbackEventHander h = NodeDragFeedback; + if (h != null) + h(this, e); + } + + private int _DropAsChildOffset = 24; + /// + /// Gets or sets the offset in pixels from node's X position that is used during drag & drop operation to indicate that + /// dragged node is dropped as child node of the parent's node. + /// + [DefaultValue(24), Category("Behavior"), Description("Indicates offset in pixels from node's X position that is used during drag & drop operation to indicate that dragged node is dropped as child node of the parent's node.")] + public int DropAsChildOffset + { + get { return _DropAsChildOffset; } + set + { + _DropAsChildOffset = value; + } + } + + private bool _DragDropNodeCopyEnabled = true; + /// + /// Gets or sets whether drag & drop internal implementation allows the copying of the node being dragged when CTRL key is pressed. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether drag & drop internal implementation allows the copying of the node being dragged when CTRL key is pressed.")] + public bool DragDropNodeCopyEnabled + { + get { return _DragDropNodeCopyEnabled; } + set + { + _DragDropNodeCopyEnabled = value; + } + } + + private bool GetNodesContain(Node[] nodes, Node nodeToLookFor) + { + foreach (Node node in nodes) + { + if (node == nodeToLookFor) + return true; + } + return false; + } + + private bool _AllowExternalDrop = true; + /// + /// Gets or sets whether control accepts the dragged nodes from other AdvTree controls. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether control accepts the dragged nodes from other AdvTree controls.")] + public bool AllowExternalDrop + { + get { return _AllowExternalDrop; } + set { _AllowExternalDrop = value; } + } + + private NodeDragInfo _DragInfo = null; + /// + /// Processes drag over event. + /// + /// Drag event arguments. + [EditorBrowsable(EditorBrowsableState.Never)] + public void InternalDragOver(DragEventArgs drgevent) + { + if (!m_DragDropEnabled) + return; + + if (!_AllowExternalDrop && IsExternalTreeDrop(drgevent)) + { + drgevent.Effect = DragDropEffects.None; + return; + } + + if (m_DragNode == null) + CreateDragNode(drgevent); + + if (m_DragNode == null) + { + drgevent.Effect = DragDropEffects.None; + return; + } + + drgevent.Effect = (Control.ModifierKeys == Keys.Control && _DragDropNodeCopyEnabled) ? DragDropEffects.Copy : DragDropEffects.Move; + + InvalidateNode(m_DragNode); + Point p = this.PointToClient(new Point(drgevent.X, drgevent.Y)); + p = GetLayoutPosition(p); + TreeAreaInfo areaInfo = NodeOperations.GetTreeAreaInfo(this, p.X, p.Y); + Point insideNodeOffset = Point.Empty; + + NodeDragInfo newDragInfo = null; + Node lastVisibleNode = null; + if (areaInfo != null && areaInfo.NodeAt == null && this.ClientRectangle.Contains(p.X, p.Y)) + { + lastVisibleNode = NodeOperations.GetLastVisibleTopLevelNode(this); + if (lastVisibleNode != null && p.Y >= lastVisibleNode.Bounds.Y) + areaInfo.NodeAt = lastVisibleNode; + } + + if (areaInfo != null && areaInfo.NodeAt != null && !GetNodesContain((Node[])m_DragNode.Tag, areaInfo.NodeAt) && !NodeOperations.IsChildOfAnyParent((Node[])m_DragNode.Tag, areaInfo.NodeAt)) + { + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, areaInfo.NodeAt, m_NodeDisplay.Offset); + Rectangle rContent = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, areaInfo.NodeAt, m_NodeDisplay.Offset); + + if (_View == eView.Tile) + { + if (areaInfo.NodeAt == lastVisibleNode) + { + // Drop at the end of the tree as new parent + MultiNodeTreeDragFeedbackEventArgs feedbackArgs = new MultiNodeTreeDragFeedbackEventArgs(null, this.Nodes.Count, (Node[])m_DragNode.Tag, drgevent.Effect); + OnNodeDragFeedback(feedbackArgs); + if (feedbackArgs.AllowDrop) + { + // Adding the drag node as child node + newDragInfo = new NodeDragInfo(feedbackArgs.ParentNode, feedbackArgs.InsertPosition); + if (feedbackArgs.EffectSet) + drgevent.Effect = feedbackArgs.Effect; + } + else + drgevent.Effect = DragDropEffects.None; + } + else if ((areaInfo.NodeAt.HasChildNodes || areaInfo.NodeAt.Parent == null)) + { + // Drop as child + MultiNodeTreeDragFeedbackEventArgs feedbackArgs = new MultiNodeTreeDragFeedbackEventArgs(areaInfo.NodeAt, -1, (Node[])m_DragNode.Tag, drgevent.Effect); + OnNodeDragFeedback(feedbackArgs); + if (feedbackArgs.AllowDrop) + { + // Adding the drag node as child node + newDragInfo = new NodeDragInfo(feedbackArgs.ParentNode, feedbackArgs.InsertPosition); + if (feedbackArgs.EffectSet) + drgevent.Effect = feedbackArgs.Effect; + } + else + drgevent.Effect = DragDropEffects.None; + } + else + { + TreeDragFeedbackEventArgs feedbackArgs = null; + // Pick insert position based on X position within the mouse over node. X 0) + feedbackArgs = new MultiNodeTreeDragFeedbackEventArgs(areaInfo.NodeAt, -1, (Node[])m_DragNode.Tag); + else + feedbackArgs = new MultiNodeTreeDragFeedbackEventArgs(areaInfo.NodeAt.Parent, areaInfo.NodeAt.Index, (Node[])m_DragNode.Tag, drgevent.Effect); + } + OnNodeDragFeedback(feedbackArgs); + if (feedbackArgs.AllowDrop) + { + // Adding the drag node as child node + newDragInfo = new NodeDragInfo(feedbackArgs.ParentNode, feedbackArgs.InsertPosition); + if (feedbackArgs.EffectSet) + drgevent.Effect = feedbackArgs.Effect; + } + else + drgevent.Effect = DragDropEffects.None; + } + } + else + { + // Determine drag node insert position + if (p.X > rContent.X + _DropAsChildOffset) + { + MultiNodeTreeDragFeedbackEventArgs feedbackArgs = new MultiNodeTreeDragFeedbackEventArgs(areaInfo.NodeAt, -1, (Node[])m_DragNode.Tag, drgevent.Effect); + OnNodeDragFeedback(feedbackArgs); + if (feedbackArgs.AllowDrop) + { + // Adding the drag node as child node + newDragInfo = new NodeDragInfo(feedbackArgs.ParentNode, feedbackArgs.InsertPosition); + if (feedbackArgs.EffectSet) + drgevent.Effect = feedbackArgs.Effect; + } + else + drgevent.Effect = DragDropEffects.None; + } + else + { + TreeDragFeedbackEventArgs feedbackArgs = null; + // Pick insert position based on Y position within the mouse over node. y 0) + feedbackArgs = new MultiNodeTreeDragFeedbackEventArgs(areaInfo.NodeAt, -1, (Node[])m_DragNode.Tag); + else + feedbackArgs = new MultiNodeTreeDragFeedbackEventArgs(areaInfo.NodeAt.Parent, areaInfo.NodeAt.Index, (Node[])m_DragNode.Tag, drgevent.Effect); + } + OnNodeDragFeedback(feedbackArgs); + if (feedbackArgs.AllowDrop) + { + // Adding the drag node as child node + newDragInfo = new NodeDragInfo(feedbackArgs.ParentNode, feedbackArgs.InsertPosition); + if (feedbackArgs.EffectSet) + drgevent.Effect = feedbackArgs.Effect; + } + else + drgevent.Effect = DragDropEffects.None; + } + } + } + else if (m_Nodes.Count == 0) // Drop into empty tree + { + MultiNodeTreeDragFeedbackEventArgs feedbackArgs = new MultiNodeTreeDragFeedbackEventArgs(null, 0, (Node[])m_DragNode.Tag, drgevent.Effect); + OnNodeDragFeedback(feedbackArgs); + if (feedbackArgs.AllowDrop) + { + // Adding the drag node as child node + newDragInfo = new NodeDragInfo(null, 0); + if (feedbackArgs.EffectSet) + drgevent.Effect = feedbackArgs.Effect; + } + else + drgevent.Effect = DragDropEffects.None; + } + else + { + Rectangle temp = this.ClientRectangle; + temp.Inflate(32, 32); + if (AutoScroll && temp.Contains(p)) + { + if (p.Y < 0) + { + if (_VScrollBar != null && _VScrollBar.Value > 0) + _VScrollBar.Value -= _VScrollBar.SmallChange; + } + else if (p.Y > this.ClientRectangle.Bottom) + { + if (_VScrollBar != null && _VScrollBar.Value + _VScrollBar.SmallChange < _VScrollBar.Maximum) + _VScrollBar.Value += _VScrollBar.SmallChange; + } + + } + drgevent.Effect = DragDropEffects.None; + } + + bool update = false; + if (newDragInfo != null) + { + if (_DragInfo == null) + { + _DragInfo = newDragInfo; + InvalidateDragInfo(_DragInfo); + update = true; + } + else if (_DragInfo.Parent != newDragInfo.Parent || _DragInfo.InsertIndex != newDragInfo.InsertIndex) + { + InvalidateDragInfo(_DragInfo); + InvalidateDragInfo(newDragInfo); + _DragInfo = newDragInfo; + update = true; + } + } + else if (newDragInfo != _DragInfo) + { + InvalidateDragInfo(_DragInfo); + _DragInfo = null; + update = true; + } + + m_DragNode.SetBounds(new Rectangle(p.X, p.Y, m_DragNode.BoundsRelative.Width, m_DragNode.BoundsRelative.Height)); + m_DragNode.Visible = true; + InvalidateNode(m_DragNode); + + if (update) + { + if (this.DesignMode) + this.Refresh(); + else + this.Update(); + } + } + + + private void InvalidateDragInfo(NodeDragInfo dragInfo) + { + if (dragInfo == null) return; + Rectangle r = GetDragInsertionBounds(dragInfo); + if (!r.IsEmpty) + { + r.Inflate(1, 1); + Invalidate(r); + } + } + + private Node GetDragInfoReferenceNode(NodeDragInfo dragInfo) + { + Node referenceNode = null; + NodeCollection col = null; + if (dragInfo.Parent != null) + { + col = dragInfo.Parent.Nodes; + } + else + { + col = this.Nodes; + } + + if (col.Count > 0) + { + if (dragInfo.InsertIndex <= 0) + referenceNode = col[0]; + else if (dragInfo.InsertIndex >= col.Count) + referenceNode = col[col.Count - 1]; + else + referenceNode = col[dragInfo.InsertIndex]; + } + + return referenceNode; + } + internal static readonly int DragInsertMarkSize = 9; + internal Rectangle GetDragInsertionBounds(NodeDragInfo dragInfo) + { + if (dragInfo == null) return Rectangle.Empty; + + Rectangle r = Rectangle.Empty; + + Node referenceNode = GetDragInfoReferenceNode(dragInfo); + + Node parentDragNode = dragInfo.Parent; + if (_View == eView.Tile) + { + //Console.WriteLine(dragInfo); + if (referenceNode != null) + { + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, referenceNode, m_NodeDisplay.Offset); + if (dragInfo.InsertIndex == -1) + r.X -= 4; + else + r.X = r.Right - DragInsertMarkSize; + r.Height = referenceNode.Bounds.Height; + r.Width = DragInsertMarkSize; + } + else if (parentDragNode != null) + { + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, parentDragNode, m_NodeDisplay.Offset); + r.X += this.Indent; + if (!parentDragNode.HasChildNodes) + r.Y = r.Bottom - DragInsertMarkSize; + r.Width = parentDragNode.Bounds.Width; + r.Height = DragInsertMarkSize; + } + } + else + { + if (referenceNode != null) + { + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, referenceNode, m_NodeDisplay.Offset); + r.Width = referenceNode.Bounds.Width; + if (referenceNode.Expanded && dragInfo.InsertIndex >= 0) + { + Rectangle childBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ChildNodeBounds, referenceNode, m_NodeDisplay.Offset); + r.Y = childBounds.Bottom - r.Height; + } + } + else if (parentDragNode != null) + { + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, parentDragNode, m_NodeDisplay.Offset); + r.X += this.Indent; + r.Width = parentDragNode.Bounds.Width; + } + + if (dragInfo.InsertIndex < 0 && referenceNode != null) + r.Y -= 4; + else + r.Y = r.Bottom - 2; + r.Height = DragInsertMarkSize; + } + + return r; + } + + private int _Indent = 16; + /// + /// Gets or sets the distance to indent each of the child tree node levels. Default value is 16. + /// + [DefaultValue(16), Description("Indicates distance to indent each of the child tree node levels."), Category("Appearance")] + public int Indent + { + get { return _Indent; } + set + { + if (_Indent != value) + { + _Indent = value; + if (m_NodeLayout is NodeTreeLayout) + ((NodeTreeLayout)m_NodeLayout).NodeLevelOffset = value; + InvalidateNodesSize(); + RecalcLayout(); + } + } + } + + private bool _PaintDragDropInsertMarker = true; + /// + /// Indicates whether drop marker is displayed during drag-drop operation. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether drop marker is displayed during drag-drop operation.")] + public bool PaintDragDropInsertMarker + { + get { return _PaintDragDropInsertMarker; } + set + { + _PaintDragDropInsertMarker = value; + if (IsDragDropInProgress && _DragInfo != null) + InvalidateDragInfo(_DragInfo); + } + } + + /// + /// Gets or sets whether drag and drop operation is in progress. This member supports + /// the AdvTree infrastructure and is not intended to be used directly from your + /// code. + /// + [Browsable(false)] + public bool IsDragDropInProgress + { + get { return (m_DragNode != null); } + } + + private Node[] SortNodesByFlatIndex(Node[] dragNodes) + { + ArrayList nodes = new ArrayList(dragNodes); + nodes.Sort(new NodeFlatIndexComparer(this)); + nodes.CopyTo(dragNodes); + return dragNodes; + } + private void ReleaseDragNode(bool drop) + { + if (m_DragNode == null) + return; + bool isCopy = (Control.ModifierKeys == Keys.Control && _DragDropNodeCopyEnabled); + + this.BeginUpdate(); + try + { + if (m_NodeDisplay.LockOffset) + m_NodeDisplay.LockOffset = false; + + Node[] dragNodes = m_DragNode.Tag as Node[]; + foreach (Node item in dragNodes) + { + if (!item.Visible) item.Visible = true; + } + + if (drop && _DragInfo != null) + { + Node parent = _DragInfo.Parent; + // Fire off events and cancel processing if needed + TreeDragDropEventArgs e = new TreeDragDropEventArgs(eTreeAction.Mouse, dragNodes, dragNodes[0].Parent, parent, isCopy, _DragInfo.InsertIndex); + InvokeBeforeNodeDrop(e); + if (!e.Cancel && e.Nodes != null && e.Nodes.Length > 0) + { + isCopy = e.IsCopy; + dragNodes = e.Nodes; + int index = e.InsertPosition + 1; + + if (dragNodes.Length > 1) + dragNodes = SortNodesByFlatIndex(dragNodes); + Node[] afterDragNodes = new Node[dragNodes.Length]; + for (int i = 0; i < dragNodes.Length; i++) + { + Node childNode = dragNodes[i]; + Node node = childNode; + if (NodeOperations.IsChildOfAnyParent(dragNodes, node)) continue; + + if (isCopy) + { + node = node.DeepCopy(); + } + else + { + if (parent != null) + { + if (node.Parent == parent && parent.Nodes.IndexOf(node) < index) + index--; + } + else + { + if (node.Parent == null && node.TreeControl == this && this.Nodes.IndexOf(node) < index) + index--; + } + node.Remove(eTreeAction.Mouse); + } + afterDragNodes[i] = node; + + // Adjust index in case node was removed and flat indexes changed + if (index < 0) + index = 0; + else if (parent != null && index > parent.Nodes.Count) + index = parent.Nodes.Count; + else if (parent == null && index > this.Nodes.Count) + index = this.Nodes.Count; + + if (parent == null) + this.Nodes.Insert(index, node, eTreeAction.Mouse); + else + { + parent.Nodes.Insert(index, node, eTreeAction.Mouse); + if (!parent.Expanded) + parent.Expanded = true; + } + index++; + } + e.Nodes = afterDragNodes; + InvokeAfterNodeDrop(e); + } + } + _DragInfo = null; + } + finally + { + m_DragNode = null; + if (!m_PendingLayout) + { + this.EndUpdate(); + this.RecalcLayout(); + this.Refresh(); + } + else + this.EndUpdate(); + } + } + + /// + /// Raises the NodeDragStart event. + /// + /// Reference to node being dragged. + /// Event parameters + protected virtual void OnNodeDragStart(object sender, EventArgs e) + { + EventHandler eh = NodeDragStart; + if (eh != null) + eh(sender, e); + } + + private bool IsExternalTreeDrop(DragEventArgs e) + { + if (e.Data != null) + { + Node node = null; + Node[] nodes = null; + if (e.Data.GetDataPresent(typeof(Node))) + node = e.Data.GetData(typeof(Node)) as Node; + else if (e.Data.GetDataPresent(typeof(Node[]))) + nodes = e.Data.GetData(typeof(Node[])) as Node[]; + else if (e.Data.GetFormats().Length > 0) + { + node = e.Data.GetData(e.Data.GetFormats()[0]) as Node; + nodes = e.Data.GetData(e.Data.GetFormats()[0]) as Node[]; + } + + if (node != null && node.TreeControl != this) + return true; + else if (nodes != null && nodes.Length > 0) + { + if (nodes[0].TreeControl != this) + return true; + } + } + + return false; + } + + private void CreateDragNode(DragEventArgs e) + { + if (e.Data != null) + { + Node node = null; + Node[] nodes = null; + if (e.Data.GetDataPresent(typeof(Node))) + node = e.Data.GetData(typeof(Node)) as Node; + else if (e.Data.GetDataPresent(typeof(Node[]))) + nodes = e.Data.GetData(typeof(Node[])) as Node[]; + else if (e.Data.GetFormats().Length > 0) + { + node = e.Data.GetData(e.Data.GetFormats()[0]) as Node; + nodes = e.Data.GetData(e.Data.GetFormats()[0]) as Node[]; + } + + if (node != null) + CreateDragNode(new Node[1] { node }); + else if (nodes != null && nodes.Length > 0) + { + CreateDragNode(nodes); + } + } + } + + private bool _MultiNodeDragCountVisible = true; + /// + /// Gets or sets whether number of nodes being dragged is displayed on drag node preview. Default value is true. + /// + [DefaultValue(true), Category("Selection"), Description("Indicates whether number of nodes being dragged is displayed on drag node preview.")] + public bool MultiNodeDragCountVisible + { + get + { + return _MultiNodeDragCountVisible; + } + set + { + _MultiNodeDragCountVisible = value; + } + } + private void CreateDragNode(Node[] nodes) + { + AdvTreeMultiNodeCancelEventArgs eventArgs = new AdvTreeMultiNodeCancelEventArgs(eTreeAction.Mouse, nodes); + OnBeforeNodeDragStart(eventArgs); + if (eventArgs.Cancel) return; + + m_DragNode = nodes[0].Copy(); + m_DragNode.Tag = nodes; + m_DragNode.IsDragNode = true; + PrepareDragNodeElementStyle(m_DragNode, nodes[0]); + + if (nodes.Length > 1 && this.MultiNodeDragCountVisible) + { + Cell cell = new Cell(); + cell.Text = nodes.Length.ToString(); + cell.StyleNormal = new ElementStyle(); + cell.StyleNormal.BackColor = ColorScheme.GetColor(0x40408C); + cell.StyleNormal.BackColor2 = ColorScheme.GetColor(0x0093F9); + cell.StyleNormal.BackColorGradientAngle = 90; + cell.StyleNormal.TextColor = Color.White; + cell.StyleNormal.Padding = 3; + cell.Name = "sysNodeCount"; + cell.Tag = m_DragNode.Tag; + m_DragNode.Tag = null; + m_DragNode.Cells.Insert(0, cell); + } + + m_DragNode.Visible = false; + m_NodeLayout.PerformSingleNodeLayout(m_DragNode); + this.Refresh(); + OnNodeDragStart(nodes[0], new EventArgs()); + } + + /// + /// Raises BeforeNodeDragStart event. + /// + /// Provides event arguments. + protected virtual void OnBeforeNodeDragStart(AdvTreeNodeCancelEventArgs e) + { + if (BeforeNodeDragStart != null) BeforeNodeDragStart(this, e); + } + + private void PrepareDragNodeElementStyle(Node dragNode, Node originalNode) + { + // Setup half transparent styles + int alpha = 128; + ElementStyle style = null; + if (originalNode.Style != null) + style = originalNode.Style.Copy(); + else if (this.NodeStyle != null) + style = this.NodeStyle.Copy(); + else + { + style = new ElementStyle(); + style.TextColorSchemePart = eColorSchemePart.ItemText; + } + ElementStyle.SetColorsAlpha(style, alpha); + dragNode.Style = style; + + if (this.CellStyleDefault != null) + style = this.CellStyleDefault.Copy(); + else + style = ElementStyle.GetDefaultCellStyle(dragNode.Style); + ElementStyle.SetColorsAlpha(style, alpha); + foreach (Cell cell in dragNode.Cells) + { + cell.StyleNormal = style; + } + + for (int i = 0; i < dragNode.Cells.Count; i++) + { + if (originalNode.Cells[i].StyleNormal != null) + { + ElementStyle cellStyle = originalNode.Cells[i].StyleNormal.Copy(); + ElementStyle.SetColorsAlpha(style, alpha); + dragNode.Cells[i].StyleNormal = cellStyle; + } + else + dragNode.Cells[i].StyleNormal = style; + } + } + + private bool _MultiNodeDragDropAllowed = true; + /// + /// Gets or sets whether multiple nodes drag & drop is enabled. Default value is true. + /// + [DefaultValue(true), Category("Selection"), Description("Indicates whether multiple nodes drag & drop is enabled.")] + public bool MultiNodeDragDropAllowed + { + get + { + return _MultiNodeDragDropAllowed; + } + set + { + _MultiNodeDragDropAllowed = value; + } + } + private bool StartDragDrop() + { + if (m_MouseOverNode == null) + return false; + + if (this.MultiSelect && this.SelectedNodes.Count > 1 && this.MultiNodeDragDropAllowed) + { + Node[] nodes = new Node[this.SelectedNodes.Count]; + this.SelectedNodes.CopyTo(nodes); + return StartDragDrop(nodes); + } + + return StartDragDrop(m_MouseOverNode); + } + + private bool StartDragDrop(Node[] nodes) + { + if (IsDragDropInProgress) + return false; + + _SelectOnMouseUp = false; + foreach (Node node in nodes) + { + if (!node.DragDropEnabled || node == m_DisplayRootNode) + return false; + if (node.IsMouseDown) + OnNodeMouseUp(new MouseEventArgs(Control.MouseButtons, 0, 0, 0, 0)); + } + + this.EndCellEditing(eTreeAction.Mouse); + + Point m_MouseDownPoint = Control.MousePosition; + + if (this.DesignMode) + CreateDragNode(nodes); + else + this.DoDragDrop(nodes, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move | DragDropEffects.Scroll); + + return true; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool StartDragDrop(Node node) + { + if (IsDragDropInProgress || !node.DragDropEnabled) + return false; + + this.EndCellEditing(eTreeAction.Mouse); + + if (node.IsMouseDown) + OnNodeMouseUp(new MouseEventArgs(Control.MouseButtons, 0, 0, 0, 0)); + + if (node == m_DisplayRootNode /*|| node.Parent==null*/) // Drag & drop in designer means that parent is null + return false; + + Point m_MouseDownPoint = Control.MousePosition; + + if (this.DesignMode) + CreateDragNode(new Node[1] { node }); + else + this.DoDragDrop(node, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move | DragDropEffects.Scroll); + + return true; + } + + /// + /// Returns the display root node. + /// + /// Instance of node or null if there is no display root node. + internal Node GetDisplayRootNode() + { + if (m_DisplayRootNode != null) + return m_DisplayRootNode; + if (this.Nodes.Count > 0) + return this.Nodes[0]; + return null; + } + + /// + /// Returns reference to the node involved in drag-drop operation if any. + /// + /// Reference to node object or null if there is no drag node. + [EditorBrowsable(EditorBrowsableState.Never)] + public Node GetDragNode() + { + return m_DragNode; + } + + /// + /// Returns the reference to node drag information class that gives information about node drag & drop. + /// + /// Reference to node drag info object or null if no drag information is available + internal NodeDragInfo GetNodeDragInfo() + { + return _DragInfo; + } + #endregion + + #region ISupportInitialize + /// + /// This member supports the .NET Framework infrastructure and is not intended to be + /// used directly from your code. + /// + public void BeginInit() + { + this.BeginUpdate(); + } + + /// + /// This member supports the .NET Framework infrastructure and is not intended to be + /// used directly from your code. + /// + public void EndInit() + { + this.EndUpdate(); + } + #endregion + + #region Property Hiding + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new System.Windows.Forms.Padding Padding + { + get + { + return base.Padding; + } + set + { + //base.Padding = value; + } + } + + [Browsable(false)] + public override Image BackgroundImage + { + get + { + return base.BackgroundImage; + } + set + { + base.BackgroundImage = value; + } + } +#if FRAMEWORK20 + [Browsable(false)] + public override ImageLayout BackgroundImageLayout + { + get + { + return base.BackgroundImageLayout; + } + set + { + base.BackgroundImageLayout = value; + } + } +#endif + #endregion + + #region Licensing +#if !TRIAL + private string m_LicenseKey = ""; + private bool m_DialogDisplayed = false; + [Browsable(false), DefaultValue("")] + public string LicenseKey + { + get { return m_LicenseKey; } + set + { + if (NodeOperations.ValidateLicenseKey(value)) + return; + m_LicenseKey = (!NodeOperations.CheckLicenseKey(value) ? "9dsjkhds7" : value); + } + } +#endif + #endregion + + #region BarAccessibleObject + public class AdvTreeAccessibleObject : System.Windows.Forms.Control.ControlAccessibleObject + { + AdvTree _Owner = null; + public AdvTreeAccessibleObject(AdvTree owner) + : base(owner) + { + _Owner = owner; + } + + internal void GenerateEvent(Node sender, System.Windows.Forms.AccessibleEvents e) + { + int iChild = _Owner.Nodes.IndexOf(sender); + if (iChild >= 0) + { + if (_Owner != null && !_Owner.IsDisposed) + _Owner.AccessibilityNotifyClients(e, iChild); + } + } + + public override AccessibleRole Role + { + get + { + if (_Owner != null && !_Owner.IsDisposed) + return _Owner.AccessibleRole; + return System.Windows.Forms.AccessibleRole.None; + } + } + + public override AccessibleObject Parent + { + get + { + if (_Owner != null && !_Owner.IsDisposed) + return _Owner.Parent.AccessibilityObject; + return null; + } + } + + public override Rectangle Bounds + { + get + { + if (_Owner != null && !_Owner.IsDisposed && _Owner.Parent != null) + return this._Owner.Parent.RectangleToScreen(_Owner.Bounds); + return Rectangle.Empty; + } + } + + public override int GetChildCount() + { + if (_Owner != null && !_Owner.IsDisposed && _Owner.Nodes != null) + return _Owner.Nodes.Count; + return 0; + } + + public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) + { + if (_Owner != null && !_Owner.IsDisposed && _Owner.Nodes != null) + return _Owner.Nodes[iIndex].AccessibleObject; + return null; + } + + public override AccessibleStates State + { + get + { + AccessibleStates state = AccessibleStates.Default; + if (_Owner == null || _Owner.IsDisposed) + return AccessibleStates.None; + if (_Owner.Focused) + state = AccessibleStates.Focused; + + return state; + } + } + } + private bool _ResetAutoScrollPositionOnClearedNodes=true; + /// + /// Indicates whether AutoScrollPosition is reset to 0,0 when all nodes are cleared from the tree. Default value is true. + /// + [DefaultValue(true), Browsable(false)] + public bool ResetAutoScrollPositionOnClearedNodes + { + get { return _ResetAutoScrollPositionOnClearedNodes; } + set + { + _ResetAutoScrollPositionOnClearedNodes = value; + } + } + + internal void OnNodesCleared() + { + if (m_NodeDisplay != null) + m_NodeDisplay.PaintedNodes.Clear(); + if (_FullRowBackgroundNodes != null) + _FullRowBackgroundNodes.Clear(); + if (this.MultiSelect && this.SelectedNodes.Count > 0) this.SelectedNodes.Clear(); + if (_ResetAutoScrollPositionOnClearedNodes) + this.AutoScrollPosition = Point.Empty; + this.SelectedNode = null; + if (this.IsHandleCreated) + this.RecalcLayout(); + else + SetPendingLayout(); + } + + internal Rectangle GetPaintRectangle() + { + Rectangle rect = this.ClientRectangle; + if (_ColumnHeader != null && _ColumnHeader.Visible) + { + rect.Y += _ColumnHeader.Height; + rect.Height -= _ColumnHeader.Height; + } + if (_VScrollBar != null && _VScrollBar.Visible) + { + rect.Width -= _VScrollBar.Width; + } + if (_HScrollBar != null && _HScrollBar.Visible) + { + rect.Height -= _HScrollBar.Height; + } + return rect; + } + + #endregion + + #region Data-binding +#if FRAMEWORK20 + private List _DisplayMembers = null; + /// + /// Gets or sets the comma separated list of property or column names to display on popup tree control. + /// + [DefaultValue(""), Category("Data"), Description("Indicates comma separated list of property or column names to display on popup tree control")] + [Editor("DevComponents.DotNetBar.Design.DataMembersSelector, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string DisplayMembers + { + get + { + if (_DisplayMembers == null || _DisplayMembers.Count == 0) + return ""; + StringBuilder members = new StringBuilder(); + for (int i = 0; i < _DisplayMembers.Count; i++) + { + BindingMemberInfo item = _DisplayMembers[i]; + members.Append(item.BindingMember); + if (i + 1 < _DisplayMembers.Count) + members.Append(','); + } + return members.ToString(); + } + set + { + List displayMembers = _DisplayMembers; + + List newMembers = null; + + if (!string.IsNullOrEmpty(value)) + { + newMembers = new List(); + // Parse the members comma separated list expected... + string[] members = value.Split(','); + for (int i = 0; i < members.Length; i++) + { + newMembers.Add(new BindingMemberInfo(members[i].Trim())); + } + } + + try + { + this.SetDataConnection(_DataSource, newMembers, false); + } + catch + { + _DisplayMembers = displayMembers; + } + } + } + + private object _DataSource = null; + /// + /// Gets or sets the data source for the ComboTree. Expected is an object that implements the IList or IListSource interfaces, + /// such as a DataSet or an Array. The default is null. + /// + [AttributeProvider(typeof(IListSource)), Description("Indicates data source for the ComboTree."), Category("Data"), DefaultValue(null), RefreshProperties(RefreshProperties.Repaint)] + public object DataSource + { + get + { + return _DataSource; + } + set + { + if (((value != null) && !(value is IList)) && !(value is IListSource)) + { + throw new ArgumentException("Data type is not supported for complex data binding"); + } + //if (_DataSource != value) + { + ClearDescriptorsCache(); + try + { + this.SetDataConnection(value, _DisplayMembers, true); + } + catch + { + this.DisplayMembers = ""; + } + if (value == null) + { + this.DisplayMembers = ""; + } + } + } + } + + private bool _FormattingEnabled = false; + /// + /// Gets or sets a value indicating whether formatting is applied to the DisplayMembers property of the control. + /// + [DefaultValue(false), Description("Indicates whether formatting is applied to the DisplayMembers property of the control.")] + public bool FormattingEnabled + { + get + { + return _FormattingEnabled; + } + set + { + if (value != _FormattingEnabled) + { + _FormattingEnabled = value; + RefreshItems(); + OnFormattingEnabledChanged(EventArgs.Empty); + } + } + } + /// + /// Raises FormattingEnabledChanged event. + /// + /// Event arguments. + protected virtual void OnFormattingEnabledChanged(EventArgs e) + { + EventHandler handler = FormattingEnabledChanged; + if (handler != null) + { + handler(this, e); + } + } + + private string _FormatString = ""; + /// + /// Gets or sets the format-specifier characters that indicate how a value is to be displayed. + /// + [MergableProperty(false), Editor("System.Windows.Forms.Design.FormatStringEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor)), DefaultValue(""), Description("Indicates format-specifier characters that indicate how a value is to be displayed.")] + public string FormatString + { + get + { + return _FormatString; + } + set + { + if (value == null) + { + value = string.Empty; + } + if (!value.Equals(_FormatString)) + { + _FormatString = value; + RefreshItems(); + OnFormatStringChanged(EventArgs.Empty); + } + } + } + /// + /// Raises FormatStringChanged event. + /// + /// Event arguments. + protected virtual void OnFormatStringChanged(EventArgs e) + { + EventHandler handler = FormatStringChanged; + if (handler != null) + { + handler(this, e); + } + } + + private IFormatProvider _FormatInfo = null; + /// + /// Gets or sets the IFormatProvider that provides custom formatting behavior. + /// + [EditorBrowsable(EditorBrowsableState.Advanced), Browsable(false), DefaultValue((string)null)] + public IFormatProvider FormatInfo + { + get + { + return _FormatInfo; + } + set + { + if (value != _FormatInfo) + { + _FormatInfo = value; + RefreshItems(); + OnFormatInfoChanged(EventArgs.Empty); + } + } + } + + /// + /// Raises FormatInfoChanged event. + /// + /// Event arguments. + protected virtual void OnFormatInfoChanged(EventArgs e) + { + EventHandler handler = FormatInfoChanged; + if (handler != null) + { + handler(this, e); + } + } + + + private bool _InSetDataConnection = false; + private void SetDataConnection(object newDataSource, List newDisplayMembers, bool force) + { + bool dataSourceChanged = _DataSource != newDataSource; + bool displayMemberChanged = _DisplayMembers != newDisplayMembers; + + if (!_InSetDataConnection) + { + try + { + if ((force || dataSourceChanged) || displayMemberChanged) + { + _InSetDataConnection = true; + IList list = (this.DataManager != null) ? this.DataManager.List : null; + bool isDataManagerNull = this.DataManager == null; + this.UnwireDataSource(); + _DataSource = newDataSource; + _DisplayMembers = newDisplayMembers; + this.WireDataSource(); + if (_IsDataSourceInitialized) + { + CurrencyManager manager = null; + if (((newDataSource != null) && (this.BindingContext != null)) && (newDataSource != Convert.DBNull)) + { + string bindingPath = ""; + if (_DisplayMembers != null && _DisplayMembers.Count > 0) + bindingPath = newDisplayMembers[0].BindingPath; + manager = (CurrencyManager)this.BindingContext[newDataSource, bindingPath]; + } + + if (_DataManager != manager) + { + if (_DataManager != null) + { + _DataManager.ItemChanged -= new ItemChangedEventHandler(this.DataManager_ItemChanged); + _DataManager.PositionChanged -= new EventHandler(this.DataManager_PositionChanged); + } + _DataManager = manager; + if (_DataManager != null) + { + _DataManager.ItemChanged += new ItemChangedEventHandler(this.DataManager_ItemChanged); + _DataManager.PositionChanged += new EventHandler(this.DataManager_PositionChanged); + } + else if (newDataSource == null) + this.Nodes.Clear(); + } + if (((_DataManager != null) && (displayMemberChanged || dataSourceChanged)) && !ValidateDisplayMembers(_DisplayMembers)) + { + throw new ArgumentException("Wrong DisplayMembers parameter", "newDisplayMember"); + } + if ((_DataManager != null && (dataSourceChanged || displayMemberChanged || force)) + && (displayMemberChanged || dataSourceChanged || (force && ((list != _DataManager.List) || isDataManagerNull)))) + { + DataManager_ItemChanged(_DataManager, null); + } + } + _Converters.Clear(); + } + if (dataSourceChanged) + { + this.OnDataSourceChanged(EventArgs.Empty); + } + if (displayMemberChanged) + { + this.OnDisplayMembersChanged(EventArgs.Empty); + } + } + finally + { + _InSetDataConnection = false; + } + } + } + + private bool ValidateDisplayMembers(List members) + { + if (members == null || members.Count == 0) return true; + + foreach (BindingMemberInfo item in members) + { + if (item.BindingMember != null && !BindingMemberInfoInDataManager(item)) + return false; + } + return true; + } + private bool BindingMemberInfoInDataManager(BindingMemberInfo bindingMemberInfo) + { + if (_DataManager != null) + { + PropertyDescriptorCollection itemProperties = _DataManager.GetItemProperties(); + int count = itemProperties.Count; + for (int i = 0; i < count; i++) + { + if (!typeof(IList).IsAssignableFrom(itemProperties[i].PropertyType) && itemProperties[i].Name.Equals(bindingMemberInfo.BindingField)) + { + return true; + } + } + for (int j = 0; j < count; j++) + { + if (!typeof(IList).IsAssignableFrom(itemProperties[j].PropertyType) && (string.Compare(itemProperties[j].Name, bindingMemberInfo.BindingField, true, CultureInfo.CurrentCulture) == 0)) + { + return true; + } + } + } + return false; + } + /// + /// Raises the DataSourceChanged event. + /// + /// An EventArgs that contains the event data. + protected virtual void OnDataSourceChanged(EventArgs e) + { + EventHandler handler = DataSourceChanged; + if (handler != null) + { + handler(this, e); + } + } + /// + /// Raises the DisplayMemberChanged event. + /// + /// An EventArgs that contains the event data. + protected virtual void OnDisplayMembersChanged(EventArgs e) + { + EventHandler handler = DisplayMembersChanged; + if (handler != null) + { + handler(this, e); + } + } + + private Hashtable _Converters = new Hashtable(); + private TypeConverter GetFieldConverter(string fieldName) + { + if (_Converters.ContainsKey(fieldName)) + return (TypeConverter)_Converters[fieldName]; + if (this.DataManager != null) + { + PropertyDescriptorCollection itemProperties = this.DataManager.GetItemProperties(); + if (itemProperties != null) + { + PropertyDescriptor descriptor = itemProperties.Find(fieldName, true); + if (descriptor != null) + { + _Converters.Add(fieldName, descriptor.Converter); + return descriptor.Converter; + } + } + } + + return null; + } + + private void DataManager_ItemChanged(object sender, ItemChangedEventArgs e) + { + if (this.InvokeRequired) + { + this.Invoke(new ItemChangedEventHandler(DataManager_ItemChanged), sender, e); + return; + } + if (_DataManager != null) + { + if (e == null || e.Index == -1) + { + this.SetItemsCore(_DataManager.List); + if (this.AllowSelection) + { + if (_DataManager.Position == -1) + this.SelectedNode = null; + else + this.SelectedNode = this.FindNodeByBindingIndex(_DataManager.Position); + } + } + else + { + this.SetItemCore(e.Index, _DataManager.List[e.Index]); + } + } + } + private void DataManager_PositionChanged(object sender, EventArgs e) + { + if ((_DataManager != null) && this.AllowSelection) + { + if (_DataManager.Position == -1) + this.SelectedNode = null; + else + this.SelectedNode = this.FindNodeByBindingIndex(_DataManager.Position); + //this.SelectedIndex = _DataManager.Position; + } + } + + /// + /// When overridden in a derived class, resynchronizes the item data with the contents of the data source. + /// + public virtual void RefreshItems() + { + if (_DataManager != null) + { + SetItemsCore(_DataManager.List); + if (this.AllowSelection) + { + if (_DataManager.Position == -1) + this.SelectedNode = null; + else + this.SelectedNode = this.FindNodeByBindingIndex(_DataManager.Position); + } + } + } + + private bool _LoadingDataSource = false; + /// + /// Disposes all nodes in Nodes collection and clears it. + /// + public void ClearAndDisposeAllNodes() + { + List disposeControls = new List(); + if (m_HostedControlCells.Count > 0) + { + foreach (Cell cell in m_HostedControlCells) + { + Control c = cell.HostedControl; + if (c != null) + disposeControls.Add(c); + } + } + foreach (Node node in this.Nodes) + { + node.Dispose(); + } + foreach (Control c in disposeControls) + { + this.Controls.Remove(c); + c.Dispose(); + } + this.Nodes.Clear(); + } + private bool IsSimpleType(object current) + { + if (current == null) return false; + return current is string || current.GetType().IsPrimitive; + } + /// + /// When overridden in a derived class, sets the specified array of objects in a collection in the derived class. + /// + /// An array of items. + protected virtual void SetItemsCore(IList items) + { + this.BeginUpdate(); + this.SuspendPaint = true; + _LoadingDataSource = true; + try + { + ClearAndDisposeAllNodes(); + + //bool isGrouping = !string.IsNullOrEmpty(_GroupingMembers); + + List fieldNames = new List(); + // Create Columns + if (string.IsNullOrEmpty(this.DisplayMembers)) + { + if (this.Columns.Count > 0) + { + foreach (DevComponents.AdvTree.ColumnHeader columnHeader in this.Columns) + { + if (!string.IsNullOrEmpty(columnHeader.DataFieldName)) + fieldNames.Add(columnHeader.DataFieldName); + } + } + if (fieldNames.Count == 0) + { + this.Columns.Clear(); + if (_DataManager.List is Array) + { + DevComponents.AdvTree.ColumnHeader ch = new DevComponents.AdvTree.ColumnHeader("Items"); + ch.Width.Relative = 100; + this.Columns.Add(ch); + OnDataColumnCreated(new DevComponents.DotNetBar.Controls.DataColumnEventArgs(ch)); + } + else if (_DataManager != null) + { + if (_DataManager.Position >= 0 && _DataManager.Current != null && IsSimpleType(_DataManager.Current)) + { + DevComponents.AdvTree.ColumnHeader ch = new DevComponents.AdvTree.ColumnHeader(); + ch.Width.Relative = 100; + this.Columns.Add(ch); + OnDataColumnCreated(new DevComponents.DotNetBar.Controls.DataColumnEventArgs(ch)); + } + else + { + PropertyDescriptorCollection properties = _DataManager.GetItemProperties(); + foreach (PropertyDescriptor prop in properties) + { + fieldNames.Add(prop.Name); + DevComponents.AdvTree.ColumnHeader ch = new DevComponents.AdvTree.ColumnHeader(StringHelper.GetFriendlyName(prop.Name)); + ch.DataFieldName = prop.Name; + ch.Width.Relative = Math.Max(15, 100 / properties.Count); + this.Columns.Add(ch); + OnDataColumnCreated(new DevComponents.DotNetBar.Controls.DataColumnEventArgs(ch)); + } + } + } + } + } + else + { + this.Columns.Clear(); + if (_DisplayMembers != null && _DisplayMembers.Count > 0) + { + foreach (BindingMemberInfo item in _DisplayMembers) + { + DevComponents.AdvTree.ColumnHeader ch = new DevComponents.AdvTree.ColumnHeader(StringHelper.GetFriendlyName(item.BindingMember)); + ch.DataFieldName = item.BindingMember; + ch.Tag = item; + ch.Width.Relative = Math.Max(15, 100 / _DisplayMembers.Count); + this.Columns.Add(ch); + fieldNames.Add(item.BindingMember); + OnDataColumnCreated(new DevComponents.DotNetBar.Controls.DataColumnEventArgs(ch)); + } + } + } + + if (string.IsNullOrEmpty(_GroupingMembers) && string.IsNullOrEmpty(_ParentFieldNames)) + { + for (int i = 0; i < items.Count; i++) + { + object item = items[i]; + Node node = CreateNode(this.Nodes, item, i, fieldNames); + } + } + else if (!string.IsNullOrEmpty(_ParentFieldNames)) + { + //isGrouping = true; + + Dictionary nodeParentCollection = new Dictionary(); + Dictionary> nodeNeedsParentCollection = new Dictionary>(); + string[] parentFields = _ParentFieldNames.Split(','); + int currentPosition = _DataManager.Position; + for (int i = 0; i < items.Count; i++) + { + object item = items[i]; + string nodeKey = GetItemText(item, parentFields[0].Trim()); + string parentKey = GetItemText(item, parentFields[1].Trim()); + Node parentNode = null; + if (nodeParentCollection.TryGetValue(parentKey, out parentNode)) + { + Node node = CreateNode(parentNode.Nodes, item, i, fieldNames); + nodeParentCollection.Add(nodeKey, node); + if (node.BindingIndex == currentPosition) SelectNode(node, eTreeAction.Code); + } + else + { + Node node = CreateNode(this.Nodes, item, i, fieldNames); + List list = null; + if (!nodeNeedsParentCollection.TryGetValue(parentKey, out list)) + { + list = new List(); + nodeNeedsParentCollection.Add(parentKey, list); + } + list.Add(node); + nodeParentCollection.Add(nodeKey, node); + } + } + // If there are nodes that needed a parent process them now + foreach (KeyValuePair> keyValue in nodeNeedsParentCollection) + { + Node parentNode = null; + if (nodeParentCollection.TryGetValue(keyValue.Key, out parentNode)) + { + foreach (Node node in keyValue.Value) + { + node.Remove(); + parentNode.Nodes.Add(node); + if (node.BindingIndex == currentPosition) SelectNode(node, eTreeAction.Code); + } + } + } + } + else + { + string[] groupFields = _GroupingMembers.Split(','); + for (int i = 0; i < groupFields.Length; i++) + { + groupFields[i] = groupFields[i].Trim(); + } + Dictionary groupTable = new Dictionary(); + for (int i = 0; i < items.Count; i++) + { + object item = items[i]; + NodeCollection parentCollection = this.Nodes; + + // Find the parent collection to add item to + string key = ""; + for (int gi = 0; gi < groupFields.Length; gi++) + { + string text = GetItemText(item, groupFields[gi]); + key += text.ToLower() + "/"; + Node groupNode = null; + if (!groupTable.TryGetValue(key, out groupNode)) + { + groupNode = CreateGroupNode(parentCollection, text); + groupTable.Add(key, groupNode); + } + parentCollection = groupNode.Nodes; + } + + Node node = CreateNode(parentCollection, item, i, fieldNames); + } + } + + //// If not grouping then remove the expand part space on left-hand side + //if (isGrouping) + //{ + // this.ExpandWidth = 24; + //} + //else + //{ + // this.ExpandWidth = 0; + //} + } + finally + { + this.SuspendPaint = false; + this.EndUpdate(); + _LoadingDataSource = false; + } + } + + /// + /// Raises the DataColumnCreated event. + /// + /// Provides event arguments. + protected virtual void OnDataColumnCreated(DevComponents.DotNetBar.Controls.DataColumnEventArgs args) + { + if (DataColumnCreated != null) + DataColumnCreated(this, args); + } + + private Node CreateGroupNode(NodeCollection parentCollection, string text) + { + Node node = new Node(); + node.Text = text; + node.Style = _GroupNodeStyle; + node.Expanded = true; + node.Selectable = false; + parentCollection.Add(node); + DevComponents.DotNetBar.Controls.DataNodeEventArgs eventArgs = new DevComponents.DotNetBar.Controls.DataNodeEventArgs(node, null); + OnGroupNodeCreated(eventArgs); + return node; + } + /// + /// Raises the DataNodeCreated event. + /// + /// Provides event arguments. + protected virtual void OnGroupNodeCreated(DevComponents.DotNetBar.Controls.DataNodeEventArgs dataNodeEventArgs) + { + if (GroupNodeCreated != null) GroupNodeCreated(this, dataNodeEventArgs); + } + + /// + /// Creates a new node for the data item. + /// + /// Item to create node for. + /// New instance of the node. + private Node CreateNode(NodeCollection parentCollection, object item, int itemIndex, List fieldNames) + { + Node node = new Node(); + parentCollection.Add(node); + + SetNodeData(node, item, fieldNames, itemIndex); + + DevComponents.DotNetBar.Controls.DataNodeEventArgs eventArgs = new DevComponents.DotNetBar.Controls.DataNodeEventArgs(node, item); + + OnDataNodeCreated(eventArgs); + + return eventArgs.Node; + } + + private void SetNodeData(Node node, object item, List fieldNames, int bindingIndex) + { + node.DataKey = item; + node.BindingIndex = bindingIndex; + + node.CreateCells(); + + if (fieldNames.Count > 0) + { + for (int i = 0; i < fieldNames.Count; i++) + { + object propertyValue = GetPropertyValue(item, fieldNames[i]); + if (propertyValue is Image) + { + node.Cells[i].Images.Image = (Image)propertyValue; + //node.Cells[i].Images.AutoDispose = true; + } + else + node.Cells[i].Text = GetItemText(item, fieldNames[i]); + } + } + else if (item != null) + node.Text = item.ToString(); + } + + + /// + /// Raises the DataNodeCreated event. + /// + /// Provides event arguments. + protected virtual void OnDataNodeCreated(DevComponents.DotNetBar.Controls.DataNodeEventArgs dataNodeEventArgs) + { + if (DataNodeCreated != null) DataNodeCreated(this, dataNodeEventArgs); + } + + /// + /// When overridden in a derived class, sets the object with the specified index in the derived class. + /// + /// The array index of the object. + /// The object. + protected virtual void SetItemCore(int index, object value) + { + Node node = this.FindNodeByBindingIndex(index); + if (node == null) return; + + List fieldNames = new List(); + + foreach (DevComponents.AdvTree.ColumnHeader column in this.Columns) + { + if (!string.IsNullOrEmpty(column.DataFieldName)) + fieldNames.Add(column.DataFieldName); + } + + SetNodeData(node, value, fieldNames, index); + } + + private string _ParentFieldNames = ""; + /// + /// Gets or sets comma separated field or property names that holds the value that is used to identify node and parent node. Format expected is: FieldNodeId,ParentNodeFieldId. For example if your table represents departments, you have DepartmentId field which uniquely identifies a department and ParentDepartmentId field which identifies parent of the department if any you would set this property to DepartmentId,ParentDepartmentId. + /// Note that you can only use ParentFieldNames or GroupingMembers property but not both. If both are set ParentFieldName take precedence. + /// + [DefaultValue(""), Category("Data"), Description("Indicates comma separated field or property names that holds the value that is used to identify node and parent node. Format expected is: FieldNodeId,ParentNodeFieldId. For example if your table represents departments, you have DepartmentId field which uniquely identifies a department and ParentDepartmentId field which identifies parent of the department if any you would set this property to DepartmentId,ParentDepartmentId.")] + public string ParentFieldNames + { + get { return _ParentFieldNames; } + set + { + if (value == null) value = ""; + if (!string.IsNullOrEmpty(value)) + { + string[] fields = value.Split(','); + if (fields.Length != 2) + throw new ArgumentException("ParentFieldNames excepts two and only two fields/property names separated by comma character."); + if (string.IsNullOrEmpty(fields[0])) + throw new ArgumentException("ParentFieldNames excepts two and only two fields/property names separated by comma character. First field name is empty."); + if (string.IsNullOrEmpty(fields[1])) + throw new ArgumentException("ParentFieldNames excepts two and only two fields/property names separated by comma character. Second field name is empty."); + } + _ParentFieldNames = value; + OnParentFieldNamesChanged(); + } + } + + /// + /// Called when ParentFieldName property has changed. + /// + protected virtual void OnParentFieldNamesChanged() + { + RefreshItems(); + } + + private string _GroupingMembers = ""; + /// + /// Gets or sets comma separated list of field or property names that are used for grouping when data-binding is used. Note that you can only use ParentFieldName or GroupingMembers property but not both. If both are set ParentFieldName take precedence. + /// + [DefaultValue(""), Category("Data"), Description("Indicates comma separated list of field or property names that are used for grouping when data-binding is used")] + public string GroupingMembers + { + get { return _GroupingMembers; } + set + { + if (value == null) value = ""; + _GroupingMembers = value; + OnGroupingMembersChanged(); + } + } + + /// + /// Called when GroupingMembers property has changed. + /// + protected virtual void OnGroupingMembersChanged() + { + RefreshItems(); + } + + private ElementStyle _GroupNodeStyle = null; + /// + /// Gets or sets style for automatically created group nodes when data-binding is used and GroupingMembers property is set. + /// + /// + /// Name of the style assigned or null value indicating that no style is used. + /// Default value is null. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Gets or sets default style for the node.")] + public ElementStyle GroupNodeStyle + { + get { return _GroupNodeStyle; } + set + { + if (_GroupNodeStyle != value) + { + _GroupNodeStyle = value; + if (_DataManager != null && this.Nodes != null) + RefreshItems(); + } + } + } + + private bool AllowSelection + { + get + { + return true; + } + } + + + private CurrencyManager _DataManager = null; + protected CurrencyManager DataManager + { + get + { + return _DataManager; + } + } + private bool _IsDataSourceInitEventHooked = false; + private void UnwireDataSource() + { + if (_DataSource is IComponent) + { + ((IComponent)_DataSource).Disposed -= new EventHandler(DataSourceDisposed); + } + ISupportInitializeNotification dataSource = _DataSource as ISupportInitializeNotification; + if ((dataSource != null) && _IsDataSourceInitEventHooked) + { + dataSource.Initialized -= new EventHandler(DataSourceInitialized); + _IsDataSourceInitEventHooked = false; + } + } + private void DataSourceDisposed(object sender, EventArgs e) + { + this.SetDataConnection(null, null, true); + } + private bool _IsDataSourceInitialized = false; + private void WireDataSource() + { + if (_DataSource is IComponent) + { + ((IComponent)_DataSource).Disposed += new EventHandler(DataSourceDisposed); + } + ISupportInitializeNotification dataSource = _DataSource as ISupportInitializeNotification; + if ((dataSource != null) && !dataSource.IsInitialized) + { + dataSource.Initialized += new EventHandler(DataSourceInitialized); + _IsDataSourceInitEventHooked = true; + _IsDataSourceInitialized = false; + } + else + { + _IsDataSourceInitialized = true; + } + } + private void DataSourceInitialized(object sender, EventArgs e) + { + this.SetDataConnection(_DataSource, _DisplayMembers, true); + } + /// + /// Raises the Format event. + /// + /// Event parameters + protected virtual void OnFormat(DevComponents.DotNetBar.Controls.TreeConvertEventArgs e) + { + DevComponents.DotNetBar.Controls.TreeConvertEventHandler handler = Format; + if (handler != null) + { + handler(this, e); + } + } + + private static TypeConverter stringTypeConverter; + public string GetItemText(object item, string fieldName) + { + object propertyValue = GetPropertyValue(item, fieldName); + if (!_FormattingEnabled) + { + if (item == null) + { + return string.Empty; + } + if (propertyValue == null) + { + return ""; + } + return Convert.ToString(propertyValue, CultureInfo.CurrentCulture); + } + + DevComponents.DotNetBar.Controls.TreeConvertEventArgs e = new DevComponents.DotNetBar.Controls.TreeConvertEventArgs(propertyValue, typeof(string), item, fieldName); + this.OnFormat(e); + if ((e.Value != item) && (e.Value is string)) + { + return (string)e.Value; + } + if (stringTypeConverter == null) + { + stringTypeConverter = TypeDescriptor.GetConverter(typeof(string)); + } + try + { + return (string)FormatHelper.FormatObject(propertyValue, typeof(string), GetFieldConverter(fieldName), stringTypeConverter, _FormatString, _FormatInfo, null, DBNull.Value); + } + catch (Exception ex) + { + if (ex is SecurityException || IsCriticalException(ex)) + { + throw; + } + return ((propertyValue != null) ? Convert.ToString(item, CultureInfo.CurrentCulture) : ""); + } + } + private static bool IsCriticalException(Exception ex) + { + return (((((ex is NullReferenceException) || (ex is StackOverflowException)) || ((ex is OutOfMemoryException) || (ex is System.Threading.ThreadAbortException))) || ((ex is ExecutionEngineException) || (ex is IndexOutOfRangeException))) || (ex is AccessViolationException)); + } + Dictionary _DescriptorsCache = new Dictionary(); + /// + /// Clears internal property descriptors cache when data-binding is used. In most cases it is not needed that you call this method. Do so only if instructed by DevComponents support. + /// + public void ClearDescriptorsCache() + { + _DescriptorsCache.Clear(); + } + protected object GetPropertyValue(object item, string fieldName) + { + if ((item != null) && (fieldName.Length > 0)) + { + try + { + PropertyDescriptor descriptor = null; + string key = item.GetType().ToString() + ":" + fieldName; + if (!_DescriptorsCache.TryGetValue(key, out descriptor)) + { + if (_DataManager != null) + { + descriptor = _DataManager.GetItemProperties().Find(fieldName, true); + } + else + { + descriptor = TypeDescriptor.GetProperties(item).Find(fieldName, true); + } + if (descriptor != null) + _DescriptorsCache.Add(key, descriptor); + } + if (descriptor != null) + { + item = descriptor.GetValue(item); + } + } + catch + { + } + } + return item; + } + /// + /// Gets or sets the index specifying the currently selected item. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Description("Gets or sets the index specifying the currently selected item.")] + public int SelectedIndex + { + get + { + if (_DataManager != null) + { + if (this.SelectedNode == null || this.SelectedNode.BindingIndex < 0) + return -1; + return this.SelectedNode.BindingIndex; + } + if (this.SelectedNode == null) return -1; + return this.GetNodeFlatIndex(this.SelectedNode); + } + set + { + SetSelectedIndex(value); + } + } + private void SetSelectedIndex(int value) + { + if (value == -1) + { + this.SelectedNode = null; + return; + } + Node node = null; + if (_DataManager != null) + { + node = this.FindNodeByBindingIndex(value); + } + else + { + node = this.GetNodeByFlatIndex(value); + } + this.SelectedNode = node; + } + /// + /// Raises the SelectedIndexChanged event. + /// + /// Event arguments. + protected virtual void OnSelectedIndexChanged(EventArgs e) + { + EventHandler handler = SelectedIndexChanged; + if (handler != null) + { + handler(this, e); + } + } + private BindingMemberInfo _ValueMember = new BindingMemberInfo(); + /// + /// Gets or sets the property to use as the actual value for the items in the control. Applies to data-binding scenarios. SelectedValue property will return the value of selected node as indicated by this property. + /// + [Category("Data"), DefaultValue(""), Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor)), Description("property to use as the actual value for the items in the control. Applies to data-binding scenarios. SelectedValue property will return the value of selected node as indicated by this property.")] + public string ValueMember + { + get + { + return _ValueMember.BindingMember; + } + set + { + if (value == null) + { + value = ""; + } + BindingMemberInfo newValueMember = new BindingMemberInfo(value); + if (!newValueMember.Equals(_ValueMember)) + { + if (this.DisplayMembers.Length == 0) + { + List list = new List(); + list.Add(newValueMember); + this.SetDataConnection(this.DataSource, list, false); + } + if (((_DataManager != null) && (value != null)) && ((value.Length != 0) && !this.BindingMemberInfoInDataManager(newValueMember))) + { + throw new ArgumentException("Invalid value for ValueMember", "value"); + } + _ValueMember = newValueMember; + this.OnValueMemberChanged(EventArgs.Empty); + this.OnSelectedValueChanged(EventArgs.Empty); + } + } + } + /// + /// Raises the ValueMemberChanged event. + /// + /// Event arguments. + protected virtual void OnValueMemberChanged(EventArgs e) + { + EventHandler handler = ValueMemberChanged; + if (handler != null) + { + handler(this, e); + } + } + /// + /// Raises the SelectedValueChanged event. + /// + /// Event arguments. + protected virtual void OnSelectedValueChanged(EventArgs e) + { + EventHandler handler = SelectedValueChanged; + if (handler != null) + { + handler(this, e); + } + } + /// + /// Gets or sets the value of the member property specified by the ValueMember property. + /// + [Browsable(false), DefaultValue(null), Bindable(true), Category("Data"), Description("Indicates value of the member property specified by the ValueMember property."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object SelectedValue + { + get + { + if (_DataManager != null && this.SelectedIndex != -1) + { + object item = _DataManager.List[this.SelectedIndex]; + return this.GetPropertyValue(item, _ValueMember.BindingField); + } + return null; + } + set + { + if (_DataManager != null) + { + string bindingField = _ValueMember.BindingField; + if (string.IsNullOrEmpty(bindingField)) + { + throw new InvalidOperationException("ValueMember property must be set to be able to set SelectedValue"); + } + PropertyDescriptor property = _DataManager.GetItemProperties().Find(bindingField, true); + System.Reflection.MethodInfo mi = _DataManager.GetType().GetMethod("Find", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + int num = -1; + if (mi != null) + { + num = (int)mi.Invoke(_DataManager, new object[] { property, value, true }); + } + else + { + //int num = _DataManager.Find(property, value, true); + // Provide an alternate implementation... + } + this.SelectedIndex = num; + } + } + } + + private bool _EnableDataPositionChange = true; + /// + /// Indicates whether control changes the CurrencyManager.DataPosition when selected node is changed during data binding. + /// Default value is true. + /// + [Browsable(false), DefaultValue(true)] + public bool EnableDataPositionChange + { + get + { + return _EnableDataPositionChange; + } + set + { + _EnableDataPositionChange = value; + } + } +#endif + #endregion + + #region Touch Handling + private DevComponents.DotNetBar.Touch.TouchHandler _TouchHandler = null; + + private bool _TouchEnabled = true; + /// + /// Indicates whether touch support for scrolling is enabled. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether touch support for scrolling is enabled.")] + public bool TouchEnabled + { + get { return _TouchEnabled; } + set + { + if (value != _TouchEnabled) + { + bool oldValue = _TouchEnabled; + _TouchEnabled = value; + OnTouchEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when TouchEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTouchEnabledChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TouchEnabled")); + } + private int TriggerPageChangeOffset + { + get + { + return 32; + } + } + private int MaximumReversePageOffset + { + get + { + return 0; //Math.Min(32, this.Width / 6); + } + } + private bool _TouchDrag = false; + private Point _TouchStartLocation = Point.Empty; + private Point _TouchStartScrollPosition = Point.Empty; + private Rectangle _TouchInnerBounds = Rectangle.Empty; + private void TouchHandlerPanBegin(object sender, DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (_TouchEnabled) + { + _TouchInnerBounds = GetInnerRectangle(); + _TouchStartLocation = e.Location; + _TouchStartScrollPosition = _AutoScrollPosition; + _TouchDrag = true; + e.Handled = true; + } + } + + private void TouchHandlerPanEnd(object sender, DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + EndTouchPan(); + e.Handled = true; + } + } + + private void EndTouchPan() + { + _TouchDrag = false; + Point autoScrollPosition = this.AutoScrollPosition; + + if (_AutoScrollMinSize.Width > _TouchInnerBounds.Width) + { + if (_AutoScrollMinSize.Width - _TouchInnerBounds.Width < -_AutoScrollPosition.X) + autoScrollPosition = new Point(_AutoScrollMinSize.Width - _TouchInnerBounds.Width, autoScrollPosition.Y); + else if (-_AutoScrollPosition.X < 0) + autoScrollPosition = new Point(0, autoScrollPosition.Y); + } + + if (_AutoScrollMinSize.Height > _TouchInnerBounds.Height) + { + if (_AutoScrollMinSize.Height - _TouchInnerBounds.Height < -_AutoScrollPosition.Y) + autoScrollPosition = new Point(autoScrollPosition.X, _AutoScrollMinSize.Height - _TouchInnerBounds.Height); + else if (-_AutoScrollPosition.Y < 0) + autoScrollPosition = new Point(autoScrollPosition.X, 0); + } + + if (this.AutoScrollPosition != autoScrollPosition) + { + this.AutoScrollPosition = autoScrollPosition; + OnScroll(new ScrollEventArgs(ScrollEventType.EndScroll, autoScrollPosition.Y)); + } + //ApplyScrollChange(); + + } + + private void TouchHandlerPan(object sender, DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + Point autoScrollPosition = this.AutoScrollPosition; + + int offset = (e.Location.X - _TouchStartLocation.X); + int offsetChange = offset + _TouchStartScrollPosition.X; + + bool overflowH = false; + + if (_AutoScrollMinSize.Width > _TouchInnerBounds.Width) + { + if (-offsetChange + MaximumReversePageOffset > _AutoScrollMinSize.Width - _TouchInnerBounds.Width) + { + autoScrollPosition.X = -(_AutoScrollMinSize.Width + MaximumReversePageOffset - _TouchInnerBounds.Width); + overflowH = true; + } + else if (offsetChange > MaximumReversePageOffset) + { + autoScrollPosition.X = MaximumReversePageOffset; + overflowH = true; + } + else + autoScrollPosition.X = offsetChange; + } + + // Y Scroll + bool overflowV = false; + if (_AutoScrollMinSize.Height > _TouchInnerBounds.Height) + { + offset = (e.Location.Y - _TouchStartLocation.Y); + offsetChange = offset + _TouchStartScrollPosition.Y; + + if (-offsetChange + MaximumReversePageOffset > _AutoScrollMinSize.Height - _TouchInnerBounds.Height) + { + autoScrollPosition.Y = -(_AutoScrollMinSize.Height + MaximumReversePageOffset - _TouchInnerBounds.Height); + overflowV = true; + } + else if (offsetChange > MaximumReversePageOffset) + { + autoScrollPosition.Y = MaximumReversePageOffset; + overflowV = true; + } + else + autoScrollPosition.Y = offsetChange; + } + + if (this.AutoScrollPosition != autoScrollPosition) + { + this.AutoScrollPosition = autoScrollPosition; + Update(); + OnScroll(new ScrollEventArgs(ScrollEventType.ThumbTrack, autoScrollPosition.Y)); + } + if (overflowH && overflowV && e.IsInertia) EndTouchPan(); + + + //if (_VScrollBar != null && _VScrollBar.Value != -_AutoScrollPosition.Y) + // _VScrollBar.Value = Math.Min(_VScrollBar.Maximum, Math.Max(0, -_AutoScrollPosition.Y)); + //if (_HScrollBar != null && _HScrollBar.Value != -_AutoScrollPosition.X) + // _HScrollBar.Value = Math.Min(_HScrollBar.Maximum, Math.Max(0, -_AutoScrollPosition.X)); + e.Handled = true; + } + } + #endregion + } + + #region AdvTreeSettings + /// + /// Static class that holds AdvTree settings that are not commonly used. + /// + public class AdvTreeSettings + { + /// + /// Gets or sets whether tree control is scrolled horizontally so selected node is brought into the view. Default value is false. + /// You can set this property to false to disable the horizontal scrolling of tree control when selected node has changed. + /// + public static bool SelectedScrollIntoViewHorizontal = false; + /// + /// Gets or sets whether AdvTree node comparer that provides column sorting uses standard text comparer instead of default + /// hybrid alpha-numeric comparer. Default value is false. + /// + public static bool UseSortAlphaComparer = false; + } + #endregion + + #region ICellEditControl + /// + /// Defines an interface for cell edit control that allows custom controls to be used as cell editors. AdvTree control + /// expects that editing control inherits from System.Windows.Forms.Control. + /// + public interface ICellEditControl + { + /// + /// Called when edit operation is started. The AdvTree control will first set CurrentValue, then call BeginEdit and will call EditComplete once + /// editing is completed. + /// + void BeginEdit(); + /// + /// Called when edit operation is completed. + /// + void EndEdit(); + /// + /// Gets or sets current edit value. + /// + object CurrentValue { get;set;} + /// + /// AdvTree control subscribes to this event to be notified when edit operation is completed. For example when Enter key is + /// pressed the edit control might raise this event to indicate the completion of editing operation. + /// + event EventHandler EditComplete; + /// + /// AdvTree control subscribes to this event to be notified that user has cancelled the editing. For example when Escape key is + /// pressed the edit control might raise this event to indicate that editing has been cancelled. + /// + event EventHandler CancelEdit; + /// + /// Gets or sets whether cell requests the word-wrap based on the current cell style. If your editor does not support + /// word-wrap functionality this can be ignored. + /// + bool EditWordWrap { get;set;} + } + #endregion + + #region PrepareCellEditor + /// + /// Defines delegate for PrepareCellEditor event. + /// + /// + /// + public delegate void PrepareCellEditorEventHandler(object sender, PrepareCellEditorEventArgs e); + /// + /// Event arguments for PrepareCellEditor event. + /// + public class PrepareCellEditorEventArgs : EventArgs + { + /// + /// Gets reference to the cell being edited. + /// + public readonly Cell EditedCell; + /// + /// Gets reference to the cell editor control. + /// + public readonly ICellEditControl Editor; + /// + /// Initializes a new instance of the PrepareCellEditorEventArgs class. + /// + /// + /// + public PrepareCellEditorEventArgs(Cell editedCell, ICellEditControl editor) + { + EditedCell = editedCell; + Editor = editor; + } + } + #endregion + + #region AdvTreeRender + /// + /// Defines delegate for PrepareCellEditor event. + /// + /// + /// + public delegate void AdvTreeRenderEventHandler(object sender, AdvTreeRenderEventArgs e); + /// + /// Event arguments for AdvTree.Render event. + /// + public class AdvTreeRenderEventArgs : EventArgs + { + /// + /// Indicates the rendering operation being performed. + /// + public readonly eAdvTreeRenderType RenderType; + /// + /// Indicates graphics canvas to render on. + /// + public Graphics Graphics; + /// + /// Initializes a new instance of the AdvTreeRenderEventArgs class. + /// + /// Specifies rendering type + /// Specifies graphics canvas to render on + public AdvTreeRenderEventArgs(eAdvTreeRenderType renderType, Graphics g) + { + RenderType = renderType; + Graphics = g; + } + } + /// + /// Specifies the rendering type being performed on AdvTree control Render event. + /// + public enum eAdvTreeRenderType + { + /// + /// Control background is being painted. + /// + Background + } + #endregion +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/AdvTree/AdvTree.resx b/PROMS/DotNetBar Source Code/AdvTree/AdvTree.resx new file mode 100644 index 00000000..7e323966 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/AdvTree.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/PROMS/DotNetBar Source Code/AdvTree/Cell.cs b/PROMS/DotNetBar Source Code/AdvTree/Cell.cs new file mode 100644 index 00000000..1383dbb0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Cell.cs @@ -0,0 +1,1836 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.AdvTree.Display; +using DevComponents.DotNetBar; +using System.Collections; + +namespace DevComponents.AdvTree +{ + /// Represents a cell assigned to the Node. + /// + /// The Cell with Index 0 (zero) always exists for a Node and it is a cell that + /// you can interact with through the properties on a node, which are forwarding to the + /// Cell(0), or you can go directly to the Cell(0). + /// When Node has multiple columns defined each column corresponds to Cell in + /// Node's Cells collection. The first Column has Index 0, second Column Index 1 and so + /// forth. + /// Note that there is always at least one Cell in a Node even if multiple + /// columns are not used. + /// + [DesignTimeVisible(false),ToolboxItem(false)] + public class Cell:Component + { + #region Private Variables + private ElementStyle m_StyleNormal=null; + private ElementStyle m_StyleDisabled=null; + private ElementStyle m_StyleMouseDown=null; + private ElementStyle m_StyleMouseOver=null; + private ElementStyle m_StyleSelected=null; + private bool m_Enabled=true; + private CellImages m_Images=null; + private Rectangle m_Bounds=Rectangle.Empty; + private Rectangle m_TextBounds=Rectangle.Empty; + private Rectangle m_TextContentBounds=Rectangle.Empty; + private Rectangle m_ImageBounds=Rectangle.Empty; + private Rectangle m_CheckBoxBounds=Rectangle.Empty; + private object m_Tag=null; + private string m_Text=""; + private eCellPartAlignment m_ImageAlignment=eCellPartAlignment.Default; + private eCellPartAlignment m_CheckBoxAlignment=eCellPartAlignment.Default; + private bool m_CheckBoxVisible=false; + private bool m_Checked=false; + private bool m_MouseDown=false; + private bool m_MouseOver=false; + private bool m_Selected=false; + private Node m_Parent=null; + private bool m_Visible=true; + private eTreeAction m_ActionSource=eTreeAction.Code; + private eCellPartLayout m_Layout=eCellPartLayout.Default; + private System.Windows.Forms.Cursor m_Cursor=null; + private bool m_WordWrap=false; + private string m_Name=""; + private Control m_HostedControl=null; + private Size m_HostedControlSize=Size.Empty; + private bool m_IgnoreHostedControlSizeChange=false; + #endregion + + #region Constructor/Dispose + /// + /// Initializes new instance of Cell class. + /// + public Cell():this("") + { + } + + /// + /// Initializes new instance of Cell class. + /// + /// Cell text. + public Cell(string text) + { + Text=text; + m_Images=new CellImages(this); + } + + /// + /// Initializes new instance of Cell class. + /// + /// Cell text. + public Cell(string text, ElementStyle styleNormal) + : this(text) + { + this.StyleNormal = styleNormal; + } + + /// + /// Initializes new instance of Cell class. + /// + /// Cell text. + public Cell(string text, string styleNormalName) + : this(text) + { + this.StyleNormalName = styleNormalName; + } + + /// + /// Releases the resources used by the Component. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if(m_HostedControl!=null) + m_HostedControl.SizeChanged-=new EventHandler(this.HostedControlSizedChanged); + m_HostedControl=null; + if (m_Images != null) + { + m_Images.Dispose(); + } + base.Dispose(disposing); + } + #endregion + + #region Properties + /// + /// Occurs after Tooltip text has changed. + /// + protected virtual void OnTooltipChanged() { } + private string _Tooltip = ""; + /// + /// Gets/Sets informational text (tooltip) for the cell. + /// + [Browsable(true), DefaultValue(""), Category("Appearance"), Description("Indicates the text that is displayed when mouse hovers over the cell."), Localizable(true)] + public string Tooltip + { + get + { + + return _Tooltip; + } + set + { + if (_Tooltip == value) + return; + if (value == null) value = ""; + _Tooltip = value; + + if (this.ToolTipVisible) + { + if (string.IsNullOrEmpty(_Tooltip)) + this.HideToolTip(); + else + { + DevComponents.DotNetBar.ToolTip tooltipWindow = _ToolTipWnd; + tooltipWindow.Text = _Tooltip; + tooltipWindow.ShowToolTip(); + tooltipWindow.Invalidate(); + } + } + OnTooltipChanged(); + } + } + /// + /// Gets whether tooltip is visible or not. + /// + internal protected bool ToolTipVisible + { + get + { + return (_ToolTipWnd != null); + } + } + /// + /// Called when tooltip is shown and hidden. + /// + /// true if tooltip is being shown otherwise false. + protected virtual void OnTooltip(bool isShown) + { + } + private DevComponents.DotNetBar.ToolTip _ToolTipWnd = null; + /// + /// Shows tooltip for this item. + /// + public virtual void ShowToolTip() + { + if (this.DesignMode) + return; + + if (IsVisible) + { + AdvTree tree = TreeControl; + if (tree != null && !tree.ShowToolTips || !this.ShowToolTips) + return; + OnTooltip(true); + if (_Tooltip != "") + { + if (_ToolTipWnd == null) + _ToolTipWnd = new DevComponents.DotNetBar.ToolTip(); + _ToolTipWnd.Style = StyleManager.GetEffectiveStyle(); + _ToolTipWnd.Text = _Tooltip; + _ToolTipWnd.ReferenceRectangle = ScreenRectangle; + + OnToolTipVisibleChanged(new EventArgs()); + _ToolTipWnd.ShowToolTip(); + } + } + } + /// + /// Destroys tooltip window. + /// + internal protected void HideToolTip() + { + if (_ToolTipWnd != null) + { + System.Drawing.Rectangle tipRect = _ToolTipWnd.Bounds; + tipRect.Width += 5; + tipRect.Height += 6; + + OnTooltip(false); + OnToolTipVisibleChanged(new EventArgs()); + try + { + if (_ToolTipWnd != null) + { + _ToolTipWnd.Hide(); + _ToolTipWnd.Dispose(); + _ToolTipWnd = null; + } + } + catch { } + AdvTree tree = this.TreeControl; + if (tree != null) + { + tree.Invalidate(tree.RectangleToClient(tipRect), false); + } + } + } + /// + /// Occurs when item's tooltip visibility has changed. + /// + [System.ComponentModel.Description("Occurs when item's tooltip visibility has changed.")] + public event EventHandler ToolTipVisibleChanged; + private void OnToolTipVisibleChanged(EventArgs eventArgs) + { + EventHandler h = ToolTipVisibleChanged; + if (h != null) + ToolTipVisibleChanged(this, eventArgs); + } + private Rectangle ScreenRectangle + { + get + { + AdvTree tree = this.TreeControl; + if (tree == null) return Rectangle.Empty; + return new Rectangle(tree.PointToScreen(this.Bounds.Location), this.Bounds.Size); + } + } + + private bool _ShowToolTips = true; + /// + /// Gets or sets whether tooltips are shown when mouse is over the cell when Tooltip property is set. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether tooltips are shown when mouse is over the cell when Tooltip property is set.")] + public bool ShowToolTips + { + get { return _ShowToolTips; } + set + { + _ShowToolTips = value; + } + } + + + private bool _Editable = true; + /// + /// Gets or sets whether cell content is editable when cell editing is enabled on tree control. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether cell content is editable when cell editing is enabled on tree control.")] + public bool Editable + { + get { return _Editable; } + set + { + _Editable = value; + } + } + + /// + /// Gets whether cell can be edited. Cell can be edited if both Editable property is set to true and ColumnHeader.Editable property is set to true. + /// + [Browsable(false)] + public bool IsEditable + { + get + { + ColumnHeader header = NodeOperations.GetCellColumnHeader(this.TreeControl, this); + if (header == null) return _Editable; + return _Editable && header.Editable; + } + } + + private BaseItem _HostedItem = null; + /// + /// Gets or sets the item hosted inside of the cell. Only items that do not generate + /// popups are supported. Note that cell can only host either HostedItem or HostedControl but not both. + /// + [DefaultValue(null), Category("Appearance"), Editor("DevComponents.AdvTree.Design.HostedItemTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates item hosted inside of the cell. Only items that do not generate popups are supported. Note that cell can only host either HostedItem or HostedControl but not both.")] + public BaseItem HostedItem + { + get { return _HostedItem; } + set { SetHostedItem(value); } + } + + /// + /// Gets or sets the control hosted inside of the cell. Note that cell can only host either HostedItem or HostedControl but not both. + /// + /// + /// When control is hosted inside of the cell, cell size is determined by the + /// size of the control hosted inside of it. The cell will not display its text but it will display any image assigned + /// or check box when control is hosted inside of it. The Style settings like Margin + /// and Padding will still apply. + /// + [Browsable(true),Category("Behavior"),Description("Indicates control hosted inside of the cell."),DefaultValue(null)] + public Control HostedControl + { + get {return m_HostedControl;} + set + { + SetHostedControl(value); + } + } + + /// + /// Gets or sets whether hosted control size change event is ignored. + /// + internal bool IgnoreHostedControlSizeChange + { + get { return m_IgnoreHostedControlSizeChange;} + set { m_IgnoreHostedControlSizeChange=value; } + } + + /// + /// Gets or sets the hosted control size. Property is used to correctly scale control when AdvTree.Zoom is used to zoom view. + /// + internal Size HostedControlSize + { + get { return m_HostedControlSize;} + set { m_HostedControlSize = value;} + } + + /// + /// Returns name of the cell that can be used to identify it from the code. + /// + [Browsable(false),Category("Design"),Description("Indicates the name used to identify cell.")] + 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; + } + } + + /// + /// Gets the relative bounds of the cell. + /// + [Browsable(false)] + internal Rectangle BoundsRelative + { + get + { + return m_Bounds; + } + } + + /// + /// Gets the bounds of the cell. + /// + [Browsable(false)] + public Rectangle Bounds + { + get + { + AdvTree tree=this.TreeControl; + if(tree!=null) + { + return NodeDisplay.GetCellRectangle(eCellRectanglePart.CellBounds, this, tree.NodeDisplay.Offset); + } + return Rectangle.Empty; + } + } + + /// + /// Sets the bounds of the cell. + /// + /// New cell bounds. + internal void SetBounds(Rectangle bounds) + { + m_Bounds=bounds; + } + +// /// +// /// Gets the bounds of the text inside of cell. +// /// +// [Browsable(false)] +// public Rectangle TextBounds +// { +// get +// { +// return m_TextBounds; +// } +// } + +// /// +// /// Sets the bounds of the text inside of the cell. +// /// +// /// New cell bounds. +// internal void SetTextBounds(Rectangle bounds) +// { +// m_TextBounds=bounds; +// } + + /// + /// Gets or sets the available content bounds for the text. Text will fitted into these bounds + /// but it's true location can be obtained only after it is displayed. + /// + internal Rectangle TextContentBounds + { + get {return m_TextContentBounds;} + set {m_TextContentBounds=value;} + } + + /// + /// Gets the bounds of the text inside of cell. + /// + [Browsable(false)] + public Rectangle TextBounds + { + get + { + AdvTree tree = this.TreeControl; + if (tree != null) + { + return NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds, this, tree.NodeDisplay.Offset); + } + return Rectangle.Empty; + } + } + + /// + /// Gets the relative bounds of the image inside of cell. + /// + [Browsable(false)] + internal Rectangle ImageBoundsRelative + { + get + { + return m_ImageBounds; + } + } + + /// + /// Gets the bounds of the image inside of cell. + /// + [Browsable(false)] + public Rectangle ImageBounds + { + get + { + AdvTree tree=this.TreeControl; + if(tree!=null) + { + return NodeDisplay.GetCellRectangle(eCellRectanglePart.ImageBounds, this, tree.NodeDisplay.Offset); + } + return Rectangle.Empty; + } + } + + /// + /// Sets the bounds of the image inside of the cell. + /// + /// New cell bounds. + internal void SetImageBounds(Rectangle bounds) + { + m_ImageBounds=bounds; + } + + /// + /// Gets the bounds of the image inside of cell. + /// + [Browsable(false)] + internal Rectangle CheckBoxBoundsRelative + { + get + { + return m_CheckBoxBounds; + } + } + + /// + /// Gets the bounds of the check box inside of cell. + /// + [Browsable(false)] + public Rectangle CheckBoxBounds + { + get + { + AdvTree tree=this.TreeControl; + if (tree != null) + { + return NodeDisplay.GetCellRectangle(eCellRectanglePart.CheckBoxBounds, this, tree.NodeDisplay.Offset); + } + return Rectangle.Empty; + } + } + + /// + /// Sets the bounds of the check box inside of the cell. + /// + /// New cell bounds. + internal void SetCheckBoxBounds(Rectangle bounds) + { + m_CheckBoxBounds=bounds; + } + + /// + /// Gets a value indicating whether the cell is in an editable state. true if the cell is in editable state; otherwise, false. + /// + [Browsable(false)] + public bool IsEditing + { + get + { + return false; + } + } + + /// + /// Gets a value indicating whether the cell is in the selected state. true if the cell is in the selected state; otherwise, false. + /// + [Browsable(false)] + public bool IsSelected + { + get + { + return m_Selected; + } + } + + internal void SetSelected(bool selected, eTreeAction actionSource) + { + m_Selected = selected; + } + + /// + /// Gets a value indicating whether the cell is visible. Cell is considered to be visible when it's parent column is visible. + /// + [Browsable(false)] + public bool IsVisible + { + get + { + return m_Visible; + } + } + + /// + /// Sets whether cells is visible or not. This is set by node layout manager and it is based on column visibility. + /// + /// True if visible otherwise false. + internal void SetVisible(bool visible) + { + if(m_Visible!=visible) + { + m_Visible=visible; + OnVisibleChanged(); + } + } + + /// + /// Gets the parent node of the current cell. + /// + [Browsable(false)] + public Node Parent + { + get + { + return m_Parent; + } + } + + /// + /// Sets the parent of the cell. + /// + /// Parent node. + internal void SetParent(Node parent) + { + m_Parent=parent; + } + + /// + /// Gets or sets the object that contains data about the cell. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// + [Browsable(false),DefaultValue(null),Category("Data"),Description("Indicates text that contains data about the cell.")] + public object Tag + { + get + { + return m_Tag; + } + set + { + m_Tag=value; + } + } + + /// + /// Gets or sets the object that contains data about the cell. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// + [Browsable(true),DefaultValue(""),Category("Data"),Description("Indicates text that contains data about the cell."),DevCoSerialize()] + public string TagString + { + get + { + if(m_Tag==null) + return ""; + return m_Tag.ToString(); + } + set + { + m_Tag=value; + } + } + + private string _TextDisplayFormat = ""; + /// + /// Gets or sets the format that is applied to the value of Text property for display purposes. See "Formatting Overview" in MSDN + /// for description on available format strings. For example you can specify "C" to format text as currency, or "D" to format text as decimal number etc. + /// + /// + [Browsable(true), DefaultValue(""), Category("Appearance"), Description("Indicates format that is applied to the value of Text property for display purposes.")] + public string TextDisplayFormat + { + get { return _TextDisplayFormat; } + set + { + _TextDisplayFormat = value; + UpdateDisplayText(); + this.OnSizeChanged(); + } + } + + private string _DisplayText = string.Empty; + /// + /// Gets the formatted display text. + /// + internal string DisplayText + { + get + { + return _DisplayText; + } + } + private void UpdateDisplayText() + { + if (string.IsNullOrEmpty(_TextDisplayFormat)) + { + _DisplayText = m_Text; + return; + } + + long longNumber = 0; + double number = 0; + DateTime date = DateTime.MinValue; + if (long.TryParse(m_Text, out longNumber)) + { + _DisplayText = longNumber.ToString(_TextDisplayFormat); + } + else if (double.TryParse(m_Text, out number)) + { + _DisplayText = number.ToString(_TextDisplayFormat); + } + else if (DateTime.TryParse(m_Text, out date)) + { + _DisplayText = date.ToString(_TextDisplayFormat); + } + else + _DisplayText = m_Text; + } + + /// + /// Gets or sets the text displayed in the cell. + /// + [Browsable(true), DefaultValue(""), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Appearance"), Localizable(true), Description("Indicates text displayed in the cell."), DevCoSerialize()] + public string Text + { + get + { + return m_Text; + } + set + { + if (value == null) value = ""; + if (m_Text != value) + { + m_Text = value; + UpdateDisplayText(); + OnTextChanged(); + this.OnSizeChanged(); + } + } + } + + /// + /// Occurs after text has changed. + /// + protected virtual void OnTextChanged() + { + MarkupTextChanged(); + } + + /// + /// Gets the parent tree control that the cell belongs to. + /// + [Browsable(false)] + public AdvTree TreeControl + { + get + { + if(this.Parent!=null) + return this.Parent.TreeControl; + return null; + } + } + + /// + /// Gets or sets the style class assigned to the cell. Null value indicates that + /// default style is used as specified on cell's parent. + /// + /// + /// Reference to the style assigned to the cell or null (VB Nothing) indicating that default + /// style setting from tree control is applied. Default value is null. + /// + /// + /// When property is set to null (VB Nothing) the style setting from parent tree + /// controls is used. CellStyleNormal on AdvTree control is a root style for a cell. + /// + /// StyleDisabled Property + /// StyleMouseDown Property + /// StyleMouseOver Property + /// StyleSelected Property + [Browsable(true),DefaultValue(null),Category("Style"),Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf",typeof(System.Drawing.Design.UITypeEditor)),Description("Indicates the style class assigned to the cell.")] + public ElementStyle StyleNormal + { + get {return m_StyleNormal;} + set + { + m_StyleNormal=value; + } + } + + /// + /// Gets or sets the style name used by cell. This member is provided for internal use only. To set or get the style use StyleNormal property instead. + /// + [Browsable(false), DefaultValue(""), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) , DevCoSerialize()] + public string StyleNormalName + { + get + { + if(m_StyleNormal!=null) + return m_StyleNormal.Name; + return ""; + } + set + { + if(value.Length==0) + { + TypeDescriptor.GetProperties(this)["StyleNormal"].SetValue(this, null); + return; + } + + AdvTree tree=this.TreeControl; + if(tree!=null) + { + TypeDescriptor.GetProperties(this)["StyleNormal"].SetValue(this, tree.Styles[value]); + } + } + } + + /// + /// Gets or sets the style class that is to when cell is selected. Null value indicates that + /// default style is used as specified on cell's parent. + /// + /// + /// Reference to the style assigned to the cell or null value indicating that default + /// style setting from tree control is applied. Default is null value. + /// + /// + /// When property is set to null value the style setting from parent tree + /// controls is used. CellStyleSelected on AdvTree control is a root style for a cell. + /// + /// StyleNormal Property + /// StyleDisabled Property + /// StyleMouseDown Property + /// StyleMouseOver Property + [Browsable(true),DefaultValue(null),Category("Style"),Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf",typeof(System.Drawing.Design.UITypeEditor)),Description("Indicates the style class assigned to the cell.")] + public ElementStyle StyleSelected + { + get {return m_StyleSelected;} + set + { + m_StyleSelected=value; + } + } + + /// + /// Gets or sets the selected style name used by cell. This member is provided for internal use only. To set or get the style use StyleSelected property instead. + /// + [Browsable(false), DefaultValue(""), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) , DevCoSerialize()] + public string StyleSelectedName + { + get + { + if(m_StyleSelected!=null) + return m_StyleSelected.Name; + return ""; + } + set + { + if(value.Length==0) + { + TypeDescriptor.GetProperties(this)["StyleSelected"].SetValue(this, null); + return; + } + + AdvTree tree=this.TreeControl; + if(tree!=null) + { + TypeDescriptor.GetProperties(this)["StyleSelected"].SetValue(this, tree.Styles[value]); + } + } + } + + + /// + /// Gets or sets the disabled style class assigned to the cell. Null value indicates + /// that default style is used as specified on cell's parent. + /// + /// + /// Reference to the style assigned to the cell or null value indicating that default + /// style setting from tree control is applied. Default value is null. + /// + /// + /// When property is set to null value the style setting from parent tree + /// controls is used. CellStyleDisabled on AdvTree control is a root style for a + /// cell. + /// + /// StyleNormal Property + /// StyleMouseDown Property + /// StyleMouseOver Property + /// StyleSelected Property + [Browsable(true),DefaultValue(null),Category("Style"),Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf",typeof(System.Drawing.Design.UITypeEditor)),Description("Indicates the disabled style class assigned to the cell.")] + public ElementStyle StyleDisabled + { + get {return m_StyleDisabled;} + set + { + m_StyleDisabled=value; + } + } + + /// + /// Gets or sets the disabled style name used by cell. This member is provided for internal use only. To set or get the style use StyleDisabled property instead. + /// + [Browsable(false), DefaultValue(""), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) , DevCoSerialize()] + public string StyleDisabledName + { + get + { + if(m_StyleDisabled!=null) + return m_StyleDisabled.Name; + return ""; + } + set + { + if(value.Length==0) + { + TypeDescriptor.GetProperties(this)["StyleDisabled"].SetValue(this, null); + return; + } + + AdvTree tree=this.TreeControl; + if(tree!=null) + { + TypeDescriptor.GetProperties(this)["StyleDisabled"].SetValue(this, tree.Styles[value]); + } + } + } + + /// + /// Gets or sets the style class assigned to the cell which is applied when mouse + /// button is pressed while mouse is over the cell. Null value indicates that default + /// style is used as specified on cell's parent. + /// + /// + /// Reference to the style assigned to the cell or null value indicating that default + /// style setting from tree control is applied. Default value is null. + /// + /// + /// When property is set to null value style setting from parent tree + /// controls is used. CellStyleMouseDown on AdvTree control is a root style for a + /// cell. + /// + /// StyleNormal Property + /// StyleDisabled Property + /// StyleMouseOver Property + /// StyleSelected Property + [Browsable(true),DefaultValue(null),Category("Style"),Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf",typeof(System.Drawing.Design.UITypeEditor)),Description("Indicates the style class assigned to the cell when mouse is down.")] + public ElementStyle StyleMouseDown + { + get {return m_StyleMouseDown;} + set + { + m_StyleMouseDown=value; + } + } + + /// + /// Gets or sets the mouse down style name used by cell. This member is provided for internal use only. To set or get the style use StyleMouseDown property instead. + /// + [Browsable(false), DefaultValue(""), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) , DevCoSerialize()] + public string StyleMouseDownName + { + get + { + if(m_StyleMouseDown!=null) + return m_StyleMouseDown.Name; + return ""; + } + set + { + if(value.Length==0) + { + TypeDescriptor.GetProperties(this)["StyleMouseDown"].SetValue(this, null); + return; + } + + AdvTree tree=this.TreeControl; + if(tree!=null) + { + TypeDescriptor.GetProperties(this)["StyleMouseDown"].SetValue(this, tree.Styles[value]); + } + } + } + + /// + /// Gets or sets the style class assigned to the cell which is applied when mouse is + /// over the cell. Null value indicates that default style is used as specified on cell's + /// parent. + /// + /// + /// Reference to the style assigned to the cell or null value indicating that default + /// style setting from tree control is applied. Default value is null. + /// + /// + /// When property is set to null value the style setting from parent tree + /// controls is used. CellStyleMouseOver on AdvTree control is a root style for a + /// cell. + /// + /// StyleNormal Property + /// StyleDisabled Property + /// StyleMouseDown Property + /// StyleSelected Property + [Browsable(true),DefaultValue(""),Category("Style"),Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf",typeof(System.Drawing.Design.UITypeEditor)),Description("Indicates the style class assigned to the cell when mouse is over the cell.")] + public ElementStyle StyleMouseOver + { + get {return m_StyleMouseOver;} + set + { + m_StyleMouseOver=value; + } + } + + /// + /// Gets or sets the mouse over style name used by cell. This member is provided for internal use only. To set or get the style use StyleMouseOver property instead. + /// + [Browsable(false), DefaultValue(""), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) , DevCoSerialize()] + public string StyleMouseOverName + { + get + { + if(m_StyleMouseOver!=null) + return m_StyleMouseOver.Name; + return ""; + } + set + { + if(value.Length==0) + { + TypeDescriptor.GetProperties(this)["StyleMouseOver"].SetValue(this, null); + return; + } + + AdvTree tree=this.TreeControl; + if(tree!=null) + { + TypeDescriptor.GetProperties(this)["StyleMouseOver"].SetValue(this, tree.Styles[value]); + } + } + } + + + /// + /// Gets or sets whether cell is enabled or not. + /// + [Browsable(true),DefaultValue(true),Category("Behavior"),Description("Gets or sets whether cell is enabled or not."),DevCoSerialize()] + public bool Enabled + { + get {return m_Enabled;} + set + { + m_Enabled=value; + if (this.Parent != null) + { + this.Parent.OnDisplayChanged(); + } + } + } + + /// + /// Gets the reference to images associated with this cell. + /// + [Browsable(true),Category("Images"),Description("Gets the reference to images associated with this cell."),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CellImages Images + { + get {return m_Images;} + } + /// + /// Sets the Images to the new CellImages object. + /// + /// CellImages object. + internal void SetCellImages(CellImages ci) + { + m_Images=ci; + m_Images.Parent=this; + } + /// + /// Returns whether Images property should be serialized. Used internally for windows forms designer support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeImages() + { + return m_Images.ShouldSerialize; + } + + /// + /// Gets or sets the image alignment in relation to the text displayed by cell. + /// + [Browsable(true),Category("Image Properties"),DefaultValue(eCellPartAlignment.Default),Description("Gets or sets the image alignment in relation to the text displayed by cell."),DevCoSerialize()] + public eCellPartAlignment ImageAlignment + { + get + { + return m_ImageAlignment; + } + set + { + if(m_ImageAlignment!=value) + { + m_ImageAlignment=value; + this.OnAppearanceChanged(); + } + } + } + + /// + /// Gets or sets the checkbox alignment in relation to the text displayed by cell. + /// + [Browsable(true),Category("Check-box Properties"),DefaultValue(eCellPartAlignment.Default),Description("Indicates checkbox alignment in relation to the text displayed by cell.")] + public eCellPartAlignment CheckBoxAlignment + { + get + { + return m_CheckBoxAlignment; + } + set + { + if(m_CheckBoxAlignment!=value) + { + m_CheckBoxAlignment=value; + this.OnAppearanceChanged(); + } + } + } + + /// + /// Gets or sets whether check box is visible inside the cell. + /// + [Browsable(true),Category("Check-box Properties"),DefaultValue(false),Description("Indicates whether check box is visible inside the cell."),DevCoSerialize()] + public bool CheckBoxVisible + { + get + { + return m_CheckBoxVisible; + } + set + { + if(m_CheckBoxVisible!=value) + { + m_CheckBoxVisible=value; + this.OnAppearanceChanged(); + } + } + } + + /// + /// Gets or set a value indicating whether the check box is in the checked state. + /// + [Browsable(true),Category("Check-box Properties"),DefaultValue(false),Description("Indicates whether the check box is in the checked state."),DevCoSerialize()] + public bool Checked + { + get {return m_Checked;} + set + { + if(m_Checked!=value) + { + if (_ThreeState && value && _CheckState != CheckState.Unchecked) return; + SetChecked(value ? CheckState.Checked : CheckState.Unchecked, eTreeAction.Code); + } + } + } + + private bool _ThreeState = false; + /// + /// Gets or sets a value indicating whether the CheckBox will allow three check states rather than two. If the ThreeState property is set to true + /// CheckState property should be used instead of Checked property to set the extended state of the control. + /// + [Browsable(true), Category("Check-box Properties"), DefaultValue(false), Description("Indicates whether the CheckBox will allow three check states rather than two.")] + public bool CheckBoxThreeState + { + get { return _ThreeState; } + set { _ThreeState = value; } + } + + private CheckState _CheckState = CheckState.Unchecked; + /// + /// Specifies the state of a control, such as a check box, that can be checked, unchecked, or set to an indeterminate state. + /// + [Browsable(true), Category("Check-box Properties"), DefaultValue(CheckState.Unchecked), RefreshProperties(RefreshProperties.All), Description("Specifies the state of a control, such as a check box, that can be checked, unchecked, or set to an indeterminate state")] + public CheckState CheckState + { + get { return _CheckState; } + set + { + if (value != _CheckState) + SetChecked(value, eTreeAction.Code); + } + } + + /// + /// Sets the Checked or CheckState properties. + /// + /// New value for checked state. + /// Action source. + public void SetChecked(bool value, eTreeAction actionSource) + { + SetChecked(value ? CheckState.Checked : CheckState.Unchecked, actionSource); + } + + /// + /// Sets the Checked or CheckState properties. + /// + /// New value for checked state. + /// Action source. + public void SetChecked(CheckState value, eTreeAction actionSource) + { + AdvTreeCellBeforeCheckEventArgs beforeCheckArgs = new AdvTreeCellBeforeCheckEventArgs(actionSource, this, value); + InvokeBeforeCheck(beforeCheckArgs); + if (beforeCheckArgs.Cancel) return; + + _CheckState = value; + m_Checked = value == CheckState.Checked; + OnAppearanceChanged(); + + if (this.CheckBoxStyle == eCheckBoxStyle.RadioButton && value == CheckState.Checked && this.Parent != null) + { + Node parent = this.Parent; + AdvTree tree = parent.TreeControl; + if (tree != null) tree.BeginUpdate(); + bool processNodes = true; + foreach (Cell item in parent.Cells) + { + if (item == this) continue; + if (item.CheckBoxStyle == eCheckBoxStyle.RadioButton) + { + item.Checked = false; + processNodes = false; + } + } + if (processNodes) + { + if (parent.Parent != null) + { + foreach (Node item in parent.Parent.Nodes) + { + if (item != parent && item.CheckBoxStyle == eCheckBoxStyle.RadioButton) + item.Checked = false; + } + } + else + { + if (tree != null && NodeOperations.IsRootNode(tree, parent)) + { + foreach (Node item in tree.Nodes) + { + if (item != parent && item.CheckBoxStyle == eCheckBoxStyle.RadioButton) + item.Checked = false; + } + } + } + } + if (tree != null) tree.EndUpdate(); + } + + InvokeAfterCheck(actionSource); + } + + private eCheckBoxStyle _CheckBoxStyle = eCheckBoxStyle.CheckBox; + /// + /// Gets or sets the appearance style of the item. Default value is CheckBox. Item can also assume the style of radio-button. + /// + [Browsable(true), DefaultValue(eCheckBoxStyle.CheckBox), Category("Check-box Properties"), Description("Indicates appearance style of the item. Default value is CheckBox. Item can also assume the style of radio-button.")] + public eCheckBoxStyle CheckBoxStyle + { + get { return _CheckBoxStyle; } + set + { + _CheckBoxStyle = value; + OnAppearanceChanged(); + } + } + + /// + /// Gets whether mouse is over the cell. + /// + [Browsable(false)] + public bool IsMouseOver + { + get{return m_MouseOver;} + } + /// + /// Sets the mouse over flag. + /// + /// true if mouse is over the cell otherwise false. + internal void SetMouseOver(bool over) + { + m_MouseOver=over; + } + + /// + /// Gets whether left mouse button is pressed while over the cell. + /// + [Browsable(false)] + public bool IsMouseDown + { + get{return m_MouseDown;} + } + /// + /// Sets the mouse down flag. + /// + /// true if left mouse button is pressed while over the cell otherwise false. + internal void SetMouseDown(bool over) + { + m_MouseDown=over; + } + + /// + /// Gets or sets the layout of the cell parts like check box, image and text. Layout can be horizontal (default) + /// where parts of the cell are positioned next to each other horizontally, or vertical where + /// parts of the cell are positioned on top of each other vertically. + /// Alignment of the each part is controlled by alignment properties. + /// + /// ImageAlignment Property + /// CheckBoxAlignment Property + [Browsable(true),DefaultValue(eCellPartLayout.Default),Category("Cells"),Description("Indicates the layout of the cell parts like check box, image and text."), DevCoSerialize()] + public eCellPartLayout Layout + { + get {return m_Layout;} + set + { + if(m_Layout!=value) + { + m_Layout=value; + this.OnAppearanceChanged(); + } + } + } + + /// + /// Specifies the mouse cursor displayed when mouse is over the cell. + /// + [Browsable(true),DefaultValue(null),Category("Appearance"),Description("Specifies the mouse cursor displayed when mouse is over the cell.")] + public System.Windows.Forms.Cursor Cursor + { + get + { + return m_Cursor; + } + set + { + if(m_Cursor!=value) + { + m_Cursor=value; + } + } + } + + internal bool GetEnabled() + { + return m_Enabled; + } + + /// + /// Gets or sets whether cell wrapped the text during the layout. + /// + internal bool WordWrap + { + get {return m_WordWrap;} + set {m_WordWrap=value;} + } + + private eCellEditorType _EditorType = eCellEditorType.Default; + /// + /// Gets or sets the editor type used to edit the cell. Setting this property to value other than Default + /// overrides the cell editor type specified on column cell belongs to. + /// + [DefaultValue(eCellEditorType.Default), Category("Behavior"), Description("Indicates editor type used to edit the cell.")] + public eCellEditorType EditorType + { + get { return _EditorType; } + set { _EditorType = value; } + } + + /// + /// Returns effective editor type used for cell editing. + /// + /// Editor type. + internal eCellEditorType GetEffectiveEditorType() + { + if (_EditorType != eCellEditorType.Default) return _EditorType; + int index = -1; + if (this.Parent != null) index = this.Parent.Cells.IndexOf(this); + if (index == -1) return _EditorType; + + if (this.Parent != null && this.Parent.Parent != null && this.Parent.Parent.NodesColumns.Count > 0 && index < this.Parent.Parent.NodesColumns.Count) + { + return this.Parent.Parent.NodesColumns[index].EditorType; + } + + AdvTree tree=TreeControl; + if (tree != null && tree.Columns.Count > 0 && index < tree.Columns.Count) + return tree.Columns[index].EditorType; + + return _EditorType; + } + #endregion + + #region Methods + /// Makes a copy of a Cell. + public virtual Cell Copy() + { + // TODO: Make sure that new properties are copied + Cell c=new Cell(); + c.CheckBoxAlignment=this.CheckBoxAlignment; + c.CheckBoxVisible=this.CheckBoxVisible; + c.CheckBoxStyle = this.CheckBoxStyle; + if (this.CheckBoxThreeState) + c.CheckState = this.CheckState; + else + c.Checked=this.Checked; + c.Cursor=this.Cursor; + c.Enabled=this.Enabled; + c.ImageAlignment=this.ImageAlignment; + c.SetCellImages(this.Images.Copy()); + c.Layout=this.Layout; + c.StyleDisabled=this.StyleDisabled; + c.StyleMouseDown=this.StyleMouseDown; + c.StyleMouseOver=this.StyleMouseOver; + c.StyleNormal=this.StyleNormal; + c.StyleSelected=this.StyleSelected; + c.Tag=this.Tag; + c.Text=this.Text; + c.Editable = this.Editable; + c.EditorType = this.EditorType; + + + return c; + } + + /// + /// Ensures that the cell is visible, expanding nodes and scrolling the control as necessary. + /// + public void EnsureVisible() + { + NodeOperations.EnsureVisible(this); + } + + private void OnAppearanceChanged() + { + if(this.Parent!=null) + { + this.Parent.SizeChanged=true; + this.Parent.OnDisplayChanged(); + } + } + + private void OnSizeChanged() + { + if(this.Parent!=null) + { + this.Parent.SizeChanged=true; + this.Parent.OnDisplayChanged(); + } + } + + /// + /// Occurs when any image property for the cell has changed. + /// + internal void OnImageChanged() + { + if(m_Parent!=null) + m_Parent.OnImageChanged(); + } + + /// + /// Invokes AfterCheck event on AdvTree + /// control. + /// + protected virtual void InvokeAfterCheck(eTreeAction actionSource) + { + AdvTree tree=this.TreeControl; + if(tree!=null) + { + tree.InvokeAfterCheck(new AdvTreeCellEventArgs(actionSource, this)); + } + m_ActionSource=eTreeAction.Code; + } + + /// + /// Invokes BeforeCheck event on AdvTree + /// control. + /// + protected virtual void InvokeBeforeCheck(AdvTreeCellBeforeCheckEventArgs e) + { + AdvTree tree = this.TreeControl; + if (tree != null) + { + tree.InvokeBeforeCheck(e); + } + + if (this.Parent != null) + this.Parent.BeforeCellCheck(this, e); + } + + /// + /// Called just before cell layout is to be performed. + /// + internal void OnLayoutCell() + { + if (m_HostedControl != null && !_HostedControlAdded) + { + AddHostedControlToTree(); + } + else if (_HostedItem != null && !_HostedItemAdded) + AddHostedItemToTree(); + } + + private void SetHostedItem(BaseItem value) + { + // Note that hosted item when set is guided by the size of the text. So the TextContentBounds are actually bounds of the control. + if (m_HostedControl != null) + throw new InvalidOperationException("HostedItem cannot be set if HostedControl property is set to non-null value."); + + if (_HostedItem != null) + { + RemoveHostedItemFromTree(); + } + + _HostedItem = value; + if (_HostedItem != null) + { + if (_HostedItem.Parent != null) + _HostedItem.Parent.SubItems.Remove(_HostedItem); + _HostedItem.Visible = true; + _HostedItem.Style = eDotNetBarStyle.StyleManagerControlled; + AddHostedItemToTree(); + } + + OnSizeChanged(); + } + + private void RemoveHostedItemFromTree() + { + if (_HostedItem != null) + _HostedItem.ContainerControl = null; + _HostedItemAdded = false; + } + private bool _HostedItemAdded = false; + private void AddHostedItemToTree() + { + if (_HostedItemAdded) return; + AdvTree tree = this.TreeControl; + if (tree != null) + { + if (_HostedItem.ContainerControl != tree) + { + _HostedItem.ContainerControl = tree; + } + _HostedItemAdded = true; + } + } + + private bool _HostedControlAdded = false; + internal void AddHostedControlToTree() + { + if (_HostedControlAdded) return; + AdvTree tree = this.TreeControl; + if(tree!=null) + { + if (m_HostedControl.Parent != tree) + { + if (m_HostedControl.Parent != null) + m_HostedControl.Parent.Controls.Remove(m_HostedControl); + tree.Controls.Add(m_HostedControl); + tree.InvalidControlBorder = true; + m_HostedControl.SendToBack(); + } + tree.HostedControlCells.Add(this); + _HostedControlAdded = true; + } + } + + internal void RemoveHostedControlFromTree() + { + AdvTree tree = m_HostedControl.Parent as AdvTree; + if (tree == null) tree = this.TreeControl; + if (tree != null) + { + tree.Controls.Remove(m_HostedControl); + tree.HostedControlCells.Remove(this); + _HostedControlAdded = false; + } + } + + private void SetHostedControl(Control value) + { + // Note that hosted control when set is guided by the size of the text. So the TextContentBounds are actually bounds of the control. + if(value==this.TreeControl) + return; + + if (_HostedItem != null) + throw new InvalidOperationException("HostedControl cannot be set when HostedItem is set to non-null value."); + + if(m_HostedControl!=null) + { + m_HostedControl.SizeChanged-=new EventHandler(this.HostedControlSizedChanged); + m_HostedControl.Enter -= new EventHandler(HostedControlEnter); + RemoveHostedControlFromTree(); + } + + m_HostedControl=value; + if(m_HostedControl!=null) + { + m_HostedControl.SizeChanged+=new EventHandler(this.HostedControlSizedChanged); + m_HostedControl.Enter += new EventHandler(HostedControlEnter); + TypeDescriptor.GetProperties(m_HostedControl)["Dock"].SetValue(m_HostedControl,DockStyle.None); + if(m_HostedControl.Parent!=null) + m_HostedControl.Parent.Controls.Remove(m_HostedControl); + + if(!this.DesignMode) + m_HostedControl.Visible = false; + if(this.DesignMode || this.Parent!=null && this.Parent.Site!=null && this.Parent.Site.DesignMode) + { + bool visible=GetVisible(); + TypeDescriptor.GetProperties(m_HostedControl)["Visible"].SetValue(m_HostedControl,visible); + } + + AddHostedControlToTree(); + } + + OnSizeChanged(); + } + + private void HostedControlEnter(object sender, EventArgs e) + { + AdvTree tree = this.TreeControl; + if (tree != null) + tree.SelectedNode = this.Parent; + } + private void HostedControlSizedChanged(object sender, EventArgs e) + { + if(!m_HostedControlSize.IsEmpty && m_HostedControl!=null) + m_HostedControlSize = m_HostedControl.Size; + if (m_IgnoreHostedControlSizeChange) + return; + + OnSizeChanged(); + } + + internal void OnVisibleChanged() + { + if(m_HostedControl!=null) + { + TypeDescriptor.GetProperties(m_HostedControl)["Visible"].SetValue(m_HostedControl,GetVisible()); + } + } + + private bool GetVisible() + { + if(m_Parent!=null && !NodeOperations.GetIsNodeVisible(m_Parent)) + return false; + return m_Visible; + } + + internal void OnParentExpandedChanged(bool expanded) + { + if(m_HostedControl!=null && m_HostedControl.Visible != expanded) + { + bool visible=GetVisible(); + m_HostedControl.Visible = visible; + if(this.DesignMode || this.Parent!=null && this.Parent.Site!=null && this.Parent.Site.DesignMode) + TypeDescriptor.GetProperties(m_HostedControl)["Visible"].SetValue(m_HostedControl,visible); + } + } + + private bool _Selectable = true; + /// + /// Gets or sets whether cell can be selected by user by clicking it with the mouse or using keyboard. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether cell can be selected by user by clicking it with the mouse or using keyboard.")] + public bool Selectable + { + get { return _Selectable; } + set + { + _Selectable = value; + } + } + + /// + /// Gets whether cell can be selected. Cell must be Visible, Enabled and Selectable in order for it to be selected. + /// + [Browsable(false)] + public bool CanSelect + { + get + { + return this.Enabled & this.IsVisible & this.Selectable; + } + } + + /// + /// Returns ColumnHeader cell is under if one is defined and cell is already parented to the tree. Otherwise it returns null/nothing. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ColumnHeader ColumnHeader + { + get + { + AdvTree tree = this.TreeControl; + if (this.Parent == null || tree == null) return null; + int index = this.Parent.Cells.IndexOf(this); + if (this.Parent.HasColumns && this.Parent.NodesColumns.Count > index) + return this.Parent.NodesColumns[index]; + if (tree.Columns.Count > index) + return tree.Columns[index]; + return null; + } + } + #endregion + + #region Markup Implementation + private DevComponents.DotNetBar.TextMarkup.BodyElement m_TextMarkup = null; + + private void MarkupTextChanged() + { + if (!IsMarkupSupported) + return; + + if(m_TextMarkup!=null) + m_TextMarkup.HyperLinkClick -= new EventHandler(this.TextMarkupLinkClick); + + m_TextMarkup = null; + + if (!DevComponents.DotNetBar.TextMarkup.MarkupParser.IsMarkup(ref m_Text)) + return; + + m_TextMarkup = DevComponents.DotNetBar.TextMarkup.MarkupParser.Parse(m_Text); + + if (m_TextMarkup != null) + m_TextMarkup.HyperLinkClick += new EventHandler(TextMarkupLinkClick); + } + + /// + /// Occurs when text markup link is clicked. + /// + protected virtual void TextMarkupLinkClick(object sender, EventArgs e) + { + DevComponents.DotNetBar.TextMarkup.HyperLink link = sender as DevComponents.DotNetBar.TextMarkup.HyperLink; + + if(link!=null && this.Parent!=null) + this.Parent.InvokeMarkupLinkClick(this, new MarkupLinkClickEventArgs(link.Name, link.HRef)); + } + + /// + /// Gets reference to parsed markup body element if text was markup otherwise returns null. + /// + internal DevComponents.DotNetBar.TextMarkup.BodyElement TextMarkupBody + { + get { return m_TextMarkup; } + } + + private bool _TextMarkupEnabled = true; + /// + /// Gets or sets whether cell supports and renders text markup. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Gets or sets whether cell supports and renders text markup.")] + public bool TextMarkupEnabled + { + get { return _TextMarkupEnabled; } + set + { + _TextMarkupEnabled = value; + } + } + + /// + /// Gets whether item supports text markup. Default is false. + /// + protected virtual bool IsMarkupSupported + { + get { return _TextMarkupEnabled; } + } + + private bool _HostedItemMouseEntered = false; + protected internal virtual void InvokeNodeMouseMove(object sender, MouseEventArgs e) + { + if(m_TextMarkup!=null) + m_TextMarkup.MouseMove(sender as Control, e); + + if (_HostedItem != null) + { + if (_HostedItem.DisplayRectangle.Contains(e.X, e.Y)) + { + if (!_HostedItemMouseEntered) + { + _HostedItem.InternalMouseEnter(); + _HostedItemMouseEntered = true; + } + _HostedItem.InternalMouseMove(e); + } + else if(_HostedItemMouseEntered) + { + _HostedItem.InternalMouseLeave(); + _HostedItemMouseEntered = false; + } + } + + if (!IsMouseOver) HideToolTip(); + } + + private bool _HostedItemMouseDown = false; + protected internal virtual void InvokeNodeMouseDown(object sender, MouseEventArgs e) + { + HideToolTip(); + + if(m_TextMarkup!=null) + m_TextMarkup.MouseDown(sender as Control, e); + + if (_HostedItem != null && _HostedItem.DisplayRectangle.Contains(e.X, e.Y)) + { + _HostedItem.InternalMouseDown(e); + _HostedItemMouseDown = true; + } + } + + protected internal virtual void InvokeNodeMouseUp(object sender, MouseEventArgs e) + { + if(m_TextMarkup!=null) + m_TextMarkup.MouseUp(sender as Control, e); + + if (_HostedItem != null && _HostedItemMouseDown) + { + _HostedItem.InternalMouseUp(e); + _HostedItemMouseDown = false; + } + } + + protected internal virtual void InvokeNodeMouseLeave(object sender, EventArgs e) + { + HideToolTip(); + + if(m_TextMarkup!=null) + m_TextMarkup.MouseLeave(sender as Control); + if (_HostedItem != null) + { + if (_HostedItemMouseEntered) + { + _HostedItem.InternalMouseLeave(); + _HostedItemMouseEntered = false; + } + } + } + + protected internal virtual void InvokeNodeClick(object sender, EventArgs e) + { + if(m_TextMarkup!=null) + m_TextMarkup.Click(sender as Control); + if (_HostedItem != null && e is TreeNodeMouseEventArgs) + { + TreeNodeMouseEventArgs me = (TreeNodeMouseEventArgs)e; + if (this.Bounds.Contains(me.X, me.Y)) + _HostedItem.InternalClick(me.Button, new Point(me.X, me.Y)); + } + } + + protected internal virtual void InvokeNodeMouseHover(object sender, EventArgs e) + { + if (_HostedItem != null) + _HostedItem.InternalMouseHover(); + if (System.Windows.Forms.Control.MouseButtons == System.Windows.Forms.MouseButtons.None) + this.ShowToolTip(); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Cell.resx b/PROMS/DotNetBar Source Code/AdvTree/Cell.resx new file mode 100644 index 00000000..3f337e08 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Cell.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/PROMS/DotNetBar Source Code/AdvTree/CellCollection.cs b/PROMS/DotNetBar Source Code/AdvTree/CellCollection.cs new file mode 100644 index 00000000..85c4fd56 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/CellCollection.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections; +using System.ComponentModel; + +namespace DevComponents.AdvTree +{ + /// + /// A strongly-typed collection of objects. + /// + public class CellCollection:CollectionBase + { + #region Private Variables + private Node m_ParentNode=null; + #endregion + + #region Internal Implementation + /// Creates new instance of the class. + public CellCollection() + { + } + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(Cell cell) + { + return List.Add(cell); + } + /// + /// Returns reference to the object in collection based on it's index. + /// + public Cell this[int index] + { + get {return (Cell)(List[index]);} + set {List[index] = value;} + } + /// + /// Returns reference to the object in collection based on it's name. Returns null/nothing if cell with given name is not found. + /// + public Cell this[string name] + { + get + { + foreach (Cell item in List) + { + if (item.Name == name) return item; + } + return null; + } + } + + /// + /// Gets the cell based on the column name. Node must be able to reach AdvTree control for this method to work. + /// + /// Column name. + /// Cell object or null. + public Cell GetByColumnName(string columnName) + { + if (string.IsNullOrEmpty(columnName)) + throw new ArgumentException("columnName argument must be non-empty non-null string with column name"); + Node parentNode = this.ParentNode; + AdvTree tree = parentNode.TreeControl; + if (tree == null) + throw new NullReferenceException("AdvTree control cannot be reached. Node is not added to a tree."); + Cell cell = null; + if (parentNode.Parent != null && parentNode.Parent.NodesColumns.Count > 0) + { + int index= parentNode.Parent.NodesColumns.IndexOf(columnName); + if (index >= 0) cell = this[index]; + } + else + { + int index = tree.Columns.IndexOf(columnName); + if (index >= 0) cell = this[index]; + } + return cell; + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, Cell value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(Cell value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(Cell value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + 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); + } + protected override void OnInsert(int index, object value) + { + if (m_ParentNode != null && m_ParentNode.Site != null && m_ParentNode.Site.DesignMode && this.List.Count > 0) + { + Cell cell = value as Cell; + if (cell.Site == null && this.List.Contains(cell)) this.List.Remove(cell); + } + + base.OnInsert(index, value); + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(Cell[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the Cell array. + /// + /// Array to copy to. + internal void CopyTo(Cell[] array) + { + List.CopyTo(array,0); + } + + private Cell _RootCell = null; + protected override void OnClear() + { + if (m_ParentNode != null && m_ParentNode.Site != null && m_ParentNode.Site.DesignMode && this.List.Count>0) + { + if (this[0].Site == null) + _RootCell = this[0]; + } + base.OnClear(); + } + + protected override void OnClearComplete() + { + base.OnClearComplete(); + if (_RootCell != null) + { + this.Add(_RootCell); + _RootCell = null; + } + } + + protected override void OnSet(int index, object oldValue, object newValue) + { + base.OnSet(index, oldValue, newValue); + } + + /// + /// Gets or sets the node this collection is associated with. + /// + [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Node ParentNode + { + get {return m_ParentNode;} + } + /// + /// Sets the node collection belongs to. + /// + /// Cell that is parent of this collection. + internal void SetParentNode(Node parent) + { + m_ParentNode=parent; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/CellEditEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/CellEditEventArgs.cs new file mode 100644 index 00000000..891b6bc4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/CellEditEventArgs.cs @@ -0,0 +1,105 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Represents event arguments for cell editing events. + /// + public class CellEditEventArgs : EventArgs + { + /// + /// Indicates the action that caused the event. + /// + public eTreeAction Action=eTreeAction.Code; + /// + /// Indicates the cell that is affected. + /// + public DevComponents.AdvTree.Cell Cell=null; + /// + /// Indicates new text that will be assigned to the cell if one is appropriate for given event. + /// + public string NewText=""; + + private ICellEditControl _Editor = null; + /// + /// Gets reference to the cell editor control. + /// + public ICellEditControl Editor + { + get + { + return _Editor; + } + } + + /// + /// 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. + /// + public bool Cancel=false; + + /// + /// Indicates whether editing operation was canceled by the end user, usually by pressing ESCAPE key. + /// + public readonly bool IsUserCanceled; + + /// + /// Initializes new instance of CellEditEventArgs class. + /// + /// Reference to Cell this event is raised for. + /// Indicates the action that caused the event. + /// Indicates new text of the cell if it applies to given event. + public CellEditEventArgs(Cell cell, eTreeAction action, string newText) + { + this.Action=action; + this.Cell=cell; + this.NewText=newText; + this.IsUserCanceled = false; + } + /// + /// Initializes new instance of CellEditEventArgs class. + /// + /// Reference to Cell this event is raised for. + /// Indicates the action that caused the event. + /// Indicates new text of the cell if it applies to given event. + public CellEditEventArgs(Cell cell, eTreeAction action, string newText, ICellEditControl editor) + { + this.Action = action; + this.Cell = cell; + this.NewText = newText; + this.IsUserCanceled = false; + _Editor = editor; + } + /// + /// Initializes new instance of CellEditEventArgs class. + /// + /// Reference to Cell this event is raised for. + /// Indicates the action that caused the event. + /// Indicates new text of the cell if it applies to given event. + /// Indicates whether action is canceled by the end user. + public CellEditEventArgs(Cell cell, eTreeAction action, string newText, bool isUserCanceled) + { + this.Action = action; + this.Cell = cell; + this.NewText = newText; + this.IsUserCanceled = isUserCanceled; + } + /// + /// Initializes new instance of CellEditEventArgs class. + /// + /// Reference to Cell this event is raised for. + /// Indicates the action that caused the event. + /// Indicates new text of the cell if it applies to given event. + /// Indicates whether action is canceled by the end user. + public CellEditEventArgs(Cell cell, eTreeAction action, string newText, bool isUserCanceled, ICellEditControl editor) + { + this.Action = action; + this.Cell = cell; + this.NewText = newText; + this.IsUserCanceled = isUserCanceled; + _Editor = editor; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/CellImages.cs b/PROMS/DotNetBar Source Code/AdvTree/CellImages.cs new file mode 100644 index 00000000..ab7910ea --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/CellImages.cs @@ -0,0 +1,570 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree +{ + /// + /// Represents class that holds images for a cell. + /// + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + [ToolboxItem(false), TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))] + public class CellImages + { + // Image variables + private System.Drawing.Image m_Image=null; + private System.Drawing.Image m_DisabledImageGenerated = 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; + + /// + /// Initializes new instance of CellImages class. + /// + /// Reference to parent cell. + public CellImages(Cell parentCell) + { + m_ParentCell=parentCell; + } + + #region Properties + + internal System.Drawing.Image DisabledImageGenerated + { + get { return m_DisabledImageGenerated; } + set + { + m_DisabledImageGenerated = value; + } + } + + /// + /// Gets or sets default cell image. Setting this property to valid image will + /// override any setting of ImageIndex property. + /// + /// + /// The image set through this property will be serialized with the cell. If you + /// plan to use ImageList then use ImageIndex + /// property. + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format + /// which supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 + /// do not support alpha-blending when used through Image class. + /// + /// + /// Image object or null (Nothing) if no image is assigned. + [Browsable(true),DefaultValue(null),Category("Images"),Description("Indicates default cell image"), DevCoSerialize()] + public System.Drawing.Image Image + { + get {return m_Image;} + set + { + ChangeImage(ref m_Image, value); + } + } + + /// + /// Resets Image property to it's default value (null, VB nothing). + /// + public void ResetImage() + { + TypeDescriptor.GetProperties(this)["Image"].SetValue(this, null); + } + + /// + /// 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. + /// + /// + /// 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. + /// + [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 + { + ChangeImage(ref m_ImageMouseOver, value); + } + } + + /// + /// Resets ImageMouseOver to it's default value (null, VB nothing). + /// + public void ResetImageMouseOver() + { + TypeDescriptor.GetProperties(this)["ImageMouseOver"].SetValue(this, null); + } + + /// + /// 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. + /// + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + [Browsable(true), DefaultValue(null), Category("Images"), Description("Indicates disabled cell image")] + public System.Drawing.Image ImageDisabled + { + get { return m_ImageDisabled; } + set + { + ChangeImage(ref m_ImageDisabled, value); + } + } + + /// + /// Resets ImageDisabled to it's default value (null, VB nothing). + /// + public void ResetImageDisabled() + { + this.ImageDisabled = null; + } + + /// + /// 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. + /// + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + [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 + { + ChangeImage(ref m_ImageExpanded, value); + } + } + + /// + /// Resets ImageExpanded to it's default value (null, VB nothing). + /// + public void ResetImageExpanded() + { + TypeDescriptor.GetProperties(this)["ImageExpanded"].SetValue(this, null); + } + + /// + /// Gets or sets the Index of default cell image from ImageList specified on AdvTree + /// control. + /// + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + [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(); + } + } + + private string _ImageKey = ""; + /// + /// Gets or sets the key of the default cell image from ImageList specified on AdvTree control. + /// + [DefaultValue(""), Category("ImageList Images"), Description("Indicates the default cell image key"), DevCoSerialize()] + public string ImageKey + { + get { return _ImageKey; } + set + { + _ImageKey = value; + this.OnImageChanged(); + } + } + + + /// + /// Property Editor support for ImageIndex selection + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public System.Windows.Forms.ImageList ImageList + { + get + { + if(this.Parent!=null) + { + AdvTree tree=this.Parent.TreeControl; + if(tree!=null) + { + return tree.ImageList; + } + } + + return null; + } + } + + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + /// + /// Gets or sets the Index of cell image when mouse is over the cell from ImageList + /// specified on AdvTree control. + /// + [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(); + } + } + + private string _ImageMouseOverKey = ""; + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + /// + /// Gets or sets the key of cell image when mouse is over the cell from ImageList + /// specified on AdvTree control. + /// + [Browsable(true), DefaultValue(""), Category("ImageList Images"), Description("Indicates cell image when mouse is over the cell"), DevCoSerialize()] + public string ImageMouseOverKey + { + get { return _ImageMouseOverKey; } + set + { + _ImageMouseOverKey = value; + this.OnImageChanged(); + } + } + + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + /// + /// Gets or sets the Index of disabled cell image from ImageList specified on AdvTree + /// control. + /// + [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(); + } + } + + private string _ImageDisabledKey = ""; + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + /// + /// Gets or sets the key of disabled cell image from ImageList specified on AdvTree + /// control. + /// + [Browsable(true), DefaultValue(""), Category("ImageList Images"), Description("Indicates disabled cell image")] + public string ImageDisabledKey + { + get { return _ImageDisabledKey; } + set + { + _ImageDisabledKey = value; + this.OnImageChanged(); + } + } + + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + /// + /// Gets or sets the Index of cell image from ImageList specified on AdvTree control + /// that is used when Node associated with this cell is expanded + /// + [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(); + } + } + + private string _ImageExpandedKey = ""; + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format which + /// supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 do not support + /// alpha-blending when used through Image class. + /// + /// + /// Gets or sets the key of cell image from ImageList specified on AdvTree control + /// that is used when Node associated with this cell is expanded + /// + [Browsable(true), DefaultValue(""), Category("ImageList Images"), Description("Indicates expanded cell image"), DevCoSerialize()] + public string ImageExpandedKey + { + get { return _ImageExpandedKey; } + set + { + _ImageExpandedKey = value; + this.OnImageChanged(); + } + } + + /// + /// Gets or sets the parent node of the cell. + /// + [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Cell Parent + { + get {return m_ParentCell;} + set {m_ParentCell=value;} + } + + /// + /// Gets whether CellImages object should be serialized or not. If object has all + /// default values then this property will return false. + /// + 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; + } + } + + /// + /// Returns largest image size in this set of images. + /// + internal Size LargestImageSize + { + get + { + return m_LargestImageSize; + } + } + + #endregion + + #region Methods + + /// Makes a copy of a CellImages object. + 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 == null ? null : (Image) this.ImageExpanded.Clone(); + ci.ImageExpandedIndex=this.ImageExpandedIndex; + ci.ImageIndex=this.ImageIndex; + ci.ImageMouseOver=this.ImageMouseOver == null? null : (Image)this.ImageMouseOver.Clone(); + ci.ImageMouseOverIndex=this.ImageMouseOverIndex; + ci.ImageDisabledKey = this.ImageDisabledKey; + ci.ImageExpandedKey = this.ImageExpandedKey; + ci.ImageKey = this.ImageKey; + ci.ImageMouseOverKey = this.ImageMouseOverKey; + return ci; + } + + #endregion + + #region Internals + /// + /// Changes the image and invokes largest image size calculation if the + /// image size truly changed. + /// + /// + /// + private void ChangeImage(ref System.Drawing.Image currentImage, System.Drawing.Image newImage) + { + // Early out if no real change + if (currentImage == newImage) + return; + + // Hold onto previous image + System.Drawing.Image previousImage = currentImage; + + // Assign new image + currentImage = newImage; + + // If either current or previous is null, or the sizes don't match, + // we need to resize ourselves and the parent. + if (previousImage == null || currentImage == null || GetImageSize(previousImage) != GetImageSize(currentImage)) + { + RefreshLargestImageSize(); + + if (this.Parent != null) + this.Parent.OnImageChanged(); + } + + // Dispose the generated disabled image, if applicable. + DisposeGeneratedDisabledImage(); + } + private Size GetImageSize(Image image) + { + try + { + return image.Size; + } + catch + { + return Size.Empty; + } + } + + private void OnImageChanged() + { + RefreshLargestImageSize(); + if (this.Parent != null) + this.Parent.OnImageChanged(); + DisposeGeneratedDisabledImage(); + } + + public void Dispose() + { + DisposeGeneratedDisabledImage(); + if (BarUtilities.DisposeItemImages || _AutoDispose) + { + BarUtilities.DisposeImage(ref m_Image); + BarUtilities.DisposeImage(ref m_ImageDisabled); + BarUtilities.DisposeImage(ref m_ImageExpanded); + BarUtilities.DisposeImage(ref m_ImageMouseOver); + } + } + + internal void DisposeGeneratedDisabledImage() + { + if (m_DisabledImageGenerated != null) + { + m_DisabledImageGenerated.Dispose(); + m_DisabledImageGenerated = null; + } + } + + internal 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); + + AdjustSize(GetImageByKey(_ImageKey), ref m_LargestImageSize); + AdjustSize(GetImageByKey(_ImageDisabledKey), ref m_LargestImageSize); + AdjustSize(GetImageByKey(_ImageExpandedKey), ref m_LargestImageSize); + AdjustSize(GetImageByKey(_ImageMouseOverKey), ref m_LargestImageSize); + } + 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; + } + } + /// + /// Returns image from image list based on the image index. + /// + /// Index of the image to return. + /// Image object from image list. + internal System.Drawing.Image GetImageByIndex(int imageIndex) + { + if (imageIndex >= 0 && this.Parent != null && this.Parent.TreeControl != null && this.Parent.TreeControl.ImageList != null && this.Parent.TreeControl.ImageList.Images.Count > 0) + { + try + { + return this.Parent.TreeControl.ImageList.Images[imageIndex]; + } + catch + { + return null; + } + + } + else + return null; + } + + /// + /// Returns image from image list based on the image key. + /// + /// Key of the image to return. + /// Image object from image list. + internal System.Drawing.Image GetImageByKey(string key) + { + if (string.IsNullOrEmpty(key)) return null; + + Cell parent = this.Parent; + if (parent == null) return null; + + AdvTree tree = parent.TreeControl; + if (tree == null || tree.ImageList == null || !tree.ImageList.Images.ContainsKey(key)) return null; + + return tree.ImageList.Images[key]; + } + + private bool _AutoDispose = false; + /// + /// Indicates whether assigned images are automatically disposed when the cell and node are disposed. Default value is false. + /// + [Browsable(false), DefaultValue(false)] + public bool AutoDispose + { + get { return _AutoDispose; } + set + { + _AutoDispose = value; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/ColumnHeader.cs b/PROMS/DotNetBar Source Code/AdvTree/ColumnHeader.cs new file mode 100644 index 00000000..980bf138 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/ColumnHeader.cs @@ -0,0 +1,1183 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar; +using System.Collections; + +namespace DevComponents.AdvTree +{ + /// Represents the node or tree ColumnHeader. + [ToolboxItem(false), Designer("DevComponents.AdvTree.Design.ColumnHeaderDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ColumnHeader : Component + { + #region Private Variables + private string m_Text = ""; + private ColumnWidth m_Width = null; + private bool m_Sortable = true; + private eStyleTextAlignment m_TextAlign = eStyleTextAlignment.Near; + 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 = ""; + /// + /// Occurs when header size has changed due to the user resizing the column. + /// + public event EventHandler HeaderSizeChanged; + internal event SortCellsEventHandler SortCells; + #endregion + + #region Events + /// + /// Occurs when mouse button is pressed over the column header. + /// + public event MouseEventHandler MouseDown; + /// + /// Occurs when mouse button is released over the column header. + /// + public event MouseEventHandler MouseUp; + /// + /// Occurs when header is double clicked. + /// + public event EventHandler DoubleClick; + /// + /// Occurs when header is clicked. + /// + public event EventHandler Click; + #endregion + + #region Constructor + /// + /// Creates new instance of the object. + /// + public ColumnHeader() + : this("") + { + + } + + /// + /// Creates new instance of the object and initializes it with text. + /// + /// Text to initialize object with. + public ColumnHeader(string text) + { + m_Text = text; + m_Width = new ColumnWidth(); + m_Width.WidthChanged += new EventHandler(this.WidthChanged); + } + + protected override void Dispose(bool disposing) + { + if (BarUtilities.DisposeItemImages) + { + BarUtilities.DisposeImage(ref _Image); + } + base.Dispose(disposing); + } + #endregion + + #region Methods + /// + /// Makes a copy of ColumnHeader object. + /// + /// Returns new instance of column header object. + 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; + c.Width.AutoSize = this.Width.AutoSize; + c.Width.AutoSizeMinHeader = this.Width.AutoSizeMinHeader; + c.DisplayIndex = this.DisplayIndex; + c.SortDirection = this.SortDirection; + c.SortingEnabled = this.SortingEnabled; + c.StretchToFill = this.StretchToFill; + c.Tag = this.Tag; + c.DataFieldName = this.DataFieldName; + c.DoubleClickAutoSize = this.DoubleClickAutoSize; + c.Editable = this.Editable; + c.EditorType = this.EditorType; + c.Image = this.Image; + c.ImageAlignment = this.ImageAlignment; + c.MaxInputLength = this.MaxInputLength; + c.MinimumWidth = this.MinimumWidth; + c.SortComparer = this.SortComparer; + c.SortComparerReverse = this.SortComparerReverse; + + return c; + } + #endregion + + #region Properties + private ColumnHeaderCollection _Parent; + internal ColumnHeaderCollection Parent + { + get { return _Parent; } + set { _Parent = value; } + } + + private bool _Editable = true; + /// + /// Gets or sets whether cells content in this column is editable when cell editing is enabled on tree control. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether cells content in this column is editable when cell editing is enabled on tree control.")] + public bool Editable + { + get { return _Editable; } + set + { + _Editable = value; + } + } + + private int _MaxInputLength = 0; + /// + /// Gets or sets the maximum number of characters the user can type or paste when editing cells in this column. + /// + [DefaultValue(0), Category("Behavior"), Description("Indicates maximum number of characters the user can type or paste when editing cells in this column.")] + public int MaxInputLength + { + get { return _MaxInputLength; } + set + { + _MaxInputLength = value; + } + } + + /// + /// Returns name of the column header that can be used to identify it from the code. + /// + [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; + } + } + /// + /// Returns rectangle that this column occupies. If the layout has not been performed on the column the return value will be Rectangle.Empty. + /// + [Browsable(false)] + public Rectangle Bounds + { + get { return m_Bounds; } + } + /// + /// Sets the column bounds. + /// + internal void SetBounds(Rectangle bounds) + { + m_Bounds = bounds; + } + + /// + /// Gets the reference to the object that represents width of the column as either + /// absolute or relative value. + /// + /// + /// Set Width using Absolute or Relative properties of ColumnWidth object. + /// + /// Absolute Property (DevComponents.AdvTree.ColumnWidth) + /// Relative Property (DevComponents.AdvTree.ColumnWidth) + [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; } + } + + private int _MinimumWidth = 0; + /// + /// Gets or sets the minimum column width in pixels that is enforced when user is resizing the columns using mouse. + /// Default value is 0 which indicates that there is no minimum size constraint. + /// + [DefaultValue(0), Category("Layout"), Description("Indicates minimum column width in pixels that is enforced when user is resizing the columns using mouse")] + public int MinimumWidth + { + get { return _MinimumWidth; } + set + { + if (value < 0) value = 0; + _MinimumWidth = value; + } + } + + private bool _StretchToFill = false; + /// + /// Gets or sets whether column is stretched to fill any empty space horizontally in tree when all columns consume less width than available. + /// Only one column in tree may have this property set to true and only last column with this property set will be stretched. + /// You should always set the Width for the column since Width will be used when columns consume more space in tree horizontally than available. + /// Applies to top-level columns only. + /// + [DefaultValue(false), Category("Layout"), Description("Indicates whether column is stretched to fill any empty space horizontally in tree when all columns consume less width than available. Only one column in tree may have this property set to true and only last column with this property set will be stretched. You should always set the Width for the column since Width will be used when columns consume more space in tree horizontally than available. Applies to top-level columns only.")] + public bool StretchToFill + { + get { return _StretchToFill; } + set + { + if (_StretchToFill != value) + { + _StretchToFill = value; + OnSizeChanged(); + } + } + } + + + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// When property is set to an empty string the style setting from parent tree + /// controls is used. ColumnStyleNormal on AdvTree control is a root style for a cell. + /// + /// StyleMouseDown Property + /// StyleMouseOver Property + [Browsable(true), DefaultValue(""), Category("Style"), Description("Indicates the style class assigned to the column.")] + public string StyleNormal + { + get { return m_StyleNormal; } + set + { + if (value == null) value = ""; + m_StyleNormal = value; + this.OnSizeChanged(); + } + } + + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// When property is set to an empty string the style setting from parent tree + /// controls is used. ColumnStyleMouseDown on AdvTree control is a root style for a + /// cell. + /// + /// StyleNormal Property + /// StyleMouseOver Property + [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 + { + if (value == null) value = ""; + m_StyleMouseDown = value; + this.OnSizeChanged(); + } + } + + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// When property is set to an empty string the style setting from parent tree + /// controls is used. ColumnStyleMouseOver on AdvTree control is a root style for a + /// cell. + /// + /// StyleNormal Property + /// StyleMouseDown Property + [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 + { + if (value == null) value = ""; + m_StyleMouseOver = value; + this.OnSizeChanged(); + } + } + + /// + /// Gets or sets the name of the column in the ColumnHeaderCollection. + /// + [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; + } + } + + /// + /// Gets or sets the column caption. + /// + [Browsable(true), DefaultValue(""), Category("Appearance"), Description("Indicates column caption."), Localizable(true)] + public string Text + { + get { return m_Text; } + set + { + m_Text = value; + } + } + + /// + /// Gets or sets whether column is visible. Hiding the header column will also hide corresponding data column. + /// + [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; + OnSizeChanged(); + } + } + } + + private Image _Image = null; + /// + /// Gets or sets column image. + /// + /// + /// The image set through this property will be serialized with the column. + /// + /// If you plan to use alpha-blended images we recommend using PNG-24 format + /// which supports alpha-blending. As of this writing .NET Framework 1.0 and 1.1 + /// do not support alpha-blending when used through Image class. + /// + /// + /// Image object or null (Nothing) if no image is assigned. + [Browsable(true), DefaultValue(null), Category("Images"), Description("Indicates column image"), DevCoSerialize()] + public System.Drawing.Image Image + { + get { return _Image; } + set + { + _Image = value; + this.OnImageChanged(); + } + } + + private void OnImageChanged() + { + OnSizeChanged(); + } + /// + /// Resets Image property to it's default value (null, VB nothing). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetImage() + { + TypeDescriptor.GetProperties(this)["Image"].SetValue(this, null); + } + + private eColumnImageAlignment _ImageAlignment = eColumnImageAlignment.Left; + /// + /// Gets or sets Image alignment inside of column. Default value is Left. + /// + [DefaultValue(eColumnImageAlignment.Left), Category("Images"), Description("Indicates image alignment."), DevCoSerialize()] + public eColumnImageAlignment ImageAlignment + { + get { return _ImageAlignment; } + set { _ImageAlignment = value; OnSizeChanged(); } + } + + private string _DataFieldName = ""; + /// + /// Gets or sets the data-field or property name that is used as source of data for this column when data-binding is used. + /// + [DefaultValue(""), Category("Data"), Description("Indicates data-field or property name that is used as source of data for this column when data-binding is used.")] + public string DataFieldName + { + get { return _DataFieldName; } + set + { + if (value == null) value = ""; + if (_DataFieldName != value) + { + _DataFieldName = value; + OnDataFieldNameChanged(); + } + } + } + + /// + /// Called when DataFieldName property has changed. + /// + protected virtual void OnDataFieldNameChanged() + { + + } + + private object _Tag = null; + /// + /// Gets or sets additional custom data associated with the column. + /// + [Browsable(false), DefaultValue(null)] + public object Tag + { + get { return _Tag; } + set { _Tag = value; } + } + + private Color _CellsBackColor = Color.Empty; + /// + /// Gets or sets the color of the cells background for this column. + /// + [Category("Columns"), Description("Indicates color of cells background for this column.")] + public Color CellsBackColor + { + get { return _CellsBackColor; } + set + { + if (_CellsBackColor != value) + { + _CellsBackColor = value; + if (_Parent != null && _Parent.Parent != null) + _Parent.Parent.Invalidate(); + } + } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCellsBackColor() + { + return !_CellsBackColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetCellsBackColor() + { + this.CellsBackColor = Color.Empty; + } + + private int _DisplayIndex = -1; + /// + /// Gets or sets display index of the column. -1 indicates default value and is modified to actual display index when the column is added to a ColumnHeaderCollection. + /// + /// + /// A lower display index means a column will appear first (to the left) of columns with a higher display index. + /// Allowable values are from 0 to num columns - 1. (-1 is legal only as the default value and is modified to something else + /// when the column is added to a AdvTree's column collection). AdvTree enforces that no two columns have the same display index; + /// changing the display index of a column will cause the index of other columns to adjust as well. + /// + [DefaultValue(-1), Category("Appearance"), Description("Indicates display index of the column. -1 indicates default value and is modified to actual display index when the column is added to a ColumnHeaderCollection.")] + public int DisplayIndex + { + get { return _DisplayIndex; } + set + { + if (value != _DisplayIndex) + { + int oldValue = _DisplayIndex; + _DisplayIndex = value; + OnDisplayIndexChanged(oldValue, value); + } + } + } + + private void OnDisplayIndexChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("DisplayIndex")); + if (_Parent != null) _Parent.DisplayIndexChanged(this, newValue, oldValue); + } + + private bool _SortingEnabled = true; + /// + /// Gets or sets whether user can sort by this column by clicking it. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether user can sort by this column by clicking it.")] + public bool SortingEnabled + { + get { return _SortingEnabled; } + set + { + if (value != _SortingEnabled) + { + bool oldValue = _SortingEnabled; + _SortingEnabled = value; + OnSortingEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when SortingEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSortingEnabledChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SortingEnabled")); + } + + private eSortDirection _SortDirection = eSortDirection.None; + /// + /// Gets or sets the sort direction. Sort direction can be changed by clicking the column header if SortingEnabled=true. + /// + [DefaultValue(eSortDirection.None), Category("Behavior"), Description("Indicates sort direction. Sort direction can be changed by clicking the column header if SortingEnabled=true.")] + public eSortDirection SortDirection + { + get { return _SortDirection; } + set + { + if (value != _SortDirection) + { + eSortDirection oldValue = _SortDirection; + _SortDirection = value; + OnSortDirectionChanged(oldValue, value); + } + } + } + /// + /// Called when SortDirection property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSortDirectionChanged(eSortDirection oldValue, eSortDirection newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SortDirection")); + this.Invalidate(); + if (_SortingEnabled) + { + if (_Parent != null) _Parent.SortDirectionUpdated(this); + if (newValue == eSortDirection.Ascending) + this.Sort(false); + else if (newValue == eSortDirection.Descending) + this.Sort(true); + } + } + /// + /// Invalidates the appearance of column header. + /// + private void Invalidate() + { + if (_Parent == null) return; + if (_Parent.Parent != null) + { + if (_Parent.Parent.ColumnHeaderControl != null) + { + Rectangle r = this.Bounds; + if (!this.IsFirstVisible) + { + int spacing = _Parent.Parent.CellHorizontalSpacing; + r.Width += spacing; + r.X -= spacing; + } + _Parent.Parent.ColumnHeaderControl.Invalidate(r); + } + } + else if (_Parent.ParentNode != null) + _Parent.ParentNode.Invalidate(); + } + #endregion + + #region Internal Implementation + /// + /// Occurs after Tooltip text has changed. + /// + protected virtual void OnTooltipChanged() { } + private string _Tooltip = ""; + /// + /// Gets/Sets informational text (tooltip) for the cell. + /// + [Browsable(true), DefaultValue(""), Category("Appearance"), Description("Indicates the text that is displayed when mouse hovers over the cell."), Localizable(true)] + public string Tooltip + { + get + { + + return _Tooltip; + } + set + { + if (_Tooltip == value) + return; + if (value == null) value = ""; + _Tooltip = value; + + if (this.ToolTipVisible) + { + if (string.IsNullOrEmpty(_Tooltip)) + this.HideToolTip(); + else + { + DevComponents.DotNetBar.ToolTip tooltipWindow = _ToolTipWnd; + tooltipWindow.Text = _Tooltip; + tooltipWindow.ShowToolTip(); + tooltipWindow.Invalidate(); + } + } + OnTooltipChanged(); + } + } + /// + /// Gets whether tooltip is visible or not. + /// + internal protected bool ToolTipVisible + { + get + { + return (_ToolTipWnd != null); + } + } + /// + /// Called when tooltip is shown and hidden. + /// + /// true if tooltip is being shown otherwise false. + protected virtual void OnTooltip(bool isShown) + { + } + private DevComponents.DotNetBar.ToolTip _ToolTipWnd = null; + /// + /// Shows tooltip for this item. + /// + public virtual void ShowToolTip() + { + if (this.DesignMode) + return; + + if (Visible) + { + AdvTree tree = this.AdvTree; + if (tree != null && !tree.ShowToolTips || !this.ShowToolTips) + return; + OnTooltip(true); + if (_Tooltip != "") + { + if (_ToolTipWnd == null) + _ToolTipWnd = new DevComponents.DotNetBar.ToolTip(); + _ToolTipWnd.Style = StyleManager.GetEffectiveStyle(); + _ToolTipWnd.Text = _Tooltip; + _ToolTipWnd.ReferenceRectangle = ScreenRectangle; + + OnToolTipVisibleChanged(new EventArgs()); + _ToolTipWnd.ShowToolTip(); + } + } + } + /// + /// Destroys tooltip window. + /// + internal protected void HideToolTip() + { + if (_ToolTipWnd != null) + { + System.Drawing.Rectangle tipRect = _ToolTipWnd.Bounds; + tipRect.Width += 5; + tipRect.Height += 6; + + OnTooltip(false); + OnToolTipVisibleChanged(new EventArgs()); + try + { + if (_ToolTipWnd != null) + { + _ToolTipWnd.Hide(); + _ToolTipWnd.Dispose(); + _ToolTipWnd = null; + } + } + catch { } + AdvTree tree = this.AdvTree; + if (tree != null) + { + tree.Invalidate(tree.RectangleToClient(tipRect), false); + } + } + } + /// + /// Occurs when item's tooltip visibility has changed. + /// + [System.ComponentModel.Description("Occurs when item's tooltip visibility has changed.")] + public event EventHandler ToolTipVisibleChanged; + private void OnToolTipVisibleChanged(EventArgs eventArgs) + { + EventHandler h = ToolTipVisibleChanged; + if (h != null) + ToolTipVisibleChanged(this, eventArgs); + } + private Rectangle ScreenRectangle + { + get + { + AdvTree tree = this.AdvTree; + if (tree == null) return Rectangle.Empty; + return new Rectangle(tree.PointToScreen(this.Bounds.Location), this.Bounds.Size); + } + } + + private bool _ShowToolTips = true; + /// + /// Gets or sets whether tooltips are shown when mouse is over the cell when Tooltip property is set. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether tooltips are shown when mouse is over the cell when Tooltip property is set.")] + public bool ShowToolTips + { + get { return _ShowToolTips; } + set + { + _ShowToolTips = value; + } + } + + /// + /// Automatically sets the column width (Width.Absolute) property based on the content of the column. + /// This will perform the one-time auto sizing of the column. To make column auto-size all the time + /// set Width.AutoSize=true. + /// + public void AutoSize() + { + if (_Parent == null) + throw new InvalidOperationException("ColumnHeader is not parented."); + AdvTree tree = AdvTree; + if (tree == null) + throw new InvalidOperationException("Cannot obtain reference to parent tree control, column might not be parented."); + this.Width.AutoSize = true; + tree.RecalcLayout(); + tree.Invalidate(); + this.Width.SetAutoSize(false); + this.Width.SetAbsolute(this.Width.AutoSizeWidth); + OnHeaderSizeChanged(EventArgs.Empty); + } + private void OnHeaderSizeChanged(EventArgs e) + { + EventHandler h = HeaderSizeChanged; + if (h != null) + h(this, e); + } + /// + /// Returns reference to AdvTree control this column belongs to. + /// + [Browsable(false)] + public AdvTree AdvTree + { + get + { + if (_Parent == null) return null; + return _Parent.ParentNode == null ? _Parent.Parent : _Parent.ParentNode.TreeControl; + } + } + + private bool _DoubleClickAutoSize = true; + /// + /// Gets or sets whether column is automatically sized to the content when user double-clicks the column + /// on the column resize line. Column resizing must be enabled in order for this property to function. + /// Default value is true which indicates that column will be auto-sized to content when user double-clicks the + /// column resize marker. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether column is automatically sized to content when user double-clicks the column resize marker.")] + public bool DoubleClickAutoSize + { + get { return _DoubleClickAutoSize; } + set + { + _DoubleClickAutoSize = value; + } + } + + + /// + /// Gets or sets whether column size has changed and it's layout needs to be recalculated. + /// + internal bool SizeChanged + { + get { return m_SizeChanged; } + set { m_SizeChanged = value; } + } + + private void OnSizeChanged() + { + m_SizeChanged = true; + OnHeaderSizeChanged(EventArgs.Empty); + } + + private void WidthChanged(object sender, EventArgs e) + { + this.OnSizeChanged(); + } + + private bool _IsMouseDown = false; + /// + /// Gets whether mouse left button is pressed on the column. + /// + [Browsable(false)] + public bool IsMouseDown + { + get { return _IsMouseDown; } +#if FRAMEWORK20 + internal set +#else + set +#endif + + { + if (_IsMouseDown != value) + { + _IsMouseDown = value; + OnIsMouseDownChanged(); + } + } + } + + private void OnIsMouseDownChanged() + { + if (_Parent != null && _Parent.ParentNode != null) + { + AdvTree tree = _Parent.ParentNode.TreeControl; + if (tree != null) tree.Invalidate(this.Bounds); + } + } + + private bool _IsMouseOver = false; + /// + /// Gets whether mouse is over the column. + /// + [Browsable(false)] + public bool IsMouseOver + { + get { return _IsMouseOver; } +#if FRAMEWORK20 + internal set +#else + set +#endif + { + _IsMouseOver = value; + this.Invalidate(); + } + } + + internal bool IsLastVisible = false; + internal bool IsFirstVisible = false; + /// + /// Occurs when mouse is moving over the column header. + /// + [Description("Occurs when mouse is moving over the column header")] + public event MouseEventHandler MouseMove; + /// + /// Raises MouseMove event. + /// + /// Provides event arguments. + protected virtual void OnMouseMove(MouseEventArgs e) + { + MouseEventHandler handler = MouseMove; + if (handler != null) + handler(this, e); + } + internal void InternalMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + /// + /// Occurs when mouse enters column header. + /// + [Description("Occurs when mouse enters column header.")] + public event EventHandler MouseEnter; + /// + /// Raises MouseEnter event. + /// + /// Provides event arguments. + protected virtual void OnMouseEnter(EventArgs e) + { + EventHandler handler = MouseEnter; + if (handler != null) + handler(this, e); + } + internal void InternalMouseEnter(EventArgs e) + { + this.IsMouseOver = true; + OnMouseEnter(e); + } + /// + /// Occurs when mouse leaves the column header. + /// + [Description("Occurs when mouse leaves the column header.")] + public event EventHandler MouseLeave; + /// + /// Raises MouseLeave event. + /// + /// Provides event arguments. + protected virtual void OnMouseLeave(EventArgs e) + { + EventHandler handler = MouseLeave; + if (handler != null) + handler(this, e); + } + internal void InternalMouseLeave(EventArgs e) + { + HideToolTip(); + this.IsMouseOver = false; + OnMouseLeave(e); + } + /// + /// Occurs when mouse hovers over the column. + /// + [Description("Occurs when mouse hovers over the column.")] + public event EventHandler MouseHover; + /// + /// Raises MouseHover event. + /// + /// Provides event arguments. + protected virtual void OnMouseHover(EventArgs e) + { + EventHandler handler = MouseHover; + if (handler != null) + handler(this, e); + } + internal void InternalMouseHover(EventArgs e) + { + ShowToolTip(); + OnMouseHover(e); + } + + internal virtual void OnMouseDown(System.Windows.Forms.MouseEventArgs e) + { + HideToolTip(); + if (e.Button == MouseButtons.Left) IsMouseDown = true; + + MouseEventHandler eh = this.MouseDown; + if (eh != null) + eh(this, e); + } + + internal virtual void OnMouseUp(System.Windows.Forms.MouseEventArgs e) + { + bool wasMouseDown = IsMouseDown; + if (e.Button == MouseButtons.Left) IsMouseDown = false; + + if (_SortingEnabled && wasMouseDown) + { + if (e.Button == MouseButtons.Middle && _SortDirection != eSortDirection.None) + SortDirection = eSortDirection.None; + else if (e.Button == MouseButtons.Left) + { + if (_SortDirection == eSortDirection.None || _SortDirection == eSortDirection.Descending) + SortDirection = eSortDirection.Ascending; + else + SortDirection = eSortDirection.Descending; + } + } + + MouseEventHandler eh = this.MouseUp; + if (eh != null) + eh(this, e); + } + + internal virtual void OnDoubleClick(EventArgs e) + { + EventHandler handler = DoubleClick; + if (handler != null) handler(this, e); + } + + internal virtual void OnClick(EventArgs e) + { + EventHandler handler = Click; + if (handler != null) handler(this, e); + } + + private eCellEditorType _EditorType = eCellEditorType.Default; + /// + /// Gets or sets the editor type used to edit the cell. Setting this property to value other than Default + /// overrides the cell editor type specified on column cell belongs to. + /// + [DefaultValue(eCellEditorType.Default), Category("Behavior"), Description("Indicates editor type used to edit the cell.")] + public eCellEditorType EditorType + { + get { return _EditorType; } + set { _EditorType = value; } + } + + private bool _LastSortReverse = false; + /// + /// Sort first level nodes that belong directly to this column. Calling this method repeatedly will + /// alternate between A-Z and Z-A sorting. + /// + public void Sort() + { + Sort(_LastSortReverse); + _LastSortReverse = !_LastSortReverse; + } + + /// + /// Sort first level nodes that belong directly to this column. + /// + /// true to use reverse Z-A sorting, false to sort from A-Z + public void Sort(bool reverse) + { + if (SortCells != null) + SortCells(this, new SortEventArgs(reverse, this)); + } + + private IComparer _SortComparer = null; + /// + /// Gets or sets ascending (A-Z) column comparer used to sort nodes when this column is clicked. Your comparer will be passed to NodeCollection.Sort method and should know how to sort by appropriate column. + /// + [Browsable(false), DefaultValue(null), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IComparer SortComparer + { + get { return _SortComparer; } + set + { + if (value != _SortComparer) + { + IComparer oldValue = _SortComparer; + _SortComparer = value; + OnSortComparerChanged(oldValue, value); + } + } + } + /// + /// Called when SortComparer property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSortComparerChanged(IComparer oldValue, IComparer newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SortComparer")); + } + + private IComparer _SortComparerReverse = null; + /// + /// Gets or sets descending (Z-A) column comparer used to sort nodes when this column is clicked. Your comparer will be passed to NodeCollection.Sort method and should know how to sort by appropriate column. + /// + [Browsable(false), DefaultValue(null), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IComparer SortComparerReverse + { + get { return _SortComparerReverse; } + set + { + if (value != _SortComparerReverse) + { + IComparer oldValue = _SortComparerReverse; + _SortComparerReverse = value; + OnSortComparerReverseChanged(oldValue, value); + } + } + } + /// + /// Called when SortComparerReverse property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSortComparerReverseChanged(IComparer oldValue, IComparer newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SortComparerReverse")); + } + #endregion + + } + + public delegate void SortCellsEventHandler(object sender, SortEventArgs e); + public class SortEventArgs : EventArgs + { + public bool ReverseSort = false; + /// + /// Gets or sets whether to cancel internal sorting performed by AdvTree. + /// + public bool Cancel = false; + /// + /// Gets or sets the column header being sorted. + /// + public ColumnHeader ColumnHeader = null; + /// + /// Gets or sets the IComparer used for sorting. + /// + public IComparer Comparer = null; + public SortEventArgs(bool reverse, ColumnHeader columnHeader) + { + ReverseSort = reverse; + ColumnHeader = columnHeader; + } + } + /// + /// Defines column related event arguments. + /// + public class ColumnEventArgs : EventArgs + { + /// + /// Gets reference to the column. + /// + public readonly ColumnHeader Column; + /// + /// Initializes a new instance of the ColumnEventArgs class. + /// + /// + public ColumnEventArgs(ColumnHeader column) + { + Column = column; + } + } + + /// + /// Defines delegate for ColumnMoved event. + /// + public delegate void ColumnMovedHandler(object sender, ColumnMovedEventArgs ea); + /// + /// Defines column moved event arguments. + /// + public class ColumnMovedEventArgs : ColumnEventArgs + { + /// + /// Gets the column display index before the column was moved. + /// + public readonly int OldColumnDisplayIndex; + /// + /// Gets the column display index before the column was moved. + /// + public readonly int NewColumnDisplayIndex; + /// + /// Initializes a new instance of the ColumnMovedEventArgs class. + /// + /// Column affected + /// Old display index + /// New display index + public ColumnMovedEventArgs(ColumnHeader column, int oldColumnDisplayIndex, int newColumnDisplayIndex) + : base(column) + { + OldColumnDisplayIndex = oldColumnDisplayIndex; + NewColumnDisplayIndex = newColumnDisplayIndex; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/ColumnHeaderCollection.cs b/PROMS/DotNetBar Source Code/AdvTree/ColumnHeaderCollection.cs new file mode 100644 index 00000000..7d57b7c2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/ColumnHeaderCollection.cs @@ -0,0 +1,583 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace DevComponents.AdvTree +{ + /// + /// Represents collection for ColumnHeader objects. + /// + public class ColumnHeaderCollection : CollectionBase + { + #region Private Variables + private Node _ParentNode = null; + private AdvTree _Parent = null; + #endregion + + #region Internal Implementation + /// + /// Default constructor. + /// + public ColumnHeaderCollection() + { + } + /// + /// Gets or sets the node this collection is associated with. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Node ParentNode + { + get { return _ParentNode; } + } + /// + /// Sets the node collection belongs to. + /// + /// ColumnHeader that is parent of this collection. + internal void SetParentNode(Node parent) + { + _ParentNode = parent; + } + + internal AdvTree Parent + { + get { return _Parent; } + set { _Parent = value; } + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(ColumnHeader ch) + { + return List.Add(ch); + } + /// + /// Returns reference to the object in collection based on it's index. + /// + public ColumnHeader this[int index] + { + get { return (ColumnHeader)(List[index]); } + set { List[index] = value; } + } + + /// + /// Returns reference to the object in collection based on it's name. + /// + public ColumnHeader this[string name] + { + get + { + int index = IndexOf(name); + if (index == -1) return null; + return this[index]; + } + set { this[IndexOf(name)] = value; } + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, ColumnHeader value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(ColumnHeader value) + { + return List.IndexOf(value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Name of column to return index for. + /// Index of the column or -1 if column not found. + public int IndexOf(string name) + { + for (int i = 0; i < this.List.Count; i++) + { + if (this[i].Name == name) return i; + } + return -1; + } + + /// + /// Returns index of the object inside of the collection based on column DataFieldName. + /// + /// DataFieldName of column to return index for. + /// Index of the column or -1 if column not found. + public int IndexOfDataField(string dataFieldName) + { + dataFieldName = dataFieldName.ToLower(); + for (int i = 0; i < this.List.Count; i++) + { + if (this[i].DataFieldName.ToLower() == dataFieldName) return i; + } + return -1; + } + + /// + /// Returns index of the object inside of the collection based on column DataFieldName. + /// + /// DataFieldName of column to return index for. + /// Index of the column or -1 if column not found. + internal int IndexOfField(string fieldName) + { + fieldName = fieldName.ToLower(); + for (int i = 0; i < this.List.Count; i++) + { + ColumnHeader header = this[i]; + if (header.Tag is BindingMemberInfo && ((BindingMemberInfo)header.Tag).BindingField.ToLower() == fieldName) + return i; + if (header.DataFieldName.ToLower() == fieldName) return i; + if (header.Name == fieldName) return i; + } + return -1; + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(ColumnHeader value) + { + return List.Contains(value); + } + + protected override void OnSet(int index, object oldValue, object newValue) + { + if (oldValue is ColumnHeader) + { + ColumnHeader header = (ColumnHeader)oldValue; + if (header.SortDirection != eSortDirection.None) IsSorted = false; + } + if (newValue is ColumnHeader) + { + ColumnHeader header = (ColumnHeader)newValue; + if (header.SortDirection != eSortDirection.None) IsSorted = true; + } + base.OnSet(index, oldValue, newValue); + } + + /// + /// Removes specified object from the collection. + /// + /// + public void Remove(ColumnHeader value) + { + List.Remove(value); + } + + protected override void OnRemoveComplete(int index, object value) + { + if (value is ColumnHeader) + { + ColumnHeader header = (ColumnHeader)value; + if (header.SortDirection != eSortDirection.None) IsSorted = false; + header.HeaderSizeChanged -= new EventHandler(this.HeaderSizeChanged); + header.SortCells -= new SortCellsEventHandler(SortCellsHandler); + header.MouseDown -= new System.Windows.Forms.MouseEventHandler(ColumnMouseDown); + header.MouseUp -= new System.Windows.Forms.MouseEventHandler(ColumnMouseUp); + header.Parent = null; + } + InvalidateDisplayIndexes(); + UpdateTreeLayout(); + base.OnRemoveComplete(index, value); + } + protected override void OnInsertComplete(int index, object value) + { + if (value is ColumnHeader) + { + ((ColumnHeader)value).HeaderSizeChanged += new EventHandler(this.HeaderSizeChanged); + ((ColumnHeader)value).SortCells += new SortCellsEventHandler(SortCellsHandler); + ((ColumnHeader)value).MouseDown += new System.Windows.Forms.MouseEventHandler(ColumnMouseDown); + ((ColumnHeader)value).MouseUp += new System.Windows.Forms.MouseEventHandler(ColumnMouseUp); + ((ColumnHeader)value).Parent = this; + } + InvalidateDisplayIndexes(); + UpdateTreeLayout(); + base.OnInsertComplete(index, value); + } + + [System.Reflection.Obfuscation(Exclude = true)] + private void ColumnMouseUp(object sender, System.Windows.Forms.MouseEventArgs e) + { + AdvTree tree = GetTree(); + if (tree != null) + tree.InvokeColumnHeaderMouseUp(sender, e); + } + [System.Reflection.Obfuscation(Exclude = true)] + private void ColumnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e) + { + AdvTree tree = GetTree(); + if (tree != null) + tree.InvokeColumnHeaderMouseDown(sender, e); + } + + private AdvTree GetTree() + { + AdvTree tree = _Parent; + if (tree == null && _ParentNode != null) + tree = _ParentNode.TreeControl; + return tree; + } + + /// + /// Occurs before the cells are sorted. + /// + [Description("Occurs before the cells are sorted.")] + public event SortCellsEventHandler SortCells; + protected virtual void OnSortCells(SortEventArgs e) + { + if (SortCells != null) + SortCells(this, e); + } + + private void SortCellsHandler(object sender, SortEventArgs e) + { + ColumnHeader ch = (ColumnHeader)sender; + int i = this.IndexOf(ch); + + IComparer comparer = null; + if (e.ReverseSort) + { + if (ch.SortComparerReverse != null) + comparer = ch.SortComparerReverse; + else + comparer = new NodeComparerReverse(i); + } + else + { + if (ch.SortComparer != null) + comparer = ch.SortComparer; + else + comparer = new NodeComparer(i); + } + + if (e.Comparer == null) + e.Comparer = comparer; + else + comparer = e.Comparer; + OnSortCells(e); + if (e.Cancel) + return; + + if (_Parent != null) + { + _Parent.Nodes.Sort(comparer); + } + else if (_ParentNode != null) + _ParentNode.Nodes.Sort(comparer); + } + private bool _UpdatingSortDirection = false; + /// + /// Called when SortDirection property on column header is set to value other than None. + /// + /// Ref to column header + internal void SortDirectionUpdated(ColumnHeader header) + { + if (_UpdatingSortDirection) return; + + _UpdatingSortDirection = true; + try + { + if (header.SortDirection == eSortDirection.None) + { + IsSorted = false; + return; + } + + IsSorted = true; + + foreach (ColumnHeader col in this.List) + { + if (col != header && col.SortDirection != eSortDirection.None) + col.SortDirection = eSortDirection.None; + } + } + finally + { + _UpdatingSortDirection = false; + } + } + + private bool _IsSorted; + /// + /// Gets whether a column that is part of this collection has SortDirection set. + /// + public bool IsSorted + { + get { return _IsSorted; } + internal set { _IsSorted = value; } + } + + internal void UpdateSort() + { + if (!_IsSorted) return; + foreach (ColumnHeader header in this.List) + { + if (header.SortDirection != eSortDirection.None) + { + header.Sort(header.SortDirection == eSortDirection.Descending); + break; + } + } + } + + private void UpdateTreeLayout() + { + if (_Parent != null) + { + _Parent.InvalidateNodesSize(); + _Parent.Invalidate(); + if (_Parent.Nodes.Count == 0) + _Parent.RecalcLayout(); + else + _Parent.SetPendingLayout(); + } + else if (_ParentNode != null) + { + AdvTree tree = _ParentNode.TreeControl; + if (tree != null) + { + tree.InvalidateNodeSize(_ParentNode); + tree.Invalidate(); + } + } + } + + private void HeaderSizeChanged(object sender, EventArgs e) + { + UpdateTreeLayout(); + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(ColumnHeader[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the ColumnHeader array. + /// + /// Array to copy to. + internal void CopyTo(ColumnHeader[] array) + { + List.CopyTo(array, 0); + } + + protected override void OnClear() + { + foreach (ColumnHeader item in this) + { + item.HeaderSizeChanged -= new EventHandler(this.HeaderSizeChanged); + item.SortCells -= new SortCellsEventHandler(SortCellsHandler); + item.MouseDown -= new System.Windows.Forms.MouseEventHandler(ColumnMouseDown); + item.MouseUp -= new System.Windows.Forms.MouseEventHandler(ColumnMouseUp); + item.Parent = null; + } + IsSorted = false; + base.OnClear(); + } + + /// + /// A map of display index (key) to index in the column collection (value). Used to quickly find a column from its display index. + /// + internal List DisplayIndexMap + { + get + { + if (!_IsDisplayIndexValid) + { + UpdateDisplayIndexMap(); + } + + + return _DisplayIndexMap; + } + } + + /// + /// Gets the display index for specified column. + /// + /// Column that is part f ColumnHeaderCollection + /// Display index or -1 column is not part of this collection. + public int GetDisplayIndex(ColumnHeader column) + { + int index = this.IndexOf(column); + UpdateDisplayIndexMap(); + for (int i = 0; i < _DisplayIndexMap.Count; i++) + { + if (_DisplayIndexMap[i] == index) return i; + } + return -1; + } + + /// + /// Returns the column that is displayed at specified display index.. + /// + /// 0 based display index. + /// ColumnHeader + public ColumnHeader ColumnAtDisplayIndex(int displayIndex) + { + UpdateDisplayIndexMap(); + return this[_DisplayIndexMap[displayIndex]]; + } + + private List _DisplayIndexMap = new List(); + private bool _IsDisplayIndexValid = false; + private void UpdateDisplayIndexMap() + { + if (_IsDisplayIndexValid) return; + + _IsDisplayIndexValid = true; + _DisplayIndexMap.Clear(); + List workingMap = new List(); + bool isAllDefault = true; + for (int i = 0; i < Count; i++) + { + int displayIndex = this[i].DisplayIndex; + if (displayIndex != -1) isAllDefault = false; + workingMap.Add(new IndexToDisplayIndex(i, displayIndex)); + } + if (!isAllDefault) + workingMap.Sort(new DisplayIndexComparer()); + foreach (IndexToDisplayIndex item in workingMap) + { + _DisplayIndexMap.Add(item.Index); + } + } + /// + /// Gets reference to last visible column or null if there is no last visible column. + /// + public DevComponents.AdvTree.ColumnHeader LastVisibleColumn + { + get + { + List displayMap = DisplayIndexMap; + for (int i = displayMap.Count - 1; i >=0; i--) + { + if (this[displayMap[i]].Visible) return this[displayMap[i]]; + } + return null; + } + } + + /// + /// Gets reference to first visible column or null if there is no first visible column. + /// + public DevComponents.AdvTree.ColumnHeader FirstVisibleColumn + { + get + { + List displayMap = DisplayIndexMap; + for (int i = 0; i < displayMap.Count; i++) + { + if (this[displayMap[i]].Visible) return this[displayMap[i]]; + } + return null; + } + } + + #region IndexToDisplayIndex Class + private class IndexToDisplayIndex + { + public int Index = -1; + public int DisplayIndex = -1; + /// + /// Initializes a new instance of the IndexToDisplayIndex class. + /// + /// + /// + public IndexToDisplayIndex(int index, int displayIndex) + { + Index = index; + DisplayIndex = displayIndex; + } + } + #endregion + + #region DisplayIndexComparer + + private class DisplayIndexComparer : IComparer + { + #region IComparer Members + + public int Compare(IndexToDisplayIndex x, IndexToDisplayIndex y) + { + if (x.DisplayIndex == y.DisplayIndex) + { + return x.Index - y.Index; + } + else + { + return x.DisplayIndex - y.DisplayIndex; + } + } + #endregion + } + + #endregion + + internal void DisplayIndexChanged(ColumnHeader column, int newDisplayIndex, int oldDisplayIndex) + { + InvalidateDisplayIndexes(); + + if (_UpdatingDisplayIndexes) return; + + if (_Parent != null && !_Parent.IsUpdateSuspended) + UpdateTreeLayout(); + else if (_ParentNode != null && _ParentNode.TreeControl != null && !_ParentNode.TreeControl.IsUpdateSuspended) + UpdateTreeLayout(); + } + /// + /// Invalidates the display indexes and causes them to be re-evaluated on next layout. + /// + public void InvalidateDisplayIndexes() + { + _IsDisplayIndexValid = false; + } + #endregion + + private Rectangle _Bounds = Rectangle.Empty; + internal void SetBounds(System.Drawing.Rectangle totalBounds) + { + _Bounds = totalBounds; + } + + /// + /// Gets the column header rendering bounds. + /// + [Browsable(false)] + public Rectangle Bounds + { + get { return _Bounds; } + } + + internal bool UsesRelativeSize = false; + + private bool _UpdatingDisplayIndexes = false; + internal bool UpdatingDisplayIndexes + { + get { return _UpdatingDisplayIndexes; } + set { _UpdatingDisplayIndexes = value; } + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/ColumnHeaderControl.cs b/PROMS/DotNetBar Source Code/AdvTree/ColumnHeaderControl.cs new file mode 100644 index 00000000..179854a9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/ColumnHeaderControl.cs @@ -0,0 +1,324 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using DevComponents.DotNetBar; +using System.Drawing.Drawing2D; +using System.Drawing.Text; + +namespace DevComponents.AdvTree +{ + internal class ColumnHeaderControl : Control + { + #region Constructor + /// + /// Initializes a new instance of the ColumnHeaderControl class. + /// + public ColumnHeaderControl() + { + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(ControlStyles.DoubleBuffer, true); + this.SetStyle(ControlStyles.Selectable, false); + this.SetStyle(ControlStyles.StandardDoubleClick | ControlStyles.StandardClick, true); + } + #endregion + + #region Internal Implementation + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + + DisplayHelp.FillRectangle(g, this.ClientRectangle, this.BackColor); + + if (_Columns == null) + { + return; + } + + AdvTree tree = GetTree(); + if (tree != null) + { + SmoothingMode sm = g.SmoothingMode; + TextRenderingHint th = g.TextRenderingHint; + if (tree.AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + //Creates the drawing matrix with the right zoom; + if (tree.Zoom != 1) + { + System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix(tree.Zoom); + //use it for drawing + g.Transform = mx; + } + + tree.NodeDisplay.PaintColumnHeaders(_Columns, g, true); + + int columnMoveMarkerIndex = _ColumnMoveMarkerIndex; + if (columnMoveMarkerIndex >= 0) + DevComponents.AdvTree.Display.ColumnHeaderDisplay.PaintColumnMoveMarker(g, tree, columnMoveMarkerIndex, _Columns); + + if (tree.AntiAlias) + { + g.SmoothingMode = sm; + g.TextRenderingHint = th; + } + } + + + base.OnPaint(e); + } + + private int _ColumnMoveMarkerIndex = -1; + /// + /// Gets or sets the column move marker that marks insertion point for column that is dragged. Marker is drawn before the column specified by this index. + /// + internal int ColumnMoveMarkerIndex + { + get { return _ColumnMoveMarkerIndex; } + set + { + _ColumnMoveMarkerIndex = value; + this.Invalidate(); + } + } + + + /// + /// Returns mouse position which is translated if control Zoom is not equal 1 + /// + /// X coordinate + /// Y coordinate + /// + private Point GetLayoutPosition(float zoom, int x, int y) + { + if (zoom == 1) + return new Point(x, y); + Point[] p = new Point[] { new Point(x, y) }; + using (System.Drawing.Drawing2D.Matrix mx = GetTranslationMatrix(zoom)) + { + mx.Invert(); + mx.TransformPoints(p); + } + return p[0]; + } + + private System.Drawing.Drawing2D.Matrix GetTranslationMatrix(float zoom) + { + System.Drawing.Drawing2D.Matrix mx = new System.Drawing.Drawing2D.Matrix(zoom, 0, 0, zoom, 0, 0); + return mx; + } + + private AdvTree GetTree() + { + return this.Parent as AdvTree; + } + + private ColumnHeaderCollection _Columns = null; + /// + /// Gets or sets the column header collection to be rendered. + /// + public ColumnHeaderCollection Columns + { + get { return _Columns; } + set { _Columns = value; } + } + + private Cursor _OldCursor = null; + private ColumnHeader _MouseOverColumnHeader = null; + protected override void OnMouseMove(MouseEventArgs e) + { + AdvTree tree = GetTree(); + + Point p = GetLayoutPosition(tree.Zoom, e.X, e.Y); + ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns); + if (_MouseOverColumnHeader != ch) + { + if (_MouseOverColumnHeader != null) + _MouseOverColumnHeader.InternalMouseLeave(e); + _MouseOverColumnHeader = ch; + if (_MouseOverColumnHeader != null) + { + _MouseOverColumnHeader.InternalMouseEnter(e); + Interop.WinApi.ResetHover(this); + } + } + + if (ch != null) + { + ch.InternalMouseMove(e); + } + + if (e.Button == MouseButtons.Left && _MouseDownHeader != null && tree.AllowUserToReorderColumns && (Math.Abs(_MouseDownPoint.X-e.X)>1)) + { + tree.StartColumnReorder(p.X, p.Y); + return; + } + + if (tree == null || e.Button != MouseButtons.None || !tree.AllowUserToResizeColumns) return; + + + if (tree.CanResizeColumnAt(p.X, p.Y)) + { + if (_OldCursor == null) + { + _OldCursor = this.Cursor; + this.Cursor = Cursors.VSplit; + } + } + else + { + ReleaseCursor(); + } + + base.OnMouseMove(e); + } + + ColumnHeader _MouseDownHeader = null; + private Point _MouseDownPoint = Point.Empty; + protected override void OnMouseDown(MouseEventArgs e) + { + AdvTree tree = GetTree(); + Point p = Point.Empty; + + bool canResize = false; + _MouseDownPoint = e.Location; + + if (tree != null) + { + p = GetLayoutPosition(tree.Zoom, e.X, e.Y); + } + + if (tree != null && tree.AllowUserToResizeColumns && e.Button == MouseButtons.Left) + canResize = tree.CanResizeColumnAt(p.X, p.Y); + + if (tree != null) + { + p = GetLayoutPosition(tree.Zoom, e.X, e.Y); + ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns); + if (ch != null) + { + _MouseDownHeader = ch; + if (!canResize) + ch.OnMouseDown(e); + } + } + + if (tree == null || e.Button != MouseButtons.Left || !tree.AllowUserToResizeColumns) return; + + if (canResize) + { + tree.StartColumnResize(p.X, p.Y); + } + + this.Invalidate(); + base.OnMouseDown(e); + } + + protected override void OnMouseHover(EventArgs e) + { + if (Control.MouseButtons == MouseButtons.None) + { + AdvTree tree = GetTree(); + Point p = this.PointToClient(Control.MousePosition); + p = GetLayoutPosition(tree.Zoom, p.X, p.Y); + ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns); + if (ch != null) + { + ch.InternalMouseHover(e); + } + } + base.OnMouseHover(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + ReleaseCursor(); + _MouseDownPoint = Point.Empty; + + if (_MouseDownHeader!=null) + { + _MouseDownHeader.OnMouseUp(e); + _MouseDownHeader = null; + } + this.Invalidate(); + + base.OnMouseUp(e); + } + + protected override void OnClick(EventArgs e) + { + AdvTree tree = GetTree(); + Point p = Point.Empty; + + if (tree != null) + { + Point tp = tree.PointToClient(Control.MousePosition); + p = GetLayoutPosition(tree.Zoom, tp.X, tp.Y); + ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns); + if (ch != null) + { + ch.OnClick(e); + } + } + this.Invalidate(); + base.OnClick(e); + } + + internal DateTime IgnoreDoubleClickTime = DateTime.MinValue; + + protected override void OnDoubleClick(EventArgs e) + { + AdvTree tree = GetTree(); + Point p = Point.Empty; + + if (tree != null) + { + Point tp = tree.PointToClient(Control.MousePosition); + p = GetLayoutPosition(tree.Zoom, tp.X, tp.Y); + ColumnHeader ch = tree.GetColumnAt(p.X, p.Y, _Columns); + if (ch != null) + { + DateTime now = DateTime.Now; + if (IgnoreDoubleClickTime != DateTime.MinValue && now.Subtract(IgnoreDoubleClickTime).TotalMilliseconds <= SystemInformation.DoubleClickTime) + { + IgnoreDoubleClickTime = DateTime.MinValue; + return; + } + IgnoreDoubleClickTime = DateTime.MinValue; + + ch.OnDoubleClick(e); + } + } + this.Invalidate(); + + base.OnDoubleClick(e); + } + + private void ReleaseCursor() + { + if (_OldCursor != null) + { + this.Cursor = _OldCursor; + _OldCursor = null; + } + } + + protected override void OnMouseLeave(EventArgs e) + { + if (_MouseOverColumnHeader != null) + { + _MouseOverColumnHeader.InternalMouseLeave(e); + _MouseOverColumnHeader = null; + } + if (Control.MouseButtons != MouseButtons.Left) + ReleaseCursor(); + base.OnMouseLeave(e); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/ColumnWidth.cs b/PROMS/DotNetBar Source Code/AdvTree/ColumnWidth.cs new file mode 100644 index 00000000..21a42f7d --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/ColumnWidth.cs @@ -0,0 +1,151 @@ +using System; +using System.ComponentModel; + +namespace DevComponents.AdvTree +{ + /// + /// Represents the width of the Column. Supports absolute width in Pixels and + /// relative width as percentage of the width of parent control. + /// + [ToolboxItem(false) ,System.ComponentModel.DesignTimeVisible(false),TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))] + public class ColumnWidth + { + private int m_Relative=0; + private int m_Absolute=0; + internal event EventHandler WidthChanged; + + /// + /// Creates new instance of the object. + /// + public ColumnWidth() + { + } + + /// + /// Gets or sets relative width expressed as percentage between 1-100. 0 indicates that + /// absolute width will be used. + /// + /// + /// 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. + /// + [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(); + } + } + } + + /// Gets or sets the absolute width of the column in pixels. + /// + /// Absolute width always takes precedence over the relative width of the + /// column. + /// + [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(); + } + } + } + + internal void SetAbsolute(int value) + { + m_Absolute = value; + } + + internal int GetWidth(int containerWidth) + { + if (m_Absolute > 0) + return m_Absolute; + if(m_Relative>0) + return (100 / m_Relative) * containerWidth; + return 0; + } + + private void OnSizeChanged() + { + if(WidthChanged!=null) + WidthChanged(this,new EventArgs()); + } + + private bool _AutoSize = false; + /// + /// Gets or sets whether column width is automatically set based on the column's content. Default value is false. + /// When set absolute and relative size values are ignored. + /// + [DefaultValue(false), Description("Indicates whether column is sized based on the content.")] + public bool AutoSize + { + get { return _AutoSize; } + set + { + if (_AutoSize != value) + { + _AutoSize = value; + OnSizeChanged(); + } + } + } + + internal void SetAutoSize(bool autoSize) + { + _AutoSize = autoSize; + } + + private bool _AutoSizeMinHeader = false; + /// + /// Gets or sets whether column auto-width is set to minimum of the column header text width. Applies to AutoSize=true only. + /// + [DefaultValue(false), Description("Indicates whether column auto-width is set to minimum of the column header text width. Applies to AutoSize=true only.")] + public bool AutoSizeMinHeader + { + get { return _AutoSizeMinHeader; } + set + { + _AutoSizeMinHeader = value; + OnSizeChanged(); + } + } + + + private int _AutoSizeWidth = 0; + /// + /// Gets the auto-size calculated width of the column after tree layout is performed and column has AutoSize=true. + /// + [Browsable(false)] + public int AutoSizeWidth + { + get { return _AutoSizeWidth; } +// internal set +// { +// _AutoSizeWidth = value; +// } + } + internal void SetAutoSizeWidth(int value) + { + _AutoSizeWidth = value; + } + + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/CommandButtonEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/CommandButtonEventArgs.cs new file mode 100644 index 00000000..37324a7c --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/CommandButtonEventArgs.cs @@ -0,0 +1,30 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Provides event arguments for command button events. + /// + public class CommandButtonEventArgs:EventArgs + { + /// + /// Default constructor. + /// + /// Action type. + /// Context node. + public CommandButtonEventArgs(eTreeAction action, Node node) + { + this.Action=action; + this.Node=node; + } + + /// + /// Indicates the action type that caused the event. + /// + public eTreeAction Action=eTreeAction.Code; + /// + /// Indicates the node action is peformed on. + /// + public DevComponents.AdvTree.Node Node=null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/ConnectorPointsCollection.cs b/PROMS/DotNetBar Source Code/AdvTree/ConnectorPointsCollection.cs new file mode 100644 index 00000000..126f003b --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/ConnectorPointsCollection.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.AdvTree +{ + /// + /// Represents collection of connector points for a node. + /// + public class ConnectorPointsCollection:CollectionBase + { + #region Private Variables + private Node m_ParentNode=null; + #endregion + + #region Internal Implementation + /// + /// Default constructor. + /// + public ConnectorPointsCollection() + { + } + /// + /// Gets or sets the node this collection is associated with. + /// + [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Node ParentNode + { + get {return m_ParentNode;} + } + /// + /// Sets the node collection belongs to. + /// + /// Node that is parent of this collection. + internal void SetParentNode(Node parent) + { + m_ParentNode=parent; + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(Point p) + { + return List.Add(p); + } + + /// + /// Adds range of objects to the array. + /// + /// Array to add. + public void AddRange(Point[] ap) + { + foreach(Point p in ap) + this.Add(p); + } + + /// + /// Copies objects of the collection to the array. + /// + /// + public Point[] ToArray() + { + Point[] ap=new Point[this.Count]; + this.CopyTo(ap); + return ap; + } + + /// + /// Returns reference to the object in collection based on it's index. + /// + public Point this[int index] + { + get {return (Point)(List[index]);} + set {List[index] = value;} + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, Point value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(Point value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(Point value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + 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); + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(Point[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the ColumnHeader array. + /// + /// Array to copy to. + internal void CopyTo(Point[] array) + { + List.CopyTo(array,0); + } + + protected override void OnClear() + { + base.OnClear(); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/CustomEditors.cs b/PROMS/DotNetBar Source Code/AdvTree/CustomEditors.cs new file mode 100644 index 00000000..017e914c --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/CustomEditors.cs @@ -0,0 +1,243 @@ +using System; +using System.Text; +using DevComponents.Editors; +using System.Windows.Forms; +using DevComponents.Editors.DateTimeAdv; + +namespace DevComponents.AdvTree +{ +#if FRAMEWORK20 + #region Integer Custom Editor + internal class IntegerCellEditor : IntegerInput, ICellEditControl + { + #region ICellEditControl Members + + public void BeginEdit() + { +#if (FRAMEWORK20) + this.MinimumSize = new System.Drawing.Size(32, 10); +#endif + } + + public void EndEdit() + { + this.Dispose(); + } + + public object CurrentValue + { + get + { + if (this.FreeTextEntryMode && this.IsKeyboardFocusWithin) + this.ApplyFreeTextValue(); + return this.Text; + } + set + { + if (value is int) + this.Value = (int)value; + else if (value == null) + this.ValueObject = null; + else + { + string s = Utilities.StripNonNumeric(value.ToString()); + int i = 0; +#if FRAMEWORK20 + int.TryParse(s, out i); +#else + try + { + i = int.Parse(s); + } + catch { } +#endif + this.Value = i; + } + } + } + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (keyData == Keys.Enter || keyData == Keys.Tab) + { + if (EditComplete != null) + EditComplete(this, new EventArgs()); + return true; + } + else if (keyData == Keys.Escape) + { + if (CancelEdit != null) + CancelEdit(this, new EventArgs()); + return true; + } + return base.ProcessCmdKey(ref msg, keyData); + } + + public event EventHandler EditComplete; + + public event EventHandler CancelEdit; + + public bool EditWordWrap + { + get { return false; } + set { } + } + + #endregion + } + #endregion + + #region Double Custom Editor + internal class DoubleCellEditor : DoubleInput, ICellEditControl + { + #region ICellEditControl Members + + public void BeginEdit() + { +#if (FRAMEWORK20) + this.MinimumSize = new System.Drawing.Size(32, 10); +#endif + } + + public void EndEdit() + { + this.Dispose(); + } + + public object CurrentValue + { + get + { + if (this.FreeTextEntryMode && this.IsKeyboardFocusWithin) + this.ApplyFreeTextValue(); + return this.Text; + } + set + { + if (value is int) + this.Value = (int)value; + else if (value == null) + this.ValueObject = null; + else + { + string s = Utilities.StripNonNumeric(value.ToString()); + double i = 0; +#if FRAMEWORK20 + double.TryParse(s, out i); +#else + try + { + i = double.Parse(s); + } + catch { } +#endif + this.Value = i; + } + } + } + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (keyData == Keys.Enter || keyData == Keys.Tab) + { + if (EditComplete != null) + EditComplete(this, new EventArgs()); + return true; + } + else if (keyData == Keys.Escape) + { + if (CancelEdit != null) + CancelEdit(this, new EventArgs()); + return true; + } + return base.ProcessCmdKey(ref msg, keyData); + } + + public event EventHandler EditComplete; + + public event EventHandler CancelEdit; + + public bool EditWordWrap + { + get { return false; } + set { } + } + + #endregion + } + #endregion + + #region Date-Time Custom Editor + internal class DateTimeCellEditor : DateTimeInput, ICellEditControl + { + #region Constructor + /// + /// Initializes a new instance of the DateTimeCellEditor class. + /// + public DateTimeCellEditor() + { + this.BackgroundStyle.BorderColor = System.Drawing.Color.Transparent; + } + #endregion + + #region ICellEditControl Members + public void BeginEdit() + { + this.MinimumSize = new System.Drawing.Size(70, 10); + } + + public void EndEdit() + { + this.Dispose(); + } + + public object CurrentValue + { + get + { + return this.Text; + } + set + { + if (value is DateTime) + this.Value = (DateTime)value; + else if (value == null) + this.ValueObject = null; + else if(value is string) + { + DateTime date = DateTime.MinValue; + if (DateTime.TryParse((string)value, out date)) + this.Value = date; + } + } + } + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (keyData == Keys.Enter || keyData == Keys.Tab) + { + if (EditComplete != null) + EditComplete(this, new EventArgs()); + return true; + } + else if (keyData == Keys.Escape) + { + if (CancelEdit != null) + CancelEdit(this, new EventArgs()); + return true; + } + return base.ProcessCmdKey(ref msg, keyData); + } + + public event EventHandler EditComplete; + + public event EventHandler CancelEdit; + + public bool EditWordWrap + { + get { return false; } + set { } + } + + #endregion + } + #endregion +#endif +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/CellDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/CellDisplay.cs new file mode 100644 index 00000000..869fbe03 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/CellDisplay.cs @@ -0,0 +1,328 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using DevComponents.DotNetBar; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Represents cell display class. + /// + internal class CellDisplay + { + public CellDisplay() + { + } + + private static Office2007CheckBoxItemPainter _CheckBoxPainter; + public static Office2007CheckBoxItemPainter CheckBoxPainter + { + get { return _CheckBoxPainter; } + set { _CheckBoxPainter = value; } + } + + public static Office2007CheckBoxColorTable ColorTable = null; + + 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; + Cell cell = ci.Cell; + Rectangle r = cell.CheckBoxBoundsRelative; + r.Offset(ci.CellOffset); + + if (ci.CheckBoxImageChecked != null) + { + Image img = ci.CheckBoxImageChecked; + if (cell.CheckState == System.Windows.Forms.CheckState.Unchecked) + img = ci.CheckBoxImageUnChecked; + else if (cell.CheckState == System.Windows.Forms.CheckState.Indeterminate) + img = ci.CheckBoxImageIndeterminate; + if (img != null) + ci.Graphics.DrawImage(img, r); + } + else if (_CheckBoxPainter != null) + { + Office2007CheckBoxStateColorTable ct = GetCheckBoxStateColorTable(ci); + if (cell.CheckBoxStyle == eCheckBoxStyle.CheckBox) + { + _CheckBoxPainter.PaintCheckBox(ci.Graphics, r, ct, cell.CheckState); + } + else + { + _CheckBoxPainter.PaintRadioButton(ci.Graphics, r, ct, cell.Checked); + } + } + else + { + 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); + } + } + + private static Office2007CheckBoxStateColorTable GetCheckBoxStateColorTable(NodeCellRendererEventArgs e) + { + Cell cell = e.Cell; + + if (ColorTable != null && BarFunctions.IsOffice2007Style(e.ColorScheme.Style)) + { + Office2007CheckBoxColorTable ct = ColorTable; + if (!cell.GetEnabled()) + return ct.Disabled; + //else if (cell.IsMouseDown) + // return ct.Pressed; + //else if (cell.IsMouseOver) + // return ct.MouseOver; + return ct.Default; + } + else + { + ColorScheme cs = e.ColorScheme; + // Create color table based on the ColorScheme object... + Office2007CheckBoxStateColorTable ct = new Office2007CheckBoxStateColorTable(); + if (!cell.GetEnabled()) + { + ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + ct.CheckBorder = cs.ItemDisabledText; + ct.CheckInnerBorder = cs.ItemDisabledText; + ct.CheckInnerBackground = new LinearGradientColorTable(); + ct.CheckSign = new LinearGradientColorTable(cs.ItemDisabledText, Color.Empty); + ct.Text = cs.ItemDisabledText; + } + //else if (cell.IsMouseDown) + //{ + // ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + // ct.CheckBorder = cs.ItemPressedBorder; + // ct.CheckInnerBorder = cs.ItemPressedBorder; + // ct.CheckInnerBackground = new LinearGradientColorTable(cs.ItemPressedBackground, cs.ItemPressedBackground2); + // ct.CheckSign = new LinearGradientColorTable(cs.ItemPressedText, Color.Empty); + // ct.Text = cs.ItemPressedText; + //} + //else if (cell.IsMouseOver) + //{ + // ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + // ct.CheckBorder = cs.ItemHotBorder; + // ct.CheckInnerBorder = cs.ItemHotBorder; + // ct.CheckInnerBackground = new LinearGradientColorTable(cs.ItemHotBackground, cs.ItemHotBackground2); + // ct.CheckSign = new LinearGradientColorTable(cs.ItemHotText, Color.Empty); + // ct.Text = cs.ItemHotText; + //} + else + { + ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + ct.CheckBorder = cs.PanelBorder; + ct.CheckInnerBorder = ColorBlendFactory.SoftLight(cs.PanelBorder, Color.White); + ct.CheckInnerBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + ct.CheckSign = new LinearGradientColorTable(cs.ItemText, Color.Empty); + ct.Text = cs.ItemText; + } + return ct; + } + } + + 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.ImageSize(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.HostedItem == null && (cell.DisplayText == "" || ci.Style.TextColor.IsEmpty) || cell.TextContentBounds.IsEmpty) + return; + + Rectangle bounds = ci.Cell.TextContentBounds; + bounds.Offset(ci.CellOffset); + + Graphics g = ci.Graphics; + if (cell.HostedControl != null) + { + if (!cell.HostedControl.Visible) + cell.HostedControl.Visible = true; + return; + } + else if (cell.HostedItem != null) + { + BaseItem item = cell.HostedItem; + if (item.ItemAlignment == eItemAlignment.Near) + item.LeftInternal = bounds.X; + else if (item.ItemAlignment == eItemAlignment.Far) + item.LeftInternal = bounds.X + (bounds.Width - item.WidthInternal); + else if (item.ItemAlignment == eItemAlignment.Center) + item.LeftInternal = bounds.X + (bounds.Width - item.WidthInternal) / 2; + if (item.DisplayRectangle.Height < bounds.Height) + item.TopInternal = bounds.Y + (bounds.Height - item.DisplayRectangle.Height) / 2; + else + item.TopInternal = bounds.Y; + item.Displayed = true; + Region oldClip = g.Clip; + Rectangle cb = bounds; + cb.Inflate(2, 1); + g.SetClip(cb, CombineMode.Intersect); + item.Paint(ci.ItemPaintArgs); + if (oldClip != null) + { + g.Clip = oldClip; + oldClip.Dispose(); + } + return; + } + + Font font = ci.Style.Font; + if (bounds.Width > 1 && bounds.Height > 1) + { + //eTextFormat textFormat = ci.Style.TextFormat; + //textFormat = textFormat & ~(textFormat & eTextFormat.HidePrefix); + //textFormat |= eTextFormat.NoPrefix; + if (cell.TextMarkupBody == null) + { + TextDrawing.DrawString(g, cell.DisplayText, font, ci.Style.TextColor, bounds, ci.Style.TextFormat); + } + else + { + DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.TextMarkup.MarkupDrawContext(g, font, ci.Style.TextColor, false); + d.HotKeyPrefixVisible = !((ci.Style.TextFormat & eTextFormat.HidePrefix) == eTextFormat.HidePrefix); + Rectangle mr = Rectangle.Empty; + eStyleTextAlignment lineAlignment = ci.Style.TextLineAlignment; + if (lineAlignment == eStyleTextAlignment.Center) + { + mr = new Rectangle(bounds.X, bounds.Y + (bounds.Height - cell.TextMarkupBody.Bounds.Height) / 2, cell.TextMarkupBody.Bounds.Width, cell.TextMarkupBody.Bounds.Height); + } + else if (lineAlignment == eStyleTextAlignment.Near) + { + mr = new Rectangle(bounds.X, bounds.Y, cell.TextMarkupBody.Bounds.Width, cell.TextMarkupBody.Bounds.Height); + } + else // Far + { + mr = new Rectangle(bounds.X, bounds.Y + (bounds.Height - cell.TextMarkupBody.Bounds.Height), cell.TextMarkupBody.Bounds.Width, cell.TextMarkupBody.Bounds.Height); + } + + cell.TextMarkupBody.Bounds = mr; + cell.TextMarkupBody.Render(d); + } + } + } + + private static Image GetCellImage(Cell cell) + { + Image img=cell.Images.Image; + + bool enabled = cell.GetEnabled(); + + if (!enabled && (cell.Images.ImageDisabled != null || cell.Images.ImageDisabledIndex >= 0 || cell.Images.DisabledImageGenerated != null)) + { + if (cell.Images.DisabledImageGenerated != null) return cell.Images.DisabledImageGenerated; + if (cell.Images.ImageDisabled != null) return cell.Images.ImageDisabled; + if (cell.Images.ImageDisabledIndex >= 0) return cell.Images.GetImageByIndex(cell.Images.ImageDisabledIndex); + } + + if(img == null && !string.IsNullOrEmpty(cell.Images.ImageKey)) + img = cell.Images.GetImageByKey(cell.Images.ImageKey); + if (img == null && cell.Images.ImageIndex >= 0) + img = cell.Images.GetImageByIndex(cell.Images.ImageIndex); + + if (!enabled && img is Bitmap) + { + cell.Images.DisposeGeneratedDisabledImage(); + cell.Images.DisabledImageGenerated = ImageHelper.CreateGrayScaleImage(img as Bitmap); + if (cell.Images.DisabledImageGenerated != null) return cell.Images.DisabledImageGenerated; + return img; + } + + if(cell.IsMouseOver && (cell.Images.ImageMouseOver!=null || cell.Images.ImageMouseOverIndex>= 0 || !string.IsNullOrEmpty(cell.Images.ImageMouseOverKey))) + { + if (cell.Images.ImageMouseOver != null) + img = cell.Images.ImageMouseOver; + else if (cell.Images.ImageMouseOverIndex >= 0) + img = cell.Images.GetImageByIndex(cell.Images.ImageMouseOverIndex); + else + img = cell.Images.GetImageByKey(cell.Images.ImageMouseOverKey); + } + else if(cell.Parent.Expanded && (cell.Images.ImageExpanded!=null || cell.Images.ImageExpandedIndex>= 0 || !string.IsNullOrEmpty(cell.Images.ImageExpandedKey))) + { + if (cell.Images.ImageExpanded != null) + img = cell.Images.ImageExpanded; + else if (cell.Images.ImageExpandedIndex >= 0) + img = cell.Images.GetImageByIndex(cell.Images.ImageExpandedIndex); + else + img = cell.Images.GetImageByKey(cell.Images.ImageExpandedKey); + } + return img; + } + + public static Font GetCellFont(AdvTree 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; + } + } + + /// + /// Represents information necessary to paint the cell on canvas. + /// + 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; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/ColorTableInitializer.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/ColorTableInitializer.cs new file mode 100644 index 00000000..1dbeda02 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/ColorTableInitializer.cs @@ -0,0 +1,384 @@ +using System; +using System.Text; +using DevComponents.WinForms.Drawing; +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Initializes the tree color tables. + /// + internal class ColorTableInitializer + { + #region Office 2007 Blue + public static void InitOffice2007Blue(TreeColorTable ct, ColorFactory factory) + { + #region Tree Selection + TreeSelectionColors treeSelection = new TreeSelectionColors(); + ct.Selection = treeSelection; + // Highlight full row + SelectionColorTable selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(0xA7CDF0)); + treeSelection.FullRowSelect = selColorTable; + // Highlight full row Inactive + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(0xE5E5E5)); + treeSelection.FullRowSelectInactive = selColorTable; + + // Node Marker + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(64, 0x316AC5)); + selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x316AC5), 1); + treeSelection.NodeMarker = selColorTable; + // Node marker inactibe + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(64, 0xE5E5E5)); + selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x000000), 1); + treeSelection.NodeMarkerInactive = selColorTable; + + // Cell selection + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(new ColorStop[] { + new ColorStop(factory.GetColor(0xFFFCD9), 0f), + new ColorStop(factory.GetColor(0xFFE78D), .4f), + new ColorStop(factory.GetColor(0xFFD748), .4f), + new ColorStop(factory.GetColor(0xFFE793), 1f) + }); + selColorTable.Border = new SolidBorder(factory.GetColor(0xDDCF9B), 1); + selColorTable.BorderCornerRadius = 2; + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFF2BE), 1); + //selColorTable = new SelectionColorTable(); + //selColorTable.Fill = new GradientFill(factory.GetColor(0xF6FBFD), factory.GetColor(0xD5EFFC), 90); + //selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1); + //selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFFFFF), 1); + treeSelection.HighlightCells = selColorTable; + // Cell selection inactive + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90); + selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1); + selColorTable.BorderCornerRadius = 2; + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1); + treeSelection.HighlightCellsInactive = selColorTable; + + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90); + selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1); + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1); + treeSelection.NodeHotTracking = selColorTable; + #endregion + + #region Expand Buttons + TreeExpandColorTable expand = new TreeExpandColorTable(); + expand.CollapseBorder = new SolidBorder(factory.GetColor(0x000000), 1); + expand.CollapseFill = new SolidFill(factory.GetColor(0x595959)); + expand.CollapseMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1); + expand.CollapseMouseOverFill = new SolidFill(factory.GetColor(0x82DFFB)); + expand.ExpandBorder = new SolidBorder(factory.GetColor(0x848484), 1); + expand.ExpandFill = new SolidFill(factory.GetColor(0xFFFFFF)); + expand.ExpandMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1); + expand.ExpandMouseOverFill = new SolidFill(factory.GetColor(0xCCEDFA)); + ct.ExpandTriangle = expand; + // Rectangle + expand = new TreeExpandColorTable(); + expand.CollapseForeground = new SolidFill(factory.GetColor(0x000000)); + expand.CollapseBorder = new SolidBorder(factory.GetColor(0x969696), 1); + expand.CollapseFill = new GradientFill(new ColorStop[]{ + new ColorStop(factory.GetColor(0xFFFFFF), 0f), new ColorStop(factory.GetColor(0xFFFFFF), .40f), new ColorStop(factory.GetColor(0xB6B6B6), 1f)}, 45); + expand.CollapseMouseOverForeground = expand.CollapseForeground; + expand.CollapseMouseOverBorder = expand.CollapseBorder; + expand.CollapseMouseOverFill = expand.CollapseFill; + expand.ExpandForeground = expand.CollapseForeground; + expand.ExpandBorder = expand.CollapseBorder; + expand.ExpandFill = expand.CollapseFill; + expand.ExpandMouseOverForeground = expand.CollapseForeground; + expand.ExpandMouseOverBorder = expand.CollapseBorder; + expand.ExpandMouseOverFill = expand.CollapseFill; + ct.ExpandRectangle = expand; + ct.ExpandEllipse = expand; + #endregion + + #region Misc Tree Color + ct.GridLines = factory.GetColor(0xE1E1E1); + #endregion + } + #endregion + + #region Office 2007 Silver + public static void InitOffice2007Silver(TreeColorTable ct, ColorFactory factory) + { + #region Tree Selection + TreeSelectionColors treeSelection = new TreeSelectionColors(); + ct.Selection = treeSelection; + // Highlight full row + SelectionColorTable selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(0xA7CDF0)); + treeSelection.FullRowSelect = selColorTable; + // Highlight full row Inactive + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(0xE5E5E5)); + treeSelection.FullRowSelectInactive = selColorTable; + + // Node Marker + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(64, 0x316AC5)); + selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x316AC5), 1); + treeSelection.NodeMarker = selColorTable; + // Node marker inactibe + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(64, 0xE5E5E5)); + selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x000000), 1); + treeSelection.NodeMarkerInactive = selColorTable; + + // Cell selection + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(new ColorStop[] { + new ColorStop(factory.GetColor(0xFFFCD9), 0f), + new ColorStop(factory.GetColor(0xFFE78D), .4f), + new ColorStop(factory.GetColor(0xFFD748), .4f), + new ColorStop(factory.GetColor(0xFFE793), 1f) + }); + selColorTable.Border = new SolidBorder(factory.GetColor(0xDDCF9B), 1); + selColorTable.BorderCornerRadius = 2; + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFF2BE), 1); + //selColorTable = new SelectionColorTable(); + //selColorTable.Fill = new GradientFill(factory.GetColor(0xF6FBFD), factory.GetColor(0xD5EFFC), 90); + //selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1); + //selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFFFFF), 1); + treeSelection.HighlightCells = selColorTable; + // Cell selection inactive + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90); + selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1); + selColorTable.BorderCornerRadius = 2; + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1); + treeSelection.HighlightCellsInactive = selColorTable; + + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90); + selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1); + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1); + treeSelection.NodeHotTracking = selColorTable; + #endregion + + #region Expand Buttons + TreeExpandColorTable expand = new TreeExpandColorTable(); + expand.CollapseBorder = new SolidBorder(factory.GetColor(0x000000), 1); + expand.CollapseFill = new SolidFill(factory.GetColor(0x595959)); + expand.CollapseMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1); + expand.CollapseMouseOverFill = new SolidFill(factory.GetColor(0x82DFFB)); + expand.ExpandBorder = new SolidBorder(factory.GetColor(0x848484), 1); + expand.ExpandFill = new SolidFill(factory.GetColor(0xFFFFFF)); + expand.ExpandMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1); + expand.ExpandMouseOverFill = new SolidFill(factory.GetColor(0xCCEDFA)); + ct.ExpandTriangle = expand; + // Rectangle + expand = new TreeExpandColorTable(); + expand.CollapseForeground = new SolidFill(factory.GetColor(0x000000)); + expand.CollapseBorder = new SolidBorder(factory.GetColor(0x969696), 1); + expand.CollapseFill = new GradientFill(new ColorStop[]{ + new ColorStop(factory.GetColor(0xFFFFFF), 0f), new ColorStop(factory.GetColor(0xFFFFFF), .40f), new ColorStop(factory.GetColor(0xB6B6B6), 1f)}, 45); + expand.CollapseMouseOverForeground = expand.CollapseForeground; + expand.CollapseMouseOverBorder = expand.CollapseBorder; + expand.CollapseMouseOverFill = expand.CollapseFill; + expand.ExpandForeground = expand.CollapseForeground; + expand.ExpandBorder = expand.CollapseBorder; + expand.ExpandFill = expand.CollapseFill; + expand.ExpandMouseOverForeground = expand.CollapseForeground; + expand.ExpandMouseOverBorder = expand.CollapseBorder; + expand.ExpandMouseOverFill = expand.CollapseFill; + ct.ExpandRectangle = expand; + ct.ExpandEllipse = expand; + #endregion + + #region Misc Tree Color + ct.GridLines = factory.GetColor(0xE1E1E1); + #endregion + } + #endregion + + #region Office 2007 Black + public static void InitOffice2007Black(TreeColorTable ct, ColorFactory factory) + { + #region Tree Selection + TreeSelectionColors treeSelection = new TreeSelectionColors(); + ct.Selection = treeSelection; + // Highlight full row + SelectionColorTable selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(0xA7CDF0)); + treeSelection.FullRowSelect = selColorTable; + // Highlight full row Inactive + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(0xE5E5E5)); + treeSelection.FullRowSelectInactive = selColorTable; + + // Node Marker + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(64, 0x316AC5)); + selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x316AC5), 1); + treeSelection.NodeMarker = selColorTable; + // Node marker inactibe + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(64, 0xE5E5E5)); + selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x000000), 1); + treeSelection.NodeMarkerInactive = selColorTable; + + // Cell selection + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(new ColorStop[] { + new ColorStop(factory.GetColor(0xFFFCD9), 0f), + new ColorStop(factory.GetColor(0xFFE78D), .4f), + new ColorStop(factory.GetColor(0xFFD748), .4f), + new ColorStop(factory.GetColor(0xFFE793), 1f) + }); + selColorTable.Border = new SolidBorder(factory.GetColor(0xDDCF9B), 1); + selColorTable.BorderCornerRadius = 2; + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFF2BE), 1); + //selColorTable = new SelectionColorTable(); + //selColorTable.Fill = new GradientFill(factory.GetColor(0xF6FBFD), factory.GetColor(0xD5EFFC), 90); + //selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1); + //selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFFFFF), 1); + treeSelection.HighlightCells = selColorTable; + // Cell selection inactive + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90); + selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1); + selColorTable.BorderCornerRadius = 2; + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1); + treeSelection.HighlightCellsInactive = selColorTable; + + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(factory.GetColor(0xFAFAFB), factory.GetColor(0xE5E5E5), 90); + selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1); + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFFFFFF), 1); + treeSelection.NodeHotTracking = selColorTable; + #endregion + + #region Expand Buttons + TreeExpandColorTable expand = new TreeExpandColorTable(); + expand.CollapseBorder = new SolidBorder(factory.GetColor(0x000000), 1); + expand.CollapseFill = new SolidFill(factory.GetColor(0x595959)); + expand.CollapseMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1); + expand.CollapseMouseOverFill = new SolidFill(factory.GetColor(0x82DFFB)); + expand.ExpandBorder = new SolidBorder(factory.GetColor(0x848484), 1); + expand.ExpandFill = new SolidFill(factory.GetColor(0xFFFFFF)); + expand.ExpandMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1); + expand.ExpandMouseOverFill = new SolidFill(factory.GetColor(0xCCEDFA)); + ct.ExpandTriangle = expand; + // Rectangle + expand = new TreeExpandColorTable(); + expand.CollapseForeground = new SolidFill(factory.GetColor(0x000000)); + expand.CollapseBorder = new SolidBorder(factory.GetColor(0x969696), 1); + expand.CollapseFill = new GradientFill(new ColorStop[]{ + new ColorStop(factory.GetColor(0xFFFFFF), 0f), new ColorStop(factory.GetColor(0xFFFFFF), .40f), new ColorStop(factory.GetColor(0xB6B6B6), 1f)}, 45); + expand.CollapseMouseOverForeground = expand.CollapseForeground; + expand.CollapseMouseOverBorder = expand.CollapseBorder; + expand.CollapseMouseOverFill = expand.CollapseFill; + expand.ExpandForeground = expand.CollapseForeground; + expand.ExpandBorder = expand.CollapseBorder; + expand.ExpandFill = expand.CollapseFill; + expand.ExpandMouseOverForeground = expand.CollapseForeground; + expand.ExpandMouseOverBorder = expand.CollapseBorder; + expand.ExpandMouseOverFill = expand.CollapseFill; + ct.ExpandRectangle = expand; + ct.ExpandEllipse = expand; + #endregion + + #region Misc Tree Color + ct.GridLines = factory.GetColor(0xE1E1E1); + #endregion + } + #endregion + + #region Office 2007 Vista Glass + public static void InitOffice2007VistaGlass(TreeColorTable ct, ColorFactory factory) + { + #region Tree Selection + TreeSelectionColors treeSelection = new TreeSelectionColors(); + ct.Selection = treeSelection; + // Highlight full row + SelectionColorTable selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(0xC4E8FA)); + treeSelection.FullRowSelect = selColorTable; + // Highlight full row Inactive + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(0xE5E5E5)); + treeSelection.FullRowSelectInactive = selColorTable; + + // Node Marker + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(64, 0x316AC5)); + selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x316AC5), 1); + treeSelection.NodeMarker = selColorTable; + // Node marker inactive + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new SolidFill(factory.GetColor(64, 0xE5E5E5)); + selColorTable.Border = new SolidBorder(factory.GetColor(96, 0x000000), 1); + treeSelection.NodeMarkerInactive = selColorTable; + + // Cell selection + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(new ColorStop[] { + new ColorStop(factory.GetColor(0xF1F8FD), 0f), + new ColorStop(factory.GetColor(0xD5EFFC), 1f) + }); + selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1); + selColorTable.BorderCornerRadius = 2; + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xF6FBFD), 1); + //selColorTable = new SelectionColorTable(); + //selColorTable.Fill = new GradientFill(factory.GetColor(0xF6FBFD), factory.GetColor(0xD5EFFC), 90); + //selColorTable.Border = new SolidBorder(factory.GetColor(0x99DEFD), 1); + //selColorTable.InnerBorder = new SolidBorder(factory.GetColor(192, 0xFFFFFF), 1); + treeSelection.HighlightCells = selColorTable; + // Cell selection inactive + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(factory.GetColor(0xF8F8F8), factory.GetColor(0xE5E5E5), 90); + selColorTable.Border = new SolidBorder(factory.GetColor(0xD9D9D9), 1); + selColorTable.BorderCornerRadius = 2; + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xFAFAFB), 1); + treeSelection.HighlightCellsInactive = selColorTable; + + selColorTable = new SelectionColorTable(); + selColorTable.Fill = new GradientFill(factory.GetColor(0xF5FAFD), factory.GetColor(0xE8F5FD), 90); + selColorTable.Border = new SolidBorder(factory.GetColor(0xD8F0FA), 1); + selColorTable.InnerBorder = new SolidBorder(factory.GetColor(228, 0xF8FCFE), 1); + treeSelection.NodeHotTracking = selColorTable; + #endregion + + #region Expand Buttons + TreeExpandColorTable expand = new TreeExpandColorTable(); + expand.CollapseBorder = new SolidBorder(factory.GetColor(0x000000), 1); + expand.CollapseFill = new SolidFill(factory.GetColor(0x595959)); + expand.CollapseMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1); + expand.CollapseMouseOverFill = new SolidFill(factory.GetColor(0x82DFFB)); + expand.ExpandBorder = new SolidBorder(factory.GetColor(0x848484), 1); + expand.ExpandFill = new SolidFill(factory.GetColor(0xFFFFFF)); + expand.ExpandMouseOverBorder = new SolidBorder(factory.GetColor(0x1CC4F7), 1); + expand.ExpandMouseOverFill = new SolidFill(factory.GetColor(0xCCEDFA)); + ct.ExpandTriangle = expand; + // Rectangle + expand = new TreeExpandColorTable(); + expand.CollapseForeground = new SolidFill(factory.GetColor(0x000000)); + expand.CollapseBorder = new SolidBorder(factory.GetColor(0x969696), 1); + expand.CollapseFill = new GradientFill(new ColorStop[]{ + new ColorStop(factory.GetColor(0xFFFFFF), 0f), new ColorStop(factory.GetColor(0xFFFFFF), .40f), new ColorStop(factory.GetColor(0xB6B6B6), 1f)}, 45); + expand.CollapseMouseOverForeground = expand.CollapseForeground; + expand.CollapseMouseOverBorder = expand.CollapseBorder; + expand.CollapseMouseOverFill = expand.CollapseFill; + expand.ExpandForeground = expand.CollapseForeground; + expand.ExpandBorder = expand.CollapseBorder; + expand.ExpandFill = expand.CollapseFill; + expand.ExpandMouseOverForeground = expand.CollapseForeground; + expand.ExpandMouseOverBorder = expand.CollapseBorder; + expand.ExpandMouseOverFill = expand.CollapseFill; + ct.ExpandRectangle = expand; + ct.ExpandEllipse = expand; + #endregion + + #region Misc Tree Color + ct.GridLines = factory.GetColor(0xEDEDED); + #endregion + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/ColumnHeaderDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/ColumnHeaderDisplay.cs new file mode 100644 index 00000000..13dc9d8c --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/ColumnHeaderDisplay.cs @@ -0,0 +1,119 @@ +using System; +using System.Text; +using DevComponents.DotNetBar; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.AdvTree.Display +{ + internal class ColumnHeaderDisplay + { + internal void DrawColumnHeader(ColumnHeaderRendererEventArgs e, ElementStyleDisplayInfo di) + { + // Adjust the header bounds so the header is filled completely + if (e.Tree != null && e.Tree.CellHorizontalSpacing > 0 && !e.ColumnHeader.IsFirstVisible) { + Rectangle ob = di.Bounds; + di.Bounds = new Rectangle(ob.X - e.Tree.CellHorizontalSpacing, ob.Y, ob.Width + e.Tree.CellHorizontalSpacing, ob.Height); + ElementStyleDisplay.Paint(di); + di.Bounds = ob; + } + else + ElementStyleDisplay.Paint(di); + di.Bounds.Inflate(-1, -1); + if (di.Bounds.Width > 1 && di.Bounds.Height > 1) + { + if (e.ColumnHeader.IsFirstVisible) + { + Rectangle r = di.Bounds; + r.Width -= 3; + r.X += 3; + di.Bounds = r; + } + + if (e.ColumnHeader.SortDirection != eSortDirection.None && !e.SortIndicatorColor.IsEmpty) + { + using (GraphicsPath sortShapePath = UIGraphics.GetTrianglePath( + new Point(di.Bounds.Right - 11, di.Bounds.Y + (di.Bounds.Height - 5) / 2), 9, + (e.ColumnHeader.SortDirection == eSortDirection.Ascending ? eTriangleDirection.Top : eTriangleDirection.Bottom))) + { + SmoothingMode sm = e.Graphics.SmoothingMode; + e.Graphics.SmoothingMode = SmoothingMode.Default; + using (SolidBrush brush = new SolidBrush(e.SortIndicatorColor)) + e.Graphics.FillPath(brush, sortShapePath); + e.Graphics.SmoothingMode = sm; + } + di.Bounds.Width -= 12; + } + + if (e.ColumnHeader.Image != null) + { + Image image = e.ColumnHeader.Image; + Rectangle r = di.Bounds; + if (e.ColumnHeader.ImageAlignment == eColumnImageAlignment.Left) + { + e.Graphics.DrawImage(image, r.X, + r.Y + (r.Height - image.Height) / 2, image.Width, image.Height); + r.X += image.Width + 2; + r.Width -= image.Width + 2; + + } + else if (e.ColumnHeader.ImageAlignment == eColumnImageAlignment.Right) + { + e.Graphics.DrawImage(image, r.Right - image.Width, + r.Y + (r.Height - image.Height) / 2, image.Width, image.Height); + r.Width -= image.Width + 2; + } + di.Bounds = r; + } + + ElementStyleDisplay.PaintText(di, e.ColumnHeader.Text, e.Tree.Font); + } + } + + internal static void PaintColumnMoveMarker(Graphics g, AdvTree tree, int columnMoveMarkerIndex, ColumnHeaderCollection columns) + { + if (columnMoveMarkerIndex == -1) throw new ArgumentException("columnMoveMarkerIndex must be grater or equal than 0"); + if (columns == null) throw new ArgumentNullException("columns"); + + Color lineColor = ColorScheme.GetColor("834DD5"); + Color fillColor = ColorScheme.GetColor("CCCFF8"); + Size markerSize = new Size(10, 14); + + ColumnHeader header = null; + + if (columnMoveMarkerIndex == columns.Count) + header = columns.LastVisibleColumn; + else + header = columns[columnMoveMarkerIndex]; + Rectangle markerBounds = Rectangle.Empty; + if (columnMoveMarkerIndex == columns.Count) + markerBounds = new Rectangle(header.Bounds.Right - markerSize.Width, header.Bounds.Bottom - markerSize.Height, markerSize.Width, markerSize.Height); + else if (columns[columnMoveMarkerIndex] == columns.FirstVisibleColumn) + markerBounds = new Rectangle(header.Bounds.X, header.Bounds.Bottom - markerSize.Height, markerSize.Width, markerSize.Height); + else + markerBounds = new Rectangle(header.Bounds.X - markerSize.Width / 2 - tree.NodeLayout.GetCellLayout().LayoutSettings.CellHorizontalSpacing, header.Bounds.Bottom - markerSize.Height, markerSize.Width, markerSize.Height); + if (tree.AutoScrollPosition.X != 0) + markerBounds.Offset(tree.AutoScrollPosition.X, 0); + using (GraphicsPath path = CreateMarker(markerBounds)) + { + using (SolidBrush brush = new SolidBrush(fillColor)) + g.FillPath(brush, path); + using (Pen pen = new Pen(lineColor, 1)) + g.DrawPath(pen, path); + } + } + private static GraphicsPath CreateMarker(Rectangle markerBounds) + { + markerBounds.Height--; + GraphicsPath path = new GraphicsPath(); + path.AddLine(markerBounds.X + markerBounds.Width / 2, markerBounds.Bottom, markerBounds.X, markerBounds.Bottom - markerBounds.Width / 2); + path.AddLine(markerBounds.X, markerBounds.Bottom - markerBounds.Width / 2, markerBounds.X + markerBounds.Width / 3, markerBounds.Bottom - markerBounds.Width / 2); + path.AddLine(markerBounds.X + markerBounds.Width / 3, markerBounds.Bottom - markerBounds.Width / 2, markerBounds.X + markerBounds.Width / 3, markerBounds.Y); + path.AddLine(markerBounds.X + markerBounds.Width / 3, markerBounds.Y, markerBounds.Right - markerBounds.Width / 3, markerBounds.Y); + path.AddLine(markerBounds.Right - markerBounds.Width / 3, markerBounds.Y, markerBounds.Right - markerBounds.Width / 3, markerBounds.Bottom - markerBounds.Width / 2); + path.AddLine(markerBounds.Right - markerBounds.Width / 3, markerBounds.Bottom - markerBounds.Width / 2, markerBounds.Right, markerBounds.Bottom - markerBounds.Width / 2); + path.CloseAllFigures(); + return path; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/ColumnHeaderRendererEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/ColumnHeaderRendererEventArgs.cs new file mode 100644 index 00000000..06765d91 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/ColumnHeaderRendererEventArgs.cs @@ -0,0 +1,61 @@ +using System; +using System.Text; +using System.Drawing; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Provides data for RenderColumnHeader event. + /// + public class ColumnHeaderRendererEventArgs : EventArgs + { + /// + /// Gets the column header that is rendered. + /// + public ColumnHeader ColumnHeader = null; + /// + /// Target Graphics canvas. + /// + public Graphics Graphics; + /// + /// Gets the bounds of the column header. + /// + public Rectangle Bounds; + /// + /// Gets the effective style for the column. + /// + public ElementStyle Style = null; + /// + /// Gets the AdvTree control header is rendered for. + /// + public AdvTree Tree = null; + /// + /// Gets or sets the color of the column sort indicator. + /// + public Color SortIndicatorColor = Color.Empty; + + /// + /// Initializes a new instance of the ColumnHeaderRendererEventArgs class. + /// + public ColumnHeaderRendererEventArgs() + { + } + + /// + /// Initializes a new instance of the ColumnHeaderRendererEventArgs class. + /// + /// + /// + /// + /// + public ColumnHeaderRendererEventArgs(AdvTree tree, ColumnHeader columnHeader, Graphics graphics, Rectangle bounds, ElementStyle style) + { + Tree = tree; + ColumnHeader = columnHeader; + Graphics = graphics; + Bounds = bounds; + Style = style; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/ConnectorRendererEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/ConnectorRendererEventArgs.cs new file mode 100644 index 00000000..599bad6d --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/ConnectorRendererEventArgs.cs @@ -0,0 +1,53 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Represents helper class for node connector display. + /// + public class ConnectorRendererEventArgs:EventArgs + { + /// + /// From node reference. + /// + public Node FromNode=null; + /// + /// From node style reference. + /// + public ElementStyle StyleFromNode=null; + /// + /// To node reference. + /// + public Node ToNode=null; + /// + /// To node style reference. + /// + public ElementStyle StyleToNode=null; + /// + /// Graphics object used for drawing. + /// + public System.Drawing.Graphics Graphics=null; + /// + /// Node offset since some node coordinates are relative. + /// + public Point Offset=Point.Empty; + /// + /// Indicates whether from node is a root node. + /// + public bool IsRootNode=false; + /// + /// Reference to node connector object that describes connector type. + /// + public NodeConnector NodeConnector=null; + /// + /// Gets or sets whether connector is link connector. + /// + public bool LinkConnector=false; + /// + /// Reference to the collection of the connector path points. Default value is null indicating there are no path points. + /// + public ConnectorPointsCollection ConnectorPoints=null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/DragDropMarkerDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/DragDropMarkerDisplay.cs new file mode 100644 index 00000000..c4dca5a4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/DragDropMarkerDisplay.cs @@ -0,0 +1,78 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.AdvTree.Display +{ + internal class DragDropMarkerDisplay + { + public void DrawMarker(DragDropMarkerRendererEventArgs e) + { + Graphics g = e.Graphics; + Rectangle bounds = e.Bounds; + if (bounds.IsEmpty || _MarkerColor.IsEmpty) return; + + if (bounds.Width == AdvTree.DragInsertMarkSize) // Vertical insert mark + { + using (SolidBrush brush = new SolidBrush(_MarkerColor)) + { + using (Pen pen = new Pen(brush, 1)) + { + Point p = new Point(bounds.X + 4, bounds.Y); + g.DrawLine(pen, p.X, p.Y, p.X, bounds.Bottom - 1); + } + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLine(bounds.X, bounds.Y, bounds.X + 8, bounds.Y ); + path.AddLine(bounds.X + 8, bounds.Y, bounds.X + 4, bounds.Y + 4); + path.CloseAllFigures(); + g.FillPath(brush, path); + } + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLine(bounds.X, bounds.Bottom, bounds.X + 8, bounds.Bottom); + path.AddLine(bounds.X + 8, bounds.Bottom, bounds.X + 4, bounds.Bottom - 4); + path.CloseAllFigures(); + g.FillPath(brush, path); + } + } + } + else + { + // Horizontal insert mark + using (SolidBrush brush = new SolidBrush(_MarkerColor)) + { + using (Pen pen = new Pen(brush, 1)) + { + Point p = new Point(bounds.X, bounds.Y + 4); + g.DrawLine(pen, p.X, p.Y, bounds.Right - 1, p.Y); + } + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLine(bounds.X, bounds.Y, bounds.X, bounds.Y + 8); + path.AddLine(bounds.X, bounds.Y + 8, bounds.X + 4, bounds.Y + 4); + path.CloseAllFigures(); + g.FillPath(brush, path); + } + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLine(bounds.Right, bounds.Y, bounds.Right, bounds.Y + 8); + path.AddLine(bounds.Right, bounds.Y + 8, bounds.Right - 4, bounds.Y + 4); + path.CloseAllFigures(); + g.FillPath(brush, path); + } + } + } + } + + private Color _MarkerColor; + public Color MarkerColor + { + get { return _MarkerColor; } + set { _MarkerColor = value; } + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/DragDropMarkerRendererEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/DragDropMarkerRendererEventArgs.cs new file mode 100644 index 00000000..a2cfecb5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/DragDropMarkerRendererEventArgs.cs @@ -0,0 +1,39 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Provides data for the NodeRenderer.RenderDragDropMarker event. + /// + public class DragDropMarkerRendererEventArgs : EventArgs + { + /// + /// Gets or sets reference to Graphics object, canvas node is rendered on. + /// + public System.Drawing.Graphics Graphics = null; + /// + /// Gets or sets the selection bounds. + /// + public Rectangle Bounds = Rectangle.Empty; + + /// + /// Initializes a new instance of the DragDropMarkerRendererEventArgs class. + /// + public DragDropMarkerRendererEventArgs() + { + } + + /// + /// Initializes a new instance of the DragDropMarkerRendererEventArgs class. + /// + /// + /// + public DragDropMarkerRendererEventArgs(System.Drawing.Graphics graphics, Rectangle bounds) + { + Graphics = graphics; + Bounds = bounds; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/LineConnectorDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/LineConnectorDisplay.cs new file mode 100644 index 00000000..45651c23 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/LineConnectorDisplay.cs @@ -0,0 +1,52 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using DevComponents.AdvTree.Display; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Represents the line connector display class. + /// + public class LineConnectorDisplay:NodeConnectorDisplay + { + /// + /// Draws connector line between two nodes. + /// + /// Connector context information. + public override void DrawConnector(ConnectorRendererEventArgs info) + { + if(info.NodeConnector.LineColor.IsEmpty || info.NodeConnector.LineWidth<=0) + return; + + Point pStart, pEnd; + + // FromNode is null when connector is rendered for the child node + if (info.FromNode == null) + { + Rectangle cellBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, info.ToNode, info.Offset); + Rectangle expandBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds, info.ToNode, info.Offset); + pStart = new Point(cellBounds.X - 4, cellBounds.Y + cellBounds.Height / 2); + pEnd = new Point(expandBounds.X + expandBounds.Width / 2, pStart.Y); + } + else + { + // FromNode is parent node, ToNode is last visible child node. Connector is vertical line from parent to last visible child + Rectangle cellBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, info.FromNode, info.Offset); + Rectangle expandBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds, info.ToNode, info.Offset); + pStart = new Point(expandBounds.X + expandBounds.Width / 2, cellBounds.Bottom); + pEnd = new Point(pStart.X, expandBounds.Y + expandBounds.Height / 2); + } + + Graphics g = info.Graphics; + using (Pen pen = GetLinePen(info)) + { + SmoothingMode sm = g.SmoothingMode; + if (pen.DashStyle != DashStyle.Solid) + g.SmoothingMode = SmoothingMode.Default; + g.DrawLine(pen, pStart, pEnd); + g.SmoothingMode = sm; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeCellRendererEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeCellRendererEventArgs.cs new file mode 100644 index 00000000..62ca06b0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeCellRendererEventArgs.cs @@ -0,0 +1,59 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Provides information for cell rendering methods and events. + /// + public class NodeCellRendererEventArgs:NodeRendererEventArgs + { + /// + /// Gets or sets the cell being rendered. + /// + public Cell Cell=null; + + /// + /// Gets or sets absolute cell bounds. + /// + public Rectangle CellBounds=Rectangle.Empty; + + /// + /// Gets or sets the internal cell offset. + /// + internal Point CellOffset=Point.Empty; + + /// + /// Gets or sets the color scheme. + /// + internal ColorScheme ColorScheme = null; + + internal Image CheckBoxImageChecked = null; + internal Image CheckBoxImageUnChecked = null; + internal Image CheckBoxImageIndeterminate = null; + internal ItemPaintArgs ItemPaintArgs = null; + + /// + /// Creates new instance of the class. + /// + public NodeCellRendererEventArgs():base(null,null,Rectangle.Empty,null) + { + } + + /// + /// Creates new instance of the class and initializes it with default values. + /// + /// Reference to graphics object. + /// Reference to context node. + /// Reference to node bounds + /// Reference to cell style + /// Reference to cell + /// Reference to cell bounds + 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; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeConnectorDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeConnectorDisplay.cs new file mode 100644 index 00000000..63231b26 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeConnectorDisplay.cs @@ -0,0 +1,511 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.AdvTree +{ + namespace Display + { + /// + /// Base class for drawing node connectors. + /// + public abstract class NodeConnectorDisplay + { + //private bool m_RootNode=false; + //private bool m_DrawRootAllLevels=false; + //private bool m_EndCap=true; + //private bool m_DrawConnectorUnderNodes=true; + + /// + /// Creates new instance of the object. + /// + public NodeConnectorDisplay() + { + } + + /// + /// Draws connector line between two nodes. + /// + /// Connector context information. + public virtual void DrawConnector(ConnectorRendererEventArgs info){} + + ///// + ///// Returns the connector starting coordinates. + ///// + ///// Connector display information. + ///// Point object. + //protected virtual 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 + ///// Returns true if fromNode is above the toNode. + ///// + ///// From Node object. + ///// To Node object + ///// True if fromNode is above toNode. + //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; + //} + + ///// + ///// Returns true if fromNode is below toNode. + ///// + ///// From Node object. + ///// To Node object. + ///// True if fromNode is below toNode. + //protected bool IsBelow(Node fromNode, Node toNode) + //{ + // int toMidPoint=toNode.BoundsRelative.Top+toNode.BoundsRelative.Height/2; + // if(fromNode.BoundsRelative.Bottom + ///// Returns whether connector is extended to underline the node. + ///// + ///// Refernce to Node style. + ///// True if node should be underlined by connector. + //protected bool UnderlineNode(ElementStyle nodeStyle) + //{ + // if(!nodeStyle.PaintBottomBorder && !nodeStyle.PaintTopBorder && + // !nodeStyle.PaintLeftBorder && !nodeStyle.PaintRightBorder) + // return true; + // return false; + //} + + ///// + ///// Returns the connector end point. The array of end points. Two valid points will be returned if node needs to be underlined by connector. + ///// + ///// Connector display info. + ///// Array of point objects. + //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 = 0; // 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 + ///// Returns the offest for the node connector cap. + ///// + ///// Cap type. + ///// Cap size. + ///// + //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; + //} + + ///// + ///// Returns true if source node is on the left side of the target node. + ///// + ///// Reference to source node. + ///// Reference to target node. + ///// True if source is on the left side of target. + //protected bool IsOnLeftSide(Node source, Node target) + //{ + // if((source.BoundsRelative.Left+source.BoundsRelative.Width/2)>target.BoundsRelative.Left) + // return true; + // return false; + //} + + /// + /// Returns new instance of pen object for node connector line. Caller is responsible for + /// disposing of this object. + /// + /// Node connector display info. + /// New instance of Pen object. + protected Pen GetLinePen(ConnectorRendererEventArgs info) + { + Pen pen = new Pen(info.NodeConnector.LineColor, info.NodeConnector.LineWidth); + pen.DashStyle = info.NodeConnector.DashStyle; + return pen; + } + + ///// + ///// Returns new instance of pen object for the end node connector line. Caller is responsible for + ///// disposing of this object. + ///// + ///// Node connector display info. + ///// New instance of Pen object. + //protected Pen GetEndLinePen(ConnectorRendererEventArgs info) + //{ + // return new Pen(info.NodeConnector.LineColor,EndLineWidth); + //} + + ///// + ///// Returns new instance of pen object for the node underline line. Caller is responsible for + ///// disposing of this object. + ///// + ///// Node connector display info. + ///// New instance of Pen object. + //protected Pen GetEndUnderlinePen(ConnectorRendererEventArgs info) + //{ + // return new Pen(info.NodeConnector.LineColor,EndLineWidth); + //} + + //private int EndLineWidth + //{ + // get {return 1;} + //} + +// /// +// /// Draws straight line connector between start and end point. +// /// +// /// Node connector display info. +// /// Start point. +// /// End point. +// /// Underline end point if any. +// protected void DrawStraightLineConnector(ConnectorRendererEventArgs info, Point pStart, Point pEnd) +// { +// using (Pen pen = this.GetLinePen(info)) +// { +// if (pen.DashStyle != DashStyle.Solid) +// { +// SmoothingMode sm = info.Graphics.SmoothingMode; +// info.Graphics.SmoothingMode = SmoothingMode.Default; +// info.Graphics.DrawLine(pen, pStart, pEnd); +// info.Graphics.SmoothingMode = sm; +// } +// else +// info.Graphics.DrawLine(pen, pStart, pEnd); +// } +// } + +// /// +// /// Draws straight line connector between start and end point. +// /// +// /// Node connector display info. +// /// Start point. +// /// End point. +// /// Underline end point if any. +// 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.XpEnd.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); +// 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; + //} + } + } + + /// + /// Represents custom connector path info. + /// + internal class ConnectorPointInfo + { + public Point[] Points1=null; + public Point[] Points2=null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeDisplay.cs new file mode 100644 index 00000000..59e30afb --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeDisplay.cs @@ -0,0 +1,351 @@ +using System; +using System.Drawing; +using DevComponents.AdvTree.Layout; +using System.Collections; +using DevComponents.DotNetBar; +using System.ComponentModel; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Summary description for NodeDisplay. + /// + public class NodeDisplay + { + #region Private Variables + private Point m_Offset=Point.Empty; + private Point m_LockedOffset=Point.Empty; + private AdvTree m_Tree=null; + internal ArrayList _PaintedNodes = new ArrayList(100); +#if !TRIAL + internal static bool keyInvalid=false; +#endif + #endregion + /// Creates new instance of the class + /// Object to initialize class with. + public NodeDisplay(AdvTree tree) + { + m_Tree=tree; + } + + /// + /// Paints the layout on canvas. + /// + public virtual void Paint(Graphics g, Rectangle clipRectangle) + { + } + + /// + /// Gets or sets the offset of the tree content relative to the size of the container control. + /// + public virtual Point Offset + { + get + { + if(!m_LockedOffset.IsEmpty) + return m_LockedOffset; + + Node displayNode=m_Tree.GetDisplayRootNode(); + if(displayNode==null) + return Point.Empty;; + + Size nodesSize = m_Tree.GetScreenSize(new Size(m_Tree.NodeLayout.Width, m_Tree.NodeLayout.Height)); + return m_Tree.GetLayoutPosition(m_Offset); + } + set {m_Offset=value;} + } + + /// Gets or sets whether offset is locked, i.e. cannot be changed. + public bool LockOffset + { + get {return (!m_LockedOffset.IsEmpty);} + set + { + if(value) + m_LockedOffset=this.Offset; + else + m_LockedOffset=Point.Empty; + } + } + + /// + /// Sets locked offset to specific value. Point.Empty means there is no locked offset set. + /// + /// New locked offset. + public void SetLockedOffset(Point p) + { + m_LockedOffset=p; + } + + /// + /// + /// + /// + public Point GetLockedOffset() + { + return m_LockedOffset; + } + + /// + /// Returns the default offset for the tree content relative to the size of the container. + /// + public virtual Point DefaultOffset + { + get + { + Node displayNode=m_Tree.GetDisplayRootNode(); + if(displayNode==null) + return Point.Empty;; + + //if(m_Tree.NodeLayout is NodeMapLayout && m_Tree.Nodes.Count>0) + //{ + // if(!m_Tree.CenterContent) + // return new Point(Math.Abs(displayNode.ChildNodesBounds.Left),Math.Abs(displayNode.ChildNodesBounds.Top)); + // else + // return new Point(m_Tree.SelectionBoxSize+(m_Tree.Width - m_Tree.SelectionBoxSize * 2 - m_Tree.NodeLayout.Width) / 2 + Math.Abs(displayNode.ChildNodesBounds.Left), + // m_Tree.SelectionBoxSize + (m_Tree.Height - m_Tree.SelectionBoxSize * 2 - m_Tree.NodeLayout.Height) / 2 + Math.Abs(displayNode.ChildNodesBounds.Top)); + //} + //if(m_Tree.NodeLayout is Layout.NodeDiagramLayout) + //{ + // if(!m_Tree.CenterContent) + // return m_Tree.ClientRectangle.Location; + // else + // return new Point((m_Tree.Width-m_Tree.NodeLayout.Width)/2,(m_Tree.Height-m_Tree.NodeLayout.Height)/2); + //} + //else + return m_Tree.ClientRectangle.Location; + } + } + + /// + /// Gets or sets the reference to the tree control managed by display class. + /// + protected virtual AdvTree Tree + { + get {return m_Tree;} + set {m_Tree=value;} + } + [EditorBrowsable(EditorBrowsableState.Never)] + public 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.ExpandHitTestBounds) + { + Rectangle nodeBounds = GetNodeRectangle(eNodeRectanglePart.NodeBounds, node, offset); + + r = node.ExpandPartRectangleRelative; + if (!r.IsEmpty) + { + r.Offset(offset); + r.Offset(node.BoundsRelative.Location); + } + r.Y = nodeBounds.Y; + r.Height = nodeBounds.Height; + r.Inflate(1, 0); + } + 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); + } + } + else if (part == eNodeRectanglePart.ColumnsBounds && HasColumnsVisible(node)) + { + r = node.NodesColumns.Bounds; + if(!r.IsEmpty) + r.Offset(offset); + } + return r; + } + + internal static bool HasColumnsVisible(Node node) + { + return node.Expanded && node.HasColumns && node.NodesColumnsHeaderVisible; + } + + 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); + r.Offset(cell.Parent.BoundsRelative.Location); + } + } + 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.Rectangle: + d = new NodeExpandRectDisplay(); + break; + case eExpandButtonType.Triangle: + d = new NodeExpandTriangleDisplay(); + break; + case eExpandButtonType.Ellipse: + d=new NodeExpandEllipseDisplay(); + 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) + { + System.Windows.Forms.Control cellHostedControl = cell.HostedControl; + if (cellHostedControl == null) continue; + Rectangle bounds = NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds, cell, offset); + Rectangle screenBounds = this.Tree.GetScreenRectangle(bounds); + if (!bounds.IsEmpty && cellHostedControl.Bounds != screenBounds) + { + if (zoom != 1) + { + cell.HostedControlSize = bounds.Size; + cell.IgnoreHostedControlSizeChange = true; + } + else + { + cell.HostedControlSize = Size.Empty; + if (screenBounds.Height > cellHostedControl.Height && cellHostedControl.Height > 0) + { + screenBounds.Y += (screenBounds.Height - cellHostedControl.Height) / 2; + screenBounds.Height = cellHostedControl.Height; + } + } + cellHostedControl.Bounds = screenBounds; + if (zoom != 1) + cell.IgnoreHostedControlSizeChange = false; + if (cell.Parent != null) + { + bool visible = NodeOperations.GetIsNodeVisible(cell.Parent) && cell.IsVisible; + if (visible != cellHostedControl.Visible) + cellHostedControl.Visible = visible; + } + } + } + } + + public ArrayList PaintedNodes + { + get + { + return _PaintedNodes; + } + } + + internal virtual void PaintColumnHeaders(ColumnHeaderCollection columns, Graphics g, bool treeControlHeader) + { + + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandDisplay.cs new file mode 100644 index 00000000..f340c175 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandDisplay.cs @@ -0,0 +1,139 @@ +using System.Drawing; +using System.Drawing.Drawing2D; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree +{ + namespace Display + { + /// + /// Base class for node expand button display. + /// + public abstract class NodeExpandDisplay + { + /// Creates new instance of the class + public NodeExpandDisplay() + { + } + + /// Draws expand button. + /// Context parameters for drawing expand button. + public abstract void DrawExpandButton(NodeExpandPartRendererEventArgs e); + + protected Pen GetBorderPen(NodeExpandPartRendererEventArgs e) + { + if(!e.BorderColor.IsEmpty) + return new Pen(e.BorderColor,1); + if (_ColorTable != null) + { + bool expanded = e.Node.Expanded; + TreeExpandColorTable ct = GetExpandColorTable(e); + if (ct == null) return null; + if (expanded) + { + // Collapse node colors + if (!e.IsMouseOver && ct.CollapseBorder != null) + return ct.CollapseBorder.CreatePen(); + else if (e.IsMouseOver && ct.CollapseMouseOverBorder != null) + return ct.CollapseMouseOverBorder.CreatePen(); + } + else + { + // Expand node colors + if (!e.IsMouseOver && ct.ExpandBorder != null) + return ct.ExpandBorder.CreatePen(); + else if (e.IsMouseOver && ct.ExpandMouseOverBorder != null) + return ct.ExpandMouseOverBorder.CreatePen(); + } + } + return null; + } + + private TreeExpandColorTable GetExpandColorTable(NodeExpandPartRendererEventArgs e) + { + TreeExpandColorTable ct = null; + if (e.ExpandButtonType == eExpandButtonType.Rectangle) + ct = _ColorTable.ExpandRectangle; + else if (e.ExpandButtonType == eExpandButtonType.Triangle) + ct = _ColorTable.ExpandTriangle; + else if (e.ExpandButtonType == eExpandButtonType.Ellipse) + ct = _ColorTable.ExpandEllipse; + return ct; + } + + protected Pen GetExpandPen(NodeExpandPartRendererEventArgs e) + { + if (e.ExpandLineColor.IsEmpty) + { + TreeExpandColorTable ct = GetExpandColorTable(e); + if (ct != null) + { + bool expanded = e.Node.Expanded; + if (expanded) + { + // Collapse node colors + if (!e.IsMouseOver && ct.CollapseForeground != null) + return ct.CollapseForeground.CreatePen(Dpi.Width1); + else if (e.IsMouseOver && ct.CollapseMouseOverForeground != null) + return ct.CollapseMouseOverForeground.CreatePen(Dpi.Width1); + } + else + { + // Collapse node colors + if (!e.IsMouseOver && ct.ExpandForeground != null) + return ct.ExpandForeground.CreatePen(Dpi.Width1); + else if (e.IsMouseOver && ct.ExpandMouseOverForeground != null) + return ct.ExpandMouseOverForeground.CreatePen(Dpi.Width1); + } + } + + return GetBorderPen(e); + } + + return new Pen(e.ExpandLineColor,1); + } + + protected Brush GetBackgroundBrush(NodeExpandPartRendererEventArgs e) + { + if (e.BackColor.IsEmpty && e.BackColor2.IsEmpty) + { + bool expanded = e.Node.Expanded; + TreeExpandColorTable ct = GetExpandColorTable(e); + if (ct == null) return null; + if (expanded) + { + // Collapse node colors + if (!e.IsMouseOver && ct.CollapseFill != null) + return ct.CollapseFill.CreateBrush(e.ExpandPartBounds); + else if (e.IsMouseOver && ct.CollapseMouseOverFill != null) + return ct.CollapseMouseOverFill.CreateBrush(e.ExpandPartBounds); + } + else + { + // Expand node colors + if (!e.IsMouseOver && ct.ExpandFill != null) + return ct.ExpandFill.CreateBrush(e.ExpandPartBounds); + else if (e.IsMouseOver && ct.ExpandMouseOverFill != null) + return ct.ExpandMouseOverFill.CreateBrush(e.ExpandPartBounds); + } + + 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; + } + + private TreeColorTable _ColorTable; + public TreeColorTable ColorTable + { + get { return _ColorTable; } + set { _ColorTable = value; } + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandEllipseDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandEllipseDisplay.cs new file mode 100644 index 00000000..88ec8330 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandEllipseDisplay.cs @@ -0,0 +1,57 @@ +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Represents class that paints elliptical expand button. + /// + public class NodeExpandEllipseDisplay:NodeExpandDisplay + { + /// Draws ellipse type expand button. + /// Expand context drawing information. + public override void DrawExpandButton(NodeExpandPartRendererEventArgs e) + { + if(e.ExpandPartBounds.IsEmpty) + return; + + Brush brush=GetBackgroundBrush(e); + if(brush!=null) + { + e.Graphics.FillEllipse(brush,e.ExpandPartBounds); + brush.Dispose(); + } + + Pen pen=GetBorderPen(e); + if (pen != null) + { + SmoothingMode sm = e.Graphics.SmoothingMode; + e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + e.Graphics.DrawEllipse(pen, e.ExpandPartBounds); + e.Graphics.SmoothingMode = sm; + pen.Dispose(); + pen = null; + } + + if(e.Node.Expanded) + { + pen = GetExpandPen(e); + if (pen != null) + { + e.Graphics.DrawLine(pen, e.ExpandPartBounds.X + 2, e.ExpandPartBounds.Y + e.ExpandPartBounds.Height / 2, e.ExpandPartBounds.Right - 2, e.ExpandPartBounds.Y + e.ExpandPartBounds.Height / 2); + pen.Dispose(); + } + } + else + { + pen = GetExpandPen(e); + if (pen != null) + { + e.Graphics.DrawLine(pen,e.ExpandPartBounds.X+2,e.ExpandPartBounds.Y+e.ExpandPartBounds.Height/2,e.ExpandPartBounds.Right-2,e.ExpandPartBounds.Y+e.ExpandPartBounds.Height/2); + e.Graphics.DrawLine(pen,e.ExpandPartBounds.X+e.ExpandPartBounds.Width/2,e.ExpandPartBounds.Y+2,e.ExpandPartBounds.X+e.ExpandPartBounds.Width/2,e.ExpandPartBounds.Bottom-2); + pen.Dispose(); + } + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandImageDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandImageDisplay.cs new file mode 100644 index 00000000..f581b073 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandImageDisplay.cs @@ -0,0 +1,25 @@ + + +namespace DevComponents.AdvTree.Display +{ + /// + /// Represents expand button display using predefined images. + /// + public class NodeExpandImageDisplay:NodeExpandDisplay + { + /// + /// Draws image type expand button. + /// + /// Expand context information + 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); + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandPartRendererEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandPartRendererEventArgs.cs new file mode 100644 index 00000000..c3ef9ec9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandPartRendererEventArgs.cs @@ -0,0 +1,49 @@ +using System; +using System.Drawing; + +namespace DevComponents.AdvTree +{ + /// + /// Represents event arguments for RenderExpandPart event. + /// + public class NodeExpandPartRendererEventArgs:EventArgs + { + /// + /// Gets or sets reference to Graphics object, canvas node is rendered on. + /// + public System.Drawing.Graphics Graphics=null; + /// + /// Gets or sets the reference to Node object being rendered. + /// + public DevComponents.AdvTree.Node Node=null; + /// Expand part bounds + public Rectangle ExpandPartBounds=Rectangle.Empty; + /// Expand part border color + public Color BorderColor=Color.Empty; + /// Expand part line color + public Color ExpandLineColor=Color.Empty; + /// Expand part background color + public Color BackColor=Color.Empty; + /// Expand part target gradient background color + public Color BackColor2=Color.Empty; + /// Gradient angle + public int BackColorGradientAngle=90; + /// Expand part image when node is expanded + public Image ExpandImage=null; + /// Expand part image when node is collapsed + public Image ExpandImageCollapse=null; + /// Internal support for expand button types + internal eExpandButtonType ExpandButtonType=eExpandButtonType.Ellipse; + /// Gets whether mouse is over expand part + public bool IsMouseOver = false; + + /// + /// Creates new instance of the class and initializes it with default values. + /// + /// Reference to graphics object. + public NodeExpandPartRendererEventArgs(Graphics g) + { + this.Graphics = g; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandRectDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandRectDisplay.cs new file mode 100644 index 00000000..65ba6b8b --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandRectDisplay.cs @@ -0,0 +1,56 @@ +using System; +using System.Drawing; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Represents class that paints rectangular expand button. + /// + public class NodeExpandRectDisplay:NodeExpandDisplay + { + /// + /// Draw rectangular type expand button. + /// + /// Expand button context information. + public override void DrawExpandButton(NodeExpandPartRendererEventArgs e) + { + if(e.ExpandPartBounds.IsEmpty) + return; + + Brush brush=GetBackgroundBrush(e); + if(brush!=null) + { + e.Graphics.FillRectangle(brush,e.ExpandPartBounds); + brush.Dispose(); + } + + Pen pen = GetBorderPen(e); + if (pen != null) + { + e.Graphics.DrawRectangle(pen, e.ExpandPartBounds); + pen.Dispose(); + pen = null; + } + + if(e.Node.Expanded) + { + pen = GetExpandPen(e); + if (pen != null) + { + e.Graphics.DrawLine(pen, e.ExpandPartBounds.X + 2, e.ExpandPartBounds.Y + e.ExpandPartBounds.Height / 2, e.ExpandPartBounds.Right - 2, e.ExpandPartBounds.Y + e.ExpandPartBounds.Height / 2); + pen.Dispose(); + } + } + else + { + pen = GetExpandPen(e); + if (pen != null) + { + e.Graphics.DrawLine(pen,e.ExpandPartBounds.X+2,e.ExpandPartBounds.Y+e.ExpandPartBounds.Height/2,e.ExpandPartBounds.Right-2,e.ExpandPartBounds.Y+e.ExpandPartBounds.Height/2); + e.Graphics.DrawLine(pen,e.ExpandPartBounds.X+e.ExpandPartBounds.Width/2,e.ExpandPartBounds.Y+2,e.ExpandPartBounds.X+e.ExpandPartBounds.Width/2,e.ExpandPartBounds.Bottom-2); + pen.Dispose(); + } + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandTriangleDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandTriangleDisplay.cs new file mode 100644 index 00000000..6df26b02 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeExpandTriangleDisplay.cs @@ -0,0 +1,58 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Display +{ + internal class NodeExpandTriangleDisplay : NodeExpandDisplay + { + /// + /// Draw triangular type expand button. + /// + /// Expand button context information. + public override void DrawExpandButton(NodeExpandPartRendererEventArgs e) + { + if (e.ExpandPartBounds.IsEmpty) + return; + + SmoothingMode sm = e.Graphics.SmoothingMode; + e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + int pw = Dpi.Width5; + Rectangle r = new Rectangle(e.ExpandPartBounds.X , e.ExpandPartBounds.Y + (e.ExpandPartBounds.Height - 8) / 2, pw, Dpi.Height8); + + GraphicsPath path = null; + if (e.Node.Expanded) + { + path = new GraphicsPath(); + path.AddLine(r.X, r.Y + pw, r.X + pw, r.Y); + path.AddLine(r.X + pw, r.Y, r.X + pw, r.Y + pw); + path.CloseAllFigures(); + } + else + { + path = new GraphicsPath(); + path.AddLine(r.X, r.Y, r.X, r.Bottom); + path.AddLine(r.X, r.Bottom, r.X + Dpi.Width4, r.Y + r.Height / 2); + path.CloseAllFigures(); + } + + Brush brush = GetBackgroundBrush(e); + if (brush != null) + { + e.Graphics.FillPath(brush, path); + brush.Dispose(); + } + + Pen pen = GetBorderPen(e); + if(pen!=null) + { + e.Graphics.DrawPath(pen, path); + pen.Dispose(); + } + e.Graphics.SmoothingMode = sm; + if(path!=null) path.Dispose(); + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeGroupLineDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeGroupLineDisplay.cs new file mode 100644 index 00000000..58198541 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeGroupLineDisplay.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using DevComponents.AdvTree.Layout; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Display +{ + internal class NodeGroupLineDisplay + { + private static readonly int LineMargin = 4; + public void DrawGroupLine(NodeRendererEventArgs e) + { + Color lineColor = e.Color; + Node node = e.Node; + + if (lineColor.IsEmpty || lineColor.A == 0 || node.Cells.Count == 0) return; + Graphics g = e.Graphics; + + Rectangle r = node.Bounds; + + Cell lastCell = node.Cells[node.Cells.Count - 1]; + if (lastCell.CheckBoxVisible && CellLayout.GetCheckBoxHorizontalAlign(lastCell.CheckBoxAlignment, true, eView.Tile) == eHorizontalAlign.Right) + { + r.Width -= (lastCell.CheckBoxBounds.Right - r.X) + LineMargin; + r.X = lastCell.CheckBoxBounds.Right + LineMargin; + } + else if (!lastCell.ImageBoundsRelative.IsEmpty && CellLayout.GetHorizontalAlign(lastCell.ImageAlignment, true, eView.Tile) == eHorizontalAlign.Right) + { + r.Width -= (lastCell.ImageBounds.Right - r.X) + LineMargin; + r.X = lastCell.ImageBounds.Right + LineMargin; + } + else if (e.Style.TextAlignment == eStyleTextAlignment.Near) + { + Rectangle textBounds = lastCell.TextBounds; + if (lastCell.TextMarkupBody == null) + textBounds.Width = TextDrawing.MeasureString(g, lastCell.Text, e.Style.Font).Width; + r.Width -= (textBounds.Right - r.X) + LineMargin; + r.X = textBounds.Right + LineMargin; + } + else + return; + + using (Pen pen = new Pen(lineColor, 1)) + { + g.DrawLine(pen, r.X, r.Y + r.Height / 2, r.Right, r.Y + r.Height / 2); + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeRendererEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeRendererEventArgs.cs new file mode 100644 index 00000000..1c9ad961 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeRendererEventArgs.cs @@ -0,0 +1,55 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Summary description for NodeRendererEventArgs. + /// + public class NodeRendererEventArgs:EventArgs + { + /// + /// Gets or sets reference to Graphics object, canvas node is rendered on. + /// + public System.Drawing.Graphics Graphics=null; + /// + /// Gets or sets the reference to Node object being rendered. + /// + public DevComponents.AdvTree.Node Node=null; + /// + /// Gets or sets the absolute node bounds. + /// + public Rectangle NodeBounds=Rectangle.Empty; + /// + /// 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. + /// + public ElementStyle Style=null; + /// + /// Gets or sets color that is passed to renderer. May be Color.Empty. + /// + public Color Color = Color.Empty; + + /// + /// Creates new instance of the class. + /// + public NodeRendererEventArgs() + { + } + + public NodeRendererEventArgs(Graphics g, Node node, Rectangle bounds, ElementStyle style) + : this(g, node, bounds, style, Color.Empty) + { + } + + public NodeRendererEventArgs(Graphics g, Node node, Rectangle bounds, ElementStyle style, Color color) + { + this.Graphics = g; + this.Node = node; + this.NodeBounds = bounds; + this.Style = style; + this.Color = color; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeSelectionDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeSelectionDisplay.cs new file mode 100644 index 00000000..5a41d02b --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeSelectionDisplay.cs @@ -0,0 +1,190 @@ +using System.Drawing; +using DevComponents.WinForms.Drawing; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Represent class that paints selection around node. + /// + internal class NodeSelectionDisplay + { + public void PaintSelection(SelectionRendererEventArgs info) + { + if (info.SelectionBoxStyle == eSelectionStyle.HighlightCells) + PaintHighlightCellsSelectionStyle(info); + else if (info.SelectionBoxStyle == eSelectionStyle.FullRowSelect) + PaintFullRowSelectSelectionStyle(info); + else if (info.SelectionBoxStyle == eSelectionStyle.NodeMarker) + PaintNodeMarkerSelectionStyle(info); + + } + + public void PaintHotTracking(SelectionRendererEventArgs info) + { + // Full row is just a rectangle with the background... + Shape[] fullRowShapes = GetHotTrackingShapes(); + Graphics g = info.Graphics; + Rectangle bounds = info.Bounds; + bounds.Width--; + bounds.Height--; + foreach (Shape shape in fullRowShapes) + { + shape.Paint(g, bounds); + } + } + + private void PaintFullRowSelectSelectionStyle(SelectionRendererEventArgs info) + { + // Full row is just a rectangle with the background... + Shape[] fullRowShapes = GetFullRowShapes(info.TreeActive); + Graphics g = info.Graphics; + Rectangle bounds = info.Bounds; + //bounds.Width--; + //bounds.Height--; + + foreach (Shape shape in fullRowShapes) + { + shape.Paint(g, bounds); + } + } + + Shape[] _FullRowShapes = null; + private Shape[] GetFullRowShapes(bool treeActive) + { + if (_FullRowShapes == null) + { + _FullRowShapes = new Shape[1]; + _FullRowShapes[0] = new RectangleShape(); + } + RectangleShape shape = (RectangleShape)_FullRowShapes[0]; + SelectionColorTable colors = treeActive ? _SelectionColors.FullRowSelect : _SelectionColors.FullRowSelectInactive; + shape.Fill = colors.Fill; + shape.Border = colors.Border; + + return _FullRowShapes; + } + + private void PaintHighlightCellsSelectionStyle(SelectionRendererEventArgs info) + { + // Full row is just a rectangle with the background... + Shape[] fullRowShapes = GetHighlightCellsShapes(info.TreeActive); + Graphics g = info.Graphics; + Rectangle bounds = info.Bounds; + bounds.Width--; + bounds.Height--; + foreach (Shape shape in fullRowShapes) + { + shape.Paint(g, bounds); + } + } + + Shape[] _HighlightCellsShapes = null; + private Shape[] GetHighlightCellsShapes(bool treeActive) + { + SelectionColorTable colorTable = treeActive ? _SelectionColors.HighlightCells : _SelectionColors.HighlightCellsInactive; + + if (_HighlightCellsShapes == null || ((RectangleShape)_HighlightCellsShapes[0]).CornerRadius != null && ((RectangleShape)_HighlightCellsShapes[0]).CornerRadius.TopLeft != colorTable.BorderCornerRadius) + { + _HighlightCellsShapes = new Shape[1]; + RectangleShape rectShape = new RectangleShape(); + if (colorTable.BorderCornerRadius > 0) + { + rectShape.CornerRadius = new CornerRadius(colorTable.BorderCornerRadius); + RectangleShape inner = new RectangleShape(); + rectShape.Content = inner; + } + _HighlightCellsShapes[0] = rectShape; + } + + RectangleShape shape = (RectangleShape)_HighlightCellsShapes[0]; + shape.Fill = colorTable.Fill; + shape.Border = colorTable.Border; + if (shape.Content != null) + { + shape = (RectangleShape)shape.Content; + shape.Border = colorTable.InnerBorder; + } + + return _HighlightCellsShapes; + } + + Shape[] _HotTrackingShapes = null; + private Shape[] GetHotTrackingShapes() + { + if (_HotTrackingShapes == null) + { + _HotTrackingShapes = new Shape[1]; + RectangleShape rectShape = new RectangleShape(); + rectShape.CornerRadius = new CornerRadius(2); + RectangleShape inner = new RectangleShape(); + //inner.CornerRadius = new CornerRadius(2); + rectShape.Content = inner; + _HotTrackingShapes[0] = rectShape; + } + + SelectionColorTable colorTable = _SelectionColors.NodeHotTracking; + RectangleShape shape = (RectangleShape)_HotTrackingShapes[0]; + shape.Fill = colorTable.Fill; + shape.Border = colorTable.Border; + shape = (RectangleShape)shape.Content; + shape.Border = colorTable.InnerBorder; + + return _HotTrackingShapes; + } + + private void PaintNodeMarkerSelectionStyle(SelectionRendererEventArgs info) + { + Rectangle inside = info.Bounds; + int borderWidth = 4; + inside.Inflate(1, 1); + inside.Width--; + inside.Height--; + Rectangle outside = info.Bounds; + outside.Inflate(borderWidth, borderWidth); + outside.Width--; + outside.Height--; + + SelectionColorTable colorTable = info.TreeActive ? _SelectionColors.NodeMarker : _SelectionColors.NodeMarkerInactive; + + if (colorTable.Border != null) + { + Pen pen = colorTable.Border.CreatePen(); + if (pen != null) + { + info.Graphics.DrawRectangle(pen, inside); + info.Graphics.DrawRectangle(pen, outside); + pen.Dispose(); + } + } + + if (colorTable.Fill != null) + { + Brush brush = colorTable.Fill.CreateBrush(outside); + if (brush != null) + { + Region region = new Region(outside); + region.Exclude(inside); + info.Graphics.FillRegion(brush, region); + brush.Dispose(); + } + } + } + + private TreeSelectionColors _SelectionColors = null; + public TreeSelectionColors SelectionColors + { + get { return _SelectionColors; } + set { _SelectionColors = value; } + } + } + + 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; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeSystemRenderer.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeSystemRenderer.cs new file mode 100644 index 00000000..49f17339 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeSystemRenderer.cs @@ -0,0 +1,270 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Represents default system node and cell renderer. + /// + public class NodeSystemRenderer:TreeRenderer + { + #region Private Variables + private NodeExpandEllipseDisplay m_NodeExpandEllipseDisplay=new NodeExpandEllipseDisplay(); + private NodeExpandRectDisplay m_NodeExpandRectDisplay=new NodeExpandRectDisplay(); + private NodeExpandTriangleDisplay m_NodeExpandTriangleDisplay = new NodeExpandTriangleDisplay(); + private NodeExpandImageDisplay m_NodeExpandImageDisplay=new NodeExpandImageDisplay(); + private ElementStyleDisplayInfo m_ElementStyleDisplayInfo=new ElementStyleDisplayInfo(); + private NodeSelectionDisplay m_SelectionDisplay=new NodeSelectionDisplay(); + private LineConnectorDisplay m_LineConnectorDisplay=null; + private DragDropMarkerDisplay m_DragDropMarkerDisplay = new DragDropMarkerDisplay(); + private ColumnHeaderDisplay m_ColumnHeaderDisplay = new ColumnHeaderDisplay(); + private Office2007CheckBoxItemPainter m_CheckBoxPainter = new Office2007CheckBoxItemPainter(); + private NodeGroupLineDisplay _GroupLineDisplay = new NodeGroupLineDisplay(); + #endregion + + #region Internal Implementation + /// + /// Returns ElementStyleDisplayInfo class that provides information for ElementStyle rendering. + /// + /// Reference to style. + /// Reference to graphics object. + /// Style bounds + /// New instance of ElementStyleDisplayInfo + 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.Line: + { + if(m_LineConnectorDisplay==null) + m_LineConnectorDisplay=new LineConnectorDisplay(); + d=m_LineConnectorDisplay; + break; + } + } + return d; + } + + /// + /// 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. + /// + /// Information provided for rendering. + public override void DrawNodeBackground(NodeRendererEventArgs e) + { + ElementStyleDisplayInfo di = GetElementStyleDisplayInfo(e.Style, e.Graphics, e.NodeBounds); + ElementStyleDisplay.Paint(di); + + base.DrawNodeBackground(e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public override void DrawNodeExpandPart(NodeExpandPartRendererEventArgs e) + { + NodeExpandDisplay expandDisplay = GetExpandDisplay(e.ExpandButtonType); + expandDisplay.ColorTable = this.ColorTable; + expandDisplay.DrawExpandButton(e); + expandDisplay.ColorTable = null; + base.DrawNodeExpandPart(e); + } + + private NodeExpandDisplay GetExpandDisplay(eExpandButtonType e) + { + NodeExpandDisplay d=null; + switch(e) + { + case eExpandButtonType.Rectangle: + d=m_NodeExpandRectDisplay; + break; + case eExpandButtonType.Triangle: + d = m_NodeExpandTriangleDisplay; + break; + case eExpandButtonType.Ellipse: + d = m_NodeExpandEllipseDisplay; + break; + case eExpandButtonType.Image: + d= m_NodeExpandImageDisplay; + break; + } + return d; + } + + ///// + ///// 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. + ///// + ///// Information provided for rendering. + //public override void DrawNodeCommandPart(NodeCommandPartRendererEventArgs e) + //{ + // m_NodeCommandDisplay.DrawCommandButton(e); + // base.DrawNodeCommandPart(e); + //} + + /// + /// 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. + /// + /// Information provided for rendering. + public override void DrawCellBackground(NodeCellRendererEventArgs e) + { + ElementStyleDisplayInfo di=GetElementStyleDisplayInfo(e.Style,e.Graphics,DisplayHelp.GetDrawRectangle(e.CellBounds)); + ElementStyleDisplay.Paint(di); + + base.DrawCellBackground(e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public override void DrawCellCheckBox(NodeCellRendererEventArgs e) + { + CellDisplay.CheckBoxPainter = m_CheckBoxPainter; + if (Office2007ColorTable != null) + CellDisplay.ColorTable = Office2007ColorTable.CheckBoxItem; + CellDisplay.PaintCellCheckBox(e); + base.DrawCellCheckBox(e); + CellDisplay.CheckBoxPainter = null; + } + + /// + /// 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. + /// + /// Information provided for rendering. + public override void DrawCellImage(NodeCellRendererEventArgs e) + { + CellDisplay.PaintCellImage(e); + base.DrawCellImage(e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public override void DrawCellText(NodeCellRendererEventArgs e) + { + CellDisplay.PaintText(e); + base.DrawCellText(e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public override void DrawSelection(SelectionRendererEventArgs e) + { + m_SelectionDisplay.SelectionColors = ColorTable.Selection; + m_SelectionDisplay.PaintSelection(e); + base.DrawSelection(e); + } + + /// + /// Draws hot-tracking marker for mouse over node. 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 OnRenderHotTracking method so events can occur. + /// + /// Information provided for rendering. + public override void DrawHotTracking(SelectionRendererEventArgs e) + { + m_SelectionDisplay.SelectionColors = ColorTable.Selection; + m_SelectionDisplay.PaintHotTracking(e); + base.DrawHotTracking(e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public override void DrawConnector(ConnectorRendererEventArgs e) + { + NodeConnectorDisplay display = GetConnectorDisplay(e.NodeConnector); + if(display!=null) + display.DrawConnector(e); + + base.DrawConnector(e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public override void DrawTreeBackground(TreeBackgroundRendererEventArgs e) + { + AdvTree tree = e.AdvTree; + 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); + } + + /// + /// Draws the drag & drop marker that indicates the insertion point for the node. 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 OnRenderDragDropMarker method so events can occur. + /// + /// Information provided for rendering. + public override void DrawDragDropMarker(DragDropMarkerRendererEventArgs e) + { + m_DragDropMarkerDisplay.MarkerColor = this.ColorTable.DragDropMarker; + m_DragDropMarkerDisplay.DrawMarker(e); + base.DrawDragDropMarker(e); + } + + /// + /// Draws the column header. If you need to provide custom rendering this is the method that you should override in your custom renderer. If you + /// do not want default rendering to occur do not call the base implementation. You can call OnRenderColumnHeader method so events can occur. + /// + /// Information provided for rendering. + public override void DrawColumnHeader(ColumnHeaderRendererEventArgs e) + { + ElementStyleDisplayInfo di = GetElementStyleDisplayInfo(e.Style, e.Graphics, e.Bounds); + m_ColumnHeaderDisplay.DrawColumnHeader(e, di); + base.DrawColumnHeader(e); + } + + /// + /// Draws node group line when in tile view. 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 OnRenderTileGroupLine method so events can occur. + /// + /// Information provided for rendering. + public override void DrawTileGroupLine(NodeRendererEventArgs e) + { + _GroupLineDisplay.DrawGroupLine(e); + OnRenderTileGroupLine(e); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/NodeTreeDisplay.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeTreeDisplay.cs new file mode 100644 index 00000000..8653e3a3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/NodeTreeDisplay.cs @@ -0,0 +1,1139 @@ +using System.Drawing; +using System.Drawing.Drawing2D; +using System; +using System.Collections; +using DevComponents.DotNetBar; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Summary description for NodeTreeDisplay. + /// + 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 + /// Creates new instance of the class + /// Object to initialize class with. + public NodeTreeDisplay(AdvTree tree):base(tree) + { + m_SystemRenderer.ColorTable = new TreeColorTable(); + ColorTableInitializer.InitOffice2007Blue(m_SystemRenderer.ColorTable, new ColorFactory()); + } + + public NodeSystemRenderer SystemRenderer + { + get { return m_SystemRenderer; } + set { m_SystemRenderer = value; } + } + + public TreeRenderer GetTreeRenderer() + { + TreeRenderer renderer = m_SystemRenderer; + if (this.Tree.NodeRenderer != null && this.Tree.RenderMode == eNodeRenderMode.Custom) + renderer = this.Tree.NodeRenderer; + if (GlobalManager.Renderer is Office2007Renderer) + { + renderer.Office2007ColorTable = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + renderer.ColorTable = renderer.Office2007ColorTable.AdvTree; + } + + return renderer; + } + + private NodeDisplayContext CreateDisplayContext(Graphics g, Rectangle clipRectangle) + { + NodeDisplayContext context = new NodeDisplayContext(); + context.Graphics = g; + context.DefaultFont = this.Tree.Font; + context.ClipRectangle = clipRectangle; + context.Offset = this.Offset; + context.Styles = this.Tree.Styles; + context.IsBackgroundSelection = IsBackgroundSelection; + context.ClientRectangle = ElementStyleLayout.GetInnerRect(Tree.BackgroundStyle, Tree.ClientRectangle); + context.ColorScheme = Tree.ColorScheme; + context.GridRowLines = Tree.GridRowLines; + context.GridRowLineColor = Tree.GridLinesColor; + context.CellSelection = Tree.SelectionPerCell; + context.AlternateRowBrush = CreateBrush(Tree.AlternateRowColor); + context.DrawAlternateRowBackground = !Tree.AlternateRowColor.IsEmpty; + context.View = this.Tree.View; + context.TileGroupLineColor = this.Tree.TileGroupLineColor; + // Setup rendering + context.NodeRenderer = m_SystemRenderer; + if (this.Tree.NodeRenderer != null && this.Tree.RenderMode == eNodeRenderMode.Custom) + context.NodeRenderer = this.Tree.NodeRenderer; + if (GlobalManager.Renderer is Office2007Renderer) + { + context.NodeRenderer.Office2007ColorTable = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + context.NodeRenderer.ColorTable = context.NodeRenderer.Office2007ColorTable.AdvTree; + } + + 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; + 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.ConnectorDisplayInfo = new ConnectorRendererEventArgs(); + context.ConnectorDisplayInfo.Graphics = context.Graphics; + + // 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; + + // Setup Selection Display + context.SelectionDisplayInfo = new SelectionRendererEventArgs(); + context.SelectionDisplayInfo.Graphics = context.Graphics; + context.SelectionDisplayInfo.SelectionBoxStyle = this.Tree.SelectionBoxStyle; + context.SelectionDisplayInfo.TreeActive = this.Tree.IsKeyboardFocusWithin || !this.Tree.SelectionFocusAware; + + return context; + } + + private Brush CreateBrush(Color color) + { + if (color.IsEmpty) return null; + return new SolidBrush(color); + } + + /// + /// Paints the tree on canvas. + /// + public override void Paint(Graphics g, Rectangle clipRectangle) + { + base.Paint(g,clipRectangle); + + // Setup custom check box images if any + m_CellDisplayInfo.CheckBoxImageChecked = this.Tree.CheckBoxImageChecked; + m_CellDisplayInfo.CheckBoxImageUnChecked = this.Tree.CheckBoxImageUnChecked; + m_CellDisplayInfo.CheckBoxImageIndeterminate = this.Tree.CheckBoxImageIndeterminate; + m_CellDisplayInfo.ItemPaintArgs = new ItemPaintArgs(null, Tree, g, new ColorScheme()); + + // Paint header + if (GlobalManager.Renderer is Office2007Renderer) + { + m_SystemRenderer.Office2007ColorTable = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + m_CellDisplayInfo.ItemPaintArgs.Colors = m_SystemRenderer.Office2007ColorTable.LegacyColors; + m_CellDisplayInfo.ItemPaintArgs.Renderer = GlobalManager.Renderer; + } + // Paint Nodes... + NodeDisplayContext context = CreateDisplayContext(g, clipRectangle); + + 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); + } + + if (context.DrawAlternateRowBackground) + { + PaintAlternateRowBackground(context); + } + + // Paint Grid Lines + if (this.Tree.GridColumnLines && this.Tree.Columns.Count > 0) + { + PaintGridLines(context); + } + + // Paint background for nodes with full row background + if (this.Tree.FullRowBackgroundNodes != null && this.Tree.FullRowBackgroundNodes.Count > 0) + PaintFullRowBackgroundForNodes(context, this.Tree.FullRowBackgroundNodes); + + // Paint selection + if (context.IsBackgroundSelection) + { + PaintSelection(context); + } + if (Tree.HotTracking) + PaintHotTracking(context); + Rectangle innerRect = Tree.GetPaintRectangle(); + Rectangle clientRect = Tree.ClientRectangle; + + if(innerRect == clipRectangle || clientRect == clipRectangle || clipRectangle.IsEmpty) + _PaintedNodes.Clear(); + + 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; + } + if (this.Tree.IsDragDropInProgress && this.Tree.PaintDragDropInsertMarker) + { + PaintDragInsertMarker(context, this.Tree.GetDragInsertionBounds(this.Tree.GetNodeDragInfo())); + } + + if(!context.IsBackgroundSelection) + PaintSelection(context); + + if (context.AlternateRowBrush != null) + { + context.AlternateRowBrush.Dispose(); + context.AlternateRowBrush = null; + } + } + + private void PaintAlternateRowBackground(NodeDisplayContext context) + { + if (this.Tree.DisplayRootNode != null) + { + context.AlternateRowFlag = true; + PaintAlternateRowBackground(context, this.Tree.DisplayRootNode.Nodes); + } + else + { + PaintAlternateRowBackground(context, this.Tree.Nodes); + } + } + + private void PaintAlternateRowBackground(NodeDisplayContext context, NodeCollection nodeCollection) + { + foreach (Node node in nodeCollection) + { + if (!node.Visible) continue; + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, node, context.Offset); + if (r.Y > context.ClientRectangle.Bottom) break; + + if (r.Y >= context.ClientRectangle.Y) + { + if (context.AlternateRowFlag) + { + Rectangle backRect = new Rectangle(context.ClientRectangle.X, r.Y - 1, context.ClientRectangle.Width, r.Height + 1); + context.Graphics.FillRectangle(context.AlternateRowBrush, backRect); + } + } + context.AlternateRowFlag = !context.AlternateRowFlag; + + if (node.Expanded && node.HasChildNodes) PaintAlternateRowBackground(context, node.Nodes); + } + } + + public void ExternalPaintNode(Node node, Graphics g, Rectangle bounds) + { + // Setup custom check box images if any + m_CellDisplayInfo.CheckBoxImageChecked = this.Tree.CheckBoxImageChecked; + m_CellDisplayInfo.CheckBoxImageUnChecked = this.Tree.CheckBoxImageUnChecked; + m_CellDisplayInfo.CheckBoxImageIndeterminate = this.Tree.CheckBoxImageIndeterminate; + + // Paint header + if (GlobalManager.Renderer is Office2007Renderer) + m_SystemRenderer.Office2007ColorTable = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + // Paint Nodes... + NodeDisplayContext context = CreateDisplayContext(g, bounds); + context.ExpandDisplayInfo = null; + context.ConnectorDisplayInfo = null; + + // Update offset + context.Offset = new Point(bounds.X - node.BoundsRelative.X, bounds.Y - node.BoundsRelative.Y); + + PaintSingleNode(node, context); + } + + private void PaintGridLines(NodeDisplayContext context) + { + PaintGridLines(context, Tree.Columns, context.ClientRectangle); + } + + private void PaintGridLines(NodeDisplayContext context, ColumnHeaderCollection columnHeaderCollection, Rectangle bounds) + { + Color color = this.Tree.GridLinesColor.IsEmpty ? context.NodeRenderer.ColorTable.GridLines : this.Tree.GridLinesColor; + Graphics g = context.Graphics; + for (int i = 0; i < columnHeaderCollection.Count; i++) + { + ColumnHeader columnHeader = columnHeaderCollection.ColumnAtDisplayIndex(i); + if (!columnHeader.Visible || columnHeader.Bounds.Width <= 0) continue; + Rectangle r = columnHeader.Bounds; + r.Offset(context.Offset); + if (columnHeaderCollection.ParentNode == null) + { + r.Offset(bounds.Location); + if (!columnHeader.CellsBackColor.IsEmpty) + { + SmoothingMode oldSmoothing = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + Rectangle rBack = new Rectangle(r.X - 5, context.ClientRectangle.Y, r.Width + 4, context.ClientRectangle.Height); + using (SolidBrush brush = new SolidBrush(columnHeader.CellsBackColor)) + g.FillRectangle(brush, rBack); + g.SmoothingMode = oldSmoothing; + } + } + DisplayHelp.DrawLine(g, r.Right - (columnHeader.IsLastVisible ? 0 : 1), bounds.Y, r.Right - (columnHeader.IsLastVisible ? 0 : 1), bounds.Bottom, color, 1); + } + } + + private void PaintFullRowBackgroundForNodes(NodeDisplayContext context, ArrayList nodesCollection) + { + Rectangle clientRectangle = context.ClientRectangle; + if (this.Tree.VScrollBar != null) clientRectangle.Width -= this.Tree.VScrollBar.Width; + + foreach (Node node in nodesCollection) + { + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, node, context.Offset); + + if (!r.IsEmpty) + { + r.X = clientRectangle.X; + r.Width = clientRectangle.Width; + r.Inflate(0, 1); + } + + if (r.IsEmpty || !r.IntersectsWith(context.ClipRectangle) && !context.ClipRectangle.IsEmpty) + continue; + ElementStyle style = GetEffectiveNodeBackgroundStyle(node, context); + if (style == null) + continue; + TreeRenderer renderer = context.NodeRenderer; + if (node.NodeRenderer != null && node.RenderMode == eNodeRenderMode.Custom) + renderer = node.NodeRenderer; + if (style != null) + { + context.NodeRendererEventArgs.Graphics = context.Graphics; + context.NodeRendererEventArgs.Node = node; + context.NodeRendererEventArgs.NodeBounds = r; + context.NodeRendererEventArgs.Style = style; + renderer.DrawNodeBackground(context.NodeRendererEventArgs); + } + } + } + + private void PaintDragInsertMarker(NodeDisplayContext context, Rectangle dragInsertionBounds) + { + if (dragInsertionBounds.IsEmpty) return; + context.NodeRenderer.DrawDragDropMarker(new DragDropMarkerRendererEventArgs(context.Graphics, dragInsertionBounds)); + } + + public bool IsBackgroundSelection + { + get { return this.Tree.SelectionBoxStyle != eSelectionStyle.NodeMarker; } + } + + private void PaintSelection(NodeDisplayContext context) + { + if (!this.Tree.MultiSelect && this.Tree.SelectedNode != null && this.Tree.SelectedNode.Visible && this.Tree.SelectionBox && !(this.Tree.HideSelection && !this.Tree.Focused)) + { + PaintNodeSelection(this.Tree.SelectedNode, context); + } + else if (this.Tree.MultiSelect && this.Tree.SelectedNodes.Count>0 && this.Tree.SelectionBox && !(this.Tree.HideSelection && !this.Tree.Focused)) + { + foreach (Node node in Tree.SelectedNodes) + { + if(node.IsVisible) + PaintNodeSelection(node, context); + } + } + } + + private void PaintNodeSelection(Node node, NodeDisplayContext context) + { + if (!node.IsSelectionVisible) return; + + context.SelectionDisplayInfo.Node = node; + Rectangle r; + if (this.Tree.SelectionBoxStyle == eSelectionStyle.FullRowSelect) + { + if (context.CellSelection) + { + Cell cell = context.SelectionDisplayInfo.Node.SelectedCell != null ? context.SelectionDisplayInfo.Node.SelectedCell : context.SelectionDisplayInfo.Node.Cells[0]; + r = NodeDisplay.GetCellRectangle(eCellRectanglePart.CellBounds, + cell, context.Offset); + } + else + { + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, context.SelectionDisplayInfo.Node, context.Offset); + r.X = context.ClientRectangle.X; + r.Width = context.ClientRectangle.Width; + } + if(context.GridRowLines) + r.Inflate(0, (int)Math.Floor((float)Tree.NodeSpacing / 2)); + else + r.Inflate(0, (int)Math.Ceiling((float)Tree.NodeSpacing / 2)); + } + else if (this.Tree.SelectionBoxStyle == eSelectionStyle.HighlightCells) + { + if (context.CellSelection) + { + Cell cell = context.SelectionDisplayInfo.Node.SelectedCell != null ? context.SelectionDisplayInfo.Node.SelectedCell : context.SelectionDisplayInfo.Node.Cells[0]; + r = NodeDisplay.GetCellRectangle(eCellRectanglePart.CellBounds, + cell, context.Offset); + } + else + { + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.CellsBounds, context.SelectionDisplayInfo.Node, context.Offset); + } + r.Inflate(2, 2); + if (r.Right > context.ClientRectangle.Right) + r.Width -= (r.Right - context.ClientRectangle.Right); + + } + else + { + if (context.CellSelection) + { + Cell cell = context.SelectionDisplayInfo.Node.SelectedCell != null ? context.SelectionDisplayInfo.Node.SelectedCell : context.SelectionDisplayInfo.Node.Cells[0]; + r = NodeDisplay.GetCellRectangle(eCellRectanglePart.CellBounds, + cell, context.Offset); + } + else + { + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, context.SelectionDisplayInfo.Node, context.Offset); + } + } + + context.SelectionDisplayInfo.Bounds = r; + context.NodeRenderer.DrawSelection(context.SelectionDisplayInfo); + } + + private void PaintHotTracking(NodeDisplayContext context) + { + Node node = this.Tree.MouseOverNode; + if (node != null && !node.IsSelected && node.Selectable) + { + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.CellsBounds, node, context.Offset); + r.Inflate(2, 2); + context.SelectionDisplayInfo.Node = node; + context.SelectionDisplayInfo.Bounds = r; + context.NodeRenderer.DrawHotTracking(context.SelectionDisplayInfo); + } + } + + private Node PaintNodes(NodeCollection nodes, NodeDisplayContext context) + { + Node lastPainted = null; + int count = nodes.Count; + int start = 0; + + // Find first node to render in case there are lot of them + if (context.View == eView.Tree && count > 99 && /*this.Tree.NodesConnector == null &&*/ context.Offset.Y != 0) + { + int testIndex = count / 2; + int chunk = testIndex; + while (testIndex > 0 && testIndex < count) + { + chunk = chunk / 2; + Node node = nodes[testIndex]; + if (!node.Visible) + { + int ti = testIndex + 1; + while (ti < count) + { + node = nodes[ti]; + ti++; + if (node.Visible) break; + } + if (!node.Visible) + { + ti = testIndex - 1; + while (ti >= 0) + { + node = nodes[ti]; + ti--; + if (node.Visible) break; + } + } + } + if (!node.Visible) + { + start = 0; + break; + } + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, node, context.Offset); + if (chunk > 0 && r.Y > context.ClipRectangle.Bottom) // go back + testIndex -= chunk; + else if (chunk > 0 && r.Y < context.ClipRectangle.Y) // go forward + testIndex += chunk; + else + { + if (testIndex == 0) break; + testIndex--; + for (int i = testIndex; i >= 0; i--) + { + node = nodes[i]; + if (!node.Visible) continue; + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, node, context.Offset); + if (r.Y < context.ClipRectangle.Y) + { + start = i; + break; + } + } + break; + } + } + } + + bool clipEmpty = context.ClipRectangle.IsEmpty; + for (int i = start; i < count; i++) + { + Node node = nodes[i]; + if (PaintNode(node, context)) + { + lastPainted = node; + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, node, context.Offset); + if (!clipEmpty && r.Y > context.ClipRectangle.Bottom && !context.ClientRectangle.IsEmpty) + break; + } + } + return lastPainted; + } + + private bool PaintNode(Node node, NodeDisplayContext context) + { + if(!node.Visible) + { + node.SelectedConnectorMarker = false; + return false; + } + + Rectangle r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,node,context.Offset); + if(r.IsEmpty) + { + node.SelectedConnectorMarker = false; + return false; + } + + if (context.GridRowLines && !node.IsDragNode) + { + DisplayHelp.DrawLine(context.Graphics, context.ClientRectangle.X, r.Bottom+1, context.ClientRectangle.Right, r.Bottom+1, context.GridRowLineColor, 1); + } + + bool paintChildNodes = (node.Expanded && node.Nodes.Count > 0); + + if (!node.IsDragNode && (node.Parent != null || node.ExpandVisibility != eNodeExpandVisibility.Hidden)) + this.PaintConnector(null, node, context, false); + + if (paintChildNodes) + { + Node lastChildNode = NodeOperations.GetLastVisibleChildNode(node); + if (lastChildNode != null) + this.PaintConnector(node, lastChildNode, context, false); + } + + node.SelectedConnectorMarker = false; + + if (NodeDisplay.HasColumnsVisible(node)) + { + r.Height += node.ColumnHeaderHeight; + r.Width = Math.Max(r.Width, node.NodesColumns.Bounds.Width); + } + if (r.Y >= context.ClipRectangle.Y && r.Y <= context.ClipRectangle.Bottom || + r.Bottom >= context.ClipRectangle.Y && r.Bottom <= context.ClipRectangle.Bottom || + r.Y <= context.ClipRectangle.Y && r.Bottom > context.ClipRectangle.Y || + context.ClipRectangle.IsEmpty) + PaintSingleNode(node, context); + + if (paintChildNodes) + { + PaintNodes(node.Nodes, context); + } + + return true; + } + + private ElementStyle GetEffectiveNodeBackgroundStyle(Node node, NodeDisplayContext context) + { + ElementStyle style = context.DefaultNodeStyle.Copy(); + + bool bApplyStyles = true; + bool isSelected = (node.IsSelected && node.IsSelectionVisible); + + if (isSelected && context.SelectedNodeStyle == null && node.StyleSelected == null && !node.FullRowBackground) bApplyStyles = false; + + if (isSelected && (context.SelectedNodeStyle == null || context.SelectedNodeStyle.TextColor.IsEmpty) && + (node.StyleSelected == null || node.StyleSelected.TextColor.IsEmpty)) + { + eSelectionStyle ss = Tree.SelectionBoxStyle; + TreeSelectionColors table = context.NodeRenderer.ColorTable.Selection; + if (context.SelectionDisplayInfo.TreeActive) + { + if (ss == eSelectionStyle.FullRowSelect && !table.FullRowSelect.TextColor.IsEmpty) + style.TextColor = table.FullRowSelect.TextColor; + else if (ss == eSelectionStyle.HighlightCells && !table.HighlightCells.TextColor.IsEmpty) + style.TextColor = table.HighlightCells.TextColor; + else if (ss == eSelectionStyle.NodeMarker && !table.NodeMarker.TextColor.IsEmpty) + style.TextColor = table.NodeMarker.TextColor; + } + else + { + if (ss == eSelectionStyle.FullRowSelect && !table.FullRowSelectInactive.TextColor.IsEmpty) + style.TextColor = table.FullRowSelectInactive.TextColor; + else if (ss == eSelectionStyle.HighlightCells && !table.HighlightCellsInactive.TextColor.IsEmpty) + style.TextColor = table.HighlightCellsInactive.TextColor; + else if (ss == eSelectionStyle.NodeMarker && !table.NodeMarkerInactive.TextColor.IsEmpty) + style.TextColor = table.NodeMarkerInactive.TextColor; + } + + } + else if (this.Tree.HotTracking && !node.IsSelected && node.Selectable && this.Tree.MouseOverNode == node) + { + SelectionColorTable table = context.NodeRenderer.ColorTable.Selection.NodeHotTracking; + if (!table.TextColor.IsEmpty) + style.TextColor = table.TextColor; + } + + if (node.Style != null) + { + if (bApplyStyles) + style.ApplyStyle(node.Style); //=node.Style.Copy(); + else + style.ApplyFontStyle(node.Style); + } + + if (bApplyStyles && node.MouseOverNodePart == eMouseOverNodePart.Node && style != null) + { + ElementStyle mouseOverStyle = context.MouseOverNodeStyle; + if (node.StyleMouseOver != null) + { + mouseOverStyle = node.StyleMouseOver; + bApplyStyles = false; + } + if (mouseOverStyle != null) + { + style.ApplyStyle(mouseOverStyle); + bApplyStyles = false; + } + } + + // On default style apply expanded style + if (bApplyStyles && 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 (bApplyStyles && node.IsSelected && style != null) + { + ElementStyle selectedStyle = context.SelectedNodeStyle; + if (node.StyleSelected != null) + selectedStyle = node.StyleSelected; + if (selectedStyle != null) + style.ApplyStyle(selectedStyle); + } + + if (style != null) + { + if (style.Font == null) + style.Font = context.DefaultFont; + } + + return style; + } + + private void PaintSingleNode(Node node, NodeDisplayContext context) + { + _PaintedNodes.Add(node); + Rectangle r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,node,context.Offset); + TreeRenderer renderer=context.NodeRenderer; + if(node.NodeRenderer!=null && node.RenderMode==eNodeRenderMode.Custom) + renderer = node.NodeRenderer; + bool isSelected = node.IsSelectionVisible && node.IsSelected; + + // Paint node background + ElementStyle style = GetEffectiveNodeBackgroundStyle(node, context); + + Region backRegion=null; + if(style!=null) + { + context.NodeRendererEventArgs.Graphics=context.Graphics; + context.NodeRendererEventArgs.Node = node; + context.NodeRendererEventArgs.NodeBounds = r; + context.NodeRendererEventArgs.Style = style; + if (!node.FullRowBackground) // Node full row backgrounds are drawn first... + renderer.DrawNodeBackground(context.NodeRendererEventArgs); + ElementStyleDisplayInfo di = new ElementStyleDisplayInfo(style, context.Graphics, context.NodeRendererEventArgs.NodeBounds); + di.Bounds.Inflate(1, 1); + backRegion=ElementStyleDisplay.GetStyleRegion(di); + di.Bounds = r; + } + + if (NodeDisplay.DrawExpandPart(node) && context.ExpandDisplayInfo != null) + { + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds, node, context.Offset); + context.ExpandDisplayInfo.Node = node; + context.ExpandDisplayInfo.ExpandPartBounds = r; + context.ExpandDisplayInfo.IsMouseOver = node.MouseOverNodePart == eMouseOverNodePart.Expand; + renderer.DrawNodeExpandPart(context.ExpandDisplayInfo); + } + + if (NodeDisplay.HasColumnsVisible(node)) + { + PaintColumnHeaders(node.NodesColumns, context.Graphics, false); + } + + Region oldRegion=null; + if(backRegion!=null) + { + oldRegion=context.Graphics.Clip; + context.Graphics.SetClip(backRegion,CombineMode.Intersect); + } + + 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.TextTrimming = style.TextTrimming; + cellStyle.WordWrap = style.WordWrap; + cellStyle.Font = style.Font; + cellStyle.UseMnemonic = style.UseMnemonic; + } + + foreach(Cell cell in node.Cells) + { + if (!cell.IsVisible) continue; + if (cell.StyleNormal != null) + { + if (context.CellStyleDefault != null) + style = context.CellStyleDefault.Copy(); + else + style = cellStyle.Copy(); + style.ApplyStyle(cell.StyleNormal); + } + else if (context.CellStyleDefault != null) + style = context.CellStyleDefault.Copy(); + else + { + if (!cell.Enabled || cell.IsMouseDown && (cell.StyleMouseDown != null || context.CellStyleMouseDown != null) || + cell.IsSelected && (cell.StyleSelected != null || context.CellStyleSelected != null) || + cell.IsMouseOver && (cell.StyleMouseOver != null || context.CellStyleMouseOver != null)) + style = cellStyle.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 && context.CellStyleSelected.Custom) + style.ApplyStyle(context.CellStyleSelected); + else if (isSelected && !cell.IsSelected && this.Tree.SelectionPerCell) + style.TextColor = context.DefaultNodeStyle.TextColor; + + 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; + if (isSelected) + { + style.BackColor = Color.Empty; + style.BackColorSchemePart = eColorSchemePart.None; + style.BackColor2 = Color.Empty; + style.BackColor2SchemePart = eColorSchemePart.None; + } + + Rectangle rCell=cell.BoundsRelative; + Rectangle rText=cell.TextContentBounds; + rCell.Offset(r.Location); + rText.Offset(r.Location); + ElementStyleDisplayInfo di=GetElementStyleDisplayInfo(style,context.Graphics,rCell); + ElementStyleDisplay.Paint(di); + NodeCellRendererEventArgs ci=GetCellDisplayInfo(style,context.Graphics,cell,r.Location, context.ColorScheme); + + if(ci.Cell.CheckBoxVisible) + renderer.DrawCellCheckBox(ci); + if(!ci.Cell.Images.LargestImageSize.IsEmpty) + renderer.DrawCellImage(ci); + renderer.DrawCellText(ci); + if (context.View == eView.Tile && node.HasChildNodes && !context.TileGroupLineColor.IsEmpty) + renderer.DrawTileGroupLine(new NodeRendererEventArgs(context.Graphics, node, r, style, context.TileGroupLineColor)); + } + } + + if (backRegion != null) + { + context.Graphics.SetClip(oldRegion, CombineMode.Replace); + backRegion.Dispose(); + } + if(oldRegion!=null) oldRegion.Dispose(); + } + + 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 = fromNode != null ? IsRootNode(fromNode) : IsRootNode(toNode); + + if (context.View == eView.Tile || isRootNode && fromNode == null && toNode.Nodes.Count == 0 && toNode.ExpandVisibility != eNodeExpandVisibility.Visible || context.ConnectorDisplayInfo == null) + return; + + context.ConnectorDisplayInfo.FromNode=fromNode; + context.ConnectorDisplayInfo.ToNode=toNode; + context.ConnectorDisplayInfo.IsRootNode=isRootNode; + context.ConnectorDisplayInfo.LinkConnector=linkConnector; + if (fromNode != null && 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; + + /*if(linkConnector) + { + context.ConnectorDisplayInfo.NodeConnector=this.Tree.LinkConnector; + } + else*/ if(toNode.SelectedConnectorMarker) + { + context.ConnectorDisplayInfo.NodeConnector=this.Tree.SelectedPathConnector; + } + else if(toNode.ParentConnector!=null) + { + context.ConnectorDisplayInfo.NodeConnector=toNode.ParentConnector; + } + //else if(isRootNode) + //{ + // context.ConnectorDisplayInfo.NodeConnector=this.Tree.RootConnector; + //} + else + { + context.ConnectorDisplayInfo.NodeConnector=this.Tree.NodesConnector; + } + + if(linkConnector) + { + context.ConnectorDisplayInfo.ConnectorPoints=connectorPoints; + } + else + { + if(connectorPoints!=null) + context.ConnectorDisplayInfo.ConnectorPoints=connectorPoints; + else + context.ConnectorDisplayInfo.ConnectorPoints=null; + } + + context.NodeRenderer.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, ColorScheme cs) + { + m_CellDisplayInfo.Cell=cell; + m_CellDisplayInfo.Graphics=g; + m_CellDisplayInfo.Style=style; + m_CellDisplayInfo.CellOffset=cellOffset; + m_CellDisplayInfo.ColorScheme = cs; + return m_CellDisplayInfo; + } + internal override void PaintColumnHeaders(ColumnHeaderCollection columns, Graphics g, bool treeControlHeader) + { + // Setup rendering + TreeRenderer renderer = m_SystemRenderer; + if (this.Tree.NodeRenderer != null && this.Tree.RenderMode == eNodeRenderMode.Custom) + renderer = this.Tree.NodeRenderer; + //else if (this.Tree.RenderMode == eNodeRenderMode.Professional) + // renderer = m_ProfRenderer; + PaintColumnHeaders(renderer, columns, g, treeControlHeader); + } + + internal void PaintColumnHeaders(TreeRenderer renderer, ColumnHeaderCollection columns, Graphics g, bool treeControlHeader) + { + ColumnHeaderRendererEventArgs ce = new ColumnHeaderRendererEventArgs(); + ce.Graphics = g; + ce.Tree = this.Tree; + ce.SortIndicatorColor = renderer.ColorTable.ColumnSortIndicatorColor; + + ElementStyle defaultNormalStyle = GetDefaultColumnStyleNormal(renderer); + ElementStyle headerStyle = null; + if(treeControlHeader) + headerStyle = this.Tree.ColumnsBackgroundStyle == null ? GetDefaultHeaderStyle(renderer) : this.Tree.ColumnsBackgroundStyle; + else + headerStyle = this.Tree.NodesColumnsBackgroundStyle == null ? GetDefaultNodesHeaderStyle(renderer) : this.Tree.NodesColumnsBackgroundStyle; + + if (Tree.ColumnStyleNormal != null && Tree.ColumnStyleNormal.Custom) + defaultNormalStyle = Tree.ColumnStyleNormal; + + Point offset = Point.Empty; + if (this.Tree.AutoScroll) + { + offset = this.Tree.GetAutoScrollPositionOffset(); + if (treeControlHeader) + offset.Y = 0; + } + + Rectangle columnsBounds = columns.Bounds; + if (!treeControlHeader) columnsBounds.Offset(offset); + ElementStyleDisplayInfo di = new ElementStyleDisplayInfo(headerStyle, g, columnsBounds); + ElementStyleDisplay.Paint(di); + Color columnSeparator = (headerStyle != null && !headerStyle.BorderColor.IsEmpty) ? headerStyle.BorderColor : Color.Empty; + for (int i = 0; i < columns.Count; i++) + { + ColumnHeader column = columns.ColumnAtDisplayIndex(i); + if (!column.Visible) continue; + ElementStyle style = null; + if (column.StyleNormal != "") + style = Tree.Styles[column.StyleNormal].Copy(); + else + style = defaultNormalStyle.Copy(); + + if (column.IsMouseDown) + { + if (column.StyleMouseDown != "") + style.ApplyStyle(Tree.Styles[column.StyleMouseDown]); + else if (Tree.ColumnStyleMouseDown != null) + style.ApplyStyle(Tree.ColumnStyleMouseDown); + } + else if (column.IsMouseOver) + { + if (column.StyleMouseOver != "") + style.ApplyStyle(Tree.Styles[column.StyleMouseOver]); + else if (Tree.ColumnStyleMouseOver != null) + style.ApplyStyle(Tree.ColumnStyleMouseOver); + } + + ce.ColumnHeader = column; + Rectangle columnBounds = column.Bounds; + columnBounds.Offset(offset); + ce.Bounds = columnBounds; + ce.Style = style; + renderer.DrawColumnHeader(ce); + if (!columnSeparator.IsEmpty) + DisplayHelp.DrawLine(g, columnBounds.Right - (column.IsLastVisible ? 0 : 1), columnBounds.Y, columnBounds.Right - (column.IsLastVisible ? 0 : 1), columnBounds.Bottom - 1, columnSeparator, 1); + } + } + + private ElementStyle GetDefaultHeaderStyle(TreeRenderer renderer) + { + if (renderer != null && renderer.Office2007ColorTable != null) + { + return renderer.Office2007ColorTable.StyleClasses[ElementStyleClassKeys.TreeColumnsHeaderKey] as ElementStyle; + } + else + { + ElementStyle style = new ElementStyle(); + style.BackColor = ColorScheme.GetColor(0xF9FCFD); + style.BackColor2 = ColorScheme.GetColor(0xD3DBE9); + style.BackColorGradientAngle = 90; + style.TextColor = ColorScheme.GetColor(0x000000); + style.BorderColor = ColorScheme.GetColor(0x9EB6CE); + style.BorderBottom = eStyleBorderType.Solid; + style.BorderBottomWidth = 1; + return style; + } + } + + private ElementStyle GetDefaultNodesHeaderStyle(TreeRenderer renderer) + { + if (renderer != null && renderer.Office2007ColorTable != null) + { + return renderer.Office2007ColorTable.StyleClasses[ElementStyleClassKeys.TreeNodesColumnsHeaderKey] as ElementStyle; + } + else + { + ElementStyle style = new ElementStyle(); + style.BackColor = ColorScheme.GetColor(0xF9FCFD); + style.BackColor2 = ColorScheme.GetColor(0xD3DBE9); + style.BackColorGradientAngle = 90; + style.TextColor = ColorScheme.GetColor(0x000000); + style.BorderColor = ColorScheme.GetColor(0x9EB6CE); + style.BorderBottom = eStyleBorderType.Solid; + style.BorderBottomWidth = 1; + style.BorderLeft = eStyleBorderType.Solid; + style.BorderLeftWidth = 1; + style.BorderTop = eStyleBorderType.Solid; + style.BorderTopWidth = 1; + return style; + } + } + + private ElementStyle GetDefaultColumnStyleNormal(TreeRenderer renderer) + { + if (renderer != null && renderer.Office2007ColorTable != null) + { + return renderer.Office2007ColorTable.StyleClasses[ElementStyleClassKeys.TreeColumnKey] as ElementStyle; + } + else + { + ElementStyle style = new ElementStyle(); + style.TextColor = ColorScheme.GetColor(0x000000); + return style; + } + } + +// 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 TreeRenderer NodeRenderer=null; + public NodeRendererEventArgs NodeRendererEventArgs=null; + public bool IsBackgroundSelection = false; + public Rectangle ClientRectangle = Rectangle.Empty; + public ColorScheme ColorScheme = null; + public bool GridRowLines = false; + public Color GridRowLineColor = Color.Empty; + public bool CellSelection = false; + public Brush AlternateRowBrush = null; + public bool DrawAlternateRowBackground = false; + public bool AlternateRowFlag = false; + public eView View = eView.Tree; + public Color TileGroupLineColor = Color.Empty; + } + + + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/SelectionColorTable.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/SelectionColorTable.cs new file mode 100644 index 00000000..411e30aa --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/SelectionColorTable.cs @@ -0,0 +1,34 @@ +using System; +using System.Text; +using DevComponents.WinForms.Drawing; +using System.Drawing; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Defines the color table for tree selection. + /// + public class SelectionColorTable + { + /// + /// Gets or sets the outer border for the selection. + /// + public Border Border = null; + /// + /// Gets or sets the outer border corner radius. + /// + public int BorderCornerRadius = 0; + /// + /// Gets or sets the inner border for the selection. + /// + public Border InnerBorder = null; + /// + /// Gets or sets the selection fill. + /// + public Fill Fill = null; + /// + /// Gets or sets the selection text color. + /// + public Color TextColor = Color.Empty; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/SelectionRendererEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/SelectionRendererEventArgs.cs new file mode 100644 index 00000000..e0475495 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/SelectionRendererEventArgs.cs @@ -0,0 +1,32 @@ +using System; +using System.Drawing; + +namespace DevComponents.AdvTree +{ + /// + /// Data form RenderSelection event. + /// + public class SelectionRendererEventArgs : EventArgs + { + /// + /// Gets or sets reference to Graphics object, canvas node is rendered on. + /// + public System.Drawing.Graphics Graphics=null; + /// + /// Gets or sets the reference to selected Node object. + /// + public DevComponents.AdvTree.Node Node=null; + /// + /// Gets or sets the selection bounds. + /// + public Rectangle Bounds=Rectangle.Empty; + /// + /// Gets or sets the node selection box style. + /// + public eSelectionStyle SelectionBoxStyle = eSelectionStyle.HighlightCells; + /// + /// Gets or sets whether tree control is active, focused. + /// + public bool TreeActive = false; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/TreeBackgroundRendererEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeBackgroundRendererEventArgs.cs new file mode 100644 index 00000000..79f82314 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeBackgroundRendererEventArgs.cs @@ -0,0 +1,31 @@ +using System; +using System.Drawing; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Provides data for tree background rendering events. + /// + public class TreeBackgroundRendererEventArgs + { + /// + /// Gets or sets reference to Graphics object, canvas tree background is rendered on. + /// + public System.Drawing.Graphics Graphics=null; + + /// + /// Gets or sets the reference to AdvTree control. + /// + public AdvTree AdvTree = null; + + /// + /// Creates new instance of the class and initializes it with default values. + /// + /// Reference to graphics object. + public TreeBackgroundRendererEventArgs(Graphics g, AdvTree tree) + { + this.Graphics = g; + this.AdvTree = tree; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/TreeColorTable.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeColorTable.cs new file mode 100644 index 00000000..fdcd7717 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeColorTable.cs @@ -0,0 +1,45 @@ +using System; +using System.Text; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Defines the Tree color table. + /// + [ToolboxItem(false)] + public class TreeColorTable : Component + { + #region Internal Implementation + /// + /// Gets or sets the color table used for the node selection display. + /// + public TreeSelectionColors Selection = new TreeSelectionColors(); + /// + /// Gets or sets the color for node drag & drop marker. + /// + public Color DragDropMarker = Color.Black; + /// + /// Gets or sets the color of tree expand button type of rectangle. + /// + public TreeExpandColorTable ExpandRectangle = new TreeExpandColorTable(); + /// + /// Gets or sets the color of tree expand button type of Ellipse. + /// + public TreeExpandColorTable ExpandEllipse = new TreeExpandColorTable(); + /// + /// Gets or sets the color of tree expand button type of Triangle. + /// + public TreeExpandColorTable ExpandTriangle = new TreeExpandColorTable(); + /// + /// Gets or sets the color for tree grid lines. + /// + public Color GridLines = Color.Empty; + /// + /// Gets or sets the color of the column sort indicator which is rendered on columns when sorted. + /// + public Color ColumnSortIndicatorColor = Color.Gray; + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/TreeExpandColorTable.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeExpandColorTable.cs new file mode 100644 index 00000000..a079d19a --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeExpandColorTable.cs @@ -0,0 +1,61 @@ +using System; +using System.Text; +using DevComponents.WinForms.Drawing; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Defines the color table for node expand button. + /// + public class TreeExpandColorTable + { + /// + /// Gets or sets the border for the expand button which expands the node. + /// + public Border ExpandBorder = null; + /// + /// Gets or sets the expand button fill for button that expands the node. + /// + public Fill ExpandFill = null; + /// + /// Gets or sets the expand button foreground for button that expands the node. + /// + public Fill ExpandForeground = null; + /// + /// Gets or sets the border for the expand button which expands the node. + /// + public Border ExpandMouseOverBorder = null; + /// + /// Gets or sets the expand button fill for button that expands the node. + /// + public Fill ExpandMouseOverFill = null; + /// + /// Gets or sets the expand button foreground for button that expands the node. + /// + public Fill ExpandMouseOverForeground = null; + /// + /// Gets or sets the border for the expand button which collapses the node. + /// + public Border CollapseBorder = null; + /// + /// Gets or sets the expand button fill for button that collapses the node. + /// + public Fill CollapseFill = null; + /// + /// Gets or sets the expand button foreground for button that expands the node. + /// + public Fill CollapseForeground = null; + /// + /// Gets or sets the border for the expand button which collapses the node. + /// + public Border CollapseMouseOverBorder = null; + /// + /// Gets or sets the expand button fill for button that collapses the node. + /// + public Fill CollapseMouseOverFill = null; + /// + /// Gets or sets the expand button foreground for button that expands the node. + /// + public Fill CollapseMouseOverForeground = null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/TreeRenderer.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeRenderer.cs new file mode 100644 index 00000000..62fcbebb --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeRenderer.cs @@ -0,0 +1,386 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Represents abstract renderer class for node objects. + /// + public abstract class TreeRenderer + { + #region Events + /// + /// Occurs when node background is being drawn. + /// + public event NodeRendererEventHandler RenderNodeBackground; + /// + /// Occurs when node expand part is being drawn. + /// + public event NodeExpandPartRendererEventHandler RenderNodeExpandPart; + ///// + ///// Occurs when node command part is being drawn. + ///// + //public event NodeCommandPartRendererEventHandler RenderNodeCommandPart; + /// + /// Occurs when cell background is being drawn. + /// + public event NodeCellRendererEventHandler RenderCellBackground; + /// + /// Occurs when cell check-box is being drawn. + /// + public event NodeCellRendererEventHandler RenderCellCheckBox; + /// + /// Occurs when cell image is being drawn. + /// + public event NodeCellRendererEventHandler RenderCellImage; + /// + /// Occurs when cell text is being drawn. + /// + public event NodeCellRendererEventHandler RenderCellText; + /// + /// Occurs when node selection marker is rendered. + /// + public event SelectionRendererEventHandler RenderSelection; + /// + /// Occurs when node hot-tracking marker is rendered. + /// + public event SelectionRendererEventHandler RenderHotTracking; + /// + /// Occurs when node connector is being drawn. + /// + public event ConnectorRendererEventHandler RenderConnector; + + /// + /// Occurs when tree background is rendered. + /// + public event TreeBackgroundRendererEventHandler RenderTreeBackground; + + /// + /// Occurs when drag & drop marker is rendered. + /// + public event DragDropMarkerRendererEventHandler RenderDragDropMarker; + /// + /// Renders the Column Header. + /// + public event ColumnHeaderRendererEventHandler RenderColumnHeader; + /// + /// Occurs when node group line is being rendered while control is in tile view. + /// + public event NodeRendererEventHandler RenderTileGroupLine; + #endregion + + #region Private Variables + #endregion + + #region Constructor + public TreeRenderer() + { + } + #endregion + + #region Internal Implementation + /// + /// 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. + /// + /// Information provided for rendering. + public virtual void DrawNodeBackground(NodeRendererEventArgs e) + { + OnRenderNodeBackground(e); + } + + /// + /// Raises RenderNodeBackground event. + /// + /// Event arguments. + protected virtual void OnRenderNodeBackground(NodeRendererEventArgs e) + { + if(RenderNodeBackground!=null) + RenderNodeBackground(this,e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public virtual void DrawNodeExpandPart(NodeExpandPartRendererEventArgs e) + { + OnRenderNodeExpandPart(e); + } + + /// + /// Raises RenderNodeExpandPart event. + /// + /// + protected virtual void OnRenderNodeExpandPart(NodeExpandPartRendererEventArgs e) + { + if(RenderNodeExpandPart!=null) + RenderNodeExpandPart(this,e); + } + + ///// + ///// 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. + ///// + ///// Information provided for rendering. + //public virtual void DrawNodeCommandPart(NodeCommandPartRendererEventArgs e) + //{ + // OnRenderNodeCommandPart(e); + //} + + ///// + ///// Raises RenderNodeCommandPart event. + ///// + ///// Event arguments. + //protected virtual void OnRenderNodeCommandPart(NodeCommandPartRendererEventArgs e) + //{ + // if(RenderNodeCommandPart!=null) + // RenderNodeCommandPart(this,e); + //} + + /// + /// 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. + /// + /// Information provided for rendering. + public virtual void DrawCellBackground(NodeCellRendererEventArgs e) + { + OnRenderCellBackground(e); + } + + /// + /// Raises RenderCellBackground event. + /// + /// Event arguments + protected virtual void OnRenderCellBackground(NodeCellRendererEventArgs e) + { + if(RenderCellBackground!=null) + RenderCellBackground(this, e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public virtual void DrawCellCheckBox(NodeCellRendererEventArgs e) + { + OnRenderCellCheckBox(e); + } + + /// + /// Raises RenderCellCheckBox event. + /// + /// Event arguments + protected virtual void OnRenderCellCheckBox(NodeCellRendererEventArgs e) + { + if(RenderCellCheckBox!=null) + RenderCellCheckBox(this, e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public virtual void DrawCellImage(NodeCellRendererEventArgs e) + { + OnRenderCellImage(e); + } + + /// + /// Raises RenderCellImage event. + /// + /// Event arguments + protected virtual void OnRenderCellImage(NodeCellRendererEventArgs e) + { + if(RenderCellImage!=null) + RenderCellImage(this, e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public virtual void DrawCellText(NodeCellRendererEventArgs e) + { + OnRenderCellText(e); + } + + /// + /// Raises RenderCellImage event. + /// + /// Event arguments + protected virtual void OnRenderCellText(NodeCellRendererEventArgs e) + { + if(RenderCellText!=null) + RenderCellText(this, e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public virtual void DrawSelection(SelectionRendererEventArgs e) + { + OnRenderSelection(e); + } + + /// + /// Raises RenderSelection event. + /// + /// Event data. + protected virtual void OnRenderSelection(SelectionRendererEventArgs e) + { + if(RenderSelection!=null) + RenderSelection(this, e); + } + + /// + /// Draws hot-tracking marker for mouse over node. 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 OnRenderHotTracking method so events can occur. + /// + /// Information provided for rendering. + public virtual void DrawHotTracking(SelectionRendererEventArgs e) + { + OnRenderHotTracking(e); + } + + /// + /// Raises RenderHotTracking event. + /// + /// Event data. + protected virtual void OnRenderHotTracking(SelectionRendererEventArgs e) + { + if (RenderHotTracking != null) + RenderHotTracking(this, e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public virtual void DrawConnector(ConnectorRendererEventArgs e) + { + OnRenderConnector(e); + } + + /// + /// Raises RenderConnector event. + /// + /// Event data. + protected virtual void OnRenderConnector(ConnectorRendererEventArgs e) + { + if(RenderConnector!=null) + RenderConnector(this, e); + } + + /// + /// 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. + /// + /// Information provided for rendering. + public virtual void DrawTreeBackground(TreeBackgroundRendererEventArgs e) + { + OnRenderTreeBackground(e); + } + + /// + /// Raises RenderTreeBackground event. + /// + /// Event data. + protected virtual void OnRenderTreeBackground(TreeBackgroundRendererEventArgs e) + { + if(RenderTreeBackground!=null) + RenderTreeBackground(this, e); + } + + /// + /// Draws the drag & drop marker that indicates the insertion point for the node. 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 OnRenderDragDropMarker method so events can occur. + /// + /// Information provided for rendering. + public virtual void DrawDragDropMarker(DragDropMarkerRendererEventArgs e) + { + OnRenderDragDropMarker(e); + } + + /// + /// Raises RenderDragDropMarker event. + /// + /// Event data. + protected virtual void OnRenderDragDropMarker(DragDropMarkerRendererEventArgs e) + { + if (RenderDragDropMarker != null) + RenderDragDropMarker(this, e); + } + + /// + /// Draws the column header. 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 OnRenderColumnHeader method so events can occur. + /// + /// Information provided for rendering. + public virtual void DrawColumnHeader(ColumnHeaderRendererEventArgs e) + { + OnRenderColumnHeader(e); + } + + /// + /// Raises RenderDragDropMarker event. + /// + /// Event data. + protected virtual void OnRenderColumnHeader(ColumnHeaderRendererEventArgs e) + { + if (RenderColumnHeader != null) + RenderColumnHeader(this, e); + } + + private TreeColorTable _ColorTable = null; + /// + /// Gets or sets the color table used by the renderer. + /// + public TreeColorTable ColorTable + { + get { return _ColorTable; } + set { _ColorTable = value; } + } + + private Office2007ColorTable _Office2007ColorTable = null; + /// + /// Gets or sets the color table used by the renderer. + /// + internal Office2007ColorTable Office2007ColorTable + { + get { return _Office2007ColorTable; } + set { _Office2007ColorTable = value; } + } + + /// + /// Draws node group line when in tile view. 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 OnRenderTileGroupLine method so events can occur. + /// + /// Information provided for rendering. + public virtual void DrawTileGroupLine(NodeRendererEventArgs e) + { + OnRenderTileGroupLine(e); + } + + /// + /// Raises RenderNodeBackground event. + /// + /// Event arguments. + protected virtual void OnRenderTileGroupLine(NodeRendererEventArgs e) + { + if (RenderTileGroupLine != null) + RenderTileGroupLine(this, e); + } + + #endregion + } + +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Display/TreeSelectionColors.cs b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeSelectionColors.cs new file mode 100644 index 00000000..4909d030 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Display/TreeSelectionColors.cs @@ -0,0 +1,40 @@ +using System; +using System.Text; + +namespace DevComponents.AdvTree.Display +{ + /// + /// Defines the color table for tree selection. + /// + public class TreeSelectionColors + { + /// + /// Gets or sets the color table for FullRowSelect selection type. + /// + public SelectionColorTable FullRowSelect = null; + /// + /// Gets or sets the color table for FullRowSelect selection type when tree control is inactive. + /// + public SelectionColorTable FullRowSelectInactive = null; + /// + /// Gets or sets the color table for HighlightCells selection type. + /// + public SelectionColorTable HighlightCells = null; + /// + /// Gets or sets the color table for HighlightCells selection type when tree control is inactive. + /// + public SelectionColorTable HighlightCellsInactive = null; + /// + /// Gets or sets the color table for NodeMarker selection type. + /// + public SelectionColorTable NodeMarker = null; + /// + /// Gets or sets the color table for NodeMarker selection type when tree control is inactive. + /// + public SelectionColorTable NodeMarkerInactive = null; + /// + /// Gets or sets the color table used for node hot-tracking. + /// + public SelectionColorTable NodeHotTracking = null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/Border.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/Border.cs new file mode 100644 index 00000000..250c4817 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/Border.cs @@ -0,0 +1,40 @@ +using System; +using System.Text; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.WinForms.Drawing +{ + [ToolboxItem(false)] + public abstract class Border : Component + { + #region Internal Implementation + /// + /// Creates the pen for the border. + /// + /// Returns pen or null if pen cannot be created. + public abstract Pen CreatePen(); + + internal int _Width = 0; + /// + /// Gets or sets the border width. Default value is 0. + /// + [DefaultValue(0), Description("Indicates border width.")] + public int Width + { + get { return _Width; } + set + { + _Width = value; + } + } + + internal static Rectangle Deflate(Rectangle bounds, Border border) + { + if (border == null) return bounds; + bounds.Inflate(-border.Width, -border.Width); + return bounds; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/ColorBlendCollection.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/ColorBlendCollection.cs new file mode 100644 index 00000000..a0e0de54 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/ColorBlendCollection.cs @@ -0,0 +1,234 @@ +using System; +using System.Collections; +using System.Text; +using System.Drawing.Drawing2D; +using System.Drawing; + +namespace DevComponents.WinForms.Drawing +{ + /// + /// Represents Collection for the ColorStop objects. + /// + public class ColorBlendCollection : CollectionBase + { + #region Private Variables + + #endregion + + #region Internal Implementation + /// Creates new instance of the class. + public ColorBlendCollection() { } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(ColorStop item) + { + return List.Add(item); + } + + /// + /// Adds array of new objects to the collection. + /// + /// Array of object to add. + public void AddRange(ColorStop[] items) + { + foreach (ColorStop item in items) + this.Add(item); + } + + /// + /// Returns reference to the object in collection based on it's index. + /// + public ColorStop this[int index] + { + get { return (ColorStop)(List[index]); } + set { List[index] = value; } + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, ColorStop value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(ColorStop value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(ColorStop value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + public void Remove(ColorStop value) + { + List.Remove(value); + } + + //protected override void OnRemoveComplete(int index,object value) + //{ + // base.OnRemoveComplete(index,value); + // ColorStop me=value as ColorStop; + //} + //protected override void OnInsertComplete(int index,object value) + //{ + // base.OnInsertComplete(index,value); + // ColorStop me=value as ColorStop; + //} + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(ColorStop[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the ColorStop array. + /// + /// Array to copy to. + internal void CopyTo(ColorStop[] array) + { + List.CopyTo(array, 0); + } + + /// + /// 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. + /// + /// + 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++) + { + ColorStop b = this[i]; + colors[i] = b.Color; + positions[i] = b.Position; + } + + blend.Colors = colors; + blend.Positions = positions; + + return blend; + } + + /// + /// Adds the ColorStop objects from the collection. + /// + /// Collection to copy objects from + public void CopyFrom(ColorBlendCollection col) + { + foreach (ColorStop b in col) + this.Add(b); + } + + internal eColorStopType GetBlendType() + { + ColorBlendCollection c = this; + if (c.Count <= 1) + return eColorStopType.Invalid; + + eColorStopType t = eColorStopType.Invalid; + + foreach (ColorStop b in c) + { + if (b.Position == 0 || b.Position == 1f) + continue; + if (b.Position <= 1f) + { + if (t == eColorStopType.Invalid) + t = eColorStopType.Relative; + else if (t == eColorStopType.Absolute) + { + t = eColorStopType.Invalid; + break; + } + } + else + { + if (t == eColorStopType.Invalid) + t = eColorStopType.Absolute; + else if (t == eColorStopType.Relative) + { + t = eColorStopType.Invalid; + break; + } + } + } + + if (c.Count == 2 && c[0].Position == 0f && c[1].Position == 1f) + return eColorStopType.Relative; + + if (t == eColorStopType.Invalid) + return t; + + if (t == eColorStopType.Relative && c[0].Position != 0f && c[c.Count - 1].Position != 1f) + return eColorStopType.Invalid; + else if (t == eColorStopType.Absolute && ((c.Count / 2) * 2 != c.Count)) + return eColorStopType.Invalid; + + return t; + } + + ///// + ///// Initializes the collection with the two color blend. + ///// + ///// Collection to initialize. + ///// Start color. + ///// End color. + //public static void InitializeCollection(ColorBlendCollection collection, int backColor1, int backColor2) + //{ + // InitializeCollection(collection, ColorScheme.GetColor(backColor1), ColorScheme.GetColor(backColor2)); + //} + + /// + /// Initializes the collection with the two color blend. + /// + /// Collection to initialize. + /// Start color. + /// End color. + public static void InitializeCollection(ColorBlendCollection collection, Color backColor1, Color backColor2) + { + collection.Clear(); + collection.Add(new ColorStop(backColor1, 0f)); + collection.Add(new ColorStop(backColor2, 1f)); + } + #endregion + } + + internal enum eColorStopType + { + Invalid, + Relative, + Absolute + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/ColorStop.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/ColorStop.cs new file mode 100644 index 00000000..b17a4a50 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/ColorStop.cs @@ -0,0 +1,83 @@ +using System; +using System.Text; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.WinForms.Drawing +{ + /// + /// Defines single color blend point for the multicolor gradient fills. + /// + [ToolboxItem(false), DesignTimeVisible(false), TypeConverter(typeof(ColorStopConverter))] + public class ColorStop + { + #region Private Variables + private Color _Color = Color.Empty; + private float _Position = 0; + #endregion + + #region Internal Implementation + /// + /// Creates new instance of the class. When defining multicolor gradient blends and using the percentage positions the positions created + /// must start with 0f and end with 1f. + /// + public ColorStop() { } + + /// + /// Creates new instance of the class and initialize it with default values. + /// + public ColorStop(Color color, float position) + { + _Color = color; + _Position = position; + } + + ///// + ///// Creates new instance of the class and initialize it with default values. + ///// + //public ColorStop(int color, float position) + //{ + // _Color = ColorScheme.GetColor(color); + // _Position = position; + //} + + /// + /// Gets or sets Color to use in multicolor gradient blend at specified position. + /// + [Browsable(true), Description("Indicates the Color to use in multicolor gradient blend at specified position.")] + public Color Color + { + get { return _Color; } + set + { + _Color = value; + OnColorBlendChanged(); + } + } + private bool ShouldSerializeColor() + { + return !_Color.IsEmpty; + } + + /// + /// 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. + /// + [Browsable(true), DefaultValue(0f), Description("")] + public float Position + { + get { return _Position; } + set + { + _Position = value; + OnColorBlendChanged(); + } + } + + private void OnColorBlendChanged() + { + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/ColorStopConverter.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/ColorStopConverter.cs new file mode 100644 index 00000000..17656735 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/ColorStopConverter.cs @@ -0,0 +1,49 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Globalization; +using System.Reflection; +using System.Drawing; + +namespace DevComponents.WinForms.Drawing +{ + /// + /// Represents BackgroundColorBlend object converter. + /// + public class ColorStopConverter : TypeConverter + { + public ColorStopConverter() { } + + 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 ColorStop)) + { + ColorStop doc = (ColorStop)value; + Type[] constructorParams = null; + MemberInfo constructorMemberInfo = null; + object[] constructorValues = null; + + constructorParams = new Type[2] { typeof(Color), typeof(float) }; + constructorMemberInfo = typeof(ColorStop).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); + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/CornerRadius.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/CornerRadius.cs new file mode 100644 index 00000000..85b1b91f --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/CornerRadius.cs @@ -0,0 +1,258 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.ComponentModel; +using System.Globalization; +using System.ComponentModel.Design.Serialization; + +namespace DevComponents.WinForms.Drawing +{ + [StructLayout(LayoutKind.Sequential), TypeConverter(typeof(CornerRadiusConverter))] + public struct CornerRadius +#if FRAMEWORK20 + : IEquatable +#endif + { + #region Private Variables + private int _TopLeft; + private int _topRight; + private int _bottomLeft; + private int _bottomRight; + #endregion + + #region Constructor + public CornerRadius(int uniformRadius) + { + this._TopLeft = this._topRight = this._bottomLeft = this._bottomRight = uniformRadius; + } + + public CornerRadius(int topLeft, int topRight, int bottomRight, int bottomLeft) + { + this._TopLeft = topLeft; + this._topRight = topRight; + this._bottomRight = bottomRight; + this._bottomLeft = bottomLeft; + } + #endregion + + #region Internal Implementation + public override bool Equals(object obj) + { + if (obj is CornerRadius) + { + CornerRadius radius = (CornerRadius)obj; + return (this == radius); + } + return false; + } + + public bool Equals(CornerRadius cornerRadius) + { + return (this == cornerRadius); + } + + public override int GetHashCode() + { + return (((this._TopLeft.GetHashCode() ^ this._topRight.GetHashCode()) ^ this._bottomLeft.GetHashCode()) ^ this._bottomRight.GetHashCode()); + } + + public override string ToString() + { + return CornerRadiusConverter.ToString(this, CultureInfo.InvariantCulture); + } + + public static bool operator ==(CornerRadius cr1, CornerRadius cr2) + { + return ((cr1._TopLeft == cr2._TopLeft) && (cr1._topRight == cr2._topRight) && (cr1._bottomRight == cr2._bottomRight) && (cr1._bottomLeft == cr2._bottomLeft)); + } + + public static bool operator !=(CornerRadius cr1, CornerRadius cr2) + { + return !(cr1 == cr2); + } + + public int TopLeft + { + get + { + return this._TopLeft; + } + set + { + this._TopLeft = value; + } + } + public int TopRight + { + get + { + return this._topRight; + } + set + { + this._topRight = value; + } + } + public int BottomRight + { + get + { + return this._bottomRight; + } + set + { + this._bottomRight = value; + } + } + public int BottomLeft + { + get + { + return this._bottomLeft; + } + set + { + this._bottomLeft = value; + } + } + + internal bool IsValid(bool allowNegative) + { + if (!allowNegative && (((this._TopLeft < 0.0) || (this._topRight < 0.0)) || ((this._bottomLeft < 0.0) || (this._bottomRight < 0.0)))) + { + return false; + } + return true; + } + + internal bool IsZero + { + get + { + return (_TopLeft == 0 && _topRight == 0 && _bottomRight == 0 && _bottomLeft == 0); + } + } + #endregion + } + + #region CornerRadiusConverter + public class CornerRadiusConverter : TypeConverter + { + // Methods + public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type sourceType) + { + switch (Type.GetTypeCode(sourceType)) + { + case TypeCode.Int16: + case TypeCode.UInt16: + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + case TypeCode.String: + return true; + } + return false; + } + + public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type destinationType) + { + if ((destinationType != typeof(InstanceDescriptor)) && (destinationType != typeof(string))) + { + return false; + } + return true; + } + + public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object source) + { + if (source == null) + { + throw base.GetConvertFromException(source); + } + if (source is string) + { + return FromString((string)source, cultureInfo); + } + return new CornerRadius(Convert.ToInt32(source, cultureInfo)); + } + + public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object value, Type destinationType) + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + if (destinationType == null) + { + throw new ArgumentNullException("destinationType"); + } + if (!(value is CornerRadius)) + { + throw new ArgumentException("Unexpected parameter type", "value"); + } + CornerRadius cr = (CornerRadius)value; + if (destinationType == typeof(string)) + { + return ToString(cr, cultureInfo); + } + if (destinationType != typeof(InstanceDescriptor)) + { + throw new ArgumentException("Cannot convert to type " + destinationType.FullName); + } + return new InstanceDescriptor(typeof(CornerRadius).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int) }), new object[] { cr.TopLeft, cr.TopRight, cr.BottomRight, cr.BottomLeft }); + } + + internal static CornerRadius FromString(string s, CultureInfo cultureInfo) + { + string[] parsed = s.Split(GetNumericListSeparator(cultureInfo)); + int[] numArray = new int[4]; + for (int i = 0; i < parsed.Length; i++) + { + numArray[i] = int.Parse(parsed[i], cultureInfo); + } + + int index = Math.Min(5, parsed.Length); + + switch (index) + { + case 1: + return new CornerRadius(numArray[0]); + + case 4: + return new CornerRadius(numArray[0], numArray[1], numArray[2], numArray[3]); + } + throw new FormatException("Invalid string corner radius"); + } + + internal static string ToString(CornerRadius cr, CultureInfo cultureInfo) + { + char numericListSeparator = GetNumericListSeparator(cultureInfo); + StringBuilder builder = new StringBuilder(0x40); + builder.Append(cr.TopLeft.ToString(cultureInfo)); + builder.Append(numericListSeparator); + builder.Append(cr.TopRight.ToString(cultureInfo)); + builder.Append(numericListSeparator); + builder.Append(cr.BottomRight.ToString(cultureInfo)); + builder.Append(numericListSeparator); + builder.Append(cr.BottomLeft.ToString(cultureInfo)); + return builder.ToString(); + } + + internal static char GetNumericListSeparator(IFormatProvider provider) + { + char ch = ','; + NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider); + if ((instance.NumberDecimalSeparator.Length > 0) && (ch == instance.NumberDecimalSeparator[0])) + { + ch = ';'; + } + return ch; + } + } + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/Fill.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/Fill.cs new file mode 100644 index 00000000..9757f71a --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/Fill.cs @@ -0,0 +1,27 @@ +using System; +using System.Text; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.WinForms.Drawing +{ + [ToolboxItem(false)] + public abstract class Fill : Component + { + #region Internal Implementation + /// + /// Creates the brush for fill. + /// + /// Bounds for the brush + /// Returns brush or null if brush cannot be created for given bounds or colors are not set. It is responsibility of caller to Dispose the brush. + public abstract Brush CreateBrush(Rectangle bounds); + + /// + /// Creates a pen based on fill parameters. + /// + /// Width of the pen to create + /// new instance of pen or null if pen cannot be created. + public abstract Pen CreatePen(int width); + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/GradientFill.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/GradientFill.cs new file mode 100644 index 00000000..8072a5b3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/GradientFill.cs @@ -0,0 +1,179 @@ +using System; +using System.Text; +using System.Drawing; +using System.ComponentModel; +using System.Drawing.Drawing2D; + +namespace DevComponents.WinForms.Drawing +{ + public class GradientFill : Fill + { + #region Constructor + /// + /// Initializes a new instance of the GradientFill class. + /// + public GradientFill() + { + } + + /// + /// Initializes a new instance of the GradientFill class. + /// + /// + /// + public GradientFill(Color color1, Color color2) + { + _Color1 = color1; + _Color2 = color2; + } + + /// + /// Initializes a new instance of the GradientFill class. + /// + /// + /// + /// + public GradientFill(Color color1, Color color2, float angle) + { + _Color1 = color1; + _Color2 = color2; + _Angle = angle; + } + + /// + /// Initializes a new instance of the GradientFill class. + /// + /// + public GradientFill(ColorStop[] interpolationColors) + { + _InterpolationColors.AddRange(interpolationColors); + } + + /// + /// Initializes a new instance of the GradientFill class. + /// + /// + public GradientFill(ColorStop[] interpolationColors, int angle) + { + _InterpolationColors.AddRange(interpolationColors); + _Angle = angle; + } + #endregion + + #region Internal Implementation + /// + /// Creates the brush for fill. + /// + /// Bounds for the brush + /// Returns brush or null if brush cannot be created for given bounds or colors are not set. It is responsibility of caller to Dispose the brush. + public override Brush CreateBrush(Rectangle bounds) + { + if (_Color1.IsEmpty && _Color2.IsEmpty && _InterpolationColors.Count == 0 || bounds.Width < 1 || bounds.Height < 1) return null; + + LinearGradientBrush brush=new LinearGradientBrush(bounds, _Color1, _Color2, _Angle); + if (_InterpolationColors.Count == 0) + return brush; + brush.InterpolationColors = _InterpolationColors.GetColorBlend(); + + return brush; + } + + private Color _Color1 = Color.Empty; + /// + /// Gets or sets the starting gradient fill color. + /// + [Description("Indicates the fill color.")] + public Color Color1 + { + get { return _Color1; } + set { _Color1 = value; } + } + /// + /// Gets whether property should be serialized. + /// + /// true if property should be serialized + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeColor1() + { + return !_Color1.IsEmpty; + } + /// + /// Sets the property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetColor1() + { + Color1 = Color.Empty; + } + + private Color _Color2 = Color.Empty; + /// + /// Gets or sets the end gradient fill color. + /// + [Description("Indicates the fill color.")] + public Color Color2 + { + get { return _Color2; } + set { _Color2 = value; } + } + /// + /// Gets whether property should be serialized. + /// + /// true if property should be serialized + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeColor2() + { + return !_Color2.IsEmpty; + } + /// + /// Sets the property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetColor2() + { + Color2 = Color.Empty; + } + + private ColorBlendCollection _InterpolationColors = new ColorBlendCollection(); + /// + /// Gets the collection that defines the multicolor gradient background. + /// + /// + /// Setting this property creates a multicolor gradient with one color at each position along the gradient line. Setting this property nullifies all previous color, position, and falloff settings for this gradient fill. + /// + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Description("Collection that defines the multicolor gradient background.")] + public ColorBlendCollection InterpolationColors + { + get { return _InterpolationColors; } + } + + private float _Angle = 90; + /// + /// Gets or sets the gradient fill angle. Default value is 90. + /// + [DefaultValue(90), Description("Indicates gradient fill angle.")] + public float Angle + { + get { return _Angle; } + set + { + _Angle = value; + } + } + /// + /// Creates a pen based on fill parameters. + /// + /// Width of the pen to create + /// new instance of pen or null if pen cannot be created. + public override Pen CreatePen(int width) + { + if (!_Color1.IsEmpty) + return new Pen(_Color1, width); + if (!_Color2.IsEmpty) + return new Pen(_Color2, width); + return null; + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/RectangleShape.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/RectangleShape.cs new file mode 100644 index 00000000..5cb76178 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/RectangleShape.cs @@ -0,0 +1,128 @@ +using System; +using System.Text; +using System.Drawing; +using System.ComponentModel; +using DevComponents.AdvTree; +using System.Drawing.Drawing2D; +using DevComponents.DotNetBar; + +namespace DevComponents.WinForms.Drawing +{ + internal class RectangleShape : Shape + { + #region Internal Implementation + /// + /// Renders rectangle on canvas. + /// + /// Target graphics to render shape on. + /// Shape bounds. + public override void Paint(Graphics g, Rectangle bounds) + { + if (bounds.Width < 2 || bounds.Height < 2 || g == null || _Fill == null && _Border == null) return; + + GraphicsPath path = null; + + if (!_CornerRadius.IsZero) + { + path = DisplayHelp.GetRoundedRectanglePath(bounds, _CornerRadius.TopLeft, _CornerRadius.TopRight, + _CornerRadius.BottomRight, _CornerRadius.BottomLeft); + } + + if (_Fill != null) + { + Brush brush = _Fill.CreateBrush(bounds); + if (brush != null) + { + SmoothingMode sm = g.SmoothingMode; + if (brush is SolidBrush && path==null) + g.SmoothingMode = SmoothingMode.None; + if (path == null) + g.FillRectangle(brush, bounds); + else + g.FillPath(brush, path); + g.SmoothingMode = sm; + brush.Dispose(); + } + } + + if (_Border != null) + { + Pen pen = _Border.CreatePen(); + if (pen != null) + { + if (path == null) + g.DrawRectangle(pen, bounds); + else + g.DrawPath(pen, path); + + pen.Dispose(); + } + } + + Shape content = this.Content; + if (content != null) + { + Rectangle contentBounds = Border.Deflate(bounds, _Border); + Region oldClip = null; + if (path != null && ClipToBounds) + { + oldClip = g.Clip; + g.SetClip(path, CombineMode.Intersect); + } + content.Paint(g, contentBounds); + if (oldClip != null) g.Clip = oldClip; + } + + if (path != null) path.Dispose(); + } + + private Border _Border; + /// + /// Gets or sets shape border. + /// + [DefaultValue(null), Description("Indicates shape border.")] + public Border Border + { + get { return _Border; } + set { _Border = value; } + } + + private Fill _Fill = null; + /// + /// Gets or sets the shape fill. + /// + [DefaultValue(null), Description("Indicates shape fill")] + public Fill Fill + { + get { return _Fill; } + set { _Fill = value; } + } + + private CornerRadius _CornerRadius; + /// + /// Gets or sets the CornerRadius. + /// + public CornerRadius CornerRadius + { + get { return _CornerRadius; } + set { _CornerRadius = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCornerRadius() + { + return !_CornerRadius.IsZero; + } + /// + /// Resets the property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetCornerRadius() + { + CornerRadius = new CornerRadius(); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/Shape.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/Shape.cs new file mode 100644 index 00000000..78600219 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/Shape.cs @@ -0,0 +1,48 @@ +using System; +using System.Text; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.WinForms.Drawing +{ + /// + /// Defines a visual shape. + /// + internal abstract class Shape + { + #region Internal Implementation + /// + /// Renders shape on canvas. + /// + /// Target graphics to render shape on. + /// Shape bounds. + public abstract void Paint(Graphics g, Rectangle bounds); + + private Shape _Content = null; + /// + /// Gets or sets the single piece of content inside of the shape. + /// + [DefaultValue(null)] + public Shape Content + { + get { return _Content; } + set { _Content = value; } + } + + private bool _ClipToBounds = false; + /// + /// Gets or sets whether to clip the Content of this shape. Default value is false. + /// + [DefaultValue(false)] + public bool ClipToBounds + { + get { return _ClipToBounds; } + set + { + _ClipToBounds = value; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/SolidBorder.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/SolidBorder.cs new file mode 100644 index 00000000..7609a497 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/SolidBorder.cs @@ -0,0 +1,86 @@ +using System; +using System.Text; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.WinForms.Drawing +{ + public class SolidBorder : Border + { + #region Constructor + /// + /// Initializes a new instance of the SolidBorder class. + /// + /// + /// + public SolidBorder(Color color, int width) + { + _Color = color; + _Width = width; + } + + /// + /// Initializes a new instance of the SolidBorder class. + /// + /// + public SolidBorder(Color color) + { + _Color = color; + } + + /// + /// Initializes a new instance of the SolidBorder class. + /// + public SolidBorder() + { + } + #endregion + #region Internal Implementation + /// + /// Creates the pen for the border. + /// + /// Returns pen or null if pen cannot be created. + public override Pen CreatePen() + { + if (!CanCreatePen()) return null; + + return new Pen(_Color, _Width); + } + + private bool CanCreatePen() + { + return !_Color.IsEmpty && _Width > 0; + } + + private Color _Color = Color.Empty; + /// + /// Gets or sets the fill color. + /// + [Description("Indicates the fill color.")] + public Color Color + { + get { return _Color; } + set { _Color = value; } + } + /// + /// Gets whether property should be serialized. + /// + /// true if property should be serialized + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeColor() + { + return !_Color.IsEmpty; + } + /// + /// Sets the property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetColor() + { + Color = Color.Empty; + } + + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Drawing/SolidFill.cs b/PROMS/DotNetBar Source Code/AdvTree/Drawing/SolidFill.cs new file mode 100644 index 00000000..ae63361b --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Drawing/SolidFill.cs @@ -0,0 +1,76 @@ +using System; +using System.Text; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.WinForms.Drawing +{ + public class SolidFill : Fill + { + #region Constructor + /// + /// Initializes a new instance of the SolidFill class. + /// + /// + public SolidFill(Color color) + { + _Color = color; + } + + /// + /// Initializes a new instance of the SolidFill class. + /// + public SolidFill() + { + } + #endregion + + #region Internal Implementation + /// + /// Creates the brush for fill. + /// + /// Bounds for the brush + /// Returns brush or null if brush cannot be created for given bounds or colors are not set. It is responsibility of caller to Dispose the brush. + public override Brush CreateBrush(Rectangle bounds) + { + if (_Color.IsEmpty) return null; + return new SolidBrush(_Color); + } + + private Color _Color = Color.Empty; + /// + /// Gets or sets the fill color. + /// + [Description("Indicates the fill color.")] + public Color Color + { + get { return _Color; } + set { _Color = value; } + } + /// + /// Gets whether property should be serialized. + /// + /// true if property should be serialized + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeColor() + { + return !_Color.IsEmpty; + } + /// + /// Sets the property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetColor() + { + Color = Color.Empty; + } + + public override Pen CreatePen(int width) + { + if (!_Color.IsEmpty) + return new Pen(_Color, width); + return null; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/ElementStyleCollection.cs b/PROMS/DotNetBar Source Code/AdvTree/ElementStyleCollection.cs new file mode 100644 index 00000000..ff62e6d1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/ElementStyleCollection.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree +{ + /// + /// Represents collection for Node objects. + /// + public class ElementStyleCollection:CollectionBase + { + #region Private Variables + private AdvTree m_TreeControl=null; + //private Hashtable m_InnerHashtable=new Hashtable(); + #endregion + + #region Internal Implementation + /// Creates new instance of the object. + public ElementStyleCollection() + { + } + internal AdvTree TreeControl + { + get {return m_TreeControl;} + set {m_TreeControl=value;} + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(ElementStyle style) + { + return List.Add(style); + } + /// + /// Returns reference to the object in collection based on it's index. + /// + public ElementStyle this[int index] + { + get {return (ElementStyle)(List[index]);} + set {List[index] = value;} + } + + /// + /// Returns reference to the object in collection based on it's name. + /// + public ElementStyle this[string name] + { + get + { + foreach(ElementStyle style in this.List) + { + if(style.Name==name) + return style; + } + return null; + } + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, ElementStyle value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(ElementStyle value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(ElementStyle value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + 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); + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(ElementStyle[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the Node array. + /// + /// Array to copy to. + internal void CopyTo(ElementStyle[] array) + { + List.CopyTo(array,0); + } + + protected override void OnClear() + { + base.OnClear(); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Enums.cs b/PROMS/DotNetBar Source Code/AdvTree/Enums.cs new file mode 100644 index 00000000..55fece33 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Enums.cs @@ -0,0 +1,766 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Specifies layout of the items in AdvTree control. + /// + public enum eView + { + /// + /// Standard TreeView layout. + /// + Tree, + /// + /// ListView style tile layout. + /// + Tile + } + + /// Specifies the way background image is displayed on background. + public enum eStyleBackgroundImage:int + { + /// Image is stretched to fill the background + Stretch=0, + /// Image is centered inside the background + Center=1, + /// Image is tiled inside the background + Tile=2, + /// + /// Image is drawn in top left corner of container space. + /// + TopLeft=3, + /// + /// Image is drawn in top right corner of container space. + /// + TopRight=4, + /// + /// Image is drawn in bottom left corner of container space. + /// + BottomLeft=5, + /// + /// Image is drawn in bottom right corner of container space. + /// + BottomRight=6 + } + + /// Indicates alignment of a part of the cell like image or check box in relation to the text. + public enum eCellPartAlignment:int + { + /// + /// Part is aligned to the left center of the text assuming left-to-right + /// orientation. + /// + NearCenter=0, + /// + /// Part is aligned to the right center of the text assuming left-to-right + /// orientation. + /// + FarCenter=1, + /// + /// Part is aligned to the top left of the text assuming left-to-right + /// orientation. + /// + NearTop=2, + /// Part is aligned above the text and centered. + CenterTop=3, + /// + /// Part is aligned to the top right of the text assuming left-to-right + /// orientation. + /// + FarTop=4, + /// + /// Part is aligned to the bottom left of the text assuming left-to-right + /// orientation. + /// + NearBottom=5, + /// Part is aligned below the text and centered. + CenterBottom=6, + /// + /// Part is aligned to the bottom right of the text assuming left-to-right + /// orientation. + /// + FarBottom=7, + /// + /// Part has default alignment that depends on the parent control view. + /// + Default = 8 + } + + /// + /// Specifies how to trim characters from a text that does not completely fit into a element's shape. + /// + public enum eStyleTextTrimming + { + /// + /// Specifies that the text is trimmed to the nearest character. + /// + Character=System.Drawing.StringTrimming.Character, + /// + /// Specifies that the text is trimmed to the nearest character, and an ellipsis is inserted at the end of a trimmed line. + /// + EllipsisCharacter=System.Drawing.StringTrimming.EllipsisCharacter, + /// + /// 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. + /// + EllipsisPath=System.Drawing.StringTrimming.EllipsisPath, + /// + /// Specifies that text is trimmed to the nearest word, and an ellipsis is inserted at the end of a trimmed line. + /// + EllipsisWord=System.Drawing.StringTrimming.EllipsisWord, + /// + /// Specifies no trimming. + /// + None=System.Drawing.StringTrimming.None, + /// + /// Specifies that text is trimmed to the nearest word. + /// + Word=System.Drawing.StringTrimming.Word + } + + ///// + ///// Specifies the border type for style element. + ///// + //public enum eStyleBorderType:int + //{ + // /// Indicates no border + // None, + // /// Border is a solid line + // Solid, + // /// Border is a solid dash line + // Dash, + // /// Border is solid dash-dot line + // DashDot, + // /// Border is solid dash-dot-dot line + // DashDotDot, + // /// Border consists of dots + // Dot, + // /// Etched Border + // Etched, + // /// Double Border + // Double + //} + + /// + /// Indicates absolute vertical alignment of the content. + /// + public enum eVerticalAlign + { + /// + /// Content is aligned to the top + /// + Top, + /// + /// Content is aligned in the middle + /// + Middle, + /// + /// Content is aligned at the bottom + /// + Bottom + } + + /// + /// Indicates absolute horizontal alignment + /// + public enum eHorizontalAlign + { + /// + /// Content is left aligned + /// + Left, + /// + /// Content is centered + /// + Center, + /// + /// Content is right aligned + /// + Right + } + + /// + /// Indicates prefered node layout position on Map tree layout when node is the child node of the top-level root node. + /// + public enum eMapPosition + { + /// + /// Node is positioned based on default algorithm. + /// + Default, + /// + /// Sub-root node and all nodes after it are positioned to the left of the root. + /// + Near, + /// + /// Sub-root node and all nodes before it are positioned to the right of the root. + /// + Far + } + + ///// + ///// Indicates corner type for the border around visual element. + ///// + //public enum eCornerType + //{ + // /// + // /// Specifies that corner type is inherited from parent setting. + // /// + // Inherit, + // /// + // /// Specifies square corner. + // /// + // Square, + // /// + // /// Specifies rounded corner. + // /// + // Rounded, + // /// + // /// Specifies diagonal corner. + // /// + // Diagonal + //} + + /// + /// Specifies the column header visibility for the node. + /// + public enum eNodeHeaderVisibility + { + /// + /// 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. + /// + Automatic, + /// + /// Column header is always displayed regardless of node's position. + /// + AlwaysShow, + /// + /// Column header is always hidden regardless of node's position. + /// + AlwaysHide + } + + /// + /// Indicates the part of the node. + /// + public enum eNodeRectanglePart + { + /// + /// Bounds of complete node content except expand button. This also includes the child node bounds if node is expanded. + /// + NodeContentBounds, + /// + /// Bounds of the expand button which collapses/expands the node. + /// + ExpandBounds, + /// + /// Hit test bounds of the expand button which collapses/expands the node used by mouse routines to trigger node expansion/collapse. + /// + ExpandHitTestBounds, + /// + /// Bounds of all child nodes of give node. + /// + ChildNodeBounds, + /// + /// Bounds for cells inside a node. + /// + CellsBounds, + /// + /// Complete node bounds including expand button. + /// + NodeBounds, + /// + /// Bounds of the command button. + /// + CommandBounds, + /// + /// Bounds of child node columns if node has columns defined. + /// + ColumnsBounds + } + + /// + /// Indicates the part of the cell. + /// + internal enum eCellRectanglePart + { + /// + /// Bounds of check box or Rectangle.Empty if there is no check-box. + /// + CheckBoxBounds, + /// + /// Bounds of image inside the cell or Rectangle.Empty if there is no image. + /// + ImageBounds, + /// + /// Text bounds inside of cell. + /// + TextBounds, + /// + /// Cell bounds + /// + CellBounds + } + + /// + /// Indicates part of the node mouse is placed over. + /// + internal enum eMouseOverNodePart + { + /// + /// Mouse is not over any node part. + /// + None, + /// + /// Mouse is placed over the node. + /// + Node, + /// + /// Mouse is placed over node expand button. + /// + Expand, + /// + /// Mouse is placed over the cell. + /// + Cell, + /// + /// Mouse is placed over the command button. + /// + Command + } + + ///// + ///// Indicates white-space part of the style. + ///// + //[Flags()] + //public enum eSpacePart + //{ + // /// + // /// Represents style padding. + // /// + // Padding=1, + // /// + // /// Represents style border. + // /// + // Border=2, + // /// + // /// Represents style margin. + // /// + // Margin=4 + //} + + ///// + ///// Indicates the style side. + ///// + //public enum eStyleSide + //{ + // /// + // /// Specifies left side of the style. + // /// + // Left, + // /// + // /// Specifies right side of the style. + // /// + // Right, + // /// + // /// Specifies top side of the style. + // /// + // Top, + // /// + // /// Specifies bottom side of the style. + // /// + // Bottom + //} + + /// + /// Indicates the visibility of node expand part which allows user to expand/collaps node. + /// + public enum eNodeExpandVisibility + { + /// + /// Default setting which indicates that when node has child nodes expand part is visible otherwise it is hidden. + /// + Auto, + /// + /// Expand part is always visible regardless of whether child nodes are present or not. + /// + Visible, + /// + /// Expand part is always hidden regardless of whether child nodes are present or not. + /// + Hidden + } + + /// + /// Specifies the action that raised a AdvTreeEventArgs event + /// + public enum eTreeAction + { + /// + /// The event was caused by a keystroke. + /// + Keyboard, + /// + /// The event was caused by a mouse operation. + /// + Mouse, + /// + /// The event was caused by the Node collapsing. + /// + Collapse, + /// + /// The event was caused by the Node expanding. + /// + Expand, + /// + /// The event is caused programmatically from user code. + /// + Code + } + + /// + /// 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. + /// + public enum eNodeConnectorType + { + ///// + ///// Curved line connector type. + ///// + //Curve, + /// + /// Straight line connector type. + /// + Line + } + + ///// + ///// Specifies the cap style with which the connector line will start or end. + ///// + //public enum eConnectorCap + //{ + // /// + // /// Specifies no cap. + // /// + // None, + // /// + // /// Round cap type. + // /// + // Ellipse, + // /// + // /// Arrow cap type. + // /// + // Arrow + //} + + /// + /// Specifies the layout type used to position the cells within the nodes. + /// + public enum eCellLayout + { + /// + /// 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. + /// + Default, + /// Horizontal layout positions the cells horizontally next to each other. + Horizontal, + /// + /// Vertical layout positions cell vertically on top of each other. + /// + Vertical + } + + /// + /// Specifies the layout type used to position the parts of the cell like image, checkbox and text. + /// + public enum eCellPartLayout + { + /// + /// 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. + /// + Default, + /// Horizontal layout positions the parts of the cell horizontally next to each other. + Horizontal, + /// + /// Vertical layout positions parts of the cell vertically on top of each other. + /// + Vertical + } + + /// + /// Specifies the color scheme loaded by ColorScheme object. + /// + public enum eColorSchemeStyle + { + /// + /// Indicates Office 2003 like color scheme. + /// + Office2003, + /// + /// Indicates VS.NET 2005 like color scheme. + /// + VS2005, + /// + /// Indicates Office 2007 like color scheme. + /// + Office2007 + } + + /// + /// Specifies the currently selected system color scheme if running on Windows XP. + /// + internal enum eWinXPColorScheme + { + /// + /// Color scheme cannot be determined. + /// + Undetermined, + /// + /// Blue color scheme. + /// + Blue, + /// + /// Olive green color scheme. + /// + OliveGreen, + /// + /// Silver color scheme. + /// + Silver + } + + /// + /// Specifies the flow of diagram layout related to the root node. + /// + public enum eDiagramFlow + { + /// + /// Nodes are positioned from left to right with root node being the left-most node. + /// + LeftToRight, + /// + /// Nodes are positioned from right to left with root node being the right-most + /// node. + /// + RightToLeft, + /// + /// Nodes are positioned from top to bottom with root node being the top node. + /// + TopToBottom, + /// + /// Nodes are positioned from bottom to top with root node being bottom node. + /// + BottomToTop + } + + /// + /// Specifies the flow of the map layout. + /// + public enum eMapFlow + { + /// + /// Nodes are arranged around the root node. + /// + Spread, + /// + /// Nodes are arranged from below the root node. + /// + TopToBottom, + /// + /// Nodes are arranged above the root node. + /// + BottomToTop, + /// + /// Nodes are arranged to the right of the root node. + /// + LeftToRight, + /// + /// Nodes are arranged to the left of the root node. + /// + RightToLeft + } + + /// + /// Specifies the type of the expand button. + /// + public enum eExpandButtonType + { + /// + /// Indicates elliptical expand button. + /// + Ellipse, + /// + /// Indicates rectangular expand button. + /// + Rectangle, + /// + /// Indicates that images are used for expand button. + /// + Image, + /// + /// Indicates the Windows Vista style expand button. + /// + Triangle + } + + /// + /// Specifies the visual style for the tree control. + /// + public enum eVisualStyle + { + /// + /// Indicates default visual style. + /// + Default + } + + /// + /// Specifies the layout type for the nodes. + /// + public enum eNodeLayout + { + /// + /// Nodes are arranged around root node in map format. + /// + Map, + /// + /// Nodes are arranged from left-to-right in diagram format. + /// + Diagram + } + + /// + /// Specifies renderer type used to render nodes. + /// + public enum eNodeRenderMode + { + + /// + /// Specifies default renderer which allows most customization through AdvTree + /// properties. Default renderer integrates with the Style architecture to provide + /// customization on renderer behavior. + /// + Default, + ///// + ///// 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. + ///// Professional renderer colors can be controls through + ///// NodeProfessionalColorTable object which is exposed by + ///// NodeProfessionalRenderer.ColorTable property. + ///// + //Professional, + /// + /// Specifies that custom renderer is used. When set you must also set NodeRenderer + /// to renderer you want to use. + /// + Custom + } + + /// + /// Specifies the node selection style. + /// + public enum eSelectionStyle + { + /// + /// Node selector highlights the complete node row when node is selected. + /// + FullRowSelect, + /// + /// Node selector draws the rectangle that highlights the node content. Appearance similar to system tree view in Windows Vista. + /// + HighlightCells, + /// + /// Node selector draws hollow selection rectangle around the node. + /// + NodeMarker, + } + + /// + /// Specifies the rule for multi-node selection. + /// + public enum eMultiSelectRule + { + /// + /// Allows multiple selection of nodes with same parent node only. + /// + SameParent, + /// + /// Allows multiple selection of any node. + /// + AnyNode + } + + /// + /// Gets or sets the image alignment inside of column header. + /// + public enum eColumnImageAlignment + { + /// + /// Image is left aligned. + /// + Left, + /// + /// Image is right aligned. + /// + Right + } + + /// + /// Specifies the editor type used when cell is edited. + /// + public enum eCellEditorType + { + /// + /// Indicates default, text based editor. + /// + Default, + /// + /// Indicates that Integer numeric editor will be used for editing the value of the cell or column. + /// + NumericInteger, + /// + /// Indicates that Double numeric editor will be used for editing the value of the cell or column. + /// + NumericDouble, + /// + /// Indicates that Currency numeric editor will be used for editing the value of the cell or column. + /// + NumericCurrency, + /// + /// Indicates that date editor will be used for editing the value of the cell or column. + /// + Date, + /// + /// Indicates that time editor will be used for editing the value of the cell or column. + /// + Time, + /// + /// Indicates that date and time editor will be used for editing the value of the cell or column. + /// + DateTime, + /// + /// Indicates that cell will use custom editor that you provide by handling AdvTree.ProvideCustomCellEditor event. + /// + Custom + } + /// + /// Specifies the sort direction for the column header. + /// + public enum eSortDirection + { + /// + /// No sort is specified. + /// + None, + /// + /// Ascending sorting is in effect, i.e. A-Z + /// + Ascending, + /// + /// Descending sorting is in effect, i.e. Z-A + /// + Descending + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/EventDelegates.cs b/PROMS/DotNetBar Source Code/AdvTree/EventDelegates.cs new file mode 100644 index 00000000..6da07b7e --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/EventDelegates.cs @@ -0,0 +1,98 @@ +using System; +using DevComponents.AdvTree.Display; + +namespace DevComponents.AdvTree +{ + /// + /// Defines the delegate for AdvTree cell based action events. + /// + public delegate void AdvTreeCellEventHandler(object sender, AdvTreeCellEventArgs e); + + /// + /// Defines the delegate for AdvTree cell based action events. + /// + public delegate void AdvTreeCellCancelEventHandler(object sender, TreeCellCancelEventArgs e); + + /// + /// Defines the delegate for AdvTree node based action events that can be cancelled. + /// + public delegate void AdvTreeNodeCancelEventHandler(object sender, AdvTreeNodeCancelEventArgs e); + + /// + /// Defines the delegate for AdvTree node based action events. + /// + public delegate void AdvTreeNodeEventHandler(object sender, AdvTreeNodeEventArgs e); + + /// + /// Defines delegate for Command button events. + /// + public delegate void CommandButtonEventHandler(object sender, CommandButtonEventArgs e); + + /// + /// Defines delegate for label editing events. + /// + public delegate void CellEditEventHandler(object sender, CellEditEventArgs e); + + /// + /// Defines the delegate for AdvTree node based action events. + /// + public delegate void TreeNodeCollectionEventHandler(object sender, TreeNodeCollectionEventArgs e); + + /// + /// Defines the delegate for BeforeNodeDrop and AfterNodeDrop events + /// + public delegate void TreeDragDropEventHandler(object sender, TreeDragDropEventArgs e); + + /// + /// Defines the delegate for NodeDragFeedback event. + /// + public delegate void TreeDragFeedbackEventHander(object sender, TreeDragFeedbackEventArgs e); + + /// + /// Defines the delegate for mouse based node events + /// + public delegate void TreeNodeMouseEventHandler(object sender, TreeNodeMouseEventArgs e); + + /// + /// Defines delegate for node rendering events. + /// + public delegate void NodeRendererEventHandler(object sender, NodeRendererEventArgs e); + + /// + /// Defines delegate for cell rendering events. + /// + public delegate void NodeCellRendererEventHandler(object sender, NodeCellRendererEventArgs e); + + /// + /// Defines delegate for RenderExpandPart event. + /// + public delegate void NodeExpandPartRendererEventHandler(object sender, NodeExpandPartRendererEventArgs e); + + ///// + ///// Defines delegate for RenderExpandPart event. + ///// + //public delegate void NodeCommandPartRendererEventHandler(object sender, NodeCommandPartRendererEventArgs e); + + /// + /// Defines delegate for RenderExpandPart event. + /// + public delegate void SelectionRendererEventHandler(object sender, SelectionRendererEventArgs e); + /// + /// Defines delegate for RenderConnector event. + /// + public delegate void ConnectorRendererEventHandler(object sender, ConnectorRendererEventArgs e); + /// + /// Defines delegate for TreeBackgroundRenderer events. + /// + public delegate void TreeBackgroundRendererEventHandler(object sender, TreeBackgroundRendererEventArgs e); + /// + /// Defines delegate for RenderDragDropMarker event. + /// + public delegate void DragDropMarkerRendererEventHandler(object sender, DragDropMarkerRendererEventArgs e); + /// + /// Defines delegate for RenderColumnHeader event. + /// + public delegate void ColumnHeaderRendererEventHandler(object sender, ColumnHeaderRendererEventArgs e); + + public delegate void AdvTreeCellBeforeCheckEventHandler(object sender, AdvTreeCellBeforeCheckEventArgs e); +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Events/CustomCellEditorEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Events/CustomCellEditorEventArgs.cs new file mode 100644 index 00000000..e24d95f6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Events/CustomCellEditorEventArgs.cs @@ -0,0 +1,34 @@ +using System; +using System.Text; + +namespace DevComponents.AdvTree +{ + /// + /// Provides data for the ProvideCustomCellEditor event. + /// + public class CustomCellEditorEventArgs : EventArgs + { + /// + /// Gets or sets the cell editor. You must set this property in your event handler to the custom + /// editor to be used for cell editing. + /// + public ICellEditControl EditControl = null; + /// + /// Gets the cell editor will be used for. + /// + public readonly Cell Cell; + + /// + /// Initializes a new instance of the CustomCellEditorEventArgs class. + /// + /// + public CustomCellEditorEventArgs(Cell cell) + { + Cell = cell; + } + } + /// + /// Defines delegate for ProvideCustomCellEditor event. + /// + public delegate void CustomCellEditorEventHandler(object sender, CustomCellEditorEventArgs e); +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Events/MarkupLinkClickEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Events/MarkupLinkClickEventArgs.cs new file mode 100644 index 00000000..0cfecee9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Events/MarkupLinkClickEventArgs.cs @@ -0,0 +1,36 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Provides more information about MarkupLinkClick event. + /// + public class MarkupLinkClickEventArgs : EventArgs + { + /// + /// Gets the value of href attribute from the markup link that was clicked. + /// + public readonly string HRef = ""; + + /// + /// Gets the value of name attribute from the markup link that was clicked. + /// + public readonly string Name = ""; + + /// + /// Creates new instance of the object. + /// + /// Value of name attribute. + /// Value of href attribute. + public MarkupLinkClickEventArgs(string name, string href) + { + this.HRef = href; + this.Name = name; + } + } + + /// + /// Defines delegate for MarkupLinkClick event. + /// + public delegate void MarkupLinkClickEventHandler(object sender, MarkupLinkClickEventArgs e); +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Events/SerializeNodeEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/Events/SerializeNodeEventArgs.cs new file mode 100644 index 00000000..6424cf0f --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Events/SerializeNodeEventArgs.cs @@ -0,0 +1,38 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Represents arguments for SerializeNode event which allows you to add custom serialization data to definitions saved by control. + /// + public class SerializeNodeEventArgs : EventArgs + { + /// + /// Gets reference to the node being serialized or de-serialized. + /// + public Node Node = null; + + /// + /// 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. + /// + public System.Xml.XmlElement ItemXmlElement = null; + + /// + /// 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. + /// + 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; + } + } + + /// + /// Defines delegate for SerializeItem event. + /// + public delegate void SerializeNodeEventHandler(object sender, SerializeNodeEventArgs e); +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/HeaderDefinition.cs b/PROMS/DotNetBar Source Code/AdvTree/HeaderDefinition.cs new file mode 100644 index 00000000..35a7a948 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/HeaderDefinition.cs @@ -0,0 +1,40 @@ +using System; +using System.ComponentModel; + +namespace DevComponents.AdvTree +{ + /// + /// Represents the table header. + /// + public class HeaderDefinition + { + private string m_Name=""; + private ColumnHeaderCollection m_Columns=new ColumnHeaderCollection(); + + /// + /// Default constructor. + /// + public HeaderDefinition() + { + } + + /// + /// Gets the reference to the collection that contains the columns associated with header. + /// + [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;} + } + + /// + /// Gets or sets the name associated with this header definition. + /// + [Browsable(true),Category("Design"),Description("Indicates name associated with this header definition."),DefaultValue("")] + public string Name + { + get {return m_Name;} + set {m_Name=value;} + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/HeadersCollection.cs b/PROMS/DotNetBar Source Code/AdvTree/HeadersCollection.cs new file mode 100644 index 00000000..1ba13231 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/HeadersCollection.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections; +using System.ComponentModel; + +namespace DevComponents.AdvTree +{ + /// + /// Represents collection for HeaderDefinition objects. + /// + public class HeadersCollection:CollectionBase + { + #region Private Variables + private AdvTree m_Parent=null; + #endregion + + #region Internal Implementation + /// + /// Gets or sets the node this collection is associated with. + /// + [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AdvTree Parent + { + get {return m_Parent;} + } + /// + /// Sets the node collection belongs to. + /// + /// HeaderDefinition that is parent of this collection. + internal void SetParent(AdvTree parent) + { + m_Parent=parent; + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(HeaderDefinition ch) + { + return List.Add(ch); + } + /// + /// Returns reference to the object in collection based on it's index. + /// + public HeaderDefinition this[int index] + { + get {return (HeaderDefinition)(List[index]);} + set {List[index] = value;} + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, HeaderDefinition value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(HeaderDefinition value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(HeaderDefinition value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + 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); + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(HeaderDefinition[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the HeaderDefinition array. + /// + /// Array to copy to. + 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 + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/INodeNotify.cs b/PROMS/DotNetBar Source Code/AdvTree/INodeNotify.cs new file mode 100644 index 00000000..040d7ccf --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/INodeNotify.cs @@ -0,0 +1,26 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Specifies the notification interface that node uses to communicate status changes to it's parent tree. + /// + public interface INodeNotify + { + /// Called when Node.Expanded property has changed. + /// Node which Expanded property has changed. + void ExpandedChanged(Node node); + /// Called before node is collapsed + /// Context information. + void OnBeforeCollapse(AdvTreeNodeCancelEventArgs e); + /// Called before node is expanded + /// Context information. + void OnBeforeExpand(AdvTreeNodeCancelEventArgs e); + /// Called after node is collapsed. + /// Context information. + void OnAfterCollapse(AdvTreeNodeEventArgs e); + /// Called after node is expanded + /// Context information + void OnAfterExpand(AdvTreeNodeEventArgs e); + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Interop/WinApi.cs b/PROMS/DotNetBar Source Code/AdvTree/Interop/WinApi.cs new file mode 100644 index 00000000..489a6eeb --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Interop/WinApi.cs @@ -0,0 +1,58 @@ +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System; + +namespace DevComponents.AdvTree.Interop +{ + /// + /// Provides WinApi functions to rest of the application. + /// + 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 IntPtr 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 + /// + /// Resets Hoover timer for specified control. + /// + 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 = c.Handle; + tme.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(tme); + TrackMouseEvent(ref tme); + tme.dwFlags = tme.dwFlags | TME_HOVER; + TrackMouseEvent(ref tme); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/KeyNavigation.cs b/PROMS/DotNetBar Source Code/AdvTree/KeyNavigation.cs new file mode 100644 index 00000000..853e9fe5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/KeyNavigation.cs @@ -0,0 +1,370 @@ +using System; +using System.Windows.Forms; +using System.Drawing; + +namespace DevComponents.AdvTree +{ + /// + /// Provides AdvTree Keyboard handling. + /// + internal class KeyNavigation + { + public static void KeyDown(AdvTree tree, KeyEventArgs e) + { + Node node = tree.SelectedNode; + if (node != null) + { + node.InternalKeyDown(e); + if (e.Handled) return; + } + + switch(e.KeyCode) + { + case Keys.Space: + { + SpaceKeyDown(tree, e); + e.Handled = true; + break; + } + case Keys.Add: + { + e.Handled = PlusKeyDown(tree, e); + break; + } + case Keys.Subtract: + { + e.Handled = MinusKeyDown(tree, e); + break; + } + case Keys.F2: + { + F2KeyDown(tree, e); + break; + } + default: + { + if (e.Control && e.KeyCode == Keys.C) + CopyKeyDown(tree, e); + else if (e.Control && e.KeyCode == Keys.V) + PasteKeyDown(tree, e); + break; + } + } + } + + private static bool MinusKeyDown(AdvTree tree, KeyEventArgs e) + { + Node node = tree.SelectedNode; + if (node != null && tree.SelectedNodes.Count == 1 && node.Expanded) + { + node.Collapse(); + return true; + } + return false; + } + private static bool PlusKeyDown(AdvTree tree, KeyEventArgs e) + { + Node node = tree.SelectedNode; + if (node != null && tree.SelectedNodes.Count == 1 && !node.Expanded) + { + node.Expand(); + return true; + } + return false; + } + + private static void PasteKeyDown(AdvTree tree, KeyEventArgs args) + { + if (tree.SelectedNode != null) + tree.SelectedNode.InvokeKeyboardPaste(args); + } + + private static void CopyKeyDown(AdvTree tree, KeyEventArgs args) + { + if (tree.SelectedNode != null) + tree.SelectedNode.InvokeKeyboardCopy(args); + } + + private static void F2KeyDown(AdvTree tree, KeyEventArgs e) + { + if (tree.EditSelectedCell(eTreeAction.Keyboard)) + e.Handled = true; + } + + public static void SpaceKeyDown(AdvTree tree, KeyEventArgs e) + { + Node node = tree.SelectedNode; + if (node != null && node.CheckBoxVisible && node.Enabled) + { + if (node.CheckBoxThreeState) + { + if (node.CheckState == CheckState.Checked) + node.SetChecked(CheckState.Indeterminate, eTreeAction.Keyboard); + else if (node.CheckState == CheckState.Unchecked) + node.SetChecked(CheckState.Checked, eTreeAction.Keyboard); + else if (node.CheckState == CheckState.Indeterminate) + node.SetChecked(CheckState.Unchecked, eTreeAction.Keyboard); + } + else + node.SetChecked(!node.Checked, eTreeAction.Keyboard); + e.Handled = true; + } + } + + public static void EnterKeyDown(AdvTree tree, KeyEventArgs e) + { + if (tree.SelectedNode != null && tree.SelectedNode.Nodes.Count > 0) + { + tree.SelectedNode.Toggle(eTreeAction.Keyboard); + } + } + + public static bool NavigateKeyDown(AdvTree tree, KeyEventArgs e) + { + if(tree.SelectedNode==null) + { + if(tree.DisplayRootNode!=null) + tree.SelectNode(tree.DisplayRootNode, eTreeAction.Keyboard); + else if (tree.Nodes.Count > 0) + { + Node firstSelectable = NodeOperations.GetFirstVisibleNode(tree); + if (firstSelectable != null) + { + while (firstSelectable!=null && !firstSelectable.Selectable) + firstSelectable = NodeOperations.GetNextVisibleNode(firstSelectable); + if (firstSelectable != null) + tree.SelectNode(firstSelectable, eTreeAction.Keyboard); + } + } + return true; + } + + Node node = tree.SelectedNode; + if (node != null && !node.IsKeyboardNavigationEnabled(e)) + { + return false; + } + + if(e.KeyCode == Keys.Right) + { + if (node != null && node.Cells.Count > 1 && tree.SelectionPerCell && node.CellNavigationEnabled) + { + if (node.SelectedCell == null) + node.SetSelectedCell(NodeOperations.GetNextVisibleCell(node, -1), eTreeAction.Keyboard); + else + node.SetSelectedCell(NodeOperations.GetNextVisibleCell(node, node.Cells.IndexOf(node.SelectedCell)), eTreeAction.Keyboard); + return true; + } + + if (tree.View == eView.Tile) + { + Node nextNode = NodeOperations.GetNextVisibleNode(node); + if (nextNode != null) + { + if (node.Expanded || !node.HasChildNodes) + tree.SelectNode(nextNode, eTreeAction.Keyboard); + else + node.Expand(eTreeAction.Keyboard); + } + else if (node != null && node.ExpandVisibility == eNodeExpandVisibility.Visible && !node.Expanded) + node.Expand(eTreeAction.Keyboard); + } + else + { + Node childNode = NodeOperations.GetFirstVisibleChildNode(node); + if (childNode != null) + { + if (node.Expanded) + tree.SelectNode(childNode, eTreeAction.Keyboard); + else + node.Expand(eTreeAction.Keyboard); + } + else if (node != null && node.ExpandVisibility == eNodeExpandVisibility.Visible && !node.Expanded) + node.Expand(eTreeAction.Keyboard); + } + } + else if(e.KeyCode == Keys.Left) + { + if (node != null && node.Cells.Count > 1 && tree.SelectionPerCell && node.CellNavigationEnabled) + { + if (node.SelectedCell == null) + node.SetSelectedCell(NodeOperations.GetPreviousVisibleCell(node, node.Cells.Count - 1), eTreeAction.Keyboard); + else + node.SetSelectedCell(NodeOperations.GetPreviousVisibleCell(node, node.Cells.IndexOf(node.SelectedCell)), eTreeAction.Keyboard); + return true; + } + + if (tree.View == eView.Tile) + { + Node previousNode = NodeOperations.GetPreviousVisibleNode(node); + if (previousNode != null) + tree.SelectNode(previousNode, eTreeAction.Keyboard); + } + else + { + if (node.Expanded && node.IsSelected && NodeOperations.GetFirstVisibleChildNode(node) != null) + node.Collapse(eTreeAction.Keyboard); + else if (node.Parent != null) + tree.SelectNode(node.Parent, eTreeAction.Keyboard); + } + } + else if (e.KeyCode == Keys.End) + { + Node last = NodeOperations.GetLastVisibleNode(tree); + if (last != null) + { + if (!last.Selectable) + { + while (last != null) + { + last = NodeOperations.GetPreviousVisibleNode(last); + if (last!=null && last.Selectable) break; + } + } + if (last != null) + tree.SelectNode(last, eTreeAction.Keyboard); + } + } + else if (e.KeyCode == Keys.Home || e.KeyCode == Keys.PageDown && node == null) + { + Node first = NodeOperations.GetFirstVisibleNode(tree); + if (first != null) + { + if (!first.Selectable) + { + while (first != null) + { + first = NodeOperations.GetNextVisibleNode(first); + if (first != null && first.Selectable) break; + } + } + if (first != null) + tree.SelectNode(first, eTreeAction.Keyboard); + } + } + else if (e.KeyCode == Keys.PageDown) + { + // Find last fully rendered node + Node lastNode = NodeOperations.GetLastDisplayedNode(tree); + if (lastNode != null) + { + if (tree.SelectedNode == lastNode) + { + if (tree.VScrollBar != null && tree.AutoScroll) + { + tree.AutoScrollPosition = new Point(tree.AutoScrollPosition.X, Math.Max(tree.AutoScrollPosition.Y - tree.VScrollBar.LargeChange, -(tree.VScrollBar.Maximum - tree.VScrollBar.LargeChange))); + lastNode = NodeOperations.GetLastDisplayedNode(tree); + } + } + } + if (lastNode != null) + tree.SelectNode(lastNode, eTreeAction.Keyboard); + } + else if (e.KeyCode == Keys.PageUp) + { + // Find last fully rendered node + Node firstNode = NodeOperations.GetFirstDisplayedNode(tree); + if (firstNode != null) + { + if (tree.SelectedNode == firstNode) + { + if (tree.VScrollBar != null && tree.AutoScroll && tree.AutoScrollPosition.Y < 0) + { + tree.AutoScrollPosition = new Point(tree.AutoScrollPosition.X, Math.Min(0, tree.AutoScrollPosition.Y + tree.VScrollBar.LargeChange)); + firstNode = NodeOperations.GetFirstDisplayedNode(tree); + } + } + } + if (firstNode != null) + tree.SelectNode(firstNode, eTreeAction.Keyboard); + } + else if ((e.KeyCode & Keys.Down) == Keys.Down) + { + 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 (nextNode != null) + { + 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) == Keys.Up) + { + 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 (prevNode != null) + { + 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); + } + } + } + } + return true; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Layout/CellTileLayout.cs b/PROMS/DotNetBar Source Code/AdvTree/Layout/CellTileLayout.cs new file mode 100644 index 00000000..70a01e08 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Layout/CellTileLayout.cs @@ -0,0 +1,393 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Layout +{ + internal class CellTileLayout : CellLayout + { + /// + /// Initializes a new instance of the CellTileLayout class. + /// + public CellTileLayout(LayoutSettings layoutSettings) : base(layoutSettings) + { + + } + public override 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.Default && !(layoutInfo.ContextNode.HasChildNodes && layoutInfo.IsViewGroupping) && layoutInfo.ContextNode.ImageAlignment == eCellPartAlignment.Default) + { + return TileLayout(layoutInfo, x, y); + } + else + return base.LayoutCells(layoutInfo, x, y); + + } + private Size TileLayout(NodeLayoutContextInfo layoutInfo, int x, int y) + { + Node node = layoutInfo.ContextNode; + int height = 0, width = 0, realHeight = 0; + //eHorizontalAlign align = eHorizontalAlign.Left; + Size tileSize = layoutInfo.TileSize; + int iVisibleCells = 0; + int cellCount = node.Cells.Count; + bool isVerticalOverflow = false; + for (int i = 0; i < cellCount; i++) + { + Cell cell = node.Cells[i]; + + bool bCellVisible = isVerticalOverflow ? false : true; + + // Setup cell layout helper class + LayoutCellInfo cellLayout = this.GetLayoutCellInfo(); + cellLayout.Top = y; + cellLayout.Left = x; + cellLayout.CellWidth = tileSize.Width; + cellLayout.ContextCell = cell; + cellLayout.Graphics = layoutInfo.Graphics; + cellLayout.LeftToRight = layoutInfo.LeftToRight; + cellLayout.Font = layoutInfo.DefaultFont; + cellLayout.View = layoutInfo.View; + cellLayout.CellIndex = i; + if (cell.Layout != eCellPartLayout.Default) + cellLayout.VerticalPartAlignment = (cell.Layout == eCellPartLayout.Vertical); + else if (layoutInfo.CellPartLayout != eCellPartLayout.Default) + cellLayout.VerticalPartAlignment = (layoutInfo.CellPartLayout == eCellPartLayout.Vertical); + + // Prepare union style + if (cell.StyleNormal != null) + cellLayout.LayoutStyle = cell.StyleNormal; + else + cellLayout.LayoutStyle = layoutInfo.DefaultCellStyle; + + this.LayoutSingleTileCell(cellLayout); + if (bCellVisible && y + cell.BoundsRelative.Height > tileSize.Height && i > 0) + { + isVerticalOverflow = true; + bCellVisible = false; + } + 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; + if (i == 0) + { + realHeight += cell.BoundsRelative.Height; + if (cell.BoundsRelative.Height > 0) + realHeight += this.CellVerticalSpacing; + } + else + realHeight = Math.Max(realHeight, height); + + // Align other cells under the text of the first cell and to the right of the image, if any + if (i == 0 && !cell.Images.LargestImageSize.IsEmpty && cellCount > 1) + { + Size largestImageSize = Dpi.ImageSize(cell.Images.LargestImageSize); + if (cell.TextContentBounds.IsEmpty) + x += largestImageSize.Width + this.ImageTextSpacing; + else + x += (cell.TextContentBounds.X - x); + tileSize.Width = cell.TextContentBounds.Width; + height -= cell.BoundsRelative.Height; + height += cell.TextContentBounds.Height; + y -= cell.BoundsRelative.Height; + y += cell.TextContentBounds.Height; + } + } + } + + // Take last added spacing off + y -= this.CellVerticalSpacing; + height -= this.CellVerticalSpacing; + realHeight -= this.CellVerticalSpacing; + + if (node.Cells[0].BoundsRelative.Height > height && !node.Cells[0].Images.LargestImageSize.IsEmpty) + { + int textOffset = ((realHeight - height) / iVisibleCells) / 2; + if (textOffset > 0) + { + foreach (Cell cell in node.Cells) + { + if (!cell.IsVisible) continue; + cell.TextContentBounds = new Rectangle(cell.TextContentBounds.X, cell.TextContentBounds.Y + textOffset, cell.TextContentBounds.Width, cell.TextContentBounds.Height); + } + } + } + else if(iVisibleCells == 1) + { + Rectangle rtc = node.Cells[0].TextContentBounds; + node.Cells[0].TextContentBounds = new Rectangle(rtc.X, rtc.Y, rtc.Width, node.Cells[0].BoundsRelative.Height); + } + + // 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); + // } + //} + if (width < layoutInfo.TileSize.Width) + width = layoutInfo.TileSize.Width; + if (realHeight < layoutInfo.TileSize.Height) + realHeight = layoutInfo.TileSize.Height; + return new Size(width, realHeight); + } + + protected virtual void LayoutSingleTileCell(LayoutCellInfo info) + { + Size textSize = Size.Empty; + Font font = info.Font; + int fontHeight = info.FontHeight; + int height = 0; + if (info.LayoutStyle.Font != null) + { + font = info.LayoutStyle.Font; + fontHeight = font.Height; + } + + info.ContextCell.OnLayoutCell(); + + Size largestImageSize = info.ContextCell.Images.LargestImageSize; + if (largestImageSize.IsEmpty && HasImage(info.ContextCell)) + info.ContextCell.Images.RefreshLargestImageSize(); + largestImageSize = Dpi.ImageSize(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 if (info.ContextCell.HostedItem != null) + { + if (info.CellWidth != 0) info.ContextCell.HostedItem.WidthInternal = info.CellWidth; + info.ContextCell.HostedItem.RecalcSize(); + + Size controlSize = info.ContextCell.HostedItem.Size; + 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); + info.ContextCell.HostedItem.WidthInternal = availTextWidth; + } + } + else + { + // Calculate Text Width and Height + if (info.CellWidth == 0) + { + if (info.ContextCell.TextMarkupBody == null) + { + string text = info.ContextCell.DisplayText; + 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, 0, eTextFormat.Left | eTextFormat.LeftAndRightPadding | eTextFormat.GlyphOverhangPadding | eTextFormat.NoPrefix); +#if (FRAMEWORK20) + if (!BarFunctions.IsVista && BarUtilities.UseTextRenderer) textSize.Width += 4; +#endif + } + else if (largestImageSize.IsEmpty && !info.ContextCell.CheckBoxVisible) + { + textSize = new Size(5, fontHeight); + } + } + 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; + + DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.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 + + (largestImageSize.Width > 0 ? ImageTextSpacing * 2 : 0); + + if (info.ContextCell.CheckBoxVisible) + availTextWidth -= CheckBoxSize.Width + ImageTextSpacing * 2; + + int cellHeight = fontHeight; + + if (info.LayoutStyle.WordWrap || info.ContextCell.TextMarkupBody != null) + { + 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.DisplayText, font, new Size(availTextWidth, cellHeight), info.LayoutStyle.TextFormat); + else + textSize = TextDrawing.MeasureString(info.Graphics, info.ContextCell.DisplayText, font, availTextWidth, info.LayoutStyle.TextFormat); + } + } + else + { + Size availSize = new Size(availTextWidth, 1); + DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.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.Max(height, Math.Ceiling((double)textSize.Height)); + if (info.VerticalPartAlignment) + { + if (largestImageSize.Height > 0) + height += largestImageSize.Height + this.ImageTextSpacing; + if (info.ContextCell.CheckBoxVisible) + height += CheckBoxSize.Height + this.ImageCheckBoxSpacing; + } + 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 check box + if (info.ContextCell.CheckBoxVisible && rCellBounds.Width >= this.CheckBoxSize.Width) + { + eVerticalAlign va = GetCheckBoxVerticalAlign(info.ContextCell.CheckBoxAlignment, info.View); + eHorizontalAlign ha = GetCheckBoxHorizontalAlign(info.ContextCell.CheckBoxAlignment, info.LeftToRight, info.View); + if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || !largestImageSize.IsEmpty)) + ha = eHorizontalAlign.Left; + + 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 image + if (!largestImageSize.IsEmpty && rCellBounds.Width >= largestImageSize.Width) + { + eVerticalAlign va = GetVerticalAlign(info.ContextCell.ImageAlignment, info.View); + eHorizontalAlign ha = GetHorizontalAlign(info.ContextCell.ImageAlignment, info.LeftToRight, info.View); + if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || info.ContextCell.CheckBoxVisible)) + ha = eHorizontalAlign.Left; + + 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 text + //info.ContextCell.SetTextBounds(Rectangle.Empty); + if (!textSize.IsEmpty) + { + if (info.CellWidth > 0) + r.Width -= 2; + if (info.View == eView.Tile && info.CellIndex == 0) + info.ContextCell.TextContentBounds = new Rectangle(r.X, r.Y, textSize.Width, textSize.Height + 1); + else + info.ContextCell.TextContentBounds = r; + } + else + info.ContextCell.TextContentBounds = Rectangle.Empty; + + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Layout/ColumnHeaderLayout.cs b/PROMS/DotNetBar Source Code/AdvTree/Layout/ColumnHeaderLayout.cs new file mode 100644 index 00000000..d4052832 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Layout/ColumnHeaderLayout.cs @@ -0,0 +1,193 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Layout +{ + /// + /// Class that is used to layout column header. + /// + 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) + { + ColumnHeaderCollection columns = null; + Node node=layoutInfo.ContextNode; + if (node == null) + columns = layoutInfo.TreeColumns; + else + columns = node.NodesColumns; + columns.UsesRelativeSize = false; + int height=0; + bool adjustHeight = false; + Rectangle totalBounds = Rectangle.Empty; + ColumnHeader lastVisibleColumn = null; + ColumnHeader stretchToFillColumn = null; + bool allRelative = true; + bool firstVisible = true; + for (int i = 0; i < columns.Count; i++) + { + ColumnHeader col = columns.ColumnAtDisplayIndex(i); + col.IsLastVisible = false; + if(!col.Visible) + continue; + col.IsFirstVisible = firstVisible; + firstVisible = false; + //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.AutoSize) + { + int autoWidth = col.Width.AutoSizeWidth; + if (col.Width.AutoSizeMinHeader) + { + Font headerFont = layoutInfo.DefaultFont; + if (!string.IsNullOrEmpty(col.StyleNormal)) + { + ElementStyle style = layoutInfo.Styles[col.StyleNormal]; + if (style != null && style.Font != null) + headerFont = style.Font; + } + else if (layoutInfo.ColumnStyle != null && layoutInfo.ColumnStyle.Font != null) + headerFont = layoutInfo.ColumnStyle.Font; + if (headerFont != null) + { + int columnHeaderTextWidth = (int)Math.Ceiling(layoutInfo.Graphics.MeasureString(col.Text, headerFont).Width) + 2; + autoWidth = Math.Max(autoWidth, columnHeaderTextWidth); + col.Width.SetAutoSizeWidth(autoWidth); + } + } + bounds.Width = autoWidth; + allRelative = false; + } + else if (col.Width.Absolute > 0) + { + bounds.Width = col.Width.Absolute; + allRelative = false; + } + else if (col.Width.Absolute == -1) + { + bounds.Width = 0; + allRelative = false; + } + else if (col.Width.Relative > 0) + { + if (col.IsFirstVisible) + { + clientWidth -= layoutInfo.ExpandPartWidth; + bounds.Width = (clientWidth * col.Width.Relative) / 100 - cellHorizontalSpacing; + bounds.Width += layoutInfo.ExpandPartWidth; + } + else + bounds.Width = (clientWidth * col.Width.Relative) / 100 - cellHorizontalSpacing; + columns.UsesRelativeSize = true; + } + lastVisibleColumn = col; + + if (col.StretchToFill) + { + stretchToFillColumn = col; + columns.UsesRelativeSize = true; + } + + 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; + } + + if (col.Image != null && col.Image.Height+4>bounds.Height) + { + bounds.Height = col.Image.Height + 4; + } + + col.SetBounds(bounds); + col.SizeChanged=false; + + x += (bounds.Width + cellHorizontalSpacing); + + if (bounds.Height > height) + { + if (height > 0) + adjustHeight = true; + height = bounds.Height; + } + else if (bounds.Height < height) + adjustHeight = true; + } + + if (totalBounds.IsEmpty) + totalBounds = col.Bounds; + else + totalBounds = Rectangle.Union(totalBounds, col.Bounds); + } + if (adjustHeight) + { + foreach (ColumnHeader col in columns) + { + col.SetBounds(new Rectangle(col.Bounds.X, col.Bounds.Y, col.Bounds.Width, height)); + } + } + if (lastVisibleColumn != null && allRelative) + { + lastVisibleColumn.SetBounds(new Rectangle(lastVisibleColumn.Bounds.X, lastVisibleColumn.Bounds.Y, lastVisibleColumn.Bounds.Width + cellHorizontalSpacing, lastVisibleColumn.Bounds.Height)); + totalBounds = Rectangle.Union(totalBounds, lastVisibleColumn.Bounds); + } + + if (lastVisibleColumn != null) lastVisibleColumn.IsLastVisible = true; + + if (stretchToFillColumn != null && totalBounds.Width < clientWidth) + { + int stretch = clientWidth - totalBounds.Width; + if (stretchToFillColumn.IsFirstVisible && stretchToFillColumn.IsLastVisible) // Single column visible only case + stretch -= layoutInfo.Indent; + else if (stretchToFillColumn.Parent != null && stretchToFillColumn.Parent.ParentNode != null) + stretch -= layoutInfo.Indent; + stretchToFillColumn.SetBounds(new Rectangle(stretchToFillColumn.Bounds.X, stretchToFillColumn.Bounds.Y, + stretchToFillColumn.Bounds.Width + stretch, stretchToFillColumn.Bounds.Height)); + totalBounds = Rectangle.Union(totalBounds, stretchToFillColumn.Bounds); + if (!stretchToFillColumn.IsLastVisible) // Offset columns to the right if this was not last visible column + { + int startIndex = columns.GetDisplayIndex(stretchToFillColumn) + 1; + for (int i = startIndex; i < columns.Count; i++) + { + ColumnHeader col = columns.ColumnAtDisplayIndex(i); + if (!col.Visible) continue; + col.SetBounds(new Rectangle(col.Bounds.X + stretch, col.Bounds.Y, col.Bounds.Width, col.Bounds.Height)); + totalBounds = Rectangle.Union(totalBounds, col.Bounds); + } + } + } + + + columns.SetBounds(totalBounds); + return height; + } + + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Layout/LayoutSettings.cs b/PROMS/DotNetBar Source Code/AdvTree/Layout/LayoutSettings.cs new file mode 100644 index 00000000..1a99be55 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Layout/LayoutSettings.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.AdvTree.Layout +{ + internal class LayoutSettings + { + #region Internal Implementation + private int _NodeVerticalSpacing = 3; + /// + /// Gets or sets the vertical spacing between nodes in pixels. + /// + public virtual int NodeVerticalSpacing + { + get { return _NodeVerticalSpacing; } + set { _NodeVerticalSpacing = value; } + } + + private int _NodeHorizontalSpacing = 4; + /// + /// Gets or sets the horizontal spacing between nodes in pixels. + /// + public virtual int NodeHorizontalSpacing + { + get { return _NodeHorizontalSpacing; } + set { _NodeHorizontalSpacing = value; } + } + + private int _CellHorizontalSpacing = 5; + /// + /// Returns horizontal spacing between cells in a node + /// + public int CellHorizontalSpacing + { + get { return _CellHorizontalSpacing; } + set + { + _CellHorizontalSpacing = value; + } + } + + private int _ExpandAreaWidth = 24; + /// + /// Returns width of the expand button area. Default is 24 pixels. + /// + public virtual int ExpandAreaWidth + { + get { return _ExpandAreaWidth; } + set + { + _ExpandAreaWidth = value; + } + } + + protected Size _ExpandPartSize = new Size(8, 8); + /// + /// Gets or sets the size of the expand part that is expanding/collapsing the node. Default value is 8,8. + /// + public System.Drawing.Size ExpandPartSize + { + get { return _ExpandPartSize; } + set { _ExpandPartSize = value; } + } + + private int _CommandAreaWidth = 10; + /// + /// Gets or sets width of command button area. Default is 8 pixels. + /// + public virtual int CommandAreaWidth + { + get { return _CommandAreaWidth; } + set { _CommandAreaWidth = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeCellLayout.cs b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeCellLayout.cs new file mode 100644 index 00000000..69773d21 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeCellLayout.cs @@ -0,0 +1,888 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar; +using System.Collections; + +namespace DevComponents.AdvTree +{ + namespace Layout + { + /// + /// Represents class for Node's cell layout. + /// + internal class CellLayout + { + public CellLayout(LayoutSettings layoutSettings) + { + _LayoutSettings = layoutSettings; + } + + private LayoutSettings _LayoutSettings; + public LayoutSettings LayoutSettings + { + get { return _LayoutSettings; } + set { _LayoutSettings = value; } + } + /// + /// Offset cell bounds, check box bounds, image bounds and text bounds by specified offset. + /// + /// Cell to offset. + /// Horizontal offset in pixels. + /// Vertical offset in pixels. + protected void Offset(Cell cell, int x, int y) + { + if (x == 0 && y == 0) return; + 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); + } + + protected virtual void LayoutSingleCell(LayoutCellInfo info) + { + Size textSize = Size.Empty; + Font font = info.Font; + int fontHeight = info.FontHeight; // Uses cached FontHeight reference. Huge performance savings on some fonts!!! + int height = 0; + if (info.LayoutStyle.Font != null) + { + font = info.LayoutStyle.Font; + fontHeight = font.Height; + } + + info.ContextCell.OnLayoutCell(); + + if (info.ContextCell.Images.LargestImageSize.IsEmpty && HasImage(info.ContextCell)) + info.ContextCell.Images.RefreshLargestImageSize(); + Size largestImageSize = Dpi.ImageSize(info.ContextCell.Images.LargestImageSize); + Size checkBoxSize = Dpi.Size(CheckBoxSize); + 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 if (info.ContextCell.HostedItem != null) + { + if (info.CellWidth != 0) info.ContextCell.HostedItem.WidthInternal = info.CellWidth; + info.ContextCell.HostedItem.RecalcSize(); + + Size controlSize = info.ContextCell.HostedItem.Size; + 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); + info.ContextCell.HostedItem.WidthInternal = availTextWidth; + } + } + else + { + // Calculate Text Width and Height + string cellDisplayText = info.ContextCell.DisplayText; + if (info.CellWidth == 0) + { + if (info.ContextCell.TextMarkupBody == null) + { + string text = cellDisplayText; + 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, 0, eTextFormat.Left | eTextFormat.LeftAndRightPadding | eTextFormat.GlyphOverhangPadding | eTextFormat.NoPrefix); +#if (FRAMEWORK20) + if (!BarFunctions.IsVista && BarUtilities.UseTextRenderer) textSize.Width += 4; +#endif + } + else if (largestImageSize.IsEmpty && !info.ContextCell.CheckBoxVisible) + { + textSize = new Size(5, fontHeight); + } + } + 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; + + DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.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 + + (largestImageSize.Width > 0 ? ImageTextSpacing * 2 : 0); + + if (info.ContextCell.CheckBoxVisible) + availTextWidth -= checkBoxSize.Width + ImageTextSpacing * 2; + + int cellHeight = fontHeight; + + if (info.LayoutStyle.WordWrap || info.ContextCell.TextMarkupBody != null) + { + 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, cellDisplayText, font, new Size(availTextWidth, cellHeight), info.LayoutStyle.TextFormat); + if (textSize.Height == 0) textSize.Height = cellHeight; + } + else if (!string.IsNullOrEmpty(cellDisplayText)) + textSize = TextDrawing.MeasureString(info.Graphics, cellDisplayText, font, availTextWidth, info.LayoutStyle.TextFormat); + else + textSize = new Size(availTextWidth, fontHeight); + } + } + else + { + Size availSize = new Size(availTextWidth, 1); + DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d = new DevComponents.DotNetBar.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.Max(height, Math.Ceiling((double)textSize.Height)); + if (info.VerticalPartAlignment) + { + if (largestImageSize.Height > 0) + height += largestImageSize.Height + this.ImageTextSpacing; + if (info.ContextCell.CheckBoxVisible) + height += checkBoxSize.Height + this.ImageCheckBoxSpacing; + } + 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 check box + //Size checkBoxSize = this.CheckBoxSize; + if (info.ContextCell.CheckBoxVisible && rCellBounds.Width >= checkBoxSize.Width) + { + eVerticalAlign va = GetCheckBoxVerticalAlign(info.ContextCell.CheckBoxAlignment, info.View); + eHorizontalAlign ha = GetCheckBoxHorizontalAlign(info.ContextCell.CheckBoxAlignment, info.LeftToRight, info.View); + if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || !largestImageSize.IsEmpty)) + ha = eHorizontalAlign.Left; + if (info.VerticalPartAlignment) + info.ContextCell.SetCheckBoxBounds(AlignContentVertical(checkBoxSize, ref r, ha, va, this.ImageTextSpacing)); + else + info.ContextCell.SetCheckBoxBounds(AlignContent(checkBoxSize, ref r, ha, va, this.ImageTextSpacing)); + } + else + info.ContextCell.SetCheckBoxBounds(Rectangle.Empty); + + // Set Position of the image + if (!largestImageSize.IsEmpty && rCellBounds.Width >= largestImageSize.Width) + { + eVerticalAlign va = GetVerticalAlign(info.ContextCell.ImageAlignment, info.View); + eHorizontalAlign ha = GetHorizontalAlign(info.ContextCell.ImageAlignment, info.LeftToRight, info.View); + if (ha == eHorizontalAlign.Center && (!string.IsNullOrEmpty(info.ContextCell.Text) || info.ContextCell.CheckBoxVisible) && !info.VerticalPartAlignment) + ha = eHorizontalAlign.Left; + 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 text + //info.ContextCell.SetTextBounds(Rectangle.Empty); + if (!textSize.IsEmpty) + { + if (info.CellWidth > 0) + { + r.Width -= 2 + ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle); + } + info.ContextCell.TextContentBounds = r; + } + else + info.ContextCell.TextContentBounds = Rectangle.Empty; + + } + + protected 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.Center: + { + contentRect.X = boundingRectangle.X + (boundingRectangle.Width - contentRect.Width) / 2; + break; + } + default: + { + contentRect.X=boundingRectangle.X; + boundingRectangle.X=contentRect.Right+contentSpacing; + boundingRectangle.Width-=(contentRect.Width+contentSpacing); + 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; + } + + protected 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; + } + + public static eHorizontalAlign GetHorizontalAlign(eCellPartAlignment align, bool leftToRight, eView view) + { + if (align == eCellPartAlignment.Default) + { + if (view == eView.Tree) + align = eCellPartAlignment.NearCenter; + else if (view == eView.Tile) + align = eCellPartAlignment.NearCenter; + } + + 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; + } + + public static eVerticalAlign GetVerticalAlign(eCellPartAlignment align, eView view) + { + if (align == eCellPartAlignment.Default) + { + if (view == eView.Tree) + align = eCellPartAlignment.NearCenter; + else if (view == eView.Tile) + align = eCellPartAlignment.NearCenter; + } + 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; + } + + public static eHorizontalAlign GetCheckBoxHorizontalAlign(eCellPartAlignment align, bool leftToRight, eView view) + { + if (align == eCellPartAlignment.Default) + { + if (view == eView.Tree) + align = eCellPartAlignment.NearCenter; + else if (view == eView.Tile) + align = eCellPartAlignment.NearCenter; + } + + 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; + } + public static eVerticalAlign GetCheckBoxVerticalAlign(eCellPartAlignment align, eView view) + { + if (align == eCellPartAlignment.Default) + { + if (view == eView.Tree) + align = eCellPartAlignment.NearCenter; + else if (view == eView.Tile) + align = eCellPartAlignment.NearCenter; + } + 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 Size _CheckBoxSize = new Size(12, 12); + internal System.Drawing.Size CheckBoxSize + { + get + { + return _CheckBoxSize; + } + set + { + _CheckBoxSize = value; + } + } + internal void ResetCheckBoxSize() + { + _CheckBoxSize = new Size(12, 12); + } + + /// + /// Returns spacing between check box and image if both are displayed + /// + protected int ImageCheckBoxSpacing + { + get {return 4;} + } + + /// + /// Returns spacing between image or checkbox and text + /// + protected int ImageTextSpacing + { + get {return 4;} + } + + //private int _CellHorizontalSpacing = 5; + ///// + ///// Returns horizontal spacing between cells in a node + ///// + //public int CellHorizontalSpacing + //{ + // get {return _CellHorizontalSpacing;} + // set + // { + // _CellHorizontalSpacing = value; + // } + //} + + /// + /// Returns vertical spacing between cells in a node + /// + public int CellVerticalSpacing + { + get {return 1;} + } + + /// + /// Spacing between different parts of the cell, like image, option button, text and expand button area + /// + public int CellPartSpacing + { + get {return 1;} + } + + public virtual 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 && layoutInfo.View == eView.Tree || layoutInfo.View == eView.Tile && layoutInfo.IsViewGroupping && layoutInfo.ContextNode.HasChildNodes) + return this.LayoutCellsHorizontal(layoutInfo, x, y); + else + return this.LayoutCellsVertical(layoutInfo, x, y); + } + + protected virtual Size LayoutCellsHorizontal(NodeLayoutContextInfo layoutInfo, int x, int y) + { + Node node=layoutInfo.ContextNode; + int height=0, width=0; + bool adjustHeight = false; + int cellCount = node.Cells.Count; + bool firstVisible = true; + int runningColumnWidth = 0; + + for(int i=0;i 0 || layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count > 0) && + (node.Cells.Count > 1 || node.Cells.Count == layoutInfo.DefaultColumns.ColumnInfo.Count || + layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count == node.Cells.Count)) + { + bool usingTopLevelColumns = false; + if (layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count > 0 && i < layoutInfo.ChildColumns.ColumnInfo.Count) + ci = layoutInfo.ChildColumns.ColumnInfo[i] as ColumnInfo; + else if (i < layoutInfo.DefaultColumns.ColumnInfo.Count) + { + ci = layoutInfo.DefaultColumns.ColumnInfo[i] as ColumnInfo; + usingTopLevelColumns = true; + } + + if (ci != null) + { + bCellVisible = ci.Visible; + if (ci.AutoSize && cell.HostedControl == null) + cellLayout.CellWidth = 0; + else + { + cellLayout.CellWidth = ci.Width; + /*if (firstVisible && usingTopLevelColumns && cellLayout.CellWidth > 0) + { + cellLayout.CellWidth = Math.Max(-1, cellLayout.CellWidth - (layoutInfo.Left + x + this.LayoutSettings.CellHorizontalSpacing)); + if (cellLayout.CellWidth == 0) cellLayout.CellWidth = -1; // this ensures that cell content is not visible since 0 indicates to take as much space as needed + } + else*/ if(usingTopLevelColumns && cellLayout.CellWidth>0 && runningColumnWidth0) + { + x += this.LayoutSettings.CellHorizontalSpacing; + width += this.LayoutSettings.CellHorizontalSpacing; + } + if (cell.BoundsRelative.Height > height) + { + if (height != 0) adjustHeight = true; + height = cell.BoundsRelative.Height; + } + else if (!firstVisible && cell.BoundsRelative.Height < height && !cell.TextContentBounds.IsEmpty) + adjustHeight = true; + + firstVisible = false; + } + } + + // Apply the uniform cell text height to all cells + if (adjustHeight) + { + for (int i = 0; i < node.Cells.Count; i++) + { + Cell cell = node.Cells[i]; + if (cell.BoundsRelative.Height != height && !cell.TextContentBounds.IsEmpty) + { + cell.TextContentBounds = new Rectangle(cell.TextContentBounds.X, cell.TextContentBounds.Y, + cell.TextContentBounds.Width, cell.TextContentBounds.Height + (height - cell.BoundsRelative.Height)); + int diff = height - cell.BoundsRelative.Height; + if (!cell.CheckBoxBoundsRelative.IsEmpty) + { + eVerticalAlign va = GetCheckBoxVerticalAlign(cell.CheckBoxAlignment, layoutInfo.View); + if (va == eVerticalAlign.Middle) + cell.SetCheckBoxBounds(new Rectangle(cell.CheckBoxBoundsRelative.X, cell.CheckBoxBoundsRelative.Y + (int)Math.Ceiling((double)diff / 2), cell.CheckBoxBoundsRelative.Width, cell.CheckBoxBoundsRelative.Height)); + if (va == eVerticalAlign.Bottom) + cell.SetCheckBoxBounds(new Rectangle(cell.CheckBoxBoundsRelative.X, cell.CheckBoxBoundsRelative.Y + diff, cell.CheckBoxBoundsRelative.Width, cell.CheckBoxBoundsRelative.Height)); + } + if (!cell.ImageBoundsRelative.IsEmpty) + { + eVerticalAlign va = GetVerticalAlign(cell.ImageAlignment, layoutInfo.View); + if(va== eVerticalAlign.Middle) + cell.SetImageBounds(new Rectangle(cell.ImageBoundsRelative.X, cell.ImageBoundsRelative.Y + (int)Math.Ceiling((double)diff / 2), cell.ImageBoundsRelative.Width, cell.ImageBoundsRelative.Height)); + else if (va == eVerticalAlign.Bottom) + cell.SetImageBounds(new Rectangle(cell.ImageBoundsRelative.X, cell.ImageBoundsRelative.Y + diff, cell.ImageBoundsRelative.Width, cell.ImageBoundsRelative.Height)); + } + cell.SetBounds(new Rectangle(cell.BoundsRelative.X, cell.BoundsRelative.Y, cell.BoundsRelative.Width, height)); + } + } + } + + // Take last added spacing off + x -= this.LayoutSettings.CellHorizontalSpacing; + width -= this.LayoutSettings.CellHorizontalSpacing; + + return new Size(width,height); + } + + protected virtual Size LayoutCellsVertical(NodeLayoutContextInfo layoutInfo, int x, int y) + { + Node node=layoutInfo.ContextNode; + int height=0, width=0; + eHorizontalAlign align = node.VerticalCellLayoutAlignment; // eHorizontalAlign.Center; + int iVisibleCells=0; + int cellCount = node.Cells.Count; + for(int i=0;i 0 || layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count > 0) + { + ColumnInfo ci=null; + if (layoutInfo.ChildColumns != null && layoutInfo.ChildColumns.ColumnInfo.Count > 0) + ci=layoutInfo.ChildColumns.ColumnInfo[i] as ColumnInfo; + else + ci=layoutInfo.DefaultColumns.ColumnInfo[i] as ColumnInfo; + + bCellVisible=ci.Visible; + cellLayout.CellWidth=ci.Width; + } + else if (layoutInfo.View == eView.Tile) + { + cellLayout.CellWidth = layoutInfo.TileSize.Width; + cellLayout.CellHeight = layoutInfo.TileSize.Height; + } + + // 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; + protected virtual LayoutCellInfo GetLayoutCellInfo() + { + if(m_LayoutCellInfo==null) + m_LayoutCellInfo=new LayoutCellInfo(); + return m_LayoutCellInfo; + } + + protected virtual bool HasImage(Cell cell) + { + if (cell.Images.Image != null || cell.Images.ImageIndex >= 0 || !string.IsNullOrEmpty(cell.Images.ImageKey)) + return true; + return false; + } + } + } + + internal class LayoutCellInfo + { + public Cell ContextCell=null; + public int CellWidth=0; + public int CellHeight = 0; + public System.Drawing.Graphics Graphics=null; + public int Left=0; + public int Top=0; + public ElementStyle LayoutStyle=null; + public bool LeftToRight=true; + public bool VerticalPartAlignment=false; + public eView View = eView.Tree; + public int CellIndex = 0; + + private Font _Font; + public Font Font + { + get { return _Font; } + set + { + if (_Font != value) + { + _Font = value; + if (_Font != null) + FontHeight = _Font.Height; + else + FontHeight = 0; + } + } + } + public int FontHeight = 0; + + public LayoutCellInfo() + { + } + } + + internal class ColumnInfo + { + public bool Visible; + public int Width; + public int MaxWidth = 0; + public ColumnHeader ColumnHeader = null; + public bool AutoSize = false; + // Specifies the absolute index for column data. AbsoluteIndex may be different from DisplayIndex of columns are re-arranged + public int AbsoluteIndex = -1; + public ColumnInfo(int width, bool visible, ColumnHeader h, int absoluteIndex) + { + this.Width=width; + this.Visible=visible; + this.ColumnHeader = h; + this.AutoSize = h.Width.AutoSize; + this.AbsoluteIndex = absoluteIndex; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeLayout.cs b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeLayout.cs new file mode 100644 index 00000000..76425a45 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeLayout.cs @@ -0,0 +1,702 @@ +using System; +using System.Drawing; +using System.Collections; +using DevComponents.DotNetBar; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Collections.Generic; + +namespace DevComponents.AdvTree.Layout +{ + /// + /// Summary description for NodeLayout. + /// + internal abstract class NodeLayout + { + #region Private Variables + protected int m_Height=0; + protected int m_Width=0; + protected AdvTree m_Tree=null; + protected Rectangle m_ClientArea; + //protected int m_ExpandAreaWidth=8; + protected Size m_ExpandPartSize=new Size(8,8); + private Size _CachedExpandPartSize = Size.Empty; + private int m_CommandAreaWidth=10; + private int m_TreeLayoutChildNodeIndent = 16; + + private System.Windows.Forms.LeftRightAlignment m_LeftRight=System.Windows.Forms.LeftRightAlignment.Left; + private int m_NodeVerticalSpacing=3; + private int m_NodeHorizontalSpacing=0; + private CellLayout m_CellLayout=null; + private Graphics m_Graphics=null; + #endregion + + public NodeLayout(AdvTree treeControl, Rectangle clientArea, LayoutSettings layoutSettings) + { + m_Tree=treeControl; + m_ClientArea=clientArea; + _LayoutSettings = layoutSettings; + } + + /// + /// Performs layout of the nodes inside of the tree control. + /// + public virtual void PerformLayout() + { + } + + public virtual void UpdateTopLevelColumnsWidth() + { + } + + private LayoutSettings _LayoutSettings; + /// + /// Gets or sets layout settings. + /// + public LayoutSettings LayoutSettings + { + get { return _LayoutSettings; } + set { _LayoutSettings = value; } + } + + /// + /// Performs layout for single unassigned node. Node does not have to be part of the tree control. + /// + /// Node to perform layout on. + public virtual void PerformSingleNodeLayout(Node node) + { + if(node==null) + return; + + this.PrepareStyles(); + // Get default Columns + + System.Drawing.Graphics g=this.GetGraphics(); + + SmoothingMode sm = g.SmoothingMode; + TextRenderingHint th = g.TextRenderingHint; + if (m_Tree.AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + //g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + try + { + NodeLayoutContextInfo layoutInfo=this.GetDefaultNodeLayoutContextInfo(g); + layoutInfo.ContextNode=node; + if (node.IsDragNode) + layoutInfo.DefaultColumns = new NodeColumnInfo(new List(), false); + LayoutNode(layoutInfo); + } + finally + { + if (m_Tree.AntiAlias) + { + g.SmoothingMode = sm; + //g.TextRenderingHint = th; + } + g.Dispose(); + } + } + + public int Width + { + get {return m_Width;} + } + + public int Height + { + get {return m_Height;} + } + + public Rectangle ClientArea + { + get {return m_ClientArea;} + set {m_ClientArea=value;} + } + + public Graphics Graphics + { + get { return m_Graphics;} + set { m_Graphics = value;} + } + + internal bool DisposeGraphics + { + get + { + return (m_Graphics == null); + } + } + + protected virtual System.Drawing.Graphics GetGraphics() + { + if(m_Graphics!=null) + return m_Graphics; + + Graphics g=m_Tree.CreateGraphics(); + + + return g; + } + + /// + /// Resizes all styles and prepares them for layout. + /// + protected virtual void PrepareStyles() + { + // Resize styles if needed + foreach(ElementStyle es in m_Tree.Styles) + { + if(es.SizeChanged) + ElementStyleLayout.CalculateStyleSize(es,m_Tree.Font); + } + + if (_LayoutSettings != null) + _CachedExpandPartSize = Dpi.Size(_LayoutSettings.ExpandPartSize); + else + _CachedExpandPartSize = Dpi.Size(m_ExpandPartSize); + + } + + /// + /// Returns default top-level columns for tree control. + /// + /// Returns array list of ColumnInfo objects. + protected virtual NodeColumnInfo GetDefaultColumnInfo() + { + List ci = new List(); + NodeColumnInfo info = new NodeColumnInfo(ci, false); + ColumnHeaderCollection columns=m_Tree.Columns; + //int treeWidth = m_Tree.ClientRectangle.Width; + if(columns!=null) + { + for (int i = 0; i < columns.Count; i++) + { + int columnIndex = columns.DisplayIndexMap[i]; + ColumnHeader h = columns[columnIndex]; + ColumnInfo columnInfo = new ColumnInfo(h.Bounds.Width, h.Visible, h, columnIndex); + ci.Add(columnInfo); + info.HasAutoSizeColumn |= columnInfo.AutoSize; + } + } + + return info; + } + + /// + /// Returns column information for a given node. + /// + /// Node to return column information for + /// Returns array list of ColumnInfo objects or null if there are no columns defined. + protected virtual NodeColumnInfo GetNodeColumnInfo(Node node) + { + if (!node.HasColumns) + { + return null; + } + + List ci = new List(); + NodeColumnInfo info = new NodeColumnInfo(ci, false); + ColumnHeaderCollection columns = node.NodesColumns; + for (int i = 0; i < columns.Count; i++) + { + int columnIndex = columns.DisplayIndexMap[i]; + ColumnHeader h = columns[columnIndex]; + ColumnInfo columnInfo = new ColumnInfo(h.Bounds.Width, h.Visible, h, columnIndex); + ci.Add(columnInfo); + info.HasAutoSizeColumn |= columnInfo.AutoSize; + } + + return info; + } + + ///// + ///// Gets or sets the vertical spacing between nodes in pixels. + ///// + //public virtual int NodeVerticalSpacing + //{ + // get {return m_NodeVerticalSpacing;} + // set {m_NodeVerticalSpacing=value;} + //} + + ///// + ///// Gets or sets the horizontal spacing between nodes in pixels. + ///// + //public virtual int NodeHorizontalSpacing + //{ + // get {return m_NodeHorizontalSpacing;} + // set {m_NodeHorizontalSpacing=value;} + //} + + /// + /// Gets or sets the child node indent in pixels. + /// + public virtual int TreeLayoutChildNodeIndent + { + get {return m_TreeLayoutChildNodeIndent; } + set { m_TreeLayoutChildNodeIndent = value; } + } + + /// + /// Returns column header collection for the given column template name. + /// + /// Name of the column template. + /// Column header collection or null if template name cannot be found. + public virtual ColumnHeaderCollection GetColumnHeader(string name) + { + if(name=="" || name==null) + return null; + return m_Tree.Headers.GetByName(name).Columns; + } + + //private int _ExpandAreaWidth = 24; + ///// + ///// Returns width of the expand button area. Default is 24 pixels. + ///// + //public virtual int ExpandAreaWidth + //{ + // get { return _ExpandAreaWidth; } + // set + // { + // _ExpandAreaWidth = value; + // } + //} + + ///// + ///// Gets or sets width of command button area. Default is 8 pixels. + ///// + //public virtual int CommandAreaWidth + //{ + // get {return m_CommandAreaWidth;} + // set {m_CommandAreaWidth=value;} + //} + + /// + /// Sets the position and size of the node command button. + /// + /// Node layout context information + protected virtual void LayoutCommandPart(NodeLayoutContextInfo layoutInfo, ElementStyle nodeStyle) + { + // Command part is right-aligned just before the node border + Rectangle bounds = new Rectangle(layoutInfo.ContextNode.ContentBounds.Right - this.LayoutSettings.CommandAreaWidth - + ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Right),layoutInfo.ContextNode.ContentBounds.Y+ + ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Top), + this.LayoutSettings.CommandAreaWidth, layoutInfo.ContextNode.ContentBounds.Height - + ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Top)- + ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Bottom)); +// Rectangle bounds=new Rectangle(layoutInfo.ContextNode.ContentBounds.Right-this.CommandAreaWidth- +// ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Right),layoutInfo.ContextNode.ContentBounds.Y, +// this.CommandAreaWidth, layoutInfo.ContextNode.ContentBounds.Height); + layoutInfo.ContextNode.CommandBoundsRelative=bounds; + } + + /// + /// Determines the rectangle of the +/- part of the tree node that is used to expand node. + /// + /// Node layout context information + protected virtual void LayoutExpandPart(NodeLayoutContextInfo layoutInfo, bool bLeftNode, int x) + { + Node node=layoutInfo.ContextNode; + + Size partSize=GetExpandPartSize(); + + Rectangle bounds=new Rectangle(x,0,partSize.Width,partSize.Height); + + if (node.ExpandPartVerticalAlignment == eVerticalAlign.Middle) + bounds.Y = (node.BoundsRelative.Height - bounds.Height) / 2; + else if (node.ExpandPartVerticalAlignment == eVerticalAlign.Top) + bounds.Y = Dpi.Height3; + else + bounds.Y = node.BoundsRelative.Height - partSize.Height - Dpi.Height3; + + if (bLeftNode || layoutInfo.ExpandPartAlignedLeft && layoutInfo.LeftToRight) + bounds.X += (layoutInfo.ExpandAreaWidth - bounds.Width) / 2; + else + bounds.X = node.BoundsRelative.Right - layoutInfo.ExpandAreaWidth + (layoutInfo.ExpandAreaWidth - partSize.Width) / 2; + + node.SetExpandPartRectangle(bounds); + } + + /// + /// Returns the size of the node expand part. + /// + /// Size of the expand part, default 8,8. + protected virtual Size GetExpandPartSize() + { + return _CachedExpandPartSize; + //if (_LayoutSettings != null) + // return _LayoutSettings.ExpandPartSize; + //return m_ExpandPartSize; + } + + ///// + ///// Gets or sets the size of the expand part that is expanding/collapsing the node. Default value is 8,8. + ///// + //public System.Drawing.Size ExpandPartSize + //{ + // get {return m_ExpandPartSize;} + // set {m_ExpandPartSize=value;} + //} + + /// + /// Provides the layout for single node. + /// + /// Layout information. + protected virtual void LayoutNode(NodeLayoutContextInfo layoutInfo) + { + bool bHasExpandPart=this.HasExpandPart(layoutInfo); + bool bHasCommandPart=this.HasCommandPart(layoutInfo); + + Node node=layoutInfo.ContextNode; + + Rectangle nodeRect = new Rectangle(layoutInfo.Left, layoutInfo.Top, 0, 0); + Rectangle nodeContentRect=Rectangle.Empty; // Node content rect excludes expand rect + + int height=0, width=0; + + // Left node relative to the main root node... + bool bLeftNode = layoutInfo.LeftToRight; // (layoutInfo.MapPositionNear && layoutInfo.LeftToRight); + layoutInfo.LayoutNodeExpandPartWidth = 0; + if(bLeftNode && bHasExpandPart || this.ReserveExpandPartSpace) + { + layoutInfo.LayoutNodeExpandPartWidth = (layoutInfo.ExpandAreaWidth + this.GetCellLayout().CellPartSpacing); + width += (layoutInfo.ExpandAreaWidth + this.GetCellLayout().CellPartSpacing); + } + + int x=width; // relative to 0,0 of the node + int y=0; // Relative to 0,0 of the node + + // Apply node style + ElementStyle nodeStyle=null; + if(node.Expanded && node.StyleExpanded!=null) + nodeStyle=node.StyleExpanded; + else if(node.Style!=null) + nodeStyle=node.Style; + else + nodeStyle=layoutInfo.DefaultNodeStyle; + + nodeContentRect.X=x; + + if(nodeStyle!=null) + { + x+=ElementStyleLayout.LeftWhiteSpace(nodeStyle); + y+=ElementStyleLayout.TopWhiteSpace(nodeStyle); + nodeContentRect.X+=nodeStyle.MarginLeft; + nodeContentRect.Y+=nodeStyle.MarginTop; + } + + Size size = this.GetCellLayout().LayoutCells(layoutInfo, x, y); + + node.SetCellsBounds(new Rectangle(x, y, size.Width, size.Height)); + + height=size.Height; + width+=size.Width; + + nodeContentRect.Width=size.Width; + nodeContentRect.Height=size.Height; + + if(nodeStyle!=null) + { + nodeContentRect.Width+=(ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Left)+ + ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Right)); + nodeContentRect.Height+=(ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Top)+ + ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Bottom)); + + width+=(ElementStyleLayout.HorizontalStyleWhiteSpace(nodeStyle)); + height+=(ElementStyleLayout.VerticalStyleWhiteSpace(nodeStyle)); + } + + if (!bLeftNode && bHasExpandPart && !this.ReserveExpandPartSpace) + width += layoutInfo.ExpandAreaWidth; + + if(bHasCommandPart) + { + width += this.LayoutSettings.CommandAreaWidth; + nodeContentRect.Width += this.LayoutSettings.CommandAreaWidth; + } + + nodeRect.Height=height; + nodeRect.Width=width; + node.SetBounds(nodeRect); + node.SetContentBounds(nodeContentRect); + + if(bHasCommandPart) + LayoutCommandPart(layoutInfo, nodeStyle); + else + node.CommandBoundsRelative=Rectangle.Empty; + + if (bHasExpandPart || this.ReserveExpandPartSpace) + LayoutExpandPart(layoutInfo,bLeftNode, 0); + else + node.SetExpandPartRectangle(Rectangle.Empty); + + node.SizeChanged=false; + + // Calculate size and location of node column header if any + //if(node.NodesColumnHeaderVisible) + { + //layoutInfo.Left+=this.NodeLevelOffset; + LayoutColumnHeader(layoutInfo); + //layoutInfo.Left-=this.NodeLevelOffset; + } + } + + /// + /// Returns true if given node has expand part. + /// + /// Layout context information. + /// + 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); + } + + /// + /// Returns whether given node has command part. + /// + /// Layout context information. + /// True if command part should be drawn otherwise false. + protected virtual bool HasCommandPart(NodeLayoutContextInfo layoutInfo) + { + return layoutInfo.ContextNode.CommandButton; + } + + /// + /// Returns true if root node should have expanded part + /// + protected virtual bool RootHasExpandedPart + { + get {return true;} + } + + /// + /// 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. + /// + protected virtual bool ReserveExpandPartSpace + { + get + { + return false; + } + } + + /// + /// Returns class responsible for cell layout. + /// + /// Cell layout class. + protected internal virtual CellLayout GetCellLayout() + { + if (m_CellLayout == null) + m_CellLayout = new CellLayout(this.LayoutSettings); + return m_CellLayout; + } + + /// + /// Offsets node location and location of it's child nodes bounds. + /// + /// Node to offset. + /// Horizontal offset. + /// Vertical offset. + protected virtual void OffsetNodeLocation(Node node, int x, int y) + { + node.SetBounds(new Rectangle(node.BoundsRelative.X+x,node.BoundsRelative.Y+y,node.BoundsRelative.Width,node.BoundsRelative.Height)); + if(node.Expanded) + node.ChildNodesBounds=new Rectangle(node.ChildNodesBounds.X+x,node.ChildNodesBounds.Y+y,node.ChildNodesBounds.Width,node.ChildNodesBounds.Height); + } + + protected virtual NodeLayoutContextInfo GetDefaultNodeLayoutContextInfo(System.Drawing.Graphics graphics) + { + NodeLayoutContextInfo layoutInfo=new NodeLayoutContextInfo(); + layoutInfo.ClientRectangle=m_ClientArea; + layoutInfo.DefaultColumns=this.GetDefaultColumnInfo(); + layoutInfo.ChildColumns=null; + layoutInfo.Indent = m_Tree.Indent; + layoutInfo.Left=0; + layoutInfo.Top=0; + layoutInfo.LeftMargin = m_Tree.BackgroundStyle.PaddingLeft; + layoutInfo.DefaultFont=m_Tree.Font; + layoutInfo.LeftToRight=(this.LeftRight==System.Windows.Forms.LeftRightAlignment.Left); + layoutInfo.Graphics=graphics; + layoutInfo.Styles=m_Tree.Styles; + layoutInfo.FullRowBackgroundNodes = new ArrayList(); + if(m_Tree.CellLayout!=eCellLayout.Default) + layoutInfo.CellLayout=m_Tree.CellLayout; + if(m_Tree.CellPartLayout!=eCellPartLayout.Default) + layoutInfo.CellPartLayout=m_Tree.CellPartLayout; + + if(m_Tree.NodeStyle!=null) + layoutInfo.DefaultNodeStyle=m_Tree.NodeStyle; + + if(m_Tree.CellStyleDefault!=null) + layoutInfo.DefaultCellStyle=m_Tree.CellStyleDefault; + else + layoutInfo.DefaultCellStyle=ElementStyle.GetDefaultCellStyle(layoutInfo.DefaultNodeStyle); + + // Determine size of the default Column Header + if(m_Tree.ColumnStyleNormal!=null) + { + ElementStyleLayout.CalculateStyleSize(m_Tree.ColumnStyleNormal,layoutInfo.DefaultFont); + layoutInfo.DefaultHeaderSize=m_Tree.ColumnStyleNormal.Size; + } + + if(layoutInfo.DefaultHeaderSize.IsEmpty) + layoutInfo.DefaultHeaderSize.Height=layoutInfo.DefaultFont.Height+4; + + layoutInfo.ExpandPartWidth = Dpi.Width(this.Tree.ExpandWidth); + layoutInfo.View = this.Tree.View; + layoutInfo.TileSize = Dpi.Size(this.Tree.TileSize); + layoutInfo.ColumnStyle = this.Tree.ColumnStyleNormal; + layoutInfo.ExpandAreaWidth = Dpi.Width(this.LayoutSettings.ExpandAreaWidth); + return layoutInfo; + } + + protected Node[] GetTopLevelNodes() + { + if(m_Tree.DisplayRootNode!=null) + return new Node[] {m_Tree.DisplayRootNode}; + else + { + Node[] nodes=new Node[m_Tree.Nodes.Count]; + m_Tree.Nodes.CopyTo(nodes); + return nodes; + } + } + + protected bool IsRootNode(Node node) + { + return NodeOperations.IsRootNode(m_Tree,node); + } + + protected virtual void EmptyBoundsUnusedNodes(Node[] topLevelNodes) + { + if(m_Tree.DisplayRootNode!=null) + { + Node node=m_Tree.DisplayRootNode.PrevVisibleNode; + while(node!=null) + { + node.SetBounds(Rectangle.Empty); + node=node.PrevVisibleNode; + } + node=m_Tree.DisplayRootNode.NextNode; + if(node==null) + { + node=m_Tree.DisplayRootNode.Parent; + while(node!=null) + { + if(node.NextNode!=null) + { + node=node.NextNode; + break; + } + else + node=node.Parent; + } + } + while(node!=null) + { + node.SetBounds(Rectangle.Empty); + node=node.NextVisibleNode; + } + } + else + { + for(int i=1;i + /// Initializes a new instance of the NodeColumnInfo structure. + /// + /// + /// + public NodeColumnInfo(List columnInfo, bool hasAutoSizeColumn) + { + ColumnInfo = columnInfo; + HasAutoSizeColumn = hasAutoSizeColumn; + } + /// + /// Gets or sets the list of column info object for the columns. + /// + public List ColumnInfo; + /// + /// Gets or sets whether columns have auto-size column. + /// + public bool HasAutoSizeColumn; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeLayoutContextInfo.cs b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeLayoutContextInfo.cs new file mode 100644 index 00000000..3e970e5e --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeLayoutContextInfo.cs @@ -0,0 +1,62 @@ +using System; +using System.Drawing; +using System.Collections; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Layout +{ + /// + /// Used to pass node contextual information used for layout of the node. + /// + internal class NodeLayoutContextInfo + { + public Node ContextNode=null; + public Rectangle ClientRectangle=Rectangle.Empty; + public int Left; + public int Top; + public int LeftMargin = 0; + public NodeColumnInfo DefaultColumns=null; + public NodeColumnInfo ChildColumns = 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.Default; + public eCellPartLayout CellPartLayout=eCellPartLayout.Horizontal; + public bool MapPositionNear=false; + public bool ExpandPartAlignedLeft = false; + public ColumnHeaderCollection TreeColumns = null; + public ArrayList FullRowBackgroundNodes = null; + public int ExpandPartWidth = 0; + public int CurrentLineHeight = 0; // Used by tile layout + public int CurrentLevelLeft = 0; // Used by tile layout + public eView View = eView.Tree; // Current control view + public Size TileSize = Size.Empty; // Tile size + public bool IsViewGroupping = false; // Tile view grouping enabled + public ElementStyle ColumnStyle = null; + public int LayoutNodeExpandPartWidth = 0; + public int Indent = 0; + public int ExpandAreaWidth = 0; // Cached LayoutSettings.ExpandAreaWidth with DPI multipler applied. + + private Font _DefaultFont = null; + public Font DefaultFont + { + get { return _DefaultFont; } + set + { + if (_DefaultFont != value) + { + _DefaultFont = value; + if (_DefaultFont != null) + DefaultFontHeight = _DefaultFont.Height; + else + DefaultFontHeight = 0; + } + } + } + public int DefaultFontHeight = 0; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeTileLayout.cs b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeTileLayout.cs new file mode 100644 index 00000000..9a02205a --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeTileLayout.cs @@ -0,0 +1,393 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; + +namespace DevComponents.AdvTree.Layout +{ + /// + /// Performs ListView Tile style layout. + /// + internal class NodeTileLayout : NodeLayout + { + public NodeTileLayout(AdvTree treeControl, Rectangle clientArea, LayoutSettings layoutSettings) + : base(treeControl, clientArea, layoutSettings) + { + } + + public override void UpdateTopLevelColumnsWidth() + { + // Columns are not visible in tile layout + this.Tree.Columns.SetBounds(Rectangle.Empty); + } + + /// + /// Returns default top-level columns for tree control. + /// + /// Returns array list of ColumnInfo objects. + protected override NodeColumnInfo GetDefaultColumnInfo() + { + // There are no columns in Tile view + List ci = new List(); + NodeColumnInfo info = new NodeColumnInfo(ci, false); + return info; + } + + protected override NodeLayoutContextInfo GetDefaultNodeLayoutContextInfo(System.Drawing.Graphics graphics) + { + NodeLayoutContextInfo context = base.GetDefaultNodeLayoutContextInfo(graphics); + context.IsViewGroupping = this.Groupping; + return context; + } + + public override void PerformLayout() + { + this.PrepareStyles(); + Rectangle area = Rectangle.Empty; + Graphics g=this.GetGraphics(); + SmoothingMode sm = g.SmoothingMode; + TextRenderingHint th = g.TextRenderingHint; + if (m_Tree.AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + } + + NodeLayoutContextInfo layoutInfo = GetDefaultNodeLayoutContextInfo(g); + layoutInfo.ExpandPartAlignedLeft = true; + layoutInfo.Left = ClientArea.X; + layoutInfo.Top = ClientArea.Y; + + CellLayout cellLayout = this.GetCellLayout(); + cellLayout.ResetCheckBoxSize(); + if (this.Tree.CheckBoxImageChecked != null) + cellLayout.CheckBoxSize = this.Tree.CheckBoxImageChecked.Size; + + LayoutTopLevelColumns(layoutInfo); + + // Get default Columns + NodeColumnInfo defaultColInfoList = this.GetDefaultColumnInfo(); + layoutInfo.DefaultColumns = defaultColInfoList; + try + { + // Loop through each top-level node + Node[] topLevelNodes=this.GetTopLevelNodes(); + int defaultTop = layoutInfo.Top; + area = ProcessTopLevelNodes(area, layoutInfo, topLevelNodes); + + //if (defaultColInfoList.HasAutoSizeColumn) + //{ + // foreach (ColumnInfo columnInfo in defaultColInfoList.ColumnInfo) + // { + // if (columnInfo.AutoSize) + // { + // columnInfo.AutoSize = false; + // columnInfo.Width = columnInfo.MaxWidth; + // columnInfo.ColumnHeader.Width.SetAutoSizeWidth(columnInfo.MaxWidth); + // columnInfo.MaxWidth = 0; + // } + // } + // layoutInfo.ContextNode = null; + // LayoutTopLevelColumns(layoutInfo); + // layoutInfo.Top = defaultTop; + // area = ProcessTopLevelNodes(Rectangle.Empty, layoutInfo, topLevelNodes); + //} + } + finally + { + if (m_Tree.AntiAlias) + { + g.SmoothingMode = sm; + //g.TextRenderingHint = th; + } + + if(this.DisposeGraphics) + g.Dispose(); + } + if (layoutInfo.FullRowBackgroundNodes.Count > 0) + Tree.FullRowBackgroundNodes = layoutInfo.FullRowBackgroundNodes; + else + Tree.FullRowBackgroundNodes = null; + + m_Width = area.Width; + m_Height = area.Height; + } + + private void LayoutTopLevelColumns(NodeLayoutContextInfo layoutInfo) + { + // There are no columns in Tile view + this.Tree.SetColumnHeaderControlVisibility(false); + } + + private Rectangle ProcessTopLevelNodes(Rectangle area, NodeLayoutContextInfo layoutInfo, Node[] topLevelNodes) + { + layoutInfo.CurrentLevelLeft = layoutInfo.Left; + bool isPreviousGroupNode = false; + foreach (Node childNode in topLevelNodes) + { + layoutInfo.ContextNode = childNode; + if (childNode.Visible) + { + if (_Groupping && childNode.HasChildNodes) + { + if (layoutInfo.CurrentLineHeight > 0) + layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing; + layoutInfo.CurrentLineHeight = 0; + layoutInfo.Left = layoutInfo.CurrentLevelLeft; + isPreviousGroupNode = true; + } + else + { + if (isPreviousGroupNode) + { + if (layoutInfo.CurrentLineHeight > 0) + layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing; + layoutInfo.CurrentLineHeight = 0; + layoutInfo.Left = layoutInfo.CurrentLevelLeft; + } + isPreviousGroupNode = false; + } + } + + ProcessNode(layoutInfo); + + if (childNode.Visible) + { + area = Rectangle.Union(area, childNode.BoundsRelative); + if (childNode.Expanded && childNode.HasChildNodes) + area = Rectangle.Union(area, childNode.ChildNodesBounds); + if (!(_Groupping && childNode.HasChildNodes)) + layoutInfo.Left += childNode.BoundsRelative.Width + this.LayoutSettings.NodeHorizontalSpacing; + } + } + return area; + } + + private Rectangle ProcessChildNodes(NodeLayoutContextInfo layoutInfo, Node node, int nodeVerticalSpacing, NodeColumnInfo childColumns) + { + Rectangle childNodesBounds = new Rectangle(layoutInfo.Left, layoutInfo.Top, 0, 0); + bool isPreviousGroupNode = false; + + foreach (Node childNode in node.Nodes) + { + if (!childNode.Visible) continue; + + if (_Groupping && childNode.HasChildNodes) + { + if (layoutInfo.CurrentLineHeight > 0) + layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing; + layoutInfo.CurrentLineHeight = 0; + layoutInfo.Left = layoutInfo.CurrentLevelLeft; + isPreviousGroupNode = true; + } + else + { + if (isPreviousGroupNode) + { + if (layoutInfo.CurrentLineHeight > 0) + layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing; + layoutInfo.CurrentLineHeight = 0; + layoutInfo.Left = layoutInfo.CurrentLevelLeft; + isPreviousGroupNode = false; + } + } + + layoutInfo.ContextNode = childNode; + layoutInfo.ChildColumns = childColumns; + ProcessNode(layoutInfo); + + if (!(_Groupping && childNode.HasChildNodes)) + layoutInfo.Left += childNode.BoundsRelative.Width + this.LayoutSettings.NodeHorizontalSpacing; + if (isPreviousGroupNode) + { + childNodesBounds.Width = Math.Max(childNodesBounds.Width, + Math.Max(childNode.BoundsRelative.Width, (childNode.Expanded && childNode.ChildNodesBounds.Width > 0 ? childNode.ChildNodesBounds.Right - childNodesBounds.X : 0))); + childNodesBounds.Height += childNode.BoundsRelative.Height + (childNode.Expanded ? childNode.ChildNodesBounds.Height + childNode.ColumnHeaderHeight : 0) + nodeVerticalSpacing; + } + else + { + childNodesBounds = Rectangle.Union(childNodesBounds, childNode.BoundsRelative); + childNodesBounds.Height += nodeVerticalSpacing; + } + } + return childNodesBounds; + } + + + #region Node routines + private void ProcessNode(NodeLayoutContextInfo layoutInfo) + { + Node node=layoutInfo.ContextNode; + if (!node.Visible || node.Cells.Count == 0) return; + + if (node.SizeChanged || _Groupping && node.HasChildNodes) + { + // Calculate size of the node itself... + LayoutNode(layoutInfo); + } + if (node.FullRowBackground) + layoutInfo.FullRowBackgroundNodes.Add(node); + + // Position the node + if (_Groupping && node.HasChildNodes) + { + if (layoutInfo.CurrentLineHeight > 0) + layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing; + layoutInfo.CurrentLineHeight = 0; + } + else + { + if (layoutInfo.Left + node.BoundsRelative.Width > this.ClientArea.Right) + { + layoutInfo.Left = layoutInfo.CurrentLevelLeft; + layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing; + layoutInfo.CurrentLineHeight = 0; + } + } + layoutInfo.CurrentLineHeight = Math.Max(layoutInfo.CurrentLineHeight, node.BoundsRelative.Height); + + if (node.BoundsRelative.X != layoutInfo.Left || node.BoundsRelative.Y != layoutInfo.Top) + { + // Adjust top position + node.SetBounds(new Rectangle(layoutInfo.Left,layoutInfo.Top,node.BoundsRelative.Width,node.BoundsRelative.Height)); + } + + // Position the node + if (_Groupping && node.HasChildNodes) + { + if (layoutInfo.CurrentLineHeight > 0) + layoutInfo.Top += layoutInfo.CurrentLineHeight + this.LayoutSettings.NodeVerticalSpacing; + layoutInfo.CurrentLineHeight = 0; + } + + int nodeVerticalSpacing = this.LayoutSettings.NodeVerticalSpacing; + // Need to set the Top position properly + //layoutInfo.Top += (node.BoundsRelative.Height + nodeVerticalSpacing); + // No columns in tile view + //if (DevComponents.AdvTree.Display.NodeDisplay.HasColumnsVisible(node)) + // layoutInfo.Top += node.ColumnHeaderHeight; + + if(_Groupping && node.HasChildNodes && node.Expanded) + { + int originalLevelOffset=layoutInfo.Left; + int originalLevelLeft = layoutInfo.CurrentLevelLeft; + int childNodesTop = layoutInfo.Top; + layoutInfo.Left += this.NodeLevelOffset + node.NodesIndent; + layoutInfo.CurrentLevelLeft = layoutInfo.Left; + NodeColumnInfo parentColumns = layoutInfo.ChildColumns; + NodeColumnInfo childColumns = GetNodeColumnInfo(node); + Rectangle childNodesBounds = ProcessChildNodes(layoutInfo, node, nodeVerticalSpacing, childColumns); + + //if (childColumns != null && childColumns.HasAutoSizeColumn) + //{ + // foreach (ColumnInfo columnInfo in childColumns.ColumnInfo) + // { + // if (columnInfo.AutoSize) + // { + // columnInfo.Width = columnInfo.MaxWidth; + // columnInfo.ColumnHeader.Width.SetAutoSizeWidth(columnInfo.MaxWidth); + // columnInfo.AutoSize = false; + // columnInfo.MaxWidth = 0; + // } + // } + // layoutInfo.Top = originalTop; + // layoutInfo.Left = originalLevelOffset; + // layoutInfo.ContextNode = node; + // layoutInfo.ChildColumns = null; + // LayoutNode(layoutInfo); + // layoutInfo.Top = childNodesTop; + // layoutInfo.Left += this.NodeLevelOffset + node.NodesIndent; + // childNodesBounds = ProcessChildNodes(layoutInfo, node, nodeVerticalSpacing, childColumns); + //} + + node.ChildNodesBounds = childNodesBounds; + + layoutInfo.ChildColumns=parentColumns; + + layoutInfo.ContextNode=node; + layoutInfo.Left=originalLevelOffset; + layoutInfo.CurrentLevelLeft = originalLevelLeft; + } + else + node.ChildNodesBounds = Rectangle.Empty; + } + + /// + /// Gets whether the expand part of the node +/- is aligned to the left of the node in left-to-right layout. + /// + /// Node to get expand part alignment for + /// true if node expand part is aligned to the left in left-to-right layout. + private bool ExpandPartAlignedNear(Node node) + { + return true; // If changed LayoutExpandPart needs to be updated as well + } + + /// + /// Returns column information for a given node. + /// + /// Node to return column information for + /// Returns array list of ColumnInfo objects or null if there are no columns defined. + protected override NodeColumnInfo GetNodeColumnInfo(Node node) + { + // No columns in tile-view + return null; + } + + /// + /// 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. + /// + protected override bool ReserveExpandPartSpace + { + get + { + return false; + } + } + + /// + /// Returns true if given node has expand part. + /// + /// Layout context information. + /// + protected override bool HasExpandPart(NodeLayoutContextInfo layoutInfo) + { + Node node = layoutInfo.ContextNode; + if (node.ExpandVisibility == eNodeExpandVisibility.Auto) + { + if (!_Groupping || !NodeOperations.GetAnyVisibleNodes(node)) + return false; + return true; + } + else + return (node.ExpandVisibility == eNodeExpandVisibility.Visible); + } + + + private bool _Groupping = true; + /// + /// Gets or sets whether parent/child node relationship is displayed as groups. + /// + public bool Groupping + { + get { return _Groupping; } + set + { + _Groupping = value; + } + } + + private CellTileLayout _CellLayout = null; + /// + /// Returns class responsible for cell layout. + /// + /// Cell layout class. + protected internal override CellLayout GetCellLayout() + { + if (_CellLayout == null) + _CellLayout = new CellTileLayout(this.LayoutSettings); + return _CellLayout; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeTreeLayout.cs b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeTreeLayout.cs new file mode 100644 index 00000000..e800c105 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Layout/NodeTreeLayout.cs @@ -0,0 +1,328 @@ +using System.Collections; +using System.Drawing; +using System.Windows.Forms; +using System; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree.Layout +{ + /// + /// Performs classic TreeView layout. + /// + internal class NodeTreeLayout:NodeLayout + { + public NodeTreeLayout(AdvTree treeControl, Rectangle clientArea, LayoutSettings layoutSettings) + : base(treeControl, clientArea, layoutSettings) + { + } + + public override void UpdateTopLevelColumnsWidth() + { + if (this.Tree.Columns.Count > 0) + { + Rectangle columnsBounds = DevComponents.DotNetBar.ElementStyleLayout.GetInnerRect(this.Tree.BackgroundStyle, this.Tree.ClientRectangle); + if (this.Tree.VScrollBar != null) columnsBounds.Width -= this.Tree.VScrollBar.Width; + columnsBounds.Height = this.Tree.Columns.Bounds.Height; + if(this.Tree.Columns.Bounds.Width 0) + Tree.FullRowBackgroundNodes = layoutInfo.FullRowBackgroundNodes; + else + Tree.FullRowBackgroundNodes = null; + //if (columnsVisible && layoutInfo.DefaultColumns != null && layoutInfo.DefaultColumns.Count > 0) + //{ + // bool layoutColumns = false; + // for (int i = 0; i < layoutInfo.DefaultColumns.Count; i++) + // { + // ColumnInfo ci = (ColumnInfo)layoutInfo.DefaultColumns[i]; + // if (ci.Width == 0 && ci.MaxWidth > 0) + // { + // ci.ColumnHeader.ContentWidth = ci.MaxWidth; + // layoutColumns = true; + // } + // } + // if (layoutColumns) + // { + // layoutInfo.ContextNode = null; + // layoutInfo.TreeColumns = this.Tree.Columns; + // Layout.ColumnHeaderLayout.LayoutColumnHeader(layoutInfo, ClientArea.X, + // ClientArea.Y, ClientArea.Width, this.GetCellLayout().CellHorizontalSpacing); + // } + //} + + m_Width = area.Width; + m_Height = area.Height; + } + + private void LayoutTopLevelColumns(NodeLayoutContextInfo layoutInfo) + { + // Layout tree columns + if (this.Tree.Columns.Count > 0) + { + Rectangle columnsBounds = m_ClientArea;// DevComponents.DotNetBar.ElementStyleLayout.GetInnerRect(this.Tree.BackgroundStyle, this.Tree.ClientRectangle); + //if (this.Tree.VScrollBar != null) columnsBounds.Width -= this.Tree.VScrollBar.Width; + layoutInfo.TreeColumns = this.Tree.Columns; + int columnHeight = Layout.ColumnHeaderLayout.LayoutColumnHeader(layoutInfo, 0, + 0, columnsBounds.Width, this.GetCellLayout().LayoutSettings.CellHorizontalSpacing); + columnHeight += this.LayoutSettings.NodeVerticalSpacing; + if (this.Tree.ColumnsVisible) + { + Rectangle headerBounds = layoutInfo.TreeColumns.Bounds; + if (headerBounds.Width > 0 && headerBounds.Width < columnsBounds.Width) + { + headerBounds.Width = columnsBounds.Width; + layoutInfo.TreeColumns.SetBounds(headerBounds); + } + layoutInfo.Top += columnHeight; + this.Tree.SetColumnHeaderControlVisibility(true); + } + else + this.Tree.SetColumnHeaderControlVisibility(false); + layoutInfo.TreeColumns = null; + } + else + this.Tree.SetColumnHeaderControlVisibility(false); + } + + private Rectangle ProcessTopLevelNodes(Rectangle area, NodeLayoutContextInfo layoutInfo, Node[] topLevelNodes) + { + foreach (Node childNode in topLevelNodes) + { + layoutInfo.ContextNode = childNode; + ProcessNode(layoutInfo); + if (childNode.Visible) + { + area = Rectangle.Union(area, childNode.BoundsRelative); + if (childNode.Expanded) + area = Rectangle.Union(area, childNode.ChildNodesBounds); + } + } + return area; + } + + #region Node routines + private void ProcessNode(NodeLayoutContextInfo layoutInfo) + { + Node node=layoutInfo.ContextNode; + if (!node.Visible) return; + + int originalTop = layoutInfo.Top; + + if (node.SizeChanged || node.HasColumns || layoutInfo.DefaultColumns!=null && layoutInfo.DefaultColumns.HasAutoSizeColumn || layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.HasAutoSizeColumn) + { + // Calculate size of the node itself... + LayoutNode(layoutInfo); + } + if (node.FullRowBackground) + layoutInfo.FullRowBackgroundNodes.Add(node); + + if (node.BoundsRelative.X != layoutInfo.Left || node.BoundsRelative.Y != layoutInfo.Top) + { + // Adjust top position + node.SetBounds(new Rectangle(layoutInfo.Left,layoutInfo.Top,node.BoundsRelative.Width,node.BoundsRelative.Height)); + //foreach(Cell c in node.Cells) + // c.SetBounds(new Rectangle(c.BoundsRelative.X + layoutInfo.Left, c.BoundsRelative.Y+layoutInfo.Top, c.BoundsRelative.Width, c.BoundsRelative.Height)); + } + + int nodeVerticalSpacing = this.LayoutSettings.NodeVerticalSpacing; + // Need to set the Top position properly + layoutInfo.Top += (node.BoundsRelative.Height + nodeVerticalSpacing); + if (DevComponents.AdvTree.Display.NodeDisplay.HasColumnsVisible(node)) + layoutInfo.Top += node.ColumnHeaderHeight; + + if(node.Expanded) + { + int originalLevelOffset=layoutInfo.Left; + int childNodesTop = layoutInfo.Top; + layoutInfo.Left += this.NodeLevelOffset + node.NodesIndent; + NodeColumnInfo parentColumns = layoutInfo.ChildColumns; + NodeColumnInfo childColumns = GetNodeColumnInfo(node); + Rectangle childNodesBounds = ProcessChildNodes(layoutInfo, node, nodeVerticalSpacing, childColumns); + + if (childColumns != null && childColumns.HasAutoSizeColumn) + { + bool hasMinColumnAutoSizeWidth = false; + foreach (ColumnInfo columnInfo in childColumns.ColumnInfo) + { + if (columnInfo.AutoSize) + { + columnInfo.Width = columnInfo.MaxWidth; + columnInfo.ColumnHeader.Width.SetAutoSizeWidth(columnInfo.MaxWidth); + columnInfo.AutoSize = false; + columnInfo.MaxWidth = 0; + if (columnInfo.ColumnHeader.Width.AutoSizeMinHeader) + hasMinColumnAutoSizeWidth = true; + } + } + layoutInfo.Top = originalTop; + layoutInfo.Left = originalLevelOffset; + layoutInfo.ContextNode = node; + layoutInfo.ChildColumns = parentColumns; + LayoutNode(layoutInfo); + layoutInfo.Top = childNodesTop; + layoutInfo.Left += this.NodeLevelOffset + node.NodesIndent; + + // Adjust the of auto sized columns in case minimum header width is used + if (hasMinColumnAutoSizeWidth) + { + foreach (ColumnInfo columnInfo in childColumns.ColumnInfo) + { + if (columnInfo.ColumnHeader.Width.AutoSize && columnInfo.ColumnHeader.Width.AutoSizeMinHeader) + { + columnInfo.Width = columnInfo.ColumnHeader.Bounds.Width; + } + } + } + + childNodesBounds = ProcessChildNodes(layoutInfo, node, nodeVerticalSpacing, childColumns); + } + + node.ChildNodesBounds = childNodesBounds; + + layoutInfo.ChildColumns=parentColumns; + + layoutInfo.ContextNode=node; + layoutInfo.Left=originalLevelOffset; + } + } + + private Rectangle ProcessChildNodes(NodeLayoutContextInfo layoutInfo, Node node, int nodeVerticalSpacing, NodeColumnInfo childColumns) + { + Rectangle childNodesBounds = new Rectangle(layoutInfo.Left, layoutInfo.Top, 0, 0); + + foreach (Node childNode in node.Nodes) + { + if (!childNode.Visible) continue; + layoutInfo.ContextNode = childNode; + layoutInfo.ChildColumns = childColumns; + ProcessNode(layoutInfo); + childNodesBounds.Width = Math.Max(childNodesBounds.Width, + Math.Max(childNode.BoundsRelative.Width, (childNode.Expanded && childNode.ChildNodesBounds.Width > 0 ? childNode.ChildNodesBounds.Right - childNodesBounds.X : 0))); + childNodesBounds.Height += childNode.BoundsRelative.Height + (childNode.Expanded ? childNode.ChildNodesBounds.Height + childNode.ColumnHeaderHeight : 0) + nodeVerticalSpacing; + } + return childNodesBounds; + } + + /// + /// 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. + /// + protected override bool ReserveExpandPartSpace + { + get + { + return true; + } + } + + /// + /// Gets whether the expand part of the node +/- is aligned to the left of the node in left-to-right layout. + /// + /// Node to get expand part alignment for + /// true if node expand part is aligned to the left in left-to-right layout. + private bool ExpandPartAlignedNear(Node node) + { + return true; // If changed LayoutExpandPart needs to be updated as well + } + +// private NodeCollection GetTopLevelNodes() +// { +// return m_Tree.Nodes; +// } + + + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Node.cs b/PROMS/DotNetBar Source Code/AdvTree/Node.cs new file mode 100644 index 00000000..363daf9a --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Node.cs @@ -0,0 +1,3227 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.AdvTree.Display; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree +{ + /// + /// Represents the Node in Tree control. + /// + [DesignTimeVisible(false), ToolboxItem(false), Designer("DevComponents.AdvTree.Design.NodeDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class Node : Component, IComparable + { + #region Events + /// + /// Occurs when the mouse pointer is over the node and a mouse button is pressed. + /// + public event MouseEventHandler NodeMouseDown; + + /// + /// Occurs when the mouse pointer is over the node and a mouse button is released. + /// + public event MouseEventHandler NodeMouseUp; + + /// + /// Occurs when the mouse pointer is moved over the node. + /// + public event MouseEventHandler NodeMouseMove; + + /// + /// Occurs when the mouse enters the node. + /// + public event EventHandler NodeMouseEnter; + + /// + /// Occurs when the mouse leaves the node. + /// + public event EventHandler NodeMouseLeave; + + /// + /// Occurs when the mouse hovers over the node. + /// + public event EventHandler NodeMouseHover; + + /// + /// Occurs when the node is clicked with left mouse button. If you need to know more information like if another mouse button is clicked etc. use + /// NodeMouseDown event. + /// + public event EventHandler NodeClick; + + /// + /// Occurs when the node is double-clicked. + /// + public event EventHandler NodeDoubleClick; + + /// + /// Occurs when hyperlink in text-markup is clicked. + /// + public event MarkupLinkClickEventHandler MarkupLinkClick; + #endregion + + #region Private Variables + private Rectangle m_BoundsRelative = Rectangle.Empty; + private Rectangle m_ChildNodesBounds = Rectangle.Empty; + private Rectangle m_CellsBounds = Rectangle.Empty; + private Rectangle m_ContentBounds = Rectangle.Empty; + private Rectangle m_CommandBoundsRelative = Rectangle.Empty; + private NodeCollection m_Nodes = null; + //private LinkedNodesCollection m_LinkedNodes=null; + private CellCollection m_Cells = new CellCollection(); + //private string m_Header=""; + private ColumnHeaderCollection m_NodesColumns; + //private bool m_NodesColumnHeaderVisible=true; + private object m_Tag = null; + private object m_DataKey = null; + private string m_Text = ""; + private bool m_Expanded = false; + private eNodeExpandVisibility m_ExpandVisibility = eNodeExpandVisibility.Auto; + private Rectangle m_ExpandPartRectangle = Rectangle.Empty; + private Node m_Parent = null; + + private ElementStyle m_StyleExpanded = null; + private ElementStyle m_StyleSelected = null; + private ElementStyle m_StyleMouseOver = null; + private bool m_SizeChanged = true; + //private eNodeHeaderVisibility m_HeaderVisibility=eNodeHeaderVisibility.Automatic; + private int m_ColumnHeaderHeight = 0; + private eMapPosition m_MapSubRootPosition = eMapPosition.Default; + private int m_Offset = 0; + internal AdvTree internalTreeControl = null; + private ElementStyle m_Style = null; + private eMouseOverNodePart m_MouseOverNodePart = eMouseOverNodePart.None; + private NodeConnector m_ParentConnector = null; + private eCellLayout m_CellLayout = eCellLayout.Default; + private bool m_Visible = true; + private bool m_CommandButton = false; + private bool m_Editing = false; + private bool m_DragDropEnabled = true; + private string m_Name = ""; + private ConnectorPointsCollection m_ParentConnectorPoints = null; + private bool m_SelectedConnectorMarker = false; + private eNodeRenderMode m_RenderMode = eNodeRenderMode.Default; + private TreeRenderer m_NodeRenderer = null; + private object m_ContextMenu = null; + #endregion + + #region Constructor + /// Default Constructor. + public Node() + { + m_Cells.SetParentNode(this); + m_ParentConnectorPoints = new ConnectorPointsCollection(); + m_ParentConnectorPoints.SetParentNode(this); + + Cell defaultCell = new Cell(); + this.Cells.Add(defaultCell); + } + /// + /// Creates node and initializes its text. + /// + public Node(string text) + : this() + { + this.Text = text; + } + + /// + /// Creates node and initializes its text and Style property. + /// + public Node(string text, ElementStyle nodeStyle) + : this() + { + this.Text = text; + this.Style = nodeStyle; + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (m_Nodes != null) + { + Node[] nodes = new Node[m_Nodes.Count]; + m_Nodes.CopyTo(nodes); + foreach (Node node in nodes) + node.Dispose(); + //m_Nodes.Clear(); + } + foreach (Cell cell in this.Cells) + { + cell.Dispose(); + } + //this.Cells.Clear(); + + if (m_Style != null) + m_Style.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (m_StyleSelected != null) + m_StyleSelected.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (m_StyleExpanded != null) + m_StyleExpanded.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (m_StyleMouseOver != null) + m_StyleMouseOver.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (m_ParentConnector != null) + m_ParentConnector.AppearanceChanged -= new EventHandler(this.ConnectorAppearanceChanged); + + } + base.Dispose(disposing); + } + #endregion + + #region Properties + /// + /// Gets whether node has child nodes. + /// + [Browsable(false)] + public bool HasChildNodes + { + get { return m_Nodes != null && m_Nodes.Count > 0; } + } + + /// + /// Gets or sets the context menu assigned to this node. Standard Context Menus, VS.NET 2005 Context Menus and DotNetBar Suite context menus are supported. + /// Default value is null (Nothing) which indicates that no context menu is assigned. + /// + [Browsable(true), DefaultValue(null), Description("Indicates the context menu assigned to this node."), Editor("DevComponents.AdvTree.Design.NodeContextMenuTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public object ContextMenu + { + get { return m_ContextMenu; } + set { m_ContextMenu = value; } + } + + /// + /// Gets whether any of the cells inside the node has HostedControl property set. + /// + [Browsable(false)] + public bool HasHostedControls + { + get + { + foreach (Cell cell in m_Cells) + { + if (cell.HostedControl != null) + return true; + } + return false; + } + } + /// + /// Gets or sets custom node renderer. You can set this property to your custom renderer. When set the RenderMode should be set to custom to enable + /// your custom renderer. To choose one of the system renderer use RenderMode property. Default value is null. + /// + [Browsable(false), Category("Style"), DefaultValue(null), Description("Indicates render mode used to render the node.")] + internal TreeRenderer NodeRenderer + { + get { return m_NodeRenderer; } + set + { + m_NodeRenderer = value; + OnDisplayChanged(); + } + } + /// + /// Gets or sets the render mode used to render the node. Default value is eNodeRenderMode.Default which indicates that system default renderer is used. + /// Note that if you specify custom renderer you need to set either AdvTree.NodeRenderer or Node.NodeRenderer property. + /// + [Browsable(true), Category("Style"), DefaultValue(eNodeRenderMode.Default), Description("Indicates render mode used to render the node.")] + internal eNodeRenderMode RenderMode + { + get { return m_RenderMode; } + set + { + m_RenderMode = value; + OnDisplayChanged(); + } + } + /// + /// Gets or sets whether node is expanded. Expanded node shows it's child nodes. + /// + [Browsable(true), Category("Node State"), DefaultValue(false), Description("Indicates whether node is expanded."), DevCoSerialize()] + public bool Expanded + { + get { return m_Expanded; } + set + { + if (value) + this.Expand(); + else + this.Collapse(); + } + } + /// + /// Returns name of the node that can be used to identify it from the code. + /// + [Browsable(false), Category("Design"), Description("Indicates the name used to identify node."), DevCoSerialize()] + 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; + } + } + + /// + /// Gets or sets whether node can be dragged and dropped. Default value is true. + /// + [Browsable(true), Category("Behavior"), Description("Indicates whether node can be dragged and dropped."), DefaultValue(true), DevCoSerialize()] + public bool DragDropEnabled + { + get { return m_DragDropEnabled; } + set { m_DragDropEnabled = value; } + } + + /// + /// Gets or sets visibility of the expand button. Default value is Auto meaning that + /// expand button is displayed only if node has at least one child node. + /// + /// + /// You can use this property for example to dynamically load the child nodes when user + /// tries to expand the node. You could for example handle BeforeExpand event to load child + /// nodes into the node. + /// + [Category("Appearance"), Browsable(true), DefaultValue(eNodeExpandVisibility.Auto), Description("Indicates whether the expand button is always visible regardless of whether node contains child nodes or not."), DevCoSerialize()] + public eNodeExpandVisibility ExpandVisibility + { + get { return m_ExpandVisibility; } + set + { + m_ExpandVisibility = value; + this.SizeChanged = true; + } + } + + /// + /// Gets or sets whether any operation on the node has been performed that would affect node's size. Size changed flag + /// internally indicates that node's size needs to be recalculated because it has changed + /// due to the changes in data. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool SizeChanged + { + get { return m_SizeChanged; } + set + { + m_SizeChanged = value; + OnSizeChanged(); + } + } + + /// + /// Gets the relative bounds of the tree node including the expand part of the node. + /// + [Browsable(false)] + internal Rectangle BoundsRelative + { + get + { + return m_BoundsRelative; + } + } + + /// + /// Gets the absolute bounds of the tree node including the expand part of the node. + /// + [Browsable(false)] + public Rectangle Bounds + { + get + { + AdvTree tree = this.TreeControl; + if (tree != null) + { + return NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, this, tree.NodeDisplay.Offset); + } + return Rectangle.Empty; + } + } + + /// + /// Sets the bounds of the node. + /// + /// New location and size of the node. + internal void SetBounds(Rectangle r) + { + m_BoundsRelative = r; + } + + /// + /// Sets the content bounds of the node. Content bound is bound for the the cells inside the node + /// and it excludes the expand rectangle. Bounds also include the node style padding and + /// reflect node margin. + /// + /// New location and size of the node. + internal void SetContentBounds(Rectangle r) + { + m_ContentBounds = r; + } + + /// + /// Gets the node content bounds. + /// + internal Rectangle ContentBounds + { + get { return m_ContentBounds; } + } + + /// + /// Gets the bounds for all the cells inside the node. The bounds do not include the expand part. + /// + [Browsable(false)] + internal Rectangle CellsBoundsRelative + { + get { return m_CellsBounds; } + } + + /// + /// Gets the bounds for all the cells inside the node. The bounds do not include the expand part. + /// + [Browsable(false)] + public Rectangle CellsBounds + { + get + { + AdvTree tree = this.TreeControl; + if (tree != null) + { + return NodeDisplay.GetNodeRectangle(eNodeRectanglePart.CellsBounds, this, tree.NodeDisplay.Offset); + } + return Rectangle.Empty; + } + } + + /// + /// Sets cell bounds. + /// + /// New cells bounds. + internal void SetCellsBounds(Rectangle r) + { + m_CellsBounds = r; + } + + /// + /// Sets node parent. + /// + /// Parent node object. + internal void SetParent(Node parent) + { + if (parent == null) + { + RemoveHostedControls(true); + } + if (m_Parent != parent) + { + m_Parent = parent; + foreach (Cell cell in m_Cells) + { + if (cell.HostedControl != null) + cell.AddHostedControlToTree(); + } + OnParentChanged(); + } + } + + internal void InvokeOnParentChanged() + { + OnParentChanged(); + } + + /// + /// Called when Parent of the node has changed. + /// + protected virtual void OnParentChanged() + { + } + + internal void RemoveHostedControls(bool enumChildren) + { + foreach (Cell cell in m_Cells) + { + if (cell.HostedControl != null && cell.HostedControl.Parent is AdvTree) + cell.RemoveHostedControlFromTree(); + } + if (!enumChildren || m_Nodes == null) return; + foreach (Node item in m_Nodes) + { + item.RemoveHostedControls(true); + } + } + + /// + /// Gets or sets the bounds of child nodes. + /// + internal Rectangle ChildNodesBounds + { + get { return m_ChildNodesBounds; } + set { m_ChildNodesBounds = value; } + } + + /// + /// Gets the expand part rectangle. Expand part is used to expand/collapse node. + /// + [Browsable(false)] + internal Rectangle ExpandPartRectangleRelative + { + get { return m_ExpandPartRectangle; } + } + + /// + /// Gets the expand part rectangle. Expand part is used to expand/collapse node. + /// + [Browsable(false)] + public Rectangle ExpandPartRectangle + { + get + { + AdvTree tree = this.TreeControl; + if (tree != null) + { + return NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds, this, tree.NodeDisplay.Offset); + } + return Rectangle.Empty; + } + } + + /// + /// Sets the bounds of the expand part. + /// + /// New part bounds. + internal void SetExpandPartRectangle(Rectangle r) + { + m_ExpandPartRectangle = r; + } + + private eVerticalAlign _ExpandPartVerticalAlignment = eVerticalAlign.Middle; + /// + /// Indicates vertical alignment within the node bounds of expand part of the node, if one is visible. + /// + [DefaultValue(eVerticalAlign.Middle), Category("Appearance"), Description("Indicates vertical alignment within the node bounds of expand part of the node, if one is visible.")] + public eVerticalAlign ExpandPartVerticalAlignment + { + get { return _ExpandPartVerticalAlignment; } + set + { + if (_ExpandPartVerticalAlignment != value) + { + _ExpandPartVerticalAlignment = value; + InvalidateLayout(); + } + } + } + + /// + /// Gets or sets the Command part bounds if command part is visible. + /// + [Browsable(false)] + internal Rectangle CommandBounds + { + get + { + if (!m_CommandBoundsRelative.IsEmpty) + { + AdvTree tree = this.TreeControl; + if (tree != null) + { + return NodeDisplay.GetNodeRectangle(eNodeRectanglePart.CommandBounds, this, tree.NodeDisplay.Offset); + } + } + return Rectangle.Empty; + } + } + + internal Rectangle CommandBoundsRelative + { + get { return m_CommandBoundsRelative; } + set { m_CommandBoundsRelative = value; } + } + + /// + /// Gets or sets a value indicating whether the tree node is in a checked state. + /// + [Browsable(true), DefaultValue(false), Category("Appearance"), Description("Indicates whether the tree node is in a checked state."), DevCoSerialize()] + public bool Checked + { + get + { + return m_Cells[0].Checked; + } + set + { + m_Cells[0].Checked = value; + } + } + + /// + /// Sets the Checked or CheckState properties. + /// + /// New value for checked state. + /// Action source. + public void SetChecked(bool value, eTreeAction actionSource) + { + SetChecked(value ? CheckState.Checked : CheckState.Unchecked, actionSource); + } + + /// + /// Sets the Checked or CheckState properties. + /// + /// New value for checked state. + /// Action source. + public void SetChecked(CheckState value, eTreeAction actionSource) + { + m_Cells[0].SetChecked(value, actionSource); + } + + /// + /// Gets or sets the checkbox alignment in relation to the text displayed by first default cell. + /// + [Browsable(true), Category("Check-box Properties"), DefaultValue(eCellPartAlignment.Default), Description("Indicates checkbox alignment in relation to the text displayed by cell."), DevCoSerialize()] + public eCellPartAlignment CheckBoxAlignment + { + get + { + return m_Cells[0].CheckBoxAlignment; + } + set + { + m_Cells[0].CheckBoxAlignment = value; + } + } + + /// + /// Gets or sets whether check box is visible inside the cell. + /// + [Browsable(true), Category("Check-box Properties"), DefaultValue(false), Description("Indicates whether check box is visible inside the cell."), DevCoSerialize()] + public bool CheckBoxVisible + { + get + { + return m_Cells[0].CheckBoxVisible; + } + set + { + m_Cells[0].CheckBoxVisible = value; + } + } + + /// + /// Gets or sets the appearance style of the item. Default value is CheckBox. Item can also assume the style of radio-button. + /// + [Browsable(true), DefaultValue(eCheckBoxStyle.CheckBox), Category("Check-box Properties"), Description("Indicates appearance style of the item. Default value is CheckBox. Item can also assume the style of radio-button.")] + public eCheckBoxStyle CheckBoxStyle + { + get { return m_Cells[0].CheckBoxStyle; } + set + { + m_Cells[0].CheckBoxStyle = value; + } + } + + /// + /// Gets or sets a value indicating whether the CheckBox will allow three check states rather than two. If the ThreeState property is set to true + /// CheckState property should be used instead of Checked property to set the extended state of the control. + /// + [Browsable(true), Category("Check-box Properties"), DefaultValue(false), Description("Indicates whether the CheckBox will allow three check states rather than two.")] + public bool CheckBoxThreeState + { + get { return m_Cells[0].CheckBoxThreeState; } + set { m_Cells[0].CheckBoxThreeState = value; } + } + + /// + /// Specifies the state of a control, such as a check box, that can be checked, unchecked, or set to an indeterminate state. + /// + [Browsable(true), Category("Check-box Properties"), DefaultValue(CheckState.Unchecked), RefreshProperties(RefreshProperties.All), Description("Specifies the state of a control, such as a check box, that can be checked, unchecked, or set to an indeterminate state")] + public CheckState CheckState + { + get { return m_Cells[0].CheckState; } + set + { + m_Cells[0].CheckState = value; + } + } + + /// + /// Gets or sets whether first cell content is editable when cell editing is enabled on tree control. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether first cell content is editable when cell editing is enabled on tree control.")] + public bool Editable + { + get { return m_Cells[0].Editable; } + set + { + m_Cells[0].Editable = value; + } + } + + /// + /// Gets the path from the root tree node to the current tree node. The path consists of the labels of all the tree nodes that must be navigated to get to this tree node, starting at the root tree node. The node labels are separated by the delimiter character specified in the PathSeparator property of the Tree control that contains this node. + /// + [Browsable(false)] + public string FullPath + { + get + { + if (this.TreeControl == null) + return ""; + return NodeOperations.GetFullPath(this, this.TreeControl.PathSeparator); + } + } + + /// + /// Gets the zero based index of position of the tree node in the tree node collection. -1 is returned if node is not parented. If node is root node + /// the index of node in AdvTree.Nodes collection is returned. + /// + [Browsable(false)] + public int Index + { + get + { + return NodeOperations.GetNodeIndex(this); + } + } + + /// + /// Gets a value indicating whether the tree node is in an editable state. true if the tree node is in editable state; otherwise, false. + /// + [Browsable(false)] + public bool IsEditing + { + get { return m_Editing; } + } + /// + /// Sets whether node is in edit mode or not. + /// + /// True indicating that node is in edit mode false otherwise. + internal void SetEditing(bool b) + { + m_Editing = b; + } + + /// + /// Gets whether left mouse button is pressed on any cell contained by this node. + /// + [Browsable(false)] + public bool IsMouseDown + { + get + { + foreach (Cell cell in this.Cells) + { + if (cell.IsMouseDown) + return true; + } + return false; + } + } + + /// + /// Gets whether mouse cursor is over on any cell contained by this node. + /// + [Browsable(false)] + public bool IsMouseOver + { + get + { + foreach (Cell cell in this.Cells) + { + if (cell.IsMouseOver) + return true; + } + return false; + } + } + + private bool _IsSelected = false; + /// + /// Gets a value indicating whether the tree node is in the selected state. true if the tree node is in the selected state; otherwise, false. + /// + [Browsable(false)] + public bool IsSelected + { + get + { + return _IsSelected; + //AdvTree tree=this.TreeControl; + //if(tree!=null) + //{ + // if (tree.MultiSelect) + // { + // return tree.SelectedNodes.Contains(this); + // } + // else if(tree.SelectedNode==this) + // return true; + //} + //return false; + } + internal set + { + _IsSelected = value; + } + } + + private bool _Selectable = true; + /// + /// Gets or sets whether node can be selected by user by clicking it with the mouse or using keyboard. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether node can be selected by user by clicking it with the mouse or using keyboard.")] + public bool Selectable + { + get { return _Selectable; } + set + { + _Selectable = value; + } + } + + /// + /// Gets whether node can be selected. Node must be Visible, Enabled and Selectable in order for it to be selected. + /// + [Browsable(false)] + public bool CanSelect + { + get + { + return this.Enabled & this.Visible & this.Selectable; + } + } + + /// + /// Sets selected cell and provides information on the action that caused the selection change. + /// + /// New selected cell. + /// Action source. + public void SetSelectedCell(Cell value, eTreeAction actionSource) + { + AdvTree tree = this.TreeControl; + + if (!this.IsSelected && value != null) + { + if (tree != null) + tree.SelectedNode = this; + } + + Cell previousSelectedCell = null; + Cell selectedCell = null; + + foreach (Cell cell in m_Cells) + { + if (cell.IsSelected) previousSelectedCell = cell; + if (cell == value && cell.CanSelect) + { + selectedCell = cell; + cell.SetSelected(true, actionSource); + } + else + cell.SetSelected(false, actionSource); + } + + if (tree != null) + { + tree.InvalidateNode(this); + if (value == null || previousSelectedCell != null && value != previousSelectedCell) + { + tree.InvokeCellUnselected(new AdvTreeCellEventArgs(actionSource, previousSelectedCell)); + } + + if (selectedCell != null && previousSelectedCell != selectedCell) + { + tree.InvokeCellSelected(new AdvTreeCellEventArgs(actionSource, selectedCell)); + } + } + } + /// + /// Gets or sets a cell that is in selected state otherwise it returns null. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Cell SelectedCell + { + get + { + if (this.IsSelected) + { + return GetSelectedCell(); + } + return null; + } + set + { + SetSelectedCell(value, eTreeAction.Code); + } + } + + internal Cell GetSelectedCell() + { + foreach (Cell cell in m_Cells) + if (cell.IsSelected) + return cell; + return null; + } + internal void SelectFirstCell(eTreeAction actionSource) + { + foreach (Cell cell in m_Cells) + { + if (cell.CanSelect) + { + this.SetSelectedCell(cell, actionSource); + //cell.SetSelected(true); + break; + } + } + } + + /// + /// 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. + /// + [Browsable(false)] + public bool IsVisible + { + get + { + return NodeOperations.GetIsNodeVisible(this); + } + } + + /// + /// 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. + /// + [Browsable(false)] + public bool IsDisplayed + { + get { return NodeOperations.GetIsNodeDisplayed(this); } + } + + /// + /// 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). + /// + [Browsable(false)] + public Node LastNode + { + get + { + return NodeOperations.GetLastNode(this); + } + } + + /// + /// 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). + /// + [Browsable(false)] + public Node NextNode + { + get + { + return NodeOperations.GetNextNode(this); + } + } + + /// + /// 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). + /// + [Browsable(false)] + public Node NextVisibleNode + { + get + { + return NodeOperations.GetNextVisibleNode(this); + } + } + + /// + /// Gets the zero-based depth of the tree node in the tree control. The root node is considered the first level of nesting and returns 0. + /// + [Browsable(false)] + public int Level + { + get + { + int i = 0; + Node parent = this.Parent; + while (parent != null) + { + i++; + parent = parent.Parent; + } + return i; + } + } + + + /// + /// Gets the collection of Node objects assigned to the current tree node. The Nodes property can hold a collection of other Node objects. Each of the tree node in the collection has a Nodes property that can contain its own NodeCollection. Nesting of tree nodes can make it difficult to navigate a tree structure. The FullPath property makes it easier to determine your location in a tree. + /// + [Browsable(true), Category("Nodes"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public NodeCollection Nodes + { + get + { + if (m_Nodes == null) + { + m_Nodes = new NodeCollection(); + m_Nodes.SetParentNode(this); + } + return m_Nodes; + } + } + + ///// + ///// Gets the collection of LinkedNode objects that describe nodes linked to this node. + ///// + ///// + ///// 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 display relationships between nodes. + ///// + //[Browsable(true),Category("Nodes"), Description("Collection of LinkedNode objects that describe nodes linked to this node")] + //public LinkedNodesCollection LinkedNodes + //{ + // get + // { + // if(m_LinkedNodes==null) + // { + // m_LinkedNodes=new LinkedNodesCollection(); + // } + // return m_LinkedNodes; + // } + //} + + ///// + ///// Gets whether Node has any linked nodes. + ///// + //[Browsable(false)] + //public bool HasLinkedNodes + //{ + // get {return (m_LinkedNodes!=null && m_LinkedNodes.Count>0);} + //} + + /// + /// Gets whether there is at least one child node that has its Visible property set to true. + /// + [Browsable(false)] + public bool AnyVisibleNodes + { + get + { + return NodeOperations.GetAnyVisibleNodes(this); + } + } + + /// + /// Gets the parent tree node of the current tree node. If the tree node is at the root level, the Parent property returns a null reference (Nothing in Visual Basic). + /// + [Browsable(false)] + public Node Parent + { + get + { + return m_Parent; + } + } + + /// + /// 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). + /// + [Browsable(false)] + public Node PrevNode + { + get + { + return NodeOperations.GetPreviousNode(this); + } + } + + /// + /// 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). + /// + [Browsable(false)] + public Node PrevVisibleNode + { + get + { + return NodeOperations.GetPreviousVisibleNode(this); + } + } + + /// + /// Gets or sets the object that contains data about the tree node. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// + [Browsable(false), DefaultValue(null), Category("Data"), Description("Indicates text that contains data about the tree node."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object Tag + { + get + { + return m_Cells[0].Tag; + } + set + { + m_Cells[0].Tag = value; + } + } + + /// + /// Gets or sets the object that contains data about the tree node. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// + [Browsable(true), DefaultValue(""), Category("Data"), Description("Indicates text that contains data about the tree node."), DevCoSerialize()] + public string TagString + { + get + { + return m_Cells[0].TagString; + } + set + { + m_Cells[0].TagString = value; + } + } + + private int _BindingIndex = -1; + /// + /// Gets or sets the Binding index in CurrencyManager list if node is bound. You should not change this value directly since + /// it is used internally by the control for data binding scenarios. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int BindingIndex + { + get { return _BindingIndex; } + set + { + _BindingIndex = value; + } + } + + + /// + /// Gets or sets the object that contains additional data about the tree node. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// This property has same function as Tag property and provides you with additional separate storage of data. + /// + [Browsable(false), DefaultValue(null), Category("Data"), Description("Indicates text that contains data about the tree node."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object DataKey + { + get + { + return m_DataKey; + } + set + { + m_DataKey = value; + } + } + + /// + /// Gets or sets the object that contains additional data about the tree node. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// This property has same function as Tag property and provides you with additional separate storage of data. + /// + [Browsable(true), DefaultValue(""), Category("Data"), Description("Indicates text that contains data about the tree node."), DevCoSerialize()] + public string DataKeyString + { + get + { + if (m_DataKey == null) + return ""; + return m_DataKey.ToString(); + } + set + { + m_DataKey = value; + } + } + + /// + /// Gets or sets the format that is applied to the value of Text property for display purposes (applies to first cell in a node, i.e. Cells[0]). See "Formatting Overview" in MSDN + /// for description on available format strings. For example you can specify "C" to format text as currency, or "D" to format text as decimal number etc. + /// + /// + [Browsable(true), DefaultValue(""), Category("Appearance"), Description("Indicates format that is applied to the value of Text property for display purposes.")] + public string TextDisplayFormat + { + get { return this.Cells[0].TextDisplayFormat; } + set + { + this.Cells[0].TextDisplayFormat = value; + } + } + + /// + /// Gets or sets the text displayed in the tree node. + /// + [Browsable(true), DefaultValue(""), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Appearance"), Localizable(true), Description("Indicates text displayed in the tree node."), DevCoSerialize()] + public string Text + { + get + { + return this.Cells[0].Text; + } + set + { + this.Cells[0].Text = value; + } + } + + /// + /// Gets or sets the control hosted inside of the first node cell. + /// + /// + /// When control is hosted inside of the cell, cell size is determined by the + /// size of the control hosted inside of it. The cell will not display its text but it will display any image assigned + /// or check box when control is hosted inside of it. The Style settings like Margin + /// and Padding will still apply. + /// + [Browsable(true), Category("Appearance"), Description("Indicates control hosted inside of the cell."), DefaultValue(null)] + public Control HostedControl + { + get { return this.Cells[0].HostedControl; } + set + { + this.Cells[0].HostedControl = value; + } + } + + /// + /// Gets or sets the item hosted inside of the first cell. Only items that do not generate + /// popups are supported. Note that cell can only host either HostedItem or HostedControl but not both. + /// + [DefaultValue(null), Category("Appearance"), Editor("DevComponents.AdvTree.Design.HostedItemTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates item hosted inside of the cell. Only items that do not generate popups are supported. Note that cell can only host either HostedItem or HostedControl but not both.")] + public BaseItem HostedItem + { + get { return this.Cells[0].HostedItem; } + set { this.Cells[0].HostedItem = value; } + } + + /// + /// Gets the parent tree control that the tree node is assigned to. + /// + [Browsable(false)] + public AdvTree TreeControl + { + get + { + return this.GetTreeControl(); + } + } + + /// + /// Gets or sets the layout of the cells inside the node. Default value is Horizontal layout which + /// means that cell are positioned horizontally next to each other. + /// + [Browsable(true), DefaultValue(eCellLayout.Default), Category("Cells"), Description("Indicates layout of the cells inside the node."), DevCoSerialize()] + public eCellLayout CellLayout + { + get { return m_CellLayout; } + set + { + m_CellLayout = value; + this.SizeChanged = true; + } + } + + private eHorizontalAlign _VerticalCellLayoutAlignment = eHorizontalAlign.Center; + /// + /// Gets or sets the cell alignment when CellLayout=Vertical. Default value is center which means that cells are center aligned. + /// + [DefaultValue(eHorizontalAlign.Center), Category("Cells"), Description("Indicates cell alignment when CellLayout=Vertical. Default value is center which means that cells are center aligned.")] + public eHorizontalAlign VerticalCellLayoutAlignment + { + get { return _VerticalCellLayoutAlignment; } + set { _VerticalCellLayoutAlignment = value; this.SizeChanged = true; } + } + + /// + /// Gets or sets the layout of the cell parts like check box, image and text. Layout can be horizontal (default) + /// where parts of the cell are positioned next to each other horizontally, or vertical where + /// parts of the cell are positioned on top of each other vertically. + /// Alignment of the each part is controlled by alignment properties. This property affects only the first cell inside of the node. + /// Use Cell.Layout property to change the part layout on each cell contained by node. + /// + [Browsable(true), DefaultValue(eCellPartLayout.Default), Category("Cells"), Description("Indicates the layout of the cell parts like check box, image and text."), DevCoSerialize()] + public eCellPartLayout CellPartLayout + { + get { return m_Cells[0].Layout; } + set + { + if (m_Cells[0].Layout != value) + { + m_Cells[0].Layout = value; + } + } + } + + /// + /// Gets/Sets informational text (tooltip) for the cell. + /// + [Browsable(true), DefaultValue(""), Category("Appearance"), Description("Indicates the text that is displayed when mouse hovers over the cell."), Localizable(true)] + public string Tooltip + { + get + { + + return m_Cells[0].Tooltip; + } + set + { + m_Cells[0].Tooltip = value; + } + } + + /// + /// Gets the collection of all Cells assigned to this node. There should be always at least one cell in a node which is default cell. Default + /// collection contains a single cell. + /// + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Cells"), Description("Collection of Cells assigned to this node.")] + public CellCollection Cells + { + get { return m_Cells; } + } + + private bool _NodesColumnsHeaderVisible = true; + /// + /// Gets or sets whether column header for child nodes if defined is visible. Default value is true. + /// + [DefaultValue(true), Category("Columns"), Description("Indicates whether column header for child nodes if defined is visible.")] + public bool NodesColumnsHeaderVisible + { + get { return _NodesColumnsHeaderVisible; } + set + { + _NodesColumnsHeaderVisible = value; + SizeChanged = true; + OnDisplayChanged(); + } + } + + /// + /// Gets whether node has child nodes columns defined. + /// + [Browsable(false)] + public bool HasColumns + { + get + { + if (m_NodesColumns != null && m_NodesColumns.Count > 0) return true; + return false; + } + } + + /// + /// Get collection of child node columns. + /// + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Columns"), Description("Defines the columns for the child nodes.")] + public ColumnHeaderCollection NodesColumns + { + get + { + if (m_NodesColumns == null) + { + m_NodesColumns = new ColumnHeaderCollection(); + m_NodesColumns.SetParentNode(this); + } + return m_NodesColumns; + } + } + + // /// + // /// Gets or sets whether child node column header is visible or not. + // /// + // [Browsable(true),DefaultValue(true),Category("Columns"),Description("Indicates whether child node column header is visible or not.")] + // public bool NodesColumnHeaderVisible + // { + // get {return m_NodesColumnHeaderVisible;} + // set + // { + // if(m_NodesColumnHeaderVisible!=value) + // { + // m_NodesColumnHeaderVisible=value; + // if(this.Expanded) + // this.OnChildNodesSizeChanged(); + // } + // } + // } + + /// Gets or sets the style of the cells when node is expanded. + /// + /// Reference to the style assigned to the node/cell or null value indicating that + /// default style setting from tree control is applied. Default value is null. + /// + /// + /// When node is expanded the style specified here will be used on all cells + /// associated with this node instead of the + /// Cell.StyleNormal. That way you can give + /// different appearance to your node's cells when node is expanded. + /// When property is set to null value the style setting from parent tree + /// controls is used. NodeStyleExpanded on + /// AdvTree control is a root style for a cell. + /// + [Browsable(true), DefaultValue(null), Category("Style"), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the style for the child nodes when node is expanded.")] + public ElementStyle StyleExpanded + { + get { return m_StyleExpanded; } + set + { + if (m_StyleExpanded != value) + { + if (m_StyleExpanded != null) + m_StyleExpanded.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_StyleExpanded = value; + if (this.Expanded) + this.SizeChanged = true; + } + } + } + + /// + /// Gets or sets the expanded style name used by node. This member is provided for internal use only. To set or get the style use StyleExpanded property instead. + /// + [Browsable(false), DefaultValue(""), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), DevCoSerialize()] + public string StyleExpandedName + { + get + { + if (m_StyleExpanded != null) + return m_StyleExpanded.Name; + return ""; + } + set + { + if (value.Length == 0) + { + TypeDescriptor.GetProperties(this)["StyleExpanded"].SetValue(this, null); + return; + } + + AdvTree tree = this.TreeControl; + if (tree != null) + { + TypeDescriptor.GetProperties(this)["StyleExpanded"].SetValue(this, tree.Styles[value]); + } + } + } + + /// + /// Gets or sets the style used when Node is selected. Default value is NULL (VB + /// Nothing) + /// + [Browsable(true), DefaultValue(null), Category("Style"), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the style for the nodes when node is selected.")] + public ElementStyle StyleSelected + { + get { return m_StyleSelected; } + set + { + if (m_StyleSelected != value) + { + if (m_StyleSelected != null) + m_StyleSelected.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_StyleSelected = value; + if (this.IsSelected) + this.SizeChanged = true; + } + } + } + + /// + /// Gets or sets the selected style name used by node. This member is provided for internal use only. To set or get the style use StyleSelected property instead. + /// + [Browsable(false), DefaultValue(""), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), DevCoSerialize()] + public string StyleSelectedName + { + get + { + if (m_StyleSelected != null) + return m_StyleSelected.Name; + return ""; + } + set + { + if (value.Length == 0) + { + TypeDescriptor.GetProperties(this)["StyleSelected"].SetValue(this, null); + return; + } + + AdvTree tree = this.TreeControl; + if (tree != null) + { + TypeDescriptor.GetProperties(this)["StyleSelected"].SetValue(this, tree.Styles[value]); + } + } + } + + /// + /// Gets or sets the style used when mouse is over the Node. Default value is NULL + /// (VB Nothing) + /// + [Browsable(true), DefaultValue(null), Category("Style"), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the style for the nodes when node is selected.")] + public ElementStyle StyleMouseOver + { + get { return m_StyleMouseOver; } + set + { + if (m_StyleMouseOver != value) + { + if (m_StyleMouseOver != null) + m_StyleMouseOver.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_StyleMouseOver = value; + } + } + } + + /// + /// Gets or sets the mouse over style name used by node. This member is provided for internal use only. To set or get the style use StyleMouseOver property instead. + /// + [Browsable(false), DefaultValue(""), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), DevCoSerialize()] + public string StyleMouseOverName + { + get + { + if (m_StyleMouseOver != null) + return m_StyleMouseOver.Name; + return ""; + } + set + { + if (value.Length == 0) + { + TypeDescriptor.GetProperties(this)["StyleMouseOver"].SetValue(this, null); + return; + } + + AdvTree tree = this.TreeControl; + if (tree != null) + { + TypeDescriptor.GetProperties(this)["StyleMouseOver"].SetValue(this, tree.Styles[value]); + } + } + } + + /// + /// Gets or sets the node style. + /// + /// + /// Reference to the style assigned to the node or null value indicating that default + /// style setting from tree control is applied. Default value is null. + /// + /// + /// Style specified by this property will be used as default style for the node. + /// Each cell within the node can also specify it's own style. Since node contains the + /// cells using this style property can you for example create a border around all cell + /// contained by the node. + /// When this property is set to null value (default value) NodeStyle + /// property on AdvTree control is used. + /// + [Browsable(true), DefaultValue(null), Category("Style"), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the node style.")] + public ElementStyle Style + { + get { return m_Style; } + set + { + if (m_Style != value) + { + if (m_Style != null) + m_Style.StyleChanged -= new EventHandler(this.ElementStyleChanged); + if (value != null) + value.StyleChanged += new EventHandler(this.ElementStyleChanged); + m_Style = value; + this.SizeChanged = true; + this.Invalidate(); + } + } + } + + /// + /// Gets or sets the style name used by node. This member is provided for internal use only. To set or get the style use Style property instead. + /// + [Browsable(false), DefaultValue(""), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), DevCoSerialize()] + public string StyleName + { + get + { + if (m_Style != null) + return m_Style.Name; + return ""; + } + set + { + if (value.Length == 0) + { + TypeDescriptor.GetProperties(this)["Style"].SetValue(this, null); + return; + } + + AdvTree tree = this.TreeControl; + if (tree != null) + { + TypeDescriptor.GetProperties(this)["Style"].SetValue(this, tree.Styles[value]); + } + } + } + + /// + /// Gets or sets the part of the node mouse is over. + /// + internal eMouseOverNodePart MouseOverNodePart + { + get { return m_MouseOverNodePart; } + set { m_MouseOverNodePart = value; } + } + + + /// + /// Gets or sets the node horizontal offset from the position determined by the layout manager. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), DefaultValue(0)] + internal int Offset + { + get { return m_Offset; } + set + { + m_Offset = value; + this.SizeChanged = true; + } + } + + /// + /// Gets or sets the image alignment in relation to the text displayed by cell. This property affects only first default cell inside the node. + /// Property with same name is available on each cell and you can use it to affect each cell individually. + /// + [Browsable(true), Category("Image Properties"), DefaultValue(eCellPartAlignment.Default), Description("Gets or sets the image alignment in relation to the text displayed by cell."), DevCoSerialize()] + public eCellPartAlignment ImageAlignment + { + get + { + return m_Cells[0].ImageAlignment; + } + set + { + if (m_Cells[0].ImageAlignment != value) + { + m_Cells[0].ImageAlignment = value; + } + } + } + + private bool _Enabled = true; + /// + /// Gets or sets whether node is enabled. Default value is true. Setting this value to false will set Enabled=false on all child cells. + /// + [Browsable(true), DefaultValue(true), Category("Behavior"), Description("Gets or sets whether node is enabled."), DevCoSerialize()] + public bool Enabled + { + get { return _Enabled; } + set + { + _Enabled = value; + foreach (Cell c in m_Cells) + { + c.Enabled = _Enabled; + } + } + } + + + /// + /// Gets or sets the image displayed when the tree node is disabled. If image is not specified control will create + /// gray-scale disabled image automatically. + /// + /// + /// Image specified will be used as image when node is disabled. + /// + [Browsable(true), Category("Images"), Description("Indicates image displayed when the tree node is disabled."), DefaultValue(null), DevCoSerialize()] + public System.Drawing.Image ImageDisabled + { + get { return m_Cells[0].Images.ImageDisabled; } + set + { + this.SizeChanged = true; + m_Cells[0].Images.ImageDisabled = value; + } + } + /// + /// Resets image to its default value. Windows Forms designer support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetImageDisabled() + { + TypeDescriptor.GetProperties(this)["ImageDisabled"].SetValue(this, null); + } + /// + /// Gets or sets the image-list index value of the disabled image. + /// + [Browsable(true), Category("Images"), Description("Indicates the image-list index value of the disabled image"), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), DefaultValue(-1), DevCoSerialize()] + public int ImageDisabledIndex + { + get { return this.Cells[0].Images.ImageDisabledIndex; } + set + { + this.SizeChanged = true; + this.Cells[0].Images.ImageDisabledIndex = value; + } + } + + /// + /// Gets or sets the image displayed when the tree node is in the unselected state. + /// + /// + /// Image specified will be used as a default image for any other node state where + /// different image is not specified. + /// + [Browsable(true), Category("Images"), Description("Indicates image displayed when the tree node is in the unselected state."), DefaultValue(null), DevCoSerialize()] + public System.Drawing.Image Image + { + get { return m_Cells[0].Images.Image; } + set + { + this.SizeChanged = true; + m_Cells[0].Images.Image = value; + } + } + + /// + /// Resets image to its default value. Windows Forms designer support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetImage() + { + TypeDescriptor.GetProperties(this)["Image"].SetValue(this, null); + } + + /// + /// Gets or sets the image-list key value of the default image that is displayed by the tree nodes. + /// + [Browsable(true), Category("Images"), Description("Indicates the image-list key value of the default image that is displayed by the tree nodes."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), DefaultValue(""), DevCoSerialize()] + public string ImageKey + { + get { return this.Cells[0].Images.ImageKey; } + set + { + this.SizeChanged = true; + this.Cells[0].Images.ImageKey = value; + } + } + + /// + /// Gets or sets the image-list index value of the default image that is displayed by the tree nodes. + /// + [Browsable(true), Category("Images"), Description("Indicates the image-list index value of the default image that is displayed by the tree nodes."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), DefaultValue(-1), DevCoSerialize()] + public int ImageIndex + { + get { return this.Cells[0].Images.ImageIndex; } + set + { + this.SizeChanged = true; + this.Cells[0].Images.ImageIndex = value; + } + } + + /// + /// Gets or sets the image displayed when mouse is over the tree node. + /// + [Browsable(true), Category("Images"), Description("Indicates the image displayed when mouse is over the tree node."), DefaultValue(null), DevCoSerialize()] + public System.Drawing.Image ImageMouseOver + { + get { return this.Cells[0].Images.ImageMouseOver; } + set + { + this.Cells[0].Images.ImageMouseOver = value; + this.SizeChanged = true; + } + } + + /// + /// Resets ImageMouseOver to its default value. Windows Forms designer support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetImageMouseOver() + { + TypeDescriptor.GetProperties(this)["ImageMouseOver"].SetValue(this, null); + } + + /// + /// Gets or sets the image-list index value of the image that is displayed by the tree nodes when mouse is over the node. + /// + [Browsable(true), Category("Images"), Description("Indicates the image-list index value of the image that is displayed by the tree nodes when mouse is over the node."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), DefaultValue(-1), DevCoSerialize()] + public int ImageMouseOverIndex + { + get { return this.Cells[0].Images.ImageMouseOverIndex; } + set + { + this.SizeChanged = true; + this.Cells[0].Images.ImageMouseOverIndex = value; + } + } + + /// + /// Gets or sets the image-list key value of the image that is displayed by the tree nodes when mouse is over the node. + /// + [Browsable(true), Category("Images"), Description("Indicates the image-list key value of the image that is displayed by the tree nodes when mouse is over the node."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), DefaultValue(""), DevCoSerialize()] + public string ImageMouseOverKey + { + get { return this.Cells[0].Images.ImageMouseOverKey; } + set + { + this.SizeChanged = true; + this.Cells[0].Images.ImageMouseOverKey = value; + } + } + + /// + /// Gets or sets the image displayed when node is expanded. + /// + [Browsable(true), Category("Images"), Description("Indicates the image displayed when node is expanded."), DefaultValue(null), DevCoSerialize()] + public System.Drawing.Image ImageExpanded + { + get { return this.Cells[0].Images.ImageExpanded; } + set + { + this.Cells[0].Images.ImageExpanded = value; + this.SizeChanged = true; + } + } + + /// + /// Resets ImageExpanded to its default value. Windows Forms designer support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetImageExpanded() + { + TypeDescriptor.GetProperties(this)["ImageExpanded"].SetValue(this, null); + } + + /// + /// Gets or sets the image-list index value of the image that is displayed by the tree nodes when node is expanded. + /// + [Browsable(true), Category("Images"), Description("Indicates the image-list index value of the image that is displayed by the tree nodes when node is expanded."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), DefaultValue(-1), DevCoSerialize()] + public int ImageExpandedIndex + { + get { return this.Cells[0].Images.ImageExpandedIndex; } + set + { + this.SizeChanged = true; + this.Cells[0].Images.ImageExpandedIndex = value; + } + } + + /// + /// Gets or sets the image-list key value of the image that is displayed by the tree nodes when node is expanded. + /// + [Browsable(true), Category("Images"), Description("Indicates the image-list key value of the image that is displayed by the tree nodes when node is expanded."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), DefaultValue(""), DevCoSerialize()] + public string ImageExpandedKey + { + get { return this.Cells[0].Images.ImageExpandedKey; } + set + { + this.SizeChanged = true; + this.Cells[0].Images.ImageExpandedKey = value; + } + } + + /// + /// Property Editor support for ImageIndex selection + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public System.Windows.Forms.ImageList ImageList + { + get + { + AdvTree tree = this.TreeControl; + if (tree != null) + { + return tree.ImageList; + } + return null; + } + } + + ///// + ///// Sets the node relative position form the root when map layout is used. + ///// + ///// Relative node position. + //internal void SetMapSubRootPosition(eMapPosition pos) + //{ + // m_MapSubRootPosition=pos; + //} + + /// + /// Gets or sets the NodeConnector object that describes the type of the connector used for + /// displaying connection between current node and its parent node. + /// Default value is null which means that settings from AdvTree control are used. + /// + /// RootConnector Property (DevComponents.AdvTree.AdvTree) + /// NodesConnector Property (DevComponents.AdvTree.AdvTree) + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), Category("Connectors"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.NodeConnectorTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Indicates the nested nodes connector.")] + public NodeConnector ParentConnector + { + get { return m_ParentConnector; } + set + { + if (m_ParentConnector != value) + { + if (m_ParentConnector != null) + m_ParentConnector.AppearanceChanged -= new EventHandler(this.ConnectorAppearanceChanged); + if (value != null) + value.AppearanceChanged += new EventHandler(this.ConnectorAppearanceChanged); + m_ParentConnector = value; + this.OnDisplayChanged(); + } + } + } + + ///// + ///// Gets the collection of the parent connector line relative points. 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. + ///// + //[Browsable(true),Category("Connectors"),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + //internal ConnectorPointsCollection ParentConnectorPoints + //{ + // get {return m_ParentConnectorPoints;} + //} + + /// + /// Gets or sets whether node is visible. + /// + [Browsable(true), Category("Behavior"), DefaultValue(true), Description("Indicated whether node is visible"), DevCoSerialize()] + public bool Visible + { + get { return m_Visible; } + set + { + m_Visible = value; + this.OnVisibleChanged(); + this.SizeChanged = true; + } + } + + /// + /// Gets or sets whether command button is visible. Default value is false. + /// Command button can be used to display for example popup menu with commands for node, + /// or to display the list of linked nodes. + /// + [Browsable(true), DefaultValue(false), Category("Command Button"), Description("Indicates visibility of command button."), DevCoSerialize()] + internal bool CommandButton + { + get { return m_CommandButton; } + set + { + m_CommandButton = value; + this.OnDisplayChanged(); + } + } + + /// + /// Gets or sets internal value that indicates that node is on "path" of the selected node. + /// + internal bool SelectedConnectorMarker + { + get { return m_SelectedConnectorMarker; } + set { m_SelectedConnectorMarker = value; } + } + + public void InternalDeselected(eTreeAction action) + { + OnDeselected(action); + } + + /// + /// Called after node has been deselected. + /// + /// Provides information on how selection was performed + protected virtual void OnDeselected(eTreeAction action) + { + + } + /// + /// Called after node has been selected. + /// + /// Provides information on how selection was performed + protected virtual void OnSelected(eTreeAction action) + { + + } + public void InternalSelected(eTreeAction action) + { + OnSelected(action); + } + + private bool _IsDragNode = false; + /// + /// Gets whether node is a drag node being used for drag & drop preview. + /// + [Browsable(false)] + public bool IsDragNode + { + get { return _IsDragNode; } +#if FRAMEWORK20 + internal set +#else + set +#endif + { + if (_IsDragNode != value) + { + _IsDragNode = value; + if (m_Nodes != null) + { + foreach (Node n in this.Nodes) + { + n.IsDragNode = value; + } + } + } + } + } + + private bool _IsSelectionVisible = true; + /// + /// Gets or sets whether node selection is visible in UI when node is selected. Default value is true. You can + /// set this value to false to temporary disable the display of selection for a node. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSelectionVisible + { + get { return _IsSelectionVisible; } + set + { + if (_IsSelectionVisible != value) + { + _IsSelectionVisible = value; + this.Invalidate(); + } + } + } + + private int _NodesIndent = 0; + /// + /// Gets or sets the additional indent for the child nodes that is added to the AdvTree.Indent value when performing child node layout. Default value i 0. + /// + [DefaultValue(0), Category("Appearance"), Description("additional indent for the child nodes that is added to the AdvTree.Indent value when performing child node layout")] + public int NodesIndent + { + get { return _NodesIndent; } + set + { + _NodesIndent = value; + this.InvalidateLayout(true); + } + } + + #endregion + + #region Methods + /// + /// Returns cell within a node which contains specified coordinates. + /// + /// + /// + /// Cell which contains specified coordinates or null/nothing if no cell contains coordinates. + public Cell GetCellAt(int x, int y) + { + Cell cellAt = null; + foreach (Cell cell in m_Cells) + { + if (!cell.IsVisible) continue; + Rectangle rCell = cell.Bounds; + if (rCell.Contains(x, y)) + { + cellAt = cell; + break; + } + } + return cellAt; + } + + private bool _CellNavigationEnabled = true; + /// + /// Gets or sets whether Left/Right navigation through the cells when SingleCellSelection on tree is set is enabled. Default value is true. + /// + [DefaultValue(true), Browsable(false)] + public virtual bool CellNavigationEnabled + { + get + { + return _CellNavigationEnabled; + } + set + { + _CellNavigationEnabled = value; + } + } + internal void InternalKeyDown(KeyEventArgs e) + { + OnKeyDown(e); + } + + protected virtual void OnKeyDown(KeyEventArgs e) + { + + } + + /// + /// Invalidates the layout for this node and causes the layout to be performed on next layout request. + /// + public void InvalidateLayout() + { + NodeOperations.InvalidateNodeLayout(this, false); + } + /// + /// Invalidates the layout for this node and causes the layout to be performed on next layout request. + /// + /// Indicates whether to invalidate layout for all child nodes as well. + public void InvalidateLayout(bool invalidateChildNodes) + { + NodeOperations.InvalidateNodeLayout(this, invalidateChildNodes); + } + + /// + /// Invalidates node and causes a paint message to be sent to the tree. + /// + public void Invalidate() + { + AdvTree tree = this.TreeControl; + if (tree != null) + tree.InvalidateNode(this); + } + + /// Initiates the editing of node text. + /// + /// This method by default edits text stored in Node.Text. Call to this method is + /// same as calling the overload method BeginData(0) with zero as parameter. Use BeginData + /// overload method to begin editing the specific column for multi-column nodes. + /// + public void BeginEdit() + { + BeginEdit(0); + } + + /// Initiates the editing of node text. + /// + /// The initial text to be entered into the edit TextBox. Specify null to use existing text. + /// + public void BeginEdit(string initialText) + { + BeginEdit(0, initialText); + } + + /// Initiates text editing of certain Node column. + /// + /// Zero based index of a column to begin editing for. Column 0 always corresponds to + /// Node.Text property. + /// + public void BeginEdit(int iColumnIndex) + { + BeginEdit(iColumnIndex, null); + } + + /// Initiates text editing of certain Node column. + /// + /// Zero based index of a column to begin editing for. Column 0 always corresponds to + /// Node.Text property. + /// + /// + /// The initial text to be entered into the edit TextBox. Specify null to edit existing text. + /// + public void BeginEdit(int iColumnIndex, string initialText) + { + AdvTree tree = this.TreeControl; + if (tree == null) + return; + Cell cell = this.Cells[iColumnIndex]; + if (!cell.IsEditable) + throw new InvalidOperationException("Cell is not editable, either Cell.Editable=false or ColumnHeader.Editable=false."); + tree.EditCell(this.Cells[iColumnIndex], eTreeAction.Code, initialText); + } + /// + /// Creates new instance of the node for the Copy() and DeepCopy() methods. Allows you to returns your own node type copy if you inherit from node to add custom properties. + /// + /// New instance of a node. + protected virtual Node CreateCopyInstance() + { + return new Node(); + } + /// Makes a "shallow" copy of a Node. + /// + /// Shallow copy of a Node is a exact copy of Node but without copy + /// of all child nodes in Nodes collection. + /// + public virtual Node Copy() + { + Node n = CreateCopyInstance(); + CopyTo(n); + return n; + } + /// + /// Copies this node properties to a node. + /// + /// Node top copy properties to. + protected virtual void CopyTo(Node n) + { + // TODO: Verify that all properties are copied + n.CellLayout = this.CellLayout; + n.Cells.Clear(); + foreach (Cell c in this.Cells) + n.Cells.Add(c.Copy()); + n.Checked = this.Checked; + n.CommandButton = this.CommandButton; + n.ExpandVisibility = this.ExpandVisibility; + n.Image = this.Image; + n.ImageDisabled = this.ImageDisabled; + n.ImageDisabledIndex = this.ImageDisabledIndex; + n.ImageExpanded = this.ImageExpanded; + n.ImageExpandedIndex = this.ImageExpandedIndex; + n.ImageIndex = this.ImageIndex; + n.ImageMouseOver = this.ImageMouseOver; + n.ImageMouseOverIndex = this.ImageMouseOverIndex; + n.Expanded = this.Expanded; + n.DragDropEnabled = this.DragDropEnabled; + n.CellLayout = this.CellLayout; + n.CellPartLayout = this.CellPartLayout; + n.CheckBoxAlignment = this.CheckBoxAlignment; + n.CheckBoxStyle = this.CheckBoxStyle; + n.CheckBoxThreeState = this.CheckBoxThreeState; + n.CheckBoxVisible = this.CheckBoxVisible; + n.CheckState = this.CheckState; + n.ContextMenu = this.ContextMenu; + n.DataKey = this.DataKey; + n.DragDropEnabled = this.DragDropEnabled; + n.Enabled = this.Enabled; + n.FullRowBackground = this.FullRowBackground; + n.ImageAlignment = this.ImageAlignment; + n.Selectable = this.Selectable; + //n.NodesColumnHeaderVisible=this.NodesColumnHeaderVisible; + foreach (ColumnHeader c in this.NodesColumns) + n.NodesColumns.Add(c.Copy()); + n.ParentConnector = this.ParentConnector; + n.Style = this.Style; + n.StyleExpanded = this.StyleExpanded; + n.StyleMouseOver = this.StyleMouseOver; + n.StyleSelected = this.StyleSelected; + n.Tag = this.Tag; + n.DataKey = this.DataKey; + n.Text = this.Text; + n.Visible = this.Visible; + n.Name = this.Name; + //n.ParentConnectorPoints.AddRange(this.ParentConnectorPoints.ToArray()); + } + /// Makes a "deep" copy of a node. + /// + /// Deep copy of Node is a exact copy of Node including exact copies of all child nodes + /// in this node's Nodes collection. + /// + public virtual Node DeepCopy() + { + Node n = this.Copy(); + foreach (Node c in this.Nodes) + n.Nodes.Add(c.DeepCopy()); + return n; + } + + /// + /// Collapses the tree node. + /// + public void Collapse() + { + this.SetExpanded(false, eTreeAction.Code); + } + + /// + /// Collapses the tree node. + /// + /// Action that caused the event + public void Collapse(eTreeAction action) + { + this.SetExpanded(false, action); + } + + /// + /// Collapses all the child tree nodes. + /// + public void CollapseAll() + { + AdvTree tree = this.TreeControl; + if (tree != null) + tree.BeginUpdate(); + this.Collapse(); + foreach (Node node in this.Nodes) + node.CollapseAll(); + if (tree != null) + tree.EndUpdate(); + } + + /// + /// Ends the editing of the node text or column. + /// + /// true if the editing of the tree node label text was canceled without being saved; otherwise, false. + public void EndEdit(bool cancelChanges) + { + if (!this.IsEditing) + return; + AdvTree tree = this.TreeControl; + if (tree == null) + return; + if (cancelChanges) + tree.CancelCellEdit(eTreeAction.Code); + else + tree.EndCellEditing(eTreeAction.Code); + } + + /// + /// Ensures that the node is visible, expanding nodes and scrolling the control as necessary. + /// + public void EnsureVisible() + { + NodeOperations.EnsureVisible(this, AdvTreeSettings.SelectedScrollIntoViewHorizontal); + } + /// + /// Ensures that the node is visible, expanding nodes and scrolling the control as necessary. + /// + /// Indicates the position within a tree visible area node is scrolled to + public void EnsureVisible(eEnsureVisibleOption ensureVisibleOption) + { + NodeOperations.EnsureVisible(this, AdvTreeSettings.SelectedScrollIntoViewHorizontal, ensureVisibleOption); + } + + /// + /// Expands the node. + /// + /// + /// The Expand method expands the current Node down to the next level of nodes. + /// The state of a Node is persisted. For example, if the next level of child nodes was not collapsed previously, when the Expand method is called, the child nodes appear in their previously expanded state. + /// + public void Expand() + { + SetExpanded(true, eTreeAction.Code); + } + + /// + /// Expands the node. + /// + /// + /// The Expand method expands the current Node down to the next level of nodes. + /// The state of a Node is persisted. For example, if the next level of child nodes was not collapsed previously, when the Expand method is called, the child nodes appear in their previously expanded state. + /// + /// Action that caused the event. + public void Expand(eTreeAction action) + { + SetExpanded(true, action); + } + + /// + /// Expands all the child tree nodes. + /// + public void ExpandAll() + { + ExpandAll(eTreeAction.Code); + } + /// + /// Expands all the child tree nodes. + /// + public void ExpandAll(eTreeAction action) + { + AdvTree tree = this.TreeControl; + if (tree != null) + tree.BeginUpdate(); + try + { + if (!this.Expanded) this.Expand(action); + foreach (Node node in this.Nodes) + { + node.Expand(action); + node.ExpandAll(action); + } + } + finally + { + if (tree != null) + tree.EndUpdate(); + } + } + + /// + /// Removes the current node from the control. + /// + /// + /// When the Remove method is called, the node and any child nodes assigned to the Node are removed from the Tree. The removed child nodes are removed from the Tree, but are still attached to this node. + /// + public void Remove() + { + if (this.Parent != null) + this.Parent.Nodes.Remove(this); + else if (this.TreeControl != null && this.TreeControl.Nodes.Contains(this)) + this.TreeControl.Nodes.Remove(this); + } + + /// + /// Removes the current node from the control and provides information about source of action + /// + /// + /// When the Remove method is called, the node and any child nodes assigned to the Node are removed from the Tree. The removed child nodes are removed from the Tree, but are still attached to this node. + /// + public void Remove(eTreeAction source) + { + if (this.Parent != null) + { + this.Parent.Nodes.Remove(this, source); + } + else if (this.TreeControl != null && this.TreeControl.Nodes.Contains(this)) + { + this.TreeControl.Nodes.Remove(this, source); + } + } + + /// + /// Toggles the node to either the expanded or collapsed state. + /// + public void Toggle() + { + if (this.Expanded) + this.Collapse(); + else + this.Expand(); + } + + /// + /// Toggles the node to either the expanded or collapsed state. + /// + /// Action that caused the event. + public void Toggle(eTreeAction action) + { + if (this.Expanded) + this.Collapse(action); + else + this.Expand(action); + } + + /// Returns string representation of the Node. + public override string ToString() + { + System.Text.StringBuilder build = new System.Text.StringBuilder(); + int c = this.Cells.Count; + for (int i = 0; i < c; i++) + { + build.Append(this.Cells[i].Text); + if (i + 1 < c) build.Append(", "); + } + return build.ToString(); + } + + private bool _FullRowBackground = false; + /// + /// Gets or sets whether style background that is applied to the node is drawn across the width of the tree control instead of only + /// behind the node content. Default value is false. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether style background that is applied to the node is drawn across the width of the tree control instead of only behind the node content.")] + public bool FullRowBackground + { + get { return _FullRowBackground; } + set + { + if (_FullRowBackground != value) + { + _FullRowBackground = value; + this.SizeChanged = true; + this.Invalidate(); + } + } + } + + internal void BeforeCellCheck(Cell cell, AdvTreeCellBeforeCheckEventArgs e) + { + OnBeforeCellCheck(cell, e); + } + + protected virtual void OnBeforeCellCheck(Cell cell, AdvTreeCellBeforeCheckEventArgs e) + { + } + #endregion + + #region Private Implementation + /// + /// Called after new cell has been added to Cells collection. + /// + /// Reference to the new cell added. + internal void OnCellInserted(Cell cell) + { + this.SizeChanged = true; + OnDisplayChanged(); + } + + /// + /// Called after cell has been removed from Cells collection. + /// + /// Reference to the removed cell. + internal void OnCellRemoved(Cell cell) + { + this.SizeChanged = true; + OnDisplayChanged(); + } + + /// + /// Gets or sets the child column header height. + /// + internal int ColumnHeaderHeight + { + get { return m_ColumnHeaderHeight; } + set { m_ColumnHeaderHeight = value; } + } + + /// + /// Occurs when property on the node has changed that influences the size of the node. + /// + private void OnSizeChanged() + { + if (m_SizeChanged) + { + AdvTree tree = this.TreeControl; + if (tree != null && !tree.IsUpdateSuspended) + { + tree.SetPendingLayout(); + tree.Invalidate(); + } + } + } + + /// + /// Occurs when any image property for the cell has changed. + /// + internal void OnImageChanged() + { + if (m_SizeChanged) return; + + if (this.Parent != null) + this.Parent.OnChildNodesSizeChanged(); + else + this.SizeChanged = true; + OnDisplayChanged(); + } + + /// + /// Occurs when size of the child nodes has changed. + /// + internal void OnChildNodesSizeChanged() + { + foreach (Node node in this.Nodes) + { + node.SizeChanged = true; + node.OnChildNodesSizeChanged(); + } + } + private void OnColumnHeaderSizeChanged(object sender, EventArgs e) + { + if (this.Expanded) + this.SizeChanged = true; + } + private void SetExpanded(bool e, eTreeAction action) + { + if (e == m_Expanded) + return; + + INodeNotify notification = GetINodeNotify(); + if (notification != null) + { + AdvTreeNodeCancelEventArgs cancelArgs = new AdvTreeNodeCancelEventArgs(action, this); + if (e) + notification.OnBeforeExpand(cancelArgs); + else + notification.OnBeforeCollapse(cancelArgs); + if (cancelArgs.Cancel) + return; + } +#if TRIAL + if(NodeOperations.ColorCountExp==0) + return; +#endif + OnExpandChanging(e, action); + m_Expanded = e; + + if (notification != null) + notification.ExpandedChanged(this); + + if (notification != null) + { + AdvTreeNodeEventArgs args = new AdvTreeNodeEventArgs(action, this); + if (e) + notification.OnAfterExpand(args); + else + notification.OnAfterCollapse(args); + } + + foreach (Node node in this.Nodes) + { + node.OnParentExpandedChanged(m_Expanded); + } + + this.SizeChanged = true; + this.OnDisplayChanged(); + } + /// + /// Called before Expanded state of the node has changed. + /// + /// New Expand State + /// Action Source + protected virtual void OnExpandChanging(bool expanded, eTreeAction action) + { + + } + + internal void OnParentExpandedChanged(bool expanded) + { + foreach (Cell cell in this.Cells) + cell.OnParentExpandedChanged(expanded); + foreach (Node node in this.Nodes) + { + node.OnParentExpandedChanged(expanded); + } + } + + private AdvTree GetTreeControl() + { + Node node = this; + while (node.Parent != null) + node = node.Parent; + return node.internalTreeControl; + } + private INodeNotify GetINodeNotify() + { + AdvTree tree = this.TreeControl; + if (tree != null) return tree as INodeNotify; + return null; + } + private void ElementStyleChanged(object sender, EventArgs e) + { + this.SizeChanged = true; + this.OnDisplayChanged(); + } + /// + /// Called when visual part of the node has changed due to the changes of its properties or properties of the cells contained by node. + /// + internal virtual void OnDisplayChanged() + { + AdvTree tree = this.TreeControl; + if (tree != null && !tree.SuspendPaint) + { + if (this.SizeChanged) + { + if (!tree.IsRepositioningControls) + tree.RecalcLayout(); + else + tree.SetPendingLayout(); + } + tree.Invalidate(true); + } + } + + private void ConnectorAppearanceChanged(object sender, EventArgs e) + { + this.OnDisplayChanged(); + } + + /// + /// Called after new node has been added to Nodes collection. + /// + /// Reference to the new node. + internal void OnChildNodeInserted(Node node) + { + SizeChanged = true; + if (node.Cells.Count > 1) + node.SizeChanged = true; + } + + /// + /// Called after node has been removed from Nodes collection. + /// + /// Reference to the node that is removed. + internal void OnChildNodeRemoved(Node node) + { + SizeChanged = true; + if (node.IsSelected) + { + if (this.TreeControl != null) + this.TreeControl.SelectedNode = null; + } + } + + internal void OnVisibleChanged() + { + foreach (Cell cell in this.Cells) + { + cell.OnVisibleChanged(); + } + + foreach (Node node in this.Nodes) + { + node.OnVisibleChanged(); + } + } + + /// + /// Creates new cells based on the columns defined on either parent node or the columns in tree control. Node + /// must be parented so it can get reference to a parent tree control. + /// + public void CreateCells() + { + AdvTree tree = this.TreeControl; + if (this.Parent == null && tree == null) + throw new NullReferenceException("Node must have a parent or be added to AdvTree.Nodes collection to use this method."); + Node parent = this.Parent; + + int columnsCount = 0; + if (parent != null && parent.NodesColumns.Count > 0) + { + columnsCount = parent.NodesColumns.Count; + } + else if (tree != null && tree.Columns.Count > 0) + { + columnsCount = tree.Columns.Count; + } + + if (columnsCount == 0) return; + + for (int i = this.Cells.Count; i < columnsCount; i++) + { + this.Cells.Add(new Cell()); + } + } + + internal void OnNodesCleared() + { + this.SizeChanged = true; + } + + internal bool IsKeyboardNavigationEnabled(KeyEventArgs e) + { + return CanKeyboardNavigate(e); + } + + protected virtual bool CanKeyboardNavigate(KeyEventArgs e) + { + return true; + } + + internal void InvokeKeyboardPaste(KeyEventArgs args) + { + OnKeyboardPaste(args); + } + + protected virtual void OnKeyboardPaste(KeyEventArgs args) + { + + } + + internal void InvokeKeyboardCopy(KeyEventArgs args) + { + OnKeyboardCopy(args); + } + + protected virtual void OnKeyboardCopy(KeyEventArgs args) + { + + } + + #endregion + + #region Event Invocation + protected internal virtual void InvokeNodeMouseDown(object sender, MouseEventArgs e) + { + if (NodeMouseDown != null) + NodeMouseDown(this, e); + + foreach (Cell cell in m_Cells) + { + cell.InvokeNodeMouseDown(sender, e); + } + } + + protected internal virtual void InvokeNodeMouseUp(object sender, MouseEventArgs e) + { + if (NodeMouseUp != null) + NodeMouseUp(this, e); + + foreach (Cell cell in m_Cells) + { + cell.InvokeNodeMouseUp(sender, e); + } + } + + protected internal virtual void InvokeNodeMouseMove(object sender, MouseEventArgs e) + { + if (NodeMouseMove != null) + NodeMouseMove(this, e); + + foreach (Cell cell in m_Cells) + { + cell.InvokeNodeMouseMove(sender, e); + } + } + + /// + /// Raises the Click event on node and parent tree if available. + /// + public void RaiseClick() + { + AdvTree tree = this.TreeControl; + TreeNodeMouseEventArgs e = new TreeNodeMouseEventArgs(this, MouseButtons.None, 0, 0, 0, 0); + if (tree == null) + { + InvokeNodeClick(this, e); + } + else + { + tree.InternalInvokeNodeClick(e); + } + } + + protected internal virtual void InvokeNodeClick(object sender, EventArgs e) + { + if (NodeClick != null) + NodeClick(this, e); + + foreach (Cell cell in m_Cells) + { + cell.InvokeNodeClick(sender, e); + } + } + + protected internal virtual void InvokeNodeDoubleClick(object sender, EventArgs e) + { + OnNodeDoubleClick(e); + } + + protected virtual void OnNodeDoubleClick(EventArgs e) + { + if (NodeDoubleClick != null) + NodeDoubleClick(this, e); + } + protected internal virtual void InvokeNodeMouseEnter(object sender, EventArgs e) + { + if (NodeMouseEnter != null) + NodeMouseEnter(this, e); + } + + protected internal virtual void InvokeNodeMouseLeave(object sender, EventArgs e) + { + if (NodeMouseLeave != null) + NodeMouseLeave(this, e); + + foreach (Cell cell in m_Cells) + { + cell.InvokeNodeMouseLeave(sender, e); + } + } + + protected internal virtual void InvokeNodeMouseHover(object sender, EventArgs e) + { + if (NodeMouseHover != null) + NodeMouseHover(this, e); + + foreach (Cell cell in m_Cells) + { + if (cell.IsMouseOver) + { + cell.InvokeNodeMouseHover(sender, e); + } + } + } + + internal bool FireHoverEvent + { + get { return NodeMouseHover != null || CellsHaveHostedItemOrTooltip; } + } + + private bool CellsHaveHostedItemOrTooltip + { + get + { + foreach (Cell cell in m_Cells) + { + if (cell.HostedItem != null || !string.IsNullOrEmpty(cell.Tooltip)) return true; + } + return false; + } + } + protected internal virtual void InvokeMarkupLinkClick(Cell cell, MarkupLinkClickEventArgs args) + { + if (MarkupLinkClick != null) + MarkupLinkClick(cell, args); + AdvTree tree = this.TreeControl; + if (tree != null) + tree.InvokeMarkupLinkClick(cell, args); + } + #endregion + + #region Accessibility + /// + /// Gets the AccessibleObject assigned to the item. + /// + [System.ComponentModel.Browsable(false)] + public virtual System.Windows.Forms.AccessibleObject AccessibleObject + { + get + { + return CreateAccessibilityInstance(); + } + } + private NodeAccessibleObject _NodeAccessibleObject = null; + protected virtual System.Windows.Forms.AccessibleObject CreateAccessibilityInstance() + { + if (_NodeAccessibleObject == null) + _NodeAccessibleObject = new NodeAccessibleObject(this); + return _NodeAccessibleObject; + } + + private string _AccessibleDefaultActionDescription = ""; + /// + /// Gets or sets the default action description of the control for use by accessibility client applications. + /// + [Browsable(true), Category("Accessibility"),DefaultValue(""),Description("Gets or sets the default action description of the control for use by accessibility client applications.")] + public virtual string AccessibleDefaultActionDescription + { + get { return _AccessibleDefaultActionDescription; } + set { _AccessibleDefaultActionDescription = value; } + } + + private string _AccessibleDescription = ""; + /// + /// Gets or sets the description of the control used by accessibility client applications. + /// + [Browsable(true), Category("Accessibility"),DefaultValue(""),Description("Gets or sets the description of the control used by accessibility client applications.")] + public virtual string AccessibleDescription + { + get { return _AccessibleDescription; } + set + { + if (_AccessibleDescription != value) + { + _AccessibleDescription = value; + GenerateAccessibilityEvent(System.Windows.Forms.AccessibleEvents.DescriptionChange); + } + } + } + + private string _AccessibleName = ""; + /// + /// Gets or sets the name of the control used by accessibility client applications. + /// + [Browsable(true), Category("Accessibility"),Description("Gets or sets the name of the control used by accessibility client applications."),DefaultValue("")] + public virtual string AccessibleName + { + get { return _AccessibleName; } + set + { + if (_AccessibleName != value) + { + _AccessibleName = value; + GenerateAccessibilityEvent(System.Windows.Forms.AccessibleEvents.NameChange); + } + } + } + + private System.Windows.Forms.AccessibleRole _AccessibleRole = System.Windows.Forms.AccessibleRole.OutlineItem; + /// + /// Gets or sets the accessible role of the item. + /// + [Browsable(true), Category("Accessibility"),Description("Gets or sets the accessible role of the item."),DefaultValue(System.Windows.Forms.AccessibleRole.OutlineItem)] + public virtual System.Windows.Forms.AccessibleRole AccessibleRole + { + get { return _AccessibleRole; } + set { _AccessibleRole = value; } + } + + private bool _IsAccessible = true; + /// + /// Gets or sets a value indicating whether the node is visible to accessibility applications. + /// + [Browsable(false), DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual bool IsAccessible + { + get { return _IsAccessible; } + set { _IsAccessible = value; } + } + + internal void GenerateAccessibilityEvent(System.Windows.Forms.AccessibleEvents e) + { + AdvTree tree = this.TreeControl; + if (tree == null) return; + + AdvTree.AdvTreeAccessibleObject a = tree.AccessibilityObject as AdvTree.AdvTreeAccessibleObject; + if (a != null) + a.GenerateEvent(this, e); + } + #endregion + + #region IComparable Members + /// + /// Provides implementation for IComparable interface. This is used for sorting and it compares the Text property on nodes. + /// + /// + /// + public int CompareTo(object obj) + { + if (obj is Node) + { + Node node = obj as Node; + return Utilities.CompareAlphaNumeric(this.Text, node.Text); + } + return -1; + } + + #endregion + } + + #region ItemAccessibleObject + public class NodeAccessibleObject : System.Windows.Forms.AccessibleObject + { + private Node _Owner = null; + public NodeAccessibleObject(Node owner) + { + _Owner = owner; + } + + internal Node Owner + { + get { return _Owner; } + } + + public override string Name + { + get + { + if (_Owner == null) + return ""; + + if (_Owner.AccessibleName != "") + return _Owner.AccessibleName; + + return _Owner.Text.Replace("&", ""); + } + set + { + _Owner.AccessibleName = value; + } + } + + public override string Description + { + get + { + if (_Owner == null) + return ""; + if (_Owner.AccessibleDescription != "") + return _Owner.AccessibleDescription; + return Name + " Tree Node"; + } + } + + public override System.Windows.Forms.AccessibleRole Role + { + get + { + if (_Owner == null || !_Owner.IsAccessible) + return System.Windows.Forms.AccessibleRole.None; + + if (_Owner.AccessibleRole != System.Windows.Forms.AccessibleRole.Default) + return _Owner.AccessibleRole; + return AccessibleRole.OutlineItem; + } + } + + public override System.Windows.Forms.AccessibleStates State + { + get + { + if (_Owner == null) + return System.Windows.Forms.AccessibleStates.Unavailable; + System.Windows.Forms.AccessibleStates state = 0; + + if (!_Owner.IsAccessible) + return System.Windows.Forms.AccessibleStates.Unavailable; + + if (!_Owner.Visible) + state |= System.Windows.Forms.AccessibleStates.Invisible; + else + { + if (_Owner.IsSelected) + state = AccessibleStates.Selected; + if (_Owner.Expanded) + state |= System.Windows.Forms.AccessibleStates.Expanded; + else + state |= System.Windows.Forms.AccessibleStates.Collapsed; + } + return state; + } + } + + public override System.Windows.Forms.AccessibleObject Parent + { + get + { + if (_Owner == null) + return null; + if (_Owner.Parent != null) + { + return _Owner.Parent.AccessibleObject; + } + + System.Windows.Forms.Control control = _Owner.TreeControl as System.Windows.Forms.Control; + if (control != null) + return control.AccessibilityObject; + return null; + } + } + + public override System.Drawing.Rectangle Bounds + { + get + { + if (_Owner == null) + return System.Drawing.Rectangle.Empty; + System.Windows.Forms.Control objCtrl = _Owner.TreeControl as System.Windows.Forms.Control; + if (objCtrl != null) + return objCtrl.RectangleToScreen(_Owner.Bounds); + else + return _Owner.Bounds; + } + } + + public override int GetChildCount() + { + if (_Owner == null || !_Owner.HasChildNodes) + return 0; + return _Owner.Nodes.Count; + } + + public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) + { + if (_Owner == null) + return null; + return _Owner.Nodes[iIndex].AccessibleObject; + } + + public override string DefaultAction + { + get + { + if (_Owner.AccessibleDefaultActionDescription != "") + return _Owner.AccessibleDefaultActionDescription; + if (_Owner.Expanded) + return "Collapse"; + else if (_Owner.Nodes.Count > 0 || _Owner.ExpandVisibility == eNodeExpandVisibility.Visible) + return "Expand"; + return "Press"; + } + } + + public override void DoDefaultAction() + { + if (_Owner == null) + return; + _Owner.Toggle(); + + base.DoDefaultAction(); + } + + public override string KeyboardShortcut + { + get + { + return ""; // _Owner.ShortcutString; + } + } + + public override System.Windows.Forms.AccessibleObject GetSelected() + { + if (_Owner == null) + return base.GetSelected(); + if (_Owner.IsSelected) + return _Owner.AccessibleObject; + + return base.GetSelected(); + } + + public override System.Windows.Forms.AccessibleObject HitTest(int x, int y) + { + if (_Owner == null) + return base.HitTest(x, y); + + Point screen = new Point(x, y); + AdvTree tree = _Owner.TreeControl; + if (tree == null) return base.HitTest(x, y); + + Point p = tree.PointToClient(screen); + Node node = tree.GetNodeAt(p); + if (node != null) return node.AccessibleObject; + + return base.HitTest(x, y); + } + + public override System.Windows.Forms.AccessibleObject Navigate(System.Windows.Forms.AccessibleNavigation navDir) + { + if (_Owner == null) + return base.Navigate(navDir); + + Node item = null; + + if (navDir == System.Windows.Forms.AccessibleNavigation.Down || navDir == System.Windows.Forms.AccessibleNavigation.Right + || navDir == System.Windows.Forms.AccessibleNavigation.Next) + { + item = NodeOperations.GetNextVisibleNode(_Owner); + } + else if (navDir == System.Windows.Forms.AccessibleNavigation.FirstChild) + { + item = GetFirstVisible(_Owner.Nodes, 0); + } + else if (navDir == System.Windows.Forms.AccessibleNavigation.LastChild) + { + item = GetFirstVisibleReverse(_Owner.Nodes, _Owner.Nodes.Count - 1); + } + else if (navDir == System.Windows.Forms.AccessibleNavigation.Up || navDir == System.Windows.Forms.AccessibleNavigation.Left + || navDir == System.Windows.Forms.AccessibleNavigation.Previous) + { + item = NodeOperations.GetPreviousVisibleNode(_Owner); + } + + if (item != null) + return item.AccessibleObject; + + return base.Navigate(navDir); + } + + private Node GetFirstVisible(NodeCollection col, int startIndex) + { + int count = col.Count; + + for (int i = startIndex; i < count; i++) + { + if (col[i].Visible) + return col[i]; + } + return null; + } + + private Node GetFirstVisibleReverse(NodeCollection col, int startIndex) + { + for (int i = startIndex; i >= 0; i--) + { + if (col[i].Visible) + return col[i]; + } + return null; + } + + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/NodeCollection.cs b/PROMS/DotNetBar Source Code/AdvTree/NodeCollection.cs new file mode 100644 index 00000000..05a8957d --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/NodeCollection.cs @@ -0,0 +1,502 @@ +using System; +using System.Collections; +using System.ComponentModel; + +namespace DevComponents.AdvTree +{ + /// + /// Represents collection for Node objects. + /// + public class NodeCollection:CollectionBase + { + #region Private Variables + private Node m_ParentNode=null; + private AdvTree m_TreeControl=null; + private eTreeAction m_SourceAction=eTreeAction.Code; + private bool _PassiveCollection = false; + #endregion + + #region Internal Implementation + public NodeCollection() + { + } + internal eTreeAction SourceAction + { + get + { + return m_SourceAction; + } + set + { + m_SourceAction = value; + } + } + internal bool PassiveCollection + { + get { return _PassiveCollection; } + set + { + _PassiveCollection = value; + } + } + /// + /// Gets or sets the node this collection is associated with. + /// + [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Node ParentNode + { + get {return m_ParentNode;} + } + /// + /// Sets the node collection belongs to. + /// + /// Node that is parent of this collection. + internal void SetParentNode(Node parent) + { + m_ParentNode=parent; + } + + internal AdvTree TreeControl + { + get {return m_TreeControl;} + set {m_TreeControl=value;} + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public virtual int Add(Node node) + { + return Add(node, eTreeAction.Code); + } + + /// + /// Adds new object to the collection and provides information about the source of the command + /// + /// Node to add + /// Source action + /// + public virtual int Add(Node node, eTreeAction action) + { + m_SourceAction = action; + return List.Add(node); + } + + /// + /// Adds an array of objects to the collection. + /// + /// Array of Node objects. + public virtual void AddRange(Node[] nodes) + { + foreach(Node node in nodes) + this.Add(node); + } + + /// + /// Returns reference to the object in collection based on it's index. + /// + public Node this[int index] + { + get {return (Node)(List[index]);} + set {List[index] = value;} + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public virtual void Insert(int index, Node value) + { + List.Insert(index, value); + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + /// Action that is causing the event + public virtual void Insert(int index, Node value, eTreeAction action) + { + m_SourceAction = action; + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(Node value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(Node value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + public virtual void Remove(Node value) + { + List.Remove(value); + } + + /// + /// Removes specified object from the collection and provides information about source of the command + /// + /// Node to remove + /// Source action + public virtual void Remove(Node node, eTreeAction action) + { + m_SourceAction = action; + List.Remove(node); + } + + protected override void OnRemove(int index, object value) + { + if (!_PassiveCollection) + { + AdvTree 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); + NodeRemoveComplete(index, value); + } + + private void NodeRemoveComplete(int index, object value) + { + if (!_PassiveCollection) + { + Node node = value as Node; + node.SetParent(null); + node.internalTreeControl = null; + if (m_ParentNode != null) m_ParentNode.OnChildNodeRemoved(node); + + AdvTree 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 OnSetComplete(int index, object oldValue, object newValue) + { + base.OnSetComplete(index, oldValue, newValue); + + NodeRemoveComplete(index, oldValue); + NodeInsertComplete(newValue); + } + + protected override void OnSet(int index, object oldValue, object newValue) + { + if (!_PassiveCollection) + { + AdvTree tree = GetTreeControl(); + + if (tree != null) + tree.InvokeBeforeNodeRemove(m_SourceAction, oldValue as Node, m_ParentNode); + + if (tree != null) + tree.InvokeBeforeNodeInsert(m_SourceAction, newValue as Node, m_ParentNode); + } + base.OnSet(index, oldValue, newValue); + } + + protected override void OnInsert(int index, object value) + { + if (!_PassiveCollection) + { + AdvTree 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); + NodeInsertComplete(value); + } + + private void NodeInsertComplete(object value) + { + if (!_PassiveCollection) + { + Node node = value as Node; + if (m_ParentNode != null) + { + if (node.Parent != null && node.Parent != m_ParentNode) + node.Remove(); + node.SetParent(m_ParentNode); + if (m_ParentNode.NodesColumns.IsSorted) + { + AdvTree parentTree = m_TreeControl; + if (parentTree == null) parentTree = m_ParentNode.TreeControl; + if (parentTree != null) + parentTree.PushSortRequest(m_ParentNode); + } + } + else + { + if (node.Parent != null) + node.Remove(); + else + node.InvokeOnParentChanged(); + if (m_TreeControl != null && m_TreeControl.Columns.IsSorted) + { + m_TreeControl.PushSortRequest(); + } + } + node.internalTreeControl = m_TreeControl; + + if (m_ParentNode != null) + m_ParentNode.OnChildNodeInserted(node); + else + node.SizeChanged = true; + + AdvTree tree = GetTreeControl(); + if (tree != null) + tree.InvokeAfterNodeInsert(m_SourceAction, value as Node, m_ParentNode); + } + m_SourceAction = eTreeAction.Code; + } + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(Node[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the Node array. + /// + /// Array to copy to. + [EditorBrowsable(EditorBrowsableState.Never)] + public void CopyTo(Node[] array) + { + List.CopyTo(array,0); + } + + protected override void OnClear() + { + if (!_PassiveCollection) + { + 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(); + + AdvTree tree = GetTreeControl(); + if (tree != null) + { + tree.ValidateSelectedNode(); + } + + base.OnClearComplete(); + } + + private AdvTree GetTreeControl() + { + if(m_TreeControl!=null) + return m_TreeControl; + if(m_ParentNode!=null) + return m_ParentNode.TreeControl; + return null; + } + + /// + /// Sorts the elements in the entire collection using the IComparable implementation of each element. + /// + public virtual void Sort() + { + this.Sort(0, this.Count, Comparer.Default); + } + /// + /// Sorts the elements in the entire collection using the specified comparer. + /// + /// The IComparer implementation to use when comparing elements.-or- null to use the IComparable implementation of each element. + public virtual void Sort(IComparer comparer) + { + this.Sort(0, this.Count, comparer); + } + /// + /// Sorts the elements in a range of elements in collection using the specified comparer. + /// + /// + /// + /// + public virtual void Sort(int index, int count, IComparer comparer) + { + AdvTree tree = GetTreeControl(); + if (!_PassiveCollection && tree != null) + tree.BeginUpdate(); + + this.InnerList.Sort(index, count, comparer); + + if (tree != null && tree.DeepSort) + { + foreach (Node node in this.InnerList) + { + node.Nodes.Sort(0, node.Nodes.Count, comparer); + } + } + + if (!_PassiveCollection && tree != null) + tree.EndUpdate(); + } + + /// + /// Finds the tree nodes with specified key, optionally searching sub-nodes. + /// + /// The name of the tree node to search for. + /// true to search child nodes of tree nodes; otherwise, false. + /// An array of Node objects whose Name property matches the specified key. + public Node[] Find(string name, bool searchAllChildren) + { + ArrayList list = new ArrayList(); + NodeOperations.FindNodesByName(this, name, searchAllChildren, list); + Node[] nodes = new Node[list.Count]; + if (list.Count > 0) list.CopyTo(nodes); + return nodes; + } + + #endregion + } + + #region Node Comparer + public class NodeComparer : IComparer + { + private int _ColumnIndex = 0; + /// + /// Creates new instance of NodeComparer class. You can use NodeComparer to sort the nodes by specific column/cell by calling + /// NodeCollection.Sort method and pass new instance of NodeComparer class. + /// + public NodeComparer() + { + } + /// + /// Creates new instance of NodeComparer class. You can use NodeComparer to sort the nodes by specific column/cell by calling + /// NodeCollection.Sort method and pass new instance of NodeComparer class. + /// + /// Column/Cell index to use for sorting. + public NodeComparer(int columnIndex) + { + _ColumnIndex = columnIndex; + } + + /// + /// Gets or sets the Column/Cell index that is used for sorting. + /// + public int ColumnIndex + { + get { return _ColumnIndex; } + set { _ColumnIndex = value; } + } + #region IComparer Members + + public virtual int Compare(object x, object y) + { + Node nx = (Node)x; + Node ny = (Node)y; + if (_ColumnIndex < nx.Cells.Count && _ColumnIndex < ny.Cells.Count) + { + if(AdvTreeSettings.UseSortAlphaComparer) + return Utilities.CompareAlpha(nx.Cells[_ColumnIndex].Text, ny.Cells[_ColumnIndex].Text); + else + return Utilities.CompareAlphaNumeric(nx.Cells[_ColumnIndex].Text, ny.Cells[_ColumnIndex].Text); + } + return 0; + } + + #endregion + } + /// + /// Reverse sort nodes. + /// + public class NodeComparerReverse : NodeComparer + { + /// + /// Creates new instance of NodeComparer class. You can use NodeComparer to sort the nodes by specific column/cell by calling + /// NodeCollection.Sort method and pass new instance of NodeComparer class. + /// + /// Column/Cell index to use for sorting. + public NodeComparerReverse(int columnIndex) : base(columnIndex) + { + } + + public override int Compare(object x, object y) + { + return base.Compare(y, x); + } + } + /// + /// Sort by flat node index. + /// + public class NodeFlatIndexComparer : IComparer + { + private AdvTree _TreeControl = null; + /// + /// Creates new instance of NodeComparer class. You can use NodeComparer to sort the nodes by specific column/cell by calling + /// NodeCollection.Sort method and pass new instance of NodeComparer class. + /// + public NodeFlatIndexComparer(AdvTree treeControl) + { + _TreeControl = treeControl; + } + #region IComparer Members + + public virtual int Compare(object x, object y) + { + Node nx = (Node)x; + Node ny = (Node)y; + + if (_TreeControl.GetNodeFlatIndex(nx) < _TreeControl.GetNodeFlatIndex(ny)) + return -1; + else + return 1; + } + + #endregion + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/NodeConnector.cs b/PROMS/DotNetBar Source Code/AdvTree/NodeConnector.cs new file mode 100644 index 00000000..2ae2268e --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/NodeConnector.cs @@ -0,0 +1,215 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Drawing.Drawing2D; + +namespace DevComponents.AdvTree +{ + /// + /// Represents node connector. Node connector is the line that is drawn to indicate connection between child and parent node. + /// + [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.Line; + //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 + /// + /// Occurs when appearance of the connector has changed as result of changed settings on the connector. + /// + public event EventHandler AppearanceChanged; + #endregion + + #region Public Interface + /// + /// Default Constructor. + /// + public NodeConnector() + { + } + + /// + /// Creates new instance of the object with specified parameters. + /// + /// Connector line width. + /// Connector type. + public NodeConnector(int lineWidth, eNodeConnectorType type) + { + this.LineWidth=lineWidth; + this.ConnectorType=type; + } + + /// + /// Gets or sets the connector line width. + /// + [Browsable(true),DefaultValue(1),Category("Appearance"),Description("Indicates connector line width.")] + public int LineWidth + { + get {return m_LineWidth;} + set + { + m_LineWidth=value; + OnAppearanceChanged(); + } + } + + /// + /// Gets or sets the color of the connector line. + /// + [Browsable(true),Category("Appearance"),Description("Indicates color of the connector line.")] + public Color LineColor + { + get {return m_LineColor;} + set + { + m_LineColor=value; + OnAppearanceChanged(); + } + } + + /// + /// Returns true if editor should serialize LineColor property. + /// + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLineColor() + { + return m_LineColor!=SystemColors.Highlight; + } + + /// + /// Gets or sets the type of the connector. + /// + /// + /// See eNodeConnectorType enum for list of + /// available connectors. + /// + /// eNodeConnectorType Enumeration + [Browsable(false),DefaultValue(eNodeConnectorType.Line),Category("Appearance"),Description("Indicates visual type of the connector.")] + public eNodeConnectorType ConnectorType + { + get {return m_ConnectorType;} + set + { + m_ConnectorType=value; + OnAppearanceChanged(); + } + } + + private DashStyle _DashStyle = DashStyle.Dot; + /// + /// Gets or sets the DashStyle for the connector line. Default value is DashStyle.Dot. + /// + [DefaultValue(DashStyle.Dot), Category("Appearance"), Description("Indicates DashStyle for the connector line")] + public DashStyle DashStyle + { + get { return _DashStyle; } + set { _DashStyle = value; } + } + + ///// + ///// 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. + ///// + ///// + ///// 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. + ///// + //[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(); + // } + //} + + ///// + ///// 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. + ///// + //[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(); + // } + //} + + ///// + ///// Gets or sets the size of the end cap. + ///// + //[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(); + // } + //} + + ///// + ///// Returns true if EndCapSize property should be serialized by editor. + ///// + ///// + //[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 + +// /// +// /// 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. +// /// +// [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;} +// } +// +// /// +// /// Gets or sets the size of the start cap. +// /// +// [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;} +// } +// +// /// +// /// Returns true if StartCapSize property should be serialized by editor. +// /// +// /// +// [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] +// public bool ShouldSerializeStartCapSize() +// { +// return (m_StartCapSize.Width!=5 || m_StartCapSize.Height!=5); +// } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/NodeOperations.cs b/PROMS/DotNetBar Source Code/AdvTree/NodeOperations.cs new file mode 100644 index 00000000..13e6cf47 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/NodeOperations.cs @@ -0,0 +1,1700 @@ +using System; +using System.Drawing; +using System.Text; +using DevComponents.AdvTree.Display; +using System.Collections; + +namespace DevComponents.AdvTree +{ + /// + /// Represents node operations. + /// + internal class NodeOperations + { + /// + /// Returns full path to the given node. + /// + /// Node to return path to. + /// Full path to the node. + 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, node.Text + pathSeparator); + node=node.Parent; + } + + return sb.ToString(); + } + + /// + /// 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). + /// + /// Reference node. + /// Last node if found or null if there is no last node. + public static Node GetLastNode(Node node) + { + if(node.Nodes.Count>0) + { + return node.Nodes[node.Nodes.Count-1]; + } + return null; + } + + /// + /// Returns last rendered node on screen. + /// + /// Tree control. + /// Last rendered node or null + public static Node GetLastDisplayedNode(AdvTree tree) + { + Rectangle r = tree.NodeLayout.ClientArea; + 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.IntersectsWith(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 (nodeRect.Bottom > r.Bottom) + break; + else if (r.IntersectsWith(nodeRect)) + lastNode = node; + } + } + + return lastNode; + } + + /// + /// Returns first rendered node on screen. + /// + /// Tree control. + /// Last rendered node or null + public static Node GetFirstDisplayedNode(AdvTree tree) + { + Rectangle r = tree.GetInnerRectangle(); + r.Y += tree.ColumnHeaderHeight; + r.Height -= tree.ColumnHeaderHeight; + + 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.IntersectsWith(node.Bounds)) + lastNode = node; + while (node != null) + { + node = NodeOperations.GetPreviousVisibleNode(node); + if (node != null && node.Selectable) + { + Rectangle nodeRect = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, node, scrollPos); + if (r.IntersectsWith(nodeRect)) + lastNode = node; + else if (nodeRect.Y < r.Y) + break; + } + } + + return lastNode; + } + + /// + /// Gets first visible node. + /// + /// Reference to tree. + /// Last visible node found or null + public static Node GetFirstVisibleNode(AdvTree 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); + } + + /// + /// Gets last visible node in tree control. + /// + /// Reference to tree. + /// Last visible node found or null + public static Node GetLastVisibleNode(AdvTree tree) + { + if (tree.Nodes.Count == 0) return null; + + Node node = tree.DisplayRootNode == null ? tree.Nodes[tree.Nodes.Count - 1] : tree.DisplayRootNode; + if (node.Visible) + { + if (node.Nodes.Count > 0 && node.Expanded) + { + Node child = GetLastVisibleChildNode(node); + if (child != null) + { + while (child.Nodes.Count > 0 && child.Expanded) + { + Node child1 = GetLastVisibleChildNode(child); + if (child1 == null) return child; + child = child1; + } + return child; + } + } + return node; + } + return GetPreviousVisibleNode(node); + } + + /// + /// Gets last visible top-level node in tree control. + /// + /// Reference to tree. + /// Last visible node found or null + public static Node GetLastVisibleTopLevelNode(AdvTree tree) + { + if (tree.Nodes.Count == 0) return null; + + NodeCollection col = tree.Nodes; + if (tree.DisplayRootNode != null) col = tree.DisplayRootNode.Nodes; + + for (int i = col.Count - 1; i >= 0; i--) + { + if (col[i].Visible) + return col[i]; + } + + return null; + } + + /// + /// 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). + /// + /// Reference node. + /// Node object or null if node cannot be found. + 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 + /// Returns next visible sibling tree node. + /// + /// Reference node + /// Node object or null if next visible node cannot be found + 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; + } + + /// + /// 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). + /// + /// Reference node. + /// Node object or null if node cannot be found. + 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; + } + + /// + /// 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). + /// + /// Reference node. + /// Node object or null if node cannot be found. + 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; + } + + /// + /// 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. + /// + /// + /// + 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; + } + + /// + /// 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. + /// + /// + /// + public static bool GetIsNodeDisplayed(Node node) + { + if(!node.Visible || !GetIsNodeVisible(node)) + return false; + AdvTree tree=node.TreeControl; + if(tree!=null) + { + Rectangle r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds,node,tree.NodeDisplay.Offset); + return tree.ClientRectangle.IntersectsWith(r); + } + return false; + } + + /// + /// 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. + /// + /// Reference node. + /// Zero based index or -1 if node is not in collection. + public static int GetNodeIndex(Node node) + { + if (node.Parent == null) + { + AdvTree tree = node.TreeControl; + if (tree != null) + return tree.Nodes.IndexOf(node); + return -1; + } + return node.Parent.Nodes.IndexOf(node); + } + + /// + /// 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). + /// + /// Reference node. + /// Node object or null if node cannot be found. + 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; + } + + ///// + ///// 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). + ///// + ///// Reference node. + ///// Node object or null if node cannot be found. + //public static Node GetPreviousDisplayedNode(Node node) + //{ + // Node referenceNode = node; + // do + // { + // referenceNode = GetPreviousVisibleNode(referenceNode); + // if (referenceNode != null && referenceNode.IsVisible) break; + // } while (referenceNode != null); + // return referenceNode; + //} + + /// + /// 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). + /// + /// Reference node. + /// Node object or null if node cannot be found. + 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; + } + + /// + /// 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). + /// + /// Reference node. + /// Node object or null if node cannot be found. + 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; + } + + /// + /// Returns true if node passed is considered root node for display purposes. + /// + /// Reference to the tree control. + /// Node to test. + /// true if node is root node for display purposes otherwise false. + public static bool IsRootNode(AdvTree tree, Node node) + { + if(node.Parent==null || node==tree.DisplayRootNode) + return true; + return false; + } + + /// + /// Ensures that the cell is visible, expanding nodes and scrolling the control as necessary. + /// + /// Cell to be made visible. + public static void EnsureVisible(Cell cell) + { + Node parentNode = cell.Parent; + if (parentNode == null) return; + AdvTree tree = parentNode.TreeControl; + if (tree == null) return; + + EnsureVisible(parentNode, false); + + Rectangle r = NodeDisplay.GetCellRectangle(eCellRectanglePart.CellBounds, cell, tree.NodeDisplay.Offset); + + if (tree != null && tree.AutoScroll) + { + if (tree.Zoom != 1) + { + r = tree.GetScreenRectangle(r); + } + Rectangle treeClientRectangle = tree.GetInnerRectangle(); + if (tree.VScrollBar != null) treeClientRectangle.Width -= tree.VScrollBar.Width; + if (tree.HScrollBar != null) treeClientRectangle.Height -= tree.HScrollBar.Height; + + if (!treeClientRectangle.Contains(r)) + { + Point p = tree.NodeDisplay.Offset; + p.Y = tree.AutoScrollPosition.Y; + if (r.X < treeClientRectangle.X) + p.X -= r.X; + else if (r.X > treeClientRectangle.Right) + p.X += (r.Right - treeClientRectangle.Right); + // Scroll it to show the cell + if (!tree.IsLayoutPending) + tree.AutoScrollPosition = p; + } + } + } + + /// + /// Ensures that the node is visible, expanding nodes and scrolling the control as necessary. + /// + /// Node to be made visible. + public static void EnsureVisible(Node reference, bool scrollHorizontally) + { + EnsureVisible(reference, scrollHorizontally, eEnsureVisibleOption.Middle); + } + + /// + /// Ensures that the node is visible, expanding nodes and scrolling the control as necessary. + /// + /// Node to be made visible. + public static void EnsureVisible(Node reference, bool scrollHorizontally, eEnsureVisibleOption scrollPositionOption) + { + // First expand all parents + AdvTree tree = reference.TreeControl; + if (tree == null || tree.IsUpdateSuspended) return; + + 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.IsLayoutPending) + tree.RecalcLayoutInternal(); + + // Adjust for tree never being displayed but it has been scrolled + Point offset = tree.NodeDisplay.Offset; + if (offset.IsEmpty && tree.AutoScroll && !tree.AutoScrollPosition.IsEmpty) + offset = tree.GetAutoScrollPositionOffset(); + + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, reference, offset); + if (tree != null && tree.AutoScroll) + { + if (tree.Zoom != 1) + { + r = tree.GetScreenRectangle(r); + } + Rectangle treeClientRectangle = tree.GetInnerRectangle(); + if (tree.VScrollBar != null) treeClientRectangle.Width -= tree.VScrollBar.Width; + if (tree.HScrollBar != null) treeClientRectangle.Height -= tree.HScrollBar.Height; + int treeColumnHeaderHeight = tree.ColumnHeaderHeight; + treeClientRectangle.Y += treeColumnHeaderHeight; + treeClientRectangle.Height -= treeColumnHeaderHeight; + + if (!treeClientRectangle.Contains(r)) + { + Point p = tree.AutoScrollPosition; // tree.NodeDisplay.Offset; + if (scrollHorizontally) + { + /*if (r.Right > treeClientRectangle.Right) + p.X -= r.Right - treeClientRectangle.Right; + else*/ + if (r.X < treeClientRectangle.X) + p.X -= r.X; + if (p.X > 0) p.X = -p.X; + if (p.X > -10 && p.X < 0 || p.X < 11 && p.X > 0) p.X = 0; // Snap to left + } + if (r.Height > treeClientRectangle.Height * .8) + { + p.Y = -Math.Max(0, (r.Y - 4)); + } + else if (r.Bottom > treeClientRectangle.Bottom) + { + if (scrollPositionOption == eEnsureVisibleOption.Bottom) + { + p.Y -= r.Bottom - treeClientRectangle.Bottom + r.Height; + } + else if (scrollPositionOption == eEnsureVisibleOption.Middle) + { + p.Y -= r.Bottom - (treeClientRectangle.Bottom - treeClientRectangle.Height / 2) + r.Height / 2; + } + else if (scrollPositionOption == eEnsureVisibleOption.Top) + { + p.Y -= r.Top - (treeClientRectangle.Bottom - treeClientRectangle.Height); + } + } + else if (r.Y < treeClientRectangle.Y) + { + if (scrollPositionOption == eEnsureVisibleOption.Top) + { + p.Y -= (r.Y - treeColumnHeaderHeight); + } + else if (scrollPositionOption == eEnsureVisibleOption.Middle) + { + p.Y -= r.Y - (treeColumnHeaderHeight + treeClientRectangle.Height/2 + r.Height/2); + } + else if (scrollPositionOption == eEnsureVisibleOption.Bottom) + { + p.Y -= (r.Y - (treeColumnHeaderHeight - treeClientRectangle.Height + r.Height)); + } + } + if (p.Y > -10 && p.Y < 0 || /*p.Y < 11 &&*/ p.Y > 0) p.Y = 0; // Snap to top + // Scroll it to show the node + if (!tree.IsLayoutPending) + tree.AutoScrollPosition = p; + } + } + } + finally + { + if (tree != null) + tree.SuspendPaint = false; + } + } + + /// + /// Returns number of visible child nodes for given node. + /// + /// Reference node. + /// Number of visible child nodes. + 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; + } + + /// + /// Returns true if node has at least single visible child node. + /// + /// Reference node. + /// True if at least single child node is visible otherwise false. + public static bool GetAnyVisibleNodes(Node node) + { + if (!node.HasChildNodes) + return false; + foreach(Node n in node.Nodes) + { + if(n.Visible) + return true; + } + return false; + } + + /// + /// Retrieves the tree node that is at the specified location. + /// + /// The Node at the specified point, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// The Point to evaluate and retrieve the node from. + /// Tree control to find node at. + public static NodeHitTestInfo GetNodeAt(AdvTree tree, Point p) + { + return GetNodeAt(tree,p.X,p.Y); + } + + /// + /// Retrieves the tree node that is at the specified location. + /// + /// The TreeNode at the specified location, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// The X position to evaluate and retrieve the node from. + /// The Y position to evaluate and retrieve the node from. + /// Tree control to find node at. + public static NodeHitTestInfo GetNodeAt(AdvTree tree, int x, int y) + { + return GetNodeAt(tree, x, y, false); + } + + /// + /// Retrieves the tree node that is at the specified location. + /// + /// The TreeNode at the specified location, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// Tree control to find node at. + /// The X position to evaluate and retrieve the node from. + /// The Y position to evaluate and retrieve the node from. + /// Enumerates rendered nodes only. + public static NodeHitTestInfo GetNodeAt(AdvTree tree, int x, int y, bool paintedOnly) + { + return GetNodeAt(tree, x, y, paintedOnly, false); + } + + /// + /// Retrieves the tree node that is at the specified location. + /// + /// The TreeNode at the specified location, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// Tree control to find node at. + /// The X position to evaluate and retrieve the node from. + /// The Y position to evaluate and retrieve the node from. + /// Enumerates rendered nodes only. + public static NodeHitTestInfo GetNodeAt(AdvTree tree, int x, int y, bool paintedOnly, bool isUserInterfaceHitTest) + { + NodeHitTestInfo info = new NodeHitTestInfo(); + if (tree.Nodes.Count == 0 || !tree.DisplayRectangle.Contains(x, y) && tree.Zoom == 1) + return info; + + Node node=tree.Nodes[0]; + Node retNode=null; + + bool displayRootSet = false; + if (tree.DisplayRootNode != null) + { + node = tree.DisplayRootNode; + displayRootSet = true; + } + + Point displayOffset = tree.NodeDisplay.Offset; + + // Enumerate painted nodes first + if(tree.DisplayRectangle.Contains(x, y)) + { + ArrayList paintedNodes = tree.NodeDisplay.PaintedNodes; + foreach (Node paintedNode in paintedNodes) + { + if (!paintedNode.IsDisplayed) continue; + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, paintedNode, displayOffset); + if (r.Contains(x, y)) + { + info.NodeAt = paintedNode; + return info; + } + else if (NodeDisplay.HasColumnsVisible(paintedNode)) + { + Rectangle headerBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ColumnsBounds, paintedNode, displayOffset); + if (headerBounds.Contains(x, y)) + { + info.ColumnsAt = paintedNode.NodesColumns; + return info; + } + } + } + } + if (paintedOnly) return info; + + while (node != null) + { + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, node, displayOffset); + if (r.Contains(x, y)) + { + retNode = node; + break; + } + else if (NodeDisplay.HasColumnsVisible(node)) + { + Rectangle headerBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ColumnsBounds, node, displayOffset); + if (headerBounds.Contains(x, y)) + { + info.ColumnsAt = node.NodesColumns; + return info; + } + } + if (r.Y > y) break; + + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ChildNodeBounds, node, displayOffset); + if (!r.Contains(x, y)) + node = GetNextVisibleSibling(node); + else + node = node.NextVisibleNode; + + if (displayRootSet && !IsChildNode(tree.DisplayRootNode, node)) break; + } + + info.NodeAt = retNode; + return info; + } + + /// + /// Retrieves the tree node that is at the specified vertical location. + /// + /// The TreeNode at the specified location, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// The Y position to evaluate and retrieve the node from. + /// Tree control to find node at. + public static NodeHitTestInfo GetNodeAt(AdvTree tree, int y) + { + return GetNodeAt(tree, y, false); + } + + /// + /// Retrieves the tree node that is at the specified vertical location. + /// + /// The TreeNode at the specified location, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// The Y position to evaluate and retrieve the node from. + /// Tree control to find node at. + /// Enumerates rendered nodes only. + public static NodeHitTestInfo GetNodeAt(AdvTree tree, int y, bool paintedOnly) + { + return GetNodeAt(tree, y, paintedOnly, false); + } + + /// + /// Retrieves the tree node that is at the specified vertical location. + /// + /// The TreeNode at the specified location, in tree view coordinates. + /// + /// You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the + /// MouseDown event as the x and y parameters. + /// + /// The Y position to evaluate and retrieve the node from. + /// Tree control to find node at. + /// Enumerates rendered nodes only. + public static NodeHitTestInfo GetNodeAt(AdvTree tree, int y, bool paintedOnly, bool isUserInterfaceHitTest) + { + NodeHitTestInfo info = new NodeHitTestInfo(); + if (tree.Nodes.Count == 0 || !tree.DisplayRectangle.Contains(1, y) && tree.Zoom == 1) + return info; + Point displayOffset = tree.NodeDisplay.Offset; + + // Enumerate painted node first + if (tree.DisplayRectangle.Contains(1, y)) + { + ArrayList paintedNodes = tree.NodeDisplay.PaintedNodes; + foreach (Node paintedNode in paintedNodes) + { + if (!paintedNode.IsDisplayed && !(paintedNode.Expanded && paintedNode.HasColumns)) continue; + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, paintedNode, displayOffset); + if (y >= r.Y && y <= r.Bottom) + { + info.NodeAt = paintedNode; + return info; + } + else if(NodeDisplay.HasColumnsVisible(paintedNode)) + { + Rectangle headerBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ColumnsBounds, paintedNode, displayOffset); + if (y >= headerBounds.Y && y <= headerBounds.Bottom) + { + info.ColumnsAt = paintedNode.NodesColumns; + return info; + } + } + } + } + if (paintedOnly) return info; + + 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, displayOffset); + if (node.Visible && y >= r.Y && y <= r.Bottom) + { + retNode = node; + break; + } + else if (NodeDisplay.HasColumnsVisible(node)) + { + Rectangle headerBounds = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ColumnsBounds, node, displayOffset); + if (y >= headerBounds.Y && y <= headerBounds.Bottom) + { + info.ColumnsAt = node.NodesColumns; + return info; + } + } + if (isUserInterfaceHitTest && (r.Bottom + 16 < y || r.Y + 16 > y)) + break; + r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ChildNodeBounds, node, displayOffset); + if (!(y >= r.Y && y <= r.Bottom)) + node = GetNextVisibleSibling(node); + else + node = node.NextVisibleNode; + } + + info.NodeAt = retNode; + return info; + } + + public static TreeAreaInfo GetTreeAreaInfo(AdvTree 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; + + if (tree.DisplayRootNode != null) + node = tree.DisplayRootNode; + + Node previousNode = null; + Rectangle previousRectangle = Rectangle.Empty; + + if (tree.View == eView.Tile) + { + 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 (y >= r.Y && y <= r.Bottom && node.HasChildNodes) + { + areaInfo.NodeAt = node; + break; + } + else if (previousNode != null && y > previousRectangle.Bottom && y < r.Y) + { + // Covers the case if point is between two nodes in the vertical space between nodes due to node vertical spacing + areaInfo.NodeAt = previousNode; + break; + } + + previousNode = node; + previousRectangle = r; + + node = node.NextVisibleNode; + } + + } + else + { + while (node != null) + { + if (!node.IsDisplayed) + { + node = node.NextVisibleNode; + continue; + } + Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, node, tree.NodeDisplay.Offset); + if (y >= r.Y && y <= r.Bottom) + { + areaInfo.NodeAt = node; + break; + } + else if (previousNode != null && y > previousRectangle.Bottom && y < r.Y) + { + // Covers the case if point is between two nodes in the vertical space between nodes due to node vertical spacing + areaInfo.NodeAt = previousNode; + break; + } + + previousNode = node; + previousRectangle = r; + + node = node.NextVisibleNode; + } + } + return areaInfo; + } + + /// + /// Gets the count of visible child nodes (Visible=true) for given node. + /// + /// Reference to Node object. + /// Number of visible nodes. + public static int GetVisibleChildNodesCount(Node parent) + { + int count = 0; + foreach(Node node in parent.Nodes) + { + if(node.Visible) + count++; + } + return count; + } + + /// + /// Gets the first visible child node or returns null if node cannot be found. + /// + /// Reference to Node object. + /// First visible node or null if node cannot be found. + public static Node GetFirstVisibleChildNode(Node parent) + { + foreach(Node node in parent.Nodes) + { + if(node.Visible) + return node; + } + return null; + } + + /// + /// Gets the last visible child node or returns null if node cannot be found. + /// + /// Reference to Node object. + /// Last visible node or null if node cannot be found. + public static Node GetLastVisibleChildNode(Node parent) + { + NodeCollection col = parent.Nodes; + int c = col.Count - 1; + for (int i = c; i >=0; i--) + { + Node node = col[i]; + if (node.Visible) + return node; + } + + return null; + } + + /// + /// Gets whether any node from array is child node of parent on any level. + /// + /// Reference to parent node. + /// Reference to child nodes. + /// + public static bool IsChildNode(Node parent, Node[] childNodes) + { + foreach (Node childNode in childNodes) + { + if (IsChildNode(parent, childNode)) + return true; + } + return false; + } + + /// + /// Gets whether node is child node of parent on any level. + /// + /// Reference to parent node. + /// Reference to child node. + /// + public static bool IsChildNode(Node parent, Node child) + { + if (parent == child || child == null || parent == null) return false; + while (child.Parent != null) + { + if (child.Parent == parent) return true; + child = child.Parent; + } + return false; + } + + /// + /// Returns true if child node is child of any parent node at any level. + /// + /// Parent nodes array + /// Child node + /// true if child otherwise false + public static bool IsChildOfAnyParent(Node[] parents, Node child) + { + foreach (Node parent in parents) + { + if (IsChildNode(parent, child)) return true; + } + return false; + } + + #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) + { + // {F962CEC7-CD8F-4911-A9E9-CAB39962FC1F}, 114 + string[] parts = key.Split('-'); + int test = 0; + for(int i=parts.Length-1;i>=0;i--) + { + if(parts[i]=="CD8F") + test += 12; + else if(parts[i]=="CAB39962FC1F") + test += 2; + else if(parts[i]=="A9E9") + test += 3; + else if(parts[i]=="4911") + test += 7; + else if(parts[i]=="F962CEC7") + 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\\{C0093B14-207D-4406-826D-7186EF33C7E5}\\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 + + /// + /// Finds the node based on the Node.Name property. + /// + /// Reference to a tree control. + /// Reference to a node with given name or null if node cannot be found. + public static Node FindNodeByName(AdvTree advTree, string name) + { + return FindNodeByName(advTree.Nodes, name); + } + + public static Node FindNodeByName(NodeCollection col, string name) + { + foreach (Node node in col) + { + if (node.Name == name) + return node; + if (node.HasChildNodes) + { + Node n2 = FindNodeByName(node.Nodes, name); + if (n2 != null) return n2; + } + } + return null; + } + + public static void FindNodesByName(NodeCollection col, string name, bool searchAllChildren, ArrayList listToPopulate) + { + foreach (Node node in col) + { + if (node.Name == name) + listToPopulate.Add(node); + if (searchAllChildren && node.HasChildNodes) + { + FindNodesByName(node.Nodes, name, true, listToPopulate); + } + } + } + + /// + /// Finds the node based on the Node.DataKey property. + /// + /// Reference to a tree control. + /// Reference to a node with given key or null if node cannot be found. + public static Node FindNodeByDataKey(AdvTree advTree, object key) + { + return FindNodeByDataKey(advTree.Nodes, key); + } + public static Node FindNodeByDataKey(NodeCollection col, object key) + { + foreach (Node node in col) + { + if (object.Equals(node.DataKey, key)) + return node; + if (node.HasChildNodes) + { + Node n2 = FindNodeByDataKey(node.Nodes, key); + if (n2 != null) return n2; + } + } + return null; + } + + /// + /// Finds the node based on the Node.BindingIndex property. + /// + /// Reference to a tree control. + /// Index to look for + public static Node FindNodeByBindingIndex(AdvTree advTree, int bindingIndex) + { + return FindNodeByBindingIndex(advTree.Nodes, bindingIndex); + } + public static Node FindNodeByBindingIndex(NodeCollection col, int bindingIndex) + { + foreach (Node node in col) + { + if (node.BindingIndex == bindingIndex) + return node; + if (node.HasChildNodes) + { + Node n2 = FindNodeByBindingIndex(node.Nodes, bindingIndex); + if (n2 != null) return n2; + } + } + return null; + } + + /// + /// Returns next visible cell in node. + /// + /// Reference to a node + /// The index at which to start search. + /// Reference to cell or null if there are no visible cells + public static Cell GetNextVisibleCell(Node node, int startIndex) + { + return GetVisibleCell(node, startIndex, 1); + } + /// + /// Returns previous visible cell in node. + /// + /// Reference to a node + /// The index at which to start search. + /// Reference to cell or null if there are no visible cells + public static Cell GetPreviousVisibleCell(Node node, int startIndex) + { + return GetVisibleCell(node, startIndex, -1); + } + + public static Cell GetVisibleCell(Node node, int startIndex, int direction) + { + AdvTree tree = node.TreeControl; + if (tree != null && tree.AllowUserToReorderColumns && tree.Columns.Count > 0) + { + // Convert the startIndex to display index + startIndex = tree.Columns.GetDisplayIndex(tree.Columns[startIndex]); + startIndex += direction; + + int c = direction > 0 ? tree.Columns.Count - 1 : 0; + int i = startIndex; + int loopCount = 0; + while (loopCount < 2) + { + if (i < 0) + { + i = tree.Columns.Count - 1; + loopCount++; + } + else if (i >= tree.Columns.Count) + { + i = 0; + loopCount++; + } + int cellIndex = tree.Columns.DisplayIndexMap[i]; + if (node.Cells.Count>cellIndex && node.Cells[cellIndex].IsVisible) return node.Cells[cellIndex]; + i += direction; + } + } + else + { + startIndex += direction; + int c = direction > 0 ? node.Cells.Count - 1 : 0; + int i = startIndex; + int loopCount = 0; + while (loopCount < 2) + { + if (i < 0) + { + i = node.Cells.Count - 1; + loopCount++; + } + else if (i >= node.Cells.Count) + { + i = 0; + loopCount++; + } + + if (node.Cells[i].IsVisible) return node.Cells[i]; + i += direction; + } + } + + return null; + } + + /// + /// Returns the zero based flat index of the node. Flat index is the index of the node as if tree structure + /// has been flattened into the list. + /// + /// Reference to parent tree control. + /// Reference to the node to return index for. + /// Zero based node index or -1 if index cannot be determined. + internal static int GetNodeFlatIndex(AdvTree tree, Node node) + { + if (node == null) throw new NullReferenceException("Parameter node cannot be null"); + int count = 0; + Node currentNode = GetAnyPreviousNode(node); + while (currentNode != null) + { + count++; + currentNode = GetAnyPreviousNode(currentNode); + //if (currentNode != null && currentNode.Parent == null) + //{ + // count += tree.Nodes.IndexOf(currentNode) + 1; + // break; + //} + } + + return count; + } + + /// + /// Returns node based on the flat index. Flat index is the index of the node as if tree structure + /// has been flattened into the list. + /// + /// Parent tree control. + /// Index to return node for. + /// Reference to a node or null if node at specified index cannot be found. + internal static Node GetNodeByFlatIndex(AdvTree advTree, int index) + { + if (index == -1 || advTree.Nodes.Count == 0) return null; + + Node node = advTree.Nodes[0]; + int count = 0; + while (node != null) + { + if (index == count) + return node; + node = GetAnyNextNode(node); + count++; + } + + return null; + } + + /// + /// Finds the first node that starts with the specified text. Node.Text property is searched. + /// + /// Parent tree control. + /// Partial text to look for + /// Reference node to start searching from + /// Gets or sets whether search ignores the letter case + /// Reference to a node or null if no node is found. + internal static Node FindNodeByText(AdvTree advTree, string text, Node startFromNode, bool ignoreCase) + { + if (startFromNode == null) + startFromNode = GetFirstVisibleNode(advTree); + else + startFromNode = GetAnyNextNode(startFromNode); + if (startFromNode == null) return null; + + Node node = startFromNode; +#if FRAMEWORK20 + StringComparison comparison = ignoreCase ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture; + while (node != null) + { + if (node.Text.StartsWith(text, comparison)) + return node; + node = GetAnyNextNode(node); + } +#else + if(ignoreCase) + { + text = text.ToLower(); + while (node != null) + { + if (node.Text.ToLower().StartsWith(text)) + return node; + node = GetAnyNextNode(node); + } + } + else + { + while (node != null) + { + if (node.Text.StartsWith(text)) + return node; + node = GetAnyNextNode(node); + } + } +#endif + return null; + } + + internal static Node FindNodeByCellText( + AdvTree advTree, string text, Node startFromNode, bool ignoreCase) + { + if (string.IsNullOrEmpty(text) == true) + return (null); + + startFromNode = (startFromNode == null) + ? GetFirstVisibleNode(advTree) : GetAnyNextNode(startFromNode); + + if (startFromNode == null) + return (null); + + string[] s = text.Split(','); + + for (int i = 0; i < s.Length; i++) + s[i] = s[i].Trim(); + + Node node = startFromNode; + +#if FRAMEWORK20 + StringComparison comparison = (ignoreCase == true) + ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture; + + while (node != null) + { + if (MatchedCell(node, s, comparison) == true) + return (node); + + node = GetAnyNextNode(node); + } +#else + if (ignoreCase == true) + { + for (int i = 0; i < s.Length; i++) + s[i] = s[i].ToLower(); + } + + while (node != null) + { + if (MatchedCell(node, s, ignoreCase) == true) + return (node); + + node = GetAnyNextNode(node); + } +#endif + return (null); + } + +#if FRAMEWORK20 + private static bool MatchedCell( + Node node, string[] s, StringComparison comp) + { + for (int i = 0; i < s.Length; i++) + { + if (i >= node.Cells.Count) + break; + + Cell cell = node.Cells[i]; + + if (cell.Text.StartsWith(s[i], comp) == false) + return (false); + } + + return (true); + } +#else + private static bool MatchedCell(Node node, string[] s, bool ignoreCase) + { + for (int i = 0; i < s.Length; i++) + { + if (i >= node.Cells.Count) + break; + + Cell cell = node.Cells[i]; + + if (ignoreCase == true) + { + if (cell.Text.ToLower().StartsWith(s[i]) == false) + return (false); + } + else + { + if (cell.Text.StartsWith(s[i]) == false) + return (false); + } + } + + return (true); + } +#endif + + internal static ColumnHeader GetCellColumnHeader(AdvTree tree, Cell cell) + { + int index = -1; + if (cell.Parent != null) index = cell.Parent.Cells.IndexOf(cell); + + if (cell.Parent != null && cell.Parent.Parent != null && cell.Parent.Parent.NodesColumns.Count > 0 && index < cell.Parent.Parent.NodesColumns.Count) + { + return cell.Parent.Parent.NodesColumns[index]; + } + + if (tree != null && tree.Columns.Count > 0 && index < tree.Columns.Count) + return tree.Columns[index]; + + return null; + } + + public static void InvalidateNodeLayout(Node node, bool invalidateChildNodes) + { + node.SizeChanged = true; + if (invalidateChildNodes && node.HasChildNodes) + { + foreach (Node item in node.Nodes) + { + InvalidateNodeLayout(item, true); + } + } + } + } + + /// + /// Returned as information about the node or its column header at given coordinates. + /// + internal class NodeHitTestInfo + { + public Node NodeAt = null; + public ColumnHeaderCollection ColumnsAt = null; + } + + /// + /// Defines options for EnsureVisible method which brings node into the view. + /// + public enum eEnsureVisibleOption + { + /// + /// Scrolls the tree so node is displayed at the bottom of the tree, if possible. + /// + Bottom, + /// + /// Scrolls the tree so node is displayed in the middle of the tree, if possible. + /// + Middle, + /// + /// Scrolls the tree so node is displayed at the top of the tree, if possible. + /// + Top + } +} + diff --git a/PROMS/DotNetBar Source Code/AdvTree/NodeStyles.cs b/PROMS/DotNetBar Source Code/AdvTree/NodeStyles.cs new file mode 100644 index 00000000..1219088b --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/NodeStyles.cs @@ -0,0 +1,463 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree +{ + /// + /// Class that provides predefined styles for the nodes. Styles are defined as static memeber of the class + /// + 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; + + /// + /// Returns Apple element style + /// + public static ElementStyle Apple + { + get + { + if(s_AppleStyle==null) + s_AppleStyle = GetStyle(ePredefinedElementStyle.Apple); + return s_AppleStyle; + } + } + + /// + /// Returns Blue element style + /// + public static ElementStyle Blue + { + get + { + if(s_BlueStyle==null) + s_BlueStyle= GetStyle(ePredefinedElementStyle.Blue); + return s_BlueStyle; + } + } + + /// + /// Returns BlueLight element style + /// + public static ElementStyle BlueLight + { + get + { + if(s_BlueLightStyle==null) + s_BlueLightStyle= GetStyle(ePredefinedElementStyle.BlueLight); + return s_BlueLightStyle; + } + } + + /// + /// Returns BlueNight element style + /// + public static ElementStyle BlueNight + { + get + { + if(s_BlueNightStyle==null) + s_BlueNightStyle= GetStyle(ePredefinedElementStyle.BlueNight); + return s_BlueNightStyle; + } + } + + /// + /// Returns BlueMist element style + /// + public static ElementStyle BlueMist + { + get + { + if(s_BlueMistStyle==null) + s_BlueMistStyle= GetStyle(ePredefinedElementStyle.BlueMist); + return s_BlueMistStyle; + } + } + + /// + /// Returns Cyan element style + /// + public static ElementStyle Cyan + { + get + { + if(s_CyanStyle==null) + s_CyanStyle= GetStyle(ePredefinedElementStyle.Cyan); + return s_CyanStyle; + } + } + + /// + /// Returns Green element style + /// + public static ElementStyle Green + { + get + { + if(s_GreenStyle==null) + s_GreenStyle= GetStyle(ePredefinedElementStyle.Green); + return s_GreenStyle; + } + } + + /// + /// Returns Lemon element style + /// + public static ElementStyle Lemon + { + get + { + if(s_LemonStyle==null) + s_LemonStyle= GetStyle(ePredefinedElementStyle.Lemon); + return s_LemonStyle; + } + } + + /// + /// Returns Magenta element style + /// + public static ElementStyle Magenta + { + get + { + if(s_MagentaStyle==null) + s_MagentaStyle= GetStyle(ePredefinedElementStyle.Magenta); + return s_MagentaStyle; + } + } + + /// + /// Returns Orange element style + /// + public static ElementStyle Orange + { + get + { + if(s_OrangeStyle==null) + s_OrangeStyle= GetStyle(ePredefinedElementStyle.Orange); + return s_OrangeStyle; + } + } + + /// + /// Returns OrangeLight element style + /// + public static ElementStyle OrangeLight + { + get + { + if(s_OrangeLightStyle==null) + s_OrangeLightStyle= GetStyle(ePredefinedElementStyle.OrangeLight); + return s_OrangeLightStyle; + } + } + + /// + /// Returns Purple element style + /// + public static ElementStyle Purple + { + get + { + if(s_PurpleStyle==null) + s_PurpleStyle= GetStyle(ePredefinedElementStyle.Purple); + return s_PurpleStyle; + } + } + + /// + /// Returns PurpleMist element style + /// + public static ElementStyle PurpleMist + { + get + { + if(s_PurpleMistStyle==null) + s_PurpleMistStyle= GetStyle(ePredefinedElementStyle.PurpleMist); + return s_PurpleMistStyle; + } + } + + /// + /// Returns Red element style + /// + public static ElementStyle Red + { + get + { + if(s_RedStyle==null) + s_RedStyle= GetStyle(ePredefinedElementStyle.Red); + return s_RedStyle; + } + } + + /// + /// Returns Silver element style + /// + public static ElementStyle Silver + { + get + { + if(s_SilverStyle==null) + s_SilverStyle= GetStyle(ePredefinedElementStyle.Silver); + return s_SilverStyle; + } + } + + /// + /// Returns SilverMist element style + /// + public static ElementStyle SilverMist + { + get + { + if(s_SilverMistStyle==null) + s_SilverMistStyle= GetStyle(ePredefinedElementStyle.SilverMist); + return s_SilverMistStyle; + } + } + + /// + /// Returns Tan element style + /// + public static ElementStyle Tan + { + get + { + if(s_TanStyle==null) + s_TanStyle= GetStyle(ePredefinedElementStyle.Tan); + return s_TanStyle; + } + } + + /// + /// Returns Teal element style + /// + public static ElementStyle Teal + { + get + { + if(s_TealStyle==null) + s_TealStyle= GetStyle(ePredefinedElementStyle.Teal); + return s_TealStyle; + } + } + + /// + /// Returns Yellow element style + /// + public static ElementStyle Yellow + { + get + { + if(s_YellowStyle==null) + s_YellowStyle= GetStyle(ePredefinedElementStyle.Yellow); + return s_YellowStyle; + } + } + + /// + /// Returns Gray element style + /// + 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=Utilities.CreateStyle(new ComponentFactory(),Enum.GetName(typeof(ePredefinedElementStyle),c),borderColor,color1, color2, gradientAngle,textColor); + return style; + } + } + + /// + /// Indicates predefined element style. + /// + public enum ePredefinedElementStyle + { + Blue, + BlueLight, + BlueNight, + Yellow, + Green, + Red, + Purple, + Cyan, + Orange, + OrangeLight, + Magenta, + BlueMist, + PurpleMist, + Tan, + Lemon, + Apple, + Teal, + Silver, + SilverMist, + Gray + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/SelectedNodesCollection.cs b/PROMS/DotNetBar Source Code/AdvTree/SelectedNodesCollection.cs new file mode 100644 index 00000000..94007432 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/SelectedNodesCollection.cs @@ -0,0 +1,160 @@ +using System; +using System.Text; +using System.Collections.Generic; + +namespace DevComponents.AdvTree +{ + /// + /// Represents the selected nodes collection. + /// + public class SelectedNodesCollection : NodeCollection + { + #region Internal Implementation + internal AdvTree TreeSelectionControl = null; + internal bool SuspendEvents = false; + internal bool SuspendClearEvents = false; + /// + /// Initializes a new instance of the SelectedNodesCollection class. + /// + public SelectedNodesCollection() + { + PassiveCollection = true; + } + + /// + /// Adds new object to the collection and provides information about the source of the command + /// + /// Node to add + /// Source action + /// + public override int Add(Node node, eTreeAction action) + { + if (this.List.Contains(node)) return -1; + + if (TreeSelectionControl.MultiSelect) + { + if (TreeSelectionControl.MultiSelectRule == eMultiSelectRule.SameParent && this.Count>0) + { + if (this[0].Parent != node.Parent) + throw new InvalidOperationException("Node being added does not belong to the same parent as currently selected nodes. See AdvTree.MultiSelectRule property"); + } + if (!SuspendEvents) + { + AdvTreeNodeCancelEventArgs cancelArgs = new AdvTreeNodeCancelEventArgs(action, node); + TreeSelectionControl.InvokeOnBeforeNodeSelect(cancelArgs); + if (cancelArgs.Cancel) + return -1; + } + } + return base.Add(node, action); + } + + /// + /// Adds an array of objects to the collection. + /// + /// Array of Node objects. + public override void AddRange(Node[] nodes) + { + this.MultiNodeOperation = true; + base.AddRange(nodes); + this.MultiNodeOperation = false; + if (!SuspendEvents) + TreeSelectionControl.InvokeSelectionChanged(EventArgs.Empty); + } + + protected override void OnInsertComplete(int index, object value) + { + if (TreeSelectionControl.MultiSelect) + { + Node node = value as Node; + node.IsSelected = true; + TreeSelectionControl.InvalidateNode(node); + if (node.SelectedCell == null) + { + node.SelectFirstCell(SourceAction); + } + AdvTreeNodeEventArgs args = new AdvTreeNodeEventArgs(SourceAction, node); + TreeSelectionControl.InvokeOnAfterNodeSelect(args); + node.InternalSelected(this.SourceAction); + if(!_MultiNodeOperation) + TreeSelectionControl.InvokeSelectionChanged(EventArgs.Empty); + } + base.OnInsertComplete(index, value); + + } + + protected override void OnRemoveComplete(int index, object value) + { + if (TreeSelectionControl.MultiSelect) + { + Node node = value as Node; + node.IsSelected = false; + TreeSelectionControl.InvalidateNode(node); + if (node.SelectedCell != null) + node.SelectedCell.SetSelected(false, SourceAction); + + TreeSelectionControl.InvokeOnAfterNodeDeselect(new AdvTreeNodeEventArgs(this.SourceAction, node)); + node.InternalDeselected(this.SourceAction); + if (!_MultiNodeOperation) + TreeSelectionControl.InvokeSelectionChanged(EventArgs.Empty); + } + base.OnRemoveComplete(index, value); + } + + private int _NumberOfClearedNodes = 0; + protected override void OnClear() + { + if (TreeSelectionControl.MultiSelect) + { + _NumberOfClearedNodes = this.List.Count; + Node[] list = new Node[_NumberOfClearedNodes]; + this.List.CopyTo(list, 0); + foreach (Node node in list) + { + node.IsSelected = false; + TreeSelectionControl.InvalidateNode(node); + if (node.SelectedCell == null) + node.Cells[0].SetSelected(false, SourceAction); + _ClearedEventArgsList.Add(new AdvTreeNodeEventArgs(this.SourceAction, node)); // Delay event notification to OnClearComplete so node is not in collection if collection is being tested + //TreeSelectionControl.InvokeOnAfterNodeDeselect(new AdvTreeNodeEventArgs(this.SourceAction, node)); + node.InternalDeselected(this.SourceAction); + } + } + base.OnClear(); + } + private List _ClearedEventArgsList = new List(); + protected override void OnClearComplete() + { + if (TreeSelectionControl.MultiSelect) + { + if (TreeSelectionControl != null && !SuspendClearEvents) + { + // Invoke nodes deselected + foreach (AdvTreeNodeEventArgs advTreeNodeEventArgs in _ClearedEventArgsList) + { + TreeSelectionControl.InvokeOnAfterNodeDeselect(advTreeNodeEventArgs); + } + } + _ClearedEventArgsList.Clear(); + if (!SuspendClearEvents && _NumberOfClearedNodes > 0) + TreeSelectionControl.InvokeSelectionChanged(EventArgs.Empty); + } + base.OnClearComplete(); + } + + private bool _MultiNodeOperation; + internal bool MultiNodeOperation + { + get + { + return _MultiNodeOperation; + } + set + { + _MultiNodeOperation = value; + } + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TextBoxEx.cs b/PROMS/DotNetBar Source Code/AdvTree/TextBoxEx.cs new file mode 100644 index 00000000..8e03e717 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TextBoxEx.cs @@ -0,0 +1,159 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using System.ComponentModel; + +namespace DevComponents.AdvTree +{ + /// + /// Represents the text box for editing cell's text. + /// + [Designer("System.Windows.Forms.Design.ControlDesigner, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"),ToolboxItem(false)] + internal class TextBoxEx:TextBox, ICellEditControl + { + #region Private variables + private bool m_WordWrap=false; + #endregion + + #region Events + public event EventHandler EditComplete; + public event EventHandler CancelEdit; + #endregion + + #region Constructor + public TextBoxEx():base() + { + this.AutoSize=false; + this.BorderStyle=System.Windows.Forms.BorderStyle.None; + } + #endregion + + #region Internal Implementation + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + + if(e.KeyCode==Keys.Enter && !m_WordWrap || e.KeyCode==Keys.Enter && e.Modifiers==Keys.Control) + { + if(EditComplete!=null) + EditComplete(this, new EventArgs()); + } + else if(e.KeyCode==Keys.Escape) + { + if(CancelEdit!=null) + CancelEdit(this,new EventArgs()); + } + } +#if FRAMEWORK20 + protected override void OnKeyPress(KeyPressEventArgs e) + { + if (!m_WordWrap && _PreventEnterBeep && e.KeyChar == (char)Keys.Enter) + { + e.Handled = true; + } + base.OnKeyPress(e); + } +#endif + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (keyData == Keys.Tab) + { + if (EditComplete != null) + EditComplete(this, new EventArgs()); + } + return base.ProcessCmdKey(ref msg, keyData); + } + + protected override void OnTextChanged(EventArgs e) + { + base.OnTextChanged (e); + ResizeControl(); + } + + private void ResizeControl() + { + Graphics g=this.CreateGraphics(); + SizeF size=g.MeasureString(this.Text,this.Font); + int width=(int)Math.Ceiling(size.Width); + int height=(int)Math.Ceiling(size.Height); + if (this.Parent != null && this.Right + (width - this.Width) > (this.Parent.ClientRectangle.Right - SystemInformation.VerticalScrollBarWidth - 2)) + return; + if (width > this.Width) + this.Width = width; + + if(m_WordWrap) + { + if(this.Parent!=null && this.Bottom+(height-this.Height)>this.Parent.Bottom) + return; + if(height>this.Height) + this.Height=height; + } + } + #endregion + + #region Public Properties + + /// + /// Gets or sets whether the editing is in word-wrap mode. + /// + public bool EditWordWrap + { + get {return m_WordWrap;} + set + { + m_WordWrap=value; + if(m_WordWrap) + { + this.Multiline=true; + this.ScrollBars=ScrollBars.None; + } + else + { + this.Multiline=false; + } + } + } + + private bool _PreventEnterBeep = false; + /// + /// Gets or sets whether control prevents Beep sound when Enter key is pressed. + /// + [DefaultValue(false), Category("Behavior"), Description("Gets or sets whether control prevents Beep sound when Enter key is pressed.")] + public bool PreventEnterBeep + { + get { return _PreventEnterBeep; } + set + { + _PreventEnterBeep = value; + } + } + + #endregion + + #region ICellEditControl Members + + public void BeginEdit() + { + + } + + public void EndEdit() + { + + } + + public object CurrentValue + { + get + { + return this.Text; + } + set + { + this.Text = value.ToString(); + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeAreaInfo.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeAreaInfo.cs new file mode 100644 index 00000000..1920c540 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeAreaInfo.cs @@ -0,0 +1,60 @@ +namespace DevComponents.AdvTree +{ + /// + /// Summary description for TreeAreaInfo. + /// + internal class TreeAreaInfo + { + /// + /// Reference to parent node in which child bounds the coordinates are. Can be null if no parent node contains given coordinates. + /// + public Node ParentAreaNode=null; + /// + /// Node which contains specified coordinates. Can be null if no node contains coordinates. + /// + public Node NodeAt=null; + /// + /// Previous reference node for given coordinates. If coordinates fall between two nodes this will indicate previous node or null. + /// + public Node PreviousNode=null; + /// + /// Next reference node for given coordinates. If coordinates fall between two nodes this will indicate next node or null. + /// + public Node NextNode=null; + } + + internal class NodeDragInfo + { + /// + /// Gets or sets the parent node drag node will be added to. When null the drag node is being added as top-level node. + /// + public Node Parent = null; + /// + /// Gets or sets the insert index of drag node into the parent's node Nodes collection. + /// + public int InsertIndex = -1; + + /// + /// Initializes a new instance of the NodeDragInfo class. + /// + public NodeDragInfo() + { + } + + /// + /// Initializes a new instance of the NodeDragInfo class. + /// + /// + /// + public NodeDragInfo(Node parent, int insertIndex) + { + Parent = parent; + InsertIndex = insertIndex; + } + + public override string ToString() + { + return string.Format("NodeDragInfo-> Parent={0}, InsertIndex={1}", Parent, InsertIndex); + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeCellCancelEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeCellCancelEventArgs.cs new file mode 100644 index 00000000..9949412d --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeCellCancelEventArgs.cs @@ -0,0 +1,43 @@ +using System; +using System.Windows.Forms; + +namespace DevComponents.AdvTree +{ + /// + /// Provides data for AdvTree Cell events that can be canceled. + /// + public class TreeCellCancelEventArgs:AdvTreeCellEventArgs + { + /// + /// Default constructor for event data. + /// + /// Type of the action event is raised for. + /// Cell that event is raised for. + public TreeCellCancelEventArgs(eTreeAction action, Cell cell):base(action,cell) + { + } + + /// + /// Indicates that event action should be canceled. + /// + public bool Cancel=false; + } + + /// + /// Provides data for AdvTree.BeforeCheck event. + /// + public class AdvTreeCellBeforeCheckEventArgs : TreeCellCancelEventArgs + { + public CheckState NewCheckState = CheckState.Indeterminate; + + /// + /// Initializes a new instance of the AdvTreeCellBeforeCheckEventArgs class. + /// + /// + public AdvTreeCellBeforeCheckEventArgs(eTreeAction action, Cell cell, CheckState newCheckState) + : base(action, cell) + { + NewCheckState = newCheckState; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeCellEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeCellEventArgs.cs new file mode 100644 index 00000000..b5b25976 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeCellEventArgs.cs @@ -0,0 +1,30 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Provides data for AdvTree Cell events. + /// + public class AdvTreeCellEventArgs:EventArgs + { + /// + /// Default constructor for event data. + /// + /// Type of the action event is raised for. + /// Cell that event is raised for. + public AdvTreeCellEventArgs(eTreeAction action, Cell cell) + { + this.Action=action; + this.Cell=cell; + } + + /// + /// Indicates the type of the action performed on a cell. + /// + public eTreeAction Action=eTreeAction.Code; + /// + /// Indicates the cell that action is performed on. + /// + public DevComponents.AdvTree.Cell Cell=null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeDragDropEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeDragDropEventArgs.cs new file mode 100644 index 00000000..88705986 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeDragDropEventArgs.cs @@ -0,0 +1,48 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Represents event arguments for BeforeNodeDrop and AfterNodeDrop events + /// + public class TreeDragDropEventArgs : AdvTreeMultiNodeCancelEventArgs + { + public TreeDragDropEventArgs(eTreeAction action, Node[] nodes, Node oldParentNode, Node newParentNode, int insertPosition) + : base(action, nodes) + { + this.NewParentNode = newParentNode; + this.OldParentNode = oldParentNode; + this.InsertPosition = insertPosition; + } + + public TreeDragDropEventArgs(eTreeAction action, Node[] nodes, Node oldParentNode, Node newParentNode, bool isCopy, int insertPosition) + : base(action, nodes) + { + this.NewParentNode = newParentNode; + this.OldParentNode = oldParentNode; + this.IsCopy = isCopy; + this.InsertPosition = insertPosition; + } + + /// + /// Returns reference to the old parent node. + /// + public readonly Node OldParentNode=null; + + /// + /// Reference to the new parent node if event is not cancelled. + /// + public readonly Node NewParentNode=null; + + /// + /// Gets or sets whether drag node is being copied instead of moved. + /// + public bool IsCopy = false; + + /// + /// Gets or sets the new insert position inside of NewParentNode.Nodes collection for the node being dragged. If InsertPosition is -1 + /// the ParentNode refers to the current mouse over node and drag & drop node will be added as child node to it. + /// + public int InsertPosition = 0; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeDragFeedbackEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeDragFeedbackEventArgs.cs new file mode 100644 index 00000000..5611b904 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeDragFeedbackEventArgs.cs @@ -0,0 +1,129 @@ +using System; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.AdvTree +{ + /// + /// Defines the data for NodeDragFeedback event. + /// + public class TreeDragFeedbackEventArgs : EventArgs + { + /// + /// Gets or sets whether this drop location is accepted. Default value is true. You can set this to false to disable drop at this location. + /// + public bool AllowDrop = true; + /// + /// Gets or sets the parent node for the node that is being dragged. This can be null/nothing value to indicate a root top-level node that + /// is in AdvTree.Nodes collection. + /// + public Node ParentNode = null; + /// + /// Gets or sets the new insert position inside of ParentNode.Nodes collection for the node being dragged. If InsertPosition is -1 + /// the ParentNode refers to the current mouse over node and drag & drop node will be added as child node to it. + /// + public int InsertPosition = 0; + + private Node _DragNode; + /// + /// Gets reference to the node being dragged. + /// + public Node DragNode + { + get { return _DragNode; } +#if FRAMEWORK20 + set + { + _DragNode = value; + } +#endif + } + + /// + /// Initializes a new instance of the TreeDragFeedbackEventArgs class. + /// + /// + /// + public TreeDragFeedbackEventArgs(Node parentNode, int insertPosition, Node dragNode) + { + ParentNode = parentNode; + InsertPosition = insertPosition; + _DragNode = dragNode; + } + + /// + /// Initializes a new instance of the TreeDragFeedbackEventArgs class. + /// + /// + /// + public TreeDragFeedbackEventArgs(Node parentNode, int insertPosition, Node dragNode, DragDropEffects effect) + { + ParentNode = parentNode; + InsertPosition = insertPosition; + _DragNode = dragNode; + _Effect = effect; + } + + /// + /// Initializes a new instance of the TreeDragFeedbackEventArgs class. + /// + public TreeDragFeedbackEventArgs() + { + } + + internal bool EffectSet = false; + private DragDropEffects _Effect = DragDropEffects.None; + /// + /// Gets or sets the drop effect for the drag-drop operation. + /// + public DragDropEffects Effect + { + get { return _Effect; } + set + { + _Effect = value; + EffectSet = true; + } + } + } + + public class MultiNodeTreeDragFeedbackEventArgs : TreeDragFeedbackEventArgs + { + /// + /// Initializes a new instance of the TreeDragFeedbackEventArgs class. + /// + /// + /// + public MultiNodeTreeDragFeedbackEventArgs(Node parentNode, int insertPosition, Node[] dragNodes) : + base(parentNode, insertPosition, dragNodes[0]) + { + _DragNodes = dragNodes; + } + + /// + /// Initializes a new instance of the TreeDragFeedbackEventArgs class. + /// + /// + /// + public MultiNodeTreeDragFeedbackEventArgs(Node parentNode, int insertPosition, Node[] dragNodes, DragDropEffects effect) : + base(parentNode, insertPosition, dragNodes[0], effect) + { + _DragNodes = dragNodes; + } + + private Node[] _DragNodes; + /// + /// Gets reference to the node being dragged. + /// + public Node[] DragNodes + { + get { return _DragNodes; } +#if FRAMEWORK20 + set + { + _DragNodes = value; + } +#endif + } + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeNodeCancelEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeNodeCancelEventArgs.cs new file mode 100644 index 00000000..6f98877f --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeNodeCancelEventArgs.cs @@ -0,0 +1,46 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Provides data for AdvTree Node events that can be cancelled. + /// + public class AdvTreeNodeCancelEventArgs:AdvTreeNodeEventArgs + { + /// + /// Default constructor. + /// + /// Default action + /// Default node. + public AdvTreeNodeCancelEventArgs(eTreeAction action, Node node):base(action,node) + { + } + + /// + /// Indicates that event action should be canceled. + /// + public bool Cancel=false; + } + + /// + /// Provides data for AdvTree Node events that can be cancelled. + /// + public class AdvTreeMultiNodeCancelEventArgs : AdvTreeNodeCancelEventArgs + { + /// + /// Default constructor. + /// + /// Default action + /// Default node. + public AdvTreeMultiNodeCancelEventArgs(eTreeAction action, Node[] nodes) + : base(action, nodes[0]) + { + Nodes = nodes; + } + + /// + /// Indicates the array of nodes that action is performed on. + /// + public DevComponents.AdvTree.Node[] Nodes = null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeNodeCollectionEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeNodeCollectionEventArgs.cs new file mode 100644 index 00000000..e1bf3a2a --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeNodeCollectionEventArgs.cs @@ -0,0 +1,28 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Represents event arguments for NodeCollection based events, like BeforeNodeInsert, AfterNodeInsert etc. + /// + public class TreeNodeCollectionEventArgs : AdvTreeNodeEventArgs + { + /// + /// Creates new instance of the class. + /// + /// Source action + /// Affected node + /// Parent of the node if any + public TreeNodeCollectionEventArgs(eTreeAction action, Node node, Node parentNode):base(action, node) + { + this.ParentNode = parentNode; + } + + /// + /// Indicates parent node of the affected node. For example if event handled is BeforeNodeInsert parent of the Node is has + /// not been set yet so this property provides information on the node that will become parent. If this property returns null + /// then node is being added or removed from the main AdvTree.Nodes collection. + /// + public DevComponents.AdvTree.Node ParentNode=null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeNodeEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeNodeEventArgs.cs new file mode 100644 index 00000000..48d94091 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeNodeEventArgs.cs @@ -0,0 +1,31 @@ +using System; + +namespace DevComponents.AdvTree +{ + /// + /// Provides data for AdvTree Node events. + /// + public class AdvTreeNodeEventArgs:EventArgs + { + /// + /// Default constructor. + /// + /// Default action + /// Default node. + public AdvTreeNodeEventArgs(eTreeAction action, Node node) + { + this.Action = action; + this.Node = node; + } + + /// + /// Indicates the type of the action performed on a node. + /// + public eTreeAction Action=eTreeAction.Code; + + /// + /// Indicates the node that action is performed on. + /// + public DevComponents.AdvTree.Node Node=null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeNodeMouseEventArgs.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeNodeMouseEventArgs.cs new file mode 100644 index 00000000..a4c994c4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeNodeMouseEventArgs.cs @@ -0,0 +1,51 @@ +using System; +using System.Windows.Forms; + +namespace DevComponents.AdvTree +{ + /// + /// Represents event arguments for node mouse based events. + /// + public class TreeNodeMouseEventArgs:EventArgs + { + public TreeNodeMouseEventArgs(Node node, MouseButtons button, int clicks, int delta, int x, int y) + { + this.Node = node; + this.Button = button; + this.Clicks = clicks; + this.Delta = delta; + this.X = x; + this.Y = y; + } + + /// + /// Gets node affected by mouse action. + /// + public readonly Node Node; + + /// + /// Gets which mouse button was pressed. + /// + public readonly MouseButtons Button; + + /// + /// Gets the number of times the mouse button was pressed and released. + /// + public readonly int Clicks; + + /// + /// Gets a signed count of the number of detents the mouse wheel has rotated. A detent is one notch of the mouse wheel. + /// + public readonly int Delta; + + /// + /// Gets the x-coordinate of the mouse. + /// + public readonly int X; + + /// + /// Gets the y-coordinate of the mouse. + /// + public readonly int Y; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/TreeSerializer.cs b/PROMS/DotNetBar Source Code/AdvTree/TreeSerializer.cs new file mode 100644 index 00000000..c8917786 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/TreeSerializer.cs @@ -0,0 +1,351 @@ +using System; +using System.Xml; +using System.IO; +using DevComponents.DotNetBar; + +namespace DevComponents.AdvTree +{ + /// + /// Provides means for AdvTree serialization. + /// + public class TreeSerializer + { + #region Private Variables + private static string XmlNodeName="Node"; + private static string XmlCellsName="Cells"; + private static string XmlCellName="Cell"; + private static string XmlCellImagesName="Images"; + private static string XmlAdvTreeName="AdvTree"; + private static string XmlCustomName = "Custom"; + #endregion + + #region Saving + /// + /// Saves Nodes to specified file. + /// + /// AdvTree to save + /// Target file name + public static void Save(AdvTree tree, string fileName) + { + XmlDocument document=Save(tree); + document.Save(fileName); + } + + /// + /// Saves Nodes to stream. + /// + /// AdvTree to save + /// Stream to save nodes to. + public static void Save(AdvTree tree, Stream outStream) + { + XmlDocument document=Save(tree); + document.Save(outStream); + } + + /// + /// Saves Nodes to TextWriter + /// + /// AdvTree to save + /// TextWriter to write nodes to. + public static void Save(AdvTree tree, TextWriter writer) + { + XmlDocument document=Save(tree); + document.Save(writer); + } + + /// + /// Saves nodes to XmlWriter. + /// + /// AdvTree to save + /// XmlWriter to write nodes to + public static void Save(AdvTree tree, XmlWriter writer) + { + XmlDocument document=Save(tree); + document.Save(writer); + } + + /// + /// Creates new XmlDocument and serializes AdvTree into it. + /// + /// AdvTree to serialize + /// New instance of XmlDocument/returns> + public static XmlDocument Save(AdvTree tree) + { + XmlDocument document=new XmlDocument(); + Save(tree, document); + return document; + } + + /// + /// Saves AdvTree to an existing XmlDocument. New node AdvTree is created in document and Nodes are serialized into it. + /// + /// AdvTree to serialize + /// XmlDocument instance. + public static void Save(AdvTree tree, XmlDocument document) + { + XmlElement parent = document.CreateElement(XmlAdvTreeName); + document.AppendChild(parent); + TreeSerializer.Save(tree, parent); + } + + /// + /// Serializes AdvTree object to XmlElement object. + /// + /// Instance of AdvTree to serialize. + /// XmlElement to serialize to. + public static void Save(AdvTree tree, XmlElement parent) + { + NodeSerializationContext context = new NodeSerializationContext(); + context.RefXmlElement = parent; + context.AdvTree = tree; + context.HasSerializeNodeHandlers = tree.HasSerializeNodeHandlers; + context.HasDeserializeNodeHandlers = tree.HasDeserializeNodeHandlers; + + foreach(Node node in tree.Nodes) + { + Save(node, context); + } + } + + /// + /// Serializes Node and all child nodes to XmlElement object. + /// + /// Node to serialize. + /// Provides serialization context. + public static void Save(Node node, NodeSerializationContext context) + { + XmlElement parent = context.RefXmlElement; + + XmlElement xmlNode=parent.OwnerDocument.CreateElement(XmlNodeName); + parent.AppendChild(xmlNode); + + ElementSerializer.Serialize(node, xmlNode); + + if(context.HasSerializeNodeHandlers) + { + XmlElement customXml = parent.OwnerDocument.CreateElement(XmlCustomName); + SerializeNodeEventArgs e = new SerializeNodeEventArgs(node, xmlNode, customXml); + context.AdvTree.InvokeSerializeNode(e); + if (customXml.Attributes.Count > 0 || customXml.ChildNodes.Count > 0) + xmlNode.AppendChild(customXml); + } + + if(node.Cells.Count>1) + { + XmlElement xmlCells = parent.OwnerDocument.CreateElement(XmlCellsName); + xmlNode.AppendChild(xmlCells); + + for(int i=1; i + /// Load AdvTree Nodes from file. + /// + /// Reference to AdvTree to populate + /// File name. + public static void Load(AdvTree tree, string fileName) + { + XmlDocument document=new XmlDocument(); + document.Load(fileName); + Load(tree, document); + } + + /// + /// Load AdvTree Nodes from stream. + /// + /// Reference to AdvTree to populate + /// Reference to stream + public static void Load(AdvTree tree, Stream inStream) + { + XmlDocument document=new XmlDocument(); + document.Load(inStream); + Load(tree, document); + } + + /// + /// Load AdvTree Nodes from reader. + /// + /// Reference to AdvTree to populate + /// Reference to reader. + public static void Load(AdvTree tree, TextReader reader) + { + XmlDocument document=new XmlDocument(); + document.Load(reader); + Load(tree, document); + } + + /// + /// Load AdvTree Nodes from reader. + /// + /// Reference to AdvTree to populate + /// Reference to reader. + public static void Load(AdvTree tree, XmlReader reader) + { + XmlDocument document=new XmlDocument(); + document.Load(reader); + Load(tree, document); + } + + /// + /// Load AdvTree from XmlDocument that was created by Save method. + /// + /// Tree Control to load + /// XmlDocument to load control from + public static void Load(AdvTree tree, XmlDocument document) + { + foreach(XmlNode xmlNode in document.ChildNodes) + { + if(xmlNode.Name==XmlAdvTreeName && xmlNode is XmlElement) + { + Load(tree, xmlNode as XmlElement); + break; + } + } + } + + /// + /// Load nodes from XmlElement. + /// + /// Reference to AdvTree to be populated. + /// XmlElement that tree was serialized to. + public static void Load(AdvTree tree, XmlElement parent) + { + tree.BeginUpdate(); + tree.DisplayRootNode = null; + tree.Nodes.Clear(); + + NodeSerializationContext context = new NodeSerializationContext(); + context.AdvTree = tree; + context.HasDeserializeNodeHandlers = tree.HasDeserializeNodeHandlers; + context.HasSerializeNodeHandlers = tree.HasSerializeNodeHandlers; + + try + { + foreach(XmlNode xmlNode in parent.ChildNodes) + { + if(xmlNode.Name==XmlNodeName && xmlNode is XmlElement) + { + Node node=new Node(); + tree.Nodes.Add(node); + context.RefXmlElement = xmlNode as XmlElement; + LoadNode(node, context); + } + } + } + finally + { + tree.EndUpdate(); + } + } + + /// + /// Load single node and it's child nodes if any. + /// + /// New instance of node that is populated with loaded data. + /// Provides deserialization context. + public static void LoadNode(Node nodeToLoad, NodeSerializationContext context) + { + XmlElement xmlNode = context.RefXmlElement; + + ElementSerializer.Deserialize(nodeToLoad, xmlNode); + + foreach(XmlNode xmlChild in xmlNode.ChildNodes) + { + XmlElement xmlElem = xmlChild as XmlElement; + if(xmlElem == null) + continue; + if(xmlElem.Name==XmlNodeName) + { + Node node=new Node(); + nodeToLoad.Nodes.Add(node); + context.RefXmlElement = xmlElem; + LoadNode(node, context); + } + else if(xmlElem.Name == XmlCellsName) + { + LoadCells(nodeToLoad, xmlElem); + } + else if(xmlElem.Name == XmlCustomName) + { + if(context.HasDeserializeNodeHandlers) + { + SerializeNodeEventArgs e = new SerializeNodeEventArgs(nodeToLoad, xmlNode, xmlElem); + context.AdvTree.InvokeDeserializeNode(e); + } + } + } + context.RefXmlElement = xmlNode; + } + + private static void LoadCells(Node parentNode, XmlElement xmlCells) + { + foreach(XmlNode xmlChild in xmlCells.ChildNodes) + { + if(xmlChild.Name==XmlCellName && xmlChild is XmlElement) + { + Cell cell=new Cell(); + parentNode.Cells.Add(cell); + ElementSerializer.Deserialize(cell, xmlChild as XmlElement); + // Load images if any + foreach(XmlElement xmlImage in xmlChild.ChildNodes) + { + if(xmlImage.Name==XmlCellImagesName) + { + ElementSerializer.Deserialize(cell.Images, xmlImage); + break; + } + } + } + } + } + #endregion + } + + /// + /// Provides context information for serialization. + /// + public class NodeSerializationContext + { + /// + /// Gets or sets reference to context parent XmlElement when serializing or actual Node element when deserializing. + /// + public System.Xml.XmlElement RefXmlElement = null; + + /// + /// Gets or sets whether SerializeNode event handler has been defined and whether event should be fired. + /// + public bool HasSerializeNodeHandlers = false; + + /// + /// Gets or sets whether DeserializeNode event handler has been defined and whether event should be fired. + /// + public bool HasDeserializeNodeHandlers = false; + + /// + /// Provides access to serializer. + /// + public AdvTree AdvTree = null; + } +} diff --git a/PROMS/DotNetBar Source Code/AdvTree/Utilites.cs b/PROMS/DotNetBar Source Code/AdvTree/Utilites.cs new file mode 100644 index 00000000..0d015014 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AdvTree/Utilites.cs @@ -0,0 +1,329 @@ +using System; +using System.ComponentModel.Design; +using System.Drawing; +using System.ComponentModel; +using DevComponents.DotNetBar; +using DevComponents.DotNetBar.Rendering; +using System.Windows.Forms; + +namespace DevComponents.AdvTree +{ + /// + /// Represents class for static tree utilities. + /// + public class Utilities + { + /// + /// Initializes control with default settings for connectors and nodes. + /// + /// Control to initialize. + public static void InitializeTree(AdvTree tree) + { + InitializeTree(tree,new ComponentFactory()); + } + + /// + /// Initializes control with default settings for connectors and nodes. + /// + /// Control to initialize. + /// Factory to use to create new instances of objects. + public static void InitializeTree(AdvTree tree, ComponentFactory factory) + { + //tree.RootConnector=factory.CreateComponent(typeof(NodeConnector)) as NodeConnector; + //tree.RootConnector.LineWidth=1; + //tree.RootConnector.LineColor = SystemColors.ControlText; + tree.NodesConnector=factory.CreateComponent(typeof(NodeConnector)) as NodeConnector; + tree.NodesConnector.LineWidth=1; + tree.NodesConnector.LineColor=SystemColors.ControlText; + tree.BackColor = SystemColors.Window; + //eStyleBorderType border=eStyleBorderType.Solid; + ElementStyle style=factory.CreateComponent(typeof(ElementStyle)) as ElementStyle; + + //style.BackColorSchemePart=eColorSchemePart.BarBackground; + //style.BackColor2SchemePart=eColorSchemePart.BarBackground2; + //style.BackColorGradientAngle=90; + //style.CornerDiameter=4; + //style.CornerType=eCornerType.Rounded; + //style.BorderLeft=border; + //style.BorderLeftWidth=1; + //style.BorderTop=border; + //style.BorderTopWidth=1; + //style.BorderBottom=border; + //style.BorderBottomWidth=1; + //style.BorderRight=border; + //style.BorderRightWidth=1; + //style.BorderColorSchemePart=eColorSchemePart.BarDockedBorder; + //style.PaddingBottom=3; + //style.PaddingLeft=3; + //style.PaddingRight=3; + //style.PaddingTop=3; + style.TextColor = SystemColors.ControlText; + tree.Styles.Add(style); + + tree.NodeStyle=style; + + tree.BackgroundStyle.Class = ElementStyleClassKeys.TreeBorderKey; + tree.AccessibleRole = AccessibleRole.Outline; + } + + /// + /// Creates new style and adds it to styles collection + /// + /// Tree to assign style to + /// Style factory + /// + /// + /// + /// + internal static ElementStyle CreateStyle(ComponentFactory factory, string description, Color borderColor, Color backColor, Color backColor2, int gradientAngle, Color textColor) + { + eStyleBorderType border=eStyleBorderType.Solid; + ElementStyle style=factory.CreateComponent(typeof(ElementStyle)) as ElementStyle; + + style.Description = description; + style.BackColor = backColor; + style.BackColor2=backColor2; + style.BackColorGradientAngle=gradientAngle; + style.CornerDiameter=4; + style.CornerType=eCornerType.Square; + style.BorderLeft=border; + style.BorderLeftWidth=1; + style.BorderTop=border; + style.BorderTopWidth=1; + style.BorderBottom=border; + style.BorderBottomWidth=1; + style.BorderRight=border; + style.BorderRightWidth=1; + style.BorderColor=borderColor; + style.PaddingBottom=1; + style.PaddingLeft=1; + style.PaddingRight=1; + style.PaddingTop=1; + style.TextColor=textColor; + + return style; + } + + /// + /// Returns reference to a node that is hosting given control. + /// + /// Reference to the AdvTree control instance + /// Control instance to look for + /// Reference to a node hosting control or null if node could not be found + public static Node FindNodeForControl(AdvTree tree, System.Windows.Forms.Control c) + { + if(tree==null || c==null || tree.Nodes.Count==0) + return null; + + Node node = tree.Nodes[0]; + while(node!=null) + { + foreach(Cell cell in node.Cells) + { + if(cell.HostedControl==c) + return node; + } + node = node.NextVisibleNode; + } + + return null; + } + + internal static int CompareAlpha(string t, string t2) + { + return string.Compare(t, t2, StringComparison.CurrentCulture); + } + + internal static bool StartsWithNumber(string s) + { + if (s.Length > 0 && char.IsDigit(s[0])) + return true; + return false; + } + + internal static int CompareAlphaNumeric(string t, string t2) + { + if (Utilities.StartsWithNumber(t) && Utilities.StartsWithNumber(t2)) + { + long l = GetNumber(t), l2 = GetNumber(t2); + int i = l.CompareTo(l2); + if (i != 0) + return i; + } +#if FRAMEWORK20 + return string.Compare(t, t2, StringComparison.CurrentCulture); +#else + return string.Compare(t, t2); +#endif + } + + internal static long GetNumber(string s) + { + long l = 0; + int start = 0, end = 0; + for (int i = 0; i < s.Length; i++) + { + if (char.IsDigit(s[i])) + { + end = i; + } + else + break; + } +#if FRAMEWORK20 + long.TryParse(s.Substring(start, end - start + 1), out l); +#else + try + { + l = long.Parse(s.Substring(start, end - start + 1)); + } + catch { } +#endif + return l; + } + + internal static string StripNonNumeric(string p) + { + string s = ""; + string decimalSeparator = NumberDecimalSeparator; + string groupSeparator = NumberGroupSeparator; + for (int i = 0; i < p.Length; i++) + { + if (p[i].ToString() == decimalSeparator || p[i].ToString() == groupSeparator || p[i] >= '0' && p[i] <= '9' || i == 0 && p[i] == '-') + s += p[i]; + else if (s.Length > 0) break; + } + return s; + } + + private static string NumberDecimalSeparator + { + get + { +#if FRAMEWORK20 + return DevComponents.Editors.DateTimeAdv.DateTimeInput.GetActiveCulture().NumberFormat.NumberDecimalSeparator; +#else + return System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; +#endif + } + } + private static string NumberGroupSeparator + { + get + { +#if FRAMEWORK20 + return DevComponents.Editors.DateTimeAdv.DateTimeInput.GetActiveCulture().NumberFormat.NumberGroupSeparator; +#else + return System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; +#endif + } + } + } + + #region ComponentFactory + /// + /// Represents internal component factory with design-time support. + /// + public class ComponentFactory + { + private IDesignerHost m_Designer=null; + /// + /// Creates new instance of the class. + /// + /// Reference to DesignerHost to use for creation of new components. + public ComponentFactory(IDesignerHost designer) + { + m_Designer=designer; + } + + /// + /// Creates new instance of the class. + /// + public ComponentFactory() {} + + /// + /// Creates component and returns reference to the new instance. + /// + /// Type that identifies component to create. + /// New instance of the component. + public object CreateComponent(Type type) + { + object o=null; + if(m_Designer!=null) + o=m_Designer.CreateComponent(type); + else + o=type.Assembly.CreateInstance(type.FullName); + return o; + } + } + #endregion + + #region Padding Class + /// + /// Represents class that holds padding information for user interface elements. + /// + public class Padding + { + /// + /// Gets or sets padding on left side. Default value is 0 + /// + public int Left = 0; + /// + /// Gets or sets padding on right side. Default value is 0 + /// + public int Right = 0; + /// + /// Gets or sets padding on top side. Default value is 0 + /// + public int Top = 0; + /// + /// Gets or sets padding on bottom side. Default value is 0 + /// + public int Bottom = 0; + + /// + /// Creates new instance of the class and initializes it. + /// + /// Left padding + /// Right padding + /// Top padding + /// Bottom padding + public Padding(int left, int right, int top, int bottom) + { + this.Left = left; + this.Right = right; + this.Top = top; + this.Bottom = bottom; + } + + /// + /// Gets amount of horizontal padding (Left+Right) + /// + [Browsable(false)] + public int Horizontal + { + get { return this.Left + this.Right; } + } + + /// + /// Gets amount of vertical padding (Top+Bottom) + /// + [Browsable(false)] + public int Vertical + { + get { return this.Top + this.Bottom; } + } + + /// + /// Gets whether Padding is empty. + /// + public bool IsEmpty + { + get + { + return this.Left == 0 && this.Right == 0 && this.Top == 0 && this.Bottom == 0; + } + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/AnalogClock/AnalogClockControl.cs b/PROMS/DotNetBar Source Code/AnalogClock/AnalogClockControl.cs new file mode 100644 index 00000000..cd633acd --- /dev/null +++ b/PROMS/DotNetBar Source Code/AnalogClock/AnalogClockControl.cs @@ -0,0 +1,1101 @@ +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using System.Windows.Forms; +using System.Drawing.Text; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Analog clock control. + /// + [Description("Analog Clock Control"), ToolboxBitmap(typeof(AnalogClockControl), "AnalogClock.AnalogClockControl.bmp"), DefaultEvent("ValueChanged"), DefaultProperty("Value")] + public class AnalogClockControl : Control + { + #region Private Vars + + private const float _BaseSize = 100.0f; + + private Point _EditLoc; + private eClockEditStates _EditState; + private Size _LastSize; + private Timer _Timer; + #endregion + + #region Implementation + /// + /// Default minimum size. Defaults to 100, 100. + /// + protected override Size DefaultMinimumSize + { + get { return new Size(100, 100); } + } + + private bool _AntiAlias; + /// + /// Gets or sets whether anti-aliasing is used when rendering the control. Default value is true. + /// + [DefaultValue(true), + Category("Appearance"), + Description("Indicates whether Anti-aliasing is used when rendering the control.")] + public bool AntiAlias + { + get { return _AntiAlias; } + set + { + _AntiAlias = value; + Invalidate(); + } + } + + private bool _AutomaticMode; + /// + /// Gets or sets the state for automatic mode. When true the clock will auto redraw once a second and display the current date/time. Default value is false. + /// + [DefaultValue(false), + Category("Behavior"), + Description("Toggles the state for automatic mode. When true the clock will auto redraw once a second and display the current date/time.")] + public bool AutomaticMode + { + get { return _AutomaticMode; } + set + { + _AutomaticMode = value; + if (_AutomaticMode) + { + _Value = DateTime.Now; + _IsEditable = false; + if (!DesignMode) + { + if (_Timer != null) + _Timer.Dispose(); + _Timer = new Timer(); + _Timer.Interval = 1000; + _Timer.Tick += Timer_Tick; + _Timer.Enabled = true; + } + } + else + { + if (_Timer != null) + { + _Timer.Enabled = false; + _Timer.Dispose(); + _Timer = null; + } + } + Invalidate(); + } + } + + private eClockStyles _ClockStyle; + /// + /// Gets or sets clock style for this control. + /// + [DefaultValue(eClockStyles.Style1), + Category("Appearance"), + Description("The clock style for the control."), + RefreshProperties(RefreshProperties.All)] + public eClockStyles ClockStyle + { + get { return _ClockStyle; } + set + { + _ClockStyle = value; + if (_ClockStyle != eClockStyles.Custom) + { + if (_ClockStyleData != null) + { + _ClockStyleData.Parent = null; + _ClockStyleData.Dispose(); + } + _ClockStyleData = new ClockStyleData(_ClockStyle, this); + } + Invalidate(); + } + } + + private ClockStyleData _ClockStyleData; + /// + /// Gets or sets the clock style data elements for this control. + /// + [Category("Appearance"), + Description("The clock style data for the control."), + RefreshProperties(RefreshProperties.All)] + public ClockStyleData ClockStyleData + { + get { return _ClockStyleData; } + set + { + if (_ClockStyleData != null) _ClockStyleData.Parent = null; + _ClockStyleData = value; + _ClockStyleData.Parent = this; + _ClockStyleData.Style = eClockStyles.Custom; + ClockStyle = eClockStyles.Custom; + Invalidate(); + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetClockStyleData() + { + ClockStyle = eClockStyles.Style1; + } + + private eClockIndicatorStyles _IndicatorStyle; + /// + /// Gets or sets a the indicator style the clock control. Default value is Ticks. + /// + [DefaultValue(eClockIndicatorStyles.Ticks), + Category("Appearance"), + Description("Indicates which indicator style the clock will use.")] + public eClockIndicatorStyles IndicatorStyle + { + get { return _IndicatorStyle; } + set + { + _IndicatorStyle = value; + Invalidate(); + } + } + + private bool _IsEditable; + /// + /// Gets or sets whether the time can be changed by moving the clock hands. Default value is false. + /// + [DefaultValue(false), + Category("Behavior"), + Description("Indicates whether the time can be changed by moving the clock hands. If AutomaticMode is enabled, this setting is ignored.")] + public bool IsEditable + { + get { return _IsEditable; } + set + { + if (!AutomaticMode) + _IsEditable = value; + Invalidate(); + } + } + + private bool _ShowGlassOverlay; + /// + /// Gets or sets a value indicating whether to display the glass overlay on the clock control. Default value is true. + /// + [DefaultValue(true), + Category("Appearance"), + Description("Indicates whether the glass overlay on the clock control will be displayed or not.")] + public bool ShowGlassOverlay + { + get { return _ShowGlassOverlay; } + set + { + _ShowGlassOverlay = value; + Invalidate(); + } + } + + private bool _ShowSecondHand; + /// + /// Gets or sets a value indicating whether to display the second hand on the clock control. Default value is true. + /// + [DefaultValue(true), + Category("Appearance"), + Description("Indicates whether the second hand on the clock control will be displayed or not.")] + public bool ShowSecondHand + { + get { return _ShowSecondHand; } + set + { + _ShowSecondHand = value; + Invalidate(); + } + } + + /// + /// Occurs while user is dragging the mouse in order to change time. + /// + [Description("Occurs while user is dragging the mouse in order to change time.")] + public event TimeValueChangingEventHandler ValueChanging; + /// + /// Raises ValueChanging event. + /// + /// Provides event arguments. + protected virtual void OnValueChanging(TimeValueChangingEventArgs e) + { + TimeValueChangingEventHandler handler = ValueChanging; + if (handler != null) + handler(this, e); + } + + /// + /// Occurs when Value i.e. time clock is displaying has changed. + /// + [Description("Occurs when Value i.e. time clock is displaying has changed.")] + public event EventHandler ValueChanged; + /// + /// Raises ValueChanged event. + /// + /// Provides event arguments. + protected virtual void OnValueChanged(EventArgs e) + { + EventHandler handler = ValueChanged; + if (handler != null) + handler(this, e); + } + + private DateTime _Value; + /// + /// Gets or sets the current date/time value for this control. + /// + [Category("Behavior"), + Description("The current date/time value for this control. If AutomaticMode is enabled, assigned values are ignored.")] + public DateTime Value + { + get { return _Value; } + set + { + _Value = value; + OnValueChanged(EventArgs.Empty); + Invalidate(); + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetValue() + { + Value = DateTime.Now; + } + + ///// + ///// Occurs when subproperty value has changed. + ///// + //public event DevComponents.Schedule.Model.SubPropertyChangedEventHandler SubPropertyChanged; + + /// + /// Initializes a new instance of the ClockControl class + /// + public AnalogClockControl() + { + SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | + ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | + ControlStyles.SupportsTransparentBackColor, true); + + _AntiAlias = true; + _AutomaticMode = false; + _ClockStyle = eClockStyles.Style1; + _ClockStyleData = new ClockStyleData(); + _ClockStyleData.Parent = this; + _EditState = eClockEditStates.None; + _IndicatorStyle = eClockIndicatorStyles.Ticks; + _IsEditable = false; + _ShowGlassOverlay = true; + _ShowSecondHand = true; + _Value = DateTime.Now; + + MinimumSize = new Size((int)_BaseSize, (int)_BaseSize); ; + Size = MinimumSize; + } + + /// + /// Releases all resources used by the class. + /// + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + { + if (_ClockStyleData != null) + { + _ClockStyleData.Parent = null; + _ClockStyleData.Dispose(); + } + + if (_Timer != null) + { + _Timer.Dispose(); + _Timer = null; + } + } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + RectangleF rect; + float bezelWidth, angle; + + if (e.Button != MouseButtons.Left || !_IsEditable) + return; + + bezelWidth = _ClockStyleData.BezelWidth * (ClientRectangle.Width - 1); + rect = new RectangleF(ClientRectangle.X + bezelWidth, + ClientRectangle.Y + bezelWidth, + (ClientRectangle.Width - 1) - bezelWidth * 2.0f, + (ClientRectangle.Height - 1) - bezelWidth * 2.0f); + + angle = RoundToExactHour((float)_Value.TimeOfDay.TotalHours * 30.0f); + if (_ClockStyleData.HourHandStyle.ContainsPoint(rect, angle, e.Location)) + { + _LastMouseMoveHour = _Value.Hour; + _NewMouseMoveHour = _Value.Hour; + if (_Value.Hour > 12) _LastMouseMoveHour -= 12; + _EditState = eClockEditStates.Hour; + } + else + { + angle = (float)_Value.TimeOfDay.TotalMinutes * 6.0f; + if (_ClockStyleData.MinuteHandStyle.ContainsPoint(rect, angle, e.Location)) + _EditState = eClockEditStates.Minute; + else + { + angle = (float)_Value.TimeOfDay.Seconds * 6.0f; + if (_ShowSecondHand && _ClockStyleData.SecondHandStyle.ContainsPoint(rect, angle, e.Location)) + _EditState = eClockEditStates.Second; + } + } + if (_EditState != eClockEditStates.None) + _EditLoc = e.Location; + } + + private int _LastMouseMoveHour = -1; + private int _NewMouseMoveHour = -1; + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + + RectangleF rect; + float bezelWidth, angle; + + if (!_IsEditable) + return; + + if (_EditState != eClockEditStates.None) + { + _EditLoc = e.Location; + + // We need to record the direction of hour hand movement so AM/PM can be switched + if (_EditState == eClockEditStates.Hour) + { + int hour = GetHourFromPoint(_EditLoc); + if (hour == 1 && _LastMouseMoveHour == 12) + _LastMouseMoveHour = 0; + else if (hour == 12 && _LastMouseMoveHour == 1) + _LastMouseMoveHour = 13; + _NewMouseMoveHour += (hour - _LastMouseMoveHour); + if (_NewMouseMoveHour < 0) + _NewMouseMoveHour = 23; + else if (_NewMouseMoveHour > 23) + _NewMouseMoveHour = 0; + _LastMouseMoveHour = hour; + + } + + OnValueChanging(new TimeValueChangingEventArgs(GetCurrentMouseTime())); + + Invalidate(); + } + else + { + bezelWidth = _ClockStyleData.BezelWidth * (ClientRectangle.Width - 1); + rect = new RectangleF(ClientRectangle.X + bezelWidth, + ClientRectangle.Y + bezelWidth, + (ClientRectangle.Width - 1) - bezelWidth * 2.0f, + (ClientRectangle.Height - 1) - bezelWidth * 2.0f); + + angle = RoundToExactHour((float)_Value.TimeOfDay.TotalHours * 30.0f); + if (_ClockStyleData.HourHandStyle.ContainsPoint(rect, angle, e.Location)) + Cursor = Cursors.Hand; + else + { + angle = (float)_Value.TimeOfDay.TotalMinutes * 6.0f; + if (_ClockStyleData.MinuteHandStyle.ContainsPoint(rect, angle, e.Location)) + Cursor = Cursors.Hand; + else + { + angle = (float)_Value.TimeOfDay.Seconds * 6.0f; + if (_ShowSecondHand && _ClockStyleData.SecondHandStyle.ContainsPoint(rect, angle, e.Location)) + Cursor = Cursors.Hand; + else if (Cursor != Cursors.Default) + Cursor = Cursors.Default; + } + } + } + } + + private float GetClockAngleFromPoint(Point p) + { + float angle = (float)MathHelper.GetDegrees(GetAngleFromPoint(p)); + angle += 90.0f; + while (angle < 0) + angle += 360; + while (angle >= 360) + angle -= 360; + return angle; + } + private int GetHourFromPoint(Point p) + { + float angle = RoundToExactHour(GetClockAngleFromPoint(p)); + int hour = (int)Math.Round(angle / 30.0, 0); + if (hour == 0) hour = 12; + return hour; + } + private int GetMinuteFromPoint(Point p) + { + float angle = GetClockAngleFromPoint(p); + int minute = (int)Math.Round(angle / 6.0, 0); + if (minute == 60) + minute = 0; + return minute; + } + private int GetSecondFromPoint(Point p) + { + float angle = GetClockAngleFromPoint(p); + int minute = (int)Math.Round(angle / 6.0, 0); + if (minute == 60) + minute = 0; + return minute; + } + + private DateTime GetCurrentMouseTime() + { + DateTime time = _Value; + switch (_EditState) + { + case eClockEditStates.Hour: + time = new DateTime(_Value.Year, _Value.Month, _Value.Day, _NewMouseMoveHour, _Value.Minute, _Value.Second); + break; + case eClockEditStates.Minute: + time = new DateTime(_Value.Year, _Value.Month, _Value.Day, _Value.Hour, GetMinuteFromPoint(_EditLoc), _Value.Second); + break; + case eClockEditStates.Second: + time = new DateTime(_Value.Year, _Value.Month, _Value.Day, _Value.Hour, _Value.Minute, GetSecondFromPoint(_EditLoc)); + break; + } + + return time; + } + + protected override void OnMouseUp(MouseEventArgs e) + { + if (_EditState != eClockEditStates.None) + { + _EditLoc = e.Location; + Value = GetCurrentMouseTime(); + _EditLoc = Point.Empty; + _EditState = eClockEditStates.None; + Cursor = Cursors.Default; + } + base.OnMouseUp(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + Graphics g; + RectangleF rect; + float bezelWidth; + + g = e.Graphics; + + TextRenderingHint textHint = g.TextRenderingHint; + SmoothingMode sm = g.SmoothingMode; + if (_AntiAlias) + { + g.TextRenderingHint = BarUtilities.AntiAliasTextRenderingHint; + g.SmoothingMode = SmoothingMode.AntiAlias; + } + + bezelWidth = _ClockStyleData.BezelWidth * (ClientRectangle.Width - 1); + rect = new RectangleF(ClientRectangle.X + bezelWidth, + ClientRectangle.Y + bezelWidth, + (ClientRectangle.Width - 1) - bezelWidth * 2.0f, + (ClientRectangle.Height - 1) - bezelWidth * 2.0f); + + + e.Graphics.TranslateTransform(rect.X + rect.Width * 0.5f, rect.Y + rect.Height * 0.5f); + switch (_IndicatorStyle) + { + case eClockIndicatorStyles.Ticks: + DrawTicks(g, rect); + break; + case eClockIndicatorStyles.Numbers: + DrawNumbers(g, rect); + break; + } + + DrawHands(g, rect, false); + DrawCap(g, rect); + DrawHands(g, rect, true); + + if (_ShowGlassOverlay) + DrawGlassOverlay(g, rect); + + g.TextRenderingHint = textHint; + g.SmoothingMode = sm; + } + + protected override void OnPaintBackground(PaintEventArgs pevent) + { + base.OnPaintBackground(pevent); + Graphics gfx; + RectangleF innerRect, outerRect; + GraphicsPath outerPath, innerPath; + Brush brush; + Pen pen; + RectangleF imageRect = new RectangleF(); + float aspect, bezelWidth; + float scaleFactor; + + gfx = pevent.Graphics; + gfx.SmoothingMode = _AntiAlias ? SmoothingMode.AntiAlias : SmoothingMode.Default; + + Rectangle clientRectangle = ClientRectangle; + if (_ClockStyleData.BezelColor.BorderWidth > 0) + { + int borderInflateSize = (int)((_ClockStyleData.BezelColor.BorderWidth * Math.Min(clientRectangle.Width, clientRectangle.Height)) / 2); + clientRectangle.Inflate(-borderInflateSize, -borderInflateSize); + } + + scaleFactor = Math.Min(clientRectangle.Width, clientRectangle.Height); + bezelWidth = _ClockStyleData.BezelWidth * (scaleFactor - 1); + + innerRect = new RectangleF(clientRectangle.X + bezelWidth, + clientRectangle.Y + bezelWidth, + (clientRectangle.Width - 1) - bezelWidth * 2.0f, + (clientRectangle.Height - 1) - bezelWidth * 2.0f); + outerRect = new RectangleF(clientRectangle.X, + clientRectangle.Y, + clientRectangle.Width - 1, + clientRectangle.Height - 1); + + outerPath = new GraphicsPath(); + innerPath = new GraphicsPath(); + + switch (_ClockStyleData.ClockShape) + { + case eClockShapes.Round: + outerPath.AddEllipse(outerRect); + outerPath.CloseAllFigures(); + innerPath.AddEllipse(innerRect); + innerPath.CloseAllFigures(); + break; + default: + outerPath.AddRectangle(outerRect); + innerPath.AddRectangle(innerRect); + break; + } + + + if (_ClockStyleData.FaceBackgroundImage != null) + { + gfx.SetClip(outerPath); + if (_ClockStyleData.FaceBackgroundImage.Width < _ClockStyleData.FaceBackgroundImage.Height) + aspect = (float)innerRect.Width / (float)_ClockStyleData.FaceBackgroundImage.Width; + else + aspect = (float)innerRect.Height / (float)_ClockStyleData.FaceBackgroundImage.Height; + imageRect.X = innerRect.X + ((innerRect.Width / 2.0f) - (aspect * _ClockStyleData.FaceBackgroundImage.Width) / 2.0f); + imageRect.Y = innerRect.Y + ((innerRect.Height / 2.0f) - (aspect * _ClockStyleData.FaceBackgroundImage.Height) / 2.0f); + imageRect.Width = aspect * _ClockStyleData.FaceBackgroundImage.Width; + imageRect.Height = aspect * _ClockStyleData.FaceBackgroundImage.Height; + gfx.DrawImage(_ClockStyleData.FaceBackgroundImage, imageRect); + + } + + gfx.ResetClip(); + gfx.SetClip(innerPath, CombineMode.Exclude); + brush = _ClockStyleData.BezelColor.GetBrush(outerPath); + gfx.FillPath(brush, outerPath); + brush.Dispose(); + if (_ClockStyleData.BezelColor.BorderWidth > 0) + { + pen = _ClockStyleData.BezelColor.GetBorderPen(scaleFactor, PenAlignment.Center); + gfx.DrawPath(pen, outerPath); + pen.Dispose(); + } + + gfx.ResetClip(); + if (_ClockStyleData.FaceBackgroundImage == null) + { + brush = _ClockStyleData.FaceColor.GetBrush(innerPath, new PointF(0.50f, 0.50f)); + gfx.FillPath(brush, innerPath); + brush.Dispose(); + } + if (_ClockStyleData.FaceColor.BorderWidth > 0) + { + pen = _ClockStyleData.FaceColor.GetBorderPen(scaleFactor, PenAlignment.Center); + gfx.DrawPath(pen, innerPath); + pen.Dispose(); + } + innerPath.Dispose(); + outerPath.Dispose(); + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + //if (Width < 100) + //{ + // Width = 100; + // Height = 100; + //} + //else + if (_LastSize.Width != Width) + Height = Width; + else + Width = Height; + + _LastSize = Size; + } + + /// + /// Renders the clock's center cap. + /// + /// Graphics object used for rendering. + /// Bounding rectangle. + protected virtual void DrawCap(Graphics gfx, RectangleF rect) + { + float scaleFactor; + GraphicsPath path; + RectangleF capRect; + Pen pen; + Brush brush; + float capSize; + scaleFactor = Math.Min(rect.Width, rect.Height); + + capSize = _ClockStyleData.CapSize * scaleFactor; + capRect = new RectangleF(-capSize / 2.0f, -capSize / 2.0f, capSize, capSize); + path = new GraphicsPath(); + path.AddEllipse(capRect); + + brush = _ClockStyleData.CapColor.GetBrush(path); + gfx.FillPath(brush, path); + if (_ClockStyleData.CapColor.BorderWidth > 0) + { + pen = _ClockStyleData.CapColor.GetBorderPen(scaleFactor, PenAlignment.Outset); + gfx.DrawPath(pen, path); + pen.Dispose(); + } + brush.Dispose(); + path.Dispose(); + } + + /// + /// Renders the clock's glass overlay. + /// + /// Graphics object used for rendering. + /// Bounding rectangle. + protected virtual void DrawGlassOverlay(Graphics gfx, RectangleF rect) + { + GraphicsState gState; + PathGradientBrush brush; + GraphicsPath path, brushPath; + PointF[] curvePoints; + float radius; + + gState = gfx.Save(); + rect.Width *= 0.95f; + rect.Height *= 0.95f; + rect.X = -rect.Width / 2.0f; + rect.Y = -rect.Height / 2.0f; + radius = Math.Min(rect.Width, rect.Height) / 2.0f; + + brushPath = new GraphicsPath(); + brushPath.AddEllipse(rect); + brush = new PathGradientBrush(brushPath); + brush.CenterPoint = new PointF(0.0f, 0.0f); + brush.CenterColor = Color.FromArgb(192, Color.White); + brush.SurroundColors = new Color[] { Color.FromArgb(64, Color.White) }; + + path = new GraphicsPath(); + path.AddArc(rect, 180, 180); + curvePoints = new PointF[5]; + curvePoints[0].X = -radius; + curvePoints[0].Y = 0.0f; + + curvePoints[1].X = -radius * 0.5f; + curvePoints[1].Y = -radius * 0.175f; + + curvePoints[2].X = 0.0f; + curvePoints[2].Y = -radius * 0.25f; + + curvePoints[3].X = radius * 0.5f; + curvePoints[3].Y = -radius * 0.175f; + + curvePoints[4].X = radius; + curvePoints[4].Y = 0.0f; + + path.AddCurve(curvePoints); + path.CloseAllFigures(); + + gfx.RotateTransform(_ClockStyleData.GlassAngle); + gfx.FillPath(brush, path); + + gfx.Restore(gState); + brush.Dispose(); + brushPath.Dispose(); + path.Dispose(); + + } + + private static float RoundToExactHour(float angle) + { + return (float)Math.Floor((angle / 30f)) * 30f; + } + /// + /// Renders the clock's hands. + /// + /// Graphics object used for rendering. + /// Bounding rectangle. + /// True if this is the rending pass after the cap has been rendered. + protected virtual void DrawHands(Graphics gfx, RectangleF rect, bool overCap) + { + GraphicsState gState; + GraphicsPath path; + Pen pen; + Brush brush; + float scaleFactor, angle; + + scaleFactor = Math.Min(rect.Width, rect.Height); + gState = gfx.Save(); + gfx.ResetTransform(); + + //Hour Hand + if (_ClockStyleData.HourHandStyle.DrawOverCap == overCap) + { + if (_EditState == eClockEditStates.Hour) + angle = (float)MathHelper.GetDegrees(GetAngleFromPoint(_EditLoc)) + 90.0f; + else + angle = (float)(_Value.TimeOfDay.TotalHours > 12 ? _Value.TimeOfDay.TotalHours - 12 : _Value.TimeOfDay.TotalHours) * 30.0f; + + // When clock is editable round up the angle to point at the hour exactly + if (_IsEditable && !_AutomaticMode) + { + angle = RoundToExactHour(angle); + } + path = _ClockStyleData.HourHandStyle.GenerateHandPath(rect, angle); + brush = _ClockStyleData.HourHandStyle.HandColor.GetBrush(path, _ClockStyleData.HourHandStyle.HandColor.BrushAngle + angle); + gfx.FillPath(brush, path); + if (_ClockStyleData.HourHandStyle.HandColor.BorderWidth > 0) + { + pen = _ClockStyleData.HourHandStyle.HandColor.GetBorderPen(scaleFactor, PenAlignment.Outset); + gfx.DrawPath(pen, path); + pen.Dispose(); + } + brush.Dispose(); + path.Dispose(); + } + + //Minute Hand + if (_ClockStyleData.MinuteHandStyle.DrawOverCap == overCap) + { + if (_EditState == eClockEditStates.Minute) + angle = (float)MathHelper.GetDegrees(GetAngleFromPoint(_EditLoc)) + 90.0f; + else + angle = (float)_Value.TimeOfDay.TotalMinutes * 6.0f; + path = _ClockStyleData.MinuteHandStyle.GenerateHandPath(rect, angle); + brush = _ClockStyleData.MinuteHandStyle.HandColor.GetBrush(path, _ClockStyleData.MinuteHandStyle.HandColor.BrushAngle + angle); + gfx.FillPath(brush, path); + if (_ClockStyleData.MinuteHandStyle.HandColor.BorderWidth > 0) + { + pen = _ClockStyleData.MinuteHandStyle.HandColor.GetBorderPen(scaleFactor, PenAlignment.Outset); + gfx.DrawPath(pen, path); + pen.Dispose(); + } + brush.Dispose(); + path.Dispose(); + } + + //Second Hand + if (_ShowSecondHand && _ClockStyleData.SecondHandStyle.DrawOverCap == overCap) + { + if (_EditState == eClockEditStates.Second) + angle = (float)MathHelper.GetDegrees(GetAngleFromPoint(_EditLoc)) + 90.0f; + else + angle = (float)_Value.TimeOfDay.Seconds * 6.0f; + path = _ClockStyleData.SecondHandStyle.GenerateHandPath(rect, angle); + brush = _ClockStyleData.SecondHandStyle.HandColor.GetBrush(path, _ClockStyleData.SecondHandStyle.HandColor.BrushAngle + angle); + gfx.FillPath(brush, path); + if (_ClockStyleData.SecondHandStyle.HandColor.BorderWidth > 0) + { + pen = _ClockStyleData.SecondHandStyle.HandColor.GetBorderPen(scaleFactor, PenAlignment.Outset); + gfx.DrawPath(pen, path); + pen.Dispose(); + } + brush.Dispose(); + path.Dispose(); + } + gfx.Restore(gState); + } + + /// + /// Renders the clock's numeric hour indicators. + /// + /// Graphics object used for rendering. + /// Bounding rectangle. + protected virtual void DrawNumbers(Graphics gfx, RectangleF rect) + { + PointF center, txtCenter; + float scaleFactor, radius, tickIncrement, angle; + Brush brush; + StringFormat strFormat; + Font fnt; + + strFormat = new StringFormat(); + strFormat.Alignment = StringAlignment.Center; + strFormat.LineAlignment = StringAlignment.Center; + + scaleFactor = Math.Min(rect.Width, rect.Height) / _BaseSize; + fnt = new Font(_ClockStyleData.NumberFont.FontFamily, _ClockStyleData.NumberFont.Size * scaleFactor, _ClockStyleData.NumberFont.Style, GraphicsUnit.Pixel); + center = new PointF(rect.X + rect.Width / 2.0f, rect.Y + rect.Height / 2.0f); + radius = (rect.Width / 2.0f) - (gfx.MeasureString("12", fnt).Height) / 1.25f; + tickIncrement = (float)MathHelper.GetRadians(30.0f); + angle = (float)MathHelper.GetRadians(-60.0f); + brush = new SolidBrush(_ClockStyleData.NumberColor); + + txtCenter = new PointF(); + for (int i = 1; i <= 12; i++) + { + txtCenter.X = (float)(radius * Math.Cos(angle)); + txtCenter.Y = (float)(radius * Math.Sin(angle)); + gfx.DrawString(i.ToString(), fnt, brush, txtCenter, strFormat); + angle += tickIncrement; + } + + brush.Dispose(); + fnt.Dispose(); + } + + /// + /// Renders the clock's tick hour/minute indicators. + /// + /// Graphics object used for rendering. + /// Bounding rectangle. + protected virtual void DrawTicks(Graphics gfx, RectangleF rect) + { + float scaleFactor; + PointF[] largePts, smallPts; + GraphicsState gState; + Brush largeBrush, smallBrush; + Pen largePen = null, smallPen = null; + GraphicsPath largePath, smallPath; + + scaleFactor = Math.Min(rect.Width, rect.Height); + + largePts = new PointF[4]; + largePts[0].X = (-_ClockStyleData.LargeTickWidth * 0.5f) * scaleFactor; + largePts[0].Y = -0.45f * scaleFactor; + + largePts[1].X = (-_ClockStyleData.LargeTickWidth * 0.5f) * scaleFactor; + largePts[1].Y = (-0.45f + _ClockStyleData.LargeTickLength) * scaleFactor; + + largePts[2].X = (_ClockStyleData.LargeTickWidth * 0.5f) * scaleFactor; + largePts[2].Y = (-0.45f + _ClockStyleData.LargeTickLength) * scaleFactor; + + largePts[3].X = (_ClockStyleData.LargeTickWidth * 0.5f) * scaleFactor; + largePts[3].Y = -0.45f * scaleFactor; + + smallPts = new PointF[4]; + smallPts[0].X = (-_ClockStyleData.SmallTickWidth * -0.5f) * scaleFactor; + smallPts[0].Y = -0.45f * scaleFactor; + + smallPts[1].X = (-_ClockStyleData.SmallTickWidth * -0.5f) * scaleFactor; + smallPts[1].Y = (-0.45f + _ClockStyleData.SmallTickLength) * scaleFactor; + + smallPts[2].X = (_ClockStyleData.SmallTickWidth * -0.5f) * scaleFactor; + smallPts[2].Y = (-0.45f + _ClockStyleData.SmallTickLength) * scaleFactor; + + smallPts[3].X = (_ClockStyleData.SmallTickWidth * -0.5f) * scaleFactor; + smallPts[3].Y = -0.45f * scaleFactor; + + largePath = new GraphicsPath(); + largePath.AddPolygon(largePts); + + smallPath = new GraphicsPath(); + smallPath.AddPolygon(smallPts); + + largeBrush = _ClockStyleData.LargeTickColor.GetBrush(largePath); + if (_ClockStyleData.LargeTickColor.BorderWidth > 0) + largePen = _ClockStyleData.LargeTickColor.GetBorderPen(scaleFactor, PenAlignment.Center); + + smallBrush = _ClockStyleData.LargeTickColor.GetBrush(largePath); + if (_ClockStyleData.SmallTickColor.BorderWidth > 0) + smallPen = _ClockStyleData.SmallTickColor.GetBorderPen(scaleFactor, PenAlignment.Center); + + gState = gfx.Save(); + for (int i = 0; i < 12; i++) + { + gfx.FillPolygon(largeBrush, largePts); + if (largePen != null) + gfx.DrawPolygon(largePen, largePts); + for (int j = 0; j < 4; j++) + { + gfx.RotateTransform(6); + gfx.FillPolygon(smallBrush, smallPts); + if (smallPen != null) + gfx.DrawPolygon(smallPen, smallPts); + } + gfx.RotateTransform(6); + } + gfx.Restore(gState); + + largePath.Dispose(); + smallPath.Dispose(); + largeBrush.Dispose(); + smallBrush.Dispose(); + if (largePen != null) + largePen.Dispose(); + if (smallPen != null) + smallPen.Dispose(); + } + + private float GetAngleFromPoint(PointF pt) + { + float angle; + PointF center = new PointF(ClientRectangle.X + ClientRectangle.Width / 2.0f, ClientRectangle.Y + ClientRectangle.Height / 2.0f); + pt.X -= center.X; + pt.Y -= center.Y; + angle = (float)Math.Atan2((double)(pt.Y), (double)(pt.X)); + return angle; + } + + private void UpdateAutomaticTime() + { + if (_TimeZoneInfo != null) + Value = DevComponents.Schedule.TimeZoneInfo.ConvertTime(DateTime.Now, _TimeZoneInfo); + else + Value = DateTime.Now; + } + + private void Timer_Tick(object sender, EventArgs e) + { + UpdateAutomaticTime(); + } + + private DevComponents.Schedule.TimeZoneInfo _TimeZoneInfo = null; + private string _TimeZone = string.Empty; + /// + /// Gets or sets the time-zone string identifier that is used to display the time when AutomaticMode=true and clock is displaying current time. + /// + [DefaultValue(""), Editor("DevComponents.DotNetBar.Design.TimeZoneSelectionEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Behavior"), Description("Indicates time-zone string identifier that is used to display the time when AutomaticMode=true and clock is displaying current time.")] + public string TimeZone + { + get { return _TimeZone; } + set + { + if (value != _TimeZone) + { + DevComponents.Schedule.TimeZoneInfo timeZoneInfo = null; + if (!string.IsNullOrEmpty(value)) + timeZoneInfo = DevComponents.Schedule.TimeZoneInfo.FindSystemTimeZoneById(value); + if (timeZoneInfo != null || string.IsNullOrEmpty(value)) + { + string oldValue = _TimeZone; + _TimeZone = value; + _TimeZoneInfo = timeZoneInfo; + OnTimeZoneChanged(oldValue, value); + } + } + } + } + /// + /// Called when TimeZone property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTimeZoneChanged(string oldValue, string newValue) + { + if (_AutomaticMode) + UpdateAutomaticTime(); + //OnPropertyChanged(new PropertyChangedEventArgs("TimeZone")); + } + + ///// + ///// Raises the SubPropertyChanged event. + ///// + ///// Event arguments + //public void OnSubPropertyChanged(DevComponents.Schedule.Model.SubPropertyChangedEventArgs e) + //{ + // if (SubPropertyChanged != null) + // SubPropertyChanged(this, e); + // Invalidate(); + //} + + #endregion + } + + /// + /// Enumeration containing the available hour/minute indicators. + /// + public enum eClockIndicatorStyles + { + /// + /// Control will use ticks for hour/minute indicators. + /// + Ticks, + + /// + /// Control will use numbers for hour indicators. + /// + Numbers + } + + /// + /// Enumeration containing the available mouse edit states. + /// + public enum eClockEditStates + { + /// + /// Control is not currently in an edit state. + /// + None, + + /// + /// Control is currently in an hour edit state. + /// + Hour, + + /// + /// Control is currently in an minute edit state. + /// + Minute, + + /// + /// Control is currently in an second edit state. + /// + Second + } + + /// + /// Provides event arguments for TimeValueChanging event. + /// + public class TimeValueChangingEventArgs : EventArgs + { + /// + /// Gets the current time represented by the control. + /// + public readonly DateTime Time; + /// + /// Initializes a new instance of the TimeValueChangingEventArgs class. + /// + /// + public TimeValueChangingEventArgs(DateTime time) + { + Time = time; + } + + } + /// + /// Defines delegate for TimeValueChanging event. + /// + /// Source of event. + /// Event arguments + public delegate void TimeValueChangingEventHandler(object sender, TimeValueChangingEventArgs e); +} diff --git a/PROMS/DotNetBar Source Code/AnalogClock/ClockHandStyleData.cs b/PROMS/DotNetBar Source Code/AnalogClock/ClockHandStyleData.cs new file mode 100644 index 00000000..5cb6fa93 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AnalogClock/ClockHandStyleData.cs @@ -0,0 +1,305 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Data storage class for clock hand visual style. + /// + [Description("Clock Hand Style"), + TypeConverterAttribute(typeof(ExpandableObjectConverter))] + public class ClockHandStyleData : INotifyPropertyChanged + { + private bool _DrawOverCap; + /// + /// Gets or sets a value indicating whether the hand is drawn over the cap. + /// + [DefaultValue(false), + Category("Appearance"), + Description("Indicates whether the hand is drawn over the cap.")] + public bool DrawOverCap + { + get { return _DrawOverCap; } + set { _DrawOverCap = value; } + } + + private void ColorPropertyChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + private ColorData _HandColor; + /// + /// Gets or sets the hand color data for this hand. + /// + [Category("Appearance"), + Description("The hand color data for this hand.")] + public ColorData HandColor + { + get { return _HandColor; } + set + { + if (value != _HandColor) + { + if (_HandColor != null) _HandColor.PropertyChanged -= ColorPropertyChanged; + _HandColor = value; + if (_HandColor != null) _HandColor.PropertyChanged += ColorPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("HandColor")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetHandColor() + { + HandColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f); + } + + private eHandStyles _HandStyle; + /// + /// Gets or sets the hand style for this clock hand. Default value is Style1. + /// + [DefaultValue(eHandStyles.Style1), + Category("Appearance"), + Description("The hand style for this clock hand.")] + public eHandStyles HandStyle + { + get { return _HandStyle; } + set + { + if (value != _HandStyle) + { + _HandStyle = value; + OnPropertyChanged(new PropertyChangedEventArgs("HandStyle")); + } + } + } + + private float _Length; + /// + /// Gets or sets the length of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle. Default value is 1.0. + /// + [DefaultValue(1.0f), + Category("Appearance"), + Description("The length of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle.")] + public float Length + { + get { return _Length; } + set + { + if (value != _Length) + { + _Length = value; + OnPropertyChanged(new PropertyChangedEventArgs("Length")); + } + } + } + + private float _Width; + /// + /// Gets or sets the width of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle. Default value is 0.1. + /// + [DefaultValue(0.1f), + Category("Appearance"), + Description("The width of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle.")] + public float Width + { + get { return _Width; } + set + { + if (value != _Width) + { + _Width = value; + OnPropertyChanged(new PropertyChangedEventArgs("Width")); + } + } + } + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Initializes a new instance of the ClockHand class. + /// + public ClockHandStyleData() + { + _DrawOverCap = false; + _HandColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f); + _HandStyle = eHandStyles.Style1; + _Length = 1.0f; + _Width = 0.1f; + } + + /// + /// Initializes a new instance of the ClockHand class. + /// + /// The hand style for this item. + /// The length of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle + /// The width of this clock hand as a percentage value ranging from 0.0 to 1.0, with 1.0 being half the width/height of the bounding rectangle. + public ClockHandStyleData(eHandStyles handStyle, float length, float width) + { + _DrawOverCap = false; + _HandColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f); + _HandStyle = handStyle; + _Length = length; + _Width = width; + } + + /// + /// Indicates whether the specified point is contained within the bounds of this hand. + /// + /// The bounding rectangle of the parent clock control. + /// The clockwise angle for this clock hand in degrees from the 12 o'clock position. + /// A Point that represents the point to test. + /// + public virtual bool ContainsPoint(RectangleF boundingRect, float angle, Point pt) + { + GraphicsPath path; + bool ret; + + path = GenerateHandPath(boundingRect, angle); + + ret = path.IsVisible(pt); + path.Dispose(); + return ret; + } + + /// + /// Generates a scaled and rotated graphics path based on the given style, rectangle and angle. + /// + /// The bounding rectangle of the parent clock control. + /// The clockwise angle for this clock hand in degrees from the 12 o'clock position. + /// + public GraphicsPath GenerateHandPath(RectangleF boundingRect, float angle) + { + GraphicsPath path = new GraphicsPath(); + RectangleF rect; + Matrix matrix; + float scaleFactor; + PointF[] pts; + + switch (_HandStyle) + { + case eHandStyles.Style1: + pts = new PointF[4]; + pts[0].X = -0.5f; + pts[0].Y = 0.0f; + + pts[1].X = -0.5f; + pts[1].Y = -1.0f; + + pts[2].X = 0.5f; + pts[2].Y = -1.0f; + + pts[3].X = 0.5f; + pts[3].Y = 0.0f; + path.AddPolygon(pts); + break; + case eHandStyles.Style2: + pts = new PointF[4]; + pts[0].X = -0.4f; + pts[0].Y = 0.25f; + + pts[1].X = -0.4f; + pts[1].Y = -1.0f; + + pts[2].X = 0.4f; + pts[2].Y = -1.0f; + + pts[3].X = 0.4f; + pts[3].Y = 0.25f; + path.AddPolygon(pts); + break; + case eHandStyles.Style3: + pts = new PointF[4]; + pts[0].X = -0.5f; + pts[0].Y = 0.0f; + + pts[1].X = -0.0125f; + pts[1].Y = -1.0f; + + pts[2].X = 0.0125f; + pts[2].Y = -1.0f; + + pts[3].X = 0.5f; + pts[3].Y = 0.0f; + + path.AddPolygon(pts); + break; + case eHandStyles.Style4: + path.FillMode = FillMode.Winding; + pts = new PointF[4]; + pts[0].X = -0.5f; + pts[0].Y = -0.05f; + + pts[1].X = -0.5f; + pts[1].Y = -1.0f; + + pts[2].X = 0.5f; + pts[2].Y = -1.0f; + + pts[3].X = 0.5f; + pts[3].Y = -0.05f; + path.AddPolygon(pts); + + rect = new RectangleF(-5.0f, -0.06f, 10.0f, 0.12f); + path.AddEllipse(rect); + break; + } + scaleFactor = Math.Min(boundingRect.Width, boundingRect.Height) / 2.0f; + matrix = new Matrix(); + matrix.Translate(boundingRect.X + boundingRect.Width * 0.5f, boundingRect.Y + boundingRect.Width * 0.5f); + matrix.Rotate(angle); + matrix.Scale(scaleFactor * Width, scaleFactor * Length); + path.Transform(matrix); + matrix.Dispose(); + return path; + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (PropertyChanged != null) + PropertyChanged(this, e); + } + } + + /// + /// Enumeration containing the available hand styles. + /// + public enum eHandStyles + { + /// + /// Style 1. + /// + Style1, + + /// + /// Style 2. + /// + Style2, + + /// + /// Style 3. + /// + Style3, + + /// + /// Style 4. + /// + Style4, + } + +} diff --git a/PROMS/DotNetBar Source Code/AnalogClock/ClockStyleData.cs b/PROMS/DotNetBar Source Code/AnalogClock/ClockStyleData.cs new file mode 100644 index 00000000..b15808eb --- /dev/null +++ b/PROMS/DotNetBar Source Code/AnalogClock/ClockStyleData.cs @@ -0,0 +1,659 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Data storage class for clock visual styles. + /// + [Description("Clock Style"), + TypeConverterAttribute(typeof(ExpandableObjectConverter))] + public class ClockStyleData : IDisposable, INotifyPropertyChanged + { + + private eClockStyles _Style; + /// + /// Gets or sets the PredefinedStyles value for this style. + /// + [Browsable(false)] + public eClockStyles Style + { + get { return _Style; } + set + { + if (value != _Style) + { + _Style = value; + OnPropertyChanged(new PropertyChangedEventArgs("Style")); + } + } + } + + + private eClockShapes _ClockShape; + /// + /// Gets or sets the clock shape value for this style. + /// + [DefaultValue(eClockShapes.Round), + Category("Appearance"), + Description("The clock shape for this style.")] + public eClockShapes ClockShape + { + get { return _ClockShape; } + set + { + if (value != _ClockShape) + { + _ClockShape = value; + OnPropertyChanged(new PropertyChangedEventArgs("ClockShape")); + } + } + } + + private void ColorPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (_Parent != null) _Parent.Invalidate(); + } + + private ColorData _BezelColor; + /// + /// Gets or sets the bezel color data for this style. + /// + [Category("Appearance"), + Description("The bezel color data for this style.")] + public ColorData BezelColor + { + get { return _BezelColor; } + set + { + if (value != _BezelColor) + { + if (_BezelColor != null) _BezelColor.PropertyChanged -= ColorPropertyChanged; + _BezelColor = value; + if (_BezelColor != null) _BezelColor.PropertyChanged += ColorPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("BezelColor")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBezelColor() + { + BezelColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(255, 255, 255), Color.FromArgb(152, 152, 152), Color.FromArgb(120, 120, 120), 1.0f, 45.0f); + } + + + private float _BezelWidth; + /// + /// Gets or sets the width of clock bezel as a percentage value ranging from 0.0 to 1.0. + /// + [DefaultValue(0.03f), + Category("Appearance"), + Description("The width of clock bezel as a percentage value ranging from 0.0 to 1.0.")] + public float BezelWidth + { + get { return _BezelWidth; } + set + { + if (value != _BezelWidth) + { + _BezelWidth = value; + OnPropertyChanged(new PropertyChangedEventArgs("BezelWidth")); + } + } + } + + private ColorData _FaceColor; + /// + /// Gets or sets the face color data for this style. + /// + [Category("Appearance"), + Description("The face color data for this style.")] + public ColorData FaceColor + { + get { return _FaceColor; } + set + { + if (value != _FaceColor) + { + if (_FaceColor != null) _FaceColor.PropertyChanged -= ColorPropertyChanged; + _FaceColor = value; + if (_FaceColor != null) _FaceColor.PropertyChanged += ColorPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("FaceColor")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFaceColor() + { + FaceColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(191, 204, 213), Color.FromArgb(255, 255, 255), Color.FromArgb(135, 145, 161), 1.0f, 45.0f); + } + + private Image _FaceBackgroundImage; + /// + /// Gets or sets the face background image for this style. + /// + [DefaultValue(null), + Category("Appearance"), + Description("The face background image for this style.")] + public Image FaceBackgroundImage + { + get { return _FaceBackgroundImage; } + set + { + if (value != _FaceBackgroundImage) + { + _FaceBackgroundImage = value; + OnPropertyChanged(new PropertyChangedEventArgs("FaceBackgroundImage")); + } + } + } + + private ClockHandStyleData _HourHandStyle; + /// + /// Gets or sets the hour hand style for this style. + /// + [Category("Appearance"), + Description("The hour hand style for this style.")] + public ClockHandStyleData HourHandStyle + { + get { return _HourHandStyle; } + set + { + if (value != _HourHandStyle) + { + if (_HourHandStyle != null) _HourHandStyle.PropertyChanged -= ColorPropertyChanged; + _HourHandStyle = value; + if (_HourHandStyle != null) _HourHandStyle.PropertyChanged += ColorPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("HourHandStyle")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetHourHandStyle() + { + HourHandStyle = new ClockHandStyleData(eHandStyles.Style1, 0.55f, 0.01f); + } + + private ClockHandStyleData _MinuteHandStyle; + /// + /// Gets or sets the minute hand style for this style. + /// + [Category("Appearance"), + Description("The minute hand style for this style.")] + public ClockHandStyleData MinuteHandStyle + { + get { return _MinuteHandStyle; } + set + { + if (value != _MinuteHandStyle) + { + if (_MinuteHandStyle != null) _MinuteHandStyle.PropertyChanged -= ColorPropertyChanged; + _MinuteHandStyle = value; + if (_MinuteHandStyle != null) _MinuteHandStyle.PropertyChanged += ColorPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("MinuteHandStyle")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetMinuteHandStyle() + { + MinuteHandStyle = new ClockHandStyleData(eHandStyles.Style1, 0.8f, 0.01f); + } + + + private ClockHandStyleData _SecondHandStyle; + /// + /// Gets or sets the second hand style for this style. + /// + [Category("Appearance"), + Description("The second hand style for this style.")] + public ClockHandStyleData SecondHandStyle + { + get { return _SecondHandStyle; } + set + { + if (value != _SecondHandStyle) + { + if (_SecondHandStyle != null) _SecondHandStyle.PropertyChanged -= ColorPropertyChanged; + _SecondHandStyle = value; + if (_SecondHandStyle != null) _SecondHandStyle.PropertyChanged += ColorPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("SecondHandStyle")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSecondHandStyle() + { + SecondHandStyle = new ClockHandStyleData(eHandStyles.Style2, 0.8f, 0.005f); + } + + + private ColorData _CapColor; + /// + /// Gets or sets the center cap color data for this style. + /// + [Category("Appearance"), + Description("The center cap color data for this style.")] + public ColorData CapColor + { + get { return _CapColor; } + set + { + if (value != _CapColor) + { + if (_CapColor != null) _CapColor.PropertyChanged -= ColorPropertyChanged; + _CapColor = value; + if (_CapColor != null) _CapColor.PropertyChanged += ColorPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("CapColor")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetCapColor() + { + CapColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f); + } + + private float _CapSize; + /// + /// Gets or sets the center cap diameter as a percentage value ranging from 0.0 to 1.0. + /// + [DefaultValue(0.03f), + Category("Appearance"), + Description("The center cap diameter as a percentage value ranging from 0.0 to 1.0.")] + public float CapSize + { + get { return _CapSize; } + set + { + if (value != _CapSize) + { + _CapSize = value; + OnPropertyChanged(new PropertyChangedEventArgs("CapSize")); + } + } + } + + private Color _NumberColor; + /// + /// Gets or sets the face number color for this style. + /// + [DefaultValue(typeof(Color), "139, 158, 168"), + Category("Appearance"), + Description("The face number color for this style.")] + public Color NumberColor + { + get { return _NumberColor; } + set + { + if (value != _NumberColor) + { + _NumberColor = value; + OnPropertyChanged(new PropertyChangedEventArgs("NumberColor")); + } + } + } + + private Font _NumberFont; + /// + /// Gets or sets the center cap color data for this style. + /// + [Category("Appearance"), + Description("The face number font for this style.")] + public Font NumberFont + { + get { return _NumberFont; } + set + { + if (value != _NumberFont) + { + _NumberFont = value; + OnPropertyChanged(new PropertyChangedEventArgs("NumberFont")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetNumberFont() + { + _NumberFont = new Font("Microsoft Sans Serif", 8, FontStyle.Regular, GraphicsUnit.Pixel); + } + + private ColorData _LargeTickColor; + /// + /// Gets or sets the large tick color data for this style. + /// + [Category("Appearance"), + Description("The large tick color data for this style.")] + public ColorData LargeTickColor + { + get { return _LargeTickColor; } + set + { + if (value != _LargeTickColor) + { + if (_LargeTickColor != null) _LargeTickColor.PropertyChanged -= ColorPropertyChanged; + _LargeTickColor = value; + if (_LargeTickColor != null) _LargeTickColor.PropertyChanged += ColorPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("LargeTickColor")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetLargeTickColor() + { + LargeTickColor = new ColorData(eBrushTypes.Centered, Color.FromArgb(122, 142, 154), Color.FromArgb(122, 142, 154), Color.FromArgb(255, 255, 255), 1.0f); + } + + private float _LargeTickLength; + /// + /// Gets or sets the large tick length as a percentage value ranging from 0.0 to 1.0. + /// + [DefaultValue(0.06f), + Category("Appearance"), + Description("The large tick length as a percentage value ranging from 0.0 to 1.0.")] + public float LargeTickLength + { + get { return _LargeTickLength; } + set + { + if (value != _LargeTickLength) + { + _LargeTickLength = value; + OnPropertyChanged(new PropertyChangedEventArgs("LargeTickLength")); + } + } + } + + private float _LargeTickWidth; + /// + /// Gets or sets the large tick width as a percentage value ranging from 0.0 to 1.0. + /// + [DefaultValue(0.02f), + Category("Appearance"), + Description("The large tick width as a percentage value ranging from 0.0 to 1.0.")] + public float LargeTickWidth + { + get { return _LargeTickWidth; } + set + { + if (value != _LargeTickWidth) + { + _LargeTickWidth = value; + OnPropertyChanged(new PropertyChangedEventArgs("LargeTickWidth")); + } + } + } + + private ColorData _SmallTickColor; + /// + /// Gets or sets the small tick color data for this style. + /// + [Category("Appearance"), + Description("The small tick color data for this style.")] + public ColorData SmallTickColor + { + get { return _SmallTickColor; } + set + { + if (value != _SmallTickColor) + { + if (_SmallTickColor != null) _SmallTickColor.PropertyChanged -= ColorPropertyChanged; + _SmallTickColor = value; + if (_SmallTickColor != null) _SmallTickColor.PropertyChanged += ColorPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("SmallTickColor")); + } + } + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSmallTickColor() + { + SmallTickColor = new ColorData(eBrushTypes.Centered, Color.FromArgb(122, 142, 154), Color.FromArgb(122, 142, 154), Color.FromArgb(255, 255, 255), 1.0f); + } + + private float _SmallTickLength; + /// + /// Gets or sets the small tick length as a percentage value ranging from 0.0 to 1.0. + /// + [DefaultValue(0.02f), + Category("Appearance"), + Description("The small tick length as a percentage value ranging from 0.0 to 1.0.")] + public float SmallTickLength + { + get { return _SmallTickLength; } + set + { + if (value != _SmallTickLength) + { + _SmallTickLength = value; + OnPropertyChanged(new PropertyChangedEventArgs("SmallTickLength")); + } + } + } + + private float _SmallTickWidth; + /// + /// Gets or sets the small tick width as a percentage value ranging from 0.0 to 1.0. + /// + [DefaultValue(0.02f), + Category("Appearance"), + Description("The small tick width as a percentage value ranging from 0.0 to 1.0.")] + public float SmallTickWidth + { + get { return _SmallTickWidth; } + set + { + if (value != _SmallTickWidth) + { + _SmallTickWidth = value; + OnPropertyChanged(new PropertyChangedEventArgs("SmallTickWidth")); + } + } + } + + private int _GlassAngle; + /// + /// Gets or sets the overlay glass angle, in degrees for this style. + /// + [DefaultValue(20), + Category("Appearance"), + Description("The overlay angle, in degrees for this style.")] + public int GlassAngle + { + get { return _GlassAngle; } + set + { + if (value != _GlassAngle) + { + _GlassAngle = value; + OnPropertyChanged(new PropertyChangedEventArgs("_GlassAngle")); + } + } + } + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Initializes a new instance of the ClockStyle class. + /// + public ClockStyleData() + { + LoadStyle(eClockStyles.Style1); + } + + private AnalogClockControl _Parent = null; + /// + /// Gets the parent of the style. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AnalogClockControl Parent + { + get { return _Parent; } + internal set { _Parent = value; } + } + + /// + /// Initializes a new instance of the ClockStyle class. + /// + /// Predefined style from the PredefinedStyles enum. + public ClockStyleData(eClockStyles style) + { + LoadStyle(style); + } + + /// + /// Initializes a new instance of the ClockStyle class. + /// + /// Predefined style from the PredefinedStyles enum. + public ClockStyleData(eClockStyles style, AnalogClockControl parent) + { + LoadStyle(style); + _Parent = parent; + } + + /// + /// Releases all resources used by the class. + /// + public void Dispose() + { + if (_FaceBackgroundImage != null) + _FaceBackgroundImage.Dispose(); + if (_NumberFont != null) + _NumberFont.Dispose(); + } + + /// + /// Loads a predefined style + /// + /// The predefined style to load. + private void LoadStyle(eClockStyles style) + { + _Style = style; + switch (style) + { + case eClockStyles.Style1: + case eClockStyles.Custom: + _ClockShape = eClockShapes.Round; + BezelColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(255, 255, 255), Color.FromArgb(152, 152, 152), Color.FromArgb(120, 120, 120), 0.01f); + _BezelWidth = 0.03f; + FaceColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(191, 204, 213), Color.FromArgb(255, 255, 255), Color.FromArgb(135, 145, 161), 0.01f, 45.0f); + _FaceBackgroundImage = null; + HourHandStyle = new ClockHandStyleData(eHandStyles.Style1, 0.55f, 0.015f); + MinuteHandStyle = new ClockHandStyleData(eHandStyles.Style1, 0.8f, 0.01f); + SecondHandStyle = new ClockHandStyleData(eHandStyles.Style2, 0.8f, 0.005f); + CapColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(109, 127, 138), Color.FromArgb(109, 127, 138), Color.FromArgb(128, 109, 127, 138), 0.01f); + _CapSize = 0.03f; + _NumberColor = Color.FromArgb(139, 158, 168); + _NumberFont = new Font("Microsoft Sans Serif", 12, FontStyle.Regular, GraphicsUnit.Pixel); + LargeTickColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(122, 142, 154), Color.FromArgb(122, 142, 154), Color.FromArgb(128, 255, 255, 255), 0.01f); + _LargeTickLength = 0.06f; + _LargeTickWidth = 0.02f; + SmallTickColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(122, 142, 154), Color.FromArgb(122, 142, 154), Color.FromArgb(128, 255, 255, 255), 0.01f); + _SmallTickLength = 0.02f; + _SmallTickWidth = 0.02f; + _GlassAngle = -20; + break; + case eClockStyles.Style2: + _ClockShape = eClockShapes.Round; + BezelColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(80, 80, 80), Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 0), 0.0f, 90.0f); + _BezelWidth = 0.03f; + FaceColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(225, 225, 225), Color.FromArgb(240, 240, 240), Color.FromArgb(0, 0, 0), 0.0f, 90.0f); + _FaceBackgroundImage = null; + HourHandStyle = new ClockHandStyleData(eHandStyles.Style3, 0.45f, 0.175f); + HourHandStyle.HandColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(0, 0, 0), Color.FromArgb(80, 80, 80), Color.FromArgb(64, 0, 0, 0), 0.01f, 90.0f); + MinuteHandStyle = new ClockHandStyleData(eHandStyles.Style3, 0.75f, 0.175f); + MinuteHandStyle.HandColor = new ColorData(eBrushTypes.Linear, Color.FromArgb(0, 0, 0), Color.FromArgb(80, 80, 80), Color.FromArgb(64, 0, 0, 0), 0.01f, 90.0f); + SecondHandStyle = new ClockHandStyleData(eHandStyles.Style4, 0.9f, 0.01f); + SecondHandStyle.HandColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(255, 0, 0), Color.FromArgb(255, 0, 0), Color.FromArgb(128, 192, 0, 0), 0.01f); + _SecondHandStyle.DrawOverCap = true; + CapColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(255, 255, 255), Color.FromArgb(255, 255, 255), Color.FromArgb(223, 0, 0, 0), 0.01f); + _CapSize = 0.1f; + _NumberColor = Color.FromArgb(0, 0, 0); + _NumberFont = new Font("Trebuchet MS", 12, FontStyle.Regular, GraphicsUnit.Pixel); + LargeTickColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 0), Color.FromArgb(64, 0, 0, 0), 0.01f); + _LargeTickLength = 0.06f; + _LargeTickWidth = 0.01f; + SmallTickColor = new ColorData(eBrushTypes.Solid, Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 0), Color.FromArgb(64, 0, 0, 0), 0.01f); + _SmallTickLength = 0.01f; + _SmallTickWidth = 0.01f; + _GlassAngle = 0; + break; + } + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (PropertyChanged != null) + PropertyChanged(this, e); + if (_Parent != null) _Parent.Invalidate(); + } + } + + /// + /// Enumeration containing the predefined clock styles. + /// + public enum eClockStyles + { + /// + /// Style 1. Default style, + /// + Style1, + + /// + /// Style 2. + /// + Style2, + + /// + /// No predefined style. + /// + Custom + } + + /// + /// Enumeration containing the predefined clock shapes. + /// + public enum eClockShapes + { + /// + /// Round clock shape. + /// + Round + } +} diff --git a/PROMS/DotNetBar Source Code/AnalogClock/ColorData.cs b/PROMS/DotNetBar Source Code/AnalogClock/ColorData.cs new file mode 100644 index 00000000..b7031d9e --- /dev/null +++ b/PROMS/DotNetBar Source Code/AnalogClock/ColorData.cs @@ -0,0 +1,442 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Data storage and utility class for defining gradient colors. + /// + [Description("Color Data Class"), + TypeConverterAttribute(typeof(ExpandableObjectConverter))] + public class ColorData : INotifyPropertyChanged + { + private Color _BorderColor; + /// + /// Gets or sets the border color for this item. Default value is white. + /// + [DefaultValue(typeof(Color), "255, 255, 255"), + Category("Appearance"), + Description("The border color for this item.")] + public Color BorderColor + { + get { return _BorderColor; } + set + { + if (value != _BorderColor) + { + _BorderColor = value; + OnPropertyChanged(new PropertyChangedEventArgs("BorderColor")); + } + } + } + + private float _BorderWidth; + /// + /// Gets or sets the border width for this item. Default value is 0. + /// + [DefaultValue(0.0f), + Category("Appearance"), + Description("The border width for this item.")] + public float BorderWidth + { + get { return _BorderWidth; } + set + { + if (value != _BorderWidth) + { + _BorderWidth = value; + OnPropertyChanged(new PropertyChangedEventArgs("BorderWidth")); + } + } + } + + private float _BrushAngle; + /// + /// Gets or sets the brush angle for this item. Only applies to Linear and Reflected brush types. Default value is 0. + /// + [DefaultValue(0.0f), + Category("Appearance"), + Description("The brush angle for this item. Only applies to Linear and Reflected brush types.")] + public float BrushAngle + { + get { return _BrushAngle; } + set + { + if (value != _BrushAngle) + { + _BrushAngle = value; + OnPropertyChanged(new PropertyChangedEventArgs("BrushAngle")); + } + } + } + + private float _BrushSBSFocus; + /// + /// Gets or sets the brush SigmaBellShape focus for this item. Only applies to Reflected brush types. Default value is 0.5. + /// + [DefaultValue(0.5f), + Category("Appearance"), + Description("The brush SigmaBellShape focus for this item. Only applies to Linear and Reflected brush types.")] + public float BrushSBSFocus + { + get { return _BrushSBSFocus; } + set + { + if (value != _BrushSBSFocus) + { + _BrushSBSFocus = value; + OnPropertyChanged(new PropertyChangedEventArgs("BrushSBSFocus")); + } + } + } + + private float _BrushSBSScale; + /// + /// Gets or sets the brush SigmaBellShape scale for this item. Only applies to Reflected brush types. Default value is 0.5. + /// + [DefaultValue(0.5f), + Category("Appearance"), + Description("The brush SigmaBellShape scale for this item. Only applies to Linear and Reflected brush types.")] + public float BrushSBSScale + { + get { return _BrushSBSScale; } + set + { + if (value != _BrushSBSScale) + { + _BrushSBSScale = value; + OnPropertyChanged(new PropertyChangedEventArgs("BrushSBSScale")); + } + } + } + + private eBrushTypes _BrushType; + /// + /// Gets or sets the brush type for this item. Default value is Solid. + /// + [DefaultValue(eBrushTypes.Solid), + Category("Appearance"), + Description("The brush type for this item.")] + public eBrushTypes BrushType + { + get { return _BrushType; } + set + { + if (value != _BrushType) + { + _BrushType = value; + OnPropertyChanged(new PropertyChangedEventArgs("BrushType")); + } + } + } + + private Color _Color1; + /// + /// Gets or sets the first color for this item. Default value is white. + /// + [DefaultValue(typeof(Color), "255, 255, 255"), + Category("Appearance"), + Description("The first color for this item.")] + public Color Color1 + { + get { return _Color1; } + set + { + if (value != _Color1) + { + _Color1 = value; + OnPropertyChanged(new PropertyChangedEventArgs("Color1")); + } + } + } + + private Color _Color2; + /// + /// Gets or sets the second color for this item. Default value is white. + /// + [DefaultValue(typeof(Color), "255, 255, 255"), + Category("Appearance"), + Description("The second color for this item.")] + public Color Color2 + { + get { return _Color2; } + set + { + if (value != _Color2) + { + _Color2 = value; + OnPropertyChanged(new PropertyChangedEventArgs("Color2")); + } + } + } + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Creates new instance of the object. + /// + public ColorData() + { + LoadData(eBrushTypes.Solid, Color.White, Color.White, Color.White, 0.0f, 0.0f, 0.5f, 1.0f); + } + + /// + /// Creates new instance of the object. + /// + /// The first color for this entry. + /// The second color for this entry. + public ColorData(eBrushTypes brushType, Color color1, Color color2) + { + LoadData(brushType, color1, color2, Color.White, 0.0f, 0.0f, 0.5f, 1.0f); + } + + /// + /// Creates new instance of the object. + /// + /// The first color for this entry. + /// The second color for this entry. + /// The border color for this entry. + /// The border width for this entry. + public ColorData(eBrushTypes brushType, Color color1, Color color2, Color borderColor, float borderWidth) + { + LoadData(brushType, color1, color2, borderColor, borderWidth, 0.0f, 0.5f, 1.0f); + } + + /// + /// Creates new instance of the object. + /// + /// The first color for this entry. + /// The second color for this entry. + /// The border color for this entry. + /// The border width for this entry. + /// The gradient angle. + public ColorData(eBrushTypes brushType, Color color1, Color color2, Color borderColor, float borderWidth, float brushAngle) + { + LoadData(brushType, color1, color2, borderColor, borderWidth, brushAngle, 0.5f, 1.0f); + } + + /// + /// Creates new instance of the object. + /// + /// The first color for this entry. + /// The second color for this entry. + /// The border color for this entry. + /// The border width for this entry. + /// The focus for the SigmaBellShape. + /// The scale for the SigmaBellShape. + public ColorData(eBrushTypes brushType, Color color1, Color color2, Color borderColor, float borderWidth, float brushSBSFocus, float brushSBSScale) + { + LoadData(brushType, color1, color2, borderColor, borderWidth, 0.0f, brushSBSFocus, brushSBSScale); + } + + /// + /// Loads data into the class, called by constructors. + /// + /// The first color for this entry. + /// The second color for this entry. + /// The border color for this entry. + /// The border width for this entry. + /// The focus for the SigmaBellShape. + /// The scale for the SigmaBellShape. + protected void LoadData(eBrushTypes brushType, Color color1, Color color2, Color borderColor, float borderWidth, float brushAngle, float brushSBSFocus, float brushSBSScale) + { + _BorderColor = borderColor; + _BorderWidth = borderWidth; + _Color1 = color1; + _Color2 = color2; + _BrushType = brushType; + _BrushAngle = brushAngle; + _BrushSBSFocus = brushSBSFocus; + _BrushSBSScale = brushSBSScale; + } + + /// + /// Creates Pen object using the BorderColor and BorderWidth properties. + /// + public Pen GetBorderPen(float scaleFactor, PenAlignment penAlignment) + { + Pen pen = new Pen(_BorderColor, (float)Math.Round(_BorderWidth * scaleFactor, 0)); + pen.Alignment = penAlignment; + return pen; + } + + /// + /// Creates a brush of the type specified by BrushType. + /// + /// The graphics path used to construct the brush. + public Brush GetBrush(GraphicsPath path) + { + return GetBrush(path, new PointF(0.5f, 0.5f), _BrushAngle); + } + + /// + /// Creates a brush of the type specified by BrushType. + /// + /// The graphics path used to construct the brush. + /// The angle used for the gradients, allowing an override of BrushAngle + public Brush GetBrush(GraphicsPath path, float angle) + { + return GetBrush(path, new PointF(0.5f, 0.5f), angle); + } + + /// + /// Creates a brush of the type specified by BrushType. + /// + /// The graphics path used to construct the brush. + /// The center point of the gradient as a percentage value typically ranging from 0.0 to 1.0. + public Brush GetBrush(GraphicsPath path, PointF center) + { + return GetBrush(path, center, _BrushAngle); + } + + /// + /// Creates a brush of the type specified by BrushType. + /// + /// The graphics path used to construct the brush. + /// The center point of the gradient as a percentage value typically ranging from 0.0 to 1.0. + /// The angle used for the gradients, allowing an override of BrushAngle + public Brush GetBrush(GraphicsPath path, PointF center, float angle) + { + RectangleF rect; + switch (_BrushType) + { + case eBrushTypes.Solid: + return new SolidBrush(_Color1); + case eBrushTypes.Linear: + path.Flatten(); + rect = path.GetBounds(); + if (rect.Width > 0.0f && rect.Height > 0.0f) + return new LinearGradientBrush(path.GetBounds(), _Color1, _Color2, angle, false); + else + return null; + case eBrushTypes.Reflected: + LinearGradientBrush lBrush = new LinearGradientBrush(path.GetBounds(), _Color1, _Color2, angle, false); + lBrush.SetSigmaBellShape(_BrushSBSFocus, _BrushSBSScale); + return lBrush; + case eBrushTypes.Centered: + PointF pt = new PointF(); + rect = path.GetBounds(); + PathGradientBrush pBrush = new PathGradientBrush(path); + pt.X = rect.X + rect.Width * center.X; + pt.Y = rect.Y + rect.Height * center.Y; + pBrush.CenterPoint = pt; + pBrush.CenterColor = _Color1; + pBrush.SurroundColors = new Color[] { _Color2 }; + return pBrush; + default: + return new SolidBrush(_Color1); + } + } + + /// + /// Creates SolidBrushObject using Color1. + /// + public Brush GetSolidBrush() + { + return new SolidBrush(_Color1); + } + + /// + /// Creates a LinearGradientBrush object. + /// + /// The graphics path used to construct the brush. + /// The gradient angle. + public LinearGradientBrush GetLinearBrush(GraphicsPath path, int angle) + { + return new LinearGradientBrush(path.GetBounds(), _Color1, _Color2, angle, false); + } + + /// + /// Creates a PathGradientBrush object. + /// + /// The graphics path used to construct the brush. + /// The center point of the gradient. + public PathGradientBrush GetCenteredBrush(GraphicsPath path, PointF center) + { + PathGradientBrush brush; + + brush = new PathGradientBrush(path); + brush.CenterPoint = center; + brush.CenterColor = _Color1; + brush.SurroundColors = new Color[] { _Color2 }; + + return brush; + } + + /// + /// Creates a LinearGradientBrush object. + /// + /// The graphics path used to construct the brush. + /// The gradient angle. + public LinearGradientBrush GetReflectedBrush(GraphicsPath path, int angle) + { + return GetReflectedBrush(path, angle, 0.5f, 1.0f); + } + + /// + /// Creates a LinearGradientBrush object. + /// + /// The graphics path used to construct the brush. + /// The gradient angle. + /// The focus for the SigmaBellShape. + public LinearGradientBrush GetReflectedBrush(GraphicsPath path, int angle, float focus) + { + return GetReflectedBrush(path, angle, focus, 1.0f); + } + + /// + /// Creates a LinearGradientBrush object. + /// + /// The graphics path used to construct the brush. + /// The gradient angle. + /// The focus for the SigmaBellShape. + /// The scale for the SigmaBellShape. + public LinearGradientBrush GetReflectedBrush(GraphicsPath path, int angle, float focus, float scale) + { + LinearGradientBrush brush = new LinearGradientBrush(path.GetBounds(), _Color1, _Color2, angle, false); + brush.SetSigmaBellShape(focus, scale); + return brush; + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (PropertyChanged != null) + PropertyChanged(this, e); + } + } + + /// + /// Enumeration containing predefined brush types for the ColorData class. + /// + public enum eBrushTypes + { + /// + /// Solid brush. + /// + Solid, + /// + /// Linear gradient brush. + /// + Linear, + + /// + /// Centered path gradient brush. + /// + Centered, + + /// + /// Reflected linear gradient brush. + /// + Reflected + } + +} diff --git a/PROMS/DotNetBar Source Code/AnalogClock/MathHelper.cs b/PROMS/DotNetBar Source Code/AnalogClock/MathHelper.cs new file mode 100644 index 00000000..cf4d9307 --- /dev/null +++ b/PROMS/DotNetBar Source Code/AnalogClock/MathHelper.cs @@ -0,0 +1,30 @@ +using System; + +namespace DevComponents.DotNetBar +{ + /// + /// Math helper class + /// + internal static class MathHelper + { + /// + /// Converts radians to degrees. + /// + /// Value to be converted in radians. + /// Converted value in degrees. + public static double GetDegrees(double radians) + { + return radians * (180.0 / Math.PI); + } + + /// + /// Converts degrees to radians. + /// + /// Value to be converted in degrees. + /// Converted value in radians. + public static double GetRadians(double degrees) + { + return degrees * (Math.PI / 180.0); + } + } +} diff --git a/PROMS/DotNetBar Source Code/Animation/Animation.cs b/PROMS/DotNetBar Source Code/Animation/Animation.cs new file mode 100644 index 00000000..f3776b70 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Animation/Animation.cs @@ -0,0 +1,772 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.DotNetBar; +using System.Drawing; + +namespace DevComponents.DotNetBar.Animation +{ + internal abstract class Animation : Component + { + #region Events + /// + /// Occurs after animation has completed. + /// + public event EventHandler AnimationCompleted; + /// + /// Raises AnimationCompleted event. + /// + /// Provides event arguments. + protected virtual void OnAnimationCompleted(EventArgs e) + { + EventHandler handler = AnimationCompleted; + if (handler != null) + handler(this, e); + } + #endregion + + #region Constructor + private BackgroundWorker _Worker = null; + private AnimationEasing _EasingFunction = AnimationEasing.EaseOutQuad; + private double _Duration = 300; + private EasingFunctionDelegate[] _AnimationFunctions; + private List _AnimationList = new List(); + + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public Animation(AnimationEasing animationEasing, int animationDuration) + : + this(new AnimationRequest[0], animationEasing, animationDuration) + { + } + + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public Animation(AnimationRequest animationRequest, AnimationEasing animationEasing, int animationDuration) + : + this(new AnimationRequest[] { animationRequest }, animationEasing, animationDuration) + { + } + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public Animation(AnimationRequest[] animationRequests, AnimationEasing animationEasing, int animationDuration) + { + if (animationRequests != null && animationRequests.Length > 0) + _AnimationList.AddRange(animationRequests); + _EasingFunction = animationEasing; + _Duration = (int)animationDuration; + InitializeAnimationFunctions(); + } + + private void InitializeAnimationFunctions() + { + _AnimationFunctions = new EasingFunctionDelegate[28]; + _AnimationFunctions[(int)AnimationEasing.EaseInBounce] = new EasingFunctionDelegate(EaseInBounce); + _AnimationFunctions[(int)AnimationEasing.EaseInCirc] = new EasingFunctionDelegate(EaseInCirc); + _AnimationFunctions[(int)AnimationEasing.EaseInCubic] = new EasingFunctionDelegate(EaseInCubic); + _AnimationFunctions[(int)AnimationEasing.EaseInElastic] = new EasingFunctionDelegate(EaseInElastic); + _AnimationFunctions[(int)AnimationEasing.EaseInExpo] = new EasingFunctionDelegate(EaseInExpo); + _AnimationFunctions[(int)AnimationEasing.EaseInOutBounce] = new EasingFunctionDelegate(EaseInOutBounce); + _AnimationFunctions[(int)AnimationEasing.EaseInOutCirc] = new EasingFunctionDelegate(EaseInOutCirc); + _AnimationFunctions[(int)AnimationEasing.EaseInOutCubic] = new EasingFunctionDelegate(EaseInOutCubic); + _AnimationFunctions[(int)AnimationEasing.EaseInOutElastic] = new EasingFunctionDelegate(EaseInOutElastic); + _AnimationFunctions[(int)AnimationEasing.EaseInOutExpo] = new EasingFunctionDelegate(EaseInOutExpo); + _AnimationFunctions[(int)AnimationEasing.EaseInOutQuad] = new EasingFunctionDelegate(EaseInOutQuad); + _AnimationFunctions[(int)AnimationEasing.EaseInOutQuart] = new EasingFunctionDelegate(EaseInOutQuart); + _AnimationFunctions[(int)AnimationEasing.EaseInOutQuint] = new EasingFunctionDelegate(EaseInOutQuint); + _AnimationFunctions[(int)AnimationEasing.EaseInOutSine] = new EasingFunctionDelegate(EaseInOutSine); + _AnimationFunctions[(int)AnimationEasing.EaseInQuad] = new EasingFunctionDelegate(EaseInQuad); + _AnimationFunctions[(int)AnimationEasing.EaseInQuart] = new EasingFunctionDelegate(EaseInQuart); + _AnimationFunctions[(int)AnimationEasing.EaseInQuint] = new EasingFunctionDelegate(EaseInQuint); + _AnimationFunctions[(int)AnimationEasing.EaseInSine] = new EasingFunctionDelegate(EaseInSine); + _AnimationFunctions[(int)AnimationEasing.EaseOutBounce] = new EasingFunctionDelegate(EaseOutBounce); + _AnimationFunctions[(int)AnimationEasing.EaseOutCirc] = new EasingFunctionDelegate(EaseOutCirc); + _AnimationFunctions[(int)AnimationEasing.EaseOutCubic] = new EasingFunctionDelegate(EaseOutCubic); + _AnimationFunctions[(int)AnimationEasing.EaseOutElastic] = new EasingFunctionDelegate(EaseOutElastic); + _AnimationFunctions[(int)AnimationEasing.EaseOutExpo] = new EasingFunctionDelegate(EaseOutExpo); + _AnimationFunctions[(int)AnimationEasing.EaseOutQuad] = new EasingFunctionDelegate(EaseOutQuad); + _AnimationFunctions[(int)AnimationEasing.EaseOutQuart] = new EasingFunctionDelegate(EaseOutQuart); + _AnimationFunctions[(int)AnimationEasing.EaseOutQuint] = new EasingFunctionDelegate(EaseOutQuint); + _AnimationFunctions[(int)AnimationEasing.EaseOutSine] = new EasingFunctionDelegate(EaseOutSine); + _AnimationFunctions[(int)AnimationEasing.Linear] = new EasingFunctionDelegate(Linear); + + } + #endregion + + #region Implementation + private bool _AutoDispose = false; + /// + /// Gets or sets whether animation is auto-disposed once its completed. Default value is false. + /// + public bool AutoDispose + { + get { return _AutoDispose; } + set + { + _AutoDispose = value; + } + } + + public List Animations + { + get + { + return _AnimationList; + } + } + + protected override void Dispose(bool disposing) + { + //Console.WriteLine("{0} Animation DISPOSED", DateTime.Now); + Stop(); + _IsDisposed = true; + base.Dispose(disposing); + } + + private bool _IsDisposed = false; + public bool IsDisposed + { + get { return _IsDisposed; } + internal set + { + _IsDisposed = value; + } + } + + /// + /// Stops animation if one is currently running. + /// + public void Stop() + { + BackgroundWorker worker = _Worker; + if (worker != null) + { + worker.DoWork -= new DoWorkEventHandler(WorkerDoWork); + worker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(RunWorkerCompleted); + worker.CancelAsync(); + worker.Dispose(); + _Worker = null; + } + } + + public void Start() + { + Start(_AnimationList.ToArray()); + } + + protected void Start(AnimationRequest[] requests) + { + if (_Worker != null) + throw new InvalidOperationException("Animation is already running animations"); + //Console.WriteLine("{0} Animation Started", DateTime.Now); + _IsCompleted = false; + _Worker = new BackgroundWorker(); + _Worker.WorkerSupportsCancellation = true; + _Worker.DoWork += new DoWorkEventHandler(WorkerDoWork); + _Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted); + _Worker.RunWorkerAsync(requests); + } + + private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + //Console.WriteLine(string.Format("{0} RunWorkerCompleted", DateTime.Now)); + BackgroundWorker worker = _Worker; + _Worker = null; + if (worker != null) + { + worker.DoWork -= new DoWorkEventHandler(WorkerDoWork); + worker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(RunWorkerCompleted); + worker.Dispose(); + } + + _IsCompleted = true; + OnAnimationCompleted(EventArgs.Empty); + + if (_AutoDispose) + this.Dispose(); + } + + protected virtual void SetTargetPropertyValue(object target, PropertyInfo property, object value) + { + Control c = target as Control; + if (c != null) + { + c.Invoke(new MethodInvoker(delegate + { + property.SetValue(target, value, null); + if (c.Parent != null) + c.Parent.Update(); + else + c.Update(); + })); + } + else if (target is BaseItem) + { + if (_AnimationUpdateControl != null) + _AnimationUpdateControl.Invoke(new MethodInvoker(delegate { property.SetValue(target, value, null); if (value is Rectangle) _AnimationUpdateControl.Invalidate(); })); + else + { + if (target is DevComponents.DotNetBar.Metro.MetroTileItem && property.Name == "CurrentFrameOffset") + ((DevComponents.DotNetBar.Metro.MetroTileItem)target).CurrentFrameOffset = (int)value; + else + property.SetValue(target, value, null); + } + } + else + { + property.SetValue(target, value, null); + } + } + protected abstract object GetPropertyValueCorrectType(double value); + + protected virtual void WorkerDoWork(object sender, DoWorkEventArgs e) + { + AnimationRequest[] requests = (AnimationRequest[])e.Argument; + double elapsedTime = 0; + DateTime startTime = DateTime.UtcNow; + double duration = _Duration; + + bool firstPass = true; + + if (_FixedStepCount <= 0) + { + while (elapsedTime <= duration) + { + try + { + foreach (AnimationRequest request in requests) + { + double toValue = request.GetToValue(); + double fromValue = request.GetFromValue(); + double change = toValue - fromValue; + + if (firstPass) + SetTargetPropertyValue(request.Target, request.Property, request.From); + + double r = _AnimationFunctions[(int)_EasingFunction](elapsedTime, fromValue, change, duration); + if (change < 0 && r < toValue || change > 0 && r > toValue) { r = toValue; e.Cancel = true; break; } + if (change < 0 && r > fromValue || change > 0 && r < fromValue) r = fromValue; + + SetTargetPropertyValue(request.Target, request.Property, GetPropertyValueCorrectType(r)); + elapsedTime = DateTime.UtcNow.Subtract(startTime).TotalMilliseconds; + if (e.Cancel) break; + } + + if (e.Cancel) break; + + ExecuteStepUpdateMethod(); + + if (_AnimationUpdateControl != null) + { + if (_AnimationUpdateControl.InvokeRequired) + _AnimationUpdateControl.BeginInvoke(new MethodInvoker(delegate { _AnimationUpdateControl.Update(); })); + else + _AnimationUpdateControl.Update(); + } + if (e.Cancel) break; + firstPass = false; + } + catch (TargetInvocationException exc) + { + if (exc.InnerException is ObjectDisposedException) // Stop work if target has been disposed + return; + throw; + } + } + } + else + { + try + { + for (int i = 0; i < _FixedStepCount; i++) + { + foreach (AnimationRequest request in requests) + { + double toValue = request.GetToValue(); + double fromValue = request.GetFromValue(); + double change = toValue - fromValue; + double step = change / _FixedStepCount; + + if (firstPass) + SetTargetPropertyValue(request.Target, request.Property, request.From); + + double r = fromValue + step * (i + 1); + if (change < 0 && r < toValue || change > 0 && r > toValue) { r = toValue; e.Cancel = true; break; } + if (change < 0 && r > fromValue || change > 0 && r < fromValue) r = fromValue; + + SetTargetPropertyValue(request.Target, request.Property, GetPropertyValueCorrectType(r)); + if (e.Cancel) break; + if (_Duration > 0) + { + try + { + using ( + System.Threading.ManualResetEvent wait = + new System.Threading.ManualResetEvent(false)) + wait.WaitOne((int) _Duration); + + //System.Threading.Thread.Sleep((int)_Duration); + } + catch + { + break; + } + + } + } + + if (e.Cancel) break; + + ExecuteStepUpdateMethod(); + + if (_AnimationUpdateControl != null) + _AnimationUpdateControl.Update(); + if (e.Cancel) break; + firstPass = false; + } + } + catch (TargetInvocationException exc) + { + if (exc.InnerException is ObjectDisposedException) // Stop work if target has been disposed + return; + throw; + } + } + // Make sure final to value is assigned + foreach (AnimationRequest request in requests) + { + try + { + SetTargetPropertyValue(request.Target, request.Property, request.To); + } + catch (TargetInvocationException exc) + { + if (exc.InnerException is ObjectDisposedException) // Stop work if target has been disposed + continue; + throw; + } + } + //System.Diagnostics.Debug.WriteLine(string.Format("{0} WorkerDoWork DONE", DateTime.Now)); + } + private bool _IsCompleted; + /// + /// Gets whether animation run is complete. + /// + public bool IsCompleted + { + get { return _IsCompleted; } + } + /// + /// Gets the animation duration in milliseconds. + /// + public double Duration + { + get { return _Duration; } + internal set + { + _Duration = value; + } + } + /// + /// Gets the animation easing function. + /// + public AnimationEasing EasingFunction + { + get + { + return _EasingFunction; + } + } + + protected EasingFunctionDelegate[] AnimationFunctions + { + get + { + return _AnimationFunctions; + } + } + + protected virtual void ExecuteStepUpdateMethod() + { + if (_StepUpdateMethod != null) + _StepUpdateMethod.DynamicInvoke(null); + } + + private Delegate _StepUpdateMethod = null; + /// + /// Sets the method which is called each time value on target object property is set. This method may execute the visual updates on animation client. + /// + /// Method to call + public void SetStepUpdateMethod(Delegate method) + { + _StepUpdateMethod = method; + } + + protected delegate double EasingFunctionDelegate(double t, double b, double c, double d); + + private Control _AnimationUpdateControl; + public Control AnimationUpdateControl + { + get { return _AnimationUpdateControl; } + set { _AnimationUpdateControl = value; } + } + + private int _FixedStepCount = 0; + /// + /// Gets or sets the number of fixed steps animation will perform from star to finish instead of using the easing function in time. + /// Stepped animation executes specified number of steps always with Duration specifying delays between each step. + /// + public int FixedStepCount + { + get { return _FixedStepCount; } + set + { + _FixedStepCount = value; + } + } + #endregion + + #region Easing Functions + private double EaseInOutQuad(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) return c / 2 * t * t + b; + return -c / 2 * ((--t) * (t - 2) - 1) + b; + } + private double EaseInQuad(double t, double b, double c, double d) + { + return c * (t /= d) * t + b; + } + private double EaseOutQuad(double t, double b, double c, double d) + { + return -c * (t /= d) * (t - 2) + b; + } + private double EaseInCubic(double t, double b, double c, double d) + { + return c * (t /= d) * t * t + b; + } + private double EaseOutCubic(double t, double b, double c, double d) + { + return c * ((t = t / d - 1) * t * t + 1) + b; + } + private double EaseInOutCubic(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) return c / 2 * t * t * t + b; + return c / 2 * ((t -= 2) * t * t + 2) + b; + } + private double EaseInQuart(double t, double b, double c, double d) + { + return c * (t /= d) * t * t * t + b; + } + private double EaseOutQuart(double t, double b, double c, double d) + { + return -c * ((t = t / d - 1) * t * t * t - 1) + b; + } + private double EaseInOutQuart(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b; + return -c / 2 * ((t -= 2) * t * t * t - 2) + b; + } + private double EaseInQuint(double t, double b, double c, double d) + { + return c * (t /= d) * t * t * t * t + b; + } + private double EaseOutQuint(double t, double b, double c, double d) + { + return c * ((t = t / d - 1) * t * t * t * t + 1) + b; + } + private double EaseInOutQuint(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b; + return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; + } + private double EaseInSine(double t, double b, double c, double d) + { + return -c * Math.Cos(t / d * (Math.PI / 2)) + c + b; + } + private double EaseOutSine(double t, double b, double c, double d) + { + return c * Math.Sin(t / d * (Math.PI / 2)) + b; + } + private double EaseInOutSine(double t, double b, double c, double d) + { + return -c / 2 * (Math.Cos(Math.PI * t / d) - 1) + b; + } + private double EaseInExpo(double t, double b, double c, double d) + { + return (t == 0) ? b : c * Math.Pow(2, 10 * (t / d - 1)) + b; + } + private double EaseOutExpo(double t, double b, double c, double d) + { + return (t == d) ? b + c : c * (-Math.Pow(2, -10 * t / d) + 1) + b; + } + private double EaseInOutExpo(double t, double b, double c, double d) + { + if (t == 0) return b; + if (t == d) return b + c; + if ((t /= d / 2) < 1) return c / 2 * Math.Pow(2, 10 * (t - 1)) + b; + return c / 2 * (-Math.Pow(2, -10 * --t) + 2) + b; + } + private double EaseInCirc(double t, double b, double c, double d) + { + return -c * (Math.Sqrt(1 - (t /= d) * t) - 1) + b; + } + private double EaseOutCirc(double t, double b, double c, double d) + { + return c * Math.Sqrt(1 - (t = t / d - 1) * t) + b; + } + private double EaseInOutCirc(double t, double b, double c, double d) + { + if ((t /= d / 2) < 1) return -c / 2 * (Math.Sqrt(1 - t * t) - 1) + b; + return c / 2 * (Math.Sqrt(1 - (t -= 2) * t) + 1) + b; + } + private double EaseInElastic(double t, double b, double c, double d) + { + double s = 1.70158; + double p = 0; + double a = c; + if (t == 0) + return b; + if ((t /= d) == 1) + return b + c; + if (p == 0) + p = d * .3; + if (a < Math.Abs(c)) + { + a = c; + s = p / 4; + } + else + s = p / (2 * Math.PI) * Math.Asin(c / a); + return -(a * Math.Pow(2, 10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p)) + b; + } + private double EaseOutElastic(double t, double b, double c, double d) + { + double s = 1.70158; + double p = 0; + double a = c; + if (t == 0) + return b; + if ((t /= d) == 1) + return b + c; + if (p == 0) p = d * .3; + if (a < Math.Abs(c)) + { + a = c; + s = p / 4; + } + else + s = p / (2 * Math.PI) * Math.Asin(c / a); + return a * Math.Pow(2, -10 * t) * Math.Sin((t * d - s) * (2 * Math.PI) / p) + c + b; + } + private double EaseInOutElastic(double t, double b, double c, double d) + { + double s = 1.70158; + double p = 0; + double a = c; + if (t == 0) + return b; + if ((t /= d / 2) == 2) + return b + c; + if (p == 0) + p = d * (.3 * 1.5); + if (a < Math.Abs(c)) + { + a = c; + s = p / 4; + } + else + s = p / (2 * Math.PI) * Math.Asin(c / a); + if (t < 1) + return -.5 * (a * Math.Pow(2, 10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p)) + b; + return a * Math.Pow(2, -10 * (t -= 1)) * Math.Sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b; + } + + private double EaseInBounce(double t, double b, double c, double d) + { + return c - EaseOutBounce(d - t, 0, c, d) + b; + } + private double EaseOutBounce(double t, double b, double c, double d) + { + if ((t /= d) < (1 / 2.75)) + { + return c * (7.5625 * t * t) + b; + } + else if (t < (2 / 2.75)) + { + return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b; + } + else if (t < (2.5 / 2.75)) + { + return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b; + } + else + { + return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b; + } + } + private double EaseInOutBounce(double t, double b, double c, double d) + { + if (t < d / 2) return EaseInBounce(t * 2, 0, c, d) * .5 + b; + return EaseOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b; + } + + private double Linear(double t, double b, double c, double d) + { + return (t / d) * c + b; + } + #endregion + } + + internal class AnimationRequest + { + private PropertyInfo _TargetProperty = null; + + /// + /// Initializes a new instance of the AnimationRequest class. + /// + /// Target object for animation. + /// Target property name for animation. + /// From value. + /// To value. + public AnimationRequest(object target, string targetPropertyName, object to) + { + _TargetProperty = target.GetType().GetProperty(targetPropertyName); + _Target = target; + From = _TargetProperty.GetValue(target, null); + To = to; + } + + /// + /// Initializes a new instance of the AnimationRequest class. + /// + /// Target object for animation. + /// Target property name for animation. + /// From value. + /// To value. + public AnimationRequest(object target, string targetPropertyName, object from, object to) + { + _TargetProperty = target.GetType().GetProperty(targetPropertyName); + _Target = target; + From = from; + To = to; + } + + private object _Target; + /// + /// Target object for animation. + /// + public object Target + { + get { return _Target; } + set { _Target = value; } + } + + private object _From; + /// + /// Animation from value. + /// + public object From + { + get { return _From; } + set + { + _From = value; + _FromValue = GetDoubleValue(value); + } + } + + private object _To; + /// + /// Animation to value. + /// + public object To + { + get { return _To; } + set + { + _To = value; + _ToValue = GetDoubleValue(value); + } + } + + private static double GetDoubleValue(object value) + { + if (value is int) + return (double)(int)value; + else if (value is double) + return (double)value; + else if (value is long) + return (double)(long)value; + else if (value is float) + return (double)(float)value; + + return double.NaN; + } + + internal PropertyInfo Property + { + get + { + return _TargetProperty; + } + } + + private double _ToValue = double.NaN; + internal double GetToValue() + { + return _ToValue; + } + private double _FromValue = double.NaN; + internal double GetFromValue() + { + return _FromValue; + } + + } + /// + /// Specifies the animation easing function + /// + public enum AnimationEasing : int + { + EaseInOutQuad = 0, + EaseInQuad = 1, + EaseOutQuad = 2, + EaseInCubic = 3, + EaseOutCubic = 4, + EaseInOutCubic = 5, + EaseInQuart = 6, + EaseOutQuart = 7, + EaseInOutQuart = 8, + EaseInQuint = 9, + EaseOutQuint = 10, + EaseInOutQuint = 11, + EaseInSine = 12, + EaseOutSine = 13, + EaseInOutSine = 14, + EaseInExpo = 15, + EaseOutExpo = 16, + EaseInOutExpo = 17, + EaseInCirc = 18, + EaseOutCirc = 19, + EaseInOutCirc = 20, + EaseInElastic = 21, + EaseOutElastic = 22, + EaseInOutElastic = 23, + EaseInBounce = 24, + EaseOutBounce = 25, + EaseInOutBounce = 26, + Linear = 27 + } +} diff --git a/PROMS/DotNetBar Source Code/Animation/AnimationDouble.cs b/PROMS/DotNetBar Source Code/Animation/AnimationDouble.cs new file mode 100644 index 00000000..14dc9453 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Animation/AnimationDouble.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Animation +{ + internal class AnimationDouble : Animation + { + #region Constructor + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationDouble(AnimationEasing animationEasing, int animationDuration) + : + base(new AnimationRequest[0], animationEasing, animationDuration) + { + } + + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationDouble(AnimationRequest animationRequest, AnimationEasing animationEasing, int animationDuration) + : + base(new AnimationRequest[] { animationRequest }, animationEasing, animationDuration) + { + } + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationDouble(AnimationRequest[] animationRequests, AnimationEasing animationEasing, int animationDuration) + : + base(animationRequests, animationEasing, animationDuration) { } + #endregion + + protected override object GetPropertyValueCorrectType(double value) + { + return value; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Animation/AnimationInt.cs b/PROMS/DotNetBar Source Code/Animation/AnimationInt.cs new file mode 100644 index 00000000..d9445eea --- /dev/null +++ b/PROMS/DotNetBar Source Code/Animation/AnimationInt.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Animation +{ + internal class AnimationInt : Animation + { + + #region Constructor + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationInt(AnimationEasing animationEasing, int animationDuration) + : + base(new AnimationRequest[0], animationEasing, animationDuration) + { + } + + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationInt(AnimationRequest animationRequest, AnimationEasing animationEasing, int animationDuration) + : + base(new AnimationRequest[] { animationRequest }, animationEasing, animationDuration) + { + } + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationInt(AnimationRequest[] animationRequests, AnimationEasing animationEasing, int animationDuration) + : + base(animationRequests, animationEasing, animationDuration) { } + #endregion + + protected override object GetPropertyValueCorrectType(double value) + { + return (int)value; + } + + + } +} diff --git a/PROMS/DotNetBar Source Code/Animation/AnimationPoint.cs b/PROMS/DotNetBar Source Code/Animation/AnimationPoint.cs new file mode 100644 index 00000000..39b0fd1a --- /dev/null +++ b/PROMS/DotNetBar Source Code/Animation/AnimationPoint.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Animation +{ + internal class AnimationPoint : Animation + { + #region Constructor + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationPoint(AnimationEasing animationEasing, int animationDuration) + : + base(new AnimationRequest[0], animationEasing, animationDuration) + { + } + + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationPoint(AnimationRequest animationRequest, AnimationEasing animationEasing, int animationDuration) + : + base(new AnimationRequest[] { animationRequest }, animationEasing, animationDuration) + { + } + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationPoint(AnimationRequest[] animationRequests, AnimationEasing animationEasing, int animationDuration) + : + base(animationRequests, animationEasing, animationDuration) { } + #endregion + + #region Implementation + protected override void WorkerDoWork(object sender, DoWorkEventArgs e) + { + AnimationRequest[] requests = (AnimationRequest[])e.Argument; + double elapsedTime = 0; + DateTime startTime = DateTime.Now; + double duration = Duration; + + bool firstPass = true; + while (elapsedTime <= duration) + { + foreach (AnimationRequest request in requests) + { + Point toValue = (Point)request.To; + Point fromValue = (Point)request.From; + Point change = new Point(toValue.X - fromValue.X, toValue.Y - fromValue.Y); + Point newValue = toValue; + + if (firstPass) + SetTargetPropertyValue(request.Target, request.Property, request.From); + + if (change.X != 0) + newValue.X = (int)AnimationFunctions[(int)EasingFunction](elapsedTime, fromValue.X, change.X, duration); + if (change.Y != 0) + newValue.Y = (int)AnimationFunctions[(int)EasingFunction](elapsedTime, fromValue.Y, change.Y, duration); + + SetTargetPropertyValue(request.Target, request.Property, newValue); + + elapsedTime = DateTime.Now.Subtract(startTime).TotalMilliseconds; + + if (e.Cancel) return; + } + + ExecuteStepUpdateMethod(); + + if (AnimationUpdateControl != null) + AnimationUpdateControl.Update(); + + firstPass = false; + } + + // Make sure final to value is assigned + foreach (AnimationRequest request in requests) + { + SetTargetPropertyValue(request.Target, request.Property, request.To); + } + } + + protected override object GetPropertyValueCorrectType(double value) + { + return (int)value; + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Animation/AnimationRectangle.cs b/PROMS/DotNetBar Source Code/Animation/AnimationRectangle.cs new file mode 100644 index 00000000..5f5edc21 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Animation/AnimationRectangle.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.ComponentModel; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Animation +{ + internal class AnimationRectangle : Animation + { + #region Constructor + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationRectangle(AnimationEasing animationEasing, int animationDuration) + : + base(new AnimationRequest[0], animationEasing, animationDuration) + { + } + + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationRectangle(AnimationRequest animationRequest, AnimationEasing animationEasing, int animationDuration) + : + base(new AnimationRequest[] { animationRequest }, animationEasing, animationDuration) + { + } + /// + /// Initializes a new instance of the Animation class. + /// + /// Target object for animation + /// Target property name for animation + public AnimationRectangle(AnimationRequest[] animationRequests, AnimationEasing animationEasing, int animationDuration) + : + base(animationRequests, animationEasing, animationDuration) { } + #endregion + + #region Implementation + protected override void WorkerDoWork(object sender, DoWorkEventArgs e) + { + AnimationRequest[] requests = (AnimationRequest[])e.Argument; + double elapsedTime = 0; + DateTime startTime = DateTime.Now; + double duration = Duration; + + bool firstPass = true; + while (elapsedTime <= duration) + { + foreach (AnimationRequest request in requests) + { + Rectangle toValue = (Rectangle)request.To; + Rectangle fromValue = (Rectangle)request.From; + Rectangle change = new Rectangle(toValue.X - fromValue.X, toValue.Y - fromValue.Y, + toValue.Width - fromValue.Width, toValue.Height - fromValue.Height); + Rectangle newValue = toValue; + if (IsDisposed(request.Target)) return; + if (firstPass) + SetTargetPropertyValue(request.Target, request.Property, request.From); + + if (change.X != 0) + newValue.X = (int)AnimationFunctions[(int)EasingFunction](elapsedTime, fromValue.X, change.X, duration); + if (change.Y != 0) + newValue.Y = (int)AnimationFunctions[(int)EasingFunction](elapsedTime, fromValue.Y, change.Y, duration); + if (change.Width != 0) + newValue.Width = (int)AnimationFunctions[(int)EasingFunction](elapsedTime, fromValue.Width, change.Width, duration); + if (change.Height != 0) + newValue.Height = (int)AnimationFunctions[(int)EasingFunction](elapsedTime, fromValue.Height, change.Height, duration); + + SetTargetPropertyValue(request.Target, request.Property, newValue); + + elapsedTime = DateTime.Now.Subtract(startTime).TotalMilliseconds; + + if (e.Cancel) return; + } + + ExecuteStepUpdateMethod(); + + //if (AnimationUpdateControl != null) + // AnimationUpdateControl.Invoke(new MethodInvoker(delegate { AnimationUpdateControl.Update(); })); + + firstPass = false; + } + + // Make sure final to value is assigned + foreach (AnimationRequest request in requests) + { + SetTargetPropertyValue(request.Target, request.Property, request.To); + } + + //Console.WriteLine("{0} WorkerDoWork Complete", DateTime.Now); + } + + private bool IsDisposed(object p) + { + if (p == null) return true; + if (p is Control && ((Control)p).IsDisposed) return true; + if (p is BaseItem && ((BaseItem)p).IsDisposed) return true; + return false; + } + + protected override object GetPropertyValueCorrectType(double value) + { + return (int)value; + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Animation/Storyline.cs b/PROMS/DotNetBar Source Code/Animation/Storyline.cs new file mode 100644 index 00000000..df0d65b2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Animation/Storyline.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Threading; + +namespace DevComponents.DotNetBar.Animation +{ + internal class Storyline : Component + { + #region Events + + #endregion + + #region Constructor + + #endregion + + #region Implementation + private bool _IsDisposed = false; + /// + /// Returns whether Storyline is disposed. + /// + public bool IsDisposed + { + get + { + return _IsDisposed; + } + } + protected override void Dispose(bool disposing) + { + if (disposing) + { + BackgroundWorker worker = _Worker; + if (worker != null) + { + worker.CancelAsync(); + worker.Dispose(); + _Worker = null; + } + } + _IsDisposed = true; + base.Dispose(disposing); + } + + private List _Animations = new List(); + /// + /// Gets the list of animations to run using this storyline. + /// + public List Animations + { + get + { + return _Animations; + } + } + + private BackgroundWorker _Worker = null; + /// + /// Runs all animations from Animations list. + /// + public void Run() + { + if (_Worker != null) + throw new InvalidOperationException("Storyline is already running animations"); + + _Worker = new BackgroundWorker(); + _Worker.WorkerReportsProgress = true; + _Worker.WorkerSupportsCancellation = true; + _Worker.DoWork += new DoWorkEventHandler(WorkerDoWork); + _Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted); + _Worker.RunWorkerAsync(); + } + + void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + if (_RepeatStoryTimes > 0) + { + if (_Worker == null) + { + _RepeatStoryTimes = 0; + return; + } + + _RepeatStoryTimes--; + _Worker.RunWorkerAsync(); + } + else + { + if (_Worker != null) + _Worker.Dispose(); + _Worker = null; + if (_AutoDispose && !_IsDisposed) + this.Dispose(); + } + } + + void WorkerDoWork(object sender, DoWorkEventArgs e) + { + int count = _Animations.Count; + for (int i = 0; i < count; i++) + { + if (e.Cancel) return; + _Animations[i].Start(); + while (!_Animations[i].IsCompleted) + { + try + { + using ( + System.Threading.ManualResetEvent wait = + new System.Threading.ManualResetEvent(false)) + wait.WaitOne(50); + //Thread.Sleep(50); + } + catch + { + _Animations[i].Stop(); + return; + } + if (e.Cancel) + { + _Animations[i].Stop(); + return; + } + } + } + } + + private int _RepeatStoryTimes = 0; + /// + /// Gets or sets number of times storyline is repeated. Default value is 0 which indicates that storyline is run only once meaning not repeated. + /// + public int RepeatStoryTimes + { + get { return _RepeatStoryTimes; } + set { _RepeatStoryTimes = value; } + } + + private bool _AutoDispose = false; + /// + /// Gets or sets whether storyline is auto-disposed when finished. + /// + public bool AutoDispose + { + get { return _AutoDispose; } + set + { + _AutoDispose = value; + } + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/AssemblyInfo_ORG.cs.sav b/PROMS/DotNetBar Source Code/AssemblyInfo_ORG.cs.sav new file mode 100644 index 00000000..afe3e53d --- /dev/null +++ b/PROMS/DotNetBar Source Code/AssemblyInfo_ORG.cs.sav @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("DevComponents.DotNetBar")] +[assembly: AssemblyDescription("DotNetBar is Toolbar, Menubar, Docking Component.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("DevComponents.com")] +[assembly: AssemblyProduct("DevComponents.DotNetBar")] +[assembly: AssemblyCopyright("(c) 2002 by DevComponents.com, All Rights Reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Revision +// Build Number +// +// You can specify all the value or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyFileVersion("14.1.0.37")] +[assembly: AssemblyVersion("14.1.0.37")] + +//[assembly: AssemblyVersion("1.0.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified - the assembly cannot be signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. +// (*) If the key file and a key name attributes are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP - that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the file is installed into the CSP and used. +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +//[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyDelaySign(true)] +[assembly: AssemblyKeyFile("dotnetbar.snk")] +[assembly: AssemblyKeyName("")] +[assembly: System.Security.AllowPartiallyTrustedCallers] +// Uncomment for .NET Framework 4.0 compilation +//[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)] \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Attributes.cs b/PROMS/DotNetBar Source Code/Attributes.cs new file mode 100644 index 00000000..bee1310d --- /dev/null +++ b/PROMS/DotNetBar Source Code/Attributes.cs @@ -0,0 +1,16 @@ +using System; + +namespace DevComponents.DotNetBar +{ + [AttributeUsage(AttributeTargets.Property|AttributeTargets.Method|AttributeTargets.Field)] + public class DevCoBrowsable : Attribute + { + public static readonly DevCoBrowsable Yes=new DevCoBrowsable(true); + public static readonly DevCoBrowsable No=new DevCoBrowsable(false); + public bool Browsable; + public DevCoBrowsable(bool browsable) + { + this.Browsable = browsable; + } + } +} diff --git a/PROMS/DotNetBar Source Code/AutoHidePanel.cs b/PROMS/DotNetBar Source Code/AutoHidePanel.cs new file mode 100644 index 00000000..f3d3b7be --- /dev/null +++ b/PROMS/DotNetBar Source Code/AutoHidePanel.cs @@ -0,0 +1,1628 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Drawing.Text; + +namespace DevComponents.DotNetBar +{ + [System.ComponentModel.ToolboxItem(false), System.ComponentModel.DesignTimeVisible(false), System.Runtime.InteropServices.ComVisible(false)] + public class AutoHidePanel : System.Windows.Forms.Control + { + private ArrayList m_Panels = new ArrayList(10); + private System.Windows.Forms.Timer m_Timer = null; + + private eDotNetBarStyle m_Style = eDotNetBarStyle.OfficeXP; + + private bool m_EnableHoverExpand = true; + private bool m_EnableFocusCollapse = true; + + private int m_AutoHideShowTimeout = 800; + private ColorScheme m_ColorScheme = null; + private DotNetBarManager m_Owner = null; + + public AutoHidePanel() + { + this.SetStyle(ControlStyles.Selectable, false); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + //this.Font = SystemFonts.DefaultFont; // SystemInformation.MenuFont.Clone() as Font; + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + DestroyTimer(); + foreach (PanelBar panel in m_Panels) + { + panel.Dispose(); + } + m_Panels.Clear(); + } + base.Dispose(disposing); + } + + internal void SetOwner(DotNetBarManager owner) + { + m_Owner = owner; + } + + private Size _FixedSize = Size.Empty; + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Size FixedSize + { + get { return _FixedSize; } + set { _FixedSize = value; } + } + + private bool m_AntiAlias = false; + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is false. + /// + [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public bool AntiAlias + { + get { return m_AntiAlias; } + set + { + if (m_AntiAlias != value) + { + m_AntiAlias = value; + this.Invalidate(); + } + } + } + + protected override void OnPaint(PaintEventArgs p) + { + eTextFormat format = eTextFormat.Default | eTextFormat.VerticalCenter | eTextFormat.SingleLine; + Graphics g = p.Graphics; + ColorScheme scheme = null; + + if (this.BackColor == Color.Transparent || this.BackgroundImage != null) + { + base.OnPaintBackground(p); + } + + TextRenderingHint textHint = g.TextRenderingHint; + SmoothingMode sm = g.SmoothingMode; + if (m_AntiAlias) + { + g.TextRenderingHint = BarUtilities.AntiAliasTextRenderingHint; + g.SmoothingMode = SmoothingMode.AntiAlias; + } + bool office2007Style = BarFunctions.IsOffice2007Style(m_Style); + + if (office2007Style && m_ColorScheme == null && Rendering.GlobalManager.Renderer is Rendering.Office2007Renderer) + scheme = ((Rendering.Office2007Renderer)Rendering.GlobalManager.Renderer).ColorTable.LegacyColors; + else if (m_Owner != null && m_Owner.UseGlobalColorScheme) + scheme = m_Owner.ColorScheme; + else if (m_ColorScheme != null) + scheme = m_ColorScheme; + else + scheme = new ColorScheme(m_Style); + + Rectangle clientRect = this.ClientRectangle; + clientRect.Inflate(1, 1); + if (scheme.AutoHidePanelBackgroundImage != null) + BarFunctions.PaintBackgroundImage(g, clientRect, scheme.AutoHidePanelBackgroundImage, eBackgroundImagePosition.Tile, 255); + + if (!scheme.AutoHidePanelBackground.IsEmpty) + { + DisplayHelp.FillRectangle(g, clientRect, scheme.AutoHidePanelBackground, scheme.AutoHidePanelBackground2, 90); + } + else if (IsGradientStyle) + { + DisplayHelp.FillRectangle(g, clientRect, scheme.BarBackground, scheme.BarBackground2, scheme.BarBackgroundGradientAngle); + } + else + { + using (SolidBrush brush = new SolidBrush(ControlPaint.Light(this.BackColor))) + g.FillRectangle(brush, this.DisplayRectangle); + } + + if (m_Style == eDotNetBarStyle.VS2005 || office2007Style) + { + VS2005TabDisplay td = StyleManager.IsMetro(m_Style) ? new VS2012TabDisplay(this, scheme) : new VS2005TabDisplay(this, scheme); + td.DisplayTextForActiveTabOnly = office2007Style; + td.Paint(g, m_Panels); + + + if (m_AntiAlias) + { + g.TextRenderingHint = textHint; + g.SmoothingMode = sm; + } + + return; + } + + const int margin = 2; + int width = this.Width - 2; + int height = this.Height - 2; + + Color textColor = Color.Empty; + SolidBrush backBrush = null; + Pen linePen = null; + if (m_Style == eDotNetBarStyle.Office2003) + { + textColor = scheme.ItemText; + linePen = new Pen(scheme.ItemHotBorder, 1); + } + else if (m_Style == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(m_Style)) + { + textColor = scheme.ItemText; + linePen = new Pen(scheme.MenuBorder, 1); + } + else + { + textColor = g.GetNearestColor(ControlPaint.DarkDark(this.BackColor)); + backBrush = new SolidBrush(this.BackColor); + linePen = new Pen(g.GetNearestColor(ControlPaint.Dark(this.BackColor)), 1); + } + + if (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom || this.Dock == DockStyle.None) + { + int x = 2; + foreach (PanelBar panel in m_Panels) + { + for (int i = 0; i < panel.Tabs.Count; i++) + { + DockItemTab tab = panel.Tabs[i] as DockItemTab; + CompositeImage icon = tab.Icon; + tab.DisplayRectangle.X = x; + tab.DisplayRectangle.Y = 0; + tab.DisplayRectangle.Height = height; + x += PanelBar.TabPadding; + if (panel.ActiveTab == i || panel.BoundBar.AutoHideTabTextAlwaysVisible) + { + if (icon != null) + { + + if (this.Dock == DockStyle.Top) + { + if ((m_Style == eDotNetBarStyle.Office2003 || m_Style == eDotNetBarStyle.VS2005) && !scheme.ItemPressedBackground2.IsEmpty) + { + using (LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(tab.DisplayRectangle.X, 0, icon.Width + panel.MaxTextWidth + PanelBar.TabPadding * 3, height), scheme.ItemPressedBackground, scheme.ItemPressedBackground2, scheme.ItemPressedBackgroundGradientAngle)) + g.FillRectangle(gradient, tab.DisplayRectangle.X, 0, icon.Width + panel.MaxTextWidth + PanelBar.TabPadding * 3, height); + + } + else if (backBrush != null) + g.FillRectangle(backBrush, tab.DisplayRectangle.X, 0, icon.Width + panel.MaxTextWidth + PanelBar.TabPadding * 3, height); + icon.DrawImage(g, new Rectangle(x, (height - icon.Height) / 2, icon.Width, icon.Height)); + //g.DrawImage(icon,x,(height-icon.Height)/2,icon.Width,icon.Height); + } + else + { + if ((m_Style == eDotNetBarStyle.Office2003 || m_Style == eDotNetBarStyle.VS2005) && !scheme.ItemPressedBackground2.IsEmpty) + { + using (LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(tab.DisplayRectangle.X, margin, icon.Width + panel.MaxTextWidth + PanelBar.TabPadding * 3, height), scheme.ItemPressedBackground, scheme.ItemPressedBackground2, scheme.ItemPressedBackgroundGradientAngle)) + g.FillRectangle(gradient, tab.DisplayRectangle.X, margin, icon.Width + panel.MaxTextWidth + PanelBar.TabPadding * 3, height); + + } + else if (backBrush != null) + g.FillRectangle(backBrush, tab.DisplayRectangle.X, margin, icon.Width + panel.MaxTextWidth + PanelBar.TabPadding * 3, height); + icon.DrawImage(g, new Rectangle(x, (height - icon.Height) / 2 + margin, icon.Width, icon.Height)); + //g.DrawImage(icon,x,(height-icon.Height)/2+margin,icon.Width,icon.Height); + } + x += (icon.Width + PanelBar.TabPadding); + } + else + { + if (this.Dock == DockStyle.Top) + { + if ((m_Style == eDotNetBarStyle.Office2003 || m_Style == eDotNetBarStyle.VS2005) && !scheme.ItemPressedBackground2.IsEmpty) + { + using (LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(tab.DisplayRectangle.X, 0, tab.TextSize.Width + PanelBar.TabPadding * 2, height), scheme.ItemPressedBackground, scheme.ItemPressedBackground2, scheme.ItemPressedBackgroundGradientAngle)) + g.FillRectangle(gradient, tab.DisplayRectangle.X, 0, tab.TextSize.Width + PanelBar.TabPadding * 2, height); + + } + else if (backBrush != null) + g.FillRectangle(backBrush, tab.DisplayRectangle.X, 0, tab.TextSize.Width + PanelBar.TabPadding * 2, height); + } + else + { + if ((m_Style == eDotNetBarStyle.Office2003 || m_Style == eDotNetBarStyle.VS2005) && !scheme.ItemPressedBackground2.IsEmpty) + { + using (LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(tab.DisplayRectangle.X, margin, tab.TextSize.Width + PanelBar.TabPadding * 2, height), scheme.ItemPressedBackground, scheme.ItemPressedBackground2, scheme.ItemPressedBackgroundGradientAngle)) + g.FillRectangle(gradient, tab.DisplayRectangle.X, margin, tab.TextSize.Width + PanelBar.TabPadding * 2, height); + + } + else if (backBrush != null) + g.FillRectangle(backBrush, tab.DisplayRectangle.X, margin, tab.TextSize.Width + PanelBar.TabPadding * 2, height); + } + } + + TextDrawing.DrawStringLegacy(g, tab.Text, this.Font, textColor, new Rectangle(x, this.Dock == DockStyle.Top ? 0 : margin, (icon == null ? tab.TextSize.Width : panel.MaxTextWidth), height), format); + x += ((icon == null ? tab.TextSize.Width : panel.MaxTextWidth) + PanelBar.TabPadding); + tab.DisplayRectangle.Width = x - tab.DisplayRectangle.X; + if (this.Dock == DockStyle.Top) + tab.DisplayRectangle.Offset(0, -1); + else + { + tab.DisplayRectangle.Offset(0, 1); + tab.DisplayRectangle.Height += 2; + } + g.DrawRectangle(linePen, tab.DisplayRectangle); + } + else + { + if (icon != null) + { + if (this.Dock == DockStyle.Top) + { + if (backBrush != null) + g.FillRectangle(backBrush, tab.DisplayRectangle.X, 0, icon.Width + PanelBar.TabPadding * 2, height); + icon.DrawImage(g, new Rectangle(x, (height - icon.Height) / 2, icon.Width, icon.Height)); + //g.DrawImage(icon,x,(height-icon.Height)/2,icon.Width,icon.Height); + } + else + { + if (backBrush != null) + g.FillRectangle(backBrush, tab.DisplayRectangle.X, margin, icon.Width + PanelBar.TabPadding * 2, height); + icon.DrawImage(g, new Rectangle(x, (height - icon.Height) / 2 + margin, icon.Width, icon.Height)); + //g.DrawImage(icon,x,(height-icon.Height)/2+margin,icon.Width,icon.Height); + } + x += (icon.Width + PanelBar.TabPadding); + } + else + { + TextDrawing.DrawStringLegacy(g, tab.Text, this.Font, textColor, new Rectangle(x, this.Dock == DockStyle.Top ? 0 : margin, tab.TextSize.Width, height), format); + x += (tab.TextSize.Width + PanelBar.TabPadding); + } + tab.DisplayRectangle.Width = x - tab.DisplayRectangle.X; + if (this.Dock == DockStyle.Top) + tab.DisplayRectangle.Y--; + else + { + tab.DisplayRectangle.Y++; + tab.DisplayRectangle.Height += 2; + } + g.DrawRectangle(linePen, tab.DisplayRectangle); + } + if (x > this.Width) + break; + } + x += 4; + if (x > this.Width) + break; + } + } + else if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right) + { + int y = 2; + foreach (PanelBar panel in m_Panels) + { + for (int i = 0; i < panel.Tabs.Count; i++) + { + DockItemTab tab = panel.Tabs[i] as DockItemTab; + CompositeImage icon = tab.Icon; + tab.DisplayRectangle.X = 0; + tab.DisplayRectangle.Y = y; + tab.DisplayRectangle.Width = width; + y += PanelBar.TabPadding; + if (panel.ActiveTab == i || panel.BoundBar.AutoHideTabTextAlwaysVisible) + { + if (icon != null) + { + if (this.Dock == DockStyle.Left) + { + if ((m_Style == eDotNetBarStyle.Office2003 || m_Style == eDotNetBarStyle.VS2005) && !scheme.ItemPressedBackground2.IsEmpty) + { + using (LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(tab.DisplayRectangle.X, tab.DisplayRectangle.Y, width, icon.Height + panel.MaxTextWidth + PanelBar.TabPadding * 3), scheme.ItemPressedBackground, scheme.ItemPressedBackground2, scheme.ItemPressedBackgroundGradientAngle)) + g.FillRectangle(gradient, tab.DisplayRectangle.X, tab.DisplayRectangle.Y, width, icon.Height + panel.MaxTextWidth + PanelBar.TabPadding * 3); + + } + else if (backBrush != null) + g.FillRectangle(backBrush, tab.DisplayRectangle.X, tab.DisplayRectangle.Y, width, icon.Height + panel.MaxTextWidth + PanelBar.TabPadding * 3); + icon.DrawImage(g, new Rectangle((width - icon.Width - margin) / 2, y, icon.Width, icon.Height)); + //g.DrawImage(icon,(width-icon.Width-margin)/2,y,icon.Width,icon.Height); + } + else + { + if ((m_Style == eDotNetBarStyle.Office2003 || m_Style == eDotNetBarStyle.VS2005) && !scheme.ItemPressedBackground2.IsEmpty) + { + using (LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(margin, tab.DisplayRectangle.Y, width, icon.Height + panel.MaxTextWidth + PanelBar.TabPadding * 3), scheme.ItemPressedBackground, scheme.ItemPressedBackground2, scheme.ItemPressedBackgroundGradientAngle)) + g.FillRectangle(gradient, margin, tab.DisplayRectangle.Y, width, icon.Height + panel.MaxTextWidth + PanelBar.TabPadding * 3); + + } + else if (backBrush != null) + g.FillRectangle(backBrush, margin, tab.DisplayRectangle.Y, width, icon.Height + panel.MaxTextWidth + PanelBar.TabPadding * 3); + icon.DrawImage(g, new Rectangle((width - icon.Width + margin) / 2, y, icon.Width, icon.Height)); + //g.DrawImage(icon,(width-icon.Width+margin)/2,y,icon.Width,icon.Height); + } + y += (icon.Height + PanelBar.TabPadding); + } + else + { + if (this.Dock == DockStyle.Left) + { + if ((m_Style == eDotNetBarStyle.Office2003 || m_Style == eDotNetBarStyle.VS2005) && !scheme.ItemPressedBackground2.IsEmpty) + { + using (LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(tab.DisplayRectangle.X, tab.DisplayRectangle.Y, width, tab.TextSize.Width + PanelBar.TabPadding * 2), scheme.ItemPressedBackground, scheme.ItemPressedBackground2, scheme.ItemPressedBackgroundGradientAngle)) + g.FillRectangle(gradient, tab.DisplayRectangle.X, tab.DisplayRectangle.Y, width, tab.TextSize.Width + PanelBar.TabPadding * 2); + + } + else if (backBrush != null) + g.FillRectangle(backBrush, tab.DisplayRectangle.X, tab.DisplayRectangle.Y, width, tab.TextSize.Width + PanelBar.TabPadding * 2); + } + else + { + if ((m_Style == eDotNetBarStyle.Office2003 || m_Style == eDotNetBarStyle.VS2005) && !scheme.ItemPressedBackground2.IsEmpty) + { + using (LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(margin, tab.DisplayRectangle.Y, width, tab.TextSize.Width + PanelBar.TabPadding * 2), scheme.ItemPressedBackground, scheme.ItemPressedBackground2, scheme.ItemPressedBackgroundGradientAngle)) + g.FillRectangle(gradient, margin, tab.DisplayRectangle.Y, width, tab.TextSize.Width + PanelBar.TabPadding * 2); + + } + else if (backBrush != null) + g.FillRectangle(backBrush, margin, tab.DisplayRectangle.Y, width, tab.TextSize.Width + PanelBar.TabPadding * 2); + } + } + g.RotateTransform(90); + TextDrawing.DrawStringLegacy(g, tab.Text, this.Font, textColor, new Rectangle(y, -width, (icon == null ? tab.TextSize.Width : panel.MaxTextWidth), width), format); + g.ResetTransform(); + y += ((icon == null ? tab.TextSize.Width : panel.MaxTextWidth) + PanelBar.TabPadding); + if (this.Dock == DockStyle.Left) + tab.DisplayRectangle.Offset(-1, 0); + else + tab.DisplayRectangle.Offset(1, 0); + tab.DisplayRectangle.Height = y - tab.DisplayRectangle.Y; + g.DrawRectangle(linePen, tab.DisplayRectangle); + } + else + { + if (icon != null) + { + if (this.Dock == DockStyle.Left) + { + if (backBrush != null) + g.FillRectangle(backBrush, tab.DisplayRectangle.X, tab.DisplayRectangle.Y, width, icon.Height + PanelBar.TabPadding * 2); + icon.DrawImage(g, new Rectangle((width - icon.Width - margin) / 2, y, icon.Width, icon.Height)); + //g.DrawImage(icon,(width-icon.Width-margin)/2,y,icon.Width,icon.Height); + } + else + { + if (backBrush != null) + g.FillRectangle(backBrush, margin, tab.DisplayRectangle.Y, width, icon.Height + PanelBar.TabPadding * 2); + icon.DrawImage(g, new Rectangle((width - icon.Width + margin) / 2, y, icon.Width, icon.Height)); + //g.DrawImage(icon,(width-icon.Width+margin)/2,y,icon.Width,icon.Height); + } + y += (icon.Height + PanelBar.TabPadding); + } + else + { + g.RotateTransform(90); + TextDrawing.DrawStringLegacy(g, tab.Text, this.Font, textColor, new Rectangle(y, -width, tab.TextSize.Width, width), format); + g.ResetTransform(); + y += (tab.TextSize.Width + PanelBar.TabPadding); + } + tab.DisplayRectangle.Height = y - tab.DisplayRectangle.Y; + if (this.Dock == DockStyle.Left) + tab.DisplayRectangle.X--; + else + tab.DisplayRectangle.X++; + g.DrawRectangle(linePen, tab.DisplayRectangle); + } + if (y > this.Height) + break; + } + y += 4; + if (y > this.Height) + break; + } + } + + linePen.Dispose(); + + + if (m_AntiAlias) + { + g.TextRenderingHint = textHint; + g.SmoothingMode = sm; + } + } + + private bool IsGradientStyle + { + get + { + if (m_Style == eDotNetBarStyle.Office2003 || m_Style == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(m_Style)) + return true; + return false; + } + } + private DockItemTab _MouseOverTab = null; + private void SetMouseOverTab(AutoHidePanel.DockItemTab tab) + { + if (tab == _MouseOverTab) return; + + if (_MouseOverTab != null) + { + _MouseOverTab.IsMouseOver = false; + this.Invalidate(_MouseOverTab.DisplayRectangle); + } + + _MouseOverTab = tab; + + if (_MouseOverTab != null) + { + _MouseOverTab.IsMouseOver = true; + this.Invalidate(_MouseOverTab.DisplayRectangle); + } + } + protected override void OnMouseMove(MouseEventArgs e) + { + DockItemTab tab = HitTestTab(e.X, e.Y); + SetMouseOverTab(tab); + + base.OnMouseMove(e); + } + protected override void OnMouseEnter(EventArgs e) + { + base.OnMouseEnter(e); + CreateTimer(); + } + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + SetMouseOverTab(null); + if (m_Timer != null) + m_Timer.Interval = m_AutoHideShowTimeout; + } + private void CreateTimer() + { + if (m_Timer != null) + { + m_Timer.Start(); + return; + } + m_Timer = new Timer(); + m_Timer.Interval = m_AutoHideShowTimeout; + m_Timer.Tick += new EventHandler(this.TimerTick); + m_Timer.Start(); + } + internal void StopTimer() + { + if (m_Timer != null) + m_Timer.Stop(); + } + internal void StartTimer() + { + if (m_Timer != null) + m_Timer.Start(); + } + + private void TimerTick(object sender, EventArgs e) + { + Point p = this.PointToClient(Control.MousePosition); + + if (this.ClientRectangle.Contains(p)) + { + IntPtr activeWnd = NativeFunctions.GetActiveWindow(); + Form parentForm = this.FindForm(); + if (parentForm != null && parentForm.Handle != activeWnd) + { + Control c = parentForm; + bool bExit = true; + while (c.Parent != null) + { + c = c.Parent; + if (c.Handle == activeWnd) + { + bExit = false; + break; + } + } + if (bExit) + return; + } + if (!m_EnableHoverExpand) + return; + if (parentForm != null) + { + Point mousePosition = Control.MousePosition; + Point parentPoint = parentForm.PointToClient(mousePosition); + Control childAtPoint = parentForm.GetChildAtPoint(parentPoint, GetChildAtPointSkip.Invisible | GetChildAtPointSkip.Transparent); + while (childAtPoint != null && !(childAtPoint is AutoHidePanel)) + { + parentPoint = childAtPoint.PointToClient(mousePosition); + childAtPoint = childAtPoint.GetChildAtPoint(parentPoint, GetChildAtPointSkip.Invisible | GetChildAtPointSkip.Transparent); + } + if (!(childAtPoint is AutoHidePanel)) + { + StopTimer(); + return; + } + } + SelectPanel(p.X, p.Y); + } + else + { + PanelBar activePanel = ActivePanelBar; + if (activePanel != null && !activePanel.BoundBar.IsSizingWindow) + { + if (activePanel.BoundBar.Visible && !(!m_EnableFocusCollapse && IsBarActive(activePanel.BoundBar))) + { + p = activePanel.BoundBar.PointToClient(Control.MousePosition); + if (!activePanel.BoundBar.ClientRectangle.Contains(p)) + { + if (AnimateHide(activePanel.BoundBar)) + DestroyTimer(); + } + } + } + } + + } + private void DestroyTimer() + { + if (m_Timer == null) + return; + m_Timer.Stop(); + m_Timer.Dispose(); + m_Timer = null; + } + private bool IsBarActive(Bar bar) + { + if (bar == null) + return false; + Form form = this.FindForm(); + if (form == null) + return false; + Control activeControl = form.ActiveControl; + if (activeControl == null) + return false; + while (activeControl != null) + { + if (bar == activeControl) + return true; + activeControl = activeControl.Parent; + } + return false; + } + + /// + /// Gets or sets the timeout in milliseconds for auto hide/show action. + /// When timeout has elapsed and mouse has left the bar the bar will be automatically hidden. + /// If mouse is hovering over the collapsed bar and timeout has elapsed the bar will be displayed. + /// + [DefaultValue(800), Category("Behavior"), Description("Indicates timeout in milliseconds for auto hide/show action.")] + public int AutoHideShowTimeout + { + get { return m_AutoHideShowTimeout; } + set { m_AutoHideShowTimeout = value; } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + if (e.Button == MouseButtons.Left) + { + SelectPanel(e.X, e.Y); + } + } + + public void SelectPanel(int x, int y) + { + foreach (PanelBar panel in m_Panels) + { + foreach (DockItemTab tab in panel.Tabs) + { + if (tab.DisplayRectangle.Contains(x, y)) + { + PanelBar activePanel = ActivePanelBar; + if (activePanel != null) + { + if (activePanel != panel) + { + if (activePanel.BoundBar.IsSizingWindow) + return; + if (!AnimateHide(activePanel.BoundBar)) + return; + } + else + { + if (panel.ActiveTab < panel.Tabs.Count) + { + if (panel.Tabs[panel.ActiveTab] == tab && panel.BoundBar.Visible) + return; + ((DockItemTab)activePanel.Tabs[activePanel.ActiveTab]).Item.Displayed = false; + } + } + } + if (panel.BoundBar.VisibleItemCount == 0) + throw new InvalidOperationException("Bar.Items collection must contain at least one visible DockContainerItem object so auto-hide functionality can function properly."); + panel.ActiveTab = panel.Tabs.IndexOf(tab); + if (panel.BoundBar.IsDisposed) return; + panel.BoundBar.SelectedDockTab = panel.BoundBar.Items.IndexOf(tab.Item); + PopupManager.CloseAllPopups(); + AnimateShow(panel.BoundBar); + this.Refresh(); + return; + } + } + } + } + + /// + /// Returns the reference to DockContainerItem tab if any under specified coordinates. + /// + /// X - client mouse coordinate + /// Y - client mouse coordinate + /// Reference to DockContainerItem whose tab is at specified coordinates or null if there is no tab at given coordinates + public DockContainerItem HitTest(int x, int y) + { + DockItemTab tab = HitTestTab(x, y); + if (tab != null) + return tab.Item; + return null; + } + + private DockItemTab HitTestTab(int x, int y) + { + foreach (PanelBar panel in m_Panels) + { + foreach (DockItemTab tab in panel.Tabs) + { + if (tab.DisplayRectangle.Contains(x, y)) + { + return tab; + } + } + } + return null; + } + + + internal DockContainerItem SelectedDockContainerItem + { + get + { + PanelBar panel = this.ActivePanelBar; + if (panel == null) + { + foreach (PanelBar p in m_Panels) + { + for (int i = 0; i < p.Tabs.Count; i++) + { + DockItemTab tab = p.Tabs[i] as DockItemTab; + if (p.ActiveTab == i) + return tab.Item; + } + } + return null; + } + try + { + DockItemTab tab = panel.Tabs[panel.ActiveTab] as DockItemTab; + return tab.Item; + } + catch + { + return null; + } + } + set + { + foreach (PanelBar panel in m_Panels) + { + foreach (DockItemTab tab in panel.Tabs) + { + if (tab.Item == value) + { + PanelBar activePanel = ActivePanelBar; + if (activePanel != null) + { + if (activePanel != panel) + { + if (activePanel.BoundBar.IsSizingWindow) + return; + if (!AnimateHide(activePanel.BoundBar)) + return; + } + else + { + if (panel.Tabs[panel.ActiveTab] == tab && panel.BoundBar.Visible) + return; + ((DockItemTab)activePanel.Tabs[activePanel.ActiveTab]).Item.Displayed = false; + } + } + panel.ActiveTab = panel.Tabs.IndexOf(tab); + this.Refresh(); + return; + } + } + } + } + } + + /// + /// Gets or sets whether bars on auto-hide panel are displayed when mouse hovers over the tab. + /// + [DefaultValue(true), Browsable(true), Description("Indicates whether bars on auto-hide panel are displayed when mouse hovers over the tab.")] + public bool EnableHoverExpand + { + get { return m_EnableHoverExpand; } + set { m_EnableHoverExpand = value; } + } + + /// + /// Gets or sets whether bars that have focus are collapsed automatically or not. + /// + [DefaultValue(true), Browsable(true), Description("Indicates whether bars that have focus are collapsed automatically or not.")] + public bool EnableFocusCollapse + { + get { return m_EnableFocusCollapse; } + set { m_EnableFocusCollapse = value; } + } + + protected override void OnFontChanged(EventArgs e) + { + base.OnFontChanged(e); + RefreshPanels(); + } + + protected override void OnSystemColorsChanged(EventArgs e) + { + base.OnSystemColorsChanged(e); + Application.DoEvents(); + this.Font = SystemFonts.DefaultFont; // SystemInformation.MenuFont.Clone() as Font; + } + + private void RefreshPanels() + { + foreach (PanelBar panelbar in m_Panels) + panelbar.ReloadDockItems(); + this.Invalidate(); + } + + internal void ShowBar(Bar bar) + { + PanelBar panel = null; + foreach (PanelBar panelbar in m_Panels) + { + if (panelbar.BoundBar == bar) + { + panel = panelbar; + break; + } + } + PanelBar activePanel = ActivePanelBar; + if (activePanel == panel) + return; + + if (activePanel != null) + { + if (activePanel.BoundBar.IsSizingWindow) + return; + if (!AnimateHide(activePanel.BoundBar)) + { + CreateTimer(); + return; + } + } + panel.BoundBar.SelectedDockTab = panel.ActiveTab; + AnimateShow(panel.BoundBar); + this.Refresh(); + CreateTimer(); + } + internal void HideBar(Bar bar) + { + PanelBar activePanel = ActivePanelBar; + if (activePanel.BoundBar != bar) + return; + if (activePanel.BoundBar.Visible) + { + if (AnimateHide(activePanel.BoundBar)) + DestroyTimer(); + } + } + + private bool AnimateHide(Bar bar) + { + return bar.AnimateHide(); + } + + private bool AnimateShow(Bar bar) + { + if (bar.Enabled) + return bar.AnimateShow(); + return false; + } + + private PanelBar ActivePanelBar + { + get + { + foreach (PanelBar panel in m_Panels) + { + if (panel.ActiveTab >= 0 && panel.BoundBar.Visible) + return panel; + } + return null; + } + } + + /// + /// Sets bars position on the auto-hide panel. + /// + /// Bar for which position should be changed. + /// New indexed position of the bar. + public void SetBarPosition(Bar bar, int iIndex) + { + if (iIndex < m_Panels.Count) + { + for (int i = 0; i < m_Panels.Count; i++) + { + if (((PanelBar)m_Panels[i]).BoundBar == bar) + { + if (i != iIndex) + { + PanelBar panel = (PanelBar)m_Panels[i]; + m_Panels.RemoveAt(i); + m_Panels.Insert(iIndex, panel); + this.Refresh(); + } + break; + } + } + } + } + + /// + /// Gets or sets the style of auto-hide panel. + /// + public eDotNetBarStyle Style + { + get { return m_Style; } + set + { + m_Style = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the ColorScheme object used by this panel. Default value is null which means that ColorScheme is + /// automatically created as specified by Style property. Note that if your DotNetBarManager has UseGlobalColorScheme set to true + /// ColorScheme from DotNetBarManager will be used. + /// + [Browsable(false), DefaultValue(null)] + public ColorScheme ColorScheme + { + get { return m_ColorScheme; } + set { m_ColorScheme = value; } + } + + public void AddBar(Bar bar) + { + if (bar.Style == eDotNetBarStyle.Office2003) + m_Style = eDotNetBarStyle.Office2003; + else if (bar.Style == eDotNetBarStyle.VS2005) + m_Style = eDotNetBarStyle.VS2005; + else if (bar.Style == eDotNetBarStyle.Office2007) + m_Style = eDotNetBarStyle.Office2007; + else if (bar.Style == eDotNetBarStyle.Office2010) + m_Style = eDotNetBarStyle.Office2010; + else if (bar.Style == eDotNetBarStyle.Windows7) + m_Style = eDotNetBarStyle.Windows7; + else if (bar.Style == eDotNetBarStyle.StyleManagerControlled) + m_Style = bar.ItemsContainer.EffectiveStyle; + else + m_Style = eDotNetBarStyle.OfficeXP; + + PanelBar panel = new PanelBar(this, bar); + m_Panels.Add(panel); + if (this.Dock == DockStyle.Right || this.Dock == DockStyle.Left) + { + if (panel.PanelSize.Height > this.Width) + this.Width = panel.PanelSize.Height; + } + else + { + if (panel.PanelSize.Height > this.Height) + this.Height = panel.PanelSize.Height; + } + + if (!this.Visible) + { + BarFunctions.SetControlVisible(this, true); + } + else + this.Refresh(); + this.Parent.PerformLayout(); + this.Parent.Update(); + } + + public void RemoveBar(Bar bar) + { + foreach (PanelBar panel in m_Panels) + { + if (panel.BoundBar == bar) + { + m_Panels.Remove(panel); + panel.Dispose(); + if (m_Panels.Count == 0) + { + this.Visible = false; + if (this.Dock == DockStyle.Right || this.Dock == DockStyle.Left) + { + this.Width = 0; + } + else + { + this.Height = 0; + } + } + else + this.Refresh(); + break; + } + } + if (m_Panels.Count == 0) + DestroyTimer(); + } + + public void RefreshBar(Bar bar) + { + foreach (PanelBar panel in m_Panels) + { + if (panel.BoundBar == bar) + { + panel.ReloadDockItems(); + break; + } + } + this.Refresh(); + } + + protected override void OnHandleDestroyed(EventArgs e) + { + base.OnHandleDestroyed(e); + DestroyTimer(); + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + PanelBar panel = this.ActivePanelBar; + if (panel != null) + { + if (panel.BoundBar.Visible) + panel.BoundBar.SetAutoHideSize(); + } + } + + #region DockItemTab + private class DockItemTab : IDisposable + { + public Rectangle DisplayRectangle = new Rectangle(0, 0, 0, 0); + public DockContainerItem Item = null; + public Size TextSize = Size.Empty; + public Size IconSize = Size.Empty; + private string m_Text = ""; + private PanelBar m_Parent = null; + public DockItemTab(PanelBar parent, DockContainerItem item) + { + this.Item = item; + m_Parent = parent; + item.TextChanged += new EventHandler(this.ItemTextChanged); + CompositeImage image = this.Icon; + if (image != null) + IconSize = image.Size; + } + public DockItemTab(PanelBar parent, string text) + { + m_Text = text; + m_Parent = parent; + } + public string Text + { + get + { + if (this.Item == null) + return m_Text; + else + return this.Item.Text; + } + } + public CompositeImage Icon + { + get + { + if (Item == null) + return null; + if (Item.Image != null) + { + return new CompositeImage(Item.Image, false); + } + if (Item.ImageIndex >= 0 && Item.ImageList != null) + return new CompositeImage(Item.ImageList.Images[Item.ImageIndex], false); + if (Item.Icon != null) + return new CompositeImage(Item.Icon, false); + return null; + } + } + private bool _IsMouseOver = false; + public bool IsMouseOver + { + get + { + return _IsMouseOver; + } + set + { + _IsMouseOver = value; + } + } + private void ItemTextChanged(object sender, EventArgs e) + { + Control container = ((BaseItem)sender).ContainerControl as Control; + if (container != null) + { + Graphics g = BarFunctions.CreateGraphics(container); + try + { + TextSize = TextDrawing.MeasureStringLegacy(g, ((BaseItem)sender).Text, m_Parent.Parent.Font, Size.Empty, eTextFormat.Default); + TextSize.Width += 4; + } + finally + { + g.Dispose(); + } + CompositeImage image = this.Icon; + if (image != null) + IconSize = image.Size; + else + IconSize = Size.Empty; + } + m_Parent.Refresh(); + } + public void Dispose() + { + if (this.Item != null) + this.Item.TextChanged -= new EventHandler(this.ItemTextChanged); + } + } + #endregion + + #region PanelBar + private class PanelBar : IDisposable + { + public ArrayList Tabs = new ArrayList(10); + public int ActiveTab = -1; + public Bar BoundBar = null; + private AutoHidePanel m_Parent = null; + public static int TabPadding = 4; + public static int TabTextVPadding = 4; + public static int TabIconVPadding = 3; + private Size m_PanelSize = Size.Empty; + private int m_MaxTextWidth = 0; + + public PanelBar(AutoHidePanel parent, Bar bar) + { + m_Parent = parent; + BoundBar = bar; + ReloadDockItems(); + } + public void ReloadDockItems() + { + foreach (DockItemTab tab in Tabs) + tab.Dispose(); + Tabs.Clear(); + + Graphics g = BarFunctions.CreateGraphics(BoundBar); + try + { + if (BoundBar.LayoutType == eLayoutType.DockContainer) + { + foreach (BaseItem item in BoundBar.Items) + { + DockContainerItem dockItem = item as DockContainerItem; + if (dockItem != null && dockItem.Visible) + { + DockItemTab tab = new DockItemTab(this, dockItem); + this.Tabs.Add(tab); + tab.TextSize = TextDrawing.MeasureStringLegacy(g, dockItem.Text, m_Parent.Font, Size.Empty, eTextFormat.Default); + tab.TextSize.Width += 4; + } + } + } + if (this.Tabs.Count == 0) + { + DockItemTab tab = new DockItemTab(this, BoundBar.Text); + this.Tabs.Add(tab); + tab.TextSize = TextDrawing.MeasureStringLegacy(g, BoundBar.Text, m_Parent.Font, Size.Empty, eTextFormat.Default); + tab.TextSize.Width += 4; + } + } + finally + { + g.Dispose(); + } + m_PanelSize = CalcPanelSize(); + if (BoundBar.SelectedDockTab >= 0) + this.ActiveTab = BoundBar.SelectedDockTab; + else + this.ActiveTab = 0; + } + public void Refresh() + { + m_PanelSize = CalcPanelSize(); + m_Parent.Refresh(); + } + public void Dispose() + { + foreach (DockItemTab tab in Tabs) + tab.Dispose(); + Tabs.Clear(); + BoundBar = null; + m_Parent = null; + } + + public AutoHidePanel Parent + { + get { return m_Parent; } + } + + public Size PanelSize + { + get + { + return m_PanelSize; + } + } + + public int MaxTextWidth + { + get { return m_MaxTextWidth; } + } + + private Size CalcPanelSize() + { + Size size = Size.Empty; + Size textSize = Size.Empty; + + bool bHorizontal = true; + + foreach (DockItemTab tab in Tabs) + { + if (!tab.IconSize.IsEmpty) + { + if (bHorizontal) + { + size.Width += (tab.IconSize.Width + PanelBar.TabPadding * 2); + size.Height = tab.IconSize.Height + TabIconVPadding * 2; + } + else + { + size.Height += (tab.IconSize.Height + PanelBar.TabPadding * 2); + size.Width = tab.IconSize.Width + TabIconVPadding * 2; + } + } + if (bHorizontal) + { + if (tab.TextSize.Width > textSize.Width) + textSize.Width = tab.TextSize.Width; + if (tab.TextSize.Height > textSize.Height) + textSize.Height = tab.TextSize.Height; + } + else + { + if (tab.TextSize.Width > textSize.Height) + textSize.Height = tab.TextSize.Width; + if (tab.TextSize.Height > textSize.Width) + textSize.Width = tab.TextSize.Height; + } + } + if (bHorizontal) + { + m_MaxTextWidth = textSize.Width; + textSize.Width += PanelBar.TabPadding; + textSize.Height += (PanelBar.TabTextVPadding * 2); + size = new Size(size.Width + textSize.Width, (size.Height > textSize.Height ? size.Height : textSize.Height)); + if (StyleManager.IsMetro(StyleManager.Style)) + size.Height += 6; + } + else + { + m_MaxTextWidth = textSize.Height; + textSize.Height += PanelBar.TabPadding; + textSize.Width += (PanelBar.TabTextVPadding * 2); + size = new Size((size.Width > textSize.Height ? size.Width : textSize.Height), size.Height + textSize.Width); + if (StyleManager.IsMetro(StyleManager.Style)) + size.Width += 6; + } + + if (m_Parent != null && !m_Parent.FixedSize.IsEmpty) + return m_Parent.FixedSize; + return size; + } + } + #endregion + + #region VS2005TabDisplay + private class VS2005TabDisplay + { + protected AutoHidePanel m_AutoHidePanel = null; + private ColorScheme m_ColorScheme = null; + private int m_xTabOffset = 1; + private bool m_DisplayTextForActiveTabOnly = false; + /// + /// Creates new instance of the class. + /// + public VS2005TabDisplay(AutoHidePanel autoHidePanel, ColorScheme colorScheme) + { + m_AutoHidePanel = autoHidePanel; + m_ColorScheme = colorScheme; + } + + public bool DisplayTextForActiveTabOnly + { + get { return m_DisplayTextForActiveTabOnly; } + set { m_DisplayTextForActiveTabOnly = value; } + } + + public void Paint(Graphics g, ArrayList m_Panels) + { + ArrayList activeTabs = new ArrayList(); + Point p = new Point(0, 0); + + if (m_AutoHidePanel.Dock == DockStyle.Left || m_AutoHidePanel.Dock == DockStyle.Right) + { + p.Y = 2; + p.X = 1; + } + else + p.X = 2; + + foreach (PanelBar panel in m_Panels) + { + for (int i = 0; i < panel.Tabs.Count; i++) + { + bool displayText = true; + if (m_DisplayTextForActiveTabOnly && panel.ActiveTab != i && !panel.BoundBar.AutoHideTabTextAlwaysVisible) + displayText = false; + DockItemTab tab = panel.Tabs[i] as DockItemTab; + if (m_AutoHidePanel.Dock == DockStyle.Left || m_AutoHidePanel.Dock == DockStyle.Right) + { + tab.DisplayRectangle = new Rectangle(p.X, p.Y, m_AutoHidePanel.Width - 2, tab.IconSize.Width + 2 + + (displayText || tab.IconSize.Width == 0 ? tab.TextSize.Width : 4)); + p.Y += (tab.DisplayRectangle.Height + m_xTabOffset); + } + else + { + tab.DisplayRectangle = new Rectangle(p.X, p.Y, tab.IconSize.Width + 2 + + (displayText || tab.IconSize.Width == 0 ? tab.TextSize.Width : 4), m_AutoHidePanel.Height); + p.X += (tab.DisplayRectangle.Width + m_xTabOffset); + } + + if (panel.ActiveTab == i) + activeTabs.Add(tab); + else + PaintTab(g, tab, false); + } + if (m_AutoHidePanel.Dock == DockStyle.Left || m_AutoHidePanel.Dock == DockStyle.Right) + p.Y += 2; + else + p.X += 2; + } + + foreach (DockItemTab tab in activeTabs) + PaintTab(g, tab, true); + } + + protected virtual void PaintTab(Graphics g, DockItemTab tab, bool selected) + { + GraphicsPath path = GetTabItemPath(tab); + TabColors colors = GetTabColors(tab, selected); + + DrawTabItemBackground(tab, path, colors, g); + + DrawTabText(tab, colors, g, selected); + } + + protected virtual TabColors GetTabColors(DockItemTab tab, bool selected) + { + TabColors c = new TabColors(); + if (tab.Item != null && BarFunctions.IsOffice2007Style(tab.Item.EffectiveStyle)) + { + if (tab.Item.PredefinedTabColor == eTabItemColor.Default) + { + if (selected && !m_ColorScheme.AutoHideSelectedTabBackground.IsEmpty) + { + c.BackColor = m_ColorScheme.AutoHideSelectedTabBackground; + c.BackColor2 = m_ColorScheme.AutoHideSelectedTabBackground2; + c.BackColorGradientAngle = m_ColorScheme.AutoHideTabBackgroundGradientAngle; + c.TextColor = m_ColorScheme.AutoHideSelectedTabText; + c.BorderColor = m_ColorScheme.AutoHideSelectedTabBorder; + } + else if (!m_ColorScheme.AutoHideTabBackground.IsEmpty) + { + c.BackColor = m_ColorScheme.AutoHideTabBackground; + c.BackColor2 = m_ColorScheme.AutoHideTabBackground2; + c.BackColorGradientAngle = m_ColorScheme.AutoHideTabBackgroundGradientAngle; + c.TextColor = m_ColorScheme.AutoHideTabText; + c.BorderColor = m_ColorScheme.AutoHideTabBorder; + } + else + { + c.BackColor = m_ColorScheme.BarBackground; + c.BackColor2 = m_ColorScheme.BarBackground2; + c.BackColorGradientAngle = m_ColorScheme.BarBackgroundGradientAngle; + c.TextColor = m_ColorScheme.ItemText; + c.BorderColor = m_ColorScheme.BarDockedBorder; + } + } + else + { + Color c1, c2; + TabColorScheme.GetPredefinedColors(tab.Item.PredefinedTabColor, out c1, out c2); + c.BackColor = c1; + c.BackColor2 = c2; + c.BackColorGradientAngle = 90; + c.TextColor = m_ColorScheme.ItemText; + } + + if (m_AutoHidePanel != null && (m_AutoHidePanel.Dock == DockStyle.Left || m_AutoHidePanel.Dock == DockStyle.Right)) + { + c.BackColorGradientAngle -= 90; + } + } + else + { + c.BackColor = m_ColorScheme.DockSiteBackColor; + c.BackColor2 = m_ColorScheme.DockSiteBackColor; + c.TextColor = SystemColors.ControlText; + c.BorderColor = SystemColors.ControlDarkDark; + } + + return c; + } + + protected virtual void DrawTabItemBackground(DockItemTab tab, GraphicsPath path, TabColors colors, Graphics g) + { + RectangleF rf = path.GetBounds(); + Rectangle tabRect = new Rectangle((int)rf.X, (int)rf.Y, (int)rf.Width, (int)rf.Height); + + if (colors.BackColor2.IsEmpty) + { + if (!colors.BackColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(colors.BackColor)) + g.FillPath(brush, path); + } + } + else + { + using (SolidBrush brush = new SolidBrush(Color.White)) + g.FillPath(brush, path); + using (LinearGradientBrush brush = CreateTabGradientBrush(tabRect, colors.BackColor, colors.BackColor2, colors.BackColorGradientAngle)) + g.FillPath(brush, path); + } + + if (!colors.BorderColor.IsEmpty) + { + using (Pen pen = new Pen(colors.BorderColor, 1)) + g.DrawPath(pen, path); + } + } + + protected virtual void DrawTabText(DockItemTab tab, TabColors colors, Graphics g, bool selected) + { + int MIN_TEXT_WIDTH = 12; + eTextFormat strFormat = eTextFormat.Default | eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter + | eTextFormat.EndEllipsis | eTextFormat.SingleLine; + + Rectangle rText = tab.DisplayRectangle; + // Draw image + CompositeImage image = tab.Icon; + if (image != null && image.Width + 4 <= rText.Width) + { + if (m_AutoHidePanel.Dock == DockStyle.Top || m_AutoHidePanel.Dock == DockStyle.Bottom) + { + image.DrawImage(g, new Rectangle(rText.X + 3, rText.Y + (rText.Height - image.Height) / 2, image.Width, image.Height)); + int offset = image.Width + 2; + rText.X += offset; + rText.Width -= offset; + } + else + { + image.DrawImage(g, new Rectangle(rText.X + (rText.Width - image.Width) / 2, rText.Y + 3, image.Width, image.Height)); + int offset = image.Height + 2; + rText.Y += offset; + rText.Height -= offset; + } + } + + bool drawTextAlways = false; + if (tab.Item != null && tab.Item.ContainerControl is Bar) + drawTextAlways = ((Bar)tab.Item.ContainerControl).AutoHideTabTextAlwaysVisible; + if (m_DisplayTextForActiveTabOnly && !drawTextAlways && !selected && image != null) + return; + + // Draw text + //if(selected) + { + Font font = m_AutoHidePanel.Font; + rText.Inflate(-1, -1); + + if ((m_AutoHidePanel.Dock == DockStyle.Left || m_AutoHidePanel.Dock == DockStyle.Right)) + { + rText.Y += 2; + g.RotateTransform(90); + rText = new Rectangle(rText.Top, -rText.Right, rText.Height, rText.Width); + } + + if (rText.Width > MIN_TEXT_WIDTH) + { + TextDrawing.DrawStringLegacy(g, tab.Text, font, colors.TextColor, rText, strFormat); + } + + if ((m_AutoHidePanel.Dock == DockStyle.Left || m_AutoHidePanel.Dock == DockStyle.Right)) + g.ResetTransform(); + } + } + + protected virtual LinearGradientBrush CreateTabGradientBrush(Rectangle r, Color color1, Color color2, int gradientAngle) + { + if (r.Width <= 0) + r.Width = 1; + if (r.Height <= 0) + r.Height = 1; + LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(r.X, r.Y - 1, r.Width, r.Height + 1), color1, color2, gradientAngle); + return brush; + } + + protected virtual GraphicsPath GetTabItemPath(DockItemTab tab) + { + Rectangle r = tab.DisplayRectangle; + if (m_AutoHidePanel.Dock == DockStyle.Left) + r = new Rectangle(r.X - (r.Height - r.Width), r.Y, r.Height, r.Width); + else if (m_AutoHidePanel.Dock == DockStyle.Right) + r = new Rectangle(r.X, r.Y, r.Height, r.Width); + + r.Offset(0, 1); + + GraphicsPath path = new GraphicsPath(); + int cornerSize = 2; + // Left line + //path.AddPath(GetLeftLine(r),true); + path.AddLine(r.X, r.Bottom, r.X, r.Y + cornerSize); + + // Top line + path.AddLine(r.X + cornerSize, r.Y, r.Right - cornerSize, r.Y); + + // Right line + //path.AddPath(GetRightLine(r),true); + path.AddLine(r.Right, r.Y + cornerSize, r.Right, r.Bottom); + + // Bottom line + //path.AddLine(r.Right+m_xTabOffset,r.Bottom,r.X-m_xTabOffset,r.Bottom); + path.AddLine(r.Right, r.Bottom, r.X, r.Bottom); + + path.CloseAllFigures(); + + if (m_AutoHidePanel.Dock == DockStyle.Top) + { + // Bottom + Matrix m = new Matrix(); + m.RotateAt(180, new PointF(r.X + r.Width / 2, r.Y + r.Height / 2)); + path.Transform(m); + } + else if (m_AutoHidePanel.Dock == DockStyle.Right) + { + // Left + Matrix m = new Matrix(); + m.RotateAt(-90, new PointF(r.X, r.Bottom)); + m.Translate(r.Height, r.Width - r.Height, MatrixOrder.Append); + path.Transform(m); + } + else if (m_AutoHidePanel.Dock == DockStyle.Left) + { + // Right + Matrix m = new Matrix(); + m.RotateAt(90, new PointF(r.Right, r.Bottom)); + m.Translate(-r.Height, r.Width - (r.Height - 1), MatrixOrder.Append); + path.Transform(m); + } + + return path; + } + + private GraphicsPath GetLeftLine(Rectangle r) + { + GraphicsPath path = new GraphicsPath(); + // Left line + path.AddLine(r.X - m_xTabOffset, r.Bottom, r.X, r.Y + 5); + Point[] pc = new Point[3]; + pc[0] = new Point(r.X, r.Y + 5); + pc[1] = new Point(r.X + 2, r.Y + 2); + pc[2] = new Point(r.X + 5, r.Y); + path.AddCurve(pc, .9f); + return path; + } + + private GraphicsPath GetRightLine(Rectangle r) + { + GraphicsPath path = new GraphicsPath(); + // Right line + Point[] pc = new Point[3]; + pc[0] = new Point(r.Right - 5, r.Y); + pc[1] = new Point(r.Right - 2, r.Y + 2); + pc[2] = new Point(r.Right, r.Y + 5); + path.AddCurve(pc, .9f); + path.AddLine(r.Right, r.Y + 5, r.Right + m_xTabOffset, r.Bottom); + return path; + } + } + #endregion + + #region VS2012 Tab Display + private class VS2012TabDisplay : VS2005TabDisplay + { + private const int BorderSize = 6; + /// + /// Creates new instance of the class. + /// + public VS2012TabDisplay(AutoHidePanel autoHidePanel, ColorScheme colorScheme) + : base(autoHidePanel, colorScheme) + { + } + + protected override GraphicsPath GetTabItemPath(DockItemTab tab) + { + Rectangle r = tab.DisplayRectangle; + if (m_AutoHidePanel.Dock == DockStyle.Left) + r = new Rectangle(r.X - (r.Height - r.Width), r.Y, r.Height, r.Width); + else if (m_AutoHidePanel.Dock == DockStyle.Right) + r = new Rectangle(r.X, r.Y, r.Height, r.Width); + + r.Offset(0, 1); + + GraphicsPath path = new GraphicsPath(); + path.AddRectangle(r); + + return path; + } + protected override void DrawTabItemBackground(DockItemTab tab, GraphicsPath path, TabColors colors, Graphics g) + { + Rectangle tabRect = tab.DisplayRectangle; + + if (!colors.BackColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(colors.BackColor)) + g.FillPath(brush, path); + } + if (!colors.BorderColor.IsEmpty) + { + Rectangle br = new Rectangle(tabRect.X, tabRect.Y, BorderSize, tabRect.Height); + if (m_AutoHidePanel.Dock == DockStyle.Right) + br = new Rectangle(tabRect.Right - BorderSize, tabRect.Y, BorderSize, tabRect.Height); + else if (m_AutoHidePanel.Dock == DockStyle.Top) + br = new Rectangle(tabRect.X, tabRect.Y, tabRect.Width, BorderSize); + else if (m_AutoHidePanel.Dock == DockStyle.Bottom) + br = new Rectangle(tabRect.X, tabRect.Bottom - BorderSize, tabRect.Width, BorderSize); + using (SolidBrush brush = new SolidBrush(colors.BorderColor)) + g.FillRectangle(brush, br); + } + } + protected override TabColors GetTabColors(DockItemTab tab, bool selected) + { + selected = tab.IsMouseOver; + return base.GetTabColors(tab, selected); + } + } + #endregion + } +} + diff --git a/PROMS/DotNetBar Source Code/Balloon.cs b/PROMS/DotNetBar Source Code/Balloon.cs new file mode 100644 index 00000000..11c8adda --- /dev/null +++ b/PROMS/DotNetBar Source Code/Balloon.cs @@ -0,0 +1,2060 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Drawing.Text; +using DevComponents.DotNetBar.Rendering; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar +{ + /// + /// Indicates the Balloon tip position. + /// + public enum eTipPosition + { + /// + /// Tip is on the top. + /// + Top=0, + /// + /// Tip is on the left side. + /// + Left=1, + /// + /// Tip is on the right side. + /// + Right=2, + /// + /// Tip is on the bottom. + /// + Bottom=3 + } + + /// + /// Indicates the style of the balloon. + /// + public enum eBallonStyle + { + Balloon=0, + Alert=1, + Office2007Alert + } + + /// + /// Indicates type of Alert animation performed when alert is displayed. + /// + public enum eAlertAnimation + { + /// + /// No animation take place when alert is displayed. + /// + None=0, + /// + /// Alert is animated from bottom to top. (Default) + /// + BottomToTop=1, + /// + /// Alert is animated from top to bottom. + /// + TopToBottom=2, + /// + /// Alert is animated from left to right. + /// + LeftToRight=3, + /// + /// Alert is animated from right to left. + /// + RightToLeft=4 + } + + /// + /// Delegate for custom paint event handler. + /// + public delegate void CustomPaintEventHandler(object sender, CustomPaintEventArgs e); + + /// + /// Summary description for Balloon. + /// + [ToolboxItem(false), System.Runtime.InteropServices.ComVisible(false), Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] + public class Balloon : System.Windows.Forms.Form + { + private System.ComponentModel.IContainer components; + #region Event Definition + /// + /// Occurs when background is redrawn. + /// + public event CustomPaintEventHandler PaintBackground; + /// + /// Occurs when caption image is redrawn. + /// + public event CustomPaintEventHandler PaintCaptionImage; + /// + /// Occurs when caption text is redrawn. + /// + public event CustomPaintEventHandler PaintCaptionText; + /// + /// Occurs when text is redrawn. + /// + public event CustomPaintEventHandler PaintText; + /// + /// Occurs when close button is clicked. + /// + public event EventHandler CloseButtonClick; + /// + /// Occurs when TipPosition property has changed. + /// + public event EventHandler TipPositionChanged; + #endregion + + + private int m_TipLength=16; + private int m_CornerSize=8; + private int m_TipOffset=32; + private eTipPosition m_TipPosition=eTipPosition.Top; + + private Color m_BackColor2=Color.Empty; + private int m_BackColorGradientAngle=90; + + private eBackgroundImagePosition m_BackgroundImagePosition=eBackgroundImagePosition.Stretch; + private int m_BackgroundImageAlpha=255; + + private Color m_BorderColor=SystemColors.InfoText; + + private bool m_ShowCloseButton=true; + private ImageButton m_CloseButton=null; + + private eBallonStyle m_Style=eBallonStyle.Balloon; + + private Image m_CloseButtonNormal=null, m_CloseButtonHot=null, m_CloseButtonPressed=null; + private Image m_CaptionImage=null; + private Icon m_CaptionIcon=null; + private Font m_CaptionFont=null; + private string m_CaptionText=""; + private StringAlignment m_CaptionAlignment=StringAlignment.Near; + private Color m_CaptionColor=SystemColors.InfoText; + + private StringAlignment m_TextAlignment=StringAlignment.Near; + private StringAlignment m_TextLineAlignment=StringAlignment.Center; + + // Layout rectangles + private Rectangle m_CaptionImageRectangle=Rectangle.Empty; + private Rectangle m_CaptionRectangle=Rectangle.Empty; + private Rectangle m_TextRectangle=Rectangle.Empty; + + private bool m_AutoClose=true; + private int m_AutoCloseTimeOut=0; + private System.Windows.Forms.Timer m_Timer=null; + + const int IMAGETEXT_SPACING=4; + const int TEXTCLOSE_SPACING=4; + const int CAPTIONTEXT_VSPACING=1; + const int CAPTIONALERT_VSPACING=1; + + private Color m_BorderColor1=Color.FromArgb(241,239,226); + private Color m_BorderColor2=Color.White; + private Color m_BorderColor3=Color.FromArgb(236,233,216); + private Color m_BorderColor4=Color.FromArgb(172,168,153); + private Color m_BorderColor5=Color.FromArgb(113,111,100); + + private eAlertAnimation m_AlertAnimation=eAlertAnimation.BottomToTop; + private int m_AlertAnimationDuration=200; + private bool m_AnimationInProgress=false; + private bool m_AntiAlias = true; + + public Balloon() + { + CreateCloseButton(); + // + // Required for Windows Form Designer support + // + InitializeComponent(); + if(components==null) + this.components = new System.ComponentModel.Container(); + m_CaptionFont=new Font(this.Font,FontStyle.Bold); + + this.SetStyle(ControlStyles.UserPaint,true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint,true); + //this.SetStyle(ControlStyles.Opaque,true); + this.SetStyle(ControlStyles.ResizeRedraw,true); + this.SetStyle(DisplayHelp.DoubleBufferFlag,true); + this.SetStyle(ControlStyles.ContainerControl,true); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + DestroyAutoCloseTimer(); + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + + if (BarUtilities.DisposeItemImages && !this.DesignMode) + { + BarUtilities.DisposeImage(ref m_CaptionIcon); + BarUtilities.DisposeImage(ref m_CaptionImage); + BarUtilities.DisposeImage(ref m_CloseButtonHot); + BarUtilities.DisposeImage(ref m_CloseButtonNormal); + BarUtilities.DisposeImage(ref m_CloseButtonPressed); + } + base.Dispose( disposing ); + } + + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is false. + /// + [DefaultValue(true), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public bool AntiAlias + { + get { return m_AntiAlias; } + set + { + m_AntiAlias = value; + this.Invalidate(); + } + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + // + // Balloon + // + this.AccessibleRole = System.Windows.Forms.AccessibleRole.HelpBalloon; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.AutoScaleMode = AutoScaleMode.None; + this.BackColor = System.Drawing.SystemColors.Info; // ColorScheme.GetColor(0xFFFFBD);// + this.ClientSize = new System.Drawing.Size(192, 80); + this.ControlBox = false; + this.ForeColor = System.Drawing.SystemColors.InfoText; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "Balloon"; + this.ShowInTaskbar = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + + } + #endregion + + protected override void OnClick(EventArgs e) + { + if(m_ShowCloseButton && m_CloseButton.Bounds.Contains(this.PointToClient(Control.MousePosition))) + return; + base.OnClick(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + SmoothingMode sm = e.Graphics.SmoothingMode; + TextRenderingHint th = e.Graphics.TextRenderingHint; + + if (m_AntiAlias) + { + e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + e.Graphics.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + if(m_Style==eBallonStyle.Balloon) + PaintBalloon(e.Graphics); + else + PaintAlert(e.Graphics); + + e.Graphics.SmoothingMode = sm; + e.Graphics.TextRenderingHint = th; + } + + private void PaintAlert(Graphics g) + { + Rectangle client=this.GetAlertClientRect(); + if(PaintBackground!=null) + PaintBackground(this,new CustomPaintEventArgs(g,client)); + else + { + PaintBackgroundInternal(g); + if (m_Style == eBallonStyle.Alert) + { + // Paint Caption Background + Rectangle rCap = client; + rCap.Height = Math.Max(m_CaptionImageRectangle.Bottom, m_CaptionRectangle.Bottom) - rCap.Top; + rCap.Height += CAPTIONALERT_VSPACING; + if (rCap.Width > 0 && rCap.Height > 0) + { + using (LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(rCap, this.BackColor, m_BackColor2, m_BackColorGradientAngle)) + { + Blend b = new Blend(4); + b.Positions = new float[] { 0f, .5f, .5f, 1f }; + b.Factors = new float[] { 0f, 1f, 1f, 0f }; + gradient.Blend = b; + g.FillRectangle(gradient, rCap); + } + } + } + } + + // Draw Border + Rectangle r=this.DisplayRectangle; + if (m_Style == eBallonStyle.Office2007Alert) + { + DisplayHelp.DrawRectangle(g, m_BorderColor, r); + } + else + { + r.Width--; + r.Height--; + using (Pen pen = new Pen(m_BorderColor1, 1)) + { + g.DrawLine(pen, r.X, r.Y, r.Right, r.Y); + g.DrawLine(pen, r.X, r.Y, r.X, r.Bottom); + g.DrawLine(pen, r.X + 4, r.Bottom - 4, r.Right - 4, r.Bottom - 4); + g.DrawLine(pen, r.Right - 4, r.Y + 4, r.Right - 4, r.Bottom - 4); + } + using (Pen pen = new Pen(m_BorderColor2, 1)) + { + g.DrawLine(pen, r.X + 1, r.Y + 1, r.Right - 1, r.Y + 1); + g.DrawLine(pen, r.X + 1, r.Y + 1, r.X + 1, r.Bottom - 1); + g.DrawLine(pen, r.X + 3, r.Bottom - 3, r.Right - 3, r.Bottom - 3); + g.DrawLine(pen, r.Right - 3, r.Y + 3, r.Right - 3, r.Bottom - 3); + } + using (Pen pen = new Pen(m_BorderColor3, 1)) + { + g.DrawLine(pen, r.X + 2, r.Y + 2, r.Right - 2, r.Y + 2); + g.DrawLine(pen, r.X + 2, r.Y + 2, r.X + 2, r.Bottom - 2); + g.DrawLine(pen, r.X + 2, r.Bottom - 2, r.Right - 2, r.Bottom - 2); + g.DrawLine(pen, r.Right - 2, r.Y + 2, r.Right - 2, r.Bottom - 2); + } + using (Pen pen = new Pen(m_BorderColor4, 1)) + { + g.DrawLine(pen, r.X + 3, r.Y + 3, r.Right - 3, r.Y + 3); + g.DrawLine(pen, r.X + 3, r.Y + 3, r.X + 3, r.Bottom - 3); + g.DrawLine(pen, r.X + 1, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + g.DrawLine(pen, r.Right - 1, r.Y + 1, r.Right - 1, r.Bottom - 1); + } + using (Pen pen = new Pen(m_BorderColor5, 1)) + { + g.DrawLine(pen, r.X + 4, r.Y + 4, r.Right - 4, r.Y + 4); + g.DrawLine(pen, r.X + 4, r.Y + 4, r.X + 4, r.Bottom - 4); + g.DrawLine(pen, r.X, r.Bottom, r.Right, r.Bottom); + g.DrawLine(pen, r.Right, r.Y, r.Right, r.Bottom); + } + } + + + if(m_CloseButton!=null) + m_CloseButton.Paint(g); + + if(PaintCaptionImage!=null) + PaintCaptionImage(this,new CustomPaintEventArgs(g,m_CaptionImageRectangle)); + else + { + CompositeImage image=this.ImageInternal; + if(image!=null && !m_CaptionImageRectangle.IsEmpty) + image.DrawImage(g,m_CaptionImageRectangle); + } + + if(PaintCaptionText!=null) + PaintCaptionText(this,new CustomPaintEventArgs(g,m_CaptionRectangle)); + else + { + if(m_CaptionText!="" && !m_CaptionRectangle.IsEmpty) + { + eTextFormat format = eTextFormat.Default | eTextFormat.WordBreak; + if (m_CaptionAlignment == StringAlignment.Center) + format |= eTextFormat.HorizontalCenter; + else if (m_CaptionAlignment == StringAlignment.Far) + format |= eTextFormat.Right; + Font font=m_CaptionFont; + if(font==null) + font=this.Font; + if (_CaptionTextMarkup != null) + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, m_CaptionColor, (this.RightToLeft == RightToLeft.Yes), r, true); + _CaptionTextMarkup.Arrange(m_CaptionRectangle, d); + _CaptionTextMarkup.Render(d); + } + else + TextDrawing.DrawString(g, m_CaptionText, font, m_CaptionColor, m_CaptionRectangle, format); + } + } + + if(PaintText!=null) + PaintText(this,new CustomPaintEventArgs(g,m_TextRectangle)); + else + { + if(this.Text!="") + { + eTextFormat format = eTextFormat.Default | eTextFormat.WordBreak; + if (m_TextAlignment == StringAlignment.Center) + format |= eTextFormat.HorizontalCenter; + else if (m_TextAlignment == StringAlignment.Far) + format |= eTextFormat.Right; + if (m_TextLineAlignment == StringAlignment.Center) + format |= eTextFormat.VerticalCenter; + else if (m_TextLineAlignment == StringAlignment.Far) + format |= eTextFormat.Bottom; + if (_TextMarkup != null) + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, this.ForeColor, + (this.RightToLeft == RightToLeft.Yes), r, true); + _TextMarkup.Arrange(m_TextRectangle, d); + _TextMarkup.Render(d); + } + else + TextDrawing.DrawString(g, this.Text, this.Font, this.ForeColor, m_TextRectangle, format); + } + } + } + + private void PaintBalloon(Graphics g) + { + Rectangle r = new Rectangle(0, 0, this.Width, this.Height); //this.DisplayRectangle; + GraphicsPath path=this.GetBalloonPath(r); + if(PaintBackground!=null) + PaintBackground(this,new CustomPaintEventArgs(g,r)); + else + PaintBackgroundInternal(g); + + using(Pen pen=new Pen(m_BorderColor,1)) + { + pen.Alignment=PenAlignment.Inset; + g.DrawPath(pen,path); + } + + if(m_CloseButton!=null) + m_CloseButton.Paint(g); + + if(PaintCaptionImage!=null) + PaintCaptionImage(this,new CustomPaintEventArgs(g,m_CaptionImageRectangle)); + else + { + CompositeImage image=this.ImageInternal; + if(image!=null && !m_CaptionImageRectangle.IsEmpty) + image.DrawImage(g,m_CaptionImageRectangle); + } + + if(PaintCaptionText!=null) + PaintCaptionText(this,new CustomPaintEventArgs(g,m_CaptionRectangle)); + else + { + if(m_CaptionText!="" && !m_CaptionRectangle.IsEmpty) + { + eTextFormat format = eTextFormat.Default | TextDrawing.TranslateHorizontal(m_CaptionAlignment) | eTextFormat.WordBreak; + Font font = m_CaptionFont; + if (font == null) + font = this.Font; + + + if (_CaptionTextMarkup != null) + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, m_CaptionColor, (this.RightToLeft == RightToLeft.Yes), r, true); + _CaptionTextMarkup.Arrange(m_CaptionRectangle, d); + _CaptionTextMarkup.Render(d); + } + else + TextDrawing.DrawString(g, m_CaptionText, font, m_CaptionColor, m_CaptionRectangle, format); + } + } + + if(PaintText!=null) + PaintText(this,new CustomPaintEventArgs(g,m_TextRectangle)); + else + { + if(this.Text!="") + { + eTextFormat format = eTextFormat.Default | TextDrawing.TranslateHorizontal(m_TextAlignment) | + TextDrawing.TranslateVertical(m_TextLineAlignment) | eTextFormat.WordBreak; + if (_TextMarkup != null) + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, this.ForeColor, + (this.RightToLeft == RightToLeft.Yes), r, true); + _TextMarkup.Arrange(m_TextRectangle, d); + _TextMarkup.Render(d); + } + else + TextDrawing.DrawString(g, this.Text, this.Font, this.ForeColor, m_TextRectangle, format); + } + } + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + if(!m_AnimationInProgress) + this.RecalcLayout(); + } + private int _MinimumBalloonWidth = 180; + /// + /// Gets or sets the minimum balloon width when auto sizing balloon. Default value is 180. + /// + [DefaultValue(180), Category("Appearance"), Description("Indicates minimum balloon width when auto sizing balloon.")] + public int MinimumBalloonWidth + { + get { return _MinimumBalloonWidth; } + set { _MinimumBalloonWidth = value; } + } + + private TextMarkup.BodyElement _TextMarkup = null; + protected override void OnTextChanged(EventArgs e) + { + string text = this.Text; + + if (_TextMarkup != null) + { + _TextMarkup.MouseLeave(this); + _TextMarkup.HyperLinkClick -= new EventHandler(TextMarkupLinkClicked); + _TextMarkup = null; + } + + if (TextMarkup.MarkupParser.IsMarkup(ref text)) + _TextMarkup = TextMarkup.MarkupParser.Parse(text); + + if (_TextMarkup != null) + { + _TextMarkup.HyperLinkClick += new EventHandler(TextMarkupLinkClicked); + } + this.Invalidate(); + base.OnTextChanged(e); + } + + private void TextMarkupLinkClicked(object sender, EventArgs e) + { + TextMarkup.HyperLink link = sender as TextMarkup.HyperLink; + if (link != null) + { + OnMarkupLinkClick(new MarkupLinkClickEventArgs(link.Name, link.HRef)); + } + } + + /// + /// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + [Description("Occurs when text markup link is clicked. Markup links can be created using tag.")] + public event MarkupLinkClickEventHandler MarkupLinkClick; + + protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e) + { + if (this.MarkupLinkClick != null) + MarkupLinkClick(this, e); + } + + protected virtual Size ResizeMarkup(Graphics g, int containerWidth) + { + if (_TextMarkup != null) + { + Rectangle r= new Rectangle(0,0,containerWidth, 1); + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, SystemColors.Control, (this.RightToLeft == RightToLeft.Yes)); + _TextMarkup.Measure(r.Size, d); + //_TextMarkup.Arrange(r, d); + return _TextMarkup.Bounds.Size; + } + return Size.Empty; + } + + protected virtual Size ResizeCaptionMarkup(Graphics g, int containerWidth) + { + if (_CaptionTextMarkup != null) + { + Rectangle r = new Rectangle(0, 0, containerWidth, 1); + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, SystemColors.Control, (this.RightToLeft == RightToLeft.Yes)); + _CaptionTextMarkup.Measure(r.Size, d); + //_TextMarkup.Arrange(r, d); + return _CaptionTextMarkup.Bounds.Size; + } + return Size.Empty; + } + + /// + /// Auto resize balloon to the content. Balloon width is calculated so image and caption text can fit in single line. + /// + public void AutoResize() + { + System.Drawing.Size newSize = new Size(Dpi.Width(_MinimumBalloonWidth), 0); + + Size strSize=Size.Empty; + + // Calculates caption text rectangle height + Font font=m_CaptionFont; + if(font==null) + font=this.Font; + Graphics g=this.CreateGraphics(); + try + { + if (_CaptionTextMarkup != null) + strSize = ResizeCaptionMarkup(g, 800); + else + strSize = TextDrawing.MeasureString(g,(m_CaptionText != "" ? m_CaptionText : " "), font); + + newSize.Width = Math.Max(newSize.Width, strSize.Width); + if(m_CloseButton!=null) + newSize.Width+=Dpi.Width(m_CloseButton.Size.Width); + else + newSize.Width+=Dpi.Width18; + newSize.Width+=TEXTCLOSE_SPACING; + + int imageHeight=0; + if(m_CaptionIcon!=null) + { + newSize.Width+=Dpi.Width(m_CaptionIcon.Width+IMAGETEXT_SPACING); + imageHeight = Dpi.Height(m_CaptionIcon.Height); + } + else if(m_CaptionImage!=null) + { + newSize.Width+=Dpi.Width(m_CaptionImage.Width+IMAGETEXT_SPACING); + imageHeight = Dpi.Height(m_CaptionImage.Height); + } + + newSize.Height+=Math.Max(imageHeight,strSize.Height); + newSize.Height+=IMAGETEXT_SPACING*2; + + if (_TextMarkup == null) + strSize = TextDrawing.MeasureString(g, (this.Text != "" ? this.Text : " "), this.Font, newSize.Width, + eTextFormat.Default | eTextFormat.WordBreak); + else + strSize = ResizeMarkup(g, newSize.Width); + + newSize.Height+=strSize.Height; + + newSize.Width+=m_CornerSize*2; + newSize.Height+=m_CornerSize*2; + + if(m_Style==eBallonStyle.Balloon) + { + if(m_TipPosition==eTipPosition.Left || m_TipPosition==eTipPosition.Right) + newSize.Width+=Dpi.Width(m_TipLength); + else + newSize.Height+=Dpi.Height(m_TipLength); + } + else + newSize.Height+=(int)((float)newSize.Height*.3); + } + finally + { + g.Dispose(); + } + + this.Size=newSize; + } + + /// + /// Recalculates layout of the balloon. + /// + public void RecalcLayout() + { + if(this.DisplayRectangle.Width==0 || this.DisplayRectangle.Height==0) + return; + + Size closeButtonSize = Size.Empty; + if (m_CloseButton != null) + closeButtonSize = m_CloseButton.Size; + if(m_Style==eBallonStyle.Balloon) + { + Rectangle client=new Rectangle(m_CornerSize/2,m_CornerSize/2,this.Width-m_CornerSize,this.Height-m_CornerSize); + if(m_TipPosition==eTipPosition.Bottom) + client.Height-=m_TipLength; + else if(m_TipPosition==eTipPosition.Left) + { + client.X+=m_TipLength; + client.Width-=m_TipLength; + } + else if(m_TipPosition==eTipPosition.Right) + client.Width-=m_TipLength; + else + { + // TOP + client.Y+=m_TipLength; + client.Height-=m_TipLength; + } + + System.Drawing.Size imageSize=System.Drawing.Size.Empty; + if(m_CaptionIcon!=null) + imageSize=Dpi.ImageSize(m_CaptionIcon.Size); + else if(m_CaptionImage!=null) + imageSize=Dpi.ImageSize(m_CaptionImage.Size); + + m_CaptionRectangle=client; + if(!imageSize.IsEmpty) + { + m_CaptionRectangle.X+=(imageSize.Width+IMAGETEXT_SPACING); + m_CaptionRectangle.Width-=(imageSize.Width+IMAGETEXT_SPACING); + } + + // Calculates position of the close button if visible + if(m_CloseButton!=null) + { + m_CloseButton.Location = new Point(client.Right - closeButtonSize.Width, client.Top); + m_CaptionRectangle.Width-=(closeButtonSize.Width+TEXTCLOSE_SPACING); + } + + // Calculates caption text rectangle height + Font font=m_CaptionFont; + if(font==null) + font=this.Font; + Graphics g=this.CreateGraphics(); + try + { + eTextFormat format = eTextFormat.Default | eTextFormat.WordBreak; + if (m_CaptionAlignment == StringAlignment.Center) + format = eTextFormat.HorizontalCenter; + else if (m_CaptionAlignment == StringAlignment.Far) + format = eTextFormat.Right; + Size strSize = Size.Empty; + if (_CaptionTextMarkup != null) + strSize = ResizeCaptionMarkup(g, m_CaptionRectangle.Width); + else + strSize = TextDrawing.MeasureString(g,(m_CaptionText!=""?m_CaptionText:" "),font,m_CaptionRectangle.Width,format); + m_CaptionRectangle.Height=strSize.Height; + } + finally + { + g.Dispose(); + } + + // Calculates position of the image rectangle + if(!imageSize.IsEmpty) + { + m_CaptionImageRectangle=new Rectangle(client.X,client.Y,imageSize.Width,imageSize.Height); + if(m_CaptionRectangle.Height>imageSize.Height) + m_CaptionImageRectangle.Y+=(int)(m_CaptionRectangle.Height-imageSize.Height)/2; + else if(imageSize.Height>m_CaptionRectangle.Height) + m_CaptionRectangle.Y+=(int)(imageSize.Height-m_CaptionRectangle.Height)/2; + + } + else if(m_CloseButton!=null && closeButtonSize.Height>m_CaptionRectangle.Height) + m_CaptionRectangle.Y+=(int)(closeButtonSize.Height-m_CaptionRectangle.Height)/2; + + // Calculates the rectangle for balloon text + if(m_CaptionRectangle.Bottom>m_CaptionImageRectangle.Bottom) + m_TextRectangle=new Rectangle(client.X,m_CaptionRectangle.Bottom+CAPTIONTEXT_VSPACING,client.Width,client.Bottom-(m_CaptionRectangle.Bottom+CAPTIONTEXT_VSPACING)); + else + m_TextRectangle=new Rectangle(client.X,m_CaptionImageRectangle.Bottom+CAPTIONTEXT_VSPACING,client.Width,client.Bottom-(m_CaptionImageRectangle.Bottom+CAPTIONTEXT_VSPACING)); + + // Calculates and sets the balloon window region + GraphicsPath path=this.GetBalloonPath(this.DisplayRectangle); + GraphicsPath tmpPath = (GraphicsPath)path.Clone(); + tmpPath.Widen(Pens.Black); + Region region = new Region(tmpPath); + region.Union(path); + this.Region=region; + path.Dispose(); + tmpPath.Dispose(); + } + else + { + Rectangle client=this.GetAlertClientRect(); + System.Drawing.Size imageSize=System.Drawing.Size.Empty; + + if(m_CaptionIcon!=null) + imageSize=Dpi.ImageSize(m_CaptionIcon.Size); + else if(m_CaptionImage!=null) + imageSize=Dpi.ImageSize(m_CaptionImage.Size); + + m_CaptionRectangle=client; + if(!imageSize.IsEmpty) + { + m_CaptionRectangle.X+=(imageSize.Width+IMAGETEXT_SPACING*2); + m_CaptionRectangle.Width-=(imageSize.Width+IMAGETEXT_SPACING*2); + } + + // Calculates position of the close button if visible + if(m_CloseButton!=null) + { + m_CloseButton.Location=new Point(client.Right-m_CloseButton.Bounds.Width-CAPTIONALERT_VSPACING,client.Top); + m_CaptionRectangle.Width-=(closeButtonSize.Width+TEXTCLOSE_SPACING+CAPTIONALERT_VSPACING); + } + + // Calculates caption text rectangle height + Font font=m_CaptionFont; + if(font==null) + font=this.Font; + Graphics g=this.CreateGraphics(); + try + { + eTextFormat format = eTextFormat.Default | eTextFormat.WordBreak; + if (m_CaptionAlignment == StringAlignment.Center) + format = eTextFormat.HorizontalCenter; + else if (m_CaptionAlignment == StringAlignment.Far) + format = eTextFormat.Right; + Size strSize = TextDrawing.MeasureString(g, (m_CaptionText != "" ? m_CaptionText : " "), font, m_CaptionRectangle.Width, format); + m_CaptionRectangle.Height=strSize.Height; + } + finally + { + g.Dispose(); + } + + // Calculates position of the image rectangle + if(!imageSize.IsEmpty) + { + m_CaptionImageRectangle=new Rectangle(client.X+IMAGETEXT_SPACING,client.Y,imageSize.Width,imageSize.Height); + if(m_CaptionRectangle.Height>imageSize.Height) + m_CaptionImageRectangle.Y+=(int)(m_CaptionRectangle.Height-imageSize.Height)/2; + else if(imageSize.Height>m_CaptionRectangle.Height) + { + m_CaptionRectangle.Y+=(int)(imageSize.Height+-m_CaptionRectangle.Height)/2; + } + + } + else if(m_CloseButton!=null && closeButtonSize.Height>m_CaptionRectangle.Height) + m_CaptionRectangle.Y+=(int)(closeButtonSize.Height-m_CaptionRectangle.Height)/2; + + m_CaptionRectangle.Offset(0,CAPTIONALERT_VSPACING); + m_CaptionImageRectangle.Offset(0,CAPTIONALERT_VSPACING); + + if(m_CloseButton!=null) + { + m_CloseButton.Location=new Point(m_CloseButton.Location.X,m_CaptionRectangle.Y+(m_CaptionRectangle.Height-closeButtonSize.Height)/2); + } + + + // Calculates the rectangle for balloon text + if(m_CaptionRectangle.Bottom>m_CaptionImageRectangle.Bottom) + m_TextRectangle=new Rectangle(client.X,m_CaptionRectangle.Bottom+CAPTIONTEXT_VSPACING*4,client.Width,client.Bottom-(m_CaptionRectangle.Bottom+CAPTIONTEXT_VSPACING*4)); + else + m_TextRectangle=new Rectangle(client.X,m_CaptionImageRectangle.Bottom+CAPTIONTEXT_VSPACING*4,client.Width,client.Bottom-(m_CaptionImageRectangle.Bottom+CAPTIONTEXT_VSPACING*4)); + + this.Region=new Region(this.DisplayRectangle); + } + } + + private Rectangle GetAlertClientRect() + { + Rectangle r = new Rectangle(0, 0, this.Width, this.Height); // this.DisplayRectangle; + r.Inflate(-4,-4); + return r; + } + + private GraphicsPath GetBalloonPath(Rectangle rect) + { + GraphicsPath path = new GraphicsPath(); + + Rectangle clipBounds=rect; + Rectangle balloonBounds=clipBounds; + int cornerDiameter=m_CornerSize*2; + Matrix matrix=new Matrix(); + Point[] anchorPoints=new Point[3]; + int tipOffset=m_TipOffset; + + balloonBounds.Size=new Size(balloonBounds.Width-1,balloonBounds.Height-1); + + bool adjustOffset = false; + if(m_TipPosition==eTipPosition.Bottom) + { + adjustOffset=true; + matrix.Translate(balloonBounds.Width, balloonBounds.Height); + matrix.Rotate(180); + } + else if (m_TipPosition == eTipPosition.Left && this.RightToLeft == RightToLeft.No || + m_TipPosition == eTipPosition.Right && this.RightToLeft == RightToLeft.Yes) + { + adjustOffset = true; + balloonBounds.Size=new Size(balloonBounds.Height, balloonBounds.Width); + matrix.Translate(0, balloonBounds.Width); + matrix.Rotate(-90); + } + else if(m_TipPosition==eTipPosition.Right && this.RightToLeft == RightToLeft.No || + m_TipPosition == eTipPosition.Left && this.RightToLeft == RightToLeft.Yes) + { + balloonBounds.Size=new Size(balloonBounds.Height, balloonBounds.Width); + matrix.Translate(balloonBounds.Height, 0); + matrix.Rotate(90); + } + + int balloonEdgeCenter =((int)(balloonBounds.Width-(m_CornerSize*2))/2)+1; + int offsetFromEdge = m_CornerSize; + if(adjustOffset) + { + tipOffset=(balloonBounds.Width-(offsetFromEdge*2)-m_TipOffset)+1; + } + if(tipOffsetballoonEdgeCenter) + { + anchorPoints[0]=new Point(tipOffset-m_TipLength+offsetFromEdge,balloonBounds.Y+m_TipLength); + anchorPoints[1]=new Point(tipOffset+offsetFromEdge,balloonBounds.Y); + anchorPoints[2]=new Point(tipOffset+offsetFromEdge,balloonBounds.Y+m_TipLength); + } + else + { + anchorPoints[0]=new Point(tipOffset-m_TipLength+offsetFromEdge,balloonBounds.Y+m_TipLength); + anchorPoints[1]=new Point(tipOffset+offsetFromEdge,balloonBounds.Y); + anchorPoints[2]=new Point(tipOffset+m_TipLength+offsetFromEdge,balloonBounds.Y+m_TipLength); + } + + path.AddArc(balloonBounds.Left,balloonBounds.Top+m_TipLength,cornerDiameter, cornerDiameter,180, 90); + + path.AddLine(anchorPoints[0],anchorPoints[1]); + path.AddLine(anchorPoints[1],anchorPoints[2]); + + path.AddArc(balloonBounds.Width-cornerDiameter,balloonBounds.Top+m_TipLength,cornerDiameter, cornerDiameter, -90, 90); + path.AddArc(balloonBounds.Width-cornerDiameter,balloonBounds.Bottom-cornerDiameter,cornerDiameter, cornerDiameter, 0, 90); + path.AddArc(balloonBounds.Left, balloonBounds.Bottom-cornerDiameter,cornerDiameter, cornerDiameter, 90, 90); + + path.CloseFigure(); + + path.Transform(matrix); + + return path; + } + + private void PaintBackgroundInternal(Graphics g) + { + Rectangle r=this.ClientRectangle; + if(r.Width==0 || r.Height==0) + return; + + if(m_BackColor2.IsEmpty) + { + using(SolidBrush brush=new SolidBrush(this.BackColor)) + g.FillRectangle(brush,r); + } + else + { + using(LinearGradientBrush gradient=BarFunctions.CreateLinearGradientBrush(r,this.BackColor,m_BackColor2,m_BackColorGradientAngle)) + { + if(m_Style==eBallonStyle.Alert) + { + Blend b=new Blend(4); + b.Positions=new float[]{0f,.25f,.4f,.5f,.5f,.85f,.85f,1f}; + b.Factors=new float[] {0f,1f,1f,0f,0f,0f,0f,1f}; + gradient.Blend=b; + } + g.FillRectangle(gradient,r); + } + } + + if(this.BackgroundImage==null) + return; + +// System.Drawing.Imaging.ImageAttributes imageAtt=null; +// +// if(m_BackgroundImageAlpha!=255) +// { +// System.Drawing.Imaging.ColorMatrix colorMatrix=new System.Drawing.Imaging.ColorMatrix(); +// colorMatrix.Matrix33=255-m_BackgroundImageAlpha; +// imageAtt=new System.Drawing.Imaging.ImageAttributes(); +// imageAtt.SetColorMatrix(colorMatrix,System.Drawing.Imaging.ColorMatrixFlag.Default,System.Drawing.Imaging.ColorAdjustType.Bitmap); +// } + + BarFunctions.PaintBackgroundImage(g,r,this.BackgroundImage,m_BackgroundImagePosition,m_BackgroundImageAlpha); + +// switch(m_BackgroundImagePosition) +// { +// case eBackgroundImagePosition.Stretch: +// { +// if(imageAtt!=null) +// g.DrawImage(this.BackgroundImage,r,0,0,this.BackgroundImage.Width,this.BackgroundImage.Height,GraphicsUnit.Pixel,imageAtt); +// else +// g.DrawImage(this.BackgroundImage,r,0,0,this.BackgroundImage.Width,this.BackgroundImage.Height,GraphicsUnit.Pixel); +// break; +// } +// case eBackgroundImagePosition.Center: +// { +// Rectangle destRect=new Rectangle(r.X,r.Y,this.BackgroundImage.Width,this.BackgroundImage.Height); +// if(r.Width>this.BackgroundImage.Width) +// destRect.X+=(r.Width-this.BackgroundImage.Width)/2; +// if(r.Height>this.BackgroundImage.Height) +// destRect.Y+=(r.Height-this.BackgroundImage.Height)/2; +// if(imageAtt!=null) +// g.DrawImage(this.BackgroundImage,destRect,0,0,this.BackgroundImage.Width,this.BackgroundImage.Height,GraphicsUnit.Pixel,imageAtt); +// else +// g.DrawImage(this.BackgroundImage,destRect,0,0,this.BackgroundImage.Width,this.BackgroundImage.Height,GraphicsUnit.Pixel); +// break; +// } +// case eBackgroundImagePosition.TopLeft: +// case eBackgroundImagePosition.TopRight: +// case eBackgroundImagePosition.BottomLeft: +// case eBackgroundImagePosition.BottomRight: +// { +// Rectangle destRect=new Rectangle(r.X,r.Y,this.BackgroundImage.Width,this.BackgroundImage.Height); +// if(m_BackgroundImagePosition==eBackgroundImagePosition.TopRight) +// destRect.X=r.Right-this.BackgroundImage.Width; +// else if(m_BackgroundImagePosition==eBackgroundImagePosition.BottomLeft) +// destRect.Y=r.Bottom-this.BackgroundImage.Height; +// else if(m_BackgroundImagePosition==eBackgroundImagePosition.BottomRight) +// { +// destRect.Y=r.Bottom-this.BackgroundImage.Height; +// destRect.X=r.Right-this.BackgroundImage.Width; +// } +// +// if(imageAtt!=null) +// g.DrawImage(this.BackgroundImage,destRect,0,0,this.BackgroundImage.Width,this.BackgroundImage.Height,GraphicsUnit.Pixel,imageAtt); +// else +// g.DrawImage(this.BackgroundImage,destRect,0,0,this.BackgroundImage.Width,this.BackgroundImage.Height,GraphicsUnit.Pixel); +// break; +// } +// case eBackgroundImagePosition.Tile: +// { +// if(imageAtt!=null) +// { +// if(r.Width>this.BackgroundImage.Width || r.Height>this.BackgroundImage.Height) +// { +// int x=r.X,y=r.Y; +// while(yr.Right) +// destRect.Width=destRect.Width-(destRect.Right-r.Right); +// if(destRect.Bottom>r.Bottom) +// destRect.Height=destRect.Height-(destRect.Bottom-r.Bottom); +// g.DrawImage(this.BackgroundImage,destRect,0,0,destRect.Width,destRect.Height,GraphicsUnit.Pixel,imageAtt); +// x+=this.BackgroundImage.Width; +// } +// x=r.X; +// y+=this.BackgroundImage.Height; +// } +// } +// else +// { +// g.DrawImage(this.BackgroundImage,new Rectangle(0,0,this.BackgroundImage.Width,this.BackgroundImage.Height),0,0,this.BackgroundImage.Width,this.BackgroundImage.Height,GraphicsUnit.Pixel,imageAtt); +// } +// } +// else +// { +// TextureBrush brush=new TextureBrush(this.BackgroundImage); //,r); +// brush.WrapMode=System.Drawing.Drawing2D.WrapMode.Tile; +// g.FillRectangle(brush,r); +// brush.Dispose(); +// } +// break; +// } +// } + } + + /// + /// Gets or sets the target gradient background color. + /// + [Browsable(true),Description("Indicates the target gradient background color."),Category("Style")] + public Color BackColor2 + { + get {return m_BackColor2;} + set + { + m_BackColor2=value; + if(this.DesignMode) + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColor2() + { + return !m_BackColor2.IsEmpty; + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackColor2() + { + m_BackColor2=Color.Empty; + } + + /// + /// Gets or sets gradient fill angle. + /// + [Browsable(true),Description("Indicates gradient fill angle."),Category("Style"),DefaultValue(90)] + public int BackColorGradientAngle + { + get {return m_BackColorGradientAngle;} + set + { + if(value!=m_BackColorGradientAngle) + { + m_BackColorGradientAngle=value; + if(this.DesignMode) + this.Refresh(); + } + } + } + /// + /// Specifies the transparency of background image. + /// + [Browsable(true),DevCoBrowsable(true),Category("Appearance"),DefaultValue(255),Description("Specifies the transparency of background image.")] + public int BackgroundImageAlpha + { + get {return m_BackgroundImageAlpha;} + set + { + if(value<0) + value=0; + else if(value>255) + value=255; + if(m_BackgroundImageAlpha!=value) + { + m_BackgroundImageAlpha=value; + if(this.DesignMode) + this.Refresh(); + } + } + } + /// + /// Specifies background image position when container is larger than image. + /// + [Browsable(true),DevCoBrowsable(true),Category("Appearance"),DefaultValue(eBackgroundImagePosition.Stretch),Description("Specifies background image position when container is larger than image.")] + public eBackgroundImagePosition BackgroundImagePosition + { + get {return m_BackgroundImagePosition;} + set + { + if(m_BackgroundImagePosition!=value) + { + m_BackgroundImagePosition=value; + if(this.DesignMode) + this.Refresh(); + } + } + } + + /// + /// Gets or sets the border color.. + /// + [Browsable(true),Description("Indicates border color."),Category("Style")] + public Color BorderColor + { + get {return m_BorderColor;} + set + { + m_BorderColor=value; + if(this.DesignMode) + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBorderColor() + { + return m_BorderColor!=SystemColors.InfoText; + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBorderColor() + { + m_BorderColor=SystemColors.InfoText; + } + + /// + /// Specifies balloon style. + /// + [Browsable(true),DevCoBrowsable(true),Category("Style"),DefaultValue(eBallonStyle.Balloon),Description("Specifies balloon style.")] + public eBallonStyle Style + { + get {return m_Style;} + set + { + m_Style=value; + if(m_Style==eBallonStyle.Alert) + { + this.BackColor=Color.FromArgb(207,221,244); + this.BackColor2=Color.White; + this.ForeColor=Color.FromArgb(102,114,196); + m_TextAlignment=StringAlignment.Center; + } + else if (m_Style == eBallonStyle.Office2007Alert) + { + Office2007ColorTable ct = GetOffice2007ColorTable(); + ColorScheme cs = ct.LegacyColors; + if (ct.SuperTooltip.BackgroundColors.IsEmpty) + { + this.BackColor = cs.PanelBackground; + this.BackColor2 = cs.PanelBackground2; + this.ForeColor = cs.PanelText; + } + else + { + this.BackColor = ct.SuperTooltip.BackgroundColors.Start; + this.BackColor2 = ct.SuperTooltip.BackgroundColors.End; + this.ForeColor = ct.SuperTooltip.TextColor; + } + m_BorderColor = cs.PanelBorder; + m_TextAlignment = StringAlignment.Near; + } + else + { + m_TextAlignment = StringAlignment.Near; + m_BorderColor = SystemColors.InfoText; + } + if(m_ShowCloseButton) + this.CreateCloseButton(); + this.RecalcLayout(); + if(this.DesignMode) + this.Refresh(); + } + } + + private Office2007ColorTable GetOffice2007ColorTable() + { + Office2007Renderer r = GlobalManager.Renderer as Office2007Renderer; + if (r != null) + return r.ColorTable; + return new Office2007ColorTable(); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + if(m_CloseButton!=null) + m_CloseButton.OnMouseDown(e); + if(this.Focused) + this.Focus(); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + if(m_CloseButton!=null) + m_CloseButton.OnMouseMove(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + if(m_CloseButton!=null) + m_CloseButton.OnMouseUp(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + if(m_CloseButton!=null) + m_CloseButton.OnMouseLeave(e); + } + + /// + /// Gets or sets whether the Close button is displayed. + /// + [Browsable(true),Description("Indicates whether the Close button is displayed."),Category("Behavior"),DefaultValue(true)] + public bool ShowCloseButton + { + get {return m_ShowCloseButton;} + set + { + if(value!=m_ShowCloseButton) + { + m_ShowCloseButton=value; + OnShowCloseButtonChanged(); + if(this.DesignMode) + this.Refresh(); + } + } + } + + private void OnShowCloseButtonChanged() + { + if(m_ShowCloseButton) + { + CreateCloseButton(); + RecalcLayout(); + } + else + { + m_CloseButton=null; + } + } + + private void CreateCloseButton() + { + if (m_CloseButtonNormal != null) + { + m_CloseButton = new ImageButton(this, new Rectangle(0, 0, Dpi.Width(m_CloseButtonNormal.Width), Dpi.Height(m_CloseButtonNormal.Height))); + if (m_CloseButton.Normal != null) + { + m_CloseButton.Normal.Dispose(); + m_CloseButton.Normal = null; + } + m_CloseButton.Normal = m_CloseButtonNormal; + if (m_CloseButton.Hover != null) + { + m_CloseButton.Hover.Dispose(); + m_CloseButton.Hover = null; + } + m_CloseButton.Hover = m_CloseButtonHot; + if (m_CloseButton.Pressed != null) + { + m_CloseButton.Pressed.Dispose(); + m_CloseButton.Pressed = null; + } + m_CloseButton.Pressed = m_CloseButtonPressed; + } + else // Default Image Size is 18x18 + { + if (m_Style == eBallonStyle.Balloon) + { + m_CloseButton = new ImageButton(this, new Rectangle(0, 0, Dpi.Width18, Dpi.Height18)); + m_CloseButton.Normal = BarFunctions.LoadBitmap("BalloonImages.BalloonNormal.png"); + m_CloseButton.Hover = BarFunctions.LoadBitmap("BalloonImages.BalloonHot.png"); + m_CloseButton.Pressed = BarFunctions.LoadBitmap("BalloonImages.BalloonPress.png"); + } + else + { + m_CloseButton = new ImageButton(this, new Rectangle(0, 0, Dpi.Width13, Dpi.Height13)); + m_CloseButton.Normal = BarFunctions.LoadBitmap("BalloonImages.AlertNormal.png"); + m_CloseButton.Hover = BarFunctions.LoadBitmap("BalloonImages.AlertHot.png"); + m_CloseButton.Pressed = BarFunctions.LoadBitmap("BalloonImages.AlertPress.png"); + } + } + m_CloseButton.Click+=new EventHandler(this.CloseButtonClickInternal); + } + + private void CloseButtonClickInternal(object sender, EventArgs e) + { + if(CloseButtonClick!=null) + CloseButtonClick(this,new EventArgs()); + if(m_AutoClose) + { + this.Hide(); + this.Close(); + } + } + + /// + /// Gets or sets the animation type used to display Alert type balloon. + /// + [Browsable(true),Description("Gets or sets the animation type used to display Alert type balloon."),Category("Behavior"),DefaultValue(eAlertAnimation.BottomToTop)] + public eAlertAnimation AlertAnimation + { + get {return m_AlertAnimation;} + set {m_AlertAnimation=value;} + } + + /// + /// Gets or sets the total time in milliseconds alert animation takes. + /// Default value is 200. + /// + [Browsable(true),Description("Gets or sets the total time in milliseconds alert animation takes."),Category("Behavior"),DefaultValue(200)] + public int AlertAnimationDuration + { + get {return m_AlertAnimationDuration;} + set {m_AlertAnimationDuration=value;} + } + + /// + /// Gets or sets whether balloon will close automatically when user click the close button. + /// + [Browsable(true),Description("Indicates whether balloon will close automatically when user click the close button."),Category("Behavior"),DefaultValue(true)] + public bool AutoClose + { + get {return m_AutoClose;} + set {m_AutoClose=value;} + } + + /// + /// Gets or sets time period in seconds after balloon closes automatically. + /// + [Browsable(true),Description("Indicates time period in seconds after balloon closes automatically."),Category("Behavior"),DefaultValue(0)] + public int AutoCloseTimeOut + { + get {return m_AutoCloseTimeOut;} + set + { + m_AutoCloseTimeOut=value; + OnAutoCloseTimeOutChanged(); + } + } + + protected void OnAutoCloseTimeOutChanged() + { + if(m_AutoCloseTimeOut>0 && !this.DesignMode) + { + if(m_Timer==null) + m_Timer=new System.Windows.Forms.Timer(components); + m_Timer.Enabled=false; + m_Timer.Interval=m_AutoCloseTimeOut*1000; + m_Timer.Tick+=new EventHandler(this.AutoCloseTimeOutEllapsed); + if(this.Visible) + { + m_Timer.Enabled=true; + m_Timer.Start(); + } + } + else + { + DestroyAutoCloseTimer(); + } + } + + protected virtual void AutoCloseTimeOutEllapsed(object sender, EventArgs e) + { + if(this.IsDisposed) + return; + DestroyAutoCloseTimer(); + this.Hide(); + this.Close(); + } + + private void DestroyAutoCloseTimer() + { + if(m_Timer!=null) + { + m_Timer.Enabled=false; + m_Timer.Tick-=new EventHandler(this.AutoCloseTimeOutEllapsed); + components.Remove(m_Timer); + m_Timer.Dispose(); + m_Timer=null; + } + } + + protected override void OnVisibleChanged(EventArgs e) + { + base.OnVisibleChanged(e); + if(this.Visible) + { + if(m_Timer!=null && !m_Timer.Enabled) + { + m_Timer.Enabled=true; + m_Timer.Start(); + } + } + else + { + if(m_Timer!=null && m_Timer.Enabled) + { + m_Timer.Stop(); + m_Timer.Enabled=false; + } + } + } + + /// + /// Gets or sets the custom image for Close Button. + /// + [Browsable(true),Description("Indicates custom image for Close Button."),Category("Appearance")] + public Image CloseButtonNormal + { + get {return m_CloseButtonNormal;} + set + { + if(m_CloseButtonNormal!=value) + { + m_CloseButtonNormal=value; + OnShowCloseButtonChanged(); + if(this.DesignMode) + this.Refresh(); + } + } + } + + /// + /// Gets or sets the custom image for Close Button when mouse is over the button. + /// + [Browsable(true),Description("Indicates custom image for Close Button when mouse is over the button."),Category("Appearance"),DefaultValue(null)] + public Image CloseButtonHot + { + get {return m_CloseButtonHot;} + set + { + if(m_CloseButtonHot!=value) + { + m_CloseButtonHot=value; + OnShowCloseButtonChanged(); + if(this.DesignMode) + this.Refresh(); + } + } + } + + /// + /// Gets or sets the custom image for Close Button when button is pressed. + /// + [Browsable(true),Description("Indicates custom image for Close Button when button is pressed."),Category("Appearance"),DefaultValue(null)] + public Image CloseButtonPressed + { + get {return m_CloseButtonPressed;} + set + { + if(m_CloseButtonPressed!=value) + { + m_CloseButtonPressed=value; + OnShowCloseButtonChanged(); + if(this.DesignMode) + this.Refresh(); + } + } + } + + /// + /// Gets or sets the Caption image. + /// + [Browsable(true),Description("Indicates Caption image."),Category("Appearance"),DefaultValue(null)] + public Image CaptionImage + { + get {return m_CaptionImage;} + set + { + if(m_CaptionImage!=value) + { + m_CaptionImage=value; + this.RecalcLayout(); + if(this.DesignMode) + this.Refresh(); + } + } + } + + /// + /// Gets or sets the Caption icon. Icon is used to provide support for alpha-blended images in caption. + /// + [Browsable(true),Description("Indicates Caption icon. Icon is used to provide support for alpha-blended images in caption."),Category("Appearance"),DefaultValue(null)] + public Icon CaptionIcon + { + get {return m_CaptionIcon;} + set + { + if(m_CaptionIcon!=value) + { + m_CaptionIcon=value; + this.RecalcLayout(); + if(this.DesignMode) + this.Refresh(); + } + } + } + + private CompositeImage ImageInternal + { + get + { + if(m_CaptionIcon!=null) + return new CompositeImage(m_CaptionIcon,false); + else if(m_CaptionImage!=null) + return new CompositeImage(m_CaptionImage,false); + return null; + } + } + + /// + /// Gets or sets the Caption font. + /// + [Browsable(true),Description("Indicates Caption font."),Category("Appearance")] + public Font CaptionFont + { + get {return m_CaptionFont;} + set + { + if(m_CaptionFont!=value) + { + m_CaptionFont=value; + this.RecalcLayout(); + if(this.DesignMode) + this.Refresh(); + } + } + } + + private TextMarkup.BodyElement _CaptionTextMarkup = null; + /// + /// Gets or sets text displayed in caption. + /// + [Browsable(true),Description("Indicates text displayed in caption."),Category("Appearance"),DefaultValue(""), Localizable(true)] + public string CaptionText + { + get {return m_CaptionText;} + set + { + if(m_CaptionText!=value) + { + m_CaptionText=value; + + if (_CaptionTextMarkup != null) + { + _CaptionTextMarkup.MouseLeave(this); + _CaptionTextMarkup.HyperLinkClick -= TextMarkupLinkClicked; + _CaptionTextMarkup = null; + } + + if (TextMarkup.MarkupParser.IsMarkup(ref m_CaptionText)) + _CaptionTextMarkup = TextMarkup.MarkupParser.Parse(m_CaptionText); + + if (_CaptionTextMarkup != null) + { + _CaptionTextMarkup.HyperLinkClick += TextMarkupLinkClicked; + } + + this.RecalcLayout(); + if(this.DesignMode) + this.Refresh(); + } + } + } + + /// + /// Gets or sets color of caption text. + /// + [Browsable(true),Description("Indicates color of caption text"),Category("Appearance")] + public Color CaptionColor + { + get {return m_CaptionColor;} + set + { + if(m_CaptionColor!=value) + { + m_CaptionColor=value; + if(this.DesignMode) + this.Refresh(); + } + } + } + + /// + /// Gets or set position of the balloon tip. + /// + [Browsable(true),Description("Indicates position of the balloon tip."),Category("Appearance"),DefaultValue(eTipPosition.Top)] + public eTipPosition TipPosition + { + get {return m_TipPosition;} + set + { + if(m_TipPosition!=value) + { + m_TipPosition=value; + this.RecalcLayout(); + if(TipPositionChanged!=null) + TipPositionChanged(this,new EventArgs()); + if(this.DesignMode) + this.Refresh(); + } + } + } + + private void InternalTipPositionChanged(eTipPosition newValue) + { + if(this.Controls.Count==0 || this.Style!=eBallonStyle.Balloon) + return; + if(newValue==eTipPosition.Top && m_TipPosition==eTipPosition.Bottom) + { + foreach(Control control in this.Controls) + { + control.Top+=m_TipLength; + } + } + else if(newValue==eTipPosition.Bottom && m_TipPosition==eTipPosition.Top) + { + foreach(Control control in this.Controls) + { + control.Top-=m_TipLength; + } + } + } + + /// + /// Gets or sets tip distance from the edge of the balloon. + /// + [Browsable(true),Description("Indicates tip distance from the edge of the balloon."),Category("Appearance"),DefaultValue(32)] + public int TipOffset + { + get {return m_TipOffset;} + set + { + if(m_TipOffset!=value) + { + if(valuethis.Width-m_CornerSize-m_TipLength) + value=this.Width-m_CornerSize-m_TipLength; + else if((m_TipPosition==eTipPosition.Left || m_TipPosition==eTipPosition.Right) && value>this.Height-m_CornerSize-m_TipLength) + value=this.Height-m_CornerSize-m_TipLength; + + m_TipOffset=value; + this.RecalcLayout(); + if(this.DesignMode) + this.Refresh(); + } + } + } + + /// + /// Returns length of the tip. + /// + [Browsable(false),Description("Returns tip length"),Category("Appearance")] + public int TipLength + { + get {return m_TipLength;} + } + + /// + /// Displays balloon using control to automatically calculate balloon location. Method is usually used display balloon that is showing information for the certain control. + /// + /// Control used for balloon positioning. + public void Show(Control referenceControl) + { + this.Show(referenceControl,true); + } + + /// + /// Displays balloon using control to automatically calculate balloon location. Method is usually used display balloon that is showing information for the certain control. + /// + /// Control used for balloon positioning. + /// Indicates whether balloon receives input focus. + public void Show(Control referenceControl, bool balloonFocus) + { + if(referenceControl==null) + { + this.Show(); + return; + } + Point scrLocCtrl=Point.Empty; + + if(referenceControl.Parent!=null) + scrLocCtrl=referenceControl.Parent.PointToScreen(referenceControl.Location); + else + scrLocCtrl=referenceControl.Location; + + this.Show(new Rectangle(scrLocCtrl,referenceControl.Size),balloonFocus); + } + + /// + /// Displays balloon using rectangle to automatically calculate balloon location. Method is usually used display balloon that is showing information for the certain screen region. + /// + /// Rectangle in screen coordinates used for balloon positioning. + /// Indicates whether balloon receives input focus. + public void Show(Rectangle referenceScreenRect, bool balloonFocus) + { + if(referenceScreenRect.IsEmpty) + { + this.Show(); + return; + } + + int tipPositionOffset=m_TipLength+m_CornerSize*3; + int tipOffset=m_TipLength/2+m_CornerSize*3; + Point balloonLocation=Point.Empty; + ScreenInformation screen=BarFunctions.ScreenFromPoint(referenceScreenRect.Location); + + if(referenceScreenRect.X+referenceScreenRect.Width/2+this.Width>screen.WorkingArea.Right) + { + balloonLocation.X=referenceScreenRect.X+referenceScreenRect.Width/2-this.Width+tipPositionOffset; + tipOffset=this.Width-tipPositionOffset; + } + else + balloonLocation.X=referenceScreenRect.X+referenceScreenRect.Width/2-tipPositionOffset; + + if(referenceScreenRect.Y+referenceScreenRect.Height+this.Height>screen.WorkingArea.Bottom) + { + balloonLocation.Y=referenceScreenRect.Y-this.Height; + InternalTipPositionChanged(eTipPosition.Bottom); + this.TipPosition=eTipPosition.Bottom; + } + else + { + balloonLocation.Y=referenceScreenRect.Y+referenceScreenRect.Height; + InternalTipPositionChanged(eTipPosition.Top); + this.TipPosition=eTipPosition.Top; + } + + this.TipOffset=tipOffset; + this.Location=balloonLocation; + this.Show(balloonFocus); + } + + /// + /// Displays balloon using item to automatically calculate balloon location. Method is usually used display balloon that is showing information for the certain item. + /// + /// Item used for balloon positioning. + /// Indicates whether balloon receives input focus. + public void Show(BaseItem item, bool balloonFocus) + { + if(item==null || item.ContainerControl==null) + { + this.Show(); + return; + } + Point loc=((Control)item.ContainerControl).PointToScreen(item.DisplayRectangle.Location); + this.Show(new Rectangle(loc,item.DisplayRectangle.Size),balloonFocus); + } + + /// + /// Display balloon. + /// + /// Indicates whether balloon receives input focus. + public void Show(bool balloonFocus) + { + Rectangle rEnd=new Rectangle(this.Location,this.Size); + Rectangle rStart=GetAnimationRectangle(); + + if(!balloonFocus) + { + if(this.TopMost) + { + this.TopMost=false; + NativeFunctions.SetWindowPos(this.Handle,new IntPtr(NativeFunctions.HWND_TOP),0,0,0,0,NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE | NativeFunctions.SWP_NOMOVE | NativeFunctions.SWP_NOSIZE); + this.TopMost=true; + } + else + NativeFunctions.SetWindowPos(this.Handle,new IntPtr(NativeFunctions.HWND_TOP),0,0,0,0,NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE | NativeFunctions.SWP_NOMOVE | NativeFunctions.SWP_NOSIZE); + } + + if(ShouldAnimate()) + { + try + { + m_AnimationInProgress=true; + BarFunctions.AnimateControl(this,true,m_AlertAnimationDuration,rStart,rEnd); + } + finally + { + m_AnimationInProgress=false; + } + } + else + base.Show(); + } + + /// + /// Displays balloon. + /// + public new void Show() + { + this.Show(true); + } + /// + /// Called when balloon is hidden. + /// + protected virtual void HideBalloon() + { + DestroyAutoCloseTimer(); + if (ShouldAnimate()) + { + Rectangle rStart = new Rectangle(this.Location, this.Size); + Rectangle rEnd = GetAnimationRectangle(); + try + { + m_AnimationInProgress = true; + BarFunctions.AnimateControl(this, false, m_AlertAnimationDuration, rStart, rEnd); + } + finally + { + m_AnimationInProgress = false; + } + } + else + base.Hide(); + } + + /// + /// Hides balloon. + /// + public new void Hide() + { + HideBalloon(); + } + + private bool ShouldAnimate() + { + if (m_Style != eBallonStyle.Balloon && m_AlertAnimation != eAlertAnimation.None && !this.DesignMode) + return true; + return false; + } + + private Rectangle GetAnimationRectangle() + { + Rectangle r=new Rectangle(this.Location,this.Size); + if(m_AlertAnimation==eAlertAnimation.BottomToTop)// && bShowing || m_AlertAnimation==eAlertAnimation.TopToBottom && !bShowing) + { + r.Y=r.Bottom-1; + r.Height=1; + } + else if(m_AlertAnimation==eAlertAnimation.TopToBottom) + { + r.Height=1; + } + else if(m_AlertAnimation==eAlertAnimation.LeftToRight) + { + r.Width=2; + } + else if(m_AlertAnimation==eAlertAnimation.RightToLeft) + { + r.X=r.Right-1; + r.Width=1; + } + return r; + } + + /// + /// Gets/Sets whether Balloon is visible. + /// + [DevCoBrowsable(true)] + public new bool Visible + { + get { return base.Visible;} + set + { + if(value) + this.Show(); + else + this.Hide(); + } + } + + const int WM_MOUSEACTIVATE = 0x21; + const int MA_NOACTIVATE = 3; + protected override void WndProc(ref Message m) + { + if(m.Msg==WM_MOUSEACTIVATE) + { + m.Result=new System.IntPtr(MA_NOACTIVATE); + return; + } + base.WndProc(ref m); + } + + private class ImageButton + { + private Rectangle m_Bounds=Rectangle.Empty; + private Control m_Parent=null; + private bool m_MouseOver=false; + private bool m_MouseDown=false; + public Image Normal=null; + public Image Hover=null; + public Image Pressed=null; + + public event EventHandler Click; + + public ImageButton(Control parent, Rectangle bounds) + { + m_Parent=parent; + m_Bounds=bounds; + } + + public virtual void Paint(Graphics g) + { + Rectangle bounds = m_Bounds; + if(m_MouseDown) + { + if(Pressed!=null) + g.DrawImage(Pressed,bounds); + } + else if(m_MouseOver) + { + if(Hover!=null) + g.DrawImage(Hover,bounds); + } + else + { + if(Normal!=null) + g.DrawImage(Normal,bounds); + } + } + + public virtual void OnMouseMove(MouseEventArgs e) + { + if(m_MouseDown) + return; + + if(m_Bounds.Contains(e.X,e.Y)) + { + if(!m_MouseOver) + { + m_MouseOver=true; + if(m_Parent!=null) + m_Parent.Invalidate(m_Bounds); + } + } + else if(m_MouseOver) + { + m_MouseOver=false; + if(m_Parent!=null) + m_Parent.Invalidate(m_Bounds); + } + } + public virtual void OnMouseDown(MouseEventArgs e) + { + if(m_Bounds.Contains(e.X,e.Y) && !m_MouseDown) + { + m_MouseDown=true; + if(m_Parent!=null) + m_Parent.Invalidate(m_Bounds); + } + } + + public virtual void OnMouseUp(MouseEventArgs e) + { + if(m_Bounds.Contains(e.X,e.Y) && m_MouseDown) + { + m_MouseDown=false; + if(m_Parent!=null) + m_Parent.Invalidate(m_Bounds); + if(Click!=null) + Click(this,new EventArgs()); + } + else if(m_MouseOver || m_MouseDown) + { + m_MouseDown=false; + m_MouseOver=false; + if(m_Parent!=null) + m_Parent.Invalidate(m_Bounds); + } + } + + public virtual void OnMouseLeave(EventArgs e) + { + if(m_MouseOver && !m_MouseDown) + { + m_MouseOver=false; + if(m_Parent!=null) + m_Parent.Invalidate(m_Bounds); + } + } + + public bool MouseDown + { + get {return m_MouseDown;} + } + + public bool MouseOver + { + get {return m_MouseOver;} + } + + public Rectangle Bounds + { + get {return m_Bounds;} + set {m_Bounds=value;} + } + + public Point Location + { + get {return m_Bounds.Location;} + set {m_Bounds.Location=value;} + } + + public System.Drawing.Size Size + { + get {return m_Bounds.Size;} + set {m_Bounds.Size=value;} + } + } + } + + public class CustomPaintEventArgs:EventArgs + { + private System.Drawing.Graphics m_Graphics=null; + private Rectangle m_PaintRectangle=Rectangle.Empty; + public CustomPaintEventArgs(Graphics g, Rectangle r) + { + m_Graphics=g; + m_PaintRectangle=r; + } + + public System.Drawing.Graphics Graphics + { + get {return m_Graphics;} + } + + public Rectangle PaintRectangle + { + get {return m_PaintRectangle;} + } + } +} diff --git a/PROMS/DotNetBar Source Code/Balloon.resx b/PROMS/DotNetBar Source Code/Balloon.resx new file mode 100644 index 00000000..ae7000b3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Balloon.resx @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Balloon + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/BalloonImages/AlertHot.png b/PROMS/DotNetBar Source Code/BalloonImages/AlertHot.png new file mode 100644 index 00000000..47868a00 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BalloonImages/AlertHot.png differ diff --git a/PROMS/DotNetBar Source Code/BalloonImages/AlertNormal.png b/PROMS/DotNetBar Source Code/BalloonImages/AlertNormal.png new file mode 100644 index 00000000..07f19054 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BalloonImages/AlertNormal.png differ diff --git a/PROMS/DotNetBar Source Code/BalloonImages/AlertPress.png b/PROMS/DotNetBar Source Code/BalloonImages/AlertPress.png new file mode 100644 index 00000000..50984e27 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BalloonImages/AlertPress.png differ diff --git a/PROMS/DotNetBar Source Code/BalloonImages/BalloonHot.png b/PROMS/DotNetBar Source Code/BalloonImages/BalloonHot.png new file mode 100644 index 00000000..f7f7ef6e Binary files /dev/null and b/PROMS/DotNetBar Source Code/BalloonImages/BalloonHot.png differ diff --git a/PROMS/DotNetBar Source Code/BalloonImages/BalloonNormal.png b/PROMS/DotNetBar Source Code/BalloonImages/BalloonNormal.png new file mode 100644 index 00000000..ef7ff150 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BalloonImages/BalloonNormal.png differ diff --git a/PROMS/DotNetBar Source Code/BalloonImages/BalloonPress.png b/PROMS/DotNetBar Source Code/BalloonImages/BalloonPress.png new file mode 100644 index 00000000..298a5c23 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BalloonImages/BalloonPress.png differ diff --git a/PROMS/DotNetBar Source Code/BalloonTip.bmp b/PROMS/DotNetBar Source Code/BalloonTip.bmp new file mode 100644 index 00000000..b7fd34ba Binary files /dev/null and b/PROMS/DotNetBar Source Code/BalloonTip.bmp differ diff --git a/PROMS/DotNetBar Source Code/BalloonTip.cs b/PROMS/DotNetBar Source Code/BalloonTip.cs new file mode 100644 index 00000000..8d810096 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BalloonTip.cs @@ -0,0 +1,670 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Collections; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents a balloon style pop-up window that displays a brief description of a control's purpose when the mouse hovers over the control or when controls receives input focus. + /// + [ToolboxItem(true),ProvideProperty("BalloonCaption",typeof(Control)), + ProvideProperty("BalloonText",typeof(Control)), + System.Runtime.InteropServices.ComVisible(false)] + public class BalloonTip:Component, IExtenderProvider + { + /// + /// Occurs before balloon is displayed. + /// + [Description("Occurs before balloon is displayed.")] + public event EventHandler BalloonDisplaying; + /// + /// Occurs before balloon is closed and allows to cancel the action. + /// + [Description("Occurs before balloon is closed and allows to cancel the action.")] + public event CancelEventHandler BalloonClosing; + + private bool m_BalloonFocus=false; + private bool m_Enabled=true; + private bool m_ShowAlways=false; + private eBallonStyle m_Style=eBallonStyle.Balloon; + private int m_InitialDelay=500; + private bool m_AutoClose=true; + private int m_AutoCloseTimeOut=5; + private eAlertAnimation m_AlertAnimation=eAlertAnimation.BottomToTop; + private int m_AlertAnimationDuration=200; + private bool m_ShowBalloonOnFocus=false; + private bool m_ShowCloseButton=true; + + private Balloon m_BalloonControl=null; + + private System.Drawing.Image m_CaptionImage=null; + private System.Drawing.Icon m_CaptionIcon=null; + + private Hashtable m_BalloonsInfo=new Hashtable(); + + private Control m_MouseOverControl=null; + private Control m_FocusedControl=null; + + private Timer m_DelayTimer=null; + + private Control m_BalloonTriggerControl=null; + private int m_DefaultBalloonWidth=256; + private bool m_AntiAlias = true; + /// + /// Initializes a new instance of the BalloonTip class. + /// + public BalloonTip() + { + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + RemoveAll(); + m_MouseOverControl=null; + m_FocusedControl=null; + m_BalloonTriggerControl=null; + if (BarUtilities.DisposeItemImages && !this.DesignMode) + { + BarUtilities.DisposeImage(ref m_CaptionImage); + BarUtilities.DisposeImage(ref m_CaptionIcon); + } + DestroyDelayTimer(); + base.Dispose(disposing); + } + + bool IExtenderProvider.CanExtend(object target) + { + if (target is Control) + return true; + return false; + } + + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is false. + /// + [DefaultValue(true), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public bool AntiAlias + { + get { return m_AntiAlias; } + set + { + m_AntiAlias = value; + } + } + + /// + /// Retrieves the Balloon Caption text associated with the specified control. + /// + [DefaultValue(""), Localizable(true)] + public string GetBalloonCaption(Control control) + { + if(m_BalloonsInfo.Contains(control)) + { + BalloonTipInfo info=m_BalloonsInfo[control] as BalloonTipInfo; + if(info!=null) + return info.Caption; + } + return ""; + } + + /// + /// Associates Balloon Caption text with the specified control. + /// + /// The Control to associate the Balloon Caption text with. + /// The Balloon Caption text to display on the Balloon. + [Localizable(true)] + public void SetBalloonCaption(Control control, string caption) + { + if(caption==null) + caption=""; + if(m_BalloonsInfo.Contains(control)) + { + BalloonTipInfo info=m_BalloonsInfo[control] as BalloonTipInfo; + if(info!=null) + { + info.Caption=caption; + if(info.Caption=="" && info.Text=="") + { + this.Remove(control); + } + } + } + else if(caption!="") + { + BalloonTipInfo info=new BalloonTipInfo(); + info.Caption=caption; + this.AddControl(control,info); + } + } + + /// + /// Retrieves the Balloon text associated with the specified control. + /// + [DefaultValue(""), Localizable(true)] + public string GetBalloonText(Control control) + { + if(m_BalloonsInfo.Contains(control)) + { + BalloonTipInfo info=m_BalloonsInfo[control] as BalloonTipInfo; + if(info!=null) + return info.Text; + } + return ""; + } + + /// + /// Associates Balloon text with the specified control. + /// + /// The Control to associate the Balloon text with. + /// The Balloon text to display on the Balloon. + [Localizable(true)] + public void SetBalloonText(Control control, string text) + { + if(text==null) + text=""; + if(m_BalloonsInfo.Contains(control)) + { + BalloonTipInfo info=m_BalloonsInfo[control] as BalloonTipInfo; + if(info!=null) + { + info.Text=text; + if(info.Caption=="" && info.Text=="") + { + this.Remove(control); + } + } + } + else if(text!="") + { + BalloonTipInfo info=new BalloonTipInfo(); + info.Text=text; + this.AddControl(control,info); + } + } + + /// + /// Gets or sets a value indicating whether the BalloonTip is currently active. + /// true if the BalloonTip is currently active; otherwise, false. The default is true. + /// + [DefaultValue(true),Category("Misc"),Description("Gets or sets a value indicating whether the BalloonTip is currently active.")] + public bool Enabled + { + get{return m_Enabled;} + set + { + m_Enabled=value; + } + } + + /// + /// Removes all Balloon texts currently associated with the BalloonTip control. + /// + public void RemoveAll() + { + Control[] ctrls=new Control[m_BalloonsInfo.Keys.Count]; + + m_BalloonsInfo.Keys.CopyTo(ctrls,0); + foreach(Control c in ctrls) + { + this.Remove(c); + } + m_BalloonsInfo.Clear(); + } + + /// + /// Removes specific Balloon texts currently associated with the BalloonTip control. + /// + /// Control that has Balloon texts associated. + public void Remove(Control control) + { + if(m_BalloonsInfo.Contains(control)) + { + // Remove event handlers + try + { + control.MouseEnter-=new EventHandler(this.ControlMouseEnter); + control.MouseLeave-=new EventHandler(this.ControlMouseLeave); + control.Enter-=new EventHandler(this.ControlGotFocus); + control.Leave-=new EventHandler(this.ControlLeave); + } + catch{} + m_BalloonsInfo.Remove(control); + } + } + + private void AddControl(Control control, BalloonTipInfo info) + { + if(m_BalloonsInfo.Contains(control)) + return; + m_BalloonsInfo.Add(control,info); + // Hook-up events + control.MouseEnter+=new EventHandler(this.ControlMouseEnter); + control.MouseLeave+=new EventHandler(this.ControlMouseLeave); + control.Enter+=new EventHandler(this.ControlGotFocus); + control.Leave+=new EventHandler(this.ControlLeave); + } + + /// + /// Shows Balloon for specific control. Control must have Balloon already assigned to it. + /// + /// Control that has Balloon already assigned. + public virtual void ShowBalloon(Control control) + { + if(m_BalloonsInfo.Contains(control)) + { + BalloonTipInfo info=m_BalloonsInfo[control] as BalloonTipInfo; + if(info!=null) + { + CloseBalloon(); + + // Closing of balloon was denied exit. + if(m_BalloonControl!=null) + { + return; + } + + m_BalloonControl=CreateBalloonControl(info); + m_BalloonControl.Location=new System.Drawing.Point(0,0); + m_BalloonTriggerControl=control; + + if(BalloonDisplaying!=null) + BalloonDisplaying(this,new EventArgs()); + + // If Balloon Control is still around + if(m_BalloonControl!=null) + { + Form parentForm=control.FindForm(); + if(parentForm!=null) + m_BalloonControl.Owner=parentForm; + if(!m_BalloonControl.Location.IsEmpty) + m_BalloonControl.Show(m_BalloonFocus); + else + m_BalloonControl.Show(control,m_BalloonFocus); + } + } + } + } + + /// + /// Returns reference to the control that triggered balloon. + /// + public Control BalloonTriggerControl + { + get + { + return m_BalloonTriggerControl; + } + } + + private int _MinimumBalloonWidth = 180; + /// + /// Gets or sets the minimum balloon width when auto sizing balloon. Default value is 180. + /// + [DefaultValue(180), Category("Appearance"), Description("Indicates minimum balloon width when auto sizing balloon.")] + public int MinimumBalloonWidth + { + get { return _MinimumBalloonWidth; } + set { _MinimumBalloonWidth = value; } + } + + private Balloon CreateBalloonControl(BalloonTipInfo info) + { + Balloon b=new Balloon(); + b.CaptionText=info.Caption; + b.Text=info.Text; + b.AutoClose=m_AutoClose; + b.AutoCloseTimeOut=m_AutoCloseTimeOut; + b.CaptionImage=this.CaptionImage; + b.CaptionIcon=this.CaptionIcon; + b.AlertAnimation=m_AlertAnimation; + b.AlertAnimationDuration=m_AlertAnimationDuration; + b.ShowCloseButton=m_ShowCloseButton; + b.Style=m_Style; + b.MinimumBalloonWidth = _MinimumBalloonWidth; + if(info.Caption=="" || info.Caption==null) + { + b.Width=this.DefaultBalloonWidth; + } + else + b.AutoResize(); + + return b; + } + + /// + /// Closes Balloon control if visible. + /// + public virtual void CloseBalloon() + { + m_BalloonTriggerControl=null; + + if(m_BalloonControl==null) + return; + + CancelEventArgs e=new CancelEventArgs(false); + if(BalloonClosing!=null) + BalloonClosing(this,e); + if(e.Cancel) + return; + + if(m_BalloonControl.Visible) + { + m_BalloonControl.Hide(); + } + + m_BalloonControl.Close(); + m_BalloonControl.Dispose(); + m_BalloonControl=null; + } + + /// + /// Gets or sets a value indicating whether Balloon receives input focus when displayed. + /// Default value is false. + /// + [DefaultValue(false),Category("Misc"),Description("Gets or sets a value indicating whether Balloon receives input focus when displayed.")] + public bool BalloonFocus + { + get {return m_BalloonFocus;} + set {m_BalloonFocus=value;} + } + + /// + /// Gets or sets the time (in milliseconds) that passes before the BalloonTip appears. + /// + [DefaultValue(500),Category("Misc"),Description("Indicates the time (in milliseconds) that passes before the BalloonTip appears.")] + public int InitialDelay + { + get{return m_InitialDelay;} + set{m_InitialDelay=value;} + } + + /// + /// Gets or sets a value indicating whether a Balloon window is displayed even when its parent form is not active. Default value is false. + /// + [DefaultValue(false),Category("Misc"),Description("Indicates whether a Balloon window is displayed even when its parent form is not active.")] + public bool ShowAlways + { + get{return m_ShowAlways;} + set{m_ShowAlways=value;} + } + + /// + /// Gets or sets the internal Balloon control that is used to display Balloon. + /// This property will have valid value only during time Balloon is actually + /// displayed on the screen. Value will also be valid during BalloonDisplaying event. + /// You can use this property to further customize Balloon control before it is + /// displayed to the user. You can also set it to your own instance of the Balloon + /// control (or the control that is inheriting it) for ultimate customization options. + /// Note that new instance of Balloon control is created each time Balloon needs to be displayed. + /// Once Balloon is closed control is disposed. + /// + [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Balloon BalloonControl + { + get {return m_BalloonControl;} + set {m_BalloonControl=value;} + } + + /// + /// Specifies balloon style. + /// + [Browsable(true),DevCoBrowsable(true),Category("Style"),DefaultValue(eBallonStyle.Balloon),Description("Specifies balloon style.")] + public eBallonStyle Style + { + get {return m_Style;} + set + { + if(m_Style!=value) + { + m_Style=value; + } + } + } + + /// + /// Gets or sets the animation type used to display Alert type balloon. + /// + [Browsable(true),Description("Gets or sets the animation type used to display Alert type balloon."),Category("Behavior"),DefaultValue(eAlertAnimation.BottomToTop)] + public eAlertAnimation AlertAnimation + { + get {return m_AlertAnimation;} + set {m_AlertAnimation=value;} + } + + /// + /// Gets or sets the total time in milliseconds alert animation takes. + /// Default value is 200. + /// + [Browsable(true),Description("Gets or sets the total time in milliseconds alert animation takes."),Category("Behavior"),DefaultValue(200)] + public int AlertAnimationDuration + { + get {return m_AlertAnimationDuration;} + set {m_AlertAnimationDuration=value;} + } + + /// + /// Gets or sets whether balloon will close automatically when user click the close button. + /// + [Browsable(true),Description("Indicates whether balloon will close automatically when user click the close button."),Category("Behavior"),DefaultValue(true)] + public bool AutoClose + { + get {return m_AutoClose;} + set {m_AutoClose=value;} + } + + /// + /// Gets or sets time period in seconds after balloon closes automatically. + /// + [Browsable(true),Description("Indicates time period in seconds after balloon closes automatically."),Category("Behavior"),DefaultValue(5)] + public int AutoCloseTimeOut + { + get {return m_AutoCloseTimeOut;} + set + { + m_AutoCloseTimeOut=value; + } + } + + /// + /// Gets or sets whether Balloon is shown after control receives input focus. Default value is false. When set to true Balloon will not be displayed on mouse hover. + /// + [Browsable(true),Description("Indicates whether Balloon is shown after control receives input focus."),Category("Behavior"),DefaultValue(false)] + public bool ShowBalloonOnFocus + { + get {return m_ShowBalloonOnFocus;} + set + { + if(m_ShowBalloonOnFocus!=value) + { + m_ShowBalloonOnFocus=value; + } + } + } + + /// + /// Gets or sets whether the Balloon Close button is displayed. + /// + [Browsable(true),Description("Indicates whether the Balloon Close button is displayed."),Category("Behavior"),DefaultValue(true)] + public bool ShowCloseButton + { + get {return m_ShowCloseButton;} + set + { + if(value!=m_ShowCloseButton) + { + m_ShowCloseButton=value; + } + } + } + + /// + /// Gets or sets default balloon width. Usually the width of the balloon is calculated based on the width of the caption text. If caption text is not set then this value will be used as default width of the balloon. + /// + [Browsable(true),Description("Indicates default balloon width. Usually the width of the balloon is calculated based on the width of the caption text. If caption text is not set then this value will be used as default width of the balloon."),Category("Appearance"),DefaultValue(256)] + public int DefaultBalloonWidth + { + get {return m_DefaultBalloonWidth;} + set {m_DefaultBalloonWidth=value;} + } + + /// + /// Gets or sets the Balloon Caption image. + /// + [Browsable(true),Description("Indicates Balloon Caption image."),Category("Appearance"),DefaultValue(null)] + public System.Drawing.Image CaptionImage + { + get {return m_CaptionImage;} + set + { + if(m_CaptionImage!=value) + { + m_CaptionImage=value; + } + } + } + + /// + /// Gets or sets the Balloon Caption icon. Icon is used to provide support for alpha-blended images in caption. + /// + [Browsable(true),Description("Indicates Balloon Caption icon. Icon is used to provide support for alpha-blended images in caption."),Category("Appearance"),DefaultValue(null)] + public System.Drawing.Icon CaptionIcon + { + get {return m_CaptionIcon;} + set + { + if(m_CaptionIcon!=value) + { + m_CaptionIcon=value; + } + } + } + + private void DestroyDelayTimer() + { + if(m_DelayTimer!=null) + { + m_DelayTimer.Stop(); + m_DelayTimer.Tick-=new EventHandler(this.DelayTimerTick); + m_DelayTimer.Dispose(); + m_DelayTimer=null; + } + } + + private void DelayTimerTick(object sender, EventArgs e) + { + m_DelayTimer.Enabled=false; + DestroyDelayTimer(); + + if (m_Enabled) + { + if (m_ShowBalloonOnFocus && m_FocusedControl != null) + ShowBalloon(m_FocusedControl); + else if (!m_ShowBalloonOnFocus && m_MouseOverControl != null) + ShowBalloon(m_MouseOverControl); + } + } + + private void ShowBalloonDelayed(Control control) + { + if(control==null || !m_Enabled) + return; + + if(!m_ShowAlways) + { + Form parentForm=control.FindForm(); + if(parentForm.IsMdiChild) + { + if(parentForm.MdiParent!=null && parentForm.MdiParent.ActiveMdiChild!=parentForm) + return; + } + else + { + if(Form.ActiveForm!=parentForm) + return; + } + } + + if(m_InitialDelay==0) + { + ShowBalloon(control); + return; + } + + if(m_DelayTimer==null) + { + m_DelayTimer=new Timer(); + m_DelayTimer.Tick+=new EventHandler(this.DelayTimerTick); + m_DelayTimer.Interval=m_InitialDelay; + m_DelayTimer.Start(); + } + } + + private void OnMouseEnter() + { + if(!m_Enabled || m_MouseOverControl==null || m_ShowBalloonOnFocus || !m_BalloonsInfo.Contains(m_MouseOverControl)) + return; + + ShowBalloonDelayed(m_MouseOverControl); + } + + private void OnMouseLeave() + { + if(!m_ShowBalloonOnFocus) + { + DestroyDelayTimer(); + CloseBalloon(); + } + } + + private void OnControlGotFocus() + { + if(!m_Enabled || m_FocusedControl==null || !m_ShowBalloonOnFocus || !m_BalloonsInfo.Contains(m_FocusedControl)) + return; + + ShowBalloonDelayed(m_FocusedControl); + } + + private void OnControlLeave() + { + if(m_ShowBalloonOnFocus) + { + DestroyDelayTimer(); + CloseBalloon(); + } + } + + private void ControlMouseEnter(object sender, EventArgs e) + { + m_MouseOverControl=sender as Control; + OnMouseEnter(); + } + + private void ControlMouseLeave(object sender, EventArgs e) + { + m_MouseOverControl=null; + OnMouseLeave(); + } + + private void ControlGotFocus(object sender, EventArgs e) + { + m_FocusedControl=sender as Control; + OnControlGotFocus(); + } + + private void ControlLeave(object sender, EventArgs e) + { + m_FocusedControl=null; + OnControlLeave(); + } + + private class BalloonTipInfo + { + public string Caption; + public string Text; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Bar.bmp b/PROMS/DotNetBar Source Code/Bar.bmp new file mode 100644 index 00000000..1bfca562 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Bar.bmp differ diff --git a/PROMS/DotNetBar Source Code/Bar.cs b/PROMS/DotNetBar Source Code/Bar.cs new file mode 100644 index 00000000..c064f59c --- /dev/null +++ b/PROMS/DotNetBar Source Code/Bar.cs @@ -0,0 +1,14246 @@ +namespace DevComponents.DotNetBar +{ + using System; + using System.Windows.Forms; + using System.Drawing; + using System.ComponentModel; + using System.Collections; + using System.Resources; + using System.Drawing.Drawing2D; + using System.ComponentModel.Design; + using DevComponents.DotNetBar.Rendering; + using System.Runtime.InteropServices; + using System.Drawing.Text; + using System.Collections.Generic; + + /// + /// Represents bar control. + /// + [ToolboxBitmap(typeof(Bar), "Bar.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.BarDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.Runtime.InteropServices.ComVisible(false), DefaultEvent("ItemClick")] + public class Bar : Control, IDockInfo, IBarImageSize, IOwner, IOwnerMenuSupport, + IMessageHandlerClient, ISupportInitialize, IBarDesignerServices, + ICustomSerialization, IRenderingSupport, IAccessibilitySupport, IOwnerLocalize + { + #region Events Definitions + /// + /// Occurs after bar state has changed, like selected dock tab has changed, bar has closed, bar has been docked or undocked etc. + /// + [Description("Occurs after bar state has changed, like selected dock tab has changed, bar has closed, bar has been docked or undocked etc.")] + public event BarStateChangedEventHandler BarStateChanged; + /// + /// Raises BarStateChanged event. + /// + /// Provides event arguments. + protected virtual void OnBarStateChanged(BarStateChangedEventArgs e) + { + BarStateChangedEventHandler handler = BarStateChanged; + if (handler != null) + handler(this, e); + + DotNetBarManager manager = this.Owner as DotNetBarManager; + if (manager != null) + manager.InvokeOnBarStateChanged(e); + } + /// + /// Occurs when Item is clicked. + /// + [System.ComponentModel.Description("Occurs when Item is clicked."), Category("Item")] + public event EventHandler ItemClick; + /// + /// Occurs after Bar is docked. + /// + [System.ComponentModel.Description("Occurs after Bar is docked.")] + public event EventHandler BarDock; + + /// + /// Occurs after Bar is undocked. + /// + [System.ComponentModel.Description("Occurs after Bar is undocked.")] + public event EventHandler BarUndock; + + /// + /// Occurs after Bar definition is loaded. + /// + [System.ComponentModel.Description("Occurs after Bar definition is loaded.")] + public event EventHandler DefinitionLoaded; + + /// + /// Occurs when current Dock tab has changed. + /// + [System.ComponentModel.Description("Occurs when current Dock tab has changed.")] + public event DotNetBarManager.DockTabChangeEventHandler DockTabChange; + + /// + /// Occurs when bar visibility has changed as a result of user action. + /// + [System.ComponentModel.Description("Occurs when bar visibility has changed as a result of user action.")] + public event EventHandler UserVisibleChanged; + + /// + /// Occurs when bar auto hide state has changed. + /// + [System.ComponentModel.Description("Occurs when bar auto hide state has changed.")] + public event EventHandler AutoHideChanged; + + /// + /// Occurs when Bar is about to be closed as a result of user clicking the Close button on the bar. + /// + [System.ComponentModel.Description("Occurs when Bar is about to be closed as a result of user clicking the Close button on the bar.")] + public event DotNetBarManager.BarClosingEventHandler Closing; + + /// + /// Occurs when Bar in auto-hide state is about to be displayed. + /// + [System.ComponentModel.Description("Occurs when Bar in auto-hide state is about to be displayed.")] + public event DotNetBarManager.AutoHideDisplayEventHandler AutoHideDisplay; + + /// + /// Occurs when popup item is closing. Event is fired only when Bar is used independently of DotNetBarManager. + /// + [System.ComponentModel.Description("Occurs when popup item is closing."), Category("Item")] + public event EventHandler PopupClose; + + /// + /// Occurs when popup of type container is loading. Event is fired only when Bar is used independently of DotNetBarManager. + /// + [System.ComponentModel.Description("Occurs when popup of type container is loading."), Category("Item")] + public event EventHandler PopupContainerLoad; + + /// + /// Occurs when popup of type container is unloading. Event is fired only when Bar is used independently of DotNetBarManager. + /// + [System.ComponentModel.Description("Occurs when popup of type container is unloading."), Category("Item")] + public event EventHandler PopupContainerUnload; + + /// + /// Occurs when popup item is about to open. Event is fired only when Bar is used independently of DotNetBarManager. + /// + [System.ComponentModel.Description("Occurs when popup item is about to open."), Category("Item")] + public event DotNetBarManager.PopupOpenEventHandler PopupOpen; + + /// + /// Occurs just before popup window is shown. Event is fired only when Bar is used independently of DotNetBarManager. + /// + [System.ComponentModel.Description("Occurs just before popup window is shown."), Category("Item")] + public event EventHandler PopupShowing; + + /// + /// Occurs before dock tab is displayed. + /// + [System.ComponentModel.Description("Occurs before dock tab is displayed.")] + public event EventHandler BeforeDockTabDisplayed; + + /// + /// Occurs when caption button is clicked. Caption button is button displayed on bars with grab handle style task pane. + /// + [System.ComponentModel.Description("Occurs when caption button is clicked on bars with grab handle style task pane.")] + public event EventHandler CaptionButtonClick; + + /// + /// Occurs on dockable bars when end-user attempts to close the individual DockContainerItem objects using system buttons on dock tab. + /// Event can be canceled by setting the Cancel property of event arguments to true. This even will occur only after user presses the + /// X button on tab that is displaying the dockable windows/documents. + /// + [System.ComponentModel.Description("Occurs on dockable bars when end-user attempts to close the individual DockContainerItem objects using system buttons on dock tab.")] + public event DockTabClosingEventHandler DockTabClosing; + + /// + /// Occurs on dockable bars after DockContainerItem is closed by end-user. This action cannot be cancelled. + /// + [System.ComponentModel.Description("Occurs on dockable bars after DockContainerItem is closed by end-user. This action cannot be cancelled.")] + public event DockTabClosingEventHandler DockTabClosed; + + /// + /// Occurs after an item has been serialized to XmlElement and provides you with opportunity to add any custom data + /// to serialized XML. This allows you to serialize any data with the item and load it back up in DeserializeItem event. + /// + /// + /// To serialize custom data to XML definition control creates handle this event and use CustomXmlElement + /// property on SerializeItemEventArgs to add new nodes or set attributes with custom data you want saved. + /// + public event SerializeItemEventHandler SerializeItem; + + /// + /// Occurs after an item has been de-serialized (load) from XmlElement and provides you with opportunity to load any custom data + /// you have serialized during SerializeItem event. + /// + /// + /// To de-serialize custom data from XML definition handle this event and use CustomXmlElement + /// property on SerializeItemEventArgs to retrive any data you saved in SerializeItem event. + /// + public event SerializeItemEventHandler DeserializeItem; + + /// + /// Occurs after the TabStrip style which used on dockable windows has changed. This event gives you opportunity to + /// change the style of the tab strip by accessing Bar.DockTabControl.Style property. + /// + public event EventHandler TabStripStyleChanged; + + /// + /// Occurs before the bar control is rendered. This event is fired once for each part of the bar control being rendered. Check the Part property of the event arguments to identify the part being rendered. + /// You can cancel internal rendering by setting Cancel property. + /// + public event RenderBarEventHandler PreRender; + + /// + /// Occurs after the bar control is rendered and allows you to render on top of the default rendering provided by the control. + /// + public event RenderBarEventHandler PostRender; + + /// + /// Occurs when DotNetBar is looking for translated text for one of the internal text that are + /// displayed on menus, toolbars and customize forms. You need to set Handled=true if you want + /// your custom text to be used instead of the built-in system value. + /// + public event DotNetBarManager.LocalizeStringEventHandler LocalizeString; + #endregion + + #region System Buttons class + private class System_Buttons + { + public System_Buttons(Rectangle closerect, Rectangle custrect, bool mouseoverclose, bool mouseovercustomize, bool mousednclose, bool mousedncust) + { + this.CloseButtonRect = closerect; + this.CustomizeButtonRect = custrect; + this.MouseOverClose = mouseoverclose; + this.MouseOverCustomize = mouseovercustomize; + this.MouseDownClose = mousednclose; + this.MouseDownCustomize = mousedncust; + this.MouseOverAutoHide = false; + this.MouseDownAutoHide = false; + this.AutoHideButtonRect = Rectangle.Empty; + this.ButtonSize = new Size(Dpi.Width14, Dpi.Height14); + } + public event EventHandler MouseOverCloseChanged; + public event EventHandler MouseOverMaximizeChanged; + public event EventHandler MouseOverCustomizeChanged; + public event EventHandler MouseOverAutoHideChanged; + public event EventHandler MouseDownCloseChanged; + public event EventHandler MouseDownMaximizeChanged; + public event EventHandler MouseDownCustomizeChanged; + public event EventHandler MouseDownAutoHideChanged; + public event EventHandler MouseOverCaptionChanged; + public event EventHandler MouseDownCaptionChanged; + public Rectangle CloseButtonRect; + public Rectangle CustomizeButtonRect; + public Rectangle AutoHideButtonRect; + public Rectangle CaptionButtonRect; + public Rectangle MaximizeButtonRect; + public System.Drawing.Size ButtonSize = new Size(14, 14); + private bool m_MouseOverClose = false; + private bool m_MouseOverMaximize = false; + private bool m_MouseOverCustomize = false; + private bool m_MouseDownClose = false; + private bool m_MouseDownMaximize = false; + private bool m_MouseDownCustomize = false; + private bool m_MouseOverAutoHide = false; + private bool m_MouseDownAutoHide = false; + private bool m_MouseOverCaption = false; + private bool m_MouseDownCaption = false; + + public bool MouseOverClose + { + get { return m_MouseOverClose; } + set + { + if (m_MouseOverClose != value) + { + m_MouseOverClose = value; + if (MouseOverCloseChanged != null) + MouseOverCloseChanged(this, new EventArgs()); + } + } + } + public bool MouseOverMaximize + { + get { return m_MouseOverMaximize; } + set + { + if (m_MouseOverMaximize != value) + { + m_MouseOverMaximize = value; + if (MouseOverMaximizeChanged != null) + MouseOverMaximizeChanged(this, new EventArgs()); + } + } + } + public bool MouseOverCaption + { + get { return m_MouseOverCaption; } + set + { + if (m_MouseOverCaption != value) + { + m_MouseOverCaption = value; + if (MouseOverCaptionChanged != null) + MouseOverCaptionChanged(this, new EventArgs()); + } + } + } + public bool MouseOverCustomize + { + get { return m_MouseOverCustomize; } + set + { + if (m_MouseOverCustomize != value) + { + m_MouseOverCustomize = value; + if (MouseOverCustomizeChanged != null) + MouseOverCustomizeChanged(this, new EventArgs()); + } + } + } + public bool MouseDownClose + { + get { return m_MouseDownClose; } + set + { + if (m_MouseDownClose != value) + { + m_MouseDownClose = value; + if (MouseDownCloseChanged != null) + MouseDownCloseChanged(this, new EventArgs()); + } + } + } + public bool MouseDownMaximize + { + get { return m_MouseDownMaximize; } + set + { + if (m_MouseDownMaximize != value) + { + m_MouseDownMaximize = value; + if (MouseDownMaximizeChanged != null) + MouseDownMaximizeChanged(this, new EventArgs()); + } + } + } + public bool MouseDownCaption + { + get { return m_MouseDownCaption; } + set + { + if (m_MouseDownCaption != value) + { + m_MouseDownCaption = value; + if (MouseDownCaptionChanged != null) + MouseDownCaptionChanged(this, new EventArgs()); + } + } + } + public bool MouseDownCustomize + { + get { return m_MouseDownCustomize; } + set + { + if (m_MouseDownCustomize != value) + { + m_MouseDownCustomize = value; + if (MouseDownCustomizeChanged != null) + MouseDownCustomizeChanged(this, new EventArgs()); + } + } + } + public bool MouseOverAutoHide + { + get { return m_MouseOverAutoHide; } + set + { + if (m_MouseOverAutoHide != value) + { + m_MouseOverAutoHide = value; + if (MouseOverAutoHideChanged != null) + MouseOverAutoHideChanged(this, new EventArgs()); + } + } + } + public bool MouseDownAutoHide + { + get { return m_MouseDownAutoHide; } + set + { + if (m_MouseDownAutoHide != value) + { + m_MouseDownAutoHide = value; + if (MouseDownAutoHideChanged != null) + MouseDownAutoHideChanged(this, new EventArgs()); + } + } + } + } + #endregion + + #region Constants + private struct ThemeMargin + { + public int Left; + public int Top; + public int Right; + public int Bottom; + public bool IsEmpty + { + get + { return (Left == 0 && Top == 0 && Right == 0 && Bottom == 0); } + } + } + + const int WM_MOUSEACTIVATE = 0x21; + const int MA_NOACTIVATE = 3; + const int MA_NOACTIVATEANDEAT = 4; + const long WS_POPUP = 0x80000000L; + const long WS_CLIPSIBLINGS = 0x04000000L; + const long WS_CLIPCHILDREN = 0x02000000L; + const long WS_EX_TOPMOST = 0x00000008L; + const long WS_EX_TOOLWINDOW = 0x00000080L; + const long WS_VISIBLE = 0x10000000L; + const int WM_WINDOWPOSCHANGING = 0x0046; + const int WM_WINDOWPOSCHANGED = 0x0047; + + const int SIZE_W = 1; + const int SIZE_E = 2; + const int SIZE_N = 3; + const int SIZE_S = 4; + const int SIZE_NWN = 5; + const int SIZE_NWS = 6; + const int SIZE_NEN = 7; + const int SIZE_NES = 8; + const int SIZE_HSPLITRIGHT = 9; + const int SIZE_HSPLITLEFT = 10; + const int SIZE_VSPLITTOP = 11; + const int SIZE_VSPLITBOTTOM = 12; + const int SIZE_HSPLIT = 13; + const int SIZE_VSPLIT = 14; + const int SIZE_PARENTRESIZE = 15; + + const int DRAGRECTANGLE_WIDTH = 3; + + const int GrabHandleDotNetWidth = 7; + const int GrabHandleOfficeWidth = 7; + const int GrabHandleResizeWidth = 17; + const int GrabHandleTaskPaneHeight = 23; + const int GrabHandleCaptionHeight = 20; + + const int DOCKTABSTRIP_HEIGHT = 25; + #endregion + + #region Private Variables + private BaseItem m_ParentItem; + private Point m_ParentItemScreenPos; + private object m_OldContainer; + private Rectangle m_ClientRect; + private SideBarImage m_SideBarImage; + private Rectangle m_SideBarRect; + private GenericItemContainer m_ItemContainer; + //private BaseItem m_OldParent; + private int m_InitialContainerWidth; + private eBarState m_BarState; + private eGrabHandleStyle m_GrabHandleStyle; + private Rectangle m_GrabHandleRect; + + // IDockInfo members + private int m_DockOffset; + private int m_DockLine; + + private object m_Owner; + private Point m_MouseDownPt; + private Size m_MouseDownSize; + private bool m_MoveWindow; + private int m_DockTabTearOffIndex = -1; // Used if dock tab is being torn-off but bar cannot float so processing needs to be done after the drop is complete + + private Rectangle m_FloatingRect; + private Size m_DockedSizeH = Size.Empty, m_DockedSizeV = Size.Empty; + private int m_SizeWindow; + // Used when show window content when dragging is not set + private DockSiteInfo m_DragDockInfo = new DockSiteInfo(); + private Rectangle m_LastDragRect; + internal DockSiteInfo m_LastDockSiteInfo = new DockSiteInfo(); + private bool m_WrapItemsDock; + private bool m_WrapItemsFloat; + private bool m_MenuBar; + private bool m_DockStretch; + private FloatingContainer m_Float; + private bool m_DockingInProgress; + private IntPtr m_LastFocusWindow; + private bool m_CanDockLeft = true, m_CanDockRight = true, m_CanDockTop = true, m_CanDockBottom = true, m_CanUndock, m_CanTearOffTabs = true, m_CanReorderTabs = true; + private bool m_CanDockTab = true; + private bool m_CanDockDocument = false; + private bool m_CanHide = false; + private bool m_CloseSingleTab = false; + private bool m_AcceptDropItems = true; + private eBorderType m_DockedBorder = eBorderType.None; + private Color m_SingleLineColor = SystemColors.ControlDark; + private bool m_CustomBar = false; + private System_Buttons m_SystemButtons = new System_Buttons(Rectangle.Empty, Rectangle.Empty, false, false, false, false); + private ePopupAnimation m_PopupAnimation = ePopupAnimation.ManagerControlled; + private PopupShadow m_DropShadow = null; + private eBarImageSize m_ImageSize = eBarImageSize.Default; + private Color m_CaptionBackColor = Color.Empty; + private Color m_CaptionForeColor = Color.Empty; + private PopupItem m_CustomizeMenu = null; + private TabStrip m_TabDockItems = null; + private bool m_AutoHideState = false, m_CanAutoHide = true; + private bool m_HasFocus = false; + private bool m_SystemPrefChanged = false, m_CustomFont = false; + private bool m_LockDockPosition = false; + private ColorScheme m_ColorScheme = null; + internal bool PassiveBar = false; + private bool m_ThemeAware = false; + private ThemeMargin m_ThemeWindowMargins = new ThemeMargin(); + //private int m_MinClientSize=64; // Minimum Parent Dockable size + + // Theme Caching Support + private ThemeWindow m_ThemeWindow = null; + private ThemeRebar m_ThemeRebar = null; + private ThemeToolbar m_ThemeToolbar = null; + private ThemeHeader m_ThemeHeader = null; + private ThemeScrollBar m_ThemeScrollBar = null; + private ThemeProgress m_ThemeProgress = null; + + // Support for same line docked windows + // internal int _SplitDockWidth=0; + // internal int _SplitDockHeight=0; + private int m_SplitDockWidthPercent = 0; + private int m_SplitDockHeightPercent = 0; + + // While docking is in progress this will hold the tabbed bar that this bar was added to if any + private Bar m_TempTabBar = null; + + // Tabbed Dockable Windows Tab Control position + private eTabStripAlignment m_DockTabAlignment = eTabStripAlignment.Bottom; + + // TODO: Menu Merge Implementation - Item Merge Support + //private bool m_MergeEnabled=false; + private bool m_HideFloatingInactive = true; + + private Point m_ResizeOffset = Point.Empty; + private bool m_TabNavigation = false; + + internal bool m_AccessibleObjectCreated = false; + + private bool m_BarDefinitionLoading = false; + private bool m_ParentMsgHandlerRegistered = false; + + private BaseItem m_DoDefaultActionItem = null; + + private int m_AutoHideAnimationTime = 100; + + private eBackgroundImagePosition m_BackgroundImagePosition = eBackgroundImagePosition.Stretch; + private byte m_BackgroundImageAlpha = 255; + + private bool m_ShowToolTips = true; + private bool m_IgnoreAnimation = true; + + protected ToolTip m_ToolTipWnd = null; + + private int m_DockSideDelayed = -1; + + private bool m_AnimationInProgress = false; + + private bool m_EnableRedraw = true; + + private bool m_AlwaysDisplayDockTab = false; + private bool m_MenuEventSupport = false; + private bool m_MenuFocus = false; + + private int m_BarShowIndex = -1; // Used to control bar Z-Order if WinForms change it... + private bool m_AlwaysDisplayKeyAccelerators = false; + + private bool m_AutoCreateCaptionMenu = true; + private PopupItem m_CaptionMenu = null; + private bool m_AutoSyncBarCaption = false; + + private bool m_SaveLayoutChanges = true; + private bool m_TabsRearranged = false; + + private IBarItemDesigner m_BarDesigner = null; + private bool m_LoadingHideFloating = false; + private bool m_DesignerSelection = false; + internal Hashtable PropertyBag = new Hashtable(); + + private int m_CornerSize = 3; + private bool m_FadeEffect = false; + private bool m_AntiAlias = false; + private eBarType m_BarType = eBarType.Toolbar; + private bool m_RoundCorners = true; + private bool m_AutoHideTextAlwaysVisible = false; + private bool m_DockTabCloseButtonVisible = false; + #endregion + + /// + /// Initializes a new instance of the Bar class. + /// + public Bar() + { + if (!ColorFunctions.ColorsLoaded) + { + NativeFunctions.RefreshSettings(); + NativeFunctions.OnDisplayChange(); + ColorFunctions.LoadColors(); + } + + m_ColorScheme = new ColorScheme(); + m_ParentItem = null; + m_OldContainer = null; + m_ClientRect = Rectangle.Empty; + m_SideBarRect = Rectangle.Empty; + m_SideBarImage = new SideBarImage(); + m_ItemContainer = new GenericItemContainer(); + m_ItemContainer.GlobalItem = false; + m_ItemContainer.ContainerControl = this; + m_ItemContainer.WrapItems = true; + m_ItemContainer.Stretch = false; + m_ItemContainer.Displayed = true; + m_ItemContainer.SystemContainer = true; + //m_ItemContainer.SetSystemItem(true); + //m_OldParent=null; + m_InitialContainerWidth = 164; + //m_BarState=eBarState.Popup; + m_BarState = eBarState.Docked; + + m_DockOffset = 0; + m_DockLine = 0; + m_GrabHandleStyle = eGrabHandleStyle.None; + m_GrabHandleRect = Rectangle.Empty; + m_Owner = null; + m_MouseDownPt = Point.Empty; + m_MouseDownSize = new Size(0, 0); + m_MoveWindow = false; + m_FloatingRect = Rectangle.Empty; + m_SizeWindow = 0; + + m_LastDragRect = Rectangle.Empty; + + m_WrapItemsDock = false; + m_WrapItemsFloat = true; + m_DockStretch = false; + m_MenuBar = false; + this.Text = ""; + + m_Float = null; + m_DockingInProgress = false; + + this.SetStyle(ControlStyles.Selectable, false); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + + this.TabStop = false; + base.Font = SystemFonts.MenuFont; // System.Windows.Forms.SystemInformation.MenuFont.Clone() as Font; + + m_CanDockLeft = true; + m_CanDockRight = true; + m_CanDockTop = true; + m_CanDockBottom = true; + m_CanUndock = true; + + Microsoft.Win32.SystemEvents.UserPreferenceChanged += new Microsoft.Win32.UserPreferenceChangedEventHandler(PreferenceChanged); + + this.IsAccessible = true; + + m_SystemButtons.MouseDownAutoHideChanged += new EventHandler(this.SysButtonHideTooltip); + m_SystemButtons.MouseDownCloseChanged += new EventHandler(this.SysButtonHideTooltip); + m_SystemButtons.MouseDownCustomizeChanged += new EventHandler(this.SysButtonHideTooltip); + m_SystemButtons.MouseOverAutoHideChanged += new EventHandler(this.SysButtonMouseOverAutoHide); + m_SystemButtons.MouseOverCustomizeChanged += new EventHandler(this.SysButtonMouseOverCustomize); + m_SystemButtons.MouseOverCloseChanged += new EventHandler(this.SysButtonMouseOverClose); + + StyleManager.Register(this); + } + + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + if (m_ItemContainer == null || this.IsDisposed) return; + if(this.Style == eDotNetBarStyle.StyleManagerControlled) + this.Style = eDotNetBarStyle.StyleManagerControlled; + this.Invalidate(); + } + private void PreferenceChanged(object sender, Microsoft.Win32.UserPreferenceChangedEventArgs e) + { + if (!m_SystemPrefChanged && !m_CustomFont) + { + m_SystemPrefChanged = true; + NativeFunctions.PostMessage(this.Handle, NativeFunctions.WM_USER + 102, IntPtr.Zero, IntPtr.Zero); + } + } + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + if(Dpi.RecordScalePerControl) + Dpi.SetScaling(factor); + if (m_ItemContainer != null) + m_ItemContainer.NotifyScaleItem(factor); + m_SystemButtons.ButtonSize = Dpi.Size(m_SystemButtons.ButtonSize, factor); + base.ScaleControl(factor, specified); + } + + protected override AccessibleObject CreateAccessibilityInstance() + { + return new BarAccessibleObject(this); + } + + private void SetupAccessibility() + { + if (this.Text != "") + this.AccessibleName = this.Text; + else + this.AccessibleName = "DotNetBar Bar"; + this.AccessibleDescription = this.AccessibleName + " (" + this.Name + ")"; + if (this.MenuBar) + this.AccessibleRole = AccessibleRole.MenuBar; + else + { + if (this.LayoutType == eLayoutType.DockContainer) + this.AccessibleRole = AccessibleRole.Grouping; + else if (this.GrabHandleStyle == eGrabHandleStyle.ResizeHandle) + this.AccessibleRole = AccessibleRole.StatusBar; + else + this.AccessibleRole = AccessibleRole.ToolBar; + } + } + + /// + /// Initializes a new instance of the Control class. + /// + /// Bar Caption + public Bar(string BarCaption) + : this() + { + this.Text = BarCaption; + } + + /// + /// Gets/Sets the owner of the Bar object. + /// + [System.ComponentModel.Browsable(false), DefaultValue(null), DevCoBrowsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object Owner + { + get + { + if (m_ParentItem is CustomizeItem) + return m_ParentItem.GetOwner(); + if (this.Parent != null && !(this.Parent is FloatingContainer) && !(this.Parent is DockSite) && !this.AutoHide && !m_DesignerParent || this.Parent == null && m_Owner == null) + return this; + return m_Owner; + } + set + { + m_Owner = value; + if (this.DesignMode && this.Site != null && m_TabDockItems != null) + this.RefreshDockTab(false); + } + } + internal bool IsDisposing = false; + protected override void Dispose(bool disposing) + { + StyleManager.Unregister(this); + IsDisposing = true; + if (m_ParentMsgHandlerRegistered) + { + DotNetBarManager.UnRegisterOwnerParentMsgHandler(this, null); + m_ParentMsgHandlerRegistered = false; + } + if (m_Float != null && disposing) + { + try + { + if (m_Float.Controls.Contains(this)) + m_Float.Controls.Remove(this); + m_Float.Close(); + m_Float.Dispose(); + m_Float = null; + } + catch (Exception) + { } + } + + if (m_Owner is DotNetBarManager && ((DotNetBarManager)m_Owner).IgnoreLoadedControlDispose) + this.Controls.Clear(); + + if (this.Parent != null) + { + try + { + this.Parent.Controls.Remove(this); + } + catch (Exception) + { } + } + Microsoft.Win32.SystemEvents.UserPreferenceChanged -= new Microsoft.Win32.UserPreferenceChangedEventHandler(PreferenceChanged); + if (m_TabDockItems != null) + { + m_TabDockItems.Dispose(); + m_TabDockItems = null; + } + if (m_DropShadow != null) + { + m_DropShadow.Hide(); + m_DropShadow.Dispose(); + m_DropShadow = null; + } + if (m_FilterInstalled) + { + MessageHandler.UnregisterMessageClient(this); + m_FilterInstalled = false; + } + + RestoreContainer(); + m_Owner = null; + m_ParentItem = null; + m_OldContainer = null; + //m_OldParent=null; + if (m_ItemContainer != null) + m_ItemContainer.Dispose(); + m_ItemContainer = null; + + base.Dispose(disposing); + IsDisposing = false; + } + + protected override CreateParams CreateParams + { + get + { + CreateParams p = base.CreateParams; + if (PassiveBar) + return p; + if (m_BarState == eBarState.Popup && (m_ParentItem == null || (m_ParentItem.Site == null || !m_ParentItem.Site.DesignMode))) + { + p.Style = unchecked((int)(WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); + p.ExStyle = (int)(WS_EX_TOPMOST | WS_EX_TOOLWINDOW); + } + //else if(m_BarState==eBarState.Floating) + //{ + // p.style=(int)(WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); + // p.exStyle=(int)(WS_EX_TOOLWINDOW); + //} + p.Caption = ""; + return p; + } + } + + internal bool HasFocus + { + get { return m_HasFocus; } + } + + internal void SetHasFocus(bool b) + { + m_HasFocus = b; + if (this.DockSide == eDockSide.None && this.LayoutType == eLayoutType.DockContainer && this.Owner is DotNetBarManager) + { + DotNetBarManager manager = this.Owner as DotNetBarManager; + if (b) + manager.InternalDockContainerActivated(this.SelectedDockContainerItem); + else + manager.InternalDockContainerDeactivated(this.SelectedDockContainerItem); + } + this.Refresh(); + } + + protected override void OnLeave(EventArgs e) + { + base.OnLeave(e); + if (m_HasFocus) + { + m_HasFocus = false; + if (m_GrabHandleStyle == eGrabHandleStyle.Caption && (m_BarState == eBarState.Docked || m_BarState == eBarState.AutoHide)) + this.Invalidate(); + + if (m_BarState == eBarState.AutoHide) + { + GetAutoHidePanel(m_LastDockSiteInfo.DockSide).StartTimer(); + } + } + } + + protected override void OnEnter(EventArgs e) + { + base.OnEnter(e); + if (!m_HasFocus) + { + m_HasFocus = true; + if (m_GrabHandleStyle == eGrabHandleStyle.Caption && (m_BarState == eBarState.Docked || m_BarState == eBarState.AutoHide)) + this.Invalidate(); + if (m_BarState == eBarState.AutoHide) + { + Point p = this.PointToClient(Control.MousePosition); + if (this.ClientRectangle.Contains(p)) + GetAutoHidePanel(m_LastDockSiteInfo.DockSide).StopTimer(); + } + } + } + + protected override bool IsInputKey(Keys keyData) + { + if (keyData == System.Windows.Forms.Keys.Left || keyData == System.Windows.Forms.Keys.Right || keyData == System.Windows.Forms.Keys.Up || keyData == System.Windows.Forms.Keys.Down || keyData == System.Windows.Forms.Keys.Enter || keyData == System.Windows.Forms.Keys.Return || keyData == System.Windows.Forms.Keys.Tab || keyData == System.Windows.Forms.Keys.Escape) + return true; + return base.IsInputKey(keyData); + } + + internal bool EnableRedraw + { + get + { + return m_EnableRedraw; + } + set + { + if (m_EnableRedraw != value && this.Visible) + { + m_EnableRedraw = value; + if (m_EnableRedraw) + NativeFunctions.SendMessage(this.Handle, NativeFunctions.WM_SETREDRAW, 1, 0); + else + NativeFunctions.SendMessage(this.Handle, NativeFunctions.WM_SETREDRAW, 0, 0); + } + } + } + +#if FRAMEWORK20 + protected override void OnBindingContextChanged(EventArgs e) + { + base.OnBindingContextChanged(e); + if (m_ItemContainer != null) + m_ItemContainer.UpdateBindings(); + } +#endif + + protected override void WndProc(ref Message m) + { + if (m.Msg == WM_MOUSEACTIVATE && (m_BarState == eBarState.Popup || m_BarState == eBarState.Floating && m_ItemContainer.LayoutType == eLayoutType.TaskList))// && m_BarState!=eBarState.Docked) + { + m.Result = new System.IntPtr(MA_NOACTIVATE); + return; + } + else if (m.Msg == NativeFunctions.WM_USER + 101) + { + if (!m_DockingInProgress && m_BarState == eBarState.Floating) + NativeFunctions.SetWindowPos(this.Handle, new IntPtr(NativeFunctions.HWND_TOP), 0, 0, 0, 0, NativeFunctions.SWP_NOMOVE | NativeFunctions.SWP_NOSIZE | NativeFunctions.SWP_NOACTIVATE); + } + else if (m.Msg == NativeFunctions.WM_USER + 102) + { + if (this.Name == "StatusBar") + this.Name = this.Name; + if (this.LayoutType != eLayoutType.DockContainer) + this.Font = SystemFonts.MenuFont; // System.Windows.Forms.SystemInformation.MenuFont.Clone() as Font; + this.RecalcLayout(); + m_SystemPrefChanged = false; + } + else if (m.Msg == NativeFunctions.WM_USER + 107) + { + if (m_DoDefaultActionItem != null) + { + m_DoDefaultActionItem.DoAccesibleDefaultAction(); + m_DoDefaultActionItem = null; + } + + } + else if (m.Msg == NativeFunctions.WM_SETFOCUS) + { + IntPtr wnd = m.WParam; + Control objCtrl = Control.FromChildHandle(wnd); + if (objCtrl != null && !(objCtrl is DevComponents.DotNetBar.Bar) && !(objCtrl is MenuPanel) && !(objCtrl is Controls.TextBoxX)) + { + Form form = objCtrl.FindForm(); + if (form == this.FindForm()) + m_LastFocusWindow = m.WParam; + else if (form != null) + m_LastFocusWindow = m.WParam; + } + } + else if (m.Msg == NativeFunctions.WM_KILLFOCUS) + { + bool bLostFocus = false; + Control objCtrl = Control.FromChildHandle(m.WParam); + if (objCtrl != null) + { + while (objCtrl.Parent != null) + objCtrl = objCtrl.Parent; + if (objCtrl != this && (m_ItemContainer != null && !m_ItemContainer.IsAnyOnHandle(objCtrl.Handle))) + bLostFocus = true; + } + else + bLostFocus = true; + + if (bLostFocus && m_ItemContainer != null) + m_ItemContainer.ContainerLostFocus(false); + } + else if (m.Msg == NativeFunctions.WM_THEMECHANGED) + { + this.RefreshThemes(); + this.RefreshThemeMargins(); + Themes.RefreshIsThemeActive(); + } + //else if (m.Msg == (int)WinApi.WindowsMessages.WM_NCHITTEST) + //{ + // Form form = this.FindForm(); + // Rectangle resizeRect = GetResizeHandleRectangle(); + // if (form != null && form.WindowState == FormWindowState.Normal && !resizeRect.IsEmpty) + // { + // int mouseX = WinApi.LOWORD(m.LParam); + // int mouseY = WinApi.HIWORD(m.LParam); + // if (resizeRect.Contains(this.PointToClient(new Point(mouseX, mouseY)))) + // { + // IntPtr formHandle = form.Handle; + // if (formHandle != IntPtr.Zero) + // { + // WinApi.POINT point1; + // WinApi.RECT rect1 = new WinApi.RECT(0, 0, form.ClientRectangle.Right, form.ClientRectangle.Bottom); + // if (this.RightToLeft == RightToLeft.Yes) + // { + // point1 = new WinApi.POINT(resizeRect.Left, resizeRect.Bottom); + // } + // else + // { + // point1 = new WinApi.POINT(resizeRect.Right, resizeRect.Bottom); + // } + // WinApi.MapWindowPoints(this.Handle, formHandle, ref point1, 1); + // int num3 = Math.Abs((int)(rect1.Bottom - point1.y)); + // int num4 = Math.Abs((int)(rect1.Right - point1.x)); + // if (this.RightToLeft != RightToLeft.Yes) + // { + // m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.BottomRightSizeableCorner); + // return; + // } + // } + // } + + // } + //} + base.WndProc(ref m); + } + + protected override void OnSystemColorsChanged(EventArgs e) + { + base.OnSystemColorsChanged(e); + Application.DoEvents(); + //m_ColorScheme.Refresh(null,true); + this.GetColorScheme().Refresh(null, true); + this.Refresh(); + } + + /// + /// Gets or sets the item default accessibility action will be performed on. + /// + BaseItem IAccessibilitySupport.DoDefaultActionItem + { + get { return m_DoDefaultActionItem; } + set { m_DoDefaultActionItem = value; } + } + + /// + /// Releases the focus from the bar and selects the control that had focus before bar was selected. If control that had focus could not be determined focus will stay on the bar. + /// This method is used by internal DotNetBar implementation and you should not use it. + /// + public void ReleaseFocus() + { + if (this.Focused && m_LastFocusWindow != IntPtr.Zero) + { + Control ctrl = Control.FromChildHandle(m_LastFocusWindow); + if (ctrl != null) + { + ctrl.Select(); + if (!ctrl.Focused) + NativeFunctions.SetFocus(m_LastFocusWindow); + } + else + { + NativeFunctions.SetFocus(m_LastFocusWindow); + } + m_LastFocusWindow = IntPtr.Zero; + m_ItemContainer.AutoExpand = false; + } + } + + /// + /// Returns the reference to the control that last had input focus. This property should be used to + /// determine which control had input focus before bar gained the focus. Use it to apply + /// the menu command to active control. + /// + [Browsable(false), DevCoBrowsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Control LastFocusControl + { + get + { + if (this.Focused && m_LastFocusWindow != IntPtr.Zero) + { + Control ctrl = Control.FromChildHandle(m_LastFocusWindow); + return ctrl; + } + return null; + } + } + + internal void SetSystemFocus() + { + if (!this.Focused) + { + m_ItemContainer.SetSystemFocus(); + this.Focus(); + } + } + + private Color[] _BorderColors = null; + /// + /// Indicates the array of colors that when set are used to draw the border of the item. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the border of the item."), TypeConverter(typeof(ArrayConverter))] + internal Color[] BorderColors + { + get + { + return _BorderColors; + } + set + { + if (_BorderColors != value) + { + _BorderColors = value; + //OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + this.Invalidate(); + } + } + } + + protected override void OnPaint(PaintEventArgs e) + { + if (m_ItemContainer == null || this.IsDisposed) + return; + + if (this.BackColor == Color.Transparent) + { + base.OnPaintBackground(e); + } + + Graphics g = e.Graphics; + g.PageUnit = GraphicsUnit.Pixel; + // Support for the design-time when insert position is drawn +#if TRIAL + if(NativeFunctions.ColorExpAlt()) + { + g.Clear(Color.White); + g.DrawString("Your DotNetBar Trial has expired :-(",this.Font,SystemBrushes.ControlText,0,0); + } + else + { + if(m_ItemContainer.EffectiveStyle==eDotNetBarStyle.Office2000) + PaintOffice(g); + else + PaintDotNet(e); + } +#else + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + PaintOffice(g); + else + PaintDotNet(e); +#endif + + if (_BorderColors != null && _BorderColors.Length > 0) + { + g.ResetClip(); + DisplayHelp.DrawRoundedRectangle(g, this.ClientRectangle, _BorderColors, 0); + } + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + if (m_AnimationInProgress || this.Width == 0 || this.Height == 0) + return; + + if (!(this.Parent is DockSite || this.Parent is FloatingContainer) && m_BarState == eBarState.Docked && !m_LayoutSuspended) + this.RecalcLayout(); + ResizeDockTab(); + } + + private void PaintBackgroundImage(Graphics g) + { + if (this.BackgroundImage == null) + return; + Rectangle r = this.ClientRectangle; + BarFunctions.PaintBackgroundImage(g, r, this.BackgroundImage, m_BackgroundImagePosition, m_BackgroundImageAlpha); + } + + private bool IsGradientStyle + { + get + { + return (this.Style == eDotNetBarStyle.Office2003 || this.Style == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(this.Style)); + } + } + + /// + /// Creates the Graphics object for the control. + /// + /// The Graphics object for the control. + public new Graphics CreateGraphics() + { + Graphics g = base.CreateGraphics(); + if (m_AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; +#if FRAMEWORK20 + if (!SystemInformation.IsFontSmoothingEnabled) +#endif + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + return g; + } + + #region Rendering Support + private Rendering.BaseRenderer m_DefaultRenderer = null; + private Rendering.BaseRenderer m_Renderer = null; + private eRenderMode m_RenderMode = eRenderMode.Global; + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public virtual Rendering.BaseRenderer GetRenderer() + { + if (m_RenderMode == eRenderMode.Global && Rendering.GlobalManager.Renderer != null) + return Rendering.GlobalManager.Renderer; + else if (m_RenderMode == eRenderMode.Custom && m_Renderer != null) + return m_Renderer; + + if (m_DefaultRenderer == null) + { + if (BarFunctions.IsOffice2007Style(this.Style)) + m_DefaultRenderer = new Rendering.Office2007Renderer(); + } + + return m_Renderer; + } + + /// + /// Gets or sets the redering mode used by control. Default value is eRenderMode.Global which means that static GlobalManager.Renderer is used. If set to Custom then Renderer property must + /// also be set to the custom renderer that will be used. + /// + [Browsable(false), DefaultValue(eRenderMode.Global)] + public eRenderMode RenderMode + { + get { return m_RenderMode; } + set + { + if (m_RenderMode != value) + { + m_RenderMode = value; + this.Invalidate(true); + } + } + } + + /// + /// Gets or sets the custom renderer used by the items on this control. RenderMode property must also be set to eRenderMode.Custom in order renderer + /// specified here to be used. + /// + [Browsable(false), DefaultValue(null)] + public DevComponents.DotNetBar.Rendering.BaseRenderer Renderer + { + get + { + return m_Renderer; + } + set { m_Renderer = value; } + } + #endregion + + internal ItemPaintArgs GetItemPaintArgs(Graphics g) + { + ItemPaintArgs pa = new ItemPaintArgs(m_Owner as IOwner, this, g, this.GetColorScheme()); + pa.DesignerSelection = m_DesignerSelection; + pa.Renderer = GetRenderer(); + + if (m_BarState == eBarState.Popup && m_ParentItem != null && m_ParentItem.DesignMode) + { + ISite site = this.GetSite(); + if (site != null && site.DesignMode) + pa.DesignerSelection = true; + } + + return pa; + } + + protected void PaintDotNet(PaintEventArgs e) + { + Graphics g = e.Graphics; + SmoothingMode sm = g.SmoothingMode; + TextRenderingHint th = g.TextRenderingHint; + RenderBarEventArgs re = null; + + if (m_AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + m_SystemButtons.CustomizeButtonRect = Rectangle.Empty; + m_SystemButtons.CloseButtonRect = Rectangle.Empty; + m_SystemButtons.AutoHideButtonRect = Rectangle.Empty; + m_SystemButtons.CaptionButtonRect = Rectangle.Empty; + m_SystemButtons.MaximizeButtonRect = Rectangle.Empty; + ColorScheme cs = this.GetColorScheme(); + + ItemPaintArgs pa = GetItemPaintArgs(g); + pa.ClipRectangle = e.ClipRectangle; + Pen p; + if (m_BarState == eBarState.Popup) + p = new Pen(pa.Colors.BarPopupBorder, 1); + else + p = new Pen(pa.Colors.BarFloatingBorder); + + if (this.DisplayShadow && !this.AlphaShadow && m_ParentItem != null && !BarFunctions.IsOffice2007Style(m_ParentItem.EffectiveStyle)) + SetupRegion(); + + if (m_BarState == eBarState.Popup) + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.Background, this.ClientRectangle); + OnPreRender(re); + if (!re.Cancel) + { + if (m_ParentItem != null && BarFunctions.IsOffice2007Style(m_ParentItem.EffectiveStyle) && GetRenderer() != null) + { + ToolbarRendererEventArgs tre = new ToolbarRendererEventArgs(this, g, this.DisplayRectangle); + tre.ItemPaintArgs = pa; + GetRenderer().DrawPopupToolbarBackground(tre); + } + else + { + using (SolidBrush brush = new SolidBrush(pa.Colors.BarPopupBackground)) + g.FillRectangle(brush, this.DisplayRectangle); + PaintBackgroundImage(pa.Graphics); + + PaintSideBar(g); + + Rectangle borderRectangle = this.ClientRectangle; + if (this.DisplayShadow && !this.AlphaShadow) + borderRectangle = new Rectangle(0, 0, this.ClientSize.Width - 2, this.ClientSize.Height - 2); + + if (m_ParentItem != null && BarFunctions.IsOffice2007Style(m_ParentItem.EffectiveStyle)) + DisplayHelp.DrawRoundedRectangle(g, p, borderRectangle, m_CornerSize); + else + NativeFunctions.DrawRectangle(g, p, borderRectangle); + + if (this.DisplayShadow && !this.AlphaShadow) + { + // Shadow + p.Dispose(); + p = new Pen(SystemColors.ControlDark, 2); + Point[] pt = new Point[3]; + pt[0].X = 2; + pt[0].Y = this.ClientSize.Height - 1; + pt[1].X = this.ClientSize.Width - 1; + pt[1].Y = this.ClientSize.Height - 1; + pt[2].X = this.ClientSize.Width - 1; + pt[2].Y = 2; + g.DrawLines(p, pt); + } + if (m_ParentItem != null && !BarFunctions.IsOffice2007Style(m_ParentItem.EffectiveStyle) && m_ParentItem is ButtonItem && m_ParentItem.Displayed) + { + // Determine where to draw the line based on parent position + if (m_ParentItemScreenPos.Y < this.Location.Y) + { + Point p1 = new Point((m_ParentItemScreenPos.X - this.Location.X) + 1, 0); + Point p2 = new Point(p1.X + m_ParentItem.WidthInternal - 5, 0); + DisplayHelp.DrawLine(g, p1, p2, pa.Colors.ItemExpandedBackground, 1); + //g.DrawLine(new Pen(pa.Colors.ItemExpandedBackground, 1), p1, p2); + } + } + } + } + } + else if (m_BarState == eBarState.Floating) + { + bool drawCaptionText = true; + + re = new RenderBarEventArgs(this, g, eBarRenderPart.Background, this.ClientRectangle); + OnPreRender(re); + if (!re.Cancel) + { + if (BarFunctions.IsOffice2007Style(this.Style) && this.GetRenderer() != null) + { + ToolbarRendererEventArgs tre = new ToolbarRendererEventArgs(this, g, this.DisplayRectangle); + tre.ItemPaintArgs = pa; + this.GetRenderer().DrawToolbarBackground(tre); + } + else + { + sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + if (this.MenuBar) + DisplayHelp.FillRectangle(g, this.ClientRectangle, pa.Colors.MenuBarBackground, pa.Colors.MenuBarBackground2, pa.Colors.MenuBarBackgroundGradientAngle); + else + DisplayHelp.FillRectangle(g, this.ClientRectangle, pa.Colors.BarBackground, pa.Colors.BarBackground2, pa.Colors.BarBackgroundGradientAngle); + + PaintBackgroundImage(pa.Graphics); + g.SmoothingMode = sm; + } + } + + Rectangle r = new Rectangle(0, 0, this.Width, this.Height); + + ThemeWindow theme = null; + ThemeWindowParts part = ThemeWindowParts.SmallFrameLeft; + ThemeWindowStates state = ThemeWindowStates.FrameActive; + + re = new RenderBarEventArgs(this, g, eBarRenderPart.Caption, Rectangle.Empty); + + if (this.DrawThemedCaption) + { + re.Bounds = new Rectangle(0, 0, this.Width, m_ThemeWindowMargins.Top + 1); + OnPreRender(re); + if (!re.Cancel) + { + theme = this.ThemeWindow; + if (this.LayoutType == eLayoutType.DockContainer && !m_HasFocus) + state = ThemeWindowStates.FrameInactive; + + theme.DrawBackground(g, part, state, new Rectangle(0, 0, m_ThemeWindowMargins.Left, this.Height)); + part = ThemeWindowParts.SmallFrameRight; + theme.DrawBackground(g, part, state, new Rectangle(this.Width - m_ThemeWindowMargins.Right, 0, m_ThemeWindowMargins.Left, this.Height)); + part = ThemeWindowParts.SmallFrameBottom; + theme.DrawBackground(g, part, state, new Rectangle(0, this.Height - m_ThemeWindowMargins.Bottom, this.Width, m_ThemeWindowMargins.Bottom)); + + if (this.LayoutType == eLayoutType.DockContainer && !m_HasFocus) + state = ThemeWindowStates.CaptionInactive; + part = ThemeWindowParts.SmallCaption; + } + r = new Rectangle(0, 0, this.Width, m_ThemeWindowMargins.Top + 1); + theme.DrawBackground(g, part, state, r); + r.Offset(0, 1); + } + else if (m_GrabHandleStyle == eGrabHandleStyle.Caption && this.LayoutType == eLayoutType.DockContainer && this.Style == eDotNetBarStyle.Office2000) + { + Rectangle rback = new Rectangle(3, 3, this.Width - 6, GetGrabHandleCaptionHeight()); + re.Bounds = rback; + OnPreRender(re); + if (!re.Cancel) + { + ControlPaint.DrawBorder3D(g, r, Border3DStyle.Raised, Border3DSide.All); + eDrawCaption flags = eDrawCaption.DC_SMALLCAP | eDrawCaption.DC_GRADIENT | eDrawCaption.DC_TEXT; + if (m_HasFocus) flags |= eDrawCaption.DC_ACTIVE; + IntPtr hdc = g.GetHdc(); + NativeFunctions.RECT rect = new NativeFunctions.RECT(rback.X, rback.Y, rback.Right, rback.Bottom); + try + { + NativeFunctions.DrawCaption(this.Handle, hdc, ref rect, flags); + } + finally + { + g.ReleaseHdc(hdc); + } + } + drawCaptionText = false; + r = rback; + } + else + { + Rectangle rback = new Rectangle(3, 3, this.Width - 6, GetGrabHandleCaptionHeight()); + re.Bounds = rback; + OnPreRender(re); + + if (!re.Cancel) + { + Pen p1 = new Pen(pa.Colors.BarFloatingBorder, 1); + NativeFunctions.DrawRectangle(g, p, r); + r.Inflate(-1, -1); + NativeFunctions.DrawRectangle(g, p, r); + + p1.Dispose(); + p1 = new Pen(pa.Colors.BarFloatingBorder, 1); + g.DrawLine(p1, 1, 2, 2, 2); + g.DrawLine(p1, this.Width - 3, 2, this.Width - 2, 2); + g.DrawLine(p1, 1, this.Height - 3, 2, this.Height - 3); + g.DrawLine(p1, this.Width - 3, this.Height - 3, this.Width - 2, this.Height - 3); + p1.Dispose(); + p1 = null; + + if (this.GrabHandleStyle != eGrabHandleStyle.CaptionTaskPane) + { + sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + + if (m_CaptionBackColor.IsEmpty) + { + if (this.LayoutType == eLayoutType.Toolbar || m_HasFocus) + DisplayHelp.FillRectangle(g, rback, pa.Colors.BarCaptionBackground, pa.Colors.BarCaptionBackground2, pa.Colors.BarCaptionBackgroundGradientAngle); + else + DisplayHelp.FillRectangle(g, rback, pa.Colors.BarCaptionInactiveBackground, pa.Colors.BarCaptionInactiveBackground2, pa.Colors.BarCaptionInactiveBackgroundGAngle); + } + else + DisplayHelp.FillRectangle(g, new Rectangle(3, 3, this.Width - 6, GetGrabHandleCaptionHeight()), m_CaptionBackColor, Color.Empty); + + g.SmoothingMode = sm; + } + } + r = rback; + } + + r.Inflate(-1, -1); + + if (this.GrabHandleStyle != eGrabHandleStyle.CaptionTaskPane) + { + if (this.CanHideResolved) + { + m_SystemButtons.CloseButtonRect = new Rectangle(r.Right - (m_SystemButtons.ButtonSize.Width + 3), r.Y + (r.Height - m_SystemButtons.ButtonSize.Height) / 2, m_SystemButtons.ButtonSize.Width, m_SystemButtons.ButtonSize.Height); + re = new RenderBarEventArgs(this, g, eBarRenderPart.CloseButton, m_SystemButtons.CloseButtonRect); + OnPreRender(re); + m_SystemButtons.CloseButtonRect = re.Bounds; + r.Width -= (m_SystemButtons.CloseButtonRect.Width + 3); + if (!re.Cancel) + PaintCloseButton(pa); + } + if (this.EffectiveCanMaximizeFloating) + { + m_SystemButtons.MaximizeButtonRect = + new Rectangle(r.Right - (m_SystemButtons.ButtonSize.Width + 3), + r.Y + (r.Height - m_SystemButtons.ButtonSize.Height)/2, m_SystemButtons.ButtonSize.Width, + m_SystemButtons.ButtonSize.Height); + re = new RenderBarEventArgs(this, g, eBarRenderPart.MaximizeButton, + m_SystemButtons.MaximizeButtonRect); + OnPreRender(re); + m_SystemButtons.MaximizeButtonRect = re.Bounds; + r.Width -= (m_SystemButtons.MaximizeButtonRect.Width + 3); + if (!re.Cancel) + PaintMaximizeButton(pa); + } + if (this.ShowCustomizeMenuButton) + { + m_SystemButtons.CustomizeButtonRect = new Rectangle(r.Right - (m_SystemButtons.ButtonSize.Width + 1), r.Y + (r.Height - m_SystemButtons.ButtonSize.Height) / 2, m_SystemButtons.ButtonSize.Width, m_SystemButtons.ButtonSize.Height); + re = new RenderBarEventArgs(this, g, eBarRenderPart.CustomizeButton, m_SystemButtons.CustomizeButtonRect); + OnPreRender(re); + m_SystemButtons.CustomizeButtonRect = re.Bounds; + r.Width -= (m_SystemButtons.CustomizeButtonRect.Width + 2); + if (!re.Cancel) + PaintCustomizeButton(pa); + } + r.X += 2; + r.Width -= 2; + if (r.Width > 0 && drawCaptionText) + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.CaptionText, r); + OnPreRender(re); + if (!re.Cancel) + { + System.Drawing.Font objFont = null; + try + { + objFont = new Font(this.Font, FontStyle.Bold); + } + catch + { + objFont = SystemFonts.MenuFont; // (Font)System.Windows.Forms.SystemInformation.MenuFont.Clone(); + } + eTextFormat sf = eTextFormat.Default | eTextFormat.EndEllipsis | eTextFormat.SingleLine | eTextFormat.VerticalCenter; + if (m_CaptionForeColor.IsEmpty) + { + if (this.DrawThemedCaption) + { + if (m_HasFocus) + state = ThemeWindowStates.CaptionActive; + else + state = ThemeWindowStates.CaptionInactive; + r.Y += 1; + //theme.DrawText(g, this.Text, objFont, r, part, state, ThemeTextFormat.Left | ThemeTextFormat.VCenter); + } + //else + TextDrawing.DrawString(g, this.Text, objFont, ((m_HasFocus || this.LayoutType == eLayoutType.Toolbar) ? pa.Colors.BarCaptionText : pa.Colors.BarCaptionInactiveText), r, sf); + } + else + TextDrawing.DrawString(g, this.Text, objFont, m_CaptionForeColor, r, sf); + objFont.Dispose(); + objFont = null; + } + } + } + else + { + this.PaintGrabHandle(pa); + } + } + else if (m_BarState == eBarState.Docked && BarFunctions.IsOffice2007Style(this.Style) && this.GetRenderer() != null && (!this.IsThemed || this.MenuBar)) + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.Background, this.DisplayRectangle); + OnPreRender(re); + if (!re.Cancel && this.BackColor != Color.Transparent) + { + ToolbarRendererEventArgs tre = new ToolbarRendererEventArgs(this, g, this.DisplayRectangle); + tre.ItemPaintArgs = pa; + this.GetRenderer().DrawToolbarBackground(tre); + } + else + PaintGrabHandle(pa); + } + else + { + p.Dispose(); + p = null; + bool drawBorder = true; + // Docked state + if (m_ItemContainer.m_BackgroundColor.IsEmpty && this.BackColor != Color.Transparent) + { + if (this.IsThemed) + { + Rectangle r = new Rectangle(-this.Location.X, -this.Location.Y, this.Parent.Width, this.Parent.Height); + ThemeRebar theme = this.ThemeRebar; + theme.DrawBackground(g, ThemeRebarParts.Background, ThemeRebarStates.Normal, r); + } + else + { + sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + re = new RenderBarEventArgs(this, g, eBarRenderPart.Background, this.ClientRectangle); + OnPreRender(re); + if (!re.Cancel) + { + if (this.MenuBar) + { + if (!pa.Colors.MenuBarBackground2.IsEmpty && pa.Colors.MenuBarBackground2.A > 0) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(this.ClientRectangle, pa.Colors.MenuBarBackground, pa.Colors.MenuBarBackground2, pa.Colors.MenuBarBackgroundGradientAngle); + g.FillRectangle(gradient, this.ClientRectangle); + gradient.Dispose(); + } + else if (IsGradientStyle && this.Parent != null && !pa.Colors.DockSiteBackColor2.IsEmpty && !pa.Colors.DockSiteBackColor.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(-this.Left, -this.Top, this.Parent.Width, this.Parent.Height), pa.Colors.DockSiteBackColor, pa.Colors.DockSiteBackColor2, 0f); + g.FillRectangle(gradient, -this.Left, -this.Top, this.Parent.Width, this.Parent.Height); + gradient.Dispose(); + } + else + { + using (SolidBrush brush = new SolidBrush(pa.Colors.MenuBarBackground)) + g.FillRectangle(brush, this.DisplayRectangle); + } + } + else + { + if (this.Style == eDotNetBarStyle.VS2005 && this.LayoutType == eLayoutType.DockContainer && !this.BackColor.IsEmpty) + { + DisplayHelp.FillRectangle(g, this.ClientRectangle, this.BackColor, Color.Empty); + } + else if (this.GradientBackground) + DisplayHelp.FillRectangle(g, this.ClientRectangle, pa.Colors.BarBackground, pa.Colors.BarBackground2, pa.Colors.BarBackgroundGradientAngle); + else + { + using (SolidBrush brush = new SolidBrush(pa.Colors.BarBackground)) + g.FillRectangle(brush, this.ClientRectangle); + } + } + } + else + drawBorder = false; + g.SmoothingMode = sm; + } + } + else if (!m_ItemContainer.BackColor.IsEmpty) + { + sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + re = new RenderBarEventArgs(this, g, eBarRenderPart.Background, this.DisplayRectangle); + OnPreRender(re); + if (!re.Cancel) + { + using (SolidBrush brush = new SolidBrush(m_ItemContainer.BackColor)) + g.FillRectangle(brush, this.DisplayRectangle); + } + else + drawBorder = false; + g.SmoothingMode = sm; + } + + if (this.Parent != null && this.Parent.BackgroundImage != null && this.Parent is DockSite) + { + Rectangle r = new Rectangle(-this.Location.X, -this.Location.Y, this.Parent.Width, this.Parent.Height); + DockSite site = this.Parent as DockSite; + BarFunctions.PaintBackgroundImage(g, r, site.BackgroundImage, site.BackgroundImagePosition, site.BackgroundImageAlpha); + } + else + PaintBackgroundImage(pa.Graphics); + + if (drawBorder) + { + if (IsGradientStyle && !this.IsThemed && this.LayoutType == eLayoutType.Toolbar && !this.MenuBar && this.BarType == eBarType.Toolbar && this.BackColor != Color.Transparent) + { + if (p != null) p.Dispose(); + p = new Pen(pa.Colors.BarDockedBorder, 1); + g.DrawLine(p, 0, this.Height - 1, this.Width, this.Height - 1); + p.Dispose(); + p = null; + } + else + { + Rectangle border = this.ClientRectangle; + border.Inflate(-2, -2); + BarFunctions.DrawBorder(g, m_DockedBorder, border, m_SingleLineColor); + } + } + PaintGrabHandle(pa); + } + m_ItemContainer.Paint(pa); + if (m_BarType == eBarType.StatusBar && this.GrabHandleStyle == eGrabHandleStyle.ResizeHandle) + { + PaintGrabHandle(pa); + } + if (p != null) p.Dispose(); + g.SmoothingMode = sm; + g.TextRenderingHint = th; + + if (HasPostRender) + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.All, this.ClientRectangle); + OnPostRender(re); + } + } + + /// + /// Raises the PreRender event. + /// + /// Provides the event arguments + protected virtual void OnPreRender(RenderBarEventArgs e) + { + if (PreRender != null) + PreRender(this, e); + } + + /// + /// Raises the PostRender event. + /// + /// Provides the event arguments + protected virtual void OnPostRender(RenderBarEventArgs e) + { + if (PostRender != null) + PostRender(this, e); + } + + private bool HasPostRender + { + get + { + return PostRender != null; + } + } + + private bool GradientBackground + { + get + { + if (this.Style == eDotNetBarStyle.VS2005 && this.LayoutType == eLayoutType.DockContainer) + return false; + return true; + } + } + + internal bool ThemedBackground + { + get + { + if (this.IsThemed && m_ItemContainer.m_BackgroundColor.IsEmpty) + return true; + return false; + } + } + + /// + /// Drawns bar grab handle if one specified. + /// + /// Context information. + internal void PaintGrabHandle(ItemPaintArgs pa) + { + RenderBarEventArgs re = null; + Graphics g = pa.Graphics; + // Draw grab handles + if (m_GrabHandleStyle != eGrabHandleStyle.None) + { + Rectangle r = Rectangle.Empty; + + if (m_GrabHandleStyle != eGrabHandleStyle.Caption && m_GrabHandleStyle != eGrabHandleStyle.CaptionTaskPane && m_GrabHandleStyle != eGrabHandleStyle.CaptionDotted && this.IsThemed && m_GrabHandleStyle != eGrabHandleStyle.ResizeHandle) + { + ThemeRebar theme = this.ThemeRebar; + ThemeRebarParts part = ThemeRebarParts.Gripper; + + if (m_ItemContainer.Orientation == eOrientation.Vertical) + { + part = ThemeRebarParts.GripperVert; + r = new Rectangle(m_GrabHandleRect.X + 2, m_GrabHandleRect.Top + 2, m_GrabHandleRect.Width - 4, 5); + } + else + r = new Rectangle(m_GrabHandleRect.X + 2, m_GrabHandleRect.Top + 2, 5, m_GrabHandleRect.Height - 4); + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, r); + OnPreRender(re); + r = re.Bounds; + if (!re.Cancel) + theme.DrawBackground(g, part, ThemeRebarStates.Normal, r); + return; + } + + Color clr = pa.Colors.BarBackground; + if (!m_ItemContainer.m_BackgroundColor.IsEmpty) + clr = m_ItemContainer.m_BackgroundColor; + + switch (m_GrabHandleStyle) + { + case eGrabHandleStyle.Single: + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType != eLayoutType.DockContainer) + { + r = new Rectangle(m_GrabHandleRect.X + 2, m_GrabHandleRect.Top + 2, 3, m_GrabHandleRect.Height - 4); + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, r); + OnPreRender(re); + if (!re.Cancel) + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, clr); + } + else + { + r = new Rectangle(m_GrabHandleRect.X + 2, m_GrabHandleRect.Top + 2, m_GrabHandleRect.Width - 4, 3); + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, r); + OnPreRender(re); + if (!re.Cancel) + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, clr); + } + break; + } + case eGrabHandleStyle.Double: + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType != eLayoutType.DockContainer) + { + r = new Rectangle(m_GrabHandleRect.X + 1, m_GrabHandleRect.Top + 1, 3, m_GrabHandleRect.Height - 2); + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, clr); + r.Offset(3, 0); + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, r); + OnPreRender(re); + if (!re.Cancel) + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, clr); + } + else + { + r = new Rectangle(m_GrabHandleRect.X + 1, m_GrabHandleRect.Top + 1, m_GrabHandleRect.Width - 2, 3); + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, clr); + r.Offset(0, 3); + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, r); + OnPreRender(re); + if (!re.Cancel) + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, clr); + } + break; + } + case eGrabHandleStyle.DoubleThin: + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType != eLayoutType.DockContainer) + { + r = new Rectangle(m_GrabHandleRect.X + 1, m_GrabHandleRect.Top + 2, 3, m_GrabHandleRect.Height - 4); + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.Left | System.Windows.Forms.Border3DSide.Right, clr); + r.Offset(3, 0); + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, r); + OnPreRender(re); + if (!re.Cancel) + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.Left | System.Windows.Forms.Border3DSide.Right, clr); + } + else + { + r = new Rectangle(m_GrabHandleRect.X + 2, m_GrabHandleRect.Top + 1, m_GrabHandleRect.Width - 4, 2); + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.Top | System.Windows.Forms.Border3DSide.Bottom, clr); + r.Offset(0, 3); + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, r); + OnPreRender(re); + if (!re.Cancel) + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.Top | System.Windows.Forms.Border3DSide.Bottom, clr); + } + break; + } + case eGrabHandleStyle.DoubleFlat: + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, m_GrabHandleRect); + OnPreRender(re); + if (!re.Cancel) + { + Pen pen = new Pen(ControlPaint.Dark(clr), 1); + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType != eLayoutType.DockContainer) + { + g.DrawLine(/*SystemPens.ControlDark*/pen, m_GrabHandleRect.X + 2, m_GrabHandleRect.Top + 2, m_GrabHandleRect.X + 2, m_GrabHandleRect.Height - 4); + g.DrawLine(/*SystemPens.ControlDark*/pen, m_GrabHandleRect.X + 5, m_GrabHandleRect.Top + 2, m_GrabHandleRect.X + 5, m_GrabHandleRect.Height - 4); + } + else + { + g.DrawLine(pen, m_GrabHandleRect.X + 2, m_GrabHandleRect.Top + 2, m_GrabHandleRect.Width - 4, m_GrabHandleRect.Y + 2); + g.DrawLine(pen, m_GrabHandleRect.X + 2, m_GrabHandleRect.Top + 5, m_GrabHandleRect.Width - 4, m_GrabHandleRect.Y + 5); + } + pen.Dispose(); + pen = null; + } + break; + } + case eGrabHandleStyle.Dotted: + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, m_GrabHandleRect); + OnPreRender(re); + if (!re.Cancel) + { + Brush brushDark = new SolidBrush(ControlPaint.Dark(clr)); + Brush brushLight = new SolidBrush(ControlPaint.Light(clr)); + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType != eLayoutType.DockContainer) + { + for (int i = 0; i < (m_GrabHandleRect.Height - 4); i += 4) + { + g.FillRectangle(/*SystemBrushes.ControlDark*/brushDark, m_GrabHandleRect.X + 1, m_GrabHandleRect.Top + 2 + i, 2, 2); + g.FillRectangle(/*SystemBrushes.ControlLight*/brushLight, m_GrabHandleRect.X + 1, m_GrabHandleRect.Top + 2 + i, 1, 1); + + g.FillRectangle(brushDark, m_GrabHandleRect.X + 5, m_GrabHandleRect.Top + 2 + i, 2, 2); + g.FillRectangle(brushLight, m_GrabHandleRect.X + 5, m_GrabHandleRect.Top + 2 + i, 1, 1); + } + } + else + { + for (int i = 0; i < (m_GrabHandleRect.Width - 4); i += 4) + { + g.FillRectangle(SystemBrushes.ControlDark, m_GrabHandleRect.Left + 2 + i, m_GrabHandleRect.Y + 1, 2, 2); + g.FillRectangle(SystemBrushes.ControlLight, m_GrabHandleRect.Left + 2 + i, m_GrabHandleRect.Y + 1, 1, 1); + + g.FillRectangle(SystemBrushes.ControlDark, m_GrabHandleRect.Left + 2 + i, m_GrabHandleRect.Y + 5, 2, 2); + g.FillRectangle(SystemBrushes.ControlLight, m_GrabHandleRect.Left + 2 + i, m_GrabHandleRect.Y + 5, 1, 1); + } + } + brushDark.Dispose(); + brushLight.Dispose(); + } + break; + } + case eGrabHandleStyle.Stripe: + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, m_GrabHandleRect); + OnPreRender(re); + if (!re.Cancel) + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType != eLayoutType.DockContainer) + { + for (int i = 0; i < (m_GrabHandleRect.Height - 4); i += 3) + BarFunctions.DrawBorder3D(g, m_GrabHandleRect.X + 2, m_GrabHandleRect.Top + i + 2, 5, 2, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.Top | System.Windows.Forms.Border3DSide.Bottom, clr); + //System.Windows.Forms.ControlPaint.DrawBorder3D(g,m_GrabHandleRect.X+2,m_GrabHandleRect.Top+i+2,5,2,System.Windows.Forms.Border3DStyle.RaisedInner,System.Windows.Forms.Border3DSide.Top | System.Windows.Forms.Border3DSide.Bottom); + } + else + { + for (int i = 0; i < (m_GrabHandleRect.Width - 4); i += 3) + BarFunctions.DrawBorder3D(g, m_GrabHandleRect.Left + i + 2, m_GrabHandleRect.Y + 2, 2, 5, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.Right | System.Windows.Forms.Border3DSide.Left, clr); + //System.Windows.Forms.ControlPaint.DrawBorder3D(g,m_GrabHandleRect.Left+i+2,m_GrabHandleRect.Y+2,2,5,System.Windows.Forms.Border3DStyle.RaisedInner,System.Windows.Forms.Border3DSide.Right | System.Windows.Forms.Border3DSide.Left); + } + } + break; + } + case eGrabHandleStyle.StripeFlat: + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, m_GrabHandleRect); + OnPreRender(re); + if (!re.Cancel) + { + Pen pen = new Pen(pa.Colors.BarStripeColor/*ControlPaint.Dark(clr)*/, 1); + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType != eLayoutType.DockContainer) + { + for (int i = 2; i < (m_GrabHandleRect.Height - 6); i += 2) + g.DrawLine(/*SystemPens.ControlDark*/pen, m_GrabHandleRect.X + 3, m_GrabHandleRect.Top + i + 3, m_GrabHandleRect.X + 5, m_GrabHandleRect.Top + i + 3); + } + else + { + for (int i = 1; i < (m_GrabHandleRect.Width - 6); i += 2) + g.DrawLine(/*SystemPens.ControlDark*/pen, m_GrabHandleRect.Left + i + 3, m_GrabHandleRect.Y + 2, m_GrabHandleRect.Left + i + 3, m_GrabHandleRect.Y + 5); + } + pen.Dispose(); + } + break; + } + case eGrabHandleStyle.CaptionTaskPane: + case eGrabHandleStyle.CaptionDotted: + { + Rectangle targetRect = m_GrabHandleRect; + Brush brush = null; + re = new RenderBarEventArgs(this, g, eBarRenderPart.Caption, m_GrabHandleRect); + OnPreRender(re); + if (!re.Cancel) + { + if (m_BarState == eBarState.Floating) + { + DisplayHelp.FillRectangle(g, targetRect, pa.Colors.BarCaptionBackground, pa.Colors.BarCaptionBackground2, pa.Colors.BarCaptionBackgroundGradientAngle); + } + else + { + if (!this.CaptionBackColor.IsEmpty) + brush = new SolidBrush(this.CaptionBackColor); + if (pa.Colors.BarBackground2.IsEmpty) + { + if (m_HasFocus && m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + brush = new SolidBrush(pa.Colors.BarCaptionBackground); + else + brush = new SolidBrush(pa.Colors.BarBackground); + } + else + { + brush = BarFunctions.CreateLinearGradientBrush(targetRect, pa.Colors.BarBackground, pa.Colors.BarBackground2, pa.Colors.BarBackgroundGradientAngle); + } + + g.FillRectangle(brush, targetRect); + + brush.Dispose(); + brush = null; + } + + Brush brushDark = null; + Brush brushLight = new SolidBrush(ControlPaint.Light(clr)); + + if (!pa.Colors.BarStripeColor.IsEmpty) + { + clr = pa.Colors.BarStripeColor; + brushDark = new SolidBrush(clr); + } + else + brushDark = new SolidBrush(ControlPaint.Dark(clr)); + int y = m_GrabHandleRect.Top + 4; + int x = m_GrabHandleRect.Left + 4; + for (int i = y; i <= m_GrabHandleRect.Bottom - 4; i += 5) + { + g.FillRectangle(brushLight, x + 1, i + 1, 2, 2); + g.FillRectangle(brushDark, x, i, 2, 2); + } + if (brushLight != null) brushLight.Dispose(); + if (brushDark != null) brushDark.Dispose(); + } + + targetRect.X += 8; + targetRect.Width -= 8; + + targetRect.Inflate(-1, -1); + PaintGrabHandleButtons(pa, ref targetRect); + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + PaintCaptionText(pa, targetRect); + break; + } + case eGrabHandleStyle.Caption: + { + Rectangle targetRect = m_GrabHandleRect; + re = new RenderBarEventArgs(this, g, eBarRenderPart.Caption, m_GrabHandleRect); + OnPreRender(re); + if (!re.Cancel) + { + ThemeWindow theme = null; + ThemeWindowParts part = ThemeWindowParts.SmallCaption; + ThemeWindowStates state = ThemeWindowStates.CaptionInactive; + if (this.DrawThemedCaption) + theme = this.ThemeWindow; + + if (m_DockedBorder == eBorderType.None) + targetRect.Inflate(-1, 0); + if (m_CaptionBackColor.IsEmpty) + { + if (this.Style == eDotNetBarStyle.Office2000) + { + if (m_HasFocus) + g.FillRectangle(SystemBrushes.ActiveCaption, targetRect); + else + g.FillRectangle(SystemBrushes.InactiveCaption, targetRect); + } + else + { + if (this.DrawThemedCaption) + { + if (m_HasFocus) + state = ThemeWindowStates.CaptionActive; + theme.DrawBackground(g, part, state, targetRect); + } + else + { + Color hatchForeColor, hatchBackColor; + if (m_HasFocus) + { + hatchForeColor = Color.FromArgb(128, pa.Colors.BarCaptionText); + hatchBackColor = pa.Colors.BarCaptionBackground; + if (pa.Colors.BarCaptionBackground2.IsEmpty) + DisplayHelp.FillRectangle(g, targetRect, pa.Colors.BarCaptionBackground); + else + { + using (System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(targetRect, pa.Colors.BarCaptionBackground, pa.Colors.BarCaptionBackground2, pa.Colors.BarCaptionBackgroundGradientAngle)) + g.FillRectangle(gradient, targetRect); + } + } + else + { + hatchForeColor = Color.FromArgb(192, pa.Colors.BarCaptionInactiveText); + hatchBackColor = pa.Colors.BarCaptionInactiveBackground; + if (pa.Colors.BarCaptionInactiveBackground2.IsEmpty) + DisplayHelp.FillRectangle(g, targetRect, pa.Colors.BarCaptionInactiveBackground); + else + { + using (System.Drawing.Drawing2D.LinearGradientBrush brush = BarFunctions.CreateLinearGradientBrush(targetRect, pa.Colors.BarCaptionInactiveBackground, pa.Colors.BarCaptionInactiveBackground2, pa.Colors.BarCaptionInactiveBackgroundGAngle)) + { + g.FillRectangle(brush, targetRect); + } + } + + eDotNetBarStyle effectiveStyle = m_ItemContainer.EffectiveStyle; + if (effectiveStyle != eDotNetBarStyle.VS2005 && effectiveStyle != eDotNetBarStyle.Office2010 && !StyleManager.IsMetro(effectiveStyle)) + { + Pen penCap = new Pen(pa.Colors.BarCaptionBackground, 1); + g.DrawLine(penCap, targetRect.X + 1, targetRect.Y, targetRect.Right - 2, targetRect.Y); + g.DrawLine(penCap, targetRect.X + 1, targetRect.Bottom - 1, targetRect.Right - 2, targetRect.Bottom - 1); + g.DrawLine(penCap, targetRect.X, targetRect.Y + 1, targetRect.X, targetRect.Bottom - 2); + g.DrawLine(penCap, targetRect.Right - 1, targetRect.Y + 1, targetRect.Right - 1, targetRect.Bottom - 2); + penCap.Dispose(); + } + } + if (StyleManager.IsVisualStudio2012(StyleManager.Style)) + { + Rectangle hatchRect = new Rectangle(targetRect.X, targetRect.Y + (targetRect.Height - 6) / 2, targetRect.Width, 6); + if (!string.IsNullOrEmpty(this.Text)) + { + Size textSize = TextDrawing.MeasureString(g, this.Text, this.Font); + textSize.Width += 8; + if (textSize.Width < hatchRect.Width) + { + hatchRect.Width -= textSize.Width; + hatchRect.X += textSize.Width; + if (CanHideResolved) + hatchRect.Width -= 16; + if (GetPaintAutoHidePin()) + hatchRect.Width -= 16; + if (ShowCustomizeMenuButton) + hatchRect.Width -= 16; + if (hatchRect.Width <= 0) + hatchRect = Rectangle.Empty; + } + else + hatchRect = Rectangle.Empty; + } + if (!hatchRect.IsEmpty) + { + Region oldClip = g.Clip; + g.SetClip(new Rectangle(hatchRect.X + 2, hatchRect.Y, hatchRect.Width - 2, hatchRect.Height), CombineMode.Intersect); + using (HatchBrush hatch = new HatchBrush(HatchStyle.Percent20, hatchForeColor, hatchBackColor)) + g.FillRectangle(hatch, hatchRect); + g.Clip = oldClip; + if (oldClip != null) oldClip.Dispose(); + } + } + } + } + } + else + { + DisplayHelp.FillRectangle(g, targetRect, m_CaptionBackColor); + } + } + + targetRect.Inflate(-1, -1); + + PaintGrabHandleButtons(pa, ref targetRect); + + PaintCaptionText(pa, targetRect); + break; + } + case eGrabHandleStyle.ResizeHandle: + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.ResizeHandle, m_GrabHandleRect); + OnPreRender(re); + if (!re.Cancel && !StyleManager.IsMetro(m_ItemContainer.EffectiveStyle)) + { + // Paint Internet Explorer-style dotted sizer in lower right + // draw light 'shadows' + Form form = this.FindForm(); + if (form != null && form.WindowState == FormWindowState.Maximized) + break; + int direction = 1; + Point startLoc = new Point(this.ClientRectangle.Right, this.ClientRectangle.Bottom); + if (this.RightToLeft == RightToLeft.Yes) + { + direction = -1; + startLoc = new Point(0, this.ClientRectangle.Bottom - 2); + } + ColorFunctions.HLSColor hls = ColorFunctions.RGBToHSL(clr); + Color lightColor = ColorFunctions.HLSToRGB(hls.Hue, hls.Lightness + .3d, hls.Saturation); + Pen pen = new Pen(lightColor, 1); + g.DrawLine(pen, startLoc.X - 2 * direction, startLoc.Y - 2, + startLoc.X - 3 * direction, startLoc.Y - 2); + g.DrawLine(pen, startLoc.X - 6 * direction, startLoc.Y - 2, + startLoc.X - 7 * direction, startLoc.Y - 2); + g.DrawLine(pen, startLoc.X - 10 * direction, startLoc.Y - 2, + startLoc.X - 11 * direction, startLoc.Y - 2); + g.DrawLine(pen, startLoc.X - 2 * direction, startLoc.Y - 2, + startLoc.X - 2 * direction, startLoc.Y - 3); + g.DrawLine(pen, startLoc.X - 6 * direction, startLoc.Y - 2, + startLoc.X - 6 * direction, startLoc.Y - 3); + g.DrawLine(pen, startLoc.X - 10 * direction, startLoc.Y - 2, + startLoc.X - 10 * direction, startLoc.Y - 3); + g.DrawLine(pen, startLoc.X - 2 * direction, startLoc.Y - 6, + startLoc.X - 3 * direction, startLoc.Y - 6); + g.DrawLine(pen, startLoc.X - 6 * direction, startLoc.Y - 6, + startLoc.X - 7 * direction, startLoc.Y - 6); + g.DrawLine(pen, startLoc.X - 2 * direction, startLoc.Y - 6, + startLoc.X - 2 * direction, startLoc.Y - 7); + g.DrawLine(pen, startLoc.X - 6 * direction, startLoc.Y - 6, + startLoc.X - 6 * direction, startLoc.Y - 7); + g.DrawLine(pen, startLoc.X - 2 * direction, startLoc.Y - 10, + startLoc.X - 3 * direction, startLoc.Y - 10); + g.DrawLine(pen, startLoc.X - 2 * direction, startLoc.Y - 10, + startLoc.X - 2 * direction, startLoc.Y - 11); + pen.Dispose(); + + // draw dark squares + if (!StyleManager.IsMetro(m_ItemContainer.EffectiveStyle)) + { + pen = new Pen(pa.Colors.BarStripeColor/*ControlPaint.Dark(clr)*/, 1); + g.DrawRectangle(pen, startLoc.X - 4 * direction, startLoc.Y - 4, 1, 1); + g.DrawRectangle(pen, startLoc.X - 8 * direction, startLoc.Y - 4, 1, 1); + g.DrawRectangle(pen, startLoc.X - 12 * direction, startLoc.Y - 4, 1, 1); + g.DrawRectangle(pen, startLoc.X - 4 * direction, startLoc.Y - 8, 1, 1); + g.DrawRectangle(pen, startLoc.X - 8 * direction, startLoc.Y - 8, 1, 1); + g.DrawRectangle(pen, startLoc.X - 4 * direction, startLoc.Y - 12, 1, 1); + pen.Dispose(); + pen = null; + } + } + break; + } + case eGrabHandleStyle.Office2003: + case eGrabHandleStyle.Office2003SingleDot: + { + re = new RenderBarEventArgs(this, g, eBarRenderPart.GrabHandle, m_GrabHandleRect); + OnPreRender(re); + if (!re.Cancel) + { + int x = m_GrabHandleRect.Left + (m_GrabHandleRect.Width - 3) / 2; + int y = m_GrabHandleRect.Top + 4; + + if (m_GrabHandleStyle == eGrabHandleStyle.Office2003SingleDot) + { + x = m_GrabHandleRect.Left + (m_GrabHandleRect.Width - 3) / 2; + y = m_GrabHandleRect.Top + (m_GrabHandleRect.Height - 3) / 2; + } + else + { + if (m_ItemContainer.Orientation == eOrientation.Vertical) + { + x = m_GrabHandleRect.Left + 4; + y = m_GrabHandleRect.Top + (m_GrabHandleRect.Height - 3) / 2; + } + } + + Brush brushDark = null; + Brush brushLight = new SolidBrush(ControlPaint.Light(clr)); + + if (!pa.Colors.BarStripeColor.IsEmpty) + { + clr = pa.Colors.BarStripeColor; + brushDark = new SolidBrush(clr); + } + else + brushDark = new SolidBrush(ControlPaint.Dark(clr)); + + if (m_GrabHandleStyle == eGrabHandleStyle.Office2003SingleDot) + { + g.FillRectangle(brushLight, x + 1, y + 1, 2, 2); + g.FillRectangle(brushDark, x, y, 2, 2); + } + else + { + if (StyleManager.IsVisualStudio2012(StyleManager.Style)) + { + Rectangle tr = new Rectangle(m_GrabHandleRect.X, m_GrabHandleRect.Y+2, 6, m_GrabHandleRect.Height-4); + Region oldClip = g.Clip; + g.SetClip(new Rectangle(tr.X, tr.Y + 1, tr.Width, tr.Height - 2), CombineMode.Intersect); + using (HatchBrush hatch = new HatchBrush(HatchStyle.Percent20, clr, pa.Colors.BarBackground)) + g.FillRectangle(hatch, tr); + g.Clip = oldClip; + if (oldClip != null) oldClip.Dispose(); + } + else + { + if (m_ItemContainer.Orientation == eOrientation.Vertical) + { + for (int i = x; i <= m_GrabHandleRect.Right - 4; i += 5) + { + g.FillRectangle(brushLight, i + 1, y + 1, 2, 2); + g.FillRectangle(brushDark, i, y, 2, 2); + } + } + else + { + for (int i = y; i <= m_GrabHandleRect.Bottom - 4; i += 5) + { + g.FillRectangle(brushLight, x + 1, i + 1, 2, 2); + g.FillRectangle(brushDark, x, i, 2, 2); + } + } + } + } + brushDark.Dispose(); + brushLight.Dispose(); + } + break; + } + } + } + } + + private void PaintCaptionText(ItemPaintArgs pa, Rectangle targetRect) + { + Graphics g = pa.Graphics; + RenderBarEventArgs re = new RenderBarEventArgs(this, g, eBarRenderPart.CaptionText, targetRect); + OnPreRender(re); + if (re.Cancel) return; + System.Drawing.Font objFont = null; + bool bDisposeFont = false; + try + { + objFont = this.Font.Clone() as Font; //new Font(this.Font.Name, 8); + bDisposeFont = true; + } + catch + { + objFont = SystemFonts.MenuFont; // System.Windows.Forms.SystemInformation.MenuFont; + bDisposeFont = true; + } + eTextFormat sf = eTextFormat.Default | eTextFormat.SingleLine | eTextFormat.EndEllipsis | eTextFormat.VerticalCenter; + if (m_CaptionForeColor.IsEmpty) + { + if (this.IsThemed) + { + if (targetRect.Height < objFont.Height) + targetRect.Height = objFont.Height; + if (targetRect.Width > 0) + { + if (!m_HasFocus) + TextDrawing.DrawString(g, this.Text, objFont, SystemColors.WindowText, targetRect, sf); + else + TextDrawing.DrawString(g, this.Text, objFont, SystemColors.ActiveCaptionText, targetRect, sf); + } + } + else + { + if (targetRect.Height < objFont.Height) + targetRect.Height = objFont.Height; + if (targetRect.Width > 0) + { + Color textColor = pa.Colors.BarCaptionText; + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + textColor = pa.Colors.ItemText; + else if ((this.Style == eDotNetBarStyle.OfficeXP || this.Style == eDotNetBarStyle.Office2003 || this.Style == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(this.Style)) && !m_HasFocus) + textColor = pa.Colors.BarCaptionInactiveText; + TextDrawing.DrawString(g, this.Text, objFont, textColor, targetRect, sf); + } + } + } + else if (targetRect.Width > 0) + TextDrawing.DrawString(g, this.Text, objFont, m_CaptionForeColor, targetRect, sf); + if (bDisposeFont) + objFont.Dispose(); + } + + /// + /// Gets whether caption of floating bar will be drawn using themes. + /// + internal bool DrawThemedCaption + { + get + { + if (BarFunctions.IsOffice2007Style(this.Style) || !this.ThemeAware) + return false; + if (this.IsThemed || m_BarState == eBarState.Floating && BarFunctions.ThemedOS && Themes.ThemesActive && this.LayoutType == eLayoutType.DockContainer) + return true; + return false; + } + } + + private bool GetPaintAutoHidePin() + { + bool ret = false; + if (m_CanAutoHide && m_ItemContainer.LayoutType == eLayoutType.DockContainer && m_BarState != eBarState.Floating) + { + if (this.Parent is DockSite && this.Parent.Dock == DockStyle.Fill) + ret = false; + else + ret = true; + } + return ret; + } + + private void PaintGrabHandleButtons(ItemPaintArgs pa, ref Rectangle targetRect) + { + RenderBarEventArgs re = null; + if (this.CanHideResolved) + { + if (this.Style == eDotNetBarStyle.Office2000) + m_SystemButtons.CloseButtonRect = new Rectangle(targetRect.Right - 11, targetRect.Y + (targetRect.Height - m_SystemButtons.ButtonSize.Width) / 2, m_SystemButtons.ButtonSize.Width, m_SystemButtons.ButtonSize.Height); + else + m_SystemButtons.CloseButtonRect = new Rectangle(targetRect.Right - (m_SystemButtons.ButtonSize.Width + 1), targetRect.Y + (targetRect.Height - m_SystemButtons.ButtonSize.Height) / 2, m_SystemButtons.ButtonSize.Width, m_SystemButtons.ButtonSize.Height); + re = new RenderBarEventArgs(this, pa.Graphics, eBarRenderPart.CloseButton, m_SystemButtons.CloseButtonRect); + OnPreRender(re); + m_SystemButtons.CloseButtonRect = re.Bounds; + targetRect.Width -= (m_SystemButtons.CloseButtonRect.Width + 3); + if (!re.Cancel) + PaintCloseButton(pa); + } + if (GetPaintAutoHidePin()) + { + if (this.Style == eDotNetBarStyle.Office2000) + m_SystemButtons.AutoHideButtonRect = new Rectangle(targetRect.Right - (m_SystemButtons.ButtonSize.Width - 1), targetRect.Y + (targetRect.Height - m_SystemButtons.ButtonSize.Height) / 2, m_SystemButtons.ButtonSize.Width, m_SystemButtons.ButtonSize.Height); + else + m_SystemButtons.AutoHideButtonRect = new Rectangle(targetRect.Right - (m_SystemButtons.ButtonSize.Width + 1), targetRect.Y + (targetRect.Height - m_SystemButtons.ButtonSize.Height) / 2, m_SystemButtons.ButtonSize.Width, m_SystemButtons.ButtonSize.Height); + re = new RenderBarEventArgs(this, pa.Graphics, eBarRenderPart.AutoHideButton, m_SystemButtons.AutoHideButtonRect); + OnPreRender(re); + m_SystemButtons.AutoHideButtonRect = re.Bounds; + targetRect.Width -= (m_SystemButtons.AutoHideButtonRect.Width + 3); + if (!re.Cancel) + PaintAutoHideButton(pa); + } + if (this.ShowCustomizeMenuButton) + { + re = new RenderBarEventArgs(this, pa.Graphics, eBarRenderPart.CustomizeButton, Rectangle.Empty); + + if (this.Style == eDotNetBarStyle.Office2000) + { + m_SystemButtons.CustomizeButtonRect = new Rectangle(targetRect.X, targetRect.Y + (targetRect.Height - m_SystemButtons.ButtonSize.Height) / 2, m_SystemButtons.ButtonSize.Width, m_SystemButtons.ButtonSize.Height); + re.Bounds = m_SystemButtons.CustomizeButtonRect; + OnPreRender(re); + m_SystemButtons.CustomizeButtonRect = re.Bounds; + targetRect.Width -= (m_SystemButtons.CustomizeButtonRect.Width + 2); + targetRect.X += (m_SystemButtons.CustomizeButtonRect.Width + 2); + } + else + { + m_SystemButtons.CustomizeButtonRect = new Rectangle(targetRect.Right - (m_SystemButtons.ButtonSize.Width + 1), targetRect.Y + (targetRect.Height - m_SystemButtons.ButtonSize.Height) / 2, m_SystemButtons.ButtonSize.Width, m_SystemButtons.ButtonSize.Height); + re.Bounds = m_SystemButtons.CustomizeButtonRect; + OnPreRender(re); + m_SystemButtons.CustomizeButtonRect = re.Bounds; + targetRect.Width -= (m_SystemButtons.CustomizeButtonRect.Width + 2); + } + + if (!re.Cancel) + PaintCustomizeButton(pa); + } + + if (this.GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane) + { + targetRect.X += 2; + targetRect.Width -= 2; + targetRect.Inflate(0, -2); + m_SystemButtons.CaptionButtonRect = targetRect; + re = new RenderBarEventArgs(this, pa.Graphics, eBarRenderPart.CaptionTaskPane, m_SystemButtons.CaptionButtonRect); + OnPreRender(re); + m_SystemButtons.CaptionButtonRect = re.Bounds; + if (!re.Cancel) + PaintCaptionButton(pa); + } + + targetRect.X += 2; + targetRect.Width -= 2; + } + + protected void PaintOffice(Graphics g) + { + m_SystemButtons.CustomizeButtonRect = Rectangle.Empty; + m_SystemButtons.CloseButtonRect = Rectangle.Empty; + + if (m_ItemContainer.BackColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(SystemColors.Control)) + g.FillRectangle(brush, this.DisplayRectangle); + } + else + { + using (SolidBrush brush = new SolidBrush(m_ItemContainer.BackColor)) + g.FillRectangle(brush, this.DisplayRectangle); + } + ColorScheme cs = this.GetColorScheme(); + PaintSideBar(g); + ItemPaintArgs pa = GetItemPaintArgs(g); // new ItemPaintArgs(m_Owner as IOwner, this, g, cs); // TODO: ADD SUPPORT FOR SCHEMES + //pa.DesignerSelection = m_DesignerSelection; + if (m_ItemContainer.SubItems.Count > 0) + { + if (m_BarState == eBarState.Popup) + { + System.Windows.Forms.ControlPaint.DrawBorder3D(g, 0, 0, this.ClientSize.Width, this.ClientSize.Height, System.Windows.Forms.Border3DStyle.Raised); + PaintSideBar(g); + } + else if (m_BarState == eBarState.Floating) + { + System.Windows.Forms.ControlPaint.DrawBorder3D(g, 0, 0, this.ClientSize.Width, this.ClientSize.Height, System.Windows.Forms.Border3DStyle.Raised | System.Windows.Forms.Border3DStyle.RaisedOuter); + if (m_CaptionBackColor.IsEmpty) + g.FillRectangle(SystemBrushes.ActiveCaption, 4, 4, this.ClientSize.Width - 8, 15); + else + { + using (SolidBrush b1 = new SolidBrush(m_CaptionBackColor)) + g.FillRectangle(b1, 4, 4, this.ClientSize.Width - 8, 15); + } + + System.Drawing.Font objFont = null; + bool bDisposeFont = false; + try + { + objFont = new Font(this.Font, FontStyle.Bold); + bDisposeFont = true; + } + catch + { + objFont = SystemFonts.MenuFont; // System.Windows.Forms.SystemInformation.MenuFont; + bDisposeFont = true; + } + + Rectangle r = Rectangle.Empty; + if (this.ShowCustomizeMenuButton) + { + r = new Rectangle(18, 4, this.ClientSize.Width - 22, 15); + m_SystemButtons.CustomizeButtonRect = new Rectangle(5, 6, 15, 14); + PaintCustomizeButton(pa); + } + else + { + r = new Rectangle(4, 4, this.ClientSize.Width - 8, 15); + } + if (this.CanHideResolved) + { + m_SystemButtons.CloseButtonRect = new Rectangle(r.Right - m_SystemButtons.ButtonSize.Width, 6, m_SystemButtons.ButtonSize.Width, m_SystemButtons.ButtonSize.Height); + PaintCloseButton(pa); + r.Width -= (m_SystemButtons.ButtonSize.Width + 1); + } + + if (m_CaptionForeColor.IsEmpty) + TextDrawing.DrawString(g, this.Text, objFont, SystemColors.ActiveCaptionText, r, eTextFormat.Default); + else + TextDrawing.DrawString(g, this.Text, objFont, m_CaptionForeColor, r, eTextFormat.Default); + + if (bDisposeFont) + objFont.Dispose(); + } + else + { + // Docked state + BarFunctions.DrawBorder(g, m_DockedBorder, this.ClientRectangle, m_SingleLineColor); + PaintGrabHandle(pa); + } + + m_ItemContainer.Paint(pa); + } + } + private void PaintMaximizeButton() + { + this.Invalidate(m_SystemButtons.MaximizeButtonRect); + this.Update(); + } + private void PaintCloseButton() + { + this.Invalidate(m_SystemButtons.CloseButtonRect); + this.Update(); + } + private void PaintCloseButton(ItemPaintArgs pa) + { + if (m_SystemButtons.CloseButtonRect.IsEmpty) + return; + + Graphics g = pa.Graphics; + + if (this.DrawThemedCaption) + { + ThemeWindow theme = this.ThemeWindow; + ThemeWindowParts part = ThemeWindowParts.SmallCloseButton; + ThemeWindowStates state = ThemeWindowStates.ButtonNormal; + if (m_SystemButtons.MouseDownClose) + state = ThemeWindowStates.ButtonPushed; + else if (m_SystemButtons.MouseOverClose) + state = ThemeWindowStates.ButtonHot; + theme.DrawBackground(g, part, state, m_SystemButtons.CloseButtonRect); + return; + } + + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + { + ButtonState state = ButtonState.Normal; + if (m_SystemButtons.MouseDownClose) + state = ButtonState.Pushed; + ControlPaint.DrawCaptionButton(g, m_SystemButtons.CloseButtonRect, CaptionButton.Close, state); + } + else + { + Pen pen = null; + + if (m_SystemButtons.MouseDownClose) + { + if (pa.Colors.ItemPressedBackground2.IsEmpty) + DisplayHelp.FillRectangle(g, m_SystemButtons.CloseButtonRect, pa.Colors.ItemPressedBackground); + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(m_SystemButtons.CloseButtonRect, pa.Colors.ItemPressedBackground, pa.Colors.ItemPressedBackground2, pa.Colors.ItemPressedBackgroundGradientAngle); + g.FillRectangle(gradient, m_SystemButtons.CloseButtonRect); + gradient.Dispose(); + } + using (Pen p1 = new Pen(pa.Colors.ItemPressedBorder)) + NativeFunctions.DrawRectangle(g, p1, m_SystemButtons.CloseButtonRect); + } + else if (m_SystemButtons.MouseOverClose) + { + pen = new Pen(pa.Colors.ItemHotText); //SystemPens.ControlText; + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(m_SystemButtons.CloseButtonRect, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, m_SystemButtons.CloseButtonRect); + gradient.Dispose(); + } + else + DisplayHelp.FillRectangle(g, m_SystemButtons.CloseButtonRect, pa.Colors.ItemHotBackground); + pen.Dispose(); + pen = null; + using (Pen p1 = new Pen(pa.Colors.ItemHotBorder)) + NativeFunctions.DrawRectangle(g, p1, m_SystemButtons.CloseButtonRect); + } + + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + pen = new Pen(pa.Colors.ItemText, Dpi.Width1); + else + pen = new Pen(((m_HasFocus || this.LayoutType == eLayoutType.Toolbar) ? pa.Colors.BarCaptionText : pa.Colors.BarCaptionInactiveText)); + if (m_SystemButtons.MouseOverClose) + pen = new Pen(pa.Colors.ItemHotText, Dpi.Width1); + else if (m_SystemButtons.MouseDownClose) + pen = new Pen(pa.Colors.ItemPressedText, Dpi.Width1); + else if (!m_CaptionForeColor.IsEmpty) + pen = new Pen(m_CaptionForeColor, Dpi.Width1); + else if (!m_HasFocus && m_BarState != eBarState.Floating && m_GrabHandleStyle != eGrabHandleStyle.CaptionTaskPane && m_GrabHandleStyle != eGrabHandleStyle.CaptionDotted) + pen = new Pen(pa.Colors.BarCaptionInactiveText, Dpi.Width1); + + Point[] p = new Point[2]; + Rectangle rect = m_SystemButtons.CloseButtonRect; + rect.Inflate(-1, -1); + p[0].X = rect.Left + Dpi.Width2; + p[0].Y = rect.Top + Dpi.Height3; + p[1].X = rect.Right - Dpi.Width4; + p[1].Y = rect.Bottom - Dpi.Height4; + g.DrawLine(pen, p[0], p[1]); + p[0].X++; + p[1].X++; + g.DrawLine(pen, p[0], p[1]); + + p[0].X = rect.Right - Dpi.Width3; + p[0].Y = rect.Top + Dpi.Height3; + p[1].X = rect.Left + Dpi.Width3; + p[1].Y = rect.Bottom - Dpi.Height4; + g.DrawLine(pen, p[0], p[1]); + p[0].X--; + p[1].X--; + g.DrawLine(pen, p[0], p[1]); + pen.Dispose(); + } + } + private void PaintMaximizeButton(ItemPaintArgs pa) + { + if (m_SystemButtons.MaximizeButtonRect.IsEmpty) + return; + + Graphics g = pa.Graphics; + + if (this.DrawThemedCaption) + { + ThemeWindow theme = this.ThemeWindow; + ThemeWindowParts part = ThemeWindowParts.SmallMaxCaption; + ThemeWindowStates state = ThemeWindowStates.ButtonNormal; + if (m_SystemButtons.MouseDownMaximize) + state = ThemeWindowStates.ButtonPushed; + else if (m_SystemButtons.MouseOverMaximize) + state = ThemeWindowStates.ButtonHot; + theme.DrawBackground(g, part, state, m_SystemButtons.MaximizeButtonRect); + return; + } + + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + { + ButtonState state = ButtonState.Normal; + if (m_SystemButtons.MouseDownMaximize) + state = ButtonState.Pushed; + ControlPaint.DrawCaptionButton(g, m_SystemButtons.MaximizeButtonRect, CaptionButton.Maximize, state); + } + else + { + Pen pen = null; + + if (m_SystemButtons.MouseDownMaximize) + { + if (pa.Colors.ItemPressedBackground2.IsEmpty) + DisplayHelp.FillRectangle(g, m_SystemButtons.MaximizeButtonRect, pa.Colors.ItemPressedBackground); + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(m_SystemButtons.MaximizeButtonRect, pa.Colors.ItemPressedBackground, pa.Colors.ItemPressedBackground2, pa.Colors.ItemPressedBackgroundGradientAngle); + g.FillRectangle(gradient, m_SystemButtons.CloseButtonRect); + gradient.Dispose(); + } + using (Pen p1 = new Pen(pa.Colors.ItemPressedBorder)) + NativeFunctions.DrawRectangle(g, p1, m_SystemButtons.MaximizeButtonRect); + } + else if (m_SystemButtons.MouseOverMaximize) + { + pen = new Pen(pa.Colors.ItemHotText); //SystemPens.ControlText; + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(m_SystemButtons.MaximizeButtonRect, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, m_SystemButtons.MaximizeButtonRect); + gradient.Dispose(); + } + else + DisplayHelp.FillRectangle(g, m_SystemButtons.MaximizeButtonRect, pa.Colors.ItemHotBackground); + pen.Dispose(); + pen = null; + using (Pen p1 = new Pen(pa.Colors.ItemHotBorder)) + NativeFunctions.DrawRectangle(g, p1, m_SystemButtons.MaximizeButtonRect); + } + + SolidBrush brush=null; + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + brush = new SolidBrush(pa.Colors.ItemText); + else + brush = new SolidBrush(((m_HasFocus || this.LayoutType == eLayoutType.Toolbar) ? pa.Colors.BarCaptionText : pa.Colors.BarCaptionInactiveText)); + if (m_SystemButtons.MouseOverMaximize) + brush = new SolidBrush(pa.Colors.ItemHotText); + else if (m_SystemButtons.MouseDownMaximize) + brush = new SolidBrush(pa.Colors.ItemPressedText); + else if (!m_CaptionForeColor.IsEmpty) + brush = new SolidBrush(m_CaptionForeColor); + else if (!m_HasFocus && m_BarState != eBarState.Floating && m_GrabHandleStyle != eGrabHandleStyle.CaptionTaskPane && m_GrabHandleStyle != eGrabHandleStyle.CaptionDotted) + brush = new SolidBrush(pa.Colors.BarCaptionInactiveText); + + + Rectangle rect = m_SystemButtons.MaximizeButtonRect; + rect.Inflate(-1, -1); + Region oldClip = g.Clip; + if (_IsMaximized) + { + Rectangle rMax = new Rectangle(rect.X + (rect.Width - Dpi.Width10) / 2 + Dpi.Width3, rect.Y + (rect.Height - Dpi.Height10) / 2, Dpi.Width7, Dpi.Height7); + g.SetClip(new Rectangle(rMax.X + Dpi.Width1, rMax.Y + Dpi.Height2, rMax.Width - Dpi.Width2, rMax.Height - Dpi.Height3), CombineMode.Exclude); + rMax.Offset(-Dpi.Width3, Dpi.Height3); + g.SetClip(new Rectangle(rMax.X + Dpi.Width1, rMax.Y + Dpi.Height2, rMax.Width - Dpi.Width2, rMax.Height - Dpi.Height3), CombineMode.Exclude); + rMax.Offset(Dpi.Width3, -Dpi.Height3); + g.FillRectangle(brush, rMax); + g.Clip = oldClip; + rMax.Offset(-Dpi.Width3, Dpi.Height3); + g.SetClip(new Rectangle(rMax.X + Dpi.Width1, rMax.Y + Dpi.Height2, rMax.Width - Dpi.Width2, rMax.Height - Dpi.Height3), CombineMode.Exclude); + g.FillRectangle(brush, rMax); + } + else + { + Rectangle rMax = new Rectangle(rect.X + (rect.Width - Dpi.Width9) / 2, rect.Y + (rect.Height - Dpi.Height9) / 2, Dpi.Width9, Dpi.Height9); + g.SetClip(new Rectangle(rMax.X + Dpi.Width1, rMax.Y + Dpi.Height3, rMax.Width - Dpi.Width2, rMax.Height - Dpi.Height4), CombineMode.Exclude); + g.FillRectangle(brush, rMax); + } + g.Clip = oldClip; + if (oldClip != null) oldClip.Dispose(); + brush.Dispose(); + } + } + private void PaintCaptionButton() + { + this.Invalidate(m_SystemButtons.CaptionButtonRect); + this.Update(); + } + private void PaintCaptionButton(ItemPaintArgs pa) + { + if (m_SystemButtons.CaptionButtonRect.IsEmpty) + return; + + Rectangle rect = m_SystemButtons.CaptionButtonRect; + Graphics g = pa.Graphics; + + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + { + ButtonState state = ButtonState.Normal; + if (m_SystemButtons.MouseDownCaption) + state = ButtonState.Pushed; + ControlPaint.DrawButton(g, rect, state); + } + else + { + if (m_CaptionMenu != null && m_CaptionMenu.Expanded) + { + if (pa.Colors.ItemExpandedBackground2.IsEmpty) + DisplayHelp.FillRectangle(g, rect, pa.Colors.ItemExpandedBackground); + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(rect, pa.Colors.ItemExpandedBackground, pa.Colors.ItemExpandedBackground2, pa.Colors.ItemExpandedBackgroundGradientAngle); + g.FillRectangle(gradient, rect); + gradient.Dispose(); + } + using (Pen p1 = new Pen(pa.Colors.ItemExpandedBorder)) + NativeFunctions.DrawRectangle(g, p1, rect); + } + else if (m_SystemButtons.MouseDownCaption) + { + if (pa.Colors.ItemPressedBackground2.IsEmpty) + DisplayHelp.FillRectangle(g, rect, pa.Colors.ItemPressedBackground); + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(rect, pa.Colors.ItemPressedBackground, pa.Colors.ItemPressedBackground2, pa.Colors.ItemPressedBackgroundGradientAngle); + g.FillRectangle(gradient, rect); + gradient.Dispose(); + } + using (Pen p1 = new Pen(pa.Colors.ItemPressedBorder)) + NativeFunctions.DrawRectangle(g, p1, rect); + } + else if (m_SystemButtons.MouseOverCaption) + { + Pen pen = new Pen(pa.Colors.ItemHotText); + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(rect, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, rect); + gradient.Dispose(); + } + else + DisplayHelp.FillRectangle(g, rect, pa.Colors.ItemHotBackground); + using (Pen p1 = new Pen(pa.Colors.ItemHotBorder)) + NativeFunctions.DrawRectangle(g, p1, rect); + } + } + SolidBrush brush = null; + Color textColor = pa.Colors.ItemText; + + if (m_SystemButtons.MouseOverCaption) + textColor = pa.Colors.ItemHotText; + else if (m_SystemButtons.MouseDownCaption) + textColor = pa.Colors.ItemPressedText; + else if (!m_CaptionForeColor.IsEmpty) + textColor = m_CaptionForeColor; + else + textColor = pa.Colors.ItemText; + brush = new SolidBrush(textColor); + eTextFormat format = eTextFormat.Default | eTextFormat.VerticalCenter | eTextFormat.EndEllipsis | eTextFormat.SingleLine; + Rectangle rText = rect; + rText.Width -= Dpi.Width12; + rText.X += Dpi.Width3; + if (rText.Width > Dpi.Width8) + TextDrawing.DrawString(g, this.Text, this.Font, textColor, rText, format); + + Point[] p = new Point[3]; + p[0].X = rect.Right - Dpi.Width9; + p[0].Y = rect.Top + (rect.Height + Dpi.Height6) / 2; + p[1].X = p[0].X - Dpi.Width4; + p[1].Y = p[0].Y - Dpi.Height5; + p[2].X = p[1].X + Dpi.Width9; + p[2].Y = p[1].Y; + g.FillPolygon(brush, p); + + brush.Dispose(); + } + private void PaintCustomizeButton() + { + this.Invalidate(m_SystemButtons.CustomizeButtonRect); + this.Update(); + } + private void PaintCustomizeButton(ItemPaintArgs pa) + { + if (m_SystemButtons.CustomizeButtonRect.IsEmpty) + return; + Graphics g = pa.Graphics; + Brush brush = new SolidBrush(((m_HasFocus || this.LayoutType == eLayoutType.Toolbar) ? pa.Colors.BarCaptionText : pa.Colors.BarCaptionInactiveText)); + + if (!this.DrawThemedCaption) + { + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + { + Point[] p1 = new Point[3]; + p1[0].X = m_SystemButtons.CustomizeButtonRect.X + Dpi.Width4; + p1[0].Y = m_SystemButtons.CustomizeButtonRect.Y + Dpi.Height8; + p1[1].X = p1[0].X - Dpi.Width3; + p1[1].Y = p1[0].Y - Dpi.Height4; + p1[2].X = p1[1].X + Dpi.Width7; + p1[2].Y = p1[1].Y; + g.FillPolygon(SystemBrushes.ActiveCaptionText, p1); + brush.Dispose(); + return; + } + else + { + if (!m_CaptionForeColor.IsEmpty) + { + brush.Dispose(); + brush = new SolidBrush(m_CaptionForeColor); + } + if (!m_HasFocus && m_BarState != eBarState.Floating) + { + brush.Dispose(); + brush = new SolidBrush(pa.Colors.BarCaptionInactiveText); + } + + if (m_SystemButtons.MouseDownCustomize) + { + if (pa.Colors.ItemPressedBackground2.IsEmpty) + { + using (SolidBrush b = new SolidBrush(pa.Colors.ItemPressedBackground)) + g.FillRectangle(b, m_SystemButtons.CustomizeButtonRect); + } + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(m_SystemButtons.CustomizeButtonRect, pa.Colors.ItemPressedBackground, pa.Colors.ItemPressedBackground2, pa.Colors.ItemPressedBackgroundGradientAngle); + g.FillRectangle(gradient, m_SystemButtons.CustomizeButtonRect); + gradient.Dispose(); + } + using (Pen p1 = new Pen(pa.Colors.ItemPressedBorder)) + NativeFunctions.DrawRectangle(g, p1, m_SystemButtons.CustomizeButtonRect); + } + else if (m_SystemButtons.MouseOverCustomize) + { + brush.Dispose(); + brush = new SolidBrush(pa.Colors.BarCaptionText); // SystemBrushes.ControlText; + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(m_SystemButtons.CustomizeButtonRect, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, m_SystemButtons.CustomizeButtonRect); + gradient.Dispose(); + } + else + { + using (SolidBrush b = new SolidBrush(pa.Colors.ItemHotBackground)) + g.FillRectangle(b, m_SystemButtons.CustomizeButtonRect); + } + using (Pen p1 = new Pen(pa.Colors.ItemHotBorder, Dpi.Width1)) + NativeFunctions.DrawRectangle(g, p1, m_SystemButtons.CustomizeButtonRect); + } + } + } + + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + { + brush.Dispose(); + brush = new SolidBrush(pa.Colors.ItemText); + } + else + { + brush.Dispose(); + brush = new SolidBrush(((m_HasFocus || this.LayoutType == eLayoutType.Toolbar) ? pa.Colors.BarCaptionText : pa.Colors.BarCaptionInactiveText)); + } + if (m_SystemButtons.MouseOverCustomize) + { + brush.Dispose(); + brush = new SolidBrush(pa.Colors.ItemHotText); + } + else if (m_SystemButtons.MouseDownCustomize) + { + brush.Dispose(); + brush = new SolidBrush(pa.Colors.ItemPressedText); + } + else if (!m_CaptionForeColor.IsEmpty) + { + brush.Dispose(); + brush = new SolidBrush(m_CaptionForeColor); + } + else if (!m_HasFocus && m_BarState != eBarState.Floating && m_GrabHandleStyle != eGrabHandleStyle.CaptionTaskPane && m_GrabHandleStyle != eGrabHandleStyle.CaptionDotted) + { + brush.Dispose(); + brush = new SolidBrush(pa.Colors.BarCaptionInactiveText); + } + + Point[] p = new Point[3]; + p[0].X = m_SystemButtons.CustomizeButtonRect.Right - Dpi.Width7; + p[0].Y = m_SystemButtons.CustomizeButtonRect.Top + Dpi.Height8; + p[1].X = p[0].X - Dpi.Width3; + p[1].Y = p[0].Y - Dpi.Height4; + p[2].X = p[1].X + Dpi.Width7; + p[2].Y = p[1].Y; + g.FillPolygon(brush, p); + brush.Dispose(); + } + private void PaintAutoHideButton() + { + if (!m_SystemButtons.AutoHideButtonRect.IsEmpty) + { + Rectangle r = m_SystemButtons.AutoHideButtonRect; + r.Inflate(1, 1); + this.Invalidate(r); + this.Update(); + } + } + private void PaintAutoHideButton(ItemPaintArgs pa) + { + if (m_SystemButtons.AutoHideButtonRect.IsEmpty) + return; + + Graphics g = pa.Graphics; + + if (this.DrawThemedCaption) + { + Image img = null; + if (m_SystemButtons.MouseDownAutoHide && !this.AutoHide || this.AutoHide && !m_SystemButtons.MouseDownAutoHide) + { + if (m_SystemButtons.MouseOverAutoHide) + img = BarFunctions.LoadBitmap("SystemImages.Pin.png"); + else + img = BarFunctions.LoadBitmap("SystemImages.PinInactive.png"); + g.DrawImage(img, m_SystemButtons.AutoHideButtonRect.X + (m_SystemButtons.AutoHideButtonRect.Width - img.Width) / 2, m_SystemButtons.AutoHideButtonRect.Y + (m_SystemButtons.AutoHideButtonRect.Height - img.Height) / 2, img.Width, img.Height); + } + else + { + if (m_SystemButtons.MouseOverAutoHide) + img = BarFunctions.LoadBitmap("SystemImages.PinPushed.png"); + else + img = BarFunctions.LoadBitmap("SystemImages.PinPushedInactive.png"); + g.DrawImage(img, m_SystemButtons.AutoHideButtonRect.X + (m_SystemButtons.AutoHideButtonRect.Width - img.Width) / 2, m_SystemButtons.AutoHideButtonRect.Y + (m_SystemButtons.AutoHideButtonRect.Height - img.Height) / 2, img.Width, img.Height); + } + return; + } + + + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + { + Rectangle r = m_SystemButtons.AutoHideButtonRect; + r.Inflate(1, 0); + if (m_SystemButtons.MouseDownAutoHide) + { + ControlPaint.DrawBorder3D(g, r, Border3DStyle.SunkenInner, Border3DSide.All); + } + else + { + ControlPaint.DrawBorder3D(g, r, Border3DStyle.Raised, Border3DSide.All); + } + } + else + { + if (m_SystemButtons.MouseDownAutoHide) + { + if (pa.Colors.ItemPressedBackground2.IsEmpty) + DisplayHelp.FillRectangle(g, m_SystemButtons.AutoHideButtonRect, pa.Colors.ItemPressedBackground); + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(m_SystemButtons.AutoHideButtonRect, pa.Colors.ItemPressedBackground, pa.Colors.ItemPressedBackground2, pa.Colors.ItemPressedBackgroundGradientAngle); + g.FillRectangle(gradient, m_SystemButtons.AutoHideButtonRect); + gradient.Dispose(); + } + using (Pen p1 = new Pen(pa.Colors.ItemPressedBorder)) + NativeFunctions.DrawRectangle(g, p1, m_SystemButtons.AutoHideButtonRect); + } + else if (m_SystemButtons.MouseOverAutoHide) + { + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(m_SystemButtons.AutoHideButtonRect, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, m_SystemButtons.AutoHideButtonRect); + gradient.Dispose(); + } + else + DisplayHelp.FillRectangle(g, m_SystemButtons.AutoHideButtonRect, pa.Colors.ItemHotBackground); + using (Pen p1 = new Pen(pa.Colors.ItemHotBorder)) + NativeFunctions.DrawRectangle(g, p1, m_SystemButtons.AutoHideButtonRect); + } + } + if (m_SystemButtons.MouseDownAutoHide && !this.AutoHide || this.AutoHide && !m_SystemButtons.MouseDownAutoHide) + { + Rectangle r = new Rectangle(m_SystemButtons.AutoHideButtonRect.X + (m_SystemButtons.AutoHideButtonRect.Width - Dpi.Width10) / 2, m_SystemButtons.AutoHideButtonRect.Y + (m_SystemButtons.AutoHideButtonRect.Height - Dpi.Height7) / 2, Dpi.Width10, Dpi.Height7); + + Pen pen = null; + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + pen = new Pen(pa.Colors.ItemText, Dpi.Width1); + else + pen = new Pen(((m_HasFocus || this.LayoutType == eLayoutType.Toolbar) ? pa.Colors.BarCaptionText : pa.Colors.BarCaptionInactiveText)); + if (m_SystemButtons.MouseOverAutoHide) + pen = new Pen(pa.Colors.ItemHotText, Dpi.Width1); + else if (m_SystemButtons.MouseDownAutoHide) + pen = new Pen(pa.Colors.ItemPressedText, Dpi.Width1); + else if (!m_CaptionForeColor.IsEmpty) + pen = new Pen(m_CaptionForeColor, Dpi.Width1); + else if (!m_HasFocus && m_BarState != eBarState.Floating && m_GrabHandleStyle != eGrabHandleStyle.CaptionTaskPane && m_GrabHandleStyle != eGrabHandleStyle.CaptionDotted) + pen = new Pen(pa.Colors.BarCaptionInactiveText, Dpi.Width1); + + g.DrawRectangle(pen, r.X + Dpi.Width4, r.Y + Dpi.Height1, Dpi.Width5, Dpi.Height4); + g.DrawLine(pen, r.X + Dpi.Width4, r.Y + Dpi.Height4, r.X + Dpi.Width9, r.Y + Dpi.Height4); + g.DrawLine(pen, r.X + Dpi.Width4, r.Y, r.X + Dpi.Width4, r.Y + Dpi.Height6); + g.DrawLine(pen, r.X, r.Y + Dpi.Height3, r.X + Dpi.Width3, r.Y + Dpi.Height3); + } + else + { + Rectangle r = new Rectangle(m_SystemButtons.AutoHideButtonRect.X + (m_SystemButtons.AutoHideButtonRect.Width - Dpi.Width7) / 2, m_SystemButtons.AutoHideButtonRect.Y + (m_SystemButtons.AutoHideButtonRect.Height - Dpi.Height9) / 2, Dpi.Width7, Dpi.Height9); + + Pen pen = null; + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + pen = new Pen(pa.Colors.ItemText, Dpi.Width1); + else + pen = new Pen(((m_HasFocus || this.LayoutType == eLayoutType.Toolbar) ? pa.Colors.BarCaptionText : pa.Colors.BarCaptionInactiveText), Dpi.Width1); + if (m_SystemButtons.MouseOverAutoHide) + pen = new Pen(pa.Colors.ItemHotText, Dpi.Width1); + else if (m_SystemButtons.MouseDownAutoHide) + pen = new Pen(pa.Colors.ItemPressedText, Dpi.Width1); + else if (!m_CaptionForeColor.IsEmpty) + pen = new Pen(m_CaptionForeColor, Dpi.Width1); + else if (!m_HasFocus && m_BarState != eBarState.Floating && m_GrabHandleStyle != eGrabHandleStyle.CaptionTaskPane && m_GrabHandleStyle != eGrabHandleStyle.CaptionDotted) + pen = new Pen(pa.Colors.BarCaptionInactiveText, Dpi.Width1); + + g.DrawRectangle(pen, r.X + Dpi.Width1, r.Y, Dpi.Width4, Dpi.Height5); + g.DrawLine(pen, r.X + Dpi.Width4, r.Y, r.X + Dpi.Width4, r.Y + Dpi.Height5); + g.DrawLine(pen, r.X, r.Y + Dpi.Height5, r.X + Dpi.Width6, r.Y + Dpi.Height5); + g.DrawLine(pen, r.X + Dpi.Width3, r.Y + Dpi.Height5, r.X + Dpi.Width3, r.Y + Dpi.Height8); + } + } + + /// + /// Paints bar side bar. + /// + /// Reference to graphics object. + internal void PaintSideBar(Graphics g) + { + if (m_SideBarImage.Picture == null || m_BarState != eBarState.Popup) + return; + + if (!m_SideBarImage.GradientColor1.IsEmpty && !m_SideBarImage.GradientColor2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush lgb = BarFunctions.CreateLinearGradientBrush(m_SideBarRect, m_SideBarImage.GradientColor1, m_SideBarImage.GradientColor2, m_SideBarImage.GradientAngle); + g.FillRectangle(lgb, m_SideBarRect); + } + else if (!m_SideBarImage.BackColor.Equals(Color.Empty)) + DisplayHelp.FillRectangle(g, m_SideBarRect, m_SideBarImage.BackColor); + + if (m_SideBarImage.StretchPicture) + { + g.DrawImage(m_SideBarImage.Picture, m_SideBarRect); + } + else + { + if (m_SideBarImage.Alignment == eAlignment.Top) + g.DrawImage(m_SideBarImage.Picture, m_SideBarRect.X, m_SideBarRect.Top, m_SideBarRect.Width, m_SideBarImage.Picture.Height); + else if (m_SideBarImage.Alignment == eAlignment.Bottom) + g.DrawImage(m_SideBarImage.Picture, m_SideBarRect.Left, m_SideBarRect.Bottom - m_SideBarImage.Picture.Height, m_SideBarImage.Picture.Width, m_SideBarImage.Picture.Height); + else + g.DrawImage(m_SideBarImage.Picture, m_SideBarRect.Left, m_SideBarRect.Top + (m_SideBarRect.Height - m_SideBarImage.Picture.Height) / 2, m_SideBarImage.Picture.Width, m_SideBarImage.Picture.Height); + } + } + + internal BaseItem ParentInternal + { + get + { + return m_ParentItem; + } + } + + /// + /// Gets/Sets the parent item of the Bar. The parents item sub-items are displayed on the bar. + /// + [System.ComponentModel.Browsable(false)] + public BaseItem ParentItem + { + get + { + if (m_ParentItem != null) + return m_ParentItem; + return m_ItemContainer; + } + set + { + RestoreContainer(); + + if (m_ItemContainer.SubItems.Count > 0) + m_ItemContainer.SubItems.Clear(); + + m_ParentItem = value; + + if (m_ParentItem == null || m_ParentItem.SubItems.Count == 0) + return; + + m_ItemContainer.Style = m_ParentItem.Style; + + BaseItem objTmp = m_ParentItem.SubItems[0]; + if (objTmp != null) + m_OldContainer = objTmp.ContainerControl; + else + m_OldContainer = null; + + m_ItemContainer.SubItems.AllowParentRemove = false; + foreach (BaseItem objItem in m_ParentItem.SubItems) + { + objItem.ContainerControl = this; + m_ItemContainer.SubItems.Add(objItem); + } + m_ItemContainer.SubItems.AllowParentRemove = true; + + // Get the parent's screen position + if (m_ParentItem.Displayed) + { + System.Windows.Forms.Control objCtrl = m_ParentItem.ContainerControl as System.Windows.Forms.Control; + if (BaseItem.IsHandleValid(objCtrl)) + { + m_ParentItemScreenPos = objCtrl.PointToScreen(new Point(m_ParentItem.LeftInternal, m_ParentItem.TopInternal)); + objCtrl = null; + } + } + } + } + + private void SetupRegion() + { + if (m_BarState != eBarState.Popup) + return; + + Rectangle r = new Rectangle(0, 0, this.Width, this.Height); + System.Drawing.Region rgn = new System.Drawing.Region(r); + r.X = this.Width - 2; + r.Y = 0; + r.Width = 2; + r.Height = 2; + rgn.Xor(r); + r.X = 0; + r.Y = this.Height - 2; + r.Width = 2; + r.Height = 2; + rgn.Xor(r); + this.Region = rgn; + } + + private void SetRoundRegion(Control c) + { + Rectangle rectPath = c.ClientRectangle; + rectPath.Width--; + rectPath.Height--; + GraphicsPath path = DisplayHelp.GetRoundedRectanglePath(rectPath, m_CornerSize); + Region r = new Region(); + r.MakeEmpty(); + r.Union(path); + // Widen path for the border... + path.Widen(SystemPens.ControlText); + r.Union(path); + c.Region = r; + } + + /// + /// Recalculates the layout of the Bar, resizes the Bar if necessary and repaints it. + /// + public void RecalcLayout() + { + if (m_LayoutSuspended || IsDisposing) return; + + if (m_BarState == eBarState.Docked) + { + if (this.Parent != null && !PassiveBar) + { + if (m_ItemContainer.LayoutType != eLayoutType.DockContainer) + this.Invalidate(this.Region, true); + + if (this.Parent is DockSite) + ((DockSite)this.Parent).RecalcLayout(); + else + { + RecalcSize(); + this.Refresh(); + } + ResizeDockTab(); + } + } + else + { + RecalcSize(); + ResizeDockTab(); + this.Refresh(); + } + } + + internal void OnDockContainerWidthChanged(DockContainerItem item, int width) + { + if (m_LayoutSuspended) + return; + + if (this.DockSide == eDockSide.Document || this.Parent is DockSite && ((DockSite)this.Parent).DocumentDockContainer != null) + { + ((DockSite)this.DockedSite).GetDocumentUIManager().SetBarWidth(this, width + 2); + } + else if (m_BarState == eBarState.AutoHide) + { + m_ItemContainer.MinWidth = width; + m_LastDockSiteInfo.DockedWidth = width + 2; + } + //else + //{ + // m_ItemContainer.MinWidth=width+2; + // if(this.AutoHide) + // m_LastDockSiteInfo.DockedWidth=width+2; + + // ChangeSplitSize(new Size(width+2,0)); + + // this.RecalcLayout(); + //} + } + + internal void OnDockContainerHeightChanged(DockContainerItem item, int height) + { + if (m_LayoutSuspended) + return; + + if (this.DockSide == eDockSide.Document || this.Parent is DockSite && ((DockSite)this.Parent).DocumentDockContainer != null) + { + ((DockSite)this.DockedSite).GetDocumentUIManager().SetBarHeight(this, height + this.GetNonClientHeight()); + } + else if (m_BarState == eBarState.AutoHide) + { + m_ItemContainer.MinHeight = height; + m_LastDockSiteInfo.DockedHeight = height + 2; + } + //else + //{ + // m_ItemContainer.MinHeight=height+2; + // if(this.AutoHide) + // m_LastDockSiteInfo.DockedHeight=height+2; + + // ChangeSplitSize(new Size(0,height+this.GetNonClientHeight())); // Accounts for caption size and border + + // this.RecalcLayout(); + //} + } + + internal void OnDockContainerMinimumSizeChanged(DockContainerItem item) + { + if (this.AutoHide) + { + m_LastDockSiteInfo.DockedHeight = 0; + m_LastDockSiteInfo.DockedWidth = 0; + } + } + + private void ChangeSplitSize(System.Drawing.Size size) + { + // Support for resizing of the side-by-side docked bars i.e. on the same line + if (this.Parent != null && this.Parent.Controls.Count > 1) + { + Bar barLeft = null, barRight = null; + + Bar previous = this.GetPreviousVisibleBar(this); + Bar next = this.GetNextVisibleBar(this); + if (next != null && next.LayoutType == eLayoutType.DockContainer && next.DockLine == this.DockLine) + { + barLeft = this; + barRight = next; + } + else if (previous != null && previous.LayoutType == eLayoutType.DockContainer && previous.DockLine == this.DockLine) + { + barLeft = previous; + barRight = this; + if (size.Width > 0) + size.Width = barLeft.Width + (barRight.Width - size.Width); + if (size.Height > 0) + size.Height = barLeft.Height + (barRight.Height - size.Height); + } + + if (this.DockSide == eDockSide.Left || this.DockSide == eDockSide.Right) + { + if (barLeft != null && barRight != null && barLeft.DockLine == barRight.DockLine) + { + System.Drawing.Size minLeftSize = barLeft.MinimumDockSize(eOrientation.Horizontal); + System.Drawing.Size minThisSize = barRight.MinimumDockSize(eOrientation.Horizontal); + int heightOffset = size.Height - barLeft.Height; + if (size.Height >= minLeftSize.Height && barRight.Height - heightOffset >= minThisSize.Height) + { + Size oldLeftBarSize = barLeft.Size; + Size oldSize = barRight.Size; + Size newBarLeftSize = barLeft.RecalcSizeOnly(new Size(barLeft.Width, size.Height)); + Size newSize = barRight.RecalcSizeOnly(new Size(barRight.Width, barRight.Height - heightOffset)); + if (!oldLeftBarSize.Equals(newBarLeftSize) && !oldSize.Equals(newSize)) + { + barRight.SplitDockHeight = 0; + barLeft.SplitDockHeight = size.Height; + } + } + } + else + { + this.SplitDockHeight = 0; + this.SplitDockWidth = 0; + } + } + else if (this.DockSide == eDockSide.Top || this.DockSide == eDockSide.Bottom) + { + if (barLeft != null && barRight != null && barLeft.DockLine == barRight.DockLine) + { + System.Drawing.Size minLeftSize = barLeft.MinimumDockSize(eOrientation.Horizontal); + System.Drawing.Size minThisSize = barRight.MinimumDockSize(eOrientation.Horizontal); + int widthOffset = size.Width - barLeft.Width; + if (size.Width >= minLeftSize.Width && barRight.Width - widthOffset >= minThisSize.Width) + { + Size oldLeftBarSize = barLeft.Size; + Size oldSize = barRight.Size; + Size newBarLeftSize = barLeft.RecalcSizeOnly(new Size(size.Width, barLeft.Height)); + Size newSize = barRight.RecalcSizeOnly(new Size(barRight.Width - widthOffset, barRight.Height)); + if (!oldLeftBarSize.Equals(newBarLeftSize) && !oldSize.Equals(newSize)) + { + barRight.SplitDockWidth = 0; + barLeft.SplitDockWidth = size.Width; + } + } + } + else + { + this.SplitDockHeight = 0; + this.SplitDockWidth = 0; + } + } + } + } + + internal int SplitDockHeight + { + get + { + if (this.Parent != null && m_SplitDockHeightPercent > 0) + { + int height = ((this.Parent.Height * m_SplitDockHeightPercent) / 1000); + Size sz = GetAdjustedFullSize(this.MinimumDockSize(eOrientation.Horizontal)); + if (height < sz.Height) + height = sz.Height; + return height; + } + return 0; + } + set + { + if (this.Parent != null && value > 0) + { + if (value > this.Parent.Height) + value = this.Parent.Height; + m_SplitDockHeightPercent = (int)(((float)value / (float)this.Parent.Height) * 1000); + } + else + m_SplitDockHeightPercent = 0; + } + } + internal int SplitDockWidth + { + get + { + if (this.Parent != null && m_SplitDockWidthPercent > 0) + { + return ((this.Parent.Width * m_SplitDockWidthPercent) / 1000); + } + return 0; + } + set + { + if (this.Parent != null && value > 0) + { + if (value > this.Parent.Width) + value = this.Parent.Width; + m_SplitDockWidthPercent = (int)(((float)value / (float)this.Parent.Width) * 1000); + } + else + m_SplitDockWidthPercent = 0; + } + } + + internal int MinHeight + { + get + { + if (m_ItemContainer.MinHeight > 0) + return m_ItemContainer.MinHeight + GetNonClientHeight(); + return 0; + } + set + { + if (m_ItemContainer == null) return; + if (value > 0) + m_ItemContainer.MinHeight = value - GetNonClientHeight(); + else + m_ItemContainer.MinHeight = 0; + } + } + internal int GetNonClientHeight() + { + return GetGrabHandleCaptionHeight() + 2; // Caption + border + } + + private bool m_RecalculatingSize = false; // Used to preven re-entrancy + /// + /// Recalculates the layout of the Bar and repaints it. This will not change the size of the Bar it will only force the recalculation of the size for each contained item and it will repaint the bar. To ensure that Bar is resized if necessary as well call RecalcLayout method. + /// + public void RecalcSize() + { + if (!BarFunctions.IsHandleValid(this)) + return; + + m_GrabHandleRect = Rectangle.Empty; + if (m_RecalculatingSize || m_ItemContainer == null) + return; + Form form = this.FindForm(); + if (form != null && form.WindowState == FormWindowState.Minimized) + return; + + m_RecalculatingSize = true; + + if (this.LayoutType == eLayoutType.DockContainer && m_TabDockItems == null) + RefreshDockTab(false); + + try + { + //m_ItemContainer.IsRightToLeft = (this.RightToLeft == RightToLeft.Yes); + if (m_BarState == eBarState.Docked) + { + m_ItemContainer.WrapItems = m_WrapItemsDock; + m_ItemContainer.Stretch = m_DockStretch; + } + else if (m_BarState == eBarState.Floating || m_BarState == eBarState.AutoHide) + { + m_ItemContainer.WrapItems = m_WrapItemsFloat; + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer) + m_ItemContainer.Stretch = m_DockStretch; + else + m_ItemContainer.Stretch = false; + } + else + { + m_ItemContainer.WrapItems = true; + m_ItemContainer.Stretch = false; + } + + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + { + if (m_BarState == eBarState.Docked && !(this.Parent is DockSite)) + { + System.Drawing.Size size = RecalcSizeOffice(); + if (m_ItemContainer.Orientation == eOrientation.Horizontal) + this.Height = size.Height; + else + this.Width = size.Width; + } + else + this.ClientSize = RecalcSizeOffice(); + } + else + { + if (m_BarState == eBarState.Docked && !(this.Parent is DockSite)) + { + System.Drawing.Size size = RecalcSizeDotNet(); + if (m_ItemContainer.Orientation == eOrientation.Horizontal) + this.Height = size.Height; + else + this.Width = size.Width; + } + else + this.ClientSize = RecalcSizeDotNet(); + } + + if (m_DropShadow != null) + NativeFunctions.SetWindowPos(m_DropShadow.Handle, new IntPtr(NativeFunctions.HWND_NOTOPMOST), this.Left + 5, this.Top + 5, this.Width - 2, this.Height - 2, NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); + + if (m_BarState == eBarState.Docked) + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal) + m_DockedSizeH = this.Size; + else + m_DockedSizeV = this.Size; + RefreshOffice2003Region(); + } + else if (this.Region != null) + this.Region = null; + if (m_BarState == eBarState.Floating && !PassiveBar) + { + m_Float.RefreshRegion(this.ClientSize); + m_Float.ClientSize = this.ClientSize; + } + } + finally + { + m_RecalculatingSize = false; + } + + if (this.LayoutType == eLayoutType.DockContainer && m_TabDockItems != null && this.DesignMode && this.Site != null) + RefreshDockTab(false); + + OnItemLayoutUpdated(EventArgs.Empty); + } + + /// + /// Occurs after internal item layout has been updated and items have valid bounds assigned. + /// + public event EventHandler ItemLayoutUpdated; + /// + /// Raises ItemLayoutUpdated event. + /// + /// Provides event arguments. + protected virtual void OnItemLayoutUpdated(EventArgs e) + { + EventHandler handler = ItemLayoutUpdated; + if (handler != null) + handler(this, e); + } + + private void RefreshOffice2003Region() + { + if (m_RoundCorners && IsGradientStyle && !this.MenuBar && this.LayoutType == eLayoutType.Toolbar && this.BarType == eBarType.Toolbar && !this.IsThemed && this.GrabHandleStyle != eGrabHandleStyle.ResizeHandle && this.BackColor != Color.Transparent) + { + System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); + path.AddLine(0, 2, 2, 0); + path.AddLine(2, 0, this.Width - 2, 0); + path.AddLine(this.Width, 2, this.Width, this.Height - 3); + path.AddLine(this.Width - 3, this.Height, 3, this.Height); + path.AddLine(2, this.Height, 0, this.Height - 3); + this.Region = new Region(path); + } + else if (this.Region != null) + this.Region = null; + } + + internal void RecalcSize(System.Drawing.Size frameSize) + { + m_GrabHandleRect = Rectangle.Empty; + if (m_RecalculatingSize || m_ItemContainer == null) + return; + m_RecalculatingSize = true; + + try + //if(m_ItemContainer.SubItemsCount>0) + { + if (m_BarState == eBarState.Docked) + { + m_ItemContainer.WrapItems = m_WrapItemsDock; + m_ItemContainer.Stretch = m_DockStretch; + } + else if (m_BarState == eBarState.Floating || m_BarState == eBarState.AutoHide) + { + m_ItemContainer.WrapItems = m_WrapItemsFloat; + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer) + m_ItemContainer.Stretch = m_DockStretch; + else + m_ItemContainer.Stretch = false; + } + else + { + m_ItemContainer.WrapItems = true; + m_ItemContainer.Stretch = false; + } + + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + this.ClientSize = RecalcSizeOffice(false, frameSize, m_ItemContainer.Orientation, m_BarState, m_ItemContainer.WrapItems); + else + { + this.ClientSize = RecalcSizeDotNet(false, frameSize, m_ItemContainer.Orientation, m_BarState, m_ItemContainer.WrapItems); + } + + if (m_DropShadow != null) + NativeFunctions.SetWindowPos(m_DropShadow.Handle, new IntPtr(NativeFunctions.HWND_NOTOPMOST), this.Left + 5, this.Top + 5, this.Width - 2, this.Height - 2, NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); + + if (m_BarState == eBarState.Docked) + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal) + m_DockedSizeH = this.Size; + else + m_DockedSizeV = this.Size; + RefreshOffice2003Region(); + } + if (m_BarState == eBarState.Floating && !PassiveBar) + { + m_Float.RefreshRegion(this.ClientSize); + m_Float.ClientSize = this.ClientSize; + } + } + finally + { + m_RecalculatingSize = false; + } + } + + private System.Drawing.Size RecalcSizeOnly(System.Drawing.Size objFrameSize) + { + return RecalcSizeOnly(objFrameSize, m_ItemContainer.Orientation, m_BarState, m_ItemContainer.WrapItems); + } + private System.Drawing.Size RecalcSizeOnly(System.Drawing.Size objFrameSize, eOrientation barOrientation, eBarState barState, bool bWrapItems) + { + if (m_ItemContainer.SubItems.Count > 0) + { + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + return RecalcSizeOffice(true, objFrameSize, barOrientation, barState, bWrapItems); + else + return RecalcSizeDotNet(true, objFrameSize, barOrientation, barState, bWrapItems); + } + return System.Drawing.Size.Empty; + } + + private System.Drawing.Size RecalcSizeDotNet() + { + return RecalcSizeDotNet(false, this.Size, m_ItemContainer.Orientation, this.m_BarState, m_ItemContainer.WrapItems); + } + private System.Drawing.Size RecalcSizeDotNet(bool bCalculateOnly, System.Drawing.Size objFrameSize, eOrientation barOrientation, eBarState barState, bool bWrapItems) + { + System.Drawing.Size thisSize = System.Drawing.Size.Empty; + int iTopMargin = 0, iBottomMargin = 0, iLeftMargin = 0, iRightMargin = 0, iRightTabMargin = 0; + int iOrgWidth = 0, iOrgHeight = 0; + eOrientation oldOrientation = m_ItemContainer.Orientation; + eBarState thisBarState = m_BarState; + bool bOldStretch = m_ItemContainer.Stretch; + bool bOldWrapItems = m_ItemContainer.WrapItems; + m_ItemContainer.IsRightToLeft = (this.RightToLeft == RightToLeft.Yes); + if (bCalculateOnly) + { + m_ItemContainer.Orientation = barOrientation; + thisBarState = barState; + m_ItemContainer.WrapItems = bWrapItems; + if (barState == eBarState.Docked) + m_ItemContainer.Stretch = m_DockStretch; + else + { + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer) + m_ItemContainer.Stretch = m_DockStretch; + else + m_ItemContainer.Stretch = false; + } + } + + if (thisBarState == eBarState.Docked) + { + if (m_DockedBorder != eBorderType.None) + { + iTopMargin = Dpi.Height3; + iBottomMargin = Dpi.Height3; + iLeftMargin = Dpi.Width3; + iRightMargin = Dpi.Width3; + } + } + else if (thisBarState == eBarState.Floating) + { + if (this.IsThemed || this.DrawThemedCaption) + { + if (m_ThemeWindowMargins.IsEmpty) + this.RefreshThemeMargins(); + iTopMargin = m_ThemeWindowMargins.Top; + iLeftMargin = m_ThemeWindowMargins.Left; + iRightMargin = m_ThemeWindowMargins.Right; + iBottomMargin = m_ThemeWindowMargins.Bottom; + if (this.GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane) + iTopMargin = GetGrabHandleTaskPaneHeight() + m_ThemeWindowMargins.Bottom; + } + else + { + if (this.GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane) + iTopMargin = GetGrabHandleTaskPaneHeight() + Dpi.Height4; + else + iTopMargin = GetNonClientHeight(); + iLeftMargin = Dpi.Width2; + iRightMargin = Dpi.Width2; + iBottomMargin = Dpi.Height3; + } + } + else + { + iTopMargin = this.ClientMarginTop; + iLeftMargin = this.ClientMarginLeft; + iRightMargin = this.ClientMarginRight; + iBottomMargin = this.ClientMarginBottom; + } + + int iTop = iTopMargin, iLeft = iLeftMargin; + + if (BarType == eBarType.StatusBar && BarFunctions.IsOffice2007Style(m_ItemContainer.EffectiveStyle)) + iTop += Dpi.Height2; + + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && !m_AutoHideState && GetDockTabVisible()) + { + if (m_ItemContainer.VisibleSubItems > 1 || m_AlwaysDisplayDockTab && m_ItemContainer.VisibleSubItems == 1 && m_BarState != eBarState.Floating) + { + int dockTabStripHeight = Dpi.Height(DockTabStripHeight); + switch (m_DockTabAlignment) + { + case eTabStripAlignment.Top: + { + iTop += dockTabStripHeight; + break; + } + case eTabStripAlignment.Left: + { + iLeft += dockTabStripHeight; + break; + } + case eTabStripAlignment.Right: + { + iRightTabMargin = dockTabStripHeight; + break; + } + default: + { + iBottomMargin += dockTabStripHeight; + break; + } + } + } + } + + // Take in account the side bar picture + if (thisBarState == eBarState.Popup && m_SideBarImage.Picture != null) + iLeft += m_SideBarImage.Picture.Width; + else if (thisBarState == eBarState.Docked || this.BarState == eBarState.AutoHide) + { + // Show grab handles if any selected + if (m_GrabHandleStyle != eGrabHandleStyle.None) + { + if (m_GrabHandleStyle == eGrabHandleStyle.ResizeHandle) + { + // Leave space for the window sizer at the right + if (this.RightToLeft == RightToLeft.Yes) + iLeft += GrabHandleResizeWidth; + else + iRightMargin += GrabHandleResizeWidth; + } + else + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType == eLayoutType.Toolbar) + { + + if (m_GrabHandleStyle == eGrabHandleStyle.Caption) + iLeft += GetGrabHandleCaptionHeight(); + else + { + if (this.RightToLeft == RightToLeft.Yes) + iRightMargin += GrabHandleDotNetWidth; + else + iLeft += GrabHandleDotNetWidth; + } + } + else + { + if (m_GrabHandleStyle == eGrabHandleStyle.Caption) + iTop += GetGrabHandleCaptionHeight(); + else if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + iTop += GetGrabHandleTaskPaneHeight(); + else + iTop += GrabHandleDotNetWidth; + } + } + } + } + + if (!bCalculateOnly) + { + m_ItemContainer.TopInternal = iTop; + m_ItemContainer.LeftInternal = iLeft; + } + else + { + iOrgHeight = m_ItemContainer.HeightInternal; + iOrgWidth = m_ItemContainer.WidthInternal; + } + + // Suspend Layout while setting suggested size + m_ItemContainer.SuspendLayout = true; + if (!bCalculateOnly) + { + if (thisBarState == eBarState.Popup) + m_ItemContainer.WidthInternal = m_InitialContainerWidth; + else + { + m_ItemContainer.WidthInternal = objFrameSize.Width - iLeft - iRightMargin - iRightTabMargin; //m_ItemContainer.WidthInternal=this.Width-iLeft-iRightMargin; + m_ItemContainer.HeightInternal = objFrameSize.Height - iTop - iBottomMargin; //m_ItemContainer.HeightInternal=this.Height-iTop-iBottomMargin; + } + } + else + { + m_ItemContainer.WidthInternal = objFrameSize.Width - iLeft - iRightMargin - iRightTabMargin; + m_ItemContainer.HeightInternal = objFrameSize.Height - iTop - iBottomMargin; + } + m_ItemContainer.SuspendLayout = false; + + if (m_ItemContainer.VisibleSubItems == 0 || (m_ItemContainer.SubItems.Count == 1 && m_ItemContainer.SubItems[0] is CustomizeItem && !m_ItemContainer.SubItems[0].Visible)) + { + m_ItemContainer.RecalcSize(); + if (this.LayoutType != eLayoutType.DockContainer && this.DockSide != eDockSide.Document) + { + m_ItemContainer.WidthInternal = 36; + m_ItemContainer.HeightInternal = 24; + } + } + else + m_ItemContainer.RecalcSize(); + + iTop += m_ItemContainer.HeightInternal; + if (IsGradientStyle && this.LayoutType == eLayoutType.Toolbar && !this.MenuBar && !this.IsThemed && BarType != eBarType.StatusBar) + iTop++; + + if (!bCalculateOnly) + { + if (this.RightToLeft == RightToLeft.Yes) + { + if (this.LayoutType == eLayoutType.Toolbar && m_ItemContainer.WidthInternal < objFrameSize.Width - iLeft - iRightMargin - iRightTabMargin && this.Stretch) + { + m_ItemContainer.LeftInternal = objFrameSize.Width - iRightMargin - m_ItemContainer.WidthInternal; + m_ItemContainer.RecalcSize(); + } + m_ClientRect = new Rectangle(m_ItemContainer.LeftInternal, iTopMargin, m_ItemContainer.WidthInternal, iTop); + } + else + m_ClientRect = new Rectangle(iLeft, iTopMargin, m_ItemContainer.WidthInternal, iTop); + } + + if (!bCalculateOnly) + { + if ((thisBarState == eBarState.Docked || thisBarState == eBarState.AutoHide) && m_GrabHandleStyle != eGrabHandleStyle.None && m_GrabHandleStyle != eGrabHandleStyle.ResizeHandle) + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType == eLayoutType.Toolbar) + { + if (m_GrabHandleStyle == eGrabHandleStyle.Caption) + m_GrabHandleRect = new Rectangle(iLeftMargin, iTopMargin, GetGrabHandleCaptionHeight(), iTop); + else + { + if (this.RightToLeft == RightToLeft.Yes) + m_GrabHandleRect = new Rectangle(m_ItemContainer.WidthInternal + iLeft + iLeftMargin, iTopMargin, 10, iTop); + else + m_GrabHandleRect = new Rectangle(iLeftMargin, iTopMargin, 10, iTop); + } + } + else + { + if (m_GrabHandleStyle == eGrabHandleStyle.Caption) + m_GrabHandleRect = new Rectangle(iLeftMargin, iTopMargin, m_ItemContainer.WidthInternal + iLeft - iLeftMargin + iRightTabMargin, GetGrabHandleCaptionHeight()); + else if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + m_GrabHandleRect = new Rectangle(iLeftMargin, iTopMargin, m_ItemContainer.WidthInternal + iLeft - iLeftMargin + iRightTabMargin, GetGrabHandleTaskPaneHeight()); + else + { + //if (this.RightToLeft == RightToLeft.Yes) + // m_GrabHandleRect = new Rectangle(objFrameSize.Width - iLeft - iRightMargin - iRightTabMargin, iTopMargin, m_ItemContainer.WidthInternal + iLeft - iLeftMargin + iRightTabMargin, 10); + //else + m_GrabHandleRect = new Rectangle(iLeftMargin, iTopMargin, m_ItemContainer.WidthInternal + iLeft - iLeftMargin + iRightTabMargin, 10); + } + } + } + else if (thisBarState == eBarState.Floating) + { + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane) + { + m_GrabHandleRect = new Rectangle(iLeftMargin, ((this.IsThemed || this.DrawThemedCaption) ? m_ThemeWindowMargins.Bottom : 2), m_ItemContainer.WidthInternal + iLeft - iLeftMargin + iRightTabMargin, GetGrabHandleTaskPaneHeight()); + } + else + { + m_GrabHandleRect = new Rectangle(2, 2, m_ItemContainer.WidthInternal + iRightTabMargin, GetGrabHandleCaptionHeight()); + if (this.CanHideResolved) + m_GrabHandleRect.Width -= 14; + } + } + + if (thisBarState == eBarState.Popup && m_SideBarImage.Picture != null) + m_SideBarRect = new Rectangle(iLeft - m_SideBarImage.Picture.Width, iTopMargin, m_SideBarImage.Picture.Width, iTop - iTopMargin); + + //if(iLeft+m_ItemContainer.Width+iRightMargin!=this.ClientSize.Width || this.ClientSize.Height!=iTop+iBottomMargin) + // this.ClientSize=new Size(iLeft+m_ItemContainer.Width+iRightMargin,iTop+iBottomMargin); + thisSize = new Size(iLeft + m_ItemContainer.WidthInternal + iRightMargin + iRightTabMargin, iTop + iBottomMargin); + } + else + { + //if(m_BarState==eBarState.Floating) + thisSize = new Size(iLeft + m_ItemContainer.WidthInternal + iRightMargin + iRightTabMargin, iTop + iBottomMargin); + //else + // thisSize=new Size(iLeft+m_ItemContainer.WidthInternal+iRightMargin+iRightTabMargin+14,iTop+iBottomMargin); + m_ItemContainer.WidthInternal = iOrgWidth; + m_ItemContainer.HeightInternal = iOrgHeight; + m_ItemContainer.Orientation = oldOrientation; + m_ItemContainer.WrapItems = bOldWrapItems; + m_ItemContainer.Stretch = bOldStretch; + m_ItemContainer.RecalcSize(); + } + return thisSize; + } + + private System.Drawing.Size RecalcSizeOffice() + { + return RecalcSizeOffice(false, this.Size, m_ItemContainer.Orientation, this.m_BarState, m_ItemContainer.WrapItems); + } + private System.Drawing.Size RecalcSizeOffice(bool bCalculateOnly, System.Drawing.Size objFrameSize, eOrientation barOrientation, eBarState barState, bool bWrapItems) + { + System.Drawing.Size thisSize = System.Drawing.Size.Empty; + + int iTopMargin = 0, iBottomMargin = 0, iLeftMargin = 0, iRightMargin = 0, iRightTabMargin = 0; + int iOrgWidth = 0, iOrgHeight = 0; + eOrientation oldOrientation = m_ItemContainer.Orientation; + eBarState thisBarState = m_BarState; + bool bOldStretch = m_ItemContainer.Stretch; + bool bOldWrapItems = m_ItemContainer.WrapItems; + m_ItemContainer.IsRightToLeft = (this.RightToLeft == RightToLeft.Yes); + if (bCalculateOnly) + { + m_ItemContainer.Orientation = barOrientation; + thisBarState = barState; + m_ItemContainer.WrapItems = bWrapItems; + if (barState == eBarState.Docked) + m_ItemContainer.Stretch = m_DockStretch; + else + { + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer) + m_ItemContainer.Stretch = m_DockStretch; + else + m_ItemContainer.Stretch = false; + } + } + + if (thisBarState == eBarState.Docked) + { + if (m_DockedBorder != eBorderType.None) + { + iTopMargin = 2; + iBottomMargin = 2; + iLeftMargin = 2; + iRightMargin = 2; + } + } + else if (thisBarState == eBarState.Floating) + { + iTopMargin = 22; + iLeftMargin = 4; + iRightMargin = 4; + iBottomMargin = 4; + } + else + { + iTopMargin = this.ClientMarginTop; + iLeftMargin = this.ClientMarginLeft; + iRightMargin = this.ClientMarginRight; + iBottomMargin = this.ClientMarginBottom; + } + + int iTop = iTopMargin, iLeft = iLeftMargin; + + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && !m_AutoHideState && GetDockTabVisible()) + { + if (m_ItemContainer.VisibleSubItems > 1 || m_AlwaysDisplayDockTab && m_ItemContainer.VisibleSubItems == 1 && m_BarState != eBarState.Floating) + { + int dockTabStripHeight = Dpi.Height(DockTabStripHeight); + switch (m_DockTabAlignment) + { + case eTabStripAlignment.Top: + { + iTop += dockTabStripHeight; + break; + } + case eTabStripAlignment.Left: + { + iLeft += dockTabStripHeight; + break; + } + case eTabStripAlignment.Right: + { + iRightTabMargin = dockTabStripHeight; + break; + } + default: + { + iBottomMargin += dockTabStripHeight; + break; + } + } + } + } + + // Take in account the side bar picture + if (thisBarState == eBarState.Popup && m_SideBarImage.Picture != null) + iLeft += m_SideBarImage.Picture.Width; + else if (thisBarState == eBarState.Docked || this.BarState == eBarState.AutoHide) + { + // Show grab handles if any selected + if (m_GrabHandleStyle != eGrabHandleStyle.None) + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType != eLayoutType.DockContainer) + iLeft += GrabHandleOfficeWidth; + else + { + if (m_GrabHandleStyle == eGrabHandleStyle.Caption) + iTop += GetGrabHandleCaptionHeight(); + else if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + iTop += GetGrabHandleTaskPaneHeight(); + else + iTop += GrabHandleOfficeWidth; + } + } + } + + if (!bCalculateOnly) + { + m_ItemContainer.TopInternal = iTop; + m_ItemContainer.LeftInternal = iLeft; + } + else + { + iOrgHeight = m_ItemContainer.HeightInternal; + iOrgWidth = m_ItemContainer.WidthInternal; + } + + if (!bCalculateOnly) + { + if (thisBarState == eBarState.Popup) + m_ItemContainer.WidthInternal = m_InitialContainerWidth; + else + { + m_ItemContainer.WidthInternal = objFrameSize.Width - iLeft - iRightMargin - iRightTabMargin; //m_ItemContainer.WidthInternal=this.Width-iLeft-iRightMargin; + m_ItemContainer.HeightInternal = objFrameSize.Height - iTop - iBottomMargin; //m_ItemContainer.HeightInternal=this.Height-iTop-iBottomMargin; + } + } + else + { + m_ItemContainer.WidthInternal = objFrameSize.Width - iLeft - iRightMargin - iRightTabMargin; + m_ItemContainer.HeightInternal = objFrameSize.Height - iTop - iBottomMargin; + } + + if (m_ItemContainer.VisibleSubItems == 0) + { + m_ItemContainer.WidthInternal = 36; + m_ItemContainer.HeightInternal = 24; + } + else + m_ItemContainer.RecalcSize(); + + iTop += m_ItemContainer.HeightInternal; + + if (!bCalculateOnly) + m_ClientRect = new Rectangle(iLeft, iTopMargin, m_ItemContainer.WidthInternal, iTop); + + if (!bCalculateOnly) + { + if ((thisBarState == eBarState.Docked || this.BarState == eBarState.AutoHide) && m_GrabHandleStyle != eGrabHandleStyle.None) + { + if (m_ItemContainer.Orientation == eOrientation.Horizontal && m_ItemContainer.LayoutType != eLayoutType.DockContainer) + { + m_GrabHandleRect = new Rectangle(iLeftMargin, iTopMargin, 12, iTop); + } + else + { + if (m_GrabHandleStyle == eGrabHandleStyle.Caption) + m_GrabHandleRect = new Rectangle(iLeftMargin, iTopMargin, m_ItemContainer.WidthInternal + iLeft - iLeftMargin + iRightTabMargin, GetGrabHandleCaptionHeight()); + else if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) + m_GrabHandleRect = new Rectangle(iLeftMargin, iTopMargin, m_ItemContainer.WidthInternal + iLeft - iLeftMargin + iRightTabMargin, GetGrabHandleTaskPaneHeight()); + else + m_GrabHandleRect = new Rectangle(iLeftMargin, iTopMargin, m_ItemContainer.WidthInternal + iLeft - iLeftMargin + iRightTabMargin, 12); + } + } + else if (thisBarState == eBarState.Floating) + { + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane) + m_GrabHandleRect = new Rectangle(4, 4, m_ItemContainer.WidthInternal + iRightTabMargin, GetGrabHandleTaskPaneHeight()); + else + m_GrabHandleRect = new Rectangle(4, 4, m_ItemContainer.WidthInternal + iRightTabMargin, 15); + if (this.CanHideResolved) + m_GrabHandleRect.Width -= 14; + } + + if (thisBarState == eBarState.Popup && m_SideBarImage.Picture != null) + m_SideBarRect = new Rectangle(iLeft - m_SideBarImage.Picture.Width, iTopMargin, m_SideBarImage.Picture.Width, iTop - iTopMargin); + //this.ClientSize=new Size(iLeft+m_ItemContainer.Width+iRightMargin,iTop+iBottomMargin); + thisSize = new Size(iLeft + m_ItemContainer.WidthInternal + iRightMargin + iRightTabMargin, iTop + iBottomMargin); + } + else + { + thisSize = new Size(iLeft + m_ItemContainer.WidthInternal + iRightMargin + iRightTabMargin, iTop + iBottomMargin); + m_ItemContainer.WidthInternal = iOrgWidth; + m_ItemContainer.HeightInternal = iOrgHeight; + m_ItemContainer.Orientation = oldOrientation; + m_ItemContainer.WrapItems = bOldWrapItems; + m_ItemContainer.Stretch = bOldStretch; + m_ItemContainer.RecalcSize(); + } + return thisSize; + } + + private void RestoreContainer() + { + if (m_ParentItem != null)// && m_ParentItem.SubItems.Count!=0) + { + foreach (BaseItem objItem in m_ParentItem.SubItems) + { + objItem.Expanded = false; + objItem.SetParent(m_ParentItem); + objItem.ContainerControl = m_OldContainer; + objItem.Displayed = false; + objItem.Orientation = m_ParentItem.Orientation; + } + m_ItemContainer.SubItems._Clear(); + } + } + + internal void OnAddedToBars() + { + if (m_Owner != null && m_Owner is IOwner) + { + if (((IOwner)m_Owner).Images != null) + m_ItemContainer.RefreshImageSize(); + } + } + + internal void ProcessDelayedCommands() + { + if (m_DockSideDelayed >= 0) + { + if (!((eDockSide)m_DockSideDelayed == eDockSide.Document && this.DockSide == eDockSide.Document)) + this.DockSide = (eDockSide)m_DockSideDelayed; + m_DockSideDelayed = -1; + foreach (BaseItem item in m_ItemContainer.SubItems) + item.OnProcessDelayedCommands(); + } + } + + private bool IsAnyControl(Control ctrlParent, Control ctrlReference) + { + if (ctrlParent == ctrlReference) + return true; + foreach (Control ctrl in ctrlParent.Controls) + { + if (ctrl == ctrlReference) + return true; + bool bRet = IsAnyControl(ctrl, ctrlReference); + if (bRet) + return true; + } + return false; + } + + private int GetGrabHandleTaskPaneHeight() + { + if (this.Font != null) + return Math.Max(Dpi.Height(GrabHandleTaskPaneHeight), this.Font.Height + Dpi.Height2); + return Dpi.Height(GrabHandleTaskPaneHeight); + } + + private int _CaptionHeight = 0; + /// + /// Gets or sets docked bar caption height. Default value is 0 which means system predefined height is used. + /// + [DefaultValue(0), Category("Appearance"), Description("Indicates docked bar caption height. Default value is 0 which means system predefined height is used.")] + public int CaptionHeight + { + get { return _CaptionHeight; } + set { _CaptionHeight = value; this.RecalcLayout(); } + } + + private int GetGrabHandleCaptionHeight() + { + if (_CaptionHeight > 0) return Dpi.Height(_CaptionHeight); + if (this.Font != null) + return Math.Max(Dpi.Height(GrabHandleCaptionHeight), this.Font.Height + 2); + return Dpi.Height(GrabHandleCaptionHeight); + } + + /// + /// Gets or sets whether bar when changed over to floating state is hidden instead of shown. This property is used + /// internally to optimize loading of hidden floating bars. You should not use this property in your code. It is for internal DotNetBar + /// infrastructure use only. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool LoadingHideFloating + { + get { return m_LoadingHideFloating; } + set { m_LoadingHideFloating = value; } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void DockDocumentManager(DockSiteInfo pDockInfo) + { + DocumentDockUIManager dm = pDockInfo.objDockSite.GetDocumentUIManager(); + if (pDockInfo.objDockSite.Dock == DockStyle.Fill) + dm.Dock(pDockInfo.MouseOverBar, this, pDockInfo.MouseOverDockSide); + else if ((pDockInfo.DockLine == -1 || pDockInfo.DockLine == 999) && (pDockInfo.objDockSite.Dock == DockStyle.Left || pDockInfo.objDockSite.Dock == DockStyle.Right)) // Ajdust for edge case docking + { + dm.Dock(null, this, pDockInfo.DockLine == -1 ? eDockSide.Left : eDockSide.None); + } + else if ((pDockInfo.DockLine == -1 || pDockInfo.DockLine == 999) && (pDockInfo.objDockSite.Dock == DockStyle.Top || pDockInfo.objDockSite.Dock == DockStyle.Bottom)) // Ajdust for edge case docking + { + dm.Dock(null, this, pDockInfo.DockLine == -1 ? eDockSide.Top : eDockSide.None); + } + else + dm.Dock(pDockInfo.MouseOverBar, this, pDockInfo.MouseOverDockSide); + } + + internal void RemoveFromFloatingContainer() + { + if (m_Float == null) return; + // Remember undocked size + m_FloatingRect = new Rectangle(m_Float.Location, this.Size); + m_Float.Controls.Remove(this); + m_Float.Hide(); + m_Float.Dispose(); + m_Float = null; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void DockingHandler(DockSiteInfo pDockInfo, Point p) + { + IOwner owner = m_Owner as IOwner; + + if (m_TempTabBar != null && pDockInfo.TabDockContainer == m_TempTabBar) + return; + + if (pDockInfo.objDockSite == null && (m_BarState != eBarState.Floating || m_Float == null)) + { + m_DockingInProgress = true; + + if (m_TempTabBar != null) + { + RemoveTempTabBarItems(); + m_TempTabBar.RecalcLayout(); + m_TempTabBar = null; + } + + // Remember last docking info + DockSiteInfo tempInfo = m_LastDockSiteInfo; + m_LastDockSiteInfo = new DockSiteInfo(); + // Preserve the relative last docked to bar in case the return to same docking position is needed + m_LastDockSiteInfo.LastRelativeDocumentId = tempInfo.LastRelativeDocumentId; + m_LastDockSiteInfo.LastRelativeDockToBar = tempInfo.LastRelativeDockToBar; + + m_LastDockSiteInfo.DockedHeight = this.Height; + m_LastDockSiteInfo.DockedWidth = this.Width; + m_LastDockSiteInfo.DockLine = this.DockLine; + m_LastDockSiteInfo.DockOffset = this.DockOffset; + if (this.Parent != null) + m_LastDockSiteInfo.DockSide = this.Parent.Dock; + else + m_LastDockSiteInfo.DockSide = DockStyle.Left; + + if (this.Parent != null && this.Parent is DockSite) + { + m_LastDockSiteInfo.InsertPosition = ((DockSite)this.Parent).Controls.GetChildIndex(this); + m_LastDockSiteInfo.objDockSite = (DockSite)this.DockedSite; + } + if (m_LastDockSiteInfo.objDockSite == null) + { + IOwnerBarSupport barSupp = m_Owner as IOwnerBarSupport; + if (barSupp != null) + { + switch (m_LastDockSiteInfo.DockSide) + { + case DockStyle.Left: + m_LastDockSiteInfo.objDockSite = barSupp.LeftDockSite; + break; + case DockStyle.Right: + m_LastDockSiteInfo.objDockSite = barSupp.RightDockSite; + break; + case DockStyle.Top: + m_LastDockSiteInfo.objDockSite = barSupp.TopDockSite; + break; + case DockStyle.Bottom: + m_LastDockSiteInfo.objDockSite = barSupp.BottomDockSite; + break; + case DockStyle.Fill: + m_LastDockSiteInfo.objDockSite = barSupp.FillDockSite; + break; + } + } + } + + // Undock the window + m_BarState = eBarState.Floating; + if (m_Float == null) + { + m_Float = new FloatingContainer(this); + m_Float.CreateControl(); + } + + // Must reset the ActiveControl to null because on MDI Forms if this was not done + // MDI form could not be closed if bar that had ActiveControl is floating. + if (owner.ParentForm != null && owner.ParentForm.ActiveControl == this) + { + owner.ParentForm.ActiveControl = null; + this.Focus(); // Fixes the problem on SDI forms + } + else if (owner.ParentForm != null && IsAnyControl(this, owner.ParentForm.ActiveControl)) + { + owner.ParentForm.ActiveControl = null; + this.Focus(); + } + + // Check for parent since if bar is deserialized there is no parent and state is Docked by default + + if (this.Parent != null && this.Parent is DockSite) + { + if (((DockSite)this.Parent).IsDocumentDock || ((DockSite)this.Parent).DocumentDockContainer != null) + { + ((DockSite)this.Parent).GetDocumentUIManager().UnDock(this); + } + else + ((DockSite)this.Parent).RemoveBar(this); + } + + this.Parent = null; + m_Float.Controls.Add(this); + if (!this.Visible/* && !m_BarDefinitionLoading*/) + base.Visible = true; + // IMPORTANT SINCE WE OVERRIDE BASE LOCATION WE HAVE TO USE BASE HERE TO ACTUALLY MOVE IT + base.Location = new Point(0, 0); + + m_FloatingRect = new Rectangle(m_FloatingRect.Location, GetFloatingSize()); + this.Size = m_FloatingRect.Size; + + this.DockOrientation = eOrientation.Horizontal; + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && m_AlwaysDisplayDockTab) + RefreshDockTab(true); + this.RecalcSize(); + m_FloatingRect.Size = this.Size; + + m_Float.Location = p; + if (m_ItemContainer.LayoutType != eLayoutType.Toolbar) + m_MouseDownPt = new Point(this.Width / 2, 8); + else + m_MouseDownPt = new Point(8, 8); + + if (m_LoadingHideFloating) + m_Float.Visible = false; + else + m_Float.Show(); + + m_FloatingRect.Location = m_Float.Location; + + // TODO: Bug Width was sometimes not reflected properly + if (m_Float.Width != m_FloatingRect.Width) + m_Float.Width = m_FloatingRect.Width; + + if (owner.ParentForm != null) + { + bool activate = true; + if (m_BarDefinitionLoading && owner is DotNetBarManager && !((DotNetBarManager)owner).ActivateOnLayoutLoad) + activate = false; + if (activate) + owner.ParentForm.Activate(); + } + m_DockingInProgress = false; + + // Raise events + if (BarUndock != null) + BarUndock(this, new EventArgs()); + IOwnerBarSupport ownerDockEvents = m_Owner as IOwnerBarSupport; + if (ownerDockEvents != null) + ownerDockEvents.InvokeBarUndock(this, new EventArgs()); + OnBarStateChanged(new BarStateChangedEventArgs(this, eBarStateChange.BarUndocked)); + + // Resize Docking Tab if it exists + ResizeDockTab(); + } + else + { + // Change the Z-Order of the dock-site if needed + if ((pDockInfo.FullSizeDock || pDockInfo.PartialSizeDock) && pDockInfo.DockSiteZOrderIndex >= 0 && pDockInfo.objDockSite != null && pDockInfo.objDockSite.Parent != null) + pDockInfo.objDockSite.Parent.Controls.SetChildIndex(pDockInfo.objDockSite, pDockInfo.DockSiteZOrderIndex); + + if (m_Owner != null) + { + if (pDockInfo.TabDockContainer != null) + { + if (m_TempTabBar != null && pDockInfo.TabDockContainer != m_TempTabBar) + { + RemoveTempTabBarItems(); + m_TempTabBar.RecalcLayout(); + m_TempTabBar = null; + } + if (m_TempTabBar != pDockInfo.TabDockContainer) + { + m_DockingInProgress = true; + + if (m_DockTabTearOffIndex == -1) + { + if (m_Float != null && m_Float.Visible) + { + if (owner.ParentForm != null) + owner.ParentForm.Activate(); + // Remember undocked size + m_FloatingRect = new Rectangle(m_Float.Location, this.Size); + m_DockOffset = pDockInfo.DockOffset; + m_DockLine = pDockInfo.DockLine; + m_Float.Controls.Remove(this); + m_Float.Hide(); + m_Float.Dispose(); + m_Float = null; + } + else if (this.Parent != null && this.Parent is DockSite) + ((DockSite)this.Parent).RemoveBar(this); + m_BarState = eBarState.Docked; + if (!m_BarDefinitionLoading) + base.Visible = false; + + foreach (BaseItem item in m_ItemContainer.SubItems) + { + DockContainerItem dockitem = item as DockContainerItem; + if (dockitem != null) + { + DockContainerItem temp = new DockContainerItem(); + temp.Displayed = false; + temp.Text = item.Text; + temp.Image = dockitem.Image; + temp.ImageIndex = dockitem.ImageIndex; + temp.Icon = dockitem.Icon; + temp.Tag = "systempdockitem"; + pDockInfo.TabDockContainer.Items.Add(temp); + } + m_TempTabBar = pDockInfo.TabDockContainer; + m_TempTabBar.RecalcLayout(); + m_TempTabBar.Refresh(); + } + } + else + { + DockContainerItem dockitem = m_ItemContainer.SubItems[m_DockTabTearOffIndex] as DockContainerItem; + if (dockitem != null) + { + DockContainerItem temp = new DockContainerItem(); + temp.Displayed = false; + temp.Text = dockitem.Text; + temp.Image = dockitem.Image; + temp.ImageIndex = dockitem.ImageIndex; + temp.Icon = dockitem.Icon; + temp.Tag = "systempdockitem"; + pDockInfo.TabDockContainer.Items.Add(temp); + } + m_TempTabBar = pDockInfo.TabDockContainer; + m_TempTabBar.RecalcLayout(); + m_TempTabBar.Refresh(); + } + m_DockingInProgress = false; + } + + } + else + { + if (m_TempTabBar != null) + { + // Allow tabbed bar to change position only if it is going to different bar + if (pDockInfo.objDockSite == m_TempTabBar.Parent) + return; + RemoveTempTabBarItems(); + m_TempTabBar.RecalcLayout(); + m_TempTabBar = null; + } + // If coming from the tabs + if (!this.Visible && !m_BarDefinitionLoading) + this.Visible = true; + if (pDockInfo.LastRelativeDockToBar != null && pDockInfo.LastRelativeDockToBar.DockedSite != null && owner is DotNetBarManager) + { + DotNetBarManager manager = (DotNetBarManager)owner; + if (pDockInfo.LastRelativeDockToBar.AutoHide) + { + if (pDockInfo.objDockSite != null) + pDockInfo.objDockSite.GetDocumentUIManager().Dock(this); + else + manager.Dock(this, eDockSide.Right); + } + else if (!pDockInfo.LastRelativeDockToBar.Visible || + pDockInfo.LastRelativeDockToBar.DockSide == eDockSide.None) // Closed or floating + { + manager.Dock(this, m_LastDockSiteInfo.LastDockSiteSide); + } + else if (pDockInfo.LastRelativeDockToBar.DockSide != eDockSide.None && + m_LastDockSiteInfo.LastDockSiteSide != pDockInfo.LastRelativeDockToBar.DockSide) // Reference bar docked somewhere else + { + manager.Dock(this, m_LastDockSiteInfo.LastDockSiteSide); + } + else + manager.Dock(this, pDockInfo.LastRelativeDockToBar, LastDockSide); + if (this.IsDisposed) return; + m_BarState = eBarState.Docked; + pDockInfo.LastRelativeDockToBar = null; + } + else if (pDockInfo.objDockSite != null && m_BarState != eBarState.Docked) + { + m_DockingInProgress = true; + if (m_Float != null && m_BarState == eBarState.Floating) + { + if (owner.ParentForm != null) + owner.ParentForm.Activate(); + // Remember undocked size + m_FloatingRect = new Rectangle(m_Float.Location, this.Size); + m_DockOffset = pDockInfo.DockOffset; + m_DockLine = pDockInfo.DockLine; + m_Float.Controls.Remove(this); + m_Float.Hide(); + m_Float.Dispose(); + m_Float = null; + } + m_BarState = eBarState.Docked; + + if (pDockInfo.objDockSite.IsDocumentDock || pDockInfo.objDockSite.DocumentDockContainer != null) + { + DockDocumentManager(pDockInfo); + } + else + { + if (pDockInfo.InsertPosition == -10) + pDockInfo.objDockSite.AddBar(this); + else + pDockInfo.objDockSite.AddBar(this, pDockInfo.InsertPosition); + } + m_DockingInProgress = false; + + // // Raise events + // if(BarDock!=null) + // BarDock(this,new EventArgs()); + // IOwnerBarSupport ownerDockEvents=m_Owner as IOwnerBarSupport; + // if(ownerDockEvents!=null) + // ownerDockEvents.InvokeBarDock(this,new EventArgs()); + } + else if (pDockInfo.objDockSite != null && pDockInfo.objDockSite != this.Parent) + { + m_DockingInProgress = true; + // Must reset the ActiveControl to null becouse on MDI Forms if this was not done + // MDI form could not be closed if bar that had ActiveControl is floating. + if (owner.ParentForm != null && owner.ParentForm.ActiveControl == this) + { + owner.ParentForm.ActiveControl = null; + this.Focus(); // Fixes the problem on SDI forms + } + else if (owner.ParentForm != null && IsAnyControl(this, owner.ParentForm.ActiveControl)) + { + owner.ParentForm.ActiveControl = null; + this.Focus(); + } + + // It is docked somewhere else, we need to undockit and dockit on another site + // If Bar is deserialized there is no parent + if (this.Parent != null && this.Parent is DockSite) + { + if (((DockSite)this.Parent).IsDocumentDock || ((DockSite)this.Parent).DocumentDockContainer != null) + ((DockSite)this.Parent).GetDocumentUIManager().UnDock(this); + else + ((DockSite)this.Parent).RemoveBar(this); + } + + // If coming from the tabs + if (!this.Visible && !m_BarDefinitionLoading) + this.Visible = true; + + m_DockOffset = pDockInfo.DockOffset; + m_DockLine = pDockInfo.DockLine; + + if (pDockInfo.objDockSite.IsDocumentDock || pDockInfo.objDockSite.DocumentDockContainer != null) + { + pDockInfo.objDockSite.GetDocumentUIManager().Dock(pDockInfo.MouseOverBar, this, pDockInfo.MouseOverDockSide); + } + else + { + if (pDockInfo.InsertPosition == -10) + pDockInfo.objDockSite.AddBar(this); + else + pDockInfo.objDockSite.AddBar(this, pDockInfo.InsertPosition); + } + // Raise events + // if(BarDock!=null) + // BarDock(this,new EventArgs()); + // IOwnerBarSupport ownerDockEvents=m_Owner as IOwnerBarSupport; + // if(ownerDockEvents!=null) + // ownerDockEvents.InvokeBarDock(this,new EventArgs()); + m_DockingInProgress = false; + } + else if (this.Parent != null && pDockInfo.objDockSite == this.Parent) + { + if (pDockInfo.objDockSite.IsDocumentDock || pDockInfo.objDockSite.DocumentDockContainer != null) + { + pDockInfo.objDockSite.GetDocumentUIManager().Dock(pDockInfo.MouseOverBar, this, pDockInfo.MouseOverDockSide); + } + else + { + if (m_DockLine != pDockInfo.DockLine || m_DockOffset != pDockInfo.DockOffset && !this.Stretch || pDockInfo.objDockSite.Controls.GetChildIndex(this) != pDockInfo.InsertPosition || pDockInfo.NewLine) + { + m_DockLine = pDockInfo.DockLine; + m_DockOffset = pDockInfo.DockOffset; + // If coming from the tabs + if (!this.Visible && !m_BarDefinitionLoading) + this.Visible = true; + if (pDockInfo.NewLine) + pDockInfo.objDockSite.SetBarPosition(this, pDockInfo.InsertPosition, true); + else if (pDockInfo.InsertPosition == -10) + { + pDockInfo.objDockSite.AdjustBarPosition(this); + pDockInfo.objDockSite.RecalcLayout(); + } + else + pDockInfo.objDockSite.SetBarPosition(this, pDockInfo.InsertPosition); + } + } + } + else + { + Point newLocation = new Point(p.X - m_MouseDownPt.X, p.Y - m_MouseDownPt.Y); + ScreenInformation screen = BarFunctions.ScreenFromControl(m_Float); + if (screen != null) + { + if (newLocation.Y + 8 >= screen.WorkingArea.Bottom) + newLocation.Y = screen.WorkingArea.Bottom - 8; + else if (newLocation.Y <= screen.WorkingArea.Y - 1 && this.EffectiveCanMaximizeFloating && !this.IsMaximized && + BarFunctions.ScreenFromPoint(new Point(newLocation.X, screen.Bounds.Y - 32)) == null) // Make sure there is no screen above + { + this.IsMaximized = true; + } + else if (this.IsMaximized && (Math.Abs(p.X - m_MouseDownPt.X) > 0 || Math.Abs(p.Y - m_MouseDownPt.Y) > 0) && newLocation.Y > screen.WorkingArea.Y + 8) + { + this.IsMaximized = false; + m_MouseDownPt.X = this.ClientSize.Width / 2; + newLocation = new Point(p.X - m_MouseDownPt.X, p.Y - m_MouseDownPt.Y); + } + } + if (!this.IsMaximized) + m_Float.Location = newLocation; + if (((IOwner)m_Owner).ParentForm != null) + ((IOwner)m_Owner).ParentForm.Update(); + } + } + } + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && (m_TabDockItems == null || !m_TabDockItems.Visible)) + { + int iVisible = m_ItemContainer.VisibleSubItems; + if (!(m_BarState == eBarState.Floating && iVisible <= 1) && (m_AlwaysDisplayDockTab || iVisible > 0)) + { + eBarState oldBarState = m_BarState; + m_BarState = eBarState.Docked; + RefreshDockTab(false); + m_BarState = oldBarState; + } + } + if (m_BarState != eBarState.Floating) + InvokeBarDockEvents(); + } + } + + internal void InvokeBarDockEvents() + { + // Raise events + if (BarDock != null) + BarDock(this, new EventArgs()); + IOwnerBarSupport ownerDockEvents = m_Owner as IOwnerBarSupport; + if (ownerDockEvents != null) + ownerDockEvents.InvokeBarDock(this, new EventArgs()); + OnBarStateChanged(new BarStateChangedEventArgs(this, eBarStateChange.BarDocked)); + } + + private Size GetFloatingSize() + { + Size size = m_FloatingRect.Size; + if (size.IsEmpty) + { + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer) + { + int tab = this.SelectedDockTab; + if (tab >= 0 && m_ItemContainer.SubItems[tab] is DockContainerItem) + { + DockContainerItem item = m_ItemContainer.SubItems[tab] as DockContainerItem; + size = Dpi.Size(item.DefaultFloatingSize); + } + else if (m_ItemContainer.SubItems.Count > 0 && m_ItemContainer.SubItems[0] is DockContainerItem) + { + DockContainerItem item = m_ItemContainer.SubItems[0] as DockContainerItem; + size = Dpi.Size(item.DefaultFloatingSize); + } + else + { + if (m_ItemContainer.Orientation == eOrientation.Vertical) + size = new Size(m_ItemContainer.WidthInternal + 16, m_ItemContainer.WidthInternal + 16); + else + size = new Size(m_ItemContainer.HeightInternal + 24, m_ItemContainer.HeightInternal + 24); + } + } + else + size = System.Windows.Forms.Screen.FromControl(this).WorkingArea.Size; + } + + return size; + } + + private void RemoveTempTabBarItems() + { + if (m_TempTabBar != null) + { + System.Collections.ArrayList list = new System.Collections.ArrayList(m_TempTabBar.Items.Count); + m_TempTabBar.Items.CopyTo(list); + foreach (BaseItem item in list) + { + if (item.Tag != null && item.Tag.ToString() == "systempdockitem") + m_TempTabBar.Items.Remove(item); + } + } + } + + internal Bar TempTabBar + { + get { return m_TempTabBar; } + } + + internal void DragMouseMove() + { + Point p = this.PointToClient(Control.MousePosition); + this.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 0, p.X, p.Y, 0)); + } + internal void DragMouseUp() + { + Point p = this.PointToClient(Control.MousePosition); + this.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0, p.X, p.Y, 0)); + } + + internal void InternalMouseMove(MouseEventArgs e) + { + this.OnMouseMove(e); + } + + /// + /// Returns true if bar is being moved/dragged by user. + /// + internal bool IsBarMoving + { + get { return m_MoveWindow; } + } + + /// + /// Method is called by DotNetBarManager when bar is being moved and Escape key is pressed. + /// + internal void OnEscapeKey() + { + EndDocking(true, Point.Empty); + } + + protected override void OnFontChanged(EventArgs e) + { + this.InvalidateFontChange(); + base.OnFontChanged(e); + } + + private void InvalidateFontChange() + { + if (m_ItemContainer != null) + BarUtilities.InvalidateFontChange(m_ItemContainer.SubItems); + } + + private bool m_InMouseMove = false; + private Rectangle m_OldOutlineRectangle = Rectangle.Empty; + private Form m_OutlineForm = null; + //private bool m_OutlineDrag=true; + protected override void OnMouseMove(MouseEventArgs e) + { + if (m_InMouseMove) + return; + m_InMouseMove = true; + // Start window dragging + if (m_MoveWindow && m_BarState != eBarState.Popup && e.Button == System.Windows.Forms.MouseButtons.Left && DotNetBarManager.MouseDockingEnabled) + { + if (this.Cursor != System.Windows.Forms.Cursors.SizeAll) + this.Cursor = System.Windows.Forms.Cursors.SizeAll; + + Point p = Control.MousePosition; + Point p2 = this.PointToClient(p); + IOwnerBarSupport ownerDock = m_Owner as IOwnerBarSupport; + + // Graceful exit + if (ownerDock == null || Math.Abs(p2.X - m_MouseDownPt.X) <= 4 && Math.Abs(p2.Y - m_MouseDownPt.Y) <= 4) + { + base.OnMouseMove(e); + m_InMouseMove = false; + return; + } + DockSiteInfo pDockInfo = ownerDock.GetDockInfo(this, p.X, p.Y); + if (pDockInfo.objDockSite == null && !m_CanUndock) + { + base.OnMouseMove(e); + m_InMouseMove = false; + return; + } + bool bPreview = true; + + if (!m_OldOutlineRectangle.IsEmpty) + { + NativeFunctions.DrawReversibleDesktopRect(m_OldOutlineRectangle, 3); + m_OldOutlineRectangle = Rectangle.Empty; + } + + if (pDockInfo.UseOutline && pDockInfo.objDockSite != null) + { + Rectangle r = pDockInfo.objDockSite.GetBarDockRectangle(this, ref pDockInfo); + if (!r.IsEmpty) + { + bPreview = false; + if (m_OutlineForm == null) + m_OutlineForm = CreateOutlineForm(); + NativeFunctions.SetWindowPos(m_OutlineForm.Handle, new IntPtr(NativeFunctions.HWND_TOP), r.X, r.Y, r.Width, r.Height, NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); + } + } + if (bPreview && m_OutlineForm != null) + { + m_OutlineForm.Visible = false; + } + + m_DragDockInfo = pDockInfo; + + if (bPreview) + { + //if(m_BarState==eBarState.Floating || this.LayoutType!=eLayoutType.DockContainer || pDockInfo.TabDockContainer!=null) + DockingHandler(pDockInfo, p); + } + } + else if (e.Button == System.Windows.Forms.MouseButtons.None) + { + if (m_BarState == eBarState.Floating) + { + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && ((e.X <= 2 && e.Y <= 2) || (e.X >= this.Width - 4 && e.Y >= this.Height - 4))) + this.Cursor = System.Windows.Forms.Cursors.SizeNWSE; + else if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && ((e.X >= this.Width - 2 && e.Y <= 2) || (e.X <= 4 && e.Y >= this.Height - 4))) + this.Cursor = System.Windows.Forms.Cursors.SizeNESW; + else if (e.X >= 0 && e.X <= 2 || e.X >= this.Width - 3 && e.X <= this.Width) + this.Cursor = System.Windows.Forms.Cursors.SizeWE; + else if (e.Y >= 0 && e.Y <= 2 || e.Y >= this.Height - 3 && e.Y <= this.Height) + this.Cursor = System.Windows.Forms.Cursors.SizeNS; + else if (this.Cursor == System.Windows.Forms.Cursors.SizeWE || this.Cursor == System.Windows.Forms.Cursors.SizeNS || this.Cursor == System.Windows.Forms.Cursors.SizeNWSE || this.Cursor == System.Windows.Forms.Cursors.SizeNESW) + this.Cursor = System.Windows.Forms.Cursors.Default; + } + //else if(m_BarState==eBarState.Docked && m_ItemContainer.LayoutType==eLayoutType.DockContainer && m_ItemContainer.Stretch) + //{ + // if((e.X<=2 && this.DockedSite.Dock==DockStyle.Right) || (e.X>=this.Width-2 && this.DockedSite.Dock==DockStyle.Left)) + // this.Cursor=Cursors.VSplit; + // else if((e.Y<=2 && this.DockedSite.Dock==DockStyle.Bottom) || (e.Y>=this.Height-2 && this.DockedSite.Dock==DockStyle.Top)) + // this.Cursor=Cursors.HSplit; + // else if(e.X<=2 && (this.DockedSite.Dock==DockStyle.Bottom || this.DockedSite.Dock==DockStyle.Top) && this.Left>0) + // this.Cursor=Cursors.VSplit; + // else if(e.Y<=2 && (this.DockedSite.Dock==DockStyle.Left || this.DockedSite.Dock==DockStyle.Right) && this.Top>0) + // this.Cursor=Cursors.HSplit; + // else if(this.Cursor==Cursors.HSplit || this.Cursor==Cursors.VSplit) + // this.Cursor=Cursors.Default; + //} + else if (m_BarState == eBarState.AutoHide && m_ItemContainer.LayoutType == eLayoutType.DockContainer && m_ItemContainer.Stretch) + { + if ((e.X <= 2 && m_LastDockSiteInfo.DockSide == DockStyle.Right) || (e.X >= this.Width - 2 && m_LastDockSiteInfo.DockSide == DockStyle.Left)) + this.Cursor = Cursors.VSplit; + else if ((e.Y <= 2 && m_LastDockSiteInfo.DockSide == DockStyle.Bottom) || (e.Y >= this.Height - 2 && m_LastDockSiteInfo.DockSide == DockStyle.Top)) + this.Cursor = Cursors.HSplit; + else if (e.X <= 2 && (m_LastDockSiteInfo.DockSide == DockStyle.Bottom || m_LastDockSiteInfo.DockSide == DockStyle.Top) && this.Left > 0) + this.Cursor = Cursors.VSplit; + else if (e.Y <= 2 && (m_LastDockSiteInfo.DockSide == DockStyle.Left || m_LastDockSiteInfo.DockSide == DockStyle.Right) && this.Top > 0) + this.Cursor = Cursors.HSplit; + else if (this.Cursor == Cursors.HSplit || this.Cursor == Cursors.VSplit) + this.Cursor = Cursors.Default; + } + else if (m_BarState == eBarState.Docked && m_GrabHandleStyle == eGrabHandleStyle.ResizeHandle) + { + if ((e.X > this.Location.X + this.Width - GrabHandleResizeWidth && this.RightToLeft == RightToLeft.No) || + (e.X < this.Location.X + +GrabHandleResizeWidth && this.RightToLeft == RightToLeft.Yes)) + { + Form form = this.FindForm(); + if (form != null && form.WindowState == FormWindowState.Maximized) + { + if (this.Cursor == Cursors.SizeNESW || this.Cursor == Cursors.SizeNWSE) + this.Cursor = Cursors.Default; + } + else + { + if (this.RightToLeft == RightToLeft.Yes) + this.Cursor = Cursors.SizeNESW; + else + this.Cursor = Cursors.SizeNWSE; + } + } + else if (this.Cursor == Cursors.SizeNESW || this.Cursor == Cursors.SizeNWSE) + this.Cursor = Cursors.Default; + } + + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.OfficeXP || m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2003 || m_ItemContainer.EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(m_ItemContainer.EffectiveStyle)) + { + if (!m_SystemButtons.CloseButtonRect.IsEmpty && m_SystemButtons.CloseButtonRect.Contains(e.X, e.Y)) + { + if (!m_SystemButtons.MouseOverClose) + { + m_SystemButtons.MouseOverClose = true; + PaintCloseButton(); + } + } + else if (m_SystemButtons.MouseOverClose) + { + m_SystemButtons.MouseOverClose = false; + PaintCloseButton(); + } + if (!m_SystemButtons.MaximizeButtonRect.IsEmpty && m_SystemButtons.MaximizeButtonRect.Contains(e.X, e.Y)) + { + if (!m_SystemButtons.MouseOverMaximize) + { + m_SystemButtons.MouseOverMaximize = true; + PaintMaximizeButton(); + } + } + else if (m_SystemButtons.MouseOverMaximize) + { + m_SystemButtons.MouseOverMaximize = false; + PaintMaximizeButton(); + } + if (!m_SystemButtons.CaptionButtonRect.IsEmpty && m_SystemButtons.CaptionButtonRect.Contains(e.X, e.Y)) + { + if (!m_SystemButtons.MouseOverCaption) + { + m_SystemButtons.MouseOverCaption = true; + PaintCaptionButton(); + } + } + else if (m_SystemButtons.MouseOverCaption) + { + m_SystemButtons.MouseOverCaption = false; + PaintCaptionButton(); + } + if (!m_SystemButtons.CustomizeButtonRect.IsEmpty && m_SystemButtons.CustomizeButtonRect.Contains(e.X, e.Y)) + { + if (!m_SystemButtons.MouseOverCustomize) + { + m_SystemButtons.MouseOverCustomize = true; + PaintCustomizeButton(); + } + } + else if (m_SystemButtons.MouseOverCustomize) + { + m_SystemButtons.MouseOverCustomize = false; + PaintCustomizeButton(); + } + if (!m_SystemButtons.AutoHideButtonRect.IsEmpty && m_SystemButtons.AutoHideButtonRect.Contains(e.X, e.Y)) + { + if (!m_SystemButtons.MouseOverAutoHide) + { + m_SystemButtons.MouseOverAutoHide = true; + PaintAutoHideButton(); + } + } + else if (m_SystemButtons.MouseOverAutoHide) + { + m_SystemButtons.MouseOverAutoHide = false; + PaintAutoHideButton(); + } + } + } + else if (e.Button == System.Windows.Forms.MouseButtons.Left && m_SizeWindow != 0 && m_BarState == eBarState.Floating) + { + System.Drawing.Size oldSize = this.ClientSize; + System.Drawing.Size newSize = System.Drawing.Size.Empty; + System.Drawing.Size minSize = MinimumDockSize(m_ItemContainer.Orientation); + if (m_SizeWindow == SIZE_NWN || m_SizeWindow == SIZE_NWS) + { + if (m_SizeWindow == SIZE_NWS) + newSize = RecalcSizeOnly(new System.Drawing.Size(e.X, e.Y)); + else + newSize = RecalcSizeOnly(new System.Drawing.Size(this.Width - e.X, this.Height - e.Y)); + if (!oldSize.Equals(newSize) && newSize.Width >= minSize.Width && newSize.Height >= minSize.Height) + { + if (m_SizeWindow == SIZE_NWS) + this.ClientSize = newSize; + else + { + m_Float.Location = new Point(m_Float.Left + (this.Width - newSize.Width), m_Float.Top + (this.Height - newSize.Height)); + this.ClientSize = newSize; + } + RecalcSize(); + this.Update(); + // Updates the parent form, there was a very bad lagging painting effect when dockable window is resized and the DotNetBar controls where behind it. + IOwner owner = m_Owner as IOwner; + if (owner != null && owner.ParentForm != null) + owner.ParentForm.Update(); + } + } + else if (m_SizeWindow == SIZE_NEN || m_SizeWindow == SIZE_NES) + { + if (m_SizeWindow == SIZE_NES) + newSize = RecalcSizeOnly(new System.Drawing.Size(this.Width - e.X, e.Y)); + else + newSize = RecalcSizeOnly(new System.Drawing.Size(e.X, this.Height - e.Y)); + if (!oldSize.Equals(newSize) && newSize.Width >= minSize.Width && newSize.Height >= minSize.Height) + { + if (m_SizeWindow == SIZE_NES) + { + m_Float.Location = new Point(m_Float.Left + (this.Width - newSize.Width), m_Float.Top); + this.ClientSize = newSize; + } + else + { + m_Float.Location = new Point(m_Float.Left, m_Float.Top + (this.Height - newSize.Height)); + this.ClientSize = newSize; + } + RecalcSize(); + this.Update(); + // Updates the parent form, there was a very bad lagging painting effect when dockable window is resized and the DotNetBar controls where behind it. + IOwner owner = m_Owner as IOwner; + if (owner != null && owner.ParentForm != null) + owner.ParentForm.Update(); + } + } + else if (m_SizeWindow == SIZE_E) + { + newSize = RecalcSizeOnly(new System.Drawing.Size(e.X, this.Height)); + if (!oldSize.Equals(newSize) && newSize.Width >= minSize.Width && newSize.Height >= minSize.Height) + { + this.ClientSize = newSize; + RecalcSize(); + this.Update(); + // Updates the parent form, there was a very bad lagging painting effect when dockable window is resized and the DotNetBar controls where behind it. + IOwner owner = m_Owner as IOwner; + if (owner != null && owner.ParentForm != null) + owner.ParentForm.Update(); + } + } + else if (m_SizeWindow == SIZE_W) + { + newSize = RecalcSizeOnly(new System.Drawing.Size(this.Width - e.X, this.Height)); + if (!oldSize.Equals(newSize) && newSize.Width >= minSize.Width && newSize.Height >= minSize.Height) + { + int iRight = m_Float.Right; + this.ClientSize = newSize; + RecalcSize(); + m_Float.Left = m_Float.Left + iRight - m_Float.Right; + this.Update(); + // Updates the parent form, there was a very bad lagging painting effect when dockable window is resized and the DotNetBar controls where behind it. + IOwner owner = m_Owner as IOwner; + if (owner != null && owner.ParentForm != null) + owner.ParentForm.Update(); + } + } + else if (m_SizeWindow == SIZE_S) + { + if (e.Y > 0) + { + if (m_ItemContainer.LayoutType == eLayoutType.TaskList || m_ItemContainer.LayoutType == eLayoutType.DockContainer) + newSize = RecalcSizeOnly(new System.Drawing.Size(this.Width, e.Y)); + else + newSize = RecalcSizeOnly(new System.Drawing.Size((int)(m_MouseDownSize.Width * ((float)m_MouseDownSize.Height / (float)e.Y)), this.Height)); + if (!oldSize.Equals(newSize) && newSize.Width >= minSize.Width && newSize.Height >= minSize.Height) + { + this.ClientSize = newSize; + RecalcSize(); + this.Update(); + // Updates the parent form, there was a very bad lagging painting effect when dockable window is resized and the DotNetBar controls where behind it. + IOwner owner = m_Owner as IOwner; + if (owner != null && owner.ParentForm != null) + owner.ParentForm.Update(); + } + } + } + else if (m_SizeWindow == SIZE_N) + { + if (e.Y != 0) + { + if (m_ItemContainer.LayoutType == eLayoutType.TaskList || m_ItemContainer.LayoutType == eLayoutType.DockContainer) + newSize = RecalcSizeOnly(new Size(this.Width, this.Height - e.Y)); + else + newSize = RecalcSizeOnly(new System.Drawing.Size((int)(m_MouseDownSize.Width * ((float)m_MouseDownSize.Height / (float)(this.Height - e.Y))), this.Height)); + if (!oldSize.Equals(newSize) && newSize.Width >= minSize.Width && newSize.Height >= minSize.Height) + { + int iBottom = m_Float.Bottom; + this.ClientSize = newSize; + RecalcSize(); + m_Float.Top = m_Float.Top + iBottom - m_Float.Bottom; + this.Update(); + // Updates the parent form, there was a very bad lagging painting effect when dockable window is resized and the DotNetBar controls where behind it. + IOwner owner = m_Owner as IOwner; + if (owner != null && owner.ParentForm != null) + owner.ParentForm.Update(); + } + } + } + m_FloatingRect = new Rectangle(this.Location, this.Size); + } + else if (e.Button == System.Windows.Forms.MouseButtons.Left && m_SizeWindow != 0 && m_BarState == eBarState.AutoHide || m_SizeWindow == SIZE_PARENTRESIZE && m_BarState == eBarState.Docked) //(m_BarState == eBarState.Docked || m_BarState == eBarState.AutoHide)) + { + System.Drawing.Size oldSize = this.ClientSize; + System.Drawing.Size newSize = System.Drawing.Size.Empty; + if (m_SizeWindow == SIZE_PARENTRESIZE) + { + if (this.RightToLeft == RightToLeft.No) + { + if (this.Parent != null && this.Parent.Parent != null) + { + Point pScreen = this.PointToScreen(new Point(e.X, e.Y)); + if (this.Parent.Parent.Parent != null) + { + Point pl = this.Parent.Parent.Parent.PointToScreen(this.Parent.Parent.Location); + this.Parent.Parent.Size = new Size(pScreen.X - pl.X + m_ResizeOffset.X, pScreen.Y - pl.Y + m_ResizeOffset.Y); + } + else + this.Parent.Parent.Size = new Size(pScreen.X - this.Parent.Parent.Location.X + m_ResizeOffset.X, pScreen.Y - this.Parent.Parent.Location.Y + m_ResizeOffset.Y); + IOwner owner = m_Owner as IOwner; + if (owner != null && owner.ParentForm != null) + owner.ParentForm.Update(); + } + else if (m_Owner == null && !(this.Parent is DockSite) && !(this.Parent is FloatingContainer)) + { + Form form = this.FindForm(); + if (form != null) + { + Point pScreen = this.PointToScreen(new Point(e.X, e.Y)); + form.Size = new Size(pScreen.X - form.Location.X + m_ResizeOffset.X, pScreen.Y - form.Location.Y + m_ResizeOffset.Y); + form.Update(); + } + } + } + else + { + if (this.Parent != null && this.Parent.Parent != null) + { + Point pScreen = this.PointToScreen(new Point(e.X, e.Y)); + if (this.Parent.Parent.Parent != null) + { + Point pl = this.Parent.Parent.Parent.PointToScreen(this.Parent.Parent.Location); + Rectangle b = this.Parent.Parent.Bounds; + b.X = pScreen.X - m_ResizeOffset.X; + b.Width += this.Parent.Parent.Left - b.X; + b.Height = pScreen.Y - pl.Y + m_ResizeOffset.Y; + this.Parent.Parent.Bounds = b; + } + else + { + Rectangle b = this.Parent.Parent.Bounds; + b.X = pScreen.X - m_ResizeOffset.X; + b.Width += this.Parent.Parent.Left - b.X; + b.Height = pScreen.Y - this.Parent.Parent.Location.Y + m_ResizeOffset.Y; + this.Parent.Parent.Bounds = b; + } + IOwner owner = m_Owner as IOwner; + if (owner != null && owner.ParentForm != null) + owner.ParentForm.Update(); + } + else if (m_Owner == null && !(this.Parent is DockSite) && !(this.Parent is FloatingContainer)) + { + Form form = this.FindForm(); + if (form != null) + { + Point pScreen = this.PointToScreen(new Point(e.X, e.Y)); + Rectangle b = form.Bounds; + + b.X = pScreen.X - m_ResizeOffset.X; + b.Width += form.Left - b.X; + b.Height = pScreen.Y - form.Location.Y + m_ResizeOffset.Y; + form.Bounds = b; + //Size = new Size(pScreen.X - form.Location.X + m_ResizeOffset.X, pScreen.Y - form.Location.Y + m_ResizeOffset.Y); + form.Update(); + } + } + } + } + else if (m_SizeWindow == SIZE_HSPLITRIGHT) + { + int formClientWidth = GetFormClientWidth(); + int mouseX = e.X; + int minClientSize = 32; + if (m_Owner is DotNetBarManager) minClientSize = ((DotNetBarManager)m_Owner).MinimumClientSize.Width; + + if (minClientSize > 0 && formClientWidth + mouseX < minClientSize) + mouseX = minClientSize - formClientWidth; + + if (formClientWidth + mouseX >= minClientSize || minClientSize == 0) + { + int oldMinWidth = m_ItemContainer.MinWidth; + m_ItemContainer.MinWidth = 0; + newSize = RecalcSizeOnly(new Size(this.Width - mouseX, this.Height)); + m_ItemContainer.MinWidth = oldMinWidth; + if (!oldSize.Equals(newSize)) + { + if (m_BarState == eBarState.AutoHide) + { + Rectangle oldRect = this.Bounds; + this.EnableRedraw = false; + try + { + m_ItemContainer.MinWidth = m_ItemContainer.WidthInternal - mouseX; + this.Width = this.Width - mouseX; + RecalcSize(); + this.Left = this.Left + (oldSize.Width - this.Size.Width); + } + finally + { + this.EnableRedraw = true; + } + if (this.Parent != null) + { + this.Parent.Invalidate(oldRect, true); + this.Parent.Invalidate(this.Bounds, true); + this.Parent.Update(); + } + else + this.Refresh(); + } + else + { + int iOldMinWidth = m_ItemContainer.MinWidth; + m_ItemContainer.MinWidth = m_ItemContainer.WidthInternal - mouseX; + + if (m_ItemContainer.MinWidth < iOldMinWidth) + SyncLineMinWidth(); + RecalcLayout(); + } + if (m_BarState == eBarState.AutoHide) + m_LastDockSiteInfo.DockedWidth = this.Width; + } + } + } + else if (m_SizeWindow == SIZE_HSPLITLEFT) + { + int formClientWidth = GetFormClientWidth(); + int mouseX = e.X; + int minClientSize = 32; + if (m_Owner is DotNetBarManager) minClientSize = ((DotNetBarManager)m_Owner).MinimumClientSize.Width; + + if (minClientSize > 0 && formClientWidth - (mouseX - this.Width) < minClientSize) + { + mouseX = formClientWidth + this.Width - minClientSize; + } + + if (formClientWidth - (mouseX - this.Width) >= minClientSize || minClientSize == 0) + { + int oldMinWidth = m_ItemContainer.MinWidth; + m_ItemContainer.MinWidth = 0; + newSize = RecalcSizeOnly(new Size(mouseX, this.Height)); + m_ItemContainer.MinWidth = oldMinWidth; + if (!oldSize.Equals(newSize)) + { + if (m_BarState == eBarState.AutoHide) + { + Rectangle oldRect = this.Bounds; + this.EnableRedraw = false; + try + { + m_ItemContainer.MinWidth = m_ItemContainer.WidthInternal + (mouseX - this.Width); + this.Width = this.Width + (mouseX - this.Width); + RecalcSize(); + } + finally + { + this.EnableRedraw = true; + } + if (this.Parent != null) + { + this.Parent.Invalidate(oldRect, true); + this.Parent.Invalidate(this.Bounds, true); + this.Parent.Update(); + } + else + this.Refresh(); + } + else + { + int iOldMinWidth = m_ItemContainer.MinWidth; + m_ItemContainer.MinWidth = m_ItemContainer.WidthInternal + (mouseX - this.Width); + if (m_ItemContainer.MinWidth < iOldMinWidth) + SyncLineMinWidth(); + RecalcLayout(); + } + if (m_BarState == eBarState.AutoHide) + m_LastDockSiteInfo.DockedWidth = this.Width; + } + } + } + else if (m_SizeWindow == SIZE_VSPLITBOTTOM) + { + int formClientHeight = GetFormClientHeight(); + int mouseY = e.Y; + int minClientSize = 32; + if (m_Owner is DotNetBarManager) minClientSize = ((DotNetBarManager)m_Owner).MinimumClientSize.Height; + + if (minClientSize > 0 && formClientHeight + mouseY < minClientSize) + mouseY = minClientSize - formClientHeight; + + if (formClientHeight + mouseY >= minClientSize || minClientSize == 0) + { + int oldMinHeight = m_ItemContainer.MinHeight; + m_ItemContainer.MinHeight = 0; + newSize = RecalcSizeOnly(new Size(this.Width, this.Height - mouseY)); + m_ItemContainer.MinHeight = oldMinHeight; + if (!oldSize.Equals(newSize)) + { + if (m_BarState == eBarState.AutoHide) + { + Rectangle oldRect = this.Bounds; + this.EnableRedraw = false; + try + { + m_ItemContainer.MinHeight = m_ItemContainer.HeightInternal - mouseY; + this.Height = this.Height - mouseY; + RecalcSize(); + this.Top = this.Top + (oldSize.Height - this.Height); + } + finally + { + this.EnableRedraw = true; + } + if (this.Parent != null) + { + this.Parent.Invalidate(oldRect, true); + this.Parent.Invalidate(this.Bounds, true); + this.Parent.Update(); + } + else + this.Refresh(); + } + else + { + int iOldMinHeight = m_ItemContainer.MinHeight; + Size minSize = this.MinimumDockSize(m_ItemContainer.Orientation); + if (m_ItemContainer.HeightInternal - mouseY >= minSize.Height) + m_ItemContainer.MinHeight = m_ItemContainer.HeightInternal - mouseY; + if (m_ItemContainer.MinHeight < iOldMinHeight) + SyncLineMinHeight(); + RecalcLayout(); + } + + if (m_BarState == eBarState.AutoHide) + m_LastDockSiteInfo.DockedHeight = this.Height; + } + } + } + else if (m_SizeWindow == SIZE_VSPLITTOP) + { + int formClientHeight = GetFormClientHeight(); + int mouseY = e.Y; + int minClientSize = 32; + if (m_Owner is DotNetBarManager) minClientSize = ((DotNetBarManager)m_Owner).MinimumClientSize.Height; + + if (minClientSize > 0 && formClientHeight - (mouseY - this.Height) < minClientSize) + mouseY = formClientHeight + this.Height - minClientSize; + + if (formClientHeight - (mouseY - this.Height) >= minClientSize || minClientSize == 0) + { + int oldMinHeight = m_ItemContainer.MinHeight; + m_ItemContainer.MinHeight = 0; + newSize = RecalcSizeOnly(new Size(this.Width, mouseY)); + m_ItemContainer.MinHeight = oldMinHeight; + if (!oldSize.Equals(newSize)) + { + if (m_BarState == eBarState.AutoHide) + { + Rectangle oldRect = this.Bounds; + this.EnableRedraw = false; + try + { + m_ItemContainer.MinHeight = m_ItemContainer.HeightInternal + (mouseY - this.Height); + this.Height = mouseY; + this.RecalcSize(); + } + finally + { + this.EnableRedraw = true; + } + if (this.Parent != null) + { + this.Parent.Invalidate(oldRect, true); + this.Parent.Invalidate(this.Bounds, true); + this.Parent.Update(); + } + else + this.Refresh(); + } + else + { + int iOldMinHeight = m_ItemContainer.MinHeight; + m_ItemContainer.MinHeight = m_ItemContainer.HeightInternal + (mouseY - this.Height); + if (m_ItemContainer.MinHeight < iOldMinHeight) + SyncLineMinHeight(); + RecalcLayout(); + } + + if (m_BarState == eBarState.AutoHide) + m_LastDockSiteInfo.DockedHeight = this.Height; + } + } + } + else if (m_SizeWindow == SIZE_HSPLIT && this.Parent.Controls.IndexOf(this) > 0) + { + Bar barLeft = GetPreviousVisibleBar(this); //this.Parent.Controls[iIndex] as Bar; + if (barLeft != null && barLeft.DockLine == this.DockLine) + { + System.Drawing.Size minLeftSize = GetAdjustedFullSize(barLeft.MinimumDockSize(eOrientation.Horizontal)); + System.Drawing.Size minThisSize = GetAdjustedFullSize(this.MinimumDockSize(eOrientation.Horizontal)); + int x = e.X; + if (barLeft.Width + x < minLeftSize.Width) + x += (minLeftSize.Width - (barLeft.Width + x)) - 1; + if (this.Width - x < minThisSize.Width) + x -= (minThisSize.Width - (this.Width - x)) + 1; + + if (barLeft.Width + x >= minLeftSize.Width && this.Width - x >= minThisSize.Width) + { + Size oldLeftBarSize = barLeft.Size; + Size newBarLeftSize = barLeft.RecalcSizeOnly(new Size(barLeft.Width + x, this.Height)); + newSize = this.RecalcSizeOnly(new Size(this.Width - x, this.Height)); + if (!oldLeftBarSize.Equals(newBarLeftSize) && !oldSize.Equals(newSize)) + { + this.SplitDockWidth = 0; + barLeft.SplitDockWidth = barLeft.Width + x; + foreach (Control c in this.Parent.Controls) + { + if (c != this && c != barLeft && c.Visible && c is Bar) + { + Bar b = c as Bar; + if (b.DockLine == this.DockLine && b.SplitDockHeight == 0) + b.SplitDockWidth = b.Width; + } + } + RecalcLayout(); + } + } + } + } + else if (m_SizeWindow == SIZE_VSPLIT && this.Parent.Controls.IndexOf(this) > 0) + { + // Resize two bars that are docked on the same line, this bar is always on the right side + //int iIndex=this.Parent.Controls.IndexOf(this)-1; // Index of the control to the left + Bar barLeft = GetPreviousVisibleBar(this); //this.Parent.Controls[iIndex] as Bar; + if (barLeft != null && barLeft.DockLine == this.DockLine) + { + System.Drawing.Size minLeftSize = GetAdjustedFullSize(barLeft.MinimumDockSize(eOrientation.Horizontal)); + System.Drawing.Size minThisSize = GetAdjustedFullSize(this.MinimumDockSize(eOrientation.Horizontal)); + int y = e.Y; + if (barLeft.Height + y < minLeftSize.Height) + y += (minLeftSize.Height - (barLeft.Height + y)) - 1; + if (this.Height - y < minThisSize.Height) + y -= minThisSize.Height - (this.Height - y) + 1; + if (barLeft.Height + y >= minLeftSize.Height && this.Height - y >= minThisSize.Height) + { + Size oldLeftBarSize = barLeft.Size; + Size newBarLeftSize = barLeft.RecalcSizeOnly(new Size(barLeft.Width, this.Height + y)); + newSize = this.RecalcSizeOnly(new Size(this.Width, this.Height - y)); + if (!oldLeftBarSize.Equals(newBarLeftSize) && !oldSize.Equals(newSize)) + { + this.SplitDockHeight = 0; + barLeft.SplitDockHeight = barLeft.Height + y; + foreach (Control c in this.Parent.Controls) + { + if (c != this && c != barLeft && c.Visible && c is Bar) + { + Bar b = c as Bar; + if (b.DockLine == this.DockLine && b.SplitDockHeight == 0) + b.SplitDockHeight = b.Height; + } + } + RecalcLayout(); + } + } + } + } + } + + if (m_BarState == eBarState.Popup && m_ParentItem != null && m_ParentItem.DesignMode && e.Button == System.Windows.Forms.MouseButtons.Left && (Math.Abs(e.X - m_MouseDownPt.X) >= 2 || Math.Abs(e.Y - m_MouseDownPt.Y) >= 2 || m_DragDropInProgress)) + { + BaseItem focus = m_FocusItem; + if (m_Owner is IOwner) + focus = ((IOwner)m_Owner).GetFocusItem(); + ISite site = this.GetSite(); + if (site != null && focus != null) + { + DesignTimeMouseMove(e); + } + } + + base.OnMouseMove(e); + if (m_ItemContainer.SubItems.Count == 0) + { + m_InMouseMove = false; + return; + } + if (!m_MoveWindow && m_SizeWindow == 0) + m_ItemContainer.InternalMouseMove(e); + m_InMouseMove = false; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public Form CreateOutlineForm() + { + return BarFunctions.CreateOutlineForm(); + } + private Bar GetPreviousVisibleBar(Bar startBar) + { + if (this.Parent == null) + return null; + int iIndex = this.Parent.Controls.IndexOf(this) - 1; + if (iIndex >= 0) + { + for (int i = iIndex; i >= 0; i--) + { + if (this.Parent.Controls[i].Visible) + return this.Parent.Controls[i] as Bar; + } + } + return null; + } + + private Bar GetNextVisibleBar(Bar startBar) + { + if (this.Parent == null) + return null; + int iIndex = this.Parent.Controls.IndexOf(this) + 1; + if (iIndex >= 0) + { + for (int i = iIndex; i < this.Parent.Controls.Count; i++) + { + if (this.Parent.Controls[i].Visible) + return this.Parent.Controls[i] as Bar; + } + } + return null; + } + + private int GetFormClientWidth() + { + IOwner owner = m_Owner as IOwner; + if (owner == null || this.Parent == null || (this.Parent.Parent == null && m_BarState != eBarState.AutoHide)) + return 0; + + Control parentControl = this.Parent.Parent; + if (m_BarState == eBarState.AutoHide) + parentControl = owner.ParentForm; + if (parentControl == null && owner.ParentForm == null && m_Owner is DotNetBarManager) + parentControl = ((DotNetBarManager)m_Owner).ParentUserControl; + + if (parentControl == null) + return 0; + int width = parentControl.ClientSize.Width; + + foreach (Control ctrl in parentControl.Controls) + { + if (ctrl.Visible && (ctrl.Dock == DockStyle.Left || ctrl.Dock == DockStyle.Right)) + width -= ctrl.Width; + } + if (m_BarState == eBarState.AutoHide && this.Visible) + width -= this.Width; + return width; + } + + private int GetFormClientHeight() + { + IOwner owner = m_Owner as IOwner; + if (owner == null || this.Parent == null || (this.Parent.Parent == null && m_BarState != eBarState.AutoHide)) + return 0; + Control parentControl = null; + if (m_BarState == eBarState.AutoHide) + parentControl = owner.ParentForm; + else + parentControl = this.Parent.Parent; + + if (parentControl == null && owner.ParentForm == null && m_Owner is DotNetBarManager) + parentControl = ((DotNetBarManager)m_Owner).ParentUserControl; + + if (parentControl == null) + return 0; + int height = parentControl.ClientSize.Height; + + foreach (Control ctrl in parentControl.Controls) + { + if (ctrl.Visible && (ctrl.Dock == DockStyle.Top || ctrl.Dock == DockStyle.Bottom)) + height -= ctrl.Height; + } + if (m_BarState == eBarState.AutoHide && this.Visible) + height -= this.Height; + return height; + } + + internal void SyncLineMinWidth() + { + if (this.Parent == null) + return; + foreach (Control ctrl in this.Parent.Controls) + { + Bar bar = ctrl as Bar; + if (bar == null || bar == this || bar.DockLine != m_DockLine) + continue; + bar.ItemsContainer.MinWidth = m_ItemContainer.MinWidth; + } + } + internal void SyncLineMinHeight() + { + if (this.Parent == null) + return; + foreach (Control ctrl in this.Parent.Controls) + { + Bar bar = ctrl as Bar; + if (bar == null || bar == this || bar.DockLine != m_DockLine) + continue; + bar.ItemsContainer.MinHeight = m_ItemContainer.MinHeight; + } + } + + protected override void OnMouseHover(EventArgs e) + { + base.OnMouseHover(e); + InternalMouseHover(); + } + + internal void InternalMouseHover() + { + if (!m_MoveWindow) + { + if (Control.MouseButtons == MouseButtons.Left) + { + Point pClient = this.PointToClient(Control.MousePosition); + if (!this.ClientRectangle.Contains(pClient)) + { + IOwnerMenuSupport menu = this.Owner as IOwnerMenuSupport; + if (menu != null) + { + if (menu.RelayMouseHover()) + return; + } + } + } + m_ItemContainer.InternalMouseHover(); + + if (m_SystemButtons.MouseOverAutoHide) + { + using (LocalizationManager lm = new LocalizationManager(m_Owner as IOwnerLocalize)) + { + string tip = lm.GetLocalizedString(LocalizationKeys.BarAutoHideButtonTooltip); + if (tip != "") + ShowToolTip(tip); + } + } + else if (m_SystemButtons.MouseOverCustomize) + { + using (LocalizationManager lm = new LocalizationManager(m_Owner as IOwnerLocalize)) + { + string tip = lm.GetLocalizedString(LocalizationKeys.BarCustomizeButtonTooltip); + if (tip != "") + ShowToolTip(tip); + } + } + else if (m_SystemButtons.MouseOverClose) + { + using (LocalizationManager lm = new LocalizationManager(m_Owner as IOwnerLocalize)) + { + string tip = lm.GetLocalizedString(LocalizationKeys.BarCloseButtonTooltip); + if (tip != "") + ShowToolTip(tip); + } + } + else if (m_SystemButtons.MouseOverMaximize) + { + using (LocalizationManager lm = new LocalizationManager(m_Owner as IOwnerLocalize)) + { + string tip = lm.GetLocalizedString(LocalizationKeys.BarMaximizeButtonTooltip); + if (!string.IsNullOrEmpty(tip)) + ShowToolTip(tip); + } + } + } + } + + protected override void OnMouseLeave(EventArgs e) + { + // If we had hot sub item pass the mouse leave message to it... + if (this.Cursor != System.Windows.Forms.Cursors.Arrow) + this.Cursor = System.Windows.Forms.Cursors.Arrow; + + if (m_SystemButtons.MouseOverClose) + { + m_SystemButtons.MouseOverClose = false; + PaintCloseButton(); + } + if (m_SystemButtons.MouseOverMaximize) + { + m_SystemButtons.MouseOverMaximize = false; + PaintMaximizeButton(); + } + if (m_SystemButtons.MouseOverCaption) + { + m_SystemButtons.MouseOverCaption = false; + PaintCaptionButton(); + } + if (m_SystemButtons.MouseOverCustomize) + { + m_SystemButtons.MouseOverCustomize = false; + PaintCustomizeButton(); + } + if (m_SystemButtons.MouseOverAutoHide) + { + m_SystemButtons.MouseOverAutoHide = false; + PaintAutoHideButton(); + } + + if (!m_MoveWindow) + m_ItemContainer.InternalMouseLeave(); + + base.OnMouseLeave(e); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + m_MouseDownPt = new Point(e.X, e.Y); + m_MouseDownSize = this.Size; + HideToolTip(); + if (e.Button == MouseButtons.Left && !m_SystemButtons.CustomizeButtonRect.IsEmpty && m_SystemButtons.CustomizeButtonRect.Contains(m_MouseDownPt) && !this.DesignMode && !m_ItemContainer.DesignMode) + { + if (m_CustomizeMenu != null) + { + if (m_CustomizeMenu.GetOwner() == null) + m_CustomizeMenu.SetOwner(m_Owner); + Point popupLocation; + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + popupLocation = new Point(0, 16); + else + popupLocation = new Point(m_SystemButtons.CustomizeButtonRect.Left, m_SystemButtons.CustomizeButtonRect.Bottom); + if (popupLocation.X < 0) + popupLocation.X = 0; + popupLocation = this.PointToScreen(popupLocation); + m_CustomizeMenu.SetSourceControl(this); + m_CustomizeMenu.Popup(popupLocation); + base.OnMouseDown(e); + return; + } + else + { + foreach (BaseItem objItem in m_ItemContainer.SubItems) + { + if (objItem is CustomizeItem && !objItem.Expanded) + { + if (m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2000) + ((CustomizeItem)objItem).PopupLocation = new Point(this.Left - 128, this.Top + 16); + else + ((CustomizeItem)objItem).PopupLocation = new Point(m_SystemButtons.CustomizeButtonRect.Left, m_SystemButtons.CustomizeButtonRect.Bottom); + + objItem.Expanded = true; + base.OnMouseDown(e); + return; + } + } + } + } + else if (e.Button == MouseButtons.Left && !m_SystemButtons.CloseButtonRect.IsEmpty && m_SystemButtons.CloseButtonRect.Contains(e.X, e.Y)) + { + m_SystemButtons.MouseDownClose = true; + PaintCloseButton(); + base.OnMouseDown(e); + return; + } + else if (e.Button == MouseButtons.Left && !m_SystemButtons.MaximizeButtonRect.IsEmpty && m_SystemButtons.MaximizeButtonRect.Contains(e.X, e.Y)) + { + m_SystemButtons.MouseDownMaximize = true; + PaintMaximizeButton(); + base.OnMouseDown(e); + return; + } + else if (e.Button == MouseButtons.Left && !m_SystemButtons.CaptionButtonRect.IsEmpty && m_SystemButtons.CaptionButtonRect.Contains(e.X, e.Y)) + { + m_SystemButtons.MouseDownCaption = true; + PaintCaptionButton(); + base.OnMouseDown(e); + return; + } + else if (e.Button == MouseButtons.Left && !m_SystemButtons.AutoHideButtonRect.IsEmpty && m_SystemButtons.AutoHideButtonRect.Contains(e.X, e.Y)) + { + m_SystemButtons.MouseDownAutoHide = true; + PaintAutoHideButton(); + base.OnMouseDown(e); + return; + } + else if (e.Button == System.Windows.Forms.MouseButtons.Left && m_BarState == eBarState.Floating) + { + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && e.X <= 4 && e.Y <= 4) + m_SizeWindow = SIZE_NWN; + else if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && e.X >= this.Width - 4 && e.Y >= this.Height - 4) + m_SizeWindow = SIZE_NWS; + else if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && e.X >= this.Width - 4 && e.Y <= 4) + m_SizeWindow = SIZE_NEN; + else if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && e.X <= 4 && e.Y >= this.Height - 4) + m_SizeWindow = SIZE_NES; + else if (e.X >= 0 && e.X <= 2) + m_SizeWindow = SIZE_W; + else if (e.X >= this.Width - 3 && e.X <= this.Width) + m_SizeWindow = SIZE_E; + else if (e.Y >= 0 && e.Y <= 2) + m_SizeWindow = SIZE_N; + else if (e.Y >= this.Height - 3 && e.Y <= this.Height) + m_SizeWindow = SIZE_S; + } + //else if(e.Button==System.Windows.Forms.MouseButtons.Left && m_BarState==eBarState.Docked && m_ItemContainer.LayoutType==eLayoutType.DockContainer && m_ItemContainer.Stretch) + //{ + // if(this.DockedSite.Dock==DockStyle.Right && e.X<=2) + // m_SizeWindow=SIZE_HSPLITRIGHT; + // else if(this.DockedSite.Dock==DockStyle.Left && e.X>=this.Width-2) + // m_SizeWindow=SIZE_HSPLITLEFT; + // else if(this.DockedSite.Dock==DockStyle.Bottom && e.Y<=2) + // m_SizeWindow=SIZE_VSPLITBOTTOM; + // else if(this.DockedSite.Dock==DockStyle.Top && e.Y>=this.Height-2) + // m_SizeWindow=SIZE_VSPLITTOP; + // else if((this.DockedSite.Dock==DockStyle.Bottom || this.DockedSite.Dock==DockStyle.Top) && e.X<=2 && this.Left>0) + // m_SizeWindow=SIZE_HSPLIT; + // else if((this.DockedSite.Dock==DockStyle.Left || this.DockedSite.Dock==DockStyle.Right) && e.Y<=2 && this.Top>0) + // m_SizeWindow=SIZE_VSPLIT; + //} + else if (e.Button == System.Windows.Forms.MouseButtons.Left && m_BarState == eBarState.AutoHide && m_ItemContainer.LayoutType == eLayoutType.DockContainer && m_ItemContainer.Stretch) + { + if (m_LastDockSiteInfo.DockSide == DockStyle.Right && e.X <= 2) + m_SizeWindow = SIZE_HSPLITRIGHT; + else if (m_LastDockSiteInfo.DockSide == DockStyle.Left && e.X >= this.Width - 2) + m_SizeWindow = SIZE_HSPLITLEFT; + else if (m_LastDockSiteInfo.DockSide == DockStyle.Bottom && e.Y <= 2) + m_SizeWindow = SIZE_VSPLITBOTTOM; + else if (m_LastDockSiteInfo.DockSide == DockStyle.Top && e.Y >= this.Height - 2) + m_SizeWindow = SIZE_VSPLITTOP; + else if ((m_LastDockSiteInfo.DockSide == DockStyle.Bottom || m_LastDockSiteInfo.DockSide == DockStyle.Top) && e.X <= 2 && this.Left > 0) + m_SizeWindow = SIZE_HSPLIT; + else if ((m_LastDockSiteInfo.DockSide == DockStyle.Left || m_LastDockSiteInfo.DockSide == DockStyle.Right) && e.Y <= 2 && this.Top > 0) + m_SizeWindow = SIZE_VSPLIT; + } + else if (e.Button == MouseButtons.Right && this.CanCustomize && !m_ItemContainer.DesignMode && m_BarState != eBarState.Popup && !m_MoveWindow) + { + DotNetBarManager owner = m_Owner as DotNetBarManager; + if (owner != null) + { + IOwnerBarSupport ownersupport = m_Owner as IOwnerBarSupport; + if (ownersupport != null) + ownersupport.BarContextMenu(this, e); + } + } + + if (e.Button == MouseButtons.Left && m_BarState == eBarState.Docked && this.m_GrabHandleStyle == eGrabHandleStyle.ResizeHandle + && (m_MouseDownPt.X > this.Location.X + this.Width - GrabHandleResizeWidth) && this.RightToLeft == RightToLeft.No) + { + Form formParent = this.FindForm(); + if (formParent != null && formParent.WindowState != FormWindowState.Maximized || formParent == null) + { + // Start resizing parent window... + this.Capture = true; + this.Cursor = System.Windows.Forms.Cursors.SizeNWSE; + m_SizeWindow = SIZE_PARENTRESIZE; + Point p = this.PointToScreen(m_MouseDownPt); + if (this.Parent != null && this.Parent.Parent != null) + { + p = this.Parent.Parent.PointToClient(p); + m_ResizeOffset = new Point(this.Parent.Parent.Width - p.X, this.Parent.Parent.ClientRectangle.Height - p.Y); + } + else if (m_Owner == null && !(this.Parent is DockSite) && !(this.Parent is FloatingContainer)) + { + if (formParent != null) + { + p = formParent.PointToClient(p); + m_ResizeOffset = new Point(formParent.Width - p.X, formParent.ClientRectangle.Height - p.Y); + } + } + } + } + else if (e.Button == MouseButtons.Left && m_BarState == eBarState.Docked && this.m_GrabHandleStyle == eGrabHandleStyle.ResizeHandle + && (m_MouseDownPt.X < this.Location.X + GrabHandleResizeWidth) && this.RightToLeft == RightToLeft.Yes) + { + Form formParent = this.FindForm(); + if (formParent != null && formParent.WindowState != FormWindowState.Maximized || formParent == null) + { + // Start resizing parent window... + this.Capture = true; + this.Cursor = System.Windows.Forms.Cursors.SizeNESW; + m_SizeWindow = SIZE_PARENTRESIZE; + Point pointMouseDown = m_MouseDownPt; + if (formParent.GetType().GetProperty("RightToLeftLayout") != null) + { + if ((bool)TypeDescriptor.GetProperties(formParent)["RightToLeftLayout"].GetValue(formParent)) + { + // Reverse it + pointMouseDown.X = this.Width - pointMouseDown.X; + } + } + + Point p = this.PointToScreen(pointMouseDown); + if (this.Parent != null && this.Parent.Parent != null) + { + p = this.Parent.Parent.PointToClient(p); + m_ResizeOffset = new Point(p.X, this.Parent.Parent.ClientRectangle.Height - p.Y); + } + else if (m_Owner == null && !(this.Parent is DockSite) && !(this.Parent is FloatingContainer)) + { + if (formParent != null) + { + p = formParent.PointToClient(p); + m_ResizeOffset = new Point(p.X, formParent.ClientRectangle.Height - p.Y); + } + } + } + } + + if (e.Button == MouseButtons.Left && _CanMove && !m_GrabHandleRect.IsEmpty && m_GrabHandleRect.Contains(m_MouseDownPt) && m_SizeWindow == 0 && !m_AutoHideState && !(m_CustomizeMenu != null && m_CustomizeMenu.Expanded)) + { + this.Cursor = System.Windows.Forms.Cursors.SizeAll; + this.Capture = true; + m_MoveWindow = true; + } + + if (m_BarState == eBarState.Popup && m_ParentItem != null && m_ParentItem.DesignMode) + { + DesignTimeMouseDown(e); + } + else + m_ItemContainer.InternalMouseDown(e); + + base.OnMouseDown(e); + } + + internal bool IsSizingWindow + { + get { return m_SizeWindow != 0; } + } + internal void InternalMouseUp(MouseEventArgs e) + { + this.OnMouseUp(e); + } + + internal void CloseBar() + { + BarClosingEventArgs closingArgs = new BarClosingEventArgs(); + InvokeBarClosing(closingArgs); + if (!closingArgs.Cancel) + { + if (this.AutoHide) + this.AutoHide = false; + this.HideBar(); + IOwner owner = this.Owner as IOwner; + if (owner.ParentForm != null && !owner.ParentForm.ContainsFocus) + owner.ParentForm.Focus(); + InvokeUserVisibleChanged(); + } + } + + protected override void OnMouseUp(MouseEventArgs e) + { + if (m_MoveWindow || m_SizeWindow != 0) + this.Cursor = System.Windows.Forms.Cursors.Default; + + if (m_DragDropInProgress) + { + DesignTimeMouseUp(e); + } + + if (m_MoveWindow) + { + EndDocking(false, new Point(e.X, e.Y)); + } + else if (e.Button == MouseButtons.Left && !m_SystemButtons.CloseButtonRect.IsEmpty && m_SystemButtons.CloseButtonRect.Contains(m_MouseDownPt)) + { + m_SystemButtons.MouseDownClose = false; + PaintCloseButton(); + if (m_SystemButtons.CloseButtonRect.Contains(e.X, e.Y)) + { + if (m_CloseSingleTab && this.SelectedDockContainerItem != null) + CloseDockTab(this.SelectedDockContainerItem); + else + CloseBar(); + } + } + else if (e.Button == MouseButtons.Left && !m_SystemButtons.MaximizeButtonRect.IsEmpty && m_SystemButtons.MaximizeButtonRect.Contains(m_MouseDownPt)) + { + m_SystemButtons.MouseDownMaximize = false; + if (m_SystemButtons.MaximizeButtonRect.Contains(e.X, e.Y)) + { + if (this.Parent is FloatingContainer) + { + this.IsMaximized = !this.IsMaximized; + } + } + PaintMaximizeButton(); + } + else if (e.Button == MouseButtons.Left && !m_SystemButtons.CaptionButtonRect.IsEmpty && m_SystemButtons.CaptionButtonRect.Contains(m_MouseDownPt)) + { + m_SystemButtons.MouseDownCaption = false; + PaintCaptionButton(); + if (m_SystemButtons.CaptionButtonRect.Contains(e.X, e.Y)) + { + InvokeCaptionButtonClick(); + if (m_AutoCreateCaptionMenu) + { + ToggleCaptionMenu(); + PaintCaptionButton(); + } + } + } + else if (e.Button == MouseButtons.Left && !m_SystemButtons.AutoHideButtonRect.IsEmpty && m_SystemButtons.AutoHideButtonRect.Contains(m_MouseDownPt)) + { + m_SystemButtons.MouseDownAutoHide = false; + PaintAutoHideButton(); + if (m_SystemButtons.AutoHideButtonRect.Contains(e.X, e.Y)) + { + m_IgnoreAnimation = false; + this.AutoHide = !this.AutoHide; + } + } + m_MoveWindow = false; + m_SizeWindow = 0; + + if (m_ItemContainer != null) + m_ItemContainer.InternalMouseUp(e); + + base.OnMouseUp(e); + } + + private bool _IsMaximized = false; + /// + /// Gets or sets whether floating dockable window is maximized. + /// + [Browsable(false)] + public bool IsMaximized + { + get { return _IsMaximized; } + set + { + if (value != _IsMaximized) + { + if (!(this.Parent is FloatingContainer) || this.LayoutType != eLayoutType.DockContainer) + throw new InvalidOperationException("Bar is not dockable window or its not floating"); + bool oldValue = _IsMaximized; + _IsMaximized = value; + OnIsMaximizedChanged(oldValue, value); + } + } + } + + private Rectangle _RestoredBounds = Rectangle.Empty; + /// + /// Called when IsMaximized property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnIsMaximizedChanged(bool oldValue, bool newValue) + { + FloatingContainer form = (FloatingContainer)this.Parent; + if (!newValue) + { + this.ClientSize = _RestoredBounds.Size; + this.Location = _RestoredBounds.Location; + //form.WindowState = FormWindowState.Normal; + } + else + { + _RestoredBounds = new Rectangle(m_Float.Location, this.ClientSize); + ScreenInformation screen = BarFunctions.ScreenFromControl(m_Float); + if (screen != null) + { + this.ClientSize = screen.WorkingArea.Size; + this.Location = screen.WorkingArea.Location; + } + //form.WindowState = FormWindowState.Maximized; + } + //this.ClientSize = form.ClientSize; + this.RecalcSize(); + this.Update(); + //OnPropertyChanged(new PropertyChangedEventArgs("IsMaximized")); + + } + + private void EndDocking(bool revertLast, Point mousePos) + { + if (this.Capture) + this.Capture = false; + + this.Cursor = System.Windows.Forms.Cursors.Default; + + IOwnerBarSupport barsupport = this.Owner as IOwnerBarSupport; + if (barsupport != null) + barsupport.DockComplete(); + + if (m_DragDockInfo.IsEmpty()) + { + m_MoveWindow = false; + return; + } + + if (m_TempTabBar != null || m_DragDockInfo.TabDockContainer != null) + { + DisposeDockingPreview(); + + Bar targetBar = m_TempTabBar; + if (targetBar == null) + targetBar = m_DragDockInfo.TabDockContainer; + + RemoveTempTabBarItems(); + if (m_DragDockInfo.TabDockContainer != this) + { + if (m_DockTabTearOffIndex == -1) + { + System.Collections.ArrayList list = new System.Collections.ArrayList(m_ItemContainer.SubItems.Count); + m_ItemContainer.SubItems.CopyTo(list); + DockContainerItem firstItem = null; + Form f = targetBar.FindForm(); + if (f != null) f.ActiveControl = targetBar; + foreach (BaseItem item in list) + { + DockContainerItem dockitem = item as DockContainerItem; + if (dockitem != null) + { + if (firstItem == null) firstItem = dockitem; + dockitem.Displayed = false; + if (dockitem.OriginalBarName == "") + { + dockitem.OriginalBarName = this.Name; + dockitem.OriginalPosition = m_ItemContainer.SubItems.IndexOf(dockitem); + } + m_ItemContainer.SubItems.Remove(dockitem); + targetBar.Items.Add(dockitem); + } + } + targetBar.RecalcLayout(); + + if (firstItem != null) + { + targetBar.SelectedDockContainerItem = firstItem; + //if (f != null && firstItem.Control!=null) f.ActiveControl = firstItem.Control; + } + targetBar.InvokeBarDockEvents(); + + DotNetBarManager manager = m_Owner as DotNetBarManager; + if (manager != null) + { + m_MoveWindow = false; + targetBar = null; + + if (this.CustomBar) + { + manager.Bars.Remove(this); + this.Dispose(); + } + else + { + this.Visible = false; + } + + if (manager.ParentForm != null) + manager.ParentForm.Activate(); + return; + } + } + else + { + Form f = targetBar.FindForm(); + if (f != null) f.ActiveControl = targetBar; + DockContainerItem dockitem = m_ItemContainer.SubItems[m_DockTabTearOffIndex] as DockContainerItem; + dockitem.Displayed = false; + m_ItemContainer.SubItems.Remove(dockitem); + targetBar.Items.Add(dockitem); + + targetBar.SelectedDockContainerItem = dockitem; + targetBar.RecalcLayout(); + //if (f != null && dockitem.Control != null) f.ActiveControl = dockitem.Control; + targetBar.InvokeBarDockEvents(); + } + } + m_TempTabBar = null; + m_DockTabTearOffIndex = -1; + m_MoveWindow = false; + m_DragDockInfo = new DockSiteInfo(); + return; + } + + if (m_DockTabTearOffIndex != -1) + { + DisposeDockingPreview(); + if (revertLast) + DockingHandler(m_LastDockSiteInfo, this.PointToScreen(new Point(mousePos.X, mousePos.Y))); + else + { + DockContainerItem dc = (DockContainerItem)this.Items[m_DockTabTearOffIndex]; + Bar bar = TearOffDockContainerItem(dc, false); + bar.DockingHandler(m_DragDockInfo, this.PointToScreen(new Point(mousePos.X, mousePos.Y))); + Form f = this.FindForm(); + if (f != null && dc != null && dc.Control != null) + { + f.ActiveControl = dc.Control; + } + } + m_DragDockInfo = new DockSiteInfo(); + m_DockTabTearOffIndex = -1; + } + else + { + if (!m_OldOutlineRectangle.IsEmpty || m_OutlineForm != null) + { + DisposeDockingPreview(); + if (revertLast) + { + if (this.LayoutType == eLayoutType.Toolbar) + DockingHandler(m_LastDockSiteInfo, this.PointToScreen(new Point(mousePos.X, mousePos.Y))); + } + else + DockingHandler(m_DragDockInfo, this.PointToScreen(new Point(mousePos.X, mousePos.Y))); + m_DragDockInfo = new DockSiteInfo(); + } + else if (revertLast) + { + DockingHandler(m_LastDockSiteInfo, this.PointToScreen(new Point(mousePos.X, mousePos.Y))); + m_DragDockInfo = new DockSiteInfo(); + } + } + + m_MoveWindow = false; + } + + private void DisposeDockingPreview() + { + if (!m_OldOutlineRectangle.IsEmpty || m_OutlineForm != null) + { + if (!m_OldOutlineRectangle.IsEmpty) + { + NativeFunctions.DrawReversibleDesktopRect(m_OldOutlineRectangle, DRAGRECTANGLE_WIDTH); + m_OldOutlineRectangle = Rectangle.Empty; + } + if (m_OutlineForm != null) + { + m_OutlineForm.Visible = false; + m_OutlineForm.Dispose(); + m_OutlineForm = null; + } + } + } + + internal Bar StartTabDrag() + { + if (m_TabDockItems.SelectedTab == null) + return null; + DockContainerItem item = m_TabDockItems.SelectedTab.AttachedItem as DockContainerItem; + if (item == null) + return null; + DotNetBarManager manager = m_Owner as DotNetBarManager; + if (manager == null) + return null; + + if (this.VisibleItemCount == 1 && this.GrabHandleStyle == eGrabHandleStyle.None) + { + this.StartBarMove(); + return this; + } + else if (!this.CanUndock) + { + m_DockTabTearOffIndex = this.Items.IndexOf(item); + this.StartBarMove(); + return this; + } + + Bar bar = TearOffDockContainerItem(item, true); + bar.InitalFloatLocation = Point.Empty; + bar.StartBarMove(); + return bar; + } + + internal Bar TearOffDockContainerItem(DockContainerItem item, bool floatBar) + { + return TearOffDockContainerItem(item, floatBar, new Point(Control.MousePosition.X - 32, Control.MousePosition.Y - 8)); + } + internal Bar TearOffDockContainerItem(DockContainerItem item, bool floatBar, Point initialFloatLocation) + { + Form f = this.FindForm(); + if (f != null) + { + f.ActiveControl = this; + } + DotNetBarManager manager = m_Owner as DotNetBarManager; + m_ItemContainer.SubItems.Remove(item); + this.RecalcLayout(); + Bar bar = BarFunctions.CreateDuplicateDockBar(this); + bar.Text = item.Text; + + bar.InitalFloatLocation = initialFloatLocation; + + if (manager.Bars.Contains(item.Name)) + { + string name = item.Name; + int i = 0; + while (manager.Bars.Contains(name + i.ToString())) + i++; + bar.Name = name + i.ToString(); + } + else + bar.Name = item.Name; + + bar.Items.Add(item); + manager.Bars.Add(bar); + + if (floatBar) + { + bar.DockSide = eDockSide.None; + bar.Location = initialFloatLocation; + } + + bar.LastDockSide = this.DockSide; + bar.m_LastDockSiteInfo.objDockSite = this.Parent as DockSite; + bar.m_LastDockSiteInfo.LastRelativeDockToBar = this; + bar.m_LastDockSiteInfo.LastDockSiteSide = this.DockSide; + + bar.CustomBar = true; + + IOwnerBarSupport ownerBar = m_Owner as IOwnerBarSupport; + if (ownerBar != null) + { + if (ownerBar.ApplyDocumentBarStyle && this.DockSide == eDockSide.Document) + BarFunctions.RestoreAutoDocumentBarStyle(bar); //BarFunctions.ApplyAutoDocumentBarStyle(bar); + ownerBar.InvokeBarTearOff(bar, new EventArgs()); + } + + return bar; + } + + internal void StartBarMove() + { + m_MouseDownPt = this.PointToClient(Control.MousePosition); + m_MouseDownSize = this.Size; + this.Cursor = System.Windows.Forms.Cursors.SizeAll; + m_MoveWindow = true; + } + + internal void InvokeUserVisibleChanged() + { + if (UserVisibleChanged != null) + UserVisibleChanged(this, new EventArgs()); + } + + private void InvokeAutoHideChanged() + { + EventArgs e = new EventArgs(); + if (AutoHideChanged != null) + AutoHideChanged(this, e); + IOwnerBarSupport barSupp = m_Owner as IOwnerBarSupport; + if (barSupp != null) + barSupp.InvokeAutoHideChanged(this, e); + OnBarStateChanged(new BarStateChangedEventArgs(this, eBarStateChange.AutoHideChanged)); + } + + /// + /// Closes the DockContainerItem with event source set to Code. + /// + /// DockContainerItem to close. + public void CloseDockTab(DockContainerItem dockTab) + { + CloseDockTab(dockTab, eEventSource.Code); + } + + /// + /// Closes the DockContainerItem. + /// + /// DockContainerItem to close. + /// Source of the event. + public void CloseDockTab(DockContainerItem dockTab, eEventSource source) + { + DockTabClosingEventArgs e = new DockTabClosingEventArgs(dockTab, source); + InvokeDockTabClosing(e); + if (e.Cancel) + return; + + if (this.VisibleItemCount > 1) + { + if (e.RemoveDockTab) + this.Items.Remove(dockTab); + else + BarUtilities.SetDockContainerVisible(dockTab, false); + } + else + { + if (e.RemoveDockTab) + this.Items.Remove(dockTab); + CloseBar(); + if (!this.Visible) + dockTab.Visible = false; + } + + InvokeDockTabClosed(e); + } + + private void InvokeDockTabClosed(DockTabClosingEventArgs e) + { + if (DockTabClosed != null) + DockTabClosed(this, e); + if (this.Owner is DotNetBarManager) + { + ((DotNetBarManager)this.Owner).InvokeDockTabClosed(this, e); + } + OnBarStateChanged(new BarStateChangedEventArgs(this, eBarStateChange.DockTabClosed, e.DockContainerItem)); + } + + internal void InvokeDockTabClosing(DockTabClosingEventArgs e) + { + if (DockTabClosing != null) + DockTabClosing(this, e); + if (this.Owner is DotNetBarManager) + { + ((DotNetBarManager)this.Owner).InvokeDockTabClosing(this, e); + } + } + + private void InvokeBarClosing(BarClosingEventArgs e) + { + if (Closing != null) + Closing(this, e); + IOwnerBarSupport barSupp = m_Owner as IOwnerBarSupport; + if (barSupp != null) + barSupp.InvokeBarClosing(this, e); + } + + /// + /// Raises the ItemClick event. + /// + /// Item that was clicked. + /// Event arguments. + protected virtual void OnItemClick(BaseItem item, EventArgs e) + { + if (ItemClick != null) + ItemClick(item, e); + } + + internal void InvokeItemClick(BaseItem item, EventArgs e) + { + OnItemClick(item, e); + } + + protected override void OnClick(EventArgs e) + { + m_ItemContainer.InternalClick(Control.MouseButtons, this.PointToClient(Control.MousePosition)); + base.OnClick(e); + } + + private eDoubleClickBarBehavior _DoubleClickBehavior = eDoubleClickBarBehavior.FloatAndReDock; + /// + /// Specifies the bar behavior when its title is double-clicked + /// + [DefaultValue(eDoubleClickBarBehavior.FloatAndReDock), Category("Behavior"), Description("Specifies the bar behavior when its title is double-clicked")] + public eDoubleClickBarBehavior DoubleClickBehavior + { + get { return _DoubleClickBehavior; } + set { _DoubleClickBehavior = value; } + } + + protected override void OnDoubleClick(EventArgs e) + { + if (m_BarState == eBarState.Popup) + { + ISite site = this.GetSite(); + if (site != null && site.DesignMode) + { + ISelectionService selection = (ISelectionService)site.GetService(typeof(ISelectionService)); + if (selection != null) + { + IDesignerHost host = (IDesignerHost)site.GetService(typeof(IDesignerHost)); + if (host != null) + { + IDesigner designer = host.GetDesigner(selection.PrimarySelection as IComponent); + if (designer != null) + { + designer.DoDefaultAction(); + } + } + } + } + } + + + Point mouseDownPoint = this.PointToClient(Control.MousePosition); + if (m_GrabHandleRect.Contains(mouseDownPoint) && + !m_SystemButtons.CloseButtonRect.Contains(mouseDownPoint) && + !m_SystemButtons.AutoHideButtonRect.Contains(mouseDownPoint)) + { + if (m_BarState == eBarState.Floating) + { + if (_DoubleClickBehavior == eDoubleClickBarBehavior.ReDock || _DoubleClickBehavior == eDoubleClickBarBehavior.FloatAndReDock) + ReDock(); + } + else if (m_BarState == eBarState.Docked && this.CanUndock && this.Parent is DockSite) + { + Point p = Point.Empty; + if (m_FloatingRect.IsEmpty) + p = Control.MousePosition; + else + p = m_FloatingRect.Location; + if (_DoubleClickBehavior == eDoubleClickBarBehavior.Float || _DoubleClickBehavior == eDoubleClickBarBehavior.FloatAndReDock) + DockingHandler(new DockSiteInfo(), p); + } + } + if (!this.IsDisposed) + m_ItemContainer.InternalDoubleClick(Control.MouseButtons, Control.MousePosition); + base.OnDoubleClick(e); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + ExKeyDown(e); + base.OnKeyDown(e); + } + + internal void ExKeyDown(KeyEventArgs e) + { + m_ItemContainer.InternalKeyDown(e); + } + + private void ResetHover() + { + // 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 + NativeFunctions.TRACKMOUSEEVENT tme = new NativeFunctions.TRACKMOUSEEVENT(); + tme.dwFlags = NativeFunctions.TME_QUERY; + tme.hwndTrack = this.Handle; + tme.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(tme); + NativeFunctions.TrackMouseEvent(ref tme); + tme.dwFlags = tme.dwFlags | NativeFunctions.TME_HOVER; + NativeFunctions.TrackMouseEvent(ref tme); + } + + public override string ToString() + { + return this.Text; + } + + private bool m_IsVisible = true; + internal bool IsVisible + { + get + { + return m_IsVisible; + } + } + + protected override void OnVisibleChanged(EventArgs e) + { + if (this.IsHandleCreated) + m_IsVisible = base.Visible; + // Restore bar order when docked to the side. WinForms can change it's order which + // creates problem for docking... + if (m_BarShowIndex >= 0) + { + if (this.Parent is DockSite && this.Parent.Controls.IndexOf(this) != m_BarShowIndex) + { + this.Parent.Controls.SetChildIndex(this, m_BarShowIndex); + } + m_BarShowIndex = -1; + } + + // Must reset the ActiveControl to null becouse on MDI Forms if this was not done + // MDI form could not be closed if bar that had ActiveControl is floating. + IOwner owner = m_Owner as IOwner; + if (owner != null) + { + if (owner.ParentForm != null && owner.ParentForm.ActiveControl == this) + { + owner.ParentForm.ActiveControl = null; + this.Focus(); // Fixes the problem on SDI forms + } + else if (owner.ParentForm != null && IsAnyControl(this, owner.ParentForm.ActiveControl)) + { + owner.ParentForm.ActiveControl = null; + this.Focus(); + } + } + + base.OnVisibleChanged(e); + + // m_DockingInProgress check is needed becouse we don't want RecalcLayout to be called from + // DockSite.AddBar. The visible change event will fire when from that procedure Bar is added + // to the Dock Site. + if (m_BarState == eBarState.Docked && !m_DockingInProgress && this.Visible) + { + if (this.LayoutType == eLayoutType.DockContainer && m_AlwaysDisplayDockTab) RefreshDockTab(false); + this.RecalcLayout(); + } + + if (!this.Visible && m_DropShadow != null) + { + m_DropShadow.Hide(); + m_DropShadow.Dispose(); + m_DropShadow = null; + } + if (!this.Visible && m_CustomizeMenu != null && m_CustomizeMenu.Expanded) + m_CustomizeMenu.Expanded = false; + + } + + private bool m_LayoutSuspended = false; + /// + /// Suspends normal layout logic. + /// + public new void SuspendLayout() + { + m_LayoutSuspended = true; + base.SuspendLayout(); + } + + /// + /// Resumes normal layout logic. + /// + public new void ResumeLayout() + { + this.ResumeLayout(true); + } + + /// + /// Resumes normal layout logic. Optionally forces an immediate layout of pending layout requests. + /// + public new void ResumeLayout(bool performLayout) + { + m_LayoutSuspended = false; + base.ResumeLayout(true); + } + + protected override void OnParentChanged(EventArgs e) + { + base.OnParentChanged(e); + if (this.Parent != null && !(this.Parent is FloatingContainer) && !(this.Parent is DockSite)) + { + m_ItemContainer.SetOwner(this); + if (!m_ParentMsgHandlerRegistered && this.DesignMode && this.FindForm() != null) + { + DotNetBarManager.RegisterOwnerParentMsgHandler(this, this.FindForm()); + m_ParentMsgHandlerRegistered = true; + } + + // Cycle shortcuts + if (m_ShortcutTable.Count == 0) + { + foreach (BaseItem item in m_ItemContainer.SubItems) + ((IOwner)this).AddShortcutsFromItem(item); + } + + if (this.Parent != null && !(this.Parent is FloatingContainer) && !(this.Parent is DockSite) && !this.AutoHide) + { + if (!m_FilterInstalled) + { + MessageHandler.RegisterMessageClient(this); + m_FilterInstalled = true; + } + } + + if (!m_DockStretch) Stretch = true; + } + else if (m_FilterInstalled) + { + MessageHandler.UnregisterMessageClient(this); + m_FilterInstalled = false; + } + + if (this.DesignMode) + m_ItemContainer.SetDesignMode(this.DesignMode); + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + if (m_ThemeWindowMargins.IsEmpty) + { + RefreshThemeMargins(); + } + + if (this.Parent != null && !(this.Parent is FloatingContainer) && !(this.Parent is DockSite) && !this.AutoHide) + { + if (!m_FilterInstalled) + { + MessageHandler.RegisterMessageClient(this); + m_FilterInstalled = true; + } + } + + this.RecalcSize(); + } + + protected override void OnHandleDestroyed(EventArgs e) + { + DisposeThemes(); + MenuEventSupportUnhook(); + if (m_FilterInstalled) + { + MessageHandler.UnregisterMessageClient(this); + m_FilterInstalled = false; + } + base.OnHandleDestroyed(e); + } + + private void RefreshThemeMargins() + { + if (!BarFunctions.ThemedOS) + return; + + ThemeWindow theme = this.ThemeWindow; + Graphics g = this.CreateGraphics(); + try + { + System.Drawing.Size sz = theme.ThemeMinSize(g, ThemeWindowParts.SmallFrameLeft, ThemeWindowStates.FrameActive); + m_ThemeWindowMargins.Left = sz.Width; + sz = theme.ThemeMinSize(g, ThemeWindowParts.SmallFrameRight, ThemeWindowStates.FrameActive); + m_ThemeWindowMargins.Right = sz.Width; + sz = theme.ThemeMinSize(g, ThemeWindowParts.SmallFrameBottom, ThemeWindowStates.FrameActive); + m_ThemeWindowMargins.Bottom = sz.Height; + sz = theme.ThemeTrueSize(g, ThemeWindowParts.SmallCaption, ThemeWindowStates.FrameActive); + m_ThemeWindowMargins.Top = sz.Height; + } + finally + { + g.Dispose(); + } + } + + private void DisposeThemes() + { + if (m_ThemeWindow != null) + { + m_ThemeWindow.Dispose(); + m_ThemeWindow = null; + } + if (m_ThemeRebar != null) + { + m_ThemeRebar.Dispose(); + m_ThemeRebar = null; + } + if (m_ThemeToolbar != null) + { + m_ThemeToolbar.Dispose(); + m_ThemeToolbar = null; + } + if (m_ThemeHeader != null) + { + m_ThemeHeader.Dispose(); + m_ThemeHeader = null; + } + if (m_ThemeScrollBar != null) + { + m_ThemeScrollBar.Dispose(); + m_ThemeScrollBar = null; + } + if (m_ThemeProgress != null) + { + m_ThemeProgress.Dispose(); + m_ThemeProgress = null; + } + } + private void RefreshThemes() + { + if (m_ThemeWindow != null) + { + m_ThemeWindow.Dispose(); + m_ThemeWindow = new ThemeWindow(this); + } + if (m_ThemeRebar != null) + { + m_ThemeRebar.Dispose(); + m_ThemeRebar = new ThemeRebar(this); + } + if (m_ThemeToolbar != null) + { + m_ThemeToolbar.Dispose(); + m_ThemeToolbar = new ThemeToolbar(this); + } + if (m_ThemeHeader != null) + { + m_ThemeHeader.Dispose(); + m_ThemeHeader = new ThemeHeader(this); + } + if (m_ThemeScrollBar != null) + { + m_ThemeScrollBar.Dispose(); + m_ThemeScrollBar = new ThemeScrollBar(this); + } + if (m_ThemeProgress != null) + { + m_ThemeProgress.Dispose(); + m_ThemeProgress = new ThemeProgress(this); + } + } + internal DevComponents.DotNetBar.ThemeWindow ThemeWindow + { + get + { + if (m_ThemeWindow == null) + m_ThemeWindow = new ThemeWindow(this); + return m_ThemeWindow; + } + } + internal DevComponents.DotNetBar.ThemeRebar ThemeRebar + { + get + { + if (m_ThemeRebar == null) + m_ThemeRebar = new ThemeRebar(this); + return m_ThemeRebar; + } + } + internal DevComponents.DotNetBar.ThemeToolbar ThemeToolbar + { + get + { + if (m_ThemeToolbar == null) + m_ThemeToolbar = new ThemeToolbar(this); + return m_ThemeToolbar; + } + } + internal DevComponents.DotNetBar.ThemeHeader ThemeHeader + { + get + { + if (m_ThemeHeader == null) + m_ThemeHeader = new ThemeHeader(this); + return m_ThemeHeader; + } + } + internal DevComponents.DotNetBar.ThemeScrollBar ThemeScrollBar + { + get + { + if (m_ThemeScrollBar == null) + m_ThemeScrollBar = new ThemeScrollBar(this); + return m_ThemeScrollBar; + } + } + internal DevComponents.DotNetBar.ThemeProgress ThemeProgress + { + get + { + if (m_ThemeProgress == null) + m_ThemeProgress = new ThemeProgress(this); + return m_ThemeProgress; + } + } + + private int ClientMarginLeft + { + get + { + int iMargin = 0; + + if (m_ParentItem != null && m_ParentItem.EffectiveStyle != eDotNetBarStyle.Office2000) + iMargin = 1; + else + iMargin = 3; + + return iMargin; + } + } + + private int ClientMarginTop + { + get + { + int iMargin = 0; + if (m_ParentItem != null && m_ParentItem.EffectiveStyle != eDotNetBarStyle.Office2000) + iMargin = 2; + else + iMargin = 3; + + return iMargin; + } + } + + private int ClientMarginRight + { + get + { + bool bShowShadow = true; + int iMargin = 0; + IOwnerMenuSupport ownersupport = m_Owner as IOwnerMenuSupport; + if (ownersupport != null && !ownersupport.ShowPopupShadow) + bShowShadow = false; + if (m_ParentItem != null && m_ParentItem.EffectiveStyle != eDotNetBarStyle.Office2000) + { + if (this.AlphaShadow || !bShowShadow) + iMargin = 1; + else + iMargin = 3; + } + else + iMargin = 3; + + return iMargin; + } + } + + private int ClientMarginBottom + { + get + { + bool bShowShadow = true; + int iMargin = 0; + IOwnerMenuSupport ownersupport = m_Owner as IOwnerMenuSupport; + if (ownersupport != null && !ownersupport.ShowPopupShadow) + bShowShadow = false; + if (m_ParentItem != null && m_ParentItem.EffectiveStyle != eDotNetBarStyle.Office2000) + { + if (this.AlphaShadow || !bShowShadow) + iMargin = 2; + else + iMargin = 4; + } + else + iMargin = 3; + + return iMargin; + } + } + + /// + /// Returns whether popup bar should display shadow. + /// + internal bool DisplayShadow + { + get + { + if (PassiveBar) + return false; + IOwnerMenuSupport ownersupport = m_Owner as IOwnerMenuSupport; + if (ownersupport != null) + { + if (m_ParentItem != null && m_ParentItem.EffectiveStyle == eDotNetBarStyle.Office2000) + { + if (ownersupport.MenuDropShadow == eMenuDropShadow.Show) + return true; + else + return false; + } + return ownersupport.ShowPopupShadow; + } + else + { + if (m_ParentItem != null && m_ParentItem.EffectiveStyle == eDotNetBarStyle.Office2000) + return false; + } + + return true; + } + } + + /// + /// Returns whether popup bar shadow should be alpha-blended. + /// + internal bool AlphaShadow + { + get + { + if (Environment.OSVersion.Version.Major < 5) + return false; + IOwnerMenuSupport ownersupport = m_Owner as IOwnerMenuSupport; + if (ownersupport != null && !ownersupport.AlphaBlendShadow) + return false; + return NativeFunctions.CursorShadow; + } + } + + protected override void OnGotFocus(EventArgs e) + { + base.OnGotFocus(e); + if (this.MenuBar) + this.Refresh(); + } + + protected override void OnLostFocus(EventArgs e) + { + base.OnLostFocus(e); + if (this.MenuBar) + this.Refresh(); + } + + internal bool MenuFocus + { + get + { + return m_MenuFocus; + } + set + { + if (m_MenuFocus != value) + { + m_MenuFocus = value; + if (m_MenuFocus) + { + m_ItemContainer.SetSystemFocus(); + DotNetBarManager manager = m_Owner as DotNetBarManager; + if (manager != null) + manager.FocusedBar = this; + } + else + { + if (m_ItemContainer != null) + { + m_ItemContainer.AutoExpand = false; + m_ItemContainer.ReleaseSystemFocus(); + m_ItemContainer.ContainerLostFocus(false); + } + + DotNetBarManager manager = m_Owner as DotNetBarManager; + if (manager != null) + manager.FocusedBar = null; + } + if (this.MenuBar) + { + this.Refresh(); + } + } + } + } + + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public void SetDesignMode(bool b) + { + m_ItemContainer.SetDesignMode(b); + } + + internal bool GetDesignMode() + { + return this.DesignMode; + } + + internal int PopupWidth + { + get + { + return m_InitialContainerWidth; + } + set + { + m_InitialContainerWidth = value; + } + } + + /// + /// Gets/Sets the popup animation that will be applied when popup is shown. + /// + [System.ComponentModel.Browsable(false), DefaultValue(ePopupAnimation.ManagerControlled)] + public ePopupAnimation PopupAnimation + { + get + { + return m_PopupAnimation; + } + set + { + m_PopupAnimation = value; + } + } + + #region ICustomSerialization Implementation + /// + /// Invokes SerializeItem event. + /// + /// Provides data for the event. + void ICustomSerialization.InvokeSerializeItem(SerializeItemEventArgs e) + { + if (SerializeItem != null) + SerializeItem(this, e); + if (this.Owner != this && this.Owner is ICustomSerialization) + ((ICustomSerialization)this.Owner).InvokeSerializeItem(e); + } + + /// + /// Invokes DeserializeItem event. + /// + /// Provides data for the event. + void ICustomSerialization.InvokeDeserializeItem(SerializeItemEventArgs e) + { + if (DeserializeItem != null) + DeserializeItem(this, e); + if (this.Owner != this && this.Owner is ICustomSerialization) + ((ICustomSerialization)this.Owner).InvokeDeserializeItem(e); + } + + /// + /// Gets whether any handlers have been defined for SerializeItem event. If no handles have been defined to optimize performance SerializeItem event will not be attempted to fire. + /// + bool ICustomSerialization.HasSerializeItemHandlers + { + get + { + bool b = SerializeItem != null; + if (this.Owner != this && this.Owner is ICustomSerialization) + b |= ((ICustomSerialization)this.Owner).HasSerializeItemHandlers; + return b; + } + } + + /// + /// Gets whether any handlers have been defined for DeserializeItem event. If no handles have been defined to optimize performance DeserializeItem event will not be attempted to fire. + /// + bool ICustomSerialization.HasDeserializeItemHandlers + { + get + { + bool b = DeserializeItem != null; + if (this.Owner != this && this.Owner is ICustomSerialization) + b |= ((ICustomSerialization)this.Owner).HasDeserializeItemHandlers; + return b; + } + } + #endregion + + /// + /// Saves the Bar definition to file. + /// + /// Definition file name. + public void SaveDefinition(string FileName) + { + System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); + + this.SaveDefinition(xmlDoc); + + xmlDoc.Save(FileName); + } + + internal void SaveDefinition(System.Xml.XmlDocument xmlDoc) + { + System.Xml.XmlElement xmlBar = xmlDoc.CreateElement("bar"); + xmlDoc.AppendChild(xmlBar); + this.Serialize(xmlBar); + } + + /// + /// Loads the Bar definition from file. + /// + /// Definition file name. + public void LoadDefinition(string FileName) + { + System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); + xmlDoc.Load(FileName); + this.LoadDefinition(xmlDoc); + } + + internal void LoadDefinition(System.Xml.XmlDocument xmlDoc) + { + if (xmlDoc.FirstChild.Name != "bar") + throw (new System.InvalidOperationException("XML Format not recognized")); + + m_ItemContainer.SubItems.Clear(); + this.Deserialize(xmlDoc.FirstChild as System.Xml.XmlElement); + + IOwnerBarSupport ownersupport = m_Owner as IOwnerBarSupport; + if (ownersupport != null) + ownersupport.AddShortcutsFromBar(this); + + ((IOwner)this).InvokeDefinitionLoaded(this, new EventArgs()); + } + + /// + /// Gets/Sets Bar definition as XML string. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public string Definition + { + get + { + System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); + SaveDefinition(xmlDoc); + return xmlDoc.OuterXml; + } + set + { + System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); + xmlDoc.LoadXml(value); + LoadDefinition(xmlDoc); + } + } + + void IOwner.InvokeDefinitionLoaded(object sender, EventArgs e) + { + if (DefinitionLoaded != null) + DefinitionLoaded(sender, e); + } + + internal void Serialize(System.Xml.XmlElement xmlThisBar) + { + Serialize(xmlThisBar, false); + } + + internal void Serialize(System.Xml.XmlElement xmlThisBar, bool bPropertiesOnly) + { + // Creates serialization context + ItemSerializationContext context = new ItemSerializationContext(); + context.Serializer = this; + context.HasDeserializeItemHandlers = ((ICustomSerialization)this).HasDeserializeItemHandlers; + context.HasSerializeItemHandlers = ((ICustomSerialization)this).HasSerializeItemHandlers; + + xmlThisBar.SetAttribute("name", this.Name); + xmlThisBar.SetAttribute("candockleft", System.Xml.XmlConvert.ToString(m_CanDockLeft)); + xmlThisBar.SetAttribute("candockright", System.Xml.XmlConvert.ToString(m_CanDockRight)); + xmlThisBar.SetAttribute("candocktop", System.Xml.XmlConvert.ToString(m_CanDockTop)); + xmlThisBar.SetAttribute("candockbottom", System.Xml.XmlConvert.ToString(m_CanDockBottom)); + xmlThisBar.SetAttribute("candockdoc", System.Xml.XmlConvert.ToString(m_CanDockDocument)); + xmlThisBar.SetAttribute("candocktab", System.Xml.XmlConvert.ToString(m_CanDockTab)); + xmlThisBar.SetAttribute("canmaximizefloating", System.Xml.XmlConvert.ToString(_CanMaximizeFloating)); + xmlThisBar.SetAttribute("text", this.Text); + xmlThisBar.SetAttribute("dockline", System.Xml.XmlConvert.ToString(m_DockLine)); + if (/*m_DockOffset==0 && this.Left>0 && */ (this.DockSide == eDockSide.Top || this.DockSide == eDockSide.Bottom)) + xmlThisBar.SetAttribute("dockoffset", System.Xml.XmlConvert.ToString(this.Left)); + else if (/*m_DockOffset==0 && this.Top>0 &&*/ (this.DockSide == eDockSide.Left || this.DockSide == eDockSide.Right)) + xmlThisBar.SetAttribute("dockoffset", System.Xml.XmlConvert.ToString(this.Top)); + //else + // xmlThisBar.SetAttribute("dockoffset",System.Xml.XmlConvert.ToString(m_DockOffset)); + xmlThisBar.SetAttribute("grabhandle", System.Xml.XmlConvert.ToString((int)m_GrabHandleStyle)); + xmlThisBar.SetAttribute("menubar", System.Xml.XmlConvert.ToString(m_MenuBar)); + xmlThisBar.SetAttribute("stretch", System.Xml.XmlConvert.ToString(m_DockStretch)); + xmlThisBar.SetAttribute("style", System.Xml.XmlConvert.ToString((int)m_ItemContainer.Style)); + xmlThisBar.SetAttribute("wrapdock", System.Xml.XmlConvert.ToString(m_WrapItemsDock)); + xmlThisBar.SetAttribute("wrapfloat", System.Xml.XmlConvert.ToString(m_WrapItemsFloat)); + if (m_LockDockPosition) + xmlThisBar.SetAttribute("lockdockpos", System.Xml.XmlConvert.ToString(m_LockDockPosition)); + if (!m_CanUndock) + xmlThisBar.SetAttribute("canundock", System.Xml.XmlConvert.ToString(m_CanUndock)); + if (m_TabNavigation) + xmlThisBar.SetAttribute("tabnav", System.Xml.XmlConvert.ToString(m_TabNavigation)); + + if (!m_ShowToolTips) + xmlThisBar.SetAttribute("tooltips", System.Xml.XmlConvert.ToString(m_ShowToolTips)); + + if (m_ItemContainer.MoreItemsOnMenu) + xmlThisBar.SetAttribute("overflowmenu", System.Xml.XmlConvert.ToString(m_ItemContainer.MoreItemsOnMenu)); + + if (m_AutoHideState) + { + xmlThisBar.SetAttribute("state", System.Xml.XmlConvert.ToString((int)eBarState.Docked)); + eDockSide dockside = eDockSide.None; + switch (m_LastDockSiteInfo.DockSide) + { + case DockStyle.Left: + dockside = eDockSide.Left; + break; + case DockStyle.Right: + dockside = eDockSide.Right; + break; + case DockStyle.Top: + dockside = eDockSide.Top; + break; + case DockStyle.Bottom: + dockside = eDockSide.Bottom; + break; + } + xmlThisBar.SetAttribute("dockside", System.Xml.XmlConvert.ToString((int)dockside)); + } + else + { + xmlThisBar.SetAttribute("state", System.Xml.XmlConvert.ToString((int)m_BarState)); + xmlThisBar.SetAttribute("dockside", System.Xml.XmlConvert.ToString((int)this.DockSide)); + if (this.DockSide == eDockSide.None && m_Float != null) + xmlThisBar.SetAttribute("fpos", m_Float.Location.X + "," + m_Float.Location.Y + "," + this.DisplayRectangle.Width + "," + this.DisplayRectangle.Height); + } + + IOwnerBarSupport ownersupport = m_Owner as IOwnerBarSupport; + if (m_BarState == eBarState.Floating && !this.Visible && ownersupport != null && ownersupport.WereVisible.Count > 0 && ownersupport.WereVisible.Contains(this)) + xmlThisBar.SetAttribute("visible", System.Xml.XmlConvert.ToString(true)); + else + { + if (m_AutoHideState) + { + xmlThisBar.SetAttribute("visible", System.Xml.XmlConvert.ToString(true)); + xmlThisBar.SetAttribute("autohide", System.Xml.XmlConvert.ToString(true)); + } + else + xmlThisBar.SetAttribute("visible", System.Xml.XmlConvert.ToString(this.Visible)); + } + xmlThisBar.SetAttribute("custom", System.Xml.XmlConvert.ToString(m_CustomBar)); + xmlThisBar.SetAttribute("canhide", System.Xml.XmlConvert.ToString(m_CanHide)); + xmlThisBar.SetAttribute("imagesize", System.Xml.XmlConvert.ToString((int)m_ImageSize)); + xmlThisBar.SetAttribute("itemsp", System.Xml.XmlConvert.ToString(m_ItemContainer.ItemSpacing)); + + xmlThisBar.SetAttribute("themes", System.Xml.XmlConvert.ToString(m_ThemeAware)); + + if (!m_ItemContainer.CanCustomize) + xmlThisBar.SetAttribute("cancust", System.Xml.XmlConvert.ToString(m_ItemContainer.CanCustomize)); + + // Save Font information if needed + if (this.Font != null) + { + if (m_CustomFont) + { + xmlThisBar.SetAttribute("fontname", this.Font.Name); + xmlThisBar.SetAttribute("fontemsize", System.Xml.XmlConvert.ToString(this.Font.Size)); + xmlThisBar.SetAttribute("fontstyle", System.Xml.XmlConvert.ToString((int)this.Font.Style)); + } + } + + if (!m_ItemContainer.m_BackgroundColor.IsEmpty) + xmlThisBar.SetAttribute("backcolor", BarFunctions.ColorToString(m_ItemContainer.BackColor)); + xmlThisBar.SetAttribute("layout", System.Xml.XmlConvert.ToString((int)m_ItemContainer.LayoutType)); + xmlThisBar.SetAttribute("eqbutton", System.Xml.XmlConvert.ToString(m_ItemContainer.EqualButtonSize)); + if (m_DockedBorder != eBorderType.None) + xmlThisBar.SetAttribute("dborder", System.Xml.XmlConvert.ToString((int)m_DockedBorder)); + + if (!m_AcceptDropItems) + xmlThisBar.SetAttribute("acceptdrop", System.Xml.XmlConvert.ToString(m_AcceptDropItems)); + + if (m_SingleLineColor != SystemColors.ControlDark) + xmlThisBar.SetAttribute("slcolor", BarFunctions.ColorToString(m_SingleLineColor)); + + if (!m_CaptionBackColor.IsEmpty) + xmlThisBar.SetAttribute("captionbc", BarFunctions.ColorToString(m_CaptionBackColor)); + if (!m_CaptionForeColor.IsEmpty) + xmlThisBar.SetAttribute("captionfc", BarFunctions.ColorToString(m_CaptionForeColor)); + + if (m_AlwaysDisplayDockTab) + xmlThisBar.SetAttribute("showtab", System.Xml.XmlConvert.ToString(m_AlwaysDisplayDockTab)); + + if (this.AutoHide) + { + if (m_ItemContainer.MinWidth != 0) + xmlThisBar.SetAttribute("dockwidth", System.Xml.XmlConvert.ToString(m_ItemContainer.MinWidth)); + else if (m_LastDockSiteInfo.DockedWidth != 0) + xmlThisBar.SetAttribute("dockwidth", System.Xml.XmlConvert.ToString(m_LastDockSiteInfo.DockedWidth)); + if (m_ItemContainer.MinHeight != 0) + xmlThisBar.SetAttribute("dockheight", System.Xml.XmlConvert.ToString(m_ItemContainer.MinHeight)); + else if (m_LastDockSiteInfo.DockedHeight != 0) + xmlThisBar.SetAttribute("dockheight", System.Xml.XmlConvert.ToString(m_LastDockSiteInfo.DockedHeight)); + } + else + { + if (m_ItemContainer.MinWidth != 0 && this.CanSaveMinWidth) + xmlThisBar.SetAttribute("dockwidth", System.Xml.XmlConvert.ToString(m_ItemContainer.MinWidth)); + if (m_ItemContainer.MinHeight != 0 && this.CanSaveMinHeight) + xmlThisBar.SetAttribute("dockheight", System.Xml.XmlConvert.ToString(m_ItemContainer.MinHeight)); + } + + if (m_SplitDockWidthPercent > 0) + xmlThisBar.SetAttribute("splitwidthpercent", System.Xml.XmlConvert.ToString(m_SplitDockWidthPercent)); + if (m_SplitDockHeightPercent > 0) + xmlThisBar.SetAttribute("splitheightpercent", System.Xml.XmlConvert.ToString(m_SplitDockHeightPercent)); + + + if (m_ItemContainer.PaddingBottom != 1) + xmlThisBar.SetAttribute("padbottom", System.Xml.XmlConvert.ToString(m_ItemContainer.PaddingBottom)); + if (m_ItemContainer.PaddingLeft != 1) + xmlThisBar.SetAttribute("padleft", System.Xml.XmlConvert.ToString(m_ItemContainer.PaddingLeft)); + if (m_ItemContainer.PaddingRight != 1) + xmlThisBar.SetAttribute("padright", System.Xml.XmlConvert.ToString(m_ItemContainer.PaddingRight)); + if (m_ItemContainer.PaddingTop != 1) + xmlThisBar.SetAttribute("padtop", System.Xml.XmlConvert.ToString(m_ItemContainer.PaddingTop)); + + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && this.SelectedDockTab >= 0) + xmlThisBar.SetAttribute("seldocktab", System.Xml.XmlConvert.ToString(this.SelectedDockTab)); + + if (!m_CanAutoHide) + xmlThisBar.SetAttribute("canautohide", System.Xml.XmlConvert.ToString(m_CanAutoHide)); + if (!m_CanReorderTabs) + xmlThisBar.SetAttribute("canreordertabs", System.Xml.XmlConvert.ToString(m_CanReorderTabs)); + if (!m_CanTearOffTabs) + xmlThisBar.SetAttribute("cantearoff", System.Xml.XmlConvert.ToString(m_CanTearOffTabs)); + + // TODO: Menu Merge Implementation + //if(m_MergeEnabled) + // xmlThisBar.SetAttribute("merge",System.Xml.XmlConvert.ToString(m_MergeEnabled)); + + if (!m_HideFloatingInactive) + xmlThisBar.SetAttribute("hidein", System.Xml.XmlConvert.ToString(m_HideFloatingInactive)); + + if (m_DockTabAlignment != eTabStripAlignment.Bottom) + xmlThisBar.SetAttribute("tabalign", System.Xml.XmlConvert.ToString((int)m_DockTabAlignment)); + + if (m_AutoHideAnimationTime != 100) + xmlThisBar.SetAttribute("ahanim", System.Xml.XmlConvert.ToString(m_AutoHideAnimationTime)); + + if (!m_AutoCreateCaptionMenu) + xmlThisBar.SetAttribute("autocaptionmenu", System.Xml.XmlConvert.ToString(m_AutoCreateCaptionMenu)); + + if (m_AutoSyncBarCaption) + xmlThisBar.SetAttribute("autocaptionsync", System.Xml.XmlConvert.ToString(m_AutoSyncBarCaption)); + + if (!m_SaveLayoutChanges) + xmlThisBar.SetAttribute("savelayout", System.Xml.XmlConvert.ToString(m_SaveLayoutChanges)); + + if (m_ColorScheme.SchemeChanged) + { + System.Xml.XmlElement xmlScheme = xmlThisBar.OwnerDocument.CreateElement("colorscheme"); + m_ColorScheme.Serialize(xmlScheme); + xmlThisBar.AppendChild(xmlScheme); + } + + if (this.BackgroundImage != null) + { + System.Xml.XmlElement elementImage = xmlThisBar.OwnerDocument.CreateElement("backimage"); + xmlThisBar.AppendChild(elementImage); + BarFunctions.SerializeImage(this.BackgroundImage, elementImage); + elementImage.SetAttribute("pos", ((int)m_BackgroundImagePosition).ToString()); + elementImage.SetAttribute("alpha", m_BackgroundImageAlpha.ToString()); + } + + if (!bPropertiesOnly) + { + System.Xml.XmlElement xmlItems = xmlThisBar.OwnerDocument.CreateElement("items"); + xmlThisBar.AppendChild(xmlItems); + foreach (BaseItem objItem in m_ItemContainer.SubItems) + { + if (objItem.ShouldSerialize) + { + System.Xml.XmlElement xmlItem = xmlThisBar.OwnerDocument.CreateElement("item"); + xmlItems.AppendChild(xmlItem); + context.ItemXmlElement = xmlItem; + objItem.Serialize(context); + } + } + } + } + + private bool CanSaveMinWidth + { + get + { + eDockSide dockSide = this.DockSide; + if (dockSide == eDockSide.None || dockSide == eDockSide.Left || dockSide == eDockSide.Right) + return true; + return false; + } + } + + private bool CanSaveMinHeight + { + get + { + eDockSide dockSide = this.DockSide; + if (dockSide == eDockSide.None || dockSide == eDockSide.Top || dockSide == eDockSide.Bottom) + return true; + return false; + } + } + + internal void Deserialize(System.Xml.XmlElement xmlThisBar) + { + // Creates serialization context + ItemSerializationContext context = new ItemSerializationContext(); + context.Serializer = this; + context.HasDeserializeItemHandlers = ((ICustomSerialization)this).HasDeserializeItemHandlers; + context.HasSerializeItemHandlers = ((ICustomSerialization)this).HasSerializeItemHandlers; + + Deserialize(xmlThisBar, context); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void Deserialize(System.Xml.XmlElement xmlThisBar, ItemSerializationContext context) + { + m_BarDefinitionLoading = true; + m_IgnoreAnimation = true; + try + { + LoadCommonProperties(xmlThisBar); + + this.BackgroundImage = null; + + foreach (System.Xml.XmlElement xmlElem in xmlThisBar.ChildNodes) + { + switch (xmlElem.Name) + { + case "items": + { + foreach (System.Xml.XmlElement xmlItem in xmlElem.ChildNodes) + { + BaseItem objItem = context.CreateItemFromXml(xmlItem); + m_ItemContainer.SubItems.Add(objItem); + context.ItemXmlElement = xmlItem; + objItem.Deserialize(context); + } + break; + } + case "colorscheme": + { + m_ColorScheme.Deserialize(xmlElem); + break; + } + case "backimage": + { + this.BackgroundImage = BarFunctions.DeserializeImage(xmlElem); + m_BackgroundImagePosition = (eBackgroundImagePosition)System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("pos")); + m_BackgroundImageAlpha = System.Xml.XmlConvert.ToByte(xmlElem.GetAttribute("alpha")); + break; + } + } + } + + if ((eDockSide)System.Xml.XmlConvert.ToInt32(xmlThisBar.GetAttribute("dockside")) == eDockSide.None) + { + // Try to load position + if (xmlThisBar.HasAttribute("fpos")) + { + string s = xmlThisBar.GetAttribute("fpos"); + string[] arr = s.Split(','); + if (arr.Length == 4) + { + Rectangle r = new Rectangle(System.Xml.XmlConvert.ToInt32(arr[0]), System.Xml.XmlConvert.ToInt32(arr[1]), System.Xml.XmlConvert.ToInt32(arr[2]), System.Xml.XmlConvert.ToInt32(arr[3])); + m_FloatingRect = r; + } + } + if (!System.Xml.XmlConvert.ToBoolean(xmlThisBar.GetAttribute("visible")) || xmlThisBar.HasAttribute("autohide") && System.Xml.XmlConvert.ToBoolean(xmlThisBar.GetAttribute("autohide"))) + m_LoadingHideFloating = true; + } + + if (xmlThisBar.HasAttribute("seldocktab")) + { + int iTab = System.Xml.XmlConvert.ToInt32(xmlThisBar.GetAttribute("seldocktab")); + if (iTab >= 0 && iTab < m_ItemContainer.SubItems.Count) + { + foreach (BaseItem dockItem in m_ItemContainer.SubItems) + dockItem.Displayed = false; + m_ItemContainer.SubItems[iTab].Displayed = true; + } + } + + // Last Thing to do so it is docked properly + m_DockLine = System.Xml.XmlConvert.ToInt32(xmlThisBar.GetAttribute("dockline")); + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer) + RefreshDockTab(true); + this.DockSide = (eDockSide)System.Xml.XmlConvert.ToInt32(xmlThisBar.GetAttribute("dockside")); + if (m_LoadingHideFloating) m_LoadingHideFloating = false; + if (xmlThisBar.HasAttribute("autohide") && context._DesignerHost == null) + { + base.Visible = false; + if (m_ItemContainer.MinWidth > 0) + this.Width = m_ItemContainer.MinWidth; + if (m_ItemContainer.MinHeight > 0) + this.Height = m_ItemContainer.MinHeight; + this.AutoHide = true; + m_LastDockSiteInfo.DockedWidth = m_ItemContainer.MinWidth; + m_LastDockSiteInfo.DockedHeight = m_ItemContainer.MinHeight; + } + else + { + if (context._DesignerHost == null) + this.Visible = System.Xml.XmlConvert.ToBoolean(xmlThisBar.GetAttribute("visible")); + else + this.Visible = true; + } + } + finally + { + m_BarDefinitionLoading = false; + } + m_TabsRearranged = false; + SetupAccessibility(); + } + + private void LoadCommonProperties(System.Xml.XmlElement xmlBar) + { + m_BarState = eBarState.Docked; + this.Name = xmlBar.GetAttribute("name"); + if (xmlBar.HasAttribute("candockleft")) + m_CanDockLeft = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("candockleft")); + if (xmlBar.HasAttribute("candockright")) + m_CanDockRight = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("candockright")); + if (xmlBar.HasAttribute("candocktop")) + m_CanDockTop = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("candocktop")); + if (xmlBar.HasAttribute("candockbottom")) + m_CanDockBottom = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("candockbottom")); + if (xmlBar.HasAttribute("candockdoc")) + m_CanDockDocument = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("candockdoc")); + if (xmlBar.HasAttribute("candocktab")) + m_CanDockTab = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("candocktab")); + if (xmlBar.HasAttribute("canmaximizefloating")) + _CanMaximizeFloating = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("canmaximizefloating")); + if (xmlBar.HasAttribute("text")) + this.Text = xmlBar.GetAttribute("text"); + if (xmlBar.HasAttribute("dockline")) + m_DockLine = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("dockline")); + if (xmlBar.HasAttribute("dockoffset")) + m_DockOffset = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("dockoffset")); + if (xmlBar.HasAttribute("grabhandle")) + m_GrabHandleStyle = (eGrabHandleStyle)System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("grabhandle")); + if (xmlBar.HasAttribute("menubar")) + m_MenuBar = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("menubar")); + if (xmlBar.HasAttribute("stretch")) + m_DockStretch = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("stretch")); + if (xmlBar.HasAttribute("wrapdock")) + m_WrapItemsDock = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("wrapdock")); + if (xmlBar.HasAttribute("wrapfloat")) + m_WrapItemsFloat = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("wrapfloat")); + if (xmlBar.HasAttribute("custom")) + m_CustomBar = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("custom")); + if (xmlBar.HasAttribute("canhide")) + m_CanHide = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("canhide")); + if (xmlBar.HasAttribute("imagesize")) + m_ImageSize = (eBarImageSize)System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("imagesize")); + + if (xmlBar.HasAttribute("itemsp")) + m_ItemContainer.ItemSpacing = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("itemsp")); + // else + // m_ItemContainer.ItemSpacing=0; + + if (xmlBar.HasAttribute("backcolor")) + m_ItemContainer.BackColor = BarFunctions.ColorFromString(xmlBar.GetAttribute("backcolor")); + + if (xmlBar.HasAttribute("layout")) + m_ItemContainer.LayoutType = (eLayoutType)System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("layout")); + + if (xmlBar.HasAttribute("eqbutton")) + m_ItemContainer.EqualButtonSize = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("eqbutton")); + + if (xmlBar.HasAttribute("dborder")) + m_DockedBorder = (eBorderType)System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("dborder")); + //else + // m_DockedBorder=eBorderType.None; + + if (xmlBar.HasAttribute("acceptdrop")) + m_AcceptDropItems = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("acceptdrop")); + + if (xmlBar.HasAttribute("slcolor")) + m_SingleLineColor = BarFunctions.ColorFromString(xmlBar.GetAttribute("slcolor")); + + if (xmlBar.HasAttribute("captionbc")) + m_CaptionBackColor = BarFunctions.ColorFromString(xmlBar.GetAttribute("captionbc")); + if (xmlBar.HasAttribute("captionfc")) + m_CaptionForeColor = BarFunctions.ColorFromString(xmlBar.GetAttribute("captionfc")); + + if (xmlBar.HasAttribute("dockwidth")) + m_ItemContainer.MinWidth = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("dockwidth")); + if (xmlBar.HasAttribute("dockheight")) + m_ItemContainer.MinHeight = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("dockheight")); + + if (xmlBar.HasAttribute("splitwidthpercent")) + m_SplitDockWidthPercent = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("splitwidthpercent")); + else + m_SplitDockWidthPercent = 0; + if (xmlBar.HasAttribute("splitheightpercent")) + m_SplitDockHeightPercent = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("splitheightpercent")); + // else + // m_SplitDockHeightPercent=0; + + if (xmlBar.HasAttribute("padbottom")) + m_ItemContainer.PaddingBottom = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("padbottom")); + if (xmlBar.HasAttribute("padleft")) + m_ItemContainer.PaddingLeft = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("padleft")); + if (xmlBar.HasAttribute("padright")) + m_ItemContainer.PaddingRight = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("padright")); + if (xmlBar.HasAttribute("padtop")) + m_ItemContainer.PaddingTop = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("padtop")); + + if (xmlBar.HasAttribute("lockdockpos")) + m_LockDockPosition = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("lockdockpos")); + if (xmlBar.HasAttribute("canundock")) + m_CanUndock = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("canundock")); + if (xmlBar.HasAttribute("canreordertabs")) + m_CanReorderTabs = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("canreordertabs")); + if (xmlBar.HasAttribute("cantearoff")) + m_CanTearOffTabs = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("cantearoff")); + + if (xmlBar.HasAttribute("canautohide")) + m_CanAutoHide = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("canautohide")); + + if (xmlBar.HasAttribute("cancust")) + m_ItemContainer.CanCustomize = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("cancust")); + + if (xmlBar.HasAttribute("tabalign")) + m_DockTabAlignment = (eTabStripAlignment)System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("tabalign")); + + if (xmlBar.HasAttribute("showtab")) + m_AlwaysDisplayDockTab = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("showtab")); + + // TODO: Menu Merge Implementation + //if(xmlBar.HasAttribute("merge")) + // m_MergeEnabled=System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("merge")); + + if (xmlBar.HasAttribute("hidein")) + m_HideFloatingInactive = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("hidein")); + + if (xmlBar.HasAttribute("themes")) + { + m_ThemeAware = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("themes")); + m_ItemContainer.ThemeAware = m_ThemeAware; + } + + if (xmlBar.HasAttribute("tabnav")) + m_TabNavigation = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("tabnav")); + + if (xmlBar.HasAttribute("tooltips")) + m_ShowToolTips = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("tooltips")); + // else + // m_ShowToolTips=true; + + if (xmlBar.HasAttribute("overflowmenu")) + m_ItemContainer.MoreItemsOnMenu = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("overflowmenu")); + // else + // m_ItemContainer.MoreItemsOnMenu=false; + + if (xmlBar.HasAttribute("autocaptionmenu")) + m_AutoCreateCaptionMenu = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("autocaptionmenu")); + // else + // m_AutoCreateCaptionMenu=true; + + if (xmlBar.HasAttribute("autocaptionsync")) + this.AutoSyncBarCaption = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("autocaptionsync")); + // else + // this.AutoSyncBarCaption=false; + + if (xmlBar.HasAttribute("style")) + { + string sty = xmlBar.GetAttribute("style"); + //if (sty == "5") + // this.Style = eDotNetBarStyle.Office2007; + //else + this.Style = (eDotNetBarStyle)System.Xml.XmlConvert.ToInt32(sty); + } + + // Load font information if it exists + if (xmlBar.HasAttribute("fontname")) + { + string FontName = xmlBar.GetAttribute("fontname"); + float FontSize = System.Xml.XmlConvert.ToSingle(xmlBar.GetAttribute("fontemsize")); + System.Drawing.FontStyle FontStyle = (System.Drawing.FontStyle)System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("fontstyle")); + try + { + this.Font = new Font(FontName, FontSize, FontStyle); + } + catch (Exception) + { + this.Font = SystemFonts.MenuFont; // System.Windows.Forms.SystemInformation.MenuFont.Clone() as Font; + } + m_CustomFont = true; + } + + if (xmlBar.HasAttribute("ahanim")) + m_AutoHideAnimationTime = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("ahanim")); + // else + // m_AutoHideAnimationTime=100; + + if (xmlBar.HasAttribute("savelayout")) + m_SaveLayoutChanges = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("savelayout")); + // else + // m_SaveLayoutChanges=true; + } + + /// + /// Gets or sets whether layout changes are saved for this bar when DotNetBarManager.SaveLayout method is used to save layout for all bars. Default value is true which means that layout changes are saved. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(true),Category("Behavior"),Description("Indicates whether layout changes are saved for this bar")] + public bool SaveLayoutChanges + { + get { return m_SaveLayoutChanges; } + set { m_SaveLayoutChanges = value; } + } + + /// + /// Saves the Bar layout to file. + /// + /// Definition file name. + public void SaveLayout(string FileName) + { + System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); + + this.SaveLayout(xmlDoc); + + xmlDoc.Save(FileName); + } + + internal void SaveLayout(System.Xml.XmlDocument xmlDoc) + { + System.Xml.XmlElement xmlBar = xmlDoc.CreateElement("bar"); + xmlDoc.AppendChild(xmlBar); + this.SerializeLayout(xmlBar); + } + + /// + /// Loads the Bar definition from file. + /// + /// Definition file name. + public void LoadLayout(string FileName) + { + System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); + xmlDoc.Load(FileName); + this.LoadLayout(xmlDoc); + } + + internal void LoadLayout(System.Xml.XmlDocument xmlDoc) + { + if (xmlDoc.FirstChild.Name != "bar") + throw (new System.InvalidOperationException("XML Format not recognized")); + + this.DeserializeLayout(xmlDoc.FirstChild as System.Xml.XmlElement); + } + + /// + /// Gets/Sets Bar layout as XML string. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public string LayoutDefinition + { + get + { + System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); + SaveLayout(xmlDoc); + return xmlDoc.OuterXml; + } + set + { + System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); + xmlDoc.LoadXml(value); + LoadLayout(xmlDoc); + } + } + + internal void SerializeLayout(System.Xml.XmlElement xmlThisBar) + { + if (this.CustomBar) + { + this.Serialize(xmlThisBar, true); + } + else + { + xmlThisBar.SetAttribute("name", this.Name); + xmlThisBar.SetAttribute("dockline", System.Xml.XmlConvert.ToString(m_DockLine)); + xmlThisBar.SetAttribute("layout", System.Xml.XmlConvert.ToString((int)this.LayoutType)); + + if (m_DockOffset == 0 && this.Left > 0 && (this.DockSide == eDockSide.Top || this.DockSide == eDockSide.Bottom)) + xmlThisBar.SetAttribute("dockoffset", System.Xml.XmlConvert.ToString(this.Left)); + else if (m_DockOffset == 0 && this.Top > 0 && (this.DockSide == eDockSide.Left || this.DockSide == eDockSide.Right)) + xmlThisBar.SetAttribute("dockoffset", System.Xml.XmlConvert.ToString(this.Top)); + else + xmlThisBar.SetAttribute("dockoffset", System.Xml.XmlConvert.ToString(m_DockOffset)); + + if (m_AutoHideState) + { + xmlThisBar.SetAttribute("state", System.Xml.XmlConvert.ToString((int)eBarState.Docked)); + eDockSide dockside = eDockSide.None; + switch (m_LastDockSiteInfo.DockSide) + { + case DockStyle.Left: + dockside = eDockSide.Left; + break; + case DockStyle.Right: + dockside = eDockSide.Right; + break; + case DockStyle.Top: + dockside = eDockSide.Top; + break; + case DockStyle.Bottom: + dockside = eDockSide.Bottom; + break; + } + xmlThisBar.SetAttribute("dockside", System.Xml.XmlConvert.ToString((int)dockside)); + } + else + { + xmlThisBar.SetAttribute("state", System.Xml.XmlConvert.ToString((int)m_BarState)); + xmlThisBar.SetAttribute("dockside", System.Xml.XmlConvert.ToString((int)this.DockSide)); + if (this.DockSide == eDockSide.None && m_Float != null) + xmlThisBar.SetAttribute("fpos", m_Float.Location.X + "," + m_Float.Location.Y + "," + this.DisplayRectangle.Width + "," + this.DisplayRectangle.Height); + else if (!m_FloatingRect.IsEmpty) + xmlThisBar.SetAttribute("fpos", m_FloatingRect.X + "," + m_FloatingRect.Y + "," + m_FloatingRect.Width + "," + m_FloatingRect.Height); + } + + IOwnerBarSupport ownersupport = m_Owner as IOwnerBarSupport; + if (m_BarState == eBarState.Floating && !this.Visible && ownersupport != null && ownersupport.WereVisible.Count > 0 && ownersupport.WereVisible.Contains(this)) + xmlThisBar.SetAttribute("visible", System.Xml.XmlConvert.ToString(true)); + else + { + if (m_AutoHideState) + { + xmlThisBar.SetAttribute("visible", System.Xml.XmlConvert.ToString(true)); + xmlThisBar.SetAttribute("autohide", System.Xml.XmlConvert.ToString(true)); + } + else + xmlThisBar.SetAttribute("visible", System.Xml.XmlConvert.ToString(this.Visible)); + } + + if (m_ItemContainer.MinWidth != 0) + xmlThisBar.SetAttribute("dockwidth", System.Xml.XmlConvert.ToString(m_ItemContainer.MinWidth)); + if (m_ItemContainer.MinHeight != 0) + xmlThisBar.SetAttribute("dockheight", System.Xml.XmlConvert.ToString(m_ItemContainer.MinHeight)); + if (m_SplitDockWidthPercent > 0) + xmlThisBar.SetAttribute("splitwidthpercent", System.Xml.XmlConvert.ToString(m_SplitDockWidthPercent)); + if (m_SplitDockHeightPercent > 0) + xmlThisBar.SetAttribute("splitheightpercent", System.Xml.XmlConvert.ToString(m_SplitDockHeightPercent)); + + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && this.SelectedDockTab >= 0) + xmlThisBar.SetAttribute("seldocktab", System.Xml.XmlConvert.ToString(this.SelectedDockTab)); + } + + System.Xml.XmlElement xmlItems = xmlThisBar.OwnerDocument.CreateElement("items"); + + foreach (BaseItem item in m_ItemContainer.SubItems) + { + if (item.OriginalBarName != "" || item.OriginalPosition >= 0 || item.UserCustomized || this.CustomBar || m_TabsRearranged || this.LayoutType == eLayoutType.DockContainer) + { + System.Xml.XmlElement xmlItem = xmlThisBar.OwnerDocument.CreateElement("item"); + xmlItem.SetAttribute("name", item.Name); + xmlItem.SetAttribute("origBar", item.OriginalBarName); + xmlItem.SetAttribute("origPos", System.Xml.XmlConvert.ToString(item.OriginalPosition)); + xmlItem.SetAttribute("pos", System.Xml.XmlConvert.ToString(m_ItemContainer.SubItems.IndexOf(item))); + if (!item.Visible) + xmlItem.SetAttribute("visible", System.Xml.XmlConvert.ToString(item.Visible)); + xmlItems.AppendChild(xmlItem); + } + } + + if (xmlItems.ChildNodes.Count > 0) + xmlThisBar.AppendChild(xmlItems); + } + + internal void DeserializeLayout(System.Xml.XmlElement xmlBar) + { + m_BarDefinitionLoading = true; + try + { + m_IgnoreAnimation = true; + + LoadCommonProperties(xmlBar); + + if (xmlBar.ChildNodes.Count > 0) + { + foreach (System.Xml.XmlElement xmlChild in xmlBar.ChildNodes) + { + if (xmlChild.Name == "items") + { + // Load items stored on bar first... + LoadLayoutItems(xmlBar); + break; + } + } + } + + // Try to load floating position + if (xmlBar.HasAttribute("fpos")) + { + string s = xmlBar.GetAttribute("fpos"); + string[] arr = s.Split(','); + if (arr.Length == 4) + { + Rectangle r = new Rectangle(System.Xml.XmlConvert.ToInt32(arr[0]), System.Xml.XmlConvert.ToInt32(arr[1]), System.Xml.XmlConvert.ToInt32(arr[2]), System.Xml.XmlConvert.ToInt32(arr[3])); + m_FloatingRect = r; + } + } + + if ((eDockSide)System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("dockside")) == eDockSide.None) + { + if (!System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("visible"))) + m_LoadingHideFloating = true; + } + + if (xmlBar.HasAttribute("seldocktab")) + { + int iTab = System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("seldocktab")); + if (iTab >= 0 && iTab < m_ItemContainer.SubItems.Count) + { + foreach (BaseItem dockItem in m_ItemContainer.SubItems) + dockItem.Displayed = false; + m_ItemContainer.SubItems[iTab].Displayed = true; + if (m_AutoSyncBarCaption) + this.Text = m_ItemContainer.SubItems[iTab].Text; + } + } + + // Last Thing to do so it is docked properly + //m_DockLine=System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("dockline")); + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer) + RefreshDockTab(true); + if (this.AutoHide) + { + if (xmlBar.HasAttribute("autohide")) + { + // If it is going back to auto-hide mode make sure it does not affect any bars on same line when we + // bring it out of auto-hide state + int minWidth = m_ItemContainer.MinWidth; + int minHeight = m_ItemContainer.MinHeight; + m_ItemContainer.MinWidth = 0; + m_ItemContainer.MinHeight = 0; + this.AutoHide = false; + m_ItemContainer.MinWidth = minWidth; + m_ItemContainer.MinHeight = minHeight; + } + else + this.AutoHide = false; + } + + this.DockSide = (eDockSide)System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("dockside")); + if (m_LoadingHideFloating) m_LoadingHideFloating = false; + if (xmlBar.HasAttribute("autohide")) + { + if (!this.AutoHide) + { + base.Visible = false; + if (m_ItemContainer.MinWidth > 0) + this.Width = m_ItemContainer.MinWidth; + if (m_ItemContainer.MinHeight > 0) + this.Height = m_ItemContainer.MinHeight; + this.AutoHide = true; + m_LastDockSiteInfo.DockedWidth = m_ItemContainer.MinWidth; + m_LastDockSiteInfo.DockedHeight = m_ItemContainer.MinHeight; + } + } + else + this.Visible = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("visible")); + } + finally + { + m_BarDefinitionLoading = false; + } + } + + private void LoadLayoutItems(System.Xml.XmlElement xmlBar) + { + bool customBar = false; + eLayoutType layoutType = eLayoutType.Toolbar; + DotNetBarManager manager = null; + if (m_Owner != null && m_Owner is DotNetBarManager) + manager = m_Owner as DotNetBarManager; + + if (xmlBar.HasAttribute("layout")) + layoutType = (eLayoutType)System.Xml.XmlConvert.ToInt32(xmlBar.GetAttribute("layout")); + + if (layoutType == eLayoutType.DockContainer) + m_TabsRearranged = true; + + if (xmlBar.HasAttribute("custom")) + customBar = System.Xml.XmlConvert.ToBoolean(xmlBar.GetAttribute("custom")); + + foreach (System.Xml.XmlElement xmlElem in xmlBar.ChildNodes) + { + switch (xmlElem.Name) + { + case "items": + { + for (int i = 0; i < xmlElem.ChildNodes.Count; i++) + { + System.Xml.XmlElement xmlItem = xmlElem.ChildNodes[i] as System.Xml.XmlElement; + string itemName = xmlItem.GetAttribute("name"); + string originalBar = xmlItem.GetAttribute("origBar"); + int originalPos = System.Xml.XmlConvert.ToInt32(xmlItem.GetAttribute("origPos")); + int actualPos = System.Xml.XmlConvert.ToInt32(xmlItem.GetAttribute("pos")); + bool visible = true; + if (xmlItem.HasAttribute("visible")) + visible = System.Xml.XmlConvert.ToBoolean(xmlItem.GetAttribute("visible")); + + if (layoutType == eLayoutType.DockContainer) + { + // Just adjust item position + if (this.Items.Contains(itemName)) + { + BaseItem item = this.Items[itemName]; + + if (item.Visible != visible) + item.Visible = visible; + + if (this.Items.IndexOf(this.Items[itemName]) != actualPos) + { + this.Items.Remove(item); + if (this.Items.Count > actualPos) + this.Items.Insert(actualPos, item); + else + this.Items.Add(item); + } + } + else if (manager != null) + { + // Move item from other bar onto this bar... + BaseItem item = manager.GetItem(itemName); + if (item != null && item is DockContainerItem) + { + Bar parentBar = item.ContainerControl as Bar; + item.Parent.SubItems.Remove(item); + if (item.Visible != visible) + item.Visible = visible; + if (this.Items.Count > actualPos) + this.Items.Insert(actualPos, item); + else + this.Items.Add(item); + if (parentBar != null && parentBar.Items.Count == 0) + { + if (parentBar.AutoHide) parentBar.AutoHide = false; + parentBar.Visible = false; + //manager.Bars.Remove(parentBar); + } + else if (parentBar != null && parentBar.VisibleItemCount == 0) + { + parentBar.Visible = false; + } + } + } + } + else + { + BaseItem item = null; + if (this.Items.Contains(itemName)) + { + item = this.Items[itemName]; + if (this.Items.IndexOf(itemName) != actualPos) + { + this.Items.Remove(item); + if (this.Items.Count > actualPos) + this.Items.Insert(actualPos, item); + else + this.Items.Add(item); + } + } + else + { + if (originalBar != "" && manager != null && manager.Bars.Contains(originalBar)) + { + if (manager.Bars[originalBar].Items.Contains(itemName)) + item = manager.Bars[originalBar].Items[itemName]; + } + if (item == null) + item = manager.GetItem(itemName, true); + if (item != null) + { + if (item.ContainerControl == null || originalBar == "" && !(item.ContainerControl is Bar)) + item = item.Copy(); + else + item.Parent.SubItems.Remove(item); + if (this.Items.Count > actualPos) + this.Items.Insert(actualPos, item); + else + this.Items.Add(item); + } + } + if (item != null) + { + if (item.Visible != visible) + item.Visible = visible; + item.OriginalBarName = originalBar; + item.OriginalPosition = originalPos; + item.UserCustomized = true; + } + } + } + break; + } + } + } + } + + // TODO: Menu Merge Implementation + // private bool IsParentMdiChild + // { + // get + // { + // IOwner owner=m_Owner as IOwner; + // if(owner!=null && owner.ParentForm!=null) + // { + // return ((IOwner)m_Owner).ParentForm.IsMdiChild; + // } + // return false; + // } + // } + + /// + /// Sets the client size of the bar excluding caption. This method is useful when setting the size of the bars with layout type DockContainer. + /// + /// Width of bar in pixels. + /// Height of bar in pixels. + [Obsolete("Method is obsolete. Use DocumentDockUIManager.SetBarWidth or DocumentDockUIManager.SetBarHeight instead. You can obtain DocumentDockUIManager using DockSite.GetDocumentUIManager method.")] + public void SetSize(int width, int height) + { + if (m_BarState == eBarState.Docked) + { + m_ItemContainer.MinHeight = height; + m_ItemContainer.MinWidth = width; + SyncLineMinWidth(); + SyncLineMinHeight(); + } + else + { + this.Size = new Size(width, height); + } + if (this.IsHandleCreated) + this.RecalcLayout(); + } + + /// + /// Sets the client size of the bar excluding caption. This method is useful when setting the size of the bars with layout type DockContainer. + /// + /// New bar size + [Obsolete("Method is obsolete. Use DocumentDockUIManager.SetBarWidth or DocumentDockUIManager.SetBarHeight instead. You can obtain DocumentDockUIManager using DockSite.GetDocumentUIManager method.")] + public void SetSize(System.Drawing.Size size) + { + SetSize(size.Width, size.Height); + } + + /// + /// Specifies background image position when container is larger than image. + /// + [Browsable(true), DevCoBrowsable(true),Category("Appearance"),DefaultValue(eBackgroundImagePosition.Stretch),Description("Specifies background image position when container is larger than image.")] + public eBackgroundImagePosition BackgroundImagePosition + { + get { return m_BackgroundImagePosition; } + set + { + if (m_BackgroundImagePosition != value) + { + m_BackgroundImagePosition = value; + this.Refresh(); + } + } + } + + /// + /// Specifies the transparency of background image. + /// + [Browsable(true), DefaultValue((byte)255),DevCoBrowsable(true),Category("Appearance"),Description("Specifies the transparency of background image.")] + public byte BackgroundImageAlpha + { + get { return m_BackgroundImageAlpha; } + set + { + if (m_BackgroundImageAlpha != value) + { + m_BackgroundImageAlpha = value; + this.Refresh(); + } + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackgroundImageAlpha() + { + return m_BackgroundImageAlpha != 255; + } + + /// + /// Sets/Gets the side bar image structure. + /// + [System.ComponentModel.Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SideBarImage SideBar + { + get + { + return m_SideBarImage; + } + set + { + m_SideBarImage = value; + } + } + + /// + /// Gets/Sets the caption of the Bar. This text is displayed in title of the Bar when Bar is floating. + /// + [DevCoBrowsable(true)] + public override string Text + { + get + { + return base.Text; + } + set + { + if (base.Text != value) + { + base.Text = value; + if (this.Visible && (m_BarState == eBarState.Floating || + (m_BarState == eBarState.Docked || m_BarState == eBarState.AutoHide) && + (m_GrabHandleStyle == eGrabHandleStyle.Caption || m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || + m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted))) + { + this.Refresh(); + } + } + } + } + + [DevCoBrowsable(true)] + public override System.Drawing.Font Font + { + get + { + return base.Font; + } + set + { + base.Font = value; + if (this.Font != null) + m_CustomFont = ShouldSerializeFont(); + } + } + + /// + /// Returns true if Font property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFont() + { + if (this.Font != null) + { + if (this.Font.Name != System.Windows.Forms.SystemInformation.MenuFont.Name || this.Font.Size != System.Windows.Forms.SystemInformation.MenuFont.Size || this.Font.Style != System.Windows.Forms.SystemInformation.MenuFont.Style) + return true; + else + return false; + } + return false; + } + /// + /// Designer method to reset the property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public new void ResetFont() + { + if (this.LayoutType == eLayoutType.DockContainer) + base.ResetFont(); + else + this.Font = System.Windows.Forms.SystemInformation.MenuFont.Clone() as Font; + } + + protected internal bool IsThemed + { + get + { + if (m_ThemeAware && this.Style != eDotNetBarStyle.Office2000 && BarFunctions.ThemedOS && Themes.ThemesActive) + return true; + return false; + } + } + + /// + /// Specifies whether Bar is drawn using Themes when running on OS that supports themes like Windows XP. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.DefaultValue(false),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Specifies whether SideBar is drawn using Themes when running on OS that supports themes like Windows XP.")] + public virtual bool ThemeAware + { + get + { + return m_ThemeAware; + } + set + { + m_ThemeAware = value; + m_ItemContainer.ThemeAware = value; + } + } + + /// + /// Returns current Bar state. + /// + [System.ComponentModel.Browsable(false)] + public eBarState BarState + { + get + { + return m_BarState; + } + } + + internal void SetBarState(eBarState state) + { + m_BarState = state; + if (m_BarState != eBarState.Popup && m_DropShadow != null) + { + m_DropShadow.Hide(); + m_DropShadow.Dispose(); + m_DropShadow = null; + } + } + + /// + /// Returns the collection of sub-items hosted on the Bar. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SubItemsCollection Items + { + get + { + if (m_ItemContainer == null) + return null; + return m_ItemContainer.SubItems; + } + } + + /// + /// Returns the reference to the container that containing the sub-items. + /// + [System.ComponentModel.Browsable(false)] + public GenericItemContainer ItemsContainer + { + get + { + return m_ItemContainer; + } + } + + /// + /// Gets/Sets whether the items that could not be displayed on the non-wrap Bar are displayed on popup menu or popup Bar. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates whether the items that could not be displayed on the non-wrap Bar are displayed on popup menu or popup Bar."),DefaultValue(false)] + public bool DisplayMoreItemsOnMenu + { + get + { + return m_ItemContainer.MoreItemsOnMenu; + } + set + { + m_ItemContainer.MoreItemsOnMenu = value; + } + } + + /// + /// Gets/Sets the spacing in pixels between the sub-items. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Indicates the spacing in pixels between the sub-items."),DefaultValue(0)] + public int ItemSpacing + { + get + { + return m_ItemContainer.ItemSpacing; + } + set + { + if (m_ItemContainer.ItemSpacing == value) + return; + m_ItemContainer.ItemSpacing = value; + this.RecalcLayout(); + } + } + + /// + /// Gets/Sets the padding in pixels. This represents the spacing between the top edge of the bar and the top of the item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Gets/Sets the padding in pixels. This represents the spacing between the top of the bar and the top of the item."),DefaultValue(1)] + public int PaddingTop + { + get + { + return m_ItemContainer.PaddingTop; + } + set + { + if (m_ItemContainer.PaddingTop == value) + return; + m_ItemContainer.PaddingTop = value; + if (this.DesignMode) + this.RecalcLayout(); + } + } + + /// + /// Gets/Sets the padding in pixels. This represents the spacing between the bottom edge of the bar and the bottom of the item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Gets/Sets the padding in pixels. This represents the spacing between the bottom edge of the bar and the bottom of the item."),DefaultValue(1)] + public int PaddingBottom + { + get + { + return m_ItemContainer.PaddingBottom; + } + set + { + if (m_ItemContainer.PaddingBottom == value) + return; + m_ItemContainer.PaddingBottom = value; + if (this.DesignMode) + this.RecalcLayout(); + } + } + + /// + /// Gets/Sets the padding in pixels. This represents the spacing between the left edge of the bar and the left side of the first item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Gets/Sets the padding in pixels. This represents the spacing between the left edge of the bar and the left position of the first item."),DefaultValue(1)] + public int PaddingLeft + { + get + { + return m_ItemContainer.PaddingLeft; + } + set + { + if (m_ItemContainer.PaddingLeft == value) + return; + m_ItemContainer.PaddingLeft = value; + if (this.DesignMode) + this.RecalcLayout(); + } + } + + /// + /// Gets/Sets the padding in pixels. This represents the spacing between the right edge of the bar and the right side of the last item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Gets/Sets the padding in pixels. This represents the spacing between the right edge of the bar and the right side of the last item."),DefaultValue(1)] + public int PaddingRight + { + get + { + return m_ItemContainer.PaddingRight; + } + set + { + if (m_ItemContainer.PaddingRight == value) + return; + m_ItemContainer.PaddingRight = value; + if (this.DesignMode) + this.RecalcLayout(); + } + } + + /// + /// Sets/Gets whether bar is menu bar. Menu bar will show system icons + /// for Maximized forms in MDI Applications. Only one bar can be a Menu bar in an application. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates Bar layout type."),DefaultValue(false)] + public bool MenuBar + { + get + { + return m_MenuBar; + } + set + { + m_MenuBar = value; + SetupAccessibility(); + } + } + + /// + /// Gets or sets the visual type of the bar. The type specified here is used to determine the appearance of the bar. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(eBarType.Toolbar), Category("Appearance"), Description("Indicates visual type of the bar. The type specified here is used to determine the appearance of the bar.")] + public eBarType BarType + { + get { return m_BarType; } + set + { + m_BarType = value; + if (m_BarType == eBarType.StatusBar) + m_ItemContainer.ToolbarItemsAlign = eContainerVerticalAlignment.Middle; + else + m_ItemContainer.ToolbarItemsAlign = eContainerVerticalAlignment.Top; + if (BarType == eBarType.DockWindow) + this.ResetFont(); + this.Invalidate(); + } + } + + /// + /// Gets or sets Bar Color Scheme. + /// + [System.ComponentModel.Editor(typeof(ColorSchemeVSEditor), typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Gets or sets Bar Color Scheme."),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DevComponents.DotNetBar.ColorScheme ColorScheme + { + get { return m_ColorScheme; } + set + { + if (value == null) + throw new ArgumentException("NULL is not a valid value for this property."); + m_ColorScheme = value; + if (this.Visible) + this.Refresh(); + } + } + + internal ColorScheme GetColorScheme() + { + if (BarFunctions.IsOffice2007Style(this.Style)) + { + Office2007Renderer r = this.GetRenderer() as Office2007Renderer; + if (r != null && r.ColorTable.LegacyColors != null) + return r.ColorTable.LegacyColors; + } + + if (m_Owner is DotNetBarManager && ((DotNetBarManager)m_Owner).UseGlobalColorScheme) + return ((DotNetBarManager)m_Owner).ColorScheme; + return m_ColorScheme; + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeColorScheme() + { + return m_ColorScheme.SchemeChanged; + } + + /// + /// Resets the ColorScheme property to its default value. + /// + public void ResetColorScheme() + { + m_ColorScheme.Refresh(); + this.Invalidate(); + } + + /// + /// Gets or sets Caption (Title bar) background color. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates the background color of the caption (Title bar)."),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color CaptionBackColor + { + get + { + return m_CaptionBackColor; + } + set + { + if (m_CaptionBackColor != value) + { + m_CaptionBackColor = value; + this.Refresh(); + } + } + } + + /// + /// Gets or sets Caption (Title bar) text color. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates the caption (Title bar) text color."),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color CaptionForeColor + { + get + { + return m_CaptionForeColor; + } + set + { + if (m_CaptionForeColor != value) + { + m_CaptionForeColor = value; + this.Refresh(); + } + } + } + + internal void ClearMDIChildSystemItems(bool bRecalcLayout) + { + if (m_ItemContainer == null) + return; + try + { + if (m_ItemContainer.SubItems.Contains("dotnetbarsysiconitem")) + m_ItemContainer.SubItems.Remove("dotnetbarsysiconitem"); + if (m_ItemContainer.SubItems.Contains("dotnetbarsysmenuitem")) + m_ItemContainer.SubItems.Remove("dotnetbarsysmenuitem"); + if (bRecalcLayout) + this.RecalcLayout(); + } + catch (Exception) + { + } + } + + internal void ShowMDIChildSystemItems(System.Windows.Forms.Form objMdiChild, bool bRecalcLayout) + { + ClearMDIChildSystemItems(bRecalcLayout); + + if (objMdiChild == null) + return; + + MDISystemItem mdi = new MDISystemItem("dotnetbarsysiconitem"); + mdi.Icon = objMdiChild.Icon; + if (!objMdiChild.ControlBox) + mdi.CloseEnabled = false; + if (!objMdiChild.MinimizeBox) + mdi.MinimizeEnabled = false; + mdi.Click += new System.EventHandler(this.MDISysItemClick); + mdi.IsSystemIcon = true; + m_ItemContainer.SubItems.Add(mdi, 0); + + mdi = new MDISystemItem("dotnetbarsysmenuitem"); + if (!objMdiChild.ControlBox) + mdi.CloseEnabled = false; + if (!objMdiChild.MinimizeBox) + mdi.MinimizeEnabled = false; + mdi.ItemAlignment = eItemAlignment.Far; + mdi.Click += new System.EventHandler(this.MDISysItemClick); + + m_ItemContainer.SubItems.Add(mdi); + + if (bRecalcLayout) + this.RecalcLayout(); + } + + private void MDISysItemClick(object sender, System.EventArgs e) + { + MDISystemItem mdi = sender as MDISystemItem; + IOwner owner = m_Owner as IOwner; + Form frm = null; + if (owner != null) + frm = owner.ActiveMdiChild; + if (frm == null) + { + ClearMDIChildSystemItems(true); + return; + } + if (mdi.LastButtonClick == SystemButton.Minimize) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, new IntPtr(NativeFunctions.SC_MINIMIZE), IntPtr.Zero); + //frm.WindowState=FormWindowState.Minimized; + } + else if (mdi.LastButtonClick == SystemButton.Restore) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, new IntPtr(NativeFunctions.SC_RESTORE), IntPtr.Zero); + //frm.WindowState=FormWindowState.Normal; + } + else if (mdi.LastButtonClick == SystemButton.Close) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, new IntPtr(NativeFunctions.SC_CLOSE), IntPtr.Zero); + } + else if (mdi.LastButtonClick == SystemButton.NextWindow) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, new IntPtr(NativeFunctions.SC_NEXTWINDOW), IntPtr.Zero); + } + } + + /// + /// Gets or sets whether toolbars with appropriate style appear with rounded corners. Default value is true. + /// + [Browsable(true), DevCoBrowsable(false), Category("Appearance"), Description("Indicates whether toolbars with appropriate style appear with rounded corners."), DefaultValue(true)] + public bool RoundCorners + { + get { return m_RoundCorners; } + set + { + m_RoundCorners = value; + this.RecalcLayout(); + } + } + + /// + /// Gets/Sets the visual style of the Bar. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Specifies the visual style of the Bar."),DefaultValue(eDotNetBarStyle.OfficeXP)] + public eDotNetBarStyle Style + { + get + { + return m_ItemContainer.Style; + } + set + { + //if(m_ItemContainer.Style==value) + // return; + m_ColorScheme.SwitchStyle(value); + m_ItemContainer.Style = value; + if ((m_ItemContainer.EffectiveStyle == eDotNetBarStyle.Office2003 || m_ItemContainer.EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(m_ItemContainer.EffectiveStyle)) && this.LayoutType == eLayoutType.Toolbar && this.GrabHandleStyle != eGrabHandleStyle.None && this.GrabHandleStyle != eGrabHandleStyle.ResizeHandle) + m_GrabHandleStyle = eGrabHandleStyle.Office2003; + SetDockTabStyle(m_ItemContainer.EffectiveStyle); + if (this.AutoHide) + { + AutoHidePanel panel = this.GetAutoHidePanel(); + if (panel != null) + panel.Style = value; + } + else + { + this.Invalidate(); + this.RecalcLayout(); + } + } + } + + //internal int MinClientSize + //{ + // get + // { + // if(this.SelectedDockTab>=0) + // { + // return ((DockContainerItem)m_TabDockItems.SelectedTab.AttachedItem).MinFormClientSize; + // } + // else if(m_ItemContainer.LayoutType==eLayoutType.DockContainer && m_ItemContainer.SubItems.Count==1 && m_ItemContainer.SubItems[0] is DockContainerItem) + // return ((DockContainerItem)m_ItemContainer.SubItems[0]).MinFormClientSize; + + // return m_MinClientSize; + // } + // set {m_MinClientSize=value;} + //} + + internal bool IsPositionOnDockTab(int x, int y) + { + // Receives the screen coordinates + Point p = this.PointToClient(new Point(x, y)); + if (m_GrabHandleRect.Contains(p) || m_TabDockItems != null && m_TabDockItems.Bounds.Contains(p)) + return true; + return false; + } + + internal void AppLostFocus() + { + if (m_ItemContainer != null) + m_ItemContainer.ContainerLostFocus(true); + if (!this.IsDisposed) + AccessibilityNotifyClients(AccessibleEvents.StateChange, 0); + } + internal void AppActivate() + { + if (!this.IsDisposed) + AccessibilityNotifyClients(AccessibleEvents.StateChange, 0); + } + + internal void HideBar() + { + if (m_DesignerParent && this.Parent != null) + { + this.Parent.Controls.Remove(this); + m_DesignerParent = false; + } + + if (m_BarState == eBarState.Floating) + { + if (m_Float != null) + { + m_Float.Hide(); + base.OnVisibleChanged(new EventArgs()); + } + } + else + { + base.Hide(); + + if (!m_DockingInProgress && !m_LayoutSuspended && this.Parent is DockSite && ((DockSite)this.Parent).DocumentDockContainer != null) + ((DockSite)this.Parent).GetDocumentUIManager().AdjustContainerSize(this, true); + + if (m_Owner != null && m_Owner is DotNetBarManager && ((DotNetBarManager)m_Owner).IsDisposed) + return; + this.RecalcLayout(); + } + } + + private bool m_DesignerParent = false; + private bool AddtoDesignTimeContainer() + { + ISite site = GetSite(); + if (site == null) + return false; + + IDesignerHost dh = site.GetService(typeof(IDesignerHost)) as IDesignerHost; + if (dh == null) return false; + + Control parent = dh.RootComponent as Control; + while (parent != null) + { + parent = parent.Parent; + if (parent != null && parent.GetType().Name.IndexOf("DesignerFrame") >= 0) + break; + } + if (parent == null || parent.Parent == null) return false; + //parent = parent.Parent; + Point p = parent.PointToClient(this.Location); + parent.Controls.Add(this); + this.Location = p; + base.Show(); + this.Update(); + this.BringToFront(); + m_DesignerParent = true; + return true; + } + + internal void ShowBar() + { + if (PassiveBar) + { + base.Show(); + this.Update(); + return; + } + + if (m_BarState == eBarState.Floating) + { + if (m_Float == null) + { + m_Float = new FloatingContainer(this); + m_Float.CreateControl(); + if (this.Parent != null) + { + if (this.Parent is DockSite) + ((DockSite)this.Parent).RemoveBar(this); + else + this.Parent.Controls.Remove(this); + } + this.Parent = null; + m_Float.Controls.Add(this); + // WE OVERRIDE BASE LOCATION WE MUST USE BASE. + base.Location = new Point(0, 0); + } + if (m_Float != null) + { + // TODO: Show method did not want to show the form, check has it been fixed in newer versions + //m_Float.Show(); + //NativeFunctions.SetWindowPos(m_Float.Handle.ToInt32(),NativeFunctions.HWND_TOP,0,0,0,0,NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOSIZE | NativeFunctions.SWP_NOACTIVATE | NativeFunctions.SWP_NOMOVE); + //m_Float.TopMost=true; + m_Float.TopLevel = true; + m_Float.Visible = true; + if (!base.Visible) + base.Visible = true; + m_Float.Refresh(); + } + } + else if (m_BarState == eBarState.Popup) + { + // Design mode add + if (m_ParentItem != null && (m_ParentItem.Site != null && m_ParentItem.Site.DesignMode || + m_ParentItem.Parent != null && m_ParentItem.Parent.Site != null && m_ParentItem.Parent.Site.DesignMode)) + { + if (AddtoDesignTimeContainer()) + return; + } + + //NativeFunctions.sndPlaySound("MenuPopup",NativeFunctions.SND_ASYNC | NativeFunctions.SND_NODEFAULT); + ePopupAnimation animation = m_PopupAnimation; + if (!BarFunctions.SupportsAnimation) + animation = ePopupAnimation.None; + else + { + IOwnerMenuSupport ownersupport = m_Owner as IOwnerMenuSupport; + if (animation == ePopupAnimation.ManagerControlled) + { + if (ownersupport != null) + animation = ownersupport.PopupAnimation; + if (animation == ePopupAnimation.ManagerControlled) + animation = ePopupAnimation.SystemDefault; + } + + if (animation == ePopupAnimation.SystemDefault) + animation = NativeFunctions.SystemMenuAnimation; + else if (animation == ePopupAnimation.Random) + { + Random r = new System.Random(); + int i = r.Next(2); + animation = ePopupAnimation.Fade; + if (i == 1) + animation = ePopupAnimation.Slide; + else if (i == 2) + animation = ePopupAnimation.Unfold; + } + } + + if (BarFunctions.IsOffice2007Style(this.Style) && this.BarType == eBarType.Toolbar) + SetRoundRegion(this); + + if (animation == ePopupAnimation.Fade && Environment.OSVersion.Version.Major >= 5) + { + // TODO: Blending was leaving the white dots in the region that was excluded, make sure that it is not happening for final release, test other AnimateWindows + NativeFunctions.AnimateWindow(this.Handle, BarFunctions.ANIMATION_INTERVAL, NativeFunctions.AW_BLEND); + } + else if (animation == ePopupAnimation.Slide) + NativeFunctions.AnimateWindow(this.Handle, BarFunctions.ANIMATION_INTERVAL, (NativeFunctions.AW_SLIDE | NativeFunctions.AW_HOR_POSITIVE | NativeFunctions.AW_VER_POSITIVE)); + else if (animation == ePopupAnimation.Unfold) + NativeFunctions.AnimateWindow(this.Handle, BarFunctions.ANIMATION_INTERVAL, (NativeFunctions.AW_HOR_POSITIVE | NativeFunctions.AW_VER_POSITIVE)); + else + base.Show(); + + if (animation != ePopupAnimation.None && this.Controls.Count > 0) + this.Refresh(); + + if (this.DisplayShadow && this.AlphaShadow) + { + if (m_DropShadow != null) + { + m_DropShadow.Hide(); + m_DropShadow.Dispose(); + } + m_DropShadow = new PopupShadow(true); + m_DropShadow.CreateControl(); + NativeFunctions.SetWindowPos(m_DropShadow.Handle, new IntPtr(NativeFunctions.HWND_NOTOPMOST), this.Left + 5, this.Top + 5, this.Width - 2, this.Height - 2, NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); + m_DropShadow.UpdateShadow(); + } + } + else + { + // Retain bar's position in controls collection it can change when bar is shown + // OnVisibleChanged will be triggered and index of the bar will be checked against + // this value. If it has changed it will be restored. + if (this.Parent is DockSite) + m_BarShowIndex = this.Parent.Controls.IndexOf(this); + else + m_BarShowIndex = -1; + + if (!m_DockingInProgress && !m_LayoutSuspended && this.Parent is DockSite && this.Parent.Dock != DockStyle.Fill && ((DockSite)this.Parent).DocumentDockContainer != null) + { + DockSite ds = this.Parent as DockSite; + m_LayoutSuspended = true; + base.Show(); + m_LayoutSuspended = false; + ds.GetDocumentUIManager().AdjustContainerSize(this, true); + // Reset the side by side docking for the bars so they are uniform + if (!m_BarDefinitionLoading) + { + DocumentBaseContainer dc = ds.GetDocumentUIManager().GetDocumentFromBar(this); + if (dc != null && dc.Parent is DocumentDockContainer) + { + DocumentDockContainer p = dc.Parent as DocumentDockContainer; + int visibleCount = p.Documents.VisibleCount; + if (visibleCount > 1) + { + if (p.Orientation == eOrientation.Horizontal && (ds.Dock == DockStyle.Top || ds.Dock == DockStyle.Bottom)) + { + //float f = 1 + dc.LayoutBounds.Width / (float)(p.DisplayBounds.Width - dc.LayoutBounds.Width); + //dc.SetLayoutBounds(new Rectangle(dc.LayoutBounds.X, dc.LayoutBounds.Y, (int)(dc.LayoutBounds.Width * f), dc.LayoutBounds.Height)); + dc.SetLayoutBounds(new Rectangle(dc.LayoutBounds.X, dc.LayoutBounds.Y, (int)(p.LayoutBounds.Width / visibleCount), dc.LayoutBounds.Height)); + } + else if (p.Orientation == eOrientation.Vertical && (ds.Dock == DockStyle.Left || ds.Dock == DockStyle.Right)) + { + //float f = 1 + dc.LayoutBounds.Height / (float)(p.DisplayBounds.Height - dc.LayoutBounds.Height); + //dc.SetLayoutBounds(new Rectangle(dc.LayoutBounds.X, dc.LayoutBounds.Y, dc.LayoutBounds.Width, (int)(dc.LayoutBounds.Height * f))); + dc.SetLayoutBounds(new Rectangle(dc.LayoutBounds.X, dc.LayoutBounds.Y, dc.LayoutBounds.Width, (int)(p.LayoutBounds.Height / visibleCount))); + } + } + } + } + DotNetBarManager man = this.Owner as DotNetBarManager; + if (man != null && man.SuspendLayout) + ds.NeedsLayout = true; + } + else + base.Show(); + + m_BarShowIndex = -1; + } + // This makes the bar paint BEFORE it returns out of this function + this.Update(); + } + + internal bool DockingInProgress + { + get + { + return m_DockingInProgress; + } + } + + /// + /// Gets/Sets whether the items will be wrapped into next line when Bar is full. Applies to both docked and floating Bar states. + /// + [System.ComponentModel.Browsable(false)] + public bool WrapItems + { + get + { + return m_ItemContainer.WrapItems; + } + } + + /// + /// Gets/Sets whether the items will be wrapped into next line when Bar is full. Applies only to Bars that are docked. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Indicates whether the items will be wrapped into next line when Bar is full. Applies only to Bars that are docked."),DefaultValue(false)] + public bool WrapItemsDock + { + get + { + return m_WrapItemsDock; + } + set + { + m_WrapItemsDock = value; + } + } + + /// + /// Gets/Sets whether the items will be wrapped into next line when Bar is full. Applies only to Bars that are floating. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Indicates whether the items will be wrapped into next line when Bar is full. Applies only to Bars that are floating."),DefaultValue(true)] + public bool WrapItemsFloat + { + get + { + return m_WrapItemsFloat; + } + set + { + m_WrapItemsFloat = value; + } + } + + /// + /// Gets/Sets the grab handle style of the docked Bars. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates the grab handle style of the docked Bars."),DefaultValue(eGrabHandleStyle.None)] + public eGrabHandleStyle GrabHandleStyle + { + get + { + return m_GrabHandleStyle; + } + set + { + if (m_GrabHandleStyle == value) + return; + m_GrabHandleStyle = value; + SetupAccessibility(); + if (this.Visible && !m_LayoutSuspended) + this.RecalcLayout(); + } + } + + /// + /// Gets the grab handle client rectangle. + /// + [Browsable(false), DevCoBrowsable(false)] + public Rectangle GrabHandleRect + { + get + { + return m_GrabHandleRect; + } + } + + internal void DockContainerItemCanCloseChanged(DockContainerItem item, eDockContainerClose oldValue, eDockContainerClose newValue) + { + if (SelectedDockContainerItem != item) return; + UpdateCloseButtonVisibility(); + } + + private void UpdateCloseButtonVisibility() + { + bool canHideResolved = this.CanHideResolved; + + if (m_BarState == eBarState.Floating || m_BarState == eBarState.Docked && (m_GrabHandleStyle == eGrabHandleStyle.Caption || m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted)) + this.Invalidate(m_GrabHandleRect); + + if (m_TabDockItems != null && m_TabDockItems._TabSystemBox != null) + { + m_TabDockItems._TabSystemBox.CloseVisible = canHideResolved; + } + } + + /// + /// Returns CanClose based on the selected dock-container item. + /// + private bool CanHideResolved + { + get + { + DockContainerItem item = this.SelectedDockContainerItem; + if (item == null || item.CanClose == eDockContainerClose.Inherit) + return CanHide; + return item.CanClose == eDockContainerClose.Yes; + } + } + + /// + /// Gets/Sets whether the Bar can be hidden by end-user. Applies to Document docked bars only. + /// + [Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Determines whether bar can be hidden."),DefaultValue(false)] + public bool CanHide + { + get + { + return m_CanHide; + } + set + { + if (m_CanHide == value) + return; + m_CanHide = value; + if (m_BarState == eBarState.Floating || m_BarState == eBarState.Docked && (m_GrabHandleStyle == eGrabHandleStyle.Caption || m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted)) + this.Invalidate(m_GrabHandleRect); + UpdateDockTabSettings(); + if (m_TabDockItems != null && BarFunctions.IsHandleValid(this)) + { + m_TabDockItems.RecalcSize(); + if (this.DesignMode) + m_TabDockItems.Invalidate(); + } + } + } + + private bool EffectiveCanMaximizeFloating + { + get + { + return _CanMaximizeFloating && this.LayoutType == eLayoutType.DockContainer && + this.Parent is FloatingContainer; + } + } + + private bool _CanMaximizeFloating = true; + /// + /// Indicates whether Maximize button is visible on floating dock windows. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether Maximize button is visible on floating dock windows.")] + public bool CanMaximizeFloating + { + get { return _CanMaximizeFloating; } + set + { + if (value != _CanMaximizeFloating) + { + bool oldValue = _CanMaximizeFloating; + _CanMaximizeFloating = value; + OnCanMaximizeFloatingChanged(oldValue, value); + } + } + } + /// + /// Called when CanMaximizeFloating property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCanMaximizeFloatingChanged(bool oldValue, bool newValue) + { + if (m_BarState == eBarState.Floating && (m_GrabHandleStyle == eGrabHandleStyle.Caption || m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted)) + this.Invalidate(m_GrabHandleRect); + //OnPropertyChanged(new PropertyChangedEventArgs("CanMaximizeFloating")); + } + + /// + /// Gets/Sets border style when Bar is docked. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates border style when Bar is docked."),DefaultValue(eBorderType.None)] + public eBorderType DockedBorderStyle + { + get + { + return m_DockedBorder; + } + set + { + if (m_DockedBorder == value) + return; + m_DockedBorder = value; + if (m_BarState == eBarState.Docked && this.Visible) + this.RecalcLayout(); + } + } + + /// + /// Gets/Sets whether floating bar is hidden when application loses focus. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(true),Category("Docking"),Description("Indicates whether floating bar is hidden when application loses focus.")] + public bool HideFloatingInactive + { + get + { + return m_HideFloatingInactive; + } + set + { + m_HideFloatingInactive = value; + } + } + + /// + /// Gets/Sets whether tab navigation buttons are shown for tabbed dockable bars. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(false),Category("Docking"),Description("Indicates whether tab navigation buttons are shown for tabbed dockable bars.")] + public bool TabNavigation + { + get + { + return m_TabNavigation; + } + set + { + if (m_TabNavigation != value) + { + m_TabNavigation = value; + UpdateDockTabSettings(); + } + } + } + + /// + /// Gets or sets the border line color when docked border is a single line. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates the border line color when docked border is a single line.")] + public Color SingleLineColor + { + get + { + return m_SingleLineColor; + } + set + { + if (m_SingleLineColor != value) + { + m_SingleLineColor = value; + if (m_BarState == eBarState.Docked && this.Visible && m_DockedBorder == eBorderType.SingleLine) + this.Refresh(); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSingleLineColor() + { + return (m_SingleLineColor != SystemColors.ControlDark); + } + + /// + /// Gets/Sets whether Bar is visible or not. + /// + [DevCoBrowsable(true), DefaultValue(true)] + public new bool Visible + { + get + { + if (m_BarState == eBarState.Floating && m_Float != null) + return m_Float.Visible; + return base.Visible; + } + set + { + m_IsVisible = value; + if (base.Visible == value) + { + // This allows the Bar to be hidden when Visible property is set from forms constructor... + if (/*!this.IsHandleCreated &&*/ value == false) + base.Visible = false; + return; + } + if (value) + this.ShowBar(); + else + this.HideBar(); + } + } + + /// + /// Returns number of items that have Visible property set to true. + /// + [Browsable(false)] + public int VisibleItemCount + { + get + { + return m_ItemContainer.VisibleSubItems; + } + } + + private BaseItem GetFirstVisibleItem() + { + foreach (BaseItem item in this.Items) + { + if (item.Visible) + return item; + } + return null; + } + + /// + /// Gets or sets whether bar is valid drop target for end-user bar customization. Default value is true. + /// When bar is used as dock container then you can use this property to prevent docking of other bars as dock tabs. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Determines whether end-user can drag and drop items on the Bar."),DefaultValue(true)] + public bool AcceptDropItems + { + get + { + return m_AcceptDropItems; + } + set + { + m_AcceptDropItems = value; + } + } + + /// + /// Gets or sets whether items on the Bar can be customized. + /// + [Browsable(true), Category("Behavior"),Description("Gets or sets whether items on the Bar can be customized."),DefaultValue(true)] + public bool CanCustomize + { + get + { + if (m_ItemContainer != null) + return m_ItemContainer.CanCustomize; + return false; + } + set + { + if (this.DesignMode) return; + if (m_ItemContainer != null) + m_ItemContainer.CanCustomize = value; + } + } + + + /// + /// Makes the Bar display by setting the visible property to true. + /// + public new void Show() + { + this.Visible = true; + } + + /// + /// Hides the Bar. + /// + public new void Hide() + { + if (this.AutoHide) + this.AutoHide = false; + this.Visible = false; + this.RecalcLayout(); + } + + /// + /// Specifies whether Bar was created by user using Customize dialog. + /// + [System.ComponentModel.Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool CustomBar + { + get + { + return m_CustomBar; + } + set + { + m_CustomBar = value; + } + } + + /// + /// Gets/Sets the Bar name used to identify Bar from code. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Design"),System.ComponentModel.Description("Bar name that can be used to identify Bar from code.")] + public new string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + if (this.Site != null) + this.Site.Name = value; + } + } + + /// + /// Gets/Sets the Image size for all sub-items on the Bar. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Specifies the Image size that will be used by items on this bar."),DefaultValue(eBarImageSize.Default)] + public eBarImageSize ImageSize + { + get + { + return m_ImageSize; + } + set + { + if (m_ImageSize == value) + return; + m_ImageSize = value; + m_ItemContainer.RefreshImageSize(); + this.RecalcLayout(); + } + } + + /// + /// Gets or sets the layout type. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Indicates Bar layout type."),DefaultValue(eLayoutType.Toolbar)] + public eLayoutType LayoutType + { + get + { + if (m_ItemContainer == null) + return eLayoutType.Toolbar; + return m_ItemContainer.LayoutType; + } + set + { + if (m_ItemContainer.LayoutType == value) + return; + m_ItemContainer.LayoutType = value; + if (value == eLayoutType.DockContainer) + this.ResetFont(); + SetupAccessibility(); + this.RecalcLayout(); + } + } + + /// + /// Gets or sets whether all buttons are automatically resized to the largest button in collection. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates that buttons will be automatically resized to match the size of the largest button on the bar."),DefaultValue(false)] + public bool EqualButtonSize + { + get + { + return m_ItemContainer.EqualButtonSize; + } + set + { + if (m_ItemContainer.EqualButtonSize == value) + return; + m_ItemContainer.EqualButtonSize = value; + this.RecalcLayout(); + } + } + + /// + /// Gets or sets rounded corner size for styles that use rounded corners. + /// + internal int CornerSize + { + get { return m_CornerSize; } + set { m_CornerSize = value; } + } + + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is false. + /// + [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public bool AntiAlias + { + get { return m_AntiAlias; } + set + { + if (m_AntiAlias != value) + { + m_AntiAlias = value; + this.Invalidate(); + } + } + } + + + /// + /// Gets or sets whether mouse over fade effect is enabled for buttons. Default value is false. Note that Fade effect + /// will work only when Office2007 style is used. For other styles this property has no effect and fade animation is not used regardless + /// this property setting. + /// + [Browsable(true), DefaultValue(false), Category("Appearance"), Description("Indicates whether mouse over fade effect for buttons is enabled.")] + public bool FadeEffect + { + get { return m_FadeEffect; } + set + { + m_FadeEffect = value; + } + } + + /// + /// Gets whether fade effect should be in use. + /// + internal bool IsFadeEnabled + { + get + { + if (this.DesignMode || (!BarFunctions.IsOffice2007Style(m_ItemContainer.EffectiveStyle)) || m_FadeEffect && NativeFunctions.IsTerminalSession() || this.IsThemed || TextDrawing.UseTextRenderer) + return false; + return m_FadeEffect; + } + } + + /// + /// Gets or sets the Bar back color. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Specifies background color of the Bar."),DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override Color BackColor + { + get + { + if (m_ItemContainer != null) + return m_ItemContainer.BackColor; + else + { + return base.BackColor; + } + } + set + { + if (m_ItemContainer != null) + m_ItemContainer.BackColor = value; + else + base.BackColor = value; + this.Invalidate(); + } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void ResetBackColor() + { + if (m_ItemContainer != null) + m_ItemContainer.BackColor = Color.Empty; + else + base.BackColor = SystemColors.Control; + } + public bool ShouldSerializeBackColor() + { + if (m_ItemContainer != null) + { + if (!m_ItemContainer.m_BackgroundColor.IsEmpty) + return true; + } + return false; + } + + /// + /// Returns whether Size property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSize() + { + if (this.LayoutType == eLayoutType.DockContainer && this.Parent is DockSite && this.Parent.Dock == DockStyle.Fill) + return false; + return true; + } + + /// + /// Gets or sets the Bar customize menu (Applies to the bars with LayoutType set to DockWindow only). + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates the Customize popup menu."),DefaultValue(null)] + public PopupItem CustomizeMenu + { + get + { + return m_CustomizeMenu; + } + set + { + m_CustomizeMenu = value; + } + } + + /// + /// Indicates the auto-hide side of the parent form where bar is positioned. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates the auto-hide side of the parent form where bar is positioned.")] + public eDockSide AutoHideSide + { + get + { + eDockSide side = eDockSide.None; + if (m_AutoHideState) + { + switch (m_LastDockSiteInfo.DockSide) + { + case DockStyle.Left: + { + side = eDockSide.Left; + break; + } + case DockStyle.Right: + { + side = eDockSide.Right; + break; + } + case DockStyle.Top: + { + side = eDockSide.Top; + break; + } + default: + { + side = eDockSide.Bottom; + break; + } + } + } + return side; + } + } + + /// + /// Gets or sets whether tab text is always visible while bar is in auto-hide state. Default value is false which indicates that only text for the active dock tab is visible. + /// + [Browsable(true), DefaultValue(false), Category("Auto-Hide"), Description("")] + public bool AutoHideTabTextAlwaysVisible + { + get { return m_AutoHideTextAlwaysVisible; } + set + { + m_AutoHideTextAlwaysVisible = value; + if (this.AutoHide && this.GetAutoHidePanel() != null) + this.GetAutoHidePanel().Invalidate(); + } + } + + private bool m_AutoHideStateDelayed = false; + /// + /// Indicates whether Bar is in auto-hide state. Applies to non-document dockable bars only. + /// + [Browsable(true), DefaultValue(false), DevCoBrowsable(true), System.ComponentModel.Category("Auto-Hide"), System.ComponentModel.Description("Indicates whether Bar is in auto-hide state. Applies to non-document dockable bars only."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool AutoHide + { + get + { + return m_AutoHideState; + } + set + { + if (this.DesignMode) + return; + if (m_LayoutSuspended) + { + m_AutoHideStateDelayed = value; + return; + } + if (!m_CanAutoHide || this.LayoutType != eLayoutType.DockContainer || this.Parent != null && this.Parent.Dock == DockStyle.Fill && value) + return; + if (m_AutoHideState == value) + return; + + m_AutoHideState = value; + AutoHideStateChanged(); + InvokeAutoHideChanged(); + } + } + + /// + /// Gets or sets the visibility of the bar when bar is in auto-hide state. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false),System.ComponentModel.Category("Auto-Hide"),System.ComponentModel.Description("Gets or sets the visibility of the bar when bar is in auto-hide state."), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public bool AutoHideVisible + { + get + { + return this.Visible; + } + set + { + if (!this.AutoHide || this.Visible == value) + return; + + AutoHidePanel panel = GetAutoHidePanel(m_LastDockSiteInfo.DockSide); + if (value && panel != null && m_AutoHideState) + panel.ShowBar(this); + else if (!value && panel != null && m_AutoHideState) + panel.HideBar(this); + } + } + + /// + /// Indicates whether Bar can be auto hidden. + /// + [Browsable(true), DefaultValue(true),Category("Auto-Hide"),Description("Indicates whether Bar can be auto hidden.")] + public bool CanAutoHide + { + get + { + return m_CanAutoHide; + } + set + { + m_CanAutoHide = value; + if (!m_CanAutoHide) + { + m_SystemButtons.AutoHideButtonRect = Rectangle.Empty; + m_SystemButtons.MouseOverAutoHide = false; + m_SystemButtons.MouseDownAutoHide = false; + } + if (this.IsHandleCreated) + this.Invalidate(); + } + } + + private Component m_GlobalParentComponent = null; + /// + /// Gets or sets the global parent control used as part of Global Items feature when bar is used as context menu bar. This property is used internally by + /// DotNetBar and should not be set directly. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Component GlobalParentComponent + { + get { return m_GlobalParentComponent; } + set { m_GlobalParentComponent = value; } + } + + /// + /// Returns the first child item with specified name regardless of it's hierarchy. + /// + /// Item name. + /// + public BaseItem GetItem(string name) + { + BaseItem item = BarFunctions.GetSubItemByName(m_ItemContainer, name); + if (item != null) + return item; + + if (m_GlobalParentComponent != null) + { + if (m_GlobalParentComponent is RibbonControl) + return ((RibbonControl)m_GlobalParentComponent).RibbonStrip.GetItem(name); + else if (m_GlobalParentComponent is DotNetBarManager) + return ((DotNetBarManager)m_GlobalParentComponent).GetItem(name); + } + + return null; + } + + /// + /// Returns the collection of items with the specified name. + /// + /// Item name to look for. + /// + public ArrayList GetItems(string ItemName) + { + ArrayList list = new ArrayList(15); + if (m_GlobalParentComponent != null) + { + if (m_GlobalParentComponent is RibbonControl) + list.AddRange(((RibbonControl)m_GlobalParentComponent).RibbonStrip.GetItems(ItemName)); + else if (m_GlobalParentComponent is DotNetBarManager) + list.AddRange(((DotNetBarManager)m_GlobalParentComponent).GetItems(ItemName)); + } + else + { + BarFunctions.GetSubItemsByName(m_ItemContainer, ItemName, list); + } + + return list; + } + + /// + /// Returns the collection of items with the specified name and type. + /// + /// Item name to look for. + /// Item type to look for. + /// + public ArrayList GetItems(string ItemName, Type itemType) + { + ArrayList list = new ArrayList(15); + + if (m_GlobalParentComponent != null) + { + if (m_GlobalParentComponent is RibbonControl) + list.AddRange(((RibbonControl)m_GlobalParentComponent).RibbonStrip.GetItems(ItemName, itemType)); + else if (m_GlobalParentComponent is DotNetBarManager) + list.AddRange(((DotNetBarManager)m_GlobalParentComponent).GetItems(ItemName, itemType)); + } + else + { + BarFunctions.GetSubItemsByNameAndType(m_ItemContainer, ItemName, list, itemType); + } + + return list; + } + + /// + /// Returns the collection of items with the specified name and type. This member is not implemented and should not be used. + /// + /// Item name to look for. + /// Item type to look for. + /// Indicates whether GlobalName property is used for searching. + /// + public ArrayList GetItems(string ItemName, Type itemType, bool useGlobalName) + { + ArrayList list = new ArrayList(15); + + if (m_GlobalParentComponent != null) + { + if (m_GlobalParentComponent is RibbonControl) + list.AddRange(((RibbonControl)m_GlobalParentComponent).RibbonStrip.GetItems(ItemName, itemType, useGlobalName)); + else if (m_GlobalParentComponent is DotNetBarManager) + list.AddRange(((DotNetBarManager)m_GlobalParentComponent).GetItems(ItemName, itemType, false, useGlobalName)); + } + else + { + BarFunctions.GetSubItemsByNameAndType(m_ItemContainer, ItemName, list, itemType, useGlobalName); + } + + return list; + } + + /// + /// Returns AutoHidePanel that bar is on if in auto-hide state otherwise returns null. + /// + /// AutoHidePanel object or null if bar is not in auto-hide state. + public AutoHidePanel GetAutoHidePanel() + { + if (!this.AutoHide) + return null; + + return GetAutoHidePanel(m_LastDockSiteInfo.DockSide); + } + + private AutoHidePanel GetAutoHidePanel(DockStyle dock) + { + IOwnerAutoHideSupport ownerAutoHide = m_Owner as IOwnerAutoHideSupport; + if (ownerAutoHide == null) + return null; + + AutoHidePanel panel = null; + switch (m_LastDockSiteInfo.DockSide) + { + case DockStyle.Left: + { + panel = ownerAutoHide.LeftAutoHidePanel; + break; + } + case DockStyle.Right: + { + panel = ownerAutoHide.RightAutoHidePanel; + break; + } + case DockStyle.Top: + { + panel = ownerAutoHide.TopAutoHidePanel; + break; + } + default: + { + panel = ownerAutoHide.BottomAutoHidePanel; + break; + } + } + + if (this.AntiAlias) panel.AntiAlias = true; + panel.Style = this.Style; + + return panel; + } + private Size GetLargestMinSize() + { + Size ret = Size.Empty; + foreach (BaseItem item in m_ItemContainer.SubItems) + { + if (item is DockContainerItem) + { + DockContainerItem dock = item as DockContainerItem; + if (dock.MinimumSize.Width > ret.Width) + ret.Width = dock.MinimumSize.Width; + if (dock.MinimumSize.Height > ret.Height) + ret.Height = dock.MinimumSize.Height; + } + } + return ret; + } + private Control GetOwnerControl() + { + Control parentControl = null; + IOwner owner = m_Owner as IOwner; + if (owner is DotNetBarManager && ((DotNetBarManager)owner).TopDockSite != null) + parentControl = ((DotNetBarManager)owner).TopDockSite.Parent; + else if (owner != null) + parentControl = owner.ParentForm; + return parentControl; + } + + private void AutoHideStateChanged() + { + IOwner owner = m_Owner as IOwner; + IOwnerAutoHideSupport ownerAutoHide = m_Owner as IOwnerAutoHideSupport; + if (owner == null) + return; + + Control parentControl = GetOwnerControl(); + + if (parentControl == null) + return; + + if (m_AutoHideState) + { + if (m_BarState == eBarState.AutoHide) + return; + if (m_TabDockItems != null) + m_TabDockItems.Visible = false; + // Remember last docking info + DockSiteInfo tempInfo = m_LastDockSiteInfo; + m_LastDockSiteInfo = new DockSiteInfo(); + // Preserve the relative last docked to bar in case the return to same docking position is needed + m_LastDockSiteInfo.LastRelativeDocumentId = tempInfo.LastRelativeDocumentId; + m_LastDockSiteInfo.LastRelativeDockToBar = tempInfo.LastRelativeDockToBar; + + if (!m_BarDefinitionLoading) + { + if (this.Height > 0) + m_LastDockSiteInfo.DockedHeight = this.Height; + else if (m_ItemContainer != null && m_ItemContainer.MinHeight > 0) + m_LastDockSiteInfo.DockedHeight = m_ItemContainer.MinHeight + 22; + if (this.Width > 0) + m_LastDockSiteInfo.DockedWidth = this.Width; + else if (m_ItemContainer != null && m_ItemContainer.MinWidth > 0) + m_LastDockSiteInfo.DockedWidth = m_ItemContainer.MinWidth + 22; + + // This will force proper recalculation in SetAutoHideSize procedure + System.Drawing.Size minSize = GetLargestMinSize(); + if (minSize.Width > m_LastDockSiteInfo.DockedWidth) + m_LastDockSiteInfo.DockedWidth = 0; + if (minSize.Height > m_LastDockSiteInfo.DockedHeight) + m_LastDockSiteInfo.DockedHeight = 0; + } + + m_LastDockSiteInfo.DockLine = this.DockLine; + m_LastDockSiteInfo.DockOffset = this.DockOffset; + if (this.Parent != null && m_BarState == eBarState.Docked) + m_LastDockSiteInfo.DockSide = this.Parent.Dock; + else + m_LastDockSiteInfo.DockSide = DockStyle.Left; + if (this.Parent != null && this.Parent is DockSite) + { + m_LastDockSiteInfo.InsertPosition = ((DockSite)this.Parent).Controls.GetChildIndex(this); + m_LastDockSiteInfo.objDockSite = (DockSite)this.DockedSite; + } + + // Undock the window + m_BarState = eBarState.AutoHide; + ResetActiveControl(); + parentControl.SuspendLayout(); + try + { + // Check for parent since if bar is deserialized there is no parent and state is Docked by default + base.Visible = false; + if (this.Parent != null && this.Parent is DockSite) + { + DockSite ds = this.Parent as DockSite; + if (ds.DocumentDockContainer != null) + { + // Remember the split view docking if it was in effect + if (ds.Dock != DockStyle.Fill) + { + DocumentBarContainer dbr = ds.GetDocumentUIManager().GetDocumentFromBar(this) as DocumentBarContainer; + if (dbr != null && dbr.Parent is DocumentDockContainer) + { + DocumentDockContainer ddc = dbr.Parent as DocumentDockContainer; + if (ddc.Orientation == eOrientation.Horizontal && (ds.Dock == DockStyle.Top || ds.Dock == DockStyle.Bottom) || + ddc.Orientation == eOrientation.Vertical && (ds.Dock == DockStyle.Left || ds.Dock == DockStyle.Right) && ddc.Documents.Count > 1) + { + for (int i = 0; i < ddc.Documents.Count; i++) + { + if (ddc.Documents[i] is DocumentBarContainer && ddc.Documents[i].Visible && ddc.Documents[i] != dbr) + { + m_LastDockSiteInfo.MouseOverBar = ((DocumentBarContainer)ddc.Documents[i]).Bar; + if (i < ddc.Documents.IndexOf(dbr)) + m_LastDockSiteInfo.MouseOverDockSide = (ddc.Orientation == eOrientation.Horizontal ? eDockSide.Left : eDockSide.Bottom); + else + m_LastDockSiteInfo.MouseOverDockSide = (ddc.Orientation == eOrientation.Horizontal ? eDockSide.Right : eDockSide.Top); + break; + } + } + } + } + } + ds.GetDocumentUIManager().UnDock(this); + } + else + ((DockSite)this.Parent).RemoveBar(this); + } + this.Parent = null; + + parentControl.Controls.Add(this); + parentControl.Controls.SetChildIndex(this, 0); + AutoHidePanel panel = GetAutoHidePanel(m_LastDockSiteInfo.DockSide); + panel.AddBar(this); + + if (!m_BarDefinitionLoading) + SetAutoHideSize(); + if (!m_IgnoreAnimation && m_AutoHideAnimationTime != 0) + this.Visible = true; + } + finally + { + parentControl.ResumeLayout(); + } + //this.RecalcSize(); + if (!m_BarDefinitionLoading) + { + this.Update(); + AnimateHide(); + } + } + else + { + AutoHidePanel panel = GetAutoHidePanel(m_LastDockSiteInfo.DockSide); + panel.RemoveBar(this); + if (m_LastDockSiteInfo.objDockSite != null) + { + if (m_LastDockSiteInfo.MouseOverBar != null) + { + if (m_LastDockSiteInfo.objDockSite.GetDocumentUIManager() == null || + m_LastDockSiteInfo.objDockSite.GetDocumentUIManager().GetDocumentFromBar(m_LastDockSiteInfo.MouseOverBar) == null) + { + m_LastDockSiteInfo.MouseOverBar = null; + m_LastDockSiteInfo.MouseOverDockSide = eDockSide.None; + m_LastDockSiteInfo.NewLine = true; + } + } + } + else + { + m_LastDockSiteInfo.MouseOverBar = null; + m_LastDockSiteInfo.MouseOverDockSide = eDockSide.None; + m_LastDockSiteInfo.NewLine = true; + } + + //m_LastDockSiteInfo.NewLine = true; + DockingHandler(m_LastDockSiteInfo, Point.Empty); + if (!this.IsVisible) + this.Visible = true; + this.RefreshDockTab(true); + this.ResizeDockTab(); + m_ItemContainer.MinHeight = 0; + m_ItemContainer.MinWidth = 0; + } + } + + internal void SetAutoHideSize() + { + IOwner owner = m_Owner as IOwner; + IOwnerBarSupport ownerBar = m_Owner as IOwnerBarSupport; + IOwnerAutoHideSupport ownerAutoHide = m_Owner as IOwnerAutoHideSupport; + Control parentControl = this.GetOwnerControl(); + + if (owner == null || parentControl == null || ownerBar == null || ownerAutoHide == null) + return; + + int width = parentControl.ClientSize.Width; + int height = parentControl.ClientSize.Height; + int x = 0, y = 0; + + //if(ownerBar.TopDockSite.Parent is UserControl) + { + switch (m_LastDockSiteInfo.DockSide) + { + case DockStyle.Left: + { + width = ownerBar.LeftDockSite.Parent.Width; + height = ownerBar.LeftDockSite.Parent.Height; + Point pLoc = ownerAutoHide.LeftAutoHidePanel.Location; + x = pLoc.X + ownerAutoHide.LeftAutoHidePanel.Width; + y = pLoc.Y; + break; + } + case DockStyle.Right: + { + width = ownerBar.RightDockSite.Parent.Width; + height = ownerBar.RightDockSite.Parent.Height; + Point pLoc = ownerAutoHide.RightAutoHidePanel.Location; + x = pLoc.X; + y = pLoc.Y; + break; + } + case DockStyle.Top: + { + width = ownerBar.TopDockSite.Parent.Width; + height = ownerBar.TopDockSite.Parent.Height; + Point pLoc = ownerAutoHide.TopAutoHidePanel.Location; + x = pLoc.X; + y = pLoc.Y + ownerAutoHide.TopAutoHidePanel.Height; + break; + } + default: + { + width = ownerBar.BottomDockSite.Parent.Width; + height = ownerBar.BottomDockSite.Parent.Height; + Point pLoc = ownerAutoHide.BottomAutoHidePanel.Location; + x = pLoc.X; + y = pLoc.Y; + break; + } + } + } + + switch (m_LastDockSiteInfo.DockSide) + { + case DockStyle.Left: + { + // if(ownerBar.TopDockSite.Parent.Controls.IndexOf(ownerBar.TopDockSite)>ownerBar.TopDockSite.Parent.Controls.IndexOf(ownerBar.LeftDockSite)) + // { + // height-=ownerBar.TopDockSite.Height; + // y=ownerBar.TopDockSite.Bottom; + // } + // if(ownerAutoHide.HasBottomAutoHidePanel) + // height-=ownerAutoHide.BottomAutoHidePanel.Height; + // if(ownerBar.BottomDockSite.Parent.Controls.IndexOf(ownerBar.BottomDockSite)>ownerBar.BottomDockSite.Parent.Controls.IndexOf(ownerBar.LeftDockSite)) + // height-=ownerBar.BottomDockSite.Height; + height = ownerAutoHide.LeftAutoHidePanel.Height; + width = m_LastDockSiteInfo.DockedWidth; + if (width == 0) + { + int index = -1; + if (this.SelectedDockTab >= 0 && this.Items[this.SelectedDockTab] is DockContainerItem) + index = this.SelectedDockTab; + else if (this.Items.Count > 0 && this.Items[0] is DockContainerItem) + index = 0; + if (index >= 0) + width = Math.Max(((DockContainerItem)this.Items[index]).MinimumSize.Width, ((DockContainerItem)this.Items[index]).Width); + this.EnableRedraw = false; + try + { + this.Size = new Size(width, height); + this.RecalcSize(); + } + finally + { + this.EnableRedraw = true; + } + width = this.Width; + m_LastDockSiteInfo.DockedWidth = width; + } + // if(!(ownerBar.TopDockSite.Parent is UserControl)) + // { + // x=ownerAutoHide.LeftAutoHidePanel.Right; + // } + // else + // y+=ownerBar.TopDockSite.Top; + break; + } + case DockStyle.Right: + { + // if(ownerBar.TopDockSite.Parent.Controls.IndexOf(ownerBar.TopDockSite)>ownerBar.TopDockSite.Parent.Controls.IndexOf(ownerBar.RightDockSite)) + // { + // height-=ownerBar.TopDockSite.Height; + // y=ownerBar.TopDockSite.Bottom; + // } + // if(ownerAutoHide.HasBottomAutoHidePanel) + // height-=ownerAutoHide.BottomAutoHidePanel.Height; + // if(ownerBar.BottomDockSite.Parent.Controls.IndexOf(ownerBar.BottomDockSite)>ownerBar.BottomDockSite.Parent.Controls.IndexOf(ownerBar.RightDockSite)) + // height-=ownerBar.BottomDockSite.Height; + height = ownerAutoHide.RightAutoHidePanel.Height; + width = m_LastDockSiteInfo.DockedWidth; + if (width == 0) + { + int index = -1; + if (this.SelectedDockTab >= 0 && this.Items[this.SelectedDockTab] is DockContainerItem) + index = this.SelectedDockTab; + else if (this.Items.Count > 0 && this.Items[0] is DockContainerItem) + index = 0; + if (index >= 0) + width = Math.Max(((DockContainerItem)this.Items[index]).MinimumSize.Width, ((DockContainerItem)this.Items[index]).Width); + this.EnableRedraw = false; + try + { + this.Size = new Size(width, height); + this.RecalcSize(); + } + finally + { + this.EnableRedraw = true; + } + width = this.Width; + m_LastDockSiteInfo.DockedWidth = width; + } + // if(!(ownerBar.TopDockSite.Parent is UserControl)) + // x=ownerAutoHide.RightAutoHidePanel.Left-width; + // else + // { + x -= width; + //y+=ownerBar.TopDockSite.Top; + //} + break; + } + case DockStyle.Top: + { + // if(ownerAutoHide.HasLeftAutoHidePanel) + // { + // width-=ownerAutoHide.LeftAutoHidePanel.Width; + // x+=ownerAutoHide.LeftAutoHidePanel.Width; + // } + // if(ownerAutoHide.HasRightAutoHidePanel) + // { + // width-=ownerAutoHide.RightAutoHidePanel.Width; + // } + // if(ownerBar.TopDockSite.Parent.Controls.IndexOf(ownerBar.TopDockSite)= 0 && this.Items[this.SelectedDockTab] is DockContainerItem) + index = this.SelectedDockTab; + else if (this.Items.Count > 0 && this.Items[0] is DockContainerItem) + index = 0; + if (index >= 0) + height = Math.Max(((DockContainerItem)this.Items[index]).MinimumSize.Height, ((DockContainerItem)this.Items[index]).Height); + + this.EnableRedraw = false; + try + { + this.Size = new Size(width, height); + this.RecalcSize(); + } + finally + { + this.EnableRedraw = true; + } + height = this.Height; + m_LastDockSiteInfo.DockedHeight = height; + } + + // if(!(ownerBar.TopDockSite.Parent is UserControl)) + // y=ownerAutoHide.TopAutoHidePanel.Bottom; + + break; + } + default: + { + // if(ownerAutoHide.HasLeftAutoHidePanel) + // { + // width-=ownerAutoHide.LeftAutoHidePanel.Width; + // x+=ownerAutoHide.LeftAutoHidePanel.Width; + // } + // if(ownerAutoHide.HasRightAutoHidePanel) + // width-=ownerAutoHide.RightAutoHidePanel.Width; + // if(ownerBar.BottomDockSite.Parent.Controls.IndexOf(ownerBar.BottomDockSite)= 0 && this.Items[this.SelectedDockTab] is DockContainerItem) + index = this.SelectedDockTab; + else if (this.Items.Count > 0 && this.Items[0] is DockContainerItem) + index = 0; + if (index >= 0) + height = Math.Max(((DockContainerItem)this.Items[index]).MinimumSize.Height, ((DockContainerItem)this.Items[index]).Height); + + this.EnableRedraw = false; + try + { + this.Size = new Size(width, height); + this.RecalcSize(); + } + finally + { + this.EnableRedraw = true; + } + height = this.Height; + + m_LastDockSiteInfo.DockedHeight = height; + if (m_TabDockItems != null) m_LastDockSiteInfo.DockedHeight += m_TabDockItems.Height; + } + y -= height; + // if(!(ownerBar.TopDockSite.Parent is UserControl)) + // y=ownerAutoHide.BottomAutoHidePanel.Top-height; + // else if(this.Parent!=null) + // { + // Point p=ownerAutoHide.BottomAutoHidePanel.PointToScreen(Point.Empty); + // p=this.Parent.PointToClient(p); + // y=p.Y-height; + // } + break; + } + } + + Rectangle r = new Rectangle(x, y, width, height); + AutoHideDisplayEventArgs eventArgs = new AutoHideDisplayEventArgs(r); + if (AutoHideDisplay != null) + { + AutoHideDisplay(this, eventArgs); + r = eventArgs.DisplayRectangle; + } + if (ownerBar != null) + { + ownerBar.InvokeAutoHideDisplay(this, eventArgs); + r = eventArgs.DisplayRectangle; + } + this.Bounds = r; + //this.Size=r.Size; //new Size(width,height); + //this.Location=r.Location; //new Point(x,y); + this.RecalcSize(); + + if (m_LastDockSiteInfo.DockSide == DockStyle.Bottom) + { + if (this.Height != height) + this.Top += (height - this.Height); + } + else if (m_LastDockSiteInfo.DockSide == DockStyle.Right) + { + if (this.Width != width) + this.Left += (width - this.Width); + } + + } + + /// + /// Gets or sets how long it takes to play the auto-hide animation, in milliseconds. Maximum value is 2000, 0 disables animation. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(100),Category("Auto-Hide"),Description("Specifies how long it takes to play the auto-hide animation, in milliseconds. Maximum value is 2000, 0 disables animation.")] + public virtual int AutoHideAnimationTime + { + get { return m_AutoHideAnimationTime; } + set + { + if (value < 0) + value = 0; + if (value > 2000) + value = 2000; + m_AutoHideAnimationTime = value; + } + } + + internal bool AnimateShow() + { + if (this.Visible) + return false; + + CancelEventArgs e = new CancelEventArgs(); + OnBeforeAutoHideDisplayed(e); + if (e.Cancel) return false; + + SetAutoHideSize(); + Rectangle rectEnd = new Rectangle(this.Location, this.Size); + Rectangle rectStart = rectEnd; + this.Parent.Controls.SetChildIndex(this, 0); + if (!m_IgnoreAnimation && m_AutoHideAnimationTime > 0 /*&& BarFunctions.SupportsAnimation*/) + { + switch (m_LastDockSiteInfo.DockSide) + { + case DockStyle.Left: + rectStart.Width = 1; + break; + case DockStyle.Right: + rectStart.X = rectStart.Right - 1; + rectStart.Width = 1; + break; + case DockStyle.Top: + rectStart.Height = 1; + break; + default: + rectStart.Y = rectStart.Bottom - 1; + rectStart.Height = 1; + break; + } + } + try + { + m_AnimationInProgress = true; + BarFunctions.AnimateControl(this, true, m_AutoHideAnimationTime, rectStart, rectEnd); + } + finally + { + m_AnimationInProgress = false; + } + + m_IgnoreAnimation = false; + + OnBarStateChanged(new BarStateChangedEventArgs(this, eBarStateChange.AutoHideOpen)); + + return true; + } + internal bool AnimateHide() + { + if (!this.Visible) + return true; + + CancelEventArgs e = new CancelEventArgs(); + OnBeforeAutoHideHidden(e); + if (e.Cancel) return false; + + this.Parent.Controls.SetChildIndex(this, 0); + Rectangle rectStart = new Rectangle(this.Location, this.Size); + Rectangle rectEnd = rectStart; + + if (!m_IgnoreAnimation && m_AutoHideAnimationTime > 0 /*&& BarFunctions.SupportsAnimation*/) + { + switch (m_LastDockSiteInfo.DockSide) + { + case DockStyle.Left: + rectEnd.Width = 1; + break; + case DockStyle.Right: + rectEnd.X = rectEnd.Right - 1; + rectEnd.Width = 1; + break; + case DockStyle.Top: + rectEnd.Height = 1; + break; + default: + rectEnd.Y = rectEnd.Bottom - 1; + rectEnd.Height = 1; + break; + } + + try + { + m_AnimationInProgress = true; + BarFunctions.AnimateControl(this, false, m_AutoHideAnimationTime, rectStart, rectEnd); + } + finally + { + m_AnimationInProgress = false; + } + } + else + this.Visible = false; + + OnBarStateChanged(new BarStateChangedEventArgs(this, eBarStateChange.AutoHideFolded)); + return true; + } + /// + /// Occurs before the bar in auto-hide state is displayed on popup and allows you to cancel display by setting Cancel=true on event arguments. + /// + public event CancelEventHandler BeforeAutoHideDisplayed; + /// + /// Raises BeforeAutoHideDisplayed event. + /// + /// + protected virtual void OnBeforeAutoHideDisplayed(CancelEventArgs e) + { + CancelEventHandler eh = BeforeAutoHideDisplayed; + if (eh != null) + eh(this, e); + } + + /// + /// Occurs before the bar in auto-hide state is hidden and allows you to cancel display by setting Cancel=true on event arguments. + /// + public event CancelEventHandler BeforeAutoHideHidden; + /// + /// Raises BeforeAutoHideHidden event. + /// + /// + protected virtual void OnBeforeAutoHideHidden(CancelEventArgs e) + { + CancelEventHandler eh = BeforeAutoHideHidden; + if (eh != null) + eh(this, e); + } + + private void ResetActiveControl() + { + IOwner owner = m_Owner as IOwner; + // Must reset the ActiveControl to null becouse on MDI Forms if this was not done + // MDI form could not be closed if bar that had ActiveControl is floating. + if (owner.ParentForm != null && owner.ParentForm.ActiveControl == this) + { + owner.ParentForm.ActiveControl = null; + this.Focus(); // Fixes the problem on SDI forms + } + else if (owner.ParentForm != null && IsAnyControl(this, owner.ParentForm.ActiveControl)) + { + owner.ParentForm.ActiveControl = null; + this.Focus(); + } + } + + private bool ShowCustomizeMenuButton + { + get + { + // We Show customize menu button if there is CustomizeItem in container or when + // LayoutType is DockingContainer and grab handle style is caption users have the docking container menu + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && (m_GrabHandleStyle == eGrabHandleStyle.Caption || m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane || m_GrabHandleStyle == eGrabHandleStyle.CaptionDotted) && m_CustomizeMenu != null) + return true; + if (m_ItemContainer.LayoutType != eLayoutType.DockContainer) + { + if (m_ItemContainer.HaveCustomizeItem) + return true; + return (m_CustomizeMenu != null); + } + return false; + } + } + + private void SysButtonMouseOverAutoHide(object sender, EventArgs e) + { + if (!m_SystemButtons.MouseOverAutoHide) + this.HideToolTip(); + else + ResetHover(); + } + private void SysButtonMouseOverCustomize(object sender, EventArgs e) + { + if (!m_SystemButtons.MouseOverCustomize) + this.HideToolTip(); + else + ResetHover(); + } + private void SysButtonMouseOverClose(object sender, EventArgs e) + { + if (!m_SystemButtons.MouseOverClose) + this.HideToolTip(); + else + ResetHover(); + } + private void SysButtonHideTooltip(object sender, EventArgs e) + { + HideToolTip(); + } + + /// + /// Destroys tooltip window. + /// + private void HideToolTip() + { + if (m_ToolTipWnd != null) + { + m_ToolTipWnd.Hide(); + m_ToolTipWnd.Dispose(); + m_ToolTipWnd = null; + ResetHover(); + } + } + + internal void HideAllToolTips() + { + HideToolTip(); + if (m_ItemContainer != null) + { + foreach (BaseItem item in m_ItemContainer.SubItems) + this.HideItemToolTips(item); + } + } + private void HideItemToolTips(BaseItem item) + { + item.HideToolTip(); + foreach (BaseItem i in item.SubItems) + this.HideItemToolTips(i); + } + + + + /// + /// Shows tooltip for this item. + /// + private void ShowToolTip(string tipText) + { + if (this.DesignMode || !m_ShowToolTips || tipText == null || tipText == "") + return; + + if (this.Visible) + { + if (m_ToolTipWnd == null) + m_ToolTipWnd = new ToolTip(); + m_ToolTipWnd.Text = tipText; + IOwnerItemEvents ownerEvents = this.Owner as IOwnerItemEvents; + if (ownerEvents != null) + ownerEvents.InvokeToolTipShowing(m_ToolTipWnd, new EventArgs()); + m_ToolTipWnd.ShowToolTip(); + } + } + + /// + /// Gets whether tooltip is visible or not. + /// + private bool ToolTipVisible + { + get + { + return (m_ToolTipWnd != null); + } + } + + private void UpdateDockTabSettings() + { + if (m_TabDockItems == null || !BarFunctions.IsHandleValid(this)) + return; + + if (m_TabDockItems.CanReorderTabs != m_CanReorderTabs) + m_TabDockItems.CanReorderTabs = m_CanReorderTabs; + if (m_TabDockItems.TabAlignment != m_DockTabAlignment) + m_TabDockItems.TabAlignment = m_DockTabAlignment; + + if (m_TabNavigation) + m_TabDockItems.TabLayoutType = eTabLayoutType.FixedWithNavigationBox; + else + m_TabDockItems.TabLayoutType = eTabLayoutType.FitContainer; + + m_TabDockItems.ShowFocusRectangle = false; + + if (m_TabDockItems._TabSystemBox != null) + m_TabDockItems._TabSystemBox.CloseVisible = this.CanHideResolved; + + if (m_AutoHideState) + m_TabDockItems.Visible = false; + } + + internal void CreateDockTab() + { + if (m_TabDockItems != null || !BarFunctions.IsHandleValid(this)) + return; + m_TabDockItems = new TabStrip(); + UpdateDockTabSettings(); + + this.SuspendLayout(); + this.ResizeDockTab(); + m_TabDockItems.SelectedTabChanging += new TabStrip.SelectedTabChangingEventHandler(this.TabStripTabChanging); + m_TabDockItems.SelectedTabChanged += new TabStrip.SelectedTabChangedEventHandler(TabDockItemsSelectedTabChanged); + m_TabDockItems.BeforeTabDisplay += new EventHandler(this.BeforeTabDisplay); + m_TabDockItems.TabMoved += new TabStrip.TabMovedEventHandler(this.TabStripTabMoved); + m_TabDockItems.TabItemClose += new TabStrip.UserActionEventHandler(TabStripTabItemClose); + m_TabDockItems.CloseButtonOnTabsVisible = m_DockTabCloseButtonVisible; + this.Controls.Add(m_TabDockItems); + + SetDockTabStyle(m_ItemContainer.EffectiveStyle); + + m_TabDockItems.Visible = GetDockTabVisible(); + RefreshDockTabItems(); + this.Invalidate(); + this.ResumeLayout(); + } + + private void TabDockItemsSelectedTabChanged(object sender, TabStripTabChangedEventArgs e) + { + UpdateCloseButtonVisibility(); + OnBarStateChanged(new BarStateChangedEventArgs(this, eBarStateChange.SelectedDockTabChanged, this.SelectedDockContainerItem)); + } + + private void TabStripTabItemClose(object sender, TabStripActionEventArgs e) + { + TabItem ti = sender as TabItem; + if (ti != null) + { + DockContainerItem di = ti.AttachedItem as DockContainerItem; + if (di != null) + CloseDockTab(di, eEventSource.Mouse); + } + } + + internal void SetDockTabStyle(eDotNetBarStyle style) + { + if (m_TabDockItems == null) + return; + if (style == eDotNetBarStyle.StyleManagerControlled) + style = StyleManager.GetEffectiveStyle(); + if(StyleManager.IsMetro(style)) + m_TabDockItems.Style = eTabStripStyle.Metro; + else if (style == eDotNetBarStyle.Office2003) + { + IOwnerBarSupport ob = m_Owner as IOwnerBarSupport; + if (this.DockSide == eDockSide.Document && ob != null && ob.ApplyDocumentBarStyle) + m_TabDockItems.Style = eTabStripStyle.OneNote; + else + m_TabDockItems.Style = eTabStripStyle.Office2003; + } + else if (style == eDotNetBarStyle.VS2005) + { + IOwnerBarSupport ob = m_Owner as IOwnerBarSupport; + if (this.DockSide == eDockSide.Document && ob != null && ob.ApplyDocumentBarStyle) + m_TabDockItems.Style = eTabStripStyle.VS2005Document; + else + m_TabDockItems.Style = eTabStripStyle.VS2005; + } + else if (BarFunctions.IsOffice2007Style(style)) + { + IOwnerBarSupport ob = m_Owner as IOwnerBarSupport; + if (this.DockSide == eDockSide.Document && ob != null && ob.ApplyDocumentBarStyle) + m_TabDockItems.Style = eTabStripStyle.Office2007Document; + else + m_TabDockItems.Style = eTabStripStyle.Office2007Dock; + } + else + m_TabDockItems.Style = eTabStripStyle.Flat; + m_TabDockItems.ColorScheme.TabBorder = Color.Empty; // No border + + if (TabStripStyleChanged != null) + TabStripStyleChanged(this, new EventArgs()); + } + + private void BeforeTabDisplay(object sender, EventArgs e) + { + if (sender is TabItem) + { + InvokeBeforeDockTabDisplayed(((TabItem)sender).AttachedItem); + } + } + + private void DestroyDockTab() + { + if (m_TabDockItems == null) + return; + if (m_TabDockItems.IsDraggingBar) + { + //if(m_TabDockItems.Visible) + m_TabDockItems.Visible = false; + m_TabDockItems.Tabs.Clear(); + return; + } + this.Controls.Remove(m_TabDockItems); + m_TabDockItems.Dispose(); + m_TabDockItems = null; + } + + internal void RefreshTabStrip() + { + if (m_TabDockItems != null) + m_TabDockItems.Refresh(); + } + + internal void RefreshDockTab(bool bFireEvents) + { + if (m_ItemContainer == null || !BarFunctions.IsHandleValid(this)) + return; + + SyncBarCaption(); + + int iVisibleItems = m_ItemContainer.VisibleSubItems; + + if (iVisibleItems > 1 || m_AlwaysDisplayDockTab && m_BarState != eBarState.Floating) + { + if (m_TabDockItems == null) + { + CreateDockTab(); + return; + } + else if (!m_TabDockItems.Visible && m_BarState != eBarState.AutoHide) + m_TabDockItems.Visible = GetDockTabVisible(); + } + else + { + if (iVisibleItems == 1 && m_TabDockItems != null) + { + // Fire last DockTabChange Event + DockContainerItem item = null; + foreach (BaseItem baseItem in m_ItemContainer.SubItems) + { + if (baseItem.Visible && baseItem is DockContainerItem) + { + item = baseItem as DockContainerItem; + break; + } + } + if (item != null) + { + if (bFireEvents) + InvokeDockTabChange(null, item); + } + } + if (this.DesignMode) + { + if (m_TabDockItems != null) + m_TabDockItems.Visible = false; + } + else + DestroyDockTab(); + return; + } + + BaseItem oldItem = null; + if (bFireEvents && m_TabDockItems != null && m_TabDockItems.SelectedTab != null) + oldItem = m_TabDockItems.SelectedTab.AttachedItem; + + RefreshDockTabItems(); + + if (bFireEvents && m_TabDockItems != null && m_TabDockItems.SelectedTab != null && oldItem != m_TabDockItems.SelectedTab.AttachedItem) + InvokeDockTabChange(oldItem, m_TabDockItems.SelectedTab.AttachedItem); + } + + internal void RefreshAutoHidePanel() + { + if (this.AutoHide) + { + AutoHidePanel panel = GetAutoHidePanel(m_LastDockSiteInfo.DockSide); + if (panel != null) + { + panel.RefreshBar(this); + if (panel.SelectedDockContainerItem != null) + { + InvokeDockTabChange(null, panel.SelectedDockContainerItem); + } + } + } + } + + internal void OnDockContainerVisibleChanged(DockContainerItem dockItem) + { + if (!this.AutoHide || dockItem.Visible) + return; + bool bDisplayed = true; + foreach (BaseItem item in this.Items) + { + if (item.Visible && bDisplayed) + { + item.Displayed = true; + bDisplayed = false; + } + else + item.Displayed = false; + } + } + + /// + /// Re-docks the floating bar to its previous docking position. + /// + public void ReDock() + { + + if (m_BarState == eBarState.Floating && (this.CanDockBottom || this.CanDockTop || this.CanDockLeft || this.CanDockRight || this.CanDockDocument)) + { + DockingHandler(m_LastDockSiteInfo, Point.Empty); + } + } + + internal void OnSubItemRemoved(BaseItem objItem) + { + if (objItem is DockContainerItem) + { + if (this.LayoutType == eLayoutType.DockContainer) + { + if (objItem.Displayed) + { + bool bOneDisp = false; + foreach (BaseItem item in this.Items) + { + if (item.Displayed) + bOneDisp = true; + } + if (!bOneDisp && this.Items.Count > 0) + this.Items[0].Displayed = true; + } + this.RefreshDockTab(true); + if (this.AutoHide) + { + AutoHidePanel panel = this.GetAutoHidePanel(); + if (panel != null) + panel.RefreshBar(this); + } + } + } + SyncBarCaption(); + } + + /// + /// Invokes CaptionButtonClick event. + /// + protected void InvokeCaptionButtonClick() + { + if (CaptionButtonClick != null) + CaptionButtonClick(this, new EventArgs()); + } + + /// + /// Displays or hides the automatic caption button popup menu. + /// + private void ToggleCaptionMenu() + { + if (m_CaptionMenu != null) + { + bool bClose = m_CaptionMenu.Expanded; + if (bClose) + m_CaptionMenu.ClosePopup(); + m_CaptionMenu.Dispose(); + m_CaptionMenu = null; + if (bClose) + return; + } + + if (this.Items.Count <= 0) + return; + + m_CaptionMenu = new ButtonItem("sysCaptionButtonMenuParent"); + m_CaptionMenu.Style = this.Style; + m_CaptionMenu.PopupShowing += new EventHandler(this.CaptionMenuShowing); + m_CaptionMenu.PopupFinalized += new EventHandler(this.CaptionMenuClose); + foreach (BaseItem item in this.Items) + { + ButtonItem menuItem = new ButtonItem("sysCaption_" + item.Name); + menuItem.Tag = item; + menuItem.OptionGroup = "sysCaptionMenu"; + menuItem.Text = item.Text; + menuItem.BeginGroup = item.BeginGroup; + if (item is DockContainerItem) + { + DockContainerItem dock = item as DockContainerItem; + menuItem.Checked = item.Displayed; + if (dock.Image != null) + menuItem.Image = dock.Image.Clone() as System.Drawing.Image; + else if (dock.Icon != null) + menuItem.Icon = dock.Icon.Clone() as System.Drawing.Icon; + else if (dock.ImageIndex >= 0 && dock.ImageList != null) + menuItem.Image = dock.ImageList.Images[dock.ImageIndex].Clone() as System.Drawing.Image; + } + else + menuItem.Checked = item.Visible; + menuItem.Click += new EventHandler(this.CaptionMenuItemClick); + m_CaptionMenu.SubItems.Add(menuItem); + } + + if (m_CaptionMenu.GetOwner() == null) + m_CaptionMenu.SetOwner(m_Owner); + System.Drawing.Size size = m_CaptionMenu.PopupSize; + Point popupLocation = new Point(m_SystemButtons.CaptionButtonRect.Right - size.Width, m_SystemButtons.CaptionButtonRect.Bottom); + if (popupLocation.X < 0) + popupLocation.X = 0; + popupLocation = this.PointToScreen(popupLocation); + m_CaptionMenu.Popup(popupLocation); + } + private void CaptionMenuItemClick(object sender, EventArgs e) + { + ButtonItem menuItem = sender as ButtonItem; + if (menuItem == null) + return; + if (this.LayoutType == eLayoutType.DockContainer) + this.SelectedDockTab = this.Items.IndexOf(menuItem.Tag as BaseItem); + else + { + foreach (BaseItem item in this.Items) + { + if (item == menuItem.Tag) + item.Visible = true; + else + item.Visible = false; + } + this.RecalcLayout(); + m_CaptionMenu.Dispose(); + m_CaptionMenu = null; + } + } + private void CaptionMenuShowing(object sender, EventArgs e) + { + if (m_CaptionMenu != null) + ((MenuPanel)m_CaptionMenu.PopupControl).ColorScheme = this.GetColorScheme(); + } + private void CaptionMenuClose(object sender, EventArgs e) + { + PaintCaptionButton(); + } + + internal void RefreshDockContainerItem(DockContainerItem item) + { + if (m_ItemContainer == null || m_TabDockItems == null) + { + SyncBarCaption(); + return; + } + + foreach (TabItem tab in m_TabDockItems.Tabs) + { + if (tab.AttachedItem == item) + { + tab.Text = item.Text; + tab.AttachedItem = item; + tab.Tooltip = item.Tooltip; + tab.Name = item.Name; + if (item.Icon != null) + tab.Icon = item.Icon.Clone() as Icon; + else + { + tab.Image = item.TabImage; + tab.Icon = null; + } + break; + } + } + m_TabDockItems.Refresh(); + if (this.AutoHide) + { + AutoHidePanel panel = GetAutoHidePanel(m_LastDockSiteInfo.DockSide); + if (panel != null) + panel.Refresh(); + } + SyncBarCaption(); + } + + private bool GetDockTabVisible() + { + if (m_GrabHandleStyle == eGrabHandleStyle.CaptionTaskPane && m_AutoCreateCaptionMenu || !_DockTabVisible) + return false; + return true; + } + + private bool _DockTabVisible = true; + /// + /// Indicates whether dock tabs are visible when bar is acting as dock-container and it needs to display tabs to represents multiple DockContainerItem objects hosted by the bar. Default value is true. + /// + [DefaultValue(true), Browsable(false)] + public bool DockTabVisible + { + get { return _DockTabVisible; } + set + { + _DockTabVisible = value; + if (m_TabDockItems != null && !value) + m_TabDockItems.Visible = false; + } + } + + private int _DockTabStripHeight = DOCKTABSTRIP_HEIGHT; + /// + /// Gets or sets height of the docked bar tab strip which displays docked tabs. + /// + [DefaultValue(DOCKTABSTRIP_HEIGHT), Category("Appearance"), Description("Indicates height of the docked bar tab strip which displays docked tabs.")] + public int DockTabStripHeight + { + get { return _DockTabStripHeight; } + set + { + if (value != _DockTabStripHeight) + { + int oldValue = _DockTabStripHeight; + _DockTabStripHeight = value; + OnDockTabStripHeightChanged(oldValue, value); + } + } + } + /// + /// Called when DockTabStripHeight property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDockTabStripHeightChanged(int oldValue, int newValue) + { + if (this.IsHandleCreated) + RecalcLayout(); + //OnPropertyChanged(new PropertyChangedEventArgs("DockTabStripHeight")); + } + + private bool m_RefreshingDockTab = false; // Used to preven re-entrancy + private void RefreshDockTabItems() + { + if (m_RefreshingDockTab) + return; + if (!m_TabDockItems.Visible && m_BarState != eBarState.AutoHide) + { + m_TabDockItems.Visible = GetDockTabVisible(); + int dockTabStripHeight = Dpi.Height(DockTabStripHeight); + if (this.IsThemed && m_BarState == eBarState.Floating) + { + m_TabDockItems.Size = new Size(this.Width - (m_ThemeWindowMargins.Left + m_ThemeWindowMargins.Right), dockTabStripHeight); + m_TabDockItems.Location = new Point(m_ThemeWindowMargins.Left, this.Height - dockTabStripHeight - m_ThemeWindowMargins.Bottom); + } + else + { + m_TabDockItems.Size = new Size(this.Width - Dpi.Width4, dockTabStripHeight); + m_TabDockItems.Location = new Point(Dpi.Width2, this.Height - dockTabStripHeight - Dpi.Height2); + } + } + m_RefreshingDockTab = true; + try + { + m_TabDockItems.Tabs.Clear(); + int iCount = 0; + foreach (BaseItem item in m_ItemContainer.SubItems) + { + if (item.Visible) + { + iCount++; + TabItem tab = new TabItem(); + tab.Text = item.Text; + tab.Tooltip = item.Tooltip; + tab.Name = item.Name; + if (item is DockContainerItem) + { + DockContainerItem di = item as DockContainerItem; + if (di.Icon != null) + tab.Icon = di.Icon.Clone() as Icon; + else + tab.Image = di.TabImage; + tab.PredefinedColor = di.PredefinedTabColor; + } + m_TabDockItems.Tabs.Add(tab); + tab.AttachedItem = item; + if (item.Displayed) + { + m_TabDockItems._IgnoreBeforeTabDisplayEvent = true; + m_TabDockItems.SelectedTab = tab; + m_TabDockItems._IgnoreBeforeTabDisplayEvent = false; + } + } + } + if (iCount > 1 || iCount == 1 && m_AlwaysDisplayDockTab && m_BarState != eBarState.Floating) + { + if (!m_TabDockItems.Visible && m_BarState != eBarState.AutoHide) + m_TabDockItems.Visible = GetDockTabVisible(); + if (m_TabDockItems.SelectedTab == null) + m_TabDockItems.SelectedTab = m_TabDockItems.Tabs[0]; + else if (m_TabDockItems.SelectedTab.AttachedItem != null && !m_TabDockItems.SelectedTab.AttachedItem.Displayed) + m_TabDockItems.SelectedTab.AttachedItem.Displayed = true; + m_TabDockItems.Refresh(); + } + else if (m_TabDockItems.Visible) + m_TabDockItems.Visible = false; + } + finally + { + m_RefreshingDockTab = false; + } + + if (m_BarState == eBarState.AutoHide) + { + AutoHidePanel panel = GetAutoHidePanel(m_LastDockSiteInfo.DockSide); + if (panel != null) + panel.RefreshBar(this); + } + } + + private void ResizeDockTab() + { + if (m_TabDockItems != null && m_TabDockItems.Visible) + { + Point p = Point.Empty; + Size sz = Size.Empty; + + int dockTabStripHeight = Dpi.Height(DockTabStripHeight); + switch (m_DockTabAlignment) + { + case eTabStripAlignment.Top: + { + if (m_GrabHandleStyle != eGrabHandleStyle.None && !m_GrabHandleRect.IsEmpty) + { + p = new Point(m_GrabHandleRect.X, m_GrabHandleRect.Bottom); + sz = new Size(this.Width - m_GrabHandleRect.Left * 2, dockTabStripHeight); + } + else + { + if (m_BarState == eBarState.Docked) + { + p = new Point(Dpi.Width1, Dpi.Width1); + sz = new Size(this.Width - Dpi.Width2, dockTabStripHeight); + } + else if (m_BarState == eBarState.Floating) + { + if (this.IsThemed) + { + p = new Point(m_ThemeWindowMargins.Left, m_ThemeWindowMargins.Top); + sz = new Size(this.Width - (m_ThemeWindowMargins.Left + m_ThemeWindowMargins.Right), dockTabStripHeight); + } + else + { + p = new Point(Dpi.Width3, Dpi.Height3); + sz = new Size(this.Width - Dpi.Width6, dockTabStripHeight); + } + } + else + m_TabDockItems.Visible = false; + } + break; + } + case eTabStripAlignment.Left: + { + if (m_GrabHandleStyle != eGrabHandleStyle.None && !m_GrabHandleRect.IsEmpty) + { + p = new Point(m_GrabHandleRect.X + 1, m_GrabHandleRect.Bottom + Dpi.Height1); + sz = new Size(dockTabStripHeight, m_ItemContainer.HeightInternal - Dpi.Height1); + } + else + { + if (m_BarState == eBarState.Docked) + { + p = new Point(Dpi.Width2, Dpi.Height1); + sz = new Size(dockTabStripHeight, this.Height - Dpi.Height3); + } + else if (m_BarState == eBarState.Floating) + { + if (this.IsThemed) + { + p = new Point(m_ThemeWindowMargins.Left, m_ThemeWindowMargins.Top); + sz = new Size(this.Width - (m_ThemeWindowMargins.Left + m_ThemeWindowMargins.Right), dockTabStripHeight); + } + else + { + p = new Point(Dpi.Width3, Dpi.Height3); + sz = new Size(this.Width - Dpi.Width6, dockTabStripHeight); + } + } + else + m_TabDockItems.Visible = false; + } + break; + } + case eTabStripAlignment.Right: + { + if (m_GrabHandleStyle != eGrabHandleStyle.None && !m_GrabHandleRect.IsEmpty && m_BarState == eBarState.Docked) + { + p = new Point(this.ClientRectangle.Right - dockTabStripHeight, m_GrabHandleRect.Bottom + Dpi.Height1); + sz = new Size(dockTabStripHeight - Dpi.Width2, m_ItemContainer.HeightInternal); + } + else + { + if (m_BarState == eBarState.Docked) + { + p = new Point(this.Width - dockTabStripHeight, Dpi.Height1); + sz = new Size(dockTabStripHeight, this.Height - Dpi.Height2); + } + else if (m_BarState == eBarState.Floating) + { + if (this.IsThemed) + { + p = new Point(this.Width - m_ThemeWindowMargins.Right - dockTabStripHeight, m_ThemeWindowMargins.Top); + sz = new Size(dockTabStripHeight, this.Height - (m_ThemeWindowMargins.Top + m_ThemeWindowMargins.Bottom)); + } + else + { + p = new Point(this.Width - Dpi.Width3 - dockTabStripHeight, m_ItemContainer.TopInternal); + sz = new Size(dockTabStripHeight, m_ItemContainer.HeightInternal); + } + } + else + m_TabDockItems.Visible = false; + } + break; + } + default: + { + p = new Point(0, this.Height - dockTabStripHeight); + sz = new Size(this.Width, dockTabStripHeight); + if (this.DockSide == eDockSide.Top && m_BarState == eBarState.Docked) + { + p = new Point(0, this.Height - dockTabStripHeight - Dpi.Height1); + sz = new Size(this.Width, dockTabStripHeight); + } + if (m_BarState == eBarState.Docked) + { + if (m_DockedBorder != eBorderType.None) + { + p = new Point(Dpi.Width2, this.Height - dockTabStripHeight - Dpi.Height3); + sz = new Size(this.Width - Dpi.Width4, dockTabStripHeight); + } + } + else if (m_BarState == eBarState.Floating) + { + if (this.IsThemed) + { + p = new Point(m_ThemeWindowMargins.Left, this.Height - dockTabStripHeight - m_ThemeWindowMargins.Right); + sz = new Size(this.Width - (m_ThemeWindowMargins.Left + m_ThemeWindowMargins.Right), dockTabStripHeight); + } + else + { + p = new Point(3, this.Height - dockTabStripHeight - Dpi.Height3); + sz = new Size(this.Width - Dpi.Width6, dockTabStripHeight); + } + } + else + m_TabDockItems.Visible = false; + break; + } + } + m_TabDockItems.SetBounds(p.X, p.Y, sz.Width, sz.Height); + } + } + + /// + /// Returns the reference to internal TabStrip control used to display contained DockContainerItems. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false)] + public TabStrip DockTabControl + { + get + { + return m_TabDockItems; + } + } + + private void TabStripTabChanging(object sender, TabStripTabChangingEventArgs e) + { + if (m_RefreshingDockTab) + return; + e.Cancel = InvokeDockTabChange((e.OldTab == null ? null : e.OldTab.AttachedItem), (e.NewTab == null ? null : e.NewTab.AttachedItem)); + } + + private void SyncBarCaption(BaseItem selected) + { + if (m_AutoSyncBarCaption && this.LayoutType == eLayoutType.DockContainer) + { + DockContainerItem sel = this.SelectedDockContainerItem; + if (sel != null && sel.Visible || selected != null) + { + if (selected == null) + selected = sel; // this.Items[this.SelectedDockTab]; + + this.Text = selected.Text; + } + else + { + foreach (BaseItem item in this.Items) + { + if (item.Visible && item.Displayed) + { + this.Text = item.Text; + break; + } + } + } + } + } + internal void SyncBarCaption() + { + SyncBarCaption(null); + } + + private bool InvokeDockTabChange(BaseItem oldItem, BaseItem newItem) + { + DockTabChangeEventArgs dockarg = null; + IOwnerBarSupport ownersupport = m_Owner as IOwnerBarSupport; + bool bCancel = false; + if (DockTabChange != null) + { + dockarg = new DockTabChangeEventArgs(oldItem, newItem); + DockTabChange(this, dockarg); + bCancel = dockarg.Cancel; + if (bCancel) + return bCancel; + } + if (m_Owner != null) + { + if (dockarg == null) + dockarg = new DockTabChangeEventArgs(oldItem, newItem); + if (ownersupport != null) + ownersupport.InvokeDockTabChange(this, dockarg); + bCancel = dockarg.Cancel; + } + if (!bCancel) + { + SyncBarCaption(newItem); + UpdateCloseButtonVisibility(); + } + + if (!bCancel) + OnBarStateChanged(new BarStateChangedEventArgs(this, eBarStateChange.SelectedDockTabChanging, newItem)); + + return bCancel; + } + + internal void InvokeBeforeDockTabDisplayed(BaseItem item) + { + if (BeforeDockTabDisplayed != null) + BeforeDockTabDisplayed(item, new EventArgs()); + + IOwnerBarSupport ownersupport = m_Owner as IOwnerBarSupport; + if (ownersupport != null) + ownersupport.InvokeBeforeDockTabDisplay(item, new EventArgs()); + } + + private void TabStripTabMoved(object sender, TabStripTabMovedEventArgs e) + { + List hiddenList = new List(); + foreach (BaseItem item in m_ItemContainer.SubItems) + { + if (!item.Visible) + hiddenList.Add(item); + } + foreach (BaseItem item in hiddenList) + { + m_ItemContainer.SubItems._Remove(item); + } + m_ItemContainer.SubItems._Remove((DockContainerItem)e.Tab.AttachedItem); + m_ItemContainer.SubItems._Add((DockContainerItem)e.Tab.AttachedItem, e.NewIndex); + foreach (BaseItem item in hiddenList) + { + m_ItemContainer.SubItems._Add(item); + } + m_TabsRearranged = true; + OnBarStateChanged(new BarStateChangedEventArgs(this, eBarStateChange.DockTabMoved, e.Tab.AttachedItem)); + } + + /// + /// Gets or sets the selected DockContainerItem if bar represents dockable window. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DockContainerItem SelectedDockContainerItem + { + get + { + if (m_ItemContainer.LayoutType != eLayoutType.DockContainer) return null; + int si = this.SelectedDockTab; + if (si >= 0) + return this.Items[si] as DockContainerItem; + if (this.VisibleItemCount > 0) + { + foreach (BaseItem item in this.Items) + { + if (item.Visible && item.Displayed) return item as DockContainerItem; + } + } + return null; + } + set + { + if (m_ItemContainer.LayoutType != eLayoutType.DockContainer) + throw new InvalidOperationException("Bar type is not dockable window. LayoutType must be set to eLayoutType.DockContainer"); + if (!this.Items.Contains(value)) + throw new InvalidOperationException("Bar.Items collection does not contain the item"); + this.SelectedDockTab = this.Items.IndexOf(value); + } + } + + /// + /// Gets or sets the tab (DockContainerItem) index for Bars with LayoutType set to eLayoutType.DockContainer. Index corresponds to the index of the DockContainerItem in Bar.Items collection. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Gets or sets the tab (DockContainerItem) index for Bars with LayoutType set to eLayoutType.DockContainer."),DefaultValue(-1)] + public int SelectedDockTab + { + get + { + if (m_ItemContainer.LayoutType != eLayoutType.DockContainer || m_TabDockItems == null) + return -1; + if (m_TabDockItems.SelectedTab != null) + return m_ItemContainer.SubItems.IndexOf(m_TabDockItems.SelectedTab.AttachedItem); + + return -1; + } + set + { + if (m_TabDockItems == null || m_TabDockItems != null && this.AutoHide) + { + if (value < this.Items.Count) + { + for (int i = 0; i < this.Items.Count; i++) + { + if (i == value && this.Items[i].Visible) + this.Items[i].Displayed = true; + else + this.Items[i].Displayed = false; + } + if (m_TabDockItems == null) + { + if (this.Items[value].Displayed) + InvokeDockTabChange(null, this.Items[value]); + RefreshAutoHidePanel(); + } + } + if (m_TabDockItems == null) return; + } + if (m_ItemContainer.LayoutType != eLayoutType.DockContainer) + throw new InvalidOperationException("SelectedDockTab property can be set only for LayoutType=eLayoutType.DockContainer."); + if (value < 0) value = 0; + if (value >= m_ItemContainer.SubItems.Count) + throw new InvalidOperationException("Invalid tab index."); + //if(this.AutoHide) + //{ + // m_LastDockSiteInfo.DockedHeight=0; + // m_LastDockSiteInfo.DockedWidth=0; + //} + BaseItem item = m_ItemContainer.SubItems[value]; + foreach (TabItem tab in m_TabDockItems.Tabs) + { + if (tab.AttachedItem == item) + { + if (m_TabDockItems.SelectedTab == tab && this.AutoHide) + InvokeBeforeDockTabDisplayed(item); + m_TabDockItems.SelectedTab = tab; + if (this.AutoHide) + { + AutoHidePanel panel = GetAutoHidePanel(m_LastDockSiteInfo.DockSide); + panel.SelectedDockContainerItem = item as DockContainerItem; + } + break; + } + } + } + } + + #region Inherited properties hiding + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override Cursor Cursor + { + get + { return base.Cursor; } + set + { base.Cursor = value; } + } + /// + /// Indicates Bar background image. + /// + [Browsable(true), DevCoBrowsable(true),Category("Appearance"),Description("Indicates Bar background image.")] + public override Image BackgroundImage + { + get { return base.BackgroundImage; } + set { base.BackgroundImage = value; } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override Color ForeColor + { + get { return base.ForeColor; } + set { base.ForeColor = value; } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override RightToLeft RightToLeft + { + get { return base.RightToLeft; } + set { base.RightToLeft = value; } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override ContextMenu ContextMenu + { + get { return base.ContextMenu; } + set { base.ContextMenu = value; } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public new ImeMode ImeMode + { + get { return base.ImeMode; } + set { base.ImeMode = value; } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public new int TabIndex + { + get { return base.TabIndex; } + set { base.TabIndex = value; } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public new bool TabStop + { + get { return base.TabStop; } + set { base.TabStop = value; } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public new bool CausesValidation + { + get { return base.CausesValidation; } + set { base.CausesValidation = value; } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override AnchorStyles Anchor + { + get { return base.Anchor; } + set { base.Anchor = value; } + } + [Browsable(true), DevCoBrowsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override DockStyle Dock + { + get { return base.Dock; } + set + { + if (this.DockSide == eDockSide.Document && value != DockStyle.None && this.Parent is DockSite) + return; + base.Dock = value; + } + } + + [Browsable(false)] + public new Point Location + { + get { return base.Location; } + set + { + if (m_BarState == eBarState.Floating) + { + if (m_Float != null) + m_Float.Location = value; + } + else + base.Location = value; + } + } + [Browsable(false)] + public new Size Size + { + get { return base.Size; } + set { base.Size = value; } + } + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override bool AllowDrop + { + get { return base.AllowDrop; } + set { base.AllowDrop = value; } + } +#if FRAMEWORK20 + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public new System.Windows.Forms.Padding Padding + { + get { return base.Padding; } + set { base.Padding = value; } + } +#endif + #endregion + + /// + /// Gets or sets whether caption button menu for bars with grab handle task pane is automatically created. + /// Caption menu when automatically created will display the list of all items from Items collection + /// and it will maintain only one item from the list as visible item. + /// To create custom caption menu that is displayed when user clicks the caption button handle CaptionButtonClick event. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(true),Category("Behavior"),Description("Indicates whether caption button drop-down menu is automatically created")] + public virtual bool AutoCreateCaptionMenu + { + get + { + return m_AutoCreateCaptionMenu; + } + set + { + m_AutoCreateCaptionMenu = value; + if (this.Visible) + this.RecalcLayout(); + } + } + + /// + /// Gets or sets whether caption (text) of the bars with dock container layout is automatically set to the + /// selected dock container item text. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(false),Category("Behavior"),Description("Indicates whether caption is automatically set to the active dock container item text.")] + public virtual bool AutoSyncBarCaption + { + get { return m_AutoSyncBarCaption; } + set + { + m_AutoSyncBarCaption = value; + SyncBarCaption(); + } + } + + // IDockInfo Interface implementation + /// + /// Returns the Minimum Size for specified orientation. + /// + /// Orientation to return minimum size for. + /// + public System.Drawing.Size MinimumDockSize(eOrientation dockOrientation) + { + if (m_ItemContainer == null) return new Size(32, 32); + if (m_ItemContainer.LayoutType == eLayoutType.DockContainer && (m_ItemContainer.Stretch || m_DockStretch)) + { + if (m_ItemContainer.SubItems.Count > 0 && m_ItemContainer.SubItems[0] is DockContainerItem) + return ((DockContainerItem)m_ItemContainer.SubItems[0]).MinimumSize; + return new Size(32, 32); + } + + if (m_ItemContainer.Stretch || m_DockStretch) + return PreferredDockSize(dockOrientation); + + if (m_ItemContainer.SubItems.Count > 0) + { + BaseItem objItem = m_ItemContainer.SubItems[0]; + if (objItem != null) + { + return new Size(objItem.WidthInternal + m_ClientRect.Left * 2, objItem.HeightInternal); + } + } + + return new Size(0, 0); + } + internal Size GetAdjustedFullSize(Size size) + { + const int TOTAL_BORDER_SIZE = 6; + Size newSize = size; + if (m_TabDockItems != null && m_TabDockItems.Visible && (this.DockTabAlignment == eTabStripAlignment.Top || this.DockTabAlignment == eTabStripAlignment.Bottom)) + newSize.Height += (m_TabDockItems.Height); + newSize.Height += (TOTAL_BORDER_SIZE + SystemInformation.ToolWindowCaptionHeight); + newSize.Width += TOTAL_BORDER_SIZE; + return newSize; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public int GetBarDockedSize(eOrientation o) + { + int TOTAL_BORDER_SIZE = Dpi.Width6; + if (m_ItemContainer == null) + return 0; + if (o == eOrientation.Horizontal && m_LastDockSiteInfo.DockedHeight > 0 && (m_LastDockSiteInfo.DockSide == DockStyle.Top || m_LastDockSiteInfo.DockSide == DockStyle.Bottom)) + return m_LastDockSiteInfo.DockedHeight; + else if (o == eOrientation.Vertical && m_LastDockSiteInfo.DockedWidth > 0 && (m_LastDockSiteInfo.DockSide == DockStyle.Left || m_LastDockSiteInfo.DockSide == DockStyle.Right)) + return m_LastDockSiteInfo.DockedWidth; + + if (o == eOrientation.Horizontal && m_ItemContainer.MinHeight > 0 && m_ItemContainer.MinHeight + SystemInformation.ToolWindowCaptionHeight < this.GetFormClientHeight()) + return m_ItemContainer.MinHeight + SystemInformation.ToolWindowCaptionHeight; + else if (o == eOrientation.Vertical && m_ItemContainer.MinWidth > 0 && m_ItemContainer.MinWidth + SystemInformation.ToolWindowCaptionHeight < this.GetFormClientWidth()) + return m_ItemContainer.MinWidth + SystemInformation.ToolWindowCaptionHeight; + + if (this.SelectedDockTab >= 0 || this.VisibleItemCount > 0 && this.LayoutType == eLayoutType.DockContainer) + { + DockContainerItem item = null; + if (this.SelectedDockTab >= 0) + item = this.Items[this.SelectedDockTab] as DockContainerItem; + else + item = GetFirstVisibleItem() as DockContainerItem; + if (item != null) + { + if (o == eOrientation.Horizontal) + { + if (item.MinimumSize.Height > 0) + { + int height = this.Height; + if (this.Parent != null && (this.DockSide == eDockSide.Left || this.DockSide == eDockSide.Right) || + this.Parent == null && (LastDockSide == eDockSide.Left || LastDockSide == eDockSide.Right)) + height = this.Width; + + if (height > item.MinimumSize.Height) + return height; + return item.MinimumSize.Height * 2 + Dpi.Height(DockTabStripHeight) + TOTAL_BORDER_SIZE; + } + } + else + { + if (item.MinimumSize.Width > 0) + { + int width = this.Width; + if (this.Parent != null && (this.DockSide == eDockSide.Top || this.DockSide == eDockSide.Bottom) || + this.Parent == null && (LastDockSide == eDockSide.Top || LastDockSide == eDockSide.Bottom)) + width = this.Height; + if (width > item.MinimumSize.Width) + return width; + return item.MinimumSize.Width * 2 + TOTAL_BORDER_SIZE; + } + } + } + } + + if (o == eOrientation.Horizontal) + return this.Height; + else + return this.Width; + } + + /// + /// Returns the preferred size of the Bar when docked. + /// + /// Orientation to return preferred size for. + /// + public System.Drawing.Size PreferredDockSize(eOrientation dockOrientation) + { + // Return preffered size for this container + IOwner owner = m_Owner as IOwner; + if (dockOrientation == eOrientation.Horizontal) + { + if (m_DockedSizeH.IsEmpty) + { + if (owner != null && owner.ParentForm != null) + m_DockedSizeH = RecalcSizeOnly(owner.ParentForm.Size, eOrientation.Horizontal, eBarState.Docked, m_WrapItemsDock); + else + m_DockedSizeH = RecalcSizeOnly(System.Windows.Forms.Screen.FromControl(this).WorkingArea.Size, eOrientation.Horizontal, eBarState.Docked, m_WrapItemsDock); + } + + return m_DockedSizeH; + } + else + { + // We will need to calculate that size + if (m_DockedSizeV.IsEmpty) + { + Size size = Size.Empty; + if (owner != null && owner.ParentForm != null) + size = RecalcSizeOnly(owner.ParentForm.Size, eOrientation.Horizontal, eBarState.Docked, m_WrapItemsDock); + else + size = RecalcSizeOnly(System.Windows.Forms.Screen.FromControl(this).WorkingArea.Size, eOrientation.Horizontal, eBarState.Docked, m_WrapItemsDock); + m_DockedSizeV = new Size(size.Height, size.Width); + } + + return m_DockedSizeV; + } + } + + /// + /// Specifies whether Bar can be undocked. Does not apply to stand alone bars. + /// + [Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Specifies whether Bar can be undocked."),DefaultValue(true)] + public bool CanUndock + { + get + { + return m_CanUndock; + } + set + { + if (m_CanUndock != value) + m_CanUndock = value; + } + } + + /// + /// Specifes whether end-user can tear-off (deattach) the tabs on dockable window. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Specifes whether end-user can tear-off (deattach) the tabs on dockable window."),DefaultValue(true)] + public bool CanTearOffTabs + { + get + { + return m_CanTearOffTabs; + } + set + { + if (m_CanTearOffTabs != value) + m_CanTearOffTabs = value; + } + } + + /// + /// Specifes whether end-user can reorder the tabs on dockable window. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Specifes whether end-user can reorder the tabs on dockable window."),DefaultValue(true)] + public bool CanReorderTabs + { + get + { + return m_CanReorderTabs; + } + set + { + if (m_CanReorderTabs != value) + { + m_CanReorderTabs = value; + if (m_TabDockItems != null) + m_TabDockItems.CanReorderTabs = value; + } + } + } + + /// + /// Gets or sets whether bar or DockContainerItem that is torn-off this bar can be docked + /// as tab to another bar. Default value is true which indicates that bar can be docked as tab to another bar. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(true),Category("Docking"),Description("Indicates whether bar or DockContainerItem that is torn-off this bar can be docked as tab to another bar.")] + public bool CanDockTab + { + get { return m_CanDockTab; } + set { m_CanDockTab = value; } + } + + private bool _CanMove = true; + /// + /// Gets or sets whether dock bar can be moved by dragging its caption using the mouse. + /// + [DefaultValue(true), Category("Docking"), Description("Indicates whether dock bar can be moved by dragging its caption using the mouse.")] + public bool CanMove + { + get { return _CanMove; } + set + { + _CanMove = value; + } + } + + /// + /// Specifies whether Bar can be docked on Top dock site or not. Does not apply to stand alone bars. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Determines whether bar can be docked to the top edge of container.")] + public bool CanDockTop + { + get + { + return m_CanDockTop; + } + set + { + if (m_CanDockTop != value) + m_CanDockTop = value; + } + } + + /// + /// Specifies whether Bar can be docked on Bottom dock site or not. Does not apply to stand alone bars. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(true),Category("Docking"),Description("Determines whether bar can be docked to the bottom edge of container.")] + public bool CanDockBottom + { + get + { + return m_CanDockBottom; + } + set + { + if (m_CanDockBottom != value) + m_CanDockBottom = value; + } + } + + /// + /// Specifes whether Bar can be docked on Left dock site or not. Does not apply to stand alone bars. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Determines whether bar can be docked to the left edge of container.")] + public bool CanDockLeft + { + get + { + return m_CanDockLeft; + } + set + { + if (m_CanDockLeft != value) + m_CanDockLeft = value; + } + } + + /// + /// Specifes whether Bar can be docked on Right dock site or not. Does not apply to stand alone bars. + /// + [Browsable(true), DevCoBrowsable(true),DefaultValue(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Determines whether bar can be docked to the right edge of container.")] + public bool CanDockRight + { + get + { + return m_CanDockRight; + } + set + { + if (m_CanDockRight != value) + m_CanDockRight = value; + } + } + + /// + /// Specifies whether Bar can be docked as document. Default value is false. See DotNetBarManager.EnableDocumentDocking for more details. + /// + [Browsable(true), DefaultValue(false) , Category("Docking"), Description("Specifies whether Bar can be docked as document.")] + public bool CanDockDocument + { + get { return m_CanDockDocument; } + set { m_CanDockDocument = value; } + } + + /// + /// Specifies whether Bar will stretch to always fill the space in dock site. Applies to the dockable bars only. + /// + [Browsable(false), DefaultValue(false),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Specifies whether Bar will stretch to always fill the space in dock site.")/*,DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)*/] + public bool Stretch + { + get + { + return m_DockStretch; + } + set + { + if (m_DockStretch != value) + { + m_DockStretch = value; + this.RecalcLayout(); + } + } + } + + protected override void OnDockChanged(EventArgs e) + { + base.OnDockChanged(e); + if (this.Dock != DockStyle.None) + m_DockStretch = true; + else + m_DockStretch = false; + this.RecalcLayout(); + } + + private bool m_DisabledImagesGrayScale = true; + /// + /// Gets or sets whether gray-scale algorithm is used to create automatic gray-scale images. Default is true. + /// + [System.ComponentModel.Browsable(true), DefaultValue(true),System.ComponentModel.Category("Appearance"),Description("Gets or sets whether gray-scale algorithm is used to create automatic gray-scale images.")] + public bool DisabledImagesGrayScale + { + get + { + return m_DisabledImagesGrayScale; + } + set + { + m_DisabledImagesGrayScale = value; + } + } + + // TODO: Merge Implementation + // /// + // /// Specifies whether Bar is merged with MDI Parent Bars when on MDI Child form. + // /// + // [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(false),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Specifies whether Bar is merged with MDI Parent Bars when on MDI Child form.")] + // public bool MergeEnabled + // { + // get + // { + // return m_MergeEnabled; + // } + // set + // { + // m_MergeEnabled=value; + // if(!this.DesignMode && this.Visible && IsParentMdiChild) + // { + // this.Visible=false; + // } + // } + // } + + /// + /// Gets/Sets the distance from the far left/top side of the docking site or suggests the order of the docked bar. Upon serialization this property + /// will contain actual left/top position of the bar. You can use it to re-order the bars docked on the same line. Property value is relative to the other + /// bars docked on the same line when it is used to change the order. For example setting DockOffset value to 10 will place the bar just after the last bar on the + /// same line that has DockOffset value less than 10. If there is no bar with DockOffset value less than 10 the bar will be placed in first position. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Indicates the distance from the far left/top side of the docking site.."),DefaultValue(0)] + public int DockOffset + { + get + { + return m_DockOffset; + } + set + { + m_DockOffset = value; + } + } + /// + /// Gets/Sets the dock line. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Indicates the docking line."),DefaultValue(0)] + public int DockLine + { + get + { + return m_DockLine; + } + set + { + m_DockLine = value; + if (m_BarState == eBarState.Docked) + { + if (this.Parent is DockSite && !m_LayoutSuspended) + { + ((DockSite)this.Parent).AdjustBarPosition(this); + } + } + } + } + + /// + /// Sets the dock line but it does not forces the Bar to change position. The position will be changed on next layout request or when dock site needs to recalculate the layout of the bat. Used internally only. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public void SetDockLine(int iLine) + { + m_DockLine = iLine; + } + + /// + /// Gets or sets the dock tab alignment. + /// + [Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Gets or sets the dock tab alignment."),System.ComponentModel.DefaultValue(eTabStripAlignment.Bottom)] + public eTabStripAlignment DockTabAlignment + { + get { return m_DockTabAlignment; } + set + { + m_DockTabAlignment = value; + if (m_TabDockItems != null) + { + m_TabDockItems.TabAlignment = m_DockTabAlignment; + RecalcLayout(); + ResizeDockTab(); + } + } + } + + /// + /// Gets or sets whether selected dock tab is closed when Bar caption close button is pressed. Default value is false which indicates that whole bar will be hidden when bars close button is pressed. + /// + [Browsable(true), DefaultValue(false), Category("Docking"), Description("Indicates whether selected dock tab is closed when Bar caption close button is pressed. Default value is false which indicates that whole bar will be hidden when bars close button is pressed.")] + public bool CloseSingleTab + { + get { return m_CloseSingleTab; } + set { m_CloseSingleTab = value; } + } + + /// + /// Gets or sets whether close button is displayed on each dock tab that allows closing of the tab. Default value is false. + /// + [Browsable(true), DefaultValue(false), Description("Indicates whether close button is displayed on each dock tab that allows closing of the tab."), Category("Docking")] + public bool DockTabCloseButtonVisible + { + get { return m_DockTabCloseButtonVisible; } + set + { + if (m_DockTabCloseButtonVisible != value) + { + m_DockTabCloseButtonVisible = value; + if (m_TabDockItems != null) + { + m_TabDockItems.CloseButtonOnTabsVisible = m_DockTabCloseButtonVisible; + } + } + } + } + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + DotNetBarManager manager = this.Owner as DotNetBarManager; + bool ctrlTabEnabled = false; + if (manager != null) + ctrlTabEnabled = manager.EnableDockCtrlTabKey; + if (ctrlTabEnabled && this.LayoutType == eLayoutType.DockContainer && this.VisibleItemCount > 1) + { + if ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.Tab) == Keys.Tab && WinApi.HIWORD(WinApi.GetKeyState(9)) != 0) + { + + if ((keyData & Keys.Shift) == Keys.Shift) + { + SelectPreviousTab(true); + } + else + { + SelectNextTab(true); + } + return true; + } + } + return base.ProcessCmdKey(ref msg, keyData); + } + + internal bool SelectPreviousTab(bool cycle) + { + int newIndex = -1; + if (this.SelectedDockTab <= 0) + { + if (cycle) + { + newIndex = GetTabIndex(this.Items.Count, -1); + } + else + return false; + } + else + { + newIndex = GetTabIndex(this.SelectedDockTab, -1); + if (newIndex < 0 && cycle) + { + newIndex = GetTabIndex(this.Items.Count, -1); + } + } + if (newIndex < 0) return false; + this.SelectedDockTab = newIndex; + return true; + } + + internal bool SelectNextTab(bool cycle) + { + int newIndex = -1; + if (this.SelectedDockTab >= this.Items.Count - 1) + { + if (cycle) + { + newIndex = GetTabIndex(-1, 1); + } + else + return false; + } + else + { + newIndex = GetTabIndex(this.SelectedDockTab, 1); + if (newIndex < 0 && cycle) + { + newIndex = GetTabIndex(-1, 1); + } + } + if (newIndex < 0) return false; + this.SelectedDockTab = newIndex; + return true; + } + + private int GetTabIndex(int start, int direction) + { + int i = start; + int end = this.Items.Count - 1; + int increment = 1; + + if (direction < 0) + { + end = 0; + increment = -1; + if (start <= 0) return -1; + } + else if (start >= end) return -1; + + while (end != i) + { + i += increment; + DockContainerItem tab = this.Items[i] as DockContainerItem; + if (tab != null && tab.Visible) + return i; + } + + return -1; + } + + /// + /// Gets or sets whether tab that shows all dock containers on the bar is visible all the time. By default + /// tab is hidden when there is only one item displayed. + /// + [Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Indicates whether tab that shows all dock containers on the bar is visible all the time."),System.ComponentModel.DefaultValue(false)] + public virtual bool AlwaysDisplayDockTab + { + get { return m_AlwaysDisplayDockTab; } + set + { + if (m_AlwaysDisplayDockTab != value) + { + m_AlwaysDisplayDockTab = value; + RefreshDockTab(false); + } + } + } + + /// + /// Gets or sets whether bar is locked to prevent docking below it. Applies to undockable bars only. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Indicates whether bar is locked to prevent docking below it. Applies to undockable bars only."),DefaultValue(false)] + public bool LockDockPosition + { + get { return m_LockDockPosition; } + set + { + if (m_LockDockPosition == value) + return; + m_LockDockPosition = value; + } + } + + /// + /// Gets/Sets the orientation of the Bar. + /// + [System.ComponentModel.Browsable(true), DefaultValue(eOrientation.Horizontal),DevCoBrowsable(false)] + public eOrientation DockOrientation + { + get + { + return m_ItemContainer.Orientation; + } + set + { + if (m_ItemContainer.Orientation != value) + { + m_ItemContainer.Orientation = value; + } + if (this.DesignMode && !(this.Parent is DockSite)) + this.RecalcLayout(); + } + } + + /// + /// Returns whether Bar is docked or not. + /// + [System.ComponentModel.Browsable(false)] + public bool Docked + { + get + { + return (m_BarState == eBarState.Docked); + } + } + + /// + /// Returns the Bars dock site. + /// + [System.ComponentModel.Browsable(false)] + public System.Windows.Forms.Control DockedSite + { + get + { + return this.Parent; + } + } + + public bool ShouldSerializeDockSide() + { + if (this.Parent is DockSite && ((DockSite)this.Parent).DocumentDockContainer != null) + return false; + return DockSide != eDockSide.None; + } + + private eDockSide _LastDockSidePrivate = eDockSide.None; + internal eDockSide LastDockSide + { + get + { + return _LastDockSidePrivate; + } + set + { + _LastDockSidePrivate = value; + } + } + + /// + /// Gets/Sets the dock side for the Bar. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(true),System.ComponentModel.Category("Docking"),System.ComponentModel.Description("Indicates the dock side for the Bar.")] + public eDockSide DockSide + { + get + { + if (m_BarState != eBarState.Docked) + return eDockSide.None; + if (this.Parent == null) + return eDockSide.Top; + else if (this.Parent.Dock == DockStyle.Left) + return eDockSide.Left; + else if (this.Parent.Dock == DockStyle.Right) + return eDockSide.Right; + else if (this.Parent.Dock == DockStyle.Top) + return eDockSide.Top; + else if (this.Parent.Dock == DockStyle.Bottom) + return eDockSide.Bottom; + else if (this.Parent.Dock == DockStyle.Fill) + return eDockSide.Document; + return eDockSide.None; + } + set + { + if (this.Owner == null || m_LayoutSuspended) + { + m_DockSideDelayed = (int)value; + return; + } + + if (this.AutoHide) + { + ChangeAutoHidePanel(value); + return; + } + + DockSiteInfo pDockInfo = new DockSiteInfo(); + IOwnerBarSupport ownersupport = m_Owner as IOwnerBarSupport; + if (ownersupport == null) + { + m_DockSideDelayed = (int)value; + return; + //throw(new System.InvalidOperationException("Could not find owner of the Bar or owner does not implement IOwnerBarSupport.")); + } + + // Use Dock Line and Dock Offset to determine bar insert position + pDockInfo.InsertPosition = -10; + pDockInfo.DockLine = m_DockLine; + pDockInfo.DockOffset = m_DockOffset; + + // Reset the split width and height + if (!m_BarDefinitionLoading) + { + this.SplitDockHeight = 0; + this.SplitDockWidth = 0; + } + + if (value == eDockSide.Left) + { + DockSite ds = null; + if (this.LayoutType == eLayoutType.Toolbar) + { + ds = ownersupport.ToolbarLeftDockSite; + if (ds == null) + throw (new System.InvalidOperationException("DotNetBarManager.ToolbarLeftDockSite dock-site is not set.")); + } + else + { + ds = ownersupport.LeftDockSite; + if (ds == null) + throw (new System.InvalidOperationException("DotNetBarManager.LeftDockSite dock-site is not set.")); + } + + pDockInfo.objDockSite = ds; + } + else if (value == eDockSide.Right) + { + DockSite ds = null; + if (this.LayoutType == eLayoutType.Toolbar) + { + ds = ownersupport.ToolbarRightDockSite; + if (ds == null) + throw (new System.InvalidOperationException("DotNetBarManager.ToolbarRightDockSite dock-site is not set.")); + } + else + { + ds = ownersupport.RightDockSite; + if (ds == null) + throw (new System.InvalidOperationException("DotNetBarManager.RightDockSite dock-site is not set.")); + } + + pDockInfo.objDockSite = ds; + } + else if (value == eDockSide.Top) + { + DockSite ds = null; + if (this.LayoutType == eLayoutType.Toolbar) + { + ds = ownersupport.ToolbarTopDockSite; + if (ds == null) + throw (new System.InvalidOperationException("DotNetBarManager.ToolbarTopDockSite dock-site is not set.")); + } + else + { + ds = ownersupport.TopDockSite; + if (ds == null) + throw (new System.InvalidOperationException("DotNetBarManager.TopDockSite dock-site is not set.")); + } + + pDockInfo.objDockSite = ds; + } + else if (value == eDockSide.Bottom) + { + DockSite ds = null; + if (this.LayoutType == eLayoutType.Toolbar) + { + ds = ownersupport.ToolbarBottomDockSite; + if (ds == null) + throw (new System.InvalidOperationException("DotNetBarManager.ToolbarBottomDockSite dock-site is not set.")); + } + else + { + ds = ownersupport.BottomDockSite; + if (ds == null) + throw (new System.InvalidOperationException("DotNetBarManager.BottomDockSite dock-site is not set.")); + } + + if (ds == null) + throw (new System.InvalidOperationException("Bottom dock-site is not set.")); + pDockInfo.objDockSite = ds; + } + else if (value == eDockSide.Document) + { + pDockInfo.objDockSite = ownersupport.FillDockSite; + } + else + pDockInfo.objDockSite = null; + + this.DockingHandler(pDockInfo, m_FloatingRect.Location); + } + } + + private void ChangeAutoHidePanel(eDockSide side) + { + if (!this.AutoHide) + return; + DockStyle dockStyle = DockStyle.Left; + if (side == eDockSide.Bottom) + dockStyle = DockStyle.Bottom; + else if (side == eDockSide.Right) + dockStyle = DockStyle.Right; + else if (side == eDockSide.Top) + dockStyle = DockStyle.Top; + + if (m_LastDockSiteInfo.DockSide == dockStyle || side == eDockSide.None) + return; + + AutoHidePanel panel = GetAutoHidePanel(m_LastDockSiteInfo.DockSide); + if (panel == null) + return; + + IOwnerBarSupport barSupp = m_Owner as IOwnerBarSupport; + if (barSupp == null) + return; + + AnimateHide(); + + panel.RemoveBar(this); + m_LastDockSiteInfo.DockSide = dockStyle; + switch (dockStyle) + { + case DockStyle.Left: + m_LastDockSiteInfo.objDockSite = barSupp.LeftDockSite; + break; + case DockStyle.Right: + m_LastDockSiteInfo.objDockSite = barSupp.RightDockSite; + break; + case DockStyle.Top: + m_LastDockSiteInfo.objDockSite = barSupp.TopDockSite; + break; + case DockStyle.Bottom: + m_LastDockSiteInfo.objDockSite = barSupp.BottomDockSite; + break; + } + + panel = GetAutoHidePanel(dockStyle); + panel.AddBar(this); + } + + /// + /// Gets or sets the inital floating location. This location will be used when DockSide is set to None. + /// + [Browsable(false), DevCoBrowsable(false),Description("Indicates the inital floating location."),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Point InitalFloatLocation + { + get { return m_FloatingRect.Location; } + set { m_FloatingRect.Location = value; } + } + + /// + /// Indicates whether Tooltips are shown on Bars and menus. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),DefaultValue(true),System.ComponentModel.Category("Run-time Behavior"),System.ComponentModel.Description("Indicates whether Tooltips are shown on Bar and it's sub-items.")] + public bool ShowToolTips + { + get + { + return m_ShowToolTips; + } + set + { + m_ShowToolTips = value; + } + } + + /// + /// Gets or sets whether control is selected in designer. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool DesignerSelection + { + get { return m_DesignerSelection; } + set + { + if (m_DesignerSelection != value) + { + m_DesignerSelection = value; + this.Refresh(); + } + } + } + + #region IOwner + // IOwner Implementation + BaseItem m_ExpandedItem = null; + BaseItem m_FocusItem = null; + private Hashtable m_ShortcutTable = new Hashtable(); + // Only one Popup Item can be expanded at a time. This is used + // to track the currently expanded popup item and to close the popup item + // if another item is expanding. + void IOwner.SetExpandedItem(BaseItem objItem) + { + if (objItem != null && objItem.Parent is PopupItem) + return; + if (m_ExpandedItem != null) + { + if (m_ExpandedItem.Expanded) + m_ExpandedItem.Expanded = false; + m_ExpandedItem = null; + } + m_ExpandedItem = objItem; + } + + BaseItem IOwner.GetExpandedItem() + { + return m_ExpandedItem; + } + + // Currently we are using this to communicate "focus" when control is in + // design mode. This can be used later if we decide to add focus + // handling to our BaseItem class. + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public event EventHandler FocusItemChange; + void IOwner.SetFocusItem(BaseItem objFocusItem) + { + if (DockSide == eDockSide.Document && m_Owner != null) + { + ((IOwner)m_Owner).SetFocusItem(objFocusItem); + return; + } + + if (m_FocusItem != null && m_FocusItem != objFocusItem) + { + m_FocusItem.OnLostFocus(); + } + m_FocusItem = objFocusItem; + if (m_FocusItem != null) + m_FocusItem.OnGotFocus(); + + if (FocusItemChange != null) + FocusItemChange(this, new EventArgs()); + } + + BaseItem IOwner.GetFocusItem() + { + if (DockSide == eDockSide.Document && m_Owner != null && m_Owner is IOwner) + { + return ((IOwner)m_Owner).GetFocusItem(); + } + return m_FocusItem; + } + bool IOwner.DesignMode + { + get { return this.DesignMode; } + } + void IOwner.DesignTimeContextMenu(BaseItem objItem) + { + } + + void IOwner.RemoveShortcutsFromItem(BaseItem objItem) + { + ShortcutTableEntry objEntry = null; + if (objItem.ShortcutString != "") + { + foreach (eShortcut key in objItem.Shortcuts) + { + if (m_ShortcutTable.ContainsKey(key)) + { + objEntry = (ShortcutTableEntry)m_ShortcutTable[key]; + try + { + objEntry.Items.Remove(objItem.Id); + if (objEntry.Items.Count == 0) + m_ShortcutTable.Remove(objEntry.Shortcut); + } + catch (System.ArgumentException) { } + } + } + } + IOwner owner = this as IOwner; + foreach (BaseItem objTmp in objItem.SubItems) + owner.RemoveShortcutsFromItem(objTmp); + } + + void IOwner.AddShortcutsFromItem(BaseItem objItem) + { + ShortcutTableEntry objEntry = null; + if (objItem.ShortcutString != "") + { + foreach (eShortcut key in objItem.Shortcuts) + { + if (m_ShortcutTable.ContainsKey(key)) + objEntry = (ShortcutTableEntry)m_ShortcutTable[objItem.Shortcuts[0]]; + else + { + objEntry = new ShortcutTableEntry(key); + m_ShortcutTable.Add(objEntry.Shortcut, objEntry); + } + try + { + objEntry.Items.Add(objItem.Id, objItem); + } + catch (System.ArgumentException) { } + } + } + IOwner owner = this as IOwner; + foreach (BaseItem objTmp in objItem.SubItems) + owner.AddShortcutsFromItem(objTmp); + } + + /// + /// Gets or sets whether accelerator letters for menu or toolbar commands are underlined regardless of + /// current Windows settings. Accelerator keys allow easy access to menu commands by using + /// Alt + choosen key (letter). Default value is false which indicates that system setting is used + /// to determine whether accelerator letters are underlined. Setting this property to true + /// will always display accelerator letter underlined. + /// + [Browsable(true), DevCoBrowsable(false),DefaultValue(false),Category("Run-time Behavior"),Description("Indicates whether accelerator letters for menu or toolbar commands are underlined regardless of current Windows settings.")] + public bool AlwaysDisplayKeyAccelerators + { + get { return m_AlwaysDisplayKeyAccelerators; } + set + { + if (m_AlwaysDisplayKeyAccelerators != value) + { + m_AlwaysDisplayKeyAccelerators = value; + this.Refresh(); + } + } + } + + Form IOwner.ParentForm + { + get { return this.FindForm(); } + set { } + } + + Form IOwner.ActiveMdiChild + { + get + { + Form form = this.FindForm(); + if (form == null) + return null; + if (form.IsMdiContainer) + return form.ActiveMdiChild; + return null; + } + } + System.Windows.Forms.MdiClient IOwner.GetMdiClient(System.Windows.Forms.Form MdiForm) + { + return BarFunctions.GetMdiClient(MdiForm); + } + + void IOwner.Customize() { } + + private System.Windows.Forms.ImageList m_ImageList; + private System.Windows.Forms.ImageList m_ImageListMedium = null; + private System.Windows.Forms.ImageList m_ImageListLarge = null; + /// + /// ImageList for images used on Items. Images specified here will always be used on menu-items and are by default used on all Bars. + /// + [Browsable(true), DevCoBrowsable(false),DefaultValue(null),Category("Data"),Description("ImageList for images used on Items. Images specified here will always be used on menu-items and are by default used on all Bars.")] + public System.Windows.Forms.ImageList Images + { + get + { + return m_ImageList; + } + set + { + if (m_ImageList != null) + m_ImageList.Disposed -= new EventHandler(this.ImageListDisposed); + m_ImageList = value; + if (m_ImageList != null) + m_ImageList.Disposed += new EventHandler(this.ImageListDisposed); + } + } + /// + /// ImageList for medium-sized images used on Items. + /// + [Browsable(true), DefaultValue(null),Category("Data"),Description("ImageList for medium-sized images used on Items.")] + public System.Windows.Forms.ImageList ImagesMedium + { + get + { + return m_ImageListMedium; + } + set + { + if (m_ImageListMedium != null) + m_ImageListMedium.Disposed -= new EventHandler(this.ImageListDisposed); + m_ImageListMedium = value; + if (m_ImageListMedium != null) + m_ImageListMedium.Disposed += new EventHandler(this.ImageListDisposed); + } + } + + /// + /// ImageList for large-sized images used on Items. + /// + [Browsable(true), DefaultValue(null),Category("Data"),Description("ImageList for large-sized images used on Items.")] + public System.Windows.Forms.ImageList ImagesLarge + { + get + { + return m_ImageListLarge; + } + set + { + if (m_ImageListLarge != null) + m_ImageListLarge.Disposed -= new EventHandler(this.ImageListDisposed); + m_ImageListLarge = value; + if (m_ImageListLarge != null) + m_ImageListLarge.Disposed += new EventHandler(this.ImageListDisposed); + } + } + private void ImageListDisposed(object sender, EventArgs e) + { + if (sender == m_ImageList) + { + this.Images = null; + } + else if (sender == m_ImageListLarge) + { + this.ImagesLarge = null; + } + else if (sender == m_ImageListMedium) + { + this.ImagesMedium = null; + } + } + #endregion + + #region ISupportInitialize + /// + /// ISupportInitialize.BeginInit implementation. + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + public void BeginInit() + { + m_LayoutSuspended = true; + } + + /// + /// ISupportInitialize.EndInit implementation. + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + public void EndInit() + { + m_LayoutSuspended = false; + if (this.DockSide == eDockSide.Document && this.Parent is DockSite) + { + ((DockSite)this.Parent).RecalcLayout(); + } + else + this.RecalcSize(); + if (this.AutoHide != m_AutoHideStateDelayed) + this.AutoHide = m_AutoHideStateDelayed; + } + #endregion + + #region IBarDesignerServices + IBarItemDesigner IBarDesignerServices.Designer + { + get { return m_BarDesigner; } + set { m_BarDesigner = value; } + } + #endregion + + #region IOwner + void IOwner.InvokeResetDefinition(BaseItem item, EventArgs e) { } + bool IOwner.ShowResetButton { get { return false; } set { } } + void IOwner.InvokeUserCustomize(object sender, EventArgs e) { } + void IOwner.InvokeEndUserCustomize(object sender, EndUserCustomizeEventArgs e) { } + bool IOwner.ShowShortcutKeysInToolTips { get { return true; } set { } } + void IOwner.StartItemDrag(BaseItem item) + { + if (this.DesignMode && m_BarDesigner != null) + m_BarDesigner.StartExternalDrag(item); + } + BaseItem IOwner.DragItem { get { return null; } } + bool IOwner.DragInProgress { get { return false; } } + void IOwner.OnApplicationActivate() { } + void IOwner.OnApplicationDeactivate() + { + ClosePopups(); + } + void IOwner.OnParentPositionChanging() { } + + + private void MenuEventSupportHook() + { + if (m_MenuEventSupport) + return; + m_MenuEventSupport = true; + + Form parentForm = this.FindForm(); + if (parentForm == null) + { + m_MenuEventSupport = false; + return; + } + if (parentForm.IsMdiChild && parentForm.MdiParent != null) + parentForm = parentForm.MdiParent; + + parentForm.Resize += new System.EventHandler(this.ParentResize); + parentForm.Deactivate += new System.EventHandler(this.ParentDeactivate); + + DotNetBarManager.RegisterParentMsgHandler(this, parentForm); + } + private void MenuEventSupportUnhook() + { + if (!m_MenuEventSupport) + return; + m_MenuEventSupport = false; + + Form parentForm = this.FindForm(); + if (parentForm == null) + return; + if (parentForm.IsMdiChild && parentForm.MdiParent != null) + parentForm = parentForm.MdiParent; + DotNetBarManager.UnRegisterParentMsgHandler(this, parentForm); + parentForm.Resize -= new System.EventHandler(this.ParentResize); + parentForm.Deactivate -= new System.EventHandler(this.ParentDeactivate); + } + private void ParentResize(object sender, System.EventArgs e) + { + Form parentForm = this.FindForm(); + if (parentForm.IsMdiChild && parentForm.MdiParent != null) + parentForm = parentForm.MdiParent; + + if (parentForm != null && parentForm.WindowState == FormWindowState.Minimized) + ((IOwner)this).OnApplicationDeactivate(); + } + private void ParentDeactivate(object sender, System.EventArgs e) + { + Form parentForm = this.FindForm(); + if (parentForm != null && parentForm.IsMdiChild && parentForm.MdiParent != null) + parentForm = parentForm.MdiParent; + + if (parentForm != null && parentForm.WindowState == FormWindowState.Minimized) + ((IOwner)this).OnApplicationDeactivate(); + } + #endregion + + #region IOwnerMenuSupport + private bool _UseHook = false; + /// + /// Gets or sets whether hooks are used for internal DotNetBar system functionality. Using hooks is recommended only if DotNetBar is used in hybrid environments like Visual Studio designers or IE. + /// + [System.ComponentModel.Browsable(false), DefaultValue(false), System.ComponentModel.Category("Behavior"), System.ComponentModel.Description("Gets or sets whether hooks are used for internal DotNetBar system functionality. Using hooks is recommended only if DotNetBar is used in hybrid environments like Visual Studio designers or IE.")] + public bool UseHook + { + get + { + return _UseHook; + } + set + { + if (_UseHook == value) + return; + _UseHook = value; + } + } + + // IOwnerMenuSupport + private ArrayList m_RegisteredPopups = new ArrayList(); + private bool m_FilterInstalled = false; + private Hook m_Hook = null; + bool IOwnerMenuSupport.PersonalizedAllVisible { get { return false; } set { } } + bool IOwnerMenuSupport.ShowFullMenusOnHover { get { return true; } set { } } + bool IOwnerMenuSupport.AlwaysShowFullMenus { get { return false; } set { } } + + void IOwnerMenuSupport.RegisterPopup(PopupItem objPopup) + { + if (m_RegisteredPopups.Contains(objPopup)) + return; + + if (!this.DesignMode && !_UseHook) + { + if (!m_FilterInstalled) + { + //System.Windows.Forms.Application.AddMessageFilter(this); + MessageHandler.RegisterMessageClient(this); + m_FilterInstalled = true; + } + if (!m_MenuEventSupport) + MenuEventSupportHook(); + } + else + { + if (m_Hook == null) + { + m_Hook = new Hook(this); + } + } + if (m_RegisteredPopups.Count == 0) + PopupManager.RegisterPopup((IOwnerMenuSupport)this); + m_RegisteredPopups.Add(objPopup); + if (objPopup.GetOwner() != this) + objPopup.SetOwner(this); + } + void IOwnerMenuSupport.UnregisterPopup(PopupItem objPopup) + { + if (m_RegisteredPopups.Contains(objPopup)) + m_RegisteredPopups.Remove(objPopup); + if (m_RegisteredPopups.Count == 0) + { + MenuEventSupportUnhook(); + if (m_Hook != null) + { + m_Hook.Dispose(); + m_Hook = null; + } + PopupManager.UnregisterPopup((IOwnerMenuSupport)this); + } + } + bool IOwnerMenuSupport.RelayMouseHover() + { + foreach (PopupItem popup in m_RegisteredPopups) + { + Control ctrl = popup.PopupControl; + if (ctrl != null && ctrl.DisplayRectangle.Contains(Control.MousePosition)) + { + if (ctrl is MenuPanel) + ((MenuPanel)ctrl).InternalMouseHover(); + else if (ctrl is Bar) + ((Bar)ctrl).InternalMouseHover(); + return true; + } + } + return false; + } + + void IOwnerMenuSupport.ClosePopups() + { + ClosePopups(); + } + + internal void ClosePopups() + { + ArrayList popupList = new ArrayList(m_RegisteredPopups); + foreach (PopupItem objPopup in popupList) + { + if (objPopup.QueryPopupClosing(eEventSource.Mouse)) + objPopup.ClosePopup(); + } + } + + // Events + void IOwnerMenuSupport.InvokePopupClose(PopupItem item, EventArgs e) + { + if (PopupClose != null) + PopupClose(item, e); + } + void IOwnerMenuSupport.InvokePopupContainerLoad(PopupItem item, EventArgs e) + { + if (PopupContainerLoad != null) + PopupContainerLoad(item, e); + } + void IOwnerMenuSupport.InvokePopupContainerUnload(PopupItem item, EventArgs e) + { + if (PopupContainerUnload != null) + PopupContainerUnload(item, e); + } + void IOwnerMenuSupport.InvokePopupOpen(PopupItem item, PopupOpenEventArgs e) + { + if (PopupOpen != null) + PopupOpen(item, e); + } + void IOwnerMenuSupport.InvokePopupShowing(PopupItem item, EventArgs e) + { + if (PopupShowing != null) + PopupShowing(item, e); + } + bool IOwnerMenuSupport.ShowPopupShadow { get { return true; } } + eMenuDropShadow IOwnerMenuSupport.MenuDropShadow { get { return eMenuDropShadow.SystemDefault; } set { } } + ePopupAnimation IOwnerMenuSupport.PopupAnimation { get { return ePopupAnimation.SystemDefault; } set { } } + bool IOwnerMenuSupport.AlphaBlendShadow { get { return true; } set { } } + #endregion + + #region IMessageHandlerClient + internal bool IgnoreSysKeyUp + { + get { return m_IgnoreSysKeyUp; } + set { m_IgnoreSysKeyUp = value; } + } + internal bool EatSysKeyUp + { + get { return m_EatSysKeyUp; } + set { m_EatSysKeyUp = value; } + } + // IMessageHandlerClient Implementation + private bool m_DispatchShortcuts = false; + private bool m_IgnoreSysKeyUp = false, m_EatSysKeyUp = false, m_IgnoreF10Key = false; + bool IMessageHandlerClient.IsModal + { + get + { + Form form = this.FindForm(); + if (form != null) + return form.Modal; + return false; + } + } + + bool IMessageHandlerClient.OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + bool designMode = this.DesignMode; + + int wParamInt = WinApi.ToInt(wParam); + + if (m_RegisteredPopups.Count > 0) + { + BaseItem popup = ((BaseItem)m_RegisteredPopups[m_RegisteredPopups.Count - 1]); + Keys key = (Keys)NativeFunctions.MapVirtualKey((uint)wParam, 2); + if (key == Keys.None) + key = (Keys)wParamInt; + if (popup.Parent == null || IsContextPopup(popup) || (key == Keys.Escape || key == Keys.Enter || key == Keys.Left || key == Keys.Right || key == Keys.Down || key == Keys.Up)) + { + PopupItem objItem = (PopupItem)m_RegisteredPopups[m_RegisteredPopups.Count - 1]; + + Control ctrl = objItem.PopupControl as Control; + Control ctrl2 = Control.FromChildHandle(hWnd); + + if (ctrl2 != null) + { + while (ctrl2.Parent != null) + ctrl2 = ctrl2.Parent; + } + + bool bIsOnHandle = false; + if (ctrl2 != null && objItem != null) + bIsOnHandle = objItem.IsAnyOnHandle(ctrl2.Handle); + + bool bNoEat = ctrl != null && ctrl2 != null && ctrl.Handle == ctrl2.Handle || bIsOnHandle; + + if (!bIsOnHandle) + { + objItem.InternalKeyDown(new KeyEventArgsEx(key, WinApi.ToAscii((uint)wParam))); + } + + // Don't eat the message if the pop-up window has focus + if (bNoEat) + return false; + return true && !designMode; + } + } + + Form form = this.FindForm(); + if (form == null || form != Form.ActiveForm && form.MdiParent == null || + form.MdiParent != null && form.MdiParent.ActiveMdiChild != form) + return false; + + if (wParamInt >= 0x70 || System.Windows.Forms.Control.ModifierKeys != Keys.None || (WinApi.ToInt(lParam) & 0x1000000000) != 0 || wParamInt == 0x2E || wParamInt == 0x2D) // 2E=VK_DELETE, 2D=VK_INSERT + { + int i = (int)System.Windows.Forms.Control.ModifierKeys | wParamInt; + return ProcessShortcut((eShortcut)i) && !designMode; + } + return false; + } + + protected virtual bool IsContextPopup(BaseItem popup) + { + return false; + } + private bool ProcessShortcut(eShortcut key) + { + if (!IsHandlingShortcuts) + return false; + bool eat = BarFunctions.ProcessItemsShortcuts(key, m_ShortcutTable); + return !m_DispatchShortcuts && eat; + // if(m_ShortcutTable.Contains(key)) + // { + // ShortcutTableEntry objEntry=(ShortcutTableEntry)m_ShortcutTable[key]; + // // Must convert to independable array, since if this is for example + // // close command first Click will destroy the collection we are + // // iterating through and exception will be raised. + // BaseItem[] arr=new BaseItem[objEntry.Items.Values.Count]; + // objEntry.Items.Values.CopyTo(arr,0); + // Hashtable hnames=new Hashtable(arr.Length); + // + // bool eat=false; + // + // foreach(BaseItem objItem in arr) + // { + // if(objItem.CanRaiseClick && (objItem.Name=="" || !hnames.Contains(objItem.Name))) + // { + // eat=true; + // objItem.RaiseClick(); + // if(objItem.Name!="") + // hnames.Add(objItem.Name,""); + // } + // } + // return !m_DispatchShortcuts && eat; // True will eat the key, false will pass it through + // } + // return false; + } + private bool IsHandlingShortcuts + { + get + { + Form form = this.FindForm(); + Form activeForm = Form.ActiveForm; + if (form == null) + return false; + + if (form.IsMdiChild) + { + if (form.MdiParent != null) + { + if (form.MdiParent.ActiveMdiChild == form && (form == activeForm || form.MdiParent == activeForm)) + return true; + return false; + } + } + + return (form == Form.ActiveForm); + } + } + bool IMessageHandlerClient.OnMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + if (m_RegisteredPopups.Count == 0 || this.DesignMode) + return false; + + //foreach(PopupItem objPopup in m_RegisteredPopups) + for (int i = m_RegisteredPopups.Count - 1; i >= 0; i--) + { + PopupItem objPopup = m_RegisteredPopups[i] as PopupItem; + System.Windows.Forms.Control objCtrl = objPopup.ContainerControl as System.Windows.Forms.Control; + bool bChildHandle = objPopup.IsAnyOnHandle(hWnd); + + if (!bChildHandle) + { + System.Windows.Forms.Control cTmp = System.Windows.Forms.Control.FromChildHandle(hWnd); + if (cTmp != null) + { + if (cTmp is MenuPanel) + { + bChildHandle = true; + } + else + { + while (cTmp.Parent != null) + { + cTmp = cTmp.Parent; + if (cTmp.GetType().FullName.IndexOf("DropDownHolder") >= 0 || cTmp is MenuPanel || cTmp is PopupContainerControl) + { + bChildHandle = true; + break; + } + } + } + if (!bChildHandle) + bChildHandle = objPopup.IsAnyOnHandle(cTmp.Handle); + } + else + { + string s = NativeFunctions.GetClassName(hWnd); + s = s.ToLower(); + if (s.IndexOf("combolbox") >= 0) + bChildHandle = true; + } + } + + if (!bChildHandle) + { + Control popupContainer = objPopup.PopupControl; + if (popupContainer != null) + while (popupContainer.Parent != null) popupContainer = popupContainer.Parent; + if (popupContainer != null && popupContainer.Bounds.Contains(Control.MousePosition)) + bChildHandle = true; + } + + if (bChildHandle) + break; + + if (objCtrl != null && hWnd != objCtrl.Handle && !bChildHandle) + { + if (objPopup.Expanded && objPopup.QueryPopupClosing(eEventSource.Mouse)) + { + objPopup.Expanded = !objPopup.Expanded; + if (!objPopup.Expanded && objPopup.Parent != null) + { + objPopup.Parent.AutoExpand = false; + } + } + } + else if (objCtrl == null && !bChildHandle) + { + if (objPopup.QueryPopupClosing(eEventSource.Mouse)) + objPopup.ClosePopup(); + } + + if (m_RegisteredPopups.Count == 0) + break; + } + return false; + } + + bool IMessageHandlerClient.OnMouseMove(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + if (m_RegisteredPopups.Count > 0) + { + foreach (BaseItem item in m_RegisteredPopups) + { + if (item.Parent == null) + { + Control ctrl = ((PopupItem)item).PopupControl; + if (ctrl != null && ctrl.Handle != hWnd && !item.IsAnyOnHandle(hWnd) && !(ctrl.Parent != null && ctrl.Parent.Handle != hWnd)) + return true; + } + } + } + return false; + } + + private bool _ProcessMnemonics = true; + /// + /// Indicates whether mnemonic keys, accelerator keys, which are set through item Text property used ampersand character are processed by control. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether mnemonic keys, accelerator keys, which are set through item Text property used ampersand character are processed by control.")] + public bool ProcessMnemonics + { + get { return _ProcessMnemonics; } + set + { + _ProcessMnemonics = value; + } + } + + + protected override bool ProcessMnemonic(char charCode) + { + if (!this.MenuBar && _ProcessMnemonics) + { + foreach(BaseItem objItem in this.Items) + { + if (objItem.Visible && objItem.GetEnabled() && objItem.Displayed && objItem.AccessKeyEnabled && objItem.AccessKey == charCode) + { + objItem.RaiseClick(eEventSource.Keyboard); + return true; + } + } + } + + return base.ProcessMnemonic(charCode); + } + + protected virtual bool InternalSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + int wParamInt = WinApi.ToInt(wParam); + if (wParamInt == 18 && System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Alt) + this.ClosePopups(); + + Form form = this.FindForm(); + if (form == null || !BarFunctions.IsFormActive(form)) + return false; + + Bar bar = null; + if (this.MenuBar) + bar = this; + if (bar != null && bar.ItemsContainer != null && !bar.ItemsContainer.DesignMode) + { + GenericItemContainer cont = bar.ItemsContainer; + if (cont == null) + return false; + if (wParamInt == 18 || (wParamInt == 121 && !m_IgnoreF10Key && (System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.None || System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Alt))) + { + if (cont.ExpandedItem() != null && bar.Focused) + { + bar.ReleaseFocus(); + m_IgnoreSysKeyUp = true; + return true; + } + } + else + { + // Check Shortcuts + if (System.Windows.Forms.Control.ModifierKeys != Keys.None || wParamInt >= (int)eShortcut.F1 && wParamInt <= (int)eShortcut.F12) + { + int i = (int)System.Windows.Forms.Control.ModifierKeys | wParamInt; + if (ProcessShortcut((eShortcut)i)) + return true; + } + m_IgnoreSysKeyUp = true; + if (wParamInt >= 27 && wParamInt <= 111) // VK_ESC - VK_DIVIDE range + { + int key = (int)NativeFunctions.MapVirtualKey((uint)wParam, 2); + if (key == 0) + key = wParamInt; + if (key > 0 && cont.SysKeyDown(key)) + return true; + } + } + } + else if (bar == null && !this.DesignMode) + { + // Check Shortcuts + if (System.Windows.Forms.Control.ModifierKeys != Keys.None || wParamInt >= (int)eShortcut.F1 && wParamInt <= (int)eShortcut.F12) + { + int i = (int)System.Windows.Forms.Control.ModifierKeys | wParamInt; + if (ProcessShortcut((eShortcut)i)) + return true; + } + } + + if (System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Alt && wParamInt > 0x1B) + { + m_IgnoreSysKeyUp = true; + int key = (int)NativeFunctions.MapVirtualKey((uint)wParam, 2); + if (key != 0) + { + if (!this.DesignMode) + { + if (m_ItemContainer.SysKeyDown(key)) + return true; + } + } + } + return false; + } + + bool IMessageHandlerClient.OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return InternalSysKeyDown(hWnd, wParam, lParam); + } + bool IMessageHandlerClient.OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + Form form = this.FindForm(); + if (form == null || this.DesignMode || !BarFunctions.IsFormActive(form)) + return false; + + int wParamInt = WinApi.ToInt(wParam); + if (wParamInt == 18 || wParamInt == 121) + { + if (m_IgnoreSysKeyUp) + { + m_IgnoreSysKeyUp = false; + return false; + } + if (m_EatSysKeyUp) + { + m_EatSysKeyUp = false; + return true; + } + if (wParamInt == 18 || wParamInt == 121 && !m_IgnoreF10Key) + { + DevComponents.DotNetBar.Bar bar = null; + if (this.MenuBar) + bar = this; + if (bar != null && !bar.ItemsContainer.DesignMode) + { + if (bar.Focused) + bar.ReleaseFocus(); + else + bar.SetSystemFocus(); + return true; + } + } + } + return false; + } + #endregion + + #region BarAccessibleObject + public class BarAccessibleObject : System.Windows.Forms.Control.ControlAccessibleObject + { + Bar m_Owner = null; + public BarAccessibleObject(Bar owner) + : base(owner) + { + m_Owner = owner; + } + + internal void GenerateEvent(BaseItem sender, System.Windows.Forms.AccessibleEvents e) + { + int iChild = m_Owner.Items.IndexOf(sender); + if (iChild >= 0) + { + if (m_Owner != null && !m_Owner.IsDisposed) + m_Owner.AccessibilityNotifyClients(e, iChild); + } + } + + public override AccessibleRole Role + { + get + { + if (m_Owner != null && !m_Owner.IsDisposed) + return m_Owner.AccessibleRole; + return System.Windows.Forms.AccessibleRole.None; + } + } + + public override AccessibleObject Parent + { + get + { + if (m_Owner != null && m_Owner.Parent is DockSite) + return m_Owner.Parent.AccessibilityObject; + return base.Parent; + } + } + + public override Rectangle Bounds + { + get + { + if (m_Owner != null && !m_Owner.IsDisposed && m_Owner.Parent != null) + return this.m_Owner.Parent.RectangleToScreen(m_Owner.Bounds); + return Rectangle.Empty; + } + } + + public override int GetChildCount() + { + if (m_Owner != null && !m_Owner.IsDisposed && m_Owner.Items != null) + return m_Owner.Items.Count; + return 0; + } + + public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) + { + if (m_Owner != null && !m_Owner.IsDisposed && m_Owner.Items != null) + return m_Owner.Items[iIndex].AccessibleObject; + return null; + } + + public override AccessibleStates State + { + get + { + AccessibleStates state; + if (m_Owner == null || m_Owner.IsDisposed) + return AccessibleStates.None; + + if (m_Owner.GrabHandleStyle != eGrabHandleStyle.None && m_Owner.GrabHandleStyle != eGrabHandleStyle.ResizeHandle) + { + state = AccessibleStates.Moveable; + if (m_Owner.DockSide == eDockSide.None) + state = state | AccessibleStates.Floating; + } + else + state = AccessibleStates.None; + return state; + } + } + + public override AccessibleObject Navigate(AccessibleNavigation navdir) + { + if (navdir == AccessibleNavigation.FirstChild) + { + if (m_Owner.Items.Count > 0) return m_Owner.Items[0].AccessibleObject; + } + else if (navdir == AccessibleNavigation.LastChild) + { + if (m_Owner.Items.Count > 0) return m_Owner.Items[m_Owner.Items.Count - 1].AccessibleObject; + } + else if (navdir == AccessibleNavigation.Next) + { + return null; + Control parent = m_Owner.Parent; + if (parent != null && parent.Controls.IndexOf(m_Owner) < parent.Controls.Count - 1) + { + return parent.Controls[parent.Controls.IndexOf(m_Owner) + 1].AccessibilityObject; + } + } + else if (navdir == AccessibleNavigation.Previous) + { + return null; + Control parent = m_Owner.Parent; + if (parent != null && parent.Controls.IndexOf(m_Owner) > 0) + { + return parent.Controls[parent.Controls.IndexOf(m_Owner) - 1].AccessibilityObject; + } + } + else if (navdir == AccessibleNavigation.Down) + { + return null; + if (m_Owner.Items.Count > 0) return m_Owner.Items[0].AccessibleObject; + } + else if (navdir == AccessibleNavigation.Up) + { + return null; + if (m_Owner.Parent != null) return m_Owner.Parent.AccessibilityObject; + } + return base.Navigate(navdir); + } + } + #endregion + + #region IDockInfo + /// + /// Specifes whether Bar can be docked on Top dock site or not. Does not apply to stand alone bars. + /// + bool IDockInfo.CanDockTop + { + get { return this.CanDockTop; } + } + + /// + /// Specifes whether Bar can be docked on Bottom dock site or not. Does not apply to stand alone bars. + /// + bool IDockInfo.CanDockBottom + { + get { return this.CanDockBottom; } + } + + /// + /// Specifes whether Bar can be docked on Left dock site or not. Does not apply to stand alone bars. + /// + bool IDockInfo.CanDockLeft + { + get { return this.CanDockLeft; } + } + + /// + /// Specifes whether Bar can be docked on Right dock site or not. Does not apply to stand alone bars. + /// + bool IDockInfo.CanDockRight + { + get { return this.CanDockRight; } + } + + /// + /// Specifes whether Bar can be docked as document. Default value is false. See DotNetBarManager.EnableDocumentDocking for more details. + /// + bool IDockInfo.CanDockDocument + { + get { return this.CanDockDocument; } + } + + /// + /// Returns Minimum docked size of the control. + /// + System.Drawing.Size IDockInfo.MinimumDockSize(eOrientation dockOrientation) + { + return this.MinimumDockSize(dockOrientation); + } + /// + /// Returns Preferrred size of the docked control. + /// + System.Drawing.Size IDockInfo.PreferredDockSize(eOrientation dockOrientation) + { + return this.PreferredDockSize(dockOrientation); + } + + /// + /// Indicated whether control can be stretched to fill dock site. + /// + bool IDockInfo.Stretch + { + get { return this.Stretch; } + set { this.Stretch = value; } + } + /// + /// Holds the left position (dock offset) of the control. + /// + int IDockInfo.DockOffset + { + get { return this.DockOffset; } + set { this.DockOffset = value; } + } + /// + /// Specifies the dock line for the control. + /// + int IDockInfo.DockLine + { + get { return this.DockLine; } + set { this.DockLine = value; } + } + /// + /// Specifies current dock orientation. + /// + eOrientation IDockInfo.DockOrientation + { + get { return this.DockOrientation; } + set { this.DockOrientation = value; } + } + /// + /// Gets whether control is docked. + /// + bool IDockInfo.Docked + { + get { return this.Docked; } + } + /// + /// Returns the dock site of the control. + /// + System.Windows.Forms.Control IDockInfo.DockedSite + { + get { return this.DockedSite; } + } + /// + /// Gets or sets the control dock side. + /// + eDockSide IDockInfo.DockSide + { + get { return this.DockSide; } + set { this.DockSide = value; } + } + /// + /// Sets the dock line for the control. Used internaly by dock manager. + /// + /// New Dock line. + void IDockInfo.SetDockLine(int iLine) + { + this.SetDockLine(iLine); + } + /// + /// Gets or sets whether bar is locked to prevent docking below it. + /// + bool IDockInfo.LockDockPosition + { + get { return this.LockDockPosition; } + set { this.LockDockPosition = value; } + } + #endregion + + #region Design Time Drag & Drop + private bool m_DragDropInProgress = false; + private int m_InsertPosition = -1; + private bool m_InsertBefore = false; + private IDesignTimeProvider m_DesignTimeProvider = null; + private BaseItem m_DragItem = null; + private IDesignTimeProvider m_DragDropDesignTimeProvider = null; + + private ISite GetSite() + { + ISite site = null; + IOwner owner = this.Owner as IOwner; + Control c = null; + if (owner is Control) + { + c = owner as Control; + } + + if (m_ParentItem != null && m_ParentItem.ContainerControl is Control && (c == null || c != null && c.Site == null)) + { + c = m_ParentItem.ContainerControl as Control; + } + + if (c != null) + { + while (site == null && c != null) + { + if (c.Site != null && c.Site.DesignMode) + site = c.Site; + else + c = c.Parent; + } + } + + if (site == null && m_ParentItem != null) + { + BaseItem item = m_ParentItem; + while (site == null && item != null) + { + if (item.Site != null && item.Site.DesignMode) + site = item.Site; + else + item = item.Parent; + } + } + + return site; + } + + private void DesignTimeMouseMove(MouseEventArgs e) + { + if (m_DragDropInProgress) + { + try + { + if (m_DesignTimeProvider != null) + { + m_DesignTimeProvider.DrawReversibleMarker(m_InsertPosition, m_InsertBefore); + m_DesignTimeProvider = null; + } + + InsertPosition pos = m_DragDropDesignTimeProvider.GetInsertPosition(Control.MousePosition, m_DragItem); + if (pos != null) + { + if (pos.TargetProvider == null) + { + // Cursor is over drag item + System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.No; + } + else + { + pos.TargetProvider.DrawReversibleMarker(pos.Position, pos.Before); + m_InsertPosition = pos.Position; + m_InsertBefore = pos.Before; + m_DesignTimeProvider = pos.TargetProvider; + System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Hand; + } + } + else + { + System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.No; + } + } + catch + { + m_DesignTimeProvider = null; + } + } + else + { + if (m_Owner is IOwner) + m_DragItem = ((IOwner)m_Owner).GetFocusItem(); + if (m_DragItem != null) + { + // Get top level design-time provider + BaseItem item = m_ParentItem; + while (item.Parent is IDesignTimeProvider) + item = item.Parent; + m_DragDropDesignTimeProvider = (IDesignTimeProvider)item; + + m_DragDropInProgress = true; + this.Capture = true; + } + } + } + + private void DesignTimeMouseUp(MouseEventArgs e) + { + ISite site = GetSite(); + if (site == null) + return; + IComponentChangeService cc = site.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + + if (m_DesignTimeProvider != null) + { + m_DesignTimeProvider.DrawReversibleMarker(m_InsertPosition, m_InsertBefore); + BaseItem objParent = m_DragItem.Parent; + if (objParent != null) + { + if (objParent == (BaseItem)m_DesignTimeProvider && m_InsertPosition > 0) + { + if (objParent.SubItems.IndexOf(m_DragItem) < m_InsertPosition) + m_InsertPosition--; + } + if (cc != null) + cc.OnComponentChanging(objParent, TypeDescriptor.GetProperties(objParent)["SubItems"]); + + objParent.SubItems.Remove(m_DragItem); + + if (cc != null) + cc.OnComponentChanged(objParent, TypeDescriptor.GetProperties(objParent)["SubItems"], null, null); + + Control ctrl = objParent.ContainerControl as Control; + if (ctrl is Bar) + ((Bar)ctrl).RecalcLayout(); + else if (ctrl is MenuPanel) + ((MenuPanel)ctrl).RecalcSize(); + } + + m_DesignTimeProvider.InsertItemAt(m_DragItem, m_InsertPosition, m_InsertBefore); + + m_DesignTimeProvider = null; + + } + m_DragDropDesignTimeProvider = null; + m_DragItem = null; + m_DragDropInProgress = false; + this.Capture = false; + } + + private void DesignTimeMouseDown(MouseEventArgs e) + { + IOwner owner = this.Owner as IOwner; + BaseItem objNew = m_ItemContainer.ItemAtLocation(e.X, e.Y); + // Ignore system items + if (objNew != null && objNew.SystemItem) + objNew = null; + + if (objNew == null) + return; + + if (owner != null) + { + owner.SetFocusItem(objNew); + ISite site = GetSite(); + if (site != null) + { + ISelectionService selection = (ISelectionService)site.GetService(typeof(ISelectionService)); + if (selection != null) + { + ArrayList arr = new ArrayList(1); + arr.Add(objNew); +#if FRAMEWORK20 + selection.SetSelectedComponents(arr, SelectionTypes.Primary); +#else + selection.SetSelectedComponents(arr,SelectionTypes.MouseDown); +#endif + } + if (e.Button == MouseButtons.Right) + { + IMenuCommandService service1 = (IMenuCommandService)site.GetService(typeof(IMenuCommandService)); + if (service1 != null) + { + service1.ShowContextMenu(new CommandID(new Guid("{74D21312-2AEE-11d1-8BFB-00A0C90F26F7}"), 0x500)/*System.Windows.Forms.Design.MenuCommands.SelectionMenu*/, Control.MousePosition.X, Control.MousePosition.Y); + } + } + } + } + owner = null; + if (objNew != null) + objNew.InternalMouseDown(e); + } + #endregion + + #region IOwnerLocalize Implementation + void IOwnerLocalize.InvokeLocalizeString(LocalizeEventArgs e) + { + if (LocalizeString != null) + LocalizeString(this, e); + } + #endregion + } + + #region FloatingContainer + [ToolboxItem(false)] + internal class FloatingContainer : Form + { + const int WM_MOUSEACTIVATE = 0x21; + const int MA_NOACTIVATE = 3; + //const int MA_NOACTIVATEANDEAT = 4; + Bar m_Bar; + private Size m_OldSize = Size.Empty; + public FloatingContainer(Bar objBar) + { + m_Bar = objBar; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.ControlBox = false; + this.ShowInTaskbar = false; + IOwner owner = objBar.Owner as IOwner; + if (owner != null) + this.Owner = owner.ParentForm; + this.StartPosition = FormStartPosition.Manual; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.SetStyle(ControlStyles.Selectable, false); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.Font = objBar.Font; + } + private bool m_CodeClose = false; + public new void Close() + { + m_CodeClose = true; + base.Close(); + } + protected override void OnClosing(CancelEventArgs e) + { + if (this.Visible) + { + if (!m_CodeClose) + { + e.Cancel = true; + if (m_Bar != null) + m_Bar.CloseBar(); + } + } + base.OnClosing(e); + } + + public void RefreshRegion(System.Drawing.Size sz) + { + if (m_Bar == null || m_OldSize == sz) + return; + + if (!m_Bar.IsThemed) + return; + + m_OldSize = sz; + + ThemeWindow theme = m_Bar.ThemeWindow; + Graphics g = this.CreateGraphics(); + try + { + IntPtr r = theme.GetThemeBackgroundRegion(g, ThemeWindowParts.SmallCaption, ThemeWindowStates.CaptionActive, new Rectangle(0, 0, sz.Width, sz.Height)); + if (r != IntPtr.Zero) + { + NativeFunctions.SetWindowRgn(this.Handle, r, true); + } + } + finally + { + g.Dispose(); + } + } + protected override void WndProc(ref Message m) + { + if (m.Msg == WM_MOUSEACTIVATE && m_Bar.LayoutType != eLayoutType.DockContainer) + { + m.Result = new System.IntPtr(MA_NOACTIVATE); + return; + } + base.WndProc(ref m); + } + protected override void OnActivated(EventArgs e) + { + base.OnActivated(e); + if (m_Bar != null && m_Bar.LayoutType == eLayoutType.DockContainer) + { + m_Bar.SetHasFocus(true); + } + } + + protected override void OnDeactivate(EventArgs e) + { + base.OnDeactivate(e); + if (m_Bar != null && m_Bar.LayoutType == eLayoutType.DockContainer) + { + m_Bar.SetHasFocus(false); + } + } + } + #endregion + + #region Custom Rendering Support + /// + /// Defines delegate for the PreRender and PostRender Bar control events. + /// + public delegate void RenderBarEventHandler(object sender, RenderBarEventArgs e); + + /// + /// Represents event arguments for PreRender and PostRender Bar control event. + /// + public class RenderBarEventArgs : EventArgs + { + /// + /// Gets the reference to the Bar being rendered. + /// + public readonly Bar Bar; + + /// + /// Gets or sets the rectangle of the part being rendered. Certain parts of bar like the title buttons allow you to set this property to the custom size of your button. + /// Default value is the system size of the part being rendered. + /// + public Rectangle Bounds = Rectangle.Empty; + + /// + /// Gets the Bar part being rendered. + /// + public readonly eBarRenderPart Part = eBarRenderPart.Background; + + /// + /// When used in PreRender event allows you to cancel the default rendering by setting this property to true. + /// + public bool Cancel = false; + + /// + /// Gets the reference to the Graphics object to render the tab on. + /// + public readonly Graphics Graphics; + + /// + /// Creates new instance of the class and initializes it with default values. + /// + public RenderBarEventArgs(Bar bar, Graphics g, eBarRenderPart part, Rectangle bounds) + { + this.Bar = bar; + this.Part = part; + this.Bounds = bounds; + this.Graphics = g; + } + } + + /// + /// Defines the part of the Bar control for custom rendering. + /// + public enum eBarRenderPart + { + /// + /// Indicates the Bar background and border. + /// + Background, + /// + /// Indicates the Bar caption. + /// + Caption, + /// + /// Indicates the Bar close button displayed inside of caption. + /// + CloseButton, + /// + /// Indicates the Bar customize button displayed inside of caption. + /// + CustomizeButton, + /// + /// Indicates the Bar caption text. + /// + CaptionText, + /// + /// Indicates the Bar grab handle. + /// + GrabHandle, + /// + /// Indicates the Bar resize handle. + /// + ResizeHandle, + /// + /// Indicates the Bar auto-hide button displayed inside of caption. + /// + AutoHideButton, + /// + /// Indicates the Bar caption task pane. + /// + CaptionTaskPane, + /// + /// Indicates the Bar maximize button displayed inside of caption. + /// + MaximizeButton, + /// + /// Indicates the complete bar area. This part is used for the PostRender event. + /// + All + + } + #endregion + + #region BarStateChanged Event Support + /// + /// Defines delegate for BarStateChanged event. + /// + /// + /// + public delegate void BarStateChangedEventHandler(object sender, BarStateChangedEventArgs e); + /// + /// Provides event arguments for ActiveDockContainerChanged event. + /// + public class BarStateChangedEventArgs : EventArgs + { + /// + /// Gets the Bar that is changed. + /// + public readonly Bar Bar; + /// + /// Gets the type of the change that affected the bar. + /// + public readonly eBarStateChange AffectedState; + /// + /// Provides any optional context information about the state change. + /// + public object ContextInformation; + /// + /// Initializes a new instance of the BarStateChangedEventArgs class. + /// + /// + /// + public BarStateChangedEventArgs(Bar bar, eBarStateChange affectedState) + { + Bar = bar; + AffectedState = affectedState; + } + /// + /// Initializes a new instance of the BarStateChangedEventArgs class. + /// + /// + /// + /// + public BarStateChangedEventArgs(Bar bar, eBarStateChange affectedState, object contextInformation) + { + Bar = bar; + AffectedState = affectedState; + ContextInformation = contextInformation; + } + } + /// + /// Defines bar state changes for BarStateChanged event. + /// + public enum eBarStateChange + { + /// + /// Indicates that Bar selected dock tab is about to change. + /// + SelectedDockTabChanging, + /// + /// Indicates that Bar selected dock tab has changed. + /// + SelectedDockTabChanged, + /// + /// Indicates that bar docking has changed and bar was docked. + /// + BarDocked, + /// + /// Indicates that bar has been undocked from dock site. + /// + BarUndocked, + /// + /// Indicates that bar dock tab has closed. + /// + DockTabClosed, + /// + /// Indicates that bar in auto-hide state has been folded, i.e. returned to collapsed state. + /// + AutoHideFolded, + /// + /// Indicates that bar in auto-hide state has been open, shown. + /// + AutoHideOpen, + /// + /// Indicates that bar AutoHide property has changed meaning that bar has been either placed in auto-hide mode or taken out of auto-hide mode. + /// + AutoHideChanged, + /// + /// Indicates that tab has been moved within a bar tab-strip by end user. + /// + DockTabMoved + } + #endregion + + public class KeyEventArgsEx:KeyEventArgs + { + public char KeyChar = '\0'; + public KeyEventArgsEx(Keys keyData, char keyChar):base(keyData) + { + this.KeyChar = keyChar; + } + } + + /// + /// Specifies the behavior of bar when its title is double clicked. + /// + public enum eDoubleClickBarBehavior + { + /// + /// Double clicking bar title does not do anything. + /// + None, + /// + /// Double clicking bar title when bar is docked will float the bar if CanUndock=true + /// + Float, + /// + /// Double clicking floating bar title will re-dock it if any of CanDock*** properties is true. + /// + ReDock, + /// + /// Double clicking will toggle bar state between float and dock state if all CanDock*** and CanUndock properties allow it. + /// + FloatAndReDock + } +} diff --git a/PROMS/DotNetBar Source Code/Bar.ico b/PROMS/DotNetBar Source Code/Bar.ico new file mode 100644 index 00000000..494cb4e6 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Bar.ico differ diff --git a/PROMS/DotNetBar Source Code/BarBaseControl.cs b/PROMS/DotNetBar Source Code/BarBaseControl.cs new file mode 100644 index 00000000..e69faed3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BarBaseControl.cs @@ -0,0 +1,2337 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents base control for bars. + /// + [ToolboxItem(false),System.Runtime.InteropServices.ComVisible(false)] + public abstract class BarBaseControl: System.Windows.Forms.Control, + IOwner, IOwnerMenuSupport, IMessageHandlerClient, IOwnerItemEvents, IThemeCache, IOwnerLocalize, IBarDesignerServices, IRenderingSupport, + IAccessibilitySupport + { + // Events + #region Event Definition + /// + /// Occurs when Checked property of an button has changed. + /// + public event EventHandler ButtonCheckedChanged; + /// + /// Represents the method that will handle the ItemRemoved event. + /// + public delegate void ItemRemovedEventHandler(object sender, ItemRemovedEventArgs e); + + /// + /// Occurs when Item is clicked. + /// + [System.ComponentModel.Description("Occurs when Item is clicked.")] + public event EventHandler ItemClick; + + /// + /// Occurs when Item is clicked. + /// + [Description("Occurs when Item is double-clicked.")] + public event MouseEventHandler ItemDoubleClick; + + /// + /// Occurs when popup of type container is loading. + /// + [System.ComponentModel.Description("Occurs when popup of type container is loading.")] + public event EventHandler PopupContainerLoad; + + /// + /// Occurs when popup of type container is unloading. + /// + [System.ComponentModel.Description("Occurs when popup of type container is unloading.")] + public event EventHandler PopupContainerUnload; + + /// + /// Occurs when popup item is about to open. + /// + [System.ComponentModel.Description("Occurs when popup item is about to open.")] + public event EventHandler PopupOpen; + + /// + /// Occurs when popup item is closing. + /// + [System.ComponentModel.Description("Occurs when popup item is closing.")] + public event EventHandler PopupClose; + + /// + /// Occurs just before popup window is shown. + /// + [System.ComponentModel.Description("Occurs just before popup window is shown.")] + public event EventHandler PopupShowing; + + /// + /// Occurs when Item Expanded property has changed. + /// + [System.ComponentModel.Description("Occurs when Item Expanded property has changed.")] + public event EventHandler ExpandedChange; + + private MouseEventHandler EventMouseDown; + /// + /// Occurs when mouse button is pressed. + /// + [System.ComponentModel.Description("Occurs when mouse button is pressed.")] + new public event MouseEventHandler MouseDown + { + add { EventMouseDown += value; } + remove { EventMouseDown -= value; } + } + + private MouseEventHandler EventMouseUp; + /// + /// Occurs when mouse button is released. + /// + [System.ComponentModel.Description("Occurs when mouse button is released.")] + new public event MouseEventHandler MouseUp + { + add { EventMouseUp += value; } + remove { EventMouseUp -= value; } + } + + private EventHandler EventMouseEnter; + /// + /// Occurs when mouse enters the item. + /// + [System.ComponentModel.Description("Occurs when mouse enters the item.")] + new public event EventHandler MouseEnter + { + add { EventMouseEnter += value; } + remove { EventMouseEnter -= value; } + } + + private EventHandler EventMouseLeave; + /// + /// Occurs when mouse leaves the item. + /// + [System.ComponentModel.Description("Occurs when mouse leaves the item.")] + new public event EventHandler MouseLeave + { + add { EventMouseLeave += value; } + remove { EventMouseLeave -= value; } + } + + private MouseEventHandler EventMouseMove; + /// + /// Occurs when mouse moves over the item. + /// + [System.ComponentModel.Description("Occurs when mouse moves over the item.")] + new public event MouseEventHandler MouseMove + { + add { EventMouseMove += value; } + remove { EventMouseMove -= value; } + } + + private EventHandler EventMouseHover; + /// + /// Occurs when mouse remains still inside an item for an amount of time. + /// + [System.ComponentModel.Description("Occurs when mouse remains still inside an item for an amount of time.")] + new public event EventHandler MouseHover + { + add { EventMouseHover += value; } + remove { EventMouseHover -= value; } + } + + private EventHandler EventLostFocus; + /// + /// Occurs when item loses input focus. + /// + [System.ComponentModel.Description("Occurs when item loses input focus.")] + new public event EventHandler LostFocus + { + add { EventLostFocus += value; } + remove { EventLostFocus -= value; } + } + + private EventHandler EventGotFocus; + /// + /// Occurs when item receives input focus. + /// + [System.ComponentModel.Description("Occurs when item receives input focus.")] + new public event EventHandler GotFocus + { + add { EventGotFocus += value; } + remove { EventGotFocus -= value; } + } + + /// + /// Occurs when user changes the item position, removes the item, adds new item or creates new bar. + /// + [System.ComponentModel.Description("Occurs when user changes the item position.")] + public event EventHandler UserCustomize; + + /// + /// Occurs after an Item is removed from SubItemsCollection. + /// + [System.ComponentModel.Description("Occurs after an Item is removed from SubItemsCollection.")] + public event ItemRemovedEventHandler ItemRemoved; + + /// + /// Occurs after an Item has been added to the SubItemsCollection. + /// + [System.ComponentModel.Description("Occurs after an Item has been added to the SubItemsCollection.")] + public event EventHandler ItemAdded; + + /// + /// Occurs when ControlContainerControl is created and contained control is needed. + /// + [System.ComponentModel.Description("Occurs when ControlContainerControl is created and contained control is needed.")] + public event EventHandler ContainerLoadControl; + + /// + /// Occurs when Text property of an Item has changed. + /// + [System.ComponentModel.Description("Occurs when Text property of an Item has changed.")] + public event EventHandler ItemTextChanged; + + /// + /// Use this event if you want to serialize the hosted control state directly into the DotNetBar definition file. + /// + public event ControlContainerItem.ControlContainerSerializationEventHandler ContainerControlSerialize; + /// + /// Use this event if you want to deserialize the hosted control state directly from the DotNetBar definition file. + /// + public event ControlContainerItem.ControlContainerSerializationEventHandler ContainerControlDeserialize; + + /// + /// Occurs after DotNetBar definition is loaded. + /// + [System.ComponentModel.Description("Occurs after DotNetBar definition is loaded.")] + public event EventHandler DefinitionLoaded; + + /// + /// Occurs when DotNetBar is looking for translated text for one of the internal text that are + /// displayed on menus, toolbars and customize forms. You need to set Handled=true if you want + /// your custom text to be used instead of the built-in system value. + /// + public event DotNetBarManager.LocalizeStringEventHandler LocalizeString; + + /// + /// Occurs before an item in option group is checked and provides opportunity to cancel that. + /// + public event OptionGroupChangingEventHandler OptionGroupChanging; + + /// + /// Occurs before tooltip for an item is shown. Sender could be the BaseItem or derived class for which tooltip is being displayed or it could be a ToolTip object itself it tooltip is not displayed for any item in particular. + /// + public event EventHandler ToolTipShowing; + + /// + /// Occurs after main application form is activated. + /// + internal event EventHandler ApplicationActivate; + /// + /// Occurs after main application form is deacticated. + /// + internal event EventHandler ApplicationDeactivate; + /// + /// Occurs on application wide mouse down event. + /// + internal event HandlerMessageEventHandler ApplicationMouseDown; + #endregion + + #region Private Variables + private BaseItem m_BaseItemContainer=null; + private BaseItem m_ExpandedItem=null; + private BaseItem m_FocusItem=null; + private Hashtable m_ShortcutTable=new Hashtable(); + private System.Windows.Forms.ImageList m_ImageList; + private System.Windows.Forms.ImageList m_ImageListMedium=null; + private System.Windows.Forms.ImageList m_ImageListLarge=null; + private BaseItem m_DragItem=null; + private bool m_DragDropSupport=false; + private bool m_DragLeft=false; + private bool m_AllowExternalDrop=false; + private bool m_UseNativeDragDrop=false; + private bool m_DragInProgress=false; + private bool m_ExternalDragInProgress=false; + private Cursor m_MoveCursor, m_CopyCursor, m_NACursor; + private bool m_ShowToolTips=true; + private bool m_ShowShortcutKeysInToolTips=false; + private bool m_FilterInstalled=false; + private bool m_DispatchShortcuts=false; + private bool m_MenuEventSupport=false; + private IDesignTimeProvider m_DesignTimeProvider=null; + private int m_InsertPosition; + private bool m_InsertBefore=false; + private System.Windows.Forms.Timer m_ClickTimer=null; + private BaseItem m_ClickRepeatItem=null; + // Theme Caching Support + private ThemeWindow m_ThemeWindow=null; + private ThemeRebar m_ThemeRebar=null; + private ThemeToolbar m_ThemeToolbar=null; + private ThemeHeader m_ThemeHeader=null; + private ThemeScrollBar m_ThemeScrollBar=null; + private ThemeExplorerBar m_ThemeExplorerBar=null; + private ThemeProgress m_ThemeProgress=null; + private ThemeButton m_ThemeButton = null; + + private ColorScheme m_ColorScheme=null; + private bool m_ThemeAware=false; + private string m_EmptyContainerDesignTimeHint="Right-click to add more items..."; + private ItemStyle m_BackgroundStyle=new ItemStyle(); + private bool m_DesignModeInternal=false; + private IBarItemDesigner m_BarDesigner=null; + private BaseItem m_DoDefaultActionItem = null; + private bool m_AntiAlias = false; + #endregion + + #region Constructor + public BarBaseControl() + { + if(!ColorFunctions.ColorsLoaded) + { + NativeFunctions.RefreshSettings(); + NativeFunctions.OnDisplayChange(); + ColorFunctions.LoadColors(); + } + + this.SetStyle(ControlStyles.UserPaint,true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint,true); + this.SetStyle(ControlStyles.Opaque,true); + this.SetStyle(ControlStyles.ResizeRedraw,true); + this.SetStyle(DisplayHelp.DoubleBufferFlag,true); + + try + { + m_MoveCursor=new Cursor(typeof(DevComponents.DotNetBar.DotNetBarManager),"DRAGMOVE.CUR"); + m_CopyCursor=new Cursor(typeof(DevComponents.DotNetBar.DotNetBarManager),"DRAGCOPY.CUR"); + m_NACursor=new Cursor(typeof(DevComponents.DotNetBar.DotNetBarManager),"DRAGNONE.CUR"); + } + catch(Exception) + { + m_MoveCursor=null; + m_CopyCursor=null; + m_NACursor=null; + } + + m_ColorScheme=new ColorScheme(eDotNetBarStyle.Office2003); + + m_BackgroundStyle.BackColor1.Color=SystemColors.Control; + m_BackgroundStyle.VisualPropertyChanged+=new EventHandler(this.VisualPropertyChanged); + + this.IsAccessible=true; + } + + protected bool GetDesignMode() + { + if(!m_DesignModeInternal) + return this.DesignMode; + return m_DesignModeInternal; + } + + internal void SetDesignMode(bool mode) + { + m_DesignModeInternal=mode; + m_BaseItemContainer.SetDesignMode(mode); + } + + protected override AccessibleObject CreateAccessibilityInstance() + { + return new BarBaseControlAccessibleObject(this); + } + + /// + /// Notifies the accessibility client applications of the specified AccessibleEvents for the specified child control. + /// + /// The AccessibleEvents object to notify the accessibility client applications of. + /// The child Control to notify of the accessible event. + internal void InternalAccessibilityNotifyClients(AccessibleEvents accEvent,int childID) + { + this.AccessibilityNotifyClients(accEvent,childID); + } + #endregion + + #region IOwner Implementation + /// + /// Gets or sets the form SideBar is attached to. + /// + Form IOwner.ParentForm + { + get + { + return base.FindForm(); + } + set {} + } + + /// + /// Returns the collection of items with the specified name. + /// + /// Item name to look for. + /// + public virtual ArrayList GetItems(string ItemName) + { + ArrayList list=new ArrayList(15); + BarFunctions.GetSubItemsByName(m_BaseItemContainer,ItemName,list); + return list; + } + + /// + /// Returns the collection of items with the specified name and type. + /// + /// Item name to look for. + /// Item type to look for. + /// + public virtual ArrayList GetItems(string ItemName, Type itemType) + { + ArrayList list=new ArrayList(15); + BarFunctions.GetSubItemsByNameAndType(m_BaseItemContainer,ItemName,list,itemType); + return list; + } + + /// + /// Returns the collection of items with the specified name and type. + /// + /// Item name to look for. + /// Item type to look for. + /// + public virtual ArrayList GetItems(string ItemName, Type itemType, bool useGlobalName) + { + ArrayList list = new ArrayList(15); + BarFunctions.GetSubItemsByNameAndType(m_BaseItemContainer, ItemName, list, itemType, useGlobalName); + return list; + } + + /// + /// Returns the first item that matches specified name. + /// + /// Item name to look for. + /// + public virtual BaseItem GetItem(string ItemName) + { + BaseItem item=BarFunctions.GetSubItemByName(m_BaseItemContainer,ItemName); + if(item!=null) + return item; + return null; + } + + // Only one Popup Item can be expanded at a time. This is used + // to track the currently expanded popup item and to close the popup item + // if another item is expanding. + void IOwner.SetExpandedItem(BaseItem objItem) + { + if(objItem!=null && objItem.Parent is PopupItem) + return; + if(m_ExpandedItem!=null) + { + if(m_ExpandedItem.Expanded) + m_ExpandedItem.Expanded=false; + m_ExpandedItem=null; + } + m_ExpandedItem=objItem; + } + + BaseItem IOwner.GetExpandedItem() + { + return m_ExpandedItem; + } + + // Currently we are using this to communicate "focus" when control is in + // design mode. This can be used later if we decide to add focus + // handling to our BaseItem class. + void IOwner.SetFocusItem(BaseItem objFocusItem) + { + if(m_FocusItem!=null && m_FocusItem!=objFocusItem) + { + m_FocusItem.OnLostFocus(); + } + OnSetFocusItem(objFocusItem); + m_FocusItem=objFocusItem; + if(m_FocusItem!=null) + m_FocusItem.OnGotFocus(); + } + + protected virtual void OnSetFocusItem(BaseItem objFocusItem) + { + } + + BaseItem IOwner.GetFocusItem() + { + return m_FocusItem; + } + + void IOwner.DesignTimeContextMenu(BaseItem objItem) + { + } + + bool IOwner.DesignMode + { + get {return this.GetDesignMode();} + } + + void IOwner.RemoveShortcutsFromItem(BaseItem objItem) + { + ShortcutTableEntry objEntry=null; + if(objItem.ShortcutString!="") + { + foreach(eShortcut key in objItem.Shortcuts) + { + if(m_ShortcutTable.ContainsKey(key)) + { + objEntry=(ShortcutTableEntry)m_ShortcutTable[key]; + try + { + objEntry.Items.Remove(objItem.Id); + if(objEntry.Items.Count==0) + m_ShortcutTable.Remove(objEntry.Shortcut); + } + catch(System.ArgumentException) {} + } + } + } + IOwner owner=this as IOwner; + foreach(BaseItem objTmp in objItem.SubItems) + owner.RemoveShortcutsFromItem(objTmp); + } + + void IOwner.AddShortcutsFromItem(BaseItem objItem) + { + ShortcutTableEntry objEntry=null; + if(objItem.ShortcutString!="") + { + foreach(eShortcut key in objItem.Shortcuts) + { + if(m_ShortcutTable.ContainsKey(key)) + objEntry=(ShortcutTableEntry)m_ShortcutTable[objItem.Shortcuts[0]]; + else + { + objEntry=new ShortcutTableEntry(key); + m_ShortcutTable.Add(objEntry.Shortcut,objEntry); + } + try + { + objEntry.Items.Add(objItem.Id,objItem); + } + catch(System.ArgumentException) {} + } + } + IOwner owner=this as IOwner; + foreach(BaseItem objTmp in objItem.SubItems) + owner.AddShortcutsFromItem(objTmp); + } + + Form IOwner.ActiveMdiChild + { + get + { + Form form=base.FindForm(); + if(form==null) + return null; + if(form.IsMdiContainer) + { + return form.ActiveMdiChild; + } + return null; + } + } + + bool IOwner.AlwaysDisplayKeyAccelerators + { + get {return false;} + set {} + } + + /// + /// Invokes the DotNetBar Customize dialog. + /// + void IOwner.Customize() + { + } + + void IOwner.InvokeResetDefinition(BaseItem item,EventArgs e) + { + } + + /// + /// Indicates whether Reset buttons is shown that allows end-user to reset the toolbar state. + /// + bool IOwner.ShowResetButton + { + get{return false;} + set {} + } + + void IOwner.OnApplicationActivate() + { + if (ApplicationActivate != null) + ApplicationActivate(this, new EventArgs()); + } + void IOwner.OnApplicationDeactivate() + { + ClosePopups(); + if (ApplicationDeactivate != null) + ApplicationDeactivate(this, new EventArgs()); + } + void IOwner.OnParentPositionChanging(){} + + void IOwner.StartItemDrag(BaseItem item) + { + if(!m_DragDropSupport) + return; + + if(m_DragItem==null) + { + m_DragItem=item; + if(!m_UseNativeDragDrop) + { + this.Capture=true; + if(m_MoveCursor!=null) + System.Windows.Forms.Cursor.Current=m_MoveCursor; + else + System.Windows.Forms.Cursor.Current=System.Windows.Forms.Cursors.Hand; + m_DragInProgress=true; + } + else + { + m_DragInProgress=true; + this.DoDragDrop(item,DragDropEffects.All); + if(m_DragInProgress) + MouseDragDrop(-1,-1,null); + } + + } + } + + bool IOwner.DragInProgress + { + get{ return m_DragInProgress;} + } + + BaseItem IOwner.DragItem + { + get {return m_DragItem;} + } + + void IOwner.InvokeUserCustomize(object sender,EventArgs e) + { + if(UserCustomize!=null) + UserCustomize(sender,e); + } + + void IOwner.InvokeEndUserCustomize(object sender,EndUserCustomizeEventArgs e){} + + System.Windows.Forms.MdiClient IOwner.GetMdiClient(System.Windows.Forms.Form MdiForm) + { + return BarFunctions.GetMdiClient(MdiForm); + } + + /// + /// ImageList for images used on Items. Images specified here will always be used on menu-items and are by default used on all Bars. + /// + [System.ComponentModel.Browsable(true),System.ComponentModel.Category("Data"),DefaultValue(null),System.ComponentModel.Description("ImageList for images used on Items. Images specified here will always be used on menu-items and are by default used on all Bars.")] + public System.Windows.Forms.ImageList Images + { + get + { + return m_ImageList; + } + set + { + if(m_ImageList!=null) + m_ImageList.Disposed-=new EventHandler(this.ImageListDisposed); + m_ImageList=value; + if(m_ImageList!=null) + m_ImageList.Disposed+=new EventHandler(this.ImageListDisposed); + } + } + + /// + /// ImageList for medium-sized images used on Items. + /// + [System.ComponentModel.Browsable(true),System.ComponentModel.Category("Data"),DefaultValue(null),System.ComponentModel.Description("ImageList for medium-sized images used on Items.")] + public System.Windows.Forms.ImageList ImagesMedium + { + get + { + return m_ImageListMedium; + } + set + { + if(m_ImageListMedium!=null) + m_ImageListMedium.Disposed-=new EventHandler(this.ImageListDisposed); + m_ImageListMedium=value; + if(m_ImageListMedium!=null) + m_ImageListMedium.Disposed+=new EventHandler(this.ImageListDisposed); + } + } + + /// + /// ImageList for large-sized images used on Items. + /// + [System.ComponentModel.Browsable(true),System.ComponentModel.Category("Data"),DefaultValue(null),System.ComponentModel.Description("ImageList for large-sized images used on Items.")] + public System.Windows.Forms.ImageList ImagesLarge + { + get + { + return m_ImageListLarge; + } + set + { + if(m_ImageListLarge!=null) + m_ImageListLarge.Disposed-=new EventHandler(this.ImageListDisposed); + m_ImageListLarge=value; + if(m_ImageListLarge!=null) + m_ImageListLarge.Disposed+=new EventHandler(this.ImageListDisposed); + } + } + + private void ImageListDisposed(object sender, EventArgs e) + { + if(sender==m_ImageList) + { + m_ImageList=null; + } + else if(sender==m_ImageListLarge) + { + m_ImageListLarge=null; + } + else if(sender==m_ImageListMedium) + { + m_ImageListMedium=null; + } + } + + protected override void OnParentChanged(EventArgs e) + { + base.OnParentChanged(e); + if(this.Parent!=null && (this.Images!=null || this.ImagesLarge!=null || this.ImagesMedium!=null)) + { + foreach(BaseItem panel in m_BaseItemContainer.SubItems) + { + foreach(BaseItem item in panel.SubItems) + { + if(item is ImageItem) + ((ImageItem)item).OnImageChanged(); + } + } + } + + if(this.DesignMode) + m_BaseItemContainer.SetDesignMode(this.DesignMode); + } + + void IOwner.InvokeDefinitionLoaded(object sender,EventArgs e) + { + if(DefinitionLoaded!=null) + DefinitionLoaded(sender,e); + } + + /// + /// Indicates whether Tooltips are shown on Bars and menus. + /// + [System.ComponentModel.Browsable(true),DefaultValue(true),System.ComponentModel.Category("Run-time Behavior"),System.ComponentModel.Description("Indicates whether Tooltips are shown on Bars and menus.")] + public bool ShowToolTips + { + get + { + return m_ShowToolTips; + } + set + { + m_ShowToolTips=value; + } + } + + /// + /// Indicates whether item shortcut is displayed in Tooltips. + /// + [System.ComponentModel.Browsable(true),DefaultValue(false),System.ComponentModel.Category("Run-time Behavior"),System.ComponentModel.Description("Indicates whether item shortcut is displayed in Tooltips.")] + public bool ShowShortcutKeysInToolTips + { + get + { + return m_ShowShortcutKeysInToolTips; + } + set + { + m_ShowShortcutKeysInToolTips=value; + } + } + + + #endregion + + #region IOwnerMenuSupport Implementation + // IOwnerMenuSupport + private Hook m_Hook = null; + private ArrayList m_RegisteredPopups=new ArrayList(); + bool IOwnerMenuSupport.PersonalizedAllVisible {get{return false;}set{}} + bool IOwnerMenuSupport.ShowFullMenusOnHover {get{return true;}set{}} + bool IOwnerMenuSupport.AlwaysShowFullMenus {get{return false;}set{}} + + void IOwnerMenuSupport.RegisterPopup(PopupItem objPopup) + { + if(m_RegisteredPopups.Contains(objPopup)) + return; + + if(!this.GetDesignMode()) + { + if(!m_FilterInstalled) + { + //System.Windows.Forms.Application.AddMessageFilter(this); + MessageHandler.RegisterMessageClient(this); + m_FilterInstalled=true; + } + } + else + { + if (m_Hook == null) + { + m_Hook = new Hook(this); + } + } + + if(!m_MenuEventSupport) + MenuEventSupportHook(); + + if (m_RegisteredPopups.Count == 0) + PopupManager.RegisterPopup((IOwnerMenuSupport)this); + + m_RegisteredPopups.Add(objPopup); + if(objPopup.GetOwner()!=this) + objPopup.SetOwner(this); + } + void IOwnerMenuSupport.UnregisterPopup(PopupItem objPopup) + { + if(m_RegisteredPopups.Contains(objPopup)) + m_RegisteredPopups.Remove(objPopup); + if (m_RegisteredPopups.Count == 0) + { + MenuEventSupportUnhook(); + if (m_Hook != null) + { + m_Hook.Dispose(); + m_Hook = null; + } + PopupManager.UnregisterPopup((IOwnerMenuSupport)this); + } + } + bool IOwnerMenuSupport.RelayMouseHover() + { + foreach(PopupItem popup in m_RegisteredPopups) + { + Control ctrl=popup.PopupControl; + if(ctrl!=null && ctrl.DisplayRectangle.Contains(Control.MousePosition)) + { + if(ctrl is MenuPanel) + ((MenuPanel)ctrl).InternalMouseHover(); + else if(ctrl is Bar) + ((Bar)ctrl).InternalMouseHover(); + return true; + } + } + return false; + } + + void IOwnerMenuSupport.ClosePopups() + { + ClosePopups(); + } + + private void ClosePopups() + { + ArrayList popupList = new ArrayList(m_RegisteredPopups); + foreach (PopupItem objPopup in popupList) + objPopup.ClosePopup(); + } + + // Events + void IOwnerMenuSupport.InvokePopupClose(PopupItem item,EventArgs e) + { + if(PopupClose!=null) + PopupClose(item,e); + } + void IOwnerMenuSupport.InvokePopupContainerLoad(PopupItem item,EventArgs e) + { + if(PopupContainerLoad!=null) + PopupContainerLoad(item,e); + } + void IOwnerMenuSupport.InvokePopupContainerUnload(PopupItem item,EventArgs e) + { + if(PopupContainerUnload!=null) + PopupContainerUnload(item,e); + } + void IOwnerMenuSupport.InvokePopupOpen(PopupItem item,PopupOpenEventArgs e) + { + if(PopupOpen!=null) + PopupOpen(item,e); + } + void IOwnerMenuSupport.InvokePopupShowing(PopupItem item,EventArgs e) + { + if(PopupShowing!=null) + PopupShowing(item,e); + } + bool IOwnerMenuSupport.ShowPopupShadow {get{return false;}} + eMenuDropShadow IOwnerMenuSupport.MenuDropShadow{get{return eMenuDropShadow.Hide;}set{}} + ePopupAnimation IOwnerMenuSupport.PopupAnimation{get {return ePopupAnimation.SystemDefault;}set{}} + bool IOwnerMenuSupport.AlphaBlendShadow{get {return true;}set{}} + #endregion + + #region IOwnerItemEvents Implementation + void IOwnerItemEvents.InvokeCheckedChanged(ButtonItem item, EventArgs e) + { + if (ButtonCheckedChanged != null) + ButtonCheckedChanged(item, e); + } + void IOwnerItemEvents.InvokeItemAdded(BaseItem item,EventArgs e) + { + if(ItemAdded!=null) + ItemAdded(item,e); + } + void IOwnerItemEvents.InvokeItemRemoved(BaseItem item, BaseItem parent, int itemIndex) + { + if(ItemRemoved!=null) + { + ItemRemoved(item,new ItemRemovedEventArgs(parent, itemIndex)); + } + } + void IOwnerItemEvents.InvokeMouseEnter(BaseItem item,EventArgs e) + { + if(EventMouseEnter!=null) + EventMouseEnter(item,e); + } + void IOwnerItemEvents.InvokeMouseHover(BaseItem item,EventArgs e) + { + if(EventMouseHover!=null) + EventMouseHover(item,e); + } + void IOwnerItemEvents.InvokeMouseLeave(BaseItem item,EventArgs e) + { + if(EventMouseLeave!=null) + EventMouseLeave(item,e); + } + void IOwnerItemEvents.InvokeMouseDown(BaseItem item, System.Windows.Forms.MouseEventArgs e) + { + if (EventMouseDown!= null) + EventMouseDown(item, e); + //if(this.MouseDown!=null) + // this.MouseDown(item,e); + if(item.ClickAutoRepeat && e.Button==MouseButtons.Left) + { + m_ClickRepeatItem=item; + if(m_ClickTimer==null) + m_ClickTimer=new Timer(); + m_ClickTimer.Interval=item.ClickRepeatInterval; + m_ClickTimer.Tick+=new EventHandler(this.ClickTimerTick); + m_ClickTimer.Start(); + } + } + void IOwnerItemEvents.InvokeMouseUp(BaseItem item, System.Windows.Forms.MouseEventArgs e) + { + if(EventMouseUp!=null) + EventMouseUp(item, e); + + if(m_ClickTimer!=null && m_ClickTimer.Enabled) + { + m_ClickTimer.Stop(); + m_ClickTimer.Enabled=false; + } + } + private void ClickTimerTick(object sender, EventArgs e) + { + if(m_ClickRepeatItem!=null) + m_ClickRepeatItem.RaiseClick(); + else + m_ClickTimer.Stop(); + } + void IOwnerItemEvents.InvokeMouseMove(BaseItem item, System.Windows.Forms.MouseEventArgs e) + { + if(EventMouseMove!=null) + EventMouseMove(item,e); + } + void IOwnerItemEvents.InvokeItemDoubleClick(BaseItem objItem, MouseEventArgs e) + { + OnItemDoubleClick(objItem, e); + } + /// + /// Invokes ItemDoubleClick event. + /// + /// Reference to item double-clicked + /// Event arguments + protected virtual void OnItemDoubleClick(BaseItem objItem, MouseEventArgs e) + { + MouseEventHandler handler = ItemDoubleClick; + if (handler != null) + handler(objItem, e); + } + void IOwnerItemEvents.InvokeItemClick(BaseItem objItem) + { + if(ItemClick!=null) + ItemClick(objItem,new EventArgs()); + } + void IOwnerItemEvents.InvokeGotFocus(BaseItem item,EventArgs e) + { + if(EventGotFocus!=null) + EventGotFocus(item,e); + } + void IOwnerItemEvents.InvokeLostFocus(BaseItem item,EventArgs e) + { + if(EventLostFocus!=null) + EventLostFocus(item,e); + } + void IOwnerItemEvents.InvokeExpandedChange(BaseItem item,EventArgs e) + { + if(ExpandedChange!=null) + ExpandedChange(item,e); + } + void IOwnerItemEvents.InvokeItemTextChanged(BaseItem item, EventArgs e) + { + if(ItemTextChanged!=null) + ItemTextChanged(item,e); + } + + void IOwnerItemEvents.InvokeContainerControlDeserialize(BaseItem item,ControlContainerSerializationEventArgs e) + { + if(ContainerControlDeserialize!=null) + ContainerControlDeserialize(item,e); + } + void IOwnerItemEvents.InvokeContainerControlSerialize(BaseItem item,ControlContainerSerializationEventArgs e) + { + if(ContainerControlSerialize!=null) + ContainerControlSerialize(item,e); + } + void IOwnerItemEvents.InvokeContainerLoadControl(BaseItem item,EventArgs e) + { + if(ContainerLoadControl!=null) + ContainerLoadControl(item,e); + } + + void IOwnerItemEvents.InvokeOptionGroupChanging(BaseItem item, OptionGroupChangingEventArgs e) + { + if(OptionGroupChanging!=null) + OptionGroupChanging(item,e); + } + + void IOwnerItemEvents.InvokeToolTipShowing(object item, EventArgs e) + { + if(ToolTipShowing!=null) + ToolTipShowing(item,e); + } + #endregion + + #region IMessageHandlerClient Implementation + + bool IMessageHandlerClient.IsModal + { + get + { + Form form=this.FindForm(); + if(form!=null) + return form.Modal; + return false; + } + } + bool IMessageHandlerClient.OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + bool IMessageHandlerClient.OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + int wParamInt = WinApi.ToInt(wParam); + if (m_RegisteredPopups.Count > 0) + { + if (((BaseItem)m_RegisteredPopups[m_RegisteredPopups.Count - 1]).Parent == null) + { + PopupItem objItem = (PopupItem)m_RegisteredPopups[m_RegisteredPopups.Count - 1]; + + Control ctrl = objItem.PopupControl as Control; + Control ctrl2 = Control.FromChildHandle(hWnd); + + if (ctrl2 != null) + { + while (ctrl2.Parent != null) + ctrl2 = ctrl2.Parent; + } + + bool bIsOnHandle = false; + if (ctrl2 != null && objItem != null) + bIsOnHandle = objItem.IsAnyOnHandle(ctrl2.Handle); + + bool bNoEat = ctrl != null && ctrl2 != null && ctrl.Handle == ctrl2.Handle || bIsOnHandle; + + if (!bIsOnHandle) + { + Keys key = (Keys)NativeFunctions.MapVirtualKey((uint)wParam, 2); + if (key == Keys.None) + key = (Keys)wParamInt; + objItem.InternalKeyDown(new KeyEventArgs(key)); + } + + // Don't eat the message if the pop-up window has focus + if (bNoEat) + return false; + return true; + } + } + + if (!this.IsParentFormActive) + return false; + + if (wParamInt>= 0x70 || System.Windows.Forms.Control.ModifierKeys != Keys.None || (WinApi.ToInt(lParam) & 0x1000000000) != 0 || wParamInt== 0x2E || wParamInt== 0x2D) // 2E=VK_DELETE, 2D=VK_INSERT + { + int i = (int)System.Windows.Forms.Control.ModifierKeys | wParamInt; + return ProcessShortcut((eShortcut)i); + } + return false; + } + private bool ProcessShortcut(eShortcut key) + { + bool eat=BarFunctions.ProcessItemsShortcuts(key,m_ShortcutTable); + return !m_DispatchShortcuts && eat; + +// if(m_ShortcutTable.Contains(key)) +// { +// ShortcutTableEntry objEntry=(ShortcutTableEntry)m_ShortcutTable[key]; +// // Must convert to independable array, since if this is for example +// // close command first Click will destroy the collection we are +// // iterating through and exception will be raised. +// BaseItem[] arr=new BaseItem[objEntry.Items.Values.Count]; +// objEntry.Items.Values.CopyTo(arr,0); +// Hashtable hnames=new Hashtable(arr.Length); +// +// bool eat=false; +// +// foreach(BaseItem objItem in arr) +// { +// if(objItem.CanRaiseClick && (objItem.Name=="" || !hnames.Contains(objItem.Name))) +// { +// eat=true; +// objItem.RaiseClick(); +// if(objItem.Name!="") +// hnames.Add(objItem.Name,""); +// } +// } +// return !m_DispatchShortcuts && eat; // True will eat the key, false will pass it through +// } +// return false; + } + protected bool IsParentFormActive + { + get + { + // Process only if parent form is active + Form form=this.FindForm(); + if(form==null) + return false; + if(form.IsMdiChild) + { + if(form.MdiParent==null) + return false; + if(form.MdiParent.ActiveMdiChild!=form) + return false; + } + else if(form!=Form.ActiveForm) + return false; + return true; + } + } + bool IMessageHandlerClient.OnMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + if(ApplicationMouseDown!=null) + ApplicationMouseDown(this,new HandlerMessageEventArgs(hWnd,wParam,lParam)); + + if(m_RegisteredPopups.Count==0) + return false; + + for(int i=m_RegisteredPopups.Count-1;i>=0;i--) + { + PopupItem objPopup=m_RegisteredPopups[i] as PopupItem; + bool bChildHandle=objPopup.IsAnyOnHandle(hWnd); + + if(!bChildHandle) + { + System.Windows.Forms.Control cTmp = System.Windows.Forms.Control.FromChildHandle(hWnd); + if (cTmp != null) + { + if (cTmp is MenuPanel) + { + bChildHandle = true; + } + else + { + while (cTmp.Parent != null) + { + cTmp = cTmp.Parent; + if (cTmp.GetType().FullName.IndexOf("DropDownHolder") >= 0 || cTmp is MenuPanel || cTmp is PopupContainerControl) + { + bChildHandle = true; + break; + } + } + } + if (!bChildHandle) + bChildHandle = objPopup.IsAnyOnHandle(cTmp.Handle); + } + else + { + string s = NativeFunctions.GetClassName(hWnd); + s = s.ToLower(); + if (s.IndexOf("combolbox") >= 0) + bChildHandle = true; + } + } + + if (!bChildHandle) + { + Control popupContainer = objPopup.PopupControl; + if (popupContainer != null) + while (popupContainer.Parent != null) popupContainer = popupContainer.Parent; + if (popupContainer != null && popupContainer.Bounds.Contains(Control.MousePosition)) + bChildHandle = true; + } + + if(bChildHandle) + break; + + if(objPopup.Displayed) + { + // Do not close if mouse is inside the popup parent button + Point p=this.PointToClient(Control.MousePosition); + if(objPopup.DisplayRectangle.Contains(p)) + break; + } + + objPopup.ClosePopup(); + + if(m_RegisteredPopups.Count==0) + break; + } + return false; + } + bool IMessageHandlerClient.OnMouseMove(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + if(m_RegisteredPopups.Count>0) + { + foreach(BaseItem item in m_RegisteredPopups) + { + if(item.Parent==null) + { + Control ctrl=((PopupItem)item).PopupControl; + if(ctrl!=null && ctrl.Handle!=hWnd && !item.IsAnyOnHandle(hWnd) && !(ctrl.Parent!=null && ctrl.Parent.Handle!=hWnd)) + return true; + } + } + } + return false; + } + bool IMessageHandlerClient.OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + if (!this.GetDesignMode()) + { + // Check Shortcuts + int wParamInt = WinApi.ToInt(wParam); + if (System.Windows.Forms.Control.ModifierKeys != Keys.None || wParamInt>= (int)eShortcut.F1 && wParamInt<= (int)eShortcut.F12) + { + int i = (int)System.Windows.Forms.Control.ModifierKeys | wParamInt; + if (ProcessShortcut((eShortcut)i)) + return true; + } + } + return false; + } + bool IMessageHandlerClient.OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + private void MenuEventSupportHook() + { + if(m_MenuEventSupport) + return; + m_MenuEventSupport=true; + + Form parentForm=this.FindForm(); + if(parentForm==null) + { + m_MenuEventSupport=false; + return; + } + + parentForm.Resize+=new System.EventHandler(this.ParentResize); + parentForm.Deactivate+=new System.EventHandler(this.ParentDeactivate); + + DotNetBarManager.RegisterParentMsgHandler(this,parentForm); + } + + private void MenuEventSupportUnhook() + { + if(!m_MenuEventSupport) + return; + m_MenuEventSupport=false; + + Form parentForm=this.FindForm(); + if(parentForm==null) + return; + DotNetBarManager.UnRegisterParentMsgHandler(this, parentForm); + parentForm.Resize-=new System.EventHandler(this.ParentResize); + parentForm.Deactivate-=new System.EventHandler(this.ParentDeactivate); + } + private void ParentResize(object sender, System.EventArgs e) + { + Form parentForm=this.FindForm(); + if(parentForm!=null && parentForm.WindowState==FormWindowState.Minimized) + ((IOwner)this).OnApplicationDeactivate(); + } + private void ParentDeactivate(object sender, System.EventArgs e) + { + Form parentForm=this.FindForm(); + if(parentForm!=null && parentForm.WindowState==FormWindowState.Minimized) + ((IOwner)this).OnApplicationDeactivate(); + } + #endregion + + #region IThemeCache Implementation + protected override void WndProc(ref Message m) + { + if(m.Msg==NativeFunctions.WM_THEMECHANGED) + { + this.RefreshThemes(); + } + else if (m.Msg == NativeFunctions.WM_USER + 107) + { + if (m_DoDefaultActionItem != null) + { + m_DoDefaultActionItem.DoAccesibleDefaultAction(); + m_DoDefaultActionItem = null; + } + + } + base.WndProc(ref m); + } + protected void RefreshThemes() + { + if(m_ThemeWindow!=null) + { + m_ThemeWindow.Dispose(); + m_ThemeWindow=new ThemeWindow(this); + } + if(m_ThemeRebar!=null) + { + m_ThemeRebar.Dispose(); + m_ThemeRebar=new ThemeRebar(this); + } + if(m_ThemeToolbar!=null) + { + m_ThemeToolbar.Dispose(); + m_ThemeToolbar=new ThemeToolbar(this); + } + if(m_ThemeHeader!=null) + { + m_ThemeHeader.Dispose(); + m_ThemeHeader=new ThemeHeader(this); + } + if(m_ThemeScrollBar!=null) + { + m_ThemeScrollBar.Dispose(); + m_ThemeScrollBar=new ThemeScrollBar(this); + } + if(m_ThemeProgress!=null) + { + m_ThemeProgress.Dispose(); + m_ThemeProgress=new ThemeProgress(this); + } + if(m_ThemeExplorerBar!=null) + { + m_ThemeExplorerBar.Dispose(); + m_ThemeExplorerBar=new ThemeExplorerBar(this); + } + if (m_ThemeButton != null) + { + m_ThemeButton.Dispose(); + m_ThemeButton = new ThemeButton(this); + } + } + private void DisposeThemes() + { + if(m_ThemeWindow!=null) + { + m_ThemeWindow.Dispose(); + m_ThemeWindow=null; + } + if(m_ThemeRebar!=null) + { + m_ThemeRebar.Dispose(); + m_ThemeRebar=null; + } + if(m_ThemeToolbar!=null) + { + m_ThemeToolbar.Dispose(); + m_ThemeToolbar=null; + } + if(m_ThemeHeader!=null) + { + m_ThemeHeader.Dispose(); + m_ThemeHeader=null; + } + if(m_ThemeScrollBar!=null) + { + m_ThemeScrollBar.Dispose(); + m_ThemeScrollBar=null; + } + if (m_ThemeProgress != null) + { + m_ThemeProgress.Dispose(); + m_ThemeProgress = null; + } + if (m_ThemeExplorerBar != null) + { + m_ThemeExplorerBar.Dispose(); + m_ThemeExplorerBar = null; + } + if (m_ThemeButton != null) + { + m_ThemeButton.Dispose(); + m_ThemeButton = null; + } + } + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + + if(!m_FilterInstalled && !this.DesignMode) + { + MessageHandler.RegisterMessageClient(this); + m_FilterInstalled=true; + } + } + protected override void OnHandleDestroyed(EventArgs e) + { + DisposeThemes(); + MenuEventSupportUnhook(); + base.OnHandleDestroyed(e); + + if(m_FilterInstalled) + { + MessageHandler.UnregisterMessageClient(this); + m_FilterInstalled=false; + } + } + DevComponents.DotNetBar.ThemeWindow IThemeCache.ThemeWindow + { + get + { + if(m_ThemeWindow==null) + m_ThemeWindow=new ThemeWindow(this); + return m_ThemeWindow; + } + } + DevComponents.DotNetBar.ThemeRebar IThemeCache.ThemeRebar + { + get + { + if(m_ThemeRebar==null) + m_ThemeRebar=new ThemeRebar(this); + return m_ThemeRebar; + } + } + DevComponents.DotNetBar.ThemeToolbar IThemeCache.ThemeToolbar + { + get + { + if(m_ThemeToolbar==null) + m_ThemeToolbar=new ThemeToolbar(this); + return m_ThemeToolbar; + } + } + DevComponents.DotNetBar.ThemeHeader IThemeCache.ThemeHeader + { + get + { + if(m_ThemeHeader==null) + m_ThemeHeader=new ThemeHeader(this); + return m_ThemeHeader; + } + } + DevComponents.DotNetBar.ThemeScrollBar IThemeCache.ThemeScrollBar + { + get + { + if(m_ThemeScrollBar==null) + m_ThemeScrollBar=new ThemeScrollBar(this); + return m_ThemeScrollBar; + } + } + DevComponents.DotNetBar.ThemeExplorerBar IThemeCache.ThemeExplorerBar + { + get + { + if(m_ThemeExplorerBar==null) + m_ThemeExplorerBar=new ThemeExplorerBar(this); + return m_ThemeExplorerBar; + } + } + DevComponents.DotNetBar.ThemeProgress IThemeCache.ThemeProgress + { + get + { + if(m_ThemeProgress==null) + m_ThemeProgress=new ThemeProgress(this); + return m_ThemeProgress; + } + } + DevComponents.DotNetBar.ThemeButton IThemeCache.ThemeButton + { + get + { + if (m_ThemeButton == null) + m_ThemeButton = new ThemeButton(this); + return m_ThemeButton; + } + } + #endregion + + #region Mouse & Keyboard Support + protected override void OnClick(EventArgs e) + { + m_BaseItemContainer.InternalClick(Control.MouseButtons,Control.MousePosition); + base.OnClick(e); + } + + protected override void OnDoubleClick(EventArgs e) + { + m_BaseItemContainer.InternalDoubleClick(Control.MouseButtons,Control.MousePosition); + base.OnDoubleClick(e); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + ExKeyDown(e); + base.OnKeyDown(e); + } + + internal void ExKeyDown(KeyEventArgs e) + { + m_BaseItemContainer.InternalKeyDown(e); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + m_BaseItemContainer.InternalMouseDown(e); + base.OnMouseDown(e); + } + + protected override void OnMouseHover(EventArgs e) + { + base.OnMouseHover(e); + m_BaseItemContainer.InternalMouseHover(); + } + + protected override void OnMouseLeave(EventArgs e) + { + // If we had hot sub item pass the mouse leave message to it... + if(this.Cursor!=System.Windows.Forms.Cursors.Arrow) + this.Cursor=System.Windows.Forms.Cursors.Arrow; + m_BaseItemContainer.InternalMouseLeave(); + base.OnMouseLeave(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + if(m_DragDropSupport && !m_UseNativeDragDrop) + MouseDragDrop(e.X,e.Y,null); + + m_BaseItemContainer.InternalMouseUp(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + if(m_DragDropSupport && m_DragInProgress) + { + if(!m_UseNativeDragDrop) + MouseDragOver(e.X,e.Y,null); + } + else + m_BaseItemContainer.InternalMouseMove(e); + } + + protected override void OnDragOver(DragEventArgs e) + { + if(m_DragDropSupport && (m_DragInProgress || m_ExternalDragInProgress)) + { + Point p=this.PointToClient(new Point(e.X,e.Y)); + MouseDragOver(p.X,p.Y,e); + m_DragLeft=false; + } + base.OnDragOver(e); + } + + protected override void OnDragLeave(EventArgs e) + { + if(m_DragDropSupport) + { + if(m_DragInProgress || m_ExternalDragInProgress) + MouseDragOver(-1,-1,null); + m_DragLeft=true; + m_ExternalDragInProgress=false; + } + base.OnDragLeave(e); + } + + protected override void OnDragEnter(DragEventArgs e) + { + base.OnDragEnter(e); + if(m_DragDropSupport) + { + if(m_DragInProgress || !m_AllowExternalDrop) + return; + if(e.Data.GetData(typeof(ButtonItem))==null) + { + if(e.Effect!=DragDropEffects.None) + m_ExternalDragInProgress=true; + return; + } + if((e.AllowedEffect & DragDropEffects.Move)==DragDropEffects.Move) + e.Effect=DragDropEffects.Move; + else if((e.AllowedEffect & DragDropEffects.Copy)==DragDropEffects.Copy) + e.Effect=DragDropEffects.Move; + else if((e.AllowedEffect & DragDropEffects.Link)==DragDropEffects.Link) + e.Effect=DragDropEffects.Move; + else + return; + m_ExternalDragInProgress=true; + } + } + + protected override void OnDragDrop(DragEventArgs e) + { + if(m_DragDropSupport) + { + if(m_DragInProgress) + { + Point p=this.PointToClient(new Point(e.X,e.Y)); + MouseDragDrop(p.X,p.Y,null); + } + else if(m_ExternalDragInProgress) + { + Point p=this.PointToClient(new Point(e.X,e.Y)); + MouseDragDrop(p.X,p.Y,e); + } + } + base.OnDragDrop(e); + } + + protected override void OnQueryContinueDrag(QueryContinueDragEventArgs e) + { + if(m_DragDropSupport) + { + if(m_DragInProgress) + { + if(m_DragLeft && e.Action==DragAction.Drop || e.Action==DragAction.Cancel) + MouseDragDrop(-1,-1,null); + } + } + base.OnQueryContinueDrag(e); + } + + private void MouseDragOver(int x, int y, DragEventArgs dragArgs) + { + if(!m_DragInProgress && !m_ExternalDragInProgress) + return; + BaseItem dragItem=m_DragItem; + + if(m_ExternalDragInProgress && dragArgs!=null) + dragItem=dragArgs.Data.GetData(typeof(ButtonItem)) as BaseItem; + + if(m_DesignTimeProvider!=null) + { + m_DesignTimeProvider.DrawReversibleMarker(m_InsertPosition,m_InsertBefore); + m_DesignTimeProvider=null; + } + + if(m_ExternalDragInProgress && dragItem==null) + return; + + Point pScreen=this.PointToScreen(new Point(x,y)); + foreach(SideBarPanelItem panel in m_BaseItemContainer.SubItems) + { + if(!panel.Visible) + continue; + InsertPosition pos=((IDesignTimeProvider)panel).GetInsertPosition(pScreen, dragItem); + + if(pos!=null) + { + if(pos.TargetProvider==null) + { + // Cursor is over drag item + if(!m_UseNativeDragDrop) + { + if(m_NACursor!=null) + System.Windows.Forms.Cursor.Current=m_NACursor; + else + System.Windows.Forms.Cursor.Current=System.Windows.Forms.Cursors.No; + } + break; + } + pos.TargetProvider.DrawReversibleMarker(pos.Position,pos.Before); + m_InsertPosition=pos.Position; + m_InsertBefore=pos.Before; + m_DesignTimeProvider=pos.TargetProvider; + if(!m_UseNativeDragDrop) + { + if(m_MoveCursor!=null) + System.Windows.Forms.Cursor.Current=m_MoveCursor; + else + System.Windows.Forms.Cursor.Current=System.Windows.Forms.Cursors.Hand; + } + else if(dragArgs!=null) + dragArgs.Effect=DragDropEffects.Move; + break; + } + else + { + if(!m_UseNativeDragDrop) + { + if(m_NACursor!=null) + System.Windows.Forms.Cursor.Current=m_NACursor; + else + System.Windows.Forms.Cursor.Current=System.Windows.Forms.Cursors.No; + } + else if(dragArgs!=null) + dragArgs.Effect=DragDropEffects.None; + } + } + } + #endregion + + #region IOwnerLocalize Implementation + void IOwnerLocalize.InvokeLocalizeString(LocalizeEventArgs e) + { + if(LocalizeString!=null) + LocalizeString(this,e); + } + #endregion + + /// + /// Gets or sets the item default accessibility action will be performed on. + /// + BaseItem IAccessibilitySupport.DoDefaultActionItem + { + get { return m_DoDefaultActionItem; } + set { m_DoDefaultActionItem = value; } + } + + protected void SetBaseItemContainer(BaseItem item) + { + m_BaseItemContainer=item; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public BaseItem GetBaseItemContainer() + { + return m_BaseItemContainer; + } + +#if FRAMEWORK20 + protected override void OnBindingContextChanged(EventArgs e) + { + base.OnBindingContextChanged(e); + if (m_BaseItemContainer != null) + m_BaseItemContainer.UpdateBindings(); + } +#endif + + protected virtual string EmptyContainerDesignTimeHint + { + get {return m_EmptyContainerDesignTimeHint;} + set {m_EmptyContainerDesignTimeHint=value;} + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(m_ClickTimer!=null) + { + m_ClickTimer.Stop(); + m_ClickTimer.Dispose(); + m_ClickTimer=null; + } + } + base.Dispose( disposing ); + } + + /// + /// Specifies the background style of the Explorer Bar. + /// + [Browsable(true),DevCoBrowsable(true),Category("Style"),Description("Gets or sets bar background style."),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ItemStyle BackgroundStyle + { + get {return m_BackgroundStyle;} + } + + public void ResetBackgroundStyle() + { + m_BackgroundStyle.VisualPropertyChanged-=new EventHandler(this.VisualPropertyChanged); + m_BackgroundStyle=new ItemStyle(); + m_BackgroundStyle.VisualPropertyChanged+=new EventHandler(this.VisualPropertyChanged); + } + + private void VisualPropertyChanged(object sender, EventArgs e) + { + if(m_BackgroundStyle!=null) + m_BackgroundStyle.ApplyColorScheme(this.ColorScheme); + if(this.GetDesignMode()) + this.Refresh(); + } + + protected virtual void MouseDragDrop(int x, int y, DragEventArgs dragArgs) + { + if(!m_DragInProgress && !m_ExternalDragInProgress) + return; + BaseItem dragItem=m_DragItem; + if(m_ExternalDragInProgress) + dragItem=dragArgs.Data.GetData(typeof(ButtonItem)) as BaseItem; + + if(dragItem!=null) + dragItem.InternalMouseLeave(); + + if(m_DesignTimeProvider!=null) + { + if(x==-1 && y==-1) + { + // Cancel state + m_DesignTimeProvider.DrawReversibleMarker(m_InsertPosition, m_InsertBefore); + } + else + { + m_DesignTimeProvider.DrawReversibleMarker(m_InsertPosition, m_InsertBefore); + if(dragItem!=null) + { + BaseItem objParent=dragItem.Parent; + if(objParent!=null) + { + if(objParent==(BaseItem)m_DesignTimeProvider && m_InsertPosition>0) + { + if(objParent.SubItems.IndexOf(dragItem) + /// Indicates whether shortucts handled by items are dispatched to the next handler or control. + /// + [System.ComponentModel.Browsable(true),DefaultValue(false),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates whether shortucts handled by items are dispatched to the next handler or control.")] + public bool DispatchShortcuts + { + get {return m_DispatchShortcuts;} + set {m_DispatchShortcuts=value;} + } + + /// + /// Gets or sets Bar Color Scheme. + /// + [Browsable(false),DevCoBrowsable(false),Category("Appearance"),Description("Gets or sets Bar Color Scheme."),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DevComponents.DotNetBar.ColorScheme ColorScheme + { + get {return m_ColorScheme;} + set + { + if(value==null) + throw new ArgumentException("NULL is not a valid value for this property."); + m_ColorScheme=value; + if(this.Visible) + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeColorScheme() + { + return m_ColorScheme.SchemeChanged; + } + + protected bool IsThemed + { + get + { + if (m_ThemeAware && m_BaseItemContainer.EffectiveStyle != eDotNetBarStyle.Office2000 && BarFunctions.ThemedOS && Themes.ThemesActive) + return true; + return false; + } + } + + private bool m_DisabledImagesGrayScale=true; + /// + /// Gets or sets whether gray-scale algorithm is used to create automatic gray-scale images. Default is true. + /// + [System.ComponentModel.Browsable(true),DefaultValue(true),System.ComponentModel.Category("Appearance"),Description("Gets or sets whether gray-scale algorithm is used to create automatic gray-scale images.")] + public bool DisabledImagesGrayScale + { + get + { + return m_DisabledImagesGrayScale; + } + set + { + m_DisabledImagesGrayScale=value; + } + } + + /// + /// Specifies whether SideBar is drawn using Themes when running on OS that supports themes like Windows XP. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(false),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Specifies whether SideBar is drawn using Themes when running on OS that supports themes like Windows XP.")] + public virtual bool ThemeAware + { + get + { + return m_ThemeAware; + } + set + { + m_ThemeAware=value; + m_BaseItemContainer.ThemeAware=value; + if(this.GetDesignMode()) + this.Refresh(); + } + } + + /// + /// Applies design-time defaults to control. + /// + public virtual void SetDesignTimeDefaults() + { + } + + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is false. + /// + [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public bool AntiAlias + { + get { return m_AntiAlias; } + set + { + if (m_AntiAlias != value) + { + m_AntiAlias = value; + this.Invalidate(); + } + } + } + + /// + /// Creates the Graphics object for the control. + /// + /// The Graphics object for the control. + public new Graphics CreateGraphics() + { + Graphics g = base.CreateGraphics(); + if (m_AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; +#if FRAMEWORK20 + if (!SystemInformation.IsFontSmoothingEnabled) +#endif + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + return g; + } + + #region Painting Support + private Rendering.BaseRenderer m_DefaultRenderer = null; + private Rendering.BaseRenderer m_Renderer = null; + private eRenderMode m_RenderMode = eRenderMode.Global; + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public virtual Rendering.BaseRenderer GetRenderer() + { + if (m_RenderMode == eRenderMode.Global && Rendering.GlobalManager.Renderer != null) + return Rendering.GlobalManager.Renderer; + else if (m_RenderMode == eRenderMode.Custom && m_Renderer != null) + return m_Renderer; + + if (m_DefaultRenderer == null) + m_DefaultRenderer = new Rendering.Office2007Renderer(); + + return m_Renderer; + } + + /// + /// Gets or sets the redering mode used by control. Default value is eRenderMode.Global which means that static GlobalManager.Renderer is used. If set to Custom then Renderer property must + /// also be set to the custom renderer that will be used. + /// + [Browsable(false), DefaultValue(eRenderMode.Global)] + public eRenderMode RenderMode + { + get { return m_RenderMode; } + set + { + if (m_RenderMode != value) + { + m_RenderMode = value; + this.Invalidate(true); + } + } + } + + /// + /// Gets or sets the custom renderer used by the items on this control. RenderMode property must also be set to eRenderMode.Custom in order renderer + /// specified here to be used. + /// + [Browsable(false), DefaultValue(null)] + public DevComponents.DotNetBar.Rendering.BaseRenderer Renderer + { + get + { + return m_Renderer; + } + set { m_Renderer = value; } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public ColorScheme GetColorScheme() + { + if (BarFunctions.IsOffice2007Style(m_BaseItemContainer.EffectiveStyle)) + { + Office2007Renderer r = this.GetRenderer() as Office2007Renderer; + if (r != null && r.ColorTable.LegacyColors != null) + return r.ColorTable.LegacyColors; + } + return m_ColorScheme; + } + + protected override void OnPaint(PaintEventArgs e) + { + if(m_BaseItemContainer==null || this.IsDisposed) + return; + + ItemPaintArgs pa=new ItemPaintArgs(this as IOwner,this,e.Graphics,GetColorScheme()); + pa.Renderer = this.GetRenderer(); + if (m_AntiAlias) + { + pa.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + pa.Graphics.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + PaintControlBackground(pa); + + pa.Graphics.SetClip(this.GetItemContainerRectangle()); + PaintItemContainer(pa); + pa.Graphics.ResetClip(); + + if(m_BaseItemContainer.SubItems.Count==0 && this.GetDesignMode()) + PaintDesignTimeEmptyHint(pa); + + PaintContentOnTop(pa); + } + /// + /// Called after control has painted its content and allows painting on top of the controls content. + /// + /// Paint arguments. + protected virtual void PaintContentOnTop(ItemPaintArgs pa) { } + protected virtual void PaintControlBackground(ItemPaintArgs pa) + { + if (m_BackgroundStyle != null) + { + m_BackgroundStyle.ApplyColorScheme(pa.Colors); + m_BackgroundStyle.Paint(pa.Graphics, this.ClientRectangle); + } + } + + protected virtual void PaintItemContainer(ItemPaintArgs pa) + { + m_BaseItemContainer.Paint(pa); + } + + protected virtual void PaintDesignTimeEmptyHint(ItemPaintArgs pa) + { + string info=m_EmptyContainerDesignTimeHint; + Rectangle rText=this.GetItemContainerRectangle(); + rText.Inflate(-2,-2); + if(rText.Width<0 || rText.Height<0) + return; + eTextFormat format = eTextFormat.Default | eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter | eTextFormat.WordBreak; + TextDrawing.DrawString(pa.Graphics,info,this.Font,SystemColors.ControlDark,rText,format); + } + #endregion + + #region Layout Support + protected virtual Rectangle GetItemContainerRectangle() + { + if(m_BackgroundStyle==null) + return this.ClientRectangle; + + Rectangle r=this.ClientRectangle; + + if(m_BackgroundStyle.Border==eBorderType.SingleLine) + { + if(m_BackgroundStyle.BorderSide==eBorderSide.All) + r.Inflate(-1,-1); + else + { + if((m_BackgroundStyle.BorderSide & eBorderSide.Left)!=0) + r.X++; + if((m_BackgroundStyle.BorderSide & eBorderSide.Right)!=0) + r.Width--; + if((m_BackgroundStyle.BorderSide & eBorderSide.Top)!=0) + r.Y++; + if((m_BackgroundStyle.BorderSide & eBorderSide.Bottom)!=0) + r.Height--; + } + } + else if(m_BackgroundStyle.Border!=eBorderType.None) + { + if(m_BackgroundStyle.BorderSide==eBorderSide.All) + r.Inflate(-2,-2); + else + { + if((m_BackgroundStyle.BorderSide & eBorderSide.Left)!=0) + r.X+=2; + if((m_BackgroundStyle.BorderSide & eBorderSide.Right)!=0) + r.Width-=2; + if((m_BackgroundStyle.BorderSide & eBorderSide.Top)!=0) + r.Y+=2; + if((m_BackgroundStyle.BorderSide & eBorderSide.Bottom)!=0) + r.Height-=2; + } + } + + return r; + } + + protected virtual void RecalcSize() + { + if(m_BaseItemContainer.IsRecalculatingSize) + return; + Rectangle r=this.GetItemContainerRectangle(); + m_BaseItemContainer.IsRightToLeft = (this.RightToLeft == RightToLeft.Yes); + m_BaseItemContainer.LeftInternal=r.X; + m_BaseItemContainer.TopInternal=r.Y; + m_BaseItemContainer.WidthInternal =r.Width; + m_BaseItemContainer.HeightInternal=r.Height; + + m_BaseItemContainer.RecalcSize(); + + OnItemLayoutUpdated(EventArgs.Empty); + } + + /// + /// Occurs after internal item layout has been updated and items have valid bounds assigned. + /// + public event EventHandler ItemLayoutUpdated; + /// + /// Raises ItemLayoutUpdated event. + /// + /// Provides event arguments. + protected virtual void OnItemLayoutUpdated(EventArgs e) + { + EventHandler handler = ItemLayoutUpdated; + if (handler != null) + handler(this, e); + } + + /// + /// Applies any layout changes and repaint the control. + /// + public virtual void RecalcLayout() + { + if(m_BaseItemContainer.IsRecalculatingSize) + return; + this.RecalcSize(); + this.Invalidate(); + } + #endregion + + #region IBarDesignerServices + IBarItemDesigner IBarDesignerServices.Designer + { + get {return m_BarDesigner;} + set {m_BarDesigner=value;} + } + #endregion + } + + #region HandlerMessageEventArgs + internal class HandlerMessageEventArgs : EventArgs + { + public IntPtr hWnd = IntPtr.Zero; + public IntPtr wParam = IntPtr.Zero; + public IntPtr lParam = IntPtr.Zero; + + public HandlerMessageEventArgs(IntPtr hwnd, IntPtr wparam, IntPtr lparam) + { + this.hWnd = hwnd; + this.wParam = wparam; + this.lParam = lparam; + } + } + + internal delegate void HandlerMessageEventHandler(object sender, HandlerMessageEventArgs e); + #endregion + + + #region BarAccessibleObject + /// + /// Represents class for Accessibility support. + /// + public class BarBaseControlAccessibleObject : System.Windows.Forms.Control.ControlAccessibleObject + { + BarBaseControl m_Owner = null; + /// + /// Creates new instance of the object and initializes it with owner control. + /// + /// Reference to owner control. + public BarBaseControlAccessibleObject(BarBaseControl owner):base(owner) + { + m_Owner = owner; + } + + internal void GenerateEvent(BaseItem sender, System.Windows.Forms.AccessibleEvents e) + { + int iChild = m_Owner.GetBaseItemContainer().SubItems.IndexOf(sender); + if(iChild>=0) + { + if(m_Owner!=null && !m_Owner.IsDisposed) + m_Owner.InternalAccessibilityNotifyClients(e,iChild); + } + } + + ///// + ///// Gets or sets accessible name. + ///// + //public override string Name + //{ + // get + // { + // if(m_Owner!=null && !m_Owner.IsDisposed) + // return m_Owner.AccessibleName; + // return ""; + // } + // set + // { + // if(m_Owner!=null && !m_Owner.IsDisposed) + // m_Owner.AccessibleName = value; + // } + //} + + ///// + ///// Gets accessible description. + ///// + //public override string Description + //{ + // get + // { + // if(m_Owner!=null && !m_Owner.IsDisposed) + // return m_Owner.AccessibleDescription; + // return ""; + // } + //} + + /// + /// Gets accessible role. + /// + public override AccessibleRole Role + { + get + { + if(m_Owner!=null && !m_Owner.IsDisposed) + return m_Owner.AccessibleRole; + return System.Windows.Forms.AccessibleRole.None; + } + } + + /// + /// Gets parent accessibility object. + /// + public override AccessibleObject Parent + { + get + { + if(m_Owner!=null && !m_Owner.IsDisposed) + return m_Owner.Parent.AccessibilityObject; + return null; + } + } + + /// + /// Returns bounds of the control. + /// + public override Rectangle Bounds + { + get + { + if(m_Owner!=null && !m_Owner.IsDisposed && m_Owner.Parent!=null) + return this.m_Owner.Parent.RectangleToScreen(m_Owner.Bounds); + return Rectangle.Empty; + } + } + + /// + /// Returns number of child objects. + /// + /// Total number of child objects. + public override int GetChildCount() + { + if(m_Owner!=null && !m_Owner.IsDisposed && m_Owner.GetBaseItemContainer()!=null) + return m_Owner.GetBaseItemContainer().SubItems.Count; + return 0; + } + + /// + /// Returns reference to child object given the index. + /// + /// 0 based index of child object. + /// Reference to child object. + public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) + { + if(m_Owner!=null && !m_Owner.IsDisposed && m_Owner.GetBaseItemContainer()!=null) + return m_Owner.GetBaseItemContainer().SubItems[iIndex].AccessibleObject; + return null; + } + + /// + /// Returns current accessible state. + /// + public override AccessibleStates State + { + get + { + AccessibleStates state; + if(m_Owner==null || m_Owner.IsDisposed) + return AccessibleStates.None; + + state=AccessibleStates.None; + return state; + } + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/BarBaseControlDesigner.cs b/PROMS/DotNetBar Source Code/BarBaseControlDesigner.cs new file mode 100644 index 00000000..6165cda1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BarBaseControlDesigner.cs @@ -0,0 +1,1317 @@ +using System; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using System.Collections; +using System.Drawing; +using System.ComponentModel.Design; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for BarBaseControlDesigner. + /// + public class BarBaseControlDesigner:System.Windows.Forms.Design.ParentControlDesigner,IDesignerServices + { + #region Private Variables + const string TEMP_NAME="tempDragDropItem"; + private bool m_EnableItemDragDrop=false; + private bool m_AcceptExternalControls=true; + private Point m_MouseDownPoint=Point.Empty; + private BaseItem m_DragItem=null; + private bool m_DragInProgress=false; + private IDesignTimeProvider m_DesignTimeProvider=null; + private int m_InsertPosition; + private bool m_InsertBefore; + private bool m_Capture=false; + private System.Windows.Forms.Control m_DesignerHost=null; + private Timer m_TimerAdded=null; + private Timer m_TimerDragDrop=null; + private bool m_NewControlAdded=false; + private bool m_SuspendInternalCursor=false; + private bool m_DragLeave=false; + private bool m_ControlRemoved=false; + private DateTime m_JustAdded=DateTime.MinValue; + private bool m_MouseDownSelectionPerformed=false; + #endregion + + #region Designer Implementation + public BarBaseControlDesigner() + { + + } + + 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); + cc.ComponentRemoved+=new ComponentEventHandler(this.OnComponentRemoved); + } + + IDesignerEventService ds=GetService(typeof(IDesignerEventService)) as IDesignerEventService; + if(ds!=null) + { + ds.ActiveDesignerChanged+=new ActiveDesignerEventHandler(this.OnActiveDesignerChanged); + ds.SelectionChanged+=new EventHandler(DesignerSelectionChanged); + } + + if(this.Control is IBarDesignerServices) + ((IBarDesignerServices)this.Control).Designer=this; + + if(component is System.Windows.Forms.Control) + { + ((Control)component).ControlAdded+=new ControlEventHandler(this.ComponentAdded); + ((Control)component).ControlRemoved+=new ControlEventHandler(this.ComponentRemoved); + } + //this.EnableDragDrop(false); + } + + protected override void Dispose(bool disposing) + { + // Unhook events + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + if(cc!=null) + { + cc.ComponentRemoving-=new ComponentEventHandler(this.OnComponentRemoving); + cc.ComponentRemoved-=new ComponentEventHandler(this.OnComponentRemoved); + } + + ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService)); + if(ss!=null) + ss.SelectionChanged-=new EventHandler(OnSelectionChanged); + + IDesignerEventService ds=GetService(typeof(IDesignerEventService)) as IDesignerEventService; + if(ds!=null) + { + ds.ActiveDesignerChanged-=new ActiveDesignerEventHandler(this.OnActiveDesignerChanged); + ds.SelectionChanged-=new EventHandler(DesignerSelectionChanged); + } + + if(this.Component is System.Windows.Forms.Control) + { + ((Control)this.Component).ControlAdded-=new ControlEventHandler(this.ComponentAdded); + ((Control)this.Component).ControlRemoved-=new ControlEventHandler(this.ComponentRemoved); + } + + base.Dispose(disposing); + } + + public override bool CanParent(Control control) + { + BaseItem item = GetControlItem(control); + if (item != null && item != m_DragItem && !m_NewControlAdded) + return false; + return base.CanParent(control); + } + + private void ComponentAdded(object sender, ControlEventArgs e) + { + if(!m_NewControlAdded || !m_EnableItemDragDrop || !m_AcceptExternalControls || this.IsDockableWindow) + { + 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; + } + + /// + /// Called after control has been added to container but not through drag & drop. Control added could also be + /// internal control by the bar container. + /// + /// Event arguments + /// true if acted upon this new control otherwise false. + protected virtual bool OnControlAdded(ControlEventArgs e) + { + return false; + } + + private void ComponentRemoved(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 && this.GetControlItem(e.Control)!=null) + { + ControlRemoved(e.Control); + } + } + } + + private void ControlRemoved(Control control) + { + if(control!=null) + { + BaseItem item=this.GetControlItem(control); + if(item!=null) + { + MouseDragDrop(-1,-1); + if(item.Parent!=null) + item.Parent.SubItems.Remove(item); + this.DestroyComponent(item); + 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 OnSelectionChanged(object sender, EventArgs e) + { + DesignTimeSelectionChanged(sender as ISelectionService); + } + + private void OnActiveDesignerChanged(object sender, ActiveDesignerEventArgs e) + { + this.ActiveDesignerChanged(e); + } + + /// + /// Support for popup menu closing. + /// + /// + protected virtual void ActiveDesignerChanged(ActiveDesignerEventArgs e) + { + if((this.GetItemContainerControl() as IOwner)!=null) + { + ((IOwner)this.GetItemContainerControl()).OnApplicationDeactivate(); // Closes all popups + } + } + + /// + /// Support for popup menu closing. + /// + protected virtual void DesignTimeSelectionChanged(ISelectionService ss) + { + if(ss==null) + return; + if(this.Control==null || this.Control.IsDisposed) + return; + + if(ss.PrimarySelection!=this.Control) + { + BaseItem container=this.GetItemContainer(); + if(container==null) + return; + if(ss.PrimarySelection is BaseItem) + { + BaseItem item=ss.PrimarySelection as BaseItem; + if(item.ContainerControl==this.GetItemContainerControl()) + return; + + if(this.GetAllAssociatedComponents().Contains(item)) + return; + + if((this.GetItemContainerControl() as IOwner)!=null) + ((IOwner)this.GetItemContainerControl()).SetFocusItem(null); + } + else + { + if((this.GetItemContainerControl() as IOwner)!=null) + { + ((IOwner)this.GetItemContainerControl()).SetFocusItem(null); + ((IOwner)this.GetItemContainerControl()).OnApplicationDeactivate(); // Closes all popups + } + } + } + else + { + if((this.GetItemContainerControl() as IOwner)!=null) + ((IOwner)this.GetItemContainerControl()).OnApplicationDeactivate(); // Closes all popups + } + } + + protected virtual BaseItem GetItemContainer() + { + BarBaseControl bar=this.Control as BarBaseControl; + if(bar!=null) + return bar.GetBaseItemContainer(); + return null; + } + + protected virtual System.Windows.Forms.Control GetItemContainerControl() + { + return this.Control; + } + + protected bool m_InternalRemoving=false; + private void OnComponentRemoving(object sender,ComponentEventArgs e) + { + if(e.Component==this.Component) + ThisComponentRemoving(sender,e); + else + OtherComponentRemoving(sender,e); + } + + private void OnComponentRemoved(object sender,ComponentEventArgs e) + { + ComponentRemoved(sender,e); + } + + protected virtual void ComponentRemoved(object sender, ComponentEventArgs e){} + + /// + /// Removes all subitems from container. + /// + protected virtual void ThisComponentRemoving(object sender, ComponentEventArgs e) + { + if(!m_InternalRemoving) + { + m_InternalRemoving=true; + try + { + // Unhook events + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + if(cc!=null) + cc.ComponentRemoving-=new ComponentEventHandler(this.OnComponentRemoving); + + BaseItem container=this.GetItemContainer(); + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + + if(dh==null || container==null) + return; + + foreach(BaseItem item in container.SubItems) + { + // Covers the undo case in designer + if(item.Parent==container) + { + DestroySubItems(item,dh); + dh.DestroyComponent(item); + } + } + } + finally + { + m_InternalRemoving=false; + } + } + } + + /// + /// Triggered when some other component on the form is removed. + /// + protected virtual void OtherComponentRemoving(object sender, ComponentEventArgs e) + { + if(e.Component is BaseItem) + { + BaseItem item=e.Component as BaseItem; + if(item.ContainerControl==GetItemContainerControl()) + { + if(item.Parent!=null && item.Parent.SubItems.Contains(item)) + item.Parent.SubItems.Remove(item); + if(item!=null) + DestroySubItems(item); + this.RecalcLayout(); + } + } + } + + protected virtual void DestroySubItems(BaseItem parent, IDesignerHost dh) + { + if(parent is ControlContainerItem) + { + if(((ControlContainerItem)parent).Control!=null) + { + Control c=((ControlContainerItem)parent).Control; + ((ControlContainerItem)parent).Control=null; + dh.DestroyComponent(c); + } + } + else if(parent is DockContainerItem) + { + if(((DockContainerItem)parent).Control!=null) + { + Control c=((DockContainerItem)parent).Control; + ((DockContainerItem)parent).Control=null; + dh.DestroyComponent(c); + } + } + + BaseItem[] subitems=new BaseItem[parent.SubItems.Count]; + parent.SubItems.CopyTo(subitems,0); + foreach(BaseItem item in subitems) + { + DestroySubItems(item,dh); + dh.DestroyComponent(item); + } + } + + protected virtual void DestroySubItems(BaseItem parent) + { + IDesignerHost dh=GetService(typeof(IDesignerHost)) as IDesignerHost; + if(dh!=null) + DestroySubItems(parent,dh); + } + + /// + /// Selection support for items on container. + /// + protected override void WndProc(ref Message m) + { + if(m_DesignerHost==null) + m_DesignerHost=System.Windows.Forms.Control.FromHandle(m.HWnd); + BaseItem container=this.GetItemContainer(); + System.Windows.Forms.Control ctrl=this.GetItemContainerControl(); + if(container==null || ctrl==null || ctrl.IsDisposed) + { + base.WndProc(ref m); + return; + } + + switch(m.Msg) + { + case NativeFunctions.WM_LBUTTONDOWN: + case NativeFunctions.WM_RBUTTONDOWN: + { + if(OnMouseDown(ref m)) + return; + break; + } + case NativeFunctions.WM_RBUTTONUP: + case NativeFunctions.WM_LBUTTONUP: + { + if(OnMouseUp(ref m)) + return; + + break; + } + case NativeFunctions.WM_MOUSEMOVE: + { + if(OnMouseMove(ref m)) + { + m.Result=IntPtr.Zero; + return; + } + break; + } + case NativeFunctions.WM_MOUSELEAVE: + { + if(OnMouseLeave(ref m)) + return; + break; + } + case NativeFunctions.WM_LBUTTONDBLCLK: + { + if(OnMouseDoubleClick(m)) + return; + break; + } + } + + base.WndProc(ref m); + } + + protected virtual bool OnMouseDown(ref Message m) + { + if(this.IsDockableWindow) + return false; + + System.Windows.Forms.Control ctrl=this.GetItemContainerControl(); + BaseItem container=this.GetItemContainer(); + + if(ctrl==null || (ctrl as IOwner)==null || container==null) + return false; + + if(m.Msg==NativeFunctions.WM_RBUTTONDOWN) + { + Point pos=ctrl.PointToClient(System.Windows.Forms.Control.MousePosition); + MouseEventArgs e=new MouseEventArgs(MouseButtons.Left,0,pos.X,pos.Y,0); + container.InternalMouseDown(e); + if(((IOwner)ctrl).GetFocusItem()!=null) + { + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(selection!=null) + { + ArrayList arr=new ArrayList(1); + arr.Add(((IOwner)ctrl).GetFocusItem()); +#if FRAMEWORK20 + selection.SetSelectedComponents(arr,SelectionTypes.Primary); +#else + selection.SetSelectedComponents(arr,SelectionTypes.MouseDown); +#endif + OnItemSelected(((IOwner)ctrl).GetFocusItem()); + this.OnContextMenu(System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y); + return true; + } + } + } + return false; + } + + protected virtual bool OnMouseUp(ref Message m) + { + bool bProcessed=false; + + if(m_Capture) + { + m_Capture=false; + System.Windows.Forms.Control c=System.Windows.Forms.Control.FromHandle(m.HWnd); + if(c!=null) + c.Capture=false; + } + + System.Windows.Forms.Control ctrl=this.GetItemContainerControl(); + BaseItem container=this.GetItemContainer(); + + if(ctrl==null || (ctrl as IOwner)==null || container==null) + return false; + + Point pos=ctrl.PointToClient(System.Windows.Forms.Control.MousePosition); + MouseEventArgs e=new MouseEventArgs(MouseButtons.Left,0,pos.X,pos.Y,0); + container.InternalMouseUp(e); + +// if(((IOwner)ctrl).GetFocusItem()==null && !m_MouseDownSelectionPerformed) +// { +// ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); +// if(selection!=null && selection.PrimarySelection!=this.Control && !(selection.PrimarySelection.GetType() == this.Control.GetType())) +// { +// ArrayList arr=new ArrayList(1); +// arr.Add(this.Control); +// selection.SetSelectedComponents(arr,SelectionTypes.Click); +// } +// } + if (m_MouseDownSelectionPerformed) + bProcessed = true; + m_MouseDownSelectionPerformed=false; + + if(m_DragItem!=null && m_DragItem is ControlContainerItem) + MouseDragDrop(pos.X,pos.Y); + + return bProcessed; + } + + protected virtual bool OnMouseMove(ref Message m) + { + return false; + } + + protected override void OnMouseDragBegin(int x, int y) + { + Control bar=this.GetItemContainerControl(); + System.Windows.Forms.Control ctrl=this.GetItemContainerControl(); + + BaseItem container=this.GetItemContainer(); + Point pos=ctrl.PointToClient(new Point(x,y)); + MouseEventArgs e=new MouseEventArgs(MouseButtons.Left,0,pos.X,pos.Y,0); + + BaseItem dragItem=null; + container.InternalMouseDown(e); + dragItem=((IOwner)ctrl).GetFocusItem(); + + if(dragItem!=null) + { + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(selection!=null) + { + ArrayList arr=new ArrayList(1); + arr.Add(dragItem); +#if FRAMEWORK20 + selection.SetSelectedComponents(arr, SelectionTypes.Primary); +#else + selection.SetSelectedComponents(arr,SelectionTypes.MouseDown); +#endif + OnItemSelected(((IOwner)ctrl).GetFocusItem()); + } + } + + if(bar==null || dragItem==null || this.IsDockableWindow || !m_EnableItemDragDrop || !CanDragItem(dragItem)) + { + if(dragItem==null) + base.OnMouseDragBegin(x,y); + else + this.Control.Capture = true; // Does same as base implementation + return; + } + + bar.Capture = true; + NativeFunctions.RECT rect = new NativeFunctions.RECT(0,0,0,0); + NativeFunctions.GetWindowRect(bar.Handle, ref rect); + Rectangle r=Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom); + Cursor.Clip=r; + StartItemDrag(dragItem); + + // Does same as base implementation + this.Control.Capture = true; + } + protected virtual bool CanDragItem(BaseItem item) + { + return true; + } + protected override void OnMouseDragMove(int x, int y) + { + if(m_DragInProgress) + { + Point p=this.Control.PointToClient(new Point(x,y)); + MouseDragOver(p.X,p.Y); + } + } + protected override void OnMouseDragEnd(bool cancel) + { + if(!this.IsDockableWindow) + { + this.Control.Capture = false; + Cursor.Clip = Rectangle.Empty; + + if(m_DragInProgress) + { + if(cancel) + MouseDragDrop(-1,-1); + else + { + Point p=this.Control.PointToClient(Control.MousePosition); + MouseDragDrop(p.X,p.Y); + } + cancel=true; + } + else + { + System.Windows.Forms.Control ctrl=this.GetItemContainerControl(); + if(ctrl is IOwner && ((IOwner)ctrl).GetFocusItem()!=null) + cancel=true; + } + } + + base.OnMouseDragEnd(cancel); + } + + protected virtual bool OnMouseLeave(ref Message m) + { + return false; + } + + protected virtual bool OnMouseDoubleClick(Message m) + { + bool processed=false; + + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(selection!=null && selection.PrimarySelection is ButtonItem && ((ButtonItem)selection.PrimarySelection).ContainerControl==this.GetItemContainerControl()) + { + 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 void OnItemSelected(BaseItem item) + { + + } + + protected virtual void RecalcLayout() + { + BarBaseControl bar=this.GetItemContainerControl() as BarBaseControl; + if(bar!=null) + bar.RecalcLayout(); + } + + /// + /// Indicates to the designed control that it has been selected or one of the elements managed by the control is selected in designer. + /// + /// true if selected otherwise false + protected virtual void SetComponentSelected(bool selected) + { + + } + + public override System.Collections.ICollection AssociatedComponents + { + get + { + ArrayList c=new ArrayList(base.AssociatedComponents); + BaseItem container=this.GetItemContainer(); + if(container!=null) + { + foreach(BaseItem item in container.SubItems) + { + if(item.DesignMode) + c.Add(item); + } + } + return c; + } + } + + private ArrayList GetAllAssociatedComponents() + { + ArrayList c=new ArrayList(base.AssociatedComponents); + BaseItem container=this.GetItemContainer(); + if(container!=null) + { + AddSubItems(container,c); + } + return c; + } + + private void AddSubItems(BaseItem parent, ArrayList list) + { + foreach(BaseItem item in parent.SubItems) + { + if(item.DesignMode) + list.Add(item); + AddSubItems(item,list); + } + } + #endregion + + #region Design-Time Item Creation + protected virtual void CreateButton(object sender, EventArgs e) + { + OnSubItemsChanging(); + CreateButton(this.GetItemContainer()); + OnSubItemsChanged(); + } + + protected virtual void CreateButton(BaseItem parent) + { + if(parent==null) + return; + + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh!=null) + { + ButtonItem item=dh.CreateComponent(typeof(ButtonItem)) as ButtonItem; + if(item==null) + return; + + TypeDescriptor.GetProperties(item)["Text"].SetValue(item,item.Name); + + IComponentChangeService cc=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(parent!=this.GetItemContainer() && cc!=null) + cc.OnComponentChanging(parent,TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"]); + + parent.SubItems.Add(item); + this.RecalcLayout(); + + if(parent!=this.GetItemContainer() && cc!=null) + cc.OnComponentChanged(parent,TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"],null,null); + } + } + + protected virtual void CreateTextBox(object sender, EventArgs e) + { + OnSubItemsChanging(); + CreateTextBox(this.GetItemContainer()); + OnSubItemsChanged(); + } + + protected virtual void CreateTextBox(BaseItem parent) + { + if(parent==null) + return; + + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh!=null) + { + TextBoxItem item=dh.CreateComponent(typeof(TextBoxItem)) as TextBoxItem; + if(item==null) + return; + + IComponentChangeService cc=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(parent!=this.GetItemContainer() && cc!=null) + cc.OnComponentChanging(parent,TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"]); + + parent.SubItems.Add(item); + this.RecalcLayout(); + + if(parent!=this.GetItemContainer() && cc!=null) + cc.OnComponentChanged(parent,TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"],null,null); + } + } + + + protected virtual void CreateComboBox(object sender, EventArgs e) + { + OnSubItemsChanging(); + CreateComboBox(this.GetItemContainer()); + OnSubItemsChanged(); + } + + protected virtual void CreateComboBox(BaseItem parent) + { + if(parent==null) + return; + + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh!=null) + { + ComboBoxItem item=dh.CreateComponent(typeof(ComboBoxItem)) as ComboBoxItem; + if(item==null) + return; + + IComponentChangeService cc=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(parent!=this.GetItemContainer() && cc!=null) + cc.OnComponentChanging(parent,TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"]); + + parent.SubItems.Add(item); + this.RecalcLayout(); + + if(parent!=this.GetItemContainer() && cc!=null) + cc.OnComponentChanged(parent,TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"],null,null); + } + } + + protected virtual void CreateLabel(object sender, EventArgs e) + { + OnSubItemsChanging(); + CreateLabel(this.GetItemContainer()); + OnSubItemsChanged(); + } + + protected virtual void CreateLabel(BaseItem parent) + { + if(parent==null) + return; + + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh!=null) + { + LabelItem item=dh.CreateComponent(typeof(LabelItem)) as LabelItem; + if(item==null) + return; + + TypeDescriptor.GetProperties(item)["Text"].SetValue(item,item.Name); + + IComponentChangeService cc=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(parent!=this.GetItemContainer() && cc!=null) + cc.OnComponentChanging(parent,TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"]); + + parent.SubItems.Add(item); + this.RecalcLayout(); + + if(parent!=this.GetItemContainer() && cc!=null) + cc.OnComponentChanged(parent,TypeDescriptor.GetProperties(typeof(BaseItem))["SubItems"],null,null); + } + } + + protected virtual void CreateDocument(object sender, EventArgs e) + { + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh==null) + return; + DockContainerItem item=dh.CreateComponent(typeof(DockContainerItem)) as DockContainerItem; + item.Text=item.Name; + OnSubItemsChanging(); + this.GetItemContainer().SubItems.Add(item); + PanelDockContainer panel=dh.CreateComponent(typeof(PanelDockContainer)) as PanelDockContainer; + this.Control.Controls.Add(panel); + panel.ColorSchemeStyle=this.Style; + panel.ApplyLabelStyle(); + item.Control=panel; + OnSubItemsChanged(); + + + this.RecalcLayout(); + } + + protected virtual void OnSubItemsChanging() {} + protected virtual void OnSubItemsChanged() {} + + protected virtual eDotNetBarStyle Style + { + get {return eDotNetBarStyle.Office2003;} + } + #endregion + + #region Drag & Drop support + 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 System.Windows.Forms.Control) + ControlRemoved((System.Windows.Forms.Control)sel.PrimarySelection); + } + } + } + + protected override void OnDragLeave(EventArgs e) + { + if(m_DragInProgress) + { + MouseDragDrop(-1,-1); + } + base.OnDragLeave (e); + } + + protected override void OnDragOver(DragEventArgs de) + { + if(m_DragInProgress) + { + Point p=this.Control.PointToClient(new Point(de.X,de.Y)); + MouseDragOver(p.X,p.Y); + de.Effect=DragDropEffects.Move; + return; + } + + if(m_EnableItemDragDrop && m_AcceptExternalControls && !this.IsDockableWindow) + { + 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)) + { + BaseItem item=GetControlItem(sel.PrimarySelection as Control); + if(item!=null) + { + m_MouseDownPoint=this.Control.PointToClient(new Point(de.X,de.Y)); + m_SuspendInternalCursor=true; + StartItemDrag(item); + 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(); + } + } + 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 + BaseItem dragItem=null; + if(this.IsDockableWindow) + { + DockContainerItem dc=new DockContainerItem(); + dc.Name=TEMP_NAME; + //dc.Control=sel.PrimarySelection as System.Windows.Forms.Control; + dragItem=dc; + } + else + { + ControlContainerItem cc=new ControlContainerItem(); + cc.Name=TEMP_NAME; + //cc.Control=sel.PrimarySelection as System.Windows.Forms.Control; + dragItem=cc; + } + m_MouseDownPoint=this.Control.PointToClient(new Point(de.X,de.Y)); + m_SuspendInternalCursor=true; + StartItemDrag(dragItem); + } + } + } + base.OnDragOver (de); + } + + protected override void OnDragDrop(DragEventArgs de) + { + if(m_EnableItemDragDrop && m_AcceptExternalControls && !this.IsDockableWindow) + { + 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; + Point p=this.Control.PointToClient(new Point(de.X,de.Y)); + MouseDragDrop(p.X,p.Y); + } + else + { + if(sel.SelectionCount>1) + { + de.Effect=DragDropEffects.None; + return; + } + else + { + if(m_DragItem!=null && m_DragItem.Name==TEMP_NAME && (m_DragItem is ControlContainerItem || m_DragItem is DockContainerItem)) + { + m_JustAdded=DateTime.Now; + BaseItem dragItem=null; + if(m_DragItem is ControlContainerItem) + { + ControlContainerItem cc=m_DragItem as ControlContainerItem; + cc.Control=null; + cc=this.CreateComponent(typeof(ControlContainerItem)) as ControlContainerItem; + TypeDescriptor.GetProperties(cc)["Control"].SetValue(cc,sel.PrimarySelection as System.Windows.Forms.Control); + dragItem=cc; + } + else if(m_DragItem is DockContainerItem) + { + DockContainerItem dc=m_DragItem as DockContainerItem; + dc.Control=null; + dc=this.CreateComponent(typeof(DockContainerItem)) as DockContainerItem; + TypeDescriptor.GetProperties(dc)["Control"].SetValue(dc,sel.PrimarySelection as System.Windows.Forms.Control); + dragItem=dc; + } + m_DragItem=dragItem; + Point p=this.Control.PointToClient(new Point(de.X,de.Y)); + MouseDragDrop(p.X,p.Y); + } + m_NewControlAdded=true; + } + } + } + + base.OnDragDrop(de); + } + + protected virtual BaseItem GetControlItem(System.Windows.Forms.Control control) + { + BaseItem parent=this.GetItemContainer(); + if(parent==null) + return null; + return GetControlItem(control,parent); + } + + private BaseItem GetControlItem(System.Windows.Forms.Control control, BaseItem parent) + { + if(parent is ControlContainerItem && ((ControlContainerItem)parent).Control==control) + return parent; + else if(parent is DockContainerItem && ((DockContainerItem)parent).Control==control) + return parent; + + foreach(BaseItem item in parent.SubItems) + { + BaseItem i2=GetControlItem(control,item); + if(i2!=null) + return i2; + } + return null; + } + + protected virtual bool DragInProgress + { + get {return m_DragInProgress;} + set {m_DragInProgress=value;} + } + + protected void StartItemDrag(BaseItem item) + { + if(item==null) + return; + + if(m_DragItem==null) + { + m_DragItem=item; + if(!m_SuspendInternalCursor) + System.Windows.Forms.Cursor.Current=System.Windows.Forms.Cursors.Hand; + m_DragInProgress=true; + } + } + + private void MouseDragOver(int x, int y) + { + if(!m_DragInProgress) + return; + BaseItem dragItem=m_DragItem; + BaseItem container=this.GetItemContainer(); + + if(m_DesignTimeProvider!=null) + { + m_DesignTimeProvider.DrawReversibleMarker(m_InsertPosition,m_InsertBefore); + m_DesignTimeProvider=null; + } + + Control control=this.GetItemContainerControl(); + Point pScreen=control.PointToScreen(new Point(x,y)); + + InsertPosition pos=((IDesignTimeProvider)container).GetInsertPosition(pScreen, dragItem); + + if(pos!=null) + { + if(pos.TargetProvider==null) + { + // Cursor is over drag item + if(!m_SuspendInternalCursor) + System.Windows.Forms.Cursor.Current=System.Windows.Forms.Cursors.No; + } + else + { + pos.TargetProvider.DrawReversibleMarker(pos.Position,pos.Before); + m_InsertPosition=pos.Position; + m_InsertBefore=pos.Before; + m_DesignTimeProvider=pos.TargetProvider; + if(!m_SuspendInternalCursor) + System.Windows.Forms.Cursor.Current=System.Windows.Forms.Cursors.Hand; + } + } + else + { + if(!m_SuspendInternalCursor) + System.Windows.Forms.Cursor.Current=System.Windows.Forms.Cursors.No; + } + } + + private void MouseDragDrop(int x, int y) + { + if(!m_DragInProgress) + return; + BaseItem dragItem=m_DragItem; + BaseItem container=this.GetItemContainer(); + bool changed=false; + + if(m_DesignTimeProvider!=null) + { + if(x==-1 && y==-1) + { + // Cancel state + m_DesignTimeProvider.DrawReversibleMarker(m_InsertPosition, m_InsertBefore); + } + else + { + m_DesignTimeProvider.DrawReversibleMarker(m_InsertPosition, m_InsertBefore); + if(dragItem!=null) + { + BaseItem objParent=dragItem.Parent; + if(objParent!=null) + { + if(objParent==(BaseItem)m_DesignTimeProvider && m_InsertPosition>0) + { + if(objParent.SubItems.IndexOf(dragItem) + /// Gets or sets whether drag and drop of BaseItems is enabled. Default is false. + /// + protected virtual bool EnableItemDragDrop + { + get {return m_EnableItemDragDrop;} + set {m_EnableItemDragDrop=value;} + } + + /// + /// Gets or sets whether dropping of external control into Bar is enabled. Default is false. + /// + protected virtual bool AcceptExternalControls + { + get {return m_AcceptExternalControls;} + set {m_AcceptExternalControls=value;} + } + + public void StartExternalDrag(BaseItem item) + { + if(!m_DragInProgress && m_DesignerHost!=null) + { + m_SuspendInternalCursor=false; + m_MouseDownPoint=this.Control.PointToClient(System.Windows.Forms.Control.MousePosition); + this.StartItemDrag(item); + m_DesignerHost.Capture=true; + } + } + + protected virtual bool IsDockableWindow + { + get {return false;} + } + + protected virtual void SelectComponent(IComponent comp, SelectionTypes selectionType) + { + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(selection!=null) + { + ArrayList arr=new ArrayList(1); + arr.Add(comp); + selection.SetSelectedComponents(arr,selectionType); + } + } + + protected virtual bool MouseDownSelectionPerformed + { + get {return m_MouseDownSelectionPerformed;} + set {m_MouseDownSelectionPerformed=value;} + } + #endregion + + #region IDesignerServices Implementation + public object CreateComponent(System.Type componentClass) + { + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh==null) + return null; + return dh.CreateComponent(componentClass); + } + + public void DestroyComponent(IComponent c) + { + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh==null) + return; + dh.DestroyComponent(c); + } + + object IDesignerServices.GetService(Type serviceType) + { + return this.GetService(serviceType); + } + #endregion + + private void DesignerSelectionChanged(object sender, EventArgs e) + { + ISelectionService sel=this.GetService(typeof(ISelectionService)) as ISelectionService; + if(sel==null) + { + SetComponentSelected(false); + return; + } + bool selected=false; + if(sel.PrimarySelection==this.Control || sel.PrimarySelection==this.GetItemContainerControl()) + selected=true; + else if(sel.PrimarySelection is BaseItem && ((BaseItem)sel.PrimarySelection).ContainerControl==this.GetItemContainerControl()) + selected=true; + + SetComponentSelected(selected); + } + } + + #region IDesignerServices + /// + /// Classes used for internal support of design-time features. + /// + public interface IDesignerServices + { + /// + /// Creates new component. + /// + /// Component type to create + /// New instance of component + object CreateComponent(System.Type componentClass); + /// + /// Destroys component + /// + /// Component to destroy + void DestroyComponent(IComponent c); + + /// + /// Gets specified designer service. + /// + /// Type of the service to get + /// Returns reference to the service. + object GetService(Type serviceType); + } + + /// + /// Interface implemented by target Bar interested in access to designer. + /// + public interface IBarDesignerServices + { + /// + /// Gets or sets the BarBaseControlDesigner instance. + /// + BarBaseControlDesigner Designer {get;set;} + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/BarDesigner.cs b/PROMS/DotNetBar Source Code/BarDesigner.cs new file mode 100644 index 00000000..b1cd258c --- /dev/null +++ b/PROMS/DotNetBar Source Code/BarDesigner.cs @@ -0,0 +1,701 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Windows.Forms; +using System.ComponentModel.Design.Serialization; +using System.CodeDom; +using System.Drawing; +using System.Collections; +using System.Windows.Forms.Design; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents Windows Forms designer for Bar control. + /// + public class BarDesigner:BarBaseControlDesigner + { + #region Internal Implementation + private int m_MouseDownSelectedTabIndex=-1; + private bool m_IsDocking=false; + private Form m_OutlineForm=null; + private DockSiteInfo m_DockInfo; + private bool m_DragDrop=false; + + public BarDesigner():base() + { + m_DockInfo=new DockSiteInfo(); + this.EnableItemDragDrop=true; + } + + public override DesignerVerbCollection Verbs + { + get + { + Bar bar=this.Control as Bar; + DesignerVerb[] verbs=null; + if(this.IsDockableWindow) + { + verbs = new DesignerVerb[] + { + new DesignerVerb("Create Document", new EventHandler(CreateDocument))}; + } + else + { + verbs = new DesignerVerb[] + { + new DesignerVerb("Create Button", new EventHandler(CreateButton)), + new DesignerVerb("Create Text Box", new EventHandler(CreateTextBox)), + new DesignerVerb("Create Combo Box", new EventHandler(CreateComboBox)), + new DesignerVerb("Create Label", new EventHandler(CreateLabel)), + new DesignerVerb("Open Bar Designer", new EventHandler(EditBar))}; + } + + return new DesignerVerbCollection(verbs); + } + } + + private void EditBar(object sender, EventArgs e) + { + OpenDesigner(); + } + + public override void DoDefaultAction() + { + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(!this.IsDockableWindow && selection!=null && selection.PrimarySelection==this.Control) + OpenDesigner(); + else + base.DoDefaultAction(); + } + + private void OpenDesigner() + { + Bar bar=this.Control as Bar; + if(bar!=null) + { + DotNetBarManagerDesigner.OpenDesignerEditor(null,bar,this); + } + } + +#if FRAMEWORK20 + public override void InitializeNewComponent(IDictionary defaultValues) + { + base.InitializeNewComponent(defaultValues); + SetDesignTimeDefaults(); + } +#else + public override void OnSetComponentDefaults() + { + base.OnSetComponentDefaults(); + SetDesignTimeDefaults(); + } +#endif + + private void SetDesignTimeDefaults() + { + Bar bar = this.Component as Bar; + if (bar == null) + return; + bar.Style = eDotNetBarStyle.Office2003; + } + + protected override BaseItem GetItemContainer() + { + Bar bar=this.Control as Bar; + if(bar!=null) + return bar.ItemsContainer; + return null; + } + + protected override void RecalcLayout() + { + Bar bar=this.GetItemContainerControl() as Bar; + if(bar!=null) + bar.RecalcLayout(); + } + + protected override void OnSubItemsChanging() + { + base.OnSubItemsChanging(); + IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(change!=null) + { + Bar bar=this.GetItemContainerControl() as Bar; + change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(bar).Find("Items",true)); + } + } + + protected override void OnSubItemsChanged() + { + base.OnSubItemsChanged(); + IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(change!=null) + { + Bar bar=this.GetItemContainerControl() as Bar; + change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(bar).Find("Items",true),null,null); + } + } + + + #endregion + + #region Support For Dockable Windows + + public override SelectionRules SelectionRules + { + get + { + if(this.IsDockableWindow) + return (SelectionRules.Locked); + return base.SelectionRules; + } + } + + public override bool CanParent(Control control) + { + if(control.Contains(this.Control)) + return false; + if(this.IsDockableWindow && !(control is PanelDockContainer)) + return false; + return base.CanParent(control); + } + + protected override bool IsDockableWindow + { + get + { + Bar bar=this.Control as Bar; + if(bar!=null && bar.LayoutType==eLayoutType.DockContainer) + return true; + return false; + } + } + + private void SelectDockTab(int index) + { + Bar bar=this.Control as Bar; + if(bar==null) return; + + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + if(cc!=null) + cc.OnComponentChanging(bar,TypeDescriptor.GetProperties(typeof(Bar))["SelectedDockTab"]); + bar.SelectedDockTab=index; + if(cc!=null) + cc.OnComponentChanged(bar,TypeDescriptor.GetProperties(typeof(Bar))["SelectedDockTab"],null,null); + if(bar.SelectedDockTab>=0) + { +#if FRAMEWORK20 + SelectComponent(bar.Items[bar.SelectedDockTab], SelectionTypes.Primary); +#else + SelectComponent(bar.Items[bar.SelectedDockTab],SelectionTypes.MouseDown); +#endif + DockContainerItem dock=bar.Items[bar.SelectedDockTab] as DockContainerItem; + if(dock!=null && dock.Control!=null) + { + dock.Control.BringToFront(); + if(cc!=null) + cc.OnComponentChanged(bar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"],null,null); + } + } + } + + protected override eDotNetBarStyle Style + { + get + { + Bar bar=this.Control as Bar; + if(bar!=null) + return bar.Style; + return base.Style;; + } + } + + protected override void OtherComponentRemoving(object sender, ComponentEventArgs e) + { + Bar bar=this.Control as Bar; + if(e.Component is Control) + { + BaseItem item=GetControlItem(e.Component as Control); + if(item!=null && item.Parent!=null && item.Parent.SubItems.Contains(item)) + { + if(item is DockContainerItem) + ((DockContainerItem)item).Control=null; + else if(item is ControlContainerItem) + ((ControlContainerItem)item).Control = null; + item.Parent.SubItems.Remove(item); + DestroySubItems(item); + this.RecalcLayout(); + if(bar!=null && bar.Items.Count>0) + SelectDockTab(0); + } + } + else if(!m_InternalRemoving && bar!=null && e.Component is DockContainerItem && bar.Items.Contains((BaseItem)e.Component)) + { + // Throw exception to stop removing the last dock container item. + if(bar.VisibleItemCount==1) + throw new InvalidOperationException("Cannot delete last DockContainerItem object. Select and Delete Bar object instead"); + } + base.OtherComponentRemoving(sender,e); + } + + protected override bool OnMouseDown(ref Message m) + { + Bar bar=this.Control as Bar; + if(!this.IsDockableWindow || bar==null) + return base.OnMouseDown(ref m); + Point p=Control.MousePosition; + int i=GetTabAt(p.X,p.Y); + if(i>=0 && m.Msg==NativeFunctions.WM_RBUTTONDOWN) + { + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(selection!=null && selection.PrimarySelection!=bar.Items[i]) + { + ArrayList arr=new ArrayList(1); + arr.Add(bar.Items[i]); +#if FRAMEWORK20 + selection.SetSelectedComponents(arr, SelectionTypes.Primary); +#else + selection.SetSelectedComponents(arr,SelectionTypes.MouseDown); +#endif + + SelectDockTab(i); + this.OnContextMenu(System.Windows.Forms.Control.MousePosition.X,System.Windows.Forms.Control.MousePosition.Y); + return true; + } + } + + + return base.OnMouseDown(ref m); + } + + protected override void OnMouseDragBegin(int x, int y) + { + Bar bar=this.Control as Bar; + m_DragDrop=false; + + if(bar!=null && this.IsDockableWindow) + { + m_MouseDownSelectedTabIndex=GetTabAt(x,y); + if(m_MouseDownSelectedTabIndex!=-1) + { + if(bar.SelectedDockTab!=m_MouseDownSelectedTabIndex) + SelectDockTab(m_MouseDownSelectedTabIndex); + m_DragDrop=true; + } + else if(IsInTabSystemBox(x,y)) + { + MouseDownTabSystemBox(x,y); + } + else if(IsCaptionGrabHandle(bar)) + { + Point clientPos=bar.PointToClient(new Point(x,y)); + if(bar.GrabHandleRect.Contains(clientPos)) + m_DragDrop=true; + } + } + base.OnMouseDragBegin(x,y); + + if(m_MouseDownSelectedTabIndex!=-1) + { + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(selection!=null && selection.PrimarySelection!=bar.Items[m_MouseDownSelectedTabIndex]) + { + ArrayList arr=new ArrayList(1); + arr.Add(bar.Items[m_MouseDownSelectedTabIndex]); +#if FRAMEWORK20 + selection.SetSelectedComponents(arr, SelectionTypes.Primary); +#else + selection.SetSelectedComponents(arr,SelectionTypes.Click); +#endif + } + } + + if(m_DragDrop) + { + bar.Capture = true; + NativeFunctions.RECT rect = new NativeFunctions.RECT(0,0,0,0); + NativeFunctions.GetWindowRect(bar.Parent.Handle, ref rect); + Rectangle r=Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom); + Cursor.Clip=r; + } + } + + private bool IsCaptionGrabHandle(Bar bar) + { + return (bar.GrabHandleStyle==eGrabHandleStyle.Caption || bar.GrabHandleStyle==eGrabHandleStyle.CaptionTaskPane); + } + + protected override void OnMouseDragMove(int x, int y) + { + if(!this.IsDockableWindow || !m_DragDrop) + { + base.OnMouseDragMove(x,y); + return; + } + + Point screenPos=new Point(x,y); + + Bar bar=this.Control as Bar; + if(bar==null) return; + + Point tabPos=bar.DockTabControl.PointToClient(screenPos); + if(bar.DockTabControl!=null && bar.DockTabControl.ClientRectangle.Contains(tabPos)) + { + if(m_IsDocking) + { + EndBarOwnerDocking(bar); + m_IsDocking=false; + m_DockInfo=new DockSiteInfo(); + } + MouseEventArgs e=new MouseEventArgs(MouseButtons.Left,0,tabPos.X,tabPos.Y,0); + bar.DockTabControl.InternalOnMouseMove(e); + } + else + { + m_IsDocking=true; + IOwnerBarSupport ownerDock=bar.Owner as IOwnerBarSupport; + m_DockInfo=ownerDock.GetDockInfo(bar,screenPos.X,screenPos.Y); + if(m_DockInfo.objDockSite==null) + { + if(m_OutlineForm!=null) + m_OutlineForm.Hide(); + } + else + { + Rectangle r=m_DockInfo.objDockSite.GetBarDockRectangle(bar,ref m_DockInfo); + if(!r.IsEmpty) + { + if(m_OutlineForm==null) + m_OutlineForm=BarFunctions.CreateOutlineForm(); + NativeFunctions.SetWindowPos(m_OutlineForm.Handle.ToInt32(),NativeFunctions.HWND_TOP,r.X,r.Y,r.Width,r.Height,NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); + } + else if(m_OutlineForm!=null) + m_OutlineForm.Hide(); + } + } + } + + protected override void OnMouseDragEnd(bool cancel) + { + if(!this.IsDockableWindow) + { + base.OnMouseDragEnd(cancel); + return; + } + + this.Control.Capture = false; + Cursor.Clip = Rectangle.Empty; + + Bar bar=this.Control as Bar; + + if(cancel || bar==null || !m_DragDrop) + { + base.OnMouseDragEnd(cancel); + return; + } + + m_DragDrop=false; + + IDesignerHost designerHost=this.GetService(typeof(IDesignerHost)) as IDesignerHost; + if(designerHost==null) + { + EndBarOwnerDocking(bar); + m_IsDocking=false; + m_MouseDownSelectedTabIndex=-1; + base.OnMouseDragEnd(cancel); + return; + } + + if(m_IsDocking) + { + EndBarOwnerDocking(bar); + // Moves and docks the selected DockContainerItem or bar + Bar referenceBar=m_DockInfo.MouseOverBar; + if(m_DockInfo.MouseOverDockSide!=eDockSide.None && m_DockInfo.MouseOverDockSide!=eDockSide.Document && (referenceBar!=bar || m_MouseDownSelectedTabIndex!=-1 && bar.VisibleItemCount>1)) + { + DesignerTransaction trans=designerHost.CreateTransaction("DotNetBar Docking"); + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + try + { + Bar newBar=null; + if(m_MouseDownSelectedTabIndex!=-1 && bar.VisibleItemCount>1) + newBar=BarFunctions.CreateDuplicateDockBar(bar,this); + else + newBar=bar; + + cc.OnComponentChanging(bar,TypeDescriptor.GetProperties(typeof(Bar))["SelectedDockTab"]); + + if(m_MouseDownSelectedTabIndex!=-1 && bar.VisibleItemCount>1) + { + DockContainerItem item=bar.Items[bar.SelectedDockTab] as DockContainerItem; + cc.OnComponentChanging(bar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"]); + cc.OnComponentChanging(bar,TypeDescriptor.GetProperties(typeof(Bar))["Items"]); + bar.Items.Remove(item); + cc.OnComponentChanged(bar,TypeDescriptor.GetProperties(typeof(Bar))["Items"],null,null); + cc.OnComponentChanged(bar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"],null,null); + + cc.OnComponentChanging(newBar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"]); + cc.OnComponentChanging(newBar,TypeDescriptor.GetProperties(typeof(Bar))["Items"]); + newBar.Items.Add(item); + cc.OnComponentChanged(newBar,TypeDescriptor.GetProperties(typeof(Bar))["Items"],null,null); + cc.OnComponentChanged(newBar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"],null,null); + } + + cc.OnComponentChanging(m_DockInfo.objDockSite,TypeDescriptor.GetProperties(typeof(DockSite))["Controls"]); + cc.OnComponentChanging(newBar,null); + cc.OnComponentChanging(referenceBar,null); + cc.OnComponentChanging(m_DockInfo.objDockSite,TypeDescriptor.GetProperties(typeof(DockSite))["DocumentDockContainer"]); + m_DockInfo.objDockSite.GetDocumentUIManager().Dock(referenceBar,newBar,m_DockInfo.MouseOverDockSide); + cc.OnComponentChanged(m_DockInfo.objDockSite,TypeDescriptor.GetProperties(typeof(DockSite))["DocumentDockContainer"],null,null); + cc.OnComponentChanged(referenceBar,null,null,null); + cc.OnComponentChanged(newBar,null,null,null); + cc.OnComponentChanged(m_DockInfo.objDockSite,TypeDescriptor.GetProperties(typeof(DockSite))["Controls"],null,null); + + } + catch + { + trans.Cancel(); + throw; + } + finally + { + if(!trans.Canceled) + trans.Commit(); + } + } + else if(m_DockInfo.MouseOverDockSide==eDockSide.Document && bar!=referenceBar) + { + BarDesigner referenceDesigner=designerHost.GetDesigner(referenceBar) as BarDesigner; + if(referenceDesigner!=null) + referenceDesigner.DelayedDockTabs(bar,m_MouseDownSelectedTabIndex); + } + + m_DockInfo=new DockSiteInfo(); + } + else if(m_MouseDownSelectedTabIndex!=-1) + { + if(m_MouseDownSelectedTabIndex!=bar.SelectedDockTab) + { + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + if(cc!=null) + { + cc.OnComponentChanged(bar,TypeDescriptor.GetProperties(typeof(Bar))["Items"],null,null); + cc.OnComponentChanged(bar,TypeDescriptor.GetProperties(typeof(Bar))["SelectedDockTab"],null,null); + cc.OnComponentChanged(bar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"],null,null); + } + } + } + m_IsDocking=false; + m_MouseDownSelectedTabIndex=-1; + base.OnMouseDragEnd(cancel); + } + + private Timer m_TimerDelayRemove=null; + private Bar m_DelayDockBar=null; + private int m_DelayDockTabIndex=-1; + internal void DelayedDockTabs(Bar bar, int tabIndex) + { + if(m_TimerDelayRemove==null) + { + m_DelayDockBar=bar; + m_DelayDockTabIndex=tabIndex; + m_TimerDelayRemove=new Timer(); + m_TimerDelayRemove.Tick+=new EventHandler(this.TimerTickDelayRemove); + m_TimerDelayRemove.Interval=200; + m_TimerDelayRemove.Enabled=true; + m_TimerDelayRemove.Start(); + } + } + private void TimerTickDelayRemove(object sender, EventArgs e) + { + m_TimerDelayRemove.Stop(); + m_TimerDelayRemove.Enabled=false; + m_TimerDelayRemove.Dispose(); + m_TimerDelayRemove=null; + + DockTabs(m_DelayDockBar,m_DelayDockTabIndex,this.Control as Bar); + + m_DelayDockBar=null; + m_DelayDockTabIndex=-1; + } + + private void DockTabs(Bar sourceBar, int selectedTabIndex, Bar targetBar) + { + // Move Dock-container item to different bar + IDesignerHost designerHost=this.GetService(typeof(IDesignerHost)) as IDesignerHost; + DesignerTransaction trans=designerHost.CreateTransaction("DotNetBar Docking"); + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + try + { + DockContainerItem[] items=null; + if(selectedTabIndex!=-1) + items=new DockContainerItem[] {sourceBar.Items[sourceBar.SelectedDockTab] as DockContainerItem}; + else + { + items=new DockContainerItem[sourceBar.Items.Count]; + sourceBar.Items.CopyTo(items,0); + } + + cc.OnComponentChanging(sourceBar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"]); + cc.OnComponentChanging(sourceBar,TypeDescriptor.GetProperties(typeof(Bar))["Items"]); + sourceBar.Items.RemoveRange(items); + cc.OnComponentChanged(sourceBar,TypeDescriptor.GetProperties(typeof(Bar))["Items"],null,null); + cc.OnComponentChanged(sourceBar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"],null,null); + + cc.OnComponentChanging(targetBar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"]); + cc.OnComponentChanging(targetBar,TypeDescriptor.GetProperties(typeof(Bar))["Items"]); + targetBar.Items.AddRange(items); + cc.OnComponentChanged(targetBar,TypeDescriptor.GetProperties(typeof(Bar))["Items"],null,null); + cc.OnComponentChanged(targetBar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"],null,null); + + if(sourceBar.Items.Count==0) + { + DockSite sourceDockSite=sourceBar.Parent as DockSite; + cc.OnComponentChanging(sourceDockSite,TypeDescriptor.GetProperties(typeof(DockSite))["DocumentDockContainer"]); + cc.OnComponentChanging(sourceBar,null); + sourceDockSite.GetDocumentUIManager().UnDock(sourceBar,false); + cc.OnComponentChanged(sourceBar,null,null,null); + cc.OnComponentChanged(sourceDockSite,TypeDescriptor.GetProperties(typeof(DockSite))["DocumentDockContainer"],null,null); + + designerHost.DestroyComponent(sourceBar); + } + + if(targetBar!=null && targetBar.SelectedDockTab>=0) + { + DockContainerItem dock=targetBar.Items[targetBar.SelectedDockTab] as DockContainerItem; + if(dock!=null && dock.Control!=null) + { + cc.OnComponentChanged(targetBar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"],null,null); + dock.Control.BringToFront(); + cc.OnComponentChanged(targetBar,TypeDescriptor.GetProperties(typeof(Bar))["Controls"],null,null); + } + } + } + catch + { + trans.Cancel(); + throw; + } + finally + { + if(!trans.Canceled) + trans.Commit(); + } + } + + private void EndBarOwnerDocking(Bar bar) + { + IOwnerBarSupport barSupport=bar.Owner as IOwnerBarSupport; + if(barSupport!=null) + barSupport.DockComplete(); + if(m_OutlineForm!=null) + { + m_OutlineForm.Hide(); + m_OutlineForm.Dispose(); + m_OutlineForm=null; + } + } + + /// + /// Returns tab index under specified coordinates. + /// + /// Screen X coordinate + /// Screen Y coordinate + /// Tab index or -1 if tab was not found + private int GetTabAt(int x, int y) + { + Bar bar=this.Control as Bar; + if(bar==null) return -1; + + // Select dockable tab if mouse is clicked over the tab + if(this.IsDockableWindow && bar.DockTabControl!=null) + { + Point posTab=bar.DockTabControl.PointToClient(new Point(x,y)); + if(bar.DockTabControl._TabSystemBox.Visible && bar.DockTabControl._TabSystemBox.DisplayRectangle.Contains(posTab)) + { + return -1; + } + TabItem tab=bar.DockTabControl.HitTest(posTab.X,posTab.Y); + if(tab!=null) + return bar.Items.IndexOf(tab.AttachedItem); + } + + return -1; + } + + private bool IsInTabSystemBox(int x, int y) + { + Bar bar=this.Control as Bar; + if(bar==null) return false; + + // Select dockable tab if mouse is clicked over the tab + if(this.IsDockableWindow && bar.DockTabControl!=null) + { + Point posTab=bar.DockTabControl.PointToClient(new Point(x,y)); + if(bar.DockTabControl._TabSystemBox.Visible && bar.DockTabControl._TabSystemBox.DisplayRectangle.Contains(posTab)) + return true; + } + + return false; + } + + private void MouseDownTabSystemBox(int x, int y) + { + Bar bar=this.Control as Bar; + if(bar==null) return; + + // Select dockable tab if mouse is clicked over the tab + if(this.IsDockableWindow && bar.DockTabControl!=null) + { + Point posTab=bar.DockTabControl.PointToClient(new Point(x,y)); + if(bar.DockTabControl._TabSystemBox.Visible && bar.DockTabControl._TabSystemBox.DisplayRectangle.Contains(posTab)) + { + if(bar.DockTabControl._TabSystemBox.ForwardEnabled && bar.DockTabControl._TabSystemBox.ForwardRect.Contains(posTab)) + { + bar.DockTabControl.ScrollForward(); + } + else if(bar.DockTabControl._TabSystemBox.BackEnabled && bar.DockTabControl._TabSystemBox.BackRect.Contains(posTab)) + { + bar.DockTabControl.ScrollBackwards(); + } + } + } + + } + + /// + /// Removes all subitems from container. + /// + protected override void ThisComponentRemoving(object sender, ComponentEventArgs e) + { + if(!m_InternalRemoving) + { + m_InternalRemoving=true; + try + { + if(this.IsDockableWindow) + { + Bar bar=this.Control as Bar; + if(bar!=null && bar.DockSide==eDockSide.Document && bar.Parent is DockSite) + { + IComponentChangeService cc=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(cc!=null) + cc.OnComponentChanging(((DockSite)bar.Parent),TypeDescriptor.GetProperties(typeof(DockSite)).Find("DocumentDockContainer",true)); + ((DockSite)bar.Parent).GetDocumentUIManager().UnDock(bar,false); + if(cc!=null) + cc.OnComponentChanged(((DockSite)bar.Parent),TypeDescriptor.GetProperties(typeof(DockSite)).Find("DocumentDockContainer",true),null,null); + } + } + } + finally + { + m_InternalRemoving=false; + } + } + + base.ThisComponentRemoving(sender,e); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/BarEditor.cs b/PROMS/DotNetBar Source Code/BarEditor.cs new file mode 100644 index 00000000..e0acfce6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BarEditor.cs @@ -0,0 +1,2106 @@ +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for BarEditor. + /// + public class BarEditor : System.Windows.Forms.Form + { + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.TreeView barTree; + private System.Windows.Forms.PropertyGrid propertyGrid1; + private System.Windows.Forms.Splitter splitter1; + private System.ComponentModel.IContainer components; + private DevComponents.DotNetBar.DockSite barTopDockSite; + private DevComponents.DotNetBar.DockSite barBottomDockSite; + private DevComponents.DotNetBar.DockSite barLeftDockSite; + private DevComponents.DotNetBar.DockSite barRightDockSite; + private DevComponents.DotNetBar.DotNetBarManager barManager; + private System.Windows.Forms.ImageList imageList; + + private DotNetBarManager m_DotNetBar; + private Bar m_Bar=null; + private TreeNode m_BarsNode=null,m_CategoriesNode=null,m_PopupsNode=null; + + private System.Windows.Forms.Button btnClose; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.OpenFileDialog m_OpenFileDialog; + private Hashtable m_catTable; + private System.Windows.Forms.SaveFileDialog m_SaveFileDialog; + private System.Windows.Forms.ImageList m_BarImages; + private string m_DefinitionFileName=""; + private bool m_ShowItemText=true; + private GridViewSubclass m_GridViewSubclass=null; + private bool m_DataChanged=false; + private HTMLHelp m_HtmlHelp=null; + + internal IDesignerServices _barDesigner=null; + + public BarEditor(DotNetBarManager dotnetbar) + { + m_DotNetBar=dotnetbar; + Initialize(); + } + + public BarEditor(Bar bar) + { + m_Bar=bar; + Initialize(); + } + + private void Initialize() + { + InitializeComponent(); + if(m_Bar!=null) + propertyGrid1.BrowsableAttributes=new AttributeCollection(new Attribute[] {BrowsableAttribute.Yes}); + else + propertyGrid1.BrowsableAttributes=new AttributeCollection(new Attribute[] {DevCoBrowsable.Yes}); + propertyGrid1.CommandsVisibleIfAvailable=false; + LoadResourceImages(); + m_catTable=new Hashtable(20); + + m_GridViewSubclass=new GridViewSubclass(); + m_GridViewSubclass.OnRightMouseDown+=new EventHandler(this.GridViewMouseDown); + + foreach(Control ctrl in propertyGrid1.Controls) + { + if(ctrl.GetType().ToString().IndexOf("PropertyGridView")>=0) + { + m_GridViewSubclass.AssignHandle(ctrl.Handle); + break; + } + } + + if(m_DotNetBar!=null && !m_DotNetBar.IsDesignTime() || m_Bar!=null) + { + btnCancel.Visible=false; + btnClose.Location=btnCancel.Location; + } + + CreateToolbar(); + RefreshView(); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(BarEditor)); + this.panel1 = new System.Windows.Forms.Panel(); + this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); + this.splitter1 = new System.Windows.Forms.Splitter(); + this.barTree = new System.Windows.Forms.TreeView(); + this.imageList = new System.Windows.Forms.ImageList(this.components); + #if TRIAL + this.barManager = new DevComponents.DotNetBar.DotNetBarManager(this.components); + #else + this.barManager = new DevComponents.DotNetBar.DotNetBarManager(this.components,false); + #endif + this.barBottomDockSite = new DevComponents.DotNetBar.DockSite(); + this.m_BarImages = new System.Windows.Forms.ImageList(this.components); + this.barLeftDockSite = new DevComponents.DotNetBar.DockSite(); + this.barRightDockSite = new DevComponents.DotNetBar.DockSite(); + this.barTopDockSite = new DevComponents.DotNetBar.DockSite(); + this.m_OpenFileDialog = new System.Windows.Forms.OpenFileDialog(); + this.m_SaveFileDialog = new System.Windows.Forms.SaveFileDialog(); + this.btnClose = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right); + this.panel1.Controls.AddRange(new System.Windows.Forms.Control[] { + this.propertyGrid1, + this.splitter1, + this.barTree}); + this.panel1.Location = new System.Drawing.Point(8, 48); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(520, 232); + this.panel1.TabIndex = 5; + // + // propertyGrid1 + // + this.propertyGrid1.CommandsVisibleIfAvailable = true; + this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill; + this.propertyGrid1.LargeButtons = false; + this.propertyGrid1.LineColor = System.Drawing.SystemColors.ScrollBar; + this.propertyGrid1.Location = new System.Drawing.Point(182, 0); + this.propertyGrid1.Name = "propertyGrid1"; + this.propertyGrid1.Size = new System.Drawing.Size(338, 232); + this.propertyGrid1.TabIndex = 1; + this.propertyGrid1.Text = "propertyGrid1"; + this.propertyGrid1.ViewBackColor = System.Drawing.SystemColors.Window; + this.propertyGrid1.ViewForeColor = System.Drawing.SystemColors.WindowText; + this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.OnPropertyValueChanged); + // + // splitter1 + // + this.splitter1.Location = new System.Drawing.Point(176, 0); + this.splitter1.Name = "splitter1"; + this.splitter1.Size = new System.Drawing.Size(6, 232); + this.splitter1.TabIndex = 2; + this.splitter1.TabStop = false; + // + // barTree + // + this.barTree.Dock = System.Windows.Forms.DockStyle.Left; + this.barTree.HideSelection = false; + this.barTree.ImageList = this.imageList; + this.barTree.Name = "barTree"; + this.barTree.Size = new System.Drawing.Size(176, 232); + this.barTree.TabIndex = 0; + this.barTree.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TreeKeyDown); + this.barTree.MouseDown += new System.Windows.Forms.MouseEventHandler(this.TreeMouseDown); + this.barTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.ItemSelected); + this.barTree.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.BeforeItemSelect); + this.barTree.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.ItemEdited); + this.barTree.BeforeCollapse += new System.Windows.Forms.TreeViewCancelEventHandler(this.NodeCollapsing); + this.barTree.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.NodeExpanding); + // + // imageList + // + this.imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit; + this.imageList.ImageSize = new System.Drawing.Size(16, 16); + this.imageList.TransparentColor = System.Drawing.Color.Magenta; + // + // barManager + // + this.barManager.BottomDockSite = this.barBottomDockSite; + this.barManager.Images = this.m_BarImages; + this.barManager.ImagesLarge = null; + this.barManager.ImagesMedium = null; + this.barManager.LeftDockSite = this.barLeftDockSite; + this.barManager.ParentForm = this; + this.barManager.RightDockSite = this.barRightDockSite; + this.barManager.TopDockSite = this.barTopDockSite; + this.barManager.UseHook = true; + this.barManager.ItemClick += new System.EventHandler(this.BarItemClick); + // + // barBottomDockSite + // + this.barBottomDockSite.Dock = System.Windows.Forms.DockStyle.Bottom; + this.barBottomDockSite.Location = new System.Drawing.Point(0, 325); + this.barBottomDockSite.Name = "barBottomDockSite"; + this.barBottomDockSite.Size = new System.Drawing.Size(536, 0); + this.barBottomDockSite.TabIndex = 8; + this.barBottomDockSite.TabStop = false; + // + // m_BarImages + // + this.m_BarImages.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit; + this.m_BarImages.ImageSize = new System.Drawing.Size(16, 16); + this.m_BarImages.TransparentColor = System.Drawing.Color.Magenta; + // + // barLeftDockSite + // + this.barLeftDockSite.Dock = System.Windows.Forms.DockStyle.Left; + this.barLeftDockSite.Name = "barLeftDockSite"; + this.barLeftDockSite.Size = new System.Drawing.Size(0, 325); + this.barLeftDockSite.TabIndex = 9; + this.barLeftDockSite.TabStop = false; + // + // barRightDockSite + // + this.barRightDockSite.Dock = System.Windows.Forms.DockStyle.Right; + this.barRightDockSite.Location = new System.Drawing.Point(536, 0); + this.barRightDockSite.Name = "barRightDockSite"; + this.barRightDockSite.Size = new System.Drawing.Size(0, 325); + this.barRightDockSite.TabIndex = 10; + this.barRightDockSite.TabStop = false; + // + // barTopDockSite + // + this.barTopDockSite.Dock = System.Windows.Forms.DockStyle.Top; + this.barTopDockSite.Name = "barTopDockSite"; + this.barTopDockSite.Size = new System.Drawing.Size(536, 0); + this.barTopDockSite.TabIndex = 7; + this.barTopDockSite.TabStop = false; + // + // m_OpenFileDialog + // + this.m_OpenFileDialog.Filter = "DotNetBar Files (*.dnb)|*.dnb|All Files (*.*)|*.*"; + this.m_OpenFileDialog.ShowReadOnly = true; + this.m_OpenFileDialog.Title = "Open DotNetBar Definition File"; + // + // m_SaveFileDialog + // + this.m_SaveFileDialog.CreatePrompt = false; + this.m_SaveFileDialog.DefaultExt = "dnb"; + this.m_SaveFileDialog.FileName = "dotnetbardefinition"; + this.m_SaveFileDialog.Filter = "DotNetBar Files (*.dnb)|*.dnb|XML Files (*.xml)|*.xml|All Files (*.*)|*.*"; + this.m_SaveFileDialog.Title = "Save DotNetBar Definition"; + // + // btnClose + // + this.btnClose.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right); + this.btnClose.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnClose.Location = new System.Drawing.Point(376, 291); + this.btnClose.Name = "btnClose"; + this.btnClose.Size = new System.Drawing.Size(73, 24); + this.btnClose.TabIndex = 6; + this.btnClose.Text = "OK"; + this.btnClose.Click += new System.EventHandler(this.CloseClick); + // + // btnCancel + // + this.btnCancel.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnCancel.Location = new System.Drawing.Point(455, 291); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(73, 24); + this.btnCancel.TabIndex = 7; + this.btnCancel.Text = "Cancel"; + this.btnCancel.Click += new System.EventHandler(this.CloseClick); + // + // BarEditor + // + //this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(536, 325); + this.Controls.AddRange(new System.Windows.Forms.Control[] { + this.panel1, + this.btnClose, + this.btnCancel, + this.barTopDockSite, + this.barBottomDockSite, + this.barLeftDockSite, + this.barRightDockSite}); + this.MinimizeBox = false; + this.Name = "BarEditor"; + this.Text = "DotNetBar Editor"; + this.Closing += new System.ComponentModel.CancelEventHandler(this.FormClosing); + this.Load += new EventHandler(this.FormLoad); + this.panel1.ResumeLayout(false); + this.ResumeLayout(false); + + } + #endregion + + private void FormLoad(object sender, EventArgs e) + { + try + { + Microsoft.Win32.RegistryKey key=Microsoft.Win32.Registry.LocalMachine; + string helpfile=""; + try + { + key=key.OpenSubKey("Software\\DevComponents\\DotNetBar"); + helpfile=key.GetValue("InstallationFolder","").ToString(); + } + finally{key.Close();} + + if(helpfile.Substring(helpfile.Length-1,1)!="\\") + helpfile+="\\"; + + if(System.IO.File.Exists(helpfile+"dotnetbar.chm")) + helpfile+="dotnetbar.chm"; + else + helpfile=""; + + if(helpfile!="") + m_HtmlHelp=new HTMLHelp(this,helpfile); + } + catch(Exception) + { + } + + // Load position if any + try + { + Microsoft.Win32.RegistryKey key=Microsoft.Win32.Registry.CurrentUser; + key=key.OpenSubKey("Software\\DevComponents\\DotNetBar"); + if(key!=null) + { + try + { + string s=key.GetValue("DesignerPosition","").ToString(); + if(s!="") + { + if(s=="1") + { + this.WindowState=FormWindowState.Maximized; + } + else + { + string[] arr=s.Split(','); + if(arr.Length==4) + { + Rectangle r=new Rectangle(int.Parse(arr[0]),int.Parse(arr[1]),int.Parse(arr[2]),int.Parse(arr[3])); + foreach(Screen screen in Screen.AllScreens) + { + if(screen.Bounds.IntersectsWith(r)) + { + this.StartPosition=FormStartPosition.Manual; + this.DesktopLocation=r.Location; + this.Size=r.Size; + break; + } + } + } + } + } + s=key.GetValue("DesignerPanelSize","").ToString(); + barTree.Width=int.Parse(s); + } + finally + { + key.Close(); + } + } + } + catch(Exception) + { + } + } + + #region Toolbar Definition Code + private void CreateToolbar() + { + Bar bar, barToolbar; + ButtonItem item, item2, item3, popupmain; + ButtonItem popup=new ButtonItem("popup"); + barManager.Items.Add(popup); + bar=new Bar("Main Menu"); + barManager.Bars.Add(bar); + bar.MenuBar=true; + bar.Stretch=true; + + barToolbar=new Bar("Item Navigation"); + barManager.Bars.Add(barToolbar); + + // File Menu + item=new ButtonItem("file"); + item.Text="&File"; + item.PopupType=ePopupType.Menu; + bar.Items.Add(item); + item2=new ButtonItem("open"); + item2.Shortcuts.Add(eShortcut.CtrlO); + item.SubItems.Add(item2); + item2.Text="&Open definition..."; + item2.ImageIndex=4; + barToolbar.Items.Add(item2.Copy()); + + item2=new ButtonItem("save"); + item2.Shortcuts.Add(eShortcut.CtrlS); + item.SubItems.Add(item2); + item2.Text="&Save definition..."; + item2.ImageIndex=5; + barToolbar.Items.Add(item2.Copy()); + item2.BeginGroup=true; + + item2=new ButtonItem("saveas"); + item2.Text="&Save definition as..."; + item.SubItems.Add(item2); + + item2=new ButtonItem("loadbar"); + item2.Shortcuts.Add(eShortcut.CtrlL); + item.SubItems.Add(item2); + item2.Text="Load Bar..."; + barManager.Items.Add(item2.Copy()); + item2.BeginGroup=true; + item2.Enabled=true; + + item2=new ButtonItem("savebaras"); + item2.Shortcuts.Add(eShortcut.CtrlD); + item.SubItems.Add(item2); + item2.Text="Save Bar as..."; + barManager.Items.Add(item2.Copy()); + item2.Enabled=false; + + item2=new ButtonItem("close"); + item2.Text="&Close Designer"; + item2.BeginGroup=true; + item.SubItems.Add(item2); + + // Tools + item=new ButtonItem("tools"); + item.Text="&Tools"; + item.PopupType=ePopupType.Menu; + bar.Items.Add(item); + item2=new ButtonItem("barscreation","Create Bar"); + item.SubItems.Add(item2); + popupmain=item2.Copy() as ButtonItem; + popup.SubItems.Add(popupmain); + if(m_Bar!=null) + item2.Visible=false; + else if(m_DotNetBar.LeftDockSite==null && m_DotNetBar.RightDockSite==null && m_DotNetBar.TopDockSite==null && m_DotNetBar.BottomDockSite==null) + item2.Enabled=false; + item3=new ButtonItem("createbar"); + item3.Text="&Toolbar"; + item2.SubItems.Add(item3); + popupmain.SubItems.Add(item3.Copy()); + item3=new ButtonItem("createmenubar"); + item3.Text="&Menu Bar"; + item2.SubItems.Add(item3); + popupmain.SubItems.Add(item3.Copy()); + item3=new ButtonItem("createstatusbar","&Status Bar"); + item2.SubItems.Add(item3); + popupmain.SubItems.Add(item3.Copy()); + item3=new ButtonItem("createdockwindow","&Dockable Window"); + item2.SubItems.Add(item3); + popupmain.SubItems.Add(item3.Copy()); + item3=new ButtonItem("createtaskpane","&Task Pane"); + item2.SubItems.Add(item3); + popupmain.SubItems.Add(item3.Copy()); + + item2=new ButtonItem("buttonitem"); + item2.Text="Add &ButtonItem"; + item2.BeginGroup=true; + item.SubItems.Add(item2); + popup.SubItems.Add(item2.Copy()); + item2=new ButtonItem("textboxitem"); + item2.Text="Add &TextBoxItem"; + item.SubItems.Add(item2); + popup.SubItems.Add(item2.Copy()); + item2=new ButtonItem("comboboxitem"); + item2.Text="Add &ComboBoxItem"; + item.SubItems.Add(item2); + popup.SubItems.Add(item2.Copy()); + item2=new ButtonItem("labelitem"); + item2.Text="Add &LabelItem"; + item.SubItems.Add(item2); + popup.SubItems.Add(item2.Copy()); + // Progress Bar Item + item2=new ButtonItem("progressbaritem"); + item2.Tooltip="Displays a progress bar."; + item2.Text="Add &ProgressBarItem"; + item.SubItems.Add(item2); + popup.SubItems.Add(item2.Copy()); + + item2=new ButtonItem("customizeitem"); + item2.BeginGroup=true; + item2.Tooltip="Lets end users hide/show Bar items as well as open the Customize dialog."; + item2.Text="Add Custo&mizeItem"; + item.SubItems.Add(item2); + popup.SubItems.Add(item2.Copy()); + item2=new ButtonItem("mdiwindowlistitem"); + item2.Tooltip="Displays list of MDI Child forms."; + item2.Text="Add &MdiWindowListItem"; + item.SubItems.Add(item2); + popup.SubItems.Add(item2.Copy()); + item2=new ButtonItem("controlcontaineritem"); + item2.Tooltip="Allows you to host any Control on Bar or Menu-bar."; + item2.Text="Add &ControlContainerItem"; + item.SubItems.Add(item2); + popup.SubItems.Add(item2.Copy()); + item2=new ButtonItem("dockcontaineritem"); + item2.Tooltip="Helps you create dockable windows."; + item2.Text="Add &DockContainerItem"; + item.SubItems.Add(item2); + popup.SubItems.Add(item2.Copy()); + + // Pop-up specific items + item2=new ButtonItem("copyto"); + item2.Text="Copy To"; + item2.BeginGroup=true; + item2.PopupType=ePopupType.Menu; + popup.SubItems.Add(item2); + item2=new ButtonItem("moveto"); + item2.Text="Move To"; + item2.PopupType=ePopupType.Menu; + popup.SubItems.Add(item2); + + item2=new ButtonItem("delselected"); + item.SubItems.Add(item2); + item2.Text="&Delete Selected Item"; + item2.BeginGroup=true; + item2.ImageIndex=7; + popup.SubItems.Add(item2.Copy()); + + // Help + item=new ButtonItem("help"); + item.Text="&Help"; + item.PopupType=ePopupType.Menu; + bar.Items.Add(item); + item2=new ButtonItem("contents"); + item2.Text="&Contents..."; + item.SubItems.Add(item2); +// item2=new ButtonItem("index"); +// item2.Text="&Index..."; +// item.SubItems.Add(item2); +// item2=new ButtonItem("search"); +// item2.Text="&Search..."; +// item.SubItems.Add(item2); + item2=new ButtonItem("about"); + item2.Text="&About"; + item2.BeginGroup=true; + item.SubItems.Add(item2); + + bar.DockSide=eDockSide.Top; + + // Create left bar with the item navigation buttons + item=new ButtonItem("addnewitems"); + barToolbar.Items.Add(item); + item.PopupType=ePopupType.Menu; + item.ImageIndex=6; + item.Text="Create new item"; + item.Tooltip="Press to see available items that can be created"; + item.BeginGroup=true; + item.Enabled=true; + item.SubItems.Add(barManager.Items["buttonitem"].Copy()); + item.SubItems.Add(barManager.Items["textboxitem"].Copy()); + item.SubItems.Add(barManager.Items["comboboxitem"].Copy()); + item.SubItems.Add(barManager.Items["customizeitem"].Copy()); + item.SubItems.Add(barManager.Items["mdiwindowlistitem"].Copy()); + item.SubItems.Add(barManager.Items["controlcontaineritem"].Copy()); + item.SubItems.Add(barManager.Items["dockcontaineritem"].Copy()); + item.SubItems.Add(barManager.Items["progressbaritem"].Copy()); + barToolbar.Items.Add(barManager.Items["delselected"].Copy()); + + + item=new ButtonItem("moveleft"); + barToolbar.Items.Add(item); + item.ImageIndex=0; + item.Text="Move Left"; + item.Tooltip="Move selected item left"; + item.BeginGroup=true; + item.Enabled=false; + item.ClickAutoRepeat=true; + barManager.Items.Add(item.Copy()); + + item=new ButtonItem("moveright"); + barToolbar.Items.Add(item); + item.ImageIndex=1; + item.Text="Move Right"; + item.Tooltip="Move selected item right"; + item.Enabled=false; + item.ClickAutoRepeat=true; + barManager.Items.Add(item.Copy()); + + item=new ButtonItem("moveup"); + barToolbar.Items.Add(item); + item.ImageIndex=2; + item.Text="Move Up"; + item.Tooltip="Move selected item up"; + item.Enabled=false; + item.ClickAutoRepeat=true; + barManager.Items.Add(item.Copy()); + + item=new ButtonItem("movedown"); + barToolbar.Items.Add(item); + item.ImageIndex=3; + item.Text="Move Down"; + item.Tooltip="Move selected item down"; + item.Enabled=false; + item.ClickAutoRepeat=true; + barManager.Items.Add(item.Copy()); + + item=new ButtonItem("synccat"); + barToolbar.Items.Add(item); + item.ImageIndex=8; + item.Text="Sync Categories"; + item.Tooltip="Recreates Categories from your current definition."; + item.Enabled=true; + item.ButtonStyle=eButtonStyle.ImageAndText; + item.ClickAutoRepeat=false; + + barToolbar.DockLine=1; + barToolbar.DockSide=eDockSide.Top; + + popup=new ButtonItem("resetimagepopup"); + item=new ButtonItem("resetimage","Reset"); + popup.SubItems.Add(item); + barManager.ContextMenus.Add(popup); + + barManager.Style=eDotNetBarStyle.Office2003; + + } + #endregion + + protected void CloseClick (object sender, System.EventArgs e) + { + this.Close(); + } + + private void RefreshView() + { + barTree.Nodes.Clear(); + + if(m_Bar!=null) + { + try + { + this.Cursor=Cursors.WaitCursor; + m_BarsNode=barTree.Nodes.Add("Bar"); + m_BarsNode.ImageIndex=2; + m_BarsNode.SelectedImageIndex=2; + + TreeNode barNode=m_BarsNode.Nodes.Add(m_Bar.Text); + barNode.Tag=m_Bar; + barNode.ImageIndex=1; + barNode.SelectedImageIndex=1; + foreach(BaseItem objItem in m_Bar.Items) + { + TreeNode itemNode=barNode.Nodes.Add(GetTreeItemText(objItem)); + itemNode.Tag=objItem; + + itemNode.ImageIndex=GetItemImageIndex(objItem); + itemNode.SelectedImageIndex=itemNode.ImageIndex; + + AddSubItems(objItem,itemNode); + } + m_BarsNode.Expand(); + barNode.Expand(); + } + finally + { + this.Cursor=Cursors.Arrow; + } + return; + } + + if(m_DotNetBar==null) + return; + + this.Cursor=Cursors.WaitCursor; + + if(m_DotNetBar.TopDockSite==null && m_DotNetBar.BottomDockSite==null && m_DotNetBar.LeftDockSite==null && m_DotNetBar.RightDockSite==null) + { + m_CategoriesNode=null; + m_BarsNode=null; + } + else + { + m_CategoriesNode=barTree.Nodes.Add("Categories"); + m_CategoriesNode.ImageIndex=5; + m_CategoriesNode.SelectedImageIndex=5; + + m_BarsNode=barTree.Nodes.Add("Bars"); + m_BarsNode.ImageIndex=2; + m_BarsNode.SelectedImageIndex=2; + } + + m_PopupsNode=barTree.Nodes.Add("Context Menus"); + m_PopupsNode.ImageIndex=12; + m_PopupsNode.SelectedImageIndex=12; + + if(m_BarsNode!=null) + { + foreach(Bar bar in m_DotNetBar.Bars) + { + TreeNode barNode=m_BarsNode.Nodes.Add(bar.Text); + barNode.Tag=bar; + barNode.ImageIndex=1; + barNode.SelectedImageIndex=1; + foreach(BaseItem objItem in bar.Items) + { + TreeNode itemNode=barNode.Nodes.Add(GetTreeItemText(objItem)); + itemNode.Tag=objItem; + + itemNode.ImageIndex=GetItemImageIndex(objItem); + itemNode.SelectedImageIndex=itemNode.ImageIndex; + + AddSubItems(objItem,itemNode); + } + } + } + + // Load nodes from items + m_catTable.Clear(); + if(m_CategoriesNode!=null) + { + foreach(DictionaryEntry o in m_DotNetBar.Items) + { + BaseItem objItem=o.Value as BaseItem; + TreeNode itemNode=CategorizeItem(objItem); + itemNode.Tag=objItem; + + itemNode.ImageIndex=GetItemImageIndex(objItem); + itemNode.SelectedImageIndex=itemNode.ImageIndex; + + AddSubItems(objItem,itemNode); + } + } + + // Load all popups + foreach(BaseItem objItem in m_DotNetBar.ContextMenus) + { + TreeNode itemNode=m_PopupsNode.Nodes.Add(GetTreeItemText(objItem)); + itemNode.Tag=objItem; + + itemNode.ImageIndex=GetItemImageIndex(objItem); + itemNode.SelectedImageIndex=itemNode.ImageIndex; + + AddSubItems(objItem,itemNode); + } + + if(m_BarsNode!=null) + m_BarsNode.Expand(); + if(m_CategoriesNode!=null) + m_CategoriesNode.Expand(); + m_PopupsNode.Expand(); + + this.Cursor=Cursors.Arrow; + } + private void AddSubItems(BaseItem objItem, TreeNode parentNode) + { + if(objItem.SubItems.Count==0) + return; + foreach(BaseItem objChild in objItem.SubItems) + { + TreeNode itemNode=parentNode.Nodes.Add(GetTreeItemText(objChild)); + itemNode.Tag=objChild; + + itemNode.ImageIndex=GetItemImageIndex(objChild); + itemNode.SelectedImageIndex=itemNode.ImageIndex; + + AddSubItems(objChild,itemNode); + } + } + // TODO: Make sure that when designing the Menu Bar when new item is added default + // PopupType is MENU not TOOLBAR + private void ItemSelected(object sender,TreeViewEventArgs e) + { + barTree.LabelEdit=false; + if(e.Node.Tag==null) + { + propertyGrid1.SelectedObject=null; + return; + } + + if(e.Node.Tag is BaseItem) + { + propertyGrid1.SelectedObject=e.Node.Tag; + barTree.LabelEdit=true; + + // Now way to detect when Items collection has changed, reset changed flag if combo box is selected... + if(e.Node.Tag is ComboBoxItem) + m_DataChanged=true; + } + else if(e.Node.Tag is Bar) + { + propertyGrid1.SelectedObject=(Bar)e.Node.Tag; + + } + else + { + propertyGrid1.SelectedObject=null; + } + + } + + private void BeforeItemSelect(object sender, System.Windows.Forms.TreeViewCancelEventArgs e) + { + // Disable/Enable toolbar items... + bool bLeftEnabled=false, bRightEnabled=false, bUpEnabled=false, bDownEnabled=false; + + BaseItem popupItem=barManager.Items["popup"]; + + if(e.Node!=null && e.Node.Tag is BaseItem) + { + if(e.Node.Parent==m_PopupsNode) + { + bRightEnabled=true; + } + else + { + BaseItem objItem=e.Node.Tag as BaseItem; + int i=0; + if(objItem.Parent!=null) + i=objItem.Parent.SubItems.IndexOf(objItem); + else + i=e.Node.Index; + if(i>0) + { + bUpEnabled=true; + bRightEnabled=true; + } + int iCount=0; + if(objItem.Parent!=null) + iCount=objItem.Parent.SubItems.Count-1; + else + iCount=e.Node.Parent.Nodes.Count-1; + + if(i0) + if(MessageBox.Show(this,"Are you sure you want to delete selected item?","DotNetBar Editor",MessageBoxButtons.YesNo,MessageBoxIcon.Question)==DialogResult.No) + return; + + if(barTree.SelectedNode.Tag is BaseItem) + { + BaseItem item=barTree.SelectedNode.Tag as BaseItem; + Bar cont=item.ContainerControl as Bar; + + TreeNode topParentNode=barTree.SelectedNode; + while(topParentNode.Parent!=null) + topParentNode=topParentNode.Parent; + + if(item.Parent!=null) + item.Parent.SubItems.Remove(item); + else if(topParentNode==m_CategoriesNode) + m_DotNetBar.Items.Remove(item); + else if(barTree.SelectedNode.Parent==m_PopupsNode) + m_DotNetBar.ContextMenus.Remove(item); + + if(_barDesigner!=null) + _barDesigner.DestroyComponent(item); + else + item.Dispose(); + + barTree.SelectedNode.Tag=null; + TreeNode parentNode=barTree.SelectedNode.Parent; + barTree.Nodes.Remove(barTree.SelectedNode); + // If it is last node under one of the categories remove parent too + if(parentNode!=null && parentNode.Parent==m_CategoriesNode && parentNode.Nodes.Count==0) + barTree.Nodes.Remove(parentNode); + if(cont!=null) + cont.RecalcLayout(); + + } + else if(barTree.SelectedNode.Tag is Bar) + { + Bar bar=barTree.SelectedNode.Tag as Bar; + + m_DotNetBar.Bars.Remove(bar); + + barTree.SelectedNode.Tag=null; + barTree.Nodes.Remove(barTree.SelectedNode); + } + else if(m_CategoriesNode!=null && barTree.SelectedNode.Parent==m_CategoriesNode) + { + // Delete all items within this category + foreach(TreeNode node in barTree.SelectedNode.Nodes) + { + objItem=node.Tag as BaseItem; + if(objItem!=null) + { + m_DotNetBar.Items.Remove(objItem); + objItem.Dispose(); + } + node.Tag=null; + } + barTree.SelectedNode.Remove(); + } + + return; + } + else if(objItem.Name=="open") + { + if(m_OpenFileDialog.ShowDialog()==DialogResult.OK && System.IO.File.Exists(m_OpenFileDialog.FileName)) + { + m_DotNetBar.Bars.Owner.LoadDefinition(m_OpenFileDialog.FileName); + m_DefinitionFileName=m_OpenFileDialog.FileName; + RefreshView(); + m_DataChanged=true; + } + return; + } + else if(objItem.Name=="save" && m_DefinitionFileName!="") + { + m_DotNetBar.Bars.Owner.SaveDefinition(m_DefinitionFileName); + return; + } + else if(objItem.Name=="saveas" || objItem.Name=="save" && m_DefinitionFileName=="") + { + if(m_SaveFileDialog.ShowDialog()==DialogResult.OK) + { + m_DotNetBar.Bars.Owner.SaveDefinition(m_SaveFileDialog.FileName); + m_DefinitionFileName=m_SaveFileDialog.FileName; + } + return; + } + else if(objItem.Name=="savebaras") + { + // Save currently selected bar + if(barTree.SelectedNode==null || !(barTree.SelectedNode.Tag is Bar)) + return; + + Bar bar=barTree.SelectedNode.Tag as Bar; + string stitle=m_SaveFileDialog.Title; + string defaultExt=m_SaveFileDialog.DefaultExt; + string fileName=m_SaveFileDialog.FileName; + string filter=m_SaveFileDialog.Filter; + + m_SaveFileDialog.Title="Save Bar Definition"; + m_SaveFileDialog.DefaultExt = "xml"; + m_SaveFileDialog.FileName = (bar.Name!=""?bar.Name:"MyBar"); + m_SaveFileDialog.Filter = "DotNetBar Bar Files (*.xml)|*.xml|All Files (*.*)|*.*"; + + if(m_SaveFileDialog.ShowDialog()==DialogResult.OK) + { + bar.SaveDefinition(m_SaveFileDialog.FileName); + } + + m_SaveFileDialog.Title=stitle; + m_SaveFileDialog.DefaultExt=defaultExt; + m_SaveFileDialog.FileName=fileName; + m_SaveFileDialog.Filter=filter; + + return; + } + else if(objItem.Name=="loadbar") + { + string defaultExt=m_OpenFileDialog.DefaultExt; + string filter=m_OpenFileDialog.Filter; + m_OpenFileDialog.DefaultExt="xml"; + m_OpenFileDialog.Filter = "DotNetBar Bar Files (*.xml)|*.xml|All Files (*.*)|*.*"; + if(m_OpenFileDialog.ShowDialog()==DialogResult.OK && System.IO.File.Exists(m_OpenFileDialog.FileName)) + { + Bar bar=new Bar(); + try + { + bar.LoadDefinition(m_OpenFileDialog.FileName); + } + catch(Exception ex) + { + MessageBox.Show("File '"+m_OpenFileDialog.FileName+"' does not appear to be valid Bar file.\n\rException has been generated while loading: "+ex.Source+": "+ex.Message+"\n\r"+ex.StackTrace); + return; + } + bar.Dispose(); + bar=new Bar(); + m_DotNetBar.SuspendLayout=true; + m_DotNetBar.Bars.Add(bar); + bar.LoadDefinition(m_OpenFileDialog.FileName); + m_DotNetBar.SuspendLayout=false; + } + m_OpenFileDialog.DefaultExt=defaultExt; + m_OpenFileDialog.Filter=filter; + } + else if(objItem.Name=="moveleft" || objItem.Name=="moveright" || objItem.Name=="moveup" || objItem.Name=="movedown") + MoveSelectedItem(objItem.Name); + else if(objItem.Name=="addnewitems") + objItem.Expanded=true; + else if(objItem.Name=="synccat") + { + RescanCategories(); + return; + } + + m_DataChanged=true; + + // Creation of new items only below this point + if(objItem.Name!="buttonitem" && objItem.Name!="textboxitem" && objItem.Name!="comboboxitem" && objItem.Name!="customizeitem" && objItem.Name!="labelitem" && objItem.Name!="mdiwindowlistitem" && objItem.Name!="controlcontaineritem" && objItem.Name!="dockcontaineritem" && objItem.Name!="progressbaritem") + return; + + // Item creation buttons only below!!! + if(objItem.Name=="buttonitem") + { + ButtonItem btn=CreateObject(typeof(ButtonItem)) as ButtonItem; + btn.Text="New Button"; + newItem=btn; + } + else if(objItem.Name=="textboxitem") + { + TextBoxItem tb=CreateObject(typeof(TextBoxItem)) as TextBoxItem; + tb.Text="Text Box"; + newItem=tb; + } + else if(objItem.Name=="comboboxitem") + { + ComboBoxItem cb=CreateObject(typeof(ComboBoxItem)) as ComboBoxItem; + cb.Text="Combo Box"; + newItem=cb; + } + else if(objItem.Name=="customizeitem") + { + CustomizeItem cust=CreateObject(typeof(CustomizeItem)) as CustomizeItem; + newItem=cust; + } + else if(objItem.Name=="labelitem") + { + LabelItem li=CreateObject(typeof(LabelItem)) as LabelItem; + li.Text="Label"; + li.BorderType=eBorderType.SingleLine; + newItem=li; + } + else if(objItem.Name=="mdiwindowlistitem") + { + MdiWindowListItem mdi=CreateObject(typeof(MdiWindowListItem)) as MdiWindowListItem; + mdi.Text="MDI Window List"; + newItem=mdi; + } + else if(objItem.Name=="controlcontaineritem") + { + ControlContainerItem cci=CreateObject(typeof(ControlContainerItem)) as ControlContainerItem; + newItem=cci; + } + else if(objItem.Name=="dockcontaineritem") + { + DockContainerItem dci=CreateObject(typeof(DockContainerItem)) as DockContainerItem; + dci.Text="Dockable Window"; + newItem=dci; + } + else if(objItem.Name=="progressbaritem") + { + ProgressBarItem pb=CreateObject(typeof(ProgressBarItem)) as ProgressBarItem; + pb.Text="Progress Bar"; + pb.SetDesignMode(true); + pb.Style=m_DotNetBar.Style; + pb.ResetBackgroundStyle(); + newItem=pb; + } + + if(_barDesigner==null) + { + string name="item_"; + long id=newItem.Id; + if(m_DotNetBar!=null) + { + while(m_DotNetBar.GetItem(name+id,true)!=null) + id++; + } + else if(m_Bar!=null) + { + while(m_Bar.GetItem(name+id)!=null) + id++; + } + newItem.Name=name+id; + } + + if(barTree.SelectedNode.Tag is BaseItem) + { + newItem.Style=((BaseItem)barTree.SelectedNode.Tag).Style; + if(barTree.SelectedNode.Tag is PopupItem && newItem is PopupItem) + ((PopupItem)newItem).PopupType=((PopupItem)barTree.SelectedNode.Tag).PopupType; + } + else if(barTree.SelectedNode.Tag is Bar) + { + newItem.Style=((Bar)barTree.SelectedNode.Tag).Style; + if(newItem is PopupItem && ((Bar)barTree.SelectedNode.Tag).MenuBar) + ((PopupItem)newItem).PopupType=ePopupType.Menu; + } + + // We need to determine is new item being added to the Categories + TreeNode itemNode=barTree.SelectedNode; + while(itemNode.Parent!=null) + itemNode=itemNode.Parent; + + if(itemNode==m_CategoriesNode) + { + // Assign category to new item + if(barTree.SelectedNode==m_CategoriesNode) + newItem.Category="(Untitled)"; + else if(barTree.SelectedNode.Parent==m_CategoriesNode) + newItem.Category=barTree.SelectedNode.Text; + else + newItem.Category=((BaseItem)barTree.SelectedNode.Tag).Category; + + m_DotNetBar.Items.Add(newItem); + itemNode=CategorizeItem(newItem); + } + else if(itemNode==m_PopupsNode) + { + //if(barTree.SelectedNode.Tag is BaseItem && barTree.SelectedNode.Parent.Tag is BaseItem) + if(barTree.SelectedNode.Tag is BaseItem) + { + //itemNode=barTree.SelectedNode.Parent.Nodes.Add(GetTreeItemText(newItem)); + itemNode=barTree.SelectedNode.Nodes.Add(GetTreeItemText(newItem)); + + //BaseItem objParent=((BaseItem)barTree.SelectedNode.Tag).Parent; + BaseItem objParent=(BaseItem)barTree.SelectedNode.Tag; + int iPos=-1; + // New Items are always added before any system items which are by default kept at the end + if(objParent.SubItems.Count>0 && !newItem.SystemItem) + { + iPos=GetAppendPosition(objParent); + } + objParent.SubItems.Add(newItem,iPos); + } + else + { + itemNode=m_PopupsNode.Nodes.Add(GetTreeItemText(newItem)); + m_DotNetBar.ContextMenus.Add(newItem); + } + } + else + { + Control cont=null; + if(barTree.SelectedNode.Tag is BaseItem) + { + //itemNode=barTree.SelectedNode.Parent.Nodes.Add(GetTreeItemText(newItem)); + itemNode=barTree.SelectedNode.Nodes.Add(GetTreeItemText(newItem)); + //BaseItem objParent=((BaseItem)barTree.SelectedNode.Tag).Parent; + BaseItem objParent=(BaseItem)barTree.SelectedNode.Tag; + int iPos=-1; + // New Items are always added before any system items which are by default kept at the end + if(objParent.SubItems.Count>0 && !newItem.SystemItem) + { + iPos=GetAppendPosition(objParent); + } + objParent.SubItems.Add(newItem,iPos); + cont=newItem.ContainerControl as Control; + if(cont==null) + ((BaseItem)barTree.SelectedNode.Tag).Refresh(); + + } + else if(barTree.SelectedNode.Tag is Bar) + { + itemNode=barTree.SelectedNode.Nodes.Add(GetTreeItemText(newItem)); + Bar bar=(Bar)barTree.SelectedNode.Tag; + int iPos=-1; + // New Items are always added before any system items which are by default kept at the end + if(bar.Items.Count>0 && !newItem.SystemItem) + { + iPos=GetAppendPosition(bar.ItemsContainer); + } + bar.Items.Add(newItem,iPos); + cont=bar; + } + if(cont!=null && cont is Bar) + ((Bar)cont).RecalcLayout(); + } + + itemNode.Tag=newItem; + itemNode.ImageIndex=GetItemImageIndex(newItem); + itemNode.SelectedImageIndex=itemNode.ImageIndex; + + itemNode.EnsureVisible(); + barTree.SelectedNode=itemNode; + //itemNode.BeginEdit(); + } + + public void RescanCategories() + { + if(m_DotNetBar==null) + return; + if(m_DotNetBar.Bars.Count==0) + return; + m_DotNetBar.Items.Clear(); + foreach(Bar bar in m_DotNetBar.Bars) + { + foreach(BaseItem item in bar.Items) + AutoCategorizeItem(item); + } + m_DataChanged=true; + RefreshView(); + } + + private void AutoCategorizeItem(BaseItem item) + { + if(item.Category!="" && item.Name!="" && !m_DotNetBar.Items.Contains(item.Name)) + m_DotNetBar.Items.Add(item.Copy()); + foreach(BaseItem i in item.SubItems) + AutoCategorizeItem(i); + } + + private void MoveSelectedItem(string Direction) + { + if(barTree.SelectedNode==null) + return; + m_DataChanged=true; + BaseItem objItem=barTree.SelectedNode.Tag as BaseItem; + if(objItem==null) + return; + + bool bCategoryItem=false; + if(barTree.SelectedNode.Parent==m_CategoriesNode) + bCategoryItem=true; + + bool bPopupsItem=false; + if(barTree.SelectedNode.Parent==m_PopupsNode) + bPopupsItem=true; + + + TreeNode selNode=barTree.SelectedNode; + TreeNode parentNode=selNode.Parent; + + BaseItem objParent=objItem.Parent; + + int i=0; + if(objParent!=null) + i=objParent.SubItems.IndexOf(objItem); + else + i=selNode.Index; + + if(Direction=="moveup" && i>0) + { + if(objParent!=null) + { + objParent.SubItems.Remove(objItem); + objParent.SubItems.Add(objItem,i-1); + if(objParent.ContainerControl is Bar) + ((Bar)objParent.ContainerControl).RecalcLayout(); + } + + i=selNode.Index; + selNode.Remove(); + parentNode.Nodes.Insert(i-1,selNode); + barTree.SelectedNode=selNode; + selNode.EnsureVisible(); + } + else if(Direction=="moveright" && i>0) + { + BaseItem objNewParent=null; + + if(bCategoryItem) + m_DotNetBar.Items.Remove(objItem); + else if(bPopupsItem) + m_DotNetBar.ContextMenus.Remove(objItem); + + if(objParent!=null) + { + objNewParent=objParent.SubItems[i-1]; + objParent.SubItems.Remove(objItem); + if(objParent.ContainerControl is Bar) + ((Bar)objParent.ContainerControl).RecalcLayout(); + } + else + { + objNewParent=selNode.PrevNode.Tag as BaseItem; + } + objNewParent.SubItems.Add(objItem,GetAppendPosition(objNewParent)); + objNewParent.Refresh(); + if(objNewParent.ContainerControl is Bar) + ((Bar)objNewParent.ContainerControl).RecalcLayout(); + + i=selNode.Index; + TreeNode newParent=selNode.PrevNode; + selNode.Remove(); + newParent.Nodes.Add(selNode); + barTree.SelectedNode=selNode; + selNode.EnsureVisible(); + } + else if(Direction=="movedown" && ((objParent!=null && i=0;i--) + { + if(objParent.SubItems[i].SystemItem) + iPos=i; + else + break; + } + return iPos; + } + + private void OnPropertyValueChanged(object s, System.Windows.Forms.PropertyValueChangedEventArgs e) + { + m_DataChanged=true; + // If user changes the category of the item that is in categories we need to + // reflect that change and move item to the right category + TreeNode node=barTree.SelectedNode; + BaseItem item=node.Tag as BaseItem; + + if(e.ChangedItem.PropertyDescriptor.Name=="Category" && e.ChangedItem.Value!=e.OldValue) + { + if(node.Tag==null || !(node.Tag is BaseItem)) + return; + while(node.Parent!=null) + node=node.Parent; + if(node!=m_CategoriesNode) + return; + + node=barTree.SelectedNode; + BaseItem objItem=node.Tag as BaseItem; + node.Remove(); + node=CategorizeItem(objItem); + node.ImageIndex=GetItemImageIndex(objItem); + node.SelectedImageIndex=node.ImageIndex; + AddSubItems(objItem,node); + node.EnsureVisible(); + barTree.SelectedNode=node; + } + else if(e.ChangedItem.PropertyDescriptor.Name=="Name" && e.ChangedItem.Value!=e.OldValue && !m_ShowItemText) + { + node.Text=(string)e.ChangedItem.Value; + } + else if(e.ChangedItem.PropertyDescriptor.Name=="Text" && e.ChangedItem.Value!=e.OldValue && m_ShowItemText) + { + node.Text=(string)e.ChangedItem.Value; + } + else if(e.ChangedItem.PropertyDescriptor.Name=="DockLine" || e.ChangedItem.PropertyDescriptor.Name=="DockOffset") + { + Bar bar=node.Tag as Bar; + if(bar!=null) + bar.RecalcLayout(); + } + + if(e.ChangedItem.PropertyDescriptor.Name=="Name" && m_DotNetBar!=null) + { + TreeNode parent=node; + while(parent.Parent!=null) + parent=parent.Parent; + if(parent==m_CategoriesNode) + { + if(m_DotNetBar.Items.Contains(e.ChangedItem.Value.ToString())) + { + item.Name=e.OldValue.ToString(); + propertyGrid1.Refresh(); + MessageBox.Show("Item with that name already exists."); + } + else + { + m_DotNetBar.Items.Remove(e.OldValue.ToString()); + m_DotNetBar.Items.Add(item); + } + } + } + + if(item!=null) + { + Bar barContainer=item.ContainerControl as Bar; + if(barContainer!=null) + barContainer.RecalcLayout(); + } + } + + private TreeNode CategorizeItem(BaseItem newItem) + { + // Assign item to category + if(newItem.Category=="") + newItem.Category="(Untitled)"; + + TreeNode parentNode=null; + if(m_catTable.ContainsKey(newItem.Category)) + parentNode=m_catTable[newItem.Category] as TreeNode; + else + { + parentNode=m_CategoriesNode.Nodes.Add(newItem.Category); + parentNode.ImageIndex=5; + parentNode.SelectedImageIndex=5; + m_catTable.Add(newItem.Category,parentNode); + } + + TreeNode newNode=parentNode.Nodes.Add(GetTreeItemText(newItem)); + newNode.ImageIndex=GetItemImageIndex(newItem); + newNode.SelectedImageIndex=newNode.ImageIndex; + newNode.Tag=newItem; + return newNode; + } + + private void CopyMoveToClick(object sender, System.EventArgs e) + { + BaseItem item=sender as BaseItem; + BaseItem itemSel=barTree.SelectedNode.Tag as BaseItem; + BaseItem itemOriginal=barTree.SelectedNode.Tag as BaseItem; + + bool bMove=(item.Parent.Name=="moveto"); + if(!bMove) + { + itemSel=itemSel.Copy(); + if((Control.ModifierKeys & Keys.Control)==Keys.Control) + itemSel.Name=itemOriginal.Name; + else + itemSel.Name="item_"+itemSel.Id; + } + + if((item.Tag is string && (string)item.Tag=="cat") || item.Name=="tocategories") + { + // To Categories + if(item.Name!="tocategories") + itemSel.Category=item.Text; + if(bMove) + { + if(itemSel.Parent!=null) + itemSel.Parent.SubItems.Remove(itemSel); + barTree.SelectedNode.Remove(); + } + if(m_DotNetBar.Items.Contains(itemSel.Name)) + { + string sDupName=itemSel.Name; + itemSel.Name="item_"+itemSel.Id; + MessageBox.Show("Item with name: '"+sDupName+"' already exists. Item that you are trying to move will be renamed."); + } + m_DotNetBar.Items.Add(itemSel); + barTree.SelectedNode=CategorizeItem(itemSel); + barTree.SelectedNode.EnsureVisible(); + } + else if(item.Name=="topopups" || item.Tag is BaseItem) + { + if(bMove) + { + if(itemSel.Parent!=null) + itemSel.Parent.SubItems.Remove(itemSel); + barTree.SelectedNode.Remove(); + } + + if(item.Name=="topopups") + { + TreeNode itemNode=m_PopupsNode.Nodes.Add(GetTreeItemText(itemSel)); + itemNode.Tag=itemSel; + itemNode.ImageIndex=GetItemImageIndex(itemSel); + itemNode.SelectedImageIndex=itemNode.ImageIndex; + AddSubItems(itemSel,itemNode); + m_DotNetBar.ContextMenus.Add(itemSel); + itemNode.EnsureVisible(); + } + else + { + BaseItem objParent=item.Tag as BaseItem; + objParent.SubItems.Add(itemSel); + foreach(TreeNode node in m_PopupsNode.Nodes) + { + if(node.Tag==objParent) + { + TreeNode itemNode=node.Nodes.Add(GetTreeItemText(itemSel)); + itemNode.Tag=itemSel; + itemNode.ImageIndex=GetItemImageIndex(itemSel); + itemNode.SelectedImageIndex=itemNode.ImageIndex; + AddSubItems(itemSel,itemNode); + itemNode.EnsureVisible(); + break; + } + } + } + } + else if(item.Tag is TreeNode) + { + // To Bar + TreeNode barNode=item.Tag as TreeNode; + Bar bar=barNode.Tag as Bar; + if(bMove) + { + if(itemSel.Parent!=null) + itemSel.Parent.SubItems.Remove(itemSel); + barTree.SelectedNode.Remove(); + } + + bar.Items.Add(itemSel,GetAppendPosition(bar.ItemsContainer)); + TreeNode itemNode=barNode.Nodes.Add(GetTreeItemText(itemSel)); + itemNode.Tag=itemSel; + itemNode.ImageIndex=GetItemImageIndex(itemSel); + itemNode.SelectedImageIndex=itemNode.ImageIndex; + AddSubItems(itemSel,itemNode); + barTree.SelectedNode=itemNode; + barTree.SelectedNode.EnsureVisible(); + bar.RecalcLayout(); + } + + // Clear Copy To and Move To + item=barManager.Items["popup"]; + item.SubItems["copyto"].SubItems.Clear(); + item.SubItems["moveto"].SubItems.Clear(); + } + + private void ItemEdited(object sender, System.Windows.Forms.NodeLabelEditEventArgs e) + { + if(e.CancelEdit) + return; + + BaseItem objItem=e.Node.Tag as BaseItem; + if(m_ShowItemText) + objItem.Text=e.Label; + else + objItem.Name=e.Label; + + propertyGrid1.Refresh(); + m_DataChanged=true; + } + + private string GetTreeItemText(BaseItem objItem) + { + if(objItem==null) + return ""; + + if(m_ShowItemText) + return objItem.Text; + else + return objItem.Name; + } + + private int GetItemImageIndex(BaseItem objItem) + { + int index=0; + if(objItem is ButtonItem) + { + index=7; + } + else if(objItem is ComboBoxItem) + { + index=8; + } + else if(objItem is TextBoxItem) + { + index=9; + } + else if(objItem is CustomizeItem) + { + index=10; + } + else if(objItem is LabelItem) + { + index=11; + } + return index; + } + + private void TreeKeyDown(object sender, System.Windows.Forms.KeyEventArgs e) + { + if(e.KeyCode==Keys.F2 && barTree.SelectedNode!=null && barTree.LabelEdit) + barTree.SelectedNode.BeginEdit(); + } + + private void GridViewMouseDown(object sender, EventArgs e) + { + if(propertyGrid1.SelectedGridItem==null) + return; + if(!(propertyGrid1.SelectedGridItem.PropertyDescriptor.PropertyType==typeof(System.Drawing.Image))) + return; + PopupItem popup=barManager.ContextMenus["resetimagepopup"] as PopupItem; + popup.PopupMenu(Control.MousePosition); + } + + private void FormClosing(object sender, System.ComponentModel.CancelEventArgs e) + { + m_GridViewSubclass.ReleaseHandle(); + m_GridViewSubclass=null; + + if(m_HtmlHelp!=null) + m_HtmlHelp.CloseHelpWindow(); + + // ColorScheme property when changed is not detected, so try to fix it here... + if(m_DotNetBar!=null) + { + foreach(Bar bar in m_DotNetBar.Bars) + { + if(bar.ColorScheme._DesignTimeSchemeChanged) + { + m_DataChanged=true; + bar.ColorScheme._DesignTimeSchemeChanged=false; + } + } + } + else if(m_Bar!=null) + { + if(m_Bar.ColorScheme._DesignTimeSchemeChanged) + { + m_DataChanged=true; + m_Bar.ColorScheme._DesignTimeSchemeChanged=false; + } + } + + + // Save form position + if(this.WindowState!=FormWindowState.Minimized) + { + string s=""; + if(this.WindowState==FormWindowState.Maximized) + { + s="1"; + } + else + { + s=this.DesktopLocation.X+","+this.DesktopLocation.Y+","+this.Width+","+this.Height; + } + try + { + Microsoft.Win32.RegistryKey key=Microsoft.Win32.Registry.CurrentUser; + key=key.CreateSubKey("Software\\DevComponents\\DotNetBar"); + key.SetValue("DesignerPosition",s); + // Save Panel size + key.SetValue("DesignerPanelSize",barTree.Width); + key.Close(); + } + catch(Exception) + { + } + } + } + + private class GridViewSubclass:NativeWindow + { + public event EventHandler OnRightMouseDown; + protected override void WndProc(ref Message m) + { + if(m.Msg==NativeFunctions.WM_CONTEXTMENU) + { + if(OnRightMouseDown!=null) + OnRightMouseDown(this,new EventArgs()); + return; + } + base.WndProc(ref m); + } + } + + public bool DataChanged + { + get { return m_DataChanged;} + set { m_DataChanged=value;} + } + + public DotNetBarManager FormBarManager + { + get + { + return barManager; + } + } + + private void LoadResourceImages() + { + Image img=null; + try + { + m_BarImages.Images.Clear(); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.MoveItemLeft.bmp"); + m_BarImages.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.MoveItemRight.bmp"); + m_BarImages.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.MoveItemUp.bmp"); + m_BarImages.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.MoveItemDown.bmp"); + m_BarImages.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.FileOpen.bmp"); + m_BarImages.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.FileSave.bmp"); + m_BarImages.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.CreateItem.bmp"); + m_BarImages.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.DeleteItem.bmp"); + m_BarImages.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.RescanCategories.bmp"); + m_BarImages.Images.Add(img,Color.Magenta); + + imageList.Images.Clear(); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.Item.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.Toolbar.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.Toolbars.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.Toolbar.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.Item.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.Folder.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.FolderOpen.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.ButtonItem.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.ComboItem.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.TextBoxItem.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.CustomizeItem.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.LableItem.bmp"); + imageList.Images.Add(img,Color.Magenta); + img=new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager),"BarEditorImages.PopupMenu.bmp"); + imageList.Images.Add(img,Color.Magenta); + + } + catch(Exception e) + { + MessageBox.Show("Could not load resource images. Exception was thrown: "+e.ToString()); + } + } + + private object CreateObject(Type type) + { + if(_barDesigner!=null) + return _barDesigner.CreateComponent(type); + else + return type.Assembly.CreateInstance(type.FullName); + } + } +} diff --git a/PROMS/DotNetBar Source Code/BarEditor.resx b/PROMS/DotNetBar Source Code/BarEditor.resx new file mode 100644 index 00000000..af96e84f --- /dev/null +++ b/PROMS/DotNetBar Source Code/BarEditor.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 419, 17 + + + 518, 17 + + + 298, 17 + + + 17, 17 + + + 159, 17 + + + BarEditor + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/ButtonItem.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/ButtonItem.bmp new file mode 100644 index 00000000..eff482aa Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/ButtonItem.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/ComboItem.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/ComboItem.bmp new file mode 100644 index 00000000..4b9f807a Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/ComboItem.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/CreateItem.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/CreateItem.bmp new file mode 100644 index 00000000..6eb00f55 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/CreateItem.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/CustomizeItem.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/CustomizeItem.bmp new file mode 100644 index 00000000..c5b6aa58 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/CustomizeItem.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/DeleteItem.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/DeleteItem.bmp new file mode 100644 index 00000000..96d9e054 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/DeleteItem.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/FileClose.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/FileClose.bmp new file mode 100644 index 00000000..d51e2df4 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/FileClose.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/FileCloseSol.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/FileCloseSol.bmp new file mode 100644 index 00000000..0d540644 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/FileCloseSol.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/FileNew.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/FileNew.bmp new file mode 100644 index 00000000..318ff541 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/FileNew.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/FileOpen.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/FileOpen.bmp new file mode 100644 index 00000000..520b24c4 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/FileOpen.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/FileOpenSol.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/FileOpenSol.bmp new file mode 100644 index 00000000..47d0de66 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/FileOpenSol.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/FileSave.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/FileSave.bmp new file mode 100644 index 00000000..9a43d0e2 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/FileSave.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/Folder.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/Folder.bmp new file mode 100644 index 00000000..e469bcc4 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/Folder.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/FolderOpen.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/FolderOpen.bmp new file mode 100644 index 00000000..6a24e1fb Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/FolderOpen.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/Item.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/Item.bmp new file mode 100644 index 00000000..e0c64c5f Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/Item.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/LableItem.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/LableItem.bmp new file mode 100644 index 00000000..4d5ca551 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/LableItem.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemDown.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemDown.bmp new file mode 100644 index 00000000..15adffd9 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemDown.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemLeft.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemLeft.bmp new file mode 100644 index 00000000..20c9c53e Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemLeft.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemRight.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemRight.bmp new file mode 100644 index 00000000..74574131 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemRight.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemUp.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemUp.bmp new file mode 100644 index 00000000..fbf0c715 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/MoveItemUp.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/PopupMenu.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/PopupMenu.bmp new file mode 100644 index 00000000..c3ebaf4d Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/PopupMenu.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/RescanCategories.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/RescanCategories.bmp new file mode 100644 index 00000000..75412cdf Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/RescanCategories.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/TextBoxItem.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/TextBoxItem.bmp new file mode 100644 index 00000000..b5896f4f Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/TextBoxItem.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/Toolbar.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/Toolbar.bmp new file mode 100644 index 00000000..4d56068c Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/Toolbar.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarEditorImages/Toolbars.bmp b/PROMS/DotNetBar Source Code/BarEditorImages/Toolbars.bmp new file mode 100644 index 00000000..4630ed96 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BarEditorImages/Toolbars.bmp differ diff --git a/PROMS/DotNetBar Source Code/BarFunctions.cs b/PROMS/DotNetBar Source Code/BarFunctions.cs new file mode 100644 index 00000000..081a4c02 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BarFunctions.cs @@ -0,0 +1,2363 @@ +using System; +using System.Drawing; +using System.Reflection; +using System.Xml; +using System.Resources; +using System.Collections; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using System.IO; +using System.Collections.Generic; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for BarFunctions. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class BarFunctions + { + public const int ANIMATION_INTERVAL = 100; + + private static string ms_ResourceName = ""; + const string DEFAULT_RESOURCE = ".Strings"; + private static bool m_ThemedOS = false; + private static bool m_IsVista = false; + private static bool _IsWindows7 = false; + private static bool _IsWindows8 = false; + private static bool _IsWindows10 = false; + private static bool m_SupportsAnimation = true; + private static bool _IsWindowsXP = false; + + static BarFunctions() + { + + m_ThemedOS = false; + + NativeFunctions.OSVERSIONINFO os = new NativeFunctions.OSVERSIONINFO(); + os.dwOSVersionInfoSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(NativeFunctions.OSVERSIONINFO)); + NativeFunctions.GetVersionEx(ref os); + if (os.dwPlatformId == 2 && os.dwMajorVersion == 4) + m_SupportsAnimation = false; + if (os.dwMajorVersion == 5 && os.dwMinorVersion >= 1 && os.dwPlatformId == 2 || + os.dwMajorVersion > 5 && os.dwPlatformId == 2) + m_ThemedOS = System.Windows.Forms.OSFeature.Feature.IsPresent(System.Windows.Forms.OSFeature.Themes); + Version osVersion = System.Environment.OSVersion.Version; + _IsWindowsXP = osVersion.Major <= 5; + m_IsVista = osVersion.Major >= 6; + _IsWindows7 = (osVersion.Major == 6 && osVersion.Minor >= 1 || osVersion.Major>6) && osVersion.Build >= 7000; + _IsWindows8 = (osVersion.Major == 6 && osVersion.Minor >= 2 || osVersion.Major > 6) && osVersion.Build >= 9200; + _IsWindows10 = (osVersion.Major == 6 && osVersion.Minor >= 3 || osVersion.Major > 6) && osVersion.Build >= 9600; + RefreshScreens(); + } + + private static Size _Windows10CaptionButtonSize = new Size(46, 28); + public static Size CaptionButtonSize + { + get + { + if (_IsWindows10) + return Dpi.Size(_Windows10CaptionButtonSize); + else + return SystemInformation.CaptionButtonSize; + } + } + + public static Size Windows10CaptionButtonSize + { + get { return _Windows10CaptionButtonSize; } + set { _Windows10CaptionButtonSize = value; } + } + + public static bool IsWindowsXP + { + get + { + return _IsWindowsXP; + } + } + + public static bool IsVista + { + get { return m_IsVista; } + } + public static bool IsWindows7 + { + get + { + return _IsWindows7; + } + } + + public static bool IsWindows8 + { + get + { + return _IsWindows8; + } + } + + public static bool IsWindows10 + { + get + { + return _IsWindows10; + } + } + + internal static char GetCharForKeyValue(int keyValue) + { + byte[] chars = new byte[2]; + try + { + byte[] keyState = new byte[256]; + if (NativeFunctions.GetKeyboardState(keyState)) + { + if (NativeFunctions.ToAscii((uint)keyValue, 0, keyState, chars, 0) != 0) + { + return (char)chars[0]; + } + } + } + catch (Exception) + { + return char.MinValue; + } + + return char.MinValue; + } + + public static Color Darken(Color color, int percent) + { + ColorFunctions.HLSColor h = ColorFunctions.RGBToHSL(color.R, color.G, color.B); + h.Lightness *= (double)(100 - percent) / 100; + return ColorFunctions.HLSToRGB(h); + } + + public static Color Ligten(Color color, int percent) + { + ColorFunctions.HLSColor h = ColorFunctions.RGBToHSL(color.R, color.G, color.B); + h.Lightness *= (1 + (double)percent / 100); + return ColorFunctions.HLSToRGB(h); + } + + /// + /// Tries to invoke the RecalcLayout method on the control and return true if such method was invoked. + /// + /// Reference to the control + /// Indicates whether to invalidate control if no recalc layout method is found + /// return true if method is invoked. + public static bool InvokeRecalcLayout(Control c, bool invalidate) + { + if (c is ItemControl) + { + ((ItemControl)c).RecalcLayout(); + return true; + } + else if (c is Bar) + { + ((Bar)c).RecalcLayout(); + return true; + } + else if (c is ExplorerBar) + { + ((ExplorerBar)c).RecalcLayout(); + return true; + } + else if (c is BaseItemControl) + { + ((BaseItemControl)c).RecalcLayout(); + return true; + } + else if (c is BarBaseControl) + { + ((BarBaseControl)c).RecalcLayout(); + return true; + } + else if (c is PopupItemControl) + { + ((PopupItemControl)c).RecalcLayout(); + return true; + } + + + + MethodInfo m = c.GetType().GetMethod("RecalcLayout"); + + if (m != null) + { + m.Invoke(c, null); + return true; + } + else if (invalidate) + { + c.Invalidate(true); + c.Update(); + } + return false; + } + + public static bool ThemedOS + { + get { return m_ThemedOS; } + set { m_ThemedOS = value; } + } + + public static StringFormat CreateStringFormat() + { + StringFormat sf = new StringFormat(); + sf.Alignment = StringAlignment.Near; + sf.LineAlignment = StringAlignment.Near; + sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None; + sf.Trimming = StringTrimming.Character; + return sf; + //return new StringFormat(StringFormat.GenericDefault); + } + + public static void SetControlVisible(Control c, bool visible) + { + if (visible) + { + int indexZOrder = -1; + if (c.Parent != null && c.Dock != DockStyle.None) indexZOrder = c.Parent.Controls.IndexOf(c); + c.Visible = true; + if (indexZOrder != -1) c.Parent.Controls.SetChildIndex(c, indexZOrder); + } + else + c.Visible = false; + } + + public static bool ProcessItemsShortcuts(eShortcut key, Hashtable itemsShortcuts) + { + bool eat = false; + if (itemsShortcuts.Contains(key)) + { + ShortcutTableEntry objEntry = (ShortcutTableEntry)itemsShortcuts[key]; + // Must convert to new array, since if this is for example + // close command first Click will destroy the collection we are + // iterating through and exception will be raised. + BaseItem[] arr = new BaseItem[objEntry.Items.Values.Count]; + objEntry.Items.Values.CopyTo(arr, 0); + Hashtable hnames = new Hashtable(arr.Length); + foreach (BaseItem objItem in arr) + { + if (objItem.CanRaiseClick && (objItem.Name == "" || !hnames.Contains(objItem.Name))) + { + if (!objItem.GlobalItem || objItem.GlobalName == "" || !hnames.Contains(objItem.GlobalName)) + { + eat = true; + objItem.RaiseClick(eEventSource.Keyboard); + if (objItem.Name != "") + { + hnames.Add(objItem.Name, ""); + } + if (objItem.GlobalItem && objItem.GlobalName != "" && objItem.GlobalName != objItem.Name && !hnames.Contains(objItem.GlobalName)) + hnames.Add(objItem.GlobalName, ""); + } + } + } + } + return eat; + } + + /// + /// Creates copy of a bar to be used as new dock bar. This function is used to create new bar for tabs that are torn off the existing dock bars. + /// + /// Original base bar to base the new bar on. + /// New instance of a bar. Note that bar is not added to the DotNetBarManager.Bars collection and DockSide is not set. + public static Bar CreateDuplicateDockBar(Bar instance) + { + // Create new Bar and invoke the drag there + Bar bar = new Bar(instance.Text); + return CreateDuplicateDockBar(instance, bar); + } + + ///// + ///// Creates copy of a bar to be used as new dock bar. This function is used to create new bar for tabs that are torn off the existing dock bars. + ///// + ///// Original base bar to base the new bar on. + ///// IDesignerServices to use for creation of the new instance of the object. + ///// New instance of a bar. Note that bar is not added to the DotNetBarManager.Bars collection and DockSide is not set. + //public static Bar CreateDuplicateDockBar(Bar instance, IDesignerServices services) + //{ + // Bar bar = services.CreateComponent(typeof(Bar)) as Bar; + // return CreateDuplicateDockBar(instance, bar); + //} + [EditorBrowsable(EditorBrowsableState.Never)] + public static Bar CreateDuplicateDockBar(Bar instance, Bar bar) + { + bar.Text = instance.Text; + bar.ItemsContainer.MinHeight = instance.MinHeight; + bar.ItemsContainer.MinWidth = instance.ItemsContainer.MinWidth; + bar.CanDockBottom = instance.CanDockBottom; + bar.CanDockLeft = instance.CanDockLeft; + bar.CanDockRight = instance.CanDockRight; + bar.CanDockTop = instance.CanDockTop; + bar.CanDockDocument = instance.CanDockDocument; + bar.CanDockTab = instance.CanDockTab; + bar.CanUndock = instance.CanUndock; + bar.CanMaximizeFloating = instance.CanMaximizeFloating; + bar.CanAutoHide = instance.CanAutoHide; + bar.DockTabAlignment = instance.DockTabAlignment; + bar.CanCustomize = instance.CanCustomize; + bar.AutoHideAnimationTime = instance.AutoHideAnimationTime; + bar.AlwaysDisplayDockTab = instance.AlwaysDisplayDockTab; + bar.AutoCreateCaptionMenu = instance.AutoCreateCaptionMenu; + bar.AutoSyncBarCaption = instance.AutoSyncBarCaption; + bar.HideFloatingInactive = instance.HideFloatingInactive; + bar.CloseSingleTab = instance.CloseSingleTab; + bar.DockTabCloseButtonVisible = instance.DockTabCloseButtonVisible; + bar.CaptionHeight = instance.CaptionHeight; + bar.TabNavigation = instance.TabNavigation; + + if (!instance.CaptionBackColor.IsEmpty) + bar.CaptionBackColor = instance.CaptionBackColor; + if (!instance.CaptionForeColor.IsEmpty) + bar.CaptionForeColor = instance.CaptionForeColor; + if (!instance.ItemsContainer.m_BackgroundColor.IsEmpty) + bar.ItemsContainer.BackColor = instance.ItemsContainer.m_BackgroundColor; + if (instance.DockedBorderStyle != eBorderType.None) + bar.DockedBorderStyle = instance.DockedBorderStyle; + + bar.Style = instance.Style; + + if (instance.ColorScheme.SchemeChanged) + bar.ColorScheme = instance.ColorScheme; + + bar.LayoutType = instance.LayoutType; + bar.GrabHandleStyle = instance.GrabHandleStyle; + bar.Stretch = instance.Stretch; + bar.CanHide = instance.CanHide; + bar.ThemeAware = instance.ThemeAware; + bar.DockedBorderStyle = instance.DockedBorderStyle; + + return bar; + } + + public static void ApplyAutoDocumentBarStyle(Bar bar) + { + bar.SetDockTabStyle(bar.Style); + bar.TabNavigation = true; + if (!bar.AlwaysDisplayDockTab) + bar.AlwaysDisplayDockTab = true; + if (bar.DockTabAlignment != eTabStripAlignment.Top) + bar.DockTabAlignment = eTabStripAlignment.Top; + if (bar.GrabHandleStyle != eGrabHandleStyle.None) + bar.GrabHandleStyle = eGrabHandleStyle.None; + } + + public static void RestoreAutoDocumentBarStyle(Bar bar) + { + bar.SetDockTabStyle(bar.Style); + if (bar.AlwaysDisplayDockTab) + bar.AlwaysDisplayDockTab = false; + if (bar.DockTabAlignment != eTabStripAlignment.Bottom) + bar.DockTabAlignment = eTabStripAlignment.Bottom; + if (bar.GrabHandleStyle != eGrabHandleStyle.Caption) + bar.GrabHandleStyle = eGrabHandleStyle.Caption; + } + + /// + /// Returns if passed control is ready for painting. + /// + /// Control to test. + /// true if handle is valid otherwise false + public static bool IsHandleValid(System.Windows.Forms.Control objCtrl) + { + return (objCtrl != null && !objCtrl.Disposing && !objCtrl.IsDisposed && objCtrl.IsHandleCreated); + } + + public static void DrawMenuCheckBox(ItemPaintArgs pa, System.Drawing.Rectangle r, eDotNetBarStyle style, bool MouseOver) + { + System.Drawing.Graphics g = pa.Graphics; + Color clr; + if (style != eDotNetBarStyle.Office2000) + { + if (MouseOver) + { + //clr=g.GetNearestColor(Color.FromArgb(45,SystemColors.Highlight)); + //SolidBrush objBrush=new SolidBrush(clr); + //g.FillRectangle(objBrush,r); + //objBrush.Dispose(); + } + else + { + //clr=g.GetNearestColor(Color.FromArgb(96,ColorFunctions.HoverBackColor())); + clr = pa.Colors.ItemCheckedBackground; //ColorFunctions.CheckBoxBackColor(g); + SolidBrush objBrush = new SolidBrush(clr); + g.FillRectangle(objBrush, r); + objBrush.Dispose(); + } + //clr=g.GetNearestColor(Color.FromArgb(200,SystemColors.Highlight)); + clr = pa.Colors.ItemCheckedBorder; // SystemColors.Highlight; + Pen objPen = new Pen(clr, 1); + // TODO: Beta 2 fix --> g.DrawRectangle(objPen,r); + NativeFunctions.DrawRectangle(g, objPen, r); + objPen.Dispose(); + // Draw checker... + Point[] pt = new Point[3]; + pt[0].X = r.Left + (r.Width - 5) / 2 - 1; + pt[0].Y = r.Top + (r.Height - 6) / 2 + 3; + pt[1].X = pt[0].X + 2; + pt[1].Y = pt[0].Y + 2; + pt[2].X = pt[1].X + 4; + pt[2].Y = pt[1].Y - 4; + objPen = new Pen(pa.Colors.ItemCheckedText); + g.DrawLines(objPen, pt); + pt[0].X++; + pt[1].X++; + pt[2].X++; + g.DrawLines(objPen, pt); + objPen.Dispose(); + } + else if (style == eDotNetBarStyle.Office2000) + { + // Draw checked box + System.Windows.Forms.ControlPaint.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.SunkenOuter, System.Windows.Forms.Border3DSide.All); + if (!MouseOver) + { + r.Inflate(-1, -1); + g.FillRectangle(ColorFunctions.GetPushedBrush(), r); + } + // Draw checker... + Point[] pt = new Point[3]; + pt[0].X = r.Left + (r.Width - 6) / 2; + pt[0].Y = r.Top + (r.Height - 6) / 2 + 3; + pt[1].X = pt[0].X + 2; + pt[1].Y = pt[0].Y + 2; + pt[2].X = pt[1].X + 4; + pt[2].Y = pt[1].Y - 4; + g.DrawLines(SystemPens.ControlText, pt); + pt[0].X++; + pt[1].X++; + pt[2].X++; + g.DrawLines(SystemPens.ControlText, pt); + } + } + + 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(); + } + + public static System.Windows.Forms.Form CreateOutlineForm() + { + System.Windows.Forms.Form form = new System.Windows.Forms.Form(); + try + { + form.Size = new Size(0, 0); + } + catch + { + form = new System.Windows.Forms.Form(); + } + form.BackColor = SystemColors.Highlight; + form.MinimizeBox = false; + form.MaximizeBox = false; + form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + if (NativeFunctions.AlphaBlendingSupported) + form.Opacity = .5; + else + form.BackColor = System.Windows.Forms.ControlPaint.LightLight(SystemColors.Highlight); + form.ShowInTaskbar = false; + form.Text = ""; + form.CreateControl(); + return form; + } + + public static System.Windows.Forms.Form CreateTransparentOutlineForm() + { + System.Windows.Forms.Form form = new TransparentForm(); + try + { + form.Size = new Size(0, 0); + } + catch + { + form = new TransparentForm(); + } + form.BackColor = SystemColors.Highlight; + form.MinimizeBox = false; + form.MaximizeBox = false; + form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + if (NativeFunctions.AlphaBlendingSupported) + form.Opacity = .5; + else + form.BackColor = System.Windows.Forms.ControlPaint.LightLight(SystemColors.Highlight); + form.ShowInTaskbar = false; + form.Text = ""; + form.CreateControl(); + return form; + } + + private class TransparentForm : Form + { + protected override void WndProc(ref Message m) + { + if (m.Msg == (int)WinApi.WindowsMessages.WM_NCHITTEST) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + base.WndProc(ref m); + } + } + + /// + /// XML element is expected to be something like Image data Base64 encoded + /// + /// Image data + /// + 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 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 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; + } + + internal static BaseItem CreateItemFromXml(System.Xml.XmlElement xmlItem) + { + string cl = xmlItem.GetAttribute("class"); + BaseItem returnItem = null; + switch (cl) + { + case "DevComponents.DotNetBar.ButtonItem": + returnItem = new ButtonItem(); + break; + case "DevComponents.DotNetBar.TextBoxItem": + returnItem = new TextBoxItem(); + break; + case "DevComponents.DotNetBar.ComboBoxItem": + returnItem = new ComboBoxItem(); + break; + case "DevComponents.DotNetBar.LabelItem": + returnItem = new LabelItem(); + break; + case "DevComponents.DotNetBar.CustomizeItem": + returnItem = new CustomizeItem(); + break; + case "DevComponents.DotNetBar.ControlContainerItem": + returnItem = new ControlContainerItem(); + break; + case "DevComponents.DotNetBar.DockContainerItem": + returnItem = new DockContainerItem(); + break; + case "DevComponents.DotNetBar.MdiWindowListItem": + returnItem = new MdiWindowListItem(); + break; + case "DevComponents.DotNetBar.SideBarContainerItem": + returnItem = new SideBarContainerItem(); + break; + case "DevComponents.DotNetBar.SideBarPanelItem": + returnItem = new SideBarPanelItem(); + break; + case "DevComponents.DotNetBar.ExplorerBarGroupItem": + returnItem = new ExplorerBarGroupItem(); + break; + case "DevComponents.DotNetBar.ExplorerBarContainerItem": + returnItem = new ExplorerBarContainerItem(); + break; + case "DevComponents.DotNetBar.ProgressBarItem": + returnItem = new ProgressBarItem(); + break; + case "DevComponents.DotNetBar.ColorPickerDropDown": + returnItem = new ColorPickerDropDown(); + break; + default: + { + try + { + //System.Windows.Forms.MessageBox.Show("Loading custom: "+xmlItem.GetAttribute("assembly")+" "+xmlItem.GetAttribute("class")); + System.Reflection.Assembly a = System.Reflection.Assembly.Load(xmlItem.GetAttribute("assembly")); + if (a == null) + return null; + BaseItem item = a.CreateInstance(xmlItem.GetAttribute("class")) as BaseItem; + returnItem = item; + } + catch (Exception e) + { + throw new ArgumentException("Could not create item from XML. Assembly=" + xmlItem.GetAttribute("assembly") + ", Class=" + xmlItem.GetAttribute("class") + ", Inner Exception: " + e.Message + ", Source=" + e.Source); + } + break; + } + } + return returnItem; + } + + internal static BaseItem CreateItemFromXml(System.Xml.XmlElement xmlItem, System.ComponentModel.Design.IDesignerHost dh, string name) + { + string cl = xmlItem.GetAttribute("class"); + BaseItem returnItem = null; + switch (cl) + { + case "DevComponents.DotNetBar.ButtonItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(ButtonItem), name) as ButtonItem; + else + returnItem = dh.CreateComponent(typeof(ButtonItem)) as ButtonItem; + break; + case "DevComponents.DotNetBar.TextBoxItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(TextBoxItem), name) as TextBoxItem; + else + returnItem = dh.CreateComponent(typeof(TextBoxItem)) as TextBoxItem; + break; + case "DevComponents.DotNetBar.ComboBoxItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(ComboBoxItem), name) as ComboBoxItem; + else + returnItem = dh.CreateComponent(typeof(ComboBoxItem)) as ComboBoxItem; + break; + case "DevComponents.DotNetBar.LabelItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(LabelItem), name) as LabelItem; + else + returnItem = dh.CreateComponent(typeof(LabelItem)) as LabelItem; + break; + case "DevComponents.DotNetBar.CustomizeItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(CustomizeItem), name) as CustomizeItem; + else + returnItem = dh.CreateComponent(typeof(CustomizeItem)) as CustomizeItem; + break; + case "DevComponents.DotNetBar.ControlContainerItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(ControlContainerItem), name) as ControlContainerItem; + else + returnItem = dh.CreateComponent(typeof(ControlContainerItem)) as ControlContainerItem; + break; + case "DevComponents.DotNetBar.DockContainerItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(DockContainerItem), name) as DockContainerItem; + else + returnItem = dh.CreateComponent(typeof(DockContainerItem)) as DockContainerItem; + break; + case "DevComponents.DotNetBar.MdiWindowListItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(MdiWindowListItem), name) as MdiWindowListItem; + else + returnItem = dh.CreateComponent(typeof(MdiWindowListItem)) as MdiWindowListItem; + break; + case "DevComponents.DotNetBar.SideBarContainerItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(SideBarContainerItem), name) as SideBarContainerItem; + else + returnItem = dh.CreateComponent(typeof(SideBarContainerItem)) as SideBarContainerItem; + break; + case "DevComponents.DotNetBar.SideBarPanelItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(SideBarPanelItem), name) as SideBarPanelItem; + else + returnItem = dh.CreateComponent(typeof(SideBarPanelItem)) as SideBarPanelItem; + break; + case "DevComponents.DotNetBar.ExplorerBarGroupItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(ExplorerBarGroupItem), name) as ExplorerBarGroupItem; + else + returnItem = dh.CreateComponent(typeof(ExplorerBarGroupItem)) as ExplorerBarGroupItem; + break; + case "DevComponents.DotNetBar.ExplorerBarContainerItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(ExplorerBarContainerItem), name) as ExplorerBarContainerItem; + else + returnItem = dh.CreateComponent(typeof(ExplorerBarContainerItem)) as ExplorerBarContainerItem; + break; + case "DevComponents.DotNetBar.ProgressBarItem": + if (name != "") + returnItem = dh.CreateComponent(typeof(ProgressBarItem), name) as ProgressBarItem; + else + returnItem = dh.CreateComponent(typeof(ProgressBarItem)) as ProgressBarItem; + break; + case "DevComponents.DotNetBar.ColorPickerDropDown": + if (name != "") + returnItem = dh.CreateComponent(typeof(ColorPickerDropDown), name) as ColorPickerDropDown; + else + returnItem = dh.CreateComponent(typeof(ColorPickerDropDown)) as ColorPickerDropDown; + break; + default: + { + try + { + //System.Windows.Forms.MessageBox.Show("Loading custom: "+xmlItem.GetAttribute("assembly")+" "+xmlItem.GetAttribute("class")); + System.Reflection.Assembly a = System.Reflection.Assembly.Load(xmlItem.GetAttribute("assembly")); + if (a == null) + return null; + BaseItem item = a.CreateInstance(xmlItem.GetAttribute("class")) as BaseItem; + returnItem = dh.CreateComponent(item.GetType()) as BaseItem; + } + catch (Exception e) + { + throw new ArgumentException("Could not create item from XML. Assembly=" + xmlItem.GetAttribute("assembly") + ", Class=" + xmlItem.GetAttribute("class") + ", Inner Exception: " + e.Message + ", Source=" + e.Source); + } + break; + } + } + return returnItem; + } + + internal static string GetItemErrorInfo(System.Xml.XmlElement xmlItem) + { + string s = ""; + if (xmlItem.HasAttribute("assembly")) + s = s + xmlItem.GetAttribute("assembly"); + if (xmlItem.HasAttribute("class")) + s = s + xmlItem.GetAttribute("class"); + return s; + } + + internal static void PaintSystemButton(System.Drawing.Graphics g, SystemButton btn, Rectangle r, bool MouseDown, bool MouseOver, bool Disabled) + { + // Draw state if any + if (MouseDown) + { + g.FillRectangle(new SolidBrush(ColorFunctions.PressedBackColor(g)), r); + NativeFunctions.DrawRectangle(g, SystemPens.Highlight, r); + } + else if (MouseOver) + { + g.FillRectangle(new SolidBrush(ColorFunctions.HoverBackColor(g)), r); + NativeFunctions.DrawRectangle(g, SystemPens.Highlight, r); + } + + Bitmap bmp = new Bitmap(r.Width, r.Height, g); + Graphics gBmp = Graphics.FromImage(bmp); + Rectangle rBtn = new Rectangle(0, 0, r.Width, r.Height); + rBtn.Inflate(0, -1); + Rectangle rClip = rBtn; + rClip.Inflate(-1, -1); + using (SolidBrush brush = new SolidBrush(SystemColors.Control)) + gBmp.FillRectangle(brush, 0, 0, r.Width, r.Height); + gBmp.SetClip(rClip); + System.Windows.Forms.ControlPaint.DrawCaptionButton(gBmp, rBtn, (System.Windows.Forms.CaptionButton)btn, System.Windows.Forms.ButtonState.Flat); + gBmp.ResetClip(); + gBmp.Dispose(); + + bmp.MakeTransparent(SystemColors.Control); + if (Disabled) + { + float[][] array = new float[5][]; + array[0] = new float[5] { 0, 0, 0, 0, 0 }; + array[1] = new float[5] { 0, 0, 0, 0, 0 }; + array[2] = new float[5] { 0, 0, 0, 0, 0 }; + array[3] = new float[5] { .5f, .5f, .5f, .5f, 0 }; + array[4] = new float[5] { 0, 0, 0, 0, 0 }; + System.Drawing.Imaging.ColorMatrix grayMatrix = new System.Drawing.Imaging.ColorMatrix(array); + System.Drawing.Imaging.ImageAttributes disabledImageAttr = new System.Drawing.Imaging.ImageAttributes(); + disabledImageAttr.ClearColorKey(); + disabledImageAttr.SetColorMatrix(grayMatrix); + g.DrawImage(bmp, r, 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, disabledImageAttr); + } + else + { + if (MouseDown) + r.Offset(1, 1); + g.DrawImageUnscaled(bmp, r); + } + + } + + internal static void SyncProperty(BaseItem item, string propertyName) + { + if (item.GlobalName.Length > 0) + { + PropertyDescriptor propDesc = TypeDescriptor.GetProperties(item)[propertyName]; + SetPropertyByGlobalName(GetOwner(item), item.GetType(), item.GlobalName, propDesc, propDesc.GetValue(item)); + } + else if (item.Name.Length > 0) + { + PropertyDescriptor propDesc = TypeDescriptor.GetProperties(item)[propertyName]; + SetProperty(GetOwner(item), item.GetType(), item.Name, propDesc, propDesc.GetValue(item)); + } + } + + private static object GetOwner(BaseItem item) + { + object owner = item.GetOwner(); + if (owner is RibbonBar && ((RibbonBar)owner).IsOverflowRibbon) + { + if (((RibbonBar)owner).IsOnQat) + owner = ((RibbonBar)owner).QatButtonParent.GetOwner(); + else + owner = ((RibbonBar)owner).OverflowParent; + } + return owner; + } + + internal static void SetProperty(object owner, System.Type itemType, string itemName, System.ComponentModel.PropertyDescriptor prop, object value) + { + IOwner manager = owner as IOwner; + DotNetBarManager dnbmanager = owner as DotNetBarManager; + + if (manager == null || itemName == "" || prop == null) + return; + + System.Collections.ArrayList list = null; + if (dnbmanager != null) + { + if (!dnbmanager.IsDisposed) + list = dnbmanager.GetItems(itemName, itemType, true); + } + else + list = manager.GetItems(itemName, itemType); + if (list == null) + return; + foreach (BaseItem objItem in list) + { + object propertyValue = prop.GetValue(objItem); + if (!(propertyValue == value || propertyValue != null && propertyValue.Equals(value))) + prop.SetValue(objItem, value); + } + } + + internal static void SetPropertyByGlobalName(object owner, System.Type itemType, string itemName, System.ComponentModel.PropertyDescriptor prop, object value) + { + IOwner manager = owner as IOwner; + DotNetBarManager dnbmanager = owner as DotNetBarManager; + + if (manager == null || itemName == "" || prop == null) + return; + + System.Collections.ArrayList list = null; + if (dnbmanager != null) + { + if (!dnbmanager.IsDisposed) + list = dnbmanager.GetItems(itemName, itemType, true, true); + } + else + list = manager.GetItems(itemName, itemType, true); + if (list == null) + return; + foreach (BaseItem objItem in list) + { + if (prop.GetValue(objItem) != value) + prop.SetValue(objItem, value); + } + } + + internal static ResourceManager GetResourceManager(bool bDefault) + { + string defaultResource = DEFAULT_RESOURCE; + DotNetBarResourcesAttribute att = Attribute.GetCustomAttribute(System.Reflection.Assembly.GetExecutingAssembly(), typeof(DotNetBarResourcesAttribute)) as DotNetBarResourcesAttribute; + if (att != null && att.NamespacePrefix != "") + defaultResource = att.NamespacePrefix + defaultResource; + else + defaultResource = "DevComponents.DotNetBar" + defaultResource; + + ResourceManager rm = new ResourceManager(defaultResource, System.Reflection.Assembly.GetExecutingAssembly()); + return rm; + } + internal static ResourceManager GetResourceManager() + { + string defaultResource = DEFAULT_RESOURCE; + DotNetBarResourcesAttribute att = Attribute.GetCustomAttribute(System.Reflection.Assembly.GetExecutingAssembly(), typeof(DotNetBarResourcesAttribute)) as DotNetBarResourcesAttribute; + if (att != null && att.NamespacePrefix != "") + defaultResource = att.NamespacePrefix + defaultResource; + else + defaultResource = "DevComponents.DotNetBar" + defaultResource; + + if (ms_ResourceName == "") + { + System.Globalization.CultureInfo cu = System.Threading.Thread.CurrentThread.CurrentUICulture; + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); + string[] arr = assembly.GetManifestResourceNames(); + int count = 0; // Make sure this exits + while (cu.LCID != 127 && count < 16) + { + if (assembly.GetManifestResourceInfo(defaultResource + "_" + cu.Name.ToLower() + ".resources") != null) + { + ms_ResourceName = defaultResource + "_" + cu.Name.ToLower(); + break; + } + else if (assembly.GetManifestResourceInfo(defaultResource + "_" + cu.TwoLetterISOLanguageName.ToLower() + ".resources") != null) + { + ms_ResourceName = defaultResource + "_" + cu.TwoLetterISOLanguageName.ToLower(); + break; + } + cu = cu.Parent; + count++; + } + if (ms_ResourceName == "") + ms_ResourceName = defaultResource; + } + + ResourceManager rm = new ResourceManager(ms_ResourceName, System.Reflection.Assembly.GetExecutingAssembly()); + return rm; + } + + internal static void DrawBorder(Graphics g, eBorderType bordertype, Rectangle r, Color singleLineColor) + { + DrawBorder(g, bordertype, r, singleLineColor, eBorderSide.Left | eBorderSide.Right | eBorderSide.Top | eBorderSide.Bottom); + } + internal static void DrawBorder(Graphics g, eBorderType bordertype, Rectangle r, Color singleLineColor, eBorderSide side) + { + DrawBorder(g, bordertype, r, singleLineColor, side, System.Drawing.Drawing2D.DashStyle.Solid); + } + internal static void DrawBorder(Graphics g, eBorderType bordertype, Rectangle r, Color singleLineColor, eBorderSide side, System.Drawing.Drawing2D.DashStyle borderDashStyle) + { + DrawBorder(g, bordertype, r, singleLineColor, side, borderDashStyle, 1); + } + internal static void DrawBorder(Graphics g, eBorderType bordertype, Rectangle r, Color singleLineColor, eBorderSide side, System.Drawing.Drawing2D.DashStyle borderDashStyle, int lineWidth) + { + if (lineWidth <= 0) return; + System.Windows.Forms.Border3DSide border3dside; + if (side == eBorderSide.All) + border3dside = System.Windows.Forms.Border3DSide.All; + else + border3dside = (((side | eBorderSide.Left) != 0) ? System.Windows.Forms.Border3DSide.Left : 0) | + (((side | eBorderSide.Right) != 0) ? System.Windows.Forms.Border3DSide.Right : 0) | + (((side | eBorderSide.Top) != 0) ? System.Windows.Forms.Border3DSide.Top : 0) | + (((side | eBorderSide.Bottom) != 0) ? System.Windows.Forms.Border3DSide.Bottom : 0); + + switch (bordertype) + { + case eBorderType.Bump: + { + System.Windows.Forms.ControlPaint.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.Bump, border3dside); + break; + } + case eBorderType.Etched: + System.Windows.Forms.ControlPaint.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.Etched, border3dside); + break; + case eBorderType.Raised: + System.Windows.Forms.ControlPaint.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, border3dside); + break; + case eBorderType.Sunken: + System.Windows.Forms.ControlPaint.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.SunkenOuter, border3dside); + break; + case eBorderType.SingleLine: + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + using (Pen pen = new Pen(singleLineColor, lineWidth)) + { + pen.DashStyle = borderDashStyle; + int offset = lineWidth / 2; + if ((side & eBorderSide.Left) != 0) + g.DrawLine(pen, r.X + offset, r.Y, r.X + offset, r.Bottom - (lineWidth > 1 ? 0 : 1)); + if ((side & eBorderSide.Top) != 0) + g.DrawLine(pen, r.X, r.Y + offset, r.Right - 1, r.Y + offset); + if (offset == 0) offset = 1; + if ((side & eBorderSide.Right) != 0) + g.DrawLine(pen, r.Right - offset, r.Y, r.Right - offset, r.Bottom - (lineWidth>1?0:1)); + if ((side & eBorderSide.Bottom) != 0) + g.DrawLine(pen, r.X, r.Bottom - offset, r.Right - 1, r.Bottom - offset); + } + g.SmoothingMode = sm; + break; + } + case eBorderType.DoubleLine: + { + using (Pen pen = new Pen(singleLineColor, lineWidth)) + { + pen.DashStyle = borderDashStyle; + for (int i = 0; i < lineWidth + 1; i += lineWidth) + { + if ((side & eBorderSide.Left) != 0) + g.DrawLine(pen, r.X, r.Y, r.X, r.Bottom - 1); + if ((side & eBorderSide.Top) != 0) + g.DrawLine(pen, r.X, r.Y, r.Right - 1, r.Y); + if ((side & eBorderSide.Right) != 0) + g.DrawLine(pen, r.Right - 1, r.Y, r.Right - 1, r.Bottom - 1); + if ((side & eBorderSide.Bottom) != 0) + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + r.Inflate(-1, -1); + } + + } + break; + } + default: + break; + } + } + + internal static void DrawBorder3D(Graphics g, int x, int y, int width, int height, System.Windows.Forms.Border3DStyle style, System.Windows.Forms.Border3DSide side) + { + DrawBorder3D(g, x, y, width, height, style, side, SystemColors.Control, true); + } + internal static void DrawBorder3D(Graphics g, int x, int y, int width, int height, System.Windows.Forms.Border3DStyle style, Color clr) + { + DrawBorder3D(g, x, y, width, height, style, System.Windows.Forms.Border3DSide.All, clr, true); + } + internal static void DrawBorder3D(Graphics g, int x, int y, int width, int height, System.Windows.Forms.Border3DStyle style) + { + DrawBorder3D(g, x, y, width, height, style, System.Windows.Forms.Border3DSide.All, SystemColors.Control, true); + } + internal static void DrawBorder3D(Graphics g, Rectangle r, System.Windows.Forms.Border3DStyle style, System.Windows.Forms.Border3DSide side, Color baseColor) + { + DrawBorder3D(g, r.X, r.Y, r.Width, r.Height, style, side, baseColor, true); + } + internal static void DrawBorder3D(Graphics g, Rectangle r, System.Windows.Forms.Border3DStyle style, System.Windows.Forms.Border3DSide side, Color baseColor, bool bFillInner) + { + DrawBorder3D(g, r.X, r.Y, r.Width, r.Height, style, side, baseColor, bFillInner); + } + internal static void DrawBorder3D(Graphics g, Rectangle r, System.Windows.Forms.Border3DStyle style) + { + DrawBorder3D(g, r.X, r.Y, r.Width, r.Height, style, System.Windows.Forms.Border3DSide.All, SystemColors.Control, true); + } + internal static void DrawBorder3D(Graphics g, int x, int y, int width, int height, System.Windows.Forms.Border3DStyle style, System.Windows.Forms.Border3DSide side, Color baseColor) + { + DrawBorder3D(g, x, y, width, height, style, side, baseColor, true); + } + internal static void DrawBorder3D(Graphics g, int x, int y, int width, int height, System.Windows.Forms.Border3DStyle style, System.Windows.Forms.Border3DSide side, Color baseColor, bool bFillInner) + { + if (bFillInner) + g.FillRectangle(new SolidBrush(baseColor), x, y, width, height); + + Color colorLight = System.Windows.Forms.ControlPaint.Light(baseColor); + Color colorDark = System.Windows.Forms.ControlPaint.Dark(baseColor); + Pen penLight = null; + Pen penDark = null; + Pen penBase = new Pen(baseColor); + height--; + width--; + switch (style) + { + case System.Windows.Forms.Border3DStyle.RaisedInner: + { + penLight = new Pen(colorLight, 1); + penDark = new Pen(colorDark, 1); + if ((side & System.Windows.Forms.Border3DSide.Top) != 0) + g.DrawLine(penLight, x, y, x + width, y); + if ((side & System.Windows.Forms.Border3DSide.Left) != 0) + g.DrawLine(penLight, x, y, x, y + height); + if ((side & System.Windows.Forms.Border3DSide.Right) != 0) + g.DrawLine(penDark, x + width, y, x + width, y + height); + if ((side & System.Windows.Forms.Border3DSide.Bottom) != 0) + g.DrawLine(penDark, x, y + height, x + width, y + height); + break; + } + case System.Windows.Forms.Border3DStyle.SunkenOuter: + { + penLight = new Pen(colorLight, 1); + penDark = new Pen(colorDark, 1); + if ((side & System.Windows.Forms.Border3DSide.Top) != 0) + g.DrawLine(penDark, x, y, x + width, y); + if ((side & System.Windows.Forms.Border3DSide.Left) != 0) + g.DrawLine(penDark, x, y, x, y + height); + if ((side & System.Windows.Forms.Border3DSide.Right) != 0) + g.DrawLine(penLight, x + width, y, x + width, y + height); + if ((side & System.Windows.Forms.Border3DSide.Bottom) != 0) + g.DrawLine(penLight, x, y + height, x + width, y + height); + break; + } + case System.Windows.Forms.Border3DStyle.Raised: + { + if ((side & System.Windows.Forms.Border3DSide.Top) != 0 && + (side & System.Windows.Forms.Border3DSide.Left) != 0 && + (side & System.Windows.Forms.Border3DSide.Right) != 0 && + (side & System.Windows.Forms.Border3DSide.Bottom) != 0) + { + + penLight = new Pen(Color.White, 1); + g.DrawRectangle(penBase, x, y, width, height); + g.DrawLine(penLight, x + 1, y + 1, x + width - 1, y + 1); + g.DrawLine(penLight, x + 1, y + 1, x + 1, y + height - 1); + } + else + { + penDark = new Pen(colorLight, 1); + penLight = new Pen(System.Windows.Forms.ControlPaint.LightLight(baseColor), 1); + if ((side & System.Windows.Forms.Border3DSide.Top) != 0) + { + g.DrawLine(penDark, x, y, x + width, y); + g.DrawLine(penLight, x + 1, y + 1, x + width - 2, y + 1); + } + if ((side & System.Windows.Forms.Border3DSide.Left) != 0) + { + g.DrawLine(penDark, x, y, x, y + height); + g.DrawLine(penLight, x + 1, y + 1, x + 1, y + height - 2); + } + + penDark.Dispose(); + penLight.Dispose(); + + penDark = new Pen(System.Windows.Forms.ControlPaint.DarkDark(baseColor), 1); + penLight = new Pen(colorDark, 1); + + if ((side & System.Windows.Forms.Border3DSide.Right) != 0) + { + g.DrawLine(penDark, x + width, y, x + width, y + height); + g.DrawLine(penLight, x + width - 1, y + 1, x + width - 1, y + height - 1); + } + if ((side & System.Windows.Forms.Border3DSide.Bottom) != 0) + { + g.DrawLine(penDark, x, y + height, x + width, y + height); + g.DrawLine(penLight, x + 1, y + height - 1, x + width - 1, y + height - 1); + } + } + break; + } + case System.Windows.Forms.Border3DStyle.Sunken: + { + penDark = new Pen(System.Windows.Forms.ControlPaint.DarkDark(baseColor), 1); + penLight = new Pen(colorDark, 1); + + if ((side & System.Windows.Forms.Border3DSide.Top) != 0) + { + g.DrawLine(penDark, x, y, x + width, y); + g.DrawLine(penLight, x + 1, y + 1, x + width - 2, y + 1); + } + if ((side & System.Windows.Forms.Border3DSide.Left) != 0) + { + g.DrawLine(penDark, x, y, x, y + height); + g.DrawLine(penLight, x + 1, y + 1, x + 1, y + height - 2); + } + + penDark.Dispose(); + penLight.Dispose(); + + penDark = new Pen(colorLight, 1); + penLight = new Pen(System.Windows.Forms.ControlPaint.LightLight(baseColor), 1); + + if ((side & System.Windows.Forms.Border3DSide.Right) != 0) + { + g.DrawLine(penDark, x + width, y, x + width, y + height); + g.DrawLine(penLight, x + width - 1, y + 1, x + width - 1, y + height - 1); + } + if ((side & System.Windows.Forms.Border3DSide.Bottom) != 0) + { + g.DrawLine(penDark, x, y + height, x + width, y + height); + g.DrawLine(penLight, x + 1, y + height - 1, x + width - 1, y + height - 1); + } + break; + } + } + if (penLight != null) + penLight.Dispose(); + if (penDark != null) + penDark.Dispose(); + penBase.Dispose(); + } + + internal static System.Drawing.Drawing2D.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 System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(r.X, r.Y - 1, r.Width, r.Height + 1), color1, color2, gradientAngle); + } + + internal static System.Drawing.Drawing2D.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 System.Drawing.Drawing2D.LinearGradientBrush(new RectangleF(r.X, r.Y - 1, r.Width, r.Height + 1), color1, color2, gradientAngle); + } + + internal static System.Drawing.Drawing2D.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 System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(r.X, r.Y - 1, r.Width, r.Height + 1), color1, color2, gradientAngle, isAngleScalable); + } + + public static void DrawDesignTimeSelection(Graphics g, Rectangle r, Color backColor, Color border, int penWidth) + { + if (r.Width <= 0 || r.Height <= 0) + return; + if (!backColor.IsEmpty && backColor != Color.Transparent) + { + if ((double)backColor.GetBrightness() < 0.5) + border = System.Windows.Forms.ControlPaint.Light(backColor); + else + border = System.Windows.Forms.ControlPaint.Dark(backColor); + } + using (Pen pen = new Pen(border, penWidth)) + { + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; + r.Width--; + r.Height--; + g.DrawRectangle(pen, r); + } + } + + public static BaseItem GetSubItemByName(BaseItem objParent, string ItemName) + { + return GetSubItemByName(objParent, ItemName, false); + } + + public static BaseItem GetSubItemByName(BaseItem objParent, string ItemName, bool useGlobalName) + { + if (objParent == null) + return null; + foreach (BaseItem objItem in objParent.SubItems) + { + if (useGlobalName && objItem.GlobalName == ItemName || !useGlobalName && objItem.Name == ItemName) + return objItem; + if (objItem.SubItems.Count > 0) + { + BaseItem item = GetSubItemByName(objItem, ItemName, useGlobalName); + if (item != null) + return item; + } + } + + if (objParent is GalleryContainer) + { + return GetSubItemByName(((GalleryContainer)objParent).PopupGalleryItem, ItemName, useGlobalName); + } + + return null; + } + + public static void GetSubItemsByName(BaseItem objParent, string ItemName, ArrayList list) + { + GetSubItemsByName(objParent, ItemName, list, false); + } + + public static void GetSubItemsByName(BaseItem objParent, string ItemName, ArrayList list, bool useGlobalName) + { + if (objParent == null) return; + foreach (BaseItem objItem in objParent.SubItems) + { + if (useGlobalName && objItem.GlobalName == ItemName || !useGlobalName && objItem.Name == ItemName) + list.Add(objItem); + else if (objItem is ControlContainerItem) + { + ControlContainerItem cc = objItem as ControlContainerItem; + if (cc.Control is RibbonBar) + { + RibbonBar rb = cc.Control as RibbonBar; + ArrayList rbList = rb.GetItems(ItemName); + list.AddRange(rbList); + } + } + + if (objItem.SubItems.Count > 0) + GetSubItemsByName(objItem, ItemName, list, useGlobalName); + } + + if (objParent is GalleryContainer) + { + GetSubItemsByName(((GalleryContainer)objParent).PopupGalleryItem, ItemName, list, useGlobalName); + } + } + + public static void GetSubItemsByNameAndType(BaseItem objParent, string ItemName, ArrayList list, Type itemType) + { + GetSubItemsByNameAndType(objParent, ItemName, list, itemType, false); + } + + public static void GetSubItemsByNameAndType(BaseItem objParent, string ItemName, ArrayList list, Type itemType, bool useGlobalName) + { + if (objParent == null) return; + foreach (BaseItem objItem in objParent.SubItems) + { + if (objItem.GetType() == itemType && (useGlobalName && objItem.GlobalName == ItemName || !useGlobalName && objItem.Name == ItemName)) + list.Add(objItem); + else if (objItem is ControlContainerItem) + { + ControlContainerItem cc = objItem as ControlContainerItem; + if (cc.Control is RibbonBar) + { + RibbonBar rb = cc.Control as RibbonBar; + ArrayList rbList = rb.GetItems(ItemName, itemType, useGlobalName); + list.AddRange(rbList); + } + } + + if (objItem.SubItems.Count > 0) + GetSubItemsByNameAndType(objItem, ItemName, list, itemType, useGlobalName); + } + } + + public static string ColorToString(Color clr) + { + if (clr.IsSystemColor) + return ("." + clr.Name); + else + return clr.ToArgb().ToString(); + } + + public 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)); + } + + public static bool SupportsAnimation + { + get { return m_SupportsAnimation; } + } + + internal static ScreenInformation PrimaryScreen + { + get + { + if (m_Screens.Count == 0) + RefreshScreens(); + foreach (ScreenInformation s in m_Screens) + { + if (s.Primary) + return s; + } + if (m_Screens.Count > 0) + return m_Screens[0]; + return new ScreenInformation(new Rectangle(0, 0, 1024, 768), new Rectangle(0, 0, 1024, 768), true); + } + } + + internal static ScreenInformation ScreenFromPoint(Point pScreen) + { + if (m_Screens.Count == 0) + RefreshScreens(); + //foreach (System.Windows.Forms.Screen s in System.Windows.Forms.Screen.AllScreens) + foreach (ScreenInformation s in m_Screens) + { + if (s.Bounds.Contains(pScreen)) + { + return s; + } + } + + System.Windows.Forms.Screen scr = System.Windows.Forms.Screen.FromPoint(pScreen); + if (scr != null && scr.Bounds.Contains(pScreen)) + return new ScreenInformation(scr.Bounds, scr.WorkingArea); + + return null; + } + internal static ScreenInformation ScreenFromControl(System.Windows.Forms.Control control) + { + Rectangle r; + if (control.Parent != null) + { + Point screenLocation = control.PointToScreen(Point.Empty); + r = new Rectangle(screenLocation, control.Size); + } + else + r = new Rectangle(control.Location, control.Size); + if (m_Screens.Count == 0) + RefreshScreens(); + //foreach (System.Windows.Forms.Screen s in System.Windows.Forms.Screen.AllScreens) + foreach (ScreenInformation s in m_Screens) + { + //if(s.Bounds.Contains(r)) + if (s.Bounds.Contains(r)) + { + return s; + } + } + System.Windows.Forms.Screen scr = System.Windows.Forms.Screen.FromControl(control); + if (scr != null) + return new ScreenInformation(scr.Bounds, scr.WorkingArea); + return null; + } + + private static List m_Screens = new List(2); + public static void RefreshScreens() + { + m_Screens.Clear(); + foreach (System.Windows.Forms.Screen s in System.Windows.Forms.Screen.AllScreens) + m_Screens.Add(new ScreenInformation(s.Bounds, s.WorkingArea, s.Primary)); + } + + public static void SetExplorerBarStyle(ExplorerBar bar, eExplorerBarStockStyle stockStyle) + { + if (stockStyle == eExplorerBarStockStyle.SystemColors) + { + bar.BackStyle.Reset(); + bar.BackStyle.BackColorSchemePart = eColorSchemePart.ExplorerBarBackground; + bar.BackStyle.BackColor2SchemePart = eColorSchemePart.ExplorerBarBackground2; + bar.BackStyle.BackColorGradientAngle = bar.ColorScheme.ExplorerBarBackgroundGradientAngle; + } + else if (stockStyle != eExplorerBarStockStyle.Custom) + { + ePredefinedColorScheme scheme = ePredefinedColorScheme.Blue2003; + if (stockStyle == eExplorerBarStockStyle.Silver || stockStyle == eExplorerBarStockStyle.SilverSpecial) + scheme = ePredefinedColorScheme.Silver2003; + else if (stockStyle == eExplorerBarStockStyle.OliveGreen || stockStyle == eExplorerBarStockStyle.OliveGreenSpecial) + scheme = ePredefinedColorScheme.OliveGreen2003; + ColorScheme cs = new ColorScheme(eDotNetBarStyle.Office2003); + cs.PredefinedColorScheme = scheme; + + bar.BackStyle.Reset(); + bar.BackStyle.BackColor = cs.ExplorerBarBackground; + bar.BackStyle.BackColor2 = cs.ExplorerBarBackground2; + bar.BackStyle.BackColorGradientAngle = cs.ExplorerBarBackgroundGradientAngle; + } + } + public static void SetExplorerBarStyle(ExplorerBarGroupItem group, eExplorerBarStockStyle stockStyle) + { + if (stockStyle == eExplorerBarStockStyle.SystemColors) + { + eExplorerBarStockStyle stock = eExplorerBarStockStyle.Blue; + eExplorerBarStockStyle special = eExplorerBarStockStyle.BlueSpecial; + + if (SystemColors.Control.ToArgb() == Color.FromArgb(224, 223, 227).ToArgb() && SystemColors.Highlight.ToArgb() == Color.FromArgb(178, 180, 191).ToArgb()) + { + stock = eExplorerBarStockStyle.Silver; + special = eExplorerBarStockStyle.SilverSpecial; + } + else if (SystemColors.Control.ToArgb() == Color.FromArgb(236, 233, 216).ToArgb() && SystemColors.Highlight.ToArgb() == Color.FromArgb(147, 160, 112).ToArgb()) + { + stock = eExplorerBarStockStyle.OliveGreen; + special = eExplorerBarStockStyle.OliveGreenSpecial; + } + + if (group.XPSpecialGroup) + stockStyle = special; + else + stockStyle = stock; + } + + if (stockStyle != eExplorerBarStockStyle.Custom) + { + group.TitleStyle.Reset(); + group.TitleHotStyle.Reset(); + group.BackStyle.Reset(); + + group.TitleStyle.CornerTypeTopLeft = eCornerType.Rounded; + group.TitleStyle.CornerTypeTopRight = eCornerType.Rounded; + group.TitleStyle.CornerDiameter = 3; + group.TitleHotStyle.CornerTypeTopLeft = eCornerType.Rounded; + group.TitleHotStyle.CornerTypeTopRight = eCornerType.Rounded; + group.TitleHotStyle.CornerDiameter = 3; + } + + switch (stockStyle) + { + case eExplorerBarStockStyle.Blue: + { + group.TitleStyle.BackColor = Color.White; + group.TitleStyle.BackColor2 = Color.FromArgb(199, 211, 247); + group.TitleStyle.TextColor = Color.FromArgb(33, 93, 198); + group.TitleHotStyle.TextColor = Color.FromArgb(66, 142, 255); + group.TitleHotStyle.BackColor = Color.White; + group.TitleHotStyle.BackColor2 = Color.FromArgb(199, 211, 247); ; + group.BackStyle.BackColor = Color.FromArgb(214, 223, 247); + group.BackStyle.BorderBottom = eStyleBorderType.Solid; + group.BackStyle.BorderTop = eStyleBorderType.None; + group.BackStyle.BorderLeft = eStyleBorderType.Solid; + group.BackStyle.BorderRight = eStyleBorderType.Solid; + group.BackStyle.BorderBottomWidth = 1; + group.BackStyle.BorderTopWidth = 0; + group.BackStyle.BorderLeftWidth = 1; + group.BackStyle.BorderRightWidth = 1; + group.BackStyle.BorderColor = Color.White; + group.ExpandBackColor = Color.White; + group.ExpandBorderColor = Color.FromArgb(174, 182, 216); + group.ExpandForeColor = Color.FromArgb(0, 60, 165); + group.ExpandHotBackColor = Color.White; + group.ExpandHotBorderColor = Color.FromArgb(174, 182, 216); + group.ExpandHotForeColor = Color.FromArgb(66, 142, 255); + + break; + } + case eExplorerBarStockStyle.BlueSpecial: + { + group.TitleStyle.BackColor = Color.FromArgb(0, 73, 181); + group.TitleStyle.BackColor2 = Color.FromArgb(41, 93, 206); + group.TitleStyle.TextColor = Color.White; + group.TitleHotStyle.TextColor = Color.FromArgb(66, 142, 255); + group.TitleHotStyle.BackColor = Color.FromArgb(0, 73, 181); + group.TitleHotStyle.BackColor2 = Color.FromArgb(41, 93, 206); + group.BackStyle.Reset(); + group.BackStyle.BackColor = Color.FromArgb(239, 243, 255); + group.BackStyle.BorderBottom = eStyleBorderType.Solid; + group.BackStyle.BorderTop = eStyleBorderType.None; + group.BackStyle.BorderLeft = eStyleBorderType.Solid; + group.BackStyle.BorderRight = eStyleBorderType.Solid; + group.BackStyle.BorderBottomWidth = 1; + group.BackStyle.BorderTopWidth = 0; + group.BackStyle.BorderLeftWidth = 1; + group.BackStyle.BorderRightWidth = 1; + group.BackStyle.BorderColor = Color.White; + + group.ExpandBackColor = Color.FromArgb(48, 97, 196); + group.ExpandBorderColor = Color.FromArgb(123, 168, 229); + group.ExpandForeColor = Color.White; + group.ExpandHotBackColor = Color.FromArgb(48, 97, 196); + group.ExpandHotBorderColor = Color.FromArgb(123, 168, 229); + group.ExpandHotForeColor = Color.FromArgb(172, 205, 255); + + break; + } + case eExplorerBarStockStyle.OliveGreen: + { + group.TitleStyle.BackColor = Color.FromArgb(255, 252, 236); + group.TitleStyle.BackColor2 = Color.FromArgb(224, 231, 184); + group.TitleStyle.TextColor = Color.FromArgb(86, 102, 45); + group.TitleHotStyle.TextColor = Color.FromArgb(114, 146, 29); + group.TitleHotStyle.BackColor = Color.FromArgb(255, 252, 236); + group.TitleHotStyle.BackColor2 = Color.FromArgb(224, 231, 184); + group.BackStyle.Reset(); + group.BackStyle.BackColor = Color.FromArgb(246, 246, 236); + group.BackStyle.BorderBottom = eStyleBorderType.Solid; + group.BackStyle.BorderTop = eStyleBorderType.None; + group.BackStyle.BorderLeft = eStyleBorderType.Solid; + group.BackStyle.BorderRight = eStyleBorderType.Solid; + group.BackStyle.BorderBottomWidth = 1; + group.BackStyle.BorderTopWidth = 0; + group.BackStyle.BorderLeftWidth = 1; + group.BackStyle.BorderRightWidth = 1; + group.BackStyle.BorderColor = Color.White; + group.ExpandBackColor = Color.FromArgb(254, 254, 253); + group.ExpandBorderColor = Color.FromArgb(194, 206, 185); + group.ExpandForeColor = Color.FromArgb(75, 103, 28); + group.ExpandHotBackColor = Color.FromArgb(254, 254, 253); + group.ExpandHotBorderColor = Color.FromArgb(194, 206, 185); + group.ExpandHotForeColor = Color.FromArgb(114, 146, 29); + + break; + } + case eExplorerBarStockStyle.OliveGreenSpecial: + { + group.TitleStyle.BackColor = Color.FromArgb(119, 140, 64); + group.TitleStyle.BackColor2 = Color.FromArgb(150, 168, 103); + group.TitleStyle.TextColor = Color.White; + group.TitleHotStyle.TextColor = Color.FromArgb(224, 231, 184); + group.TitleHotStyle.BackColor = Color.FromArgb(119, 140, 64); + group.TitleHotStyle.BackColor2 = Color.FromArgb(150, 168, 103); + group.BackStyle.Reset(); + group.BackStyle.BackColor = Color.FromArgb(246, 246, 236); + group.BackStyle.BorderBottom = eStyleBorderType.Solid; + group.BackStyle.BorderTop = eStyleBorderType.None; + group.BackStyle.BorderLeft = eStyleBorderType.Solid; + group.BackStyle.BorderRight = eStyleBorderType.Solid; + group.BackStyle.BorderBottomWidth = 1; + group.BackStyle.BorderTopWidth = 0; + group.BackStyle.BorderLeftWidth = 1; + group.BackStyle.BorderRightWidth = 1; + group.BackStyle.BorderColor = Color.White; + + group.ExpandBackColor = Color.FromArgb(129, 163, 79); + group.ExpandBorderColor = Color.FromArgb(191, 205, 156); + group.ExpandForeColor = Color.White; + group.ExpandHotBackColor = Color.FromArgb(130, 164, 80); + group.ExpandHotBorderColor = Color.FromArgb(182, 202, 139); + group.ExpandHotForeColor = Color.FromArgb(221, 237, 190); + + break; + } + case eExplorerBarStockStyle.Silver: + { + group.TitleStyle.BackColor = Color.White; + group.TitleStyle.BackColor2 = Color.FromArgb(214, 215, 224); + group.TitleStyle.TextColor = Color.FromArgb(63, 61, 61); + group.TitleHotStyle.TextColor = Color.FromArgb(126, 124, 124); + group.TitleHotStyle.BackColor = Color.White; + group.TitleHotStyle.BackColor2 = Color.FromArgb(214, 215, 224); + group.BackStyle.Reset(); + group.BackStyle.BackColor = Color.FromArgb(240, 241, 245); + group.BackStyle.BorderBottom = eStyleBorderType.Solid; + group.BackStyle.BorderTop = eStyleBorderType.None; + group.BackStyle.BorderLeft = eStyleBorderType.Solid; + group.BackStyle.BorderRight = eStyleBorderType.Solid; + group.BackStyle.BorderBottomWidth = 1; + group.BackStyle.BorderTopWidth = 0; + group.BackStyle.BorderLeftWidth = 1; + group.BackStyle.BorderRightWidth = 1; + group.BackStyle.BorderColor = Color.White; + + group.ExpandBackColor = Color.White; + group.ExpandBorderColor = Color.FromArgb(188, 189, 203); + group.ExpandForeColor = Color.FromArgb(49, 68, 115); + group.ExpandHotBackColor = Color.White; + group.ExpandHotBorderColor = Color.FromArgb(194, 195, 208); + group.ExpandHotForeColor = Color.FromArgb(126, 124, 124); + + break; + } + case eExplorerBarStockStyle.SilverSpecial: + { + group.TitleStyle.BackColor = Color.FromArgb(119, 119, 146); + group.TitleStyle.BackColor2 = Color.FromArgb(180, 182, 199); + group.TitleStyle.TextColor = Color.White; + group.TitleHotStyle.BackColor = Color.FromArgb(119, 119, 146); + group.TitleHotStyle.BackColor2 = Color.FromArgb(180, 182, 199); + group.TitleHotStyle.TextColor = Color.FromArgb(230, 230, 230); + group.BackStyle.Reset(); + group.BackStyle.BackColor = Color.FromArgb(240, 241, 245); + group.BackStyle.BorderBottom = eStyleBorderType.Solid; + group.BackStyle.BorderTop = eStyleBorderType.None; + group.BackStyle.BorderLeft = eStyleBorderType.Solid; + group.BackStyle.BorderRight = eStyleBorderType.Solid; + group.BackStyle.BorderBottomWidth = 1; + group.BackStyle.BorderTopWidth = 0; + group.BackStyle.BorderLeftWidth = 1; + group.BackStyle.BorderRightWidth = 1; + group.BackStyle.BorderColor = Color.White; + + group.ExpandBackColor = Color.FromArgb(111, 117, 151); + group.ExpandBorderColor = Color.FromArgb(196, 203, 224); + group.ExpandForeColor = Color.White; + group.ExpandHotBackColor = Color.FromArgb(111, 117, 151); + group.ExpandHotBorderColor = Color.FromArgb(196, 203, 224); + group.ExpandHotForeColor = Color.White; + + break; + } + } + } + public static void SetExplorerBarStyle(ButtonItem item, eExplorerBarStockStyle stockStyle) + { + if (stockStyle == eExplorerBarStockStyle.SystemColors) + { + eExplorerBarStockStyle stock = eExplorerBarStockStyle.Blue; + + if (SystemColors.Control.ToArgb() == Color.FromArgb(224, 223, 227).ToArgb() && SystemColors.Highlight.ToArgb() == Color.FromArgb(178, 180, 191).ToArgb()) + { + stock = eExplorerBarStockStyle.Silver; + } + else if (SystemColors.Control.ToArgb() == Color.FromArgb(236, 233, 216).ToArgb() && SystemColors.Highlight.ToArgb() == Color.FromArgb(147, 160, 112).ToArgb()) + { + stock = eExplorerBarStockStyle.OliveGreen; + } + + stockStyle = stock; + } + + switch (stockStyle) + { + case eExplorerBarStockStyle.Blue: + case eExplorerBarStockStyle.BlueSpecial: + { + item.ForeColor = Color.FromArgb(33, 93, 198); + item.HotForeColor = Color.FromArgb(66, 142, 255); + break; + } + case eExplorerBarStockStyle.OliveGreen: + case eExplorerBarStockStyle.OliveGreenSpecial: + { + item.ForeColor = Color.FromArgb(86, 102, 45); + item.HotForeColor = Color.FromArgb(114, 146, 29); + break; + } + case eExplorerBarStockStyle.Silver: + case eExplorerBarStockStyle.SilverSpecial: + { + item.ForeColor = Color.FromArgb(63, 61, 61); + item.HotForeColor = Color.FromArgb(126, 124, 124); + break; + } + default: + { + item.ForeColor = SystemColors.ControlText; + item.HotForeColor = SystemColors.ControlDark; + break; + } + } + } + + public static System.Windows.Forms.MdiClient GetMdiClient(System.Windows.Forms.Form MdiForm) + { + if (!MdiForm.IsMdiContainer) + return null; + foreach (System.Windows.Forms.Control ctrl in MdiForm.Controls) + { + if (ctrl is System.Windows.Forms.MdiClient) + return (ctrl as System.Windows.Forms.MdiClient); + } + return null; + } + + //internal static Bitmap CreateDisabledBitmap(Bitmap bmp) + //{ + // if(bmp==null) + // return null; + + // Bitmap bmpTarget=null; + // try + // { + // int nWidth = bmp.Width; + // int nHeight = bmp.Height; + // bmpTarget = new Bitmap(bmp); + // for (int iX = 0; iX < nWidth; iX++) + // { + // for (int iY = 0; iY < nHeight; iY++) + // { + // Color cr = bmp.GetPixel(iX, iY); + // if(cr.IsEmpty || cr==Color.Transparent) + // { + // bmpTarget.SetPixel(iX, iY, Color.Transparent); + // } + // else + // { + // byte nA = cr.A; + // byte nB = (byte) ((cr.B + 255) / 2); + // byte nG = (byte) ((cr.G + 255) / 2); + // byte nR = (byte) ((cr.R + 255) / 2); + // nR = nG = nB = (byte) (nR * 0.299 + nG * 0.587 + nB * 0.114); + // bmpTarget.SetPixel(iX, iY, Color.FromArgb(nA, nR, nG, nB)); + // } + // } + // } + // } + // catch + // { + // return null; + // } + + // return bmpTarget; + //} + internal static Icon CreateDisabledIcon(Icon ico) + { + try + { + System.IO.MemoryStream memStream = new System.IO.MemoryStream(); + ico.Save(memStream); + byte[] array = memStream.ToArray(); + int nIconCount = array[4]; + for (int iIcon = 0; iIcon < nIconCount; iIcon++) + { + int nBaseOffset = 6 + iIcon * 16; + int nWidth = array[nBaseOffset + 0]; + int nHeight = array[nBaseOffset + 1]; + int nOffset = GetDWORD(ref array, nBaseOffset + 12); + //data at position + int nStructSize = GetDWORD(ref array, nOffset); + int nPlanes = GetWORD(ref array, nOffset + 12); + int nBitCount = GetWORD(ref array, nOffset + 14); + //process 32-bit Icons (bitcount=32) + + //process 24-bit icons (bitcount=24) + + //process 8-bit (256 color) icons (bitcount=8) + if (nPlanes != 1) continue; + + int nSize = GetDWORD(ref array, nOffset + 20); + int nStep = 0; + + switch (nBitCount) + { + case 32: nStep = 4; nSize = nWidth * nHeight * 4; break; + case 24: nStep = 3; nSize = nWidth * nHeight * 3; break; + case 8: nStep = 4; nSize = 1024; break; //256 colors x 4 bytes + default: continue; + } + + int iDataStart = nOffset + nStructSize; + for (int iPtr = iDataStart; iPtr < iDataStart + nSize; iPtr += nStep) + { + byte nB = (byte)((array[iPtr] + 255) / 2); + byte nG = (byte)((array[iPtr + 1] + 255) / 2); + byte nR = (byte)((array[iPtr + 2] + 255) / 2); + if (!(nB == 127 && nG == 127 && nR == 127)) + { + byte nNewRGB = (byte)(nR * 0.299 + nG * 0.587 + nB * 0.114); + array[iPtr] = nNewRGB; + array[iPtr + 1] = nNewRGB; + array[iPtr + 2] = nNewRGB; + } + } + } + return new Icon(new System.IO.MemoryStream(array)); + } + catch (Exception) + { + return null; + } + } + private static int GetDWORD(ref byte[] array, int offset) + { + return array[offset] + (array[offset + 1] << 8) + (array[offset + 2] << 16) + (array[offset + 3] << 24); + } + private static int GetWORD(ref byte[] array, int offset) + { + return array[offset] + (array[offset + 1] << 8); + } + + internal static void PaintBackgroundImage(Graphics g, Rectangle targetRect, Image backgroundImage, eStyleBackgroundImage backgroundImagePosition, int backgroundImageAlpha) + { + PaintBackgroundImage(g, targetRect, backgroundImage, (eBackgroundImagePosition)backgroundImagePosition, backgroundImageAlpha); + } + + internal static void PaintBackgroundImage(Graphics g, Rectangle targetRect, Image backgroundImage, eBackgroundImagePosition backgroundImagePosition, int backgroundImageAlpha) + { + if (backgroundImage == null) + return; + + Rectangle r = targetRect; + System.Drawing.Imaging.ImageAttributes imageAtt = null; + + if (backgroundImageAlpha != 255) + { + float[][] matrixItems ={ + new float[] {1, 0, 0, 0, 0}, + new float[] {0, 1, 0, 0, 0}, + new float[] {0, 0, 1, 0, 0}, + new float[] {0, 0, 0, (float)backgroundImageAlpha/255, 0}, + new float[] {0, 0, 0, 0, 1}}; + System.Drawing.Imaging.ColorMatrix colorMatrix = new System.Drawing.Imaging.ColorMatrix(matrixItems); + + //System.Drawing.Imaging.ColorMatrix colorMatrix = new System.Drawing.Imaging.ColorMatrix(); + //colorMatrix.Matrix33 = 255 - backgroundImageAlpha; + imageAtt = new System.Drawing.Imaging.ImageAttributes(); + imageAtt.SetColorMatrix(colorMatrix, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap); + } + + switch (backgroundImagePosition) + { + case eBackgroundImagePosition.Stretch: + { + if (imageAtt != null) + g.DrawImage(backgroundImage, r, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel, imageAtt); + else + g.DrawImage(backgroundImage, r, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel); + break; + } + case eBackgroundImagePosition.CenterLeft: + case eBackgroundImagePosition.CenterRight: + { + Rectangle destRect = new Rectangle(r.X, r.Y, Dpi.Width(backgroundImage.Width), Dpi.Height(backgroundImage.Height)); + if (r.Width > destRect.Width && backgroundImagePosition == eBackgroundImagePosition.CenterRight) + destRect.X += (r.Width - destRect.Width); + destRect.Y += (r.Height - destRect.Height) / 2; + if (imageAtt != null) + g.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel, imageAtt); + else + g.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel); + + break; + } + case eBackgroundImagePosition.Center: + { + Rectangle destRect = new Rectangle(r.X, r.Y, Dpi.Width(backgroundImage.Width), Dpi.Height(backgroundImage.Height)); + if (r.Width > destRect.Width) + destRect.X += (r.Width - destRect.Width) / 2; + if (r.Height > destRect.Height) + destRect.Y += (r.Height - destRect.Height) / 2; + if (imageAtt != null) + g.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel, imageAtt); + else + g.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel); + break; + } + case eBackgroundImagePosition.TopLeft: + case eBackgroundImagePosition.TopRight: + case eBackgroundImagePosition.BottomLeft: + case eBackgroundImagePosition.BottomRight: + { + Rectangle destRect = new Rectangle(r.X, r.Y, Dpi.Width(backgroundImage.Width), Dpi.Height(backgroundImage.Height)); + if (backgroundImagePosition == eBackgroundImagePosition.TopRight) + destRect.X = r.Right - destRect.Width; + else if (backgroundImagePosition == eBackgroundImagePosition.BottomLeft) + destRect.Y = r.Bottom - destRect.Height; + else if (backgroundImagePosition == eBackgroundImagePosition.BottomRight) + { + destRect.Y = r.Bottom - destRect.Height; + destRect.X = r.Right - destRect.Width; + } + + if (imageAtt != null) + g.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel, imageAtt); + else + g.DrawImage(backgroundImage, destRect, 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel); + break; + } + case eBackgroundImagePosition.Tile: + { + if (imageAtt != null) + { + int imageWidth = Dpi.Width(backgroundImage.Width); + int imageHeight = Dpi.Height(backgroundImage.Height); + if (r.Width > imageWidth || r.Height > imageHeight) + { + int x = r.X, y = r.Y; + while (y < r.Bottom) + { + while (x < r.Right) + { + Rectangle destRect = new Rectangle(x, y, imageWidth, imageHeight); + if (destRect.Right > r.Right) + destRect.Width = destRect.Width - (destRect.Right - r.Right); + if (destRect.Bottom > r.Bottom) + destRect.Height = destRect.Height - (destRect.Bottom - r.Bottom); + g.DrawImage(backgroundImage, destRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAtt); + x += imageWidth; + } + x = r.X; + y += imageHeight; + } + } + else + { + g.DrawImage(backgroundImage, new Rectangle(0, 0, imageWidth, imageHeight), 0, 0, backgroundImage.Width, backgroundImage.Height, GraphicsUnit.Pixel, imageAtt); + } + } + else + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + using (TextureBrush brush = new TextureBrush(backgroundImage)) + { + brush.WrapMode = System.Drawing.Drawing2D.WrapMode.Tile; + g.FillRectangle(brush, r); + } + g.SmoothingMode = sm; + } + break; + } + } + } + + public static bool IsSystemKey(System.Windows.Forms.Keys key) + { + if (key == Keys.Add || key == Keys.Alt || key == Keys.Apps || key == Keys.Attn || + key == Keys.Back || key == Keys.Escape || key == Keys.Enter || + (key >= Keys.F1 && key <= Keys.F19) || key == Keys.Tab) + return true; + return false; + } + + public static bool IsFormActive(Form f) + { + if (f == null) return false; + + if (Form.ActiveForm == f) + { + if (f.IsMdiChild) + { + if (f.MdiParent != null) + { + if (f.MdiParent.ActiveMdiChild == f) + return true; + else + return false; + } + } + return true; + } + + return false; + } + + public static void AnimateControl(System.Windows.Forms.Control control, bool show, int animationTime, Rectangle rectStart, Rectangle rectEnd) + { + control.Bounds = rectStart; + if (!control.Visible) + control.Visible = true; + + bool directSet = false; + if (animationTime <= 0) + directSet = true; + + TimeSpan time = new TimeSpan(0, 0, 0, 0, animationTime); + int dxLoc, dyLoc; + int dWidth, dHeight; + dxLoc = dyLoc = dWidth = dHeight = 0; + if (rectStart.Left == rectEnd.Left && + rectStart.Top == rectEnd.Top && + rectStart.Right == rectEnd.Right && rectStart.Height != rectEnd.Height) + { + dHeight = (rectEnd.Height > rectStart.Height ? 1 : -1); + } + else if (rectStart.Left == rectEnd.Left && + rectStart.Top == rectEnd.Top && + rectStart.Bottom == rectEnd.Bottom && rectStart.Width != rectEnd.Width) + { + dWidth = (rectEnd.Width > rectStart.Width ? 1 : -1); + } + else if (rectStart.Right == rectEnd.Right && + rectStart.Top == rectEnd.Top && + rectStart.Bottom == rectEnd.Bottom && rectStart.Width != rectEnd.Width) + { + dxLoc = (rectEnd.Width > rectStart.Width ? -1 : 1); + dWidth = (rectEnd.Width > rectStart.Width ? 1 : -1); + } + else if (rectStart.Right == rectEnd.Right && + rectStart.Left == rectEnd.Left && + rectStart.Bottom == rectEnd.Bottom && rectStart.Height != rectEnd.Height) + { + dyLoc = (rectEnd.Height > rectStart.Height ? -1 : 1); + dHeight = (rectEnd.Height > rectStart.Height ? 1 : -1); + } + else if (rectEnd.X != rectStart.X && rectEnd.Y == rectStart.Y && rectStart.Height == rectEnd.Height && rectEnd.Width == rectStart.Width) + { + // Simple to left move of the control + dxLoc = (rectEnd.X > rectStart.X ? 1 : -1); + } + else if (rectEnd.Y != rectStart.Y && rectEnd.X == rectStart.X && rectStart.Height == rectEnd.Height && rectEnd.Width == rectStart.Width) + { + // Simple to left move of the control + dxLoc = (rectEnd.Y > rectStart.Y ? 1 : -1); + } + else + directSet = true; + + if (directSet) + { + control.Bounds = rectEnd; + } + else + { + int speedFactor = 1; + int totalPixels = (rectStart.Width != rectEnd.Width) ? + Math.Abs(rectStart.Width - rectEnd.Width) : + Math.Abs(rectStart.Height - rectEnd.Height); + if (totalPixels == 0 && rectStart.Width == rectEnd.Width && rectStart.Height == rectEnd.Height) + { + if (rectEnd.X - rectStart.X != 0) + totalPixels = Math.Abs(rectStart.X - rectEnd.X); + else if (rectEnd.Y - rectStart.Y != 0) + totalPixels = Math.Abs(rectStart.Y - rectEnd.Y); + } + int remainPixels = totalPixels; + DateTime startingTime = DateTime.Now; + Rectangle rectAnimation = rectStart; + while (rectAnimation != rectEnd) + { + DateTime startPerMove = DateTime.Now; + + rectAnimation.X += dxLoc * speedFactor; + rectAnimation.Y += dyLoc * speedFactor; + rectAnimation.Width += dWidth * speedFactor; + rectAnimation.Height += dHeight * speedFactor; + if (Math.Sign(rectEnd.X - rectAnimation.X) != Math.Sign(dxLoc)) + rectAnimation.X = rectEnd.X; + if (Math.Sign(rectEnd.Y - rectAnimation.Y) != Math.Sign(dyLoc)) + rectAnimation.Y = rectEnd.Y; + if (Math.Sign(rectEnd.Width - rectAnimation.Width) != Math.Sign(dWidth)) + rectAnimation.Width = rectEnd.Width; + if (Math.Sign(rectEnd.Height - rectAnimation.Height) != Math.Sign(dHeight)) + rectAnimation.Height = rectEnd.Height; + control.Bounds = rectAnimation; + + if (control.Parent != null) + control.Parent.Update(); + else + control.Update(); + + remainPixels -= speedFactor; + + while (true) + { + DateTime now = DateTime.Now; + TimeSpan elapsedPerMove = now - startPerMove; + TimeSpan elapsedTime = now - startingTime; + if ((time - elapsedTime).TotalMilliseconds <= 0) + { + speedFactor = remainPixels; + break; + } + else + { + if ((int)(time - elapsedTime).TotalMilliseconds == 0) + speedFactor = 1; + else + { + try + { + + speedFactor = remainPixels * (int)elapsedPerMove.TotalMilliseconds / (int)((time - elapsedTime).TotalMilliseconds); + } + catch { } + } + } + if (speedFactor >= 1) + break; + } + } + } + + if (!show) + { + control.Visible = false; + control.Bounds = rectStart; + } + } + + // internal static Keys GetPressedKey() + // { + // NativeFunctions.GetKeyboardState + // + // return Keys.None; + // } + + internal static eWinXPColorScheme WinXPColorScheme + { + get + { + eWinXPColorScheme c = eWinXPColorScheme.Undetermined; + if (BarFunctions.ThemedOS && NativeFunctions.ColorDepth >= 16) + { + if (m_IsVista) + c = eWinXPColorScheme.Blue; + else 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; + } + } + + internal static Bitmap LoadBitmap(string imageName) + { + DotNetBarResourcesAttribute att = Attribute.GetCustomAttribute(System.Reflection.Assembly.GetExecutingAssembly(), typeof(DotNetBarResourcesAttribute)) as DotNetBarResourcesAttribute; + if (att != null && att.NamespacePrefix != "") + { + return new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream(att.NamespacePrefix + "." + imageName)); + } + else + return new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager), imageName); + } + + internal static Icon LoadIcon(string imageName) + { + DotNetBarResourcesAttribute att = Attribute.GetCustomAttribute(System.Reflection.Assembly.GetExecutingAssembly(), typeof(DotNetBarResourcesAttribute)) as DotNetBarResourcesAttribute; + if (att != null && att.NamespacePrefix != "") + { + return new Icon(Assembly.GetExecutingAssembly().GetManifestResourceStream(att.NamespacePrefix + "." + imageName)); + } + else + return new Icon(typeof(DevComponents.DotNetBar.DotNetBarManager), imageName); + } + + public static Graphics CreateGraphics(Control objCtrl) + { + if (objCtrl is ItemControl) + return ((ItemControl)objCtrl).CreateGraphics(); + else if (objCtrl is Bar) + return ((Bar)objCtrl).CreateGraphics(); + else if (objCtrl is ExplorerBar) + return ((ExplorerBar)objCtrl).CreateGraphics(); + else if (objCtrl is BaseItemControl) + return ((BaseItemControl)objCtrl).CreateGraphics(); + else if (objCtrl is BarBaseControl) + return ((BarBaseControl)objCtrl).CreateGraphics(); + else if (objCtrl is PanelControl) + return ((PanelControl)objCtrl).CreateGraphics(); + else if (objCtrl is PopupItemControl) + return ((PopupItemControl)objCtrl).CreateGraphics(); + + return objCtrl.CreateGraphics(); + } + + public static bool IsOffice2007Style(eDotNetBarStyle style) + { + if (style == eDotNetBarStyle.StyleManagerControlled) + style = StyleManager.GetEffectiveStyle(); + return (style == eDotNetBarStyle.Office2007 || style == eDotNetBarStyle.Office2010 || style == eDotNetBarStyle.Windows7 || StyleManager.IsMetro(style)); + } + + public static bool IsOffice2010Style(eDotNetBarStyle style) + { + if (style == eDotNetBarStyle.StyleManagerControlled) + style = StyleManager.GetEffectiveStyle(); + return (style == eDotNetBarStyle.Office2010 || style == eDotNetBarStyle.Windows7 || StyleManager.IsMetro(style)); + } + + public static bool IsOffice2007StyleOnly(eDotNetBarStyle style) + { + if (style == eDotNetBarStyle.StyleManagerControlled) + style = StyleManager.GetEffectiveStyle(); + return (style == eDotNetBarStyle.Office2007); + } + } + + internal class ScreenInformation + { + public Rectangle Bounds = Rectangle.Empty; + public Rectangle WorkingArea = Rectangle.Empty; + public bool Primary = false; + public ScreenInformation(Rectangle bounds, Rectangle workingarea) + { + this.Bounds = bounds; + this.WorkingArea = workingarea; + } + public ScreenInformation(Rectangle bounds, Rectangle workingarea, bool primary) + { + this.Bounds = bounds; + this.WorkingArea = workingarea; + this.Primary = primary; + } + } + + internal enum eWinXPColorScheme + { + Undetermined, + Blue, + OliveGreen, + Silver + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public class LocalizationManager : IDisposable + { + private ResourceManager m_ResourceManager = null; + private IOwnerLocalize m_Manager = null; + + public LocalizationManager() + : this(null) + { + } + public LocalizationManager(IOwnerLocalize manager) + { + m_Manager = manager; + } + public void Dispose() + { + m_ResourceManager = null; + m_Manager = null; + } + + public string GetDefaultLocalizedString(string key) + { + string s = GetLocalizedString(key); + if (s == "" || s == null) + { + ResourceManager res = BarFunctions.GetResourceManager(true); + s = res.GetString(key); + } + if (s == null) + s = ""; + return s; + } + + public static string GetLocalizedString(string key, string defaultValue) + { + LocalizeEventArgs e = new LocalizeEventArgs(); + e.Key = key; + e.LocalizedValue = defaultValue; + LocalizationKeys.InvokeLocalizeString(e); + if (e.Handled) + return e.LocalizedValue; + + return defaultValue; + } + + public string GetLocalizedString(string key) + { + string s = ""; + if (m_ResourceManager == null) + m_ResourceManager = BarFunctions.GetResourceManager(); + if (m_ResourceManager != null) + { + s = m_ResourceManager.GetString(key); + if (s == null) + s = ""; + } + + // Fire static event first + LocalizeEventArgs e = new LocalizeEventArgs(); + e.Key = key; + e.LocalizedValue = s; + LocalizationKeys.InvokeLocalizeString(e); + if (e.Handled) + return e.LocalizedValue; + + + if (m_Manager != null) + { + m_Manager.InvokeLocalizeString(e); + if (e.Handled) + return e.LocalizedValue; + } + + return s; + } + } +} diff --git a/PROMS/DotNetBar Source Code/BarSerialization/BarSerializationXml.cs b/PROMS/DotNetBar Source Code/BarSerialization/BarSerializationXml.cs new file mode 100644 index 00000000..b69a675d --- /dev/null +++ b/PROMS/DotNetBar Source Code/BarSerialization/BarSerializationXml.cs @@ -0,0 +1,14 @@ +using System; + +namespace DevComponents.DotNetBar +{ + /// + /// Holds the XML element and attribute names for bar serialization. + /// + internal class BarSerializationXml + { + public static string Bar="bar"; + public static string Name="name"; + public static string Custom="custom"; + } +} diff --git a/PROMS/DotNetBar Source Code/BarTextBox.cs b/PROMS/DotNetBar Source Code/BarTextBox.cs new file mode 100644 index 00000000..edf0c230 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BarTextBox.cs @@ -0,0 +1,80 @@ +using System; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for BarTextBox. + /// + internal class BarTextBox:TextBox + { + private int m_LastFocusWindow; + private string m_OriginalText; + public BarTextBox() + { + this.BorderStyle=System.Windows.Forms.BorderStyle.None; + this.AutoSize=false; + this.TabStop=false; + m_LastFocusWindow=0; + } + + protected override void WndProc(ref Message m) + { + if(m.Msg==NativeFunctions.WM_SETFOCUS) + { + m_LastFocusWindow=m.WParam.ToInt32(); + m_OriginalText=this.Text; + } + base.WndProc(ref m); + } + + public void ReleaseFocus() + { + if(this.Focused && m_LastFocusWindow!=0) + { + int focus=m_LastFocusWindow; + m_LastFocusWindow=0; + Control ctrl=Control.FromChildHandle(new System.IntPtr(focus)); + if(ctrl!=this) + { + Control p=this.Parent; + while(p!=null) + { + if(p==ctrl) + return; + p=p.Parent; + } + + if(ctrl!=null) + ctrl.Focus(); + else + { + NativeFunctions.SetFocus(focus); + } + } + + //this.OnLostFocus(new System.EventArgs()); + //this.InvokeLostFocus(this,new System.EventArgs()); + } + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if(e.KeyCode==Keys.Enter) + ReleaseFocus(); + else if(e.KeyCode==Keys.Escape) + { + this.Text=m_OriginalText; + ReleaseFocus(); + } + + base.OnKeyDown(e); + } + + protected override void OnLostFocus(EventArgs e) + { + m_LastFocusWindow=0; + base.OnLostFocus(e); + } + } +} diff --git a/PROMS/DotNetBar Source Code/BarUtilities.cs b/PROMS/DotNetBar Source Code/BarUtilities.cs new file mode 100644 index 00000000..9e46f569 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BarUtilities.cs @@ -0,0 +1,422 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Drawing.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents class with static functions that provide commonly used utility functions when working with + /// Bar objects and items hosted by Bar object. + /// + public class BarUtilities + { + #region Docking + /// + /// Sets Bar visible property and remembers the auto-hide state. + /// + /// Bar to set visibility for. + /// true if visible otherwise false + public static void SetBarVisible(Bar bar, bool visible) + { + if (bar == null || bar.Visible == visible) + return; + + DotNetBarManager manager = bar.Owner as DotNetBarManager; + if (manager != null) + manager.SuspendLayout = true; + + try + { + if (visible) + { + bar.Visible = true; + if (bar.PropertyBag.ContainsKey(BarPropertyBagKeys.AutoHideSetting)) + { + bar.PropertyBag.Remove(BarPropertyBagKeys.AutoHideSetting); + bar.AutoHide = true; + } + } + else + { + if (bar.PropertyBag.ContainsKey(BarPropertyBagKeys.AutoHideSetting)) + bar.PropertyBag.Remove(BarPropertyBagKeys.AutoHideSetting); + // Remember auto-hide setting + if (bar.AutoHide) + bar.PropertyBag.Add(BarPropertyBagKeys.AutoHideSetting, true); + bar.CloseBar(); + } + } + finally + { + if (manager != null) + manager.SuspendLayout = false; + bar.RecalcLayout(); + } + } + + /// + /// Sets the visible property of DockContainerItem and hides the bar if the given item is the last visible item on the bar. + /// It will also automatically display the bar if bar is not visible. + /// + /// DockContainerItem to set visibility for. + /// Indicates the visibility of the item + public static void SetDockContainerVisible(DevComponents.DotNetBar.DockContainerItem item, bool visible) + { + if(item==null || item.Visible==visible) + return; + + DevComponents.DotNetBar.Bar containerBar=item.ContainerControl as DevComponents.DotNetBar.Bar; + + if(containerBar==null) + { + // If bar has not been assigned yet just set the visible property and exit + item.Visible=visible; + return; + } + + DotNetBarManager manager=containerBar.Owner as DotNetBarManager; + if(manager!=null) + manager.SuspendLayout=true; + + try + { + int visibleCount=containerBar.VisibleItemCount; + + if(visible) + { + item.Visible=true; + if(!containerBar.AutoHide && !containerBar.Visible && visibleCount<=1) + { + containerBar.Visible=true; + if(containerBar.PropertyBag.ContainsKey(BarPropertyBagKeys.AutoHideSetting)) + { + containerBar.PropertyBag.Remove(BarPropertyBagKeys.AutoHideSetting); + containerBar.AutoHide=true; + } + } + } + else + { + if (visibleCount <= 1) + { + if (containerBar.PropertyBag.ContainsKey(BarPropertyBagKeys.AutoHideSetting)) + containerBar.PropertyBag.Remove(BarPropertyBagKeys.AutoHideSetting); + // Remember auto-hide setting + if (containerBar.AutoHide) + containerBar.PropertyBag.Add(BarPropertyBagKeys.AutoHideSetting, true); + containerBar.CloseBar(); + } + item.Visible=false; + } + } + finally + { + if(manager!=null) + manager.SuspendLayout=false; + containerBar.RecalcLayout(); + } + } + + /// + /// Creates new instance of the bar and sets its properties so bar can be used as Document bar. + /// + /// Returns new instance of the bar. + public static Bar CreateDocumentBar() + { + Bar bar=new Bar(); + BarUtilities.InitializeDocumentBar(bar); + return bar; + } + + /// + /// Sets the properties on a bar so it can be used as Document bar. + /// + /// Bar to set properties of. + public static void InitializeDocumentBar(Bar bar) + { + TypeDescriptor.GetProperties(bar)["LayoutType"].SetValue(bar,eLayoutType.DockContainer); + TypeDescriptor.GetProperties(bar)["DockTabAlignment"].SetValue(bar,eTabStripAlignment.Top); + TypeDescriptor.GetProperties(bar)["AlwaysDisplayDockTab"].SetValue(bar,true); + TypeDescriptor.GetProperties(bar)["Stretch"].SetValue(bar,true); + TypeDescriptor.GetProperties(bar)["GrabHandleStyle"].SetValue(bar,eGrabHandleStyle.None); + TypeDescriptor.GetProperties(bar)["CanDockBottom"].SetValue(bar,false); + TypeDescriptor.GetProperties(bar)["CanDockTop"].SetValue(bar,false); + TypeDescriptor.GetProperties(bar)["CanDockLeft"].SetValue(bar,false); + TypeDescriptor.GetProperties(bar)["CanDockRight"].SetValue(bar,false); + TypeDescriptor.GetProperties(bar)["CanDockDocument"].SetValue(bar,true); + TypeDescriptor.GetProperties(bar)["CanUndock"].SetValue(bar,false); + TypeDescriptor.GetProperties(bar)["CanHide"].SetValue(bar,true); + TypeDescriptor.GetProperties(bar)["CanCustomize"].SetValue(bar,false); + TypeDescriptor.GetProperties(bar)["TabNavigation"].SetValue(bar,true); + } + + #region Win API + [DllImport("user32")] + private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + [DllImport("user32")] + private static extern int GetWindowLong(IntPtr hWnd, int nIndex); + private const int GWL_EXSTYLE = (-20); + private const int WS_EX_CLIENTEDGE = 0x00000200; + [DllImport("user32")] + private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); + const int SWP_FRAMECHANGED = 0x0020; + const int SWP_NOSIZE = 0x0001; + const int SWP_NOMOVE = 0x0002; + const int SWP_NOZORDER = 0x0004; + #endregion + + /// + /// Changes the MDI Client border edge to remove 3D border or to add it. + /// + /// Reference to MDI Client object. + /// Indicates whether to remove border. + public static void ChangeMDIClientBorder(System.Windows.Forms.MdiClient c, bool removeBorder) + { + if (c != null) + { + int exStyle = GetWindowLong(c.Handle, GWL_EXSTYLE); + + if(removeBorder) + exStyle ^= WS_EX_CLIENTEDGE; + else + exStyle |= WS_EX_CLIENTEDGE; + + SetWindowLong(c.Handle, GWL_EXSTYLE, exStyle); + SetWindowPos(c.Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + } + } + + /// + /// Changes the MDI Client border edge to remove 3D border or to add it. + /// + /// Reference to MDI parent form. + /// Indicates whether to remove border. + public static void ChangeMDIClientBorder(System.Windows.Forms.Form c, bool removeBorder) + { + if (c.IsMdiContainer && c.IsHandleCreated) + { + foreach (System.Windows.Forms.Control control in c.Controls) + { + if (control is System.Windows.Forms.MdiClient) + { + ChangeMDIClientBorder(control as System.Windows.Forms.MdiClient, removeBorder); + break; + } + } + } + } + #endregion + + #region Item Invalidate + internal static void InvalidateFontChange(SubItemsCollection col) + { + foreach (BaseItem item in col) + { + InvalidateFontChange(item); + } + } + + internal static void InvalidateFontChange(BaseItem item) + { + if (item.TextMarkupBody != null) item.TextMarkupBody.InvalidateElementsSize(); + if (item.SubItems.Count > 0) InvalidateFontChange(item.SubItems); + } + #endregion + + internal static void InvokeRecalcLayout(System.Windows.Forms.Control control) + { + if (control is Bar) + ((Bar)control).RecalcLayout(); + else if (control is ItemControl) + ((ItemControl)control).RecalcLayout(); + else if (control is BaseItemControl) + ((BaseItemControl)control).RecalcLayout(); + else if (control is ExplorerBar) + ((ExplorerBar)control).RecalcLayout(); + else if (control is SideBar) + ((SideBar)control).RecalcLayout(); + } + + private static volatile bool _FadeAnimatorEnabled = true; + /// + /// Gets or sets whether Fade Animation is enabled on system level for DotNetBar items which use this. Default value is true. + /// + public static bool FadeAnimatorEnabled + { + get { return _FadeAnimatorEnabled; } + set { _FadeAnimatorEnabled = value; } + } + + /// + /// Gets or sets whether StringFormat internally used by all DotNetBar controls to render text is GenericDefault. Default value is false + /// which indicates that GenericTypographic is used. + /// + public static bool UseGenericDefaultStringFormat + { + get { return TextDrawing.UseGenericDefault; } + set { TextDrawing.UseGenericDefault = value; } + } + + /// + /// Gets or sets the anti-alias text rendering hint that will be used to render text on controls that have AntiAlias property set to true. + /// + public static TextRenderingHint AntiAliasTextRenderingHint + { + get + { + return DisplayHelp.AntiAliasTextRenderingHint; + } + set + { + DisplayHelp.AntiAliasTextRenderingHint = value; + } + } + +#if FRAMEWORK20 + /// + /// Gets or sets whether .NET Framework TextRenderer class is used for text rendering instead of Graphics.DrawString. + /// Default value is false. + /// Using TextRenderer will disable the Fade and Animation effects on controls because of issues in TextRenderer when drawing text on transparent + /// surfaces. + /// + public static bool UseTextRenderer + { + get { return TextDrawing.UseTextRenderer; } + set { TextDrawing.UseTextRenderer = value; } + } +#endif + + + private static bool _AlwaysGenerateAccessibilityFocusEvent = false; + /// + /// Gets or sets whether items always generate the Focus accessibility event when mouse enters the item. Default value is false which indicates + /// that focus event will be raised only when item is on menu bar. + /// + public static bool AlwaysGenerateAccessibilityFocusEvent + { + get { return _AlwaysGenerateAccessibilityFocusEvent; } + set + { + _AlwaysGenerateAccessibilityFocusEvent = value; + } + } + + internal static bool IsModalFormOpen + { + get + { +#if (FRAMEWORK20) + for (int i = 0; i < System.Windows.Forms.Application.OpenForms.Count; i++) + { + System.Windows.Forms.Form form = System.Windows.Forms.Application.OpenForms[i]; + if (form.Modal) return true; + } +#endif + return false; + } + } + + private static bool _AutoRemoveMessageFilter = false; + /// + /// Gets or sets whether Application Message Filter that is registered by popup controls + /// is automatically unregistered when last control is disposed. Default value is false and + /// in most cases should not be changed. + /// + public static bool AutoRemoveMessageFilter + { + get { return _AutoRemoveMessageFilter; } + set { _AutoRemoveMessageFilter = value; } + } + + private static int _TextMarkupCultureSpecific = 3; + /// + /// Get or sets the text-markup padding for text measurement when running on Japanese version of Windows. + /// + public static int TextMarkupCultureSpecificPadding + { + get { return _TextMarkupCultureSpecific; } + set + { + _TextMarkupCultureSpecific = value; + } + } + + private static bool _DisposeItemImages = false; + /// + /// Gets or sets whether Image and Icon resources assigned to items and controls are automatically disposed when + /// control or item is disposed. Default value is false. + /// + public static bool DisposeItemImages + { + get + { + return _DisposeItemImages; + } + set + { + _DisposeItemImages = value; + } + } + + /// + /// Disposes image reference and sets it to null. + /// + /// Reference to image to dispose. + internal static void DisposeImage(ref System.Drawing.Image image) + { + if (image == null) return; + image.Dispose(); + image = null; + } + /// + /// Disposes image reference and sets it to null. + /// + /// Reference to image to dispose. + internal static void DisposeImage(ref System.Drawing.Icon icon) + { + if (icon == null) return; + icon.Dispose(); + icon = null; + } + + #region Delayed Invoke + /// + /// Invokes the method asynchronously using the WinForms Timer. + /// + /// Method to invoke. + public static void InvokeDelayed(MethodInvoker method) + { + InvokeDelayed(method, 10); + } + /// + /// Invokes the method asynchronously using the WinForms Timer. + /// + /// Method to invoke. + /// Time in milliseconds after which method is invoked. + public static void InvokeDelayed(MethodInvoker method, int delayInterval) + { + Timer delayedInvokeTimer = new Timer(); + delayedInvokeTimer = new Timer(); + delayedInvokeTimer.Tag = method; + delayedInvokeTimer.Interval = delayInterval; + delayedInvokeTimer.Tick += new EventHandler(DelayedInvokeTimerTick); + delayedInvokeTimer.Start(); + } + private static void DelayedInvokeTimerTick(object sender, EventArgs e) + { + Timer timer = (Timer)sender; + MethodInvoker method = (MethodInvoker)timer.Tag; + timer.Stop(); + timer.Dispose(); + method.Invoke(); + } + #endregion + } + + internal class BarPropertyBagKeys + { + public static string AutoHideSetting="autohide"; + } +} diff --git a/PROMS/DotNetBar Source Code/Bars.cs b/PROMS/DotNetBar Source Code/Bars.cs new file mode 100644 index 00000000..42530b22 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Bars.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections; +using System.Runtime.Serialization; +using System.Xml; + +namespace DevComponents.DotNetBar +{ + + /// + /// Collection of Bar objects. + /// + public class Bars:System.Collections.CollectionBase,IDisposable + { + private DotNetBarManager m_Owner; + internal Bars(DotNetBarManager Owner) + { + m_Owner=Owner; + } + + internal DotNetBarManager Owner + { + get + { + return m_Owner; + } + } + + /// + /// Releases the resources used by the Component. + /// + public void Dispose() + { + m_Owner=null; + List.Clear(); + } + + /// + /// Adds an Bar to the end of Bars collection. + /// + /// The Bar to be added to the end of the Bars collection. + public void Add(Bar bar) + { + if(List.IndexOf(bar)<0) + List.Add(bar); + else + throw new InvalidOperationException("Bar is already in collection."); + } + + protected override void OnInsertComplete(int index,object value) + { + base.OnInsertComplete(index,value); + Bar bar=(Bar)value; + bar.Owner=m_Owner; + bar.ThemeAware=m_Owner.ThemeAware; + bar.Style=m_Owner.Style; + IOwnerBarSupport ownersupport=m_Owner as IOwnerBarSupport; + if(ownersupport!=null) + ownersupport.AddShortcutsFromBar(bar); + bar.OnAddedToBars(); + } + + /// + /// Gets the Bar at the specified index. + /// + public Bar this[int Index] + { + get + { + return List[Index] as Bar; + } + } + + /// + /// Gets the Bar with the specified name. + /// + public Bar this[string Name] + { + get + { + foreach(Bar bar in List) + if(bar.Name==Name) + return bar; + return null; + } + } + + /// + /// Removes specified bar from collection. + /// + /// Bar to remove + public virtual void Remove(Bar bar) + { + List.Remove(bar); + } + + protected override void OnRemoveComplete(int index,object value) + { + Bar bar=(Bar)value; + IOwnerBarSupport ownersupport=m_Owner as IOwnerBarSupport; + if(ownersupport!=null) + ownersupport.RemoveShortcutsFromBar(bar); + + if(bar.Visible) + bar.HideBar(); + + if(bar.Parent!=null) + { + if(bar.Parent is DockSite && ((DockSite)bar.Parent).IsDocumentDock) + ((DockSite)bar.Parent).GetDocumentUIManager().UnDock(bar); + if(bar.Parent!=null) + bar.Parent.Controls.Remove(bar); + } + + base.OnRemoveComplete(index,value); + } + + protected override void OnClear() + { + if (m_Owner != null && m_Owner.GetDesignMode()) + return; + + foreach(Bar bar in List) + { + if (bar.GetDesignMode()) + continue; + if(bar.AutoHide) + bar.AutoHide=false; + if(bar.Visible) + bar.HideBar(); + if (bar.DockSide == eDockSide.Document && bar.Parent is DockSite && ((DockSite)bar.Parent).GetDocumentUIManager()!=null) + ((DockSite)bar.Parent).GetDocumentUIManager().UnDock(bar); + if(bar!=null && !bar.IsDisposed) + ((IOwnerBarSupport)m_Owner).RemoveShortcutsFromBar(bar); + if(bar.Parent!=null) + bar.Parent.Controls.Remove(bar); + if (!bar.GetDesignMode()) + bar.Dispose(); + } + } + + /// + /// Determines whether an Bar is in the collection. + /// + /// The Bar to locate in the collection. + /// true if item is found in the collection; otherwise, false. + public bool Contains(Bar bar) + { + return List.Contains(bar); + } + + /// + /// Determines whether bar with given name is in collection. + /// + /// Name of the bar + /// True if bar is part of this collection, otherwise false. + public bool Contains(string name) + { + foreach(Bar bar in this.List) + if(bar.Name==name) + return true; + return false; + } + + /// + /// Returns the zero-based index of the Bar in the collection. + /// + /// Bar to locate. + /// + public int IndexOf(Bar bar) + { + return List.IndexOf(bar); + } + + public void CopyTo(System.Array array) + { + List.CopyTo(array,0); + } + + internal void ClearNonDocumentBars() + { + ArrayList removeList=new ArrayList(this.Count); + foreach(Bar bar in this.List) + { + if(bar.DockSide!=eDockSide.Document) + removeList.Add(bar); + } + + foreach(Bar bar in removeList) + this.Remove(bar); + } + } +} diff --git a/PROMS/DotNetBar Source Code/BaseItem.cs b/PROMS/DotNetBar Source Code/BaseItem.cs new file mode 100644 index 00000000..ee0af3b7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BaseItem.cs @@ -0,0 +1,4880 @@ +using System; +using System.Collections; +using DevComponents.UI.ContentManager; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Defines the base class for items that are used by DotNetBar. + /// + [System.ComponentModel.ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false)] + public abstract class BaseItem : Component, ICloneable, IBlock, ICommandSource, IComparable +#if FRAMEWORK20 + , IBindableComponent +#endif + { + #region Event Definition + // Events + /// + /// Occurs when Item is clicked. + /// + [System.ComponentModel.Description("Occurs when Item is clicked.")] + public event EventHandler Click; + + /// + /// Occurs when Item is double-clicked. + /// + [System.ComponentModel.Description("Occurs when Item is double-clicked.")] + public event EventHandler DoubleClick; + + /// + /// Occurs when Item Expanded property has changed. + /// + [System.ComponentModel.Description("Occurs when Item Expanded property has changed.")] + public event EventHandler ExpandChange; + + /// + /// Occurs when item loses input focus. + /// + [System.ComponentModel.Description("Occurs when item loses input focus.")] + public event EventHandler LostFocus; + + /// + /// Occurs when item receives input focus. + /// + [System.ComponentModel.Description("Occurs when item receives input focus.")] + public event EventHandler GotFocus; + + /// + /// Occurs when mouse button is pressed. + /// + [System.ComponentModel.Description("Occurs when mouse button is pressed.")] + public event System.Windows.Forms.MouseEventHandler MouseDown; + + /// + /// Occurs when mouse button is released. + /// + [System.ComponentModel.Description("Occurs when mouse button is released.")] + public event System.Windows.Forms.MouseEventHandler MouseUp; + + /// + /// Occurs when mouse enters the item. + /// + [System.ComponentModel.Description("Occurs when mouse enters the item.")] + public event EventHandler MouseEnter; + + /// + /// Occurs when mouse leaves the item. + /// + [System.ComponentModel.Description("Occurs when mouse leaves the item.")] + public event EventHandler MouseLeave; + + /// + /// Occurs when mouse moves over the item. + /// + [System.ComponentModel.Description("Occurs when mouse moves over the item.")] + public event System.Windows.Forms.MouseEventHandler MouseMove; + + /// + /// Occurs when mouse remains still inside an item for an amount of time. + /// + [System.ComponentModel.Description("Occurs when mouse remains still inside an item for an amount of time.")] + public event EventHandler MouseHover; + + /// + /// Occurs when copy of the item is made. + /// + [System.ComponentModel.Description("Occurs when copy of the item is made.")] + public event EventHandler ItemCopied; + + /// + /// Occurs when Text property of an Item has changed. + /// + [System.ComponentModel.Description("Occurs when Text property of an Item has changed.")] + public event EventHandler TextChanged; + + /// + /// Occurs when Visible property of an Item has changed. + /// + [System.ComponentModel.Description("Occurs when Visible property of an Item has changed.")] + public event EventHandler VisibleChanged; + + /// + /// Occurs when Enabled property of an Item has changed. + /// + [System.ComponentModel.Description("Occurs when Enabled property of an Item has changed.")] + public event EventHandler EnabledChanged; + + ///// + ///// Occurs when component is Disposed. + ///// + //[System.ComponentModel.Description("Occurs when component is Disposed.")] + //public event EventHandler Disposed; + + /// + /// Occurs when item's tooltip visibility has changed. + /// + [System.ComponentModel.Description("Occurs when item's tooltip visibility has changed.")] + public event EventHandler ToolTipVisibleChanged; +// /// +// /// Occurs when actual visiblity on screen of an item has changed i.e. Displayed property change. +// /// +// [System.ComponentModel.Description("Occurs when actual visiblity on screen of an item has changed.")] +// public event EventHandler DisplayedChanged; + /// + /// Occurs when content of SubItems collection has changed. + /// + [Description("Occurs when content of SubItems collection has changed")] + public event CollectionChangeEventHandler SubItemsChanged; + #endregion + + #region Private variables + protected string m_Text; + protected System.Drawing.Rectangle m_Rect; + protected SubItemsCollection m_SubItems; + protected bool m_Visible; + protected BaseItem m_HotSubItem; // Sub Item with Mouse over it + protected bool m_IsContainer; + protected BaseItem m_Parent; + protected bool m_NeedRecalcSize; + protected bool m_Expanded; + protected bool m_AutoExpand; // If this is a container should it expand automaticly its child items + protected object m_ContainerControl; + protected bool m_Displayed; // Set to true when item is shown on screen + protected object m_ItemData; + protected bool m_Enabled; + protected bool m_BeginGroup; + protected eDotNetBarStyle m_Style; + protected string m_Description; // Item description + protected string m_Tooltip; // Tooltip + protected string m_Name=""; // Unique Item name that can be used to access item + private string m_GlobalName = ""; + protected string m_Category; + protected eOrientation m_Orientation; + protected bool m_SystemItem; + protected eSupportedOrientation m_SupportedOrientation=eSupportedOrientation.Both; + protected bool m_RecalculatingSize=false; + protected bool m_CheckMouseMovePressed = false; + private bool m_CanCustomize; + private int m_Id; + private bool m_ShowSubItems; + private bool m_Focused; + private bool m_Stretch=false; + internal Rectangle m_ViewRectangle; + + protected ToolTip m_ToolTipWnd; + private static int s_IdCounter; + private bool m_IsOnCustomizeMenu; + private bool m_IsOnCustomizeDialog; + protected char m_AccessKey; + private bool m_DesignMode; + private eItemAlignment m_ItemAlignment; // Item alignment in containers that support alignment + + private ShortcutsCollection m_Shortcuts; + private string m_ShortcutString = ""; + + private System.Drawing.Point m_MouseDownPt; + + private object m_Owner; + + private bool m_ClickAutoRepeat=false; + private int m_ClickRepeatInterval=600; + private bool m_AutoCollapseOnClick=true; + private bool m_SuspendLayout=false; + private bool m_IsRightToLeft = false; + //private System.ComponentModel.ISite m_ComponentSite=null; + protected bool m_ThemeAware=false; + + // When item is parented to the Items collection GlobalItem is set to true. + // This flag is used to propagate property changes to all items with the same name. + // Setting for example Visible property on the item that has GlobalItem true will + // set visible property to the same value on all items with the same name. + private bool m_GlobalItem=true; + + private eDesignInsertPosition m_DesignInsertMarker=eDesignInsertPosition.None; + + private System.Windows.Forms.Cursor m_Cursor=null; + private System.Windows.Forms.Cursor m_ContainerCursor=null; + protected bool m_ShouldSerialize=true; + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool _IgnoreClick=false; + protected bool m_AllowOnlyOneSubItemExpanded=true; // Controls whether only ONE sub item can be expanded at a time, see InternalMouseDown + + //private System.Windows.Forms.AccessibleObject m_Accessible=null; + private string m_AccessibleDefaultActionDescription=""; + private System.Windows.Forms.AccessibleRole m_AccessibleRole=System.Windows.Forms.AccessibleRole.Default; + private string m_AccessibleName=""; + private string m_AccessibleDescription=""; + private bool m_IsAccessible=true; + + // Used to save extended information about item customization... + private string m_OriginalBarName=""; + private int m_OriginalPosition=-1; + private string m_KeyTips = ""; + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Point DesignTimeMouseDownPoint = Point.Empty; + internal bool RenderText = true; + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool MouseUpNotification = false; + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool MouseDownCapture = false; // Indicates whether item will receive mouse messages if it is pressed and mouse leaves the item + private bool m_UserCustomized = false; + private bool m_IsDisposed = false; + #endregion + + #region Constructor + /// + /// Creates new instance of BaseItem. + /// + public BaseItem():this("","") {} + /// + /// Creates new instance of BaseItem and assigns item name. + /// + /// Item name. + public BaseItem(string sItemName):this(sItemName,""){} + /// + /// Creates new instance of BaseItem and assigns item name and item text. + /// + /// Item Name + /// Item Text + public BaseItem(string sItemName, string ItemText) + { + if (ItemText == null) + ItemText = ""; + m_Text=ItemText; + if(m_Text!="") + m_AccessKey=NativeFunctions.GetAccessKey(m_Text); + m_Rect=System.Drawing.Rectangle.Empty; + m_ContainerControl=null; + m_HotSubItem=null; + m_IsContainer=false; + m_SubItems=null; + m_Parent=null; + m_NeedRecalcSize=true; + m_Visible=true; + m_Expanded=false; + m_AutoExpand=false; + m_ItemData=null; + m_Enabled=true; + m_BeginGroup=false; + m_Style=eDotNetBarStyle.OfficeXP; + m_Description=""; + m_Tooltip=""; + m_Name=sItemName; + m_Category=""; + m_Orientation=eOrientation.Horizontal; + m_ToolTipWnd=null; + m_Id=++s_IdCounter; + m_IsOnCustomizeMenu=false; + m_IsOnCustomizeDialog=false; + m_SystemItem=false; + //m_AccessKey=; + m_Shortcuts=null; + m_DesignMode=false; + m_CanCustomize=true; + m_ShowSubItems=true; + m_ItemAlignment=eItemAlignment.Near; + m_Focused=false; + m_Owner=null; + MarkupTextChanged(); + } + #endregion + + #region Serialization + /// + /// Serializes the item and all sub-items into the XmlElement. + /// + /// XmlElement to serialize the item to. + protected internal virtual void Serialize(ItemSerializationContext context) + { + System.Xml.XmlElement ThisItem = context.ItemXmlElement; + Type t=this.GetType(); + System.Reflection.AssemblyName aname=t.Assembly.GetName(); + if(aname.Name!="DevComponents.DotNetBar") + ThisItem.SetAttribute("assembly",aname.Name+", PublicKeyToken="+System.Text.Encoding.ASCII.GetString(aname.GetPublicKey())); + else + ThisItem.SetAttribute("assembly",aname.Name); + + ThisItem.SetAttribute("class",t.FullName); + + ThisItem.SetAttribute("name",m_Name); + ThisItem.SetAttribute("globalname", m_GlobalName); + ThisItem.SetAttribute("text",m_Text); + ThisItem.SetAttribute("iscontainer",System.Xml.XmlConvert.ToString(m_IsContainer)); + ThisItem.SetAttribute("visible",System.Xml.XmlConvert.ToString(m_Visible)); + if(m_ItemData!=null && m_ItemData.ToString()!="") + ThisItem.SetAttribute("itemdata",m_ItemData.ToString()); + else + ThisItem.SetAttribute("itemdata",""); + ThisItem.SetAttribute("enabled",System.Xml.XmlConvert.ToString(m_Enabled)); + ThisItem.SetAttribute("begingroup",System.Xml.XmlConvert.ToString(m_BeginGroup)); + ThisItem.SetAttribute("style",System.Xml.XmlConvert.ToString((int)m_Style)); + ThisItem.SetAttribute("desc",m_Description); + ThisItem.SetAttribute("tooltip",m_Tooltip); + ThisItem.SetAttribute("category",m_Category); + ThisItem.SetAttribute("cancustomize",System.Xml.XmlConvert.ToString(m_CanCustomize)); + ThisItem.SetAttribute("showsubitems",System.Xml.XmlConvert.ToString(m_ShowSubItems)); + ThisItem.SetAttribute("itemalignment",System.Xml.XmlConvert.ToString((int)m_ItemAlignment)); + ThisItem.SetAttribute("stretch",System.Xml.XmlConvert.ToString(m_Stretch)); + ThisItem.SetAttribute("global",System.Xml.XmlConvert.ToString(m_GlobalItem)); + ThisItem.SetAttribute("themes",System.Xml.XmlConvert.ToString(m_ThemeAware)); + if(m_AccessibleDefaultActionDescription!="") + ThisItem.SetAttribute("adefdesc",m_AccessibleDefaultActionDescription); + if(m_AccessibleDescription!="") + ThisItem.SetAttribute("adesc",m_AccessibleDescription); + if(m_AccessibleName!="") + ThisItem.SetAttribute("aname",m_AccessibleName); + if(m_AccessibleRole!=System.Windows.Forms.AccessibleRole.Default) + ThisItem.SetAttribute("arole",System.Xml.XmlConvert.ToString((int)m_AccessibleRole)); + if(!m_AutoCollapseOnClick) + ThisItem.SetAttribute("autocollapse",System.Xml.XmlConvert.ToString(m_AutoCollapseOnClick)); + if(m_ClickAutoRepeat) + ThisItem.SetAttribute("autorepeat",System.Xml.XmlConvert.ToString(m_ClickAutoRepeat)); + if(m_ClickRepeatInterval!=600) + ThisItem.SetAttribute("clickrepinterv",System.Xml.XmlConvert.ToString(m_ClickRepeatInterval)); + //if(m_GenerateCommandLink) + // ThisItem.SetAttribute("GenerateCommandLink", System.Xml.XmlConvert.ToString(m_GenerateCommandLink)); + + + if(m_Cursor!=null) + { + if(m_Cursor==System.Windows.Forms.Cursors.Hand) + ThisItem.SetAttribute("cur","4"); + else if(m_Cursor==System.Windows.Forms.Cursors.AppStarting) + ThisItem.SetAttribute("cur","1"); + else if(m_Cursor==System.Windows.Forms.Cursors.Arrow) + ThisItem.SetAttribute("cur","2"); + else if(m_Cursor==System.Windows.Forms.Cursors.Cross) + ThisItem.SetAttribute("cur","3"); + else if(m_Cursor==System.Windows.Forms.Cursors.Help) + ThisItem.SetAttribute("cur","5"); + else if(m_Cursor==System.Windows.Forms.Cursors.HSplit) + ThisItem.SetAttribute("cur","6"); + else if(m_Cursor==System.Windows.Forms.Cursors.IBeam) + ThisItem.SetAttribute("cur","7"); + else if(m_Cursor==System.Windows.Forms.Cursors.No) + ThisItem.SetAttribute("cur","8"); + else if(m_Cursor==System.Windows.Forms.Cursors.NoMove2D) + ThisItem.SetAttribute("cur","9"); + else if(m_Cursor==System.Windows.Forms.Cursors.NoMoveHoriz) + ThisItem.SetAttribute("cur","10"); + else if(m_Cursor==System.Windows.Forms.Cursors.NoMoveVert) + ThisItem.SetAttribute("cur","11"); + else if(m_Cursor==System.Windows.Forms.Cursors.PanEast) + ThisItem.SetAttribute("cur","12"); + else if(m_Cursor==System.Windows.Forms.Cursors.PanNE) + ThisItem.SetAttribute("cur","13"); + else if(m_Cursor==System.Windows.Forms.Cursors.PanNorth) + ThisItem.SetAttribute("cur","14"); + else if(m_Cursor==System.Windows.Forms.Cursors.PanNW) + ThisItem.SetAttribute("cur","15"); + else if(m_Cursor==System.Windows.Forms.Cursors.PanSE) + ThisItem.SetAttribute("cur","16"); + else if(m_Cursor==System.Windows.Forms.Cursors.PanSouth) + ThisItem.SetAttribute("cur","17"); + else if(m_Cursor==System.Windows.Forms.Cursors.PanSW) + ThisItem.SetAttribute("cur","18"); + else if(m_Cursor==System.Windows.Forms.Cursors.PanWest) + ThisItem.SetAttribute("cur","19"); + else if(m_Cursor==System.Windows.Forms.Cursors.SizeAll) + ThisItem.SetAttribute("cur","20"); + else if(m_Cursor==System.Windows.Forms.Cursors.SizeNESW) + ThisItem.SetAttribute("cur","21"); + else if(m_Cursor==System.Windows.Forms.Cursors.SizeNS) + ThisItem.SetAttribute("cur","22"); + else if(m_Cursor==System.Windows.Forms.Cursors.SizeNWSE) + ThisItem.SetAttribute("cur","23"); + else if(m_Cursor==System.Windows.Forms.Cursors.SizeWE) + ThisItem.SetAttribute("cur","24"); + else if(m_Cursor==System.Windows.Forms.Cursors.UpArrow) + ThisItem.SetAttribute("cur","25"); + else if(m_Cursor==System.Windows.Forms.Cursors.VSplit) + ThisItem.SetAttribute("cur","26"); + else if(m_Cursor==System.Windows.Forms.Cursors.WaitCursor) + ThisItem.SetAttribute("cur","27"); + } + + if(SubItems.Count>0 && this.ShouldSerializeSubItems()) + { + System.Xml.XmlElement subitems=ThisItem.OwnerDocument.CreateElement("subitems"); + ThisItem.AppendChild(subitems); + foreach(BaseItem objItem in this.SubItems) + { + if(objItem.ShouldSerialize) + { + System.Xml.XmlElement ChildItem=ThisItem.OwnerDocument.CreateElement("item"); + t=objItem.GetType(); + subitems.AppendChild(ChildItem); + context.ItemXmlElement = ChildItem; + objItem.Serialize(context); + context.ItemXmlElement = ThisItem; + } + } + } + + // Serialize Shortcuts + if(m_Shortcuts!=null && m_Shortcuts.Count>0) + ThisItem.SetAttribute("shortcuts",m_Shortcuts.ToString(",")); + + if (context.HasSerializeItemHandlers) + { + System.Xml.XmlElement customData = ThisItem.OwnerDocument.CreateElement("customData"); + SerializeItemEventArgs e = new SerializeItemEventArgs(this, ThisItem, customData); + context.Serializer.InvokeSerializeItem(e); + if (customData.Attributes.Count > 0 || customData.ChildNodes.Count > 0) + ThisItem.AppendChild(customData); + } + } + + /// + /// Deserialize the Item from the XmlElement. + /// + /// Source XmlElement. + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void Deserialize(ItemSerializationContext context) + { + System.Xml.XmlElement ItemXmlSource = context.ItemXmlElement; + + m_Name=ItemXmlSource.GetAttribute("name"); + if (ItemXmlSource.HasAttribute("globalname")) + m_GlobalName = ItemXmlSource.GetAttribute("globalname"); + m_Text=ItemXmlSource.GetAttribute("text"); + m_AccessKey=NativeFunctions.GetAccessKey(m_Text); + m_IsContainer=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("iscontainer")); + if (context._DesignerHost == null) + m_Visible = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("visible")); + else + TypeDescriptor.GetProperties(this)["Visible"].SetValue(this, System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("visible"))); + if(ItemXmlSource.GetAttribute("itemdata")!="") + m_ItemData=ItemXmlSource.GetAttribute("itemdata"); + else + m_ItemData=null; + m_Enabled=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("enabled")); + m_BeginGroup=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("begingroup")); + m_Style=(eDotNetBarStyle)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("style")); + m_Description=ItemXmlSource.GetAttribute("desc"); + m_Tooltip=ItemXmlSource.GetAttribute("tooltip"); + m_Category=ItemXmlSource.GetAttribute("category"); + m_CanCustomize=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("cancustomize")); + m_ShowSubItems=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("showsubitems")); + m_ItemAlignment=(eItemAlignment)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("itemalignment")); + if(ItemXmlSource.HasAttribute("stretch")) + m_Stretch=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("stretch")); + else + m_Stretch=false; + if(ItemXmlSource.HasAttribute("global")) + m_GlobalItem=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("global")); + + if(ItemXmlSource.HasAttribute("themes")) + m_ThemeAware=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("themes")); + + if(ItemXmlSource.HasAttribute("adefdesc")) + m_AccessibleDefaultActionDescription=ItemXmlSource.GetAttribute("adefdesc"); + if(ItemXmlSource.HasAttribute("adesc")) + m_AccessibleDescription=ItemXmlSource.GetAttribute("adesc"); + if(ItemXmlSource.HasAttribute("aname")) + m_AccessibleName=ItemXmlSource.GetAttribute("aname"); + if(ItemXmlSource.HasAttribute("arole")) + m_AccessibleRole=(System.Windows.Forms.AccessibleRole)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("arole")); + if(ItemXmlSource.HasAttribute("autocollapse")) + m_AutoCollapseOnClick=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("autocollapse")); + else + m_AutoCollapseOnClick=true; + + if(ItemXmlSource.HasAttribute("autorepeat")) + m_ClickAutoRepeat=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("autorepeat")); + else + m_ClickAutoRepeat=false; + if(ItemXmlSource.HasAttribute("clickrepinterv")) + m_ClickRepeatInterval=System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("clickrepinterv")); + else + m_ClickRepeatInterval=600; + + //if (ItemXmlSource.HasAttribute("GenerateCommandLink")) + // m_GenerateCommandLink = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("GenerateCommandLink")); + //else + // m_GenerateCommandLink = false; + + // Load Cursor + if(ItemXmlSource.HasAttribute("cur")) + { + switch(ItemXmlSource.GetAttribute("cur")) + { + case "4": + m_Cursor=System.Windows.Forms.Cursors.Hand; + break; + case "1": + m_Cursor=System.Windows.Forms.Cursors.AppStarting; + break; + case "2": + m_Cursor=System.Windows.Forms.Cursors.Arrow; + break; + case "3": + m_Cursor=System.Windows.Forms.Cursors.Cross; + break; + case "5": + m_Cursor=System.Windows.Forms.Cursors.Help; + break; + case "6": + m_Cursor=System.Windows.Forms.Cursors.HSplit; + break; + case "7": + m_Cursor=System.Windows.Forms.Cursors.IBeam; + break; + case "8": + m_Cursor=System.Windows.Forms.Cursors.No; + break; + case "9": + m_Cursor=System.Windows.Forms.Cursors.NoMove2D; + break; + case "10": + m_Cursor=System.Windows.Forms.Cursors.NoMoveHoriz; + break; + case "11": + m_Cursor=System.Windows.Forms.Cursors.NoMoveVert; + break; + case "12": + m_Cursor=System.Windows.Forms.Cursors.PanEast; + break; + case "13": + m_Cursor=System.Windows.Forms.Cursors.PanNE; + break; + case "14": + m_Cursor=System.Windows.Forms.Cursors.PanNorth; + break; + case "15": + m_Cursor=System.Windows.Forms.Cursors.PanNW; + break; + case "16": + m_Cursor=System.Windows.Forms.Cursors.PanSE; + break; + case "17": + m_Cursor=System.Windows.Forms.Cursors.PanSouth; + break; + case "18": + m_Cursor=System.Windows.Forms.Cursors.PanSW; + break; + case "19": + m_Cursor=System.Windows.Forms.Cursors.PanWest; + break; + case "20": + m_Cursor=System.Windows.Forms.Cursors.SizeAll; + break; + case "21": + m_Cursor=System.Windows.Forms.Cursors.SizeNESW; + break; + case "22": + m_Cursor=System.Windows.Forms.Cursors.SizeNS; + break; + case "23": + m_Cursor=System.Windows.Forms.Cursors.SizeNWSE; + break; + case "24": + m_Cursor=System.Windows.Forms.Cursors.SizeWE; + break; + case "25": + m_Cursor=System.Windows.Forms.Cursors.UpArrow; + break; + case "26": + m_Cursor=System.Windows.Forms.Cursors.VSplit; + break; + case "27": + m_Cursor=System.Windows.Forms.Cursors.WaitCursor; + break; + } + } + + System.Xml.XmlNodeList list=ItemXmlSource.GetElementsByTagName("subitems"); + if(list.Count>0) + { + foreach(System.Xml.XmlElement xmlChild in list[0].ChildNodes) + { +// BaseItem oi=null; +// System.Reflection.Assembly a=System.Reflection.Assembly.Load(xmlChild.GetAttribute("assembly")); +// if(a==null) continue; +// oi=a.CreateInstance(xmlChild.GetAttribute("class")) as BaseItem; + BaseItem oi=context.CreateItemFromXml(xmlChild); + if(oi!=null) + { + this.SubItems.Add(oi); + context.ItemXmlElement = xmlChild; + oi.Deserialize(context); + context.ItemXmlElement = ItemXmlSource; + } + } + } + if(ItemXmlSource.HasAttribute("shortcuts")) + { + if(m_Shortcuts==null) + m_Shortcuts=new ShortcutsCollection(this); + m_Shortcuts.FromString(ItemXmlSource.GetAttribute("shortcuts"),","); + } + + if (context.HasDeserializeItemHandlers) + { + System.Xml.XmlNodeList customDataList=ItemXmlSource.GetElementsByTagName("customData"); + if (customDataList.Count > 0) + { + System.Xml.XmlElement customData = customDataList[0] as System.Xml.XmlElement; + SerializeItemEventArgs e = new SerializeItemEventArgs(this, ItemXmlSource, customData); + context.Serializer.InvokeDeserializeItem(e); + } + } + + MarkupTextChanged(); + } + + /// + /// Indicates whether SubItems collection is serialized. Default value is true. + /// + protected virtual bool ShouldSerializeSubItems() + { + return true; + } + #endregion + + #region Internal Implementation + + internal void NotifyScaleItem(SizeF factor) + { + ScaleItem(factor); + } + + /// + /// Called on each item when ScaleControl method of parent control is called and gives opportunity to item to adjust its displayed based on current scaling. + /// + /// Scale factor. + protected virtual void ScaleItem(SizeF factor) + { + if (m_SubItems == null) return; + foreach (BaseItem item in m_SubItems) + { + item.NotifyScaleItem(factor); + } + } + + private bool _IsRendered = true; + /// + /// Gets or sets whether item is rendered. + /// + internal bool IsRendered + { + get { return _IsRendered; } + set + { + _IsRendered = value; + } + } + + private bool _DesignTimeVisible = true; + /// + /// Gets or sets whether item is selectable at design-time. Default value is true. + /// + internal bool DesignTimeVisible + { + get { return _DesignTimeVisible; } + set + { + _DesignTimeVisible = value; + } + } + + /// + /// Called when item container has changed. If you override this method you must call the base implementation to allow default processing to occur. + /// + /// Previous container of the item. + protected internal virtual void OnContainerChanged(object objOldContainer) + { + if(m_SubItems==null || !this.IsContainer) + return; + foreach(BaseItem objItem in m_SubItems) + objItem.OnContainerChanged(objOldContainer); + } + + /// + /// Control Container (System.Windows.Forms.Control or its descendant) + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual object ContainerControl + { + get + { + return GetContainerControl(true); + //if(m_Parent==null) + // return m_ContainerControl; + + //if(m_ContainerControl==null && m_Parent.IsContainer) + // return m_Parent.ContainerControl; + + //return m_ContainerControl; + } + set + { + object oldContainer=this.ContainerControl; + m_ContainerControl=value; + //if(oldContainer!=this.ContainerControl) + OnContainerChanged(oldContainer); + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public object GetContainerControl(bool checkIsContainer) + { + if (m_Parent == null) + return m_ContainerControl; + + if (m_ContainerControl == null && (m_Parent.IsContainer || !checkIsContainer)) + return m_Parent.GetContainerControl(checkIsContainer); + + return m_ContainerControl; + } + + /// + /// Returns the Parent of the item. + /// + [System.ComponentModel.Browsable(false)] + public virtual BaseItem Parent + { + get + { + if(this.ContainerControl is Bar) + { + Bar bar=this.ContainerControl as Bar; + if(bar.ParentItem==this) + return null; + if(m_Parent==bar.ItemsContainer) + return bar.ParentItem; + } + return m_Parent; + } + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void SetParent(BaseItem o) + { + m_Parent=o; + // Do not set recalc size flag on parent... + m_NeedRecalcSize=true; + OnParentChanged(); + } + /// + /// Called when item parent has changed. + /// + protected virtual void OnParentChanged() + { + + } + + /// + /// Returns whether item is enabled including the parent control item is on. + /// + /// + internal bool GetEnabled(System.Windows.Forms.Control container) + { + if (!m_Enabled || container == null) return m_Enabled; + if (!container.Enabled) return false; + if (m_Parent != null) + { + BaseItem parent = m_Parent; + while (parent != null) + { + if(!parent.Enabled) + return false; + parent = parent.Parent; + } + } + return container.Enabled && m_Enabled; + } + + /// + /// Returns whether item is enabled including the parent control item is on. + /// + /// + internal bool GetEnabled() + { + return GetEnabled(GetContainerControl(false) as Control); + } + + /// + /// Gets or sets a value indicating whether the item is enabled. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates whether is item enabled.")] + public virtual bool Enabled + { + get + { + return m_Enabled; + } + set + { + if(m_Enabled!=value) + { + m_Enabled=value; + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "Enabled"); + + if(!m_Enabled && m_Expanded) + { + this.Expanded=false; + //CollapseAll(this); + } + this.Refresh(); + this.OnEnabledChanged(); + OnAppearanceChanged(); + } + } + } + + /// + /// Gets or sets whether item separator is shown before this item. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(false),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates whether this item is beginning of the group.")] + public virtual bool BeginGroup + { + get + { + return m_BeginGroup; + } + set + { + if(m_BeginGroup!=value) + { + NeedRecalcSize=true; + m_BeginGroup=value; + + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "BeginGroup"); + + this.Refresh(); + OnAppearanceChanged(); + } + } + } + + + /// + /// Gets or sets Left position of this item + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual int LeftInternal + { + get + { + return m_Rect.Left; + } + set + { + if(m_Rect.X!=value) + { + int old=m_Rect.X; + m_Rect.X=value; + this.OnLeftLocationChanged(old); + } + } + } + + /// + /// Gets or sets Top position of this item + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual int TopInternal + { + get + { + return m_Rect.Top; + } + set + { + if(m_Rect.Y!=value) + { + int oldValue=m_Rect.Y; + m_Rect.Y=value; + this.OnTopLocationChanged(oldValue); + } + } + } + + /// + /// Gets or sets Width of this item + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual int WidthInternal + { + get + { + return m_Rect.Width; + } + set + { + if(m_Rect.Width!=value) + { + m_Rect.Width=value; + OnExternalSizeChange(); + } + } + } + + /// + /// Gets whether item is in right-to-left layout mode. + /// + protected virtual internal bool IsRightToLeft + { + get { return m_IsRightToLeft; } + set + { + if (m_IsRightToLeft == value) + return; + m_IsRightToLeft = value; + foreach (BaseItem item in this.SubItems) + { + item.IsRightToLeft = value; + } + } + } + + /// + /// Called when size of the item is changed externally. + /// + protected virtual void OnExternalSizeChange(){} + + /// + /// Gets or sets Height of this item + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual int HeightInternal + { + get + { + return m_Rect.Height; + } + set + { + if(m_Rect.Height!=value) + { + m_Rect.Height=value; + OnExternalSizeChange(); + } + } + } + + /// + /// Called when Visibility of the items has changed. + /// + /// New Visible state. + protected internal virtual void OnVisibleChanged(bool newValue) + { + if(this.VisibleChanged!=null) + this.VisibleChanged(this,new EventArgs()); + if (this.DesignMode) + { + if (this.Parent != null) + { + this.Parent.NeedRecalcSize = true; + this.Parent.Refresh(); + } + } + else if (this.Parent != null && this.Parent is ItemContainer) + this.Parent.NeedRecalcSize = true; + } + + /// + /// Gets or sets a value indicating whether the item is visible. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Determines whether the item is visible or hidden.")] + public virtual bool Visible + { + get + { + return m_Visible; + } + set + { + if(m_Visible==value) + return; + + m_Visible=value; + this.NeedRecalcSize = true; + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "Visible"); + + if(!m_Visible && m_Displayed && m_Parent!=null) + { + m_Parent.SubItemSizeChanged(this); + } + if(!m_IsOnCustomizeMenu) + this.Displayed=false; + + OnVisibleChanged(value); + } + } + + internal void SetVisibleDirect(bool b) + { + m_Visible = b; + if (!m_Visible && !m_IsOnCustomizeMenu) + m_Displayed = false; + } + + /// + /// Gets or sets a value indicating whether the item is expanded or not. For Popup items this would indicate whether the item is popped up or not. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DefaultValue(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual bool Expanded + { + get { return m_Expanded; } + + set + { + if(m_Expanded!=value) + { + m_Expanded = value; + + OnExpandChange(); + + if(m_Parent!=null) + m_Parent.OnSubItemExpandChange(this); + } + } + } + + /// + /// Indicates whether the item will auto-collapse (fold) when clicked. + /// When item is on popup menu and this property is set to false, menu will not + /// close when item is clicked. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.DefaultValue(true),System.ComponentModel.Description("Indicates whether the item will auto-collapse (fold) when clicked.")] + public virtual bool AutoCollapseOnClick + { + get + { + return m_AutoCollapseOnClick; + } + set + { + m_AutoCollapseOnClick=value; + } + } + + /// + /// Gets or sets whether item will auto expand when mouse is over the item or not. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DefaultValue(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual bool AutoExpand + { + get + { + return m_AutoExpand; + } + set + { + if(m_AutoExpand==value) + return; + m_AutoExpand=value; + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "AutoExpand"); + } + } + + /// + /// Gets the rectangle that represents the display area of the item. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual System.Drawing.Rectangle DisplayRectangle + { + get + { + return m_Rect; + } + } + + /// + /// Gets or sets the size of the item. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual System.Drawing.Size Size + { + get {return m_Rect.Size;} + set + { + if(m_Rect.Size!=value) + { + m_Rect.Size=value; + OnExternalSizeChange(); + } + } + } + + /// + /// IBlock member implementation + /// + [Browsable(false), DevCoBrowsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] + public virtual System.Drawing.Rectangle Bounds + { + get { return m_Rect; } + set + { + if (m_Rect != value) + { + bool sizeChanged = m_Rect.Size != value.Size; + //bool topLocationChanged = m_Rect.Top != value.Top; + //bool leftLocationChanged = m_Rect.Left != value.Left; + //int oldLeft = m_Rect.Left; + m_Rect = value; + if(sizeChanged) + OnExternalSizeChange(); + //if (leftLocationChanged) + // OnLeftLocationChanged(oldLeft); + } + } + } + + internal void SetDisplayRectangle(Rectangle r) + { + m_Rect = r; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetViewRectangle(Rectangle r) + { + m_ViewRectangle = r; + } + + /// + /// Specifies whether this item is visual container or not. For example + /// Tool Menu is not container since it drops-down its items and they are + /// not "visualy" contained. Also, the pop-up menus, drop-down Bars etc. are not containers. + /// + [System.ComponentModel.Browsable(false)] + public virtual bool IsContainer + { + get + { + return m_IsContainer; + } + } + + protected internal void SetIsContainer(bool b) + { + m_IsContainer=b; + } + + /// + /// Returns true if this item is currently displayed. This property should not be set directly since it is managed by system and container of the item. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual bool Displayed + { + get + { + return m_Displayed; + } + set + { + if (m_Displayed != value && !LockDisplayedChange) + { + m_Displayed=value; + OnDisplayedChanged(); + } + } + } + internal bool LockDisplayedChange = false; + + /// + /// Called when item Display state has changed. + /// + protected virtual void OnDisplayedChanged() + { +// if(DisplayedChanged!=null) +// DisplayedChanged(this,new EventArgs()); + if(this.Displayed && this.Visible) + this.GenerateAccessibilityEvent(System.Windows.Forms.AccessibleEvents.Show); + else + this.GenerateAccessibilityEvent(System.Windows.Forms.AccessibleEvents.Hide); +// IOwnerItemEvents owner=this.GetIOwnerItemEvents(); +// if(owner!=null) +// owner.InvokeItemDisplayedChanged(this,new EventArgs()); + } + + protected internal virtual void OnProcessDelayedCommands(){} + + /// + /// Called when item owner has changed. + /// + protected virtual void OnOwnerChanged() {} + + /// + /// Raises SubItemsChanged event. + /// + /// + protected virtual void OnSubItemsChanged(CollectionChangeEventArgs e) + { + CollectionChangeEventHandler eh = SubItemsChanged; + if (eh != null) eh(this, e); + } + + protected virtual void OnSubItemsChanged(CollectionChangeAction action, BaseItem item) + { + if (SubItemsChanged != null) OnSubItemsChanged(new CollectionChangeEventArgs(action, item)); + } + + /// + /// Occurs after an item has been added to the container. This procedure is called on both item being added and the parent of the item. To distinguish between those two states check the item parameter. + /// + /// When occurring on the parent this will hold the reference to the item that has been added. When occurring on the item being added this will be null (Nothing). + protected internal virtual void OnItemAdded(BaseItem item) + { + OnSubItemsChanged(CollectionChangeAction.Add, item); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null) + owner.InvokeItemAdded(item,new EventArgs()); + } + /// + /// Occurs after an item has been removed. + /// + /// Item being removed. + protected internal virtual void OnAfterItemRemoved(BaseItem item, int itemIndex) + { + if(item==null) + return; + OnSubItemsChanged(CollectionChangeAction.Remove, item); + + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null) + owner.InvokeItemRemoved(item,this,itemIndex); + } + + /// + /// Occurs just before Click event is fired. + /// + protected virtual void OnClick(){} + + /// + /// Occurs after SubItems Collection has been cleared. + /// + protected internal virtual void OnSubItemsClear() {} + /// + /// Occurs before an item is removed. + /// + /// Item being removed. + protected internal virtual void OnBeforeItemRemoved(BaseItem item) {} + /// + /// Occurs when IsOnCustomizeMenu property has changed. + /// + protected virtual void OnIsOnCustomizeMenuChanged(){} + /// + /// Occurs when IsOnCustomizeDialogChanged property has changed. + /// + protected virtual void OnIsOnCustomizeDialogChanged(){} + /// + /// Occurs when item enter or exists the design mode. + /// + protected virtual void OnDesignModeChanged(){} + /// + /// Occurs when tooltip is about to be shown or hidden. + /// + /// Specifies whether tooltip is shown or hidden. + protected virtual void OnTooltip(bool bShow){} + /// + /// Occurs after item has received the input focus. + /// + /// Item that received the focus. + protected virtual void OnSubItemGotFocus(BaseItem item){} + /// + /// Occurs after item has lost the input focus. + /// + /// Item that lost the input focus. + protected virtual void OnSubItemLostFocus(BaseItem item){} + /// + /// Indicates whether the item enabled property has changed. + /// + protected virtual void OnEnabledChanged() + { + if(this.EnabledChanged!=null) + this.EnabledChanged(this,new EventArgs()); + } + /// + /// Called after TopInternal property has changed + /// + protected virtual void OnTopLocationChanged(int oldValue){} + + /// + /// Called after LeftInternal property has changed + /// + protected virtual void OnLeftLocationChanged(int oldValue){} + + /// + /// Occurs when the mouse pointer enters the item. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void InternalMouseEnter() + { + if(!m_DesignMode) + { + if(MouseEnter!=null) + MouseEnter(this,new EventArgs()); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeMouseEnter(this,new EventArgs()); + } + if(!this.DesignMode) + { + ResetHover(); + + System.Windows.Forms.Control objContainer=this.ContainerControl as System.Windows.Forms.Control; + + if(m_Cursor!=null && objContainer!=null) + { + m_ContainerCursor=objContainer.Cursor; + objContainer.Cursor=m_Cursor; + } + + // Accessibility Narrator support for menu items ONLY + if (BarUtilities.AlwaysGenerateAccessibilityFocusEvent && !(objContainer is MenuPanel) || objContainer is Bar && this.IsOnMenuBar) + { + Bar.BarAccessibleObject acc=objContainer.AccessibilityObject as Bar.BarAccessibleObject; + if (acc != null) + { + //acc.GenerateEvent(this,System.Windows.Forms.AccessibleEvents.SystemMenuStart); + acc.GenerateEvent(this, System.Windows.Forms.AccessibleEvents.Focus); + } + else + { + ItemControlAccessibleObject ic = objContainer.AccessibilityObject as ItemControlAccessibleObject; + if (ic != null) + ic.GenerateEvent(this, System.Windows.Forms.AccessibleEvents.Focus); + } + } + else if(objContainer is MenuPanel && !((MenuPanel)objContainer).IsDisposed) + { + MenuPanel.PopupMenuAccessibleObject a=objContainer.AccessibilityObject as MenuPanel.PopupMenuAccessibleObject; + if(a!=null) + { + a.GenerateEvent(this,System.Windows.Forms.AccessibleEvents.Focus); + } + } + } + } + + /// + /// Occurs when the mouse pointer hovers the item. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void InternalMouseHover() + { + if(m_DesignMode) + return; + + if(m_HotSubItem!=null) + { + if(!m_AutoExpand) + { + BaseItem objItem=ExpandedItem(); + if(objItem!=null && m_HotSubItem!=objItem && objItem.Visible && (this.IsOnMenu || this.ContainerControl is Bar || this.ContainerControl is RibbonBar)) + objItem.Expanded=false; + } + // Changing the Expanded of the item can cause hot sub item to be set to null + if(m_HotSubItem!=null) + m_HotSubItem.InternalMouseHover(); + } + else + { + if(System.Windows.Forms.Control.MouseButtons==System.Windows.Forms.MouseButtons.None) + ShowToolTip(); + if(!m_DesignMode) + { + if(MouseHover!=null) + MouseHover(this,new EventArgs()); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeMouseHover(this,new EventArgs()); + } + } + } + + /// + /// Occurs when the mouse pointer leaves the item. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void InternalMouseLeave() + { + if(m_ContainerCursor!=null) + { + System.Windows.Forms.Control objContainer=this.ContainerControl as System.Windows.Forms.Control; + if(objContainer!=null) + { + objContainer.Cursor=m_ContainerCursor; + } + m_ContainerCursor=null; + } + + if(m_DesignMode) + return; + + // If we had hot sub item pass the mouse leave message to it... + if(m_HotSubItem!=null) + { + m_HotSubItem.InternalMouseLeave(); + HotSubItem = null; + } + else + { + if (m_TextMarkup != null) + m_TextMarkup.MouseLeave(this.ContainerControl as System.Windows.Forms.Control); + + if(MouseLeave!=null) + MouseLeave(this,new EventArgs()); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeMouseLeave(this,new EventArgs()); + } + HideToolTip(); + } + /// + /// Gets the mouse down coordinates. + /// + internal Point MouseDownPt + { + get + { + return m_MouseDownPt; + } + } + + protected virtual bool ShouldCollapseParentItem() + { + return true; + } + protected void RaiseMouseDown(System.Windows.Forms.MouseEventArgs objArg) + { + if (MouseDown != null) + MouseDown(this, objArg); + } + /// + /// Occurs when the mouse pointer is over the item and a mouse button is pressed. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void InternalMouseDown(System.Windows.Forms.MouseEventArgs objArg) + { + IOwner owner=null; + + // Colapse any item if expanded + m_MouseDownPt=new System.Drawing.Point(objArg.X,objArg.Y); + BaseItem objItem=ExpandedItem(); + if(objItem!=null && objItem!=m_HotSubItem && !this.DesignMode && m_AllowOnlyOneSubItemExpanded && ShouldCollapseParentItem()) + { + objItem.Expanded=false; + m_AutoExpand=false; + } + + if(m_DesignMode && (m_CanCustomize || this.Site!=null && this.Site.DesignMode))// && !this.SystemItem) + { + if(this.IsContainer && this.SubItems.Count>0) + { + BaseItem objNew=ItemAtLocation(objArg.X,objArg.Y); + + if (objNew != null && (objNew.CanCustomize || this.Site != null && this.Site.DesignMode || objNew.Site != null && objNew.Site.DesignMode) && !(objNew.DesignMode && !objNew.DesignTimeVisible)) + { + owner=this.GetOwner() as IOwner; + if(owner!=null) + owner.SetFocusItem(objNew); + } + else if(objNew==null) + { + owner=this.GetOwner() as IOwner; + if(owner!=null) + owner.SetFocusItem(null); + } + + if(objNew!=null && objNew!=this) + objNew.InternalMouseDown(objArg); + } + + if(objArg.Button==System.Windows.Forms.MouseButtons.Right && !m_IsContainer) + { + owner=this.GetOwner() as IOwner; + if(owner!=null) + owner.DesignTimeContextMenu(this); + } + } + + if(!this.DesignMode) + { + owner=this.GetOwner() as IOwner; + if(owner!=null && owner.GetFocusItem()!=null) + { + BaseItem objNew=ItemAtLocation(objArg.X,objArg.Y); + if(objNew!=owner.GetFocusItem()) + owner.GetFocusItem().ReleaseFocus(); + } + } + + if(m_HotSubItem!=null) + { + m_HotSubItem.InternalMouseDown(objArg); + } + else if(!m_DesignMode) + { + if (m_TextMarkup != null) + m_TextMarkup.MouseDown(this.ContainerControl as System.Windows.Forms.Control, objArg); + + RaiseMouseDown(objArg); + //if(owner==null) + // owner=this.GetOwner() as IOwner; + IOwnerItemEvents ownerEvents=this.GetIOwnerItemEvents(); + if(ownerEvents!=null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + ownerEvents.InvokeMouseDown(this,objArg); + } + + HideToolTip(); + } + + protected void RaiseMouseUp(System.Windows.Forms.MouseEventArgs objArg) + { + if (MouseUp != null) + MouseUp(this, objArg); + } + /// + /// Occurs when the mouse pointer is over the item and a mouse button is released. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void InternalMouseUp(System.Windows.Forms.MouseEventArgs objArg) + { + if(m_HotSubItem!=null) + { + if(m_HotSubItem.DisplayRectangle.Contains(objArg.X,objArg.Y) || m_HotSubItem.MouseUpNotification) + m_HotSubItem.InternalMouseUp(objArg); + } + else if(!m_DesignMode) + { + if (m_TextMarkup != null) + m_TextMarkup.MouseUp(this.ContainerControl as System.Windows.Forms.Control, objArg); + RaiseMouseUp(objArg); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeMouseUp(this,objArg); + if ((objArg.Button == System.Windows.Forms.MouseButtons.Left || objArg.Button == System.Windows.Forms.MouseButtons.Right && this.IsOnContextMenu) && this.DisplayRectangle.Contains(objArg.X, objArg.Y) && (this.DisplayRectangle.Contains(m_MouseDownPt) && this.GetEnabled() || this.IsOnMenu)) + RaiseClick(eEventSource.Mouse); + } + else + { + BaseItem objNew=ItemAtLocation(objArg.X,objArg.Y); + if(objNew!=null && objNew!=this) + objNew.InternalMouseUp(objArg); + } + + m_MouseDownPt=System.Drawing.Point.Empty; + } + + /// + /// Gets whether item is on context menu created using ContextMenuBar + /// + [Browsable(false)] + public bool IsOnContextMenu + { + get { return this.GetOwner() is ContextMenuBar; } + } + + /// + /// Occurs when a key is pressed down while the item has focus. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void InternalKeyDown(System.Windows.Forms.KeyEventArgs objArg) + { + if(m_DesignMode) + { + objArg.Handled=true; + return; + } + + if(m_HotSubItem!=null) + { + m_HotSubItem.InternalKeyDown(objArg); + } + + if(objArg.KeyCode==System.Windows.Forms.Keys.Enter || objArg.KeyCode==System.Windows.Forms.Keys.Return) + { + if (!(this.IsOnMenuBar || (this.IsOnMenu || this.ShowSubItems) && this.SubItems.Count > 0) && this.GetEnabled()) + { + RaiseClick(eEventSource.Keyboard); + objArg.Handled=true; + + if (this.GetOwner() is RibbonStrip || this.GetOwner() is RibbonBar) + { + ((ItemControl)this.GetOwner()).ReleaseFocus(); + ((ItemControl)this.GetOwner()).MenuFocus = false; + } + } + } + } + + /// + /// Processes the MouseLeave for the current mouse over item. + /// + protected virtual void LeaveHotSubItem(BaseItem newMouseOverItem) + { + BaseItem hotSubItem = m_HotSubItem; + if (hotSubItem != null) + { + hotSubItem.InternalMouseLeave(); + //if(objNew!=null && m_AutoExpand && m_HotSubItem.Expanded) + if (newMouseOverItem != null && hotSubItem.Expanded && (this.IsOnMenu || this.ContainerControl is Bar && ((Bar)this.ContainerControl).BarType == eBarType.MenuBar)) + hotSubItem.Expanded = false; + HotSubItem = null; + } + } + + /// + /// Occurs when the mouse pointer is moved over the item. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void InternalMouseMove(System.Windows.Forms.MouseEventArgs objArg) + { + if(m_DesignMode && objArg.Button==System.Windows.Forms.MouseButtons.Left && (Math.Abs(objArg.X-m_MouseDownPt.X)>=2 || Math.Abs(objArg.Y-m_MouseDownPt.Y)>=2)) + { + BaseItem objFocus=this.FocusedItem(); + if(objFocus!=null && objFocus.CanCustomize) + { + if(!objFocus.SystemItem) + { + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null) + owner.StartItemDrag(objFocus); + } + } + else if(!m_IsContainer) + { + if(!this.SystemItem && m_CanCustomize) + { + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null) + owner.StartItemDrag(this); + } + } + return; + } + + // If item is container and not in design time... + if(m_IsContainer && !m_DesignMode) + { + BaseItem objNew=ItemAtLocation(objArg.X,objArg.Y); + if(objNew!=m_HotSubItem && (!(objArg.Button != MouseButtons.None && m_HotSubItem!=null) || m_CheckMouseMovePressed) && + !(m_HotSubItem!=null && m_HotSubItem.MouseDownCapture && objArg.Button == MouseButtons.Left)) + { + LeaveHotSubItem(objNew); + + if(objNew!=null) + { + if(m_AutoExpand) + { + BaseItem objItem=ExpandedItem(); + if(objItem!=null && objItem!=objNew) + objItem.Expanded=false; + } + if (objNew != this) + { + objNew.InternalMouseEnter(); + objNew.InternalMouseMove(objArg); + if (objNew.GetEnabled()) + { + if (m_AutoExpand && objNew.ShowSubItems) + { + if (objNew is PopupItem) + { + PopupItem pi = objNew as PopupItem; + ePopupAnimation oldAnim = pi.PopupAnimation; + pi.PopupAnimation = ePopupAnimation.None; + if (objNew.SubItems.Count > 0) + objNew.Expanded = true; + pi.PopupAnimation = oldAnim; + } + else + objNew.Expanded = true; + } + } + HotSubItem = objNew; + } + } + else + HotSubItem=null; + if(MouseMove!=null) + MouseMove(this, objArg); + } + else if(m_HotSubItem!=null) + { + m_HotSubItem.InternalMouseMove(objArg); + } + else + { + if(MouseMove!=null) + MouseMove(this,objArg); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeMouseMove(this,objArg); + } + + if (m_TextMarkup != null) + { + //m_TextMarkup.MouseMove(this.ContainerControl as Control, objArg); + + Control control = GetParentControl(); + + if (control != null) + m_TextMarkup.MouseMove(control, objArg); + } + } + else + { + if (!m_DesignMode) + { + if (m_TextMarkup != null) + { + //m_TextMarkup.MouseMove(this.ContainerControl as Control, objArg); + + Control control = GetParentControl(); + + if (control != null) + m_TextMarkup.MouseMove(control, objArg); + } + + if (MouseMove!=null) + MouseMove(this,objArg); + + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + + if (owner!=null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeMouseMove(this,objArg); + } + } + } + + internal Control GetParentControl() + { + Control control = ContainerControl as Control; + + if (control == null) + { + BaseItem item = ContainerControl as BaseItem; + + while (item != null) + { + control = item.ContainerControl as Control; + + if (control != null) + break; + + item = item.Parent; + } + } + + return (control); + } + + /// + /// Occurs when the item is clicked. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void InternalClick(System.Windows.Forms.MouseButtons mb, System.Drawing.Point mpos) + { + if(m_HotSubItem!=null) + { + m_HotSubItem.InternalClick(mb,mpos); + return; + } + + if (m_TextMarkup != null) + m_TextMarkup.Click(this.ContainerControl as System.Windows.Forms.Control); + + //RaiseClick(); + } + + /// + /// Gets whether RaiseClick method will generate a click event give current item state. + /// + internal bool CanRaiseClick + { + get + { + if (this.DesignMode || !m_Visible && !this.SystemItem && !this.IsOnCustomizeMenu || _IgnoreClick || !GetEnabled()) + return false; + if(this.ContainerControl is BaseItemControl && ((BaseItemControl)this.ContainerControl).IsValidationCancelled) + return false; +#if TRIAL + if(NativeFunctions.ColorExpAlt()) + return false; +#endif + + return true; + } + } + + private bool _CollapseAllBeforeRaisingClick = true; + /// + /// Indicates whether RaiseClick method collapses parent popups before raising click event. Default value is true. + /// + internal bool CollapseAllBeforeRaisingClick + { + get { return _CollapseAllBeforeRaisingClick; } + set + { + _CollapseAllBeforeRaisingClick = value; + } + } + + private void ClickCollapseAll() + { + if (m_AutoCollapseOnClick) + { + if ((!this.SystemItem || this.SystemItem && this.Name.StartsWith("mdi-")) && (IsOnPopup(this)) && !(m_Parent != null && m_Parent.SystemItem && !(m_Parent is DisplayMoreItem))) + { + if (!(this is PopupItem && ((PopupItem)this).ShowSubItems && (SubItems.Count > 0 || ((PopupItem)this).PopupType == ePopupType.Container))) + CollapseAll(this); + } + + if (m_Parent != null && m_Parent.AutoExpand && this.SubItems.Count == 0) + m_Parent.AutoExpand = false; + } + } + /// + /// Raises the click event and provide the information about the source of the event. + /// + /// + public virtual void RaiseClick(eEventSource source) + { + //if (BaseItem.IsOnPopup(this)) + // NativeFunctions.sndPlaySound("MenuCommand", NativeFunctions.SND_ASYNC | NativeFunctions.SND_NODEFAULT); + if (!CanRaiseClick) + return; + + IOwnerItemEvents owner = this.GetIOwnerItemEvents(); + BaseItem rootParent = this.RootParentItem; + + if(_CollapseAllBeforeRaisingClick) + ClickCollapseAll(); + + if (m_InClickEvent) return; + m_InClickEvent = true; + try + { + this.OnClick(); + + if (Click != null) + Click(this, new DevComponents.DotNetBar.Events.EventSourceArgs(source)); + + if (rootParent != null && rootParent.ContainerControl is Bar) + { + Bar bar = rootParent.ContainerControl as Bar; + if (bar != null) + bar.InvokeItemClick(this, new DevComponents.DotNetBar.Events.EventSourceArgs(source)); + } + else if (this.GetOwner() is Bar && owner == null) + ((Bar)this.GetOwner()).InvokeItemClick(this, new DevComponents.DotNetBar.Events.EventSourceArgs(source)); + + if (owner != null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeItemClick(this); + } + finally + { + m_InClickEvent = false; + } + + if (!_CollapseAllBeforeRaisingClick) + ClickCollapseAll(); + } + + /// + /// Raises the Click event with default source as Code. + /// + private bool m_InClickEvent=false; + public virtual void RaiseClick() + { + RaiseClick(eEventSource.Code); + } + + private BaseItem RootParentItem + { + get + { + BaseItem parent = Parent; + while (parent != null && parent.Parent != null) + parent = parent.Parent; + return parent; + } + } + + internal void ClearClick() + { + Click=null; + } + + /// + /// Occurs when the item is double clicked. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void InternalDoubleClick(System.Windows.Forms.MouseButtons mb, System.Drawing.Point mpos) + { + if (m_HotSubItem != null) + { + m_HotSubItem.InternalDoubleClick(mb, mpos); + } + else + { + InvokeDoubleClick(); + + IOwnerItemEvents owner = this.GetIOwnerItemEvents(); + if (owner != null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeItemDoubleClick(this, new MouseEventArgs(mb, 2, mpos.X, mpos.Y, 0)); + } + } + + /// + /// Invokes DoubleClick event. + /// + protected virtual void InvokeDoubleClick() + { + if (DoubleClick != null) + DoubleClick(this, new EventArgs()); + } + + /// + /// Occurs when the item receives focus. If overridden base implementation must be called so default processing can occur. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void OnGotFocus() + { + m_Focused=true; + + if(!m_DesignMode) + { + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeGotFocus(this,new EventArgs()); + } + + this.Refresh(); + + OnGotFocus(EventArgs.Empty); + } + + protected virtual void OnGotFocus(EventArgs e) + { + if (GotFocus != null) + GotFocus(this, e); + } + /// + /// Occurs when the item has lost the focus. If overridden base implementation must be called so default processing can occur. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void OnLostFocus() + { + if (this.IsDisposed) return; + + if (!m_DesignMode) + { + IOwnerItemEvents owner = this.GetIOwnerItemEvents(); + if (owner != null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeLostFocus(this, new EventArgs()); + } + else + InternalMouseLeave(); + m_Focused=false; + this.Refresh(); + + OnLostFocus(EventArgs.Empty); + } + + protected virtual void OnLostFocus(EventArgs e) + { + if (LostFocus != null) + LostFocus(this, e); + } + /// + /// Sets the input focus to the item. If overridden base implementation must be called so default processing can occur. + /// + public virtual void Focus() + { + if(BaseItem.IsOnPopup(this)) + { + MenuPanel menu=this.ContainerControl as MenuPanel; + if(menu!=null && menu.ParentItem.Parent==null) + { + menu.SetFocusItem(this); + return; + } + } + + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null) + owner.SetFocusItem(this); + else + this.OnGotFocus(); + + if(this.Parent!=null) + this.Parent.OnSubItemGotFocus(this); + } + + /// + /// Releases the input focus. If overridden base implementation must be called so default processing can occur. + /// + public virtual void ReleaseFocus() + { + if(m_Focused) + { + if(BaseItem.IsOnPopup(this)) + { + MenuPanel menu=this.ContainerControl as MenuPanel; + if(menu!=null && menu.ParentItem.Parent==null) + { + menu.SetFocusItem(null); + return; + } + } + + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null) + owner.SetFocusItem(null); + else + this.OnLostFocus(); + + if(this.Parent!=null) + this.Parent.OnSubItemLostFocus(this); + } + } + + /// + /// Gets whether item has input focus. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual bool Focused + { + get + { + return m_Focused; + } + } + + /// + /// Occurs when item container has lost the input focus. If overridden base implementation must be called so default processing can occur. + /// + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void ContainerLostFocus(bool appLostFocus) + { + if(m_SubItems!=null) + { + foreach(BaseItem objSub in m_SubItems) + { + objSub.ContainerLostFocus(appLostFocus); + } + } + if(m_HotSubItem!=null) + { + bool leave = true; + if (!appLostFocus) + { + System.Windows.Forms.Control c = this.ContainerControl as System.Windows.Forms.Control; + if (c != null) + { + Point p = c.PointToClient(System.Windows.Forms.Control.MousePosition); + if (m_HotSubItem.DisplayRectangle.Contains(p)) + leave = false; + } + } + if (leave) + { + m_HotSubItem.InternalMouseLeave(); + HotSubItem = null; + } + } + if(this.Focused) + { + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null) + owner.SetFocusItem(null); + } + } + + /// + /// Occurs when item container receives the input focus. If overridden base implementation must be called so default processing can occur. + /// + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void ContainerGotFocus() + { + if(m_SubItems!=null) + { + foreach(BaseItem objSub in m_SubItems) + { + objSub.ContainerGotFocus(); + } + } + } + + /// + /// Indicates that item size has changed. It must be called by child item to let the parent know that its size + /// has been changed. + /// + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual void SubItemSizeChanged(BaseItem objChildItem) {} + + /// + /// Return Sub Item at specified location + /// + public virtual BaseItem ItemAtLocation(int x, int y) + { + if(!m_IsContainer) + { + return null; + } + if(m_SubItems!=null) + { + foreach (BaseItem objSub in m_SubItems) + { + //if(objSub.Visible && objSub.Displayed && x>=objSub.Left && x<=(objSub.Left+objSub.Width) && y>=objSub.Top && y<=(objSub.Top+objSub.Height)) + if ((objSub.Visible || m_IsOnCustomizeMenu) && objSub.Displayed && objSub.DisplayRectangle.Contains(x, y)) + { + if (m_ViewRectangle.IsEmpty || m_ViewRectangle.Contains(x, y)) + return objSub; + } + } + } + return null; + } + + /// + /// Gets the current expanded subitem. + /// + /// + protected internal virtual BaseItem ExpandedItem() + { + if(!m_IsContainer) + { + return null; + } + if(m_SubItems!=null) + { + foreach(BaseItem objSub in m_SubItems) + { + if (objSub is GalleryContainer && ((GalleryContainer)objSub).IsGalleryPopupOpen) + return objSub; + if (objSub is ItemContainer) + { + BaseItem exp = objSub.ExpandedItem(); + if (exp != null) + return exp; + } + else if(objSub.Expanded) + { + return objSub; + } + } + } + return null; + } + + /// + /// Gets the item that has input focus. + /// + /// Item that has focus or Null (Nothing) if none of the subitems have focus. + protected internal BaseItem FocusedItem() + { + if(!m_IsContainer) + return null; + if(m_SubItems!=null) + { + foreach(BaseItem objSub in m_SubItems) + { + if(objSub.Focused) + { + return objSub; + } + else if (objSub.IsContainer) + { + BaseItem focused = objSub.FocusedItem(); + if (focused != null) + return focused; + } + } + } + return null; + } + + /// + /// Gets the owner of the item. + /// + /// DotNetBarManager that owns the item. + public object GetOwner() + { + if(m_Owner!=null) + return m_Owner; + + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + + if (objCtrl is Bar) + return ((Bar)objCtrl).Owner; + else if(objCtrl is MenuPanel) + return ((MenuPanel)objCtrl).Owner; + else if(m_Parent!=null) + return m_Parent.GetOwner(); + + return null; + } + + protected object OwnerDirect + { + get { return m_Owner; } + } + + internal protected IOwnerItemEvents GetIOwnerItemEvents() + { + return this.GetOwner() as IOwnerItemEvents; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetOwner(object owner) + { + if(m_Owner!=owner) + { + m_Owner=owner; + this.OnOwnerChanged(); + } + } + + /// + /// Recalculate the size of the item. If overridden base implementation must be called so default processing can occur. + /// + public virtual void RecalcSize() + { + m_NeedRecalcSize=false; + } + + /// + /// Indicates that item is recalculating its size. + /// + [System.ComponentModel.Browsable(false),DevCoBrowsable(false)] + public bool IsRecalculatingSize + { + get {return m_RecalculatingSize;} + } + + /// + /// Must be overridden by class that is inheriting to provide the painting for the item. + /// + public abstract void Paint(ItemPaintArgs p); + + /// + /// Must be overridden by class that is inheriting to provide the method to + /// return copy of an item. + /// + public abstract BaseItem Copy(); + + /// + /// Internal Copy implementation. + /// + /// Item to copy to. + protected virtual void CopyToItem(BaseItem objCopy) + { + objCopy.Visible=m_Visible; + objCopy.SetIsContainer(m_IsContainer); + objCopy.AutoExpand=m_AutoExpand; + objCopy.BeginGroup=m_BeginGroup; + objCopy.Enabled=m_Enabled; + objCopy.Description=m_Description; + objCopy.Tooltip=m_Tooltip; + objCopy.Category=m_Category; + objCopy.Orientation=m_Orientation; + objCopy.Text=m_Text; + objCopy.Name=m_Name; + objCopy.GlobalName = m_GlobalName; + objCopy.GlobalItem = m_GlobalItem; + objCopy.Style=m_Style; + objCopy.SetDesignMode(m_DesignMode); + objCopy.ShowSubItems=m_ShowSubItems; + objCopy.Stretch=m_Stretch; + if(m_Shortcuts!=null && m_Shortcuts.Count>0) + objCopy.Shortcuts.FromString(m_Shortcuts.ToString(","),","); + + // Copy Events + objCopy.Click=this.Click; + objCopy.ExpandChange=this.ExpandChange; + objCopy.LostFocus=this.LostFocus; + objCopy.GotFocus=this.GotFocus; + objCopy.MouseDown=this.MouseDown; + objCopy.MouseEnter=this.MouseEnter; + objCopy.MouseHover=this.MouseHover; + objCopy.MouseLeave=this.MouseLeave; + objCopy.MouseMove=this.MouseMove; + objCopy.MouseUp=this.MouseUp; + objCopy.VisibleChanged=this.VisibleChanged; + objCopy.EnabledChanged=this.EnabledChanged; + objCopy.TextChanged=this.TextChanged; + objCopy.IsRightToLeft = this.IsRightToLeft; + objCopy.Cursor=m_Cursor; + objCopy.ThemeAware=m_ThemeAware; + objCopy.AutoCollapseOnClick = this.AutoCollapseOnClick; + objCopy.Tag=m_ItemData; + objCopy.CanCustomize = m_CanCustomize; + objCopy.Command = this.Command; + objCopy.CommandParameter = this.CommandParameter; + objCopy.KeyTips = this.KeyTips; + if(m_SubItems!=null) + { + foreach(BaseItem objItem in m_SubItems) + objCopy.SubItems.Add(objItem.Copy()); + } + + if(ItemCopied!=null) + ItemCopied(objCopy,new EventArgs()); + } + + /// + /// Returns copy of the item. + /// + /// Copy of the item. + public object Clone() + { + return this.Copy(); + } + + /// + /// Forces the repaint the item. + /// + public virtual void Refresh() + { + if(m_SuspendLayout) + return; + + if((m_Visible || m_IsOnCustomizeMenu) && m_Displayed) + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if (objCtrl != null && IsHandleValid(objCtrl) && !(objCtrl is ItemsListBox)) + { + if (objCtrl.InvokeRequired) + { + objCtrl.BeginInvoke(new MethodInvoker(delegate { this.Refresh(); })); + return; + } + + if (m_NeedRecalcSize) + { + if (m_Parent is ItemContainer) + { + m_Parent.RecalcSize(); + } + else + { + RecalcSize(); + if (m_Parent != null) + m_Parent.SubItemSizeChanged(this); + } + } + Invalidate(objCtrl); + } + } + } + + protected virtual void Update() + { + Control cont = this.ContainerControl as Control; + if (cont != null) + Update(cont); + } + protected virtual void Update(Control containerControl) + { + if (containerControl.InvokeRequired) + containerControl.BeginInvoke(new MethodInvoker(delegate { containerControl.Update(); })); + else + containerControl.Update(); + } + protected virtual void Invalidate() + { + Control cont = this.ContainerControl as Control; + if (cont != null) + Invalidate(cont); + } + private static void InvalidateFormCaption(Control containerControl) + { + int height = SystemInformation.Border3DSize.Height + SystemInformation.CaptionHeight; + WinApi.RECT r = new WinApi.RECT(0, -height, containerControl.Width, height); + WinApi.RedrawWindow(containerControl.Handle, ref r, IntPtr.Zero, WinApi.RedrawWindowFlags.RDW_INVALIDATE | WinApi.RedrawWindowFlags.RDW_FRAME | WinApi.RedrawWindowFlags.RDW_UPDATENOW); + } + protected virtual void Invalidate(Control containerControl) + { + if (this.DesignMode) + { + if (containerControl is Form && !(containerControl is RadialMenuPopup)) + { + if (IsHandleValid(containerControl)) + InvalidateFormCaption(containerControl); + containerControl.Refresh(); + } + else + { + if (containerControl.InvokeRequired) + containerControl.BeginInvoke(new MethodInvoker(delegate { containerControl.Invalidate(); })); + else + containerControl.Invalidate(); + } + } + else + { + if (containerControl is Form && !(containerControl is RadialMenuPopup)) + { + if (IsHandleValid(containerControl)) + InvalidateFormCaption(containerControl); + } + else + { + if (containerControl.InvokeRequired) + containerControl.BeginInvoke(new MethodInvoker(delegate { containerControl.Invalidate(GetInvalidateBounds(), true); })); + else + containerControl.Invalidate(GetInvalidateBounds(), true); + } + } + } + protected virtual Rectangle GetInvalidateBounds() + { + return m_Rect; + } + + private bool m_Refreshing=false; + protected internal void OnAppearanceChanged() + { + if(m_Refreshing || !this.DesignMode) + return; + + m_Refreshing=true; + try + { + System.Windows.Forms.Control c=this.ContainerControl as System.Windows.Forms.Control; + if(c!=null) + { + BarFunctions.InvokeRecalcLayout(c, true); + } + } + finally + { + m_Refreshing=false; + } + } + + /// + /// Occurs when Expanded state changes. If overridden base implementation must be called so default processing can occur. + /// + protected internal virtual void OnExpandChange() + { + HideToolTip(); + RaiseExpandChange(EventArgs.Empty); + } + + /// + /// Raises ExpandChange event. + /// + /// Event arguments + protected virtual void RaiseExpandChange(EventArgs e) + { + if (ExpandChange != null) + ExpandChange(this, e); + + IOwnerItemEvents owner = this.GetIOwnerItemEvents(); + if (owner != null && !this.SystemItem && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + owner.InvokeExpandedChange(this, e); + } + + /// + /// Occurs when sub item expanded state has changed. + /// + /// Sub item affected. + protected internal virtual void OnSubItemExpandChange(BaseItem item){} + + /// + /// Suspends all layout for the item including painting. Use this property carefully and only to improve performace. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual bool SuspendLayout + { + get + { + return m_SuspendLayout; + } + set + { + m_SuspendLayout=value; + } + } + + private bool _IsLayoutPass = false; + + /// + /// Indicates whether item is performing layout pass. + /// + [Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public bool IsLayoutPass + { + get { return _IsLayoutPass; } + set { _IsLayoutPass = value; } + } + + /// + /// Gets whether layout pass is in progress in the parent chain. + /// + [Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public bool IsLayoutPassInProgress + { + get + { + BaseItem parent = this.Parent; + while (parent != null) + { + if (parent.IsLayoutPass) return true; + parent = parent.Parent; + } + return false; + } + } + + /// + /// Releases all resurces used in this control. After calling Dispose() + /// object is not in valid state and cannot be recovered to the valid state. + /// Recreation of the object is required. + /// + protected override void Dispose(bool disposing) + { + if(m_Expanded && (this.Site!=null && !this.Site.DesignMode || this.Site==null)) + this.Expanded=false; + + HideToolTip(); + + if(m_Parent!=null) + { + m_Parent=null; + } + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null) + owner.RemoveShortcutsFromItem(this); + + if(this.Site==null || this.Site!=null && !this.Site.DesignMode) + { + if(m_SubItems!=null && m_SubItems.Count>0) + { + ArrayList subitems=new ArrayList(m_SubItems.Count); + m_SubItems.CopyTo(subitems); + foreach(BaseItem objSub in subitems) + { + if(objSub.Parent==this) + objSub.Dispose(); + } + m_SubItems._Clear(); + } + m_SubItems=null; + } + + //if(Disposed != null) + // Disposed(this,EventArgs.Empty); + + if(this.Site==null || this.Site!=null && !this.Site.DesignMode) + { + if(m_Shortcuts!=null) + m_Shortcuts=null; + //m_ItemData=null; + m_ContainerControl=null; + } + + if (_Command != null) + this.Command = null; + + if (m_TextMarkup != null) + { + m_TextMarkup.HyperLinkClick -= TextMarkupLinkClick; + m_TextMarkup = null; + } + + m_IsDisposed = true; + + base.Dispose(disposing); + } + + /// + /// Gets whether item has been disposed through Dispose method call. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDisposed + { + get + { + return m_IsDisposed; + } + } + + /// + /// Returns the collection of sub items. + /// + [System.ComponentModel.Browsable(false),DevCoBrowsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)] + public virtual SubItemsCollection SubItems + { + get + { + if(m_SubItems==null) + m_SubItems=new SubItemsCollection(this); + return m_SubItems; + } + } + + /// + /// Returns count of sub items in SubItems collection that have Visible property set to true. + /// + [Browsable(false)] + public int VisibleSubItems + { + get + { + int iCount = 0; + foreach (BaseItem item in this.SubItems) + if (item.Visible) + iCount++; + return iCount; + } + } + + + /// + /// Unique ID that indentifies the item. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.Category("Design"),System.ComponentModel.Description("Specifies unique ID of the item.")] + public long Id + { + get + { + return m_Id; + } + } + +// /// +// /// Allows the user to associate custom user data with the item. +// /// +// [System.ComponentModel.Browsable(false), DevCoBrowsable(false),System.ComponentModel.Category("Data"),System.ComponentModel.DefaultValue(""),System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)),Obsolete("ItemData is being replaced by Tag property.")] +// public virtual object ItemData +// { +// get +// { +// return m_ItemData; +// } +// set +// { +// m_ItemData=value; +// } +// } + + /// + /// Allows the user to associate custom user data with the item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true),System.ComponentModel.Category("Data"),System.ComponentModel.DefaultValue(null),System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)),System.ComponentModel.Localizable(true)] + public virtual object Tag + { + get + { + return m_ItemData; + } + set + { + m_ItemData=value; + } + } + + /// + /// Applies new visual style to this the item and all of its sub-items. + /// + [System.ComponentModel.Browsable(false),DevCoBrowsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden),System.ComponentModel.DefaultValue(eDotNetBarStyle.OfficeXP),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Determines the display of the item when shown.")] + public virtual eDotNetBarStyle Style + { + get + { + return m_Style; + } + set + { + m_Style=value; + if(m_SubItems!=null) + { + foreach(BaseItem objSub in m_SubItems) + { + objSub.Style=m_Style; + } + } + OnStyleChanged(); + } + } + /// + /// Gets the effective item style. + /// + [Browsable(false)] + public virtual eDotNetBarStyle EffectiveStyle + { + get + { + if (Style == eDotNetBarStyle.StyleManagerControlled) + return StyleManager.GetEffectiveStyle(); + return Style; + } + } + + /// + /// Occurs after item visual style has changed. + /// + protected virtual void OnStyleChanged(){} + + /// + /// Occurs after text has changed. + /// + protected virtual void OnTextChanged() + { + MarkupTextChanged(); + if(TextChanged!=null) + TextChanged(this,new EventArgs()); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null) + owner.InvokeItemTextChanged(this,new EventArgs()); + this.GenerateAccessibilityEvent(System.Windows.Forms.AccessibleEvents.NameChange); + + this.OnAppearanceChanged(); + } + + /// + /// Gets or sets whether item will display sub items. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Determines whether sub-items are displayed.")] + public virtual bool ShowSubItems + { + get + { + return m_ShowSubItems; + } + set + { + if(m_ShowSubItems!=value) + { + NeedRecalcSize=true; + m_ShowSubItems=value; + if(this.Displayed) + this.Refresh(); + } + } + } + + /// + /// Gets or sets item alignment inside the container. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(eItemAlignment.Near),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Determines alignment of the item inside the container.")] + public virtual eItemAlignment ItemAlignment + { + get + { + return m_ItemAlignment; + } + set + { + if(m_ItemAlignment!=value) + { + m_ItemAlignment=value; + NeedRecalcSize=true; + if(this.Displayed && this.Parent!=null) + this.Parent.SubItemSizeChanged(this); + if (this.DesignMode) + { + OnAppearanceChanged(); + Refresh(); + } + } + } + } + + /// + /// Returns if passed control is valid. + /// + /// Control to test. + /// + protected internal static bool IsHandleValid(System.Windows.Forms.Control objCtrl) + { + return (objCtrl!=null && !objCtrl.Disposing && !objCtrl.IsDisposed && objCtrl.IsHandleCreated); + } + + /// + /// Resets Hoover timer. + /// + protected virtual void ResetHover() + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(!IsHandleValid(objCtrl)) + 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 + NativeFunctions.TRACKMOUSEEVENT tme=new NativeFunctions.TRACKMOUSEEVENT(); + tme.dwFlags=NativeFunctions.TME_QUERY; + tme.hwndTrack=objCtrl.Handle; + tme.cbSize=System.Runtime.InteropServices.Marshal.SizeOf(tme); + NativeFunctions.TrackMouseEvent(ref tme); + tme.dwFlags=tme.dwFlags | NativeFunctions.TME_HOVER; + NativeFunctions.TrackMouseEvent(ref tme); + objCtrl=null; + } + + /// + /// Returns true if any subitem is contained on the control with a given handle. + /// + /// Container handle to test. + /// + protected internal virtual bool IsAnyOnHandle(IntPtr iHandle) + { + bool bRet=false; + if(m_SubItems==null || m_SubItems.Count==0) + return bRet; + BaseItem objTmp=m_SubItems[0] as BaseItem; + System.Windows.Forms.Control objCtrl=null; + // Since all items are always contained on same control check the first child only + if(objTmp!=null) + { + objCtrl=objTmp.ContainerControl as System.Windows.Forms.Control; + if(objCtrl is MenuPanel && ((MenuPanel)objCtrl).PopupMenu) + objCtrl=objCtrl.Parent; + if (objCtrl != null && objCtrl.Handle == iHandle) + return true; + objTmp=null; + } + + foreach(BaseItem objItem in m_SubItems) + { + // Now go through each child and if it is expanded call this function to verify the handle + if(objItem.Expanded) + { + if(objItem.IsAnyOnHandle(iHandle)) + { + bRet=true; + break; + } + } + } + + return bRet; + } + + /// + /// Gets or sets item description. This description is displayed in + /// Customize dialog to describe the item function in an application. + /// + [Browsable(true),DevCoBrowsable(true),DefaultValue(""),Category("Design"),Description("Indicates description of the item that is displayed during design."), Localizable(true)] + public virtual string Description + { + get + { + + return m_Description; + } + set + { + if(m_Description==value) + return; + m_Description=value; + + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "Description"); + } + } + + /// + /// Gets or sets whether the item expands automatically to fill out the remaining space inside the container. Applies to Items on stretchable, no-wrap Bars only. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(false),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates whether item will stretch to consume empty space. Items on stretchable, no-wrap Bars only.")] + public virtual bool Stretch + { + get + { + return m_Stretch; + } + set + { + if(m_Stretch==value) + return; + m_Stretch=value; + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "Stretch"); + NeedRecalcSize=true; + if(this.Displayed && m_Parent!=null && !m_SuspendLayout) + { + m_Parent.SubItemSizeChanged(this); + } + OnAppearanceChanged(); + } + } + + /// + /// Occurs after Tooltip text has changed. + /// + protected virtual void OnTooltipChanged(){} + /// + /// Gets/Sets informational text (tooltip) for the item. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(""),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates the text that is displayed when mouse hovers over the item."),System.ComponentModel.Localizable(true)] + public virtual string Tooltip + { + get + { + + return m_Tooltip; + } + set + { + if (m_Tooltip == value) + return; + if (value == null) value = ""; + m_Tooltip = value; + + if (this.ToolTipVisible) + { + if (string.IsNullOrEmpty(m_Tooltip)) + this.HideToolTip(); + else + { + ToolTip tooltipWindow = m_ToolTipWnd; + tooltipWindow.Text = m_Tooltip; + tooltipWindow.ShowToolTip(); + tooltipWindow.Invalidate(); + } + } + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "Tooltip"); + OnTooltipChanged(); + } + } + + /// + /// Returns category for this item. If item cannot be customzied using the + /// customize dialog category is empty string. + /// + [Browsable(true),DevCoBrowsable(true),DefaultValue(""),Category("Design"),Description("Indicates item category used to group similar items at design-time."), Localizable(true)] + public virtual string Category + { + get + { + + return m_Category; + } + set + { + m_Category=value; + } + } + + /// + /// Returns name of the item that can be used to identify item from the code. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Design"),System.ComponentModel.Description("Indicates the name used to identify item.")] + public virtual 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; + } + } + + /// + /// Gets or sets the global name of the item that is used to synchronize the Global properties for the item across all instances with same + /// global name. Note that only instances that belong to the same control are synchronized. GlobalItem must be set to true to perform the synchronization. + /// You can find more information and list of + /// properties that are synchronized in help file. + /// + [Browsable(true), Category("Design"), Description("Indicates global name of the item that is used to synchronize the Global properties for the item across all instances with same global name."), DefaultValue("")] + public virtual string GlobalName + { + get { return m_GlobalName; } + set { m_GlobalName = value; } + } + + /// + /// Gets whether global properties should synchronized. + /// + protected virtual bool ShouldSyncProperties + { + get { return this.GlobalItem && (this.GlobalName.Length > 0 || this.Name.Length > 0) && !m_IsOnCustomizeDialog; } + } + + /// + /// Gets orientation within container that is supported by this item. If item does not support certain orientation the container automatically hides it when container switches into that orientation. + /// + [System.ComponentModel.Browsable(false)] + public eSupportedOrientation SupportedOrientation + { + get + { + return m_SupportedOrientation; + } + } + + /// + /// Gets or sets whether item is global or not. + /// This flag is used to propagate property changes to all items with the same name. + /// Setting for example Visible property on the item that has GlobalItem set to true will + /// set visible property to the same value on all items with the same name. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates whether certain global properties are propagated to all items with the same name when changed.")] + public virtual bool GlobalItem + { + get + { + return m_GlobalItem; + } + set + { + m_GlobalItem=value; + } + } + + /// + /// Gets or sets orientation inside the container. Do not change the value of this property. It is managed by system only. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual eOrientation Orientation + { + get + { + return m_Orientation; + } + set + { + if(m_Orientation!=value) + { + SetOrientation(value); + NeedRecalcSize=true; + } + } + } + + /// + /// Sets orientation of the item but it does not cause the recalculate layout flag setting on the parent item. + /// + /// New orientation value. + internal void SetOrientation(eOrientation o) + { + if (m_Orientation != o) + { + m_Orientation = o; + if (m_SubItems != null) + { + foreach (BaseItem objItem in m_SubItems) + { + objItem.Orientation = m_Orientation; + } + } + m_NeedRecalcSize = true; + } + } + + /// + /// Destroys tooltip window. + /// + internal protected void HideToolTip() + { + if(m_ToolTipWnd!=null) + { + System.Drawing.Rectangle tipRect=m_ToolTipWnd.Bounds; + tipRect.Width+=5; + tipRect.Height+=6; + + OnTooltip(false); + OnToolTipVisibleChanged(new EventArgs()); + try + { + if(m_ToolTipWnd!=null) + { + m_ToolTipWnd.Hide(); + m_ToolTipWnd.Dispose(); + m_ToolTipWnd=null; + } + } + catch{} + + if(this.ContainerControl!=null) + { + System.Windows.Forms.Control ctrl=this.ContainerControl as System.Windows.Forms.Control; + if(ctrl!=null) + ctrl.Invalidate(ctrl.RectangleToClient(tipRect),false); + } + } + } + + private void OnToolTipVisibleChanged(EventArgs eventArgs) + { + EventHandler h = ToolTipVisibleChanged; + if (h != null) + ToolTipVisibleChanged(this, eventArgs); + } + + internal BaseItem HotSubItem + { + get + { + return m_HotSubItem; + } + set + { + BaseItem oldValue = m_HotSubItem; + m_HotSubItem = value; + if (oldValue != value) + OnHotSubItemChanged(value, oldValue); + } + } + /// + /// Called when HotSubItem has changed. + /// + /// New value. + /// Old value. + protected virtual void OnHotSubItemChanged(BaseItem newValue, BaseItem oldValue) + { + } + + /// + /// Shows tooltip for this item. + /// + public virtual void ShowToolTip() + { + if(m_DesignMode) + return; + + if(m_Visible && m_Displayed && !m_Expanded) + { + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null && !owner.ShowToolTips || !this.ShowToolTips) + return; + Control container = this.ContainerControl as Control; + if (container is Bar && !((Bar)container).ShowToolTips) + return; + + if (container is MenuPanel && !((MenuPanel)container).ShowToolTips) + return; + + OnTooltip(true); + if(m_Tooltip!="") + { + if(m_ToolTipWnd==null) + m_ToolTipWnd=new ToolTip(); + m_ToolTipWnd.Style = EffectiveStyle; + m_ToolTipWnd.Text=m_Tooltip; + if(owner!=null && owner.ShowShortcutKeysInToolTips && m_Shortcuts!=null && m_Shortcuts.Count>0) + m_ToolTipWnd.Text+=(" ("+GetTooltipShortcutString()+")"); + IOwnerItemEvents ownerEvents=this.GetIOwnerItemEvents(); + if(ownerEvents!=null) + ownerEvents.InvokeToolTipShowing(this,new EventArgs()); + + m_ToolTipWnd.ReferenceRectangle = ScreenRectangle; + + OnToolTipVisibleChanged(new EventArgs()); + m_ToolTipWnd.ShowToolTip(); + } + } + } + /// + /// Returns the shortcut string that is displayed on tooltip. + /// + /// + protected virtual string GetTooltipShortcutString() + { + return this.ShortcutString; + } + + /// + /// Gets whether tooltip for the item is displayed. + /// + protected virtual bool ShowToolTips + { + get { return true; } + } + + internal virtual Rectangle ScreenRectangle + { + get + { + System.Windows.Forms.Control c = this.ContainerControl as System.Windows.Forms.Control; + if (c == null) return Rectangle.Empty; + return new Rectangle(c.PointToScreen(this.DisplayRectangle.Location), this.DisplayRectangle.Size); + } + } + + /// + /// Returns the point in screen coordinates. + /// + /// Client point + /// Point in screen coordinates if there is a parent Control otherwise clientPoint + public virtual Point PointToScreen(Point clientPoint) + { + Control c = this.ContainerControl as Control; + if (c == null) return clientPoint; + return c.PointToScreen(clientPoint); + } + + /// + /// Gets whether tooltip is visible or not. + /// + internal protected bool ToolTipVisible + { + get + { + return (m_ToolTipWnd!=null); + } + } + + /// + /// Gets or sets the name of the bar this item originated on. This is used to remember the + /// originating bar when user is moving the items from bar to bar. + /// + internal string OriginalBarName + { + get {return m_OriginalBarName;} + set {m_OriginalBarName=value;} + } + + /// + /// Gets or sets item's original position (index) if item position has changed due to the user customization. + /// + internal int OriginalPosition + { + get {return m_OriginalPosition;} + set {m_OriginalPosition=value;} + } + + /// + /// Gets or sets flag that indicates whether item was customize by the end-user. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool UserCustomized + { + get { return m_UserCustomized; } + set { m_UserCustomized = value; } + } + + /// + /// Gets reference to the tooltip control if tooltip is displayed for this item. + /// + [System.ComponentModel.Browsable(false)] + public ToolTip ToolTipControl + { + get {return m_ToolTipWnd;} + } + + /// + /// Gets or sets the Key Tips access key or keys for the item when on Ribbon Control or Ribbon Bar. Use KeyTips property + /// when you want to assign the one or more letters to be used to access an item. For example assigning the FN to KeyTips property + /// will require the user to press F then N keys to select an item. Pressing the F letter will show only keytips for the items that start with letter F. + /// + [Browsable(true), Category("Appearance"), DefaultValue(""), Description("Indicates the Key Tips access key or keys for the item when on Ribbon Control or Ribbon Bar.")] + public virtual string KeyTips + { + get { return m_KeyTips; } + set + { + if (value == null) value = ""; + m_KeyTips = value.ToUpper(); + } + } + + /// + /// Gets or sets the text associated with this item. + /// + [Browsable(true),DevCoBrowsable(true),Category("Appearance"),Description("The text contained in the item."),Localizable(true),DefaultValue(""), Bindable(true)] + public virtual string Text + { + get + { + return m_Text; + } + set + { + if(m_Text==value) + return; + if(value==null) + m_Text=""; + else + m_Text=value; + m_AccessKey=NativeFunctions.GetAccessKey(m_Text); + + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "Text"); + + NeedRecalcSize=true; + if(this.Displayed && m_Parent!=null && !m_SuspendLayout) + { + RecalcSize(); + m_Parent.SubItemSizeChanged(this); + } + + this.OnTextChanged(); + OnAppearanceChanged(); + } + } + + /// + /// Gets or sets whether item can be customized by end user. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates whether item can be customized by user.")] + public virtual bool CanCustomize + { + get + { + return m_CanCustomize; + } + set + { + m_CanCustomize=value; + } + } + + /// + /// Returns whether item is hosted on Customize menu. + /// + protected internal bool IsOnCustomizeMenu + { + get + { + return m_IsOnCustomizeMenu; + } + } + + internal void SetIsOnCustomizeMenu(bool b) + { + if(m_IsOnCustomizeMenu!=b) + { + m_IsOnCustomizeMenu=b; + OnIsOnCustomizeMenuChanged(); + } + } + + public override string ToString() + { + return m_Text; + } + + /// + /// Returns whether item is hosted on Customize Dialog. + /// + protected internal bool IsOnCustomizeDialog + { + get + { + return m_IsOnCustomizeDialog; + } + } + + internal void SetIsOnCustomizeDialog(bool b) + { + if(m_IsOnCustomizeDialog!=b) + { + m_IsOnCustomizeDialog=b; + OnIsOnCustomizeDialogChanged(); + } + } + + /// + /// Returns whether item is hosted on menu or not. + /// + [System.ComponentModel.Browsable(false)] + public bool IsOnMenu + { + get + { + if(this.ContainerControl is MenuPanel || this.ContainerControl is ItemsListBox) + return true; + else + return false; + } + } + + /// + /// Returns whether item is hosted on menu bar or not. + /// + [System.ComponentModel.Browsable(false)] + public virtual bool IsOnMenuBar + { + get + { + System.Windows.Forms.Control ctrl=this.ContainerControl as System.Windows.Forms.Control; + if(ctrl!=null && ctrl is Bar) + return ((Bar)ctrl).MenuBar; + return false; + } + } + + /// + /// Returns whether item is hosted on bar or not. + /// + [System.ComponentModel.Browsable(false)] + public bool IsOnBar + { + get + { + System.Windows.Forms.Control ctrl=this.ContainerControl as System.Windows.Forms.Control; + if(ctrl!=null && ctrl is Bar) + return true; + return false; + } + } + + /// + /// Returns whether item is in design mode or not. + /// + [System.ComponentModel.Browsable(false),DevCoBrowsable(false)] + public virtual bool DesignMode + { + get + { + return m_DesignMode; + } + } + + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public void SetDesignMode(bool b) + { + if(m_DesignMode!=b) + { + m_DesignMode=b; + if(m_SubItems!=null) + { + foreach(BaseItem objItem in m_SubItems) + objItem.SetDesignMode(m_DesignMode); + } + if(m_HotSubItem!=null) + { + m_HotSubItem.InternalMouseLeave(); + HotSubItem = null; + } + OnDesignModeChanged(); + } + } + + /// + /// Get or sets whether item has been changed in a way that it needs its size recalculated. This is internal + /// property and it should not be used by your code. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool NeedRecalcSize + { + get + { + return m_NeedRecalcSize; + } + set + { + m_NeedRecalcSize=value; + if(value && this.Parent!=null && this.ContainerControl == this.Parent.ContainerControl) + { + this.Parent.NeedRecalcSize=true; + } + } + } + + + /// + /// Returns whether item is System item. + /// + [System.ComponentModel.Browsable(false)] + public bool SystemItem + { + get + { + return m_SystemItem; + } + } + + internal void SetSystemItem(bool b) + { + m_SystemItem=b; + } + + private bool _AccessKeyEnabled = true; + /// + /// Indicates whether access key processing set using ampersand key in Text is enabled. When enabled, and access key is pressed, item will raise Click event. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether access key processing set using ampersand key in Text is enabled. When enabled, and access key is pressed, item will raise Click event.")] + public bool AccessKeyEnabled + { + get { return _AccessKeyEnabled; } + set + { + _AccessKeyEnabled = value; + } + } + + + /// + /// Return Access key for the item. + /// + protected internal char AccessKey + { + get + { + return m_AccessKey; + } + } + + /// + /// Gets or sets the collection of shortcut keys associated with the item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Design"), System.ComponentModel.Description("Indicates list of shortcut keys for this item."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ShortcutsDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter("DevComponents.DotNetBar.Design.ShortcutsConverter, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)] + public virtual ShortcutsCollection Shortcuts + { + get + { + if(m_Shortcuts==null) + m_Shortcuts=new ShortcutsCollection(this); + return m_Shortcuts; + } + set + { + IOwner owner=this.GetOwner() as IOwner; + if(m_Shortcuts!=null && owner!=null) + owner.RemoveShortcutsFromItem(this); + m_Shortcuts=value; + m_Shortcuts.Parent=this; + if(m_Shortcuts!=null && owner!=null) + owner.AddShortcutsFromItem(this); + } + } + + /// + /// Returns text representation of shortcut for this item. + /// + protected internal string ShortcutString + { + get + { + return m_ShortcutString; + } + } + + internal void RefreshShortcutString() + { + m_ShortcutString = ""; + if (m_Shortcuts == null || m_Shortcuts.Count == 0) + return; + System.Windows.Forms.KeysConverter objConv = new System.Windows.Forms.KeysConverter(); + m_ShortcutString = objConv.ConvertToString((System.Windows.Forms.Keys)m_Shortcuts[0]); + } + + /// + /// Collapses all sub items by setting their Expanded property to false. + /// + /// Item to collapse. + public static void CollapseSubItems(BaseItem item) + { + if(item==null && item.SubItems.Count==0) + return; + BaseItem[] subItems = new BaseItem[item.SubItems.Count]; + item.SubItems.CopyTo(subItems, 0); + foreach (BaseItem o in subItems) + if (o.Expanded) + o.Expanded = false; + } + + /// + /// Collapses all sub items by setting their Expanded property to false. Enumerates all child items as well. + /// + /// Item to collapse. + public static void CollapseSubItemsTree(BaseItem item) + { + if (item == null && item.SubItems.Count == 0) + return; + BaseItem[] subItems = new BaseItem[item.SubItems.Count]; + item.SubItems.CopyTo(subItems, 0); + foreach (BaseItem o in subItems) + { + CollapseSubItemsTree(o); + if (o.Expanded) + o.Expanded = false; + } + } + + /// + /// Collapses whole tree for the item starting with its parent. + /// + /// Item to collapse. + public static void CollapseAll(BaseItem objItem) + { + if(objItem==null) + return; + + do + { + System.Windows.Forms.Control objCtrl=objItem.ContainerControl as System.Windows.Forms.Control; + if (objCtrl is MenuPanel) + { + if (objItem.Parent != null) + objItem = objItem.Parent; + } + else if (objCtrl is Bar) + { + if (((Bar)objCtrl).ParentInternal == null) + break; + objItem = ((Bar)objCtrl).ParentItem; + } + else if (objItem is RadialMenuContainer && objItem.Parent != null) + { + break; + } + else if (objItem.Parent != null) + objItem = objItem.Parent; + } while (objItem!=null && objItem.Parent!=null); + + if(objItem!=null) + { + objItem.Expanded=false; + objItem.AutoExpand=false; + if(objItem.Parent!=null) + objItem.Parent.AutoExpand=false; + } + } + + /// + /// Returns whether item is hosted on popup menu or bar. + /// + /// Item to get information for. + /// + public static bool IsOnPopup(BaseItem item) + { + if(item==null) + return false; + object objCont=item.ContainerControl; + if(objCont==null) + return false; + if(objCont is MenuPanel) + return true; + if(objCont is Bar) + { + if(((Bar)objCont).BarState==eBarState.Popup) + return true; + } + if (objCont is RadialMenuPopup) return true; + + return false; + } + + /// + /// Gets or sets whether Click event will be auto repeated when mouse button is kept pressed over the item. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(false),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Gets or sets whether Click event will be auto repeated when mouse button is kept pressed over the item.")] + public virtual bool ClickAutoRepeat + { + get + { + return m_ClickAutoRepeat; + } + set + { + m_ClickAutoRepeat=value; + } + } + + /// + /// Gets or sets the auto-repeat interval for the click event when mouse button is kept pressed over the item. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(600),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Gets or sets the auto-repeat interval for the click event when mouse button is kept pressed over the item.")] + public virtual int ClickRepeatInterval + { + get + { + return m_ClickRepeatInterval; + } + set + { + m_ClickRepeatInterval=value; + } + } + + /// + /// Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table. + /// + /// Hash code. + public override int GetHashCode() + { + return m_Id; + } + + internal eDesignInsertPosition DesignInsertMarker + { + get {return m_DesignInsertMarker;} + set + { + if(m_DesignInsertMarker==value) + return; + m_DesignInsertMarker=value; + //if(this.DesignMode) + this.Refresh(); + } + } + + private eDesignMarkerOrientation _DesignMarkerOrientation = eDesignMarkerOrientation.NotSet; + /// + /// Gets or sets the design-marker orientation for the item. + /// + protected internal virtual eDesignMarkerOrientation DesignMarkerOrientation + { + get + { + return _DesignMarkerOrientation; + } + set + { + _DesignMarkerOrientation = value; + } + } + + /// + /// Gets whether design-time item drag & drop marker is horizontal. + /// + internal bool IsDesignMarkHorizontal + { + get + { + if (_DesignMarkerOrientation != eDesignMarkerOrientation.NotSet) + return _DesignMarkerOrientation == eDesignMarkerOrientation.Horizontal; + + if (this.Parent is ItemContainer) + { + if (((ItemContainer)this.Parent).LayoutOrientation == eOrientation.Horizontal) + return true; + else + return false; + } + else if (this.Parent is SimpleItemContainer) + { + if (((SimpleItemContainer)this.Parent).LayoutOrientation == eOrientation.Horizontal) + return true; + else + return false; + } + + if(m_Orientation==eOrientation.Horizontal && !this.IsOnMenu && !(this.Parent is SideBarPanelItem) && !(this.Parent is ExplorerBarGroupItem)) + return true; + + return false; + } + } + + protected virtual bool ShouldDrawInsertMarker() + { + IOwner owner = GetOwner() as IOwner; + + return m_DesignInsertMarker != eDesignInsertPosition.None && this.Visible && this.Displayed && + (owner != null && !owner.DragInProgress && !this.DesignMode); + } + + protected internal void DrawInsertMarker(System.Drawing.Graphics g) + { + if (!ShouldDrawInsertMarker()) + return; + + Color lineColor = ColorScheme.GetColor("834DD5"); + Color fillColor = ColorScheme.GetColor("CCCFF8"); + + int size = 4; + int lineThickness = 1; + int padding = 2; + + if(IsDesignMarkHorizontal) + { + Point start = new Point(m_Rect.X, m_Rect.Y + padding), end = new Point(m_Rect.X, m_Rect.Bottom - (padding + 1)); + if (m_DesignInsertMarker == eDesignInsertPosition.After) + { + start = new Point(m_Rect.Right - size * 2, m_Rect.Y + padding); + end = new Point(m_Rect.Right - size * 2, m_Rect.Bottom - (padding+1)); + } + + using (SolidBrush fillBrush = new SolidBrush(fillColor)) + { + using (Pen pen = new Pen(lineColor, 1)) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLine(start.X, start.Y + size, start.X + size, start.Y); + path.AddLine(start.X + size * 2, start.Y + size, start.X + (size * 2 - (size - lineThickness)), start.Y + size); + path.AddLine(end.X + (size * 2 - (size - lineThickness)), end.Y - size, end.X + size * 2, end.Y - size); + path.AddLine(end.X + size, end.Y, end.X, end.Y - size); + path.AddLine(end.X + (size - lineThickness), end.Y - size, start.X + (size - lineThickness), start.Y + size); + path.CloseAllFigures(); + + g.FillPath(fillBrush, path); + g.DrawPath(pen, path); + } + } + } + } + else + { + Point start = new Point(m_Rect.X + padding, m_Rect.Y), end = new Point(m_Rect.Right - (padding+1), m_Rect.Y); + if (m_DesignInsertMarker == eDesignInsertPosition.After) + { + start = new Point(m_Rect.X + padding, m_Rect.Bottom - (size * 2 + 1)); + end = new Point(m_Rect.Right - (padding + 1), m_Rect.Bottom - (size * 2 + 1)); + } + + using (SolidBrush fillBrush = new SolidBrush(fillColor)) + { + using (Pen pen = new Pen(lineColor, 1)) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLine(start.X, start.Y + size, start.X + size, start.Y); + path.AddLine(start.X + size, start.Y + (size - lineThickness), end.X - size, end.Y + (size - lineThickness)); + path.AddLine(end.X - size, end.Y, end.X, end.Y + size); + path.AddLine(end.X - size, end.Y + size * 2, end.X - size, end.Y + (size*2 - (size-padding))); + path.AddLine(start.X + size, start.Y + (size * 2 - (size - padding)), start.X + size, start.Y + size * 2); + + path.CloseAllFigures(); + + g.FillPath(fillBrush, path); + g.DrawPath(pen, path); + } + } + } + //if(m_DesignInsertMarker==eDesignInsertPosition.Before) + //{ + // p[0].X=m_Rect.Left+1; + // p[0].Y=m_Rect.Top; + // p[1].X=m_Rect.Left+1; + // p[1].Y=m_Rect.Top+4; + // g.DrawLines(pen,p); + + // p[0].X=m_Rect.Left+1; + // p[0].Y=m_Rect.Top+2; + // p[1].X=m_Rect.Right-1; + // p[1].Y=m_Rect.Top+2; + // g.DrawLines(pen,p); + + // p[0].X=m_Rect.Right-1; + // p[0].Y=m_Rect.Top; + // p[1].X=m_Rect.Right-1; + // p[1].Y=m_Rect.Top+4; + // g.DrawLines(pen,p); + //} + //else + //{ + // p[0].X=m_Rect.Left+1; + // p[0].Y=m_Rect.Bottom-4; + // p[1].X=m_Rect.Left+1; + // p[1].Y=m_Rect.Bottom; + // g.DrawLines(pen,p); + + // p[0].X=m_Rect.Left+1; + // p[0].Y=m_Rect.Bottom-2; + // p[1].X=m_Rect.Right-1; + // p[1].Y=m_Rect.Bottom-2; + // g.DrawLines(pen,p); + + // p[0].X=m_Rect.Right-1; + // p[0].Y=m_Rect.Bottom-4; + // p[1].X=m_Rect.Right-1; + // p[1].Y=m_Rect.Bottom; + // g.DrawLines(pen,p); + //} + } + //g.SmoothingMode = sm; + } + + /// + /// Specifes the mouse cursor displayed when mouse is over the item. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(null),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Specifies the mouse cursor displayed when mouse is over the item.")] + public virtual System.Windows.Forms.Cursor Cursor + { + get + { + return m_Cursor; + } + set + { + if(m_Cursor!=value) + { + m_Cursor=value; + if(m_Cursor!=null && m_Visible && m_Displayed) + { + System.Windows.Forms.Control cont=this.ContainerControl as System.Windows.Forms.Control; + if(cont!=null) + { + System.Drawing.Point p=cont.PointToClient(System.Windows.Forms.Control.MousePosition); + if(m_Rect.Contains(p)) + cont.Cursor=m_Cursor; + } + } + } + } + } + + [System.ComponentModel.Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override System.ComponentModel.ISite Site + { + get + { + return base.Site; + } + set + { + base.Site = value; + OnSiteChanged(); + } + } + + protected virtual void OnSiteChanged() + { + + } + + /// + /// Indicates whether item will be Serialized. + /// + [System.ComponentModel.Browsable(false),DevCoBrowsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public bool ShouldSerialize + { + get + { + return m_ShouldSerialize; + } + set + { + m_ShouldSerialize=value; + } + } + + internal bool IsThemed + { + get + { + if(m_ThemeAware && BarFunctions.ThemedOS && Themes.ThemesActive && !BarFunctions.IsWindows8) + return true; + return false; + } + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public virtual bool IsWindowed + { + get {return false;} + } + + /// + /// Specifies whether item is drawn using Themes when running on OS that supports themes like Windows XP. + /// + [Browsable(true),DevCoBrowsable(true),DefaultValue(false),Category("Appearance"),Description("Specifies whether item is drawn using Themes when running on OS that supports themes like Windows XP.")] + public virtual bool ThemeAware + { + get + { + return m_ThemeAware; + } + set + { + m_ThemeAware=value; + if(m_SubItems!=null) + { + foreach(BaseItem item in m_SubItems) + item.ThemeAware=value; + } + } + } + + /// + /// Gets the AccessibleObject assigned to the item. + /// + [System.ComponentModel.Browsable(false),DevCoBrowsable(false)] + public virtual System.Windows.Forms.AccessibleObject AccessibleObject + { + get + { + return CreateAccessibilityInstance(); //m_Accessible; + } + } + + private ItemAccessibleObject _ItemAccessibleObject = null; + protected virtual System.Windows.Forms.AccessibleObject CreateAccessibilityInstance() + { + if (_ItemAccessibleObject == null) + _ItemAccessibleObject = new ItemAccessibleObject(this); + return _ItemAccessibleObject; + } + + /// + /// Gets or sets the default action description of the control for use by accessibility client applications. + /// + [DevCoBrowsable(true),System.ComponentModel.Browsable(true),System.ComponentModel.Category("Accessibility"),System.ComponentModel.DefaultValue(""),System.ComponentModel.Description("Gets or sets the default action description of the control for use by accessibility client applications.")] + public virtual string AccessibleDefaultActionDescription + { + get {return m_AccessibleDefaultActionDescription;} + set {m_AccessibleDefaultActionDescription=value;} + } + + /// + /// Gets or sets the description of the control used by accessibility client applications. + /// + [DevCoBrowsable(true),System.ComponentModel.Browsable(true),System.ComponentModel.Category("Accessibility"),System.ComponentModel.DefaultValue(""),System.ComponentModel.Description("Gets or sets the description of the control used by accessibility client applications.")] + public virtual string AccessibleDescription + { + get {return m_AccessibleDescription;} + set + { + if(m_AccessibleDescription!=value) + { + m_AccessibleDescription=value; + GenerateAccessibilityEvent(System.Windows.Forms.AccessibleEvents.DescriptionChange); + } + } + } + + /// + /// Gets or sets the name of the control used by accessibility client applications. + /// + [DevCoBrowsable(true),System.ComponentModel.Browsable(true),System.ComponentModel.Category("Accessibility"),System.ComponentModel.Description("Gets or sets the name of the control used by accessibility client applications."),System.ComponentModel.DefaultValue("")] + public virtual string AccessibleName + { + get {return m_AccessibleName;} + set + { + if(m_AccessibleName!=value) + { + m_AccessibleName=value; + GenerateAccessibilityEvent(System.Windows.Forms.AccessibleEvents.NameChange); + } + } + } + + /// + /// Gets or sets the accessible role of the item. + /// + [DevCoBrowsable(true),System.ComponentModel.Browsable(true),System.ComponentModel.Category("Accessibility"),System.ComponentModel.Description("Gets or sets the accessible role of the item."),System.ComponentModel.DefaultValue(System.Windows.Forms.AccessibleRole.Default)] + public virtual System.Windows.Forms.AccessibleRole AccessibleRole + { + get {return m_AccessibleRole;} + set {m_AccessibleRole=value;} + } + + /// + /// Gets or sets a value indicating whether the item is visible to accessibility applications. + /// + [DevCoBrowsable(false),System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public virtual bool IsAccessible + { + get {return m_IsAccessible;} + set {m_IsAccessible=value;} + } + + internal void GenerateAccessibilityEvent(System.Windows.Forms.AccessibleEvents e) + { + if(this.ContainerControl is Bar && ((Bar)this.ContainerControl).m_AccessibleObjectCreated) + { + Bar.BarAccessibleObject a=((Bar)this.ContainerControl).AccessibilityObject as Bar.BarAccessibleObject; + if(a!=null) + a.GenerateEvent(this,e); + } +// else if(this.ContainerControl is PopupMenu && ((PopupMenu)this.ContainerControl).m_AccessibleObjectCreated) +// { +// PopupMenu.PopupMenuAccessibleObject a=((PopupMenu)this.ContainerControl).AccessibilityObject as PopupMenu.PopupMenuAccessibleObject; +// if(a!=null) +// a.GenerateEvent(this,e); +// } + } + internal bool _AccessibleExpandAction = false; + internal virtual void DoAccesibleDefaultAction() + { + if(this.VisibleSubItems>0 && (this.IsOnMenu || this.IsOnMenuBar || _AccessibleExpandAction)) + { + if(this.Expanded) + { + this.Expanded=false; + if(this.Parent!=null && this.IsOnMenuBar) + this.Parent.AutoExpand=false; + } + else + { + if(this.IsOnMenuBar && this.Parent!=null) + this.Parent.AutoExpand=true; + this.Expanded=true; + } + this.Refresh(); + _AccessibleExpandAction = false; + } + else + this.RaiseClick(eEventSource.Keyboard); + } + + private eContainerState _ContainerState = eContainerState.NotSet; + /// + /// Gets the item state inside of the parent container. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public eContainerState ContainerState + { + get { return _ContainerState; } + internal set { _ContainerState = value; } + } + + private Point _DragStartPoint; + internal Point DragStartPoint + { + get { return _DragStartPoint; } + set + { + if (value != _DragStartPoint) + { + Point oldValue = _DragStartPoint; + _DragStartPoint = value; + OnDragStartPointChanged(oldValue, value); + } + } + } + /// + /// Called when DragStartPoint property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDragStartPointChanged(Point oldValue, Point newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("DragStartPoint")); + } + private bool _AllowDrop = true; + internal bool AllowDrop + { + get { return _AllowDrop; } + set + { + _AllowDrop = value; + } + } + + protected void InvokeDelayed(MethodInvoker method) + { + InvokeDelayed(method, 10); + } + protected void InvokeDelayed(MethodInvoker method, int delayInterval) + { + Timer delayedInvokeTimer = new Timer(); + delayedInvokeTimer = new Timer(); + delayedInvokeTimer.Tag = method; + delayedInvokeTimer.Interval = delayInterval; + delayedInvokeTimer.Tick += new EventHandler(DelayedInvokeTimerTick); + delayedInvokeTimer.Start(); + } + void DelayedInvokeTimerTick(object sender, EventArgs e) + { + Timer timer = (Timer)sender; + MethodInvoker method = (MethodInvoker)timer.Tag; + timer.Stop(); + timer.Dispose(); + if (!this.IsDisposed) + method.Invoke(); + } + + private DevComponents.DotNetBar.Padding _Margin = new DevComponents.DotNetBar.Padding(0); + /// + /// Gets or sets item margin only used by certain items in certain containers. Provided only for internal DotNetBar use. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DevComponents.DotNetBar.Padding Margin + { + get { return _Margin; } + set { _Margin = value; } + } + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + if (_Command is Command && ((Command)_Command).IsSyncingCommand) return; + + CommandManager.ExecuteCommand(this); + } + + internal void ExecuteCommandInternal() + { + ExecuteCommand(); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that for ButtonItem instances if this property is set to null and command was assigned previously, Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public virtual Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "Command"); + } + } + + private ICommand _Command = null; + //[System.ComponentModel.Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if (changed) + OnCommandChanged(); + } + } + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public virtual object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "CommandParameter"); + } + } + + #endregion + + #region ItemAccessibleObject + public class ItemAccessibleObject: System.Windows.Forms.AccessibleObject + { + private BaseItem m_Owner=null; + private bool m_Hot=false; + public ItemAccessibleObject(BaseItem owner) + { + m_Owner = owner; + m_Owner.MouseEnter+=new EventHandler(OnMouseEnter); + m_Owner.MouseLeave+=new EventHandler(OnMouseLeave); + } + + protected virtual void OnMouseEnter(object sender, System.EventArgs e) + { + m_Hot=true; + } + + protected virtual void OnMouseLeave(object sender, System.EventArgs e) + { + m_Hot=false; + } + + internal BaseItem Owner + { + get { return m_Owner; } + } + + public override string Name + { + get + { + if(m_Owner==null) + return""; + + if(m_Owner.AccessibleName!="") + return m_Owner.AccessibleName; + + if(m_Owner.Text!=null) + return m_Owner.Text.Replace("&", ""); + + return m_Owner.Tooltip; + } + set + { + m_Owner.AccessibleName=value; + } + } + + public override string Description + { + get + { + if(m_Owner==null) + return ""; + if(m_Owner.AccessibleDescription!="") + return m_Owner.AccessibleDescription; + if (m_Owner.IsOnMenu) + return Name + " menu item"; + else if(m_Owner.IsOnMenuBar) + return Name + " menu"; + else + return Name + " button"; + } + } + + public override System.Windows.Forms.AccessibleRole Role + { + get + { + if(m_Owner==null || !m_Owner.IsAccessible) + return System.Windows.Forms.AccessibleRole.None; + + if(m_Owner.AccessibleRole!=System.Windows.Forms.AccessibleRole.Default) + return m_Owner.AccessibleRole; + BaseItem topParent=m_Owner; + while(topParent.Parent!=null) + topParent=topParent.Parent; + return (m_Owner.IsOnMenu || m_Owner.IsOnMenuBar || topParent.IsOnMenuBar ? + System.Windows.Forms.AccessibleRole.MenuItem : + System.Windows.Forms.AccessibleRole.PushButton); + } + } + + public override System.Windows.Forms.AccessibleStates State + { + get + { + if(m_Owner==null) + return System.Windows.Forms.AccessibleStates.Unavailable; + //System.Diagnostics.Trace.WriteLine("Getting state for "+m_Owner.Text); + System.Windows.Forms.AccessibleStates state=0; + + if(!m_Owner.IsAccessible) + return System.Windows.Forms.AccessibleStates.Unavailable; + + if(!m_Owner.Displayed || !m_Owner.Visible) + state |= System.Windows.Forms.AccessibleStates.Invisible; + else if (!m_Owner.GetEnabled()) + { + state=System.Windows.Forms.AccessibleStates.Unavailable; + if(m_Owner.Expanded || m_Hot || m_Owner is ButtonItem && ((ButtonItem)m_Owner).IsMouseOver) + state|=(System.Windows.Forms.AccessibleStates.HotTracked | System.Windows.Forms.AccessibleStates.Focused); + return state; + } + else + { + if(m_Owner.Expanded || m_Hot || m_Owner is ButtonItem && ((ButtonItem)m_Owner).IsMouseOver) + state |= (System.Windows.Forms.AccessibleStates.Focused | System.Windows.Forms.AccessibleStates.HotTracked); + else + state |= System.Windows.Forms.AccessibleStates.Focusable; + if(m_Owner.ShowSubItems && m_Owner.SubItems.Count>0) + { + if(m_Owner.Expanded) + state|=System.Windows.Forms.AccessibleStates.Expanded; + else + state|=System.Windows.Forms.AccessibleStates.Collapsed; + } + } + + +// if(m_Owner.SubItems.Count>0 && m_Owner.ShowSubItems) +// state|=(System.Windows.Forms.AccessibleStates)0x40000000; + + return state; + } + } + + /*public override string Value + { + get { return m_owner.AccessibleRole; } + set { m_owner.AccessibleRole = value; } + }*/ + + public override System.Windows.Forms.AccessibleObject Parent + { + get + { + if(m_Owner==null) + return null; + if(m_Owner.Parent!=null) + { + if(!(m_Owner.Parent is GenericItemContainer && ((GenericItemContainer)m_Owner.Parent).SystemContainer)) + return m_Owner.Parent.AccessibleObject; + } + + System.Windows.Forms.Control control=m_Owner.ContainerControl as System.Windows.Forms.Control; + if(control!=null) + return control.AccessibilityObject; + return null; + } + } + + public override System.Drawing.Rectangle Bounds + { + get + { + if(m_Owner==null) + return System.Drawing.Rectangle.Empty; + + System.Windows.Forms.Control objCtrl=m_Owner.ContainerControl as System.Windows.Forms.Control; + if (objCtrl != null) + return objCtrl.RectangleToScreen(m_Owner.DisplayRectangle); + else + return m_Owner.m_Rect; + } + } + + public override int GetChildCount() + { + if(m_Owner==null) + return 0; + return m_Owner.SubItems.Count; + } + + public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) + { + if (m_Owner == null || iIndex < 0 || iIndex >= m_Owner.SubItems.Count) + return null; + return m_Owner.SubItems[iIndex].AccessibleObject; + } + + public override string DefaultAction + { + get + { + if(m_Owner.AccessibleDefaultActionDescription!="") + return m_Owner.AccessibleDefaultActionDescription; + return "Press"; + } + } + + public override void DoDefaultAction() + { + if(m_Owner==null) + return; + + System.Windows.Forms.Control cont=m_Owner.ContainerControl as System.Windows.Forms.Control; + if(cont is MenuPanel && !(cont is IAccessibilitySupport)) + { + cont=((MenuPanel)cont).ParentItem.ContainerControl as System.Windows.Forms.Control; + } + + IAccessibilitySupport ias = cont as IAccessibilitySupport; + if(ias!=null) + { + ias.DoDefaultActionItem=m_Owner; + NativeFunctions.PostMessage(cont.Handle,NativeFunctions.WM_USER+107,IntPtr.Zero,IntPtr.Zero); + } + + base.DoDefaultAction(); + } + + public override string KeyboardShortcut + { + get + { + return m_Owner.ShortcutString; + } + } + + public override System.Windows.Forms.AccessibleObject GetSelected() + { + if (m_Owner == null) + return base.GetSelected(); + foreach (BaseItem item in m_Owner.SubItems) + { + if ((item.AccessibleObject.State & System.Windows.Forms.AccessibleStates.HotTracked) == System.Windows.Forms.AccessibleStates.HotTracked) + return item.AccessibleObject; + } + + return base.GetSelected(); + } + + public override System.Windows.Forms.AccessibleObject HitTest(int x, int y) + { + if (m_Owner == null) + return base.HitTest(x, y); + + Point screen=new Point(x,y); + foreach (BaseItem item in m_Owner.SubItems) + { + System.Windows.Forms.Control cont = item.ContainerControl as System.Windows.Forms.Control; + if (cont != null) + { + Point p = cont.PointToClient(screen); + if (item.DisplayRectangle.Contains(p)) + return item.AccessibleObject; + } + } + + return base.HitTest(x, y); + } + + public override System.Windows.Forms.AccessibleObject Navigate(System.Windows.Forms.AccessibleNavigation navdir) + { + if (m_Owner == null) + return base.Navigate(navdir); + + BaseItem item = null; + + if (navdir == System.Windows.Forms.AccessibleNavigation.Down || navdir == System.Windows.Forms.AccessibleNavigation.Right) + { + if (m_Owner.Parent != null) + { + BaseItem parent = m_Owner.Parent; + item = GetFirstVisible(parent.SubItems, parent.SubItems.IndexOf(m_Owner) + 1); + } + } + else if (navdir == System.Windows.Forms.AccessibleNavigation.Next) + { + if (m_Owner != null && m_Owner.Parent != null) + { + int index = m_Owner.Parent.SubItems.IndexOf(m_Owner); + if (index < m_Owner.Parent.SubItems.Count - 1) + item = m_Owner.Parent.SubItems[index + 1]; + } + } + else if (navdir == System.Windows.Forms.AccessibleNavigation.Previous) + { + if (m_Owner != null && m_Owner.Parent != null) + { + int index = m_Owner.Parent.SubItems.IndexOf(m_Owner); + if (index > 0) + item = m_Owner.Parent.SubItems[index - 1]; + } + } + else if (navdir == System.Windows.Forms.AccessibleNavigation.FirstChild) + { + item = GetFirstVisible(m_Owner.SubItems, 0); + } + else if (navdir == System.Windows.Forms.AccessibleNavigation.LastChild) + { + item = GetFirstVisibleReverse(m_Owner.SubItems, m_Owner.SubItems.Count - 1); + } + else if (navdir == System.Windows.Forms.AccessibleNavigation.Up) + { + if (m_Owner != null && m_Owner.Parent.IsContainer && m_Owner.Parent.SystemItem) + { + Control container = m_Owner.Parent.ContainerControl as Control; + if (container != null) return container.AccessibilityObject; + } + if (m_Owner.Parent != null) return m_Owner.Parent.AccessibleObject; + } + else if (navdir == System.Windows.Forms.AccessibleNavigation.Left) + { + BaseItem parent = m_Owner.Parent; + item = GetFirstVisibleReverse(m_Owner.SubItems, parent.SubItems.IndexOf(m_Owner) - 1); + } + + if (item != null) + return item.AccessibleObject; + + return base.Navigate(navdir); + } + + private BaseItem GetFirstVisible(SubItemsCollection col, int startIndex) + { + int count = col.Count; + if (count == 0) return null; + if (startIndex >= col.Count) startIndex = col.Count - 1; + for (int i = startIndex; i < count; i++) + { + if (col[i].Visible) + return col[i]; + } + return null; + } + + private BaseItem GetFirstVisibleReverse(SubItemsCollection col, int startIndex) + { + if (col.Count == 0) return null; + if (startIndex >= col.Count) startIndex = col.Count - 1; + for (int i = startIndex; i >= 0; i--) + { + if (col[i].Visible) + return col[i]; + } + return null; + } + + } + #endregion + + #region Markup Implementation + private TextMarkup.BodyElement m_TextMarkup = null; + + private void MarkupTextChanged() + { + if (m_TextMarkup != null) + m_TextMarkup.HyperLinkClick -= TextMarkupLinkClick; + + m_TextMarkup = null; + + if (!IsMarkupSupported) + return; + + if (!TextMarkup.MarkupParser.IsMarkup(ref m_Text)) + return; + + m_TextMarkup = TextMarkup.MarkupParser.Parse(m_Text); + + if(m_TextMarkup!=null) + m_TextMarkup.HyperLinkClick += TextMarkupLinkClick; + } + + /// + /// Occurs when text markup link is clicked. + /// + protected virtual void TextMarkupLinkClick(object sender, EventArgs e) {} + + /// + /// Gets reference to parsed markup body element if text was markup otherwise returns null. + /// + internal TextMarkup.BodyElement TextMarkupBody + { + get { return m_TextMarkup; } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void TextMarkupBodyMeasure(Size size, DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d) + { + TextMarkupBody.InvalidateElementsSize(); + TextMarkupBody.Measure(size, d); + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void TextMarkupBodyArrange(Rectangle r, DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d) + { + TextMarkupBody.Arrange(r, d); + } + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle TextMarkupBodyBounds + { + get + { + if (TextMarkupBody == null) return Rectangle.Empty; + return TextMarkupBody.Bounds; + } + set + { + TextMarkupBody.Bounds = value; + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void TextMarkupBodyRender(DevComponents.DotNetBar.TextMarkup.MarkupDrawContext d) + { + TextMarkupBody.Render(d); + } + + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)] + public bool IsUsingTextMarkup + { + get + { + return m_TextMarkup != null; + } + } + + /// + /// Gets plain text without text-markup if text-markup is used in Text. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public string PlainText + { + get + { + return m_TextMarkup != null ? m_TextMarkup.PlainText : Text; + } + } + + /// + /// Gets whether item supports text markup. Default is false. + /// + protected virtual bool IsMarkupSupported + { + get { return false; } + } + #endregion + + #region IBindableComponent Members +#if FRAMEWORK20 + private BindingContext _BindingContext = null; + [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public BindingContext BindingContext + { + get + { + if (_BindingContext != null) return _BindingContext; + Control container = this.ContainerControl as Control; + if (container != null) + { + if (container is MenuPanel) + { + object owner = this.GetOwner(); + if (owner is DotNetBarManager && ((DotNetBarManager)owner).ParentForm != null) + return ((DotNetBarManager)owner).ParentForm.BindingContext; + else if (owner is Control) + return ((Control)owner).BindingContext; + } + else + return container.BindingContext; + } + else + { + object owner = this.GetOwner(); + if (owner is DotNetBarManager && ((DotNetBarManager)owner).ParentForm != null) + return ((DotNetBarManager)owner).ParentForm.BindingContext; + else if (owner is Control) + { + return ((Control)owner).BindingContext; + } + } + + return null; + } + set + { + _BindingContext = value; + UpdateBindings(); + } + } + + /// + /// Updates data bindings for item and its sub-items in response to binding context change on parent control. + /// + public void UpdateBindings() + { + if(_DataBindings!=null) + { + BindingContext context = this.BindingContext; + for (int i = 0; i < _DataBindings.Count; i++) + { + BindingContext.UpdateBinding(context, _DataBindings[i]); + } + } + if (m_SubItems != null) + { + foreach (BaseItem item in m_SubItems) + { + item.UpdateBindings(); + } + } + } + + private ControlBindingsCollection _DataBindings = null; + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Data"), ParenthesizePropertyName(true), RefreshProperties(RefreshProperties.All)] + public ControlBindingsCollection DataBindings + { + get + { + if (_DataBindings == null) + { + _DataBindings = new ControlBindingsCollection(this); + } + return _DataBindings; + } + } +#endif + #endregion + + #region Invoke Support + /// + /// Gets a value indicating whether the caller must call an invoke method when making method calls to the item because the caller is on a different thread than the one the item was created on. + /// This property calls directly the ContainerControl.InvokeRequired and is provided as shortcut convinience property only. + /// + [Browsable(false)] + public bool InvokeRequired + { + get + { + Control parent = this.ContainerControl as Control; + if (parent != null) return parent.InvokeRequired; + return false; + } + } + + /// + /// Executes the specified delegate, on the thread that owns the control's underlying window handle, with the specified list of arguments. + /// This property calls directly the ContainerControl.Invoke and is provided as shortcut convenience property only. + /// + /// A delegate to a method that takes parameters of the same number and type that are contained in the args parameter. + /// An array of objects to pass as arguments to the specified method. This parameter can be null reference (Nothing in Visual Basic) if the method takes no arguments. + /// An Object that contains the return value from the delegate being invoked, or nullNothingnullptra null reference (Nothing in Visual Basic) if the delegate has no return value. + public Object Invoke(Delegate method,Object[] args) + { + Control parent = this.ContainerControl as Control; + if (parent == null || parent.IsDisposed) return null; + return parent.Invoke(method, args); + } + + /// + /// Executes the specified delegate, on the thread that owns the control's underlying window handle, with the specified list of arguments. + /// This property calls directly the ContainerControl.Invoke and is provided as shortcut convenience property only. + /// + /// A delegate to a method that takes parameters of the same number and type that are contained in the args parameter. + /// An Object that contains the return value from the delegate being invoked, or nullNothingnullptra null reference (Nothing in Visual Basic) if the delegate has no return value. + public Object Invoke(Delegate method) + { + Control parent = this.ContainerControl as Control; + if (parent == null || parent.IsDisposed) return null; + return parent.Invoke(method); + } + /// + /// Executes the specified delegate, on the thread that owns the control's underlying window handle, with the specified list of arguments. + /// This property calls directly the ContainerControl.BeginInvoke and is provided as shortcut convenience property only. + /// + /// A delegate to a method that takes parameters of the same number and type that are contained in the args parameter. + /// An Object that contains the return value from the delegate being invoked, or nullNothingnullptra null reference (Nothing in Visual Basic) if the delegate has no return value. + public Object BeginInvoke(Delegate method) + { + Control parent = this.ContainerControl as Control; + if (parent == null || parent.IsDisposed) return null; + return parent.BeginInvoke(method); + } + #endregion + + #region IComparable Members + + int IComparable.CompareTo(object obj) + { + if (obj == null) return 1; + + BaseItem targetItem = obj as BaseItem; + if (targetItem != null) + return string.Compare(this.Text, targetItem.Text); + else + throw new ArgumentException("Object is not a BaseItem"); + } + + #endregion + } + + /// + /// Defines item parent container states. + /// + public enum eContainerState + { + /// + /// State is not set. + /// + NotSet, + /// + /// Item in on the NavigationPane in normal size. + /// + NavigationPane, + } +} diff --git a/PROMS/DotNetBar Source Code/BaseItemController.cs b/PROMS/DotNetBar Source Code/BaseItemController.cs new file mode 100644 index 00000000..66b346b5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BaseItemController.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the controller which allows single BaseItem to be hosted on the control. + /// + internal class BaseItemController : IDisposable + { + #region Constructor + private BaseItem _Item = null; + private Control _ParentControl = null; + + /// + /// Initializes a new instance of the BaseItemController class. + /// + /// + /// + public BaseItemController(BaseItem item, Control parentControl) + { + _Item = item; + _ParentControl = parentControl; + _ParentControl.MouseDown += new MouseEventHandler(ParentControlMouseDown); + _ParentControl.MouseEnter += new EventHandler(ParentControlMouseEnter); + _ParentControl.MouseMove += new MouseEventHandler(ParentControlMouseMove); + _ParentControl.MouseUp += new MouseEventHandler(ParentControlMouseUp); + _ParentControl.MouseLeave += new EventHandler(ParentControlMouseLeave); + _ParentControl.Paint += new PaintEventHandler(ParentControlPaint); + _Item.ContainerControl = _ParentControl; + } + + #endregion + + #region Implementation + public BaseItem Item + { + get + { + return _Item; + } + } + void ParentControlPaint(object sender, PaintEventArgs e) + { + if (_Item.NeedRecalcSize) + { + _Item.RecalcSize(); + } + _Item.Displayed = true; + Graphics g = e.Graphics; + SmoothingMode sm = g.SmoothingMode; + TextRenderingHint th = g.TextRenderingHint; + g.SmoothingMode = SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + _Item.Paint(GetItemPaintArgs(g)); + g.SmoothingMode = sm; + g.TextRenderingHint = th; + } + + void ParentControlMouseLeave(object sender, EventArgs e) + { + if (_MouseOver) + { + _Item.InternalMouseLeave(); + _MouseOver = false; + } + } + + void ParentControlMouseUp(object sender, MouseEventArgs e) + { + _Item.InternalMouseUp(e); + } + + void ParentControlMouseMove(object sender, MouseEventArgs e) + { + if (_Item.Bounds.Contains(e.Location)) + { + if (!_MouseOver) + { + _Item.InternalMouseEnter(); + _MouseOver = true; + } + _Item.InternalMouseMove(e); + } + else if (_MouseOver) + { + _Item.InternalMouseLeave(); + _MouseOver = false; + } + } + private bool _MouseOver = false; + void ParentControlMouseEnter(object sender, EventArgs e) + { + Point p = _ParentControl.PointToClient(Control.MousePosition); + + if (_Item.Bounds.Contains(p)) + _Item.InternalMouseEnter(); + } + + void ParentControlMouseDown(object sender, MouseEventArgs e) + { + if (_Item.Bounds.Contains(e.Location)) + _Item.InternalMouseDown(e); + } + + private ItemPaintArgs GetItemPaintArgs(Graphics g) + { + ItemPaintArgs pa = new ItemPaintArgs(null, _ParentControl, g, GetColorScheme()); + pa.Renderer = this.GetRenderer(); + pa.ButtonStringFormat = pa.ButtonStringFormat & ~(pa.ButtonStringFormat & eTextFormat.SingleLine); + pa.ButtonStringFormat |= (eTextFormat.WordBreak | eTextFormat.EndEllipsis); + return pa; + } + + private ColorScheme GetColorScheme() + { + BaseRenderer r = GetRenderer(); + if (r is Office2007Renderer) + return ((Office2007Renderer)r).ColorTable.LegacyColors; + return new ColorScheme(eDotNetBarStyle.StyleManagerControlled); + } + private Rendering.BaseRenderer m_DefaultRenderer = null; + private Rendering.BaseRenderer m_Renderer = null; + private eRenderMode m_RenderMode = eRenderMode.Global; + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public virtual Rendering.BaseRenderer GetRenderer() + { + return Rendering.GlobalManager.Renderer; + } + #endregion + + #region IDisposable Members + + public void Dispose() + { + if (_ParentControl != null) + { + _ParentControl.MouseDown -= new MouseEventHandler(ParentControlMouseDown); + _ParentControl.MouseEnter -= new EventHandler(ParentControlMouseEnter); + _ParentControl.MouseMove -= new MouseEventHandler(ParentControlMouseMove); + _ParentControl.MouseUp -= new MouseEventHandler(ParentControlMouseUp); + _ParentControl.MouseLeave -= new EventHandler(ParentControlMouseLeave); + _ParentControl.Paint -= new PaintEventHandler(ParentControlPaint); + _Item.ContainerControl = null; + _Item = null; + _ParentControl = null; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/BaseItemDesigner.cs b/PROMS/DotNetBar Source Code/BaseItemDesigner.cs new file mode 100644 index 00000000..3a2cac92 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BaseItemDesigner.cs @@ -0,0 +1,258 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents designer for BaseItem objects and derived classes. + /// + public class BaseItemDesigner:System.ComponentModel.Design.ComponentDesigner,IDesignerServices + { + #region Internal Implementation + /// + /// Creates new instance of the class. + /// + public BaseItemDesigner() + { + } + + 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); + + BaseItem c=component as BaseItem; + if(c!=null) + this.Visible=c.Visible; + + // If our component is removed we need to clean-up + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + if(cc!=null) + { + cc.ComponentRemoved+=new ComponentEventHandler(this.OnComponentRemoved); + } + } + protected override void Dispose(bool disposing) + { + ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService)); + if(ss!=null) + ss.SelectionChanged-=new EventHandler(OnSelectionChanged); + + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + if(cc!=null) + { + cc.ComponentRemoved-=new ComponentEventHandler(this.OnComponentRemoved); + } + + base.Dispose(disposing); + } + + private void OnComponentRemoved(object sender,ComponentEventArgs e) + { + if(e.Component is BaseItem) + { + BaseItem parent=this.Component as BaseItem; + BaseItem item=e.Component as BaseItem; + if(item!=null && parent!=null && parent.SubItems.Contains(item)) + { + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + if(cc!=null) + cc.OnComponentChanging(parent,TypeDescriptor.GetProperties(parent)["SubItems"]); + parent.SubItems.Remove(item); + if(cc!=null) + cc.OnComponentChanged(parent,TypeDescriptor.GetProperties(parent)["SubItems"],null,null); + this.RecalcLayout(); + } + } + } + + private void OnSelectionChanged(object sender, EventArgs e) + { + ISelectionService ss = (ISelectionService)sender; + if(ss!=null && ss.PrimarySelection!=this.Component && ss.PrimarySelection is BaseItem) + { + BaseItem item=this.Component as BaseItem; + if(item!=null) + { + BaseItem selected=ss.PrimarySelection as BaseItem; + IOwner owner=item.GetOwner() as IOwner; + if(owner!=null) + { + if(owner.GetItem(selected.Name)!=selected) + owner.SetFocusItem(null); + } + } + } + } + + public override DesignerVerbCollection Verbs + { + get + { + DesignerVerb[] verbs = new DesignerVerb[] + { + new DesignerVerb("Create Button", new EventHandler(CreateButton)), + new DesignerVerb("Create Text Box", new EventHandler(CreateTextBox)), + new DesignerVerb("Create Combo Box", new EventHandler(CreateComboBox)), + new DesignerVerb("Create Label", new EventHandler(CreateLabel)), + }; + return new DesignerVerbCollection(verbs); + } + } + + protected virtual void CreateButton(object sender, EventArgs e) + { + CreateNewItem(typeof(ButtonItem)); + } + + protected virtual void CreateComboBox(object sender, EventArgs e) + { + CreateNewItem(typeof(ComboBoxItem)); + } + + protected virtual void CreateLabel(object sender, EventArgs e) + { + CreateNewItem(typeof(LabelItem)); + } + + protected virtual void CreateTextBox(object sender, EventArgs e) + { + CreateNewItem(typeof(TextBoxItem)); + } + + protected virtual void CreateNewItem(Type itemType) + { + BaseItem parent=this.Component as BaseItem; + System.ComponentModel.Design.IDesignerHost dh=(System.ComponentModel.Design.IDesignerHost)GetService(typeof(System.ComponentModel.Design.IDesignerHost)); + System.ComponentModel.Design.IComponentChangeService change=this.GetService(typeof(System.ComponentModel.Design.IComponentChangeService)) as IComponentChangeService; + if(change!=null) + change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(parent).Find("SubItems",true)); + BaseItem item=dh.CreateComponent(itemType) as BaseItem; + if(item==null) + return; + item.Text=item.Name; + BeforeNewItemAdded(item); + parent.SubItems.Add(item); + AfterNewItemAdded(item); + if(change!=null) + change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(parent).Find("SubItems",true),null,null); + + this.RecalcLayout(); + } + + protected virtual void BeforeNewItemAdded(BaseItem item) {} + + protected virtual void AfterNewItemAdded(BaseItem item) {} + + protected virtual void RecalcLayout() + { + BaseItem item=this.Component as BaseItem; + System.Windows.Forms.Control control=item.ContainerControl as System.Windows.Forms.Control; + + if(control is Bar) + ((Bar)control).RecalcLayout(); + else if(control is ExplorerBar) + ((ExplorerBar)control).RecalcLayout(); + else if(control is BarBaseControl) + ((BarBaseControl)control).RecalcLayout(); + else if(control is SideBar) + ((SideBar)control).RecalcLayout(); + } + + public override System.Collections.ICollection AssociatedComponents + { + get + { + System.Collections.ArrayList components=new System.Collections.ArrayList(); + BaseItem parent=this.Component as BaseItem; + if(parent==null) + return base.AssociatedComponents; + parent.SubItems.CopyTo(components); + return components; + } + } + + protected override void PreFilterProperties(IDictionary properties) + { + base.PreFilterProperties(properties); + properties["Visible"] = TypeDescriptor.CreateProperty(typeof(BaseItemDesigner),(PropertyDescriptor)properties["Visible"], new Attribute[] + { + new DefaultValueAttribute(true), + new BrowsableAttribute(true), + new CategoryAttribute("Layout")}); + properties["CanCustomize"] = TypeDescriptor.CreateProperty(typeof(BaseItemDesigner),(PropertyDescriptor)properties["CanCustomize"], new Attribute[] + { + new DefaultValueAttribute(true), + new BrowsableAttribute(true), + new CategoryAttribute("Behavior"), + new DescriptionAttribute("Indicates whether item can be customized by user.")}); + } + + /// + /// Gets or sets whether item can be customized by end user. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.DefaultValue(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates whether item can be customized by user.")] + public virtual bool CanCustomize + { + get + { + return (bool)ShadowProperties["CanCustomize"]; + } + set + { + // this value is not passed to the actual control + this.ShadowProperties["CanCustomize"] = value; + } + } + + /// + /// Gets or sets whether item is visible. + /// + [DefaultValue(true),Browsable(true),DevCoBrowsable(true),Category("Layout"),Description("Gets or sets whether item is visible.")] + public bool Visible + { + get + { + return (bool)ShadowProperties["Visible"]; + } + set + { + // this value is not passed to the actual control + this.ShadowProperties["Visible"] = value; + } + } + #endregion + + #region IDesignerServices Implementation + object IDesignerServices.CreateComponent(System.Type componentClass) + { + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh==null) + return null; + return dh.CreateComponent(componentClass); + } + + void IDesignerServices.DestroyComponent(IComponent c) + { + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh==null) + return; + dh.DestroyComponent(c); + } + + object IDesignerServices.GetService(Type serviceType) + { + return this.GetService(serviceType); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/BindingDef.cs b/PROMS/DotNetBar Source Code/BindingDef.cs new file mode 100644 index 00000000..6ef3f779 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BindingDef.cs @@ -0,0 +1,504 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Windows.Forms; +using System.Globalization; +using System.Drawing; +using System.Security; +using System.Reflection; +using System.Collections; +using System.ComponentModel.Design.Serialization; + +namespace DevComponents.DotNetBar +{ + /// + /// Defines class which described single binding. + /// + [TypeConverter(typeof(BindingDefConverer)), DesignTimeVisible(false), ToolboxItem(false)] + public class BindingDef : INotifyPropertyChanged + { + #region Dependency Properties & Events + public event DataConvertEventHandler Format; + /// + /// Raises Format event. + /// + /// Provides event arguments. + protected virtual void OnFormat(DataConvertEventArgs e) + { + DataConvertEventHandler handler = Format; + if (handler != null) + handler(this, e); + } + #endregion + + #region Constructor + /// + /// Initializes a new instance of the BindingDef class. + /// + public BindingDef() + { + + } + /// + /// Initializes a new instance of the BindingDef class. + /// + /// + /// + public BindingDef(string propertyName, string dataMember) + { + _PropertyName = propertyName; + _PropertyPath = propertyName.Split('.'); + _DataMember = dataMember; + _BindingMemberInfo = new BindingMemberInfo(dataMember); + } + #endregion + + #region Implementation + /// + /// Updates specified item PropertyName with the data from data object property specified by DataMember. + /// + /// Item to set PropertyName on. + /// Data to retrieve DataMember value from. + public void Update(object item, object data) + { + Update(null, item, data); + } + + /// + /// Updates specified item PropertyName with the data from data object property specified by DataMember. + /// + /// CurrencyManager to use + /// Item to set PropertyName on. + /// Data to retrieve DataMember value from. + public void Update(ItemVisualGenerator generator, object item, object data) + { + string propertyName = _PropertyName; + + if (item is BaseItem && _PropertyPath.Length > 1) + { + // Dig into child items + BaseItem parent = (BaseItem)item; + for (int i = 0; i < _PropertyPath.Length - 1; i++) + { + parent = parent.SubItems[_PropertyPath[i]]; + } + item = parent; + propertyName = _PropertyPath[_PropertyPath.Length - 1]; + } + + PropertyInfo targetProp = item.GetType().GetProperty(propertyName); + if (targetProp.PropertyType == typeof(string)) + targetProp.SetValue(item, GetDataText(generator, data, _DataMember), null); + else + targetProp.SetValue(item, GetDataValue(generator, data, _DataMember, GetPropertyValue(generator, data, _DataMember)), null); + } + + private static TypeConverter stringTypeConverter; + private string GetDataText(ItemVisualGenerator generator, object data, string fieldName) + { + object propertyValue = GetPropertyValue(generator, data, fieldName); + return GetDataText(generator, data, fieldName, propertyValue); + } + private string GetDataText(ItemVisualGenerator generator, object data, string fieldName, object propertyValue) + { + if (!_FormattingEnabled) + { + if (data == null) + { + return string.Empty; + } + if (propertyValue == null) + { + return ""; + } + return Convert.ToString(propertyValue, CultureInfo.CurrentCulture); + } + + DataConvertEventArgs e = new DataConvertEventArgs(propertyValue, typeof(string), data, fieldName); + this.OnFormat(e); + if ((e.Value != data) && (e.Value is string)) + { + return (string)e.Value; + } + if (stringTypeConverter == null) + { + stringTypeConverter = TypeDescriptor.GetConverter(typeof(string)); + } + try + { + return (string)FormatHelper.FormatObject(propertyValue, typeof(string), generator.GetFieldConverter(fieldName), stringTypeConverter, _FormatString, _FormatInfo, null, DBNull.Value); + } + catch (Exception ex) + { + if (ex is SecurityException || IsCriticalException(ex)) + { + throw; + } + return ((propertyValue != null) ? Convert.ToString(data, CultureInfo.CurrentCulture) : ""); + } + } + + private object GetDataValue(ItemVisualGenerator generator, object data, string fieldName, object propertyValue) + { + if (!_FormattingEnabled) + { + return propertyValue; + } + + DataConvertEventArgs e = new DataConvertEventArgs(propertyValue, typeof(object), data, fieldName); + this.OnFormat(e); + return e.Value; + } + + private static bool IsCriticalException(Exception ex) + { + return (((((ex is NullReferenceException) || (ex is StackOverflowException)) || ((ex is OutOfMemoryException) || (ex is System.Threading.ThreadAbortException))) || ((ex is ExecutionEngineException) || (ex is IndexOutOfRangeException))) || (ex is AccessViolationException)); + } + + private object GetPropertyValue(ItemVisualGenerator generator, object data, string fieldName) + { + if ((data != null) && (fieldName.Length > 0)) + { + try + { + PropertyDescriptor descriptor = null; + if (generator.DataManager != null) + { + descriptor = generator.DataManager.GetItemProperties().Find(fieldName, true); + } + if(descriptor == null) + { + descriptor = TypeDescriptor.GetProperties(data).Find(fieldName, true); + } + if (descriptor != null) + { + data = descriptor.GetValue(data); + } + } + catch + { + } + } + + if (data == DBNull.Value && _NullValue != null) + return _NullValue; + + return data; + } + #endregion + + #region Properties + private string[] _PropertyPath = new string[0]; + private string _PropertyName = ""; + /// + /// Gets or sets the property name binding is attached to. + /// + [DefaultValue(""), Category("Data"), Description("Indicates property name binding is attached to.")] + public string PropertyName + { + get { return _PropertyName; } + set + { + if (value != _PropertyName) + { + string oldValue = _PropertyName; + _PropertyName = value; + OnPropertyNameChanged(oldValue, value); + } + } + } + /// + /// Called when PropertyName property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPropertyNameChanged(string oldValue, string newValue) + { + _PropertyPath = newValue.Split('.'); + OnPropertyChanged(new PropertyChangedEventArgs("PropertyName")); + } + + /// + /// Gets the reference to BindingMemberInfo created based on DataMember. + /// + [Browsable(false)] + public BindingMemberInfo BindingMemberInfo + { + get + { + return _BindingMemberInfo; + } + } + + private BindingMemberInfo _BindingMemberInfo; + private string _DataMember = ""; + /// + /// Gets or sets the data member name which holds data that PropertyName is populated with. + /// + [DefaultValue(""), Category("Data"), Description("Indicates data member name which holds data that PropertyName is populated with.")] + public string DataMember + { + get { return _DataMember; } + set + { + if (value == null) value = ""; + if (value != _DataMember) + { + string oldValue = _DataMember; + _DataMember = value; + OnDataMemberChanged(oldValue, value); + } + } + } + /// + /// Called when DataMember property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDataMemberChanged(string oldValue, string newValue) + { + if (!string.IsNullOrEmpty(newValue)) + _BindingMemberInfo = new BindingMemberInfo(newValue); + else + _BindingMemberInfo = new BindingMemberInfo(); + OnPropertyChanged(new PropertyChangedEventArgs("DataMember")); + } + + private bool _FormattingEnabled = false; + /// + /// Gets or sets whether type conversion and formatting is applied to the property data. + /// + [DefaultValue(false), Category("Data"), Description("Indicates whether type conversion and formatting is applied to the property data.")] + public bool FormattingEnabled + { + get { return _FormattingEnabled; } + set + { + if (value != _FormattingEnabled) + { + bool oldValue = _FormattingEnabled; + _FormattingEnabled = value; + OnFormattingEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when FormattingEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnFormattingEnabledChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("FormattingEnabled")); + + } + + private string _FormatString = ""; + /// + /// Gets or sets format specifier characters that indicate how a value is to be displayed. + /// For more information, see Formatting Overview: http://msdn.microsoft.com/en-us/library/26etazsy%28v=vs.71%29.aspx + /// + [DefaultValue(""), Category("Data"), Description("Indicates format specifier characters that indicate how a value is to be displayed.")] + public string FormatString + { + get { return _FormatString; } + set + { + if (value != _FormatString) + { + string oldValue = _FormatString; + _FormatString = value; + OnFormatStringChanged(oldValue, value); + } + } + } + /// + /// Called when FormatString property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnFormatStringChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("FormatString")); + + } + + private IFormatProvider _FormatInfo = null; + /// + /// Gets or sets the IFormatProvider that provides custom formatting behavior. + /// + [DefaultValue(null), Category("Data"), Description("Indicates IFormatProvider that provides custom formatting behavior.")] + public IFormatProvider FormatInfo + { + get { return _FormatInfo; } + set + { + if (value != _FormatInfo) + { + IFormatProvider oldValue = _FormatInfo; + _FormatInfo = value; + OnFormatInfoChanged(oldValue, value); + } + } + } + /// + /// Called when FormatInfo property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnFormatInfoChanged(IFormatProvider oldValue, IFormatProvider newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("FormatInfo")); + + } + + private object _NullValue = null; + /// + /// Gets or sets the Object to be set as the target property when the data source contains a DBNull value. + /// The data source must contain DBNull for the NullValue property to be correctly applied. + /// If the data source type is a type such as a string or integer the value of the NullValue property will be ignored. + /// Also, the NullValue property is ignored if it is set to null. + /// + [DefaultValue(null), Category("Data"), Description("Indicates Object to be set as the control property when the data source contains a DBNull value. ")] + [System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter))] + public object NullValue + { + get { return _NullValue; } + set + { + if (value != _NullValue) + { + object oldValue = _NullValue; + _NullValue = value; + OnNullValueChanged(oldValue, value); + } + } + } + /// + /// Called when NullValue property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnNullValueChanged(object oldValue, object newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("NullValue")); + } + #endregion + + #region INotifyPropertyChanged Members + /// + /// Raises the PropertyChanged event. + /// + /// Provides event arguments. + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) handler(this, e); + } + /// + /// Occurs when property on BindingDef object has changed. + /// + [Description("Occurs when property on BindingDef object has changed.Occurs when property on BindingDef object has changed.")] + public event PropertyChangedEventHandler PropertyChanged; + + #endregion + } + + /// + /// Represents the method that will handle converting for bindings. + /// + /// + /// + public delegate void DataConvertEventHandler(object sender, DataConvertEventArgs e); + public class DataConvertEventArgs : ConvertEventArgs + { + // Fields + private object _DataItem; + + // Methods + public DataConvertEventArgs(object value, Type desiredType, object dataItem, string fieldName) + : base(value, desiredType) + { + _DataItem = dataItem; + _FieldName = fieldName; + } + + /// + /// Gets the reference to the item being converted. + /// + public object DataItem + { + get + { + return _DataItem; + } + } + + private string _FieldName = ""; + /// + /// Get the reference to the name of the field or property on the item that needs conversion. + /// + public string FieldName + { + get { return _FieldName; } + } + } + + /// + /// Represents BindingDefConverer converter. + /// + public class BindingDefConverer : TypeConverter + { + /// + /// Creates new instance of the class. + /// + public BindingDefConverer() { } + + /// + /// Checks whether conversion can be made to specified type. + /// + /// Context Information. + /// Destination type. + /// + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(InstanceDescriptor)) + return true; + return base.CanConvertTo(context, destinationType); + } + + /// + /// Converts object to specified type. + /// + /// Context information. + /// Culture information. + /// Object to convert. + /// Destination type. + /// Object converted to destination type. + 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 BindingDef)) + { + BindingDef info = (BindingDef)value; + Type[] constructorParams = null; + MemberInfo constructorMemberInfo = null; + object[] constructorValues = null; + + constructorParams = new Type[] { typeof(string), typeof(string) }; + constructorMemberInfo = typeof(BindingDef).GetConstructor(constructorParams); + constructorValues = new object[] { info.PropertyName, info.DataMember }; + + if (constructorMemberInfo != null) + { + return new InstanceDescriptor(constructorMemberInfo, constructorValues); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } +} diff --git a/PROMS/DotNetBar Source Code/BubbleBar.bmp b/PROMS/DotNetBar Source Code/BubbleBar.bmp new file mode 100644 index 00000000..e19d0ac5 Binary files /dev/null and b/PROMS/DotNetBar Source Code/BubbleBar.bmp differ diff --git a/PROMS/DotNetBar Source Code/BubbleBar.cs b/PROMS/DotNetBar Source Code/BubbleBar.cs new file mode 100644 index 00000000..8e9376af --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleBar.cs @@ -0,0 +1,2088 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.UI.ContentManager; +using System.Drawing.Drawing2D; +using System.Drawing.Text; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the toolbar control with the magnifying (bubbling) buttons. + /// + [ToolboxItem(true), DefaultEvent("ButtonClick"), System.Runtime.InteropServices.ComVisible(false), Designer("DevComponents.DotNetBar.Design.BubbleBarDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class BubbleBar : Control, ISupportInitialize, IMessageHandlerClient + { + #region Private Variables + const float _falloffFactor = .3f; + + private System.Windows.Forms.ImageList m_Images; + private System.Windows.Forms.ImageList m_ImagesLarge = null; + private bool m_ShowTooltips = true; + private eOrientation m_Orientation = eOrientation.Horizontal; + private System.Drawing.Size m_ImageSizeLarge = new System.Drawing.Size(48, 48); + private System.Drawing.Size m_ImageSizeNormal = new System.Drawing.Size(24, 24); + private BubbleContentManager m_ContentManager = new BubbleContentManager(); + private BubbleButtonLayoutManager m_ButtonLayoutManager = new BubbleButtonLayoutManager(); + private BubbleButton m_MouseOverButton = null; + private BubbleButton m_MouseDownButton = null; + private int m_AnimationTime = 100; + private BubbleButtonDisplayInfo m_BubbleButtonDisplayInfo = new BubbleButtonDisplayInfo(); + private bool m_AntiAlias = true; + private BubbleBarOverlay m_Overlay = null; + private bool m_Animation = false; + private bool m_AnimationEnabled = true; + private bool m_IgnoreMouseMove = false; + private bool m_EnableOverlay = true; + private eBubbleButtonAlignment m_ButtonAlignment = eBubbleButtonAlignment.Bottom; + private int m_ButtonMargin = 6; + private Font m_TooltipFont = null; + private int m_MagTooltipIncrease = 0; + private Rectangle m_ButtonBounds = Rectangle.Empty; + private BubbleBarTab m_SelectedTab = null; + private BubbleBarTab m_MouseOverTab = null; + private TabColors m_SelectedTabColors = new TabColors(); + private TabColors m_MouseOverTabColors = new TabColors(); + private BubbleBarTabCollection m_Tabs = null; + private bool m_TabsVisible = true; + private Rectangle m_TabsBounds = Rectangle.Empty; + private SimpleTabLayoutManager m_TabLayoutManager = null; + private SimpleTabDisplay m_TabDisplay = null; + private SerialContentLayoutManager m_TabContentManager = null; + private Point m_LastMouseOverPosition = Point.Empty; + private BubbleButton m_IgnoreButtonMouseMove = null; + private ElementStyle m_ButtonBackAreaStyle = new ElementStyle(); + private ElementStyle m_BackgroundStyle = new ElementStyle(); + private bool m_ButtonBackgroundStretch = true; + private bool m_FilterInstalled = false; + private bool m_HasShortcuts = false; + private Color m_TooltipTextColor = Color.White; + private Color m_TooltipOutlineColor = Color.Black; + #endregion + + #region Events + /// + /// Occurs when active tab is about to change. + /// + public event BubbleBarTabChangingEventHadler TabChanging; + /// + /// Occurs when any of the buttons is clicked. Sender object should be casted to BubbleButton to get the button that was actually clicked. + /// + public event ClickEventHandler ButtonClick; + /// + /// Occurs when mouse first enters the control and bubble effect is employed to provide feedback. + /// + public event EventHandler BubbleStart; + /// + /// Occurs when mouse leaves the control and bubble effect is ended. + /// + public event EventHandler BubbleEnd; + #endregion + + #region Constructor + /// + /// Creates new instance of the control. + /// + public BubbleBar() + { + if (!ColorFunctions.ColorsLoaded) + { + NativeFunctions.RefreshSettings(); + NativeFunctions.OnDisplayChange(); + ColorFunctions.LoadColors(); + } + + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + this.SetStyle(ControlStyles.ContainerControl, false); + this.SetStyle(ControlStyles.Selectable, false); + + m_Tabs = new BubbleBarTabCollection(this); + + m_ButtonBackAreaStyle.StyleChanged += new EventHandler(ElementStyleChanged); + m_BackgroundStyle.StyleChanged += new EventHandler(ElementStyleChanged); + + m_ContentManager.BlockSpacing = 0; + m_ContentManager.ContentVerticalAlignment = eContentVerticalAlignment.Bottom; + m_ContentManager.BlockLineAlignment = eContentVerticalAlignment.Bottom; + m_ContentManager.ContentOrientation = eContentOrientation.Horizontal; + + m_TabLayoutManager = new SimpleTabLayoutManager(); + m_TabDisplay = new SimpleTabDisplay(); + m_TabContentManager = new SerialContentLayoutManager(); + + //m_Buttons=new BubbleButtonCollection(this); + m_BubbleButtonDisplayInfo.BubbleBar = this; + // Make sure this is JIT-ed + m_Overlay = new BubbleBarOverlay(this); + m_Overlay = null; + + if (!OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) + m_EnableOverlay = false; + + ApplyButtonAlignment(); + + // m_SelectedTabColors.BorderColor=Color.Black; + // m_MouseOverTabColors.BorderColor=SystemColors.Highlight; + } + #endregion + + #region Public Properties + /// + /// Gets or sets the bubble button tooltip text color. Default value is White color. + /// + [Browsable(true), Category("Appearance"), Description("Indicates bubble button tooltip text color.")] + public Color TooltipTextColor + { + get { return m_TooltipTextColor; } + set { m_TooltipTextColor = value; } + } + /// + /// Indicates whether property should be serialized. Used by the Windows Forms design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTooltipTextColor() + { + return m_TooltipTextColor != Color.White; + } + /// + /// Resets the property to default value. Used by the Windows Forms design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTooltipTextColor() + { + TypeDescriptor.GetProperties(this)["TooltipTextColor"].SetValue(this, Color.White); + } + + /// + /// Gets or sets the bubble button tooltip text outline color. Default value is Black color. + /// + [Browsable(true), Category("Appearance"), Description("Indicates bubble button tooltip text outline color.")] + public Color TooltipOutlineColor + { + get { return m_TooltipOutlineColor; } + set { m_TooltipOutlineColor = value; } + } + /// + /// Indicates whether property should be serialized. Used by the Windows Forms design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTooltipOutlineColor() + { + return m_TooltipOutlineColor != Color.Black; + } + /// + /// Resets the property to default value. Used by the Windows Forms design-time support. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTooltipOutlineColor() + { + TypeDescriptor.GetProperties(this)["TooltipOutlineColor"].SetValue(this, Color.Black); + } + + /// + /// Gets or sets the spacing in pixels between buttons. Default value is 0. + /// + [Browsable(true), DefaultValue(0), Description("Indicates spacing in pixels between buttons."), Category("Appearance")] + public int ButtonSpacing + { + get { return m_ContentManager.BlockSpacing; } + set + { + m_ContentManager.BlockSpacing = value; + this.RecalcLayout(); + this.Refresh(); + } + } + /// + /// Gets or sets whether background for the buttons is stretched to consume complete width of the control. Default value is true. + /// + [Browsable(true), Category("Button Background"), Description("Indicates whether background for the buttons is stretched to consume complete width of the control."), DefaultValue(true)] + public bool ButtonBackgroundStretch + { + get { return m_ButtonBackgroundStretch; } + set + { + if (m_ButtonBackgroundStretch != value) + { + m_ButtonBackgroundStretch = value; + if (this.DesignMode) + this.Refresh(); + } + } + } + + /// + /// Gets the style for the background of the control. + /// + [Browsable(true), Category("Appearance"), Description("Gets the style for the background of the control."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return m_BackgroundStyle; } + } + + /// + /// Gets the style for the background of the buttons. + /// + [Browsable(true), Category("Button Background"), Description("Gets the style for the background of the buttons."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle ButtonBackAreaStyle + { + get { return m_ButtonBackAreaStyle; } + } + + /// + /// Gets the bounds of the buttons back area. + /// + [Browsable(false)] + public Rectangle ButtonBackAreaBounds + { + get { return m_ButtonBounds; } + } + + /// + /// Gets the bounds of the tabs area. + /// + [Browsable(false)] + public Rectangle TabAreaBounds + { + get { return m_TabsBounds; } + } + + /// + /// Gets or sets the duration of animation that is performed when mouse enters a button for the first time or when mouse has left the control. + /// + [Browsable(true), Category("Appearance"), Description("Indicates duration of animatio."), DefaultValue(100)] + public int AnimationTime + { + get { return m_AnimationTime; } + set { m_AnimationTime = value; } + } + + /// + /// Gets or sets whether bubble animation is enabled. Default value is true. + /// + [Browsable(false), Description("Indicates whether animation is enabled."), DefaultValue(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool AnimationEnabled + { + get { return m_AnimationEnabled; } + set + { + m_AnimationEnabled = value; + if (!m_AnimationEnabled) + OverlayInactive(); + } + } + + /// + /// Gets or sets whether anti-alias smoothing is used while painting. + /// + [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public bool AntiAlias + { + get { return m_AntiAlias; } + set + { + if (m_AntiAlias != value) + { + m_AntiAlias = value; + this.Refresh(); + } + } + } + + /// + /// Gets or sets ImageList for images used on buttons. These images will be used as images for the buttons that are not magnified. + /// Use ImagesLarge to specify the magnified images for the coresponding images based on the index in this list. + /// + [Browsable(true), DefaultValue(null), Category("Button Images"), Description("ImageList for images used on buttons.")] + public System.Windows.Forms.ImageList Images + { + get + { + return m_Images; + } + set + { + if (m_Images != null) + m_Images.Disposed -= new EventHandler(this.ImageListDisposed); + m_Images = value; + if (m_Images != null) + m_Images.Disposed += new EventHandler(this.ImageListDisposed); + } + } + + /// + /// Gets or sets ImageList for large-sized images used on buttons when button is magnified. + /// + [Browsable(true), DefaultValue(null), Category("Button Images"), Description("ImageList for large-sized images used on buttons when button is magnified.")] + public System.Windows.Forms.ImageList ImagesLarge + { + get + { + return m_ImagesLarge; + } + set + { + if (m_ImagesLarge != null) + m_ImagesLarge.Disposed -= new EventHandler(this.ImageListDisposed); + m_ImagesLarge = value; + if (m_ImagesLarge != null) + m_ImagesLarge.Disposed += new EventHandler(this.ImageListDisposed); + } + } + + /// + /// Gets or sets whether tooltips are displayed for the buttons. + /// + [Browsable(true), Category("Appearance"), DefaultValue(true), Description("Indicates whether tooltips are displayed for the buttons.")] + public bool ShowTooltips + { + get { return m_ShowTooltips; } + set { m_ShowTooltips = value; } + } + + /// + /// Gets or sets size of the images when button is enlarged, default value is 48 by 48 pixels. Note that you should provide the + /// images in the same size for the buttons through the image properties on the buttons or through ImagesLarge property. + /// If the large images are not provided the regular button image will be automatically enlarged. + /// + [Browsable(true), Category("Button Images"), Description("Indicates size of the images when button is enlarged.")] + public System.Drawing.Size ImageSizeLarge + { + get { return m_ImageSizeLarge; } + set + { + if (m_ImageSizeLarge != value) + { + m_ImageSizeLarge = value; + this.RecalcLayout(); + this.Refresh(); + } + } + } + + /// + /// Returns whether property should be serialized by Windows Forms designer. + /// + /// True if property is different than default value otherwise false. + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeImageSizeLarge() + { + if (m_ImageSizeLarge.Width != 48 || m_ImageSizeLarge.Height != 48) + return true; + return false; + } + + /// + /// Gets or sets the normal image size for the buttons, default value is 24 by 24 pixels. This should be set to the default image size that you will use on the + /// buttons. If the images specified for the buttons are not of the same size as the size specified here then they will + /// be automatically resized. Normal size must always be smaller than the size specified by ImageSizeLarge property. + /// + [Browsable(true), Category("Button Images"), Description("Indicates size of the images when button is enlarged.")] + public System.Drawing.Size ImageSizeNormal + { + get { return m_ImageSizeNormal; } + set + { + if (m_ImageSizeNormal != value) + { + m_ImageSizeNormal = value; + this.RecalcLayout(); + this.Refresh(); + } + } + } + + /// + /// Returns whether property should be serialized by Windows Forms designer. + /// + /// True if property is different than default value otherwise false. + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeImageSizeNormal() + { + if (m_ImageSizeLarge.Width != 24 || m_ImageSizeLarge.Height != 24) + return true; + return false; + } + + /// + /// Gets or sets the font that is used to display tooltips. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + public Font TooltipFont + { + get { return m_TooltipFont; } + set { m_TooltipFont = value; } + } + + /// + /// Gets or sets the selected tab. + /// + [Browsable(false), DefaultValue(null)] + public BubbleBarTab SelectedTab + { + get { return m_SelectedTab; } + set + { + if (m_SelectedTab != value) + { + m_SelectedTab = value; + OnSelectedTabChanged(); + } + } + } + + /// + /// Gets the reference to the colors that are used when tab is selected. + /// + [Browsable(true), Category("Tabs"), Description("Gets the reference to the colors that are used when tab is selected."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TabColors SelectedTabColors + { + get { return m_SelectedTabColors; } + } + + /// + /// Gets the reference to the colors that are used when mouse is over the tab. + /// + [Browsable(true), Category("Tabs"), Description("Gets the reference to the colors that are used when mouse is over the tab."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TabColors MouseOverTabColors + { + get { return m_MouseOverTabColors; } + } + + /// + /// Gets the collection of all tabs. + /// + [Editor("DevComponents.DotNetBar.Design.BubbleBarTabCollectionEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), System.ComponentModel.Category("Tabs"), Description("Returns the collection of Tabs.")] + public BubbleBarTabCollection Tabs + { + get { return m_Tabs; } + } + + /// + /// Gets or sets the button alignment. + /// + [Browsable(true), Category("Appearance"), Description("Indicates button alignment.")] + public eBubbleButtonAlignment Alignment + { + get + { + return m_ButtonAlignment; + } + set + { + if (m_ButtonAlignment != value) + { + m_ButtonAlignment = value; + ApplyButtonAlignment(); + this.RecalcLayout(); + this.Refresh(); + } + } + } + + /// + /// Gets or sets whether tabs are visible. Default value is true. + /// + [Browsable(true), Category("Tabs"), Description("Indicates whether tabs are visible."), DefaultValue(true)] + public bool TabsVisible + { + get { return m_TabsVisible; } + set + { + if (m_TabsVisible != value) + { + m_TabsVisible = value; + this.LayoutButtons(); + this.RepaintAll(); + } + } + } + + #endregion + + #region Public Methods + + /// + /// Recalculates the layout of the control. This method should be called after all changes to the tabs, buttons are completed so + /// layout of the control recalculated. + /// + public void RecalcLayout() + { + this.StopBubbleEffect(); + this.LayoutButtons(); + this.Invalidate(); + OnItemLayoutUpdated(EventArgs.Empty); + } + + /// + /// Occurs after internal item layout has been updated and items have valid bounds assigned. + /// + public event EventHandler ItemLayoutUpdated; + /// + /// Raises ItemLayoutUpdated event. + /// + /// Provides event arguments. + protected virtual void OnItemLayoutUpdated(EventArgs e) + { + EventHandler handler = ItemLayoutUpdated; + if (handler != null) + handler(this, e); + } + + /// + /// Returns reference to the button at specified location + /// + /// x - coordinate + /// y - coordinate + /// Reference to the button or null if no button could be found at given coordinates. + public BubbleButton GetButtonAt(int x, int y) + { + if (m_SelectedTab == null) + return null; + BubbleButton ret = null; + foreach (BubbleButton button in m_SelectedTab.Buttons) + { + if (!button.Visible) continue; + if (m_MouseOverButton != null) + { + Rectangle r = button.MagnifiedDisplayRectangle; + if (r.Contains(x, y)) + { + ret = button; + break; + } + } + else + { + Rectangle r = button.DisplayRectangle; + if (r.Contains(x, y)) + { + ret = button; + break; + } + } + } + return ret; + } + + /// + /// Returns reference to the button at specified location + /// + /// Location coordinates + /// Reference to the button or null if no button could be found at given coordinates. + public BubbleButton GetButtonAt(Point p) + { + return GetButtonAt(p.X, p.Y); + } + + /// + /// Returns tab at specific location. + /// + /// Coordinates to get the tab from. + /// Reference to the tab object or null if tab cannot be found at specified location + public BubbleBarTab GetTabAt(Point p) + { + return GetTabAt(p.X, p.Y); + } + + /// + /// Returns tab at specific location. + /// + /// x - coordinate + /// y - coordinate + /// Reference to the tab object or null if tab cannot be found at specified location + public BubbleBarTab GetTabAt(int x, int y) + { + foreach (BubbleBarTab tab in m_Tabs) + { + if (tab.DisplayRectangle.Contains(x, y)) + return tab; + } + return null; + } + + #endregion + + #region Internal Implementation + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + if (Dpi.RecordScalePerControl) + Dpi.SetScaling(factor); + base.ScaleControl(factor, specified); + } + + protected override void OnCursorChanged(EventArgs e) + { + if (m_Overlay != null) + m_Overlay.Cursor = this.Cursor; + base.OnCursorChanged(e); + } + /// + /// Invokes BubbleStart event. + /// + protected virtual void OnBubbleStart(EventArgs e) + { + if (BubbleStart != null) + BubbleStart(this, e); + } + + /// + /// Invokes BubbleEnd event. + /// + protected virtual void OnBubbleEnd(EventArgs e) + { + if (BubbleEnd != null) + BubbleEnd(this, e); + } + /// + /// Invokes ButtonClick event on the control. + /// + /// Reference to the button that was clicked. + internal void InvokeButtonClick(BubbleButton button, ClickEventArgs e) + { + if (ButtonClick != null) + ButtonClick(button, e); + } + protected override bool ProcessMnemonic(char charCode) + { + string s = "&" + charCode.ToString(); + s = s.ToLower(); + foreach (BubbleBarTab tab in this.Tabs) + { + string text = tab.Text.ToLower(); + if (text.IndexOf(s) >= 0) + { + this.SelectedTab = tab; + return true; + } + } + return base.ProcessMnemonic(charCode); + } + + protected override void OnSystemColorsChanged(EventArgs e) + { + base.OnSystemColorsChanged(e); + Application.DoEvents(); + if (m_ButtonBackAreaStyle.GetColorScheme() != null) + m_ButtonBackAreaStyle.GetColorScheme().Refresh(); + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + + if (this.Width == 0 || this.Height == 0) + return; + + this.RecalcLayout(); + this.Refresh(); + } + + private void RepaintAll() + { + if (m_Overlay != null) + { + m_Overlay.UpdateWindow(); + // m_Overlay.Parent.Invalidate(m_Overlay.Bounds,true); + // m_Overlay.Parent.Update(); + // m_Overlay.Update(); + //m_Overlay.Refresh(); + this.Refresh(); + } + else + this.Refresh(); + } + + private void ElementStyleChanged(object sender, EventArgs e) + { + if (this.DesignMode) + { + this.LayoutButtons(); + this.Refresh(); + } + } + + protected override void OnPaint(PaintEventArgs e) + { + PaintBackground(e); + PaintControl(e); + } + + protected virtual void PaintControl(PaintEventArgs e) + { + ElementStyleDisplayInfo info = new ElementStyleDisplayInfo(); + info.Bounds = this.DisplayRectangle; + info.Graphics = e.Graphics; + info.Style = m_BackgroundStyle; + ElementStyleDisplay.Paint(info); + + if (!m_ButtonBounds.IsEmpty && this.Tabs.Count > 0) + { + Rectangle r = GetButtonsBackground(); + info.Bounds = r; + info.Graphics = e.Graphics; + info.Style = m_ButtonBackAreaStyle; + ElementStyleDisplay.Paint(info); + } + + SmoothingMode sm = e.Graphics.SmoothingMode; + TextRenderingHint th = e.Graphics.TextRenderingHint; + + if (m_AntiAlias) + { + e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + e.Graphics.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + if (!m_TabsBounds.IsEmpty) + { + Rectangle r = GetTabBounds(); + e.Graphics.SetClip(r); + ISimpleTab[] tabs = new ISimpleTab[m_Tabs.Count]; + m_Tabs.CopyTo(tabs); + m_TabDisplay.Paint(e.Graphics, tabs); + e.Graphics.ResetClip(); + } + + if (m_Overlay == null) + { + BubbleButtonDisplayInfo displayInfo = GetBubbleButtonDisplayInfo(); + displayInfo.Graphics = e.Graphics; + + if (m_SelectedTab != null) + { + foreach (BubbleButton button in m_SelectedTab.Buttons) + { + displayInfo.Button = button; + BubbleButtonDisplay.Paint(displayInfo); + } + } + } + + if (this.DesignMode && this.Tabs.Count == 0) + { + Rectangle r = this.DisplayRectangle; + eTextFormat format = eTextFormat.Default | eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter | + eTextFormat.EndEllipsis | eTextFormat.WordBreak; + string INFO_TEXT = "Right-click and choose Create Tab or Button to add new items."; + TextDrawing.DrawString(e.Graphics, INFO_TEXT, this.Font, SystemColors.ControlDarkDark, r, format); + } + +#if !TRIAL + if (NativeFunctions.keyValidated2 != 266) + TextDrawing.DrawString(e.Graphics, "Invalid License", this.Font, Color.FromArgb(128, Color.Red), this.ClientRectangle, eTextFormat.Bottom | eTextFormat.HorizontalCenter); +#endif + e.Graphics.TextRenderingHint = th; + e.Graphics.SmoothingMode = sm; + } + + protected virtual void PaintBackground(PaintEventArgs e) + { + if (this.BackColor.A < 255) + { + base.OnPaintBackground(e); + } + + if (!this.BackColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(this.BackColor)) + e.Graphics.FillRectangle(brush, this.DisplayRectangle); + } + } + + internal void OnPaintOverlay(PaintEventArgs e) + { + BubbleButtonDisplayInfo displayInfo = GetBubbleButtonDisplayInfo(); + displayInfo.Graphics = e.Graphics; + + if (m_SelectedTab != null) + { + foreach (BubbleButton button in m_SelectedTab.Buttons) + { + displayInfo.Button = button; + BubbleButtonDisplay.Paint(displayInfo); + } + } + } + + private bool IsParentFormActive() + { + Form form = this.FindForm(); + if (form != null && form.MdiParent == null && form.Parent is Control) + { + form = form.Parent.FindForm(); + } + + if (form != null) + { + return (Form.ActiveForm == form && form.MdiParent == null || + form.MdiParent != null && form.MdiParent.ActiveMdiChild == form); + } + + bool ret = false; + IntPtr foregroundWindow = NativeFunctions.GetForegroundWindow(); + try + { + Control c = Control.FromHandle(foregroundWindow); + if (c != null) + ret = true; + } + catch + { + ret = false; + } + return ret; + } + + private void CreateOverlay() + { + if (m_Overlay == null) + { + OnBubbleStart(new EventArgs()); + } + + if (m_Overlay != null || this.Parent == null || !m_EnableOverlay || this.DesignMode || !m_AnimationEnabled) + return; + + Rectangle overlayBounds = this.GetOverlayBounds(); + m_Overlay = new BubbleBarOverlay(this); + m_Overlay.Bounds = overlayBounds; + m_Overlay.Visible = false; + + // Layout buttons for overlay + m_ContentManager.MouseOverIndex = -1; + this.LayoutButtons(); + if (m_MouseOverButton != null) + m_ContentManager.MouseOverIndex = m_MouseOverButton.Parent.Buttons.IndexOf(m_MouseOverButton); + + m_Overlay.CreateControl(); + Point p = this.Parent.PointToScreen(m_Overlay.Location); + m_Overlay.BeforeShow(); + int hwndInsertAfter = NativeFunctions.HWND_NOTOPMOST; + if (this.FindForm() != null && this.FindForm().TopMost) + hwndInsertAfter = NativeFunctions.HWND_TOPMOST; + NativeFunctions.SetWindowPos(m_Overlay.Handle, new IntPtr(hwndInsertAfter), p.X, p.Y, m_Overlay.Width, m_Overlay.Height, NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); + m_Overlay.Visible = true; + m_Overlay.UpdateWindow(); + this.Refresh(); + } + + private Rectangle GetOverlayBounds() + { + Rectangle r = new Rectangle(this.Location, this.Size); + if (m_ButtonAlignment == eBubbleButtonAlignment.Top || m_ButtonAlignment == eBubbleButtonAlignment.Bottom) + { + Size imageSizeLarge = Dpi.ImageSize(m_ImageSizeLarge); + Size imageSizeNormal = Dpi.ImageSize(m_ImageSizeNormal); + int increase = (imageSizeLarge.Height - imageSizeNormal.Height); + if (this.ShowTooltips) + { + if (this.TooltipFont != null) + m_MagTooltipIncrease = this.TooltipFont.Height + 6; + else + m_MagTooltipIncrease = this.Font.Height + 6; + + increase += m_MagTooltipIncrease; + } + r.Height += increase; + if (m_ButtonAlignment == eBubbleButtonAlignment.Bottom) + r.Y -= increase; + } + else + { + + } + return r; + } + + /// + /// Called after overlay window became inactive. + /// + internal void OverlayInactive() + { + SetMouseDown(null); + // Mouse Over destroys overlay window as well + SetMouseOver(null); + this.RepaintAll(); + } + + /// + /// Stops the bubble animation effect is one is applied currently. + /// + public void StopBubbleEffect() + { + SetMouseDown(null); + SetMouseOver(null); + } + + private void DestroyOverlay() + { + if (m_Overlay == null) + return; + + OnBubbleEnd(new EventArgs()); + + m_Overlay.Hide(); + m_Overlay.AfterClose(); + m_Overlay.Dispose(); + m_Overlay = null; + + // Layout buttons without overlay + m_ContentManager.MouseOverIndex = -1; + this.LayoutButtons(); + if (m_MouseOverButton != null) + m_ContentManager.MouseOverIndex = m_MouseOverButton.Parent.Buttons.IndexOf(m_MouseOverButton); + this.Invalidate(); + } + + private BubbleButtonDisplayInfo GetBubbleButtonDisplayInfo() + { + m_BubbleButtonDisplayInfo.Magnified = (m_MouseOverButton != null) && m_AnimationEnabled; + m_BubbleButtonDisplayInfo.Alignment = m_ButtonAlignment; + return m_BubbleButtonDisplayInfo; + } + + + protected override void OnMouseMove(MouseEventArgs e) + { + if (!IsParentFormActive()) + return; + if (m_Overlay != null && m_MagTooltipIncrease > 0) + { + Point p = this.PointToScreen(new Point(e.X, e.Y)); + p = m_Overlay.PointToClient(p); + MouseEventArgs em = new MouseEventArgs(e.Button, e.Clicks, p.X, p.Y, e.Delta); + MouseMoveMessage(em); + } + else + MouseMoveMessage(e); + } + + /// + /// Internal processing of MouseMove event. + /// + /// Move move event arguments. + internal void MouseMoveMessage(MouseEventArgs e) + { + base.OnMouseMove(e); + if (m_IgnoreMouseMove) + { + m_IgnoreMouseMove = false; + return; + } + + bool bRefresh = false; + + Point mousePosition = new Point(e.X, e.Y); + BubbleButton mouseOver = GetButtonAt(mousePosition.X, mousePosition.Y); + if (mouseOver != null && mouseOver == m_IgnoreButtonMouseMove) + return; + else if (mouseOver == null) + m_IgnoreButtonMouseMove = null; + + if (mouseOver != null) + { + if (m_MouseOverButton == null) + { + CreateOverlay(); + // Set to enable painting of magnified buttons... + m_MouseOverButton = mouseOver; + AnimateButton(mouseOver, mousePosition, true); + m_MouseOverButton = null; + } + + if (m_AnimationEnabled) + { + BubbleFactors factors = this.GetBubbleFactors(mouseOver.DisplayRectangle, mousePosition); + m_ContentManager.Factor1 = factors.Factor1; + m_ContentManager.Factor2 = factors.Factor2; + m_ContentManager.Factor3 = factors.Factor3; + m_ContentManager.Factor4 = factors.Factor4; + Size imageSizeLarge = Dpi.ImageSize(m_ImageSizeLarge); + m_ContentManager.BubbleSize = imageSizeLarge; + m_ContentManager.MouseOverPosition = factors.x; + m_ContentManager.MouseOverIndex = mouseOver.Parent.Buttons.IndexOf(mouseOver); + this.LayoutButtons(); + bRefresh = true; + m_LastMouseOverPosition = mousePosition; + } + } + + if (m_MouseOverTab != null || m_TabsBounds.Contains(mousePosition)) + { + BubbleBarTab tab = GetTabAt(mousePosition); + SetMouseOverTab(tab); + } + + if (m_MouseOverButton != mouseOver) + { + SetMouseOver(mouseOver); + bRefresh |= true; + } + + if (m_MouseOverButton != mouseOver && e.Button == MouseButtons.Left) + { + SetMouseDown(mouseOver); + bRefresh |= true; + } + + // Make sure that cursor did not escape while animation was going on... + if (m_MouseOverButton != null) + { + Point p = Control.MousePosition; + if (m_Overlay != null) + p = m_Overlay.PointToClient(p); + else + p = this.PointToClient(p); + mouseOver = GetButtonAt(p.X, p.Y); + if (mouseOver != m_MouseOverButton) + { + SetMouseOver(mouseOver); + bRefresh |= true; + } + } + + if (bRefresh) + this.RepaintAll(); + } + + private void SetMouseOver(BubbleButton mouseOver) + { + if (m_MouseOverButton != null) + { + m_MouseOverButton.SetMouseOver(false); + if (mouseOver == null && !m_LastMouseOverPosition.IsEmpty) + { + AnimateButton(m_MouseOverButton, m_LastMouseOverPosition, false); + m_LastMouseOverPosition = Point.Empty; + } + } + + m_MouseOverButton = mouseOver; + if (m_MouseOverButton != null) + { + m_MouseOverButton.SetMouseOver(true); + CreateOverlay(); + } + else + { + SetMouseDown(null); + DestroyOverlay(); + } + if (m_MouseOverButton != null) + m_ContentManager.MouseOverIndex = m_MouseOverButton.Parent.Buttons.IndexOf(m_MouseOverButton); + else + m_ContentManager.MouseOverIndex = -1; + } + + private void SetMouseDown(BubbleButton mouseDown) + { + if (m_MouseDownButton != null) + m_MouseDownButton.SetMouseDown(false); + + if (mouseDown != null && !mouseDown.Enabled) + { + m_MouseDownButton = null; + return; + } + + m_MouseDownButton = mouseDown; + if (m_MouseDownButton != null) + m_MouseDownButton.SetMouseDown(true); + } + + protected override void OnMouseEnter(EventArgs e) + { + StopMouseLeaveTimer(); + base.OnMouseEnter(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + MouseLeaveMessage(e); + base.OnMouseLeave(e); + } + + /// + /// Internal processing for MouseLeave event. + /// + /// Event arguments + internal void MouseLeaveMessage(EventArgs e) + { + Point p = Point.Empty; + if (m_MouseOverButton != null && m_Overlay != null) + p = m_Overlay.PointToClient(Control.MousePosition); + else + p = this.PointToClient(Control.MousePosition); + + bool bRepaint = false; + BubbleButton buttonAt = GetButtonAt(p.X, p.Y); + + if (m_MouseDownButton != null && buttonAt == null) + { + SetMouseDown(null); + bRepaint = true; + } + + SetMouseOverTab(null); + + if (bRepaint) + this.RepaintAll(); + StartMouseLeaveTimer(); + m_IgnoreButtonMouseMove = null; + } + + private Timer m_MouseLeaveTimer = null; + private void StartMouseLeaveTimer() + { + if (m_Overlay == null || m_MouseOverButton == null || m_MouseLeaveTimer != null) return; + + m_MouseLeaveTimer = new Timer(); + m_MouseLeaveTimer.Interval = 500; + m_MouseLeaveTimer.Tick += new EventHandler(MouseLeaveTimerTick); + m_MouseLeaveTimer.Start(); + } + + private void MouseLeaveTimerTick(object sender, EventArgs e) + { + Point p = Point.Empty; + if (m_MouseOverButton != null && m_Overlay != null) + p = m_Overlay.PointToClient(Control.MousePosition); + else + p = this.PointToClient(Control.MousePosition); + + bool bRepaint = false; + BubbleButton buttonAt = GetButtonAt(p.X, p.Y); + + if (buttonAt == null) + { + StopBubbleEffect(); + StopMouseLeaveTimer(); + } + } + + private void StopMouseLeaveTimer() + { + Timer t = m_MouseLeaveTimer; + m_MouseLeaveTimer = null; + if (t == null) return; + t.Stop(); + t.Dispose(); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + MouseDownMessage(e); + base.OnMouseDown(e); + } + + internal void OverlayMouseDownMessage(MouseEventArgs e) + { + OnMouseDown(e); + } + + private void MouseDownMessage(MouseEventArgs e) + { + BubbleButton mouseOver = GetButtonAt(e.X, e.Y); + if (mouseOver != null) + { + SetMouseDown(mouseOver); + this.RepaintAll(); + } + else if (m_TabsBounds.Contains(e.X, e.Y)) + { + BubbleBarTab tab = GetTabAt(new Point(e.X, e.Y)); + if (tab != null && tab != m_SelectedTab) + SetSelectedTab(tab, eEventSource.Mouse, true); + } + } + + protected override void OnMouseUp(MouseEventArgs e) + { + MouseUpMessage(e); + base.OnMouseUp(e); + } + + internal void OverlayMouseUpMessage(MouseEventArgs e) + { + OnMouseUp(e); + } + + private void MouseUpMessage(MouseEventArgs e) + { + if (m_MouseDownButton != null) + { + BubbleButton button = m_MouseDownButton; + Rectangle dispRect = button.DisplayRectangle; + Rectangle magRect = button.MagnifiedDisplayRectangle; + SetMouseDown(null); + SetMouseOver(null); + m_IgnoreMouseMove = true; + this.RepaintAll(); + if (dispRect.Contains(e.X, e.Y) || magRect.Contains(e.X, e.Y)) + button.InvokeClick(eEventSource.Mouse, e.Button); + m_IgnoreButtonMouseMove = button; + } + } + + private void ImageListDisposed(object sender, EventArgs e) + { + if (sender == m_Images) + { + this.Images = null; + } + else if (sender == m_ImagesLarge) + { + this.ImagesLarge = null; + } + } + + /// + /// Called after all buttons have been removed. + /// + /// Tab from which all buttons were removed. + internal void OnButtonsCollectionClear(BubbleBarTab tab) + { + StopBubbleEffect(); + if (this.DesignMode) + { + this.RecalcLayout(); + this.Refresh(); + } + } + + /// + /// Called after specified button has been removed. + /// + /// Tab from which button was removed. + /// Button that was removed. + internal void OnButtonRemoved(BubbleBarTab tab, BubbleButton button) + { + StopBubbleEffect(); + if (m_HasShortcuts && !this.IsDisposed) + RefreshHasShortcut(); + if (this.DesignMode) + { + this.RecalcLayout(); + this.Refresh(); + } + } + + internal void RefreshHasShortcut() + { + m_HasShortcuts = false; + foreach (BubbleBarTab t in this.Tabs) + { + foreach (BubbleButton b in t.Buttons) + { + if (b.Shortcut != eShortcut.None) + { + m_HasShortcuts = true; + break; + } + } + if (m_HasShortcuts) + break; + } + } + + /// + /// Called after new button is added to the Buttons collection. + /// + /// Tab to which button was added. + /// Reference to the button added. + internal void OnButtonInserted(BubbleBarTab tab, BubbleButton button) + { + StopBubbleEffect(); + LayoutButtons(); + if (button.Shortcut != eShortcut.None) + { + m_HasShortcuts = true; + } + if (this.DesignMode) + { + this.RecalcLayout(); + this.Refresh(); + } + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + this.RecalcLayout(); + InstallIMessageHandlerClient(); + } + + protected override void OnHandleDestroyed(EventArgs e) + { + base.OnHandleDestroyed(e); + UninstallIMessageHandlerClient(); + StopMouseLeaveTimer(); + } + + /// + /// Called when Visible property of Button has changed. + /// + /// Button affected. + internal void OnButtonVisibleChanged(BubbleButton button) + { + LayoutButtons(); + } + + private void LayoutButtons() + { + if (m_SelectedTab != null) + { + if (m_SelectedTab.Buttons.Count > 0) + { + IBlock[] buttons = new IBlock[m_SelectedTab.Buttons.Count]; + m_SelectedTab.Buttons.CopyTo(buttons); + Rectangle r = m_ContentManager.Layout(GetButtonDisplayArea(), buttons, m_ButtonLayoutManager); + if (m_Overlay != null) + { + m_ButtonBounds.X = r.X; + m_ButtonBounds.Width = r.Width; + } + else + m_ButtonBounds = r; + } + else + { + m_ButtonBounds = GetButtonDisplayArea(); + m_ButtonBounds.Inflate(-m_ButtonBounds.Width / 2, 0); + int b = m_ButtonBounds.Bottom; + Size imageSizeNormal = Dpi.ImageSize(m_ImageSizeNormal); + m_ButtonBounds.Height = imageSizeNormal.Height; + if (m_ButtonAlignment == eBubbleButtonAlignment.Bottom) + m_ButtonBounds.Y = b - m_ButtonBounds.Height; + } + } + + LayoutTabs(); + } + + private void LayoutTabs() + { + if (!BarFunctions.IsHandleValid(this)) + return; + // Layout tabs + if (m_TabsVisible && m_Tabs.Count > 0) + { + IBlock[] tabs = new IBlock[m_Tabs.Count]; + m_Tabs.CopyTo(tabs); + Graphics g = null; + try + { + g = this.CreateGraphics(); + m_TabLayoutManager.Graphics = g; + m_TabsBounds = m_TabContentManager.Layout(GetTabDisplayArea(), tabs, m_TabLayoutManager); + } + finally + { + m_TabLayoutManager.Graphics = null; + if (g != null) + g.Dispose(); + } + } + else + m_TabsBounds = Rectangle.Empty; + } + + private Rectangle GetButtonDisplayArea() + { + Rectangle r = this.DisplayRectangle; + if (m_Overlay != null) + r = m_Overlay.DisplayRectangle; + if (m_ButtonAlignment == eBubbleButtonAlignment.Bottom) + r.Height -= m_ButtonMargin; + else if (m_ButtonAlignment == eBubbleButtonAlignment.Top) + { + r.Height -= m_ButtonMargin; + r.Y += m_ButtonMargin; + } + + return r; + } + + /// + /// Returns the button background rectangle for display purposes. Applies setting for the ButtonBackgroundStretch property. + /// + /// Background rectangle. + private Rectangle GetButtonsBackground() + { + Rectangle r = m_ButtonBounds; + if (m_ButtonBackgroundStretch) + { + r.Width = this.Width; + r.X = 0; + } + else if (m_TabsBounds.Width + 16 > r.Width) + { + int diff = (m_TabsBounds.Width + 16) - r.Width; + r.Width += diff; + r.X -= diff / 2; + } + + r.Height += (m_ButtonBackAreaStyle.PaddingTop + m_ButtonBackAreaStyle.PaddingBottom); + r.Y -= m_ButtonBackAreaStyle.PaddingTop; + + if (!m_ButtonBackgroundStretch) + { + r.Width += (m_ButtonBackAreaStyle.PaddingLeft + m_ButtonBackAreaStyle.PaddingRight); + r.X -= m_ButtonBackAreaStyle.PaddingLeft; + } + + return r; + } + + private Rectangle GetTabDisplayArea() + { + Rectangle r; + Rectangle rButtonsBack = GetButtonsBackground(); + + if (m_ButtonAlignment == eBubbleButtonAlignment.Bottom) + { + r = new Rectangle(rButtonsBack.X, 0, rButtonsBack.Width, rButtonsBack.Y); + } + else + { + r = new Rectangle(rButtonsBack.X, rButtonsBack.Bottom, rButtonsBack.Width, this.Height - rButtonsBack.Bottom); + } + if (r.Height < 0) + r.Height = 0; + + r.Width -= 16; + r.X += 8; + return r; + } + + private Rectangle GetTabBounds() + { + Rectangle r = m_TabsBounds; + if (!r.IsEmpty) + { + r.Width += 16; + r.X -= 8; + } + return r; + } + + private void AnimateButton(BubbleButton button, Point mousePosition, bool animateGrow) + { + if (m_AnimationTime <= 0 || m_Animation || m_SelectedTab == null || !m_AnimationEnabled) + return; + + m_Animation = true; + try + { + m_ContentManager.MouseOverIndex = m_SelectedTab.Buttons.IndexOf(button); + bool animate = true; + Size imageSizeLarge = Dpi.ImageSize(m_ImageSizeLarge); + Size imageSizeNormal = Dpi.ImageSize(m_ImageSizeNormal); + int totalSteps = imageSizeLarge.Width - imageSizeNormal.Width; + int step = 1; + int current = imageSizeNormal.Width + step; + if (!animateGrow) + current = imageSizeLarge.Width - step; + + Rectangle displayRectangle = GetButtonDisplayArea(); + + IBlock[] blocks = new IBlock[m_SelectedTab.Buttons.Count]; + m_SelectedTab.Buttons.CopyTo(blocks); + + DateTime start = DateTime.Now; + TimeSpan stepDuration = TimeSpan.MinValue; + + while (animate) + { + DateTime stepStart = DateTime.Now; + + float multi = (float)current / (float)imageSizeNormal.Width; + Size bubbleSize = new Size((int)((float)imageSizeNormal.Width * multi), (int)((float)imageSizeNormal.Height * multi)); + BubbleFactors factors = this.GetBubbleFactors(button.DisplayRectangle, mousePosition, bubbleSize); + m_ContentManager.Factor1 = factors.Factor1; + m_ContentManager.Factor2 = factors.Factor2; + m_ContentManager.Factor3 = factors.Factor3; + m_ContentManager.Factor4 = factors.Factor4; + m_ContentManager.BubbleSize = bubbleSize; + m_ContentManager.MouseOverPosition = factors.x; + m_ContentManager.Layout(displayRectangle, blocks, m_ButtonLayoutManager); + this.RepaintAll(); + + stepDuration = DateTime.Now.Subtract(stepStart); + step = (int)((float)totalSteps * ((float)stepDuration.TotalMilliseconds / (float)m_AnimationTime)); + if (step <= 0) + { + int diff = (int)(m_AnimationTime / Math.Max((float)stepDuration.TotalMilliseconds, (float)1) / totalSteps); + if (diff <= 0) + diff = (int)stepDuration.TotalMilliseconds; + try + { + using ( + System.Threading.ManualResetEvent wait = + new System.Threading.ManualResetEvent(false)) + wait.WaitOne(diff); + //System.Threading.Thread.Sleep(diff); + } + catch + { + break; + } + step = 1; + } + if (animateGrow) + current += step; + else + current -= step; + totalSteps -= step; + if (totalSteps <= 0 || DateTime.Now.Subtract(start).TotalMilliseconds >= m_AnimationTime) + break; + } + } + finally + { + m_Animation = false; + } + } + + private BubbleFactors GetBubbleFactors(Rectangle buttonMouseOver, Point mousePosition) + { + return GetBubbleFactors(buttonMouseOver, mousePosition, Dpi.ImageSize(m_ImageSizeLarge)); + } + + private BubbleFactors GetBubbleFactors(Rectangle buttonMouseOver, Point mousePosition, Size finalSize) + { + BubbleFactors factors = new BubbleFactors(); + + float pp = 0; + int xa = 0, ya = 0; + int xDiff = Math.Max(mousePosition.X - buttonMouseOver.X, 0); + xDiff = Math.Min(xDiff, buttonMouseOver.Width); + int yDiff = Math.Max(mousePosition.Y - buttonMouseOver.Y, 0); + yDiff = Math.Min(yDiff, buttonMouseOver.Height); + + if (m_Orientation == eOrientation.Horizontal) + { + pp = (float)(xDiff) / (float)buttonMouseOver.Width; + xa = mousePosition.X - (int)(pp * (float)finalSize.Width); + } + else + { + pp = (float)(yDiff) / (float)buttonMouseOver.Height; + ya = mousePosition.Y - (int)(pp * (float)finalSize.Height); + } + + factors.x = xa; + factors.y = ya; + + factors.Factor1 = (1 - pp) * _falloffFactor; + factors.Factor2 = Math.Max(1 - pp, _falloffFactor); + factors.Factor3 = Math.Max(pp, _falloffFactor); + factors.Factor4 = pp * _falloffFactor; + + return factors; + } + + private class BubbleFactors + { + public int x = 0; + public int y = 0; + public float Factor1 = 0; + public float Factor2 = 0; + public float Factor3 = 0; + public float Factor4 = 0; + } + + private void ApplyButtonAlignment() + { + m_TabContentManager.BlockSpacing = 8; + + if (m_ButtonAlignment == eBubbleButtonAlignment.Bottom) + { + m_ContentManager.ContentAlignment = eContentAlignment.Center; + m_ContentManager.ContentVerticalAlignment = eContentVerticalAlignment.Bottom; + m_ContentManager.BlockLineAlignment = eContentVerticalAlignment.Bottom; + m_ContentManager.ContentOrientation = eContentOrientation.Horizontal; + + m_TabContentManager.ContentAlignment = eContentAlignment.Center; + m_TabContentManager.ContentVerticalAlignment = eContentVerticalAlignment.Bottom; + m_TabContentManager.BlockLineAlignment = eContentVerticalAlignment.Bottom; + m_TabContentManager.ContentOrientation = eContentOrientation.Horizontal; + } + else if (m_ButtonAlignment == eBubbleButtonAlignment.Top) + { + m_ContentManager.ContentAlignment = eContentAlignment.Center; + m_ContentManager.ContentVerticalAlignment = eContentVerticalAlignment.Top; + m_ContentManager.BlockLineAlignment = eContentVerticalAlignment.Top; + m_ContentManager.ContentOrientation = eContentOrientation.Horizontal; + + m_TabContentManager.ContentAlignment = eContentAlignment.Center; + m_TabContentManager.ContentVerticalAlignment = eContentVerticalAlignment.Top; + m_TabContentManager.BlockLineAlignment = eContentVerticalAlignment.Top; + m_TabContentManager.ContentOrientation = eContentOrientation.Horizontal; + } + // else if(m_ButtonAlignment==eBubbleButtonAlignment.Left) + // { + // m_ContentManager.ContentAlignment=eContentAlignment.Center; + // m_ContentManager.ContentVerticalAlignment=eContentVerticalAlignment.Bottom; + // m_ContentManager.ContentOrientation=eContentOrientation.Horizontal; + // } + } + #endregion + + #region Tabs Support + /// + /// Called after tab has been removed from the collection. + /// + /// Tab that was removed. + internal void OnTabRemoved(BubbleBarTab tab) + { + if (m_SelectedTab == tab) + { + SelectNextVisible(tab, eEventSource.Code, false); + } + if (this.DesignMode) + { + this.RecalcLayout(); + this.Refresh(); + } + } + + /// + /// Called after tab has been added to the collection. + /// + /// Newly added tab. + internal void OnTabAdded(BubbleBarTab tab) + { + if (m_SelectedTab == null) + m_SelectedTab = tab; + this.LayoutButtons(); + if (this.DesignMode) + { + this.RecalcLayout(); + this.Refresh(); + } + } + + /// + /// Called after all tabs are removed from the collection. + /// + internal void OnTabsCleared() + { + m_SelectedTab = null; + this.LayoutButtons(); + if (this.DesignMode) + { + this.RecalcLayout(); + this.Refresh(); + } + } + + /// + /// Called after text of a tab has changed. + /// + /// Tab which text has changed. + internal void OnTabTextChanged(BubbleBarTab tab) + { + this.RecalcLayout(); + this.Refresh(); + } + + /// + /// Called after Visible property of the tab has changed. + /// + /// Tab affected. + internal void OnTabVisibleChanged(BubbleBarTab tab) + { + if (m_SelectedTab == tab) + { + SelectNextVisible(tab, eEventSource.Code, false); + } + this.LayoutButtons(); + this.Refresh(); + } + + private void OnSelectedTabChanged() + { + StopBubbleEffect(); + m_IgnoreButtonMouseMove = null; + LayoutButtons(); + this.Refresh(); + } + + internal BubbleBarTab GetMouseOverTab() + { + return m_MouseOverTab; + } + + private void SelectNextVisible(BubbleBarTab reference, eEventSource source, bool bCanCancel) + { + BubbleBarTab sel = m_Tabs.GetNextVisibleTab(reference); + if (sel == null) + sel = m_Tabs.GetPreviousVisibleTab(reference); + SetSelectedTab(sel, source, bCanCancel); + } + + private void SetSelectedTab(BubbleBarTab tab, eEventSource source, bool bCanCancel) + { + if (TabChanging != null) + { + BubbleBarTabChangingEventArgs e = new BubbleBarTabChangingEventArgs(); + e.CurrentTab = m_SelectedTab; + e.NewTab = tab; + e.Source = source; + TabChanging(this, e); + if (e.Cancel && bCanCancel) return; + } + m_SelectedTab = tab; + m_IgnoreButtonMouseMove = null; + this.LayoutButtons(); + this.RepaintAll(); + } + + /// + /// Sets the tab mouse is placed over. + /// + /// Tab that mouse is currently over or null if mouse is not over any tab. + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetMouseOverTab(BubbleBarTab tab) + { + if (m_MouseOverTab == tab) + return; + + m_MouseOverTab = tab; + + this.Invalidate(GetTabBounds()); + this.Update(); + } + #endregion + + #region Drag & Drop support + private BubbleBarTab m_DragTab = null; + private int m_DragTabOriginalIndex = -1; + private int m_DragButtonOriginalIndex = -1; + private BubbleButton m_DragButton = null; + private bool m_DragInProgress = false; + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool DragInProgress + { + get { return m_DragInProgress; } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void StartDrag(BubbleBarTab tab) + { + if (m_DragInProgress) + return; + + m_DragInProgress = true; + m_DragTab = tab; + Cursor.Current = Cursors.Hand; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void StartDrag(BubbleButton button) + { + if (m_DragInProgress) + return; + + m_DragInProgress = true; + m_DragButton = button; + Cursor.Current = Cursors.Hand; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void DragMouseMove(Point mousePosition) + { + if (m_DragTab != null) + { + BubbleBarTab tab = GetTabAt(mousePosition); + if (tab != null && tab != m_DragTab) + { + if (m_DragTabOriginalIndex == -1) + m_DragTabOriginalIndex = this.Tabs.IndexOf(m_DragTab); + int insertPos = this.Tabs.IndexOf(tab); + this.Tabs.Remove(m_DragTab); + this.Tabs.Insert(insertPos, m_DragTab); + this.SelectedTab = m_DragTab; + } + } + else if (m_DragButton != null) + { + BubbleBarTab tab = GetTabAt(mousePosition); + if (tab != null && tab != m_DragButton.Parent) + { + // Move button to the tab and select that tab + if (m_DragTabOriginalIndex == -1) + m_DragTabOriginalIndex = this.Tabs.IndexOf(m_DragButton.Parent); + if (m_DragButtonOriginalIndex == -1) + m_DragButtonOriginalIndex = m_DragButton.Parent.Buttons.IndexOf(m_DragButton); + this.SelectedTab = tab; + BubbleButton b = GetButtonAt(mousePosition); + if (m_DragButton.Parent != null) + m_DragButton.Parent.Buttons.Remove(m_DragButton); + if (b != null) + tab.Buttons.Insert(tab.Buttons.IndexOf(b), m_DragButton); + else + tab.Buttons.Add(m_DragButton); + this.RecalcLayout(); + this.Refresh(); + } + else + { + BubbleButton button = GetButtonAt(mousePosition); + if (button != null && button != m_DragButton) + { + if (m_DragTabOriginalIndex == -1) + m_DragTabOriginalIndex = this.Tabs.IndexOf(m_DragButton.Parent); + if (m_DragButtonOriginalIndex == -1) + m_DragButtonOriginalIndex = m_DragButton.Parent.Buttons.IndexOf(m_DragButton); + BubbleBarTab parent = m_DragButton.Parent; + int insertIndex = parent.Buttons.IndexOf(button); + parent.Buttons.Remove(m_DragButton); + parent.Buttons.Insert(insertIndex, m_DragButton); + this.RecalcLayout(); + this.Refresh(); + } + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void DragMouseUp(Point mousePosition) + { + if (m_DragTab != null) + { + BubbleBarTab tab = GetTabAt(mousePosition); + if (tab != m_DragTab) + { + DragCancel(); + } + else + { + m_DragTab = null; + m_DragTabOriginalIndex = -1; + } + } + else if (m_DragButton != null) + { + BubbleButton button = GetButtonAt(mousePosition); + if (button != m_DragButton) + DragCancel(); + else + { + m_DragButton = null; + m_DragTabOriginalIndex = -1; + m_DragButtonOriginalIndex = -1; + } + } + + m_DragInProgress = false; + } + + internal void DragCancel() + { + if (!m_DragInProgress) + return; + + if (m_DragTab != null) + { + if (m_DragTabOriginalIndex >= 0) + { + this.Tabs.Remove(m_DragTab); + this.Tabs.Insert(m_DragTabOriginalIndex, m_DragTab); + this.RecalcLayout(); + this.Refresh(); + } + m_DragTab = null; + m_DragTabOriginalIndex = -1; + } + else if (m_DragButton != null) + { + if (m_DragButtonOriginalIndex >= 0) + { + if (m_DragButton.Parent != null) + m_DragButton.Parent.Buttons.Remove(m_DragButton); + if (m_DragTabOriginalIndex >= 0 && m_DragTabOriginalIndex != this.Tabs.IndexOf(m_DragButton.Parent)) + { + this.Tabs[m_DragTabOriginalIndex].Buttons.Insert(m_DragButtonOriginalIndex, m_DragButton); + } + else + this.Tabs[m_DragTabOriginalIndex].Buttons.Insert(m_DragButtonOriginalIndex, m_DragButton); + m_DragButtonOriginalIndex = -1; + m_DragTabOriginalIndex = -1; + m_DragButton = null; + this.RecalcLayout(); + this.Refresh(); + } + } + + m_DragInProgress = false; + } + #endregion + + #region ISupportInitialize + void ISupportInitialize.BeginInit() + { + } + void ISupportInitialize.EndInit() + { + //this.RecalcLayout(); + } + #endregion + + #region IMessageHandlerClient Implementation + + bool IMessageHandlerClient.IsModal + { + get + { + Form form = this.FindForm(); + if (form != null) + return form.Modal; + return false; + } + } + bool IMessageHandlerClient.OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + bool IMessageHandlerClient.OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + // Check Shortcuts + int wParamInt = WinApi.ToInt(wParam); + if (System.Windows.Forms.Control.ModifierKeys != Keys.None || wParamInt >= (int)eShortcut.F1 && wParamInt <= (int)eShortcut.F12) + { + int i = (int)System.Windows.Forms.Control.ModifierKeys | wParamInt; + if (ProcessShortcut((eShortcut)i)) + return true; + } + return false; + } + private bool ProcessShortcut(eShortcut key) + { + Form form = this.FindForm(); + if (form == null || (form != Form.ActiveForm && form.MdiParent == null || + form.MdiParent != null && form.MdiParent.ActiveMdiChild != form) && !form.IsMdiContainer || Form.ActiveForm != null && Form.ActiveForm.Modal && Form.ActiveForm != form) + return false; + + if (m_HasShortcuts) + { + foreach (BubbleBarTab t in this.Tabs) + { + foreach (BubbleButton b in t.Buttons) + { + if (b.Shortcut == key && b.Enabled) + { + b.InvokeClick(eEventSource.Keyboard, MouseButtons.None); + return true; + } + } + } + } + return false; + } + bool IMessageHandlerClient.OnMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + bool IMessageHandlerClient.OnMouseMove(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + bool IMessageHandlerClient.OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + if (!this.DesignMode) + { + // Check Shortcuts + int wParamInt = WinApi.ToInt(wParam); + if (System.Windows.Forms.Control.ModifierKeys != Keys.None || wParamInt >= (int)eShortcut.F1 && wParamInt <= (int)eShortcut.F12) + { + int i = (int)System.Windows.Forms.Control.ModifierKeys | wParamInt; + if (ProcessShortcut((eShortcut)i)) + return true; + } + } + return false; + } + bool IMessageHandlerClient.OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + private void InstallIMessageHandlerClient() + { + if (!m_FilterInstalled && !this.DesignMode) + { + MessageHandler.RegisterMessageClient(this); + m_FilterInstalled = true; + } + } + private void UninstallIMessageHandlerClient() + { + if (m_FilterInstalled) + { + MessageHandler.UnregisterMessageClient(this); + m_FilterInstalled = false; + } + } + #endregion + + #region Licensing +#if !TRIAL + private string m_LicenseKey = ""; + [Browsable(false), DefaultValue("")] + public string LicenseKey + { + get { return m_LicenseKey; } + set + { + if (NativeFunctions.ValidateLicenseKey(value)) + return; + m_LicenseKey = (!NativeFunctions.CheckLicenseKey(value) ? "9dsjkhds7" : value); + } + } +#endif + #endregion + + } + + #region Event handlers declaration + /// + /// Delegate for tab change events. + /// + public delegate void BubbleBarTabChangingEventHadler(object sender, BubbleBarTabChangingEventArgs e); + #endregion + + #region Event Arguments + /// + /// Represents the event arguments tab changing events. + /// + public class BubbleBarTabChangingEventArgs : EventArgs + { + /// + /// Cancels the operation. + /// + public bool Cancel = false; + /// + /// Specifies the event source. + /// + public eEventSource Source = eEventSource.Code; + /// + /// Specifies newly selected tab. + /// + public BubbleBarTab NewTab = null; + /// + /// Specifies currently selected tab. + /// + public BubbleBarTab CurrentTab = null; + /// + /// Default Constructor. + /// + public BubbleBarTabChangingEventArgs() { } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/BubbleBarDesigner.cs b/PROMS/DotNetBar Source Code/BubbleBarDesigner.cs new file mode 100644 index 00000000..e2d750b9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleBarDesigner.cs @@ -0,0 +1,625 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Reflection; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents Windows Forms designer for BubbleBar control. + /// + public class BubbleBarDesigner:System.Windows.Forms.Design.ControlDesigner + { + #region Private Variables + private bool m_IgnoreMouseUp=false; + private Point m_MouseDownPosition=Point.Empty; + private bool m_Capture=false; + + #endregion + + + public BubbleBarDesigner() + { + } + + 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); + } + + 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); + + base.Dispose(disposing); + } + + public override DesignerVerbCollection Verbs + { + get + { + DesignerVerb[] verbs = new DesignerVerb[] + { + new DesignerVerb("Create Tab", new EventHandler(CreateTab)), + new DesignerVerb("Create Button", new EventHandler(CreateButton))}; + return new DesignerVerbCollection(verbs); + } + } + +#if FRAMEWORK20 + public override void InitializeNewComponent(IDictionary defaultValues) + { + base.InitializeNewComponent(defaultValues); + SetDesignTimeDefaults(); + } +#else + public override void OnSetComponentDefaults() + { + base.OnSetComponentDefaults(); + SetDesignTimeDefaults(); + } +#endif + + private void SetDesignTimeDefaults() + { + BubbleBar bar = this.Component as BubbleBar; + if (bar == null) + return; + // Setup default back style + bar.ButtonBackAreaStyle.SetColorScheme(new ColorScheme(eDotNetBarStyle.Office2003)); + bar.ButtonBackAreaStyle.BackColor = Color.FromArgb(66, Color.DimGray); + bar.ButtonBackAreaStyle.BorderColor = Color.FromArgb(180, Color.WhiteSmoke); + bar.ButtonBackAreaStyle.BorderTop = eStyleBorderType.Solid; + bar.ButtonBackAreaStyle.BorderTopWidth = 1; + bar.ButtonBackAreaStyle.BorderBottom = eStyleBorderType.Solid; + bar.ButtonBackAreaStyle.BorderBottomWidth = 1; + bar.ButtonBackAreaStyle.BorderLeft = eStyleBorderType.Solid; + bar.ButtonBackAreaStyle.BorderLeftWidth = 1; + bar.ButtonBackAreaStyle.BorderRight = eStyleBorderType.Solid; + bar.ButtonBackAreaStyle.BorderRightWidth = 1; + bar.ButtonBackAreaStyle.PaddingBottom = 3; + bar.ButtonBackAreaStyle.PaddingTop = 3; + bar.ButtonBackAreaStyle.PaddingLeft = 3; + bar.ButtonBackAreaStyle.PaddingRight = 3; + bar.SelectedTabColors.BorderColor = Color.Black; + bar.MouseOverTabColors.BorderColor = SystemColors.Highlight; + } + + private void OnSelectionChanged(object sender, EventArgs e) + { + ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService)); + if(ss==null) + return; + + bool refresh=ResetFocus(); + if(ss.PrimarySelection is BubbleBarTab) + { + if(((BubbleBarTab)ss.PrimarySelection).Parent==this.Control) + { + ((BubbleBarTab)ss.PrimarySelection).Focus=true; + refresh=true; + } + } + else if(ss.PrimarySelection is BubbleButton) + { + if(((BubbleButton)ss.PrimarySelection).Parent.Parent==this.Control) + { + ((BubbleButton)ss.PrimarySelection).Focus=true; + refresh=true; + } + } + + if(refresh) + this.Control.Refresh(); + } + + private bool ResetFocus() + { + bool refresh=false; + BubbleBar bar=this.Control as BubbleBar; + foreach(BubbleBarTab tab in bar.Tabs) + { + if(tab.Focus) + { + tab.Focus=false; + refresh=true; + } + foreach(BubbleButton button in tab.Buttons) + { + if(button.Focus) + { + button.Focus=false; + refresh=true; + } + } + } + return refresh; + } + + private void OnComponentRemoving(object sender,ComponentEventArgs e) + { + if(e.Component==this.Component) + ThisComponentRemoving(sender,e); + else if(e.Component is BubbleBarTab) + { + BubbleBarTab tab=e.Component as BubbleBarTab; + if(tab.Parent==this.Control) + { + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + foreach(BubbleButton button in tab.Buttons) + dh.DestroyComponent(button); + BubbleBar bar=this.Component as BubbleBar; + bar.Tabs.Remove(tab); + bar.RecalcLayout(); + bar.Refresh(); + } + } + else if(e.Component is BubbleButton) + { + BubbleButton button=e.Component as BubbleButton; + if(button.GetBubbleBar()==this.Control) + { + button.Parent.Buttons.Remove(button); + BubbleBar bar=this.Component as BubbleBar; + bar.RecalcLayout(); + bar.Refresh(); + } + } + } + + /// + /// Removes all tabs and buttons. + /// + protected virtual void ThisComponentRemoving(object sender, ComponentEventArgs e) + { + //m_InternalRemoving=true; +// try +// { + // Unhook events + IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); + if(cc!=null) + cc.ComponentRemoving-=new ComponentEventHandler(this.OnComponentRemoving); + + ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService)); + if(ss!=null) + ss.SelectionChanged-=new EventHandler(OnSelectionChanged); + + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + BubbleBar bar=this.Component as BubbleBar; + if(dh==null) + return; + + foreach(BubbleBarTab tab in bar.Tabs) + { + foreach(BubbleButton button in tab.Buttons) + dh.DestroyComponent(button); + dh.DestroyComponent(tab); + } + //} +// finally +// { +// m_InternalRemoving=false; +// } + } + + private void CreateButton(object sender,EventArgs e) + { + BubbleBar bar=this.Control as BubbleBar; + if(bar==null) + return; + + if(bar.SelectedTab==null) + { + BubbleBarTab tab=CreateTab(); + IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(change!=null) + change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(bar).Find("SelectedTab",true)); + bar.SelectedTab=tab; + if(change!=null) + change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(bar).Find("SelectedTab",true),null,null); + } + + if(bar.SelectedTab==null) + return; + + BubbleButton button=CreateButton(bar.SelectedTab); + + if(button==null) + return; + + ISelectionService ss=(ISelectionService)GetService(typeof(ISelectionService)); + if(ss!=null) + { + ArrayList list=new ArrayList(); + list.Add(button); + ss.SetSelectedComponents(list); + } + } + + private void CreateTab(object sender,EventArgs e) + { + BubbleBar bar=this.Control as BubbleBar; + if(bar==null) + return; + + BubbleBarTab tab=CreateTab(); + if(tab!=null) + { + if(bar.SelectedTab!=tab) + { + IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(change!=null) + change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(bar).Find("SelectedTab",true)); + bar.SelectedTab=tab; + if(change!=null) + change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(bar).Find("SelectedTab",true),null,null); + } + + ISelectionService ss=(ISelectionService)GetService(typeof(ISelectionService)); + if(ss!=null) + { + ArrayList list=new ArrayList(); + list.Add(tab); + ss.SetSelectedComponents(list); + } + } + } + + private BubbleBarTab CreateTab() + { + BubbleBar bar=this.Control as BubbleBar; + if(bar==null) + return null; + + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh==null) + return null; + + IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(change!=null) + change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(bar).Find("Tabs",true)); + + BubbleBarTab tab=dh.CreateComponent(typeof(BubbleBarTab)) as BubbleBarTab; + if(tab==null) + return null; + + tab.Text=tab.Name; + eTabItemColor color=eTabItemColor.Blue; + if(bar.Tabs.Count>0) + { + int tt=bar.Tabs.Count+1; + Type t=typeof(eTabItemColor); + FieldInfo[] fi=t.GetFields(BindingFlags.Public | BindingFlags.Static); + int count=fi.Length; + while(tt>count) + tt-=count; + if(tt==0) tt++; + color=(eTabItemColor)Enum.Parse(typeof(eTabItemColor),fi[tt].Name); + } + tab.PredefinedColor=color; + + bar.Tabs.Add(tab); + + if(change!=null) + change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(bar).Find("Tabs",true),null,null); + + return tab; + } + + private BubbleButton CreateButton(BubbleBarTab tab) + { + BubbleBar bar=this.Control as BubbleBar; + if(bar==null) + return null; + + IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); + if(dh==null) + return null; + + IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(change!=null) + change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tab).Find("Buttons",true)); + + BubbleButton button=dh.CreateComponent(typeof(BubbleButton)) as BubbleButton; + if(button==null) + return null; + button.Image=BarFunctions.LoadBitmap("SystemImages.Note24.png"); + button.ImageLarge=BarFunctions.LoadBitmap("SystemImages.Note64.png"); + tab.Buttons.Add(button); + + if(change!=null) + change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tab).Find("Buttons",true),null,null); + + return button; + } + + /// + /// Returns all components associated with this control + /// + public override System.Collections.ICollection AssociatedComponents + { + get + { + ArrayList c=new ArrayList(base.AssociatedComponents); + BubbleBar bar=this.Control as BubbleBar; + if(bar!=null) + { + foreach(BubbleBarTab tab in bar.Tabs) + { + c.Add(tab); + GetTabComponents(tab,c); + } + } + return c; + } + } + + private void GetTabComponents(BubbleBarTab tab, ArrayList c) + { + foreach(BubbleButton b in tab.Buttons) + c.Add(b); + } + + protected override void OnSetCursor() + { + BubbleBar bar=this.Control as BubbleBar; + Point pos=bar.PointToClient(System.Windows.Forms.Control.MousePosition); + BubbleButton button=bar.GetButtonAt(pos); + if(button!=null) + { + Cursor.Current=Cursors.Default; + return; + } + BubbleBarTab tab=bar.GetTabAt(pos); + if(tab!=null) + { + Cursor.Current=Cursors.Default; + return; + } + base.OnSetCursor(); + } + + /// + /// Selection support for items on container. + /// + protected override void WndProc(ref Message m) + { + switch(m.Msg) + { + case NativeFunctions.WM_LBUTTONDOWN: + case NativeFunctions.WM_RBUTTONDOWN: + { + if(OnMouseDown(ref m)) + return; + break; + } + case NativeFunctions.WM_RBUTTONUP: + case NativeFunctions.WM_LBUTTONUP: + { + if(OnMouseUp(ref m)) + return; + break; + } + case NativeFunctions.WM_MOUSEMOVE: + { + if(OnMouseMove(ref m)) + return; + break; + } + case NativeFunctions.WM_LBUTTONDBLCLK: + { + if(OnMouseDoubleClick(m)) + return; + break; + } + } + + base.WndProc(ref m); + } + + private bool OnMouseDoubleClick(Message m) + { + bool processed=false; + + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(selection!=null && selection.PrimarySelection is BubbleButton && ((BubbleButton)selection.PrimarySelection).GetBubbleBar()==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) + { + BubbleBar bar=this.Control as BubbleBar; + + if(bar==null) + return false; + + Point pos=bar.PointToClient(System.Windows.Forms.Control.MousePosition); + m_MouseDownPosition=pos; + + BubbleButton button=bar.GetButtonAt(pos); + if(button!=null) + { + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(selection!=null) + { + ArrayList arr=new ArrayList(1); + arr.Add(button); +#if FRAMEWORK20 + selection.SetSelectedComponents(arr, SelectionTypes.Primary); +#else + selection.SetSelectedComponents(arr,SelectionTypes.MouseDown); +#endif + m_IgnoreMouseUp =true; + + if(m.Msg==NativeFunctions.WM_RBUTTONDOWN) + { + this.OnContextMenu(System.Windows.Forms.Control.MousePosition.X,System.Windows.Forms.Control.MousePosition.Y); + } + + return true; + } + } + + BubbleBarTab tab=bar.GetTabAt(pos); + if(tab!=null) + { + ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); + if(selection!=null && selection.PrimarySelection!=tab) + { + ArrayList arr=new ArrayList(1); + arr.Add(tab); +#if FRAMEWORK20 + selection.SetSelectedComponents(arr, SelectionTypes.Primary); +#else + selection.SetSelectedComponents(arr,SelectionTypes.MouseDown); +#endif + + if (bar.SelectedTab!=tab) + { + IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(change!=null) + change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(bar).Find("SelectedTab",true)); + + bar.SelectedTab=tab; + + if(change!=null) + change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(bar).Find("SelectedTab",true),null,null); + } + m_IgnoreMouseUp=true; + if(m.Msg!=NativeFunctions.WM_RBUTTONDOWN) + return true; + } + + if(m.Msg==NativeFunctions.WM_RBUTTONDOWN) + { + this.OnContextMenu(System.Windows.Forms.Control.MousePosition.X,System.Windows.Forms.Control.MousePosition.Y); + return true; + } + } + + return false; + } + + protected virtual bool OnMouseMove(ref Message m) + { + BubbleBar bar=this.Control as BubbleBar; + Point pos=bar.PointToClient(System.Windows.Forms.Control.MousePosition); + + if(Control.MouseButtons==MouseButtons.Left) + { + if(bar.DragInProgress) + { + bar.DragMouseMove(pos); + return true; + } + else if(!m_MouseDownPosition.IsEmpty && Math.Abs(m_MouseDownPosition.X-pos.X)>=2 || Math.Abs(m_MouseDownPosition.Y-pos.Y)>=2) + { + BubbleBarTab tabDrag=bar.GetTabAt(pos); + if(tabDrag!=null) + { + bar.StartDrag(tabDrag); + System.Windows.Forms.Control c=System.Windows.Forms.Control.FromHandle(m.HWnd); + if(c!=null) + { + m_Capture=true; + c.Capture=true; + } + return true; + } + BubbleButton buttonDrag=bar.GetButtonAt(pos); + if(buttonDrag!=null) + { + bar.StartDrag(buttonDrag); + System.Windows.Forms.Control c=System.Windows.Forms.Control.FromHandle(m.HWnd); + if(c!=null) + { + m_Capture=true; + c.Capture=true; + } + return true; + } + m_MouseDownPosition=Point.Empty; + } + } + + //BubbleButton button=bar.GetButtonAt(pos); + BubbleBarTab tab=bar.GetTabAt(pos); + if(tab!=null) + bar.SetMouseOverTab(tab); + else + bar.SetMouseOverTab(null); + + return false; + } + + private bool OnMouseUp(ref Message m) + { + if(m_Capture) + { + System.Windows.Forms.Control c=System.Windows.Forms.Control.FromHandle(m.HWnd); + if(c!=null) + c.Capture=false; + m_Capture=false; + } + + BubbleBar bar=this.Control as BubbleBar; + if(bar!=null && bar.DragInProgress) + { + Point pos=bar.PointToClient(System.Windows.Forms.Control.MousePosition); + bar.DragMouseUp(pos); + + BubbleBarTab tab=bar.SelectedTab; + if(tab!=null) + { + IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if(change!=null) + change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tab).Find("Buttons",true)); + if(change!=null) + change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tab).Find("Buttons",true),null,null); + } + } + + if(m_IgnoreMouseUp) + { + m_IgnoreMouseUp=false; + return true; + } + + return false; + } + } +} diff --git a/PROMS/DotNetBar Source Code/BubbleBarOverlay.cs b/PROMS/DotNetBar Source Code/BubbleBarOverlay.cs new file mode 100644 index 00000000..da016f52 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleBarOverlay.cs @@ -0,0 +1,282 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Drawing.Text; +using System.Windows.Forms; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents overlay class to support bubble effects on BubbleBar control. + /// + [ToolboxItem(false)] + internal class BubbleBarOverlay:Control + { + #region Private Variables + private BubbleBar m_BubbleBar=null; + private Timer m_VisibilityTimer=null; + #endregion + + #region Internal Implementation + public BubbleBarOverlay(BubbleBar parent) + { + if(parent==null) + throw new InvalidOperationException("Parent BubbleBar object for BubbleBarOverlay cannot be null."); + + m_BubbleBar=parent; + this.SetStyle(ControlStyles.UserPaint,true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint,true); + this.SetStyle(ControlStyles.Opaque,true); + this.SetStyle(ControlStyles.ResizeRedraw,true); + //this.SetStyle(DisplayHelp.DoubleBufferFlag,true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor,true); + this.SetStyle(ControlStyles.ContainerControl,false); + this.SetStyle(ControlStyles.Selectable,false); + this.BackColor=Color.Transparent; + } + + protected override void OnPaint(PaintEventArgs e){} + + internal void UpdateWindow() + { + // Create bitmap for drawing onto + Bitmap memoryBitmap = new Bitmap(this.Width, this.Height, PixelFormat.Format32bppArgb); + + using(Graphics g = Graphics.FromImage(memoryBitmap)) + { + // Draw the background area + g.Clear(Color.Transparent); + g.CompositingMode=System.Drawing.Drawing2D.CompositingMode.SourceCopy; + + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + g.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + + PaintEventArgs p=new PaintEventArgs(g,this.DisplayRectangle); + m_BubbleBar.OnPaintOverlay(p); + + // Get hold of the screen DC + IntPtr hDC = NativeFunctions.GetDC(IntPtr.Zero); + + // Create a memory based DC compatible with the screen DC + IntPtr memoryDC = WinApi.CreateCompatibleDC(hDC); + + // Get access to the bitmap handle contained in the Bitmap object + IntPtr hBitmap = memoryBitmap.GetHbitmap(Color.FromArgb(0)); + + // Select this bitmap for updating the window presentation + IntPtr oldBitmap = WinApi.SelectObject(memoryDC, hBitmap); + + // New window size + NativeFunctions.SIZE ulwsize; + ulwsize.cx = this.Width; + ulwsize.cy = this.Height; + + // New window position + NativeFunctions.POINT topPos; + topPos.x = this.Left; + topPos.y = this.Top; + + // Offset into memory bitmap is always zero + NativeFunctions.POINT pointSource; + pointSource.x = 0; + pointSource.y = 0; + + // We want to make the entire bitmap opaque + NativeFunctions.BLENDFUNCTION blend = new NativeFunctions.BLENDFUNCTION(); + blend.BlendOp = (byte)NativeFunctions.Win23AlphaFlags.AC_SRC_OVER; + blend.BlendFlags = 0; + blend.SourceConstantAlpha = 255; + blend.AlphaFormat = (byte)NativeFunctions.Win23AlphaFlags.AC_SRC_ALPHA; + + // Tell operating system to use our bitmap for painting + NativeFunctions.UpdateLayeredWindow(this.Handle, hDC, ref topPos, ref ulwsize, + memoryDC, ref pointSource, 0, ref blend, + (int)NativeFunctions.Win32UpdateLayeredWindowsFlags.ULW_ALPHA); + // Put back the old bitmap handle + WinApi.SelectObject(memoryDC, oldBitmap); + + // Cleanup resources + WinApi.ReleaseDC(IntPtr.Zero, hDC); + WinApi.DeleteObject(hBitmap); + WinApi.DeleteDC(memoryDC); + } + } + + protected override void OnMouseEnter(EventArgs e) + { + this.Capture=true; + base.OnMouseEnter (e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if(!this.DisplayRectangle.Contains(e.X,e.Y)) + this.Capture=false; + m_BubbleBar.MouseMoveMessage(e); + base.OnMouseMove (e); + } + + protected override void OnMouseLeave(EventArgs e) + { + m_BubbleBar.MouseLeaveMessage(e); + base.OnMouseLeave(e); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + m_BubbleBar.OverlayMouseDownMessage(e); + base.OnMouseDown (e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + m_BubbleBar.OverlayMouseUpMessage(e); + base.OnMouseUp(e); + } + + protected override void WndProc(ref Message m) + { + const int WM_MOUSEACTIVATE = 0x21; + const int MA_NOACTIVATE = 3; + if(m.Msg==WM_MOUSEACTIVATE) + { + m.Result=new System.IntPtr(MA_NOACTIVATE); + return; + } + base.WndProc(ref m); + } + + protected override CreateParams CreateParams + { + get + { + const uint WS_POPUP=0x80000000; + const uint WS_CLIPSIBLINGS=0x04000000; + const uint WS_CLIPCHILDREN=0x02000000; + const int WS_EX_LAYERED=0x00080000; + const int WS_EX_TOOLWINDOW=0x00000080; + CreateParams p=base.CreateParams; + p.ExStyle=(p.ExStyle | WS_EX_LAYERED | WS_EX_TOOLWINDOW); + p.Style=unchecked((int)(WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); + p.Caption=""; + return p; + } + } + + private void CreateTimer() + { + if(m_VisibilityTimer!=null) + return; + m_VisibilityTimer=new Timer(); + m_VisibilityTimer.Tick+=new EventHandler(this.CheckVisibility); + m_VisibilityTimer.Interval=500; + m_VisibilityTimer.Enabled=true; + m_VisibilityTimer.Start(); + } + + private void DestroyTimer() + { + if(m_VisibilityTimer==null) + return; + m_VisibilityTimer.Stop(); + m_VisibilityTimer.Enabled=false; + m_VisibilityTimer.Dispose(); + m_VisibilityTimer=null; + } + + private void CheckVisibility(object sender,EventArgs e) + { + try + { + BubbleBar bar = m_BubbleBar; + if (bar == null || bar.IsDisposed) + { + DestroyTimer(); + return; + } + + Form form = bar.FindForm(); + IntPtr foregroundWindow = NativeFunctions.GetForegroundWindow(); + Control c = null; + if (foregroundWindow != IntPtr.Zero) + c = Control.FromHandle(foregroundWindow); + if (c == null) + { + OnOverlayInactive(); + return; + } + if (form != null) + { + if (Form.ActiveForm == form) + return; + Form parentForm = form; + while (parentForm.ParentForm != null) + { + if (parentForm.ParentForm == Form.ActiveForm) + return; + parentForm = parentForm.ParentForm; + } + + if (form.IsMdiChild && form.MdiParent != null) + { + if (form.MdiParent.ActiveMdiChild == form) + return; + } + } + + NativeFunctions.POINT p = new NativeFunctions.POINT(); + Point pm = Control.MousePosition; + p.x = pm.X; + p.x = pm.Y; + IntPtr window = IntPtr.Zero; + if (bar.Parent != null) + NativeFunctions.ChildWindowFromPoint(bar.Parent.Handle, p); + if (window == IntPtr.Zero) + { + window = NativeFunctions.WindowFromPoint(p); + } + if (window != IntPtr.Zero && window != this.Handle && window != bar.Handle && bar.Parent != null && bar.Parent.Handle != window) + { + OnOverlayInactive(); + } + else + { + Point pc = this.PointToClient(pm); + if (!this.DisplayRectangle.Contains(pc)) + { + bar.MouseLeaveMessage(e); + } + } + } + catch (NullReferenceException) + { + DestroyTimer(); + } + } + + private void OnOverlayInactive() + { + this.Capture=false; + DestroyTimer(); + m_BubbleBar.OverlayInactive(); + } + + /// + /// Called just before window is shown. + /// + internal void BeforeShow() + { + CreateTimer(); + } + + /// + /// Called after window is closed. + /// + internal void AfterClose() + { + DestroyTimer(); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/BubbleBarTab.cs b/PROMS/DotNetBar Source Code/BubbleBarTab.cs new file mode 100644 index 00000000..364e4c5b --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleBarTab.cs @@ -0,0 +1,495 @@ +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.UI.ContentManager; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for BubbleBarGroup. + /// + [ToolboxItem(false), DesignTimeVisible(false), Designer("DevComponents.DotNetBar.Design.BubbleBarTabDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class BubbleBarTab:Component,ISimpleTab,IBlock + { + #region Private Properties + private string m_Text=""; + private BubbleBar m_Parent=null; + private bool m_Visible=true; + private Rectangle m_DisplayRectangle=Rectangle.Empty; + private Color m_BackColor=Color.Empty; + private Color m_BackColor2=Color.Empty; + private int m_BackColorGradientAngle=90; + private Color m_LightBorderColor=Color.Empty; + private Color m_DarkBorderColor=Color.Empty; + private Color m_BorderColor=Color.Empty; + private Color m_TextColor=Color.Empty; + private string m_Name=""; + private eTabItemColor m_PredefinedColor=eTabItemColor.Default; + private object m_Tag=null; + private BubbleButtonCollection m_Buttons=null; + private bool m_Focus=false; + #endregion + + #region Internal Implementation + /// + /// Default constructor. + /// + public BubbleBarTab():this(null){} + + /// + /// Default constructor. + /// + /// Container object. + public BubbleBarTab(IContainer container) + { + if(container!=null) + container.Add(this); + m_Buttons=new BubbleButtonCollection(this); + } + + + /// + /// Gets the collection of the buttons associated with the tab. + /// + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Buttons"), Description("Returns collection of buttons on the tab."), Editor("DevComponents.DotNetBar.Design.BubbleButtonCollectionEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public BubbleButtonCollection Buttons + { + get {return m_Buttons;} + } + + /// + /// Gets or sets the text displayed on the tab. + /// + [Browsable(true),DevCoBrowsable(true),Category("Appearance"),Description("Indicates the text displayed on the tab."),Localizable(true)] + public string Text + { + get {return m_Text;} + set + { + if(m_Text==value) + return; + m_Text=value; + if(m_Parent!=null) + m_Parent.OnTabTextChanged(this); + Refresh(); + } + } + + /// + /// Gets or sets whether tab is visible. + /// + [Browsable(true),DevCoBrowsable(true),DefaultValue(true),Category("Behavior"),Description("Indicates whether the tab is visible.")] + public bool Visible + { + get{return m_Visible;} + set + { + if(m_Visible==value) + return; + m_Visible=value; + if(m_Parent!=null) + m_Parent.OnTabVisibleChanged(this); + Refresh(); + } + } + + /// + /// Gets the display bounds of the tab. + /// + [Browsable(false)] + public Rectangle DisplayRectangle + { + get {return m_DisplayRectangle;} + } + + /// + /// Gets or sets the object that contains data about the tab. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// + [Browsable(false),DefaultValue(null),Category("Data"),Description("Indicates text that contains data about the cell.")] + public object Tag + { + get + { + return m_Tag; + } + set + { + m_Tag=value; + } + } + + /// + /// Gets or sets the object that contains data about the tab. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// + [Browsable(true),DefaultValue(""),Category("Data"),Description("Indicates text that contains data about the cell.")] + public string TagString + { + get + { + if(m_Tag==null) + return ""; + return m_Tag.ToString(); + } + set + { + m_Tag=value; + } + } + + /// + /// Gets or sets the background color of the tab when inactive. + /// + [Browsable(true),Description("Indicates the inactive tab background color."),Category("Style")] + public Color BackColor + { + get {return m_BackColor;} + set + { + m_BackColor=value; + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColor() + { + return !m_BackColor.IsEmpty; + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackColor() + { + BackColor=Color.Empty; + } + + /// + /// Gets or sets the target gradient background color of the tab when inactive. + /// + [Browsable(true),Description("Indicates the inactive tab target gradient background color."),Category("Style")] + public Color BackColor2 + { + get {return m_BackColor2;} + set + { + m_BackColor2=value; + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColor2() + { + return !m_BackColor2.IsEmpty; + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackColor2() + { + BackColor2=Color.Empty; + } + + /// + /// Gets or sets the gradient angle. + /// + [Browsable(true),Description("Indicates the gradient angle."),Category("Style"),DefaultValue(90)] + public int BackColorGradientAngle + { + get {return m_BackColorGradientAngle;} + set {m_BackColorGradientAngle=value;this.Refresh();} + } + + /// + /// Gets or sets the light border color when tab is inactive. + /// + [Browsable(true),Description("Indicates the inactive tab light border color."),Category("Style")] + public Color LightBorderColor + { + get {return m_LightBorderColor;} + set + { + m_LightBorderColor=value; + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLightBorderColor() + { + return !m_LightBorderColor.IsEmpty; + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public void ResetLightBorderColor() + { + LightBorderColor=Color.Empty; + } + + /// + /// Gets or sets the dark border color when tab is inactive. + /// + [Browsable(true),Description("Indicates the inactive tab dark border color."),Category("Style")] + public Color DarkBorderColor + { + get {return m_DarkBorderColor;} + set + { + m_DarkBorderColor=value; + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeDarkBorderColor() + { + return !m_DarkBorderColor.IsEmpty; + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public void ResetDarkBorderColor() + { + DarkBorderColor=Color.Empty; + } + + /// + /// Gets or sets the border color when tab is inactive. + /// + [Browsable(true),Description("Indicates the inactive tab border color."),Category("Style")] + public Color BorderColor + { + get {return m_BorderColor;} + set + { + m_BorderColor=value; + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBorderColor() + { + return !m_BorderColor.IsEmpty; + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBorderColor() + { + BorderColor=Color.Empty; + } + + /// + /// Gets or sets the text color when tab is inactive. + /// + [Browsable(true),Description("Indicates the inactive tab text color."),Category("Style")] + public Color TextColor + { + get {return m_TextColor;} + set + { + m_TextColor=value; + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return !m_TextColor.IsEmpty; + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + TextColor=Color.Empty; + } + + public override string ToString() + { + return m_Text; + } + + /// + /// Gets or sets name of the tab item that can be used to identify item from the code. + /// + [Browsable(true),DevCoBrowsable(true),Category("Design"),Description("Indicates the name used to identify item.")] + 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; + } + } + + /// + /// Gets or sets the predefined tab color. + /// + [Browsable(true), DefaultValue(eTabItemColor.Default),Category("Style"),Description("Applies predefined color to tab.")] + public eTabItemColor PredefinedColor + { + get {return m_PredefinedColor;} + set + { + m_PredefinedColor=value; + TabColorScheme.ApplyPredefinedColor(this,m_PredefinedColor); + this.Refresh(); + } + } + + /// + /// Returns the font for the tab text. + /// + /// Reference to the font object. + public Font GetTabFont() + { + if (m_Parent != null) + return m_Parent.Font; + else + return SystemFonts.DefaultFont; + } + + /// + /// Returns true if tab is selected tab. + /// + [Browsable(false)] + public bool IsSelected + { + get + { + if(m_Parent!=null) + { + return (m_Parent.SelectedTab==this); + } + return false; + } + } + + /// + /// Returns true if mouse is over the tab. + /// + [Browsable(false)] + public bool IsMouseOver + { + get + { + if(m_Parent!=null) + return (m_Parent.GetMouseOverTab()==this); + return false; + } + } + + /// + /// Gets the tab alignment. + /// + eTabStripAlignment ISimpleTab.TabAlignment + { + get + { + if(m_Parent!=null) + { + if(m_Parent.Alignment==eBubbleButtonAlignment.Top) + return eTabStripAlignment.Bottom; + } + return eTabStripAlignment.Top; + } + } + + /// + /// Returns reference to parent object or null if tab does not have parent. + /// + [Browsable(false)] + public BubbleBar Parent + { + get {return m_Parent;} + } + + /// + /// Sets the parent of the tab. + /// + /// Reference to the tab parent object or null. + internal void SetParent(BubbleBar parent) + { + m_Parent=parent; + } + + private void Refresh() + { + if(m_Parent!=null) + { + Rectangle r=this.DisplayRectangle; + r.Width+=16; + r.X-=8; + m_Parent.Invalidate(r); + m_Parent.Update(); + } + } + + /// + /// Called after new button is added to the Buttons collection. + /// + /// Reference to the added button. + internal void OnButtonInserted(BubbleButton button) + { + if(m_Parent!=null) + m_Parent.OnButtonInserted(this, button); + } + + /// + /// Called after specified button has been removed. + /// + /// Button that was removed. + internal void OnButtonRemoved(BubbleButton button) + { + if(m_Parent!=null) + m_Parent.OnButtonRemoved(this,button); + } + + /// + /// Called after all buttons have been removed. + /// + internal void OnButtonsCollectionClear() + { + if(m_Parent!=null) + m_Parent.OnButtonsCollectionClear(this); + } + + /// + /// Gets or sets whether tab has design-time focus. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool Focus + { + get {return m_Focus;} + set {m_Focus=value;} + } + #endregion + + #region IBlock + /// + /// Gets or sets the bounds of the content block. + /// + Rectangle IBlock.Bounds + { + get + { + return m_DisplayRectangle; + } + set + { + m_DisplayRectangle=value; + } + } + private DevComponents.DotNetBar.Padding _Margin = new DevComponents.DotNetBar.Padding(0); + /// + /// Gets or sets item margin only used by certain items in certain containers. Provided only for internal DotNetBar use. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + DevComponents.DotNetBar.Padding DevComponents.UI.ContentManager.IBlock.Margin + { + get { return _Margin; } + set { _Margin = value; } + } + #endregion + } + + +} diff --git a/PROMS/DotNetBar Source Code/BubbleBarTabCollection.cs b/PROMS/DotNetBar Source Code/BubbleBarTabCollection.cs new file mode 100644 index 00000000..5b09af93 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleBarTabCollection.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections; +using DevComponents.UI.ContentManager; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents collection for BubbleBarTab objects. + /// + public class BubbleBarTabCollection:CollectionBase + { + #region Private Variables + private BubbleBar m_Owner=null; + #endregion + + #region Internal Implementation + public BubbleBarTabCollection(BubbleBar owner) + { + m_Owner=owner; + } + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(BubbleBarTab tab) + { + return List.Add(tab); + } + /// + /// Returns reference to the object in collection based on it's index. + /// + public BubbleBarTab this[int index] + { + get {return (BubbleBarTab)(List[index]);} + set {List[index] = value;} + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, BubbleBarTab value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(BubbleBarTab value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(BubbleBarTab value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + public void Remove(BubbleBarTab value) + { + List.Remove(value); + } + + protected override void OnRemoveComplete(int index,object value) + { + base.OnRemoveComplete(index,value); + BubbleBarTab item=value as BubbleBarTab; + m_Owner.OnTabRemoved(item); + item.SetParent(null); + } + protected override void OnInsertComplete(int index,object value) + { + base.OnInsertComplete(index,value); + BubbleBarTab item=value as BubbleBarTab; + item.SetParent(m_Owner); + m_Owner.OnTabAdded(item); + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(BubbleBarTab[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the IBlock array. + /// + /// Array to copy to. + internal void CopyTo(IBlock[] array) + { + List.CopyTo(array,0); + } + + /// + /// Copies contained items to the ISimpleTab array. + /// + /// Array to copy to. + internal void CopyTo(ISimpleTab[] array) + { + List.CopyTo(array,0); + } + + protected override void OnClear() + { + m_Owner.OnTabsCleared(); + base.OnClear(); + } + + /// + /// Returns next visible tab from the reference tab. + /// + /// Reference tab. + /// Next visible tab or null if next visible tab cannot be determined. + internal BubbleBarTab GetNextVisibleTab(BubbleBarTab tabFrom) + { + int from=0; + if(tabFrom!=null)from=this.IndexOf(tabFrom)+1; + for(int i=from;i + /// Returns previous visible tab from the reference tab. + /// + /// Reference tab. + /// Previous visible tab or null if Previous visible tab cannot be determined. + internal BubbleBarTab GetPreviousVisibleTab(BubbleBarTab tabFrom) + { + int from=0; + if(tabFrom!=null) from=this.IndexOf(tabFrom)-1; + + for(int i=from;i>=0;i--) + { + if(this[i].Visible) + return this[i]; + } + return null; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/BubbleButton.cs b/PROMS/DotNetBar Source Code/BubbleButton.cs new file mode 100644 index 00000000..442e193d --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleButton.cs @@ -0,0 +1,594 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using System.Diagnostics; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents a button used on BubbleBar control. + /// + [ToolboxItem(false),DesignTimeVisible(false),DefaultEvent("Click")] + public class BubbleButton:Component,DevComponents.UI.ContentManager.IBlock + { + #region Private Variables + private string m_TooltipText=""; +// private System.Drawing.Icon m_Icon=null; + private int m_ImageIndex=-1; + private int m_ImageIndexLarge=-1; + private bool m_Enabled=true; + private Image m_ImageCached=null; + private Image m_ImageLargeCached=null; + private Image m_Image=null; + private Image m_ImageLarge=null; + private Rectangle m_DisplayRectangle=Rectangle.Empty; + private Rectangle m_MagnifiedDisplayRectangle=Rectangle.Empty; + private bool m_MouseOver=false; + private bool m_MouseDown=false; + //private SubItemsCollection m_MenuItems; + private BubbleButtonCollection m_ParentCollection=null; + private string m_Name=""; + private bool m_Visible=true; + private object m_Tag=null; + private bool m_Focus=false; + private eShortcut m_Shortcut=eShortcut.None; + #endregion + + #region Events + /// + /// Occurs when user clicks the button. + /// + public event ClickEventHandler Click; + /// + /// Occurs when mouse enters the button. + /// + public event EventHandler MouseEnter; + /// + /// Occurs when mouse leaves the button. + /// + public event EventHandler MouseLeave; + #endregion + + /// + /// Creates new instance of button object. + /// + public BubbleButton() + { + } + + protected override void Dispose(bool disposing) + { + if (BarUtilities.DisposeItemImages && !this.DesignMode) + { + BarUtilities.DisposeImage(ref m_Image); + BarUtilities.DisposeImage(ref m_ImageLarge); + BarUtilities.DisposeImage(ref m_ImageCached); + BarUtilities.DisposeImage(ref m_ImageLargeCached); + } + base.Dispose(disposing); + } + #region Public Properties + /// + /// Gets or sets the shortcut key to expand/collapse splitter. + /// + [Browsable(true),Category("Expand"),DefaultValue(eShortcut.None),Description("Indicates shortcut key to expand/collapse splitter."),] + public eShortcut Shortcut + { + get {return m_Shortcut;} + set + { + m_Shortcut=value; + if (m_Shortcut != eShortcut.None && this.GetBubbleBar()!=null) + { + this.GetBubbleBar().RefreshHasShortcut(); + } + } + } + + /// + /// Gets or sets the tooltip for the button. + /// + [Category("Appearance"),DefaultValue(""),Description("Indicates tooltip for the button."), Localizable(true)] + public string TooltipText + { + get {return m_TooltipText;} + set {m_TooltipText=value;} + } + +// /// +// /// Gets or sets the icon used on the button. The icon should at least have two sizes. Normal and enlarged size. +// /// Proper size will be determined based on the settings for image size on BubbleBar object. +// /// +// [Browsable(true),Category("Images"),Description("Indicates icons used on the button."),DefaultValue(null)] +// public Icon Icon +// { +// get {return m_Icon;} +// set +// { +// m_Icon=value; +// OnAppearanceChanged(); +// } +// } + + /// + /// Gets or sets the default image used on the button. Note that for improved appearance of the buttons when enlarged + /// you should set the ImageIndexLarge to the large version of the image specified here. The image size should be the same size + /// that is specified by the image size properties on BubbleBar object. + /// + [Browsable(true),Category("Images"),Description("Indicates default image used on the button."),Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)),System.ComponentModel.TypeConverter(typeof(ImageIndexConverter)),DefaultValue(-1)] + public int ImageIndex + { + get {return m_ImageIndex;} + set + { + m_ImageIndex=value; + m_ImageCached=null; + OnImageIndexChanged(); + OnAppearanceChanged(); + } + } + + /// + /// Gets reference to the internal cached image loaded from the ImageIndex. + /// + internal Image ImageCached + { + get {return m_ImageCached;} + } + + /// + /// Gets reference to the internal cached image loaded from the ImageIndex. + /// + internal Image ImageLargeCached + { + get {return m_ImageLargeCached;} + } + + /// + /// Specifies the Button image. + /// + [Browsable(true),Category("Images"),Description("The image that will be displayed on the face of the button."),DefaultValue(null)] + public System.Drawing.Image Image + { + get {return m_Image;} + set + { + m_Image=value; + this.OnImageChanged(); + } + } + + /// + /// Specifies enlarged the Button image. + /// + [Browsable(true),Category("Images"),Description("Indicates enlarged image that will be displayed on the face of the button."),DefaultValue(null)] + public System.Drawing.Image ImageLarge + { + get {return m_ImageLarge;} + set + { + m_ImageLarge=value; + this.OnImageChanged(); + } + } + + /// + /// Gets or sets the image index of the enlarged image for the button. Note that if large image is not specified the + /// default image will be enlarged which might not result in perfect image appearance. + /// + [Browsable(true),Category("Images"),Description("Indicates image index of the enlarged image for the button."),Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)),TypeConverter(typeof(ImageIndexConverter)),DefaultValue(-1)] + public int ImageIndexLarge + { + get {return m_ImageIndexLarge;} + set + { + m_ImageIndexLarge=value; + m_ImageLargeCached=null; + OnImageIndexChanged(); + OnAppearanceChanged(); + } + } + + /// + /// Property for Property Editor support for ImageIndex selection. + /// + [Browsable(false),EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public System.Windows.Forms.ImageList ImageList + { + get + { + BubbleBar bar=this.GetBubbleBar(); + if(bar!=null) + return bar.Images; + return null; + } + } + + /// + /// Gets or sets a value indicating whether button is enabled. + /// + [Browsable(true),DefaultValue(true),Category("Behavior"),Description("Indicates whether button is enabled.")] + public bool Enabled + { + get {return m_Enabled;} + set + { + if(m_Enabled!=value) + { + m_Enabled=value; + this.OnAppearanceChanged(); + } + } + } + + /// + /// Gets the display rectangle occupied by the button. + /// + [Browsable(false)] + public Rectangle DisplayRectangle + { + get {return m_DisplayRectangle;} + } + + /// + /// Sets the display rectangle of the button. + /// + /// New display rectangle of the button. + internal void SetDisplayRectangle(Rectangle r) + { + m_DisplayRectangle=r; + } + + /// + /// Gets or sets the magnified display rectangle of the button. + /// + [Browsable(false)] + public Rectangle MagnifiedDisplayRectangle + { + get {return m_MagnifiedDisplayRectangle;} + } + + /// + /// Sets the magnified display rectangle of the button. + /// + /// New magnified display rectangle. + internal void SetMagnifiedDisplayRectangle(Rectangle r) + { + m_MagnifiedDisplayRectangle=r; + } + + /// + /// Gets whether mouse is over the button. + /// + [Browsable(false)] + public bool MouseOver + { + get {return m_MouseOver;} + } + + /// + /// Sets whether mouse is over the button. + /// + /// True if mouse is over the button otherwise false. + internal void SetMouseOver(bool value) + { + bool changed=m_MouseOver!=value; + m_MouseOver=value; + UpdateCursor(); + if (changed) + { + if (value) + OnMouseEnter(); + else + OnMouseLeave(); + } + } + + /// + /// Raises the MouseEnter event. + /// + protected virtual void OnMouseEnter() + { + EventHandler eh = MouseEnter; + if (eh != null) + eh(this, new EventArgs()); + } + /// + /// Raises the MouseLeave event. + /// + protected virtual void OnMouseLeave() + { + EventHandler eh = MouseLeave; + if (eh != null) + eh(this, new EventArgs()); + } + + private void UpdateCursor() + { + BubbleBar parent = GetBubbleBar(); + if (parent == null || _Cursor == null) return; + + if (m_MouseOver) + { + if (_OldCursor == null) + { + _OldCursor = Cursor.Current; + } + parent.Cursor = _Cursor; + } + else + { + if (_OldCursor != null) + { + parent.Cursor = _OldCursor; + _OldCursor = null; + } + } + } + + /// + /// Gets whether left mouse button is pressed on the button. + /// + [Browsable(false)] + public bool MouseDown + { + get {return m_MouseDown;} + } + + /// + /// Sets whether left mouse button is pressed over this button. + /// + /// True if left mouse button is pressed otherwise false. + internal void SetMouseDown(bool value) + { + m_MouseDown=value; + } + + /// + /// Returns name of the button that can be used to identify it from the code. + /// + [Browsable(false),Category("Design"),Description("Indicates the name used to identify button.")] + 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; + } + } + + /// + /// Gets or sets a value indicating whether button is visible. + /// + [Browsable(true),DefaultValue(true),Category("Behavior"),Description("Determines whether the button is visible or hidden.")] + public virtual bool Visible + { + get + { + return m_Visible; + } + set + { + if(m_Visible==value) + return; + + m_Visible=value; + + OnVisibleChanged(); + } + } + + /// + /// Gets or sets the object that contains data about the tab. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// + [Browsable(false),DefaultValue(null),Category("Data"),Description("Indicates text that contains data about the cell.")] + public object Tag + { + get + { + return m_Tag; + } + set + { + m_Tag=value; + } + } + + /// + /// Gets or sets the object that contains data about the tab. Any Object derived type can be assigned to this property. If this property is being set through the Windows Forms designer, only text can be assigned. + /// + [Browsable(true),DefaultValue(""),Category("Data"),Description("Indicates text that contains data about the cell.")] + public string TagString + { + get + { + if(m_Tag==null) + return ""; + return m_Tag.ToString(); + } + set + { + m_Tag=value; + } + } + + /// + /// Returns the reference to parent tab. + /// + [Browsable(false)] + public BubbleBarTab Parent + { + get + { + if(m_ParentCollection!=null) + return m_ParentCollection.Parent; + return null; + } + } + #endregion + + #region Public Methods + #endregion + + #region Internal Implementation + /// + /// Gets or sets whether button has design-time focus. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool Focus + { + get {return m_Focus;} + set {m_Focus=value;} + } + + /// + /// Sets the parent collection button belongs to. + /// + /// Parent collection of the item. + internal void SetParentCollection(BubbleButtonCollection value) + { + m_ParentCollection=value; + } + + private void OnAppearanceChanged() + { + BubbleBar bar=this.GetBubbleBar(); + if(bar==null) + return; + bar.Refresh(); + } + + private void OnImageIndexChanged() + { + BubbleBar bar=this.GetBubbleBar(); + if(bar==null) + return; + if(m_ImageIndex>=0 && m_ImageCached==null) + { + if(bar.Images!=null && m_ImageIndex=0 && m_ImageLargeCached==null) + { + if(bar.ImagesLarge!=null && m_ImageIndexLarge + /// Returns the reference to the BubbleBar that contains this button. + /// + /// + public BubbleBar GetBubbleBar() + { + if(m_ParentCollection!=null && m_ParentCollection.Parent!=null && m_ParentCollection.Parent.Parent!=null) + return m_ParentCollection.Parent.Parent; + return null; + } + + private void OnVisibleChanged() + { + BubbleBar bar=this.GetBubbleBar(); + if(bar!=null) + bar.OnButtonVisibleChanged(this); + } + + /// + /// Invokes button's Click event. + /// + /// Indicates source of the event. + public void InvokeClick(eEventSource source, MouseButtons mouseButton) + { + OnClick(new ClickEventArgs(source, mouseButton)); + } + + /// + /// Raises click event. + /// + /// Default event arguments. + protected virtual void OnClick(ClickEventArgs e) + { + if(Click!=null) + Click(this,e); + + BubbleBar bar=this.GetBubbleBar(); + if(bar!=null) + bar.InvokeButtonClick(this,e); + } + + private Cursor _OldCursor = null; + private Cursor _Cursor = null; + /// + /// Gets or sets the mouse cursor that is displayed when mouse is over the button. + /// + [DefaultValue(null), Category("Appearance"), Description("Indciates mouse cursor that is displayed when mouse is over the button.")] + public Cursor Cursor + { + get { return _Cursor; } + set { _Cursor = value; } + } + #endregion + + #region IBlock Interface + /// + /// Gets or sets the bounds of the content block. + /// + Rectangle DevComponents.UI.ContentManager.IBlock.Bounds + { + get {return m_DisplayRectangle;} + set {m_DisplayRectangle=value;} + } + private DevComponents.DotNetBar.Padding _Margin = new DevComponents.DotNetBar.Padding(0); + /// + /// Gets or sets item margin only used by certain items in certain containers. Provided only for internal DotNetBar use. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + DevComponents.DotNetBar.Padding DevComponents.UI.ContentManager.IBlock.Margin + { + get { return _Margin; } + set { _Margin = value; } + } + #endregion + } + + #region Event Arguments and delegates + public delegate void ClickEventHandler(object sender, ClickEventArgs e); + + /// + /// Represents event arguments for Click event. + /// + public class ClickEventArgs:EventArgs + { + /// + /// Gets the action that caused the event, event source. + /// + public readonly eEventSource EventSource=eEventSource.Code; + public readonly MouseButtons Button=MouseButtons.None; + + public ClickEventArgs(eEventSource action, MouseButtons button) + { + this.EventSource=action; + this.Button=button; + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/BubbleButtonCollection.cs b/PROMS/DotNetBar Source Code/BubbleButtonCollection.cs new file mode 100644 index 00000000..77841c0f --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleButtonCollection.cs @@ -0,0 +1,405 @@ +using System; +using System.Collections; +using System.Windows.Forms; +using DevComponents.UI.ContentManager; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents typed collection of BubbleButton objects. + /// + public class BubbleButtonCollection:CollectionBase + { + #region Private Variables + private BubbleBarTab m_Parent=null; + private bool m_IgnoreEvents=false; + #endregion + + #region Internal Implementation + /// + /// Copies contained items to the IBlock array. + /// + /// Array to copy to. + internal void CopyTo(IBlock[] array) + { + List.CopyTo(array,0); + } + + /// + /// Creates new instance of the collection. + /// + /// Parent of the collection. + internal BubbleButtonCollection(BubbleBarTab parent) + { + m_Parent=parent; + } + + /// + /// Gets the parent of the collection. + /// + internal BubbleBarTab Parent + { + get {return m_Parent;} + } + + /// + /// Adds new item to the collection but it does not raise internal events. + /// + /// New item to add. + /// Index of newly added item. + internal int _Add(BubbleButton item) + { + m_IgnoreEvents=true; + int i=0; + try + { + i=List.Add(item); + } + finally + { + m_IgnoreEvents=false; + } + return i; + } + + /// + /// Adds new item to the collection at specified location but it does not raise internal events. + /// + /// New item to add. + /// Position to add item to. + internal void _Add(BubbleButton item, int Position) + { + m_IgnoreEvents=true; + try + { + List.Insert(Position,item); + } + finally + { + m_IgnoreEvents=false; + } + } + + /// + /// Clears the collection but it does not raise internal events. + /// + internal void _Clear() + { + m_IgnoreEvents=true; + try + { + List.Clear(); + } + finally + { + m_IgnoreEvents=false; + } + } + + /// + /// Performs additional custom processes before setting a value in the CollectionBase instance. + /// + /// The zero-based index at which oldValue can be found. + /// The value to replace with newValue. + /// The new value of the element at index. + protected override void OnSet(int index,object oldValue,object newValue) + { + if(newValue==null) + throw new InvalidOperationException("Setting of null values to BubbleButtonCollection is not allowed."); + + BubbleButton item=newValue as BubbleButton; + if(item.Parent!=null) + { + item.Parent.Buttons.Remove(item); + } + + base.OnSet(index,oldValue,newValue); + } + + /// + /// Performs additional custom processes after setting a value in the CollectionBase instance. + /// + /// The zero-based index at which oldValue can be found. + /// The value to replace with newValue. + /// The new value of the element at index. + protected override void OnSetComplete(int index,object oldValue,object newValue) + { + if(!m_IgnoreEvents) + { + BubbleButton item=newValue as BubbleButton; + item.SetParentCollection(this); + m_Parent.OnButtonInserted(item); + } + base.OnSetComplete(index,oldValue,newValue); + } + + /// + /// Performs additional custom processes before inserting a new element into the CollectionBase instance. + /// + /// The zero-based index at which to insert value. + /// The new value of the element at index. + protected override void OnInsert(int index,object value) + { + BubbleButton item=value as BubbleButton; + if(item.Parent!=null && item.Parent!=this.Parent) + { + item.Parent.Buttons.Remove(item); + } + base.OnInsert(index,value); + } + + /// + /// Performs additional custom processes after inserting a new element into the CollectionBase instance. + /// + /// The zero-based index at which to insert value. + /// The new value of the element at index. + protected override void OnInsertComplete(int index,object value) + { + if(!m_IgnoreEvents) + { + BubbleButton item=value as BubbleButton; + item.SetParentCollection(this); + m_Parent.OnButtonInserted(item); + } + + base.OnInsertComplete(index,value); + } + + /// + /// Performs additional custom processes when removing an element from the CollectionBase instance. + /// + /// The zero-based index at which value can be found. + /// The value of the element to remove from index. + protected override void OnRemove(int index,object value) + { +// if(!m_IgnoreEvents) +// { +// BubbleButton item=value as BubbleButton; +// } + base.OnRemove(index,value); + } + + /// + /// Performs additional custom processes after removing an element from the CollectionBase instance. + /// + /// The zero-based index at which value can be found. + /// The value of the element to remove from index. + protected override void OnRemoveComplete(int index,object value) + { + if(!m_IgnoreEvents) + { + BubbleButton item=value as BubbleButton; + item.SetParentCollection(null); + m_Parent.OnButtonRemoved(item); + } + + base.OnRemoveComplete(index,value); + } + + /// + /// Removes an item without raising internal events. + /// + /// Item to remove. + internal void _Remove(BubbleButton item) + { + m_IgnoreEvents=true; + try{List.Remove(item);} + finally{m_IgnoreEvents=false;} + } + + /// + /// Performs additional custom processes when clearing the contents of the CollectionBase instance. + /// + protected override void OnClear() + { + if(!m_IgnoreEvents) + { +// if(List.Count>0) +// { +// foreach(BubbleButton objSub in this) +// { +// if(owner!=null) +// owner.RemoveShortcutsFromItem(objSub); +// } +// } + if(m_Parent!=null) + { + m_Parent.OnButtonsCollectionClear(); + } + } + base.OnClear(); + } + + /// + /// Copies the collection to the ArrayList object. + /// + /// Target ArrayList. + public void CopyTo(ArrayList list) + { + if(list==null) + return; + foreach(BubbleButton item in this) + list.Add(item); + } + #endregion + + #region Public Interface + /// + /// Adds new item to the collection. + /// + /// New item to add. + /// Index of newly added item. + public virtual int Add(BubbleButton item) + { + return Add(item,-1); + } + + /// + /// Adds new item to the collection at specified location. + /// + /// New item to add. + /// Position to insert item at. Position of -1 will append the item to the end of the collection. + /// Index of the newly added item. + public virtual int Add(BubbleButton item, int Position) + { + int iRet=Position; + + if(Position>=0) + List.Insert(Position,item); + else + iRet=List.Add(item); + + return iRet; + } + + /// + /// Accesses items inside of the collection based on the index. + /// + public virtual BubbleButton this[int index] + { + get {return (BubbleButton)(List[index]);} + set {List[index] = value;} + } + + /// + /// Accesses items inside of the collection based on the name. + /// + public virtual BubbleButton this[string name] + { + get {return (BubbleButton)(List[this.IndexOf(name)]);} + set {List[this.IndexOf(name)] = value;} + } + + /// + /// Inserts new item at the specified position. + /// + /// Position to insert item at. + /// Item to insert. + public virtual void Insert(int index, BubbleButton item) + { + this.Add(item,index); + } + + /// + /// Returns index of an item. + /// + /// Item to return index for. + /// Item at the specified position. + public virtual int IndexOf(BubbleButton value) + { + return List.IndexOf(value); + } + + /// + /// Returns index of an item with given the item's name. + /// + /// Name of the item. + /// Index of the Item with the specified name or -1 if item is not found. + public virtual int IndexOf(string name) + { + int i=-1; + foreach(BubbleButton item in List) + { + i++; + if(item.Name==name) + return i; + } + return -1; + } + + /// + /// Returns true if given item is contained by this collection. + /// + /// Item to test. + /// True if item is part of this collection otherwise false. + public virtual bool Contains(BubbleButton value) + { + return List.Contains(value); + } + + /// + /// Returns true if item with given name is part of this collection. + /// + /// Item name. + /// True if item is part of this collection otherwise false. + public virtual bool Contains(string name) + { + foreach(BubbleButton item in List) + { + if(item.Name==name) + return true; + } + return false; + } + + /// + /// Removes an item from the collection. + /// + /// Item to remove. + public virtual void Remove(BubbleButton item) + { + List.Remove(item); + } + + /// + /// Removes an item from collection at specified index. + /// + /// Index of the item to remove. + public void Remove(int index) + { + this.Remove((BubbleButton)List[index]); + } + + /// + /// Removes item from the collection with specified name. + /// + /// Name of the item to remove. + public virtual void Remove(string name) + { + this.Remove(this[name]); + } + + /// + /// Adds array of the items to the collection. + /// + /// Array of items to add. + public virtual void AddRange(BubbleButton[] items) + { + foreach(BubbleButton item in items) + { + this.Add(item); + } + } + + /// + /// Copy the collection to the array. + /// + /// Array to copy collection to. + /// The zero-based relative index in array at which copying begins. + public virtual void CopyTo(BubbleButton[] array, int index) + { + List.CopyTo(array, index); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/BubbleButtonDisplay.cs b/PROMS/DotNetBar Source Code/BubbleButtonDisplay.cs new file mode 100644 index 00000000..96ba9c39 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleButtonDisplay.cs @@ -0,0 +1,231 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Drawing.Text; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents class for displaying BubbleButton objects on canvas. + /// + internal class BubbleButtonDisplay + { + static int BUTTON_TOOLTIP_SPACING=3; + /// + /// Paints button on given canvas. + /// + /// Painting information. + public static void Paint(BubbleButtonDisplayInfo info) + { + if(!info.Button.Visible) + return; + + CompositeImage image=null; + Rectangle buttonRectangle=Rectangle.Empty; + if(info.Magnified) + { + buttonRectangle=info.Button.MagnifiedDisplayRectangle; + image=GetButtonImage(info.Button,buttonRectangle.Size); + } + else + { + buttonRectangle=info.Button.DisplayRectangle; + image=GetButtonImage(info.Button,buttonRectangle.Size); + } + + if (buttonRectangle.Width < 2 || buttonRectangle.Height < 2) return; + + if(image!=null) + { + if(!info.Button.Enabled) + image.DrawImage(info.Graphics,buttonRectangle,0,0,image.ActualWidth,image.ActualHeight,GraphicsUnit.Pixel,GetDisabledAttributes()); + else if(info.Button.MouseDown) + image.DrawImage(info.Graphics,buttonRectangle,0,0,image.ActualWidth,image.ActualHeight,GraphicsUnit.Pixel,GetDarkAttributes()); + else + image.DrawImage(info.Graphics,buttonRectangle); + } + else + info.Graphics.DrawRectangle(SystemPens.Highlight,buttonRectangle); + + if(info.Button.Focus) + { + buttonRectangle.Inflate(1,1); + DesignTime.DrawDesignTimeSelection(info.Graphics,buttonRectangle,Color.Navy); + } + + DrawTooltip(info); + } + + public static CompositeImage GetButtonImage(BubbleButton button, Size size) + { + CompositeImage image=null; + if(button.Image!=null) + { + if(button.Image.Size==size || button.ImageLarge==null) + image=new CompositeImage(button.Image,false,size); + else if(button.ImageLarge!=null && (button.ImageLarge.Size==size || button.ImageLarge.Size.Height/size.Height<2)) + image=new CompositeImage(button.ImageLarge,false,size); + else + image=new CompositeImage(button.Image,false,size); + } + else if(button.ImageCached!=null) + { + if(button.ImageCached.Size==size || button.ImageLargeCached==null) + image=new CompositeImage(button.ImageCached,false,size); + else if(button.ImageLargeCached!=null && button.ImageLargeCached.Size.Height/size.Height<=2) + image=new CompositeImage(button.ImageLargeCached,false,size); + else + image=new CompositeImage(button.ImageCached,false,size); + } +// else if(button.Icon!=null) +// { +// +// } + return image; + } + + private static void DrawTooltip(BubbleButtonDisplayInfo info) + { + //float emMulti=1.3285f; + + if(info.Button.MouseOver && info.BubbleBar.ShowTooltips && info.Button.TooltipText!="") + { + Color textColor = info.BubbleBar.TooltipTextColor; + Color outlineColor = info.BubbleBar.TooltipOutlineColor; + + StringFormat format = TextDrawing.GetStringFormat(eTextFormat.Default); // BarFunctions.CreateStringFormat(); + System.Drawing.Drawing2D.CompositingMode cs=info.Graphics.CompositingMode=System.Drawing.Drawing2D.CompositingMode.SourceOver; + Font font=info.BubbleBar.TooltipFont; + if(font==null) + font=info.BubbleBar.Font; + Rectangle rText=info.Button.DisplayRectangle; + + Size size = TextDrawing.MeasureString(info.Graphics, info.Button.TooltipText, font); + + if(info.Magnified) + rText=info.Button.MagnifiedDisplayRectangle; + if(info.Alignment==eBubbleButtonAlignment.Bottom) + rText.Y-=(Math.Max(font.Height, size.Height)+BUTTON_TOOLTIP_SPACING); + else + rText.Y=rText.Bottom+BUTTON_TOOLTIP_SPACING; + + rText.Offset(-(size.Width-rText.Width)/2,0); + + Size tooltipSize = TextDrawing.MeasureString(info.Graphics, info.Button.TooltipText, font); + Rectangle outline = rText; + outline.Size = tooltipSize; + outline.Inflate(2, 2); + using (SolidBrush brush = new SolidBrush(Color.FromArgb(200, outlineColor))) + DisplayHelp.FillRoundedRectangle(info.Graphics, brush, outline, 3); + //Point pOutline=rText.Location; + //pOutline.Offset(-1,0); + //GraphicsPath path=new GraphicsPath(); + //path.AddString(info.Button.TooltipText,font.FontFamily,(int)font.Style,font.SizeInPoints/*font.SizeInPoints*emMulti*/,new PointF((pOutline.X+1)*72/info.Graphics.DpiX,(pOutline.Y-1)*72/info.Graphics.DpiY),format); + //using(Pen pen=new Pen(outlineColor,(font.SizeInPoints>=10?1:1))) + // path.Widen(pen); + //using(SolidBrush brush=new SolidBrush(Color.FromArgb(200,outlineColor))) + //{ + // GraphicsUnit pageUnit=info.Graphics.PageUnit; + // info.Graphics.PageUnit=GraphicsUnit.Point; + // info.Graphics.FillPath(brush,path); + // info.Graphics.PageUnit=pageUnit; + //} + + //path.Dispose(); + //path=new GraphicsPath(); + //path.AddString(info.Button.TooltipText,font.FontFamily,(int)font.Style,font.SizeInPoints/*font.SizeInPoints*emMulti*/,new PointF(pOutline.X*72/info.Graphics.DpiX,pOutline.Y*72/info.Graphics.DpiY),format); + //path.Widen(SystemPens.ControlText); + //using(SolidBrush brush=new SolidBrush(Color.FromArgb(200,outlineColor))) + //{ + // GraphicsUnit pageUnit=info.Graphics.PageUnit; + // info.Graphics.PageUnit=GraphicsUnit.Point; + // info.Graphics.FillPath(brush,path); + // info.Graphics.PageUnit=pageUnit; + //} + //path.Dispose(); + + TextDrawing.DrawString(info.Graphics,info.Button.TooltipText,font,textColor,rText.X,rText.Y,eTextFormat.Default); + + info.Graphics.CompositingMode=cs; + format.Dispose(); + } + } + + private static ImageAttributes GetDarkAttributes() + { + float[][] array = new float[5][]; +// array[0] = new float[5] {1, 0, 0, 0, 0}; +// array[1] = new float[5] {0, 1, 0, 0, 0}; +// array[2] = new float[5] {0, 0, 1, 0, 0}; +// array[3] = new float[5] {0, 0, 1, 0, 0}; +// array[4] = new float[5] {.5f, .5f, .5f, 0, 1}; + array[0] = new float[5] {.65f, 0, 0, 0, 0}; + array[1] = new float[5] {0, .65f, 0, 0, 0}; + array[2] = new float[5] {0, 0, .65f, 0, 0}; + array[3] = new float[5] {0, 0, 0, 1, 0}; + array[4] = new float[5] {0, 0, 0, 0, .65f}; + ColorMatrix grayMatrix = new ColorMatrix(array); + ImageAttributes darkImageAttr = new ImageAttributes(); + darkImageAttr.ClearColorKey(); + darkImageAttr.SetColorMatrix(grayMatrix); + return darkImageAttr; + } + + private static ImageAttributes GetDisabledAttributes() + { + float[][] array = new float[5][]; + array[0] = new float[5] {0.5f, 0.5f, 0.5f, 0.0f, 0.0f}; + array[1] = new float[5] {0.5f, 0.5f, 0.5f, 0.0f, 0.0f}; + array[2] = new float[5] {0.5f, 0.5f, 0.5f, 0.0f, 0.0f}; + array[3] = new float[5] {0.0f, 0.0f, 0.0f, 1.0f, 0.0f}; + array[4] = new float[5] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + //ColorMatrix grayMatrix = new ColorMatrix(array); + ColorMatrix grayMatrix = new ColorMatrix(); + grayMatrix.Matrix00 = 1/3f; + grayMatrix.Matrix01 = 1/3f; + grayMatrix.Matrix02 = 1/3f; + grayMatrix.Matrix10 = 1/3f; + grayMatrix.Matrix11 = 1/3f; + grayMatrix.Matrix12 = 1/3f; + grayMatrix.Matrix20 = 1/3f; + grayMatrix.Matrix21 = 1/3f; + grayMatrix.Matrix22 = 1/3f; + grayMatrix.Matrix33 = .5f; // Alpha-channel + + ImageAttributes darkImageAttr = new ImageAttributes(); + darkImageAttr.ClearColorKey(); + darkImageAttr.SetColorMatrix(grayMatrix); + return darkImageAttr; + } + } + + #region BubbleButtonDisplayInfo + /// + /// Represents class that holds information for BubbleButton painting. + /// + public class BubbleButtonDisplayInfo + { + /// + /// Graphics object. + /// + public Graphics Graphics=null; + /// + /// Button to paint. + /// + public BubbleButton Button=null; + /// + /// Reference to BubbleBar control. + /// + public BubbleBar BubbleBar=null; + /// + /// Gets or sets whether magnified version of the button is painted. + /// + public bool Magnified=false; + /// + /// Gets or sets the button alignment inside of the bar. + /// + public eBubbleButtonAlignment Alignment=eBubbleButtonAlignment.Bottom; + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/BubbleButtonLayoutManager.cs b/PROMS/DotNetBar Source Code/BubbleButtonLayoutManager.cs new file mode 100644 index 00000000..d10041c0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleButtonLayoutManager.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections; +using System.Drawing; +using DevComponents.UI.ContentManager; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents class for default layout of the BubbleButton objects. + /// + public class BubbleButtonLayoutManager:BlockLayoutManager + { + /// + /// Creates new instance of the class. + /// + public BubbleButtonLayoutManager() + { + } + + /// + /// Resizes the content block and sets it's Bounds property to reflect new size. + /// + /// Content block to resize. + public override void Layout(IBlock block, Size availableSize) + { + BubbleButton button=block as BubbleButton; + BubbleBar bar=button.GetBubbleBar(); + if(bar==null) + { + if(button.Site!=null && button.Site.DesignMode) + return; + throw new InvalidOperationException("BubbleBar object could not be found for button named: '"+button.Name+"' in BubbleButtonLayoutManager.Layout"); + } + Size defaultSize=Dpi.ImageSize(bar.ImageSizeNormal); + button.SetDisplayRectangle(new Rectangle(button.DisplayRectangle.Location,defaultSize)); + } + + public override Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines) + { + return (blocksBounds); + } + } +} diff --git a/PROMS/DotNetBar Source Code/BubbleContentManager.cs b/PROMS/DotNetBar Source Code/BubbleContentManager.cs new file mode 100644 index 00000000..e83edfee --- /dev/null +++ b/PROMS/DotNetBar Source Code/BubbleContentManager.cs @@ -0,0 +1,302 @@ +using System; +using System.Drawing; +using DevComponents.UI.ContentManager; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents class that provides mangification for the BubbleMar control + /// + public class BubbleContentManager:SerialContentLayoutManager + { + #region Private Variables + private Size m_BubbleSize=Size.Empty; + private float m_Factor1=0,m_Factor2=0,m_Factor3=0,m_Factor4=0; + private int m_MouseOverIndex=-1; + private int m_MouseOverPosition=-1; + #endregion + + public BubbleContentManager() + { + this.ContentAlignment=eContentAlignment.Center; + } + + #region IContentLayout + + /// + /// Performs layout of the content block. + /// + /// Container bounds to layout content blocks in. + /// Content blocks to layout. + /// Block layout manager that resizes the content blocks. + /// The bounds of the content blocks within the container bounds. + public override Rectangle Layout(Rectangle containerBounds,IBlock[] contentBlocks,BlockLayoutManager blockLayout) + { + if(contentBlocks.Length==0) + return Rectangle.Empty; + + if(m_MouseOverIndex==-1) + { + return base.Layout(containerBounds,contentBlocks,blockLayout); + } + + BubbleButton[] buttons=new BubbleButton[contentBlocks.Length]; + contentBlocks.CopyTo(buttons,0); + + int x=0,y=0; + if(this.ContentOrientation==eContentOrientation.Horizontal) + { + buttons[m_MouseOverIndex].SetMagnifiedDisplayRectangle(new Rectangle(m_MouseOverPosition,GetY(containerBounds,m_BubbleSize.Height),m_BubbleSize.Width,m_BubbleSize.Height)); + x=m_MouseOverPosition; + } + else + { + buttons[m_MouseOverIndex].SetMagnifiedDisplayRectangle(new Rectangle(GetX(containerBounds,m_BubbleSize.Width),m_MouseOverPosition,m_BubbleSize.Width,m_BubbleSize.Height)); + y=m_MouseOverPosition; + } + + int growthWidth=m_BubbleSize.Width-contentBlocks[0].Bounds.Width; + int growthHeight=m_BubbleSize.Height-contentBlocks[0].Bounds.Height; + + // Apply factor 2 + int index=GetPreviousButtonIndex(buttons,m_MouseOverIndex); + if(index>=0) + SetFactorPrevious(containerBounds,buttons[index],growthWidth,growthHeight,m_Factor2,ref x, ref y); + + // Apply factor 1 + index=GetPreviousButtonIndex(buttons,index); + if(index>=0) + SetFactorPrevious(containerBounds,buttons[index],growthWidth,growthHeight,m_Factor1,ref x, ref y); + + if(this.ContentOrientation==eContentOrientation.Horizontal) + { + while(index>=0) + { + index=GetPreviousButtonIndex(buttons,index); + if(index>=0) + { + x-=(buttons[index].DisplayRectangle.Width+this.BlockSpacing); + buttons[index].SetMagnifiedDisplayRectangle(new Rectangle(x,buttons[index].DisplayRectangle.Y,buttons[index].DisplayRectangle.Width,buttons[index].DisplayRectangle.Height)); + } + } + x=m_MouseOverPosition+m_BubbleSize.Width+this.BlockSpacing; + } + else + { + while(index>=0) + { + index=GetPreviousButtonIndex(buttons,index); + if(index>=0) + { + y-=(buttons[index].DisplayRectangle.Height+this.BlockSpacing); + buttons[index].SetMagnifiedDisplayRectangle(new Rectangle(buttons[index].DisplayRectangle.X,y,buttons[index].DisplayRectangle.Width,buttons[index].DisplayRectangle.Height)); + } + } + + y=m_MouseOverPosition+m_BubbleSize.Height+this.BlockSpacing; + } + + // Apply factor 3 + index=GetNextButtonIndex(buttons,m_MouseOverIndex); + if(index>=0) + SetFactorNext(containerBounds,buttons[index],growthWidth,growthHeight,m_Factor3,ref x, ref y); + + // Apply factor 4 + if(index==-1) index=m_MouseOverIndex; + index=GetNextButtonIndex(buttons,index); + if(index>=0) + SetFactorNext(containerBounds,buttons[index],growthWidth,growthHeight,m_Factor4,ref x, ref y); + + if(this.ContentOrientation==eContentOrientation.Horizontal) + { + while(index>=0) + { + index=GetNextButtonIndex(buttons,index); + if(index>=0) + { + buttons[index].SetMagnifiedDisplayRectangle(new Rectangle(x,buttons[index].DisplayRectangle.Y,buttons[index].DisplayRectangle.Width,buttons[index].DisplayRectangle.Height)); + x+=(buttons[index].DisplayRectangle.Width+this.BlockSpacing); + } + } + } + else + { + while(index>=0) + { + index=GetNextButtonIndex(buttons,index); + if(index>=0) + { + buttons[index].SetMagnifiedDisplayRectangle(new Rectangle(buttons[index].DisplayRectangle.X,y,buttons[index].DisplayRectangle.Width,buttons[index].DisplayRectangle.Height)); + y+=(buttons[index].DisplayRectangle.Height+this.BlockSpacing); + } + } + } + + if(buttons.Length==1) + return buttons[0].MagnifiedDisplayRectangle; + + return Rectangle.Union(buttons[0].MagnifiedDisplayRectangle,buttons[buttons.Length-1].MagnifiedDisplayRectangle); + } + + private void SetFactorPrevious(Rectangle containerBounds, BubbleButton button, int growthWidth, int growthHeight, float factor, ref int x, ref int y) + { + int w=(int)(button.DisplayRectangle.Width+growthWidth*factor); + int h=(int)(button.DisplayRectangle.Height+growthHeight*factor); + if(this.ContentOrientation==eContentOrientation.Horizontal) + { + x-=(w+this.BlockSpacing); + button.SetMagnifiedDisplayRectangle(new Rectangle(x,GetY(containerBounds,h),w,h)); + } + else + { + y-=(h+this.BlockSpacing); + button.SetMagnifiedDisplayRectangle(new Rectangle(GetX(containerBounds,w),y,w,h)); + } + } + + private void SetFactorNext(Rectangle containerBounds, BubbleButton button, int growthWidth, int growthHeight, float factor, ref int x, ref int y) + { + int w=(int)(button.DisplayRectangle.Width+growthWidth*factor); + int h=(int)(button.DisplayRectangle.Height+growthHeight*factor); + if(this.ContentOrientation==eContentOrientation.Horizontal) + { + button.SetMagnifiedDisplayRectangle(new Rectangle(x,GetY(containerBounds,h),w,h)); + x+=(w+this.BlockSpacing); + } + else + { + button.SetMagnifiedDisplayRectangle(new Rectangle(GetX(containerBounds,w),y,w,h)); + y+=(h+this.BlockSpacing); + } + } + + private int GetNextButtonIndex(BubbleButton[] buttons, int index) + { + int next=-1; + for(int i=index+1;i=0;i--) + { + if(buttons[i].Visible) + { + next=i; + break; + } + } + return next; + } + + private int GetX(Rectangle containerBounds, int width) + { + if(this.ContentOrientation==eContentOrientation.Vertical) + { + if(this.ContentVerticalAlignment==eContentVerticalAlignment.Top) + return containerBounds.Left; + else if(this.ContentVerticalAlignment==eContentVerticalAlignment.Middle) + return containerBounds.Left+(containerBounds.Width-width)/2; + else if(this.ContentVerticalAlignment==eContentVerticalAlignment.Bottom) + return containerBounds.Right-width; + } + else + throw new InvalidOperationException("Cannot use GetX method on eContentOrientation.Horizontal"); + return -1; + } + + private int GetY(Rectangle containerBounds, int height) + { + if(this.ContentOrientation==eContentOrientation.Horizontal) + { + if(this.ContentVerticalAlignment==eContentVerticalAlignment.Top) + return containerBounds.Top; + else if(this.ContentVerticalAlignment==eContentVerticalAlignment.Middle) + return containerBounds.Top+(containerBounds.Height-height)/2; + else if(this.ContentVerticalAlignment==eContentVerticalAlignment.Bottom) + return containerBounds.Bottom-height; + } + else + throw new InvalidOperationException("Cannot use GetX method on eContentOrientation.Vertical"); + return -1; + } + #endregion + + #region Public Properties + + /// + /// Gets or sets the bubble size for the mouse over item. + /// + public Size BubbleSize + { + get {return m_BubbleSize;} + set {m_BubbleSize=value;} + } + + /// + /// Gets or sets magnification factor for the item that is at the position MouseOverIndex-1 + /// + public float Factor1 + { + get {return m_Factor1;} + set {m_Factor1=value;} + } + + /// + /// Gets or sets magnification factor for the item that is at the position MouseOverIndex-2 + /// + public float Factor2 + { + get {return m_Factor2;} + set {m_Factor2=value;} + } + + /// + /// Gets or sets magnification factor for the item that is at the position MouseOverIndex+1 + /// + public float Factor3 + { + get {return m_Factor3;} + set {m_Factor3=value;} + } + + /// + /// Gets or sets magnification factor for the item that is at the position MouseOverIndex+2 + /// + public float Factor4 + { + get {return m_Factor4;} + set {m_Factor4=value;} + } + + /// + /// Gets or sets the index of the item mouse is over. + /// + public int MouseOverIndex + { + get {return m_MouseOverIndex;} + set {m_MouseOverIndex=value;} + } + + /// + /// Gets or sets new X coordinate of the mouse over item when in horizontal layout or Y + /// coordinate when in vertical layout. + /// + public int MouseOverPosition + { + get {return m_MouseOverPosition;} + set {m_MouseOverPosition=value;} + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/BufferedBitmap.cs b/PROMS/DotNetBar Source Code/BufferedBitmap.cs new file mode 100644 index 00000000..15c049a9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/BufferedBitmap.cs @@ -0,0 +1,123 @@ +using System; +using System.Text; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar +{ + public class BufferedBitmap : IDisposable + { + #region Private Variables + private Rectangle m_TargetRect = Rectangle.Empty; + private IntPtr m_MemDC = IntPtr.Zero; + private Graphics m_BitmapGraphics = null; + private IntPtr m_MemDib = IntPtr.Zero; + #endregion + + #region Internal Implementation + public BufferedBitmap(Graphics source, Rectangle rect) + { + IntPtr hdc = source.GetHdc(); + try + { + Initialize(hdc, rect); + } + finally + { + source.ReleaseHdc(hdc); + } + } + + public Graphics Graphics + { + get + { + return m_BitmapGraphics; + } + } + + public BufferedBitmap(IntPtr hdcSource, Rectangle rect) + { + Initialize(hdcSource, rect); + } + private void Initialize(IntPtr hdcSource, Rectangle r) + { + m_TargetRect = r; + + m_MemDC = WinApi.CreateCompatibleDC(hdcSource); + WinApi.BITMAPINFO info = new WinApi.BITMAPINFO(); + info.biWidth = r.Width; + info.biHeight = r.Height; + info.biPlanes = 1; + info.biBitCount = 32; + info.biSize = Marshal.SizeOf(info); + m_MemDib = WinApi.CreateDIBSection(hdcSource, info, 0, 0, IntPtr.Zero, 0); + WinApi.SelectObject(m_MemDC, m_MemDib); + m_BitmapGraphics = Graphics.FromHdc(m_MemDC); + } + + public void Render(Graphics targetGraphics) + { + Render(targetGraphics, new Rectangle[] { }); + } + + public void Render(Graphics targetGraphics, Rectangle exclude) + { + Render(targetGraphics, new Rectangle[] { exclude }); + } + + public void Render(Graphics targetGraphics, Rectangle[] excludeArr) + { + const int SRCCOPY = 0x00CC0020; + IntPtr hdc = targetGraphics.GetHdc(); + try + { + if (excludeArr!=null && excludeArr.Length > 0) + { + foreach (Rectangle r in excludeArr) + { + if (!r.IsEmpty) + WinApi.ExcludeClipRect(hdc, r.X, r.Y, r.Right, r.Bottom); + } + } + WinApi.BitBlt(hdc, m_TargetRect.Left, m_TargetRect.Top, m_TargetRect.Width, m_TargetRect.Height, m_MemDC, 0, 0, SRCCOPY); + } + finally + { + targetGraphics.ReleaseHdc(hdc); + } + } + + public Rectangle TargetRect + { + get { return m_TargetRect; } + set { m_TargetRect = value; } + } + #endregion + + #region IDisposable Members + + public void Dispose() + { + if (m_BitmapGraphics != null) + { + m_BitmapGraphics.Dispose(); + m_BitmapGraphics = null; + } + + if (m_MemDib != IntPtr.Zero) + { + WinApi.DeleteObject(m_MemDib); + m_MemDib = IntPtr.Zero; + } + + if (m_MemDC != IntPtr.Zero) + { + WinApi.DeleteDC(m_MemDC); + m_MemDC = IntPtr.Zero; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ButtonItem.cs b/PROMS/DotNetBar Source Code/ButtonItem.cs new file mode 100644 index 00000000..85ac7eef --- /dev/null +++ b/PROMS/DotNetBar Source Code/ButtonItem.cs @@ -0,0 +1,6512 @@ +using System.ComponentModel; +using System; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for ButtonItem. + /// + [System.ComponentModel.ToolboxItem(false), System.ComponentModel.DesignTimeVisible(false), DefaultEvent("Click"), Designer("DevComponents.DotNetBar.Design.BaseItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ButtonItem : PopupItem, IPersonalizedMenuItem + { + #region Events + /// + /// Occurs when Checked property has changed. + /// + public event EventHandler CheckedChanged; + /// + /// Occurs before an item in option group is checked and provides opportunity to cancel that. + /// + [Description("Occurs before an item in option group is checked and provides opportunity to cancel that.")] + public event OptionGroupChangingEventHandler OptionGroupChanging; + #endregion + + #region Private Variables + private const int STATEBUTTON_SPACING = 3; + private System.Drawing.Image m_Image; + private System.Drawing.Image m_ImageSmall; + private int m_ImageIndex; // Image index if image from ImageList is used + private System.Drawing.Image m_HoverImage; + private int m_HoverImageIndex; // Image index if image from ImageList is used + private System.Drawing.Image m_DisabledImage; + private bool m_DisabledImageCustom = false; + private int m_DisabledImageIndex; // Image index if image from ImageList is used + private System.Drawing.Icon m_DisabledIcon = null; + private System.Drawing.Image m_PressedImage; + private int m_PressedImageIndex; // Image index if image from ImageList is used + private eButtonStyle m_ButtonStyle; + private eImagePosition m_ImagePosition; + private Font m_Font; + + private string m_AlternateShortcutText; + + private bool m_MouseOver = false; + private bool m_MouseOverExpand = false; + private bool m_MouseDown; + + private bool m_Checked; + + private Rectangle m_ImageDrawRect; + private Rectangle m_TextDrawRect; + private Rectangle m_SubItemsRect; + private int m_VerticalPadding; + private int m_HorizontalPadding; + + private Color m_ForeColor = System.Drawing.Color.Empty; + private Color m_HotForeColor = System.Drawing.Color.Empty; + private bool m_HotFontUnderline = false; + private bool m_HotFontBold = false; + private bool m_FontBold = false; + private bool m_FontItalic = false; + private bool m_FontUnderline = false; + + // IPersonalizedMenuItem Implementation + private eMenuVisibility m_MenuVisibility = eMenuVisibility.VisibleAlways; + private bool m_RecentlyUsed = false; + private eHotTrackingStyle m_HotTrackingStyle = eHotTrackingStyle.Default; + private System.Drawing.Image m_ImageCachedIdx = null; + private ItemPaintArgs _ItemPaintArgs = null; + private int m_SubItemsExpandWidth = 12; + private string m_OptionGroup = ""; + private Size m_ImageSizeOverride = Size.Empty; + + internal bool _FitContainer = false; + + System.Drawing.Icon m_Icon = null; + private bool m_AutoExpandOnClick = false; + + private eButtonColor m_ColorTable = eButtonColor.Orange; private string m_CashedColorName = "Orange"; + + private int m_ImagePaddingHorizontal = 8; + private int m_ImagePaddingVertical = 6; + private string m_CustomColorName = ""; + private Size m_FixedSize = Size.Empty; + private bool m_SplitButton = false; + private bool m_IgnoreAlpha = false; + private int m_MouseOverFadeAlphaIncrement = 65; + private int m_PulseFadeAlphaIncrement = 12; + private bool m_Pulse = false; + private int m_PulseBeats = 0, m_PulseCount = 0; + private bool m_StopPulseOnMouseOver = true; + private bool m_RibbonWordWrap = true; + private bool m_AutoCheckOnClick = false; + private bool m_UseSmallImage = false; + internal bool _FixedSizeCenterText = false; + #endregion + + #region Constructor, Copy + /// + /// Creates new instance of ButtonItem. + /// + public ButtonItem() : this("", "") { } + /// + /// Creates new instance of ButtonItem and assigns the name to it. + /// + /// Item name. + public ButtonItem(string sItemName) : this(sItemName, "") { } + /// + /// Creates new instance of ButtonItem and assigns the name and text to it. + /// + /// Item name. + /// item text. + public ButtonItem(string sItemName, string ItemText) + : base(sItemName, ItemText) + { + m_IsContainer = false; + m_Image = null; + m_ImageIndex = -1; + m_HoverImage = null; + m_HoverImageIndex = -1; + m_DisabledImage = null; + m_DisabledImageIndex = -1; + m_PressedImage = null; + m_PressedImageIndex = -1; + m_MouseOver = false; + m_MouseDown = false; + m_ButtonStyle = eButtonStyle.Default; + m_ImagePosition = eImagePosition.Left; + m_Font = null; + m_ImageDrawRect = Rectangle.Empty; + m_TextDrawRect = Rectangle.Empty; + m_SubItemsRect = Rectangle.Empty; + m_VerticalPadding = 0; + m_HorizontalPadding = 0; + m_AlternateShortcutText = ""; + } + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + ButtonItem objCopy = new ButtonItem(m_Name); + this.CopyToItem(objCopy); + return objCopy; + } + + /// + /// Copies the ButtonItem specific properties to new instance of the item. + /// + /// New ButtonItem instance. + internal void InternalCopyToItem(ButtonItem copy) + { + CopyToItem((BaseItem)copy); + } + + /// + /// Copies the ButtonItem specific properties to new instance of the item. + /// + /// New ButtonItem instance. + protected override void CopyToItem(BaseItem copy) + { + ButtonItem objCopy = copy as ButtonItem; + base.CopyToItem(objCopy); + + if (m_Image != null) + objCopy.Image = (Image)m_Image.Clone(); + if (m_ImageSmall != null) + objCopy.ImageSmall = (Image)m_ImageSmall.Clone(); + if (m_HoverImage != null) + objCopy.HoverImage = (Image)m_HoverImage.Clone(); + if (m_PressedImage != null) + objCopy.PressedImage = (Image)m_PressedImage.Clone(); + if (m_DisabledImage != null && m_DisabledImageCustom) + objCopy.DisabledImage = (Image)m_DisabledImage.Clone(); + if (m_Icon != null) + objCopy.Icon = m_Icon.Clone() as Icon; + + objCopy.ButtonStyle = m_ButtonStyle; + //objCopy.ButtonType=m_ButtonType; + objCopy.ImagePosition = m_ImagePosition; + objCopy.OptionGroup = m_OptionGroup; + objCopy.Checked = m_Checked; + objCopy.PopupType = this.PopupType; + objCopy.AlternateShortCutText = this.AlternateShortCutText; + + if (m_ImageIndex >= 0) + objCopy.SetImageIndex(m_ImageIndex); + if (m_PressedImageIndex >= 0) + objCopy.PressedImageIndex = m_PressedImageIndex; + if (m_HoverImageIndex >= 0) + objCopy.HoverImageIndex = m_HoverImageIndex; + if (m_DisabledImageIndex >= 0) + objCopy.DisabledImageIndex = m_DisabledImageIndex; + + if (!m_ForeColor.IsEmpty) + objCopy.ForeColor = m_ForeColor; + + objCopy.HotFontBold = m_HotFontBold; + objCopy.HotFontUnderline = m_HotFontUnderline; + + if (!m_HotForeColor.IsEmpty) + objCopy.HotForeColor = m_HotForeColor; + + objCopy.HotTrackingStyle = m_HotTrackingStyle; + objCopy.MenuVisibility = m_MenuVisibility; + objCopy.AutoExpandOnClick = this.AutoExpandOnClick; + objCopy.AlternateShortCutText = this.AlternateShortCutText; + objCopy.SubItemsExpandWidth = this.SubItemsExpandWidth; + objCopy.CheckedChanged = this.CheckedChanged; + objCopy.OptionGroupChanging = this.OptionGroupChanging; + + if (!this.ImageFixedSize.IsEmpty) + objCopy.ImageFixedSize = this.ImageFixedSize; + + objCopy.ImagePaddingHorizontal = m_ImagePaddingHorizontal; + objCopy.ImagePaddingVertical = m_ImagePaddingVertical; + objCopy.FixedSize = this.FixedSize; + objCopy.RibbonWordWrap = this.RibbonWordWrap; + objCopy.AutoCheckOnClick = this.AutoCheckOnClick; + + if (this.Shape != null) + objCopy.Shape = this.Shape; + + objCopy.ColorTable = this.ColorTable; + objCopy.CustomColorName = this.CustomColorName; + objCopy.AutoExpandMenuItem = this.AutoExpandMenuItem; + + objCopy.EnableMarkup = this.EnableMarkup; + objCopy.SplitButton = this.SplitButton; + + objCopy.NotificationMarkColor = this.NotificationMarkColor; + objCopy.NotificationMarkPosition = this.NotificationMarkPosition; + objCopy.NotificationMarkSize = this.NotificationMarkSize; + objCopy.NotificationMarkText = this.NotificationMarkText; + + objCopy.Symbol = this.Symbol; + objCopy.SymbolSet = this.SymbolSet; + objCopy.SymbolColor = this.SymbolColor; + objCopy.SymbolSize = this.SymbolSize; + } + + protected override void Dispose(bool disposing) + { + StopFade(); + StopPulse(); + StopImageAnimation(); + DisposeMouseOverFont(); + DisposedCachedImageListImage(); + if (BarUtilities.DisposeItemImages && !this.DesignMode || _AutoDisposeImages) + { + BarUtilities.DisposeImage(ref m_Image); + BarUtilities.DisposeImage(ref m_Icon); + BarUtilities.DisposeImage(ref m_ImageSmall); + BarUtilities.DisposeImage(ref m_HoverImage); + BarUtilities.DisposeImage(ref m_DisabledImage); + BarUtilities.DisposeImage(ref m_PressedImage); + BarUtilities.DisposeImage(ref m_DisabledIcon); + } + base.Dispose(disposing); + } + + private void DisposedCachedImageListImage() + { + if (m_ImageCachedIdx != null) m_ImageCachedIdx.Dispose(); + m_ImageCachedIdx = null; + } + private ButtonItemAccessibleObject _ButtonItemAccessibleObject = null; + protected override System.Windows.Forms.AccessibleObject CreateAccessibilityInstance() + { + if (_ButtonItemAccessibleObject == null) + _ButtonItemAccessibleObject = new ButtonItemAccessibleObject(this); + return _ButtonItemAccessibleObject; + } + + private bool _AutoDisposeImages = false; + /// + /// Indicates whether images assigned to the button are disposed when button is disposed. Default value is false. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether images assigned to the button are disposed when button is disposed. Default value is false.")] + public bool AutoDisposeImages + { + get + { + return _AutoDisposeImages; + } + set + { + _AutoDisposeImages = value; + } + } + + #endregion + + #region Serialization + /// + /// Overloaded. Serializes the item and all sub-items into the XmlElement. + /// + /// XmlElement to serialize the item to. + protected internal override void Serialize(ItemSerializationContext context) + { + base.Serialize(context); + System.Xml.XmlElement ThisItem = context.ItemXmlElement; + ThisItem.SetAttribute("ImagePosition", System.Xml.XmlConvert.ToString(((int)m_ImagePosition))); + ThisItem.SetAttribute("ButtonStyle", System.Xml.XmlConvert.ToString(((int)m_ButtonStyle))); + ThisItem.SetAttribute("Checked", System.Xml.XmlConvert.ToString(m_Checked)); + ThisItem.SetAttribute("VerticalPadding", System.Xml.XmlConvert.ToString(m_VerticalPadding)); + ThisItem.SetAttribute("HorizontalPadding", System.Xml.XmlConvert.ToString(m_HorizontalPadding)); + + ThisItem.SetAttribute("MenuVisibility", System.Xml.XmlConvert.ToString((int)m_MenuVisibility)); + ThisItem.SetAttribute("RecentlyUsed", System.Xml.XmlConvert.ToString(m_RecentlyUsed)); + + if (m_AlternateShortcutText != "") + ThisItem.SetAttribute("AlternateShortcutText", m_AlternateShortcutText); + + if (!m_ForeColor.IsEmpty) + ThisItem.SetAttribute("forecolor", BarFunctions.ColorToString(m_ForeColor)); + + if (m_HotTrackingStyle != eHotTrackingStyle.Default) + ThisItem.SetAttribute("hottrack", System.Xml.XmlConvert.ToString((int)m_HotTrackingStyle)); + + if (m_HotFontBold) + ThisItem.SetAttribute("hotfb", System.Xml.XmlConvert.ToString(m_HotFontBold)); + if (m_HotFontUnderline) + ThisItem.SetAttribute("hotfu", System.Xml.XmlConvert.ToString(m_HotFontUnderline)); + + if (!m_HotForeColor.IsEmpty) + ThisItem.SetAttribute("hotclr", BarFunctions.ColorToString(m_HotForeColor)); + + if (m_OptionGroup != "") + ThisItem.SetAttribute("optiongroup", m_OptionGroup); + + if (m_FontBold) + ThisItem.SetAttribute("fontbold", System.Xml.XmlConvert.ToString(m_FontBold)); + if (m_FontItalic) + ThisItem.SetAttribute("fontitalic", System.Xml.XmlConvert.ToString(m_FontItalic)); + if (m_FontUnderline) + ThisItem.SetAttribute("fontunderline", System.Xml.XmlConvert.ToString(m_FontUnderline)); + + if (m_AutoExpandOnClick) + ThisItem.SetAttribute("autoexpandclick", System.Xml.XmlConvert.ToString(m_AutoExpandOnClick)); + + if (m_CustomColorName != "") + ThisItem.SetAttribute("CustomColorName", m_CustomColorName); + if (m_ColorTable != eButtonColor.Orange) + ThisItem.SetAttribute("ColorTable", Enum.GetName(m_ColorTable.GetType(), m_ColorTable)); + + System.Xml.XmlElement xmlElem = null, xmlElem2 = null; + + // Serialize Images + if (m_Image != null || m_ImageIndex >= 0 || m_HoverImage != null || m_HoverImageIndex >= 0 || m_DisabledImage != null || m_DisabledImageIndex >= 0 || m_PressedImage != null || m_PressedImageIndex >= 0 || m_Icon != null || m_ImageSmall != null) + { + xmlElem = ThisItem.OwnerDocument.CreateElement("images"); + ThisItem.AppendChild(xmlElem); + + if (m_ImageIndex >= 0) + xmlElem.SetAttribute("imageindex", System.Xml.XmlConvert.ToString(m_ImageIndex)); + if (m_HoverImageIndex >= 0) + xmlElem.SetAttribute("hoverimageindex", System.Xml.XmlConvert.ToString(m_HoverImageIndex)); + if (m_DisabledImageIndex >= 0) + xmlElem.SetAttribute("disabledimageindex", System.Xml.XmlConvert.ToString(m_DisabledImageIndex)); + if (m_PressedImageIndex >= 0) + xmlElem.SetAttribute("pressedimageindex", System.Xml.XmlConvert.ToString(m_PressedImageIndex)); + + if (m_Image != null) + { + xmlElem2 = ThisItem.OwnerDocument.CreateElement("image"); + xmlElem2.SetAttribute("type", "default"); + xmlElem.AppendChild(xmlElem2); + BarFunctions.SerializeImage(m_Image, xmlElem2); + } + if (m_ImageSmall != null) + { + xmlElem2 = ThisItem.OwnerDocument.CreateElement("imagesmall"); + xmlElem2.SetAttribute("type", "small"); + xmlElem.AppendChild(xmlElem2); + BarFunctions.SerializeImage(m_ImageSmall, xmlElem2); + } + if (m_HoverImage != null) + { + xmlElem2 = ThisItem.OwnerDocument.CreateElement("image"); + xmlElem2.SetAttribute("type", "hover"); + xmlElem.AppendChild(xmlElem2); + BarFunctions.SerializeImage(m_HoverImage, xmlElem2); + } + if (m_DisabledImage != null && m_DisabledImageCustom) + { + xmlElem2 = ThisItem.OwnerDocument.CreateElement("image"); + xmlElem2.SetAttribute("type", "disabled"); + xmlElem.AppendChild(xmlElem2); + BarFunctions.SerializeImage(m_DisabledImage, xmlElem2); + } + if (m_PressedImage != null) + { + xmlElem2 = ThisItem.OwnerDocument.CreateElement("image"); + xmlElem2.SetAttribute("type", "pressed"); + xmlElem.AppendChild(xmlElem2); + BarFunctions.SerializeImage(m_PressedImage, xmlElem2); + } + if (m_Icon != null) + { + xmlElem2 = ThisItem.OwnerDocument.CreateElement("image"); + xmlElem2.SetAttribute("type", "icon"); + xmlElem.AppendChild(xmlElem2); + BarFunctions.SerializeIcon(m_Icon, xmlElem2); + } + } + } + + /// + /// Overloaded. Deserializes the Item from the XmlElement. + /// + /// Source XmlElement. + public override void Deserialize(ItemSerializationContext context) + { + base.Deserialize(context); + + System.Xml.XmlElement ItemXmlSource = context.ItemXmlElement; + m_ImagePosition = (eImagePosition)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("ImagePosition")); + m_ButtonStyle = (eButtonStyle)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("ButtonStyle")); + m_Checked = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("Checked")); + m_VerticalPadding = System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("VerticalPadding")); + m_HorizontalPadding = System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("HorizontalPadding")); + + m_MenuVisibility = (eMenuVisibility)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("MenuVisibility")); + m_RecentlyUsed = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("RecentlyUsed")); + + if (ItemXmlSource.HasAttribute("forecolor")) + m_ForeColor = BarFunctions.ColorFromString(ItemXmlSource.GetAttribute("forecolor")); + else + m_ForeColor = System.Drawing.Color.Empty; + + if (ItemXmlSource.HasAttribute("hottrack")) + m_HotTrackingStyle = (eHotTrackingStyle)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("hottrack")); + else + m_HotTrackingStyle = eHotTrackingStyle.Default; + + if (ItemXmlSource.HasAttribute("hotclr")) + m_HotForeColor = BarFunctions.ColorFromString(ItemXmlSource.GetAttribute("hotclr")); + else + m_HotForeColor = System.Drawing.Color.Empty; + + if (ItemXmlSource.HasAttribute("hotfb")) + m_HotFontBold = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("hotfb")); + else + m_HotFontBold = false; + if (ItemXmlSource.HasAttribute("hotfu")) + m_HotFontUnderline = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("hotfu")); + else + m_HotFontUnderline = false; + + if (ItemXmlSource.HasAttribute("optiongroup")) + m_OptionGroup = ItemXmlSource.GetAttribute("optiongroup"); + else + m_OptionGroup = ""; + + if (ItemXmlSource.HasAttribute("fontbold")) + m_FontBold = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("fontbold")); + else + m_FontBold = false; + if (ItemXmlSource.HasAttribute("fontitalic")) + m_FontItalic = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("fontitalic")); + else + m_FontItalic = false; + if (ItemXmlSource.HasAttribute("fontunderline")) + m_FontUnderline = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("fontunderline")); + else + m_FontUnderline = false; + + if (ItemXmlSource.HasAttribute("AlternateShortcutText")) + m_AlternateShortcutText = ItemXmlSource.GetAttribute("AlternateShortcutText"); + else + m_AlternateShortcutText = ""; + + if (ItemXmlSource.HasAttribute("autoexpandclick")) + m_AutoExpandOnClick = System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("autoexpandclick")); + else + m_AutoExpandOnClick = false; + + if (ItemXmlSource.HasAttribute("CustomColorName")) + m_CustomColorName = ItemXmlSource.GetAttribute("CustomColorName"); + else + m_CustomColorName = ""; + + if (ItemXmlSource.HasAttribute("ColorTable")) + m_ColorTable = (eButtonColor)Enum.Parse(m_ColorTable.GetType(), ItemXmlSource.GetAttribute("ColorTable")); + else + m_ColorTable = eButtonColor.Orange; + + m_ImageIndex = -1; + m_HoverImageIndex = -1; + m_DisabledImageIndex = -1; + m_PressedImageIndex = -1; + m_Icon = null; + m_Image = null; + m_ImageSmall = null; + m_HoverImage = null; + m_DisabledImage = null; + m_DisabledImageCustom = false; + m_PressedImage = null; + + // Load Images + foreach (System.Xml.XmlElement xmlElem in ItemXmlSource.ChildNodes) + { + if (xmlElem.Name == "images") + { + if (xmlElem.HasAttribute("imageindex")) + m_ImageIndex = System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("imageindex")); + if (xmlElem.HasAttribute("hoverimageindex")) + m_HoverImageIndex = System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("hoverimageindex")); + if (xmlElem.HasAttribute("disabledimageindex")) + m_DisabledImageIndex = System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("disabledimageindex")); + if (xmlElem.HasAttribute("pressedimageindex")) + m_PressedImageIndex = System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("pressedimageindex")); + + foreach (System.Xml.XmlElement xmlElem2 in xmlElem.ChildNodes) + { + switch (xmlElem2.GetAttribute("type")) + { + case "default": + { + m_Image = BarFunctions.DeserializeImage(xmlElem2); + m_ImageIndex = -1; + break; + } + case "icon": + { + m_Icon = BarFunctions.DeserializeIcon(xmlElem2); + m_ImageIndex = -1; + break; + } + case "hover": + { + m_HoverImage = BarFunctions.DeserializeImage(xmlElem2); + m_HoverImageIndex = -1; + break; + } + case "disabled": + { + m_DisabledImage = BarFunctions.DeserializeImage(xmlElem2); + m_DisabledImageIndex = -1; + m_DisabledImageCustom = true; + break; + } + case "pressed": + { + m_PressedImage = BarFunctions.DeserializeImage(xmlElem2); + m_PressedImageIndex = -1; + break; + } + case "small": + { + m_ImageSmall = BarFunctions.DeserializeImage(xmlElem2); + break; + } + } + } + break; + } + } + this.OnImageChanged(); + } + #endregion + + #region Internal Implementation + private string _NotificationMarkText = ""; + /// + /// Specifies maximum of 2 character text displayed inside of the notification mark on top of the button. + /// + [DefaultValue(""), Category("Appearance"), Description("Specifies maximum of 2 character text displayed inside of the notification mark on top of the button.")] + public string NotificationMarkText + { + get { return _NotificationMarkText; } + set + { + if (value != _NotificationMarkText) + { + string oldValue = _NotificationMarkText; + _NotificationMarkText = value; + OnNotificationMarkTextChanged(oldValue, value); + } + } + } + /// + /// Called when NotificationMarkText property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnNotificationMarkTextChanged(string oldValue, string newValue) + { + if (string.IsNullOrEmpty(newValue)) _NotificationMarkWasDisplayed = true; // Make sure button gets invalidated properly + this.Refresh(); + } + + private eNotificationMarkPosition _NotificationMarkPosition = eNotificationMarkPosition.TopRight; + /// + /// Indicates the position of the notification marker within the bounds of the button. + /// + [DefaultValue(eNotificationMarkPosition.TopRight), Category("Appearance"), Description("Indicates the position of the notification marker within the bounds of the button.")] + public eNotificationMarkPosition NotificationMarkPosition + { + get { return _NotificationMarkPosition; } + set + { + if (value != _NotificationMarkPosition) + { + eNotificationMarkPosition oldValue = _NotificationMarkPosition; + _NotificationMarkPosition = value; + OnNotificationMarkPositionChanged(oldValue, value); + } + } + } + /// + /// Called when NotificationMarkPosition property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnNotificationMarkPositionChanged(eNotificationMarkPosition oldValue, eNotificationMarkPosition newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("NotificationMarkPosition")); + if(!string.IsNullOrEmpty(_NotificationMarkText)) + this.Refresh(); + } + private int _NotificationMarkSize = 0; + /// + /// Specifies diameter of notification mark. When set to 0 system default value is used. + /// + [DefaultValue(0), Category("Appearance"), Description("Specifies diameter of notification mark. When set to 0 system default value is used.")] + public int NotificationMarkSize + { + get { return _NotificationMarkSize; } + set + { + if (value != _NotificationMarkSize) + { + int oldValue = _NotificationMarkSize; + _NotificationMarkSize = value; + OnNotificationMarkSizeChanged(oldValue, value); + } + } + } + /// + /// Called when NotificationMarkSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnNotificationMarkSizeChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("NotificationMarkSize")); + this.Refresh(); + } + private Color _NotificationMarkColor = Color.Empty; + /// + /// Gets or sets background color of the notification mark. + /// + [Category("Appearance"), Description("Indicates background color of the notification mark.")] + public Color NotificationMarkColor + { + get { return _NotificationMarkColor; } + set { _NotificationMarkColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeNotificationMarkColor() + { + return !_NotificationMarkColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetNotificationMarkColor() + { + this.NotificationMarkColor = Color.Empty; + } + private bool _NotificationMarkWasDisplayed = false; + protected override Rectangle GetInvalidateBounds() + { + if (_NotificationMarkWasDisplayed || !string.IsNullOrEmpty(_NotificationMarkText)) + { + _NotificationMarkWasDisplayed = false; + Rectangle r = base.GetInvalidateBounds(); + r.Inflate(6, 6); + return r; + } + return base.GetInvalidateBounds(); + } + + private static readonly Point DefaultNotificationMarkOffset = new Point(3, 3); + private Point _NotificationMarkOffset = DefaultNotificationMarkOffset; + /// + /// Specifies the offset for the notification mark relative to its position. + /// + [Category("Appearance"), Description("Specifies the offset for the notification mark relative to its position.")] + public Point NotificationMarkOffset + { + get { return _NotificationMarkOffset; } + set + { + if (value != _NotificationMarkOffset) + { + Point oldValue = _NotificationMarkOffset; + _NotificationMarkOffset = value; + OnNotificationMarkOffsetChanged(oldValue, value); + } + } + } + /// + /// Called when NotificationMarkOffset property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnNotificationMarkOffsetChanged(Point oldValue, Point newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("NotificationMarkOffset")); + this.Invalidate(); + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeNotificationMarkOffset() + { + return _NotificationMarkOffset != DefaultNotificationMarkOffset; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetNotificationMarkOffset() + { + this.NotificationMarkOffset = DefaultNotificationMarkOffset; + } + + /// + /// Gets/Sets the image position inside the button. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The alignment of the image in relation to text displayed by this item."), System.ComponentModel.DefaultValue(eImagePosition.Left)] + public virtual eImagePosition ImagePosition + { + get + { + return m_ImagePosition; + } + set + { + if (m_ImagePosition != value) + { + m_ImagePosition = value; + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "ImagePosition"); + + NeedRecalcSize = true; + if (this.Parent != null) + this.Parent.NeedRecalcSize = true; + OnAppearanceChanged(); + } + } + } + + /// + /// Gets or sets the custom color name. Name specified here must be represented by the corresponding object with the same name that is part + /// of the Office2007ColorTable.RibbonTabItemColors collection. See documentation for Office2007ColorTable.RibbonTabItemColors for more information. + /// If color table with specified name cannot be found default color will be used. Valid settings for this property override any + /// setting to the Color property. + /// Applies to items with Office 2007 style only. + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(""), Category("Appearance"), Description("Indicates custom color table name for the button when Office 2007 style is used.")] + public virtual string CustomColorName + { + get { return m_CustomColorName; } + set + { + m_CustomColorName = value; + this.Refresh(); + } + } + + /// + /// Gets or sets the predefined color of the button. Color specified applies to buttons with Office 2007 style only. It does not have + /// any effect on other styles. Default value is eButtonColor.Default + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(eButtonColor.Orange), Category("Appearance"), Description("Indicates predefined color of button when Office 2007 style is used.")] + public virtual eButtonColor ColorTable + { + get { return m_ColorTable; } + set + { + if (m_ColorTable != value) + { + m_ColorTable = value; + m_CashedColorName = Enum.GetName(typeof(eButtonColor), m_ColorTable); + this.Refresh(); + } + } + } + + internal virtual string GetColorTableName() + { + return m_CashedColorName; + } + + /// + /// Gets/Sets the button style which controls the appearance of the button elements. Changing the property can display image only, text only or image and text on the button at all times. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Determines the style of the button."), System.ComponentModel.DefaultValue(eButtonStyle.Default)] + public virtual eButtonStyle ButtonStyle + { + get + { + return m_ButtonStyle; + } + set + { + if (m_ButtonStyle != value) + { + m_ButtonStyle = value; + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "ButtonStyle"); + NeedRecalcSize = true; + if (this.Displayed && m_Parent != null) + { + RecalcSize(); + m_Parent.SubItemSizeChanged(this); + } + OnAppearanceChanged(); + } + } + } + + /// + /// Indicates whether the item will auto-expand when clicked. + /// When item is on top level bar and not on menu and contains sub-items, sub-items will be shown only if user + /// click the expand part of the button. Setting this property to true will expand the button and show sub-items when user + /// clicks anywhere inside of the button. Default value is false which indicates that button is expanded only + /// if its expand part is clicked. + /// + [DefaultValue(false), Browsable(true), DevCoBrowsable(true), Category("Behavior"), Description("Indicates whether the item will auto-expand (display pop-up menu or toolbar) when clicked.")] + public virtual bool AutoExpandOnClick + { + get + { + return m_AutoExpandOnClick; + } + set + { + m_AutoExpandOnClick = value; + } + } + + private Color _SymbolColor = Color.Empty; + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return _SymbolColor; } + set { _SymbolColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return !_SymbolColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + this.SymbolColor = Color.Empty; + } + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get { return _SymbolRealized; } + } + private string _Symbol = "", _SymbolRealized =""; + /// + /// Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return _Symbol; } + set + { + if (value != _Symbol) + { + string oldValue = _Symbol; + _Symbol = value; + OnSymbolChanged(oldValue, value); + } + } + } + /// + /// Called when Symbol property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolChanged(string oldValue, string newValue) + { + if (string.IsNullOrEmpty(newValue)) + _SymbolRealized = ""; + else + _SymbolRealized = Symbols.GetSymbol(newValue); + //OnPropertyChanged(new PropertyChangedEventArgs("Symbol")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return _SymbolSet; } + set + { + if(_SymbolSet!=value) + { + eSymbolSet oldValue = _SymbolSet; + _SymbolSet = value; + OnSymbolSetChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSet property value changes. + /// + /// Indciates old value + /// Indicates new value + protected virtual void OnSymbolSetChanged(eSymbolSet oldValue, eSymbolSet newValue) + { + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + + private float _SymbolSize = 0f; + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(0f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return _SymbolSize; } + set + { + if (value != _SymbolSize) + { + float oldValue = _SymbolSize; + _SymbolSize = value; + OnSymbolSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolSizeChanged(float oldValue, float newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SymbolSize")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + /// + /// Specifies the Button icon. Icons support multiple image sizes and alpha blending. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Specifies the Button icon. Icons support multiple image sizes and alpha blending."), DefaultValue(null)] + public virtual System.Drawing.Icon Icon + { + get + { + return m_Icon; + } + set + { + NeedRecalcSize = true; + m_Icon = value; + this.OnImageChanged(); + OnAppearanceChanged(); + this.Refresh(); + } + } + + private Image _ImageAlt = null; + /// + /// Specifies the Button image which is used when button background is black or very dark. Image is used when button text is white. This is provided for Metro style applications. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Specifies the Button image which is used when button background is black or very dark. Image is used when button text is white. This is provided for Metro style applications."), DefaultValue(null)] + public System.Drawing.Image ImageAlt + { + get + { + return _ImageAlt; + } + set + { + _ImageAlt = value; + OnAppearanceChanged(); + this.Refresh(); + } + } + + /// + /// Specifies the Button image. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("The image that will be displayed on the face of the item."), DefaultValue(null)] + public System.Drawing.Image Image + { + get + { + return m_Image; + } + set + { + NeedRecalcSize = true; + m_Image = value; + this.OnImageChanged(); + OnAppearanceChanged(); + this.Refresh(); + } + } + + /// + /// Specifies the small Button image used by Ribbon control when small image variant is needed because of the automatic button resizing or + /// because the button is on the Quick Access Toolbar. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Specifies the small Button image used by Ribbon control when small image variant is needed"), DefaultValue(null)] + public virtual System.Drawing.Image ImageSmall + { + get + { + return m_ImageSmall; + } + set + { + m_ImageSmall = value; + if (!m_ImageSizeOverride.IsEmpty || UseSmallImageResolved) + { + NeedRecalcSize = true; + OnAppearanceChanged(); + OnImageChanged(); + this.Refresh(); + } + } + } + + private bool UseSmallImageResolved + { + get + { + return m_UseSmallImage; + } + } + + private eButtonImageListSelection _ImageListSizeSelection = eButtonImageListSelection.NotSet; + /// + /// Gets or sets the image size that is used by the button when multiple ImageList controls are used as source for button image. + /// By default ImageList assigned to Images property of parent control is used. Using this property you can selection ImagesMedium or + /// ImagesLarge ImageList to be used as source for image for this button. + /// + [DefaultValue(eButtonImageListSelection.NotSet), Category("Image"), Description("Indicates image size that is used by the button when multiple ImageList controls are used as source for button image.")] + public virtual eButtonImageListSelection ImageListSizeSelection + { + get { return _ImageListSizeSelection; } + set + { + _ImageListSizeSelection = value; + NeedRecalcSize = true; + OnImageChanged(); + this.OnAppearanceChanged(); + } + } + + /// + /// Gets or sets whether button uses the ImageSmall as source of the image displayed on the button if ImageSmall is set to valid image. Default value is false. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool UseSmallImage + { + get { return m_UseSmallImage; } + set + { + if (m_UseSmallImage != value) + { + m_UseSmallImage = value; + if (m_ImageSmall != null) + { + NeedRecalcSize = true; + OnImageChanged(); + this.OnAppearanceChanged(); + } + } + } + } + + + /// + /// Specifies the index of the image for the button if ImageList is used. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The image list image index of the image that will be displayed on the face of the item."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), System.ComponentModel.DefaultValue(-1)] + public int ImageIndex + { + get + { + return m_ImageIndex; + } + set + { + if (m_ImageCachedIdx != null) m_ImageCachedIdx.Dispose(); + m_ImageCachedIdx = null; + if (m_ImageIndex != value) + { + //if(this.GetOwner()==null) + // throw(new System.InvalidOperationException("Owner DotNetBarManager is not set. Add containing bar do the bars collection first.")); + m_ImageIndex = value; + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "ImageIndex"); + if (m_Parent != null) + { + OnImageChanged(); + NeedRecalcSize = true; + this.Refresh(); + } + OnAppearanceChanged(); + } + } + } + + internal void SetImageIndex(int iImageIndex) + { + m_ImageIndex = iImageIndex; + } + + protected override void ScaleItem(SizeF factor) + { + OnImageChanged(); // Force image size re-evaluation + base.ScaleItem(factor); + } + + /// + /// Called when button image has changed. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void OnImageChanged() + { + base.OnImageChanged(); + + StopPulse(); + StopImageAnimation(); + + if (m_DisabledImage != null && !m_DisabledImageCustom) + { + m_DisabledImage.Dispose(); + m_DisabledImage = null; + } + if (m_DisabledIcon != null) + { + m_DisabledIcon.Dispose(); + m_DisabledIcon = null; + } + + CompositeImage img = this.GetImage(ImageState.Default, Color.Black); + if (img != null) + { + if (m_Image != null) + { + IBarImageSize iImageSize = null; + if (_ItemPaintArgs != null) + iImageSize = _ItemPaintArgs.ContainerControl as IBarImageSize; + if (iImageSize == null) iImageSize = this.ContainerControl as IBarImageSize; + eBarImageSize imageListSize = GetImageListSize(iImageSize); + + if (iImageSize != null && imageListSize != eBarImageSize.Default) + { + if (imageListSize == eBarImageSize.Medium) + { + this.ImageSize = new Size(32, 32); + } + else + { + this.ImageSize = new Size(48, 48); + } + } + else + this.ImageSize = new Size(img.Width, img.Height); + } + else + this.ImageSize = new Size(img.Width, img.Height); + + if (img.Image == m_Image) + _CanAnimateImage = ImageAnimator.CanAnimate(m_Image); + else + _CanAnimateImage = false; + + img.Dispose(); + } + else + this.ImageSize = Dpi.Size(ImageItem._InitalImageSize); // This is ImageItem default size + + if (m_Parent != null) + { + ImageItem objParentImageItem = m_Parent as ImageItem; + if (objParentImageItem != null) + { + //if(this.DesignMode) + objParentImageItem.RefreshSubItemImageSize(); + //else + // objParentImageItem.OnSubItemImageSizeChanged(this); + } + } + } + private bool _CanAnimateImage = false; + internal bool CanAnimateImage + { + get + { + return _CanAnimateImage; + } + } + internal bool CurrentlyAnimatingImage + { + get + { + return _CurrentlyAnimatingImage; + } + } + private bool _CurrentlyAnimatingImage = false; + private Image _AnimateImage = null; + internal void StartImageAnimation(Image image) + { + if (!ImageAnimator.CanAnimate(image)) return; + + _CurrentlyAnimatingImage = true; + _AnimateImage = image; + + ImageAnimator.Animate(image, OnFrameChanged); + } + internal void StopImageAnimation() + { + if (_CurrentlyAnimatingImage == true) + { + _CurrentlyAnimatingImage = false; + + Image animateImage = _AnimateImage; + _AnimateImage = null; + + if (animateImage != null) + { + ImageAnimator.StopAnimate(animateImage, OnFrameChanged); + + System.Drawing.Imaging.FrameDimension frameDimensions = + new System.Drawing.Imaging.FrameDimension(animateImage.FrameDimensionsList[0]); + + animateImage.SelectActiveFrame(frameDimensions, 0); + } + } + } + private void OnFrameChanged(object o, EventArgs e) + { + if (_CurrentlyAnimatingImage && this.Visible) + { + this.Refresh(); + this.Update(); + } + else + { + StopImageAnimation(); + } + } + + /// + /// Called when container of the item has changed. + /// + /// Previous item container. + protected internal override void OnContainerChanged(object objOldContainer) + { + if (this.DesignMode || (m_ImageIndex >= 0 || m_Icon != null) && this.ImageSize.Width == ImageItem._InitalImageSize.Width && this.ImageSize.Height == ImageItem._InitalImageSize.Height) + OnImageChanged(); + base.OnContainerChanged(objOldContainer); + } + + /// + /// Specifies the image for the button when mouse is over the item. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("The image that will be displayed when mouse hovers over the item."), DefaultValue(null)] + public virtual System.Drawing.Image HoverImage + { + get + { + return m_HoverImage; + } + set + { + m_HoverImage = value; + OnAppearanceChanged(); + } + } + + /// + /// Specifies the index of the image for the button when mouse is over the item when ImageList is used. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The image list image index of the image that will be displayed when mouse hovers over the item."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), System.ComponentModel.DefaultValue(-1)] + public virtual int HoverImageIndex + { + get + { + return m_HoverImageIndex; + } + set + { + if (m_HoverImageIndex != value) + { + //if(this.GetOwner()==null) + // throw(new System.InvalidOperationException("Owner DotNetBarManager is not set. Add containing bar do the bars collection first.")); + m_HoverImageIndex = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "HoverImageIndex"); + + this.Refresh(); + OnAppearanceChanged(); + } + } + } + + /// + /// Specifies the image for the button when mouse left button is pressed. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("The image that will be displayed when item is pressed."), DefaultValue(null)] + public virtual System.Drawing.Image PressedImage + { + get + { + return m_PressedImage; + } + set + { + m_PressedImage = value; + OnAppearanceChanged(); + } + } + + /// + /// Specifies the index of the image for the button when mouse left button is pressed and ImageList is used. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The image list image index of the image that will be displayed when item is pressed."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), System.ComponentModel.DefaultValue(-1)] + public virtual int PressedImageIndex + { + get + { + return m_PressedImageIndex; + } + set + { + if (m_PressedImageIndex != value) + { + //if(this.GetOwner()==null) + // throw(new System.InvalidOperationException("Owner DotNetBarManager is not set. Add containing bar do the bars collection first.")); + m_PressedImageIndex = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "PressedImageIndex"); + + OnAppearanceChanged(); + this.Refresh(); + } + } + } + + /// + /// Specifies the image for the button when items Enabled property is set to false. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("The image that will be displayed when item is disabled."), DefaultValue(null)] + public System.Drawing.Image DisabledImage + { + get + { + if (!m_DisabledImageCustom) + return null; + return m_DisabledImage; + } + set + { + m_DisabledImage = value; + if (value == null) + m_DisabledImageCustom = false; + else + m_DisabledImageCustom = true; + OnAppearanceChanged(); + } + } + + /// + /// Specifies the index of the image for the button when items Enabled property is set to false and ImageList is used. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The image list image index of the image that will be displayed when item is disabled."), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), System.ComponentModel.DefaultValue(-1)] + public int DisabledImageIndex + { + get + { + return m_DisabledImageIndex; + } + set + { + if (m_DisabledImageIndex != value) + { + if (m_DisabledImage != null) + m_DisabledImage.Dispose(); + m_DisabledImage = null; + //if(this.GetOwner()==null) + // throw(new System.InvalidOperationException("Owner DotNetBarManager is not set. Add containing bar do the bars collection first.")); + m_DisabledImageIndex = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "DisabledImageIndex"); + + this.Refresh(); + } + } + } + + /// + /// Overriden. Draws the item. + /// + /// Item paint arguments. + public override void Paint(ItemPaintArgs p) + { + if (this.SuspendLayout) + return; + + bool oldMouseOver = m_MouseOver; + + m_FadeImageLock.AcquireReaderLock(-1); + try + { + if (m_ImageState2 != null) + m_MouseOver = false; + try + { + _ItemPaintArgs = p; + + if (EffectiveStyle == eDotNetBarStyle.Office2000 && !this.IsThemed) + PaintOffice(p); + else + { + RenderButton(p); + + if (m_ImageState2 != null && !m_IgnoreAlpha) + { + Graphics g = p.Graphics; + Rectangle r = this.DisplayRectangle; + System.Drawing.Imaging.ColorMatrix matrix1 = new System.Drawing.Imaging.ColorMatrix(); + matrix1[3, 3] = (float)((float)m_Alpha / 255); + using (System.Drawing.Imaging.ImageAttributes imageAtt = new System.Drawing.Imaging.ImageAttributes()) + { + imageAtt.SetColorMatrix(matrix1); + g.DrawImage(m_ImageState2, r, 0, 0, r.Width, r.Height, GraphicsUnit.Pixel, imageAtt); + } + return; + } + } + } + finally + { + _ItemPaintArgs = null; + m_MouseOver = oldMouseOver; + } + } + finally + { + m_FadeImageLock.ReleaseReaderLock(); + } + + this.DrawInsertMarker(p.Graphics); + } + + protected virtual void RenderButton(ItemPaintArgs p) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + p.ButtonItemRendererEventArgs.Graphics = p.Graphics; + p.ButtonItemRendererEventArgs.ButtonItem = this; + p.ButtonItemRendererEventArgs.ItemPaintArgs = p; + renderer.DrawButtonItem(p.ButtonItemRendererEventArgs); + } + else + { + ButtonItemPainter painter = PainterFactory.CreateButtonPainter(this); + if (painter != null) + { + painter.PaintButton(this, p); + } + else + { + if (EffectiveStyle == eDotNetBarStyle.Office2000) + PaintOffice(p); + else + PaintDotNet(p); + } + } + if (!string.IsNullOrEmpty(_NotificationMarkText)) + DevComponents.DotNetBar.Rendering.NotificationMarkPainter.Paint(p.Graphics, this.Bounds, _NotificationMarkPosition, + _NotificationMarkText, new Size(_NotificationMarkSize, _NotificationMarkSize), _NotificationMarkOffset, _NotificationMarkColor); + } + + private void PaintDotNet(ItemPaintArgs pa) + { + bool bIsOnMenu = pa.IsOnMenu; + bool bIsOnMenuBar = pa.IsOnMenuBar; + bool bThemed = this.IsThemed; + + if (!bIsOnMenu && !bIsOnMenuBar && bThemed) + { + ThemedButtonItemPainter.PaintButton(this, pa); + return; + } + + bool mouseOver = m_MouseOver; + if (bIsOnMenu && this.Expanded && pa.ContainerControl != null && pa.ContainerControl.Parent != null) + { + if (!pa.ContainerControl.Parent.Bounds.Contains(System.Windows.Forms.Control.MousePosition)) + mouseOver = true; + } + + System.Drawing.Graphics g = pa.Graphics; + + Rectangle rect = Rectangle.Empty; + Rectangle itemRect = new Rectangle(m_Rect.X, m_Rect.Y, m_Rect.Width, m_Rect.Height); + Color textColor = System.Drawing.Color.Empty; + + if (mouseOver && !m_HotForeColor.IsEmpty) + textColor = m_HotForeColor; + else if (!m_ForeColor.IsEmpty) + textColor = m_ForeColor; + else if (mouseOver /*&& m_Checked*/ && !m_Expanded && /*!bIsOnMenu &&*/ m_HotTrackingStyle != eHotTrackingStyle.Image) + textColor = pa.Colors.ItemHotText; + else if (m_Expanded) + textColor = pa.Colors.ItemExpandedText; + else + { + if (bThemed && bIsOnMenuBar && pa.Colors.ItemText == SystemColors.ControlText) + textColor = SystemColors.MenuText; + else + textColor = pa.Colors.ItemText; + } + + Font objFont = null; + + eTextFormat objStringFormat = pa.ButtonStringFormat; + CompositeImage objImage = GetImage(); + System.Drawing.Size imageSize = System.Drawing.Size.Empty; + + if (m_Font != null) + objFont = m_Font; + else + objFont = GetFont(pa, false); + + // Calculate image position + if (objImage != null) + { + imageSize = this.ImageSize;// objImage.Size; + if (!bIsOnMenu && (m_ImagePosition == eImagePosition.Top || m_ImagePosition == eImagePosition.Bottom)) + rect = new Rectangle(m_ImageDrawRect.X, m_ImageDrawRect.Y, itemRect.Width, m_ImageDrawRect.Height); + else + rect = new Rectangle(m_ImageDrawRect.X, m_ImageDrawRect.Y, m_ImageDrawRect.Width, m_ImageDrawRect.Height); + + rect.Offset(itemRect.Left, itemRect.Top); + //if(m_ButtonType==eButtonType.StateButton) + // rect.Offset(STATEBUTTON_SPACING+(m_ImageSize.Width-STATEBUTTON_SPACING)/2+(rect.Width-m_Image.Width*2)/2,(rect.Height-m_Image.Height)/2); + //else + rect.Offset((rect.Width - imageSize.Width) / 2, (rect.Height - imageSize.Height) / 2); + + rect.Width = imageSize.Width; + rect.Height = imageSize.Height; + } + + if (bIsOnMenu) + { + // Draw side bar + if (this.MenuVisibility == eMenuVisibility.VisibleIfRecentlyUsed && !this.RecentlyUsed) + { + if (!pa.Colors.MenuUnusedSide2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(m_Rect.Left, m_Rect.Top, m_ImageDrawRect.Right, m_Rect.Height), pa.Colors.MenuUnusedSide, pa.Colors.MenuUnusedSide2, pa.Colors.MenuUnusedSideGradientAngle); + g.FillRectangle(gradient, m_Rect.Left, m_Rect.Top, m_ImageDrawRect.Right, m_Rect.Height); + gradient.Dispose(); + } + else + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.MenuUnusedSide/*ColorFunctions.SideRecentlyBackColor(g)*/)) + g.FillRectangle(mybrush, m_Rect.Left, m_Rect.Top, m_ImageDrawRect.Right, m_Rect.Height); + } + } + else + { + if (!pa.Colors.MenuSide2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(m_Rect.Left, m_Rect.Top, m_ImageDrawRect.Right, m_Rect.Height), pa.Colors.MenuSide, pa.Colors.MenuSide2, pa.Colors.MenuSideGradientAngle); + g.FillRectangle(gradient, m_Rect.Left, m_Rect.Top, m_ImageDrawRect.Right, m_Rect.Height); + gradient.Dispose(); + } + else + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.MenuSide)) + g.FillRectangle(mybrush, m_Rect.Left, m_Rect.Top, m_ImageDrawRect.Right, m_Rect.Height); + } + } + // Draw Background of the item + //using(SolidBrush mybrush=new SolidBrush(pa.Colors.MenuBackground)) + // g.FillRectangle(mybrush,m_Rect.Left+m_ImageDrawRect.Right,m_Rect.Top,m_Rect.Width-m_ImageDrawRect.Right,m_Rect.Height); + } + else + { + // Draw button background + //if(bIsOnMenuBar) + // g.FillRectangle(SystemBrushes.Control,m_Rect); + //else + // g.FillRectangle(new SolidBrush(ColorFunctions.ToolMenuFocusBackColor(g)),m_Rect); + if (!pa.Colors.ItemBackground.IsEmpty) + { + if (pa.Colors.ItemBackground2.IsEmpty) + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemBackground)) + g.FillRectangle(mybrush, m_Rect); + } + else + { + using (System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(this.DisplayRectangle, pa.Colors.ItemBackground, pa.Colors.ItemBackground2, pa.Colors.ItemBackgroundGradientAngle)) + g.FillRectangle(gradient, this.DisplayRectangle); + } + } + else if (!GetEnabled(pa.ContainerControl) && !pa.Colors.ItemDisabledBackground.IsEmpty) + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemDisabledBackground)) + g.FillRectangle(mybrush, m_Rect); + } + } + + if (GetEnabled(pa.ContainerControl) || this.DesignMode) + { + if (m_Expanded && !bIsOnMenu) + { + // DotNet Style + if (pa.Colors.ItemExpandedBackground2.IsEmpty) + { + Rectangle rBack = new Rectangle(itemRect.Left, itemRect.Top, itemRect.Width, itemRect.Height); + if (pa.Colors.ItemExpandedShadow.IsEmpty) + rBack.Width -= 2; + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemExpandedBackground)) + g.FillRectangle(mybrush, rBack); + } + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(new Rectangle(itemRect.Left, itemRect.Top, itemRect.Width - 2, itemRect.Height), pa.Colors.ItemExpandedBackground, pa.Colors.ItemExpandedBackground2, pa.Colors.ItemExpandedBackgroundGradientAngle); + Rectangle rBack = new Rectangle(itemRect.Left, itemRect.Top, itemRect.Width, itemRect.Height); + if (pa.Colors.ItemExpandedShadow.IsEmpty) + rBack.Width -= 2; + g.FillRectangle(gradient, rBack); + gradient.Dispose(); + } + Point[] p; + if (m_Orientation == eOrientation.Horizontal && this.PopupSide == ePopupSide.Default) + p = new Point[4]; + else + p = new Point[5]; + p[0].X = itemRect.Left; + p[0].Y = itemRect.Top + itemRect.Height - 1; + p[1].X = itemRect.Left; + p[1].Y = itemRect.Top; + if (m_Orientation == eOrientation.Horizontal /*&& !pa.Colors.ItemExpandedShadow.IsEmpty*/) + p[2].X = itemRect.Left + itemRect.Width - 3; + else + p[2].X = itemRect.Left + itemRect.Width - 1; + p[2].Y = itemRect.Top; + if (m_Orientation == eOrientation.Horizontal /*&& !pa.Colors.ItemExpandedShadow.IsEmpty*/) + p[3].X = itemRect.Left + itemRect.Width - 3; + else + p[3].X = itemRect.Left + itemRect.Width - 1; + + p[3].Y = itemRect.Top + itemRect.Height - 1; + if (m_Orientation == eOrientation.Vertical || this.PopupSide != ePopupSide.Default) + { + p[4].X = itemRect.Left; + p[4].Y = itemRect.Top + itemRect.Height - 1; + } + + if (!pa.Colors.ItemExpandedBorder.IsEmpty) + { + using (Pen mypen = new Pen(pa.Colors.ItemExpandedBorder, 1)) + g.DrawLines(mypen, p); + } + // Draw the shadow + if (!pa.Colors.ItemExpandedShadow.IsEmpty && m_Orientation == eOrientation.Horizontal) + { + using (SolidBrush shadow = new SolidBrush(pa.Colors.ItemExpandedShadow)) + g.FillRectangle(shadow, itemRect.Left + itemRect.Width - 2, itemRect.Top + 2, 2, itemRect.Height - 2); // TODO: ADD GRADIENT SHADOW + } + } + + if ((mouseOver && m_HotTrackingStyle != eHotTrackingStyle.None) || m_Expanded && !bIsOnMenu) + { + // Draw Mouse over marker + if (!m_Expanded || bIsOnMenu) + { + Rectangle r = itemRect; + if (bIsOnMenu) + r = new Rectangle(itemRect.Left + 1, itemRect.Top, itemRect.Width - 2, itemRect.Height); + if (this.DesignMode && this.Focused) + { + //g.FillRectangle(new SolidBrush(ColorFunctions.MenuBackColor(g)),r); + r = m_Rect; + r.Inflate(-1, -1); + DesignTime.DrawDesignTimeSelection(g, r, pa.Colors.ItemDesignTimeBorder); + } + else + { + if (m_MouseDown) + { + if (m_HotTrackingStyle == eHotTrackingStyle.Image) + { + r = rect; + r.Inflate(2, 2); + } + if (pa.Colors.ItemPressedBackground2.IsEmpty) + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemPressedBackground/*ColorFunctions.PressedBackColor(g)*/)) + g.FillRectangle(mybrush, r); + } + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemPressedBackground, pa.Colors.ItemPressedBackground2, pa.Colors.ItemPressedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + } + using (Pen mypen = new Pen(pa.Colors.ItemPressedBorder, 1)) + NativeFunctions.DrawRectangle(g, mypen, r); + } + else if (m_HotTrackingStyle == eHotTrackingStyle.Image && !rect.IsEmpty) + { + Rectangle rImage = rect; + rImage.Inflate(2, 2); + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(rImage, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, rImage); + gradient.Dispose(); + } + else + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemHotBackground/*ColorFunctions.HoverBackColor(g)*/)) + g.FillRectangle(mybrush, rImage); + } + using (Pen mypen = new Pen(pa.Colors.ItemHotBorder, 1)) + NativeFunctions.DrawRectangle(g, mypen, rImage); + } + else + { + if (!pa.Colors.ItemCheckedBackground2.IsEmpty && m_Checked) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemCheckedBackground2, pa.Colors.ItemCheckedBackground, pa.Colors.ItemCheckedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + } + else + { + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + } + else + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemHotBackground)) + g.FillRectangle(mybrush, r); + } + } + using (Pen mypen = new Pen(pa.Colors.ItemHotBorder, 1)) + NativeFunctions.DrawRectangle(g, mypen, r); + } + } + // TODO: Beta 2 Hack for DrawRectangle Possible bug, need to verify + //r.Width-=1; + //r.Height-=1; + //g.DrawRectangle(SystemPens.Highlight,r); + } + + // Image needs shadow when it has focus + if (objImage != null && m_ButtonStyle != eButtonStyle.TextOnlyAlways) + { + // We needed the image to stay "up" when button is expanded too so we removed the checking here + //if(m_MouseDown || (m_Expanded && !bIsOnMenu) || m_Checked && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + if (m_MouseDown || m_Checked && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + { + objImage.DrawImage(g, rect);// g.DrawImage(objImage,rect);//,0,0,imageSize.Width,imageSize.Height,System.Drawing.GraphicsUnit.Pixel); + } + else + { + if (NativeFunctions.ColorDepth >= 16 && EffectiveStyle != eDotNetBarStyle.Office2003) + { + float[][] array = new float[5][]; + array[0] = new float[5] { 0, 0, 0, 0, 0 }; + array[1] = new float[5] { 0, 0, 0, 0, 0 }; + array[2] = new float[5] { 0, 0, 0, 0, 0 }; + array[3] = new float[5] { .5f, .5f, .5f, .5f, 0 }; + array[4] = new float[5] { 0, 0, 0, 0, 0 }; + System.Drawing.Imaging.ColorMatrix grayMatrix = new System.Drawing.Imaging.ColorMatrix(array); + System.Drawing.Imaging.ImageAttributes disabledImageAttr = new System.Drawing.Imaging.ImageAttributes(); + disabledImageAttr.ClearColorKey(); + disabledImageAttr.SetColorMatrix(grayMatrix); + + rect.Offset(1, 1); + //g.DrawImage(objImage,rect,0,0,objImage.Width,objImage.Height,GraphicsUnit.Pixel,disabledImageAttr); + objImage.DrawImage(g, rect, 0, 0, objImage.Width, objImage.Height, GraphicsUnit.Pixel, disabledImageAttr); + rect.Offset(-2, -2); + //g.DrawImage(objImage,rect); + objImage.DrawImage(g, rect); + } + else + { + if (EffectiveStyle == eDotNetBarStyle.OfficeXP) + rect.Offset(-1, -1); + //g.DrawImage(objImage,rect); + objImage.DrawImage(g, rect); + } + } + } + + if (bIsOnMenu && this.IsOnCustomizeMenu && m_Visible && !this.SystemItem) + { + // Draw check box if this item is visible + Rectangle r = new Rectangle(m_Rect.Left, m_Rect.Top, m_Rect.Height, m_Rect.Height); + r.Inflate(-1, -1); + //Color clr=g.GetNearestColor(Color.FromArgb(45,SystemColors.Highlight)); + Color clr = pa.Colors.ItemCheckedBackground/*ColorFunctions.CheckBoxBackColor(g)*/; + if (mouseOver && !pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + } + else + { + if (mouseOver) + clr = pa.Colors.ItemHotBackground; + + if (!pa.Colors.ItemCheckedBackground2.IsEmpty && !mouseOver) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemCheckedBackground, pa.Colors.ItemCheckedBackground2, pa.Colors.ItemCheckedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + } + else + { + SolidBrush objBrush = new SolidBrush(clr); + g.FillRectangle(objBrush, r); + objBrush.Dispose(); + } + } + } + } + else + { + if (objImage != null && m_ButtonStyle != eButtonStyle.TextOnlyAlways) + { + if (!m_Checked || this.IsOnCustomizeMenu) + { + if (m_HotTrackingStyle != eHotTrackingStyle.Color) + { + objImage.DrawImage(g, rect); + } + else + { + // Draw gray-scale image for this hover style... + float[][] array = new float[5][]; + array[0] = new float[5] { 0.2125f, 0.2125f, 0.2125f, 0, 0 }; + array[1] = new float[5] { 0.5f, 0.5f, 0.5f, 0, 0 }; + array[2] = new float[5] { 0.0361f, 0.0361f, 0.0361f, 0, 0 }; + array[3] = new float[5] { 0, 0, 0, 1, 0 }; + array[4] = new float[5] { 0.2f, 0.2f, 0.2f, 0, 1 }; + System.Drawing.Imaging.ColorMatrix grayMatrix = new System.Drawing.Imaging.ColorMatrix(array); + System.Drawing.Imaging.ImageAttributes att = new System.Drawing.Imaging.ImageAttributes(); + att.SetColorMatrix(grayMatrix); + //g.DrawImage(objImage,rect,0,0,objImage.Width,objImage.Height,GraphicsUnit.Pixel,att); + objImage.DrawImage(g, rect, 0, 0, objImage.Width, objImage.Height, GraphicsUnit.Pixel, att); + } + } + else + { + if ((m_Checked && bIsOnMenu || !this.Expanded) && !this.IsOnCustomizeDialog) + { + Rectangle r; + if (bIsOnMenu) + r = new Rectangle(m_Rect.X + 1, m_Rect.Y, m_ImageDrawRect.Width - 2, m_Rect.Height); + else if (m_HotTrackingStyle == eHotTrackingStyle.Image) + { + r = rect; + r.Inflate(2, 2); + } + else + r = m_Rect; + if (bIsOnMenu) + r.Inflate(-1, -1); + Color clr; + if (mouseOver && m_HotTrackingStyle != eHotTrackingStyle.None) + { + if (m_Checked && !pa.Colors.ItemCheckedBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemCheckedBackground2, pa.Colors.ItemCheckedBackground, pa.Colors.ItemCheckedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + clr = System.Drawing.Color.Empty; + } + else + { + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + clr = System.Drawing.Color.Empty; + } + else + clr = System.Windows.Forms.ControlPaint.Dark(pa.Colors.ItemHotBackground); + } + } + else + { + if (!pa.Colors.ItemCheckedBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemCheckedBackground, pa.Colors.ItemCheckedBackground2, pa.Colors.ItemCheckedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + clr = System.Drawing.Color.Empty; + } + else + clr = pa.Colors.ItemCheckedBackground/*ColorFunctions.CheckBoxBackColor(g)*/; + } + if (!clr.IsEmpty) + { + SolidBrush objBrush = new SolidBrush(clr); + g.FillRectangle(objBrush, r); + objBrush.Dispose(); + } + } + objImage.DrawImage(g, rect); + } + } + if (bIsOnMenu && this.IsOnCustomizeMenu && m_Visible && !this.SystemItem) + { + // Draw check box if this item is visible + Rectangle r = new Rectangle(m_Rect.Left, m_Rect.Top, m_Rect.Height, m_Rect.Height); + r.Inflate(-1, -1); + //Color clr=g.GetNearestColor(Color.FromArgb(96,ColorFunctions.HoverBackColor())); + if (pa.Colors.ItemCheckedBackground2.IsEmpty) + { + Color clr = pa.Colors.ItemCheckedBackground/*ColorFunctions.CheckBoxBackColor(g)*/; + SolidBrush objBrush = new SolidBrush(clr); + g.FillRectangle(objBrush, r); + objBrush.Dispose(); + } + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemCheckedBackground, pa.Colors.ItemCheckedBackground2, pa.Colors.ItemCheckedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + } + } + else if (m_Checked && !bIsOnMenu && objImage == null) + { + Rectangle r = m_Rect; + // TODO: In 9188 GetNearestColor on the Graphics that were taken directly from Paint event did not work correctly. Check in future versions... + // Draw background + //Color clr=g.GetNearestColor(Color.FromArgb(96,ColorFunctions.HoverBackColor(g))); + Color clr; + if (mouseOver && m_HotTrackingStyle != eHotTrackingStyle.None) + { + if (!pa.Colors.ItemCheckedBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemCheckedBackground2, pa.Colors.ItemCheckedBackground, pa.Colors.ItemCheckedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + clr = System.Drawing.Color.Empty; + } + else + { + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + clr = System.Drawing.Color.Empty; + } + else + clr = pa.Colors.ItemHotBackground; + } + } + else + { + if (!pa.Colors.ItemCheckedBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemCheckedBackground, pa.Colors.ItemCheckedBackground2, pa.Colors.ItemCheckedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + clr = System.Drawing.Color.Empty; + } + else + clr = pa.Colors.ItemCheckedBackground; + } + if (!clr.IsEmpty) + { + SolidBrush objBrush = new SolidBrush(clr); + g.FillRectangle(objBrush, r); + objBrush.Dispose(); + } + } + } + + if (bIsOnMenu && this.IsOnCustomizeMenu && m_Visible && !this.SystemItem) + { + Rectangle r = new Rectangle(m_Rect.Left, m_Rect.Top, m_Rect.Height, m_Rect.Height); + r.Inflate(-1, -1); + //Color clr=g.GetNearestColor(Color.FromArgb(200,SystemColors.Highlight)); + Color clr = pa.Colors.ItemCheckedBorder/*SystemColors.Highlight*/; + Pen objPen = new Pen(clr, 1); + // TODO: Beta 2 fix --> g.DrawRectangle(objPen,r); + NativeFunctions.DrawRectangle(g, objPen, r); + + objPen.Dispose(); + objPen = new Pen(pa.Colors.ItemCheckedText); + // Draw checker... + Point[] pt = new Point[3]; + pt[0].X = r.Left + (r.Width - 5) / 2 - 1; + pt[0].Y = r.Top + (r.Height - 6) / 2 + 3; + pt[1].X = pt[0].X + 2; + pt[1].Y = pt[0].Y + 2; + pt[2].X = pt[1].X + 4; + pt[2].Y = pt[1].Y - 4; + g.DrawLines(objPen/*SystemPens.ControlText*/, pt); + pt[0].X++; + pt[1].X++; + pt[2].X++; + g.DrawLines(objPen/*SystemPens.ControlText*/, pt); + objPen.Dispose(); + } + + if (m_Checked && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + { + Rectangle r; + + if (bIsOnMenu) + r = new Rectangle(m_Rect.X + 1, m_Rect.Y, m_ImageDrawRect.Width - 2, m_Rect.Height); + else if (m_HotTrackingStyle == eHotTrackingStyle.Image) + { + r = rect; + r.Inflate(2, 2); + } + else + r = new Rectangle(m_Rect.X, m_Rect.Y, m_Rect.Width, m_Rect.Height); + if (bIsOnMenu) + r.Inflate(-1, -1); + + // Draw line around... + if (bIsOnMenu || !this.Expanded) + { + if (objImage == null || m_ButtonStyle == eButtonStyle.TextOnlyAlways) + { + if (mouseOver) + { + if (m_Checked && !pa.Colors.ItemCheckedBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemCheckedBackground2, pa.Colors.ItemCheckedBackground, pa.Colors.ItemCheckedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + } + else + { + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + } + else + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemHotBackground)) + g.FillRectangle(mybrush, r); + } + } + } + else + { + if (pa.Colors.ItemCheckedBackground2.IsEmpty) + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemCheckedBackground)) + g.FillRectangle(mybrush, r); + } + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(r, pa.Colors.ItemCheckedBackground, pa.Colors.ItemCheckedBackground2, pa.Colors.ItemCheckedBackgroundGradientAngle); + g.FillRectangle(gradient, r); + gradient.Dispose(); + } + } + } + + //Color clr=g.GetNearestColor(Color.FromArgb(200,SystemColors.Highlight)); + Color clr = pa.Colors.ItemCheckedBorder/*SystemColors.Highlight*/; + Pen objPen = new Pen(clr, 1); + // TODO: Beta 2 fix ---> g.DrawRectangle(objPen,r); + NativeFunctions.DrawRectangle(g, objPen, r); + + objPen.Dispose(); + } + + if ((objImage == null || m_ButtonStyle == eButtonStyle.TextOnlyAlways) && bIsOnMenu) + { + // Draw checker... + Pen pen = new Pen(pa.Colors.ItemCheckedText); + Point[] pt = new Point[3]; + pt[0].X = r.Left + (r.Width - 5) / 2 - 1; + pt[0].Y = r.Top + (r.Height - 6) / 2 + 3; + pt[1].X = pt[0].X + 2; + pt[1].Y = pt[0].Y + 2; + pt[2].X = pt[1].X + 4; + pt[2].Y = pt[1].Y - 4; + g.DrawLines(pen/*SystemPens.ControlText*/, pt); + pt[0].X++; + //pt[0].Y + pt[1].X++; + //pt[1].Y; + pt[2].X++; + //pt[2].Y; + g.DrawLines(pen/*SystemPens.ControlText*/, pt); + pen.Dispose(); + } + } + } + else + { + if (bIsOnMenu && mouseOver && m_HotTrackingStyle == eHotTrackingStyle.Default) + { + Rectangle r = new Rectangle(itemRect.Left + 1, itemRect.Top, itemRect.Width - 2, itemRect.Height); + using (Pen mypen = new Pen(pa.Colors.ItemHotBorder, 1)) + NativeFunctions.DrawRectangle(g, mypen, r); + } + + // Replicated code from above to draw the item checked box + if (m_Checked && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + { + Rectangle r; + + if (bIsOnMenu) + r = new Rectangle(m_Rect.X + 1, m_Rect.Y, m_ImageDrawRect.Width - 2, m_Rect.Height); + else if (m_HotTrackingStyle == eHotTrackingStyle.Image) + { + r = rect; + r.Inflate(2, 2); + } + else + r = new Rectangle(m_Rect.X, m_Rect.Y, m_Rect.Width, m_Rect.Height); + if (bIsOnMenu) + r.Inflate(-1, -1); + + // Draw line around... + if (bIsOnMenu || !this.Expanded) + { + Color clr = pa.Colors.ItemDisabledText; + Pen objPen = new Pen(clr, 1); + NativeFunctions.DrawRectangle(g, objPen, r); + objPen.Dispose(); + } + + if ((objImage == null || m_ButtonStyle == eButtonStyle.TextOnlyAlways) && bIsOnMenu) + { + // Draw checker... + Pen pen = new Pen(pa.Colors.ItemDisabledText); + Point[] pt = new Point[3]; + pt[0].X = r.Left + (r.Width - 5) / 2 - 1; + pt[0].Y = r.Top + (r.Height - 6) / 2 + 3; + pt[1].X = pt[0].X + 2; + pt[1].Y = pt[0].Y + 2; + pt[2].X = pt[1].X + 4; + pt[2].Y = pt[1].Y - 4; + g.DrawLines(pen, pt); + pt[0].X++; + //pt[0].Y + pt[1].X++; + //pt[1].Y; + pt[2].X++; + //pt[2].Y; + g.DrawLines(pen, pt); + pen.Dispose(); + } + } + textColor = pa.Colors.ItemDisabledText; + if (objImage != null && m_ButtonStyle != eButtonStyle.TextOnlyAlways) + { + // Draw disabled image + objImage.DrawImage(g, rect); + } + } + + // Draw menu item text + if (bIsOnMenu || m_ButtonStyle != eButtonStyle.Default || objImage == null || (!bIsOnMenu && (m_ImagePosition == eImagePosition.Top || m_ImagePosition == eImagePosition.Bottom)) /*|| !this.IsOnBar*/) // Commented out becouse it caused text to be drawn if item is not on bar no matter what + { + if (bIsOnMenu) + rect = new Rectangle(m_TextDrawRect.X, m_TextDrawRect.Y, itemRect.Width - m_ImageDrawRect.Right - 26, m_TextDrawRect.Height); + else + { + rect = m_TextDrawRect; + if (m_ImagePosition == eImagePosition.Top || m_ImagePosition == eImagePosition.Bottom) + { + if (m_Orientation == eOrientation.Vertical) + { + rect = new Rectangle(m_TextDrawRect.X, m_TextDrawRect.Y, m_TextDrawRect.Width, m_TextDrawRect.Height); + } + else + { + rect = new Rectangle(m_TextDrawRect.X, m_TextDrawRect.Y, itemRect.Width, m_TextDrawRect.Height); + if ((this.SubItems.Count > 0 || this.PopupType == ePopupType.Container) && this.ShowSubItems) + rect.Width -= 10; + } + + objStringFormat |= eTextFormat.HorizontalCenter; + } + else if (bIsOnMenuBar && objImage == null) + objStringFormat |= eTextFormat.HorizontalCenter; + + if (m_MouseDown && m_HotTrackingStyle != eHotTrackingStyle.Image) + { + if (m_ForeColor.IsEmpty) + { + textColor = pa.Colors.ItemPressedText; + } + else + { + textColor = System.Windows.Forms.ControlPaint.Light(m_ForeColor); + } + } + } + + rect.Offset(itemRect.Left, itemRect.Top); + + if (m_Orientation == eOrientation.Vertical && !bIsOnMenu) + { + g.RotateTransform(90); + TextDrawing.DrawStringLegacy(g, m_Text, objFont, textColor, new Rectangle(rect.Top, -rect.Right, rect.Height, rect.Width), objStringFormat); + g.ResetTransform(); + } + else + { + if (rect.Right > m_Rect.Right) + rect.Width = m_Rect.Right - rect.Left; + TextDrawing.DrawString(g, m_Text, objFont, textColor, rect, objStringFormat); + if (!this.DesignMode && this.Focused && !bIsOnMenu && !bIsOnMenuBar) + { + //SizeF szf=g.MeasureString(m_Text,objFont,rect.Width,objStringFormat); + Rectangle r = rect; + //r.Width=(int)Math.Ceiling(szf.Width); + //r.Height=(int)Math.Ceiling(szf.Height); + //r.Inflate(1,1); + System.Windows.Forms.ControlPaint.DrawFocusRectangle(g, r); + } + } + + } + + // Draw Shortcut text if needed + if (this.DrawShortcutText != "" && bIsOnMenu && !this.IsOnCustomizeDialog) + { + objStringFormat |= eTextFormat.HidePrefix | eTextFormat.Right; + TextDrawing.DrawString(g, this.DrawShortcutText, objFont, textColor, rect, objStringFormat); + } + + // If it has subitems draw the triangle to indicate that + if ((this.SubItems.Count > 0 || this.PopupType == ePopupType.Container) && this.ShowSubItems) + { + if (bIsOnMenu) + { + Point[] p = new Point[3]; + p[0].X = itemRect.Left + itemRect.Width - 12; + p[0].Y = itemRect.Top + (itemRect.Height - 8) / 2; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 8; + p[2].X = p[0].X + 4; + p[2].Y = p[0].Y + 4; + using (SolidBrush brush = new SolidBrush(textColor)) + g.FillPolygon(brush, p); + } + else if (!m_SubItemsRect.IsEmpty) + { + if (GetEnabled(pa.ContainerControl) && ((mouseOver || m_Checked) && !m_Expanded && m_HotTrackingStyle != eHotTrackingStyle.None && m_HotTrackingStyle != eHotTrackingStyle.Image)) + { + if (m_Orientation == eOrientation.Horizontal) + { + using (Pen mypen = new Pen(pa.Colors.ItemHotBorder)) + g.DrawLine(mypen/*SystemPens.Highlight*/, itemRect.Left + m_SubItemsRect.Left, itemRect.Top, itemRect.Left + m_SubItemsRect.Left, itemRect.Bottom - 1); + } + else + { + using (Pen mypen = new Pen(pa.Colors.ItemHotBorder)) + g.DrawLine(mypen/*SystemPens.Highlight*/, itemRect.Left, itemRect.Top + m_SubItemsRect.Top, itemRect.Right - 2, itemRect.Top + m_SubItemsRect.Top); + } + } + Point[] p = new Point[3]; + if (this.PopupSide == ePopupSide.Default) + { + if (m_Orientation == eOrientation.Horizontal) + { + p[0].X = itemRect.Left + m_SubItemsRect.Left + (m_SubItemsRect.Width - 5) / 2; + p[0].Y = itemRect.Top + (m_SubItemsRect.Height - 3) / 2 + 1; + p[1].X = p[0].X + 5; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 2; + p[2].Y = p[0].Y + 3; + } + else + { + p[0].X = itemRect.Left + (m_SubItemsRect.Width - 3) / 2 + 1; + p[0].Y = itemRect.Top + m_SubItemsRect.Top + (m_SubItemsRect.Height - 5) / 2; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X - 3; + p[2].Y = p[0].Y + 3; + } + } + else + { + switch (this.PopupSide) + { + case ePopupSide.Left: + { + p[0].X = itemRect.Left + m_SubItemsRect.Left + m_SubItemsRect.Width / 2; + p[0].Y = itemRect.Top + m_SubItemsRect.Height / 2 - 3; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X + 3; + p[2].Y = p[0].Y + 3; + break; + } + case ePopupSide.Right: + { + p[0].X = itemRect.Left + m_SubItemsRect.Left + m_SubItemsRect.Width / 2 + 3; + p[0].Y = itemRect.Top + m_SubItemsRect.Height / 2 - 3; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X - 3; + p[2].Y = p[0].Y + 3; + break; + } + case ePopupSide.Top: + { + p[0].X = itemRect.Left + m_SubItemsRect.Left + (m_SubItemsRect.Width - 5) / 2; + p[0].Y = itemRect.Top + (m_SubItemsRect.Height - 3) / 2 + 4; + p[1].X = p[0].X + 6; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 3; + p[2].Y = p[0].Y - 4; + break; + } + case ePopupSide.Bottom: + { + p[0].X = itemRect.Left + m_SubItemsRect.Left + (m_SubItemsRect.Width - 5) / 2 + 1; + p[0].Y = itemRect.Top + (m_SubItemsRect.Height - 3) / 2 + 1; + p[1].X = p[0].X + 5; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 2; + p[2].Y = p[0].Y + 3; + break; + } + } + } + if (GetEnabled(pa.ContainerControl)) + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemText)) + g.FillPolygon(mybrush/*SystemBrushes.ControlText*/, p); + } + else + { + using (SolidBrush mybrush = new SolidBrush(pa.Colors.ItemDisabledText)) + g.FillPolygon(mybrush/*SystemBrushes.ControlDark*/, p); + } + } + } + + if (this.Focused && this.DesignMode) + { + Rectangle r = itemRect; + r.Inflate(-1, -1); + DesignTime.DrawDesignTimeSelection(g, r, pa.Colors.ItemDesignTimeBorder); + } + + if (objImage != null) + objImage.Dispose(); + } + + internal bool IgnoreAlpha + { + get { return m_IgnoreAlpha; } + set { m_IgnoreAlpha = value; } + } + + private void PaintThemed(ItemPaintArgs pa) + { + System.Drawing.Graphics g = pa.Graphics; + ThemeToolbar theme = pa.ThemeToolbar; + ThemeToolbarParts part = ThemeToolbarParts.Button; + ThemeToolbarStates state = ThemeToolbarStates.Normal; + eTextFormat format = pa.ButtonStringFormat; //GetStringFormat(); + Color textColor = SystemColors.ControlText; + + Rectangle rectImage = Rectangle.Empty; + Rectangle itemRect = m_Rect; + + Font font = null; + CompositeImage image = GetImage(); + + if (m_Font != null) + font = m_Font; + else + font = GetFont(pa, false); + + bool bSplitButton = (this.SubItems.Count > 0 || this.PopupType == ePopupType.Container) && this.ShowSubItems && !m_SubItemsRect.IsEmpty; + + if (bSplitButton) + part = ThemeToolbarParts.SplitButton; + + // Calculate image position + if (image != null) + { + if (m_ImagePosition == eImagePosition.Top || m_ImagePosition == eImagePosition.Bottom) + rectImage = new Rectangle(m_ImageDrawRect.X, m_ImageDrawRect.Y, itemRect.Width, m_ImageDrawRect.Height); + else + rectImage = new Rectangle(m_ImageDrawRect.X, m_ImageDrawRect.Y, m_ImageDrawRect.Width, m_ImageDrawRect.Height); + + rectImage.Offset(itemRect.Left, itemRect.Top); + rectImage.Offset((rectImage.Width - this.ImageSize.Width) / 2, (rectImage.Height - this.ImageSize.Height) / 2); + rectImage.Width = this.ImageSize.Width; + rectImage.Height = this.ImageSize.Height; + } + + // Set the state and text brush + if (!GetEnabled(pa.ContainerControl)) + { + state = ThemeToolbarStates.Disabled; + textColor = pa.Colors.ItemDisabledText; + } + else if (m_MouseDown) + { + state = ThemeToolbarStates.Pressed; + textColor = pa.Colors.ItemPressedText; + } + else if (m_MouseOver && m_Checked) + { + state = ThemeToolbarStates.HotChecked; + textColor = pa.Colors.ItemHotText; + } + else if (m_MouseOver || m_Expanded) + { + state = ThemeToolbarStates.Hot; + textColor = pa.Colors.ItemHotText; + } + else if (m_Checked) + { + state = ThemeToolbarStates.Checked; + textColor = pa.Colors.ItemCheckedText; + } + else + textColor = pa.Colors.ItemText; + + Rectangle backRect = m_Rect; + if (m_HotTrackingStyle == eHotTrackingStyle.Image && image != null) + { + backRect = rectImage; + backRect.Inflate(3, 3); + } + else if (bSplitButton) + { + backRect.Width = backRect.Width - m_SubItemsRect.Width; + } + + // Draw Button Background + if (m_HotTrackingStyle != eHotTrackingStyle.None) + { + theme.DrawBackground(g, part, state, backRect); + } + + // Draw Image + if (image != null && m_ButtonStyle != eButtonStyle.TextOnlyAlways) + { + if (state == ThemeToolbarStates.Normal && m_HotTrackingStyle == eHotTrackingStyle.Color) + { + // Draw gray-scale image for this hover style... + float[][] array = new float[5][]; + array[0] = new float[5] { 0.2125f, 0.2125f, 0.2125f, 0, 0 }; + array[1] = new float[5] { 0.5f, 0.5f, 0.5f, 0, 0 }; + array[2] = new float[5] { 0.0361f, 0.0361f, 0.0361f, 0, 0 }; + array[3] = new float[5] { 0, 0, 0, 1, 0 }; + array[4] = new float[5] { 0.2f, 0.2f, 0.2f, 0, 1 }; + System.Drawing.Imaging.ColorMatrix grayMatrix = new System.Drawing.Imaging.ColorMatrix(array); + System.Drawing.Imaging.ImageAttributes att = new System.Drawing.Imaging.ImageAttributes(); + att.SetColorMatrix(grayMatrix); + //g.DrawImage(image,rectImage,0,0,image.Width,image.Height,GraphicsUnit.Pixel,att); + image.DrawImage(g, rectImage, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, att); + } + else if (state == ThemeToolbarStates.Normal && !image.IsIcon) + { + // Draw image little bit lighter, I decied to use gamma it is easy + System.Drawing.Imaging.ImageAttributes lightImageAttr = new System.Drawing.Imaging.ImageAttributes(); + lightImageAttr.SetGamma(.7f, System.Drawing.Imaging.ColorAdjustType.Bitmap); + //g.DrawImage(image,rectImage,0,0,image.Width,image.Height,GraphicsUnit.Pixel,lightImageAttr); + image.DrawImage(g, rectImage, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, lightImageAttr); + } + else + { + image.DrawImage(g, rectImage); + } + } + + // Draw Text + if (m_ButtonStyle == eButtonStyle.ImageAndText || m_ButtonStyle == eButtonStyle.TextOnlyAlways || image == null /*|| !this.IsOnBar*/) // Commented out becouse it caused text to be drawn if item is not on bar no matter what + { + Rectangle rectText = m_TextDrawRect; + if (m_ImagePosition == eImagePosition.Top || m_ImagePosition == eImagePosition.Bottom) + { + if (m_Orientation == eOrientation.Vertical) + { + rectText = new Rectangle(m_TextDrawRect.X, m_TextDrawRect.Y, m_TextDrawRect.Width, m_TextDrawRect.Height); + } + else + { + rectText = new Rectangle(m_TextDrawRect.X, m_TextDrawRect.Y, itemRect.Width, m_TextDrawRect.Height); + if ((this.SubItems.Count > 0 || this.PopupType == ePopupType.Container) && this.ShowSubItems) + rectText.Width -= 10; + } + format |= eTextFormat.HorizontalCenter; + } + + rectText.Offset(itemRect.Left, itemRect.Top); + + if (m_Orientation == eOrientation.Vertical) + { + g.RotateTransform(90); + TextDrawing.DrawStringLegacy(g, m_Text, font, textColor, new Rectangle(rectText.Top, -rectText.Right, rectText.Height, rectText.Width), format); + g.ResetTransform(); + } + else + { + if (rectText.Right > m_Rect.Right) + rectText.Width = m_Rect.Right - rectText.Left; + TextDrawing.DrawString(g, m_Text, font, textColor, rectText, format); + if (!this.DesignMode && this.Focused && !pa.IsOnMenu && !pa.IsOnMenuBar) + { + //SizeF szf=g.MeasureString(m_Text,font,rectText.Width,format); + Rectangle r = rectText; + //r.Width=(int)Math.Ceiling(szf.Width); + //r.Height=(int)Math.Ceiling(szf.Height); + //r.Inflate(1,1); + System.Windows.Forms.ControlPaint.DrawFocusRectangle(g, r); + } + } + } + + // If it has subitems draw the triangle to indicate that + if (bSplitButton) + { + part = ThemeToolbarParts.SplitButtonDropDown; + + if (!GetEnabled(pa.ContainerControl)) + state = ThemeToolbarStates.Disabled; + else + state = ThemeToolbarStates.Normal; + + if (m_HotTrackingStyle != eHotTrackingStyle.None && m_HotTrackingStyle != eHotTrackingStyle.Image && GetEnabled(pa.ContainerControl)) + { + if (m_Expanded || m_MouseDown) + state = ThemeToolbarStates.Pressed; + else if (m_MouseOver && m_Checked) + state = ThemeToolbarStates.HotChecked; + else if (m_Checked) + state = ThemeToolbarStates.Checked; + else if (m_MouseOver) + state = ThemeToolbarStates.Hot; + } + + if (m_Orientation == eOrientation.Horizontal) + { + Rectangle r = m_SubItemsRect; + r.Offset(itemRect.X, itemRect.Y); + theme.DrawBackground(g, part, state, r); + } + else + { + Rectangle r = m_SubItemsRect; + r.Offset(itemRect.X, itemRect.Y); + theme.DrawBackground(g, part, state, r); + } + //g.DrawLine(new Pen(pa.Colors.ItemHotBorder)/*SystemPens.Highlight*/,itemRect.Left,itemRect.Top+m_SubItemsRect.Top,itemRect.Right-2,itemRect.Top+m_SubItemsRect.Top); + } + + if (this.Focused && this.DesignMode) + { + Rectangle r = itemRect; + r.Inflate(-1, -1); + DesignTime.DrawDesignTimeSelection(g, r, pa.Colors.ItemDesignTimeBorder); + } + + if (image != null) + image.Dispose(); + } + + private void PaintOffice(ItemPaintArgs pa) + { + System.Drawing.Graphics g = pa.Graphics; + Rectangle rect = Rectangle.Empty; + Rectangle itemRect = m_Rect; + Rectangle rTmp = Rectangle.Empty; + Color textColor = SystemColors.ControlText; + Color color3d = SystemColors.Control; + + if (m_Parent is GenericItemContainer && !((GenericItemContainer)m_Parent).BackColor.IsEmpty) + color3d = ((GenericItemContainer)m_Parent).BackColor; + else if (m_Parent is SideBarPanelItem && !((SideBarPanelItem)m_Parent).BackgroundStyle.BackColor1.IsEmpty) + color3d = ((SideBarPanelItem)m_Parent).BackgroundStyle.BackColor1.GetCompositeColor(); + + if (m_MouseOver && !m_HotForeColor.IsEmpty) + textColor = m_HotForeColor; + else if (!m_ForeColor.IsEmpty) + textColor = m_ForeColor; + + Font objFont = null; + bool bIsOnMenu = pa.IsOnMenu; + bool buttonX = pa.ContainerControl is ButtonX; + //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + //g.TextRenderingHint=System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + eTextFormat objStringFormat = pa.ButtonStringFormat; + CompositeImage objImage = GetImage(); + + if (m_Font != null) + objFont = m_Font; + else + objFont = GetFont(pa, false); + + // Calculate image position + if (objImage != null) + { + + if (!bIsOnMenu && (m_ImagePosition == eImagePosition.Top || m_ImagePosition == eImagePosition.Bottom)) + rect = new Rectangle(m_ImageDrawRect.X, m_ImageDrawRect.Y + 1, itemRect.Width, m_ImageDrawRect.Height); + else + rect = m_ImageDrawRect; //new Rectangle(m_ImageDrawRect.X,m_ImageDrawRect.Y,m_ImageDrawRect.Width,m_ImageDrawRect.Height); + + rect.Offset(itemRect.Left, itemRect.Top); + //if(m_ButtonType==eButtonType.StateButton) + // rect.Offset(STATEBUTTON_SPACING+(m_ImageSize.Width-STATEBUTTON_SPACING)/2+(rect.Width-m_Image.Width*2)/2,(rect.Height-m_Image.Height)/2); + //else + rect.Offset((rect.Width - this.ImageSize.Width) / 2, (rect.Height - this.ImageSize.Height) / 2); + + rect.Width = this.ImageSize.Width; + rect.Height = this.ImageSize.Height; + } + + // Draw background + if (bIsOnMenu && !this.DesignMode && this.MenuVisibility == eMenuVisibility.VisibleIfRecentlyUsed && !this.RecentlyUsed) + g.FillRectangle(new SolidBrush(ColorFunctions.RecentlyUsedOfficeBackColor()), m_Rect); + else if (buttonX) + { + ButtonState state = ButtonState.Normal; + if (m_MouseDown) + state = ButtonState.Pushed; + else if (m_Checked || m_Expanded) + state = ButtonState.Checked; + ControlPaint.DrawButton(g, itemRect, state); + } + //else + // g.FillRectangle(SystemBrushes.Control,m_Rect); + + if (GetEnabled(pa.ContainerControl) || this.DesignMode) + { + if (m_Expanded && !bIsOnMenu) + { + // Office 2000 Style + g.FillRectangle(SystemBrushes.Control, itemRect); + //System.Windows.Forms.ControlPaint.DrawBorder3D(g,itemRect,System.Windows.Forms.Border3DStyle.SunkenOuter,System.Windows.Forms.Border3DSide.All); + BarFunctions.DrawBorder3D(g, itemRect, System.Windows.Forms.Border3DStyle.SunkenOuter, System.Windows.Forms.Border3DSide.All, color3d); + } + + if ((m_MouseOver && m_HotTrackingStyle != eHotTrackingStyle.None) || m_Expanded || m_Checked && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + { + //if(m_ButtonType!=eButtonType.Label) + { + // Draw Mouse over marker + if (bIsOnMenu || this.IsOnCustomizeDialog) + { + if ((m_MouseOver && m_HotTrackingStyle != eHotTrackingStyle.None) || m_Expanded) + { + if (!(m_MouseOver && this.DesignMode) || this.IsOnCustomizeDialog) + g.FillRectangle(SystemBrushes.Highlight, itemRect); + } + } + else + { + if (m_MouseDown || (m_Checked && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) || this.Expanded && (!this.ShowSubItems || this.IsOnMenuBar)) + { + if (m_SubItemsRect.IsEmpty) + { + if (!buttonX) + { + BarFunctions.DrawBorder3D(g, itemRect, System.Windows.Forms.Border3DStyle.SunkenOuter, System.Windows.Forms.Border3DSide.All, color3d); + if (m_Checked && !m_MouseOver && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + { + Rectangle r = itemRect; // Rectangle(itemRect.X,itemRect.Y,itemRect.Width,itemRect.Height); + r.Inflate(-1, -1); + g.FillRectangle(ColorFunctions.GetPushedBrush(this), r); + } + } + } + else + { + if (!buttonX) + { + Rectangle r; + if (m_Orientation == eOrientation.Horizontal) + r = new Rectangle(itemRect.X, itemRect.Y, itemRect.Width - m_SubItemsRect.Width, itemRect.Height); + else + r = new Rectangle(itemRect.X, itemRect.Y, itemRect.Width, itemRect.Height - m_SubItemsRect.Height); + //System.Windows.Forms.ControlPaint.DrawBorder3D(g,r,System.Windows.Forms.Border3DStyle.SunkenOuter,System.Windows.Forms.Border3DSide.All); + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.SunkenOuter, System.Windows.Forms.Border3DSide.All, color3d); + if (!m_MouseOver) + { + r.Inflate(-1, -1); + g.FillRectangle(ColorFunctions.GetPushedBrush(this), r); + } + } + } + } + else if (!this.DesignMode) + { + if (m_SubItemsRect.IsEmpty) + { + if (!buttonX) + BarFunctions.DrawBorder3D(g, itemRect, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, color3d); + } + else + { + Rectangle r; + if (m_Orientation == eOrientation.Horizontal) + r = new Rectangle(itemRect.X, itemRect.Y, itemRect.Width - m_SubItemsRect.Width, itemRect.Height); + else + r = new Rectangle(itemRect.X, itemRect.Y, itemRect.Width, itemRect.Height - m_SubItemsRect.Height); + //System.Windows.Forms.ControlPaint.DrawBorder3D(g,r,System.Windows.Forms.Border3DStyle.RaisedInner,System.Windows.Forms.Border3DSide.All); + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, color3d); + } + } + + } + + // TODO: Add support for Checked buttons etc... + if (objImage != null && m_ButtonStyle != eButtonStyle.TextOnlyAlways) + { + //if(m_ButtonType==eButtonType.StateButton) + // rTmp=new Rectangle(m_ImageDrawRect.X,m_ImageDrawRect.Y,itemRect.Height,itemRect.Height); + //else + rTmp = new Rectangle(m_ImageDrawRect.X, m_ImageDrawRect.Y, m_ImageDrawRect.Width, itemRect.Height); + //if(m_ImagePosition==eImagePosition.Right) + // rTmp.X=itemRect.Width-21-m_ImageDrawRect.Width; + + rTmp.Offset(itemRect.Left, itemRect.Top); + if (bIsOnMenu) + { + if (m_Checked && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog) + { + //System.Windows.Forms.ControlPaint.DrawBorder3D(g,rTmp,System.Windows.Forms.Border3DStyle.SunkenOuter,System.Windows.Forms.Border3DSide.All); + BarFunctions.DrawBorder3D(g, rTmp, System.Windows.Forms.Border3DStyle.SunkenOuter, System.Windows.Forms.Border3DSide.All, color3d); + if (!m_MouseOver) + { + rTmp.Inflate(-1, -1); + g.FillRectangle(ColorFunctions.GetPushedBrush(this), rTmp); + } + /*if(m_ButtonType==eButtonType.StateButton) + { + // Draw checker... + Point[] pt=new Point[3]; + pt[0].X=rTmp.Left+(rTmp.Width-5)/2; + pt[0].Y=rTmp.Top+(rTmp.Height-6)/2+3; + pt[1].X=pt[0].X+2; + pt[1].Y=pt[0].Y+2; + pt[2].X=pt[1].X+4; + pt[2].Y=pt[1].Y-4; + g.DrawLines(SystemPens.ControlText,pt); + pt[0].X++; + //pt[0].Y + pt[1].X++; + //pt[1].Y; + pt[2].X++; + //pt[2].Y; + g.DrawLines(SystemPens.ControlText,pt); + }*/ + } + else + { + //System.Windows.Forms.ControlPaint.DrawBorder3D(g,rTmp,System.Windows.Forms.Border3DStyle.RaisedInner,System.Windows.Forms.Border3DSide.All); + BarFunctions.DrawBorder3D(g, rTmp, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, color3d); + } + /*if(m_ButtonType==eButtonType.StateButton && m_MouseOver) + { + rTmp=new Rectangle(rTmp.Right+STATEBUTTON_SPACING,rTmp.Top,m_ImageDrawRect.Width-rTmp.Width-STATEBUTTON_SPACING,itemRect.Height); + System.Windows.Forms.ControlPaint.DrawBorder3D(g,rTmp,System.Windows.Forms.Border3DStyle.RaisedInner,System.Windows.Forms.Border3DSide.All); + }*/ + } + else + { + if (m_MouseDown) + rect.Offset(1, 1); + } + //g.DrawImage(objImage,rect,0,0,objImage.Width,objImage.Height,System.Drawing.GraphicsUnit.Pixel); + objImage.DrawImage(g, rect); + } + else if ((objImage == null || m_ButtonStyle == eButtonStyle.TextOnlyAlways) && m_Checked && !this.IsOnCustomizeMenu && !this.IsOnCustomizeDialog && bIsOnMenu) + { + // Draw checked box + rTmp = new Rectangle(m_ImageDrawRect.X, m_ImageDrawRect.Y, m_ImageDrawRect.Width, itemRect.Height); + rTmp.Offset(itemRect.Left, itemRect.Top); + DrawOfficeCheckBox(g, rTmp); + } + } + //else + // g.FillRectangle(SystemBrushes.Highlight,itemRect); + } + else + { + if (objImage != null && m_ButtonStyle != eButtonStyle.TextOnlyAlways) + { + if (m_HotTrackingStyle != eHotTrackingStyle.Color) + { + //g.DrawImage(objImage,rect,0,0,objImage.Width,objImage.Height,System.Drawing.GraphicsUnit.Pixel); + objImage.DrawImage(g, rect); + } + else if (m_HotTrackingStyle == eHotTrackingStyle.Color) + { + // Draw gray-scale image for this hover style... + float[][] array = new float[5][]; + array[0] = new float[5] { 0.2125f, 0.2125f, 0.2125f, 0, 0 }; + array[1] = new float[5] { 0.5f, 0.5f, 0.5f, 0, 0 }; + array[2] = new float[5] { 0.0361f, 0.0361f, 0.0361f, 0, 0 }; + array[3] = new float[5] { 0, 0, 0, 1, 0 }; + array[4] = new float[5] { 0.2f, 0.2f, 0.2f, 0, 1 }; + System.Drawing.Imaging.ColorMatrix grayMatrix = new System.Drawing.Imaging.ColorMatrix(array); + System.Drawing.Imaging.ImageAttributes att = new System.Drawing.Imaging.ImageAttributes(); + att.SetColorMatrix(grayMatrix); + //g.DrawImage(objImage,rect,0,0,objImage.Width,objImage.Height,GraphicsUnit.Pixel,att); + objImage.DrawImage(g, rect, 0, 0, objImage.Width, objImage.Height, GraphicsUnit.Pixel, att); + } + //g.CompositingMode=System.Drawing.Drawing2D.CompositingMode.SourceCopy; + } + } + + if (bIsOnMenu && this.IsOnCustomizeMenu && m_Visible && !this.SystemItem) + { + Rectangle r = new Rectangle(m_Rect.Left, m_Rect.Top, m_Rect.Height, m_Rect.Height); + //r.Inflate(-1,-1); + DrawOfficeCheckBox(g, r); + } + } + else + { + textColor = SystemColors.ControlDark; + if (objImage != null && m_ButtonStyle != eButtonStyle.TextOnlyAlways) + { + // Draw disabled image + //g.DrawImage(objImage,rect); + objImage.DrawImage(g, rect); + } + } + + // Draw menu item text + if (bIsOnMenu || m_ButtonStyle != eButtonStyle.Default || objImage == null || (!bIsOnMenu && (m_ImagePosition == eImagePosition.Top || m_ImagePosition == eImagePosition.Bottom))) + { + if (bIsOnMenu) + rect = new Rectangle(m_TextDrawRect.X, m_TextDrawRect.Y, itemRect.Width - m_ImageDrawRect.Right - 24, m_TextDrawRect.Height); + else + { + rect = m_TextDrawRect; + if (m_ImagePosition == eImagePosition.Top || m_ImagePosition == eImagePosition.Bottom) + { + if (m_Orientation == eOrientation.Horizontal) + rect = new Rectangle(m_TextDrawRect.X, m_TextDrawRect.Y, itemRect.Width, m_TextDrawRect.Height); + if ((this.SubItems.Count > 0 || this.PopupType == ePopupType.Container) && m_Orientation == eOrientation.Horizontal && this.ShowSubItems) + rect.Width -= 12; + + objStringFormat |= eTextFormat.HorizontalCenter; + } + //else + //rect=new Rectangle(m_TextDrawRect.X,m_TextDrawRect.Y,itemRect.Width-m_ImageDrawRect.Width,m_TextDrawRect.Height); + } + + if (((m_MouseOver && m_HotTrackingStyle != eHotTrackingStyle.None) || m_Expanded) && bIsOnMenu && !this.DesignMode) + textColor = SystemColors.HighlightText; + + rect.Offset(itemRect.Left, itemRect.Top); + + if (!bIsOnMenu && (m_MouseDown || (this.Expanded && this.IsOnMenuBar))) + rect.Offset(1, 1); + + if (buttonX) + { + objStringFormat |= eTextFormat.HorizontalCenter; + rect.Height--; + } + if (GetEnabled(pa.ContainerControl) || this.DesignMode) + { + if (m_Orientation == eOrientation.Vertical && !bIsOnMenu) + { + g.RotateTransform(90); + TextDrawing.DrawStringLegacy(g, m_Text, objFont, textColor, new Rectangle(rect.Top, -rect.Right, rect.Height, rect.Width), objStringFormat); + g.ResetTransform(); + } + else + { + TextDrawing.DrawString(g, m_Text, objFont, textColor, rect, objStringFormat); + if (!this.DesignMode && this.Focused && !bIsOnMenu && !pa.IsOnMenuBar) + { + //SizeF szf=g.MeasureString(m_Text,objFont,rect.Width,objStringFormat); + Rectangle r = rect; + //r.Width=(int)Math.Ceiling(szf.Width); + //r.Height=(int)Math.Ceiling(szf.Height); + //r.Inflate(1,1); + System.Windows.Forms.ControlPaint.DrawFocusRectangle(g, r); + } + } + } + else + { + if (m_Orientation == eOrientation.Vertical && !bIsOnMenu) + { + g.RotateTransform(90); + System.Windows.Forms.ControlPaint.DrawStringDisabled(g, m_Text, objFont, SystemColors.Control, new Rectangle(rect.Top, -rect.Right, rect.Height, rect.Width), TextDrawing.GetStringFormat(objStringFormat)); + g.ResetTransform(); + } + else + System.Windows.Forms.ControlPaint.DrawStringDisabled(g, m_Text, objFont, SystemColors.Control, rect, TextDrawing.GetStringFormat(objStringFormat)); + } + } + + // Draw Shortcut text if needed + if (this.DrawShortcutText != "" && bIsOnMenu) + { + objStringFormat |= eTextFormat.HidePrefix | eTextFormat.Right; + if (GetEnabled(pa.ContainerControl) || this.DesignMode) + TextDrawing.DrawString(g, this.DrawShortcutText, objFont, textColor, rect, objStringFormat); + else + System.Windows.Forms.ControlPaint.DrawStringDisabled(g, this.DrawShortcutText, objFont, SystemColors.Control, rect, TextDrawing.GetStringFormat(objStringFormat)); + } + + // If it has subitems draw the triangle to indicate that + if ((this.SubItems.Count > 0 || this.PopupType == ePopupType.Container) && this.ShowSubItems) + { + if (bIsOnMenu) + { + Point[] p = new Point[3]; + p[0].X = itemRect.Left + itemRect.Width - 12; + p[0].Y = itemRect.Top + (itemRect.Height - 8) / 2; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 8; + p[2].X = p[0].X + 4; + p[2].Y = p[0].Y + 4; + using (SolidBrush brush = new SolidBrush(textColor)) + g.FillPolygon(brush, p); + } + else if (!m_SubItemsRect.IsEmpty) + { + if (m_MouseOver && !m_Expanded && m_HotTrackingStyle != eHotTrackingStyle.None) + { + Rectangle r = new Rectangle(m_SubItemsRect.X, m_SubItemsRect.Y, m_SubItemsRect.Width, m_SubItemsRect.Height); + r.Offset(itemRect.X, itemRect.Y); + //System.Windows.Forms.ControlPaint.DrawBorder3D(g,r,System.Windows.Forms.Border3DStyle.RaisedInner,System.Windows.Forms.Border3DSide.All); + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.RaisedInner, System.Windows.Forms.Border3DSide.All, color3d); + } + else if (m_Expanded) + { + Rectangle r = new Rectangle(m_SubItemsRect.X, m_SubItemsRect.Y, m_SubItemsRect.Width, m_SubItemsRect.Height); + r.Offset(itemRect.X, itemRect.Y); + //System.Windows.Forms.ControlPaint.DrawBorder3D(g,r,System.Windows.Forms.Border3DStyle.SunkenOuter,System.Windows.Forms.Border3DSide.All); + BarFunctions.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.SunkenOuter, System.Windows.Forms.Border3DSide.All, color3d); + } + Point[] p = new Point[3]; + if (m_Orientation == eOrientation.Horizontal) + { + p[0].X = itemRect.Left + m_SubItemsRect.Left + (m_SubItemsRect.Width - 5) / 2; + p[0].Y = itemRect.Top + (m_SubItemsRect.Height - 3) / 2 + 1; + p[1].X = p[0].X + 5; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 2; + p[2].Y = p[0].Y + 3; + } + else + { + p[0].X = itemRect.Left + (m_SubItemsRect.Width - 3) / 2 + 1; + p[0].Y = itemRect.Top + m_SubItemsRect.Top + (m_SubItemsRect.Height - 5) / 2; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X - 3; + p[2].Y = p[0].Y + 3; + } + g.FillPolygon(SystemBrushes.ControlText, p); + } + } + + if (this.Focused && this.DesignMode) + { + Rectangle r = itemRect; + r.Inflate(-1, -1); + g.DrawRectangle(new Pen(SystemColors.ControlText, 2), r); + } + + if (objImage != null) + objImage.Dispose(); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public Image GetItemImage() + { + CompositeImage image = GetImage(); + if (image != null) + return image.Image; + return null; + } + + internal CompositeImage GetImage(Color textColor) + { + if (!GetEnabled() && !this.IsOnCustomizeDialog) // Issue: B1002 + return GetImage(ImageState.Disabled, textColor); + else if (m_MouseDown || this.Checked || this.Expanded && m_HotTrackingStyle == eHotTrackingStyle.Image) + return GetImage(ImageState.Pressed, textColor); + else if (m_MouseOver && !m_MouseOverExpand && !(StyleManager.IsMetro(this.EffectiveStyle) && this.Expanded)) + return GetImage(ImageState.Hover, textColor); + return GetImage(ImageState.Default, textColor); + } + internal CompositeImage GetImage() + { + return GetImage(Color.Black); + } + internal CompositeImage GetImage(ImageState state, Color textColor) + { + Image image = null; + if (state == ImageState.Disabled && (m_DisabledImage != null || m_DisabledImageIndex >= 0 || m_DisabledIcon != null || m_Image != null || m_ImageIndex >= 0 || m_Icon != null)) + { + if (m_DisabledImage != null) + return new CompositeImage(m_DisabledImage, false, m_ImageSizeOverride); + else if (m_DisabledIcon != null) + return new CompositeImage(m_DisabledIcon, false, m_ImageSizeOverride); + if (m_DisabledImageIndex >= 0) + { + DisposedCachedImageListImage(); + image = GetImageFromImageList(m_DisabledImageIndex); + if (image != null) + return new CompositeImage(image, (image != m_ImageCachedIdx), m_ImageSizeOverride); + return null; + } + + CreateDisabledImage(); + + if (m_DisabledImage != null) + return new CompositeImage(m_DisabledImage, false, m_ImageSizeOverride); + else if (m_DisabledIcon != null) + return new CompositeImage(m_DisabledIcon, false, m_ImageSizeOverride); + else + return null; + } + + if (m_Icon != null) + { + System.Drawing.Size iconSize = this.IconSize; + System.Drawing.Icon icon = null; + try + { + icon = new System.Drawing.Icon(m_Icon, iconSize); + } + catch { icon = null; } + if (icon == null) + return new CompositeImage(m_Icon, false, m_ImageSizeOverride); + else + return new CompositeImage(icon, true, m_ImageSizeOverride); + } + + if (state == ImageState.Hover && (m_HoverImage != null || m_HoverImageIndex >= 0)) + { + if (m_HoverImage != null) + return new CompositeImage(m_HoverImage, false, m_ImageSizeOverride); + if (m_HoverImageIndex >= 0) + { + DisposedCachedImageListImage(); + image = GetImageFromImageList(m_HoverImageIndex); + if (image != null) + return new CompositeImage(image, (image != m_ImageCachedIdx), m_ImageSizeOverride); + return null; + } + } + + if (state == ImageState.Pressed && (m_PressedImage != null || m_PressedImageIndex >= 0)) + { + if (m_PressedImage != null) + return new CompositeImage(m_PressedImage, false, m_ImageSizeOverride); + if (m_PressedImageIndex >= 0) + { + DisposedCachedImageListImage(); + image = GetImageFromImageList(m_PressedImageIndex); + if (image != null) + return new CompositeImage(image, (image != m_ImageCachedIdx), m_ImageSizeOverride); + return null; + } + } + + if (m_ImageSmall != null && (UseSmallImageResolved || m_ImageSizeOverride.Width == m_ImageSmall.Width && m_ImageSizeOverride.Height == m_ImageSmall.Height)) + return new CompositeImage(m_ImageSmall, false); + if (m_Image != null) + { + if (_ImageAlt != null && textColor == Color.White) + return new CompositeImage(_ImageAlt, false, m_ImageSizeOverride); + return new CompositeImage(m_Image, false, m_ImageSizeOverride); + } + if (m_ImageIndex >= 0) + { + if (m_DisabledImageIndex >= 0 || m_HoverImageIndex >= 0 || m_PressedImageIndex >= 0) + DisposedCachedImageListImage(); + image = GetImageFromImageList(m_ImageIndex); + if (image != null) + return new CompositeImage(image, (image != m_ImageCachedIdx), m_ImageSizeOverride); + } + + return null; + } + + //private ImageList GetImageList() + //{ + // IOwner owner = null; + // IBarImageSize iImageSize = null; + // if (_ItemPaintArgs != null) + // { + // owner = _ItemPaintArgs.Owner; + // iImageSize = _ItemPaintArgs.ContainerControl as IBarImageSize; + // } + // if (owner == null) owner = this.GetOwner() as IOwner; + // if (iImageSize == null) iImageSize = this.ContainerControl as IBarImageSize; + + // if (owner != null) + // { + // try + // { + // if (iImageSize != null && iImageSize.ImageSize != eBarImageSize.Default) + // { + // if (iImageSize.ImageSize == eBarImageSize.Medium && owner.ImagesMedium != null) + // return owner.ImagesMedium; + // else if (iImageSize.ImageSize == eBarImageSize.Large && owner.ImagesLarge != null) + // return owner.ImagesLarge; + // else if (owner.Images != null) + // return owner.Images; + // } + // else if (m_Parent is SideBarPanelItem && ((SideBarPanelItem)m_Parent).ItemImageSize != eBarImageSize.Default) + // { + // eBarImageSize imgSize = ((SideBarPanelItem)m_Parent).ItemImageSize; + // if (imgSize == eBarImageSize.Medium && owner.ImagesMedium != null) + // return owner.ImagesMedium; + // else if (imgSize == eBarImageSize.Large && owner.ImagesLarge != null) + // return owner.ImagesLarge; + // else if (owner.Images != null) + // return owner.Images; + // } + // else if (owner.Images != null) + // return owner.Images; + // } + // catch (Exception) + // { + // return null; + // } + // } + + // return null; + //} + + private eBarImageSize GetImageListSize(IBarImageSize barImageSize) + { + eBarImageSize imageListSize = eBarImageSize.Default; + if (barImageSize != null) imageListSize = barImageSize.ImageSize; + if (_ImageListSizeSelection != eButtonImageListSelection.NotSet) + imageListSize = (eBarImageSize)_ImageListSizeSelection; + return imageListSize; + } + + private Image GetImageFromImageList(int ImageIndex) + { + if (ImageIndex >= 0) + { + IOwner owner = null; + IBarImageSize iImageSize = null; + if (_ItemPaintArgs != null) + { + owner = _ItemPaintArgs.Owner; + iImageSize = _ItemPaintArgs.ContainerControl as IBarImageSize; + } + if (owner == null) owner = this.GetOwner() as IOwner; + if (iImageSize == null) + { + iImageSize = this.ContainerControl as IBarImageSize; + } + + if (owner != null) + { + try + { + eBarImageSize imageListSize = GetImageListSize(iImageSize); + + if (imageListSize != eBarImageSize.Default) + { + if (imageListSize == eBarImageSize.Medium && owner.ImagesMedium != null && !UseSmallImageResolved) // && owner.ImagesMedium.Images.Count>0 && ImageIndex0 && ImageIndex0 && ImageIndex0 && ImageIndex0 && ImageIndex0 && ImageIndex0 && ImageIndex + /// Sets fixed size of the image. Image will be scaled and painted it size specified. + /// + [Browsable(true), DevCoBrowsable(false)] + public System.Drawing.Size ImageFixedSize + { + get { return m_ImageSizeOverride; } + set + { + m_ImageSizeOverride = value; + this.OnImageChanged(); + if (m_Parent != null && m_Parent is ImageItem) + { + ((ImageItem)m_Parent).RefreshImageSize(); + } + } + } + /// + /// Resets ImageFixedSize property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetImageFixedSize() + { + this.ImageFixedSize = new Size(); + } + /// + /// Gets whether ImageFixedSize property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeImageFixedSize() + { + return !m_ImageSizeOverride.IsEmpty; + } + + /// + /// Gets or sets the fixed size of the button. Both width and height must be set to value greater than 0 in order for button to use fixed size. + /// Setting both width and height to 0 (default value) indicates that button will be sized based on content. + /// + [Browsable(true), DevCoBrowsable(false), Description("Indicates fixed size of the button."), Category("Layout")] + public virtual System.Drawing.Size FixedSize + { + get { return m_FixedSize; } + set + { + if (value.Width < 0) value.Width = 0; + if (value.Height < 0) value.Height = 0; + m_FixedSize = value; + this.NeedRecalcSize = true; + this.OnAppearanceChanged(); + } + } + /// + /// Gets whether FixedSize property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFixedSize() + { + return !m_FixedSize.IsEmpty; + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFixedSize() + { + TypeDescriptor.GetProperties(this)["FixedSize"].SetValue(this, Size.Empty); + } + + private System.Drawing.Size IconSize + { + get + { + // Default Icon Size + System.Drawing.Size size = new Size(16, 16); + IBarImageSize iImageSize = null; + if (_ItemPaintArgs != null) + { + iImageSize = _ItemPaintArgs.ContainerControl as IBarImageSize; + } + if (iImageSize == null) iImageSize = this.ContainerControl as IBarImageSize; + + try + { + eBarImageSize imageListSize = GetImageListSize(iImageSize); + if (iImageSize != null && imageListSize != eBarImageSize.Default) + { + if (imageListSize == eBarImageSize.Medium) + size = new Size(24, 24); + else if (imageListSize == eBarImageSize.Large) + size = new Size(32, 32); + } + else if (m_Parent is SideBarPanelItem && ((SideBarPanelItem)m_Parent).ItemImageSize != eBarImageSize.Default) + { + eBarImageSize imgSize = ((SideBarPanelItem)m_Parent).ItemImageSize; + if (imgSize == eBarImageSize.Medium) + size = new Size(24, 24); + else if (imgSize == eBarImageSize.Large) + size = new Size(32, 32); + } + } + catch (Exception) + { + } + + return size; + } + } + + /// + /// Overridden. Recalculates the size of the item. + /// + public override void RecalcSize() + { + if (this.SuspendLayout) + return; + bool pulse = false; + int pulseBeats = m_PulseBeats; + if (m_FadeAnimation) + { + StopFade(); + pulse = m_Pulse; + m_Pulse = false; + } + + if (Dpi.Factor.Width > 1) + { + CompositeImage img = GetImage(); + if (img != null && this.ImageSize.Width != img.Width) + this.OnImageChanged(); + } + + if (EffectiveStyle == eDotNetBarStyle.Office2000 && !this.IsThemed) + RecalcSizeOffice(); + else + RecalcSizeDotNet(); + base.RecalcSize(); + + if (pulse) + InvokeDelayed(new MethodInvoker(delegate { Pulse(pulseBeats); }), 500); + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool UseParentSubItemsImageSize + { + get + { + return true; + } + } + + private void RecalcSizeDotNet() + { + ButtonItemLayout.LayoutButton(this); + + // System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + // if(!IsHandleValid(objCtrl)) + // return; + // //Graphics g=Graphics.FromHwnd(objCtrl.Handle); + // Graphics g = BarFunctions.CreateGraphics(objCtrl); + // bool bHasImage=false; + // if(GetImage(ImageState.Default)!=null) + // bHasImage=true; + // + // m_TextDrawRect=Rectangle.Empty; + // m_ImageDrawRect=Rectangle.Empty; + // m_SubItemsRect=Rectangle.Empty; + // int measureStringWidth=0; + // if(_FitContainer) + // measureStringWidth=m_Rect.Width-4; + // m_Rect.Width=0; + // m_Rect.Height=0; + // + // // Get the right image size that we will use for calculation + // Size objImageSize=Size.Empty; + // if(m_Parent!=null && m_ImageSizeOverride.IsEmpty) + // { + // ImageItem objParentImageItem=m_Parent as ImageItem; + // if(objParentImageItem!=null && !objParentImageItem.SubItemsImageSize.IsEmpty) + // { + // if(!bHasImage || this.IsOnMenu) + // objImageSize=new Size(objParentImageItem.SubItemsImageSize.Width,objParentImageItem.SubItemsImageSize.Height); + // else + // { + // if(this.Orientation==eOrientation.Horizontal) + // objImageSize=new Size(this.ImageSize.Width,objParentImageItem.SubItemsImageSize.Height); + // else + // objImageSize=new Size(objParentImageItem.SubItemsImageSize.Width,this.ImageSize.Height); + // } + // } + // else + // objImageSize=this.ImageSize; + // } + // else if(!m_ImageSizeOverride.IsEmpty) + // objImageSize=m_ImageSizeOverride; + // else + // objImageSize=this.ImageSize; + // if(_FitContainer && bHasImage && (m_ImagePosition==eImagePosition.Left || m_ImagePosition==eImagePosition.Right)) + // { + // measureStringWidth-=(objImageSize.Width+10); + // } + // + // // Measure string + // Font objCurrentFont=null; + // if(m_Font!=null) + // objCurrentFont=m_Font; + // else + // { + // objCurrentFont=GetFont(null); + // if(m_HotFontBold) + // objCurrentFont=new Font(objCurrentFont,FontStyle.Bold); + // } + // + // Size objStringSize=Size.Empty; + // eTextFormat objStringFormat=GetStringFormat(); + // + // if(m_Text!="") + // { + // if (m_Orientation == eOrientation.Vertical && !this.IsOnMenu) + // objStringSize = TextDrawing.MeasureStringLegacy(g, m_Text, objCurrentFont, new Size(measureStringWidth,0), objStringFormat); + // else + // objStringSize=TextDrawing.MeasureString(g,m_Text,objCurrentFont,measureStringWidth,objStringFormat); + // } + // + // // See if this button is on menu, and do appropriate calculations + // if(this.IsOnMenu) + // { + // if(objImageSize.IsEmpty) + // objImageSize=new Size(16,16); + // // Add 4 pixel padding to the image size, 2 pixels on each side + // objImageSize.Height+=2; + // objImageSize.Width+=7; + // + // // Calculate item height + // if(objStringSize.Height>objImageSize.Height) + // m_Rect.Height=(int)objStringSize.Height+4; + // else + // m_Rect.Height=objImageSize.Height+4; + // + // // Add Vertical Padding to it + // m_Rect.Height+=m_VerticalPadding; + // + // // We know the image position now, we will center it into this area + // if(this.IsOnCustomizeMenu) + // m_ImageDrawRect=new Rectangle(m_Rect.Height+2,(m_Rect.Height-objImageSize.Height)/2,objImageSize.Width,objImageSize.Height); + // else + // m_ImageDrawRect=new Rectangle(0,(m_Rect.Height-objImageSize.Height)/2,objImageSize.Width,objImageSize.Height); + // + // m_Rect.Width=(int)objStringSize.Width; + // // Add short-cut size if we have short-cut + // if( this.DrawShortcutText != "" ) + // { + // Size objSizeShortcut=TextDrawing.MeasureString(g,this.DrawShortcutText,objCurrentFont,0,objStringFormat); + // m_Rect.Width+=(objSizeShortcut.Width+14); // 14 distance between text and shortcut + // } + // + // m_TextDrawRect=new Rectangle(m_ImageDrawRect.Right+8,3,m_Rect.Width,m_Rect.Height-6); + // + // // 8 pixels distance between image and text, 22 pixels if this item has sub items + // m_Rect.Width+=(m_ImageDrawRect.Right+8+26); + // m_Rect.Width+=m_HorizontalPadding; + // } + // else + // { + // bool bThemed=this.IsThemed; + // if(m_Orientation==eOrientation.Horizontal && (m_ImagePosition==eImagePosition.Left || m_ImagePosition==eImagePosition.Right)) + // { + // // Recalc size for the Bar button + // // Add 8 pixel padding to the image size, 4 pixels on each side + // //objImageSize.Height+=4; + // objImageSize.Width+=10; + // + // // Calculate item height + // if(objStringSize.Height>objImageSize.Height) + // m_Rect.Height=(int)objStringSize.Height+6; + // else + // m_Rect.Height=objImageSize.Height+6; + // + // // Add Vertical Padding + // m_Rect.Height+=m_VerticalPadding; + // + // if(bThemed && !this.IsOnMenuBar) + // m_Rect.Height+=4; + // + // m_ImageDrawRect=Rectangle.Empty; + // if(m_ButtonStyle!=eButtonStyle.TextOnlyAlways && bHasImage) + // { + // // We know the image position now, we will center it into this area + // m_ImageDrawRect=new Rectangle(0,(m_Rect.Height-objImageSize.Height)/2,objImageSize.Width,objImageSize.Height); + // } + // + // // Draw Text only if needed + // m_TextDrawRect=Rectangle.Empty; + // if(m_ButtonStyle!=eButtonStyle.Default || !bHasImage) + // { + // if(m_ImageDrawRect.Right>0) + // { + // m_Rect.Width=(int)objStringSize.Width+1; + // m_TextDrawRect=new Rectangle(m_ImageDrawRect.Right-2,2,m_Rect.Width,m_Rect.Height-4); + // } + // else + // { + // m_Rect.Width=(int)objStringSize.Width+6; + // if(!bHasImage && this.IsOnMenuBar) + // { + // m_Rect.Width+=6; + // m_TextDrawRect=new Rectangle(0,2,m_Rect.Width,m_Rect.Height-4); + // } + // else + // m_TextDrawRect=new Rectangle(3,2,m_Rect.Width,m_Rect.Height-4); + // } + // } + // // No need for the code below since it causes text to be drawn if item is not on Bar no matter what + //// else if(!this.IsOnBar) + //// { + //// if(m_ImageDrawRect.Right>0) + //// { + //// m_Rect.Width=(int)objStringSize.Width+4; + //// m_TextDrawRect=new Rectangle(m_ImageDrawRect.Right-2,2,m_Rect.Width,m_Rect.Height-4); + //// } + //// else + //// { + //// m_Rect.Width=(int)objStringSize.Width+6; + //// m_TextDrawRect=new Rectangle(3,2,m_Rect.Width,m_Rect.Height-4); + //// } + //// } + // m_Rect.Width+=m_ImageDrawRect.Right; + // + // if(m_ImagePosition==eImagePosition.Right && m_ImageDrawRect.Right>0) + // { + // m_TextDrawRect.X=3; + // m_ImageDrawRect.X=m_Rect.Width-m_ImageDrawRect.Width; + // } + // + // // Add Horizontal padding + // m_Rect.Width+=m_HorizontalPadding; + // } + // else + // { + // // Image is on top or bottom + // // Calculate width, that is easy + // if(m_Orientation==eOrientation.Horizontal) + // { + // if(objStringSize.Width>objImageSize.Width) + // m_Rect.Width=(int)objStringSize.Width+6; + // else + // m_Rect.Width=objImageSize.Width+6; + // + // // Calculate item height 3 padding on top and bottom and 2 pixels distance between the image and text + // m_Rect.Height=(int)(objImageSize.Height+objStringSize.Height+10); + // + // // Add Horizontal/Vertical padding + // m_Rect.Width+=m_HorizontalPadding; + // m_Rect.Height+=m_VerticalPadding; + // + // if(m_ImagePosition==eImagePosition.Top) + // { + // m_ImageDrawRect=new Rectangle(0,m_VerticalPadding/2+2,m_Rect.Width,objImageSize.Height+2); + // m_TextDrawRect=new Rectangle((int)(m_Rect.Width-objStringSize.Width)/2,m_ImageDrawRect.Bottom,(int)objStringSize.Width,(int)objStringSize.Height+5); + // } + // else + // { + // m_TextDrawRect=new Rectangle((int)(m_Rect.Width-objStringSize.Width)/2,m_VerticalPadding/2,(int)objStringSize.Width,(int)objStringSize.Height+2); + // m_ImageDrawRect=new Rectangle(0,m_TextDrawRect.Bottom,m_Rect.Width,objImageSize.Height+5); + // } + // } + // else + // { + // if(objStringSize.Height>objImageSize.Width && m_ButtonStyle!=eButtonStyle.Default) + // m_Rect.Width=(int)objStringSize.Height+6; + // else + // m_Rect.Width=objImageSize.Width+10; + // + // // Add Horizontal Padding + // m_Rect.Width+=m_HorizontalPadding; + // + // // Calculate item height 3 padding on top and bottom and 2 pixels distance between the image and text + // if(m_ButtonStyle!=eButtonStyle.Default || !bHasImage) + // { + // if(bHasImage) + // m_Rect.Height=(int)(objImageSize.Height+objStringSize.Width+12); + // else + // m_Rect.Height=(int)(objStringSize.Width+6); + // } + // else + // m_Rect.Height=objImageSize.Height+6; + // + // if(m_ImagePosition==eImagePosition.Top || m_ImagePosition==eImagePosition.Left) + // { + // if(bHasImage) + // m_ImageDrawRect=new Rectangle(0,0,m_Rect.Width,objImageSize.Height+6); + // m_TextDrawRect=new Rectangle((int)(m_Rect.Width-objStringSize.Height)/2,m_ImageDrawRect.Bottom+2,(int)objStringSize.Height,(int)objStringSize.Width+5); + // } + // else + // { + // m_TextDrawRect=new Rectangle((int)(m_Rect.Width-objStringSize.Width)/2,0,(int)objStringSize.Height,(int)objStringSize.Width+5); + // if(bHasImage) + // m_ImageDrawRect=new Rectangle(0,m_TextDrawRect.Bottom+2,m_Rect.Width,objImageSize.Height+5); + // } + // + // // Add Vertical Padding + // m_Rect.Height+=m_VerticalPadding; + // } + // } + // + // //if(SubItemsCount>0 && this.ShowSubItems && (!this.IsOnMenuBar || this.GetImage()!=null)) + // if((SubItems.Count>0 || this.PopupType==ePopupType.Container) && this.ShowSubItems && !this.IsOnMenuBar) + // { + // // Add small button to expand the item + // if(m_Orientation==eOrientation.Horizontal) + // { + // if(bThemed) + // m_SubItemsRect=new Rectangle(m_Rect.Width,0,m_SubItemsExpandWidth,m_Rect.Height); + // else + // m_SubItemsRect=new Rectangle(m_Rect.Width-2,0/*m_Rect.Top*/,m_SubItemsExpandWidth,m_Rect.Height); + // m_Rect.Width+=m_SubItemsExpandWidth; + // } + // else + // { + // m_SubItemsRect=new Rectangle(/*m_Rect.Left+2*/2,m_Rect.Height-2,m_Rect.Width,m_SubItemsExpandWidth); + // m_Rect.Height+=m_SubItemsExpandWidth; + // } + // } + // } + // // This button is on Bar + // //objCurrentFont.Dispose(); + // g.Dispose(); + // objCtrl=null; + } + + private void RecalcSizeOffice() + { + System.Windows.Forms.Control objCtrl = this.ContainerControl as System.Windows.Forms.Control; + if (!IsHandleValid(objCtrl)) + return; + Graphics g = Graphics.FromHwnd(objCtrl.Handle); + g.PageUnit = System.Drawing.GraphicsUnit.Pixel; + + m_TextDrawRect = Rectangle.Empty; + m_ImageDrawRect = Rectangle.Empty; + m_Rect = Rectangle.Empty; + m_SubItemsRect = Rectangle.Empty; + + bool bHasImage = false; + if (GetImage(ImageState.Default, Color.Black) != null) + bHasImage = true; + + // Get the right image size that we will use for calculation + Size objImageSize; + if (m_Parent != null) + { + ImageItem objImageItem = m_Parent as ImageItem; + if (objImageItem != null) + { + if (!bHasImage || this.IsOnMenu) + objImageSize = new Size(objImageItem.SubItemsImageSize.Width, objImageItem.SubItemsImageSize.Height); + else + { + if (this.Orientation == eOrientation.Horizontal) + objImageSize = new Size(this.ImageSize.Width, objImageItem.SubItemsImageSize.Height); + else + objImageSize = new Size(objImageItem.SubItemsImageSize.Width, this.ImageSize.Height); + } + } + else + objImageSize = this.ImageSize; + } + else + objImageSize = this.ImageSize; + + // Measure string + Font objCurrentFont = null; + if (m_Font != null) + objCurrentFont = m_Font; + else + objCurrentFont = GetFont(null, true); + + Size objStringSize; + eTextFormat objStringFormat = GetStringFormat(); + + if (m_Orientation == eOrientation.Vertical && !this.IsOnMenu) + objStringSize = TextDrawing.MeasureStringLegacy(g, m_Text, objCurrentFont, Size.Empty, objStringFormat); + else + objStringSize = TextDrawing.MeasureString(g, m_Text, objCurrentFont, 0, objStringFormat); + + // See if this button is on menu, and do appropriate calculations + if (this.IsOnMenu) + { + // Add 4 pixel padding to the image size, 2 pixels on each side + //objImageSize.Height+=1; + objImageSize.Width += 4; + + // Calculate item height + if (objStringSize.Height > objImageSize.Height) + m_Rect.Height = (int)objStringSize.Height + 4; + else + m_Rect.Height = objImageSize.Height + 4; + + // Add Padding + m_Rect.Height += m_VerticalPadding; + + // We know the image position now, we will center it into this area + if (this.IsOnCustomizeMenu) + m_ImageDrawRect = new Rectangle(m_Rect.Height, 0, m_Rect.Height, m_Rect.Height); + else + m_ImageDrawRect = new Rectangle(0, 0, objImageSize.Width, m_Rect.Height); + + m_Rect.Width = (int)objStringSize.Width; + // Add short-cut size if we have short-cut + if (this.DrawShortcutText != "") + { + Size objSizeShortcut = TextDrawing.MeasureString(g, this.DrawShortcutText, objCurrentFont, 0, objStringFormat); + m_Rect.Width += (objSizeShortcut.Width + 14); // 14 distance between text and shortcut + } + + //m_TextDrawRect=new Rectangle(m_ImageDrawRect.Right+2,3,m_Rect.Width,m_Rect.Height-6); + m_TextDrawRect = new Rectangle(m_ImageDrawRect.Right + 2, (int)(m_Rect.Height - objStringSize.Height) / 2, m_Rect.Width, (int)objStringSize.Height); + + // 8 pixels distance between image and text, 22 pixels if this item has sub items + m_Rect.Width += (m_ImageDrawRect.Right + 2 + 24); + + // Add Horizontal Padding + m_Rect.Width += m_HorizontalPadding; + + // Don't support the image alignment in menus yet + /*if(m_ImagePosition==eImagePosition.Right) + { + int i=m_TextDrawRect.Right-m_ImageDrawRect.Right; + m_TextDrawRect.X=m_ImageDrawRect.X; + m_ImageDrawRect.X=i; + }*/ + + //if(m_BeginGroup) + // m_Rect.Height+=9; + } + else + { + // Recalc size for the Bar button + if (m_Orientation == eOrientation.Horizontal && (m_ImagePosition == eImagePosition.Left || m_ImagePosition == eImagePosition.Right)) + { + // Add 8 pixel padding to the image size, 4 pixels on each side + //objImageSize.Height+=4; + objImageSize.Width += 10; + + // Calculate item height + if (objStringSize.Height > objImageSize.Height) + m_Rect.Height = (int)objStringSize.Height + 6; + else + m_Rect.Height = objImageSize.Height + 6; + + // Add Vertical Padding + m_Rect.Height += m_VerticalPadding; + + m_ImageDrawRect = Rectangle.Empty; + if (m_ButtonStyle != eButtonStyle.TextOnlyAlways && bHasImage) + { + // We know the image position now, we will center it into this area + m_ImageDrawRect = new Rectangle(0, (m_Rect.Height - objImageSize.Height) / 2, objImageSize.Width, objImageSize.Height); + } + + // Draw Text only if needed + m_TextDrawRect = Rectangle.Empty; + if (m_ButtonStyle != eButtonStyle.Default || !bHasImage) + { + if (m_ImageDrawRect.Right > 0) + { + m_Rect.Width = (int)objStringSize.Width + 1; + m_TextDrawRect = new Rectangle(m_ImageDrawRect.Right - 2, 2, m_Rect.Width, m_Rect.Height - 4); + } + else + { + m_Rect.Width = (int)objStringSize.Width + 6; + m_TextDrawRect = new Rectangle(3, 2, m_Rect.Width, m_Rect.Height - 4); + } + } + m_Rect.Width += m_ImageDrawRect.Right; + + // Add Horizontal Padding + m_Rect.Width += m_HorizontalPadding; + } + else + { + // Image is on top or bottom + if (m_Orientation == eOrientation.Horizontal) + { + // Calculate width, that is easy + if (objStringSize.Width > objImageSize.Width) + m_Rect.Width = (int)objStringSize.Width + 6; + else + m_Rect.Width = objImageSize.Width + 6; + + // Calculate item height 3 padding on top and bottom and 2 pixels distance between the image and text + m_Rect.Height = (int)(objImageSize.Height + objStringSize.Height + 10); + + // Add Padding + m_Rect.Width += m_HorizontalPadding; + m_Rect.Height += m_VerticalPadding; + + if (m_ImagePosition == eImagePosition.Top) + { + m_ImageDrawRect = new Rectangle(0, m_VerticalPadding / 2, m_Rect.Width, objImageSize.Height + 2); + m_TextDrawRect = new Rectangle((int)(m_Rect.Width - objStringSize.Width) / 2, m_ImageDrawRect.Bottom + 2, (int)objStringSize.Width, (int)objStringSize.Height + 5); + } + else + { + m_TextDrawRect = new Rectangle((int)(m_Rect.Width - objStringSize.Width) / 2, m_VerticalPadding / 2, (int)objStringSize.Width, (int)objStringSize.Height + 2); + m_ImageDrawRect = new Rectangle(0, m_TextDrawRect.Bottom + 2, m_Rect.Width, objImageSize.Height + 5); + } + } + else + { + // Calculate width, that is easy + if (objStringSize.Height > objImageSize.Height && m_ButtonStyle != eButtonStyle.Default) + m_Rect.Width = (int)objStringSize.Height + 6; + else + m_Rect.Width = objImageSize.Width + 6; + + m_Rect.Width += m_HorizontalPadding; + + // Calculate item height 3 padding on top and bottom and 2 pixels distance between the image and text + if (m_ButtonStyle != eButtonStyle.Default || !bHasImage) + { + if (bHasImage) + m_Rect.Height = (int)(objImageSize.Height + objStringSize.Width + 12); + else + m_Rect.Height = (int)(objStringSize.Width + 6); + } + else + m_Rect.Height = objImageSize.Height + 6; + + if (m_ImagePosition == eImagePosition.Top || m_ImagePosition == eImagePosition.Left) + { + if (bHasImage) + m_ImageDrawRect = new Rectangle(0, 0, m_Rect.Width, objImageSize.Height + 5); + m_TextDrawRect = new Rectangle((int)(m_Rect.Width - objStringSize.Height) / 2, m_ImageDrawRect.Bottom + 2, (int)objStringSize.Height, (int)objStringSize.Width + 5); + } + else + { + m_TextDrawRect = new Rectangle((int)(m_Rect.Width - objStringSize.Height) / 2, 0, (int)objStringSize.Height, (int)objStringSize.Width + 5); + if (bHasImage) + m_ImageDrawRect = new Rectangle(0, m_TextDrawRect.Bottom + 2, m_Rect.Width, objImageSize.Height + 5); + } + m_Rect.Height += m_VerticalPadding; + } + } + + if ((this.SubItems.Count > 0 || this.PopupType == ePopupType.Container) && this.ShowSubItems && (!this.IsOnMenuBar || this.GetImage() != null)) + { + // Add small button to expand the item + if (m_Orientation == eOrientation.Horizontal) + { + m_SubItemsRect = new Rectangle(m_Rect.Right, 0/*m_Rect.Top*/, 12, m_Rect.Height); + m_Rect.Width += m_SubItemsRect.Width; + } + else + { + m_SubItemsRect = new Rectangle(0/*m_Rect.Left*/, m_Rect.Bottom, m_Rect.Width, 12); + m_Rect.Height += m_SubItemsRect.Height; + } + } + } + + // This button is on Bar + //objCurrentFont.Dispose(); + g.Dispose(); + objCtrl = null; + } + + private void DrawOfficeCheckBox(Graphics g, Rectangle r) + { + // Draw checked box + System.Windows.Forms.ControlPaint.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.SunkenOuter, System.Windows.Forms.Border3DSide.All); + if (!m_MouseOver) + { + r.Inflate(-1, -1); + g.FillRectangle(ColorFunctions.GetPushedBrush(), r); + } + // Draw checker... + Point[] pt = new Point[3]; + pt[0].X = r.Left + (r.Width - 6) / 2; + pt[0].Y = r.Top + (r.Height - 6) / 2 + 3; + pt[1].X = pt[0].X + 2; + pt[1].Y = pt[0].Y + 2; + pt[2].X = pt[1].X + 4; + pt[2].Y = pt[1].Y - 4; + g.DrawLines(SystemPens.ControlText, pt); + pt[0].X++; + pt[1].X++; + pt[2].X++; + g.DrawLines(SystemPens.ControlText, pt); + } + + protected internal override void OnItemAdded(BaseItem item) + { + base.OnItemAdded(item); + OnAppearanceChanged(); + } + + /// + /// Overloaded. Called when size of the item is changed externally. + /// + protected override void OnExternalSizeChange() + { + base.OnExternalSizeChange(); + if (!m_FixedSize.IsEmpty) + { + if (m_FixedSize.Width > 0) m_Rect.Width = Dpi.Width(m_FixedSize.Width); + if (m_FixedSize.Height > 0) m_Rect.Height = Dpi.Height(m_FixedSize.Height); + } + ButtonItemLayout.Arrange(this); + return; + } + + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void ContainerLostFocus(bool appLostFocus) + { + base.ContainerLostFocus(appLostFocus); + if (m_Expanded) + { + this.Expanded = false; + if (m_Parent != null) + m_Parent.AutoExpand = false; + } + } + + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalKeyDown(System.Windows.Forms.KeyEventArgs objArg) + { + base.InternalKeyDown(objArg); + if (this.Expanded || objArg.Handled) + return; + + if (objArg.KeyCode == System.Windows.Forms.Keys.Enter || objArg.KeyCode == System.Windows.Forms.Keys.Return || objArg.KeyCode == System.Windows.Forms.Keys.Right && this.IsOnMenu) + { + if (SubItems.Count > 0 && this.GetEnabled()) + { + if (this.Expanded) + { + if (m_Parent != null) + m_Parent.AutoExpand = false; + this.Expanded = false; + } + else + { + if (m_Parent != null) + m_Parent.AutoExpand = true; + this.Expanded = true; + // Select first item on that popup + if (this.PopupType == ePopupType.Menu && this.PopupControl is MenuPanel) + { + ((MenuPanel)this.PopupControl).SelectFirstItem(); + } + } + objArg.Handled = true; + return; + } + } + else if (objArg.KeyCode == System.Windows.Forms.Keys.Escape) + { + if (SubItems.Count > 0 && this.Expanded) + { + this.Expanded = false; + if (m_Parent != null) + m_Parent.AutoExpand = false; + objArg.Handled = true; + return; + } + } + + base.InternalKeyDown(objArg); + } + + #region Fade Effect Support + private Bitmap m_ImageState2 = null; + private int m_Direction = 1; + private int m_Alpha = 0; + private bool m_FadeAnimation = false; + private System.Threading.ReaderWriterLock m_FadeImageLock = new System.Threading.ReaderWriterLock(); + private void SetMouseOver(bool value) + { + if (value != m_MouseOver) + { + if (m_Pulse) + { + if (m_StopPulseOnMouseOver) + m_Pulse = false; + StopFade(); + } + + bool fadeEnabled = (IsFadeEnabled || m_Pulse) && this.GetEnabled() && this.Displayed && this.Visible && this.WidthInternal > 0 && this.HeightInternal > 0; + if (fadeEnabled) + { + int direction = value ? 1 : -1; + int initialAlpha = value ? 10 : 255; + + m_MouseOver = value; + StartFade(direction, initialAlpha); + } + else + m_MouseOver = value; + } + } + + private void StartFade(int direction, int initialAlpha) + { + bool createImage = false; + m_FadeImageLock.AcquireReaderLock(-1); + try + { + createImage = (m_ImageState2 == null); + } + finally + { + m_FadeImageLock.ReleaseReaderLock(); + } + + if (createImage) + { + bool oldMouseOver = m_MouseOver; + m_MouseOver = true; + try + { + bool readerLockHeld = m_FadeImageLock.IsReaderLockHeld; + System.Threading.LockCookie cookie1 = new System.Threading.LockCookie(); + if (readerLockHeld) + { + cookie1 = m_FadeImageLock.UpgradeToWriterLock(-1); + } + else + { + m_FadeImageLock.AcquireWriterLock(-1); + } + + try + { + m_ImageState2 = GetCurrentStateImage(); + } + finally + { + if (readerLockHeld) + { + m_FadeImageLock.DowngradeFromWriterLock(ref cookie1); + } + else + { + m_FadeImageLock.ReleaseWriterLock(); + } + } + } + finally + { + m_MouseOver = oldMouseOver; + } + } + + m_Direction = direction; + m_Alpha = initialAlpha; + + FadeAnimator.Fade(this, new EventHandler(this.OnFadeChanged)); + m_FadeAnimation = true; + } + + internal void StopFade() + { + if (!m_FadeAnimation) + return; + + m_FadeAnimation = false; + FadeAnimator.StopFade(this, new EventHandler(OnFadeChanged)); + + bool disposeImage = false; + m_FadeImageLock.AcquireReaderLock(-1); + try + { + disposeImage = (m_ImageState2 != null); + } + finally + { + m_FadeImageLock.ReleaseReaderLock(); + } + if (disposeImage) + DisposeFadeImage(); + + if (m_Alpha > 230) + m_Alpha = 255; + else if (m_Alpha < 0) + m_Alpha = 0; + this.Invalidate(); + } + + private void DisposeFadeImage() + { + bool readerLockHeld = m_FadeImageLock.IsReaderLockHeld; + System.Threading.LockCookie cookie1 = new System.Threading.LockCookie(); + + if (readerLockHeld) + { + cookie1 = m_FadeImageLock.UpgradeToWriterLock(-1); + } + else + { + m_FadeImageLock.AcquireWriterLock(-1); + } + + try + { + m_ImageState2.Dispose(); + m_ImageState2 = null; + } + finally + { + if (readerLockHeld) + { + m_FadeImageLock.DowngradeFromWriterLock(ref cookie1); + } + else + { + m_FadeImageLock.ReleaseWriterLock(); + } + } + } + + private void OnFadeChanged(object sender, EventArgs e) + { + m_Alpha += (m_Direction * (m_Pulse ? m_PulseFadeAlphaIncrement : m_MouseOverFadeAlphaIncrement)); + + if (m_Direction < 0 && m_Alpha <= 0 || m_Direction > 0 && m_Alpha >= 255) + { + if (m_Pulse) + { + m_Direction *= -1; + if (m_Alpha >= 255) m_Alpha = 255; else m_Alpha = 0; + m_PulseCount++; + if (m_PulseBeats > 0 && m_PulseCount > m_PulseBeats) + { + StopFade(); + StopPulse(); + } + } + else + StopFade(); + } + + System.Windows.Forms.Control cc = this.ContainerControl as System.Windows.Forms.Control; + if (cc != null && BarFunctions.IsHandleValid(cc)) + { + try + { + cc.Invalidate(this.DisplayRectangle); + } + catch (ObjectDisposedException) { } + catch (System.ComponentModel.Win32Exception) { } + } + } + + private Bitmap GetCurrentStateImage() + { + Bitmap bitmap = new Bitmap(this.WidthInternal, this.HeightInternal, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); // Format32bppArgb); + bitmap.MakeTransparent(); + Graphics g = Graphics.FromImage(bitmap); + + try + { + System.Windows.Forms.Control cc = this.ContainerControl as System.Windows.Forms.Control; + bool antiAlias = false; + ItemPaintArgs pa = null; + if (cc is ItemControl) + { + antiAlias = ((ItemControl)cc).AntiAlias; + pa = ((ItemControl)cc).GetItemPaintArgs(g); + } + else if (cc is Bar) + { + antiAlias = ((Bar)cc).AntiAlias; + pa = ((Bar)cc).GetItemPaintArgs(g); + } + else if (cc is ButtonX) + { + antiAlias = ((ButtonX)cc).AntiAlias; + pa = ((ButtonX)cc).GetItemPaintArgs(g); + } + + System.Drawing.Drawing2D.Matrix myMatrix = new System.Drawing.Drawing2D.Matrix(); + myMatrix.Translate(-this.DisplayRectangle.X, -this.DisplayRectangle.Y, System.Drawing.Drawing2D.MatrixOrder.Append); + g.Transform = myMatrix; + myMatrix.Dispose(); + myMatrix = null; + if (antiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + if (pa == null) + { + bitmap.Dispose(); + return null; + } + + this.Paint(pa); + } + finally + { + g.Dispose(); + } + return bitmap; + } + + internal bool _FadeEnabled = true; + /// + /// Gets whether fade effect is enabled. + /// + protected virtual bool IsFadeEnabled + { + get + { + eDotNetBarStyle effectiveStyle = EffectiveStyle; + + if (this.DesignMode || m_HotTrackingStyle == eHotTrackingStyle.None || !_FadeEnabled || TextDrawing.UseTextRenderer + || effectiveStyle == eDotNetBarStyle.Office2010 || effectiveStyle == eDotNetBarStyle.Windows7 || StyleManager.IsMetro(effectiveStyle) || !BarUtilities.FadeAnimatorEnabled) + return false; + if (WinApi.IsGlassEnabled && (this.Parent is CaptionItemContainer || this.Parent is RibbonTabItemContainer && effectiveStyle == eDotNetBarStyle.Office2010)) + return false; + + System.Windows.Forms.Control cc = this.ContainerControl as System.Windows.Forms.Control; + if (cc != null) + { + if (cc is ItemControl) + return ((ItemControl)cc).IsFadeEnabled; + else if (cc is Bar) + return ((Bar)cc).IsFadeEnabled; + else if (cc is ButtonX) + return ((ButtonX)cc).IsFadeEnabled; + } + return false; + } + } + + /// + /// Starts the button pulse effect which alternates slowly between the mouse over and the default state. The pulse effect + /// continues indefinitely until it is stopped by call to StopPulse method. + /// + public void Pulse() + { + Pulse(0); + } + /// + /// Gets whether Pulse function is enabled. + /// + protected virtual bool IsPulseEnabed + { + get + { + return true; + } + } + /// + /// Starts the button pulse effect which alternates slowly between the mouse over and the default state. Pulse effect + /// will alternate between the pulse state for the number of times specified by the pulseBeatCount parameter. + /// + /// Specifies the number of times button alternates between pulse states. 0 indicates indefinite pulse + public void Pulse(int pulseBeatCount) + { + if (this.DesignMode || m_HotTrackingStyle == eHotTrackingStyle.None || !IsPulseEnabed) + return; + + m_PulseBeats = pulseBeatCount; + m_PulseCount = 0; + if (m_Pulse) return; + + m_Pulse = true; + if (m_MouseOver) return; + + StartFade(1, 0); + } + + /// + /// Stops the button Pulse effect. + /// + public void StopPulse() + { + if (m_Pulse) + { + m_Pulse = false; + if (m_MouseOver) SetMouseOver(false); + StopFade(); + } + } + + /// + /// Gets whether the button is currently pulsing, alternating slowly between the mouse over and default state. + /// + [Browsable(false)] + public bool IsPulsing + { + get { return m_Pulse; } + } + + /// + /// Gets or sets whether pulse effect started with StartPulse method stops automatically when mouse moves over the button. Default value is true. + /// + [DefaultValue(true), Browsable(true), Category("Behavior"), Description("Indicates whether pulse effect started with Pulse method stops automatically when mouse moves over the button.")] + public virtual bool StopPulseOnMouseOver + { + get { return m_StopPulseOnMouseOver; } + set { m_StopPulseOnMouseOver = value; } + } + + /// + /// Gets or sets the pulse speed. The value must be greater than 0 and less than 128. Higher values indicate faster pulse. Default value is 12. + /// + [Browsable(true), DefaultValue(12), Category("Behavior"), Description("Indicates pulse speed. The value must be greater than 0 and less than 128.")] + public virtual int PulseSpeed + { + get { return m_PulseFadeAlphaIncrement; } + set + { + if (value <= 0 || value >= 128) + throw new ArgumentOutOfRangeException("PulseSpeed value must be greater than 0 and less than 128"); + m_PulseFadeAlphaIncrement = value; + } + } + #endregion + + /// + /// Indicates whether the item enabled property has changed. + /// + protected override void OnEnabledChanged() + { + if (!this.GetEnabled()) + { + SetMouseOver(false); + SetMouseDown(false); + } + base.OnEnabledChanged(); + } + + //[System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + //public override void InternalMouseEnter() + //{ + // base.InternalMouseEnter(); + + //} + + public override void InternalMouseMove(System.Windows.Forms.MouseEventArgs objArg) + { + base.InternalMouseMove(objArg); + + if (!this.DisplayRectangle.Contains(objArg.X, objArg.Y)) + return; + + bool refresh = false; + + Rectangle r = GetTotalSubItemsRect(); // m_SubItemsRect; + if (!r.IsEmpty && this.GetEnabled()) + { + r.Offset(this.DisplayRectangle.Location); + if (r.Contains(objArg.X, objArg.Y)) + { + if (!m_MouseOverExpand) + { + m_MouseOverExpand = true; + refresh = true; + } + } + else if (m_MouseOverExpand) + { + m_MouseOverExpand = false; + refresh = true; + } + } + + if (!m_MouseOver) + { + SetMouseOver(true); + if (this.GetEnabled() || this.IsOnMenu) + refresh = true; + } + + if (refresh) + this.Refresh(); + } + + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseLeave() + { + base.InternalMouseLeave(); + + m_MouseOverExpand = false; + SetMouseOver(false); + m_MouseDown = false; + + if (this.GetEnabled() || this.IsOnMenu) + this.Refresh(); + } + + internal bool MouseIsOver + { + get { return (m_MouseOver); } + set { m_MouseOver = value; } + } + + internal bool MouseIsOverExpand + { + get { return (m_MouseOverExpand); } + set { m_MouseOverExpand = value; } + } + + internal bool MouseIsDown + { + get { return (m_MouseDown); } + set { m_MouseDown = value; } + } + + internal bool ButtonIsExpanded + { + get { return (m_Expanded); } + set { m_Expanded = value; } + } + + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseHover() + { + base.InternalMouseHover(); + + if ((this.SubItems.Count > 0 || (this.PopupType == ePopupType.Container && !this.IsOnCustomizeMenu)) && this.IsOnMenu && this.ShowSubItems && this.AutoExpandMenuItem) + { + if (!this.Expanded && GetEnabled()) + this.Expanded = true; + } + } + + private bool _AutoExpandMenuItem = true; + /// + /// Gets or sets whether button auto-expands on mouse hover when button is used as menu-item and displayed on menu. Default value is true. + /// + [DefaultValue(true), Browsable(false), Description("Indicates whether button auto-expands on mouse hover when button is used as menu-item and displayed on menu."), Category("Behavior")] + public bool AutoExpandMenuItem + { + get { return _AutoExpandMenuItem; } + set + { + _AutoExpandMenuItem = value; + } + } + + + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseDown(System.Windows.Forms.MouseEventArgs objArg) + { + base.InternalMouseDown(objArg); + ButtonMouseDown(objArg); + } + + protected virtual bool CanShowPopup + { + get + { + return (this.ShowSubItems || ShouldAutoExpandOnClick) && (this.SubItems.Count > 0 || this.PopupType == ePopupType.Container); + } + } + /// + /// Provides internal implementation for ButtonItem mouse down events. + /// + /// Mouse event arguments. + protected virtual void ButtonMouseDown(System.Windows.Forms.MouseEventArgs objArg) + { + // If this is a label don't do anything + //if(m_ButtonType==eButtonType.Label) + // return; + + if (objArg.Button != System.Windows.Forms.MouseButtons.Left || !GetEnabled()) + return; + + m_MouseDown = true; + + if ((this.IsOnMenuBar || ShouldAutoExpandOnClick) && !this.DesignMode) + { + if (objArg.Clicks != 2) // Ignore Double Click + { + if (CanShowPopup) + { + if (this.Expanded) + { + // Order of those two commands is very important since setting autoexpand to false will collapse all other items + this.Expanded = false; + if (m_Parent != null) + m_Parent.AutoExpand = false; + } + else + { + if (this.IsOnMenuBar && m_Parent != null) + m_Parent.AutoExpand = true; + this.Expanded = true; + } + } + else + this.Refresh(); + } + } + else if ((this.IsOnMenuBar || ShouldAutoExpandOnClick) && this.DesignMode) + this.Expanded = !this.Expanded; + else if (!this.IsOnMenu) + { + // If user clicks on expand sub items part of this button expand the item + if ((this.SubItems.Count > 0 || (this.PopupType == ePopupType.Container && !this.IsOnCustomizeMenu)) && this.ShowSubItems) + { + if (!m_Expanded) + { + Rectangle r = GetTotalSubItemsRect(); + r.Width += 2; + r.Height += 2; + //Rectangle r = new Rectangle(m_SubItemsRect.X, m_SubItemsRect.Y, m_SubItemsRect.Width + 2, m_SubItemsRect.Height + 2); + r.Offset(m_Rect.X, m_Rect.Y); // This was a bug since m_SubItemsRect already has the right position see RecalcSize... + if (r.Contains(objArg.X, objArg.Y)) + { + if (EffectiveStyle == eDotNetBarStyle.Office2000) + m_MouseDown = false; + this.Expanded = true; + } + + } + else + this.Expanded = false; + } + + this.Refresh(); + } + else + { + if ((this.SubItems.Count > 0 || this.PopupType == ePopupType.Container && !this.IsOnCustomizeMenu) && this.ShowSubItems) + { + if (!(this.IsOnMenu && this.Expanded)) + this.Expanded = !m_Expanded; + } + else + this.Refresh(); + } + } + + internal override void DoAccesibleDefaultAction() + { + if (this.VisibleSubItems > 0 && (this.IsOnMenu || this.IsOnMenuBar || _AccessibleExpandAction || ShouldAutoExpandOnClick)) + { + if (this.Expanded) + { + this.Expanded = false; + if (this.Parent != null && this.IsOnMenuBar) + this.Parent.AutoExpand = false; + } + else + { + if (this.IsOnMenuBar && this.Parent != null) + this.Parent.AutoExpand = true; + this.Expanded = true; + } + this.Refresh(); + _AccessibleExpandAction = false; + } + else + this.RaiseClick(eEventSource.Keyboard); + } + + /// + /// Indicates whether button should popup when clicked automatically. + /// + protected virtual bool ShouldAutoExpandOnClick + { + get { return m_AutoExpandOnClick; } + } + + internal bool GetShouldAutoExpandOnClick() + { + return this.ShouldAutoExpandOnClick; + } + + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseUp(System.Windows.Forms.MouseEventArgs objArg) + { + bool bCallBase = true; + + Rectangle rsub = GetTotalSubItemsRect(); + rsub.Width += 2; + rsub.Height += 2; + rsub.Offset(m_Rect.X, m_Rect.Y); + + if (objArg.Button == System.Windows.Forms.MouseButtons.Left) + { + if (GetEnabled() && !this.DesignMode) + { + if (m_MenuVisibility == eMenuVisibility.VisibleIfRecentlyUsed && !m_RecentlyUsed && this.IsOnMenu) + { + // Propagate to the top + m_RecentlyUsed = true; + BaseItem objItem = this.Parent; + while (objItem != null) + { + IPersonalizedMenuItem ipm = objItem as IPersonalizedMenuItem; + if (ipm != null) + ipm.RecentlyUsed = true; + objItem = objItem.Parent; + } + } + } + + // Since base item does not auto-collapse when clicked if it has subitems and it is on + // pop-up we need to handle that here and check did user click on expand part of this button + // and if they did not we need to raise click event and collapse the item. + if (!this.IsOnMenu && (this.SubItems.Count > 0 || this.PopupType == ePopupType.Container) && this.ShowSubItems && m_HotSubItem == null && !this.DesignMode && !this.IsOnMenuBar && !ShouldAutoExpandOnClick) + { + System.Windows.Forms.Control objCtrl = this.ContainerControl as System.Windows.Forms.Control; + if (objCtrl == null) + return; + + //Point p=objCtrl.PointToClient(new Point(objArg.X,objArg.Y)); + objCtrl = null; + if (!rsub.Contains(objArg.X, objArg.Y)) + { + bool bCollapse = true; + if (this.PopupType == ePopupType.ToolBar || this.PopupType == ePopupType.Menu) + { + bool bExpanded = this.Expanded; + base.InternalMouseUp(objArg); + // Do not collapse if user has expanded it in Click event + if (!bExpanded && this.Expanded) + bCollapse = false; + bCallBase = false; + } + if (bCollapse) + CollapseAll(this); + } + } + } + + if (!this.IsOnMenu || this.Parent is ItemContainer) + { + // If user clicks on expand sub items part of this button do not raise the click event, do not call base MouseUp + if ((this.SubItems.Count > 0 || (this.PopupType == ePopupType.Container && !this.IsOnCustomizeMenu)) && this.ShowSubItems) + { + if (rsub.Contains(objArg.X, objArg.Y)) + bCallBase = false; + } + } + + if (bCallBase) + base.InternalMouseUp(objArg); + + if (!m_MouseDown) + return; + + m_MouseDown = false; + + if (!this.IsOnMenu || !(this.Parent is ButtonItem)) + { + this.Refresh(); + } + } + + internal void SetMouseDown(bool mouseDown) + { + m_MouseDown = mouseDown; + } + + /// + /// Occurs when the item is double clicked. This is used by internal implementation only. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalDoubleClick(System.Windows.Forms.MouseButtons mb, System.Drawing.Point mpos) + { + base.InternalDoubleClick(mb, mpos); + + if (this.Expanded && this.IsOnMenuBar + && m_Parent != null && !this.DesignMode && this.PopupType == ePopupType.Menu && + (this.PersonalizedMenus == ePersonalizedMenus.Both || this.PersonalizedMenus == ePersonalizedMenus.DisplayOnClick)) + { + if (this.PopupControl is MenuPanel) + ((MenuPanel)this.PopupControl).ExpandRecentlyUsed(); + } + } + + /*public override void InternalClick(System.Windows.Forms.MouseButtons mb, System.Drawing.Point mpos) + { + if(m_Enabled && !this.DesignMode) + { + if(m_MenuVisibility==eMenuVisibility.VisibleIfRecentlyUsed && !m_RecentlyUsed && this.IsOnMenu) + { + // Propagate to the top + m_RecentlyUsed=true; + BaseItem objItem=this.Parent; + while(objItem!=null) + { + IPersonalizedMenuItem ipm=objItem as IPersonalizedMenuItem; + if(ipm!=null) + ipm.RecentlyUsed=true; + objItem=objItem.Parent; + } + } + } + + // Since base item does not auto-collapse when clicked if it has subitems and it is on + // pop-up we need to handle that here and check did user click on expand part of this button + // and if they did not we need to raise click event and collapse the item. + if(!this.IsOnMenu && (this.SubItemsCount>0 || this.PopupType==ePopupType.Container) && this.ShowSubItems && m_HotSubItem==null && !this.DesignMode && !this.IsOnMenuBar) + { + Rectangle r=new Rectangle(m_SubItemsRect.X,m_SubItemsRect.Y,m_SubItemsRect.Width,m_SubItemsRect.Height); + r.Offset(m_Rect.X,m_Rect.Y); + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl==null) + { + base.InternalClick(mb,mpos); + return; + } + Point p=objCtrl.PointToClient(mpos); + objCtrl=null; + if(!r.Contains(p)) + { + CollapseAll(this); + RaiseClick(); + } + } + else + base.InternalClick(mb,mpos); + }*/ + + // private void CreateDisabledImage() + // { + // if(m_Image==null && m_ImageIndex<0 && m_Icon==null) + // return; + // if(m_DisabledImage!=null) + // m_DisabledImage.Dispose(); + // m_DisabledImage=null; + // + // CompositeImage defaultImage=GetImage(ImageState.Default); + // + // if(defaultImage==null) + // return; + // if(!defaultImage.IsIcon && defaultImage.Image!=null && defaultImage.Image is Bitmap) + // { + // m_DisabledImage=BarFunctions.CreateDisabledBitmap((Bitmap)defaultImage.Image); + // } + // } + private void CreateDisabledImage() + { + if (m_Image == null && m_ImageIndex < 0 && m_Icon == null) + return; + if (m_DisabledImage != null) + m_DisabledImage.Dispose(); + m_DisabledImage = null; + if (m_DisabledIcon != null) + m_DisabledIcon.Dispose(); + m_DisabledIcon = null; + + CompositeImage defaultImage = GetImage(ImageState.Default, Color.Black); + + if (defaultImage == null) + return; + + if (this.GetOwner() is IOwner && ((IOwner)this.GetOwner()).DisabledImagesGrayScale) + { + if (defaultImage.IsIcon) + { + m_DisabledIcon = BarFunctions.CreateDisabledIcon(defaultImage.Icon); + } + else + { + m_DisabledImage = ImageHelper.CreateGrayScaleImage(defaultImage.Image as Bitmap); + } + } + if (m_DisabledIcon != null || m_DisabledImage != null) + return; + + // Use old algorithm if first one failed... + System.Drawing.Imaging.PixelFormat pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppArgb; + if (!defaultImage.IsIcon && defaultImage.Image != null) + pixelFormat = defaultImage.Image.PixelFormat; + + if (pixelFormat == System.Drawing.Imaging.PixelFormat.Format1bppIndexed || pixelFormat == System.Drawing.Imaging.PixelFormat.Format4bppIndexed || pixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed) + pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppArgb; + + Bitmap bmp = new Bitmap(defaultImage.Width, defaultImage.Height, pixelFormat); + m_DisabledImage = new Bitmap(defaultImage.Width, defaultImage.Height, pixelFormat); + + Graphics g2 = Graphics.FromImage(bmp); + using (SolidBrush brush = new SolidBrush(System.Drawing.Color.White)) + g2.FillRectangle(brush, 0, 0, defaultImage.Width, defaultImage.Height); + //g2.DrawImage(defaultImage,0,0,defaultImage.Width,defaultImage.Height); + defaultImage.DrawImage(g2, new Rectangle(0, 0, defaultImage.Width, defaultImage.Height)); + g2.Dispose(); + g2 = Graphics.FromImage(m_DisabledImage); + + bmp.MakeTransparent(System.Drawing.Color.White); + eDotNetBarStyle effectiveStyle = EffectiveStyle; + if ((effectiveStyle == eDotNetBarStyle.OfficeXP || effectiveStyle == eDotNetBarStyle.Office2003 || effectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(effectiveStyle)) && NativeFunctions.ColorDepth >= 8) + { + float[][] array = new float[5][]; + array[0] = new float[5] { 0, 0, 0, 0, 0 }; + array[1] = new float[5] { 0, 0, 0, 0, 0 }; + array[2] = new float[5] { 0, 0, 0, 0, 0 }; + array[3] = new float[5] { .5f, .5f, .5f, .5f, 0 }; + array[4] = new float[5] { 0, 0, 0, 0, 0 }; + System.Drawing.Imaging.ColorMatrix grayMatrix = new System.Drawing.Imaging.ColorMatrix(array); + System.Drawing.Imaging.ImageAttributes disabledImageAttr = new System.Drawing.Imaging.ImageAttributes(); + disabledImageAttr.ClearColorKey(); + disabledImageAttr.SetColorMatrix(grayMatrix); + g2.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, disabledImageAttr); + } + else + System.Windows.Forms.ControlPaint.DrawImageDisabled(g2, bmp, 0, 0, ColorFunctions.MenuBackColor(g2)); + + // Clean up + g2.Dispose(); + g2 = null; + bmp.Dispose(); + bmp = null; + + defaultImage.Dispose(); + } + + private eTextFormat GetStringFormat() + { + eTextFormat format = eTextFormat.Default; + if (!_FitContainer) + { + format |= eTextFormat.SingleLine; + } + else + format |= eTextFormat.WordBreak; + + format |= eTextFormat.VerticalCenter; + return format; + + // //bool bMenuBar=this.IsOnMenuBar; + // StringFormat sfmt=BarFunctions.CreateStringFormat(); //new StringFormat(StringFormat.GenericDefault); + // if(NativeFunctions.ShowKeyboardCues /*&& bMenuBar*/ || this.IsOnMenu) + // sfmt.HotkeyPrefix=System.Drawing.Text.HotkeyPrefix.Show; + // else/* if(bMenuBar)*/ + // { + // System.Windows.Forms.Control ctrl=this.ContainerControl as System.Windows.Forms.Control; + // if(ctrl!=null && (ctrl.Focused || ctrl is Bar && ((Bar)ctrl).MenuFocus) || ctrl is NavigationBar) + // sfmt.HotkeyPrefix=System.Drawing.Text.HotkeyPrefix.Show; + // else + // sfmt.HotkeyPrefix=System.Drawing.Text.HotkeyPrefix.Hide; + // } + //// else + //// sfmt.HotkeyPrefix=System.Drawing.Text.HotkeyPrefix.Hide; + + // //sfmt.FormatFlags=sfmt.FormatFlags & ~(sfmt.FormatFlags & StringFormatFlags.DisableKerning); + // if(_FitContainer) + // { + // sfmt.FormatFlags=sfmt.FormatFlags & ~(sfmt.FormatFlags & StringFormatFlags.NoWrap); + // } + // else + // { + // sfmt.FormatFlags=sfmt.FormatFlags | StringFormatFlags.NoWrap; + // } + // sfmt.Trimming=StringTrimming.EllipsisCharacter; + // sfmt.Alignment=System.Drawing.StringAlignment.Near; + // sfmt.LineAlignment=System.Drawing.StringAlignment.Center; + + // return sfmt; + } + + private ThemeTextFormat GetThemeTextFormat() + { + ThemeTextFormat format = ThemeTextFormat.Left | ThemeTextFormat.HidePrefix | + ThemeTextFormat.WordEllipsis | + ThemeTextFormat.VCenter; + return format; + } + + private Font _MouseOverFont = null; + /// + /// Returns the Font object to be used for drawing the item text. + /// + /// Font object. + internal virtual Font GetFont(ItemPaintArgs pa, bool isLayout) + { + System.Drawing.Font objFont = null; + + if (pa != null) + objFont = pa.Font; + + if (objFont == null) + { + System.Windows.Forms.Control objCtrl = null; + if (pa != null) + objCtrl = pa.ContainerControl; + if (objCtrl == null) + objCtrl = this.ContainerControl as System.Windows.Forms.Control; + if (objCtrl != null) + { + if (objCtrl.Font != null) + objFont = (Font)objCtrl.Font; + } + else + objFont = (Font)SystemFonts.DefaultFont; + } + + if (m_MouseOver || isLayout && (m_HotFontBold || m_HotFontUnderline)) + { + if (_MouseOverFont != null && objFont != null && objFont.FontFamily.Name == _MouseOverFont.FontFamily.Name && objFont.SizeInPoints == _MouseOverFont.SizeInPoints) + return _MouseOverFont; + try + { + Font mouseOverFont = null; + FontStyle fontStyle = objFont.Style; + if (m_HotFontBold) fontStyle |= FontStyle.Bold; + if (m_HotFontUnderline) fontStyle |= FontStyle.Underline; + mouseOverFont = new Font(objFont, fontStyle); + DisposeMouseOverFont(); + _MouseOverFont = mouseOverFont; + return _MouseOverFont; + } + catch + { + + } + } + + if (m_FontBold || m_FontItalic || m_FontUnderline) + { + FontStyle style = objFont.Style; + if (m_FontBold) + style = style | System.Drawing.FontStyle.Bold; + if (m_FontItalic) + style = style | System.Drawing.FontStyle.Italic; + if (m_FontUnderline) + style = style | System.Drawing.FontStyle.Underline; + Font font = null; + try + { + font = new Font(objFont, style); + } + catch { } + if (font != null) + objFont = font; + } + + return objFont; + } + + private void DisposeMouseOverFont() + { + if (_MouseOverFont != null) + { + _MouseOverFont.Dispose(); + _MouseOverFont = null; + } + } + + /// + /// Gets or sets whether Checked property is automatically inverted, button checked/unchecked, when button is clicked. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Behavior"), Description("Indicates whether Checked property is automatically inverted when button is clicked.")] + public virtual bool AutoCheckOnClick + { + get { return m_AutoCheckOnClick; } + set { m_AutoCheckOnClick = value; } + } + + /// + /// Gets or set a value indicating whether the button is in the checked state. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Indicates whether item is checked or not."), DefaultValue(false), Bindable(true)] + public virtual bool Checked + { + get + { + return m_Checked; + } + set + { + if (m_Checked != value) + { + // Allow user to cancel the checking + if (value && m_OptionGroup.Length > 0 && this.Parent != null) + { + ButtonItem b = null; + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this) + continue; + b = item as ButtonItem; + if (b != null && b.OptionGroup == m_OptionGroup && b.Checked) + { + break; + } + } + OptionGroupChangingEventArgs e = new OptionGroupChangingEventArgs(b, this); + InvokeOptionGroupChanging(e); + if (e.Cancel) + return; + } + + m_Checked = value; + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "Checked"); + this.OnCheckedChanged(); + if (this.Displayed) + this.Refresh(); + OnAppearanceChanged(); + } + } + } + + /// + /// Called after Checked property has changed. + /// + protected virtual void OnCheckedChanged() + { + if (m_OptionGroup != "" && m_Checked && this.Parent != null) + { + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this) + continue; + ButtonItem b = item as ButtonItem; + if (b != null && b.OptionGroup == m_OptionGroup && b.Checked) + b.Checked = false; + } + } + InvokeCheckedChanged(); + } + + /// + /// Called when Visibility of the items has changed. + /// + /// New Visible state. + protected internal override void OnVisibleChanged(bool bVisible) + { + base.OnVisibleChanged(bVisible); + + if (!bVisible) + { + StopFade(); + StopImageAnimation(); + } + + if (!bVisible && this.Checked && m_OptionGroup != "") + { + this.Checked = false; + // Try to check first item in the group + if (this.Parent != null) + { + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this || !item.GetEnabled() || !item.Visible) + continue; + ButtonItem b = item as ButtonItem; + if (b != null && b.OptionGroup == m_OptionGroup) + { + b.Checked = true; + break; + } + } + } + } + else if (bVisible && m_OptionGroup != "" && this.VisibleSubItems <= 1) + { + bool checkIt = true; + // Try to check first item in the group + if (this.Parent != null) + { + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this || !item.GetEnabled() || !item.Visible) + continue; + ButtonItem b = item as ButtonItem; + if (b != null && b.OptionGroup == m_OptionGroup && b.Checked) + { + checkIt = false; + break; + } + } + } + if (checkIt) + this.Checked = true; + } + } + + /// + /// Sets Checked property without firing any events or performing any built-in logic. + /// + internal void SetChecked(bool b) + { + m_Checked = b; + } + + /// + /// Fires CheckedChanged event. + /// + protected virtual void InvokeCheckedChanged() + { + if (CheckedChanged != null) + CheckedChanged(this, new EventArgs()); + IOwnerItemEvents owner = this.GetIOwnerItemEvents(); + if (owner != null) + owner.InvokeCheckedChanged(this, new EventArgs()); + } + + /// + /// Fires OptionGroupChanging event. + /// + protected virtual void InvokeOptionGroupChanging(OptionGroupChangingEventArgs e) + { + if (OptionGroupChanging != null) + OptionGroupChanging(this, e); + if (!e.Cancel) + { + IOwnerItemEvents owner = this.GetIOwnerItemEvents(); + if (owner != null) + owner.InvokeOptionGroupChanging(this, e); + } + } + + /// + /// Occurs just before Click event is fired. + /// + protected override void OnClick() + { + if (m_AutoCheckOnClick && m_OptionGroup == "") + this.Checked = !this.Checked; + base.OnClick(); + if (m_OptionGroup != "" && !m_Checked) + this.Checked = true; + ExecuteCommand(); + } + + protected override void OnCommandChanged() + { + if (!this.DesignMode && this.Command == null) + this.Enabled = false; + base.OnCommandChanged(); + } + + /// + /// Gets or set the alternative shortcut text. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Design"), System.ComponentModel.Description("Gets or set the alternative Shortcut Text. This text appears next to the Text instead of any shortcuts"), System.ComponentModel.DefaultValue(""), Localizable(true)] + public virtual string AlternateShortCutText + { + get + { + return m_AlternateShortcutText; + } + set + { + m_AlternateShortcutText = value; + OnAppearanceChanged(); + } + } + + /// + /// Returns shortcut text if any that needs to be displayed. + /// + internal string DrawShortcutText + { + get + { + if (this.AlternateShortCutText != "") + return this.AlternateShortCutText; + else + return this.ShortcutString; + } + } + + /// + /// Returns the shortcut string that is displayed on tooltip. + /// + /// + protected override string GetTooltipShortcutString() + { + return this.DrawShortcutText; + } + + /// + /// Gets or sets the image bounds. + /// + internal Rectangle ImageDrawRect + { + get { return m_ImageDrawRect; } + set { m_ImageDrawRect = value; } + } + + /// + /// Gets or sets sub items bounds. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle SubItemsRect + { + get { return m_SubItemsRect; } + set { m_SubItemsRect = value; } + } + + /// + /// Gets or sets text bounds. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle TextDrawRect + { + get { return m_TextDrawRect; } + set { m_TextDrawRect = value; } + } + + + /// + /// Gets or set the Group item belongs to. The groups allows a user to choose from mutually exclusive options within the group. The choice is reflected by Checked property. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Behavior"), System.ComponentModel.Description("Gets or set the Group item belongs to. The groups allows a user to choose from mutually exclusive options within the group."), System.ComponentModel.DefaultValue("")] + public virtual string OptionGroup + { + get + { + return m_OptionGroup; + } + set + { + if (m_OptionGroup != value) + { + m_OptionGroup = value; + if (m_OptionGroup != "" && m_Checked && this.Parent != null) + { + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this) + continue; + ButtonItem b = item as ButtonItem; + if (b != null && b.OptionGroup == m_OptionGroup && b.Checked) + this.Checked = false; + } + } + OnAppearanceChanged(); + } + } + } + + private eColorSchemePart _ForeColorColorSchemePart = eColorSchemePart.None; + internal eColorSchemePart ForeColorColorSchemePart + { + get + { + return _ForeColorColorSchemePart; + } + set + { + _ForeColorColorSchemePart = value; + } + } + /// + /// Gets or sets the text color of the button. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The foreground color used to display text.")] + public virtual Color ForeColor + { + get + { + return m_ForeColor; + } + set + { + if (m_ForeColor != value) + { + m_ForeColor = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "ForeColor"); + + if (this.Displayed) + this.Refresh(); + OnAppearanceChanged(); + } + } + } + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public bool ShouldSerializeForeColor() + { + if (m_ForeColor.IsEmpty) + return false; + return true; + } + + /// + /// Gets or sets the text color of the button when mouse is over the item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The foreground color used to display text when mouse is over the item.")] + public virtual Color HotForeColor + { + get + { + return m_HotForeColor; + } + set + { + if (m_HotForeColor != value) + { + m_HotForeColor = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "HotForeColor"); + + if (this.Displayed && m_MouseOver) + this.Refresh(); + OnAppearanceChanged(); + } + } + } + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public bool ShouldSerializeHotForeColor() + { + if (m_HotForeColor.IsEmpty) + return false; + return true; + } + + /// + /// Gets or sets whether the font used to draw the item text is underlined when mouse is over the item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Specifies that text font is underlined when mouse is over the item."), System.ComponentModel.DefaultValue(false)] + public virtual bool HotFontUnderline + { + get + { + return m_HotFontUnderline; + } + set + { + if (m_HotFontUnderline != value) + { + DisposeMouseOverFont(); + m_HotFontUnderline = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "HotFontUnderline"); + + if (this.Displayed && m_MouseOver) + this.Refresh(); + OnAppearanceChanged(); + } + } + } + + /// + /// Gets or sets whether the font used to draw the item text is bold when mouse is over the item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Specifies that text font is bold when mouse is over the item."), System.ComponentModel.DefaultValue(false)] + public virtual bool HotFontBold + { + get + { + return m_HotFontBold; + } + set + { + if (m_HotFontBold != value) + { + DisposeMouseOverFont(); + m_HotFontBold = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "HotFontBold"); + + if (this.Displayed && m_MouseOver) + this.Refresh(); + OnAppearanceChanged(); + } + } + } + + /// + /// Gets or sets whether the font used to draw the item text is bold. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Specifies whether the font used to draw the item text is bold."), System.ComponentModel.DefaultValue(false)] + public virtual bool FontBold + { + get + { + return m_FontBold; + } + set + { + if (m_FontBold != value) + { + m_FontBold = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "FontBold"); + + if (this.Displayed) + this.Refresh(); + OnAppearanceChanged(); + } + } + } + + /// + /// Gets or sets whether the font used to draw the item text is italic. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Specifies whether the font used to draw the item text is italic."), System.ComponentModel.DefaultValue(false)] + public virtual bool FontItalic + { + get + { + return m_FontItalic; + } + set + { + if (m_FontItalic != value) + { + m_FontItalic = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "FontItalic"); + + if (this.Displayed) + this.Refresh(); + OnAppearanceChanged(); + } + } + } + + /// + /// Gets or sets whether the font used to draw the item text is underlined. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Specifies whether the font used to draw the item text is underlined."), System.ComponentModel.DefaultValue(false)] + public virtual bool FontUnderline + { + get + { + return m_FontUnderline; + } + set + { + if (m_FontUnderline != value) + { + m_FontUnderline = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "FontUnderline"); + + if (this.Displayed) + this.Refresh(); + OnAppearanceChanged(); + } + } + } + + + /// + /// Gets or sets the width of the expand part of the button item. + /// + [Browsable(true), DevCoBrowsable(true), Category("Behavior"), Description("Indicates the width of the expand part of the button item."), DefaultValue(12)] + public virtual int SubItemsExpandWidth + { + get { return m_SubItemsExpandWidth; } + set + { + m_SubItemsExpandWidth = value; + NeedRecalcSize = true; + if (this.DesignMode) + this.Refresh(); + OnAppearanceChanged(); + } + } + + /// + /// Returns the collection of sub items. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(false), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ButtonItemEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.Category("Data"), System.ComponentModel.Description("Collection of sub items."), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)] + public override SubItemsCollection SubItems + { + get + { + return base.SubItems; + } + } + + /// + /// Gets or sets whether button appears as split button. Split button appearance divides button into two parts. Image which raises the click event + /// when clicked and text and expand sign which shows button sub items on popup menu when clicked. Button must have both text and image visible (ButtonStyle property) in order to appear as a full split button. + /// Use AutoExpandOnClick=true if you want to make complete surface of the button display popup when clicked. + /// + [Browsable(true), DefaultValue(false), Category("Appearance"), Description("Indicates whether button appears as split button. Use AutoExpandOnClick=true if you want to make complete surface of the button display popup when clicked.")] + public virtual bool SplitButton + { + get { return m_SplitButton; } + set + { + m_SplitButton = value; + OnAppearanceChanged(); + } + } + + internal Rectangle GetTotalSubItemsRect() + { + Rectangle r = this.SubItemsRect; + if (this.SplitButton && (this.ButtonStyle == eButtonStyle.ImageAndText || this.ImagePosition == eImagePosition.Top || this.ImagePosition == eImagePosition.Bottom) + && (this.Image != null || this.ImageIndex >= 0 || !string.IsNullOrEmpty(this.SymbolRealized)) && this.Text.Length > 0) + { + Rectangle rText = this.TextDrawRect; + rText.Inflate(0, -2); + if (this.ImagePosition == eImagePosition.Left) + { + if (this.Orientation == eOrientation.Horizontal) + rText.X -= 3; + else + rText.Y -= 6; + } + if (r.IsEmpty) + { + r = rText; + if (m_ImagePosition == eImagePosition.Top) + { + r.X = 0;// m_Rect.X - 1; + r.Width = m_Rect.Width; + r.Height = this.DisplayRectangle.Bottom - r.Y; + } + else if (m_ImagePosition == eImagePosition.Bottom) + { + r.X = 0;// m_Rect.X - 1; + r.Width = m_Rect.Width; + } + } + else + r = Rectangle.Union(r, rText); + return r; + } + return r; + } + + /// + /// Gets or sets the text associated with this item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The text contained in the item."), System.ComponentModel.Localizable(true), System.ComponentModel.DefaultValue("")] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + internal int VerticalPadding + { + get { return m_VerticalPadding; } + set { m_VerticalPadding = value; } + } + + internal int HorizontalPadding + { + get { return m_HorizontalPadding; } + set { m_HorizontalPadding = value; } + } + + /// + /// Gets or sets the amount of padding added horizontally to the button images when not on menus. Default value is 10 pixels. + /// + [Browsable(true), DefaultValue(8), Category("Layout"), Description("Indicates amount of padding added horizontally to the button images when not on menus")] + public virtual int ImagePaddingHorizontal + { + get { return m_ImagePaddingHorizontal; } + set + { + m_ImagePaddingHorizontal = value; + this.OnAppearanceChanged(); + } + } + + /// + /// Gets or sets the amount of padding added vertically to the button images when not on menus. Default value is 6 pixels. + /// + [Browsable(true), DefaultValue(6), Category("Layout"), Description("Indicates amount of padding added vertically to the button images when not on menus")] + public virtual int ImagePaddingVertical + { + get { return m_ImagePaddingVertical; } + set + { + m_ImagePaddingVertical = value; + this.OnAppearanceChanged(); + } + } + /// + /// Gets or sets the current font for the button. + /// + // public System.Drawing.Font Font + // { + // get + // { + // return m_Font; + // } + // set + // { + // if(m_Font!=value) + // { + // m_Font=value; + // if(this.Displayed) + // this.Refresh(); + // } + // } + // } + + private ShapeDescriptor _Shape = null; + /// + /// Gets or sets an shape descriptor for the button which describes the shape of the button. Default value is null + /// which indicates that system default shape is used. + /// + [DefaultValue(null), Editor("DevComponents.DotNetBar.Design.ShapeTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), TypeConverter("DevComponents.DotNetBar.Design.ShapeStringConverter, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), MergableProperty(false)] + public virtual ShapeDescriptor Shape + { + get { return _Shape; } + set + { + if (_Shape != value) + { + _Shape = value; + this.OnAppearanceChanged(); + } + } + } + + protected override void OnDisplayedChanged() + { + // Reset all internal states upon display changed + m_MouseDown = false; + m_MouseOver = false; + if (!this.Displayed && _CurrentlyAnimatingImage) + StopImageAnimation(); + } + + // IPersonalizedMenuItem Impementation + /// + /// Indicates item's visibility when on pop-up menu. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Indicates item's visiblity when on pop-up menu."), System.ComponentModel.DefaultValue(eMenuVisibility.VisibleAlways)] + public virtual eMenuVisibility MenuVisibility + { + get + { + return m_MenuVisibility; + } + set + { + if (m_MenuVisibility != value) + { + m_MenuVisibility = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "MenuVisibility"); + } + } + } + + /// + /// Indicates whether item was recently used. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public bool RecentlyUsed + { + get + { + return m_RecentlyUsed; + } + set + { + if (m_RecentlyUsed != value) + { + m_RecentlyUsed = value; + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "RecentlyUsed"); + + OnAppearanceChanged(); + } + } + } + + /// + /// Indicates whether mouse is over the item. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public bool IsMouseOver + { + get { return m_MouseOver; } + } + + /// + /// Indicates whether mouse is over the expand part of the button. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public bool IsMouseOverExpand + { + get { return m_MouseOverExpand; } + } + + /// + /// Indicates whether mouse is pressed. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public bool IsMouseDown + { + get { return m_MouseDown; } + } + + /// + /// Indicates the way item is painting the picture when mouse is over it. Setting the value to Color will render the image in gray-scale when mouse is not over the item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Indicates the way item is painting the picture when mouse is over it. Setting the value to Color will render the image in gray-scale when mouse is not over the item."), System.ComponentModel.DefaultValue(eHotTrackingStyle.Default)] + public virtual eHotTrackingStyle HotTrackingStyle + { + get { return m_HotTrackingStyle; } + set + { + if (m_HotTrackingStyle == value) + return; + m_HotTrackingStyle = value; + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "HotTrackingStyle"); + this.Refresh(); + OnAppearanceChanged(); + } + } + + // Property Editor support for ImageIndex selection + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public System.Windows.Forms.ImageList ImageList + { + get + { + IOwner owner = this.GetOwner() as IOwner; + if (owner != null) + return owner.Images; + return null; + } + } + + /// + /// Gets or sets whether the button text is automatically wrapped over multiple lines when button is used on RibbonBar control. Default value is true. + /// + [Browsable(true), DefaultValue(true), Localizable(true), Category("Ribbon"), Description("Indicates whether the button text is automatically wrapped over multiple lines when button is used on RibbonBar control.")] + public virtual bool RibbonWordWrap + { + get { return m_RibbonWordWrap; } + set + { + if (m_RibbonWordWrap != value) + { + m_RibbonWordWrap = value; + this.OnAppearanceChanged(); + } + } + } + + private bool _EnableImageAnimation = false; + /// + /// Gets or sets whether image animation is enabled + /// + [Browsable(true), DevCoBrowsable(true)] + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether image animation is enabled.")] + public bool EnableImageAnimation + { + get { return (_EnableImageAnimation); } + + set + { + if (_EnableImageAnimation != value) + { + _EnableImageAnimation = value; + this.Refresh(); + } + } + } + + /// + /// Creates new ButtonItem with text set to corresponding item from string array and adds it to SubItems collection. + /// + /// + public void AddSubItems(string[] itemTexts) + { + AddSubItems(itemTexts, null); + } + + /// + /// Creates new ButtonItem with text set to corresponding item from string array and adds it to SubItems collection. + /// + /// Click event handler assigned to each item + public void AddSubItems(string[] itemTexts, EventHandler clickHandler) + { + if (itemTexts == null || itemTexts.Length == 0) return; + for (int i = 0; i < itemTexts.Length; i++) + { + ButtonItem item = new ButtonItem(); + item.Text = itemTexts[i]; + if (clickHandler != null) + item.Click += clickHandler; + this.SubItems.Add(item); + } + } + + #endregion + + #region Markup Implementation + /// + /// Gets whether item supports text markup. Default is false. + /// + protected override bool IsMarkupSupported + { + get { return _EnableMarkup; } + } + + private bool _EnableMarkup = true; + /// + /// Gets or sets whether text-markup support is enabled for items Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the item instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for items Text property.")] + public bool EnableMarkup + { + get { return _EnableMarkup; } + set + { + if (_EnableMarkup != value) + { + _EnableMarkup = value; + NeedRecalcSize = true; + OnTextChanged(); + } + } + } + + /// + /// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + [Description("Occurs when text markup link is clicked. Markup links can be created using a tag.")] + public event MarkupLinkClickEventHandler MarkupLinkClick; + protected override void TextMarkupLinkClick(object sender, EventArgs e) + { + TextMarkup.HyperLink link = sender as TextMarkup.HyperLink; + if (link != null) + OnMarkupLinkClick(new MarkupLinkClickEventArgs(link.Name, link.HRef)); + base.TextMarkupLinkClick(sender, e); + } + protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e) + { + if (this.MarkupLinkClick != null) + MarkupLinkClick(this, e); + } + #endregion + + #region ButtonItemAccessibleObject + /// + /// Represents accessible interface for ButtonItem object. + /// + public class ButtonItemAccessibleObject : BaseItem.ItemAccessibleObject + { + private ButtonItemPartAccessibleObject m_PushButtonPart = null; + private ButtonItemPartAccessibleObject m_ExpandPart = null; + + public ButtonItemAccessibleObject(BaseItem owner) : base(owner) { } + + internal ButtonItem ButtonItem + { + get { return this.Owner as ButtonItem; } + } + + private ButtonItemPartAccessibleObject AccessiblePushButtonPart + { + get + { + if (m_PushButtonPart == null) + { + m_PushButtonPart = new ButtonItemPartAccessibleObject(this.ButtonItem, true); + } + return m_PushButtonPart; + } + } + + private ButtonItemPartAccessibleObject AccessibleExpandPart + { + get + { + if (m_ExpandPart == null) + { + m_ExpandPart = new ButtonItemPartAccessibleObject(this.ButtonItem, false); + } + return m_ExpandPart; + } + } + + public override System.Windows.Forms.AccessibleRole Role + { + get + { + if (IsSplitButton) + return System.Windows.Forms.AccessibleRole.Grouping; + return base.Role; + } + } + + private bool IsSplitButton + { + get + { + ButtonItem b = this.ButtonItem; + if (b.VisibleSubItems > 0 && !b.AutoExpandOnClick && !b.IsOnMenu && !b.IsOnMenuBar) + return true; + return false; + } + } + + public override System.Windows.Forms.AccessibleStates State + { + get + { + if (this.IsSplitButton) + { + if (this.Owner == null || !this.Owner.IsAccessible) + return System.Windows.Forms.AccessibleStates.Unavailable; + + System.Windows.Forms.AccessibleStates state = 0; + + if (!this.Owner.Displayed || !this.Owner.Visible) + state |= System.Windows.Forms.AccessibleStates.Invisible; + else if (!this.Owner.GetEnabled()) + { + return System.Windows.Forms.AccessibleStates.Unavailable; + } + + return System.Windows.Forms.AccessibleStates.Default; + } + + System.Windows.Forms.AccessibleStates st = base.State; + + if (this.ButtonItem.GetEnabled()) + { + if (this.ButtonItem.Checked || this.ButtonItem.IsMouseDown) + st |= System.Windows.Forms.AccessibleStates.Pressed; + } + return st; + } + } + + public override int GetChildCount() + { + if (IsSplitButton) + return 2; + return base.GetChildCount(); + } + + public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) + { + if (IsSplitButton) + { + if (iIndex == 0) + return this.AccessiblePushButtonPart; + else if (iIndex == 1) + return this.AccessibleExpandPart; + } + + return base.GetChild(iIndex); + } + + public override AccessibleObject Navigate(AccessibleNavigation navdir) + { + if (IsSplitButton) + { + //if (navdir == AccessibleNavigation.FirstChild) + // return this.AccessiblePushButtonPart; + //else if (navdir == AccessibleNavigation.LastChild) + // return this.AccessibleExpandPart; + return null; + } + return base.Navigate(navdir); + } + + public override string DefaultAction + { + get + { + if (this.IsSplitButton) + return ""; + else + return base.DefaultAction; + } + } + + public override void DoDefaultAction() + { + if (!this.IsSplitButton) + base.DoDefaultAction(); + } + + public override string KeyboardShortcut + { + get + { + return ""; + } + } + + public override System.Windows.Forms.AccessibleObject GetSelected() + { + if (this.IsSplitButton) + { + if (this.ButtonItem.IsMouseOverExpand) + return this.AccessibleExpandPart; + else if (this.ButtonItem.IsMouseOver) + return this.AccessiblePushButtonPart; + return null; + } + else + return base.GetSelected(); + } + + public override System.Windows.Forms.AccessibleObject HitTest(int x, int y) + { + if (this.IsSplitButton) + { + Rectangle r = this.AccessiblePushButtonPart.Bounds; + if (r.Contains(x, y)) + return this.AccessiblePushButtonPart; + r = this.AccessibleExpandPart.Bounds; + if (r.Contains(x, y)) + return this.AccessibleExpandPart; + + return null; + } + return base.HitTest(x, y); + } + } + + /// + /// Represents accessible interface for ButtonItem object. + /// + public class ButtonItemPartAccessibleObject : System.Windows.Forms.AccessibleObject + { + private ButtonItem m_Button = null; + //private bool m_Hot = false; + private bool m_PushButtonPart = true; + + public ButtonItemPartAccessibleObject(ButtonItem owner, bool pushButtonPart) + { + m_Button = owner; + m_PushButtonPart = pushButtonPart; + } + + public override string Name + { + get + { + if (!m_PushButtonPart) return "Open"; + + if (m_Button == null) + return ""; + + if (m_Button.AccessibleName != "") + return m_Button.AccessibleName; + + if (m_Button.Text != null) + return m_Button.Text.Replace("&", ""); + + return m_Button.Tooltip; + } + set + { + m_Button.AccessibleName = value; + } + } + + public override string Description + { + get + { + if (m_Button == null) + return ""; + if (m_Button.AccessibleDescription != "") + return m_Button.AccessibleDescription; + return Name + " button"; + } + } + + public override System.Windows.Forms.AccessibleRole Role + { + get + { + if (m_PushButtonPart) + { +#if FRAMEWORK20 + return System.Windows.Forms.AccessibleRole.SplitButton; +#else + return System.Windows.Forms.AccessibleRole.PushButton; +#endif + } + + return System.Windows.Forms.AccessibleRole.ButtonDropDown; + } + } + + public override System.Windows.Forms.AccessibleStates State + { + get + { + if (m_Button == null) + return System.Windows.Forms.AccessibleStates.Unavailable; + + System.Windows.Forms.AccessibleStates state = 0; + + if (!m_Button.IsAccessible) + return System.Windows.Forms.AccessibleStates.Unavailable; + + if (!m_Button.Displayed || !m_Button.Visible) + state |= System.Windows.Forms.AccessibleStates.Invisible; + else if (!m_Button.GetEnabled()) + { + state = System.Windows.Forms.AccessibleStates.Unavailable; + } + else + { + if (m_PushButtonPart) + { + if (m_Button.IsMouseOver && !m_Button.IsMouseOverExpand) + state |= System.Windows.Forms.AccessibleStates.HotTracked | System.Windows.Forms.AccessibleStates.Focused; + else + state |= System.Windows.Forms.AccessibleStates.Focusable; + } + else + { + if (m_Button.Expanded || m_Button.IsMouseOverExpand) + state |= (System.Windows.Forms.AccessibleStates.Focused | System.Windows.Forms.AccessibleStates.HotTracked); + if (m_Button.Expanded) + state |= System.Windows.Forms.AccessibleStates.Expanded; + else + state |= System.Windows.Forms.AccessibleStates.Collapsed; + } + } + return state; + } + } + + public override System.Windows.Forms.AccessibleObject Parent + { + get + { + return m_Button.AccessibleObject; + } + } + + public override System.Drawing.Rectangle Bounds + { + get + { + System.Windows.Forms.Control parent = m_Button.ContainerControl as System.Windows.Forms.Control; + Rectangle r = Rectangle.Empty; + + if (m_PushButtonPart) + { + Rectangle rs = m_Button.SubItemsRect; + rs.Offset(m_Button.Bounds.Location); + r = m_Button.Bounds; + if (rs.X == r.X && rs.Y == r.Y) + { + r.X += rs.Width; + r.Width -= rs.Width; + } + else if (rs.X == r.X && rs.Bottom == r.Bottom && rs.Y > r.Y) + { + r.Y += rs.Height; + r.Height -= rs.Height; + } + else + { + r.Width -= rs.Width; + } + } + else + { + r = m_Button.SubItemsRect; + r.Offset(m_Button.Bounds.Location); + } + if (parent != null) + r.Location = parent.PointToScreen(r.Location); + return r; + } + } + + public override int GetChildCount() + { + if (m_PushButtonPart) + return 0; + return m_Button.SubItems.Count; + } + + public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) + { + if (m_Button == null || m_PushButtonPart) + return null; + + return m_Button.SubItems[iIndex].AccessibleObject; + } + + public override string DefaultAction + { + get + { + if (m_Button.AccessibleDefaultActionDescription != "") + return m_Button.AccessibleDefaultActionDescription; + if (m_PushButtonPart) + return "Press"; + else + return "Open"; + } + } + + public override void DoDefaultAction() + { + if (m_Button == null) + return; + + if (m_PushButtonPart) + m_Button._AccessibleExpandAction = false; + else + m_Button._AccessibleExpandAction = true; + + System.Windows.Forms.Control cont = m_Button.ContainerControl as System.Windows.Forms.Control; + if (cont is MenuPanel && !(cont is IAccessibilitySupport)) + { + cont = ((MenuPanel)cont).ParentItem.ContainerControl as System.Windows.Forms.Control; + } + + IAccessibilitySupport ias = cont as IAccessibilitySupport; + if (ias != null) + { + ias.DoDefaultActionItem = m_Button; + NativeFunctions.PostMessage(cont.Handle, NativeFunctions.WM_USER + 107, IntPtr.Zero, IntPtr.Zero); + } + + base.DoDefaultAction(); + } + + public override string KeyboardShortcut + { + get + { + return m_Button.ShortcutString; + } + } + + public override System.Windows.Forms.AccessibleObject GetSelected() + { + if (m_Button == null || m_PushButtonPart) + return base.GetSelected(); + + foreach (BaseItem item in m_Button.SubItems) + { + if ((item.AccessibleObject.State & System.Windows.Forms.AccessibleStates.HotTracked) == System.Windows.Forms.AccessibleStates.HotTracked) + return item.AccessibleObject; + } + + return base.GetSelected(); + } + + public override System.Windows.Forms.AccessibleObject HitTest(int x, int y) + { + if (m_Button == null) + return base.HitTest(x, y); + + Point screen = new Point(x, y); + foreach (BaseItem item in m_Button.SubItems) + { + System.Windows.Forms.Control cont = item.ContainerControl as System.Windows.Forms.Control; + if (cont != null) + { + Point p = cont.PointToClient(screen); + if (item.DisplayRectangle.Contains(p)) + return item.AccessibleObject; + } + } + + return base.HitTest(x, y); + } + + public override System.Windows.Forms.AccessibleObject Navigate(System.Windows.Forms.AccessibleNavigation navdir) + { + if (m_Button == null || m_PushButtonPart) + return base.Navigate(navdir); + + BaseItem item = null; + + if (navdir == System.Windows.Forms.AccessibleNavigation.Down || navdir == System.Windows.Forms.AccessibleNavigation.Right + || navdir == System.Windows.Forms.AccessibleNavigation.Next) + { + if (m_Button.Parent != null) + { + BaseItem parent = m_Button.Parent; + item = GetFirstVisible(parent.SubItems, parent.SubItems.IndexOf(m_Button) + 1); + } + } + else if (navdir == System.Windows.Forms.AccessibleNavigation.FirstChild) + { + item = GetFirstVisible(m_Button.SubItems, 0); + } + else if (navdir == System.Windows.Forms.AccessibleNavigation.LastChild) + { + item = GetFirstVisibleReverse(m_Button.SubItems, m_Button.SubItems.Count - 1); + } + else if (navdir == System.Windows.Forms.AccessibleNavigation.Up || navdir == System.Windows.Forms.AccessibleNavigation.Left + || navdir == System.Windows.Forms.AccessibleNavigation.Previous) + { + BaseItem parent = m_Button.Parent; + item = GetFirstVisibleReverse(m_Button.SubItems, parent.SubItems.IndexOf(m_Button) - 1); + } + + if (item != null) + return item.AccessibleObject; + + return base.Navigate(navdir); + } + + private BaseItem GetFirstVisible(SubItemsCollection col, int startIndex) + { + int count = col.Count; + if (count == 0) return null; + if (startIndex >= col.Count) startIndex = col.Count - 1; + + for (int i = startIndex; i < count; i++) + { + if (col[i].Visible) + return col[i]; + } + return null; + } + + private BaseItem GetFirstVisibleReverse(SubItemsCollection col, int startIndex) + { + if (col.Count == 0) return null; + if (startIndex >= col.Count) startIndex = col.Count - 1; + for (int i = startIndex; i >= 0; i--) + { + if (col[i].Visible) + return col[i]; + } + return null; + } + } + #endregion + } + + #region OptionGroupChangingEventHandler + /// + /// Delegate for OptionGroupChanging event. + /// + public delegate void OptionGroupChangingEventHandler(object sender, OptionGroupChangingEventArgs e); + #endregion + + #region OptionGroupChangingEventArgs + /// + /// Represents event arguments for OptionGroupChanging event. + /// + public class OptionGroupChangingEventArgs : EventArgs + { + /// + /// Set to true to cancel the checking on NewChecked button. + /// + public bool Cancel = false; + /// + /// Button that will become checked if operation is not canceled. + /// + public readonly BaseItem NewChecked; + /// + /// Button that is currently checked and which will be unchecked if operation is not canceled. + /// + public readonly BaseItem OldChecked; + /// + /// Default constructor. + /// + public OptionGroupChangingEventArgs(BaseItem oldchecked, BaseItem newchecked) + { + NewChecked = newchecked; + OldChecked = oldchecked; + } + } + #endregion + + #region SideBarImage + /// + /// Stores all information for side bar images that are used by Bar or Popup menu. + /// + public struct SideBarImage + { + /// + /// Gets or sets the side bar image. + /// + public Image Picture; + /// + /// Gets or sets the side bar back color. + /// + public Color BackColor; + /// + /// Gets or sets the gradient staring color. + /// + public Color GradientColor1; + /// + /// Gets or sets the gradient ending color. + /// + public Color GradientColor2; + /// + /// Gets or sets the gradient angle. + /// + public float GradientAngle; + /// + /// Gets or sets the gradient staring color. + /// + public eAlignment Alignment; + + /// + /// Gets or sets whether image is stretched so it fills the side bar or not if image is smaller than current side bar size. + /// + public bool StretchPicture; + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/ButtonItemLayout.cs b/PROMS/DotNetBar Source Code/ButtonItemLayout.cs new file mode 100644 index 00000000..17cc306a --- /dev/null +++ b/PROMS/DotNetBar Source Code/ButtonItemLayout.cs @@ -0,0 +1,985 @@ +using System.Drawing; +using System.Drawing.Text; +using System.Windows.Forms; +using System; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for ButtonItemLayout. + /// + internal class ButtonItemLayout + { + /// + /// Arranges the button inner parts when button size has changed externally. + /// + /// Button to arrange inner parts for. + public static void Arrange(ButtonItem button) + { + int minTextSize = Dpi.Width8; + bool isOnMenu = button.IsOnMenu; + if (isOnMenu && button.Parent is ItemContainer) + isOnMenu = false; + bool hasImage = false; + + Size imageSize = Size.Empty; + if (!string.IsNullOrEmpty(button.SymbolRealized)) + { + hasImage = true; + imageSize = button.ImageSize; + } + else + { + using (CompositeImage buttonImage = button.GetImage()) + { + if (buttonImage != null) + hasImage = true; + } + imageSize = GetLayoutImageSize(button, hasImage, isOnMenu, false); + } + + bool rightToLeft = button.IsRightToLeft; + Rectangle bounds = button.DisplayRectangle; + + if (isOnMenu) + { + // Add 4 pixel padding to the image size, 2 pixels on each side + imageSize.Height += Dpi.Width2; + imageSize.Width += Dpi.Width7; + // Center image if any... + //if (rightToLeft) + //{ + // if (button.IsOnCustomizeMenu) + // button.ImageDrawRect = new Rectangle(bounds.Width - (imageSize.Width + bounds.Height + 2), Math.Max(0, (bounds.Height - imageSize.Height) / 2), imageSize.Width, imageSize.Height); + // else + // button.ImageDrawRect = new Rectangle(bounds.Width - imageSize.Width - 1, Math.Max(0, (bounds.Height - imageSize.Height) / 2), imageSize.Width, imageSize.Height); + //} + //else + { + if (button.IsOnCustomizeMenu && !rightToLeft) + button.ImageDrawRect = new Rectangle(bounds.Height + 2, Math.Max(0, (bounds.Height - imageSize.Height) / 2), imageSize.Width, imageSize.Height); + else + button.ImageDrawRect = new Rectangle(0, Math.Max(0, (bounds.Height - imageSize.Height) / 2), imageSize.Width, imageSize.Height); + } + + //if (rightToLeft) + // button.TextDrawRect = new Rectangle(Math.Max(0, button.ImageDrawRect.X - button.TextDrawRect.Width - 2), Math.Max(0, (bounds.Height - button.TextDrawRect.Height) / 2), button.TextDrawRect.Width, button.TextDrawRect.Height); + //else + button.TextDrawRect = new Rectangle(button.ImageDrawRect.Right + 8, Math.Max(0, (bounds.Height - button.TextDrawRect.Height) / 2), button.TextDrawRect.Width, button.TextDrawRect.Height); + + return; + } + int x = 0; + if (!button.SubItemsRect.IsEmpty) + { + Rectangle subItemsRect = button.SubItemsRect; + if (button.ContainerControl is RibbonBar && (button.ImagePosition == eImagePosition.Top || button.ImagePosition == eImagePosition.Bottom)) + { + subItemsRect = new Rectangle(0, bounds.Height - subItemsRect.Height, bounds.Width, subItemsRect.Height); + bounds.Height -= subItemsRect.Height; + } + else + { + if (button.Orientation == eOrientation.Horizontal) + { + if (rightToLeft) + { + subItemsRect = new Rectangle(0, 0, subItemsRect.Width, bounds.Height); + //bounds.Width -= subItemsRect.Width; + //bounds.X += subItemsRect.Width; + x = subItemsRect.Width; + } + else + { + subItemsRect = new Rectangle(bounds.Width - subItemsRect.Width, 0, subItemsRect.Width, bounds.Height); + bounds.Width -= subItemsRect.Width; + } + } + else + { + subItemsRect = new Rectangle(0, 0, bounds.Width, subItemsRect.Height); + bounds.Height -= subItemsRect.Height; + } + } + button.SubItemsRect = subItemsRect; + } + + if (!hasImage || button.ButtonStyle == eButtonStyle.TextOnlyAlways) + { + int newHeight = bounds.Height - 2; + button.TextDrawRect = new Rectangle(2, + Math.Max(0, (bounds.Height - newHeight) / 2), bounds.Width - 4, newHeight); + return; + } + else if (button.ButtonStyle == eButtonStyle.Default && !(button.ImagePosition == eImagePosition.Top || button.ImagePosition == eImagePosition.Bottom) || bounds.Width < imageSize.Width + minTextSize) + { + // Display image only in center of the button + button.ImageDrawRect = new Rectangle(Math.Max(0, (bounds.Width - button.ImageDrawRect.Width) / 2), + Math.Max(0, (bounds.Height - button.ImageDrawRect.Height) / 2), button.ImageDrawRect.Width, button.ImageDrawRect.Height); + if (bounds.Width < imageSize.Width + minTextSize) + button.TextDrawRect = Rectangle.Empty; + return; + } + + // Displays both image and text + if (button.ImagePosition == eImagePosition.Left && !rightToLeft || button.ImagePosition == eImagePosition.Right && rightToLeft) + { + button.ImageDrawRect = new Rectangle(0, Math.Max(0, (bounds.Height - button.ImageDrawRect.Height) / 2), + button.ImageDrawRect.Width, button.ImageDrawRect.Height); + button.TextDrawRect = new Rectangle(button.ImageDrawRect.Right - 2, Math.Max(0, (bounds.Height - button.TextDrawRect.Height) / 2), + Math.Min(button.TextDrawRect.Width, bounds.Width - (button.ImageDrawRect.Right - 2)), button.TextDrawRect.Height); + } + else if (button.ImagePosition == eImagePosition.Right && !rightToLeft || button.ImagePosition == eImagePosition.Left && rightToLeft) + { + button.ImageDrawRect = new Rectangle(bounds.Width - button.ImageDrawRect.Width, Math.Max(0, (bounds.Height - button.TextDrawRect.Height) / 2), + button.ImageDrawRect.Width, button.ImageDrawRect.Height); + button.TextDrawRect = new Rectangle(Math.Max(x, button.ImageDrawRect.X - button.TextDrawRect.Width + 2), Math.Max(0, (bounds.Height - button.TextDrawRect.Height) / 2), + Math.Min(button.TextDrawRect.Width, button.ImageDrawRect.X), button.TextDrawRect.Height); + } + else if (button.ImagePosition == eImagePosition.Top) + { + int y = Math.Max(2, (bounds.Height - (button.TextDrawRect.Height + button.ImageDrawRect.Height - 2)) / 2); + if (button.Name != "sysOverflowButton" && button.Parent is ItemContainer && ((ItemContainer)button.Parent).LayoutOrientation == eOrientation.Horizontal && ((ItemContainer)button.Parent).VerticalItemAlignment == eVerticalItemsAlignment.Top) + y = 2; + + button.ImageDrawRect = new Rectangle(0, y, + bounds.Width, button.ImageDrawRect.Height); + + button.TextDrawRect = new Rectangle(Math.Max(0, (bounds.Width - button.TextDrawRect.Width) / 2), button.ImageDrawRect.Bottom, + button.TextDrawRect.Width, button.TextDrawRect.Height); + } + else if (button.ImagePosition == eImagePosition.Bottom) + { + int y = Math.Max(0, (bounds.Height - (button.TextDrawRect.Height + button.ImageDrawRect.Height - 2)) / 2); + //button.ImageDrawRect = new Rectangle(Math.Max(0, (bounds.Width - button.ImageDrawRect.Width) / 2), bounds.Height - y - button.ImageDrawRect.Height, + // button.ImageDrawRect.Width, button.ImageDrawRect.Height); + button.ImageDrawRect = new Rectangle(0, bounds.Height - y - button.ImageDrawRect.Height, + bounds.Width, button.ImageDrawRect.Height); + button.TextDrawRect = new Rectangle(Math.Max(0, (bounds.Width - button.ImageDrawRect.Width) / 2), Math.Max(0, button.ImageDrawRect.Y + 2 - button.TextDrawRect.Height), + button.TextDrawRect.Width, Math.Min(button.TextDrawRect.Height, button.ImageDrawRect.Y)); + } + } + + public static Size MeasureItemText(BaseItem item, Graphics g, int containerWidth, Font font, eTextFormat stringFormat, bool rightToLeft) + { + return MeasureItemText(item, g, containerWidth, font, stringFormat, rightToLeft, false, eImagePosition.Left); + } + + public static Size MeasureItemText(BaseItem item, Graphics g, int containerWidth, Font font, eTextFormat stringFormat, bool rightToLeft, bool ribbonBarButton, eImagePosition imagePosition) + { + if (item.Text == "" && item.TextMarkupBody == null) return Size.Empty; + + Size textSize = Size.Empty; + + if (item.TextMarkupBody == null) + { + textSize = TextDrawing.MeasureString(g, ButtonItemPainter.GetDrawText(item.Text), font, containerWidth, stringFormat); + } + else + { + Size availSize = new Size(containerWidth, 1); + if (containerWidth == 0) + availSize.Width = 1600; + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, Color.Empty, false); + item.TextMarkupBody.Measure(availSize, d); + availSize = item.TextMarkupBody.Bounds.Size; + if (containerWidth != 0 && !(ribbonBarButton && imagePosition == eImagePosition.Top)) + availSize.Width = containerWidth; + d.RightToLeft = rightToLeft; + item.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d); + + textSize = item.TextMarkupBody.Bounds.Size; + } + + return textSize; + } + + public static void LayoutButton(ButtonItem button) + { + LayoutButton(button, false); + } + + private static bool UseRibbonWordBreak(ButtonItem button) + { + if (button.TextMarkupBody == null) + return button.Text.IndexOf(' ') > 0 || button.Text.IndexOf(Environment.NewLine)> 0; + + return (button.Text.IndexOf(' ') > 0 && !button.TextMarkupBody.HasExpandElement || button.Text.Split(' ').Length > 2 && button.TextMarkupBody.HasExpandElement && button.ButtonStyle != eButtonStyle.Default); + } + + public static void LayoutButton(ButtonItem button, bool startButtonType) + { + Control objCtrl = button.ContainerControl as Control; + if (objCtrl == null || objCtrl.Disposing || objCtrl.IsDisposed) //if(!BarFunctions.IsHandleValid(objCtrl)) + return; + if (objCtrl is ButtonX && button._FitContainer) + { + LayoutButtonX(button); + return; + } + else if (button.FixedSize.Width > 0 && button.FixedSize.Height > 0) + { + Size fixedSize=Dpi.Size(button.FixedSize); + button.SetDisplayRectangle(new Rectangle(button.DisplayRectangle.Location, fixedSize)); + LayoutButtonX(button); + return; + } + + bool isOnMenu = button.IsOnMenu; + if (isOnMenu && button.Parent is ItemContainer) + isOnMenu = false; + bool bHasImage = false; + bool isSymbolImage = false; + eDotNetBarStyle effectiveStyle = button.EffectiveStyle; + bool ignoreImage = false; + if (startButtonType && (effectiveStyle == eDotNetBarStyle.Office2010 || effectiveStyle == eDotNetBarStyle.Office2013 || effectiveStyle == eDotNetBarStyle.Metro)) + ignoreImage = true; + if (!ignoreImage) + { + if (!string.IsNullOrEmpty(button.SymbolRealized)) + { + bHasImage = true; + isSymbolImage = true; + } + else + { + using (CompositeImage buttonImage = button.GetImage()) + { + if (buttonImage != null || startButtonType) + bHasImage = true; + } + } + } + + eImagePosition imagePosition = button.ImagePosition; + bool rightToLeft = (objCtrl.RightToLeft == RightToLeft.Yes); + + Rectangle textDrawRect = Rectangle.Empty; + Rectangle imageDrawRect = Rectangle.Empty; + Rectangle subItemsRect = Rectangle.Empty; + Rectangle bounds = new Rectangle(button.DisplayRectangle.Location, Size.Empty); // Critical to preserve the location for compatibility reasons + + if (rightToLeft && button.Orientation == eOrientation.Horizontal) + { + if (imagePosition == eImagePosition.Left) + imagePosition = eImagePosition.Right; + else if (imagePosition == eImagePosition.Right) + imagePosition = eImagePosition.Left; + } + + int measureStringWidth = 0; + + if (button._FitContainer) + measureStringWidth = button.DisplayRectangle.Width - 4; + + bounds.Width = 0; + bounds.Height = 0; + + Graphics g = BarFunctions.CreateGraphics(objCtrl); + try + { + eTextFormat stringFormat = GetTextFormat(button); + + // Get the right image size that we will use for calculation + Size imageSize = Size.Empty; + if (isSymbolImage) + { + Font symFont = Symbols.GetFont(button.SymbolSize, button.SymbolSet); + + if(button.IsOnMenu || objCtrl is SideNavStrip) // Need to do this to get consistent size for the symbol since they are not all the same width we pick widest + imageSize = TextDrawing.MeasureStringLegacy(g, "\uF00A", symFont, Size.Empty, eTextFormat.Default); + else + imageSize = TextDrawing.MeasureStringLegacy(g, button.SymbolRealized, symFont, Size.Empty, eTextFormat.Default); + + //int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) * + //symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style))); + //imageSize.Height -= descent; + button.ImageSize = imageSize; + } + else + { + imageSize = GetLayoutImageSize(button, bHasImage, isOnMenu, startButtonType); + } + bool ribbonBarButton = false; + if (button._FitContainer && bHasImage && (imagePosition == eImagePosition.Left || imagePosition == eImagePosition.Right)) + { + measureStringWidth -= (imageSize.Width + Dpi.Width10); + } + else if (button.RibbonWordWrap && bHasImage && imagePosition == eImagePosition.Top && objCtrl is RibbonBar && UseRibbonWordBreak(button)) + { + measureStringWidth = imageSize.Width + Dpi.Width4; + stringFormat |= eTextFormat.WordBreak; + ribbonBarButton = true; + } + + // Measure string + Font font = button.GetFont(null, true); + + SizeF textSize = SizeF.Empty; + + if ((button.Text != "" || button.TextMarkupBody != null) && (!bHasImage || isOnMenu || button.ButtonStyle != eButtonStyle.Default || button.ImagePosition != eImagePosition.Left && bHasImage)) + { + textSize = ButtonItemLayout.MeasureItemText(button, g, measureStringWidth, font, stringFormat, rightToLeft, ribbonBarButton, imagePosition); + //if (button.HotFontBold) textSize.Width += textSize.Width * .15f; + int maxItt = 0; + int increase = Math.Max(14, imageSize.Width / 2); + while (ribbonBarButton && textSize.Height > font.Height * 2.2 && maxItt < 4) + { + measureStringWidth += increase; + textSize = ButtonItemLayout.MeasureItemText(button, g, measureStringWidth, font, stringFormat, rightToLeft, ribbonBarButton, imagePosition); + maxItt++; + } + if (maxItt > 0) + { + measureStringWidth += increase; + textSize = ButtonItemLayout.MeasureItemText(button, g, measureStringWidth, font, stringFormat, rightToLeft, ribbonBarButton, imagePosition); + } + if (/*!ribbonBarButton &&*/ objCtrl is RibbonBar && bHasImage && imagePosition == eImagePosition.Top) + textSize.Height += Dpi.Width2; + if (startButtonType && ignoreImage) + textSize.Width = Dpi.Width((int)Math.Max(51, textSize.Width+6)); + } + + // See if this button is on menu, and do appropriate calculations + if (isOnMenu) + { + if (imageSize.IsEmpty) + imageSize = new Size(Dpi.Width16, Dpi.Height16); + + // Add 4 pixel padding to the image size, 2 pixels on each side + imageSize.Height += Dpi.Width2; + imageSize.Width += Dpi.Width7; + + // Calculate item height + if (textSize.Height > imageSize.Height) + bounds.Height = (int)textSize.Height + Dpi.Height4; + else + bounds.Height = imageSize.Height + Dpi.Height4; + + // Add Vertical Padding to it + bounds.Height += Dpi.Height(button.VerticalPadding); + + // We know the image position now, we will center it into this area + if (button.IsOnCustomizeMenu && !rightToLeft) + imageDrawRect = new Rectangle(bounds.Height + Dpi.Width2, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else + imageDrawRect = new Rectangle(0, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + + bounds.Width = (int)textSize.Width; + // Add short-cut size if we have short-cut + if (button.DrawShortcutText != "") + { + Size objSizeShortcut = TextDrawing.MeasureString(g, button.DrawShortcutText, font, 0, stringFormat); + bounds.Width += (objSizeShortcut.Width + 14); // 14 distance between text and shortcut + } + + textDrawRect = new Rectangle(imageDrawRect.Right + 8, 2, bounds.Width, bounds.Height - 4); + + // 8 pixels distance between image and text, 22 pixels if this item has sub items + bounds.Width += (imageDrawRect.Right + Dpi.Width34); + bounds.Width += Dpi.Width(button.HorizontalPadding); + } + else + { + bool bThemed = button.IsThemed; + if (StyleManager.Style == eStyle.OfficeMobile2014) + { + imageSize.Width += Dpi.Width6; imageSize.Height += Dpi.Height4; + } + else if (StyleManager.Style == eStyle.Office2016) + { + imageSize.Width += Dpi.Width4; imageSize.Height += Dpi.Width2; + } + if (button.Orientation == eOrientation.Horizontal && (imagePosition == eImagePosition.Left || imagePosition == eImagePosition.Right)) + { + // Recalc size for the Bar button + // Add 8 pixel padding to the image size, 4 pixels on each side + //objImageSize.Height+=4; + imageSize.Width += Dpi.Width(button.ImagePaddingHorizontal); + + // Calculate item height + if (textSize.Height > imageSize.Height) + bounds.Height = (int)textSize.Height + Dpi.Height(button.ImagePaddingVertical); + else + bounds.Height = imageSize.Height + Dpi.Height(button.ImagePaddingVertical); + + // Add Vertical Padding + bounds.Height += Dpi.Height(button.VerticalPadding); + + if (bThemed && !button.IsOnMenuBar) + bounds.Height += Dpi.Height4; + + imageDrawRect = Rectangle.Empty; + if (button.ButtonStyle != eButtonStyle.TextOnlyAlways && bHasImage) + { + // We know the image position now, we will center it into this area + imageDrawRect = new Rectangle(0, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + } + + // Draw Text only if needed + textDrawRect = Rectangle.Empty; + if (button.ButtonStyle != eButtonStyle.Default || !bHasImage) + { + if (imageDrawRect.Right > 0) + { + bounds.Width = (int)textSize.Width + 1; + textDrawRect = new Rectangle(imageDrawRect.Right - 2, 2, bounds.Width, bounds.Height - 4); + } + else + { + bounds.Width = (int)textSize.Width + Dpi.Width6; + if (!bHasImage && button.IsOnMenuBar) + { + bounds.Width += Dpi.Width6; + textDrawRect = new Rectangle(2, 2, bounds.Width, bounds.Height - 4); + } + else + textDrawRect = new Rectangle(2, 2, bounds.Width + Dpi.Width(button.HorizontalPadding - 4), bounds.Height - 4); + } + } + bounds.Width += imageDrawRect.Right; + + if (imagePosition == eImagePosition.Right && imageDrawRect.Right > 0 && bHasImage) + { + textDrawRect.X = 3; + imageDrawRect.X = bounds.Width - imageDrawRect.Width; + } + + // Add Horizontal padding + bounds.Width += Dpi.Width(button.HorizontalPadding); + } + else + { + // Image is on top or bottom + // Calculate width, that is easy + if (button.Orientation == eOrientation.Horizontal) + { + + if (textSize.Width > imageSize.Width) + bounds.Width = (int)textSize.Width + Dpi.Width(button.ImagePaddingHorizontal); + else + bounds.Width = imageSize.Width + Dpi.Width(button.ImagePaddingHorizontal); + + // Calculate item height 3 padding on top and bottom and 2 pixels distance between the image and text + bounds.Height = (int)(imageSize.Height + textSize.Height + Dpi.Height(button.ImagePaddingVertical) /*10*/); + + // Add Horizontal/Vertical padding + bounds.Width += Dpi.Width(button.HorizontalPadding); + bounds.Height += Dpi.Height(button.VerticalPadding); + + if (imagePosition == eImagePosition.Top) + { + imageDrawRect = new Rectangle(0, Dpi.Height(button.VerticalPadding) / 2 + 2, bounds.Width, imageSize.Height/*+2*/); + textDrawRect = new Rectangle((int)(bounds.Width - textSize.Width) / 2, imageDrawRect.Bottom, (int)textSize.Width, (int)textSize.Height + 5); + } + else + { + textDrawRect = new Rectangle((int)(bounds.Width - textSize.Width) / 2, Dpi.Height(button.VerticalPadding) / 2, (int)textSize.Width, (int)textSize.Height + 2); + imageDrawRect = new Rectangle(0, textDrawRect.Bottom, bounds.Width, imageSize.Height + 5); + } + } + else + { + if (textSize.Height > imageSize.Width && button.ButtonStyle != eButtonStyle.Default) + bounds.Width = (int)textSize.Height + 6; + else + bounds.Width = imageSize.Width + 10; + + // Add Horizontal Padding + bounds.Width += Dpi.Width(button.HorizontalPadding); + + // Calculate item height 3 padding on top and bottom and 2 pixels distance between the image and text + if (button.ButtonStyle != eButtonStyle.Default || !bHasImage) + { + if (bHasImage) + bounds.Height = (int)(imageSize.Height + textSize.Width + Dpi.Width12); + else + bounds.Height = (int)(textSize.Width + Dpi.Width6); + } + else + bounds.Height = imageSize.Height + Dpi.Height6; + + if (imagePosition == eImagePosition.Top || imagePosition == eImagePosition.Left) + { + if (bHasImage) + imageDrawRect = new Rectangle(0, 0, bounds.Width, imageSize.Height + Dpi.Height6); + textDrawRect = new Rectangle((int)(bounds.Width - textSize.Height) / 2, imageDrawRect.Bottom + Dpi.Width2, (int)textSize.Height, (int)textSize.Width + Dpi.Width5); + } + else + { + textDrawRect = new Rectangle((int)(bounds.Width - textSize.Height) / 2, Dpi.Height5, (int)textSize.Height, (int)textSize.Width + Dpi.Width5); + if (bHasImage) + imageDrawRect = new Rectangle(0, textDrawRect.Bottom - Dpi.Height3, bounds.Width, imageSize.Height + Dpi.Height5); + } + + // Add Vertical Padding + bounds.Height += Dpi.Height(button.VerticalPadding); + } + } + + if (HasExpandPart(button)) + { + subItemsRect = GetSubItemsButtonBounds(button, bounds, rightToLeft); + // Add small button to expand the item + Rectangle rTemp = subItemsRect; + rTemp.Offset(bounds.Location); + + if (rightToLeft && !(objCtrl is RibbonBar && + (button.ImagePosition == eImagePosition.Top || button.ImagePosition == eImagePosition.Bottom))) + { + if (!textDrawRect.IsEmpty) + textDrawRect.Offset(subItemsRect.Width + 1, 0); + if (!imageDrawRect.IsEmpty && (button.Orientation == eOrientation.Horizontal && (imagePosition == eImagePosition.Left || imagePosition == eImagePosition.Right))) + imageDrawRect.Offset(subItemsRect.Width, 0); + bounds.X += subItemsRect.Width; + } + + bounds = Rectangle.Union(bounds, rTemp); + } + } + } + finally + { + g.TextRenderingHint = TextRenderingHint.SystemDefault; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + g.Dispose(); + } + objCtrl = null; + + button.SetDisplayRectangle(bounds); + button.ImageDrawRect = imageDrawRect; + button.TextDrawRect = textDrawRect; + button.SubItemsRect = subItemsRect; + } + + private static bool HasExpandPart(ButtonItem button) + { + return (button.SubItems.Count > 0 || button.PopupType == ePopupType.Container) && button.ShowSubItems && !button.IsOnMenuBar && + !(button.TextMarkupBody != null && button.TextMarkupBody.HasExpandElement && button.ButtonStyle != eButtonStyle.Default); + } + + //private static ButtonTextSize GetTextSize(ButtonItem button, int containerWidth, bool measureShortcut) + //{ + // ButtonTextSize textSize = new ButtonTextSize(); + // Control ctrl = button.ContainerControl as Control; + // Graphics g = BarFunctions.CreateGraphics(ctrl); + // try + // { + // eTextFormat stringFormat = GetTextFormat(button); + // Font font = button.GetFont(null); + + // if (button.TextMarkupBody == null) + // { + // textSize.TextSize = TextDrawing.MeasureString(g, ButtonItemPainter.GetDrawText(button.Text), font, containerWidth, stringFormat); + // } + // else + // { + // Size availSize = new Size(containerWidth, 1); + // if (containerWidth == 0) + // availSize.Width = 1600; + // TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, Color.Empty, false); + // button.TextMarkupBody.Measure(availSize, d); + // availSize = button.TextMarkupBody.Bounds.Size; + // if (containerWidth != 0) + // availSize.Width = containerWidth; + // d.RightToLeft = button.IsRightToLeft; + // button.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d); + + // textSize.TextSize = button.TextMarkupBody.Bounds.Size; + // } + + // if (measureShortcut && button.DrawShortcutText != "") + // textSize.ShortcutTextSize = TextDrawing.MeasureString(g, button.DrawShortcutText, font, 0, stringFormat); + // } + // finally + // { + // g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + // g.TextRenderingHint = TextRenderingHint.SystemDefault; + // g.Dispose(); + // } + // return textSize; + //} + + private static Size GetLayoutImageSize(ButtonItem button, bool hasImage, bool isOnMenu, bool startButtonType) + { + // Get the right image size that we will use for calculation + Size imageSize = Size.Empty; + if (button.Parent != null && button.ImageFixedSize.IsEmpty && button.UseParentSubItemsImageSize) + { + ImageItem parentImageItem = button.Parent as ImageItem; + if (parentImageItem != null && !parentImageItem.SubItemsImageSize.IsEmpty) + { + if (!hasImage || isOnMenu) + imageSize = new Size(parentImageItem.SubItemsImageSize.Width, parentImageItem.SubItemsImageSize.Height); + else + { + if (button.Orientation == eOrientation.Horizontal) + imageSize = new Size(button.ImageSize.Width, Math.Max(parentImageItem.SubItemsImageSize.Height, button.ImageSize.Height)); + else + imageSize = new Size(Math.Max(parentImageItem.SubItemsImageSize.Width, button.ImageSize.Width), button.ImageSize.Height); + } + } + else + imageSize = button.ImageSize; + } + else if(startButtonType && !button.ImageFixedSize.IsEmpty) + imageSize = button.ImageFixedSize; + else if (!button.ImageFixedSize.IsEmpty) + imageSize = Dpi.Size(button.ImageFixedSize); + else + imageSize = button.ImageSize; + + if (startButtonType) + { + Office2007Renderer renderer = GlobalManager.Renderer as Office2007Renderer; + if (renderer != null && renderer.ColorTable is Office2007ColorTable) + { + Office2007ColorTable table = renderer.ColorTable as Office2007ColorTable; + if (table.RibbonControl.StartButtonDefault != null) + { + if (imageSize.Width < table.RibbonControl.StartButtonDefault.Width) + imageSize.Width = table.RibbonControl.StartButtonDefault.Width; + if (imageSize.Height < table.RibbonControl.StartButtonDefault.Height) + imageSize.Height = table.RibbonControl.StartButtonDefault.Height; + } + } + imageSize = Dpi.ImageSize(imageSize); + } + + return imageSize; + } + + public static Rectangle GetSubItemsButtonBounds(ButtonItem button, Rectangle buttonBounds, bool rightToLeft) + { + Rectangle subItemsRect = Rectangle.Empty; + + int subItemsExpandWidth = Dpi.Width(button.SubItemsExpandWidth); + if (button.ContainerControl is RibbonBar && (button.ImagePosition == eImagePosition.Top || button.ImagePosition == eImagePosition.Bottom)) + { + subItemsRect = new Rectangle(0, buttonBounds.Height, buttonBounds.Width, subItemsExpandWidth); + } + else + { + // Add small button to expand the item + if (button.Orientation == eOrientation.Horizontal) + { + if (button.IsThemed) + { + if (rightToLeft) + subItemsRect = new Rectangle(0, 0, subItemsExpandWidth, buttonBounds.Height); + else + subItemsRect = new Rectangle(buttonBounds.Width, 0, subItemsExpandWidth, buttonBounds.Height); + } + else + { + if (rightToLeft) + subItemsRect = new Rectangle(0, 0, subItemsExpandWidth, buttonBounds.Height); + else + subItemsRect = new Rectangle(buttonBounds.Width + 1, 0, subItemsExpandWidth, buttonBounds.Height); + } + } + else + { + subItemsRect = new Rectangle(0, buttonBounds.Height - 2, buttonBounds.Width, subItemsExpandWidth); + } + } + + return subItemsRect; + } + + public static eTextFormat GetTextFormat(ButtonItem button) + { + eTextFormat format = eTextFormat.Default; + if (!button._FitContainer) + { + format |= eTextFormat.SingleLine; + } + else + format |= eTextFormat.WordBreak; + + format |= eTextFormat.VerticalCenter; + return format; + } + + public static void LayoutButtonX(ButtonItem button) + { + Control objCtrl = button.ContainerControl as Control; + ButtonX btnX = button.ContainerControl as ButtonX; + if (!BarFunctions.IsHandleValid(objCtrl)) + return; + bool isOnMenu = button.IsOnMenu; + if (isOnMenu && button.Parent is ItemContainer) + isOnMenu = false; + bool bHasImage = false; + + if (!string.IsNullOrEmpty(button.SymbolRealized)) + { + bHasImage = true; + } + else + { + using (CompositeImage buttonImage = button.GetImage()) + { + if (buttonImage != null) + bHasImage = true; + } + } + + eImagePosition imagePosition = button.ImagePosition; + bool rightToLeft = (objCtrl.RightToLeft == RightToLeft.Yes); + + Rectangle textDrawRect = Rectangle.Empty; + Rectangle imageDrawRect = Rectangle.Empty; + Rectangle subItemsRect = Rectangle.Empty; + Rectangle bounds = button.Bounds; + + // Calculate sub-items rectangle + if (button.SubItems.Count > 0 && button.ShowSubItems && + !(button.TextMarkupBody != null && button.TextMarkupBody.HasExpandElement && button.ButtonStyle != eButtonStyle.Default)) + { + // Add small button to expand the item + int subItemsExpandWidth = Dpi.Width(button.SubItemsExpandWidth); + if (button.Orientation == eOrientation.Horizontal) + { + if (rightToLeft) + subItemsRect = new Rectangle(0, 0, subItemsExpandWidth, bounds.Height); + else + subItemsRect = new Rectangle(bounds.Width - subItemsExpandWidth, 0, subItemsExpandWidth, bounds.Height); + if (rightToLeft) + bounds.X += subItemsExpandWidth + 1; + bounds.Width -= subItemsExpandWidth + 1; + } + else + { + subItemsRect = new Rectangle(0, bounds.Height - subItemsExpandWidth, bounds.Width, subItemsExpandWidth); + bounds.Height -= subItemsExpandWidth + 1; + } + } + + // Adjust image position + if (rightToLeft && button.Orientation == eOrientation.Horizontal) + { + if (imagePosition == eImagePosition.Left) + imagePosition = eImagePosition.Right; + else if (imagePosition == eImagePosition.Right) + imagePosition = eImagePosition.Left; + } + + int measureStringWidth = 0; + + measureStringWidth = bounds.Width; + + Graphics g = BarFunctions.CreateGraphics(objCtrl); + try + { + + // Get the right image size that we will use for calculation + Size imageSize = Size.Empty; + if (!string.IsNullOrEmpty(button.SymbolRealized)) + { + Font symFont = Symbols.GetFont(button.SymbolSize, button.SymbolSet); + imageSize = TextDrawing.MeasureStringLegacy(g, button.SymbolRealized, symFont, Size.Empty, eTextFormat.Default); + int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) * + symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style))); + imageSize.Height -= descent; + button.ImageSize = imageSize; + } + else + { + if (!button.ImageFixedSize.IsEmpty) + imageSize = button.ImageFixedSize; + else + imageSize = button.ImageSize; + } + + if (bHasImage && (imagePosition == eImagePosition.Left || imagePosition == eImagePosition.Right)) + { + if (btnX != null) + measureStringWidth -= imageSize.Width + btnX.ImageTextSpacing * 2 + 3; + else + measureStringWidth -= (imageSize.Width + 8); + } + + if (bHasImage && !imageSize.IsEmpty && btnX != null && btnX.ImageTextSpacing != 0) + { + if (imagePosition == eImagePosition.Left || imagePosition == eImagePosition.Right) + imageSize.Width += btnX.ImageTextSpacing * 2; + else + imageSize.Height += btnX.ImageTextSpacing * 2; + } + + // Measure string + Font font = button.GetFont(null, true); + + SizeF textSize = SizeF.Empty; + eTextFormat stringFormat = eTextFormat.Default | eTextFormat.VerticalCenter; +#if FRAMEWORK20 + if (BarFunctions.IsWindowsXP && BarUtilities.UseTextRenderer) stringFormat |= eTextFormat.LeftAndRightPadding; +#endif + if (btnX != null || objCtrl is RibbonBar && button.RibbonWordWrap) stringFormat |= eTextFormat.WordBreak; + if (btnX != null && !btnX.UseMnemonic) stringFormat |= eTextFormat.NoPrefix; + + if (button.Text != "") + { + if (button.TextMarkupBody == null) + { + if (button.Orientation == eOrientation.Vertical && !isOnMenu) + textSize = TextDrawing.MeasureStringLegacy(g, ButtonItemPainter.GetDrawText(button.Text), font, new Size(measureStringWidth, 0), stringFormat); + else + { + textSize = TextDrawing.MeasureString(g, ButtonItemPainter.GetDrawText(button.Text), font, measureStringWidth, stringFormat); +#if FRAMEWORK20 + if (BarFunctions.IsWindowsXP && BarUtilities.UseTextRenderer) textSize.Width += 2; +#endif + } + } + else + { + Size availSize = new Size(measureStringWidth, 1); + if (measureStringWidth == 0) + availSize.Width = 1600; + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, Color.Empty, false); + d.RightToLeft = rightToLeft; + button.TextMarkupBody.Measure(availSize, d); + availSize = button.TextMarkupBody.Bounds.Size; + button.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d); + + textSize = button.TextMarkupBody.Bounds.Size; + } + } + + if (button.Orientation == eOrientation.Horizontal && (imagePosition == eImagePosition.Left || imagePosition == eImagePosition.Right)) + { + // Recalc size for the Bar button + // Add 8 pixel padding to the image size, 4 pixels on each side + if (button.ButtonStyle != eButtonStyle.Default || !bHasImage) + imageSize.Width += 4; + + imageDrawRect = Rectangle.Empty; + if (button.ButtonStyle != eButtonStyle.TextOnlyAlways && bHasImage) + { + // We know the image position now, we will center it into this area + if (imagePosition == eImagePosition.Left) + { + if (btnX != null && btnX.TextAlignment == eButtonTextAlignment.Left) + imageDrawRect = new Rectangle(2, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else if (btnX != null && btnX.TextAlignment == eButtonTextAlignment.Right) + imageDrawRect = new Rectangle(bounds.Width - (imageSize.Width + (int)Math.Ceiling(textSize.Width) + 4), (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else if (btnX != null) + imageDrawRect = new Rectangle(/*bounds.X+*/(int)(bounds.Width - (textSize.Width + imageSize.Width)) / 2, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else + { + if (subItemsRect.IsEmpty && button.ButtonStyle == eButtonStyle.Default) + imageDrawRect = new Rectangle((bounds.Width - imageSize.Width) / 2, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else + imageDrawRect = new Rectangle(0, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + } + } + else + { + if (btnX != null && btnX.TextAlignment == eButtonTextAlignment.Left) + imageDrawRect = new Rectangle((int)textSize.Width + 4, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else if (btnX != null && btnX.TextAlignment == eButtonTextAlignment.Right) + imageDrawRect = new Rectangle(bounds.Width - imageSize.Width, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else if (btnX != null) + imageDrawRect = new Rectangle(bounds.Width - (int)(bounds.Width - (textSize.Width + imageSize.Width)) / 2 - (imageSize.Width), (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else + imageDrawRect = new Rectangle(bounds.Width - imageSize.Width, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + } + } + + // Draw Text only if needed + textDrawRect = Rectangle.Empty; + if (button.ButtonStyle != eButtonStyle.Default || !bHasImage) + { + if (bHasImage) + { + if (imagePosition == eImagePosition.Left) + { + if (btnX != null && btnX.TextAlignment == eButtonTextAlignment.Center) + textDrawRect = new Rectangle(imageDrawRect.Right + 1, (int)((bounds.Height - textSize.Height) / 2), (int)textSize.Width, (int)textSize.Height); + else if (btnX != null && (btnX.TextAlignment == eButtonTextAlignment.Right || btnX.TextAlignment == eButtonTextAlignment.Left)) + textDrawRect = new Rectangle(imageDrawRect.Right + 1, (int)((bounds.Height - textSize.Height) / 2), bounds.Width - 3 - imageDrawRect.Width, (int)textSize.Height); + else + textDrawRect = new Rectangle(imageDrawRect.Right + 1, (int)((bounds.Height - textSize.Height) / 2), bounds.Width - 3 - imageDrawRect.Width, (int)textSize.Height); + } + else + { + if (btnX != null && btnX.TextAlignment == eButtonTextAlignment.Center) + textDrawRect = new Rectangle((int)(imageDrawRect.X - textSize.Width) - 1, (int)((bounds.Height - textSize.Height) / 2), (int)textSize.Width, (int)textSize.Height); + else if (btnX != null && btnX.TextAlignment == eButtonTextAlignment.Right) + textDrawRect = new Rectangle(imageDrawRect.X - ((int)textSize.Width + 4), (int)((bounds.Height - textSize.Height) / 2), (int)textSize.Width + 2, (int)textSize.Height); + else + textDrawRect = new Rectangle(3, (int)((bounds.Height - textSize.Height) / 2), imageDrawRect.X - 2, (int)textSize.Height); + } + } + else + { + if (btnX != null && btnX.TextAlignment == eButtonTextAlignment.Center || button._FixedSizeCenterText) + textDrawRect = new Rectangle(/*bounds.X+*/(int)((bounds.Width - textSize.Width) / 2), (int)((bounds.Height - textSize.Height) / 2), (int)textSize.Width, (int)textSize.Height); + else + textDrawRect = new Rectangle(/*bounds.X +*/ 3, (int)((bounds.Height - textSize.Height) / 2), bounds.Width - 6, (int)textSize.Height); + } + } + } + else + { + // Image is on top or bottom + // Calculate width, that is easy + if (button.Orientation == eOrientation.Horizontal) + { + + if (imagePosition == eImagePosition.Top) + { + imageDrawRect = new Rectangle(0, (int)(bounds.Height - (imageSize.Height + textSize.Height)) / 2, bounds.Width, imageSize.Height/*+2*/); + textDrawRect = new Rectangle(0, imageDrawRect.Bottom, (int)textSize.Width, (int)textSize.Height + 5); + } + else + { + textDrawRect = new Rectangle((int)(bounds.Width - textSize.Width) / 2, (int)(bounds.Height - (imageSize.Height + textSize.Height)) / 2, (int)textSize.Width, (int)textSize.Height); + imageDrawRect = new Rectangle(0, textDrawRect.Bottom, bounds.Width, imageSize.Height + 5); + } + } + else + { + if (imagePosition == eImagePosition.Top || imagePosition == eImagePosition.Left) + { + if (bHasImage) + { + if (subItemsRect.IsEmpty && button.ButtonStyle == eButtonStyle.Default) + imageDrawRect = new Rectangle((bounds.Width - imageSize.Width) / 2, (bounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else + imageDrawRect = new Rectangle(0, 0, bounds.Width, imageSize.Height + 6); + } + textDrawRect = new Rectangle((int)(bounds.Width - textSize.Height) / 2, imageDrawRect.Bottom + 2, (int)textSize.Height, (int)textSize.Width + 5); + } + else + { + textDrawRect = new Rectangle((int)(bounds.Width - textSize.Width) / 2, 0, (int)textSize.Height, (int)textSize.Width + 5); + if (bHasImage) + imageDrawRect = new Rectangle(0, textDrawRect.Bottom + 2, bounds.Width, imageSize.Height + 5); + } + } + } + } + finally + { + g.TextRenderingHint = TextRenderingHint.SystemDefault; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + g.Dispose(); + } + + button.ImageDrawRect = imageDrawRect; + button.TextDrawRect = textDrawRect; + button.SubItemsRect = subItemsRect; + } + + private struct ButtonTextSize + { + public Size TextSize; + public Size ShortcutTextSize; + } + } +} diff --git a/PROMS/DotNetBar Source Code/ButtonX/ButtonX.cs b/PROMS/DotNetBar Source Code/ButtonX/ButtonX.cs new file mode 100644 index 00000000..211bd86c --- /dev/null +++ b/PROMS/DotNetBar Source Code/ButtonX/ButtonX.cs @@ -0,0 +1,1542 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; +using System.Collections; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Drawing.Design; + +namespace DevComponents.DotNetBar +{ + [ToolboxBitmap(typeof(ButtonX),"ButtonX.ButtonX.ico"),ToolboxItem(true), DefaultEvent("Click"), Designer("DevComponents.DotNetBar.Design.ButtonXDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.Runtime.InteropServices.ComVisible(false)] + public class ButtonX : PopupItemControl, IButtonControl, ICommandSource + { + #region Events + /// + /// Occurs when Checked property has changed. + /// + [Description("Occurs when Checked property has changed.")] + public event EventHandler CheckedChanged; + #endregion + + #region Private Variables + private ButtonItem m_Button = null; + private ColorScheme m_ColorScheme = null; + private DialogResult m_DialogResult = DialogResult.None; + private bool m_IsDefault = false; + private bool m_FadeEffect = true; + private eButtonTextAlignment m_TextAlignment = eButtonTextAlignment.Center; + private Size m_PreferredSize = Size.Empty; + #endregion + + #region Constructor + public ButtonX() + { + this.IsAccessible = true; + this.AccessibleRole = AccessibleRole.PushButton; + base.SetStyle(ControlStyles.StandardDoubleClick | ControlStyles.StandardClick, false); + StyleManager.Register(this); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + StyleManager.Unregister(this); + //m_Button.Dispose(); + } + base.Dispose(disposing); + } + + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + this.Style = this.Style; + } + + protected virtual ButtonItem CreateButtonItem() + { + return new ButtonItem(); + } + + protected override PopupItem CreatePopupItem() + { + m_Button = CreateButtonItem(); + m_Button.GlobalItem = false; + m_Button.Displayed = true; + m_Button.ContainerControl = this; + m_Button.ColorTable = eButtonColor.BlueWithBackground; + m_Button.ButtonStyle = eButtonStyle.ImageAndText; + m_Button._FitContainer = true; + m_Button.Style = eDotNetBarStyle.Office2007; + m_Button.SetOwner(this); + m_Button.CheckedChanged += new EventHandler(OnCheckedChanged); + return m_Button; + } + + private void OnCheckedChanged(object sender, EventArgs e) + { + if (CheckedChanged != null) + CheckedChanged(this, e); + } + + /// + /// Creates new accessibility instance. + /// + /// Reference to AccessibleObject. + protected override AccessibleObject CreateAccessibilityInstance() + { + return new ButtonXAccessibleObject(this); + } + #endregion + + #region Internal Implementation + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)] + protected internal ButtonItem ButtonItem + { + get { return (m_Button); } + } + + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)] + protected bool IsMouseDown + { + get + { + return m_Button.IsMouseDown; + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + protected void StopFade() + { + m_Button.StopFade(); + } + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + base.ScaleControl(factor, specified); + m_Button.NotifyScaleItem(factor); + } + /// + /// Gets or sets whether text-markup support is enabled for controls Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the control instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for controls Text property.")] + public bool EnableMarkup + { + get { return m_Button.EnableMarkup; } + set + { + m_Button.EnableMarkup = value; + } + } + + /// + /// Starts the button pulse effect which alternates slowly between the mouse over and the default state. The pulse effect + /// continues indefinitely until it is stopped by call to StopPulse method. + /// + public void Pulse() + { + m_Button.Pulse(); + } + + /// + /// Starts the button pulse effect which alternates slowly between the mouse over and the default state. Pulse effect + /// will alternate between the pulse state for the number of times specified by the pulseBeatCount parameter. + /// + /// Specifies the number of times button alternates between pulse states. 0 indicates indefinite pulse + public void Pulse(int pulseBeatCount) + { + m_Button.Pulse(pulseBeatCount); + } + + /// + /// Stops the button Pulse effect. + /// + public void StopPulse() + { + m_Button.StopPulse(); + } + + /// + /// Gets whether the button is currently pulsing, alternating slowly between the mouse over and default state. + /// + [Browsable(false)] + public bool IsPulsing + { + get { return m_Button.IsPulsing; } + } + + /// + /// Gets or sets whether pulse effect started with StartPulse method stops automatically when mouse moves over the button. Default value is true. + /// + [DefaultValue(true), Browsable(true), Category("Behavior"), Description("Indicates whether pulse effect started with Pulse method stops automatically when mouse moves over the button.")] + public bool StopPulseOnMouseOver + { + get { return m_Button.StopPulseOnMouseOver; } + set { m_Button.StopPulseOnMouseOver = value; } + } + + /// + /// Gets or sets the pulse speed. The value must be greater than 0 and less than 128. Higher values indicate faster pulse. Default value is 12. + /// + [Browsable(true), DefaultValue(12), Category("Behavior"), Description("Indicates pulse speed. The value must be greater than 0 and less than 128.")] + public int PulseSpeed + { + get { return m_Button.PulseSpeed; } + set + { + m_Button.PulseSpeed = value; + } + } + + protected override void OnEnabledChanged(EventArgs e) + { + if (!this.Enabled && this.IsPulsing) this.StopPulse(); + base.OnEnabledChanged(e); + } + + /// + /// Sets fixed size of the image. Image will be scaled and painted it size specified. + /// + [Browsable(true)] + public System.Drawing.Size ImageFixedSize + { + get { return m_Button.ImageFixedSize; } + set + { + m_Button.ImageFixedSize = value; + this.RecalcLayout(); + } + } + /// + /// Gets whether ImageFixedSize property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeImageFixedSize() + { + return m_Button.ShouldSerializeImageFixedSize(); + } + + /// + /// Gets or sets the text alignment. Applies only when button text is not composed using text markup. Default value is center. + /// + [Browsable(true), DefaultValue(eButtonTextAlignment.Center), Category("Appearance"), Description("Indicates text alignment. Applies only when button text is not composed using text markup. Default value is center.")] + public eButtonTextAlignment TextAlignment + { + get { return m_TextAlignment; } + set + { + m_TextAlignment = value; + this.RecalcLayout(); + } + } + + private bool _CallBasePaintBackground = true; + /// + /// Gets or sets whether during painting OnPaintBackground on base control is called when BackColor=Transparent. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool CallBasePaintBackground + { + get { return _CallBasePaintBackground; } + set + { + _CallBasePaintBackground = value; + } + } + + internal void InternalPaint(PaintEventArgs e) + { + OnPaint(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + if ((this.BackColor.IsEmpty || this.BackColor == Color.Transparent || this.BackgroundImage != null) && _CallBasePaintBackground) + { + base.OnPaintBackground(e); + } + else + { + DisplayHelp.FillRectangle(e.Graphics, this.ClientRectangle, this.BackColor, System.Drawing.Color.Empty); + } + + Rectangle r = this.ClientRectangle; + Graphics g=e.Graphics; + + ColorScheme cs = this.GetColorScheme(); + + if (!IsThemed) + { + if (BarFunctions.IsOffice2007Style(m_Button.EffectiveStyle)) + { + //int cornerSize = this.CornerSize; + //SmoothingMode sm = g.SmoothingMode; + //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + //DisplayHelp.FillRoundedRectangle(g, r, cornerSize, cs.BarBackground, cs.BarBackground2, cs.BarBackgroundGradientAngle); + //DisplayHelp.DrawRoundedRectangle(g, cs.BarDockedBorder, r, cornerSize); + //g.SmoothingMode = sm; + } + else + { + DisplayHelp.FillRectangle(g, r, cs.BarBackground, cs.BarBackground2, cs.BarBackgroundGradientAngle); + DisplayHelp.DrawRectangle(g, cs.BarDockedBorder, r); + } + } + + SmoothingMode sm = g.SmoothingMode; + TextRenderingHint th = g.TextRenderingHint; + + ItemPaintArgs pa = GetItemPaintArgs(g); + + if (this.AntiAlias) + { + pa.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + pa.Graphics.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + IShapeDescriptor shape = GetButtonShape(); + if (!(shape is RoundRectangleShapeDescriptor)) + { + Rectangle rs = this.ClientRectangle; + rs.Y--; + rs.X--; + rs.Width++; + rs.Height++; + if (shape.CanDrawShape(rs)) + { + using (GraphicsPath path = shape.GetShape(rs)) + g.SetClip(path); + } + } + + m_Button.Paint(pa); + + g.SmoothingMode = sm; + g.TextRenderingHint = th; + + base.OnPaint(e); + } + + protected override void OnResize(EventArgs e) + { + RecalcLayout(); + base.OnResize(e); + } + + protected override void OnTextChanged(EventArgs e) + { + m_Button.Text = this.Text; + UpdateButtonAutoSize(); + base.OnTextChanged(e); + } + + private void UpdateButtonAutoSize() + { + InvalidateAutoSize(); +#if FRAMEWORK20 + this.AdjustSize(); +#endif + this.RecalcLayout(); + } + + protected override void OnFontChanged(EventArgs e) + { + base.OnFontChanged(e); + InvalidateAutoSize(); + } + + //protected override void OnForeColorChanged(EventArgs e) + //{ + // if (this.ForeColor != SystemColors.ControlText) + // m_Button.ForeColor = this.ForeColor; + // else + // m_Button.ForeColor = Color.Empty; + + // base.OnForeColorChanged(e); + //} + + protected override void RecalcSize() + { + m_Button.Bounds = this.ClientRectangle; + m_Button.RecalcSize(); + m_Button.Bounds = this.ClientRectangle; + } + + private bool _IsSpaceKeyDown = false; + protected override void OnKeyDown(KeyEventArgs e) + { + if(e.KeyCode == Keys.Space && !m_Button.Expanded) + { + if (m_Button.GetShouldAutoExpandOnClick()) + m_Button.Expanded = true; + else + m_Button.SetMouseDown(true); + this.Invalidate(); + } + _IsSpaceKeyDown = (e.KeyCode == Keys.Space); + base.OnKeyDown(e); + } + + protected override void OnKeyUp(KeyEventArgs e) + { + if (e.KeyCode == Keys.Space && _IsSpaceKeyDown && !m_Button.Expanded) + { + m_Button.SetMouseDown(false); + this.Invalidate(); + PerformClick(); + } + _IsSpaceKeyDown = false; + base.OnKeyUp(e); + } + + protected override void OnMouseEnter(EventArgs e) + { + m_Button.InternalMouseEnter(); + base.OnMouseEnter(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + m_Button.InternalMouseMove(e); + base.OnMouseMove(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + m_Button.InternalMouseLeave(); + base.OnMouseLeave(e); + } + + protected override void OnMouseHover(EventArgs e) + { + m_Button.InternalMouseHover(); + base.OnMouseHover(e); + } + + private Point _MouseDownPoint = Point.Empty; + protected override void OnMouseDown(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + if (!this.Focused && this.CanSelect && _FocusOnLeftMouseButtonDown) + { + if (!this.Focus()) + return; + } + _MouseDownPoint = new Point(e.X, e.Y); + } + + m_Button.InternalMouseDown(e); + base.OnMouseDown(e); + } + + private bool _FocusOnLeftMouseButtonDown = true; + /// + /// Gets or sets whether button is focused when pressed using left mouse button. Default value is true. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool FocusOnLeftMouseButtonDown + { + get { return _FocusOnLeftMouseButtonDown; } + set + { + _FocusOnLeftMouseButtonDown = value; + } + } + + protected override void OnMouseUp(MouseEventArgs e) + { + m_Button.InternalMouseUp(e); + if (e.Button == MouseButtons.Left && this.ClientRectangle.Contains(e.X, e.Y) && !_MouseDownPoint.IsEmpty) + { +#if FRAMEWORK20 + this.OnMouseClick(e); +#endif + this.OnClick(e); + } + _MouseDownPoint = Point.Empty; + base.OnMouseUp(e); + } + + protected override void OnVisibleChanged(EventArgs e) + { + if(m_Button.IsMouseOver) + m_Button.InternalMouseLeave(); + + base.OnVisibleChanged(e); + } + + private bool IsImageSet + { + get + { + if (!string.IsNullOrEmpty(this.Symbol)) + return true; + CompositeImage image = m_Button.GetImage(); + bool imageSet = image != null; + if (image != null) + image.Dispose(); + return imageSet; + } + } + protected override void OnClick(EventArgs e) + { + // Ignore Click event if it is fired when click occurred on sub items rectangle... + if (!m_Button.SubItemsRect.IsEmpty) + { + Point p = this.PointToClient(Control.MousePosition); + if (m_Button.SubItemsRect.Contains(p)) + return; + } + + if (this.SplitButton && !m_Button.TextDrawRect.IsEmpty && IsImageSet) + { + Point p = this.PointToClient(Control.MousePosition); + if (m_Button.TextDrawRect.Contains(p)) + return; + } + + Form form1 = this.FindForm(); + if (form1 != null) + { + form1.DialogResult = this.DialogResult; + } + + base.OnClick(e); + + if(ExecuteCommandOnClick) + ExecuteCommand(); + } + + /// + /// Gets whether command is executed when button is clicked. + /// + protected virtual bool ExecuteCommandOnClick + { + get { return true; } + } + + protected override void OnGotFocus(EventArgs e) + { + m_Button.OnGotFocus(); + base.OnGotFocus(e); + } + + protected override void OnLostFocus(EventArgs e) + { + m_Button.OnLostFocus(); + base.OnLostFocus(e); + } + + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return m_Button.SymbolColor; } + set { m_Button.SymbolColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return m_Button.ShouldSerializeSymbolColor(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + m_Button.ResetSymbolColor(); + } + + /// + /// Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return m_Button.Symbol; } + set + { + m_Button.Symbol = value; + } + } + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return m_Button.SymbolSet; } + set { m_Button.SymbolSet = value; } + } + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(0f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return m_Button.SymbolSize; } + set + { + m_Button.SymbolSize = value; + } + } + + /// + /// Specifies the Button image which is used when button background is black or very dark. Image is used when button text is white. This is provided for Metro style applications. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Specifies the Button image which is used when button background is black or very dark. Image is used when button text is white. This is provided for Metro style applications."), DefaultValue(null)] + public System.Drawing.Image ImageAlt + { + get { return m_Button.ImageAlt; } + set + { + m_Button.ImageAlt = value; + } + } + /// + /// Specifies the Button image. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("The image that will be displayed on the face of the button."), DefaultValue(null)] + public System.Drawing.Image Image + { + get { return m_Button.Image; } + set + { + m_Button.Image = value; + InvalidateAutoSize(); +#if FRAMEWORK20 + this.AdjustSize(); +#endif + } + } + + /// + /// Specifies the image for the button when mouse is over the item. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("The image that will be displayed when mouse hovers over the item."), DefaultValue(null)] + public System.Drawing.Image HoverImage + { + get { return m_Button.HoverImage; } + set { m_Button.HoverImage = value; } + } + + /// + /// Specifies the image for the button when items Enabled property is set to false. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("The image that will be displayed when item is disabled."),DefaultValue(null)] + public System.Drawing.Image DisabledImage + { + get { return m_Button.DisabledImage; } + set { m_Button.DisabledImage = value; } + } + + /// + /// Specifies the image for the button when mouse left button is pressed. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("The image that will be displayed when item is pressed."), DefaultValue(null)] + public System.Drawing.Image PressedImage + { + get { return m_Button.PressedImage; } + set { m_Button.PressedImage = value; } + } + + /// + /// Gets or sets the location of popup in relation to it's parent. + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(ePopupSide.Default), Description("Indicates location of popup in relation to it's parent.")] + public ePopupSide PopupSide + { + get { return m_Button.PopupSide; } + set { m_Button.PopupSide = value; InvalidateAutoSize(); } + } + + /// + /// Returns the collection of sub items. + /// + [Browsable(true), DevCoBrowsable(false), Editor("DevComponents.DotNetBar.Design.ButtonItemEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Data"), Description("Collection of sub items."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public virtual SubItemsCollection SubItems + { + get + { + return m_Button.SubItems; + } + } + + /// + /// Gets or sets whether button appears as split button. Split button appearance divides button into two parts. Image which raises the click event + /// when clicked and text and expand sign which shows button sub items on popup menu when clicked. Button must have both text and image visible (ButtonStyle property) in order to appear as a full split button. + /// + [Browsable(true), DefaultValue(false), Category("Appearance"), Description("Indicates whether button appears as split button.")] + public bool SplitButton + { + get { return m_Button.SplitButton; } + set { m_Button.SplitButton = value; InvalidateAutoSize(); } + } + + /// + /// Gets or sets whether button displays the expand part that indicates that button has popup. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.DefaultValue(true), System.ComponentModel.Category("Behavior"), System.ComponentModel.Description("Determines whether sub-items are displayed.")] + public bool ShowSubItems + { + get + { + return m_Button.ShowSubItems; + } + set + { + m_Button.ShowSubItems = value; + } + } + + /// + /// Gets/Sets the image position inside the button. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("The alignment of the image in relation to text displayed by this item."), DefaultValue(eImagePosition.Left)] + public eImagePosition ImagePosition + { + get { return m_Button.ImagePosition; } + set + { + m_Button.ImagePosition = value; + InvalidateAutoSize(); + this.RecalcLayout(); + } + } + + /// + /// Gets or sets whether mouse over fade effect is enabled. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether mouse over fade effect is enabled")] + public bool FadeEffect + { + get { return m_FadeEffect; } + set + { + m_FadeEffect = value; + } + } + + internal bool IsFadeEnabled + { + get + { + if (this.DesignMode || (!BarFunctions.IsOffice2007Style(m_Button.EffectiveStyle)) || + m_FadeEffect && NativeFunctions.IsTerminalSession() || IsThemed || TextDrawing.UseTextRenderer) + return false; + return m_FadeEffect; + } + } + + /// + /// Indicates the way button is rendering the mouse over state. Setting the value to Color will render the image in gray-scale when mouse is not over the item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Indicates the button mouse over tracking style. Setting the value to Color will render the image in gray-scale when mouse is not over the item."), System.ComponentModel.DefaultValue(eHotTrackingStyle.Default)] + public virtual eHotTrackingStyle HotTrackingStyle + { + get { return m_Button.HotTrackingStyle; } + set + { + m_Button.HotTrackingStyle = value; + } + } + + internal override ItemPaintArgs GetItemPaintArgs(Graphics g) + { + ItemPaintArgs pa = base.GetItemPaintArgs(g); + pa.IsDefaultButton = m_IsDefault && _FocusCuesEnabled; + + return pa; + } + + /// + /// Gets or sets the width of the expand part of the button item. + /// + [Browsable(true), DevCoBrowsable(true), Category("Behavior"), Description("Indicates the width of the expand part of the button item."), DefaultValue(12)] + public virtual int SubItemsExpandWidth + { + get { return m_Button.SubItemsExpandWidth; } + set + { + m_Button.SubItemsExpandWidth = value; + this.RecalcLayout(); + } + } + + /// + /// Gets or sets the text associated with this button. + /// + [Browsable(true), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Appearance"), Description("Indicates text associated with this button.."), Localizable(true), DefaultValue("")] + public override string Text + { + get { return base.Text; } + set { base.Text = value; } + } + + /// + /// Gets/Sets informational text (tooltip) for the button. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(""), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Appearance"), Description("Indicates informational text (tooltip) for the button."), Localizable(true)] + public virtual string Tooltip + { + get { return m_Button.Tooltip; } + set { m_Button.Tooltip = value; } + } + + private bool _EnableMnemonicWithAltKeyOnly = false; + /// + /// Gets or sets whether mnemonic character assigned to button is processed only if Alt key is pressed. Default value is false which indicate that Alt key is not required. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether mnemonic character assigned to button is processed only if Alt key is pressed")] + public bool EnableMnemonicWithAltKeyOnly + { + get { return _EnableMnemonicWithAltKeyOnly; } + set + { + _EnableMnemonicWithAltKeyOnly = value; + } + } + + private bool _UseMnemonic = true; + /// + /// Gets or sets a value indicating whether the control interprets an ampersand character (&) in the control's Text property to be an access key prefix character. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether the control interprets an ampersand character (&) in the control's Text property to be an access key prefix character.")] + public bool UseMnemonic + { + get { return _UseMnemonic; } + set + { + _UseMnemonic = value; + if (this.IsHandleCreated) + UpdateButtonAutoSize(); + } + } + + protected override bool ProcessMnemonic(char charCode) + { + if (CanSelect && IsMnemonic(charCode, this.Text) && this.Enabled && _UseMnemonic && + (!_EnableMnemonicWithAltKeyOnly || Control.ModifierKeys == Keys.Alt || this.Focused) && !m_Button.IsUsingTextMarkup) + { + if (Focus()) + { + PerformClick(); + return true; + } + } + return base.ProcessMnemonic(charCode); + } + + /// + /// Indicates whether the button will auto-expand when clicked. + /// When button contains sub-items, sub-items will be shown only if user + /// click the expand part of the button. Setting this property to true will expand the button and show sub-items when user + /// clicks anywhere inside of the button. Default value is false which indicates that button is expanded only + /// if its expand part is clicked. + /// + [DefaultValue(false), Browsable(true), DevCoBrowsable(true), Category("Behavior"), Description("Indicates whether the button will auto-expand (display pop-up menu or toolbar) when clicked.")] + public virtual bool AutoExpandOnClick + { + get { return (InternalAutoExpandOnClick); } + set { InternalAutoExpandOnClick = value; } + } + + protected bool InternalAutoExpandOnClick + { + get { return m_Button.AutoExpandOnClick; } + set + { + m_Button.AutoExpandOnClick = value; + this.RecalcLayout(); + } + } + + /// + /// Gets or sets whether Checked property is automatically inverted, button checked/unchecked, when button is clicked. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Behavior"), Description("Indicates whether Checked property is automatically inverted when button is clicked.")] + public bool AutoCheckOnClick + { + get { return m_Button.AutoCheckOnClick; } + set { m_Button.AutoCheckOnClick = value; } + } + + /// + /// Gets or set a value indicating whether the button is in the checked state. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Indicates whether item is checked or not."), DefaultValue(false)] + public virtual bool Checked + { + get + { + return m_Button.Checked; + } + set + { + m_Button.Checked = value; + this.Invalidate(); + } + } + + private static RoundRectangleShapeDescriptor _DefaultButtonShape = new RoundRectangleShapeDescriptor(2); + private static RoundRectangleShapeDescriptor _DefaultMetroButtonShape = new RoundRectangleShapeDescriptor(0); + internal IShapeDescriptor GetButtonShape() + { + if (this.Shape != null) + return this.Shape; + if (StyleManager.IsMetro(m_Button.EffectiveStyle)) + return _DefaultMetroButtonShape; + return _DefaultButtonShape; + } + + private ShapeDescriptor _Shape = null; + /// + /// Gets or sets an shape descriptor for the button which describes the shape of the button. Default value is null + /// which indicates that system default shape is used. + /// + [DefaultValue(null), Editor("DevComponents.DotNetBar.Design.ShapeTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor)), TypeConverter("DevComponents.DotNetBar.Design.ShapeStringConverter, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), MergableProperty(false)] + public ShapeDescriptor Shape + { + get { return _Shape; } + set + { + if (_Shape != value) + { + _Shape = value; + this.Invalidate(); + } + } + } + + private bool _FocusCuesEnabled = true; + /// + /// Gets or sets whether control displays focus cues when focused. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether control displays focus cues when focused.")] + public virtual bool FocusCuesEnabled + { + get { return (InternalFocusCuesEnabled); } + set { InternalFocusCuesEnabled = value; } + } + + protected bool InternalFocusCuesEnabled + { + get { return _FocusCuesEnabled; } + set + { + _FocusCuesEnabled = value; + if (this.Focused) this.Invalidate(); + } + } + + internal int CornerSize + { + get { return 2; } + } + + /// + /// Gets or sets the custom color name. Name specified here must be represented by the corresponding object with the same name that is part + /// of the Office2007ColorTable.ButtonItemColors collection. See documentation for Office2007ColorTable.ButtonItemColors for more information. + /// If color table with specified name cannot be found default color will be used. Valid settings for this property override any + /// setting to the Color property. + /// Applies to items with Office 2007 style only. + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(""), Category("Appearance"), Description("Indicates custom color table name for the button when Office 2007 style is used.")] + public string CustomColorName + { + get { return m_Button.CustomColorName; } + set + { + m_Button.CustomColorName = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the predefined color of the button. Color specified applies to buttons with Office 2007 style only. It does not have + /// any effect on other styles. Default value is eButtonColor.Default + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(eButtonColor.BlueWithBackground), Category("Appearance"), Description("Indicates predefined color of button when Office 2007 style is used.")] + public eButtonColor ColorTable + { + get { return m_Button.ColorTable; } + set + { + if (m_Button.ColorTable != value) + { + m_Button.ColorTable = value; + this.Invalidate(); + } + } + } + protected override void InvalidateAutoSize() + { + m_PreferredSize = Size.Empty; + } + +#if FRAMEWORK20 + //[Localizable(true), Browsable(false)] + //public new System.Windows.Forms.Padding Padding + //{ + // get { return base.Padding; } + // set { base.Padding = value; } + //} + + public override Size GetPreferredSize(Size proposedSize) + { + if (!m_PreferredSize.IsEmpty) return m_PreferredSize; + + if (!BarFunctions.IsHandleValid(this)) + return base.GetPreferredSize(proposedSize); + if (this.Text.Length == 0 && this.Image == null) + return base.GetPreferredSize(proposedSize); + + int oldWidth = m_Button.WidthInternal, oldHeight = m_Button.HeightInternal; + + m_Button._FitContainer = false; + m_Button.RecalcSize(); + + Size s = m_Button.Size; + if (s.Width < this.MinimumSize.Width) + s.Width = this.MinimumSize.Width; + if (s.Height < this.MinimumSize.Height) + s.Height = this.MinimumSize.Height; + + if (m_AutoSizeMode == AutoSizeMode.GrowOnly) + { + if (s.Width < this.Size.Width) + s.Width = this.Size.Width; + if (s.Height < this.Size.Height) + s.Height = this.Size.Height; + + if (proposedSize.Width > 0 && proposedSize.Width < 50000 && s.Width < proposedSize.Width) + s.Width = proposedSize.Width; + if (proposedSize.Height > 0 && proposedSize.Height < 50000 && s.Height < proposedSize.Height) + s.Height = proposedSize.Height; + + } + m_Button._FitContainer = true; + RecalcSize(); + m_PreferredSize = s; + return m_PreferredSize; + } + + /// + /// Gets or sets a value indicating whether the control is automatically resized to display its entire contents. You can set MaximumSize.Width property to set the maximum width used by the control. + /// + [Browsable(true), DefaultValue(false), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override bool AutoSize + { + get + { + return base.AutoSize; + } + set + { + if (this.AutoSize != value) + { + base.AutoSize = value; + InvalidateAutoSize(); + AdjustSize(); + } + } + } + + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + if (this.AutoSize) + { + Size preferredSize = base.PreferredSize; + if(preferredSize.Width>0) + width = preferredSize.Width; + if (preferredSize.Height > 0) + height = preferredSize.Height; + } + base.SetBoundsCore(x, y, width, height, specified); + } + + protected override void AdjustSize() + { + if (this.AutoSize) + { + System.Drawing.Size prefSize = base.PreferredSize; + if(prefSize.Width>0 && prefSize.Height>0) + this.Size = base.PreferredSize; + } + } + + private AutoSizeMode m_AutoSizeMode = AutoSizeMode.GrowOnly; + /// + /// Gets or sets the mode by which the Button automatically resizes itself. + /// + [LocalizableAttribute(true), Browsable(true), DefaultValue(AutoSizeMode.GrowOnly), Category("Layout"), Description("Indicates the mode by which the Button automatically resizes itself. ")] + public AutoSizeMode AutoSizeMode + { + get { return m_AutoSizeMode; } + set + { + if (m_AutoSizeMode != value) + { + m_AutoSizeMode = value; + InvalidateAutoSize(); + AdjustSize(); + } + } + } + + //[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + //public override Image BackgroundImage + //{ + // get { return base.BackgroundImage; } + // set { base.BackgroundImage = value; } + //} + //[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + //public override ImageLayout BackgroundImageLayout + //{ + // get + // { + // return base.BackgroundImageLayout; + // } + // set + // { + // base.BackgroundImageLayout = value; + // } + //} +#endif + private int _ImageTextSpacing = 0; + /// + /// Gets or sets the amount of spacing between button image if specified and text. + /// + [Browsable(true), DefaultValue(0), Category("Layout"), Description("Indicates amount of spacing between button image if specified and text.")] + public virtual int ImageTextSpacing + { + get { return _ImageTextSpacing; } + set + { + _ImageTextSpacing = value; + RecalcLayout(); + } + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + + private static readonly Color DefaultTextColor = Color.Empty; + private Color _TextColor = DefaultTextColor; + /// + /// Gets or sets the text color. + /// + [Category("Appearance"), Description("Indicates text color.")] + public Color TextColor + { + get { return _TextColor; } + set + { + _TextColor = value; + m_Button.ForeColor = value; + } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return _TextColor != DefaultTextColor; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + this.TextColor = DefaultTextColor; + } + #endregion + + #region IButtonControl Members + /// + /// Gets or sets the value returned to the parent form when the button is clicked. + /// + [Browsable(true), Category("Behavior"), DefaultValue(DialogResult.None), Description("Gets or sets the value returned to the parent form when the button is clicked.")] + public DialogResult DialogResult + { + get + { + return m_DialogResult; + } + + set + { + if (Enum.IsDefined(typeof(DialogResult), value)) + { + m_DialogResult = value; + } + } + } + + /// + /// Notifies a control that it is the default button so that its appearance and behavior is adjusted accordingly. + /// + /// true if the control should behave as a default button; otherwise false. + public void NotifyDefault(bool value) + { + if (m_IsDefault != value) + { + m_IsDefault = value; + this.Invalidate(); + } + } + + /// + /// Generates a Click event for the control. + /// + public override void PerformClick() + { + if (!this.Enabled) return; + + Form form1 = this.FindForm(); + if (form1 != null) + { + form1.DialogResult = this.DialogResult; + } + if (this.AutoCheckOnClick) this.Checked = !this.Checked; + + if (ExecuteCommandOnClick) + ExecuteCommand(); + + // Must call base since this class overrides OnClick to prevent it from firing when sub-items rect is clicked + base.OnClick(EventArgs.Empty); + } + #endregion + + #region IOwner + + /// + /// Gets or sets a value indicating whether the button is expanded (displays drop-down) or not. + /// + [Browsable(false), DefaultValue(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool Expanded + { + get { return m_Button.Expanded; } + set { m_Button.Expanded = value; } + } + + /// + /// Gets or sets the collection of shortcut keys associated with the button. When shortcut key is pressed button Click event is raised. + /// + [Browsable(true), DevCoBrowsable(true), Category("Design"), Description("Indicates list of shortcut keys for this button."), Editor("DevComponents.DotNetBar.Design.ShortcutsDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.TypeConverter("DevComponents.DotNetBar.Design.ShortcutsConverter, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public virtual ShortcutsCollection Shortcuts + { + get { return m_Button.Shortcuts; } + set { m_Button.Shortcuts = value; } + } + + /// + /// Displays the sub-items on popup specified by PopupType. + /// + /// Popup location. + public virtual void Popup(Point p) + { + m_Button.Popup(p); + } + + /// + /// Displays the sub-items on popup specified by PopupType. + /// + /// Horizontal coordinate in pixels of the upper left corner of a popup. + /// Vertical coordinate in pixels of the upper left corner of a popup. + public virtual void Popup(int x, int y) + { + m_Button.Popup(x, y); + } + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + CommandManager.ExecuteCommand(this); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + } + } + + private ICommand _Command = null; + //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if(changed) + OnCommandChanged(); + } + } + + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + } + } + + #endregion + } + + #region ButtonXAccessibleObject + /// + /// Represents class for Accessibility support. + /// + public class ButtonXAccessibleObject : Control.ControlAccessibleObject + { + private ButtonX m_Owner = null; + /// + /// Creates new instance of the object and initializes it with owner control. + /// + /// Reference to owner control. + public ButtonXAccessibleObject(ButtonX owner) + : base(owner) + { + m_Owner = owner; + } + + protected ButtonX Owner + { + get { return m_Owner; } + } + + ///// + ///// Gets or sets accessible name. + ///// + //public override string Name + //{ + // get + // { + // if (m_Owner != null && !m_Owner.IsDisposed && !string.IsNullOrEmpty(m_Owner.AccessibleName)) + // return m_Owner.AccessibleName; + // if (m_Owner != null) return TextWithoutMnemonics(m_Owner.Text); + // return ""; + // } + // set + // { + // if (m_Owner != null && !m_Owner.IsDisposed) + // m_Owner.AccessibleName = value; + // } + //} + + //internal static string TextWithoutMnemonics(string text) + //{ + // if (text == null) + // { + // return null; + // } + // int index = text.IndexOf('&'); + // if (index == -1) + // { + // return text; + // } + // StringBuilder builder = new StringBuilder(text.Substring(0, index)); + // while (index < text.Length) + // { + // if (text[index] == '&') + // { + // index++; + // } + // if (index < text.Length) + // { + // builder.Append(text[index]); + // } + // index++; + // } + // return builder.ToString(); + //} + + ///// + ///// Gets accessible description. + ///// + //public override string Description + //{ + // get + // { + // if (m_Owner != null && !m_Owner.IsDisposed) + // return m_Owner.AccessibleDescription; + // return ""; + // } + //} + + ///// + ///// Gets accessible role. + ///// + //public override AccessibleRole Role + //{ + // get + // { + // if (m_Owner != null && !m_Owner.IsDisposed) + // return m_Owner.AccessibleRole; + // return System.Windows.Forms.AccessibleRole.None; + // } + //} + + ///// + ///// Gets parent accessibility object. + ///// + //public override AccessibleObject Parent + //{ + // get + // { + // if (m_Owner != null && !m_Owner.IsDisposed) + // return m_Owner.Parent.AccessibilityObject; + // return null; + // } + //} + + ///// + ///// Returns bounds of the control. + ///// + //public override Rectangle Bounds + //{ + // get + // { + // if (m_Owner != null && !m_Owner.IsDisposed && m_Owner.Parent != null) + // return this.m_Owner.Parent.RectangleToScreen(m_Owner.Bounds); + // return Rectangle.Empty; + // } + //} + + /// + /// Returns number of child objects. + /// + /// Total number of child objects. + public override int GetChildCount() + { + if (m_Owner != null && !m_Owner.IsDisposed) + return m_Owner.InternalItem.AccessibleObject.GetChildCount(); + return 0; + } + + /// + /// Returns reference to child object given the index. + /// + /// 0 based index of child object. + /// Reference to child object. + public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) + { + if (m_Owner != null && !m_Owner.IsDisposed) + return m_Owner.InternalItem.AccessibleObject.GetChild(iIndex); //return m_Owner.SubItems[iIndex].AccessibleObject; + return null; + } + + /// + /// Returns current accessible state. + /// + public override AccessibleStates State + { + get + { + AccessibleStates state=m_Owner.InternalItem.AccessibleObject.State; + if(m_Owner.Focused) + state|= AccessibleStates.Focused; + return state; + } + } + + ///// + ///// Gets or sets the value of an accessible object. + ///// + //public override string Value + //{ + // get + // { + // return m_Owner.Text; + // } + // set + // { + // m_Owner.Text = value; + // } + //} + + public override void DoDefaultAction() + { + if (m_Owner != null) + m_Owner.PerformClick(); + } + + public override string DefaultAction + { + get + { + if (m_Owner != null && m_Owner.AccessibleDefaultActionDescription != "") + return m_Owner.AccessibleDefaultActionDescription; + + return "Click"; + } + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/ButtonX/ButtonX.ico b/PROMS/DotNetBar Source Code/ButtonX/ButtonX.ico new file mode 100644 index 00000000..66d1a417 Binary files /dev/null and b/PROMS/DotNetBar Source Code/ButtonX/ButtonX.ico differ diff --git a/PROMS/DotNetBar Source Code/ButtonX/ThemedButtonXPainter.cs b/PROMS/DotNetBar Source Code/ButtonX/ThemedButtonXPainter.cs new file mode 100644 index 00000000..93c76cd2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ButtonX/ThemedButtonXPainter.cs @@ -0,0 +1,191 @@ +using System; +using System.Drawing; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for ThemedButtonItemPainter. + /// + internal class ThemedButtonXPainter + { + public static void PaintButton(ButtonItem button, ItemPaintArgs pa) + { + System.Drawing.Graphics g = pa.Graphics; + ThemeButton theme = pa.ThemeButton; + ThemeButtonParts part = ThemeButtonParts.PushButton; + ThemeButtonStates state = ThemeButtonStates.PushButtonNormal; + Color textColor = ButtonItemPainterHelper.GetTextColor(button, pa); + ButtonX buttonX = pa.ContainerControl as ButtonX; + bool paintFocusCues = true; + if (buttonX != null) paintFocusCues = buttonX.FocusCuesEnabled; + Rectangle rectImage = Rectangle.Empty; + Rectangle itemRect = button.DisplayRectangle; + + Font font = null; + CompositeImage image = button.GetImage(); + + eTextFormat format = GetStringFormat(button, pa, image); + + font = button.GetFont(pa, false); + + bool bSplitButton = (button.SubItems.Count > 0 || button.PopupType == ePopupType.Container) && button.ShowSubItems && !button.SubItemsRect.IsEmpty; + + // Calculate image position + if (image != null) + { + if (button.ImagePosition == eImagePosition.Top || button.ImagePosition == eImagePosition.Bottom) + rectImage = new Rectangle(button.ImageDrawRect.X, button.ImageDrawRect.Y, itemRect.Width, button.ImageDrawRect.Height); + else + rectImage = new Rectangle(button.ImageDrawRect.X, button.ImageDrawRect.Y, button.ImageDrawRect.Width, button.ImageDrawRect.Height); + + rectImage.Offset(itemRect.Left, itemRect.Top); + rectImage.Offset((rectImage.Width - button.ImageSize.Width) / 2, (rectImage.Height - button.ImageSize.Height) / 2); + rectImage.Width = button.ImageSize.Width; + rectImage.Height = button.ImageSize.Height; + } + + // Set the state and text brush + if (!ButtonItemPainter.IsItemEnabled(button, pa)) + { + state = ThemeButtonStates.PushButtonDisabled; + } + else if (button.IsMouseDown || button.Expanded) + { + state = ThemeButtonStates.PushButtonPressed; + } + else if (button.IsMouseOver && button.Checked) + { + state = ThemeButtonStates.PushButtonPressed; + } + else if (button.IsMouseOver) + { + state = ThemeButtonStates.PushButtonHot; + } + else if (button.Checked || button.Expanded) + { + state = ThemeButtonStates.PushButtonPressed; + } + else if (button.Focused || pa.ContainerControl.Focused) + state = ThemeButtonStates.PushButtonDefaulted; + + Rectangle backRect = button.DisplayRectangle; + if (button.HotTrackingStyle == eHotTrackingStyle.Image && image != null) + { + backRect = rectImage; + backRect.Inflate(3, 3); + } + //else if (bSplitButton) + //{ + // backRect.Width = backRect.Width - button.SubItemsRect.Width; + //} + + // Draw Button Background + if (button.HotTrackingStyle != eHotTrackingStyle.None) + { + theme.DrawBackground(g, part, state, backRect); + } + + // Draw Image + if (image != null && button.ButtonStyle != eButtonStyle.TextOnlyAlways) + { + if (state == ThemeButtonStates.PushButtonNormal && button.HotTrackingStyle == eHotTrackingStyle.Color) + { + // Draw gray-scale image for this hover style... + float[][] array = new float[5][]; + array[0] = new float[5] { 0.2125f, 0.2125f, 0.2125f, 0, 0 }; + array[1] = new float[5] { 0.5f, 0.5f, 0.5f, 0, 0 }; + array[2] = new float[5] { 0.0361f, 0.0361f, 0.0361f, 0, 0 }; + array[3] = new float[5] { 0, 0, 0, 1, 0 }; + array[4] = new float[5] { 0.2f, 0.2f, 0.2f, 0, 1 }; + System.Drawing.Imaging.ColorMatrix grayMatrix = new System.Drawing.Imaging.ColorMatrix(array); + System.Drawing.Imaging.ImageAttributes att = new System.Drawing.Imaging.ImageAttributes(); + att.SetColorMatrix(grayMatrix); + //g.DrawImage(image,rectImage,0,0,image.Width,image.Height,GraphicsUnit.Pixel,att); + image.DrawImage(g, rectImage, 0, 0, image.ActualWidth, image.ActualHeight, GraphicsUnit.Pixel, att); + } + else if (state == ThemeButtonStates.PushButtonNormal && !image.IsIcon) + { + // Draw image little bit lighter, I decied to use gamma it is easy + System.Drawing.Imaging.ImageAttributes lightImageAttr = new System.Drawing.Imaging.ImageAttributes(); + lightImageAttr.SetGamma(.7f, System.Drawing.Imaging.ColorAdjustType.Bitmap); + //g.DrawImage(image,rectImage,0,0,image.Width,image.Height,GraphicsUnit.Pixel,lightImageAttr); + image.DrawImage(g, rectImage, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, lightImageAttr); + } + else + { + image.DrawImage(g, rectImage); + } + } + + // Draw Text + if (button.ButtonStyle == eButtonStyle.ImageAndText || button.ButtonStyle == eButtonStyle.TextOnlyAlways || image == null) + { + Rectangle rectText = button.TextDrawRect; + if (button.ImagePosition == eImagePosition.Top || button.ImagePosition == eImagePosition.Bottom) + { + if (button.Orientation == eOrientation.Vertical) + { + rectText = new Rectangle(button.TextDrawRect.X, button.TextDrawRect.Y, button.TextDrawRect.Width, button.TextDrawRect.Height); + } + else + { + rectText = new Rectangle(button.TextDrawRect.X, button.TextDrawRect.Y, button.TextDrawRect.Width, button.TextDrawRect.Height); + //if ((button.SubItems.Count > 0 || button.PopupType == ePopupType.Container) && button.ShowSubItems) + // rectText.Width -= 10; + } + format |= eTextFormat.HorizontalCenter; + } + + rectText.Offset(itemRect.Left, itemRect.Top); + + if (button.Orientation == eOrientation.Vertical) + { + g.RotateTransform(90); + TextDrawing.DrawStringLegacy(g, ButtonItemPainter.GetDrawText(button.Text), font, textColor, new Rectangle(rectText.Top, -rectText.Right, rectText.Height, rectText.Width), format); + g.ResetTransform(); + } + else + { + if (rectText.Right > button.DisplayRectangle.Right) + rectText.Width = button.DisplayRectangle.Right - rectText.Left; + TextDrawing.DrawString(g, ButtonItemPainter.GetDrawText(button.Text), font, textColor, rectText, format); + if (!button.DesignMode && button.Focused && paintFocusCues && !pa.IsOnMenu && !pa.IsOnMenuBar) + { + Rectangle r = button.Bounds; + r.Inflate(-3, -3); + System.Windows.Forms.ControlPaint.DrawFocusRectangle(g, r); + } + } + } + + // If it has subitems draw the triangle to indicate that + if (bSplitButton) + { + ButtonItemPainter.PaintButtonExpandIndicator(button, pa); + } + + if (image != null) + image.Dispose(); + } + + private static eTextFormat GetStringFormat(ButtonItem button, ItemPaintArgs pa, CompositeImage image) + { + eTextFormat stringFormat = pa.ButtonStringFormat; + bool isOnMenu = IsOnMenu(button, pa); + if (!isOnMenu) + { + if (image == null || button.ImagePosition == eImagePosition.Top || button.ImagePosition == eImagePosition.Bottom) + stringFormat |= eTextFormat.HorizontalCenter; + } + return stringFormat; + } + + private static bool IsOnMenu(ButtonItem button, ItemPaintArgs pa) + { + bool isOnMenu = pa.IsOnMenu; + if (isOnMenu && button.Parent is ItemContainer) + isOnMenu = false; + return isOnMenu; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Calculator.ico b/PROMS/DotNetBar Source Code/Calculator.ico new file mode 100644 index 00000000..af20d9d6 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Calculator.ico differ diff --git a/PROMS/DotNetBar Source Code/CheckBoxItem/CheckBoxItem.cs b/PROMS/DotNetBar Source Code/CheckBoxItem/CheckBoxItem.cs new file mode 100644 index 00000000..8c3516fe --- /dev/null +++ b/PROMS/DotNetBar Source Code/CheckBoxItem/CheckBoxItem.cs @@ -0,0 +1,812 @@ +using System; +using System.Text; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the Check-box item. Use a CheckBox to give the user an option, such as true/false or yes/no. + /// + [ToolboxItem(false), DesignTimeVisible(false), DefaultEvent("Click"), Designer("DevComponents.DotNetBar.Design.CheckBoxItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class CheckBoxItem : BaseItem + { + #region Private Variables + private bool m_Checked = false; + private eCheckBoxStyle m_CheckBoxStyle = eCheckBoxStyle.CheckBox; + private Size m_CheckSignSize = new Size(13, 13); + private eCheckBoxPosition m_CheckBoxPosition = eCheckBoxPosition.Left; + private int m_CheckTextSpacing = 6; + private int m_VerticalPadding = 3; + private bool m_MouseDown = false; + private bool m_MouseOver = false; + private bool m_TextVisible = true; + private Color m_TextColor = Color.Empty; + private bool m_ThreeState = false; + private CheckState m_CheckState = CheckState.Unchecked; + #endregion + + #region Events + /// + /// Occurs before Checked property is changed and allows you to cancel the change. + /// + public event CheckBoxChangeEventHandler CheckedChanging; + /// + /// Occurs after Checked property is changed. Action cannot be cancelled. + /// + public event CheckBoxChangeEventHandler CheckedChanged; + /// + /// Occurs when CheckState property has changed. + /// + public event EventHandler CheckStateChanged; + /// + /// Occurs when CheckedBindable property has changed. + /// + public event EventHandler CheckedBindableChanged; + #endregion + + #region Constructor, Copy + /// + /// Creates new instance of CheckBoxItem. + /// + public CheckBoxItem():this("","") {} + /// + /// Creates new instance of CheckBoxItem and assigns the name to it. + /// + /// Item name. + public CheckBoxItem(string sItemName):this(sItemName,"") {} + /// + /// Creates new instance of CheckBoxItem and assigns the name and text to it. + /// + /// Item name. + /// item text. + public CheckBoxItem(string sItemName, string ItemText) + : base(sItemName, ItemText) + { + } + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + CheckBoxItem objCopy = new CheckBoxItem(m_Name); + this.CopyToItem(objCopy); + return objCopy; + } + + /// + /// Copies the CheckBoxItem specific properties to new instance of the item. + /// + /// New CheckBoxItem instance. + internal void InternalCopyToItem(CheckBoxItem copy) + { + CopyToItem(copy); + } + + /// + /// Copies the CheckBoxItem specific properties to new instance of the item. + /// + /// New CheckBoxItem instance. + protected override void CopyToItem(BaseItem copy) + { + CheckBoxItem objCopy = copy as CheckBoxItem; + + if (objCopy != null) + { + objCopy.CheckBoxPosition = this.CheckBoxPosition; + objCopy.CheckBoxStyle = this.CheckBoxStyle; + objCopy.Checked = this.Checked; + objCopy.CheckState = this.CheckState; + objCopy.TextColor = this.TextColor; + objCopy.TextVisible = this.TextVisible; + + objCopy.ThreeState = this.ThreeState; + objCopy.EnableMarkup = this.EnableMarkup; + + objCopy.CheckBoxImageChecked = this.CheckBoxImageChecked; + objCopy.CheckBoxImageIndeterminate = this.CheckBoxImageIndeterminate; + objCopy.CheckBoxImageUnChecked = this.CheckBoxImageUnChecked; + + base.CopyToItem(objCopy); + } + } + #endregion + + #region Internal Implementation + private bool _AutoCheck = true; + /// + /// Gets or set whether the Checked values and the item appearance are automatically changed when the Check-Box is clicked. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether the Checked values and the item appearance are automatically changed when the Check-Box is clicked.")] + public bool AutoCheck + { + get { return _AutoCheck; } + set + { + if (value != _AutoCheck) + { + bool oldValue = _AutoCheck; + _AutoCheck = value; + OnAutoCheckChanged(oldValue, value); + } + } + } + private void OnAutoCheckChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("AutoCheck")); + } + + public override void Paint(ItemPaintArgs p) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + CheckBoxItemRenderEventArgs e = new CheckBoxItemRenderEventArgs(p.Graphics, this, p.Colors, p.Font, p.RightToLeft); + e.ItemPaintArgs = p; + renderer.DrawCheckBoxItem(e); + } + else + { + Rendering.CheckBoxItemPainter painter = PainterFactory.CreateCheckBoxItemPainter(this); + if (painter != null) + { + CheckBoxItemRenderEventArgs e = new CheckBoxItemRenderEventArgs(p.Graphics, this, p.Colors, p.Font, p.RightToLeft); + e.ItemPaintArgs = p; + painter.Paint(e); + } + } + + this.DrawInsertMarker(p.Graphics); + } + + internal int CheckTextSpacing + { + get { return m_CheckTextSpacing; } + } + + internal int VerticalPadding + { + get { return m_VerticalPadding; } + set { m_VerticalPadding = value; } + } + + /// + /// Gets or sets the size of the check or radio sign. Default value is 13x13. Minimum value is 6x6. + /// + [Category("Appearance"), Description("Indicates size of the check or radio sign. Default value is 13x13.")] + public Size CheckSignSize + { + get { return m_CheckSignSize; } + set + { + if (value.Width < 6) value.Width = 6; + if (value.Height < 6) value.Height = 6; + + m_CheckSignSize = value; this.NeedRecalcSize = true; this.Refresh(); + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCheckSignSize() + { + return m_CheckSignSize.Width != 13 || m_CheckSignSize.Height != 13; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetCheckSignSize() + { + this.CheckSignSize = new Size(13, 13); + } + + internal Size GetCheckSignSize() + { + Size checkSignSize = m_CheckSignSize; + if (_CheckBoxImageChecked != null || _CheckBoxImageIndeterminate != null || _CheckBoxImageUnChecked != null) + { + checkSignSize = Size.Empty; + if (_CheckBoxImageChecked != null) + checkSignSize = new Size(Math.Max(checkSignSize.Width, _CheckBoxImageChecked.Width), + Math.Max(checkSignSize.Height, _CheckBoxImageChecked.Height)); + if (_CheckBoxImageIndeterminate != null) + checkSignSize = new Size(Math.Max(checkSignSize.Width, _CheckBoxImageIndeterminate.Width), + Math.Max(checkSignSize.Height, _CheckBoxImageIndeterminate.Height)); + if (_CheckBoxImageUnChecked != null) + checkSignSize = new Size(Math.Max(checkSignSize.Width, _CheckBoxImageUnChecked.Width), + Math.Max(checkSignSize.Height, _CheckBoxImageUnChecked.Height)); + return Dpi.ImageSize(checkSignSize); + } + return Dpi.Size(checkSignSize); + } + + private bool _IsTextMultiLine = false; + + internal bool IsTextMultiLine + { + get { return _IsTextMultiLine; } + } + private Size _TextSize = Size.Empty; + internal Size TextSize + { + get + { + return _TextSize; + } + } + public override void RecalcSize() + { + Control objCtrl = this.ContainerControl as Control; + if (objCtrl == null || objCtrl.Disposing || objCtrl.IsDisposed) + return; + + int verticalPadding = Dpi.Height(m_VerticalPadding); + int checkTextSpacing = Dpi.Width(m_CheckTextSpacing); + + Graphics g = BarFunctions.CreateGraphics(objCtrl); + if (g == null) return; + + Size checkSignSize = GetCheckSignSize(); + + if (m_TextVisible) + { + try + { + Size textSize = Size.Empty; + _IsTextMultiLine = false; + if (objCtrl is CheckBoxX && !((CheckBoxX) objCtrl).AutoSize) + { + textSize = ButtonItemLayout.MeasureItemText(this, g, + m_Rect.Width - checkSignSize.Width - CheckTextSpacing, objCtrl.Font, eTextFormat.Default, + objCtrl.RightToLeft == RightToLeft.Yes); + Size singleLine = TextDrawing.MeasureString(g,"Abc", objCtrl.Font); + _IsTextMultiLine = (textSize.Height > singleLine.Height); + } + else + textSize = ButtonItemLayout.MeasureItemText(this, g, 0, objCtrl.Font, eTextFormat.Default, + objCtrl.RightToLeft == RightToLeft.Yes); + textSize.Width += 1; + _TextSize = textSize; + if (m_CheckBoxPosition == eCheckBoxPosition.Left || m_CheckBoxPosition == eCheckBoxPosition.Right) + { + m_Rect = new Rectangle(m_Rect.X, m_Rect.Y, + textSize.Width + checkTextSpacing + checkSignSize.Width, + Math.Max(checkSignSize.Height, textSize.Height) + verticalPadding * 2); + } + else + { + m_Rect = new Rectangle(m_Rect.X, m_Rect.Y, + Math.Max(textSize.Width, checkSignSize.Width) + verticalPadding * 2, + textSize.Height + checkTextSpacing + checkSignSize.Height); + } + } + finally + { + g.Dispose(); + } + } + else + { + Size s = checkSignSize; + s.Width += verticalPadding * 2; + s.Height += verticalPadding * 2; + m_Rect = new Rectangle(m_Rect.Location, s); + } + + base.RecalcSize(); + } + + /// + /// Gets or sets the text associated with this item. + /// + [Browsable(true), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Appearance"), Description("The text contained in the item."), Localizable(true), DefaultValue("")] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + #region Markup Implementation + /// + /// Gets whether item supports text markup. Default is false. + /// + protected override bool IsMarkupSupported + { + get { return _EnableMarkup; } + } + + private bool _EnableMarkup = true; + /// + /// Gets or sets whether text-markup support is enabled for items Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the item instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for items Text property.")] + public bool EnableMarkup + { + get { return _EnableMarkup; } + set + { + if (_EnableMarkup != value) + { + _EnableMarkup = value; + NeedRecalcSize = true; + OnTextChanged(); + } + } + } + #endregion + + /// + /// Gets or sets whether text assigned to the check box is visible. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether text assigned to the check box is visible.")] + public bool TextVisible + { + get { return m_TextVisible; } + set + { + m_TextVisible = value; + this.NeedRecalcSize = true; + OnAppearanceChanged(); + } + } + + /// + /// Gets or sets the text color. Default value is Color.Empty which indicates that default color is used. + /// + [Browsable(true), Category("Appearance"), Description("Indicates text color.")] + public Color TextColor + { + get { return m_TextColor; } + set + { + m_TextColor = value; + OnAppearanceChanged(); + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return !m_TextColor.IsEmpty; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + this.TextColor = Color.Empty; + } + + /// + /// Gets or sets the appearance style of the item. Default value is CheckBox. Item can also assume the style of radio-button. + /// + [Browsable(true), DefaultValue(eCheckBoxStyle.CheckBox), Category("Appearance"), Description("Indicates appearance style of the item. Default value is CheckBox. Item can also assume the style of radio-button.")] + public eCheckBoxStyle CheckBoxStyle + { + get { return m_CheckBoxStyle; } + set + { + m_CheckBoxStyle = value; + OnAppearanceChanged(); + } + } + + /// + /// Gets or sets the check box position relative to the text. Default value is Left. + /// + [Browsable(true), DefaultValue(eCheckBoxPosition.Left), Category("Appearance"), Description("Indicates the check box position relative to the text.")] + public eCheckBoxPosition CheckBoxPosition + { + get { return m_CheckBoxPosition; } + set + { + m_CheckBoxPosition = value; + this.NeedRecalcSize = true; + OnAppearanceChanged(); + } + } + + public override void InternalMouseEnter() + { + base.InternalMouseEnter(); + if (!this.DesignMode && _AutoCheck) + { + m_MouseOver = true; + if (this.GetEnabled()) + this.Refresh(); + } + } + + public override void InternalMouseLeave() + { + base.InternalMouseLeave(); + if (!this.DesignMode) + { + m_MouseOver = false; + m_MouseDown = false; + if (this.GetEnabled()) + this.Refresh(); + } + } + + public override void InternalMouseDown(MouseEventArgs objArg) + { + base.InternalMouseDown(objArg); + if (objArg.Button == MouseButtons.Left && !this.DesignMode && _AutoCheck) + { + m_MouseDown = true; + if (this.GetEnabled()) + this.Refresh(); + } + } + + public override void InternalMouseUp(MouseEventArgs objArg) + { + base.InternalMouseUp(objArg); + + if (m_MouseDown && !this.DesignMode) + { + m_MouseDown = false; + if (this.GetEnabled()) + this.Refresh(); + } + } + + /// + /// Gets whether mouse is over the item. + /// + [Browsable(false)] + public bool IsMouseOver + { + get { return m_MouseOver; } + internal set { m_MouseOver = value; } + } + + /// + /// Gets whether left mouse button is pressed on the item. + /// + [Browsable(false)] + public bool IsMouseDown + { + get { return m_MouseDown; } + internal set { m_MouseDown = value; } + } + + /// + /// Gets or set a value indicating whether the button is in the checked state. + /// + [Browsable(true), RefreshProperties(RefreshProperties.All), Category("Appearance"), Description("Indicates whether item is checked or not."), DefaultValue(false), Bindable(false)] + public virtual bool Checked + { + get + { + return m_Checked; + } + set + { + if (m_Checked != value) + { + if (m_ThreeState && value && m_CheckState != CheckState.Unchecked) return; + + SetChecked(value, eEventSource.Code); + } + } + } + + /// + /// Gets or set a value indicating whether the button is in the checked state. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), RefreshProperties(RefreshProperties.All), Category("Appearance"), Description("Indicates whether item is checked or not."), DefaultValue(false), Bindable(true)] + public virtual bool CheckedBindable + { + get + { + return this.Checked; + } + set + { + this.Checked = value; + } + } + + /// + /// Raises the click event and provide the information about the source of the event. + /// + /// + public override void RaiseClick(eEventSource source) + { + if (_AutoCheck && CanRaiseClick && !(this.CheckBoxStyle == eCheckBoxStyle.RadioButton && this.Checked)) + { + if (this.ThreeState) + { + if (this.CheckState == CheckState.Unchecked) + SetChecked(CheckState.Checked, source); + else if (this.CheckState == CheckState.Checked) + SetChecked(CheckState.Indeterminate, source); + else if (this.CheckState == CheckState.Indeterminate) + SetChecked(CheckState.Unchecked, source); + } + else + SetChecked(!this.Checked, source); + + ExecuteCommand(); + } + base.RaiseClick(source); + } + + /// + /// Sets the Checked property of the item, raises appropriate events and provides the information about the source of the change. + /// + /// New value for Checked property + /// Source of the change. + public virtual void SetChecked(bool newValue, eEventSource source) + { + // Allow user to cancel the checking + if (m_CheckBoxStyle == eCheckBoxStyle.RadioButton && newValue && this.Parent != null) + { + CheckBoxItem b = null; + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this) + continue; + b = item as CheckBoxItem; + if (b != null && b.Checked && b.CheckBoxStyle == eCheckBoxStyle.RadioButton) + { + break; + } + } + CheckBoxChangeEventArgs e = new CheckBoxChangeEventArgs(b, this, source); + InvokeCheckedChanging(e); + if (e.Cancel) + return; + } + else + { + CheckBoxChangeEventArgs e = new CheckBoxChangeEventArgs(null, this, source); + InvokeCheckedChanging(e); + if (e.Cancel) + return; + } + + m_Checked = newValue; + if (m_Checked && m_CheckState == CheckState.Unchecked || !m_Checked && m_CheckState != CheckState.Unchecked) + { + m_CheckState = m_Checked ? CheckState.Checked : CheckState.Unchecked; + } + + if (this.Command != null) + this.Command.Checked = m_Checked; + + this.OnCheckedChanged(source); + OnCheckedBindableChanged(EventArgs.Empty); + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "Checked"); + + if (this.Displayed) + this.Refresh(); + } + + /// + /// Called when Command property value changes. + /// + protected override void OnCommandChanged() + { + Command command = this.Command; + if (command != null && command.Checked != this.Checked) + { + SetChecked(command.Checked, eEventSource.Code); + } + base.OnCommandChanged(); + } + + /// + /// Sets the Checked property of the item, raises appropriate events and provides the information about the source of the change. + /// + /// New value for Checked property + /// Source of the change. + public virtual void SetChecked(CheckState newValue, eEventSource source) + { + CheckBoxChangeEventArgs e = new CheckBoxChangeEventArgs(null, this, source); + InvokeCheckedChanging(e); + if (e.Cancel) + return; + + m_CheckState = newValue; + m_Checked = (newValue != CheckState.Unchecked); + if (this.Command != null) + this.Command.Checked = m_Checked; + this.OnCheckedChanged(source); + OnCheckStateChanged(EventArgs.Empty); + + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "CheckState"); + + if (this.Displayed) + this.Refresh(); + } + + /// + /// Raises CheckState changed event. + /// + /// Event arguments. + protected virtual void OnCheckStateChanged(EventArgs eventArgs) + { + if (CheckStateChanged != null) + CheckStateChanged(this, eventArgs); + } + + /// + /// Raises CheckedBindableChanged changed event. + /// + /// Event arguments. + protected virtual void OnCheckedBindableChanged(EventArgs eventArgs) + { + if (CheckedBindableChanged != null) + CheckedBindableChanged(this, eventArgs); + } + + /// + /// Called after Checked property has changed. + /// + protected virtual void OnCheckedChanged(eEventSource source) + { + CheckBoxItem previous = null; + if (m_CheckBoxStyle == eCheckBoxStyle.RadioButton && m_Checked && this.Parent != null) + { + BaseItem[] items = new BaseItem[this.Parent.SubItems.Count]; + this.Parent.SubItems.CopyTo(items, 0); + foreach (BaseItem item in items) + { + if (item == this) + continue; + CheckBoxItem b = item as CheckBoxItem; + if (b != null && b.Checked && b.CheckBoxStyle == eCheckBoxStyle.RadioButton) + { + b.Checked = false; + previous = b; + } + } + } + + InvokeCheckedChanged(new CheckBoxChangeEventArgs(previous, this, source)); + } + + /// + /// Raises the CheckedChanging event. + /// + protected virtual void InvokeCheckedChanging(CheckBoxChangeEventArgs e) + { + if (CheckedChanging != null) + CheckedChanging(this, e); + } + + /// + /// Raises the CheckedChanged event. + /// + protected virtual void InvokeCheckedChanged(CheckBoxChangeEventArgs e) + { + if (CheckedChanged != null) + CheckedChanged(this, e); + } + + /// + /// Gets or sets a value indicating whether the CheckBox will allow three check states rather than two. If the ThreeState property is set to true + /// CheckState property should be used instead of Checked property to set the extended state of the control. + /// + [Browsable(true), Category("Behavior"), DefaultValue(false), Description("Indicates whether the CheckBox will allow three check states rather than two.")] + public bool ThreeState + { + get { return m_ThreeState; } + set { m_ThreeState = value; } + } + + /// + /// Specifies the state of a control, such as a check box, that can be checked, unchecked, or set to an indeterminate state. + /// + [Browsable(true), Category("Behavior"), DefaultValue(CheckState.Unchecked), RefreshProperties(RefreshProperties.All), Description("Specifies the state of a control, such as a check box, that can be checked, unchecked, or set to an indeterminate state"), Bindable(true)] + public CheckState CheckState + { + get { return m_CheckState; } + set + { + if (value != m_CheckState) + SetChecked(value, eEventSource.Code); + } + } + + private Image _CheckBoxImageChecked = null; + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box is checked. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box is checked")] + public Image CheckBoxImageChecked + { + get { return _CheckBoxImageChecked; } + set + { + _CheckBoxImageChecked = value; + OnCheckBoxImageChanged(); + } + } + private Image _CheckBoxImageUnChecked = null; + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box is unchecked. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box is unchecked")] + public Image CheckBoxImageUnChecked + { + get { return _CheckBoxImageUnChecked; } + set + { + _CheckBoxImageUnChecked = value; + OnCheckBoxImageChanged(); + } + } + private Image _CheckBoxImageIndeterminate = null; + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box is in indeterminate state. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box is in indeterminate state")] + public Image CheckBoxImageIndeterminate + { + get { return _CheckBoxImageIndeterminate; } + set + { + _CheckBoxImageIndeterminate = value; + OnCheckBoxImageChanged(); + } + } + private void OnCheckBoxImageChanged() + { + NeedRecalcSize = true; + Refresh(); + } + #endregion + } + + /// + /// Delegate for OptionGroupChanging event. + /// + public delegate void CheckBoxChangeEventHandler(object sender, CheckBoxChangeEventArgs e); + + #region CheckBoxChangeEventArgs + /// + /// Represents event arguments for OptionGroupChanging event. + /// + public class CheckBoxChangeEventArgs : EventArgs + { + /// + /// Set to true to cancel the checking on NewChecked button. + /// + public bool Cancel = false; + /// + /// Check-box that will become checked if operation is not cancelled. + /// + public readonly CheckBoxItem NewChecked; + /// + /// Check-box that is currently checked and which will be unchecked if operation is not cancelled. This property will have only valid values for eCheckBoxStyle.RadioButton style CheckBoxItems. + /// + public readonly CheckBoxItem OldChecked; + /// + /// Indicates the action that has caused the event. + /// + public readonly eEventSource EventSource = eEventSource.Code; + + /// + /// Default constructor. + /// + public CheckBoxChangeEventArgs(CheckBoxItem oldchecked, CheckBoxItem newchecked, eEventSource eventSource) + { + NewChecked = newchecked; + OldChecked = oldchecked; + EventSource = eventSource; + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/CheckBoxItem/CheckBoxItemPainter.cs b/PROMS/DotNetBar Source Code/CheckBoxItem/CheckBoxItemPainter.cs new file mode 100644 index 00000000..9515523f --- /dev/null +++ b/PROMS/DotNetBar Source Code/CheckBoxItem/CheckBoxItemPainter.cs @@ -0,0 +1,17 @@ +using System; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + /// + /// Represents painter for CheckBoxItem. + /// + internal class CheckBoxItemPainter + { + /// + /// Paints CheckBoxItem. + /// + /// Provides arguments for the operation. + public virtual void Paint(CheckBoxItemRenderEventArgs e) { } + } +} diff --git a/PROMS/DotNetBar Source Code/CheckBoxItem/Office2007CheckBoxItemPainter.cs b/PROMS/DotNetBar Source Code/CheckBoxItem/Office2007CheckBoxItemPainter.cs new file mode 100644 index 00000000..af9611b3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CheckBoxItem/Office2007CheckBoxItemPainter.cs @@ -0,0 +1,391 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.Ribbon; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class Office2007CheckBoxItemPainter : CheckBoxItemPainter, IOffice2007Painter + { + #region Private Variables + + #endregion + + #region IOffice2007Painter + private Office2007ColorTable m_ColorTable = null; + + /// + /// Gets or sets color table used by renderer. + /// + public Office2007ColorTable ColorTable + { + get { return m_ColorTable; } + set { m_ColorTable = value; } + } + #endregion + + #region Internal Implementation + public override void Paint(CheckBoxItemRenderEventArgs e) + { + Graphics g = e.Graphics; + CheckBoxItem item = e.CheckBoxItem; + bool rtl = e.RightToLeft; + Font font = e.Font; + Office2007CheckBoxStateColorTable ct = this.GetCheckBoxStateColorTable(e); + bool standalone = e.ItemPaintArgs.ContainerControl is DevComponents.DotNetBar.Controls.CheckBoxX; + + Rectangle checkBoxPosition = Rectangle.Empty; + Rectangle textRect = Rectangle.Empty; + eTextFormat tf = eTextFormat.Default; + if (!(e.ItemPaintArgs != null && e.ItemPaintArgs.ContainerControl is DevComponents.DotNetBar.Controls.CheckBoxX || + (e.ItemPaintArgs != null && e.ItemPaintArgs.ContainerControl is ItemControl) || + (e.ItemPaintArgs != null && e.ItemPaintArgs.ContainerControl is Bar) || + (e.ItemPaintArgs != null && e.ItemPaintArgs.ContainerControl is MenuPanel))) + { + tf |= eTextFormat.NoPrefix; + } + + Size checkSignSize = item.GetCheckSignSize(); + + float baselineOffsetPixels = g.DpiY / 72f * (font.SizeInPoints / font.FontFamily.GetEmHeight(font.Style) * font.FontFamily.GetCellAscent(font.Style)) + .5f; + //float fontDescentPixels = g.DpiY / 72f * (font.SizeInPoints / font.FontFamily.GetEmHeight(font.Style) * font.FontFamily.GetCellDescent(font.Style)); + + if (item.CheckBoxPosition == eCheckBoxPosition.Left && !rtl || item.CheckBoxPosition == eCheckBoxPosition.Right && rtl) + { + checkBoxPosition = new Rectangle(item.DisplayRectangle.X + (standalone ? 0 : item.CheckTextSpacing / 2), + item.DisplayRectangle.Y + (item.DisplayRectangle.Height - checkSignSize.Height) / 2, + checkSignSize.Width, checkSignSize.Height); + textRect = new Rectangle(checkBoxPosition.Right + item.CheckTextSpacing / 2, item.DisplayRectangle.Y, + item.DisplayRectangle.Right - (checkBoxPosition.Right + item.CheckTextSpacing / 2), item.DisplayRectangle.Height); + + if (item.TextMarkupBody == null) + { + if (!(item.Text.Contains(Environment.NewLine) || item.IsTextMultiLine) && item.TextSize.Width <= textRect.Width) + textRect.Y = checkBoxPosition.Bottom - (int)baselineOffsetPixels - Dpi.Height(3); + else + tf |= eTextFormat.VerticalCenter | eTextFormat.WordBreak; + } + else + tf |= eTextFormat.VerticalCenter; + } + else if (item.CheckBoxPosition == eCheckBoxPosition.Right && !rtl || item.CheckBoxPosition == eCheckBoxPosition.Left && rtl) + { + checkBoxPosition = new Rectangle(item.DisplayRectangle.Right - (standalone ? 1 : item.CheckTextSpacing / 2) - checkSignSize.Width, + item.DisplayRectangle.Y + (item.DisplayRectangle.Height - checkSignSize.Height) / 2, + checkSignSize.Width, checkSignSize.Height); + textRect = new Rectangle(item.DisplayRectangle.X, item.DisplayRectangle.Y, + checkBoxPosition.X - (item.DisplayRectangle.X + item.CheckTextSpacing / 2), item.DisplayRectangle.Height); + + if (item.TextMarkupBody == null) + { + if (!item.Text.Contains(Environment.NewLine) && item.TextSize.Width <= textRect.Width) + textRect.Y = checkBoxPosition.Bottom - (int)baselineOffsetPixels - Dpi.Height(3); + else + tf |= eTextFormat.VerticalCenter | eTextFormat.WordBreak; + } + else + tf |= eTextFormat.VerticalCenter; + + tf |= eTextFormat.Right; + } + else if (item.CheckBoxPosition == eCheckBoxPosition.Top) + { + checkBoxPosition = new Rectangle(item.DisplayRectangle.X + (item.DisplayRectangle.Width - checkSignSize.Width) / 2, + item.DisplayRectangle.Y + item.VerticalPadding, checkSignSize.Width, checkSignSize.Height); + textRect = new Rectangle(item.DisplayRectangle.X, checkBoxPosition.Bottom, + item.DisplayRectangle.Width, item.DisplayRectangle.Bottom - checkBoxPosition.Bottom); + tf |= eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter; + } + else if (item.CheckBoxPosition == eCheckBoxPosition.Bottom) + { + checkBoxPosition = new Rectangle(item.DisplayRectangle.X + (item.DisplayRectangle.Width - checkSignSize.Width) / 2, + item.DisplayRectangle.Bottom - item.VerticalPadding - checkSignSize.Height - 1, checkSignSize.Width, checkSignSize.Height); + textRect = new Rectangle(item.DisplayRectangle.X, item.DisplayRectangle.Y, + item.DisplayRectangle.Width, checkBoxPosition.Y - (item.DisplayRectangle.Y + item.VerticalPadding)); + + tf |= eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter; + } + + if (item.CheckState == CheckState.Unchecked && item.CheckBoxImageUnChecked != null) + g.DrawImage(item.CheckBoxImageUnChecked, checkBoxPosition); + else if (item.CheckState == CheckState.Checked && item.CheckBoxImageChecked != null) + g.DrawImage(item.CheckBoxImageChecked, checkBoxPosition); + else if (item.CheckState == CheckState.Indeterminate && item.CheckBoxImageIndeterminate != null) + g.DrawImage(item.CheckBoxImageIndeterminate, checkBoxPosition); + else + { + if (item.CheckBoxStyle == eCheckBoxStyle.CheckBox) + { + PaintCheckBox(g, checkBoxPosition, ct, item.CheckState); + } + else + { + PaintRadioButton(g, checkBoxPosition, ct, item.Checked); + } + } + + Color textColor = ct.Text; + if (!item.TextColor.IsEmpty) textColor = item.TextColor; + if (item.Text != "" && !textRect.IsEmpty && !textColor.IsEmpty && item.Orientation != eOrientation.Vertical && item.TextVisible) + { + if (item.TextMarkupBody != null) + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, textColor, rtl); + d.HotKeyPrefixVisible = !((tf & eTextFormat.HidePrefix) == eTextFormat.HidePrefix); + if ((tf & eTextFormat.VerticalCenter) == eTextFormat.VerticalCenter) + { + textRect.Y = item.TopInternal + (item.Bounds.Height - item.TextMarkupBody.Bounds.Height) / 2; + textRect.Height = item.TextMarkupBody.Bounds.Height; + } + else if ((tf & eTextFormat.Bottom) == eTextFormat.Bottom) + { + textRect.Y += (item.Bounds.Height - item.TextMarkupBody.Bounds.Height) + 1; + textRect.Height = item.TextMarkupBody.Bounds.Height; + } + + item.TextMarkupBody.Bounds = textRect; + item.TextMarkupBody.Render(d); + } + else + { +#if FRAMEWORK20 + if (e.ItemPaintArgs != null && e.ItemPaintArgs.GlassEnabled && item.Parent is CaptionItemContainer && !(e.ItemPaintArgs.ContainerControl is QatToolbar)) + { + if (!e.ItemPaintArgs.CachedPaint) + Office2007RibbonControlPainter.PaintTextOnGlass(g, item.Text, font, textRect, TextDrawing.GetTextFormat(tf)); + } + else +#endif + TextDrawing.DrawString(g, item.Text, font, textColor, textRect, tf); + } + } + + if (item.Focused && item.DesignMode) + { + Rectangle r = item.DisplayRectangle; + r.Inflate(-1, -1); + DesignTime.DrawDesignTimeSelection(g, r, e.ColorScheme.ItemDesignTimeBorder); + } + } + + public void PaintRadioButton(Graphics g, Rectangle checkBoxPosition, Office2007CheckBoxStateColorTable ct, bool isChecked) + { + Rectangle r = checkBoxPosition; + r.Inflate(-1, -1); + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(r); + DisplayHelp.FillPath(g, path, ct.CheckBackground); + } + using (Pen pen = new Pen(ct.CheckBorder, 1)) + { + g.DrawEllipse(pen, checkBoxPosition); + } + // Draw inner border + checkBoxPosition.Inflate(-3, -3); + using (Pen pen = new Pen(ct.CheckInnerBorder, 1)) + { + g.DrawEllipse(pen, checkBoxPosition); + } + + if (!ct.CheckInnerBackground.IsEmpty) + { + if (ct.CheckInnerBackground.End.IsEmpty) + { + r = checkBoxPosition; + r.Inflate(-1, -1); + using (SolidBrush brush = new SolidBrush(ct.CheckInnerBackground.Start)) + g.FillEllipse(brush, r); + } + else + { + // Draw gradient + Region old = g.Clip; + g.SetClip(checkBoxPosition, System.Drawing.Drawing2D.CombineMode.Replace); + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(checkBoxPosition); + + using (PathGradientBrush brush = new PathGradientBrush(path)) + { + brush.CenterColor = ct.CheckInnerBackground.Start; + brush.SurroundColors = new Color[] { ct.CheckInnerBackground.End }; + brush.CenterPoint = new PointF(checkBoxPosition.X, checkBoxPosition.Y); + g.FillEllipse(brush, checkBoxPosition); + } + } + g.Clip = old; + } + } + + if (isChecked && !ct.CheckSign.IsEmpty) + { + r = checkBoxPosition; + //r.Inflate(-1, -1); + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(r); + DisplayHelp.FillPath(g, path, ct.CheckSign); + } + } + } + + public void PaintCheckBox(Graphics g, Rectangle checkBoxPosition, Office2007CheckBoxStateColorTable ct, CheckState checkState) + { + Rectangle r = checkBoxPosition; + r.Inflate(-1, -1); + if (checkBoxPosition.Width < 5 || checkBoxPosition.Height < 5) return; + + DisplayHelp.FillRectangle(g, r, ct.CheckBackground); + DisplayHelp.DrawRectangle(g, ct.CheckBorder, checkBoxPosition); + + // Inside rectangle + checkBoxPosition.Inflate(-2, -2); + + if (!ct.CheckInnerBackground.IsEmpty) + { + if (ct.CheckInnerBackground.End.IsEmpty) + { + r = checkBoxPosition; + r.Inflate(-1, -1); + DisplayHelp.FillRectangle(g, r, ct.CheckInnerBackground.Start); + } + else + { + // Draw gradient + Region old = g.Clip; + g.SetClip(checkBoxPosition, System.Drawing.Drawing2D.CombineMode.Intersect); + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddRectangle(checkBoxPosition); + + using (PathGradientBrush brush = new PathGradientBrush(path)) + { + brush.CenterColor = ct.CheckInnerBackground.Start; + brush.SurroundColors = new Color[] { ct.CheckInnerBackground.End }; + brush.CenterPoint = new PointF(checkBoxPosition.X, checkBoxPosition.Y); + g.FillRectangle(brush, checkBoxPosition); + } + } + g.Clip = old; + } + } + + DisplayHelp.DrawRectangle(g, ct.CheckInnerBorder, checkBoxPosition); + + if (checkState == CheckState.Indeterminate) + { + checkBoxPosition.Inflate(-2, -2); + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + DisplayHelp.FillRectangle(g, checkBoxPosition, ct.CheckSign); + g.SmoothingMode = sm; + } + else if (checkState == CheckState.Checked && !ct.CheckSign.IsEmpty) + { + using (GraphicsPath path = GetCheckSign(checkBoxPosition)) + DisplayHelp.FillPath(g, path, ct.CheckSign); + } + } + + private GraphicsPath GetCheckSign(Rectangle outterRect) + { + GraphicsPath path = new GraphicsPath(); + + Rectangle r = outterRect; + r.Inflate(-1, -1); + + path.AddLine(r.X, r.Y + r.Height * .75f, r.X + r.Width * .3f, r.Bottom); + path.AddLine(r.X + r.Width * .4f, r.Bottom, r.Right, r.Y + r.Height * .05f); + path.AddLine(r.Right - r.Width * .3f, r.Y, r.X + r.Width * .25f, r.Y + r.Height * .75f); + path.AddLine(r.X + r.Width * .1f, r.Y + r.Height * .5f, r.X, r.Y + r.Height * .55f); + path.CloseAllFigures(); + + return path; + } + protected virtual Office2007CheckBoxColorTable GetColorTable(CheckBoxItem item, System.Windows.Forms.Control container) + { + if (container == null) + return m_ColorTable.CheckBoxItem; + + Office2007ColorTable table = m_ColorTable; + + string key = Office2007ColorTable.GetContextualKey(typeof(Office2007CheckBoxColorTable), container.GetType()); + object st = null; + + if (container is Bar) + { + if (table.ContextualTables.TryGetValue(key + "+" + ((Bar)container).BarType.ToString(), out st)) + return (Office2007CheckBoxColorTable)st; + } + + if (table.ContextualTables.TryGetValue(key, out st)) + return (Office2007CheckBoxColorTable)st; + + return m_ColorTable.CheckBoxItem; + } + private Office2007CheckBoxStateColorTable GetCheckBoxStateColorTable(CheckBoxItemRenderEventArgs e) + { + CheckBoxItem item = e.CheckBoxItem; + if (m_ColorTable != null && BarFunctions.IsOffice2007Style(e.CheckBoxItem.EffectiveStyle)) + { + Office2007CheckBoxColorTable ct = GetColorTable(e.CheckBoxItem, e.ItemPaintArgs.ContainerControl); // m_ColorTable.CheckBoxItem; + if (!item.GetEnabled()) + return ct.Disabled; + else if (item.IsMouseDown) + return ct.Pressed; + else if (item.IsMouseOver) + return ct.MouseOver; + return ct.Default; + } + else + { + ColorScheme cs = e.ColorScheme; + // Create color table based on the ColorScheme object... + Office2007CheckBoxStateColorTable ct = new Office2007CheckBoxStateColorTable(); + if (!item.GetEnabled()) + { + ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + ct.CheckBorder = cs.ItemDisabledText; + ct.CheckInnerBorder = cs.ItemDisabledText; + ct.CheckInnerBackground = new LinearGradientColorTable(); + ct.CheckSign = new LinearGradientColorTable(cs.ItemDisabledText, Color.Empty); + ct.Text = cs.ItemDisabledText; + } + else if (item.IsMouseDown) + { + ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + ct.CheckBorder = cs.ItemPressedBorder; + ct.CheckInnerBorder = cs.ItemPressedBorder; + ct.CheckInnerBackground = new LinearGradientColorTable(cs.ItemPressedBackground, cs.ItemPressedBackground2); + ct.CheckSign = new LinearGradientColorTable(cs.ItemPressedText, Color.Empty); + ct.Text = cs.ItemPressedText; + } + else if (item.IsMouseOver) + { + ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + ct.CheckBorder = cs.ItemHotBorder; + ct.CheckInnerBorder = cs.ItemHotBorder; + ct.CheckInnerBackground = new LinearGradientColorTable(cs.ItemHotBackground, cs.ItemHotBackground2); + ct.CheckSign = new LinearGradientColorTable(cs.ItemHotText, Color.Empty); + ct.Text = cs.ItemHotText; + } + else + { + ct.CheckBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + ct.CheckBorder = cs.PanelBorder; + ct.CheckInnerBorder = ColorBlendFactory.SoftLight(cs.PanelBorder, Color.White); + ct.CheckInnerBackground = new LinearGradientColorTable(cs.MenuBackground, Color.Empty); + ct.CheckSign = new LinearGradientColorTable(cs.ItemText, Color.Empty); + ct.Text = cs.ItemText; + } + return ct; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/CircularProgressItem.cs b/PROMS/DotNetBar Source Code/CircularProgressItem.cs new file mode 100644 index 00000000..69636f0f --- /dev/null +++ b/PROMS/DotNetBar Source Code/CircularProgressItem.cs @@ -0,0 +1,1339 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Threading; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents circular progress indicator. + /// + [ToolboxItem(false), Designer("DevComponents.DotNetBar.Design.SimpleItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class CircularProgressItem : BaseItem + { + #region Events + + #endregion + + #region Constructor + /// + /// Creates new instance of circular progress indicator. + /// + public CircularProgressItem() : this("", "") { } + /// + /// Creates new instance of circular progress indicator and assigns the name to it. + /// + /// Item name. + public CircularProgressItem(string sItemName) : this(sItemName, "") { } + /// + /// Creates new instance of circular progress indicator and assigns the name and text to it. + /// + /// Item name. + /// item text. + public CircularProgressItem(string sItemName, string ItemText) + : base(sItemName, ItemText) + { + _SpokeAngles = GetSpokeAngles(_SpokeCount); + } + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + CircularProgressItem objCopy = new CircularProgressItem(m_Name); + this.CopyToItem(objCopy); + return objCopy; + } + + /// + /// Copies the ProgressBarItem specific properties to new instance of the item. + /// + /// New ProgressBarItem instance. + internal void InternalCopyToItem(ProgressBarItem copy) + { + CopyToItem(copy); + } + + /// + /// Copies the ProgressBarItem specific properties to new instance of the item. + /// + /// New ProgressBarItem instance. + protected override void CopyToItem(BaseItem copy) + { + CircularProgressItem objCopy = copy as CircularProgressItem; + base.CopyToItem(objCopy); + + + } + + private bool _IsDisposing = false; + protected override void Dispose(bool disposing) + { + _IsDisposing = true; + Stop(true); + base.Dispose(disposing); + _IsDisposing = false; + } + #endregion + + #region Implementation + public override void Paint(ItemPaintArgs e) + { + //e.Graphics.SmoothingMode = SmoothingMode.HighQuality; + //e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + + if (_ProgressBarType == eCircularProgressType.Line) + { + PaintLineProgressBar(e); + } + else if (_ProgressBarType == eCircularProgressType.Dot) + { + PaintDotProgressBar(e); + } + else if (_ProgressBarType == eCircularProgressType.Donut) + { + PaintDonutProgressBar(e); + } + else if (_ProgressBarType == eCircularProgressType.Spoke) + { + PaintSpokeProgressBar(e); + } + else if (_ProgressBarType == eCircularProgressType.Pie) + { + PaintPieProgressBar(e); + } + + PaintLabel(e); + + if (this.Focused && this.DesignMode) + { + Rectangle r = this.DisplayRectangle; + r.Inflate(-1, -1); + DesignTime.DrawDesignTimeSelection(e.Graphics, r, e.Colors.ItemDesignTimeBorder); + } + + this.DrawInsertMarker(e.Graphics); + } + + private void PaintLabel(ItemPaintArgs e) + { + if (!_TextVisible || string.IsNullOrEmpty(this.Text)) + return; + Font font = e.Font; + Graphics g = e.Graphics; + Color textColor = GetTextColor(e); + Rectangle textBounds = Rectangle.Empty; + Rectangle bounds = m_Rect; + Rectangle progressBounds = GetProgressBarBounds(); + eTextFormat format = eTextFormat.Default | eTextFormat.NoClipping; + + int textContentSpacing = Dpi.Width(TextContentSpacing); + if (_TextPosition == eTextPosition.Left) + { + textBounds = new Rectangle(bounds.X + _TextPadding.Left, bounds.Y + _TextPadding.Top, + m_Rect.Width - _TextPadding.Horizontal - textContentSpacing - progressBounds.Width, + m_Rect.Height - _TextPadding.Vertical); + format |= eTextFormat.VerticalCenter; + } + else if (_TextPosition == eTextPosition.Right) + { + textBounds = new Rectangle(bounds.X + _TextPadding.Left + textContentSpacing + progressBounds.Width, bounds.Y + _TextPadding.Top, + m_Rect.Width - _TextPadding.Horizontal - textContentSpacing - progressBounds.Width, + m_Rect.Height - _TextPadding.Vertical); + format |= eTextFormat.VerticalCenter; + } + else if (_TextPosition == eTextPosition.Top) + { + textBounds = new Rectangle(bounds.X + _TextPadding.Left, bounds.Y + _TextPadding.Top, + m_Rect.Width - _TextPadding.Horizontal, + m_Rect.Height - _TextPadding.Vertical - progressBounds.Height - textContentSpacing); + format |= eTextFormat.HorizontalCenter; + } + else if (_TextPosition == eTextPosition.Bottom) + { + textBounds = new Rectangle(bounds.X + _TextPadding.Left, bounds.Y + _TextPadding.Top + textContentSpacing + progressBounds.Height, + m_Rect.Width - _TextPadding.Horizontal, + m_Rect.Height - _TextPadding.Vertical - progressBounds.Height - textContentSpacing); + format |= eTextFormat.HorizontalCenter; + } + if (_TextWidth > 0) + { + textBounds.Width = _TextWidth; + format |= eTextFormat.WordBreak; + } + //g.FillRectangle(Brushes.WhiteSmoke, textBounds); + TextDrawing.DrawString(g, this.Text, font, textColor, textBounds, format); + } + + private Color GetTextColor(ItemPaintArgs e) + { + if (!_TextColor.IsEmpty) return _TextColor; + return LabelItem.GetTextColor(e, this.EffectiveStyle, this.GetEnabled(), _TextColor); + } + + private bool RenderesProgressText + { + get + { + return _ProgressTextVisible && (!_IsEndlessProgressBar || !string.IsNullOrEmpty(_ProgressText)); + } + } + private void PaintPieProgressBar(ItemPaintArgs e) + { + Graphics g = e.Graphics; + Rectangle bounds = GetProgressBarBounds(); + PointF centerPoint = new PointF(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2); + float penWidth = (float)Math.Max(1.5f, bounds.Height * .2); + bounds.Inflate(-1, -1); + bounds.Width--; + bounds.Height--; + + float borderWidth = 1f; + if (bounds.Height > 31) + borderWidth = bounds.Height * .05f; + + if (!_IsEndlessProgressBar) + { + int value = GetValue(); + Rectangle pieBounds = bounds; + pieBounds.Inflate(-(int)borderWidth, -(int)borderWidth); + + int sweepAngle = (int)(360 * ((double)value / Math.Max(1, (_Maximum - _Minimum)))); + using (SolidBrush brush = new SolidBrush(_ProgressColor)) + { + g.FillPie(brush, pieBounds, 270, sweepAngle); + } + } + else + { + Rectangle pieBounds = bounds; + pieBounds.Inflate(-(int)borderWidth, -(int)borderWidth); + + int startAngle = (int)(360 * _EndlessProgressValue / (double)_SpokeCount); + int sweepAngle = 90; + using (SolidBrush brush = new SolidBrush(_ProgressColor)) + { + g.FillPie(brush, pieBounds, startAngle, sweepAngle); + } + } + + Rectangle borderBounds = bounds; + borderBounds.Width--; + borderBounds.Height--; + + borderBounds.Offset(1, 1); + using (Pen pen = new Pen(_PieBorderDark, borderWidth)) + { + pen.Alignment = PenAlignment.Inset; + g.DrawEllipse(pen, borderBounds); + } + borderBounds.Offset(-1, -1); + //using (Pen pen = new Pen(_PieBorderLight, borderWidth)) + // g.DrawEllipse(pen, borderBounds); + + using (Pen pen = new Pen(_PieBorderLight, borderWidth + .5f)) + { + pen.Alignment = PenAlignment.Inset; + g.DrawEllipse(pen, borderBounds); + g.DrawEllipse(pen, borderBounds); + } + + if (RenderesProgressText) + { + bounds.Offset(1, 0); + PaintProgressText(g, bounds, (int)(bounds.Height * .4f), e.Font); + } + } + + private void PaintSpokeProgressBar(ItemPaintArgs e) + { + Graphics g = e.Graphics; + Rectangle bounds = GetProgressBarBounds(); + // Account for border and shade + bounds.Width -= 2; + bounds.Height -= 2; + + PointF centerPoint = new PointF(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2); + float penWidth = (float)Math.Max(1.5f, bounds.Height * .2); + //bounds.Inflate(-(int)(penWidth / 2), -(int)(penWidth / 2)); + GraphicsPath clipPath = new GraphicsPath(); + Rectangle clipPathEllipse = bounds; + clipPathEllipse.Inflate(-(int)((float)bounds.Height / 3f), -(int)((float)bounds.Height / 3f)); + clipPath.AddEllipse(clipPathEllipse); + Region oldClip = g.Clip; + g.SetClip(clipPath, CombineMode.Exclude); + + if (!_IsEndlessProgressBar) + { + int value = GetValue(); + + int sweepAngle = (int)(360 * ((double)value / Math.Max(1, (_Maximum - _Minimum)))); + using (SolidBrush brush = new SolidBrush(_ProgressColor)) + { + g.FillPie(brush, bounds, 270, sweepAngle); + } + } + else + { + int startAngle = (int)(360 * _EndlessProgressValue / (double)_SpokeCount); + int sweepAngle = 90; + using (SolidBrush brush = new SolidBrush(_ProgressColor)) + { + g.FillPie(brush, bounds, startAngle, sweepAngle); + } + } + + int radius = bounds.Width / 2; + + PointF shadeCenterPoint = centerPoint; + float shadeSpokeWidth = 1f; + float circleWidth = 1f; + float shadeCircleWidth = 1f; + //if (bounds.Height < 28) + //{ + // shadeSpokeWidth = 1f; + // circleWidth = 1f; + // shadeCircleWidth = 1f; + //} + radius--; + using (Pen pen = new Pen(_SpokeBorderDark, shadeSpokeWidth)) + { + pen.Alignment = PenAlignment.Right; + PointF p1 = GetCoordinate(centerPoint, radius, 315); p1.X++; + PointF p2 = GetCoordinate(shadeCenterPoint, radius, 135); p2.X++; + g.DrawLine(pen, p1, p2); g.DrawLine(pen, p1, p2); + p1 = GetCoordinate(centerPoint, radius, 270); p1.X++; + p2 = GetCoordinate(shadeCenterPoint, radius, 90); p2.X++; + g.DrawLine(pen, p1, p2); + p1 = GetCoordinate(centerPoint, radius, 225); p1.Y++; + p2 = GetCoordinate(shadeCenterPoint, radius, 45); p2.Y++; + g.DrawLine(pen, p1, p2); + p1 = GetCoordinate(centerPoint, radius, 180); p1.Y++; + p2 = GetCoordinate(shadeCenterPoint, radius, 0); p2.Y++; + g.DrawLine(pen, p1, p2); + } + + using (Pen pen = new Pen(_SpokeBorderDark, shadeCircleWidth)) + { + pen.Alignment = PenAlignment.Inset; + Rectangle shadeBounds = bounds; + shadeBounds.Offset(1, 1); + //shadeBounds.Width--; + //shadeBounds.Height--; + g.DrawEllipse(pen, shadeBounds); + } + + using (Pen pen = new Pen(_SpokeBorderLight, shadeSpokeWidth)) + { + g.DrawLine(pen, GetCoordinate(centerPoint, radius, 315), GetCoordinate(centerPoint, radius, 135)); + g.DrawLine(pen, GetCoordinate(centerPoint, radius, 270), GetCoordinate(centerPoint, radius, 90)); + g.DrawLine(pen, GetCoordinate(centerPoint, radius, 225), GetCoordinate(centerPoint, radius, 45)); + g.DrawLine(pen, GetCoordinate(centerPoint, radius, 180), GetCoordinate(centerPoint, radius, 0)); + } + + using (Pen pen = new Pen(_SpokeBorderLight, circleWidth)) + { + pen.Alignment = PenAlignment.Inset; + g.DrawEllipse(pen, bounds); + g.DrawEllipse(pen, bounds); + } + g.Clip = oldClip; + oldClip.Dispose(); + + float innerCircleWidth = 1f; + using (Pen pen = new Pen(Color.White, innerCircleWidth)) + { + pen.Alignment = PenAlignment.Inset; + g.DrawEllipse(pen, clipPathEllipse); + g.DrawEllipse(pen, clipPathEllipse); + } + + if (RenderesProgressText) + { + //bounds.Y--; + PaintProgressText(g, bounds, (int)(bounds.Height * .35f), e.Font); + } + } + + private int GetValue() + { + int value = Math.Min(_Maximum, Math.Max(_Minimum, _Value)); + if (this.DesignMode && value == _Minimum) value = (int)(_Maximum * .75d); + return value; + } + + private void PaintDonutProgressBar(ItemPaintArgs e) + { + Graphics g = e.Graphics; + RectangleF bounds = GetProgressBarBounds(); + PointF centerPoint = new PointF(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2); + float penWidth = (float)Math.Max(1.5f, bounds.Height * .2); + bounds.Inflate(-Math.Max(1, penWidth / 2), -Math.Max(1, penWidth / 2)); + bounds.Width--; + bounds.Height--; + if (!_IsEndlessProgressBar) + { + int value = GetValue(); + + int sweepAngle = (int)(360 * ((double)value / Math.Max(1, (_Maximum - _Minimum)))); + using (Pen pen = new Pen(_ProgressColor, penWidth)) + { + + g.DrawArc(pen, bounds, 270, sweepAngle); + } + } + else + { + int startAngle = (int)(360 * _EndlessProgressValue / (double)_SpokeCount); + int sweepAngle = 140; + using (Pen pen = new Pen(_ProgressColor, penWidth)) + { + pen.EndCap = LineCap.Round; + pen.StartCap = LineCap.Round; + g.DrawArc(pen, bounds, startAngle, sweepAngle); + } + } + + if (RenderesProgressText) + { + PaintProgressText(g, bounds, (int)(bounds.Height * .4f), e.Font); + } + } + + private void PaintDotProgressBar(ItemPaintArgs e) + { + Graphics g = e.Graphics; + Rectangle bounds = GetProgressBarBounds(); + PointF centerPoint = new PointF(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2); + + int outerRadius = 14; + int circleSize = 2; + + outerRadius = (int)Math.Round(bounds.Width * .40d); + circleSize = Math.Max(1, (int)Math.Round(outerRadius * .25d)); + + int value = GetValue(); + + if (!_IsEndlessProgressBar) + { + int spoke = (int)Math.Round(_SpokeCount * ((double)value / Math.Max(1, (_Maximum - _Minimum)))); + for (int i = 0; i < spoke; i++) + { + PointF endPoint = GetCoordinate(centerPoint, outerRadius, _SpokeAngles[i]); + RectangleF circleBounds = new RectangleF(endPoint, Size.Empty); + circleBounds.Inflate(circleSize, circleSize); + using (SolidBrush brush = new SolidBrush(ColorFromSpokeIndex(i))) + { + g.FillEllipse(brush, circleBounds); + } + } + } + else if (_IsRunning) // Endless Progress Bar + { + int position = _EndlessProgressValue; + for (int i = 0; i < _SpokeCount; i++) + { + position = position % _SpokeCount; + + PointF endPoint = GetCoordinate(centerPoint, outerRadius, _SpokeAngles[position]); + RectangleF circleBounds = new RectangleF(endPoint, Size.Empty); + circleBounds.Inflate(circleSize, circleSize); + using (SolidBrush brush = new SolidBrush(ColorFromSpokeIndex(i))) + { + g.FillEllipse(brush, circleBounds); + } + + position++; + + } + } + + if (RenderesProgressText) + { + PaintProgressText(g, bounds, (int)(bounds.Height * .35f), e.Font); + } + } + + private int _SpokeCount = 12; + private int _EndlessProgressValue = 0; + private void PaintLineProgressBar(ItemPaintArgs e) + { + //e.Graphics.DrawRectangle(Pens.Green, new Rectangle(0, 0, this.Width - 1, this.Height - 1)); + Graphics g = e.Graphics; + Rectangle bounds = GetProgressBarBounds(); + PointF centerPoint = new PointF(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2); + + int innerRadius = 6; + int outerRadius = 14; + int spokeSize = 2; + + outerRadius = (int)Math.Round(bounds.Width * .45d); + innerRadius = (int)Math.Round(outerRadius * .45d); + spokeSize = Math.Max(2, (int)Math.Round(outerRadius * .15d)); + + int value = GetValue(); + + if (!_IsEndlessProgressBar) + { + int spoke = (int)Math.Round(_SpokeCount * ((double)value / Math.Max(1, (_Maximum - _Minimum)))); + for (int i = 0; i < spoke; i++) + { + PointF startPoint = GetCoordinate(centerPoint, innerRadius, _SpokeAngles[i]); + PointF endPoint = GetCoordinate(centerPoint, outerRadius, _SpokeAngles[i]); + using (Pen pen = new Pen(ColorFromSpokeIndex(i), spokeSize)) + { + pen.EndCap = System.Drawing.Drawing2D.LineCap.Round; + pen.StartCap = System.Drawing.Drawing2D.LineCap.Round; + g.DrawLine(pen, startPoint, endPoint); + } + } + } + else if (_IsRunning) // Endless Progress Bar + { + int position = _EndlessProgressValue; + for (int i = 0; i < _SpokeCount; i++) + { + position = position % _SpokeCount; + + PointF startPoint = GetCoordinate(centerPoint, innerRadius, _SpokeAngles[position]); + PointF endPoint = GetCoordinate(centerPoint, outerRadius, _SpokeAngles[position]); + using (Pen pen = new Pen(ColorFromSpokeIndex(i), spokeSize)) + { + pen.EndCap = System.Drawing.Drawing2D.LineCap.Round; + pen.StartCap = System.Drawing.Drawing2D.LineCap.Round; + g.DrawLine(pen, startPoint, endPoint); + } + + position++; + + } + } + + if (RenderesProgressText) + { + PaintProgressText(g, bounds, innerRadius, e.Font); + } + + } + + private string GetProgressValueText() + { + try + { + if (!string.IsNullOrEmpty(_ProgressText)) return _ProgressText; + return string.Format(_ProgressTextFormat, _Value); + } + catch + { + return "Format Error"; + } + } + private void PaintProgressText(Graphics g, RectangleF bounds, int innerRadius, Font baseFont) + { + //StringFormat format = (StringFormat)StringFormat.GenericDefault.Clone(); + //format.Alignment = StringAlignment.Center; + //format.LineAlignment = StringAlignment.Center; + //format.FormatFlags = StringFormatFlags.NoWrap; + //format.Trimming = StringTrimming.None; + eTextFormat format = eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter | eTextFormat.NoPadding | eTextFormat.SingleLine | eTextFormat.NoClipping; + float fontSize = Math.Max(1f, innerRadius / 1.8f); + Color textColor = _ProgressTextColor.IsEmpty ? _ProgressColor : _ProgressTextColor; + + using (Font font = new Font(baseFont.FontFamily, fontSize, FontStyle.Regular)) + { + TextDrawing.DrawString(g, GetProgressValueText(), font, textColor, Rectangle.Round(bounds), format); + //using (SolidBrush brush = new SolidBrush(textColor)) + // g.DrawString(string.Format("{0}%", _Value), font, brush, bounds, format); + } + } + private Color ColorFromSpokeIndex(int spokeIndex, int spokeCount) + { + return Color.FromArgb((int)(210 * (double)spokeIndex / spokeCount) + 45, _ProgressColor); + } + private Color ColorFromSpokeIndex(int spokeIndex) + { + return ColorFromSpokeIndex(spokeIndex, _SpokeCount); + } + + private PointF GetCoordinate(PointF centerPoint, int radius, double angle) + { + double dblAngle = Math.PI * angle / 180; + + return new PointF(centerPoint.X + radius * (float)Math.Cos(dblAngle), + centerPoint.Y + radius * (float)Math.Sin(dblAngle)); + } + + internal static readonly int TextContentSpacing = 3; + private Size _TextSize = Size.Empty; + public override void RecalcSize() + { + int diameter = _Diameter; + if (!(this.ContainerControl is CircularProgress)) + diameter = Dpi.Width(_Diameter); + Rectangle r = new Rectangle(m_Rect.X, m_Rect.Y, diameter, diameter); + if (_TextVisible && !string.IsNullOrEmpty(this.Text)) + { + Control parent = this.ContainerControl as Control; + if (parent != null) + { + Font font = parent.Font; + using (Graphics g = parent.CreateGraphics()) + { + Size textSize = ButtonItemLayout.MeasureItemText(this, g, _TextWidth, font, (_TextWidth > 0 ? eTextFormat.WordBreak : eTextFormat.SingleLine), parent.RightToLeft == RightToLeft.Yes); + _TextSize = textSize; + textSize.Width += _TextPadding.Horizontal; + textSize.Height += _TextPadding.Vertical; + int textContentSpacing = Dpi.Width(TextContentSpacing); + if (_TextPosition == eTextPosition.Left || _TextPosition == eTextPosition.Right) + { + textSize.Width += textContentSpacing; + r.Width += textSize.Width; + r.Height = Math.Max(r.Height, textSize.Height); + } + else + { + textSize.Height += textContentSpacing; + r.Height += textSize.Height; + r.Width = Math.Max(r.Width, textSize.Width); + } + + } + } + } + + m_Rect = r; + base.RecalcSize(); + } + + private Rectangle _ProgressBarBounds = Rectangle.Empty; + private Rectangle GetProgressBarBounds() + { + int diameter = _Diameter; + if (!(this.ContainerControl is CircularProgress)) + diameter = Dpi.Width(_Diameter); + if (string.IsNullOrEmpty(Text) || !_TextVisible) + { + return new Rectangle(m_Rect.X + (m_Rect.Width - diameter) / 2, m_Rect.Y + (m_Rect.Height - diameter) / 2, diameter, diameter); + } + + if (_TextPosition == eTextPosition.Top) + { + return new Rectangle(m_Rect.X + (m_Rect.Width - diameter) / 2, m_Rect.Y + (m_Rect.Height - diameter), diameter, diameter); + } + else if (_TextPosition == eTextPosition.Right) + { + return new Rectangle(m_Rect.X, m_Rect.Y + (m_Rect.Height - diameter) / 2, diameter, diameter); + } + else if (_TextPosition == eTextPosition.Left) + { + return new Rectangle(m_Rect.Right - diameter, + m_Rect.Y + (m_Rect.Height - diameter) / 2, + diameter, diameter); + } + else if (_TextPosition == eTextPosition.Bottom) + { + return new Rectangle(m_Rect.X + (m_Rect.Width - diameter) / 2, m_Rect.Y, diameter, diameter); + } + return new Rectangle(m_Rect.X, m_Rect.Y, diameter, diameter); + } + + private double[] _SpokeAngles = null; + private double[] GetSpokeAngles(int numberOfSpokes) + { + double[] angles = new double[numberOfSpokes]; + double angleStep = 360d / numberOfSpokes; + + for (int i = 0; i < numberOfSpokes; i++) + angles[i] = (i == 0 ? 270 + angleStep : angles[i - 1] + angleStep); + + return angles; + } + + private eCircularProgressType _ProgressBarType = eCircularProgressType.Line; + /// + /// Gets or sets the circular progress bar type. + /// + [DefaultValue(eCircularProgressType.Line), Category("Appearance"), Description("Indicates circular progress bar type.")] + public eCircularProgressType ProgressBarType + { + get { return _ProgressBarType; } + set + { + if (value != _ProgressBarType) + { + eCircularProgressType oldValue = _ProgressBarType; + _ProgressBarType = value; + OnProgressBarTypeChanged(oldValue, value); + } + } + } + + private void OnProgressBarTypeChanged(eCircularProgressType oldValue, eCircularProgressType newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ProgressBarType")); + this.Refresh(); + } + + private int _Maximum = 100; + /// + /// Gets or sets the maximum value of the progress bar. + /// + [Description("Indicates maximum value of the progress bar."), Category("Behavior"), DefaultValue(100)] + public int Maximum + { + get { return _Maximum; } + set + { + if (value != _Maximum) + { + int oldValue = _Maximum; + _Maximum = value; + OnMaximumChanged(oldValue, value); + } + } + } + private void OnMaximumChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Maximum")); + CoerceValue(); + } + + private int _Minimum = 0; + /// + /// Gets or sets the minimum value of the progress bar. + /// + [Description("Indicates minimum value of the progress bar."), Category("Behavior"), DefaultValue(0)] + public int Minimum + { + get { return _Minimum; } + set + { + if (value != _Minimum) + { + int oldValue = _Minimum; + _Minimum = value; + OnMinimumChanged(oldValue, value); + } + } + } + private void OnMinimumChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Minimum")); + CoerceValue(); + } + + private void CoerceValue() + { + int newValue = _Value; + if (_Value < _Minimum) + newValue = _Minimum; + else if (_Value > _Maximum) + newValue = _Maximum; + Value = newValue; + } + + private Color _ProgressTextColor = Color.Empty; + /// + /// Gets or sets the color of the progress percentage text. + /// + [Category("Appearance"), Description("Indicates color of progress percentage text")] + public Color ProgressTextColor + { + get { return _ProgressTextColor; } + set { _ProgressTextColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeProgressTextColor() + { + return !_ProgressTextColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetProgressTextColor() + { + this.ProgressTextColor = Color.Empty; + } + + private bool _ProgressTextVisible = false; + /// + /// Gets or sets whether text that displays the progress bar completion percentage text is visible. Default value is false. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether text that displays the progress bar completion percentage text is visible")] + public bool ProgressTextVisible + { + get { return _ProgressTextVisible; } + set + { + if (value != _ProgressTextVisible) + { + bool oldValue = _ProgressTextVisible; + _ProgressTextVisible = value; + OnProgressTextVisibleChanged(oldValue, value); + } + } + } + + private void OnProgressTextVisibleChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ProgressTextVisible")); + this.Refresh(); + } + + private string _ProgressText = ""; + /// + /// Gets or sets the text displayed on top of the circular progress bar. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates text displayed on top of the circular progress bar.")] + public string ProgressText + { + get { return _ProgressText; } + set + { + if (value != _ProgressText) + { + string oldValue = _ProgressText; + _ProgressText = value; + OnProgressTextChanged(oldValue, value); + } + } + } + + private void OnProgressTextChanged(string oldValue, string newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("ProgressText")); + Refresh(); + } + + private int _Value; + /// + /// Gets or sets the current value of the progress bar. + /// + [Description("Indicates current value of the progress bar."), Category("Behavior"), DefaultValue(0)] + public int Value + { + get { return _Value; } + set + { + value = Math.Min(_Maximum, Math.Max(value, _Minimum)); + + if (value != _Value) + { + int oldValue = _Value; + _Value = value; + OnValueChanged(oldValue, value); + } + } + } + + private void OnValueChanged(int oldValue, int newValue) + { + if (!_IsEndlessProgressBar) + this.Refresh(); + OnValueChanged(EventArgs.Empty); + OnPropertyChanged(new PropertyChangedEventArgs("Value")); + } + + /// + /// Occurs when Value property has changed. + /// + public event EventHandler ValueChanged; + /// + /// Raises ValueChanged event. + /// + /// Provides event arguments. + protected virtual void OnValueChanged(EventArgs e) + { + EventHandler handler = ValueChanged; + if (handler != null) + handler(this, e); + } + + /// + /// Called when property on CircularProgressBar changes. + /// + /// Property Change Arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + } + + private void MoveEndlessProgressBar() + { + if (!this.IsRunning || this.IsDisposed || _IsDisposing) return; + + if (this.InvokeRequired) + { + this.BeginInvoke(new MethodInvoker(delegate() + { + MoveEndlessProgressBar(); + })); + return; + } + + _EndlessProgressValue = ++_EndlessProgressValue % _SpokeCount; + this.Refresh(); + Control container = this.ContainerControl as Control; + if (container != null) + container.Update(); + } + + private bool _IsEndlessProgressBar = false; + private BackgroundWorker _LoopWorker = null; + /// + /// Starts the progress bar loop for endless type progress bar. Progress bar will continue to run until Stop() method is called. + /// + public void Start() + { + if (_IsRunning) return; + + _IsEndlessProgressBar = true; + _IsRunning = true; + _LoopWorker = new BackgroundWorker(); + _LoopWorker.WorkerSupportsCancellation = true; + _LoopWorker.DoWork += LoopWorkerDoWork; + _LoopWorker.RunWorkerAsync(); + } + + void LoopWorkerDoWork(object sender, DoWorkEventArgs e) + { + BackgroundWorker worker = (BackgroundWorker)sender; + while (!worker.CancellationPending) + { + MoveEndlessProgressBar(); + try + { + using ( + System.Threading.ManualResetEvent wait = + new System.Threading.ManualResetEvent(false)) + wait.WaitOne(_AnimationSpeed); + //Thread.Sleep(_AnimationSpeed); + } + catch + { + e.Cancel = true; + } + } + e.Cancel = true; + } + + /// + /// Stops the progress bar loop for endless type progress bar. + /// + public void Stop() + { + Stop(false); + } + public void Stop(bool disposing) + { + if (!_IsRunning) return; + + _IsEndlessProgressBar = false; + + _IsRunning = false; + BackgroundWorker worker = _LoopWorker; + _LoopWorker = null; + + worker.CancelAsync(); + while (worker.IsBusy) + Application.DoEvents(); + worker.DoWork -= LoopWorkerDoWork; + worker.Dispose(); + if (!disposing) + this.Refresh(); + } + + private bool _IsRunning = false; + /// + /// Gets or sets whether endless type progress bar is running. + /// + [Browsable(false), DefaultValue(false)] + public bool IsRunning + { + get { return _IsRunning; } + set + { + if (_IsRunning != value) + { + if (value) + Start(); + else + Stop(); + } + } + } + + private static readonly Color DefaultProgressColor = Color.DarkSlateGray;//Color.FromArgb(143, 223, 95); + private Color _ProgressColor = DefaultProgressColor; + /// + /// Gets or sets the color of the color of progress indicator. + /// + [Category("Columns"), Description("Indicates color of progress indicator.")] + public Color ProgressColor + { + get { return _ProgressColor; } + set { _ProgressColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeProgressColor() + { + return _ProgressColor != DefaultProgressColor; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetProgressColor() + { + this.ProgressColor = DefaultProgressColor; + } + + private int _Diameter = 24; + /// + /// Gets or sets circular progress indicator diameter in pixels. + /// + [DefaultValue(24), Category("Appearance"), Description("Indicates circular progress indicator diameter in pixels.")] + public int Diameter + { + get { return _Diameter; } + set + { + if (value != _Diameter) + { + int oldValue = _Diameter; + _Diameter = value; + OnDiameterChanged(oldValue, value); + } + } + } + private void OnDiameterChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Diameter")); + NeedRecalcSize = true; + this.Refresh(); + } + + private eTextPosition _TextPosition = eTextPosition.Left; + /// + /// Gets or sets the text position in relation to the circular progress indicator. + /// + [DefaultValue(eTextPosition.Left), Category("Appearance"), Description("Indicatesd text position in relation to the circular progress indicator.")] + public eTextPosition TextPosition + { + get { return _TextPosition; } + set + { + if (value != _TextPosition) + { + eTextPosition oldValue = _TextPosition; + _TextPosition = value; + OnTextPositionChanged(oldValue, value); + } + } + } + private void OnTextPositionChanged(eTextPosition oldValue, eTextPosition newValue) + { + NeedRecalcSize = true; + this.Refresh(); + OnPropertyChanged(new PropertyChangedEventArgs("TextPosition")); + } + + private bool _TextVisible = true; + /// + /// Gets or sets whether text/label displayed next to the item is visible. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether caption/label set using Text property is visible.")] + public bool TextVisible + { + get { return _TextVisible; } + set + { + if (value != _TextVisible) + { + bool oldValue = _TextVisible; + _TextVisible = value; + OnTextVisibleChanged(oldValue, value); + } + } + } + + private void OnTextVisibleChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("TextVisible")); + NeedRecalcSize = true; + this.Refresh(); + } + + private int _TextWidth = 0; + /// + /// Gets or sets the suggested text-width. If you want to make sure that text you set wraps over multiple lines you can set suggested text-width so word break is performed. + /// + [DefaultValue(0), Category("Appearance"), Description("Indicates suggested text-width. If you want to make sure that text you set wraps over multiple lines you can set suggested text-width so word break is performed.")] + public int TextWidth + { + get { return _TextWidth; } + set + { + if (value != _TextWidth) + { + int oldValue = _TextWidth; + _TextWidth = value; + OnTextWidthChanged(oldValue, value); + } + } + } + private void OnTextWidthChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("TextWidth")); + NeedRecalcSize = true; + Refresh(); + } + + private Padding _TextPadding = new Padding(0, 0, 0, 0); + /// + /// Gets or sets text padding. + /// + [Browsable(true), Category("Appearance"), Description("Gets or sets text padding."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public Padding TextPadding + { + get { return _TextPadding; } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextPadding() + { + return _TextPadding.Bottom != 0 || _TextPadding.Top != 0 || _TextPadding.Left != 0 || _TextPadding.Right != 0; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextPadding() + { + _TextPadding = new Padding(0, 0, 0, 0); + } + private void TextPaddingPropertyChanged(object sender, PropertyChangedEventArgs e) + { + NeedRecalcSize = true; + this.Refresh(); + } + + private Color _TextColor = Color.Empty; + /// + /// Gets or sets the color of the text label. + /// + [Category("Columns"), Description("Indicates color of text label.")] + public Color TextColor + { + get { return _TextColor; } + set { _TextColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return !_TextColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + this.TextColor = Color.Empty; + } + + private static readonly Color DefaultPieBorderDarkColor = Color.FromArgb(50, Color.Black); + private Color _PieBorderDark = DefaultPieBorderDarkColor; + /// + /// Gets or sets the color of the pie progress bar dark border. + /// + [Category("Pie"), Description("Indicates color of pie progress bar dark border.")] + public Color PieBorderDark + { + get { return _PieBorderDark; } + set { _PieBorderDark = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePieBorderDark() + { + return _PieBorderDark != DefaultPieBorderDarkColor; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetPieBorderDark() + { + this.PieBorderDark = DefaultPieBorderDarkColor; + } + + private static readonly Color DefaultPieBorderLightColor = Color.FromArgb(255, Color.White); + private Color _PieBorderLight = DefaultPieBorderLightColor; + /// + /// Gets or sets the color of the pie progress bar light border. + /// + [Category("Pie"), Description("Indicates color of pie progress bar light border. ")] + public Color PieBorderLight + { + get { return _PieBorderLight; } + set { _PieBorderLight = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePieBorderLight() + { + return _PieBorderLight != DefaultPieBorderLightColor; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetPieBorderLight() + { + this.PieBorderLight = DefaultPieBorderLightColor; + } + + private static readonly Color DefaultSpokeBorderDarkColor = Color.FromArgb(48, Color.Black); + private Color _SpokeBorderDark = DefaultSpokeBorderDarkColor; + /// + /// Gets or sets the color of the spoke progress bar dark border. + /// + [Category("Spoke"), Description("Indicates color of spoke progress bar dark border.")] + public Color SpokeBorderDark + { + get { return _SpokeBorderDark; } + set { _SpokeBorderDark = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSpokeBorderDark() + { + return _SpokeBorderDark != DefaultSpokeBorderDarkColor; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSpokeBorderDark() + { + this.SpokeBorderDark = DefaultSpokeBorderDarkColor; + } + + private static readonly Color DefaultSpokeBorderLightColor = Color.FromArgb(255, Color.White); + private Color _SpokeBorderLight = DefaultSpokeBorderLightColor; + /// + /// Gets or sets the color of the spoke progress bar light border. + /// + [Category("Spoke"), Description("Indicates color of spoke progress bar light border..")] + public Color SpokeBorderLight + { + get { return _SpokeBorderLight; } + set { _SpokeBorderLight = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSpokeBorderLight() + { + return _SpokeBorderLight != DefaultSpokeBorderLightColor; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSpokeBorderLight() + { + this.SpokeBorderLight = DefaultSpokeBorderLightColor; + } + + private string _ProgressTextFormat = "{0}%"; + /// + /// Gets or sets format string for progress value. + /// + [DefaultValue("{0}%"), Category("Appearance"), Description("Indicates format string for progress value.")] + public string ProgressTextFormat + { + get { return _ProgressTextFormat; } + set + { + if (value != _ProgressTextFormat) + { + string oldValue = _ProgressTextFormat; + _ProgressTextFormat = value; + OnProgressTextFormatChanged(oldValue, value); + } + } + } + /// + /// Called when ProgressTextFormat property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnProgressTextFormatChanged(string oldValue, string newValue) + { + this.Refresh(); + OnPropertyChanged(new PropertyChangedEventArgs("ProgressTextFormat")); + } + + private int _AnimationSpeed = 100; + /// + /// Gets or sets the animation speed for endless running progress. Lower number means faster running. + /// + [DefaultValue(100), Description("Indicates the animation speed for endless running progress. Lower number means faster running."), Category("Behavior")] + public int AnimationSpeed + { + get { return _AnimationSpeed; } + set + { + if (value < 1) + value = 1; + _AnimationSpeed = value; + } + } + #endregion + } + + /// + /// Defines available circular progress bar types. + /// + public enum eCircularProgressType + { + /// + /// Line spokes progress bar. + /// + Line, + /// + /// Dot type/FireFox progress bar. + /// + Dot, + /// + /// Donut type progress bar. + /// + Donut, + /// + /// Spoke type progress bar. + /// + Spoke, + /// + /// Pie type progress bar. + /// + Pie + } +} diff --git a/PROMS/DotNetBar Source Code/ColorFunctions.cs b/PROMS/DotNetBar Source Code/ColorFunctions.cs new file mode 100644 index 00000000..d1ab3f8a --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorFunctions.cs @@ -0,0 +1,441 @@ +namespace DevComponents.DotNetBar +{ + using System; + using System.Drawing; + + /// + /// Summary description for ColorFunctions. + /// + public class ColorFunctions + { + 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 Bitmap m_PushedBrushBmp = null; + + internal static bool ColorsLoaded = false; + + public static void LoadColors() + { + RefreshColors(); + if (!ColorsLoaded) + Microsoft.Win32.SystemEvents.UserPreferenceChanged += new Microsoft.Win32.UserPreferenceChangedEventHandler(ColorFunctions.PreferenceChanged); + ColorsLoaded = true; + } + + private static void PreferenceChanged(object sender, Microsoft.Win32.UserPreferenceChangedEventArgs e) + { + RefreshColors(); + NativeFunctions.RefreshSettings(); + BarFunctions.RefreshScreens(); + } + + private static void RefreshColors() + { + if (NativeFunctions.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 (NativeFunctions.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 static Color GetShade(Color color, int shadePercent) + { + HLSColor hls = RGBToHSL(color); + if (hls.Lightness == 0) + return HLSToRGB(hls.Hue, shadePercent / 100, hls.Saturation); + else + return HLSToRGB(hls.Hue, Math.Max(0, (hls.Lightness - shadePercent / 100)), hls.Saturation); + } + + 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); + delta = Max - Min; + 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.} + + double delr = (((Max - rR) / 6) + (delta / 2)) / delta; + double delg = (((Max - rG) / 6) + (delta / 2)) / delta; + double delb = (((Max - rB) / 6) + (delta / 2)) / delta; + + if (rR == Max) + ret.Hue = delb - delg; //{Resulting color is between yellow and magenta} + else if (rG == Max) + ret.Hue = (1d / 3d) + delr - delb; // {Resulting color is between cyan and yellow} + else if (rB == Max) + ret.Hue = (2d / 3d) + delg - delr;; // {Resulting color is between magenta and cyan} + + if (ret.Hue < 0) ret.Hue += 1; + if (ret.Hue > 1) ret.Hue -= 1; + } + return ret; + } + + public static HLSColor RGBToHSL(Color color) + { + return RGBToHSL(color.R, color.G, color.B); + } + + 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 Color HLSToRGB(double Hue, double Lightness, double Saturation) + { + if (Lightness < 0) Lightness = 0; else if (Lightness > 1) Lightness = 1; + if (Saturation < 0) Saturation = 0; else if (Saturation > 1) Saturation = 1; + + int r, g, b; + double var1, var2; + if (Saturation == 0) + { + r = (int)(Lightness * 255); + g = (int)(Lightness * 255); + b = (int)(Lightness * 255); + } + else + { + if (Lightness < 0.5) + { + var2 = Lightness * (1 + Saturation); + } + else + { + var2 = (Lightness + Saturation) - (Saturation * Lightness); + } + + var1 = 2 * Lightness - var2; + r = (int)(255 * hue_2_rgb(var1, var2, Hue + (1d / 3d))); + g = (int)(255 * hue_2_rgb(var1, var2, Hue)); + b = (int)(255 * hue_2_rgb(var1, var2, Hue - (1d / 3d))); + } + + return Color.FromArgb(r, g, b); + } + + private static double hue_2_rgb(double v1, double v2,double vh) + { + if (vh < 0) + { + vh += 1; + } + + if (vh > 1) + { + vh -= 1; + } + + if ((6 * vh) < 1) + { + return (v1 + (v2 - v1) * 6 * vh); + }; + + if ((2 * vh) < 1) + { + return (v2); + }; + + if ((3 * vh) < 2) + { + return (v1 + (v2 - v1) * ((2d / 3d - vh) * 6)); + }; + + return (v1); + } + + public static Color 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.Brush GetPushedBrush(BaseItem item) + { + if (item.Parent is GenericItemContainer) + { + if (!((GenericItemContainer)item.Parent).m_BackgroundColor.IsEmpty) + { + return new SolidBrush(((GenericItemContainer)item.Parent).m_BackgroundColor); + } + } + else if (item.Parent is SideBarPanelItem) + { + if (((SideBarPanelItem)item.Parent).BackgroundStyle.ShouldSerializeBackColor1()) + { + return new SolidBrush(((SideBarPanelItem)item.Parent).BackgroundStyle.BackColor1.Color); + } + else if (((SideBarPanelItem)item.Parent).BackgroundStyle.ShouldSerializeBackColor1()) + { + return new SolidBrush(((SideBarPanelItem)item.Parent).BackgroundStyle.BackColor1.Color); + } + } + + return ColorFunctions.GetPushedBrush(); + } + 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 IsEqual(Color color1, Color color2) + { + return color1.A == color2.A && color1.R == color2.R && color1.G == color2.G && color1.B == color2.B; + } + } +} diff --git a/PROMS/DotNetBar Source Code/ColorPicker.cs b/PROMS/DotNetBar Source Code/ColorPicker.cs new file mode 100644 index 00000000..0be40a33 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPicker.cs @@ -0,0 +1,659 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Reflection; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.UI +{ + /// + /// Provides popup color picker. + /// + [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 IWindowsFormsEditorService m_EditorService=null; + + /// + /// Required designer variable. + /// + 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; + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + #endregion + + #region Component Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + 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 + + /// + /// Gets or sets the reference to the IWindowsFormsEditorService interface used for Windows Forms design time support. + /// + internal IWindowsFormsEditorService EditorService + { + get {return m_EditorService;} + set {m_EditorService=value;} + } + + /// + /// Gets or sets the ColorScheme object for Scheme colors. + /// + [Browsable(false),DefaultValue(null)] + public object ColorScheme + { + get {return m_ColorScheme;} + set + { + m_ColorScheme=value; + InitColorSchemeColors(); + } + } + + /// + /// Gets or sets currently selected color. + /// + public Color SelectedColor + { + get {return m_SelectedColor;} + set + { + m_SelectedColor=value; + OnSelectedColorChanged(); + } + } + + /// + /// Gets the selected color color scheme name if color scheme color is selected otherwise it returns an empty string. + /// + public string SelectedColorSchemeName + { + get {return m_SelectedColorSchemeName;} + set {m_SelectedColorSchemeName=value;} + } + + /// + /// Returns true if color selection was cancelled. + /// + 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; + + Color textColor=SystemColors.ControlText; + if((e.State & DrawItemState.Selected)!=0) + { + textColor=SystemColors.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; + DevComponents.DotNetBar.TextDrawing.DrawString(e.Graphics,colorName,list.Font,textColor,r,DevComponents.DotNetBar.eTextFormat.Default); + } + #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(); + } + else + { + 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 && m_SelectedColorSchemeName!="") + transparencyTrack.Enabled=false; + else + transparencyTrack.Enabled=true; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ColorPicker.resx b/PROMS/DotNetBar Source Code/ColorPicker.resx new file mode 100644 index 00000000..ddae5a77 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPicker.resx @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + True + + + True + + + Private + + + Private + + + 8, 8 + + + True + + + False + + + True + + + Private + + + Private + + + 8, 8 + + + Private + + + Private + + + True + + + True + + + False + + + True + + + Private + + + Private + + + 8, 8 + + + Private + + + True + + + Private + + + True + + + False + + + True + + + Private + + + Private + + + 8, 8 + + + True + + + Private + + + Private + + + True + + + False + + + True + + + Private + + + Private + + + 8, 8 + + + True + + + False + + + Private + + + 8, 8 + + + True + + + Private + + + True + + + Private + + + Private + + + True + + + Private + + + Private + + + True + + + False + + + Private + + + 8, 8 + + + True + + + Private + + + True + + + Private + + + Private + + + True + + + Private + + + Private + + + False + + + True + + + False + + + True + + + 80 + + + (Default) + + + False + + + Private + + + 8, 8 + + + ColorPicker + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/ColorPickers/ColorCombControl.cs b/PROMS/DotNetBar Source Code/ColorPickers/ColorCombControl.cs new file mode 100644 index 00000000..0fbef30c --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPickers/ColorCombControl.cs @@ -0,0 +1,427 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.ColorPickers +{ + /// + /// Represents the color comb control that allows color choice from pre-defined color comb palette. + /// + [ToolboxItem(true), DefaultEvent("SelectedColorChanged"), DefaultProperty("SelectedColor"), ToolboxBitmap(typeof(ColorCombControl), "ColorPickerItem.ColorCombControl.ico")] + public class ColorCombControl : System.Windows.Forms.Control + { + #region Events + /// + /// Occurs when SelectedColor has changed. + /// + public event EventHandler SelectedColorChanged; + /// + /// Raises SelectedColorChanged event. + /// + /// Provides event arguments. + protected virtual void OnSelectedColorChanged(EventArgs e) + { + EventHandler handler = SelectedColorChanged; + if (handler != null) + handler(this, e); + } + #endregion + + #region Private Variables + private CombCell[] m_ColorCombs = new CombCell[144]; + private const float YOffset = .824f; + private float[] arrXOffset = new float[] { -0.5f, -1.0f, -0.5f, 0.5f, 1.0f, 0.5f }; + private float[] arrYOffset = new float[] { YOffset, 0.0f, -YOffset, -YOffset, 0.0f, YOffset }; + private int CombDepth = 7; + private int m_MouseOverIndex = -1; + private int m_SelectedIndex = -1; + + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + #endregion + + #region Constructor, Dispose + /// + /// Creates new instance of the control. + /// + public ColorCombControl() + { + for (int i = 0; i < m_ColorCombs.Length; i++) + m_ColorCombs[i] = new CombCell(); + + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + InitializeComponent(); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose(disposing); + } + #endregion + + #region Component Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + #endregion + + #region Internal Implementation + private bool m_AntiAlias = true; + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is true. + /// + [DefaultValue(true), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public bool AntiAlias + { + get { return m_AntiAlias; } + set + { + if (m_AntiAlias != value) + { + m_AntiAlias = value; + this.Invalidate(); + } + } + } + + private int GetCellSize(int height) + { + int cellSize = height / (2 * CombDepth - 1) + 1; + if ((int)(Math.Floor((double)cellSize / 2)) * 2 < cellSize) + cellSize--; + return cellSize; + } + + private void InitializeColorComb() + { + Rectangle clientRect = this.ClientRectangle; + clientRect.Inflate(-8, -8); + clientRect.Height -= GetCellSize(Math.Min(clientRect.Height, clientRect.Width)); + + // Normalize... + if (clientRect.Height < clientRect.Width) + clientRect.Inflate(-(clientRect.Width - clientRect.Height) / 2, 0); + else + clientRect.Inflate(0, -(clientRect.Height - clientRect.Width) / 2); + + int cellSize = GetCellSize(clientRect.Height); + clientRect.Height -= cellSize * 2; + //clientRect.Inflate(-cellSize, 0); + int x = (clientRect.Left + clientRect.Right) / 2; + int y = (clientRect.Top + clientRect.Bottom) / 2; + + // Center White Comb + m_ColorCombs[0].Color = Color.White; + m_ColorCombs[0].SetPosition(x, y, cellSize); + + int index = 1; + for (int nLevel = 1; nLevel < CombDepth; nLevel++) + { + float posX = x + (cellSize * nLevel); + float posY = y; + + for (int nSide = 0; nSide < CombDepth - 1; nSide++) + { + int xIncrease = (int)((cellSize) * arrXOffset[nSide]); + int yIncrease = (int)((cellSize) * arrYOffset[nSide]); + + for (int nCell = 0; nCell < nLevel; nCell++) + { + float nAngle = GetAngleFromPoint(posX - x, posY - y); + double L = .936 * (CombDepth - nLevel) / CombDepth + .12; + + m_ColorCombs[index].Color = GetRGBFromHLSExtend((float)nAngle, L, 1.0F); + m_ColorCombs[index].SetPosition(posX, posY, cellSize); + index++; + + posX += xIncrease; + posY += yIncrease; + } + } + } + + m_ColorCombs[index].Color = Color.Black; + index++; + m_ColorCombs[index].Color = Color.White; + + int RGBOffset = 255 / (15 + 2); + + int rgb = 255 - RGBOffset; + + x = clientRect.X + cellSize * 3; + y = clientRect.Bottom + cellSize; + + for (int i = 0; i < 15; i++) + { + Color color = Color.FromArgb(rgb, rgb, rgb); + m_ColorCombs[index].Color = color; + m_ColorCombs[index].SetPosition(x, y, cellSize); + x += cellSize; + index++; + if (i == 7) + { + x = clientRect.X + (int)(cellSize * 3.5); + y += (int)(cellSize * YOffset); + } + rgb -= RGBOffset; + } + m_ColorCombs[index].Color = Color.Black; + } + + + private Color GetRGBFromHLSExtend(double H, double L, double S) + { + int R, G, B; + + if (S == 0.0) + { + R = G = B = (int)(L * 255.0); + } + else + { + float rm1, rm2; + + if (L <= 0.5f) + rm2 = (float)(L + L * S); + else + rm2 = (float)(L + S - L * S); + + rm1 = (float)(2.0f * L - rm2); + + R = GetRGBFromHue(rm1, rm2, (float)(H + 120.0f)); + G = GetRGBFromHue(rm1, rm2, (float)(H)); + B = GetRGBFromHue(rm1, rm2, (float)(H - 120.0f)); + } + + return Color.FromArgb(R, G, B); + } + + private float GetAngleFromPoint(float nX, float nY) + { + double dAngle = Math.Atan2(nY, nX); + return (float)(dAngle * 180.0 / Math.PI); + } + + private int GetRGBFromHue(float rm1, float rm2, float rh) + { + if (rh > 360.0f) + rh -= 360.0f; + else if (rh < 0.0f) + rh += 360.0f; + + if (rh < 60.0f) + rm1 = rm1 + (rm2 - rm1) * rh / 60.0f; + else if (rh < 180.0f) + rm1 = rm2; + else if (rh < 240.0f) + rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f; + + return (int)(rm1 * 255); + } + + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + + if (m_AntiAlias) + { + e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + e.Graphics.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + using (SolidBrush brush = new SolidBrush(this.BackColor)) + g.FillRectangle(brush, -1, -1, this.Width + 1, this.Height + 1); + + if (this.BackColor == Color.Transparent || this.BackgroundImage != null) + { + base.OnPaintBackground(e); + } + + + foreach (CombCell c in m_ColorCombs) + c.Draw(g); + + if (m_MouseOverIndex >= 0) + m_ColorCombs[m_MouseOverIndex].Draw(g); + if (m_SelectedIndex >= 0) + m_ColorCombs[m_SelectedIndex].Draw(g); + + base.OnPaint(e); + } + + protected override void OnResize(EventArgs e) + { + InitializeColorComb(); + base.OnResize(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + + int newMouseOver = GetCellAt(e.X, e.Y); + SetMouseOver(newMouseOver); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + if (m_SelectedIndex >= 0) + { + m_ColorCombs[m_SelectedIndex].Selected = false; + this.Invalidate(m_ColorCombs[m_SelectedIndex].Bounds); + } + m_SelectedIndex = -1; + + if (m_MouseOverIndex >= 0) + { + m_SelectedIndex = m_MouseOverIndex; + m_ColorCombs[m_SelectedIndex].Selected = true; + this.Invalidate(m_ColorCombs[m_SelectedIndex].Bounds); + OnSelectedColorChanged(EventArgs.Empty); + } + } + base.OnMouseDown(e); + } + + /// + /// Gets the color mouse is currently over. If mouse is not over any color in comb Color.Empty is returned. + /// + [Browsable(false)] + public Color MouseOverColor + { + get + { + if (m_MouseOverIndex < 0) + return Color.Empty; + return m_ColorCombs[m_MouseOverIndex].Color; + } + } + + /// + /// Gets or sets the selected color. When setting the color note that color must be already present in the color comb otherwise the selected color will be reset to Color.Empty. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color SelectedColor + { + get + { + if (m_SelectedIndex < 0) + return Color.Empty; + return m_ColorCombs[m_SelectedIndex].Color; + } + set + { + if (value == Color.Empty && m_SelectedIndex >= 0) + { + m_ColorCombs[m_SelectedIndex].Selected = false; + m_SelectedIndex = -1; + this.Invalidate(); + OnSelectedColorChanged(EventArgs.Empty); + } + else + { + int colorIndex = GetCombColorIndex(value); + if (colorIndex != m_SelectedIndex) + { + if (m_SelectedIndex >= 0) + m_ColorCombs[m_SelectedIndex].Selected = false; + m_SelectedIndex = colorIndex; + if (m_SelectedIndex >= 0) + m_ColorCombs[m_SelectedIndex].Selected = true; + this.Invalidate(); + OnSelectedColorChanged(EventArgs.Empty); + } + } + } + } + private int GetCombColorIndex(Color value) + { + for (int i = 0; i < m_ColorCombs.Length; i++) + { + if (m_ColorCombs[i].Color.Equals(value)) + return i; + } + return -1; + } + + /// + /// Occurs when MouseOverColor property has changed. + /// + public event EventHandler MouseOverColorChanged; + /// + /// Raises MouseOverColorChanged event. + /// + /// Provides event arguments. + protected virtual void OnMouseOverColorChanged(EventArgs e) + { + EventHandler handler = MouseOverColorChanged; + if (handler != null) + handler(this, e); + } + private void SetMouseOver(int newMouseOver) + { + if (newMouseOver != m_MouseOverIndex) + { + if (m_MouseOverIndex >= 0) + { + m_ColorCombs[m_MouseOverIndex].MouseOver = false; + this.Invalidate(m_ColorCombs[m_MouseOverIndex].Bounds); + } + m_MouseOverIndex = newMouseOver; + if (m_MouseOverIndex >= 0) + { + m_ColorCombs[m_MouseOverIndex].MouseOver = true; + this.Invalidate(m_ColorCombs[m_MouseOverIndex].Bounds); + } + OnMouseOverColorChanged(EventArgs.Empty); + } + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + SetMouseOver(-1); + } + + private int GetCellAt(int x, int y) + { + for (int i = 0; i < m_ColorCombs.Length; i++) + { + if (m_ColorCombs[i].Bounds.Contains(x, y)) + { + return i; + } + } + + return -1; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ColorPickers/ColorCombControl.ico b/PROMS/DotNetBar Source Code/ColorPickers/ColorCombControl.ico new file mode 100644 index 00000000..8167ada4 Binary files /dev/null and b/PROMS/DotNetBar Source Code/ColorPickers/ColorCombControl.ico differ diff --git a/PROMS/DotNetBar Source Code/ColorPickers/ColorContrastControl.cs b/PROMS/DotNetBar Source Code/ColorPickers/ColorContrastControl.cs new file mode 100644 index 00000000..710c61c7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPickers/ColorContrastControl.cs @@ -0,0 +1,290 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.ColorPickerItem +{ + /// + /// Represents the color selection control. + /// + [ToolboxItem(false)] + internal class ColorContrastControl : System.Windows.Forms.Control + { + #region Events + /// + /// Occurs when SelectedColor has changed. + /// + public event EventHandler SelectedColorChanged; + /// + /// Raises SelectedColorChanged event. + /// + /// Provides event arguments. + protected virtual void OnSelectedColorChanged(EventArgs e) + { + EventHandler handler = SelectedColorChanged; + if (handler != null) + handler(this, e); + } + #endregion + + #region Private Variables + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + private Color m_SelectedColor = Color.White; + private Bitmap m_BlendBitmap=null; + private double m_SelectedLuminance = -1; + #endregion + + #region Constructor, Dispose + public ColorContrastControl() + { + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + + // This call is required by the Windows.Forms Form Designer. + InitializeComponent(); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + #endregion + + #region Internal Implementation + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + + if(this.BackColor == Color.Transparent) + { + base.OnPaintBackground(e); + } + else + { + using(SolidBrush brush=new SolidBrush(this.BackColor)) + g.FillRectangle(brush, this.ClientRectangle); + } + + if(m_BlendBitmap!=null) + g.DrawImageUnscaled(m_BlendBitmap, 0, 0); + + if(m_SelectedLuminance>=0) + { + int y = (int)(this.ClientRectangle.Height * (1 - m_SelectedLuminance)); + int x = m_BlendBitmap.Width + 4; + GraphicsPath path = new GraphicsPath(); + path.AddLine(x, y, x + 7, y - 4); + path.AddLine(x+ 7 , y - 4, x + 7, y + 4); + path.CloseAllFigures(); + using(SolidBrush brush=new SolidBrush(Color.Black)) + g.FillPath(brush, path); + path.Dispose(); + } + } + + protected override void OnResize(EventArgs e) + { + CreateBlendBitmap(); + base.OnResize (e); + } + + + private void CreateBlendBitmap() + { + Rectangle clientRect = this.ClientRectangle; + + Bitmap bmp = new Bitmap(12, clientRect.Height, PixelFormat.Format24bppRgb); + using (Graphics graph = Graphics.FromImage(bmp)) + { + graph.FillRectangle(SystemBrushes.Control, clientRect); + + Color color = m_SelectedColor; + int ry = color.R, gy = color.G, by = color.B; + + int pointHeight = 4; + int pointWidth = 12; + + int x = clientRect.X; + int y = clientRect.Y; + double h = 0, s = 0, l = 0; + GetHSLFromRGB(m_SelectedColor, ref h, ref s, ref l); + + for (int j = clientRect.Y; j < clientRect.Height; j += pointHeight) + { + double lumCurrent = 1 - (double) j / (double) clientRect.Height; + Color c = GetColorFromHSL(h, s, lumCurrent); + using (SolidBrush brush = new SolidBrush(c)) + graph.FillRectangle(brush, new Rectangle(x, y, pointWidth, pointHeight)); + y += pointHeight; + } + } + + if(m_BlendBitmap!=null) + m_BlendBitmap.Dispose(); + m_BlendBitmap = bmp; + } + + /// + /// Gets or sets the selected color. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color SelectedColor + { + get + { + if(m_SelectedLuminance>=0) + { + double h = 0, s = 0, l = 0; + GetHSLFromRGB(m_SelectedColor, ref h, ref s, ref l); + return GetColorFromHSL(h, s, m_SelectedLuminance); + } + return m_SelectedColor; + } + set + { + m_SelectedColor = value; + double h = 0, s = 0, l = 0; + GetHSLFromRGB(m_SelectedColor, ref h, ref s, ref l); + //if(m_SelectedLuminance<0) + m_SelectedLuminance = l; + CreateBlendBitmap(); + this.Invalidate(); + } + } + + private int GetRGBFromHue(float rm1, float rm2, float rh) + { + if (rh > 360.0f) + rh -= 360.0f; + else if (rh < 0.0f) + rh += 360.0f; + + if (rh < 60.0f) + rm1 = rm1 + (rm2 - rm1) * rh / 60.0f; + else if (rh < 180.0f) + rm1 = rm2; + else if (rh < 240.0f) + rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f; + + return (int)(rm1 * 255); + } + + private Color GetColorFromHSL( double H, double S, double L) + { + double r=0,g=0,b=0; + double temp1,temp2; + if(L==0) + { + r=g=b=0; + } + else + { + if(S==0) + { + r=g=b=L; + } + else + { + temp2 = ((L<=0.5) ? L*(1.0+S) : L+S-(L*S)); + temp1 = 2.0*L-temp2; + double[] t3=new double[]{H+1.0/3.0,H,H-1.0/3.0}; + double[] clr=new double[]{0,0,0}; + for(int i=0;i<3;i++) + { + if(t3[i]<0) + t3[i]+=1.0; + + if(t3[i]>1) + t3[i]-=1.0; + + if(6.0*t3[i] < 1.0) + clr[i]=temp1+(temp2-temp1)*t3[i]*6.0; + else if(2.0*t3[i] < 1.0) + clr[i]=temp2; + else if(3.0*t3[i] < 2.0) + clr[i]=(temp1+(temp2-temp1)*((2.0/3.0)-t3[i])*6.0); + else + clr[i]=temp1; + } + + r=clr[0]; + g=clr[1]; + b=clr[2]; + } + } + + return Color.FromArgb((int)(255*r),(int)(255*g),(int)(255*b)); + } + + private void GetHSLFromRGB(Color color, ref double H, ref double S, ref double L ) + { + H=color.GetHue()/360.0; // we store hue as 0-1 as opposed to 0-360 + L=color.GetBrightness(); + S=color.GetSaturation(); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + double d = 1 - (double) e.Y / (double) ClientRectangle.Height; + SetLuminance(d); + base.OnMouseDown (e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if(e.Button==MouseButtons.Left && e.Y>=0 && e.Y + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + // + // ColorContrastControl + // + this.Name = "ColorContrastControl"; + this.Size = new System.Drawing.Size(24, 248); + + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ColorPickers/ColorItem.cs b/PROMS/DotNetBar Source Code/ColorPickers/ColorItem.cs new file mode 100644 index 00000000..56b28a07 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPickers/ColorItem.cs @@ -0,0 +1,198 @@ +using System; +using System.Text; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents color item used for color picker control. Color item can only be used as part of the color picker DotNetBar feature. + /// + public class ColorItem : BaseItem + { + #region Private Variables + private Color m_Color = Color.Black; + private Size m_DesiredSize = new Size(13, 13); + private bool m_MouseOver = false; + private eColorItemBorder m_Border = eColorItemBorder.All; + #endregion + + #region Internal Implementation + public ColorItem():this("","") {} + public ColorItem(string sName):this(sName,""){} + public ColorItem(string sName, string ItemText) + : base(sName, ItemText) + { + this.IsAccessible=false; + this.CanCustomize = false; + } + + public ColorItem(string sName, string ItemText, Color color) + : base(sName, ItemText) + { + this.IsAccessible = false; + this.CanCustomize = false; + m_Color = color; + } + + public override BaseItem Copy() + { + ColorItem copy = new ColorItem(m_Name); + this.CopyToItem(copy); + + return copy; + } + protected override void CopyToItem(BaseItem copy) + { + ColorItem ci = copy as ColorItem; + base.CopyToItem(ci); + ci.DesiredSize = this.DesiredSize; + ci.Color = this.Color; + ci.Border = this.Border; + if (this.ShouldSerializeDesiredSize()) + ci.DesiredSize = this.DesiredSize; + } + + public override void Paint(ItemPaintArgs p) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + ColorItemRendererEventArgs e = new ColorItemRendererEventArgs(p.Graphics, this); + renderer.DrawColorItem(e); + } + else + { + Rendering.ColorItemPainter painter = PainterFactory.CreateColorItemPainter(this); + if (painter != null) + { + ColorItemRendererEventArgs e = new ColorItemRendererEventArgs(p.Graphics, this); + painter.PaintColorItem(e); + } + } + } + + public override void RecalcSize() + { + m_Rect.Size = Dpi.Size(m_DesiredSize); + base.RecalcSize(); + } + + /// + /// Gets or sets the color represented by this item. Default value is Color.Black. + /// + [Browsable(true), DevCoBrowsable(true), DevCoSerialize(), Category("Appearance"), Description("Indicates the color represented by this item.")] + public System.Drawing.Color Color + { + get { return m_Color; } + set + { + m_Color = value; + OnAppearanceChanged(); + } + } + private bool ShouldSerializeColor() + { + return (m_Color != Color.Black); + } + + /// + /// Gets or sets the size of the item when displayed. Default value is 13x13 pixels. + /// + [Browsable(true), DevCoBrowsable(true), DevCoSerialize(), Category("Appearance"), Description("Indicates the size of the item when displayed.")] + public System.Drawing.Size DesiredSize + { + get { return m_DesiredSize; } + set + { + if (value.Width > 0 && value.Height > 0) + { + m_DesiredSize = value; + NeedRecalcSize = true; + OnAppearanceChanged(); + } + } + } + private bool ShouldSerializeDesiredSize() + { + return (m_DesiredSize.Width!=13 || m_DesiredSize.Height!=13); + } + + /// + /// Gets or sets border drawn around the item. Default value is eColorItemBorder.All which indicates that border is drawn + /// on all four sides. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(eColorItemBorder.All), Description("Indicate border drawn around the item"), DevCoSerialize()] + public eColorItemBorder Border + { + get { return m_Border; } + set + { + m_Border = value; + OnAppearanceChanged(); + } + } + + /// + /// Gets whether mouse is over the item. + /// + public bool IsMouseOver + { + get { return m_MouseOver; } + } + + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseEnter() + { + base.InternalMouseEnter(); + SetMouseOver(true); + BaseItem parent = this.Parent; + while (parent != null && !(parent is ColorPickerDropDown)) + parent = parent.Parent; + if (parent != null && parent is ColorPickerDropDown) + ((ColorPickerDropDown)parent).InvokeColorPreview(new ColorPreviewEventArgs(this.Color, this)); + } + + + [System.ComponentModel.Browsable(false), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseLeave() + { + base.InternalMouseLeave(); + SetMouseOver(false); + } + + private void SetMouseOver(bool value) + { + if (value != m_MouseOver) + { + m_MouseOver = value; + this.Refresh(); + } + } + #endregion + + #region Serialization + /// + /// Overloaded. Serializes the item and all sub-items into the XmlElement. + /// + /// XmlElement to serialize the item to. + protected internal override void Serialize(ItemSerializationContext context) + { + base.Serialize(context); + System.Xml.XmlElement xml = context.ItemXmlElement; + ElementSerializer.Serialize(this, xml); + } + + // + /// Overloaded. Deserializes the Item from the XmlElement. + /// + /// Source XmlElement. + public override void Deserialize(ItemSerializationContext context) + { + base.Deserialize(context); + System.Xml.XmlElement xml = context.ItemXmlElement; + ElementSerializer.Deserialize(this, xml); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ColorPickers/ColorPickerDropDown.cs b/PROMS/DotNetBar Source Code/ColorPickers/ColorPickerDropDown.cs new file mode 100644 index 00000000..525f5107 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPickers/ColorPickerDropDown.cs @@ -0,0 +1,978 @@ +using System; +using System.Text; +using System.Collections; +using System.Drawing; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the color picker drop down button. + /// + [DefaultEvent("SelectedColorChanged")] + public class ColorPickerDropDown : ButtonItem + { + #region Events + /// + /// Occurs when color is chosen from drop-down color picker or from Custom Colors dialog box. Selected color can be accessed through SelectedColor property. + /// + [Description("Occurs when color is chosen from drop-down color picker or from Custom Colors dialog box.")] + public event EventHandler SelectedColorChanged; + + /// + /// Occurs when mouse is moving over the colors presented by the color picker. You can use it to preview the color before it is selected. + /// + [Description("Occurs when mouse is moving over the colors presented by the color picker")] + public event ColorPreviewEventHandler ColorPreview; + + /// + /// Occurs before color picker dialog is shown. Data property of the event arguments will hold the reference to the Form about to be shown. + /// + public event CancelObjectValueEventHandler BeforeColorDialog; + #endregion + + #region Private Variables + private bool m_ColorsInitialized = false; + private bool m_DisplayThemeColors = true; + private bool m_DisplayStandardColors = true; + private bool m_DisplayMoreColors = true; + + private bool m_Localized = false; + private string m_ThemeColorsLabel = "Theme Colors"; + private string m_StandardColorsLabel = "Standard Colors"; + private string m_MoreColorsLabel = "&More Colors..."; + private Color m_SelectedColor = System.Drawing.Color.Empty; + private Rectangle m_SelectedColorRectangle = Rectangle.Empty; + private bool m_SelectedImageCreated = false; + #endregion + + #region Constructor + /// + /// Creates new instance of ButtonItem. + /// + public ColorPickerDropDown() : this("", "") { } + /// + /// Creates new instance of ButtonItem and assigns the name to it. + /// + /// Item name. + public ColorPickerDropDown(string sItemName) : this(sItemName, "") { } + /// + /// Creates new instance of ButtonItem and assigns the name and text to it. + /// + /// Item name. + /// item text. + public ColorPickerDropDown(string sItemName, string ItemText) + : base(sItemName, ItemText) + { + //this.AutoExpandOnClick = true; + this.SubItems.Add(new ButtonItem("tempColorPickerItem")); + } + #endregion + + #region Internal Implementation + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + ColorPickerDropDown objCopy = new ColorPickerDropDown(); + this.CopyToItem(objCopy); + return objCopy; + } + /// + /// Copies the ButtonItem specific properties to new instance of the item. + /// + /// New ButtonItem instance. + protected override void CopyToItem(BaseItem c) + { + ColorPickerDropDown copy = c as ColorPickerDropDown; + copy.DisplayMoreColors = this.DisplayMoreColors; + copy.DisplayStandardColors = this.DisplayStandardColors; + copy.DisplayThemeColors = this.DisplayThemeColors; + copy.SelectedColorChanged = this.SelectedColorChanged; + copy.CustomStandardColors = GetCopy(this.CustomStandardColors); + copy.CustomThemeColors = GetCopy(this.CustomThemeColors); + copy.SelectedColorImageRectangle = this.SelectedColorImageRectangle; + copy.SelectedColor = this.SelectedColor; + + base.CopyToItem(copy); + } + + private ColorItem[][] GetCopy(ColorItem[][] colorItems) + { + if (colorItems == null || colorItems.Length == 0) + return null; + ColorItem[][] copies=new ColorItem[colorItems.Length][]; + for (int i = 0; i < colorItems.Length; i++) + { + ColorItem[] items = colorItems[i]; + copies[i]=new ColorItem[items.Length]; + for (int j = 0; j < items.Length; j++) + { + copies[i][j] = (ColorItem) items[j].Copy(); + } + } + + return copies; + } + + + /// + /// Raises the ColorPreview event. + /// + /// Provides the data for the event. + protected virtual void OnColorPreview(ColorPreviewEventArgs e) + { + if (ColorPreview != null) + ColorPreview(this, e); + } + + /// + /// Invokes the ColorPreview event. + /// + /// Provides data for the event. + public void InvokeColorPreview(ColorPreviewEventArgs e) + { + OnColorPreview(e); + } + + /// + /// Gets or sets the last selected color from either the drop-down or Custom Color dialog box. Default value is + /// Color.Empty. You can use SelectedColorChanged event to be notified when this property changes. + /// + [Browsable(false), DevCoBrowsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color SelectedColor + { + get { return m_SelectedColor; } + set { SetSelectedColor(value, false); } + } + + /// + /// Gets or sets whether theme colors are displayed on drop-down. Default value is true. + /// + [Browsable(true), DefaultValue(true), DevCoBrowsable(true), DevCoSerialize(), Category("Appearance"), Description("Indicates whether theme colors are displayed on drop-down.")] + public bool DisplayThemeColors + { + get { return m_DisplayThemeColors; } + set { m_DisplayThemeColors = value; } + } + + /// + /// Gets or sets whether standard colors are displayed on drop-down. Default value is true. + /// + [Browsable(true), DefaultValue(true), DevCoBrowsable(true), DevCoSerialize(), Category("Appearance"), Description("Indicates whether standard colors are displayed on drop-down.")] + public bool DisplayStandardColors + { + get { return m_DisplayStandardColors; } + set { m_DisplayStandardColors = value; } + } + + /// + /// Gets or sets more colors menu item is visible which allows user to open Custom Colors dialog box. Default value is true. + /// + [Browsable(true), DefaultValue(true), DevCoBrowsable(true), DevCoSerialize(), Category("Appearance"), Description("Indicates more colors menu item is visible which allows user to open Custom Colors dialog box.")] + public bool DisplayMoreColors + { + get { return m_DisplayMoreColors; } + set { m_DisplayMoreColors = value; } + } + + /// + /// Indicates whether SubItems collection is serialized. ColorPickerDropDown does not serialize the sub items. + /// + protected override bool ShouldSerializeSubItems() + { + return false; + } + + /// + /// Gets or sets the rectangle in Image coordinates where selected color will be painted. Setting this property will + /// have an effect only if Image property is used to set the image. Default value is an empty rectangle which indicates + /// that selected color will not be painted on the image. + /// + [Browsable(true), Description("Indicates rectangle in Image coordinates where selected color will be painted. Property will have effect only if Image property is used to set the image."), Category("Behaviour")] + public Rectangle SelectedColorImageRectangle + { + get { return m_SelectedColorRectangle; } + set + { + m_SelectedColorRectangle = value; + UpdateSelectedColorImage(); + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSelectedColorImageRectangle() + { + return !m_SelectedColorRectangle.IsEmpty; + } + + /// + /// Resets the property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSelectedColorImageRectangle() + { + SelectedColorImageRectangle = Rectangle.Empty; + } + + ///// + ///// Indicates whether the item will auto-expand when clicked. + ///// When item is on top level bar and not on menu and contains sub-items, sub-items will be shown only if user + ///// click the expand part of the button. Setting this property to true will expand the button and show sub-items when user + ///// clicks anywhere inside of the button. Default value is true which indicates that button is expanded only + ///// if its expand part is clicked. + ///// + //[DefaultValue(true), Browsable(true), DevCoBrowsable(true), Category("Behavior"), Description("Indicates whether the item will auto-expand (display pop-up menu or toolbar) when clicked.")] + //public override bool AutoExpandOnClick + //{ + // get { return base.AutoExpandOnClick; } + // set { base.AutoExpandOnClick = value; } + //} + + /// + /// Gets whether internal representation of color items on popup has been initialized. + /// + [Browsable(false)] + public bool ColorsInitialized + { + get + { + return m_ColorsInitialized; + } + } + + protected override void OnStyleChanged() + { + m_ColorsInitialized = false; + base.OnStyleChanged(); + } + + protected override void OnPopupOpen(PopupOpenEventArgs e) + { + base.OnPopupOpen(e); // Fire events first then initialize + if (!m_ColorsInitialized) + InitializeColorDropDown(); + } + + private void InitializeColorDropDown() + { + this.SubItems.Clear(); + + LoadResources(); + if (m_DisplayThemeColors) + { + LabelItem label = new LabelItem(); + label.CanCustomize = false; + label.Text = m_ThemeColorsLabel; + if (GlobalManager.Renderer is Office2007Renderer) + { + label.BackColor = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.Gallery.GroupLabelBackground; + label.ForeColor = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.Gallery.GroupLabelText; + label.SingleLineColor = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.Gallery.GroupLabelBorder; + } + else + { + label.BackColor = ColorScheme.GetColor("DDE7EE"); + label.ForeColor = ColorScheme.GetColor("00156E"); + label.SingleLineColor = ColorScheme.GetColor("C5C5C5"); + } + label.PaddingBottom = 1; + label.PaddingLeft = 0; + label.PaddingRight = 0; + label.PaddingTop = 1; + label.BorderSide = eBorderSide.Bottom; + label.BorderType = eBorderType.SingleLine; + this.SubItems.Add(label); + ArrayList colors = this.GetThemeColors(); + AddColors(colors); + } + + if (m_DisplayStandardColors) + { + LabelItem label = new LabelItem(); + label.CanCustomize = false; + label.Text = m_StandardColorsLabel; + if (GlobalManager.Renderer is Office2007Renderer) + { + label.BackColor = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.QuickAccessToolbar.QatCustomizeMenuLabelBackground; + label.ForeColor = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.QuickAccessToolbar.QatCustomizeMenuLabelText; + label.SingleLineColor = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.Gallery.GroupLabelBorder; + } + else + { + label.BackColor = ColorScheme.GetColor("DDE7EE"); + label.ForeColor = ColorScheme.GetColor("00156E"); + label.SingleLineColor = ColorScheme.GetColor("C5C5C5"); + } + label.PaddingBottom = 1; + label.PaddingLeft = 0; + label.PaddingRight = 0; + label.PaddingTop = 1; + label.BorderSide = eBorderSide.Bottom; + label.BorderType = eBorderType.SingleLine; + this.SubItems.Add(label); + ArrayList colors = this.GetStandardColors(); + AddColors(colors); + } + + if (m_DisplayMoreColors) + { + ButtonItem button = new ButtonItem("sys_CPMoreColors", m_MoreColorsLabel); + button.CanCustomize = false; + button.Image = BarFunctions.LoadBitmap("SystemImages.ColorPickerCustomColors.png"); + button.Click += new EventHandler(MoreColorsButtonClick); + button.BeginGroup = true; + this.SubItems.Add(button); + } + + m_ColorsInitialized = true; + + OnColorItemsInitialized(EventArgs.Empty); + } + + /// + /// "Occurs after popup colors have been added to the SubItems collection. This event can be used to effectively add custom items to the popup. + /// + [Description("Occurs after popup colors have been added to the SubItems collection. This event can be used to effectively add custom items to the popup.")] + public event EventHandler ColorItemsInitialized; + + /// + /// Raises RemovingToken event. + /// + /// Provides event arguments. + protected virtual void OnColorItemsInitialized(EventArgs e) + { + EventHandler handler = ColorItemsInitialized; + if (handler != null) + handler(this, e); + } + + private void MoreColorsButtonClick(object sender, EventArgs e) + { + DisplayMoreColorsDialog(); + } + + /// + /// Displays the Colors dialog that allows user to choose the color or create a custom color. If new color is chosen the + /// SelectedColorChanged event is raised. + /// + public DialogResult DisplayMoreColorsDialog() + { + DialogResult result = DialogResult.Cancel; + + if (StyleManager.IsMetro(this.EffectiveStyle)) + { + ColorPickerItem.CustomColorDialogMetro d = new ColorPickerItem.CustomColorDialogMetro(); + d.SetStyle(this.EffectiveStyle); + d.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + if (!this.SelectedColor.IsEmpty) + d.CurrentColor = this.SelectedColor; + LocalizeDialog(d); + CancelObjectValueEventArgs e = new CancelObjectValueEventArgs(d); + OnBeforeColorDialog(e); + if (e.Cancel) + { + d.Dispose(); + return DialogResult.None; + } + if (_OwnerWindow != null) + { + if (_OwnerWindow is Form && ((Form)_OwnerWindow).TopMost) + d.TopMost = true; + d.ShowDialog(_OwnerWindow); + } + else + d.ShowDialog(); + + result = d.DialogResult; + if (result == System.Windows.Forms.DialogResult.OK) + { + if (!d.NewColor.IsEmpty) + { + this.SetSelectedColor(d.NewColor); + } + } + + d.Dispose(); + } + else + { + ColorPickerItem.CustomColorDialog d = new ColorPickerItem.CustomColorDialog(); + d.SetStyle(this.EffectiveStyle); + d.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + if (!this.SelectedColor.IsEmpty) + d.CurrentColor = this.SelectedColor; + LocalizeDialog(d); + CancelObjectValueEventArgs e = new CancelObjectValueEventArgs(d); + OnBeforeColorDialog(e); + if (e.Cancel) + { + d.Dispose(); + return DialogResult.None; + } + if (_OwnerWindow != null) + { + if (_OwnerWindow is Form && ((Form)_OwnerWindow).TopMost) + d.TopMost = true; + d.ShowDialog(_OwnerWindow); + } + else + d.ShowDialog(); + + result = d.DialogResult; + if (result == System.Windows.Forms.DialogResult.OK) + { + if (!d.NewColor.IsEmpty) + { + this.SetSelectedColor(d.NewColor); + } + } + + d.Dispose(); + } + return result; + } + + /// + /// Raises the BeforeColorDialog event. + /// + /// + protected virtual void OnBeforeColorDialog(CancelObjectValueEventArgs e) + { + CancelObjectValueEventHandler h = this.BeforeColorDialog; + if (h != null) + h(this, e); + } + + private IWin32Window _OwnerWindow = null; + /// + /// Gets or sets the Owner Window that will be used as owner for the colors modal dialog when displayed. + /// + [Browsable(false), DefaultValue(null)] + public IWin32Window OwnerWindow + { + get { return _OwnerWindow; } + set { _OwnerWindow = value; } + } + + private void LocalizeDialog(ColorPickerItem.CustomColorDialog d) + { + if (this.GetOwner() != null) + m_Localized = true; + using (LocalizationManager lm = new LocalizationManager(this.GetOwner() as IOwnerLocalize)) + { + string s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogOKButton); + if (s != "") d.buttonOK.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogCancelButton); + if (s != "") d.buttonCancel.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogNewColorLabel); + if (s != "") d.labelNewColor.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogCurrentColorLabel); + if (s != "") d.labelCurrentColor.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogStandardColorsLabel); + if (s != "") d.labelStandardColors.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogCustomColorsLabel); + if (s != "") d.labelCustomColors.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogGreenLabel); + if (s != "") d.labelGreen.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogBlueLabel); + if (s != "") d.labelBlue.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogRedLabel); + if (s != "") d.labelRed.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerTabStandard); + if (s != "") d.tabItemStandard.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerTabCustom); + if (s != "") d.tabItemCustom.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerCaption); + if (s != "") d.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogColorModelLabel); + if (s != "") d.labelColorModel.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogRgbLabel); + if (s != "") d.comboColorModel.Items[0] = s; + } + } + private void LocalizeDialog(ColorPickerItem.CustomColorDialogMetro d) + { + if (this.GetOwner() != null) + m_Localized = true; + using (LocalizationManager lm = new LocalizationManager(this.GetOwner() as IOwnerLocalize)) + { + string s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogOKButton); + if (s != "") d.buttonOK.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogCancelButton); + if (s != "") d.buttonCancel.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogNewColorLabel); + if (s != "") d.labelNewColor.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogCurrentColorLabel); + if (s != "") d.labelCurrentColor.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogStandardColorsLabel); + if (s != "") d.labelStandardColors.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogCustomColorsLabel); + if (s != "") d.labelCustomColors.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogGreenLabel); + if (s != "") d.labelGreen.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogBlueLabel); + if (s != "") d.labelBlue.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogRedLabel); + if (s != "") d.labelRed.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerTabStandard); + if (s != "") d.tabItemStandard.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerTabCustom); + if (s != "") d.tabItemCustom.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerCaption); + if (s != "") d.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogColorModelLabel); + if (s != "") d.labelColorModel.Text = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerDialogRgbLabel); + if (s != "") d.comboColorModel.Items[0] = s; + } + } + + private void AddColors(ArrayList colors) + { + int colorItemSpacing = 3; + for (int i = 0; i < colors.Count; i++) + { + ItemContainer cont = new ItemContainer(); + cont.Orientation = eOrientation.Horizontal; + cont.ItemSpacing = colorItemSpacing; + if (i == 0) + { + cont.BackgroundStyle.MarginBottom = 5; + cont.BackgroundStyle.MarginTop = 3; + } + if (i == colors.Count - 1) + cont.BackgroundStyle.MarginBottom = 3; + + ColorItem[] colorLine = (ColorItem[])colors[i]; + foreach (ColorItem ci in colorLine) + { + cont.SubItems.Add(ci); + ci.Click += new EventHandler(ColorItemClick); + ci.AutoCollapseOnClick = false; + } + this.SubItems.Add(cont); + } + } + + private void ColorItemClick(object sender, EventArgs e) + { + ColorItem ci = sender as ColorItem; + if (ci == null) + return; + + SetSelectedColor(ci.Color); + if (AutoCollapseOnClick) + BaseItem.CollapseAll(this); + else if (this.PopupControl != null) + this.PopupControl.Invalidate(); + } + + private void SetSelectedColor(Color c) + { + SetSelectedColor(c, true); + } + + private void SetSelectedColor(Color c, bool raiseClick) + { + bool valueChanged = (m_SelectedColor != c); + m_SelectedColor = c; + + OnSelectedColorChanged(new EventArgs()); + if (raiseClick) + RaiseClick(); + + if (valueChanged && ShouldSyncProperties) + BarFunctions.SyncProperty(this, "SelectedColor"); + + UpdateSelectedColorImage(); + } + + protected override void ScaleItem(SizeF factor) + { + base.ScaleItem(factor); + UpdateSelectedColorImage(); + } + + /// + /// Update the selected color image if the SelectedColorImageRectangle has been set and button is using Image property to display the image. + /// + public void UpdateSelectedColorImage() + { + if (m_SelectedColorRectangle.IsEmpty || m_SelectedColorRectangle.Width <= 0 || m_SelectedColorRectangle.Height <= 0 || + this.Image == null || this.DesignMode) return; + + Bitmap bmp = new Bitmap(this.Image.Width, this.Image.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + using (Graphics g = Graphics.FromImage(bmp)) + { + Rectangle r = m_SelectedColorRectangle; + g.DrawImage(this.Image, 0, 0, this.Image.Width, this.Image.Height); + Color selColor = this.SelectedColor; + bool noColor = false; + if (selColor.IsEmpty || selColor == Color.Transparent) + { + selColor = Color.White; + noColor = true; + } + using (SolidBrush b = new SolidBrush(selColor)) + { + g.FillRectangle(b, r); + } + if (noColor && r.Height > 5) + { + r.Width--; + r.Height--; + using (Pen p = new Pen(Color.Black)) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + g.DrawLine(p, r.X, r.Y, r.Right, r.Bottom); + g.DrawLine(p, r.Right, r.Y, r.X, r.Bottom); + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + } + } + } + if (m_SelectedImageCreated) + { + Image img = this.Image; + this.Image = bmp; + img.Dispose(); + } + else + this.Image = bmp; + m_SelectedImageCreated = true; + } + +#if FRAMEWORK20 + private ColorItem[][] _CustomThemeColors = null; + /// + /// Gets or sets the array of ColorItem objects that will be used as theme colors instead of built-in color palette. + /// See: http://www.devcomponents.com/kb2/?p=79 for instructions. + /// + [DefaultValue(null), Category("Colors"), Description("Array of ColorItem objects that will be used as theme colors instead of built-in color palette.")] + public ColorItem[][] CustomThemeColors + { + get { return _CustomThemeColors; } + set + { + _CustomThemeColors = value; + m_ColorsInitialized = false; + } + } +#endif + + /// + /// Gets collection of ColorItem[] arrays that represent themed colors. Each ColorItem[] array is used to represent single line of theme colors. + /// + /// Collection of ColorItem[] arrays. + protected virtual ArrayList GetThemeColors() + { + ArrayList colors = new ArrayList(); +#if FRAMEWORK20 + if (_CustomThemeColors == null || _CustomThemeColors.Length == 0) +#endif + { + eDotNetBarStyle effectiveStyle = EffectiveStyle; + if (effectiveStyle == eDotNetBarStyle.Office2010 || StyleManager.IsMetro(effectiveStyle)) + { + colors.Add(new ColorItem[] { + GetColorItem("FFFFFF"), + GetColorItem("000000"), + GetColorItem("EEECE1"), + GetColorItem("1F497D"), + GetColorItem("4F81BD"), + GetColorItem("C0504D"), + GetColorItem("9BBB59"), + GetColorItem("8064A2"), + GetColorItem("4BACC6"), + GetColorItem("F79646")}); + + colors.Add(new ColorItem[] { + GetColorItemTop("F2F2F2"), + GetColorItemTop("7F7F7F"), + GetColorItemTop("DDD9C3"), + GetColorItemTop("C6D9F0"), + GetColorItemTop("DBE5F1"), + GetColorItemTop("F2DCDB"), + GetColorItemTop("EBF1DD"), + GetColorItemTop("E5E0EC"), + GetColorItemTop("DBEEF3"), + GetColorItemTop("FDEADA")}); + + colors.Add(new ColorItem[] { + GetColorItemMiddle("D8D8D8"), + GetColorItemMiddle("595959"), + GetColorItemMiddle("C4BD97"), + GetColorItemMiddle("8DB3E2"), + GetColorItemMiddle("B8CCE4"), + GetColorItemMiddle("E5B9B7"), + GetColorItemMiddle("D7E3BC"), + GetColorItemMiddle("CCC1D9"), + GetColorItemMiddle("B7DDE8"), + GetColorItemMiddle("FBD5B5")}); + + colors.Add(new ColorItem[] { + GetColorItemMiddle("BFBFBF"), + GetColorItemMiddle("3F3F3F"), + GetColorItemMiddle("938953"), + GetColorItemMiddle("548DD4"), + GetColorItemMiddle("95B3D7"), + GetColorItemMiddle("D99694"), + GetColorItemMiddle("C3D69B"), + GetColorItemMiddle("B2A1C7"), + GetColorItemMiddle("92CDDC"), + GetColorItemMiddle("FAC08F")}); + + colors.Add(new ColorItem[] { + GetColorItemMiddle("A5A5A5"), + GetColorItemMiddle("262626"), + GetColorItemMiddle("494429"), + GetColorItemMiddle("17365D"), + GetColorItemMiddle("366092"), + GetColorItemMiddle("953734"), + GetColorItemMiddle("76923C"), + GetColorItemMiddle("5F497A"), + GetColorItemMiddle("31859B"), + GetColorItemMiddle("E36C09")}); + + colors.Add(new ColorItem[] { + GetColorItemBottom("7F7F7F"), + GetColorItemBottom("0C0C0C"), + GetColorItemBottom("1D1B10"), + GetColorItemBottom("0F243E"), + GetColorItemBottom("244061"), + GetColorItemBottom("632423"), + GetColorItemBottom("4F6128"), + GetColorItemBottom("3F3151"), + GetColorItemBottom("205867"), + GetColorItemBottom("974806")}); + } + else + { + colors.Add(new ColorItem[] { + GetColorItem("FFFFFF"), + GetColorItem("000000"), + GetColorItem("FAF3E8"), + GetColorItem("1F497D"), + GetColorItem("5C83B4"), + GetColorItem("C0504D"), + GetColorItem("9DBB61"), + GetColorItem("8066A0"), + GetColorItem("4BACC6"), + GetColorItem("F59D56")}); + + colors.Add(new ColorItem[] { + GetColorItemTop("D8D8D8"), + GetColorItemTop("7F7F7F"), + GetColorItemTop("BBB6AE"), + GetColorItemTop("C7D1DE"), + GetColorItemTop("D6E0EC"), + GetColorItemTop("EFD3D2"), + GetColorItemTop("E6EED7"), + GetColorItemTop("DFD8E7"), + GetColorItemTop("D2EAF0"), + GetColorItemTop("FCE6D4")}); + + colors.Add(new ColorItem[] { + GetColorItemMiddle("BFBFBF"), + GetColorItemMiddle("727272"), + GetColorItemMiddle("A29D96"), + GetColorItemMiddle("8FA4BE"), + GetColorItemMiddle("ADC1D9"), + GetColorItemMiddle("DFA7A6"), + GetColorItemMiddle("CEDDB0"), + GetColorItemMiddle("BFB2CF"), + GetColorItemMiddle("A5D5E2"), + GetColorItemMiddle("FACEAA")}); + + colors.Add(new ColorItem[] { + GetColorItemMiddle("A5A5A5"), + GetColorItemMiddle("595959"), + GetColorItemMiddle("7D7974"), + GetColorItemMiddle("57769D"), + GetColorItemMiddle("84A2C6"), + GetColorItemMiddle("CF7B79"), + GetColorItemMiddle("B5CC88"), + GetColorItemMiddle("9F8CB7"), + GetColorItemMiddle("78C0D4"), + GetColorItemMiddle("F7B580")}); + + colors.Add(new ColorItem[] { + GetColorItemMiddle("8C8C8C"), + GetColorItemMiddle("3F3F3F"), + GetColorItemMiddle("575551"), + GetColorItemMiddle("17365D"), + GetColorItemMiddle("456287"), + GetColorItemMiddle("903C39"), + GetColorItemMiddle("758C48"), + GetColorItemMiddle("604C78"), + GetColorItemMiddle("388194"), + GetColorItemMiddle("B77540")}); + + colors.Add(new ColorItem[] { + GetColorItemBottom("7F7F7F"), + GetColorItemBottom("262626"), + GetColorItemBottom("3E3C3A"), + GetColorItemBottom("0F243E"), + GetColorItemBottom("2E415A"), + GetColorItemBottom("602826"), + GetColorItemBottom("4E5D30"), + GetColorItemBottom("403350"), + GetColorItemBottom("255663"), + GetColorItemBottom("7A4E2B")}); + } + } +#if FRAMEWORK20 + else + colors.AddRange(_CustomThemeColors); +#endif + + return colors; + } + + /// + /// Returns an array that represents the standard colors. Usually instances of ColorItem are included. + /// + /// ArrayList containing objects that describe standard colors. + protected virtual ArrayList GetStandardColors() + { + ArrayList colors = new ArrayList(); +#if FRAMEWORK20 + if (_CustomStandardColors == null || _CustomStandardColors.Length == 0) +#endif + { + eDotNetBarStyle effectiveStyle = EffectiveStyle; + if (effectiveStyle == eDotNetBarStyle.Office2010 || StyleManager.IsMetro(effectiveStyle)) + { + colors.Add(new ColorItem[] { + GetColorItem("C00000"), + GetColorItem("FF0000"), + GetColorItem("FFC000"), + GetColorItem("FFFF00"), + GetColorItem("92D050"), + GetColorItem("00B050"), + GetColorItem("00B0F0"), + GetColorItem("0070C0"), + GetColorItem("002060"), + GetColorItem("7030A0")}); + } + else + { + colors.Add(new ColorItem[] { + GetColorItem("BA1419"), + GetColorItem("ED1C24"), + GetColorItem("FFC20E"), + GetColorItem("FFF200"), + GetColorItem("9DDA4E"), + GetColorItem("22B14C"), + GetColorItem("00B7EF"), + GetColorItem("0072BC"), + GetColorItem("2F3699"), + GetColorItem("6F3198")}); + } + } +#if FRAMEWORK20 + else + colors.AddRange(_CustomStandardColors); +#endif + + return colors; + } +#if FRAMEWORK20 + private ColorItem[][] _CustomStandardColors = null; + /// + /// Gets or sets the array of ColorItem objects that will be used as standard colors instead of built-in color palette. + /// See: http://www.devcomponents.com/kb2/?p=79 for instructions. + /// + [DefaultValue(null), Category("Colors"), Description("Array of ColorItem objects that will be used as standard colors instead of built-in color palette.")] + public ColorItem[][] CustomStandardColors + { + get { return _CustomStandardColors; } + set + { + _CustomStandardColors = value; + m_ColorsInitialized = false; + } + } +#endif + + private ColorItem GetColorItem(string color) + { + ColorItem c = new ColorItem("", "", ColorScheme.GetColor(color)); + + return c; + } + + private ColorItem GetColorItemTop(string color) + { + ColorItem c = new ColorItem("", "", ColorScheme.GetColor(color)); + eColorItemBorder border = eColorItemBorder.Top | eColorItemBorder.Left | eColorItemBorder.Right; + c.Border = border; + return c; + } + + private ColorItem GetColorItemMiddle(string color) + { + ColorItem c = new ColorItem("", "", ColorScheme.GetColor(color)); + eColorItemBorder border = eColorItemBorder.Left | eColorItemBorder.Right; + c.Border = border; + return c; + } + + private ColorItem GetColorItemBottom(string color) + { + ColorItem c = new ColorItem("", "", ColorScheme.GetColor(color)); + eColorItemBorder border = eColorItemBorder.Bottom | eColorItemBorder.Left | eColorItemBorder.Right; + c.Border = border; + return c; + } + + private void LoadResources() + { + if (!m_Localized) + { + if (this.GetOwner() != null) + m_Localized = true; + using (LocalizationManager lm = new LocalizationManager(this.GetOwner() as IOwnerLocalize)) + { + string s = lm.GetLocalizedString(LocalizationKeys.ColorPickerThemeColorsLabel); + if (s != "") m_ThemeColorsLabel = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerStandardColorsLabel); + if (s != "") m_StandardColorsLabel = s; + s = lm.GetLocalizedString(LocalizationKeys.ColorPickerMoreColorsMenuItem); + if (s != "") m_MoreColorsLabel = s; + } + } + } + + /// + /// Invokes SelectedColorChanged event. + /// + protected virtual void OnSelectedColorChanged(EventArgs e) + { + if (SelectedColorChanged != null) + SelectedColorChanged(this, e); + DotNetBarManager manager = this.GetOwner() as DotNetBarManager; + if (manager != null) + manager.InvokeColorPickerSelectedColorChanged(this); + } + + /// + /// Indicates whether button should popup when clicked automatically. + /// + protected override bool ShouldAutoExpandOnClick + { + get { return base.ShouldAutoExpandOnClick || m_SelectedColor.IsEmpty; } + } + + protected override void OnCommandChanged() + { + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ColorPickers/ColorSelectionPreviewControl.cs b/PROMS/DotNetBar Source Code/ColorPickers/ColorSelectionPreviewControl.cs new file mode 100644 index 00000000..e92f1570 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPickers/ColorSelectionPreviewControl.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.ColorPickerItem +{ + [ToolboxItem(false)] + internal class ColorSelectionPreviewControl : System.Windows.Forms.UserControl + { + #region Private Variables + private Color m_CurrentColor = Color.Black; + private Color m_NewColor = Color.Empty; + #endregion + + #region Constructor + public ColorSelectionPreviewControl() + { + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + } + #endregion + + #region Internal Implementation + protected override void OnPaint(PaintEventArgs e) + { + if(this.BackColor == Color.Transparent) + { + base.OnPaintBackground(e); + } + + Graphics g = e.Graphics; + + Rectangle r = this.ClientRectangle; + + g.FillRectangle(SystemBrushes.Control, r); + + if(!m_NewColor.IsEmpty) + { + using(SolidBrush brush = new SolidBrush(m_NewColor)) + g.FillRectangle(brush, r.X, r.Y, r.Width, r.Height / 2); + } + + if(!m_CurrentColor.IsEmpty) + { + using(SolidBrush brush = new SolidBrush(m_CurrentColor)) + g.FillRectangle(brush, r.X, r.Y + r.Height / 2, r.Width, r.Height / 2); + } + + using(Pen pen=new Pen(Color.Black)) + { + r.Width--; + r.Height--; + g.DrawRectangle(pen, r); + + g.DrawLine(pen, r.X, r.Y + r.Height / 2, r.Right, r.Y + r.Height / 2); + } + } + + public Color NewColor + { + get { return m_NewColor;} + set + { + m_NewColor = value; + this.Invalidate(); + } + } + + public Color CurrentColor + { + get { return m_CurrentColor;} + set + { + m_CurrentColor = value; + this.Invalidate(); + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ColorPickers/CombCell.cs b/PROMS/DotNetBar Source Code/ColorPickers/CombCell.cs new file mode 100644 index 00000000..854a0d5b --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPickers/CombCell.cs @@ -0,0 +1,100 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.ColorPickers +{ + internal class CombCell + { + #region Private Variables + private Color m_Color = Color.Empty; + private Point[] m_HexagonPoints=new Point[6]; + private const float Tan30 = 0.57735026918962F; + private bool m_MouseOver = false; + private bool m_Selected = false; + private Rectangle m_Bounds = Rectangle.Empty; + #endregion + + #region Internal Implementation + public Color Color + { + get { return m_Color; } + set { m_Color=value; } + } + + public void SetPosition(float x, float y, int nWidth) + { + float nSideLength = (float)((float)nWidth * Tan30); + m_HexagonPoints[0] = new Point((int)Math.Floor(x - (float)(nWidth / 2)), (int)Math.Floor(y - (nSideLength / 2))-1); + m_HexagonPoints[1] = new Point((int)Math.Floor((float)x), (int)Math.Floor(y - (float)(nWidth / 2))-1); + m_HexagonPoints[2] = new Point((int)Math.Floor(x + (float)(nWidth / 2)), (int)Math.Floor(y - (nSideLength / 2))-1); + m_HexagonPoints[3] = new Point((int)Math.Floor(x + (float)(nWidth / 2)), (int)Math.Floor(y + (nSideLength / 2)) + 1); + m_HexagonPoints[4] = new Point((int)Math.Floor((float)x), (int)Math.Floor(y + (float)(nWidth / 2)) + 1); + m_HexagonPoints[5] = new Point((int)Math.Floor(x - (float)(nWidth / 2)), (int)Math.Floor(y + (nSideLength / 2)) + 1); + + GraphicsPath path = new GraphicsPath(); + path.AddPolygon(m_HexagonPoints); + m_Bounds = Rectangle.Round(path.GetBounds()); + m_Bounds.Inflate(2, 2); + } + + public void Draw(Graphics g) + { + GraphicsPath path = new GraphicsPath(); + path.AddPolygon(m_HexagonPoints); + path.CloseAllFigures(); + + using (SolidBrush brush = new SolidBrush(m_Color)) + { + g.FillPath(brush, path); + } + + if (m_MouseOver || m_Selected) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + using (Pen pen = new Pen(Color.FromArgb(41, 92, 150), 2)) + g.DrawPath(pen, path); + using (Pen pen = new Pen(Color.FromArgb(149, 178, 239), 1)) + g.DrawPath(pen, path); + g.SmoothingMode = sm; + } + + path.Dispose(); + } + + public void Draw(Graphics g, Color c) + { + GraphicsPath path = new GraphicsPath(); + path.AddPolygon(m_HexagonPoints); + using (SolidBrush brush = new SolidBrush(c)) + { + g.FillPath(brush, path); + } + path.Dispose(); + } + + public Rectangle Bounds + { + get + { + return m_Bounds; + } + } + + public bool MouseOver + { + get { return m_MouseOver; } + set { m_MouseOver = value; } + } + + public bool Selected + { + get { return m_Selected; } + set { m_Selected = value; } + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/ColorPickers/CustomColorBlender.cs b/PROMS/DotNetBar Source Code/ColorPickers/CustomColorBlender.cs new file mode 100644 index 00000000..2c413af1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPickers/CustomColorBlender.cs @@ -0,0 +1,340 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Drawing.Imaging; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.ColorPickers +{ + /// + /// Represents custom color blend selection control. + /// + [ToolboxItem(true), DefaultEvent("SelectedColorChanged"), DefaultProperty("SelectedColor"), ToolboxBitmap(typeof(CustomColorBlender), "ColorPickerItem.CustomColorBlender.ico")] + public class CustomColorBlender : System.Windows.Forms.Control + { + #region Events + /// + /// Occurs when SelectedColor has changed. + /// + public event EventHandler SelectedColorChanged; + /// + /// Raises SelectedColorChanged event. + /// + /// Provides event arguments. + protected virtual void OnSelectedColorChanged(EventArgs e) + { + EventHandler handler = SelectedColorChanged; + if (handler != null) + handler(this, e); + } + #endregion + + #region Private Variables + private Bitmap m_ColorBlendBitmap = null; + private Point m_SelectedPoint = new Point(-1, -1); + #endregion + + #region Constructor, Dispose + public CustomColorBlender() + { + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (m_ColorBlendBitmap != null) + { + m_ColorBlendBitmap.Dispose(); + m_ColorBlendBitmap = null; + } + } + base.Dispose(disposing); + } + + private void CreateBlendBitmap() + { + int stripeCount = 6; + Rectangle clientRect = this.ClientRectangle; + + int stripeWidth = clientRect.Width / stripeCount; + int ySteps=127; + int xStart = clientRect.X; + Bitmap bmp = new Bitmap(clientRect.Width, clientRect.Height, PixelFormat.Format24bppRgb); + using (Graphics graph = Graphics.FromImage(bmp)) + { + graph.FillRectangle(SystemBrushes.Control, clientRect); + + for (int stripe = 0; stripe < stripeCount; stripe++) + { + // Calculate X steps and point Width + int pointWidth = 4; + int colorStepX = 255 / (stripeWidth / pointWidth); + + if (colorStepX<1) + { + pointWidth = stripeWidth / 255; + colorStepX = 1; + } + + int pointHeight = 4; + int colorStepY = ySteps / (clientRect.Height / pointHeight); + + if (colorStepY<1) + { + pointHeight = clientRect.Height / ySteps; + colorStepY = 1; + } + + int x = xStart; + int y = clientRect.Y; + int r = 0, g = 0, b = 0; + int rXInc = 0, gXInc = 0, bXInc = 0; + int rYInc = 0, gYInc = 0, bYInc = 0; + + if (stripe == 0) + { + r = 255; + g = 0; + b = 0; + gXInc = colorStepX; + } + else if (stripe == 1) + { + r = 255; + g = 255; + b = 0; + rXInc = - colorStepX; + } + else if (stripe == 2) + { + r = 0; + g = 255; + b = 0; + bXInc = colorStepX; + } + else if (stripe == 3) + { + r = 0; + g = 255; + b = 255; + gXInc = -colorStepX; + } + else if (stripe == 4) + { + r = 0; + g = 0; + b = 255; + rXInc = colorStepX; + } + else if (stripe == 5) + { + r = 255; + g = 0; + b = 255; + bXInc = -colorStepX; + } + + for (int i = 0; i < stripeWidth; i += pointWidth) + { + int ry = r, gy = g, by = b; + rYInc = 127-r; + gYInc = 127-g; + bYInc = 127-b; + + for (int j = clientRect.Y; j < clientRect.Height; j += pointHeight) + { + using (SolidBrush brush = new SolidBrush(Color.FromArgb(ry, gy, by))) + graph.FillRectangle(brush, new Rectangle(x, y, pointWidth, pointHeight)); + y += pointHeight; + + ry = r + (int)(rYInc * ((float)j / (float)clientRect.Height)); + gy = g + (int)(gYInc * ((float)j / (float)clientRect.Height)); + by = b + (int)(bYInc * ((float)j / (float)clientRect.Height)); + } + + x += pointWidth; + y = clientRect.Y; + r += rXInc; + g += gXInc; + b += bXInc; + + } + xStart = x; + if (stripe == 5) + break; + } + } + + if (m_ColorBlendBitmap != null) + m_ColorBlendBitmap.Dispose(); + m_ColorBlendBitmap = bmp; + } + + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + + if (!this.BackColor.IsEmpty && this.BackColor != Color.Transparent) + { + using (SolidBrush brush = new SolidBrush(this.BackColor)) + g.FillRectangle(brush, -1, -1, this.Width + 1, this.Height + 1); + } + + if (this.BackColor == Color.Transparent || this.BackgroundImage != null) + { + base.OnPaintBackground(e); + } + + if (m_ColorBlendBitmap == null) return; + + g.DrawImageUnscaled(m_ColorBlendBitmap, 0, 0); + + if (m_SelectedPoint.X >= 0 && m_SelectedPoint.Y >= 0) + { + Color clr = Color.White; + using (SolidBrush brush = new SolidBrush(clr)) + { + Rectangle r = new Rectangle(m_SelectedPoint.X - 2, m_SelectedPoint.Y - 9, 3, 5); + g.FillRectangle(brush, r); + r.Offset(0, 10); + g.FillRectangle(brush, r); + r = new Rectangle(m_SelectedPoint.X - 8, m_SelectedPoint.Y - 3, 5, 3); + g.FillRectangle(brush, r); + r.Offset(10, 0); + g.FillRectangle(brush, r); + } + + } + + base.OnPaint(e); + } + + private void SetSelectedPoint(Point p) + { + Rectangle r = this.ClientRectangle; + + if (m_ColorBlendBitmap != null) + { + r.Width = m_ColorBlendBitmap.Width; + r.Height = m_ColorBlendBitmap.Height; + } + + if (p.X < 0) + p.X = 0; + if (p.Y < 0) + p.Y = 0; + if (p.X > r.Right) + p.X = r.Right - 1; + if (p.Y > r.Bottom) + p.Y = r.Bottom - 1; + + if (p != m_SelectedPoint) + { + if (m_SelectedPoint.X >= 0 && m_SelectedPoint.Y >= 0) + { + Rectangle inv = new Rectangle(m_SelectedPoint, Size.Empty); + inv.Inflate(10, 10); + this.Invalidate(inv); + } + m_SelectedPoint = p; + if (m_SelectedPoint.X >= 0 && m_SelectedPoint.Y >= 0) + { + Rectangle inv = new Rectangle(m_SelectedPoint, Size.Empty); + inv.Inflate(10, 10); + this.Invalidate(inv); + } + OnSelectedColorChanged(EventArgs.Empty); + } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + SetSelectedPoint(new Point(e.X, e.Y)); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + if (e.Button == MouseButtons.Left) + { + int x = e.X; + int y = e.Y; + if(x<0) + x = 0; + if(x>=this.ClientRectangle.Width) + x = this.ClientRectangle.Width - 1; + if(y<0) + y = 0; + if(y>=this.ClientRectangle.Height) + y = this.ClientRectangle.Height - 1; + SetSelectedPoint(new Point(x, y)); + } + } + + protected override void OnResize(EventArgs e) + { + CreateBlendBitmap(); + base.OnResize(e); + } + + /// + /// Gets or sets the color selected by the control. Color that is assigned must be visible on the face of the control otherwise the SelectedColor will be set to Color.Empty + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color SelectedColor + { + get + { + if (m_SelectedPoint.X < 0 || m_SelectedPoint.Y < 0 || m_ColorBlendBitmap==null) + return Color.Empty; + return m_ColorBlendBitmap.GetPixel(m_SelectedPoint.X, m_SelectedPoint.Y); + } + set + { + if (value.Equals(Color.Transparent) || value.IsEmpty) + { + if (!m_SelectedPoint.IsEmpty) + { + m_SelectedPoint = new Point(-1, -1); + this.Invalidate(); + OnSelectedColorChanged(EventArgs.Empty); + } + } + else + { + Point colorPoint = FindColorPoint(value); + if (m_SelectedPoint != colorPoint) + { + m_SelectedPoint = colorPoint; + this.Invalidate(); + OnSelectedColorChanged(EventArgs.Empty); + } + } + } + } + private Point FindColorPoint(Color value) + { + if (m_ColorBlendBitmap == null || value.IsEmpty || value == Color.Transparent) return new Point(-1, -1); + for (int x = 0; x < m_ColorBlendBitmap.Width; x++) + { + for (int y = 0; y < m_ColorBlendBitmap.Height; y++) + { + Color color = m_ColorBlendBitmap.GetPixel(x, y); + if (Math.Abs(color.R-value.R)<=30 && Math.Abs(color.G-value.G)<=30 && Math.Abs(color.B-value.B)<=30) + return new Point(x, y); + } + } + return new Point(-1, -1); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ColorPickers/CustomColorBlender.ico b/PROMS/DotNetBar Source Code/ColorPickers/CustomColorBlender.ico new file mode 100644 index 00000000..849d5562 Binary files /dev/null and b/PROMS/DotNetBar Source Code/ColorPickers/CustomColorBlender.ico differ diff --git a/PROMS/DotNetBar Source Code/ColorPickers/CustomColorDialog.cs b/PROMS/DotNetBar Source Code/ColorPickers/CustomColorDialog.cs new file mode 100644 index 00000000..9ba808bb --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorPickers/CustomColorDialog.cs @@ -0,0 +1,1079 @@ +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Data; +using DevComponents.DotNetBar.Controls; +using DevComponents.Editors; +using DevComponents.DotNetBar.ColorPickers; + +namespace DevComponents.DotNetBar.ColorPickerItem +{ + [ToolboxItem(false)] + internal class CustomColorDialog : DevComponents.DotNetBar.OfficeForm + { + #region Private Variables + internal ButtonX buttonOK; + internal ButtonX buttonCancel; + internal System.Windows.Forms.Label labelNewColor; + internal System.Windows.Forms.Label labelCurrentColor; + + private Color m_CurrentColor = Color.Black; + private Color m_NewColor = Color.Empty; + private ColorCombControl colorCombControl1; + internal System.Windows.Forms.Label labelStandardColors; + internal System.Windows.Forms.Label labelCustomColors; + internal System.Windows.Forms.Label labelGreen; + internal System.Windows.Forms.Label labelBlue; + private DevComponents.DotNetBar.TabControl tabControl2; + internal DevComponents.DotNetBar.TabItem tabItemStandard; + private DevComponents.DotNetBar.TabControlPanel tabControlPanel1; + internal DevComponents.DotNetBar.TabItem tabItemCustom; + private DevComponents.DotNetBar.TabControlPanel tabControlPanel2; + private CustomColorBlender customColorBlender3; + internal System.Windows.Forms.Label labelRed; + internal System.Windows.Forms.Label labelColorModel; + internal ComboBoxEx comboColorModel; +#if FRAMEWORK20 + private IntegerInput numericBlue; + private IntegerInput numericGreen; + private IntegerInput numericRed; +#else + private System.Windows.Forms.NumericUpDown numericBlue; + private System.Windows.Forms.NumericUpDown numericGreen; + private System.Windows.Forms.NumericUpDown numericRed; +#endif + private ColorContrastControl colorContrastControl1; + private ColorSelectionPreviewControl colorSelectionPreview; + private System.ComponentModel.IContainer components; + #endregion + + #region Constructor, Dispose + public CustomColorDialog() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + #endregion + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.labelStandardColors = new System.Windows.Forms.Label(); + this.colorCombControl1 = new ColorCombControl(); + this.labelBlue = new System.Windows.Forms.Label(); + this.labelGreen = new System.Windows.Forms.Label(); +#if (FRAMEWORK20) + this.numericBlue = new IntegerInput(); + this.numericGreen = new IntegerInput(); + this.numericRed = new IntegerInput(); +#else + this.numericBlue = new System.Windows.Forms.NumericUpDown(); + this.numericGreen = new System.Windows.Forms.NumericUpDown(); + this.numericRed = new System.Windows.Forms.NumericUpDown(); +#endif + this.labelCustomColors = new System.Windows.Forms.Label(); + this.buttonOK = new ButtonX(); + this.buttonCancel = new ButtonX(); + this.labelNewColor = new System.Windows.Forms.Label(); + this.labelCurrentColor = new System.Windows.Forms.Label(); + this.tabControl2 = new DevComponents.DotNetBar.TabControl(); + this.tabControlPanel1 = new DevComponents.DotNetBar.TabControlPanel(); + this.tabItemStandard = new DevComponents.DotNetBar.TabItem(this.components); + this.tabControlPanel2 = new DevComponents.DotNetBar.TabControlPanel(); + this.colorContrastControl1 = new ColorContrastControl(); + this.customColorBlender3 = new CustomColorBlender(); + this.comboColorModel = new ComboBoxEx(); + this.labelRed = new System.Windows.Forms.Label(); + this.labelColorModel = new System.Windows.Forms.Label(); + this.tabItemCustom = new DevComponents.DotNetBar.TabItem(this.components); + this.colorSelectionPreview = new ColorSelectionPreviewControl(); + ((System.ComponentModel.ISupportInitialize)(this.numericBlue)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericGreen)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericRed)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.tabControl2)).BeginInit(); + this.tabControl2.SuspendLayout(); + this.tabControlPanel1.SuspendLayout(); + this.tabControlPanel2.SuspendLayout(); + this.SuspendLayout(); + // + // label3 + // + this.labelStandardColors.BackColor = System.Drawing.Color.Transparent; + this.labelStandardColors.Dock = System.Windows.Forms.DockStyle.Top; + this.labelStandardColors.Location = new System.Drawing.Point(1, 1); + this.labelStandardColors.Name = "labelStandardColors"; + this.labelStandardColors.Size = new System.Drawing.Size(224, 19); + this.labelStandardColors.TabIndex = 1; + this.labelStandardColors.Text = " Colors:"; + this.labelStandardColors.TextAlign = System.Drawing.ContentAlignment.BottomLeft; + // + // colorCombControl1 + // + this.colorCombControl1.BackColor = System.Drawing.Color.Transparent; + this.colorCombControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.colorCombControl1.Location = new System.Drawing.Point(1, 20); + this.colorCombControl1.Name = "colorCombControl1"; + this.colorCombControl1.Size = new System.Drawing.Size(224, 267); + this.colorCombControl1.TabIndex = 0; + this.colorCombControl1.SelectedColorChanged += new System.EventHandler(this.colorCombControl1_SelectedColorChanged); + // + // label8 + // + this.labelBlue.BackColor = System.Drawing.Color.Transparent; + this.labelBlue.Location = new System.Drawing.Point(4, 256); + this.labelBlue.Name = "labelBlue"; + this.labelBlue.Size = new System.Drawing.Size(90, 16); + this.labelBlue.TabIndex = 10; + this.labelBlue.Text = "&Blue:"; + // + // label7 + // + this.labelGreen.BackColor = System.Drawing.Color.Transparent; + this.labelGreen.Location = new System.Drawing.Point(4, 232); + this.labelGreen.Name = "labelGreen"; + this.labelGreen.Size = new System.Drawing.Size(90, 16); + this.labelGreen.TabIndex = 8; + this.labelGreen.Text = "&Green:"; + // + // numericBlue + // + this.numericBlue.Location = new System.Drawing.Point(98, 260); +#if (FRAMEWORK20) + this.numericBlue.MaxValue = 255; + this.numericBlue.MinValue = 0; + this.numericBlue.ShowUpDown = true; + this.numericBlue.AllowEmptyState = false; +#else + this.numericBlue.Maximum = new System.Decimal(new int[] { + 255, + 0, + 0, + 0}); +#endif + this.numericBlue.Name = "numericBlue"; + this.numericBlue.Size = new System.Drawing.Size(47, 20); + this.numericBlue.TabIndex = 11; + this.numericBlue.ValueChanged += new System.EventHandler(this.numericRGBValueChanged); + // + // numericGreen + // + this.numericGreen.Location = new System.Drawing.Point(98, 236); +#if (FRAMEWORK20) + this.numericGreen.MaxValue = 255; + this.numericGreen.MinValue = 0; + this.numericGreen.ShowUpDown = true; + this.numericGreen.AllowEmptyState = false; +#else + this.numericGreen.Maximum = new System.Decimal(new int[] { + 255, + 0, + 0, + 0}); +#endif + this.numericGreen.Name = "numericGreen"; + this.numericGreen.Size = new System.Drawing.Size(47, 20); + this.numericGreen.TabIndex = 9; + this.numericGreen.ValueChanged += new System.EventHandler(this.numericRGBValueChanged); + // + // numericRed + // + this.numericRed.Location = new System.Drawing.Point(98, 212); +#if (FRAMEWORK20) + this.numericRed.MaxValue = 255; + this.numericRed.MinValue = 0; + this.numericRed.ShowUpDown = true; + this.numericRed.AllowEmptyState = false; +#else + this.numericRed.Maximum = new System.Decimal(new int[] { + 255, + 0, + 0, + 0}); +#endif + this.numericRed.Name = "numericRed"; + this.numericRed.Size = new System.Drawing.Size(47, 20); + this.numericRed.TabIndex = 7; + this.numericRed.ValueChanged += new System.EventHandler(this.numericRGBValueChanged); + // + // label4 + // + this.labelCustomColors.BackColor = System.Drawing.Color.Transparent; + this.labelCustomColors.Dock = System.Windows.Forms.DockStyle.Top; + this.labelCustomColors.Location = new System.Drawing.Point(1, 1); + this.labelCustomColors.Name = "labelCustomColors"; + this.labelCustomColors.Size = new System.Drawing.Size(224, 20); + this.labelCustomColors.TabIndex = 2; + this.labelCustomColors.Text = " Colors:"; + this.labelCustomColors.TextAlign = System.Drawing.ContentAlignment.BottomLeft; + // + // button1 + // + this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.buttonOK.Location = new System.Drawing.Point(242, 6); + this.buttonOK.ColorTable = eButtonColor.OrangeWithBackground; + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(74, 24); + this.buttonOK.TabIndex = 1; + this.buttonOK.Text = "OK"; + // + // button2 + // + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonCancel.Location = new System.Drawing.Point(242, 36); + this.buttonCancel.ColorTable = eButtonColor.OrangeWithBackground; + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(74, 24); + this.buttonCancel.TabIndex = 2; + this.buttonCancel.Text = "Cancel"; + // + // label1 + // + this.labelNewColor.Location = new System.Drawing.Point(246, 232); + this.labelNewColor.Name = "labelNewColor"; + this.labelNewColor.Size = new System.Drawing.Size(70, 12); + this.labelNewColor.TabIndex = 4; + this.labelNewColor.Text = "New"; + this.labelNewColor.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label2 + // + this.labelCurrentColor.Location = new System.Drawing.Point(246, 306); + this.labelCurrentColor.Name = "labelCurrentColor"; + this.labelCurrentColor.Size = new System.Drawing.Size(70, 16); + this.labelCurrentColor.TabIndex = 5; + this.labelCurrentColor.Text = "Current"; + this.labelCurrentColor.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // tabControl2 + // + this.tabControl2.BackColor = Color.Transparent; + this.tabControl2.CanReorderTabs = true; + this.tabControl2.ColorScheme.TabBackground = Color.Transparent; + this.tabControl2.Controls.Add(this.tabControlPanel2); + this.tabControl2.Controls.Add(this.tabControlPanel1); + this.tabControl2.FixedTabSize = new System.Drawing.Size(60, 0); + this.tabControl2.Location = new System.Drawing.Point(8, 8); + this.tabControl2.Name = "tabControl2"; + this.tabControl2.SelectedTabFont = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold); + this.tabControl2.SelectedTabIndex = 0; + this.tabControl2.Size = new System.Drawing.Size(226, 314); + this.tabControl2.Style = DevComponents.DotNetBar.eTabStripStyle.VS2005; + this.tabControl2.TabIndex = 6; + this.tabControl2.TabLayoutType = DevComponents.DotNetBar.eTabLayoutType.FixedWithNavigationBox; + this.tabControl2.Tabs.Add(this.tabItemStandard); + this.tabControl2.Tabs.Add(this.tabItemCustom); + this.tabControl2.ThemeAware = true; + // + // tabControlPanel1 + // + this.tabControlPanel1.Controls.Add(this.colorCombControl1); + this.tabControlPanel1.Controls.Add(this.labelStandardColors); + this.tabControlPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControlPanel1.DockPadding.All = 1; + this.tabControlPanel1.Location = new System.Drawing.Point(0, 26); + this.tabControlPanel1.Name = "tabControlPanel1"; + this.tabControlPanel1.Size = new System.Drawing.Size(226, 288); + this.tabControlPanel1.Style.BackColor1.Color = System.Drawing.SystemColors.Control; + this.tabControlPanel1.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; + this.tabControlPanel1.Style.BorderSide = ((DevComponents.DotNetBar.eBorderSide)(((DevComponents.DotNetBar.eBorderSide.Left | DevComponents.DotNetBar.eBorderSide.Right) + | DevComponents.DotNetBar.eBorderSide.Bottom))); + this.tabControlPanel1.Style.GradientAngle = 90; + this.tabControlPanel1.TabIndex = 1; + this.tabControlPanel1.TabItem = this.tabItemStandard; + this.tabControlPanel1.ThemeAware = true; + // + // tabItem1 + // + this.tabItemStandard.AttachedControl = this.tabControlPanel1; + this.tabItemStandard.CloseButtonBounds = new System.Drawing.Rectangle(0, 0, 0, 0); + this.tabItemStandard.Name = "tabItemStandard"; + this.tabItemStandard.Text = "Standard"; + // + // tabControlPanel2 + // + this.tabControlPanel2.Controls.Add(this.colorContrastControl1); + this.tabControlPanel2.Controls.Add(this.numericGreen); + this.tabControlPanel2.Controls.Add(this.labelGreen); + this.tabControlPanel2.Controls.Add(this.numericRed); + this.tabControlPanel2.Controls.Add(this.customColorBlender3); + this.tabControlPanel2.Controls.Add(this.comboColorModel); + this.tabControlPanel2.Controls.Add(this.labelRed); + this.tabControlPanel2.Controls.Add(this.labelColorModel); + this.tabControlPanel2.Controls.Add(this.numericBlue); + this.tabControlPanel2.Controls.Add(this.labelBlue); + this.tabControlPanel2.Controls.Add(this.labelCustomColors); + this.tabControlPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControlPanel2.DockPadding.All = 1; + this.tabControlPanel2.Location = new System.Drawing.Point(0, 26); + this.tabControlPanel2.Name = "tabControlPanel2"; + this.tabControlPanel2.Size = new System.Drawing.Size(226, 288); + this.tabControlPanel2.Style.BackColor1.Color = System.Drawing.SystemColors.Control; + this.tabControlPanel2.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; + this.tabControlPanel2.Style.BorderSide = ((DevComponents.DotNetBar.eBorderSide)(((DevComponents.DotNetBar.eBorderSide.Left | DevComponents.DotNetBar.eBorderSide.Right) + | DevComponents.DotNetBar.eBorderSide.Bottom))); + this.tabControlPanel2.Style.GradientAngle = 90; + this.tabControlPanel2.TabIndex = 2; + this.tabControlPanel2.TabItem = this.tabItemCustom; + this.tabControlPanel2.ThemeAware = true; + // + // colorContrastControl1 + // + this.colorContrastControl1.BackColor = System.Drawing.Color.Transparent; + this.colorContrastControl1.Location = new System.Drawing.Point(188, 28); + this.colorContrastControl1.Name = "colorContrastControl1"; + this.colorContrastControl1.SelectedColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(255)), ((System.Byte)(255))); + this.colorContrastControl1.Size = new System.Drawing.Size(32, 152); + this.colorContrastControl1.TabIndex = 12; + this.colorContrastControl1.SelectedColorChanged += new System.EventHandler(this.colorContrastControl1_SelectedColorChanged); + // + // customColorBlender3 + // + this.customColorBlender3.Location = new System.Drawing.Point(8, 28); + this.customColorBlender3.Name = "customColorBlender3"; + this.customColorBlender3.Size = new System.Drawing.Size(174, 152); + this.customColorBlender3.TabIndex = 3; + this.customColorBlender3.SelectedColorChanged += new System.EventHandler(this.customColorBlender3_SelectedColorChanged); + // + // comboColorModel + // + this.comboColorModel.DrawMode = DrawMode.OwnerDrawFixed; + this.comboColorModel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboColorModel.Items.AddRange(new object[] { + "RGB"}); + this.comboColorModel.Location = new System.Drawing.Point(98, 188); + this.comboColorModel.Name = "comboColorModel"; + this.comboColorModel.Size = new System.Drawing.Size(89, 21); + this.comboColorModel.TabIndex = 5; + // + // label9 + // + this.labelRed.BackColor = System.Drawing.Color.Transparent; + this.labelRed.Location = new System.Drawing.Point(4, 212); + this.labelRed.Name = "labelRed"; + this.labelRed.Size = new System.Drawing.Size(90, 16); + this.labelRed.TabIndex = 6; + this.labelRed.Text = "&Red:"; + // + // label10 + // + this.labelColorModel.BackColor = System.Drawing.Color.Transparent; + this.labelColorModel.Location = new System.Drawing.Point(4, 192); + this.labelColorModel.Name = "labelColorModel"; + this.labelColorModel.Size = new System.Drawing.Size(90, 16); + this.labelColorModel.TabIndex = 4; + this.labelColorModel.Text = "Color Mo&del:"; + // + // tabItem2 + // + this.tabItemCustom.AttachedControl = this.tabControlPanel2; + this.tabItemCustom.CloseButtonBounds = new System.Drawing.Rectangle(0, 0, 0, 0); + this.tabItemCustom.Name = "tabItemCustom"; + this.tabItemCustom.Text = "Custom"; + // + // colorSelectionPreview + // + this.colorSelectionPreview.CurrentColor = System.Drawing.Color.Black; + this.colorSelectionPreview.Location = new System.Drawing.Point(252, 252); + this.colorSelectionPreview.Name = "colorSelectionPreview"; + this.colorSelectionPreview.NewColor = System.Drawing.Color.Empty; + this.colorSelectionPreview.Size = new System.Drawing.Size(56, 48); + this.colorSelectionPreview.TabIndex = 7; + // + // CustomColorDialog + // + this.AcceptButton = this.buttonOK; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.CancelButton = this.buttonCancel; + this.ClientSize = new System.Drawing.Size(324, 326); + this.Controls.Add(this.colorSelectionPreview); + this.Controls.Add(this.tabControl2); + this.Controls.Add(this.labelCurrentColor); + this.Controls.Add(this.labelNewColor); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonOK); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CustomColorDialog"; + this.ShowInTaskbar = false; + this.Text = "Colors"; + this.Load += new System.EventHandler(this.Form1_Load); + ((System.ComponentModel.ISupportInitialize)(this.numericBlue)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericGreen)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericRed)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.tabControl2)).EndInit(); + this.tabControl2.ResumeLayout(false); + this.tabControlPanel1.ResumeLayout(false); + this.tabControlPanel2.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + #region Internal Implementation + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + Size fixedSize = tabControl2.FixedTabSize; + using (Graphics g = this.CreateGraphics()) + { + System.Drawing.Size s = TextDrawing.MeasureString(g, tabItemCustom.Text, this.Font); + System.Drawing.Size s1 = TextDrawing.MeasureString(g, tabItemStandard.Text, this.Font); + fixedSize.Width = Math.Max(fixedSize.Width, s.Width + 5); + fixedSize.Width = Math.Max(fixedSize.Width, s1.Width + 5); + } + tabControl2.FixedTabSize = fixedSize; + if (fixedSize.Width > tabControl2.Width / 2) + { + tabControl2.FixedTabSize = Size.Empty; + } + } + internal void SetStyle(eDotNetBarStyle style) + { + if (BarFunctions.IsOffice2007Style(style)) + { + this.EnableCustomStyle = true; + tabControl2.Style = eTabStripStyle.Office2007Dock; + } + else + { + this.EnableCustomStyle = false; + this.tabControl2.Style = DevComponents.DotNetBar.eTabStripStyle.VS2005; + } + + buttonCancel.Style = style; + buttonOK.Style = style; + + tabControl2.BackColor = Color.Transparent; + tabControl2.ColorScheme.TabBackground = Color.Transparent; + tabControl2.ColorScheme.TabBackground2 = Color.Empty; + } + private void colorCombControl1_SelectedColorChanged(object sender, System.EventArgs e) + { + SetNewColor(colorCombControl1.SelectedColor); + colorContrastControl1.SelectedColor = colorCombControl1.SelectedColor; + } + + private void customColorBlender3_SelectedColorChanged(object sender, System.EventArgs e) + { + colorContrastControl1.SelectedColor = customColorBlender3.SelectedColor; + SetNewColor(colorContrastControl1.SelectedColor); + } + + private bool m_SettingColor = false; + private void SetNewColor(Color color) + { + if(m_SettingColor) return; + m_SettingColor = true; + try + { + m_NewColor = color; + colorSelectionPreview.NewColor = color; + + numericRed.Value = m_NewColor.R; + numericGreen.Value = m_NewColor.G; + numericBlue.Value = m_NewColor.B; + } + finally + { + m_SettingColor = false; + } + } + + private void Form1_Load(object sender, System.EventArgs e) + { + comboColorModel.SelectedIndex = 0; + } + + private void numericRGBValueChanged(object sender, System.EventArgs e) + { + SetNewColor(Color.FromArgb((int)numericRed.Value, (int)numericGreen.Value, (int)numericBlue.Value)); + } + + private void colorContrastControl1_SelectedColorChanged(object sender, System.EventArgs e) + { + SetNewColor(colorContrastControl1.SelectedColor); + } + + public Color CurrentColor + { + get { return m_CurrentColor;} + set + { + m_CurrentColor = value; + colorSelectionPreview.CurrentColor = value; + customColorBlender3.SelectedColor = m_CurrentColor; + colorContrastControl1.SelectedColor = m_CurrentColor; + if (!value.IsEmpty) + { + numericRed.Value = value.R; + numericBlue.Value = value.B; + numericGreen.Value = value.G; + } + } + } + + public Color NewColor + { + get { return m_NewColor;} + } + #endregion + } + + [ToolboxItem(false)] + internal class CustomColorDialogMetro : DevComponents.DotNetBar.Metro.MetroForm + { + #region Private Variables + internal ButtonX buttonOK; + internal ButtonX buttonCancel; + internal System.Windows.Forms.Label labelNewColor; + internal System.Windows.Forms.Label labelCurrentColor; + + private Color m_CurrentColor = Color.Black; + private Color m_NewColor = Color.Empty; + private ColorCombControl colorCombControl1; + internal System.Windows.Forms.Label labelStandardColors; + internal System.Windows.Forms.Label labelCustomColors; + internal System.Windows.Forms.Label labelGreen; + internal System.Windows.Forms.Label labelBlue; + private DevComponents.DotNetBar.TabControl tabControl2; + internal DevComponents.DotNetBar.TabItem tabItemStandard; + private DevComponents.DotNetBar.TabControlPanel tabControlPanel1; + internal DevComponents.DotNetBar.TabItem tabItemCustom; + private DevComponents.DotNetBar.TabControlPanel tabControlPanel2; + private CustomColorBlender customColorBlender3; + internal System.Windows.Forms.Label labelRed; + internal System.Windows.Forms.Label labelColorModel; + internal ComboBoxEx comboColorModel; +#if FRAMEWORK20 + private IntegerInput numericBlue; + private IntegerInput numericGreen; + private IntegerInput numericRed; +#else + private System.Windows.Forms.NumericUpDown numericBlue; + private System.Windows.Forms.NumericUpDown numericGreen; + private System.Windows.Forms.NumericUpDown numericRed; +#endif + private ColorContrastControl colorContrastControl1; + private ColorSelectionPreviewControl colorSelectionPreview; + private System.ComponentModel.IContainer components; + #endregion + + #region Constructor, Dispose + public CustomColorDialogMetro() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // + // TODO: Add any constructor code after InitializeComponent call + // + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose(disposing); + } + #endregion + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.labelStandardColors = new System.Windows.Forms.Label(); + this.colorCombControl1 = new ColorCombControl(); + this.labelBlue = new System.Windows.Forms.Label(); + this.labelGreen = new System.Windows.Forms.Label(); +#if (FRAMEWORK20) + this.numericBlue = new IntegerInput(); + this.numericGreen = new IntegerInput(); + this.numericRed = new IntegerInput(); +#else + this.numericBlue = new System.Windows.Forms.NumericUpDown(); + this.numericGreen = new System.Windows.Forms.NumericUpDown(); + this.numericRed = new System.Windows.Forms.NumericUpDown(); +#endif + this.labelCustomColors = new System.Windows.Forms.Label(); + this.buttonOK = new ButtonX(); + this.buttonCancel = new ButtonX(); + this.labelNewColor = new System.Windows.Forms.Label(); + this.labelCurrentColor = new System.Windows.Forms.Label(); + this.tabControl2 = new DevComponents.DotNetBar.TabControl(); + this.tabControlPanel1 = new DevComponents.DotNetBar.TabControlPanel(); + this.tabItemStandard = new DevComponents.DotNetBar.TabItem(this.components); + this.tabControlPanel2 = new DevComponents.DotNetBar.TabControlPanel(); + this.colorContrastControl1 = new ColorContrastControl(); + this.customColorBlender3 = new CustomColorBlender(); + this.comboColorModel = new ComboBoxEx(); + this.labelRed = new System.Windows.Forms.Label(); + this.labelColorModel = new System.Windows.Forms.Label(); + this.tabItemCustom = new DevComponents.DotNetBar.TabItem(this.components); + this.colorSelectionPreview = new ColorSelectionPreviewControl(); + ((System.ComponentModel.ISupportInitialize)(this.numericBlue)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericGreen)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericRed)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.tabControl2)).BeginInit(); + this.tabControl2.SuspendLayout(); + this.tabControlPanel1.SuspendLayout(); + this.tabControlPanel2.SuspendLayout(); + this.SuspendLayout(); + // + // label3 + // + this.labelStandardColors.BackColor = System.Drawing.Color.Transparent; + this.labelStandardColors.Dock = System.Windows.Forms.DockStyle.Top; + this.labelStandardColors.Location = new System.Drawing.Point(1, 1); + this.labelStandardColors.Name = "labelStandardColors"; + this.labelStandardColors.Size = new System.Drawing.Size(224, 19); + this.labelStandardColors.TabIndex = 1; + this.labelStandardColors.Text = " Colors:"; + this.labelStandardColors.TextAlign = System.Drawing.ContentAlignment.BottomLeft; + // + // colorCombControl1 + // + this.colorCombControl1.BackColor = System.Drawing.Color.Transparent; + this.colorCombControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.colorCombControl1.Location = new System.Drawing.Point(1, 20); + this.colorCombControl1.Name = "colorCombControl1"; + this.colorCombControl1.Size = new System.Drawing.Size(224, 267); + this.colorCombControl1.TabIndex = 0; + this.colorCombControl1.SelectedColorChanged += new System.EventHandler(this.colorCombControl1_SelectedColorChanged); + // + // label8 + // + this.labelBlue.BackColor = System.Drawing.Color.Transparent; + this.labelBlue.Location = new System.Drawing.Point(4, 256); + this.labelBlue.Name = "labelBlue"; + this.labelBlue.Size = new System.Drawing.Size(90, 16); + this.labelBlue.TabIndex = 10; + this.labelBlue.Text = "&Blue:"; + // + // label7 + // + this.labelGreen.BackColor = System.Drawing.Color.Transparent; + this.labelGreen.Location = new System.Drawing.Point(4, 232); + this.labelGreen.Name = "labelGreen"; + this.labelGreen.Size = new System.Drawing.Size(90, 16); + this.labelGreen.TabIndex = 8; + this.labelGreen.Text = "&Green:"; + // + // numericBlue + // + this.numericBlue.Location = new System.Drawing.Point(98, 260); +#if (FRAMEWORK20) + this.numericBlue.MaxValue = 255; + this.numericBlue.MinValue = 0; + this.numericBlue.ShowUpDown = true; + this.numericBlue.AllowEmptyState = false; +#else + this.numericBlue.Maximum = new System.Decimal(new int[] { + 255, + 0, + 0, + 0}); +#endif + this.numericBlue.Name = "numericBlue"; + this.numericBlue.Size = new System.Drawing.Size(47, 20); + this.numericBlue.TabIndex = 11; + this.numericBlue.ValueChanged += new System.EventHandler(this.numericRGBValueChanged); + // + // numericGreen + // + this.numericGreen.Location = new System.Drawing.Point(98, 236); +#if (FRAMEWORK20) + this.numericGreen.MaxValue = 255; + this.numericGreen.MinValue = 0; + this.numericGreen.ShowUpDown = true; + this.numericGreen.AllowEmptyState = false; +#else + this.numericGreen.Maximum = new System.Decimal(new int[] { + 255, + 0, + 0, + 0}); +#endif + this.numericGreen.Name = "numericGreen"; + this.numericGreen.Size = new System.Drawing.Size(47, 20); + this.numericGreen.TabIndex = 9; + this.numericGreen.ValueChanged += new System.EventHandler(this.numericRGBValueChanged); + // + // numericRed + // + this.numericRed.Location = new System.Drawing.Point(98, 212); +#if (FRAMEWORK20) + this.numericRed.MaxValue = 255; + this.numericRed.MinValue = 0; + this.numericRed.ShowUpDown = true; + this.numericRed.AllowEmptyState = false; +#else + this.numericRed.Maximum = new System.Decimal(new int[] { + 255, + 0, + 0, + 0}); +#endif + this.numericRed.Name = "numericRed"; + this.numericRed.Size = new System.Drawing.Size(47, 20); + this.numericRed.TabIndex = 7; + this.numericRed.ValueChanged += new System.EventHandler(this.numericRGBValueChanged); + // + // label4 + // + this.labelCustomColors.BackColor = System.Drawing.Color.Transparent; + this.labelCustomColors.Dock = System.Windows.Forms.DockStyle.Top; + this.labelCustomColors.Location = new System.Drawing.Point(1, 1); + this.labelCustomColors.Name = "labelCustomColors"; + this.labelCustomColors.Size = new System.Drawing.Size(224, 20); + this.labelCustomColors.TabIndex = 2; + this.labelCustomColors.Text = " Colors:"; + this.labelCustomColors.TextAlign = System.Drawing.ContentAlignment.BottomLeft; + // + // button1 + // + this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.buttonOK.Location = new System.Drawing.Point(242, 6); + this.buttonOK.ColorTable = eButtonColor.OrangeWithBackground; + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(74, 24); + this.buttonOK.TabIndex = 1; + this.buttonOK.Text = "OK"; + // + // button2 + // + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonCancel.Location = new System.Drawing.Point(242, 36); + this.buttonCancel.ColorTable = eButtonColor.OrangeWithBackground; + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(74, 24); + this.buttonCancel.TabIndex = 2; + this.buttonCancel.Text = "Cancel"; + // + // label1 + // + this.labelNewColor.Location = new System.Drawing.Point(256, 232); + this.labelNewColor.Name = "labelNewColor"; + this.labelNewColor.Size = new System.Drawing.Size(44, 12); + this.labelNewColor.TabIndex = 4; + this.labelNewColor.Text = "New"; + this.labelNewColor.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label2 + // + this.labelCurrentColor.Location = new System.Drawing.Point(256, 306); + this.labelCurrentColor.Name = "labelCurrentColor"; + this.labelCurrentColor.Size = new System.Drawing.Size(44, 16); + this.labelCurrentColor.TabIndex = 5; + this.labelCurrentColor.Text = "Current"; + this.labelCurrentColor.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // tabControl2 + // + this.tabControl2.BackColor = Color.White; + this.tabControl2.ForeColor = System.Drawing.Color.Black; + this.tabControl2.CanReorderTabs = false; + this.tabControl2.Controls.Add(this.tabControlPanel2); + this.tabControl2.Controls.Add(this.tabControlPanel1); + this.tabControl2.FixedTabSize = new System.Drawing.Size(60, 0); + this.tabControl2.Location = new System.Drawing.Point(8, 8); + this.tabControl2.Name = "tabControl2"; + this.tabControl2.SelectedTabFont = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold); + this.tabControl2.SelectedTabIndex = 0; + this.tabControl2.Size = new System.Drawing.Size(226, 314); + this.tabControl2.Style = DevComponents.DotNetBar.eTabStripStyle.Metro; + this.tabControl2.TabIndex = 6; + this.tabControl2.TabLayoutType = DevComponents.DotNetBar.eTabLayoutType.FixedWithNavigationBox; + this.tabControl2.Tabs.Add(this.tabItemStandard); + this.tabControl2.Tabs.Add(this.tabItemCustom); + this.tabControl2.ThemeAware = true; + // + // tabControlPanel1 + // + this.tabControlPanel1.Controls.Add(this.colorCombControl1); + this.tabControlPanel1.Controls.Add(this.labelStandardColors); + this.tabControlPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControlPanel1.DockPadding.All = 1; + this.tabControlPanel1.Location = new System.Drawing.Point(0, 26); + this.tabControlPanel1.Name = "tabControlPanel1"; + this.tabControlPanel1.Size = new System.Drawing.Size(226, 288); + this.tabControlPanel1.Style.BackColor1.Color = System.Drawing.Color.White; + this.tabControlPanel1.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; + this.tabControlPanel1.Style.BorderSide = ((DevComponents.DotNetBar.eBorderSide)(((DevComponents.DotNetBar.eBorderSide.Left | DevComponents.DotNetBar.eBorderSide.Right) + | DevComponents.DotNetBar.eBorderSide.Bottom))); + this.tabControlPanel1.Style.GradientAngle = 90; + this.tabControlPanel1.TabIndex = 1; + this.tabControlPanel1.TabItem = this.tabItemStandard; + this.tabControlPanel1.ThemeAware = false; + // + // tabItem1 + // + this.tabItemStandard.AttachedControl = this.tabControlPanel1; + this.tabItemStandard.CloseButtonBounds = new System.Drawing.Rectangle(0, 0, 0, 0); + this.tabItemStandard.Name = "tabItemStandard"; + this.tabItemStandard.Text = "Standard"; + // + // tabControlPanel2 + // + this.tabControlPanel2.Controls.Add(this.colorContrastControl1); + this.tabControlPanel2.Controls.Add(this.numericGreen); + this.tabControlPanel2.Controls.Add(this.labelGreen); + this.tabControlPanel2.Controls.Add(this.numericRed); + this.tabControlPanel2.Controls.Add(this.customColorBlender3); + this.tabControlPanel2.Controls.Add(this.comboColorModel); + this.tabControlPanel2.Controls.Add(this.labelRed); + this.tabControlPanel2.Controls.Add(this.labelColorModel); + this.tabControlPanel2.Controls.Add(this.numericBlue); + this.tabControlPanel2.Controls.Add(this.labelBlue); + this.tabControlPanel2.Controls.Add(this.labelCustomColors); + this.tabControlPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControlPanel2.DockPadding.All = 1; + this.tabControlPanel2.Location = new System.Drawing.Point(0, 26); + this.tabControlPanel2.Name = "tabControlPanel2"; + this.tabControlPanel2.Size = new System.Drawing.Size(226, 288); + this.tabControlPanel2.Style.BackColor1.Color = System.Drawing.Color.White; + this.tabControlPanel2.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; + this.tabControlPanel2.Style.BorderSide = ((DevComponents.DotNetBar.eBorderSide)(((DevComponents.DotNetBar.eBorderSide.Left | DevComponents.DotNetBar.eBorderSide.Right) + | DevComponents.DotNetBar.eBorderSide.Bottom))); + this.tabControlPanel2.Style.GradientAngle = 90; + this.tabControlPanel2.TabIndex = 2; + this.tabControlPanel2.TabItem = this.tabItemCustom; + this.tabControlPanel2.ThemeAware = true; + // + // colorContrastControl1 + // + this.colorContrastControl1.BackColor = System.Drawing.Color.Transparent; + this.colorContrastControl1.Location = new System.Drawing.Point(188, 28); + this.colorContrastControl1.Name = "colorContrastControl1"; + this.colorContrastControl1.SelectedColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(255)), ((System.Byte)(255))); + this.colorContrastControl1.Size = new System.Drawing.Size(32, 152); + this.colorContrastControl1.TabIndex = 12; + this.colorContrastControl1.SelectedColorChanged += new System.EventHandler(this.colorContrastControl1_SelectedColorChanged); + // + // customColorBlender3 + // + this.customColorBlender3.Location = new System.Drawing.Point(8, 28); + this.customColorBlender3.Name = "customColorBlender3"; + this.customColorBlender3.Size = new System.Drawing.Size(174, 152); + this.customColorBlender3.TabIndex = 3; + this.customColorBlender3.SelectedColorChanged += new System.EventHandler(this.customColorBlender3_SelectedColorChanged); + // + // comboColorModel + // + this.comboColorModel.DrawMode = DrawMode.OwnerDrawFixed; + this.comboColorModel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboColorModel.Items.AddRange(new object[] { + "RGB"}); + this.comboColorModel.Location = new System.Drawing.Point(98, 188); + this.comboColorModel.Name = "comboColorModel"; + this.comboColorModel.Size = new System.Drawing.Size(89, 21); + this.comboColorModel.TabIndex = 5; + // + // label9 + // + this.labelRed.BackColor = System.Drawing.Color.Transparent; + this.labelRed.Location = new System.Drawing.Point(4, 212); + this.labelRed.Name = "labelRed"; + this.labelRed.Size = new System.Drawing.Size(90, 16); + this.labelRed.TabIndex = 6; + this.labelRed.Text = "&Red:"; + // + // label10 + // + this.labelColorModel.BackColor = System.Drawing.Color.Transparent; + this.labelColorModel.Location = new System.Drawing.Point(4, 192); + this.labelColorModel.Name = "labelColorModel"; + this.labelColorModel.Size = new System.Drawing.Size(90, 16); + this.labelColorModel.TabIndex = 4; + this.labelColorModel.Text = "Color Mo&del:"; + // + // tabItem2 + // + this.tabItemCustom.AttachedControl = this.tabControlPanel2; + this.tabItemCustom.CloseButtonBounds = new System.Drawing.Rectangle(0, 0, 0, 0); + this.tabItemCustom.Name = "tabItemCustom"; + this.tabItemCustom.Text = "Custom"; + // + // colorSelectionPreview + // + this.colorSelectionPreview.CurrentColor = System.Drawing.Color.Black; + this.colorSelectionPreview.Location = new System.Drawing.Point(252, 252); + this.colorSelectionPreview.Name = "colorSelectionPreview"; + this.colorSelectionPreview.NewColor = System.Drawing.Color.Empty; + this.colorSelectionPreview.Size = new System.Drawing.Size(56, 48); + this.colorSelectionPreview.TabIndex = 7; + // + // CustomColorDialog + // + this.AcceptButton = this.buttonOK; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.CancelButton = this.buttonCancel; + this.ClientSize = new System.Drawing.Size(324, 326); + this.Controls.Add(this.colorSelectionPreview); + this.Controls.Add(this.tabControl2); + this.Controls.Add(this.labelCurrentColor); + this.Controls.Add(this.labelNewColor); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonOK); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CustomColorDialog"; + this.ShowInTaskbar = false; + this.Text = "Colors"; + this.Load += new System.EventHandler(this.Form1_Load); + ((System.ComponentModel.ISupportInitialize)(this.numericBlue)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericGreen)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericRed)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.tabControl2)).EndInit(); + this.tabControl2.ResumeLayout(false); + this.tabControlPanel1.ResumeLayout(false); + this.tabControlPanel2.ResumeLayout(false); + this.ResumeLayout(false); + + } + #endregion + + #region Internal Implementation + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + Size fixedSize = tabControl2.FixedTabSize; + using (Graphics g = this.CreateGraphics()) + { + System.Drawing.Size s = TextDrawing.MeasureString(g, tabItemCustom.Text, this.Font); + System.Drawing.Size s1 = TextDrawing.MeasureString(g, tabItemStandard.Text, this.Font); + fixedSize.Width = Math.Max(fixedSize.Width, s.Width + 5); + fixedSize.Width = Math.Max(fixedSize.Width, s1.Width + 5); + } + tabControl2.FixedTabSize = fixedSize; + if (fixedSize.Width > tabControl2.Width / 2) + { + tabControl2.FixedTabSize = Size.Empty; + } + } + internal void SetStyle(eDotNetBarStyle style) + { + buttonCancel.Style = style; + buttonOK.Style = style; + + //tabControl2.BackColor = Color.Transparent; + //tabControl2.ColorScheme.TabBackground = Color.Transparent; + //tabControl2.ColorScheme.TabBackground2 = Color.Empty; + } + private void colorCombControl1_SelectedColorChanged(object sender, System.EventArgs e) + { + SetNewColor(colorCombControl1.SelectedColor); + colorContrastControl1.SelectedColor = colorCombControl1.SelectedColor; + } + + private void customColorBlender3_SelectedColorChanged(object sender, System.EventArgs e) + { + colorContrastControl1.SelectedColor = customColorBlender3.SelectedColor; + SetNewColor(colorContrastControl1.SelectedColor); + } + + private bool m_SettingColor = false; + private void SetNewColor(Color color) + { + if (m_SettingColor) return; + m_SettingColor = true; + try + { + m_NewColor = color; + colorSelectionPreview.NewColor = color; + + numericRed.Value = m_NewColor.R; + numericGreen.Value = m_NewColor.G; + numericBlue.Value = m_NewColor.B; + } + finally + { + m_SettingColor = false; + } + } + + private void Form1_Load(object sender, System.EventArgs e) + { + comboColorModel.SelectedIndex = 0; + } + + private void numericRGBValueChanged(object sender, System.EventArgs e) + { + SetNewColor(Color.FromArgb((int)numericRed.Value, (int)numericGreen.Value, (int)numericBlue.Value)); + } + + private void colorContrastControl1_SelectedColorChanged(object sender, System.EventArgs e) + { + SetNewColor(colorContrastControl1.SelectedColor); + } + + public Color CurrentColor + { + get { return m_CurrentColor; } + set + { + m_CurrentColor = value; + colorSelectionPreview.CurrentColor = value; + customColorBlender3.SelectedColor = value; + colorContrastControl1.SelectedColor = value; + if (!value.IsEmpty) + { + numericRed.Value = value.R; + numericBlue.Value = value.B; + numericGreen.Value = value.G; + } + + } + } + + public Color NewColor + { + get { return m_NewColor; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ColorScheme.cs b/PROMS/DotNetBar Source Code/ColorScheme.cs new file mode 100644 index 00000000..f59b1b5b --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorScheme.cs @@ -0,0 +1,4764 @@ +using System; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the Color scheme used by items on the Bar. + /// + public class ColorScheme + { + #region Private Variables + private Color m_MenuBarBackground; + private bool m_MenuBarBackgroundCustom=false; + + private Color m_MenuBarBackground2=Color.Empty; + private bool m_MenuBarBackground2Custom=false; + + private int m_MenuBarBackgroundGradientAngle=90; + + private Color m_BarBackground; + private bool m_BarBackgroundCustom=false; + + private Color m_BarBackground2=Color.Empty; + private bool m_BarBackground2Custom=false; + + private int m_BarBackgroundGradientAngle=90; + + private Color m_BarCaptionBackground; + private bool m_BarCaptionBackgroundCustom=false; + + private Color m_BarCaptionBackground2=Color.Empty; + private bool m_BarCaptionBackground2Custom=false; + + private int m_BarCaptionBackgroundGradientAngle=90; + + private Color m_BarCaptionText; + private bool m_BarCaptionTextCustom=false; + + private Color m_BarCaptionInactiveBackground; + private bool m_BarCaptionInactiveBackgroundCustom=false; + + private Color m_BarCaptionInactiveBackground2=Color.Empty; + private bool m_BarCaptionInactiveBackground2Custom=false; + + private int m_BarCaptionInactiveBackgroundGAngle=90; + + private Color m_BarCaptionInactiveText; + private bool m_BarCaptionInactiveTextCustom=false; + + private Color m_BarPopupBackground; + private bool m_BarPopupBackgroundCustom=false; + + private Color m_BarPopupBorder; + private bool m_BarPopupBorderCustom=false; + + private Color m_BarDockedBorder; + private bool m_BarDockedBorderCustom=false; + + private Color m_BarStripeColor; + private bool m_BarStripeColorCustom=false; + + private Color m_BarFloatingBorder; + private bool m_BarFloatingBorderCustom=false; + + private Color m_ItemBackground; + private bool m_ItemBackgroundCustom=false; + + private Color m_ItemBackground2; + private bool m_ItemBackground2Custom=false; + + private int m_ItemBackgroundGradientAngle=90; + + private Color m_ItemText; + private bool m_ItemTextCustom=false; + + private Color m_ItemDisabledBackground; + private bool m_ItemDisabledBackgroundCustom=false; + + private Color m_ItemDisabledText; + private bool m_ItemDisabledTextCustom=false; + + private Color m_ItemHotBackground; + private bool m_ItemHotBackgroundCustom=false; + + private Color m_ItemHotBackground2=Color.Empty; + private bool m_ItemHotBackground2Custom=false; + + private int m_ItemHotBackgroundGradientAngle=90; + + private Color m_ItemHotText; + private bool m_ItemHotTextCustom=false; + + private Color m_ItemHotBorder; + private bool m_ItemHotBorderCustom=false; + + private Color m_ItemPressedBackground; + private bool m_ItemPressedBackgroundCustom=false; + + private Color m_ItemPressedBackground2=Color.Empty; + private bool m_ItemPressedBackground2Custom=false; + private int m_ItemPressedBackgroundGradientAngle=90; + + private Color m_ItemPressedText; + private bool m_ItemPressedTextCustom=false; + + private Color m_ItemPressedBorder; + private bool m_ItemPressedBorderCustom=false; + + private Color m_ItemSeparator; + private bool m_ItemSeparatorCustom=false; + + private Color m_ItemSeparatorShade=Color.Empty; + private bool m_ItemSeparatorShadeCustom=false; + + private Color m_ItemExpandedBackground; + private bool m_ItemExpandedBackgroundCustom=false; + + private Color m_ItemExpandedBackground2=Color.Empty; + private bool m_ItemExpandedBackground2Custom=false; + private int m_ItemExpandedBackgroundGradientAngle=90; + + private Color m_ItemExpandedText; + private bool m_ItemExpandedTextCustom=false; + + private Color m_ItemExpandedShadow; + private bool m_ItemExpandedShadowCustom=false; + + private Color m_ItemExpandedBorder; + private bool m_ItemExpandedBorderCustom=false; + + private Color m_ItemCheckedBackground; + private bool m_ItemCheckedBackgroundCustom=false; + + private int m_ItemCheckedBackgroundGradientAngle=90; + + private Color m_ItemCheckedBackground2=Color.Empty; + private bool m_ItemCheckedBackground2Custom=false; + + private Color m_ItemCheckedBorder; + private bool m_ItemCheckedBorderCustom=false; + + private Color m_ItemCheckedText; + private bool m_ItemCheckedTextCustom=false; + + private Color m_MenuBorder; + private bool m_MenuBorderCustom=false; + + private Color m_MenuBackground; + private bool m_MenuBackgroundCustom=false; + + private Color m_MenuBackground2=Color.Empty; + private bool m_MenuBackground2Custom=false; + + private int m_MenuBackgroundGradientAngle=0; + + private Color m_MenuSide; + private bool m_MenuSideCustom=false; + + private Color m_MenuSide2=Color.Empty; + private bool m_MenuSide2Custom=false; + + private int m_MenuSideGradientAngle=0; + + private Color m_MenuUnusedBackground; + private bool m_MenuUnusedBackgroundCustom=false; + + private Color m_MenuUnusedSide; + private bool m_MenuUnusedSideCustom=false; + + private Color m_MenuUnusedSide2=Color.Empty; + private bool m_MenuUnusedSide2Custom=false; + + private int m_MenuUnusedSideGradientAngle=0; + + private Color m_ItemDesignTimeBorder; + private bool m_ItemDesignTimeBorderCustom=false; + + private Color m_CustomizeBackground=Color.Empty; + private bool m_CustomizeBackgroundCustom=false; + private Color m_CustomizeBackground2=Color.Empty; + private bool m_CustomizeBackground2Custom=false; + private int m_CustomizeBackgroundGradientAngle=90; + private Color m_CustomizeText=Color.Empty; + private bool m_CustomizeTextCustom=false; + + // Panel Colors + private Color m_PanelBackground=Color.Empty; + private bool m_PanelBackgroundCustom=false; + + private Color m_PanelBackground2=Color.Empty; + private bool m_PanelBackground2Custom=false; + + private int m_PanelBackgroundGradientAngle=90; + + private Color m_PanelText=Color.Empty; + private bool m_PanelTextCustom=false; + + private Color m_PanelBorder=Color.Empty; + private bool m_PanelBorderCustom=false; + + // Splitter Colors + private Color m_SplitterBackground = Color.Empty; + private bool m_SplitterBackgroundCustom = false; + + private Color m_SplitterBackground2 = Color.Empty; + private bool m_SplitterBackground2Custom = false; + + private int m_SplitterBackgroundGradientAngle = 90; + + private Color m_SplitterText = Color.Empty; + private bool m_SplitterTextCustom = false; + + private Color m_SplitterBorder = Color.Empty; + private bool m_SplitterBorderCustom = false; + + private Color m_ExplorerBarBackground=Color.Empty; + private bool m_ExplorerBarBackgroundCustom=false; + private Color m_ExplorerBarBackground2=Color.Empty; + private bool m_ExplorerBarBackground2Custom=false; + private int m_ExplorerBarBackgroundGradientAngle=90; + + internal bool _DesignTimeSchemeChanged=false; + + private eDotNetBarStyle m_Style=eDotNetBarStyle.OfficeXP; + + private Color m_DockSiteBackColor=Color.Empty; + private bool m_DockSiteBackColorCustom=false; + private Color m_DockSiteBackColor2=Color.Empty; + private bool m_DockSiteBackColor2Custom=false; + private int m_DockSiteBackColorGradientAngle=0; + + private ePredefinedColorScheme m_PredefinedColorScheme=ePredefinedColorScheme.AutoGenerated; + + private Color m_MdiSystemItemForeground = Color.Empty; + #endregion + + #region Public Interface + public ColorScheme() + { + Refresh(null,false); + } + public ColorScheme(System.Drawing.Graphics graphics) + { + Refresh(graphics,false); + } + + public ColorScheme(eDotNetBarStyle style) + { + m_Style=style; + Refresh(null,true); + } + +#if !NOTREE + public ColorScheme(DevComponents.AdvTree.eColorSchemeStyle cs) + { + eDotNetBarStyle style = eDotNetBarStyle.Office2003; + if (cs == DevComponents.AdvTree.eColorSchemeStyle.VS2005) + style = eDotNetBarStyle.VS2005; + else if (cs == DevComponents.AdvTree.eColorSchemeStyle.Office2007) + style = eDotNetBarStyle.Office2007; + m_Style = style; + Refresh(null, true); + } +#endif + + internal eDotNetBarStyle Style + { + get {return m_Style;} + set + { + if(m_Style!=value) + { + m_Style=value; + this.Refresh(); + } + } + } + + internal void SwitchStyle(eDotNetBarStyle style) + { + if(m_Style!=style) + { + m_Style=style; + this.Refresh(null,true); + } + } + + /// + /// Specifies Dock Site BackColor. + /// + [Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Panel Colors"), System.ComponentModel.Description("Specifies starting color of dock site.")] + public Color DockSiteBackColor + { + get { return m_DockSiteBackColor; } + set + { + if(m_DockSiteBackColor != value) + { + m_DockSiteBackColor = value; + m_DockSiteBackColorCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeDockSiteBackColor() + { + return m_DockSiteBackColorCustom; + } + /// + /// Specifies Dock Site BackColor2. + /// + [Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Panel Colors"), System.ComponentModel.Description("Specifies ending gradient color of dock site.")] + public Color DockSiteBackColor2 + { + get { return m_DockSiteBackColor2; } + set + { + if(m_DockSiteBackColor2 != value) + { + m_DockSiteBackColor2 = value; + m_DockSiteBackColor2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeDockSiteBackColor2() + { + return m_DockSiteBackColor2Custom; + } + + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Panel Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(0)] + public int DockSiteBackColorGradientAngle + { + get {return m_DockSiteBackColorGradientAngle;} + set {m_DockSiteBackColorGradientAngle=value;} + } + + /// + /// Specifies the menu bar background color. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the menu bar background color.")] + public Color MenuBarBackground + { + get{return m_MenuBarBackground;} + set + { + if(m_MenuBarBackground!=value) + { + m_MenuBarBackground=value; + m_MenuBarBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuBarBackground() + { + return m_MenuBarBackgroundCustom; + } + /// + /// Specifies the target menu bar gradient background color. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the target menu bar gradient background color.")] + public Color MenuBarBackground2 + { + get{return m_MenuBarBackground2;} + set + { + if(m_MenuBarBackground2!=value) + { + m_MenuBarBackground2=value; + m_MenuBarBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuBarBackground2() + { + return m_MenuBarBackground2Custom; + } + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(90)] + public int MenuBarBackgroundGradientAngle + { + get {return m_MenuBarBackgroundGradientAngle;} + set {m_MenuBarBackgroundGradientAngle=value;} + } + /// + /// Specifies the background color for the bar when floating or when docked. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the background color for the bar when floating or when docked.")] + public Color BarBackground + { + get {return m_BarBackground;} + set + { + if(m_BarBackground!=value) + { + m_BarBackground=value; + m_BarBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarBackground() + { + return m_BarBackgroundCustom; + } + /// + /// Specifies the target gradient background color for the bar when floating or when docked. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the target gradient background color for the bar when floating or when docked.")] + public Color BarBackground2 + { + get {return m_BarBackground2;} + set + { + if(m_BarBackground2!=value) + { + m_BarBackground2=value; + m_BarBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarBackground2() + { + return m_BarBackground2Custom; + } + + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(90)] + public int BarBackgroundGradientAngle + { + get {return m_BarBackgroundGradientAngle;} + set {m_BarBackgroundGradientAngle=value;} + } + + /// + /// Specifies the background color for the bar Caption. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the background color for the bar Caption.")] + public Color BarCaptionBackground + { + get{return m_BarCaptionBackground;} + set + { + if(m_BarCaptionBackground!=value) + { + m_BarCaptionBackground=value; + m_BarCaptionBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarCaptionBackground() + { + return m_BarCaptionBackgroundCustom; + } + /// + /// Specifies the target gradient background color for the bar Caption. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the target bar gradient background color for the bar Caption.")] + public Color BarCaptionBackground2 + { + get{return m_BarCaptionBackground2;} + set + { + if(m_BarCaptionBackground2!=value) + { + m_BarCaptionBackground2=value; + m_BarCaptionBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarCaptionBackground2() + { + return m_BarCaptionBackground2Custom; + } + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(90)] + public int BarCaptionBackgroundGradientAngle + { + get {return m_BarCaptionBackgroundGradientAngle;} + set{m_BarCaptionBackgroundGradientAngle=value;} + } + /// + /// Specifies the color for text of the Caption. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the color for text of the Caption.")] + public Color BarCaptionText + { + get {return m_BarCaptionText;} + set + { + if(m_BarCaptionText!=value) + { + m_BarCaptionText=value; + m_BarCaptionTextCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarCaptionText() + { + return m_BarCaptionTextCustom; + } + /// + /// Specifies the Bar Caption inactive (lost focus) background color. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the Bar Caption inactive (lost focus) background color.")] + public Color BarCaptionInactiveBackground + { + get {return m_BarCaptionInactiveBackground;} + set + { + if(m_BarCaptionInactiveBackground!=value) + { + m_BarCaptionInactiveBackground=value; + m_BarCaptionInactiveBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarCaptionInactiveBackground() + { + return m_BarCaptionInactiveBackgroundCustom; + } + /// + /// Specifies the target background gradient Bar Caption inactive (lost focus) color. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the target background gradient Bar Caption inactive (lost focus) color.")] + public Color BarCaptionInactiveBackground2 + { + get {return m_BarCaptionInactiveBackground2;} + set + { + if(m_BarCaptionInactiveBackground2!=value) + { + m_BarCaptionInactiveBackground2=value; + m_BarCaptionInactiveBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarCaptionInactiveBackground2() + { + return m_BarCaptionInactiveBackground2Custom; + } + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(90)] + internal int BarCaptionInactiveBackgroundGAngle + { + get {return m_BarCaptionInactiveBackgroundGAngle;} + set {m_BarCaptionInactiveBackgroundGAngle=value;} + } + /// + /// Specifies the Bar inactive (lost focus) text color. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the Bar inactive (lost focus) text color.")] + public Color BarCaptionInactiveText + { + get {return m_BarCaptionInactiveText;} + set + { + if(m_BarCaptionInactiveText!=value) + { + m_BarCaptionInactiveText=value; + m_BarCaptionInactiveTextCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarCaptionInactiveText() + { + return m_BarCaptionInactiveTextCustom; + } + /// + /// Specifies the background color for popup bars. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the background color for popup bars.")] + public Color BarPopupBackground + { + get {return m_BarPopupBackground;} + set + { + if(m_BarPopupBackground!=value) + { + m_BarPopupBackground=value; + m_BarPopupBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarPopupBackground() + { + return m_BarPopupBackgroundCustom; + } + /// + /// Specifies the border color for popup bars. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the border color for popup bars.")] + public Color BarPopupBorder + { + get {return m_BarPopupBorder;} + set + { + if(m_BarPopupBorder!=value) + { + m_BarPopupBorder=value; + m_BarPopupBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarPopupBorder() + { + return m_BarPopupBorderCustom; + } + /// + /// Specifies the border color for docked bars. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the border color for docked bars.")] + public Color BarDockedBorder + { + get {return m_BarDockedBorder;} + set + { + if(m_BarDockedBorder!=value) + { + m_BarDockedBorder=value; + m_BarDockedBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarDockedBorder() + { + return m_BarDockedBorderCustom; + } + /// + /// Specifies the color of the grab handle stripes. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the color of the grab handle stripes.")] + public Color BarStripeColor + { + get {return m_BarStripeColor;} + set + { + if(m_BarStripeColor!=value) + { + m_BarStripeColor=value; + m_BarStripeColorCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarStripeColor() + { + return m_BarStripeColorCustom; + } + /// + /// Specifies the border color for floating bars. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Bar Colors"),System.ComponentModel.Description("Specifies the border color for floating bars.")] + public Color BarFloatingBorder + { + get {return m_BarFloatingBorder;} + set + { + if(m_BarFloatingBorder!=value) + { + m_BarFloatingBorder=value; + m_BarFloatingBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBarFloatingBorder() + { + return m_BarFloatingBorderCustom; + } + /// + /// Specifies the item background color. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the item background color.")] + public Color ItemBackground + { + get {return m_ItemBackground;} + set + { + if(m_ItemBackground!=value) + { + m_ItemBackground=value; + m_ItemBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemBackground() + { + return m_ItemBackgroundCustom; + } + /// + /// Specifies the target item background gradient color. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the target item background gradient color.")] + public Color ItemBackground2 + { + get {return m_ItemBackground2;} + set + { + if(m_ItemBackground2!=value) + { + m_ItemBackground2=value; + m_ItemBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemBackground2() + { + return m_ItemBackground2Custom; + } + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(90)] + public int ItemBackgroundGradientAngle + { + get {return m_ItemBackgroundGradientAngle;} + set {m_ItemBackgroundGradientAngle=value;} + } + + /// + /// Specifies the item text color. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the item text color.")] + public Color ItemText + { + get {return m_ItemText;} + set + { + if(m_ItemText!=value) + { + m_ItemText=value; + m_ItemTextCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemText() + { + return m_ItemTextCustom; + } + /// + /// Specifies the background color for the item that is disabled. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the background color for the item that is disabled.")] + public Color ItemDisabledBackground + { + get {return m_ItemDisabledBackground;} + set + { + if(m_ItemDisabledBackground!=value) + { + m_ItemDisabledBackground=value; + m_ItemDisabledBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemDisabledBackground() + { + return m_ItemDisabledBackgroundCustom; + } + /// + /// Specifies the text color for the item that is disabled. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the text color for the item that is disabled.")] + public Color ItemDisabledText + { + get {return m_ItemDisabledText;} + set + { + if(m_ItemDisabledText!=value) + { + m_ItemDisabledText=value; + m_ItemDisabledTextCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemDisabledText() + { + return m_ItemDisabledTextCustom; + } + /// + /// Specifies the background color when mouse is over the item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the background color when mouse is over the item.")] + public Color ItemHotBackground + { + get {return m_ItemHotBackground;} + set + { + if(m_ItemHotBackground!=value) + { + m_ItemHotBackground=value; + m_ItemHotBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemHotBackground() + { + return m_ItemHotBackgroundCustom; + } + /// + /// Specifies the target gradient background color when mouse is over the item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the target gradient background color when mouse is over the item.")] + public Color ItemHotBackground2 + { + get {return m_ItemHotBackground2;} + set + { + if(m_ItemHotBackground2!=value) + { + m_ItemHotBackground2=value; + m_ItemHotBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemHotBackground2() + { + return m_ItemHotBackground2Custom; + } + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(90)] + public int ItemHotBackgroundGradientAngle + { + get {return m_ItemHotBackgroundGradientAngle;} + set {m_ItemHotBackgroundGradientAngle=value;} + } + /// + /// Specifies the text color when mouse is over the item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the text color when mouse is over the item.")] + public Color ItemHotText + { + get {return m_ItemHotText;} + set + { + if(m_ItemHotText!=value) + { + m_ItemHotText=value; + m_ItemHotTextCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemHotText() + { + return m_ItemHotTextCustom; + } + /// + /// Specifies the border color when mouse is over the item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the border color when mouse is over the item.")] + public Color ItemHotBorder + { + get {return m_ItemHotBorder;} + set + { + if(m_ItemHotBorder!=value) + { + m_ItemHotBorder=value; + m_ItemHotBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemHotBorder() + { + return m_ItemHotBorderCustom; + } + /// + /// Specifies the background color when item is pressed. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the background color when item is pressed.")] + public Color ItemPressedBackground + { + get {return m_ItemPressedBackground;} + set + { + if(m_ItemPressedBackground!=value) + { + m_ItemPressedBackground=value; + m_ItemPressedBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemPressedBackground() + { + return m_ItemPressedBackgroundCustom; + } + /// + /// Specifies the target gradient background color when item is pressed. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the target gradient background color when item is pressed.")] + public Color ItemPressedBackground2 + { + get {return m_ItemPressedBackground2;} + set + { + if(m_ItemPressedBackground2!=value) + { + m_ItemPressedBackground2=value; + m_ItemPressedBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemPressedBackground2() + { + return m_ItemPressedBackground2Custom; + } + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(90)] + public int ItemPressedBackgroundGradientAngle + { + get {return m_ItemPressedBackgroundGradientAngle;} + set {m_ItemPressedBackgroundGradientAngle=value;} + } + /// + /// Specifies the text color when item is pressed. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the text color when item is pressed.")] + public Color ItemPressedText + { + get {return m_ItemPressedText;} + set + { + if(m_ItemPressedText!=value) + { + m_ItemPressedText=value; + m_ItemPressedTextCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemPressedText() + { + return m_ItemPressedTextCustom; + } + /// + /// Specifies the border color when item is pressed. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the border color when item is pressed.")] + public Color ItemPressedBorder + { + get {return m_ItemPressedBorder;} + set + { + if(m_ItemPressedBorder!=value) + { + m_ItemPressedBorder=value; + m_ItemPressedBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemPressedBorder() + { + return m_ItemPressedBorderCustom; + } + /// + /// Specifies the color for the item group separator. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the color for the item group separator.")] + public Color ItemSeparator + { + get {return m_ItemSeparator;} + set + { + if(m_ItemSeparator!=value) + { + m_ItemSeparator=value; + m_ItemSeparatorCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemSeparator() + { + return m_ItemSeparatorCustom; + } + /// + /// Specifies the color for the item group separator shade. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the color for the item group separator shade.")] + public Color ItemSeparatorShade + { + get {return m_ItemSeparatorShade;} + set + { + if(m_ItemSeparatorShade!=value) + { + m_ItemSeparatorShade=value; + m_ItemSeparatorShadeCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemSeparatorShade() + { + return m_ItemSeparatorShadeCustom; + } + /// + /// Specifies the background color for the shadow of expanded item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the background color for the shadow of expanded item.")] + public Color ItemExpandedShadow + { + get {return m_ItemExpandedShadow;} + set + { + if(m_ItemExpandedShadow!=value) + { + m_ItemExpandedShadow=value; + m_ItemExpandedShadowCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemExpandedShadow() + { + return m_ItemExpandedShadowCustom; + } + /// + /// Specifies the background color for the expanded item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the background color for the expanded item.")] + public Color ItemExpandedBackground + { + get {return m_ItemExpandedBackground;} + set + { + if(m_ItemExpandedBackground!=value) + { + m_ItemExpandedBackground=value; + m_ItemExpandedBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemExpandedBackground() + { + return m_ItemExpandedBackgroundCustom; + } + /// + /// Specifies the target gradient background color for the expanded item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the target gradient background color for the expanded item.")] + public Color ItemExpandedBackground2 + { + get {return m_ItemExpandedBackground2;} + set + { + if(m_ItemExpandedBackground2!=value) + { + m_ItemExpandedBackground2=value; + m_ItemExpandedBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemExpandedBackground2() + { + return m_ItemExpandedBackground2Custom; + } + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(90)] + public int ItemExpandedBackgroundGradientAngle + { + get {return m_ItemExpandedBackgroundGradientAngle;} + set {m_ItemExpandedBackgroundGradientAngle=value;} + } + + /// + /// Specifies the text color for the expanded item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the text color for the expanded item.")] + public Color ItemExpandedText + { + get {return m_ItemExpandedText;} + set + { + if(m_ItemExpandedText!=value) + { + m_ItemExpandedText=value; + m_ItemExpandedTextCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemExpandedText() + { + return m_ItemExpandedTextCustom; + } + /// + /// Specifies the border color for the expanded item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the border color for the expanded item.")] + public Color ItemExpandedBorder + { + get {return m_ItemExpandedBorder;} + set + { + if(m_ItemExpandedBorder!=value) + { + m_ItemExpandedBorder=value; + m_ItemExpandedBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemExpandedBorder() + { + return m_ItemExpandedBorderCustom; + } + + /// + /// Specifies the background color for the checked item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the background color for the checked item.")] + public Color ItemCheckedBackground + { + get {return m_ItemCheckedBackground;} + set + { + if(m_ItemCheckedBackground!=value) + { + m_ItemCheckedBackground=value; + m_ItemCheckedBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemCheckedBackground() + { + return m_ItemCheckedBackgroundCustom; + } + /// + /// Specifies the target gradient background color for the checked item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the target gradient background color for the checked item.")] + public Color ItemCheckedBackground2 + { + get {return m_ItemCheckedBackground2;} + set + { + if(m_ItemCheckedBackground2!=value) + { + m_ItemCheckedBackground2=value; + m_ItemCheckedBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemCheckedBackground2() + { + return m_ItemCheckedBackground2Custom; + } + /// + /// Specifies the gradient angle. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the gradient angle."),DefaultValue(90)] + public int ItemCheckedBackgroundGradientAngle + { + get {return m_ItemCheckedBackgroundGradientAngle;} + set {m_ItemCheckedBackgroundGradientAngle=value;} + } + + /// + /// Specifies the border color for the checked item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the border color for the checked item.")] + public Color ItemCheckedBorder + { + get {return m_ItemCheckedBorder;} + set + { + if(m_ItemCheckedBorder!=value) + { + m_ItemCheckedBorder=value; + m_ItemCheckedBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemCheckedBorder() + { + return m_ItemCheckedBorderCustom; + } + /// + /// Specifies the text color for the checked item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Item Colors"),System.ComponentModel.Description("Specifies the text color for the checked item.")] + public Color ItemCheckedText + { + get {return m_ItemCheckedText;} + set + { + if(m_ItemCheckedText!=value) + { + m_ItemCheckedText=value; + m_ItemCheckedTextCustom=true; + } + } + + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemCheckedText() + { + return m_ItemCheckedTextCustom; + } + /// + /// Specifies the customize item background color. Applies to Office2003 style only. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Special Item Colors"),System.ComponentModel.Description("Specifies the customize item background color.")] + public Color CustomizeBackground + { + get {return m_CustomizeBackground;} + set + { + if(m_CustomizeBackground!=value) + { + m_CustomizeBackground=value; + m_CustomizeBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCustomizeBackground() + { + return m_CustomizeBackgroundCustom; + } + /// + /// Specifies the customize item target gradient background color. Applies to Office2003 style only. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Special Item Colors"),System.ComponentModel.Description("Specifies the customize item target gradient background color.")] + public Color CustomizeBackground2 + { + get {return m_CustomizeBackground2;} + set + { + if(m_CustomizeBackground2!=value) + { + m_CustomizeBackground2=value; + m_CustomizeBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCustomizeBackground2() + { + return m_CustomizeBackground2Custom; + } + /// + /// Specifies the customize item background color gradient angle. Applies to Office2003 style only. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Special Item Colors"),System.ComponentModel.Description("Specifies the customize item background color gradient angle."),DefaultValue(90)] + public int CustomizeBackgroundGradientAngle + { + get {return m_CustomizeBackgroundGradientAngle;} + set {m_CustomizeBackgroundGradientAngle=value;} + } + /// + /// Specifies the customize item text color. Applies to Office2003 style only. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Special Item Colors"),System.ComponentModel.Description("Specifies the customize item text color.")] + public Color CustomizeText + { + get {return m_CustomizeText;} + set + { + if(m_CustomizeText!=value) + { + m_CustomizeText=value; + m_CustomizeTextCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCustomizeText() + { + return m_CustomizeTextCustom; + } + /// + /// Specifies the color of the menu border. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the color of the menu border.")] + public Color MenuBorder + { + get {return m_MenuBorder;} + set + { + if(m_MenuBorder!=value) + { + m_MenuBorder=value; + m_MenuBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuBorder() + { + return m_MenuBorderCustom; + } + /// + /// Specifies the background color of the menu. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the background color of the menu.")] + public Color MenuBackground + { + get {return m_MenuBackground;} + set + { + if(m_MenuBackground!=value) + { + m_MenuBackground=value; + m_MenuBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuBackground() + { + return m_MenuBackgroundCustom; + } + /// + /// Specifies the target gradient background color of the menu. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the target gradient background color of the menu.")] + public Color MenuBackground2 + { + get {return m_MenuBackground2;} + set + { + if(m_MenuBackground2!=value) + { + m_MenuBackground2=value; + m_MenuBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuBackground2() + { + return m_MenuBackground2Custom; + } + /// + /// Specifies the angle of the gradient fill for the menu background. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the angle of the gradient fill for the menu background."),DefaultValue(0)] + public int MenuBackgroundGradientAngle + { + get {return m_MenuBackgroundGradientAngle;} + set + { + if(m_MenuBackgroundGradientAngle!=value) + { + m_MenuBackgroundGradientAngle=value; + } + } + } + /// + /// Specifies the background color of the menu part (left side) that is showing the images. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the background color of the menu part (left side) that is showing the images.")] + public Color MenuSide + { + get {return m_MenuSide;} + set + { + if(m_MenuSide!=value) + { + m_MenuSide=value; + m_MenuSideCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuSide() + { + return m_MenuSideCustom; + } + /// + /// Specifies the target gradient background color of the menu part (left side) that is showing the images. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the target gradient background color of the menu part (left side) that is showing the images.")] + public Color MenuSide2 + { + get {return m_MenuSide2;} + set + { + if(m_MenuSide2!=value) + { + m_MenuSide2=value; + m_MenuSide2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuSide2() + { + return m_MenuSide2Custom; + } + /// + /// Specifies the angle of the gradient fill for the menu part (left side) that is showing the images. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the angle of the gradient fill for the menu part (left side) that is showing the images."),DefaultValue(0)] + public int MenuSideGradientAngle + { + get {return m_MenuSideGradientAngle;} + set + { + if(m_MenuSideGradientAngle!=value) + { + m_MenuSideGradientAngle=value; + } + } + } + /// + /// Specifies the background color for the items that were not recently used. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the background color for the items that were not recently used.")] + public Color MenuUnusedBackground + { + get {return m_MenuUnusedBackground;} + set + { + if(m_MenuUnusedBackground!=value) + { + m_MenuUnusedBackground=value; + m_MenuUnusedBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuUnusedBackground() + { + return m_MenuUnusedBackgroundCustom; + } + /// + /// Specifies the side bar color for the items that were not recently used. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the side bar color for the items that were not recently used.")] + public Color MenuUnusedSide + { + get {return m_MenuUnusedSide;} + set + { + if(m_MenuUnusedSide!=value) + { + m_MenuUnusedSide=value; + m_MenuUnusedSideCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuUnusedSide() + { + return m_MenuUnusedSideCustom; + } + /// + /// Specifies the target gradient side bar color for the items that were not recently used. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the target gradient side bar color for the items that were not recently used.")] + public Color MenuUnusedSide2 + { + get {return m_MenuUnusedSide2;} + set + { + if(m_MenuUnusedSide2!=value) + { + m_MenuUnusedSide2=value; + m_MenuUnusedSide2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMenuUnusedSide2() + { + return m_MenuUnusedSide2Custom; + } + /// + /// Specifies the angle of the gradient fill for the menu part (left side) that is showing the images. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Menu Colors"),System.ComponentModel.Description("Specifies the angle of the gradient fill for the menu part (left side) that is showing the images."),DefaultValue(0)] + public int MenuUnusedSideGradientAngle + { + get {return m_MenuUnusedSideGradientAngle;} + set + { + if(m_MenuUnusedSideGradientAngle!=value) + { + m_MenuUnusedSideGradientAngle=value; + } + } + } + /// + /// Specifies the border color for focused design-time item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Design Colors"),System.ComponentModel.Description("Specifies the border color for focused design-time item.")] + public Color ItemDesignTimeBorder + { + get {return m_ItemDesignTimeBorder;} + set + { + if(m_ItemDesignTimeBorder!=value) + { + m_ItemDesignTimeBorder=value; + m_ItemDesignTimeBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeItemDesignTimeBorder() + { + return m_ItemDesignTimeBorderCustom; + } + + /// + /// Gets or sets predefined color scheme. By default DotNetBar will automatically change and generate color scheme depending on system colors. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Color Scheme"),System.ComponentModel.Description("Indicates predefined color scheme. By default DotNetBar will automatically change and generate color scheme depending on system colors."),DefaultValue(ePredefinedColorScheme.AutoGenerated)] + public ePredefinedColorScheme PredefinedColorScheme + { + get {return m_PredefinedColorScheme;} + set + { + if(m_PredefinedColorScheme!=value) + { + m_PredefinedColorScheme=value; + this.Refresh(); + } + } + } + + /// + /// Specifies the background color of the panel. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Panel Colors"),System.ComponentModel.Description("Specifies the background color of the panel.")] + public Color PanelBackground + { + get {return m_PanelBackground;} + set + { + if(m_PanelBackground!=value) + { + m_PanelBackground=value; + m_PanelBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePanelBackground() + { + return m_PanelBackgroundCustom; + } + /// + /// Specifies the target background gradient color of the panel. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Panel Colors"),System.ComponentModel.Description("Specifies the target background gradient color of the panel.")] + public Color PanelBackground2 + { + get {return m_PanelBackground2;} + set + { + if(m_PanelBackground2!=value) + { + m_PanelBackground2=value; + m_PanelBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePanelBackground2() + { + return m_PanelBackground2Custom; + } + /// + /// Specifies the angle of the gradient fill for the panel background. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Panel Colors"),System.ComponentModel.Description("Specifies the angle of the gradient fill for the panel background."),DefaultValue(90)] + public int PanelBackgroundGradientAngle + { + get {return m_PanelBackgroundGradientAngle;} + set + { + if(m_PanelBackgroundGradientAngle!=value) + { + m_PanelBackgroundGradientAngle=value; + } + } + } + /// + /// Specifies border color of the panel. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Panel Colors"),System.ComponentModel.Description("Specifies border color of the panel.")] + public Color PanelBorder + { + get {return m_PanelBorder;} + set + { + if(m_PanelBorder!=value) + { + m_PanelBorder=value; + m_PanelBorderCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePanelBorder() + { + return m_PanelBorderCustom; + } + /// + /// Specifies color of the text on the panel. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Panel Colors"),System.ComponentModel.Description("Specifies color of the text on the panel.")] + public Color PanelText + { + get {return m_PanelText;} + set + { + if(m_PanelText!=value) + { + m_PanelText=value; + m_PanelTextCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePanelText() + { + return m_PanelTextCustom; + } + + /// + /// Specifies the background color of the explorer bar. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Explorer Bar Colors"),System.ComponentModel.Description("Specifies the background color of the explorer bar.")] + public Color ExplorerBarBackground + { + get {return m_ExplorerBarBackground;} + set + { + if(m_ExplorerBarBackground!=value) + { + m_ExplorerBarBackground=value; + m_ExplorerBarBackgroundCustom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeExplorerBarBackground() + { + return m_ExplorerBarBackgroundCustom; + } + /// + /// Specifies the target gradient background color of the explorer bar. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Explorer Bar Colors"),System.ComponentModel.Description("Specifies target gradient background color of the explorer bar.")] + public Color ExplorerBarBackground2 + { + get {return m_ExplorerBarBackground2;} + set + { + if(m_ExplorerBarBackground2!=value) + { + m_ExplorerBarBackground2=value; + m_ExplorerBarBackground2Custom=true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeExplorerBarBackground2() + { + return m_ExplorerBarBackground2Custom; + } + /// + /// Specifies the angle of the gradient fill for the explorer bar background. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Explorer Bar Colors"),System.ComponentModel.Description("Specifies the angle of the gradient fill for the explorer bar background."),DefaultValue(90)] + public int ExplorerBarBackgroundGradientAngle + { + get {return m_ExplorerBarBackgroundGradientAngle;} + set + { + if(m_ExplorerBarBackgroundGradientAngle!=value) + { + m_ExplorerBarBackgroundGradientAngle=value; + } + } + } + + /// + /// Specifies the foreground color of MDI System Item buttons. + /// + [Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Item Colors"), System.ComponentModel.Description("Specifies the foreground color of MDI System Item buttons.")] + public Color MdiSystemItemForeground + { + get { return m_MdiSystemItemForeground; } + set + { + m_MdiSystemItemForeground = value; + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMdiSystemItemForeground() + { + return !m_MdiSystemItemForeground.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetMdiSystemItemForeground() + { + MdiSystemItemForeground = Color.Empty; + } + + + /// + /// Specifies the background color of the Splitter. + /// + [Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Splitter Colors"), System.ComponentModel.Description("Specifies the background color of the Splitter.")] + public Color SplitterBackground + { + get { return m_SplitterBackground; } + set + { + if (m_SplitterBackground != value) + { + m_SplitterBackground = value; + m_SplitterBackgroundCustom = true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSplitterBackground() + { + return m_SplitterBackgroundCustom; + } + /// + /// Specifies the target background gradient color of the Splitter. + /// + [Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Splitter Colors"), System.ComponentModel.Description("Specifies the target background gradient color of the Splitter.")] + public Color SplitterBackground2 + { + get { return m_SplitterBackground2; } + set + { + if (m_SplitterBackground2 != value) + { + m_SplitterBackground2 = value; + m_SplitterBackground2Custom = true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSplitterBackground2() + { + return m_SplitterBackground2Custom; + } + /// + /// Specifies the angle of the gradient fill for the Splitter background. + /// + [Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Splitter Colors"), System.ComponentModel.Description("Specifies the angle of the gradient fill for the Splitter background."), DefaultValue(90)] + public int SplitterBackgroundGradientAngle + { + get { return m_SplitterBackgroundGradientAngle; } + set + { + if (m_SplitterBackgroundGradientAngle != value) + { + m_SplitterBackgroundGradientAngle = value; + } + } + } + /// + /// Specifies border color of the Splitter. + /// + [Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Splitter Colors"), System.ComponentModel.Description("Specifies border color of the Splitter.")] + public Color SplitterBorder + { + get { return m_SplitterBorder; } + set + { + if (m_SplitterBorder != value) + { + m_SplitterBorder = value; + m_SplitterBorderCustom = true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSplitterBorder() + { + return m_SplitterBorderCustom; + } + /// + /// Specifies color of the text on the Splitter. + /// + [Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Splitter Colors"), System.ComponentModel.Description("Specifies color of the text on the Splitter.")] + public Color SplitterText + { + get { return m_SplitterText; } + set + { + if (m_SplitterText != value) + { + m_SplitterText = value; + m_SplitterTextCustom = true; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSplitterText() + { + return m_SplitterTextCustom; + } + + public void Refresh() + { + this.Refresh(null,false); + } + public void ResetChangedFlag() + { + m_BarCaptionBackgroundCustom=false; + m_BarCaptionBackground2Custom=false; + m_BarStripeColorCustom=false; + m_BarCaptionInactiveBackgroundCustom=false; + m_BarCaptionInactiveBackground2Custom=false; + m_BarCaptionInactiveTextCustom=false; + m_BarCaptionTextCustom=false; + m_BarFloatingBorderCustom=false; + m_BarPopupBackgroundCustom=false; + m_BarPopupBorderCustom=false; + m_BarDockedBorderCustom=false; + m_BarBackgroundCustom=false; + m_BarBackground2Custom=false; + m_ItemBackgroundCustom=false; + m_ItemBackground2Custom=false; + m_ItemCheckedBackgroundCustom=false; + m_ItemCheckedBackground2Custom=false; + m_ItemCheckedBorderCustom=false; + m_ItemCheckedTextCustom=false; + m_ItemDisabledBackgroundCustom=false; + m_ItemDisabledTextCustom=false; + m_ItemExpandedShadowCustom=false; + m_ItemExpandedBackgroundCustom=false; + m_ItemExpandedBackground2Custom=false; + m_ItemExpandedTextCustom=false; + m_ItemExpandedBorderCustom=false; + m_ItemHotBackgroundCustom=false; + m_ItemHotBackground2Custom=false; + m_ItemHotBorderCustom=false; + m_ItemHotTextCustom=false; + m_ItemPressedBackgroundCustom=false; + m_ItemPressedBackground2Custom=false; + m_ItemPressedBorderCustom=false; + m_ItemPressedTextCustom=false; + m_ItemSeparatorCustom=false; + m_ItemSeparatorShadeCustom=false; + m_ItemTextCustom=false; + m_MenuBackgroundCustom=false; + m_MenuBackground2Custom=false; + m_MenuBarBackgroundCustom=false; + m_MenuBarBackground2Custom=false; + m_MenuBorderCustom=false; + m_MenuSideCustom=false; + m_MenuSide2Custom=false; + m_MenuUnusedBackgroundCustom=false; + m_MenuUnusedSideCustom=false; + m_MenuUnusedSide2Custom=false; + m_ItemDesignTimeBorderCustom=false; + m_CustomizeBackgroundCustom=false; + m_CustomizeBackground2Custom=false; + m_CustomizeTextCustom=false; + m_PanelBackgroundCustom=false; + m_PanelBackground2Custom=false; + m_PanelBorderCustom=false; + m_PanelTextCustom=false; + m_SplitterBackgroundCustom = false; + m_SplitterBackground2Custom = false; + m_SplitterBorderCustom = false; + m_SplitterTextCustom = false; + m_ExplorerBarBackgroundCustom=false; + m_ExplorerBarBackground2Custom=false; + m_MdiSystemItemForeground = Color.Empty; + } + + [Browsable(false),DevCoBrowsable(false)] + public bool SchemeChanged + { + get + { + return m_BarCaptionBackgroundCustom || + m_BarCaptionBackground2Custom || + m_BarStripeColorCustom || + m_BarCaptionInactiveBackgroundCustom || + m_BarCaptionInactiveBackground2Custom || + m_BarCaptionInactiveTextCustom || + m_BarCaptionTextCustom || + m_BarFloatingBorderCustom || + m_BarPopupBackgroundCustom || + m_BarDockedBorderCustom || + m_BarPopupBorderCustom || + m_BarBackgroundCustom || + m_BarBackground2Custom || + m_ItemBackgroundCustom || + m_ItemCheckedBackgroundCustom || + m_ItemCheckedBackground2Custom || + m_ItemCheckedBorderCustom || + m_ItemCheckedTextCustom || + m_ItemDisabledBackgroundCustom || + m_ItemDisabledTextCustom || + m_ItemExpandedShadowCustom || + m_ItemExpandedBackgroundCustom || + m_ItemExpandedBackground2Custom || + m_ItemExpandedTextCustom || + m_ItemExpandedBorderCustom || + m_ItemHotBackgroundCustom || + m_ItemHotBackground2Custom || + m_ItemHotBorderCustom || + m_ItemHotTextCustom || + m_ItemPressedBackgroundCustom || + m_ItemPressedBackground2Custom || + m_ItemPressedBorderCustom || + m_ItemPressedTextCustom || + m_ItemSeparatorCustom || + m_ItemTextCustom || + m_MenuBackgroundCustom || + m_MenuBackground2Custom || + m_MenuBarBackgroundCustom || + m_MenuBarBackground2Custom || + m_MenuBorderCustom || + m_MenuSideCustom || + m_MenuSide2Custom || + m_MenuUnusedBackgroundCustom || + m_MenuUnusedSideCustom || + m_MenuUnusedSide2Custom || + m_ItemDesignTimeBorderCustom || + m_CustomizeBackgroundCustom || + m_CustomizeBackground2Custom || + m_DockSiteBackColorCustom || + m_DockSiteBackColor2Custom || + !m_MdiSystemItemForeground.IsEmpty || + (m_PredefinedColorScheme != ePredefinedColorScheme.AutoGenerated); + } + } + + private Image _AutoHidePanelBackgroundImage = null; + /// + /// Indicates auto-hide panel background image if any. + /// + [DefaultValue(null), Description("Indicates auto-hide panel background image if any."), Category("Auto-Hide Panel")] + public Image AutoHidePanelBackgroundImage + { + get { return _AutoHidePanelBackgroundImage; } + set { _AutoHidePanelBackgroundImage = value; } + } + private Color _AutoHidePanelBackground = Color.Empty; + /// + /// Gets or sets the color of the auto-hide panel background. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of auto-hide panel background.")] + public Color AutoHidePanelBackground + { + get { return _AutoHidePanelBackground; } + set { _AutoHidePanelBackground = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHidePanelBackground() + { + return !_AutoHidePanelBackground.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHidePanelBackground() + { + this.AutoHidePanelBackground = Color.Empty; + } + private Color _AutoHidePanelBackground2 = Color.Empty; + /// + /// Gets or sets the color of the auto-hide panel background. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of auto-hide panel background.")] + public Color AutoHidePanelBackground2 + { + get { return _AutoHidePanelBackground2; } + set { _AutoHidePanelBackground2 = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHidePanelBackground2() + { + return !_AutoHidePanelBackground2.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHidePanelBackground2() + { + this.AutoHidePanelBackground2 = Color.Empty; + } + + private Color _AutoHideTabBackground = Color.Empty; + /// + /// Gets or sets the color of the auto-hide tab. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of the auto-hide tab.")] + public Color AutoHideTabBackground + { + get { return _AutoHideTabBackground; } + set { _AutoHideTabBackground = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHideTabBackground() + { + return !_AutoHideTabBackground.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHideTabBackground() + { + this.AutoHideTabBackground = Color.Empty; + } + + private Color _AutoHideTabBackground2 = Color.Empty; + /// + /// Gets or sets the color of the auto-hide tab. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of auto-hide tab.")] + public Color AutoHideTabBackground2 + { + get { return _AutoHideTabBackground2; } + set { _AutoHideTabBackground2 = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHideTabBackground2() + { + return !_AutoHideTabBackground2.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHideTabBackground2() + { + this.AutoHideTabBackground2 = Color.Empty; + } + private int _AutoHideTabBackgroundGradientAngle = 90; + /// + /// Gets or sets the auto-hide tab background gradient angle. + /// + [DefaultValue(90), Category("Auto-Hide Panel"), Description("Gets or sets the auto-hide tab background gradient angle.")] + public int AutoHideTabBackgroundGradientAngle + { + get { return _AutoHideTabBackgroundGradientAngle; } + set { _AutoHideTabBackgroundGradientAngle = value; } + } + private Color _AutoHideTabText = Color.Empty; + /// + /// Gets or sets the color of the auto-hide tab text. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of auto-hide tab text.")] + public Color AutoHideTabText + { + get { return _AutoHideTabText; } + set { _AutoHideTabText = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHideTabText() + { + return !_AutoHideTabText.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHideTabText() + { + this.AutoHideTabText = Color.Empty; + } + private Color _AutoHideTabBorder = Color.Empty; + /// + /// Gets or sets the color of the auto-hide tab border. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of auto-hide tab border.")] + public Color AutoHideTabBorder + { + get { return _AutoHideTabBorder; } + set { _AutoHideTabBorder = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHideTabBorder() + { + return !_AutoHideTabBorder.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHideTabBorder() + { + this.AutoHideTabBorder = Color.Empty; + } + + private Color _AutoHideSelectedTabBackground = Color.Empty; + /// + /// Gets or sets the color of the auto-hide tab. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of the auto-hide tab.")] + public Color AutoHideSelectedTabBackground + { + get { return _AutoHideSelectedTabBackground; } + set { _AutoHideSelectedTabBackground = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHideSelectedTabBackground() + { + return !_AutoHideSelectedTabBackground.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHideSelectedTabBackground() + { + this.AutoHideSelectedTabBackground = Color.Empty; + } + + private Color _AutoHideSelectedTabBackground2 = Color.Empty; + /// + /// Gets or sets the color of the auto-hide tab. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of auto-hide tab.")] + public Color AutoHideSelectedTabBackground2 + { + get { return _AutoHideSelectedTabBackground2; } + set { _AutoHideSelectedTabBackground2 = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHideSelectedTabBackground2() + { + return !_AutoHideSelectedTabBackground2.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHideSelectedTabBackground2() + { + this.AutoHideSelectedTabBackground2 = Color.Empty; + } + + private Color _AutoHideSelectedTabText = Color.Empty; + /// + /// Gets or sets the color of the auto-hide tab text. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of auto-hide tab text.")] + public Color AutoHideSelectedTabText + { + get { return _AutoHideSelectedTabText; } + set { _AutoHideSelectedTabText = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHideSelectedTabText() + { + return !_AutoHideSelectedTabText.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHideSelectedTabText() + { + this.AutoHideSelectedTabText = Color.Empty; + } + + private Color _AutoHideSelectedTabBorder = Color.Empty; + /// + /// Gets or sets the color of the tab border. + /// + [Category("Auto-Hide Panel"), Description("Indicates color of tab border.")] + public Color AutoHideSelectedTabBorder + { + get { return _AutoHideSelectedTabBorder; } + set { _AutoHideSelectedTabBorder = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAutoHideSelectedTabBorder() + { + return !_AutoHideSelectedTabBorder.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAutoHideSelectedTabBorder() + { + this.AutoHideSelectedTabBorder = Color.Empty; + } + #endregion + + #region Color Scheme Generation + public void Refresh(System.Drawing.Graphics graphics, bool bSystemColorEvent) + { + if(!bSystemColorEvent) + { + ResetChangedFlag(); + } + + if (m_PredefinedColorScheme == ePredefinedColorScheme.Blue2003) + SchemeXpBlue2003(); + else if (m_PredefinedColorScheme == ePredefinedColorScheme.OliveGreen2003) + SchemeXpOliveGreen2003(); + else if (m_PredefinedColorScheme == ePredefinedColorScheme.Silver2003) + SchemeXpSilver2003(); + else if (m_PredefinedColorScheme == ePredefinedColorScheme.SystemColors) + GenerateScheme(); + else + { + if (Style == eDotNetBarStyle.Office2007) + SchemeOffice2007(); + else + { + eWinXPColorScheme xpc = BarFunctions.WinXPColorScheme; + if (xpc != eWinXPColorScheme.Undetermined) + { + if (xpc == eWinXPColorScheme.Blue) + { + if (Style == eDotNetBarStyle.Office2003) + SchemeXpBlue2003(); + else if (Style == eDotNetBarStyle.VS2005) + SchemeXpBlueVS2005(); + else + SchemeXpBlue(); + } + else if (xpc == eWinXPColorScheme.Silver) + { + if (Style == eDotNetBarStyle.Office2003) + SchemeXpSilver2003(); + else if (Style == eDotNetBarStyle.VS2005) + SchemeXpSilverVS2005(); + else + SchemeXpSilver(); + } + else if (xpc == eWinXPColorScheme.OliveGreen) + { + if (Style == eDotNetBarStyle.Office2003) + SchemeXpOliveGreen2003(); + else if (Style == eDotNetBarStyle.VS2005) + SchemeXpOliveGreenVS2005(); + else + SchemeXpOliveGreen(); + } + else + GenerateScheme(); + } + else + GenerateScheme(); + } + } + + bool bDisposeGraphics=false; + if(graphics==null) + { + IntPtr wnd=NativeFunctions.GetDesktopWindow(); + if(wnd!=IntPtr.Zero) + { + graphics=System.Drawing.Graphics.FromHwnd(wnd); + bDisposeGraphics=true; + } + } + try + { + if(graphics!=null) + { + if(!m_BarCaptionBackground.IsSystemColor && !m_BarCaptionBackground.IsEmpty) + m_BarCaptionBackground=graphics.GetNearestColor(m_BarCaptionBackground); + if(!m_BarCaptionBackground2.IsSystemColor && !m_BarCaptionBackground2.IsEmpty) + m_BarCaptionBackground2=graphics.GetNearestColor(m_BarCaptionBackground2); + if(!m_BarStripeColor.IsSystemColor && !m_BarStripeColor.IsEmpty) + m_BarStripeColor=graphics.GetNearestColor(m_BarStripeColor); + if(!m_BarCaptionInactiveBackground.IsSystemColor && !m_BarCaptionInactiveBackground.IsEmpty) + m_BarCaptionInactiveBackground=graphics.GetNearestColor(m_BarCaptionInactiveBackground); + if(!m_BarCaptionInactiveBackground2.IsSystemColor && !m_BarCaptionInactiveBackground2.IsEmpty) + m_BarCaptionInactiveBackground2=graphics.GetNearestColor(m_BarCaptionInactiveBackground2); + if(!m_BarCaptionInactiveText.IsSystemColor && !m_BarCaptionInactiveText.IsEmpty) + m_BarCaptionInactiveText=graphics.GetNearestColor(m_BarCaptionInactiveText); + if(!m_BarCaptionText.IsSystemColor && !m_BarCaptionText.IsEmpty) + m_BarCaptionText=graphics.GetNearestColor(m_BarCaptionText); + if(!m_BarFloatingBorder.IsSystemColor && !m_BarFloatingBorder.IsEmpty) + m_BarFloatingBorder=graphics.GetNearestColor(m_BarFloatingBorder); + if(!m_BarPopupBackground.IsSystemColor && !m_BarPopupBackground.IsEmpty) + m_BarPopupBackground=graphics.GetNearestColor(m_BarPopupBackground); + if(!m_BarPopupBorder.IsSystemColor && !m_BarPopupBorder.IsEmpty) + m_BarPopupBorder=graphics.GetNearestColor(m_BarPopupBorder); + if(!m_BarDockedBorder.IsSystemColor && !m_BarDockedBorder.IsEmpty) + m_BarDockedBorder=graphics.GetNearestColor(m_BarDockedBorder); + if(!m_BarBackground.IsSystemColor && !m_BarBackground.IsEmpty) + m_BarBackground=graphics.GetNearestColor(m_BarBackground); + if(!m_BarBackground2.IsEmpty && !m_BarBackground2.IsSystemColor) + m_BarBackground2=graphics.GetNearestColor(m_BarBackground2); + if(!m_ItemBackground.IsEmpty) + m_ItemBackground=graphics.GetNearestColor(m_ItemBackground); + if(!m_ItemBackground2.IsEmpty) + m_ItemBackground2=graphics.GetNearestColor(m_ItemBackground2); + if(!m_ItemCheckedBackground.IsSystemColor) + m_ItemCheckedBackground=graphics.GetNearestColor(m_ItemCheckedBackground); + if(!m_ItemCheckedBackground2.IsEmpty && !m_ItemCheckedBackground2.IsSystemColor) + m_ItemCheckedBackground2=graphics.GetNearestColor(m_ItemCheckedBackground2); + if(!m_ItemCheckedBorder.IsSystemColor) + m_ItemCheckedBorder=graphics.GetNearestColor(m_ItemCheckedBorder); + if(!m_ItemCheckedText.IsSystemColor) + m_ItemCheckedText=graphics.GetNearestColor(m_ItemCheckedText); + if(!m_ItemDisabledBackground.IsEmpty && !m_ItemDisabledBackground.IsSystemColor) + m_ItemDisabledBackground=graphics.GetNearestColor(m_ItemDisabledBackground); + if(!m_ItemDisabledText.IsSystemColor) + m_ItemDisabledText=graphics.GetNearestColor(m_ItemDisabledText); + if(!m_ItemExpandedShadow.IsSystemColor && !m_ItemExpandedShadow.IsEmpty) + m_ItemExpandedShadow=graphics.GetNearestColor(m_ItemExpandedShadow); + if(!m_ItemExpandedBackground.IsSystemColor) + m_ItemExpandedBackground=graphics.GetNearestColor(m_ItemExpandedBackground); + if(!m_ItemExpandedText.IsSystemColor) + m_ItemExpandedText=graphics.GetNearestColor(m_ItemExpandedText); + if(!m_ItemExpandedBorder.IsSystemColor) + m_ItemExpandedBorder=graphics.GetNearestColor(m_ItemExpandedBorder); + if(!m_ItemHotBackground.IsSystemColor) + m_ItemHotBackground=graphics.GetNearestColor(m_ItemHotBackground); + if(!m_ItemHotBackground2.IsEmpty && !m_ItemHotBackground2.IsSystemColor) + m_ItemHotBackground2=graphics.GetNearestColor(m_ItemHotBackground2); + if(!m_ItemHotBorder.IsSystemColor) + m_ItemHotBorder=graphics.GetNearestColor(m_ItemHotBorder); + if(!m_ItemHotText.IsSystemColor) + m_ItemHotText=graphics.GetNearestColor(m_ItemHotText); + if(!m_ItemPressedBackground.IsSystemColor) + m_ItemPressedBackground=graphics.GetNearestColor(m_ItemPressedBackground); + if(!m_ItemPressedBackground2.IsEmpty && !m_ItemPressedBackground2.IsSystemColor) + m_ItemPressedBackground2=graphics.GetNearestColor(m_ItemPressedBackground2); + if(!m_ItemPressedBorder.IsSystemColor) + m_ItemPressedBorder=graphics.GetNearestColor(m_ItemPressedBorder); + if(!m_ItemPressedText.IsSystemColor) + m_ItemPressedText=graphics.GetNearestColor(m_ItemPressedText); + if(!m_ItemSeparator.IsSystemColor) + m_ItemSeparator=graphics.GetNearestColor(m_ItemSeparator); + if(!m_ItemSeparatorShade.IsSystemColor && !m_ItemSeparatorShade.IsEmpty) + m_ItemSeparatorShade=graphics.GetNearestColor(m_ItemSeparatorShade); + if(!m_ItemText.IsSystemColor) + m_ItemText=graphics.GetNearestColor(m_ItemText); + if(!m_MenuBackground.IsSystemColor) + m_MenuBackground=graphics.GetNearestColor(m_MenuBackground); + if(!m_MenuBarBackground.IsSystemColor) + m_MenuBarBackground=graphics.GetNearestColor(m_MenuBarBackground); + if(!m_MenuBarBackground2.IsEmpty && !m_MenuBarBackground2.IsSystemColor) + m_MenuBarBackground2=graphics.GetNearestColor(m_MenuBarBackground2); + if(!m_MenuBorder.IsSystemColor) + m_MenuBorder=graphics.GetNearestColor(m_MenuBorder); + if(!m_MenuSide.IsSystemColor) + m_MenuSide=graphics.GetNearestColor(m_MenuSide); + if(!m_MenuUnusedBackground.IsSystemColor) + m_MenuUnusedBackground=graphics.GetNearestColor(m_MenuUnusedBackground); + if(!m_MenuUnusedSide.IsSystemColor) + m_MenuUnusedSide=graphics.GetNearestColor(m_MenuUnusedSide); + if(!m_ItemDesignTimeBorder.IsSystemColor) + m_ItemDesignTimeBorder=graphics.GetNearestColor(m_ItemDesignTimeBorder); + if(!m_CustomizeBackground.IsEmpty && !m_CustomizeBackground.IsSystemColor) + m_CustomizeBackground=graphics.GetNearestColor(m_CustomizeBackground); + if(!m_CustomizeBackground2.IsEmpty && !m_CustomizeBackground2.IsSystemColor) + m_CustomizeBackground2=graphics.GetNearestColor(m_CustomizeBackground2); + if(!m_CustomizeText.IsEmpty && !m_CustomizeText.IsSystemColor) + m_CustomizeText=graphics.GetNearestColor(m_CustomizeText); + } + } + finally + { + if(bDisposeGraphics) + graphics.Dispose(); + } + } + private void GenerateScheme() + { + if(m_Style==eDotNetBarStyle.Office2003 || m_Style==eDotNetBarStyle.VS2005) + GenerateScheme2003(); + else + GenerateSchemeDefault(); + } + private void GenerateSchemeDefault() + { + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground=ColorFunctions.MenuFocusBorderColor(); + m_BarCaptionBackground2=Color.Empty; + if(!m_BarStripeColorCustom) + m_BarStripeColor=SystemColors.ControlDark; + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground=SystemColors.Control; + m_BarCaptionInactiveBackground2=Color.Empty; + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=SystemColors.ControlText; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=SystemColors.ActiveCaptionText; + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=ColorFunctions.MenuFocusBorderColor(); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=SystemColors.Control; + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=ColorFunctions.MenuFocusBorderColor(); + if(!m_BarBackgroundCustom) + m_BarBackground=ColorFunctions.ToolMenuFocusBackColor(); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=ColorFunctions.CheckBoxBackColor(); + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=SystemColors.Highlight; + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=SystemColors.ControlDark; + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=SystemColors.ControlDark; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=ColorFunctions.ToolMenuFocusBackColor(); + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=ColorFunctions.HoverBackColor(); + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=SystemColors.Highlight; + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=ColorFunctions.PressedBackColor(); + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=SystemColors.Highlight; + if(!m_ItemPressedTextCustom) + m_ItemPressedText=SystemColors.ControlDarkDark; + if(!m_ItemSeparatorCustom) + m_ItemSeparator=SystemColors.ControlDark; + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=ColorFunctions.MenuBackColor(); + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=SystemColors.Control; + if(!m_MenuBorderCustom) + m_MenuBorder=SystemColors.ControlDark; + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=ColorFunctions.ToolMenuFocusBackColor(); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=ColorFunctions.SideRecentlyBackColor(); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=SystemColors.Highlight; + + if(!m_BarBackground2Custom) + m_BarBackground2=Color.Empty; + if(!m_MenuBarBackground2Custom) + m_MenuBarBackground2=Color.Empty; + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=Color.Empty; + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=Color.Empty; + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.Empty; + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.Empty; + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuSide2Custom) + m_MenuSide2=Color.Empty; + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=Color.Empty; + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=Color.Empty; + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.Empty; + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=Color.Empty; + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=Color.Empty; + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=Color.Empty; + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=Color.Empty; + if(!m_CustomizeTextCustom) + m_CustomizeText=Color.Empty; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=System.Windows.Forms.ControlPaint.Dark(m_BarBackground); + if(!m_PanelBackground2Custom) + m_PanelBackground2=System.Windows.Forms.ControlPaint.DarkDark(m_BarBackground); + if(!m_PanelTextCustom) + m_PanelText=System.Windows.Forms.ControlPaint.LightLight(m_BarBackground); + if(!m_PanelBorderCustom) + m_PanelBorder=System.Windows.Forms.ControlPaint.DarkDark(m_BarBackground); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = System.Windows.Forms.ControlPaint.Dark(m_BarBackground); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = System.Windows.Forms.ControlPaint.DarkDark(m_BarBackground); + if (!m_SplitterTextCustom) + m_SplitterText = System.Windows.Forms.ControlPaint.LightLight(m_BarBackground); + if (!m_SplitterBorderCustom) + m_SplitterBorder = System.Windows.Forms.ControlPaint.DarkDark(m_BarBackground); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=m_MenuBarBackground; + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=m_ItemSeparator; + + } + + private void GenerateScheme2003() + { + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground=ColorFunctions.MenuFocusBorderColor(); + if (!m_BarCaptionBackground2Custom) + m_BarCaptionBackground2 = System.Windows.Forms.ControlPaint.Light(m_BarCaptionBackground); + if(!m_BarStripeColorCustom) + m_BarStripeColor=SystemColors.ControlDark; + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground=SystemColors.Control; + m_BarCaptionInactiveBackground2=Color.Empty; + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=SystemColors.ControlText; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=SystemColors.ActiveCaptionText; + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=ColorFunctions.MenuFocusBorderColor(); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=SystemColors.Control; + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=ColorFunctions.MenuFocusBorderColor(); + if(!m_BarBackgroundCustom) + m_BarBackground=ColorFunctions.MenuBackColor(); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=ColorFunctions.CheckBoxBackColor(); + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.Empty; + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=SystemColors.Highlight; + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=SystemColors.ControlDark; + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=Color.Empty; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=ColorFunctions.ToolMenuFocusBackColor(); + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=ColorFunctions.HoverBackColor3(); + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=SystemColors.Highlight; + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=ColorFunctions.HoverBackColor2(); + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=SystemColors.Highlight; + if(!m_ItemPressedTextCustom) + m_ItemPressedText=SystemColors.ControlDarkDark; + if(!m_ItemSeparatorCustom) + m_ItemSeparator=SystemColors.ControlDark; + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=ColorFunctions.MenuBackColor(); + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=SystemColors.Control; + if(!m_MenuBorderCustom) + m_MenuBorder=SystemColors.ControlDark; + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=ColorFunctions.MenuBackColor(); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=ColorFunctions.SideRecentlyBackColor(); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=SystemColors.Highlight; + + if(!m_BarBackground2Custom) + m_BarBackground2=SystemColors.Control; + if(!m_MenuBarBackground2Custom) + m_MenuBarBackground2=Color.Empty; + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=ColorFunctions.HoverBackColor2(); + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=ColorFunctions.HoverBackColor3(); + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.Empty; + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.Empty; + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuSide2Custom) + m_MenuSide2=ColorFunctions.ToolMenuFocusBackColor(); + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=Color.Empty; + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=SystemColors.Control; + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=SystemColors.ControlLightLight; + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=SystemColors.Control; + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=ColorFunctions.MenuBackColor(); + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=SystemColors.ControlDark; + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=ColorFunctions.MenuFocusBorderColor(); + if(!m_CustomizeTextCustom) + m_CustomizeText=SystemColors.ControlText; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=(m_BarBackground2); + if(!m_PanelBackground2Custom) + m_PanelBackground2=System.Windows.Forms.ControlPaint.Dark(m_BarBackground2); + if(!m_PanelTextCustom) + m_PanelText=System.Windows.Forms.ControlPaint.LightLight(m_BarBackground); + if(!m_PanelBorderCustom) + m_PanelBorder=System.Windows.Forms.ControlPaint.DarkDark(m_BarBackground2); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = (m_BarBackground2); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = System.Windows.Forms.ControlPaint.Dark(m_BarBackground2); + if (!m_SplitterTextCustom) + m_SplitterText = System.Windows.Forms.ControlPaint.LightLight(m_BarBackground); + if (!m_SplitterBorderCustom) + m_SplitterBorder = System.Windows.Forms.ControlPaint.DarkDark(m_BarBackground2); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=m_MenuBarBackground; + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=m_ItemSeparator; + } + + private void SchemeXpBlue() + { + if(!m_BarBackgroundCustom) + m_BarBackground=Color.FromArgb(239,237,222); + if(!m_BarStripeColorCustom) + m_BarStripeColor=Color.FromArgb(191,188,177); + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground=Color.FromArgb(172,168,153); + m_BarCaptionBackground2=Color.Empty; + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground=SystemColors.Control; + m_BarCaptionInactiveBackground2=Color.Empty; + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=SystemColors.ControlText; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=Color.FromArgb(64,64,64); + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=Color.FromArgb(172,168,153); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=Color.FromArgb(252,252,249); + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=Color.FromArgb(138,134,122); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=Color.FromArgb(225,230,232); + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=SystemColors.Highlight; + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=SystemColors.ControlDark; + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=SystemColors.ControlDark; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=Color.FromArgb(239,237,222); + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=Color.FromArgb(193,210,238); + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=SystemColors.Highlight; + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=Color.FromArgb(152,181,226); + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=SystemColors.Highlight; + if(!m_ItemPressedTextCustom) + m_ItemPressedText=Color.FromArgb(73,73,73); + if(!m_ItemSeparatorCustom) + m_ItemSeparator=Color.FromArgb(197,194,184); + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=Color.FromArgb(252,252,249); + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=SystemColors.Control; + if(!m_MenuBorderCustom) + m_MenuBorder=SystemColors.ControlDark; + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=Color.FromArgb(239,237,222); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=Color.FromArgb(230,227,210); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=SystemColors.Highlight; + + if(!m_BarBackground2Custom) + m_BarBackground2=Color.Empty; + if(!m_MenuBarBackground2Custom) + m_MenuBarBackground2=Color.Empty; + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=Color.Empty; + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=Color.Empty; + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.Empty; + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.Empty; + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuSide2Custom) + m_MenuSide2=Color.Empty; + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=Color.Empty; + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=Color.Empty; + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.Empty; + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=Color.Empty; + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=Color.Empty; + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=Color.Empty; + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=Color.Empty; + if(!m_CustomizeTextCustom) + m_CustomizeText=Color.Empty; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=Color.FromArgb(89,135,214); + if(!m_PanelBackground2Custom) + m_PanelBackground2=Color.FromArgb(3,56,148); + if(!m_PanelTextCustom) + m_PanelText=Color.White; + if(!m_PanelBorderCustom) + m_PanelBorder=Color.FromArgb(0,45,150); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = Color.FromArgb(89, 135, 214); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = Color.FromArgb(3, 56, 148); + if (!m_SplitterTextCustom) + m_SplitterText = Color.White; + if (!m_SplitterBorderCustom) + m_SplitterBorder = Color.FromArgb(0, 45, 150); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=Color.FromArgb(123,162,231); + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=Color.FromArgb(99,117,214); + } + private void SchemeXpOliveGreen() + { + if(!m_BarBackgroundCustom) + m_BarBackground=Color.FromArgb(239,237,222); + if(!m_BarStripeColorCustom) + m_BarStripeColor=Color.FromArgb(191,188,177); + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground=Color.FromArgb(153,153,153); + m_BarCaptionBackground2=Color.Empty; + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground=SystemColors.Control; + m_BarCaptionInactiveBackground2=Color.Empty; + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=SystemColors.ControlText; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=Color.FromArgb(64,64,64); + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=Color.FromArgb(153,153,153); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=Color.FromArgb(252,252,249); + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=Color.FromArgb(138,134,122); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=Color.FromArgb(234,235,223); + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=SystemColors.Highlight; + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=SystemColors.ControlDark; + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=SystemColors.ControlDark; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=Color.FromArgb(239,237,222); + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=Color.FromArgb(206,209,195); + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=SystemColors.Highlight; + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=Color.FromArgb(201,208,184); + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=SystemColors.Highlight; + if(!m_ItemPressedTextCustom) + m_ItemPressedText=Color.FromArgb(102,102,102); + if(!m_ItemSeparatorCustom) + m_ItemSeparator=Color.FromArgb(197,194,184); + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=Color.FromArgb(252,252,249); + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=SystemColors.Control; + if(!m_MenuBorderCustom) + m_MenuBorder=SystemColors.ControlDark; + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=Color.FromArgb(239,237,222); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=Color.FromArgb(230,227,210); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=SystemColors.Highlight; + + if(!m_BarBackground2Custom) + m_BarBackground2=Color.Empty; + if(!m_MenuBarBackground2Custom) + m_MenuBarBackground2=Color.Empty; + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=Color.Empty; + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=Color.Empty; + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.Empty; + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.Empty; + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuSide2Custom) + m_MenuSide2=Color.Empty; + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=Color.Empty; + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=Color.Empty; + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.Empty; + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=Color.Empty; + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=Color.Empty; + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=Color.Empty; + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=Color.Empty; + if(!m_CustomizeTextCustom) + m_CustomizeText=Color.Empty; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=Color.FromArgb(175,192,130); + if(!m_PanelBackground2Custom) + m_PanelBackground2=Color.FromArgb(99,122,68); + if(!m_PanelTextCustom) + m_PanelText=Color.White; + if(!m_PanelBorderCustom) + m_PanelBorder=Color.FromArgb(96,128,88); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = Color.FromArgb(175, 192, 130); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = Color.FromArgb(99, 122, 68); + if (!m_SplitterTextCustom) + m_SplitterText = Color.White; + if (!m_SplitterBorderCustom) + m_SplitterBorder = Color.FromArgb(96, 128, 88); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=Color.FromArgb(204,217,173); + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=Color.FromArgb(165,189,132); + } + private void SchemeXpSilver() + { + if(!m_BarBackgroundCustom) + m_BarBackground=Color.FromArgb(229,228,232); + if(!m_BarStripeColorCustom) + m_BarStripeColor=Color.FromArgb(179,179,182); + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground=Color.FromArgb(157,157,161); + m_BarCaptionBackground2=Color.Empty; + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground=SystemColors.Control; + m_BarCaptionInactiveBackground2=Color.Empty; + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=SystemColors.ControlText; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=Color.FromArgb(53,53,53); + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=Color.FromArgb(157,157,161); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=Color.FromArgb(251,250,251); + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=Color.FromArgb(126,126,129); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=Color.FromArgb(233,234,237); + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=SystemColors.Highlight; + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=SystemColors.ControlDark; + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=SystemColors.ControlDark; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=Color.FromArgb(229,228,232); + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=Color.FromArgb(199,199,202); + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=Color.FromArgb(169,171,181); + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=Color.FromArgb(210,211,216); + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=SystemColors.Highlight; + if(!m_ItemPressedTextCustom) + m_ItemPressedText=SystemColors.ControlText; + if(!m_ItemSeparatorCustom) + m_ItemSeparator=Color.FromArgb(186,186,189); + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=Color.FromArgb(251,250,251); + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=SystemColors.Control; + if(!m_MenuBorderCustom) + m_MenuBorder=SystemColors.ControlDark; + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=Color.FromArgb(229,228,232); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=Color.FromArgb(217,216,220); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=SystemColors.Highlight; + + if(!m_BarBackground2Custom) + m_BarBackground2=Color.Empty; + if(!m_MenuBarBackground2Custom) + m_MenuBarBackground2=Color.Empty; + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=Color.Empty; + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=Color.Empty; + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.Empty; + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.Empty; + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuSide2Custom) + m_MenuSide2=Color.Empty; + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=Color.Empty; + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=Color.Empty; + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.Empty; + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=Color.Empty; + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=Color.Empty; + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=Color.Empty; + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=Color.Empty; + if(!m_CustomizeTextCustom) + m_CustomizeText=Color.Empty; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=Color.FromArgb(168,167,191); + if(!m_PanelBackground2Custom) + m_PanelBackground2=Color.FromArgb(112,111,145); + if(!m_PanelTextCustom) + m_PanelText=Color.White; + if(!m_PanelBorderCustom) + m_PanelBorder=Color.FromArgb(124,124,148); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = Color.FromArgb(168, 167, 191); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = Color.FromArgb(112, 111, 145); + if (!m_SplitterTextCustom) + m_SplitterText = Color.White; + if (!m_SplitterBorderCustom) + m_SplitterBorder = Color.FromArgb(124, 124, 148); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=Color.FromArgb(196,200,212); + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=Color.FromArgb(177,179,200); + } + + private void SchemeXpBlue2003() + { + if(!m_BarBackgroundCustom) + m_BarBackground=Color.FromArgb(223,237,254); + if(!m_BarBackground2Custom) + m_BarBackground2=Color.FromArgb(142,179,231); + if(!m_BarStripeColorCustom) + m_BarStripeColor=Color.FromArgb(39,65,118); + if (!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground = GetColor(0x6690E0); + if (!m_BarCaptionBackground2Custom) + m_BarCaptionBackground2 = Color.FromArgb(42, 102, 201); + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground = GetColor(0x6699FF); + if (!m_BarCaptionInactiveBackground2Custom) + m_BarCaptionInactiveBackground2 = GetColor(0x557BC2); + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=Color.White; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=Color.White; + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=Color.FromArgb(42,102,201); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=Color.FromArgb(246,246,246); + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=Color.FromArgb(0,45,150); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=Color.FromArgb(255,213,140); + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.FromArgb(255,173,85); + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=Color.FromArgb(0,0,128); + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=Color.FromArgb(141,141,141); + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=Color.Empty; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=Color.FromArgb(227,239,255); + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.FromArgb(147,181,231); + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=Color.FromArgb(255,244,204); + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=Color.FromArgb(255,208,145); + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=Color.FromArgb(0,0,128); + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=Color.FromArgb(254,142,75); + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=Color.FromArgb(255,207,139); + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=Color.FromArgb(0,0,128); + if(!m_ItemPressedTextCustom) + m_ItemPressedText=SystemColors.ControlText; + if(!m_ItemSeparatorCustom) + m_ItemSeparator=Color.FromArgb(106,140,203); + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.FromArgb(241,249,255); + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=Color.FromArgb(246,246,246); + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty;// Color.FromArgb(246,246,246); + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=Color.FromArgb(158,190,245); + if(!m_MenuBorderCustom) + m_MenuBorder=Color.FromArgb(0,45,150); + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=Color.FromArgb(227,239,255); + if(!m_MenuSide2Custom) + m_MenuSide2=Color.FromArgb(135,173,228); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=Color.FromArgb(203,221,246); + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=Color.FromArgb(121,161,220); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=Color.FromArgb(0,0,128); + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=Color.FromArgb(59,97,156); + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=Color.FromArgb(158,190,245); + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=Color.FromArgb(195,218,249); + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=Color.FromArgb(117,166,241); + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=Color.FromArgb(0,53,145); + if(!m_CustomizeTextCustom) + m_CustomizeText=SystemColors.ControlText; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=Color.FromArgb(89,135,214); + if(!m_PanelBackground2Custom) + m_PanelBackground2=Color.FromArgb(3,56,148); + if(!m_PanelTextCustom) + m_PanelText=Color.White; + if(!m_PanelBorderCustom) + m_PanelBorder=Color.FromArgb(0,45,150); + + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = Color.FromArgb(89, 135, 214); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = Color.FromArgb(3, 56, 148); + if (!m_SplitterTextCustom) + m_SplitterText = Color.White; + if (!m_SplitterBorderCustom) + m_SplitterBorder = Color.FromArgb(0, 45, 150); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=Color.FromArgb(123,162,231); + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=Color.FromArgb(99,117,214); + } + + private void SchemeXpOliveGreen2003() + { + if(!m_BarBackgroundCustom) + m_BarBackground=Color.FromArgb(244,247,222); + if(!m_BarBackground2Custom) + m_BarBackground2=Color.FromArgb(183,198,145); + if(!m_BarStripeColorCustom) + m_BarStripeColor=Color.FromArgb(81,94,51); + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground = Color.FromArgb(183, 198, 145); //Color.FromArgb(116, 134, 94); + if (!m_BarCaptionBackground2Custom) + m_BarCaptionBackground2 = Color.FromArgb(116, 134, 94); + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground = GetColor(0xD1DBB6); // Color.FromArgb(183, 198, 145); + if (!m_BarCaptionInactiveBackground2Custom) + m_BarCaptionInactiveBackground2 = Color.FromArgb(116, 134, 94); + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=Color.White; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=Color.White; + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=Color.FromArgb(116,134,94); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=Color.FromArgb(244,244,238); + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=Color.FromArgb(117,141,94); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=Color.FromArgb(255,213,140); + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.FromArgb(255,173,85); + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=Color.FromArgb(63,93,56); + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=Color.FromArgb(141,141,141); + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=Color.Empty; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=Color.FromArgb(236,240,213); + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.FromArgb(194,206,159); + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=Color.FromArgb(255,244,204); + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=Color.FromArgb(255,208,145); + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=Color.FromArgb(63,93,56); + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=Color.FromArgb(254,142,75); + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=Color.FromArgb(255,207,139); + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=Color.FromArgb(63,93,56); + if(!m_ItemPressedTextCustom) + m_ItemPressedText=SystemColors.ControlText; + if(!m_ItemSeparatorCustom) + m_ItemSeparator=Color.FromArgb(96,128,88); + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.FromArgb(244,247,222); + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=Color.FromArgb(244,244,238); + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=Color.FromArgb(217,217,168); + if(!m_MenuBorderCustom) + m_MenuBorder=Color.FromArgb(117,141,94); + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=Color.FromArgb(255,255,237); + if(!m_MenuSide2Custom) + m_MenuSide2=Color.FromArgb(184,199,146); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=Color.FromArgb(230,230,239); + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=Color.FromArgb(164,180,120); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=Color.FromArgb(63,93,56); + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=Color.FromArgb(96,128,88); + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=Color.FromArgb(217,217,167); + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=Color.FromArgb(242,240,228); + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=Color.FromArgb(176,194,140); + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=Color.FromArgb(96,119,107); + if(!m_CustomizeTextCustom) + m_CustomizeText=SystemColors.ControlText; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=Color.FromArgb(175,192,130); + if(!m_PanelBackground2Custom) + m_PanelBackground2=Color.FromArgb(99,122,68); + if(!m_PanelTextCustom) + m_PanelText=Color.White; + if(!m_PanelBorderCustom) + m_PanelBorder=Color.FromArgb(96,128,88); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = Color.FromArgb(175, 192, 130); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = Color.FromArgb(99, 122, 68); + if (!m_SplitterTextCustom) + m_SplitterText = Color.White; + if (!m_SplitterBorderCustom) + m_SplitterBorder = Color.FromArgb(96, 128, 88); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=Color.FromArgb(204,217,173); + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=Color.FromArgb(165,189,132); + } + + private void SchemeXpSilver2003() + { + if(!m_BarBackgroundCustom) + m_BarBackground=Color.FromArgb(243,244,250); + if(!m_BarBackground2Custom) + m_BarBackground2=Color.FromArgb(153,151,181); + if(!m_BarStripeColorCustom) + m_BarStripeColor=Color.FromArgb(84,84,117); + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground = Color.FromArgb(153, 151, 181); //Color.FromArgb(122, 121, 153); + if (!m_BarCaptionBackground2Custom) + m_BarCaptionBackground2 = Color.FromArgb(122, 121, 153); + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground = GetColor(0xA6A6B7); // Color.FromArgb(243, 244, 250); //Color.FromArgb(122, 121, 153); + if (!m_BarCaptionInactiveBackground2Custom) + m_BarCaptionInactiveBackground2 = Color.FromArgb(122, 121, 153); + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=Color.White; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=Color.White; + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=Color.FromArgb(122,121,153); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=Color.FromArgb(253,250,255); + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=Color.FromArgb(124,124,148); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=Color.FromArgb(255,213,140); + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.FromArgb(255,173,85); + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=Color.FromArgb(75,75,111); + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=Color.FromArgb(141,141,141); + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=Color.Empty; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=Color.FromArgb(232,233,241); + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.FromArgb(177,176,198); + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=Color.FromArgb(255,244,204); + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=Color.FromArgb(255,208,145); + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=Color.FromArgb(75,75,111); + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=Color.FromArgb(254,142,75); + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=Color.FromArgb(255,207,139); + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=Color.FromArgb(75,75,111); + if(!m_ItemPressedTextCustom) + m_ItemPressedText=SystemColors.ControlText; + if(!m_ItemSeparatorCustom) + m_ItemSeparator=Color.FromArgb(110,109,143); + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.White; + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=Color.FromArgb(253,250,255); + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=Color.FromArgb(215,215,229); + if(!m_MenuBorderCustom) + m_MenuBorder=Color.FromArgb(124,124,148); + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=Color.FromArgb(249,249,255); + if(!m_MenuSide2Custom) + m_MenuSide2=Color.FromArgb(159,157,185); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=Color.FromArgb(215,215,226); + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=Color.FromArgb(128,126,158); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=Color.FromArgb(84,84,117); + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=Color.FromArgb(124,124,148); + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=Color.FromArgb(215,215,229); + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=Color.FromArgb(243,243,247); + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=Color.FromArgb(179,178,200); + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=Color.FromArgb(118,116,146); + if(!m_CustomizeTextCustom) + m_CustomizeText=SystemColors.ControlText; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=Color.FromArgb(168,167,191); + if(!m_PanelBackground2Custom) + m_PanelBackground2=Color.FromArgb(112,111,145); + if(!m_PanelTextCustom) + m_PanelText=Color.White; + if(!m_PanelBorderCustom) + m_PanelBorder=Color.FromArgb(124,124,148); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = Color.FromArgb(168, 167, 191); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = Color.FromArgb(112, 111, 145); + if (!m_SplitterTextCustom) + m_SplitterText = Color.White; + if (!m_SplitterBorderCustom) + m_SplitterBorder = Color.FromArgb(124, 124, 148); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=Color.FromArgb(196,200,212); + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=Color.FromArgb(177,179,200); + } + + /// + /// VS.NET 2005 Blue Color Scheme + /// + private void SchemeXpBlueVS2005() + { + if(!m_BarBackgroundCustom) + m_BarBackground=Color.FromArgb(251,250,247); + if(!m_BarBackground2Custom) + m_BarBackground2=Color.FromArgb(181,181,154); + if(!m_BarStripeColorCustom) + m_BarStripeColor=Color.FromArgb(193,190,179); + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground=Color.FromArgb(0,84,227); + if(!m_BarCaptionBackground2Custom) + m_BarCaptionBackground2=Color.FromArgb(60,148,254); + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground=GetColor(0xCCC7BA); + if(!m_BarCaptionInactiveBackground2Custom) + m_BarCaptionInactiveBackground2=Color.Empty; + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=Color.Black; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=Color.White; + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=Color.FromArgb(146,143,130); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=Color.FromArgb(252,252,249); + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=Color.FromArgb(138,134,122); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=Color.FromArgb(225,230,232); + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.Empty; + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=Color.FromArgb(49,106,197); + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=Color.FromArgb(180,177,163); + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=Color.Empty; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=Color.FromArgb(251,250,247); + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.Empty; + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=Color.FromArgb(193,210,238); + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=Color.Empty; + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=Color.FromArgb(49,106,197); + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=Color.FromArgb(152,181,226); + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=Color.Empty; + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=Color.FromArgb(75,75,111); + if(!m_ItemPressedTextCustom) + m_ItemPressedText=SystemColors.ControlText; + if(!m_ItemSeparatorCustom) + m_ItemSeparator=Color.FromArgb(197,194,184); + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.Empty; + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=Color.FromArgb(252,252,249); + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=Color.FromArgb(229,229,215); + if(!m_MenuBorderCustom) + m_MenuBorder=Color.FromArgb(138,134,122); + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=m_MenuBackground; + if(!m_MenuSide2Custom) + m_MenuSide2=Color.FromArgb(186,186,160); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=m_MenuBackground; + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=System.Windows.Forms.ControlPaint.Light(Color.FromArgb(186,186,160)); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=Color.Black; + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=Color.FromArgb(146,146,118); + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=Color.FromArgb(229,229,215); + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=Color.FromArgb(250,250,247); + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=Color.FromArgb(239,238,235); + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=Color.FromArgb(152,152,126); + if(!m_CustomizeTextCustom) + m_CustomizeText=SystemColors.ControlText; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=GetColor(0xBFBFA2); + if(!m_PanelBackground2Custom) + m_PanelBackground2=Color.FromArgb(152,152,126); + if(!m_PanelTextCustom) + m_PanelText=Color.Black; + if(!m_PanelBorderCustom) + m_PanelBorder=Color.FromArgb(82,82,79); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = GetColor(0xBFBFA2); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = Color.FromArgb(152, 152, 126); + if (!m_SplitterTextCustom) + m_SplitterText = Color.Black; + if (!m_SplitterBorderCustom) + m_SplitterBorder = Color.FromArgb(82, 82, 79); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=Color.FromArgb(123,162,231); + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=Color.FromArgb(99,117,214); + } + + private void SchemeXpOliveGreenVS2005() + { + if(!m_BarBackgroundCustom) + m_BarBackground=GetColor(0xFAFAF6); + if(!m_BarBackground2Custom) + m_BarBackground2=GetColor(0xEDEADB); + if(!m_BarStripeColorCustom) + m_BarStripeColor=GetColor(0xC1BEB3); + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground=GetColor(0x8BA169); + if(!m_BarCaptionBackground2Custom) + m_BarCaptionBackground2=GetColor(0xC5D1A1); + if (!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground = GetColor(0xCCC7BA); + if (!m_BarCaptionInactiveBackground2Custom) + m_BarCaptionInactiveBackground2 = Color.Empty; + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=Color.Black; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=Color.White; + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=GetColor(0x928F82); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=GetColor(0xFCFCF9); + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=GetColor(0x8A867A); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=GetColor(0xB6C68D); + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=Color.Empty; + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=GetColor(0x93A070); + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=GetColor(0xB4B1A3); + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=Color.Empty; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=GetColor(0xF9F9F4); + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=Color.Empty; + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=GetColor(0xB6C68D); + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=Color.Empty; + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=GetColor(0x93A070); + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=GetColor(0x93A070); + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=Color.Empty; + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=GetColor(0x93A070); + if(!m_ItemPressedTextCustom) + m_ItemPressedText=Color.White; + if(!m_ItemSeparatorCustom) + m_ItemSeparator=GetColor(0xC5C2B8); + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.Empty; + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=GetColor(0xFCFCF9); + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=GetColor(0xECE9D8); + if(!m_MenuBorderCustom) + m_MenuBorder=GetColor(0x8A867A); + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=GetColor(0xFCFCF9); + if(!m_MenuSide2Custom) + m_MenuSide2=GetColor(0xEDEADB); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=m_MenuSide; + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=System.Windows.Forms.ControlPaint.Light(m_MenuSide2); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=Color.Black; + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=GetColor(0xEFEDDE); + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=GetColor(0xECE9D8); + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=GetColor(0xFAF9F6); + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=GetColor(0xEFEEEB); + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=GetColor(0xACA899); + if(!m_CustomizeTextCustom) + m_CustomizeText=SystemColors.ControlText; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=GetColor(0xF3F2EA); + if(!m_PanelBackground2Custom) + m_PanelBackground2=GetColor(0xE4E2D5); + if(!m_PanelTextCustom) + m_PanelText=Color.Black; + if(!m_PanelBorderCustom) + m_PanelBorder=GetColor(0xACA899); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = GetColor(0xF3F2EA); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = GetColor(0xE4E2D5); + if (!m_SplitterTextCustom) + m_SplitterText = Color.Black; + if (!m_SplitterBorderCustom) + m_SplitterBorder = GetColor(0xACA899); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=Color.FromArgb(204,217,173); + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=Color.FromArgb(165,189,132); + } + + private void SchemeXpSilverVS2005() + { + if(!m_BarBackgroundCustom) + m_BarBackground=GetColor(0xF3F4FA); + if(!m_BarBackground2Custom) + m_BarBackground2=GetColor(0x9997B5); + if(!m_BarStripeColorCustom) + m_BarStripeColor=GetColor(0x545475); + if(!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground=GetColor(0xA09EBA); + if(!m_BarCaptionBackground2Custom) + m_BarCaptionBackground2=GetColor(0xE1E2EC); + if(!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground = GetColor(0xCECECE); + if(!m_BarCaptionInactiveBackground2Custom) + m_BarCaptionInactiveBackground2=GetColor(0xF2F2F6); + if(!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText=Color.Black; + if(!m_BarCaptionTextCustom) + m_BarCaptionText=Color.Black; + if(!m_BarFloatingBorderCustom) + m_BarFloatingBorder=GetColor(0x7A7999); + if(!m_BarPopupBackgroundCustom) + m_BarPopupBackground=GetColor(0xFDFAFF); + if(!m_BarPopupBorderCustom) + m_BarPopupBorder=GetColor(0x7C7C94); + if(!m_ItemBackgroundCustom) + m_ItemBackground=Color.Empty; + if(!m_ItemBackground2Custom) + m_ItemBackground2=Color.Empty; + if(!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground=GetColor(0xFFD58C); + if(!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2=GetColor(0xFFAD55); + if(!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder=GetColor(0x4B4B6F); + if(!m_ItemCheckedTextCustom) + m_ItemCheckedText=SystemColors.ControlText; + if(!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground=Color.Empty; + if(!m_ItemDisabledTextCustom) + m_ItemDisabledText=GetColor(0x8D8D8D); + if(!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow=Color.Empty; + if(!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground=GetColor(0xE8E9F1); + if(!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2=GetColor(0xBAB9CD); + if(!m_ItemExpandedTextCustom) + m_ItemExpandedText=SystemColors.ControlText; + if(!m_ItemHotBackgroundCustom) + m_ItemHotBackground=GetColor(0xFFF4CC); + if(!m_ItemHotBackground2Custom) + m_ItemHotBackground2=GetColor(0xFFD091); + if(!m_ItemHotBorderCustom) + m_ItemHotBorder=GetColor(0x4B4B6F); + if(!m_ItemHotTextCustom) + m_ItemHotText=SystemColors.ControlText; + if(!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground=GetColor(0xFE914E); + if(!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2=GetColor(0xFFD38E); + if(!m_ItemPressedBorderCustom) + m_ItemPressedBorder=GetColor(0x4B4B6F); + if(!m_ItemPressedTextCustom) + m_ItemPressedText=Color.Black; + if(!m_ItemSeparatorCustom) + m_ItemSeparator=GetColor(0x6E6D8F); + if(!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade=Color.Empty; + if(!m_ItemTextCustom) + m_ItemText=SystemColors.ControlText; + if(!m_MenuBackgroundCustom) + m_MenuBackground=GetColor(0xFDFAFF); + if(!m_MenuBackground2Custom) + m_MenuBackground2=Color.Empty; + if(!m_MenuBarBackgroundCustom) + m_MenuBarBackground=GetColor(0xD7D7E5); + if(!m_MenuBorderCustom) + m_MenuBorder=GetColor(0x7C7C94); + if(!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder=m_MenuBorder; + if(!m_MenuSideCustom) + m_MenuSide=GetColor(0xF9F9FF); + if(!m_MenuSide2Custom) + m_MenuSide2=GetColor(0x9F9DB9); + if(!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground=m_MenuBackground; + if(!m_MenuUnusedSideCustom) + m_MenuUnusedSide=m_MenuSide; + if(!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2=System.Windows.Forms.ControlPaint.Light(m_MenuSide2); + if(!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder=Color.Black; + if(!m_BarDockedBorderCustom) + m_BarDockedBorder=GetColor(0x7C7C94); + + if(!m_DockSiteBackColorCustom) + m_DockSiteBackColor=GetColor(0xD7D7E5); + if(!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2=GetColor(0xF3F3F7); + + if(!m_CustomizeBackgroundCustom) + m_CustomizeBackground=GetColor(0xB3B2C8); + if(!m_CustomizeBackground2Custom) + m_CustomizeBackground2=GetColor(0x797794); + if(!m_CustomizeTextCustom) + m_CustomizeText=SystemColors.ControlText; + + if(!m_PanelBackgroundCustom) + m_PanelBackground=GetColor(0xEEEEEE); + if(!m_PanelBackground2Custom) + m_PanelBackground2=GetColor(0xFFFFFF); + if(!m_PanelTextCustom) + m_PanelText=Color.Black; + if(!m_PanelBorderCustom) + m_PanelBorder=GetColor(0x9D9DA1); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = GetColor(0xEEEEEE); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = GetColor(0xFFFFFF); + if (!m_SplitterTextCustom) + m_SplitterText = Color.Black; + if (!m_SplitterBorderCustom) + m_SplitterBorder = GetColor(0x9D9DA1); + + if(!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground=Color.FromArgb(196,200,212); + if(!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2=Color.FromArgb(177,179,200); + } + + private void SchemeOffice2007() + { + if (!m_BarBackgroundCustom) + m_BarBackground = GetColor(0xE3EFFF); + if (!m_BarBackground2Custom) + m_BarBackground2 = GetColor(0xA9CEFE); + if (!m_BarStripeColorCustom) + m_BarStripeColor = GetColor(0x6F9DD9); + if (!m_BarCaptionBackgroundCustom) + m_BarCaptionBackground = GetColor(0x6593CF); + if (!m_BarCaptionBackground2Custom) + m_BarCaptionBackground2 = GetColor(0x3764A0); + if (!m_BarCaptionInactiveBackgroundCustom) + m_BarCaptionInactiveBackground = GetColor(0xE3EFFF); + if (!m_BarCaptionInactiveBackground2Custom) + m_BarCaptionInactiveBackground2 = GetColor(0xAFD2FF); + if (!m_BarCaptionInactiveTextCustom) + m_BarCaptionInactiveText = GetColor(0x083772); + if (!m_BarCaptionTextCustom) + m_BarCaptionText = GetColor(0xFFFFFF); + if (!m_BarFloatingBorderCustom) + m_BarFloatingBorder = GetColor(0x3764A0); + if (!m_BarPopupBackgroundCustom) + m_BarPopupBackground = GetColor(0xF6F6F6); + if (!m_BarPopupBorderCustom) + m_BarPopupBorder = GetColor(0x6593CF); + if (!m_ItemBackgroundCustom) + m_ItemBackground = Color.Empty; + if (!m_ItemBackground2Custom) + m_ItemBackground2 = Color.Empty; + if (!m_ItemCheckedBackgroundCustom) + m_ItemCheckedBackground = GetColor(0xFCD578); + if (!m_ItemCheckedBackground2Custom) + m_ItemCheckedBackground2 = GetColor(0xFBC84F); + if (!m_ItemCheckedBorderCustom) + m_ItemCheckedBorder = GetColor(0xBB5503); + if (!m_ItemCheckedTextCustom) + m_ItemCheckedText = GetColor(0x000000); + if (!m_ItemDisabledBackgroundCustom) + m_ItemDisabledBackground = Color.Empty; + if (!m_ItemDisabledTextCustom) + m_ItemDisabledText = GetColor(0x8D8D8D); + if (!m_ItemExpandedShadowCustom) + m_ItemExpandedShadow = Color.Empty; + if (!m_ItemExpandedBackgroundCustom) + m_ItemExpandedBackground = GetColor(0xE3EFFE); + if (!m_ItemExpandedBackground2Custom) + m_ItemExpandedBackground2 = GetColor(0x99BFF0); + if (!m_ItemExpandedTextCustom) + m_ItemExpandedText = GetColor(0x000000); + if (!m_ItemHotBackgroundCustom) + m_ItemHotBackground = GetColor(0xFFF5CC); + if (!m_ItemHotBackground2Custom) + m_ItemHotBackground2 = GetColor(0xFFDB75); + if (!m_ItemHotBorderCustom) + m_ItemHotBorder = GetColor(0xFFBD69); + if (!m_ItemHotTextCustom) + m_ItemHotText = GetColor(0x000000); + if (!m_ItemPressedBackgroundCustom) + m_ItemPressedBackground = GetColor(0xFC973D); + if (!m_ItemPressedBackground2Custom) + m_ItemPressedBackground2 = GetColor(0xFFB85E); + if (!m_ItemPressedBorderCustom) + m_ItemPressedBorder = GetColor(0xFB8C3C); + if (!m_ItemPressedTextCustom) + m_ItemPressedText = GetColor(0x000000); + if (!m_ItemSeparatorCustom) + m_ItemSeparator = Color.FromArgb(80, GetColor(0x9AC6FF)); + if (!m_ItemSeparatorShadeCustom) + m_ItemSeparatorShade = Color.FromArgb(250, GetColor(0xFFFFFF)); + if (!m_ItemTextCustom) + m_ItemText = GetColor(0x000000); // SystemColors.ControlTet; + if (!m_MenuBackgroundCustom) + m_MenuBackground = GetColor(0xF6F6F6); + if (!m_MenuBackground2Custom) + m_MenuBackground2 = Color.Empty; // Color.White; + if (!m_MenuBarBackgroundCustom) + m_MenuBarBackground = GetColor(0xBFDBFF); + if (!m_MenuBorderCustom) + m_MenuBorder = GetColor(0x6593CF); + if (!m_ItemExpandedBorderCustom) + m_ItemExpandedBorder = m_MenuBorder; + if (!m_MenuSideCustom) + m_MenuSide = GetColor(0xE9EEEE); + if (!m_MenuSide2Custom) + m_MenuSide2 = Color.Empty; // GetColor(0xDDE0E8); + if (!m_MenuUnusedBackgroundCustom) + m_MenuUnusedBackground = m_MenuBackground; + if (!m_MenuUnusedSideCustom) + m_MenuUnusedSide = GetColor(0xDADADA); + if (!m_MenuUnusedSide2Custom) + m_MenuUnusedSide2 = Color.Empty;// System.Windows.Forms.ControlPaint.Light(m_MenuSide2); + if (!m_ItemDesignTimeBorderCustom) + m_ItemDesignTimeBorder = Color.Black; + if (!m_BarDockedBorderCustom) + m_BarDockedBorder = GetColor(0x6F9DD9); + + if (!m_DockSiteBackColorCustom) + m_DockSiteBackColor = GetColor(0xBFDBFF); + if (!m_DockSiteBackColor2Custom) + m_DockSiteBackColor2 = Color.Empty; + + if (!m_CustomizeBackgroundCustom) + m_CustomizeBackground = GetColor(0xD7E8FF); + if (!m_CustomizeBackground2Custom) + m_CustomizeBackground2 = GetColor(0x6F9DD9); + if (!m_CustomizeTextCustom) + m_CustomizeText = GetColor(0x000000); + + if (!m_PanelBackgroundCustom) + m_PanelBackground = GetColor(0xE3EFFF); + if (!m_PanelBackground2Custom) + m_PanelBackground2 = GetColor(0xAFD2FF); + if (!m_PanelTextCustom) + m_PanelText = GetColor(0x083772); + if (!m_PanelBorderCustom) + m_PanelBorder = GetColor(0x6593CF); + + if (!m_SplitterBackgroundCustom) + m_SplitterBackground = GetColor(0xE3EFFF); + if (!m_SplitterBackground2Custom) + m_SplitterBackground2 = GetColor(0xAFD2FF); + if (!m_SplitterTextCustom) + m_SplitterText = GetColor(0x083772); + if (!m_SplitterBorderCustom) + m_SplitterBorder = GetColor(0x6593CF); + + if (!m_ExplorerBarBackgroundCustom) m_ExplorerBarBackground = Color.FromArgb(196, 200, 212); + if (!m_ExplorerBarBackground2Custom) m_ExplorerBarBackground2 = Color.FromArgb(177, 179, 200); + } + + /// + /// Converts hex string to Color type. + /// + /// Hexadecimal color representation. + /// Reference to Color object. + public static Color GetColor(string rgbHex) + { + if(string.IsNullOrEmpty(rgbHex)) + return Color.Empty; + if(rgbHex.Length == 8) + return Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0, 2), 16), + Convert.ToInt32(rgbHex.Substring(2, 2), 16), + Convert.ToInt32(rgbHex.Substring(4, 2), 16), + Convert.ToInt32(rgbHex.Substring(6, 2), 16)); + + return Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0,2),16), + Convert.ToInt32(rgbHex.Substring(2,2),16), + Convert.ToInt32(rgbHex.Substring(4,2),16)); + } + + /// + /// Converts hex string to Color type. + /// + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int rgb) + { + if (rgb == -1) return Color.Empty; + return Color.FromArgb((rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF); + } + + /// + /// Converts hex string to Color type. + /// + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int alpha, int rgb) + { + if (rgb == -1) return Color.Empty; + return Color.FromArgb(alpha, (rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF); + } + #endregion + + #region Serialization + public void Serialize(System.Xml.XmlElement xmlElem) + { + if(m_BarBackgroundCustom) + xmlElem.SetAttribute("barback",BarFunctions.ColorToString(m_BarBackground)); + if(m_BarBackground2Custom) + xmlElem.SetAttribute("barback2",BarFunctions.ColorToString(m_BarBackground2)); + if(m_BarBackgroundGradientAngle!=90) + xmlElem.SetAttribute("barbackga",m_BarBackgroundGradientAngle.ToString()); + if(m_BarStripeColorCustom) + xmlElem.SetAttribute("barstripeclr",BarFunctions.ColorToString(m_BarStripeColor)); + if(m_BarCaptionBackgroundCustom) + xmlElem.SetAttribute("barcapback",BarFunctions.ColorToString(m_BarCaptionBackground)); + if(m_BarCaptionBackground2Custom) + xmlElem.SetAttribute("barcapback2",BarFunctions.ColorToString(m_BarCaptionBackground2)); + if(m_BarCaptionBackgroundGradientAngle!=90) + xmlElem.SetAttribute("barcapbackga",m_BarCaptionBackgroundGradientAngle.ToString()); + if(m_BarCaptionInactiveBackgroundCustom) + xmlElem.SetAttribute("barcapiback",BarFunctions.ColorToString(m_BarCaptionInactiveBackground)); + if(m_BarCaptionInactiveBackground2Custom) + xmlElem.SetAttribute("barcapiback2",BarFunctions.ColorToString(m_BarCaptionInactiveBackground2)); + if(m_BarCaptionInactiveBackgroundGAngle!=90) + xmlElem.SetAttribute("barcapibackga",m_BarCaptionInactiveBackgroundGAngle.ToString()); + if(m_BarDockedBorderCustom) + xmlElem.SetAttribute("bardockborder",BarFunctions.ColorToString(m_BarDockedBorder)); + if(m_BarCaptionInactiveTextCustom) + xmlElem.SetAttribute("barcapitext",BarFunctions.ColorToString(m_BarCaptionInactiveText)); + if(m_BarCaptionTextCustom) + xmlElem.SetAttribute("barcaptext",BarFunctions.ColorToString(m_BarCaptionText)); + if(m_BarFloatingBorderCustom) + xmlElem.SetAttribute("barfloatb",BarFunctions.ColorToString(m_BarFloatingBorder)); + if(m_BarPopupBackgroundCustom) + xmlElem.SetAttribute("barpopupback",BarFunctions.ColorToString(m_BarPopupBackground)); + if(m_BarPopupBorderCustom) + xmlElem.SetAttribute("barpopupb",BarFunctions.ColorToString(m_BarPopupBorder)); + if(m_ItemBackgroundCustom) + xmlElem.SetAttribute("itemback",BarFunctions.ColorToString(m_ItemBackground)); + if(m_ItemBackground2Custom) + xmlElem.SetAttribute("itemback2",BarFunctions.ColorToString(m_ItemBackground2)); + if(m_ItemBackgroundGradientAngle!=90) + xmlElem.SetAttribute("itembackga",m_ItemBackgroundGradientAngle.ToString()); + if(m_ItemCheckedBackgroundCustom) + xmlElem.SetAttribute("itemchkback",BarFunctions.ColorToString(m_ItemCheckedBackground)); + if(m_ItemCheckedBackground2Custom) + xmlElem.SetAttribute("itemchkback2",BarFunctions.ColorToString(m_ItemCheckedBackground2)); + if(m_ItemCheckedBackgroundGradientAngle!=90) + xmlElem.SetAttribute("itemchkbackga",m_ItemCheckedBackgroundGradientAngle.ToString()); + if(m_ItemCheckedBorderCustom) + xmlElem.SetAttribute("itemchkb",BarFunctions.ColorToString(m_ItemCheckedBorder)); + if(m_ItemCheckedTextCustom) + xmlElem.SetAttribute("itemchktext",BarFunctions.ColorToString(m_ItemCheckedText)); + if(m_ItemDisabledBackgroundCustom && !m_ItemDisabledBackground.IsEmpty) + xmlElem.SetAttribute("itemdisback",BarFunctions.ColorToString(m_ItemDisabledBackground)); + if(m_ItemDisabledTextCustom) + xmlElem.SetAttribute("itemdistext",BarFunctions.ColorToString(m_ItemDisabledText)); + if(m_ItemExpandedShadowCustom) + xmlElem.SetAttribute("itemexpshadow",BarFunctions.ColorToString(m_ItemExpandedShadow)); + if(m_ItemExpandedBackgroundCustom) + xmlElem.SetAttribute("itemexpback",BarFunctions.ColorToString(m_ItemExpandedBackground)); + if(m_ItemExpandedBackground2Custom) + xmlElem.SetAttribute("itemexpback2",BarFunctions.ColorToString(m_ItemExpandedBackground2)); + if(m_ItemExpandedBackgroundGradientAngle!=90) + xmlElem.SetAttribute("itemexpbackga",m_ItemExpandedBackgroundGradientAngle.ToString()); + if(m_ItemExpandedTextCustom) + xmlElem.SetAttribute("itemexptext",BarFunctions.ColorToString(m_ItemExpandedText)); + if(m_ItemExpandedBorderCustom) + xmlElem.SetAttribute("itemexpborder",BarFunctions.ColorToString(m_ItemExpandedBorder)); + if(m_ItemHotBackgroundCustom) + xmlElem.SetAttribute("itemhotback",BarFunctions.ColorToString(m_ItemHotBackground)); + if(m_ItemHotBackground2Custom) + xmlElem.SetAttribute("itemhotback2",BarFunctions.ColorToString(m_ItemHotBackground2)); + if(m_ItemHotBackgroundGradientAngle!=90) + xmlElem.SetAttribute("itemhotbackga",m_ItemHotBackgroundGradientAngle.ToString()); + if(m_ItemHotBorderCustom) + xmlElem.SetAttribute("itemhotb",BarFunctions.ColorToString(m_ItemHotBorder)); + if(m_ItemHotTextCustom) + xmlElem.SetAttribute("itemhottext",BarFunctions.ColorToString(m_ItemHotText)); + if(m_ItemPressedBackgroundCustom) + xmlElem.SetAttribute("itempressback",BarFunctions.ColorToString(m_ItemPressedBackground)); + if(m_ItemPressedBackground2Custom) + xmlElem.SetAttribute("itempressback2",BarFunctions.ColorToString(m_ItemPressedBackground2)); + if(m_ItemPressedBackgroundGradientAngle!=90) + xmlElem.SetAttribute("itempressbackga",m_ItemPressedBackgroundGradientAngle.ToString()); + if(m_ItemPressedBorderCustom) + xmlElem.SetAttribute("itempressb",BarFunctions.ColorToString(m_ItemPressedBorder)); + if(m_ItemPressedTextCustom) + xmlElem.SetAttribute("itempresstext",BarFunctions.ColorToString(m_ItemPressedText)); + if(m_ItemSeparatorCustom) + xmlElem.SetAttribute("itemsep",BarFunctions.ColorToString(m_ItemSeparator)); + if(m_ItemTextCustom) + xmlElem.SetAttribute("itemtext",BarFunctions.ColorToString(m_ItemText)); + if(m_MenuBackgroundCustom) + xmlElem.SetAttribute("menuback",BarFunctions.ColorToString(m_MenuBackground)); + if(m_MenuBackground2Custom) + xmlElem.SetAttribute("menuback2",BarFunctions.ColorToString(m_MenuBackground2)); + if(m_MenuBackgroundGradientAngle!=0) + xmlElem.SetAttribute("menubackga",m_MenuBackgroundGradientAngle.ToString()); + if(m_MenuBarBackgroundCustom) + xmlElem.SetAttribute("menubarback",BarFunctions.ColorToString(m_MenuBarBackground)); + if(m_MenuBarBackground2Custom) + xmlElem.SetAttribute("menubarback2",BarFunctions.ColorToString(m_MenuBarBackground2)); + if(m_MenuBarBackgroundGradientAngle!=90) + xmlElem.SetAttribute("menubarbackga",m_MenuBarBackgroundGradientAngle.ToString()); + if(m_MenuBorderCustom) + xmlElem.SetAttribute("menub",BarFunctions.ColorToString(m_MenuBorder)); + if(m_MenuSideCustom) + xmlElem.SetAttribute("menuside",BarFunctions.ColorToString(m_MenuSide)); + if(m_MenuSide2Custom) + xmlElem.SetAttribute("menuside2",BarFunctions.ColorToString(m_MenuSide2)); + if(m_MenuSideGradientAngle!=0) + xmlElem.SetAttribute("menusidega",m_MenuSideGradientAngle.ToString()); + if(m_MenuUnusedBackgroundCustom) + xmlElem.SetAttribute("menuuback",BarFunctions.ColorToString(m_MenuUnusedBackground)); + if(m_MenuUnusedSideCustom) + xmlElem.SetAttribute("menuuside",BarFunctions.ColorToString(m_MenuUnusedSide)); + if(m_MenuUnusedSide2Custom) + xmlElem.SetAttribute("menuuside2",BarFunctions.ColorToString(m_MenuUnusedSide2)); + if(m_MenuSideGradientAngle!=0) + xmlElem.SetAttribute("menuusidega",m_MenuSideGradientAngle.ToString()); + if(m_ItemDesignTimeBorderCustom) + xmlElem.SetAttribute("menudtb",BarFunctions.ColorToString(m_ItemDesignTimeBorder)); + if(m_CustomizeBackgroundCustom) + xmlElem.SetAttribute("customback",BarFunctions.ColorToString(m_CustomizeBackground)); + if(m_CustomizeBackground2Custom) + xmlElem.SetAttribute("customback2",BarFunctions.ColorToString(m_CustomizeBackground2)); + if(m_CustomizeTextCustom) + xmlElem.SetAttribute("customtext",BarFunctions.ColorToString(m_CustomizeText)); + if(m_CustomizeBackgroundGradientAngle!=90) + xmlElem.SetAttribute("custombackga",m_CustomizeBackgroundGradientAngle.ToString()); + + // Panel Colors + if(m_PanelBackgroundCustom) + xmlElem.SetAttribute("panelback",BarFunctions.ColorToString(m_PanelBackground)); + if(m_PanelBackground2Custom) + xmlElem.SetAttribute("panelback2",BarFunctions.ColorToString(m_PanelBackground2)); + if(m_PanelBorderCustom) + xmlElem.SetAttribute("panelborder",BarFunctions.ColorToString(m_PanelBorder)); + if(m_PanelTextCustom) + xmlElem.SetAttribute("paneltext",BarFunctions.ColorToString(m_PanelText)); + if(m_PanelBackgroundGradientAngle!=90) + xmlElem.SetAttribute("panelbackga",m_PanelBackgroundGradientAngle.ToString()); + + // Splitter Colors + if (m_SplitterBackgroundCustom) + xmlElem.SetAttribute("splitterback", BarFunctions.ColorToString(m_SplitterBackground)); + if (m_SplitterBackground2Custom) + xmlElem.SetAttribute("splitterback2", BarFunctions.ColorToString(m_SplitterBackground2)); + if (m_SplitterBorderCustom) + xmlElem.SetAttribute("splitterborder", BarFunctions.ColorToString(m_SplitterBorder)); + if (m_SplitterTextCustom) + xmlElem.SetAttribute("splittertext", BarFunctions.ColorToString(m_SplitterText)); + if (m_SplitterBackgroundGradientAngle != 90) + xmlElem.SetAttribute("splitterbackga", m_SplitterBackgroundGradientAngle.ToString()); + + // Explorer Bar + if(m_ExplorerBarBackgroundCustom) + xmlElem.SetAttribute("exbarback",BarFunctions.ColorToString(m_ExplorerBarBackground)); + if(m_ExplorerBarBackground2Custom) + xmlElem.SetAttribute("exbarback2",BarFunctions.ColorToString(m_ExplorerBarBackground2)); + if(m_ExplorerBarBackgroundGradientAngle!=90) + xmlElem.SetAttribute("exbarbackga",m_ExplorerBarBackgroundGradientAngle.ToString()); + + // Dock Site colors + if(m_DockSiteBackColorCustom) + xmlElem.SetAttribute("dsback",BarFunctions.ColorToString(m_DockSiteBackColor)); + if(m_DockSiteBackColor2Custom) + xmlElem.SetAttribute("dsback2",BarFunctions.ColorToString(m_DockSiteBackColor2)); + if(m_DockSiteBackColorGradientAngle!=0) + xmlElem.SetAttribute("dsbackga",m_DockSiteBackColorGradientAngle.ToString()); + + if (!m_MdiSystemItemForeground.IsEmpty) + xmlElem.SetAttribute("mdisystemitemforeground", BarFunctions.ColorToString(m_MdiSystemItemForeground)); + + if(m_PredefinedColorScheme!=ePredefinedColorScheme.AutoGenerated) + xmlElem.SetAttribute("predefcolorscheme",System.Xml.XmlConvert.ToString(((int)m_PredefinedColorScheme))); + } + + public void Deserialize(System.Xml.XmlElement xmlElem) + { + if(xmlElem.HasAttribute("predefcolorscheme")) + m_PredefinedColorScheme=(ePredefinedColorScheme)System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("predefcolorscheme")); + + this.Refresh(); + + if(xmlElem.HasAttribute("barback")) + { + m_BarBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("barback")); + m_BarBackgroundCustom=true; + } + if(xmlElem.HasAttribute("barback2")) + { + m_BarBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("barback2")); + m_BarBackground2Custom=true; + } + if(xmlElem.HasAttribute("barbackga")) + { + m_BarBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("barbackga")); + } + if(xmlElem.HasAttribute("barstripeclr")) + { + m_BarStripeColor=BarFunctions.ColorFromString(xmlElem.GetAttribute("barstripeclr")); + m_BarStripeColorCustom=true; + } + if(xmlElem.HasAttribute("barcapback")) + { + m_BarCaptionBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("barcapback")); + m_BarCaptionBackgroundCustom=true; + } + if(xmlElem.HasAttribute("barcapback2")) + { + m_BarCaptionBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("barcapback2")); + m_BarCaptionBackground2Custom=true; + } + if(xmlElem.HasAttribute("barcapbackga")) + { + m_BarCaptionBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("barcapbackga")); + } + if(xmlElem.HasAttribute("barcapiback")) + { + m_BarCaptionInactiveBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("barcapiback")); + m_BarCaptionInactiveBackgroundCustom=true; + } + if(xmlElem.HasAttribute("barcapiback2")) + { + m_BarCaptionInactiveBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("barcapiback2")); + m_BarCaptionInactiveBackground2Custom=true; + } + if(xmlElem.HasAttribute("barcapibackga")) + { + m_BarCaptionInactiveBackgroundGAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("barcapibackga")); + } + if(xmlElem.HasAttribute("barcapitext")) + { + m_BarCaptionInactiveText=BarFunctions.ColorFromString(xmlElem.GetAttribute("barcapitext")); + m_BarCaptionInactiveTextCustom=true; + } + if(xmlElem.HasAttribute("barcaptext")) + { + m_BarCaptionText=BarFunctions.ColorFromString(xmlElem.GetAttribute("barcaptext")); + m_BarCaptionTextCustom=true; + } + if(xmlElem.HasAttribute("barfloatb")) + { + m_BarFloatingBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("barfloatb")); + m_BarFloatingBorderCustom=true; + } + if(xmlElem.HasAttribute("bardockborder")) + { + m_BarDockedBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("bardockborder")); + m_BarDockedBorderCustom=true; + } + if(xmlElem.HasAttribute("barpopupback")) + { + m_BarPopupBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("barpopupback")); + m_BarPopupBackgroundCustom=true; + } + if(xmlElem.HasAttribute("barpopupb")) + { + m_BarPopupBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("barpopupb")); + m_BarPopupBorderCustom=true; + } + if(xmlElem.HasAttribute("itemback")) + { + m_ItemBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemback")); + m_ItemBackgroundCustom=true; + } + if(xmlElem.HasAttribute("itemback2")) + { + m_ItemBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemback2")); + m_ItemBackground2Custom=true; + } + if(xmlElem.HasAttribute("itembackga")) + { + m_ItemBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("itembackga")); + } + + if(xmlElem.HasAttribute("itemchkback")) + { + m_ItemCheckedBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemchkback")); + m_ItemCheckedBackgroundCustom=true; + } + if(xmlElem.HasAttribute("itemchkback2")) + { + m_ItemCheckedBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemchkback2")); + m_ItemCheckedBackground2Custom=true; + } + if(xmlElem.HasAttribute("itemchkbackga")) + { + m_ItemCheckedBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("itemchkbackga")); + } + if(xmlElem.HasAttribute("itemchkb")) + { + m_ItemCheckedBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemchkb")); + m_ItemCheckedBorderCustom=true; + } + if(xmlElem.HasAttribute("itemchktext")) + { + m_ItemCheckedText=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemchktext")); + m_ItemCheckedTextCustom=true; + } + if(xmlElem.HasAttribute("itemdisback")) + { + m_ItemDisabledBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemdisback")); + m_ItemDisabledBackgroundCustom=true; + } + if(xmlElem.HasAttribute("itemdistext")) + { + m_ItemDisabledText=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemdistext")); + m_ItemDisabledTextCustom=true; + } + if(xmlElem.HasAttribute("itemexpshadow")) + { + m_ItemExpandedShadow=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemexpshadow")); + m_ItemExpandedShadowCustom=true; + } + if(xmlElem.HasAttribute("itemexpback")) + { + m_ItemExpandedBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemexpback")); + m_ItemExpandedBackgroundCustom=true; + } + if(xmlElem.HasAttribute("itemexpback2")) + { + m_ItemExpandedBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemexpback2")); + m_ItemExpandedBackground2Custom=true; + } + if(xmlElem.HasAttribute("itemexpbackga")) + { + m_ItemExpandedBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("itemexpbackga")); + } + if(xmlElem.HasAttribute("itemexptext")) + { + m_ItemExpandedText=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemexptext")); + m_ItemExpandedTextCustom=true; + } + if(xmlElem.HasAttribute("itemexpborder")) + { + m_ItemExpandedBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemexpborder")); + m_ItemExpandedBorderCustom=true; + } + if(xmlElem.HasAttribute("itemhotback")) + { + m_ItemHotBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemhotback")); + m_ItemHotBackgroundCustom=true; + } + if(xmlElem.HasAttribute("itemhotback2")) + { + m_ItemHotBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemhotback2")); + m_ItemHotBackground2Custom=true; + } + if(xmlElem.HasAttribute("itemhotbackga")) + { + m_ItemHotBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("itemhotbackga")); + } + if(xmlElem.HasAttribute("itemhotb")) + { + m_ItemHotBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemhotb")); + m_ItemHotBorderCustom=true; + } + if(xmlElem.HasAttribute("itemhottext")) + { + m_ItemHotText=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemhottext")); + m_ItemHotTextCustom=true; + } + if(xmlElem.HasAttribute("itempressback")) + { + m_ItemPressedBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("itempressback")); + m_ItemPressedBackgroundCustom=true; + } + if(xmlElem.HasAttribute("itempressback2")) + { + m_ItemPressedBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("itempressback2")); + m_ItemPressedBackground2Custom=true; + } + if(xmlElem.HasAttribute("itempressbackga")) + { + m_ItemPressedBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("itempressbackga")); + } + if(xmlElem.HasAttribute("itempressb")) + { + m_ItemPressedBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("itempressb")); + m_ItemPressedBorderCustom=true; + } + if(xmlElem.HasAttribute("itempresstext")) + { + m_ItemPressedText=BarFunctions.ColorFromString(xmlElem.GetAttribute("itempresstext")); + m_ItemPressedTextCustom=true; + } + if(xmlElem.HasAttribute("itemsep")) + { + m_ItemSeparator=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemsep")); + m_ItemSeparatorCustom=true; + } + if(xmlElem.HasAttribute("itemtext")) + { + m_ItemText=BarFunctions.ColorFromString(xmlElem.GetAttribute("itemtext")); + m_ItemTextCustom=true; + } + if(xmlElem.HasAttribute("menuback")) + { + m_MenuBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("menuback")); + m_MenuBackgroundCustom=true; + } + if(xmlElem.HasAttribute("menuback2")) + { + m_MenuBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("menuback2")); + m_MenuBackground2Custom=true; + } + if(xmlElem.HasAttribute("menubackga")) + { + m_MenuBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("menubackga")); + } + if(xmlElem.HasAttribute("menubarback")) + { + m_MenuBarBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("menubarback")); + m_MenuBarBackgroundCustom=true; + } + if(xmlElem.HasAttribute("menubarback2")) + { + m_MenuBarBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("menubarback2")); + m_MenuBarBackground2Custom=true; + } + if(xmlElem.HasAttribute("menubarbackga")) + { + m_MenuBarBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("menubarbackga")); + } + else m_MenuBarBackgroundGradientAngle=90; + if(xmlElem.HasAttribute("menub")) + { + m_MenuBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("menub")); + m_MenuBorderCustom=true; + } + if(xmlElem.HasAttribute("menuside")) + { + m_MenuSide=BarFunctions.ColorFromString(xmlElem.GetAttribute("menuside")); + m_MenuSideCustom=true; + } + if(xmlElem.HasAttribute("menuside2")) + { + m_MenuSide2=BarFunctions.ColorFromString(xmlElem.GetAttribute("menuside2")); + m_MenuSide2Custom=true; + } + if(xmlElem.HasAttribute("menusidega")) + { + m_MenuSideGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("menusidega")); + } + if(xmlElem.HasAttribute("menuuback")) + { + m_MenuUnusedBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("menuuback")); + m_MenuUnusedBackgroundCustom=true; + } + if(xmlElem.HasAttribute("menuuside")) + { + m_MenuUnusedSide=BarFunctions.ColorFromString(xmlElem.GetAttribute("menuuside")); + m_MenuUnusedSideCustom=true; + } + if(xmlElem.HasAttribute("menuuside2")) + { + m_MenuUnusedSide2=BarFunctions.ColorFromString(xmlElem.GetAttribute("menuuside2")); + m_MenuUnusedSide2Custom=true; + } + if(xmlElem.HasAttribute("menuusidega")) + { + m_MenuUnusedSideGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("menuusidega")); + } + if(xmlElem.HasAttribute("menudtb")) + { + m_ItemDesignTimeBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("menudtb")); + m_ItemDesignTimeBorderCustom=true; + } + if(xmlElem.HasAttribute("customback")) + { + m_CustomizeBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("customback")); + m_CustomizeBackgroundCustom=true; + } + if(xmlElem.HasAttribute("customback2")) + { + m_CustomizeBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("customback2")); + m_CustomizeBackground2Custom=true; + } + if(xmlElem.HasAttribute("customtext")) + { + m_CustomizeText=BarFunctions.ColorFromString(xmlElem.GetAttribute("customtext")); + m_CustomizeTextCustom=true; + } + if(xmlElem.HasAttribute("custombackga")) + { + m_CustomizeBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("custombackga")); + } + + // Panel Colors + if(xmlElem.HasAttribute("panelback")) + { + m_PanelBackgroundCustom=true; + m_PanelBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("panelback")); + } + if(xmlElem.HasAttribute("panelback2")) + { + m_PanelBackground2Custom=true; + m_PanelBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("panelback2")); + } + if(xmlElem.HasAttribute("panelborder")) + { + m_PanelBorderCustom=true; + m_PanelBorder=BarFunctions.ColorFromString(xmlElem.GetAttribute("panelborder")); + } + if(xmlElem.HasAttribute("paneltext")) + { + m_PanelTextCustom=true; + m_PanelText=BarFunctions.ColorFromString(xmlElem.GetAttribute("paneltext")); + } + if(xmlElem.HasAttribute("panelbackga")) + { + m_PanelBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("panelbackga")); + } + + // Splitter Colors + if (xmlElem.HasAttribute("splitterback")) + { + m_SplitterBackgroundCustom = true; + m_SplitterBackground = BarFunctions.ColorFromString(xmlElem.GetAttribute("Splitterback")); + } + if (xmlElem.HasAttribute("splitterback2")) + { + m_SplitterBackground2Custom = true; + m_SplitterBackground2 = BarFunctions.ColorFromString(xmlElem.GetAttribute("Splitterback2")); + } + if (xmlElem.HasAttribute("splitterborder")) + { + m_SplitterBorderCustom = true; + m_SplitterBorder = BarFunctions.ColorFromString(xmlElem.GetAttribute("Splitterborder")); + } + if (xmlElem.HasAttribute("splittertext")) + { + m_SplitterTextCustom = true; + m_SplitterText = BarFunctions.ColorFromString(xmlElem.GetAttribute("Splittertext")); + } + if (xmlElem.HasAttribute("splitterbackga")) + { + m_SplitterBackgroundGradientAngle = System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("Splitterbackga")); + } + + // Explorer Bar Colors + if(xmlElem.HasAttribute("exbarback")) + { + m_ExplorerBarBackgroundCustom=true; + m_ExplorerBarBackground=BarFunctions.ColorFromString(xmlElem.GetAttribute("exbarback")); + } + if(xmlElem.HasAttribute("exbarback2")) + { + m_ExplorerBarBackground2Custom=true; + m_ExplorerBarBackground2=BarFunctions.ColorFromString(xmlElem.GetAttribute("exbarback2")); + } + if(xmlElem.HasAttribute("exbarbackga")) + { + m_ExplorerBarBackgroundGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("exbarbackga")); + } + + // Dock Site colors + // Explorer Bar Colors + if(xmlElem.HasAttribute("dsback")) + { + m_DockSiteBackColorCustom=true; + m_DockSiteBackColor=BarFunctions.ColorFromString(xmlElem.GetAttribute("dsback")); + } + if(xmlElem.HasAttribute("dsback2")) + { + m_DockSiteBackColor2Custom=true; + m_DockSiteBackColor2=BarFunctions.ColorFromString(xmlElem.GetAttribute("dsback2")); + } + if(xmlElem.HasAttribute("dsbackga")) + m_DockSiteBackColorGradientAngle=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("dsbackga")); + + if (xmlElem.HasAttribute("mdisystemitemforeground")) + { + m_MdiSystemItemForeground = BarFunctions.ColorFromString(xmlElem.GetAttribute("mdisystemitemforeground")); + } + else + m_MdiSystemItemForeground = Color.Empty; + } + #endregion + } + + #region Enums + /// + /// Specifies the type of predefined color scheme in ColorScheme object. + /// + public enum ePredefinedColorScheme + { + /// + /// Default value. DotNetBar will automatically change and generate color scheme depending on system colors. + /// + AutoGenerated=0, + /// + /// Blue Office 2003 Color Scheme. This setting specifies that this color scheme will be used regardless of system color setting on user machine. + /// + Blue2003=1, + /// + /// Olive Green Office 2003 Color Scheme. This setting specifies that this color scheme will be used regardless of system color setting on user machine. + /// + OliveGreen2003=2, + /// + /// Silver Office 2003 Color Scheme. This setting specifies that this color scheme will be used regardless of system color setting on user machine. + /// + Silver2003=3, + /// + /// Always use system colors to auto-generate color scheme. + /// + SystemColors + } + + /// + /// Specifies a color scheme member. + /// + public enum eColorSchemePart + { + BarBackground, + BarBackground2, + BarCaptionBackground, + BarCaptionBackground2, + BarCaptionInactiveBackground, + BarCaptionInactiveBackground2, + BarCaptionInactiveText, + BarCaptionText, + BarDockedBorder, + BarFloatingBorder, + BarPopupBackground, + BarPopupBorder, + BarStripeColor, + CustomizeBackground, + CustomizeBackground2, + CustomizeText, + ItemBackground, + ItemBackground2, + ItemCheckedBackground, + ItemCheckedBackground2, + ItemCheckedBorder, + ItemCheckedText, + ItemDesignTimeBorder, + ItemDisabledBackground, + ItemDisabledText, + ItemExpandedBackground, + ItemExpandedBackground2, + ItemExpandedBorder, + ItemExpandedShadow, + ItemExpandedText, + ItemHotBackground, + ItemHotBackground2, + ItemHotBorder, + ItemHotText, + ItemPressedBackground, + ItemPressedBackground2, + ItemPressedBorder, + ItemPressedText, + ItemSeparator, + ItemSeparatorShade, + ItemText, + MenuBackground, + MenuBackground2, + MenuBarBackground, + MenuBarBackground2, + MenuBorder, + MenuSide, + MenuSide2, + MenuUnusedBackground, + MenuUnusedSide, + MenuUnusedSide2, + PanelBackground, + PanelBackground2, + PanelBorder, + PanelText, + SplitterBackground, + SplitterBackground2, + SplitterBorder, + SplitterText, + ExplorerBarBackground, + ExplorerBarBackground2, + Custom, + None, + DockSiteBackColor, + DockSiteBackColor2 + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/ColorSchemeEditor.cs b/PROMS/DotNetBar Source Code/ColorSchemeEditor.cs new file mode 100644 index 00000000..f9d4f46b --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorSchemeEditor.cs @@ -0,0 +1,384 @@ +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Xml; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for ColorSchemeEditor. + /// + public class ColorSchemeEditor : System.Windows.Forms.Form + { + private System.Windows.Forms.PropertyGrid propertyGrid1; + private System.Windows.Forms.GroupBox groupBox1; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + private ColorScheme m_ColorScheme=null; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button2; + private MenuPanel m_Menu=null; + private Bar m_SimpleBar=null; + private Bar m_FloatBar=null; + private System.Windows.Forms.Button button3; + private Bar m_PopupBar=null; + private System.Windows.Forms.Button btnSaveScheme; + private System.Windows.Forms.Button btnLoadScheme; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + public bool ColorSchemeChanged=false; + + public ColorSchemeEditor() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + this.StartPosition=FormStartPosition.CenterScreen; + } + + private void AddDotNetBarControls() + { + if(m_Menu!=null) + { + m_Menu.RecalcSize(); + m_SimpleBar.Size=new Size(groupBox1.ClientRectangle.Width-12,16); + m_SimpleBar.RecalcSize(); + m_FloatBar.Size=new Size(groupBox1.ClientRectangle.Width,16); + m_FloatBar.RecalcSize(); + m_PopupBar.Size=new Size(groupBox1.ClientRectangle.Width,24); + m_PopupBar.RecalcSize(); + return; + } + + m_Menu=new MenuPanel(); + m_Menu.PopupMenu=false; + m_Menu.Location=new Point(8,135); + + // Create Simple Toolbar + m_SimpleBar=new Bar(); + m_SimpleBar.PassiveBar=true; + m_SimpleBar.Location=new Point(4,16); + m_SimpleBar.ThemeAware=false; + + m_FloatBar=new Bar(); + m_FloatBar.PassiveBar=true; + m_FloatBar.Location=new Point(4,46); + m_FloatBar.ThemeAware=false; + + m_PopupBar=new Bar(); + m_PopupBar.PassiveBar=true; + m_PopupBar.Location=new Point(4,96); + m_PopupBar.ThemeAware=false; + + ButtonItem menuItem=new ButtonItem(); + ButtonItem item, item2; + Bitmap bmp=null; + + item=new ButtonItem("new","&New..."); + bmp=BarFunctions.LoadBitmap("BarEditorImages.FileNew.bmp"); + bmp.MakeTransparent(Color.Magenta); + item.Image=bmp; + m_SimpleBar.Items.Add(item.Copy()); + m_FloatBar.Items.Add(item.Copy()); + m_PopupBar.Items.Add(item.Copy()); + menuItem.SubItems.Add(item); + item=new ButtonItem("open","&Open"); + bmp=BarFunctions.LoadBitmap("BarEditorImages.FileOpen.bmp"); + bmp.MakeTransparent(Color.Magenta); + item.Image=bmp; + item2=(ButtonItem)item.Copy(); + item2.ButtonStyle=eButtonStyle.ImageAndText; + m_SimpleBar.Items.Add(item2); + m_FloatBar.Items.Add(item2.Copy()); + m_PopupBar.Items.Add(item2.Copy()); + menuItem.SubItems.Add(item); + item=new ButtonItem("close","&Close"); + bmp=BarFunctions.LoadBitmap("BarEditorImages.FileClose.bmp"); + bmp.MakeTransparent(Color.Magenta); + item.Image=bmp; + item2=(ButtonItem)item.Copy(); + item2.Checked=true; + item2.ButtonStyle=eButtonStyle.ImageAndText; + m_SimpleBar.Items.Add(item2); + m_PopupBar.Items.Add(item2.Copy()); + item2=(ButtonItem)item2.Copy(); + item2.Enabled=false; + m_FloatBar.Items.Add(item2.Copy()); + menuItem.SubItems.Add(item); + item=new ButtonItem("open","Add Ne&w Item..."); + menuItem.SubItems.Add(item); + item=new ButtonItem("open","Add Existin&g Item..."); + menuItem.SubItems.Add(item); + item=new ButtonItem("opensol","Open Solution..."); + item.BeginGroup=true; + bmp=BarFunctions.LoadBitmap("BarEditorImages.FileOpenSol.bmp"); + bmp.MakeTransparent(Color.Magenta); + item.Image=bmp; + item2=(ButtonItem)item.Copy(); + item2.Enabled=false; + m_SimpleBar.Items.Add(item2); + m_FloatBar.Items.Add(item2.Copy()); + m_PopupBar.Items.Add(item2.Copy()); + menuItem.SubItems.Add(item); + item=new ButtonItem("open","Close Solution"); + bmp=BarFunctions.LoadBitmap("BarEditorImages.FileCloseSol.bmp"); + bmp.MakeTransparent(Color.Magenta); + item.Image=bmp; + item.Enabled=false; + menuItem.SubItems.Add(item); + + m_Menu.ParentItem=menuItem; + + groupBox1.Controls.Add(m_Menu); + m_Menu.RecalcSize(); + m_Menu.Show(); + + //m_SimpleBar.SetBarState(eBarState.Docked); + m_SimpleBar.Size=new Size(groupBox1.ClientRectangle.Width,16); + m_SimpleBar.GrabHandleStyle=eGrabHandleStyle.StripeFlat; + groupBox1.Controls.Add(m_SimpleBar); + m_SimpleBar.RecalcSize(); + m_SimpleBar.Show(); + + m_FloatBar.SetBarState(eBarState.Floating); + m_FloatBar.Size=new Size(groupBox1.ClientRectangle.Width,16); + groupBox1.Controls.Add(m_FloatBar); + m_FloatBar.Text="Bar Caption"; + m_FloatBar.RecalcSize(); + m_FloatBar.Show(); + + m_PopupBar.SetBarState(eBarState.Popup); + m_PopupBar.Size=new Size(groupBox1.ClientRectangle.Width,24); + m_PopupBar.PopupWidth=groupBox1.ClientRectangle.Width; + groupBox1.Controls.Add(m_PopupBar); + m_PopupBar.RecalcSize(); + m_PopupBar.Show(); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.button1 = new System.Windows.Forms.Button(); + this.button2 = new System.Windows.Forms.Button(); + this.button3 = new System.Windows.Forms.Button(); + this.btnSaveScheme = new System.Windows.Forms.Button(); + this.btnLoadScheme = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + this.SuspendLayout(); + // + // propertyGrid1 + // + this.propertyGrid1.CommandsVisibleIfAvailable = true; + this.propertyGrid1.LargeButtons = false; + this.propertyGrid1.LineColor = System.Drawing.SystemColors.ScrollBar; + this.propertyGrid1.Location = new System.Drawing.Point(208, 4); + this.propertyGrid1.Name = "propertyGrid1"; + this.propertyGrid1.Size = new System.Drawing.Size(352, 299); + this.propertyGrid1.TabIndex = 0; + this.propertyGrid1.Text = "propertyGrid1"; + this.propertyGrid1.ViewBackColor = System.Drawing.SystemColors.Window; + this.propertyGrid1.ViewForeColor = System.Drawing.SystemColors.WindowText; + this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged); + // + // groupBox1 + // + this.groupBox1.Location = new System.Drawing.Point(10, 0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(190, 303); + this.groupBox1.TabIndex = 1; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Color Scheme Preview:"; + // + // button1 + // + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button1.Location = new System.Drawing.Point(404, 307); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(76, 24); + this.button1.TabIndex = 2; + this.button1.Text = "OK"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // button2 + // + this.button2.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button2.Location = new System.Drawing.Point(316, 307); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(76, 24); + this.button2.TabIndex = 3; + this.button2.Text = "&Reset"; + this.button2.Click += new System.EventHandler(this.button2_Click); + // + // button3 + // + this.button3.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.button3.Location = new System.Drawing.Point(484, 307); + this.button3.Name = "button3"; + this.button3.Size = new System.Drawing.Size(76, 24); + this.button3.TabIndex = 4; + this.button3.Text = "Cancel"; + this.button3.Click += new System.EventHandler(this.button3_Click); + // + // btnSaveScheme + // + this.btnSaveScheme.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.btnSaveScheme.Location = new System.Drawing.Point(10, 308); + this.btnSaveScheme.Name = "btnSaveScheme"; + this.btnSaveScheme.Size = new System.Drawing.Size(92, 24); + this.btnSaveScheme.TabIndex = 5; + this.btnSaveScheme.Text = "Save Scheme..."; + this.btnSaveScheme.Click += new System.EventHandler(this.btnSaveScheme_Click); + // + // btnLoadScheme + // + this.btnLoadScheme.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.btnLoadScheme.Location = new System.Drawing.Point(107, 308); + this.btnLoadScheme.Name = "btnLoadScheme"; + this.btnLoadScheme.Size = new System.Drawing.Size(92, 24); + this.btnLoadScheme.TabIndex = 6; + this.btnLoadScheme.Text = "Load Scheme..."; + this.btnLoadScheme.Click += new System.EventHandler(this.btnLoadScheme_Click); + // + // openFileDialog1 + // + this.openFileDialog1.DefaultExt = "*.dcs"; + this.openFileDialog1.Filter = "DotNetBar Color Scheme files|*.dcs|All files|*.*"; + this.openFileDialog1.Title = "Open DotNetBar Color Scheme File"; + // + // saveFileDialog1 + // + this.saveFileDialog1.DefaultExt = "dcs"; + this.saveFileDialog1.FileName = "colorscheme1"; + this.saveFileDialog1.Filter = "DotNetBar Color Scheme files|*.dcs|All files|*.*"; + this.saveFileDialog1.Title = "Save DotNetBar Color Scheme File"; + // + // ColorSchemeEditor + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(567, 338); + this.Controls.AddRange(new System.Windows.Forms.Control[] { + this.btnLoadScheme, + this.btnSaveScheme, + this.button3, + this.button2, + this.button1, + this.groupBox1, + this.propertyGrid1}); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ColorSchemeEditor"; + this.Text = "ColorScheme Editor"; + this.Load += new System.EventHandler(this.ColorSchemeEditorLoad); + this.ResumeLayout(false); + + } + #endregion + + private void ColorSchemeEditorLoad(object sender, EventArgs e) + { + AddDotNetBarControls(); + } + + private void propertyGrid1_PropertyValueChanged(object s, System.Windows.Forms.PropertyValueChangedEventArgs e) + { + m_Menu.Refresh(); + m_SimpleBar.Refresh(); + m_FloatBar.Refresh(); + m_PopupBar.Refresh(); + ColorSchemeChanged=true; + } + + private void button1_Click(object sender, System.EventArgs e) + { + this.Hide(); + } + + private void button2_Click(object sender, System.EventArgs e) + { + if(MessageBox.Show("Reseting the Color Scheme will destroy any changes you made. Are you sure you want to reset the Color Scheme?","Color Scheme Editor",MessageBoxButtons.YesNo)==DialogResult.Yes) + { + this.ColorScheme=new ColorScheme(this.ColorScheme.Style); + ColorSchemeChanged=true; + } + } + + private void button3_Click(object sender, System.EventArgs e) + { + ColorSchemeChanged=false; + this.Hide(); + } + + private void btnSaveScheme_Click(object sender, System.EventArgs e) + { + if(saveFileDialog1.ShowDialog()==DialogResult.OK) + { + XmlDocument doc=new XmlDocument(); + XmlElement elem1=doc.CreateElement("colorschemes"); + doc.AppendChild(elem1); + XmlElement elem2=doc.CreateElement("colorscheme"); + elem1.AppendChild(elem2); + m_ColorScheme.Serialize(elem2); + doc.Save(saveFileDialog1.FileName); + MessageBox.Show("Color Scheme has been saved.","DotNetBar Color Scheme Editor",MessageBoxButtons.OK,MessageBoxIcon.Information); + } + } + + private void btnLoadScheme_Click(object sender, System.EventArgs e) + { + if(openFileDialog1.ShowDialog()==DialogResult.OK && System.IO.File.Exists(openFileDialog1.FileName)) + { + DevComponents.DotNetBar.ColorScheme scheme=new ColorScheme(); + XmlDocument doc=new XmlDocument(); + doc.Load(openFileDialog1.FileName); + scheme.Deserialize(doc.FirstChild.FirstChild as XmlElement); + this.ColorScheme=scheme; + ColorSchemeChanged=true; + } + } + + public DevComponents.DotNetBar.ColorScheme ColorScheme + { + get {return m_ColorScheme;} + set + { + if(m_Menu==null) + AddDotNetBarControls(); + m_ColorScheme=value; + propertyGrid1.SelectedObject=m_ColorScheme; + m_Menu.ColorScheme=m_ColorScheme; + m_SimpleBar.ColorScheme=m_ColorScheme; + m_FloatBar.ColorScheme=m_ColorScheme; + m_PopupBar.ColorScheme=m_ColorScheme; + ColorSchemeChanged=false; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/ColorSchemeEditor.resx b/PROMS/DotNetBar Source Code/ColorSchemeEditor.resx new file mode 100644 index 00000000..87c738c3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorSchemeEditor.resx @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 147, 17 + + + ColorSchemeEditor + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/ColorSchemeVSEditor.cs b/PROMS/DotNetBar Source Code/ColorSchemeVSEditor.cs new file mode 100644 index 00000000..52494321 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorSchemeVSEditor.cs @@ -0,0 +1,66 @@ +using System; +using System.Drawing.Design; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for ColorSchemeVSEditor. + /// + public sealed class ColorSchemeVSEditor:UITypeEditor + { + private System.Windows.Forms.Design.IWindowsFormsEditorService m_EditorService=null; + public ColorSchemeVSEditor() + { + } + public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + if (context != null && context.Instance != null) + { + return System.Drawing.Design.UITypeEditorEditStyle.Modal; + } + return base.GetEditStyle(context); + } + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + if (context!=null && context.Instance!=null && provider!=null) + { + m_EditorService=(System.Windows.Forms.Design.IWindowsFormsEditorService)provider.GetService(typeof(System.Windows.Forms.Design.IWindowsFormsEditorService)); + + if(m_EditorService!=null) + { + if(context.Instance is Bar) + { + Bar bar=context.Instance as Bar; + if(bar.Owner is DotNetBarManager && ((DotNetBarManager)bar.Owner).UseGlobalColorScheme) + System.Windows.Forms.MessageBox.Show("Please note that your DotNetBarManager has its UseGlobalColorScheme set to true and any changes you make to ColorScheme object on the bar will not be used."); + } + else if(context.Instance is DotNetBarManager && !((DotNetBarManager)context.Instance).UseGlobalColorScheme) + { + System.Windows.Forms.MessageBox.Show("Please note that you need to set UseGlobalColorScheme=true in order for all bars to use ColorScheme you change on this dialog."); + } + + if(value==null) + value=new ColorScheme(); + ColorSchemeEditor editor=new ColorSchemeEditor(); + editor.CreateControl(); + editor.ColorScheme=(ColorScheme)value; + m_EditorService.ShowDialog(editor); + if(editor.ColorSchemeChanged) + { + value=editor.ColorScheme; + context.OnComponentChanged(); + ((ColorScheme)value)._DesignTimeSchemeChanged=true; + if(context.Instance is Bar) + { + ((Bar)context.Instance).Refresh(); + } + } + editor.Close(); + } + } + + return value; + } + } +} diff --git a/PROMS/DotNetBar Source Code/ColorTypeEditor.cs b/PROMS/DotNetBar Source Code/ColorTypeEditor.cs new file mode 100644 index 00000000..ef7a4ad8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ColorTypeEditor.cs @@ -0,0 +1,131 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Reflection; +using System.Windows.Forms.Design; +using DevComponents.UI; +using System.Windows.Forms; + +#if AdvTree +namespace DevComponents.Tree +#elif DOTNETBAR +namespace DevComponents.DotNetBar +#endif +{ + /// + /// Represents Color type editor with support for color schemes. + /// + public class ColorTypeEditor:UITypeEditor + { + private IWindowsFormsEditorService m_EditorService=null; + + /// + /// Edits the value of the specified object using the editor style indicated by GetEditStyle. + /// + /// An ITypeDescriptorContext that can be used to gain additional context information. + /// An IServiceProvider that this editor can use to obtain services. + /// The object to edit. + /// The new value of the object. + 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 = null; + if (context.Instance is object[]) + { + method = ((object[])context.Instance)[0].GetType().GetMethod("GetColorScheme", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + if (method != null) + { + cs = method.Invoke(((object[])context.Instance)[0], null) as ColorScheme; + } + } + else + { + 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 = null; + if (context.Instance is object[]) + property = ((object[])context.Instance)[0].GetType().GetProperty(propertyName + "SchemePart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + else + property=context.Instance.GetType().GetProperty(propertyName+"SchemePart",BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + + if(property!=null) + { + if (context.Instance is object[]) + colorPicker.SelectedColorSchemeName = property.GetValue(((object[])context.Instance)[0], null).ToString(); + else + 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) + { + if (context.Instance is object[]) + { + object[] objects = (object[])context.Instance; + foreach (object item in objects) + { + property = item.GetType().GetProperty(propertyName + "SchemePart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + property.SetValue(item, schemePart, null); + } + } + else + property.SetValue(context.Instance, schemePart, null); + } + return returnColor; + } + } + } + + return value; + } + + /// + /// Gets the editor style used by the EditValue method. + /// + /// An ITypeDescriptorContext that can be used to gain additional context information. + /// 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. + /// + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + if (context != null && context.Instance != null) + { + return UITypeEditorEditStyle.DropDown; + } + return base.GetEditStyle(context); + } + } +} diff --git a/PROMS/DotNetBar Source Code/ComboBoxItem.cs b/PROMS/DotNetBar Source Code/ComboBoxItem.cs new file mode 100644 index 00000000..e629e0a2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ComboBoxItem.cs @@ -0,0 +1,1538 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for ComboBoxItem. + /// + [System.ComponentModel.ToolboxItem(false), DefaultEvent("Click"), System.ComponentModel.DesignTimeVisible(false), Designer("DevComponents.DotNetBar.Design.ComboBoxItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ComboBoxItem:ImageItem,IPersonalizedMenuItem + { + private Controls.ComboBoxEx m_ComboBox=null; + private int m_ComboWidth=64; + private bool m_MouseOver=false; + //private string m_ControlText=""; + private bool m_AlwaysShowCaption; + private bool m_FontCombo=false; + + // IPersonalizedMenuItem Implementation + private eMenuVisibility m_MenuVisibility=eMenuVisibility.VisibleAlways; + private bool m_RecentlyUsed=false; + internal bool _CopyInProgress=false; + + private bool m_PreventEnterBeep=false; + + /// + /// Occurs when underlining control ComboBox.Text property has changed. + /// + public event EventHandler ComboBoxTextChanged; + + /// + /// Occurs when selected item on combo box has changed. + /// + public event EventHandler SelectedIndexChanged; + + /// + /// Creates new instance of ComboBoxItem. + /// + public ComboBoxItem():this("","") {} + /// + /// Creates new instance of ComboBoxItem and assigns item name. + /// + /// Item Name. + public ComboBoxItem(string sName):this(sName,""){} + /// + /// Creates new instance of ComboBoxItem and assigns item name and item text. + /// + /// Item Name + /// Item Text. + public ComboBoxItem(string sName, string ItemText):base(sName,ItemText) + { + CreateComboBox(); + m_ComboWidth=64; + m_SupportedOrientation=eSupportedOrientation.Horizontal; + this.IsAccessible=true; + this.AccessibleRole = AccessibleRole.ComboBox; + } + private void CreateComboBox() + { + if(m_ComboBox!=null) + { + m_ComboBox.Dispose(); + m_ComboBox=null; + } + m_ComboBox = new Controls.ComboBoxEx(); + m_ComboBox.IsStandalone = false; + m_ComboBox.TabStop = false; + m_ComboBox.TabIndex = 9999; + m_ComboBox.Style = this.Style; + m_ComboBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; + m_ComboBox.IntegralHeight = false; + //m_ComboBox.ItemHeight = 13; + m_ComboBox.ThemeAware = false; + m_ComboBox.Visible = false; + m_ComboBox.Text = this.Text; + m_ComboBox.SelectionStart = 0; + m_ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + + m_ComboBox.LostFocus += new EventHandler(this.ComboLostFocus); + m_ComboBox.GotFocus += new EventHandler(this.ComboGotFocus); + m_ComboBox.MouseHover += new EventHandler(this.ComboMouseHover); + m_ComboBox.MouseEnter += new EventHandler(this.ComboMouseEnter); + m_ComboBox.MouseLeave += new EventHandler(this.ComboMouseLeave); + m_ComboBox.VisibleChanged += new EventHandler(ComboBoxVisibleChanged); + m_ComboBox.DropDownChange += new Controls.ComboBoxEx.OnDropDownChangeEventHandler(this.ComboDropDownChange); + m_ComboBox.TextChanged += new EventHandler(this.InternalComboTextChanged); + m_ComboBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ComboKeyDown); + m_ComboBox.SelectedIndexChanged += new System.EventHandler(this.ComboSelChanged); + m_ComboBox.PreventEnterBeep = m_PreventEnterBeep; + m_ComboBox.ParentItem = this; + if(m_FontCombo) + m_ComboBox.LoadFonts(); + + if(this.ContainerControl!=null) + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null) + { + objCtrl.Controls.Add(m_ComboBox); + m_ComboBox.Refresh(); + } + } + + if(this.Displayed) + { + m_ComboBox.Visible=true; + } + } + + public override BaseItem Copy() + { + ComboBoxItem objCopy=new ComboBoxItem(this.Name); + this.CopyToItem(objCopy); + objCopy.DropDownStyle=this.DropDownStyle; + objCopy.AlwaysShowCaption=this.AlwaysShowCaption; + objCopy.FontCombo=this.FontCombo; + objCopy.ItemHeight=this.ItemHeight; + objCopy.Caption = this.Caption; + + return objCopy; + } + protected override void CopyToItem(BaseItem copy) + { + ((ComboBoxItem)copy)._CopyInProgress=true; + try + { + ComboBoxItem objCopy=copy as ComboBoxItem; + base.CopyToItem(objCopy); + + + objCopy.ComboWidth=m_ComboWidth; + objCopy.FontCombo=m_FontCombo; + objCopy.PreventEnterBeep=m_PreventEnterBeep; + if (m_ComboBox != null) + { + objCopy.DisplayMember = m_ComboBox.DisplayMember; + + Controls.ComboBoxEx cb = objCopy.ComboBoxEx; + if (!m_FontCombo) + { + foreach (object o in m_ComboBox.Items) + cb.Items.Add(o); + } + cb.SelectedIndex = m_ComboBox.SelectedIndex; + } + } + finally + { + ((ComboBoxItem)copy)._CopyInProgress=false; + } + } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + // Control gets disposed by the parent control it is added to + //if (m_ComboBox != null) + //{ + // if (m_ComboBox.Parent == null && !m_ComboBox.IsDisposed) + // m_ComboBox.Dispose(); + //} + } + protected override System.Windows.Forms.AccessibleObject CreateAccessibilityInstance() + { + return m_ComboBox.AccessibilityObject; + } + /// + /// Gets or sets the accessible role of the item. + /// + [Browsable(true), Category("Accessibility"), Description("Gets or sets the accessible role of the item."), DefaultValue(System.Windows.Forms.AccessibleRole.ComboBox)] + public override System.Windows.Forms.AccessibleRole AccessibleRole + { + get { return base.AccessibleRole; } + set { base.AccessibleRole = value; } + } + protected internal override void Serialize(ItemSerializationContext context) + { + base.Serialize(context); + System.Xml.XmlElement ThisItem = context.ItemXmlElement; + ThisItem.SetAttribute("ComboWidth",System.Xml.XmlConvert.ToString(m_ComboWidth)); + ThisItem.SetAttribute("FontCombo",System.Xml.XmlConvert.ToString(m_FontCombo)); + + ThisItem.SetAttribute("MenuVisibility",System.Xml.XmlConvert.ToString((int)m_MenuVisibility)); + ThisItem.SetAttribute("RecentlyUsed",System.Xml.XmlConvert.ToString(m_RecentlyUsed)); + ThisItem.SetAttribute("DropDownStyle",System.Xml.XmlConvert.ToString((int)m_ComboBox.DropDownStyle)); + //ThisItem.SetAttribute("CText",m_ControlText); + ThisItem.SetAttribute("ThemeAware",System.Xml.XmlConvert.ToString(m_ComboBox.ThemeAware)); + + ThisItem.SetAttribute("AlwaysShowCaption",System.Xml.XmlConvert.ToString(m_AlwaysShowCaption)); + ThisItem.SetAttribute("ItemHeight",System.Xml.XmlConvert.ToString(m_ComboBox.ItemHeight)); + + if(m_ComboBox.DisplayMember!="") + ThisItem.SetAttribute("DisplayMembers", m_ComboBox.DisplayMember); + + if(m_PreventEnterBeep) + ThisItem.SetAttribute("nobeep",System.Xml.XmlConvert.ToString(m_PreventEnterBeep)); + + if(!m_FontCombo && m_ComboBox.Items.Count>0) + { + System.Xml.XmlElement xmlItems=ThisItem.OwnerDocument.CreateElement("cbitems"); + ThisItem.AppendChild(xmlItems); + foreach(object item in m_ComboBox.Items) + { + DevComponents.Editors.ComboItem ci=item as DevComponents.Editors.ComboItem; + if(ci!=null) + { + System.Xml.XmlElement xmlChild=ThisItem.OwnerDocument.CreateElement("ci"); + + if(!ci.BackColor.IsEmpty) + xmlChild.SetAttribute("bc",BarFunctions.ColorToString(ci.BackColor)); + if(ci.FontName!="") + xmlChild.SetAttribute("fn",ci.FontName); + if(ci.FontSize!=8) + xmlChild.SetAttribute("fs",System.Xml.XmlConvert.ToString(ci.FontSize)); + + xmlChild.SetAttribute("fy",System.Xml.XmlConvert.ToString((int)ci.FontStyle)); + + if(!ci.ForeColor.IsEmpty) + xmlChild.SetAttribute("fc",BarFunctions.ColorToString(ci.ForeColor)); + + BarFunctions.SerializeImage(ci.Image,xmlChild); + + if(ci.ImageIndex>=0) + xmlChild.SetAttribute("img",System.Xml.XmlConvert.ToString(ci.ImageIndex)); + + if(ci.ImagePosition!=System.Windows.Forms.HorizontalAlignment.Left) + xmlChild.SetAttribute("ip",System.Xml.XmlConvert.ToString((int)ci.ImagePosition)); + + xmlChild.SetAttribute("text",ci.Text); + + xmlChild.SetAttribute("ta",System.Xml.XmlConvert.ToString((int)ci.TextAlignment)); + xmlChild.SetAttribute("tla",System.Xml.XmlConvert.ToString((int)ci.TextLineAlignment)); + + if(m_ComboBox.SelectedItem==item) + xmlChild.SetAttribute("selected","1"); + + xmlItems.AppendChild(xmlChild); + } + else + { + System.Xml.XmlElement xmlChild=ThisItem.OwnerDocument.CreateElement("co"); + xmlChild.InnerText=item.ToString(); + xmlItems.AppendChild(xmlChild); + + if(m_ComboBox.SelectedItem==item) + xmlChild.SetAttribute("selected","1"); + } + } + } + } + + public override void Deserialize(ItemSerializationContext context) + { + base.Deserialize(context); + System.Xml.XmlElement ItemXmlSource = context.ItemXmlElement; + m_ComboWidth=System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("ComboWidth")); + m_FontCombo=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("FontCombo")); + + m_MenuVisibility=(eMenuVisibility)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("MenuVisibility")); + m_RecentlyUsed=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("RecentlyUsed")); + if(ItemXmlSource.HasAttribute("DropDownStyle")) + m_ComboBox.DropDownStyle=(System.Windows.Forms.ComboBoxStyle)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("DropDownStyle")); + + if(ItemXmlSource.HasAttribute("CText")) + this.Text=ItemXmlSource.GetAttribute("CText"); + + if(ItemXmlSource.HasAttribute("ThemeAware")) + m_ComboBox.ThemeAware=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("ThemeAware")); + else + m_ComboBox.ThemeAware=true; + + if(ItemXmlSource.HasAttribute("AlwaysShowCaption")) + m_AlwaysShowCaption=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("AlwaysShowCaption")); + + if(ItemXmlSource.HasAttribute("nobeep")) + this.PreventEnterBeep=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("nobeep")); + + System.Xml.XmlNodeList list=ItemXmlSource.GetElementsByTagName("cbitems"); + if(!m_FontCombo && list.Count>0) + { + foreach(System.Xml.XmlElement xmlChild in list[0].ChildNodes) + { + if(xmlChild.Name=="ci") + { + DevComponents.Editors.ComboItem ci=new DevComponents.Editors.ComboItem(); + if(xmlChild.HasAttribute("bc")) + ci.BackColor=BarFunctions.ColorFromString(xmlChild.GetAttribute("bk")); + if(xmlChild.HasAttribute("fn")) + ci.FontName=xmlChild.GetAttribute("fn"); + if(xmlChild.HasAttribute("fs")) + ci.FontSize=System.Xml.XmlConvert.ToSingle(xmlChild.GetAttribute("fs")); + if(xmlChild.HasAttribute("fy")) + ci.FontStyle=(FontStyle)System.Xml.XmlConvert.ToInt32(xmlChild.GetAttribute("fy")); + if(xmlChild.HasAttribute("fc")) + ci.ForeColor=BarFunctions.ColorFromString(xmlChild.GetAttribute("fc")); + + ci.Image=BarFunctions.DeserializeImage(xmlChild); + + if(xmlChild.HasAttribute("img")) + ci.ImageIndex=System.Xml.XmlConvert.ToInt32(xmlChild.GetAttribute("img")); + + if(xmlChild.HasAttribute("ip")) + ci.ImagePosition=(System.Windows.Forms.HorizontalAlignment)System.Xml.XmlConvert.ToInt32(xmlChild.GetAttribute("ip")); + + if(xmlChild.HasAttribute("ItemHeight")) + m_ComboBox.ItemHeight=System.Xml.XmlConvert.ToInt32(xmlChild.GetAttribute("ItemHeight")); + + ci.Text=xmlChild.GetAttribute("text"); + + ci.TextAlignment=(StringAlignment)System.Xml.XmlConvert.ToInt32(xmlChild.GetAttribute("ta")); + ci.TextLineAlignment=(StringAlignment)System.Xml.XmlConvert.ToInt32(xmlChild.GetAttribute("tla")); + + m_ComboBox.Items.Add(ci); + + if(xmlChild.HasAttribute("selected") && xmlChild.GetAttribute("selected")=="1") + m_ComboBox.SelectedItem=ci; + } + else if(xmlChild.Name=="co") + { + m_ComboBox.Items.Add(xmlChild.InnerText); + if(xmlChild.HasAttribute("selected") && xmlChild.GetAttribute("selected")=="1") + m_ComboBox.SelectedItem=m_ComboBox.Items[m_ComboBox.Items.Count-1]; + } + } + } + if(m_FontCombo) + m_ComboBox.LoadFonts(); + + if(m_ComboBox!=null) + m_ComboBox.Enabled=this.Enabled; + + if (ItemXmlSource.HasAttribute("DisplayMembers") && m_ComboBox!=null) + m_ComboBox.DisplayMember = ItemXmlSource.GetAttribute("DisplayMembers"); + } + + /// + /// Gets or sets whether combo box generates the audible alert when Enter key is pressed. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates whether combo box generates the audible alert when Enter key is pressed."),System.ComponentModel.DefaultValue(false)] + public bool PreventEnterBeep + { + get + { + return m_PreventEnterBeep; + } + set + { + m_PreventEnterBeep=value; + if(m_ComboBox!=null) + m_ComboBox.PreventEnterBeep=value; + } + } + + private Color _LabelForeColor = Color.Empty; + /// + /// Gets or sets the text color of the combo box label. + /// + [Category("Columns"), Description("Indicates color of combo box label.")] + public Color LabelForeColor + { + get { return _LabelForeColor; } + set { _LabelForeColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLabelForeColor() + { + return !_LabelForeColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetLabelForeColor() + { + this.LabelForeColor = Color.Empty; + } + + public override void Paint(ItemPaintArgs pa) + { + if(this.SuspendLayout) + return; + System.Drawing.Graphics g=pa.Graphics; + Rectangle r=this.DisplayRectangle; + Size objImageSize=GetMaxImageSize(); + bool bOnMenu = this.IsOnMenu && !(this.Parent is ItemContainer); + bool enabled = GetEnabled(pa.ContainerControl); + Color textColor = enabled ? SystemColors.ControlText : SystemColors.ControlDark; + if (BarFunctions.IsOffice2007Style(this.EffectiveStyle) && pa.Renderer is Rendering.Office2007Renderer && + ((Rendering.Office2007Renderer)pa.Renderer).ColorTable.ButtonItemColors.Count > 0) + { + textColor = enabled ? ((Rendering.Office2007Renderer)pa.Renderer).ColorTable.ButtonItemColors[0].Default.Text : pa.Colors.ItemDisabledText; + } + if (!_LabelForeColor.IsEmpty) + textColor = _LabelForeColor; + + if(this.Orientation==eOrientation.Horizontal) + { + if (bOnMenu && (EffectiveStyle == eDotNetBarStyle.OfficeXP || EffectiveStyle == eDotNetBarStyle.Office2003 || EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(EffectiveStyle))) + { + objImageSize.Width+=7; + r.Width-=objImageSize.Width; + r.X+=objImageSize.Width; + if(this.IsOnCustomizeMenu) + objImageSize.Width+=objImageSize.Height+8; + // Draw side bar + Rectangle sideRect = new Rectangle(m_Rect.Left, m_Rect.Top, objImageSize.Width, m_Rect.Height); + if(this.MenuVisibility==eMenuVisibility.VisibleIfRecentlyUsed && !this.RecentlyUsed) + { + if(!pa.Colors.MenuUnusedSide2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient=BarFunctions.CreateLinearGradientBrush(sideRect,pa.Colors.MenuUnusedSide,pa.Colors.MenuUnusedSide2,pa.Colors.MenuUnusedSideGradientAngle); + g.FillRectangle(gradient,sideRect); + gradient.Dispose(); + } + else + g.FillRectangle(new SolidBrush(pa.Colors.MenuUnusedSide), sideRect); + } + else + { + if(!pa.Colors.MenuSide2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(sideRect, pa.Colors.MenuSide, pa.Colors.MenuSide2, pa.Colors.MenuSideGradientAngle); + g.FillRectangle(gradient, sideRect); + gradient.Dispose(); + } + else + g.FillRectangle(new SolidBrush(pa.Colors.MenuSide), sideRect); + } + if (BarFunctions.IsOffice2007Style(EffectiveStyle) && GlobalManager.Renderer is Office2007Renderer) + { + Office2007MenuColorTable mt = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.Menu; + if (mt != null && !mt.SideBorder.IsEmpty) + { + if (pa.RightToLeft) + DisplayHelp.DrawGradientLine(g, sideRect.X + 1, sideRect.Y, sideRect.X + 1, sideRect.Bottom - 1, mt.SideBorder, 1); + else + DisplayHelp.DrawGradientLine(g, sideRect.Right - 2, sideRect.Y, sideRect.Right - 2, sideRect.Bottom - 1, mt.SideBorder, 1); + } + if (mt != null && !mt.SideBorderLight.IsEmpty) + { + if (pa.RightToLeft) + DisplayHelp.DrawGradientLine(g, sideRect.X, sideRect.Y, sideRect.X, sideRect.Bottom - 1, mt.SideBorder, 1); + else + DisplayHelp.DrawGradientLine(g, sideRect.Right - 1, sideRect.Y, sideRect.Right - 1, sideRect.Bottom - 1, mt.SideBorderLight, 1); + } + } + } + + if(this.IsOnCustomizeMenu) + { + if (this.EffectiveStyle == eDotNetBarStyle.OfficeXP || this.EffectiveStyle == eDotNetBarStyle.Office2003 || EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(EffectiveStyle)) + { + r.X+=(objImageSize.Height+8); + r.Width-=(objImageSize.Height+8); + } + else + { + r.X+=(objImageSize.Height+4); + r.Width-=(objImageSize.Height+4); + } + } + + if (bOnMenu && (this.EffectiveStyle == eDotNetBarStyle.OfficeXP || this.EffectiveStyle == eDotNetBarStyle.Office2003 || EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(EffectiveStyle))) + { + if(m_MouseOver) + { + Rectangle rHover=this.DisplayRectangle; + rHover.Inflate(-1,0); + if (BarFunctions.IsOffice2007Style(EffectiveStyle) && !(pa.Owner is DotNetBarManager) && GlobalManager.Renderer is Office2007Renderer) + { + Office2007ButtonItemStateColorTable bt = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.ButtonItemColors[0].MouseOver; + Office2007ButtonItemPainter.PaintBackground(g, bt, rHover, RoundRectangleShapeDescriptor.RoundCorner3); + } + else + { + if (!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(rHover, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient, rHover); + gradient.Dispose(); + } + else + g.FillRectangle(new SolidBrush(pa.Colors.ItemHotBackground), rHover); + NativeFunctions.DrawRectangle(g, new Pen(pa.Colors.ItemHotBorder), rHover); + } + } + } + + // Draw text if needed + if (Caption != "" && (m_AlwaysShowCaption || bOnMenu)) + { + eTextFormat objStringFormat=GetStringFormat(); + Font objFont=this.GetFont(); + Rectangle rText=new Rectangle(r.X+8,r.Y,r.Width,r.Height); + + if (pa.GlassEnabled && this.Parent is CaptionItemContainer && !(this.ContainerControl is Ribbon.QatToolbar)) + { + if (!pa.CachedPaint) + Office2007RibbonControlPainter.PaintTextOnGlass(g, Caption, objFont, + rText, TextDrawing.GetTextFormat(objStringFormat), textColor, true, true, 7); + } + else + { + TextDrawing.DrawString(g, Caption, objFont, textColor, rText, objStringFormat); + } + + Size textSize = TextDrawing.MeasureString(g, Caption, objFont, 0, objStringFormat); + r.X+=(int)textSize.Width+8; + r.Width-=((int)textSize.Width+8); + } + + if(m_ComboBox==null || this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.DesignMode) + { + r.Inflate(-3,-2); + g.FillRectangle(SystemBrushes.Window,r); + NativeFunctions.DrawRectangle(g,SystemPens.ControlDark,r); + r.X=r.Right-(System.Windows.Forms.SystemInformation.HorizontalScrollBarThumbWidth-2); + r.Width=System.Windows.Forms.SystemInformation.HorizontalScrollBarThumbWidth-2; + System.Windows.Forms.ControlPaint.DrawComboButton(g,r,System.Windows.Forms.ButtonState.Flat); + } + else + { + int selLength = m_ComboBox.SelectionLength; + r.Inflate(-2,-2); + if(m_ComboBox.Width!=r.Width) + m_ComboBox.Width=r.Width; + Point loc=r.Location; + loc.Offset((r.Width-m_ComboBox.Width)/2,(r.Height-m_ComboBox.Height)/2); + + ScrollableControl scc = pa.ContainerControl as ScrollableControl; + if (scc != null && scc.AutoScroll) + loc.Offset(scc.AutoScrollPosition.X, scc.AutoScrollPosition.Y); + if (m_ComboBox.Location != loc) + m_ComboBox.Location = loc; + + if (selLength > 0 && selLength < 1000 && m_ComboBox.SelectionLength != selLength && m_ComboBox.Text.Length > selLength && m_ComboBox.DropDownStyle == ComboBoxStyle.DropDown) + { + m_ComboBox.SelectionLength = selLength; + } + } + + if(this.IsOnCustomizeMenu && this.Visible) + { + // Draw check box if this item is visible + Rectangle rBox=new Rectangle(m_Rect.Left,m_Rect.Top,m_Rect.Height,m_Rect.Height); + if (EffectiveStyle == eDotNetBarStyle.OfficeXP || EffectiveStyle == eDotNetBarStyle.Office2003 || EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(EffectiveStyle)) + rBox.Inflate(-1,-1); + BarFunctions.DrawMenuCheckBox(pa, rBox, EffectiveStyle, m_MouseOver); + } + } + else + { + string Caption=this.Text; + if(Caption=="") + Caption="..."; + else + Caption+=" "; + + if (EffectiveStyle == eDotNetBarStyle.OfficeXP || EffectiveStyle == eDotNetBarStyle.Office2003 || EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(EffectiveStyle)) + g.FillRectangle(new SolidBrush(ColorFunctions.ToolMenuFocusBackColor(g)),this.DisplayRectangle); + else + g.FillRectangle(SystemBrushes.Control,this.DisplayRectangle); + + if(m_MouseOver && !this.DesignMode) + { + if (EffectiveStyle == eDotNetBarStyle.Office2000) + { + //r.Inflate(-1,-1); + System.Windows.Forms.ControlPaint.DrawBorder3D(g,r,System.Windows.Forms.Border3DStyle.RaisedInner,System.Windows.Forms.Border3DSide.All); + } + else if (EffectiveStyle == eDotNetBarStyle.OfficeXP || EffectiveStyle == eDotNetBarStyle.Office2003 || EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(EffectiveStyle)) + { + r.Inflate(-1,-1); + g.FillRectangle(new SolidBrush(ColorFunctions.HoverBackColor(g)),r); + NativeFunctions.DrawRectangle(g,SystemPens.Highlight,r); + } + } + + r=new Rectangle(m_Rect.Top,-m_Rect.Right,m_Rect.Height,m_Rect.Width); + g.RotateTransform(90); + eTextFormat sf=GetStringFormat(); + sf |= eTextFormat.HorizontalCenter; + TextDrawing.DrawStringLegacy(g, Caption, GetFont(), textColor, r, sf); + g.ResetTransform(); + } + + if(this.Focused && this.DesignMode) + { + r=this.DisplayRectangle; + r.Inflate(-1,-1); + DesignTime.DrawDesignTimeSelection(g,r,pa.Colors.ItemDesignTimeBorder); + } + + //if(this.DesignMode) + this.DrawInsertMarker(g); + } + + /// + /// IBlock member implementation + /// + [Browsable(false), DevCoBrowsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] + public override System.Drawing.Rectangle Bounds + { + get { return base.Bounds; } + set + { + if (base.Bounds != value) + { + bool topLocationChanged = base.Bounds.Top != value.Top; + bool leftLocationChanged = base.Bounds.Left != value.Left; + base.Bounds = value; + if ((topLocationChanged || leftLocationChanged) && (this.ContainerControl is ItemPanel || this.ContainerControl is ExplorerBar)) + UpdateControlLocation(); + } + } + } + + private void UpdateControlLocation() + { + if (m_ComboBox == null) return; + Rectangle r = this.DisplayRectangle; + r.Inflate(-2, -2); + m_ComboBox.Location = r.Location; + } + + public override void RecalcSize() + { + if (this.SuspendLayout) + return; + + bool bOnMenu = this.IsOnMenu; + + if (this.Orientation == eOrientation.Horizontal) + { + // Default Height + if (this.Parent != null && this.Parent is ImageItem) + m_Rect.Height = ((ImageItem)this.Parent).SubItemsImageSize.Height + Dpi.Height(4); + else + m_Rect.Height = this.SubItemsImageSize.Height + Dpi.Height(4); + + eDotNetBarStyle effectiveStyle = EffectiveStyle; + if (effectiveStyle == eDotNetBarStyle.OfficeXP || effectiveStyle == eDotNetBarStyle.Office2003 || effectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(effectiveStyle)) + { + if (m_ComboBox != null && m_Rect.Height < (m_ComboBox.Height + 2)) + m_Rect.Height = m_ComboBox.Height + 2; + } + else + { + if (m_ComboBox != null && m_Rect.Height < (m_ComboBox.Height + 2)) + m_Rect.Height = m_ComboBox.Height + 2; + } + + // Default width + m_Rect.Width = Dpi.Width(m_ComboWidth + 4); + + // Calculate Item Height + if (Caption != "" && (m_AlwaysShowCaption || bOnMenu)) + { + System.Windows.Forms.Control objCtrl = this.ContainerControl as System.Windows.Forms.Control; + if (objCtrl != null && IsHandleValid(objCtrl)) + { + Graphics g = BarFunctions.CreateGraphics(objCtrl); + try + { + Size textSize = Size.Empty; + if (m_Orientation == eOrientation.Vertical && !bOnMenu) + textSize = TextDrawing.MeasureStringLegacy(g, Caption, GetFont(), Size.Empty, GetStringFormat()); + else + textSize = TextDrawing.MeasureString(g, Caption, GetFont(), 0, GetStringFormat()); + if (textSize.Height > this.SubItemsImageSize.Height && textSize.Height > m_Rect.Height) + m_Rect.Height = (int)textSize.Height + 4; + m_Rect.Width = Dpi.Width(m_ComboWidth + 4) + (int)textSize.Width + 8; + } + finally + { + g.Dispose(); + } + } + } + + Size objImageSize = GetMaxImageSize(); + if (this.IsOnMenu && (effectiveStyle == eDotNetBarStyle.OfficeXP || effectiveStyle == eDotNetBarStyle.Office2003 || effectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(effectiveStyle))) + { + // THis is side bar that will need to be drawn for DotNet style + m_Rect.Width += (objImageSize.Width + 7); + } + + if (this.IsOnCustomizeMenu) + m_Rect.Width += (objImageSize.Height + 2); + } + else + { + // Default width + m_Rect.Width = Dpi.Width(this.SubItemsImageSize.Width + 4); + string caption = this.Caption; + if (caption == "") + caption = "..."; + else + caption += " "; + System.Windows.Forms.Control objCtrl = this.ContainerControl as System.Windows.Forms.Control; + if (objCtrl != null && IsHandleValid(objCtrl)) + { + Graphics g = BarFunctions.CreateGraphics(objCtrl); + try + { + SizeF textSize = TextDrawing.MeasureString(g, caption, GetFont(), 0, GetStringFormat()); + if (textSize.Height > this.SubItemsImageSize.Height) + m_Rect.Width = (int)textSize.Height + 4; + m_Rect.Height = (int)textSize.Width + 8; + } + finally + { + g.Dispose(); + } + } + + } + + // Always call base implementation to reset resize flag + base.RecalcSize(); + } + protected internal override void OnContainerChanged(object objOldContainer) + { + base.OnContainerChanged(objOldContainer); + if(m_ComboBox!=null) + { + if(m_ComboBox.Parent!=null) + { + //bool bVisible=false; + if(m_ComboBox.Visible) + { + m_ComboBox.Visible=false; + //bVisible=true; + } + System.Windows.Forms.Control parent=m_ComboBox.Parent; + parent.Controls.Remove(m_ComboBox); + //if(bVisible) + //m_ComboBox.Visible=true; + } + + System.Windows.Forms.Control objCtrl=null; + if(this.ContainerControl!=null) + { + objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null) + { + objCtrl.Controls.Add(m_ComboBox); + OnDisplayedChanged(); + m_ComboBox.Refresh(); + } + } + } + } + protected internal override void OnAfterItemRemoved(BaseItem item, int itemIndex) + { + base.OnAfterItemRemoved(item, itemIndex); + this.ContainerControl=null; + } + protected internal override void OnVisibleChanged(bool newValue) + { + if(m_ComboBox!=null && !newValue) + m_ComboBox.Visible=newValue; + base.OnVisibleChanged(newValue); + } + protected override void OnDisplayedChanged() + { + if(m_ComboBox!=null && !(this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.DesignMode)) + { + m_ComboBox.Visible=this.Displayed; + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public override void OnGotFocus() + { + base.OnGotFocus(); + if(m_ComboBox==null) + return; + if(m_ComboBox.Focused || this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.DesignMode) + return; + m_ComboBox.Focus(); + } + + private void ComboLostFocus(object sender, EventArgs e) + { + this.HideToolTip(); + this.Text=m_ComboBox.Text; + this.ReleaseFocus(); + if(!m_MouseOver) + return; + m_MouseOver=false; + this.Refresh(); + } + + private void ComboMouseHover(object sender, EventArgs e) + { + if(this.DesignMode) + return; + if(System.Windows.Forms.Control.MouseButtons==System.Windows.Forms.MouseButtons.None) + ShowToolTip(); + } + + private void ComboMouseEnter(object sender, EventArgs e) + { + if(!m_MouseOver) + { + m_MouseOver=true; + this.Refresh(); + } + } + + private void ComboMouseLeave(object sender, EventArgs e) + { + this.HideToolTip(); + if(m_ComboBox.Focused) + return; + if(m_MouseOver) + { + m_MouseOver=false; + this.Refresh(); + } + } + private void ComboBoxVisibleChanged(object sender, EventArgs e) + { + this.HideToolTip(); + } + + private void ComboGotFocus(object sender, EventArgs e) + { + this.HideToolTip(); + this.Focus(); + + if (GetEnabled() && !this.DesignMode) + { + if(m_MenuVisibility==eMenuVisibility.VisibleIfRecentlyUsed && !m_RecentlyUsed && this.IsOnMenu) + { + // Propagate to the top + m_RecentlyUsed=true; + BaseItem objItem=this.Parent; + while(objItem!=null) + { + IPersonalizedMenuItem ipm=objItem as IPersonalizedMenuItem; + if(ipm!=null) + ipm.RecentlyUsed=true; + objItem=objItem.Parent; + } + } + } + } + + private void ComboSelChanged(object sender, EventArgs e) + { + if (!_CopyInProgress) + { + this.RaiseClick(); + if (SelectedIndexChanged != null) + SelectedIndexChanged(this, e); + if (ShouldSyncProperties) + BarFunctions.SyncProperty(this, "SelectedIndex"); + ExecuteCommand(); + } + + } + + private void ComboKeyDown(object sender,System.Windows.Forms.KeyEventArgs e) + { + this.HideToolTip(); + if(e.KeyCode==System.Windows.Forms.Keys.Enter && this.Parent is PopupItem) + { + ((PopupItem)this.Parent).ClosePopup(); + } + } + private void ComboDropDownChange(object sender,bool bExpanded) + { + this.Expanded=bExpanded; + if(!bExpanded) + this.ReleaseFocus(); + } + protected override void OnIsOnCustomizeDialogChanged() + { + base.OnIsOnCustomizeDialogChanged(); + CustomizeChanged(); + } + + protected override void OnDesignModeChanged() + { + base.OnDesignModeChanged(); + CustomizeChanged(); + } + + protected override void OnIsOnCustomizeMenuChanged() + { + base.OnIsOnCustomizeMenuChanged(); + CustomizeChanged(); + } + + private void CustomizeChanged() + { + if(this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.DesignMode) + { + m_ComboBox.Visible=false; + } + else + { + m_ComboBox.Visible=this.Displayed; + } + } + + /// + /// Gets or sets the width of the of the drop-down portion of a combo box. + /// + [Category("Layout"), Browsable(true), Description("Indicates width of the of the drop-down portion of a combo box.")] + public int DropDownWidth + { + get { return m_ComboBox.DropDownWidth; } + set { m_ComboBox.DropDownWidth = value; } + } + + /// + /// Returns whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeDropDownWidth() + { + return m_ComboBox.Width != m_ComboBox.DropDownWidth; + } + + /// + /// Gets or sets the height of the of the drop-down portion of a combo box. + /// + [Category("Layout"), Browsable(true), DefaultValue(0), Description("Indicates height of the of the drop-down portion of a combo box.")] + public int DropDownHeight + { + get { return m_ComboBox.DropDownHeight; } + set { m_ComboBox.DropDownHeight = value; } + } + + /// + /// Indicates the Width of the combo box part of the item. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Indicates the Width of the combo box part of the item."),System.ComponentModel.DefaultValue(64)] + public int ComboWidth + { + get + { + return m_ComboWidth; + } + set + { + if(m_ComboWidth!=value) + { + m_ComboWidth=value; + if(this.Name!="" && this.GlobalItem) + { + BarFunctions.SetProperty(this.GetOwner(),this.GetType(),m_Name,System.ComponentModel.TypeDescriptor.GetProperties(this)["ComboWidth"],m_ComboWidth); + } + NeedRecalcSize=true; + this.Refresh(); + } + OnAppearanceChanged(); + } + } + + /// + /// Overridden. Releases the input focus. + /// + public override void ReleaseFocus() + { + if(m_ComboBox!=null && m_ComboBox.Focused) + m_ComboBox.ReleaseFocus(); + base.ReleaseFocus(); + } + + /// + /// Indicates whether control automatically releases its input focus when selection is made using keyboard. + /// + [DefaultValue(true), Browsable(true), Category("Behavior"), Description("Indicates whether control automatically releases its input focus when selection is made using keyboard.")] + public bool AutoReleaseFocus + { + get + { + return m_ComboBox.AutoReleaseFocus; + } + set + { + m_ComboBox.AutoReleaseFocus = value; + } + } + + /// + /// Returns the reference to the inner combo box control. + /// + [Browsable(false)] + public ComboBoxEx ComboBoxEx + { + get + { + return m_ComboBox; + } + } + +// [System.ComponentModel.Browsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("The caption of the item.")] +// public string Caption +// { +// get +// { +// return m_Caption; +// } +// set +// { +// if(m_Caption!=value) +// { +// m_Caption=value; +// if(this.Name!="" && this.GlobalItem) +// { +// BarFunctions.SetProperty(this.GetOwner(),this.GetType(),m_Name,System.ComponentModel.TypeDescriptor.GetProperties(this)["Caption"],m_Caption); +// } +// m_NeedRecalcSize=true; +// this.Refresh(); +// } +// } +// } + + /// + /// Indicates whether item caption is always shown. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates whether item caption is always shown."), System.ComponentModel.DefaultValue(false)] + public bool AlwaysShowCaption + { + get + { + return m_AlwaysShowCaption; + } + set + { + if(m_AlwaysShowCaption!=value) + { + m_AlwaysShowCaption=value; + } + NeedRecalcSize=true; + } + } + private Size GetMaxImageSize() + { + if(m_Parent!=null) + { + ImageItem objParentImageItem=m_Parent as ImageItem; + if(objParentImageItem!=null) + return objParentImageItem.SubItemsImageSize; + else + return this.ImageSize; + } + else + return this.ImageSize; + } + private eTextFormat GetStringFormat() + { + eTextFormat format = eTextFormat.Default; + format |= eTextFormat.SingleLine; + format |= eTextFormat.EndEllipsis; + format |= eTextFormat.VerticalCenter; + return format; + //sfmt.HotkeyPrefix=System.Drawing.Text.HotkeyPrefix.Show; + //sfmt.FormatFlags=sfmt.FormatFlags | StringFormatFlags.NoWrap; + //sfmt.Trimming=StringTrimming.EllipsisCharacter; + //sfmt.Alignment=System.Drawing.StringAlignment.Near; + //sfmt.LineAlignment=System.Drawing.StringAlignment.Center; + + //return sfmt; + } + protected virtual Font GetFont() + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null) + return (Font)objCtrl.Font; + return SystemFonts.DefaultFont; + } + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseEnter() + { + base.InternalMouseEnter(); + //if(this.DesignMode || this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.Orientation==eOrientation.Vertical) + if(!m_MouseOver) + { + m_MouseOver=true; + this.Refresh(); + } + } + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseLeave() + { + base.InternalMouseLeave(); + if(m_MouseOver) + { + m_MouseOver=false; + this.Refresh(); + } + } + protected internal override bool IsAnyOnHandle(IntPtr iHandle) + { + bool bRet=base.IsAnyOnHandle(iHandle); + if(!bRet && m_ComboBox!=null && m_ComboBox.DroppedDown && m_ComboBox.DropDownHandle!=IntPtr.Zero && m_ComboBox.DropDownHandle==iHandle) + bRet=true; + return bRet; + } + protected override void OnStyleChanged() + { + base.OnStyleChanged(); + m_ComboBox.Style=this.Style; + } + + /// + /// Gets an object representing the collection of the items contained in inner ComboBoxEx. + /// + [System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ComboItemsEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.Category("Data"), DevCoBrowsable(true), Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public System.Windows.Forms.ComboBox.ObjectCollection Items + { + get + { + return m_ComboBox.Items; + + } + } + + /// + /// Gets or sets a value specifying the style of the combo box. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),DefaultValue(System.Windows.Forms.ComboBoxStyle.DropDownList),System.ComponentModel.Description("Gets or sets a value specifying the style of the combo box.")] + public System.Windows.Forms.ComboBoxStyle DropDownStyle + { + get + { + return m_ComboBox.DropDownStyle; + } + set + { + m_ComboBox.DropDownStyle=value; + } + } + + /// + /// Gets or sets the starting index of text selected in the combo box. + /// + [Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden),System.ComponentModel.DefaultValue(0)] + public int SelectionStart + { + get + { + return m_ComboBox.SelectionStart; + } + set + { + m_ComboBox.SelectionStart=value; + } + } + + /// + /// Gets or sets the number of characters selected in the editable portion of the combo box. + /// + [Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden),System.ComponentModel.DefaultValue(0)] + public int SelectionLength + { + get + { + return m_ComboBox.SelectionLength; + } + set + { + m_ComboBox.SelectionLength=value; + } + } + + /// + /// Gets or sets the text that is selected in the editable portion of a combo box. + /// + [Browsable(false),System.ComponentModel.DefaultValue(""),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public string SelectedText + { + get + { + return m_ComboBox.SelectedText; + } + set + { + m_ComboBox.SelectedText=value; + } + } + + /// + /// Gets or sets currently selected item in the combo box. + /// + [Browsable(false),System.ComponentModel.DefaultValue(null),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public object SelectedItem + { + get + { + return m_ComboBox.SelectedItem; + } + set + { + m_ComboBox.SelectedItem=value; + } + } + + /// + /// Gets or sets the index specifying the currently selected item. + /// + [Browsable(false),System.ComponentModel.DefaultValue(-1),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public int SelectedIndex + { + get + { + return m_ComboBox.SelectedIndex; + } + set + { + m_ComboBox.SelectedIndex=value; + } + } + + /// + /// Gets or sets the value indicating whether the item automatically loads all the fonts available into the combo box. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Automatically loads all the fonts available into the combo box."),System.ComponentModel.DefaultValue(false)] + public bool FontCombo + { + get + { + return m_FontCombo; + } + set + { + if(m_FontCombo!=value) + { + m_FontCombo=value; + if(m_FontCombo) + { + m_ComboBox.LoadFonts(); + m_ComboBox.DropDownStyle=System.Windows.Forms.ComboBoxStyle.DropDownList; + //m_ComboBox.DrawMode=System.Windows.Forms.DrawMode.OwnerDrawVariable; + } + } + } + } + + /// + /// Gets or sets the height of an item in the combo box. + /// + [DefaultValue(15), System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates the height of an item in the combo box.")] + public int ItemHeight + { + get + { + return m_ComboBox.ItemHeight; + } + set + { + m_ComboBox.ItemHeight=value; + } + } + + // IPersonalizedMenuItem Implementation + /// + /// Indicates item's visibility when on pop-up menu. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates item's visiblity when on pop-up menu."),System.ComponentModel.DefaultValue(eMenuVisibility.VisibleAlways)] + public eMenuVisibility MenuVisibility + { + get + { + return m_MenuVisibility; + } + set + { + if(m_MenuVisibility!=value) + { + m_MenuVisibility=value; + if(m_Name!="" && this.GlobalItem) + { + BarFunctions.SetProperty(this.GetOwner(),this.GetType(),m_Name,System.ComponentModel.TypeDescriptor.GetProperties(this)["MenuVisibility"],m_MenuVisibility); + } + } + } + } + /// + /// Gets or sets the value that indicates whether the item was recently used. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DefaultValue(false)] + public bool RecentlyUsed + { + get + { + return m_RecentlyUsed; + } + set + { + if(m_RecentlyUsed!=value) + { + m_RecentlyUsed=value; + if(m_Name!="" && this.GlobalItem) + { + BarFunctions.SetProperty(this.GetOwner(),this.GetType(),m_Name,System.ComponentModel.TypeDescriptor.GetProperties(this)["RecentlyUsed"],m_RecentlyUsed); + } + } + } + } + + protected override void OnEnabledChanged() + { + base.OnEnabledChanged(); + if(m_ComboBox!=null) + m_ComboBox.Enabled=this.Enabled; + } + + private void InternalComboTextChanged(object sender, EventArgs e) + { + if(!_SettingText) + this.Text = m_ComboBox.Text; + OnComboBoxTextChanged(e); + } + + /// + /// Raises the ComboBoxTextChanged event. + /// + /// Provides event arguments. + protected virtual void OnComboBoxTextChanged(EventArgs e) + { + if (ComboBoxTextChanged != null) + ComboBoxTextChanged(this, e); + } + + /// + /// Overridden. Gets or sets the text associated with this item. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false), Obsolete("Please use Text property instead to access ComboBox text.")] + public virtual string ControlText + { + get + { + return this.Text; + } + set + { + this.Text = value; + } + } + + /// + /// Gets or sets the text associated with this item. + /// + [Browsable(true), Category("Appearance"), Description("The text contained in the underlining Control portion of the item."), DefaultValue("")] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + private bool _SettingText = false; + protected override void OnTextChanged() + { + if (m_ComboBox != null && m_ComboBox.Text != this.Text) + { + try + { + _SettingText = true; + m_ComboBox.Text = this.Text; + } + finally + { + _SettingText = false; + } + } + base.OnTextChanged(); + } + + private string _Caption = ""; + /// + /// Gets or sets the item caption text displayed next to the combo box. + /// + [DefaultValue(""), System.ComponentModel.Category("Appearance"), Description("Indicates the item Caption displayed next to the combo box."), Localizable(true)] + public string Caption + { + get { return _Caption; } + set + { + if (value == null) value = ""; + _Caption = value; + } + } + + /// + /// Gets or sets a string that specifies the property of the data source whose contents you want to display. When ComboBoxItem is used in DropDown mode + /// and objects like ComboItem are added to ComboBoxItems.Items collection DisplayMembers should be set to the name of the property you would + /// like to use as text representation in editable portion of ComboBox. For example in case of ComboItem objects property should be set to Text. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Data"), System.ComponentModel.Description("Indicates string that specifies the property of the data source whose contents you want to display."), System.ComponentModel.DefaultValue("")] + public virtual string DisplayMember + { + get + { + if(m_ComboBox!=null) + return m_ComboBox.DisplayMember; + return ""; + } + set + { + if (m_ComboBox != null) + m_ComboBox.DisplayMember = value; + } + } + + /// + /// Specifies whether combo box is drawn using themes when running on OS that supports themes like Windows XP + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Specifies whether combo box is drawn using themes when running on OS that supports themes like Windows XP.")] + public override bool ThemeAware + { + get + { + return m_ComboBox.ThemeAware; + } + set + { + m_ComboBox.ThemeAware=value; + } + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override bool IsWindowed + { + get {return true;} + } + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark font."), DefaultValue(null)] + public Font WatermarkFont + { + get { return m_ComboBox.WatermarkFont; } + set { m_ComboBox.WatermarkFont = value; } + } + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return m_ComboBox.WatermarkColor; } + set { m_ComboBox.WatermarkColor = value; } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return m_ComboBox.WatermarkColor != SystemColors.GrayText; + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + this.WatermarkColor = SystemColors.GrayText; + } + + /// + /// Gets or sets whether watermark text is displayed when control is empty. Default value is true. + /// + [DefaultValue(true), Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return m_ComboBox.WatermarkEnabled; } + set { m_ComboBox.WatermarkEnabled = value; } + } + + /// + /// Gets or sets the watermark (tip) text displayed inside of the control when Text is not set and control does not have input focus. This property supports text-markup. + /// Note that WatermarkText is not compatible with the auto-complete feature of .NET Framework 2.0. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus."), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string WatermarkText + { + get { return m_ComboBox.WatermarkText; } + set + { + m_ComboBox.WatermarkText = value; + } + } + + /// + /// Gets or sets the watermark hiding behaviour. Default value indicates that watermark is hidden when control receives input focus. + /// + [DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior"), Description("Indicates watermark hiding behaviour.")] + public eWatermarkBehavior WatermarkBehavior + { + get { return m_ComboBox.WatermarkBehavior; } + set { m_ComboBox.WatermarkBehavior = value; } + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), RefreshProperties(RefreshProperties.All), ParenthesizePropertyName(true)] + public ControlBindingsCollection DataBindings + { + get { return m_ComboBox.DataBindings; } + } + + /// + /// Gets or sets whether control is stand-alone control. Stand-alone flag affects the appearance of the control in Office 2007 style. + /// + [Browsable(true), DefaultValue(false), Category("Appearance"), Description("Indicates the appearance of the control.")] + public bool IsStandalone + { + get { return m_ComboBox.IsStandalone; } + set + { + m_ComboBox.IsStandalone = value; + } + } + + public override string ToString() + { + return m_Text; + } + } +} diff --git a/PROMS/DotNetBar Source Code/ComboItem.cs b/PROMS/DotNetBar Source Code/ComboItem.cs new file mode 100644 index 00000000..a05145da --- /dev/null +++ b/PROMS/DotNetBar Source Code/ComboItem.cs @@ -0,0 +1,354 @@ +using System; +using System.Windows.Forms; +using System.Drawing.Drawing2D; +using System.Drawing; +using System.ComponentModel; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar; + +namespace DevComponents.Editors +{ + /// + /// Summary description for ComboItem. + /// + [System.ComponentModel.ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false)] + public class ComboItem:Component + { + private string m_Text=""; + private int m_ImageIndex=-1; + private Image m_Image; + private StringFormat m_TextFormat; + private HorizontalAlignment m_ImagePosition=HorizontalAlignment.Left; + + private string m_FontName=""; + private FontStyle m_FontStyle=FontStyle.Regular; + private float m_FontSize=8; + + private Color m_ForeColor=Color.Empty; + private Color m_BackColor=Color.Empty; + + private object m_Tag; + + internal ComboBoxEx m_ComboBox=null; + internal bool IsFontItem=false; + + /// + /// Creates new instance of ComboItem. + /// + public ComboItem() + { + m_TextFormat=DevComponents.DotNetBar.BarFunctions.CreateStringFormat(); //new StringFormat(StringFormat.GenericDefault); + m_TextFormat.Alignment=StringAlignment.Near; + } + + /// + /// Initializes a new instance of the ComboItem class. + /// + /// + public ComboItem(string text) : this() + { + this.m_Text = text; + } + + /// + /// Initializes a new instance of the ComboItem class. + /// + /// + /// + public ComboItem(string text, Color foreColor) : this() + { + this.m_Text = text; + this.m_ForeColor = foreColor; + } + + /// + /// Initializes a new instance of the ComboItem class. + /// + /// + /// + /// + public ComboItem(string text, Color foreColor, Color backColor) + : this() + { + this.m_Text = text; + this.m_ForeColor = foreColor; + this.m_BackColor = backColor; + } + + /// + /// Initializes a new instance of the ComboItem class. + /// + /// + /// + public ComboItem(string text, Image image) + : this() + { + this.m_Text = text; + this.m_Image = image; + } + + protected override void Dispose(bool disposing) + { + if (BarUtilities.DisposeItemImages && !this.DesignMode) + { + BarUtilities.DisposeImage(ref m_Image); + } + base.Dispose(disposing); + } + + /// + /// Gets or sets the text associated with this item. + /// + [DefaultValue(""),Browsable(true), Localizable(true)] + public string Text + { + get + { + return m_Text; + } + set + { + m_Text=value; + } + } + + /// + /// Gets or sets the index value of the image assigned to the item. + /// + [DefaultValue(-1), System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter)), Localizable(true)] + public int ImageIndex + { + get + { + return m_ImageIndex; + } + set + { + m_ImageIndex=value; + } + } + + /// + /// Gets or sets the text alignment.. + /// + [DefaultValue(StringAlignment.Near)] + public StringAlignment TextAlignment + { + get + { + return m_TextFormat.Alignment; + } + set + { + m_TextFormat.Alignment=value; + } + } + + /// + /// Gets or sets the line alignment for the item. + /// + [DefaultValue(StringAlignment.Near)] + public StringAlignment TextLineAlignment + { + get + { + return m_TextFormat.LineAlignment; + } + set + { + m_TextFormat.LineAlignment=value; + } + } + + /// + /// Gets or sets the value that encapsulates text layout information (such as alignment, orientation, tab stops, and clipping) and display manipulations. + /// + [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public StringFormat TextFormat + { + get + { + return m_TextFormat; + } + set + { + m_TextFormat=value; + } + } + + /// + /// Gets or sets the image horizontal image position. + /// + [DefaultValue(HorizontalAlignment.Left)] + public HorizontalAlignment ImagePosition + { + get + { + return m_ImagePosition; + } + set + { + m_ImagePosition=value; + } + } + + /// + /// Gets or sets the font name used to draw the item text. + /// + [DefaultValue("")] + public String FontName + { + get + { + return m_FontName; + } + set + { + m_FontName=value; + } + } + + /// + /// Gets or sets the text color. + /// + public Color ForeColor + { + get + { + return m_ForeColor; + } + set + { + m_ForeColor=value; + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeForeColor() + { + return !m_ForeColor.IsEmpty; + } + + /// + /// Gets or sets the background color of the item. + /// + public Color BackColor + { + get + { + return m_BackColor; + } + set + { + m_BackColor=value; + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColor() + { + return !m_BackColor.IsEmpty; + } + + /// + /// Specifies style information applied to text. + /// + [DefaultValue(FontStyle.Regular)] + public System.Drawing.FontStyle FontStyle + { + get + { + return m_FontStyle; + } + set + { + m_FontStyle=value; + } + } + + /// + /// Gets the em-size of this Font object in design units. + /// + [DefaultValue(8f)] + public float FontSize + { + get + { + return m_FontSize; + } + set + { + m_FontSize=value; + } + } + + /// + /// Gets or sets the image assigned to this item. + /// + [DefaultValue(null), Localizable(true)] + public System.Drawing.Image Image + { + get + { + return m_Image; + } + set + { + m_Image=value; + } + } + + /// + /// Overridden. Returns a human-readable string representation of this object. + /// + /// A string that represents this object. + public override string ToString() + { + return m_Text; + } + + /// + /// Gets or sets an object that contains data to associate with the item. + /// + [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object Tag + { + get + { + return m_Tag; + } + set + { + m_Tag=value; + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public System.Windows.Forms.ImageList ImageList + { + get + { + if(m_ComboBox!=null) + { + return m_ComboBox.Images; + } + return null; + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public ComboBoxEx Parent + { + get + { + return m_ComboBox; + } + } + + private object _Value = null; + [DefaultValue(null), Category("Data"), TypeConverter(typeof(StringConverter)), Localizable(true)] + public object Value + { + get { return _Value; } + set { _Value = value; } + } + } +} diff --git a/PROMS/DotNetBar Source Code/Command.ico b/PROMS/DotNetBar Source Code/Command.ico new file mode 100644 index 00000000..236756d7 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Command.ico differ diff --git a/PROMS/DotNetBar Source Code/CommandLink.cs b/PROMS/DotNetBar Source Code/CommandLink.cs new file mode 100644 index 00000000..25b62cf3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandLink.cs @@ -0,0 +1,144 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the base class that provides link between DotNetBar BaseItem commands and typed code representation for them. + /// + [ToolboxItem(false), DesignTimeVisible(false), DefaultEvent("Click")] + public class CommandLink : Component + { + #region Private Variables + private string m_Name = ""; + private DotNetBarManager m_Manager = null; + private static string CommandPrefix = "cmd"; + #endregion + + #region Events + /// + /// Occurs when item connected to the command link is clicked. + /// + public event EventHandler Click; + #endregion + + /// + /// Returns name of the item that can be used to identify item from the code. You should not set this property directly since it is populated by DotNetBar designer. + /// + [Browsable(false), Category("Design"), Description("Indicates the name used to identify item command link is connected to.")] + 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; + } + } + + protected virtual BaseItem GetItem(Type expectedItemType) + { + if (this.Manager == null) + throw new InvalidOperationException("Manager property is not assigned to the instance of DotNetBarManager this CommandLink is linking to."); + + string itemName = GetItemName(this.Name); + if (itemName == "") + { + throw new InvalidOperationException("Command link name is not in expected format. Could not retrive item."); + } + + BaseItem item = this.Manager.GetItem(itemName, true); + + if (item == null) + throw new InvalidOperationException("Item '" + itemName + "' cannot be found. DotNetBarManager definition might not be loaded. Try moving your code to Load event."); + + if (item.GetType() != expectedItemType) + throw new InvalidOperationException("This CommandLink type can only by connected to " + expectedItemType.Name + " type. Currently link is connecting to " + item.GetType().ToString()); + + return item; + } + + /// + /// Disconnects the CommandLink object to the DotNetBarManager. + /// + protected virtual void DisconnectManager() + { + if (m_Manager == null) + return; + m_Manager.ItemClick -= new EventHandler(ItemClick); + m_Manager.CommandLinks.Remove(this); + } + + /// + /// Connects the CommandLink object to the DotNetBarManager. + /// + protected virtual void ConnectManager() + { + if (m_Manager == null) + return; + m_Manager.ItemClick += new EventHandler(ItemClick); + m_Manager.CommandLinks.Add(this); + } + + private void ItemClick(object sender, EventArgs e) + { + if(sender is BaseItem) + { + BaseItem item = sender as BaseItem; + if(item.Name == GetItemName(this.Name)) + { + if (Click != null) + Click(sender, e); + } + } + } + + /// + /// Gets or sets the instance of DotNetBarManager associated with the command link. + /// + [Browsable(false), DefaultValue(null)] + public DotNetBarManager Manager + { + get { return m_Manager; } + set + { + if (m_Manager != null) + DisconnectManager(); + m_Manager = value; + + if (m_Manager != null) + ConnectManager(); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + this.Manager = null; + base.Dispose(disposing); + } + + internal static string GetCommandLinkName(string itemName) + { + return CommandPrefix + itemName; + } + + internal static string GetItemName(string commandLinkName) + { + if (commandLinkName.StartsWith(CommandPrefix)) + return commandLinkName.Substring(CommandPrefix.Length); + + return ""; + } + } +} diff --git a/PROMS/DotNetBar Source Code/CommandLinkButtonItem.cs b/PROMS/DotNetBar Source Code/CommandLinkButtonItem.cs new file mode 100644 index 00000000..8eeb0456 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandLinkButtonItem.cs @@ -0,0 +1,25 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the typed command link for ButtonItem type. + /// + public class CommandLinkButtonItem : CommandLink + { + /// + /// Gets reference to the ButtonItem this CommandLink is linked to. Note that this is the first ButtonItem object found by DotNetBarManager. + /// It is possible that multiple buttons have same name see Global Items under DotNetBar Fundamentals in help file for more details. + /// + [Browsable(false)] + public ButtonItem Item + { + get + { + return this.GetItem(typeof(ButtonItem)) as ButtonItem; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/CommandLinkColorPickerDropDown.cs b/PROMS/DotNetBar Source Code/CommandLinkColorPickerDropDown.cs new file mode 100644 index 00000000..3598430e --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandLinkColorPickerDropDown.cs @@ -0,0 +1,53 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the typed command link for ColorPickerDropDown type. + /// + public class CommandLinkColorPickerDropDown : CommandLink + { + #region Events + /// + /// Occurs when color is choosen from drop-down color picker or from Custom Colors dialog box. Selected color can be accessed through SelectedColor property. + /// + [Description("Occurs when color is choosen from drop-down color picker or from Custom Colors dialog box.")] + public event EventHandler SelectedColorChanged; + #endregion + + /// + /// Gets reference to the ColorPickerDropDown this CommandLink is linked to. Note that this is the first ColorPickerDropDown object found by DotNetBarManager. + /// It is possible that multiple buttons have same name see Global Items under DotNetBar Fundamentals in help file for more details. + /// + [Browsable(false)] + public ColorPickerDropDown Item + { + get + { + return this.GetItem(typeof(ColorPickerDropDown)) as ColorPickerDropDown; + } + } + + protected override void ConnectManager() + { + base.ConnectManager(); + if(this.Manager!=null) + this.Manager.ColorPickerSelectedColorChanged += new EventHandler(ManagerColorPickerSelectedColorChanged); + } + + private void ManagerColorPickerSelectedColorChanged(object sender, EventArgs e) + { + if (SelectedColorChanged != null) + SelectedColorChanged(sender, e); + } + + protected override void DisconnectManager() + { + base.DisconnectManager(); + if(this.Manager!=null) + this.Manager.ColorPickerSelectedColorChanged -= new EventHandler(ManagerColorPickerSelectedColorChanged); + } + } +} diff --git a/PROMS/DotNetBar Source Code/CommandLinkComboBoxItem.cs b/PROMS/DotNetBar Source Code/CommandLinkComboBoxItem.cs new file mode 100644 index 00000000..9c6d9491 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandLinkComboBoxItem.cs @@ -0,0 +1,25 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the command link for a combo box item + /// + public class CommandLinkComboBoxItem : CommandLink + { + /// + /// Gets reference to the ComboBoxItem this CommandLink is linked to. Note that this is the first ComboBoxItem object found by DotNetBarManager. + /// It is possible that multiple buttons have same name see Global Items under DotNetBar Fundamentals in help file for more details. + /// + [Browsable(false)] + public ComboBoxItem Item + { + get + { + return this.GetItem(typeof(ComboBoxItem)) as ComboBoxItem; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/CommandLinkControlContainerItem.cs b/PROMS/DotNetBar Source Code/CommandLinkControlContainerItem.cs new file mode 100644 index 00000000..0807ec6d --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandLinkControlContainerItem.cs @@ -0,0 +1,25 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the typed command link for ControlContainerItem type. + /// + public class CommandLinkControlContainerItem : CommandLink + { + /// + /// Gets reference to the ControlContainerItem this CommandLink is linked to. Note that this is the first ControlContainerItem object found by DotNetBarManager. + /// It is possible that multiple buttons have same name see Global Items under DotNetBar Fundamentals in help file for more details. + /// + [Browsable(false)] + public ControlContainerItem Item + { + get + { + return this.GetItem(typeof(ControlContainerItem)) as ControlContainerItem; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/CommandLinkDockContainerItem.cs b/PROMS/DotNetBar Source Code/CommandLinkDockContainerItem.cs new file mode 100644 index 00000000..326e8210 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandLinkDockContainerItem.cs @@ -0,0 +1,25 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the typed command link for DockContainerItem type. + /// + public class CommandLinkDockContainerItem : CommandLink + { + /// + /// Gets reference to the ControlContainerItem this CommandLink is linked to. Note that this is the first ControlContainerItem object found by DotNetBarManager. + /// It is possible that multiple buttons have same name see Global Items under DotNetBar Fundamentals in help file for more details. + /// + [Browsable(false)] + public DockContainerItem Item + { + get + { + return this.GetItem(typeof(DockContainerItem)) as DockContainerItem; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/CommandLinkLabelItem.cs b/PROMS/DotNetBar Source Code/CommandLinkLabelItem.cs new file mode 100644 index 00000000..a09e3fde --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandLinkLabelItem.cs @@ -0,0 +1,25 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the command link for a label item + /// + public class CommandLinkLabelItem : CommandLink + { + /// + /// Gets reference to the LabelItem this CommandLink is linked to. Note that this is the first LabelItem object found by DotNetBarManager. + /// It is possible that multiple buttons have same name see Global Items under DotNetBar Fundamentals in help file for more details. + /// + [Browsable(false)] + public LabelItem Item + { + get + { + return this.GetItem(typeof(LabelItem)) as LabelItem; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/CommandLinkProgressBarItem.cs b/PROMS/DotNetBar Source Code/CommandLinkProgressBarItem.cs new file mode 100644 index 00000000..f280b2c2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandLinkProgressBarItem.cs @@ -0,0 +1,25 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the typed command link for ProgressBarItem type. + /// + public class CommandLinkProgressBarItem : CommandLink + { + /// + /// Gets reference to the ControlContainerItem this CommandLink is linked to. Note that this is the first ControlContainerItem object found by DotNetBarManager. + /// It is possible that multiple buttons have same name see Global Items under DotNetBar Fundamentals in help file for more details. + /// + [Browsable(false)] + public ProgressBarItem Item + { + get + { + return this.GetItem(typeof(ProgressBarItem)) as ProgressBarItem; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/CommandLinkTextBoxItem.cs b/PROMS/DotNetBar Source Code/CommandLinkTextBoxItem.cs new file mode 100644 index 00000000..8b14f9e6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandLinkTextBoxItem.cs @@ -0,0 +1,55 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the command link for a text box item + /// + public class CommandLinkTextBoxItem : CommandLink + { + #region Events + /// + /// Occurs when text in text box item has changed. + /// + public event EventHandler InputTextChanged; + #endregion + + /// + /// Gets reference to the TextBoxItem this CommandLink is linked to. Note that this is the first TextBoxItem object found by DotNetBarManager. + /// It is possible that multiple buttons have same name see Global Items under DotNetBar Fundamentals in help file for more details. + /// + [Browsable(false)] + public TextBoxItem Item + { + get + { + return this.GetItem(typeof(TextBoxItem)) as TextBoxItem; + } + } + + protected override void ConnectManager() + { + base.ConnectManager(); + + if (this.Manager != null) + { + this.Manager.TextBoxItemTextChanged += new EventHandler(this.ItemInputTextChanged); + } + } + + protected override void DisconnectManager() + { + base.DisconnectManager(); + if(this.Manager!=null) + this.Manager.TextBoxItemTextChanged -= new EventHandler(this.ItemInputTextChanged); + } + + private void ItemInputTextChanged(object sender, EventArgs e) + { + if (InputTextChanged != null) + InputTextChanged(sender, e); + } + } +} diff --git a/PROMS/DotNetBar Source Code/CommandManager.cs b/PROMS/DotNetBar Source Code/CommandManager.cs new file mode 100644 index 00000000..2c244bfb --- /dev/null +++ b/PROMS/DotNetBar Source Code/CommandManager.cs @@ -0,0 +1,148 @@ +using System; +using System.Text; +using System.Collections; + +namespace DevComponents.DotNetBar +{ + /// + /// Provides command related utility methods that register and unregister commands. + /// + public class CommandManager + { + private static Hashtable _CommandBindings = new Hashtable(); + private static bool _UseReflection = true; + + /// + /// Gets or sets whether commands use Reflection to find the property names when applying value to the unknown types. Default value is true. + /// Setting this value to false will increase performance if Unknown types are used but it will at same time disable the + /// command setting value for these types. + /// + public static bool UseReflection + { + get + { + return _UseReflection; + } + set + { + _UseReflection = value; + } + } + + private static bool _AutoUpdateLayout = true; + /// + /// Gets or sets whether layout on the items of type BaseItem is automatically updated when command text or other property changes which requires layout updated. Default value is true. + /// + public static bool AutoUpdateLayout + { + get { return _AutoUpdateLayout; } + set + { + if (_AutoUpdateLayout != value) + { + _AutoUpdateLayout = value; + } + } + } + + /// + /// Connects the Command Source to the Command. + /// + /// Command source to connect to the command. + /// Reference to the command. + public static void RegisterCommand(ICommandSource commandSource, ICommand command) + { + if (commandSource == null) + throw new NullReferenceException("commandSource cannot be null"); + if (command == null) + throw new NullReferenceException("command cannot be null"); + + ArrayList subscribers = null; + if (_CommandBindings.Contains(command)) + { + subscribers = (ArrayList)_CommandBindings[command]; + if (!subscribers.Contains(commandSource)) + subscribers.Add(commandSource); + } + else + { + subscribers = new ArrayList(); + subscribers.Add(commandSource); + _CommandBindings.Add(command, subscribers); + } + command.CommandSourceRegistered(commandSource); + } + + /// + /// Disconnects command source from the command. + /// + /// Reference to command source. + /// Reference to the command. + public static void UnRegisterCommandSource(ICommandSource commandSource, ICommand command) + { + if (commandSource == null) + throw new NullReferenceException("commandSource cannot be null"); + if (command == null) + throw new NullReferenceException("command cannot be null"); + if (_CommandBindings.Contains(command)) + { + ArrayList subscribers = (ArrayList)_CommandBindings[command]; + if (subscribers.Contains(commandSource)) + subscribers.Remove(commandSource); + } + command.CommandSourceUnregistered(commandSource); + } + + /// + /// Unregister command from all subscribers. Called when command is disposed. + /// + /// Command to unregister. + public static void UnRegisterCommand(ICommand command) + { + if (command == null) + throw new NullReferenceException("command cannot be null"); + + if (_CommandBindings.Contains(command)) + _CommandBindings.Remove(command); + } + + /// + /// Gets an array of Command Sources that are connected with the command. + /// + /// Reference to command + /// An array of command sources. + public static ArrayList GetSubscribers(ICommand command) + { + if (command == null) + throw new NullReferenceException("command cannot be null"); + ArrayList subscribers = null; + if (_CommandBindings.Contains(command)) + subscribers = (ArrayList)((ArrayList)_CommandBindings[command]).Clone(); + else + subscribers = new ArrayList(); + + return subscribers; + } + + internal static void ExecuteCommand(ICommandSource commandSource) + { + if (commandSource == null) + throw new NullReferenceException("commandSource cannot be null"); + ICommand command=commandSource.Command; + if(command == null) + throw new NullReferenceException("commandSource.Command cannot be null"); + + command.Execute(commandSource); + } + + internal static void ExecuteCommand(ICommandSource commandSource, ICommand command) + { + if (commandSource == null) + throw new NullReferenceException("commandSource cannot be null"); + if (command == null) + throw new NullReferenceException("commandSource.Command cannot be null"); + + command.Execute(commandSource); + } + } +} diff --git a/PROMS/DotNetBar Source Code/CompositeImage.cs b/PROMS/DotNetBar Source Code/CompositeImage.cs new file mode 100644 index 00000000..12969cdc --- /dev/null +++ b/PROMS/DotNetBar Source Code/CompositeImage.cs @@ -0,0 +1,262 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Serves as integration of regular Image class and Icon class + /// + internal class CompositeImage : IDisposable + { + private bool m_DisposeImage = false; + + private Image m_Image = null; + private Icon m_Icon = null; + private Size m_ImageSizeOverride = Size.Empty; + private ImageList m_ImageList = null; + private int m_ImageIndex = -1; + + public CompositeImage(int imageIndex, ImageList imageList) + { + m_ImageIndex = imageIndex; + m_ImageList = imageList; + } + + public CompositeImage(Image image, bool dispose) + { + m_Image = image; + m_DisposeImage = dispose; + } + public CompositeImage(Icon icon, bool dispose) + { + m_Icon = icon; + m_DisposeImage = dispose; + } + public CompositeImage(Image image, bool dispose, Size overrideSize) + { + m_Image = image; + m_DisposeImage = dispose; + m_ImageSizeOverride = overrideSize; + } + public CompositeImage(Icon icon, bool dispose, Size overrideSize) + { + m_Icon = icon; + m_DisposeImage = dispose; + m_ImageSizeOverride = overrideSize; + } + ~CompositeImage() // destructor + { + if (m_DisposeImage && (m_Image != null || m_Icon != null)) + { + Dispose(); + } + } + + public void Dispose() + { + if (m_DisposeImage) + { + if (m_Image != null) + m_Image.Dispose(); + if (m_Icon != null) + m_Icon.Dispose(); + } + + m_Image = null; + m_Icon = null; + } + + public void DrawImage(Graphics g, Rectangle rect) + { + if (m_Image != null) + g.DrawImage(m_Image, rect); + else if (m_Icon != null) + DrawIcon(g, rect); + else if (m_ImageIndex >= 0 && m_ImageList != null && m_ImageIndex < m_ImageList.Images.Count) + m_ImageList.Draw(g, rect.X, rect.Y, rect.Width, rect.Height, m_ImageIndex); + } + + private void DrawIcon(Graphics g, Rectangle rect) + { + if (System.Environment.Version.Build <= 3705 && System.Environment.Version.Revision == 288 && System.Environment.Version.Major == 1 && System.Environment.Version.Minor == 0) + { + if (g.ClipBounds.IntersectsWith(rect) && rect.Width > 0 && rect.Height > 0 && m_Icon.Handle != IntPtr.Zero) + { + IntPtr hdc = g.GetHdc(); + try + { + NativeFunctions.DrawIconEx(hdc, rect.X, rect.Y, m_Icon.Handle, rect.Width, rect.Height, 0, IntPtr.Zero, 3); + } + finally + { + g.ReleaseHdc(hdc); + } + } + } + else if (rect.Width > 0 && rect.Height > 0 && m_Icon.Handle != IntPtr.Zero) + { + try + { + g.DrawIcon(m_Icon, rect); + } + catch { } + } + } + + public void DrawImage(Graphics g, Rectangle destRect, int srcX, int srcY, int srcWidth, int srcHeight, GraphicsUnit srcUnit, System.Drawing.Imaging.ImageAttributes imageAttrs) + { + if (m_Image != null) + { + g.DrawImage(m_Image, destRect, srcX, srcY, srcWidth, srcHeight, srcUnit, imageAttrs); + } + else if (m_Icon != null) + { + // Attempt to solve issues with icon drawing... + //DrawIcon(g,destRect); + Bitmap bmp = new Bitmap(this.Width, this.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + bmp.MakeTransparent(); + Graphics gBmp = Graphics.FromImage(bmp); + gBmp.DrawIcon(m_Icon, 0, 0); + gBmp.Dispose(); + g.DrawImage(bmp, destRect, srcX, srcY, srcWidth, srcHeight, srcUnit, imageAttrs); + bmp.Dispose(); + } + else if (m_ImageIndex >= 0 && m_ImageList != null && m_ImageIndex < m_ImageList.Images.Count) + m_ImageList.Draw(g, srcX, srcY, srcWidth, srcHeight, m_ImageIndex); + } + + public bool IsIcon + { + get { return (m_Icon != null); } + } + + public int Width + { + get + { + if (!m_ImageSizeOverride.IsEmpty) + return GetSize(m_ImageSizeOverride.Width); + if (m_Image != null) + return GetSize(m_Image.Width); + if (m_Icon != null) + return GetSize(m_Icon.Width); + if (m_ImageIndex >= 0 && m_ImageList != null) + return GetSize(m_ImageList.ImageSize.Width); + return 0; + } + } + + public int Height + { + get + { + if (!m_ImageSizeOverride.IsEmpty) + return GetSize(m_ImageSizeOverride.Height); + if (m_Image != null) + return GetSize(m_Image.Height); + if (m_Icon != null) + return GetSize(m_Icon.Height); + if (m_ImageIndex >= 0 && m_ImageList != null) + return GetSize(m_ImageList.ImageSize.Height); + return 0; + } + } + + private int GetSize(int height) + { + return (Dpi.AutoScaleImages ? Dpi.Height(height) : height); + } + private Size GetSize(Size size) + { + return (Dpi.AutoScaleImages ? Dpi.Size(size) : size); + } + + public System.Drawing.Size Size + { + get + { + if (!m_ImageSizeOverride.IsEmpty) + return GetSize(m_ImageSizeOverride); + if (m_Image != null) + return GetSize(m_Image.Size); + if (m_Icon != null) + return GetSize(m_Icon.Size); + if (m_ImageIndex >= 0 && m_ImageList != null) + return GetSize(m_ImageList.ImageSize); + return System.Drawing.Size.Empty; + } + } + + public System.Drawing.Image Image + { + get + { + if (m_ImageIndex >= 0 && m_ImageList != null) + return m_ImageList.Images[m_ImageIndex]; + return m_Image; + } + } + + public System.Drawing.Icon Icon + { + get { return m_Icon; } + } + + internal int RealHeight + { + get + { + if (m_Image != null) + return GetSize(m_Image.Height); + if (m_Icon != null) + return GetSize(m_Icon.Height); + if (m_ImageIndex >= 0 && m_ImageList != null) + return GetSize(m_ImageList.ImageSize.Height); + return 0; + } + } + + internal int RealWidth + { + get + { + if (m_Image != null) + return GetSize(m_Image.Width); + if (m_Icon != null) + return GetSize(m_Icon.Width); + if (m_ImageIndex >= 0 && m_ImageList != null) + return GetSize(m_ImageList.ImageSize.Width); + return 0; + } + } + + internal int ActualHeight + { + get + { + if (m_Image != null) + return m_Image.Height; + if (m_Icon != null) + return m_Icon.Height; + if (m_ImageIndex >= 0 && m_ImageList != null) + return m_ImageList.ImageSize.Height; + return 0; + } + } + + internal int ActualWidth + { + get + { + if (m_Image != null) + return (m_Image.Width); + if (m_Icon != null) + return (m_Icon.Width); + if (m_ImageIndex >= 0 && m_ImageList != null) + return (m_ImageList.ImageSize.Width); + return 0; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/ContainerKeyboardNavigation.cs b/PROMS/DotNetBar Source Code/ContainerKeyboardNavigation.cs new file mode 100644 index 00000000..1f89a151 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContainerKeyboardNavigation.cs @@ -0,0 +1,206 @@ +using System; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + internal class ContainerKeyboardNavigation + { + internal static void ProcessKeyDown(BaseItem container, System.Windows.Forms.KeyEventArgs objArg) + { + if (container.SubItems.Count == 0 || objArg.Handled) + return; + + BaseItem objExpanded = container.ExpandedItem(); + + if (objExpanded != null) + { + objExpanded.InternalKeyDown(objArg); + if (objArg.Handled) + return; + } + + eOrientation containerOrientation = container.Orientation; + if (container is ItemContainer) + containerOrientation = ((ItemContainer)container).LayoutOrientation; + + if (containerOrientation == eOrientation.Horizontal && (objArg.KeyCode == Keys.Left || objArg.KeyCode == Keys.Right || container.HotSubItem == null && (objArg.KeyCode == Keys.Down || objArg.KeyCode == Keys.Up)) || + (containerOrientation == eOrientation.Vertical && (objArg.KeyCode == Keys.Up || objArg.KeyCode == Keys.Down || container.HotSubItem == null && (objArg.KeyCode == Keys.Right || objArg.KeyCode == Keys.Left)))) + { + // Select next object + if (container.HotSubItem != null) + { + container.HotSubItem.InternalMouseLeave(); + if (container.AutoExpand && container.HotSubItem.Expanded) + { + container.HotSubItem.Expanded = false; + } + } + if (objArg.KeyCode == System.Windows.Forms.Keys.Left || objArg.KeyCode == Keys.Up) + { + int iIndex = 0; + if (container.HotSubItem != null) + iIndex = container.SubItems.IndexOf(container.HotSubItem) - 1; + if (iIndex < 0) + iIndex = container.SubItems.Count - 1; + BaseItem objNew = null; + bool bRepeat = false; + do + { + for (int i = iIndex; i >= 0; i--) + { + objNew = container.SubItems[i]; + if (CanFocus(objNew)) + { + iIndex = i; + break; + } + } + if (!CanFocus(container.SubItems[iIndex])) + { + if (!bRepeat) + { + iIndex = container.SubItems.Count - 1; + bRepeat = true; + } + else + bRepeat = false; + } + else + bRepeat = false; + } while (bRepeat); + container.HotSubItem = container.SubItems[iIndex]; + } + else + { + int iIndex = 0; + if (container.HotSubItem != null) + iIndex = container.SubItems.IndexOf(container.HotSubItem) + 1; + + while (iIndex < container.SubItems.Count && !CanFocus(container.SubItems[iIndex])) + iIndex++; + if (iIndex >= container.SubItems.Count) + iIndex = 0; + BaseItem objNew = null; + for (int i = iIndex; i < container.SubItems.Count; i++) + { + objNew = container.SubItems[i]; + if (CanFocus(objNew)) + { + iIndex = i; + break; + } + } + container.HotSubItem = container.SubItems[iIndex]; + } + + if (container.HotSubItem != null) + { + if (container.HotSubItem is ItemContainer) + { + ((ItemContainer)container.HotSubItem).SelectFirstItem(); + } + else + { + container.HotSubItem.InternalMouseEnter(); + container.HotSubItem.InternalMouseMove(new MouseEventArgs(MouseButtons.None, 0, container.HotSubItem.LeftInternal + 1, container.HotSubItem.TopInternal + 1, 0)); + IScrollableItemControl isc = container.ContainerControl as IScrollableItemControl; + if (isc != null) + isc.KeyboardItemSelected(container.HotSubItem); + } + } + + objArg.Handled = true; + } + else if (objArg.KeyCode == System.Windows.Forms.Keys.Escape) + { + if (objExpanded != null) + { + objExpanded.Expanded = false; + objArg.Handled = true; + } + else + { + Control cc = container.ContainerControl as Control; + if (cc is Bar) + { + Bar bar = cc as Bar; + if (bar.BarState == eBarState.Popup) + { + bar.ParentItem.Expanded = false; + } + else + { + if (container.AutoExpand) + container.AutoExpand = false; + else if (bar.Focused || bar.MenuFocus) + { + bar.MenuFocus = false; + bar.ReleaseFocus(); + } + } + objArg.Handled = true; + } + else if (cc is ItemControl) + { + ItemControl ic = cc as ItemControl; + if (container.AutoExpand) + container.AutoExpand = false; + else if (ic.Focused || ic.MenuFocus) + { + ic.MenuFocus = false; + ic.ReleaseFocus(); + } + } + } + } + else + { + BaseItem objItem = container.ExpandedItem(); + if (objItem != null) + objItem.InternalKeyDown(objArg); + else + { + int key = 0; + if (objArg.Shift) + { + try + { + byte[] keyState = new byte[256]; + if (NativeFunctions.GetKeyboardState(keyState)) + { + byte[] chars = new byte[2]; + if (NativeFunctions.ToAscii((uint)objArg.KeyValue, 0, keyState, chars, 0) != 0) + { + key = chars[0]; + } + } + } + catch (Exception) + { + key = 0; + } + } + + if (key == 0) + key = (int)NativeFunctions.MapVirtualKey((uint)objArg.KeyValue, 2); + + if (container.HotSubItem != null) + container.HotSubItem.InternalKeyDown(objArg); + } + } + } + + private static bool CanFocus(BaseItem objNew) + { + if (objNew == null) return false; + if (!objNew.Visible || !objNew.GetEnabled() || objNew is ListBoxItem && ((ListBoxItem)objNew).IsSelected) + return false; + + if (objNew is LabelItem) + return false; + + return true; + } + } +} diff --git a/PROMS/DotNetBar Source Code/ContentManager/BlockLayoutManager.cs b/PROMS/DotNetBar Source Code/ContentManager/BlockLayoutManager.cs new file mode 100644 index 00000000..c828e842 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContentManager/BlockLayoutManager.cs @@ -0,0 +1,46 @@ +using System.Collections; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + /// + /// Represents block layout manager responsible for sizing the content blocks. + /// + public abstract class BlockLayoutManager + { + private Graphics m_Graphics; + + /// + /// Resizes the content block and sets it's Bounds property to reflect new size. + /// + /// Content block to resize. + /// Content size available for the block in the given line. + public abstract void Layout(IBlock block, Size availableSize); + + /// + /// Performs layout finalization + /// + /// + /// + /// + /// + public abstract Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines); + + /// + /// Gets or sets the graphics object used by layout manager. + /// + public System.Drawing.Graphics Graphics + { + get {return m_Graphics;} + set {m_Graphics=value;} + } + } +} diff --git a/PROMS/DotNetBar Source Code/ContentManager/Enums.cs b/PROMS/DotNetBar Source Code/ContentManager/Enums.cs new file mode 100644 index 00000000..e61ff8a7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContentManager/Enums.cs @@ -0,0 +1,66 @@ +using System; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Specifies orientation of content. + /// + public enum eContentOrientation + { + /// + /// Indicates Horizontal orientation of the content. + /// + Horizontal, + /// + /// Indicates Vertical orientation of the content. + /// + Vertical + } + + /// + /// Specifies content horizontal alignment. + /// + public enum eContentAlignment + { + /// + /// Content is left aligned.UI + /// + Left, + /// + /// Content is right aligned. + /// + Right, + /// + /// Content is centered. + /// + Center + } + + /// + /// Specifies content vertical alignment. + /// + public enum eContentVerticalAlignment + { + /// + /// Content is top aligned. + /// + Top, + /// + /// Content is bottom aligned. + /// + Bottom, + /// + /// Content is in the middle. + /// + Middle + } +} diff --git a/PROMS/DotNetBar Source Code/ContentManager/IBlock.cs b/PROMS/DotNetBar Source Code/ContentManager/IBlock.cs new file mode 100644 index 00000000..a321c68d --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContentManager/IBlock.cs @@ -0,0 +1,34 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Represents a content block interface. + /// + public interface IBlock + { + /// + /// Gets or sets the bounds of the content block. + /// + Rectangle Bounds {get;set;} + /// + /// Gets or sets whether content block is visible. + /// + bool Visible {get;set;} + /// + /// Gets or sets the block margins. + /// + DevComponents.DotNetBar.Padding Margin { get;set;} + } +} diff --git a/PROMS/DotNetBar Source Code/ContentManager/IBlockExtended.cs b/PROMS/DotNetBar Source Code/ContentManager/IBlockExtended.cs new file mode 100644 index 00000000..a263b22b --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContentManager/IBlockExtended.cs @@ -0,0 +1,28 @@ +using System; +using System.Text; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Represents a extended content block interface for advanced layout information. + /// + public interface IBlockExtended : IBlock + { + bool IsBlockElement { get;} + bool IsNewLineAfterElement { get;} + bool CanStartNewLine { get; } + /// + /// Returns whether element is an container so it receives full available size of parent control for layout. + /// + bool IsBlockContainer { get; } + } +} diff --git a/PROMS/DotNetBar Source Code/ContentManager/IContentLayoutManager.cs b/PROMS/DotNetBar Source Code/ContentManager/IContentLayoutManager.cs new file mode 100644 index 00000000..d9426e1b --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContentManager/IContentLayoutManager.cs @@ -0,0 +1,29 @@ +using System; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Represents interface for block layout. + /// + public interface IContentLayout + { + /// + /// Performs layout of the content block. + /// + /// Container bounds to layout content blocks in. + /// Content blocks to layout. + /// Block layout manager that resizes the content blocks. + /// The bounds of the content blocks within the container bounds. + Rectangle Layout(Rectangle containerBounds, IBlock[] contentBlocks, BlockLayoutManager blockLayout); + } +} diff --git a/PROMS/DotNetBar Source Code/ContentManager/SerialContentLayoutManager.cs b/PROMS/DotNetBar Source Code/ContentManager/SerialContentLayoutManager.cs new file mode 100644 index 00000000..31bb509f --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContentManager/SerialContentLayoutManager.cs @@ -0,0 +1,742 @@ +using System; +using System.Collections; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Represents the serial content layout manager that arranges content blocks in series next to each other. + /// + public class SerialContentLayoutManager:IContentLayout + { + #region Events + /// + /// Occurs when X, Y position of next block is calcualted. + /// + public event LayoutManagerPositionEventHandler NextPosition; + + /// + /// Occurs before new block is layed out. + /// + 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 bool m_HorizontalFitContainerHeight = 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; + private bool m_OversizeDistribute = false; + #endregion + + /// + /// Creates new instance of the class. + /// + public SerialContentLayoutManager() + { + } + + #region IContentLayout Members + /// + /// Performs layout of the content block. + /// + /// Container bounds to layout content blocks in. + /// Content blocks to layout. + /// Block layout manager that resizes the content blocks. + /// The bounds of the content blocks within the container bounds. + 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; + bool canStartOnNewLine = true; + int visibleIndex = 0; + bool callLayout = true; + + if (_EqualItemSize) + { + Size largestItemSize = Size.Empty; + 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; + blockLayout.Layout(block, availableSize); + if (block.Bounds.Width > largestItemSize.Width) + largestItemSize.Width = block.Bounds.Width; + if (block.Bounds.Height > largestItemSize.Height) + largestItemSize.Height = block.Bounds.Height; + } + + foreach (IBlock block in contentBlocks) + { + if (!block.Visible) + continue; + block.Bounds=new Rectangle(block.Bounds.Location, largestItemSize); + + } + callLayout = false; + } + + 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; + bool isContainer = false; + if (block is IBlockExtended) + { + IBlockExtended ex = block as IBlockExtended; + isBlockElement = ex.IsBlockElement; + isNewLineTriggger = ex.IsNewLineAfterElement; + canStartOnNewLine = ex.CanStartNewLine; + isContainer = ex.IsBlockContainer; + } + else + canStartOnNewLine = true; + + if (!isBlockElement && !isContainer) + { + if (m_ContentOrientation == eContentOrientation.Horizontal) + availableSize.Width = (containerBounds.Right - position.X); + else + availableSize.Height = (containerBounds.Bottom - position.Y); + } + + // Resize the content block + if(callLayout) + blockLayout.Layout(block, availableSize); + + if(m_MultiLine && currentLine.Blocks.Count > 0) + { + if (m_ContentOrientation == eContentOrientation.Horizontal && (position.X + block.Bounds.Width > containerBounds.Right && canStartOnNewLine || 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 && canStartOnNewLine || 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); + if (block.Visible) currentLine.VisibleItemsCount++; + Rectangle r = new Rectangle(position, block.Bounds.Size); + r.X += block.Margin.Left; + r.Y += block.Margin.Top; + block.Bounds = r; + + if (blocksBounds.IsEmpty) + { + r = block.Bounds; // Make sure that blocks bounds take in account any margin + r.X -= block.Margin.Left; + r.Y -= block.Margin.Top; + r.Width += block.Margin.Horizontal; + r.Height += block.Margin.Vertical; + blocksBounds = r; + } + else + blocksBounds = Rectangle.Union(blocksBounds, block.Bounds); + + switchToNewLine = isBlockElement | isNewLineTriggger; + + position = GetNextPosition(block, position, ref switchToNewLine); + } + + blocksBounds=AlignResizeBlocks(containerBounds, blocksBounds, lines); + + if (m_RightToLeft) + blocksBounds = MirrorContent(containerBounds, blocksBounds, contentBlocks); + + blocksBounds = blockLayout.FinalizeLayout(containerBounds, blocksBounds, lines); + + return blocksBounds; + } + + #endregion + + #region Internals + private struct SizeExtended + { + public int Width; + public int Height; + public float WidthReduction; + public float HeightReduction; + public bool UseAbsoluteWidth; + } + + 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; + + //Reverting to EventHeight property check so the buttons on RibbonBar are properly stretched so they consume same height. + // Be very careful when changing this code! + if (m_ContentAlignment == eContentAlignment.Left && m_ContentVerticalAlignment == eContentVerticalAlignment.Top && + !m_FitContainer && !m_FitContainerOversize && !m_EvenHeight && m_BlockLineAlignment == eContentVerticalAlignment.Top && + (!(m_ContentOrientation == eContentOrientation.Vertical && (m_VerticalFitContainerWidth || m_EvenHeight)) || m_MultiLine)) + return blocksBounds; + + Point[] offset=new Point[lines.Count]; + SizeExtended[] sizeOffset = new SizeExtended[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) + { + if (m_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width * .75) + { + sizeOffset[lineInfo.Line].Width = (int)Math.Floor((float)(containerBounds.Width - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.VisibleItemsCount); + sizeOffset[lineInfo.Line].UseAbsoluteWidth = true; + } + else + sizeOffset[lineInfo.Line].Width = ((containerBounds.Width - lineInfo.VisibleItemsCount * m_BlockSpacing) - lineInfo.LineSize.Width) / lineInfo.VisibleItemsCount; + sizeOffset[lineInfo.Line].WidthReduction = (float)(containerBounds.Width - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.LineSize.Width; + blocksBounds.Width=containerBounds.Width; + } + + if (m_HorizontalFitContainerHeight && containerBounds.Height > blocksBounds.Height && lines.Count == 1) + sizeOffset[lineInfo.Line].Height = (containerBounds.Height - lineInfo.LineSize.Height) / lines.Count; + } + else + { + if(m_FitContainer && containerBounds.Height>lineInfo.LineSize.Height || + m_FitContainerOversize && lineInfo.LineSize.Height>containerBounds.Height) + { + if (m_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width * .75) + { + sizeOffset[lineInfo.Line].Height = (int)Math.Floor((float)(containerBounds.Height - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.VisibleItemsCount); + sizeOffset[lineInfo.Line].UseAbsoluteWidth = true; + } + else + sizeOffset[lineInfo.Line].Height = ((containerBounds.Height - lineInfo.VisibleItemsCount * m_BlockSpacing) - lineInfo.LineSize.Height) / lineInfo.VisibleItemsCount; + sizeOffset[lineInfo.Line].HeightReduction = (float)(containerBounds.Height - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.LineSize.Height; + blocksBounds.Height=containerBounds.Height; + } + + if (m_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width && lines.Count==1) + 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: + if (containerBounds.Width > lineInfo.LineSize.Width) + offset[lineInfo.Line].X = containerBounds.Width - lineInfo.LineSize.Width; + break; + case eContentAlignment.Center: + if (containerBounds.Width > lineInfo.LineSize.Width) + 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: + if (containerBounds.Height > lineInfo.LineSize.Height) + offset[lineInfo.Line].Y = containerBounds.Height - lineInfo.LineSize.Height; + break; + case eContentVerticalAlignment.Middle: + if (containerBounds.Height > lineInfo.LineSize.Height) + offset[lineInfo.Line].Y = (containerBounds.Height - lineInfo.LineSize.Height) / 2; + break; + } + } + } + } + + if (m_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width && m_ContentOrientation==eContentOrientation.Vertical) + blocksBounds.Width = containerBounds.Width; + else if(m_HorizontalFitContainerHeight && containerBounds.Height>blocksBounds.Height && m_ContentOrientation==eContentOrientation.Horizontal) + blocksBounds.Height = containerBounds.Height; + + 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) + { + if (m_OversizeDistribute) + { + int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth ? sizeOffset[lineInfo.Line].Width : (int)Math.Floor(r.Width * sizeOffset[lineInfo.Line].WidthReduction); + offset[lineInfo.Line].X += nw - r.Width; + r.Width = nw; + } + else + { + 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 (!m_OversizeDistribute && 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; + } + if (!m_FitContainer && m_ContentAlignment != eContentAlignment.Left && _ReserveLeftSpace) + { + // For block elements they should consume the space available to the left otherwise + // the parent is not aware that the space has been consumed + newBounds.Width += (newBounds.X - containerBounds.X); + newBounds.X = containerBounds.X; + } + } + } + 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 - block.Margin.Horizontal; + 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) + { + if (m_OversizeDistribute) + { + int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth ? sizeOffset[lineInfo.Line].Height : (int)Math.Floor(r.Height * sizeOffset[lineInfo.Line].HeightReduction); + offset[lineInfo.Line].Y += nw - r.Height; + r.Height = nw; + } + else + { + r.Height += sizeOffset[lineInfo.Line].Height; + offset[lineInfo.Line].Y += sizeOffset[lineInfo.Line].Height; + } + } + block.Bounds=r; + if (newBounds.IsEmpty) + { + r.Y -= block.Margin.Top; // Account for any margin set on first element + r.X -= block.Margin.Left; + r.Width += block.Margin.Horizontal; + r.Height += block.Margin.Vertical; + newBounds = r; + } + else + newBounds = Rectangle.Union(newBounds, block.Bounds); + } + if (!m_OversizeDistribute && 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, ref bool switchToNewLine) + { + if (NextPosition != null) + { + LayoutManagerPositionEventArgs e = new LayoutManagerPositionEventArgs(); + + e.Block = block; + e.CurrentPosition = position; + e.SwitchToNewLine = switchToNewLine; + + NextPosition(this, e); + + switchToNewLine = e.SwitchToNewLine; + + if (e.Cancel) + return e.NextPosition; + } + + if (m_ContentOrientation == eContentOrientation.Horizontal) + position.X += block.Bounds.Width + m_BlockSpacing + block.Margin.Horizontal; + else + position.Y += block.Bounds.Height + m_BlockSpacing + block.Margin.Vertical; + + return position; + } + + internal class BlockLineInfo + { + public BlockLineInfo() {} + public ArrayList Blocks=new ArrayList(); + public Size LineSize=Size.Empty; + public int Line=0; + public int VisibleItemsCount = 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 + + private bool _ReserveLeftSpace = false; + + /// + /// Indicates whether space to the left of center and right aligned blocks is blocked out by stretching the block so it consumes that space. + /// + public bool ReserveLeftSpace + { + get { return _ReserveLeftSpace; } + set { _ReserveLeftSpace = value; } + } + + /// + /// Gets or sets the spacing in pixels between content blocks. Default value is 0. + /// + public virtual int BlockSpacing + { + get {return m_BlockSpacing;} + set {m_BlockSpacing=value;} + } + + /// + /// 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. + /// + public virtual bool FitContainerOversize + { + get {return m_FitContainerOversize;} + set {m_FitContainerOversize=value;} + } + + /// + /// 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. + /// + public virtual bool FitContainer + { + get {return m_FitContainer;} + set {m_FitContainer=value;} + } + + /// + /// 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. + /// + public virtual bool VerticalFitContainerWidth + { + get { return m_VerticalFitContainerWidth; } + set { m_VerticalFitContainerWidth = value; } + } + + /// + /// Gets or sets whether content blocks are resized (Height) to fit container bounds if they + /// occupy less space than the actual container height. Applies to the Horizontal orientation only. Default value is false. + /// + public virtual bool HorizontalFitContainerHeight + { + get { return m_HorizontalFitContainerHeight; } + set { m_HorizontalFitContainerHeight = value; } + } + + /// + /// Gets or sets the content orientation. Default value is Horizontal. + /// + public virtual eContentOrientation ContentOrientation + { + get {return m_ContentOrientation;} + set {m_ContentOrientation=value;} + } + + /// + /// Gets or sets the content vertical alignment. Default value is Middle. + /// + public virtual eContentVerticalAlignment ContentVerticalAlignment + { + get {return m_ContentVerticalAlignment;} + set {m_ContentVerticalAlignment=value;} + } + + /// + /// Gets or sets the block line vertical alignment. Default value is Middle. + /// + public virtual eContentVerticalAlignment BlockLineAlignment + { + get { return m_BlockLineAlignment; } + set { m_BlockLineAlignment = value; } + } + + /// + /// Gets or sets the content horizontal alignment. Default value is Left. + /// + public virtual eContentAlignment ContentAlignment + { + get {return m_ContentAlignment;} + set {m_ContentAlignment=value;} + } + + /// + /// Gets or sets whether all content blocks are resized so they have same height which is height of the tallest content block. Default value is false. + /// + public virtual bool EvenHeight + { + get {return m_EvenHeight;} + set {m_EvenHeight=value;} + } + + /// + /// Gets or sets whether oversized blocks are resized based on the percentage reduction instead of based on equal pixel distribution. Default value is false. + /// + public virtual bool OversizeDistribute + { + get { return m_OversizeDistribute; } + set { m_OversizeDistribute = value; } + } + + /// + /// Gets or sets whether content is wrapped into new line if it exceeds the width of the container. + /// + public bool MultiLine + { + get {return m_MultiLine;} + set {m_MultiLine=value;} + } + + /// + /// Gets or sets whether layout is right-to-left. + /// + public bool RightToLeft + { + get { return m_RightToLeft; } + set { m_RightToLeft = value; } + } + + private bool _EqualItemSize = false; + + /// + /// Gets or sets whether all items are equaly sized based on the size of the largest item in the list. + /// + public bool EqualItemSize + { + get { return _EqualItemSize; } + set { _EqualItemSize = value; } + } + + #endregion + } + + /// + /// Represents event arguments for SerialContentLayoutManager.NextPosition event. + /// + public class LayoutManagerPositionEventArgs : EventArgs + { + /// + /// Gets or sets the block that is layed out. + /// + public IBlock Block = null; + /// + /// Gets or sets the current block position. + /// + public Point CurrentPosition = Point.Empty; + /// + /// Gets or sets the calculated next block position. + /// + public Point NextPosition = Point.Empty; + /// + /// Cancels default position calculation. + /// + public bool Cancel = false; + + public bool SwitchToNewLine; + } + + /// + /// Represents event arguments for the SerialContentLayoutManager layout events. + /// + public class LayoutManagerLayoutEventArgs : EventArgs + { + /// + /// Gets or sets the reference block object. + /// + public IBlock Block = null; + + /// + /// Gets or sets the position block will assume. + /// + public Point CurrentPosition = Point.Empty; + + /// + /// Cancel the layout of the block, applies only to BeforeXXX layout event. + /// + public bool CancelLayout = false; + + /// + /// Gets or sets the visibility index of the block. + /// + public int BlockVisibleIndex = 0; + + /// + /// Creates new instance of the class and initializes it with default values. + /// + public LayoutManagerLayoutEventArgs(IBlock block, Point currentPosition, int visibleIndex) + { + this.Block = block; + this.CurrentPosition = currentPosition; + this.BlockVisibleIndex = visibleIndex; + } + } + + /// + /// Delegate for SerialContentLayoutManager.NextPosition event. + /// + public delegate void LayoutManagerPositionEventHandler(object sender, LayoutManagerPositionEventArgs e); + + /// + /// Delegate for the SerialContentLayoutManager layout events. + /// + public delegate void LayoutManagerLayoutEventHandler(object sender, LayoutManagerLayoutEventArgs e); + + +} diff --git a/PROMS/DotNetBar Source Code/ContextExMenuTypeEditor.cs b/PROMS/DotNetBar Source Code/ContextExMenuTypeEditor.cs new file mode 100644 index 00000000..fe761086 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContextExMenuTypeEditor.cs @@ -0,0 +1,89 @@ +using System; +using System.ComponentModel; +using System.Collections; +using System.Diagnostics; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using System.Drawing.Design; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for ContextExMenuTypeEditor. + /// + public class ContextExMenuTypeEditor : System.Drawing.Design.UITypeEditor + { + private IWindowsFormsEditorService edSvc = null; + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + if (context != null + && context.Instance != null + && provider != null) + { + edSvc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + ContextMenuBar cb = null; + GridItem pg = provider as GridItem; + string propLabel = ""; + if (pg != null) + propLabel = pg.Label; + + foreach (IComponent c in context.Container.Components) + { + if (c is ContextMenuBar) + { + if(propLabel.EndsWith(((ContextMenuBar)c).Name) || propLabel=="") + { + cb = c as ContextMenuBar; + break; + } + } + } + + BaseItem selectedItem=null; + if(value!=null && value is BaseItem) + selectedItem = (BaseItem)value; + if(cb!=null && edSvc!=null) + { + ListBox lb=new ListBox(); + lb.SelectedIndexChanged+=new EventHandler(this.SelectedChanged); + foreach(BaseItem item in cb.Items) + { + if(item.Name!="") + { + int i=lb.Items.Add(item.Name); + if (item == selectedItem) + lb.SelectedIndex=i; + } + } + edSvc.DropDownControl(lb); + if(lb.SelectedItem!=null) + return cb.Items[lb.SelectedItem.ToString()]; + } + } + + return value; + } + + private void SelectedChanged(object sender, EventArgs e) + { + if(edSvc!=null) + edSvc.CloseDropDown(); + } + + /// + /// Gets the editor style used by the EditValue method. + /// + /// An ITypeDescriptorContext that can be used to gain additional context information. + /// 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 + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + if (context != null && context.Instance != null) + { + return UITypeEditorEditStyle.DropDown; + } + return base.GetEditStyle(context); + } + + } +} diff --git a/PROMS/DotNetBar Source Code/ContextMenuBar.cs b/PROMS/DotNetBar Source Code/ContextMenuBar.cs new file mode 100644 index 00000000..889f5673 --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContextMenuBar.cs @@ -0,0 +1,387 @@ +using System; +using System.Text; +using System.ComponentModel; +using System.Collections; +using System.Windows.Forms; +using System.Drawing; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the context menu bar that provides the context menus for the System.Windows.Forms.Control inherited controls on the form. + /// + [ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.ContextMenuBarDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), ProvideProperty("ContextMenuEx", typeof(Control)), System.Runtime.InteropServices.ComVisible(false), DefaultEvent("ItemClick")] + public class ContextMenuBar : Bar, System.ComponentModel.IExtenderProvider + { + #region Private Variables + private Hashtable m_ContextExMenus = new Hashtable(); + private Hashtable m_ContextExHandlers = new Hashtable(); + private bool m_ContextMenuSubclass = true; + #endregion + + #region Internal Implementation + public ContextMenuBar() : base() + { + this.Visible = false; + this.WrapItemsDock = true; + this.WrapItemsFloat = true; + } + + protected override bool IsContextPopup(BaseItem popup) + { + if (this.Items.Contains(popup)) return true; + return base.IsContextPopup(popup); + } + #endregion + + #region Property Hiding + /// + /// Gets/Sets whether Bar is visible or not. + /// + [DevCoBrowsable(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool Visible + { + get { return base.Visible; } + set { base.Visible = value; } + } + #endregion + + #region Extender Implementation + // ********************************************************************* + // + // Extended Property ContextMenuEx implementation code + // + // ********************************************************************* + bool IExtenderProvider.CanExtend(object target) + { + if (target is Control) + return true; + return false; + } + + private delegate void WmContextEventHandler(object sender, WmContextEventArgs e); + /// + /// Returns the instance of the BaseItem that is assigned as context menu to the control. + /// + /// Control to return context menu for. + /// Instance of the BaseItem used as context menu for the control. + [DefaultValue(null), Editor(typeof(ContextExMenuTypeEditor), typeof(System.Drawing.Design.UITypeEditor))] + public BaseItem GetContextMenuEx(Control control) + { + if (control is DevComponents.DotNetBar.Controls.RichTextBoxEx) + control = ((DevComponents.DotNetBar.Controls.RichTextBoxEx)control).RichTextBox; + + BaseItem item = (BaseItem)m_ContextExMenus[control]; + return item; + } + /// + /// Assigns the context menu to a control. + /// + /// Control to assign the context menu to. + /// Instance of PopupItem derived class usually ButtonItem to act as context menu for a control. The SubItems collection of the item specified here actually defines the visible context menu items. + public void SetContextMenuEx(Control control, BaseItem value) + { + if (control is DevComponents.DotNetBar.Controls.RichTextBoxEx) + control = ((DevComponents.DotNetBar.Controls.RichTextBoxEx)control).RichTextBox; + if (value == null) + { + if (m_ContextExMenus.Contains(control)) + { + if (m_ContextExHandlers.Contains(control)) + { + ContextMessageHandler h = m_ContextExHandlers[control] as ContextMessageHandler; + if (h != null) + { + h.ContextMenu -= new WmContextEventHandler(this.OnContextMenu); + h.ReleaseHandle(); + h = null; + } + m_ContextExHandlers.Remove(control); + } + + m_ContextExMenus.Remove(control); + control.MouseUp -= new MouseEventHandler(this.ContextExMouseUp); + try + { + control.HandleDestroyed -= new EventHandler(this.ContextExHandleDestroy); + } + catch { } + try + { + control.HandleCreated -= new EventHandler(this.ContextExHandleCreate); + } + catch { } + try { control.MouseUp -= new MouseEventHandler(this.ContextExMouseUp); } + catch { } + } + } + else + { + if (m_ContextExMenus.Contains(control)) + { + m_ContextExMenus[control] = value; + } + else + { + m_ContextExMenus[control] = value; + if (!m_ContextExHandlers.Contains(control) && !this.DesignMode) + { + if (!(control is System.Windows.Forms.TreeView) && !(control is System.Windows.Forms.Form) && + !(control is System.Windows.Forms.Panel +#if FRAMEWORK20 + || control is System.Windows.Forms.DataGridView +#endif + ) && + m_ContextMenuSubclass) + { + if (control.IsHandleCreated) + { + ContextMessageHandler h = new ContextMessageHandler(); + h.ContextMenu += new WmContextEventHandler(this.OnContextMenu); + h.ParentControl = control; + h.AssignHandle(control.Handle); + m_ContextExHandlers[control] = h; + } + control.HandleDestroyed += new EventHandler(this.ContextExHandleDestroy); + control.HandleCreated += new EventHandler(this.ContextExHandleCreate); + } + if (control is ComboBox) + { + ComboBox cbo = control as ComboBox; + cbo.ContextMenu = new ContextMenu(); + } + } + try { control.MouseUp += new MouseEventHandler(this.ContextExMouseUp); } + catch { } + } + } + } + + internal bool HasContextMenu(Control ctrl) + { + return m_ContextExMenus.Contains(ctrl); + } + + private void ContextExHandleDestroy(object sender, EventArgs e) + { + Control control = sender as Control; + if (control == null) + return; + ContextMessageHandler h = m_ContextExHandlers[control] as ContextMessageHandler; + if (h != null) + { + h.ContextMenu -= new WmContextEventHandler(this.OnContextMenu); + h.ReleaseHandle(); + h = null; + } + m_ContextExHandlers.Remove(control); + } + + private void ContextExHandleCreate(object sender, EventArgs e) + { + Control control = sender as Control; + if (control == null) + return; + if (m_ContextExHandlers.Contains(control)) + return; + + ContextMessageHandler h = new ContextMessageHandler(); + h.ContextMenu += new WmContextEventHandler(this.OnContextMenu); + h.ParentControl = control; + h.AssignHandle(control.Handle); + m_ContextExHandlers[control] = h; + } + + private void ContextExMouseUp(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Right) + return; + Control ctrl = sender as Control; + if (ctrl == null) + return; + // Find it in pop-ups + PopupItem popup = GetContextExItem(ctrl) as PopupItem; + if (popup == null) return; + + if (!popup.Expanded) + { + popup.Style = this.Style; + popup.SetSourceControl(ctrl); + popup.Popup(ctrl.PointToScreen(new Point(e.X, e.Y))); + } + } + + private Control FindControl(Control parent, IntPtr handle) + { + foreach (Control ctrl in parent.Controls) + { + if (ctrl.Handle == handle) + return ctrl; + if (ctrl.Controls.Count > 0) + { + Control ret = FindControl(ctrl, handle); + if (ret != null) + return ret; + } + } + return parent; + } + + private BaseItem GetContextExItem(Control ctrl) + { + BaseItem item = (BaseItem)m_ContextExMenus[ctrl]; + return item; + } + private void OnContextMenu(object sender, WmContextEventArgs e) + { + ContextMessageHandler h = sender as ContextMessageHandler; + if (h == null) + return; + + BaseItem contextItem = GetContextExItem(h.ParentControl); + if (contextItem == null) + return; + + // Check whether context menu originated elsewhere in particular a Panel which handles MouseUp + if (e.Handle != e.SourceHandle && e.SourceHandle != IntPtr.Zero) + { + Control ctrl = Control.FromChildHandle(e.Handle); + if (ctrl != null && ctrl is Panel && this.GetContextExItem(ctrl) != null) return; // WM_CONTEXT bubbles up and Panel handles MouseUp + } + + // Find it in pop-ups + PopupItem popup = contextItem as PopupItem; + popup.Style = this.Style; + + if (e.Button == MouseButtons.None) + { + // Get the control with focus + Control ctrl = Control.FromChildHandle(e.Handle); + if (ctrl != null && ctrl.Handle != e.Handle) + { + ctrl = FindControl(ctrl, e.Handle); + } + popup.SetSourceControl(h.ParentControl); + if (ctrl != null) + { + if (ctrl.ClientRectangle.Contains(ctrl.PointToClient(Control.MousePosition))) + popup.Popup(Control.MousePosition); + else + popup.Popup(ctrl.PointToScreen(Point.Empty)); + } + else + popup.Popup(Control.MousePosition); + + // We need to eat the message in OnSysKeyUp for Shift+F10 case + if (this.IgnoreSysKeyUp) + { + this.IgnoreSysKeyUp = false; + this.EatSysKeyUp = true; + } + } + else + { + // This is handled by the WM_RBUTTONUP just eat it + if (!e.WmContext) + { + popup.SetSourceControl(h.ParentControl); + popup.Popup(e.X, e.Y); + } + } + e.Handled = true; + } + private class ContextMessageHandler : NativeWindow + { + public event WmContextEventHandler ContextMenu; + private const int WM_CONTEXTMENU = 0x007B; + private const int WM_RBUTTONUP = 0x0205; + private const int WM_NCRBUTTONUP = 0x00A5; + private const int WM_RBUTTONDOWN = 0x0204; + public Control ParentControl = null; + protected override void WndProc(ref Message m) + { + if (m.Msg == WM_CONTEXTMENU) + { + if (ContextMenu != null) + { + int ilParam = WinApi.ToInt(m.LParam); + int y = ilParam >> 16; + int x = (short)(ilParam & 0xFFFF); + IntPtr hWnd = m.WParam; + if (hWnd == IntPtr.Zero) + hWnd = m.HWnd; + bool context = true; + if (m.HWnd != m.WParam) + context = false; + WmContextEventArgs e = new WmContextEventArgs(hWnd, x, y, ((x == -1 && y == -1) ? MouseButtons.None : MouseButtons.Right), context, m.HWnd); + ContextMenu(this, e); + if (e.Handled) + return; + } + } + // This case was taken out becouse the message was not generated for the listview control and possibly for + // treview control so this code was moved to the MouseUp event of the Control see ContextExMouseUp + // else if(m.Msg==WM_RBUTTONUP || m.Msg==WM_NCRBUTTONUP) + // { + // if(ContextMenu!=null) + // { + // int ilParam=m.LParam.ToInt32(); + // int y=ilParam>>16; + // int x=ilParam & 0xFFFF; + // Point p=ParentControl.PointToScreen(new Point(x,y)); + // WmContextEventArgs e=new WmContextEventArgs(m.HWnd,p.X,p.Y,MouseButtons.Right,false); + // ContextMenu(this,e); + // } + // } + base.WndProc(ref m); + } + } + private class WmContextEventArgs : EventArgs + { + private readonly int x; + private readonly int y; + private readonly MouseButtons button = 0; + private readonly IntPtr hwnd; + private readonly bool wmcontext; + public bool Handled = false; + private IntPtr sourceHandle; + public WmContextEventArgs(IntPtr phwnd, int ix, int iy, MouseButtons eButton, bool WmContextMessage, IntPtr sourceHandle) + { + this.x = ix; + this.y = iy; + this.button = eButton; + this.hwnd = phwnd; + this.wmcontext = WmContextMessage; + this.sourceHandle = sourceHandle; + } + public int X + { + get { return this.x; } + } + public int Y + { + get { return this.y; } + } + public MouseButtons Button + { + get { return this.button; } + } + public IntPtr Handle + { + get { return this.hwnd; } + } + public bool WmContext + { + get { return this.wmcontext; } + } + public IntPtr SourceHandle + { + get + { + return this.sourceHandle; + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/ContextMenusCollection.cs b/PROMS/DotNetBar Source Code/ContextMenusCollection.cs new file mode 100644 index 00000000..1a45552b --- /dev/null +++ b/PROMS/DotNetBar Source Code/ContextMenusCollection.cs @@ -0,0 +1,101 @@ +using System; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for Popups. + /// + public class ContextMenusCollection:System.Collections.CollectionBase + { + private DotNetBarManager m_Owner; + public ContextMenusCollection(DotNetBarManager owner) + { + m_Owner=owner; + } + public int Add(BaseItem item) + { + item.SetOwner(m_Owner); + item.Visible=false; + item.Displayed=false; + return List.Add(item); + } + public BaseItem this[int index] + { + get {return (BaseItem)(List[index]);} + set {List[index] = value;} + } + public BaseItem this[string name] + { + get {return (BaseItem)(List[this.IndexOf(name)]);} + set {List[this.IndexOf(name)] = value;} + } + + public void Insert(int index, BaseItem value) + { + value.Visible=false; + value.Displayed=false; + List.Insert(index, value); + } + + public int IndexOf(BaseItem value) + { + return List.IndexOf(value); + } + + public int IndexOf(string name) + { + int i=-1; + foreach(BaseItem item in List) + { + i++; + if(item.Name==name) + return i; + } + return -1; + } + + public bool Contains(BaseItem value) + { + return List.Contains(value); + } + + public bool Contains(string name) + { + foreach(BaseItem item in List) + { + if(item.Name==name) + return true; + } + return false; + } + + public void Remove(BaseItem value) + { + List.Remove(value); + } + + public void CopyTo(BaseItem[] array, int index) + { + List.CopyTo(array, index); + } + + protected override void OnClear() + { + IOwner owner=m_Owner as IOwner; + if(List.Count>0 && owner!=null) + { + foreach(BaseItem objSub in this) + { + if(owner!=null) + owner.RemoveShortcutsFromItem(objSub); + } + } + base.OnClear(); + } + + internal void SetOwner(DotNetBarManager owner) + { + m_Owner=owner; + } + } +} diff --git a/PROMS/DotNetBar Source Code/ControlContainerItem.cs b/PROMS/DotNetBar Source Code/ControlContainerItem.cs new file mode 100644 index 00000000..5bae8deb --- /dev/null +++ b/PROMS/DotNetBar Source Code/ControlContainerItem.cs @@ -0,0 +1,746 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for ControlContainerItem. + /// + [System.ComponentModel.ToolboxItem(false), System.ComponentModel.DesignTimeVisible(false), Designer("DevComponents.DotNetBar.Design.SimpleBaseItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ControlContainerItem:ImageItem,IPersonalizedMenuItem + { + /// + /// Occurs when container control needs to be assigned to the item. + /// + public event EventHandler ContainerLoadControl; + public delegate void ControlContainerSerializationEventHandler(object sender, ControlContainerSerializationEventArgs e); + public event ControlContainerSerializationEventHandler ContainerControlSerialize; + public event ControlContainerSerializationEventHandler ContainerControlDeserialize; + + // IPersonalizedMenuItem Implementation + private eMenuVisibility m_MenuVisibility=eMenuVisibility.VisibleAlways; + private bool m_RecentlyUsed=false; + private System.Windows.Forms.Control m_Control=null; + private bool m_MouseOver=false; + private bool m_AllowItemResize=true; + + /// + /// Creates new instance of ControlContainerItem and assigns item name. + /// + public ControlContainerItem():this("","") {} + /// + /// Creates new instance of ControlContainerItem and assigns item name. + /// + /// Item name. + public ControlContainerItem(string sName):this(sName,""){} + /// + /// Creates new instance of ControlContainerItem and assigns item name and item text. + /// + /// Item name. + /// Item text. + public ControlContainerItem(string sName, string ItemText):base(sName,ItemText) + { + m_SupportedOrientation=eSupportedOrientation.Horizontal; + } + + internal void InitControl() + { + EventArgs e=new EventArgs(); + if(ContainerLoadControl!=null) + ContainerLoadControl(this,e); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null) + owner.InvokeContainerLoadControl(this,e); + CustomizeChanged(); + } + + /// + /// Overridden. Returns the copy of the ControlContainerItem. + /// + /// Copy of the ControlContainerItem. + public override BaseItem Copy() + { + ControlContainerItem objCopy=new ControlContainerItem(this.Name); + objCopy.AllowItemResize = this.AllowItemResize; + this.CopyToItem(objCopy); + return objCopy; + } + protected override void CopyToItem(BaseItem copy) + { + ControlContainerItem objCopy=copy as ControlContainerItem; + base.CopyToItem(objCopy); + objCopy.ContainerLoadControl=this.ContainerLoadControl; + objCopy.InitControl(); + } + protected override void Dispose(bool disposing) + { + if(m_Control!=null) + { + m_Control.Enter -= new EventHandler(HostedControlEnter); + m_Control.GotFocus -= new EventHandler(HostedControlGotFocus); + m_Control.Resize -= new EventHandler(HostedControlResized); +// if(m_Control.Parent!=null && (!m_Control.Parent.Disposing && !(m_Control.Parent is Bar && ((Bar)m_Control.Parent).IsDisposing))) +// { +// m_Control.Parent.Controls.Remove(m_Control); +// } + m_Control=null; + } + base.Dispose(disposing); + } + protected internal override void Serialize(ItemSerializationContext context) + { + base.Serialize(context); + System.Xml.XmlElement ThisItem = context.ItemXmlElement; + ThisItem.SetAttribute("AllowResize",System.Xml.XmlConvert.ToString(m_AllowItemResize)); + + if(ContainerControlSerialize!=null) + this.ContainerControlSerialize(this,new ControlContainerSerializationEventArgs(ThisItem)); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null) + owner.InvokeContainerControlSerialize(this,new ControlContainerSerializationEventArgs(ThisItem)); + + } + public override void Deserialize(ItemSerializationContext context) + { + base.Deserialize(context); + System.Xml.XmlElement ItemXmlSource = context.ItemXmlElement; + m_AllowItemResize=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("AllowResize")); + InitControl(); + + if(ContainerControlDeserialize!=null) + this.ContainerControlDeserialize(this,new ControlContainerSerializationEventArgs(ItemXmlSource)); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null) + owner.InvokeContainerControlDeserialize(this,new ControlContainerSerializationEventArgs(ItemXmlSource)); + } + + // IPersonalizedMenuItem Impementation + /// + /// Indicates item's visiblity when on pop-up menu. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates item's visiblity when on pop-up menu.")] + public eMenuVisibility MenuVisibility + { + get + { + return m_MenuVisibility; + } + set + { + if(m_MenuVisibility!=value) + { + m_MenuVisibility=value; + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "MenuVisibility"); + } + } + } + /// + /// Indicates whether item was recently used. + /// + [System.ComponentModel.Browsable(false),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public bool RecentlyUsed + { + get + { + return m_RecentlyUsed; + } + set + { + if(m_RecentlyUsed!=value) + { + m_RecentlyUsed=value; + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "RecentlyUsed"); + } + } + } + + /// + /// Gets/Sets informational text (tooltip) for the item. + /// + [System.ComponentModel.Browsable(false),DevCoBrowsable(false),System.ComponentModel.DefaultValue(""),System.ComponentModel.Category("Appearance"),System.ComponentModel.Description("Indicates the text that is displayed when mouse hovers over the item."),System.ComponentModel.Localizable(true)] + public override string Tooltip + { + get + { + + return base.Tooltip; + } + set + { + base.Tooltip=value; + } + } + + /// + /// Gets or sets the reference to the control that is managed by the item. + /// + [Category("Data"), DefaultValue(null), Description("Indicates the control that is managed by the item.")] + public System.Windows.Forms.Control Control + { + get + { + return m_Control; + } + set + { + if(m_Control!=null) + { + if(m_Control.Parent!=null) + m_Control.Parent.Controls.Remove(m_Control); + m_Control.Enter -= new EventHandler(HostedControlEnter); + m_Control.GotFocus -= new EventHandler(HostedControlGotFocus); + m_Control.Resize -= new EventHandler(HostedControlResized); + } + m_Control=value; + if(m_Control!=null) + { + m_Control.Enter += new EventHandler(HostedControlEnter); + m_Control.GotFocus += new EventHandler(HostedControlGotFocus); + m_Control.Resize += new EventHandler(HostedControlResized); + if(m_Control.Parent!=null) + m_Control.Parent.Controls.Remove(m_Control); + m_Control.Dock=System.Windows.Forms.DockStyle.None; + + //if (m_Control is System.Windows.Forms.ListBox) + //{ + // TypeDescriptor.GetProperties(m_Control)["IntegralHeight"].SetValue(m_Control, false); + //} + //if (!(m_Control is ItemControl) && TypeDescriptor.GetProperties(m_Control).Find("AutoSize", true) != null) + // TypeDescriptor.GetProperties(m_Control)["AutoSize"].SetValue(m_Control, false); + + System.Windows.Forms.Control objCtrl=null; + if(this.ContainerControl!=null) + { + objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null) + { + objCtrl.Controls.Add(m_Control); + m_Control.Refresh(); + } + } + if(!this.Displayed) + m_Control.Visible=false; + } + } + } + + void HostedControlResized(object sender, EventArgs e) + { + NeedRecalcSize = true; + if (this.ContainerControl is MenuPanel) + ((MenuPanel)this.ContainerControl).RecalcLayout(); + } + + private void HostedControlGotFocus(object sender, EventArgs e) + { + SetMenuHotSubItem(); + } + + private void SetMenuHotSubItem() + { + if (this.IsOnMenu) + { + MenuPanel panel = this.ContainerControl as MenuPanel; + if (panel != null && panel.HotSubItem != this) + panel.HotSubItem = this; + } + } + private void HostedControlEnter(object sender, EventArgs e) + { + SetMenuHotSubItem(); + } + + /// + /// Overridden. Draws the item. + /// + /// Target Graphics object. + public override void Paint(ItemPaintArgs pa) + { + if(this.SuspendLayout) + return; + + System.Drawing.Graphics g = pa.Graphics; + + if (m_Control != null && m_Control.Visible != this.Displayed && !m_Control.Visible) + CustomizeChanged(); // Determine based on customize status + + Rectangle r = this.DisplayRectangle; + + Size objImageSize = GetMaxImageSize(); + bool bOnMenu = this.IsOnMenu; + if (bOnMenu && this.Parent is ItemContainer) + bOnMenu = false; + + if (this.Orientation == eOrientation.Horizontal) + { + if (bOnMenu && !this.Stretch) + { + objImageSize.Width += 7; + r.Width -= objImageSize.Width; + r.X += objImageSize.Width; + if (this.IsOnCustomizeMenu) + objImageSize.Width += objImageSize.Height + 8; + + // Draw side bar + Rectangle sideRect = new Rectangle(m_Rect.Left, m_Rect.Top, objImageSize.Width, m_Rect.Height); + if (this.MenuVisibility == eMenuVisibility.VisibleIfRecentlyUsed && !this.RecentlyUsed) + { + if (!pa.Colors.MenuUnusedSide2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(sideRect, pa.Colors.MenuUnusedSide, pa.Colors.MenuUnusedSide2, pa.Colors.MenuUnusedSideGradientAngle); + g.FillRectangle(gradient, sideRect); + gradient.Dispose(); + } + else + g.FillRectangle(new SolidBrush(pa.Colors.MenuUnusedSide), sideRect); + } + else + { + if (!pa.Colors.MenuSide2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient = BarFunctions.CreateLinearGradientBrush(sideRect, pa.Colors.MenuSide, pa.Colors.MenuSide2, pa.Colors.MenuSideGradientAngle); + g.FillRectangle(gradient, sideRect); + gradient.Dispose(); + } + else + g.FillRectangle(new SolidBrush(pa.Colors.MenuSide), sideRect); + } + if (BarFunctions.IsOffice2007Style(EffectiveStyle) && GlobalManager.Renderer is Office2007Renderer) + { + Office2007MenuColorTable mt = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.Menu; + if (mt != null && !mt.SideBorder.IsEmpty) + { + if (pa.RightToLeft) + DisplayHelp.DrawGradientLine(g, sideRect.X + 1, sideRect.Y, sideRect.X + 1, sideRect.Bottom - 1, mt.SideBorder, 1); + else + DisplayHelp.DrawGradientLine(g, sideRect.Right - 2, sideRect.Y, sideRect.Right - 2, sideRect.Bottom - 1, mt.SideBorder, 1); + } + if (mt != null && !mt.SideBorderLight.IsEmpty) + { + if (pa.RightToLeft) + DisplayHelp.DrawGradientLine(g, sideRect.X, sideRect.Y, sideRect.X, sideRect.Bottom - 1, mt.SideBorder, 1); + else + DisplayHelp.DrawGradientLine(g, sideRect.Right - 1, sideRect.Y, sideRect.Right - 1, sideRect.Bottom - 1, mt.SideBorderLight, 1); + } + } + } + + if(this.IsOnCustomizeMenu) + { + if (EffectiveStyle != eDotNetBarStyle.Office2000) + { + r.X+=(objImageSize.Height+8); + r.Width-=(objImageSize.Height+8); + } + else + { + r.X+=(objImageSize.Height+4); + r.Width-=(objImageSize.Height+4); + } + } + + if (bOnMenu && EffectiveStyle != eDotNetBarStyle.Office2000) + { + //g.FillRectangle(new SolidBrush(pa.Colors.MenuBackground),r); + } + //else if(this.Style==eDotNetBarStyle.OfficeXP && !this.IsOnMenuBar) + // g.FillRectangle(new SolidBrush(ColorFunctions.ToolMenuFocusBackColor(g)),this.DisplayRectangle); + //else + // g.FillRectangle(SystemBrushes.Control,this.DisplayRectangle); + + // Draw text if needed + if (m_Control == null || this.GetDesignMode() || this.IsOnCustomizeMenu) + { + string text=m_Text; + if(text=="") + text="Container"; + eTextFormat objStringFormat=GetStringFormat(); + Font objFont=this.GetFont(); + Rectangle rText=new Rectangle(r.X+8,r.Y,r.Width,r.Height); + if (EffectiveStyle == eDotNetBarStyle.Office2000) + { + TextDrawing.DrawString(g, text, objFont, SystemColors.ControlText, rText, objStringFormat); + } + else + { + TextDrawing.DrawString(g, text, objFont, SystemColors.ControlText, rText, objStringFormat); + } + Size textSize = TextDrawing.MeasureString(g, text, objFont, 0, objStringFormat); + r.X += (int)textSize.Width + 8; + r.Width -= ((int)textSize.Width + 8); + } + else if (m_Control != null) + { + r.Inflate(-2, -2); + if (m_AllowItemResize) + { + m_Control.Width = r.Width; + } + Point loc = r.Location; + loc.Offset((r.Width - m_Control.Width) / 2, (r.Height - m_Control.Height) / 2); + + ScrollableControl scc = pa.ContainerControl as ScrollableControl; + if (scc != null && scc.AutoScroll /*&& !(scc is ItemPanel)*/) + loc.Offset(scc.AutoScrollPosition.X, scc.AutoScrollPosition.Y); + + if (m_Control.Location != loc && + (!(m_Control is Controls.ComboBoxEx && ContainerControl is RibbonBar) || IsOnPopup(this)) || _ControlLocationUpdatePending) + { + m_Control.Location = loc; + _ControlLocationUpdatePending = false; + } + } + + if(this.IsOnCustomizeMenu && this.Visible) + { + // Draw check box if this item is visible + Rectangle rBox=new Rectangle(m_Rect.Left,m_Rect.Top,m_Rect.Height,m_Rect.Height); + if (EffectiveStyle != eDotNetBarStyle.Office2000) + rBox.Inflate(-1,-1); + BarFunctions.DrawMenuCheckBox(pa, rBox, EffectiveStyle, m_MouseOver); + } + } + + if (this.Focused && (this.GetDesignMode() || m_Control == null && this.DesignMode)) + { + r = this.DisplayRectangle; + r.Inflate(-1, -1); + DesignTime.DrawDesignTimeSelection(g, r, pa.Colors.ItemDesignTimeBorder); + } + } + + /// + /// IBlock member implementation + /// + [Browsable(false), DevCoBrowsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] + public override System.Drawing.Rectangle Bounds + { + get { return base.Bounds; } + set + { + if (base.Bounds != value) + { + bool topLocationChanged = base.Bounds.Top != value.Top; + bool leftLocationChanged = base.Bounds.Left != value.Left; + base.Bounds = value; + if (topLocationChanged || leftLocationChanged) + UpdateControlLocation(); + } + } + } + + private bool _ControlLocationUpdatePending = false; + private void UpdateControlLocation() + { + if (m_Control == null) return; + if (this.IsLayoutPassInProgress) + { + _ControlLocationUpdatePending = true; + return; + } + Rectangle r = this.DisplayRectangle; + r.Inflate(-2, -2); + m_Control.Location = r.Location; + _ControlLocationUpdatePending = false; + } + + /// + /// Overridden. Recalculates the size of the item. + /// + public override void RecalcSize() + { + if(this.SuspendLayout) + return; + + bool bOnMenu=this.IsOnMenu; + + if(m_Control==null && !this.DesignMode) + InitControl(); + + // Default Height + if(this.Parent!=null && this.Parent is ImageItem) + m_Rect.Height=((ImageItem)this.Parent).SubItemsImageSize.Height+4; + else + m_Rect.Height=this.SubItemsImageSize.Height+4; + + if (EffectiveStyle == eDotNetBarStyle.OfficeXP || EffectiveStyle == eDotNetBarStyle.Office2003 || EffectiveStyle == eDotNetBarStyle.VS2005) + { + if(m_Control!=null && m_Rect.Height<(m_Control.Height+2)) + m_Rect.Height=m_Control.Height+2; + } + else + { + if(m_Control!=null && m_Rect.Height<(m_Control.Height+2)) + m_Rect.Height=m_Control.Height+2; + } + + // Default width + if(m_Control!=null) + { + if (this.Stretch) + m_Rect.Width = 32; + else + { + m_Rect.Width = m_Control.Width + 4; + } + } + else + m_Rect.Width=64+4; + + // Calculate Item Height + if(m_Control==null) + { + string text=m_Text; + if(text=="") + text="Container"; + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null && IsHandleValid(objCtrl)) + { + Graphics g=BarFunctions.CreateGraphics(objCtrl); + try + { + Size textSize = TextDrawing.MeasureString(g, text, GetFont(), 0, GetStringFormat()); + if (textSize.Height > this.SubItemsImageSize.Height && textSize.Height > m_Rect.Height) + m_Rect.Height = (int)textSize.Height + 4; + m_Rect.Width = (int)textSize.Width + 8; + } + finally + { + g.Dispose(); + } + } + } + + Size objImageSize=GetMaxImageSize(); + if (this.IsOnMenu && EffectiveStyle != eDotNetBarStyle.Office2000 && !this.Stretch && !(this.Parent is ItemContainer)) + { + // THis is side bar that will need to be drawn for DotNet style + m_Rect.Width+=(objImageSize.Width+7); + } + + if(this.IsOnCustomizeMenu) + m_Rect.Width+=(objImageSize.Height+2); + + // Always call base implementation to reset resize flag + base.RecalcSize(); + } + + /// + /// Called when size of the item is changed externally. + /// + protected override void OnExternalSizeChange() + { + base.OnExternalSizeChange(); + if(m_AllowItemResize) + NeedRecalcSize=true; + } + + protected internal override void OnContainerChanged(object objOldContainer) + { + base.OnContainerChanged(objOldContainer); + if(m_Control!=null) + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(m_Control.Parent!=null && objCtrl!=m_Control.Parent) + m_Control.Parent.Controls.Remove(m_Control); + + if(objCtrl!=null && m_Control.Parent==null) + { + objCtrl.Controls.Add(m_Control); + m_Control.Refresh(); + } + } + } + + protected internal override void OnVisibleChanged(bool newValue) + { + if(m_Control!=null && !newValue) + m_Control.Visible=newValue; + base.OnVisibleChanged(newValue); + } + protected override void OnDisplayedChanged() + { + if (!this.Displayed && m_Control != null && !(this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.GetDesignMode())) + { + m_Control.Visible=this.Displayed; + } + } + + protected override void OnIsOnCustomizeDialogChanged() + { + base.OnIsOnCustomizeDialogChanged(); + CustomizeChanged(); + } + + protected override void OnDesignModeChanged() + { + base.OnDesignModeChanged(); + CustomizeChanged(); + } + + protected override void OnIsOnCustomizeMenuChanged() + { + base.OnIsOnCustomizeMenuChanged(); + CustomizeChanged(); + } + + private bool m_CustomizeChangedExecuting = false; + private void CustomizeChanged() + { + if(m_Control!=null) + { + if (m_CustomizeChangedExecuting) return; + m_CustomizeChangedExecuting = true; + try + { + if (this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.GetDesignMode()) + { + m_Control.Visible = false; + } + else + { + m_Control.Visible = this.Displayed; + } + } + finally + { + m_CustomizeChangedExecuting = false; + } + } + } + + private Size GetMaxImageSize() + { + if(m_Parent!=null) + { + ImageItem objParentImageItem=m_Parent as ImageItem; + if(objParentImageItem!=null) + return objParentImageItem.SubItemsImageSize; + else + return this.ImageSize; + } + else + return this.ImageSize; + } + private eTextFormat GetStringFormat() + { + eTextFormat format = eTextFormat.Default; + format |= eTextFormat.SingleLine; + format |= eTextFormat.EndEllipsis; + format |= eTextFormat.VerticalCenter; + return format; + + + //StringFormat sfmt=BarFunctions.CreateStringFormat(); //new StringFormat(StringFormat.GenericDefault); + //sfmt.HotkeyPrefix=System.Drawing.Text.HotkeyPrefix.Show; + ////sfmt.FormatFlags=sfmt.FormatFlags & ~(sfmt.FormatFlags & StringFormatFlags.DisableKerning); + //sfmt.FormatFlags=sfmt.FormatFlags | StringFormatFlags.NoWrap; + //sfmt.Trimming=StringTrimming.EllipsisCharacter; + //sfmt.Alignment=System.Drawing.StringAlignment.Near; + //sfmt.LineAlignment=System.Drawing.StringAlignment.Center; + + //return sfmt; + } + + /// + /// Returns the Font object to be used for drawing the item text. + /// + /// Font object. + protected virtual Font GetFont() + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null) + return (Font)objCtrl.Font; + return SystemFonts.DefaultFont; + } + protected internal override bool IsAnyOnHandle(IntPtr iHandle) + { + bool bRet=base.IsAnyOnHandle(iHandle); + if(!bRet && m_Control!=null && m_Control.Handle==iHandle) + bRet=true; + return bRet; + } + protected override void OnEnabledChanged() + { + base.OnEnabledChanged(); + if(m_Control!=null) + m_Control.Enabled=this.Enabled; + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseEnter() + { + base.InternalMouseEnter(); + if(!m_MouseOver) + { + m_MouseOver=true; + if(this.IsOnCustomizeMenu && this.Visible) + this.Refresh(); + } + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseLeave() + { + base.InternalMouseLeave(); + if(m_MouseOver) + { + m_MouseOver=false; + if (this.IsOnCustomizeMenu && this.Visible) + this.Refresh(); + } + } + + /// + /// Specifies whether contained control can be automatically resized to fill the item container. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Specifies whether contained control can be automatically resized to fill the item container.")] + public bool AllowItemResize + { + get {return m_AllowItemResize;} + set {m_AllowItemResize=value;} + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public override void OnGotFocus() + { + base.OnGotFocus(); + if(m_Control==null) + return; + if (m_Control.Focused || this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.GetDesignMode()) + return; + m_Control.Focus(); + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override bool IsWindowed + { + get {return true;} + } + + private bool GetDesignMode() + { + if (this.ContainerControl is IBarDesignerServices && ((IBarDesignerServices)this.ContainerControl).Designer != null) + return false; + return base.DesignMode; + } + } + + public class ControlContainerSerializationEventArgs : EventArgs + { + private readonly System.Xml.XmlElement xmlstore; + public ControlContainerSerializationEventArgs(System.Xml.XmlElement xmlstorage) + { + this.xmlstore=xmlstorage; + } + public System.Xml.XmlElement XmlStorage + { + get{return this.xmlstore;} + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/AnalogClockControl.bmp b/PROMS/DotNetBar Source Code/Controls/AnalogClockControl.bmp new file mode 100644 index 00000000..783bb5c9 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/AnalogClockControl.bmp differ diff --git a/PROMS/DotNetBar Source Code/Controls/BaseItemControl.cs b/PROMS/DotNetBar Source Code/Controls/BaseItemControl.cs new file mode 100644 index 00000000..61796360 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/BaseItemControl.cs @@ -0,0 +1,667 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using DevComponents.DotNetBar.Rendering; +using System.Reflection; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the class for the BaseItem non-popup based control host. + /// + [ToolboxItem(false)] + public abstract class BaseItemControl : Control + { + #region Private Variables + private BaseItem m_Item = null; + private ElementStyle m_BackgroundStyle = null; + private ColorScheme m_ColorScheme = null; + private bool m_DesignModeInternal = false; + private bool m_AntiAlias = true; + #endregion + + #region Constructor Dispose + /// + /// Creates new instance of the object. + /// + public BaseItemControl() + { + if (!ColorFunctions.ColorsLoaded) + { + NativeFunctions.RefreshSettings(); + NativeFunctions.OnDisplayChange(); + ColorFunctions.LoadColors(); + } + + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(ControlStyles.StandardDoubleClick, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + + m_ColorScheme = new ColorScheme(eDotNetBarStyle.Office2007); + m_BackgroundStyle = new ElementStyle(); + m_BackgroundStyle.SetColorScheme(m_ColorScheme); + m_BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + } + + protected override void Dispose(bool disposing) + { + if (disposing && m_Item != null) + m_Item.Dispose(); + base.Dispose(disposing); + } + #endregion + + #region Internal Implementation + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + if (Dpi.RecordScalePerControl) + Dpi.SetScaling(factor); + if (m_Item != null) + { + m_Item.NotifyScaleItem(factor); + RecalcLayout(); + } + base.ScaleControl(factor, specified); + } + + internal bool IsValidationCancelled + { + get + { + PropertyInfo pi=this.GetType().GetProperty("ValidationCancelled", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + if (pi != null) + return (bool)pi.GetValue(this, null); + return false; + } + } + + +#if FRAMEWORK20 + protected override void OnBindingContextChanged(EventArgs e) + { + base.OnBindingContextChanged(e); + if (m_Item != null) + m_Item.UpdateBindings(); + } +#endif + + protected bool GetDesignMode() + { + if (!m_DesignModeInternal) + return this.DesignMode; + return m_DesignModeInternal; + } + + protected virtual ElementStyle GetBackgroundStyle() + { + return m_BackgroundStyle; + } + + internal void SetDesignMode(bool mode) + { + m_DesignModeInternal = mode; + if(m_Item!=null) + m_Item.SetDesignMode(mode); + } + + /// + /// Gets or sets the instance of BaseItem object hosted by this control. + /// + protected virtual BaseItem HostItem + { + get { return m_Item; } + set + { + m_Item = value; + if (m_Item != null) + { + m_Item.Displayed = true; + m_Item.ContainerControl = this; + } + } + } + + /// + /// Returns the color scheme used by control. Color scheme for Office2007 style will be retrieved from the current renderer instead of + /// local color scheme referenced by ColorScheme property. + /// + /// An instance of ColorScheme object. + protected virtual ColorScheme GetColorScheme() + { + if (m_Item != null && BarFunctions.IsOffice2007Style(m_Item.EffectiveStyle)) + { + BaseRenderer r = GetRenderer(); + if (r is Office2007Renderer) + return ((Office2007Renderer)r).ColorTable.LegacyColors; + } + return m_ColorScheme; + } + + private bool _CallBasePaintBackground = true; + /// + /// Gets or sets whether during painting OnPaintBackground on base control is called when BackColor=Transparent. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool CallBasePaintBackground + { + get { return _CallBasePaintBackground; } + set + { + _CallBasePaintBackground = value; + } + } + + internal void InternalPaint(PaintEventArgs e) + { + OnPaint(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + if ((this.BackColor.IsEmpty || this.BackColor == Color.Transparent) && _CallBasePaintBackground) + { + base.OnPaintBackground(e); + } + + if (m_BackgroundStyle != null) + m_BackgroundStyle.SetColorScheme(this.GetColorScheme()); + + PaintBackground(e); + PaintControl(e); + + if (this.Focused && /*this.ShowFocusCues &&*/ this.FocusCuesEnabled) + { + PaintFocusCues(e); + } + + base.OnPaint(e); + } + + private bool _FocusCuesEnabled = true; + /// + /// Gets or sets whether control displays focus cues when focused. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether control displays focus cues when focused.")] + public virtual bool FocusCuesEnabled + { + get { return _FocusCuesEnabled; } + set + { + _FocusCuesEnabled = value; + if (this.Focused) this.Invalidate(); + } + } + + /// + /// Paints the control focus cues. + /// + /// Paint event information. + protected virtual void PaintFocusCues(PaintEventArgs e) + { + ControlPaint.DrawFocusRectangle(e.Graphics, this.ClientRectangle); + } + + protected virtual void PaintBackground(PaintEventArgs e) + { + Graphics g = e.Graphics; + Rectangle r = this.ClientRectangle; + ElementStyle style = this.GetBackgroundStyle(); + + if (!this.BackColor.IsEmpty && this.BackColor != Color.Transparent) + { + DisplayHelp.FillRectangle(g, r, this.BackColor); + } + + if (this.BackgroundImage != null) + base.OnPaintBackground(e); + + if (style.Custom) + { + SmoothingMode sm = g.SmoothingMode; + if (m_AntiAlias) + g.SmoothingMode = SmoothingMode.HighQuality; + ElementStyleDisplayInfo displayInfo = new ElementStyleDisplayInfo(style, e.Graphics, r); + ElementStyleDisplay.Paint(displayInfo); + if (m_AntiAlias) + g.SmoothingMode = sm; + } + } + + protected virtual void PaintControl(PaintEventArgs e) + { + SmoothingMode sm = e.Graphics.SmoothingMode; + TextRenderingHint th = e.Graphics.TextRenderingHint; + Graphics g = e.Graphics; + + if (m_AntiAlias) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + ItemPaintArgs pa = GetItemPaintArgs(g); + pa.ClipRectangle = e.ClipRectangle; + + if (m_Item != null) m_Item.Paint(pa); + + if (m_AntiAlias) + { + g.SmoothingMode = sm; + g.TextRenderingHint = th; + } + } + + /// + /// Creates the Graphics object for the control. + /// + /// The Graphics object for the control. + public new Graphics CreateGraphics() + { + Graphics g = base.CreateGraphics(); + if (m_AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + #if FRAMEWORK20 + if (!SystemInformation.IsFontSmoothingEnabled) + #endif + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + return g; + } + + protected virtual ItemPaintArgs GetItemPaintArgs(Graphics g) + { + ItemPaintArgs pa = new ItemPaintArgs(this as IOwner, this, g, GetColorScheme()); + pa.Renderer = this.GetRenderer(); + pa.DesignerSelection = false; + pa.GlassEnabled = !this.DesignMode && WinApi.IsGlassEnabled; + return pa; + } + + private Rendering.BaseRenderer m_DefaultRenderer = null; + private Rendering.BaseRenderer m_Renderer = null; + private eRenderMode m_RenderMode = eRenderMode.Global; + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public virtual Rendering.BaseRenderer GetRenderer() + { + if (m_RenderMode == eRenderMode.Global && Rendering.GlobalManager.Renderer != null) + return Rendering.GlobalManager.Renderer; + else if (m_RenderMode == eRenderMode.Custom && m_Renderer != null) + return m_Renderer; + + if (m_DefaultRenderer == null) + m_DefaultRenderer = new Rendering.Office2007Renderer(); + + return m_Renderer; + } + + /// + /// Gets or sets the redering mode used by control. Default value is eRenderMode.Global which means that static GlobalManager.Renderer is used. If set to Custom then Renderer property must + /// also be set to the custom renderer that will be used. + /// + [Browsable(false), DefaultValue(eRenderMode.Global)] + public eRenderMode RenderMode + { + get { return m_RenderMode; } + set + { + if (m_RenderMode != value) + { + m_RenderMode = value; + this.Invalidate(true); + } + } + } + + /// + /// Gets or sets the custom renderer used by the items on this control. RenderMode property must also be set to eRenderMode.Custom in order renderer + /// specified here to be used. + /// + [Browsable(false), DefaultValue(null)] + public DevComponents.DotNetBar.Rendering.BaseRenderer Renderer + { + get + { + return m_Renderer; + } + set { m_Renderer = value; } + } + + /// + /// Specifies the background style of the control. + /// + [Browsable(true), DevCoBrowsable(true), Category("Style"), Description("Gets or sets bar background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return m_BackgroundStyle; } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + m_BackgroundStyle.StyleChanged -= new EventHandler(this.VisualPropertyChanged); + m_BackgroundStyle = new ElementStyle(); + m_BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + OnBackgroundStyleChanged(); + this.Invalidate(); + } + + protected virtual void OnBackgroundStyleChanged() + { + } + + private void VisualPropertyChanged(object sender, EventArgs e) + { + OnVisualPropertyChanged(); + } + + /// + /// Called when visual property of the control has changed so the control can be updated. + /// + protected virtual void OnVisualPropertyChanged() + { + if (this.GetDesignMode() || + this.Parent != null && this.Parent.Site != null && this.Parent.Site.DesignMode) + { + this.RecalcLayout(); + } + } + + /// + /// Gets or sets Bar Color Scheme. + /// + [Browsable(false), DevCoBrowsable(false), Category("Appearance"), Description("Gets or sets Bar Color Scheme."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ColorScheme ColorScheme + { + get { return m_ColorScheme; } + set + { + if (value == null) + throw new ArgumentException("NULL is not a valid value for this property."); + m_ColorScheme = value; + if (this.Visible) + this.Refresh(); + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeColorScheme() + { + return m_ColorScheme.SchemeChanged; + } + + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is false. + /// + [DefaultValue(true), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public bool AntiAlias + { + get { return m_AntiAlias; } + set + { + if (m_AntiAlias != value) + { + m_AntiAlias = value; + this.Invalidate(); + } + } + } + + protected override void OnParentChanged(EventArgs e) + { + base.OnParentChanged(e); + //if (this.Parent != null && (this.Images != null || this.ImagesLarge != null || this.ImagesMedium != null)) + //{ + // foreach (BaseItem panel in m_BaseItemContainer.SubItems) + // { + // foreach (BaseItem item in panel.SubItems) + // { + // if (item is ImageItem) + // ((ImageItem)item).OnImageChanged(); + // } + // } + //} + + if (this.DesignMode && m_Item!=null) + m_Item.SetDesignMode(this.DesignMode); + } + + /// + /// Forces the button to perform internal layout. + /// + public virtual void RecalcLayout() + { + if (m_Item == null) return; + + Rectangle r = GetItemBounds(); + m_Item.Bounds = r; + this.RecalcSize(); + m_Item.Bounds = r; + this.Invalidate(); + } + + /// + /// Recalculates the size of the internal item. + /// + protected virtual void RecalcSize() + { + m_Item.RecalcSize(); + } + + protected virtual Rectangle GetItemBounds() + { + Rectangle r = this.ClientRectangle; + r.X += ElementStyleLayout.LeftWhiteSpace(this.BackgroundStyle); + r.Width -= ElementStyleLayout.HorizontalStyleWhiteSpace(this.BackgroundStyle); + r.Y += ElementStyleLayout.TopWhiteSpace(this.BackgroundStyle); + r.Height -= ElementStyleLayout.VerticalStyleWhiteSpace(this.BackgroundStyle); + + return r; + } + + protected override void OnResize(EventArgs e) + { + RecalcLayout(); + base.OnResize(e); + } + + protected override void OnTextChanged(EventArgs e) + { + m_Item.Text = this.Text; + this.RecalcLayout(); + base.OnTextChanged(e); + } + + protected override void OnFontChanged(EventArgs e) + { + base.OnFontChanged(e); + BarUtilities.InvalidateFontChange(m_Item); + this.RecalcLayout(); + } + + protected override void OnEnabledChanged(EventArgs e) + { + m_Item.Enabled = this.Enabled; + base.OnEnabledChanged(e); + } + + private bool m_MouseFocus = false; + protected override void OnGotFocus(EventArgs e) + { + if (!m_MouseFocus) + m_Item.OnGotFocus(); + m_MouseFocus = false; + base.OnGotFocus(e); + } + + protected override void OnLostFocus(EventArgs e) + { + m_Item.OnLostFocus(); + base.OnLostFocus(e); + } + + protected override void OnMouseEnter(EventArgs e) + { + m_Item.InternalMouseEnter(); + base.OnMouseEnter(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + m_Item.InternalMouseMove(e); + base.OnMouseMove(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + m_Item.InternalMouseLeave(); + base.OnMouseLeave(e); + } + + protected override void OnMouseHover(EventArgs e) + { + m_Item.InternalMouseHover(); + base.OnMouseHover(e); + } + + protected virtual MouseButtons MouseDownFocusButtons + { + get { return MouseButtons.Left; } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + if ((e.Button & MouseDownFocusButtons) != 0) + { + if (!this.Focused && this.GetStyle(ControlStyles.Selectable)) + { + m_MouseFocus = true; + this.Select(); + } + } + + m_Item.InternalMouseDown(e); + base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + m_Item.InternalMouseUp(e); + base.OnMouseUp(e); + } + + protected override void OnClick(EventArgs e) + { + m_Item.InternalClick(Control.MouseButtons, this.PointToClient(Control.MousePosition)); + base.OnClick(e); + } + + protected override void OnDoubleClick(EventArgs e) + { + m_Item.InternalDoubleClick(Control.MouseButtons, this.PointToClient(Control.MousePosition)); + base.OnDoubleClick(e); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + m_Item.InternalKeyDown(e); + base.OnKeyDown(e); + } + + /// + /// Gets/Sets the visual style for the control. + /// + [Browsable(true), Category("Appearance"), Description("Specifies the visual style of the control."), DefaultValue(eDotNetBarStyle.Office2007)] + public virtual eDotNetBarStyle Style + { + get + { + return m_Item.Style; + } + set + { + m_Item.Style = value; + if(!BarFunctions.IsOffice2007Style(value)) + this.GetColorScheme().Style = value; + this.RecalcLayout(); + } + } + + protected override bool ProcessMnemonic(char charCode) + { + if (IsMnemonic(charCode, m_Item.Text)) + { + if (ProcessAccelerator()) + return true; + } + return base.ProcessMnemonic(charCode); + } + + protected virtual bool ProcessAccelerator() + { + m_Item.RaiseClick(eEventSource.Keyboard); + return true; + } + #endregion + + #region Layout Support + private int m_UpdateSuspendCount = 0; + /// + /// Indicates to control that all further update operations should not result in layout and refresh of control content. + /// Use this method to optimize the addition of new items to the control. This method supports nested calls meaning + /// that multiple calls are allowed but they must be ended with appropriate number of EndUpdate calls. + /// IsUpdateSuspended property returns whether update is suspended. + /// + public void BeginUpdate() + { + m_UpdateSuspendCount++; + } + + /// + /// Indicates that update operation is complete and that control should perform layout and refresh to show changes. See BeginUpdate + /// for more details. + /// + public void EndUpdate() + { + EndUpdate(true); + } + + /// + /// Indicates that update operation is complete and that control should perform layout and refresh to show changes. See BeginUpdate + /// for more details. + /// + public void EndUpdate(bool callRecalcLayout) + { + if (m_UpdateSuspendCount > 0) + { + m_UpdateSuspendCount--; + if (m_UpdateSuspendCount == 0 && callRecalcLayout) + this.RecalcLayout(); + } + } + + /// + /// Gets whether control layout is suspended becouse of the call to BeginUpdate method. + /// + [Browsable(false)] + public bool IsUpdateSuspended + { + get { return m_UpdateSuspendCount > 0; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/BindingNavigatorEx.cs b/PROMS/DotNetBar Source Code/Controls/BindingNavigatorEx.cs new file mode 100644 index 00000000..c8f04a89 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/BindingNavigatorEx.cs @@ -0,0 +1,671 @@ +using System.ComponentModel; + +using System.Globalization; +using System.Drawing; +using System.Runtime.InteropServices; +using DevComponents.DotNetBar; +using System.Windows.Forms; +using System; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the bound data navigator in current DotNetBar style. + /// + [DefaultEvent("RefreshItems"), Description("DotNetBar Binding Navigator Control"), ClassInterface(ClassInterfaceType.AutoDispatch), DefaultProperty("BindingSource")] + [Designer("DevComponents.DotNetBar.Design.BindingNavigatorExDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + [ToolboxBitmap(typeof(BindingNavigatorEx), "Controls.BindingNavigatorEx.ico"), ToolboxItem(true)] + public class BindingNavigatorEx : Bar, ISupportInitialize + { + #region Private Variables + private ButtonItem _AddNewButton; + private bool _AddNewItemUserEnabled; + private BindingSource _BindingSource; + private LabelItem _CountLabel; + private string _CountLabelFormat; + private ButtonItem _DeleteButton; + private bool _DeleteButtonUserEnabled; + private bool _Initializing; + private ButtonItem _MoveFirstButton; + private ButtonItem _MoveLastButton; + private ButtonItem _MoveNextButton; + private ButtonItem _MovePreviousButton; + private TextBoxItem _PositionTextBox; + #endregion + + #region Constructor + /// + /// Creates new instance of BindingNavigatorEx + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public BindingNavigatorEx() + : this(false) + { + } + /// + /// Creates new instance of BindingNavigatorEx + /// + public BindingNavigatorEx(bool addStandardItems) + { + _CountLabelFormat = "of {0}"; + _AddNewItemUserEnabled = true; + _DeleteButtonUserEnabled = true; + if (addStandardItems) + { + this.AddDefaultItems(); + } + } + /// + /// Creates new instance of BindingNavigatorEx + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public BindingNavigatorEx(IContainer container) + : this(false) + { + if (container == null) + { + throw new ArgumentNullException("container"); + } + container.Add(this); + + } + /// + /// Creates new instance of BindingNavigatorEx + /// + public BindingNavigatorEx(BindingSource bindingSource) + : this(true) + { + this.BindingSource = bindingSource; + } + #endregion + + #region Internal Implementation + + private void AcceptNewPosition() + { + if (_PositionTextBox != null && _BindingSource != null) + { + int position = this._BindingSource.Position; + try + { + position = Convert.ToInt32(this._PositionTextBox.Text, CultureInfo.CurrentCulture) - 1; + } + catch (FormatException) + { + } + catch (OverflowException) + { + } + if (position != this._BindingSource.Position) + { + this._BindingSource.Position = position; + } + this.RefreshStateInternal(); + } + } + /// + /// Adds default items that make up the binding navigation control. + /// + public virtual void AddDefaultItems() + { + this.MoveFirstButton = new ButtonItem(); + this.MovePreviousButton = new ButtonItem(); + this.MoveNextButton = new ButtonItem(); + this.MoveLastButton = new ButtonItem(); + this.PositionTextBox = new TextBoxItem(); + this.CountLabel = new LabelItem(); + this.AddNewRecordButton = new ButtonItem(); + this.DeleteButton = new ButtonItem(); + char ch = (string.IsNullOrEmpty(base.Name) || char.IsLower(base.Name[0])) ? 'b' : 'B'; + this.MoveFirstButton.Name = ch + "indingNavigatorMoveFirstItem"; + this.MovePreviousButton.Name = ch + "indingNavigatorMovePreviousItem"; + this.MoveNextButton.Name = ch + "indingNavigatorMoveNextItem"; + this.MoveLastButton.Name = ch + "indingNavigatorMoveLastItem"; + this.PositionTextBox.Name = ch + "indingNavigatorPositionItem"; + this.CountLabel.Name = ch + "indingNavigatorCountItem"; + this.AddNewRecordButton.Name = ch + "indingNavigatorAddNewItem"; + this.DeleteButton.Name = ch + "indingNavigatorDeleteItem"; + this.MoveFirstButton.Text = "Move first"; + this.MovePreviousButton.Text = "Move previous"; + this.MoveNextButton.Text = "Move next"; + this.MoveLastButton.Text = "Move last"; + this.AddNewRecordButton.Text = "Add new"; + this.DeleteButton.Text = "Delete"; + this.PositionTextBox.AccessibleName = "Position"; + + _PositionTextBox.BeginGroup = true; + _MoveNextButton.BeginGroup = true; + _MoveFirstButton.Image = BarFunctions.LoadBitmap("SystemImages.FirstRecord.png"); + _MovePreviousButton.Image = BarFunctions.LoadBitmap("SystemImages.PreviousRecord.png"); + _MoveNextButton.Image = BarFunctions.LoadBitmap("SystemImages.NextRecord.png"); ; + _MoveLastButton.Image = BarFunctions.LoadBitmap("SystemImages.LastRecord.png"); ; + _AddNewButton.Image = BarFunctions.LoadBitmap("SystemImages.NewRecord.png"); ; + _DeleteButton.Image = BarFunctions.LoadBitmap("SystemImages.Delete.png"); ; + + _PositionTextBox.TextBoxWidth = 54; + this.Items.AddRange(new BaseItem[] { this.MoveFirstButton, this.MovePreviousButton, this.PositionTextBox, this.CountLabel, this.MoveNextButton, this.MoveLastButton, this.AddNewRecordButton, this.DeleteButton }); + } + + + private void CancelNewPosition() + { + this.RefreshStateInternal(); + } + + private bool _IsDisposing = false; + protected override void Dispose(bool disposing) + { + if (disposing) + { + _IsDisposing = true; + try + { + this.BindingSource = null; + } + finally + { + _IsDisposing = false; + } + } + base.Dispose(disposing); + } + + private void OnAddNew(object sender, EventArgs e) + { + if (this.Validate() && _BindingSource != null) + { + _BindingSource.EndEdit(); + _BindingSource.AddNew(); + RefreshStateInternal(); + } + } + + private void OnAddNewItemEnabledChanged(object sender, EventArgs e) + { + if (AddNewRecordButton != null) + { + _AddNewItemUserEnabled = _AddNewButton.Enabled; + } + } + + private void OnBindingSourceListChanged(object sender, ListChangedEventArgs e) + { + RefreshStateInternal(); + } + + private void OnBindingSourceStateChanged(object sender, EventArgs e) + { + RefreshStateInternal(); + } + + private void OnDelete(object sender, EventArgs e) + { + if (this.Validate() && _BindingSource != null) + { + _BindingSource.RemoveCurrent(); + RefreshStateInternal(); + } + } + + private void OnDeleteItemEnabledChanged(object sender, EventArgs e) + { + if (DeleteButton != null) + { + _DeleteButtonUserEnabled = _DeleteButton.Enabled; + } + } + + private void OnMoveFirst(object sender, EventArgs e) + { + if (Validate() && _BindingSource != null) + { + _BindingSource.MoveFirst(); + RefreshStateInternal(); + } + } + + private void OnMoveLast(object sender, EventArgs e) + { + if (Validate() && _BindingSource != null) + { + _BindingSource.MoveLast(); + RefreshStateInternal(); + } + } + + private void OnMoveNext(object sender, EventArgs e) + { + if (Validate() && this._BindingSource != null) + { + _BindingSource.MoveNext(); + RefreshStateInternal(); + } + } + + private void OnMovePrevious(object sender, EventArgs e) + { + if (Validate() && _BindingSource != null) + { + _BindingSource.MovePrevious(); + RefreshStateInternal(); + } + } + + private void OnPositionKey(object sender, KeyEventArgs e) + { + Keys keyCode = e.KeyCode; + if (keyCode != Keys.Return) + { + if (keyCode != Keys.Escape) + { + return; + } + } + else + { + AcceptNewPosition(); + return; + } + CancelNewPosition(); + } + + private void OnPositionLostFocus(object sender, EventArgs e) + { + AcceptNewPosition(); + } + + protected virtual void OnRefreshState() + { + RefreshState(); + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + protected virtual void RefreshState() + { + int count; + int currentPosition; + bool allowNew; + bool allowRemove; + if (_BindingSource == null) + { + count = 0; + currentPosition = 0; + allowNew = false; + allowRemove = false; + } + else if (_BindingSource.Position == -1) + { + count = -1; + currentPosition = -1; + allowNew = true; + allowRemove = false; + } + else + { + count = _BindingSource.Count; + currentPosition = _BindingSource.Position + 1; + allowNew = _BindingSource.AllowNew; + allowRemove = _BindingSource.AllowRemove; + } + if (!base.DesignMode) + { + if (MoveFirstButton != null) + { + _MoveFirstButton.Enabled = currentPosition > 1; + } + if (MovePreviousButton != null) + { + _MovePreviousButton.Enabled = currentPosition > 1; + } + if (MoveNextButton != null) + { + _MoveNextButton.Enabled = currentPosition < count; + } + if (MoveLastButton != null) + { + _MoveLastButton.Enabled = currentPosition < count; + } + if (AddNewRecordButton != null) + { + EventHandler handler = this.OnAddNewItemEnabledChanged; + _AddNewButton.EnabledChanged -= handler; + _AddNewButton.Enabled = _AddNewItemUserEnabled && allowNew; + _AddNewButton.EnabledChanged += handler; + } + if (DeleteButton != null) + { + EventHandler handler2 = OnDeleteItemEnabledChanged; + _DeleteButton.EnabledChanged -= handler2; + _DeleteButton.Enabled = (this._DeleteButtonUserEnabled && allowRemove) && (count > 0); + _DeleteButton.EnabledChanged += handler2; + } + if (PositionTextBox != null) + { + _PositionTextBox.Enabled = (currentPosition > 0) && (count > 0); + } + if (CountLabel != null) + { + _CountLabel.Enabled = count > 0; + } + } + if (_PositionTextBox != null) + { + _PositionTextBox.Text = currentPosition.ToString(CultureInfo.CurrentCulture); + } + if (_CountLabel != null) + { + _CountLabel.Text = base.DesignMode ? CountLabelFormat : string.Format(CultureInfo.CurrentCulture, CountLabelFormat, new object[] { count }); + } + } + + private void RefreshStateInternal() + { + if (!_Initializing && !_IsDisposing) + OnRefreshState(); + } + + public bool Validate() + { + bool flag = false; + System.Reflection.MethodInfo mi = ((Control)this).GetType().GetMethod("ValidateActiveControl", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (mi != null) + { + return (bool)mi.Invoke(this, new object[] { flag }); + } + return true; + } + + private void WireUpBindingSource(ref BindingSource oldBindingSource, BindingSource newBindingSource) + { + if (oldBindingSource != newBindingSource) + { + if (oldBindingSource != null) + { + oldBindingSource.PositionChanged -= OnBindingSourceStateChanged; + oldBindingSource.CurrentChanged -= OnBindingSourceStateChanged; + oldBindingSource.CurrentItemChanged -= OnBindingSourceStateChanged; + oldBindingSource.DataSourceChanged -= OnBindingSourceStateChanged; + oldBindingSource.DataMemberChanged -= OnBindingSourceStateChanged; + oldBindingSource.ListChanged -= OnBindingSourceListChanged; + } + if (newBindingSource != null) + { + newBindingSource.PositionChanged += OnBindingSourceStateChanged; + newBindingSource.CurrentChanged += OnBindingSourceStateChanged; + newBindingSource.CurrentItemChanged += OnBindingSourceStateChanged; + newBindingSource.DataSourceChanged += OnBindingSourceStateChanged; + newBindingSource.DataMemberChanged += OnBindingSourceStateChanged; + newBindingSource.ListChanged += OnBindingSourceListChanged; + } + oldBindingSource = newBindingSource; + this.RefreshStateInternal(); + } + } + + private void WireUpButton(ref ButtonItem oldButton, ButtonItem newButton, EventHandler clickHandler) + { + if (oldButton != newButton) + { + if (oldButton != null) + { + oldButton.Click -= clickHandler; + } + if (newButton != null) + { + newButton.Click += clickHandler; + } + oldButton = newButton; + this.RefreshStateInternal(); + } + } + + private void WireUpLabel(ref LabelItem oldLabel, LabelItem newLabel) + { + if (oldLabel != newLabel) + { + oldLabel = newLabel; + this.RefreshStateInternal(); + } + } + + private void WireUpTextBox(ref TextBoxItem oldTextBox, TextBoxItem newTextBox, KeyEventHandler keyUpHandler, EventHandler lostFocusHandler) + { + if (oldTextBox != newTextBox) + { + if (oldTextBox != null) + { + oldTextBox.KeyUp -= keyUpHandler; + oldTextBox.LostFocus -= lostFocusHandler; + } + if (newTextBox != null) + { + newTextBox.KeyUp += keyUpHandler; + newTextBox.LostFocus += lostFocusHandler; + } + oldTextBox = newTextBox; + this.RefreshStateInternal(); + } + } + + /// + /// Gets or sets the reference to Add New record button. + /// + [DefaultValue(null), Category("Items"), TypeConverter(typeof(ReferenceConverter)), Description("BindingNavigatorAddNewItemPropDescr")] + public ButtonItem AddNewRecordButton + { + get + { + if (_AddNewButton != null && _AddNewButton.IsDisposed) + { + _AddNewButton = null; + } + return _AddNewButton; + } + set + { + if ((_AddNewButton != value) && (value != null)) + { + value.EnabledChanged += OnAddNewItemEnabledChanged; + _AddNewItemUserEnabled = value.Enabled; + } + WireUpButton(ref _AddNewButton, value, OnAddNew); + } + } + + /// + /// Gets or sets the binding source for the navigator. + /// + [Category("Data"), Description("Gets or sets the binding source for the navigator."), DefaultValue((string)null), TypeConverter(typeof(ReferenceConverter))] + public BindingSource BindingSource + { + get + { + return _BindingSource; + } + set + { + WireUpBindingSource(ref _BindingSource, value); + } + } + + /// + /// Gets or sets the label which represents the items count. + /// + [TypeConverter(typeof(ReferenceConverter)), Category("Items"), Description("Indicates label which represents the items count.")] + public LabelItem CountLabel + { + get + { + if (_CountLabel != null && _CountLabel.IsDisposed) + { + _CountLabel = null; + } + return _CountLabel; + } + set + { + this.WireUpLabel(ref _CountLabel, value); + } + } + + /// + /// Indicates the format string for the label which displays the number of items bound. + /// + [Description("Indicates the format string for the label which displays the number of items bound."), Category("Appearance")] + public string CountLabelFormat + { + get + { + return _CountLabelFormat; + } + set + { + if (_CountLabelFormat != value) + { + _CountLabelFormat = value; + RefreshStateInternal(); + } + } + } + + /// + /// Gets or sets the item which deletes current record. + /// + [DefaultValue(null), Description("Indicates item which deletes current record."), TypeConverter(typeof(ReferenceConverter)), Category("Items")] + public ButtonItem DeleteButton + { + get + { + if ((this._DeleteButton != null) && this._DeleteButton.IsDisposed) + { + _DeleteButton = null; + } + return _DeleteButton; + } + set + { + if ((this._DeleteButton != value) && (value != null)) + { + value.EnabledChanged += new EventHandler(this.OnDeleteItemEnabledChanged); + _DeleteButtonUserEnabled = value.Enabled; + } + this.WireUpButton(ref _DeleteButton, value, new EventHandler(this.OnDelete)); + } + } + + /// + /// Gets or sets the item which moves to first record. + /// + [DefaultValue(null), TypeConverter(typeof(ReferenceConverter)), Category("Items"), Description("Indicates item which moves to first record.")] + public ButtonItem MoveFirstButton + { + get + { + if (_MoveFirstButton != null && _MoveFirstButton.IsDisposed) + { + _MoveFirstButton = null; + } + return _MoveFirstButton; + } + set + { + WireUpButton(ref _MoveFirstButton, value, this.OnMoveFirst); + } + } + /// + /// Gets or sets the item which moves to last record. + /// + [DefaultValue(null), Category("Items"), Description("Indicates item which moves to last record."), TypeConverter(typeof(ReferenceConverter))] + public ButtonItem MoveLastButton + { + get + { + if ((_MoveLastButton != null) && _MoveLastButton.IsDisposed) + { + _MoveLastButton = null; + } + return _MoveLastButton; + } + set + { + this.WireUpButton(ref _MoveLastButton, value, OnMoveLast); + } + } + /// + /// Gets or sets the item which moves to next record. + /// + [DefaultValue(null), TypeConverter(typeof(ReferenceConverter)), Category("Items"), Description("Indicates item which moves to next record")] + public ButtonItem MoveNextButton + { + get + { + if (_MoveNextButton != null && _MoveNextButton.IsDisposed) + { + _MoveNextButton = null; + } + return _MoveNextButton; + } + set + { + this.WireUpButton(ref _MoveNextButton, value, new EventHandler(this.OnMoveNext)); + } + } + /// + /// Gets or sets the item which moves to previous record. + /// + [DefaultValue(null), Description("Indicates item which moves to previous record"), TypeConverter(typeof(ReferenceConverter)), Category("Items")] + public ButtonItem MovePreviousButton + { + get + { + if (_MovePreviousButton != null && this._MovePreviousButton.IsDisposed) + { + _MovePreviousButton = null; + } + return _MovePreviousButton; + } + set + { + this.WireUpButton(ref _MovePreviousButton, value, OnMovePrevious); + } + } + /// + /// Gets or sets the text-box which shows current position. + /// + [DefaultValue(null), Category("Items"), Description("Indicates text-box which shows current position."), TypeConverter(typeof(ReferenceConverter))] + public TextBoxItem PositionTextBox + { + get + { + if (_PositionTextBox != null && _PositionTextBox.IsDisposed) + { + _PositionTextBox = null; + } + return _PositionTextBox; + } + set + { + this.WireUpTextBox(ref _PositionTextBox, value, OnPositionKey, OnPositionLostFocus); + } + } + #endregion + + #region ISupportInitialize Members + + void ISupportInitialize.BeginInit() + { + _Initializing = true; + } + + void ISupportInitialize.EndInit() + { + + _Initializing = false; + this.RefreshStateInternal(); + } + + + #endregion + + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/BindingNavigatorEx.ico b/PROMS/DotNetBar Source Code/Controls/BindingNavigatorEx.ico new file mode 100644 index 00000000..732ac22e Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/BindingNavigatorEx.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/CheckBoxX.cs b/PROMS/DotNetBar Source Code/Controls/CheckBoxX.cs new file mode 100644 index 00000000..4e0270de --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/CheckBoxX.cs @@ -0,0 +1,786 @@ +using System; +using System.Text; +using System.Drawing; +using System.ComponentModel; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the Check Box control with extended styles. + /// + [ToolboxBitmap(typeof(CheckBoxX), "Controls.CheckBoxX.ico"), ToolboxItem(true), DefaultEvent("CheckedChanged"), System.Runtime.InteropServices.ComVisible(false), Designer("DevComponents.DotNetBar.Design.CheckBoxXDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class CheckBoxX : BaseItemControl, ICommandSource + { + #region Private Variables + private const string DefaultCheckValueUnchecked = "N"; + private const string DefaultCheckValueChecked = "Y"; + private const object DefaultCheckValueIndeterminate = null; + + private CheckBoxItem m_CheckBox = null; + private object m_CheckValue = DefaultCheckValueUnchecked; + + private object m_CheckValueUnchecked = DefaultCheckValueUnchecked; + private object m_CheckValueChecked = DefaultCheckValueChecked; + private object m_CheckValueIndeterminate = DefaultCheckValueIndeterminate; + private bool m_ConsiderEmptyStringAsNull = true; + #endregion + + #region Events + /// + /// Occurs before Checked property is changed and allows you to cancel the change. + /// + public event CheckBoxXChangeEventHandler CheckedChanging; + + /// + /// Occurs after Checked property is changed with extended information. + /// + public event CheckBoxXChangeEventHandler CheckedChangedEx; + + /// + /// Occurs after Checked property is changed. This event is provided for the Windows Forms data binding support. You can use CheckedChangedEx to get extended information about the changed. + /// + public event EventHandler CheckedChanged; + + /// + /// Occurs after Checked property is changed. This event is provided for the Windows Forms data binding support. You can use CheckedChangedEx to get extended information about the changed. + /// + public event EventHandler CheckValueChanged; + #endregion + + #region Constructor, Dispose + public CheckBoxX() + { + this.SetStyle(ControlStyles.Selectable, true); + m_CheckBox = new CheckBoxItem(); + m_CheckBox.VerticalPadding = 0; + m_CheckBox.Style = eDotNetBarStyle.Office2007; + m_CheckBox.CheckedChanging += new CheckBoxChangeEventHandler(OnCheckedChanging); + m_CheckBox.CheckedChanged += new CheckBoxChangeEventHandler(OnCheckedChanged); + this.HostItem = m_CheckBox; + } + + #endregion + + #region Internal Implementation + /// + /// Gets or sets the size of the check or radio sign. Default value is 13x13. Minimum value is 6x6. + /// + [Category("Appearance"), Description("Indicates size of the check or radio sign. Default value is 13x13.")] + public Size CheckSignSize + { + get { return m_CheckBox.CheckSignSize; } + set { m_CheckBox.CheckSignSize = value; this.RecalcLayout(); this.Invalidate(); } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCheckSignSize() + { + return m_CheckBox.ShouldSerializeCheckSignSize(); + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetCheckSignSize() + { + this.CheckSignSize = new Size(13, 13); + } + + /// + /// Gets or sets whether text-markup support is enabled for controls Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the control instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for controls Text property.")] + public bool EnableMarkup + { + get { return m_CheckBox.EnableMarkup; } + set + { + m_CheckBox.EnableMarkup = value; + } + } + protected override MouseButtons MouseDownFocusButtons + { + get { return MouseButtons.Left | MouseButtons.Right | MouseButtons.Middle | MouseButtons.XButton1 | MouseButtons.XButton2; } + } + //protected override void OnMouseDown(MouseEventArgs e) + //{ + // if (!this.Focused) + // this.Select(); + // base.OnMouseDown(e); + //} + + //protected override void OnEnter(EventArgs e) + //{ + // if (this.CheckBoxStyle == eCheckBoxStyle.RadioButton && Control.MouseButtons == MouseButtons.None && WinApi.GetKeyState(9) < 0 && this.AutoCheck) + // { + // m_CheckBox.SetChecked(true, eEventSource.Keyboard); + // } + // base.OnEnter(e); + //} + + /// + /// Invokes the CheckedChanged event. + /// + private void OnCheckedChanged(object sender, CheckBoxChangeEventArgs e) + { + CheckBoxX previous = null; + if (m_CheckBox.CheckBoxStyle == eCheckBoxStyle.RadioButton && m_CheckBox.Checked && this.Parent != null) + { + foreach (Control c in this.Parent.Controls) + { + if (c == this) + { + //c.TabStop = true; + continue; + } + CheckBoxX b = c as CheckBoxX; + if (b != null && b.Checked && b.CheckBoxStyle == eCheckBoxStyle.RadioButton) + { + b.Checked = false; + //b.TabStop = false; + previous = b; + } + } + } + + if (this.Command != null) + this.Command.Checked = this.Checked; + + CheckBoxXChangeEventArgs e1 = new CheckBoxXChangeEventArgs(previous, this, e.EventSource); + + if (CheckedChangedEx != null) + CheckedChangedEx(this, e1); + + if (CheckedChanged != null) + CheckedChanged(this, new EventArgs()); + + if (GetCheckState(m_CheckValue) != this.CheckState) + m_CheckValue = GetCheckValue(this.CheckState); + + if (CheckValueChanged != null) + CheckValueChanged(this, new EventArgs()); + + ExecuteCommand(); + } + + /// + /// Invokes CheckedChanging event. + /// + private void OnCheckedChanging(object sender, CheckBoxChangeEventArgs e) + { + CheckBoxXChangeEventArgs e1 = new CheckBoxXChangeEventArgs(null, this, e.EventSource); + + if (m_CheckBox.CheckBoxStyle == eCheckBoxStyle.RadioButton && !m_CheckBox.Checked && this.Parent != null) + { + CheckBoxX b = null; + foreach (Control c in this.Parent.Controls) + { + if (c == this) + continue; + b = c as CheckBoxX; + if (b != null && b.Checked && b.CheckBoxStyle == eCheckBoxStyle.RadioButton) + { + break; + } + } + e1 = new CheckBoxXChangeEventArgs(b, this, e.EventSource); + } + + if (CheckedChanging != null) + { + CheckedChanging(this, e1); + e.Cancel = e1.Cancel; + } + } + + /// + /// Gets or sets the appearance style of the item. Default value is CheckBox. Item can also assume the style of radio-button. + /// + [Browsable(true), DefaultValue(eCheckBoxStyle.CheckBox), Category("Appearance"), Description("Indicates appearance style of the item. Default value is CheckBox. Item can also assume the style of radio-button.")] + public eCheckBoxStyle CheckBoxStyle + { + get { return m_CheckBox.CheckBoxStyle; } + set + { + m_CheckBox.CheckBoxStyle = value; + } + } + + /// + /// Gets or sets the check box position relative to the text. Default value is Left. + /// + [Browsable(true), DefaultValue(eCheckBoxPosition.Left), Category("Appearance"), Description("Indicates the check box position relative to the text.")] + public eCheckBoxPosition CheckBoxPosition + { + get { return m_CheckBox.CheckBoxPosition; } + set + { + m_CheckBox.CheckBoxPosition = value; + } + } + + /// + /// Gets or set a value indicating whether the button is in the checked state. + /// + [Browsable(true), Bindable(true), DevCoBrowsable(true), Category("Appearance"), Description("Indicates whether item is checked or not."), DefaultValue(false)] + public virtual bool Checked + { + get + { + return m_CheckBox.Checked; + } + set + { + m_CheckBox.Checked = value; + } + } + + /// + /// Gets or sets whether text assigned to the check box is visible. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether text assigned to the check box is visible.")] + public bool TextVisible + { + get { return m_CheckBox.TextVisible; } + set + { + m_CheckBox.TextVisible = value; + this.RecalcLayout(); + } + } + + /// + /// Gets or sets the text color. Default value is Color.Empty which indicates that default color is used. + /// + [Browsable(true), Category("Appearance"), Description("Indicates text color.")] + public Color TextColor + { + get { return m_CheckBox.TextColor; } + set + { + m_CheckBox.TextColor = value; + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return !m_CheckBox.TextColor.IsEmpty; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + this.TextColor = Color.Empty; + } + + [Browsable(false)] + public override Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if (e.KeyCode == Keys.Space && this.Enabled && this.AutoCheck) + { + if (this.CheckBoxStyle == eCheckBoxStyle.CheckBox) + SetChecked(!this.Checked, eEventSource.Keyboard); + else if (!this.Checked) + SetChecked(true, eEventSource.Keyboard); + } + base.OnKeyDown(e); + } + + private void SetChecked(bool newValue, eEventSource source) + { + m_CheckBox.SetChecked(newValue, source); + } + + private void SetChecked(CheckState newValue, eEventSource source) + { + m_CheckBox.SetChecked(newValue, source); + } + + /// + /// Gets or sets the text associated with the control. + /// + [Browsable(true), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Appearance"), Description("Indicates text associated with this button.."), Localizable(true), DefaultValue("")] + public override string Text + { + get { return base.Text; } + set { base.Text = value; } + } + +#if FRAMEWORK20 + [Localizable(true), Browsable(false)] + public new System.Windows.Forms.Padding Padding + { + get { return base.Padding; } + set { base.Padding = value; } + } + + public override Size GetPreferredSize(Size proposedSize) + { + if (!BarFunctions.IsHandleValid(this)) + return base.GetPreferredSize(proposedSize); + if (this.Text.Length == 0) + return base.GetPreferredSize(proposedSize); + + m_CheckBox.RecalcSize(); + Size s = m_CheckBox.Size; + s.Width += 2; + s.Height += 2; + if (!this.TextVisible) s.Width += 2; + m_CheckBox.Bounds = GetItemBounds(); + return s; + } + + /// + /// Gets or sets a value indicating whether the control is automatically resized to display its entire contents. You can set MaximumSize.Width property to set the maximum width used by the control. + /// + [Browsable(true), DefaultValue(false), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override bool AutoSize + { + get + { + return base.AutoSize; + } + set + { + if (this.AutoSize != value) + { + base.AutoSize = value; + AdjustSize(); + } + } + } + + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + if (this.AutoSize) + { + Size preferredSize = base.PreferredSize; + width = preferredSize.Width; + height = preferredSize.Height; + } + base.SetBoundsCore(x, y, width, height, specified); + } + + private void AdjustSize() + { + if (this.AutoSize) + { + this.Size = base.PreferredSize; + } + } + + protected override void OnTextChanged(EventArgs e) + { + base.OnTextChanged(e); + this.AdjustSize(); + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + if (this.AutoSize) + this.AdjustSize(); + } +#endif + + /// + /// Gets or sets a value indicating whether the CheckBox will allow three check states rather than two. If the ThreeState property is set to true + /// CheckState property should be used instead of Checked property to set the extended state of the control. + /// + [Browsable(true), Category("Behavior"), DefaultValue(false), Description("Indicates whether the CheckBox will allow three check states rather than two.")] + public bool ThreeState + { + get { return m_CheckBox.ThreeState; } + set { m_CheckBox.ThreeState = value; } + } + + /// + /// Specifies the state of a control, such as a check box, that can be checked, unchecked, or set to an indeterminate state. + /// + [Browsable(true), Category("Behavior"), DefaultValue(CheckState.Unchecked), Description("Specifies the state of a control, such as a check box, that can be checked, unchecked, or set to an indeterminate state")] + public CheckState CheckState + { + get { return m_CheckBox.CheckState; } + set { m_CheckBox.CheckState = value; } + } + + /// + /// Gets the underlying CheckBoxItem + /// + internal CheckBoxItem CheckBoxItem + { + get { return (m_CheckBox); } + } + + private bool _EnableMnemonicWithAltKeyOnly = false; + /// + /// Gets or sets whether mnemonic character assigned to control is processed only if Alt key is pressed. Default value is false which indicate that Alt key is not required. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether mnemonic character assigned to control is processed only if Alt key is pressed")] + public bool EnableMnemonicWithAltKeyOnly + { + get { return _EnableMnemonicWithAltKeyOnly; } + set + { + _EnableMnemonicWithAltKeyOnly = value; + } + } + + protected override bool ProcessMnemonic(char charCode) + { + if (AutoCheck && CanSelect && IsMnemonic(charCode, this.Text) && this.Enabled && + (!_EnableMnemonicWithAltKeyOnly || Control.ModifierKeys == Keys.Alt || this.Focused) && !m_CheckBox.IsUsingTextMarkup) + { + if (Focus()) + { + if (this.CheckBoxStyle == eCheckBoxStyle.CheckBox) + SetChecked(!this.Checked, eEventSource.Keyboard); + else if (!this.Checked) + SetChecked(true, eEventSource.Keyboard); + return true; + } + } + return false; + } + #endregion + + #region Data-Binding Support + /// + /// Gets or set whether the Checked values and the item appearance are automatically changed when the Check-Box is clicked. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether the Checked values and the item appearance are automatically changed when the Check-Box is clicked.")] + public bool AutoCheck + { + get { return m_CheckBox.AutoCheck; } + set + { + m_CheckBox.AutoCheck = value; + } + } + /// + /// Gets or sets the object that represents the Checked state of control. + /// + [DefaultValue("N"), Bindable(true), RefreshProperties(RefreshProperties.All), TypeConverter(typeof(StringConverter)), Description("Indicates object that represents the Checked state of control.")] + public object CheckValue + { + get { return m_CheckValue; } + set + { + m_CheckValue = value; + OnCheckValueChanged(); + } + } + + private void OnCheckValueChanged() + { + CheckState cs = GetCheckState(m_CheckValue); + this.CheckState = cs; + } + + private bool IsNull(object value) + { + return value == null || value is string && (string)value == string.Empty && m_ConsiderEmptyStringAsNull || + value == DBNull.Value; + } + + private object GetCheckValue(CheckState cs) + { + if (cs == CheckState.Indeterminate) + return m_CheckValueIndeterminate; + + if (cs == CheckState.Unchecked) + return m_CheckValueUnchecked; + + return m_CheckValueChecked; + } + + private CheckState GetCheckState(object value) + { + if (m_CheckValueIndeterminate == null && IsNull(value) || m_CheckValueIndeterminate!=null && m_CheckValueIndeterminate.Equals(value)) + { + return CheckState.Indeterminate; + } + else if (m_CheckValueChecked == null && IsNull(value) || m_CheckValueChecked!=null && m_CheckValueChecked.Equals(value)) + { + return CheckState.Checked; + } + else if (m_CheckValueUnchecked == null && IsNull(value) || m_CheckValueUnchecked!=null && m_CheckValueUnchecked.Equals(value)) + { + return CheckState.Unchecked; + } + else + { + if (value is System.Data.SqlTypes.SqlBoolean) + { + System.Data.SqlTypes.SqlBoolean sqlBool = (System.Data.SqlTypes.SqlBoolean)value; + if (sqlBool.IsTrue) + return CheckState.Checked; + else if (sqlBool.IsNull) + return CheckState.Indeterminate; + else + return CheckState.Unchecked; + } + else if (value is int? && this.ThreeState) + { + if (value == null) return CheckState.Indeterminate; + if (((int?)value).Value == 0) + return CheckState.Unchecked; + return CheckState.Checked; + } + else if (value is int) + { + if (this.ThreeState && (int)value == -1) + return CheckState.Indeterminate; + return ((int)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is long) + { + if (this.ThreeState && (long)value == -1) + return CheckState.Indeterminate; + return ((long)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is short) + { + if (this.ThreeState && (short)value == -1) + return CheckState.Indeterminate; + return ((short)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is float) + { + if (this.ThreeState && (float)value == -1) + return CheckState.Indeterminate; + return ((float)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is double) + { + if (this.ThreeState && (double)value == -1) + return CheckState.Indeterminate; + return ((double)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is byte) + { + return ((byte)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is uint) + { + return ((uint)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is ulong) + { + return ((ulong)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is bool) + { + return ((bool)value) == false ? CheckState.Unchecked : CheckState.Checked; + } + + return CheckState.Indeterminate; + } + } + + /// + /// Gets or sets whether empty string is consider as null value during CheckValue value comparison. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Browsable(true), Description("Indicates whether empty string is consider as null value during CheckValue value comparison.")] + public bool ConsiderEmptyStringAsNull + { + get { return m_ConsiderEmptyStringAsNull; } + set { m_ConsiderEmptyStringAsNull = value; } + } + + /// + /// Gets or sets the value that represents the Indeterminate state of check box when CheckValue property is set to that value. Default value is null. + /// + [Browsable(true), DefaultValue(null), Category("Behavior"), TypeConverter(typeof(StringConverter)), Description("Represents the Indeterminate state value of check box when CheckValue property is set to that value")] + public object CheckValueIndeterminate + { + get { return m_CheckValueIndeterminate; } + set { m_CheckValueIndeterminate = value; OnCheckValueChanged(); } + } + + /// + /// Gets or sets the value that represents the Checked state of check box when CheckValue property is set to that value. Default value is null. + /// + [Browsable(true), DefaultValue("Y"), Category("Behavior"), TypeConverter(typeof(StringConverter)), Description("Represents the Checked state value of check box when CheckValue property is set to that value")] + public object CheckValueChecked + { + get { return m_CheckValueChecked; } + set { m_CheckValueChecked = value; OnCheckValueChanged(); } + } + + /// + /// Gets or sets the value that represents the Unchecked state of check box when CheckValue property is set to that value. Default value is null. + /// + [Browsable(true), DefaultValue("N"), Category("Behavior"), TypeConverter(typeof(StringConverter)), Description("Represents the Unchecked state value of check box when CheckValue property is set to that value")] + public object CheckValueUnchecked + { + get { return m_CheckValueUnchecked; } + set { m_CheckValueUnchecked = value; OnCheckValueChanged(); } + } + + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box is checked. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box is checked")] + public Image CheckBoxImageChecked + { + get { return m_CheckBox.CheckBoxImageChecked; } + set + { + m_CheckBox.CheckBoxImageChecked = value; + } + } + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box is unchecked. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box is unchecked")] + public Image CheckBoxImageUnChecked + { + get { return m_CheckBox.CheckBoxImageUnChecked; } + set + { + m_CheckBox.CheckBoxImageUnChecked = value; + } + } + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box is in indeterminate state. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box is in indeterminate state")] + public Image CheckBoxImageIndeterminate + { + get { return m_CheckBox.CheckBoxImageIndeterminate; } + set + { + m_CheckBox.CheckBoxImageIndeterminate = value; + } + } + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + CommandManager.ExecuteCommand(this); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + } + } + + private ICommand _Command = null; + //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if (changed) + OnCommandChanged(); + } + } + + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + Command command = this.Command; + if (command != null && command.Checked != this.Checked) + { + SetChecked(command.Checked, eEventSource.Code); + } + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + } + } + + #endregion + } + + /// + /// Delegate for OptionGroupChanging event. + /// + public delegate void CheckBoxXChangeEventHandler(object sender, CheckBoxXChangeEventArgs e); + + #region CheckBoxXChangeEventArgs + /// + /// Represents event arguments for OptionGroupChanging event. + /// + public class CheckBoxXChangeEventArgs : EventArgs + { + /// + /// Set to true to cancel the checking on NewChecked button. + /// + public bool Cancel = false; + /// + /// Check-box that will become checked if operation is not cancelled. + /// + public readonly CheckBoxX NewChecked; + /// + /// Check-box that is currently checked and which will be unchecked if operation is not cancelled. This property will have only valid values for eCheckBoxStyle.RadioButton style CheckBoxItems. + /// + public readonly CheckBoxX OldChecked; + /// + /// Indicates the action that has caused the event. + /// + public readonly eEventSource EventSource = eEventSource.Code; + + /// + /// Default constructor. + /// + public CheckBoxXChangeEventArgs(CheckBoxX oldchecked, CheckBoxX newchecked, eEventSource eventSource) + { + NewChecked = newchecked; + OldChecked = oldchecked; + EventSource = eventSource; + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/Controls/CheckBoxX.ico b/PROMS/DotNetBar Source Code/Controls/CheckBoxX.ico new file mode 100644 index 00000000..4d82de2b Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/CheckBoxX.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/CircularProgress.cs b/PROMS/DotNetBar Source Code/Controls/CircularProgress.cs new file mode 100644 index 00000000..f9e6a162 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/CircularProgress.cs @@ -0,0 +1,474 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(CircularProgress), "Controls.CircularProgress.ico"), ToolboxItem(true), DefaultEvent("ValueChanged")] + public class CircularProgress : BaseItemControl + { + #region Constructor + private CircularProgressItem _Item = null; + /// + /// Initializes a new instance of the CircularProgress class. + /// + public CircularProgress() + { + _Item = new CircularProgressItem(); + _Item.ValueChanged += new EventHandler(ItemValueChanged); + _Item.TextVisible = false; + this.HostItem = _Item; + } + #endregion + + #region Implementation + protected override void Dispose(bool disposing) + { + _Item.Dispose(); + base.Dispose(disposing); + } + protected override void RecalcSize() + { + _Item.Diameter = Math.Min(this.Width, this.Height); + base.RecalcSize(); + } + private void ItemValueChanged(object sender, EventArgs e) + { + OnValueChanged(e); + } + /// + /// Occurs when Value property has changed. + /// + public event EventHandler ValueChanged; + /// + /// Raises ValueChanged event. + /// + /// Provides event arguments. + protected virtual void OnValueChanged(EventArgs e) + { + EventHandler handler = ValueChanged; + if (handler != null) + handler(this, e); + } + + /// + /// Gets or sets the circular progress bar type. + /// + [DefaultValue(eCircularProgressType.Line), Category("Appearance"), Description("Indicates circular progress bar type.")] + public eCircularProgressType ProgressBarType + { + get { return _Item.ProgressBarType; } + set + { + _Item.ProgressBarType = value; + } + } + /// + /// Gets or sets the maximum value of the progress bar. + /// + [Description("Indicates maximum value of the progress bar."), Category("Behavior"), DefaultValue(100)] + public int Maximum + { + get { return _Item.Maximum; } + set + { + _Item.Maximum = value; + } + } + /// + /// Gets or sets the minimum value of the progress bar. + /// + [Description("Indicates minimum value of the progress bar."), Category("Behavior"), DefaultValue(0)] + public int Minimum + { + get { return _Item.Minimum; } + set + { + _Item.Minimum = value; + } + } + /// + /// Gets or sets the color of the progress percentage text. + /// + [Category("Appearance"), Description("Indicates color of progress percentage text")] + public Color ProgressTextColor + { + get { return _Item.ProgressTextColor; } + set { _Item.ProgressTextColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeProgressTextColor() + { + return _Item.ShouldSerializeProgressTextColor(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetProgressTextColor() + { + _Item.ResetProgressTextColor(); + } + + /// + /// Gets or sets whether text that displays the progress bar completion percentage text is visible. Default value is false. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether text that displays the progress bar completion percentage text is visible")] + public bool ProgressTextVisible + { + get { return _Item.ProgressTextVisible; } + set + { + _Item.ProgressTextVisible = value; + } + } + /// + /// Gets or sets the text displayed on top of the circular progress bar. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates text displayed on top of the circular progress bar.")] + public string ProgressText + { + get { return _Item.ProgressText; } + set + { + _Item.ProgressText = value; + } + } + /// + /// Gets or sets the current value of the progress bar. + /// + [Description("Indicates current value of the progress bar."), Category("Behavior"), DefaultValue(0)] + public int Value + { + get { return _Item.Value; } + set + { + _Item.Value = value; + } + } + + /// + /// Gets or sets whether endless type progress bar is running. + /// + [Browsable(false), DefaultValue(false)] + public bool IsRunning + { + get { return _Item.IsRunning; } + set + { + _Item.IsRunning = value; + } + } + /// + /// Gets or sets the color of the color of progress indicator. + /// + [Category("Columns"), Description("Indicates color of progress indicator.")] + public Color ProgressColor + { + get { return _Item.ProgressColor; } + set { _Item.ProgressColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeProgressColor() + { + return _Item.ShouldSerializeProgressColor(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetProgressColor() + { + _Item.ResetProgressColor(); + } + + ///// + ///// Gets or sets circular progress indicator diameter in pixels. + ///// + //[DefaultValue(24), Category("Appearance"), Description("Indicates circular progress indicator diameter in pixels.")] + //public int Diameter + //{ + // get { return _Item.Diameter; } + // set + // { + // _Item.Diameter = value; + // this.RecalcLayout(); + // } + //} + ///// + ///// Gets or sets the text position in relation to the circular progress indicator. + ///// + //[DefaultValue(eTextPosition.Left), Category("Appearance"), Description("Indicatesd text position in relation to the circular progress indicator.")] + //public eTextPosition TextPosition + //{ + // get { return _Item.TextPosition; } + // set + // { + // _Item.TextPosition = value; + // } + //} + ///// + ///// Gets or sets whether text/label displayed next to the item is visible. + ///// + //[DefaultValue(true), Category("Appearance"), Description("Indicates whether caption/label set using Text property is visible.")] + //public bool TextVisible + //{ + // get { return _Item.TextVisible; } + // set + // { + // _Item.TextVisible = value; + // } + //} + ///// + ///// Gets or sets the suggested text-width. If you want to make sure that text you set wraps over multiple lines you can set suggested text-width so word break is performed. + ///// + //[DefaultValue(0), Category("Appearance"), Description("Indicates suggested text-width. If you want to make sure that text you set wraps over multiple lines you can set suggested text-width so word break is performed.")] + //public int TextWidth + //{ + // get { return _Item.TextWidth; } + // set + // { + // _Item.TextWidth = value; + // } + //} + + ///// + ///// Gets or sets text padding. + ///// + //[Browsable(true), Category("Appearance"), Description("Gets or sets text padding."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + //public Padding TextPadding + //{ + // get { return _Item.TextPadding; } + //} + //[EditorBrowsable(EditorBrowsableState.Never)] + //public bool ShouldSerializeTextPadding() + //{ + // return _Item.ShouldSerializeTextPadding(); + //} + //[EditorBrowsable(EditorBrowsableState.Never)] + //public void ResetTextPadding() + //{ + // _Item.ResetTextPadding(); + //} + + //protected override void OnForeColorChanged(EventArgs e) + //{ + // _Item.TextColor = this.ForeColor; + // base.OnForeColorChanged(e); + //} + + /// + /// Gets or sets the color of the pie progress bar dark border. + /// + [Category("Pie"), Description("Indicates color of pie progress bar dark border.")] + public Color PieBorderDark + { + get { return _Item.PieBorderDark; } + set { _Item.PieBorderDark = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePieBorderDark() + { + return _Item.ShouldSerializePieBorderDark(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetPieBorderDark() + { + _Item.ResetPieBorderDark(); + } + /// + /// Gets or sets the color of the pie progress bar light border. + /// + [Category("Pie"), Description("Indicates color of pie progress bar light border. ")] + public Color PieBorderLight + { + get { return _Item.PieBorderLight; } + set { _Item.PieBorderLight = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePieBorderLight() + { + return _Item.ShouldSerializePieBorderLight(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetPieBorderLight() + { + _Item.ResetPieBorderLight(); + } + + /// + /// Gets or sets the color of the spoke progress bar dark border. + /// + [Category("Spoke"), Description("Indicates color of spoke progress bar dark border.")] + public Color SpokeBorderDark + { + get { return _Item.SpokeBorderDark; } + set { _Item.SpokeBorderDark = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSpokeBorderDark() + { + return _Item.ShouldSerializeSpokeBorderDark(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSpokeBorderDark() + { + _Item.ResetSpokeBorderDark(); + } + /// + /// Gets or sets the color of the spoke progress bar light border. + /// + [Category("Spoke"), Description("Indicates color of spoke progress bar light border..")] + public Color SpokeBorderLight + { + get { return _Item.SpokeBorderLight; } + set { _Item.SpokeBorderLight = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSpokeBorderLight() + { + return _Item.ShouldSerializeSpokeBorderLight(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSpokeBorderLight() + { + _Item.ResetSpokeBorderLight(); + } + + /// + /// Gets or sets format string for progress value. + /// + [DefaultValue("{0}%"), Category("Appearance"), Description("Indicates format string for progress value.")] + public string ProgressTextFormat + { + get { return _Item.ProgressTextFormat; } + set + { + _Item.ProgressTextFormat = value; + } + } + + /// + /// Gets or sets the animation speed for endless running progress. Lower number means faster running. + /// + [DefaultValue(100), Description("Indicates the animation speed for endless running progress. Lower number means faster running."), Category("Behavior")] + public int AnimationSpeed + { + get + { + return _Item.AnimationSpeed; + } + set + { + _Item.AnimationSpeed = value; + } + } + + /// + /// Starts the progress bar loop for endless type progress bar. Progress bar will continue to run until Stop() method is called. + /// + public void Start() + { + _Item.Start(); + } + + /// + /// Stops the progress bar loop for endless type progress bar. + /// + public void Stop() + { + _Item.Stop(false); + } + #endregion + + #region Property-Hiding + [Browsable(false)] + public override eDotNetBarStyle Style + { + get { return base.Style; } + set { base.Style = value;} + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Color ForeColor + { + get { return base.ForeColor; } + set { base.ForeColor = value; } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override RightToLeft RightToLeft + { + get { return base.RightToLeft; } + set { base.RightToLeft = value; } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Image BackgroundImage + { + get + { + return base.BackgroundImage; + } + set + { + base.BackgroundImage = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override ImageLayout BackgroundImageLayout + { + get + { + return base.BackgroundImageLayout; + } + set + { + base.BackgroundImageLayout = value; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/CircularProgress.ico b/PROMS/DotNetBar Source Code/Controls/CircularProgress.ico new file mode 100644 index 00000000..83dae94e Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/CircularProgress.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/CollapsibleSplitContainer.cs b/PROMS/DotNetBar Source Code/Controls/CollapsibleSplitContainer.cs new file mode 100644 index 00000000..2a5f91dd --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/CollapsibleSplitContainer.cs @@ -0,0 +1,558 @@ +using DevComponents.DotNetBar.Rendering; +using DevComponents.Editors; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Reflection; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(CollapsibleSplitContainer), "Controls.CollapsibleSplitContainer.ico")] + public class CollapsibleSplitContainer : SplitContainer + { + #region Constructor + /// + /// Initializes a new instance of the CollapsibleSplitContainer class. + /// + public CollapsibleSplitContainer() + { + ControlStyles cs = ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer; + this.SetStyle(cs, true); + object[] objArgs = new object[] { cs, true }; + MethodInfo mi = typeof(Control).GetMethod("SetStyle", BindingFlags.NonPublic | BindingFlags.Instance); + if (mi != null) + { + mi.Invoke(this.Panel1, objArgs); + mi.Invoke(this.Panel2, objArgs); + } + this.SplitterWidth = 20; + _OverrideCursorPropInfo = typeof(SplitContainer).GetProperty("OverrideCursor", BindingFlags.NonPublic | BindingFlags.Instance); + + this.SplitterMoved += SplitterMovedHandler; + } + + protected override void Dispose(bool disposing) + { + this.SplitterMoved -= SplitterMovedHandler; + base.Dispose(disposing); + } + #endregion + + #region Implementation + private Rectangle _NearCollapseButton = Rectangle.Empty; + private Rectangle _FarCollapseButton = Rectangle.Empty; + private eButtonState _NearCollapseButtonState = eButtonState.Normal, _FarCollapseButtonState = eButtonState.Normal; + private const int ButtonSpacing = 2; + + private void UpdateButtonLayout() + { + Rectangle r = this.SplitterRectangle; + Size buttonSize = new Size(this.SplitterWidth, this.SplitterWidth); + if (this.Orientation == System.Windows.Forms.Orientation.Horizontal) + { + if (_ButtonPosition == eSplitterButtonPosition.Near) + { + _NearCollapseButton = new Rectangle(r.X, r.Y, buttonSize.Width, buttonSize.Height); + _FarCollapseButton = new Rectangle(_NearCollapseButton.Right + ButtonSpacing, r.Y, buttonSize.Width, buttonSize.Height); + } + else if (_ButtonPosition == eSplitterButtonPosition.Center) + { + _NearCollapseButton = new Rectangle(r.X + (r.Width - (buttonSize.Width * 2 + ButtonSpacing)) / 2, r.Y, buttonSize.Width, buttonSize.Height); + _FarCollapseButton = new Rectangle(_NearCollapseButton.Right + ButtonSpacing, r.Y, buttonSize.Width, buttonSize.Height); + } + else if (_ButtonPosition == eSplitterButtonPosition.Far) + { + _NearCollapseButton = new Rectangle(r.Right - buttonSize.Width * 2 - ButtonSpacing, r.Y, buttonSize.Width, buttonSize.Height); + _FarCollapseButton = new Rectangle(_NearCollapseButton.Right + ButtonSpacing, r.Y, buttonSize.Width, buttonSize.Height); + } + } + else + { + if (_ButtonPosition == eSplitterButtonPosition.Near) + { + _NearCollapseButton = new Rectangle(r.X, r.Y, buttonSize.Width, buttonSize.Height); + _FarCollapseButton = new Rectangle(r.X, _NearCollapseButton.Bottom + ButtonSpacing, buttonSize.Width, buttonSize.Height); + } + else if (_ButtonPosition == eSplitterButtonPosition.Center) + { + _NearCollapseButton = new Rectangle(r.X, r.Y + (r.Height - (buttonSize.Height * 2 + ButtonSpacing)) / 2, buttonSize.Width, buttonSize.Height); + _FarCollapseButton = new Rectangle(r.X, _NearCollapseButton.Bottom + ButtonSpacing, buttonSize.Width, buttonSize.Height); + } + else if (_ButtonPosition == eSplitterButtonPosition.Far) + { + _NearCollapseButton = new Rectangle(r.X, r.Bottom - buttonSize.Height * 2 - ButtonSpacing, buttonSize.Width, buttonSize.Height); + _FarCollapseButton = new Rectangle(r.X, _NearCollapseButton.Bottom + ButtonSpacing, buttonSize.Width, buttonSize.Height); + } + } + } + + protected override void OnPaint(PaintEventArgs e) + { + UpdateButtonLayout(); + + base.OnPaint(e); + + Graphics g = e.Graphics; + bool isHorizontal = this.Orientation == System.Windows.Forms.Orientation.Horizontal; + + if (_NearCollapseButtonState != eButtonState.Hidden) + { + Office2007ButtonItemStateColorTable ct = GetOffice2007StateColorTable(_NearCollapseButtonState); + Office2007ButtonItemPainter.PaintBackground(g, ct, _NearCollapseButton, RoundRectangleShapeDescriptor.RectangleShape); + Rectangle r = _NearCollapseButton; + r.Inflate(-2, -2); + TextDrawing.DrawStringLegacy(g, isHorizontal ? "\uf077" : "\uf053", Symbols.GetFont(9f, eSymbolSet.Awesome), + ct.Text, r, eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter); + } + if (_FarCollapseButtonState != eButtonState.Hidden) + { + Office2007ButtonItemStateColorTable ct = GetOffice2007StateColorTable(_FarCollapseButtonState); + Office2007ButtonItemPainter.PaintBackground(g, ct, _FarCollapseButton, RoundRectangleShapeDescriptor.RectangleShape); + Rectangle r = _FarCollapseButton; + r.Inflate(-2, -2); + TextDrawing.DrawStringLegacy(g, isHorizontal ? "\uf078" : "\uf054", Symbols.GetFont(9f, eSymbolSet.Awesome), + ct.Text, r, eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter); + } + + + } + + protected Office2007ButtonItemStateColorTable GetOffice2007StateColorTable(eButtonState state) + { + if (GlobalManager.Renderer is Office2007Renderer) + { + Office2007ColorTable ct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + Office2007ButtonItemColorTable buttonColorTable = ct.ButtonItemColors[Enum.GetName(typeof(eButtonColor), eButtonColor.OrangeWithBackground)]; + if (!this.Enabled || state == eButtonState.Disabled) + return buttonColorTable.Disabled; + else if (state == eButtonState.MouseDownLeft) + return buttonColorTable.Pressed; + else if (state == eButtonState.MouseOver) + return buttonColorTable.MouseOver; + else + return buttonColorTable.Default; + } + + return null; + } + + private Orientation _CurrentOrientation = Orientation.Vertical; + protected override void OnLayout(LayoutEventArgs e) + { + base.OnLayout(e); + + if (_CurrentOrientation != this.Orientation) + { + _CurrentOrientation = this.Orientation; + UpdateButtonLayout(); + } + Invalidate(); + } + + private bool IsButtonActive(eButtonState state) + { + return state != eButtonState.Hidden && state != eButtonState.Disabled; + } + private Cursor _OriginalCursor = null; + protected override void OnMouseMove(MouseEventArgs e) + { + if (IsButtonActive(_NearCollapseButtonState)) + { + if (_NearCollapseButton.Contains(e.Location)) + { + if (_NearCollapseButtonState == eButtonState.Normal) + { + _NearCollapseButtonState = eButtonState.MouseOver; + this.Invalidate(); + } + } + else + { + _NearCollapseButtonState = eButtonState.Normal; + this.Invalidate(); + } + } + if (IsButtonActive(_FarCollapseButtonState)) + { + if (_FarCollapseButton.Contains(e.Location)) + { + if (_FarCollapseButtonState == eButtonState.Normal) + { + _FarCollapseButtonState = eButtonState.MouseOver; + this.Invalidate(); + } + } + else + { + _FarCollapseButtonState = eButtonState.Normal; + this.Invalidate(); + } + } + if (_NearCollapseButton.Contains(e.Location) || _FarCollapseButton.Contains(e.Location)) + { + if (_OriginalCursor == null && _OverrideCursorPropInfo != null) + { + _OriginalCursor = (Cursor)_OverrideCursorPropInfo.GetValue(this, null); + _OverrideCursorPropInfo.SetValue(this, Cursors.Default, null); + } + return; + } + + RestoreOriginalCursor(); + + base.OnMouseMove(e); + } + + private PropertyInfo _OverrideCursorPropInfo = null; + private void RestoreOriginalCursor() + { + if (_OriginalCursor != null) + { + _OverrideCursorPropInfo.SetValue(this, _OriginalCursor, null); ; + _OriginalCursor = null; + } + } + protected override void OnMouseDown(MouseEventArgs e) + { + if (IsButtonActive(_NearCollapseButtonState)) + { + if (_NearCollapseButton.Contains(e.Location) && e.Button == System.Windows.Forms.MouseButtons.Left) + { + _NearCollapseButtonState = eButtonState.MouseDownLeft; + this.Invalidate(); + } + } + if (IsButtonActive(_FarCollapseButtonState)) + { + if (_FarCollapseButton.Contains(e.Location) && e.Button == System.Windows.Forms.MouseButtons.Left) + { + _FarCollapseButtonState = eButtonState.MouseDownLeft; + this.Invalidate(); + } + } + if (_NearCollapseButton.Contains(e.Location) || _FarCollapseButton.Contains(e.Location)) + return; + base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + if (IsButtonActive(_NearCollapseButtonState)) + { + if (_NearCollapseButton.Contains(e.Location)) + { + if (_NearCollapseButtonState == eButtonState.MouseDownLeft) + { + _NearCollapseButtonState = eButtonState.MouseOver; + // Trigger button action + NearCollapseButtonClick(); + } + this.Invalidate(); + } + } + if (IsButtonActive(_FarCollapseButtonState)) + { + if (_FarCollapseButton.Contains(e.Location)) + { + if (_FarCollapseButtonState == eButtonState.MouseDownLeft) + { + _FarCollapseButtonState = eButtonState.MouseOver; + // Trigger button action + FarCollapseButtonClick(); + } + this.Invalidate(); + } + } + + if (_NearCollapseButton.Contains(e.Location) || _FarCollapseButton.Contains(e.Location)) + return; + + base.OnMouseUp(e); + } + + protected override void OnKeyUp(KeyEventArgs e) + { + base.OnKeyUp(e); + this.Invalidate(); + } + + // + /// Occurs before near collapse button is clicked and allows you to cancel its action. + /// + [Description("Occurs before near collapse button is clicked and allows you to cancel its action.")] + public event CancelEventHandler BeforeNearCollapseButtonClick; + /// + /// Raises BeforeNearCollapseButtonClick event. + /// + /// Provides event arguments. + protected virtual void OnBeforeNearCollapseButtonClick(CancelEventArgs e) + { + CancelEventHandler handler = BeforeNearCollapseButtonClick; + if (handler != null) + handler(this, e); + } + + /// + /// Occurs after near collapse button is clicked. + /// + [Description("Occurs after near collapse button is clicked.")] + public event EventHandler NearCollapseButtonClicked; + /// + /// Raises NearCollapseButtonClick event. + /// + /// Provides event arguments. + protected virtual void OnNearCollapseButtonClicked(EventArgs e) + { + EventHandler handler = NearCollapseButtonClicked; + if (handler != null) + handler(this, e); + } + + private int _OriginalSplitterDistance = 0; + private bool _IsPanel1Minimized = false; + private bool _IsPanel2Minimized = false; + private bool _InternalDistanceChange = false; + private void NearCollapseButtonClick() + { + CancelEventArgs e = new CancelEventArgs(); + OnBeforeNearCollapseButtonClick(e); + if (e.Cancel) return; + + if (_CollapseMode == eCollapseMode.PanelMinSize) + { + _InternalDistanceChange = true; + try + { + if (_IsPanel2Minimized) + { + this.SplitterDistance = _OriginalSplitterDistance; + _IsPanel2Minimized = false; + _FarCollapseButtonState = eButtonState.Normal; + } + else if (!_IsPanel1Minimized) + { + _OriginalSplitterDistance = this.SplitterDistance; + this.SplitterDistance = this.Panel1MinSize; + _IsPanel1Minimized = true; + _NearCollapseButtonState = eButtonState.Disabled; + } + } + finally + { + _InternalDistanceChange = false; + } + } + else + { + this.Panel1Collapsed = true; + } + + OnNearCollapseButtonClicked(EventArgs.Empty); + } + + /// + /// Occurs before far collapse button is clicked and allows you to cancel its action. + /// + [Description("Occurs before far collapse button is clicked and allows you to cancel its action.")] + public event CancelEventHandler BeforeFarCollapseButtonClick; + /// + /// Raises BeforeFarCollapseButtonClick event. + /// + /// Provides event arguments. + protected virtual void OnBeforeFarCollapseButtonClick(CancelEventArgs e) + { + CancelEventHandler handler = BeforeFarCollapseButtonClick; + if (handler != null) + handler(this, e); + } + + /// + /// Occurs after far collapse button is clicked. + /// + [Description("Occurs after far collapse button is clicked.")] + public event EventHandler FarCollapseButtonClicked; + /// + /// Raises FarCollapseButtonClick event. + /// + /// Provides event arguments. + protected virtual void OnFarCollapseButtonClicked(EventArgs e) + { + EventHandler handler = FarCollapseButtonClicked; + if (handler != null) + handler(this, e); + } + + private void FarCollapseButtonClick() + { + CancelEventArgs e=new CancelEventArgs(); + OnBeforeFarCollapseButtonClick(e); + if (e.Cancel) return; + + if (_CollapseMode == eCollapseMode.PanelMinSize) + { + _InternalDistanceChange = true; + + try + { + if (_IsPanel1Minimized) + { + this.SplitterDistance = _OriginalSplitterDistance; + _IsPanel1Minimized = false; + _NearCollapseButtonState = eButtonState.Normal; + } + else if (!_IsPanel2Minimized) + { + _OriginalSplitterDistance = this.SplitterDistance; + if (this.Orientation == System.Windows.Forms.Orientation.Vertical) + this.SplitterDistance = this.Width - this.Panel2MinSize; + else + this.SplitterDistance = this.Height - this.Panel2MinSize; + _IsPanel2Minimized = true; + _FarCollapseButtonState = eButtonState.Disabled; + } + } + finally + { + _InternalDistanceChange = false; + } + } + else + { + this.Panel2Collapsed = true; + } + + OnFarCollapseButtonClicked(EventArgs.Empty); + } + + private void SplitterMovedHandler(object sender, SplitterEventArgs e) + { + if (_InternalDistanceChange) return; + if(_IsPanel1Minimized) + { + _IsPanel1Minimized = false; + _NearCollapseButtonState = eButtonState.Normal; + } + else if (_IsPanel2Minimized) + { + _IsPanel2Minimized = false; + _FarCollapseButtonState = eButtonState.Normal; + } + } + + protected override void OnMouseEnter(EventArgs e) + { + base.OnMouseEnter(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + if (IsButtonActive(_NearCollapseButtonState)) + { + _NearCollapseButtonState = eButtonState.Normal; + } + if (IsButtonActive(_FarCollapseButtonState)) + { + _FarCollapseButtonState = eButtonState.Normal; + } + RestoreOriginalCursor(); + Invalidate(); + base.OnMouseLeave(e); + } + + private eSplitterButtonPosition _ButtonPosition = eSplitterButtonPosition.Near; + /// + /// Indicates position of buttons inside container. + /// + [DefaultValue(eSplitterButtonPosition.Near), Category("Appearance"), Description("Indicates position of buttons inside container.")] + public eSplitterButtonPosition ButtonPosition + { + get { return _ButtonPosition; } + set + { + if (value != _ButtonPosition) + { + eSplitterButtonPosition oldValue = _ButtonPosition; + _ButtonPosition = value; + OnButtonPositionChanged(oldValue, value); + } + } + } + /// + /// Called when ButtonPosition property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnButtonPositionChanged(eSplitterButtonPosition oldValue, eSplitterButtonPosition newValue) + { + UpdateButtonLayout(); + this.Invalidate(); + //OnPropertyChanged(new PropertyChangedEventArgs("ButtonPosition")); + } + + private eCollapseMode _CollapseMode = eCollapseMode.PanelMinSize; + /// + /// Specifies how panels are collapsed when collapse buttons are pressed. + /// + [DefaultValue(eCollapseMode.PanelMinSize), Category("Behavior"), Description("Specifies how panels are collapsed when collapse buttons are pressed.")] + public eCollapseMode CollapseMode + { + get { return _CollapseMode; } + set + { + if (value !=_CollapseMode) + { + eCollapseMode oldValue = _CollapseMode; + _CollapseMode = value; + OnCollapseModeChanged(oldValue, value); + } + } + } + /// + /// Called when CollapseMode property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCollapseModeChanged(eCollapseMode oldValue, eCollapseMode newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("CollapseMode")); + } + #endregion + } + + /// + /// Defines available positions for buttons inside CollapsibleSplitterContainer. + /// + public enum eSplitterButtonPosition + { + /// + /// Buttons are positioned on left or top side depending on orientation. + /// + Near, + /// + /// Buttons are positioned in center of container. + /// + Center, + /// + /// Buttons are positioned on right or bottom side depending on orientation. + /// + Far, + } + + /// + /// Defines collapse mode for the CollapsibleSplitContainer control. + /// + public enum eCollapseMode + { + /// + /// When buttons are pressed the splitter is positioned at the PanelMinSize. + /// + PanelMinSize, + /// + /// When buttons are pressed associated panel is collapsed through Panel1Collapsed or Panel2Collapsed properties. + /// + PanelCollapse + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/CollapsibleSplitContainer.ico b/PROMS/DotNetBar Source Code/Controls/CollapsibleSplitContainer.ico new file mode 100644 index 00000000..8d7682bc Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/CollapsibleSplitContainer.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/ColorPickerButton.cs b/PROMS/DotNetBar Source Code/Controls/ColorPickerButton.cs new file mode 100644 index 00000000..4b01ea46 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ColorPickerButton.cs @@ -0,0 +1,240 @@ +using System; +using System.Text; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the color picker button control. + /// + [ToolboxBitmap(typeof(ColorPickerButton), "Controls.ColorPickerButton.ico"), ToolboxItem(true), DefaultEvent("SelectedColorChanged"), Designer("DevComponents.DotNetBar.Design.ColorPickerButtonDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.Runtime.InteropServices.ComVisible(false)] + public class ColorPickerButton : ButtonX + { + #region Private Variables + #endregion + + #region Events + /// + /// Occurs when color is chosen from drop-down color picker or from Custom Colors dialog box. Selected color can be accessed through SelectedColor property. + /// + [Description("Occurs when color is chosen from drop-down color picker or from Custom Colors dialog box.")] + public event EventHandler SelectedColorChanged; + + /// + /// Occurs when mouse is moving over the colors presented by the color picker. You can use it to preview the color before it is selected. + /// + [Description("Occurs when mouse is moving over the colors presented by the color picker")] + public event ColorPreviewEventHandler ColorPreview; + #endregion + + #region Constructor + /// + /// Creates new instance of the object. + /// + public ColorPickerButton() + : base() + { + ColorPickerDropDown cp = GetColorPickerDropDown(); + cp.SelectedColorChanged += new EventHandler(InternalSelectedColorChanged); + cp.ColorPreview += new ColorPreviewEventHandler(InternalColorPreview); + } + #endregion + + #region Internal Implementation +#if FRAMEWORK20 + /// + /// Gets or sets the array of ColorItem objects that will be used as standard colors instead of built-in color palette. + /// See: http://www.devcomponents.com/kb2/?p=79 for instructions. + /// + [DefaultValue(null), Browsable(false), Category("Colors"), Description("Array of ColorItem objects that will be used as standard colors instead of built-in color palette.")] + public ColorItem[][] CustomStandardColors + { + get { return GetColorPickerDropDown().CustomStandardColors; } + set + { + GetColorPickerDropDown().CustomStandardColors = value; + } + } + /// + /// Gets or sets the array of ColorItem objects that will be used as theme colors instead of built-in color palette. + /// See: http://www.devcomponents.com/kb2/?p=79 for instructions. + /// + [DefaultValue(null), Browsable(false), Category("Colors"), Description("Array of ColorItem objects that will be used as theme colors instead of built-in color palette.")] + public ColorItem[][] CustomThemeColors + { + get { return GetColorPickerDropDown().CustomThemeColors; } + set + { + GetColorPickerDropDown().CustomThemeColors = value; + } + } +#endif + + /// + /// Displays the Colors dialog that allows user to choose the color or create a custom color. If new color is chosen the + /// SelectedColorChanged event is raised. + /// + public System.Windows.Forms.DialogResult DisplayMoreColorsDialog() + { + return GetColorPickerDropDown().DisplayMoreColorsDialog(); + } + + protected override ButtonItem CreateButtonItem() + { + return new ColorPickerDropDown(); + } + + private ColorPickerDropDown GetColorPickerDropDown() + { + return InternalItem as ColorPickerDropDown; + } + + private void InternalColorPreview(object sender, ColorPreviewEventArgs e) + { + OnColorPreview(e); + } + + /// + /// Raises the ColorPreview event. + /// + /// Provides event data. + protected virtual void OnColorPreview(ColorPreviewEventArgs e) + { + if (ColorPreview != null) + ColorPreview(this, e); + } + + private void InternalSelectedColorChanged(object sender, EventArgs e) + { + OnSelectedColorChanged(e); + ExecuteCommand(); + } + + /// + /// Gets whether command is executed when button is clicked. + /// + protected virtual bool ExecuteCommandOnClick + { + get { return false; } + } + + /// + /// Raises the SelectedColorChanged event. + /// + /// Provides event data. + protected virtual void OnSelectedColorChanged(EventArgs e) + { + if (SelectedColorChanged != null) + SelectedColorChanged(this, e); + } + + /// + /// Gets or sets the Owner Window that will be used as owner for the colors modal dialog when displayed. + /// + [Browsable(false), DefaultValue(null)] + public System.Windows.Forms.IWin32Window OwnerWindow + { + get { return GetColorPickerDropDown().OwnerWindow; } + set { GetColorPickerDropDown().OwnerWindow = value; } + } + + /// + /// Gets or sets more colors menu item is visible which allows user to open Custom Colors dialog box. Default value is true. + /// + [Browsable(true), DefaultValue(true), DevCoSerialize(), Category("Appearance"), Description("Indicates more colors menu item is visible which allows user to open Custom Colors dialog box.")] + public bool DisplayMoreColors + { + get { return GetColorPickerDropDown().DisplayMoreColors; } + set { GetColorPickerDropDown().DisplayMoreColors = value; } + } + + /// + /// Gets or sets the last selected color from either the drop-down or Custom Color dialog box. Default value is + /// Color.Empty. You can use SelectedColorChanged event to be notified when this property changes. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color SelectedColor + { + get { return GetColorPickerDropDown().SelectedColor; } + set { GetColorPickerDropDown().SelectedColor = value; } + } + + /// + /// Gets or sets whether theme colors are displayed on drop-down. Default value is true. + /// + [Browsable(true), DefaultValue(true), DevCoSerialize(), Category("Appearance"), Description("Indicates whether theme colors are displayed on drop-down.")] + public bool DisplayThemeColors + { + get { return GetColorPickerDropDown().DisplayThemeColors; } + set { GetColorPickerDropDown().DisplayThemeColors = value; } + } + + /// + /// Gets or sets whether standard colors are displayed on drop-down. Default value is true. + /// + [Browsable(true), DefaultValue(true), DevCoSerialize(), Category("Appearance"), Description("Indicates whether standard colors are displayed on drop-down.")] + public bool DisplayStandardColors + { + get { return GetColorPickerDropDown().DisplayStandardColors; } + set { GetColorPickerDropDown().DisplayStandardColors = value; } + } + + /// + /// Indicates whether SubItems collection is serialized. ColorPickerDropDown does not serialize the sub items. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSubItems() + { + return false; + } + + /// + /// Gets or sets the rectangle in Image coordinates where selected color will be painted. Setting this property will + /// have an effect only if Image property is used to set the image. Default value is an empty rectangle which indicates + /// that selected color will not be painted on the image. + /// + [Browsable(true), Description("Indicates rectangle in Image coordinates where selected color will be painted. Property will have effect only if Image property is used to set the image."), Category("Behaviour")] + public Rectangle SelectedColorImageRectangle + { + get { return GetColorPickerDropDown().SelectedColorImageRectangle; } + set { GetColorPickerDropDown().SelectedColorImageRectangle = value; } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSelectedColorImageRectangle() + { + return GetColorPickerDropDown().ShouldSerializeSelectedColorImageRectangle(); + } + + /// + /// Resets the property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSelectedColorImageRectangle() + { + GetColorPickerDropDown().ResetSelectedColorImageRectangle(); + } + + /// + /// Invokes the ColorPreview event. + /// + /// Provides data for the event. + public void InvokeColorPreview(ColorPreviewEventArgs e) + { + GetColorPickerDropDown().InvokeColorPreview(e); + } + + /// + /// Update the selected color image if the SelectedColorImageRectangle has been set and button is using Image property to display the image. + /// + public void UpdateSelectedColorImage() + { + GetColorPickerDropDown().UpdateSelectedColorImage(); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ColorPickerButton.ico b/PROMS/DotNetBar Source Code/Controls/ColorPickerButton.ico new file mode 100644 index 00000000..ef4b5644 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/ColorPickerButton.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/ComboBoxEx.bmp b/PROMS/DotNetBar Source Code/Controls/ComboBoxEx.bmp new file mode 100644 index 00000000..2195b5f9 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/ComboBoxEx.bmp differ diff --git a/PROMS/DotNetBar Source Code/Controls/ComboBoxEx.cs b/PROMS/DotNetBar Source Code/Controls/ComboBoxEx.cs new file mode 100644 index 00000000..3706d754 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ComboBoxEx.cs @@ -0,0 +1,2796 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using DevComponents.DotNetBar.Rendering; +using DevComponents.Editors; +using DevComponents.DotNetBar.TextMarkup; +using DevComponents.AdvTree; +using System.Reflection; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents enhanced Windows combo box control. + /// + [ToolboxBitmap(typeof(ComboBoxEx), "Controls.ComboBoxEx.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.ComboBoxExDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ComboBoxEx : System.Windows.Forms.ComboBox, ICommandSource + { + #region Constructor + /// + /// Represents the method that will handle the DropDownChange event. + /// + public delegate void OnDropDownChangeEventHandler(object sender, bool Expanded); + /// + /// Occurs when drop down portion of combo box is shown or hidden. + /// + public event OnDropDownChangeEventHandler DropDownChange; + + private eDotNetBarStyle m_Style = eDotNetBarStyle.Office2007; + private bool m_DefaultStyle = false; // Disables our drawing in WndProc + private bool m_MouseOver = false; + private bool m_MouseOverThumb = false; + private bool _DroppedDown = false; + //private System.Windows.Forms.Timer m_Timer; + private bool m_WindowsXPAware = false; + private bool m_DisableInternalDrawing = false; + private ImageList m_ImageList = null; + private int m_DropDownHeight = 0; + private IntPtr m_LastFocusWindow; + private IntPtr m_DropDownHandle = IntPtr.Zero; + private ComboTextBoxMsgHandler m_TextWindowMsgHandler = null; + //private ComboListBoxMsgHandler m_ListBoxMsgHandler = null; + + [DllImport("user32")] + private static extern bool ValidateRect(IntPtr hWnd, ref NativeFunctions.RECT pRect); + + [DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)] + private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); + private const uint GW_CHILD = 5; + + private bool m_PreventEnterBeep = false; + + private string m_WatermarkText = ""; + private bool m_Focused = false; + private Font m_WatermarkFont = null; + private Color m_WatermarkColor = SystemColors.GrayText; + private bool m_IsStandalone = true; + private Timer m_MouseOverTimer = null; + private Rectangle m_ThumbRect = Rectangle.Empty; + private bool _FocusHighlightEnabled = false; + private static Color _DefaultHighlightColor = Color.FromArgb(0xFF, 0xFF, 0x88); + private Color _FocusHighlightColor = _DefaultHighlightColor; + + /// + /// Creates new instance of ComboBoxEx. + /// + public ComboBoxEx() + : base() + { + if (!ColorFunctions.ColorsLoaded) + { + NativeFunctions.RefreshSettings(); + NativeFunctions.OnDisplayChange(); + ColorFunctions.LoadColors(); + } + m_MouseOverTimer = new Timer(); + m_MouseOverTimer.Interval = 10; + m_MouseOverTimer.Enabled = false; + m_MouseOverTimer.Tick += new EventHandler(MouseOverTimerTick); +#if FRAMEWORK20 + this.FlatStyle = FlatStyle.Flat; +#endif + StyleManager.Register(this); + } + #endregion + + #region Implementation + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + // Metro needs BackColor and ForeColor set + if (StyleManager.IsMetro(newStyle) || StyleManager.IsMetro(StyleManager.PreviousStyle) && !StyleManager.IsMetro(newStyle)) + StyleManager.UpdateAmbientColors(this); + } + + private bool _FocusCuesEnabled = true; + /// + /// Gets or sets whether control displays focus cues when focused. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether control displays focus cues when focused.")] + public virtual bool FocusCuesEnabled + { + get { return _FocusCuesEnabled; } + set + { + _FocusCuesEnabled = value; + if (this.Focused) this.Invalidate(); + } + } + + /// + /// Gets or sets whether control is stand-alone control. Stand-alone flag affects the appearance of the control in Office 2007 style. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates the appearance of the control.")] + public bool IsStandalone + { + get { return m_IsStandalone; } + set + { + m_IsStandalone = value; + } + } + + private bool _WatermarkEnabled = true; + /// + /// Gets or sets whether watermark text is displayed when control is empty. Default value is true. + /// + [DefaultValue(true), Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return _WatermarkEnabled; } + set { _WatermarkEnabled = value; this.Invalidate(); } + } + + /// + /// Gets or sets the watermark (tip) text displayed inside of the control when Text is not set and control does not have input focus. This property supports text-markup. + /// Note that WatermarkText is not compatible with the auto-complete feature of .NET Framework 2.0. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus."), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string WatermarkText + { + get { return m_WatermarkText; } + set + { + if (value == null) value = ""; + m_WatermarkText = value; + MarkupTextChanged(); + this.Invalidate(); + } + } + + private eWatermarkBehavior _WatermarkBehavior = eWatermarkBehavior.HideOnFocus; + /// + /// Gets or sets the watermark hiding behaviour. Default value indicates that watermark is hidden when control receives input focus. + /// + [DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior"), Description("Indicates watermark hiding behaviour.")] + public eWatermarkBehavior WatermarkBehavior + { + get { return _WatermarkBehavior; } + set { _WatermarkBehavior = value; this.Invalidate(); } + } + + private TextMarkup.BodyElement m_TextMarkup = null; + private void MarkupTextChanged() + { + m_TextMarkup = null; + + if (!TextMarkup.MarkupParser.IsMarkup(ref m_WatermarkText)) + return; + + m_TextMarkup = TextMarkup.MarkupParser.Parse(m_WatermarkText); + ResizeMarkup(); + } + + private void ResizeMarkup() + { + if (m_TextMarkup != null) + { + using (Graphics g = this.CreateGraphics()) + { + MarkupDrawContext dc = GetMarkupDrawContext(g); + m_TextMarkup.Measure(GetWatermarkBounds().Size, dc); + Size sz = m_TextMarkup.Bounds.Size; + m_TextMarkup.Arrange(new Rectangle(GetWatermarkBounds().Location, sz), dc); + } + } + } + private MarkupDrawContext GetMarkupDrawContext(Graphics g) + { + return new MarkupDrawContext(g, (m_WatermarkFont == null ? this.Font : m_WatermarkFont), m_WatermarkColor, this.RightToLeft == RightToLeft.Yes); + } + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark font."), DefaultValue(null)] + public Font WatermarkFont + { + get { return m_WatermarkFont; } + set { m_WatermarkFont = value; this.Invalidate(true); } + } + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return m_WatermarkColor; } + set { m_WatermarkColor = value; this.Invalidate(true); } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return m_WatermarkColor != SystemColors.GrayText; + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + this.WatermarkColor = SystemColors.GrayText; + } + + /// + /// Gets or sets the combo box background color. Note that in Office 2007 style back color of the control is automatically managed. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + private bool m_UseCustomBackColor = false; + /// + /// Gets or sets whether the BackColor value you set is used instead of the style back color automatically provided by the control. Default + /// value is false which indicates that BackColor property is automatically managed. Set this property to true and then set BackColor property + /// to make control use your custom back color. + /// + [Browsable(false), DefaultValue(false)] + public bool UseCustomBackColor + { + get { return m_UseCustomBackColor; } + set { m_UseCustomBackColor = value; } + } + + /// + /// Gets or sets value indicating whether system combo box appearance is used. Default value is false. + /// + [Browsable(false), Category("Behavior"), Description("Makes Combo box appear the same as built-in Combo box."), DefaultValue(false)] + public bool DefaultStyle + { + get + { + return m_DefaultStyle; + } + set + { + if (m_DefaultStyle != value) + { + m_DefaultStyle = value; + this.Invalidate(true); + } + } + } + + /// + /// Gets or sets value indicating whether the combo box is draw using the Windows XP Theme manager when running on Windows XP or theme aware OS. + /// + [Browsable(false), Category("Behavior"), Description("When running on WindowsXP draws control using the Windows XP Themes if theme manager is enabled."), DefaultValue(false)] + public bool ThemeAware + { + get + { + return m_WindowsXPAware; + } + set + { + if (m_WindowsXPAware != value) + { + m_WindowsXPAware = value; + if (!m_WindowsXPAware) + m_DefaultStyle = false; + else if (m_WindowsXPAware && BarFunctions.ThemedOS) + { + m_DefaultStyle = true; +#if FRAMEWORK20 + this.FlatStyle = FlatStyle.Standard; +#endif + } + } + } + } + + /// + /// Disables internal drawing support for the List-box portion of Combo-box. Default value is false which means that internal drawing code is used. If + /// you plan to provide your own drawing for combo box items you must set this property to True. + /// + [Browsable(true), Category("Behavior"), Description("Disables internal drawing support for the List-box portion of Combo-box."), DefaultValue(false)] + public bool DisableInternalDrawing + { + get + { + return m_DisableInternalDrawing; + } + set + { + if (m_DisableInternalDrawing != value) + m_DisableInternalDrawing = value; + } + } + + /// + /// Gets or sets whether combo box generates the audible alert when Enter key is pressed. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), System.ComponentModel.Category("Behavior"), System.ComponentModel.Description("Indicates whether combo box generates the audible alert when Enter key is pressed."), System.ComponentModel.DefaultValue(false)] + public bool PreventEnterBeep + { + get + { + return m_PreventEnterBeep; + } + set + { + m_PreventEnterBeep = value; + } + } + + /// + /// The ImageList control used by Combo box to draw images. + /// + [Browsable(true), Category("Behavior"), Description("The ImageList control used by Combo box to draw images."), DefaultValue(null)] + public System.Windows.Forms.ImageList Images + { + get + { + return m_ImageList; + } + set + { + m_ImageList = value; + } + } + + /// + /// Determines the visual style applied to the combo box when shown. Default style is Office 2007. + /// + [Browsable(true), Category("Appearance"), DefaultValue(eDotNetBarStyle.Office2007), Description("Determines the display of the item when shown.")] + public eDotNetBarStyle Style + { + get + { + return m_Style; + } + set + { + m_Style = value; + UpdateBackColor(); + this.Invalidate(true); + } + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + UpdateBackColor(); + SetupTextBoxMessageHandler(); + RemoveTheme(this.Handle); + if (_AutoItemHeight) + UpdateItemHeight(); + } + + /*protected override void OnHandleDestroyed(EventArgs e) + { + if(m_Timer!=null) + m_Timer.Enabled=false; + base.OnHandleDestroyed(e); + }*/ + + protected override void OnResize(EventArgs e) + { + ResizeMarkup(); + this.Invalidate(); + base.OnResize(e); + } + + private void MouseOverTimerTick(object sender, EventArgs e) + { + bool over = false; + + if (this.IsHandleCreated && this.Visible) + { + WinApi.RECT rw = new WinApi.RECT(); + WinApi.GetWindowRect(this.Handle, ref rw); + Rectangle r = rw.ToRectangle(); + if (r.Contains(Control.MousePosition)) + over = true; + Point p = this.PointToClient(Control.MousePosition); + if (m_ThumbRect.Contains(p)) + MouseOverThumb = true; + else + MouseOverThumb = false; + } + + if (!over) + { + SetMouseOverTimerEnabled(false); + m_MouseOver = false; + UpdateBackColor(); + this.Invalidate(); + if (this.ParentItem != null) this.ParentItem.HideToolTip(); + } + } + internal BaseItem ParentItem = null; + + private bool MouseOverThumb + { + get { return m_MouseOverThumb; } + set + { + if (m_MouseOverThumb != value) + { + m_MouseOverThumb = value; + this.Invalidate(); + } + } + } + + protected override void OnGotFocus(EventArgs e) + { + base.OnGotFocus(e); + if (!m_MouseOver) + m_MouseOver = true; + UpdateBackColor(); + this.Invalidate(true); + } + + protected override void OnLostFocus(EventArgs e) + { + //if(!this.ClientRectangle.Contains(this.PointToClient(Control.MousePosition))) + //m_MouseOver=false; + SetMouseOverTimerEnabled(true); + //Color c = GetComboColors().Background; + //if (this.BackColor != c) + //this.BackColor = c; + //if(!m_MouseOver) + // this.Refresh(); + m_LastFocusWindow = IntPtr.Zero; + base.OnLostFocus(e); + } + + private Timer m_DropDownTrackTimer = null; + private void StartDropDownTrackTimer() + { + if (m_DropDownTrackTimer == null) + { + m_DropDownTrackTimer = new Timer(); + m_DropDownTrackTimer.Tick += new EventHandler(DropDownTrackTimerTick); + m_DropDownTrackTimer.Interval = 200; + } + m_DropDownTrackTimer.Start(); + } + private void StopDropDownTrackTimer() + { + Timer t = m_DropDownTrackTimer; + m_DropDownTrackTimer = null; + if (t != null) + { + t.Stop(); + t.Dispose(); + } + } + + private void DropDownTrackTimerTick(object sender, EventArgs e) + { + DroppedDownInternal = (WinApi.SendMessage(this.Handle, (int)WinApi.WindowsMessages.CB_GETDROPPEDSTATE, IntPtr.Zero, IntPtr.Zero) != 0); + } + + private bool DroppedDownInternal + { + get + { + return _DroppedDown; + } + set + { + if (IsMultiColumnDropDown) + { + _DroppedDown = value; + return; + } + if (_DroppedDown != value) + { + StopDropDownTrackTimer(); + _DroppedDown = value; + this.Invalidate(); + + if (DropDownChange != null) + DropDownChange(this, _DroppedDown); +#if !FRAMEWORK20 + if(m_DroppedDown) + { + StartDropDownTrackTimer(); + } +#endif + if (!_DroppedDown) + ReleasePopupHandler(); + } + } + } + +#if FRAMEWORK20 + protected override void OnDropDownClosed(EventArgs e) + { + if (!IsMultiColumnDropDown) + { + DroppedDownInternal = false; + m_SelectedIndexInternal = this.SelectedIndex; + } + base.OnDropDownClosed(e); + } +#endif + + protected override void OnDropDown(EventArgs e) + { + base.OnDropDown(e); + if (!IsMultiColumnDropDown) + { + DroppedDownInternal = true; + } + } + + [DllImport("user32", CharSet = CharSet.Unicode)] + private static extern int SetWindowTheme(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] String pszSubAppName, [MarshalAs(UnmanagedType.LPWStr)] String pszSubIdList); + + private void RemoveTheme(IntPtr handle) + { + bool isXp = false; + if (System.Environment.Version.Major > 5) + isXp = true; + else if ((System.Environment.Version.Major == 5) && + (System.Environment.Version.Minor >= 1)) + isXp = true; + if (isXp) + SetWindowTheme(handle, " ", " "); + } + + #region Internal Combo Colors + private class InternalComboColors + { + public Color Background = SystemColors.Window; + public Color Border = SystemColors.Window; + public LinearGradientColorTable ThumbBackground = null; + public Color ThumbText = SystemColors.ControlText; + public LinearGradientColorTable ThumbBorderOuter = null; + public LinearGradientColorTable ThumbBorderInner = null; + } + + private InternalComboColors GetComboColors() + { + InternalComboColors c = new InternalComboColors(); + + bool bFocus = (m_MouseOverThumb || this.Focused || this.DroppedDownInternal && this.DropDownStyle != ComboBoxStyle.Simple); + if (bFocus && !this.Enabled) + bFocus = false; + + if (BarFunctions.IsOffice2007Style(this.Style) && GlobalManager.Renderer is Office2007Renderer) + { + Office2007ComboBoxColorTable colorTable = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.ComboBox; + Office2007ComboBoxStateColorTable stateColors = (IsToolbarStyle && !m_MouseOver ? colorTable.Default : colorTable.DefaultStandalone); + if (bFocus) + { + if (this.DroppedDown) + stateColors = colorTable.DroppedDown; + else if (bFocus) + stateColors = colorTable.MouseOver; + } + + c.Background = stateColors.Background; + c.Border = stateColors.Border; + c.ThumbBackground = stateColors.ExpandBackground; + c.ThumbText = stateColors.ExpandText; + c.ThumbBorderOuter = stateColors.ExpandBorderOuter; + c.ThumbBorderInner = stateColors.ExpandBorderInner; + } + else + { + ColorScheme cs = new ColorScheme(this.Style); + if (bFocus) + { + if (DroppedDownInternal) + { + c.ThumbBackground = new LinearGradientColorTable(cs.ItemPressedBackground, cs.ItemPressedBackground2, cs.ItemPressedBackgroundGradientAngle); + c.Border = cs.ItemPressedBorder; + c.ThumbText = cs.ItemPressedText; + } + else + { + if (m_MouseOverThumb) + c.ThumbBackground = new LinearGradientColorTable(cs.ItemHotBackground, cs.ItemHotBackground2, cs.ItemHotBackgroundGradientAngle); + else + c.ThumbBackground = new LinearGradientColorTable(cs.BarBackground, cs.BarBackground2, cs.BarBackgroundGradientAngle); + c.Border = cs.ItemHotBorder; + c.ThumbText = cs.ItemHotText; + } + } + else + { + c.ThumbBackground = new LinearGradientColorTable(cs.BarBackground, cs.BarBackground2, cs.BarBackgroundGradientAngle); + if (m_MouseOver || !IsToolbarStyle) + { + c.Border = cs.ItemHotBorder; + } + } + } + + if (_FocusHighlightEnabled && this.Enabled && this.Focused) + c.Background = _FocusHighlightColor; + else if (!this.Enabled) + { + c.Background = _DisabledBackColor.IsEmpty ? SystemColors.Control : _DisabledBackColor; + c.ThumbText = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor; ; + } + + return c; + } + #endregion + private ComboBoxPopupMsgHandler _PopupMsgHandler = null; + private void ReleasePopupHandler() + { + ComboBoxPopupMsgHandler handler = _PopupMsgHandler; + _PopupMsgHandler = null; + if (handler != null) + { + handler.ReleaseHandle(); + } + } + private void CreatePopupHandler(IntPtr handle) + { + if (_PopupMsgHandler == null) + { + _PopupMsgHandler = new ComboBoxPopupMsgHandler(); + _PopupMsgHandler.AssignHandle(handle); + } + } + protected override bool ProcessDialogKey(Keys keyData) + { + if (keyData == Keys.F4 && IsMultiColumnDropDown) + { + IsPopupOpen = !IsPopupOpen; + return true; + } + return base.ProcessDialogKey(keyData); + } + protected override void WndProc(ref Message m) + { + const int WM_PAINT = 0xF; + const int WM_PRINTCLIENT = 0x0318; + const int WM_CTLCOLORLISTBOX = 0x0134; + const int CB_ADDSTRING = 0x143; + const int CB_INSERTSTRING = 0x14A; + const int CB_DELETESTRING = 0x0144; + + WinApi.RECT rect = new WinApi.RECT(); + + switch (m.Msg) + { + case WM_CTLCOLORLISTBOX: + if (IsMultiColumnDropDown && base.DroppedDown) + { + BarUtilities.InvokeDelayed(new MethodInvoker(delegate { base.DroppedDown = false; }), 10); + break; + } + + if (BarFunctions.IsWindows7 && !IsMultiColumnDropDown) + { + if (m_DropDownHandle != m.LParam) + ReleasePopupHandler(); + + if (_PopupMsgHandler == null) + CreatePopupHandler(m.LParam); + } + + m_DropDownHandle = m.LParam; + + if (!IsMultiColumnDropDown && (m_DropDownHeight > 0 || this.Items.Count == 0)) // Reason for zero items check here is to set the height of popup in case that it was visible before with large number of items and now its deleted. The ComboBox has bug and it displays popup in last large size even though its empty. + { + WinApi.GetWindowRect(m.LParam, ref rect); + int height = m_DropDownHeight; + if (this.Items.Count == 0) + height = Math.Max(18, this.ItemHeight); + Point thisLocation = this.PointToScreen(Point.Empty); + if (rect.Top < thisLocation.Y) + rect.Top = thisLocation.Y + this.Height; + NativeFunctions.SetWindowPos(m.LParam, IntPtr.Zero, rect.Left, rect.Top, rect.Width, + height, NativeFunctions.SWP_NOACTIVATE); + } + break; + + case (int)WinApi.WindowsMessages.CB_GETDROPPEDSTATE: + + base.WndProc(ref m); + + if (m.Result == IntPtr.Zero && DroppedDownInternal && !IsMultiColumnDropDown) + DroppedDownInternal = false; + return; + + case NativeFunctions.WM_SETFOCUS: + if (m.WParam != this.Handle) + m_LastFocusWindow = m.WParam; + + break; + + case CB_ADDSTRING: + if (this.Items.Count > 0) + { + ComboItem cb = this.Items[this.Items.Count - 1] as ComboItem; + + if (cb != null) + cb.m_ComboBox = this; + } + break; + + case CB_INSERTSTRING: + int index = WinApi.ToInt(m.WParam); + + if (index >= 0 && index < this.Items.Count) + { + ComboItem cb = this.Items[index] as ComboItem; + + if (cb != null) + cb.m_ComboBox = this; + } + + m_SelectedIndexInternal = -1; + break; + + case CB_DELETESTRING: + m_SelectedIndexInternal = -1; + break; + + case NativeFunctions.WM_USER + 7: + if (this.DropDownStyle == ComboBoxStyle.DropDown && !m_Focused) + this.SelectionLength = 0; + + this.Invalidate(true); + return; + case (int)WinApi.WindowsMessages.WM_LBUTTONDOWN: + { + if (IsMultiColumnDropDown) + { + if (IsPopupOpen) + CloseMultiColumnDropDown(); + else if (DateTime.Now.Subtract(_MultiDropDownClosedAtTime).TotalMilliseconds > 500 && (this.Focused || this.Focus())) + { + OpenMultiColumnDropDown(); + } + return; // Don't call base + } + break; + } + case (int)WinApi.WindowsMessages.WM_REFLECTCOMMAND: + { + if (IsMultiColumnDropDown) + { + int wp = WinApi.HIWORD(m.WParam); + if (wp == CBN_DROPDOWN) + { + OpenMultiColumnDropDown(); + return; // Don't call base + } + else if (wp == CBN_CLOSEUP) + { + if (DateTime.Now.Subtract(_MultiDropDownOpenedAtTime).TotalMilliseconds > 900) + { + CloseMultiColumnDropDown(); + return; // Don't call base + } + } + } + break; + } + } + + if (m_DefaultStyle) + { + base.WndProc(ref m); + return; + } + + if ((m.Msg == WM_PAINT || m.Msg == WM_PRINTCLIENT) && DrawMode != DrawMode.Normal) + { + WinApi.GetWindowRect(m.HWnd, ref rect); + Rectangle r = new Rectangle(0, 0, rect.Width, rect.Height); + + if (m.Msg == WM_PAINT) + { + WinApi.PAINTSTRUCT ps = new WinApi.PAINTSTRUCT(); + + IntPtr hdc = WinApi.BeginPaint(m.HWnd, ref ps); + + using (Graphics gHdc = Graphics.FromHdc(hdc)) + { + using (BufferedBitmap bmp = new BufferedBitmap(gHdc, r)) + { + PaintComboBox(bmp.Graphics, r); + + bmp.Render(gHdc); + } + } + + WinApi.EndPaint(m.HWnd, ref ps); + } + else + { + using (Graphics g = Graphics.FromHdc(m.WParam)) + PaintComboBox(g, r); + } + + if (this.Parent is ItemControl) + ((ItemControl)this.Parent).UpdateKeyTipsCanvas(); + } + else + { + base.WndProc(ref m); + } + } + private const uint CBN_DROPDOWN = 7; + private const uint CBN_CLOSEUP = 8; + public override bool PreProcessMessage(ref Message m) + { + if (m.Msg == (int)WinApi.WindowsMessages.WM_REFLECTCOMMAND && IsMultiColumnDropDown) + { + if (WinApi.HIWORD(m.WParam) == CBN_DROPDOWN) + return false; + } + return base.PreProcessMessage(ref m); + } + + private void PaintComboBox(Graphics g, Rectangle r) + { + InternalComboColors colors = GetComboColors(); + + PaintComboBackground(g, r, colors); + PaintComboBorder(g, r, colors); + + Rectangle contentRect = PaintComboThumb(g, r, colors); + + int selectedIndex = SelectedIndex == -1 ? -1 : m_SelectedIndexInternal; + + if (m_SelectedIndexInternal == -1 && SelectedIndex >= 0) + selectedIndex = SelectedIndex; + + if (DropDownStyle == ComboBoxStyle.DropDownList) + { + if (Items.Count > 0 && (uint)selectedIndex < Items.Count) + { + DrawItemState state = DrawItemState.ComboBoxEdit; + + if (Enabled == false) + state |= DrawItemState.Disabled; + + else if (Focused == true) + state |= (DrawItemState.Focus | DrawItemState.Selected); + + g.SetClip(contentRect); + contentRect.Inflate(-1, -1); + OnDrawItem(new DrawItemEventArgs(g, Font, contentRect, + selectedIndex, state, ForeColor, BackColor)); + g.ResetClip(); + } + + if (ShouldDrawWatermark() == true) + DrawWatermark(g); + } + } + + private Rectangle PaintComboThumb(Graphics g, Rectangle r, InternalComboColors colors) + { + Rectangle contentRect = r; + contentRect.Inflate(-2, -2); + + if (this.DropDownStyle == ComboBoxStyle.Simple || !_RenderThumb) return contentRect; + + int thumbWidth = SystemInformation.HorizontalScrollBarThumbWidth; + Rectangle thumbRect = new Rectangle(r.Width - thumbWidth, r.Y, thumbWidth, r.Height); + if (RightToLeft == RightToLeft.Yes) + thumbRect = new Rectangle(r.X + 1, r.Y + 1, thumbWidth, r.Height - 2); + if (!this.IsToolbarStyle) + { + thumbRect.Y += 2; + thumbRect.Height -= 4; + thumbRect.Width -= 2; ; + if (RightToLeft == RightToLeft.Yes) + thumbRect.X += 2; + } + else if (!BarFunctions.IsOffice2007Style(this.Style)) + thumbRect.Inflate(-1, -1); + + if (RightToLeft == RightToLeft.Yes) + { + int diff = thumbRect.Right - contentRect.X + 2; + contentRect.Width -= diff; + contentRect.X += diff; + } + else + { + int diff = contentRect.Right - thumbRect.X + 2; + contentRect.Width -= diff; + } + //contentRect.Y++; + //contentRect.Height--; + + if (!this.IsToolbarStyle && BarFunctions.IsOffice2007Style(this.Style)) + { + Office2007ButtonItemPainter.PaintBackground(g, GetOffice2007StateColorTable(), thumbRect, RoundRectangleShapeDescriptor.RectangleShape); + } + else + { + if (colors.ThumbBackground != null) + DisplayHelp.FillRectangle(g, thumbRect, colors.ThumbBackground); + if (colors.ThumbBorderOuter != null) + DisplayHelp.DrawGradientRectangle(g, thumbRect, colors.ThumbBorderOuter, 1); + Rectangle innerBorder = thumbRect; + innerBorder.Inflate(-1, -1); + if (colors.ThumbBorderInner != null) + DisplayHelp.DrawGradientRectangle(g, innerBorder, colors.ThumbBorderInner, 1); + } + + using (SolidBrush brush = new SolidBrush(colors.ThumbText)) + DrawArrow(thumbRect, g, brush); + + m_ThumbRect = thumbRect; + return contentRect; + } + + internal Rectangle GetThumbRect(Rectangle r) + { + if (this.DropDownStyle == ComboBoxStyle.Simple || !_RenderThumb) + return (Rectangle.Empty); + + int thumbWidth = SystemInformation.HorizontalScrollBarThumbWidth; + Rectangle thumbRect = new Rectangle(r.Width - thumbWidth, r.Y, thumbWidth, r.Height); + + if (RightToLeft == RightToLeft.Yes) + thumbRect = new Rectangle(r.X + 1, r.Y + 1, thumbWidth, r.Height - 2); + + if (!this.IsToolbarStyle) + { + thumbRect.Y += 2; + thumbRect.Height -= 4; + thumbRect.Width -= 2; + + if (RightToLeft == RightToLeft.Yes) + thumbRect.X += 2; + } + else if (!BarFunctions.IsOffice2007Style(this.Style)) + thumbRect.Inflate(-1, -1); + + return (thumbRect); + } + + [Browsable(false)] + public bool IsToolbarStyle + { + get { return !m_IsStandalone; } + } + + private bool _RenderThumb = true; + /// + /// Gets or sets whether ComboBoxEx thumb button that displays drop-down is rendered. Default value is true. + /// + internal bool RenderThumb + { + get { return _RenderThumb; } + set + { + _RenderThumb = value; + } + } + + + private bool _RenderBorder = true; + /// + /// Gets or sets whether ComboBoxEx border is rendered. Default value is true. + /// + internal bool RenderBorder + { + get { return _RenderBorder; } + set + { + _RenderBorder = value; + } + } + + + protected Office2007ButtonItemStateColorTable GetOffice2007StateColorTable() + { + bool bFocus = (m_MouseOverThumb || this.DroppedDownInternal && this.DropDownStyle != ComboBoxStyle.Simple); + + if (GlobalManager.Renderer is Office2007Renderer) + { + Office2007ColorTable ct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + Office2007ButtonItemColorTable buttonColorTable = ct.ButtonItemColors[Enum.GetName(typeof(eButtonColor), eButtonColor.OrangeWithBackground)]; + if (!this.Enabled) + return buttonColorTable.Disabled; + else if (this.DroppedDownInternal) + return buttonColorTable.Checked; + else if (bFocus) + return buttonColorTable.MouseOver; + else + return buttonColorTable.Default; + } + + return null; + } + + private void PaintComboBorder(Graphics g, Rectangle controlBounds, InternalComboColors colors) + { + if (!_RenderBorder) return; + DisplayHelp.DrawRectangle(g, colors.Border, controlBounds); + } + + private void PaintComboBackground(Graphics g, Rectangle controlBounds, InternalComboColors colors) + { + if (this.UseCustomBackColor && !BackColor.IsEmpty) + DisplayHelp.FillRectangle(g, controlBounds, BackColor); + else + DisplayHelp.FillRectangle(g, controlBounds, colors.Background); + } + + private bool ShouldDrawWatermark() + { + if (_WatermarkEnabled && this.Enabled && (!this.Focused || _WatermarkBehavior == eWatermarkBehavior.HideNonEmpty) && this.Text == "" && this.SelectedIndex == -1) + return true; + return false; + } + + private void DrawWatermark(Graphics g) + { + if (m_TextMarkup != null) + { + MarkupDrawContext dc = GetMarkupDrawContext(g); + m_TextMarkup.Render(dc); + } + else + { + eTextFormat tf = eTextFormat.Left | eTextFormat.VerticalCenter; + + if (this.RightToLeft == RightToLeft.Yes) tf |= eTextFormat.RightToLeft; + //if (this.TextAlign == HorizontalAlignment.Left) + // tf |= eTextFormat.Left; + //else if (this.TextAlign == HorizontalAlignment.Right) + // tf |= eTextFormat.Right; + //else if (this.TextAlign == HorizontalAlignment.Center) + // tf |= eTextFormat.HorizontalCenter; + tf |= eTextFormat.EndEllipsis; + tf |= eTextFormat.WordBreak; + TextDrawing.DrawString(g, m_WatermarkText, (m_WatermarkFont == null ? this.Font : m_WatermarkFont), + m_WatermarkColor, GetWatermarkBounds(), tf); + } + } + + private Rectangle GetWatermarkBounds() + { + if (this.DropDownStyle != ComboBoxStyle.DropDownList && m_TextWindowMsgHandler != null) + { + WinApi.RECT rect = new WinApi.RECT(); + WinApi.GetWindowRect(m_TextWindowMsgHandler.Handle, ref rect); + return new Rectangle(0, 0, rect.Width, rect.Height); + } + + Rectangle r = new Rectangle(2, 0, this.Width - 2, this.Height); + r.Inflate(-2, -1); + int thumbSize = SystemInformation.HorizontalScrollBarThumbWidth; + r.Width -= thumbSize; + if (this.RightToLeft == RightToLeft.Yes) + r.X += thumbSize; + + return r; + } + + //private void CreateListBoxMsgHandler(IntPtr m_DropDownHandle) + //{ + // DisposeListBoxMsgHandler(); + // m_ListBoxMsgHandler = new ComboListBoxMsgHandler(); + // m_ListBoxMsgHandler.AssignHandle(m_DropDownHandle); + //} + + //private void DisposeListBoxMsgHandler() + //{ + // if (m_ListBoxMsgHandler != null) + // { + // m_ListBoxMsgHandler.ReleaseHandle(); + // m_ListBoxMsgHandler = null; + // } + //} + + private void DrawArrow(Rectangle r, Graphics g, Brush b) + { + Point[] p = new Point[3]; + p[0].X = r.Left + (r.Width - Dpi.Width4) / 2; + p[0].Y = r.Top + (r.Height - Dpi.Height3) / 2 + 1; + p[1].X = p[0].X + Dpi.Width5; + p[1].Y = p[0].Y; + p[2].X = p[0].X + Dpi.Width2; + p[2].Y = p[0].Y + Dpi.Height3; + g.FillPolygon(b, p); + } + + /*private void OnTimer(object sender, EventArgs e) + { + bool bRefresh=false; + + if(m_DroppedDown && !this.DroppedDown) + { + m_DroppedDown=false; + + if(DropDownChange!=null) + this.DropDownChange(this,false); + + m_DropDownHandle=IntPtr.Zero; + bRefresh=true; + } + + Point mousePos=this.PointToClient(Control.MousePosition); + if(!this.ClientRectangle.Contains(mousePos)) + { + if(m_MouseOver && !m_DroppedDown) + { + m_MouseOver=false; + bRefresh=true; + } + } + else if(!m_MouseOver) + { + m_MouseOver=true; + bRefresh=true; + } + + if(bRefresh) + this.Refresh(); + }*/ + + protected override void OnVisibleChanged(EventArgs e) + { + base.OnVisibleChanged(e); + m_MouseOver = false; + if (this.DropDownStyle == ComboBoxStyle.DropDown && this.Items.Count > 0 && this.Items[0] is ComboItem && this.DisplayMember != "") + { + string s = this.DisplayMember; + this.DisplayMember = ""; + this.DisplayMember = s; + } + if (this.IsHandleCreated && !this.IsDisposed) + { + UpdateBackColor(); + } + if (!this.Visible && IsMultiColumnDropDown && IsPopupOpen) + IsPopupOpen = false; + } + + private int m_SelectedIndexInternal = -1; + private bool _InSelectedIndexChanged = false; + protected override void OnSelectedIndexChanged(EventArgs e) + { + m_SelectedIndexInternal = this.SelectedIndex; + + if (!this.DroppedDownInternal) + { + if (DroppedDownInternal) + { + DroppedDownInternal = false; + } + if (!m_MouseOver) + this.Invalidate(true); + } + if (this.SelectedIndex == -1 && _WatermarkBehavior == eWatermarkBehavior.HideNonEmpty && m_WatermarkText.Length > 0 && this.Text == "") + this.Invalidate(true); + else if (this.DropDownStyle == ComboBoxStyle.DropDownList) + this.Invalidate(); + + base.OnSelectedIndexChanged(e); + + if (!_InSelectedIndexChanged && this.DropDownStyle != ComboBoxStyle.DropDown && !(this.SelectedItem is string)) + { + try + { + _InSelectedIndexChanged = true; + if (this.SelectedItem == null) + this.Text = ""; + else + { + this.Text = GetItemText(this.SelectedItem); + } + } + finally + { + _InSelectedIndexChanged = false; + } + } + + ExecuteCommand(); + } + + public override string Text + { + get + { + if (this.DropDownStyle == ComboBoxStyle.DropDownList && this.SelectedItem != null && !(this.SelectedItem is string)) + return GetItemText(this.SelectedItem); + return base.Text; + } + set + { + base.Text = value; + } + } + + protected override void OnTextChanged(EventArgs e) + { + if (this.SelectedIndex == -1 && _WatermarkBehavior == eWatermarkBehavior.HideNonEmpty && m_WatermarkText.Length > 0 && this.Text == "") + this.Invalidate(true); + base.OnTextChanged(e); + } + + /*protected override void OnEnabledChanged(EventArgs e) + { + base.OnEnabledChanged(e); + SyncTimerEnabled(); + }*/ + + /*private void SyncTimerEnabled() + { + if(this.Visible) + { + if(!m_Timer.Enabled && this.Enabled && !this.DesignMode) + m_Timer.Enabled=true; + } + else + { + if(m_Timer.Enabled) + m_Timer.Enabled=false; + } + }*/ + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + if (Dpi.RecordScalePerControl) + Dpi.SetScaling(factor); + base.ScaleControl(factor, specified); + + if (_AutoItemHeight && !this.DesignMode) + UpdateItemHeight(); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + /*if(m_Timer!=null) + { + if(m_Timer.Enabled) + m_Timer.Enabled=false; + m_Timer.Dispose(); + m_Timer=null; + }*/ + if (m_MouseOverTimer != null) + { + m_MouseOverTimer.Enabled = false; + m_MouseOverTimer.Dispose(); + m_MouseOverTimer = null; + } + m_DisableInternalDrawing = true; + if (m_TextWindowMsgHandler != null) + { + m_TextWindowMsgHandler.ReleaseHandle(); + m_TextWindowMsgHandler = null; + } + ReleasePopupHandler(); + if (_MultiColumnDisplay != null) + { + _MultiColumnDisplay.AfterNodeSelect -= TreeAfterNodeSelect; + _MultiColumnDisplay.BeforeNodeSelect -= TreeBeforeNodeSelect; + _MultiColumnDisplay.NodeMouseDown -= TreeNodeMouseDown; + _MultiColumnDisplay.DataColumnCreated -= TreeDataColumnCreated; + _MultiColumnDisplay.KeyDown -= TreeKeyDown; + _MultiColumnDisplay.Dispose(); + _MultiColumnDisplay = null; + } + if (_PopupController != null) + { + _PopupController.Closed -= PopupControllerClosed; + _PopupController.Dispose(); + _PopupController = null; + } + base.Dispose(disposing); + } + + protected override void OnFontChanged(EventArgs e) + { + base.OnFontChanged(e); + UpdateItemHeight(); + } + + private bool _AutoItemHeight = true; + /// + /// Indicates whether ItemHeight property is set automatically based on the current font when DrawMode=OwnerDrawFixed + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether ItemHeight property is set automatically based on the current font when DrawMode=OwnerDrawFixed")] + public bool AutoItemHeight + { + get + { + return _AutoItemHeight; + } + set + { + _AutoItemHeight = value; + if (this.IsHandleCreated && value) + UpdateItemHeight(); + } + } + + private void UpdateItemHeight() + { + if (this.Disposing || this.IsDisposed) + return; + if (!m_DisableInternalDrawing && this.DrawMode == DrawMode.OwnerDrawFixed) + { + if (this.IsHandleCreated && this.Parent != null && !this.Parent.IsDisposed) + { + this.ItemHeight = this.FontHeight + 2; + } + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public int GetFontHeight() + { + return this.FontHeight; + } + + protected override void OnMeasureItem(MeasureItemEventArgs e) + { + base.OnMeasureItem(e); + if (!m_DisableInternalDrawing) + { + if (this.DrawMode == DrawMode.OwnerDrawFixed) + { + e.ItemHeight = this.ItemHeight - 2; + } + else + { + object o = this.Items[e.Index]; + if (o is ComboItem) + { + if (((ComboItem)o).IsFontItem) + MeasureFontItem(e); + else + { + Size sz = GetComboItemSize(o as ComboItem); + e.ItemHeight = sz.Height; + e.ItemWidth = sz.Width; + if (BarFunctions.IsOffice2007Style(m_Style)) + { + e.ItemHeight += 6; + e.ItemWidth += 6; + } + } + } + } + } + } + + protected override void OnDrawItem(DrawItemEventArgs e) + { + base.OnDrawItem(e); + InternalDrawItem(e); + } + + private void InternalDrawItem(DrawItemEventArgs e) + { + if (!m_DisableInternalDrawing && e.Index >= 0) + { + object o = this.Items[e.Index]; + if (o is ComboItem) + DrawComboItem(e); + else + DrawObjectItem(e); + } + } + + protected virtual Size GetComboItemSize(ComboItem item) + { + Size size = Size.Empty; + if (BarFunctions.IsHandleValid(this)) + { + Graphics g = this.CreateGraphics(); + try + { + size = GetComboItemSize(item, g); + } + finally + { + g.Dispose(); + } + } + return size; + } + + protected virtual void DrawObjectItem(DrawItemEventArgs e) + { + Graphics g = e.Graphics; + string text = GetItemText(this.Items[e.Index]); + Color textColor = Color.Empty; + Office2007ButtonItemStateColorTable ct = null; + + if (BarFunctions.IsOffice2007Style(m_Style)) + { + Office2007ButtonItemColorTable bct = GetComboItemColor(); + if ((e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0) + { + ct = bct.MouseOver; + if (textColor.IsEmpty) + textColor = ct.Text; + } + else if ((e.State & DrawItemState.Disabled) != 0 || !this.Enabled) + ct = bct.Disabled; + else + ct = bct.Default; + + //if (ct != null) + // textColor = ct.Text; + if ((e.State & DrawItemState.Disabled) != 0 || !this.Enabled) + textColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor; + else if (textColor.IsEmpty) + textColor = this.ForeColor; + if ((e.State & DrawItemState.HotLight) != 0 || (e.State & DrawItemState.Selected) != 0) + { + Rectangle r = e.Bounds; + //r.Width--; + //r.Height--; + if ((e.State & DrawItemState.ComboBoxEdit) != 0) r.Inflate(1, 1); + Office2007ButtonItemPainter.PaintBackground(g, ct, r, + (StyleManager.IsMetro(this.Style) ? RoundRectangleShapeDescriptor.RectangleShape : RoundRectangleShapeDescriptor.RoundCorner2)); + } + else + e.DrawBackground(); + } + else + { + e.DrawBackground(); + + if ((e.State & DrawItemState.HotLight) != 0 || (e.State & DrawItemState.Selected) != 0) + { + g.FillRectangle(SystemBrushes.Highlight, e.Bounds); + textColor = SystemColors.HighlightText; + } + else if ((e.State & DrawItemState.Disabled) != 0 || (e.State & DrawItemState.Grayed) != 0) + textColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor; + else if (this.ForeColor.IsEmpty) + textColor = SystemColors.ControlText; + else + textColor = this.ForeColor; + } + + if ((e.State & DrawItemState.Focus) != 0) + DrawFocusRectangle(e); + Rectangle rText = e.Bounds; + + if ((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit) + { + //rText.Inflate(-1, 0); + + } + else if (BarFunctions.IsOffice2007Style(m_Style)) + rText.Inflate(-3, 0); + else + rText.Inflate(-2, 0); + TextDrawing.DrawString(g, text, this.Font, textColor, rText, eTextFormat.Default | eTextFormat.NoClipping | eTextFormat.NoPrefix); + } + + private Office2007ButtonItemColorTable _ComboItemColors = null; + /// + /// Gets or sets the custom color table used to render combo-box items + /// + [DefaultValue(null), Browsable(false)] + public Office2007ButtonItemColorTable ComboItemColors + { + get { return _ComboItemColors; } + set { _ComboItemColors = value; } + } + + protected virtual Office2007ButtonItemColorTable GetComboItemColor() + { + if (_ComboItemColors != null) return _ComboItemColors; + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.ButtonItemColors[0]; + } + + private void DrawFocusRectangle(DrawItemEventArgs e) + { + if (_FocusCuesEnabled && ((e.State & DrawItemState.Focus) == DrawItemState.Focus) && ((e.State & DrawItemState.NoFocusRect) != DrawItemState.NoFocusRect) + && ((e.State & DrawItemState.NoFocusRect) == DrawItemState.ComboBoxEdit)) + { + Rectangle r = e.Bounds; + r.Inflate(2, 2); + //r.Width--; + //r.Height--; + ControlPaint.DrawFocusRectangle(e.Graphics, r, e.ForeColor, e.BackColor); + } + } + + private Color _DisabledForeColor = Color.Empty; + /// + /// Gets or sets the text color for the text in combo-box when control Enabled property is set to false. + /// Setting this property is effective only for DropDownList ComboBox style. + /// + [Category("Appearance"), Description("Indicates text color for the text in combo-box when control Enabled property is set to false. Setting this property is effective only for DropDownList ComboBox style.")] + public Color DisabledForeColor + { + get { return _DisabledForeColor; } + set + { + _DisabledForeColor = value; + if (!this.Enabled) + this.Invalidate(); + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool ShouldSerializeDisabledForeColor() + { + return !_DisabledForeColor.IsEmpty; + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public void ResetDisabledForeColor() + { + DisabledForeColor = Color.Empty; + } + + private Color _DisabledBackColor = Color.Empty; + /// + /// Gets or sets the control background color when control is disabled. Default value is an empty color which indicates that system background color is used when control is disabled. + /// + [Description("Indicates control background color when control is disabled"), Category("Appearance")] + public Color DisabledBackColor + { + get { return _DisabledBackColor; } + set + { + if (_DisabledBackColor != value) + { + _DisabledBackColor = value; + if (!this.Enabled) this.Invalidate(); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeDisabledBackColor() + { + return !_DisabledBackColor.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetDisabledBackColor() + { + DisabledBackColor = Color.Empty; + } + + protected virtual void DrawComboItem(DrawItemEventArgs e) + { + ComboItem item = this.Items[e.Index] as ComboItem; + if (item.IsFontItem) + { + this.DrawFontItem(e); + return; + } + + Graphics g = e.Graphics; + Image img = null; + Color clr; + Color textColor = item.ForeColor; + + if (item.ImageIndex >= 0 && m_ImageList != null && m_ImageList.Images.Count > item.ImageIndex) + img = m_ImageList.Images[item.ImageIndex]; + else if (item.Image != null) + img = item.Image; + + Office2007ButtonItemStateColorTable ct = null; + if (BarFunctions.IsOffice2007Style(m_Style)) + { + Office2007ButtonItemColorTable bct = GetComboItemColor(); + if ((e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0) + { + ct = bct.MouseOver; + if (textColor.IsEmpty) + textColor = ct.Text; + } + else if ((e.State & DrawItemState.Disabled) != 0 || !this.Enabled) + ct = bct.Disabled; + else + ct = bct.Default; + //if (ct == null) + if (!this.Enabled) + textColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor; + } + + if (textColor.IsEmpty) + textColor = this.ForeColor; + + int contWidth = this.DropDownWidth; + if (item.ImagePosition != HorizontalAlignment.Center && img != null) + { + contWidth -= img.Width; + if (contWidth <= 0) + contWidth = this.DropDownWidth; + } + + // Back Color + if ((e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0) + { + Rectangle backBounds = e.Bounds; + if ((e.State & DrawItemState.ComboBoxEdit) != 0) + backBounds.Inflate(1, 1); + if (BarFunctions.IsOffice2007Style(m_Style)) + Office2007ButtonItemPainter.PaintBackground(g, ct, backBounds, + (StyleManager.IsMetro(this.Style) ? RoundRectangleShapeDescriptor.RectangleShape : RoundRectangleShapeDescriptor.RoundCorner2)); + else + e.DrawBackground(); + DrawFocusRectangle(e); + } + else + { + clr = item.BackColor; + if (item.BackColor.IsEmpty) + clr = e.BackColor; + using (SolidBrush clrb = new SolidBrush(clr)) + g.FillRectangle(clrb, e.Bounds); + } + + // Draw Image + Rectangle rImg = e.Bounds; + Rectangle rText = e.Bounds; + //if (e.State != DrawItemState.ComboBoxEdit) + { + if ((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit) + { + if (img != null) + { + rText.X += 3; + rText.Width -= 3; + } + //rText.Inflate(-1, 0); + //rText.Y++; + //rText.Height--; + } + else if (BarFunctions.IsOffice2007Style(m_Style)) + rText.Inflate(-3, 0); + else + rText.Inflate(-2, 0); + } + if (img != null) + { + rImg.Width = img.Width; + rImg.Height = img.Height; + if (item.ImagePosition == HorizontalAlignment.Left) + { + // Left + if (e.Bounds.Height > img.Height) + rImg.Y += (e.Bounds.Height - img.Height) / 2; + rText.Width -= rImg.Width; + rText.X += rImg.Width; + } + else if (item.ImagePosition == HorizontalAlignment.Right) + { + // Right + if (e.Bounds.Height > img.Height) + rImg.Y += (e.Bounds.Height - img.Height) / 2; + rImg.X = e.Bounds.Right - img.Width; + rText.Width -= rImg.Width; + } + else + { + // Center + rImg.X += (e.Bounds.Width - img.Width) / 2; + rText.Y = rImg.Bottom; + } + g.DrawImage(img, rImg); + } + + // Draw Text + if (item.Text != "") + { + System.Drawing.Font f = e.Font; + bool bDisposeFont = false; + try + { + if (item.FontName != "") + { + f = new Font(item.FontName, item.FontSize, item.FontStyle); + bDisposeFont = true; + } + else if (item.FontStyle != f.Style) + { + f = new Font(f, item.FontStyle); + bDisposeFont = true; + } + } + catch + { + f = e.Font; + if (f == null) + { + f = SystemFonts.DefaultFont; // System.Windows.Forms.SystemInformation.MenuFont.Clone() as Font; + bDisposeFont = true; + } + } + + eTextFormat format = eTextFormat.Default | eTextFormat.NoClipping | eTextFormat.NoPrefix; + if (item.TextFormat.Alignment == StringAlignment.Center) + format = eTextFormat.HorizontalCenter; + else if (item.TextFormat.Alignment == StringAlignment.Far) + format = eTextFormat.Right; + if (item.TextLineAlignment == StringAlignment.Center) + format |= eTextFormat.VerticalCenter; + else if (item.TextLineAlignment == StringAlignment.Far) + format |= eTextFormat.Bottom; + TextDrawing.DrawString(g, item.Text, f, textColor, rText, format); + + if (bDisposeFont) + f.Dispose(); + } + + } + + protected virtual Size GetComboItemSize(ComboItem item, Graphics g) + { + if (this.DrawMode == DrawMode.OwnerDrawFixed) + return new Size(this.DropDownWidth, this.ItemHeight); + + Size sz = Size.Empty; + Size textSize = Size.Empty; + Image img = null; + if (item.ImageIndex >= 0) + img = m_ImageList.Images[item.ImageIndex]; + else if (item.Image != null) + img = item.Image; + + int contWidth = this.DropDownWidth; + if (item.ImagePosition != HorizontalAlignment.Center && img != null) + { + contWidth -= img.Width; + if (contWidth <= 0) + contWidth = this.DropDownWidth; + } + + Font font = this.Font; + if (item.FontName != "") + { + try + { + font = new Font(item.FontName, item.FontSize, item.FontStyle); + } + catch + { + font = this.Font; + } + } + + eTextFormat format = eTextFormat.Default; + if (item.TextFormat.Alignment == StringAlignment.Center) + format = eTextFormat.HorizontalCenter; + else if (item.TextFormat.Alignment == StringAlignment.Far) + format = eTextFormat.Right; + if (item.TextLineAlignment == StringAlignment.Center) + format |= eTextFormat.VerticalCenter; + else if (item.TextLineAlignment == StringAlignment.Far) + format |= eTextFormat.Bottom; + + textSize = TextDrawing.MeasureString(g, item.Text, font, this.DropDownWidth, format); + textSize.Width += 2; + sz.Width = textSize.Width; + sz.Height = textSize.Height; + if (sz.Width < this.DropDownWidth) + sz.Width = this.DropDownWidth; + + if (item.ImagePosition == HorizontalAlignment.Center && img != null) + sz.Height += img.Height; + else if (img != null && img.Height > sz.Height) + sz.Height = img.Height; + + return sz; + } + + /// + /// Loads all fonts available on system into the combo box. + /// + public void LoadFonts() + { + this.Items.Clear(); + + System.Drawing.Text.InstalledFontCollection colInstalledFonts = new System.Drawing.Text.InstalledFontCollection(); + FontFamily[] aFamilies = colInstalledFonts.Families; + foreach (FontFamily ff in aFamilies) + { + ComboItem item = new ComboItem(); + item.IsFontItem = true; + item.FontName = ff.GetName(0); + item.FontSize = this.Font.Size; + item.Text = ff.GetName(0); + this.Items.Add(item); + } + this.DropDownWidth = this.Width * 2; + } + + private void DrawFontItem(DrawItemEventArgs e) + { + FontStyle[] styles = new FontStyle[4] { FontStyle.Regular, FontStyle.Bold, FontStyle.Italic, FontStyle.Bold | FontStyle.Italic }; + if (!BarFunctions.IsOffice2007Style(m_Style)) + e.DrawBackground(); + string fontname = this.Items[e.Index].ToString(); + FontFamily family = new FontFamily(fontname); + + int iWidth = this.DropDownWidth / 2 - 4; + if (iWidth <= 0) + iWidth = this.Width; + foreach (FontStyle style in styles) + { + if (family.IsStyleAvailable(style)) + { + eTextFormat format = eTextFormat.Default | eTextFormat.NoPrefix; + Color textColor = (e.State & DrawItemState.Selected) != 0 ? SystemColors.HighlightText : SystemColors.ControlText; + + Office2007ButtonItemStateColorTable ct = null; + if (BarFunctions.IsOffice2007Style(m_Style)) + { + Office2007ButtonItemColorTable bct = GetComboItemColor(); + if ((e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0) + ct = bct.MouseOver; + else if ((e.State & DrawItemState.Disabled) != 0 || !this.Enabled) + ct = bct.Disabled; + else + ct = bct.Default; + //if (ct == null) + if (!this.Enabled) + textColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor; + else if (StyleManager.IsMetro(StyleManager.Style)) + textColor = ct.Text; + else if (this.ForeColor.IsEmpty) + textColor = SystemColors.ControlText; + else + textColor = this.ForeColor; + + if ((e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0) + Office2007ButtonItemPainter.PaintBackground(e.Graphics, ct, e.Bounds, + (StyleManager.IsMetro(this.Style) ? RoundRectangleShapeDescriptor.RectangleShape : RoundRectangleShapeDescriptor.RoundCorner2)); + else + { + e.DrawBackground(); + } + } + + if ((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit) + { + Rectangle rt = e.Bounds; + rt.Height = 0; // Prevents clipping based on height + format |= eTextFormat.NoClipping | eTextFormat.NoPadding; + TextDrawing.DrawString(e.Graphics, fontname, this.Font, textColor, rt, format); + } + else + { + Size szFont = TextDrawing.MeasureString(e.Graphics, fontname, this.Font); + int iDiff = (int)((e.Bounds.Height - szFont.Height) / 2); + Rectangle rFontName = new Rectangle(e.Bounds.X, e.Bounds.Y + iDiff, + ((e.State & DrawItemState.Disabled) == DrawItemState.Disabled ? e.Bounds.Width : Math.Max(e.Bounds.Width - 100, 32)), e.Bounds.Height - iDiff); + TextDrawing.DrawString(e.Graphics, fontname, this.Font, textColor, rFontName, format); + Rectangle rRemainder = new Rectangle(e.Bounds.X + iWidth + 4, e.Bounds.Y, e.Bounds.Width + 100, e.Bounds.Height); + //using(Font f = new Font(family, (float)e.Bounds.Height - 8, style)) + using (Font f = new Font(family, this.Font.Size, style)) + TextDrawing.DrawString(e.Graphics, fontname, f, textColor, rRemainder, format); + } + break; + } + } + if (family != null) family.Dispose(); + } + + private void MeasureFontItem(MeasureItemEventArgs e) + { + e.ItemHeight = Dpi.Height18; + } + +#if !FRAMEWORK20 + /// + /// Specifies the height of the drop-down portion of combo box. + /// + [Browsable(true),Category("Behavior"),Description("The height, in pixels, of drop down box in a combo box."), DefaultValue(0)] + public int DropDownHeight + { + get + { + return m_DropDownHeight; + } + set + { + m_DropDownHeight=value; + } + } +#endif + private bool _AutoReleaseFocus = true; + [DefaultValue(true), Browsable(false)] + public bool AutoReleaseFocus + { + get + { + return _AutoReleaseFocus; + } + set + { + _AutoReleaseFocus = value; + } + } + /// + /// Releases the focus from combo box. The control that last had focus will receive focus back when this method is called. + /// + public void ReleaseFocus() + { + if (_AutoReleaseFocus && this.Focused && m_LastFocusWindow != IntPtr.Zero) + { + Control ctrl = Control.FromChildHandle(m_LastFocusWindow); + if (ctrl != this) + { + if (ctrl != null) + ctrl.Focus(); + else + { + NativeFunctions.SetFocus(m_LastFocusWindow); + } + this.OnLostFocus(new System.EventArgs()); + } + m_LastFocusWindow = IntPtr.Zero; + + } + } + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (keyData == Keys.Enter && m_PreventEnterBeep) + { + this.OnKeyPress(new KeyPressEventArgs((char)13)); + return true; + } + return base.ProcessCmdKey(ref msg, keyData); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if (!IsStandalone) + { + if (e.KeyCode == Keys.Enter) + ReleaseFocus(); + else if (e.KeyCode == Keys.Escape) + { + ReleaseFocus(); + } + } + + base.OnKeyDown(e); + } + + /// + /// Gets the window handle that the drop down list is bound to. + /// + [Browsable(false)] + public IntPtr DropDownHandle + { + get + { + return m_DropDownHandle; + } + } + + internal bool MouseOver + { + get + { + return m_MouseOver; + } + set + { + if (m_MouseOver != value) + { + m_MouseOver = value; + this.Invalidate(true); + } + } + } + + [System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ComboItemsEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Localizable(true)] + public new ComboBox.ObjectCollection Items + { + get { return base.Items; } + } + + protected override void OnEnabledChanged(EventArgs e) + { + UpdateBackColor(); + base.OnEnabledChanged(e); + } + + private void UpdateBackColor() + { + if (!m_UseCustomBackColor) + { + Color c = GetComboColors().Background; + if (this.BackColor != c) + this.BackColor = c; + } + } + + protected override void OnMouseEnter(EventArgs e) + { + if (!m_MouseOver) + { + m_MouseOver = true; + UpdateBackColor(); + this.Invalidate(true); + } + SetMouseOverTimerEnabled(true); + base.OnMouseEnter(e); + } + protected override void OnMouseLeave(EventArgs e) + { + //if(this.DroppedDown) + //{ + // m_MouseOver=false; + //} + //else if(this.DropDownStyle!=ComboBoxStyle.DropDownList && m_MouseOver) + //{ + // // Get the mouse position + // Point p=this.PointToClient(Control.MousePosition); + // if(!this.ClientRectangle.Contains(p)) + // { + // m_MouseOver=false; + // } + //} + //else if(m_MouseOver) + //{ + // m_MouseOver=false; + //} + SetMouseOverTimerEnabled(true); + //Color c = GetComboColors().Background; + //if (this.BackColor != c) + // this.BackColor = c; + //this.Refresh(); + base.OnMouseLeave(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + if (!m_MouseOver) + { + //if (!m_Focused) + { + m_MouseOver = true; + this.Invalidate(); + SetMouseOverTimerEnabled(true); + } + } + } + + private void SetMouseOverTimerEnabled(bool value) + { + if (m_MouseOverTimer != null) m_MouseOverTimer.Enabled = value; + } + + private void SetupTextBoxMessageHandler() + { +#if FRAMEWORK20 + if (this.DropDownStyle != ComboBoxStyle.DropDownList && this.AutoCompleteMode == AutoCompleteMode.None) +#else + if (this.DropDownStyle != ComboBoxStyle.DropDownList) +#endif + { + if (m_TextWindowMsgHandler == null) + { + // Get hold of the text box + IntPtr hwnd = GetWindow(this.Handle, GW_CHILD); + // Subclass so we can track messages + if (hwnd != IntPtr.Zero) + { + m_TextWindowMsgHandler = new ComboTextBoxMsgHandler(); + m_TextWindowMsgHandler.MouseLeave += new EventHandler(this.TextBoxMouseLeave); + m_TextWindowMsgHandler.Paint += new PaintEventHandler(TextBoxPaint); + m_TextWindowMsgHandler.AssignHandle(hwnd); + } + } + } + else if (m_TextWindowMsgHandler != null) + { + m_TextWindowMsgHandler.ReleaseHandle(); + m_TextWindowMsgHandler = null; + } + } + + protected override void OnDropDownStyleChanged(EventArgs e) + { + SetupTextBoxMessageHandler(); + base.OnDropDownStyleChanged(e); + } + + private void TextBoxPaint(object sender, PaintEventArgs e) + { + if (ShouldDrawWatermark()) + DrawWatermark(e.Graphics); + } + + private void TextBoxMouseLeave(object sender, EventArgs e) + { + if (!m_MouseOver) + return; + SetMouseOverTimerEnabled(true); + } + + /// + /// Gets or sets whether FocusHighlightColor is used as background color to highlight text box when it has input focus. Default value is false. + /// + [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Indicates whether FocusHighlightColor is used as background color to highlight text box when it has input focus.")] + public virtual bool FocusHighlightEnabled + { + get { return _FocusHighlightEnabled; } + set + { + if (_FocusHighlightEnabled != value) + { + _FocusHighlightEnabled = value; + if (this.Focused) + this.Invalidate(); + } + } + } + + /// + /// Gets or sets the color used as background color to highlight text box when it has input focus and focus highlight is enabled. + /// + [Browsable(true), Category("Appearance"), Description("Indicates color used as background color to highlight text box when it has input focus and focus highlight is enabled.")] + public virtual Color FocusHighlightColor + { + get { return _FocusHighlightColor; } + set + { + if (_FocusHighlightColor != value) + { + _FocusHighlightColor = value; + if (this.Focused) + this.Invalidate(); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFocusHighlightColor() + { + return !_FocusHighlightColor.Equals(_DefaultHighlightColor); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFocusHighlightColor() + { + FocusHighlightColor = _DefaultHighlightColor; + } + #endregion + + #region Multi-Column DropDown + protected override void OnLeave(EventArgs e) + { + if (IsMultiColumnDropDown && IsPopupOpen) + IsPopupOpen = false; + + base.OnLeave(e); + } + + private string _DropDownColumns = ""; + /// + /// Gets or sets comma separated list of field names that are displayed on drop down. When set it activates ComboBoxEx multi-column drop-down mode. + /// DataSource must be set in order for drop-down to display data. + /// + [DefaultValue(""), Category("Multi-Column"), Description("Indicates comma separated list of field names that are displayed on drop down. When set it activates ComboBoxEx multi-column drop-down mode.")] + [Editor("DevComponents.DotNetBar.Design.DataMembersSelector, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string DropDownColumns + { + get { return _DropDownColumns; } + set + { + if (value != _DropDownColumns) + { + string oldValue = _DropDownColumns; + _DropDownColumns = value; + OnDropDownColumnsChanged(oldValue, value); + } + } + } + private AdvTree.AdvTree _MultiColumnDisplay = null; + /// + /// Called when DropDownColumns property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDropDownColumnsChanged(string oldValue, string newValue) + { + _DataChangeType |= eDataChange.DropDownColumnsChanged; + } + + private string _DropDownColumnsHeaders = ""; + /// + /// Indicates custom column names with each column separated by new line, i.e. \r\n escape sequence. + /// + [DefaultValue(""), Category("Multi-Column"), Description("Indicates custom column names with each column separated by new line, i.e. \r\n escape sequence.")] + [Editor("DevComponents.DotNetBar.Design.ColumnNamesEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + [TypeConverter("DevComponents.DotNetBar.Design.ColumnNamesConverter, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public string DropDownColumnsHeaders + { + get { return _DropDownColumnsHeaders; } + set + { + if (value != _DropDownColumnsHeaders) + { + string oldValue = _DropDownColumnsHeaders; + _DropDownColumnsHeaders = value; + OnDropDownColumnsHeadersChanged(oldValue, value); + } + } + } + + private string[] _ColumnsHeaders = new string[0]; + /// + /// Called when DropDownColumnsHeaders property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDropDownColumnsHeadersChanged(string oldValue, string newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("DropDownColumnsHeaders")); + _DataChangeType |= eDataChange.DropDownColumnsChanged; + + if (!string.IsNullOrEmpty(_DropDownColumnsHeaders)) + { + _ColumnsHeaders = _DropDownColumnsHeaders.Split('\r'); + for (int i = 0; i < _ColumnsHeaders.Length; i++) + { + _ColumnsHeaders[i] = _ColumnsHeaders[i].Replace("\n", ""); + } + } + else + _ColumnsHeaders = new string[0]; + } + + private bool IsMultiColumnDropDown + { + get + { + return !string.IsNullOrEmpty(_DropDownColumns); + } + } + + /// + /// Occurs before the multi-column popup is opened and it allows canceling of popup by setting CancelEventArgs.Cancel=true. + /// + [Description("Occurs before the multi-column popup is opened and it allows canceling of popup by setting CancelEventArgs.Cancel=true.")] + public event CancelEventHandler BeforeMultiColumnPopupOpen; + /// + /// Raises BeforeMultiColumnPopupOpen event. + /// + /// Provides event arguments. + protected virtual void OnBeforeMultiColumnPopupOpen(CancelEventArgs e) + { + CancelEventHandler handler = BeforeMultiColumnPopupOpen; + if (handler != null) + handler(this, e); + } + + private eDataChange _DataChangeType = eDataChange.None; + private DateTime _MultiDropDownOpenedAtTime = DateTime.MinValue; + private DateTime _MultiDropDownClosedAtTime = DateTime.MinValue; + private PopupHostController _PopupController = null; + private void OpenMultiColumnDropDown() + { + if (_PopupController == null) + { + _PopupController = new PopupHostController(); + _PopupController.Closed += PopupControllerClosed; + } + + if (_MultiColumnDisplay == null) + { + _MultiColumnDisplay = CreateMultiColumnDisplayControl(); + _DataChangeType = eDataChange.All; + } + if (IsDataChange(eDataChange.BindingContextChanged)) + _MultiColumnDisplay.BindingContext = this.BindingContext; + if (IsDataChange(eDataChange.DataSourceChanged)) + _MultiColumnDisplay.DataSource = this.DataSource; + if (IsDataChange(eDataChange.DropDownColumnsChanged)) + _MultiColumnDisplay.DisplayMembers = _DropDownColumns; + + if (!_PopupController.PopupUserSize || !_PreservePopupSize) + { + _MultiColumnDisplay.Height = Dpi.Height(this.DropDownHeight); + _MultiColumnDisplay.Width = Dpi.Width(this.DropDownWidth); + } + _PopupController.CloseButtonVisible = _PopupCloseButtonVisible; + CancelEventArgs cancelArgs = new CancelEventArgs(); + OnBeforeMultiColumnPopupOpen(cancelArgs); + if (cancelArgs.Cancel) + return; + + _MultiColumnDisplay.SelectedIndex = this.SelectedIndex; + + Point location = PointToScreen(new Point(0, Height)); + + ePopupResizeEdge resize = _EnablePopupResize ? ePopupResizeEdge.BottomRight : ePopupResizeEdge.None; + _PopupController.Show(_MultiColumnDisplay, location.X, location.Y, 0, 0, resize); + if (_MultiColumnDisplay.SelectedNode != null) + _MultiColumnDisplay.SelectedNode.EnsureVisible(); + _DroppedDown = true; + _MultiDropDownOpenedAtTime = DateTime.Now; + + _DataChangeType = eDataChange.None; + + base.OnDropDown(EventArgs.Empty); + } + private bool _DisconnectedPopupDataSource = false; + protected bool DisconnectedPopupDataSource + { + get { return _DisconnectedPopupDataSource; } + set { _DisconnectedPopupDataSource = value; } + } + void PopupControllerClosed(object sender, ToolStripDropDownClosedEventArgs e) + { + _DroppedDown = false; + + m_SelectedIndexInternal = this.SelectedIndex; + _MultiDropDownClosedAtTime = DateTime.Now; + if (DisconnectedPopupDataSource && _MultiColumnDisplay != null) + { + _MultiColumnDisplay.DataSource = null; + _MultiColumnDisplay.DisplayMembers = string.Empty; + _MultiColumnDisplay.BindingContext = null; + _DataChangeType = eDataChange.All; + } + base.OnDropDownClosed(e); + } + private void CloseMultiColumnDropDown() + { + if (_PopupController != null && _DroppedDown) + { + _PopupController.Hide(); + } + } + private AdvTree.AdvTree CreateMultiColumnDisplayControl() + { + AdvTree.AdvTree tree = new DevComponents.AdvTree.AdvTree(); +#if (!TRIAL) + tree.LicenseKey = "F962CEC7-CD8F-4911-A9E9-CAB39962FC1F"; +#endif + tree.EnableDataPositionChange = false; + tree.BackgroundStyle.Reset(); + tree.BackgroundStyle.BackColor = SystemColors.Window; + tree.BackgroundStyle.Border = eStyleBorderType.None; + tree.ExpandButtonType = eExpandButtonType.Triangle; + tree.DragDropEnabled = false; + tree.HotTracking = true; + tree.Indent = 0; + tree.ExpandWidth = 0; + tree.SelectionFocusAware = false; + ElementStyle nodeStyle = new ElementStyle(); + nodeStyle.Name = "nodeElementStyle"; + nodeStyle.TextColor = System.Drawing.SystemColors.ControlText; + tree.NodeStyle = nodeStyle; + tree.PathSeparator = ";"; + tree.Styles.Add(nodeStyle); + tree.AfterNodeSelect += TreeAfterNodeSelect; + tree.BeforeNodeSelect += TreeBeforeNodeSelect; + tree.NodeMouseDown += TreeNodeMouseDown; + tree.NodeClick += new TreeNodeMouseEventHandler(TreeNodeClick); + tree.DataColumnCreated += TreeDataColumnCreated; + tree.KeyDown += TreeKeyDown; + if (_MultiColumnControlFont != null) + tree.Font = _MultiColumnControlFont; + return tree; + } + + void TreeKeyDown(object sender, KeyEventArgs e) + { + if (_DroppedDown && e.KeyCode == Keys.Enter) + { + //if (this.SelectionClosesPopup) + // CloseMultiColumnDropDown(); + //else + { + this.SelectedIndex = _MultiColumnDisplay.SelectedIndex; + CloseMultiColumnDropDown(); + OnSelectionChangeCommitted(e); + } + } + } + /// + /// Occurs when ColumnHeader is automatically created by control as result of data binding for multi-column drop-down and provides you with opportunity to modify it. + /// + [Description("Occurs when ColumnHeader is automatically created by control as result of data binding for multi-column drop down and provides you with opportunity to modify it.")] + public event DevComponents.DotNetBar.Controls.DataColumnEventHandler DataColumnCreated; + /// + /// Raises the DataColumnCreated event. + /// + /// Provides event arguments. + protected virtual void OnDataColumnCreated(DevComponents.DotNetBar.Controls.DataColumnEventArgs e) + { + if (DataColumnCreated != null) + DataColumnCreated(this, e); + } + void TreeDataColumnCreated(object sender, DataColumnEventArgs e) + { + if (_ColumnsHeaders.Length > 0) + { + int i = e.ColumnHeader.Parent.IndexOf(e.ColumnHeader); + if (i < _ColumnsHeaders.Length) + e.ColumnHeader.Text = _ColumnsHeaders[i]; + } + OnDataColumnCreated(e); + } + private void TreeNodeMouseDown(object sender, TreeNodeMouseEventArgs e) + { + //if (this.SelectionClosesPopup && e.Button == MouseButtons.Left && e.Node != null && + // e.Node.IsSelected && _DroppedDown) + //{ + // CloseMultiColumnDropDown(); + //} + } + void TreeNodeClick(object sender, TreeNodeMouseEventArgs e) + { + if (e.Button == MouseButtons.Left && e.Node != null && + e.Node.IsSelected && _DroppedDown) + { + this.SelectedIndex = _MultiColumnDisplay.SelectedIndex; + if (this.SelectionClosesPopup) + CloseMultiColumnDropDown(); + OnSelectionChangeCommitted(e); + } + } + private void TreeAfterNodeSelect(object sender, AdvTreeNodeEventArgs e) + { + //if (_DroppedDown && (e.Action == eTreeAction.Keyboard)) + //{ + // this.SelectedIndex = _MultiColumnDisplay.SelectedIndex; + //} + + //if (this.SelectionClosesPopup && _DroppedDown && e.Action == eTreeAction.Keyboard) + //{ + // CloseMultiColumnDropDown(); + //} + + //if (/*e.Action == eTreeAction.Mouse || */ e.Action == eTreeAction.Keyboard) + // OnSelectionChangeCommitted(e); + } + private void TreeBeforeNodeSelect(object sender, AdvTreeNodeCancelEventArgs e) + { + OnSelectionChanging(e); + } + /// + /// Occurs before selection on multi-column drop-down has changed and allows canceling of the change. Applies to multi-column drop-down only. + /// + [Description("Occurs before selection on multi-column drop-down has changed and allows canceling of the change.")] + public event AdvTreeNodeCancelEventHandler SelectionChanging; + /// + /// Raises SelectionChanging event. + /// + /// Provides event arguments. + protected virtual void OnSelectionChanging(AdvTreeNodeCancelEventArgs e) + { + AdvTreeNodeCancelEventHandler handler = SelectionChanging; + if (handler != null) + handler(this, e); + } + + private bool _SelectionClosesPopup = true; + /// + /// Gets or sets whether selection change on multi-column drop-down closes the popup. Default value is true. Applies to multi-column drop-down only. + /// + [DefaultValue(true), Category("Multi-Column"), Description("Indicates whether selection change on multi-column drop-down closes the popup. Default value is true. Applies to multi-column drop-down only.")] + public bool SelectionClosesPopup + { + get { return _SelectionClosesPopup; } + set + { + _SelectionClosesPopup = value; + } + } + + private bool _PreservePopupSize = true; + /// + /// Indicates whether multi-column popup size is preserved between popup displays if popup is resized by end-user. Applies to multi-column drop-down only. + /// + [DefaultValue(true), Category("Multi-Column"), Description("Indicates whether multi-column popup size is preserved between popup displays if popup is resized by end-user. Applies to multi-column drop-down only.")] + public bool PreservePopupSize + { + get { return _PreservePopupSize; } + set + { + _PreservePopupSize = value; + } + } + + private bool _EnablePopupResize = true; + /// + /// Indicates whether multi-column popup can be resized by end user. Applies to multi-column drop-down only. + /// + [DefaultValue(true), Category("Multi-Column"), Description("Indicates whether multi-column popup can be resized by end user. Applies to multi-column drop-down only.")] + public bool EnablePopupResize + { + get { return _EnablePopupResize; } + set + { + _EnablePopupResize = value; + } + } + + private bool _PopupCloseButtonVisible = true; + /// + /// Indicates whether multi-column popup close button is visible. + /// + [DefaultValue(true), Category("Multi-Column"), Description("Indicates whether multi-column popup close button is visible.")] + public bool PopupCloseButtonVisible + { + get { return _PopupCloseButtonVisible; } + set + { + _PopupCloseButtonVisible = value; + } + } + + /// + /// Gets or sets whether multi-column popup window is open. Applies to multi-column drop-down only. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPopupOpen + { + get { return _DroppedDown; } + set + { + if (value != _DroppedDown) + { + if (IsMultiColumnDropDown) + { + if (value) + OpenMultiColumnDropDown(); + else + CloseMultiColumnDropDown(); + } + } + } + } + + protected override void OnDataSourceChanged(EventArgs e) + { + if (_MultiColumnDisplay != null) + _MultiColumnDisplay.DataSource = null; + _DataChangeType |= eDataChange.DataSourceChanged; + base.OnDataSourceChanged(e); + } + protected override void OnBindingContextChanged(EventArgs e) + { + _DataChangeType |= eDataChange.BindingContextChanged; + base.OnBindingContextChanged(e); + } + + private bool IsDataChange(eDataChange changeType) + { + return ((_DataChangeType & changeType) == changeType); + } + [Flags()] + private enum eDataChange + { + None = 0, + DataSourceChanged = 1, + DropDownColumnsChanged = 2, + BindingContextChanged = 4, + All = DataSourceChanged | DropDownColumnsChanged | BindingContextChanged + } + /// + /// Gets the reference to the control which is used to display multi-column data on popup. Control is created just before the popup is opened. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AdvTree.AdvTree MultiColumnDisplayControl + { + get + { + return _MultiColumnDisplay; + } + } + + private Font _MultiColumnControlFont = null; + /// + /// Indicates the font used by the multi-column control on the popup. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the font used by the multi-column control on the popup.")] + public Font MultiColumnControlFont + { + get { return _MultiColumnControlFont; } + set + { + if (value != _MultiColumnControlFont) + { + Font oldValue = _MultiColumnControlFont; + _MultiColumnControlFont = value; + OnMultiColumnControlFontChanged(oldValue, value); + } + } + } + /// + /// Called when MultiColumnControlFont property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnMultiColumnControlFontChanged(Font oldValue, Font newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("MultiColumnControlFont")); + if (_MultiColumnDisplay != null) + _MultiColumnDisplay.Font = _MultiColumnControlFont; + } + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + CommandManager.ExecuteCommand(this); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + } + } + + private ICommand _Command = null; + //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if (changed) + OnCommandChanged(); + } + } + + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + } + } + + #endregion + + #region ComboTextBoxMsgHandler + private class ComboTextBoxMsgHandler : NativeWindow + { + private const int WM_MOUSELEAVE = 0x02A3; + private const int WM_MOUSEMOVE = 0x0200; + private const int TME_LEAVE = 0x02; + [DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)] + private static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack); + + public event EventHandler MouseLeave; + public event PaintEventHandler Paint; + + private struct TRACKMOUSEEVENT + { + public int cbSize; + public int dwFlags; + public IntPtr hwndTrack; + public int dwHoverTime; + } + + private bool m_MouseTracking = false; + + protected override void WndProc(ref Message m) + { + const int WM_PAINT = 0xF; + if (m.Msg == WM_MOUSEMOVE && !m_MouseTracking) + { + m_MouseTracking = true; + TRACKMOUSEEVENT tme = new TRACKMOUSEEVENT(); + tme.dwFlags = TME_LEAVE; + tme.cbSize = Marshal.SizeOf(tme); + tme.hwndTrack = this.Handle; + tme.dwHoverTime = 0; + m_MouseTracking = TrackMouseEvent(ref tme); + } + else if (m.Msg == WM_MOUSELEAVE) + { + if (MouseLeave != null) + MouseLeave(this, new EventArgs()); + m_MouseTracking = false; + } + else if (m.Msg == WM_PAINT) + { + base.WndProc(ref m); + if (Paint != null) + { + using (Graphics g = Graphics.FromHwnd(m.HWnd)) + Paint(this, new PaintEventArgs(g, Rectangle.Empty)); + } + return; + } + base.WndProc(ref m); + } + } + #endregion + + #region ComboBoxPopupMsgHandler + private class ComboBoxPopupMsgHandler : NativeWindow + { + protected override void WndProc(ref Message m) + { + if (m.Msg == (int)WinApi.WindowsMessages.WM_VSCROLL) + { + base.WndProc(ref m); + WinApi.RedrawWindow(m.HWnd, + IntPtr.Zero, + IntPtr.Zero, + WinApi.RedrawWindowFlags.RDW_INVALIDATE | WinApi.RedrawWindowFlags.RDW_UPDATENOW); + return; + } + base.WndProc(ref m); + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ComboBoxEx.ico b/PROMS/DotNetBar Source Code/Controls/ComboBoxEx.ico new file mode 100644 index 00000000..fbe135b6 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/ComboBoxEx.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/ComboTree.cs b/PROMS/DotNetBar Source Code/Controls/ComboTree.cs new file mode 100644 index 00000000..4b598559 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ComboTree.cs @@ -0,0 +1,3447 @@ +#if FRAMEWORK20 +using System; +using System.Text; +using System.ComponentModel; +using System.Drawing; +using DevComponents.Editors; +using System.Windows.Forms; +using System.Drawing.Drawing2D; +using System.Collections; +using System.Drawing.Design; +using DevComponents.AdvTree; +using System.Security; +using System.Globalization; +using System.Threading; +using System.Collections.Generic; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the combo box like control which shows the AdvTree control on popup. Tree control + /// can be configured to display multiple columns as well. + /// + [ToolboxBitmap(typeof(ComboTree), "Controls.ComboTree.ico"), ToolboxItem(true), DefaultProperty("Text"), DefaultBindingProperty("Text"), DefaultEvent("TextChanged"), Designer("DevComponents.DotNetBar.Design.ComboTreeDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ComboTree : PopupItemControl, IInputButtonControl, ICommandSource + { + #region Private Variables + //private TextBoxX _TextBox = null; + private AdvTree.AdvTree _AdvTree = null; + private ButtonItem _PopupItem = null; + private static string _DropDownItemContainerName = "sysPopupItemContainer"; + private static string _DropDownControlContainerName = "sysPopupControlContainer"; + private Color _FocusHighlightColor = ColorScheme.GetColor(0xFFFF88); + private bool _FocusHighlightEnabled = false; + #endregion + + #region Events + /// + /// Occurs when Clear button is clicked and allows you to cancel the default action performed by the button. + /// + public event CancelEventHandler ButtonClearClick; + /// + /// Occurs when Drop-Down button that shows popup is clicked and allows you to cancel showing of the popup. + /// + public event CancelEventHandler ButtonDropDownClick; + /// + /// Occurs when ButtonCustom control is clicked. + /// + public event EventHandler ButtonCustomClick; + /// + /// Occurs when ButtonCustom2 control is clicked. + /// + public event EventHandler ButtonCustom2Click; + /// + /// Occurs when the text alignment in text box has changed. + /// + [Description("Occurs when the text alignment in text box has changed.")] + public event EventHandler TextAlignChanged; + ///// + ///// Occurs when the value of the Modified property has changed. + ///// + //public event EventHandler ModifiedChanged; + /// + /// Occurs before Node has been selected by user or through the SelectedNode property. Event can be canceled. + /// + public event AdvTreeNodeCancelEventHandler SelectionChanging; + /// + /// Occurs after node has been selected by user or through the SelectedNode property. + /// + public event AdvTreeNodeEventHandler SelectionChanged; + /// + /// Occurs when the DataSource changes. + /// + [Description("Occurs when the DataSource changes.")] + public event EventHandler DataSourceChanged; + /// + /// Occurs when the DisplayMembers property changes. + /// + [Description("Occurs when the DisplayMembers property changes")] + public event EventHandler DisplayMembersChanged; + /// + /// Occurs when the control is bound to a data value that need to be converted. + /// + [Description("Occurs when the control is bound to a data value that need to be converted.")] + public event TreeConvertEventHandler Format; + /// + /// Occurs when FormattingEnabled property changes. + /// + [Description("Occurs when FormattingEnabled property changes.")] + public event EventHandler FormattingEnabledChanged; + /// + /// Occurs when FormatString property changes. + /// + [Description("Occurs when FormatString property changes.")] + public event EventHandler FormatStringChanged; + /// + /// Occurs when FormatInfo property has changed. + /// + [Description("Occurs when FormatInfo property has changed.")] + public event EventHandler FormatInfoChanged; + /// + /// Occurs when a Node for an data-bound object item has been created and provides you with opportunity to modify the node. + /// + [Description("Occurs when a Node for an data-bound object item has been created and provides you with opportunity to modify the node")] + public event DataNodeEventHandler DataNodeCreated; + /// + /// Occurs when a group Node is created as result of GroupingMembers property setting and provides you with opportunity to modify the node. + /// + [Description("Occurs when a group Node is created as result of GroupingMembers property setting and provides you with opportunity to modify the node")] + public event DataNodeEventHandler GroupNodeCreated; + /// + /// Occurs when value of ValueMember property has changed. + /// + [Description("Occurs when value of ValueMember property has changed.")] + public event EventHandler ValueMemberChanged; + /// + /// Occurs when value of SelectedValue property has changed. + /// + [Description("Occurs when value of SelectedValue property has changed.")] + public event EventHandler SelectedValueChanged; + /// + /// Occurs when value of SelectedIndex property has changed. + /// + [Description("Occurs when value of SelectedValue property has changed.")] + public event EventHandler SelectedIndexChanged; + /// + /// Occurs when ColumnHeader is automatically created by control as result of data binding and provides you with opportunity to modify it. + /// + [Description("Occurs when ColumnHeader is automatically created by control as result of data binding and provides you with opportunity to modify it.")] + public event DataColumnEventHandler DataColumnCreated; + #endregion + + #region Constructor + /// + /// Initializes a new instance of the TextBoxDropDown class. + /// + public ComboTree() + { + this.SetStyle(ControlStyles.Selectable, true); + InitControl(); + this.BackColor = SystemColors.Window; + } + private void InitControl() + { + _BackgroundStyle.SetColorScheme(this.ColorScheme); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + + _ButtonCustom = new InputButtonSettings(this); + _ButtonCustom2 = new InputButtonSettings(this); + _ButtonClear = new InputButtonSettings(this); + _ButtonDropDown = new InputButtonSettings(this); + CreateButtonGroup(); + + //_TextBox = new TextBoxX(); + //_TextBox.BorderStyle = BorderStyle.None; + //_TextBox.TextChanged += new EventHandler(TextBoxTextChanged); + //_TextBox.TextAlignChanged += new EventHandler(TextBoxTextAlignChanged); + //_TextBox.SizeChanged += new EventHandler(TextBoxSizeChanged); + //_TextBox.Visible=false; + ////_TextBox.ModifiedChanged += new EventHandler(TextBoxModifiedChanged); + //this.Controls.Add(_TextBox); + + // Init popup tree + _AdvTree = new DevComponents.AdvTree.AdvTree(); +#if (!TRIAL) + _AdvTree.LicenseKey = "F962CEC7-CD8F-4911-A9E9-CAB39962FC1F"; +#endif + _AdvTree.BackgroundStyle.Reset(); + _AdvTree.BackgroundStyle.BackColor = SystemColors.Window; + _AdvTree.BackgroundStyle.Border = eStyleBorderType.None; + _AdvTree.ExpandButtonType = eExpandButtonType.Triangle; + _AdvTree.DragDropEnabled = false; + _AdvTree.HotTracking = true; + _AdvTree.Indent = 6; + _AdvTree.SelectionFocusAware = false; + ElementStyle nodeStyle = new ElementStyle(); + nodeStyle.Name = "nodeElementStyle"; + nodeStyle.TextColor = System.Drawing.SystemColors.ControlText; + _AdvTree.NodeStyle = nodeStyle; + _AdvTree.PathSeparator = ";"; + _AdvTree.Styles.Add(nodeStyle); + _AdvTree.AfterNodeSelect += new AdvTreeNodeEventHandler(TreeAfterNodeSelect); + _AdvTree.BeforeNodeSelect += new AdvTreeNodeCancelEventHandler(TreeBeforeNodeSelect); + _AdvTree.NodeMouseDown += new TreeNodeMouseEventHandler(TreeNodeMouseDown); + + this.DropDownControl = _AdvTree; + } + #endregion + + #region Internal Implementation + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + base.ScaleControl(factor, specified); + if (_ButtonGroup!=null) + _ButtonGroup.InvalidateArrange(); + } + + protected override void OnBackColorChanged(EventArgs e) + { + _AdvTree.BackgroundStyle.BackColor = this.BackColor; + base.OnBackColorChanged(e); + } + protected override void InvalidateAutoSize() + { + if (_AdvTree != null) + _AdvTree.AntiAlias = this.AntiAlias; + } + /// + /// Gets or sets the tree node that is currently selected in the tree control. + /// + /// + /// If no Node is currently selected, the + /// SelectedNode property is a null reference (Nothing in Visual + /// Basic). + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Node SelectedNode + { + get + { + return _AdvTree.SelectedNode; + } + set + { + _AdvTree.SelectedNode = value; + } + } + + void TreeNodeMouseDown(object sender, TreeNodeMouseEventArgs e) + { + if (this.SelectionClosesPopup && e.Button == MouseButtons.Left && e.Node != null && + e.Node.IsSelected && this.IsPopupOpen && !e.Node.ExpandPartRectangle.Contains(e.X, e.Y)) + { + this.IsPopupOpen = false; + } + } + + private void TreeBeforeNodeSelect(object sender, AdvTreeNodeCancelEventArgs e) + { + if (SelectionChanging != null) + SelectionChanging(this, e); + } + private void TreeAfterNodeSelect(object sender, AdvTreeNodeEventArgs e) + { + if (SelectionChanged != null) + SelectionChanged(this, e); + + if (_DataManager != null) + { + Node selectedNode = _AdvTree.SelectedNode; + if (selectedNode != null && selectedNode.BindingIndex > -1 && _DataManager.Position != selectedNode.BindingIndex) + { + _DataManager.Position = selectedNode.BindingIndex; + } + //else if (selectedNode == null) + // _DataManager.Position = -1; + } + + if (this.SelectionClosesPopup && this.IsPopupOpen && e.Action == eTreeAction.Mouse) + { + this.IsPopupOpen = false; + } + + if (e.Node != null) this.Text = e.Node.ToString(); + this.Invalidate(); + + OnSelectedIndexChanged(EventArgs.Empty); + if(!string.IsNullOrEmpty(this.ValueMember)) + this.OnSelectedValueChanged(EventArgs.Empty); + } + + private bool _SelectionClosesPopup = true; + /// + /// Gets or sets whether selection change on popup tree closes the popup. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether selection change on popup tree closes the popup.")] + public bool SelectionClosesPopup + { + get { return _SelectionClosesPopup; } + set + { + _SelectionClosesPopup = value; + } + } + + private string _SelectedDisplayMember = ""; + /// + /// Gets or sets the field name that holds the text that will be displayed in the control for selected item. When not set all items set in DisplayMembers will be displayed in control. + /// + [DefaultValue(""), Category("Data"), Description("Indicates field name that holds the text that will be displayed in the control for selected item. When not set all items set in DisplayMembers will be displayed in control.")] + [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))] + public string SelectedDisplayMember + { + get { return _SelectedDisplayMember; } + set + { + _SelectedDisplayMember = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the field name that holds the text that will be displayed in the control for selected item. When not set all items set in DisplayMembers will be displayed in control. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Obsolete("This property name was misspelled. Use SelectedDisplayMember instead.")] + public string SelectedDisplayMemeber + { + get { return _SelectedDisplayMember; } + set + { + _SelectedDisplayMember = value; + this.Invalidate(); + } + } + + + private List _DisplayMembers = null; + /// + /// Gets or sets the comma separated list of property or column names to display on popup tree control. + /// + [DefaultValue(""), Category("Data"), Description("Indicates comma separated list of property or column names to display on popup tree control")] + [Editor("DevComponents.DotNetBar.Design.DataMembersSelector, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string DisplayMembers + { + get + { + if (_DisplayMembers == null || _DisplayMembers.Count == 0) + return ""; + StringBuilder members = new StringBuilder(); + for (int i = 0; i < _DisplayMembers.Count; i++) + { + BindingMemberInfo item = _DisplayMembers[i]; + members.Append(item.BindingMember); + if (i + 1 < _DisplayMembers.Count) + members.Append(','); + } + return members.ToString(); + } + set + { + List displayMembers = _DisplayMembers; + + List newMembers = null; + + if (!string.IsNullOrEmpty(value)) + { + newMembers = new List(); + // Parse the members comma separated list expected... + string[] members = value.Split(','); + for (int i = 0; i < members.Length; i++) + { + newMembers.Add(new BindingMemberInfo(members[i].Trim())); + } + } + + try + { + this.SetDataConnection(_DataSource, newMembers, false); + } + catch + { + _DisplayMembers = displayMembers; + } + } + } + + private object _DataSource = null; + /// + /// Gets or sets the data source for the ComboTree. Expected is an object that implements the IList or IListSource interfaces, + /// such as a DataSet or an Array. The default is null. + /// + [AttributeProvider(typeof(IListSource)), Description("Indicates data source for the ComboTree."), Category("Data"), DefaultValue(null), RefreshProperties(RefreshProperties.Repaint)] + public object DataSource + { + get + { + return _DataSource; + } + set + { + if (((value != null) && !(value is IList)) && !(value is IListSource)) + { + throw new ArgumentException("Data type is not supported for complex data binding"); + } + if (_DataSource != value) + { + try + { + this.SetDataConnection(value, _DisplayMembers, true); + } + catch + { + this.DisplayMembers = ""; + } + if (value == null) + { + this.DisplayMembers = ""; + } + } + } + } + + private bool _FormattingEnabled = false; + /// + /// Gets or sets a value indicating whether formatting is applied to the DisplayMembers property of the control. + /// + [DefaultValue(false), Description("Indicates whether formatting is applied to the DisplayMembers property of the control.")] + public bool FormattingEnabled + { + get + { + return _FormattingEnabled; + } + set + { + if (value != _FormattingEnabled) + { + _FormattingEnabled = value; + RefreshItems(); + OnFormattingEnabledChanged(EventArgs.Empty); + } + } + } + /// + /// Raises FormattingEnabledChanged event. + /// + /// Event arguments. + protected virtual void OnFormattingEnabledChanged(EventArgs e) + { + EventHandler handler = FormattingEnabledChanged; + if (handler != null) + { + handler(this, e); + } + } + + private string _FormatString = ""; + /// + /// Gets or sets the format-specifier characters that indicate how a value is to be displayed. + /// + [MergableProperty(false), Editor("System.Windows.Forms.Design.FormatStringEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), DefaultValue(""), Description("Indicates format-specifier characters that indicate how a value is to be displayed.")] + public string FormatString + { + get + { + return _FormatString; + } + set + { + if (value == null) + { + value = string.Empty; + } + if (!value.Equals(_FormatString)) + { + _FormatString = value; + RefreshItems(); + OnFormatStringChanged(EventArgs.Empty); + } + } + } + /// + /// Raises FormatStringChanged event. + /// + /// Event arguments. + protected virtual void OnFormatStringChanged(EventArgs e) + { + EventHandler handler = FormatStringChanged; + if (handler != null) + { + handler(this, e); + } + } + + private IFormatProvider _FormatInfo = null; + /// + /// Gets or sets the IFormatProvider that provides custom formatting behavior. + /// + [EditorBrowsable(EditorBrowsableState.Advanced), Browsable(false), DefaultValue((string)null)] + public IFormatProvider FormatInfo + { + get + { + return _FormatInfo; + } + set + { + if (value != _FormatInfo) + { + _FormatInfo = value; + RefreshItems(); + OnFormatInfoChanged(EventArgs.Empty); + } + } + } + + /// + /// Raises FormatInfoChanged event. + /// + /// Event arguments. + protected virtual void OnFormatInfoChanged(EventArgs e) + { + EventHandler handler = FormatInfoChanged; + if (handler != null) + { + handler(this, e); + } + } + + + private bool _InSetDataConnection = false; + private void SetDataConnection(object newDataSource, List newDisplayMembers, bool force) + { + bool dataSourceChanged = _DataSource != newDataSource; + bool displayMemberChanged = _DisplayMembers != newDisplayMembers; + + if (!_InSetDataConnection) + { + try + { + if ((force || dataSourceChanged) || displayMemberChanged) + { + _InSetDataConnection = true; + IList list = (this.DataManager != null) ? this.DataManager.List : null; + bool isDataManagerNull = this.DataManager == null; + this.UnwireDataSource(); + _DataSource = newDataSource; + _DisplayMembers = newDisplayMembers; + this.WireDataSource(); + if (_IsDataSourceInitialized) + { + CurrencyManager manager = null; + if (((newDataSource != null) && (this.BindingContext != null)) && (newDataSource != Convert.DBNull)) + { + string bindingPath = ""; + if (_DisplayMembers != null && _DisplayMembers.Count > 0) + bindingPath = newDisplayMembers[0].BindingPath; + manager = (CurrencyManager)this.BindingContext[newDataSource, bindingPath]; + } + if (_DataManager != manager) + { + if (_DataManager != null) + { + _DataManager.ItemChanged -= new ItemChangedEventHandler(this.DataManager_ItemChanged); + _DataManager.PositionChanged -= new EventHandler(this.DataManager_PositionChanged); + } + _DataManager = manager; + if (_DataManager != null) + { + _DataManager.ItemChanged += new ItemChangedEventHandler(this.DataManager_ItemChanged); + _DataManager.PositionChanged += new EventHandler(this.DataManager_PositionChanged); + } + } + if (((_DataManager != null) && (displayMemberChanged || dataSourceChanged)) && !ValidateDisplayMembers(_DisplayMembers)) + { + throw new ArgumentException("Wrong DisplayMembers parameter", "newDisplayMember"); + } + if (((_DataManager != null) && ((dataSourceChanged || displayMemberChanged) || force)) && (displayMemberChanged || (force && ((list != _DataManager.List) || isDataManagerNull || dataSourceChanged)))) + { + DataManager_ItemChanged(_DataManager, null); + } + } + _Converters.Clear(); + } + if (dataSourceChanged) + { + this.OnDataSourceChanged(EventArgs.Empty); + } + if (displayMemberChanged) + { + this.OnDisplayMembersChanged(EventArgs.Empty); + } + } + finally + { + _InSetDataConnection = false; + } + } + } + + private bool ValidateDisplayMembers(List members) + { + if (members == null || members.Count == 0) return true; + + foreach (BindingMemberInfo item in members) + { + if (item.BindingMember != null && !BindingMemberInfoInDataManager(item)) + return false; + } + return true; + } + private bool BindingMemberInfoInDataManager(BindingMemberInfo bindingMemberInfo) + { + if (_DataManager != null) + { + PropertyDescriptorCollection itemProperties = _DataManager.GetItemProperties(); + int count = itemProperties.Count; + for (int i = 0; i < count; i++) + { + if (!typeof(IList).IsAssignableFrom(itemProperties[i].PropertyType) && itemProperties[i].Name.Equals(bindingMemberInfo.BindingField)) + { + return true; + } + } + for (int j = 0; j < count; j++) + { + if (!typeof(IList).IsAssignableFrom(itemProperties[j].PropertyType) && (string.Compare(itemProperties[j].Name, bindingMemberInfo.BindingField, true, CultureInfo.CurrentCulture) == 0)) + { + return true; + } + } + } + return false; + } + /// + /// Raises the DataSourceChanged event. + /// + /// An EventArgs that contains the event data. + protected virtual void OnDataSourceChanged(EventArgs e) + { + EventHandler handler = DataSourceChanged; + if (handler != null) + { + handler(this, e); + } + } + /// + /// Raises the DisplayMemberChanged event. + /// + /// An EventArgs that contains the event data. + protected virtual void OnDisplayMembersChanged(EventArgs e) + { + EventHandler handler = DisplayMembersChanged; + if (handler != null) + { + handler(this, e); + } + } + + private Hashtable _Converters = new Hashtable(); + private TypeConverter GetFieldConverter(string fieldName) + { + if (_Converters.ContainsKey(fieldName)) + return (TypeConverter)_Converters[fieldName]; + if (this.DataManager != null) + { + PropertyDescriptorCollection itemProperties = this.DataManager.GetItemProperties(); + if (itemProperties != null) + { + PropertyDescriptor descriptor = itemProperties.Find(fieldName, true); + if (descriptor != null) + { + _Converters.Add(fieldName, descriptor.Converter); + return descriptor.Converter; + } + } + } + + return null; + } + + private void DataManager_ItemChanged(object sender, ItemChangedEventArgs e) + { + if (this.InvokeRequired) + { + this.Invoke(new ItemChangedEventHandler(DataManager_ItemChanged), sender, e); + return; + } + if (_DataManager != null) + { + if (e==null || e.Index == -1) + { + this.SetItemsCore(_DataManager.List); + if (this.AllowSelection) + { + if (_DataManager.Position == -1) + this.SelectedNode = null; + else + this.SelectedNode = _AdvTree.FindNodeByBindingIndex(_DataManager.Position); + } + } + else + { + this.SetItemCore(e.Index, _DataManager.List[e.Index]); + } + } + } + private void DataManager_PositionChanged(object sender, EventArgs e) + { + if ((_DataManager != null) && this.AllowSelection) + { + if (_DataManager.Position == -1) + this.SelectedNode = null; + else + this.SelectedNode = _AdvTree.FindNodeByBindingIndex(_DataManager.Position); + //this.SelectedIndex = _DataManager.Position; + } + } + + /// + /// When overridden in a derived class, resynchronizes the item data with the contents of the data source. + /// + public virtual void RefreshItems() + { + if (_DataManager != null) + { + SetItemsCore(_DataManager.List); + if (this.AllowSelection) + { + if (_DataManager.Position == -1) + this.SelectedNode = null; + else + this.SelectedNode = _AdvTree.FindNodeByBindingIndex(_DataManager.Position); + } + } + } + + private bool IsSimpleType(object current) + { + if (current == null) return false; + return current is string || current.GetType().IsPrimitive; + } + /// + /// When overridden in a derived class, sets the specified array of objects in a collection in the derived class. + /// + /// An array of items. + protected virtual void SetItemsCore(IList items) + { + if(this.DesignMode) return; + _AdvTree.BeginUpdate(); + _AdvTree.ClearAndDisposeAllNodes(); + + bool isGrouping = !string.IsNullOrEmpty(_GroupingMembers); + + List fieldNames = new List(); + // Create Columns + if (string.IsNullOrEmpty(this.DisplayMembers)) + { + if (_AdvTree.Columns.Count > 0) + { + foreach (DevComponents.AdvTree.ColumnHeader columnHeader in _AdvTree.Columns) + { + if(!string.IsNullOrEmpty(columnHeader.DataFieldName)) + fieldNames.Add(columnHeader.DataFieldName); + } + } + if (fieldNames.Count == 0) + { + _AdvTree.Columns.Clear(); + if (_DataManager.List is Array) + { + DevComponents.AdvTree.ColumnHeader ch = new DevComponents.AdvTree.ColumnHeader("Items"); + ch.Width.Relative = 100; + _AdvTree.Columns.Add(ch); + OnDataColumnCreated(new DataColumnEventArgs(ch)); + } + else if (_DataManager != null) + { + if (_DataManager.Current != null && IsSimpleType(_DataManager.Current)) + { + DevComponents.AdvTree.ColumnHeader ch = new DevComponents.AdvTree.ColumnHeader(); + ch.Width.Relative = 100; + _AdvTree.Columns.Add(ch); + OnDataColumnCreated(new DataColumnEventArgs(ch)); + } + else + { + PropertyDescriptorCollection properties = _DataManager.GetItemProperties(); + foreach (PropertyDescriptor prop in properties) + { + fieldNames.Add(prop.Name); + DevComponents.AdvTree.ColumnHeader ch = new DevComponents.AdvTree.ColumnHeader(StringHelper.GetFriendlyName(prop.Name)); + ch.DataFieldName = prop.Name; + ch.Width.Relative = Math.Max(10, 100 / properties.Count); + _AdvTree.Columns.Add(ch); + OnDataColumnCreated(new DataColumnEventArgs(ch)); + } + } + } + } + } + else + { + _AdvTree.Columns.Clear(); + if (_DisplayMembers != null && _DisplayMembers.Count > 0) + { + foreach (BindingMemberInfo item in _DisplayMembers) + { + DevComponents.AdvTree.ColumnHeader ch = new DevComponents.AdvTree.ColumnHeader(StringHelper.GetFriendlyName(item.BindingMember)); + ch.Tag = item; + ch.Width.Relative = Math.Max(10, 100 / _DisplayMembers.Count); + _AdvTree.Columns.Add(ch); + fieldNames.Add(item.BindingMember); + OnDataColumnCreated(new DataColumnEventArgs(ch)); + } + } + } + + if (string.IsNullOrEmpty(_GroupingMembers) && string.IsNullOrEmpty(_ParentFieldNames)) + { + for (int i = 0; i < items.Count; i++) + { + object item = items[i]; + Node node = CreateNode(_AdvTree.Nodes, item, i, fieldNames); + } + } + else if (!string.IsNullOrEmpty(_ParentFieldNames)) + { + isGrouping = true; + + Dictionary nodeParentCollection = new Dictionary(); + Dictionary> nodeNeedsParentCollection = new Dictionary>(); + string[] parentFields = _ParentFieldNames.Split(','); + + for (int i = 0; i < items.Count; i++) + { + object item = items[i]; + string nodeKey = GetItemText(item, parentFields[0]); + string parentKey = GetItemText(item, parentFields[1]); + Node parentNode = null; + if (nodeParentCollection.TryGetValue(parentKey, out parentNode)) + { + Node node = CreateNode(parentNode.Nodes, item, i, fieldNames); + nodeParentCollection.Add(nodeKey, node); + } + else + { + Node node = CreateNode(this.Nodes, item, i, fieldNames); + List list = null; + if (!nodeNeedsParentCollection.TryGetValue(parentKey, out list)) + { + list = new List(); + nodeNeedsParentCollection.Add(parentKey, list); + } + list.Add(node); + nodeParentCollection.Add(nodeKey, node); + } + } + // If there are nodes that needed a parent process them now + foreach (KeyValuePair> keyValue in nodeNeedsParentCollection) + { + Node parentNode = null; + if (nodeParentCollection.TryGetValue(keyValue.Key, out parentNode)) + { + foreach (Node node in keyValue.Value) + { + node.Remove(); + parentNode.Nodes.Add(node); + } + } + } + } + else + { + string[] groupFields = _GroupingMembers.Split(','); + for (int i = 0; i < groupFields.Length; i++) + { + groupFields[i] = groupFields[i].Trim(); + } + Dictionary _GroupTable = new Dictionary(); + for (int i = 0; i < items.Count; i++) + { + object item = items[i]; + NodeCollection parentCollection = _AdvTree.Nodes; + + // Find the parent collection to add item to + string key = ""; + for (int gi = 0; gi < groupFields.Length; gi++) + { + string text = GetItemText(item, groupFields[gi]); + key += text.ToLower() + "/"; + Node groupNode = null; + if (!_GroupTable.TryGetValue(key, out groupNode)) + { + groupNode = CreateGroupNode(parentCollection, text); + _GroupTable.Add(key, groupNode); + } + parentCollection = groupNode.Nodes; + } + + Node node = CreateNode(parentCollection, item, i, fieldNames); + } + } + + // If not grouping then remove the expand part space on left-hand side + if (isGrouping) + { + _AdvTree.ExpandWidth = 14; + } + else + { + _AdvTree.ExpandWidth = 0; + } + + _AdvTree.EndUpdate(); + } + /// + /// Raises the DataColumnCreated event. + /// + /// Provides event arguments. + protected virtual void OnDataColumnCreated(DataColumnEventArgs args) + { + if (DataColumnCreated != null) + DataColumnCreated(this, args); + } + + private Node CreateGroupNode(NodeCollection parentCollection, string text) + { + Node node = new Node(); + node.Text = text; + node.Style = _GroupNodeStyle; + node.Expanded = true; + node.Selectable = false; + parentCollection.Add(node); + DataNodeEventArgs eventArgs = new DataNodeEventArgs(node, null); + OnGroupNodeCreated(eventArgs); + return node; + } + /// + /// Raises the DataNodeCreated event. + /// + /// Provides event arguments. + protected virtual void OnGroupNodeCreated(DataNodeEventArgs dataNodeEventArgs) + { + if (GroupNodeCreated != null) GroupNodeCreated(this, dataNodeEventArgs); + } + + /// + /// Creates a new node for the data item. + /// + /// Item to create node for. + /// New instance of the node. + private Node CreateNode(NodeCollection parentCollection, object item, int itemIndex, List fieldNames) + { + Node node = new Node(); + parentCollection.Add(node); + + SetNodeData(node, item, fieldNames, itemIndex); + + DataNodeEventArgs eventArgs = new DataNodeEventArgs(node, item); + + OnDataNodeCreated(eventArgs); + + return eventArgs.Node; + } + + private void SetNodeData(Node node, object item, List fieldNames, int bindingIndex) + { + node.DataKey = item; + node.BindingIndex = bindingIndex; + + node.CreateCells(); + + if (fieldNames.Count > 0) + { + for (int i = 0; i < fieldNames.Count; i++) + { + object propertyValue = GetPropertyValue(item, fieldNames[i]); + if (propertyValue is Image) + { + node.Cells[i].Images.Image = (Image)propertyValue; + //node.Cells[i].Images.AutoDispose = true; + } + else + node.Cells[i].Text = GetItemText(item, fieldNames[i]); + } + } + else if (item != null) + node.Text = item.ToString(); + } + + + /// + /// Raises the DataNodeCreated event. + /// + /// Provides event arguments. + protected virtual void OnDataNodeCreated(DataNodeEventArgs dataNodeEventArgs) + { + if (DataNodeCreated != null) DataNodeCreated(this, dataNodeEventArgs); + } + + /// + /// When overridden in a derived class, sets the object with the specified index in the derived class. + /// + /// The array index of the object. + /// The object. + protected virtual void SetItemCore(int index, object value) + { + Node node = _AdvTree.FindNodeByBindingIndex(index); + if (node == null) return; + + List fieldNames = new List(); + + foreach (DevComponents.AdvTree.ColumnHeader column in _AdvTree.Columns) + { + if (!string.IsNullOrEmpty(column.DataFieldName)) + fieldNames.Add(column.DataFieldName); + } + + SetNodeData(node, value, fieldNames, index); + } + + private string _ParentFieldNames = ""; + /// + /// Gets or sets comma separated field or property names that holds the value that is used to identify node and parent node. Format expected is: FieldNodeId,ParentNodeFieldId. For example if your table represents departments, you have DepartmentId field which uniquely identifies a department and ParentDepartmentId field which identifies parent of the department if any you would set this property to DepartmentId,ParentDepartmentId. + /// Note that you can only use ParentFieldNames or GroupingMembers property but not both. If both are set ParentFieldName take precedence. + /// + [DefaultValue(""), Category("Data"), Description("Indicates comma separated field or property names that holds the value that is used to identify node and parent node. Format expected is: FieldNodeId,ParentNodeFieldId. For example if your table represents departments, you have DepartmentId field which uniquely identifies a department and ParentDepartmentId field which identifies parent of the department if any you would set this property to DepartmentId,ParentDepartmentId.")] + public string ParentFieldNames + { + get { return _ParentFieldNames; } + set + { + if (value == null) value = ""; + if (!string.IsNullOrEmpty(value)) + { + string[] fields = value.Split(','); + if (fields.Length != 2) + throw new ArgumentException("ParentFieldNames excepts two and only two fields/property names separated by comma character."); + if (string.IsNullOrEmpty(fields[0])) + throw new ArgumentException("ParentFieldNames excepts two and only two fields/property names separated by comma character. First field name is empty."); + if (string.IsNullOrEmpty(fields[1])) + throw new ArgumentException("ParentFieldNames excepts two and only two fields/property names separated by comma character. Second field name is empty."); + } + _ParentFieldNames = value; + OnParentFieldNamesChanged(); + } + } + + /// + /// Called when ParentFieldName property has changed. + /// + protected virtual void OnParentFieldNamesChanged() + { + RefreshItems(); + } + + private string _GroupingMembers = ""; + /// + /// Gets or sets comma separated list of field or property names that are used for grouping when data-binding is used. + /// + [DefaultValue(""), Category("Data"), Description("Indicates comma separated list of field or property names that are used for grouping when data-binding is used")] + public string GroupingMembers + { + get { return _GroupingMembers; } + set + { + if (value == null) value = ""; + _GroupingMembers = value; + OnGroupingMembersChanged(); + } + } + + /// + /// Called when GroupingMembers property has changed. + /// + protected virtual void OnGroupingMembersChanged() + { + RefreshItems(); + } + + private ElementStyle _GroupNodeStyle = null; + /// + /// Gets or sets style for automatically created group nodes when data-binding is used and GroupingMembers property is set. + /// + /// + /// Name of the style assigned or null value indicating that no style is used. + /// Default value is null. + /// + [Browsable(true), Category("Node Style"), DefaultValue(null), Editor("DevComponents.AdvTree.Design.ElementStyleTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Description("Gets or sets default style for the node.")] + public ElementStyle GroupNodeStyle + { + get { return _GroupNodeStyle; } + set + { + if (_GroupNodeStyle != value) + { + _GroupNodeStyle = value; + if (_DataManager != null && _AdvTree.Nodes != null) + RefreshItems(); + } + } + } + + private bool AllowSelection + { + get + { + return true; + } + } + + + private CurrencyManager _DataManager = null; + protected CurrencyManager DataManager + { + get + { + return _DataManager; + } + } + private bool _IsDataSourceInitEventHooked = false; + private void UnwireDataSource() + { + if (_DataSource is IComponent) + { + ((IComponent)_DataSource).Disposed -= new EventHandler(DataSourceDisposed); + } + ISupportInitializeNotification dataSource = _DataSource as ISupportInitializeNotification; + if ((dataSource != null) && _IsDataSourceInitEventHooked) + { + dataSource.Initialized -= new EventHandler(DataSourceInitialized); + _IsDataSourceInitEventHooked = false; + } + } + private void DataSourceDisposed(object sender, EventArgs e) + { + this.SetDataConnection(null, null, true); + } + private bool _IsDataSourceInitialized = false; + private void WireDataSource() + { + if (_DataSource is IComponent) + { + ((IComponent)_DataSource).Disposed += new EventHandler(DataSourceDisposed); + } + ISupportInitializeNotification dataSource = _DataSource as ISupportInitializeNotification; + if ((dataSource != null) && !dataSource.IsInitialized) + { + dataSource.Initialized += new EventHandler(DataSourceInitialized); + _IsDataSourceInitEventHooked = true; + _IsDataSourceInitialized = false; + } + else + { + _IsDataSourceInitialized = true; + } + } + private void DataSourceInitialized(object sender, EventArgs e) + { + this.SetDataConnection(_DataSource, _DisplayMembers, true); + } + /// + /// Raises the Format event. + /// + /// Event parameters + protected virtual void OnFormat(TreeConvertEventArgs e) + { + TreeConvertEventHandler handler = Format; + if (handler != null) + { + handler(this, e); + } + } + + private static TypeConverter stringTypeConverter; + public string GetItemText(object item, string fieldName) + { + object propertyValue = GetPropertyValue(item, fieldName); + if (!_FormattingEnabled) + { + if (item == null) + { + return string.Empty; + } + if (propertyValue == null) + { + return ""; + } + return Convert.ToString(propertyValue, CultureInfo.CurrentCulture); + } + + TreeConvertEventArgs e = new TreeConvertEventArgs(propertyValue, typeof(string), item, fieldName); + this.OnFormat(e); + if ((e.Value != item) && (e.Value is string)) + { + return (string)e.Value; + } + if (stringTypeConverter == null) + { + stringTypeConverter = TypeDescriptor.GetConverter(typeof(string)); + } + try + { + return (string)FormatHelper.FormatObject(propertyValue, typeof(string), GetFieldConverter(fieldName), stringTypeConverter, _FormatString, _FormatInfo, null, DBNull.Value); + } + catch (Exception ex) + { + if (ex is SecurityException || IsCriticalException(ex)) + { + throw; + } + return ((propertyValue != null) ? Convert.ToString(item, CultureInfo.CurrentCulture) : ""); + } + } + private static bool IsCriticalException(Exception ex) + { + return (((((ex is NullReferenceException) || (ex is StackOverflowException)) || ((ex is OutOfMemoryException) || (ex is ThreadAbortException))) || ((ex is ExecutionEngineException) || (ex is IndexOutOfRangeException))) || (ex is AccessViolationException)); + } + protected object GetPropertyValue(object item, string fieldName) + { + if ((item != null) && (fieldName.Length > 0)) + { + try + { + PropertyDescriptor descriptor; + if (_DataManager != null) + { + descriptor = _DataManager.GetItemProperties().Find(fieldName, true); + } + else + { + descriptor = TypeDescriptor.GetProperties(item).Find(fieldName, true); + } + if (descriptor != null) + { + item = descriptor.GetValue(item); + } + } + catch + { + } + } + return item; + } + /// + /// Gets or sets the index specifying the currently selected item. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Description("Gets or sets the index specifying the currently selected item.")] + public int SelectedIndex + { + get + { + if (_DataManager != null) + { + if (_AdvTree.SelectedNode == null || _AdvTree.SelectedNode.BindingIndex < 0) + return -1; + return _AdvTree.SelectedNode.BindingIndex; + } + if (_AdvTree.SelectedNode == null) return -1; + return _AdvTree.GetNodeFlatIndex(_AdvTree.SelectedNode); + } + set + { + SetSelectedIndex(value); + } + } + private void SetSelectedIndex(int value) + { + if (value == -1) + { + _AdvTree.SelectedNode = null; + return; + } + Node node = null; + if (_DataManager != null) + { + node = _AdvTree.FindNodeByBindingIndex(value); + } + else + { + node = _AdvTree.GetNodeByFlatIndex(value); + } + _AdvTree.SelectedNode = node; + } + /// + /// Raises the SelectedIndexChanged event. + /// + /// Event arguments. + protected virtual void OnSelectedIndexChanged(EventArgs e) + { + EventHandler handler = SelectedIndexChanged; + if (handler != null) + { + handler(this, e); + } + } + + protected override void OnParentChanged(EventArgs e) + { + if (this.DataSource != null && _AdvTree.Nodes.Count == 0 && _DisplayMembers!=null && _DisplayMembers.Count>0) + { + this.SetDataConnection(this.DataSource, _DisplayMembers, true); + _AdvTree.SetPendingLayout(); + } + + base.OnParentChanged(e); + } + + private BindingMemberInfo _ValueMember = new BindingMemberInfo(); + /// + /// Gets or sets the property to use as the actual value for the items in the control. Applies to data-binding scenarios. SelectedValue property will return the value of selected node as indicated by this property. + /// + [Category("Data"), DefaultValue(""), Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Description("property to use as the actual value for the items in the control. Applies to data-binding scenarios. SelectedValue property will return the value of selected node as indicated by this property.")] + public string ValueMember + { + get + { + return _ValueMember.BindingMember; + } + set + { + if (value == null) + { + value = ""; + } + BindingMemberInfo newValueMember = new BindingMemberInfo(value); + if (!newValueMember.Equals(_ValueMember)) + { + if (this.DisplayMembers.Length == 0 && this.Columns.Count == 0) + { + List list = new List(); + list.Add(newValueMember); + this.SetDataConnection(this.DataSource, list, false); + } + if (((_DataManager != null) && (value != null)) && ((value.Length != 0) && !this.BindingMemberInfoInDataManager(newValueMember))) + { + throw new ArgumentException("Invalid value for ValueMember", "value"); + } + _ValueMember = newValueMember; + this.OnValueMemberChanged(EventArgs.Empty); + this.OnSelectedValueChanged(EventArgs.Empty); + } + } + } + /// + /// Raises the ValueMemberChanged event. + /// + /// Event arguments. + protected virtual void OnValueMemberChanged(EventArgs e) + { + EventHandler handler = ValueMemberChanged; + if (handler != null) + { + handler(this, e); + } + } + /// + /// Raises the SelectedValueChanged event. + /// + /// Event arguments. + protected virtual void OnSelectedValueChanged(EventArgs e) + { + EventHandler handler = SelectedValueChanged; + if (handler != null) + { + handler(this, e); + } + } + /// + /// Gets or sets the value of the member property specified by the ValueMember property. + /// + [Browsable(false), DefaultValue(null), Bindable(true), Category("Data"), Description("Indicates value of the member property specified by the ValueMember property."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object SelectedValue + { + get + { + if (_DataManager != null && this.SelectedIndex != -1) + { + object item = _DataManager.List[this.SelectedIndex]; + return this.GetPropertyValue(item, _ValueMember.BindingField); + } + return null; + } + set + { + if (_DataManager != null) + { + string bindingField = _ValueMember.BindingField; + if (string.IsNullOrEmpty(bindingField)) + { + throw new InvalidOperationException("ValueMember property must be set to be able to set SelectedValue"); + } + PropertyDescriptor property = _DataManager.GetItemProperties().Find(bindingField, true); + System.Reflection.MethodInfo mi = _DataManager.GetType().GetMethod("Find", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + int num = -1; + if (mi != null) + { + num = (int)mi.Invoke(_DataManager, new object[] { property, value, true }); + } + else + { + //int num = _DataManager.Find(property, value, true); + // Provide an alternate implementation... + } + this.SelectedIndex = num; + } + } + } + + + //private void TextBoxSizeChanged(object sender, EventArgs e) + //{ + // if (!_InternalSizeUpdate) + // UpdateLayout(); + //} + + //private void TextBoxTextChanged(object sender, EventArgs e) + //{ + // base.Text = _TextBox.Text; + //} + + //private void TextBoxTextAlignChanged(object sender, EventArgs e) + //{ + // OnTextAlignChanged(e); + //} + ///// + ///// Raises the TextAlignChanged event. + ///// + //protected virtual void OnTextAlignChanged(EventArgs e) + //{ + // EventHandler eh = TextAlignChanged; + // if (eh != null) + // eh(this, e); + //} + + private Font _WatermarkFont = null; + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark font."), DefaultValue(null)] + public virtual Font WatermarkFont + { + get { return _WatermarkFont; } + set { _WatermarkFont = value; this.Invalidate(); } + } + + private Color _WatermarkColor = SystemColors.GrayText; + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark text color.")] + public virtual Color WatermarkColor + { + get { return _WatermarkColor; } + set { _WatermarkColor = value; this.Invalidate(); } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return _WatermarkColor != SystemColors.GrayText; + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + this.WatermarkColor = SystemColors.GrayText; + } + + private bool _WatermarkEnabled = true; + /// + /// Gets or sets whether watermark text is displayed if set for the input items. Default value is true. + /// + [DefaultValue(true), Description("Indicates whether watermark text is displayed if set for the input items.")] + public virtual bool WatermarkEnabled + { + get { return _WatermarkEnabled; } + set { _WatermarkEnabled = value; this.Invalidate(); } + } + + private string _WatermarkText = ""; + /// + /// Gets or sets the watermark text displayed on the input control when control is empty. + /// + [DefaultValue(""), Localizable(true), Description("Indicates watermark text displayed on the input control when control is empty."), Category("Watermark")] + public string WatermarkText + { + get { return _WatermarkText; } + set + { + if (value != null) + { + _WatermarkText = value; + this.Invalidate(); + } + } + } + + private eTextAlignment _WatermarkAlignment = eTextAlignment.Left; + /// + /// Gets or sets the watermark text alignment. Default value is left. + /// + [Browsable(true), DefaultValue(eTextAlignment.Left), Description("Indicates watermark text alignment."), Category("Watermark")] + public eTextAlignment WatermarkAlignment + { + get { return _WatermarkAlignment; } + set + { + if (_WatermarkAlignment != value) + { + _WatermarkAlignment = value; + this.Invalidate(); + } + } + } + + /// + /// Gets or sets whether FocusHighlightColor is used as background color to highlight text box when it has input focus. Default value is false. + /// + [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Indicates whether FocusHighlightColor is used as background color to highlight text box when it has input focus.")] + public bool FocusHighlightEnabled + { + get { return _FocusHighlightEnabled; } + set + { + if (_FocusHighlightEnabled != value) + { + _FocusHighlightEnabled = value; + //_TextBox.FocusHighlightEnabled = value; + if (this.Focused) + this.Invalidate(true); + } + } + } + + /// + /// Gets or sets the color used as background color to highlight text box when it has input focus and focus highlight is enabled. + /// + [Browsable(true), Category("Appearance"), Description("Indicates color used as background color to highlight text box when it has input focus and focus highlight is enabled.")] + public Color FocusHighlightColor + { + get { return _FocusHighlightColor; } + set + { + if (_FocusHighlightColor != value) + { + _FocusHighlightColor = value; + //_TextBox.FocusHighlightColor = value; + if (this.Focused) + this.Invalidate(true); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFocusHighlightColor() + { + return !_FocusHighlightColor.Equals(ColorScheme.GetColor(0xFFFF88)); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFocusHighlightColor() + { + FocusHighlightColor = ColorScheme.GetColor(0xFFFF88); + } + + private ElementStyle _BackgroundStyle = new ElementStyle(); + /// + /// Specifies the background style of the control. + /// + [Category("Style"), Description("Gets or sets control background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return _BackgroundStyle; } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _BackgroundStyle.StyleChanged -= new EventHandler(this.VisualPropertyChanged); + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + this.Invalidate(); + } + + private void VisualPropertyChanged(object sender, EventArgs e) + { + OnVisualPropertyChanged(); + } + + protected virtual void OnVisualPropertyChanged() + { + _ButtonGroup.InvalidateArrange(); + this.Invalidate(); + } + + protected override void Dispose(bool disposing) + { + if (_BackgroundStyle != null) _BackgroundStyle.StyleChanged -= new EventHandler(VisualPropertyChanged); + System.Windows.Forms.Timer timer = _SearchBufferExpireTimer; + _SearchBufferExpireTimer = null; + if (timer != null) + { + timer.Stop(); + timer.Dispose(); + } + if (_AdvTree != null) + { + _AdvTree.AfterNodeSelect -= new AdvTreeNodeEventHandler(TreeAfterNodeSelect); + _AdvTree.BeforeNodeSelect -= new AdvTreeNodeCancelEventHandler(TreeBeforeNodeSelect); + _AdvTree.NodeMouseDown -= new TreeNodeMouseEventHandler(TreeNodeMouseDown); + } + if(_DropDownControl!=null) + { + _DropDownControl.Dispose(); + _DropDownControl = null; + } + base.Dispose(disposing); + } + + private InputButtonSettings _ButtonDropDown = null; + /// + /// Gets the object that describes the settings for the button that shows drop-down when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the button that shows drop-down when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonDropDown + { + get + { + return _ButtonDropDown; + } + } + + private InputButtonSettings _ButtonClear = null; + /// + /// Gets the object that describes the settings for the button that clears the content of the control when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the button that clears the content of the control when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonClear + { + get + { + return _ButtonClear; + } + } + + + private InputButtonSettings _ButtonCustom = null; + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get + { + return _ButtonCustom; + } + } + + private InputButtonSettings _ButtonCustom2 = null; + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get + { + return _ButtonCustom2; + } + } + + + void IInputButtonControl.InputButtonSettingsChanged(InputButtonSettings inputButtonSettings) + { + OnInputButtonSettingsChanged(inputButtonSettings); + } + + protected virtual void OnInputButtonSettingsChanged(InputButtonSettings inputButtonSettings) + { + UpdateButtons(); + } + + private VisualGroup _ButtonGroup = null; + private void UpdateButtons() + { + RecreateButtons(); + _ButtonGroup.InvalidateArrange(); + this.Invalidate(); + } + + protected virtual void RecreateButtons() + { + VisualItem[] buttons = CreateOrderedButtonList(); + // Remove all system buttons that are already in the list + VisualGroup group = _ButtonGroup; + VisualItem[] items = new VisualItem[group.Items.Count]; + group.Items.CopyTo(items); + foreach (VisualItem item in items) + { + if (item.ItemType == eSystemItemType.SystemButton) + { + group.Items.Remove(item); + if (item == _ButtonCustom.ItemReference) + item.MouseUp -= new MouseEventHandler(CustomButtonClick); + else if (item == _ButtonCustom2.ItemReference) + item.MouseUp -= new MouseEventHandler(CustomButton2Click); + } + } + + // Add new buttons to the list + group.Items.AddRange(buttons); + } + + private void CustomButtonClick(object sender, MouseEventArgs e) + { + if (_ButtonCustom.ItemReference.RenderBounds.Contains(e.X, e.Y)) + OnButtonCustomClick(e); + } + + protected virtual void OnButtonCustomClick(EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + private void CustomButton2Click(object sender, MouseEventArgs e) + { + if (_ButtonCustom2.ItemReference.RenderBounds.Contains(e.X, e.Y)) + OnButtonCustom2Click(e); + } + + protected virtual void OnButtonCustom2Click(EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + private VisualItem[] CreateOrderedButtonList() + { + SortedList list = CreateSortedButtonList(); + + VisualItem[] items = new VisualItem[list.Count]; + list.Values.CopyTo(items, 0); + + return items; + } + + protected virtual SortedList CreateSortedButtonList() + { + SortedList list = new SortedList(4); + if (_ButtonCustom.Visible) + { + VisualItem button = CreateButton(_ButtonCustom); + if (_ButtonCustom.ItemReference != null) + { + _ButtonCustom.ItemReference.MouseUp -= new MouseEventHandler(CustomButtonClick); + _ButtonCustom.ItemReference.Click -= CustomButtonKeyClick; + } + _ButtonCustom.ItemReference = button; + button.Click += CustomButtonKeyClick; + button.MouseUp += new MouseEventHandler(CustomButtonClick); + button.Enabled = _ButtonCustom.Enabled; + list.Add(_ButtonCustom, button); + } + + if (_ButtonCustom2.Visible) + { + VisualItem button = CreateButton(_ButtonCustom2); + if (_ButtonCustom2.ItemReference != null) + { + _ButtonCustom2.ItemReference.MouseUp -= new MouseEventHandler(CustomButton2Click); + _ButtonCustom2.ItemReference.Click -= CustomButton2KeyClick; + } + _ButtonCustom2.ItemReference = button; + button.Click += CustomButton2KeyClick; + button.MouseUp += new MouseEventHandler(CustomButton2Click); + button.Enabled = _ButtonCustom2.Enabled; + list.Add(_ButtonCustom2, button); + } + + if (_ButtonClear.Visible) + { + VisualItem button = CreateButton(_ButtonClear); + if (_ButtonClear.ItemReference != null) + { + _ButtonClear.ItemReference.MouseUp -= ClearButtonClick; + _ButtonClear.ItemReference.Click -= ClearButtonKeyClick; + } + _ButtonClear.ItemReference = button; + button.MouseUp += ClearButtonClick; + button.Click += ClearButtonKeyClick; + list.Add(_ButtonClear, button); + } + + if (_ButtonDropDown.Visible) + { + VisualItem button = CreateButton(_ButtonDropDown); + if (_ButtonDropDown.ItemReference != null) + { + _ButtonDropDown.ItemReference.MouseDown -= new MouseEventHandler(DropDownButtonMouseDown); + _ButtonDropDown.ItemReference.Click -= DropDownButtonKeyClick; + } + _ButtonDropDown.ItemReference = button; + button.MouseDown += new MouseEventHandler(DropDownButtonMouseDown); + button.Click += DropDownButtonKeyClick; + list.Add(_ButtonDropDown, button); + } + + return list; + } + + private void ClearButtonKeyClick(object sender, EventArgs e) + { + if (e is KeyEventArgs) + ClearButtonClick(sender, e); + } + private void CustomButtonKeyClick(object sender, EventArgs e) + { + if (e is KeyEventArgs) + OnButtonCustomClick(e); + } + private void CustomButton2KeyClick(object sender, EventArgs e) + { + if (e is KeyEventArgs) + OnButtonCustom2Click(e); + } + private void DropDownButtonKeyClick(object sender, EventArgs e) + { + if (e is KeyEventArgs) + IsPopupOpen = !IsPopupOpen; + } + protected virtual VisualItem CreateButton(InputButtonSettings buttonSettings) + { + VisualItem item = null; + + if (buttonSettings == _ButtonDropDown) + { + item = new VisualDropDownButton(); + ApplyButtonSettings(buttonSettings, item as VisualButton); + } + else + { + item = new VisualCustomButton(); + ApplyButtonSettings(buttonSettings, item as VisualButton); + } + + VisualButton button = item as VisualButton; + button.ClickAutoRepeat = false; + + if (buttonSettings == _ButtonClear) + { + if (buttonSettings.Image == null && string.IsNullOrEmpty(buttonSettings.Text)) + { + //if (Dpi.Factor.Width > 1) + button.Symbol = "\uf00d"; + //else + // button.Image = DevComponents.DotNetBar.BarFunctions.LoadBitmap("SystemImages.DateReset.png"); + } + } + + return item; + } + + protected virtual void ApplyButtonSettings(InputButtonSettings buttonSettings, VisualButton button) + { + button.Text = buttonSettings.Text; + button.Image = buttonSettings.Image; + button.ItemType = eSystemItemType.SystemButton; + button.Enabled = buttonSettings.Enabled; + button.Shortcut = buttonSettings.Shortcut; + button.Tooltip = buttonSettings.Tooltip; + button.Symbol = buttonSettings.Symbol; + button.SymbolSet = buttonSettings.SymbolSet; + button.SymbolColor = buttonSettings.SymbolColor; + } + + private void CreateButtonGroup() + { + VisualGroup group = new VisualGroup(); + group.HorizontalItemSpacing = 0; + group.ArrangeInvalid += new EventHandler(ButtonGroupArrangeInvalid); + group.RenderInvalid += new EventHandler(ButtonGroupRenderInvalid); + group.ResetMouseHover += ButtonGroupRenderMouseHover; + _ButtonGroup = group; + } + + private void ButtonGroupRenderInvalid(object sender, EventArgs e) + { + Invalidate(); + } + + private void ButtonGroupArrangeInvalid(object sender, EventArgs e) + { + Invalidate(); + } + + private void ButtonGroupRenderMouseHover(object sender, EventArgs e) + { + DevComponents.AdvTree.Interop.WinApi.ResetHover(this); + } + + private bool _MouseOver = false; + private PaintInfo CreatePaintInfo(Graphics g) + { + PaintInfo p = new PaintInfo(); + p.Graphics = g; + p.DefaultFont = this.Font; + p.ForeColor = this.ForeColor; + p.RenderOffset = new System.Drawing.Point(); + Size s = this.Size; + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + s.Height -= (ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.BottomWhiteSpace(style, eSpacePart.Border)) + 2; + s.Width -= (ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border)) + 2; + p.AvailableSize = s; + p.ParentEnabled = this.Enabled; + p.MouseOver = _MouseOver || this.Focused; + if(disposeStyle) style.Dispose(); + return p; + } + + private ElementStyle GetBackgroundStyle(out bool disposeStyle) + { + disposeStyle = false; + _BackgroundStyle.SetColorScheme(this.GetColorScheme()); + return ElementStyleDisplay.GetElementStyle(_BackgroundStyle, out disposeStyle); + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + Graphics g = e.Graphics; + Rectangle clientRect = this.ClientRectangle; + bool enabled = this.Enabled; + +#if !TRIAL + if (NativeFunctions.keyValidated2 != 266) + TextDrawing.DrawString(e.Graphics, "Invalid License", this.Font, Color.FromArgb(180, Color.Red), this.ClientRectangle, eTextFormat.Bottom | eTextFormat.HorizontalCenter); +#else + if (NativeFunctions.ColorExpAlt() || !NativeFunctions.CheckedThrough) + { + e.Graphics.Clear(SystemColors.Control); + return; + } +#endif + + if (!this.Enabled) + { + if (!_DisabledBackColor.IsEmpty) + { + using(SolidBrush brush=new SolidBrush(_DisabledBackColor)) + e.Graphics.FillRectangle(brush, clientRect); + } + else + e.Graphics.FillRectangle(SystemBrushes.Control, clientRect); + } + else + { + using (SolidBrush brush = new SolidBrush(this.BackColor)) + e.Graphics.FillRectangle(brush, clientRect); + } + + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + + if (style.Custom) + { + SmoothingMode sm = g.SmoothingMode; + if (this.AntiAlias) + g.SmoothingMode = SmoothingMode.AntiAlias; + ElementStyleDisplayInfo displayInfo = new ElementStyleDisplayInfo(style, g, clientRect); + if (!enabled) + { + ElementStyleDisplay.PaintBorder(displayInfo); + } + else + ElementStyleDisplay.Paint(displayInfo); + if (this.AntiAlias) + g.SmoothingMode = sm; + } + + Rectangle buttonBounds = PaintButtons(g); + // Paint selected content + Rectangle selectionRect = GetSelectionRectangle(style, clientRect); + if (!buttonBounds.IsEmpty) + { + Rectangle[] split = DisplayHelp.ExcludeRectangle(selectionRect, buttonBounds); + if (split.Length >= 1) + selectionRect = split[0]; + selectionRect.Width--; + } + + if (this.WatermarkEnabled && this.WatermarkText.Length > 0 && this.IsWatermarkRendered) + { + Rectangle watermarkBounds = selectionRect; + watermarkBounds.Inflate(-1, -1); + DrawWatermark(g, watermarkBounds); + } + + PaintSelection(g, selectionRect); + + if(disposeStyle) style.Dispose(); + } + + private void DrawWatermark(Graphics g, Rectangle r) + { + if (this.WatermarkText.Length == 0) return; + Font font = this.Font; + if (this.WatermarkFont != null) font = this.WatermarkFont; + + eTextFormat format = eTextFormat.Default; + if (_WatermarkAlignment == eTextAlignment.Center) + format |= eTextFormat.HorizontalCenter; + else if (_WatermarkAlignment == eTextAlignment.Right) + format |= eTextFormat.Right; + + TextDrawing.DrawString(g, this.WatermarkText, font, this.WatermarkColor, r, format); + } + + protected virtual bool IsWatermarkRendered + { + get + { + return !this.Focused && this.SelectedNode == null; + } + } + + private Rectangle GetSelectionRectangle(ElementStyle style, Rectangle clientRect) + { + return new Rectangle(ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + 1, + ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + 1, + clientRect.Width-(ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + 2), + clientRect.Height-(ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.BottomWhiteSpace(style, eSpacePart.Border) + 2)); + + } + + protected string GetSelectedDisplayMemberText(Node node) + { + int index = _AdvTree.Columns.IndexOfField(_SelectedDisplayMember); + if (index >= 0) + { + return node.Cells[index].Text; + } + // Try to get it from data + return GetItemText(node.DataKey, _SelectedDisplayMember); + } + + /// + /// Renders the selected node inside the combo box. + /// + /// Graphics reference. + /// Render bounds. + protected virtual void PaintSelection(Graphics g, Rectangle bounds) + { + if (bounds.Width < 2 || bounds.Height < 2) return; + + if (this.Focused && !this.IsPopupOpen) + { + SelectionRendererEventArgs selectionArgs = new SelectionRendererEventArgs(); + selectionArgs.Bounds = bounds; + selectionArgs.Graphics = g; + selectionArgs.SelectionBoxStyle = eSelectionStyle.HighlightCells; + selectionArgs.TreeActive = true; + ((DevComponents.AdvTree.Display.NodeTreeDisplay)_AdvTree.NodeDisplay).GetTreeRenderer().DrawSelection(selectionArgs); + } + + Node node = _AdvTree.SelectedNode; + if (node != null) + { + if (node.BoundsRelative.IsEmpty || _AdvTree.IsLayoutPending || node.BoundsRelative.Width <= 0 || _AdvTree.Width <= 0) + { + UpdateTreeSize(); + if (_AdvTree.IsLayoutPending) _AdvTree.RecalcLayout(); + } + + Region oldClip = g.Clip; + g.SetClip(bounds); + + Rectangle nodeRenderBounds = bounds; + + if (!string.IsNullOrEmpty(_SelectedDisplayMember)) + { + string text = GetSelectedDisplayMemberText(node); + + if (string.IsNullOrEmpty(text) == false) + { + nodeRenderBounds.Y--; + nodeRenderBounds.X++; + nodeRenderBounds.Width--; + + TextDrawing.DrawString(g, text, Font, Enabled ? ForeColor : SystemColors.ControlDark, + nodeRenderBounds, eTextFormat.Left | eTextFormat.NoClipping | eTextFormat.NoPadding | eTextFormat.VerticalCenter); + } + } + else + { + + if (DevComponents.AdvTree.Display.NodeDisplay.DrawExpandPart(node)) + { + nodeRenderBounds.X -= _AdvTree.ExpandWidth; + } + else + nodeRenderBounds.X -= (node.Bounds.X - node.BoundsRelative.X - 2); + if (nodeRenderBounds.Height > node.BoundsRelative.Height) + nodeRenderBounds.Y += (nodeRenderBounds.Height - node.BoundsRelative.Height) / 2; + else + nodeRenderBounds.Y += 1; + bool oldEnabled = node.Enabled; + if (node.Enabled != this.Enabled) + node.Enabled = this.Enabled; + bool oldSelectionVisible = node.IsSelectionVisible; + node.IsSelectionVisible = this.Focused && !this.IsPopupOpen; + ((DevComponents.AdvTree.Display.NodeTreeDisplay)_AdvTree.NodeDisplay).ExternalPaintNode(node, g, nodeRenderBounds); + node.Enabled = oldEnabled; + node.IsSelectionVisible = oldSelectionVisible; + } + + g.Clip = oldClip; + if(oldClip!=null) oldClip.Dispose(); + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColor() + { + return this.BackColor != SystemColors.Window; + } + + //protected override void OnBackColorChanged(EventArgs e) + //{ + // base.OnBackColorChanged(e); + // _TextBox.BackColor = this.BackColor; + //} + + private Rectangle PaintButtons(Graphics g) + { + PaintInfo p = CreatePaintInfo(g); + + if (!_ButtonGroup.IsLayoutValid) + { + UpdateLayout(p); + } + + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + _ButtonGroup.RenderBounds = GetButtonsRenderBounds(style); + _ButtonGroup.ProcessPaint(p); + if(disposeStyle) style.Dispose(); + return _ButtonGroup.RenderBounds; + } + + private Rectangle GetButtonsRenderBounds(ElementStyle style) + { + if (this.RightToLeft == RightToLeft.Yes) + { + return new Rectangle((ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + 1), ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + 1, + _ButtonGroup.Size.Width, _ButtonGroup.Size.Height); + } + + return new Rectangle(this.Width - (ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border) + 1) - _ButtonGroup.Size.Width, ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + 1, + _ButtonGroup.Size.Width, _ButtonGroup.Size.Height); + } + + protected override void OnResize(EventArgs e) + { + _ButtonGroup.InvalidateArrange(); + UpdateLayout(); + this.Invalidate(); + base.OnResize(e); + } + + protected override void OnEnter(EventArgs e) + { + this.Invalidate(); + base.OnEnter(e); + } + + protected override void OnLeave(EventArgs e) + { + if (this.IsPopupOpen) this.IsPopupOpen = false; + this.Invalidate(); + base.OnLeave(e); + } + + //protected override void OnGotFocus(EventArgs e) + //{ + // if(_TextBox.Visible) + // _TextBox.Focus(); + // base.OnGotFocus(e); + //} + + protected override void OnKeyDown(KeyEventArgs e) + { + _ButtonGroup.ProcessKeyDown(e); + base.OnKeyDown(e); + } + + private bool _EnterKeyTogglesPopup = true; + /// + /// Indicates whether Enter key when pressed while control has input focus toggles the popup. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether Enter key when pressed while control has input focus toggles the popup.")] + public bool EnterKeyTogglesPopup + { + get { return _EnterKeyTogglesPopup; } + set + { + _EnterKeyTogglesPopup = value; + } + } + + + protected override bool OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + if (this.Focused) + { + Keys key = (Keys)NativeFunctions.MapVirtualKey((uint)wParam, 2); + if (key == Keys.None) + key = (Keys)WinApi.ToInt(wParam); + if (key == Keys.F4) + { + this.IsPopupOpen = !this.IsPopupOpen; + return true; + } + else if (((key == Keys.Down && (Control.ModifierKeys & Keys.Alt) != 0) || key == Keys.Enter && _EnterKeyTogglesPopup) && !this.IsPopupOpen) + { + this.IsPopupOpen = !this.IsPopupOpen; + return true; + } + else if (this.IsPopupOpen && (key == Keys.Tab || key == Keys.Enter)) + { + this.IsPopupOpen = false; + if(key == Keys.Enter) + return true; + } + else if (this.IsPopupOpen) + { + if (key == Keys.Up) + { + this.SelectPreviousNode(eTreeAction.Keyboard); + return true; + } + else if (key == Keys.Down) + { + this.SelectNextNode(eTreeAction.Keyboard); + return true; + } + else + { + try + { + byte[] keyState = new byte[256]; + if (NativeFunctions.GetKeyboardState(keyState)) + { + byte[] chars = new byte[2]; + if (NativeFunctions.ToAscii((uint)key, 0, keyState, chars, 0) != 0) + { + char[] characters = new char[2]; + System.Text.Encoding.Default.GetDecoder().GetChars(chars, 0, 2, characters, 0); + if (ProcessKeyboardCharacter(characters[0])) + return true; + } + } + } + catch (Exception) + { + + } + } + } + } + return base.OnKeyDown(hWnd, wParam, lParam); + } + + protected override void OnKeyUp(KeyEventArgs e) + { + _ButtonGroup.ProcessKeyUp(e); + base.OnKeyUp(e); + } + + protected override bool IsInputChar(char charCode) + { + if(_KeyboardSearchEnabled && char.IsLetterOrDigit(charCode)) + return true; + return base.IsInputChar(charCode); + } + + protected override void OnKeyPress(KeyPressEventArgs e) + { + if(_KeyboardSearchEnabled) + e.Handled = ProcessKeyboardCharacter(e.KeyChar); + if(!e.Handled) + _ButtonGroup.ProcessKeyPress(e); + base.OnKeyPress(e); + } + + private bool _KeyboardSearchEnabled = true; + /// + /// Gets or sets whether keyboard incremental search is enabled. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether keyboard incremental search is enabled.")] + public bool KeyboardSearchEnabled + { + get { return _KeyboardSearchEnabled; } + set + { + _KeyboardSearchEnabled = value; + } + } + + private bool _KeyboardSearchNoSelectionAllowed = true; + /// + /// Gets or sets whether during keyboard search selected node can be set to nothing/null if there is no match found. + /// Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether during keyboard search selected node can be set to nothing/null if there is no match found.")] + public bool KeyboardSearchNoSelectionAllowed + { + get { return _KeyboardSearchNoSelectionAllowed; } + set + { + _KeyboardSearchNoSelectionAllowed = value; + } + } + + + + private System.Windows.Forms.Timer _SearchBufferExpireTimer = null; + private bool ProcessKeyboardCharacter(char p) + { + if (!char.IsLetterOrDigit(p)) return false; + string searchString = UpdateSearchBuffer(p.ToString()); + Node node = _AdvTree.FindNodeByText(searchString, _AdvTree.SelectedNode, true); + if (node == null && _AdvTree.SelectedNode != null) + { + // Try from top searching + node = _AdvTree.FindNodeByText(searchString, true); + } + // If binding to data do not select the groupping virtual nodes + if (_DataSource != null && node != null && node.BindingIndex == -1) + { + while (node != null && node.BindingIndex == -1) + node = _AdvTree.FindNodeByText(searchString, node, true); + } + if (!_KeyboardSearchNoSelectionAllowed && node == null) return false; + + SelectNode(node, eTreeAction.Keyboard); + return false; + } + + private int _SearchBufferExpireTimeout = 1000; + /// + /// Gets or sets the keyboard search buffer expiration timeout. Default value is 1000 which indicates that + /// key pressed within 1 second will add to the search buffer and control will be searched for node text + /// that begins with resulting string. Setting this value to 0 will disable the search buffer. + /// + [DefaultValue(1000), Category("Behavior"), Description("Indicates keyboard search buffer expiration timeout.")] + public int SearchBufferExpireTimeout + { + get { return _SearchBufferExpireTimeout; } + set + { + if (value < 0) value = 0; + _SearchBufferExpireTimeout = value; + } + } + + private string _SearchBuffer = ""; + private string UpdateSearchBuffer(string s) + { + if (_SearchBufferExpireTimeout <= 0) + return s; + + if (_SearchBufferExpireTimer == null) + { + _SearchBufferExpireTimer = new System.Windows.Forms.Timer(); + _SearchBufferExpireTimer.Interval = _SearchBufferExpireTimeout; + _SearchBufferExpireTimer.Tick += new EventHandler(SearchBufferExpireTimerTick); + _SearchBufferExpireTimer.Start(); + } + else + _SearchBufferExpireTimer.Start(); + _SearchBuffer += s; + return _SearchBuffer; + } + + private void SearchBufferExpireTimerTick(object sender, EventArgs e) + { + _SearchBufferExpireTimer.Stop(); + _SearchBuffer = ""; + } + + protected override bool ProcessMnemonic(char charCode) + { + if (this.Focused && Control.ModifierKeys != Keys.Alt) + return true; + return base.ProcessMnemonic(charCode); + } + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if ((keyData & Keys.Down) == Keys.Down && (Control.ModifierKeys & Keys.Alt) != 0 && !this.IsPopupOpen) + { + this.IsPopupOpen = !this.IsPopupOpen; + return true; + } + else if (keyData == Keys.Up) + { + this.SelectPreviousNode(eTreeAction.Keyboard); + return true; + } + else if (keyData == Keys.Down) + { + this.SelectNextNode(eTreeAction.Keyboard); + return true; + } + if (_ButtonGroup.ProcessCmdKey(ref msg, keyData)) + return true; + return base.ProcessCmdKey(ref msg, keyData); + } + + private void SelectNextNode(eTreeAction action) + { + Node node = null; + if (this.SelectedNode == null) + node = NodeOperations.GetFirstVisibleNode(_AdvTree); + else + node = NodeOperations.GetNextVisibleNode(this.SelectedNode); + + if (node != null && !node.CanSelect) + { + int counter = 0; + while (node != null && counter < 100) + { + node = NodeOperations.GetNextVisibleNode(node); + if (node != null && node.CanSelect) break; + } + } + + if (node != null) + { + if (_DataManager != null) + { + while (node != null && node.DataKey == null) + node = NodeOperations.GetNextVisibleNode(node); + if (node != null) + SelectNode(node, action); + } + else + SelectNode(node, action); + } + } + + private void SelectPreviousNode(eTreeAction action) + { + Node node = null; + if (this.SelectedNode == null) + node = NodeOperations.GetLastVisibleNode(_AdvTree); + else + node = NodeOperations.GetPreviousVisibleNode(this.SelectedNode); + + if (node != null && !node.CanSelect) + { + int counter = 0; + while (node != null && counter < 100) + { + node = NodeOperations.GetPreviousVisibleNode(node); + if (node != null && node.CanSelect) break; + } + } + + if (node != null) + { + if (_DataManager != null) + { + while (node != null && node.DataKey == null) + node = NodeOperations.GetNextVisibleNode(node); + if (node != null) + SelectNode(node, action); + } + else + SelectNode(node, action); + } + } + + private void SelectNode(Node node, eTreeAction action) + { + _AdvTree.SelectNode(node, action); + } + + protected override void OnRightToLeftChanged(EventArgs e) + { + _ButtonGroup.InvalidateArrange(); + UpdateLayout(); + this.Invalidate(); + base.OnRightToLeftChanged(e); + } + + protected override void OnFontChanged(EventArgs e) + { + _ButtonGroup.InvalidateArrange(); + _AdvTree.Font = this.Font; + UpdateLayout(); + this.Invalidate(); + base.OnFontChanged(e); + } + + private void UpdateLayout() + { + using (Graphics g = BarFunctions.CreateGraphics(this)) + UpdateLayout(CreatePaintInfo(g)); + } + + private bool _InternalSizeUpdate = false; + private void UpdateLayout(PaintInfo p) + { + if (_InternalSizeUpdate) return; + + _InternalSizeUpdate = true; + + try + { + if (!_ButtonGroup.IsLayoutValid) + { + _ButtonGroup.PerformLayout(p); + } + + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + + Rectangle textBoxControlRect = ElementStyleLayout.GetInnerRect(style, this.ClientRectangle); + if (RenderButtons) + { + Rectangle buttonsRect = GetButtonsRenderBounds(style); + if (this.RightToLeft == RightToLeft.Yes) + { + textBoxControlRect.X += buttonsRect.Right; + textBoxControlRect.Width -= buttonsRect.Right; + } + else + { + textBoxControlRect.Width -= (textBoxControlRect.Right - buttonsRect.X); + } + } + + if (disposeStyle) style.Dispose(); + //if (_TextBox.PreferredHeight < textBoxControlRect.Height) + //{ + // textBoxControlRect.Y += (textBoxControlRect.Height - _TextBox.PreferredHeight) / 2; + //} + //_TextBox.Bounds = textBoxControlRect; + } + finally + { + _InternalSizeUpdate = false; + } + } + + private Control _PreviousDropDownControlParent = null; + private void DropDownButtonMouseDown(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Left || _CloseTime != DateTime.MinValue && DateTime.Now.Subtract(_CloseTime).TotalMilliseconds < 250) + { + _CloseTime = DateTime.MinValue; + return; + } + + ShowDropDown(); + } + /// + /// Updates popup tree size based on its content. + /// + public void UpdateTreeSize() + { + _AdvTree.BeginUpdate(); + bool recalcLayout = false; + if (_DropDownWidth == 0) + { + if (_AdvTree.Width != this.Width - 4) + { + _AdvTree.Width = this.Width - 4; + recalcLayout = true; + } + } + + if (_DropDownHeight == 0) + _AdvTree.Height = 600; + else + _AdvTree.Height = _DropDownHeight; + _AdvTree.EndUpdate(false); + + if (_DropDownHeight == 0) + { + // Auto calculate height based on content + _AdvTree.RecalcLayout(); + ScreenInformation screenInfo = BarFunctions.ScreenFromControl(this); + if (screenInfo != null && _AdvTree.NodeLayout.Height > screenInfo.WorkingArea.Height / 2) + { + _AdvTree.Height = screenInfo.WorkingArea.Height / 2; + } + else if (_AdvTree.Nodes.Count > 0) + { + int height=_AdvTree.NodeLayout.Height + 4;//(_AdvTree.ColumnHeaderHeight > 0 ? (_AdvTree.ColumnHeaderHeight + 4) : 4); + if (_AdvTree.HScrollBar != null) + height += _AdvTree.HScrollBar.Height + 1; + _AdvTree.Height = height; + } + else + _AdvTree.Height = this.Height; + } + else + { + _AdvTree.Height = _DropDownHeight; + if (recalcLayout) + _AdvTree.RecalcLayout(); + } + } + + private bool _ShowingPopup = false; + /// + /// Shows drop-down popup. Note that popup will be shown only if there is a DropDownControl assigned or DropDownItems collection has at least one item. + /// + public void ShowDropDown() + { + + if (_DropDownControl == null && _PopupItem.SubItems.Count == 0 || _ShowingPopup || _PopupItem.Expanded) + return; + + _ShowingPopup = true; + try + { + ControlContainerItem cc = null; + ItemContainer ic = null; + if (_DropDownControl != null) + { + ic = new ItemContainer(); + ic.Name = _DropDownItemContainerName; + cc = new ControlContainerItem(_DropDownControlContainerName); + ic.SubItems.Add(cc); + _PopupItem.SubItems.Insert(0, ic); + } + + CancelEventArgs cancelArgs = new CancelEventArgs(); + OnButtonDropDownClick(cancelArgs); + if (cancelArgs.Cancel || _PopupItem.SubItems.Count == 0) + { + if (ic != null) + _PopupItem.SubItems.Remove(ic); + ic.Dispose(); + return; + } + + UpdateTreeSize(); + + _PreviousDropDownControlParent = _DropDownControl.Parent; + cc.Control = _DropDownControl; + + _PopupItem.SetDisplayRectangle(this.ClientRectangle); + if (_PopupLocation != null) + _PopupItem.PopupLocation = _PopupLocation.Value; + else if (this.RightToLeft == RightToLeft.No) + { + Point pl = new Point(this.Width - _PopupItem.PopupSize.Width, this.Height); + ScreenInformation screen = BarFunctions.ScreenFromControl(this); + Point ps = PointToScreen(pl); + if (screen != null && screen.WorkingArea.X > ps.X) + { + pl.X = 0; + } + _PopupItem.PopupLocation = pl; + } + if (!IsPopupOpen && this.SelectedNode != null) + this.SelectedNode.EnsureVisible(); + + _PopupItem.Expanded = !_PopupItem.Expanded; + } + finally + { + _ShowingPopup = false; + } + this.Invalidate(); + } + + /// + /// Closes the drop-down popup if it is open. + /// + public void CloseDropDown() + { + if (_PopupItem.Expanded) _PopupItem.Expanded = false; + } + + private DateTime _CloseTime = DateTime.MinValue; + private void DropDownPopupClose(object sender, EventArgs e) + { + _CloseTime = DateTime.Now; + ItemContainer ic = _PopupItem.SubItems[_DropDownItemContainerName] as ItemContainer; + if (ic != null) + { + ControlContainerItem cc = ic.SubItems[_DropDownControlContainerName] as ControlContainerItem; + if (cc != null) + { + cc.Control = null; + ic.SubItems.Remove(cc); + cc.Dispose(); + if (_DropDownControl != null) + { + _DropDownControl.Parent = _PreviousDropDownControlParent; + _PreviousDropDownControlParent = null; + } + } + _PopupItem.SubItems.Remove(ic); + ic.Dispose(); + } + this.Invalidate(); + } + + private Point? _PopupLocation = null; + /// + /// Indicates the custom popup location for the ComboTree popup + /// + [Browsable(false),DefaultValue(null), Category("Behavior"), Description("Indicates the custom popup location for the ComboTree popup"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Point? PopupLocation + { + get { return _PopupLocation; } + set + { + if (value != _PopupLocation) + { + Point? oldValue = _PopupLocation; + _PopupLocation = value; + OnPopupLocationChanged(oldValue, value); + } + } + } + /// + /// Called when PopupLocation property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPopupLocationChanged(Point? oldValue, Point? newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("PopupLocation")); + + } + + private void ClearButtonClick(object sender, EventArgs e) + { + if (_ButtonClear.Enabled) + { + CancelEventArgs cancelArgs = new CancelEventArgs(); + OnButtonClearClick(cancelArgs); + if (cancelArgs.Cancel) return; + + this.SelectedNode = null; + } + } + + /// + /// Raises the ButtonClearClick event. + /// + /// + protected virtual void OnButtonClearClick(CancelEventArgs e) + { + if (ButtonClearClick != null) + ButtonClearClick(this, e); + } + + /// + /// Raises the ButtonDropDownClick event. + /// + /// + protected virtual void OnButtonDropDownClick(CancelEventArgs e) + { + if (ButtonDropDownClick != null) + ButtonDropDownClick(this, e); + } + + private Control _DropDownControl = null; + /// + /// Gets or sets the reference of the control that will be displayed on popup that is shown when drop-down button is clicked. + /// + [DefaultValue(null), Description("Indicates reference of the control that will be displayed on popup that is shown when drop-down button is clicked.")] + internal Control DropDownControl + { + get { return _DropDownControl; } + set + { + _DropDownControl = value; + } + } + + protected override PopupItem CreatePopupItem() + { + ButtonItem button = new ButtonItem("sysPopupProvider"); + button.PopupFinalized += new EventHandler(DropDownPopupClose); + _PopupItem = button; + return button; + } + + /// + /// Gets the collection of BaseItem derived items displayed on popup menu. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SubItemsCollection DropDownItems + { + get { return _PopupItem.SubItems; } + } + + protected override void RecalcSize() + { + } + + public override void PerformClick() + { + } + + private bool RenderButtons + { + get + { + return _ButtonCustom != null && _ButtonCustom.Visible || _ButtonCustom2 != null && _ButtonCustom2.Visible || + _ButtonDropDown != null && _ButtonDropDown.Visible || _ButtonClear != null && _ButtonClear.Visible; + } + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseMove(e); + } + base.OnMouseMove(e); + } + protected override void OnMouseHover(EventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseHover(e); + } + base.OnMouseHover(e); + } + protected override void OnMouseLeave(EventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseLeave(); + } + base.OnMouseLeave(e); + } + protected override void OnMouseDown(MouseEventArgs e) + { + this.Focus(); + if (RenderButtons) + { + _ButtonGroup.ProcessMouseDown(e); + } + + Rectangle r = this.ClientRectangle; + r.Inflate(1, 1); + if (this.RenderButtons && !_ButtonGroup.RenderBounds.Contains(e.X, e.Y) && r.Contains(e.X, e.Y) && !IsPopupOpen) + { + if (_CloseTime != DateTime.MinValue && DateTime.Now.Subtract(_CloseTime).TotalMilliseconds < 150) + { + _CloseTime = DateTime.MinValue; + } + else if(e.Button == MouseButtons.Left) + IsPopupOpen = true; + } + + base.OnMouseDown(e); + } + protected override void OnMouseUp(MouseEventArgs e) + { + if (RenderButtons) + _ButtonGroup.ProcessMouseUp(e); + base.OnMouseUp(e); + } + + ///// + ///// Gets the reference to internal TextBox control. Use it to get access to the text box events and properties. + ///// + //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + //public TextBox TextBox + //{ + // get + // { + // return _TextBox; + // } + //} + /// + /// Gets the reference to internal AdvTree control that is displayed on popup Use it to get access to the AdvTree events and properties. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AdvTree.AdvTree AdvTree + { + get + { + return _AdvTree; + } + } + + ///// + ///// Gets or sets whether watermark text is displayed when control is empty. Default value is true. + ///// + //[DefaultValue(true), Description("Indicates whether watermark text is displayed when control is empty.")] + //public virtual bool WatermarkEnabled + //{ + // get { return _TextBox.WatermarkEnabled; } + // set { _TextBox.WatermarkEnabled = value; this.Invalidate(true); } + //} + + ///// + ///// Gets or sets the watermark (tip) text displayed inside of the control when Text is not set and control does not have input focus. This property supports text-markup. + ///// + //[Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus."), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + //public string WatermarkText + //{ + // get { return _TextBox.WatermarkText; } + // set + // { + // if (value == null) value = ""; + // _TextBox.WatermarkText = value; + // this.Invalidate(true); + // } + //} + + ///// + ///// Gets or sets the watermark font. + ///// + //[Browsable(true), Category("Appearance"), Description("Indicates watermark font."), DefaultValue(null)] + //public Font WatermarkFont + //{ + // get { return _TextBox.WatermarkFont; } + // set { _TextBox.WatermarkFont = value; this.Invalidate(true); } + //} + + ///// + ///// Gets or sets the watermark text color. + ///// + //[Browsable(true), Category("Appearance"), Description("Indicates watermark text color.")] + //public Color WatermarkColor + //{ + // get { return _TextBox.WatermarkColor; } + // set { _TextBox.WatermarkColor = value; this.Invalidate(); } + //} + ///// + ///// Indicates whether property should be serialized by Windows Forms designer. + ///// + //[EditorBrowsable(EditorBrowsableState.Never)] + //public bool ShouldSerializeWatermarkColor() + //{ + // return _TextBox.WatermarkColor != SystemColors.GrayText; + //} + ///// + ///// Resets the property to default value. + ///// + //[EditorBrowsable(EditorBrowsableState.Never)] + //public void ResetWatermarkColor() + //{ + // this.WatermarkColor = SystemColors.GrayText; + //} + + ///// + ///// Gets or sets the watermark hiding behaviour. Default value indicates that watermark is hidden when control receives input focus. + ///// + //[DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior"), Description("Indicates watermark hiding behaviour.")] + //public eWatermarkBehavior WatermarkBehavior + //{ + // get { return _TextBox.WatermarkBehavior; } + // set { _TextBox.WatermarkBehavior = value; this.Invalidate(true); } + //} + + private int _DropDownHeight = 0; + /// + /// Gets or sets the height in pixels of the drop-down portion of the ComboTreeBox control. + /// + [DefaultValue(0), Category("Behavior"), Description("Indicates height in pixels of the drop-down portion of the ComboTreeBox control.")] + public int DropDownHeight + { + get { return _DropDownHeight; } + set + { + if (value < 0) + throw new ArgumentException("DropDownHeight Value must be equal or greater than zero."); + _DropDownHeight = value; + OnDropDownSizeChanged(); + } + } + private int _DropDownWidth = 0; + /// + /// Gets or sets the width in pixels of the drop-down portion of the ComboTreeBox control. + /// + [DefaultValue(0), Category("Behavior"), Description("Indicates width in pixels of the drop-down portion of the ComboTreeBox control.")] + public int DropDownWidth + { + get { return _DropDownWidth; } + set + { + if (value < 0) + throw new ArgumentException("DropDownWidth Value must be equal or greater than zero."); + _DropDownWidth = value; + OnDropDownSizeChanged(); + } + } + private void OnDropDownSizeChanged() + { + _AdvTree.BeginUpdate(); + if (_DropDownWidth > 0) + _AdvTree.Width = _DropDownWidth; + if (_DropDownHeight > 0) + _AdvTree.Height = _DropDownHeight; + _AdvTree.EndUpdate(false); + } + + /// + /// Gets or sets a value indicating whether the combo box is displaying its drop-down portion. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPopupOpen + { + get + { + return _PopupItem.Expanded; + } + set + { + if (value != _PopupItem.Expanded) + { + if (value) + ShowDropDown(); + else + CloseDropDown(); + } + } + } + + /// + /// Gets the collection of tree nodes that are assigned to the popup tree view control. + /// + /// + /// A NodeCollection that represents the tree nodes + /// assigned to the tree control. + /// + /// + /// The Nodes property holds a collection of Node objects, each of which has a + /// Nodes property that can contain its own NodeCollection. + /// + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Description("Gets the collection of tree nodes that are assigned to the tree control.")] + public AdvTree.NodeCollection Nodes + { + get { return _AdvTree.Nodes; } + } + + /// + /// Gets the collection of column headers that appear in the popup tree. + /// + /// + /// By default there are no column headers defined. In that case tree control + /// functions as regular tree control where text has unrestricted width. + /// If you want to restrict the horizontal width of the text but not display + /// column header you can create one column and set its width to the width desired and + /// set its Visible property to false. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Columns"), Description("Gets collection of column headers that appear in the popup tree.")] + public ColumnHeaderCollection Columns + { + get + { + return _AdvTree.Columns; + } + } + + /// + /// Gets or sets whether column headers are visible if they are defined through Columns collection. Default value is true. + /// + [DefaultValue(true), Category("Columns"), Description("Indicates whether column headers are visible if they are defined through Columns collection.")] + public bool ColumnsVisible + { + get { return _AdvTree.ColumnsVisible; } + set + { + _AdvTree.ColumnsVisible = value; + } + } + /// + /// Gets or sets whether grid lines are displayed when columns are defined. Default value is true. + /// + [DefaultValue(true), Category("Columns"), Description("Indicates whether grid lines are displayed when columns are defined.")] + public bool GridColumnLines + { + get { return _AdvTree.GridColumnLines; } + set + { + _AdvTree.GridColumnLines = value; + } + } + /// + /// Gets or sets the grid lines color. + /// + [Category("Columns"), Description("Indicates grid lines color.")] + public Color GridLinesColor + { + get { return _AdvTree.GridLinesColor; } + set { _AdvTree.GridLinesColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeGridLinesColor() + { + return _AdvTree.ShouldSerializeGridLinesColor(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetGridLinesColor() + { + _AdvTree.ResetGridLinesColor(); + } + /// + /// Gets or sets whether horizontal grid lines between each row are displayed. Default value is false. + /// + [DefaultValue(false), Category("Columns"), Description("")] + public bool GridRowLines + { + get { return _AdvTree.GridRowLines; } + set + { + _AdvTree.GridRowLines = value; + } + } + /// + /// Gets or sets whether node is highlighted when mouse enters the node. Default value is false. + /// + /// + /// There are two ways to enable the node hot-tracking. You can set the HotTracking property to true in which case the + /// mouse tracking is enabled using system colors specified in TreeColorTable. You can also define the NodeStyleMouseOver + /// style which gets applied to the node when mouse is over the node. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether node is highlighted when mouse enters the node.")] + public bool HotTracking + { + get { return _AdvTree.HotTracking; } + set + { + _AdvTree.HotTracking = value; + } + } + + /// + /// Gets or sets the node selection box style for popup tree control. + /// + /// SelectionBox Property + /// SelectionBoxSize Property + /// SelectionBoxFillColor Property + /// SelectionBoxBorderColor Property + [DefaultValue(eSelectionStyle.HighlightCells), Category("Selection"), Description("Indicates node selection box style of popup tree control.")] + public eSelectionStyle SelectionBoxStyle + { + get { return _AdvTree.SelectionBoxStyle; } + set { _AdvTree.SelectionBoxStyle = value; } + } + + /// + /// Gets or sets the ImageList that contains the Image objects used by the tree nodes. + /// + [Browsable(true),DefaultValue(null),Category("Images"),Description("Indicates the ImageList that contains the Image objects used by the tree nodes.")] + public ImageList ImageList + { + get + { + return _AdvTree.ImageList; + } + set + { + _AdvTree.ImageList=value; + } + } + + /// + /// Gets or sets the image-list index value of the default image that is displayed by the tree nodes. + /// + [Browsable(true), Category("Images"), Description("Indicates the image-list index value of the default image that is displayed by the tree nodes."), Editor("DevComponents.AdvTree.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), TypeConverter(typeof(ImageIndexConverter)), DefaultValue(-1)] + public int ImageIndex + { + get { return _AdvTree.ImageIndex; } + set + { + _AdvTree.ImageIndex = value; + } + } + + private Color _DisabledBackColor = Color.Empty; + /// + /// Gets or sets the control background color when control is disabled. Default value is an empty color which indicates that system background color is used when control is disabled. + /// + [Description("Indicates control background color when control is disabled"), Category("Appearance")] + public Color DisabledBackColor + { + get { return _DisabledBackColor; } + set + { + if (_DisabledBackColor != value) + { + _DisabledBackColor = value; + if (!this.Enabled) this.Invalidate(); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeDisabledBackColor() + { + return !_DisabledBackColor.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetDisabledBackColor() + { + DisabledBackColor = Color.Empty; + } + #endregion + + #region Property Forwarding + ///// + ///// Gets or sets a custom StringCollection to use when the AutoCompleteSource property is set to CustomSource. + ///// A StringCollection to use with AutoCompleteSource. + ///// + //[Browsable(true), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Localizable(true), Description("Indicates custom StringCollection to use when the AutoCompleteSource property is set to CustomSource."), Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + //private AutoCompleteStringCollection AutoCompleteCustomSource + //{ + // get + // { + // return _TextBox.AutoCompleteCustomSource; + // } + // set + // { + // _TextBox.AutoCompleteCustomSource = value; + // } + //} + + ///// + ///// Gets or sets an option that controls how automatic completion works for the TextBox. + ///// One of the values of AutoCompleteMode. The values are Append, None, Suggest, and SuggestAppend. The default is None. + ///// + //[Description("Gets or sets an option that controls how automatic completion works for the TextBox."), Browsable(true), EditorBrowsable(EditorBrowsableState.Always), DefaultValue(0)] + //private AutoCompleteMode AutoCompleteMode + //{ + // get + // { + // return _TextBox.AutoCompleteMode; + // } + // set + // { + // _TextBox.AutoCompleteMode = value; + // } + //} + + ///// + ///// Gets or sets a value specifying the source of complete strings used for automatic completion. + ///// One of the values of AutoCompleteSource. The options are AllSystemSources, AllUrl, FileSystem, HistoryList, RecentlyUsedList, CustomSource, and None. The default is None. + ///// + //[DefaultValue(0x80), TypeConverter(typeof(TextBoxAutoCompleteSourceConverter)), Browsable(true), EditorBrowsable(EditorBrowsableState.Always), Description("Gets or sets a value specifying the source of complete strings used for automatic completion.")] + //private AutoCompleteSource AutoCompleteSource + //{ + // get + // { + // return _TextBox.AutoCompleteSource; + // } + // set + // { + // _TextBox.AutoCompleteSource = value; + // } + //} + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + CommandManager.ExecuteCommand(this); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + } + } + + private ICommand _Command = null; + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if (changed) + OnCommandChanged(); + } + } + + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + } + } + + #endregion + + #region Licensing +#if !TRIAL + private string _LicenseKey = ""; + [Browsable(false), DefaultValue("")] + public string LicenseKey + { + get { return _LicenseKey; } + set + { + if (NativeFunctions.ValidateLicenseKey(value)) + return; + _LicenseKey = (!NativeFunctions.CheckLicenseKey(value) ? "9dsjkhds7" : value); + } + } +#endif + #endregion + } + /// + /// Represents the method that will handle converting for ComboTree control. + /// + /// + /// + public delegate void TreeConvertEventHandler(object sender, TreeConvertEventArgs e); + + public class TreeConvertEventArgs : ConvertEventArgs + { + // Fields + private object _ListItem; + + // Methods + public TreeConvertEventArgs(object value, Type desiredType, object listItem, string fieldName) + : base(value, desiredType) + { + _ListItem = listItem; + _FieldName = fieldName; + } + + /// + /// Gets the reference to the item being converted. + /// + public object ListItem + { + get + { + return _ListItem; + } + } + + private string _FieldName = ""; + /// + /// Get the reference to the name of the field or property on the item that needs conversion. + /// + public string FieldName + { + get { return _FieldName; } + } + } + /// + /// Defines delegate for data node based events. + /// + public delegate void DataNodeEventHandler(object sender, DataNodeEventArgs e); + /// + /// Defines event arguments for data node based events. + /// + public class DataNodeEventArgs : EventArgs + { + /// + /// Gets or sets the node that is created for data item. + /// + public Node Node = null; + /// + /// Gets the data-item node is being created for. + /// + public readonly object DataItem = null; + + /// + /// Initializes a new instance of the DataNodeEventArgs class. + /// + /// + /// + public DataNodeEventArgs(Node node, object dataItem) + { + Node = node; + DataItem = dataItem; + } + } + /// + /// Defines delegate for data column based events. + /// + public delegate void DataColumnEventHandler(object sender, DataColumnEventArgs e); + /// + /// Defines event arguments for data column based events. + /// + public class DataColumnEventArgs : EventArgs + { + /// + /// Gets or sets the column header that is created for data. + /// + public DevComponents.AdvTree.ColumnHeader ColumnHeader = null; + + /// + /// Initializes a new instance of the DataColumnEventArgs class. + /// + /// + public DataColumnEventArgs(DevComponents.AdvTree.ColumnHeader header) + { + ColumnHeader = header; + } + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/ComboTree.ico b/PROMS/DotNetBar Source Code/Controls/ComboTree.ico new file mode 100644 index 00000000..9bed9b81 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/ComboTree.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/ControlWithBackgroundStyle.cs b/PROMS/DotNetBar Source Code/Controls/ControlWithBackgroundStyle.cs new file mode 100644 index 00000000..04ffa602 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ControlWithBackgroundStyle.cs @@ -0,0 +1,156 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false)] + public class ControlWithBackgroundStyle : Control + { + #region Private Variables + private ElementStyle _BackgroundStyle = null; + private bool _AntiAlias = true; + #endregion + + #region Events + #endregion + + #region Constructor + /// + /// Initializes a new instance of the ControlWithBackgroundStyle class. + /// + public ControlWithBackgroundStyle() + { + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(ControlStyles.StandardDoubleClick, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + } + #endregion + + #region Internal Implementation + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public virtual bool AntiAlias + { + get { return _AntiAlias; } + set + { + if (_AntiAlias != value) + { + _AntiAlias = value; + this.Invalidate(); + } + } + } + + /// + /// Specifies the background style of the control. + /// + [Category("Style"), Description("Indicates control background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return _BackgroundStyle; } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _BackgroundStyle.StyleChanged -= new EventHandler(this.VisualPropertyChanged); + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + this.Invalidate(); + } + + private void VisualPropertyChanged(object sender, EventArgs e) + { + OnVisualPropertyChanged(); + } + + protected virtual void OnVisualPropertyChanged() + { + this.Invalidate(); + } + + protected override void OnPaint(PaintEventArgs e) + { + if (this.BackColor.IsEmpty || this.BackColor == Color.Transparent) + { + base.OnPaintBackground(e); + } + + PaintBackground(e); + PaintContent(e); + + base.OnPaint(e); + } + + protected virtual void PaintContent(PaintEventArgs e) + { + + } + + protected virtual Rectangle GetContentRectangle() + { + bool disposeStyle = false; + ElementStyle style = this.GetBackgroundStyle(out disposeStyle); + Rectangle r = ElementStyleLayout.GetInnerRect(style, this.ClientRectangle); + if (disposeStyle) style.Dispose(); + //Rectangle r=this.ClientRectangle; + //r.X += ElementStyleLayout.LeftWhiteSpace(style); + //r.Y += ElementStyleLayout.TopWhiteSpace(style); + //r.Width -= ElementStyleLayout.HorizontalStyleWhiteSpace(style); + //r.Height -= ElementStyleLayout.VerticalStyleWhiteSpace(style); + + return r; + } + + protected virtual ElementStyle GetBackgroundStyle(out bool disposeStyle) + { + disposeStyle = false; + return ElementStyleDisplay.GetElementStyle(_BackgroundStyle, out disposeStyle); + } + + protected virtual void PaintBackground(PaintEventArgs e) + { + Graphics g = e.Graphics; + Rectangle r = this.ClientRectangle; + bool disposeStyle = false; + ElementStyle style = this.GetBackgroundStyle(out disposeStyle); + + if (!this.BackColor.IsEmpty) + { + DisplayHelp.FillRectangle(g, r, this.BackColor); + } + + if (style.Custom) + { + SmoothingMode sm = g.SmoothingMode; + if (this.AntiAlias) + g.SmoothingMode = SmoothingMode.HighQuality; + ElementStyleDisplayInfo displayInfo = new ElementStyleDisplayInfo(style, e.Graphics, r); + ElementStyleDisplay.Paint(displayInfo); + if (this.AntiAlias) + g.SmoothingMode = sm; + } + + if (disposeStyle) style.Dispose(); + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/CursorHelper.cs b/PROMS/DotNetBar Source Code/Controls/CursorHelper.cs new file mode 100644 index 00000000..e87c752b --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/CursorHelper.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + internal struct IconInfo + { + public bool fIcon; + public int xHotspot; + public int yHotspot; + public IntPtr hbmMask; + public IntPtr hbmColor; + } + internal class CursorHelper + { + [DllImport("user32.dll")] + public static extern IntPtr CreateIconIndirect(ref IconInfo icon); + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo); + [DllImport("gdi32.dll")] + public static extern bool DeleteObject(IntPtr handle); + [DllImport("user32.dll", CharSet = CharSet.Auto)] + extern static bool DestroyIcon(IntPtr handle); + public static Cursor CreateCursor(Bitmap bm, int xHotspot, int yHotspot, bool resize = true) + { + IntPtr ptr = (resize) ? ((Bitmap)ResizeBitmap(bm, 32, 32)).GetHicon() : bm.GetHicon(); + IconInfo inf = new IconInfo(); + GetIconInfo(ptr, ref inf); + inf.xHotspot = xHotspot; + inf.yHotspot = yHotspot; + inf.fIcon = false; + IntPtr cursorPtr = CreateIconIndirect(ref inf); + if (inf.hbmColor != IntPtr.Zero) { DeleteObject(inf.hbmColor); } + if (inf.hbmMask != IntPtr.Zero) { DeleteObject(inf.hbmMask); } + if (ptr != IntPtr.Zero) { DestroyIcon(ptr); } + Cursor c = new Cursor(cursorPtr); + c.Tag = (resize) ? new Size(32, 32) : bm.Size; + return c; + } + public static Bitmap ResizeBitmap(Image image, int maxWidth, int maxHeight) + { + double ratio = System.Math.Min((double)maxHeight / image.Height, (double)maxWidth / image.Width); + var propWidth = (int)(image.Width * ratio); + var propHeight = (int)(image.Height * ratio); + var newImage = new Bitmap(propWidth, propHeight); + using (var g = Graphics.FromImage(newImage)) + { + g.DrawImage(image, 0, 0, propWidth, propHeight); + } + return newImage; + } + public static Bitmap GetControlBitmap(Control c, Color transparent) + { + var bm = new Bitmap(c.Width, c.Height); + c.DrawToBitmap(bm, new Rectangle(0, 0, c.Width, c.Height)); + if (!transparent.IsEmpty) + { + bm.MakeTransparent(transparent); + } + return bm; + } + public static Bitmap OverlayBitmap(Bitmap baseBitmap, Bitmap overlay, Point atPosition) + { + using (var g = Graphics.FromImage(baseBitmap)) + { + g.DrawImage(overlay, new Rectangle(atPosition, overlay.Size)); + } + return baseBitmap; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DGHScrollBar.cs b/PROMS/DotNetBar Source Code/Controls/DGHScrollBar.cs new file mode 100644 index 00000000..4200b4e4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DGHScrollBar.cs @@ -0,0 +1,196 @@ +#if FRAMEWORK20 +using System; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using DevComponents.DotNetBar.ScrollBar; +using System.ComponentModel; +using DevComponents.DotNetBar.Rendering; +using System.Runtime.InteropServices; +using System.Reflection; + +namespace DevComponents.DotNetBar.Controls +{ + internal class DGHScrollBar : HScrollBar, ScrollBarReplacement.IScrollBarExtender + { + #region Private Variables + private ScrollBarReplacement m_ScrollBarImpl = null; + private bool m_EnableStyling = true; + #endregion + + #region Constructor + public DGHScrollBar() + { + m_ScrollBarImpl = new ScrollBarReplacement(this); + + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, false); + } + #endregion + + #region Internal Implementation + protected override CreateParams CreateParams + { + get + { + CreateParams p = base.CreateParams; + if (m_EnableStyling) + { + p.ClassName = null; + p.Style = 0x2000000; + p.Style |= 0x44000000; + if (this.Visible) + p.Style |= 0x10000000; + if (!this.Enabled) + p.Style |= 0x8000000; + if (this.RightToLeft == RightToLeft.Yes) + { + p.ExStyle |= 0x2000; + p.ExStyle |= 0x1000; + p.ExStyle |= 0x4000; + } + } + return p; + } + } + protected override void Dispose(bool disposing) + { + m_ScrollBarImpl.Dispose(); + base.Dispose(disposing); + } + + /// + /// Gets or sets whether custom styling (Office 2007 style) is enabled. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether custom styling (Office 2007 style) is enabled.")] + public bool EnableStyling + { + get { return m_EnableStyling; } + set + { + if (m_EnableStyling != value) + { + m_EnableStyling = value; + if (this.IsHandleCreated) + this.RecreateHandle(); + } + } + } + + ///// + ///// Gets or sets whether scroll bar appears as application style scroll bar which usually uses darker colors. Default value is true. + ///// + //[Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether scroll bar appears as application style scroll bar which usually uses darker colors.")] + //public bool IsAppScrollBarStyle + //{ + // get { return m_ScrollBarImpl.IsAppScrollBarStyle; } + // set { m_ScrollBarImpl.IsAppScrollBarStyle = value; } + //} + + protected override void OnHandleCreated(EventArgs e) + { + m_ScrollBarImpl.OnHandleCreated(); + base.OnHandleCreated(e); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + if (m_EnableStyling) + m_ScrollBarImpl.OnMouseDown(e); + base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + if (m_EnableStyling) + m_ScrollBarImpl.OnMouseUp(e); + base.OnMouseUp(e); + } + + protected override void OnMouseEnter(EventArgs e) + { + if (m_EnableStyling) + m_ScrollBarImpl.OnMouseEnter(e); + base.OnMouseEnter(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + if (m_EnableStyling) + m_ScrollBarImpl.OnMouseLeave(e); + base.OnMouseLeave(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if (m_EnableStyling) + m_ScrollBarImpl.OnMouseMove(e); + base.OnMouseMove(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + if(m_EnableStyling) + m_ScrollBarImpl.OnPaint(e); + base.OnPaint(e); + } + + protected override void NotifyInvalidate(Rectangle invalidatedArea) + { + if (m_EnableStyling) + m_ScrollBarImpl.NotifyInvalidate(invalidatedArea); + base.NotifyInvalidate(invalidatedArea); + } + + public void UpdateScrollValues() + { + m_ScrollBarImpl.UpdateScrollValues(); + } + + protected override void OnParentChanged(EventArgs e) + { + if (this.Parent is DataGridView) + { + m_ScrollBarImpl.ScrollBarCore.SideBorderOnly = true; + m_ScrollBarImpl.ScrollBarCore.HasBorder = false; + } + else + { + m_ScrollBarImpl.ScrollBarCore.SideBorderOnly = false; + m_ScrollBarImpl.ScrollBarCore.HasBorder = true; + } + base.OnParentChanged(e); + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + UpdateScrollValues(); + } + + public bool AppStyleScrollBar + { + get { return m_ScrollBarImpl.AppStyleScrollBar; } + set { m_ScrollBarImpl.AppStyleScrollBar = value; } + } + #endregion + + #region IScrollBarExtender Members + void ScrollBarReplacement.IScrollBarExtender.SetValue(int newValue, ScrollEventType type) + { + if (newValue != this.Value) + { + int v = this.Value; + this.Value = newValue; + ScrollEventArgs se = new ScrollEventArgs(type, v, newValue, ScrollOrientation.HorizontalScroll); + OnScroll(se); + } + } + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/DGVScrollBar.cs b/PROMS/DotNetBar Source Code/Controls/DGVScrollBar.cs new file mode 100644 index 00000000..f18bff33 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DGVScrollBar.cs @@ -0,0 +1,206 @@ +#if FRAMEWORK20 +using System; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the Vertical Office 2007 Style Scroll Bar control. + /// + internal class DGVScrollBar : VScrollBar, ScrollBarReplacement.IScrollBarExtender + { + #region Private Variables + private ScrollBarReplacement m_ScrollBarImpl = null; + private bool m_EnableStyling = true; + #endregion + + #region Constructor + public DGVScrollBar() + { + m_ScrollBarImpl = new ScrollBarReplacement(this); + + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(DisplayHelp.DoubleBufferFlag, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, false); + } + #endregion + + #region Internal Implementation + protected override CreateParams CreateParams + { + get + { + CreateParams p = base.CreateParams; + if (m_EnableStyling) + { + p.ClassName = null; + p.Style = 0x2000000; + p.Style |= 0x44000000; + if (this.Visible) + p.Style |= 0x10000000; + if (!this.Enabled) + p.Style |= 0x8000000; + if (this.RightToLeft == RightToLeft.Yes) + { + p.ExStyle |= 0x2000; + p.ExStyle |= 0x1000; + p.ExStyle |= 0x4000; + } + } + return p; + } + } + protected override void Dispose(bool disposing) + { + m_ScrollBarImpl.Dispose(); + base.Dispose(disposing); + } + + /// + /// Gets or sets whether custom styling (Office 2007 style) is enabled. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether custom styling (Office 2007 style) is enabled.")] + public bool EnableStyling + { + get { return m_EnableStyling; } + set + { + if (m_EnableStyling != value) + { + m_EnableStyling = value; + if (this.IsHandleCreated) + this.RecreateHandle(); + } + } + } + + ///// + ///// Gets or sets whether scroll bar appears as application style scroll bar which usually uses darker colors. Default value is true. + ///// + //[Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether scroll bar appears as application style scroll bar which usually uses darker colors.")] + //public bool IsAppScrollBarStyle + //{ + // get { return m_ScrollBarImpl.IsAppScrollBarStyle; } + // set { m_ScrollBarImpl.IsAppScrollBarStyle = value; } + //} + + protected override void OnHandleCreated(EventArgs e) + { + m_ScrollBarImpl.OnHandleCreated(); + base.OnHandleCreated(e); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + if (m_EnableStyling) + m_ScrollBarImpl.OnMouseDown(e); + base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + if (m_EnableStyling) + m_ScrollBarImpl.OnMouseUp(e); + base.OnMouseUp(e); + } + + protected override void OnMouseEnter(EventArgs e) + { + if (m_EnableStyling) + m_ScrollBarImpl.OnMouseEnter(e); + base.OnMouseEnter(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + if (m_EnableStyling) + m_ScrollBarImpl.OnMouseLeave(e); + base.OnMouseLeave(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if (m_EnableStyling) + { + m_ScrollBarImpl.UpdateScrollValues(); + m_ScrollBarImpl.OnMouseMove(e); + } + base.OnMouseMove(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + if(m_EnableStyling) + m_ScrollBarImpl.OnPaint(e); + base.OnPaint(e); + } + + protected override void NotifyInvalidate(Rectangle invalidatedArea) + { + if (m_EnableStyling) + m_ScrollBarImpl.NotifyInvalidate(invalidatedArea); + base.NotifyInvalidate(invalidatedArea); + } + + protected override void OnResize(EventArgs e) + { + UpdateScrollValues(); + base.OnResize(e); + } + + public void UpdateScrollValues() + { + m_ScrollBarImpl.UpdateScrollValues(); + } + + protected override void OnParentChanged(EventArgs e) + { + if (this.Parent is DataGridView) + { + m_ScrollBarImpl.ScrollBarCore.SideBorderOnly = true; + m_ScrollBarImpl.ScrollBarCore.HasBorder = false; + } + else + { + m_ScrollBarImpl.ScrollBarCore.SideBorderOnly = false; + m_ScrollBarImpl.ScrollBarCore.HasBorder = true; + } + base.OnParentChanged(e); + } + + public bool AppStyleScrollBar + { + get { return m_ScrollBarImpl.AppStyleScrollBar; } + set { m_ScrollBarImpl.AppStyleScrollBar = value; } + } + #endregion + + #region IScrollBarExtender Members + void ScrollBarReplacement.IScrollBarExtender.SetValue(int newValue, ScrollEventType type) + { + //if (newValue != this.Value) + { + // Fix for scrolling to the last row + if (type== ScrollEventType.SmallIncrement && + (this.Maximum - this.LargeChange) - newValue < 21) + { + newValue = this.Maximum - this.LargeChange + 1; + type = ScrollEventType.Last; + } + + int v = this.Value; + this.Value = newValue; + ScrollEventArgs se = new ScrollEventArgs(type, v, newValue, ScrollOrientation.VerticalScroll); + OnScroll(se); + } + } + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX.bmp b/PROMS/DotNetBar Source Code/Controls/DataGridViewX.bmp new file mode 100644 index 00000000..d474c2e2 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/DataGridViewX.bmp differ diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX.cs new file mode 100644 index 00000000..bd24e17b --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX.cs @@ -0,0 +1,812 @@ +#if FRAMEWORK20 +using System; +using System.Windows.Forms; +using System.Drawing; +using DevComponents.DotNetBar.Rendering; +using System.Drawing.Drawing2D; +using System.Reflection; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the DataGridView control with enhanced Office 2007 style. + /// + [ToolboxBitmap(typeof(DataGridViewX), "Controls.DataGridViewX.bmp")] + public class DataGridViewX : DataGridView + { + #region Private Variables + private int m_MouseOverColumnHeader = -2; + private int m_MouseDownColumnHeader = -2; + private int m_MouseDownRowIndex = -2; + private int m_MouseOverRowIndex = -2; + private bool m_Office2007StyleEnabled = true; + private Office2007DataGridViewColorTable m_ColorTable = null; + private Office2007ButtonItemStateColorTable m_ButtonStateColorTable = null; + private SelectionInfo[] m_ColumnSelectionState = new SelectionInfo[1]; + //private int m_CurrentCellRowIndex = -1; + private int m_SelectedRowIndex = -2; + private bool m_HighlightSelectedColumnHeaders = true; + private bool m_SelectAllSignVisible = true; + private bool m_PaintEnhancedSelection = true; + #endregion + + #region Constructor + public DataGridViewX() + : base() + { + SetupScrollBars(); + SetStyle(ControlStyles.OptimizedDoubleBuffer | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.ResizeRedraw, true); + this.DoubleBuffered = true; + StyleManager.Register(this); + } + #endregion + + #region internal properties + + internal Office2007ButtonItemStateColorTable ButtonStateColorTable + { + get { return (m_ButtonStateColorTable); } + } + + #endregion + + #region Internal Implementation + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + DGVScrollBar vsb = GetVScrollBar(); + if (vsb != null && vsb.Visible) vsb.Invalidate(); + + DGHScrollBar hsb = GetHScrollBar(); + if (hsb != null && hsb.Visible) hsb.Invalidate(); + + // Update Style + Office2007ColorTable ct = null; + if (GlobalManager.Renderer is Office2007Renderer) + { + ct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + m_ColorTable = ct.DataGridView; + m_ButtonStateColorTable = ct.ButtonItemColors[0].Checked; + } + try // Don't like to do this but bug in GridColor setter requires it + { + if (!_UseCustomBackgroundColor) + this.BackgroundColor = m_ColorTable.BackgroundColor; + this.ColumnHeadersDefaultCellStyle.ForeColor = m_ColorTable.ColumnHeaderNormalText; + this.ColumnHeadersDefaultCellStyle.SelectionForeColor = m_ColorTable.ColumnHeaderSelectedText; + this.DefaultCellStyle.BackColor = m_ColorTable.DefaultCellBackground; + this.DefaultCellStyle.ForeColor = m_ColorTable.DefaultCellText; + if (this.PaintEnhancedSelection) + this.DefaultCellStyle.SelectionForeColor = m_ButtonStateColorTable.Text; + this.GridColor = m_ColorTable.GridColor; + this.RowHeadersDefaultCellStyle.ForeColor = m_ColorTable.ColumnHeaderNormalText; + this.RowHeadersDefaultCellStyle.SelectionForeColor = m_ColorTable.ColumnHeaderSelectedText; + this.EnableHeadersVisualStyles = false; + } + catch { } + } + + protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e) + { + bool enabled = this.Enabled; + Office2007DataGridViewColorTable ct = GetColorTable(); + if (!m_Office2007StyleEnabled || ct == null || + e.Handled || e.ColumnIndex >= 0 && e.RowIndex >= 0 && + (!m_PaintEnhancedSelection || (e.State & DataGridViewElementStates.Selected) != DataGridViewElementStates.Selected)) + { + base.OnCellPainting(e); + return; + } + + Rectangle r = e.CellBounds; + Graphics g = e.Graphics; + LinearGradientColorTable bt = null; + Color borderColor = Color.Empty; + DataGridViewColumn column = null; + int displayIndex = -1; + if (e.ColumnIndex >= 0) + { + column = this.Columns[e.ColumnIndex]; + displayIndex = column.DisplayIndex; + } + + if (e.ColumnIndex == -1 && e.RowIndex == -1) + { + // Paint top-left corner + if (m_MouseOverColumnHeader == -1) + { + bt = ct.SelectorMouseOverBackground; + borderColor = ct.SelectorMouseOverBorder; + } + else + { + bt = ct.SelectorBackground; + borderColor = ct.SelectorBorder; + } + DisplayHelp.FillRectangle(g, r, bt); + DisplayHelp.DrawRectangle(g, borderColor, r); + if (m_MouseOverColumnHeader == -1) + borderColor = ct.SelectorMouseOverBorderLight; + else + borderColor = ct.SelectorBorderLight; + Rectangle inner = r; + inner.Inflate(-1, -1); + using (Pen p = new Pen(borderColor)) + { + g.DrawLine(p, inner.X, inner.Bottom - 1, inner.X, inner.Y); + g.DrawLine(p, inner.X, inner.Y, inner.Right - 1, inner.Y); + } + if (m_MouseOverColumnHeader == -1) + borderColor = ct.SelectorMouseOverBorderDark; + else + borderColor = ct.SelectorBorderDark; + using (Pen p = new Pen(borderColor)) + { + g.DrawLine(p, inner.Right - 1, inner.Y, inner.Right - 1, inner.Bottom - 1); + g.DrawLine(p, inner.X, inner.Bottom - 1, inner.Right - 1, inner.Bottom - 1); + } + + if (m_SelectAllSignVisible) + { + GraphicsPath path = GetSelectorPath(inner); + if (path != null) + { + DisplayHelp.FillPath(g, path, (m_MouseOverColumnHeader == -1 ? ct.SelectorMouseOverSign : ct.SelectorSign)); + path.Dispose(); + } + } + } + else if (e.ColumnIndex == -1) + { + // Paint Rows + bt = ct.RowNormalBackground; + borderColor = ct.RowNormalBorder; + + if (m_MouseDownRowIndex == e.RowIndex) + { + bt = ct.RowPressedBackground; + borderColor = ct.RowPressedBorder; + } + else if (m_SelectedRowIndex == e.RowIndex && enabled) + { + if (m_MouseOverRowIndex == e.RowIndex) + { + bt = ct.RowSelectedMouseOverBackground; + borderColor = ct.RowSelectedMouseOverBorder; + } + else + { + bt = ct.RowSelectedBackground; + borderColor = ct.RowSelectedBorder; + } + } + else if (this.Rows[e.RowIndex].Selected && enabled) + { + if (m_MouseOverRowIndex == e.RowIndex) + { + bt = ct.RowPressedBackground; + borderColor = ct.RowPressedBorder; + } + else + { + bt = ct.RowPressedBackground; + borderColor = ct.RowPressedBorder; + } + } + else if (m_MouseOverRowIndex == e.RowIndex) + { + bt = ct.RowMouseOverBackground; + borderColor = ct.RowMouseOverBorder; + } + + DisplayHelp.FillRectangle(g, r, bt); + // Paint border + using (Pen p = new Pen(borderColor)) + { + g.DrawLine(p, r.Right - 1, r.Y, r.Right - 1, r.Bottom - 1); + + if (m_SelectedRowIndex == e.RowIndex + 1 && enabled) + { + Color bc = ct.RowSelectedBorder; + if (m_MouseDownRowIndex == e.RowIndex + 1) + bc = ct.RowPressedBorder; + else if (m_MouseOverRowIndex == e.RowIndex + 1) + bc = ct.RowSelectedMouseOverBorder; + using (Pen p2 = new Pen(bc)) + g.DrawLine(p2, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + } + else + g.DrawLine(p, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + } + + e.PaintContent(r); + } + else if (e.RowIndex == -1) + { + // Determine Colors + if (m_MouseDownColumnHeader == e.ColumnIndex) + { + bt = ct.ColumnHeaderPressedBackground; + borderColor = ct.ColumnHeaderPressedBorder; + } + else if (m_MouseOverColumnHeader == e.ColumnIndex) + { + if (m_HighlightSelectedColumnHeaders && (displayIndex >= 0 && e.ColumnIndex >= 0 && (m_ColumnSelectionState.Length > displayIndex && m_ColumnSelectionState[displayIndex].Selected || this.Columns[e.ColumnIndex].Selected))) + { + bt = ct.ColumnHeaderSelectedMouseOverBackground; + borderColor = ct.ColumnHeaderSelectedMouseOverBorder; + } + else + { + bt = ct.ColumnHeaderMouseOverBackground; + borderColor = ct.ColumnHeaderMouseOverBorder; + } + } + else if (!m_HighlightSelectedColumnHeaders) + { + bt = ct.ColumnHeaderNormalBackground; + borderColor = ct.ColumnHeaderNormalBorder; + } + else if (displayIndex >= 0 && e.ColumnIndex >= 0 && (m_ColumnSelectionState.Length > displayIndex && m_ColumnSelectionState[displayIndex].Selected || this.Columns[e.ColumnIndex].Selected) && enabled) + { + bt = ct.ColumnHeaderSelectedBackground; + borderColor = ct.ColumnHeaderSelectedBorder; + } + else + { + if (this.Columns[e.ColumnIndex].Selected && enabled) + { + bt = ct.ColumnHeaderPressedBackground; + borderColor = ct.ColumnHeaderPressedBorder; + } + else + { + bt = ct.ColumnHeaderNormalBackground; + borderColor = ct.ColumnHeaderNormalBorder; + } + } + + // Paint row markers + DisplayHelp.FillRectangle(g, r, bt); + // Paint border + using (Pen p = new Pen(borderColor)) + { + g.DrawLine(p, r.X, r.Bottom-1, r.Right - 1, r.Bottom-1); + //if (displayIndex == 0) + // g.DrawLine(p, r.X, r.Y, r.X, r.Bottom - 1); + + if (enabled && (m_HighlightSelectedColumnHeaders && (displayIndex>=0 && m_ColumnSelectionState.Length > displayIndex + 1 && (m_ColumnSelectionState[displayIndex + 1].Selected || + m_ColumnSelectionState[displayIndex + 1].ColumnIndex == m_MouseDownColumnHeader)))) + { + Color bc = ct.ColumnHeaderSelectedBorder; + if (m_ColumnSelectionState[displayIndex + 1].ColumnIndex == m_MouseDownColumnHeader) + bc = ct.ColumnHeaderPressedBorder; + else if (m_MouseOverColumnHeader == displayIndex + 1) + bc = ct.ColumnHeaderSelectedMouseOverBorder; + using (Pen p2 = new Pen(bc)) + g.DrawLine(p2, r.Right - 1, r.Y, r.Right - 1, r.Bottom - 1); + } + else + g.DrawLine(p, r.Right - 1, r.Y, r.Right - 1, r.Bottom - 1); + } + e.PaintContent(r); + } + else if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected) + { + IDataGridViewColumn ic = this.Columns[e.ColumnIndex] as IDataGridViewColumn; + + if (ic != null && ic.OwnerPaintCell == true) + { + base.OnCellPainting(e); + return; + } + + e.PaintBackground(r, false); + + if (enabled) + { + r.Height--; + Office2007ButtonItemPainter.PaintBackground(g, m_ButtonStateColorTable, r, RoundRectangleShapeDescriptor.RectangleShape, false, false); + r.Height++; + + if (CurrentCellAddress.X==e.ColumnIndex && CurrentCellAddress.Y==e.RowIndex && (e.PaintParts & DataGridViewPaintParts.Focus) == DataGridViewPaintParts.Focus && + ShowFocusCues && Focused && r.Width > 0 && r.Height > 0) + { + if (m_ButtonStateColorTable.TopBackground != null) + ControlPaint.DrawFocusRectangle(g, r, Color.Empty, m_ButtonStateColorTable.TopBackground.End); + else if (m_ButtonStateColorTable.Background != null) + ControlPaint.DrawFocusRectangle(g, r, Color.Empty, m_ButtonStateColorTable.Background.Start); + else + ControlPaint.DrawFocusRectangle(g, r, Color.Empty, this.BackgroundColor); + } + } + + e.PaintContent(r); + + } + e.Handled = true; + base.OnCellPainting(e); + } + + private GraphicsPath GetSelectorPath(Rectangle inner) + { + inner.Inflate(-3, -3); + if (inner.Width > 2 && inner.Height > 2) + { + GraphicsPath path = new GraphicsPath(); + path.AddLine(inner.Right, inner.Y, inner.Right, inner.Bottom); + path.AddLine(inner.Right, inner.Bottom, inner.Right - inner.Height, inner.Bottom); + path.CloseAllFigures(); + return path; + } + + return null; + } + + protected override void OnHandleCreated(EventArgs e) + { + if (GlobalManager.Renderer is Office2007Renderer) + { + Office2007DataGridViewColorTable ct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.DataGridView; + UpdateOffice2007Styles(ct); + } + base.OnHandleCreated(e); + } + + private void UpdateOffice2007Styles(Office2007DataGridViewColorTable ct) + { + if (this.GridColor != ct.GridColor) + this.GridColor = ct.GridColor; + if(m_PaintEnhancedSelection) + this.DefaultCellStyle.SelectionForeColor = this.DefaultCellStyle.ForeColor; + } + + protected override void OnPaint(PaintEventArgs e) + { + Office2007ColorTable ct = null; + if (GlobalManager.Renderer is Office2007Renderer) + { + ct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + m_ColorTable = ct.DataGridView; + if(StyleManager.IsVisualStudio2012(StyleManager.Style)) + m_ButtonStateColorTable = ct.ButtonItemColors[0].Pressed; + else + m_ButtonStateColorTable = ct.ButtonItemColors[0].Checked; + } + + if (this.CurrentCell != null) + m_SelectedRowIndex = this.CurrentCell.RowIndex; + else + m_SelectedRowIndex = -1; + + base.OnPaint(e); + + if (this.VerticalScrollBar.Visible && this.HorizontalScrollBar.Visible) + { + Rectangle r = new Rectangle(this.VerticalScrollBar.Left, this.VerticalScrollBar.Bottom, this.VerticalScrollBar.Width, this.HorizontalScrollBar.Height); + Color c = ct.AppScrollBar.Default.Background.End; + if (c.IsEmpty) c = ct.AppScrollBar.Default.Background.Start; + DisplayHelp.FillRectangle(e.Graphics, r, c); + //e.Graphics.FillRectangle(Brushes.BlueViolet, r); + } + + m_ColorTable = null; + m_ButtonStateColorTable = null; + } + + protected override void OnCurrentCellChanged(EventArgs e) + { + if (this.SelectionMode == DataGridViewSelectionMode.FullRowSelect) + UpdateSelectionState(); + base.OnCurrentCellChanged(e); + } + + protected override void OnSelectionChanged(EventArgs e) + { + UpdateSelectionState(); + base.OnSelectionChanged(e); + } + + protected override void OnDataSourceChanged(EventArgs e) + { + base.OnDataSourceChanged(e); + UpdateSelectionState(); + } + + private void UpdateSelectionState() + { + SelectionInfo[] newSelection = new SelectionInfo[this.Columns.Count]; + for (int i = 0; i < this.Columns.Count; i++) + newSelection[this.Columns[i].DisplayIndex].ColumnIndex = i; + int columnCount = this.Columns.Count; + + if (this.SelectionMode == DataGridViewSelectionMode.FullRowSelect) + { + if (this.CurrentCell != null) + { + int displayIndex = this.Columns[this.CurrentCell.ColumnIndex].DisplayIndex; + newSelection[displayIndex].Selected = true; + newSelection[displayIndex].ColumnIndex = this.CurrentCell.ColumnIndex; + } + } + else + { + foreach (DataGridViewCell cell in this.SelectedCells) + { + if (cell.ColumnIndex == -1) continue; + int displayIndex = this.Columns[cell.ColumnIndex].DisplayIndex; + if (!newSelection[displayIndex].Selected) + { + columnCount--; + newSelection[displayIndex].Selected = true; + newSelection[displayIndex].ColumnIndex = cell.ColumnIndex; + if (columnCount == 0) break; + } + } + } + + for (int i = 0; i < newSelection.Length; i++) + { + if (m_ColumnSelectionState.Length > i && newSelection[i].Selected != m_ColumnSelectionState[i].Selected) + { + int ci = m_ColumnSelectionState[i].ColumnIndex; + if (!(ci < 0 || ci >= this.Columns.Count)) + { + this.InvalidateColumn(ci); + if (ci > 0) this.InvalidateColumn(ci - 1); + } + } + } + if (m_SelectedRowIndex > 0 && m_SelectedRowIndex < this.Rows.Count) + this.InvalidateRow(m_SelectedRowIndex - 1); + if (this.CurrentCell != null && this.CurrentCell.RowIndex > 0) + { + m_SelectedRowIndex = this.CurrentCell.RowIndex; + this.InvalidateRow(m_SelectedRowIndex - 1); + } + else + m_SelectedRowIndex = -2; + m_ColumnSelectionState = newSelection; + } + + protected virtual Office2007DataGridViewColorTable GetColorTable() + { + return m_ColorTable; + } + + protected override void OnCellMouseDown(DataGridViewCellMouseEventArgs e) + { + // Disable double buffer so column resize drag markers will work + if (e.ColumnIndex == -1 || e.RowIndex == -1) + { + this.DoubleBuffered = false; + } + + if (e.RowIndex == -1) + { + m_MouseDownColumnHeader = e.ColumnIndex; + if (e.ColumnIndex >= 0) + this.InvalidatePreviousColumn(this.Columns[e.ColumnIndex].DisplayIndex); + } + else + m_MouseDownColumnHeader = -2; + + if (e.ColumnIndex == -1) + { + m_MouseDownRowIndex = e.RowIndex; + if (m_MouseDownRowIndex > 0 && m_MouseDownRowIndex < this.Rows.Count) + this.InvalidateRow(m_MouseDownRowIndex - 1); + } + else + m_MouseDownRowIndex = -2; + + base.OnCellMouseDown(e); + } + + private void InvalidatePreviousColumn(int displayIndex) + { + displayIndex--; + for (int i = 0; i < this.Columns.Count; i++) + { + DataGridViewColumn c = this.Columns[i]; + if (c.Displayed && c.DisplayIndex == displayIndex) + { + this.InvalidateColumn(i); + break; + } + } + } + + protected override void OnDragDrop(DragEventArgs drgevent) + { + CleanUpOnCellMouseUp(); + base.OnDragDrop(drgevent); + } + + private void CleanUpOnCellMouseUp() + { + // Enable double buffering that was disabled in CellMouseDown + if (!this.DoubleBuffered) + this.DoubleBuffered = true; + + if (m_MouseDownRowIndex > 0 && m_MouseDownRowIndex < this.Rows.Count) + this.InvalidateRow(m_MouseDownRowIndex - 1); + if (m_MouseDownRowIndex >= 0 && m_MouseDownRowIndex < this.Rows.Count) + this.InvalidateRow(m_MouseDownRowIndex); + + m_MouseDownRowIndex = -2; + m_MouseDownColumnHeader = -2; + } + protected override void OnCellMouseUp(DataGridViewCellMouseEventArgs e) + { + CleanUpOnCellMouseUp(); + base.OnCellMouseUp(e); + } + + protected override void OnCellMouseEnter(DataGridViewCellEventArgs e) + { + if (e.RowIndex == -1) + m_MouseOverColumnHeader = e.ColumnIndex; + else + m_MouseOverColumnHeader = -2; + if (e.ColumnIndex == -1) + { + if (m_MouseOverRowIndex != e.RowIndex) + { + m_MouseOverRowIndex = e.RowIndex; + if (m_MouseOverRowIndex > 0) + this.InvalidateRow(m_MouseOverRowIndex - 1); + } + } + else + m_MouseOverRowIndex = -2; + base.OnCellMouseEnter(e); + } + + protected override void OnCellMouseLeave(DataGridViewCellEventArgs e) + { + m_MouseOverColumnHeader = -2; + m_MouseOverRowIndex = -2; + base.OnCellMouseLeave(e); + } + + private struct SelectionInfo + { + public bool Selected; + public int ColumnIndex; + } + + protected override void OnScroll(ScrollEventArgs e) + { + base.OnScroll(e); + DGVScrollBar vsb = GetVScrollBar(); + if (vsb != null && vsb.Visible) vsb.UpdateScrollValues(); + + DGHScrollBar hsb = GetHScrollBar(); + if (hsb != null && hsb.Visible) hsb.UpdateScrollValues(); + } + + private DGVScrollBar GetVScrollBar() + { + return this.VerticalScrollBar as DGVScrollBar; + //Type t = typeof(System.Windows.Forms.DataGridView); + //FieldInfo fi = t.GetField("vertScrollBar", BindingFlags.NonPublic | BindingFlags.Instance); + //if (fi == null) return null; + //DGVScrollBar sb = fi.GetValue(this) as DGVScrollBar; + //return sb; + } + + private DGHScrollBar GetHScrollBar() + { + return this.HorizontalScrollBar as DGHScrollBar; + //Type t = typeof(System.Windows.Forms.DataGridView); + //FieldInfo fi = t.GetField("horizScrollBar", BindingFlags.NonPublic | BindingFlags.Instance); + //if (fi == null) return null; + //DGHScrollBar sb = fi.GetValue(this) as DGHScrollBar; + //return sb; + } + + private void InvokeDelayed(MethodInvoker method) + { + Timer delayedInvokeTimer = new Timer(); + delayedInvokeTimer = new Timer(); + delayedInvokeTimer.Tag = method; + delayedInvokeTimer.Interval = 10; + delayedInvokeTimer.Tick += new EventHandler(DelayedInvokeTimerTick); + delayedInvokeTimer.Start(); + } + void DelayedInvokeTimerTick(object sender, EventArgs e) + { + Timer timer = (Timer)sender; + MethodInvoker method = (MethodInvoker)timer.Tag; + timer.Stop(); + timer.Dispose(); + method.Invoke(); + } + + protected override void OnResize(EventArgs e) + { + if (_DelayResizeCallWhenMdiChild) + { + Form form = this.FindForm(); + if (form != null && form.IsMdiChild) + InvokeDelayed(new MethodInvoker(delegate { CallBaseOnResize(e); })); + else + base.OnResize(e); + } + else + base.OnResize(e); + } + + private void CallBaseOnResize(EventArgs e) + { + base.OnResize(e); + } + + private bool _DelayResizeCallWhenMdiChild = true; + /// + /// Indicates whether control will delay call to OnResize base DataGridView method when control is running on MDI Child which was introduced as workaround to an issue in control. + /// + [DefaultValue(true), Browsable(false)] + public bool DelayResizeCallWhenMdiChild + { + get { return _DelayResizeCallWhenMdiChild; } + set { _DelayResizeCallWhenMdiChild = value; } + } + + private eScrollBarAppearance _ScrollBarAppearance = eScrollBarAppearance.ApplicationScroll; + /// + /// Gets or sets the scroll-bar visual style. + /// + [DefaultValue(eScrollBarAppearance.ApplicationScroll), Category("Appearance"), Description("Gets or sets the scroll-bar visual style.")] + public eScrollBarAppearance ScrollBarAppearance + { + get { return _ScrollBarAppearance; } + set + { + _ScrollBarAppearance = value; + OnScrollBarAppearance(); + } + } + private void OnScrollBarAppearance() + { + DGVScrollBar sbv = GetVScrollBar(); + if (sbv != null) + sbv.AppStyleScrollBar = (_ScrollBarAppearance == eScrollBarAppearance.ApplicationScroll); + + DGHScrollBar sbh = GetHScrollBar(); + if (sbh != null) + sbh.AppStyleScrollBar = (_ScrollBarAppearance == eScrollBarAppearance.ApplicationScroll); + } + + private void SetupScrollBars() + { + // Vertical Scroll Bar Replacement + Type t = typeof(System.Windows.Forms.DataGridView); + FieldInfo fi = t.GetField("vertScrollBar", BindingFlags.NonPublic | BindingFlags.Instance); + if(fi==null) return; + System.Windows.Forms.ScrollBar sb = fi.GetValue(this) as System.Windows.Forms.ScrollBar; + if (sb == null) return; + //sb.Scroll += new ScrollEventHandler(sb_Scroll); return; + MethodInfo mi = t.GetMethod("DataGridViewVScrolled", BindingFlags.NonPublic | BindingFlags.Instance); + if (mi == null) return; + + DGVScrollBar newVSb = new DGVScrollBar(); + newVSb.AppStyleScrollBar = (_ScrollBarAppearance == eScrollBarAppearance.ApplicationScroll); + newVSb.Minimum = sb.Minimum; + newVSb.Maximum = sb.Maximum; + newVSb.SmallChange = sb.SmallChange; + newVSb.LargeChange = sb.LargeChange; + newVSb.Top = sb.Top; + newVSb.AccessibleName = sb.AccessibleName; + newVSb.Left = sb.Left; + newVSb.Visible = sb.Visible; + newVSb.Scroll += (ScrollEventHandler)ScrollEventHandler.CreateDelegate(typeof(ScrollEventHandler), this, mi); + fi.SetValue(this, newVSb); + sb.Dispose(); + this.Controls.Remove(sb); + this.Controls.Add(newVSb); + + // Horizontal Scroll Bar Replacement + fi = t.GetField("horizScrollBar", BindingFlags.NonPublic | BindingFlags.Instance); + if (fi == null) return; + sb = fi.GetValue(this) as System.Windows.Forms.ScrollBar; + if (sb == null) return; + mi = t.GetMethod("DataGridViewHScrolled", BindingFlags.NonPublic | BindingFlags.Instance); + if (mi == null) return; + + DGHScrollBar newHSb = new DGHScrollBar(); + newHSb.AppStyleScrollBar = (_ScrollBarAppearance == eScrollBarAppearance.ApplicationScroll); ; + newHSb.Minimum = sb.Minimum; + newHSb.Maximum = sb.Maximum; + newHSb.SmallChange = sb.SmallChange; + newHSb.LargeChange = sb.LargeChange; + newHSb.Top = sb.Top; + newHSb.AccessibleName = sb.AccessibleName; + newHSb.Left = sb.Left; + newHSb.Visible = sb.Visible; + newHSb.RightToLeft = sb.RightToLeft; + newHSb.Scroll += (ScrollEventHandler)ScrollEventHandler.CreateDelegate(typeof(ScrollEventHandler), this, mi); + fi.SetValue(this, newHSb); + sb.Dispose(); + this.Controls.Remove(sb); + this.Controls.Add(newHSb); + + base.PerformLayout(); + } + + //void sb_Scroll(object sender, ScrollEventArgs e) + //{ + // Console.WriteLine(e.NewValue); + //} + + /// + /// Gets or sets whether selected column header is highlighted. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Behavior"), Description("Indicates whether selected column header is highlighted.")] + public bool HighlightSelectedColumnHeaders + { + get { return m_HighlightSelectedColumnHeaders; } + set + { + m_HighlightSelectedColumnHeaders = value; + if(BarFunctions.IsHandleValid(this)) + this.Invalidate(); + } + } + + /// + /// Gets or sets whether select all sign displayed in top-left corner of the grid is visible. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Behavior"), Description("Indicates whether select all sign displayed in top-left corner of the grid is visible.")] + public bool SelectAllSignVisible + { + get { return m_SelectAllSignVisible; } + set + { + m_SelectAllSignVisible = value; + if (BarFunctions.IsHandleValid(this)) + this.Invalidate(); + } + } + + /// + /// Gets or sets whether enhanced selection for the cells is painted in Office 2007 style. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether enhanced selection for the cells is painted in Office 2007 style")] + public bool PaintEnhancedSelection + { + get { return m_PaintEnhancedSelection; } + set + { + m_PaintEnhancedSelection = value; + if (BarFunctions.IsHandleValid(this)) + this.Invalidate(); + } + } + + private bool _UseCustomBackgroundColor = false; + /// + /// Indicates whether BackgroundColor property set on DataGridView is obeyed instead of using system color scheme color. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether BackgroundColor property set on DataGridView is obeyed instead of using system color scheme color.")] + public bool UseCustomBackgroundColor + { + get { return _UseCustomBackgroundColor; } + set + { + _UseCustomBackgroundColor = value; + } + } + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewButtonX/DataGridViewButtonXCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewButtonX/DataGridViewButtonXCell.cs new file mode 100644 index 00000000..ad03a29f --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewButtonX/DataGridViewButtonXCell.cs @@ -0,0 +1,498 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewButtonXCell : DataGridViewButtonCell + { + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (null); } + } + + #endregion + + #region FormattedValueType + + /// + /// FormattedValueType + /// + public override Type FormattedValueType + { + get { return (typeof (string)); } + } + + #endregion + + #endregion + + #region GetContentBounds + + /// + /// GetContentBounds + /// + /// + /// + /// + /// + protected override Rectangle GetContentBounds(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) + { + Rectangle cellBounds = DataGridView.GetCellDisplayRectangle(ColumnIndex, rowIndex, false); + cellBounds.Location = new Point(0, 0); + + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn)OwningColumn; + ButtonX bx = oc.ButtonX; + + Rectangle rBt = GetButtonBounds(cellBounds, true); + + if (bx.ButtonItem.SubItems.Count > 0) + rBt.Width -= bx.ButtonItem.SubItemsExpandWidth; + + return (rBt); + } + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, + object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintButtonBackground(g, cellStyle, rBk); + PaintButtonContent(cellBounds, rowIndex, formattedValue, cellStyle, paintParts, bm); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintButtonBackground + + /// + /// Paints the Button background + /// + /// + /// + /// + private void PaintButtonBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintButtonContent + + /// + /// Paints the button background and content + /// + /// + /// + /// + /// + /// + /// + private void PaintButtonContent(Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, Bitmap bm) + { + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn)OwningColumn; + ButtonX bx = oc.ButtonX; + + Rectangle rBt = GetButtonBounds(cellBounds, true); + + if (rBt.Width > 0 && rBt.Height > 0) + { + bool mouseIsOver = bx.ButtonItem.MouseIsOver; + bool mouerIsOverExpand = bx.ButtonItem.MouseIsOverExpand; + bool mouseIsDown = bx.ButtonItem.MouseIsDown; + bool buttonIsExpanded = bx.ButtonItem.ButtonIsExpanded; + + try + { + string s = oc.Text; + + oc.InCellCallBack = true; + + if (rowIndex != oc.ActiveRowIndex) + { + bx.ButtonItem.MouseIsOver = false; + bx.ButtonItem.MouseIsOverExpand = false; + bx.ButtonItem.MouseIsDown = false; + bx.ButtonItem.ButtonIsExpanded = false; + } + + bx.Font = cellStyle.Font; + bx.ForeColor = cellStyle.ForeColor; + bx.BackColor = cellStyle.BackColor; + + if (rowIndex < DataGridView.RowCount) + { + bx.Text = UseColumnTextForButtonValue ? s : GetValue(value); + + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + } + else + { + bx.Text = ""; + } + + bx.Bounds = rBt; + bx.RecalcLayout(); + bx.DrawToBitmap(bm, rBt); + } + finally + { + bx.ButtonItem.MouseIsOver = mouseIsOver; + bx.ButtonItem.MouseIsOverExpand = mouerIsOverExpand; + bx.ButtonItem.MouseIsDown = mouseIsDown; + bx.ButtonItem.ButtonIsExpanded = buttonIsExpanded; + + oc.InCellCallBack = false; + } + } + } + + #endregion + + #endregion + + #region Mouse processing + + #region OnMouseEnter + + /// + /// OnMouseEnter + /// + /// + protected override void OnMouseEnter(int rowIndex) + { + base.OnMouseEnter(rowIndex); + + DoMouseEnter(rowIndex); + } + + /// + /// Establishes the given rowIndex as the + /// ActiveRowIndex. + /// + /// + internal void DoMouseEnter(int rowIndex) + { + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn)OwningColumn; + ButtonX bx = oc.ButtonX; + + oc.CurrentRowIndex = rowIndex; + + if (bx.Expanded == false) + { + oc.ActiveRowIndex = rowIndex; + + bx.ButtonItem.InternalMouseEnter(); + + RefreshButton(ColumnIndex, rowIndex); + } + } + + #endregion + + #region OnMouseLeave + + /// + /// Processes MouseLeave events + /// + /// + protected override void OnMouseLeave(int rowIndex) + { + base.OnMouseLeave(rowIndex); + + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn)OwningColumn; + ButtonX bx = oc.ButtonX; + + oc.CurrentRowIndex = -1; + + if (bx.Expanded == false) + { + oc.ActiveRowIndex = -1; + + bx.ButtonItem.InternalMouseLeave(); + + RefreshButton(ColumnIndex, rowIndex); + } + } + + #endregion + + #region OnMouseMove + + /// + /// Processes MouseMove events + /// + /// + protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) + { + base.OnMouseMove(e); + + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn) OwningColumn; + ButtonX bx = oc.ButtonX; + + if (oc.ActiveRowIndex == e.RowIndex || bx.Expanded == false) + { + bx.ButtonItem.InternalMouseMove( + new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta)); + + RefreshButton(e.ColumnIndex, e.RowIndex); + } + } + + #endregion + + #region OnMouseDown + + /// + /// Processes MouseDown events + /// + /// + protected override void OnMouseDown(DataGridViewCellMouseEventArgs e) + { + base.OnMouseDown(e); + + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn) OwningColumn; + ButtonX bx = oc.ButtonX; + + if (DataGridView.Controls.Contains(bx) == false) + DataGridView.Controls.Add(bx); + + if (oc.ExpandClosed == false || bx.ButtonItem.MouseIsOverExpand == false) + { + Rectangle cellBounds = DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false); + Rectangle rBt = GetButtonBounds(cellBounds, false); + + Point pt = e.Location; + pt.Offset(rBt.Location); + + if (rBt.Contains(pt) == true) + { + bx.Bounds = rBt; + + bx.ButtonItem.InternalMouseDown( + new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta)); + + DataGridView.Invalidate(rBt); + } + } + + oc.ExpandClosed = false; + } + + #endregion + + #region OnMouseUp + + /// + /// Processes MouseUp events + /// + /// + protected override void OnMouseUp(DataGridViewCellMouseEventArgs e) + { + base.OnMouseUp(e); + + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn) OwningColumn; + ButtonX bx = oc.ButtonX; + + Rectangle cellBounds = DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false); + Rectangle rBt = GetButtonBounds(cellBounds, false); + + DataGridView.Invalidate(rBt); + + bx.Bounds = rBt; + bx.ButtonItem.InternalMouseUp( + new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta)); + } + + #endregion + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetButtonBounds + + /// + /// Gets the button bounds for the given cell + /// + /// + /// + /// + private Rectangle GetButtonBounds(Rectangle cellBounds, bool localize) + { + DataGridViewButtonXColumn oc = (DataGridViewButtonXColumn)OwningColumn; + + cellBounds.Width -= (oc.DividerWidth + 3); + cellBounds.Height -= 3; + + if (localize == true) + cellBounds.Location = new Point(0, 0); + + cellBounds.X++; + cellBounds.Y++; + + return (cellBounds); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + private string GetValue(object value) + { + return (value != Convert.DBNull ? Convert.ToString(value) : "" ); + } + + #endregion + + #region RefreshButton + + /// + /// Initiates the refresh of the cell button + /// + /// + /// + private void RefreshButton(int columnIndex, int rowIndex) + { + if (DataGridView != null) + { + Rectangle cellBounds = DataGridView.GetCellDisplayRectangle(columnIndex, rowIndex, false); + Rectangle rBt = GetButtonBounds(cellBounds, false); + + DataGridView.Invalidate(rBt); + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewButtonX/DataGridViewButtonXColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewButtonX/DataGridViewButtonXColumn.cs new file mode 100644 index 00000000..f2592174 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewButtonX/DataGridViewButtonXColumn.cs @@ -0,0 +1,751 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewButtonXColumn), "ButtonX.ButtonX.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewButtonXColumn : DataGridViewButtonColumn, IDataGridViewColumn + { + #region Events + + [Description("Occurs right before a Button Cell is painted.")] + public event EventHandler BeforeCellPaint; + + [Description("Occurs when a Button Cell is Clicked.")] + public event EventHandler Click; + + #endregion + + #region Private variables + + private ButtonX _ButtonX; + + private int _ActiveRowIndex = -1; + private int _CurrentRowIndex = -1; + + private bool _ExpandClosed; + private bool _InCellCallBack; + + private Bitmap _CellBitmap; + + #endregion + + /// + /// Constructor + /// + public DataGridViewButtonXColumn() + { + CellTemplate = new DataGridViewButtonXCell(); + + _ButtonX = new ButtonX(); + + _ButtonX.Visible = false; + _ButtonX.FadeEffect = false; + + HookEvents(true); + } + + #region Internal properties + + #region ActiveRowIndex + + /// + /// Gets or sets the active row index + /// + internal int ActiveRowIndex + { + get { return (_ActiveRowIndex); } + set { _ActiveRowIndex = value; } + } + + #endregion + + #region ButtonX + + /// + /// Gets the Control Button + /// + internal ButtonX ButtonX + { + get { return (_ButtonX); } + } + + #endregion + + #region CurrentRowIndex + + /// + /// Gets or sets the Current row index + /// + internal int CurrentRowIndex + { + get { return (_CurrentRowIndex); } + set { _CurrentRowIndex = value; } + } + + #endregion + + #region ExpandClosed + + /// + /// Gets or sets a expanded button + /// was just closed + /// + internal bool ExpandClosed + { + get { return (_ExpandClosed); } + set { _ExpandClosed = value; } + } + + #endregion + + #region InCellCallBack + + /// + /// Gets or sets the cell callback state + /// + internal bool InCellCallBack + { + get { return (_InCellCallBack); } + set { _InCellCallBack = value; } + } + + #endregion + + #endregion + + #region Public properties + + #region AutoCheckOnClick + + /// + /// Gets or sets whether Checked property is automatically inverted, button checked/unchecked, when button is clicked. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Behavior")] + [Description("Indicates whether Checked property is automatically inverted when button is clicked.")] + public bool AutoCheckOnClick + { + get { return (_ButtonX.AutoCheckOnClick); } + set { _ButtonX.AutoCheckOnClick = value; } + } + + #endregion + + #region AutoExpandOnClick + + /// + /// Indicates whether the button will auto-expand when clicked. + /// When button contains sub-items, sub-items will be shown only if user + /// click the expand part of the button. Setting this property to true will expand the button and show sub-items when user + /// clicks anywhere inside of the button. Default value is false which indicates that button is expanded only + /// if its expand part is clicked. + /// + [DefaultValue(false), Browsable(true), DevCoBrowsable(true), Category("Behavior")] + [Description("Indicates whether the button will auto-expand (display pop-up menu or toolbar) when clicked.")] + public virtual bool AutoExpandOnClick + { + get { return (_ButtonX.AutoExpandOnClick); } + set { _ButtonX.AutoExpandOnClick = value; } + } + + #endregion + + #region Checked + + /// + /// Gets or set a value indicating whether the button is in the checked state. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), DefaultValue(false)] + [Description("Indicates whether item is checked or not.")] + public virtual bool Checked + { + get { return (_ButtonX.Checked); } + set { _ButtonX.Checked = value; } + } + + #endregion + + #region ColorScheme + + /// + /// Gets or sets button Color Scheme. ColorScheme does not apply to Office2007 styled buttons. + /// + [Browsable(false), DevCoBrowsable(false), Category("Appearance")] + [Description("Gets or sets Bar Color Scheme."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ColorScheme ColorScheme + { + get { return (_ButtonX.ColorScheme); } + set { _ButtonX.ColorScheme = value; } + } + + #endregion + + #region ColorTable + + /// + /// Gets or sets the predefined color of the button. Color specified applies to buttons with Office 2007 style only. It does not have + /// any effect on other styles. Default value is eButtonColor.BlueWithBackground + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(eButtonColor.BlueWithBackground), Category("Appearance")] + [Description("Indicates predefined color of button when Office 2007 style is used.")] + [NotifyParentProperty(true)] + public eButtonColor ColorTable + { + get { return (_ButtonX.ColorTable); } + set { _ButtonX.ColorTable = value; } + } + + #endregion + + #region CustomColorName + + /// + /// Gets or sets the custom color name. Name specified here must be represented by the corresponding object with the same name that is part + /// of the Office2007ColorTable.ButtonItemColors collection. See documentation for Office2007ColorTable.ButtonItemColors for more information. + /// If color table with specified name cannot be found default color will be used. Valid settings for this property override any + /// setting to the Color property. Applies to items with Office 2007 style only. + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(""), Category("Appearance")] + [Description("Indicates custom color table name for the button when Office 2007 style is used.")] + public string CustomColorName + { + get { return (_ButtonX.CustomColorName); } + set { _ButtonX.CustomColorName = value; } + } + + #endregion + + #region DisabledImage + + /// + /// Specifies the image for the button when items Enabled property is set to false. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(null), Category("Appearance")] + [Description("The image that will be displayed when item is disabled.")] + public Image DisabledImage + { + get { return (_ButtonX.DisabledImage); } + set { _ButtonX.DisabledImage = value; } + } + + #endregion + + #region EnableMarkup + + /// + /// Gets or sets whether text-markup support is enabled for items Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the item instead of it being parsed as text-markup. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for items Text property.")] + public bool EnableMarkup + { + get { return (_ButtonX.EnableMarkup); } + set { _ButtonX.EnableMarkup = value; } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_ButtonX.Enabled); } + set { _ButtonX.Enabled = value; } + } + + #endregion + + #region HotTrackingStyle + + /// + /// Indicates the way button is rendering the mouse over state. Setting the value to + /// Color will render the image in gray-scale when mouse is not over the item. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(eHotTrackingStyle.Default), Category("Appearance")] + [Description("Indicates the button mouse over tracking style. Setting the value to Color will render the image in gray-scale when mouse is not over the item.")] + public eHotTrackingStyle HotTrackingStyle + { + get { return (_ButtonX.HotTrackingStyle); } + set { _ButtonX.HotTrackingStyle = value; } + } + + #endregion + + #region HoverImage + + /// + /// Specifies the image for the button when mouse is over the item. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(null), Category("Appearance")] + [Description("The image that will be displayed when mouse hovers over the item.")] + public Image HoverImage + { + get { return (_ButtonX.HoverImage); } + set { _ButtonX.HoverImage = value; } + } + + #endregion + + #region Image + + /// + /// Specifies the Button image. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(null), Category("Appearance")] + [Description("The image that will be displayed on the face of the button.")] + public Image Image + { + get { return (_ButtonX.Image); } + set { _ButtonX.Image = value; } + } + + #endregion + + #region ImageFixedSize + + /// + /// Sets fixed size of the image. Image will be scaled and painted it size specified. + /// + [Browsable(true)] + public Size ImageFixedSize + { + get { return (_ButtonX.ImageFixedSize); } + set { _ButtonX.ImageFixedSize = value; } + } + + /// + /// Gets whether ImageFixedSize property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeImageFixedSize() + { + return (_ButtonX.ShouldSerializeImageFixedSize()); + } + + #endregion + + #region ImagePosition + + /// + /// Gets/Sets the image position inside the button. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(eImagePosition.Left), Category("Appearance")] + [Description("The alignment of the image in relation to text displayed by this item.")] + public eImagePosition ImagePosition + { + get { return (_ButtonX.ImagePosition); } + set { _ButtonX.ImagePosition = value; } + } + + #endregion + + #region ImageTextSpacing + + /// + /// Gets or sets the amount of spacing between button image if specified and text. + /// + [Browsable(true), DefaultValue(0), Category("Layout")] + [Description("Indicates amount of spacing between button image if specified and text.")] + public int ImageTextSpacing + { + get { return (_ButtonX.ImageTextSpacing); } + set { _ButtonX.ImageTextSpacing = value; } + + } + + #endregion + + #region PopupSide + + /// + /// Gets or sets the location of popup in relation to it's parent. + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(ePopupSide.Default)] + [Description("Indicates location of popup in relation to it's parent.")] + public ePopupSide PopupSide + { + get { return (_ButtonX.PopupSide); } + set { _ButtonX.PopupSide = value; } + } + + #endregion + + #region PressedImage + + /// + /// Specifies the image for the button when mouse left button is pressed. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(null), Category("Appearance")] + [Description("The image that will be displayed when item is pressed.")] + public Image PressedImage + { + get { return (_ButtonX.PressedImage); } + set { _ButtonX.PressedImage = value; } + } + + #endregion + + #region Shape + + /// + /// Gets or sets an shape descriptor for the button + /// which describes the shape of the button. Default value is null + /// which indicates that system default shape is used. + /// + [DefaultValue(null)] + [Editor("DevComponents.DotNetBar.Design.ShapeTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + [TypeConverter("DevComponents.DotNetBar.Design.ShapeStringConverter, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public ShapeDescriptor Shape + { + get { return (_ButtonX.Shape); } + set { _ButtonX.Shape = value; } + } + + #endregion + + #region ShowSubItems + + /// + /// Gets or sets whether button displays the expand part that indicates that button has popup. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(true), Category("Behavior")] + [Description("Determines whether sub-items are displayed.")] + public bool ShowSubItems + { + get { return (_ButtonX.ShowSubItems); } + set { _ButtonX.ShowSubItems = value; } + } + + #endregion + + #region SplitButton + + /// + /// Gets or sets whether button appears as split button. Split button appearance + /// divides button into two parts. Image which raises the click event when clicked + /// and text and expand sign which shows button sub items on popup menu when clicked. + /// Button must have both text and image visible (ButtonStyle property) in order to + /// appear as a full split button. + /// + [Browsable(true), DefaultValue(false), Category("Appearance")] + [Description("Indicates whether button appears as split button.")] + public bool SplitButton + { + get { return (_ButtonX.SplitButton); } + set { _ButtonX.SplitButton = value; } + } + + #endregion + + #region Style + + /// + /// Gets/Sets the visual style for the button. + /// + [Category("Appearance"), Description("Specifies the visual style of the button.")] + [DefaultValue(eDotNetBarStyle.Office2007)] + public eDotNetBarStyle Style + { + get { return (_ButtonX.Style); } + set { _ButtonX.Style = value; } + } + + #endregion + + #region SubItems + + /// + /// Returns the collection of sub items. + /// + [Browsable(false), DevCoBrowsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SubItemsCollection SubItems + { + get { return (_ButtonX.SubItems); } + } + + #endregion + + #region SubItemsExpandWidth + + /// + /// Gets or sets the width of the expand part of the button item. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(12), Category("Behavior")] + [Description("Indicates the width of the expand part of the button item.")] + public int SubItemsExpandWidth + { + get { return (_ButtonX.SubItemsExpandWidth); } + set { _ButtonX.SubItemsExpandWidth = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the default Text to display on the Button + /// + [Browsable(true), Category("Appearance"), DefaultValue("")] + [Description("Indicates the default Text to display on the Button.")] + public new string Text + { + get + { + return (_InCellCallBack == true ? + _ButtonX.Text : base.Text); + } + + set + { + if (_InCellCallBack == true) + _ButtonX.Text = value; + else + base.Text = value; + } + } + + #endregion + + #region TextAlignment + + /// + /// Gets or sets the text alignment. Applies only when button text is not composed using text markup. Default value is center. + /// + [Browsable(true), DefaultValue(eButtonTextAlignment.Center), Category("Appearance")] + [Description("Indicates text alignment. Applies only when button text is not composed using text markup. Default value is center.")] + public eButtonTextAlignment TextAlignment + { + get { return (_ButtonX.TextAlignment); } + set { _ButtonX.TextAlignment = value; } + } + + #endregion + + #endregion + + #region HookEvents + + /// + /// Hooks or unhooks our system events + /// + /// + private void HookEvents(bool hook) + { + if (hook == true) + { + _ButtonX.ButtonItem.Click += ButtonItem_Click; + _ButtonX.ButtonItem.ExpandChange += ButtonItem_ExpandChange; + } + else + { + _ButtonX.ButtonItem.Click -= ButtonItem_Click; + _ButtonX.ButtonItem.ExpandChange -= ButtonItem_ExpandChange; + } + } + + #endregion + + #region Event processing + + #region ButtonItem_ExpandChange + + /// + /// Processes Button expand changes + /// + /// + /// + void ButtonItem_ExpandChange(object sender, EventArgs e) + { + if (_ButtonX.ButtonItem.Expanded == false) + { + DataGridView.InvalidateCell(Index, ActiveRowIndex); + + _ExpandClosed = (_ActiveRowIndex == _CurrentRowIndex); + _ActiveRowIndex = -1; + + if (_CurrentRowIndex >= 0) + { + DataGridViewButtonXCell cell = + DataGridView.Rows[_CurrentRowIndex].Cells[Index] as DataGridViewButtonXCell; + + if (cell != null) + cell.DoMouseEnter(_CurrentRowIndex); + } + } + } + + #endregion + + #region ButtonItem_Click + + /// + /// ButtonItem_Click + /// + /// + /// + void ButtonItem_Click(object sender, EventArgs e) + { + if (Click != null) + Click(sender, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewButtonXColumn bc = base.Clone() as DataGridViewButtonXColumn; + + if (bc != null) + { + _ButtonX.ButtonItem.InternalCopyToItem(bc.ButtonX.ButtonItem); + + bc.Enabled = Enabled; + bc.TextAlignment = TextAlignment; + bc.ImageTextSpacing = ImageTextSpacing; + + bc.Shape = Shape; + } + + return (bc); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the ButtonX control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + HookEvents(false); + + if (disposing == true) + _ButtonX.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + } + + #region BeforeCellPaintEventArgs + + /// + /// BeforeCellPaintEventArgs + /// + public class BeforeCellPaintEventArgs : EventArgs + { + #region Private variables + + private int _RowIndex; + private int _ColumnIndex; + + #endregion + + public BeforeCellPaintEventArgs(int rowIndex, int columnIndex) + { + _RowIndex = rowIndex; + _ColumnIndex = columnIndex; + } + + #region Public properties + + /// + /// RowIndex of cell being painted + /// + public int RowIndex + { + get { return (_RowIndex); } + } + + /// + /// ColumnIndex of cell being painted + /// + public int ColumnIndex + { + get { return (_ColumnIndex); } + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewCheckBoxX/DataGridViewCheckBoxXCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewCheckBoxX/DataGridViewCheckBoxXCell.cs new file mode 100644 index 00000000..d78e8aba --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewCheckBoxX/DataGridViewCheckBoxXCell.cs @@ -0,0 +1,696 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewCheckBoxXCell : DataGridViewCell + { + #region Private variables + + private bool _MouseEntered; + private string _Text; + + #endregion + + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (null); } + } + + #endregion + + #region FormattedValueType + + /// + /// FormattedValueType + /// + public override Type FormattedValueType + { + get { return (typeof(string)); } + } + + #endregion + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetContentBounds(editingControlBounds); + + if (cellStyle != null) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.TopCenter: + editingControlBounds.X += (editingControlBounds.Width - r.Width) / 2; + break; + + case DataGridViewContentAlignment.TopRight: + editingControlBounds.X = (editingControlBounds.Right - r.Width); + break; + + case DataGridViewContentAlignment.MiddleLeft: + editingControlBounds.Y += (editingControlBounds.Height - r.Height) / 2; + break; + + case DataGridViewContentAlignment.MiddleCenter: + editingControlBounds.X += (editingControlBounds.Width - r.Width) / 2; + editingControlBounds.Y += (editingControlBounds.Height - r.Height) / 2; + break; + + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.X = (editingControlBounds.Right - r.Width); + editingControlBounds.Y += (editingControlBounds.Height - r.Height) / 2; + break; + + case DataGridViewContentAlignment.BottomLeft: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + + case DataGridViewContentAlignment.BottomCenter: + editingControlBounds.X += (editingControlBounds.Width - r.Width) / 2; + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.X = (editingControlBounds.Right - r.Width); + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + if (editingControlBounds.Y < 1) + editingControlBounds.Y = 1; + + editingControlBounds.Width = Math.Max(1, editingControlBounds.Width); + editingControlBounds.Height = Math.Max(1, r.Height); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + #region GetPreferredSize + + /// + /// GetPreferredSize + /// + /// + /// + /// + /// + /// + protected override Size GetPreferredSize(Graphics graphics, + DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + { + if (DataGridView == null) + return (new Size(-1, -1)); + + Size preferredSize = Size.Empty; + + if (constraintSize.Width == 0) + { + DataGridViewCheckBoxXColumn oc = OwningColumn as DataGridViewCheckBoxXColumn; + + if (oc != null) + { + GetFormattedValue(GetValue(rowIndex), rowIndex, + ref cellStyle, null, null, new DataGridViewDataErrorContexts()); + + if (rowIndex < DataGridView.RowCount) + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + + CheckBoxX cb = oc.CheckBoxX; + + SizeF sf = graphics.MeasureString(cb.Text, cellStyle.Font); + + preferredSize.Width = (int) sf.Width + 4; + preferredSize.Height = cb.Height; + + preferredSize.Width += cb.CheckBoxItem.CheckSignSize.Width; + } + } + + return (preferredSize); + } + + #endregion + + #region GetFormattedValue + + protected override object GetFormattedValue(object value, int rowIndex, + ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, + TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) + { + return (base.GetFormattedValue(value, rowIndex, + ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context)); + } + + #endregion + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, + object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewCheckBoxXColumn oc = (DataGridViewCheckBoxXColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintButtonBackground(g, cellStyle, rBk); + PaintButtonContent(cellBounds, rowIndex, value, cellStyle, paintParts, g); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintButtonBackground + + /// + /// Paints the Button background + /// + /// + /// + /// + private void PaintButtonBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintButtonContent + + /// + /// Paints the button background and content + /// + /// + /// + /// + /// + /// + /// + private void PaintButtonContent(Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, Graphics g) + { + DataGridViewCheckBoxXColumn oc = (DataGridViewCheckBoxXColumn) OwningColumn; + CheckBoxX bx = oc.CheckBoxX; + + string text = bx.Text; + bool isChecked = bx.Checked; + object checkValue = bx.CheckValue; + CheckState checkState = bx.CheckState; + bool isMouseOver = bx.CheckBoxItem.IsMouseOver; + bool isMouseDown = bx.CheckBoxItem.IsMouseDown; + + GraphicsState gs = g.Save(); + + try + { + oc.InCellCallBack = true; + + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + bx.CheckValue = (oc.ThreeState == true) ? value : GetCheckValue(oc, value); + + bx.Font = cellStyle.Font; + bx.ForeColor = cellStyle.ForeColor; + bx.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + + if (rowIndex != oc.ActiveRowIndex) + { + bx.CheckBoxItem.IsMouseOver = false; + bx.CheckBoxItem.IsMouseDown = false; + } + + if (rowIndex < DataGridView.RowCount) + { + bx.Text = text; + + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + } + else + { + bx.Text = ""; + } + + _Text = bx.Text; + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + + bx.CallBasePaintBackground = false; + + g.TranslateTransform(r.X, r.Y); + + bx.Bounds = r; + bx.RecalcLayout(); + bx.InternalPaint(new PaintEventArgs(g, Rectangle.Empty)); + } + finally + { + bx.Text = text; + + if (bx.ThreeState == true) + bx.CheckValue = checkValue; + + bx.Checked = isChecked; + bx.CheckState = checkState; + + bx.CheckBoxItem.IsMouseOver = isMouseOver; + bx.CheckBoxItem.IsMouseDown = isMouseDown; + + g.Restore(gs); + + oc.InCellCallBack = false; + } + } + + #region GetCheckValue + + private bool GetCheckValue(DataGridViewCheckBoxXColumn oc, object value) + { + if (value == null || value == DBNull.Value) + return (false); + + Type type = value.GetType(); + + if (type == typeof(bool)) + return ((bool)value); + + if (type == typeof(string)) + { + string s = (string)value; + + if (oc.CheckValueChecked is string && s.Equals(oc.CheckValueChecked)) + return (true); + + if (oc.CheckValueUnchecked is string && s.Equals(oc.CheckValueUnchecked)) + return (false); + } + else + { + int n = Convert.ToInt32(value); + + if (n == 1) + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #endregion + + #region Mouse processing + + #region OnMouseEnter + + /// + /// OnMouseEnter + /// + /// + protected override void OnMouseEnter(int rowIndex) + { + base.OnMouseEnter(rowIndex); + + DataGridViewCheckBoxXColumn oc = OwningColumn as DataGridViewCheckBoxXColumn; + + if (oc != null && DataGridView != null) + { + _MouseEntered = false; + + oc.ActiveRowIndex = rowIndex; + ToolTipText = _Text; + + RefreshCell(ColumnIndex, rowIndex); + } + } + + #endregion + + #region OnMouseLeave + + /// + /// Processes MouseLeave events + /// + /// + protected override void OnMouseLeave(int rowIndex) + { + base.OnMouseLeave(rowIndex); + + DataGridViewCheckBoxXColumn oc = OwningColumn as DataGridViewCheckBoxXColumn; + + if (oc != null && DataGridView != null) + { + oc.ActiveRowIndex = -1; + + if (_MouseEntered == true) + { + _MouseEntered = false; + + oc.CheckBoxX.CheckBoxItem.InternalMouseLeave(); + } + + RefreshCell(ColumnIndex, rowIndex); + } + } + + #endregion + + #region OnMouseMove + + /// + /// Processes MouseMove events + /// + /// + protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) + { + base.OnMouseMove(e); + + DataGridViewCheckBoxXColumn oc = OwningColumn as DataGridViewCheckBoxXColumn; + + if (oc != null && DataGridView != null) + { + if (this.ReadOnly == true || oc.ReadOnly == true || DataGridView.ReadOnly == true) + return; + + Rectangle cellBounds = DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false); + + cellBounds.X = 0; + cellBounds.Y = 0; + + DataGridViewCellStyle cellStyle = DataGridView.Columns[e.ColumnIndex].InheritedStyle; + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + Point pt = new Point(e.X - r.X, e.Y - r.Y); + + if (oc.CheckBoxX.CheckBoxItem.DisplayRectangle.Contains(pt) == true) + { + if (_MouseEntered == false) + { + _MouseEntered = true; + oc.CheckBoxX.CheckBoxItem.InternalMouseEnter(); + } + } + else + { + if (_MouseEntered == true) + { + _MouseEntered = false; + oc.CheckBoxX.CheckBoxItem.InternalMouseLeave(); + } + } + + oc.CheckBoxX.CheckBoxItem.InternalMouseMove( + new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta)); + + RefreshCell(e.ColumnIndex, e.RowIndex); + } + } + + #endregion + + #region OnMouseDown + + /// + /// Processes MouseDown events + /// + /// + protected override void OnMouseDown(DataGridViewCellMouseEventArgs e) + { + base.OnMouseDown(e); + + if (_MouseEntered == true) + { + DataGridViewCheckBoxXColumn oc = OwningColumn as DataGridViewCheckBoxXColumn; + + if (oc != null && !oc.ReadOnly && DataGridView != null) + { + oc.DownRowIndex = e.RowIndex; + + Rectangle cellBounds = DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false); + + cellBounds.X = 0; + cellBounds.Y = 0; + + DataGridViewCellStyle cellStyle = DataGridView.Columns[e.ColumnIndex].InheritedStyle; + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + Point pt = new Point(e.X - r.X, e.Y - r.Y); + + if (oc.CheckBoxX.CheckBoxItem.DisplayRectangle.Contains(pt) == true) + { + oc.CheckBoxX.CheckValue = GetValue(e.RowIndex); + + oc.CheckBoxX.CheckBoxItem.InternalMouseDown( + new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta)); + + RefreshCell(e.ColumnIndex, e.RowIndex); + } + } + } + } + + #endregion + + #region OnMouseUp + + /// + /// Processes MouseUp events + /// + /// + protected override void OnMouseUp(DataGridViewCellMouseEventArgs e) + { + base.OnMouseUp(e); + + DataGridViewCheckBoxXColumn oc = OwningColumn as DataGridViewCheckBoxXColumn; + + if (oc != null && !oc.ReadOnly && DataGridView != null) + { + Rectangle cellBounds = DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false); + + cellBounds.X = 0; + cellBounds.Y = 0; + + DataGridViewCellStyle cellStyle = DataGridView.Columns[e.ColumnIndex].InheritedStyle; + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + Point pt = new Point(e.X - r.X, e.Y - r.Y); + + oc.CheckBoxX.CheckBoxItem.InternalMouseUp( + new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta)); + + if (e.RowIndex == oc.DownRowIndex) + { + if (r.Contains(e.Location) == true) + Value = oc.CheckBoxX.CheckValue; + + RefreshCell(e.ColumnIndex, e.RowIndex); + } + + oc.DownRowIndex = -1; + } + } + + #endregion + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewCheckBoxXColumn oc = (DataGridViewCheckBoxXColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetContentBounds + + /// + /// Gets the Content bounds for the given cell + /// + /// + /// + private Rectangle GetContentBounds(Rectangle cellBounds) + { + DataGridViewCheckBoxXColumn oc = OwningColumn as DataGridViewCheckBoxXColumn; + + if (oc != null) + { + if (oc.CheckBoxX.Parent == null) + { + Form form = oc.DataGridView.FindForm(); + + if (form != null) + oc.CheckBoxX.Parent = form; + } + + oc.CheckBoxX.CheckBoxItem.RecalcSize(); + + cellBounds.Width = Math.Min(oc.CheckBoxX.CheckBoxItem.WidthInternal, cellBounds.Width); + cellBounds.Width -= (oc.DividerWidth + 3); + cellBounds.Height = oc.CheckBoxX.CheckBoxItem.HeightInternal; + } + + return (cellBounds); + } + + #endregion + + #region RefreshCell + + /// + /// Initiates the refresh of the cell + /// + /// + /// + private void RefreshCell(int columnIndex, int rowIndex) + { + if (DataGridView != null) + DataGridView.InvalidateCell(columnIndex, rowIndex); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewCheckBoxX/DataGridViewCheckBoxXColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewCheckBoxX/DataGridViewCheckBoxXColumn.cs new file mode 100644 index 00000000..c55cc11c --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewCheckBoxX/DataGridViewCheckBoxXColumn.cs @@ -0,0 +1,562 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewButtonXColumn), "Controls.CheckBoxX.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewCheckBoxXColumn : DataGridViewColumn, IDataGridViewColumn + { + #region Events + + [Description("Occurs right before a CheckBoxX Cell is painted.")] + public event EventHandler BeforeCellPaint; + + [Description("Occurs when a CheckBoxX Cell is Clicked.")] + public event EventHandler Click; + + [Description("Occurs when a CheckBoxX Cell is DoubleClicked.")] + public event EventHandler DoubleClicked; + + #endregion + + #region Private variables + + private CheckBoxX _CheckBoxX; + + private int _ActiveRowIndex = -1; + private int _CurrentRowIndex = -1; + private int _DownRowIndex = -1; + + private bool _InCellCallBack; + + private Bitmap _CellBitmap; + + #endregion + + /// + /// Constructor + /// + public DataGridViewCheckBoxXColumn() + { + CellTemplate = new DataGridViewCheckBoxXCell(); + + _CheckBoxX = new CheckBoxX(); + _CheckBoxX.Visible = false; + + _CheckBoxX.CheckValueChecked = true; + _CheckBoxX.CheckValueUnchecked = false; + + HookEvents(true); + } + + #region Internal properties + + #region ActiveRowIndex + + /// + /// Gets or sets the active row index + /// + internal int ActiveRowIndex + { + get { return (_ActiveRowIndex); } + set { _ActiveRowIndex = value; } + } + + #endregion + + #region CheckBoxX + + /// + /// Gets the Control Button + /// + internal CheckBoxX CheckBoxX + { + get { return (_CheckBoxX); } + } + + #endregion + + #region CurrentRowIndex + + /// + /// Gets or sets the Current row index + /// + internal int CurrentRowIndex + { + get { return (_CurrentRowIndex); } + set { _CurrentRowIndex = value; } + } + + #endregion + + #region DownRowIndex + + /// + /// Gets or sets the MouseDown row index + /// + internal int DownRowIndex + { + get { return (_DownRowIndex); } + set { _DownRowIndex = value; } + } + + #endregion + + #region InCellCallBack + + /// + /// Gets or sets the cell callback state + /// + internal bool InCellCallBack + { + get { return (_InCellCallBack); } + set { _InCellCallBack = value; } + } + + #endregion + + #endregion + + #region Public properties + + #region CheckBoxImageChecked + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box is checked. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box is checked")] + public Image CheckBoxImageChecked + { + get { return _CheckBoxX.CheckBoxImageChecked; } + set + { + _CheckBoxX.CheckBoxImageChecked = value; + } + } + #endregion + #region CheckBoxImageUnChecked + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box is unchecked. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box is unchecked")] + public Image CheckBoxImageUnChecked + { + get { return _CheckBoxX.CheckBoxImageUnChecked; } + set + { + _CheckBoxX.CheckBoxImageUnChecked = value; + } + } + #endregion + #region CheckBoxImageIndeterminate + /// + /// Gets or sets the custom image that is displayed instead default check box representation when check box is in indeterminate state. + /// + [DefaultValue(null), Category("CheckBox Images"), Description("Indicates custom image that is displayed instead default check box representation when check box is in indeterminate state")] + public Image CheckBoxImageIndeterminate + { + get { return _CheckBoxX.CheckBoxImageIndeterminate; } + set + { + _CheckBoxX.CheckBoxImageIndeterminate = value; + } + } + #endregion + + #region CheckBoxPosition + + /// + /// Gets or sets the check box position relative to the text. + /// Default value is Left. + /// + [Browsable(true), DefaultValue(eCheckBoxPosition.Left), Category("Appearance")] + [Description("Indicates the check box position relative to the text.")] + public eCheckBoxPosition CheckBoxPosition + { + get { return (_CheckBoxX.CheckBoxPosition); } + set { _CheckBoxX.CheckBoxPosition = value; } + } + + #endregion + + #region Checked + + /// + /// Gets or set a value indicating whether the button is in the checked state. + /// + [Browsable(false)] + public virtual bool Checked + { + get { return (_CheckBoxX.Checked); } + set { _CheckBoxX.Checked = value; } + } + + #endregion + + #region CheckState + + /// + /// Specifies the state of the control, that can be + /// checked, unchecked, or set to an indeterminate state. + /// + [Browsable(false)] + public CheckState CheckState + { + get { return (_CheckBoxX.CheckState); } + set { _CheckBoxX.CheckState = value; } + } + + #endregion + + #region CheckValue + + /// + /// CheckValue + /// + [Browsable(false)] + public object CheckValue + { + get { return (_CheckBoxX.CheckValue); } + set { _CheckBoxX.CheckValue = value; } + } + + #endregion + + #region CheckValueChecked + + /// + /// Gets or sets the value that represents the Checked state value of the check + /// box when CheckValue property is set to that value. Default value is null. + /// + [Browsable(true), DefaultValue(true), Category("Behavior"), TypeConverter(typeof(StringConverter))] + [Description("Represents the Checked state value of the check box when CheckValue property is set to that value. Note that in the designer, this value type is always a string.")] + public object CheckValueChecked + { + get { return (_CheckBoxX.CheckValueChecked); } + set { _CheckBoxX.CheckValueChecked = value; } + } + + #endregion + + #region CheckValueIndeterminate + + /// + /// Gets or sets the value that represents the Indeterminate state of the check + /// box when CheckValue property is set to that value. Default value is null. + /// + [Browsable(true), DefaultValue(null), Category("Behavior"), TypeConverter(typeof(StringConverter))] + [Description("Represents the Indeterminate state value of the check box when CheckValue property is set to that value. Note that in the designer, this value type is always a string.")] + public object CheckValueIndeterminate + { + get { return (_CheckBoxX.CheckValueIndeterminate); } + set { _CheckBoxX.CheckValueIndeterminate = value; } + } + + #endregion + + #region CheckValueUnchecked + + /// + /// Gets or sets the value that represents the Unchecked state value of check + /// box when CheckValue property is set to that value. Default value is 'N'. + /// + [Browsable(true), DefaultValue(false), Category("Behavior"), TypeConverter(typeof(StringConverter))] + [Description("Represents the Unchecked state value of the check box when CheckValue property is set to that value. Note that in the designer, this value type is always a string.")] + public object CheckValueUnchecked + { + get { return (_CheckBoxX.CheckValueUnchecked); } + set { _CheckBoxX.CheckValueUnchecked = value; } + } + + #endregion + + #region ConsiderEmptyStringAsNull + + /// + /// Gets or sets whether empty string is consider as null value + /// during CheckValue value comparison. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Browsable(true)] + [Description("Indicates whether empty string is consider as null value during CheckValue value comparison.")] + public bool ConsiderEmptyStringAsNull + { + get { return (_CheckBoxX.ConsiderEmptyStringAsNull); } + set { _CheckBoxX.ConsiderEmptyStringAsNull = value; } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_CheckBoxX.Enabled); } + set { _CheckBoxX.Enabled = value; } + } + + #endregion + + #region EnableMarkup + + /// + /// Gets or sets whether text-markup support is enabled for controls + /// Text property. Default value is true. Set this property to false to + /// display HTML or other markup in the control instead of it being parsed as text-markup. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for controls Text property.")] + public bool EnableMarkup + { + get { return (_CheckBoxX.EnableMarkup); } + set { _CheckBoxX.EnableMarkup = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the default Text to display + /// + [Browsable(true), Category("Appearance"), DefaultValue("")] + [Description("Indicates the default Text to display.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public string Text + { + get { return (_CheckBoxX.Text); } + set { _CheckBoxX.Text = value; } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the text color. Default value is + /// Color.Empty which indicates that default color is used. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates control text color.")] + public Color TextColor + { + get { return (_CheckBoxX.TextColor); } + set { _CheckBoxX.TextColor = value; } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return (_CheckBoxX.TextColor.IsEmpty == false); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + TextColor = Color.Empty; + } + + #endregion + + #region TextVisible + + /// + /// Gets or sets whether text assigned to the check box is visible. + /// Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether text assigned to the check box is visible.")] + public bool TextVisible + { + get { return (_CheckBoxX.TextVisible); } + set { _CheckBoxX.TextVisible = value; } + } + + #endregion + + #region ThreeState + + /// + /// Gets or sets a value indicating whether the CheckBox will allow + /// three check states rather than two. If the ThreeState property is + /// set to true CheckState property should be used instead of Checked + /// property to set the extended state of the control. + /// + [Browsable(true), Category("Behavior"), DefaultValue(false)] + [Description("Indicates whether the CheckBox will allow three check states rather than two.")] + public bool ThreeState + { + get { return (_CheckBoxX.ThreeState); } + set { _CheckBoxX.ThreeState = value; } + } + + #endregion + + #endregion + + #region HookEvents + + /// + /// HookEvents + /// + /// + private void HookEvents(bool hook) + { + if (hook == true) + { + _CheckBoxX.CheckBoxItem.Click += CheckBoxItem_Click; + _CheckBoxX.CheckBoxItem.DoubleClick += CheckBoxItem_DoubleClick; + } + else + { + _CheckBoxX.CheckBoxItem.Click -= CheckBoxItem_Click; + _CheckBoxX.CheckBoxItem.DoubleClick -= CheckBoxItem_DoubleClick; + } + } + + #endregion + + #region Event processing + + #region CheckBoxItem_Click + + /// + /// CheckBoxItem_Click + /// + /// + /// + void CheckBoxItem_Click(object sender, EventArgs e) + { + if (Click != null) + Click(sender, e); + } + + #endregion + + #region CheckBoxItem_DoubleClick + + /// + /// CheckBoxItem_DoubleClick + /// + /// + /// + void CheckBoxItem_DoubleClick(object sender, EventArgs e) + { + if (DoubleClicked != null) + DoubleClicked(sender, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewCheckBoxXColumn cb = base.Clone() as DataGridViewCheckBoxXColumn; + + if (cb != null) + { + _CheckBoxX.CheckBoxItem.InternalCopyToItem(cb.CheckBoxX.CheckBoxItem); + + cb.CheckValue = CheckValue; + cb.CheckValueChecked = CheckValueChecked; + cb.CheckValueIndeterminate = CheckValueIndeterminate; + cb.CheckValueUnchecked = CheckValueUnchecked; + cb.ConsiderEmptyStringAsNull = ConsiderEmptyStringAsNull; + cb.Enabled = Enabled; + cb.Text = Text; + } + + return (cb); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the ButtonX control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + HookEvents(false); + + if (disposing == true) + _CheckBoxX.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewComboBoxEx/DataGridViewComboBoxExCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewComboBoxEx/DataGridViewComboBoxExCell.cs new file mode 100644 index 00000000..0cc6f5db --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewComboBoxEx/DataGridViewComboBoxExCell.cs @@ -0,0 +1,895 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewComboBoxExCell : DataGridViewTextBoxCell + { + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (typeof(DataGridViewComboBoxExEditingControl)); } + } + + #endregion + + #endregion + + #region InitializeEditingControl + + /// + /// InitializeEditingControl + /// + /// + /// + /// + public override void InitializeEditingControl(int rowIndex, + object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) + { + DetachEditingControl(); + + base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); + + DataGridViewComboBoxExEditingControl ctl = + (DataGridViewComboBoxExEditingControl) DataGridView.EditingControl; + + DataGridViewComboBoxExColumn oc = (DataGridViewComboBoxExColumn) OwningColumn; + ComboBoxEx cb = oc.ComboBoxEx; + + ctl.DropDownStyle = cb.DropDownStyle; + ctl.AutoCompleteCustomSource = cb.AutoCompleteCustomSource; + ctl.AutoCompleteMode = cb.AutoCompleteMode; + ctl.AutoCompleteSource = cb.AutoCompleteSource; + ctl.DrawMode = cb.DrawMode; + ctl.DropDownHeight = cb.DropDownHeight; + ctl.Enabled = cb.Enabled; + ctl.FlatStyle = cb.FlatStyle; + ctl.FocusCuesEnabled = cb.FocusCuesEnabled; + ctl.FormatString = cb.FormatString; + ctl.FormattingEnabled = cb.FormattingEnabled; + ctl.Images = cb.Images; + ctl.ImeMode = cb.ImeMode; + ctl.IntegralHeight = cb.IntegralHeight; + ctl.IsStandalone = cb.IsStandalone; + ctl.ItemHeight = cb.ItemHeight; + ctl.MaxDropDownItems = cb.MaxDropDownItems; + ctl.MaxLength = cb.MaxLength; + ctl.RenderBorder = cb.RenderBorder; + ctl.RightToLeft = cb.RightToLeft; + ctl.Style = cb.Style; + ctl.WatermarkBehavior = cb.WatermarkBehavior; + ctl.WatermarkColor = cb.WatermarkColor; + ctl.WatermarkEnabled = cb.WatermarkEnabled; + ctl.WatermarkFont = cb.WatermarkFont; + ctl.WatermarkText = cb.WatermarkText; + + ctl.DataSource = cb.DataSource; + + if (ctl.DataSource is List == false) + ctl.ValueMember = cb.ValueMember; + + ctl.DisplayMember = cb.DisplayMember; + + if (ctl.DataSource == null) + { + object[] items = new object[cb.Items.Count]; + cb.Items.CopyTo(items, 0); + + ctl.Items.Clear(); + ctl.Items.AddRange(items); + + ctl.Text = Convert.ToString(initialFormattedValue); + } + else + { + object o = GetValue(rowIndex); + object value = GetDataSourceValueEx(oc, cb, o); + + if (value == null) + { + ctl.SelectedIndex = -1; + ctl.SelectedIndex = -1; + } + else + { + ctl.SelectedItem = value; + } + } + + ctl.Click += Click; + ctl.DrawItem += DrawItem; + ctl.DropDownChange += DropDownChange; + ctl.MeasureItem += MeasureItem; + } + + #endregion + + #region DetachEditingControl + + /// + /// DetachEditingControl + /// + public override void DetachEditingControl() + { + if (DataGridView != null && DataGridView.EditingControl != null) + { + DataGridViewComboBoxExEditingControl cb = + DataGridView.EditingControl as DataGridViewComboBoxExEditingControl; + + if (cb != null) + { + cb.Click -= Click; + cb.DrawItem -= DrawItem; + cb.DropDownChange -= DropDownChange; + cb.MeasureItem -= MeasureItem; + } + } + + base.DetachEditingControl(); + } + + #endregion + + #region Event processing + + #region Click + + /// + /// Click + /// + /// + /// + void Click(object sender, EventArgs e) + { + ((DataGridViewComboBoxExColumn)OwningColumn).DoComboBoxEx_Click(sender, e); + } + + #endregion + + #region DrawItem + + /// + /// DrawItem + /// + /// + /// + void DrawItem(object sender, DrawItemEventArgs e) + { + ((DataGridViewComboBoxExColumn)OwningColumn).DoComboBoxEx_DrawItem(sender, e); + } + + #endregion + + #region DropDownChange + + /// + /// DropDownChange + /// + /// + /// + void DropDownChange(object sender, bool expanded) + { + ((DataGridViewComboBoxExColumn)OwningColumn).DoComboBoxEx_DropDownChange( + sender, new DropDownChangeEventArgs(RowIndex, ColumnIndex, expanded)); + } + + #endregion + + #region MeasureItem + + /// + /// MeasureItem + /// + /// + /// + void MeasureItem(object sender, MeasureItemEventArgs e) + { + ((DataGridViewComboBoxExColumn)OwningColumn).DoComboBoxEx_MeasureItem(sender, e); + } + + #endregion + + #endregion + + #region PositionEditingControl + + /// + /// PositionEditingControl + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public override void PositionEditingControl(bool setLocation, bool setSize, Rectangle cellBounds, + Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, + bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) + { + Rectangle editingControlBounds = + PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, + singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow); + + editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle); + + DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y); + DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height); + } + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetCellBounds(editingControlBounds); + + if (r.Height < editingControlBounds.Height) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.MiddleLeft: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height) / 2; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + editingControlBounds.Width = Math.Max(1, editingControlBounds.Width); + editingControlBounds.Height = Math.Max(1, r.Height); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + #region GetPreferredSize + + /// + /// GetPreferredSize + /// + /// + /// + /// + /// + /// + protected override Size GetPreferredSize(Graphics graphics, + DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + { + if (DataGridView == null) + return (new Size(-1, -1)); + + Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize); + + DataGridViewComboBoxExColumn oc = OwningColumn as DataGridViewComboBoxExColumn; + + if (oc != null) + { + ComboBoxEx cb = oc.ComboBoxEx; + + preferredSize.Height = cb.Height; + + if (constraintSize.Width == 0) + { + Rectangle r = DataGridView.GetCellDisplayRectangle(ColumnIndex, rowIndex, true); + preferredSize.Width += cb.GetThumbRect(r).Width; + } + } + + return (preferredSize); + } + + #endregion + + #endregion + + #region ParseFormattedValue + + /// + /// ParseFormattedValue + /// + /// + /// + /// + /// + /// + public override object ParseFormattedValue(object formattedValue, + DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter) + { + DataGridViewComboBoxExColumn oc = (DataGridViewComboBoxExColumn)OwningColumn; + ComboBoxEx di = oc.ComboBoxEx; + + if (di.DataSource != null) + return (GetDataSourceValue(oc, di, formattedValue)); + + return (base.ParseFormattedValue(formattedValue, + cellStyle, formattedValueTypeConverter, valueTypeConverter)); + } + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, + DataGridViewElementStates elementState, object value, object formattedValue, + string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, + DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewComboBoxExColumn oc = (DataGridViewComboBoxExColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintCellBackground(g, cellStyle, rBk); + PaintCellContent(g, cellBounds, rowIndex, value, cellStyle, paintParts, bm); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintCellBackground + + /// + /// Paints the cell background + /// + /// + /// + /// + private void PaintCellBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintCellContent + + private BindingContext _BindingContext = new BindingContext(); + /// + /// Paints the cell content + /// + /// + /// + /// + /// + /// + /// + /// + private void PaintCellContent(Graphics g, Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, Bitmap bm) + { + DataGridViewComboBoxExColumn oc = (DataGridViewComboBoxExColumn)OwningColumn; + ComboBoxEx di = oc.ComboBoxEx; + + Point ptCurrentCell = DataGridView.CurrentCellAddress; + bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex; + bool cellEdited = cellCurrent && DataGridView.EditingControl != null; + + // If the cell is in editing mode, there is nothing else to paint + + if (cellEdited == false && rowIndex < DataGridView.RowCount) + { + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + { + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + if (di.DataSource == null) + { + di.DisplayMember = "Text"; + di.ValueMember = null; + } + else + { + value = GetDataSourceDisplayValue(oc, di, value); + di.BindingContext = _BindingContext; + } + + di.Font = cellStyle.Font; + di.ForeColor = cellStyle.ForeColor; + di.BackColor = cellStyle.BackColor; + + string s = (value == Convert.DBNull || + string.IsNullOrEmpty(Convert.ToString(value))) ? null : Convert.ToString(value); + + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + + if (oc.DisplayControlForCurrentCellOnly == false) + DrawControl(di, r, bm, g, oc, s); + else + DrawText(di, r, g, s); + } + } + } + + #region DrawControl + + /// + /// DrawControl + /// + /// + /// + /// + /// + /// + /// + private void DrawControl(ComboBoxEx di, Rectangle r, + Bitmap bm, Graphics g, DataGridViewComboBoxExColumn oc, string s) + { + Rectangle t = di.GetThumbRect(new Rectangle(0, 0, r.Width, r.Height)); + + if (t.IsEmpty == false) + { + // Work around Windows XP and Windows DropDownList + // DrawToBitmap problems + + if (MustRenderVisibleControl(di.DropDownStyle) == true) + { + di.Location = oc.DataGridView.Location; + + if (di.Parent == null) + { + Form form = oc.DataGridView.FindForm(); + + if (form != null) + di.Parent = form; + } + + di.SendToBack(); + di.Visible = true; + } + + using (Bitmap bm2 = new Bitmap(bm)) + { + di.Bounds = r; + di.DrawToBitmap(bm2, r); + + t.X += r.X; + t.Y += r.Y; + + g.DrawImage(bm2, t, t, GraphicsUnit.Pixel); + + if (t.Left < r.Right) + r.Width -= (r.Right - t.Left - 3); + } + + di.Visible = false; + } + + DrawText(di, r, g, s); + } + + #endregion + + #region DrawText + + /// + /// DrawText + /// + /// + /// + /// + /// + private void DrawText(ComboBoxEx di, Rectangle r, Graphics g, string s) + { + r.Inflate(-2, 0); + + TextDrawing.DrawString(g, s, di.Font, di.ForeColor, r, + eTextFormat.VerticalCenter | eTextFormat.EndEllipsis | eTextFormat.NoPrefix); + } + + #endregion + + #region GetDataSource + + #region GetDataSourceDisplayValue + + private object GetDataSourceDisplayValue( + DataGridViewComboBoxExColumn oc, ComboBoxEx di, object key) + { + if (key != null && + string.IsNullOrEmpty(di.ValueMember) == false && + string.IsNullOrEmpty(di.DisplayMember) == false) + { + CurrencyManager cm = GetCurrencyManager(oc, di); + + if (cm != null) + { + string t = key.ToString(); + + for (int i = 0; i < cm.List.Count; i++) + { + if (cm.List[i] is DataRowView) + { + DataRowView drView = (DataRowView) cm.List[i]; + + string s = drView[di.ValueMember].ToString(); + + if (t.Equals(s) == true) + return (drView[di.DisplayMember]); + } + else if (cm.List[i] is string) + { + if (t.Equals(cm.List[i]) == true) + return (key); + } + else + { + object o = cm.List[i]; + object value = o.GetType().GetProperty(di.ValueMember).GetValue(o, null); + + //if (value is string) + { + if (key.Equals(value) == true) + { + value = o.GetType().GetProperty(di.DisplayMember).GetValue(o, null); + + return (value); + } + } + } + } + } + } + + return ((key == Convert.DBNull) ? "" : key); + } + + #endregion + + #region GetDataSourceValueEx + + private object GetDataSourceValueEx( + DataGridViewComboBoxExColumn oc, ComboBoxEx di, object key) + { + if (key != null && + string.IsNullOrEmpty(di.ValueMember) == false && + string.IsNullOrEmpty(di.DisplayMember) == false) + { + CurrencyManager cm = GetCurrencyManager(oc, di); + + if (cm != null) + { + string t = key.ToString(); + + for (int i = 0; i < cm.List.Count; i++) + { + if (cm.List[i] is DataRowView) + { + DataRowView drView = (DataRowView)cm.List[i]; + + string s = drView[di.ValueMember].ToString(); + + if (t.Equals(s) == true) + return (drView); + } + else if (cm.List[i] is string) + { + if (t.Equals(cm.List[i]) == true) + return (key); + } + else + { + object o = cm.List[i]; + object value = o.GetType().GetProperty(di.ValueMember).GetValue(o, null); + + if (key.Equals(value) == true) + return (o); + } + } + } + } + + return ((key == Convert.DBNull) ? null : key); + } + + #endregion + + #region GetDataSourceValue + + private object GetDataSourceValue( + DataGridViewComboBoxExColumn oc, ComboBoxEx di, object key) + { + if (key != null && + string.IsNullOrEmpty(di.ValueMember) == false && + string.IsNullOrEmpty(di.DisplayMember) == false) + { + CurrencyManager cm = GetCurrencyManager(oc, di); + + if (cm != null) + { + string t = key.ToString(); + + for (int i = 0; i < cm.List.Count; i++) + { + if (cm.List[i] is DataRowView) + { + DataRowView drView = (DataRowView) cm.List[i]; + + string s = drView[di.DisplayMember].ToString(); + + if (t.Equals(s) == true) + return (drView[di.ValueMember]); + } + else if (cm.List[i] is string) + { + if (t.Equals(cm.List[i]) == true) + return (key); + } + else + { + object o = cm.List[i]; + object value = o.GetType().GetProperty(di.DisplayMember).GetValue(o, null); + + if (value is string) + { + if (t.Equals(value) == true) + { + value = o.GetType().GetProperty(di.ValueMember).GetValue(o, null); + + return (value); + } + } + } + } + } + } + + return (key); + } + + #endregion + + #region GetCurrencyManager + + private CurrencyManager GetCurrencyManager( + DataGridViewComboBoxExColumn oc, ComboBoxEx di) + { + if (oc.CurrencyManager == null) + { + if (DataGridView != null && DataGridView.BindingContext != null && + di.DataSource != null && di.DataSource != Convert.DBNull) + { + oc.CurrencyManager = (CurrencyManager) DataGridView.BindingContext[di.DataSource]; + } + } + + return (oc.CurrencyManager); + } + + #endregion + + #endregion + + #region MustRenderVisibleControl + + /// + /// MustRenderVisibleControl + /// + /// + /// + private bool MustRenderVisibleControl(ComboBoxStyle style) + { + if (style == ComboBoxStyle.DropDownList) + return (true); + + OperatingSystem osInfo = Environment.OSVersion; + + return (osInfo.Platform == PlatformID.Win32Windows || + (osInfo.Platform == PlatformID.Win32NT && osInfo.Version.Major < 6)); + + } + + #endregion + + #endregion + + #endregion + + #region Mouse support + + #region OnMouseEnter + + /// + /// OnMouseEnter + /// + /// + protected override void OnMouseEnter(int rowIndex) + { + DataGridViewComboBoxExColumn oc = (DataGridViewComboBoxExColumn) OwningColumn; + ComboBoxEx di = oc.ComboBoxEx; + + if (DataGridView != null) + { + if ((uint)RowIndex < DataGridView.Rows.Count) + { + if (di.DataSource != null) + this.ToolTipText = Convert.ToString(GetDataSourceDisplayValue(oc, di, Value)); + else + this.ToolTipText = Convert.ToString(Value); + } + } + + base.OnMouseEnter(rowIndex); + } + + #endregion + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewComboBoxExColumn oc = (DataGridViewComboBoxExColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetCellBounds + + /// + /// Gets the button bounds for the given cell + /// + /// + /// + private Rectangle GetCellBounds(Rectangle cellBounds) + { + DataGridViewComboBoxExColumn oc = (DataGridViewComboBoxExColumn)OwningColumn; + + Size size = oc.ComboBoxEx.Size; + + cellBounds.Location = new Point(1, 1); + + cellBounds.Width -= oc.DividerWidth; + cellBounds.Height = Math.Min(size.Height, cellBounds.Height); + + return (cellBounds); + } + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewComboBoxEx/DataGridViewComboBoxExColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewComboBoxEx/DataGridViewComboBoxExColumn.cs new file mode 100644 index 00000000..5bdf2500 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewComboBoxEx/DataGridViewComboBoxExColumn.cs @@ -0,0 +1,954 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewButtonXColumn), "Controls.ComboBoxEx.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewComboBoxExColumn : DataGridViewTextBoxColumn, IDataGridViewColumn + { + #region Events + + /// + /// Occurs right before a ComboBox Cell is painted + /// + [Description("Occurs right before a ComboBox Cell is painted.")] + public event EventHandler BeforeCellPaint; + + /// + /// Occurs when the ComboBox is clicked + /// + [Description("Occurs when the ComboBox is clicked.")] + public event EventHandler Click; + + /// + /// Occurs when a visual aspect of an owner-drawn ComboBox changes + /// + [Description("Occurs when a visual aspect of an owner-drawn ComboBox changes.")] + public event EventHandler DrawItem; + + /// + /// Occurs when drop down portion of the ComboBox is shown or hidden. + /// + [Description("Occurs when drop down portion of the ComboBox is shown or hidden.")] + public event EventHandler DropDownChange; + + /// + /// Occurs each time an owner-drawn ComboBox item needs + /// to be drawn and when the sizes of the list items are determined + /// + [Description("Occurs each time an owner-drawn ComboBox item needs to be drawn and when the sizes of the list items are determined.")] + public event EventHandler MeasureItem; + + #endregion + + #region Private variables + + private ComboBoxEx _ComboBoxEx; + private Bitmap _CellBitmap; + private CurrencyManager _CurrencyManager; + private bool _DisplayControlForCurrentCellOnly = true; + + #endregion + + /// + /// Constructor + /// + public DataGridViewComboBoxExColumn() + { + CellTemplate = new DataGridViewComboBoxExCell(); + + _ComboBoxEx = new ComboBoxEx(); + + _ComboBoxEx.RenderBorder = false; + _ComboBoxEx.Visible = false; + + HookEvents(true); + } + + #region Internal properties + + #region ComboBoxEx + + /// + /// Gets the underlying ComboBoxEx control + /// + internal ComboBoxEx ComboBoxEx + { + get { return (_ComboBoxEx); } + } + + #endregion + + #region CurrencyManager + + /// + /// Gets or sets the ComboBox CurrencyManager + /// + internal CurrencyManager CurrencyManager + { + get { return (_CurrencyManager); } + set { _CurrencyManager = value; } + } + + #endregion + + #endregion + + #region Public properties + + #region AutoCompleteCustomSource + + /// + /// Gets or sets a custom System.Collections.Specialized.StringCollection + /// to use when the AutoCompleteSource property is set to CustomSource. + /// + [Browsable(true), DefaultValue(null)] + [Description("Gets or sets a custom Specialized.StringCollection to use when the AutoCompleteSource property is set to CustomSource.")] + public AutoCompleteStringCollection AutoCompleteCustomSource + { + get { return (_ComboBoxEx.AutoCompleteCustomSource); } + set { _ComboBoxEx.AutoCompleteCustomSource = value; } + } + + #endregion + + #region AutoCompleteMode + + /// + /// Gets or sets an option that controls how automatic completion works for the ComboBox. + /// + [Browsable(true), DefaultValue(AutoCompleteMode.None)] + [Description("Indicates how automatic completion works for the ComboBox.")] + public AutoCompleteMode AutoCompleteMode + { + get { return (_ComboBoxEx.AutoCompleteMode); } + set { _ComboBoxEx.AutoCompleteMode = value; } + } + + #endregion + + #region AutoCompleteSource + + /// + /// Gets or sets a value specifying the source of complete strings used for automatic completion. + /// + [Browsable(true), DefaultValue(AutoCompleteSource.None)] + [Description("Indicates the source of complete strings used for automatic completion.")] + public AutoCompleteSource AutoCompleteSource + { + get { return (_ComboBoxEx.AutoCompleteSource); } + set { _ComboBoxEx.AutoCompleteSource = value; } + } + + #endregion + + #region DataSource + + /// + /// Gets or sets the data source that populates the selections for the combo box + /// + [Browsable(true), Category("Data"), DefaultValue((string)null)] + [AttributeProvider(typeof(IListSource))] + [Description("Indicates the data source that populates the selections for the combo box.")] + public object DataSource + { + get { return (_ComboBoxEx.DataSource); } + + set + { + _ComboBoxEx.DataSource = value; + + CurrencyManager = null; + } + } + + #endregion + + #region DisplayMember + + /// + /// Gets or sets a string that specifies the property or column + /// from which to retrieve strings for display in the combo box. + /// + [Browsable(true), DefaultValue(""), Category("Data")] + [Description("Indicates a string that specifies the property or column from which to retrieve strings for display in the combo box")] + [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + [TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] + public string DisplayMember + { + get { return (_ComboBoxEx.DisplayMember); } + set { _ComboBoxEx.DisplayMember = value; } + } + + #endregion + + #region DisplayControlForCurrentCellOnly + + /// + /// Gets or sets whether the control + /// will be displayed for the current cell only. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the control will be displayed for the current cell only.")] + public bool DisplayControlForCurrentCellOnly + { + get { return (_DisplayControlForCurrentCellOnly); } + + set + { + if (_DisplayControlForCurrentCellOnly != value) + { + _DisplayControlForCurrentCellOnly = value; + _ComboBoxEx.Invalidate(); + } + } + } + + #endregion + + #region DrawMode + + /// + /// Gets or sets a value indicating whether user code or + /// operating system code will handle drawing of elements in the list. + /// + [Browsable(true), DefaultValue(DrawMode.Normal)] + [Description("Indicates whether user code or operating system code will handle drawing of elements in the list.")] + public DrawMode DrawMode + { + get { return (_ComboBoxEx.DrawMode); } + set { _ComboBoxEx.DrawMode = value; } + } + + #endregion + + #region DropDownStyle + + /// + /// Gets or sets a value specifying the style of the combo box. + /// + [Browsable(true), DefaultValue(ComboBoxStyle.DropDown)] + [Description("Indicates the style of the combo box.")] + public ComboBoxStyle DropDownStyle + { + get { return (_ComboBoxEx.DropDownStyle); } + set { _ComboBoxEx.DropDownStyle = value; } + } + + #endregion + + #region DropDownHeight + + /// + /// Gets or sets the height in pixels of the drop-down portion of the ComboBox. + /// + [Browsable(true), DefaultValue(100)] + [Description("Indicates the height in pixels of the drop-down portion of the ComboBox.")] + public int DropDownHeight + { + get { return (_ComboBoxEx.DropDownHeight); } + set { _ComboBoxEx.DropDownHeight = value; } + } + + #endregion + + #region DropDownWidth + + /// + /// Gets or sets the width of the drop-down lists of the combo box. + /// + [Browsable(true), Category("Behavior"), DefaultValue(1)] + [Description("Indicates the width of the drop-down lists of the combo box")] + public int DropDownWidth + { + get { return (_ComboBoxEx.DropDownWidth); } + set { _ComboBoxEx.DropDownWidth = value; } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_ComboBoxEx.Enabled); } + set { _ComboBoxEx.Enabled = value; } + } + + #endregion + + #region FlatStyle + + /// + /// Gets or sets the flat style appearance of the column's cells. + /// + [Browsable(true), Category("Appearance"), DefaultValue(FlatStyle.Standard)] + [Description("Indicates the flat style appearance of the column's cells")] + public FlatStyle FlatStyle + { + get { return (_ComboBoxEx.FlatStyle); } + set { _ComboBoxEx.FlatStyle = value; } + } + + #endregion + + #region FocusCuesEnabled + + /// + /// Gets or sets whether control displays focus cues when focused. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether control displays focus cues when focused.")] + public bool FocusCuesEnabled + { + get { return (_ComboBoxEx.FocusCuesEnabled); } + set { _ComboBoxEx.FocusCuesEnabled = value; } + } + + #endregion + + #region FormatString + + /// + /// Gets or sets the format-specifier + /// characters that indicate how a value is to be displayed. + /// + [Browsable(true), DefaultValue("")] + [Description("Indicates the format-specifier characters that indicate how a value is to be displayed.")] + public string FormatString + { + get { return (_ComboBoxEx.FormatString); } + set { _ComboBoxEx.FormatString = value; } + } + + #endregion + + #region FormattingEnabled + + /// + /// Gets or sets a value indicating whether formatting is applied to the DisplayMember property. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether formatting is applied to the DisplayMember.")] + public bool FormattingEnabled + { + get { return (_ComboBoxEx.FormattingEnabled); } + set { _ComboBoxEx.FormattingEnabled = value; } + } + + #endregion + + #region Images + + /// + /// Gets or sets the ImageList control used by Combo box to draw images. + /// + [Browsable(true), Category("Behavior"), DefaultValue(null)] + [Description("The ImageList control used by Combo box to draw images.")] + public ImageList Images + { + get { return (_ComboBoxEx.Images); } + set { _ComboBoxEx.Images = value; } + } + + #endregion + + #region ImeMode + + /// + /// Gets or sets the Input Method Editor (IME) mode of the control. + /// + [Browsable(true), DefaultValue(ImeMode.Inherit)] + [Description("Indicates the Input Method Editor (IME) mode of the control.")] + public ImeMode ImeMode + { + get { return (_ComboBoxEx.ImeMode); } + set { _ComboBoxEx.ImeMode = value; } + } + + #endregion + + #region IntegralHeight + + /// + /// Gets or sets a value indicating whether + /// the control should resize to avoid showing partial items. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether the control should resize to avoid showing partial items.")] + public bool IntegralHeight + { + get { return (_ComboBoxEx.IntegralHeight); } + set { _ComboBoxEx.IntegralHeight = value; } + } + + #endregion + + #region IsStandalone + + /// + /// Gets or sets whether control is stand-alone control. + /// Stand-alone flag affects the appearance of the control in Office 2007 style. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates the appearance of the control.")] + public bool IsStandalone + { + get { return (_ComboBoxEx.IsStandalone); } + set { _ComboBoxEx.IsStandalone = value; } + } + + #endregion + + #region ItemHeight + + /// + /// Gets or sets the height of an item in the combo box. + /// + [Browsable(true), DefaultValue(12)] + [Description("Indicates the height of an item in the combo box.")] + public int ItemHeight + { + get { return (_ComboBoxEx.ItemHeight); } + set { _ComboBoxEx.ItemHeight = value; } + } + + #endregion + + #region Items + + /// + /// Gets the collection of objects used as selections in the combo box. + /// + [Browsable(true), Category("Data")] + [Description("Indicates the collection of objects used as selections in the combo box")] + [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ComboBox.ObjectCollection Items + { + get { return (_ComboBoxEx.Items); } + } + + #endregion + + #region MaxDropDownItems + + /// + /// Gets or sets the maximum number of items + /// in the drop-down list of the cells in the column. + /// + [Browsable(true), DefaultValue(8), Category("Behavior")] + [Description("Indicates the maximum number of items in the drop-down list of the cells in the column.")] + public int MaxDropDownItems + { + get { return (_ComboBoxEx.MaxDropDownItems); } + set { _ComboBoxEx.MaxDropDownItems = value; } + } + + #endregion + + #region MaxLength + + /// + /// Gets or sets the number of characters a user can type into the ComboBox. + /// + [Browsable(true), DefaultValue(0)] + [Description("Indicates the number of characters a user can type into the ComboBox.")] + public int MaxLength + { + get { return (_ComboBoxEx.MaxLength); } + set { _ComboBoxEx.MaxLength = value; } + } + + #endregion + + #region RightToLeft + + /// + /// Gets or sets a value indicating whether control's + /// elements are aligned to support locales using right-to-left fonts. + /// + [Browsable(true), DefaultValue(RightToLeft.Inherit)] + [Description("Indicates control's elements are aligned to support locales using right-to-left fonts.")] + public RightToLeft RightToLeft + { + get { return (_ComboBoxEx.RightToLeft); } + set { _ComboBoxEx.RightToLeft = value; } + } + + #endregion + + #region Sorted + + /// + /// Gets or sets whether the items in the combo box are sorted. + /// + [Browsable(true), DefaultValue(false), Category("Behavior")] + [Description("Indicates whether the items in the combo box are sorted.")] + public bool Sorted + { + get { return (_ComboBoxEx.Sorted); } + set { _ComboBoxEx.Sorted = value; } + } + + #endregion + + #region Style + + /// + /// Determines the visual style applied to + /// the combo box when shown. Default style is Office 2007. + /// + [Browsable(true), Category("Appearance"), DefaultValue(eDotNetBarStyle.Office2007)] + [Description("Determines the display of the item when shown.")] + public eDotNetBarStyle Style + { + get { return (_ComboBoxEx.Style); } + set { _ComboBoxEx.Style = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the text associated with this control. + /// + [Browsable(true), DefaultValue("")] + [Description("Indicates the text associated with this control.")] + public string Text + { + get { return (_ComboBoxEx.Text); } + set { _ComboBoxEx.Text = value; } + } + + #endregion + + #region ValueMember + + /// + /// Gets or sets a string that specifies the property or column + /// from which to get values that correspond to the selections in the drop-down list. + /// + [Browsable(true), Category("Data"), DefaultValue("")] + [Description("Indicates a string that specifies the property or column from which to get values that correspond to the selections in the drop-down list.")] + [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + [TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] + public string ValueMember + { + get { return (_ComboBoxEx.ValueMember); } + set { _ComboBoxEx.ValueMember = value; } + } + + #endregion + + #region WatermarkBehavior + + /// + /// Gets or sets the watermark hiding behaviour. Default value + /// indicates that watermark is hidden when control receives input focus. + /// + [DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior")] + [Description("Indicates watermark hiding behaviour.")] + public eWatermarkBehavior WatermarkBehavior + { + get { return (_ComboBoxEx.WatermarkBehavior); } + set { _ComboBoxEx.WatermarkBehavior = value; } + } + + #endregion + + #region WatermarkColor + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return (_ComboBoxEx.WatermarkColor); } + set { _ComboBoxEx.WatermarkColor = value; } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return (_ComboBoxEx.ShouldSerializeWatermarkColor()); + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + _ComboBoxEx.ResetWatermarkColor(); + } + + #endregion + + #region WatermarkEnabled + + /// + /// Gets or sets whether watermark text is + /// displayed when control is empty. Default value is true. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return (_ComboBoxEx.WatermarkEnabled); } + set { _ComboBoxEx.WatermarkEnabled = value; } + } + + #endregion + + #region WatermarkFont + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates watermark font.")] + public Font WatermarkFont + { + get { return (_ComboBoxEx.WatermarkFont); } + set { _ComboBoxEx.WatermarkFont = value; } + } + + #endregion + + #region WatermarkText + + /// + /// Gets or sets the watermark (tip) text displayed inside of the control when Text + /// is not set and control does not have input focus. This property supports text-markup. + /// Note that WatermarkText is not compatible with the auto-complete feature of .NET Framework 2.0. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus.")] + [Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public string WatermarkText + { + get { return (_ComboBoxEx.WatermarkText); } + set { _ComboBoxEx.WatermarkText = value; } + } + + #endregion + + #endregion + + #region HookEvents + + /// + /// HookEvents + /// + /// + private void HookEvents(bool hook) + { + if (hook == true) + _ComboBoxEx.DataSourceChanged += ComboBoxEx_DataSourceChanged; + else + _ComboBoxEx.DataSourceChanged -= ComboBoxEx_DataSourceChanged; + } + + #endregion + + #region Event processing + + #region ComboBoxEx_DataSourceChanged + + /// + /// ComboBoxEx_DataSourceChanged + /// + /// + /// + void ComboBoxEx_DataSourceChanged(object sender, EventArgs e) + { + _CurrencyManager = null; + + _ComboBoxEx.Items.Clear(); + _ComboBoxEx.DisplayMember = null; + _ComboBoxEx.ValueMember = null; + } + + #endregion + + #region DoComboBoxEx_Click + + /// + /// DoComboBoxEx_Click + /// + /// + /// + internal void DoComboBoxEx_Click(object sender, EventArgs e) + { + if (Click != null) + Click(sender, e); + } + + #endregion + + #region DoComboBoxEx_DrawItem + + /// + /// DoComboBoxEx_DrawItem + /// + /// + /// + internal void DoComboBoxEx_DrawItem(object sender, DrawItemEventArgs e) + { + if (DrawItem != null) + DrawItem(sender, e); + } + + #endregion + + #region DoComboBoxEx_DropDownChange + + /// + /// DoComboBoxEx_DropDownChange + /// + /// + /// + internal void DoComboBoxEx_DropDownChange(object sender, DropDownChangeEventArgs e) + { + if (DropDownChange != null) + DropDownChange(sender, e); + } + + #endregion + + #region DoComboBoxEx_MeasureItem + + /// + /// DoComboBoxEx_MeasureItem + /// + /// + /// + internal void DoComboBoxEx_MeasureItem(object sender, MeasureItemEventArgs e) + { + if (MeasureItem != null) + MeasureItem(sender, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ToString + + public override string ToString() + { + StringBuilder builder = new StringBuilder(); + + builder.Append("DataGridViewComboBoxExColumn { Name="); + builder.Append(Name); + builder.Append(", Index="); + builder.Append(Index.ToString(CultureInfo.CurrentCulture)); + builder.Append(" }"); + + return (builder.ToString()); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewComboBoxExColumn cb = base.Clone() as DataGridViewComboBoxExColumn; + + if (cb != null) + { + cb.AutoCompleteCustomSource = AutoCompleteCustomSource; + cb.AutoCompleteMode = AutoCompleteMode; + cb.AutoCompleteSource = AutoCompleteSource; + cb.DrawMode = DrawMode; + cb.DropDownHeight = DropDownHeight; + cb.DropDownStyle = DropDownStyle; + cb.Enabled = Enabled; + cb.FlatStyle = FlatStyle; + cb.FocusCuesEnabled = FocusCuesEnabled; + cb.FormatString = FormatString; + cb.FormattingEnabled = FormattingEnabled; + cb.Images = Images; + cb.ImeMode = ImeMode; + cb.IntegralHeight = IntegralHeight; + cb.IsStandalone = IsStandalone; + cb.ItemHeight = ItemHeight; + cb.MaxDropDownItems = MaxDropDownItems; + cb.MaxLength = MaxLength; + cb.RightToLeft = RightToLeft; + cb.Style = Style; + cb.Text = Text; + cb.WatermarkBehavior = WatermarkBehavior; + cb.WatermarkColor = WatermarkColor; + cb.WatermarkEnabled = WatermarkEnabled; + cb.WatermarkFont = WatermarkFont; + cb.WatermarkText = WatermarkText; + + cb.DataSource = DataSource; + cb.DisplayMember = DisplayMember; + cb.ValueMember = ValueMember; + + if (cb.DataSource == null) + { + for (int i = 0; i < Items.Count; i++) + cb.Items.Add(Items[i]); + } + + cb.DisplayControlForCurrentCellOnly = DisplayControlForCurrentCellOnly; + } + + return (cb); + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + HookEvents(false); + + if (disposing == true) + _ComboBoxEx.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + } + + #region DropDownChangeEventArgs + + /// + /// DropDownChangeEventArgs + /// + public class DropDownChangeEventArgs : EventArgs + { + #region Private variables + + private int _RowIndex; + private int _ColumnIndex; + private bool _Expanded; + + #endregion + + public DropDownChangeEventArgs(int rowIndex, int columnIndex, bool expanded) + { + _RowIndex = rowIndex; + _ColumnIndex = columnIndex; + _Expanded = expanded; + } + + #region Public properties + + /// + /// ColumnIndex + /// + public int ColumnIndex + { + get { return (_ColumnIndex); } + } + + /// + /// Expanded state + /// + public bool Expanded + { + get { return (_Expanded); } + } + + /// + /// RowIndex + /// + public int RowIndex + { + get { return (_RowIndex); } + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewComboBoxEx/DataGridViewComboBoxExEditingControl.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewComboBoxEx/DataGridViewComboBoxExEditingControl.cs new file mode 100644 index 00000000..3374a6dc --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewComboBoxEx/DataGridViewComboBoxExEditingControl.cs @@ -0,0 +1,240 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), ComVisible(false)] + public class DataGridViewComboBoxExEditingControl : ComboBoxEx, IDataGridViewEditingControl + { + #region Private variables + + private DataGridView _DataGridView; + + private int _RowIndex; + private bool _ValueChanged; + + #endregion + + public DataGridViewComboBoxExEditingControl() + { + TabStop = false; + } + + #region OnTextChanged + + /// + /// Handles OnTextChanged events + /// + /// + protected override void OnTextChanged(EventArgs e) + { + NotifyDataGridViewOfValueChange(); + + base.OnTextChanged(e); + } + + #endregion + + #region OnSelectedIndexChanged + + /// + /// OnSelectedIndexChanged + /// + /// + protected override void OnSelectedIndexChanged(EventArgs e) + { + base.OnSelectedIndexChanged(e); + + if (SelectedIndex != -1) + NotifyDataGridViewOfValueChange(); + } + + /// + /// NotifyDataGridViewOfValueChange + /// + private void NotifyDataGridViewOfValueChange() + { + if (_DataGridView.EditingControl == this) + { + _ValueChanged = true; + _DataGridView.NotifyCurrentCellDirty(true); + } + } + + #endregion + + #region IDataGridViewEditingControl Members + + #region Public properties + + #region EditingControlDataGridView + + /// + /// Gets or sets the DataGridView + /// + public DataGridView EditingControlDataGridView + { + get { return (_DataGridView); } + set { _DataGridView = value; } + } + + #endregion + + #region EditingControlFormattedValue + + /// + /// Gets or sets the Control Formatted Value + /// + public object EditingControlFormattedValue + { + get { return (GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting)); } + + set + { + string s = value as string; + + if (s != null) + { + Text = s; + + if (string.Compare(s, this.Text, true, CultureInfo.CurrentCulture) != 0) + SelectedIndex = -1; + } + } + } + + #endregion + + #region EditingControlRowIndex + + /// + /// Gets or sets the Control RoeIndex + /// + public int EditingControlRowIndex + { + get { return (_RowIndex); } + set { _RowIndex = value; } + } + + #endregion + + #region EditingControlValueChanged + + /// + /// Gets or sets the Control ValueChanged state + /// + public bool EditingControlValueChanged + { + get { return (_ValueChanged); } + set { _ValueChanged = value; } + } + + #endregion + + #region EditingPanelCursor + + /// + /// Gets the Panel Cursor + /// + public Cursor EditingPanelCursor + { + get { return (Cursors.Default); } + } + + #endregion + + #region RepositionEditingControlOnValueChange + + /// + /// Gets whether to RepositionEditingControlOnValueChange + /// + public bool RepositionEditingControlOnValueChange + { + get { return (false); } + } + + #endregion + + #endregion + + #region ApplyCellStyleToEditingControl + + /// + /// ApplyCellStyleToEditingControl + /// + /// + public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) + { + Font = dataGridViewCellStyle.Font; + + ForeColor = dataGridViewCellStyle.ForeColor; + BackColor = dataGridViewCellStyle.BackColor; + } + + #endregion + + #region GetEditingControlFormattedValue + + /// + /// Gets EditingControlFormattedValue + /// + /// + /// + public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) + { + return (Text); + } + + #endregion + + #region EditingControlWantsInputKey + + /// + /// Gets whether the given key wants to be processed + /// by the Control + /// + /// + /// + /// + public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) + { + if (DroppedDown == false) + { + if ((keyData & Keys.Right) == Keys.Right) + return (true); + + if ((keyData & Keys.Left) == Keys.Left) + return (true); + } + + if (((((keyData & Keys.KeyCode) != Keys.Down) && ((keyData & Keys.KeyCode) != Keys.Up)) && + (!DroppedDown || ((keyData & Keys.KeyCode) != Keys.Escape))) && ((keyData & Keys.KeyCode) != Keys.Return)) + { + return (dataGridViewWantsInputKey == false); + } + + return (true); + } + + #endregion + + #region PrepareEditingControlForEdit + + /// + /// PrepareEditingControlForEdit + /// + /// + public void PrepareEditingControlForEdit(bool selectAll) + { + if (selectAll) + SelectAll(); + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDateTimeInput/DataGridViewDateTimeInputCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDateTimeInput/DataGridViewDateTimeInputCell.cs new file mode 100644 index 00000000..ab0528b3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDateTimeInput/DataGridViewDateTimeInputCell.cs @@ -0,0 +1,746 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Media; +using System.Windows.Forms; +using DevComponents.Editors; +using DevComponents.Editors.DateTimeAdv; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewDateTimeInputCell : DataGridViewTextBoxCell + { + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (typeof(DataGridViewDateTimeInputEditingControl)); } + } + + #endregion + + #region FormattedValueType + + /// + /// FormattedValueType + /// + public override Type FormattedValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region ValueType + + public override Type ValueType + { + get { return (typeof(DateTime)); } + } + + #endregion + + #endregion + + #region InitializeEditingControl + + /// + /// InitializeEditingControl + /// + /// + /// + /// + public override void InitializeEditingControl(int rowIndex, + object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) + { + DetachEditingControl(); + + base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); + + DataGridViewDateTimeInputEditingControl ctl = + (DataGridViewDateTimeInputEditingControl)DataGridView.EditingControl; + + DataGridViewDateTimeInputColumn oc = OwningColumn as DataGridViewDateTimeInputColumn; + + if (oc != null) + { + DateTimeInput di = oc.DateTimeInput; + + ctl.AllowEmptyState = di.AllowEmptyState; + ctl.AutoAdvance = di.AutoAdvance; + ctl.AutoOverwrite = di.AutoOverwrite; + ctl.AutoSelectDate = di.AutoSelectDate; + ctl.CustomFormat = di.CustomFormat; + ctl.DefaultInputValues = di.DefaultInputValues; + ctl.Enabled = di.Enabled; + ctl.Format = di.Format; + ctl.InputHorizontalAlignment = GetHorizontalAlignment(dataGridViewCellStyle.Alignment); + ctl.IsInputReadOnly = di.IsInputReadOnly; + ctl.LockUpdateChecked = di.LockUpdateChecked; + ctl.MinDate = di.MinDate; + ctl.MaxDate = di.MaxDate; + ctl.SelectNextInputCharacters = di.SelectNextInputCharacters; + ctl.ShowCheckBox = di.ShowCheckBox; + ctl.ShowUpDown = di.ShowUpDown; + + ctl.BackgroundStyle.ApplyStyle(di.BackgroundStyle); + ctl.BackgroundStyle.Class = di.BackgroundStyle.Class; + + di.ButtonClear.CopyToItem(ctl.ButtonClear); + di.ButtonDropDown.CopyToItem(ctl.ButtonDropDown); + di.ButtonFreeText.CopyToItem(ctl.ButtonFreeText); + di.ButtonCustom.CopyToItem(ctl.ButtonCustom); + di.ButtonCustom2.CopyToItem(ctl.ButtonCustom2); + di.MonthCalendar.InternalCopyToItem(ctl.MonthCalendar); + + ctl.ButtonClearClick += ButtonClearClick; + ctl.ButtonCustomClick += ButtonCustomClick; + ctl.ButtonCustom2Click += ButtonCustom2Click; + ctl.ButtonDropDownClick += ButtonDropDownClick; + ctl.ButtonFreeTextClick += ButtonFreeTextClick; + ctl.ConvertFreeTextEntry += ConvertFreeTextEntry; + + //ctl.Value = GetValue(initialFormattedValue); + ctl.ValueObject = Value; + + ctl.EditCancelled = false; + } + } + + #endregion + + #region DetachEditingControl + + /// + /// DetachEditingControl + /// + public override void DetachEditingControl() + { + if (DataGridView != null && DataGridView.EditingControl != null) + { + DataGridViewDateTimeInputEditingControl di = + DataGridView.EditingControl as DataGridViewDateTimeInputEditingControl; + + if (di != null) + { + di.ButtonClearClick -= ButtonClearClick; + di.ButtonCustomClick -= ButtonCustomClick; + di.ButtonCustom2Click -= ButtonCustom2Click; + di.ButtonDropDownClick -= ButtonDropDownClick; + di.ButtonFreeTextClick -= ButtonFreeTextClick; + di.ConvertFreeTextEntry -= ConvertFreeTextEntry; + + if (di.EditCancelled == true) + { + di.EditCancelled = false; + + SystemSounds.Beep.Play(); + } + } + } + + base.DetachEditingControl(); + } + + #endregion + + #region Event processing + + #region ButtonClearClick + + /// + /// ButtonClearClick + /// + /// + /// + void ButtonClearClick(object sender, CancelEventArgs e) + { + ((DataGridViewDateTimeInputColumn)OwningColumn).DoButtonClearClick(sender, e); + } + + #endregion + + #region ButtonCustomClick + + /// + /// ButtonCustomClick + /// + /// + /// + void ButtonCustomClick(object sender, EventArgs e) + { + ((DataGridViewDateTimeInputColumn)OwningColumn).DoButtonCustomClick(sender, e); + } + + #endregion + + #region ButtonCustom2Click + + /// + /// ButtonCustom2Click + /// + /// + /// + void ButtonCustom2Click(object sender, EventArgs e) + { + ((DataGridViewDateTimeInputColumn)OwningColumn).DoButtonCustom2Click(sender, e); + } + + #endregion + + #region ButtonDropDownClick + + /// + /// ButtonDropDownClick + /// + /// + /// + void ButtonDropDownClick(object sender, CancelEventArgs e) + { + ((DataGridViewDateTimeInputColumn)OwningColumn).DoButtonDropDownClick(sender, e); + } + + #endregion + + #region ButtonFreeTextClick + + /// + /// ButtonFreeTextClick + /// + /// + /// + void ButtonFreeTextClick(object sender, CancelEventArgs e) + { + ((DataGridViewDateTimeInputColumn)OwningColumn).DoButtonFreeTextClick(sender, e); + } + + #endregion + + #region ConvertFreeTextEntry + + /// + /// ConvertFreeTextEntry + /// + /// + /// + void ConvertFreeTextEntry(object sender, FreeTextEntryConversionEventArgs e) + { + ((DataGridViewDateTimeInputColumn)OwningColumn).DoConvertFreeTextEntry(sender, e); + } + + #endregion + + #endregion + + #region PositionEditingControl + + /// + /// PositionEditingControl + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public override void PositionEditingControl(bool setLocation, bool setSize, Rectangle cellBounds, + Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, + bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) + { + Rectangle editingControlBounds = + PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, + singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow); + + editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle); + + DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y); + DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height); + } + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetCellBounds(editingControlBounds); + + if (cellStyle != null && r.Height < editingControlBounds.Height) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.MiddleLeft: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height) / 2; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + editingControlBounds.Width = Math.Max(1, editingControlBounds.Width); + editingControlBounds.Height = Math.Max(1, r.Height); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + #region GetPreferredSize + + /// + /// GetPreferredSize + /// + /// + /// + /// + /// + /// + protected override Size GetPreferredSize(Graphics graphics, + DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + { + if (DataGridView == null) + return (new Size(-1, -1)); + + Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize); + + DataGridViewDateTimeInputColumn oc = OwningColumn as DataGridViewDateTimeInputColumn; + + if (oc != null) + { + DateTimeInput dt = oc.DateTimeInput; + + preferredSize.Width += 6; + preferredSize.Height = dt.Height; + + if (constraintSize.Width == 0) + { + preferredSize.Width += GetImageWidth(dt.ButtonClear); + preferredSize.Width += GetImageWidth(dt.ButtonCustom); + preferredSize.Width += GetImageWidth(dt.ButtonCustom2); + preferredSize.Width += GetImageWidth(dt.ButtonDropDown); + preferredSize.Width += GetImageWidth(dt.ButtonFreeText); + + if (dt.ShowUpDown == true) + preferredSize.Width += 16; + + if (dt.ShowCheckBox == true) + preferredSize.Width += 16; + } + } + + return (preferredSize); + } + + #endregion + + #region GetFormattedValue + + protected override object GetFormattedValue(object value, int rowIndex, + ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, + TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) + { + DataGridViewDateTimeInputColumn oc = OwningColumn as DataGridViewDateTimeInputColumn; + + if (oc != null) + { + DateTimeInput dt = oc.DateTimeInput; + dt.Value = GetValue(value); + + return (dt.Text); + } + + return (base.GetFormattedValue(value, rowIndex, + ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context)); + } + + #endregion + + #region GetImageWidth + + private int GetImageWidth(InputButtonSettings ibs) + { + if (ibs.Visible == true) + return (ibs.Image != null ? ibs.Image.Width : 16); + + return (0); + } + + #endregion + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, + DataGridViewElementStates elementState, object value, object formattedValue, + string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, + DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewDateTimeInputColumn oc = (DataGridViewDateTimeInputColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintCellBackground(g, cellStyle, rBk); + PaintCellContent(g, cellBounds, rowIndex, formattedValue, cellStyle, paintParts); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintCellBackground + + /// + /// Paints the cell background + /// + /// + /// + /// + private void PaintCellBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintCellContent + + /// + /// Paints the cell content + /// + /// + /// + /// + /// + /// + /// + private void PaintCellContent(Graphics g, Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts) + { + DataGridViewDateTimeInputColumn oc = (DataGridViewDateTimeInputColumn)OwningColumn; + DateTimeInput di = oc.DateTimeInput; + + Point ptCurrentCell = DataGridView.CurrentCellAddress; + bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex; + bool cellEdited = cellCurrent && DataGridView.EditingControl != null; + + // If the cell is in editing mode, there is nothing else to paint + + if (cellEdited == false && rowIndex < DataGridView.RowCount) + { + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + { + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + di.Font = cellStyle.Font; + di.ForeColor = cellStyle.ForeColor; + di.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + + di.BackgroundStyle.TextColor = cellStyle.ForeColor; + di.BackgroundStyle.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + + di.InputHorizontalAlignment = GetHorizontalAlignment(cellStyle.Alignment); + + di.Value = GetValue(value); + + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + + if (oc.DisplayControlForCurrentCellOnly == false) + DrawControl(di, r, g); + else + DrawText(di, r, g); + } + } + } + + #region DrawControl + + /// + /// DrawControl + /// + /// + /// + /// + private void DrawControl(DateTimeInput di, Rectangle r, Graphics g) + { + GraphicsState gs = g.Save(); + + try + { + g.TranslateTransform(r.X, r.Y); + + di.Width = r.Width; + di.InternalPaint(new PaintEventArgs(g, Rectangle.Empty)); + } + finally + { + g.Restore(gs); + } + } + + #endregion + + #region DrawText + + /// + /// DrawText + /// + /// + /// + /// + private void DrawText(DateTimeInput di, Rectangle r, Graphics g) + { + r.Inflate(-2, 0); + + eTextFormat tf = eTextFormat.VerticalCenter; + + switch (di.InputHorizontalAlignment) + { + case eHorizontalAlignment.Center: + tf |= eTextFormat.HorizontalCenter; + break; + + case eHorizontalAlignment.Right: + tf |= eTextFormat.Right; + break; + } + + TextDrawing.DrawString(g, di.Text, di.Font, di.ForeColor, r, tf); + } + + #endregion + + #endregion + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewDateTimeInputColumn oc = (DataGridViewDateTimeInputColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetCellBounds + + /// + /// Gets the button bounds for the given cell + /// + /// + /// + private Rectangle GetCellBounds(Rectangle cellBounds) + { + DataGridViewDateTimeInputColumn oc = (DataGridViewDateTimeInputColumn)OwningColumn; + + Size size = oc.DateTimeInput.Size; + + cellBounds.Location = new Point(1, 1); + + cellBounds.Width = Math.Min(size.Width, cellBounds.Width); + cellBounds.Width -= oc.DividerWidth; + cellBounds.Height = size.Height; + + return (cellBounds); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + private DateTime GetValue(object value) + { + if (value == Convert.DBNull || + (value is string && String.IsNullOrEmpty((string)value) == true)) + { + return (DateTime.MinValue); + } + + if (value is DateTime) + return (Convert.ToDateTime(value)); + else if (value is string && DevComponents.Editors.DateTimeAdv.DateTimeInput.CurrentCulture != null) + { + System.DateTime d = new System.DateTime(); + if (System.DateTime.TryParse(value.ToString(), DevComponents.Editors.DateTimeAdv.DateTimeInput.GetActiveCulture().DateTimeFormat, + System.Globalization.DateTimeStyles.None, out d)) + return d; + } + + return (Convert.ToDateTime(value)); + } + + #endregion + + #region GetHorizontalAlignment + + /// + /// GetHorizontalAlignment + /// + /// + /// + private eHorizontalAlignment GetHorizontalAlignment(DataGridViewContentAlignment alignment) + { + switch (alignment) + { + case DataGridViewContentAlignment.TopCenter: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.BottomCenter: + return (eHorizontalAlignment.Center); + + case DataGridViewContentAlignment.TopRight: + case DataGridViewContentAlignment.MiddleRight: + case DataGridViewContentAlignment.BottomRight: + return (eHorizontalAlignment.Right); + + default: + return (eHorizontalAlignment.Left); + } + } + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDateTimeInput/DataGridViewDateTimeInputColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDateTimeInput/DataGridViewDateTimeInputColumn.cs new file mode 100644 index 00000000..a21a75d8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDateTimeInput/DataGridViewDateTimeInputColumn.cs @@ -0,0 +1,750 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using DevComponents.Editors; +using DevComponents.Editors.DateTimeAdv; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewButtonXColumn), "DateTimeInput.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewDateTimeInputColumn : DataGridViewTextBoxColumn, IDataGridViewColumn + { + #region Events + + /// + /// Occurs right before a DateTimeInput Cell is painted + /// + [Description("Occurs right before a DateTimeInput Cell is painted.")] + public event EventHandler BeforeCellPaint; + + /// + /// Occurs when Clear button is clicked and allows you + /// to cancel the default action performed by the button + /// + [Description("Occurs when Clear button is clicked and allows you to cancel the default action performed by the button.")] + public event EventHandler ButtonClearClick; + + /// + /// Occurs when ButtonCustom control is clicked + /// + [Description("Occurs when ButtonCustom control is clicked.")] + public event EventHandler ButtonCustomClick; + + /// + /// Occurs when ButtonCustom2 control is clicked + /// + [Description("Occurs when ButtonCustom2 control is clicked.")] + public event EventHandler ButtonCustom2Click; + + /// + /// Occurs when Drop-Down button that shows calendar + /// is clicked and allows you to cancel showing of the popup + /// + [Description("Occurs when Drop-Down button that shows calendar is clicked and allows you to cancel showing of the popup.")] + public event EventHandler ButtonDropDownClick; + + /// + /// Occurs when Free-Text button is clicked + /// and allows you to cancel its default action + /// + [Description("Occurs when Free-Text button is clicked and allows you to cancel its default action.")] + public event EventHandler ButtonFreeTextClick; + + /// + /// Occurs if Free-Text entry value is not natively recognized by + /// the control and provides you with opportunity to convert that + /// value to the value the control expects + /// + [Description("Occurs if Free-Text entry value is not natively recognized by the control and provides you with opportunity to convert that value to the value the control expects.")] + public event EventHandler ConvertFreeTextEntry; + + #endregion + + #region Private variables + + private DateTimeInput _DateTimeInput; + private Bitmap _CellBitmap; + private bool _DisplayControlForCurrentCellOnly = true; + + #endregion + + /// + /// Constructor + /// + public DataGridViewDateTimeInputColumn() + { + CellTemplate = new DataGridViewDateTimeInputCell(); + + _DateTimeInput = new DateTimeInput(); + + _DateTimeInput.BackgroundStyle.Class = ElementStyleClassKeys.DataGridViewDateTimeBorderKey; + _DateTimeInput.Visible = false; + } + + #region Dispose + + protected override void Dispose(bool disposing) + { + if (disposing == true) + _DateTimeInput.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + + #region Internal properties + + #region DateTimeInput + + /// + /// Gets the underlying DateTimeInput control + /// + internal DateTimeInput DateTimeInput + { + get { return (_DateTimeInput); } + } + + #endregion + + #endregion + + #region Public properties + + #region AllowEmptyState + + /// + /// Gets or sets whether empty null/nothing state of the control is + /// allowed. Default value is true which means that IsEmpty property may + /// return true if input value is resets or ValueObject set to null/nothing. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether empty null/nothing state of the control is allowed.")] + public bool AllowEmptyState + { + get { return (_DateTimeInput.AllowEmptyState); } + set { _DateTimeInput.AllowEmptyState = value; } + } + + #endregion + + #region AutoAdvance + + /// + /// Gets or sets whether input focus is automatically advanced + /// to next input field when input is complete in current one. + /// + [Browsable(true), DefaultValue(false), Category("Behavior")] + [Description("Indicates whether input focus is automatically advanced to next input field when input is complete in current one.")] + public bool AutoAdvance + { + get { return (_DateTimeInput.AutoAdvance); } + set { _DateTimeInput.AutoAdvance = value; } + } + + #endregion + + #region AutoSelectDate + + /// + /// Gets or sets whether first day in month is automatically + /// selected on popup date picker when month or year is changed. + /// + [Browsable(true), DefaultValue(false), Category("Behavior")] + [Description("Indicates whether first day in month is automatically selected on popup date picker when month or year is changed.")] + public bool AutoSelectDate + { + get { return (_DateTimeInput.AutoSelectDate); } + set { _DateTimeInput.AutoSelectDate = value; } + } + + #endregion + + #region AutoOverwrite + + /// + /// Gets or sets whether auto-overwrite functionality for input is enabled. + /// When in auto-overwrite mode input field will erase existing entry + /// and start new one if typing is continued after InputComplete method is called. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether auto-overwrite functionality for input is enabled.")] + public bool AutoOverwrite + { + get { return (_DateTimeInput.AutoOverwrite); } + set { _DateTimeInput.AutoOverwrite = value; } + } + + #endregion + + #region BackgroundStyle + + /// + /// Specifies the background style of the control. + /// + [Browsable(true), Category("Style")] + [Description("Gets or sets control background style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return (_DateTimeInput.BackgroundStyle); } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _DateTimeInput.ResetBackgroundStyle(); + + _DateTimeInput.BackgroundStyle.Class = "TextBoxBorder"; + _DateTimeInput.BackgroundStyle.CornerType = eCornerType.Square; + } + + #endregion + + #region ButtonClear + + /// + /// Gets the object that describes the settings for the button + /// that clears the content of the control when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that clears the content of the control when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonClear + { + get { return (_DateTimeInput.ButtonClear); } + } + + #endregion + + #region ButtonCustom + + /// + /// Gets the object that describes the settings for the custom button + /// that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get { return (_DateTimeInput.ButtonCustom); } + } + + #endregion + + #region ButtonCustom2 + + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get { return (_DateTimeInput.ButtonCustom2); } + } + + #endregion + + #region ButtonDropDown + + /// + /// Gets the object that describes the settings for the button + /// that shows drop-down when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that shows drop-down when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonDropDown + { + get { return (_DateTimeInput.ButtonDropDown); } + } + + #endregion + + #region ButtonFreeText + + /// + /// Gets the object that describes the settings for the button + /// that switches the control into the free-text entry mode when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that switches the control into the free-text entry mode when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonFreeText + { + get { return (_DateTimeInput.ButtonFreeText); } + } + + #endregion + + #region CustomFormat + + /// + /// Gets or sets the custom date/time format string. + /// + [Browsable(true), DefaultValue("")] + [Description("Indicates the custom date/time format string. "), Localizable(true)] + public string CustomFormat + { + get { return (_DateTimeInput.CustomFormat); } + set { _DateTimeInput.CustomFormat = value; } + } + + #endregion + + #region DisplayControlForCurrentCellOnly + + /// + /// Gets or sets whether the control + /// will be displayed for the current cell only. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the control will be displayed for the current cell only.")] + public bool DisplayControlForCurrentCellOnly + { + get { return (_DisplayControlForCurrentCellOnly); } + + set + { + if (_DisplayControlForCurrentCellOnly != value) + { + _DisplayControlForCurrentCellOnly = value; + _DateTimeInput.Invalidate(); + } + } + } + + #endregion + + #region DefaultInputValues + + /// + /// Gets or sets whether empty input values (year, month or day) are + /// set to defaults while user is entering data. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether empty input values (year, month or day) are set to defaults while user is entering data")] + public bool DefaultInputValues + { + get { return (_DateTimeInput.DefaultInputValues); } + set { _DateTimeInput.DefaultInputValues = value; } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_DateTimeInput.Enabled); } + set { _DateTimeInput.Enabled = value; } + } + + #endregion + + #region Format + + /// + /// Gets or sets the format date/time is displayed in. To specify + /// custom format set this value to Custom and specify custom format + /// using CustomFormat property. + /// + [Browsable(true), DefaultValue(eDateTimePickerFormat.Short)] + [Description("Indicates the format date/time is displayed in. To specify custom format set this value to Custom and specify custom format using CustomFormat property.")] + public eDateTimePickerFormat Format + { + get { return (_DateTimeInput.Format); } + set { _DateTimeInput.Format = value; } + } + + #endregion + + #region InputHorizontalAlignment + + /// + /// Gets or sets the input field alignment inside the control + /// + [Browsable(true), DefaultValue(eHorizontalAlignment.Right), Category("Appearance")] + [Description("Indicates alignment of input fields inside of the control.")] + public eHorizontalAlignment InputHorizontalAlignment + { + get { return (_DateTimeInput.InputHorizontalAlignment); } + set { _DateTimeInput.InputHorizontalAlignment = value; } + } + + #endregion + + #region IsInputReadOnly + + /// + /// Gets or sets whether input part of the control is read-only. When set + /// to true the input part of the control becomes read-only and does not allow + /// the typing. However, drop-down part if visible still allows user to change + /// the value of the control. Use this property to allow change of the value + /// through drop-down picker only. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether input part of the control is read-only.")] + public bool IsInputReadOnly + { + get { return (_DateTimeInput.IsInputReadOnly); } + set { _DateTimeInput.IsInputReadOnly = value; } + } + + #endregion + + #region LockUpdateChecked + + /// + /// Gets or sets whether check box shown using ShowCheckBox + /// property which locks/unlocks the control update is checked. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether check box shown using ShowCheckBox property which locks/unlocks the control update is checked.")] + public bool LockUpdateChecked + { + get { return (_DateTimeInput.LockUpdateChecked); } + set { _DateTimeInput.LockUpdateChecked = value; } + } + + #endregion + + #region MaxDate + + /// + /// Gets or sets the maximum date and time that can be selected in the control. + /// + [Browsable(true)] + [Description("Indicates maximum date and time that can be selected in the control.")] + public DateTime MaxDate + { + get { return (_DateTimeInput.MaxDate); } + set { _DateTimeInput.MaxDate = value; } + } + + /// + /// Gets whether Value property should be serialized by Windows Forms designer. + /// + /// true if value serialized otherwise false. + public bool ShouldSerializeMaxDate() + { + return (MaxDate.Equals(DateTimeGroup.MaxDateTime) == false); + } + + #endregion + + #region MinDate + + /// + /// Gets or sets the minimum date and time that can be selected in the control. + /// + [Browsable(true)] + [Description("Indicates minimum date and time that can be selected in the control.")] + public DateTime MinDate + { + get { return (_DateTimeInput.MinDate); } + set { _DateTimeInput.MinDate = value; } + } + + /// + /// Gets whether Value property should be serialized by Windows Forms designer. + /// + /// true if value serialized otherwise false. + public bool ShouldSerializeMinDate() + { + return (MinDate.Equals(DateTimeGroup.MinDateTime) == false); + } + + #endregion + + #region MonthCalendar + + /// + /// Gets the reference to the internal MonthCalendarItem control which is used to display calendar when drop-down is open. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Description("Gets the reference to the internal MonthCalendarAdv control which is used to display calendar when drop-down is open.")] + public MonthCalendarItem MonthCalendar + { + get { return (_DateTimeInput.MonthCalendar); } + } + + #endregion + + #region SelectNextInputCharacters + + /// + /// List of characters that when pressed would select next input field. For example if you are + /// allowing time input you could set this property to : so when user presses the : character, + /// the input is forwarded to the next input field. + /// + [Browsable(true), DefaultValue(""), Category("Behavior")] + [Description("List of characters that when pressed would select next input field.")] + public string SelectNextInputCharacters + { + get { return (_DateTimeInput.SelectNextInputCharacters); } + set { _DateTimeInput.SelectNextInputCharacters = value; } + } + + #endregion + + #region ShowCheckBox + + /// + /// Gets or sets a value indicating whether a check box is + /// displayed to the left of the input value. Set to true if a check box + /// is displayed to the left of the input value; otherwise, false. The default is false. + /// + /// When the ShowCheckBox property is set to true, a check box is displayed + /// to the left of the input in the control. When the check box is selected, the value + /// can be updated. When the check box is cleared, the value is unable to be changed. + /// You can handle the LockUpdateChanged event to be notified when this check box is checked + /// and unchecked. Use LockUpdateChecked property to get or sets whether check box is checked. + /// + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether a check box is displayed to the left of the input value which allows locking of the control.")] + public bool ShowCheckBox + { + get { return (_DateTimeInput.ShowCheckBox); } + set { _DateTimeInput.ShowCheckBox = value; } + } + + #endregion + + #region ShowUpDown + + /// + /// Gets or sets a value indicating whether a spin button control + /// (up-down control) is used to adjust the current value. The default is false. + /// + /// When the ShowUpDown property is set to true, a spin button control + /// is shown to adjust value of currently focused input item. The value can + /// be adjusted by using the up and down buttons to change the value. + /// + /// + [Browsable(true), DefaultValue(false)] + public bool ShowUpDown + { + get { return (_DateTimeInput.ShowUpDown); } + set { _DateTimeInput.ShowUpDown = value; } + } + + #endregion + + #endregion + + #region Event processing + + #region DoButtonClearClick + + /// + /// DoButtonClearClick + /// + /// + /// + internal void DoButtonClearClick(object sender, CancelEventArgs e) + { + if (ButtonClearClick != null) + ButtonClearClick(this, e); + } + + #endregion + + #region DoButtonCustomClick + + /// + /// DoButtonCustomClick + /// + /// + /// + internal void DoButtonCustomClick(object sender, EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + #endregion + + #region DoButtonCustom2Click + + /// + /// DoButtonCustom2Click + /// + /// + /// + internal void DoButtonCustom2Click(object sender, EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + #endregion + + #region DoButtonDropDownClick + + /// + /// DoButtonDropDownClick + /// + /// + /// + internal void DoButtonDropDownClick(object sender, CancelEventArgs e) + { + if (ButtonDropDownClick != null) + ButtonDropDownClick(this, e); + } + + #endregion + + #region DoButtonFreeTextClick + + /// + /// DoButtonFreeTextClick + /// + /// + /// + internal void DoButtonFreeTextClick(object sender, CancelEventArgs e) + { + if (ButtonFreeTextClick != null) + ButtonFreeTextClick(this, e); + } + + #endregion + + #region DoConvertFreeTextEntry + + /// + /// DoConvertFreeTextEntry + /// + /// + /// + internal void DoConvertFreeTextEntry(object sender, FreeTextEntryConversionEventArgs e) + { + if (ConvertFreeTextEntry != null) + ConvertFreeTextEntry(this, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewDateTimeInputColumn dc = base.Clone() as DataGridViewDateTimeInputColumn; + + if (dc != null) + { + dc.AllowEmptyState = AllowEmptyState; + dc.AutoAdvance = AutoAdvance; + dc.AutoOverwrite = AutoOverwrite; + dc.AutoSelectDate = AutoSelectDate; + dc.CustomFormat = CustomFormat; + dc.DefaultInputValues = DefaultInputValues; + dc.Enabled = Enabled; + dc.Format = Format; + dc.InputHorizontalAlignment = InputHorizontalAlignment; + dc.IsInputReadOnly = IsInputReadOnly; + dc.LockUpdateChecked = LockUpdateChecked; + dc.MinDate = MinDate; + dc.MaxDate = MaxDate; + dc.SelectNextInputCharacters = SelectNextInputCharacters; + dc.ShowCheckBox = ShowCheckBox; + dc.ShowUpDown = ShowUpDown; + + dc.DisplayControlForCurrentCellOnly = DisplayControlForCurrentCellOnly; + + DateTimeInput.MonthCalendar.InternalCopyToItem(dc.DateTimeInput.MonthCalendar); + + dc.BackgroundStyle.ApplyStyle(DateTimeInput.BackgroundStyle); + dc.BackgroundStyle.Class = DateTimeInput.BackgroundStyle.Class; + + DateTimeInput.ButtonClear.CopyToItem(dc.DateTimeInput.ButtonClear); + DateTimeInput.ButtonDropDown.CopyToItem(dc.DateTimeInput.ButtonDropDown); + DateTimeInput.ButtonFreeText.CopyToItem(dc.DateTimeInput.ButtonFreeText); + DateTimeInput.ButtonCustom.CopyToItem(dc.DateTimeInput.ButtonCustom); + DateTimeInput.ButtonCustom2.CopyToItem(dc.DateTimeInput.ButtonCustom2); + } + + return (dc); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDateTimeInput/DataGridViewDateTimeInputEditingControl.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDateTimeInput/DataGridViewDateTimeInputEditingControl.cs new file mode 100644 index 00000000..3e61ea96 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDateTimeInput/DataGridViewDateTimeInputEditingControl.cs @@ -0,0 +1,218 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.Editors.DateTimeAdv; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), ComVisible(false)] + public class DataGridViewDateTimeInputEditingControl : DateTimeInput, IDataGridViewEditingControl + { + #region Private variables + + private DataGridView _DataGridView; + + private int _RowIndex; + private bool _ValueChanged; + private bool _EditCancelled; + + #endregion + + #region OnValueChanged + + /// + /// Handles OnValueChanged events + /// + /// + protected override void OnValueChanged(EventArgs e) + { + _ValueChanged = true; + + _DataGridView.NotifyCurrentCellDirty(true); + + base.OnValueChanged(e); + } + + #endregion + + #region Internal properties + + /// + /// Gets or sets the Edit state + /// + internal bool EditCancelled + { + get { return (_EditCancelled); } + set { _EditCancelled = value; } + } + + #endregion + + #region IDataGridViewEditingControl Members + + #region Public properties + + #region EditingControlDataGridView + + /// + /// Gets or sets the DataGridView + /// + public DataGridView EditingControlDataGridView + { + get { return (_DataGridView); } + set { _DataGridView = value; } + } + + #endregion + + #region EditingControlFormattedValue + + /// + /// Gets or sets the Control Formatted Value + /// + public object EditingControlFormattedValue + { + get + { + DateTime date = Value; + + if (date.Equals(DateTime.MinValue)) + return (String.Empty); + + return (this.Value.ToString()); + } + + set + { + string newValue = value as string; + + if (newValue != null) + Value = DateTime.Parse(newValue); + } + } + + #endregion + + #region EditingControlRowIndex + + /// + /// Gets or sets the Control RoeIndex + /// + public int EditingControlRowIndex + { + get { return (_RowIndex); } + set { _RowIndex = value; } + } + + #endregion + + #region EditingControlValueChanged + + /// + /// Gets or sets the Control ValueChanged state + /// + public bool EditingControlValueChanged + { + get { return (_ValueChanged); } + set { _ValueChanged = value; } + } + + #endregion + + #region EditingPanelCursor + + /// + /// Gets the Panel Cursor + /// + public Cursor EditingPanelCursor + { + get { return (base.Cursor); } + } + + #endregion + + #region RepositionEditingControlOnValueChange + + /// + /// Gets whether to RepositionEditingControlOnValueChange + /// + public bool RepositionEditingControlOnValueChange + { + get { return (false); } + } + + #endregion + + #endregion + + #region ApplyCellStyleToEditingControl + + /// + /// ApplyCellStyleToEditingControl + /// + /// + public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) + { + Font = dataGridViewCellStyle.Font; + + ForeColor = dataGridViewCellStyle.ForeColor; + BackColor = dataGridViewCellStyle.BackColor; + } + + #endregion + + #region GetEditingControlFormattedValue + + /// + /// Gets EditingControlFormattedValue + /// + /// + /// + public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) + { + return (EditingControlFormattedValue); + } + + #endregion + + #region EditingControlWantsInputKey + + /// + /// Gets whether the given key wants to be processed + /// by the Control + /// + /// + /// + /// + public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) + { + if ((keyData & Keys.Right) == Keys.Right) + return (true); + + if ((keyData & Keys.Left) == Keys.Left) + return (true); + + if ((keyData & Keys.Escape) == Keys.Escape) + _EditCancelled = true; + + return (dataGridViewWantsInputKey == false); + } + + #endregion + + #region PrepareEditingControlForEdit + + /// + /// PrepareEditingControlForEdit + /// + /// + public void PrepareEditingControlForEdit(bool selectAll) + { + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDoubleInput/DataGridViewDoubleInputCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDoubleInput/DataGridViewDoubleInputCell.cs new file mode 100644 index 00000000..5a562188 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDoubleInput/DataGridViewDoubleInputCell.cs @@ -0,0 +1,730 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Media; +using System.Windows.Forms; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewDoubleInputCell : DataGridViewTextBoxCell + { + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (typeof(DataGridViewDoubleInputEditingControl)); } + } + + #endregion + + #region FormattedValueType + + /// + /// FormattedValueType + /// + public override Type FormattedValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region ValueType + + public override Type ValueType + { + get { return (typeof(double)); } + } + + #endregion + + #endregion + + #region InitializeEditingControl + + /// + /// InitializeEditingControl + /// + /// + /// + /// + public override void InitializeEditingControl(int rowIndex, + object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) + { + DetachEditingControl(); + + base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); + + DataGridViewDoubleInputEditingControl ctl = + (DataGridViewDoubleInputEditingControl)DataGridView.EditingControl; + + DataGridViewDoubleInputColumn oc = OwningColumn as DataGridViewDoubleInputColumn; + + if (oc != null) + { + DoubleInput di = oc.DoubleInput; + + ctl.Value = GetValue(di.Value); + + ctl.DisplayFormat = di.DisplayFormat; + ctl.Enabled = di.Enabled; + ctl.Increment = di.Increment; + ctl.LockUpdateChecked = di.LockUpdateChecked; + ctl.MaxValue = di.MaxValue; + ctl.MinValue = di.MinValue; + ctl.ShowCheckBox = di.ShowCheckBox; + ctl.ShowUpDown = di.ShowUpDown; + + ctl.BackgroundStyle.ApplyStyle(di.BackgroundStyle); + ctl.BackgroundStyle.Class = di.BackgroundStyle.Class; + + ctl.InputHorizontalAlignment = GetHorizontalAlignment(dataGridViewCellStyle.Alignment); + + di.ButtonClear.CopyToItem(ctl.ButtonClear); + di.ButtonCustom.CopyToItem(ctl.ButtonCustom); + di.ButtonCustom2.CopyToItem(ctl.ButtonCustom2); + di.ButtonDropDown.CopyToItem(ctl.ButtonDropDown); + di.ButtonFreeText.CopyToItem(ctl.ButtonFreeText); + + ctl.ButtonClearClick += ButtonClearClick; + ctl.ButtonCustomClick += ButtonCustomClick; + ctl.ButtonCustom2Click += ButtonCustom2Click; + ctl.ButtonDropDownClick += ButtonDropDownClick; + ctl.ButtonFreeTextClick += ButtonFreeTextClick; + ctl.ConvertFreeTextEntry += ConvertFreeTextEntry; + + ctl.EditCancelled = false; + } + } + + #endregion + + #region DetachEditingControl + + /// + /// DetachEditingControl + /// + public override void DetachEditingControl() + { + if (DataGridView != null && DataGridView.EditingControl != null) + { + DataGridViewDoubleInputEditingControl di = + DataGridView.EditingControl as DataGridViewDoubleInputEditingControl; + + if (di != null) + { + di.ButtonClearClick -= ButtonClearClick; + di.ButtonDropDownClick -= ButtonDropDownClick; + di.ButtonFreeTextClick -= ButtonFreeTextClick; + di.ButtonCustomClick -= ButtonCustomClick; + di.ButtonCustom2Click -= ButtonCustom2Click; + di.ConvertFreeTextEntry -= ConvertFreeTextEntry; + + if (di.EditCancelled == true) + { + di.EditCancelled = false; + + SystemSounds.Beep.Play(); + } + } + } + + base.DetachEditingControl(); + } + + #endregion + + #region Event processing + + #region ButtonClearClick + + /// + /// ButtonClearClick + /// + /// + /// + void ButtonClearClick(object sender, CancelEventArgs e) + { + ((DataGridViewDoubleInputColumn)OwningColumn).DoButtonClearClick(sender, e); + } + + #endregion + + #region ButtonCustomClick + + /// + /// ButtonCustomClick + /// + /// + /// + void ButtonCustomClick(object sender, EventArgs e) + { + ((DataGridViewDoubleInputColumn)OwningColumn).DoButtonCustomClick(sender, e); + } + + #endregion + + #region ButtonCustom2Click + + /// + /// ButtonCustom2Click + /// + /// + /// + void ButtonCustom2Click(object sender, EventArgs e) + { + ((DataGridViewDoubleInputColumn)OwningColumn).DoButtonCustom2Click(sender, e); + } + + #endregion + + #region ButtonDropDownClick + + /// + /// ButtonDropDownClick + /// + /// + /// + void ButtonDropDownClick(object sender, CancelEventArgs e) + { + ((DataGridViewDoubleInputColumn)OwningColumn).DoButtonDropDownClick(sender, e); + } + + #endregion + + #region ButtonFreeTextClick + + /// + /// ButtonFreeTextClick + /// + /// + /// + void ButtonFreeTextClick(object sender, CancelEventArgs e) + { + ((DataGridViewDoubleInputColumn)OwningColumn).DoButtonFreeTextClick(sender, e); + } + + #endregion + + #region ConvertFreeTextEntry + + /// + /// ConvertFreeTextEntry + /// + /// + /// + void ConvertFreeTextEntry(object sender, FreeTextEntryConversionEventArgs e) + { + ((DataGridViewDoubleInputColumn)OwningColumn).DoConvertFreeTextEntry(sender, e); + } + + #endregion + + #endregion + + #region PositionEditingControl + + /// + /// PositionEditingControl + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public override void PositionEditingControl(bool setLocation, bool setSize, Rectangle cellBounds, + Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, + bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) + { + Rectangle editingControlBounds = + PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, + singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow); + + editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle); + + DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y); + DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height); + } + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetCellBounds(editingControlBounds); + + if (cellStyle != null && r.Height < editingControlBounds.Height) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.MiddleLeft: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height) / 2; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + editingControlBounds.Width = Math.Max(1, editingControlBounds.Width); + editingControlBounds.Height = Math.Max(1, r.Height); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + #region GetPreferredSize + + /// + /// GetPreferredSize + /// + /// + /// + /// + /// + /// + protected override Size GetPreferredSize(Graphics graphics, + DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + { + if (DataGridView == null) + return (new Size(-1, -1)); + + Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize); + + DataGridViewDoubleInputColumn oc = OwningColumn as DataGridViewDoubleInputColumn; + + if (oc != null) + { + DoubleInput di = oc.DoubleInput; + + preferredSize.Height = di.Height; + + if (constraintSize.Width == 0) + { + preferredSize.Width += GetImageWidth(di.ButtonClear); + preferredSize.Width += GetImageWidth(di.ButtonCustom); + preferredSize.Width += GetImageWidth(di.ButtonCustom2); + preferredSize.Width += GetImageWidth(di.ButtonDropDown); + preferredSize.Width += GetImageWidth(di.ButtonFreeText); + + if (di.ShowUpDown == true) + preferredSize.Width += 16; + + if (di.ShowCheckBox == true) + preferredSize.Width += 16; + } + } + + return (preferredSize); + } + + #endregion + + #region GetFormattedValue + + protected override object GetFormattedValue(object value, int rowIndex, + ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, + TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) + { + DataGridViewDoubleInputColumn oc = OwningColumn as DataGridViewDoubleInputColumn; + + if (oc != null) + { + DoubleInput di = oc.DoubleInput; + di.Value = GetValue(value); + + return (di.Text); + } + + return (base.GetFormattedValue(value, rowIndex, + ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context)); + } + + #endregion + + #region GetImageWidth + + private int GetImageWidth(InputButtonSettings ibs) + { + if (ibs.Visible == true) + return (ibs.Image != null ? ibs.Image.Width : 16); + + return (0); + } + + #endregion + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, + DataGridViewElementStates elementState, object value, object formattedValue, + string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, + DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewDoubleInputColumn oc = (DataGridViewDoubleInputColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintCellBackground(g, cellStyle, rBk); + PaintCellContent(g, cellBounds, rowIndex, value, cellStyle, paintParts); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintCellBackground + + /// + /// Paints the cell background + /// + /// + /// + /// + private void PaintCellBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintCellContent + + /// + /// Paints the cell content + /// + /// + /// + /// + /// + /// + /// + private void PaintCellContent(Graphics g, Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts) + { + DataGridViewDoubleInputColumn oc = (DataGridViewDoubleInputColumn)OwningColumn; + DoubleInput di = oc.DoubleInput; + + Point ptCurrentCell = DataGridView.CurrentCellAddress; + bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex; + bool cellEdited = cellCurrent && DataGridView.EditingControl != null; + + // If the cell is in editing mode, there is nothing else to paint + + if (cellEdited == false && rowIndex < DataGridView.RowCount) + { + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + { + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + di.Font = cellStyle.Font; + di.ForeColor = cellStyle.ForeColor; + di.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + + di.BackgroundStyle.TextColor = cellStyle.ForeColor; + di.BackgroundStyle.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + + di.InputHorizontalAlignment = GetHorizontalAlignment(cellStyle.Alignment); + + di.Value = GetValue(value); + + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + + if (oc.DisplayControlForCurrentCellOnly == false) + DrawControl(di, r, g); + else + DrawText(di, r, g); + } + } + } + + #region DrawControl + + /// + /// DrawControl + /// + /// + /// + /// + private void DrawControl(DoubleInput di, Rectangle r, Graphics g) + { + GraphicsState gs = g.Save(); + + try + { + g.TranslateTransform(r.X, r.Y); + + di.Width = r.Width; + di.InternalPaint(new PaintEventArgs(g, Rectangle.Empty)); + } + finally + { + g.Restore(gs); + } + } + + #endregion + + #region DrawText + + /// + /// DrawText + /// + /// + /// + /// + private void DrawText(DoubleInput di, Rectangle r, Graphics g) + { + r.Inflate(-2, 0); + + eTextFormat tf = eTextFormat.VerticalCenter; + + switch (di.InputHorizontalAlignment) + { + case eHorizontalAlignment.Center: + tf |= eTextFormat.HorizontalCenter; + break; + + case eHorizontalAlignment.Right: + tf |= eTextFormat.Right; + break; + } + + TextDrawing.DrawString(g, di.Text, di.Font, di.ForeColor, r, tf); + } + + #endregion + + #endregion + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewDoubleInputColumn oc = (DataGridViewDoubleInputColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetCellBounds + + /// + /// Gets the button bounds for the given cell + /// + /// + /// + private Rectangle GetCellBounds(Rectangle cellBounds) + { + DataGridViewDoubleInputColumn oc = (DataGridViewDoubleInputColumn)OwningColumn; + + Size size = oc.DoubleInput.Size; + + cellBounds.Location = new Point(1, 1); + + cellBounds.Width = Math.Min(size.Width, cellBounds.Width); + cellBounds.Width -= oc.DividerWidth; + cellBounds.Height = size.Height; + + return (cellBounds); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + private double GetValue(object value) + { + if (value == Convert.DBNull || + (value is string && String.IsNullOrEmpty((string)value) == true)) + { + return (0); + } + if (value is string) + { + string svalue = value.ToString(); + return Convert.ToDouble(svalue.Replace(" ", "")); + } + return (Convert.ToDouble(value)); + } + + #endregion + + #region GetHorizontalAlignment + + /// + /// GetHorizontalAlignment + /// + /// + /// + private eHorizontalAlignment GetHorizontalAlignment(DataGridViewContentAlignment alignment) + { + switch (alignment) + { + case DataGridViewContentAlignment.TopCenter: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.BottomCenter: + return (eHorizontalAlignment.Center); + + case DataGridViewContentAlignment.TopRight: + case DataGridViewContentAlignment.MiddleRight: + case DataGridViewContentAlignment.BottomRight: + return (eHorizontalAlignment.Right); + + default: + return (eHorizontalAlignment.Left); + } + } + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDoubleInput/DataGridViewDoubleInputColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDoubleInput/DataGridViewDoubleInputColumn.cs new file mode 100644 index 00000000..0aa6d49b --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDoubleInput/DataGridViewDoubleInputColumn.cs @@ -0,0 +1,597 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewButtonXColumn), "DoubleInput.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewDoubleInputColumn : DataGridViewTextBoxColumn, IDataGridViewColumn + { + #region Events + + /// + /// Occurs right before a DoubleInput Cell is painted + /// + [Description("Occurs right before a DoubleInput Cell is painted.")] + public event EventHandler BeforeCellPaint; + + /// + /// Occurs when Clear button is clicked and allows you + /// to cancel the default action performed by the button + /// + [Description("Occurs when Clear button is clicked and allows you to cancel the default action performed by the button.")] + public event EventHandler ButtonClearClick; + + /// + /// Occurs when ButtonCustom control is clicked + /// + [Description("Occurs when ButtonCustom control is clicked.")] + public event EventHandler ButtonCustomClick; + + /// + /// Occurs when ButtonCustom2 control is clicked + /// + [Description("Occurs when ButtonCustom2 control is clicked.")] + public event EventHandler ButtonCustom2Click; + + /// + /// Occurs when Drop-Down button that shows calendar + /// is clicked and allows you to cancel showing of the popup + /// + [Description("Occurs when Drop-Down button that shows calendar is clicked and allows you to cancel showing of the popup.")] + public event EventHandler ButtonDropDownClick; + + /// + /// Occurs when Free-Text button is clicked + /// and allows you to cancel its default action + /// + [Description("Occurs when Free-Text button is clicked and allows you to cancel its default action.")] + public event EventHandler ButtonFreeTextClick; + + /// + /// Occurs if Free-Text entry value is not natively recognized by + /// the control and provides you with opportunity to convert that + /// value to the value the control expects + /// + [Description("Occurs if Free-Text entry value is not natively recognized by the control and provides you with opportunity to convert that value to the value the control expects.")] + public event EventHandler ConvertFreeTextEntry; + + #endregion + + #region Private variables + + private DoubleInput _DoubleInput; + private Bitmap _CellBitmap; + private bool _DisplayControlForCurrentCellOnly = true; + + #endregion + + /// + /// Constructor + /// + public DataGridViewDoubleInputColumn() + { + CellTemplate = new DataGridViewDoubleInputCell(); + + _DoubleInput = new DoubleInput(); + + _DoubleInput.BackgroundStyle.Class = ElementStyleClassKeys.DataGridViewNumericBorderKey; + _DoubleInput.Visible = false; + } + + #region Internal properties + + #region DoubleInput + + /// + /// DoubleInput + /// + internal DoubleInput DoubleInput + { + get { return (_DoubleInput); } + } + + #endregion + + #endregion + + #region Public properties + + #region BackgroundStyle + + /// + /// Specifies the background style of the control. + /// + [Browsable(true), Category("Style")] + [Description("Gets or sets control background style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return (_DoubleInput.BackgroundStyle); } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _DoubleInput.ResetBackgroundStyle(); + + _DoubleInput.BackgroundStyle.Class = "TextBoxBorder"; + _DoubleInput.BackgroundStyle.CornerType = eCornerType.Square; + } + + #endregion + + #region ButtonClear + + /// + /// Gets the object that describes the settings for the button + /// that clears the content of the control when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that clears the content of the control when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonClear + { + get { return (_DoubleInput.ButtonClear); } + } + + #endregion + + #region ButtonCustom + + /// + /// Gets the object that describes the settings for the custom button + /// that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get { return (_DoubleInput.ButtonCustom); } + } + + #endregion + + #region ButtonCustom2 + + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get { return (_DoubleInput.ButtonCustom2); } + } + + #endregion + + #region ButtonDropDown + + /// + /// Gets the object that describes the settings for the button + /// that shows drop-down when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that shows drop-down when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonDropDown + { + get { return (_DoubleInput.ButtonDropDown); } + } + + #endregion + + #region ButtonFreeText + + /// + /// Gets the object that describes the settings for the button + /// that switches the control into the free-text entry mode when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that switches the control into the free-text entry mode when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonFreeText + { + get { return (_DoubleInput.ButtonFreeText); } + } + + #endregion + + #region DisplayFormat + + /// + /// Gets or sets the Numeric String Format that is used to format + /// the numeric value entered for display purpose. Read more about + /// available formats in MSDN under "Standard Numeric Format Strings" + /// and "Custom Numeric Format Strings" topics. + /// + /// The format specified here indicates the format for display purpose + /// only, not for the input purpose. For example to display the number + /// in system Currency format set the DisplayFormat to 'C'. + /// + /// + [Browsable(true), DefaultValue("")] + [Description("Indicates Numeric String Format that is used to format the numeric value entered for display purpose.")] + public string DisplayFormat + { + get { return (_DoubleInput.DisplayFormat); } + set { _DoubleInput.DisplayFormat = value; } + } + + #endregion + + #region DisplayControlForCurrentCellOnly + + /// + /// Gets or sets whether the control + /// will be displayed for the current cell only. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the control will be displayed for the current cell only.")] + public bool DisplayControlForCurrentCellOnly + { + get { return (_DisplayControlForCurrentCellOnly); } + + set + { + if (_DisplayControlForCurrentCellOnly != value) + { + _DisplayControlForCurrentCellOnly = value; + _DoubleInput.Invalidate(); + } + } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_DoubleInput.Enabled); } + set { _DoubleInput.Enabled = value; } + } + + #endregion + + #region Increment + + /// + /// Gets or sets the value to increment or decrement the value of the + /// control when the up or down buttons are clicked. + /// + [Browsable(true), DefaultValue(1)] + [Description("Indicates value to increment or decrement the value of the control when the up or down buttons are clicked. ")] + public double Increment + { + get { return (_DoubleInput.Increment); } + set { _DoubleInput.Increment = value; } + } + + #endregion + + #region InputHorizontalAlignment + + /// + /// Gets or sets the input field alignment inside the control + /// + [Browsable(true), DefaultValue(eHorizontalAlignment.Right), Category("Appearance")] + [Description("Indicates alignment of input fields inside of the control.")] + public eHorizontalAlignment InputHorizontalAlignment + { + get { return (_DoubleInput.InputHorizontalAlignment); } + set { _DoubleInput.InputHorizontalAlignment = value; } + } + + #endregion + + #region LockUpdateChecked + + /// + /// Gets or sets whether check box shown using ShowCheckBox + /// property which locks/unlocks the control update is checked. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether check box shown using ShowCheckBox property which locks/unlocks the control update is checked.")] + public bool LockUpdateChecked + { + get { return (_DoubleInput.LockUpdateChecked); } + set { _DoubleInput.LockUpdateChecked = value; } + } + + #endregion + + #region MaxValue + + /// + /// Gets or sets the maximum value that can be entered. + /// + [Browsable(true), DefaultValue(double.MaxValue)] + [Description("Indicates maximum value that can be entered.")] + public double MaxValue + { + get { return (_DoubleInput.MaxValue); } + set { _DoubleInput.MaxValue = value; } + } + + #endregion + + #region MinValue + + /// + /// Gets or sets the minimum value that can be entered. + /// + [Browsable(true), DefaultValue(double.MinValue)] + [Description("Indicates minimum value that can be entered.")] + public double MinValue + { + get { return (_DoubleInput.MinValue); } + set { _DoubleInput.MinValue = value; } + } + + #endregion + + #region ShowCheckBox + + /// + /// Gets or sets a value indicating whether a check box is + /// displayed to the left of the input value. Set to true if a check box + /// is displayed to the left of the input value; otherwise, false. The default is false. + /// + /// When the ShowCheckBox property is set to true, a check box is displayed + /// to the left of the input in the control. When the check box is selected, the value + /// can be updated. When the check box is cleared, the value is unable to be changed. + /// You can handle the LockUpdateChanged event to be notified when this check box is checked + /// and unchecked. Use LockUpdateChecked property to get or sets whether check box is checked. + /// + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether a check box is displayed to the left of the input value which allows locking of the control.")] + public bool ShowCheckBox + { + get { return (_DoubleInput.ShowCheckBox); } + set { _DoubleInput.ShowCheckBox = value; } + } + + #endregion + + #region ShowUpDown + + /// + /// Gets or sets a value indicating whether a spin button control + /// (up-down control) is used to adjust the current value. The default is false. + /// + /// When the ShowUpDown property is set to true, a spin button control + /// is shown to adjust value of currently focused input item. The value can + /// be adjusted by using the up and down buttons to change the value. + /// + /// + [Browsable(true), DefaultValue(false)] + public bool ShowUpDown + { + get { return (_DoubleInput.ShowUpDown); } + set { _DoubleInput.ShowUpDown = value; } + } + + #endregion + + #endregion + + #region Event processing + + #region DoButtonClearClick + + /// + /// DoButtonClearClick + /// + /// + /// + internal void DoButtonClearClick(object sender, CancelEventArgs e) + { + if (ButtonClearClick != null) + ButtonClearClick(this, e); + } + + #endregion + + #region DoButtonCustomClick + + /// + /// DoButtonCustomClick + /// + /// + /// + internal void DoButtonCustomClick(object sender, EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + #endregion + + #region DoButtonCustom2Click + + /// + /// DoButtonCustom2Click + /// + /// + /// + internal void DoButtonCustom2Click(object sender, EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + #endregion + + #region DoButtonDropDownClick + + /// + /// DoButtonDropDownClick + /// + /// + /// + internal void DoButtonDropDownClick(object sender, CancelEventArgs e) + { + if (ButtonDropDownClick != null) + ButtonDropDownClick(this, e); + } + + #endregion + + #region DoButtonFreeTextClick + + /// + /// DoButtonFreeTextClick + /// + /// + /// + internal void DoButtonFreeTextClick(object sender, CancelEventArgs e) + { + if (ButtonFreeTextClick != null) + ButtonFreeTextClick(this, e); + } + + #endregion + + #region DoConvertFreeTextEntry + + /// + /// DoConvertFreeTextEntry + /// + /// + /// + internal void DoConvertFreeTextEntry(object sender, FreeTextEntryConversionEventArgs e) + { + if (ConvertFreeTextEntry != null) + ConvertFreeTextEntry(this, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewDoubleInputColumn dc = base.Clone() as DataGridViewDoubleInputColumn; + + if (dc != null) + { + dc.DisplayFormat = DisplayFormat; + dc.Enabled = Enabled; + dc.Increment = Increment; + dc.InputHorizontalAlignment = InputHorizontalAlignment; + dc.LockUpdateChecked = LockUpdateChecked; + dc.MaxValue = MaxValue; + dc.MinValue = MinValue; + dc.ShowCheckBox = ShowCheckBox; + dc.ShowUpDown = ShowUpDown; + + dc.DisplayControlForCurrentCellOnly = DisplayControlForCurrentCellOnly; + + dc.BackgroundStyle.ApplyStyle(DoubleInput.BackgroundStyle); + dc.BackgroundStyle.Class = DoubleInput.BackgroundStyle.Class; + + DoubleInput.ButtonClear.CopyToItem(dc.DoubleInput.ButtonClear); + DoubleInput.ButtonDropDown.CopyToItem(dc.DoubleInput.ButtonDropDown); + DoubleInput.ButtonFreeText.CopyToItem(dc.DoubleInput.ButtonFreeText); + DoubleInput.ButtonCustom.CopyToItem(dc.DoubleInput.ButtonCustom); + DoubleInput.ButtonCustom2.CopyToItem(dc.DoubleInput.ButtonCustom2); + } + + return (dc); + } + + #endregion + + #region Dispose + + protected override void Dispose(bool disposing) + { + if (disposing == true) + _DoubleInput.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDoubleInput/DataGridViewDoubleInputEditingControl.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDoubleInput/DataGridViewDoubleInputEditingControl.cs new file mode 100644 index 00000000..69c1015f --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewDoubleInput/DataGridViewDoubleInputEditingControl.cs @@ -0,0 +1,211 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), ComVisible(false)] + public class DataGridViewDoubleInputEditingControl : DoubleInput, IDataGridViewEditingControl + { + #region Private variables + + private DataGridView _DataGridView; + + private int _RowIndex; + private bool _ValueChanged; + private bool _EditCancelled; + + #endregion + + #region OnValueChanged + + /// + /// Handles OnValueChanged events + /// + /// + protected override void OnValueChanged(EventArgs e) + { + _ValueChanged = true; + + _DataGridView.NotifyCurrentCellDirty(true); + + base.OnValueChanged(e); + } + + #endregion + + #region Internal properties + + /// + /// Gets or sets the Edit state + /// + internal bool EditCancelled + { + get { return (_EditCancelled); } + set { _EditCancelled = value; } + } + + #endregion + + #region IDataGridViewEditingControl Members + + #region Public properties + + #region EditingControlDataGridView + + /// + /// Gets or sets the DataGridView + /// + public DataGridView EditingControlDataGridView + { + get { return (_DataGridView); } + set {_DataGridView = value; } + } + + #endregion + + #region EditingControlFormattedValue + + /// + /// Gets or sets the Control Formatted Value + /// + public object EditingControlFormattedValue + { + get { return (Value.ToString()); } + + set + { + string newValue = value as string; + + if (newValue != null) + Value = int.Parse(newValue); + } + } + + #endregion + + #region EditingControlRowIndex + + /// + /// Gets or sets the Control RoeIndex + /// + public int EditingControlRowIndex + { + get { return (_RowIndex); } + set { _RowIndex = value; } + } + + #endregion + + #region EditingControlValueChanged + + /// + /// Gets or sets the Control ValueChanged state + /// + public bool EditingControlValueChanged + { + get { return (_ValueChanged); } + set { _ValueChanged = value; } + } + + #endregion + + #region EditingPanelCursor + + /// + /// Gets the Panel Cursor + /// + public Cursor EditingPanelCursor + { + get { return (base.Cursor); } + } + + #endregion + + #region RepositionEditingControlOnValueChange + + /// + /// Gets whether to RepositionEditingControlOnValueChange + /// + public bool RepositionEditingControlOnValueChange + { + get { return (false); } + } + + #endregion + + #endregion + + #region ApplyCellStyleToEditingControl + + /// + /// ApplyCellStyleToEditingControl + /// + /// + public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) + { + Font = dataGridViewCellStyle.Font; + + ForeColor = dataGridViewCellStyle.ForeColor; + BackColor = dataGridViewCellStyle.BackColor; + } + + #endregion + + #region GetEditingControlFormattedValue + + /// + /// Gets EditingControlFormattedValue + /// + /// + /// + public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) + { + return (EditingControlFormattedValue); + } + + #endregion + + #region EditingControlWantsInputKey + + /// + /// Gets whether the given key wants to be processed + /// by the Control + /// + /// + /// + /// + public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) + { + if ((keyData & Keys.Right) == Keys.Right) + return (true); + + if ((keyData & Keys.Left) == Keys.Left) + return (true); + + if ((keyData & Keys.Escape) == Keys.Escape) + _EditCancelled = true; + + return (dataGridViewWantsInputKey == false); + } + + #endregion + + #region PrepareEditingControlForEdit + + /// + /// PrepareEditingControlForEdit + /// + /// + public void PrepareEditingControlForEdit(bool selectAll) + { + } + + #endregion + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIntegerInput/DataGridViewIntegerInputCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIntegerInput/DataGridViewIntegerInputCell.cs new file mode 100644 index 00000000..0901f033 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIntegerInput/DataGridViewIntegerInputCell.cs @@ -0,0 +1,724 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Media; +using System.Windows.Forms; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewIntegerInputCell : DataGridViewTextBoxCell + { + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (typeof(DataGridViewIntegerInputEditingControl)); } + } + + #endregion + + #region FormattedValueType + + /// + /// FormattedValueType + /// + public override Type FormattedValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region ValueType + + public override Type ValueType + { + get { return (typeof(int)); } + } + + #endregion + + #endregion + + #region InitializeEditingControl + + /// + /// InitializeEditingControl + /// + /// + /// + /// + public override void InitializeEditingControl(int rowIndex, + object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) + { + DetachEditingControl(); + + base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); + + DataGridViewIntegerInputEditingControl ctl = + (DataGridViewIntegerInputEditingControl)DataGridView.EditingControl; + + DataGridViewIntegerInputColumn oc = OwningColumn as DataGridViewIntegerInputColumn; + + if (oc != null) + { + IntegerInput di = oc.IntegerInput; + + ctl.Value = GetValue(DataGridView[OwningColumn.Index, rowIndex].Value); + + ctl.DisplayFormat = di.DisplayFormat; + ctl.Enabled = di.Enabled; + ctl.Increment = di.Increment; + ctl.InputHorizontalAlignment = GetHorizontalAlignment(dataGridViewCellStyle.Alignment); + ctl.LockUpdateChecked = di.LockUpdateChecked; + ctl.MaxValue = di.MaxValue; + ctl.MinValue = di.MinValue; + ctl.ShowCheckBox = di.ShowCheckBox; + ctl.ShowUpDown = di.ShowUpDown; + + ctl.BackgroundStyle.ApplyStyle(di.BackgroundStyle); + ctl.BackgroundStyle.Class = di.BackgroundStyle.Class; + + di.ButtonClear.CopyToItem(ctl.ButtonClear); + di.ButtonCustom.CopyToItem(ctl.ButtonCustom); + di.ButtonCustom2.CopyToItem(ctl.ButtonCustom2); + di.ButtonDropDown.CopyToItem(ctl.ButtonDropDown); + di.ButtonFreeText.CopyToItem(ctl.ButtonFreeText); + + ctl.ButtonClearClick += ButtonClearClick; + ctl.ButtonCustomClick += ButtonCustomClick; + ctl.ButtonCustom2Click += ButtonCustom2Click; + ctl.ButtonDropDownClick += ButtonDropDownClick; + ctl.ButtonFreeTextClick += ButtonFreeTextClick; + ctl.ConvertFreeTextEntry += ConvertFreeTextEntry; + + ctl.EditCancelled = false; + } + } + + #endregion + + #region DetachEditingControl + + /// + /// DetachEditingControl + /// + public override void DetachEditingControl() + { + if (DataGridView != null && DataGridView.EditingControl != null) + { + DataGridViewIntegerInputEditingControl di = + DataGridView.EditingControl as DataGridViewIntegerInputEditingControl; + + if (di != null) + { + di.ButtonClearClick -= ButtonClearClick; + di.ButtonDropDownClick -= ButtonDropDownClick; + di.ButtonFreeTextClick -= ButtonFreeTextClick; + di.ButtonCustomClick -= ButtonCustomClick; + di.ButtonCustom2Click -= ButtonCustom2Click; + di.ConvertFreeTextEntry -= ConvertFreeTextEntry; + + if (di.EditCancelled == true) + { + di.EditCancelled = false; + + SystemSounds.Beep.Play(); + } + } + } + + base.DetachEditingControl(); + } + + #endregion + + #region Event processing + + #region ButtonClearClick + + /// + /// ButtonClearClick + /// + /// + /// + void ButtonClearClick(object sender, CancelEventArgs e) + { + ((DataGridViewIntegerInputColumn)OwningColumn).DoButtonClearClick(sender, e); + } + + #endregion + + #region ButtonCustomClick + + /// + /// ButtonCustomClick + /// + /// + /// + void ButtonCustomClick(object sender, EventArgs e) + { + ((DataGridViewIntegerInputColumn)OwningColumn).DoButtonCustomClick(sender, e); + } + + #endregion + + #region ButtonCustom2Click + + /// + /// ButtonCustom2Click + /// + /// + /// + void ButtonCustom2Click(object sender, EventArgs e) + { + ((DataGridViewIntegerInputColumn)OwningColumn).DoButtonCustom2Click(sender, e); + } + + #endregion + + #region ButtonDropDownClick + + /// + /// ButtonDropDownClick + /// + /// + /// + void ButtonDropDownClick(object sender, CancelEventArgs e) + { + ((DataGridViewIntegerInputColumn)OwningColumn).DoButtonDropDownClick(sender, e); + } + + #endregion + + #region ButtonFreeTextClick + + /// + /// ButtonFreeTextClick + /// + /// + /// + void ButtonFreeTextClick(object sender, CancelEventArgs e) + { + ((DataGridViewIntegerInputColumn)OwningColumn).DoButtonFreeTextClick(sender, e); + } + + #endregion + + #region ConvertFreeTextEntry + + /// + /// ConvertFreeTextEntry + /// + /// + /// + void ConvertFreeTextEntry(object sender, FreeTextEntryConversionEventArgs e) + { + ((DataGridViewIntegerInputColumn)OwningColumn).DoConvertFreeTextEntry(sender, e); + } + + #endregion + + #endregion + + #region PositionEditingControl + + /// + /// PositionEditingControl + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public override void PositionEditingControl(bool setLocation, bool setSize, Rectangle cellBounds, + Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, + bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) + { + Rectangle editingControlBounds = + PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, + singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow); + + editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle); + + DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y); + DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height); + } + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetCellBounds(editingControlBounds); + + if (r.Height < editingControlBounds.Height) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.MiddleLeft: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height) / 2; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + editingControlBounds.Width = Math.Max(1, editingControlBounds.Width); + editingControlBounds.Height = Math.Max(1, r.Height); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + #region GetPreferredSize + + /// + /// GetPreferredSize + /// + /// + /// + /// + /// + /// + protected override Size GetPreferredSize(Graphics graphics, + DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + { + if (DataGridView == null) + return (new Size(-1, -1)); + + Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize); + + DataGridViewIntegerInputColumn oc = OwningColumn as DataGridViewIntegerInputColumn; + + if (oc != null) + { + IntegerInput ip = oc.IntegerInput; + + preferredSize.Height = ip.Height; + + if (constraintSize.Width == 0) + { + preferredSize.Width += GetImageWidth(ip.ButtonClear); + preferredSize.Width += GetImageWidth(ip.ButtonCustom); + preferredSize.Width += GetImageWidth(ip.ButtonCustom2); + preferredSize.Width += GetImageWidth(ip.ButtonDropDown); + preferredSize.Width += GetImageWidth(ip.ButtonFreeText); + + if (ip.ShowUpDown == true) + preferredSize.Width += 16; + + if (ip.ShowCheckBox == true) + preferredSize.Width += 16; + } + } + + return (preferredSize); + } + + #endregion + + #region GetFormattedValue + + protected override object GetFormattedValue(object value, int rowIndex, + ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, + TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) + { + DataGridViewIntegerInputColumn oc = OwningColumn as DataGridViewIntegerInputColumn; + + if (oc != null) + { + IntegerInput ip = oc.IntegerInput; + ip.Value = GetValue(value); + + return (ip.Text); + } + + return (base.GetFormattedValue(value, rowIndex, + ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context)); + } + + #endregion + + #region GetImageWidth + + private int GetImageWidth(InputButtonSettings ibs) + { + if (ibs.Visible == true) + return (ibs.Image != null ? ibs.Image.Width : 16); + + return (0); + } + + #endregion + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, + DataGridViewElementStates elementState, object value, object formattedValue, + string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, + DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewIntegerInputColumn oc = (DataGridViewIntegerInputColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintCellBackground(g, cellStyle, rBk); + PaintCellContent(g, cellBounds, rowIndex, value, cellStyle, paintParts); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintCellBackground + + /// + /// Paints the cell background + /// + /// + /// + /// + private void PaintCellBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintCellContent + + /// + /// Paints the cell content + /// + /// + /// + /// + /// + /// + /// + private void PaintCellContent(Graphics g, Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts) + { + DataGridViewIntegerInputColumn oc = (DataGridViewIntegerInputColumn)OwningColumn; + IntegerInput di = oc.IntegerInput; + + Point ptCurrentCell = DataGridView.CurrentCellAddress; + bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex; + bool cellEdited = cellCurrent && DataGridView.EditingControl != null; + + // If the cell is in editing mode, there is nothing else to paint + + if (cellEdited == false && rowIndex < DataGridView.RowCount) + { + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + { + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + di.Font = cellStyle.Font; + di.ForeColor = cellStyle.ForeColor; + di.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + + di.BackgroundStyle.TextColor = cellStyle.ForeColor; + di.BackgroundStyle.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + di.InputHorizontalAlignment = GetHorizontalAlignment(cellStyle.Alignment); + + di.Value = GetValue(value); + + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + + if (oc.DisplayControlForCurrentCellOnly == false) + DrawControl(di, r, g); + else + DrawText(di, r, g); + } + } + } + + #region DrawControl + + /// + /// DrawControl + /// + /// + /// + /// + private void DrawControl(IntegerInput di, Rectangle r, Graphics g) + { + GraphicsState gs = g.Save(); + + try + { + g.TranslateTransform(r.X, r.Y); + + di.Width = r.Width; + di.InternalPaint(new PaintEventArgs(g, Rectangle.Empty)); + } + finally + { + g.Restore(gs); + } + } + + #endregion + + #region DrawText + + /// + /// DrawText + /// + /// + /// + /// + private void DrawText(IntegerInput di, Rectangle r, Graphics g) + { + r.Inflate(-2, 0); + + eTextFormat tf = eTextFormat.VerticalCenter; + + switch (di.InputHorizontalAlignment) + { + case eHorizontalAlignment.Center: + tf |= eTextFormat.HorizontalCenter; + break; + + case eHorizontalAlignment.Right: + tf |= eTextFormat.Right; + break; + } + + TextDrawing.DrawString(g, di.Text, di.Font, di.ForeColor, r, tf); + } + + #endregion + + #endregion + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewIntegerInputColumn oc = (DataGridViewIntegerInputColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetCellBounds + + /// + /// Gets the button bounds for the given cell + /// + /// + /// + private Rectangle GetCellBounds(Rectangle cellBounds) + { + DataGridViewIntegerInputColumn oc = (DataGridViewIntegerInputColumn)OwningColumn; + + Size size = oc.IntegerInput.Size; + + cellBounds.Location = new Point(1, 1); + + cellBounds.Width = Math.Min(size.Width, cellBounds.Width); + cellBounds.Width -= oc.DividerWidth; + cellBounds.Height = size.Height; + + return (cellBounds); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + private int GetValue(object value) + { + if (value == Convert.DBNull || + (value is string && String.IsNullOrEmpty((string) value) == true)) + { + return (0); + } + + return (Convert.ToInt32(value)); + } + + #endregion + + #region GetHorizontalAlignment + + /// + /// GetHorizontalAlignment + /// + /// + /// + private eHorizontalAlignment GetHorizontalAlignment(DataGridViewContentAlignment alignment) + { + switch (alignment) + { + case DataGridViewContentAlignment.TopCenter: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.BottomCenter: + return (eHorizontalAlignment.Center); + + case DataGridViewContentAlignment.TopRight: + case DataGridViewContentAlignment.MiddleRight: + case DataGridViewContentAlignment.BottomRight: + return (eHorizontalAlignment.Right); + + default: + return (eHorizontalAlignment.Left); + } + } + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIntegerInput/DataGridViewIntegerInputColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIntegerInput/DataGridViewIntegerInputColumn.cs new file mode 100644 index 00000000..e40feae0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIntegerInput/DataGridViewIntegerInputColumn.cs @@ -0,0 +1,597 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewButtonXColumn), "IntegerInput.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewIntegerInputColumn : DataGridViewTextBoxColumn, IDataGridViewColumn + { + #region Events + + /// + /// Occurs right before a DateTimeInput Cell is painted + /// + [Description("Occurs right before an IntegerInput Cell is painted.")] + public event EventHandler BeforeCellPaint; + + /// + /// Occurs when Clear button is clicked and allows you + /// to cancel the default action performed by the button + /// + [Description("Occurs when Clear button is clicked and allows you to cancel the default action performed by the button.")] + public event EventHandler ButtonClearClick; + + /// + /// Occurs when ButtonCustom control is clicked + /// + [Description("Occurs when ButtonCustom control is clicked.")] + public event EventHandler ButtonCustomClick; + + /// + /// Occurs when ButtonCustom2 control is clicked + /// + [Description("Occurs when ButtonCustom2 control is clicked.")] + public event EventHandler ButtonCustom2Click; + + /// + /// Occurs when Drop-Down button that shows calendar + /// is clicked and allows you to cancel showing of the popup + /// + [Description("Occurs when Drop-Down button that shows calendar is clicked and allows you to cancel showing of the popup.")] + public event EventHandler ButtonDropDownClick; + + /// + /// Occurs when Free-Text button is clicked + /// and allows you to cancel its default action + /// + [Description("Occurs when Free-Text button is clicked and allows you to cancel its default action.")] + public event EventHandler ButtonFreeTextClick; + + /// + /// Occurs if Free-Text entry value is not natively recognized by + /// the control and provides you with opportunity to convert that + /// value to the value the control expects + /// + [Description("Occurs if Free-Text entry value is not natively recognized by the control and provides you with opportunity to convert that value to the value the control expects.")] + public event EventHandler ConvertFreeTextEntry; + + #endregion + + #region Private variables + + private IntegerInput _IngegerInput; + private Bitmap _CellBitmap; + private bool _DisplayControlForCurrentCellOnly = true; + + #endregion + + /// + /// Constructor + /// + public DataGridViewIntegerInputColumn() + { + CellTemplate = new DataGridViewIntegerInputCell(); + + _IngegerInput = new IntegerInput(); + + _IngegerInput.BackgroundStyle.Class = ElementStyleClassKeys.DataGridViewNumericBorderKey; + _IngegerInput.Visible = false; + } + + #region Internal properties + + #region IntegerInput + + /// + /// IntegerInput + /// + internal IntegerInput IntegerInput + { + get { return (_IngegerInput); } + } + + #endregion + + #endregion + + #region Public properties + + #region BackgroundStyle + + /// + /// Specifies the background style of the control. + /// + [Browsable(true), Category("Style")] + [Description("Gets or sets control background style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return (_IngegerInput.BackgroundStyle); } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _IngegerInput.ResetBackgroundStyle(); + + _IngegerInput.BackgroundStyle.Class = "TextBoxBorder"; + _IngegerInput.BackgroundStyle.CornerType = eCornerType.Square; + } + + #endregion + + #region ButtonClear + + /// + /// Gets the object that describes the settings for the button + /// that clears the content of the control when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that clears the content of the control when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonClear + { + get { return (_IngegerInput.ButtonClear); } + } + + #endregion + + #region ButtonCustom + + /// + /// Gets the object that describes the settings for the custom button + /// that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get { return (_IngegerInput.ButtonCustom); } + } + + #endregion + + #region ButtonCustom2 + + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get { return (_IngegerInput.ButtonCustom2); } + } + + #endregion + + #region ButtonDropDown + + /// + /// Gets the object that describes the settings for the button + /// that shows drop-down when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that shows drop-down when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonDropDown + { + get { return (_IngegerInput.ButtonDropDown); } + } + + #endregion + + #region ButtonFreeText + + /// + /// Gets the object that describes the settings for the button + /// that switches the control into the free-text entry mode when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that switches the control into the free-text entry mode when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonFreeText + { + get { return (_IngegerInput.ButtonFreeText); } + } + + #endregion + + #region DisplayFormat + + /// + /// Gets or sets the Numeric String Format that is used to format + /// the numeric value entered for display purpose. Read more about + /// available formats in MSDN under "Standard Numeric Format Strings" + /// and "Custom Numeric Format Strings" topics. + /// + /// The format specified here indicates the format for display purpose + /// only, not for the input purpose. For example to display the number + /// in system Currency format set the DisplayFormat to 'C'. + /// + /// + [Browsable(true), DefaultValue("")] + [Description("Indicates Numeric String Format that is used to format the numeric value entered for display purpose.")] + public string DisplayFormat + { + get { return (_IngegerInput.DisplayFormat); } + set { _IngegerInput.DisplayFormat = value; } + } + + #endregion + + #region DisplayControlForCurrentCellOnly + + /// + /// Gets or sets whether the control + /// will be displayed for the current cell only. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the control will be displayed for the current cell only.")] + public bool DisplayControlForCurrentCellOnly + { + get { return (_DisplayControlForCurrentCellOnly); } + + set + { + if (_DisplayControlForCurrentCellOnly != value) + { + _DisplayControlForCurrentCellOnly = value; + _IngegerInput.Invalidate(); + } + } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_IngegerInput.Enabled); } + set { _IngegerInput.Enabled = value; } + } + + #endregion + + #region Increment + + /// + /// Gets or sets the value to increment or decrement the value of the + /// control when the up or down buttons are clicked. + /// + [Browsable(true), DefaultValue(1)] + [Description("Indicates value to increment or decrement the value of the control when the up or down buttons are clicked. ")] + public int Increment + { + get { return (_IngegerInput.Increment); } + set { _IngegerInput.Increment = value; } + } + + #endregion + + #region InputHorizontalAlignment + + /// + /// Gets or sets the input field alignment inside the control + /// + [Browsable(true), DefaultValue(eHorizontalAlignment.Right), Category("Appearance")] + [Description("Indicates alignment of input fields inside of the control.")] + public eHorizontalAlignment InputHorizontalAlignment + { + get { return (_IngegerInput.InputHorizontalAlignment); } + set { _IngegerInput.InputHorizontalAlignment = value; } + } + + #endregion + + #region LockUpdateChecked + + /// + /// Gets or sets whether check box shown using ShowCheckBox + /// property which locks/unlocks the control update is checked. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether check box shown using ShowCheckBox property which locks/unlocks the control update is checked.")] + public bool LockUpdateChecked + { + get { return (_IngegerInput.LockUpdateChecked); } + set { _IngegerInput.LockUpdateChecked = value; } + } + + #endregion + + #region MaxValue + + /// + /// Gets or sets the maximum value that can be entered. + /// + [Browsable(true), DefaultValue(int.MaxValue)] + [Description("Indicates maximum value that can be entered.")] + public int MaxValue + { + get { return (_IngegerInput.MaxValue); } + set { _IngegerInput.MaxValue = value; } + } + + #endregion + + #region MinValue + + /// + /// Gets or sets the minimum value that can be entered. + /// + [Browsable(true), DefaultValue(int.MinValue)] + [Description("Indicates minimum value that can be entered.")] + public int MinValue + { + get { return (_IngegerInput.MinValue); } + set { _IngegerInput.MinValue = value; } + } + + #endregion + + #region ShowCheckBox + + /// + /// Gets or sets a value indicating whether a check box is + /// displayed to the left of the input value. Set to true if a check box + /// is displayed to the left of the input value; otherwise, false. The default is false. + /// + /// When the ShowCheckBox property is set to true, a check box is displayed + /// to the left of the input in the control. When the check box is selected, the value + /// can be updated. When the check box is cleared, the value is unable to be changed. + /// You can handle the LockUpdateChanged event to be notified when this check box is checked + /// and unchecked. Use LockUpdateChecked property to get or sets whether check box is checked. + /// + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether a check box is displayed to the left of the input value which allows locking of the control.")] + public bool ShowCheckBox + { + get { return (_IngegerInput.ShowCheckBox); } + set { _IngegerInput.ShowCheckBox = value; } + } + + #endregion + + #region ShowUpDown + + /// + /// Gets or sets a value indicating whether a spin button control + /// (up-down control) is used to adjust the current value. The default is false. + /// + /// When the ShowUpDown property is set to true, a spin button control + /// is shown to adjust value of currently focused input item. The value can + /// be adjusted by using the up and down buttons to change the value. + /// + /// + [Browsable(true), DefaultValue(false)] + public bool ShowUpDown + { + get { return (_IngegerInput.ShowUpDown); } + set { _IngegerInput.ShowUpDown = value; } + } + + #endregion + + #endregion + + #region Event processing + + #region DoButtonClearClick + + /// + /// DoButtonClearClick + /// + /// + /// + internal void DoButtonClearClick(object sender, CancelEventArgs e) + { + if (ButtonClearClick != null) + ButtonClearClick(this, e); + } + + #endregion + + #region DoButtonCustomClick + + /// + /// DoButtonCustomClick + /// + /// + /// + internal void DoButtonCustomClick(object sender, EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + #endregion + + #region DoButtonCustom2Click + + /// + /// DoButtonCustom2Click + /// + /// + /// + internal void DoButtonCustom2Click(object sender, EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + #endregion + + #region DoButtonDropDownClick + + /// + /// DoButtonDropDownClick + /// + /// + /// + internal void DoButtonDropDownClick(object sender, CancelEventArgs e) + { + if (ButtonDropDownClick != null) + ButtonDropDownClick(this, e); + } + + #endregion + + #region DoButtonFreeTextClick + + /// + /// DoButtonFreeTextClick + /// + /// + /// + internal void DoButtonFreeTextClick(object sender, CancelEventArgs e) + { + if (ButtonFreeTextClick != null) + ButtonFreeTextClick(this, e); + } + + #endregion + + #region DoConvertFreeTextEntry + + /// + /// DoConvertFreeTextEntry + /// + /// + /// + internal void DoConvertFreeTextEntry(object sender, FreeTextEntryConversionEventArgs e) + { + if (ConvertFreeTextEntry != null) + ConvertFreeTextEntry(this, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewIntegerInputColumn dc = base.Clone() as DataGridViewIntegerInputColumn; + + if (dc != null) + { + dc.DisplayFormat = DisplayFormat; + dc.Enabled = Enabled; + dc.Increment = Increment; + dc.InputHorizontalAlignment = InputHorizontalAlignment; + dc.LockUpdateChecked = LockUpdateChecked; + dc.MaxValue = MaxValue; + dc.MinValue = MinValue; + dc.ShowCheckBox = ShowCheckBox; + dc.ShowUpDown = ShowUpDown; + + dc.DisplayControlForCurrentCellOnly = DisplayControlForCurrentCellOnly; + + dc.BackgroundStyle.ApplyStyle(IntegerInput.BackgroundStyle); + dc.BackgroundStyle.Class = IntegerInput.BackgroundStyle.Class; + + IntegerInput.ButtonClear.CopyToItem(dc.IntegerInput.ButtonClear); + IntegerInput.ButtonDropDown.CopyToItem(dc.IntegerInput.ButtonDropDown); + IntegerInput.ButtonFreeText.CopyToItem(dc.IntegerInput.ButtonFreeText); + IntegerInput.ButtonCustom.CopyToItem(dc.IntegerInput.ButtonCustom); + IntegerInput.ButtonCustom2.CopyToItem(dc.IntegerInput.ButtonCustom2); + } + + return (dc); + } + + #endregion + + #region Dispose + + protected override void Dispose(bool disposing) + { + if (disposing == true) + _IngegerInput.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIntegerInput/DataGridViewIntegerInputEditingControl.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIntegerInput/DataGridViewIntegerInputEditingControl.cs new file mode 100644 index 00000000..dfaa04b7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIntegerInput/DataGridViewIntegerInputEditingControl.cs @@ -0,0 +1,210 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), ComVisible(false)] + public class DataGridViewIntegerInputEditingControl : IntegerInput, IDataGridViewEditingControl + { + #region Private variables + + private DataGridView _DataGridView; + + private int _RowIndex; + private bool _ValueChanged; + private bool _EditCancelled; + + #endregion + + #region OnValueChanged + + /// + /// Handles OnValueChanged events + /// + /// + protected override void OnValueChanged(EventArgs e) + { + _ValueChanged = true; + + _DataGridView.NotifyCurrentCellDirty(true); + + base.OnValueChanged(e); + } + + #endregion + + #region Internal properties + + /// + /// Gets or sets the Edit state + /// + internal bool EditCancelled + { + get { return (_EditCancelled); } + set { _EditCancelled = value; } + } + + #endregion + + #region IDataGridViewEditingControl Members + + #region Public properties + + #region EditingControlDataGridView + + /// + /// Gets or sets the DataGridView + /// + public DataGridView EditingControlDataGridView + { + get { return (_DataGridView); } + set { _DataGridView = value; } + } + + #endregion + + #region EditingControlFormattedValue + + /// + /// Gets or sets the Control Formatted Value + /// + public object EditingControlFormattedValue + { + get { return (this.Value.ToString()); } + + set + { + string newValue = value as string; + + if (newValue != null) + Value = int.Parse(newValue); + } + } + + #endregion + + #region EditingControlRowIndex + + /// + /// Gets or sets the Control RoeIndex + /// + public int EditingControlRowIndex + { + get { return (_RowIndex); } + set { _RowIndex = value; } + } + + #endregion + + #region EditingControlValueChanged + + /// + /// Gets or sets the Control ValueChanged state + /// + public bool EditingControlValueChanged + { + get { return (_ValueChanged); } + set { _ValueChanged = value; } + } + + #endregion + + #region EditingPanelCursor + + /// + /// Gets the Panel Cursor + /// + public Cursor EditingPanelCursor + { + get { return (base.Cursor); } + } + + #endregion + + #region RepositionEditingControlOnValueChange + + /// + /// Gets whether to RepositionEditingControlOnValueChange + /// + public bool RepositionEditingControlOnValueChange + { + get { return (false); } + } + + #endregion + + #endregion + + #region ApplyCellStyleToEditingControl + + /// + /// ApplyCellStyleToEditingControl + /// + /// + public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) + { + Font = dataGridViewCellStyle.Font; + + ForeColor = dataGridViewCellStyle.ForeColor; + BackColor = dataGridViewCellStyle.BackColor; + } + + #endregion + + #region GetEditingControlFormattedValue + + /// + /// Gets EditingControlFormattedValue + /// + /// + /// + public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) + { + return (EditingControlFormattedValue); + } + + #endregion + + #region EditingControlWantsInputKey + + /// + /// Gets whether the given key wants to be processed + /// by the Control + /// + /// + /// + /// + public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) + { + if ((keyData & Keys.Right) == Keys.Right) + return (true); + + if ((keyData & Keys.Left) == Keys.Left) + return (true); + + if ((keyData & Keys.Escape) == Keys.Escape) + _EditCancelled = true; + + return (dataGridViewWantsInputKey == false); + } + + #endregion + + #region PrepareEditingControlForEdit + + /// + /// PrepareEditingControlForEdit + /// + /// + public void PrepareEditingControlForEdit(bool selectAll) + { + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIpAddressInput/DataGridViewIpAddressInputCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIpAddressInput/DataGridViewIpAddressInputCell.cs new file mode 100644 index 00000000..4d27e7c8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIpAddressInput/DataGridViewIpAddressInputCell.cs @@ -0,0 +1,711 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Media; +using System.Windows.Forms; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewIpAddressInputCell : DataGridViewTextBoxCell + { + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (typeof(DataGridViewIpAddressInputEditingControl)); } + } + + #endregion + + #endregion + + #region InitializeEditingControl + + /// + /// InitializeEditingControl + /// + /// + /// + /// + public override void InitializeEditingControl(int rowIndex, + object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) + { + DetachEditingControl(); + + base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); + + DataGridViewIpAddressInputEditingControl ctl = + (DataGridViewIpAddressInputEditingControl)DataGridView.EditingControl; + + DataGridViewIpAddressInputColumn oc = (DataGridViewIpAddressInputColumn)OwningColumn; + IpAddressInput tb = oc.IpAddressInput; + + ctl.Font = dataGridViewCellStyle.Font; + ctl.ForeColor = dataGridViewCellStyle.ForeColor; + ctl.BackColor = dataGridViewCellStyle.BackColor; + + ctl.AllowEmptyState = tb.AllowEmptyState; + ctl.AutoOffFreeTextEntry = tb.AutoOffFreeTextEntry; + ctl.AutoOverwrite = tb.AutoOverwrite; + ctl.AutoResolveFreeTextEntries = tb.AutoResolveFreeTextEntries; + ctl.DropDownControl = tb.DropDownControl; + ctl.Enabled = tb.Enabled; + ctl.FocusHighlightColor = tb.FocusHighlightColor; + ctl.FocusHighlightEnabled = tb.FocusHighlightEnabled; + ctl.FreeTextEntryMode = tb.FreeTextEntryMode; + ctl.ImeMode = tb.ImeMode; + ctl.InputHorizontalAlignment = GetHorizontalAlignment(dataGridViewCellStyle.Alignment); + ctl.IsInputReadOnly = tb.IsInputReadOnly; + ctl.LockUpdateChecked = tb.LockUpdateChecked; + ctl.RightToLeft = tb.RightToLeft; + ctl.SelectNextInputCharacters = tb.SelectNextInputCharacters; + ctl.ShowCheckBox = tb.ShowCheckBox; + ctl.WatermarkColor = tb.WatermarkColor; + ctl.WatermarkEnabled = tb.WatermarkEnabled; + ctl.WatermarkFont = tb.WatermarkFont; + ctl.WatermarkText = tb.WatermarkText; + + ctl.DropDownItems.Clear(); + + if (tb.DropDownItems.Count > 0) + { + for (int i = 0; i < tb.DropDownItems.Count; i++) + ctl.DropDownItems.Add(tb.DropDownItems[i]); + } + + ctl.BackgroundStyle.ApplyStyle(tb.BackgroundStyle); + ctl.BackgroundStyle.Class = tb.BackgroundStyle.Class; + + tb.ButtonClear.CopyToItem(ctl.ButtonClear); + tb.ButtonCustom.CopyToItem(ctl.ButtonCustom); + tb.ButtonCustom2.CopyToItem(ctl.ButtonCustom2); + tb.ButtonDropDown.CopyToItem(ctl.ButtonDropDown); + + ctl.ButtonClearClick += ButtonClearClick; + ctl.ButtonCustomClick += ButtonCustomClick; + ctl.ButtonCustom2Click += ButtonCustom2Click; + ctl.ButtonDropDownClick += ButtonDropDownClick; + + ctl.Value = GetValue(initialFormattedValue); + + ctl.EditCancelled = false; + } + + #endregion + + #region DetachEditingControl + + /// + /// DetachEditingControl + /// + public override void DetachEditingControl() + { + if (DataGridView != null && DataGridView.EditingControl != null) + { + DataGridViewIpAddressInputEditingControl di = + DataGridView.EditingControl as DataGridViewIpAddressInputEditingControl; + + if (di != null) + { + di.ButtonClearClick -= ButtonClearClick; + di.ButtonCustomClick -= ButtonCustomClick; + di.ButtonCustom2Click -= ButtonCustom2Click; + di.ButtonDropDownClick -= ButtonDropDownClick; + + if (di.EditCancelled == true) + { + di.EditCancelled = false; + + SystemSounds.Beep.Play(); + } + } + } + + base.DetachEditingControl(); + } + + #endregion + + #region Event processing + + #region ButtonClearClick + + /// + /// ButtonClearClick + /// + /// + /// + void ButtonClearClick(object sender, CancelEventArgs e) + { + ((DataGridViewIpAddressInputColumn)OwningColumn).DoButtonClearClick(sender, e); + } + + #endregion + + #region ButtonCustomClick + + /// + /// ButtonCustomClick + /// + /// + /// + void ButtonCustomClick(object sender, EventArgs e) + { + ((DataGridViewIpAddressInputColumn)OwningColumn).DoButtonCustomClick(sender, e); + } + + #endregion + + #region ButtonCustom2Click + + /// + /// ButtonCustom2Click + /// + /// + /// + void ButtonCustom2Click(object sender, EventArgs e) + { + ((DataGridViewIpAddressInputColumn)OwningColumn).DoButtonCustom2Click(sender, e); + } + + #endregion + + #region ButtonDropDownClick + + /// + /// ButtonDropDownClick + /// + /// + /// + void ButtonDropDownClick(object sender, CancelEventArgs e) + { + ((DataGridViewIpAddressInputColumn)OwningColumn).DoButtonDropDownClick(sender, e); + } + + #endregion + + #endregion + + #region PositionEditingControl + + /// + /// PositionEditingControl + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public override void PositionEditingControl(bool setLocation, bool setSize, Rectangle cellBounds, + Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, + bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) + { + Rectangle editingControlBounds = + PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, + singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow); + + editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle); + + DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y); + DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height); + } + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetCellBounds(editingControlBounds); + + if (cellStyle != null && r.Height < editingControlBounds.Height) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.MiddleLeft: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height) / 2; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + editingControlBounds.Width = Math.Max(1, editingControlBounds.Width); + editingControlBounds.Height = Math.Max(1, r.Height); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + #region GetPreferredSize + + /// + /// GetPreferredSize + /// + /// + /// + /// + /// + /// + protected override Size GetPreferredSize(Graphics graphics, + DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + { + if (DataGridView == null) + return (new Size(-1, -1)); + + Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize); + + DataGridViewIpAddressInputColumn oc = OwningColumn as DataGridViewIpAddressInputColumn; + + if (oc != null) + { + IpAddressInput ip = oc.IpAddressInput; + + preferredSize.Width += 6; + preferredSize.Height = ip.Height; + + if (constraintSize.Width == 0) + { + preferredSize.Width += GetImageWidth(ip.ButtonClear); + preferredSize.Width += GetImageWidth(ip.ButtonCustom); + preferredSize.Width += GetImageWidth(ip.ButtonCustom2); + preferredSize.Width += GetImageWidth(ip.ButtonDropDown); + preferredSize.Width += GetImageWidth(ip.ButtonFreeText); + + if (ip.ShowCheckBox == true) + preferredSize.Width += 16; + } + } + + return (preferredSize); + } + + #endregion + + #region GetFormattedValue + + protected override object GetFormattedValue(object value, int rowIndex, + ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, + TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) + { + DataGridViewIpAddressInputColumn oc = OwningColumn as DataGridViewIpAddressInputColumn; + + if (oc != null) + { + IpAddressInput ip = oc.IpAddressInput; + ip.Value = GetValue(value); + + return (ip.Text); + } + + return (base.GetFormattedValue(value, rowIndex, + ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context)); + } + + #endregion + + #region GetImageWidth + + private int GetImageWidth(InputButtonSettings ibs) + { + if (ibs.Visible == true) + return (ibs.Image != null ? ibs.Image.Width : 16); + + return (0); + } + + #endregion + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, + DataGridViewElementStates elementState, object value, object formattedValue, + string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, + DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewIpAddressInputColumn oc = (DataGridViewIpAddressInputColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintCellBackground(g, cellStyle, rBk); + PaintCellContent(g, cellBounds, rowIndex, formattedValue, cellStyle, paintParts); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintCellBackground + + /// + /// Paints the cell background + /// + /// + /// + /// + private void PaintCellBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintCellContent + + /// + /// Paints the cell content + /// + /// + /// + /// + /// + /// + /// + private void PaintCellContent(Graphics g, Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts) + { + DataGridViewIpAddressInputColumn oc = (DataGridViewIpAddressInputColumn)OwningColumn; + IpAddressInput di = oc.IpAddressInput; + + Point ptCurrentCell = DataGridView.CurrentCellAddress; + bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex; + bool cellEdited = cellCurrent && DataGridView.EditingControl != null; + + // If the cell is in editing mode, there is nothing else to paint + + if (cellEdited == false && rowIndex < DataGridView.RowCount) + { + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + { + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + di.Font = cellStyle.Font; + di.ForeColor = cellStyle.ForeColor; + di.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + di.InputHorizontalAlignment = GetHorizontalAlignment(cellStyle.Alignment); + + di.Value = GetValue(value); + + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + + if (oc.DisplayControlForCurrentCellOnly == false) + DrawControl(di, r, g); + else + DrawText(di, r, g); + } + } + } + + #region DrawControl + + /// + /// DrawControl + /// + /// + /// + /// + private void DrawControl(IpAddressInput di, Rectangle r, Graphics g) + { + GraphicsState gs = g.Save(); + + try + { + g.TranslateTransform(r.X, r.Y); + + di.Width = r.Width; + di.InternalPaint(new PaintEventArgs(g, Rectangle.Empty)); + } + finally + { + g.Restore(gs); + } + } + + #endregion + + #region DrawText + + /// + /// DrawText + /// + /// + /// + /// + private void DrawText(IpAddressInput di, Rectangle r, Graphics g) + { + r.Inflate(-2, 0); + + eTextFormat tf = eTextFormat.VerticalCenter; + + switch (di.InputHorizontalAlignment) + { + case eHorizontalAlignment.Center: + tf |= eTextFormat.HorizontalCenter; + break; + + case eHorizontalAlignment.Right: + tf |= eTextFormat.Right; + break; + } + + TextDrawing.DrawString(g, di.Text, di.Font, di.ForeColor, r, tf); + } + + #endregion + + #endregion + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewIpAddressInputColumn oc = (DataGridViewIpAddressInputColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetCellBounds + + /// + /// Gets the button bounds for the given cell + /// + /// + /// + private Rectangle GetCellBounds(Rectangle cellBounds) + { + DataGridViewIpAddressInputColumn oc = (DataGridViewIpAddressInputColumn)OwningColumn; + + oc.IpAddressInput.RecalcLayout(); + Size size = oc.IpAddressInput.PreferredSize; + + if (oc.IpAddressInput.ButtonClear.Visible == true) + { + if (oc.IpAddressInput.ButtonClear.Image != null) + size.Width += oc.IpAddressInput.ButtonClear.Image.Size.Width; + else + size.Width += 16; + } + + if (oc.IpAddressInput.ButtonCustom.Visible == true) + { + if (oc.IpAddressInput.ButtonCustom.Image != null) + size.Width += oc.IpAddressInput.ButtonCustom.Image.Size.Width; + else + size.Width += 16; + } + + if (oc.IpAddressInput.ButtonCustom2.Visible == true) + { + if (oc.IpAddressInput.ButtonCustom2.Image != null) + size.Width += oc.IpAddressInput.ButtonCustom2.Image.Size.Width; + else + size.Width += 16; + } + + if (oc.IpAddressInput.ButtonDropDown.Visible == true) + { + if (oc.IpAddressInput.ButtonDropDown.Image != null) + size.Width += oc.IpAddressInput.ButtonDropDown.Image.Size.Width; + else + size.Width += 16; + } + + cellBounds.Location = new Point(1, 1); + + cellBounds.Width = Math.Min(size.Width, cellBounds.Width); + cellBounds.Width -= oc.DividerWidth; + cellBounds.Height = size.Height; + + return (cellBounds); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + private string GetValue(object value) + { + return (value != Convert.DBNull ? Convert.ToString(value) : ""); + } + + #endregion + + #region GetHorizontalAlignment + + /// + /// GetHorizontalAlignment + /// + /// + /// + private eHorizontalAlignment GetHorizontalAlignment(DataGridViewContentAlignment alignment) + { + switch (alignment) + { + case DataGridViewContentAlignment.TopCenter: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.BottomCenter: + return (eHorizontalAlignment.Center); + + case DataGridViewContentAlignment.TopRight: + case DataGridViewContentAlignment.MiddleRight: + case DataGridViewContentAlignment.BottomRight: + return (eHorizontalAlignment.Right); + + default: + return (eHorizontalAlignment.Left); + } + } + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIpAddressInput/DataGridViewIpAddressInputColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIpAddressInput/DataGridViewIpAddressInputColumn.cs new file mode 100644 index 00000000..dc546459 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIpAddressInput/DataGridViewIpAddressInputColumn.cs @@ -0,0 +1,781 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewButtonXColumn), "IpAddressInput.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewIpAddressInputColumn : DataGridViewTextBoxColumn, IDataGridViewColumn + { + #region Events + + /// + /// Occurs right before a IpAddressInput Cell is painted + /// + [Description("Occurs right before a IpAddressInput Cell is painted.")] + public event EventHandler BeforeCellPaint; + + /// + /// Occurs when Clear button is clicked and allows you + /// to cancel the default action performed by the button + /// + [Description("Occurs when Clear button is clicked and allows you to cancel the default action performed by the button.")] + public event EventHandler ButtonClearClick; + + /// + /// Occurs when ButtonCustom control is clicked + /// + [Description("Occurs when ButtonCustom control is clicked.")] + public event EventHandler ButtonCustomClick; + + /// + /// Occurs when ButtonCustom2 control is clicked + /// + [Description("Occurs when ButtonCustom2 control is clicked.")] + public event EventHandler ButtonCustom2Click; + + /// + /// Occurs when Drop-Down button that shows calendar + /// is clicked and allows you to cancel showing of the popup + /// + [Description("Occurs when Drop-Down button that shows calendar is clicked and allows you to cancel showing of the popup.")] + public event EventHandler ButtonDropDownClick; + + #endregion + + #region Private variables + + private IpAddressInput _IpAddressInput; + private Bitmap _CellBitmap; + private bool _DisplayControlForCurrentCellOnly = true; + + #endregion + + /// + /// Constructor + /// + public DataGridViewIpAddressInputColumn() + { + CellTemplate = new DataGridViewIpAddressInputCell(); + + _IpAddressInput = new IpAddressInput(); + + _IpAddressInput.BackgroundStyle.Class = ElementStyleClassKeys.DataGridViewIpAddressBorderKey; + } + + #region Internal properties + + #region IpAddressInput + + /// + /// Gets the underlying IpAddressInput control + /// + [Browsable(false)] + internal IpAddressInput IpAddressInput + { + get { return (_IpAddressInput); } + } + + #endregion + + #endregion + + #region Public properties + + #region AllowEmptyState + + /// + /// Gets or sets whether empty null/nothing state of the control + /// is allowed. Default value is true which means that Text property + /// may return null if there is no input value. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether empty null/nothing state of the control is allowed.")] + public bool AllowEmptyState + { + get { return (_IpAddressInput.AllowEmptyState); } + set { _IpAddressInput.AllowEmptyState = value; } + } + + #endregion + + #region AutoOffFreeTextEntry + + /// + /// Gets or sets whether free-text entry is automatically + /// turned off when control loses input focus. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Free-Text")] + [Description("Indicates whether free-text entry is automatically turned off when control loses input focus.")] + public bool AutoOffFreeTextEntry + { + get { return (_IpAddressInput.AutoOffFreeTextEntry); } + set { _IpAddressInput.AutoOffFreeTextEntry = value; } + } + + #endregion + + #region AutoOverwrite + + /// + /// Gets or sets whether auto-overwrite functionality for input + /// is enabled. When in auto-overwrite mode input field will erase existing entry + /// and start new one if typing is continued after InputComplete method is called. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether auto-overwrite functionality for input is enabled.")] + public bool AutoOverwrite + { + get { return (_IpAddressInput.AutoOverwrite); } + set { _IpAddressInput.AutoOverwrite = value; } + } + + #endregion + + #region AutoResolveFreeTextEntries + + /// + /// Gets or sets whether free text entries are attempted to be + /// auto-resolved to IP address as host/domain names. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Free-Text")] + [Description("Indicates whether free text entries are attempted to be auto-resolved to IP address as host/domain names.")] + public bool AutoResolveFreeTextEntries + { + get { return (_IpAddressInput.AutoResolveFreeTextEntries); } + set { _IpAddressInput.AutoResolveFreeTextEntries = value; } + } + + #endregion + + #region BackColor + + /// + /// Gets or sets the Background color. + /// + [Browsable(false)] + public Color BackColor + { + get { return (_IpAddressInput.BackColor); } + set { _IpAddressInput.BackColor = value; } + } + + #endregion + + #region BackgroundStyle + + /// + /// Specifies the background style of the control. + /// + [Browsable(true), Category("Style")] + [Description("Gets or sets control background style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return (_IpAddressInput.BackgroundStyle); } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _IpAddressInput.ResetBackgroundStyle(); + + _IpAddressInput.BackgroundStyle.Class = "TextBoxBorder"; + _IpAddressInput.BackgroundStyle.CornerType = eCornerType.Square; + } + + #endregion + + #region ButtonClear + + /// + /// Gets the object that describes the settings for the button + /// that clears the content of the control when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that clears the content of the control when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonClear + { + get { return (_IpAddressInput.ButtonClear); } + } + + #endregion + + #region ButtonCustom + + /// + /// Gets the object that describes the settings for the custom button + /// that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get { return (_IpAddressInput.ButtonCustom); } + } + + #endregion + + #region ButtonCustom2 + + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get { return (_IpAddressInput.ButtonCustom2); } + } + + #endregion + + #region ButtonDropDown + + /// + /// Gets the object that describes the settings for the button + /// that shows drop-down when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that shows drop-down when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonDropDown + { + get { return (_IpAddressInput.ButtonDropDown); } + } + + #endregion + + #region DisplayControlForCurrentCellOnly + + /// + /// Gets or sets whether the control + /// will be displayed for the current cell only. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the control will be displayed for the current cell only.")] + public bool DisplayControlForCurrentCellOnly + { + get { return (_DisplayControlForCurrentCellOnly); } + + set + { + if (_DisplayControlForCurrentCellOnly != value) + { + _DisplayControlForCurrentCellOnly = value; + _IpAddressInput.Invalidate(); + } + } + } + + #endregion + + #region DropDownControl + + /// + /// Gets or sets the reference of the control that will be + /// displayed on popup that is shown when the drop-down button is clicked. + /// + [DefaultValue(null)] + [Description("Indicates reference of the control that will be displayed on popup that is shown when the drop-down button is clicked.")] + public Control DropDownControl + { + get { return (_IpAddressInput.DropDownControl); } + set { _IpAddressInput.DropDownControl = value; } + } + + #endregion + + #region DropDownItems + + /// + /// Returns the collection of DropDownItems. + /// + [Browsable(false), DevCoBrowsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SubItemsCollection DropDownItems + { + get { return (_IpAddressInput.DropDownItems); } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_IpAddressInput.Enabled); } + set { _IpAddressInput.Enabled = value; } + } + + #endregion + + #region FocusHighlightColor + + /// + /// Gets or sets the color used as background color to highlight + /// the text box when it has input focus and FocusHighlight is enabled. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates color used as background color to highlight the text box when it has input focus and FocusHighlight is enabled.")] + public Color FocusHighlightColor + { + get { return (_IpAddressInput.FocusHighlightColor); } + set { _IpAddressInput.FocusHighlightColor = value; } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFocusHighlightColor() + { + return (_IpAddressInput.ShouldSerializeFocusHighlightColor()); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFocusHighlightColor() + { + _IpAddressInput.ResetFocusHighlightColor(); + } + + #endregion + + #region FocusHighlightEnabled + + /// + /// Gets or sets whether FocusHighlightColor is used as + /// background color to highlight the text box when it has + /// input focus. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Appearance")] + [Description("Indicates whether FocusHighlightColor is used as background color to highlight the text box when it has input focus.")] + public bool FocusHighlightEnabled + { + get { return (_IpAddressInput.FocusHighlightEnabled); } + set { _IpAddressInput.FocusHighlightEnabled = value; } + } + + #endregion + + #region ForeColor + + /// + /// Gets or sets the foreground color. + /// + [Browsable(false)] + public Color ForeColor + { + get { return (_IpAddressInput.ForeColor); } + set { _IpAddressInput.ForeColor = value; } + } + + #endregion + + #region FreeTextEntryMode + + /// + /// Gets or sets whether control input is in + /// free-text input mode. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Free-Text")] + [Description("Indicates whether control input is in free-text input mode.")] + public bool FreeTextEntryMode + { + get { return (_IpAddressInput.FreeTextEntryMode); } + set { _IpAddressInput.FreeTextEntryMode = value; } + } + + #endregion + + #region ImeMode + + /// + /// Gets or sets the Input Method Editor (IME) mode of the control. + /// + [Browsable(true), DefaultValue(ImeMode.Inherit)] + [Description("Indicates the Input Method Editor (IME) mode of the control.")] + public ImeMode ImeMode + { + get { return (_IpAddressInput.ImeMode); } + set { _IpAddressInput.ImeMode = value; } + } + + #endregion + + #region IsInputReadOnly + + /// + /// Gets or sets whether input part of the control is read-only. When + /// set to true the input part of the control becomes read-only and does + /// not allow the typing. However, drop-down part if visible still allows + /// user to possibly change the value of the control through the method you + /// can provide on drop-down. Use this property to allow change of the value + /// through drop-down button only. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether input part of the control is read-only.")] + public bool IsInputReadOnly + { + get { return (_IpAddressInput.IsInputReadOnly); } + set { _IpAddressInput.IsInputReadOnly = value; } + } + + #endregion + + #region LockUpdateChecked + + /// + /// Gets or sets whether check box shown using ShowCheckBox + /// property which locks/unlocks the control update is checked. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether check box shown using ShowCheckBox property which locks/unlocks the control update is checked.")] + public bool LockUpdateChecked + { + get { return (_IpAddressInput.LockUpdateChecked); } + set { _IpAddressInput.LockUpdateChecked = value; } + } + + #endregion + + #region RightToLeft + + /// + /// Gets or sets a value indicating whether control's + /// elements are aligned to support locales using right-to-left fonts. + /// + [Browsable(true), DefaultValue(RightToLeft.Inherit)] + [Description("Indicates the control's elements are aligned to support locales using right-to-left fonts.")] + public RightToLeft RightToLeft + { + get { return (_IpAddressInput.RightToLeft); } + set { _IpAddressInput.RightToLeft = value; } + } + + #endregion + + #region SelectNextInputCharacters + + /// + /// List of characters that when pressed would select next input field. For example if you are + /// allowing time input you could set this property to : so when user presses the : character, + /// the input is forwarded to the next input field. + /// + [DefaultValue("."), Category("Behavior")] + [Description("List of characters that when pressed would select next input field.")] + public string SelectNextInputCharacters + { + get { return (_IpAddressInput.SelectNextInputCharacters); } + set { _IpAddressInput.SelectNextInputCharacters = value; } + } + + #endregion + + #region ShowCheckBox + + /// + /// Gets or sets a value indicating whether a check box is displayed to + /// the left of the input value. Set to true if a check box is displayed + /// to the left of the input value; otherwise, false. The default is false. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether a check box is displayed to the left of the input value which allows locking of the control.")] + public bool ShowCheckBox + { + get { return (_IpAddressInput.ShowCheckBox); } + set { _IpAddressInput.ShowCheckBox = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the text as it is currently displayed to the user. + /// + [Browsable(false)] + public string Text + { + get { return (_IpAddressInput.Text); } + set { _IpAddressInput.Text = value; } + } + + #endregion + + #region WatermarkColor + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return (_IpAddressInput.WatermarkColor); } + set { _IpAddressInput.WatermarkColor = value; } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return (_IpAddressInput.ShouldSerializeWatermarkColor()); + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + _IpAddressInput.ResetWatermarkColor(); + } + + #endregion + + #region WatermarkEnabled + + /// + /// Gets or sets whether watermark text is + /// displayed when control is empty. Default value is true. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return (_IpAddressInput.WatermarkEnabled); } + set { _IpAddressInput.WatermarkEnabled = value; } + } + + #endregion + + #region WatermarkFont + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates watermark font.")] + public Font WatermarkFont + { + get { return (_IpAddressInput.WatermarkFont); } + set { _IpAddressInput.WatermarkFont = value; } + } + + #endregion + + #region WatermarkText + + /// + /// Gets or sets the watermark (tip) text displayed inside of + /// the control when Text is not set and control does not have + /// input focus. This property supports text-markup. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus.")] + [Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string WatermarkText + { + get { return (_IpAddressInput.WatermarkText); } + set { _IpAddressInput.WatermarkText = value; } + } + + #endregion + + #endregion + + #region Event processing + + #region DoButtonClearClick + + /// + /// DoButtonClearClick + /// + /// + /// + internal void DoButtonClearClick(object sender, CancelEventArgs e) + { + if (ButtonClearClick != null) + ButtonClearClick(this, e); + } + + #endregion + + #region DoButtonCustomClick + + /// + /// DoButtonCustomClick + /// + /// + /// + internal void DoButtonCustomClick(object sender, EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + #endregion + + #region DoButtonCustom2Click + + /// + /// DoButtonCustom2Click + /// + /// + /// + internal void DoButtonCustom2Click(object sender, EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + #endregion + + #region DoButtonDropDownClick + + /// + /// DoButtonDropDownClick + /// + /// + /// + internal void DoButtonDropDownClick(object sender, CancelEventArgs e) + { + if (ButtonDropDownClick != null) + ButtonDropDownClick(this, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewIpAddressInputColumn dc = base.Clone() as DataGridViewIpAddressInputColumn; + + if (dc != null) + { + dc.AllowEmptyState = AllowEmptyState; + dc.AutoOffFreeTextEntry = AutoOffFreeTextEntry; + dc.AutoOverwrite = AutoOverwrite; + dc.AutoResolveFreeTextEntries = AutoResolveFreeTextEntries; + dc.DropDownControl = DropDownControl; + dc.Enabled = Enabled; + dc.FocusHighlightColor = FocusHighlightColor; + dc.FocusHighlightEnabled = FocusHighlightEnabled; + dc.FreeTextEntryMode = FreeTextEntryMode; + dc.ImeMode = ImeMode; + dc.IsInputReadOnly = IsInputReadOnly; + dc.LockUpdateChecked = LockUpdateChecked; + dc.RightToLeft = RightToLeft; + dc.SelectNextInputCharacters = SelectNextInputCharacters; + dc.ShowCheckBox = ShowCheckBox; + dc.WatermarkColor = WatermarkColor; + dc.WatermarkEnabled = WatermarkEnabled; + dc.WatermarkFont = WatermarkFont; + dc.WatermarkText = WatermarkText; + + dc.DisplayControlForCurrentCellOnly = DisplayControlForCurrentCellOnly; + + dc.BackgroundStyle.ApplyStyle(IpAddressInput.BackgroundStyle); + dc.BackgroundStyle.Class = IpAddressInput.BackgroundStyle.Class; + + IpAddressInput.ButtonClear.CopyToItem(dc.IpAddressInput.ButtonClear); + IpAddressInput.ButtonDropDown.CopyToItem(dc.IpAddressInput.ButtonDropDown); + IpAddressInput.ButtonCustom.CopyToItem(dc.IpAddressInput.ButtonCustom); + IpAddressInput.ButtonCustom2.CopyToItem(dc.IpAddressInput.ButtonCustom2); + } + + return (dc); + } + + #endregion + + #region Dispose + + protected override void Dispose(bool disposing) + { + if (disposing == true) + _IpAddressInput.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIpAddressInput/DataGridViewIpAddressInputEditingControl.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIpAddressInput/DataGridViewIpAddressInputEditingControl.cs new file mode 100644 index 00000000..1b7e8b8e --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewIpAddressInput/DataGridViewIpAddressInputEditingControl.cs @@ -0,0 +1,199 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), ComVisible(false)] + public class DataGridViewIpAddressInputEditingControl : IpAddressInput, IDataGridViewEditingControl + { + #region Private variables + + private DataGridView _DataGridView; + + private int _RowIndex; + private bool _ValueChanged; + private bool _EditCancelled; + + #endregion + + #region Internal properties + + /// + /// Gets or sets the Edit state + /// + internal bool EditCancelled + { + get { return (_EditCancelled); } + set { _EditCancelled = value; } + } + + #endregion + + #region OnTextChanged + + /// + /// Handles OnTextChanged events + /// + /// + protected override void OnTextChanged(EventArgs e) + { + _ValueChanged = true; + + _DataGridView.NotifyCurrentCellDirty(true); + + base.OnTextChanged(e); + } + + #endregion + + #region IDataGridViewEditingControl Members + + #region Public properties + + #region EditingControlDataGridView + + /// + /// Gets or sets the DataGridView + /// + public DataGridView EditingControlDataGridView + { + get { return (_DataGridView); } + set { _DataGridView = value; } + } + + #endregion + + #region EditingControlFormattedValue + + /// + /// Gets or sets the Control Formatted Value + /// + public object EditingControlFormattedValue + { + get { return (Value ?? ""); } + set { Value = (string)value; } + } + + #endregion + + #region EditingControlRowIndex + + /// + /// Gets or sets the Control RoeIndex + /// + public int EditingControlRowIndex + { + get { return (_RowIndex); } + set { _RowIndex = value; } + } + + #endregion + + #region EditingControlValueChanged + + /// + /// Gets or sets the Control ValueChanged state + /// + public bool EditingControlValueChanged + { + get { return (_ValueChanged); } + set { _ValueChanged = value; } + } + + #endregion + + #region EditingPanelCursor + + /// + /// Gets the Panel Cursor + /// + public Cursor EditingPanelCursor + { + get { return (base.Cursor); } + } + + #endregion + + #region RepositionEditingControlOnValueChange + + /// + /// Gets whether to RepositionEditingControlOnValueChange + /// + public bool RepositionEditingControlOnValueChange + { + get { return (false); } + } + + #endregion + + #endregion + + #region ApplyCellStyleToEditingControl + + /// + /// ApplyCellStyleToEditingControl + /// + /// + public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) + { + } + + #endregion + + #region GetEditingControlFormattedValue + + /// + /// Gets EditingControlFormattedValue + /// + /// + /// + public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) + { + return (EditingControlFormattedValue); + } + + #endregion + + #region EditingControlWantsInputKey + + /// + /// Gets whether the given key wants to be processed + /// by the Control + /// + /// + /// + /// + public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) + { + if ((keyData & Keys.Right) == Keys.Right) + return (true); + + if ((keyData & Keys.Left) == Keys.Left) + return (true); + + if ((keyData & Keys.Escape) == Keys.Escape) + _EditCancelled = true; + + return (dataGridViewWantsInputKey == false); + } + + #endregion + + #region PrepareEditingControlForEdit + + /// + /// PrepareEditingControlForEdit + /// + /// + public void PrepareEditingControlForEdit(bool selectAll) + { + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewLabelX/DataGridViewLabelXCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewLabelX/DataGridViewLabelXCell.cs new file mode 100644 index 00000000..b7bb3405 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewLabelX/DataGridViewLabelXCell.cs @@ -0,0 +1,666 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewLabelXCell : DataGridViewButtonCell + { + #region Private variables + + private DataGridViewCellStyle _CellStyle; + + #endregion + + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (null); } + } + + #endregion + + #region FormattedValueType + + /// + /// FormattedValueType + /// + public override Type FormattedValueType + { + get { return (typeof(string)); } + } + + #endregion + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle, int rowIndex) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetContentBounds(rowIndex); + + if (cellStyle != null) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.TopCenter: + editingControlBounds.X += (editingControlBounds.Width - r.Width) / 2; + break; + + case DataGridViewContentAlignment.TopRight: + editingControlBounds.X = (editingControlBounds.Right - r.Width); + break; + + case DataGridViewContentAlignment.MiddleLeft: + editingControlBounds.Y += (editingControlBounds.Height - r.Height)/2; + break; + + case DataGridViewContentAlignment.MiddleCenter: + editingControlBounds.X += (editingControlBounds.Width - r.Width)/2; + editingControlBounds.Y += (editingControlBounds.Height - r.Height)/2; + break; + + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.X = (editingControlBounds.Right - r.Width); + editingControlBounds.Y += (editingControlBounds.Height - r.Height)/2; + break; + + case DataGridViewContentAlignment.BottomLeft: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + + case DataGridViewContentAlignment.BottomCenter: + editingControlBounds.X += (editingControlBounds.Width - r.Width)/2; + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.X = (editingControlBounds.Right - r.Width); + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + if (editingControlBounds.Y < 1) + editingControlBounds.Y = 1; + + editingControlBounds.Width = Math.Max(1, r.Width); + editingControlBounds.Height = Math.Max(1, r.Height); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + /// + /// GetPreferredSize + /// + /// + /// + /// + /// + /// + protected override Size GetPreferredSize(Graphics graphics, + DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + { + Size size = Size.Empty; + + if (DataGridView == null) + return new Size(-1, -1); + + DataGridViewLabelXColumn oc = OwningColumn as DataGridViewLabelXColumn; + + if (oc != null) + { + LabelX lx = oc.LabelX; + + if (oc.LabelX.IsHandleCreated == false) + { + if (oc.LabelX.Parent == null) + { + Form form = oc.DataGridView.FindForm(); + + if (form != null) + oc.LabelX.Parent = form; + } + + oc.LabelX.Visible = true; + oc.LabelX.Visible = false; + } + + FreeDimension fd = GetDFromConstraint(constraintSize); + + if (fd != FreeDimension.Width) + constraintSize.Width -= 2; + + lx.Font = cellStyle.Font; + lx.WordWrap = GetWordWrap(oc, cellStyle); + lx.TextAlignment = GetTextAlignment(cellStyle.Alignment); + lx.MaximumSize = Size.Empty; + lx.Image = oc.Image; + + string s = lx.Text = @" "; + + if (rowIndex < DataGridView.RowCount) + s = GetValue(DataGridView.Rows[rowIndex].Cells[ColumnIndex].Value); + + if (string.IsNullOrEmpty(s) == true) + s = " "; + + lx.Text = s; + + size = lx.GetPreferredSize(constraintSize); + + Rectangle stdBorderWidths = BorderWidths(new DataGridViewAdvancedBorderStyle()); + + int hpad = (stdBorderWidths.Left + stdBorderWidths.Width) + cellStyle.Padding.Horizontal; + int vpad = (stdBorderWidths.Top + stdBorderWidths.Height) + cellStyle.Padding.Vertical; + + switch (fd) + { + case FreeDimension.Height: + size.Width = 0; + break; + + case FreeDimension.Width: + size.Height = 0; + break; + } + + if (fd != FreeDimension.Height) + size.Width += (hpad + 4); + + if (fd != FreeDimension.Width) + size.Height += (vpad + 2); + } + + return size; + } + + #region GetDFromConstraint + + private enum FreeDimension + { + Both, + Height, + Width + } + + private FreeDimension GetDFromConstraint(Size constraintSize) + { + if (constraintSize.Width == 0) + { + if (constraintSize.Height == 0) + return (FreeDimension.Both); + + return (FreeDimension.Width); + } + + return (FreeDimension.Height); + } + + #endregion + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, + object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewLabelXColumn oc = (DataGridViewLabelXColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintLabelBackground(g, cellStyle, rBk); + PaintLabelContent(cellBounds, rowIndex, formattedValue, cellStyle, paintParts, g); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintLabelBackground + + /// + /// Paints the Label background + /// + /// + /// + /// + private void PaintLabelBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintLabelContent + + /// + /// Paints the Label background and content + /// + /// + /// + /// + /// + /// + /// + private void PaintLabelContent(Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, Graphics g) + { + DataGridViewLabelXColumn oc = (DataGridViewLabelXColumn) OwningColumn; + LabelX lx = oc.LabelX; + + _CellStyle = cellStyle; + + string s = GetValue(value); + + oc.InCallBack = true; + bool wordWrap = lx.WordWrap; + StringAlignment textAlignment = lx.TextAlignment; + + GraphicsState gs = g.Save(); + + try + { + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + lx.Font = cellStyle.Font; + lx.ForeColor = cellStyle.ForeColor; + lx.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + + lx.WordWrap = GetWordWrap(oc, cellStyle); + lx.TextAlignment = GetTextAlignment(cellStyle.Alignment); + + Rectangle r = cellBounds; + + if (rowIndex < DataGridView.RowCount) + { + lx.Text = s; + + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + + r = GetAdjustedEditingControlBounds(cellBounds, cellStyle, rowIndex); + } + else + { + lx.Text = " "; + } + + lx.CallBasePaintBackground = false; + + g.TranslateTransform(r.X, r.Y); + + lx.Bounds = r; + lx.RecalcLayout(); + lx.InternalPaint(new PaintEventArgs(g, Rectangle.Empty)); + } + finally + { + lx.WordWrap = wordWrap; + lx.TextAlignment = textAlignment; + oc.InCallBack = false; + + g.Restore(gs); + } + } + + #region GetWordWrap + + private bool GetWordWrap(DataGridViewLabelXColumn oc, DataGridViewCellStyle cellStyle) + { + if (oc.WordWrap == true) + return (true); + + switch (cellStyle.WrapMode) + { + case DataGridViewTriState.True: + return (true); + + case DataGridViewTriState.False: + return (false); + } + + return (DataGridView.DefaultCellStyle.WrapMode == DataGridViewTriState.True); + } + + #endregion + + #endregion + + #endregion + + #region Mouse processing + + #region OnMouseEnter + + /// + /// OnMouseEnter + /// + /// + protected override void OnMouseEnter(int rowIndex) + { + base.OnMouseEnter(rowIndex); + + DataGridViewLabelXColumn oc = (DataGridViewLabelXColumn)OwningColumn; + LabelX bx = oc.LabelX; + + bx.LabelItem.InternalMouseEnter(); + } + + #endregion + + #region OnMouseLeave + + /// + /// Processes MouseLeave events + /// + /// + protected override void OnMouseLeave(int rowIndex) + { + base.OnMouseLeave(rowIndex); + + DataGridViewLabelXColumn oc = (DataGridViewLabelXColumn)OwningColumn; + LabelX bx = oc.LabelX; + + bx.LabelItem.InternalMouseLeave(); + } + + #endregion + + #region OnMouseMove + + /// + /// Processes MouseMove events + /// + /// + protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) + { + base.OnMouseMove(e); + + DataGridViewLabelXColumn oc = OwningColumn as DataGridViewLabelXColumn; + + if (oc != null) + { + if ((uint)e.RowIndex < DataGridView.Rows.Count) + { + Point pt = CellAlignPoint(e); + + oc.LabelX.LabelItem.InternalMouseMove( + new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta)); + } + } + } + + #endregion + + #region OnMouseDown + + /// + /// Processes MouseDown events + /// + /// + protected override void OnMouseDown(DataGridViewCellMouseEventArgs e) + { + base.OnMouseDown(e); + + DataGridViewLabelXColumn oc = OwningColumn as DataGridViewLabelXColumn; + + if (oc != null) + { + Point pt = CellAlignPoint(e); + + oc.LabelX.LabelItem.InternalMouseDown( + new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta)); + + RefreshCell(e.ColumnIndex, e.RowIndex); + } + } + + #endregion + + #region OnMouseUp + + /// + /// Processes MouseUp events + /// + /// + protected override void OnMouseUp(DataGridViewCellMouseEventArgs e) + { + base.OnMouseUp(e); + + DataGridViewLabelXColumn oc = OwningColumn as DataGridViewLabelXColumn; + + if (oc != null) + { + Point pt = CellAlignPoint(e); + + oc.LabelX.LabelItem.InternalMouseUp( + new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta)); + + RefreshCell(e.ColumnIndex, e.RowIndex); + } + } + + #endregion + + #region CellAlignPoint + + /// + /// CellAlignPoint + /// + /// + /// + private Point CellAlignPoint(DataGridViewCellMouseEventArgs e) + { + Rectangle bounds = DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true); + bounds.Location = new Point(0, 0); + + Rectangle r = GetAdjustedEditingControlBounds(bounds, _CellStyle, e.RowIndex); + + return (new Point(e.X - r.X, e.Y - r.Y)); + } + + #endregion + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewLabelXColumn oc = (DataGridViewLabelXColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + private string GetValue(object value) + { + return (value != Convert.DBNull ? Convert.ToString(value) : ""); + } + + #endregion + + #region GetTextAlignment + + /// + /// GetHorizontalAlignment + /// + /// + /// + private StringAlignment GetTextAlignment(DataGridViewContentAlignment alignment) + { + switch (alignment) + { + case DataGridViewContentAlignment.TopCenter: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.BottomCenter: + return (StringAlignment.Center); + + case DataGridViewContentAlignment.TopRight: + case DataGridViewContentAlignment.MiddleRight: + case DataGridViewContentAlignment.BottomRight: + return (StringAlignment.Far); + + default: + return (StringAlignment.Near); + } + } + + #endregion + + #region RefreshCell + + /// + /// Initiates the refresh of the cell label + /// + /// + /// + internal void RefreshCell(int columnIndex, int rowIndex) + { + DataGridView.InvalidateCell(columnIndex, rowIndex); + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewLabelX/DataGridViewLabelXColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewLabelX/DataGridViewLabelXColumn.cs new file mode 100644 index 00000000..39a5fb1f --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewLabelX/DataGridViewLabelXColumn.cs @@ -0,0 +1,515 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewLabelXColumn), "Controls.LabelX.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewLabelXColumn : DataGridViewButtonColumn, IDataGridViewColumn + { + #region Events + + [Description("Occurs right before a LabelX Cell is painted.")] + public event EventHandler BeforeCellPaint; + + [Description("Occurs when a LabelX Cell is Clicked.")] + public event EventHandler Click; + + #endregion + + #region Private variables + + private LabelX _LabelX; + private Bitmap _CellBitmap; + + private bool _InCellCallBack; + + #endregion + + /// + /// Constructor + /// + public DataGridViewLabelXColumn() + { + CellTemplate = new DataGridViewLabelXCell(); + + _LabelX = new LabelX(); + _LabelX.CreateControl(); + + _LabelX.Visible = false; + + HookEvents(true); + } + + #region Hidden properties + + /// + /// Button FlatStyle + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new FlatStyle FlatStyle + { + get { return base.FlatStyle; } + set { base.FlatStyle = value; } + } + + /// + /// Button UseColumnTextForButtonValue + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool UseColumnTextForButtonValue + { + get { return base.UseColumnTextForButtonValue; } + set { base.UseColumnTextForButtonValue = value; } + } + + #endregion + + #region Internal properties + + #region InCallBack + + /// + /// InCallBack + /// + internal bool InCallBack + { + get { return (_InCellCallBack); } + set { _InCellCallBack = value; } + } + + #endregion + + #region LabelX + + /// + /// Gets the Control LabelX + /// + internal LabelX LabelX + { + get { return (_LabelX); } + } + + #endregion + + #endregion + + #region Public properties + + #region EnableMarkup + + /// + /// Gets or sets whether text-markup support is enabled for items Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the item instead of it being parsed as text-markup. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for the item's Text property.")] + public bool EnableMarkup + { + get { return (_LabelX.EnableMarkup); } + set { _LabelX.EnableMarkup = value; } + } + + #endregion + + #region FocusCuesEnabled + + /// + /// Gets or sets whether control displays focus cues when focused. + /// + [Browsable(true), DefaultValue(false), Category("Behavior")] + [Description("Indicates whether control displays focus cues when focused.")] + public bool FocusCuesEnabled + { + get { return (_LabelX.FocusCuesEnabled); } + set { _LabelX.FocusCuesEnabled = value; } + } + + #endregion + + #region BorderSide + + /// + /// Gets or sets the border sides that are displayed. + /// Default value specifies border on all 4 sides. + /// + [Browsable(false), Category("Appearance"), DefaultValue(LabelItem.DEFAULT_BORDERSIDE)] + [Description("Specifies border sides that are displayed.")] + public eBorderSide BorderSide + { + get { return (_LabelX.BorderSide); } + set { _LabelX.BorderSide = value; } + } + + #endregion + + #region BorderType + + /// + /// Gets or sets the type of the border drawn around the label. + /// + [Browsable(false), Category("Appearance"), DefaultValue(eBorderType.None)] + [Description("Indicates the type of the border drawn around the label.")] + public eBorderType BorderType + { + get { return (_LabelX.BorderType); } + set { _LabelX.BorderType = value; } + } + + #endregion + + #region Image + + /// + /// Specifies label image. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("The image that will be displayed on the face of the item.")] + public Image Image + { + get { return (_LabelX.Image); } + set { _LabelX.Image = value; } + } + + #endregion + + #region ImagePosition + + /// + /// Gets/Sets the image position inside the label. + /// + [Browsable(true), Category("Appearance"), DefaultValue(eImagePosition.Left)] + [Description("The alignment of the image in relation to text displayed by this item.")] + public eImagePosition ImagePosition + { + get { return (_LabelX.ImagePosition); } + set { _LabelX.ImagePosition = value; } + } + + #endregion + + #region PaddingBottom + + /// + /// Gets or sets the bottom padding in pixels. + /// + [Browsable(true), DefaultValue(0), Category("Layout")] + [Description("Indicates bottom padding in pixels.")] + public int PaddingBottom + { + get { return (_LabelX.PaddingBottom); } + set { _LabelX.PaddingBottom = value; } + } + + #endregion + + #region PaddingLeft + + /// + /// Gets or sets the left padding in pixels. + /// + [Browsable(true), DefaultValue(0), Category("Layout")] + [Description("Indicates left padding in pixels.")] + public int PaddingLeft + { + get { return (_LabelX.PaddingLeft); } + set { _LabelX.PaddingLeft = value; } + } + + #endregion + + #region PaddingTop + + /// + /// Gets or sets the top padding in pixels. + /// + [Browsable(true), DefaultValue(0), Category("Layout")] + [Description("Indicates top padding in pixels.")] + public int PaddingTop + { + get { return (_LabelX.PaddingTop); } + set { _LabelX.PaddingTop = value; } + } + + #endregion + + #region PaddingRight + + /// + /// Gets or sets the right padding in pixels. + /// + [Browsable(true), DefaultValue(0), Category("Layout")] + [Description("Indicates right padding in pixels.")] + public int PaddingRight + { + get { return (_LabelX.PaddingRight); } + set { _LabelX.PaddingRight = value; } + } + + #endregion + + #region SingleLineColor + + /// + /// Gets or sets the border line color when border is single line. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates border line color when border is single line.")] + public Color SingleLineColor + { + get { return (_LabelX.SingleLineColor); } + set { _LabelX.SingleLineColor = value; } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSingleLineColor() + { + return (_LabelX.ShouldSerializeSingleLineColor()); + } + + /// + /// Resets the SingleLineColor property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSingleLineColor() + { + _LabelX.ResetSingleLineColor(); + } + + #endregion + + #region Text + + /// + /// Gets or sets the text associated with this item. + /// + [Browsable(true), Category("Appearance")] + [Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + [Description("The text contained in the item.")] + public new string Text + { + get + { + return (_InCellCallBack == true ? + _LabelX.Text : base.Text); + } + + set + { + if (_InCellCallBack == true) + _LabelX.Text = value; + else + base.Text = value; + } + } + + #endregion + + #region TextAlignment + + /// + /// Gets or sets the horizontal text alignment. + /// + [Browsable(true), DefaultValue(StringAlignment.Near), DevCoBrowsable(true), Category("Layout")] + [Description("Indicates the horizontal text alignment.")] + public StringAlignment TextAlignment + { + get { return (_LabelX.TextAlignment); } + set { _LabelX.TextAlignment = value; } + } + + #endregion + + #region TextLineAlignment + + /// + /// Gets or sets the vertical text alignment. + /// + [Browsable(true), DefaultValue(StringAlignment.Center), DevCoBrowsable(true), Category("Layout")] + [Description("Indicates vertical text line alignment.")] + public StringAlignment TextLineAlignment + { + get { return (_LabelX.TextLineAlignment); } + set { _LabelX.TextLineAlignment = value; } + } + + #endregion + + #region UseMnemonic + + /// + /// Gets or sets a value indicating whether the control interprets an + /// ampersand character (&) in the control's Text property to be an + /// access key prefix character. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the control interprets an ampersand character (&) in the control's Text property to be an access key prefix character.")] + public bool UseMnemonic + { + get { return (_LabelX.UseMnemonic); } + set { _LabelX.UseMnemonic = value; } + } + + #endregion + + #region WordWrap + + /// + /// Gets or sets a value that determines whether text is displayed in multiple lines or one long line. + /// + [Browsable(true), Category("Style"), DefaultValue(false)] + [Description("Indicates whether text is displayed in multiple lines or one long line.")] + public bool WordWrap + { + get { return (_LabelX.WordWrap); } + set { _LabelX.WordWrap = value; } + } + + #endregion + + #endregion + + #region HookEvents + + /// + /// Hooks or unhooks our system events + /// + /// + private void HookEvents(bool hook) + { + if (hook == true) + { + _LabelX.LabelItem.Click += LabelItemClick; + } + else + { + _LabelX.LabelItem.Click -= LabelItemClick; + } + } + + #endregion + + #region Event processing + + #region LabelItem_Click + + /// + /// LabelItem_Click + /// + /// + /// + void LabelItemClick(object sender, EventArgs e) + { + if (Click != null) + Click(sender, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the LabelX Column + /// + /// + public override object Clone() + { + DataGridViewLabelXColumn bc = base.Clone() as DataGridViewLabelXColumn; + + if (bc != null) + { + _LabelX.LabelItem.InternalCopyToItem(bc.LabelX.LabelItem); + + bc.FocusCuesEnabled = FocusCuesEnabled; + bc.Text = Text; + bc.UseMnemonic = UseMnemonic; + } + + return (bc); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the ButtonX control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + HookEvents(false); + + if (disposing == true) + _LabelX.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewMaskedTextBoxAdv/DataGridViewMaskedTextBoxAdvCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewMaskedTextBoxAdv/DataGridViewMaskedTextBoxAdvCell.cs new file mode 100644 index 00000000..66d58574 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewMaskedTextBoxAdv/DataGridViewMaskedTextBoxAdvCell.cs @@ -0,0 +1,790 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewMaskedTextBoxAdvCell : DataGridViewTextBoxCell + { + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] + static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam); + + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (typeof(DataGridViewMaskedTextBoxAdvEditingControl)); } + } + + #endregion + + #endregion + + #region InitializeEditingControl + + /// + /// InitializeEditingControl + /// + /// + /// + /// + public override void InitializeEditingControl(int rowIndex, + object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) + { + DetachEditingControl(); + + base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); + + DataGridViewMaskedTextBoxAdvEditingControl ctl = + (DataGridViewMaskedTextBoxAdvEditingControl) DataGridView.EditingControl; + + DataGridViewMaskedTextBoxAdvColumn oc = OwningColumn as DataGridViewMaskedTextBoxAdvColumn; + + if (oc != null) + { + MaskedTextBoxAdv tb = oc.MaskedTextBoxAdv; + + ctl.AllowPromptAsInput = tb.AllowPromptAsInput; + ctl.AsciiOnly = tb.AsciiOnly; + ctl.BeepOnError = false; + ctl.Culture = tb.Culture; + ctl.CutCopyMaskFormat = tb.CutCopyMaskFormat; + ctl.DropDownControl = tb.DropDownControl; + ctl.Enabled = tb.Enabled; + ctl.FocusHighlightColor = tb.FocusHighlightColor; + ctl.FocusHighlightEnabled = tb.FocusHighlightEnabled; + ctl.HidePromptOnLeave = tb.HidePromptOnLeave; + ctl.ImeMode = tb.ImeMode; + ctl.InsertKeyMode = tb.InsertKeyMode; + ctl.Mask = tb.Mask; + ctl.PasswordChar = tb.PasswordChar; + ctl.PromptChar = tb.PromptChar; + ctl.RejectInputOnFirstFailure = tb.RejectInputOnFirstFailure; + ctl.ResetOnPrompt = tb.ResetOnPrompt; + ctl.ResetOnSpace = tb.ResetOnSpace; + ctl.RightToLeft = tb.RightToLeft; + ctl.SkipLiterals = tb.SkipLiterals; + ctl.TextAlign = GetTextAlignment(dataGridViewCellStyle.Alignment); + ctl.TextMaskFormat = tb.TextMaskFormat; + ctl.UseSystemPasswordChar = tb.UseSystemPasswordChar; + ctl.ValidatingType = tb.ValidatingType; + ctl.WatermarkBehavior = tb.WatermarkBehavior; + ctl.WatermarkColor = tb.WatermarkColor; + ctl.WatermarkEnabled = tb.WatermarkEnabled; + ctl.WatermarkFont = tb.WatermarkFont; + ctl.WatermarkText = tb.WatermarkText; + + // The underlying MaskedTextBox's MultiLine property + // is "not fully supported" - but we'll set it anyway. + + ctl.MaskedTextBox.Multiline = (dataGridViewCellStyle.WrapMode == DataGridViewTriState.True); + + ctl.BackgroundStyle.ApplyStyle(tb.BackgroundStyle); + ctl.BackgroundStyle.Class = tb.BackgroundStyle.Class; + + tb.ButtonClear.CopyToItem(ctl.ButtonClear); + tb.ButtonCustom.CopyToItem(ctl.ButtonCustom); + tb.ButtonCustom2.CopyToItem(ctl.ButtonCustom2); + tb.ButtonDropDown.CopyToItem(ctl.ButtonDropDown); + + ctl.ButtonClearClick += ButtonClearClick; + ctl.ButtonCustomClick += ButtonCustomClick; + ctl.ButtonCustom2Click += ButtonCustom2Click; + ctl.ButtonDropDownClick += ButtonDropDownClick; + ctl.KeyDown += KeyDown; + + ctl.Text = GetValue(initialFormattedValue); + + ctl.BeepOnError = tb.BeepOnError; + } + } + + #endregion + + #region DetachEditingControl + + /// + /// DetachEditingControl + /// + public override void DetachEditingControl() + { + if (DataGridView != null && DataGridView.EditingControl != null) + { + DataGridViewMaskedTextBoxAdvEditingControl di = + DataGridView.EditingControl as DataGridViewMaskedTextBoxAdvEditingControl; + + if (di != null) + { + di.ButtonClearClick -= ButtonClearClick; + di.ButtonCustomClick -= ButtonCustomClick; + di.ButtonCustom2Click -= ButtonCustom2Click; + di.ButtonDropDownClick -= ButtonDropDownClick; + di.KeyDown -= KeyDown; + } + } + + base.DetachEditingControl(); + } + + #endregion + + #region Event processing + + #region ButtonClearClick + + /// + /// ButtonClearClick + /// + /// + /// + void ButtonClearClick(object sender, CancelEventArgs e) + { + ((DataGridViewMaskedTextBoxAdvColumn)OwningColumn).DoButtonClearClick(sender, e); + } + + #endregion + + #region ButtonCustomClick + + /// + /// ButtonCustomClick + /// + /// + /// + void ButtonCustomClick(object sender, EventArgs e) + { + ((DataGridViewMaskedTextBoxAdvColumn)OwningColumn).DoButtonCustomClick(sender, e); + } + + #endregion + + #region ButtonCustom2Click + + /// + /// ButtonCustom2Click + /// + /// + /// + void ButtonCustom2Click(object sender, EventArgs e) + { + ((DataGridViewMaskedTextBoxAdvColumn)OwningColumn).DoButtonCustom2Click(sender, e); + } + + #endregion + + #region ButtonDropDownClick + + /// + /// ButtonDropDownClick + /// + /// + /// + void ButtonDropDownClick(object sender, CancelEventArgs e) + { + ((DataGridViewMaskedTextBoxAdvColumn)OwningColumn).DoButtonDropDownClick(sender, e); + } + + #endregion + + #region KeyDown + + /// + /// KeyDown routine forwards all DataGridView sent keys to + /// the underlying focusable control + /// + /// + /// + void KeyDown(object sender, KeyEventArgs e) + { + if (DataGridView != null && DataGridView.EditingControl != null) + { + DataGridViewMaskedTextBoxAdvEditingControl di = + DataGridView.EditingControl as DataGridViewMaskedTextBoxAdvEditingControl; + + if (di != null) + { + di.MaskedTextBox.SelectAll(); + + PostMessage(di.MaskedTextBox.Handle, 256, (int) e.KeyCode, 1); + } + } + } + + #endregion + + #endregion + + #region PositionEditingControl + + /// + /// PositionEditingControl + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public override void PositionEditingControl(bool setLocation, bool setSize, Rectangle cellBounds, + Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, + bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) + { + Rectangle editingControlBounds = + PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, + singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow); + + editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle); + + DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y); + DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height); + } + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetCellBounds(editingControlBounds); + + if (cellStyle.WrapMode != DataGridViewTriState.True) + { + if (r.Height < editingControlBounds.Height) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.MiddleLeft: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height)/2; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + editingControlBounds.Height = Math.Max(1, r.Height); + } + + editingControlBounds.Width = Math.Max(1, editingControlBounds.Width); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + #region GetPreferredSize + + /// + /// GetPreferredSize + /// + /// + /// + /// + /// + /// + protected override Size GetPreferredSize(Graphics graphics, + DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + { + if (DataGridView == null) + return (new Size(-1, -1)); + + Size preferredSize = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize); + + DataGridViewMaskedTextBoxAdvColumn oc = OwningColumn as DataGridViewMaskedTextBoxAdvColumn; + + if (oc != null) + { + MaskedTextBoxAdv msk = oc.MaskedTextBoxAdv; + + preferredSize.Height = msk.Height; + + if (constraintSize.Width == 0) + { + preferredSize.Width += GetImageWidth(msk.ButtonClear); + preferredSize.Width += GetImageWidth(msk.ButtonCustom); + preferredSize.Width += GetImageWidth(msk.ButtonCustom2); + preferredSize.Width += GetImageWidth(msk.ButtonDropDown); + } + } + + return (preferredSize); + } + + #endregion + + #region GetFormattedValue + + protected override object GetFormattedValue(object value, int rowIndex, + ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, + TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) + { + DataGridViewMaskedTextBoxAdvColumn oc = OwningColumn as DataGridViewMaskedTextBoxAdvColumn; + + if (oc != null) + { + MaskedTextBoxAdv msk = oc.MaskedTextBoxAdv; + msk.Text = GetValue(value); + + return (msk.Text); + } + + return (base.GetFormattedValue(value, rowIndex, + ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context)); + } + + #endregion + + #region GetImageWidth + + private int GetImageWidth(InputButtonSettings ibs) + { + if (ibs.Visible == true) + return (ibs.Image != null ? ibs.Image.Width : 16); + + return (0); + } + + #endregion + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, + DataGridViewElementStates elementState, object value, object formattedValue, + string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, + DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewMaskedTextBoxAdvColumn oc = (DataGridViewMaskedTextBoxAdvColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintCellBackground(g, cellStyle, rBk); + PaintCellContent(g, cellBounds, rowIndex, formattedValue, cellStyle, paintParts, bm); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintCellBackground + + /// + /// Paints the cell background + /// + /// + /// + /// + private void PaintCellBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintCellContent + + /// + /// Paints the cell content + /// + /// + /// + /// + /// + /// + /// + /// + private void PaintCellContent(Graphics g, Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, Bitmap bm) + { + DataGridViewMaskedTextBoxAdvColumn oc = (DataGridViewMaskedTextBoxAdvColumn)OwningColumn; + MaskedTextBoxAdv di = oc.MaskedTextBoxAdv; + + Point ptCurrentCell = DataGridView.CurrentCellAddress; + bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex; + bool cellEdited = cellCurrent && DataGridView.EditingControl != null; + + // If the cell is in editing mode, there is nothing else to paint + + if (cellEdited == false && rowIndex < DataGridView.RowCount) + { + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + { + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + di.Font = cellStyle.Font; + di.ForeColor = cellStyle.ForeColor; + di.BackColor = cellStyle.BackColor; + + di.TextAlign = GetTextAlignment(cellStyle.Alignment); + di.Text = GetValue(value); + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + + if (oc.DisplayControlForCurrentCellOnly == false) + DrawControl(di, cellStyle, r, bm, g, oc); + else + DrawText(di, cellStyle, r, g); + } + } + } + + #region DrawControl + + /// + /// DrawControl + /// + /// + /// + /// + /// + /// + /// + private void DrawControl(MaskedTextBoxAdv di, DataGridViewCellStyle cellStyle, Rectangle r, + Bitmap bm, Graphics g, DataGridViewMaskedTextBoxAdvColumn oc) + { + if (di.ButtonGroup.Items.Count > 0) + { + // Determine if we must perform some tom-foolery in order + // to get the control to DrawToBitmap correctly in older + // Windows versions + + if (MustRenderVisibleControl() == true) + { + di.Location = oc.DataGridView.Location; + + if (di.Parent == null) + { + Form form = oc.DataGridView.FindForm(); + + if (form != null) + di.Parent = form; + } + + di.SendToBack(); + di.Visible = true; + } + + using (Bitmap bm2 = new Bitmap(bm)) + { + di.Bounds = r; + di.DrawToBitmap(bm2, r); + + foreach (VisualItem item in di.ButtonGroup.Items) + { + if (item.Visible == true) + { + Rectangle t = item.RenderBounds; + t.X += r.X; + t.Y += r.Y; + + g.DrawImage(bm2, t, t, GraphicsUnit.Pixel); + + if (t.Left < r.Right) + r.Width -= (r.Right - t.Left - 1); + } + } + } + + di.Visible = false; + } + + DrawText(di, cellStyle, r, g); + } + + #endregion + + #region DrawText + + /// + /// DrawText + /// + /// + /// + /// + /// + private void DrawText(MaskedTextBoxAdv di, DataGridViewCellStyle cellStyle, Rectangle r, Graphics g) + { + r.Inflate(-2, 0); + + eTextFormat tf = eTextFormat.Default | eTextFormat.NoPrefix; + + switch (di.TextAlign) + { + case HorizontalAlignment.Center: + tf |= eTextFormat.HorizontalCenter; + break; + + case HorizontalAlignment.Right: + tf |= eTextFormat.Right; + break; + } + + if (cellStyle.WrapMode == DataGridViewTriState.True) + tf |= eTextFormat.WordBreak; + + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.TopLeft: + case DataGridViewContentAlignment.TopCenter: + case DataGridViewContentAlignment.TopRight: + tf |= eTextFormat.Top; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + tf |= eTextFormat.Bottom; + break; + + default: + tf |= eTextFormat.VerticalCenter; + break; + } + + DataGridViewMaskedTextBoxAdvColumn oc = (DataGridViewMaskedTextBoxAdvColumn)OwningColumn; + + string text = di.Text; + + if (oc.PasswordChar != '\0') + text = "".PadRight(text.Length, oc.PasswordChar); + + TextDrawing.DrawString(g, text, di.Font, di.ForeColor, r, tf); + } + + #endregion + + #endregion + + #endregion + + #region MustRenderVisibleControl + + /// + /// MustRenderVisibleControl + /// + /// + private bool MustRenderVisibleControl() + { + OperatingSystem osInfo = Environment.OSVersion; + + return (osInfo.Platform == PlatformID.Win32Windows || + (osInfo.Platform == PlatformID.Win32NT && osInfo.Version.Major < 6)); + + } + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewMaskedTextBoxAdvColumn oc = (DataGridViewMaskedTextBoxAdvColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + #endregion + + #region GetCellBounds + + /// + /// Gets the button bounds for the given cell + /// + /// + /// + private Rectangle GetCellBounds(Rectangle cellBounds) + { + DataGridViewMaskedTextBoxAdvColumn oc = (DataGridViewMaskedTextBoxAdvColumn)OwningColumn; + + Size size = oc.MaskedTextBoxAdv.PreferredSize; + + cellBounds.Location = new Point(1, 1); + + cellBounds.Width -= oc.DividerWidth; + cellBounds.Height = size.Height - 1; + + return (cellBounds); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + private string GetValue(object value) + { + return ((value != Convert.DBNull ? Convert.ToString(value) : "")); + } + + #endregion + + #region GetTextAlignment + + /// + /// GetTextAlignment + /// + /// + /// + private HorizontalAlignment GetTextAlignment(DataGridViewContentAlignment alignment) + { + switch (alignment) + { + case DataGridViewContentAlignment.TopCenter: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.BottomCenter: + return (HorizontalAlignment.Center); + + case DataGridViewContentAlignment.TopRight: + case DataGridViewContentAlignment.MiddleRight: + case DataGridViewContentAlignment.BottomRight: + return (HorizontalAlignment.Right); + + default: + return (HorizontalAlignment.Left); + } + } + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewMaskedTextBoxAdv/DataGridViewMaskedTextBoxAdvColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewMaskedTextBoxAdv/DataGridViewMaskedTextBoxAdvColumn.cs new file mode 100644 index 00000000..c5503143 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewMaskedTextBoxAdv/DataGridViewMaskedTextBoxAdvColumn.cs @@ -0,0 +1,924 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewMaskedTextBoxAdvColumn), "Controls.MaskedTextBoxAdv.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewMaskedTextBoxAdvColumn : DataGridViewTextBoxColumn, IDataGridViewColumn + { + #region Events + + /// + /// Occurs right before a MaskedTextBoxAdv Cell is painted + /// + [Description("Occurs right before a MaskedTextBoxAdv Cell is painted.")] + public event EventHandler BeforeCellPaint; + + /// + /// Occurs when Clear button is clicked and allows you + /// to cancel the default action performed by the button + /// + [Description("Occurs when Clear button is clicked and allows you to cancel the default action performed by the button.")] + public event EventHandler ButtonClearClick; + + /// + /// Occurs when ButtonCustom control is clicked + /// + [Description("Occurs when ButtonCustom control is clicked.")] + public event EventHandler ButtonCustomClick; + + /// + /// Occurs when ButtonCustom2 control is clicked + /// + [Description("Occurs when ButtonCustom2 control is clicked.")] + public event EventHandler ButtonCustom2Click; + + /// + /// Occurs when Drop-Down button is clicked and allows you to cancel showing of the popup + /// + [Description("Occurs when Drop-Down button is clicked and allows you to cancel showing of the popup.")] + public event EventHandler ButtonDropDownClick; + + #endregion + + #region Private variables + + private MaskedTextBoxAdv _MaskedTextBoxAdv; + private Bitmap _CellBitmap; + private bool _DisplayControlForCurrentCellOnly = true; + + #endregion + + /// + /// Constructor + /// + public DataGridViewMaskedTextBoxAdvColumn() + { + CellTemplate = new DataGridViewMaskedTextBoxAdvCell(); + + _MaskedTextBoxAdv = new MaskedTextBoxAdv(); + + _MaskedTextBoxAdv.BackgroundStyle.Class = ElementStyleClassKeys.DataGridViewBorderKey; + } + + #region Internal properties + + #region MaskedTextBoxAdv + + /// + /// Gets the underlying MaskedTextBoxAdv control + /// + [Browsable(false)] + internal MaskedTextBoxAdv MaskedTextBoxAdv + { + get { return (_MaskedTextBoxAdv); } + } + + #endregion + + #endregion + + #region Public properties + + #region AllowPromptAsInput + + /// + /// Gets or sets a value indicating whether PromptChar can be entered as valid data. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether PromptChar can be entered as valid data.")] + public bool AllowPromptAsInput + { + get { return (_MaskedTextBoxAdv.AllowPromptAsInput); } + set { _MaskedTextBoxAdv.AllowPromptAsInput = value; } + } + + #endregion + + #region AsciiOnly + + /// + /// Gets or sets a value indicating whether characters outside of the ASCII character set will be accepted. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether whether characters outside of the ASCII character set will be accepted.")] + public bool AsciiOnly + { + get { return (_MaskedTextBoxAdv.AsciiOnly); } + set { _MaskedTextBoxAdv.AsciiOnly = value; } + } + + #endregion + + #region BackColor + + /// + /// Gets or sets the Background color. + /// + [Browsable(false)] + public Color BackColor + { + get { return (_MaskedTextBoxAdv.BackColor); } + set { _MaskedTextBoxAdv.BackColor = value; } + } + + #endregion + + #region BackgroundStyle + + /// + /// Specifies the background style of the control. + /// + [Browsable(true), Category("Style")] + [Description("Gets or sets control background style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return (_MaskedTextBoxAdv.BackgroundStyle); } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _MaskedTextBoxAdv.ResetBackgroundStyle(); + + _MaskedTextBoxAdv.BackgroundStyle.Class = "TextBoxBorder"; + _MaskedTextBoxAdv.BackgroundStyle.CornerType = eCornerType.Square; + } + + #endregion + + #region BeepOnError + + /// + /// Gets or sets a value indicating whether the masked text box + /// control raises the system beep for each user key stroke that it rejects. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether the masked text box control raises the system beep for each user key stroke that it rejects.")] + public bool BeepOnError + { + get { return (_MaskedTextBoxAdv.BeepOnError); } + set { _MaskedTextBoxAdv.BeepOnError = value; } + } + + #endregion + + #region ButtonClear + + /// + /// Gets the object that describes the settings for the button + /// that clears the content of the control when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that clears the content of the control when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonClear + { + get { return (_MaskedTextBoxAdv.ButtonClear); } + } + + #endregion + + #region ButtonCustom + + /// + /// Gets the object that describes the settings for the custom button + /// that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get { return (_MaskedTextBoxAdv.ButtonCustom); } + } + + #endregion + + #region ButtonCustom2 + + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get { return (_MaskedTextBoxAdv.ButtonCustom2); } + } + + #endregion + + #region ButtonDropDown + + /// + /// Gets the object that describes the settings for the button + /// that shows drop-down when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that shows drop-down when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonDropDown + { + get { return (_MaskedTextBoxAdv.ButtonDropDown); } + } + + #endregion + + #region Culture + + /// + /// Gets or sets the culture information associated with the masked text box. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates the culture information associated with the masked text box.")] + public CultureInfo Culture + { + get { return (_MaskedTextBoxAdv.Culture); } + set { _MaskedTextBoxAdv.Culture = value; } + } + + #endregion + + #region CutCopyMaskFormat + + /// + /// Gets or sets a value that determines whether + /// literals and prompt characters are copied to the clipboard + /// + [Browsable(true), DefaultValue(MaskFormat.IncludeLiterals)] + [Description("Indicates whether literals and prompt characters are copied to the clipboard.")] + public MaskFormat CutCopyMaskFormat + { + get { return (_MaskedTextBoxAdv.CutCopyMaskFormat); } + set { _MaskedTextBoxAdv.CutCopyMaskFormat = value; } + } + + #endregion + + #region DisplayControlForCurrentCellOnly + + /// + /// Gets or sets whether the control + /// will be displayed for the current cell only. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the control will be displayed for the current cell only.")] + public bool DisplayControlForCurrentCellOnly + { + get { return (_DisplayControlForCurrentCellOnly); } + + set + { + if (_DisplayControlForCurrentCellOnly != value) + { + _DisplayControlForCurrentCellOnly = value; + _MaskedTextBoxAdv.Invalidate(); + } + } + } + + #endregion + + #region DropDownControl + + /// + /// Gets or sets the reference of the control that will be + /// displayed on popup that is shown when the drop-down button is clicked. + /// + [DefaultValue(null)] + [Description("Indicates reference of the control that will be displayed on popup that is shown when the drop-down button is clicked.")] + public Control DropDownControl + { + get { return (_MaskedTextBoxAdv.DropDownControl); } + set { _MaskedTextBoxAdv.DropDownControl = value; } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_MaskedTextBoxAdv.Enabled); } + set { _MaskedTextBoxAdv.Enabled = value; } + } + + #endregion + + #region FocusHighlightColor + + /// + /// Gets or sets the color used as background color to highlight + /// the text box when it has input focus and FocusHighlight is enabled. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates color used as background color to highlight the text box when it has input focus and FocusHighlight is enabled.")] + public Color FocusHighlightColor + { + get { return (_MaskedTextBoxAdv.FocusHighlightColor); } + set { _MaskedTextBoxAdv.FocusHighlightColor = value; } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFocusHighlightColor() + { + return (_MaskedTextBoxAdv.ShouldSerializeFocusHighlightColor()); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFocusHighlightColor() + { + _MaskedTextBoxAdv.ResetFocusHighlightColor(); + } + + #endregion + + #region FocusHighlightEnabled + + /// + /// Gets or sets whether FocusHighlightColor is used as + /// background color to highlight the text box when it has + /// input focus. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Appearance")] + [Description("Indicates whether FocusHighlightColor is used as background color to highlight the text box when it has input focus.")] + public bool FocusHighlightEnabled + { + get { return (_MaskedTextBoxAdv.FocusHighlightEnabled); } + set { _MaskedTextBoxAdv.FocusHighlightEnabled = value; } + } + + #endregion + + #region ForeColor + + /// + /// Gets or sets the foreground color. + /// + [Browsable(false)] + public Color ForeColor + { + get { return (_MaskedTextBoxAdv.ForeColor); } + set { _MaskedTextBoxAdv.ForeColor = value; } + } + + #endregion + + #region HidePromptOnLeave + + /// + /// Gets or sets a value indicating whether the prompt characters + /// in the input mask are hidden when the masked text box loses focus. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether the prompt characters in the input mask are hidden when the masked text box loses focus.")] + public bool HidePromptOnLeave + { + get { return (_MaskedTextBoxAdv.HidePromptOnLeave); } + set { _MaskedTextBoxAdv.HidePromptOnLeave = value; } + } + + #endregion + + #region ImeMode + + /// + /// Gets or sets the Input Method Editor (IME) mode of the control. + /// + [Browsable(true), DefaultValue(ImeMode.Inherit)] + [Description("Indicates the Input Method Editor (IME) mode of the control.")] + public ImeMode ImeMode + { + get { return (_MaskedTextBoxAdv.ImeMode); } + set { _MaskedTextBoxAdv.ImeMode = value; } + } + + #endregion + + #region InsertKeyMode + + /// + /// Gets or sets the text insertion mode of the masked text box control. + /// + [Browsable(true), DefaultValue(InsertKeyMode.Default)] + [Description("Indicates the text insertion mode of the masked text box control.")] + public InsertKeyMode InsertKeyMode + { + get { return (_MaskedTextBoxAdv.InsertKeyMode); } + set { _MaskedTextBoxAdv.InsertKeyMode = value; } + } + + #endregion + + #region Mask + + /// + /// Gets or sets the input mask to use at run time. + /// + [Browsable(true), DefaultValue(null)] + [Description("Indicates the input mask to use at run time.")] + public string Mask + { + get { return (_MaskedTextBoxAdv.Mask); } + set { _MaskedTextBoxAdv.Mask = value; } + } + + #endregion + + #region PasswordChar + + /// + /// Gets or sets the character to be displayed in substitute for user input. + /// + [Browsable(true), DefaultValue(null)] + [Description("Indicates the character to be displayed in substitute for user input.")] + public char PasswordChar + { + get { return (_MaskedTextBoxAdv.PasswordChar); } + set { _MaskedTextBoxAdv.PasswordChar = value; } + } + + #endregion + + #region PromptChar + + /// + /// Gets or sets the character used to represent the absence of user input. + /// + [Browsable(true), DefaultValue('_')] + [Description("Indicates the character used to represent the absence of user input.")] + public char PromptChar + { + get { return (_MaskedTextBoxAdv.PromptChar); } + set { _MaskedTextBoxAdv.PromptChar = value; } + } + + #endregion + + #region RejectInputOnFirstFailure + + /// + /// Gets or sets a value indicating whether the parsing of + /// user input should stop after the first invalid character is reached. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates the parsing of user input should stop after the first invalid character is reached.")] + public bool RejectInputOnFirstFailure + { + get { return (_MaskedTextBoxAdv.RejectInputOnFirstFailure); } + set { _MaskedTextBoxAdv.RejectInputOnFirstFailure = value; } + } + + #endregion + + #region ResetOnPrompt + + /// + /// Gets or sets a value that determines how an input + /// character that matches the prompt character should be handled. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates how an input character that matches the prompt character should be handled.")] + public bool ResetOnPrompt + { + get { return (_MaskedTextBoxAdv.ResetOnPrompt); } + set { _MaskedTextBoxAdv.ResetOnPrompt = value; } + } + + #endregion + + #region ResetOnSpace + + /// + /// Gets or sets a value that determines how + /// a space input character should be handled. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates how a space input character should be handled.")] + public bool ResetOnSpace + { + get { return (_MaskedTextBoxAdv.ResetOnSpace); } + set { _MaskedTextBoxAdv.ResetOnSpace = value; } + } + + #endregion + + #region RightToLeft + + /// + /// Gets or sets a value indicating whether control's + /// elements are aligned to support locales using right-to-left fonts. + /// + [Browsable(true), DefaultValue(RightToLeft.Inherit)] + [Description("Indicates the control's elements are aligned to support locales using right-to-left fonts.")] + public RightToLeft RightToLeft + { + get { return (_MaskedTextBoxAdv.RightToLeft); } + set { _MaskedTextBoxAdv.RightToLeft = value; } + } + + #endregion + + #region SkipLiterals + + /// + /// Gets or sets a value indicating + /// whether the user is allowed to reenter literal values. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates the user is allowed to reenter literal values.")] + public bool SkipLiterals + { + get { return (_MaskedTextBoxAdv.SkipLiterals); } + set { _MaskedTextBoxAdv.SkipLiterals = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the text as it is currently displayed to the user. + /// + [Browsable(false)] + public string Text + { + get { return (_MaskedTextBoxAdv.Text); } + set { _MaskedTextBoxAdv.Text = value; } + } + + #endregion + + #region TextAlign + + /// + /// Gets or sets how text is aligned in a masked text box control. + /// + [Browsable(true), DefaultValue(HorizontalAlignment.Left)] + [Description("Indicates how text is aligned in a masked text box control.")] + public HorizontalAlignment TextAlign + { + get { return (_MaskedTextBoxAdv.TextAlign); } + set { _MaskedTextBoxAdv.TextAlign = value; } + } + + #endregion + + #region TextMaskFormat + + /// + /// Gets or sets a value that determines whether literals + /// and prompt characters are included in the formatted string. + /// + [Browsable(true), DefaultValue(MaskFormat.IncludeLiterals)] + [Description("Indicates whether literals and prompt characters are included in the formatted string.")] + public MaskFormat TextMaskFormat + { + get { return (_MaskedTextBoxAdv.TextMaskFormat); } + set { _MaskedTextBoxAdv.TextMaskFormat = value; } + } + + #endregion + + #region UseSystemPasswordChar + + /// + /// Gets or sets a value indicating whether + /// the operating system-supplied password character should be used. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether the operating system-supplied password character should be used.")] + public bool UseSystemPasswordChar + { + get { return (_MaskedTextBoxAdv.UseSystemPasswordChar); } + set { _MaskedTextBoxAdv.UseSystemPasswordChar = value; } + } + + #endregion + + #region ValidatingType + + /// + /// Gets or sets the data type used to verify the data input by the user. + /// + [Browsable(false), DefaultValue(null)] + [Description("Indicates the data type used to verify the data input by the user.")] + public Type ValidatingType + { + get { return (_MaskedTextBoxAdv.ValidatingType); } + set { _MaskedTextBoxAdv.ValidatingType = value; } + } + + #endregion + + #region WatermarkBehavior + + /// + /// Gets or sets the watermark hiding behaviour. Default value + /// indicates that watermark is hidden when control receives input focus. + /// + [Browsable(true), DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior")] + [Description("Indicates watermark hiding behaviour.")] + public eWatermarkBehavior WatermarkBehavior + { + get { return (_MaskedTextBoxAdv.WatermarkBehavior); } + set { _MaskedTextBoxAdv.WatermarkBehavior = value; } + } + + #endregion + + #region WatermarkColor + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return (_MaskedTextBoxAdv.WatermarkColor); } + set { _MaskedTextBoxAdv.WatermarkColor = value; } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return (_MaskedTextBoxAdv.ShouldSerializeWatermarkColor()); + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + _MaskedTextBoxAdv.ResetWatermarkColor(); + } + + #endregion + + #region WatermarkEnabled + + /// + /// Gets or sets whether watermark text is + /// displayed when control is empty. Default value is true. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return (_MaskedTextBoxAdv.WatermarkEnabled); } + set { _MaskedTextBoxAdv.WatermarkEnabled = value; } + } + + #endregion + + #region WatermarkFont + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates watermark font.")] + public Font WatermarkFont + { + get { return (_MaskedTextBoxAdv.WatermarkFont); } + set { _MaskedTextBoxAdv.WatermarkFont = value; } + } + + #endregion + + #region WatermarkText + + /// + /// Gets or sets the watermark (tip) text displayed inside of + /// the control when Text is not set and control does not have + /// input focus. This property supports text-markup. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus.")] + [Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string WatermarkText + { + get { return (_MaskedTextBoxAdv.WatermarkText); } + set { _MaskedTextBoxAdv.WatermarkText = value; } + } + + #endregion + + #endregion + + #region Event processing + + #region DoButtonClearClick + + /// + /// DoButtonClearClick + /// + /// + /// + internal void DoButtonClearClick(object sender, CancelEventArgs e) + { + if (ButtonClearClick != null) + ButtonClearClick(this, e); + } + + #endregion + + #region DoButtonCustomClick + + /// + /// DoButtonCustomClick + /// + /// + /// + internal void DoButtonCustomClick(object sender, EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + #endregion + + #region DoButtonCustom2Click + + /// + /// DoButtonCustom2Click + /// + /// + /// + internal void DoButtonCustom2Click(object sender, EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + #endregion + + #region DoButtonDropDownClick + + /// + /// DoButtonDropDownClick + /// + /// + /// + internal void DoButtonDropDownClick(object sender, CancelEventArgs e) + { + if (ButtonDropDownClick != null) + ButtonDropDownClick(this, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewMaskedTextBoxAdvColumn dc = base.Clone() as DataGridViewMaskedTextBoxAdvColumn; + + if (dc != null) + { + dc.AllowPromptAsInput = AllowPromptAsInput; + dc.AsciiOnly = AsciiOnly; + dc.BeepOnError = BeepOnError; + dc.Culture = Culture; + dc.CutCopyMaskFormat = CutCopyMaskFormat; + dc.DropDownControl = DropDownControl; + dc.Enabled = Enabled; + dc.FocusHighlightColor = FocusHighlightColor; + dc.FocusHighlightEnabled = FocusHighlightEnabled; + dc.HidePromptOnLeave = HidePromptOnLeave; + dc.ImeMode = ImeMode; + dc.InsertKeyMode = InsertKeyMode; + dc.Mask = Mask; + dc.PasswordChar = PasswordChar; + dc.PromptChar = PromptChar; + dc.RejectInputOnFirstFailure = RejectInputOnFirstFailure; + dc.ResetOnPrompt = ResetOnPrompt; + dc.ResetOnSpace = ResetOnSpace; + dc.RightToLeft = RightToLeft; + dc.SkipLiterals = SkipLiterals; + dc.TextAlign = TextAlign; + dc.TextMaskFormat = TextMaskFormat; + dc.UseSystemPasswordChar = UseSystemPasswordChar; + dc.ValidatingType = ValidatingType; + dc.WatermarkBehavior = WatermarkBehavior; + dc.WatermarkColor = WatermarkColor; + dc.WatermarkEnabled = WatermarkEnabled; + dc.WatermarkFont = WatermarkFont; + dc.WatermarkText = WatermarkText; + + dc.DisplayControlForCurrentCellOnly = DisplayControlForCurrentCellOnly; + + dc.BackgroundStyle.ApplyStyle(MaskedTextBoxAdv.BackgroundStyle); + dc.BackgroundStyle.Class = MaskedTextBoxAdv.BackgroundStyle.Class; + + MaskedTextBoxAdv.ButtonClear.CopyToItem(dc.MaskedTextBoxAdv.ButtonClear); + MaskedTextBoxAdv.ButtonDropDown.CopyToItem(dc.MaskedTextBoxAdv.ButtonDropDown); + MaskedTextBoxAdv.ButtonCustom.CopyToItem(dc.MaskedTextBoxAdv.ButtonCustom); + MaskedTextBoxAdv.ButtonCustom2.CopyToItem(dc.MaskedTextBoxAdv.ButtonCustom2); + } + + return (dc); + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + if (disposing == true) + _MaskedTextBoxAdv.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewMaskedTextBoxAdv/DataGridViewMaskedTextBoxAdvEditingControl.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewMaskedTextBoxAdv/DataGridViewMaskedTextBoxAdvEditingControl.cs new file mode 100644 index 00000000..74df2d7f --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewMaskedTextBoxAdv/DataGridViewMaskedTextBoxAdvEditingControl.cs @@ -0,0 +1,185 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), ComVisible(false)] + public class DataGridViewMaskedTextBoxAdvEditingControl : MaskedTextBoxAdv, IDataGridViewEditingControl + { + #region Private variables + + private DataGridView _DataGridView; + + private int _RowIndex; + private bool _ValueChanged; + + #endregion + + #region OnTextChanged + + /// + /// Handles OnTextChanged events + /// + /// + protected override void OnTextChanged(EventArgs e) + { + _ValueChanged = true; + + _DataGridView.NotifyCurrentCellDirty(true); + + base.OnTextChanged(e); + } + + #endregion + + #region IDataGridViewEditingControl Members + + #region Public properties + + #region EditingControlDataGridView + + /// + /// Gets or sets the DataGridView + /// + public DataGridView EditingControlDataGridView + { + get { return (_DataGridView); } + set { _DataGridView = value; } + } + + #endregion + + #region EditingControlFormattedValue + + /// + /// Gets or sets the Control Formatted Value + /// + public object EditingControlFormattedValue + { + get { return (Text); } + set { Text = (string) value; } + } + + #endregion + + #region EditingControlRowIndex + + /// + /// Gets or sets the Control RoeIndex + /// + public int EditingControlRowIndex + { + get { return (_RowIndex); } + set { _RowIndex = value; } + } + + #endregion + + #region EditingControlValueChanged + + /// + /// Gets or sets the Control ValueChanged state + /// + public bool EditingControlValueChanged + { + get { return (_ValueChanged); } + set { _ValueChanged = value; } + } + + #endregion + + #region EditingPanelCursor + + /// + /// Gets the Panel Cursor + /// + public Cursor EditingPanelCursor + { + get { return (base.Cursor); } + } + + #endregion + + #region RepositionEditingControlOnValueChange + + /// + /// Gets whether to RepositionEditingControlOnValueChange + /// + public bool RepositionEditingControlOnValueChange + { + get { return (false); } + } + + #endregion + + #endregion + + #region ApplyCellStyleToEditingControl + + /// + /// ApplyCellStyleToEditingControl + /// + /// + public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) + { + Font = dataGridViewCellStyle.Font; + + ForeColor = dataGridViewCellStyle.ForeColor; + BackColor = dataGridViewCellStyle.BackColor; + } + + #endregion + + #region GetEditingControlFormattedValue + + /// + /// Gets EditingControlFormattedValue + /// + /// + /// + public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) + { + return (EditingControlFormattedValue); + } + + #endregion + + #region EditingControlWantsInputKey + + /// + /// Gets whether the given key wants to be processed + /// by the Control + /// + /// + /// + /// + public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) + { + if ((keyData & Keys.Right) == Keys.Right) + return (true); + + if ((keyData & Keys.Left) == Keys.Left) + return (true); + + return (dataGridViewWantsInputKey == false); + } + + #endregion + + #region PrepareEditingControlForEdit + + /// + /// PrepareEditingControlForEdit + /// + /// + public void PrepareEditingControlForEdit(bool selectAll) + { + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewProgressBarX/DataGridViewProgressBarXCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewProgressBarX/DataGridViewProgressBarXCell.cs new file mode 100644 index 00000000..84f3adae --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewProgressBarX/DataGridViewProgressBarXCell.cs @@ -0,0 +1,402 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewProgressBarXCell : DataGridViewButtonCell + { + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (null); } + } + + #endregion + + #region FormattedValueType + + /// + /// FormattedValueType + /// + public override Type FormattedValueType + { + get { return (typeof(string)); } + } + + #endregion + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, + object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewProgressBarXColumn oc = (DataGridViewProgressBarXColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintButtonBackground(g, cellStyle, rBk); + PaintButtonContent(cellBounds, rowIndex, formattedValue, cellStyle, paintParts, bm); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintButtonBackground + + /// + /// Paints the Button background + /// + /// + /// + /// + private void PaintButtonBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, + false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintButtonContent + + /// + /// Paints the button background and content + /// + /// + /// + /// + /// + /// + /// + private void PaintButtonContent(Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, Bitmap bm) + { + DataGridViewProgressBarXColumn oc = (DataGridViewProgressBarXColumn)OwningColumn; + ProgressBarX bx = oc.ProgressBarX; + + Rectangle rBt = GetContentBounds(cellBounds, true); + + if (rBt.Width > 0 && rBt.Height > 0) + { + string s = oc.Text; + + oc.InCallBack = true; + + try + { + bx.Font = cellStyle.Font; + bx.ForeColor = cellStyle.ForeColor; + bx.BackColor = cellStyle.BackColor; + + bx.Value = GetValue(value, bx.Minimum); + + if (rowIndex < DataGridView.RowCount) + { + bx.Text = s; + + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + } + else + { + bx.Text = ""; + } + + bx.Bounds = rBt; + bx.RecalcLayout(); + bx.DrawToBitmap(bm, rBt); + } + finally + { + oc.InCallBack = false; + } + } + } + + #endregion + + #endregion + + #region Mouse processing + + #region OnMouseEnter + + /// + /// OnMouseEnter + /// + /// + protected override void OnMouseEnter(int rowIndex) + { + base.OnMouseEnter(rowIndex); + + DataGridViewProgressBarXColumn oc = (DataGridViewProgressBarXColumn) OwningColumn; + ProgressBarX bx = oc.ProgressBarX; + + bx.ProgressBarItem.InternalMouseEnter(); + } + + #endregion + + #region OnMouseLeave + + /// + /// Processes MouseLeave events + /// + /// + protected override void OnMouseLeave(int rowIndex) + { + base.OnMouseLeave(rowIndex); + + DataGridViewProgressBarXColumn oc = (DataGridViewProgressBarXColumn)OwningColumn; + ProgressBarX bx = oc.ProgressBarX; + + bx.ProgressBarItem.InternalMouseLeave(); + } + + #endregion + + #region OnMouseMove + + /// + /// Processes MouseMove events + /// + /// + protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) + { + base.OnMouseMove(e); + + DataGridViewProgressBarXColumn oc = (DataGridViewProgressBarXColumn)OwningColumn; + ProgressBarX bx = oc.ProgressBarX; + + bx.ProgressBarItem.InternalMouseMove( + new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta)); + } + + #endregion + + #region OnMouseDown + + /// + /// Processes MouseDown events + /// + /// + protected override void OnMouseDown(DataGridViewCellMouseEventArgs e) + { + base.OnMouseDown(e); + + DataGridViewProgressBarXColumn oc = (DataGridViewProgressBarXColumn)OwningColumn; + ProgressBarX bx = oc.ProgressBarX; + + Rectangle cellBounds = DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false); + Rectangle rBt = GetContentBounds(cellBounds, false); + + Point pt = e.Location; + pt.Offset(rBt.Location); + + if (rBt.Contains(pt) == true) + { + bx.Bounds = rBt; + + bx.ProgressBarItem.InternalMouseDown( + new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta)); + + DataGridView.Invalidate(rBt); + } + } + + #endregion + + #region OnMouseUp + + /// + /// Processes MouseUp events + /// + /// + protected override void OnMouseUp(DataGridViewCellMouseEventArgs e) + { + base.OnMouseUp(e); + + DataGridViewProgressBarXColumn oc = (DataGridViewProgressBarXColumn)OwningColumn; + ProgressBarX bx = oc.ProgressBarX; + + Rectangle cellBounds = DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false); + Rectangle rBt = GetContentBounds(cellBounds, false); + + bx.Bounds = rBt; + + bx.ProgressBarItem.InternalMouseUp( + new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta)); + + DataGridView.Invalidate(rBt); + } + + #endregion + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewProgressBarXColumn oc = (DataGridViewProgressBarXColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetContentBounds + + /// + /// Gets the content bounds for the given cell + /// + /// + /// + /// + private Rectangle GetContentBounds(Rectangle cellBounds, bool localize) + { + DataGridViewProgressBarXColumn oc = (DataGridViewProgressBarXColumn)OwningColumn; + + cellBounds.Width -= (oc.DividerWidth + 3); + cellBounds.Height -= 3; + + if (localize == true) + cellBounds.Location = new Point(0, 0); + + cellBounds.X++; + cellBounds.Y++; + + return (cellBounds); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + /// + private int GetValue(object value, int minimum) + { + if (value == Convert.DBNull || + (value is string && String.IsNullOrEmpty((string) value) == true)) + { + return (minimum); + } + + return (Convert.ToInt32(value)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewProgressBarX/DataGridViewProgressBarXColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewProgressBarX/DataGridViewProgressBarXColumn.cs new file mode 100644 index 00000000..67997259 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewProgressBarX/DataGridViewProgressBarXColumn.cs @@ -0,0 +1,433 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewButtonXColumn), "Controls.ProgressBarX.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewProgressBarXColumn : DataGridViewButtonColumn, IDataGridViewColumn + { + #region Events + + [Description("Occurs right before a ProgressBarX Cell is painted.")] + public event EventHandler BeforeCellPaint; + + [Description("Occurs when a ProgressBarX Cell is Clicked.")] + public event EventHandler Click; + + #endregion + + #region Private variables + + private ProgressBarX _ProgressBarX; + private Bitmap _CellBitmap; + + private bool _InCellCallBack; + + #endregion + + /// + /// Constructor + /// + public DataGridViewProgressBarXColumn() + { + CellTemplate = new DataGridViewProgressBarXCell(); + + _ProgressBarX = new ProgressBarX(); + _ProgressBarX.Visible = false; + + HookEvents(true); + } + + #region Hidden properties + + /// + /// Button FlatStyle + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new FlatStyle FlatStyle + { + get { return base.FlatStyle; } + set { base.FlatStyle = value; } + } + + /// + /// Button UseColumnTextForButtonValue + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool UseColumnTextForButtonValue + { + get { return base.UseColumnTextForButtonValue; } + set { base.UseColumnTextForButtonValue = value; } + } + + #endregion + + #region Internal properties + + #region InCallBack + + /// + /// InCallBack + /// + internal bool InCallBack + { + get { return (_InCellCallBack); } + set { _InCellCallBack = value; } + } + + #endregion + + #region ProgressBarX + + /// + /// Gets the Control ProgressBarX + /// + internal ProgressBarX ProgressBarX + { + get { return (_ProgressBarX); } + } + + #endregion + + #endregion + + #region Public properties + + #region ChunkColor + + /// + /// Gets or sets the color of the progress chunk. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance")] + [Description("Gets or sets the color of the progress chunk.")] + public Color ChunkColor + { + get { return (_ProgressBarX.ChunkColor); } + set { _ProgressBarX.ChunkColor = value; } + } + + /// + /// Gets whether ChunkColor property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeChunkColor() + { + return (_ProgressBarX.ChunkColor.IsEmpty == false); + } + + /// + /// Resets the ChunkColor property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetChunkColor() + { + _ProgressBarX.ChunkColor = Color.Empty; + } + + #endregion + + #region ChunkColor2 + + /// + /// Gets or sets the target gradient color of the progress chunk. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance")] + [Description("Gets or sets the target gradient color of the progress chunk.")] + public Color ChunkColor2 + { + get { return (_ProgressBarX.ChunkColor2); } + set { _ProgressBarX.ChunkColor2 = value; } + } + + /// + /// Gets whether ChunkColor property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeChunkColor2() + { + return (_ProgressBarX.ChunkColor2.IsEmpty == false); + } + + /// + /// Resets the ChunkColor property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetChunkColor2() + { + _ProgressBarX.ChunkColor2 = Color.Empty; + } + + #endregion + + #region ChunkGradientAngle + + /// + /// Gets or sets the gradient angle of the progress chunk. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(0), Category("Appearance")] + [Description("Gets or sets the gradient angle of the progress chunk.")] + public int ChunkGradientAngle + { + get { return (_ProgressBarX.ChunkGradientAngle); } + set { _ProgressBarX.ChunkGradientAngle = value; } + } + + #endregion + + #region ColorTable + + /// + /// Gets or sets the predefined color state table for progress bar. Color + /// specified applies to items with Office 2007 style only. It does not have + /// any effect on other styles. You can use ColorTable to indicate the state + /// of the operation that Progress Bar is tracking. Default value is eProgressBarItemColor.Normal. + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(eProgressBarItemColor.Normal), Category("Appearance")] + [Description("Indicates predefined color of item when Office 2007 style is used.")] + public eProgressBarItemColor ColorTable + { + get { return (_ProgressBarX.ColorTable); } + set { _ProgressBarX.ColorTable = value; } + } + + #endregion + + #region Maximum + + /// + /// Gets or sets the maximum value of the range of the control. + /// + [Browsable(true), Category("Behavior"), DefaultValue(100)] + [Description("Indicates the maximum value of the range of the control.")] + public int Maximum + { + get { return (_ProgressBarX.Maximum); } + set { _ProgressBarX.Maximum = value; } + } + + #endregion + + #region Minimum + + /// + /// Gets or sets the minimum value of the range of the control. + /// + [Browsable(true), DevCoBrowsable(true), Category("Behavior"), DefaultValue(0)] + [Description("Indicates the minimum value of the range of the control.")] + public int Minimum + { + get { return (_ProgressBarX.Minimum); } + set { _ProgressBarX.Minimum = value; } + } + + #endregion + + #region Style + + /// + /// Gets/Sets the visual style for the control. + /// + [Browsable(true), Category("Appearance"), DefaultValue(eDotNetBarStyle.Office2007)] + [Description("Specifies the visual style of the control.")] + public virtual eDotNetBarStyle Style + { + get { return (_ProgressBarX.Style); } + set { _ProgressBarX.Style = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the default Text to display on the Progress Bar + /// + [Browsable(true), Category("Appearance"), DefaultValue("")] + [Description("Indicates the default Text to display on the Progress Bar.")] + public new string Text + { + get + { + return (_InCellCallBack == true ? + _ProgressBarX.Text : base.Text); + } + + set + { + if (_InCellCallBack == true) + _ProgressBarX.Text = value; + else + base.Text = value; + } + } + + #endregion + + #region TextVisible + + /// + /// Gets or sets whether the text inside the progress bar is displayed. + /// + [Browsable(true), Category("Behavior"), DefaultValue(false)] + [Description("Gets or sets whether the text inside the progress bar is displayed.")] + public bool TextVisible + { + get { return (_ProgressBarX.TextVisible); } + set { _ProgressBarX.TextVisible = value; } + } + + #endregion + + #region Value + + /// + /// Gets or sets the current position of the progress bar. + /// + [Browsable(true), DevCoBrowsable(true), Category("Behavior"), DefaultValue(0)] + [Description("Indicates the current position of the progress bar.")] + public int Value + { + get { return (_ProgressBarX.Value); } + set { _ProgressBarX.Value = value; } + } + + #endregion + + #endregion + + #region HookEvents + + /// + /// Hooks or unhooks our system events + /// + /// + private void HookEvents(bool hook) + { + if (hook == true) + { + _ProgressBarX.ProgressBarItem.Click += ProgressBarItem_Click; + } + else + { + _ProgressBarX.ProgressBarItem.Click -= ProgressBarItem_Click; + } + } + + #endregion + + #region Event processing + + #region ProgressBarItem_Click + + /// + /// ProgressBarItem_Click + /// + /// + /// + void ProgressBarItem_Click(object sender, EventArgs e) + { + if (Click != null) + Click(sender, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewProgressBarXColumn bc = base.Clone() as DataGridViewProgressBarXColumn; + + if (bc != null) + _ProgressBarX.ProgressBarItem.InternalCopyToItem(bc.ProgressBarX.ProgressBarItem); + + return (bc); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the ButtonX control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + HookEvents(false); + + if (disposing == true) + _ProgressBarX.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewSlider/DataGridViewSliderCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewSlider/DataGridViewSliderCell.cs new file mode 100644 index 00000000..8f352326 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewSlider/DataGridViewSliderCell.cs @@ -0,0 +1,604 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewSliderCell : DataGridViewTextBoxCell + { + #region Private variables + + private DataGridViewCellStyle _CellStyle; + + #endregion + + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (null); } + } + + #endregion + + #region ValueType + + /// + /// Gets the type of the underlying data + /// (i.e., the type of the cell's Value property) + /// + public override Type ValueType + { + get { return (base.ValueType ?? typeof(Int32)); } + } + + #endregion + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetContentBounds(editingControlBounds); + + if (r.Height < editingControlBounds.Height) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.MiddleLeft: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height) / 2; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + editingControlBounds.Width = Math.Max(1, editingControlBounds.Width); + editingControlBounds.Height = Math.Max(1, r.Height); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + #region GetPreferredSize + + /// + /// GetPreferredSize + /// + /// + /// + /// + /// + /// + protected override Size GetPreferredSize(Graphics graphics, + DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + { + Size preferredSize = new Size(-1, -1); + + if (DataGridView != null) + { + DataGridViewSliderColumn oc = OwningColumn as DataGridViewSliderColumn; + + if (oc != null) + { + Slider sc = oc.Slider; + + preferredSize.Height = sc.Height; + + if (constraintSize.Width == 0) + { + preferredSize.Width += 80; + + if (sc.LabelVisible == true) + preferredSize.Width += sc.LabelWidth; + } + } + } + + return (preferredSize); + } + + #endregion + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, + object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewSliderColumn oc = (DataGridViewSliderColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintSliderBackground(g, cellStyle, rBk); + PaintSliderContent(cellBounds, rowIndex, formattedValue, cellStyle, paintParts, g); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintSliderBackground + + /// + /// Paints the Slider background + /// + /// + /// + /// + private void PaintSliderBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintSliderContent + + /// + /// Paints the Slider content + /// + /// + /// + /// + /// + /// + /// + private void PaintSliderContent(Rectangle cellBounds, + int rowIndex, object value, DataGridViewCellStyle cellStyle, + DataGridViewPaintParts paintParts, Graphics g) + { + DataGridViewSliderColumn oc = (DataGridViewSliderColumn) OwningColumn; + Slider slider = oc.Slider; + + _CellStyle = cellStyle; + + int saveValue = slider.Value; + + eSliderPart mouseOverPart = slider.SliderItem.MouseOverPart; + eSliderPart mouseDownPart = slider.SliderItem.MouseDownPart; + + GraphicsState gs = g.Save(); + + try + { + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + if (rowIndex != oc.ActiveRowIndex) + { + slider.SliderItem.MouseOverPart = eSliderPart.None; + slider.SliderItem.MouseDownPart = eSliderPart.None; + } + + slider.Font = cellStyle.Font; + slider.ForeColor = cellStyle.ForeColor; + slider.BackColor = Selected ? Color.Transparent : cellStyle.BackColor; + + if (rowIndex < DataGridView.RowCount) + { + slider.Text = oc.Text; + + if (rowIndex != oc.ActiveRowIndex) + slider.Value = GetSliderValue(value); + + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + } + else + { + slider.Text = ""; + slider.Value = GetSliderValue(value); + } + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + + g.TranslateTransform(r.X, r.Y); + + slider.CallBasePaintBackground = false; + + slider.Bounds = r; + slider.InternalPaint(new PaintEventArgs(g, Rectangle.Empty)); + } + finally + { + g.Restore(gs); + + slider.Value = saveValue; + + slider.SliderItem.MouseOverPart = mouseOverPart; + slider.SliderItem.MouseDownPart = mouseDownPart; + } + } + + #endregion + + #endregion + + #region Mouse processing + + #region OnMouseEnter + + /// + /// OnMouseEnter + /// + /// + protected override void OnMouseEnter(int rowIndex) + { + base.OnMouseEnter(rowIndex); + + DoMouseEnter(rowIndex, true); + } + + #region DoMouseEnter + + /// + /// Process MouseEnter state + /// + /// + /// + private void DoMouseEnter(int rowIndex, bool refresh) + { + DataGridViewSliderColumn oc = (DataGridViewSliderColumn) OwningColumn; + Slider slider = oc.Slider; + + // Work around an issue where we get notified of a mouse enter, but + // we will fault if we try to get the Value associated with the cell + + if (Visible == true) + { + oc.ActiveRowIndex = rowIndex; + + slider.Value = GetSliderValue(Value); + + slider.SliderItem.InternalMouseEnter(); + + if (refresh == true) + RefreshSlider(ColumnIndex, rowIndex); + } + } + + #endregion + + #endregion + + #region OnMouseLeave + + /// + /// Processes MouseLeave events + /// + /// + protected override void OnMouseLeave(int rowIndex) + { + base.OnMouseLeave(rowIndex); + + DataGridViewSliderColumn oc = (DataGridViewSliderColumn)OwningColumn; + Slider slider = oc.Slider; + + if (oc.ActiveRowIndex >= 0) + { + oc.ActiveRowIndex = -1; + + slider.SliderItem.InternalMouseLeave(); + + Value = slider.Value; + + RefreshSlider(ColumnIndex, rowIndex); + } + } + + #endregion + + #region OnMouseMove + + /// + /// Processes MouseMove events + /// + /// + protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) + { + base.OnMouseMove(e); + + DataGridViewSliderColumn oc = OwningColumn as DataGridViewSliderColumn; + + if (oc != null) + { + // Work around an issue where we get notified of a mouse enter / move, but + // we will fault if we try to get the Value associated with the cell + + if (oc.ActiveRowIndex == -1) + DoMouseEnter(e.RowIndex, false); + + if (oc.ActiveRowIndex >= 0) + { + Point pt = CellAlignPoint(e.X, e.Y); + + oc.Slider.SliderItem.InternalMouseMove( + new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta)); + + RefreshSlider(e.ColumnIndex, e.RowIndex); + } + } + } + + #endregion + + #region OnMouseDown + + /// + /// Processes MouseDown events + /// + /// + protected override void OnMouseDown(DataGridViewCellMouseEventArgs e) + { + base.OnMouseDown(e); + + DataGridViewSliderColumn oc = OwningColumn as DataGridViewSliderColumn; + + if (oc != null) + { + Point pt = CellAlignPoint(e.X, e.Y); + + oc.Slider.SliderItem.InternalMouseDown( + new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta)); + + RefreshSlider(e.ColumnIndex, e.RowIndex); + } + } + + #endregion + + #region OnMouseUp + + /// + /// Processes MouseUp events + /// + /// + protected override void OnMouseUp(DataGridViewCellMouseEventArgs e) + { + base.OnMouseUp(e); + + DataGridViewSliderColumn oc = OwningColumn as DataGridViewSliderColumn; + + if (oc != null) + { + Point pt = CellAlignPoint(e.X, e.Y); + + oc.Slider.SliderItem.InternalMouseUp( + new MouseEventArgs(e.Button, e.Clicks, pt.X, pt.Y, e.Delta)); + + Value = oc.Slider.Value; + + RefreshSlider(e.ColumnIndex, e.RowIndex); + } + } + + #endregion + + #region CellAlignPoint + + /// + /// CellAlignPoint + /// + /// + /// + /// + private Point CellAlignPoint(int x, int y) + { + Rectangle r = GetAdjustedEditingControlBounds(ContentBounds, _CellStyle); + + return (new Point(x, y - r.Y)); + } + + #endregion + + #endregion + + #region GetSliderValue + + /// + /// GetSliderValue + /// + /// + /// + internal int GetSliderValue(object value) + { + if (value == Convert.DBNull || + (value is string && String.IsNullOrEmpty((string) value) == true)) + { + return (0); + } + + return (Convert.ToInt32(value)); + } + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewSliderColumn oc = (DataGridViewSliderColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + + #endregion + + #region GetContentBounds + + /// + /// Gets the content bounds for the given cell + /// + /// + /// + private Rectangle GetContentBounds(Rectangle cellBounds) + { + DataGridViewSliderColumn oc = (DataGridViewSliderColumn)OwningColumn; + + if (oc.Slider.Parent == null) + { + Form form = oc.DataGridView.FindForm(); + + if (form != null) + oc.Slider.Parent = form; + } + + oc.Slider.SliderItem.RecalcSize(); + + cellBounds.Width -= (oc.DividerWidth + 3); + cellBounds.Height = oc.Slider.SliderItem.HeightInternal; + + return (cellBounds); + } + + #endregion + + #region RefreshSlider + + /// + /// Initiates the refresh of the cell slider + /// + /// + /// + internal void RefreshSlider(int columnIndex, int rowIndex) + { + if (DataGridView != null) + DataGridView.InvalidateCell(columnIndex, rowIndex); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewSlider/DataGridViewSliderColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewSlider/DataGridViewSliderColumn.cs new file mode 100644 index 00000000..40ba6be8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewSlider/DataGridViewSliderColumn.cs @@ -0,0 +1,462 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewButtonXColumn), "Controls.Slider.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewSliderColumn : DataGridViewTextBoxColumn, IDataGridViewColumn + { + #region Events + + /// + /// Occurs right before a Slider Cell is painted + /// + [Description("Occurs right before a Slider Cell is painted.")] + public event EventHandler BeforeCellPaint; + + [Description("Occurs when a Slider Cell is Clicked.")] + public event EventHandler Click; + + #endregion + + #region Private variables + + private Slider _Slider; + private Bitmap _CellBitmap; + + private int _ActiveRowIndex = -1; + private bool _BindingComplete; + + #endregion + + /// + /// Constructor + /// + public DataGridViewSliderColumn() + { + CellTemplate = new DataGridViewSliderCell(); + + _Slider = new Slider(); + _Slider.Visible = false; + + HookEvents(true); + } + + #region Internal properties + + #region ActiveRowIndex + + /// + /// Gets or sets the active row index + /// + internal int ActiveRowIndex + { + get { return (_ActiveRowIndex); } + set { _ActiveRowIndex = value; } + } + + #endregion + + #region BindingComplete + + /// + /// Gets or sets the DataBindingComplete state + /// + internal bool BindingComplete + { + get { return (_BindingComplete); } + set { _BindingComplete = value; } + } + + #endregion + + #region Slider + + /// + /// Gets the Control Slider + /// + internal Slider Slider + { + get { return (_Slider); } + } + + #endregion + + #endregion + + #region Public properties + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_Slider.Enabled); } + set { _Slider.Enabled = value; } + } + + #endregion + + #region EnableMarkup + + /// + /// Gets or sets whether text-markup support is enabled for items Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the item instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for items Text property.")] + public bool EnableMarkup + { + get { return (_Slider.EnableMarkup); } + set { _Slider.EnableMarkup = value; } + } + + #endregion + + #region LabelPosition + + /// + /// Gets or sets the text label position in relationship to the slider. Default value is Left. + /// + [Browsable(true), DefaultValue(eSliderLabelPosition.Left), Category("Layout")] + [Description("Indicates text label position in relationship to the slider")] + public eSliderLabelPosition LabelPosition + { + get { return (_Slider.LabelPosition); } + set { _Slider.LabelPosition = value; } + } + + #endregion + + #region LabelVisible + + /// + /// Gets or sets whether the text label next to the slider is displayed. + /// + [DevCoBrowsable(true), Browsable(true)] + [Description("Gets or sets whether the label text is displayed."), Category("Behavior"), DefaultValue(true)] + public bool LabelVisible + { + get { return (_Slider.LabelVisible); } + set { _Slider.LabelVisible = value; } + } + + #endregion + + #region LabelWidth + + /// + /// Gets or sets the width of the label part of the item in pixels. Value must be greater than 0. Default value is 38. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(38), Category("Layout")] + [Description("Indicates width of the label part of the item in pixels.")] + public int LabelWidth + { + get { return (_Slider.LabelWidth); } + set { _Slider.LabelWidth = value; } + } + + #endregion + + #region Maximum + + /// + /// Gets or sets the maximum value of the range of the control. + /// + [DevCoBrowsable(true), Browsable(true), Category("Behavior"), DefaultValue(100)] + [Description("Gets or sets the maximum value of the range of the control.")] + public int Maximum + { + get { return (_Slider.Maximum); } + set { _Slider.Maximum = value; } + } + + #endregion + + #region Minimum + + /// + /// Gets or sets the minimum value of the range of the control. + /// + [DevCoBrowsable(true), Browsable(true), Category("Behavior"), DefaultValue(0)] + [Description("Gets or sets the minimum value of the range of the control.")] + public int Minimum + { + get { return (_Slider.Minimum); } + set { _Slider.Minimum = value; } + } + + #endregion + + #region Step + + /// + /// Gets or sets the amount by which a call to the PerformStep method increases the current position of the slider. Value must be greater than 0. + /// + [DevCoBrowsable(true), Browsable(true), Category("Behavior"), DefaultValue(1)] + [Description("Gets or sets the amount by which a call to the PerformStep method increases the current position of the slider.")] + public int Step + { + get { return (_Slider.Step); } + set { _Slider.Step = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the text associated with this item. + /// + [Browsable(false), DevCoBrowsable(false), DefaultValue(""), Category("Appearance")] + [Description("The text contained in the item.")] + public string Text + { + get { return (_Slider.Text); } + set { _Slider.Text = value; } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the color of the label text. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates color of the label text.")] + public Color TextColor + { + get { return (_Slider.TextColor); } + set { _Slider.TextColor = value; } + } + + /// + /// Returns whether property should be serialized. Used by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return (_Slider.TextColor.IsEmpty == false); + } + + /// + /// Resets the property to default value. Used by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + _Slider.TextColor = Color.Empty; + } + + #endregion + + #region TrackMarker + + /// + /// Gets or sets whether vertical line track marker is displayed on the slide line. Default value is true. + /// + [Browsable(true), Category("Appearance"), DefaultValue(true)] + [Description("Indicates whether vertical line track marker is displayed on the slide line.")] + public virtual bool TrackMarker + { + get { return (_Slider.TrackMarker); } + set { _Slider.TrackMarker = value; } + } + + #endregion + + #region Value + + /// + /// Gets or sets the current position of the slider. + /// + [Browsable(false)] + [Description("Indicates the current position of the slider.")] + public int Value + { + get { return (_Slider.Value); } + set { _Slider.Value = value; } + } + + #endregion + + #endregion + + #region HookEvents + + /// + /// Hooks or unhooks our system events + /// + /// + private void HookEvents(bool hook) + { + if (hook == true) + { + _Slider.SliderItem.Click += SliderItem_Click; + _Slider.SliderItem.ValueChanged += SliderItem_ValueChanged; + } + else + { + _Slider.SliderItem.Click -= SliderItem_Click; + _Slider.SliderItem.ValueChanged -= SliderItem_ValueChanged; + } + } + + #endregion + + #region Event processing + + #region SliderItem_Click + + /// + /// SliderItem_Click + /// + /// + /// + void SliderItem_Click(object sender, EventArgs e) + { + if (Click != null) + Click(sender, e); + } + + #endregion + + #region SliderItem_ValueChanged + + /// + /// SliderItem_ValueChanged + /// + /// + /// + void SliderItem_ValueChanged(object sender, EventArgs e) + { + if (_Slider.SliderItem.MouseDownPart == eSliderPart.IncreaseButton || + _Slider.SliderItem.MouseDownPart == eSliderPart.DecreaseButton) + { + DataGridViewSliderCell cell = DataGridView.Rows[ActiveRowIndex].Cells[Index] as DataGridViewSliderCell; + + if (cell != null) + { + int value = cell.GetSliderValue(cell.Value); + + if (value != _Slider.SliderItem.Value) + { + cell.Value = _Slider.SliderItem.Value; + cell.RefreshSlider(Index, ActiveRowIndex); + + } + } + } + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewSliderColumn sc = base.Clone() as DataGridViewSliderColumn; + + if (sc != null) + { + _Slider.SliderItem.InternalCopyToItem(sc.Slider.SliderItem); + + sc.Enabled = Enabled; + } + + return (sc); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the ButtonX control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + HookEvents(false); + + if (disposing == true) + _Slider.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewTextBoxDropDown/DataGridViewTextBoxDropDownCell.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewTextBoxDropDown/DataGridViewTextBoxDropDownCell.cs new file mode 100644 index 00000000..c067e9fe --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewTextBoxDropDown/DataGridViewTextBoxDropDownCell.cs @@ -0,0 +1,670 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + public class DataGridViewTextBoxDropDownCell : DataGridViewTextBoxCell + { + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] + static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam); + + #region Public properties + + #region EditType + + /// + /// Gets the Type of the editing control associated with the cell + /// + public override Type EditType + { + get { return (typeof(DataGridViewTextBoxDropDownEditingControl)); } + } + + #endregion + + #endregion + + #region InitializeEditingControl + + /// + /// InitializeEditingControl + /// + /// + /// + /// + public override void InitializeEditingControl(int rowIndex, + object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) + { + DetachEditingControl(); + + base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); + + DataGridViewTextBoxDropDownEditingControl ctl = + (DataGridViewTextBoxDropDownEditingControl)DataGridView.EditingControl; + + DataGridViewTextBoxDropDownColumn oc = (DataGridViewTextBoxDropDownColumn)OwningColumn; + TextBoxDropDown tb = oc.TextBoxDropDown; + + ctl.AutoCompleteCustomSource = tb.AutoCompleteCustomSource; + ctl.AutoCompleteMode = tb.AutoCompleteMode; + ctl.AutoCompleteSource = tb.AutoCompleteSource; + ctl.BackColor = tb.BackColor; + ctl.CharacterCasing = tb.CharacterCasing; + ctl.DropDownControl = tb.DropDownControl; + ctl.Enabled = tb.Enabled; + ctl.FocusHighlightColor = tb.FocusHighlightColor; + ctl.FocusHighlightEnabled = tb.FocusHighlightEnabled; + ctl.ForeColor = tb.ForeColor; + ctl.HideSelection = tb.HideSelection; + ctl.ImeMode = tb.ImeMode; + ctl.MaxLength = tb.MaxLength; + ctl.PasswordChar = tb.PasswordChar; + ctl.RightToLeft = tb.RightToLeft; + ctl.TextAlign = GetTextAlignment(dataGridViewCellStyle.Alignment); + ctl.UseSystemPasswordChar = tb.UseSystemPasswordChar; + ctl.WatermarkBehavior = tb.WatermarkBehavior; + ctl.WatermarkColor = tb.WatermarkColor; + ctl.WatermarkEnabled = tb.WatermarkEnabled; + ctl.WatermarkFont = tb.WatermarkFont; + ctl.WatermarkText = tb.WatermarkText; + + ctl.TextBox.Multiline = (dataGridViewCellStyle.WrapMode == DataGridViewTriState.True); + + ctl.BackgroundStyle.ApplyStyle(tb.BackgroundStyle); + ctl.BackgroundStyle.Class = tb.BackgroundStyle.Class; + + tb.ButtonClear.CopyToItem(ctl.ButtonClear); + tb.ButtonCustom.CopyToItem(ctl.ButtonCustom); + tb.ButtonCustom2.CopyToItem(ctl.ButtonCustom2); + tb.ButtonDropDown.CopyToItem(ctl.ButtonDropDown); + + ctl.ButtonClearClick += ButtonClearClick; + ctl.ButtonCustomClick += ButtonCustomClick; + ctl.ButtonCustom2Click += ButtonCustom2Click; + ctl.ButtonDropDownClick += ButtonDropDownClick; + ctl.KeyDown += KeyDown; + + ctl.Text = (initialFormattedValue != null && initialFormattedValue != Convert.DBNull + ? Convert.ToString(initialFormattedValue) : ""); + } + + #endregion + + #region DetachEditingControl + + /// + /// DetachEditingControl + /// + public override void DetachEditingControl() + { + if (DataGridView != null && DataGridView.EditingControl != null) + { + DataGridViewTextBoxDropDownEditingControl di = + DataGridView.EditingControl as DataGridViewTextBoxDropDownEditingControl; + + if (di != null) + { + di.ButtonClearClick -= ButtonClearClick; + di.ButtonCustomClick -= ButtonCustomClick; + di.ButtonCustom2Click -= ButtonCustom2Click; + di.ButtonDropDownClick -= ButtonDropDownClick; + di.KeyDown -= KeyDown; + } + } + + base.DetachEditingControl(); + } + + #endregion + + #region Event processing + + #region ButtonClearClick + + /// + /// ButtonClearClick + /// + /// + /// + void ButtonClearClick(object sender, CancelEventArgs e) + { + ((DataGridViewTextBoxDropDownColumn)OwningColumn).DoButtonClearClick(sender, e); + } + + #endregion + + #region ButtonCustomClick + + /// + /// ButtonCustomClick + /// + /// + /// + void ButtonCustomClick(object sender, EventArgs e) + { + ((DataGridViewTextBoxDropDownColumn)OwningColumn).DoButtonCustomClick(sender, e); + } + + #endregion + + #region ButtonCustom2Click + + /// + /// ButtonCustom2Click + /// + /// + /// + void ButtonCustom2Click(object sender, EventArgs e) + { + ((DataGridViewTextBoxDropDownColumn)OwningColumn).DoButtonCustom2Click(sender, e); + } + + #endregion + + #region ButtonDropDownClick + + /// + /// ButtonDropDownClick + /// + /// + /// + void ButtonDropDownClick(object sender, CancelEventArgs e) + { + ((DataGridViewTextBoxDropDownColumn)OwningColumn).DoButtonDropDownClick(sender, e); + } + + #endregion + + #region KeyDown + + /// + /// KeyDown routine forwards all DataGridView sent keys to + /// the underlying focusable control + /// + /// + /// + void KeyDown(object sender, KeyEventArgs e) + { + if (DataGridView != null && DataGridView.EditingControl != null) + { + DataGridViewTextBoxDropDownEditingControl di = + DataGridView.EditingControl as DataGridViewTextBoxDropDownEditingControl; + + if (di != null) + PostMessage(di.TextBox.Handle, 256, (int) e.KeyCode, 1); + } + } + + #endregion + + #endregion + + #region PositionEditingControl + + /// + /// PositionEditingControl + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public override void PositionEditingControl(bool setLocation, bool setSize, Rectangle cellBounds, + Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, + bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) + { + Rectangle editingControlBounds = + PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, + singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow); + + editingControlBounds = GetAdjustedEditingControlBounds(editingControlBounds, cellStyle); + + DataGridView.EditingControl.Location = new Point(editingControlBounds.X, editingControlBounds.Y); + DataGridView.EditingControl.Size = new Size(editingControlBounds.Width, editingControlBounds.Height); + } + + #endregion + + #region GetAdjustedEditingControlBounds + + /// + /// GetAdjustedEditingControlBounds + /// + /// + /// + /// + private Rectangle GetAdjustedEditingControlBounds( + Rectangle editingControlBounds, DataGridViewCellStyle cellStyle) + { + // Add a 1 pixel padding around the editing control + + editingControlBounds.X += 1; + editingControlBounds.Y += 1; + editingControlBounds.Width = Math.Max(0, editingControlBounds.Width - 2); + editingControlBounds.Height = Math.Max(0, editingControlBounds.Height - 2); + + // Adjust the vertical location of the editing control + + Rectangle r = GetCellBounds(editingControlBounds); + + if (cellStyle.WrapMode != DataGridViewTriState.True) + { + if (r.Height < editingControlBounds.Height) + { + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.MiddleLeft: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.MiddleRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height)/2; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + editingControlBounds.Y += (editingControlBounds.Height - r.Height); + break; + } + } + + editingControlBounds.Height = Math.Max(1, r.Height); + } + + editingControlBounds.Width = Math.Max(1, editingControlBounds.Width); + + return (editingControlBounds); + } + + #endregion + + #region GetPreferredSize + + ///// + ///// GetPreferredSize + ///// + ///// + ///// + ///// + ///// + ///// + //protected override Size GetPreferredSize(Graphics graphics, + // DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) + //{ + // if (DataGridView == null) + // return (new Size(-1, -1)); + + // DataGridViewTextBoxDropDownColumn oc = (DataGridViewTextBoxDropDownColumn)OwningColumn; + + // Size size = oc.TextBoxDropDown.PreferredSize; + // size.Height += 3; + + // return (size); + //} + + #endregion + + #region Paint + + #region Paint + + /// + /// Cell painting + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected override void Paint(Graphics graphics, + Rectangle clipBounds, Rectangle cellBounds, int rowIndex, + DataGridViewElementStates elementState, object value, object formattedValue, + string errorText, DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, + DataGridViewPaintParts paintParts) + { + if (DataGridView != null) + { + // First paint the borders of the cell + + if (PartsSet(paintParts, DataGridViewPaintParts.Border)) + PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); + + // Now paint the background and content + + if (PartsSet(paintParts, DataGridViewPaintParts.Background)) + { + Rectangle rBk = GetBackBounds(cellBounds, advancedBorderStyle); + + if (rBk.Height > 0 && rBk.Width > 0) + { + DataGridViewTextBoxDropDownColumn oc = (DataGridViewTextBoxDropDownColumn)OwningColumn; + Bitmap bm = oc.GetCellBitmap(cellBounds); + + if (bm != null) + { + using (Graphics g = Graphics.FromImage(bm)) + { + PaintCellBackground(g, cellStyle, rBk); + PaintCellContent(g, cellBounds, rowIndex, formattedValue, cellStyle, paintParts, bm); + + graphics.DrawImageUnscaledAndClipped(bm, rBk); + } + + if ((DataGridView.ShowCellErrors == true) && + (paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon) + { + base.PaintErrorIcon(graphics, clipBounds, cellBounds, errorText); + } + } + } + } + } + } + + #endregion + + #region PaintCellBackground + + /// + /// Paints the cell background + /// + /// + /// + /// + private void PaintCellBackground(Graphics g, + DataGridViewCellStyle cellStyle, Rectangle rBack) + { + Rectangle r = rBack; + r.Location = new Point(0, 0); + + DataGridViewX dx = DataGridView as DataGridViewX; + + if (dx != null && dx.Enabled == true && Selected == true && + dx.PaintEnhancedSelection == true) + { + Office2007ButtonItemPainter.PaintBackground(g, dx.ButtonStateColorTable, + r, RoundRectangleShapeDescriptor.RectangleShape, false, false); + } + else + { + Color color = (Selected == true) + ? cellStyle.SelectionBackColor : cellStyle.BackColor; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region PaintCellContent + + /// + /// Paints the cell content + /// + /// + /// + /// + /// + /// + /// + /// + private void PaintCellContent(Graphics g, Rectangle cellBounds, int rowIndex, object value, + DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts, Bitmap bm) + { + DataGridViewTextBoxDropDownColumn oc = (DataGridViewTextBoxDropDownColumn)OwningColumn; + TextBoxDropDown di = oc.TextBoxDropDown; + + Point ptCurrentCell = DataGridView.CurrentCellAddress; + bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex; + bool cellEdited = cellCurrent && DataGridView.EditingControl != null; + + // If the cell is in editing mode, there is nothing else to paint + + if (cellEdited == false && rowIndex < DataGridView.RowCount) + { + if (PartsSet(paintParts, DataGridViewPaintParts.ContentForeground)) + { + cellBounds.X = 0; + cellBounds.Y = 0; + cellBounds.Width -= (oc.DividerWidth + 1); + cellBounds.Height -= 1; + + di.Font = cellStyle.Font; + di.ForeColor = cellStyle.ForeColor; + di.BackColor = cellStyle.BackColor; + + di.TextAlign = GetTextAlignment(cellStyle.Alignment); + di.Text = GetValue(value); + + oc.OnBeforeCellPaint(rowIndex, ColumnIndex); + + Rectangle r = GetAdjustedEditingControlBounds(cellBounds, cellStyle); + + if (oc.DisplayControlForCurrentCellOnly == false) + DrawControl(di, cellStyle, r, bm, g); + else + DrawText(di, cellStyle, r, g); + } + } + } + + #region DrawControl + + /// + /// DrawControl + /// + /// + /// + /// + /// + /// + private void DrawControl(TextBoxDropDown di, DataGridViewCellStyle cellStyle, Rectangle r, Bitmap bm, Graphics g) + { + if (di.ButtonGroup.Items.Count > 0) + { + using (Bitmap bm2 = new Bitmap(bm)) + { + di.Bounds = r; + di.DrawToBitmap(bm2, r); + + foreach (VisualItem item in di.ButtonGroup.Items) + { + if (item.Visible == true) + { + Rectangle t = item.RenderBounds; + t.X += r.X; + t.Y += r.Y; + + g.DrawImage(bm2, t, t, GraphicsUnit.Pixel); + + if (t.Left < r.Right) + r.Width -= (r.Right - t.Left - 1); + } + } + } + } + + DrawText(di, cellStyle, r, g); + } + + #endregion + + #region DrawText + + /// + /// DrawText + /// + /// + /// + /// + /// + private void DrawText(TextBoxDropDown di, DataGridViewCellStyle cellStyle, Rectangle r, Graphics g) + { + r.Inflate(-2, 0); + + eTextFormat tf = eTextFormat.Default | eTextFormat.NoPrefix; + + switch (di.TextAlign) + { + case HorizontalAlignment.Center: + tf |= eTextFormat.HorizontalCenter; + break; + + case HorizontalAlignment.Right: + tf |= eTextFormat.Right; + break; + } + + if (cellStyle.WrapMode == DataGridViewTriState.True) + tf |= eTextFormat.WordBreak; + + switch (cellStyle.Alignment) + { + case DataGridViewContentAlignment.TopLeft: + case DataGridViewContentAlignment.TopCenter: + case DataGridViewContentAlignment.TopRight: + tf |= eTextFormat.Top; + break; + + case DataGridViewContentAlignment.BottomLeft: + case DataGridViewContentAlignment.BottomCenter: + case DataGridViewContentAlignment.BottomRight: + tf |= eTextFormat.Bottom; + break; + + default: + tf |= eTextFormat.VerticalCenter; + break; + } + + TextDrawing.DrawString(g, di.Text, di.Font, di.ForeColor, r, tf); + } + + #endregion + + #endregion + + #endregion + + #region GetBackBounds + + /// + /// Gets the background bounds for the given cell + /// + /// + /// + /// + private Rectangle GetBackBounds( + Rectangle cellBounds, DataGridViewAdvancedBorderStyle advancedBorderStyle) + { + DataGridViewTextBoxDropDownColumn oc = (DataGridViewTextBoxDropDownColumn)OwningColumn; + + Rectangle r = BorderWidths(advancedBorderStyle); + + cellBounds.Offset(r.X, r.Y); + cellBounds.Width -= r.Right; + cellBounds.Height -= r.Bottom; + + if (Selected == true) + cellBounds.Width += oc.DividerWidth; + + return (cellBounds); + } + #endregion + + #region GetCellBounds + + /// + /// Gets the button bounds for the given cell + /// + /// + /// + private Rectangle GetCellBounds(Rectangle cellBounds) + { + DataGridViewTextBoxDropDownColumn oc = (DataGridViewTextBoxDropDownColumn)OwningColumn; + + Size size = oc.TextBoxDropDown.PreferredSize; + + cellBounds.Location = new Point(1, 1); + + cellBounds.Width -= oc.DividerWidth; + cellBounds.Height = size.Height - 1; + + return (cellBounds); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + private string GetValue(object value) + { + return (value != Convert.DBNull ? Convert.ToString(value) : ""); + } + + #endregion + + #region GetTextAlignment + + /// + /// GetTextAlignment + /// + /// + /// + private HorizontalAlignment GetTextAlignment(DataGridViewContentAlignment alignment) + { + switch (alignment) + { + case DataGridViewContentAlignment.TopCenter: + case DataGridViewContentAlignment.MiddleCenter: + case DataGridViewContentAlignment.BottomCenter: + return (HorizontalAlignment.Center); + + case DataGridViewContentAlignment.TopRight: + case DataGridViewContentAlignment.MiddleRight: + case DataGridViewContentAlignment.BottomRight: + return (HorizontalAlignment.Right); + + default: + return (HorizontalAlignment.Left); + } + } + + #endregion + + #region PartsSet + + /// + /// Determines if the given part is set + /// + /// + /// + /// + private bool PartsSet(DataGridViewPaintParts paintParts, DataGridViewPaintParts parts) + { + return ((paintParts & parts) == parts); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewTextBoxDropDown/DataGridViewTextBoxDropDownColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewTextBoxDropDown/DataGridViewTextBoxDropDownColumn.cs new file mode 100644 index 00000000..e6ea6117 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewTextBoxDropDown/DataGridViewTextBoxDropDownColumn.cs @@ -0,0 +1,1058 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Runtime.InteropServices; +using System.Security.Permissions; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(DataGridViewTextBoxDropDownColumn), "Controls.TextBoxDropDown.ico"), ToolboxItem(false), ComVisible(false)] + public class DataGridViewTextBoxDropDownColumn : DataGridViewTextBoxColumn, IDataGridViewColumn + { + #region Events + + /// + /// Occurs right before a TextBoxDropDown Cell is painted + /// + [Description("Occurs right before a TextBoxDropDown Cell is painted.")] + public event EventHandler BeforeCellPaint; + + /// + /// Occurs when Clear button is clicked and allows you + /// to cancel the default action performed by the button + /// + [Description("Occurs when Clear button is clicked and allows you to cancel the default action performed by the button.")] + public event EventHandler ButtonClearClick; + + /// + /// Occurs when ButtonCustom control is clicked + /// + [Description("Occurs when ButtonCustom control is clicked.")] + public event EventHandler ButtonCustomClick; + + /// + /// Occurs when ButtonCustom2 control is clicked + /// + [Description("Occurs when ButtonCustom2 control is clicked.")] + public event EventHandler ButtonCustom2Click; + + /// + /// Occurs when Drop-Down button is clicked and allows you to cancel showing of the popup + /// + [Description("Occurs when Drop-Down button is clicked and allows you to cancel showing of the popup.")] + public event EventHandler ButtonDropDownClick; + + #endregion + + #region Private variables + + private TextBoxDropDown _TextBoxDropDown; + private Bitmap _CellBitmap; + private bool _DisplayControlForCurrentCellOnly = true; + + #endregion + + /// + /// Constructor + /// + public DataGridViewTextBoxDropDownColumn() + { + CellTemplate = new DataGridViewTextBoxDropDownCell(); + + _TextBoxDropDown = new TextBoxDropDown(); + + _TextBoxDropDown.BackgroundStyle.Class = ElementStyleClassKeys.DataGridViewIpAddressBorderKey; + } + + #region Internal properties + + #region TextBoxDropDown + + /// + /// Gets the underlying TextBoxDropDown control + /// + [Browsable(false)] + internal TextBoxDropDown TextBoxDropDown + { + get { return (_TextBoxDropDown); } + } + + #endregion + + #endregion + + #region Public properties + + #region AutoCompleteCustomSource + + /// + /// Gets or sets a custom StringCollection to use when + /// the AutoCompleteSource property is set to CustomSource. + /// A StringCollection to use with AutoCompleteSource. + /// + [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Localizable(true)] + [Description("Indicates custom StringCollection to use when the AutoCompleteSource property is set to CustomSource.")] + [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + public AutoCompleteStringCollection AutoCompleteCustomSource + { + get { return (_TextBoxDropDown.AutoCompleteCustomSource); } + set { _TextBoxDropDown.AutoCompleteCustomSource = value; } + } + + #endregion + + #region AutoCompleteMode + + /// + /// Gets or sets an option that controls + /// how automatic completion works for the TextBox. + /// One of the values of AutoCompleteMode. The values are Append, + /// None, Suggest, and SuggestAppend. The default is None. + /// + [Browsable(true), EditorBrowsable(EditorBrowsableState.Always), DefaultValue(0)] + [Description("Gets or sets an option that controls how automatic completion works for the TextBox.")] + public AutoCompleteMode AutoCompleteMode + { + get { return (_TextBoxDropDown.AutoCompleteMode); } + set { _TextBoxDropDown.AutoCompleteMode = value; } + } + + #endregion + + #region AutoCompleteSource + + /// + /// Gets or sets a value specifying the source of complete strings used for automatic completion. + /// One of the values of AutoCompleteSource. The options are AllSystemSources, AllUrl, FileSystem, HistoryList, RecentlyUsedList, CustomSource, and None. The default is None. + /// + [ Browsable(true), DefaultValue(0x80), TypeConverter(typeof(TextBoxAutoCompleteSourceConverter))] + [EditorBrowsable(EditorBrowsableState.Always)] + [Description("Gets or sets a value specifying the source of complete strings used for automatic completion.")] + public AutoCompleteSource AutoCompleteSource + { + get { return (_TextBoxDropDown.AutoCompleteSource); } + set { _TextBoxDropDown.AutoCompleteSource = value; } + } + + #endregion + + #region BackColor + + /// + /// Gets or sets the Background color. + /// + [Browsable(false)] + public Color BackColor + { + get { return (_TextBoxDropDown.BackColor); } + set { _TextBoxDropDown.BackColor = value; } + } + + #endregion + + #region BackgroundStyle + + /// + /// Specifies the background style of the control. + /// + [Browsable(true), Category("Style")] + [Description("Gets or sets control background style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return (_TextBoxDropDown.BackgroundStyle); } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _TextBoxDropDown.ResetBackgroundStyle(); + + _TextBoxDropDown.BackgroundStyle.Class = "TextBoxBorder"; + _TextBoxDropDown.BackgroundStyle.CornerType = eCornerType.Square; + } + + #endregion + + #region ButtonClear + + /// + /// Gets the object that describes the settings for the button + /// that clears the content of the control when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that clears the content of the control when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonClear + { + get { return (_TextBoxDropDown.ButtonClear); } + } + + #endregion + + #region ButtonCustom + + /// + /// Gets the object that describes the settings for the custom button + /// that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get { return (_TextBoxDropDown.ButtonCustom); } + } + + #endregion + + #region ButtonCustom2 + + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get { return (_TextBoxDropDown.ButtonCustom2); } + } + + #endregion + + #region ButtonDropDown + + /// + /// Gets the object that describes the settings for the button + /// that shows drop-down when clicked. + /// + [Browsable(true), Category("Buttons")] + [Description("Describes the settings for the button that shows drop-down when clicked.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonDropDown + { + get { return (_TextBoxDropDown.ButtonDropDown); } + } + + #endregion + + #region CharacterCasing + + /// + /// Gets or sets whether the TextBox control + /// modifies the case of characters as they are typed. + /// One of the CharacterCasing enumeration values that specifies + /// whether the TextBox control modifies the case of characters. + /// The default is CharacterCasing.Normal. + /// + [Browsable(true), Category("Behavior"), DefaultValue(0)] + [Description("Indicates whether the TextBox control modifies the case of characters as they are typed.")] + public CharacterCasing CharacterCasing + { + get { return (_TextBoxDropDown.CharacterCasing); } + set { _TextBoxDropDown.CharacterCasing = value; } + } + + #endregion + + #region DisplayControlForCurrentCellOnly + + /// + /// Gets or sets whether the control + /// will be displayed for the current cell only. + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the control will be displayed for the current cell only.")] + public bool DisplayControlForCurrentCellOnly + { + get { return (_DisplayControlForCurrentCellOnly); } + + set + { + if (_DisplayControlForCurrentCellOnly != value) + { + _DisplayControlForCurrentCellOnly = value; + _TextBoxDropDown.Invalidate(); + } + } + } + + #endregion + + #region DropDownControl + + /// + /// Gets or sets the reference of the control that will be + /// displayed on popup that is shown when the drop-down button is clicked. + /// + [DefaultValue(null)] + [Description("Indicates reference of the control that will be displayed on popup that is shown when the drop-down button is clicked.")] + public Control DropDownControl + { + get { return (_TextBoxDropDown.DropDownControl); } + set { _TextBoxDropDown.DropDownControl = value; } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether the control can respond to user interaction + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the control can respond to user interaction.")] + public bool Enabled + { + get { return (_TextBoxDropDown.Enabled); } + set { _TextBoxDropDown.Enabled = value; } + } + + #endregion + + #region FocusHighlightColor + + /// + /// Gets or sets the color used as background color to highlight + /// the text box when it has input focus and FocusHighlight is enabled. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates color used as background color to highlight the text box when it has input focus and FocusHighlight is enabled.")] + public Color FocusHighlightColor + { + get { return (_TextBoxDropDown.FocusHighlightColor); } + set { _TextBoxDropDown.FocusHighlightColor = value; } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFocusHighlightColor() + { + return (_TextBoxDropDown.ShouldSerializeFocusHighlightColor()); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFocusHighlightColor() + { + _TextBoxDropDown.ResetFocusHighlightColor(); + } + + #endregion + + #region FocusHighlightEnabled + + /// + /// Gets or sets whether FocusHighlightColor is used as + /// background color to highlight the text box when it has + /// input focus. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Appearance")] + [Description("Indicates whether FocusHighlightColor is used as background color to highlight the text box when it has input focus.")] + public bool FocusHighlightEnabled + { + get { return (_TextBoxDropDown.FocusHighlightEnabled); } + set { _TextBoxDropDown.FocusHighlightEnabled = value; } + } + + #endregion + + #region ForeColor + + /// + /// Gets or sets the foreground color. + /// + [Browsable(false)] + public Color ForeColor + { + get { return (_TextBoxDropDown.ForeColor); } + set { _TextBoxDropDown.ForeColor = value; } + } + + #endregion + + #region HideSelection + + /// + /// Gets or sets a value indicating whether the selected text in + /// the text box control remains highlighted when the control loses focus. + /// true if the selected text does not appear highlighted when the + /// text box control loses focus; false, if the selected text remains + /// highlighted when the text box control loses focus. The default is true. + /// + [Browsable(true), Category("Behavior"), DefaultValue(true)] + [Description("Gets or sets a value indicating whether the selected text in the text box control remains highlighted when the control loses focus.")] + public bool HideSelection + { + get { return (_TextBoxDropDown.HideSelection); } + set { _TextBoxDropDown.HideSelection = value; } + } + + #endregion + + #region ImeMode + + /// + /// Gets or sets the Input Method Editor (IME) mode of the control. + /// + [Browsable(true), DefaultValue(ImeMode.Inherit)] + [Description("Indicates the Input Method Editor (IME) mode of the control.")] + public ImeMode ImeMode + { + get { return (_TextBoxDropDown.ImeMode); } + set { _TextBoxDropDown.ImeMode = value; } + } + + #endregion + + #region MaxLength + + /// + /// Gets or sets the maximum number of characters the user can type or paste into the text box control. + /// The number of characters that can be entered into the control. The default is 32767. + /// + [Category("Behavior"), DefaultValue(0x7fff), Localizable(true)] + [Description("Gets or sets the maximum number of characters the user can type or paste into the text box control.")] + public int MaxLength + { + get { return (_TextBoxDropDown.MaxLength); } + set { _TextBoxDropDown.MaxLength = value; } + } + + #endregion + + #region PasswordChar + + /// + /// Gets or sets the character to be displayed in substitute for user input. + /// + [Browsable(true), DefaultValue(null)] + [Description("Indicates the character to be displayed in substitute for user input.")] + public char PasswordChar + { + get { return (_TextBoxDropDown.PasswordChar); } + set { _TextBoxDropDown.PasswordChar = value; } + } + + #endregion + + #region RightToLeft + + /// + /// Gets or sets a value indicating whether control's + /// elements are aligned to support locales using right-to-left fonts. + /// + [Browsable(true), DefaultValue(RightToLeft.Inherit)] + [Description("Indicates the control's elements are aligned to support locales using right-to-left fonts.")] + public RightToLeft RightToLeft + { + get { return (_TextBoxDropDown.RightToLeft); } + set { _TextBoxDropDown.RightToLeft = value; } + } + + #endregion + + #region SelectedText + + /// + /// Gets or sets a value indicating the currently selected text in the control. + /// A string that represents the currently selected text in the text box. + /// + [Browsable(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets or sets a value indicating the currently selected text in the control.")] + public virtual string SelectedText + { + get { return (_TextBoxDropDown.SelectedText); } + set { _TextBoxDropDown.SelectedText = value; } + } + + #endregion + + #region SelectionLength + + /// + /// Gets or sets the number of characters selected in the text box. + /// The number of characters selected in the text box. + /// + [Browsable(false), Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets or sets the number of characters selected in the text box.")] + public int SelectionLength + { + get { return (_TextBoxDropDown.SelectionLength); } + set { _TextBoxDropDown.SelectionLength = value; } + } + + #endregion + + #region SelectionStart + + /// + /// Gets or sets the starting point of text selected in the text box. + /// The starting position of text selected in the text box. + /// + [Browsable(false), Category("Appearance")] + [Description("Gets or sets the starting point of text selected in the text box.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectionStart + { + get { return (_TextBoxDropDown.SelectionStart); } + set { _TextBoxDropDown.SelectionStart = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the text as it is currently displayed to the user. + /// + [Browsable(false)] + public string Text + { + get { return (_TextBoxDropDown.Text); } + set { _TextBoxDropDown.Text = value; } + } + + #endregion + + #region TextAlign + + /// + /// Gets or sets how text is aligned in a masked text box control. + /// + [Browsable(true), DefaultValue(HorizontalAlignment.Left)] + [Description("Indicates how text is aligned in a masked text box control.")] + public HorizontalAlignment TextAlign + { + get { return (_TextBoxDropDown.TextAlign); } + set { _TextBoxDropDown.TextAlign = value; } + } + + #endregion + + #region TextLength + + /// + /// Gets the length of text in the control. + /// Returns number of characters contained in the text of the control. + /// + [Browsable(false)] + public virtual int TextLength + { + get { return (_TextBoxDropDown.TextLength); } + } + + #endregion + + #region UseSystemPasswordChar + + /// + /// Gets or sets a value indicating whether + /// the operating system-supplied password character should be used. + /// + [Browsable(true), DefaultValue(false)] + [Description("Indicates whether the operating system-supplied password character should be used.")] + public bool UseSystemPasswordChar + { + get { return (_TextBoxDropDown.UseSystemPasswordChar); } + set { _TextBoxDropDown.UseSystemPasswordChar = value; } + } + + #endregion + + #region WatermarkBehavior + + /// + /// Gets or sets the watermark hiding behaviour. Default value + /// indicates that watermark is hidden when control receives input focus. + /// + [Browsable(true), DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior")] + [Description("Indicates watermark hiding behaviour.")] + public eWatermarkBehavior WatermarkBehavior + { + get { return (_TextBoxDropDown.WatermarkBehavior); } + set { _TextBoxDropDown.WatermarkBehavior = value; } + } + + #endregion + + #region WatermarkColor + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance")] + [Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return (_TextBoxDropDown.WatermarkColor); } + set { _TextBoxDropDown.WatermarkColor = value; } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return (_TextBoxDropDown.ShouldSerializeWatermarkColor()); + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + _TextBoxDropDown.ResetWatermarkColor(); + } + + #endregion + + #region WatermarkEnabled + + /// + /// Gets or sets whether watermark text is + /// displayed when control is empty. Default value is true. + /// + [Browsable(true), DefaultValue(true)] + [Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return (_TextBoxDropDown.WatermarkEnabled); } + set { _TextBoxDropDown.WatermarkEnabled = value; } + } + + #endregion + + #region WatermarkFont + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates watermark font.")] + public Font WatermarkFont + { + get { return (_TextBoxDropDown.WatermarkFont); } + set { _TextBoxDropDown.WatermarkFont = value; } + } + + #endregion + + #region WatermarkText + + /// + /// Gets or sets the watermark (tip) text displayed inside of + /// the control when Text is not set and control does not have + /// input focus. This property supports text-markup. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus.")] + [Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public string WatermarkText + { + get { return (_TextBoxDropDown.WatermarkText); } + set { _TextBoxDropDown.WatermarkText = value; } + } + + #endregion + + #endregion + + #region Method forwarding + + #region AppendText + + /// + /// Appends text to the current text of a text box. + /// + /// The text to append to the current contents of the text box. + public void AppendText(string text) + { + _TextBoxDropDown.AppendText(text); + } + + #endregion + + #region Clear + + /// + /// Clears all text from the text box control. + /// + public void Clear() + { + _TextBoxDropDown.Clear(); + } + + #endregion + + #region ClearUndo + + /// + /// Clears information about the most recent operation from the undo buffer of the text box. + /// + public void ClearUndo() + { + _TextBoxDropDown.ClearUndo(); + } + + #endregion + + #region Copy + + /// + /// Copies the current selection in the text box to the Clipboard. + /// + [UIPermission(SecurityAction.Demand, Clipboard = UIPermissionClipboard.OwnClipboard)] + public void Copy() + { + _TextBoxDropDown.Copy(); + } + + #endregion + + #region Cut + + /// + /// Moves the current selection in the text box to the Clipboard. + /// + public void Cut() + { + _TextBoxDropDown.Cut(); + } + + #endregion + + #region DeselectAll + + /// + /// Specifies that the value of the SelectionLength + /// property is zero so that no characters are selected in the control. + /// + public void DeselectAll() + { + _TextBoxDropDown.DeselectAll(); + } + + #endregion + + #region GetCharFromPosition + + /// + /// Retrieves the character that is closest to the specified location within the control. + /// + /// The location from which to seek the nearest character. + /// The character at the specified location. + public char GetCharFromPosition(Point pt) + { + return (_TextBoxDropDown.GetCharFromPosition(pt)); + } + + #endregion + + #region GetCharIndexFromPosition + + /// + /// Retrieves the index of the character nearest to the specified location. + /// + /// The location to search. + /// The zero-based character index at the specified location. + public int GetCharIndexFromPosition(Point pt) + { + return (_TextBoxDropDown.GetCharIndexFromPosition(pt)); + } + + #endregion + + #region GetFirstCharIndexFromLine + + /// + /// Retrieves the index of the first character of a given line. + /// + /// The line for which to get the index of its first character. + /// The zero-based character index in the specified line. + public int GetFirstCharIndexFromLine(int lineNumber) + { + return (_TextBoxDropDown.GetFirstCharIndexFromLine(lineNumber)); + } + + #endregion + + #region GetFirstCharIndexOfCurrentLine + + /// + /// Retrieves the index of the first character of the current line. + /// + /// The zero-based character index in the current line. + public int GetFirstCharIndexOfCurrentLine() + { + return (_TextBoxDropDown.GetFirstCharIndexOfCurrentLine()); + } + + #endregion + + #region GetLineFromCharIndex + + /// + /// Retrieves the line number from the specified character position within the text of the control. + /// + /// The character index position to search. + /// The zero-based line number in which the character index is located. + public int GetLineFromCharIndex(int index) + { + return (_TextBoxDropDown.GetLineFromCharIndex(index)); + } + + /// + /// Retrieves the location within the control at the specified character index. + /// + /// The index of the character for which to retrieve the location. + /// The location of the specified character. + public virtual Point GetPositionFromCharIndex(int index) + { + return _TextBoxDropDown.GetPositionFromCharIndex(index); + } + + /// + /// Replaces the current selection in the text box with the contents of the Clipboard. + /// + [UIPermission(SecurityAction.Demand, Clipboard = UIPermissionClipboard.OwnClipboard)] + public void Paste() + { + _TextBoxDropDown.Paste(); + } + + /// + /// Selects a range of text in the text box. + /// + /// The position of the first character in the current text selection within the text box. + /// The number of characters to select. + public void Select(int start, int length) + { + _TextBoxDropDown.Select(start, length); + } + + /// + /// Selects all text in the text box. + /// + public void SelectAll() + { + _TextBoxDropDown.SelectAll(); + } + + /// + /// Undoes the last edit operation in the text box. + /// + public void Undo() + { + _TextBoxDropDown.Undo(); + } + + /// + /// Replaces the specified selection in the TextBox with the contents of the Clipboard. + /// + /// The text to replace. + public void Paste(string text) + { + _TextBoxDropDown.Paste(text); + } + #endregion + + #endregion + + #region Event processing + + #region DoButtonClearClick + + /// + /// DoButtonClearClick + /// + /// + /// + internal void DoButtonClearClick(object sender, CancelEventArgs e) + { + if (ButtonClearClick != null) + ButtonClearClick(this, e); + } + + #endregion + + #region DoButtonCustomClick + + /// + /// DoButtonCustomClick + /// + /// + /// + internal void DoButtonCustomClick(object sender, EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + #endregion + + #region DoButtonCustom2Click + + /// + /// DoButtonCustom2Click + /// + /// + /// + internal void DoButtonCustom2Click(object sender, EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + #endregion + + #region DoButtonDropDownClick + + /// + /// DoButtonDropDownClick + /// + /// + /// + internal void DoButtonDropDownClick(object sender, CancelEventArgs e) + { + if (ButtonDropDownClick != null) + ButtonDropDownClick(this, e); + } + + #endregion + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + internal Bitmap GetCellBitmap(Rectangle cellBounds) + { + if (_CellBitmap == null || + (_CellBitmap.Width != cellBounds.Width || _CellBitmap.Height < cellBounds.Height)) + { + if (_CellBitmap != null) + _CellBitmap.Dispose(); + + _CellBitmap = new Bitmap(cellBounds.Width, cellBounds.Height); + } + + return (_CellBitmap); + } + + #endregion + + #region OnBeforeCellPaint + + /// + /// Invokes BeforeCellPaint user events + /// + /// Row index + /// Column index + internal void OnBeforeCellPaint(int rowIndex, int columnIndex) + { + if (BeforeCellPaint != null) + BeforeCellPaint(this, new BeforeCellPaintEventArgs(rowIndex, columnIndex)); + } + + #endregion + + #region ICloneable members + + /// + /// Clones the ButtonX Column + /// + /// + public override object Clone() + { + DataGridViewTextBoxDropDownColumn dc = base.Clone() as DataGridViewTextBoxDropDownColumn; + + if (dc != null) + { + dc.AutoCompleteCustomSource = AutoCompleteCustomSource; + dc.AutoCompleteMode = AutoCompleteMode; + dc.AutoCompleteSource = AutoCompleteSource; + dc.BackColor = BackColor; + dc.CharacterCasing = CharacterCasing; + dc.DropDownControl = DropDownControl; + dc.Enabled = Enabled; + dc.FocusHighlightColor = FocusHighlightColor; + dc.FocusHighlightEnabled = FocusHighlightEnabled; + dc.ForeColor = ForeColor; + dc.HideSelection = HideSelection; + dc.ImeMode = ImeMode; + dc.MaxLength = MaxLength; + dc.PasswordChar = PasswordChar; + dc.RightToLeft = RightToLeft; + dc.TextAlign = TextAlign; + dc.UseSystemPasswordChar = UseSystemPasswordChar; + dc.WatermarkBehavior = WatermarkBehavior; + dc.WatermarkColor = WatermarkColor; + dc.WatermarkEnabled = WatermarkEnabled; + dc.WatermarkFont = WatermarkFont; + dc.WatermarkText = WatermarkText; + + dc.DisplayControlForCurrentCellOnly = DisplayControlForCurrentCellOnly; + + dc.BackgroundStyle.ApplyStyle(TextBoxDropDown.BackgroundStyle); + dc.BackgroundStyle.Class = TextBoxDropDown.BackgroundStyle.Class; + + TextBoxDropDown.ButtonClear.CopyToItem(dc.TextBoxDropDown.ButtonClear); + TextBoxDropDown.ButtonDropDown.CopyToItem(dc.TextBoxDropDown.ButtonDropDown); + TextBoxDropDown.ButtonCustom.CopyToItem(dc.TextBoxDropDown.ButtonCustom); + TextBoxDropDown.ButtonCustom2.CopyToItem(dc.TextBoxDropDown.ButtonCustom2); + } + + return (dc); + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + if (disposing == true) + _TextBoxDropDown.Dispose(); + + if (_CellBitmap != null) + { + _CellBitmap.Dispose(); + _CellBitmap = null; + } + + base.Dispose(disposing); + } + + #endregion + + #region IDataGridViewColumn Members + + /// + /// Gets the Cell paint setting for the control + /// + [Browsable(false)] + public bool OwnerPaintCell + { + get { return (true); } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewTextBoxDropDown/DataGridViewTextBoxDropDownEditingControl.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewTextBoxDropDown/DataGridViewTextBoxDropDownEditingControl.cs new file mode 100644 index 00000000..3b0bab39 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/DataGridViewTextBoxDropDown/DataGridViewTextBoxDropDownEditingControl.cs @@ -0,0 +1,185 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), ComVisible(false)] + public class DataGridViewTextBoxDropDownEditingControl : TextBoxDropDown, IDataGridViewEditingControl + { + #region Private variables + + private DataGridView _DataGridView; + + private int _RowIndex; + private bool _ValueChanged; + + #endregion + + #region OnTextChanged + + /// + /// Handles OnTextChanged events + /// + /// + protected override void OnTextChanged(EventArgs e) + { + _ValueChanged = true; + + _DataGridView.NotifyCurrentCellDirty(true); + + base.OnTextChanged(e); + } + + #endregion + + #region IDataGridViewEditingControl Members + + #region Public properties + + #region EditingControlDataGridView + + /// + /// Gets or sets the DataGridView + /// + public DataGridView EditingControlDataGridView + { + get { return (_DataGridView); } + set { _DataGridView = value; } + } + + #endregion + + #region EditingControlFormattedValue + + /// + /// Gets or sets the Control Formatted Value + /// + public object EditingControlFormattedValue + { + get { return (Text); } + set { Text = (string)value; } + } + + #endregion + + #region EditingControlRowIndex + + /// + /// Gets or sets the Control RoeIndex + /// + public int EditingControlRowIndex + { + get { return (_RowIndex); } + set { _RowIndex = value; } + } + + #endregion + + #region EditingControlValueChanged + + /// + /// Gets or sets the Control ValueChanged state + /// + public bool EditingControlValueChanged + { + get { return (_ValueChanged); } + set { _ValueChanged = value; } + } + + #endregion + + #region EditingPanelCursor + + /// + /// Gets the Panel Cursor + /// + public Cursor EditingPanelCursor + { + get { return (base.Cursor); } + } + + #endregion + + #region RepositionEditingControlOnValueChange + + /// + /// Gets whether to RepositionEditingControlOnValueChange + /// + public bool RepositionEditingControlOnValueChange + { + get { return (false); } + } + + #endregion + + #endregion + + #region ApplyCellStyleToEditingControl + + /// + /// ApplyCellStyleToEditingControl + /// + /// + public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) + { + Font = dataGridViewCellStyle.Font; + + ForeColor = dataGridViewCellStyle.ForeColor; + BackColor = dataGridViewCellStyle.BackColor; + } + + #endregion + + #region GetEditingControlFormattedValue + + /// + /// Gets EditingControlFormattedValue + /// + /// + /// + public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) + { + return (EditingControlFormattedValue); + } + + #endregion + + #region EditingControlWantsInputKey + + /// + /// Gets whether the given key wants to be processed + /// by the Control + /// + /// + /// + /// + public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) + { + if ((keyData & Keys.Right) == Keys.Right) + return (true); + + if ((keyData & Keys.Left) == Keys.Left) + return (true); + + return (dataGridViewWantsInputKey == false); + } + + #endregion + + #region PrepareEditingControlForEdit + + /// + /// PrepareEditingControlForEdit + /// + /// + public void PrepareEditingControlForEdit(bool selectAll) + { + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DataGridViewX/IDataGridViewColumn.cs b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/IDataGridViewColumn.cs new file mode 100644 index 00000000..8414b50e --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DataGridViewX/IDataGridViewColumn.cs @@ -0,0 +1,14 @@ +namespace DevComponents.DotNetBar.Controls +{ + internal interface IDataGridViewColumn + { + /// + /// Gets whether the Column cells will fully paint + /// their cell background and content + /// + bool OwnerPaintCell + { + get; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DesktopAlert/DesktopAlert.cs b/PROMS/DotNetBar Source Code/Controls/DesktopAlert/DesktopAlert.cs new file mode 100644 index 00000000..0bdc9a82 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DesktopAlert/DesktopAlert.cs @@ -0,0 +1,511 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Displays the desktop alerts with optional image or symbol. Text on alerts supports text-markup. + /// + public static class DesktopAlert + { + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + public static void Show(string text) + { + Show(text, _AlertColor, _AlertPosition, null); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Specifies reference control which is used to find target screen alert is displayed on. + public static void Show(string text, Control referenceControl) + { + Show(text, _AlertColor, _AlertPosition, null, referenceControl); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Text-markup link click event handler. + public static void Show(string text, MarkupLinkClickEventHandler markupLinkClickHandler) + { + Show(text, _AlertColor, _AlertPosition, markupLinkClickHandler); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Specifies alert color. + public static void Show(string text, eDesktopAlertColor alertColor) + { + Show(text, alertColor, _AlertPosition, null); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Specifies alert color. + /// Specifies reference control which is used to find target screen alert is displayed on. + public static void Show(string text, eDesktopAlertColor alertColor, Control referenceControl) + { + Show(text, alertColor, _AlertPosition, null, referenceControl); + } + + /// + /// Shows desktop alert at specific screen position. + /// + /// Text to show on the alert. Text supports text-markup. + /// Alert position on the screen. + public static void Show(string text, eAlertPosition position) + { + Show(text, _AlertColor, position, null); + } + + /// + /// Shows desktop alert at specific screen position. + /// + /// Text to show on the alert. Text supports text-markup. + /// Alert position on the screen. + /// Specifies reference control which is used to find target screen alert is displayed on. + public static void Show(string text, eAlertPosition position, Control referenceControl) + { + Show(text, _AlertColor, position, null, referenceControl); + } + + /// + /// Shows desktop alert at specific screen position. + /// + /// Text to show on the alert. Text supports text-markup. + /// Image to display on alert. + public static void Show(string text, Image image) + { + Show(text, image, _AlertColor, _AlertPosition, _AutoCloseTimeOut, 0, null); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Alert color. + /// Alert position on the screen. + public static void Show(string text, eDesktopAlertColor alertColor, eAlertPosition position) + { + Show(text, alertColor, position, null); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Alert color + /// Alert position on the screen + /// Text-markup link click event handler. + /// Specifies reference control which is used to find target screen alert is displayed on. + public static void Show(string text, eDesktopAlertColor alertColor, eAlertPosition position, MarkupLinkClickEventHandler markupLinkClickHandler, Control referenceControl) + { + DesktopAlertWindow alert = new DesktopAlertWindow(); + alert.Text = text; + alert.MaximumSize = Dpi.Size(_MaximumAlertSize); + alert.AlertPosition = position; + alert.AutoCloseTimeOut = _AutoCloseTimeOut; + alert.TextMarkupEnabled = _TextMarkupEnabled; + if (markupLinkClickHandler != null) + alert.MarkupLinkClick += markupLinkClickHandler; + alert.AlertAnimationDuration = _AlertAnimationDuration; + alert.PlaySound = _PlaySound; + alert.ReferenceControl = referenceControl; + SetColors(alert, alertColor); + alert.Show(); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Alert color + /// Alert position on the screen + /// Text-markup link click event handler. + public static void Show(string text, eDesktopAlertColor alertColor, eAlertPosition position, MarkupLinkClickEventHandler markupLinkClickHandler) + { + Show(text, alertColor, position, markupLinkClickHandler, null); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Alert ID used to recognize alert if clicked and specified Action is called + /// Action method to call if alert is clicked. + public static void Show(string text, long alertId, Action alertClickAction) + { + Show(text, null, _AlertColor, _AlertPosition, _AutoCloseTimeOut, alertId, alertClickAction); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Alert color + /// Alert ID used to recognize alert if clicked and specified Action is called + /// Action method to call if alert is clicked. + public static void Show(string text, eDesktopAlertColor alertColor, long alertId, Action alertClickAction) + { + Show(text, null, alertColor, _AlertPosition, _AutoCloseTimeOut, alertId, alertClickAction); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Symbol to show on the alert, see http://www.devcomponents.com/kb2/?p=1347 + /// Symbol set to use + /// Symbol color or Color.Empty to use default text color + /// Alert color + /// Alert position on the screen + /// Duration of alert in the seconds. + /// Alert ID used to recognize alert if clicked and specified Action is called + /// Action method to call if alert is clicked. + public static void Show(string text, string symbol, eSymbolSet symbolSet, Color symbolColor, eDesktopAlertColor alertColor, eAlertPosition position, + int alertDurationSeconds, long alertId, Action alertClickAction) + { + Show(text, symbol, symbolSet, symbolColor, alertColor,position, alertDurationSeconds, alertId, alertClickAction, null); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Symbol to show on the alert, see http://www.devcomponents.com/kb2/?p=1347 + /// Symbol set to use + /// Symbol color or Color.Empty to use default text color + /// Alert position on the screen + /// Alert color + /// Duration of alert in the seconds. + /// Alert ID used to recognize alert if clicked and specified Action is called + /// Action method to call if alert is clicked. + /// Text-markup link click event handler. + public static void Show(string text, string symbol, eSymbolSet symbolSet, Color symbolColor, eDesktopAlertColor alertColor, eAlertPosition position, + int alertDurationSeconds, long alertId, Action alertClickAction, MarkupLinkClickEventHandler markupLinkClickHandler) + { + Show(text, symbol, symbolSet, symbolColor, alertColor, position, alertDurationSeconds, alertId, alertClickAction, markupLinkClickHandler, null); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Symbol to show on the alert, see http://www.devcomponents.com/kb2/?p=1347 + /// Symbol set to use + /// Symbol color or Color.Empty to use default text color + /// Alert position on the screen + /// Alert color + /// Duration of alert in the seconds. + /// Alert ID used to recognize alert if clicked and specified Action is called + /// Action method to call if alert is clicked. + /// Text-markup link click event handler. + /// Specifies reference control which is used to find target screen alert is displayed on. + public static void Show(string text, string symbol, eSymbolSet symbolSet, Color symbolColor, eDesktopAlertColor alertColor, eAlertPosition position, + int alertDurationSeconds, long alertId, Action alertClickAction, MarkupLinkClickEventHandler markupLinkClickHandler, Control referenceControl) + { + DesktopAlertWindow alert = new DesktopAlertWindow(); + alert.Text = text; + alert.MaximumSize = Dpi.Size(_MaximumAlertSize); + alert.AlertPosition = position; + alert.Symbol = symbol; + alert.SymbolSet = symbolSet; + alert.SymbolColor = symbolColor; + alert.AlertId = alertId; + alert.ClickAction = alertClickAction; + alert.AutoCloseTimeOut = alertDurationSeconds; + alert.TextMarkupEnabled = _TextMarkupEnabled; + if (markupLinkClickHandler != null) + alert.MarkupLinkClick += markupLinkClickHandler; + alert.AlertAnimationDuration = _AlertAnimationDuration; + alert.PlaySound = _PlaySound; + alert.ReferenceControl = referenceControl; + SetColors(alert, alertColor); + alert.Show(); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Image to display on the alert + /// Alert screen position + /// Alert color + /// Duration of alert in seconds + /// Alert ID used to recognize alert if clicked and specified Action is called + /// Action method to call if alert is clicked. + public static void Show(string text, Image image, eDesktopAlertColor alertColor, eAlertPosition position, + int alertDurationSeconds, long alertId, Action alertClickAction) + { + Show(text, image, alertColor, position, alertDurationSeconds, alertId, alertClickAction, null); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Image to display on the alert + /// Alert screen position + /// Alert color + /// Duration of alert in seconds + /// Alert ID used to recognize alert if clicked and specified Action is called + /// Action method to call if alert is clicked. + /// Text-markup link click event handler. + public static void Show(string text, Image image, eDesktopAlertColor alertColor, eAlertPosition position, + int alertDurationSeconds, long alertId, Action alertClickAction, MarkupLinkClickEventHandler markupLinkClickHandler) + { + Show(text, image, alertColor, position, alertDurationSeconds, alertId, alertClickAction, markupLinkClickHandler, null); + } + + /// + /// Shows desktop alert. + /// + /// Text to show on the alert. Text supports text-markup. + /// Image to display on the alert + /// Alert screen position + /// Alert color + /// Duration of alert in seconds + /// Alert ID used to recognize alert if clicked and specified Action is called + /// Action method to call if alert is clicked. + /// Text-markup link click event handler. + /// Specifies reference control which is used to find target screen alert is displayed on. + public static void Show(string text, Image image, eDesktopAlertColor alertColor, eAlertPosition position, + int alertDurationSeconds, long alertId, Action alertClickAction, MarkupLinkClickEventHandler markupLinkClickHandler, Control referenceControl) + { + DesktopAlertWindow alert = new DesktopAlertWindow(); + alert.Text = text; + alert.MaximumSize = Dpi.Size(_MaximumAlertSize); + alert.AlertPosition = position; + alert.Image = image; + alert.AlertId = alertId; + alert.ClickAction = alertClickAction; + alert.AutoCloseTimeOut = alertDurationSeconds; + alert.TextMarkupEnabled = _TextMarkupEnabled; + if (markupLinkClickHandler != null) + alert.MarkupLinkClick += markupLinkClickHandler; + alert.AlertAnimationDuration = _AlertAnimationDuration; + alert.PlaySound = _PlaySound; + alert.ReferenceControl = referenceControl; + SetColors(alert, alertColor); + alert.Show(); + } + + private static void SetColors(DesktopAlertWindow w, eDesktopAlertColor c) + { + if (c == eDesktopAlertColor.Default) + { + w.BackColor = ColorScheme.GetColor(0x0078D7); + w.ForeColor = Color.White; + } + else if (c == eDesktopAlertColor.Black) + { + w.BackColor = Color.Black; + w.ForeColor = Color.White; + } + else if (c == eDesktopAlertColor.Blue) + { + w.BackColor = ColorScheme.GetColor(0x5B9BD5); + w.ForeColor = Color.White; + } + else if (c == eDesktopAlertColor.BlueGray) + { + w.BackColor = ColorScheme.GetColor(0x44546A); + w.ForeColor = Color.White; + } + else if (c == eDesktopAlertColor.DarkBlue) + { + w.BackColor = ColorScheme.GetColor(0x4472C4); + w.ForeColor = Color.White; + } + else if (c == eDesktopAlertColor.DarkRed) + { + w.BackColor = ColorScheme.GetColor(0xC00000); + w.ForeColor = Color.White; + } + else if (c == eDesktopAlertColor.Gold) + { + w.BackColor = ColorScheme.GetColor(0xFFC000); + w.ForeColor = Color.Black; + } + else if (c == eDesktopAlertColor.Gray) + { + w.BackColor = ColorScheme.GetColor(0xE7E6E6); + w.ForeColor = Color.Black; + } + else if (c == eDesktopAlertColor.Green) + { + w.BackColor = ColorScheme.GetColor(0x375623); + w.ForeColor = Color.White; + } + else if (c == eDesktopAlertColor.Orange) + { + w.BackColor = ColorScheme.GetColor(0xCA5010); + w.ForeColor = Color.White; + } + else if (c == eDesktopAlertColor.Red) + { + w.BackColor = ColorScheme.GetColor(0xE81123); + w.ForeColor = Color.White; + } + } + + private static Size _MaximumAlertSize = new Size(400, 128); + /// + /// Indicates maximum alert size. + /// + public static Size MaximumAlertSize + { + get { return _MaximumAlertSize; } + set { _MaximumAlertSize = value; } + } + + private static eAlertPosition _AlertPosition = eAlertPosition.BottomRight; + /// + /// Specifies default alert screen position. + /// + public static eAlertPosition AlertPosition + { + get { return _AlertPosition; } + set { _AlertPosition = value; } + } + + private static eDesktopAlertColor _AlertColor = eDesktopAlertColor.Default; + /// + /// Specifies default alert color. + /// + public static eDesktopAlertColor AlertColor + { + get { return _AlertColor; } + set { _AlertColor = value; } + } + + private static int _AlertAnimationDuration = 200; + /// + /// Gets or sets the total time in milliseconds alert animation takes. + /// Default value is 200. + /// + public static int AlertAnimationDuration + { + get { return _AlertAnimationDuration; } + set { _AlertAnimationDuration = value; } + } + + private static int _AutoCloseTimeOut = 6; + /// + /// Gets or sets time period in seconds after alert closes automatically. + /// + public static int AutoCloseTimeOut + { + get { return _AutoCloseTimeOut; } + set { _AutoCloseTimeOut = value; } + } + + private static bool _TextMarkupEnabled = true; + /// + /// Gets or sets whether text-markup can be used in alert text, default value is true. + /// + public static bool TextMarkupEnabled + { + get { return _TextMarkupEnabled; } + set { _TextMarkupEnabled = value; } + } + + private static bool _PlaySound = true; + /// + /// Indicates whether alert plays exclamation sound when shown. + /// + public static bool PlaySound + { + get { return _PlaySound; } + set { _PlaySound = value; } + } + + /// + /// Occurs before alert is displayed and allows access to the alert Window through sender. + /// + [Description("Occurs before alert is displayed and allows access to the alert Window through sender.")] + public static event EventHandler BeforeAlertDisplayed; + + /// + /// Raises BeforeAlertDisplayed event. + /// + /// Provides event arguments. + internal static void OnBeforeAlertDisplayed(DesktopAlertWindow w, EventArgs e) + { + EventHandler h = BeforeAlertDisplayed; + if (h != null) + h(w, e); + } + + /// + /// Occurs after alert as been closed. + /// + [Description("Occurs after alert has been closed.")] + public static event AlertClosedEventHandler AlertClosed; + + /// + /// Raises RemovingToken event. + /// + /// Provides event arguments. + internal static void OnAlertClosed(object sender, AlertClosedEventArgs e) + { + AlertClosedEventHandler handler = AlertClosed; + if (handler != null) + handler(sender, e); + } + } + + /// + /// Defines delegate for AlertClosed event. + /// + /// Sender. + /// Event arguments + public delegate void AlertClosedEventHandler(object sender, AlertClosedEventArgs args); + /// + /// Defines event arguments for AlertClosed event. + /// + public class AlertClosedEventArgs : EventArgs + { + /// + /// Specifies alert closure source. + /// + public readonly eAlertClosureSource ClosureSource; + + public AlertClosedEventArgs(eAlertClosureSource source) + { + ClosureSource = source; + } + } + + /// + /// Defines predefined desktop alert colors. + /// + public enum eDesktopAlertColor + { + Default, + DarkRed, + Black, + Gray, + BlueGray, + Blue, + Orange, + Gold, + DarkBlue, + Green, + Red + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/DesktopAlert/DesktopAlertWindow.cs b/PROMS/DotNetBar Source Code/Controls/DesktopAlert/DesktopAlertWindow.cs new file mode 100644 index 00000000..f2460c19 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/DesktopAlert/DesktopAlertWindow.cs @@ -0,0 +1,1478 @@ +using DevComponents.DotNetBar.Rendering; +using DevComponents.DotNetBar.TextMarkup; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Threading; +using System.Windows.Forms; +using System.Windows.Forms.VisualStyles; +using DevComponents.DotNetBar.Metro.Helpers; + +namespace DevComponents.DotNetBar.Controls +{ + public class DesktopAlertWindow : Form + { + #region Constructor + public DesktopAlertWindow() + { + this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque | + ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer, true); + + this.AccessibleRole = System.Windows.Forms.AccessibleRole.Alert; + this.ClientSize = DefaultAlertSizeValue; + this.AutoScaleDimensions = new SizeF(96f, 96f); + this.AutoScaleMode = AutoScaleMode.Dpi; + this.ControlBox = false; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.ShowInTaskbar = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.Manual; + this.Padding = new System.Windows.Forms.Padding(8); + this.Font = new Font("Segoe UI", 10.125F); + } + + protected override void Dispose(bool disposing) + { + DestroyAutoCloseTimer(); + base.Dispose(disposing); + } + #endregion + + #region Implementation + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + Color backColor = this.BackColor; + Color foreColor = this.ForeColor; + + using (SolidBrush brush = new SolidBrush(backColor)) + g.FillRectangle(brush, this.ClientRectangle); + + if (_CloseButtonVisible) + { + Font symFont = Symbols.GetFont(12f, eSymbolSet.Material); + TextDrawing.DrawStringLegacy(g, "\uE14C", symFont, + (_CloseButtonMouseOver ? ColorHelpers.GetShadeColor(foreColor) : foreColor), + _CloseButtonBounds, + eTextFormat.Default | eTextFormat.NoClipping); + } + + if (!string.IsNullOrEmpty(_SymbolRealized)) + { + Font symFont = Symbols.GetFont(_SymbolSize, _SymbolSet); + + TextDrawing.DrawStringLegacy(g, _SymbolRealized, symFont, _SymbolColor.IsEmpty ? foreColor : _SymbolColor, + _ImageBounds, + eTextFormat.Default | eTextFormat.NoClipping | eTextFormat.VerticalCenter); + } + else if (_Image != null) + { + g.DrawImage(_Image, _ImageBounds); + } + + Rectangle r = _TextBounds; + if (r.Bottom > this.ClientRectangle.Bottom - this.Padding.Bottom) + r.Height -= (r.Bottom - (this.ClientRectangle.Bottom - this.Padding.Bottom)); + eTextFormat format = TextFormat; + if (_TextMarkup == null) + { + if (this.RightToLeft == RightToLeft.Yes) format |= eTextFormat.RightToLeft; + if (UseTextRenderer) + { + TextRenderer.DrawText(g, Text, Font, r, foreColor, backColor, + TextDrawing.GetTextFormatFlags(format)); + } + else + TextDrawing.DrawString(g, Text, this.Font, foreColor, r, format); + } + else + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, foreColor, + (this.RightToLeft == RightToLeft.Yes), r, true); + Size markupSize = _TextMarkup.Bounds.Size; + if (!markupSize.IsEmpty && (format & eTextFormat.VerticalCenter) == eTextFormat.VerticalCenter && r.Height>markupSize.Height) + { + r.Y += (r.Height - markupSize.Height) / 2; + r.Height = markupSize.Height; + } + _TextMarkup.Arrange(r, d); + _TextMarkup.Render(d); + } + + base.OnPaint(e); + } + private eTextFormat TextFormat + { + get + { + return eTextFormat.Default | eTextFormat.WordBreak | eTextFormat.VerticalCenter | eTextFormat.EndEllipsis; + } + } + + protected override void OnMouseEnter(EventArgs e) + { + if (_AutoClose && _AutoCloseTimer != null) + _AutoCloseTimer.Enabled = false; + base.OnMouseEnter(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + if (_TextMarkup != null) + _TextMarkup.MouseLeave(this); + if (_AutoClose && _AutoCloseTimer != null) + _AutoCloseTimer.Enabled = true; + base.OnMouseLeave(e); + } + + private bool _CloseButtonMouseOver = false; + protected override void OnMouseMove(MouseEventArgs e) + { + if (_CloseButtonVisible && _CloseButtonBounds.Contains(e.Location)) + { + _CloseButtonMouseOver = true; + Invalidate(_CloseButtonBounds); + } + else if (_CloseButtonMouseOver) + { + _CloseButtonMouseOver = false; + Invalidate(_CloseButtonBounds); + } + + if (_TextMarkup != null) + _TextMarkup.MouseMove(this, e); + + base.OnMouseMove(e); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + if (_TextMarkup != null) + _TextMarkup.MouseDown(this, e); + base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + if (_TextMarkup != null) + _TextMarkup.MouseUp(this, e); + + if (_CloseButtonMouseOver && e.Button == MouseButtons.Left) + this.HideAlert(eAlertClosureSource.CloseButton); + base.OnMouseUp(e); + } + + private bool _AutoSize = true; + [DefaultValue(true)] + public override bool AutoSize + { + get + { + return _AutoSize; + } + set + { + _AutoSize = value; + } + } + + private Rectangle _ImageBounds = Rectangle.Empty; + private Rectangle _TextBounds = Rectangle.Empty; + private Rectangle _CloseButtonBounds = Rectangle.Empty; + /// + /// Sets alert size based on its content, it respects MinimumSize and MaximumSize property settings. + /// + public void PerformAutoSize() + { + Size size = Dpi.Size(_DefaultAlertSize); + if (!this.MinimumSize.IsEmpty) + size = Dpi.Size(this.MinimumSize); + + if (!this.IsHandleCreated) + this.CreateHandle(); + + size = LayoutAlert(size); + + Size maximumSize = this.MaximumSize; + if (!maximumSize.IsEmpty) + { + if (maximumSize.Width > 0 && size.Width > maximumSize.Width) + size.Width = maximumSize.Width; + if (maximumSize.Height > 0 && size.Height > maximumSize.Height) + size.Height = maximumSize.Height; + size = LayoutAlert(size); + } + + this.Size = size; + } + + private Size LayoutAlert(Size size) + { + Rectangle r = new Rectangle(Point.Empty, size); + r.X += Dpi.Width(this.Padding.Left); + r.Width -= Dpi.Width(this.Padding.Horizontal); + r.Y += Dpi.Height(this.Padding.Top); + r.Height -= Dpi.Height(this.Padding.Vertical); + + if (!string.IsNullOrEmpty(Text) || !string.IsNullOrEmpty(_SymbolRealized) || _Image != null) + { + using (Graphics g = BarFunctions.CreateGraphics(this)) + { + if (_CloseButtonVisible) + { + Font symFont = Symbols.GetFont(12f, eSymbolSet.Material); + Size closeSize = TextDrawing.MeasureString(g, "\uE14C", symFont); // Need to do this to get consistent size for the symbol since they are not all the same width we pick widest + _CloseButtonBounds = new Rectangle(r.Right - closeSize.Width - Dpi.Width4, r.Y + Dpi.Height4, closeSize.Width, closeSize.Height); + r.Width -= closeSize.Width + Dpi.Width8; + } + + + _ImageBounds = Rectangle.Empty; + if (!string.IsNullOrEmpty(_SymbolRealized)) + { + Size symSize = GetSymbolSize(g); + symSize.Width += Dpi.Width2; + _ImageBounds = new Rectangle(r.X, r.Y, symSize.Width, symSize.Height); + r.X += symSize.Width + _ImageTextPadding; + r.Width -= symSize.Width + _ImageTextPadding; + if (symSize.Height > r.Height) + { + size.Height += (symSize.Height - r.Height); + r.Height = symSize.Height; + } + else + { + _ImageBounds.Height = r.Height; + } + } + else if (_Image != null) + { + _ImageBounds = new Rectangle(r.X, r.Y, _Image.Width, _Image.Height); + r.X += _Image.Width + _ImageTextPadding; + r.Width -= _Image.Width + _ImageTextPadding; + if (_Image.Height > r.Height) + { + size.Height += (_Image.Height - r.Height); + r.Height = _Image.Height; + } + } + + _TextBounds = Rectangle.Empty; + + if (_TextMarkup != null) + { + MarkupDrawContext dc = GetMarkupDrawContext(g); + _TextMarkup.Measure(r.Size, dc); + Size sz = _TextMarkup.Bounds.Size; + _TextMarkup.Arrange(new Rectangle(r.Location, sz), dc); + if (sz.Width > r.Width) + { + size.Width += (sz.Width - r.Width); + r.Width = size.Width; + } + if (sz.Height > r.Height) + { + size.Height += (sz.Height - r.Height); + r.Height = size.Height; + } + _TextBounds = r; + } + else if (!string.IsNullOrEmpty(this.Text)) + { + Size sz = (UseTextRenderer ? TextRenderer.MeasureText(g, this.Text, this.Font, r.Size, TextDrawing.GetTextFormatFlags(TextFormat)) : TextDrawing.MeasureString(g, this.Text, this.Font, size, TextFormat)); + if (sz.Width > r.Width) + { + size.Width += (sz.Width - r.Width); + r.Width = size.Width; + } + if (sz.Height > r.Height) + { + size.Height += (sz.Height - r.Height); + r.Height = size.Height; + } + _TextBounds = r; + } + } + } + + return size; + } + + private MarkupDrawContext GetMarkupDrawContext(Graphics g) + { + return new MarkupDrawContext(g, this.Font, this.ForeColor, this.RightToLeft == RightToLeft.Yes); + } + private Size GetSymbolSize(Graphics g) + { + Size symbolSize = Size.Empty; + if (g == null || string.IsNullOrEmpty(_Symbol)) return symbolSize; + Font symFont = Symbols.GetFont(this.SymbolSize, this.SymbolSet); + symbolSize = TextDrawing.MeasureString(g, "\uF00A", symFont); // Need to do this to get consistent size for the symbol since they are not all the same width we pick widest + //int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) * + // symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style))); + //symbolSize.Height -= descent; + return symbolSize; + } + + //private Color[] _BackColors = null; + ///// + ///// Indicates the array of colors that when set are used to draw the background of the alert. + ///// + //[DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the background of the alert."), TypeConverter(typeof(ArrayConverter))] + //public Color[] BackColors + //{ + // get + // { + // return _BackColors; + // } + // set + // { + // if (_BackColors != value) + // { + // _BackColors = value; + // this.Invalidate(); + // } + // } + //} + + //private Color[] _BorderColors = null; + ///// + ///// Indicates the array of colors that when set are used to draw the border of the alert. + ///// + //[DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the border of the alert."), TypeConverter(typeof(ArrayConverter))] + //public Color[] BorderColors + //{ + // get + // { + // return _BorderColors; + // } + // set + // { + // if (_BorderColors != value) + // { + // _BorderColors = value; + // //OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + // this.Invalidate(); + // } + // } + //} + + private Color _SymbolColor = Color.Empty; + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return _SymbolColor; } + set { _SymbolColor = value; this.Invalidate(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return !_SymbolColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + this.SymbolColor = Color.Empty; + } + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get { return _SymbolRealized; } + } + private string _Symbol = "", _SymbolRealized = ""; + /// + /// Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return _Symbol; } + set + { + if (value != _Symbol) + { + string oldValue = _Symbol; + _Symbol = value; + OnSymbolChanged(oldValue, value); + } + } + } + /// + /// Called when Symbol property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolChanged(string oldValue, string newValue) + { + if (string.IsNullOrEmpty(newValue)) + _SymbolRealized = ""; + else + _SymbolRealized = Symbols.GetSymbol(newValue); + this.Invalidate(); + } + + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return _SymbolSet; } + set + { + if (_SymbolSet != value) + { + eSymbolSet oldValue = _SymbolSet; + _SymbolSet = value; + OnSymbolSetChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSet property value changes. + /// + /// Indciates old value + /// Indicates new value + protected virtual void OnSymbolSetChanged(eSymbolSet oldValue, eSymbolSet newValue) + { + this.Invalidate(); + this.Refresh(); + } + + + private float _SymbolSize = 22f; + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(22f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return _SymbolSize; } + set + { + if (value != _SymbolSize) + { + float oldValue = _SymbolSize; + _SymbolSize = value; + OnSymbolSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolSizeChanged(float oldValue, float newValue) + { + this.Invalidate(); + } + + private Image _Image = null; + /// + /// Indicates image displayed on alert. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates image displayed on alert.")] + public Image Image + { + get { return _Image; } + set + { + _Image = value; + this.Invalidate(); + } + } + + protected override void OnTextChanged(EventArgs e) + { + // Markup support + MarkupTextChanged(); + base.OnTextChanged(e); + } + + //private string _TitleText = ""; + ///// + ///// Gets or sets the tile title text displayed by default in lower left corner. + ///// + //[DefaultValue(""), Category("Appearance"), Description("Indicates tile title text displayed by default in lower left corner"), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + //public string TitleText + //{ + // get { return _TitleText; } + // set + // { + // if (value != _TitleText) + // { + // string oldValue = _TitleText; + // _TitleText = value; + // OnTitleTextChanged(oldValue, value); + // } + // } + //} + ///// + ///// Called when TitleText property has changed. + ///// + ///// Old property value + ///// New property value + //protected virtual void OnTitleTextChanged(string oldValue, string newValue) + //{ + // TitleTextMarkupUpdate(); + // this.Invalidate(); + // //OnPropertyChanged(new PropertyChangedEventArgs("TitleText")); + //} + ///// + ///// Gets reference to parsed markup body element if text was markup otherwise returns null. + ///// + //internal TextMarkup.BodyElement TitleTextMarkupBody + //{ + // get { return _TitleTextMarkup; } + //} + //private TextMarkup.BodyElement _TitleTextMarkup = null; + //private void TitleTextMarkupUpdate() + //{ + // if (_TitleTextMarkup != null) + // _TitleTextMarkup.HyperLinkClick -= TitleTextMarkupLinkClicked; + // _TitleTextMarkup = null; + + // if (!_TextMarkupEnabled) + // return; + + // if (!TextMarkup.MarkupParser.IsMarkup(ref _TitleText)) + // return; + + // _TitleTextMarkup = TextMarkup.MarkupParser.Parse(_TitleText); + + // if (_TitleTextMarkup != null) + // _TitleTextMarkup.HyperLinkClick += TitleTextMarkupLinkClicked; + //} + //private void TitleTextMarkupLinkClicked(object sender, EventArgs e) + //{ + // DevComponents.DotNetBar.TextMarkup.HyperLink link = sender as DevComponents.DotNetBar.TextMarkup.HyperLink; + + // if (link != null) + // OnTitleTextMarkupLinkClick(new MarkupLinkClickEventArgs(link.Name, link.HRef)); + // else + // OnTitleTextMarkupLinkClick(e); + //} + ///// + ///// Occurs when an hyperlink in title text markup is clicked. + ///// + //public event EventHandler TitleTextMarkupLinkClick; + ///// + ///// Raises TitleTextMarkupLinkClick event. + ///// + ///// Provides event arguments. + //protected virtual void OnTitleTextMarkupLinkClick(EventArgs e) + //{ + // EventHandler handler = TitleTextMarkupLinkClick; + // if (handler != null) + // handler(this, e); + //} + + + //private Font _TitleTextFont = null; + ///// + ///// Gets or sets the title text font. + ///// + //[DefaultValue(null), Category("Appearance"), Description("Gets or sets the title text font.")] + //public Font TitleTextFont + //{ + // get { return _TitleTextFont; } + // set + // { + // if (value != _TitleTextFont) + // { + // Font oldValue = _TitleTextFont; + // _TitleTextFont = value; + // OnTitleTextFontChanged(oldValue, value); + // } + // } + //} + ///// + ///// Called when TitleTextFont property has changed. + ///// + ///// Old property value + ///// New property value + //protected virtual void OnTitleTextFontChanged(Font oldValue, Font newValue) + //{ + // this.Invalidate(); + // //OnPropertyChanged(new PropertyChangedEventArgs("TitleTextFont")); + //} + //private Rectangle _TitleTextBounds = Rectangle.Empty; + //internal Rectangle TitleTextBounds + //{ + // get + // { + // return _TitleTextBounds; + // } + // set + // { + // _TitleTextBounds = value; + // } + //} + + //private Color _TitleTextColor = Color.Empty; + ///// + ///// Gets or sets the color of the title text. + ///// + //[Category("Columns"), Description("Indicates color of title text.")] + //public Color TitleTextColor + //{ + // get { return _TitleTextColor; } + // set + // { + // if (_TitleTextColor != value) + // { + // Color oldValue = _TitleTextColor; + // _TitleTextColor = value; + // OnTitleTextColorChanged(oldValue, value); + // } + // } + //} + ///// + ///// Called when TitleTextColor property has changed. + ///// + ///// Old property value + ///// New property value + //protected virtual void OnTitleTextColorChanged(Color oldValue, Color newValue) + //{ + // this.Invalidate(); + // //OnPropertyChanged(new PropertyChangedEventArgs("TitleTextColor")); + //} + ///// + ///// Gets whether property should be serialized. + ///// + //[EditorBrowsable(EditorBrowsableState.Never)] + //public bool ShouldSerializeTitleTextColor() + //{ + // return !_TitleTextColor.IsEmpty; + //} + ///// + ///// Resets property to its default value. + ///// + //[EditorBrowsable(EditorBrowsableState.Never)] + //public void ResetTitleTextColor() + //{ + // this.TitleTextColor = Color.Empty; + //} + + //private ContentAlignment _TitleTextAlignment = ContentAlignment.BottomLeft; + ///// + ///// Gets or sets title text alignment. + ///// + //[DefaultValue(ContentAlignment.BottomLeft), Category("Appearance"), Description("Indicates title text alignment.")] + //public ContentAlignment TitleTextAlignment + //{ + // get { return _TitleTextAlignment; } + // set + // { + // if (value != _TitleTextAlignment) + // { + // ContentAlignment oldValue = _TitleTextAlignment; + // _TitleTextAlignment = value; + // OnTitleTextAlignmentChanged(oldValue, value); + // } + // } + //} + ///// + ///// Called when TitleTextAlignment property has changed. + ///// + ///// Old property value + ///// New property value + //protected virtual void OnTitleTextAlignmentChanged(ContentAlignment oldValue, ContentAlignment newValue) + //{ + // //OnPropertyChanged(new PropertyChangedEventArgs("TitleTextAlignment")); + // this.Invalidate(); + //} + + protected override void OnClick(EventArgs e) + { + if (_TextMarkup != null && _TextMarkup.MouseOverElement is HyperLink) + { + _TextMarkup.Click(this); + base.OnClick(e); + return; + } + else if (_CloseButtonMouseOver) + { + base.OnClick(e); + return; + } + + if (_ClickAction != null) + { + _ClickAction.Invoke(_AlertId); + this.HideAlert(eAlertClosureSource.AlertClicked); + } + base.OnClick(e); + } + + private long _AlertId = 0; + /// + /// Indicates optional Alert Id. + /// + [Browsable(false), DefaultValue(0)] + public long AlertId { + get { return _AlertId; } + set { _AlertId = value; } + } + + private Action _ClickAction = null; + /// + /// Indicates the method that will be invoked if user clicks the alert. + /// + [Browsable(false), DefaultValue(null)] + public Action ClickAction + { + get { return _ClickAction; } + set { _ClickAction = value; } + } + + private bool _TextMarkupEnabled = true; + /// + /// Gets or sets whether text-markup can be used in Text property. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup can be used in Text property.")] + public bool TextMarkupEnabled + { + get { return _TextMarkupEnabled; } + set + { + if (value != _TextMarkupEnabled) + { + bool oldValue = _TextMarkupEnabled; + _TextMarkupEnabled = value; + OnTextMarkupEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when TextMarkupEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextMarkupEnabledChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TextMarkupEnabled")); + this.Invalidate(); + } + #endregion + + #region Markup Implementation + private TextMarkup.BodyElement _TextMarkup = null; + + private void MarkupTextChanged() + { + if (_TextMarkup != null) + _TextMarkup.HyperLinkClick -= TextMarkupLinkClick; + + _TextMarkup = null; + + if (!_TextMarkupEnabled) + return; + string text = this.Text; + if (!TextMarkup.MarkupParser.IsMarkup(ref text)) + return; + + _TextMarkup = TextMarkup.MarkupParser.Parse(text); + + if (_TextMarkup != null) + _TextMarkup.HyperLinkClick += TextMarkupLinkClick; + } + + /// + /// Occurs when text markup link is clicked. + /// + protected virtual void TextMarkupLinkClick(object sender, EventArgs e) + { + TextMarkup.HyperLink link = sender as TextMarkup.HyperLink; + if (link != null) + OnMarkupLinkClick(new MarkupLinkClickEventArgs(link.Name, link.HRef)); + } + /// + /// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + [Description("Occurs when text markup link is clicked. Markup links can be created using a tag.")] + public event MarkupLinkClickEventHandler MarkupLinkClick; + /// + /// Raises MarkupLinkClick event. + /// + /// Provides event arguments. + protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e) + { + MarkupLinkClickEventHandler handler = MarkupLinkClick; + if (handler != null) + handler(this, e); + } + + /// + /// Gets reference to parsed markup body element if text was markup otherwise returns null. + /// + internal TextMarkup.BodyElement TextMarkupBody + { + get { return _TextMarkup; } + } + + internal static Size MeasureText(DesktopAlertWindow item, Graphics g, int containerWidth, Font font, eTextFormat stringFormat, bool rightToLeft) + { + if (item.Text == "" && item.TextMarkupBody == null) return Size.Empty; + + Size textSize = Size.Empty; + + if (item.TextMarkupBody == null) + { + textSize = TextDrawing.MeasureString(g, ButtonItemPainter.GetDrawText(item.Text), font, containerWidth, stringFormat); + } + else + { + Size availSize = new Size(containerWidth, 1); + if (containerWidth == 0) + availSize.Width = 1600; + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, Color.Empty, false); + item.TextMarkupBody.Measure(availSize, d); + availSize = item.TextMarkupBody.Bounds.Size; + if (containerWidth != 0) + availSize.Width = containerWidth; + d.RightToLeft = rightToLeft; + item.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d); + + textSize = item.TextMarkupBody.Bounds.Size; + } + + return textSize; + } + + private static readonly Size DefaultAlertSizeValue = new Size(360, 64); + private Size _DefaultAlertSize = DefaultAlertSizeValue; + /// + /// Gets or sets the default alert size. + /// + [Category("Appearance"), Description("Indicates default alert size.")] + public Size DefaultAlertSize + { + get { return _DefaultAlertSize; } + set + { + if (value != _DefaultAlertSize) + { + Size oldValue = _DefaultAlertSize; + _DefaultAlertSize = value; + OnDefaultAlertSizeChanged(oldValue, value); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeDefaultAlertSize() + { + return _DefaultAlertSize.Width != DefaultAlertSizeValue.Width || _DefaultAlertSize.Height != DefaultAlertSizeValue.Height; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetDefaultAlertSize() + { + DefaultAlertSize = DefaultAlertSizeValue; + } + private void OnDefaultAlertSizeChanged(Size oldValue, Size newValue) + { + if (_AutoSize && this.IsHandleCreated) + PerformAutoSize(); + } + + //private eAlertAnimation _AlertAnimation = eAlertAnimation.RightToLeft; + ///// + ///// Gets or sets the animation type used to display Alert. + ///// + //[Browsable(true), Description("Gets or sets the animation type used to display Alert."), Category("Behavior"), DefaultValue(eAlertAnimation.RightToLeft)] + //public eAlertAnimation AlertAnimation + //{ + // get { return _AlertAnimation; } + // set { _AlertAnimation = value; } + //} + + private int _AlertAnimationDuration = 200; + /// + /// Gets or sets the total time in milliseconds alert animation takes. + /// Default value is 200. + /// + [Browsable(true), Description("Gets or sets the total time in milliseconds alert animation takes."), Category("Behavior"), DefaultValue(200)] + public int AlertAnimationDuration + { + get { return _AlertAnimationDuration; } + set { _AlertAnimationDuration = value; } + } + + private bool _AutoClose = true; + /// + /// Gets or sets whether balloon will close automatically when user click the close button. + /// + [Description("Indicates whether balloon will close automatically when user click the close button."), Category("Behavior"), DefaultValue(true)] + public bool AutoClose + { + get { return _AutoClose; } + set { _AutoClose = value; } + } + + private int _AutoCloseTimeOut = 6; + /// + /// Gets or sets time period in seconds after alert closes automatically. + /// + [Description("Indicates time period in seconds after balloon closes automatically."), Category("Behavior"), DefaultValue(6)] + public int AutoCloseTimeOut + { + get { return _AutoCloseTimeOut; } + set + { + _AutoCloseTimeOut = value; + OnAutoCloseTimeOutChanged(); + } + } + + private System.Windows.Forms.Timer _AutoCloseTimer = null; + protected void OnAutoCloseTimeOutChanged() + { + if (_AutoCloseTimeOut > 0 && !this.DesignMode) + { + StartAutoCloseTimer(); + } + else + { + DestroyAutoCloseTimer(); + } + } + + private void StartAutoCloseTimer() + { + if (_AutoCloseTimer == null) + { + _AutoCloseTimer = new System.Windows.Forms.Timer(); + _AutoCloseTimer.Enabled = false; + _AutoCloseTimer.Tick += new EventHandler(this.AutoCloseTimeOutEllapsed); + } + _AutoCloseTimer.Interval = _AutoCloseTimeOut * 1000; + if (this.Visible) + { + _AutoCloseTimer.Enabled = true; + _AutoCloseTimer.Start(); + } + } + + protected virtual void AutoCloseTimeOutEllapsed(object sender, EventArgs e) + { + if (this.IsDisposed) + return; + DestroyAutoCloseTimer(); + this.HideAlert(eAlertClosureSource.Timeout); + this.Close(); + } + + private void DestroyAutoCloseTimer() + { + if (_AutoCloseTimer != null) + { + _AutoCloseTimer.Enabled = false; + _AutoCloseTimer.Tick -= new EventHandler(this.AutoCloseTimeOutEllapsed); + _AutoCloseTimer.Dispose(); + _AutoCloseTimer = null; + } + } + + protected override void OnVisibleChanged(EventArgs e) + { + base.OnVisibleChanged(e); + if (this.Visible) + { + if (_AutoCloseTimeOut > 0) + StartAutoCloseTimer(); + + if (_AutoCloseTimer != null && !_AutoCloseTimer.Enabled) + { + _AutoCloseTimer.Enabled = true; + _AutoCloseTimer.Start(); + } + } + else + { + if (_AutoCloseTimer != null && _AutoCloseTimer.Enabled) + { + _AutoCloseTimer.Stop(); + _AutoCloseTimer.Enabled = false; + } + } + } + + private Control _ReferenceControl = null; + /// + /// Specifies the reference control which is used to find which screen the alert is displayed on. If not specified alert is displayed on primary screen. + /// + [DefaultValue(null), Browsable(false)] + public Control ReferenceControl + { + get { return _ReferenceControl; } + set { _ReferenceControl = value; } + } + + private static Semaphore _DisplayPositionsSemaphore = new Semaphore(1, 1); + private static List _DisplayPositions = new List(); + private Rectangle GetAlertBounds() + { + Rectangle r = this.Bounds; + + ScreenInformation si = null; + if (_ReferenceControl == null) + si = BarFunctions.PrimaryScreen; + else + si = BarFunctions.ScreenFromControl(_ReferenceControl); + + if (_AlertPosition == eAlertPosition.BottomRight) + { + r = new Rectangle(si.WorkingArea.Right - this.Width, si.WorkingArea.Bottom - this.Height - Dpi.Height12, this.Width, this.Height); + } + else if (_AlertPosition == eAlertPosition.BottomLeft) + { + r = new Rectangle(si.WorkingArea.Left, si.WorkingArea.Bottom - this.Height - Dpi.Height12, this.Width, this.Height); + } + else if (_AlertPosition == eAlertPosition.TopRight) + { + r = new Rectangle(si.WorkingArea.Right - this.Width, si.WorkingArea.Top + Dpi.Height12, this.Width, this.Height); + } + else if (_AlertPosition == eAlertPosition.TopLeft) + { + r = new Rectangle(si.WorkingArea.Left, si.WorkingArea.Top + Dpi.Height12, this.Width, this.Height); + } + + // Now adjust display position + if (_DisplayPositions.Count > 0) + { + if(_AlertPosition == eAlertPosition.TopLeft || _AlertPosition == eAlertPosition.TopRight) + _DisplayPositions.Sort(_RectangleComparer); + else + _DisplayPositions.Sort(_RectangleReverseComparer); + Rectangle originalBounds = r; + for (int i = 0; i < _DisplayPositions.Count; i++) + { + if (_DisplayPositions[i].IntersectsWith(r)) + { + if (_AlertPosition == eAlertPosition.BottomLeft || _AlertPosition == eAlertPosition.BottomRight) + r.Y -= _DisplayPositions[i].Height + _AlertsSpacing; + else + r.Y += _DisplayPositions[i].Height + _AlertsSpacing; + } + else + break; + if (!si.WorkingArea.Contains(r)) + { + r = originalBounds; + break; + } + if (i == _DisplayPositions.Count - 1) + break; + } + } + + _DisplayPositionsSemaphore.WaitOne(); + try + { + _DisplayPositions.Add(r); + } + finally + { + _DisplayPositionsSemaphore.Release(); + } + return r; + } + + private static readonly RectangleComparer _RectangleComparer = new RectangleComparer(); + private static readonly RectangleReverseComparer _RectangleReverseComparer = new RectangleReverseComparer(); + private class RectangleComparer : IComparer + { + public int Compare(Rectangle x, Rectangle y) + { + return x.Y - y.Y; + } + } + private class RectangleReverseComparer : IComparer + { + public int Compare(Rectangle x, Rectangle y) + { + return y.Y - x.Y; + } + } + + protected override void OnClosed(EventArgs e) + { + _DisplayPositionsSemaphore.WaitOne(); + try + { + for (int i = _DisplayPositions.Count - 1; i >= 0; i--) + { + if (_DisplayPositions[i] == this.Bounds) + { + _DisplayPositions.RemoveAt(i); + break; + } + } + } + finally + { + _DisplayPositionsSemaphore.Release(); + } + base.OnClosed(e); + } + + /// + /// Display balloon. + /// + /// Indicates whether alert receives input focus upon showing. + public void Show(bool focusAlert) + { + PerformAutoSize(); + + this.Bounds = GetAlertBounds(); + Rectangle rEnd = this.Bounds; + + DesktopAlert.OnBeforeAlertDisplayed(this, EventArgs.Empty); + if(this.IsDisposed) + return; + + if (ShouldAnimate()) + { + try + { + _AnimationInProgress = true; + eAlertAnimation alertAnimation = GetAlertAnimation(); + if (alertAnimation == eAlertAnimation.RightToLeft) + NativeFunctions.AnimateWindow(this.Handle, _AlertAnimationDuration, (NativeFunctions.AW_SLIDE | NativeFunctions.AW_HOR_NEGATIVE)); + else if (alertAnimation == eAlertAnimation.LeftToRight) + NativeFunctions.AnimateWindow(this.Handle, _AlertAnimationDuration, (NativeFunctions.AW_SLIDE | NativeFunctions.AW_HOR_POSITIVE)); + else if (alertAnimation == eAlertAnimation.BottomToTop) + NativeFunctions.AnimateWindow(this.Handle, _AlertAnimationDuration, (NativeFunctions.AW_SLIDE | NativeFunctions.AW_VER_NEGATIVE)); + else if (alertAnimation == eAlertAnimation.TopToBottom) + NativeFunctions.AnimateWindow(this.Handle, _AlertAnimationDuration, (NativeFunctions.AW_SLIDE | NativeFunctions.AW_VER_POSITIVE)); + } + finally + { + _AnimationInProgress = false; + } + } + base.Show(); + + if (_TopMost) + NativeFunctions.SetWindowPos(this.Handle, + new IntPtr(NativeFunctions.HWND_TOPMOST), 0, 0, 0, 0, + NativeFunctions.SWP_NOACTIVATE | NativeFunctions.SWP_NOMOVE | NativeFunctions.SWP_NOSIZE); + //this.Visible = true; + + if (_PlaySound) + System.Media.SystemSounds.Beep.Play(); + } + + protected override bool ShowWithoutActivation + { + get + { + return true; + } + } + + private eAlertAnimation GetAlertAnimation() + { + if (_AlertPosition == eAlertPosition.TopLeft || _AlertPosition == eAlertPosition.BottomLeft) + return eAlertAnimation.LeftToRight; + else + return eAlertAnimation.RightToLeft; + } + + /// + /// Displays balloon. + /// + public new void Show() + { + this.Show(false); + } + + private bool _AnimationInProgress = false; + /// + /// Called when alert needs to be hidden. + /// + protected virtual void HideAlert(eAlertClosureSource source) + { + DestroyAutoCloseTimer(); + if (ShouldAnimate()) + { + Rectangle rStart = this.Bounds; + //Rectangle rEnd = GetAnimationRectangle(); + try + { + _AnimationInProgress = true; + eAlertAnimation alertAnimation = GetAlertAnimation(); + if (alertAnimation == eAlertAnimation.RightToLeft) + NativeFunctions.AnimateWindow(this.Handle, _AlertAnimationDuration, (NativeFunctions.AW_SLIDE | NativeFunctions.AW_HOR_POSITIVE | NativeFunctions.AW_HIDE)); + else if (alertAnimation == eAlertAnimation.LeftToRight) + NativeFunctions.AnimateWindow(this.Handle, _AlertAnimationDuration, (NativeFunctions.AW_SLIDE | NativeFunctions.AW_HOR_NEGATIVE | NativeFunctions.AW_HIDE)); + else if (alertAnimation == eAlertAnimation.BottomToTop) + NativeFunctions.AnimateWindow(this.Handle, _AlertAnimationDuration, (NativeFunctions.AW_SLIDE | NativeFunctions.AW_VER_POSITIVE | NativeFunctions.AW_HIDE)); + else if (alertAnimation == eAlertAnimation.TopToBottom) + NativeFunctions.AnimateWindow(this.Handle, _AlertAnimationDuration, (NativeFunctions.AW_SLIDE | NativeFunctions.AW_VER_NEGATIVE | NativeFunctions.AW_HIDE)); + } + finally + { + _AnimationInProgress = false; + } + } + else + base.Hide(); + this.Close(); + DesktopAlert.OnAlertClosed(this, new AlertClosedEventArgs(source)); + _ClickAction = null; + this.Dispose(); + } + + /// + /// Hides balloon. + /// + public new void Hide() + { + HideAlert(eAlertClosureSource.Timeout); + } + + private bool ShouldAnimate() + { + if (_AlertAnimationDuration > 0 && !this.DesignMode && !this.IsDisposed) + return true; + return false; + } + + private int _AlertsSpacing = 8; + /// + /// Indicates spacing between alerts on the screen + /// + [DefaultValue(8), Category("Behavior"), Description("Indicates spacing between alerts on the screen")] + public int AlertsSpacing + { + get { return _AlertsSpacing; } + set + { + if (_AlertsSpacing != value) + { + int oldValue = _AlertsSpacing; + _AlertsSpacing = value; + OnAlertsSpacingChanged(value, oldValue); + } + } + } + + protected virtual void OnAlertsSpacingChanged(int newValue, int oldValue) + { + throw new NotImplementedException(); + } + + //private Rectangle GetAnimationRectangle() + //{ + // Rectangle r = new Rectangle(this.Location, this.Size); + // if (_AlertAnimation == eAlertAnimation.BottomToTop) + // { + // r.Y = r.Bottom - 1; + // r.Height = 1; + // } + // else if (_AlertAnimation == eAlertAnimation.TopToBottom) + // { + // r.Height = 1; + // } + // else if (_AlertAnimation == eAlertAnimation.LeftToRight) + // { + // r.Width = 2; + // } + // else if (_AlertAnimation == eAlertAnimation.RightToLeft) + // { + // r.X = r.Right - 1; + // r.Width = 1; + // } + // return r; + //} + + private eAlertPosition _AlertPosition = eAlertPosition.BottomRight; + /// + /// Indicates the request screen position for the alert + /// + [DefaultValue(eAlertPosition.BottomRight), Category("Behavior"), Description("Indicates the request screen position for the alert")] + public eAlertPosition AlertPosition + { + get { return _AlertPosition; } + set + { + if (_AlertPosition != value) + { + eAlertPosition oldValue = _AlertPosition; + _AlertPosition = value; + OnAlertPositionChanged(value, oldValue); + } + } + } + protected virtual void OnAlertPositionChanged(eAlertPosition newValue, eAlertPosition oldValue) + { + //throw new NotImplementedException(); + } + + private bool _TopMost = true; + [DefaultValue(true)] + public new bool TopMost + { + get { return _TopMost; } + set + { + if (_TopMost != value) + { + bool oldValue = _TopMost; + _TopMost = value; + OnTopMostChanged(value, oldValue); + } + } + } + + protected virtual void OnTopMostChanged(bool newValue, bool oldValue) + { + if (IsHandleCreated && Visible) + NativeFunctions.SetWindowPos(this.Handle, + new IntPtr(newValue ? NativeFunctions.HWND_TOPMOST : NativeFunctions.HWND_NOTOPMOST), 0, 0, 0, 0, + NativeFunctions.SWP_NOACTIVATE | NativeFunctions.SWP_NOMOVE | NativeFunctions.SWP_NOSIZE); + } + + private int _ImageTextPadding = 11; + /// + /// Indicates spacing in pixels between image and text + /// + [DefaultValue(11), Category("Appearance"), Description("Indicates spacing in pixels between image and text")] + public int ImageTextPadding + { + get { return _ImageTextPadding; } + set + { + if (_ImageTextPadding != value) + { + int oldValue = _ImageTextPadding; + _ImageTextPadding = value; + OnImageTextPaddingChanged(value, oldValue); + } + } + } + + protected virtual void OnImageTextPaddingChanged(int newValue, int oldValue) + { + + } + + private bool UseTextRenderer + { + get { return true; /*_BackColors == null || _BackColors.Length < 2;*/ } + } + + private bool _PlaySound = true; + /// + /// Indicates whether alert plays exclamation sound when shown. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether alert plays exclamation sound when shown.")] + public bool PlaySound + { + get { return _PlaySound; } + set + { + if (_PlaySound != value) + { + bool oldValue = _PlaySound; + _PlaySound = value; + OnPlaySoundChanged(value, oldValue); + } + } + } + + protected virtual void OnPlaySoundChanged(bool newValue, bool oldValue) + { + //throw new NotImplementedException(); + } + + private bool _CloseButtonVisible = true; + /// + /// Indicates whether close button on alert is visible + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether close button on alert is visible")] + public bool CloseButtonVisible + { + get { return _CloseButtonVisible; } + set + { + if (_CloseButtonVisible != value) + { + bool oldValue = _CloseButtonVisible; + _CloseButtonVisible = value; + OnCloseButtonVisibleChanged(value, oldValue); + } + } + } + + protected virtual void OnCloseButtonVisibleChanged(bool newValue, bool oldValue) + { + //throw new NotImplementedException(); + } + #endregion + } + + /// + /// Defines the alert positions. + /// + public enum eAlertPosition + { + /// + /// Top-left screen position. + /// + TopLeft, + /// + /// Top-right screen position. + /// + TopRight, + /// + /// Bottom-right screen position. + /// + BottomRight, + /// + /// Bottom left screen position. + /// + BottomLeft + } + /// + /// Defines closure sources for the alert. + /// + public enum eAlertClosureSource + { + /// + /// Alert is closed becouse of timeout + /// + Timeout, + /// + /// Alert is closed becouse user clicked close button. + /// + CloseButton, + /// + /// Alert is closed becouse user clicked on the alert. + /// + AlertClicked + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Flyout.ico b/PROMS/DotNetBar Source Code/Controls/Flyout.ico new file mode 100644 index 00000000..f6992446 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/Flyout.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/Flyout/Flyout.cs b/PROMS/DotNetBar Source Code/Controls/Flyout/Flyout.cs new file mode 100644 index 00000000..e5c0fea0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Flyout/Flyout.cs @@ -0,0 +1,1342 @@ +using DevComponents.DotNetBar; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Component to display flyout popup. + /// + [ToolboxBitmap(typeof(Flyout), "Controls.Flyout.ico")] + [ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.FlyoutDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + [DefaultEvent("PrepareContent")] + public partial class Flyout : Component, IMessageHandlerClient + { + #region Constructor + public Flyout() + { + InitializeComponent(); + } + + public Flyout(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + #endregion + + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + Close(); + if (_MessageHandlerInstalled) + { + MessageHandler.UnregisterMessageClient(this); + _MessageHandlerInstalled = false; + } + if (disposing && (components != null)) + { + components.Dispose(); + } + + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + + #region Implementation + private bool _DropShadow; + private bool _TopMost; + private Control _Content = null; + /// + /// Indicates a control, usually panel with other controls inside of it, that is displayed on the flyout popup. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates a control, usually panel with other controls inside of it, that is displayed on the flyout popup.")] + public Control Content + { + get { return _Content; } + set + { + if (value != _Content) + { + Control oldValue = _Content; + _Content = value; + OnContentChanged(oldValue, value); + } + } + } + /// + /// Called when Content property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnContentChanged(Control oldValue, Control newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Content")); + + } + + private ePointerSide _PointerSide = ePointerSide.Bottom; + /// + /// Indicates the side of the flyout triangle pointer is displayed on. + /// + [DefaultValue(ePointerSide.Bottom), Category("Appearance"), Description("Indicates the side of the flyout triangle pointer is displayed on.")] + public ePointerSide PointerSide + { + get { return _PointerSide; } + set + { + if (value != _PointerSide) + { + ePointerSide oldValue = _PointerSide; + _PointerSide = value; + OnPointerSideChanged(oldValue, value); + } + } + } + /// + /// Called when PointerSide property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPointerSideChanged(ePointerSide oldValue, ePointerSide newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("PointerSide")); + } + + private Control _TargetControl = null; + /// + /// Indicates the target control for the flyout display and positioning. + /// + [DefaultValue(null), Category("Behavior"), Description("Indicates the target control for the flyout display and positioning.")] + public Control TargetControl + { + get { return _TargetControl; } + set + { + if (value != _TargetControl) + { + Control oldValue = _TargetControl; + _TargetControl = value; + OnTargetControlChanged(oldValue, value); + } + } + } + /// + /// Called when TargetControl property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTargetControlChanged(Control oldValue, Control newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TargetControl")); + if (!this.DesignMode) + { + DetachFromControl(oldValue, _DisplayMode, _DeepIntegration); + AttachToControl(newValue, _DisplayMode, _DeepIntegration); + } + } + + private void AttachToControl(Control c, eFlyoutDisplayMode displayMode, bool deepIntegration) + { + if (c == null) return; + if (displayMode == eFlyoutDisplayMode.MouseClick) + { + if (deepIntegration && c is SuperTabControl) + { + SuperTabControl tab = (SuperTabControl)c; + tab.TabStrip.ItemClick += TabStripMouseEvent; + } + else if (deepIntegration && c is AdvTree.AdvTree) + { + AdvTree.AdvTree tree = (AdvTree.AdvTree)c; + tree.NodeClick += TreeMouseEvent; + } + else if (deepIntegration && c is TokenEditor) + { + TokenEditor token = (TokenEditor)c; + token.TokenMouseClick += TokenMouseEvent; + } + else if (deepIntegration && c is TabStrip) + { + TabStrip strip = (TabStrip)c; + strip.TabMouseClick += TabItemMouseEvent; + } + else if (deepIntegration && c is TabControl) + { + TabControl strip = (TabControl)c; + strip.TabStrip.TabMouseClick += TabItemMouseEvent; + } + else if (deepIntegration && c is Bar) + { + Bar bar = (Bar)c; + bar.ItemClick += BaseItemMouseEvent; + } + else + c.MouseClick += TargetMouseClick; + } + else if (displayMode == eFlyoutDisplayMode.MouseHover) + { + if (deepIntegration && c is SuperTabControl) + { + SuperTabControl tab = (SuperTabControl)c; + tab.TabStrip.MouseHover += TabStripMouseEvent; + tab.TabStrip.MouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is AdvTree.AdvTree) + { + AdvTree.AdvTree tree = (AdvTree.AdvTree)c; + tree.NodeMouseHover += TreeMouseEvent; + tree.NodeMouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is TokenEditor) + { + TokenEditor token = (TokenEditor)c; + token.TokenMouseHover += TokenMouseEvent; + token.TokenMouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is TabStrip) + { + TabStrip tab = (TabStrip)c; + tab.TabMouseHover += TabItemMouseEvent; + tab.TabMouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is TabControl) + { + TabControl tab = (TabControl)c; + tab.TabStrip.TabMouseHover += TabItemMouseEvent; + tab.TabStrip.TabMouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is Bar) + { + Bar bar = (Bar)c; + bar.MouseHover += BaseItemMouseEvent; + bar.MouseLeave += TargetMouseLeave; + } + else + c.MouseHover += TargetMouseHover; + } + else if (displayMode == eFlyoutDisplayMode.MouseOver) + { + if (deepIntegration && c is SuperTabControl) + { + SuperTabControl tab = (SuperTabControl)c; + tab.TabStrip.MouseEnter += TabStripMouseEvent; + tab.TabStrip.MouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is AdvTree.AdvTree) + { + AdvTree.AdvTree tree = (AdvTree.AdvTree)c; + tree.NodeMouseEnter += TreeMouseEvent; + tree.NodeMouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is TokenEditor) + { + TokenEditor token = (TokenEditor)c; + token.TokenMouseEnter += TokenMouseEvent; + token.TokenMouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is TabStrip) + { + TabStrip tab = (TabStrip)c; + tab.TabMouseEnter += TabItemMouseEvent; + tab.TabMouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is TabControl) + { + TabControl tab = (TabControl)c; + tab.TabStrip.TabMouseEnter += TabItemMouseEvent; + tab.TabStrip.TabMouseLeave += TargetMouseLeave; + } + else if (deepIntegration && c is Bar) + { + Bar bar = (Bar)c; + bar.MouseMove += BaseItemMouseEvent; + bar.MouseLeave += TargetMouseLeave; + } + else + c.MouseEnter += TargetMouseEnter; + } + c.Leave += TargetLeaveFocus; + c.VisibleChanged += TargetVisibleChanged; + } + + private void DetachFromControl(Control c, eFlyoutDisplayMode displayMode, bool deepIntegration) + { + if (c == null) return; + if (displayMode == eFlyoutDisplayMode.MouseClick) + { + if (deepIntegration && c is SuperTabControl) + { + SuperTabControl tab = (SuperTabControl)c; + tab.TabStrip.ItemClick -= TabStripMouseEvent; + } + else if (deepIntegration && c is AdvTree.AdvTree) + { + AdvTree.AdvTree tree = (AdvTree.AdvTree)c; + tree.NodeClick -= TreeMouseEvent; + } + else if (deepIntegration && c is TokenEditor) + { + TokenEditor token = (TokenEditor)c; + token.TokenMouseClick -= TokenMouseEvent; + } + else if (deepIntegration && c is TabStrip) + { + TabStrip strip = (TabStrip)c; + strip.TabMouseClick -= TabItemMouseEvent; + } + else if (deepIntegration && c is TabControl) + { + TabControl strip = (TabControl)c; + strip.TabStrip.TabMouseClick -= TabItemMouseEvent; + } + else if (deepIntegration && c is Bar) + { + Bar bar = (Bar)c; + bar.ItemClick -= BaseItemMouseEvent; + } + else + c.MouseClick -= TargetMouseClick; + } + else if (displayMode == eFlyoutDisplayMode.MouseHover) + { + if (deepIntegration && c is SuperTabControl) + { + SuperTabControl tab = (SuperTabControl)c; + tab.TabStrip.MouseHover -= TabStripMouseEvent; + tab.TabStrip.MouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is AdvTree.AdvTree) + { + AdvTree.AdvTree tree = (AdvTree.AdvTree)c; + tree.NodeMouseHover -= TreeMouseEvent; + tree.NodeMouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is TokenEditor) + { + TokenEditor token = (TokenEditor)c; + token.TokenMouseHover -= TokenMouseEvent; + token.TokenMouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is TabStrip) + { + TabStrip tab = (TabStrip)c; + tab.TabMouseHover -= TabItemMouseEvent; + tab.TabMouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is TabControl) + { + TabControl tab = (TabControl)c; + tab.TabStrip.TabMouseHover -= TabItemMouseEvent; + tab.TabStrip.TabMouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is Bar) + { + Bar bar = (Bar)c; + bar.MouseHover -= BaseItemMouseEvent; + bar.MouseLeave -= TargetMouseLeave; + } + else + c.MouseHover -= TargetMouseHover; + } + else if (displayMode == eFlyoutDisplayMode.MouseOver) + { + if (deepIntegration && c is SuperTabControl) + { + SuperTabControl tab = (SuperTabControl)c; + tab.TabStrip.MouseEnter -= TabStripMouseEvent; + tab.TabStrip.MouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is AdvTree.AdvTree) + { + AdvTree.AdvTree tree = (AdvTree.AdvTree)c; + tree.NodeMouseEnter -= TreeMouseEvent; + tree.NodeMouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is TokenEditor) + { + TokenEditor token = (TokenEditor)c; + token.TokenMouseEnter -= TokenMouseEvent; + token.TokenMouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is TabStrip) + { + TabStrip tab = (TabStrip)c; + tab.TabMouseEnter -= TabItemMouseEvent; + tab.TabMouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is TabControl) + { + TabControl tab = (TabControl)c; + tab.TabStrip.TabMouseEnter -= TabItemMouseEvent; + tab.TabStrip.TabMouseLeave -= TargetMouseLeave; + } + else if (deepIntegration && c is Bar) + { + Bar bar = (Bar)c; + bar.MouseEnter -= BaseItemMouseEvent; + bar.MouseLeave -= TargetMouseLeave; + } + else + c.MouseEnter -= TargetMouseEnter; + } + c.Leave -= TargetLeaveFocus; + c.VisibleChanged -= TargetVisibleChanged; + } + private bool _CloseDelayed = false; + private void TargetMouseLeave(object sender, EventArgs e) + { + if (_IsFlyoutFormShown) + { + _CloseDelayed = true; + BarUtilities.InvokeDelayed(new MethodInvoker(delegate { CloseFlyoutDelayed(); }), 1000); + //Close(); + } + } + private void CloseFlyoutDelayed() + { + if (!_CloseDelayed) return; + _CloseDelayed = false; + if (_IsFlyoutFormShown && _Flyout!=null && !_Flyout.Bounds.Contains(Control.MousePosition) && + _TargetControl!=null && !(new Rectangle(_TargetControl.PointToScreen(_TargetControl.Location), _TargetControl.Size).Contains(Control.MousePosition))) + { + Close(); + } + } + private void TokenMouseEvent(object sender, EventArgs e) + { + if (_IsFlyoutFormShown) + Close(); + Show(sender); + } + private void TreeMouseEvent(object sender, AdvTree.TreeNodeMouseEventArgs e) + { + if (_IsFlyoutFormShown) + Close(); + Show(e.Node); + } + private void TabItemMouseEvent(object sender, EventArgs e) + { + if (sender is TabItem) + { + if (_IsFlyoutFormShown) + Close(); + if (!_IsFlyoutFormShown) + { + Show(sender); + } + } + else + Close(); + } + private void BaseItemMouseEvent(object sender, EventArgs e) + { + if (sender is BaseItem) + { + if (_IsFlyoutFormShown) + Close(); + if (!_IsFlyoutFormShown) + { + Show(sender); + } + } + else if (sender is Bar) + { + Bar bar = (Bar)sender; + Point p = bar.PointToClient(Control.MousePosition); + BaseItem item = bar.ItemsContainer.ItemAtLocation(p.X, p.Y); + if (item != null) + { + if (_TargetItem != null && _TargetItem.IsAlive && _TargetItem.Target == item) + return; + + if (_IsFlyoutFormShown) + Close(); + + if (!_IsFlyoutFormShown) + { + Show(item); + } + } + else + Close(); + } + else + Close(); + } + private void TabStripMouseEvent(object sender, EventArgs e) + { + if (sender is SuperTabItem) + { + if (_IsFlyoutFormShown) + Close(); + if (!_IsFlyoutFormShown) + { + Show(sender); + } + } + else + Close(); + } + + private bool _DeepIntegration = true; + /// + /// Indicates whether Flyout integrates on item level with DotNetBar controls it recognizes like SuperTabControl, AdvTree etc. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether Flyout integrates on item level with DotNetBar controls it recognizes like SuperTabControl, AdvTree etc.")] + public bool DeepIntegration + { + get { return _DeepIntegration; } + set + { + if (value != _DeepIntegration) + { + bool oldValue = _DeepIntegration; + _DeepIntegration = value; + OnDeepControlIntegrationChanged(oldValue, value); + } + } + } + /// + /// Called when DeepControlIntegration property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDeepControlIntegrationChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("DeepControlIntegration")); + DetachFromControl(_TargetControl, _DisplayMode, oldValue); + AttachToControl(_TargetControl, _DisplayMode, newValue); + } + + private void TargetVisibleChanged(object sender, EventArgs e) + { + if ((_CloseMode & eFlyoutCloseMode.TargetControlHidden) == eFlyoutCloseMode.TargetControlHidden && _TargetControl != null && !_TargetControl.Visible) + Close(); + } + void TargetLeaveFocus(object sender, EventArgs e) + { + if ((_CloseMode & eFlyoutCloseMode.TargetControlLostFocus) == eFlyoutCloseMode.TargetControlLostFocus) + Close(); + } + + void TargetMouseEnter(object sender, EventArgs e) + { + if (!_IsFlyoutFormShown) + Show(); + } + + void TargetMouseHover(object sender, EventArgs e) + { + if (!_IsFlyoutFormShown) + Show(); + } + private void TargetMouseClick(object sender, MouseEventArgs e) + { + if (!_IsFlyoutFormShown) + Show(); + } + private eFlyoutDisplayMode _DisplayMode = eFlyoutDisplayMode.MouseOver; + /// + /// Specifies when the flyout is displayed. + /// + [DefaultValue(eFlyoutDisplayMode.MouseOver), Category("Behavior"), Description("Specifies when the flyout is displayed.")] + public eFlyoutDisplayMode DisplayMode + { + get { return _DisplayMode; } + set + { + if (value != _DisplayMode) + { + eFlyoutDisplayMode oldValue = _DisplayMode; + _DisplayMode = value; + OnDisplayModeChanged(oldValue, value); + } + } + } + /// + /// Called when DisplayMode property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDisplayModeChanged(eFlyoutDisplayMode oldValue, eFlyoutDisplayMode newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("DisplayMode")); + DetachFromControl(_TargetControl, oldValue, _DeepIntegration); + AttachToControl(_TargetControl, newValue, _DeepIntegration); + } + + private eFlyoutCloseMode _CloseMode = eFlyoutCloseMode.ClickOutside | eFlyoutCloseMode.ParentFormDeactivate; + /// + /// Indicates when Flyout is automatically closed. + /// + [DefaultValue(eFlyoutCloseMode.ClickOutside | eFlyoutCloseMode.ParentFormDeactivate), Category("Behavior"), Description("Indicates when Flyout is automatically closed.")] + public eFlyoutCloseMode CloseMode + { + get { return _CloseMode; } + set + { + if (value != _CloseMode) + { + eFlyoutCloseMode oldValue = _CloseMode; + _CloseMode = value; + OnCloseModeChanged(oldValue, value); + } + } + } + /// + /// Called when CloseMode property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCloseModeChanged(eFlyoutCloseMode oldValue, eFlyoutCloseMode newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("CloseMode")); + + } + + private Rectangle GetTargetBounds(object targetItem) + { + if (targetItem is BaseItem) + { + BaseItem item = (BaseItem)targetItem; + return new Rectangle(_TargetControl.PointToScreen(item.Bounds.Location), item.Bounds.Size); + } + else if (targetItem is DevComponents.AdvTree.Node) + { + DevComponents.AdvTree.Node node = (DevComponents.AdvTree.Node)targetItem; + return new Rectangle(_TargetControl.PointToScreen(node.Bounds.Location), node.Bounds.Size); + } + else if(targetItem is EditToken) + { + EditToken token = (EditToken)targetItem; + return new Rectangle(_TargetControl.PointToScreen(token.Bounds.Location), token.Bounds.Size); + } + else if (targetItem is TabItem) + { + TabItem tab = (TabItem)targetItem; + return new Rectangle(_TargetControl.PointToScreen(tab.DisplayRectangle.Location), tab.DisplayRectangle.Size); + } + + return new Rectangle(_TargetControl.PointToScreen(Point.Empty), _TargetControl.Size); + } + + /// + /// Occurs before the flyout is shown for specific target and allows you to prepare Content for it. Sender of event will be the targeted control or item. + /// + [Description("Occurs before the flyout is shown for specific target and allows you to prepare Content for it. Sender of event will be the targeted control or item.")] + public event EventHandler PrepareContent; + /// + /// Raises PrepareContent event. + /// + /// Provides event arguments. + protected virtual void OnPrepareContent(object sender, EventArgs e) + { + EventHandler handler = PrepareContent; + if (handler != null) + handler(sender, e); + } + + public virtual void Show(object targetItem) + { + OnPrepareContent(targetItem, EventArgs.Empty); + + Rectangle r = new Rectangle(); + ePointerSide pointerSide = _PointerSide; + int pointerOffset = 10; + + if (_TargetControl != null) + { + Rectangle targetBounds = GetTargetBounds(targetItem ?? _TargetControl); + ScreenInformation si = BarFunctions.ScreenFromControl(_TargetControl); + if (pointerSide == ePointerSide.Top) + { + // Displaying callout below the control + r.Size = GetFlyoutFormSize(); + if (targetBounds.Bottom + r.Height > si.WorkingArea.Bottom) + { + // Move flyout above the control + pointerSide = ePointerSide.Bottom; + r.Location = new Point(targetBounds.X, targetBounds.Y - r.Height); + } + else + r.Location = new Point(targetBounds.X, targetBounds.Bottom); + if (targetBounds.Width > r.Width) + r.X += (targetBounds.Width - r.Width) / 2; + else if (targetBounds.Width < r.Width) + r.X -= (r.Width - targetBounds.Width) / 2; + if (r.X < si.WorkingArea.X) + r.X = si.WorkingArea.X; + else if (r.Right > si.WorkingArea.Right) + r.X = si.WorkingArea.Right - r.Width; + Rectangle intersect = Rectangle.Intersect(r, new Rectangle(targetBounds.X, r.Y, targetBounds.Width, r.Height)); + if (intersect.IsEmpty) + pointerOffset = (Math.Min(targetBounds.Width, r.Width) - FlyoutForm.PointerSize.Width) / 2; + else + pointerOffset = Math.Abs(intersect.X - r.X) + (intersect.Width - FlyoutForm.PointerSize.Width) / 2; + } + else if (pointerSide == ePointerSide.Bottom) + { + // Displaying callout above the control + r.Size = GetFlyoutFormSize(); + if (targetBounds.Y - r.Height < si.WorkingArea.Y) + { + // Move flyout below the control + pointerSide = ePointerSide.Top; + r.Location = new Point(targetBounds.X, targetBounds.Bottom); + } + else + r.Location = new Point(targetBounds.X, targetBounds.Y - r.Height); + if (targetBounds.Width > r.Width) + r.X += (targetBounds.Width - r.Width) / 2; + else if (targetBounds.Width < r.Width) + r.X -= (r.Width - targetBounds.Width) / 2; + if (r.X < si.WorkingArea.X) + r.X = si.WorkingArea.X; + else if (r.Right > si.WorkingArea.Right) + r.X = si.WorkingArea.Right - r.Width; + Rectangle intersect = Rectangle.Intersect(r, new Rectangle(targetBounds.X, r.Y, targetBounds.Width, r.Height)); + if (intersect.IsEmpty) + pointerOffset = (Math.Min(targetBounds.Width, r.Width) - FlyoutForm.PointerSize.Width) / 2; + else + pointerOffset = Math.Abs(intersect.X - r.X) + (intersect.Width - FlyoutForm.PointerSize.Width) / 2; + } + else if (pointerSide == ePointerSide.Left) + { + // Displaying callout to the right of the target control + r.Size = GetFlyoutFormSize(); + if (targetBounds.Right + r.Width > si.WorkingArea.Right) + { + // Move flyout to the left of the control + pointerSide = ePointerSide.Right; + r.Location = new Point(targetBounds.X - r.Width, targetBounds.Y); + } + else + r.Location = new Point(targetBounds.Right, targetBounds.Y); + + if (targetBounds.Height > r.Height) + r.Y += (targetBounds.Height - r.Height) / 2; + pointerOffset = (Math.Min(targetBounds.Height, r.Height) - FlyoutForm.PointerSize.Width) / 2; + } + else if (pointerSide == ePointerSide.Right) + { + // Displaying callout to the Left of the target control + r.Size = GetFlyoutFormSize(); + if (targetBounds.X - r.Width < si.WorkingArea.X) + { + // Move flyout to the right of the control + pointerSide = ePointerSide.Left; + r.Location = new Point(targetBounds.Right, targetBounds.Y); + } + else + r.Location = new Point(targetBounds.X - r.Width, targetBounds.Y); + + if (targetBounds.Height > r.Height) + r.Y += (targetBounds.Height - r.Height) / 2; + pointerOffset = (Math.Min(targetBounds.Height, r.Height) - FlyoutForm.PointerSize.Width) / 2; + } + } + Show(r, pointerSide, pointerOffset, targetItem); + } + + /// + /// Shows flyout with the Content. + /// + public virtual void Show() + { + Show(_TargetControl); + } + + /// + /// Returns the flyout size based on Content size. + /// + /// Proposed flyout size. + public virtual Size GetFlyoutFormSize() + { + if (_Content != null) + { + Size size = _Content.Size; + if (_PointerSide == ePointerSide.Bottom || _PointerSide == ePointerSide.Top) + { + size.Height += FlyoutForm.PointerSize.Height + 4; + size.Width += 2; + } + else + { + size.Width += FlyoutForm.PointerSize.Height + 4; + size.Height += 2; + } + return size; + } + return new Size(100, 100); + } + /// + /// Shows flyout at specified location and with specified size. Size can be empty (0,0) and flyout will be automatically sized based on the content. + /// + /// + public virtual void Show(Rectangle screenFlyoutBounds) + { + Show(screenFlyoutBounds, _PointerSide, 10, _TargetControl); + } + [Description("Occurs before the flyout form is shown and allows you to cancel the showing.")] + public event FlyoutShowingEventHandler FlyoutShowing; + /// + /// Raises FlyoutShowing event. + /// + /// Provides event arguments. + protected virtual void OnFlyoutShowing(FlyoutShowingEventArgs e) + { + FlyoutShowingEventHandler handler = FlyoutShowing; + if (handler != null) + handler(this, e); + } + /// + /// Occurs after flyout has been shown. + /// + [Description("Occurs after flyout has been shown.")] + public event EventHandler FlyoutShown; + /// + /// Raises FlyoutShown event. + /// + /// Provides event arguments. + protected virtual void OnFlyoutShown(EventArgs e) + { + EventHandler handler = FlyoutShown; + if (handler != null) + handler(this, e); + } + + /// + /// Provides opportunity to cancel showing of the flyout before any objects are created and allocated. This is preferred event to cancel flyout showing. + /// + [Description("Provides opportunity to cancel showing of the flyout before any objects are created and allocated. This is preferred event to cancel flyout showing.")] + public event CancelEventHandler QueryShowFlyout; + /// + /// Raises QueryShowFlyout event. + /// + /// Provides event arguments. + protected virtual void OnQueryShowFlyout(object sender, CancelEventArgs e) + { + CancelEventHandler handler = QueryShowFlyout; + if (handler != null) + handler(sender, e); + } + + private bool _IsFlyoutFormShown = false; + private Control _OldContentParent = null; + private WeakReference _TargetItem = null; + private FlyoutForm _Flyout = null; + + /// + /// Gets reference to active FlyoutForm or return null/nothing if flyout is not currently shown. + /// + [Browsable(false)] + public FlyoutForm FlyoutForm + { + get { return _Flyout; } + } + + /// + /// Shows flyout at specified location and with specified size. Size can be empty (0,0) and flyout will be automatically sized based on the content. + /// + /// Screen bounds to display flyout at. + /// Side of the flyout which will have pointer triangle + /// Pointer position either x or y depending on which side pointer is displayed on. + /// Target item for the flyout. + public virtual void Show(Rectangle screenFlyoutBounds, ePointerSide pointerSide, int pointerOffset, object targetItem) + { + _CloseDelayed = false; + if (_IsFlyoutFormShown) + { + if (_Flyout != null) _Flyout.Activate(); + return; + } + + CancelEventArgs cancelShow = new CancelEventArgs(); + OnQueryShowFlyout(targetItem??_TargetControl,cancelShow); + if (cancelShow.Cancel) return; + + FlyoutForm form = new FlyoutForm(); + if (!_BorderColor.IsEmpty) + form.BorderColor = _BorderColor; + if (!_BackColor.IsEmpty) + form.BackColor = _BackColor; + form.PointerSide = pointerSide; + form.ActivateOnShow = _ActivateOnShow; + form.TopMost = _TopMost; + form.DropShadow = _DropShadow; + form.PointerOffset = pointerOffset; + if (_Content != null) + { + if (screenFlyoutBounds.Size.IsEmpty) + { + screenFlyoutBounds.Size = GetFlyoutFormSize(); + } + + if (_Content.Parent != null) + { + _OldContentParent = _Content.Parent; + _OldContentParent.Controls.Remove(_Content); + } + + form.Controls.Add(_Content); + _Content.Location = new Point( + (pointerSide == ePointerSide.Left) ? FlyoutForm.PointerSize.Height + 1 : 1, + (pointerSide == ePointerSide.Top) ? FlyoutForm.PointerSize.Height + 1 : 1); + _Content.Visible = true; + } + + form.Size = Size.Empty; + form.Location = screenFlyoutBounds.Location; + form.FormClosed += FlyoutFormClosed; + form.FormClosing += FlyoutFormClosing; + FlyoutShowingEventArgs eargs = new FlyoutShowingEventArgs(form, targetItem); + OnFlyoutShowing(eargs); + if (eargs.Cancel) + { + FlyoutCloseCleanup(form); + form.Close(); + form.Dispose(); + return; + } + _IsFlyoutFormShown = true; + form.Visible = true; + form.Size = screenFlyoutBounds.Size; + _Flyout = form; + _TargetItem = new WeakReference(targetItem); + OnFlyoutShown(EventArgs.Empty); + + if (!_MessageHandlerInstalled && (_CloseMode & eFlyoutCloseMode.ClickOutside) == eFlyoutCloseMode.ClickOutside) + { + MessageHandler.RegisterMessageClient(this); + _MessageHandlerInstalled = true; + } + + if (_Parent != null && (_CloseMode & eFlyoutCloseMode.ParentFormDeactivate) == eFlyoutCloseMode.ParentFormDeactivate) + { + Form parentForm = null; + if (_Parent is Form) + parentForm = (Form)_Parent; + else + parentForm = _Parent.FindForm(); + if (parentForm != null) + { + parentForm.Deactivate += ParentFormDeactivate; + _ParentForm = parentForm; + } + } + } + + /// + /// Occurs before flyout is closed and allows you to cancel the closing. + /// + [Description("Occurs before flyout is closed and allows you to cancel the closing.")] + public event FormClosingEventHandler FlyoutClosing; + /// + /// Raises FlyoutClosing event. + /// + /// Provides event arguments. + protected virtual void OnFlyoutClosing(FormClosingEventArgs e) + { + FormClosingEventHandler handler = FlyoutClosing; + if (handler != null) + handler(this, e); + } + private void FlyoutFormClosing(object sender, FormClosingEventArgs e) + { + OnFlyoutClosing(e); + } + + /// + /// Occurs after flyout is closed. + /// + [Description("Occurs after flyout is closed.")] + public event FormClosedEventHandler FlyoutClosed; + /// + /// Raises FlyoutClosed event. + /// + /// Provides event arguments. + protected virtual void OnFlyoutClosed(FormClosedEventArgs e) + { + FormClosedEventHandler handler = FlyoutClosed; + if (handler != null) + handler(this, e); + } + + private Form _ParentForm = null; + void ParentFormDeactivate(object sender, EventArgs e) + { + if (_Flyout != null && _Flyout.Bounds.Contains(Control.MousePosition)) + return; + Close(); + } + + /// + /// Closes the flyout form if it was open. + /// + public virtual void Close() + { + FlyoutForm flyout = _Flyout; + if (flyout != null) + { + flyout.Close(); + flyout.Dispose(); + } + } + + private void FlyoutCloseCleanup(FlyoutForm form) + { + _TargetItem = null; + _IsFlyoutFormShown = false; + form.FormClosed -= FlyoutFormClosed; + form.Controls.Remove(_Content); + if (_OldContentParent != null) + { + _Content.Visible = false; + _OldContentParent.Controls.Add(_Content); + _OldContentParent = null; + } + _Flyout = null; + if (_ParentForm != null) + { + _ParentForm.Deactivate -= ParentFormDeactivate; + _ParentForm = null; + } + } + private void FlyoutFormClosed(object sender, FormClosedEventArgs e) + { + FlyoutForm form = (FlyoutForm)sender; + OnFlyoutClosed(e); + FlyoutCloseCleanup(form); + } + + private bool _ActivateOnShow = false; + /// + /// Indicates whether flyout is active/focused when its shown, default value is false. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether flyout is active/focused when its shown, default value is false.")] + public bool ActivateOnShow + { + get { return _ActivateOnShow; } + set + { + if (value != _ActivateOnShow) + { + bool oldValue = _ActivateOnShow; + _ActivateOnShow = value; + OnActivateOnShowChanged(oldValue, value); + } + } + } + /// + /// Called when ActivateOnShow property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnActivateOnShowChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("ActivateOnShow")); + + } + + /// + /// Indicates whether flyout is made top-most window when shown + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether flyout is made top-most window when shown.")] + public bool TopMost + { + get { return _TopMost; } + set + { + if (value != _TopMost) + { + bool oldValue = _TopMost; + _TopMost = value; + OnTopMostChanged(oldValue, value); + } + } + } + /// + /// Called when TopMost property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTopMostChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TopMost")); + + } + + private Color _BackColor = Color.Empty; + /// + /// Gets or sets the background flyout color. Default value is Color.Empty which indicates that current color scheme will be used. + /// + [Category("Columns"), Description("Indicates background flyout color. Default value is Color.Empty which indicates that current color scheme will be used.")] + public Color BackColor + { + get { return _BackColor; } + set { _BackColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColor() + { + return !_BackColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackColor() + { + this.BackColor = Color.Empty; + } + + private Color _BorderColor = Color.Empty; + /// + /// Gets or sets the flyout border color. Default value of Color.Empty indicates that color scheme will be used. + /// + [Category("Columns"), Description("Indicates flyout border color. Default value of Color.Empty indicates that color scheme will be used.")] + public Color BorderColor + { + get { return _BorderColor; } + set { _BorderColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBorderColor() + { + return !_BorderColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBorderColor() + { + this.BorderColor = Color.Empty; + } + + /// + /// Indicates whether flyout displays drop shadow. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether flyout displays drop shadow")] + public bool DropShadow + { + get { return _DropShadow; } + set + { + if (value != _DropShadow) + { + bool oldValue = _DropShadow; + _DropShadow = value; + OnDropShadowChanged(oldValue, value); + } + } + } + /// + /// Called when DropShadow property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDropShadowChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("DropShadow")); + + } + + private Control _Parent = null; + /// + /// Gets or sets the parent control for the Flyout. Parent is used to find the parent form so flyout can be closed when form is de-activated. + /// + [Browsable(false), DefaultValue(null)] + public Control Parent + { + get { return _Parent; } + set + { + if (value != _Parent) + { + Control oldValue = _Parent; + _Parent = value; + OnParentChanged(oldValue, value); + } + } + } + /// + /// Called when Parent property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnParentChanged(Control oldValue, Control newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Parent")); + } + #endregion + + #region IMessageHandlerClient + private bool _MessageHandlerInstalled = false; + bool IMessageHandlerClient.OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.OnMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + if ((_CloseMode & eFlyoutCloseMode.ClickOutside) == eFlyoutCloseMode.ClickOutside) + { + FlyoutForm form = _Flyout; + if (form != null && form.Visible) + { + if (!form.Bounds.Contains(Control.MousePosition)) + { + // Ignore clicks on ComboBox popup + string s = NativeFunctions.GetClassName(hWnd); + s = s.ToLower(); + if (s.IndexOf("combolbox") < 0) + Close(); + } + } + } + return false; + } + + bool IMessageHandlerClient.OnMouseMove(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.IsModal + { + get { return false; } + } + #endregion + } + /// + /// Defines delegate for the FlyoutShowing event. + /// + /// + /// + public delegate void FlyoutShowingEventHandler(object sender, FlyoutShowingEventArgs e); + public class FlyoutShowingEventArgs : EventArgs + { + /// + /// Gets the reference to the flyout form. + /// + public FlyoutForm Flyout; + /// + /// Gets the reference to the flyout target usually TargetControl. + /// + public object Target; + /// + /// Allows you to cancel showing of the flyout by setting this value to true. + /// + public bool Cancel; + /// + /// Initializes a new instance of the FlyoutShowingEventArgs class. + /// + /// + /// + public FlyoutShowingEventArgs(FlyoutForm flyout, object target) + { + Flyout = flyout; + Target = target; + } + } + + /// + /// Defines the modes for Flyout display. + /// + public enum eFlyoutDisplayMode + { + /// + /// Flyout is displayed manually using flyout.Show() method. + /// + Manual, + /// + /// Flyout is displayed when mouse is over TargetControl. + /// + MouseOver, + /// + /// Flyout is displayed when mouse is hovering over TargetControl. + /// + MouseHover, + /// + /// Flyout is displayed when left mouse button is clicked on TargetControl. + /// + MouseClick + } + + /// + /// Defines Flyout closing condition. + /// + [Flags()] + public enum eFlyoutCloseMode + { + /// + /// Flyout is closed manually using flyout.Close() method. + /// + Manual, + /// + /// Flyout is closed when user clicks outside of flyout bounds. + /// + ClickOutside, + /// + /// Flyout is closed when TargetControl is hidden. + /// + TargetControlHidden, + /// + /// Flyout is closed when TargetControl loses focus. + /// + TargetControlLostFocus, + /// + /// Flyout is closed when parent forms deactivates. + /// + ParentFormDeactivate + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutColorTable.cs b/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutColorTable.cs new file mode 100644 index 00000000..b51be9a0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutColorTable.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + /// + /// Defines colors for the Flyout control. + /// + public class FlyoutColorTable + { + /// + /// Specifies Flyout background color. + /// + public Color BackColor = Color.White; + /// + /// Specifies Flyout border color. + /// + public Color BorderColor = ColorScheme.GetColor(0x2B579A); + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutForm.Designer.cs b/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutForm.Designer.cs new file mode 100644 index 00000000..75850a60 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutForm.Designer.cs @@ -0,0 +1,53 @@ +namespace DevComponents.DotNetBar.Controls +{ + partial class FlyoutForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // FlyoutForm + // + + this.ControlBox = false; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FlyoutForm"; + this.ShowInTaskbar = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; + this.Load += new System.EventHandler(this.Form1_Load); + this.ResumeLayout(false); + + } + + #endregion + + } +} + diff --git a/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutForm.cs b/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutForm.cs new file mode 100644 index 00000000..d12d80ec --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutForm.cs @@ -0,0 +1,323 @@ +using DevComponents.DotNetBar.Rendering; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + public partial class FlyoutForm : Form + { + public FlyoutForm() + { + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + + InitializeComponent(); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.BackColor = Color.White; + + //_PointerSide = ePointerSide.Top; + _PointerOffset = this.Width-50; + } + + private int _PointerOffset; + private const int CS_DROPSHADOW = 0x00020000; + protected override CreateParams CreateParams + { + get + { + // add the drop shadow flag for automatically drawing + // a drop shadow around the form + CreateParams cp = base.CreateParams; + if(_DropShadow) + cp.ClassStyle |= CS_DROPSHADOW; + return cp; + } + } + protected override bool ShowWithoutActivation + { + get + { + return !_ActivateOnShow; + } + } + + private bool _DropShadow = true; + /// + /// Indicates whether flyout displays a drop shadow. + /// + [DefaultValue(true)] + public bool DropShadow + { + get { return _DropShadow; } + set + { + _DropShadow = value; + } + } + + + private bool _ActivateOnShow = false; + /// + /// Gets or sets whether form is made active/focused when shown. + /// + [DefaultValue(false)] + public bool ActivateOnShow + { + get { return _ActivateOnShow; } + set + { + _ActivateOnShow = value; + } + } + + private GraphicsPath GetFormPath(Rectangle r) + { + return GetFormPath(r, false); + } + + private static readonly Size _PointerSize = new Size(24, 12); + internal static Size PointerSize + { + get + { + return _PointerSize; + } + } + private GraphicsPath GetFormPath(Rectangle r, bool isBorder) + { + Size calloutSize = _PointerSize; // new Size(24, 12); + GraphicsPath path = new GraphicsPath(); + + if (_PointerSide == ePointerSide.Top) + { + int cX = Math.Min(Math.Max(3, _PointerOffset), r.Width - calloutSize.Width + 3); //r.Right - (calloutSize.Width + 10); + path.AddLine(r.X, r.Y + calloutSize.Height, cX + (isBorder ? 1 : 0), r.Y + calloutSize.Height); + path.AddLine(cX, r.Y + calloutSize.Height, cX + calloutSize.Width / 2, r.Y); + path.AddLine(cX + calloutSize.Width / 2, r.Y, cX + calloutSize.Width, r.Y + calloutSize.Height); + path.AddLine(cX + calloutSize.Width, r.Y + calloutSize.Height, r.Right, r.Y + calloutSize.Height); + path.AddLine(r.Right, r.Y + calloutSize.Height, r.Right, r.Bottom); + path.AddLine(r.Right, r.Bottom, r.X, r.Bottom); + path.AddLine(r.X, r.Bottom, r.X, r.Y + calloutSize.Height); + path.CloseAllFigures(); + } + else if (_PointerSide == ePointerSide.Bottom) + { + int cX = Math.Min(Math.Max(3, _PointerOffset), r.Width - calloutSize.Width + 3); //r.Right - (calloutSize.Width + 10); + path.AddLine(r.X, r.Bottom - calloutSize.Height, cX + (isBorder ? 1 : 0), r.Bottom - calloutSize.Height); + path.AddLine(cX, r.Bottom - calloutSize.Height, cX + calloutSize.Width / 2, r.Bottom); + path.AddLine(cX + calloutSize.Width / 2, r.Bottom, cX + calloutSize.Width, r.Bottom - calloutSize.Height); + path.AddLine(cX + calloutSize.Width, r.Bottom - calloutSize.Height, r.Right, r.Bottom - calloutSize.Height); + path.AddLine(r.Right, r.Bottom - calloutSize.Height, r.Right, r.Y); + path.AddLine(r.Right, r.Y, r.X, r.Y); + path.AddLine(r.X, r.Y, r.X, r.Bottom - calloutSize.Height); + path.CloseAllFigures(); + } + else if (_PointerSide == ePointerSide.Left) + { + int cY = Math.Min(Math.Max(3, _PointerOffset), r.Height - calloutSize.Width + 3); //r.Bottom - (calloutSize.Width + 10); + path.AddLine(r.X + calloutSize.Height, r.Bottom, r.X + calloutSize.Height, cY + (isBorder ? 1 : 0)); + path.AddLine(r.X + calloutSize.Height, cY + (isBorder ? 1 : 0), r.X, cY + calloutSize.Width / 2); + path.AddLine(r.X, cY + calloutSize.Width / 2, r.X + calloutSize.Height, cY + calloutSize.Width); + path.AddLine(r.X + calloutSize.Height, cY + calloutSize.Width, r.X + calloutSize.Height, r.Y); + path.AddLine(r.X + calloutSize.Height, r.Y, r.Right, r.Y); + path.AddLine(r.Right, r.Y, r.Right, r.Bottom); + path.AddLine(r.Right, r.Bottom, r.X + calloutSize.Height, r.Bottom); + path.CloseAllFigures(); + } + else if (_PointerSide == ePointerSide.Right) + { + int cY = Math.Min(Math.Max(3, _PointerOffset), r.Width - calloutSize.Height + 3); //r.Bottom - (calloutSize.Width + 10); + path.AddLine(r.Right - calloutSize.Height, r.Y, r.Right - calloutSize.Height, cY + (isBorder ? 1 : 0)); + path.AddLine(r.Right - calloutSize.Height, cY + (isBorder ? 1 : 0), r.Right - (isBorder ? 1 : 0), cY + calloutSize.Width / 2); + path.AddLine(r.Right - (isBorder ? 1 : 0), cY + calloutSize.Width / 2, r.Right - calloutSize.Height, cY + calloutSize.Width); + path.AddLine(r.Right - calloutSize.Height, cY + calloutSize.Width, r.Right - calloutSize.Height, r.Bottom); + path.AddLine(r.Right - calloutSize.Height, r.Bottom, r.X, r.Bottom); + path.AddLine(r.X, r.Bottom, r.X, r.Y); + path.AddLine(r.X, r.Y, r.Right - calloutSize.Height, r.Y); + path.CloseAllFigures(); + } + + return path; + } + private Region GetFormRegion() + { + return new Region(GetFormPath(this.ClientRectangle)); + } + protected override void OnPaint(PaintEventArgs e) + { + Rectangle r = this.ClientRectangle; + r.Inflate(-1, -1); + + FlyoutColorTable table = GetColorTable(); + + Color backColor = this.BackColor; + if (backColor.IsEmpty) + backColor = table.BackColor; + Color borderColor = _BorderColor; + if(borderColor == Color.Empty) + { + borderColor = table.BorderColor; + } + + using (GraphicsPath path = GetFormPath(r, true)) + { + using(SolidBrush borderBrush=new SolidBrush(borderColor)) + e.Graphics.FillRectangle(borderBrush, this.ClientRectangle); + e.Graphics.SetClip(path); + using (SolidBrush brush = new SolidBrush(backColor)) + e.Graphics.FillRectangle(brush, this.ClientRectangle); + e.Graphics.SmoothingMode = SmoothingMode.HighQuality; + //e.Graphics.DrawPath(Pens.Red, path); + } + //base.OnPaint(e); + } + private FlyoutColorTable GetColorTable() + { + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.Flyout; + } + private void Form1_Load(object sender, EventArgs e) + { + //UpdateFormRegion(); + } + + protected override void OnHandleCreated(EventArgs e) + { + UpdateFormRegion(); + base.OnHandleCreated(e); + } + + protected override void OnResize(EventArgs e) + { + UpdateFormRegion(); + base.OnResize(e); + } + + private void UpdateFormRegion() + { + this.Region = GetFormRegion(); + } + + /// + /// Gets or sets the pointer offset from the top-left corner + /// + public int PointerOffset + { + get { return _PointerOffset; } + set + { + if (value !=_PointerOffset) + { + int oldValue = _PointerOffset; + _PointerOffset = value; + OnPointerOffsetChanged(oldValue, value); + } + } + } + /// + /// Called when PointerOffset property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPointerOffsetChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("PointerOffset")); + if (this.IsHandleCreated) + UpdateFormRegion(); + } + + private ePointerSide _PointerSide = ePointerSide.Bottom; + /// + /// Gets or sets the side pointer triangle is displayed on. + /// + public ePointerSide PointerSide + { + get { return _PointerSide; } + set + { + if (value != _PointerSide) + { + ePointerSide oldValue = _PointerSide; + _PointerSide = value; + OnPointerSideChanged(oldValue, value); + } + } + } + /// + /// Called when PointerSide property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPointerSideChanged(ePointerSide oldValue, ePointerSide newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("PointerSide")); + if (this.IsHandleCreated) + UpdateFormRegion(); + } + + private Color _BorderColor = Color.Empty; + /// + /// Gets or sets the flyout border color. Default value of Color.Empty indicates that color scheme will be used. + /// + [Category("Columns"), Description("Indicates flyout border color. Default value of Color.Empty indicates that color scheme will be used.")] + public Color BorderColor + { + get { return _BorderColor; } + set { _BorderColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBorderColor() + { + return !_BorderColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBorderColor() + { + this.BorderColor = Color.Empty; + } + + private bool _IsActive = false; + protected override void OnActivated(EventArgs e) + { + _IsActive = true; + base.OnActivated(e); + } + + protected override void OnDeactivate(EventArgs e) + { + _IsActive = false; + base.OnDeactivate(e); + } + [Browsable(false)] + public bool IsActive + { + get + { + return _IsActive; + } + } + } + /// + /// Defines the side of triangle pointer displayed on flyout popup. + /// + public enum ePointerSide + { + Top, + Bottom, + Left, + Right + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutForm.resx b/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Flyout/FlyoutForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/GroupPanel.cs b/PROMS/DotNetBar Source Code/Controls/GroupPanel.cs new file mode 100644 index 00000000..d4ee18ab --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/GroupPanel.cs @@ -0,0 +1,837 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.ComponentModel.Design; +using System.Reflection; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(GroupPanel), "Controls.GroupPanel.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.GroupPanelDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class GroupPanel : PanelControl, INonClientControl + { + #region Private Variables + private NonClientPaintHandler m_NCPainter = null; + private Image m_TitleImage = null; + private eTitleImagePosition m_TitleImagePosition = eTitleImagePosition.Left; + private bool m_DrawTitleBox = true; + private bool m_IsShadowEnabled = false; + #endregion + + #region Constructor + public GroupPanel() + { + m_NCPainter = new NonClientPaintHandler(this, eScrollBarSkin.Optimized); + m_NCPainter.BeforeBorderPaint += new CustomNCPaintEventHandler(NCBeforeBorderPaint); + m_NCPainter.AfterBorderPaint += new CustomNCPaintEventHandler(NCAfterBorderPaint); + + this.SetStyle(ControlStyles.StandardDoubleClick, true); + } + #endregion + + #region Internal Implementation + private ePanelColorTable _ColorTable = ePanelColorTable.Default; + /// + /// Gets or sets the panel color scheme. + /// + [DefaultValue(ePanelColorTable.Default), Category("Appearance"), Description("Indicates panel color scheme.")] + public ePanelColorTable ColorTable + { + get { return _ColorTable; } + set + { + _ColorTable = value; + SetColorTable(value); + } + } + + protected override void OnResize(EventArgs e) + { + InvalidateNonClient(); + base.OnResize(e); + } + /// + /// Gets or sets the image that appears in title with text. + /// + [Browsable(true), DefaultValue(null), Category("Visual"), Description("Indicates image that appears in title with text.")] + public Image TitleImage + { + get { return m_TitleImage; } + set + { + m_TitleImage = value; + RefreshTextClientRectangle(); + this.Invalidate(); + } + } + + /// + /// Gets or sets the position of the title image. Default value is left. + /// + [Browsable(true), DefaultValue(eTitleImagePosition.Left), Category("Visual"), Description("Indicates position of the title image.")] + public eTitleImagePosition TitleImagePosition + { + get { return m_TitleImagePosition; } + set + { + m_TitleImagePosition = value; + RefreshTextClientRectangle(); + this.Invalidate(); + } + } + + [Browsable(true), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override Color BackColor + { + get { return base.BackColor; } + set { base.BackColor = value; } + } + + /// + /// Gets or sets the scrollbar skining type when control is using Office 2007 style. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public eScrollBarSkin ScrollbarSkin + { + get { return m_NCPainter.SkinScrollbars; } + set { m_NCPainter.SkinScrollbars = value; } + } + + protected override void Dispose(bool disposing) + { + if (m_NCPainter != null) + { + m_NCPainter.Dispose(); + //m_NCPainter = null; + } + if (BarUtilities.DisposeItemImages && !this.DesignMode) + { + BarUtilities.DisposeImage(ref m_TitleImage); + } + base.Dispose(disposing); + } + /// + /// Specifies whether item is drawn using Themes when running on OS that supports themes like Windows XP. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(false), Category("Appearance"), Description("Specifies whether item is drawn using Themes when running on OS that supports themes like Windows XP.")] + public override bool ThemeAware + { + get + { + return base.ThemeAware; + } + set + { + base.ThemeAware = value; + } + } + + /// + /// Gets or sets whether box around the title of the group is drawn. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("")] + public bool DrawTitleBox + { + get { return m_DrawTitleBox; } + set + { + if (m_DrawTitleBox != value) + { + m_DrawTitleBox = value; + this.InvalidateNonClient(); + } + } + } + + /// + /// Invalidates non-client area of the control. + /// + public void InvalidateNonClient() + { + if (!BarFunctions.IsHandleValid(this)) return; + const int RDW_INVALIDATE = 0x0001; + const int RDW_FRAME = 0x0400; + NativeFunctions.RECT r = new NativeFunctions.RECT(0, 0, this.Width, this.Height); + NativeFunctions.RedrawWindow(this.Handle, ref r, IntPtr.Zero, RDW_INVALIDATE | RDW_FRAME); + } + + /// + /// Paints insides of the control. + /// + /// Paint event arguments. + protected override void PaintInnerContent(PaintEventArgs e, ElementStyle style, bool paintText) + { + Graphics g = e.Graphics; + if (this.TextMarkupElement == null) + RefreshTextClientRectangle(); + Rectangle r = this.DisplayRectangle; +#if FRAMEWORK20 + r.X -= this.Padding.Left; + r.Y -= this.Padding.Top; + r.Width += this.Padding.Horizontal; + r.Height += this.Padding.Vertical; +#else + r.X -= this.DockPadding.Left; + r.Y -= this.DockPadding.Top; + r.Width += this.DockPadding.Left + this.DockPadding.Right; + r.Height += this.DockPadding.Top + this.DockPadding.Bottom; +#endif + r.Inflate(2, 2); + ElementStyleDisplayInfo info = new ElementStyleDisplayInfo(style, g, r); + info.RightToLeft = (this.RightToLeft == RightToLeft.Yes); + ElementStyleDisplay.PaintBackground(info, false); + if (style.BackgroundImage != null) ElementStyleDisplay.PaintBackgroundImage(info); + if (!m_IsShadowEnabled) return; + ShadowPaintInfo pi = new ShadowPaintInfo(); + pi.Graphics = g; + pi.Size = 6; + foreach (Control c in this.Controls) + { + if (!c.Visible || c.BackColor == Color.Transparent && !(c is GroupPanel)) continue; + if (c is GroupPanel) + { + GroupPanel p = c as GroupPanel; + pi.Rectangle = new Rectangle(c.Bounds.X, c.Bounds.Y + p.GetInternalClientRectangle().Y / 2, c.Bounds.Width, c.Bounds.Height - p.GetInternalClientRectangle().Y / 2); + } + else + pi.Rectangle = c.Bounds; + ShadowPainter.Paint2(pi); + } + } + + private void NCAfterBorderPaint(object sender, CustomNCPaintEventArgs e) + { + Graphics g = e.Graphics; + + TextRenderingHint th = g.TextRenderingHint; + SmoothingMode sm = g.SmoothingMode; + if (this.AntiAlias) + { + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + g.SmoothingMode = SmoothingMode.AntiAlias; + } + g.ResetClip(); + ElementStyle style = this.Style; + + if (!this.Enabled) + { + style = style.Copy(); + style.TextColor = GetColorScheme().ItemDisabledText; + } + + if (m_DrawTitleBox && !m_TitleArea.IsEmpty) + { + DisplayHelp.FillRoundedRectangle(g, m_TitleArea, 2, style.BackColor, style.BackColor2, -90); + DisplayHelp.DrawRoundedRectangle(g, this.Style.BorderColor, m_TitleArea, 2); + } + + Rectangle rText = new Rectangle(m_NCPainter.ClientRectangle.X + 4, 1, this.ClientRectangle.Width - 8, m_NCPainter.ClientRectangle.Y - 1); + if (m_TitleImage != null) + { + Size textSize = GetAutoSize(rText.Width); + if (m_TitleImagePosition == eTitleImagePosition.Left && this.RightToLeft == RightToLeft.No || m_TitleImagePosition == eTitleImagePosition.Right && this.RightToLeft == RightToLeft.Yes) + { + g.DrawImage(m_TitleImage, rText.X - 1, rText.Y, m_TitleImage.Width, m_TitleImage.Height); + rText.X += m_TitleImage.Width; + rText.Width -= m_TitleImage.Width; + } + else if (m_TitleImagePosition == eTitleImagePosition.Right && this.RightToLeft == RightToLeft.No || m_TitleImagePosition == eTitleImagePosition.Left && this.RightToLeft == RightToLeft.Yes) + { + g.DrawImage(m_TitleImage, rText.Right - m_TitleImage.Width, rText.Y, m_TitleImage.Width, m_TitleImage.Height); + rText.Width -= m_TitleImage.Width; + } + else if (m_TitleImagePosition == eTitleImagePosition.Center) + { + g.DrawImage(m_TitleImage, rText.X + (rText.Width - m_TitleImage.Width) / 2, rText.Y, m_TitleImage.Width, m_TitleImage.Height); + } + rText.Y = rText.Bottom - textSize.Height - 2; + } + + // Paint text + if (this.TextMarkupElement == null) + { + ElementStyleDisplayInfo info = new ElementStyleDisplayInfo(style, g, rText); + info.RightToLeft = (this.RightToLeft == RightToLeft.Yes); + ElementStyleDisplay.PaintText(info, this.Text, this.Font); + } + else + { + TextRenderingHint tr = g.TextRenderingHint; + if (this.AntiAlias) + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, style.TextColor, (this.RightToLeft == RightToLeft.Yes), Rectangle.Empty, true); + Rectangle r = this.TextMarkupElement.Bounds; + if (style.TextAlignment == eStyleTextAlignment.Center) + this.TextMarkupElement.Bounds = new Rectangle(this.TextMarkupElement.Bounds.X + (rText.Width - this.TextMarkupElement.Bounds.Width) / 2, this.TextMarkupElement.Bounds.Y, + this.TextMarkupElement.Bounds.Width, this.TextMarkupElement.Bounds.Height); + else if(style.TextAlignment == eStyleTextAlignment.Far && this.RightToLeft == RightToLeft.No || this.RightToLeft == RightToLeft.Yes && style.TextAlignment== eStyleTextAlignment.Near) + this.TextMarkupElement.Bounds = new Rectangle(rText.Right - this.TextMarkupElement.Bounds.Width, this.TextMarkupElement.Bounds.Y, + this.TextMarkupElement.Bounds.Width, this.TextMarkupElement.Bounds.Height); + this.TextMarkupElement.Render(d); + g.TextRenderingHint = tr; + this.TextMarkupElement.Bounds = r; + } + + g.TextRenderingHint = th; + g.SmoothingMode = sm; + } + private Rectangle m_TitleArea = Rectangle.Empty; + private void NCBeforeBorderPaint(object sender, CustomNCPaintEventArgs e) + { + m_TitleArea = Rectangle.Empty; + // Exclude text area from border rendering + if (this.Text != null && this.Text.Length > 0) + { + Size s = GetAutoSize(this.ClientRectangle.Width - 8); + Rectangle r = new Rectangle(m_NCPainter.ClientRectangle.X + 3, 0, s.Width, m_NCPainter.ClientRectangle.Y); + Size availSize = new Size(m_NCPainter.ClientRectangle.Width - 8, m_NCPainter.ClientRectangle.Y); + + if (m_TitleImage != null && (m_TitleImagePosition == eTitleImagePosition.Left && this.RightToLeft == RightToLeft.Yes || + m_TitleImagePosition == eTitleImagePosition.Right && this.RightToLeft == RightToLeft.No)) + { + //r.X -= m_TitleImage.Width; + availSize.Width -= m_TitleImage.Width; + } + else if (m_TitleImage != null && (m_TitleImagePosition == eTitleImagePosition.Right && this.RightToLeft == RightToLeft.Yes || + m_TitleImagePosition == eTitleImagePosition.Left && this.RightToLeft == RightToLeft.No)) + { + r.X += m_TitleImage.Width; + availSize.Width -= m_TitleImage.Width; + } + //if (this.TextMarkupElement == null) + { + if (this.Style.TextAlignment == eStyleTextAlignment.Center) + { + //r.X = m_NCPainter.ClientRectangle.X; + r.X += (availSize.Width - r.Width) / 2; + } + else if (this.Style.TextAlignment == eStyleTextAlignment.Far || this.RightToLeft == RightToLeft.Yes && this.Style.TextAlignment == eStyleTextAlignment.Near) + { + r.X = r.X + (availSize.Width - r.Width); + } + } + + if (!r.IsEmpty) + { + r.Inflate(3, 0); + r.Width += 3; + } + + e.Graphics.SetClip(r, System.Drawing.Drawing2D.CombineMode.Exclude); + m_TitleArea = r; + } + + if (m_TitleImage != null) + { + Rectangle r = new Rectangle(m_NCPainter.ClientRectangle.X + 3, 0, m_TitleImage.Width, m_TitleImage.Height); + if (m_TitleImagePosition == eTitleImagePosition.Left && this.RightToLeft == RightToLeft.Yes || + m_TitleImagePosition == eTitleImagePosition.Right && this.RightToLeft == RightToLeft.No) + { + r.X = m_NCPainter.ClientRectangle.Right - r.Width - 4; + } + else if (m_TitleImagePosition == eTitleImagePosition.Center) + { + r.X = m_NCPainter.ClientRectangle.X; + r.X += (m_NCPainter.ClientRectangle.Width - r.Width) / 2; + } + + e.Graphics.SetClip(r, System.Drawing.Drawing2D.CombineMode.Exclude); + if (m_TitleArea.IsEmpty) + m_TitleArea = r; + else + m_TitleArea = Rectangle.Union(r, m_TitleArea); + } + } + + /// + /// Returns the size of the panel calculated based on the text assigned. + /// + /// Calculated size of the panel or Size.Empty if panel size cannot be calculated. + private Size GetAutoSize(int preferedWidth) + { + Size size = Size.Empty; + if (!this.IsHandleCreated) return size; + + if (TextMarkupElement != null) + { + if (preferedWidth == 0) + { + size = TextMarkupElement.Bounds.Size; + } + else + { + size = GetMarkupSize(preferedWidth); + } + size.Width += 4; + //size.Height += 1; + } + else if (this.Text.Length > 0) + { + Font font = this.Font; + if (this.Style.Font != null) font = this.Style.Font; + eTextFormat tf = eTextFormat.Default | eTextFormat.SingleLine | eTextFormat.NoPrefix; + using (Graphics g = BarFunctions.CreateGraphics(this)) + { + if (preferedWidth <= 0) + size = TextDrawing.MeasureString(g, this.Text, font, 0, tf); + else + size = TextDrawing.MeasureString(g, this.Text, font, preferedWidth, tf); + } + size.Width += 2; + size.Height += 2; + } + + if (size.IsEmpty) return size; + + size.Width += this.Style.MarginLeft + this.Style.MarginRight; + size.Height += this.Style.MarginTop + this.Style.MarginBottom; + + return size; + } + + private Size GetMarkupSize(int proposedWidth) + { + Size size = Size.Empty; + if (TextMarkupElement != null) + { + Rectangle r = new Rectangle(0, 0, proposedWidth, 500); + r.Inflate(-2, -2); + Graphics g = this.CreateGraphics(); + TextMarkup.BodyElement markup = TextMarkup.MarkupParser.Parse(this.Text); + try + { + if (AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, SystemColors.Control, (this.RightToLeft == RightToLeft.Yes)); + markup.Measure(r.Size, d); + size = markup.Bounds.Size; + } + finally + { + g.Dispose(); + } + } + + return size; + } + + protected override void RefreshTextClientRectangle() + { + if (m_NCPainter != null) + { + Rectangle r = new Rectangle(m_NCPainter.ClientRectangle.X, 0, m_NCPainter.ClientRectangle.Width, this.Height / 2); + r.Inflate(-2, 0); + if (m_TitleImage != null) + { + if (m_TitleImagePosition == eTitleImagePosition.Left && this.RightToLeft == RightToLeft.No || + m_TitleImagePosition == eTitleImagePosition.Right && this.RightToLeft == RightToLeft.Yes) + { + r.X += m_TitleImage.Width; + r.Width -= m_TitleImage.Width; + } + else if (m_TitleImagePosition == eTitleImagePosition.Left && this.RightToLeft == RightToLeft.Yes || + m_TitleImagePosition == eTitleImagePosition.Right && this.RightToLeft == RightToLeft.No) + { + r.Width -= m_TitleImage.Width; + } + Size s = GetMarkupSize(r.Width); + r.Y = Math.Max(0, m_NCPainter.ClientRectangle.Y - s.Height - 4); + } + this.ClientTextRectangle = r; + } + else + this.ClientTextRectangle = this.ClientRectangle; + + ResizeMarkup(); + } + + /// + /// Gets or sets whether text rectangle painted on panel is considering docked controls inside the panel. + /// + [Browsable(false), DefaultValue(true), Category("Appearance"), Description("Indicates whether text rectangle painted on panel is considering docked controls inside the panel.")] + public override bool TextDockConstrained + { + get { return base.TextDockConstrained; } + set { base.TextDockConstrained = value; } + + } + + /// + /// Gets or sets whether panel automatically provides shadows for child controls. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Appearance"), Description("Indicates whether panel automatically provides shadows for child controls.")] + public bool IsShadowEnabled + { + get { return m_IsShadowEnabled; } + set + { + if (m_IsShadowEnabled != value) + { + m_IsShadowEnabled = value; + this.Invalidate(); + } + } + } + /// + /// Applies color scheme to the panel. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetColorTable(ePanelColorTable colorScheme) + { + GroupPanel p = this; + DevComponents.DotNetBar.Rendering.ColorFactory factory = DevComponents.DotNetBar.Rendering.ColorFactory.Empty; + p.CanvasColor = SystemColors.Control; + p.ResetStyle(); + p.ColorSchemeStyle = eDotNetBarStyle.Office2007; + + if (colorScheme == ePanelColorTable.Default) + SetDefaultPanelStyle(); + else if (colorScheme == ePanelColorTable.Green) + { + p.Style.BackColor2 = factory.GetColor(0x9CBF8B); + p.Style.BackColorGradientAngle = 90; + p.Style.BackColor = factory.GetColor(0xC3D9B9); + p.Style.Border = DevComponents.DotNetBar.eStyleBorderType.Solid; + p.Style.BorderWidth = 1; + p.Style.BorderColor = factory.GetColor(0x72A45A); + p.Style.CornerDiameter = 4; + p.Style.CornerType = DevComponents.DotNetBar.eCornerType.Rounded; + p.Style.TextAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Center; + p.Style.TextColor = factory.GetColor(0x3C4A1F); + p.Style.TextLineAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Near; + } + else if (colorScheme == ePanelColorTable.Orange) + { + p.Style.BackColor = factory.GetColor(0xFAC08F); + p.Style.BackColor2 = factory.GetColor(0xF79646); + p.Style.BorderColor = factory.GetColor(0x974806); + p.Style.TextColor = factory.GetColor(0x7F3D06); + p.Style.BackColorGradientAngle = 90; + p.Style.Border = DevComponents.DotNetBar.eStyleBorderType.Solid; + p.Style.BorderWidth = 1; + p.Style.CornerDiameter = 4; + p.Style.CornerType = DevComponents.DotNetBar.eCornerType.Rounded; + p.Style.TextAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Center; + p.Style.TextLineAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Near; + } + else if (colorScheme == ePanelColorTable.Red) + { + p.Style.BackColor = factory.GetColor(0xE5BFBF); + p.Style.BackColor2 = factory.GetColor(0xD39696); + p.Style.BorderColor = factory.GetColor(0x953734); + p.Style.TextColor = factory.GetColor(0x632423); + p.Style.BackColorGradientAngle = 90; + p.Style.Border = DevComponents.DotNetBar.eStyleBorderType.Solid; + p.Style.BorderWidth = 1; + p.Style.CornerDiameter = 4; + p.Style.CornerType = DevComponents.DotNetBar.eCornerType.Rounded; + p.Style.TextAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Center; + p.Style.TextLineAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Near; + } + else if (colorScheme == ePanelColorTable.Yellow) + { + p.Style.BackColor = factory.GetColor(0xFFF3B2); + p.Style.BackColor2 = factory.GetColor(0xFAD945); + p.Style.BorderColor = factory.GetColor(0xEE9311); + p.Style.TextColor = factory.GetColor(0x3F3F00); + p.Style.BackColorGradientAngle = 90; + p.Style.Border = DevComponents.DotNetBar.eStyleBorderType.Solid; + p.Style.BorderWidth = 1; + p.Style.CornerDiameter = 4; + p.Style.CornerType = DevComponents.DotNetBar.eCornerType.Rounded; + p.Style.TextAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Center; + p.Style.TextLineAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Near; + } + else if (colorScheme == ePanelColorTable.Magenta) + { + p.Style.BackColor = factory.GetColor(0xEF91B4); + p.Style.BackColor2 = factory.GetColor(0xE66896); + p.Style.BorderColor = factory.GetColor(0xB12753); + p.Style.TextColor = factory.GetColor(0x8E2648); + p.Style.BackColorGradientAngle = 90; + p.Style.Border = DevComponents.DotNetBar.eStyleBorderType.Solid; + p.Style.BorderWidth = 1; + p.Style.CornerDiameter = 4; + p.Style.CornerType = DevComponents.DotNetBar.eCornerType.Rounded; + p.Style.TextAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Center; + p.Style.TextLineAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Near; + } + } + + /// + /// Applies default group panel style to the control. + /// + public void SetDefaultPanelStyle() + { + GroupPanel p = this; + + p.CanvasColor = SystemColors.Control; + p.ResetStyle(); + p.ColorSchemeStyle = eDotNetBarStyle.Office2007; + p.Style.BackColor2SchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBackground2; + p.Style.BackColorGradientAngle = 90; + p.Style.BackColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBackground; + p.Style.Border = DevComponents.DotNetBar.eStyleBorderType.Solid; + p.Style.BorderWidth = 1; + p.Style.BorderColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBorder; + p.Style.CornerDiameter = 4; + p.Style.CornerType = DevComponents.DotNetBar.eCornerType.Rounded; + p.Style.TextAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Center; + p.Style.TextColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelText; + p.Style.TextLineAlignment = DevComponents.DotNetBar.eStyleTextAlignment.Near; + } + + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + base.SetBoundsCore(x, y, width, height, specified); + + UpdateInternalClientSize(width, height, specified); + } + + protected override void OnTextChanged(EventArgs e) + { + if (IsHandleCreated) + { + UpdateInternalClientSize(this.Width, this.Height, BoundsSpecified.Width | BoundsSpecified.Height); + InvalidateNonClient(); + } + base.OnTextChanged(e); + } + + private void UpdateInternalClientSize(int width, int height, BoundsSpecified specified) + { + if (((specified & BoundsSpecified.Height) == BoundsSpecified.Height || (specified & BoundsSpecified.Width) == BoundsSpecified.Width)) + { + ElementStyle style = this.Style; + Rectangle r = new Rectangle(0, 0, width, height); + if (m_NCPainter != null) + { + Rectangle cr = m_NCPainter.GetClientRectangleForBorderStyle(r, style); + if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height) + height = cr.Height; + if ((specified & BoundsSpecified.Width) == BoundsSpecified.Width) + width = cr.Width; + + Type type = typeof(Control); + try // try with ignore catch is bad idea but in this case its for future proofing, just in case M$ removes these members + { + type.InvokeMember("clientWidth", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField, null, this, new object[] { width }); + type.InvokeMember("clientHeight", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField, null, this, new object[] { height }); + } + catch { } + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override bool AutoScroll + { + get + { + return base.AutoScroll; + } + set + { + base.AutoScroll = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public override Point AutoScrollOffset + { + get + { + return base.AutoScrollOffset; + } + set + { + base.AutoScrollOffset = value; + } + } + #endregion + + #region INonClientControl Members + + protected override void WndProc(ref System.Windows.Forms.Message m) + { + if (m_NCPainter == null) + { + base.WndProc(ref m); + return; + } + + if (m.Msg == (int)WinApi.WindowsMessages.WM_HSCROLL || m.Msg == (int)WinApi.WindowsMessages.WM_VSCROLL || + m.Msg == (int)WinApi.WindowsMessages.WM_MOUSEWHEEL) + { + //Region reg = new Region(new Rectangle(0, 0, this.Width, this.Height)); + //SuspendPaint = true; + //try + //{ + bool callBase = m_NCPainter.WndProc(ref m); + if (callBase) + BaseWndProc(ref m); + //} + //finally + //{ + //SuspendPaint = false; + //} + //foreach (Control c in this.Controls) + //{ + // if (c.Visible) + // reg.Exclude(c.Bounds); + //} + RefreshTextClientRectangle(); + //this.Invalidate(reg, false); + //if (this.Controls.Count > 0) + // this.Update(); + //reg.Dispose(); + } + else + { + bool callBase = m_NCPainter.WndProc(ref m); + //if (m.Msg == (int)WinApi.WindowsMessages.WM_NCCALCSIZE) + // UpdateInternalClientSize(this.Width, this.Height, BoundsSpecified.Width | BoundsSpecified.Height); + if (callBase) + BaseWndProc(ref m); + } + } + + void INonClientControl.BaseWndProc(ref Message m) + { + BaseWndProc(ref m); + } + + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public virtual Rendering.BaseRenderer GetRenderer() + { + if (Rendering.GlobalManager.Renderer != null) + return Rendering.GlobalManager.Renderer; + return null; + } + + ItemPaintArgs INonClientControl.GetItemPaintArgs(System.Drawing.Graphics g) + { + ItemPaintArgs pa = new ItemPaintArgs(this as IOwner, this, g, GetColorScheme()); + pa.Renderer = this.GetRenderer(); + pa.DesignerSelection = false; // m_DesignerSelection; + pa.GlassEnabled = !this.DesignMode && WinApi.IsGlassEnabled; + return pa; + } + + ElementStyle INonClientControl.BorderStyle + { + get { return this.Style; } + } + + void INonClientControl.PaintBackground(PaintEventArgs e) + { + base.OnPaintBackground(e); + } + + IntPtr INonClientControl.Handle + { + get { return this.Handle; } + } + + int INonClientControl.Width + { + get { return this.Width; } + } + + int INonClientControl.Height + { + get { return this.Height; } + } + + bool INonClientControl.IsHandleCreated + { + get { return this.IsHandleCreated; } + } + + System.Drawing.Point INonClientControl.PointToScreen(System.Drawing.Point client) + { + return this.PointToScreen(client); + } + + System.Drawing.Color INonClientControl.BackColor + { + get { return this.BackColor; } + } + + void DevComponents.DotNetBar.Controls.INonClientControl.RenderNonClient(Graphics g) { } + + void DevComponents.DotNetBar.Controls.INonClientControl.AdjustClientRectangle(ref Rectangle r) + { + Size textSize = GetAutoSize(r.Width); + if (m_TitleImage != null) + { + textSize.Height = Math.Max(m_TitleImage.Height, textSize.Height); + } + if (textSize.Height > r.Height) textSize.Height = r.Height - 8; + r.Y += textSize.Height; + r.Height -= textSize.Height; + } + + void INonClientControl.AdjustBorderRectangle(ref Rectangle r) + { + if (this.Text != "") + { + int h = GetNonClientTopHeight(); + r.Y += h; + r.Height -= h; + } + } + + private int GetNonClientTopHeight() + { + Font f = this.Font; + if (this.Style.Font != null) + f = this.Style.Font; + int h = (int)(f.Height * .7f); + if (m_TitleImage != null) + { + h = Math.Max(m_TitleImage.Height - (f.Height - h - 1), h); + } + return h; + } + internal Rectangle GetInternalClientRectangle() + { + return m_NCPainter.ClientRectangle; + } + private Color _DisabledBackColor = Color.Empty; + /// + /// Specifies back color when Enabled=false + /// + [Browsable(false), Category("Appearance"), Description("Specifies back color when Enabled=false")] + public Color DisabledBackColor + { + get { return _DisabledBackColor; } + set + { + _DisabledBackColor = value; + if (!Enabled) this.Invalidate(); + } + } + #endregion + } + /// + /// Defines predefined color schemes for panel control. + /// + public enum ePanelColorTable + { + Default, + Green, + Orange, + Red, + Yellow, + Magenta + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/GroupPanel.ico b/PROMS/DotNetBar Source Code/Controls/GroupPanel.ico new file mode 100644 index 00000000..d810f802 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/GroupPanel.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/LabelX.cs b/PROMS/DotNetBar Source Code/Controls/LabelX.cs new file mode 100644 index 00000000..1fe70dc2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/LabelX.cs @@ -0,0 +1,696 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; +using System.Security.Permissions; + +namespace DevComponents.DotNetBar +{ +#if FRAMEWORK20 + [Designer("DevComponents.DotNetBar.Design.LabelXDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] +#endif + [ToolboxBitmap(typeof(LabelX), "Controls.LabelX.ico"), ToolboxItem(true), System.Runtime.InteropServices.ComVisible(false)] + public class LabelX : BaseItemControl, ICommandSource + { + #region Private Variables + private LabelItem m_Label = null; + private bool m_UseMnemonic = true; + private Size m_PreferredSize = Size.Empty; + #endregion + + #region Events + /// + /// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + public event MarkupLinkClickEventHandler MarkupLinkClick; + #endregion + + #region Constructor, Dispose + public LabelX() + { + m_Label = new LabelItem(); + m_Label.Style = eDotNetBarStyle.Office2007; + m_Label.MarkupLinkClick += new MarkupLinkClickEventHandler(LabelMarkupLinkClick); + this.FocusCuesEnabled = false; + this.HostItem = m_Label; + this.TabStop = false; + this.SetStyle(ControlStyles.Selectable, false); + } + #endregion + + #region Internal Implementation + /// + /// Specifies spacing between label image and text. + /// + [DefaultValue(2), Category("Appearance"), Description("Specifies spacing between label image and text.")] + public int ImageTextSpacing + { + get { return m_Label.ImageTextSpacing; } + set { m_Label.ImageTextSpacing = value; } + } + + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)] + protected string PlainText + { + get + { + return m_Label.PlainText; + } + } + + /// + /// Gets or sets whether text-markup support is enabled for controls Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the control instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for controls Text property.")] + public bool EnableMarkup + { + get { return m_Label.EnableMarkup; } + set + { + m_Label.EnableMarkup = value; + } + } + + /// + /// Gets or sets whether control displays focus cues when focused. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether control displays focus cues when focused.")] + public override bool FocusCuesEnabled + { + get + { + return base.FocusCuesEnabled; + } + set + { + base.FocusCuesEnabled = value; + } + } + protected override void OnHandleCreated(EventArgs e) + { +#if FRAMEWORK20 + if (this.AutoSize) + this.AdjustSize(); +#endif + this.RecalcLayout(); + base.OnHandleCreated(e); + } + /// + /// Recalculates the size of the internal item. + /// + protected override void RecalcSize() + { + m_Label.SuspendPaint = true; + m_Label.Width = Dpi.DescaleWidth(m_Label.Bounds.Width); + m_Label.Height = Dpi.DescaleHeight(m_Label.Bounds.Height); + m_Label.SuspendPaint = false; + base.RecalcSize(); + } + + protected override void OnBackColorChanged(EventArgs e) + { + m_Label.BackColor = this.BackColor; + base.OnBackColorChanged(e); + } + + protected override void OnForeColorChanged(EventArgs e) + { + if (this.ForeColor == SystemColors.ControlText) + m_Label.ForeColor = Color.Empty; + else + m_Label.ForeColor = this.ForeColor; + base.OnForeColorChanged(e); + } + + /// + /// Gets or sets the border sides that are displayed. Default value specifies border on all 4 sides. + /// + [Browsable(false), Category("Appearance"), DefaultValue(LabelItem.DEFAULT_BORDERSIDE), Description("Specifies border sides that are displayed.")] + public eBorderSide BorderSide + { + get { return m_Label.BorderSide; } + set { m_Label.BorderSide = value; InvalidateAutoSize(); } + } + + /// + /// Gets or sets the type of the border drawn around the label. + /// + [Browsable(false), Category("Appearance"), DefaultValue(eBorderType.None), Description("Indicates the type of the border drawn around the label.")] + public eBorderType BorderType + { + get { return m_Label.BorderType; } + set { m_Label.BorderType = value; InvalidateAutoSize(); } + } + + /// + /// Specifies label image. + /// + [Browsable(true), Category("Appearance"), Description("The image that will be displayed on the face of the item."), DefaultValue(null)] + public System.Drawing.Image Image + { + get { return m_Label.Image; } + set { m_Label.Image = value; InvalidateAutoSize(); } + } + + /// + /// Gets/Sets the image position inside the label. + /// + [Browsable(true), Category("Appearance"), Description("The alignment of the image in relation to text displayed by this item."), DefaultValue(eImagePosition.Left)] + public eImagePosition ImagePosition + { + get { return m_Label.ImagePosition; } + set { m_Label.ImagePosition = value; InvalidateAutoSize(); } + } + + /// + /// Gets or sets the border line color when border is single line. + /// + [Browsable(true), Category("Appearance"), Description("Indicates border line color when border is single line.")] + public Color SingleLineColor + { + get { return m_Label.SingleLineColor; } + set { m_Label.SingleLineColor = value; } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSingleLineColor() + { + return m_Label.ShouldSerializeSingleLineColor(); + } + + /// + /// Resets the SingleLineColor property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSingleLineColor() + { + m_Label.ResetSingleLineColor(); + } + + /// + /// Gets or sets the text associated with this item. + /// + [Browsable(true), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Appearance"), Description("The text contained in the item.")] + public override string Text + { + get { return base.Text; } + set { base.Text = value; } + } + + /// + /// Gets or sets the horizontal text alignment. + /// + [Browsable(true), DefaultValue(StringAlignment.Near), DevCoBrowsable(true), Category("Layout"), Description("Indicates text alignment.")] + public System.Drawing.StringAlignment TextAlignment + { + get { return m_Label.TextAlignment; } + set + { + m_Label.TextAlignment = value; + this.RecalcLayout(); + } + } + + /// + /// Gets or sets the text vertical alignment. + /// + [Browsable(true), DefaultValue(System.Drawing.StringAlignment.Center), DevCoBrowsable(true), Category("Layout"), Description("Indicates text line alignment.")] + public System.Drawing.StringAlignment TextLineAlignment + { + get { return m_Label.TextLineAlignment; } + set + { + m_Label.TextLineAlignment = value; + this.RecalcLayout(); + } + } + + /// + /// Gets or sets a value that determines whether text is displayed in multiple lines or one long line. + /// + [Browsable(true), Category("Style"), DefaultValue(false), Description("Gets or sets a value that determines whether text is displayed in multiple lines or one long line.")] + public bool WordWrap + { + get { return m_Label.WordWrap; } + set { m_Label.WordWrap = value; RecalcLayout(); } + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool TabStop + { + get { return base.TabStop; } + set { base.TabStop = value; } + } + + /// + /// Gets or sets the left padding in pixels. + /// + [Browsable(true), DefaultValue(0), Category("Layout"), Description("Indicates left padding in pixels.")] + public int PaddingLeft + { + get { return m_Label.PaddingLeft; } + set { m_Label.PaddingLeft = value; InvalidateAutoSize(); } + } + + /// + /// Gets or sets the right padding in pixels. + /// + [Browsable(true), DefaultValue(0), Category("Layout"), Description("Indicates right padding in pixels.")] + public int PaddingRight + { + get + { + return m_Label.PaddingRight; + } + set + { + m_Label.PaddingRight = value; + InvalidateAutoSize(); + } + } + + /// + /// Gets or sets the top padding in pixels. + /// + [Browsable(true), DefaultValue(0), Category("Layout"), Description("Indicates top padding in pixels.")] + public int PaddingTop + { + get + { + return m_Label.PaddingTop; + } + set + { + m_Label.PaddingTop = value; + InvalidateAutoSize(); + } + } + + /// + /// Gets or sets the bottom padding in pixels. + /// + [Browsable(true), DefaultValue(0), Category("Layout"), Description("Indicates bottom padding in pixels.")] + public int PaddingBottom + { + get + { + return m_Label.PaddingBottom; + } + set + { + m_Label.PaddingBottom = value; + InvalidateAutoSize(); + } + } + + private void LabelMarkupLinkClick(object sender, MarkupLinkClickEventArgs e) + { + OnMarkupLinkClick(e); + } + + /// + /// Invokes the MarkupLinkClick event. + /// + /// Provides additional data about event. + protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e) + { + if (MarkupLinkClick != null) + MarkupLinkClick(this, e); + } + + /// + /// Gets or sets a value indicating whether the control interprets an ampersand character (&) in the control's Text property to be an access key prefix character. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether the control interprets an ampersand character (&) in the control's Text property to be an access key prefix character.")] + public bool UseMnemonic + { + get { return m_UseMnemonic; } + set + { + m_UseMnemonic = value; + InvalidateAutoSize(); + this.Invalidate(); + } + } + + protected void InvalidateAutoSize() + { + m_PreferredSize = Size.Empty; + } + + protected override void OnPaint(PaintEventArgs e) + { + if (m_UseMnemonic) + m_Label.ShowPrefix = true; + else + m_Label.ShowPrefix = false; + + if (m_Label.NeedRecalcSize) m_Label.RecalcSize(); + + base.OnPaint(e); + } + + private bool CanProcessMnemonic() + { + if (!this.Enabled || !this.Visible) + return false; + return true; + } + + [UIPermission(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)] + protected override bool ProcessMnemonic(char charCode) + { + if ((!this.UseMnemonic || !Control.IsMnemonic(charCode, this.Text)) || !this.CanProcessMnemonic() || Control.ModifierKeys != Keys.Alt || m_Label.IsUsingTextMarkup) + { + return false; + } + Control parent = this.Parent; + if (parent != null) + { + if (parent.SelectNextControl(this, true, false, true, false) && !parent.ContainsFocus) + { + parent.Focus(); + } + } + return true; + } + +#if FRAMEWORK20 + [Localizable(true), Browsable(false)] + public new System.Windows.Forms.Padding Padding + { + get { return base.Padding; } + set { base.Padding = value; } + } + + internal bool IsUsingTextMarkup + { + get + { + if (m_Label != null) + return m_Label.TextMarkupBody != null; + return false; + } + } + + public override Size GetPreferredSize(Size proposedSize) + { + if (!m_PreferredSize.IsEmpty && (proposedSize.Width == m_PreferredSize.Width || proposedSize.Width == 0 || this.AutoSize)) return m_PreferredSize; + + if (!BarFunctions.IsHandleValid(this) || this.DesignMode && !this.AutoSize) + return base.GetPreferredSize(proposedSize); + if (this.Text.Length == 0) + return base.GetPreferredSize(proposedSize); + + int oldWidth = m_Label.Width, oldHeight = m_Label.Height; + m_Label.SuspendPaint = true; + m_Label.Width = 0; + m_Label.Height = 0; + if ((proposedSize.Width > 0 && proposedSize.Width < 500000 || this.MaximumSize.Width > 0) && m_Label.TextMarkupBody != null) + { + if (TextOrientation == eOrientation.Horizontal) + m_Label.RecalcSizeMarkup((this.MaximumSize.Width > 0 ? this.MaximumSize.Width : proposedSize.Width)); + else + m_Label.RecalcSizeMarkup((this.MaximumSize.Height > 0 ? this.MaximumSize.Height : proposedSize.Height)); + } + else + { + m_Label.RecalcSize(); + if (this.WordWrap && m_Label.WidthInternal > this.MaximumSize.Width && this.MaximumSize.Width > 0) + { + m_Label.Height = 0; + m_Label.Width = Dpi.DescaleWidth(this.MaximumSize.Width); + m_Label.RecalcSize(); + } + else if (this.WordWrap && m_Label.WidthInternal > proposedSize.Width && proposedSize.Width > 0) + { + m_Label.Height = 0; + m_Label.Width = Dpi.DescaleWidth(proposedSize.Width); + m_Label.RecalcSize(); + } + } + Size s = m_Label.Size; + s.Height += 2; + if (this.TextOrientation == eOrientation.Vertical) + { + s.Width += Dpi.Width2; + } + if (this.Font.Size > 13) + s.Height += 2; + m_Label.Width = oldWidth; + m_Label.Height = oldHeight; + m_Label.SuspendPaint = false; + m_PreferredSize = s; + + return m_PreferredSize; + } + + /// + /// Gets or sets a value indicating whether the control is automatically resized to display its entire contents. You can set MaximumSize.Width property to set the maximum width used by the control. + /// + [Browsable(true), DefaultValue(false), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override bool AutoSize + { + get + { + return base.AutoSize; + } + set + { + if (this.AutoSize != value) + { + base.AutoSize = value; + AdjustSize(); + } + } + } + + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + if (this.AutoSize) + { + Size preferredSize = Size.Empty; + if (width != m_PreferredSize.Width && width > 0) + { + InvalidateAutoSize(); + preferredSize = this.GetPreferredSize(new Size(width, 0)); + } + else + preferredSize = this.PreferredSize; + width = preferredSize.Width; + height = preferredSize.Height; + } + base.SetBoundsCore(x, y, width, height, specified); + } + + private void AdjustSize() + { + if (this.AutoSize) + { + this.Size = base.PreferredSize; + } + } + + protected override void OnFontChanged(EventArgs e) + { + InvalidateAutoSize(); + base.OnFontChanged(e); + } + + protected override void OnTextChanged(EventArgs e) + { + InvalidateAutoSize(); + base.OnTextChanged(e); + this.AdjustSize(); + } +#endif + /// + /// Gets or sets text-orientation. Default is horizontal. + /// + [DefaultValue(eOrientation.Horizontal), Category("Appearance"), Description("Indicates text-orientation")] + public eOrientation TextOrientation + { + get { return m_Label.TextOrientation; } + set + { + m_Label.TextOrientation = value; + InvalidateAutoSize(); + this.AdjustSize(); + } + } + + /// + /// Gets or sets how vertical text is rotated when TextOrientation = Vertical. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates how vertical text is rotated when TextOrientation = Vertical.")] + public bool VerticalTextTopUp + { + get { return m_Label.VerticalTextTopUp; } + set + { + m_Label.VerticalTextTopUp = value; + if (TextOrientation == eOrientation.Vertical) + { + this.Invalidate(); + } + } + } + + /// + /// Gets the underlying LabelItem + /// + internal LabelItem LabelItem + { + get { return (m_Label); } + } + + /// + /// Indicates the symbol displayed on label instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the tile instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return m_Label.Symbol; } + set { m_Label.Symbol = value; } + } + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return m_Label.SymbolSet; } + set { m_Label.SymbolSet = value; } + } + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(0f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return m_Label.SymbolSize; } + set { m_Label.SymbolSize = value; } + } + /// + /// Gets or sets the color of the symbol. + /// + [Category("Appearance"), Description("Indicates color of the symbol.")] + public Color SymbolColor + { + get { return m_Label.SymbolColor; } + set { m_Label.SymbolColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return m_Label.ShouldSerializeSymbolColor(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + m_Label.ResetSymbolColor(); + } + + /// + /// Indicates whether label text is rendered using bold font unless the Font property is specifically set to different font. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether label text is rendered using bold font unless the Font property is specifically set to different font.")] + public bool FontBold + { + get { return m_Label.FontBold; } + set + { + if (m_Label.FontBold != value) + { + m_Label.FontBold = value; + this.Invalidate(); + } + } + } + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + CommandManager.ExecuteCommand(this); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + } + } + + private ICommand _Command = null; + //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if (changed) + OnCommandChanged(); + } + } + + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/LabelX.ico b/PROMS/DotNetBar Source Code/Controls/LabelX.ico new file mode 100644 index 00000000..4e97915d Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/LabelX.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/Line.cs b/PROMS/DotNetBar Source Code/Controls/Line.cs new file mode 100644 index 00000000..9c978945 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Line.cs @@ -0,0 +1,489 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// A single horizontal or vertical line control. + /// + [ToolboxBitmap(typeof(Line), "Controls.Line.ico"), ToolboxItem(true), Description("Horizontal or Vertical Line Control")] + public class Line : Control + { + #region Constructor + /// + /// Initializes a new instance of the Line class. + /// + public Line() + { + this.SetStyle(ControlStyles.AllPaintingInWmPaint + | ControlStyles.OptimizedDoubleBuffer + | ControlStyles.UserPaint + | ControlStyles.SupportsTransparentBackColor + , true); + } + #endregion + + #region Implementation + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + using (Pen pen = new Pen(ForeColor, _Thickness)) + { + pen.DashStyle = _DashStyle; + pen.DashOffset = _DashOffset; + + Point lineStart = LineStartPoint; + Point lineEnd = LineEndPoint; + + if (_StartLineCap != eLineEndType.None && _Thickness > 1) + { + if (_VerticalLine) + lineStart.Y += _StartLineCapSize.Height / 2; + else + lineStart.X += _StartLineCapSize.Width / 2; + } + if (_EndLineCap != eLineEndType.None && _Thickness > 1) + { + if (_VerticalLine) + lineEnd.Y -= _EndLineCapSize.Height / 2; + else + lineEnd.X -= _EndLineCapSize.Width / 2; + } + + g.DrawLine(pen, lineStart, lineEnd); + } + + if (_StartLineCap != eLineEndType.None && _StartLineCapSize.Width > 0 && _StartLineCapSize.Height > 0) + DrawLineCap(g, LineStartPoint, _StartLineCap, _StartLineCapSize, true); + + if (_EndLineCap != eLineEndType.None && _EndLineCapSize.Width > 0 && _EndLineCapSize.Height > 0) + DrawLineCap(g, LineEndPoint, _EndLineCap, _EndLineCapSize, false); + + g.SmoothingMode = sm; + + base.OnPaint(e); + } + private void DrawLineCap(Graphics g, Point linePoint, eLineEndType lineCap, Size capSize, bool isStartCap) + { + if (lineCap == eLineEndType.Arrow) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.HighQuality; + using (GraphicsPath path = new GraphicsPath()) + { + if (isStartCap) + { + if (VerticalLine) + path.AddLines(new Point[] { + new Point(linePoint.X, linePoint.Y), + new Point(linePoint.X - capSize.Width/2, linePoint.Y+capSize.Height), + new Point(linePoint.X+capSize.Width / 2, linePoint.Y+capSize.Height)}); + else + path.AddLines(new Point[] { + new Point(linePoint.X, linePoint.Y), + new Point(linePoint.X + capSize.Width, linePoint.Y-capSize.Height/2), + new Point(linePoint.X+capSize.Width, linePoint.Y+ capSize.Height/2)}); + } + else + { + if (VerticalLine) + path.AddLines(new Point[] { + new Point(linePoint.X, linePoint.Y), + new Point(linePoint.X + capSize.Width / 2, linePoint.Y - capSize.Height), + new Point(linePoint.X - capSize.Width / 2, linePoint.Y - capSize.Height)}); + else + path.AddLines(new Point[] { + new Point(linePoint.X, linePoint.Y), + new Point(linePoint.X - capSize.Width, linePoint.Y + capSize.Height / 2), + new Point(linePoint.X - capSize.Width, linePoint.Y - capSize.Height/2)}); + } + path.CloseAllFigures(); + using (SolidBrush brush = new SolidBrush(ForeColor)) + g.FillPath(brush, path); + } + g.SmoothingMode = sm; + } + else if (lineCap == eLineEndType.Circle) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.HighQuality; + using (SolidBrush brush = new SolidBrush(ForeColor)) + { + if (VerticalLine && isStartCap) + g.FillEllipse(brush, new Rectangle(linePoint.X - capSize.Width/2, linePoint.Y , capSize.Width, capSize.Height)); + else if (VerticalLine) + g.FillEllipse(brush, new Rectangle(linePoint.X - capSize.Width/2, linePoint.Y - capSize.Height - 1, capSize.Width, capSize.Height)); + else if (isStartCap) + g.FillEllipse(brush, new Rectangle(linePoint.X, linePoint.Y - capSize.Height / 2, capSize.Width, capSize.Height)); + else + g.FillEllipse(brush, new Rectangle(linePoint.X - capSize.Width - 1, linePoint.Y - capSize.Height / 2, capSize.Width, capSize.Height)); + } + g.SmoothingMode = sm; + } + else if (lineCap == eLineEndType.Diamond) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.HighQuality; + using (GraphicsPath path = new GraphicsPath()) + { + if (isStartCap) + { + if (VerticalLine) + path.AddLines(new Point[] { + new Point(linePoint.X, linePoint.Y), + new Point(linePoint.X - capSize.Width/2, linePoint.Y+capSize.Height / 2), + new Point(linePoint.X, linePoint.Y+capSize.Height), + new Point(linePoint.X+capSize.Width / 2, linePoint.Y+capSize.Height / 2)}); + else + path.AddLines(new Point[] { + new Point(linePoint.X, linePoint.Y), + new Point(linePoint.X + capSize.Width/2, linePoint.Y-capSize.Height/2), + new Point(linePoint.X + capSize.Width, linePoint.Y), + new Point(linePoint.X+capSize.Width / 2, linePoint.Y+ capSize.Height/2)}); + } + else + { + if (VerticalLine) + { + linePoint.Y--; + path.AddLines(new Point[] { + new Point(linePoint.X, linePoint.Y), + new Point(linePoint.X + capSize.Width / 2, linePoint.Y - capSize.Height / 2), + new Point(linePoint.X, linePoint.Y - capSize.Height), + new Point(linePoint.X - capSize.Width / 2, linePoint.Y - capSize.Height / 2)}); + } + else + { + linePoint.X--; + path.AddLines(new Point[] { + new Point(linePoint.X, linePoint.Y), + new Point(linePoint.X - capSize.Width / 2, linePoint.Y - capSize.Height / 2), + new Point(linePoint.X - capSize.Width, linePoint.Y), + new Point(linePoint.X - capSize.Width / 2, linePoint.Y + capSize.Height/2)}); + } + } + path.CloseAllFigures(); + using (SolidBrush brush = new SolidBrush(ForeColor)) + g.FillPath(brush, path); + } + g.SmoothingMode = sm; + } + else if (lineCap == eLineEndType.Rectangle) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.HighQuality; + using (SolidBrush brush = new SolidBrush(ForeColor)) + { + if (VerticalLine && isStartCap) + g.FillRectangle(brush, new Rectangle(linePoint.X - capSize.Width / 2, linePoint.Y, capSize.Width, capSize.Height)); + else if (VerticalLine) + g.FillRectangle(brush, new Rectangle(linePoint.X - capSize.Width / 2, linePoint.Y - capSize.Height - 1, capSize.Width, capSize.Height)); + else if (isStartCap) + g.FillRectangle(brush, new Rectangle(linePoint.X, linePoint.Y - capSize.Height / 2, capSize.Width, capSize.Height)); + else + g.FillRectangle(brush, new Rectangle(linePoint.X - capSize.Width - 1, linePoint.Y - capSize.Height / 2, capSize.Width, capSize.Height)); + } + g.SmoothingMode = sm; + } + } + private Point LineStartPoint + { + get + { + if (!_VerticalLine) + { + if (_LineAlignment == eItemAlignment.Center) + return new Point(0, this.Height / 2); + else if (_LineAlignment == eItemAlignment.Near) + return new Point(0, _Thickness / 2 + ((_StartLineCap != eLineEndType.None) ? _StartLineCapSize.Height / 2 : 0)); + else if (_LineAlignment == eItemAlignment.Far) + return new Point(0, this.Height - _Thickness / 2 - ((_StartLineCap != eLineEndType.None) ? _StartLineCapSize.Height / 2 : 0)); + } + else + { + if (_LineAlignment == eItemAlignment.Center) + return new Point(this.Width / 2, 0); + else if (_LineAlignment == eItemAlignment.Near) + { + return new Point(_Thickness / 2 + ((_EndLineCap != eLineEndType.None) ? _EndLineCapSize.Width / 2 : 0), 0); + } + else if (_LineAlignment == eItemAlignment.Far) + return new Point(this.Width - _Thickness / 2 - ((_EndLineCap != eLineEndType.None) ? _EndLineCapSize.Width / 2 : 0), 0); + } + return Point.Empty; + } + } + private Point LineEndPoint + { + get + { + if (!_VerticalLine) + { + return new Point(this.Width, LineStartPoint.Y); + } + else + { + return new Point(LineStartPoint.X, this.Height); + } + + } + } + + private eItemAlignment _LineAlignment = eItemAlignment.Center; + /// + /// Specifies the line alignment within control bounds. + /// + [DefaultValue(eItemAlignment.Center), Category("Appearance"), Description("Specifies the line alignment within control bounds.")] + public eItemAlignment LineAlignment + { + get { return _LineAlignment; } + set { _LineAlignment = value; this.Invalidate(); } + } + + private float _DashOffset; + /// + /// Specifies distance from the start of a line to the beginning of a dash pattern. + /// + [DefaultValue(0f), Category("Appearance"), Description("Specifies distance from the start of a line to the beginning of a dash pattern.")] + public float DashOffset + { + get { return _DashOffset; } + set { _DashOffset = value; this.Invalidate(); } + } + + private DashStyle _DashStyle = DashStyle.Solid; + /// + /// Specifies the line dash style. + /// + [DefaultValue(DashStyle.Solid), Category("Appearance"), Description("Specifies the line dash style.")] + public DashStyle DashStyle + { + get { return _DashStyle; } + set { _DashStyle = value; this.Invalidate(); } + } + + //private LineCap _LineCap = System.Drawing.Drawing2D.LineCap.Round; + ///// + ///// Gets or sets the line cap i.e. line ending. + ///// + //[DefaultValue(LineCap.Round), Category("Appearance"), Description("Specifies line cap i.e. line ending.")] + //public LineCap LineCap + //{ + // get { return _LineCap; } + // set { _LineCap = value; this.Invalidate(); } + //} + + private int _Thickness = 1; + /// + /// Gets or sets the line thickness in pixels. + /// + [DefaultValue(1), Category("Appearance"), Description("Indicates line thickness in pixels.")] + public int Thickness + { + get { return _Thickness; } + set + { + _Thickness = value; + this.Invalidate(); + if (this.AutoSize) AdjustSize(); + } + } + + + private bool _VerticalLine = false; + /// + /// Gets or sets whether vertical line is drawn. Default value is false which means horizontal line is drawn. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether vertical line is drawn.")] + public bool VerticalLine + { + get { return _VerticalLine; } + set + { + _VerticalLine = value; + this.Invalidate(); + } + } + /// + /// Gets or sets a value indicating whether the control is automatically resized to display its entire contents. You can set MaximumSize.Width property to set the maximum width used by the control. + /// + [Browsable(true), DefaultValue(false), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override bool AutoSize + { + get + { + return base.AutoSize; + } + set + { + if (this.AutoSize != value) + { + base.AutoSize = value; + AdjustSize(); + } + } + } + private void AdjustSize() + { + this.Size = GetPreferredSize(this.Size); + } + public override Size GetPreferredSize(Size proposedSize) + { + if (this.VerticalLine) + return new Size(_Thickness, this.Height); + else + return new Size(this.Width, _Thickness); + //return base.GetPreferredSize(proposedSize); + } + + private eLineEndType _StartLineCap = eLineEndType.None; + /// + /// Indicates the start of the line cap. + /// + [DefaultValue(eLineEndType.None), Category("Appearance"), Description("Indicates the start of the line cap.")] + public eLineEndType StartLineCap + { + get { return _StartLineCap; } + set + { + if (value != _StartLineCap) + { + eLineEndType oldValue = _StartLineCap; + _StartLineCap = value; + OnStartLineCapChanged(oldValue, value); + } + } + } + /// + /// Called when StartLineCap property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnStartLineCapChanged(eLineEndType oldValue, eLineEndType newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("StartLineCap")); + this.Refresh(); + } + private static readonly Size DefaultCapSize = new Size(6, 6); + private Size _StartLineCapSize = DefaultCapSize; + /// + /// Indicates the size of the start cap. + /// + [Category("Appearance"), Description("Indicates the size of the start cap.")] + public Size StartLineCapSize + { + get { return _StartLineCapSize; } + set + { + if (value != _StartLineCapSize) + { + Size oldValue = _StartLineCapSize; + _StartLineCapSize = value; + OnStartLineCapSizeChanged(oldValue, value); + } + } + } + /// + /// Called when StartLineCapSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnStartLineCapSizeChanged(Size oldValue, Size newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("StartLineCapSize")); + this.Refresh(); + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeStartLineCapSize() + { + return _StartLineCapSize != DefaultCapSize; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetStartLineCapSize() + { + this.StartLineCapSize = DefaultCapSize; + } + + private eLineEndType _EndLineCap = eLineEndType.None; + /// + /// Indicates the start of the line cap. + /// + [DefaultValue(eLineEndType.None), Category("Appearance"), Description("Indicates the start of the line cap.")] + public eLineEndType EndLineCap + { + get { return _EndLineCap; } + set + { + if (value != _EndLineCap) + { + eLineEndType oldValue = _EndLineCap; + _EndLineCap = value; + OnEndLineCapChanged(oldValue, value); + } + } + } + /// + /// Called when EndLineCap property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnEndLineCapChanged(eLineEndType oldValue, eLineEndType newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("EndLineCap")); + this.Refresh(); + } + + private Size _EndLineCapSize = DefaultCapSize; + /// + /// Indicates end line cap size. + /// + [Category("Appearance"), Description("Indicates end line cap size.")] + public Size EndLineCapSize + { + get { return _EndLineCapSize; } + set { _EndLineCapSize = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeEndLineCapSize() + { + return _EndLineCapSize != DefaultCapSize; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetEndLineCapSize() + { + this.EndLineCapSize = DefaultCapSize; + } + #endregion + } + /// + /// Defined line end types. + /// + public enum eLineEndType + { + None, + Arrow, + Rectangle, + Circle, + Diamond + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Line.ico b/PROMS/DotNetBar Source Code/Controls/Line.ico new file mode 100644 index 00000000..074e3392 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/Line.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/CheckStateConvertEventArgs.cs b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/CheckStateConvertEventArgs.cs new file mode 100644 index 00000000..9b757274 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/CheckStateConvertEventArgs.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Provides data for CheckStateConvert event. + /// + public class CheckStateConvertEventArgs : EventArgs + { + public readonly object Value; + public CheckState? CheckState = null; + /// + /// Initializes a new instance of the CheckStateConvertEventArgs class. + /// + /// + public CheckStateConvertEventArgs(object value) + { + Value = value; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxAdv.cs b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxAdv.cs new file mode 100644 index 00000000..5c77e9b5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxAdv.cs @@ -0,0 +1,1051 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Collections.Generic; +using System.Collections; +using DevComponents.DotNetBar.Primitives; +using System.Drawing.Design; + +namespace DevComponents.DotNetBar +{ + [ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.ListBoxAdvDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.Runtime.InteropServices.ComVisible(false)] + [ToolboxBitmap(typeof(ToolboxIconResFinder), "ListBoxAdv.ico")] + public class ListBoxAdv : ItemPanelBase + { + #region Constructor + /// + /// Initializes a new instance of the ListBoxAdv class. + /// + public ListBoxAdv() + { + _SelectedItems = new CustomCollection(); + m_ItemContainer.LayoutOrientation = eOrientation.Vertical; + EnsureBindingGenerator(); + ItemVisualGenerator generator = ItemGenerator; + generator.CustomCollectionBinding = true; + generator.DataSource = _Items; + } + #endregion + + #region Implementation + private string _CheckStateMember; + private CustomCollection _Items = new CustomCollection(); + /// + /// Gets the list of items displayed in list box. + /// + [Category("Appearance"), Description("List of items displayed in list box."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), MergableProperty(false), Localizable(true)] + [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + public CustomCollection Items + { + get { return _Items; } + } + /// + /// Gets the collection of view items which are created to represent each data item in Items collection. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IList Views + { + get { return GetItemsCollection();} + } + + protected override void OnDataSourceChanged(object newDataSource) + { + ClearDescriptorsCache(); + EnsureBindingGenerator(); + + ItemVisualGenerator generator = ItemGenerator; + if (newDataSource == null && generator.CustomCollectionBinding) return; // Nothing changed + + if (newDataSource == null) + { + generator.CustomCollectionBinding = true; + generator.DataSource = _Items; + } + else + { + generator.CustomCollectionBinding = false; + generator.DataSource = newDataSource; + } + if (generator.DataSource != newDataSource) + { + generator.DataSource = newDataSource; + OnDataSourceChanged(EventArgs.Empty); + } + } + + // Fields... + private bool _CheckBoxesVisible = false; + /// + /// Indicates whether check-boxes are visible inside list box items. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether check-boxes are visible inside list box items.")] + public bool CheckBoxesVisible + { + get { return _CheckBoxesVisible; } + set + { + if (value != _CheckBoxesVisible) + { + bool oldValue = _CheckBoxesVisible; + _CheckBoxesVisible = value; + OnCheckBoxesVisibleChanged(oldValue, value); + } + } + } + /// + /// Called when CheckBoxesVisible property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCheckBoxesVisibleChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("CheckBoxesVisible")); + m_ItemContainer.NeedRecalcSize = true; + this.RecalcLayout(); + } + + private int _ItemHeight = 20; + /// + /// Indicates fixed item height. Maybe set to 0 to indicate that each item should be sized based on its content. + /// + [DefaultValue(20), Category("Appearance"), Description("Indicates fixed item height. Maybe set to 0 to indicate that each item should be sized based on its content.")] + public int ItemHeight + { + get { return _ItemHeight; } + set + { + if (value != _ItemHeight) + { + int oldValue = _ItemHeight; + _ItemHeight = value; + OnItemHeightChanged(oldValue, value); + } + } + } + /// + /// Called when ItemHeight property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnItemHeightChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("ItemHeight")); + + } + + protected override BaseItem GetDefaultItemTemplate() + { + ListBoxItem item = new ListBoxItem(); + return item; + } + + private eSelectionMode _SelectionMode = eSelectionMode.One; + /// + /// Specifies the selection mode used by the control. + /// + [DefaultValue(eSelectionMode.One), Category("Behavior"), Description("Specifies the selection mode used by the control.")] + public eSelectionMode SelectionMode + { + get { return _SelectionMode; } + set + { + if (value != _SelectionMode) + { + eSelectionMode oldValue = _SelectionMode; + _SelectionMode = value; + OnSelectionModeChanged(oldValue, value); + } + } + } + /// + /// Called when SelectionMode property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSelectionModeChanged(eSelectionMode oldValue, eSelectionMode newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SelectionMode")); + } + + protected override void OnItemAdded(BaseItem item, EventArgs e) + { + ListBoxItem listItem = item as ListBoxItem; + bool selectedItemsChanged = false; + if (listItem != null) + { + if (listItem.IsSelected) + { + if (_SelectionMode == eSelectionMode.One) + { + if (_SelectedItems.Count > 0) + { + ListBoxItem[] selItems = new ListBoxItem[_SelectedItems.Count]; + _SelectedItems.CopyTo(selItems); + foreach (ListBoxItem selItem in selItems) + { + selItem.IsSelected = false; + } + } + _SelectedItems.Add(listItem); + UpdateSelectedIndex(); + selectedItemsChanged = true; + } + else if (_SelectionMode == eSelectionMode.MultiSimple) + { + _SelectedItems.Add(listItem); + UpdateSelectedIndex(); + selectedItemsChanged = true; + } + } + } + + if (selectedItemsChanged) + RaiseSelectionChangedEvents(); + + base.OnItemAdded(item, e); + } + + private void RaiseSelectionChangedEvents() + { + OnSelectedIndexChanged(EventArgs.Empty); + } + + private void UpdateSelectedIndex() + { + if (_SelectedItems.Count == 0) + _SelectedIndex = -1; + else + { + ListBoxItem item = _SelectedItems[_SelectedItems.Count - 1]; + _SelectedIndex = m_ItemContainer.SubItems.IndexOf(item); + } + } + protected override void OnItemRemoved(BaseItem item, ItemRemovedEventArgs e) + { + ListBoxItem listItem = item as ListBoxItem; + bool selectedItemsChanged = false; + if (listItem != null) + { + if (listItem.IsSelected) + { + if (_SelectedItems.Contains(listItem)) + { + _SelectedItems.Remove(listItem); + UpdateSelectedIndex(); + selectedItemsChanged = true; + } + } + } + + if (selectedItemsChanged) + RaiseSelectionChangedEvents(); + + base.OnItemRemoved(item, e); + } + + private bool _HandlingSelectedChanged = false; + internal void OnListBoxItemSelectedChanged(ListBoxItem item, eEventSource source) + { + if (_HandlingSelectedChanged) return; + _HandlingSelectedChanged = true; + + bool selectedItemsChanged = false; + if (item.IsSelected) + { + if (_SelectionMode == eSelectionMode.One && _SelectedItems.Count > 0) + { + ClearSelectedItems(source); + } + if (!_SelectedItems.Contains(item)) + { + _SelectedItems.Add(item); + selectedItemsChanged = true; + UpdateSelectedIndex(); + } + } + else + { + if (_SelectedItems.Contains(item)) + { + _SelectedItems.Remove(item); + selectedItemsChanged = true; + UpdateSelectedIndex(); + } + } + + if (selectedItemsChanged) + { + this.Invalidate(); + RaiseSelectionChangedEvents(); + } + + _HandlingSelectedChanged = false; + } + + internal void ClearSelectedItems(eEventSource source) + { + if (_SelectedItems.Count == 0) return; + ListBoxItem[] selItems = new ListBoxItem[_SelectedItems.Count]; + _SelectedItems.CopyTo(selItems); + foreach (ListBoxItem selItem in selItems) + { + selItem.SetIsSelected(false, source); + } + _SelectedItems.Clear(); + } + + /// + /// Selects or clears the selection for the specified item in a ListBoxAdv. Use this property to set the selection of items in a multiple-selection ListBoxAdv. To select an item in a single-selection ListBox, use the SelectedIndex property. + /// + /// The zero-based index of the item in a ListBox to select or clear the selection for. You can pass -1 to clear the selection. + /// true to select the specified item; otherwise, false. + public void SetSelected(int index, bool value) + { + SetSelected(index, value, eEventSource.Code); + } + + /// + /// Selects or clears the selection for the specified item in a ListBoxAdv. Use this property to set the selection of items in a multiple-selection ListBoxAdv. To select an item in a single-selection ListBox, use the SelectedIndex property. + /// + /// The zero-based index of the item in a ListBox to select or clear the selection for. You can pass -1 to clear the selection. + /// true to select the specified item; otherwise, false. + /// Indicates the source of the change. + public void SetSelected(int index, bool value, eEventSource source) + { + if (index == -1) + { + ClearSelectedItems(source); + return; + } + ListBoxItem item = m_ItemContainer.SubItems[index] as ListBoxItem; + if (item != null) + item.SetIsSelected(value, source); + } + + /// + /// Gets or sets the zero-based index of the currently selected item in a ListBoxAdv. Negative one (-1) is returned if no item is selected. + /// + [Bindable(true), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override int SelectedIndex + { + get + { + return _SelectedIndex; + } + set + { + if (_SelectedItems.Count > 0) ClearSelectedItems(eEventSource.Code); + SetSelected(value, true); + } + } + + /// + /// Selects next visible list box item. + /// + public void SelectNextItem() + { + int startIndex = this.SelectedIndex == -1 ? 0 : this.SelectedIndex + 1; + if (startIndex >= m_ItemContainer.SubItems.Count) + return; + for (int i = startIndex; i < m_ItemContainer.SubItems.Count; i++) + { + ListBoxItem item = m_ItemContainer.SubItems[i] as ListBoxItem; + if (item == null) continue; + if (item.Visible) + { + item.IsSelected = true; + EnsureVisible(item); + break; + } + } + } + + /// + /// Selects previous visible list box item. + /// + public void SelectPreviousItem() + { + int startIndex = this.SelectedIndex == -1 ? 0 : this.SelectedIndex - 1; + if (startIndex < 0) + return; + for (int i = startIndex; i >= 0; i--) + { + ListBoxItem item = m_ItemContainer.SubItems[i] as ListBoxItem; + if (item == null) continue; + if (item.Visible) + { + item.IsSelected = true; + EnsureVisible(item); + break; + } + } + } + + /// + /// Gets a collection that contains the zero-based indexes of all currently selected items in the ListBoxAdv. Do not modify items in this collection. To select or deselect list items while in multi-selection mode use SetSelected method. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public List SelectedIndices + { + get + { + return GetSelectedIndices(); + } + } + + private List GetSelectedIndices() + { + List list = new List(); + if (_SelectedItems.Count == 0) return list; + foreach (ListBoxItem item in _SelectedItems) + { + list.Add(m_ItemContainer.SubItems.IndexOf(item)); + } + + return list; + } + + /// + /// Gets a collection containing the currently selected items in the ListBoxAdv. Do not modify items in this collection. To select or deselect list items while in multi-selection mode use SetSelected method. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CustomCollection SelectedItems + { + get + { + return _SelectedItems; + } + } + + private CustomCollection _SelectedItems; + /// + /// Gets or sets the selected item. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object SelectedItem + { + get + { + if (_SelectedItems.Count == 0) return null; + ListBoxItem item = _SelectedItems[0]; + if (item.Tag is ItemBindingData) + return ((ItemBindingData)item.Tag).DataItem; + return item; + } + set + { + if (value == null) + { + foreach (ListBoxItem item in _SelectedItems) + { + item.SetIsSelected(false, eEventSource.Code); + } + } + else + { + ListBoxItem item = FindListBoxItem(value); + if (item == null) + throw new InvalidOperationException("SelectedValue set cannot be found in Items collection"); + item.SetIsSelected(true, eEventSource.Code); + } + } + } + + /// + /// Gets ListBoxItem which represents an object value from Items collection when Items collection contains non ListBoxItem objects. + /// + /// Value to get ListBoxItem for. + /// + public ListBoxItem FindListBoxItem(object value) + { + if (value is ListBoxItem) + return (ListBoxItem)value; + foreach (BaseItem visual in m_ItemContainer.SubItems) + { + ListBoxItem item = visual as ListBoxItem; + if (item != null && item.Tag is ItemBindingData && ((ItemBindingData)item.Tag).DataItem == value) + return item; + } + return null; + } + + private ListBoxItem _FocusItem = null; + protected override void OnKeyboardItemSelected(BaseItem item) + { + base.OnKeyboardItemSelected(item); + if (item is ListBoxItem) + { + ListBoxItem listItem = (ListBoxItem)item; + if (_SelectionMode == eSelectionMode.One) + { + listItem.SetIsSelected(true, eEventSource.Keyboard); + } + else + { + if (_SelectionMode == eSelectionMode.MultiExtended) + { + if ((Control.ModifierKeys & Keys.Shift) == Keys.None) + { + ClearSelectedItems(eEventSource.Keyboard); + listItem.SetIsSelected(true, eEventSource.Keyboard); + } + else + { + if (listItem.IsSelected && _FocusItem != null && _FocusItem.IsSelected) + { + _FocusItem.SetIsSelected(false, eEventSource.Keyboard); + } + else + { + listItem.SetIsSelected(true, eEventSource.Keyboard); + } + } + } + if (_FocusItem != null) _FocusItem.OnLostFocus(); + _FocusItem = listItem; + _FocusItem.OnGotFocus(); + } + } + else + { + if (_FocusItem != null) _FocusItem.OnLostFocus(); + _FocusItem = null; + } + } + + protected override void OnLostFocus(EventArgs e) + { + if (_FocusItem != null) _FocusItem.OnLostFocus(); + _FocusItem = null; + base.OnLostFocus(e); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if (e.KeyCode == Keys.Space && _SelectionMode == eSelectionMode.MultiSimple && _FocusItem != null) + { + _FocusItem.SetIsSelected(!_FocusItem.IsSelected, eEventSource.Keyboard); + } + base.OnKeyDown(e); + } + + protected override bool ProcessDialogKey(Keys keyData) + { + if ((keyData & (Keys.Control | Keys.Alt)) == Keys.None) + { + Keys keys = keyData & Keys.KeyCode; + if (keys == Keys.Left || keys == Keys.Right || keys == Keys.Up || keys == Keys.Down) + { + ExKeyDown(new KeyEventArgs(keys)); + return true; + } + } + return base.ProcessDialogKey(keyData); + } + + private string _DisplayMember = ""; + /// + /// Indicates property name which will provide the value to display for this list box when data-binding is used and DataSource is set. + /// + [DefaultValue(""), Category("Data"), Description("Indicates property name which will provide the value to display for this list box when data-binding is used and DataSource is set.")] + [TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] + [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + public string DisplayMember + { + get { return _DisplayMember; } + set + { + if (value == null) value = ""; + if (value != _DisplayMember) + { + string oldValue = _DisplayMember; + _DisplayMember = value; + OnDisplayMemberChanged(oldValue, value); + } + } + } + /// + /// Called when DisplayMember property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDisplayMemberChanged(string oldValue, string newValue) + { + EnsureBindingGenerator(); + ItemVisualGenerator generator = ItemGenerator; + + foreach (BindingDef item in generator.Bindings) + { + if (item.PropertyName == "Text") + { + generator.Bindings.Remove(item); + break; + } + } + + if (!string.IsNullOrEmpty(newValue)) + { + BindingDef bindDef = new BindingDef("Text", newValue); + generator.Bindings.Add(bindDef); + } + generator.RefreshItems(); + //OnPropertyChanged(new PropertyChangedEventArgs("DisplayMember")); + } + + /// + /// Indicates property name which will provide the value for CheckState of the list box item when data-binding is used and DataSource is set. + /// + [DefaultValue(""), Category("Data"), Description("Indicates property name which will provide the value for CheckState of the list box item when data-binding is used and DataSource is set.")] + [TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] + [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + public string CheckStateMember + { + get { return _CheckStateMember; } + set + { + if (value == null) value = ""; + if (value != _CheckStateMember) + { + string oldValue = _CheckStateMember; + _CheckStateMember = value; + OnCheckStateMemberChanged(oldValue, value); + } + } + } + /// + /// Called when CheckStateMember property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCheckStateMemberChanged(string oldValue, string newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("CheckStateMember")); + EnsureBindingGenerator(); + ItemVisualGenerator generator = ItemGenerator; + + foreach (BindingDef item in generator.Bindings) + { + if (item.PropertyName == "CheckState") + { + item.Format -= CheckStateBindingFormat; + generator.Bindings.Remove(item); + break; + } + } + + if (!string.IsNullOrEmpty(newValue)) + { + BindingDef bindDef = new BindingDef("CheckState", newValue); + bindDef.FormattingEnabled = true; + bindDef.Format += CheckStateBindingFormat; + generator.Bindings.Add(bindDef); + } + generator.RefreshItems(); + } + + /// + /// Occurs when using data-binding with CheckStateMember specified and it allows you to convert a property value to CheckState. + /// + [Description("Occurs when using data-binding with CheckStateMember specified and it allows you to convert a property value to CheckState.")] + public event CheckStateConvertEventHandler CheckStateConvert; + /// + /// Raises CheckStateConvert event. + /// + /// Provides event arguments. + protected virtual void OnCheckStateConvert(CheckStateConvertEventArgs e) + { + CheckStateConvertEventHandler handler = CheckStateConvert; + if (handler != null) + handler(this, e); + } + + private void CheckStateBindingFormat(object sender, DataConvertEventArgs e) + { + if (CheckStateConvert != null) + { + CheckStateConvertEventArgs cea = new CheckStateConvertEventArgs(e.Value); + OnCheckStateConvert(cea); + if (cea.CheckState != null) + { + e.Value = cea.CheckState.Value; + return; + } + } + e.Value = GetCheckState(e.Value); + } + + private CheckState GetCheckState(object value) + { + if (value is System.Data.SqlTypes.SqlBoolean) + { + System.Data.SqlTypes.SqlBoolean sqlBool = (System.Data.SqlTypes.SqlBoolean)value; + if (sqlBool.IsTrue) + return CheckState.Checked; + else if (sqlBool.IsNull) + return CheckState.Indeterminate; + else + return CheckState.Unchecked; + } + else if (value is int?) + { + if (value == null) return CheckState.Indeterminate; + if (((int?)value).Value == 0) + return CheckState.Unchecked; + return CheckState.Checked; + } + else if (value is int) + { + if ((int)value == -1) + return CheckState.Indeterminate; + return ((int)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is long) + { + if ((long)value == -1) + return CheckState.Indeterminate; + return ((long)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is short) + { + if ((short)value == -1) + return CheckState.Indeterminate; + return ((short)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is float) + { + if ((float)value == -1) + return CheckState.Indeterminate; + return ((float)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is double) + { + if ((double)value == -1) + return CheckState.Indeterminate; + return ((double)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is byte) + { + return ((byte)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is uint) + { + return ((uint)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is ulong) + { + return ((ulong)value) == 0 ? CheckState.Unchecked : CheckState.Checked; + } + else if (value is bool) + { + return ((bool)value) == false ? CheckState.Unchecked : CheckState.Checked; + } + + return CheckState.Indeterminate; + } + + private bool IsNull(object value) + { + return value == null || + value == DBNull.Value; + } + + /// + /// Returns the enumerator with selected values if any + /// + [Browsable(false)] + public IEnumerable SelectedValues + { + get + { + List selectedIndexes = SelectedIndices; + foreach (int index in selectedIndexes) + { + yield return GetValueByIndex(index); + } + } + } + + /// + /// Gets or sets the value of the member property specified by the ValueMember property. If ValueMember specifies property that cannot be found on selected object this property returns null. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object SelectedValue + { + get + { + if (this.DataSource == null) + return null; + + int selIndex = this.SelectedIndex; + return GetValueByIndex(selIndex); + } + set + { + if (string.IsNullOrEmpty(_ValueMember)) + throw new InvalidOperationException("ValueMember property not set"); + int index = FindValueMemberIndexOf(value); + if (index < 0) + throw new InvalidPropertyValueException("value not found."); + + this.SelectedItem = m_ItemContainer.SubItems[index]; + } + } + + private object GetValueByIndex(int selIndex) + { + if (selIndex < 0) return null; + ItemVisualGenerator generator = ItemGenerator; + if (generator.DataManager == null || generator.DataManager.List == null) + return null; + + object item = generator.DataManager.List[selIndex]; + + return GetPropertyValue(item, _ValueMember); + } + private int FindValueMemberIndexOf(object value) + { + ItemVisualGenerator generator = ItemGenerator; + if (generator.DataManager == null || generator.DataManager.List == null) + return -1; + IList list = generator.DataManager.List; + for (int i = 0; i < list.Count; i++) + { + object itemValue = GetPropertyValue(list[i], _ValueMember); + if (itemValue.Equals(value)) + return i; + } + return -1; + } + private string _ValueMember = ""; + /// + /// Indicates property name which will return the value for the selected item when SelectedValue property is accessed. + /// + [Description("Indicates property name which will return the value for the selected item when SelectedValue property is accessed.")] + [DefaultValue("")] + [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + [Category("Data")] + public string ValueMember + { + get { return _ValueMember; } + set + { + if (value == null) value = ""; + if (value != _ValueMember) + { + string oldValue = _ValueMember; + _ValueMember = value; + OnValueMemberChanged(oldValue, value); + } + } + } + /// + /// Called when ValueMember property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnValueMemberChanged(string oldValue, string newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("ValueMember")); + } + + Dictionary _DescriptorsCache = new Dictionary(); + /// + /// Clears internal property descriptors cache when data-binding is used. In most cases it is not needed that you call this method. Do so only if instructed by DevComponents support. + /// + public void ClearDescriptorsCache() + { + _DescriptorsCache.Clear(); + } + protected object GetPropertyValue(object item, string fieldName) + { + if ((item != null) && (fieldName.Length > 0)) + { + try + { + PropertyDescriptor descriptor = null; + string key = item.GetType().ToString() + ":" + fieldName; + if (!_DescriptorsCache.TryGetValue(key, out descriptor)) + { + ItemVisualGenerator generator = ItemGenerator; + if (generator.DataManager != null) + { + descriptor = generator.DataManager.GetItemProperties().Find(fieldName, true); + } + else + { + descriptor = TypeDescriptor.GetProperties(item).Find(fieldName, true); + } + if (descriptor != null) + _DescriptorsCache.Add(key, descriptor); + } + if (descriptor != null) + { + item = descriptor.GetValue(item); + } + } + catch + { + } + } + return item; + } + + /// + /// Finds the first item in the ListBox that starts with the specified string. The search starts at a specific starting index. + /// + /// The text to search for. + /// The zero-based index of the first item found; returns ListBox.NoMatches if no match is found. + public int FindString(string s) + { + return FindString(s, 0); + } + + /// + /// Finds the first item in the ListBox that starts with the specified string. The search starts at a specific starting index. + /// + /// The text to search for. + /// The zero-based index of the item before the first item to be searched. Set to negative one (-1) to search from the beginning of the control. + /// The zero-based index of the first item found; returns ListBox.NoMatches if no match is found. + public int FindString(string s, int startIndex) + { + if (startIndex < 0) + startIndex = 0; + + for (int i = startIndex; i < m_ItemContainer.SubItems.Count; i++) + { + if (m_ItemContainer.SubItems[i].Text.StartsWith(s)) + return i; + } + + return ListBox.NoMatches; + } + + /// + /// Finds the first item in the ListBox that exactly matches the specified string. The search starts at a specific starting index. + /// + /// The text to search for. + /// The zero-based index of the first item found; returns ListBox.NoMatches if no match is found. + public int FindStringExact(string s) + { + return FindStringExact(s, 0); + } + + /// + /// Finds the first item in the ListBox that exactly matches the specified string. The search starts at a specific starting index. + /// + /// The text to search for. + /// The zero-based index of the item before the first item to be searched. Set to negative one (-1) to search from the beginning of the control. + /// The zero-based index of the first item found; returns ListBox.NoMatches if no match is found. + public int FindStringExact(string s, int startIndex) + { + if (startIndex < 0) + startIndex = 0; + + for (int i = startIndex; i < m_ItemContainer.SubItems.Count; i++) + { + if (m_ItemContainer.SubItems[i].Text == s) + return i; + } + + return ListBox.NoMatches; + } + + internal void ListItemCheckStateChanged(ListBoxAdvItemCheckEventArgs e) + { + OnItemCheck(e); + } + + /// + /// Occurs when CheckState of an ListBoxItem changes and it allows you to cancel the change. + /// + [Description("Occurs when CheckState of an ListBoxItem changes and it allows you to cancel the change.")] + public event ListBoxAdvItemCheckEventHandler ItemCheck; + /// + /// Raises ItemCheck event. + /// + /// Provides event arguments. + protected virtual void OnItemCheck(ListBoxAdvItemCheckEventArgs e) + { + ListBoxAdvItemCheckEventHandler handler = ItemCheck; + if (handler != null) + handler(this, e); + } + + /// + /// Gets collection of checked items in the list. Modifying this collection does not have any effect on actual checked items. Use SetItemCheckState to set checked state of an item or access ListBoxItem directly and set its CheckState property. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public List CheckedItems + { + get + { + List items = new List(); + foreach (BaseItem item in m_ItemContainer.SubItems) + { + ListBoxItem listItem = item as ListBoxItem; + if (listItem == null) continue; + if (listItem.CheckState != CheckState.Unchecked) + items.Add(listItem); + } + return items; + } + } + + /// + /// Sets the check state of the item at the specified index. + /// + /// The index of the item to set the state for. + /// One of the CheckState values. + public void SetItemCheckState(int index, CheckState value) + { + ListBoxItem item = m_ItemContainer.SubItems[index] as ListBoxItem; + item.CheckState = value; + } + + private bool _UseMnemonic = false; + /// + /// Gets or sets a value indicating whether the items interprets an ampersand character (&) in the control's Text property to be an access key prefix character. + /// + [Browsable(true), DefaultValue(false), Category("Appearance"), Description("Indicates whether the items interprets an ampersand character (&) in the control's Text property to be an access key prefix character.")] + public bool UseMnemonic + { + get { return _UseMnemonic; } + set + { + _UseMnemonic = value; + m_ItemContainer.NeedRecalcSize = true; + } + } + #endregion + } + + + + /// + /// Defines selection modes for list control. + /// + public enum eSelectionMode + { + /// + /// Items cannot be selected. + /// + None, + /// + /// Only one item at the time can be selected. + /// + One, + /// + /// Multiple items can be selected. A mouse click or pressing the SPACEBAR selects or deselects an item in the list. + /// + MultiSimple, + /// + /// Multiple items can be selected. Pressing SHIFT and clicking the mouse or pressing SHIFT and one of the arrow keys (UP ARROW, DOWN ARROW, LEFT ARROW, and RIGHT ARROW) extends the selection from the previously selected item to the current item. Pressing CTRL and clicking the mouse selects or deselects an item in the list. + /// + MultiExtended + } + + public delegate void CheckStateConvertEventHandler(object sender, CheckStateConvertEventArgs ea); +} diff --git a/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxAdvItemCheckEventArgs.cs b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxAdvItemCheckEventArgs.cs new file mode 100644 index 00000000..83d0ef75 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxAdvItemCheckEventArgs.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar +{ + public class ListBoxAdvItemCheckEventArgs : EventArgs + { + /// + /// Indicates that CheckState change of the item should be canceled. + /// + public bool Cancel = false; + /// + /// Specifies the ListBoxItem that was changing. + /// + public readonly ListBoxItem Item; + /// + /// When data-bound provides the object which was used to generate an ListBoxItem. + /// + public readonly object Value; + + /// + /// Initializes a new instance of the ListBoxAdvItemCheckEventArgs class. + /// + /// + /// + public ListBoxAdvItemCheckEventArgs(ListBoxItem item, object value) + { + Item = item; + Value = value; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxAdvItemCheckEventHandler.cs b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxAdvItemCheckEventHandler.cs new file mode 100644 index 00000000..eae885b2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxAdvItemCheckEventHandler.cs @@ -0,0 +1,8 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar +{ + public delegate void ListBoxAdvItemCheckEventHandler(object sender, ListBoxAdvItemCheckEventArgs e); +} diff --git a/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxItem.cs b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxItem.cs new file mode 100644 index 00000000..6705a4a7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxItem.cs @@ -0,0 +1,727 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the ListBoxAdv item for internal use. Not for public usage. + /// + public class ListBoxItem : BaseItem + { + #region Constructor + + #endregion + + #region Implementation + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + ListBoxItem copy = new ListBoxItem(); + this.CopyToItem(copy); + return copy; + } + + /// + /// Copies the ListBoxItem specific properties to new instance of the item. + /// + /// New ListBoxItem instance. + internal void InternalCopyToItem(ListBoxItem copy) + { + CopyToItem(copy); + } + + /// + /// Copies the ListBoxItem specific properties to new instance of the item. + /// + /// New item instance. + protected override void CopyToItem(BaseItem copy) + { + base.CopyToItem(copy); + + ListBoxItem item = copy as ListBoxItem; + item.IsSelected = _IsSelected; + item.Symbol = _Symbol; + item.SymbolSet = _SymbolSet; + item.SymbolColor = _SymbolColor; + item.SymbolSize = _SymbolSize; + } + + public override void Paint(ItemPaintArgs p) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + ListBoxItemRendererEventArgs e = new ListBoxItemRendererEventArgs(this, p.Graphics); + e.ItemPaintArgs = p; + renderer.DrawListBoxItem(e); + } + else + { + Rendering.ListBoxItemPainter painter = PainterFactory.CreateListBoxItemPainter(this); + if (painter != null) + { + ListBoxItemRendererEventArgs e = new ListBoxItemRendererEventArgs(this, p.Graphics); + e.ItemPaintArgs = p; + painter.Paint(e); + } + } + + if (this.DesignMode && this.Focused) + { + Rectangle r = m_Rect; + r.Inflate(-1, -1); + DesignTime.DrawDesignTimeSelection(p.Graphics, r, p.Colors.ItemDesignTimeBorder); + } + else if (this.Focused) + { + Rectangle r = m_Rect; + r.Inflate(-1, -1); + Color c = SystemColors.Control; + if (renderer is Rendering.Office2007Renderer) c = ((Rendering.Office2007Renderer)renderer).ColorTable.ListBoxItem.Default.TextColor; + using (Pen pen = new Pen(c, 1)) + { + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; + System.Drawing.Drawing2D.SmoothingMode sm = p.Graphics.SmoothingMode; + p.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None; + p.Graphics.DrawRectangle(pen, r); + p.Graphics.SmoothingMode = sm; + } + } + + this.DrawInsertMarker(p.Graphics); + + } + + private CheckState _CheckState = CheckState.Unchecked; + private bool _HotTracking; + private Size _CheckBoxSize = new Size(13, 13); + private const int DefaultPadding = 2; + private Padding _Padding = new Padding(DefaultPadding); + internal const int ImageTextSpacing = 4; + internal const int CheckBoxTextSpacing = 6; + public override void RecalcSize() + { + ListBoxAdv cont = this.ContainerControl as ListBoxAdv; + if (cont == null || cont.Disposing || cont.IsDisposed) return; + + bool checkBox = cont.CheckBoxesVisible; + int itemHeight = Dpi.Height(cont.ItemHeight); + Size size = Size.Empty; + + Graphics g = BarFunctions.CreateGraphics(cont); + if (g == null) return; + + try + { + if (!string.IsNullOrEmpty(_Symbol)) + { + _ActualSymbolSize = GetSymbolSize(g); + size = _ActualSymbolSize; + } + else if (_Image != null) + { + size = Dpi.ImageSize(_Image.Size); + } + if (!string.IsNullOrEmpty(this.Text)) + { + Size textSize = ButtonItemLayout.MeasureItemText(this, g, 0, cont.Font, eTextFormat.Default, cont.RightToLeft == RightToLeft.Yes); + size.Width += textSize.Width; + size.Height = Math.Max(size.Height, textSize.Height); + if (_Image != null || !string.IsNullOrEmpty(_Symbol)) + size.Width += Dpi.Width(ImageTextSpacing); + } + else if (string.IsNullOrEmpty(_Symbol) && _Image == null) + size = new System.Drawing.Size(Dpi.Width16, Dpi.Height16); + + size.Width += _Padding.Horizontal; + size.Height += _Padding.Vertical; + + base.RecalcSize(); + } + finally + { + g.Dispose(); + } + + if (checkBox) + { + size.Width += Dpi.Width(_CheckBoxSize.Width + CheckBoxTextSpacing); + size.Height = Math.Max(Dpi.Height(_CheckBoxSize.Height), size.Height); + } + + if (itemHeight > 0) size.Height = itemHeight; + + _CheckBoxBounds = Rectangle.Empty; + m_Rect.Size = size; + + base.RecalcSize(); + } + + private Rectangle _CheckBoxBounds = Rectangle.Empty; + internal Rectangle CheckBoxBounds + { + get + { + return _CheckBoxBounds; + } + set + { + _CheckBoxBounds = value; + } + } + + public override void InternalMouseEnter() + { + base.InternalMouseEnter(); + if (!this.DesignMode) + { + _MouseOver = true; + if (this.GetEnabled() && _HotTracking) + this.Refresh(); + } + } + + public override void InternalMouseLeave() + { + base.InternalMouseLeave(); + if (!this.DesignMode) + { + _MouseOver = false; + CheckBoxMouseState = eMouseState.None; + if (this.GetEnabled() && _HotTracking) + this.Refresh(); + } + } + + public override void InternalMouseMove(MouseEventArgs objArg) + { + if (_CheckBoxBounds.Contains(objArg.Location)) + CheckBoxMouseState = eMouseState.Hot; + else + CheckBoxMouseState = eMouseState.None; + base.InternalMouseMove(objArg); + } + + public override void InternalMouseDown(MouseEventArgs objArg) + { + if (objArg.Button == MouseButtons.Left && !_CheckBoxBounds.IsEmpty && _CheckBoxBounds.Contains(objArg.Location)) + CheckBoxMouseState = eMouseState.Down; + base.InternalMouseDown(objArg); + } + + public override void InternalMouseUp(MouseEventArgs objArg) + { + if (objArg.Button == MouseButtons.Left && !_CheckBoxBounds.IsEmpty && _CheckBoxBounds.Contains(objArg.Location)) + { + this.CheckState = this.CheckState == System.Windows.Forms.CheckState.Checked ? System.Windows.Forms.CheckState.Unchecked : System.Windows.Forms.CheckState.Checked; + CheckBoxMouseState = eMouseState.Hot; + } + else if (objArg.Button == MouseButtons.Left) + { + if (this.Bounds.Contains(objArg.Location)) + { + ListBoxAdv listBox = this.ContainerControl as ListBoxAdv; + if (listBox != null) + { + if (listBox.SelectionMode != eSelectionMode.None) + { + if (listBox.SelectionMode == eSelectionMode.MultiSimple) + this.SetIsSelected(!this.IsSelected, eEventSource.Mouse); + else if (listBox.SelectionMode == eSelectionMode.MultiExtended) + { + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + { + this.SetIsSelected(!this.IsSelected, eEventSource.Mouse); + } + else if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) + { + BaseItem itemContainer = listBox.GetBaseItemContainer(); + int index = itemContainer.SubItems.IndexOf(this); + int hiSel = -1, lowSel = -1; + for (int i = 0; i < listBox.SelectedItems.Count; i++) + { + int itemIndex = itemContainer.SubItems.IndexOf(listBox.SelectedItems[i]); + if (itemIndex > hiSel || hiSel < 0) hiSel = itemIndex; + if (itemIndex < lowSel || lowSel < 0) lowSel = itemIndex; + } + if (hiSel < 0 || lowSel < 0) + this.SetIsSelected(true, eEventSource.Mouse); + else + { + if (index < lowSel) + { + for (int i = lowSel; i >= index; i--) + { + ListBoxItem listItem = itemContainer.SubItems[i] as ListBoxItem; + if (listItem != null) listItem.SetIsSelected(true, eEventSource.Mouse); + } + } + else if (index > hiSel) + { + for (int i = hiSel; i <= index; i++) + { + ListBoxItem listItem = itemContainer.SubItems[i] as ListBoxItem; + if (listItem != null) listItem.SetIsSelected(true, eEventSource.Mouse); + } + } + } + } + else + { + listBox.ClearSelectedItems(eEventSource.Mouse); + this.SetIsSelected(true, eEventSource.Mouse); + } + } + else if(!this.IsSelected) + this.SetIsSelected(true, eEventSource.Mouse); + } + } + else + this.SetIsSelected(true, eEventSource.Mouse); + } + } + base.InternalMouseUp(objArg); + } + + private Size GetSymbolSize(Graphics g) + { + Size symbolSize = Size.Empty; + if (g == null || string.IsNullOrEmpty(_Symbol)) return symbolSize; + Font symFont = Symbols.GetFont(this.SymbolSize, this.SymbolSet); + symbolSize = TextDrawing.MeasureString(g, "\uF00A", symFont); // Need to do this to get consistent size for the symbol since they are not all the same width we pick widest + int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) * + symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style))); + symbolSize.Height -= descent; + return symbolSize; + } + private Size _ActualSymbolSize = Size.Empty; + internal Size ActualSymbolSize + { + get + { + return _ActualSymbolSize; + } + } + + private bool _MouseOver = false; + /// + /// Gets whether mouse is over the item. + /// + [Browsable(false)] + public bool IsMouseOver + { + get { return _MouseOver; } + internal set { _MouseOver = value; } + } + + internal Size CheckBoxSize + { + get + { + return _CheckBoxSize; + } + } + + private eMouseState _CheckBoxMouseState = eMouseState.None; + /// + /// Gets the mouse state of the check box part of item if visible. + /// + [Browsable(false)] + public eMouseState CheckBoxMouseState + { + get { return _CheckBoxMouseState; } + internal set + { + if (_CheckBoxMouseState != value) + { + _CheckBoxMouseState = value; + this.Refresh(); + } + } + } + + /// + /// Indicates check-box state if visible. + /// + [DefaultValue(CheckState.Unchecked), Category("Appearance"), Description("Indicates check-box state if visible.")] + public CheckState CheckState + { + get { return _CheckState; } + set + { + if (value != _CheckState) + { + CheckState oldValue = _CheckState; + _CheckState = value; + OnCheckStateChanged(oldValue, value); + } + } + } + /// + /// Called when CheckState property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCheckStateChanged(CheckState oldValue, CheckState newValue) + { + ListBoxAdv listBox = this.ContainerControl as ListBoxAdv; + if (listBox != null) + { + ListBoxAdvItemCheckEventArgs e = new ListBoxAdvItemCheckEventArgs(this, newValue); + listBox.ListItemCheckStateChanged(e); + if (e.Cancel) + _CheckState = oldValue; + } + //OnPropertyChanged(new PropertyChangedEventArgs("CheckState")); + this.Refresh(); + } + + // Fields... + private Image _Image; + private bool _IsSelected = false; + /// + /// Gets or sets whether item is selected. + /// + [Browsable(false), DefaultValue(false)] + public bool IsSelected + { + get { return _IsSelected; } + set + { + if (value != _IsSelected) + { + SetIsSelected(value, eEventSource.Code); + } + } + } + /// + /// Called when IsSelected property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnIsSelectedChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("IsSelected")); + this.Refresh(); + } + /// + /// Sets selected state of the item including the source of the action that caused the change. + /// + /// + /// + public void SetIsSelected(bool isSelected, eEventSource source) + { + bool oldValue = _IsSelected; + ListBoxAdv listBox = this.ContainerControl as ListBoxAdv; + _IsSelected = isSelected; + if (listBox != null) + { + listBox.OnListBoxItemSelectedChanged(this, source); + } + OnIsSelectedChanged(oldValue, isSelected); + } + /// + /// Indicates whether item changes its background colors when mouse is over the item. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether item changes its background colors when mouse is over the item")] + public bool HotTracking + { + get { return _HotTracking; } + set + { + if (value != _HotTracking) + { + bool oldValue = _HotTracking; + _HotTracking = value; + OnHotTrackingChanged(oldValue, value); + } + } + } + /// + /// Called when HotTracking property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnHotTrackingChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("HotTracking")); + } + + /// + /// Specifies image displayed on the item. + /// + [DefaultValue(null), Category("Appearance"), Description("Specifies image displayed on the item.")] + public Image Image + { + get { return _Image; } + set + { + if (value != _Image) + { + Image oldValue = _Image; + _Image = value; + OnImageChanged(oldValue, value); + } + } + } + /// + /// Called when Image property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnImageChanged(Image oldValue, Image newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Image")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + private Color _SymbolColor = Color.Empty; + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return _SymbolColor; } + set { _SymbolColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return !_SymbolColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + this.SymbolColor = Color.Empty; + } + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get { return _SymbolRealized; } + } + private string _Symbol = "", _SymbolRealized = ""; + /// + /// Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return _Symbol; } + set + { + if (value != _Symbol) + { + string oldValue = _Symbol; + _Symbol = value; + OnSymbolChanged(oldValue, value); + } + } + } + /// + /// Called when Symbol property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolChanged(string oldValue, string newValue) + { + if (string.IsNullOrEmpty(newValue)) + _SymbolRealized = ""; + else + _SymbolRealized = Symbols.GetSymbol(newValue); + //OnPropertyChanged(new PropertyChangedEventArgs("Symbol")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return _SymbolSet; } + set + { + if (_SymbolSet != value) + { + eSymbolSet oldValue = _SymbolSet; + _SymbolSet = value; + OnSymbolSetChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSet property value changes. + /// + /// Indciates old value + /// Indicates new value + protected virtual void OnSymbolSetChanged(eSymbolSet oldValue, eSymbolSet newValue) + { + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + private float _SymbolSize = 13f; + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(13f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return _SymbolSize; } + set + { + if (value != _SymbolSize) + { + float oldValue = _SymbolSize; + _SymbolSize = value; + OnSymbolSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolSizeChanged(float oldValue, float newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SymbolSize")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + private Color[] _BackColors = null; + /// + /// Indicates the array of colors that when set are used to draw the background of the item. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the background of the item."), TypeConverter(typeof(ArrayConverter))] + public Color[] BackColors + { + get + { + return _BackColors; + } + set + { + if (_BackColors != value) + { + _BackColors = value; + //OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + this.Refresh(); + } + } + } + private Color _TextColor = Color.Empty; + /// + /// Gets or sets the color of the text. + /// + [Category("Columns"), Description("Indicates color of text.")] + public Color TextColor + { + get { return _TextColor; } + set { _TextColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return !_TextColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + this.TextColor = Color.Empty; + } + /// + /// Gets or sets the text associated with this item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The text contained in the item."), System.ComponentModel.Localizable(true), System.ComponentModel.DefaultValue("")] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + private eButtonTextAlignment _TextAlignment = eButtonTextAlignment.Left; + /// + /// Gets or sets the text alignment. Default value is left. + /// + [Browsable(true), DefaultValue(eButtonTextAlignment.Left), Category("Appearance"), Description("Indicates text alignment.")] + public eButtonTextAlignment TextAlignment + { + get { return _TextAlignment; } + set + { + _TextAlignment = value; + this.Refresh(); + } + } + #endregion + + #region Markup Implementation + /// + /// Gets whether item supports text markup. Default is false. + /// + protected override bool IsMarkupSupported + { + get { return _EnableMarkup; } + } + + private bool _EnableMarkup = true; + /// + /// Gets or sets whether text-markup support is enabled for items Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the item instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for items Text property.")] + public bool EnableMarkup + { + get { return _EnableMarkup; } + set + { + if (_EnableMarkup != value) + { + _EnableMarkup = value; + NeedRecalcSize = true; + OnTextChanged(); + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxItemPainter.cs b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxItemPainter.cs new file mode 100644 index 00000000..6f90767d --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxItemPainter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class ListBoxItemPainter : IOffice2007Painter + { + /// + /// Paints ListBoxItem. + /// + /// Provides arguments for the operation. + public virtual void Paint(ListBoxItemRendererEventArgs e) { } + + #region IOffice2007Painter Members + private Office2007ColorTable _ColorTable = null; //new Office2007ColorTable(); + public Office2007ColorTable ColorTable + { + get + { + return _ColorTable; + } + set + { + _ColorTable = value; + } + } + + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxItemRendererEventArgs.cs b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxItemRendererEventArgs.cs new file mode 100644 index 00000000..5725933a --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/ListBoxItemRendererEventArgs.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar +{ + /// + /// Provides data for the Slider item rendering events. + /// + public class ListBoxItemRendererEventArgs : EventArgs + { + /// + /// Gets or sets the reference to the item being rendered. + /// + public ListBoxItem Item = null; + + /// + /// Gets or sets the reference to graphics object. + /// + public Graphics Graphics = null; + + internal ItemPaintArgs ItemPaintArgs = null; + + /// + /// Creates new instance of the object and initializes it with default values. + /// + /// Reference to the ListBoxItem being rendered. + /// Reference to the graphics object. + public ListBoxItemRendererEventArgs(ListBoxItem item, Graphics g) + { + this.Item = item; + this.Graphics = g; + } + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/OfficeListBoxItemColorTable.cs b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/OfficeListBoxItemColorTable.cs new file mode 100644 index 00000000..0c2c509c --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/OfficeListBoxItemColorTable.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + /// + /// Defines color table for ListBoxItem. + /// + public class OfficeListBoxItemColorTable + { + /// + /// Specifies default state color table. + /// + public OfficeListBoxItemStateColorTable Default = new OfficeListBoxItemStateColorTable(); + /// + /// Specifies mouse over state color table. + /// + public OfficeListBoxItemStateColorTable MouseOver = new OfficeListBoxItemStateColorTable(); + /// + /// Specifies selected state color table. + /// + public OfficeListBoxItemStateColorTable Selected = new OfficeListBoxItemStateColorTable(); + } + /// + /// Defines single state color table for ListBoxItem. + /// + public class OfficeListBoxItemStateColorTable + { + /// + /// Initializes a new instance of the OfficeListBoxItemStateColorTable class. + /// + public OfficeListBoxItemStateColorTable() + { + } + /// + /// Initializes a new instance of the OfficeListBoxItemStateColorTable class. + /// + /// + /// + /// + /// + public OfficeListBoxItemStateColorTable(Color textColor, Color[] backColors, int backColorsGradientAngle, float[] backColorsPositions) + { + TextColor = textColor; + BackColors = backColors; + BackColorsGradientAngle = backColorsGradientAngle; + BackColorsPositions = backColorsPositions; + } + /// + /// Initializes a new instance of the OfficeListBoxItemStateColorTable class. + /// + /// + public OfficeListBoxItemStateColorTable(Color textColor) + { + TextColor = textColor; + } + /// + /// Indicates item text color. + /// + public Color TextColor = Color.Black; + /// + /// Gets or sets the background colors for the item. + /// + public Color[] BackColors = new Color[0]; + /// + /// Gets or sets the back colors gradient angle if there is more than one color in BackColors array. + /// + public int BackColorsGradientAngle = 90; + /// + /// Gets or sets the gradient colors positions if there is more than one color in BackColors array. + /// + public float[] BackColorsPositions = new float[0]; + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/OfficeListBoxItemPainter.cs b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/OfficeListBoxItemPainter.cs new file mode 100644 index 00000000..51d37b57 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListBoxAdv/OfficeListBoxItemPainter.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using DevComponents.Editors.DateTimeAdv; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class OfficeListBoxItemPainter : ListBoxItemPainter + { + #region Implementation + /// + /// Paints StepItem. + /// + /// Provides arguments for the operation. + public override void Paint(ListBoxItemRendererEventArgs e) + { + Graphics g = e.ItemPaintArgs.Graphics; + ListBoxItem item = e.Item; + ListBoxAdv listBox = e.ItemPaintArgs.ContainerControl as ListBoxAdv; + bool checkBoxes = false; + bool useMnemonic = true; + if (listBox != null) + { + checkBoxes = listBox.CheckBoxesVisible; + useMnemonic = listBox.UseMnemonic; + } + OfficeListBoxItemColorTable table = ColorTable.ListBoxItem; + OfficeListBoxItemStateColorTable ct = item.IsSelected ? table.Selected : table.Default; + if (item.HotTracking && item.IsMouseOver) + ct = table.MouseOver; + + Rectangle r = item.Bounds; + + if (checkBoxes) + { + Office2007CheckBoxStateColorTable cbt = GetCheckBoxStateColorTable(item.CheckBoxMouseState); + Size checkBoxSize = Dpi.Size(item.CheckBoxSize); + Rectangle cbr = new Rectangle(r.X + 2, r.Y + (r.Height - checkBoxSize.Height) / 2, checkBoxSize.Width, checkBoxSize.Height); + _CheckBoxPainter.PaintCheckBox(g, cbr, cbt, item.CheckState); + int checkBoxTextSpacing = Dpi.Width(ListBoxItem.CheckBoxTextSpacing); + r.X += checkBoxSize.Width + checkBoxTextSpacing - 1; + r.Width -= checkBoxSize.Width + checkBoxTextSpacing - 1; + item.CheckBoxBounds = cbr; + } + + if (ct.BackColors != null && ct.BackColors.Length > 0 || item.BackColors != null && item.BackColors.Length > 0) + { + using (Brush brush = DisplayHelp.CreateBrush(r, (item.BackColors != null && item.BackColors.Length > 0) ? item.BackColors : ct.BackColors, ct.BackColorsGradientAngle, ct.BackColorsPositions)) + { + g.FillRectangle(brush, r); + } + } + + Color textColor = ct.TextColor; + + if (!string.IsNullOrEmpty(item.SymbolRealized)) + { + Color symbolColor = item.SymbolColor; + if (symbolColor.IsEmpty) symbolColor = textColor; + TextDrawing.DrawStringLegacy(g, item.SymbolRealized, Symbols.GetFont(item.SymbolSize, item.SymbolSet), + symbolColor, new Rectangle(r.X, r.Y + r.Height / 2, 0, 0), eTextFormat.Default | eTextFormat.VerticalCenter); + int imageSize = item.ActualSymbolSize.Width + Dpi.Width(ListBoxItem.ImageTextSpacing); + r.Width -= imageSize; + r.X += imageSize; + } + else if (item.Image != null) + { + Size imgSize = Dpi.ImageSize(item.Image.Size); + g.DrawImage(item.Image, new Rectangle(r.X, r.Y + (r.Height - imgSize.Height) / 2, imgSize.Width, imgSize.Height)); + int imageSize = imgSize.Width + Dpi.Width(ListBoxItem.ImageTextSpacing); + r.Width -= imageSize; + r.X += imageSize; + } + + if (!string.IsNullOrEmpty(item.Text)) + { + if (checkBoxes) { r.X += 1; r.Width -= 1; } + if (!item.TextColor.IsEmpty) textColor = item.TextColor; + Font font = e.ItemPaintArgs.Font; + if (item.TextMarkupBody == null) + { + eTextFormat textFormat = eTextFormat.Default | eTextFormat.VerticalCenter; + if (item.TextAlignment == eButtonTextAlignment.Center) + { + textFormat |= eTextFormat.HorizontalCenter; + } + else if (item.TextAlignment == eButtonTextAlignment.Right) + { + textFormat |= eTextFormat.Right; + } + if (!useMnemonic) + textFormat |= eTextFormat.NoPrefix; + TextDrawing.DrawString(g, item.Text, font, textColor, r, textFormat); + } + else + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, textColor, e.ItemPaintArgs.RightToLeft); + d.HotKeyPrefixVisible = false; + d.ContextObject = item; + Rectangle mr = new Rectangle(r.X, r.Y + (r.Height - item.TextMarkupBody.Bounds.Height) / 2, item.TextMarkupBody.Bounds.Width, item.TextMarkupBody.Bounds.Height); + item.TextMarkupBody.Bounds = mr; + item.TextMarkupBody.Render(d); + } + + } + } + + private Office2007CheckBoxStateColorTable GetCheckBoxStateColorTable(eMouseState state) + { + if (state == eMouseState.Down) + return ColorTable.CheckBoxItem.Pressed; + if (state == eMouseState.Hot) + return ColorTable.CheckBoxItem.MouseOver; + return ColorTable.CheckBoxItem.Default; + } + + private Office2007CheckBoxItemPainter _CheckBoxPainter; + public Office2007CheckBoxItemPainter CheckBoxPainter + { + get { return _CheckBoxPainter; } + set { _CheckBoxPainter = value; } + } + #endregion + } +} + diff --git a/PROMS/DotNetBar Source Code/Controls/ListViewEx.cs b/PROMS/DotNetBar Source Code/Controls/ListViewEx.cs new file mode 100644 index 00000000..606e1006 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ListViewEx.cs @@ -0,0 +1,1229 @@ +#if FRAMEWORK20 +using System; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.ComponentModel; +using DevComponents.DotNetBar.Rendering; +using System.Globalization; +using System.Drawing.Drawing2D; +using System.Runtime.InteropServices; +using System.Collections; +using System.Reflection; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the extended ListView control with the Office 2007 Style. + /// + [ToolboxBitmap(typeof(ListViewEx), "Controls.ListViewEx.ico"), ToolboxItem(true)] + public class ListViewEx : ListView, INonClientControl + { + #region Private Variables + private NonClientPaintHandler m_NCPainter = null; + private ElementStyle m_BorderStyle = null; + #endregion + + #region Constructor, Dispose + public ListViewEx() + : base() + { + m_BorderStyle = new ElementStyle(); + m_BorderStyle.Class = ElementStyleClassKeys.ListViewBorderKey; + m_BorderStyle.StyleChanged += new EventHandler(BorderStyle_StyleChanged); + m_NCPainter = new NonClientPaintHandler(this, eScrollBarSkin.Optimized); + this.OwnerDraw = true; + this.DoubleBuffered = true; + this.BorderStyle = BorderStyle.None; + StyleManager.Register(this); + } + + protected override void Dispose(bool disposing) + { + StyleManager.Unregister(this); + if (m_NCPainter != null) + { + m_NCPainter.Dispose(); + //m_NCPainter = null; + } + if (m_BorderStyle != null) m_BorderStyle.StyleChanged -= new EventHandler(BorderStyle_StyleChanged); + base.Dispose(disposing); + } + #endregion + + #region Inernal Implementation + private Font _ColumnHeaderFont = null; + /// + /// Gets or sets the column header font. Default value is null which means controls Font property is used. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates column header font.")] + public Font ColumnHeaderFont + { + get { return _ColumnHeaderFont; } + set + { + if (value != _ColumnHeaderFont) + { + Font oldValue = _ColumnHeaderFont; + _ColumnHeaderFont = value; + OnColumnHeaderFontChanged(oldValue, value); + } + } + } + /// + /// Called when ColumnHeaderFont property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnColumnHeaderFontChanged(Font oldValue, Font newValue) + { + if (this.IsHandleCreated) + this.Invalidate(true); + //OnPropertyChanged(new PropertyChangedEventArgs("ColumnHeaderFont")); + } + + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + this.Invalidate(true); + ResetCachedColorTableReference(); + } + + private void PaintHeaderBackground(Graphics g, Rectangle r) + { + Office2007ListViewColorTable ct = GetColorTable(); + DisplayHelp.FillRectangle(g, r, ct.ColumnBackground); + using (Pen pen = new Pen(ct.Border)) + { + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right, r.Bottom - 1); + } + } + private HeaderHandler m_HeaderHandler = null; + protected override void OnHandleCreated(EventArgs e) + { + m_HeaderHandler = new HeaderHandler(this); + base.OnHandleCreated(e); + } + protected override void OnHandleDestroyed(EventArgs e) + { + if (m_HeaderHandler != null) + { + m_HeaderHandler.ReleaseHandle(); + m_HeaderHandler = null; + } + base.OnHandleDestroyed(e); + } + /// + /// Resets internal Column Header handler. This method should be called after you change the View property + /// at run-time. If your control is always in single view there is no need to call this method. This method + /// will work only when controls handle has already been created. + /// + public void ResetHeaderHandler() + { + if (!this.IsHandleCreated) return; + + if (m_HeaderHandler != null) + { + m_HeaderHandler.ReleaseHandle(); + m_HeaderHandler = null; + } + m_HeaderHandler = new HeaderHandler(this); + } + + protected override void OnVisibleChanged(EventArgs e) + { + if (System.Environment.OSVersion.Version.Major < 6 && this.Visible) + WinApi.PostMessage(this.Handle, 0x120, IntPtr.Zero, IntPtr.Zero); + base.OnVisibleChanged(e); + } + + /// + /// Resets the internal color table reference. This method is usually called automatically by + /// + public void ResetCachedColorTableReference() + { + m_ListViewColorTable = null; + m_CheckBoxColorTable = null; + } + + private Office2007ListViewColorTable m_ListViewColorTable = null; + private Office2007ListViewColorTable GetColorTable() + { + if (m_ListViewColorTable == null) + { + Office2007Renderer r = this.GetRenderer() as Office2007Renderer; + if (r != null) + { + m_ListViewColorTable = r.ColorTable.ListViewEx; + } + } + + return m_ListViewColorTable; + } + + private Office2007CheckBoxColorTable m_CheckBoxColorTable = null; + private Office2007CheckBoxColorTable GetCheckBoxColorTable() + { + if (m_CheckBoxColorTable == null) + { + Office2007Renderer r = this.GetRenderer() as Office2007Renderer; + if (r != null) + { + m_CheckBoxColorTable = r.ColorTable.CheckBoxItem; + } + } + + return m_CheckBoxColorTable; + } + + + private void DrawColumnHeaderInternal(DrawListViewColumnHeaderEventArgs e) + { + Graphics g = e.Graphics; + Rectangle r = e.Bounds; + Office2007ListViewColorTable ct = GetColorTable(); + + Color c1 = ct.ColumnBackground.Start; + Color c2 = ct.ColumnBackground.End; + if ((e.State & ListViewItemStates.Selected) == ListViewItemStates.Selected && !c2.IsEmpty) + { + Color csw = c1; + c1 = c2; + c2 = csw; + } + + DisplayHelp.FillRectangle(g, r, c1, c2, ct.ColumnBackground.GradientAngle); + + using (Pen pen = new Pen(ct.Border)) + { + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right, r.Bottom - 1); + } + using (Pen pen = new Pen(ct.ColumnSeparator)) + g.DrawLine(pen, r.Right - 1, r.Y + 3, r.Right - 1, r.Bottom - 4); + + TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis | TextFormatFlags.NoPrefix; + switch (e.Header.TextAlign) + { + case HorizontalAlignment.Center: + flags |= TextFormatFlags.HorizontalCenter; + break; + case HorizontalAlignment.Right: + flags |= TextFormatFlags.Right; + break; + } + + if (e.Header.ImageList != null && (e.Header.ImageIndex >= 0 || e.Header.ImageKey != null && e.Header.ImageKey.Length > 0)) + { + Image img = null; + if (e.Header.ImageIndex >= 0) + img = e.Header.ImageList.Images[e.Header.ImageIndex]; + else + img = e.Header.ImageList.Images[e.Header.ImageKey]; + if (img != null) + { + Rectangle imageRect = new Rectangle(r.X + 2, r.Y + (r.Height - img.Height) / 2, img.Width, img.Height); + if (this.RightToLeft == RightToLeft.Yes) + { + imageRect.X = r.Right - imageRect.Width - 2; + r.Width -= imageRect.Width + 2; + } + else + { + r.Width -= imageRect.Width; + r.X += imageRect.Width; + } + g.DrawImage(img, imageRect); + } + } + + Color foreColor = e.ForeColor; + if (!ct.ColumnForeColor.IsEmpty) + foreColor = ct.ColumnForeColor; + DrawHeaderText(g, e.Font, foreColor, flags, e.Header.Text, r); + //e.DrawText(flags); + } + + + protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e) + { + //DrawColumnHeaderInternal(e); + base.OnDrawColumnHeader(e); + } + + private void DrawHeaderText(Graphics g, Font font, Color c, TextFormatFlags flags, string text, Rectangle r) + { + Size sz = TextRenderer.MeasureText(" ", font); + int w = sz.Width; + r.Inflate(-(w / 2), 0); + TextRenderer.DrawText(g, text, font, r, c, flags); + } + + private void DrawItemBackground(Graphics g, Rectangle r, ListViewItem item, ListViewItemStates state) + { + if (!this.Enabled) return; + // Bug fix in ListView for this specific state + if (state == 0 && item.Selected && this.View == View.Details && this.FullRowSelect && this.Focused) + r.X++; + + if (!item.BackColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(item.BackColor)) + { + g.FillRectangle(brush, r); + } + } + bool selected = IsInState(state, ListViewItemStates.Selected) || state == 0 && item.Selected; + if (selected) + { + Office2007ListViewColorTable ct = GetColorTable(); + // Draw the background for selected item. + r.Height--; + r.Width--; + using (Pen pen = new Pen(ct.SelectionBorder)) + g.DrawRectangle(pen, r); + r.Height++; + r.Width++; + Rectangle ir = new Rectangle(r.X, r.Y + 1, r.Width, r.Height - 2); + DisplayHelp.FillRectangle(g, ir, ct.SelectionBackground); + } + else if (IsInState(state, ListViewItemStates.Hot) && this.HotTracking) + { + Office2007Renderer rnd = this.GetRenderer() as Office2007Renderer; + Office2007ButtonItemPainter.PaintBackground(g, rnd.ColorTable.ButtonItemColors[0].MouseOver, r, RoundRectangleShapeDescriptor.RectangleShape); + } + + if (IsInState(state, ListViewItemStates.Focused) && (!IsInState(state, ListViewItemStates.Hot) && this.View != View.LargeIcon || selected)) + { + Rectangle rFocus = item.Bounds; + if (this.View == View.Details && !this.FullRowSelect || this.View == View.List) + rFocus = item.GetBounds(ItemBoundsPortion.Label); + else if (this.View == View.Details && this.FullRowSelect) + rFocus = r; + else if (this.View == View.SmallIcon) + rFocus = r; + + if (selected) + { + rFocus.Y++; + rFocus.Height -= 2; + } + + DrawFocusRectangle(g, rFocus, item); + } + else if (selected && this.View == View.Details && this.FullRowSelect && this.Focused) // Bug fix in ListView for this specific state + { + Rectangle rFocus = r; + rFocus.Y++; + rFocus.Height -= 2; + Region oldClip = g.Clip; + Rectangle rClip = rFocus; + rClip.Width--; + g.SetClip(rClip); + DrawFocusRectangle(g, rFocus, item); + g.Clip = oldClip; + } + } + + private bool IsInState(ListViewItemStates currentState, ListViewItemStates testState) + { + return ((currentState & testState) == testState); + } + + protected override void OnDrawItem(DrawListViewItemEventArgs e) + { + if (e.State == 0 && this.View != View.List && this.View != View.Tile && this.View != View.SmallIcon && this.View != View.LargeIcon || this.View == View.Details) + { + base.OnDrawItem(e); + return; + } + + FixStateForHideSelection(e); + + Graphics g = e.Graphics; + Rectangle r = e.Bounds; + + if (this.View == View.List) + r = e.Item.GetBounds(ItemBoundsPortion.Label); + else if (this.View == View.SmallIcon) + { + r = e.Item.GetBounds(ItemBoundsPortion.Label); + //Size sz = TextDrawing.MeasureString(g, e.Item.Text, e.Item.Font); + //sz.Width += 2; + //if (sz.Width > r.Width) + // r.Width = sz.Width; + } + DrawItemBackground(g, r, e.Item, e.State); + Color foreColor = e.Item.ForeColor; + if (IsInState(e.State, ListViewItemStates.Selected) && this.Enabled) + { + Office2007ListViewColorTable ct = GetColorTable(); + if (!ct.SelectionForeColor.IsEmpty) + foreColor = ct.SelectionForeColor; + } + DrawListViewItem(g, e.Item, null, e.Item.Font, foreColor, e.State); + + base.OnDrawItem(e); + } + + private bool HasImage(ListViewItem item) + { + if (item.ImageList != null && (item.ImageIndex >= 0 || item.ImageKey.Length > 0)) + return true; + return false; + } + + private Size m_CheckSignSize = new Size(13, 13); + private void DrawListViewItem(Graphics g, ListViewItem item, ColumnHeader header, Font font, Color color, ListViewItemStates state) + { + bool hasImage = HasImage(item); + // Draw Image if any + if (hasImage && (header == null || header.Width > 4)) + { + Rectangle rImage = item.GetBounds(ItemBoundsPortion.Icon); + int index = item.ImageIndex; + if (index < 0) + index = item.ImageList.Images.IndexOfKey(item.ImageKey); + if (this.View != View.Details && this.View != View.List && this.StateImageList != null) + rImage.X += this.StateImageList.ImageSize.Width + 3; + else if (this.View == View.SmallIcon && this.CheckBoxes && this.Groups.Count == 0) + rImage.X += this.SmallImageList.ImageSize.Width; + else if (this.View == View.LargeIcon && (item.ImageList.ImageSize.Width < rImage.Width || item.ImageList.ImageSize.Height < rImage.Height)) + { + if (item.ImageList.ImageSize.Width < rImage.Width) + rImage.X += (rImage.Width - item.ImageList.ImageSize.Width) / 2; + if (item.ImageList.ImageSize.Height < rImage.Height) + rImage.Y += (rImage.Height - item.ImageList.ImageSize.Height) / 2; + } + + Region oldClip = null; + if (header != null && header.Width < rImage.Width) + { + Rectangle rClip = rImage; + rClip.Width = header.Width; + oldClip = g.Clip; + g.SetClip(rClip); + } + if (rImage.Width > 2) + { + g.DrawImage(item.ImageList.Images[index], rImage.Location); // item.ImageList.Draw(g, rImage.Location, index); + } + + if (oldClip != null) g.Clip = oldClip; + } + //Console.WriteLine("{0} - {1} " ,DateTime.Now, item.SubItems[0].Text); + // Draw text + Rectangle rText = item.GetBounds(ItemBoundsPortion.Label); + if (rText.Width > 2) + { + // Draw the item text for views other than the Details view. + eTextFormat flags = eTextFormat.Left | eTextFormat.SingleLine | eTextFormat.NoPrefix; + if (this.View == View.Tile && item.SubItems.Count > 1) + flags |= eTextFormat.Top; + else + flags |= eTextFormat.VerticalCenter; + if (this.View == View.LargeIcon) + { + flags = eTextFormat.HorizontalCenter | eTextFormat.WordBreak | eTextFormat.EndEllipsis | eTextFormat.NoClipping; + } + else if (this.View == View.Details && header != null) + { + flags |= eTextFormat.EndEllipsis; + if (header.TextAlign == HorizontalAlignment.Center) + flags |= eTextFormat.HorizontalCenter; + else if (header.TextAlign == HorizontalAlignment.Right) + flags |= eTextFormat.Right; + + rText.X += 2; + } + else if (this.View == View.List || this.View == View.SmallIcon) + rText.X += 2; + if (!BarFunctions.IsVista) rText.Inflate(0, 1); + TextDrawing.DrawString(g, item.Text, font, color, rText, flags); + + if (this.View == View.Tile && item.SubItems.Count > 1) + { + Size sz = TextDrawing.MeasureString(g, item.Text, font); + rText.Y += sz.Height; + rText.Height -= sz.Height; + Color c1 = item.SubItems[1].ForeColor; + if (!c1.IsEmpty && c1 != color) + color = c1; + else + color = SystemColors.ControlDarkDark; + TextDrawing.DrawString(g, item.SubItems[1].Text, font, color, rText, flags); + } + } + + if (this.View == View.Details || this.StateImageList != null) + { + if (this.StateImageList != null) + { + if (item.StateImageIndex >= 0 && item.StateImageIndex < this.StateImageList.Images.Count) + { + Rectangle r = item.GetBounds(ItemBoundsPortion.Icon); + if (this.View == View.Details || this.View == View.List) + r.X -= 19; + else if (this.View == View.LargeIcon && r.Width > this.StateImageList.ImageSize.Width) + { + r.X += (r.Width - this.StateImageList.ImageSize.Width) / 2; + r.Y++; + } + else if (this.View == View.Tile && r.Height > this.StateImageList.ImageSize.Height) + { + r.Y += (r.Height - this.StateImageList.ImageSize.Height) / 2; + r.X++; + } + this.StateImageList.Draw(g, r.Location, item.StateImageIndex); + } + } + } + + if (this.CheckBoxes && (this.View == View.Details || this.View == View.List || this.View == View.SmallIcon || this.View == View.LargeIcon) && this.StateImageList == null) + { + Rectangle r = item.GetBounds(ItemBoundsPortion.Icon); + if (this.View == View.LargeIcon) + r.X += 9; + else if (this.View == View.List) + r.X -= 18; + else if (this.View == View.SmallIcon && hasImage && this.Groups.Count > 0) + r.X -= 20; + else if (this.View == View.SmallIcon) + r.X -= 3; + else + r.X -= 21; + Office2007CheckBoxItemPainter p = PainterFactory.CreateCheckBoxItemPainter(null); + Office2007CheckBoxColorTable ctt = GetCheckBoxColorTable(); + Office2007CheckBoxStateColorTable ct = ctt.Default; + if ((state & ListViewItemStates.Grayed) != 0 || !this.Enabled) + ct = ctt.Disabled; + //else if ((state & ListViewItemStates.Hot) != 0) + // ct = ctt.MouseOver; + p.PaintCheckBox(g, new Rectangle(r.X + 4, r.Y + (r.Height - m_CheckSignSize.Height) / 2, m_CheckSignSize.Width, m_CheckSignSize.Height), + ct, item.Checked ? CheckState.Checked : CheckState.Unchecked); + } + } + + protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e) + { + FixStateForHideSelection(e); + + Graphics g = e.Graphics; + bool backgroundErased = false; + //if (e.ItemState == 0 && this.View == View.Details && this.FullRowSelect) return; Can't do this can cause items not be displayed at all + if (this.FullRowSelect && IsInState(e.ItemState, ListViewItemStates.Selected) && e.Header != null && + (e.Header.DisplayIndex == 0 || e.Bounds.X <= 0 && e.Header.DisplayIndex > 0 && this.Scrollable)) + { + Rectangle r = e.Item.Bounds; + if ((HasImage(e.Item) || e.Header.DisplayIndex != e.Header.Index) && e.Header.DisplayIndex == 0) + { + Rectangle rLabel = e.Item.GetBounds(ItemBoundsPortion.Icon); + int w = Math.Min(e.Header.Width, (rLabel.Right - r.X) + 1); + r.Width -= w; + r.X += w; + } + DrawItemBackground(g, r, e.Item, e.ItemState); + backgroundErased = true; + } + + if (e.ColumnIndex == 0) + { + if (!(this.FullRowSelect && IsInState(e.ItemState, ListViewItemStates.Selected))) + { + Rectangle r = e.Item.GetBounds(ItemBoundsPortion.Label); + + //if (System.Environment.OSVersion.Version.Major < 6) + // r.Height += 2; + //else + // r.Height++; + DrawItemBackground(g, r, e.Item, e.ItemState); + backgroundErased = true; + } + Color foreColor = e.Item.ForeColor; + Office2007ListViewColorTable ct = GetColorTable(); + if (IsInState(e.ItemState, ListViewItemStates.Selected) && !ct.SelectionForeColor.IsEmpty) foreColor = ct.SelectionForeColor; + if (!this.Enabled) foreColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor; + DrawListViewItem(g, e.Item, e.Header, e.Item.Font, foreColor, e.ItemState); + + // This was added to address issue in Detail view where with row selected for first time, mouse over the second + // column would erase the text in subsequent columns without them getting paint call so text was was visible + if (backgroundErased && this.FullRowSelect && IsInState(e.ItemState, ListViewItemStates.Selected) && this.View == View.Details) + { + // Paint SubItems + for (int i = 1; i < e.Item.SubItems.Count; i++) + { + System.Windows.Forms.ListViewItem.ListViewSubItem subItem = e.Item.SubItems[i]; + Rectangle r = subItem.Bounds; + if (r.IntersectsWith(this.DisplayRectangle)) + PaintSubItem(g, subItem, r, e.ItemState, (i < this.Columns.Count ? this.Columns[i] : null), e.Item.BackColor, i); + } + } + + //int start = m_FirstVisibleColumnIndex; + //if (start == 0) start++; + // Paint SubItems + //for (int i = start; i < e.Item.SubItems.Count; i++) + //{ + // System.Windows.Forms.ListViewItem.ListViewSubItem subItem = e.Item.SubItems[i]; + // Rectangle r = subItem.Bounds; + // if (r.IntersectsWith(this.DisplayRectangle)) + // PaintSubItem(g, subItem, r, e.ItemState, (i < this.Columns.Count ? this.Columns[i] : null), e.Item.BackColor); + //} + } + else + { + if (this.FullRowSelect && IsInState(e.ItemState, ListViewItemStates.Selected) && e.Header.DisplayIndex != e.Header.Index) + { + Rectangle r = e.Bounds; + DrawItemBackground(g, r, e.Item, e.ItemState); + backgroundErased = true; + } + if (e.Header.Width > 0) + PaintSubItem(g, e.SubItem, e.Bounds, e.ItemState, this.Columns[e.ColumnIndex], e.Item.BackColor, e.ColumnIndex); + } + base.OnDrawSubItem(e); + } + + private Color _DisabledForeColor = Color.Empty; + /// + /// Gets or sets the item foreground color when control or item is disabled. By default SystemColors.Dark is used. + /// + [Category("Appearance"), Description("Indicates item foreground color when control or item is disabled.")] + public Color DisabledForeColor + { + get { return _DisabledForeColor; } + set { _DisabledForeColor = value; } + } + /// + /// Gets whether property should be serialized by VS.NET designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeDisabledForeColor() + { + return !_DisabledForeColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetDisabledForeColor() + { + DisabledForeColor = Color.Empty; + } + + //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + //public new bool HideSelection + //{ + // get { return base.HideSelection; } + // set { base.HideSelection = false; } + //} + + //private int m_FirstVisibleColumnIndex = 0; + //private void UpdateFirstVisibleColumnIndex() + //{ + // m_FirstVisibleColumnIndex = 0; + // if (this.View == View.Details && this.Columns.Count > 0 && this.Items.Count>0) + // { + // ListViewItem item = this.Items[0]; + // if (item.Bounds.X < 0) + // { + // int x = item.Bounds.X; + // IList list = GetOrderedColumnList(); + // for (int i = 0; i < list.Count; i++) + // { + // ColumnHeader h = list[i] as ColumnHeader; + // if (x + h.Width > 0) + // { + // m_FirstVisibleColumnIndex = i; + // break; + // } + // else + // x += h.Width; + // } + // } + // } + //} + + private IList GetOrderedColumnList() + { + IList columns = this.Columns; + if (this.AllowColumnReorder) + { + ArrayList ca = new ArrayList(this.Columns); + foreach (ColumnHeader h in columns) + { + if (h.DisplayIndex < 0) continue; + ca[h.DisplayIndex] = h; + } + columns = ca; + } + + return columns; + } + + private void PaintSubItem(Graphics g, ListViewItem.ListViewSubItem subitem, Rectangle r, ListViewItemStates state, ColumnHeader header, Color itemBackColor, int columnIndex) + { + if (!IsInState(state, ListViewItemStates.Selected) && this.Enabled) + { + Rectangle rFill = r; + //rFill.Height++; + if (!subitem.BackColor.IsEmpty /*&& !(subitem.BackColor == this.BackColor && !itemBackColor.IsEmpty)*/) + { + using (SolidBrush brush = new SolidBrush(subitem.BackColor)) + g.FillRectangle(brush, rFill); + } + else if (!itemBackColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(itemBackColor)) + g.FillRectangle(brush, rFill); + } + } + + eTextFormat flags = eTextFormat.Left | eTextFormat.SingleLine | eTextFormat.VerticalCenter | eTextFormat.EndEllipsis | eTextFormat.NoClipping | eTextFormat.NoPrefix; + + if (header != null) + { + if (header.TextAlign == HorizontalAlignment.Center) + flags |= eTextFormat.HorizontalCenter; + else if (header.TextAlign == HorizontalAlignment.Right) + flags |= eTextFormat.Right; + } + + Color foreColor = subitem.ForeColor; + if (IsInState(state, ListViewItemStates.Selected) && this.Enabled && (columnIndex == 0 || this.FullRowSelect)) + { + Office2007ListViewColorTable ct = GetColorTable(); + if (!ct.SelectionForeColor.IsEmpty) + foreColor = ct.SelectionForeColor; + } + if (!this.Enabled) foreColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor; + Rectangle rText = Rectangle.Inflate(r, -2, BarFunctions.IsVista ? 0 : 1); // Rectangle.Inflate(r, -sz.Width, 0); + TextDrawing.DrawString(g, subitem.Text, subitem.Font, foreColor, rText, flags); + //Console.WriteLine("{0}-Sub {1} {2}",DateTime.Now, subitem.Text,rText); + + } + + private void DrawFocusRectangle(Graphics g, Rectangle r, ListViewItem item) + { + if (_FocusCuesEnabled) + ControlPaint.DrawFocusRectangle(g, r, item.ForeColor, item.BackColor); + } + private bool _FocusCuesEnabled = true; + /// + /// Gets or sets whether control displays focus cues when focused. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether control displays focus cues when focused.")] + public virtual bool FocusCuesEnabled + { + get { return _FocusCuesEnabled; } + set + { + _FocusCuesEnabled = value; + if (this.Focused) this.Invalidate(); + } + } + private Rectangle UpdateBounds(Rectangle originalBounds, bool drawText, ListViewItem item) + { + Rectangle r = originalBounds; + if (this.View == View.Details) + { + if (!this.FullRowSelect && (item.SubItems.Count > 0)) + { + ListViewItem.ListViewSubItem subItem = item.SubItems[0]; + Size textSize = TextRenderer.MeasureText(subItem.Text, subItem.Font); + r = new Rectangle(originalBounds.X, originalBounds.Y, textSize.Width, textSize.Height); + r.X += 4; + r.Width++; + } + else + { + r.X += 4; + r.Width -= 4; + } + if (drawText) + { + r.X--; + } + } + return r; + } + + private Point m_MouseDown = Point.Empty; + protected override void OnMouseDown(MouseEventArgs e) + { + m_MouseDown = new Point(e.X, e.Y); + if (this.View == View.LargeIcon && this.CheckBoxes) + { + ListViewHitTestInfo info = HitTest(m_MouseDown); + if (info.Item == null) + info = HitTest(new Point(e.X + 9, e.Y)); + if (info.Item != null) + { + Rectangle r = info.Item.GetBounds(ItemBoundsPortion.Icon); + r.X += 9; + r = new Rectangle(r.X + 4, r.Y + (r.Height - m_CheckSignSize.Height) / 2, m_CheckSignSize.Width-4, + m_CheckSignSize.Height); + if (r.Contains(m_MouseDown)) + info.Item.Checked = !info.Item.Checked; + + } + } + base.OnMouseDown(e); + } + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + if (this.View == View.Details && this.FullRowSelect && !this.IsDisposed && !this.CheckBoxes) + { + ListViewItem clickedItem = GetItemAt(5, e.Y); + ListViewItem mouseDownItem = GetItemAt(5, m_MouseDown.Y); + if (clickedItem != null && clickedItem == mouseDownItem) + { + //clickedItem.Selected = true; // There was a bug when this is executed that did not allow an item to be Ctrl+Mouse Click deselected + if (clickedItem.Selected) + clickedItem.Focused = true; + } + } + } + + private bool m_FirstMouseEnter = true; + protected override void OnMouseEnter(EventArgs e) + { + if (m_FirstMouseEnter) + { + this.Refresh(); + m_FirstMouseEnter = false; + } + base.OnMouseEnter(e); + } + + protected override void OnLostFocus(EventArgs e) + { + if (this.HideSelection) + { + if (!this.VirtualMode && this.SelectedItems.Count > 0) + { + foreach (ListViewItem item in this.SelectedItems) + { + Rectangle r = item.Bounds; + if (this.View == View.Details) + { + r.X = 0; + r.Width = this.Width; + } + else if (this.View == View.LargeIcon) + { + r.Inflate(32, 32); + } + this.Invalidate(r); + } + } + } + + base.OnLostFocus(e); + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool OwnerDraw + { + get { return base.OwnerDraw; } + set { base.OwnerDraw = value; } + } + + [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] + private struct NMHDR + { + public IntPtr hwndFrom; + public IntPtr idFrom; + public int code; + } + [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] + private struct NMCUSTOMDRAW + { + public NMHDR nmcd; + public int dwDrawStage; + public IntPtr hdc; + public WinApi.RECT rc; + public IntPtr dwItemSpec; + public int uItemState; + public IntPtr lItemlParam; + } + + protected override void WndProc(ref Message m) + { + if (m_NCPainter != null) + { + bool callBase = m_NCPainter.WndProc(ref m); + + if (callBase) + base.WndProc(ref m); + } + else + { + base.WndProc(ref m); + } + + //if (m.Msg == (int)WinApi.WindowsMessages.WM_HSCROLL) + //{ + // UpdateFirstVisibleColumnIndex(); + //} + } + + private Rendering.BaseRenderer m_DefaultRenderer = null; + private Rendering.BaseRenderer m_Renderer = null; + private eRenderMode m_RenderMode = eRenderMode.Global; + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public virtual Rendering.BaseRenderer GetRenderer() + { + if (m_RenderMode == eRenderMode.Global && Rendering.GlobalManager.Renderer != null) + return Rendering.GlobalManager.Renderer; + else if (m_RenderMode == eRenderMode.Custom && m_Renderer != null) + return m_Renderer; + + if (m_DefaultRenderer == null) + m_DefaultRenderer = new Rendering.Office2007Renderer(); + + return m_DefaultRenderer; + } + + /// + /// Gets or sets the redering mode used by control. Default value is eRenderMode.Global which means that static GlobalManager.Renderer is used. If set to Custom then Renderer property must + /// also be set to the custom renderer that will be used. + /// + [Browsable(false), DefaultValue(eRenderMode.Global)] + public eRenderMode RenderMode + { + get { return m_RenderMode; } + set + { + if (m_RenderMode != value) + { + m_RenderMode = value; + m_ListViewColorTable = null; + this.Invalidate(true); + } + } + } + + /// + /// Gets or sets the custom renderer used by the items on this control. RenderMode property must also be set to eRenderMode.Custom in order renderer + /// specified here to be used. + /// + [Browsable(false), DefaultValue(null)] + public DevComponents.DotNetBar.Rendering.BaseRenderer Renderer + { + get + { + return m_Renderer; + } + set + { + m_Renderer = value; + m_ListViewColorTable = null; + } + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new BorderStyle BorderStyle + { + get { return base.BorderStyle; } + set { } + } + + private ElementStyle GetBorderStyle() + { + m_BorderStyle.SetColorScheme(this.GetColorScheme()); + bool disposeStyle = false; + return ElementStyleDisplay.GetElementStyle(m_BorderStyle,out disposeStyle); + } + + /// + /// Specifies the control border style. Default value has Class property set so the system style for the control is used. + /// + [Browsable(true), Category("Style"), Description("Specifies the control border style. Default value has Class property set so the system style for the control is used."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle Border + { + get { return m_BorderStyle; } + } + private void BorderStyle_StyleChanged(object sender, EventArgs e) + { + if (!BarFunctions.IsHandleValid(this)) return; + const int RDW_INVALIDATE = 0x0001; + const int RDW_FRAME = 0x0400; + NativeFunctions.RECT r = new NativeFunctions.RECT(0, 0, this.Width, this.Height); + NativeFunctions.RedrawWindow(this.Handle, ref r, IntPtr.Zero, RDW_INVALIDATE | RDW_FRAME); + } + + protected override CreateParams CreateParams + { + get + { + CreateParams p = base.CreateParams; + p.ExStyle = p.ExStyle & ~(p.ExStyle & 0x200); + return p; + } + } + + #endregion + + #region INonClientControl Members + void INonClientControl.BaseWndProc(ref Message m) + { + base.WndProc(ref m); + } + + ItemPaintArgs INonClientControl.GetItemPaintArgs(System.Drawing.Graphics g) + { + ItemPaintArgs pa = new ItemPaintArgs(this as IOwner, this, g, GetColorScheme()); + pa.Renderer = this.GetRenderer(); + pa.DesignerSelection = false; // m_DesignerSelection; + pa.GlassEnabled = !this.DesignMode && WinApi.IsGlassEnabled; + return pa; + } + + ElementStyle INonClientControl.BorderStyle + { + get { return GetBorderStyle(); } + } + + void INonClientControl.PaintBackground(PaintEventArgs e) + { + //if (this.Parent == null) return; + //Type t = typeof(Control); + //MethodInfo mi = t.GetMethod("PaintTransparentBackground", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(PaintEventArgs), typeof(Rectangle) }, null); + //if (mi != null) + //{ + // mi.Invoke(this, new object[] { e, new Rectangle(0, 0, this.Width, this.Height) }); + //} + } + + private ColorScheme m_ColorScheme = null; + /// + /// Returns the color scheme used by control. Color scheme for Office2007 style will be retrived from the current renderer instead of + /// local color scheme referenced by ColorScheme property. + /// + /// An instance of ColorScheme object. + protected virtual ColorScheme GetColorScheme() + { + BaseRenderer r = GetRenderer(); + if (r is Office2007Renderer) + return ((Office2007Renderer)r).ColorTable.LegacyColors; + if (m_ColorScheme == null) + m_ColorScheme = new ColorScheme(eDotNetBarStyle.Office2007); + return m_ColorScheme; + } + + IntPtr INonClientControl.Handle + { + get { return this.Handle; } + } + + int INonClientControl.Width + { + get { return this.Width; } + } + + int INonClientControl.Height + { + get { return this.Height; } + } + + bool INonClientControl.IsHandleCreated + { + get { return this.IsHandleCreated; } + } + + Point INonClientControl.PointToScreen(Point client) + { + return this.PointToScreen(client); + } + + Color INonClientControl.BackColor + { + get { return this.BackColor; } + } + + void INonClientControl.AdjustClientRectangle(ref Rectangle r) { } + + void INonClientControl.AdjustBorderRectangle(ref Rectangle r) { } + + void INonClientControl.RenderNonClient(Graphics g) { } + + private Color _DisabledBackColor = Color.Empty; + /// + /// Specifies back color when Enabled=false + /// + [Browsable(false), Category("Appearance"), Description("Specifies back color when Enabled=false")] + public Color DisabledBackColor + { + get { return _DisabledBackColor; } + set + { + _DisabledBackColor = value; + if (!Enabled) this.Invalidate(); + } + } + #endregion + + #region HeaderNativeWindowHandler + private class HeaderHandler : NativeWindow + { + private ListViewEx m_Parent = null; + private bool m_MouseDown = false; + private Point m_MouseDownPoint = Point.Empty; + public HeaderHandler(ListViewEx parent) + { + m_Parent = parent; + IntPtr h = new IntPtr(WinApi.SendMessage(parent.Handle, (0x1000 + 31), IntPtr.Zero, IntPtr.Zero)); + if (h != IntPtr.Zero) + AssignHandle(h); + } + + protected override void WndProc(ref Message m) + { + if (m.Msg == (int)WinApi.WindowsMessages.WM_PAINT) + { + WinApi.PAINTSTRUCT ps = new WinApi.PAINTSTRUCT(); + IntPtr hdc = WinApi.BeginPaint(m.HWnd, ref ps); + try + { + Graphics g = Graphics.FromHdc(hdc); + try + { + WinApi.RECT r = new WinApi.RECT(); + WinApi.GetWindowRect(m.HWnd, ref r); + Rectangle rc = new Rectangle(0, 0, r.Width, r.Height); + using (BufferedBitmap bb = new BufferedBitmap(hdc, rc)) + { + m_Parent.PaintHeaderBackground(bb.Graphics, rc); + + IList columns = m_Parent.GetOrderedColumnList(); + + int x = 0; + foreach (ColumnHeader h in columns) + { + + Rectangle hr = new Rectangle(x, 0, h.Width, r.Height); + ListViewItemStates state = ListViewItemStates.ShowKeyboardCues; + if (m_MouseDown && hr.Contains(m_MouseDownPoint)) + { + Rectangle rt = hr; + rt.Inflate(-6, 0); + if (rt.Contains(m_MouseDownPoint)) + state |= ListViewItemStates.Selected; + } + + m_Parent.DrawColumnHeaderInternal(new DrawListViewColumnHeaderEventArgs(bb.Graphics, hr, h.DisplayIndex, h, + state, SystemColors.ControlText, Color.Empty, m_Parent.ColumnHeaderFont ?? m_Parent.Font)); + x += h.Width; + } + bb.Render(g); + } + } + finally + { + g.Dispose(); + } + } + finally + { + WinApi.EndPaint(m.HWnd, ref ps); + } + return; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONDOWN) + { + if (m_Parent.HeaderStyle == ColumnHeaderStyle.Clickable) + { + m_MouseDown = true; + m_MouseDownPoint = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam)); + WinApi.RedrawWindow(m.HWnd, IntPtr.Zero, IntPtr.Zero, WinApi.RedrawWindowFlags.RDW_INVALIDATE); + } + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONUP) + { + m_MouseDown = false; + m_MouseDownPoint = Point.Empty; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_MOUSEMOVE && m_MouseDown) + { + m_MouseDownPoint = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam)); + } + + base.WndProc(ref m); + } + } + #endregion + + #region Hide-Selection ListView Bug Hacking + bool _IsItemInitialized = false; + bool _IsSubItemInitialized = false; + FieldInfo _ItemStateField = null; + FieldInfo _SubItemStateField = null; + + private void FixStateForHideSelection(DrawListViewItemEventArgs e) + { + if (HideSelection) return; + if (!this._IsItemInitialized) + { + _ItemStateField = e.GetType().GetField("state",BindingFlags.NonPublic | BindingFlags.Instance); + _IsItemInitialized = true; + } + + if (_ItemStateField != null) + { + UpdateStateBit(e, _ItemStateField, e.Item.Selected,e.State); + } + } + + private void FixStateForHideSelection(DrawListViewSubItemEventArgs e) + { + if (HideSelection) return; + if (!_IsSubItemInitialized) + { + + _SubItemStateField =e.GetType().GetField("itemState", BindingFlags.NonPublic |BindingFlags.Instance); + _IsSubItemInitialized = true; + } + + if (_SubItemStateField != null) + { + UpdateStateBit(e, _SubItemStateField,e.Item.Selected, e.ItemState); + } + } + + private void UpdateStateBit(object o, FieldInfo f, bool itemSelected, ListViewItemStates currentState) + { + bool stateSelected = (currentState & ListViewItemStates.Selected) != 0; + + if (itemSelected != stateSelected) + { + ListViewItemStates newState = currentState; + if (itemSelected) + { + newState |= ListViewItemStates.Selected; + } + else + { + newState &= ~(ListViewItemStates.Selected); + } + try + { + f.SetValue(o, newState); + } + catch { } + } + } + + + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/ListViewEx.ico b/PROMS/DotNetBar Source Code/Controls/ListViewEx.ico new file mode 100644 index 00000000..6cd7112a Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/ListViewEx.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/MaskedTextBoxAdv.cs b/PROMS/DotNetBar Source Code/Controls/MaskedTextBoxAdv.cs new file mode 100644 index 00000000..45c03048 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/MaskedTextBoxAdv.cs @@ -0,0 +1,1894 @@ +#if FRAMEWORK20 +using System; +using System.Text; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.Editors; +using System.Collections; +using System.Drawing; +using System.Globalization; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Diagnostics; +using DevComponents.DotNetBar.TextMarkup; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(MaskedTextBoxAdv), "Controls.MaskedTextBoxAdv.ico"), System.ComponentModel.ToolboxItem(true), DefaultProperty("Mask"), DefaultBindingProperty("Text"), DefaultEvent("MaskInputRejected"), Designer("DevComponents.DotNetBar.Design.MaskedTextBoxAdvDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class MaskedTextBoxAdv : PopupItemControl, IInputButtonControl, ICommandSource + { + #region Private Variables + private MaskedTextBox _MaskedTextBox = null; + private ButtonItem _PopupItem = null; + private static string _DropDownItemContainerName = "sysPopupItemContainer"; + private static string _DropDownControlContainerName = "sysPopupControlContainer"; + private Color _FocusHighlightColor = ColorScheme.GetColor(0xFFFF88); + private bool _FocusHighlightEnabled = false; + private string _WatermarkText = ""; + private Font _WatermarkFont = null; + private Color _WatermarkColor = SystemColors.GrayText; + #endregion + + #region Events + /// + /// Occurs when Clear button is clicked and allows you to cancel the default action performed by the button. + /// + public event CancelEventHandler ButtonClearClick; + /// + /// Occurs when Drop-Down button that shows popup is clicked and allows you to cancel showing of the popup. + /// + public event CancelEventHandler ButtonDropDownClick; + /// + /// Occurs when ButtonCustom control is clicked. + /// + public event EventHandler ButtonCustomClick; + /// + /// Occurs when ButtonCustom2 control is clicked. + /// + public event EventHandler ButtonCustom2Click; + /// + /// Occurs after the insert mode has changed + /// + [Description("Occurs after the insert mode has changed")] + public event EventHandler IsOverwriteModeChanged; + /// + /// Occurs after the input mask is changed. + /// + [Description("Occurs after the input mask is changed.")] + public event EventHandler MaskChanged; + /// + /// Occurs when the user's input or assigned character does not match the corresponding format element of the input mask. + /// + [Category("Behavior"), Description("Occurs when the user's input or assigned character does not match the corresponding format element of the input mask.")] + public event MaskInputRejectedEventHandler MaskInputRejected; + /// + /// Occurs when the text alignment is changed. + /// + [Description("Occurs when the text alignment is changed.")] + public event EventHandler TextAlignChanged; + /// + /// Occurs when MaskedTextBox has finished parsing the current value using the ValidatingType property. + /// + [Category("Focus"), Description("Occurs when MaskedTextBox has finished parsing the current value using the ValidatingType property.")] + public event TypeValidationEventHandler TypeValidationCompleted; + + + + #endregion + + #region Constructor + /// + /// Initializes a new instance of the MaskedTextBoxAdv class. + /// + public MaskedTextBoxAdv() + { + this.SetStyle(ControlStyles.Selectable, false); + _MaskedTextBox = new MaskedTextBoxInternal(); + this.BackColor = SystemColors.Window; + InitControl(); + } + + + /// + /// Initializes a new instance of the MaskedTextBoxAdv class using the specified input mask. + /// + /// A custom mask language provider, derived from the MaskedTextProvider class. + public MaskedTextBoxAdv(MaskedTextProvider maskedTextProvider) + { + _MaskedTextBox = new MaskedTextBox(maskedTextProvider); + InitControl(); + } + + /// + /// Initializes a new instance of the MaskedTextBoxAdv class using the specified input mask. + /// + /// Initializes a new instance of the MaskedTextBox class using the specified input mask. + public MaskedTextBoxAdv(string mask) + { + _MaskedTextBox = new MaskedTextBox(mask); + InitControl(); + } + + private void InitControl() + { + _BackgroundStyle.SetColorScheme(this.ColorScheme); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + + _ButtonCustom = new InputButtonSettings(this); + _ButtonCustom2 = new InputButtonSettings(this); + _ButtonClear = new InputButtonSettings(this); + _ButtonDropDown = new InputButtonSettings(this); + CreateButtonGroup(); + + _MaskedTextBox.BorderStyle = BorderStyle.None; + _MaskedTextBox.TextChanged += new EventHandler(MaskedTextBoxTextChanged); + _MaskedTextBox.IsOverwriteModeChanged += new EventHandler(MaskedTextBoxIsOverwriteModeChanged); + _MaskedTextBox.MaskChanged += new EventHandler(MaskedTextBoxMaskChanged); + _MaskedTextBox.MaskInputRejected += new MaskInputRejectedEventHandler(MaskedTextBoxMaskInputRejected); + _MaskedTextBox.TextAlignChanged += new EventHandler(MaskedTextBoxTextAlignChanged); + _MaskedTextBox.TypeValidationCompleted += new TypeValidationEventHandler(MaskedTextBoxTypeValidationCompleted); + _MaskedTextBox.SizeChanged += new EventHandler(MaskedTextBoxSizeChanged); + this.Controls.Add(_MaskedTextBox); + } + + private void MaskedTextBoxSizeChanged(object sender, EventArgs e) + { + if (!_InternalSizeUpdate) + UpdateLayout(); + } + #endregion + + #region Internal Implementation + private Color _EnabledBackColor = Color.Empty; + protected override void OnEnabledChanged(EventArgs e) + { + if (_WatermarkText.Length > 0) + this.Invalidate(); + UpdateEnabledBackColor(); + base.OnEnabledChanged(e); + } + private void UpdateEnabledBackColor() + { + if (!_DisabledBackColor.IsEmpty) + { + if (!this.Enabled) + { + _EnabledBackColor = this.BackColor; + this.BackColor = _DisabledBackColor; + _MaskedTextBox.BackColor = _DisabledBackColor; + } + else if (!_EnabledBackColor.IsEmpty) + { + this.BackColor = _EnabledBackColor; + _MaskedTextBox.BackColor = _EnabledBackColor; + _EnabledBackColor = Color.Empty; + } + } + } + private Color _DisabledBackColor = Color.Empty; + /// + /// Specifies back color when Enabled=false + /// + [Browsable(true), Category("Appearance"), Description("Specifies back color when Enabled=false")] + public Color DisabledBackColor + { + get { return _DisabledBackColor; } + set + { + _DisabledBackColor = value; + if (!Enabled) this.Invalidate(); + } + } + public bool ShouldSerializeDisabledBackColor() + { + return !_DisabledBackColor.IsEmpty; + } + public void ResetDisabledBackColor() + { + DisabledBackColor = Color.Empty; + } + /// + /// Gets or sets whether FocusHighlightColor is used as background color to highlight text box when it has input focus. Default value is false. + /// + [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Indicates whether FocusHighlightColor is used as background color to highlight text box when it has input focus.")] + public bool FocusHighlightEnabled + { + get { return _FocusHighlightEnabled; } + set + { + if (_FocusHighlightEnabled != value) + { + _FocusHighlightEnabled = value; + if (this.Focused) + this.Invalidate(true); + } + } + } + + /// + /// Gets or sets the color used as background color to highlight text box when it has input focus and focus highlight is enabled. + /// + [Browsable(true), Category("Appearance"), Description("Indicates color used as background color to highlight text box when it has input focus and focus highlight is enabled.")] + public Color FocusHighlightColor + { + get { return _FocusHighlightColor; } + set + { + if (_FocusHighlightColor != value) + { + _FocusHighlightColor = value; + if (this.Focused) + this.Invalidate(true); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFocusHighlightColor() + { + return !_FocusHighlightColor.Equals(ColorScheme.GetColor(0xFFFF88)); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFocusHighlightColor() + { + FocusHighlightColor = ColorScheme.GetColor(0xFFFF88); + } + + private void MaskedTextBoxTypeValidationCompleted(object sender, TypeValidationEventArgs e) + { + OnTypeValidationCompleted(e); + } + + /// + /// Raises TypeValidationCompleted event. + /// + protected virtual void OnTypeValidationCompleted(TypeValidationEventArgs e) + { + TypeValidationEventHandler eh = TypeValidationCompleted; + if (eh != null) + eh(this, e); + } + + private void MaskedTextBoxTextAlignChanged(object sender, EventArgs e) + { + OnTextAlignChanged(e); + } + /// + /// Raises the TextAlignChanged event. + /// + protected virtual void OnTextAlignChanged(EventArgs e) + { + EventHandler eh = TextAlignChanged; + if (eh != null) + eh(this, e); + } + + private void MaskedTextBoxMaskInputRejected(object sender, MaskInputRejectedEventArgs e) + { + OnMaskInputRejected(e); + } + /// + /// Raises MaskInputRejected event. + /// + /// + protected virtual void OnMaskInputRejected(MaskInputRejectedEventArgs e) + { + MaskInputRejectedEventHandler eh = MaskInputRejected; + if (eh != null) + eh(this, e); + } + + private void MaskedTextBoxMaskChanged(object sender, EventArgs e) + { + OnMaskChanged(e); + } + + /// + /// Raises the MaskChanged event. + /// + protected virtual void OnMaskChanged(EventArgs e) + { + EventHandler eh = MaskChanged; + if (eh != null) + eh(this, e); + } + + void MaskedTextBoxIsOverwriteModeChanged(object sender, EventArgs e) + { + OnIsOverwriteModeChanged(e); + } + + /// + /// Raises IsOverwriteModeChanged event. + /// + protected virtual void OnIsOverwriteModeChanged(EventArgs e) + { + EventHandler eh = IsOverwriteModeChanged; + if (eh != null) + eh(this, e); + } + + private void MaskedTextBoxTextChanged(object sender, EventArgs e) + { + base.Text = _MaskedTextBox.Text; + //OnTextChanged(e); + } + + private ElementStyle _BackgroundStyle = new ElementStyle(); + /// + /// Specifies the background style of the control. + /// + [Category("Style"), Description("Gets or sets control background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return _BackgroundStyle; } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _BackgroundStyle.StyleChanged -= new EventHandler(this.VisualPropertyChanged); + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + this.Invalidate(); + } + + private void VisualPropertyChanged(object sender, EventArgs e) + { + OnVisualPropertyChanged(); + } + + protected virtual void OnVisualPropertyChanged() + { + _ButtonGroup.InvalidateArrange(); + this.Invalidate(); + } + + protected override void Dispose(bool disposing) + { + if (_BackgroundStyle != null) _BackgroundStyle.StyleChanged -= new EventHandler(VisualPropertyChanged); + base.Dispose(disposing); + } + + private InputButtonSettings _ButtonDropDown = null; + /// + /// Gets the object that describes the settings for the button that shows drop-down when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the button that shows drop-down when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonDropDown + { + get + { + return _ButtonDropDown; + } + } + + private InputButtonSettings _ButtonClear = null; + /// + /// Gets the object that describes the settings for the button that clears the content of the control when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the button that clears the content of the control when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonClear + { + get + { + return _ButtonClear; + } + } + + + private InputButtonSettings _ButtonCustom = null; + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get + { + return _ButtonCustom; + } + } + + private InputButtonSettings _ButtonCustom2 = null; + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get + { + return _ButtonCustom2; + } + } + + + void IInputButtonControl.InputButtonSettingsChanged(InputButtonSettings inputButtonSettings) + { + OnInputButtonSettingsChanged(inputButtonSettings); + } + + protected virtual void OnInputButtonSettingsChanged(InputButtonSettings inputButtonSettings) + { + UpdateButtons(); + } + + private VisualGroup _ButtonGroup = null; + private void UpdateButtons() + { + RecreateButtons(); + _ButtonGroup.InvalidateArrange(); + this.Invalidate(); + } + + protected virtual void RecreateButtons() + { + VisualItem[] buttons = CreateOrderedButtonList(); + // Remove all system buttons that are already in the list + VisualGroup group = _ButtonGroup; + VisualItem[] items = new VisualItem[group.Items.Count]; + group.Items.CopyTo(items); + foreach (VisualItem item in items) + { + if (item.ItemType == eSystemItemType.SystemButton) + { + group.Items.Remove(item); + if (item == _ButtonCustom.ItemReference) + item.MouseUp -= new MouseEventHandler(CustomButtonClick); + else if (item == _ButtonCustom2.ItemReference) + item.MouseUp -= new MouseEventHandler(CustomButton2Click); + } + } + + // Add new buttons to the list + group.Items.AddRange(buttons); + } + + private void CustomButtonClick(object sender, MouseEventArgs e) + { + if (_ButtonCustom.ItemReference.RenderBounds.Contains(e.X, e.Y)) + OnButtonCustomClick(e); + } + + protected virtual void OnButtonCustomClick(EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + private void CustomButton2Click(object sender, MouseEventArgs e) + { + if (_ButtonCustom2.ItemReference.RenderBounds.Contains(e.X, e.Y)) + OnButtonCustom2Click(e); + } + + protected virtual void OnButtonCustom2Click(EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + private VisualItem[] CreateOrderedButtonList() + { + SortedList list = CreateSortedButtonList(); + + VisualItem[] items = new VisualItem[list.Count]; + list.Values.CopyTo(items, 0); + + return items; + } + + protected virtual SortedList CreateSortedButtonList() + { + SortedList list = new SortedList(4); + if (_ButtonCustom.Visible) + { + VisualItem button = CreateButton(_ButtonCustom); + if (_ButtonCustom.ItemReference != null) + _ButtonCustom.ItemReference.MouseUp -= new MouseEventHandler(CustomButtonClick); + _ButtonCustom.ItemReference = button; + //button.Click += new EventHandler(CustomButtonClick); + button.MouseUp += new MouseEventHandler(CustomButtonClick); + button.Enabled = _ButtonCustom.Enabled; + list.Add(_ButtonCustom, button); + } + + if (_ButtonCustom2.Visible) + { + VisualItem button = CreateButton(_ButtonCustom2); + if (_ButtonCustom.ItemReference != null) + _ButtonCustom.ItemReference.MouseUp -= new MouseEventHandler(CustomButton2Click); + _ButtonCustom2.ItemReference = button; + //button.Click += new EventHandler(CustomButton2Click); + button.MouseUp += new MouseEventHandler(CustomButton2Click); + button.Enabled = _ButtonCustom2.Enabled; + list.Add(_ButtonCustom2, button); + } + + if (_ButtonClear.Visible) + { + VisualItem button = CreateButton(_ButtonClear); + if (_ButtonClear.ItemReference != null) + _ButtonClear.ItemReference.Click -= new EventHandler(ClearButtonClick); + _ButtonClear.ItemReference = button; + button.MouseUp += new MouseEventHandler(ClearButtonClick); + list.Add(_ButtonClear, button); + } + + if (_ButtonDropDown.Visible) + { + VisualItem button = CreateButton(_ButtonDropDown); + if (_ButtonDropDown.ItemReference != null) + { + _ButtonDropDown.ItemReference.MouseDown -= new MouseEventHandler(DropDownButtonMouseDown); + } + _ButtonDropDown.ItemReference = button; + button.MouseDown += new MouseEventHandler(DropDownButtonMouseDown); + list.Add(_ButtonDropDown, button); + } + + return list; + } + + protected virtual VisualItem CreateButton(InputButtonSettings buttonSettings) + { + VisualItem item = null; + + if (buttonSettings == _ButtonDropDown) + { + item = new VisualDropDownButton(); + ApplyButtonSettings(buttonSettings, item as VisualButton); + } + else + { + item = new VisualCustomButton(); + ApplyButtonSettings(buttonSettings, item as VisualButton); + } + + VisualButton button = item as VisualButton; + button.ClickAutoRepeat = false; + + if (buttonSettings == _ButtonClear) + { + if (buttonSettings.Image == null && string.IsNullOrEmpty(buttonSettings.Text)) + { + //if (Dpi.Factor.Width > 1) + button.Symbol = "\uf00d"; + //else + // button.Image = DevComponents.DotNetBar.BarFunctions.LoadBitmap("SystemImages.DateReset.png"); + } + } + + return item; + } + + protected virtual void ApplyButtonSettings(InputButtonSettings buttonSettings, VisualButton button) + { + button.Text = buttonSettings.Text; + button.Image = buttonSettings.Image; + button.ItemType = eSystemItemType.SystemButton; + button.Enabled = buttonSettings.Enabled; + button.Tooltip = buttonSettings.Tooltip; + button.Shortcut = buttonSettings.Shortcut; + button.Symbol = buttonSettings.Symbol; + button.SymbolSet = buttonSettings.SymbolSet; + button.SymbolColor = buttonSettings.SymbolColor; + } + + private void CreateButtonGroup() + { + VisualGroup group = new VisualGroup(); + group.HorizontalItemSpacing = 0; + group.ArrangeInvalid += new EventHandler(ButtonGroupArrangeInvalid); + group.RenderInvalid += new EventHandler(ButtonGroupRenderInvalid); + group.ResetMouseHover += ButtonGroupRenderMouseHover; + _ButtonGroup = group; + } + + internal VisualGroup ButtonGroup + { + get { return (_ButtonGroup); } + } + + private void ButtonGroupRenderInvalid(object sender, EventArgs e) + { + Invalidate(); + } + + private void ButtonGroupArrangeInvalid(object sender, EventArgs e) + { + Invalidate(); + } + + private void ButtonGroupRenderMouseHover(object sender, EventArgs e) + { + DevComponents.AdvTree.Interop.WinApi.ResetHover(this); + } + + private bool _MouseOver = false; + private PaintInfo CreatePaintInfo(Graphics g) + { + PaintInfo p = new PaintInfo(); + p.Graphics = g; + p.DefaultFont = this.Font; + p.ForeColor = this.ForeColor; + p.RenderOffset = new System.Drawing.Point(); + Size s = this.Size; + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + s.Height -= (ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.BottomWhiteSpace(style, eSpacePart.Border)) + 2; + s.Width -= (ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border)) + 2; + p.AvailableSize = s; + p.ParentEnabled = this.Enabled; + p.MouseOver = _MouseOver || this.Focused; + + if(disposeStyle) style.Dispose(); + + return p; + } + + private ElementStyle GetBackgroundStyle(out bool disposeStyle) + { + _BackgroundStyle.SetColorScheme(this.GetColorScheme()); + disposeStyle = false; + return ElementStyleDisplay.GetElementStyle(_BackgroundStyle, out disposeStyle); + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + Graphics g = e.Graphics; + Rectangle clientRect = this.ClientRectangle; + bool enabled = this.Enabled; + + if (!this.Enabled) + { + if(_DisabledBackColor.IsEmpty) + e.Graphics.FillRectangle(SystemBrushes.Control, clientRect); + else + using(SolidBrush brush=new SolidBrush(_DisabledBackColor)) + e.Graphics.FillRectangle(brush, clientRect); + } + else + { + using (SolidBrush brush = new SolidBrush(this.BackColor)) + e.Graphics.FillRectangle(brush, clientRect); + } + + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + + if (style.Custom) + { + SmoothingMode sm = g.SmoothingMode; + if(this.AntiAlias) + g.SmoothingMode = SmoothingMode.AntiAlias; + ElementStyleDisplayInfo displayInfo = new ElementStyleDisplayInfo(style, g, clientRect); + if (!enabled) + { + ElementStyleDisplay.PaintBorder(displayInfo); + } + else + ElementStyleDisplay.Paint(displayInfo); + if (this.AntiAlias) + g.SmoothingMode = sm; + } + + PaintButtons(g); + + if(disposeStyle) style.Dispose(); + } + + + public override Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColor() + { + return this.BackColor != SystemColors.Window; + } + + protected override void OnBackColorChanged(EventArgs e) + { + base.OnBackColorChanged(e); + _MaskedTextBox.BackColor = this.BackColor; + } + + private void PaintButtons(Graphics g) + { + PaintInfo p = CreatePaintInfo(g); + + if (!_ButtonGroup.IsLayoutValid) + { + UpdateLayout(p); + } + + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + //p.RenderOffset = new Point(this.Width - ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border) - _ButtonGroup.Size.Width, ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border)); + _ButtonGroup.RenderBounds = GetButtonsRenderBounds(style); + _ButtonGroup.ProcessPaint(p); + + if(disposeStyle) style.Dispose(); + } + + private Rectangle GetButtonsRenderBounds(ElementStyle style) + { + if (this.RightToLeft == RightToLeft.Yes) + { + return new Rectangle((ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + 1), ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + 1, + _ButtonGroup.Size.Width, _ButtonGroup.Size.Height); + } + + return new Rectangle(this.Width - (ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border) + 1) - _ButtonGroup.Size.Width, ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + 1, + _ButtonGroup.Size.Width, _ButtonGroup.Size.Height); + } + + protected override void OnResize(EventArgs e) + { + _ButtonGroup.InvalidateArrange(); + UpdateLayout(); + this.Invalidate(); + base.OnResize(e); + } + + protected override void OnGotFocus(EventArgs e) + { + _MaskedTextBox.Focus(); + base.OnGotFocus(e); + } + + protected override void OnRightToLeftChanged(EventArgs e) + { + _ButtonGroup.InvalidateArrange(); + UpdateLayout(); + this.Invalidate(); + base.OnRightToLeftChanged(e); + } + + protected override void OnFontChanged(EventArgs e) + { + _ButtonGroup.InvalidateArrange(); + UpdateLayout(); + this.Invalidate(); + base.OnFontChanged(e); + } + + private void UpdateLayout() + { + using(Graphics g = BarFunctions.CreateGraphics(this)) + UpdateLayout(CreatePaintInfo(g)); + } + + private bool _InternalSizeUpdate = false; + private void UpdateLayout(PaintInfo p) + { + if (_InternalSizeUpdate) return; + + _InternalSizeUpdate = true; + + try + { + if (!_ButtonGroup.IsLayoutValid) + { + _ButtonGroup.PerformLayout(p); + } + + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + Rectangle maskedControlRect = ElementStyleLayout.GetInnerRect(style, this.ClientRectangle); + if (RenderButtons) + { + Rectangle buttonsRect = GetButtonsRenderBounds(style); + if (this.RightToLeft == RightToLeft.Yes) + { + maskedControlRect.X += buttonsRect.Right; + maskedControlRect.Width -= buttonsRect.Right; + } + else + { + maskedControlRect.Width -= (maskedControlRect.Right - buttonsRect.X); + } + } + if (_MaskedTextBox.PreferredHeight < maskedControlRect.Height) + { + maskedControlRect.Y += (maskedControlRect.Height - _MaskedTextBox.PreferredHeight) / 2; + } + _MaskedTextBox.Bounds = maskedControlRect; + + if(disposeStyle) style.Dispose(); + } + finally + { + _InternalSizeUpdate = false; + } + } + + private Control _PreviousDropDownControlParent = null; + private void DropDownButtonMouseDown(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Left || _CloseTime != DateTime.MinValue && DateTime.Now.Subtract(_CloseTime).TotalMilliseconds < 250) + { + _CloseTime = DateTime.MinValue; + return; + } + + ShowDropDown(); + } + + private bool _ShowingPopup = false; + /// + /// Shows drop-down popup. Note that popup will be shown only if there is a DropDownControl assigned or DropDownItems collection has at least one item. + /// + public void ShowDropDown() + { + + if (_DropDownControl == null && _PopupItem.SubItems.Count == 0 || _ShowingPopup || _PopupItem.Expanded) + return; + + _ShowingPopup = true; + try + { + ControlContainerItem cc = null; + ItemContainer ic = null; + if (_DropDownControl != null) + { + ic = new ItemContainer(); + ic.Name = _DropDownItemContainerName; + cc = new ControlContainerItem(_DropDownControlContainerName); + ic.SubItems.Add(cc); + _PopupItem.SubItems.Insert(0, ic); + } + + CancelEventArgs cancelArgs = new CancelEventArgs(); + OnButtonDropDownClick(cancelArgs); + if (cancelArgs.Cancel || _PopupItem.SubItems.Count == 0) + { + if (ic != null) + _PopupItem.SubItems.Remove(ic); + return; + } + + if (_DropDownControl != null) + { + _PreviousDropDownControlParent = _DropDownControl.Parent; + cc.Control = _DropDownControl; + } + + _PopupItem.SetDisplayRectangle(this.ClientRectangle); + if (this.RightToLeft == RightToLeft.No) + { + Point pl = new Point(this.Width - _PopupItem.PopupSize.Width, this.Height); + ScreenInformation screen = BarFunctions.ScreenFromControl(this); + Point ps = PointToScreen(pl); + if (screen != null && screen.WorkingArea.X > ps.X) + { + pl.X = 0; + } + _PopupItem.PopupLocation = pl; + } + + _PopupItem.Expanded = !_PopupItem.Expanded; + } + finally + { + _ShowingPopup = false; + } + } + + /// + /// Closes the drop-down popup if it is open. + /// + public void CloseDropDown() + { + if (_PopupItem.Expanded) _PopupItem.Expanded = false; + } + + private DateTime _CloseTime = DateTime.MinValue; + private void DropDownPopupClose(object sender, EventArgs e) + { + _CloseTime = DateTime.Now; + if (_PopupItem.SubItems.Contains(_DropDownItemContainerName)) + { + ItemContainer ic = _PopupItem.SubItems[_DropDownItemContainerName] as ItemContainer; + if (ic != null) + { + ControlContainerItem cc = ic.SubItems[_DropDownControlContainerName] as ControlContainerItem; + if (cc != null) + { + cc.Control = null; + ic.SubItems.Remove(cc); + if (_DropDownControl != null) + { + _DropDownControl.Parent = _PreviousDropDownControlParent; + _PreviousDropDownControlParent = null; + } + } + _PopupItem.SubItems.Remove(ic); + } + } + } + + private void ClearButtonClick(object sender, EventArgs e) + { + CancelEventArgs cancelArgs = new CancelEventArgs(); + OnButtonClearClick(cancelArgs); + if (cancelArgs.Cancel) return; + + _MaskedTextBox.Text = ""; + } + + /// + /// Raises the ButtonClearClick event. + /// + /// + protected virtual void OnButtonClearClick(CancelEventArgs e) + { + if (ButtonClearClick != null) + ButtonClearClick(this, e); + } + + /// + /// Raises the ButtonDropDownClick event. + /// + /// + protected virtual void OnButtonDropDownClick(CancelEventArgs e) + { + if (ButtonDropDownClick != null) + ButtonDropDownClick(this, e); + } + + private Control _DropDownControl = null; + /// + /// Gets or sets the reference of the control that will be displayed on popup that is shown when drop-down button is clicked. + /// + [DefaultValue(null), Description("Indicates reference of the control that will be displayed on popup that is shown when drop-down button is clicked.")] + public Control DropDownControl + { + get { return _DropDownControl; } + set + { + _DropDownControl = value; + } + } + + protected override PopupItem CreatePopupItem() + { + ButtonItem button = new ButtonItem("sysPopupProvider"); + button.PopupFinalized += new EventHandler(DropDownPopupClose); + _PopupItem = button; + return button; + } + + /// + /// Gets the collection of BaseItem derived items displayed on popup menu. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SubItemsCollection DropDownItems + { + get { return _PopupItem.SubItems; } + } + + protected override void RecalcSize() + { + } + + public override void PerformClick() + { + } + + private bool RenderButtons + { + get + { + return _ButtonCustom != null && _ButtonCustom.Visible || _ButtonCustom2 != null && _ButtonCustom2.Visible || + _ButtonDropDown != null && _ButtonDropDown.Visible || _ButtonClear != null && _ButtonClear.Visible; + } + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseMove(e); + } + base.OnMouseMove(e); + } + protected override void OnMouseHover(EventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseHover(e); + } + base.OnMouseHover(e); + } + protected override void OnMouseLeave(EventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseLeave(); + } + base.OnMouseLeave(e); + } + protected override void OnMouseDown(MouseEventArgs e) + { + if (RenderButtons) + _ButtonGroup.ProcessMouseDown(e); + base.OnMouseDown(e); + } + protected override void OnMouseUp(MouseEventArgs e) + { + if (RenderButtons) + _ButtonGroup.ProcessMouseUp(e); + base.OnMouseUp(e); + } + + protected override void OnForeColorChanged(EventArgs e) + { + if (_MaskedTextBox != null) _MaskedTextBox.ForeColor = this.ForeColor; + base.OnForeColorChanged(e); + } + + /// + /// Gets the reference to internal MaskedTextBox control. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public MaskedTextBox MaskedTextBox + { + get + { + return _MaskedTextBox; + } + } + + private bool _WatermarkEnabled = true; + /// + /// Gets or sets whether watermark text is displayed when control is empty. Default value is true. + /// + [DefaultValue(true), Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return _WatermarkEnabled; } + set { _WatermarkEnabled = value; this.Invalidate(true); } + } + + /// + /// Gets or sets the watermark (tip) text displayed inside of the control when Text is not set and control does not have input focus. This property supports text-markup. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus."), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string WatermarkText + { + get { return _WatermarkText; } + set + { + if (value == null) value = ""; + _WatermarkText = value; + MarkupTextChanged(); + this.Invalidate(true); + } + } + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark font."), DefaultValue(null)] + public Font WatermarkFont + { + get { return _WatermarkFont; } + set { _WatermarkFont = value; this.Invalidate(true); } + } + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return _WatermarkColor; } + set { _WatermarkColor = value; this.Invalidate(); } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return _WatermarkColor != SystemColors.GrayText; + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + this.WatermarkColor = SystemColors.GrayText; + } + + private eWatermarkBehavior _WatermarkBehavior = eWatermarkBehavior.HideOnFocus; + /// + /// Gets or sets the watermark hiding behaviour. Default value indicates that watermark is hidden when control receives input focus. + /// + [DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior"), Description("Indicates watermark hiding behaviour.")] + public eWatermarkBehavior WatermarkBehavior + { + get { return _WatermarkBehavior; } + set { _WatermarkBehavior = value; this.Invalidate(); } + } + + private TextMarkup.BodyElement _TextMarkup = null; + private void MarkupTextChanged() + { + _TextMarkup = null; + + if (!TextMarkup.MarkupParser.IsMarkup(ref _WatermarkText)) + return; + + _TextMarkup = TextMarkup.MarkupParser.Parse(_WatermarkText); + ResizeMarkup(); + } + + private void ResizeMarkup() + { + if (_TextMarkup != null) + { + using (Graphics g = this.CreateGraphics()) + { + MarkupDrawContext dc = GetMarkupDrawContext(g); + _TextMarkup.Measure(GetWatermarkBounds().Size, dc); + Size sz = _TextMarkup.Bounds.Size; + _TextMarkup.Arrange(new Rectangle(GetWatermarkBounds().Location, sz), dc); + } + } + } + + private Rectangle GetWatermarkBounds() + { + Rectangle r = this.ClientRectangle; + r.Inflate(-1, 0); + return r; + } + + private MarkupDrawContext GetMarkupDrawContext(Graphics g) + { + return new MarkupDrawContext(g, (_WatermarkFont == null ? this.Font : _WatermarkFont), _WatermarkColor, this.RightToLeft == RightToLeft.Yes); + } + #endregion + + #region Masked Edit Property Forwarding + /// + /// Gets or sets a value indicating whether PromptChar can be entered as valid data by the user. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether PromptChar can be entered as valid data by the user")] + public bool AllowPromptAsInput + { + get + { + return _MaskedTextBox.AllowPromptAsInput; + } + set + { + _MaskedTextBox.AllowPromptAsInput=value; + } + } + + /// + /// Gets or sets a value indicating whether the MaskedTextBox control accepts characters outside of the ASCII character set. + /// true if only ASCII is accepted; false if the MaskedTextBox control can accept any arbitrary Unicode character. The default is false. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether the MaskedTextBox control accepts characters outside of the ASCII character set"), RefreshProperties(RefreshProperties.Repaint)] + public bool AsciiOnly + { + get + { + return _MaskedTextBox.AsciiOnly; + } + set + { + _MaskedTextBox.AsciiOnly = value; + } + } + + /// + /// Gets or sets a value indicating whether the masked text box control raises the system beep for each user key stroke that it rejects. + /// + [Description("Indicates whether the masked text box control raises the system beep for each user key stroke that it rejects"), DefaultValue(false), Category("Behavior")] + public bool BeepOnError + { + get + { + return _MaskedTextBox.BeepOnError; + } + set + { + _MaskedTextBox.BeepOnError = value; + } + } + + /// + /// Gets or sets the culture information associated with the masked text box. + /// + [Description("Indicates culture information associated with the masked text box."), Category("Behavior"), RefreshProperties(RefreshProperties.Repaint)] + public CultureInfo Culture + { + get + { + return _MaskedTextBox.Culture; + } + set + { + _MaskedTextBox.Culture = value; + } + } + /// + /// Gets whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCulture() + { + return !CultureInfo.CurrentCulture.Equals(this.Culture); + } + + /// + /// Gets or sets a value that determines whether literals and prompt characters are copied to the clipboard. + /// + [DefaultValue(2), Category("Behavior"), Description("Indicates a value that determines whether literals and prompt characters are copied to the clipboard"), RefreshProperties(RefreshProperties.Repaint)] + public MaskFormat CutCopyMaskFormat + { + get { return _MaskedTextBox.CutCopyMaskFormat; } + set + { + _MaskedTextBox.CutCopyMaskFormat = value; + } + } + + /// + /// Gets or sets the IFormatProvider to use when performing type validation. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public IFormatProvider FormatProvider + { + get + { + return _MaskedTextBox.FormatProvider; + } + set + { + _MaskedTextBox.FormatProvider = value; + } + } + + /// + /// Gets or sets a value indicating whether the prompt characters in the input mask are hidden when the masked text box loses focus. + /// + [Description("Indicates whether the prompt characters in the input mask are hidden when the masked text box loses focus."), RefreshProperties(RefreshProperties.Repaint), DefaultValue(false), Category("Behavior")] + public bool HidePromptOnLeave + { + get + { + return _MaskedTextBox.HidePromptOnLeave; + } + set + { + _MaskedTextBox.HidePromptOnLeave = value; + } + } + + /// + /// Gets or sets the text insertion mode of the masked text box control. + /// + [DefaultValue(0), Description("Indicates text insertion mode of the masked text box control."), Category("Behavior")] + public InsertKeyMode InsertKeyMode + { + get + { + return _MaskedTextBox.InsertKeyMode; + } + set + { + _MaskedTextBox.InsertKeyMode = value; + } + } + + /// + /// Gets or sets the input mask to use at run time. The default value is the empty string which allows any input + /// + [RefreshProperties(RefreshProperties.Repaint), Editor("DevComponents.DotNetBar.Design.MaskAdvPropertyEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor)), Description("Indicates input mask to use at run time."), MergableProperty(false), Category("Behavior"), DefaultValue(""), Localizable(true)] + public string Mask + { + get + { + return _MaskedTextBox.Mask; + } + set + { + _MaskedTextBox.Mask = value; + } + } + + /// + /// Gets a value indicating whether all required inputs have been entered into the input mask. Returns true if all required input has been entered into the mask; otherwise, false. + /// + [Browsable(false)] + public bool MaskCompleted + { + get + { + return _MaskedTextBox.MaskCompleted; + } + } + + /// + /// Gets a clone of the mask provider associated with this instance of the masked text box control. Returns masking language provider of type MaskedTextProvider. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public MaskedTextProvider MaskedTextProvider + { + get + { + return _MaskedTextBox.MaskedTextProvider; + } + } + + /// + /// Gets a value indicating whether all required and optional inputs have been entered into the input mask. Returns true if all required and optional inputs have been entered; otherwise, false. + /// + [Browsable(false)] + public bool MaskFull + { + get + { + return _MaskedTextBox.MaskFull; + } + } + + /// + /// Gets or sets the character to be displayed in substitute for user input. + /// + [DefaultValue('\0'), Category("Behavior"), RefreshProperties(RefreshProperties.Repaint), Description("Indicates character to be displayed in substitute for user input.")] + public char PasswordChar + { + get + { + return _MaskedTextBox.PasswordChar; + } + set + { + _MaskedTextBox.PasswordChar = value; + } + } + + /// + /// Gets or sets the character used to represent the absence of user input in MaskedTextBox. Returns character used to prompt the user for input. The default is an underscore (_). + /// + [Category("Appearance"), Localizable(true), DefaultValue('_'), RefreshProperties(RefreshProperties.Repaint), Description("Indicates character used to represent the absence of user input in MaskedTextBox.")] + public char PromptChar + { + get + { + return _MaskedTextBox.PromptChar; + } + set + { + _MaskedTextBox.PromptChar = value; + } + } + + /// + /// Gets or sets whether text in control is read only. Default value is false. + /// + [DefaultValue(false), Description("Indicates whether text in control is read only."), Category("Behavior")] + public bool ReadOnly + { + get + { + return _MaskedTextBox.ReadOnly; + } + set + { + _MaskedTextBox.ReadOnly = value; + } + } + + /// + /// Gets or sets a value indicating whether the parsing of user input should stop after the first invalid character is reached. Returns true if processing of the input string should be terminated at the first parsing error; otherwise, false if processing should ignore all errors. The default is false. + /// + [Description("Indicates whether the parsing of user input should stop after the first invalid character is reached."), DefaultValue(false), Category("Behavior")] + public bool RejectInputOnFirstFailure + { + get + { + return _MaskedTextBox.RejectInputOnFirstFailure; + } + set + { + _MaskedTextBox.RejectInputOnFirstFailure = value; + } + } + + + /// + /// Gets or sets a value that determines how an input character that matches the prompt character should be handled. Returns true if the prompt character entered as input causes the current editable position in the mask to be reset; otherwise, false to indicate that the prompt character is to be processed as a normal input character. The default is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates value that determines how an input character that matches the prompt character should be handled.")] + public bool ResetOnPrompt + { + get + { + return _MaskedTextBox.ResetOnPrompt; + } + set + { + _MaskedTextBox.ResetOnPrompt = value; + } + } + + /// + /// Gets or sets a value that determines how a space input character should be handled. Returns true if the space input character causes the current editable position in the mask to be reset; otherwise, false to indicate that it is to be processed as a normal input character. The default is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates value that determines how a space input character should be handled.")] + public bool ResetOnSpace + { + get + { + return _MaskedTextBox.ResetOnSpace; + } + set + { + _MaskedTextBox.ResetOnSpace = value; + } + } + + /// + /// Gets or sets a value indicating the currently selected text in the control. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public virtual string SelectedText + { + get + { + return _MaskedTextBox.SelectedText; + } + set + { + _MaskedTextBox.SelectedText = value; + } + } + + /// + /// Gets or sets the number of characters selected in the text box. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual int SelectionLength + { + get + { + return _MaskedTextBox.SelectionLength; + } + set + { + _MaskedTextBox.SelectionLength = value; + } + } + + /// + /// Gets or sets the starting point of text selected in the text box. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public int SelectionStart + { + get + { + return _MaskedTextBox.SelectionStart; + } + set + { + _MaskedTextBox.SelectionStart = value; + } + } + + /// + /// Gets or sets a value indicating whether the defined shortcuts are enabled. + /// + [Description("Indicates whether the defined shortcuts are enabled."), Category("Behavior"), DefaultValue(true)] + public virtual bool ShortcutsEnabled + { + get + { + return _MaskedTextBox.ShortcutsEnabled; + } + set + { + _MaskedTextBox.ShortcutsEnabled = value; + } + } + + [Description("MaskedTextBoxSkipLiterals"), Category("CatBehavior"), DefaultValue(true)] + public bool SkipLiterals + { + get + { + return _MaskedTextBox.SkipLiterals; + } + set + { + _MaskedTextBox.SkipLiterals = value; + } + } + + /// + /// Gets or sets the text as it is currently displayed to the user. + /// + [Category("Appearance"), DefaultValue("Indicates text as it is currently displayed to the user"), Bindable(true), RefreshProperties(RefreshProperties.Repaint), Editor("System.Windows.Forms.Design.MaskedTextBoxTextEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Localizable(true)] + public override string Text + { + get + { + return base.Text; + } + set + { + _MaskedTextBox.Text = value; + } + } + + /// + /// Gets or sets how text is aligned in a masked text box control. + /// + [DefaultValue(0), Localizable(true), Description("Indicates how text is aligned in a masked text box control."), Category("Appearance")] + public HorizontalAlignment TextAlign + { + get + { + return _MaskedTextBox.TextAlign; + } + set + { + _MaskedTextBox.TextAlign = value; + } + } + + /// + /// Gets the length of the displayed text. + /// + [Browsable(false)] + public virtual int TextLength + { + get + { + return _MaskedTextBox.TextLength; + } + } + + /// + /// Gets or sets a value that determines whether literals and prompt characters are included in the formatted string. + /// + [Category("Behavior"), RefreshProperties(RefreshProperties.Repaint), DefaultValue(2), Description("Indicates a value that determines whether literals and prompt characters are included in the formatted string.")] + public MaskFormat TextMaskFormat + { + get + { + return _MaskedTextBox.TextMaskFormat; + } + set + { + _MaskedTextBox.TextMaskFormat = value; + } + } + + /// + /// Gets or sets a value indicating whether the operating system-supplied password character should be used. + /// + [DefaultValue(false), RefreshProperties(RefreshProperties.Repaint), Category("Behavior"), Description("Indicates whether the operating system-supplied password character should be used")] + public bool UseSystemPasswordChar + { + get + { + return _MaskedTextBox.UseSystemPasswordChar; + } + set + { + _MaskedTextBox.UseSystemPasswordChar = value; + } + } + + /// + /// Gets or sets the data type used to verify the data input by the user. Returns Type representing the data type used in validation. The default is null. + /// + [DefaultValue((string)null), Browsable(false)] + public Type ValidatingType + { + get + { + return _MaskedTextBox.ValidatingType; + } + set + { + _MaskedTextBox.ValidatingType = value; + } + } + + /// + /// Converts the user input string to an instance of the validating type. + /// + /// If successful, an Object of the type specified by the ValidatingType property; otherwise, null to indicate conversion failure. + public object ValidateText() + { + return _MaskedTextBox.ValidateText(); + } + + /// + /// Returns a string that represents the current masked text box. This method overrides ToString. + /// + /// A String that contains information about the current MaskedTextBox. The string includes the type, a simplified view of the input string, and the formatted input string. + public override string ToString() + { + return _MaskedTextBox.ToString(); + } + + /// + /// Gets the preferred height for a masked text box. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] + public int PreferredHeight + { + get + { + int height = _MaskedTextBox.PreferredHeight; + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + height += ElementStyleLayout.VerticalStyleWhiteSpace(style); + if (disposeStyle) + { + style.Dispose(); + } + return height; + } + } + + public override Size GetPreferredSize(Size proposedSize) + { + Size ps = _MaskedTextBox.GetPreferredSize(proposedSize); + ps.Height = PreferredHeight; + return ps; + } + #endregion + + #region Masked Edit Custom + private class MaskedTextBoxInternal : MaskedTextBox + { + private bool _IgnoreFocus = false; + private bool _Focused = false; + private Color _LastBackColor = Color.Empty; + + private bool RenderWatermark + { + get + { + MaskedTextBoxAdv parent = MaskedTextBoxAdv; + if (parent == null) return false; + + if (!parent.WatermarkEnabled) + return false; + if (parent.WatermarkBehavior == eWatermarkBehavior.HideOnFocus) + return !_Focused && this.Enabled && this.Text != null && this.Text.Length == 0 && parent.WatermarkText.Length > 0; + else + return this.Enabled && this.Text != null && this.Text.Length == 0 && parent.WatermarkText.Length > 0; + } + } + + private void DrawWatermark() + { + MaskedTextBoxAdv parent = MaskedTextBoxAdv; + if (parent == null) return; + + using (Graphics g = this.CreateGraphics()) + { + if (parent._TextMarkup != null) + { + MarkupDrawContext dc = parent.GetMarkupDrawContext(g); + parent._TextMarkup.Render(dc); + } + else + { + eTextFormat format = eTextFormat.Left; + + if (this.RightToLeft == RightToLeft.Yes) format |= eTextFormat.RightToLeft; + if (this.TextAlign == HorizontalAlignment.Left) + format |= eTextFormat.Left; + else if (this.TextAlign == HorizontalAlignment.Right) + format |= eTextFormat.Right; + else if (this.TextAlign == HorizontalAlignment.Center) + format |= eTextFormat.HorizontalCenter; + format |= eTextFormat.EndEllipsis; + format |= eTextFormat.WordBreak; + TextDrawing.DrawString(g, parent.WatermarkText, (parent.WatermarkFont == null ? this.Font : parent.WatermarkFont), + parent.WatermarkColor, parent.GetWatermarkBounds(), format); + } + } + } + + protected override void OnTextChanged(EventArgs e) + { + base.OnTextChanged(e); + + MaskedTextBoxAdv parent = MaskedTextBoxAdv; + if (parent == null) return; + if (parent.WatermarkText.Length > 0) + this.Invalidate(); + } + + protected override void WndProc(ref Message m) + { + base.WndProc(ref m); + MaskedTextBoxAdv parent = MaskedTextBoxAdv; + if (parent == null) return; + + switch (m.Msg) + { + //case (int)WinApi.WindowsMessages.WM_NCPAINT: + // { + // if (!this.Enabled && this.Parent is MaskedTextBoxAdv && !((MaskedTextBoxAdv)this.Parent).DisabledBackColor.IsEmpty) + // { + // Rectangle r = this.ClientRectangle; + // IntPtr dc = WinApi.GetWindowDC(this.Handle); + // try + // { + // using (Graphics g = Graphics.FromHdc(dc)) + // { + // using (SolidBrush brush = new SolidBrush(this.BackColor)) + // g.FillRectangle(brush, 0, 0, this.Width, this.Height); + // } + // } + // finally + // { + // WinApi.ReleaseDC(this.Handle, dc); + // } + // } + // break; + // } + case (int)WinApi.WindowsMessages.WM_SETFOCUS: + { + if (_IgnoreFocus) + { + _IgnoreFocus = false; + } + else + { + _Focused = true; + if (parent.FocusHighlightEnabled && this.Enabled) + { + _LastBackColor = this.BackColor; + this.BackColor = parent.FocusHighlightColor; + parent.BackColor = parent.FocusHighlightColor; + parent.Invalidate(true); + } + } + break; + } + case (int)WinApi.WindowsMessages.WM_KILLFOCUS: + { + if (!_Focused) + { + _IgnoreFocus = true; + } + else + { + _Focused = false; + if (this.Text == null || this.Text.Length == 0) + parent.Invalidate(true); + if (parent.FocusHighlightEnabled && !_LastBackColor.IsEmpty) + { + this.BackColor = _LastBackColor; + parent.BackColor = _LastBackColor; + parent.Invalidate(true); + } + } + break; + } + case (int)WinApi.WindowsMessages.WM_PAINT: + { + if (RenderWatermark) + DrawWatermark(); + break; + } + } + } + + private MaskedTextBoxAdv MaskedTextBoxAdv + { + get + { + return Parent as MaskedTextBoxAdv; + } + } + } + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + CommandManager.ExecuteCommand(this); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + } + } + + private ICommand _Command = null; + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if (changed) + OnCommandChanged(); + } + } + + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + } + } + + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/MaskedTextBoxAdv.ico b/PROMS/DotNetBar Source Code/Controls/MaskedTextBoxAdv.ico new file mode 100644 index 00000000..47ebea51 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/MaskedTextBoxAdv.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/NonClientHook.cs b/PROMS/DotNetBar Source Code/Controls/NonClientHook.cs new file mode 100644 index 00000000..b71f6cda --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/NonClientHook.cs @@ -0,0 +1,249 @@ +using System; +using System.Windows.Forms; +using System.Collections; +using System.Threading; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for MessageHandler. + /// + internal class NonClientHook + { + private static ArrayList m_Clients = new ArrayList(); + private static Hashtable m_FilterOnThread = new Hashtable(); + private static ReaderWriterLock rwClientsListLock; + private static MouseProc m_MouseHook = null; + + private delegate IntPtr MouseProc(int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr SetWindowsHookEx(int hookid, MouseProc pfnhook, IntPtr hinst, int threadid); + + //[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, EntryPoint = "SetWindowsHookEx")] + //private static extern IntPtr SetWindowsHookExKeyboard(int hookid, KeyboardProc pfnhook, IntPtr hinst, int threadid); + + [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] + private static extern bool UnhookWindowsHookEx(IntPtr hhook); + + [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] + private static extern IntPtr CallNextHookEx(IntPtr hhook, int code, IntPtr wparam, IntPtr lparam); + [DllImport("kernel32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] + private static extern int GetCurrentThreadId(); + + private const int WH_MOUSE = 7; + private const int HC_ACTION = 0; + private const int WH_CALLWNDPROCRET = 12; + private const int WH_CALLWNDPROC = 4; + + // Methods + static NonClientHook() + { + NonClientHook.rwClientsListLock = new ReaderWriterLock(); + m_MouseHook = new MouseProc(OnMouseHook); + } + + public static void RegisterHook(ISkinHook client) + { + if (m_Clients.Contains(client)) + return; + + if (!m_FilterOnThread.ContainsKey(System.Threading.Thread.CurrentThread.GetHashCode())) + HookThread(); + + LockCookie cookie1 = new LockCookie(); + bool readerLockHeld = NonClientHook.rwClientsListLock.IsReaderLockHeld; + + if (readerLockHeld) + { + cookie1 = NonClientHook.rwClientsListLock.UpgradeToWriterLock(-1); + } + else + { + NonClientHook.rwClientsListLock.AcquireWriterLock(-1); + } + + try + { + m_Clients.Add(client); + } + finally + { + if (readerLockHeld) + { + NonClientHook.rwClientsListLock.DowngradeFromWriterLock(ref cookie1); + } + else + { + NonClientHook.rwClientsListLock.ReleaseWriterLock(); + } + } + } + + public static void UnregisterHook(ISkinHook client) + { + if (m_Clients.Contains(client)) + { + LockCookie cookie1 = new LockCookie(); + bool readerLockHeld = NonClientHook.rwClientsListLock.IsReaderLockHeld; + + if (readerLockHeld) + { + cookie1 = NonClientHook.rwClientsListLock.UpgradeToWriterLock(-1); + } + else + { + NonClientHook.rwClientsListLock.AcquireWriterLock(-1); + } + + try + { + m_Clients.Remove(client); + if (m_Clients.Count == 0) + UnHookThread(); + } + finally + { + if (readerLockHeld) + { + NonClientHook.rwClientsListLock.DowngradeFromWriterLock(ref cookie1); + } + else + { + NonClientHook.rwClientsListLock.ReleaseWriterLock(); + } + } + } + } + + private static void HookThread() + { + if (m_FilterOnThread.ContainsKey(System.Threading.Thread.CurrentThread.GetHashCode())) + return; + + int id = GetCurrentThreadId(); + IntPtr hook = SetWindowsHookEx(WH_MOUSE, m_MouseHook, IntPtr.Zero, id); + m_FilterOnThread.Add(System.Threading.Thread.CurrentThread.GetHashCode(), hook); + } + + private static void UnHookThread() + { + if (!m_FilterOnThread.ContainsKey(System.Threading.Thread.CurrentThread.GetHashCode())) + return; + IntPtr hook = (IntPtr)m_FilterOnThread[System.Threading.Thread.CurrentThread.GetHashCode()]; + UnhookWindowsHookEx(hook); + m_FilterOnThread.Remove(System.Threading.Thread.CurrentThread.GetHashCode()); + } + + private static ISkinHook[] GetMessageClients() + { + ISkinHook[] messageClients; + NonClientHook.rwClientsListLock.AcquireReaderLock(-1); + try + { + messageClients = (ISkinHook[])m_Clients.ToArray(typeof(ISkinHook)); + } + finally + { + NonClientHook.rwClientsListLock.ReleaseReaderLock(); + } + + return messageClients; + } + + private static unsafe IntPtr OnMouseHook(int nCode, IntPtr wParam, IntPtr lParam) + { + try + { + if (nCode == HC_ACTION) + { + int wParamInt = WinApi.ToInt(wParam); + if (wParamInt == (int)WinApi.WindowsMessages.WM_MOUSEMOVE) + { + MOUSEHOOKSTRUCT* ws = (MOUSEHOOKSTRUCT*)lParam; + PostMouseMove(ws->hwnd, ws->pt.ToPoint()); + } + if (wParamInt == (int)WinApi.WindowsMessages.WM_LBUTTONUP) + { + MOUSEHOOKSTRUCT* ws = (MOUSEHOOKSTRUCT*)lParam; + PostMouseUp(ws->hwnd, ws->pt.ToPoint()); + } + //CWPRETSTRUCT* ws = (CWPRETSTRUCT*)lParam; + //if (ws->message == (uint)WinApi.WindowsMessages.WM_MOUSEMOVE || ws->message == 0x118) + //{ + // PostMouseMove(ws->hwnd, ws->wParam, ws->lParam); + //} + + } + + + + IntPtr h = (IntPtr)m_FilterOnThread[System.Threading.Thread.CurrentThread.GetHashCode()]; + IntPtr res = CallNextHookEx(h, nCode, wParam, lParam); + + return res; + } + catch + { } + return IntPtr.Zero; + } + + public static bool PostMouseMove(IntPtr hWnd, Point mousePos) + { + ISkinHook[] messageClients = GetMessageClients(); + foreach (ISkinHook client in messageClients) + { + client.PostMouseMove(hWnd, mousePos); + } + return false; + } + + public static bool PostMouseUp(IntPtr hWnd, Point mousePos) + { + ISkinHook[] messageClients = GetMessageClients(); + foreach (ISkinHook client in messageClients) + { + client.PostMouseUp(hWnd, mousePos); + } + return false; + } + + private struct POINT + { + public POINT(int x, int y) + { + this.x = x; + this.y = y; + } + public int x; + public int y; + + public Point ToPoint() + { + return new Point(x, y); + } + } + private struct MOUSEHOOKSTRUCT + { + public MOUSEHOOKSTRUCT(POINT pt, IntPtr hwnd, ushort wHitTestCode, IntPtr dwExtraInfo) + { + this.pt = pt; + this.hwnd = hwnd; + this.wHitTestCode = wHitTestCode; + this.dwExtraInfo = dwExtraInfo; + } + public POINT pt; + public IntPtr hwnd; + public ushort wHitTestCode; + public IntPtr dwExtraInfo; + } + } + + internal interface ISkinHook + { + void PostMouseMove(IntPtr hWnd, Point mousePos); + void PostMouseUp(IntPtr hWnd, Point mousePos); + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/NonClientPaintHandler.cs b/PROMS/DotNetBar Source Code/Controls/NonClientPaintHandler.cs new file mode 100644 index 00000000..1917f63b --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/NonClientPaintHandler.cs @@ -0,0 +1,1236 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Runtime.InteropServices; +using DevComponents.DotNetBar.ScrollBar; + +namespace DevComponents.DotNetBar.Controls +{ + internal class NonClientPaintHandler : ISkinHook + { + #region Private Variables + private INonClientControl m_Control = null; + private Rectangle m_ClientRectangle = Rectangle.Empty; + private ScrollBarCore m_VScrollBar = null; + private ScrollBarCore m_HScrollBar = null; + private const int HC_ACTION = 0; + private eScrollBarSkin m_SkinScrollbars = eScrollBarSkin.Optimized; + private bool m_SuspendPaint = false; + private bool m_IsVista = false; + private bool m_IsListView = false; + private bool m_IsAppScrollBarStyle = false; + #endregion + + #region Events + public event CustomNCPaintEventHandler BeforeBorderPaint; + public event CustomNCPaintEventHandler AfterBorderPaint; + #endregion + + #region Internal Implementation + public bool IsAppScrollBarStyle + { + get { return m_IsAppScrollBarStyle; } + set { m_IsAppScrollBarStyle = value; } + } + + public NonClientPaintHandler(INonClientControl c, eScrollBarSkin skinScrollbars) + { + m_IsVista = System.Environment.OSVersion.Version.Major >= 6; + //#if DEBUG + // m_IsVista = false; + //#endif + m_SkinScrollbars = skinScrollbars; + m_Control = c; + if (m_Control is Control) + { + ((Control)m_Control).HandleCreated += new EventHandler(Control_HandleCreated); + ((Control)m_Control).HandleDestroyed += new EventHandler(Control_HandleDestroyed); + } + m_IsListView = m_Control is ListView; + if (ShouldSkinScrollbars) + { + CreateScrollbars(); + } + if (m_Control.IsHandleCreated && ShouldSkinScrollbars) + RegisterHook(); + } + + private bool ShouldSkinScrollbars + { + get { return m_SkinScrollbars != eScrollBarSkin.None && !m_IsVista; } + } + + public void Dispose() + { + UnRegisterHook(); + } + + private void CreateScrollbars() + { + m_VScrollBar = new ScrollBarCore(m_Control as Control, true); + m_VScrollBar.IsAppScrollBarStyle = m_IsAppScrollBarStyle; + m_HScrollBar = new ScrollBarCore(m_Control as Control, true); + m_HScrollBar.IsAppScrollBarStyle = m_IsAppScrollBarStyle; + m_HScrollBar.Orientation = eOrientation.Horizontal; + m_HScrollBar.Enabled = false; + } + + public bool SuspendPaint + { + get { return m_SuspendPaint; } + set { m_SuspendPaint = value; } + } + + public eScrollBarSkin SkinScrollbars + { + get { return m_SkinScrollbars; } + set + { + if (m_SkinScrollbars != value) + { + if (m_SkinScrollbars != eScrollBarSkin.None) + { + if (m_VScrollBar != null) + { + m_VScrollBar.Dispose(); + m_VScrollBar = null; + } + if (m_HScrollBar != null) + { + m_HScrollBar.Dispose(); + m_HScrollBar = null; + } + UnRegisterHook(); + } + + m_SkinScrollbars = value; + if (ShouldSkinScrollbars) + { + CreateScrollbars(); + if (m_Control.IsHandleCreated) + RegisterHook(); + } + } + } + } + + private void Control_HandleDestroyed(object sender, EventArgs e) + { + UnRegisterHook(); + } + + private void Control_HandleCreated(object sender, EventArgs e) + { + if (ShouldSkinScrollbars) + RegisterHook(); + } + + private void RegisterHook() + { + UpdateScrollValues(); + NonClientHook.RegisterHook(this); + } + + private void UnRegisterHook() + { + if (ShouldSkinScrollbars) + NonClientHook.UnregisterHook(this); + } + + public Rectangle ClientRectangle + { + get { return m_ClientRectangle; } + } + + public virtual bool WndProc(ref Message m) + { + bool callBase = true; + + switch (m.Msg) + { + case (int)WinApi.WindowsMessages.WM_NCPAINT: + { + callBase = WindowsMessageNCPaint(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_CTLCOLORSCROLLBAR: + { + PaintNonClientAreaBuffered(); + callBase = false; + break; + } + case (int)WinApi.WindowsMessages.WM_NCCALCSIZE: + { + callBase = WindowsMessageNCCalcSize(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_VSCROLL: + { + callBase = WindowsMessageVScroll(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_HSCROLL: + { + callBase = WindowsMessageHScroll(ref m); + break; + } + case (int)WinApi.WindowsMessages.SBM_SETPOS: + { + callBase = WindowsMessageSbmSetPos(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_ERASEBKGND: + { + callBase = WindowsMessageEraseBkgnd(ref m); + break; + } + case (int)WinApi.WindowsMessages.EM_GETMODIFY: + { + callBase = WindowsMessageEmGetModify(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_NCLBUTTONDOWN: + { + callBase = WindowsMessageNcLButtonDown(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_NCLBUTTONUP: + { + callBase = WindowsMessageNcLButtonUp(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_NCMOUSELEAVE: + { + callBase = WindowsMessageNcMouseLeave(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_NCMOUSEMOVE: + { + callBase = WindowsMessageNcMouseMove(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_MOUSEWHEEL: + { + callBase = WindowsMessageMouseWheel(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_SIZE: + { + callBase = WindowsMessageSize(ref m); + break; + } + case (int)WinApi.WindowsMessages.WM_COMMAND: + { + if (WinApi.HIWORD(m.WParam) == 0x100) + { + CallBaseWndProcAndPaint(ref m); + callBase = false; + } + break; + } + case (int)WinApi.WindowsMessages.WM_CTLCOLORBTN: + { + CallBaseWndProcAndPaint(ref m); + callBase = false; + break; + } + case 0x120: + { + WindowsMessageCustomNotify(ref m); + callBase = false; + break; + } + } + + return callBase; + } + + private bool WindowsMessageSize(ref Message m) + { + if (m_IsListView) + { + CallBaseWndProcAndPaint(ref m); + return false; + } + + return true; + } + + private void WindowsMessageCustomNotify(ref Message m) + { + int wParamInt = WinApi.ToInt(m.WParam); + if (wParamInt == 0) + { + PaintNonClientAreaBuffered(); + } + else if (wParamInt == 1) + { + Point p = ScreenToNonClientPoint(Control.MousePosition); + if (m_VScrollBar.Visible) + { + if (m_VScrollBar.IsMouseDown) + m_VScrollBar.MouseUp(new MouseEventArgs(MouseButtons.Left, 0, p.X, p.Y, 0)); + else if (!m_VScrollBar.DisplayRectangle.Contains(p)) + m_VScrollBar.MouseLeave(); + } + + if (m_HScrollBar.Visible) + { + if (m_HScrollBar.IsMouseDown) + m_HScrollBar.MouseUp(new MouseEventArgs(MouseButtons.Left, 0, p.X, p.Y, 0)); + else if (!m_HScrollBar.DisplayRectangle.Contains(p)) + m_HScrollBar.MouseLeave(); + } + + PaintNonClientAreaBuffered(); + } + } + + private bool WindowsMessageMouseWheel(ref Message m) + { + CallBaseWndProcAndPaint(ref m); + return false; + } + + private bool WindowsMessageNcMouseLeave(ref Message m) + { + if (!ShouldSkinScrollbars) return true; + if (m_VScrollBar.Visible) + m_VScrollBar.MouseLeave(); + if (m_HScrollBar.Visible) + m_HScrollBar.MouseLeave(); + CallBaseWndProcAndPaint(ref m); + return false; + } + + private bool WindowsMessageNcMouseMove(ref Message m) + { + if (!ShouldSkinScrollbars) return true; + Point p = ScreenToNonClientPoint(new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam))); + if (m_VScrollBar.Visible) + m_VScrollBar.MouseMove(new MouseEventArgs(Control.MouseButtons, 0, p.X, p.Y, 0)); + if (m_HScrollBar.Visible) + m_HScrollBar.MouseMove(new MouseEventArgs(Control.MouseButtons, 0, p.X, p.Y, 0)); + CallBaseWndProcAndPaint(ref m); + return false; + } + + private bool WindowsMessageNcLButtonUp(ref Message m) + { + if (!ShouldSkinScrollbars) return true; + Point p = ScreenToNonClientPoint(new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam))); + if (m_VScrollBar.Visible) + m_VScrollBar.MouseUp(new MouseEventArgs(MouseButtons.Left, 0, p.X, p.Y, 0)); + if (m_HScrollBar.Visible) + m_HScrollBar.MouseUp(new MouseEventArgs(MouseButtons.Left, 0, p.X, p.Y, 0)); + CallBaseWndProcAndPaint(ref m); + return false; + } + + private bool WindowsMessageNcLButtonDown(ref Message m) + { + if (!ShouldSkinScrollbars) return true; + Point p = ScreenToNonClientPoint(new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam))); + if (m_VScrollBar.Visible) + m_VScrollBar.MouseDown(new MouseEventArgs(MouseButtons.Left, 0, p.X, p.Y, 0)); + if (m_HScrollBar.Visible) + m_HScrollBar.MouseDown(new MouseEventArgs(MouseButtons.Left, 0, p.X, p.Y, 0)); + CallBaseWndProcAndPaint(ref m); + return false; + } + + private bool WindowsMessageEmGetModify(ref Message m) + { + if (!ShouldSkinScrollbars) return true; + CallBaseWndProcAndPaint(ref m); + return false; + } + + private bool WindowsMessageEraseBkgnd(ref Message m) + { + if (!m_IsListView || !ShouldSkinScrollbars) return true; + CallBaseWndProcAndPaint(ref m); + return false; + } + + private void WindowsMessageMouseMove(IntPtr hWnd, Point mousePosition) + { + if (Control.MouseButtons == MouseButtons.Left && hWnd == m_Control.Handle && ShouldSkinScrollbars) + { + WinApi.PostMessage(hWnd, 0x120, IntPtr.Zero, IntPtr.Zero); + } + } + + private bool WindowsMessageSbmSetPos(ref Message m) + { + if (!ShouldSkinScrollbars) return true; + CallBaseWndProcAndPaint(ref m); + return false; + } + + private void CallBaseWndProcAndPaintWndStyle(ref Message m) + { + const int WS_VISIBLE = 0x10000000; + IntPtr style = WinApi.GetWindowLongPtr(m_Control.Handle, (int)WinApi.GWL.GWL_STYLE); + IntPtr newStyle; + if (IntPtr.Size == 8) + { + long ns = style.ToInt64(); + newStyle = new IntPtr(ns & ~(ns & WS_VISIBLE)); + } + else + { + int ns = WinApi.ToInt(style); + newStyle = new IntPtr(ns & ~(ns & WS_VISIBLE)); + } + WinApi.SetWindowLongPtr(m_Control.Handle, (int)WinApi.GWL.GWL_STYLE, newStyle); + //PaintUnBuffered(); + using (BufferedBitmap bmp = GetNonClientAreaBitmap()) + { + ((INonClientControl)m_Control).BaseWndProc(ref m); + WinApi.SetWindowLongPtr(m_Control.Handle, (int)WinApi.GWL.GWL_STYLE, style); + RenderNonClientAreaBitmap(bmp); + } + if (m_Control is Control) + ((Control)m_Control).Invalidate(true); + } + + private bool WindowsMessageVScroll(ref Message m) + { + if (!ShouldSkinScrollbars) return true; + + if (m_SkinScrollbars == eScrollBarSkin.Optimized) + CallBaseWndProcAndPaintWndStyle(ref m); + else + CallBaseWndProcAndPaint(ref m); + + return false; + } + + private bool WindowsMessageHScroll(ref Message m) + { + if (!ShouldSkinScrollbars) return true; + if (m_SkinScrollbars == eScrollBarSkin.Optimized) + CallBaseWndProcAndPaintWndStyle(ref m); + else + CallBaseWndProcAndPaint(ref m); + return false; + } + + private void CallBaseWndProcAndPaint(ref Message m) + { + //PaintUnBuffered(); + using (BufferedBitmap bmp = GetNonClientAreaBitmap()) + { + ((INonClientControl)m_Control).BaseWndProc(ref m); + RenderNonClientAreaBitmap(bmp); + } + } + + /// + /// Calculates the size of non-client area of the control. + /// + protected virtual bool WindowsMessageNCCalcSize(ref Message m) + { + ElementStyle style = ((INonClientControl)m_Control).BorderStyle; + if (style != null && style.PaintBorder) + { + ((INonClientControl)m_Control).BaseWndProc(ref m); + if (m.WParam == IntPtr.Zero) + { + WinApi.RECT r = (WinApi.RECT)Marshal.PtrToStructure(m.LParam, typeof(WinApi.RECT)); + Rectangle rc = GetClientRectangleForBorderStyle(r.ToRectangle(), style); + WinApi.RECT newClientRect = WinApi.RECT.FromRectangle(rc); + Marshal.StructureToPtr(newClientRect, m.LParam, false); + + // Store the client rectangle in Window coordinates non-client coordinates + m_ClientRectangle = rc; + m_ClientRectangle.X = m_ClientRectangle.X - r.Left; + m_ClientRectangle.Y = m_ClientRectangle.Y - r.Top; + } + else + { + WinApi.NCCALCSIZE_PARAMS csp; + csp = (WinApi.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(WinApi.NCCALCSIZE_PARAMS)); + + WinApi.WINDOWPOS pos = (WinApi.WINDOWPOS)Marshal.PtrToStructure(csp.lppos, typeof(WinApi.WINDOWPOS)); + WinApi.RECT rgrc0 = csp.rgrc0; + WinApi.RECT newClientRect = WinApi.RECT.FromRectangle(GetClientRectangleForBorderStyle(new Rectangle(rgrc0.Left, rgrc0.Top, rgrc0.Width, rgrc0.Height), style)); + csp.rgrc0 = newClientRect; + csp.rgrc1 = newClientRect; + Marshal.StructureToPtr(csp, m.LParam, false); + + // Store the client rectangle in Window coordinates non-client coordinates + m_ClientRectangle = csp.rgrc0.ToRectangle(); + m_ClientRectangle.X = m_ClientRectangle.X - pos.x; + m_ClientRectangle.Y = m_ClientRectangle.Y - pos.y; + } + } + else + { + // Take client rectangle directly + if (m.WParam == IntPtr.Zero) + { + WinApi.RECT rWindow = (WinApi.RECT)Marshal.PtrToStructure(m.LParam, typeof(WinApi.RECT)); + ((INonClientControl)m_Control).BaseWndProc(ref m); + WinApi.RECT r = (WinApi.RECT)Marshal.PtrToStructure(m.LParam, typeof(WinApi.RECT)); + WinApi.RECT newClientRect = WinApi.RECT.FromRectangle(GetClientRectangleForBorderStyle(new Rectangle(r.Left, r.Top, r.Width, r.Height), style)); + Marshal.StructureToPtr(newClientRect, m.LParam, false); + + // Store the client rectangle in Window coordinates non-client coordinates + m_ClientRectangle = newClientRect.ToRectangle(); + m_ClientRectangle.X = m_ClientRectangle.X - rWindow.Left; + m_ClientRectangle.Y = m_ClientRectangle.Y - rWindow.Top; + } + else + { + ((INonClientControl)m_Control).BaseWndProc(ref m); + + WinApi.NCCALCSIZE_PARAMS csp; + csp = (WinApi.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(WinApi.NCCALCSIZE_PARAMS)); + WinApi.WINDOWPOS pos = (WinApi.WINDOWPOS)Marshal.PtrToStructure(csp.lppos, typeof(WinApi.WINDOWPOS)); + WinApi.RECT rgrc0 = csp.rgrc0; + WinApi.RECT newClientRect = WinApi.RECT.FromRectangle(GetClientRectangleForBorderStyle(new Rectangle(rgrc0.Left, rgrc0.Top, rgrc0.Width, rgrc0.Height), style)); + csp.rgrc0 = newClientRect; + Marshal.StructureToPtr(csp, m.LParam, false); + + // Store the client rectangle in Window coordinates non-client coordinates + m_ClientRectangle = csp.rgrc0.ToRectangle(); + m_ClientRectangle.X = m_ClientRectangle.X - pos.x; + m_ClientRectangle.Y = m_ClientRectangle.Y - pos.y; + } + } + return false; + } + + internal int GetLeftBorderWidth(ElementStyle style) + { + if (style.PaintLeftBorder) + { + int w = style.BorderLeftWidth; + if (style.CornerTypeTopLeft == eCornerType.Rounded || style.CornerTypeTopLeft == eCornerType.Diagonal + || style.CornerTypeBottomLeft == eCornerType.Rounded || style.CornerTypeBottomLeft == eCornerType.Diagonal || + (style.CornerType == eCornerType.Rounded || style.CornerType == eCornerType.Diagonal) && + (style.CornerTypeTopLeft == eCornerType.Inherit || style.CornerTypeBottomLeft == eCornerType.Inherit)) + w = Math.Max(w, style.CornerDiameter / 2 + 1); + return w; + } + return 0; + } + + internal int GetTopBorderWidth(ElementStyle style) + { + if (style.PaintTopBorder) + { + int w = style.BorderTopWidth; + if (style.CornerTypeTopLeft == eCornerType.Rounded || style.CornerTypeTopLeft == eCornerType.Diagonal + || style.CornerTypeTopRight == eCornerType.Rounded || style.CornerTypeTopRight == eCornerType.Diagonal || + (style.CornerType == eCornerType.Rounded || style.CornerType == eCornerType.Diagonal) && + (style.CornerTypeTopLeft == eCornerType.Inherit || style.CornerTypeTopRight == eCornerType.Inherit)) + w = Math.Max(w, style.CornerDiameter / 2 + 1); + return w; + } + return 0; + } + + internal int GetRightBorderWidth(ElementStyle style) + { + if (style.PaintRightBorder) + { + int w = style.BorderRightWidth; + if (style.CornerTypeTopRight == eCornerType.Rounded || style.CornerTypeBottomRight == eCornerType.Rounded + || style.CornerTypeTopRight == eCornerType.Diagonal || style.CornerTypeBottomRight == eCornerType.Diagonal || + (style.CornerType == eCornerType.Rounded || style.CornerType == eCornerType.Diagonal) && + (style.CornerTypeTopRight == eCornerType.Inherit || style.CornerTypeBottomRight == eCornerType.Inherit)) + w = Math.Max(w, style.CornerDiameter / 2 + 1); + return w; + } + return 0; + } + + internal int GetBottomBorderWidth(ElementStyle style) + { + if (style.PaintBottomBorder) + { + int w = style.BorderBottomWidth; + if (style.CornerTypeBottomLeft == eCornerType.Rounded || style.CornerTypeBottomRight == eCornerType.Rounded || + style.CornerTypeBottomLeft == eCornerType.Diagonal || style.CornerTypeBottomRight == eCornerType.Diagonal || + (style.CornerType == eCornerType.Rounded || style.CornerType == eCornerType.Diagonal) && + (style.CornerTypeBottomLeft == eCornerType.Inherit || style.CornerTypeBottomRight == eCornerType.Inherit)) + w = Math.Max(w, style.CornerDiameter / 2 + 1); + return w; + } + return 0; + } + + internal Rectangle GetClientRectangleForBorderStyle(Rectangle rect, ElementStyle style) + { + if (style == null) + return rect; + + if (style.PaintLeftBorder) + { + int w = GetLeftBorderWidth(style); + rect.X += w; + rect.Width -= w; + } + if (style.PaintTopBorder) + { + int w = GetTopBorderWidth(style); + rect.Y += w; + rect.Height -= w; + } + if (style.PaintRightBorder) + { + int w = GetRightBorderWidth(style); + rect.Width -= w; + } + if (style.PaintBottomBorder) + { + int w = GetBottomBorderWidth(style); + rect.Height -= w; + } + + TextBox tb = m_Control as TextBox; + if (tb != null && tb.Multiline && tb.ScrollBars != ScrollBars.None) + { + if (tb.ScrollBars == ScrollBars.Vertical || tb.ScrollBars == ScrollBars.Both) + { + if (tb.RightToLeft == RightToLeft.Yes) + rect.Width -= style.PaddingRight; + else + { + rect.X += style.PaddingLeft; + rect.Width -= style.PaddingLeft; + } + } + + return rect; + } + + rect.X += style.PaddingLeft; + rect.Width -= style.PaddingLeft + style.PaddingRight; + rect.Y += style.PaddingTop; + //rect.Height -= style.PaddingTop + ((m_Control is TextBox)? 0 : style.PaddingBottom); + rect.Height -= style.PaddingTop + style.PaddingBottom; + + m_Control.AdjustClientRectangle(ref rect); + + return rect; + } + + private bool m_Painting = false; + /// + /// Paints the non-client area of the control. + /// + protected virtual bool WindowsMessageNCPaint(ref Message m) + { + if (!ShouldSkinScrollbars) + { + ((INonClientControl)m_Control).BaseWndProc(ref m); + if (m_Control.IsHandleCreated && m_Control.Handle != IntPtr.Zero) + PaintNonClientAreaBuffered(); + return false; + } + //PaintUnBuffered(); + using (BufferedBitmap bmp = GetNonClientAreaBitmap()) + { + ((INonClientControl)m_Control).BaseWndProc(ref m); + RenderNonClientAreaBitmap(bmp); + } + m.Result = IntPtr.Zero; + + //if (m_Control.IsHandleCreated && m_Control.Handle != IntPtr.Zero) + //{ + // PaintNonClientAreaBuffered(); + //} + + return false; + } + + /// + /// Draws the non-client area buffered. + /// + public void PaintNonClientAreaBuffered() + { + //PaintUnBuffered(); + + if (m_Control.Width <= 0 || m_Control.Height <= 0 || m_SuspendPaint) return; + + using (BufferedBitmap bmp = GetNonClientAreaBitmap()) + { + RenderNonClientAreaBitmap(bmp); + } + } + + //private Bitmap GetNonClientAreaBitmap() + //{ + // if (m_Control.Width <= 0 || m_Control.Height <= 0 || m_SuspendPaint || !m_Control.IsHandleCreated) return null; + // Bitmap bmp = new Bitmap(m_Control.Width, m_Control.Height); + // using (Graphics g = Graphics.FromImage(bmp)) + // { + // PaintNonClientArea(g); + // } + // return bmp; + //} + + private BufferedBitmap GetNonClientAreaBitmap() + { + if (m_Control.Width <= 0 || m_Control.Height <= 0 || m_SuspendPaint || !m_Control.IsHandleCreated) return null; + BufferedBitmap bmp = null; + IntPtr hdc = WinApi.GetWindowDC(m_Control.Handle); + if (hdc == IntPtr.Zero) return null; + Rectangle r = GetControlRectangle(); + try + { + bmp = new BufferedBitmap(hdc, new Rectangle(0, 0, r.Width, r.Height)); + PaintNonClientArea(bmp.Graphics); + } + finally + { + WinApi.ReleaseDC(m_Control.Handle, hdc); + } + return bmp; + } + + //private void PaintUnBuffered() + //{ + // IntPtr dc = WinApi.GetWindowDC(m_Control.Handle); + // try + // { + // using (Graphics g = Graphics.FromHdc(dc)) + // { + // g.SetClip(GetClientRectangle(), CombineMode.Exclude); + // if (!ShouldSkinScrollbars) + // { + // WinApi.SCROLLBARINFO psbi = new WinApi.SCROLLBARINFO(); + // psbi.cbSize = Marshal.SizeOf(psbi); + // WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_VSCROLL, ref psbi); + // if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + // { + // Rectangle rvs = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + // g.SetClip(rvs, System.Drawing.Drawing2D.CombineMode.Exclude); + // } + // psbi = new WinApi.SCROLLBARINFO(); + // psbi.cbSize = Marshal.SizeOf(psbi); + // WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_HSCROLL, ref psbi); + // if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + // { + // Rectangle rvs = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + // g.SetClip(rvs, System.Drawing.Drawing2D.CombineMode.Exclude); + // } + // } + + // PaintNonClientArea(g); + + // g.ResetClip(); + // } + // } + // finally + // { + // WinApi.ReleaseDC(m_Control.Handle, dc); + // } + //} + private void RenderNonClientAreaBitmap(BufferedBitmap bmp) + { + if (bmp == null) return; + IntPtr dc = WinApi.GetWindowDC(m_Control.Handle); + try + { + using (Graphics g = Graphics.FromHdc(dc)) + { + Rectangle[] clips = new Rectangle[3]; + clips[0] = GetClientRectangle(); + + if (!ShouldSkinScrollbars) + { + WinApi.SCROLLBARINFO psbi = new WinApi.SCROLLBARINFO(); + psbi.cbSize = Marshal.SizeOf(psbi); + WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_VSCROLL, ref psbi); + if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + { + Rectangle rvs = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + clips[1] = rvs; + } + psbi = new WinApi.SCROLLBARINFO(); + psbi.cbSize = Marshal.SizeOf(psbi); + WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_HSCROLL, ref psbi); + if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + { + Rectangle rvs = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + clips[2] = rvs; + } + } + + bmp.Render(g, clips); + } + } + finally + { + WinApi.ReleaseDC(m_Control.Handle, dc); + } + } + //private void RenderNonClientAreaBitmap(Bitmap bmp) + //{ + // if (bmp == null) return; + // IntPtr dc = WinApi.GetWindowDC(m_Control.Handle); + // try + // { + // using (Graphics g = Graphics.FromHdc(dc)) + // { + // g.SetClip(GetClientRectangle(), CombineMode.Exclude); + // if (!ShouldSkinScrollbars) + // { + // WinApi.SCROLLBARINFO psbi = new WinApi.SCROLLBARINFO(); + // psbi.cbSize = Marshal.SizeOf(psbi); + // WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_VSCROLL, ref psbi); + // if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + // { + // Rectangle rvs = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + // g.SetClip(rvs, System.Drawing.Drawing2D.CombineMode.Exclude); + // } + // psbi = new WinApi.SCROLLBARINFO(); + // psbi.cbSize = Marshal.SizeOf(psbi); + // WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_HSCROLL, ref psbi); + // if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + // { + // Rectangle rvs = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + // g.SetClip(rvs, System.Drawing.Drawing2D.CombineMode.Exclude); + // } + // } + + // g.DrawImageUnscaled(bmp, 0, 0); + // g.ResetClip(); + // } + // } + // finally + // { + // WinApi.ReleaseDC(m_Control.Handle, dc); + // } + //} + + //protected virtual void PaintNonClientAreaBuffered(Graphics targetGraphics) + //{ + // Bitmap bmp = new Bitmap(m_Control.Width, m_Control.Height); + + // try + // { + // using (Graphics g = Graphics.FromImage(bmp)) + // { + // PaintNonClientArea(g); + // } + + // targetGraphics.SetClip(GetClientRectangle(), CombineMode.Exclude); + // if (!m_SkinScrollbars) + // { + // WinApi.SCROLLBARINFO psbi = new WinApi.SCROLLBARINFO(); + // psbi.cbSize = Marshal.SizeOf(psbi); + // WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_VSCROLL, ref psbi); + // if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + // { + // Rectangle rvs = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + // targetGraphics.SetClip(rvs, System.Drawing.Drawing2D.CombineMode.Exclude); + // } + // psbi = new WinApi.SCROLLBARINFO(); + // psbi.cbSize = Marshal.SizeOf(psbi); + // WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_HSCROLL, ref psbi); + // if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + // { + // Rectangle rvs = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + // targetGraphics.SetClip(rvs, System.Drawing.Drawing2D.CombineMode.Exclude); + // } + // } + + // targetGraphics.DrawImageUnscaled(bmp, 0, 0); + // targetGraphics.ResetClip(); + // } + // finally + // { + // bmp.Dispose(); + // } + //} + + private Rectangle GetClientRectangle() + { + return m_ClientRectangle; + } + + public void UpdateScrollValues() + { + if (!ShouldSkinScrollbars) return; + + WinApi.SCROLLBARINFO psbi = new WinApi.SCROLLBARINFO(); + psbi.cbSize = Marshal.SizeOf(psbi); + WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_VSCROLL, ref psbi); + if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + { + Rectangle displayRect = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + if (m_VScrollBar.DisplayRectangle != displayRect) + m_VScrollBar.DisplayRectangle = displayRect; + + Rectangle thumbRect = new Rectangle(displayRect.X, displayRect.Y, displayRect.Width, psbi.dxyLineButton); + if (m_VScrollBar.ThumbDecreaseRectangle != thumbRect) + m_VScrollBar.ThumbDecreaseRectangle = thumbRect; + + thumbRect = new Rectangle(displayRect.X, displayRect.Bottom - psbi.dxyLineButton, displayRect.Width, psbi.dxyLineButton); + if (m_VScrollBar.ThumbIncreaseRectangle != thumbRect) + m_VScrollBar.ThumbIncreaseRectangle = thumbRect; + + thumbRect = new Rectangle(displayRect.X, displayRect.Y + psbi.xyThumbTop, displayRect.Width, psbi.xyThumbBottom - psbi.xyThumbTop); + if (m_VScrollBar.TrackRectangle != thumbRect) + m_VScrollBar.TrackRectangle = thumbRect; + if (psbi.rgstate[0] == (int)WinApi.eStateFlags.STATE_SYSTEM_UNAVAILABLE) + { + if (m_VScrollBar.Enabled) m_VScrollBar.Enabled = false; + } + else if (!m_VScrollBar.Enabled) + m_VScrollBar.Enabled = true; + m_VScrollBar.Visible = true; + } + else + m_VScrollBar.Visible = false; + + + // Horizontal scroll bar + psbi = new WinApi.SCROLLBARINFO(); + psbi.cbSize = Marshal.SizeOf(psbi); + WinApi.GetScrollBarInfo(m_Control.Handle, (uint)WinApi.eObjectId.OBJID_HSCROLL, ref psbi); + if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + { + Rectangle displayRect = ScreenToNonClientRectangle(psbi.rcScrollBar.ToRectangle()); + if (m_HScrollBar.DisplayRectangle != displayRect) + m_HScrollBar.DisplayRectangle = displayRect; + + Rectangle thumbRect = new Rectangle(displayRect.X, displayRect.Y, psbi.dxyLineButton, displayRect.Height); + if (m_HScrollBar.ThumbDecreaseRectangle != thumbRect) + m_HScrollBar.ThumbDecreaseRectangle = thumbRect; + + thumbRect = new Rectangle(displayRect.Right - psbi.dxyLineButton, displayRect.Y, psbi.dxyLineButton, displayRect.Height); + if (m_HScrollBar.ThumbIncreaseRectangle != thumbRect) + m_HScrollBar.ThumbIncreaseRectangle = thumbRect; + + thumbRect = new Rectangle(displayRect.X + psbi.xyThumbTop, displayRect.Y, psbi.xyThumbBottom - psbi.xyThumbTop, displayRect.Height); + if (m_HScrollBar.TrackRectangle != thumbRect) + m_HScrollBar.TrackRectangle = thumbRect; + if (psbi.rgstate[0] == (int)WinApi.eStateFlags.STATE_SYSTEM_UNAVAILABLE) + { + if (m_HScrollBar.Enabled) m_VScrollBar.Enabled = false; + } + else if (!m_HScrollBar.Enabled) + m_HScrollBar.Enabled = true; + m_HScrollBar.Visible = true; + } + else + m_HScrollBar.Visible = false; + } + + protected virtual void PaintNonClientArea(Graphics g) + { + if (m_Painting) return; + m_Painting = true; + try + { + // Paint Background and border + PaintBorder(g); + + if (ShouldSkinScrollbars) + { + UpdateScrollValues(); + + if (m_VScrollBar.Visible) + m_VScrollBar.Paint(((INonClientControl)m_Control).GetItemPaintArgs(g)); + if (m_HScrollBar.Visible) + m_HScrollBar.Paint(((INonClientControl)m_Control).GetItemPaintArgs(g)); + } + } + finally + { + m_Painting = false; + } + } + + private Rectangle GetControlRectangle() + { + if (m_Control.IsHandleCreated) + { + WinApi.RECT r = new WinApi.RECT(); + WinApi.GetWindowRect(m_Control.Handle, ref r); + return new Rectangle(0, 0, r.Width, r.Height); + } + else + return new Rectangle(0, 0, m_Control.Width, m_Control.Height); + } + + private void PaintBorder(Graphics g) + { + ElementStyle style = ((INonClientControl)m_Control).BorderStyle; + Rectangle r = GetControlRectangle(); + if (style == null || r.Width <= 0 || r.Height <= 0) return; + + ElementStyleDisplayInfo displayInfo = new ElementStyleDisplayInfo(style, g, r); + + if (style.BackColor == Color.Transparent && (style.BackColor2.IsEmpty || style.BackColor2 == Color.Transparent)) + { + ((INonClientControl)m_Control).PaintBackground(new PaintEventArgs(g, r)); + } + else + { + if (style.BackColor.IsEmpty && m_Control.BackColor != Color.Transparent) + { + using (SolidBrush brush = new SolidBrush(GetBackColor())) + g.FillRectangle(brush, r); + } + else + { + if (m_Control.BackColor == Color.Transparent || style.PaintBorder && (style.CornerType == eCornerType.Rounded || style.CornerType == eCornerType.Diagonal || + style.CornerTypeBottomLeft == eCornerType.Rounded || style.CornerTypeBottomLeft == eCornerType.Diagonal || + style.CornerTypeBottomRight == eCornerType.Rounded || style.CornerTypeBottomRight == eCornerType.Diagonal || + style.CornerTypeTopLeft == eCornerType.Rounded || style.CornerTypeTopLeft == eCornerType.Diagonal || + style.CornerTypeTopRight == eCornerType.Rounded || style.CornerTypeTopRight == eCornerType.Diagonal)) + { + if (m_Control is TextBox || m_Control.BackColor == Color.Transparent) + ((INonClientControl)m_Control).PaintBackground(new PaintEventArgs(g, r)); + else + using (SolidBrush brush = new SolidBrush(m_Control.BackColor)) + g.FillRectangle(brush, r); + } + else + { + using (SolidBrush brush = new SolidBrush(m_Control.BackColor)) + g.FillRectangle(brush, r); + } + } + + Rectangle rback = r; + if (style.PaintBorder) + { + if (style.PaintRightBorder && style.BorderRightWidth > 1) + rback.Width--; + if (style.PaintBottomBorder && style.BorderBottomWidth > 1) + rback.Height--; + } + m_Control.AdjustBorderRectangle(ref rback); + displayInfo.Bounds = rback; + ElementStyleDisplay.PaintBackground(displayInfo); + m_Control.RenderNonClient(g); + } + + SmoothingMode sm = g.SmoothingMode; + if (style.PaintBorder && (style.CornerType == eCornerType.Rounded || style.CornerType == eCornerType.Diagonal)) + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + m_Control.AdjustBorderRectangle(ref r); + displayInfo.Bounds = r; + this.BeforePaintBorder(g, r); + ElementStyleDisplay.PaintBorder(displayInfo); + g.SmoothingMode = sm; + this.AfterPaintBorder(g, r); + } + + private Color GetBackColor() + { + return (m_Control.Enabled ? m_Control.BackColor : (m_Control.DisabledBackColor.IsEmpty ? SystemColors.Control : m_Control.DisabledBackColor)); + } + + private void AfterPaintBorder(Graphics g, Rectangle r) + { + if (AfterBorderPaint != null) + AfterBorderPaint(this, new CustomNCPaintEventArgs(g, r)); + } + + private void BeforePaintBorder(Graphics g, Rectangle r) + { + if (BeforeBorderPaint != null) + BeforeBorderPaint(this, new CustomNCPaintEventArgs(g, r)); + } + + private Point ScreenToNonClientPoint(Point p) + { + Point pScreen = m_Control.PointToScreen(new Point(-m_ClientRectangle.X, -m_ClientRectangle.Y)); + p.X = p.X - pScreen.X; + p.Y = p.Y - pScreen.Y; + return p; + } + + private Rectangle ScreenToNonClientRectangle(Rectangle r) + { + Point p = m_Control.PointToScreen(new Point(-m_ClientRectangle.X, -m_ClientRectangle.Y)); + r.X = r.X - p.X; + r.Y = r.Y - p.Y; + + return r; + } + #endregion + + + + #region ISkinHook Members + public delegate void InvokeMouseMethodDelegate(IntPtr handle, Point mousePos); + + public void PostMouseMove(IntPtr hWnd, Point mousePos) + { + if (m_Control is Control) + { + Control c = m_Control as Control; + if (c == null || c.IsDisposed || !c.IsHandleCreated) + return; + + if (c.InvokeRequired) + { +#if FRAMEWORK20 + c.BeginInvoke(new InvokeMouseMethodDelegate(this.PostMouseMoveSafe), hWnd, mousePos); +#else + c.BeginInvoke(new InvokeMouseMethodDelegate(this.PostMouseMoveSafe), new object[]{hWnd, mousePos}); +#endif + } + else + this.PostMouseMoveSafe(hWnd, mousePos); + } + else + PostMouseMoveSafe(hWnd, mousePos); + } + private void PostMouseMoveSafe(IntPtr hWnd, Point mousePos) + { + if (hWnd == m_Control.Handle) + WindowsMessageMouseMove(hWnd, mousePos); + } + + public void PostMouseUp(IntPtr hWnd, Point mousePos) + { + if (m_Control is Control) + { + Control c = m_Control as Control; + if (c == null || c.IsDisposed || !c.IsHandleCreated) + return; + + if (c.InvokeRequired) + { +#if FRAMEWORK20 + c.BeginInvoke(new InvokeMouseMethodDelegate(this.PostMouseUpSafe), hWnd, mousePos); +#else + c.BeginInvoke(new InvokeMouseMethodDelegate(this.PostMouseUpSafe), new object[] {hWnd, mousePos}); +#endif + } + else + { + this.PostMouseUpSafe(hWnd, mousePos); + } + } + else + PostMouseUpSafe(hWnd, mousePos); + } + + public void PostMouseUpSafe(IntPtr hWnd, Point mousePos) + { + if (hWnd == m_Control.Handle && ShouldSkinScrollbars) + { + if (m_VScrollBar.IsMouseDown) + WinApi.PostMessage(m_Control.Handle, 0x120, (IntPtr)1, (IntPtr)0); + else if (m_HScrollBar.IsMouseDown) + WinApi.PostMessage(m_Control.Handle, 0x120, (IntPtr)1, (IntPtr)0); + } + } + #endregion + } + + internal delegate void CustomNCPaintEventHandler(object sender, CustomNCPaintEventArgs e); + internal class CustomNCPaintEventArgs : EventArgs + { + public Graphics Graphics = null; + public Rectangle Bounds = Rectangle.Empty; + + public CustomNCPaintEventArgs(Graphics g, Rectangle r) + { + this.Graphics = g; + this.Bounds = r; + } + } + + public interface INonClientControl + { + /// + /// Calls base WndProc implementation + /// + /// Describes Windows Message + void BaseWndProc(ref Message m); + + /// + /// Gets the ItemPaintArgs which provide information for rendering. + /// + /// Reference to Canvas + /// Returns the new ItemPaintArgs instance + ItemPaintArgs GetItemPaintArgs(Graphics g); + + /// + /// Gets the reference to the BorderStyle used by the control if any. + /// + ElementStyle BorderStyle { get; } + + /// + /// Paints the background of the control + /// + /// PaintEventArgs arguments + void PaintBackground(PaintEventArgs e); + + /// + /// Returns the Windows handle associated with the control. + /// + IntPtr Handle { get; } + + /// + /// Returns width of the control. + /// + int Width { get; } + + /// + /// Returns the height of the control. + /// + int Height { get; } + + /// + /// Returns whether handled for the control has been created. + /// + bool IsHandleCreated { get; } + + /// + /// Converts the client point into the screen point. + /// + /// Client point + /// Client point converted into screen coordinates. + Point PointToScreen(Point client); + + /// + /// Returns background color of the control. + /// + Color BackColor { get; } + + /// + /// Returns background color of the control when Enabled=false. + /// + Color DisabledBackColor { get; } + + /// + /// Returns whether control is enabled. + /// + bool Enabled { get; set; } + + /// + /// Adjusts the client rectangle for the control. + /// + /// Reference to new client rectangle. + void AdjustClientRectangle(ref Rectangle r); + + /// + /// Adjusts the border rectangle before the non-client border is rendered. + /// + /// Border rectangle + void AdjustBorderRectangle(ref Rectangle r); + + /// + /// Occurs after non-client area is rendered and provides opportunity to render on top of it. + /// + /// Reference to Graphics object. + void RenderNonClient(Graphics g); + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/PageNavigator.cs b/PROMS/DotNetBar Source Code/Controls/PageNavigator.cs new file mode 100644 index 00000000..3057e739 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/PageNavigator.cs @@ -0,0 +1,326 @@ +#if FRAMEWORK20 +using System; +using System.Runtime.InteropServices; +using System.Drawing; +using System.ComponentModel; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the PageNavigator control + /// + [ToolboxBitmap(typeof(PageNavigator), "PageNavigator.PageNavigator.ico"), ToolboxItem(true)] + [DefaultEvent("ValueChanged"), ComVisible(false)] //, Designer(typeof(Design.PageNavigatorDesigner))] + public class PageNavigator : BaseItemControl + { + #region Private Variables + + private PageNavigatorItem _PageNavItem; // Navigation item + + #endregion + + #region Events + + /// + /// Occurs when NavigateNextPage button is clicked + /// + [Description("Occurs when NavigateNextPage button is clicked.")] + public event EventHandler NavigateNextPage; + + /// + /// Occurs when NavigateToday button is clicked + /// + [Description("Occurs when NavigateToday button is clicked.")] + public event EventHandler NavigateToday; + + /// + /// Occurs when NavigatePreviousPage button is clicked + /// + [Description("Occurs when NavigatePreviousPage button is clicked.")] + public event EventHandler NavigatePreviousPage; + + #endregion + + /// + /// Constructor + /// + public PageNavigator() + { + _PageNavItem = new PageNavigatorItem(); + _PageNavItem.Style = eDotNetBarStyle.StyleManagerControlled; + this.Size = _PageNavItem.Size; + this.HostItem = _PageNavItem; + + HookEvents(true); + } + + #region DefaultSize + + /// + /// DefaultSize + /// + protected override Size DefaultSize + { + get + { + // Set a default size based upon + // the current object layout orientation + + int m = SystemInformation.VerticalScrollBarWidth; + int n = m * 3; + + if (_PageNavItem != null && + _PageNavItem.Orientation == eOrientation.Horizontal) + { + return (new Size(n, m)); + } + + return (new Size(m, n)); + } + } + #endregion + + #region Public properties + + #region Orientation + + /// + /// Gets or sets the layout orientation. Default value is horizontal. + /// + [DefaultValue(eOrientation.Horizontal), Category("Appearance")] + [Description("Indicates control layout orientation.")] + public eOrientation Orientation + { + get { return (_PageNavItem.Orientation); } + + set + { + if (_PageNavItem.Orientation != value) + { + _PageNavItem.Orientation = value; + + this.RecalcLayout(); + } + } + } + + #endregion + + #region PreviousPageTooltip + + /// + /// Gets or sets the tooltip for the PreviousPage button of the control + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates tooltip for the PreviousPage button of the control.")] + public string PreviousPageTooltip + { + get { return (_PageNavItem.PreviousPageTooltip); } + set { _PageNavItem.PreviousPageTooltip = value; } + } + + #endregion + + #region TodayTooltip + + /// + /// Gets or sets the tooltip for the Today button + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates tooltip for the TodayPage button of the control.")] + public string TodayTooltip + { + get { return (_PageNavItem.TodayTooltip); } + set { _PageNavItem.TodayTooltip = value; } + } + + #endregion + + #region NextPageTooltip + + /// + /// Gets or sets the tooltip for the NextPage button + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates tooltip for the NextPage button of the control.")] + public string NextPageTooltip + { + get { return (_PageNavItem.NextPageTooltip); } + set { _PageNavItem.NextPageTooltip = value; } + } + + #endregion + + #region Style + /// + /// Gets/Sets the visual style for the control. + /// + [Browsable(false), DefaultValue(eDotNetBarStyle.StyleManagerControlled)] + public override eDotNetBarStyle Style + { + get + { + return base.Style; + } + set + { + base.Style = value; + } + } + #endregion + + #endregion + + #region HookEvents + + /// + /// Hooks or unhooks our control events + /// + /// true to hook, false to unhook + private void HookEvents(bool hook) + { + if (hook == true) + { + _PageNavItem.NavigatePreviousPage += PageNavNavigatePreviousPage; + _PageNavItem.NavigateNextPage += PageNavNavigateNextPage; + _PageNavItem.NavigateToday += PageNavNavigateToday; + } + else + { + _PageNavItem.NavigatePreviousPage -= PageNavNavigatePreviousPage; + _PageNavItem.NavigateNextPage -= PageNavNavigateNextPage; + _PageNavItem.NavigateToday -= PageNavNavigateToday; + } + } + + #endregion + + #region Event handling + + #region PageNav_NavigatePreviousPage + + /// + /// Handles NavigatePreviousPage events + /// + /// + /// + void PageNavNavigatePreviousPage(object sender, EventArgs e) + { + OnNavigatePreviousPage(); + } + + /// + /// Raises the NavigatePreviousPage event + /// + private void OnNavigatePreviousPage() + { + if (NavigatePreviousPage != null) + NavigatePreviousPage(this, EventArgs.Empty); + } + + #endregion + + #region PageNav_NavigateToday + + /// + /// Handles NavigateToday events + /// + /// + /// + void PageNavNavigateToday(object sender, EventArgs e) + { + OnNavigateToday(); + } + + /// + /// Raises the NavigateToday event + /// + private void OnNavigateToday() + { + if (NavigateToday != null) + NavigateToday(this, EventArgs.Empty); + } + + #endregion + + #region PageNav_NavigateNextPage + + /// + /// Handles NavigateNextPage events + /// + /// + /// + void PageNavNavigateNextPage(object sender, EventArgs e) + { + OnNavigateNextPage(); + } + + /// + /// Raises the NavigateNextPage event + /// + private void OnNavigateNextPage() + { + if (NavigateNextPage != null) + NavigateNextPage(this, EventArgs.Empty); + } + + #endregion + + #endregion + + #region RecalcLayout + + /// + /// Forces the button to perform internal layout. + /// + public override void RecalcLayout() + { + base.RecalcLayout(); + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + if (disposing == true) + HookEvents(false); + + base.Dispose(disposing); + } + + #endregion + } + + #region enums + + /// + /// PageNavigator buttons + /// + public enum PageNavigatorButton + { + /// + /// Previous page + /// + PreviousPage, + + /// + /// Today + /// + Today, + + /// + /// Next page + /// + NextPage + } + + #endregion +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/PageNavigator.ico b/PROMS/DotNetBar Source Code/Controls/PageNavigator.ico new file mode 100644 index 00000000..017d6e9a Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/PageNavigator.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/PageNavigatorItem.cs b/PROMS/DotNetBar Source Code/Controls/PageNavigatorItem.cs new file mode 100644 index 00000000..4af4745e --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/PageNavigatorItem.cs @@ -0,0 +1,1116 @@ +#if FRAMEWORK20 +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the PageNavigate item + /// + [Browsable(false), Designer("DevComponents.DotNetBar.Design.SimpleItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class PageNavigatorItem : BaseItem + { + #region Events + + /// + /// Occurs when NavigateNextPage button is clicked + /// + [Description("Occurs when NavigateNextPage button is clicked.")] + public event EventHandler NavigateNextPage; + + /// + /// Occurs when NavigateToday button is clicked + /// + [Description("Occurs when NavigateToday button is clicked.")] + public event EventHandler NavigateToday; + + /// + /// Occurs when NavigatePreviousPage button is clicked + /// + [Description("Occurs when NavigatePreviousPage button is clicked.")] + public event EventHandler NavigatePreviousPage; + + #endregion + + #region Private Variables + + private ePageNavigatorPart _MouseOverPart = ePageNavigatorPart.None; + private ePageNavigatorPart _MouseDownPart = ePageNavigatorPart.None; + + private Rectangle _PreviousPageBounds; + private Rectangle _TodayBounds; + private Rectangle _NextPageBounds; + + private string _PreviousPageTooltip = ""; + private string _TodayTooltip = ""; + private string _NextPageTooltip = ""; + + private Bitmap _PreviousPageBitmap; + private Bitmap _TodayBitmap; + private Bitmap _NextPageBitmap; + + private Timer _ClickTimer; + private int _AutoClickCount; + + private int _ButtonSize = SystemInformation.VerticalScrollBarWidth; + private int _MinWidth = SystemInformation.VerticalScrollBarWidth * 3; + + #endregion + + /// + /// Creates new instance of PageNavigateItem + /// + public PageNavigatorItem() : this("") { } + + /// + /// Creates new instance of PageNavigateItem and assigns the name to it + /// + /// Item name + public PageNavigatorItem(string itemName) + { + this.Name = itemName; + + this.ClickRepeatInterval = 200; + + this.MouseUpNotification = true; + this.MouseDownCapture = true; + + this.Size = new Size(Dpi.Width(_MinWidth), Dpi.Height(_ButtonSize)); + } + + #region Internal properties + + #region MouseOverPart + + /// + /// Gets or sets the MouseOverPart + /// + internal ePageNavigatorPart MouseOverPart + { + get { return _MouseOverPart; } + + set + { + if (_MouseOverPart != value) + { + _MouseOverPart = value; + + UpdateTooltip(); + + this.Refresh(); + } + } + } + + #endregion + + #region MouseDownPart + + /// + /// Gets or sets the MouseDownPart + /// + internal ePageNavigatorPart MouseDownPart + { + get { return _MouseDownPart; } + + set + { + if (_MouseDownPart != value) + { + _MouseDownPart = value; + + this.Refresh(); + } + } + } + + #endregion + + #endregion + + #region Public properties + + #region Orientation + + /// + /// Gets or sets the control orientation. Default value is Horizontal + /// + [DefaultValue(eOrientation.Horizontal), Category("Appearance")] + [Description("Indicates PageNavigator orientation.")] + public override eOrientation Orientation + { + get { return (base.Orientation); } + + set + { + if (base.Orientation != value) + { + base.Orientation = value; + + // Release our current cached bitmaps + + ReleaseBitmap(ref _NextPageBitmap); + ReleaseBitmap(ref _PreviousPageBitmap); + + // Reset our size back to the + // default for the new orientation + + this.Size = (value == eOrientation.Horizontal) ? + new Size(Dpi.Width(_MinWidth), Dpi.Height(_ButtonSize)) : new Size(Dpi.Width(_ButtonSize), Dpi.Height(_MinWidth)); + + NeedRecalcSize = true; + + this.Refresh(); + } + } + } + + protected override void ScaleItem(SizeF factor) + { + ReleaseBitmap(ref _PreviousPageBitmap); + ReleaseBitmap(ref _TodayBitmap); + ReleaseBitmap(ref _NextPageBitmap); + + this.Size = (Orientation == eOrientation.Horizontal) ? + new Size(Dpi.Width(_MinWidth), Dpi.Height(_ButtonSize)) : new Size(Dpi.Width(_ButtonSize), Dpi.Height(_MinWidth)); + base.ScaleItem(factor); + } + + #endregion + + #region ClickAutoRepeat + + /// + /// Gets or sets whether Click event will be auto repeated + /// when mouse button is kept pressed over the item + /// + [Browsable(false), DevCoBrowsable(false), DefaultValue(false), Category("Behavior")] + [Description("Gets or sets whether Click event will be auto repeated when the mouse button is kept pressed over the item.")] + public override bool ClickAutoRepeat + { + get { return (base.ClickAutoRepeat); } + set { base.ClickAutoRepeat = value; } + } + + #endregion + + #region ClickRepeatInterval + + /// + /// Gets or sets the auto-repeat interval for the click event + /// when mouse button is kept pressed over the item + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(200), Category("Behavior")] + [Description("Gets or sets the auto-repeat interval for the click event when the mouse button is kept pressed over the item.")] + public override int ClickRepeatInterval + { + get { return (base.ClickRepeatInterval); } + set { base.ClickRepeatInterval = value; } + } + + #endregion + + #region PreviousPageTooltip + + /// + /// Gets or sets the tooltip for the PreviousPage button of the control + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates tooltip for the PreviousPage button of the control.")] + public string PreviousPageTooltip + { + get { return _PreviousPageTooltip; } + + set + { + _PreviousPageTooltip = value; + + UpdateTooltip(); + } + } + + #endregion + + #region TodayTooltip + + /// + /// Gets or sets the tooltip for the Today button + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates tooltip for the TodayPage button of the control.")] + public string TodayTooltip + { + get { return (_TodayTooltip); } + + set + { + _TodayTooltip = value; + + UpdateTooltip(); + } + } + + #endregion + + #region NextPageTooltip + + /// + /// Gets or sets the tooltip for the NextPage button + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance")] + [Description("Indicates tooltip for the NextPage button of the control.")] + public string NextPageTooltip + { + get { return (_NextPageTooltip); } + + set + { + _NextPageTooltip = value; + + UpdateTooltip(); + } + } + + #endregion + + #endregion + + #region RecalcSize + + /// + /// Handles size recalc + /// + public override void RecalcSize() + { + // Update our layout + + UpdateLayout(); + + base.RecalcSize(); + } + + #endregion + + #region OnExternalSizeChange + + /// + /// Handles external size changes + /// + protected override void OnExternalSizeChange() + { + UpdateLayout(); + + base.OnExternalSizeChange(); + } + + #endregion + + #region UpdateLayout + + /// + /// Lays out our control based upon its + /// vertical / horizontal orientation + /// + private void UpdateLayout() + { + Rectangle r = Bounds; + + if (Orientation == eOrientation.Horizontal) + { + int dx = r.Width / 3; + + _PreviousPageBounds = new Rectangle(r.Left, r.Top, dx, r.Height); + _NextPageBounds = new Rectangle(r.Right - dx, r.Top, dx, r.Height); + + _TodayBounds = new Rectangle(r.Left + dx, r.Top, r.Width - dx * 2, r.Height); + } + else + { + int dy = r.Height / 3; + + _PreviousPageBounds = new Rectangle(r.Left, r.Top, r.Width, dy); + _NextPageBounds = new Rectangle(r.Left, r.Bottom - dy, r.Width, dy); + + _TodayBounds = new Rectangle(r.Left, r.Y + dy, r.Width, r.Height - dy * 2); + } + } + + #endregion + + #region Paint + + /// + /// Handles control rendering + /// + /// + public override void Paint(ItemPaintArgs e) + { + Graphics g = e.Graphics; + + Office2007ScrollBarColorTable colorTable = + ((Office2007Renderer)GlobalManager.Renderer).ColorTable.ScrollBar; + + DrawPreviousPage(g, colorTable); + DrawToday(g, colorTable); + DrawNextPage(g, colorTable); + } + + #region DrawPreviousPage + + /// + /// Draws the PreviousPage button + /// + /// Graphics + /// Office2007ScrollBarColorTable + private void DrawPreviousPage(Graphics g, Office2007ScrollBarColorTable ct) + { + Office2007ScrollBarStateColorTable cst = + GetPageColorTable(ct, ePageNavigatorPart.PreviousPage); + + float angle = (Orientation == eOrientation.Horizontal) ? 90f : 0f; + + using (LinearGradientBrush lbr = new LinearGradientBrush( + _PreviousPageBounds, cst.Background.Start, cst.Background.End, angle)) + { + if (cst.TrackBackground.Count > 0) + lbr.InterpolationColors = + cst.TrackBackground.GetColorBlend(); + + g.FillRectangle(lbr, _PreviousPageBounds); + } + + g.DrawImageUnscaled( + GetPreviousPageBitmap(g, cst), + CenterRect(_PreviousPageBounds)); + } + + #region GetPreviousPageBitmap + + /// + /// Gets the PreviousPage bitmap + /// + /// + /// + /// + private Bitmap GetPreviousPageBitmap( + Graphics g, Office2007ScrollBarStateColorTable cst) + { + if (_PreviousPageBitmap == null) + _PreviousPageBitmap = CreatePreviousPageBitmap(g, cst); + + return (_PreviousPageBitmap); + } + + /// + /// Creates the PreviousPage bitmap + /// + /// + /// + /// + private Bitmap CreatePreviousPageBitmap( + Graphics g, Office2007ScrollBarStateColorTable cst) + { + Bitmap bmp = new Bitmap(Dpi.Width10, Dpi.Height10, g); + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + using (GraphicsPath path = new GraphicsPath()) + { + float angle; + + if (Orientation == eOrientation.Horizontal) + { + angle = 90; + + path.AddLines(new Point[] { + new Point(Dpi.Width8,0), + new Point(Dpi.Width4,Dpi.Height4), + new Point(Dpi.Width8,Dpi.Height8) + }); + + path.CloseFigure(); + + path.AddLines(new Point[] { + new Point(Dpi.Width4,0), + new Point(0,Dpi.Height4), + new Point(Dpi.Width4,Dpi.Height8) + }); + + path.CloseFigure(); + } + else + { + angle = 0; + + path.AddLines(new Point[] { + new Point(0,Dpi.Height5), + new Point(Dpi.Width4,0), + new Point(Dpi.Width8,Dpi.Height5) + }); + + path.CloseFigure(); + + path.AddLines(new Point[] { + new Point(0,Dpi.Height9), + new Point(Dpi.Width4,Dpi.Height4), + new Point(Dpi.Width8,Dpi.Height9) + }); + + path.CloseFigure(); + } + + Rectangle r = new Rectangle(0, 0, Dpi.Width10, Dpi.Height10); + + using (LinearGradientBrush lbr = new + LinearGradientBrush(r, cst.ThumbSignBackground.Start, cst.ThumbSignBackground.End, angle)) + { + gBmp.FillPath(lbr, path); + } + } + } + + return (bmp); + } + + #endregion + + #endregion + + #region DrawToday + + /// + /// Draws the Today button + /// + /// Graphics + /// Office2007ScrollBarColorTable + private void DrawToday(Graphics g, Office2007ScrollBarColorTable ct) + { + Office2007ScrollBarStateColorTable cst = + GetPageColorTable(ct, ePageNavigatorPart.Today); + + float angle = (Orientation == eOrientation.Horizontal) ? 90f : 0f; + + using (LinearGradientBrush lbr = new LinearGradientBrush( + _TodayBounds, cst.Background.Start, cst.Background.End, angle)) + { + if (cst.TrackBackground.Count > 0) + lbr.InterpolationColors = cst.TrackBackground.GetColorBlend(); + + g.FillRectangle(lbr, _TodayBounds); + } + + g.DrawImageUnscaled( + GetTodayBitmap(g, cst), + CenterRect(_TodayBounds)); + } + + #region GetTodayBitmap + + /// + /// Gets the Today Bitmap + /// + /// + /// + /// + private Bitmap GetTodayBitmap( + Graphics g, Office2007ScrollBarStateColorTable cst) + { + if (_TodayBitmap == null) + _TodayBitmap = CreateTodayBitmap(g, cst); + + return (_TodayBitmap); + } + + /// + /// Creates the Today Bitmap + /// + /// + /// + /// + private Bitmap CreateTodayBitmap( + Graphics g, Office2007ScrollBarStateColorTable cst) + { + Bitmap bmp = new Bitmap(Dpi.Width10, Dpi.Height10, g); + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + Rectangle r = new Rectangle(Dpi.Width1, Dpi.Height1, Dpi.Width6, Dpi.Height6); + + gBmp.SmoothingMode = SmoothingMode.HighQuality; + + Color color = ControlPaint.LightLight(cst.ThumbSignBackground.Start); + + using (SolidBrush br = new SolidBrush(color)) + { + gBmp.FillEllipse(br, r); + } + + using (Pen pen = new Pen(cst.ThumbSignBackground.End, Dpi.Width1)) + { + gBmp.DrawEllipse(pen, r); + } + } + + return (bmp); + } + + #endregion + + #endregion + + #region DrawNextPage + + /// + /// Draws the NextPage button + /// + /// + /// + private void DrawNextPage(Graphics g, Office2007ScrollBarColorTable ct) + { + Office2007ScrollBarStateColorTable cst = + GetPageColorTable(ct, ePageNavigatorPart.NextPage); + + float angle = (Orientation == eOrientation.Horizontal) ? 90f : 0f; + + using (LinearGradientBrush lbr = new LinearGradientBrush( + _NextPageBounds, cst.Background.Start, cst.Background.End, angle)) + { + if (cst.TrackBackground.Count > 0) + lbr.InterpolationColors = cst.TrackBackground.GetColorBlend(); + + g.FillRectangle(lbr, _NextPageBounds); + } + + g.DrawImageUnscaled( + GetNextPageBitmap(g, cst), + CenterRect(_NextPageBounds)); + } + + #region GetNextPageBitmap + + /// + /// Gets the NextPage Bitmap + /// + /// + /// + /// + private Bitmap GetNextPageBitmap(Graphics g, Office2007ScrollBarStateColorTable cst) + { + if (_NextPageBitmap == null) + _NextPageBitmap = CreateNextPageBitmap(g, cst); + + return (_NextPageBitmap); + } + + /// + /// Creates the NextPage Bitmap + /// + /// + /// + /// + private Bitmap CreateNextPageBitmap(Graphics g, Office2007ScrollBarStateColorTable cst) + { + Bitmap bmp = new Bitmap(Dpi.Width10, Dpi.Height10, g); + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + using (GraphicsPath path = new GraphicsPath()) + { + float angle; + + if (Orientation == eOrientation.Horizontal) + { + angle = 90; + + path.AddLines(new Point[] { + new Point(Dpi.Width1,0), + new Point(Dpi.Width5,Dpi.Height4), + new Point(Dpi.Width1,Dpi.Height8) + }); + + path.CloseFigure(); + + path.AddLines(new Point[] { + new Point(Dpi.Width5,0), + new Point(Dpi.Width9,Dpi.Height4), + new Point(Dpi.Width5,Dpi.Height8) + }); + + path.CloseFigure(); + } + else + { + angle = 0; + + path.AddLines(new Point[] { + new Point(Dpi.Width1,0), + new Point(Dpi.Width8,0), + new Point(Dpi.Width4,Dpi.Height4) + }); + + path.CloseFigure(); + + path.AddLines(new Point[] { + new Point(Dpi.Width1,Dpi.Height4), + new Point(Dpi.Width8,Dpi.Height4), + new Point(Dpi.Width4,Dpi.Height8) + }); + + path.CloseFigure(); + } + + Rectangle r = new Rectangle(0, 0, Dpi.Width10, Dpi.Height10); + + DisplayHelp.FillPath(gBmp, path, cst.ThumbSignBackground); + //using (LinearGradientBrush lbr = new + // LinearGradientBrush(r, cst.ThumbSignBackground.Start, cst.ThumbSignBackground.End, angle)) + //{ + // gBmp.FillPath(lbr, path); + //} + } + } + + return (bmp); + } + + #endregion + + #endregion + + #region GetPageColorTable + + private Office2007ScrollBarStateColorTable + GetPageColorTable(Office2007ScrollBarColorTable ct, ePageNavigatorPart part) + { + if (GetEnabled() == false) + return (ct.Disabled); + + if (MouseDownPart == part) + return (ct.Pressed); + + if (MouseOverPart == part) + return (ct.MouseOver); + + return (ct.Default); + } + + #endregion + + #region CenterRect + + /// + /// Centers the given rect + /// + /// + /// + private Rectangle CenterRect(Rectangle r) + { + r.X += (r.Width - 10) / 2 + 1; + r.Y += (r.Height - 10) / 2 + 1; + + if (r.X < 0) + r.X = 0; + + if (r.Y < 0) + r.Y = 0; + + return (r); + } + + #endregion + + #endregion + + #region Mouse support + + #region InternalMouseMove + + /// + /// Processes InternalMouseMove events + /// + /// + public override void InternalMouseMove(MouseEventArgs objArg) + { + if (GetEnabled() == true && DesignMode == false) + { + if (MouseDownPart == ePageNavigatorPart.None) + MouseOverPart = HitTest(objArg.Location); + } + + base.InternalMouseMove(objArg); + } + + #region HitTest + + /// + /// Returns the HitText area for the given point + /// + /// + /// + public ePageNavigatorPart HitTest(Point pt) + { + if (_PreviousPageBounds.Contains(pt)) + return (ePageNavigatorPart.PreviousPage); + + if (_NextPageBounds.Contains(pt)) + return (ePageNavigatorPart.NextPage); + + if (_TodayBounds.Contains(pt)) + return (ePageNavigatorPart.Today); + + return (ePageNavigatorPart.None); + } + + #endregion + + #endregion + + #region InternalMouseLeave + + /// + /// Processes Mouse Leave events + /// + public override void InternalMouseLeave() + { + DisposeClickTimer(); + + MouseOverPart = ePageNavigatorPart.None; + MouseDownPart = ePageNavigatorPart.None; + + base.InternalMouseLeave(); + } + + #endregion + + #region InternalMouseDown + + /// + /// Processes Mouse Down events + /// + /// + public override void InternalMouseDown(MouseEventArgs objArg) + { + if (objArg.Button == MouseButtons.Left) + { + if (GetEnabled() && DesignMode == false) + { + MouseDownPart = HitTest(objArg.Location); + + if (MouseDownPart != ePageNavigatorPart.None) + { + switch (MouseDownPart) + { + case ePageNavigatorPart.PreviousPage: + OnNavigatePreviousPage(); + break; + + case ePageNavigatorPart.NextPage: + OnNavigateNextPage(); + break; + + default: + OnNavigateToday(); + break; + } + } + } + } + + base.InternalMouseDown(objArg); + } + + #endregion + + #region InternalMouseUp + + /// + /// Processes Mouse Up events + /// + /// + public override void InternalMouseUp(MouseEventArgs objArg) + { + DisposeClickTimer(); + + MouseDownPart = ePageNavigatorPart.None; + + base.InternalMouseUp(objArg); + } + + #endregion + + #endregion + + #region OnNavigate + + /// + /// Raises the NavigatePreviousPage event + /// + protected virtual void OnNavigatePreviousPage() + { + if (NavigatePreviousPage != null) + NavigatePreviousPage(this, EventArgs.Empty); + + EnableClickTimer(); + } + + /// + /// Raises the NavigateToday event + /// + protected virtual void OnNavigateToday() + { + if (NavigateToday != null) + NavigateToday(this, EventArgs.Empty); + } + + /// + /// Raises the NavigateNextPage event + /// + protected virtual void OnNavigateNextPage() + { + if (NavigateNextPage != null) + NavigateNextPage(this, EventArgs.Empty); + + EnableClickTimer(); + } + + #endregion + + #region Timer support + + #region ClickTimerTick + + /// + /// Handles timer click events + /// + /// + /// + private void ClickTimerTick(object sender, EventArgs e) + { + switch (MouseDownPart) + { + case ePageNavigatorPart.PreviousPage: + OnNavigatePreviousPage(); + break; + + case ePageNavigatorPart.NextPage: + OnNavigateNextPage(); + break; + } + + // Auto ramp-up + + if (_ClickTimer != null) + { + _AutoClickCount++; + + if (_AutoClickCount > 4 && _ClickTimer.Interval > 20) + _ClickTimer.Interval -= 10; + } + } + + #endregion + + #region UpdateClickTimer + + /// + /// Enables our click timer + /// + private void EnableClickTimer() + { + if (ClickRepeatInterval > 0) + { + if (_ClickTimer == null) + { + _ClickTimer = new Timer(); + + _ClickTimer.Interval = ClickRepeatInterval; + _ClickTimer.Tick += ClickTimerTick; + + _ClickTimer.Start(); + + _AutoClickCount = 0; + } + } + } + + #endregion + + #region DisposeClickTimer + + /// + /// Disposes of the click timer + /// + private void DisposeClickTimer() + { + if (_ClickTimer != null) + { + _ClickTimer.Tick -= ClickTimerTick; + + _ClickTimer.Stop(); + _ClickTimer.Dispose(); + + _ClickTimer = null; + } + } + + #endregion + + #endregion + + #region OnTooltipChanged + + /// + /// OnTooltipChanged + /// + protected override void OnTooltipChanged() + { + UpdateTooltip(); + + base.OnTooltipChanged(); + } + + #endregion + + #region UpdateTooltip + + /// + /// Updates the control tooltip + /// + private void UpdateTooltip() + { + if (this.DesignMode == false) + { + string tip = ""; + + switch (MouseOverPart) + { + case ePageNavigatorPart.PreviousPage: + tip = _PreviousPageTooltip; + break; + + case ePageNavigatorPart.Today: + tip = _TodayTooltip; + break; + + case ePageNavigatorPart.NextPage: + tip = _NextPageTooltip; + break; + } + + if (tip.Equals("") == false) + { + if (m_Tooltip != tip) + { + m_Tooltip = tip; + + if (this.ToolTipVisible) + this.ShowToolTip(); + } + } + } + } + + #endregion + + #region Copy + + /// + /// Returns copy of the item + /// + public override BaseItem Copy() + { + PageNavigatorItem objCopy = new PageNavigatorItem(Name); + + this.CopyToItem(objCopy); + + return (objCopy); + } + /// + /// Copies the PageNavigatorItem specific properties to + /// new instance of the item + /// + /// New PageNavigatorItem instance + protected override void CopyToItem(BaseItem copy) + { + PageNavigatorItem c = copy as PageNavigatorItem; + + if (c != null) + { + base.CopyToItem(c); + + c.PreviousPageTooltip = _PreviousPageTooltip; + c.TodayTooltip = _TodayTooltip; + c.NextPageTooltip = _NextPageTooltip; + } + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + protected override void Dispose(bool disposing) + { + DisposeClickTimer(); + + ReleaseBitmap(ref _PreviousPageBitmap); + ReleaseBitmap(ref _TodayBitmap); + ReleaseBitmap(ref _NextPageBitmap); + + base.Dispose(disposing); + } + + /// + /// Releases the given bitmap + /// + /// Bitmap to release + private void ReleaseBitmap(ref Bitmap bmp) + { + if (bmp != null) + { + bmp.Dispose(); + bmp = null; + } + } + + #endregion + } + + #region Enums + + /// + /// Defines the PageNavigator item parts + /// + public enum ePageNavigatorPart + { + /// + /// Indicates no part + /// + None, + + /// + /// Indicates the PreviousPage button of the control + /// + PreviousPage, + + /// + /// Indicates the TodayPage button of the control + /// + Today, + + /// + /// Indicates the NextPage button of the control + /// + NextPage, + } + + #endregion + +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/PageSlider.ico b/PROMS/DotNetBar Source Code/Controls/PageSlider.ico new file mode 100644 index 00000000..952a8a68 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/PageSlider.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/PageSlider/PageSlider.cs b/PROMS/DotNetBar Source Code/Controls/PageSlider/PageSlider.cs new file mode 100644 index 00000000..8a05b5a0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/PageSlider/PageSlider.cs @@ -0,0 +1,1341 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; +using DevComponents.DotNetBar.ScrollBar; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(true), Description("Page Slider Control with Touch Support")] + [Designer("DevComponents.DotNetBar.Design.PageSliderDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + [DefaultEvent("SelectedPageChanged"), DefaultProperty("SelectedPageIndex")] + [ToolboxBitmap(typeof(StepIndicator), "Controls.PageSlider.ico")] + public class PageSlider : Control + { + #region Constructor + private StepIndicator _StepIndicator; + private Touch.TouchHandler _TouchHandler = null; + private HScrollBarAdv _HorizontalScrollBar = null; + private VScrollBarAdv _VerticalScrollBar = null; + /// + /// Initializes a new instance of the PageSlider class. + /// + public PageSlider() + { + _StepIndicator = new StepIndicator(); + _StepIndicator.Dock = DockStyle.Top; + this.Controls.Add(_StepIndicator); + if (BarFunctions.IsWindows7 && Touch.TouchHandler.IsTouchEnabled) + { + _TouchHandler = new DevComponents.DotNetBar.Touch.TouchHandler(this); + _TouchHandler.PanBegin += new EventHandler(TouchHandlerPanBegin); + _TouchHandler.Pan += new EventHandler(TouchHandlerPan); + _TouchHandler.PanEnd += new EventHandler(TouchHandlerPanEnd); + } + _HorizontalScrollBar = new HScrollBarAdv(); + _HorizontalScrollBar.Dock = DockStyle.Bottom; + _HorizontalScrollBar.Height = 12; + _HorizontalScrollBar.Scroll += new ScrollEventHandler(ScrollBarScroll); + _HorizontalScrollBar.Visible = false; + this.Controls.Add(_HorizontalScrollBar); + + _VerticalScrollBar = new VScrollBarAdv(); + _VerticalScrollBar.Dock = DockStyle.Right; + _VerticalScrollBar.Width = 12; + _VerticalScrollBar.Scroll += new ScrollEventHandler(ScrollBarScroll); + _VerticalScrollBar.Visible = false; + this.Controls.Add(_VerticalScrollBar); + } + + protected override void Dispose(bool disposing) + { + StopScrollBarTimer(); + + _HorizontalScrollBar.Scroll -= new ScrollEventHandler(ScrollBarScroll); + _VerticalScrollBar.Scroll -= new ScrollEventHandler(ScrollBarScroll); + _HorizontalScrollBar.Dispose(); + _VerticalScrollBar.Dispose(); + _VerticalScrollBar = null; + _HorizontalScrollBar = null; + if (_TouchHandler != null) + { + _TouchHandler.PanBegin -= new EventHandler(TouchHandlerPanBegin); + _TouchHandler.Pan -= new EventHandler(TouchHandlerPan); + _TouchHandler.PanEnd -= new EventHandler(TouchHandlerPanEnd); + _TouchHandler.Release(); + } + + base.Dispose(disposing); + } + + #endregion + + #region Events + /// + /// Occurs when selected page has changed. + /// + [Description("Occurs when selected page has changed.")] + public event EventHandler SelectedPageChanged; + /// + /// Raises SelectedPageChanged event. + /// + /// Provides event arguments. + protected virtual void OnSelectedPageChanged(EventArgs e) + { + EventHandler handler = SelectedPageChanged; + if (handler != null) + handler(this, e); + } + #endregion + + #region Implementation + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + if (Dpi.RecordScalePerControl) + Dpi.SetScaling(factor); + //_StepIndicator.Height = Dpi.Height(_StepIndicator.Height); + base.ScaleControl(factor, specified); + } + + protected override Size DefaultSize + { + get + { + return new Size(300, 200); + } + } + protected override void OnHandleCreated(EventArgs e) + { + if (_UpdateScrollBarVisibilityDelayed) + { + _UpdateScrollBarVisibilityDelayed = false; + UpdateScrollBarVisibility(); + } + UpdateBoundsForAllPages(false); + base.OnHandleCreated(e); + } + protected override void OnHandleDestroyed(EventArgs e) + { + StopScrollBarTimer(); + base.OnHandleDestroyed(e); + } + + private bool _IndicatorVisible = true; + /// + /// Gets or sets whether current page indicator is visible. Default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether current page indicator is visible.")] + public bool IndicatorVisible + { + get { return _IndicatorVisible; } + set + { + if (value != _IndicatorVisible) + { + bool oldValue = _IndicatorVisible; + _IndicatorVisible = value; + OnIndicatorVisibleChanged(oldValue, value); + } + } + } + /// + /// Called when IndicatorVisible property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnIndicatorVisibleChanged(bool oldValue, bool newValue) + { + _StepIndicator.Visible = newValue; + } + + protected override void OnControlAdded(ControlEventArgs e) + { + if (e.Control is PageSliderPage) + { + PageSliderPage page = (PageSliderPage)e.Control; + UpdatePageTable(); + page.Bounds = GetPageBounds(page); + UpdateScrollBar(); + } + base.OnControlAdded(e); + } + protected override void OnControlRemoved(ControlEventArgs e) + { + if (e.Control is PageSliderPage) + { + PageSliderPage page = (PageSliderPage)e.Control; + int pageIndex = _PageTable.IndexOf(page); + _PageTable.Remove(page); + UpdatePageTable(); + if (_SelectedPage == page) + { + if (_PageTable.Count > 0) + this.SelectedPage = _PageTable[pageIndex > 0 ? pageIndex-- : 0]; + else + this.SelectedPage = null; + } + UpdateScrollBar(); + UpdateBoundsForAllPages(false, true); + } + base.OnControlRemoved(e); + } + protected override void OnLayout(LayoutEventArgs levent) + { + base.OnLayout(levent); + if (levent.AffectedProperty == "ChildIndex") + { + UpdatePageTable(); + UpdateBoundsForAllPages(true, true); + } + } + private void UpdateBoundsForAllPages(bool updateControl) + { + UpdateBoundsForAllPages(updateControl, false); + } + private void UpdateBoundsForAllPages(bool updateControl, bool syncPageIndicator) + { + Rectangle selectedPageBounds = GetSelectedPageBounds(); + int currentPage = -1; + for (int i = 0; i < _PageTable.Count; i++) + { + + PageSliderPage page = _PageTable[i]; + page.Bounds = GetPageBounds(page); + if (updateControl && page.Bounds.IntersectsWith(this.ClientRectangle)) + this.Update(); + if (syncPageIndicator && !_PageBoundsOffset.IsEmpty && page.Bounds.IntersectsWith(selectedPageBounds) && currentPage == -1) + currentPage = i + 1; + } + if (syncPageIndicator && _PageBoundsOffset.IsEmpty) + currentPage = this.SelectedPageIndex + 1; + if (syncPageIndicator && currentPage > 0) + _StepIndicator.CurrentStep = currentPage; + UpdateScrollBar(); + } + private void UpdateScrollBar() + { + int selectedPageIndex = this.SelectedPageIndex; + Rectangle selectedPageBounds = GetSelectedPageBounds(); + Rectangle firstPageBounds = Rectangle.Empty, lastPageBounds = Rectangle.Empty; + if (_PageTable.Count > 0) + { + firstPageBounds = _PageTable[0].Bounds; + lastPageBounds = _PageTable[_PageTable.Count - 1].Bounds; + } + + if (_Orientation == eOrientation.Horizontal) + { + _HorizontalScrollBar.Minimum = 0; + _HorizontalScrollBar.Maximum = Math.Max(1, lastPageBounds.Right - firstPageBounds.X + (selectedPageIndex == -1 ? firstPageBounds.X : 0)); + _HorizontalScrollBar.LargeChange = Math.Max(1, selectedPageBounds.Width); + _HorizontalScrollBar.SmallChange = 32; + if (!_IsScrolling && selectedPageIndex != -1) + _HorizontalScrollBar.Value = Math.Min(Math.Max(_HorizontalScrollBar.Minimum, Math.Abs(firstPageBounds.X)), _HorizontalScrollBar.Maximum); + } + else + { + _VerticalScrollBar.Minimum = 0; + _VerticalScrollBar.Maximum = Math.Max(1, lastPageBounds.Bottom - firstPageBounds.Y + (selectedPageIndex == -1 ? firstPageBounds.Y : 0)); + _VerticalScrollBar.LargeChange = Math.Max(1, selectedPageBounds.Height); + _VerticalScrollBar.SmallChange = 32; + if (!_IsScrolling && selectedPageIndex != -1) + _VerticalScrollBar.Value = Math.Min(Math.Max(_VerticalScrollBar.Minimum, Math.Abs(firstPageBounds.Y)), _VerticalScrollBar.Maximum); + } + } + + private bool _IsScrolling = false; + private int _InitialScrollValue = 0; + private void ScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.Type == ScrollEventType.EndScroll) + { + _IsScrolling = false; + Rectangle selectedPageBounds = GetSelectedPageBounds(); + PageSliderPage newSelection = this.SelectedPage; + // Find right page to select since control can be scrolled a lot using scroll-bars + if (e.NewValue > _InitialScrollValue) + { + for (int i = _PageTable.Count - 1; i >= 0; i--) + { + PageSliderPage page = _PageTable[i]; + if (page.Bounds.IntersectsWith(selectedPageBounds) && selectedPageBounds.Right - page.Left >= TriggerPageChangeOffset) + { + newSelection = page; + break; + } + } + } + else + { + for (int i = 0; i < _PageTable.Count; i++) + { + PageSliderPage page = _PageTable[i]; + if (page.Bounds.IntersectsWith(selectedPageBounds) && page.Right - selectedPageBounds.X >= TriggerPageChangeOffset) + { + newSelection = page; + break; + } + } + } + + if (this.SelectedPage != newSelection) + { + this.SelectedPage = newSelection; + if (_Orientation == eOrientation.Horizontal) + _HorizontalScrollBar.Value = Math.Abs(_PageTable[0].Left); + else + _VerticalScrollBar.Value = Math.Abs(_PageTable[0].Top); + } + else + PageBoundsOffset = Point.Empty; + } + else + { + if (!_IsScrolling) + { + if (_Orientation == eOrientation.Horizontal) + _InitialScrollValue = _HorizontalScrollBar.Value; + else + _InitialScrollValue = _VerticalScrollBar.Value; + _IsScrolling = true; + } + if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll) + PageBoundsOffset = new Point(_InitialScrollValue - e.NewValue, 0); + else + PageBoundsOffset = new Point(0, _InitialScrollValue - e.NewValue); + } + } + protected override void OnResize(EventArgs e) + { + UpdateBoundsForAllPages(false); + base.OnResize(e); + } + + private Rectangle GetSelectedPageBounds() + { + Rectangle selectedPageBounds = DeflateRectangle(this.ClientRectangle, _PagePadding); + if (_Orientation == eOrientation.Horizontal) + selectedPageBounds.Width -= _PageSpacing + _NextPageVisibleMargin; + else + selectedPageBounds.Height -= _PageSpacing + _NextPageVisibleMargin; + + if (_IndicatorVisible) + { + if (_StepIndicator.Dock == DockStyle.Top) + { + selectedPageBounds.Y += _StepIndicator.Height; + selectedPageBounds.Height -= _StepIndicator.Height; + } + else if (_StepIndicator.Dock == DockStyle.Bottom) + { + selectedPageBounds.Height -= _StepIndicator.Height; + } + else if (_StepIndicator.Dock == DockStyle.Left) + { + selectedPageBounds.X += _StepIndicator.Width; + selectedPageBounds.Width -= _StepIndicator.Width; + } + else if (_StepIndicator.Dock == DockStyle.Right) + { + selectedPageBounds.Width -= _StepIndicator.Width; + } + } + if (_ScrollBarVisibility == eScrollBarVisibility.AlwaysVisible) + { + if (_Orientation == eOrientation.Horizontal) + selectedPageBounds.Height -= _HorizontalScrollBar.Height; + else + selectedPageBounds.Width -= _HorizontalScrollBar.Width; + + } + return selectedPageBounds; + } + + private Point PageBoundsOffset + { + get { return _PageBoundsOffset; } + set + { + if (_PageBoundsOffset != value) + { + _PageBoundsOffset = value; + UpdateBoundsForAllPages(true, true); + } + } + } + private Point _PageBoundsOffset = Point.Empty; + private System.Drawing.Rectangle GetPageBounds(PageSliderPage page) + { + int pageIndex = _PageTable.IndexOf(page); + int selectedPageIndex = this.SelectedPageIndex; + Rectangle bounds = Rectangle.Empty; + + Rectangle selectedPageBounds = GetSelectedPageBounds(); + + if (pageIndex == selectedPageIndex) + { + bounds = selectedPageBounds; + } + else if (pageIndex > selectedPageIndex) + { + bounds = selectedPageBounds; + if (_Orientation == eOrientation.Horizontal) + bounds.X += (_PageSpacing + bounds.Width) * (pageIndex - selectedPageIndex); + else + bounds.Y += (_PageSpacing + bounds.Height) * (pageIndex - selectedPageIndex); + } + else + { + bounds = selectedPageBounds; + if (_Orientation == eOrientation.Horizontal) + bounds.X -= (_PageSpacing + bounds.Width) * (selectedPageIndex - pageIndex); + else + bounds.Y -= (_PageSpacing + bounds.Height) * (selectedPageIndex - pageIndex); + } + + bounds.Offset(_PageBoundsOffset); + + return bounds; + } + + private Rectangle DeflateRectangle(Rectangle rect, Padding padding) + { + rect.X += padding.Left; + rect.Y += padding.Top; + rect.Width -= padding.Horizontal; + rect.Height -= padding.Vertical; + return rect; + } + + private List _PageTable = new List(); + private void UpdatePageTable() + { + _PageTable.Clear(); + foreach (Control control in this.Controls) + { + PageSliderPage page = control as PageSliderPage; + if (page == null) continue; + bool appendPage = true; + for (int i = 0; i < _PageTable.Count; i++) + { + if (_PageTable[i].PageNumber > page.PageNumber) + { + _PageTable.Insert(i, page); + appendPage = false; + break; + } + } + if (appendPage) _PageTable.Add(page); + } + + _StepIndicator.StepCount = _PageTable.Count; + _StepIndicator.CurrentStep = this.SelectedPageIndex + 1; + } + + /// + /// Returns array of all pages in control. + /// + /// Array of pages. + public PageSliderPage[] GetAllPages() + { + return _PageTable.ToArray(); + } + + /// + /// Removes and disposes all pages within the control. + /// + public void RemoveAllPages() + { + foreach (PageSliderPage page in _PageTable) + { + page.Visible = false; + } + while (_PageTable.Count > 0) + { + PageSliderPage page = _PageTable[0]; + this.Controls.Remove(page); + page.Dispose(); + } + } + + private PageSliderPage _SelectedPage; + /// + /// Indicates selected page. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates selected page.")] + public PageSliderPage SelectedPage + { + get { return _SelectedPage; } + set + { + if (value != _SelectedPage) + { + PageSliderPage oldValue = _SelectedPage; + _SelectedPage = value; + OnSelectedPageChanged(oldValue, value); + } + } + } + /// + /// Called when SelectedPage property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSelectedPageChanged(PageSliderPage oldValue, PageSliderPage newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SelectedPage")); + if (_AnimationTime > 0) + AnimatePageTransition(oldValue, newValue); + else + UpdateBoundsForAllPages(false); + //if (newValue != null) + //{ + // newValue.Bounds = GetPageBounds(newValue); + // newValue.BringToFront(); + //} + UpdateScrollBar(); + _StepIndicator.CurrentStep = this.SelectedPageIndex + 1; + OnSelectedPageChanged(EventArgs.Empty); + } + + private void AnimatePageTransition(PageSliderPage oldValue, PageSliderPage newValue) + { + int oldIndex = -1; + if (oldValue != null) + oldIndex = _PageTable.IndexOf(oldValue); + int newIndex = -1; + if (newValue != null) + newIndex = _PageTable.IndexOf(newValue); + if (oldIndex == newIndex) + { + UpdateBoundsForAllPages(false); + _PageBoundsOffset = Point.Empty; + return; + } + int totalOffset = 0; + + Rectangle selectedPageBounds = GetSelectedPageBounds(); + + if (_Orientation == eOrientation.Horizontal) + { + totalOffset = ((oldIndex - newIndex) * (selectedPageBounds.Width + _PageSpacing)) - _PageBoundsOffset.X; + } + else + { + totalOffset = ((oldIndex - newIndex) * (selectedPageBounds.Height + _PageSpacing)) - _PageBoundsOffset.Y; + } + + _PageBoundsOffset = Point.Empty; + + DateTime startingTime = DateTime.Now; + int speedFactor = 1; + int remainOffset = Math.Abs(totalOffset); + int offsetSign = Math.Sign(totalOffset); + int animationTimeDuration = _AnimationTime; + + if (_Orientation == eOrientation.Horizontal && remainOffset < selectedPageBounds.Width * .8 || + _Orientation == eOrientation.Vertical && remainOffset < selectedPageBounds.Height * .8) + { + if (_Orientation == eOrientation.Horizontal) + animationTimeDuration *= (remainOffset / selectedPageBounds.Width); + else + animationTimeDuration *= (remainOffset / selectedPageBounds.Height); + animationTimeDuration = Math.Max(animationTimeDuration, 50); + } + + TimeSpan animationTime = new TimeSpan(0, 0, 0, 0, animationTimeDuration); + while (remainOffset > 0) + { + DateTime startPerMove = DateTime.Now; + + foreach (PageSliderPage page in _PageTable) + { + Rectangle bounds = page.Bounds; + if (_Orientation == eOrientation.Horizontal) + bounds.Offset(speedFactor * offsetSign, 0); + else + bounds.Offset(0, speedFactor * offsetSign); + page.Bounds = bounds; + if (bounds.IntersectsWith(this.ClientRectangle)) + this.Update(); + } + remainOffset -= speedFactor; + TimeSpan elapsedPerMove = DateTime.Now - startPerMove; + TimeSpan elapsedTime = DateTime.Now - startingTime; + if ((animationTime - elapsedTime).TotalMilliseconds <= 0) + speedFactor = remainOffset; + else + { + if ((int)(animationTime - elapsedTime).TotalMilliseconds == 0) + speedFactor = 1; + else + speedFactor = remainOffset * (int)elapsedPerMove.TotalMilliseconds / Math.Max(1, (int)((animationTime - elapsedTime).TotalMilliseconds)); + } + if (speedFactor > remainOffset) speedFactor = remainOffset; + } + } + + private int _AnimationTime = 250; + /// + /// Indicates the animation time in milliseconds for operations that perform visual animation of transition. Set to zero to disable animation. + /// + [DefaultValue(250), Category("Behavior"), Description("Indicates the animation time in milliseconds for operations that perform visual animation of transition. Set to zero to disable animation.")] + public int AnimationTime + { + get { return _AnimationTime; } + set + { + if (value != _AnimationTime) + { + int oldValue = _AnimationTime; + _AnimationTime = value; + OnAnimationTimeChanged(oldValue, value); + } + } + } + /// + /// Called when AnimationTime property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnAnimationTimeChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("AnimationTime")); + + } + + /// + /// Gets or sets zero based selected page index. If there is no page selected returns -1. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectedPageIndex + { + get { return _SelectedPage != null ? _PageTable.IndexOf(_SelectedPage) : -1; } + set + { + if (value < 0 || value >= _PageTable.Count) + throw new ArgumentOutOfRangeException("SelectedPageIndex must be greater or equal than 0 and less or equal than number of pages added to control."); + this.SelectedPage = _PageTable[value]; + } + } + + private int _PageCount; + /// + /// Gets the total number of pages displayed by the control. + /// + [Browsable(false)] + public int PageCount + { + get + { + return _PageTable.Count; + } + } + + private Padding _PagePadding = new Padding(4); + /// + /// Gets or sets the single page padding. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Padding PagePadding + { + get { return _PagePadding; } + set + { + if (value != _PagePadding) + { + Padding oldValue = _PagePadding; + _PagePadding = value; + OnPagePaddingChanged(oldValue, value); + } + } + } + + /// + /// Called when SelectedPagePadding property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPagePaddingChanged(Padding oldValue, Padding newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SelectedPagePadding")); + UpdateBoundsForAllPages(false); + } + + private const int DefaultPageSpacing = 48; + private int _PageSpacing = DefaultPageSpacing; + /// + /// Gets or sets the spacing in pixels between pages. + /// + [DefaultValue(DefaultPageSpacing), Category("Appearance"), Description("Indicates spacing in pixels between pages.")] + public int PageSpacing + { + get { return _PageSpacing; } + set + { + if (value != _PageSpacing) + { + int oldValue = _PageSpacing; + _PageSpacing = value; + OnPageSpacingChanged(oldValue, value); + } + } + } + /// + /// Called when PageSpacing property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPageSpacingChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("PageSpacing")); + UpdateBoundsForAllPages(false); + } + + private const int DefaultNextPageVisibleMargin = 50; + private int _NextPageVisibleMargin = DefaultNextPageVisibleMargin; + [DefaultValue(DefaultNextPageVisibleMargin)] + public int NextPageVisibleMargin + { + get { return _NextPageVisibleMargin; } + set + { + if (value != _NextPageVisibleMargin) + { + int oldValue = _NextPageVisibleMargin; + _NextPageVisibleMargin = value; + OnNextPageVisibleMarginChanged(oldValue, value); + } + } + } + /// + /// Called when NextPageVisibleMargin property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnNextPageVisibleMarginChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("NextPageVisibleMargin")); + UpdateBoundsForAllPages(false); + } + + private eOrientation _Orientation = eOrientation.Horizontal; + /// + /// Gets or sets the page layout orientation. Default is horizontal. + /// + [DefaultValue(eOrientation.Horizontal), Category("Appearance"), Description("Indicates page layout orientation.")] + public eOrientation Orientation + { + get { return _Orientation; } + set + { + if (value != _Orientation) + { + eOrientation oldValue = _Orientation; + _Orientation = value; + OnOrientationChanged(oldValue, value); + } + } + } + /// + /// Called when Orientation property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnOrientationChanged(eOrientation oldValue, eOrientation newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Orientation")); + UpdateBoundsForAllPages(false); + } + + protected override void WndProc(ref Message m) + { + if (m.Msg == (int)WinApi.WindowsMessages.WM_APPCOMMAND) + { + int cmd = WinApi.GetAppCommandLParam(m.LParam); + if (cmd == (int)WinApi.AppCommands.APPCOMMAND_BROWSER_BACKWARD) + { + if (this.SelectedPageIndex > 0) + this.SelectedPageIndex--; + m.Result = new IntPtr(1); + } + else if (cmd == (int)WinApi.AppCommands.APPCOMMAND_BROWSER_FORWARD) + { + if (this.SelectedPageIndex < _PageTable.Count - 1) + this.SelectedPageIndex++; + m.Result = new IntPtr(1); + } + } + base.WndProc(ref m); + } + private bool _MouseDrag = false; + protected override void OnMouseDown(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left && _TouchHandler == null && _PageTable.Count > 0 && _MouseDragEnabled) + { + _MouseDrag = true; + _TouchStartLocation = e.Location; + } + base.OnMouseDown(e); + } + + private bool _PageMouseDragEnabled = true; + /// + /// Indicates whether page can be dragged using mouse to change currently selected page + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether page can be dragged using mouse to change currently selected page")] + public bool PageMouseDragEnabled + { + get { return _PageMouseDragEnabled; } + set + { + _PageMouseDragEnabled = value; + } + } + private bool _MouseDragEnabled = true; + /// + /// Indicates whether selected page can be changed by using mouse drag on PageSlider client area which is not covered by pages. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether selected page can be changed by using mouse drag on PageSlider client area which is not covered by pages.")] + public bool MouseDragEnabled + { + get { return _MouseDragEnabled; } + set + { + _MouseDragEnabled = value; + } + } + + + internal void StartPageDrag() + { + if (_PageMouseDragEnabled && !_MouseDrag && Control.MouseButtons == MouseButtons.Left && _TouchHandler == null && _PageTable.Count > 0) + { + this.Capture = true; + _MouseDrag = true; + _TouchStartLocation = this.PointToClient(Control.MousePosition); + } + } + private int MaximumReversePageOffset + { + get + { + return Math.Min(32, this.Width / 6); + } + } + private int TriggerPageChangeOffset + { + get + { + return Math.Max(32, this.Width / 5); + } + } + protected override void OnMouseMove(MouseEventArgs e) + { + if (_ScrollBarVisibility == eScrollBarVisibility.AutoVisible && !_HorizontalScrollBar.Visible && !_VerticalScrollBar.Visible) + StartScrollBarTimer(); + + if (_MouseDrag) + { + Rectangle selectedPageBounds = GetSelectedPageBounds(); + if (_Orientation == eOrientation.Horizontal) + { + int offset = e.Location.X - _TouchStartLocation.X; + int offsetChange = offset - _PageBoundsOffset.X; + Rectangle firstPageBounds = GetPageBounds(_PageTable[0]); + if (_PageTable[0].Left + offsetChange > selectedPageBounds.X + MaximumReversePageOffset && SelectedPageIndex >= 0) + { + offset -= (_PageTable[0].Left + offsetChange) - (selectedPageBounds.X + MaximumReversePageOffset); + } + else if (_PageTable[_PageTable.Count - 1].Left + offsetChange < selectedPageBounds.X - MaximumReversePageOffset) + { + offset += (selectedPageBounds.X - MaximumReversePageOffset) - (_PageTable[_PageTable.Count - 1].Left + offsetChange); + } + PageBoundsOffset = new Point(offset, 0); + } + else + { + int offset = e.Location.Y - _TouchStartLocation.Y; + int offsetChange = offset - _PageBoundsOffset.Y; + Rectangle firstPageBounds = GetPageBounds(_PageTable[0]); + if (_PageTable[0].Top + offsetChange > selectedPageBounds.Y + MaximumReversePageOffset && SelectedPageIndex >= 0) + { + offset -= (_PageTable[0].Top + offsetChange) - (selectedPageBounds.Y + MaximumReversePageOffset); + } + else if (_PageTable[_PageTable.Count - 1].Top + offsetChange < selectedPageBounds.Y - MaximumReversePageOffset) + { + offset += (selectedPageBounds.Y - MaximumReversePageOffset) - (_PageTable[_PageTable.Count - 1].Top + offsetChange); + } + PageBoundsOffset = new Point(0, offset); + } + } + base.OnMouseMove(e); + } + protected override void OnMouseUp(MouseEventArgs e) + { + if (_MouseDrag) + { + _MouseDrag = false; + int totalMoveOffset = _Orientation == eOrientation.Horizontal ? _PageBoundsOffset.X : _PageBoundsOffset.Y; + if (Math.Abs(totalMoveOffset) >= TriggerPageChangeOffset) + { + Rectangle selectedPageBounds = GetSelectedPageBounds(); + if (totalMoveOffset < 0) + { + if (this.SelectedPageIndex < _PageTable.Count - 1) + { + PageSliderPage newSelection = _PageTable[this.SelectedPageIndex + 1]; + // Find right page to select since control can be scrolled a lot through inertia + for (int i = _PageTable.Count - 1; i >= 0; i--) + { + PageSliderPage page = _PageTable[i]; + if (page.Bounds.IntersectsWith(selectedPageBounds) && selectedPageBounds.Right - page.Left >= TriggerPageChangeOffset) + { + newSelection = page; + break; + } + } + if (this.SelectedPage != newSelection) + this.SelectedPage = newSelection; + else + PageBoundsOffset = Point.Empty; + } + else + PageBoundsOffset = Point.Empty; + } + else + { + if (this.SelectedPageIndex > 0) + { + PageSliderPage newSelection = _PageTable[this.SelectedPageIndex - 1]; + // Find right page to select since control can be scrolled a lot through inertia + for (int i = 0; i < _PageTable.Count; i++) + { + PageSliderPage page = _PageTable[i]; + if (page.Bounds.IntersectsWith(selectedPageBounds) && page.Right - selectedPageBounds.X >= TriggerPageChangeOffset) + { + newSelection = page; + break; + } + } + if (this.SelectedPage != newSelection) + this.SelectedPage = newSelection; + else + PageBoundsOffset = Point.Empty; + } + else + PageBoundsOffset = Point.Empty; + } + } + else + PageBoundsOffset = Point.Empty; + } + base.OnMouseUp(e); + } + + protected override void OnVisibleChanged(EventArgs e) + { + if (_ScrollBarVisibility == eScrollBarVisibility.AutoVisible && this.Visible) + { + StartScrollBarTimer(); + } + base.OnVisibleChanged(e); + } + + private eScrollBarVisibility _ScrollBarVisibility = eScrollBarVisibility.AutoVisible; + /// + /// Indicates scrollbar visibility. + /// + [DefaultValue(eScrollBarVisibility.AutoVisible), Category("Behavior"), Description("Indicates scrollbar visibility.")] + public eScrollBarVisibility ScrollBarVisibility + { + get { return _ScrollBarVisibility; } + set + { + if (value != _ScrollBarVisibility) + { + eScrollBarVisibility oldValue = _ScrollBarVisibility; + _ScrollBarVisibility = value; + OnScrollBarVisibilityChanged(oldValue, value); + } + } + } + + /// + /// Called when ScrollBarVisibility property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnScrollBarVisibilityChanged(eScrollBarVisibility oldValue, eScrollBarVisibility newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("ScrollBarVisibility")); + if (this.IsHandleCreated) + UpdateScrollBarVisibility(); + else + _UpdateScrollBarVisibilityDelayed = true; + } + + private bool _UpdateScrollBarVisibilityDelayed = false; + private void UpdateScrollBarVisibility() + { + if (_ScrollBarVisibility == eScrollBarVisibility.Hidden) + { + StopScrollBarTimer(); + _HorizontalScrollBar.Visible = false; + _VerticalScrollBar.Visible = false; + UpdateBoundsForAllPages(false); + } + else if (_ScrollBarVisibility == eScrollBarVisibility.AlwaysVisible) + { + StopScrollBarTimer(); + if (_Orientation == eOrientation.Horizontal) + { + if (!_HorizontalScrollBar.Visible) + { + _HorizontalScrollBar.Visible = true; + if (!this.IsHandleCreated && _HorizontalScrollBar.Width == 0) + _HorizontalScrollBar.Bounds = new Rectangle(this.ClientRectangle.X, + this.ClientRectangle.Bottom - _HorizontalScrollBar.Height, this.ClientRectangle.Width, _HorizontalScrollBar.Height); + UpdateBoundsForAllPages(false); + } + _VerticalScrollBar.Visible = false; + } + else + { + _HorizontalScrollBar.Visible = false; + if (!_VerticalScrollBar.Visible) + { + _VerticalScrollBar.Visible = true; + UpdateBoundsForAllPages(false); + } + } + } + else + { + Point p = this.PointToClient(Control.MousePosition); + if (_ScrollBarTimer == null && this.ClientRectangle.Contains(p)) + { + StartScrollBarTimer(); + } + } + } + private int _AutoScrollBarVisibleTime = 3000; + /// + /// Gets or sets the time in milliseconds that scrollbar is kept visible when there is no activity in control and mouse is over the control. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int AutoScrollBarVisibleTime + { + get { return _AutoScrollBarVisibleTime; } + set + { + _AutoScrollBarVisibleTime = value; + } + } + internal void MouseEnterInternal() + { + if (_ScrollBarVisibility == eScrollBarVisibility.AutoVisible) + StartScrollBarTimer(); + } + protected override void OnMouseEnter(EventArgs e) + { + MouseEnterInternal(); + base.OnMouseEnter(e); + } + protected override void OnMouseLeave(EventArgs e) + { + MouseLeaveInternal(); + base.OnMouseLeave(e); + } + + internal void MouseLeaveInternal() + { + if (_ScrollBarVisibility == eScrollBarVisibility.AutoVisible) + StartScrollBarTimer(); + } + + private Timer _ScrollBarTimer = null; + private void StartScrollBarTimer() + { + if (_Orientation == eOrientation.Horizontal) + { + _HorizontalScrollBar.Visible = true; + _VerticalScrollBar.Visible = false; + } + else + { + _HorizontalScrollBar.Visible = false; + _VerticalScrollBar.Visible = true; + } + + if (_ScrollBarTimer == null) + { + _ScrollBarTimer = new Timer(); + _ScrollBarTimer.Tick += new EventHandler(ScrollBarTimerTick); + _ScrollBarTimer.Interval = _AutoScrollBarVisibleTime; + } + _ScrollBarTimer.Stop(); + _ScrollBarTimer.Start(); + } + private Point _LastMousePosition = Point.Empty; + void ScrollBarTimerTick(object sender, EventArgs e) + { + bool hideScrollBars = false; + Point p = this.PointToClient(Control.MousePosition); + if (this.ClientRectangle.Contains(p)) + { + if (!_LastMousePosition.IsEmpty && _LastMousePosition == p && (!_HorizontalScrollBar.Bounds.Contains(p) && _HorizontalScrollBar.Visible || !_VerticalScrollBar.Bounds.Contains(p) && _VerticalScrollBar.Visible)) + hideScrollBars = true; + } + else + { + if (!_LastMousePosition.IsEmpty) + hideScrollBars = true; + } + _LastMousePosition = p; + + if (hideScrollBars) + { + StopScrollBarTimer(); + _HorizontalScrollBar.Visible = false; + _VerticalScrollBar.Visible = false; + _LastMousePosition = Point.Empty; + } + } + private void StopScrollBarTimer() + { + Timer t = _ScrollBarTimer; + _ScrollBarTimer = null; + if (t != null) + { + t.Tick -= new EventHandler(ScrollBarTimerTick); + t.Stop(); + t.Dispose(); + } + } + #endregion + + #region Touch Handling + private bool ProcessTouch(DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (_TouchEnabled == eTouchHandling.No) return false; + if (_TouchEnabled == eTouchHandling.ClientContentOnly) + { + NativeFunctions.POINT p = new NativeFunctions.POINT(e.Location); + IntPtr handle = NativeFunctions.ChildWindowFromPoint(this.Handle, p); + if (handle == IntPtr.Zero) + return false; + Control c = Control.FromChildHandle(handle); + if (c == null) return false; + if (c is PageSliderPage) + { + handle = NativeFunctions.ChildWindowFromPoint(c.Handle, p); + if (handle == IntPtr.Zero) + return false; + c = Control.FromChildHandle(handle); + if (c == null || c is PageSliderPage || c is StepIndicator + || c is Label || c is LabelX) return true; + } + if(c == this || c is StepIndicator) + return true; + return false; + } + return true; + } + + private bool _TouchDrag = false; + private Point _TouchStartLocation = Point.Empty; + private void TouchHandlerPanBegin(object sender, DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (!ProcessTouch(e)) return; + + _TouchDrag = true; + _TouchStartLocation = e.Location; + e.Handled = true; + } + + private void TouchHandlerPanEnd(object sender, DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + EndTouchPan(); + e.Handled = true; + } + } + + private void EndTouchPan() + { + _TouchDrag = false; + int totalMoveOffset = _Orientation == eOrientation.Horizontal ? _PageBoundsOffset.X : _PageBoundsOffset.Y; + if (Math.Abs(totalMoveOffset) >= TriggerPageChangeOffset) + { + Rectangle selectedPageBounds = GetSelectedPageBounds(); + if (totalMoveOffset < 0) + { + if (this.SelectedPageIndex < _PageTable.Count - 1) + { + PageSliderPage newSelection = _PageTable[this.SelectedPageIndex + 1]; + // Find right page to select since control can be scrolled a lot through inertia + for (int i = _PageTable.Count - 1; i >= 0; i--) + { + PageSliderPage page = _PageTable[i]; + if (page.Bounds.IntersectsWith(selectedPageBounds) && selectedPageBounds.Right - page.Left >= TriggerPageChangeOffset) + { + newSelection = page; + break; + } + } + if (this.SelectedPage != newSelection) + this.SelectedPage = newSelection; + else + PageBoundsOffset = Point.Empty; + } + else + PageBoundsOffset = Point.Empty; + } + else + { + if (this.SelectedPageIndex > 0) + { + PageSliderPage newSelection = _PageTable[this.SelectedPageIndex - 1]; + // Find right page to select since control can be scrolled a lot through inertia + for (int i = 0; i < _PageTable.Count; i++) + { + PageSliderPage page = _PageTable[i]; + if (page.Bounds.IntersectsWith(selectedPageBounds) && page.Right - selectedPageBounds.X >= TriggerPageChangeOffset) + { + newSelection = page; + break; + } + } + if (this.SelectedPage != newSelection) + this.SelectedPage = newSelection; + else + PageBoundsOffset = Point.Empty; + } + else + PageBoundsOffset = Point.Empty; + } + } + else + PageBoundsOffset = Point.Empty; + } + + private void TouchHandlerPan(object sender, DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + Rectangle selectedPageBounds = GetSelectedPageBounds(); + if (_Orientation == eOrientation.Horizontal) + { + int offset = e.Location.X - _TouchStartLocation.X; + int offsetChange = offset - _PageBoundsOffset.X; + Rectangle firstPageBounds = GetPageBounds(_PageTable[0]); + bool overflow = false; + if (_PageTable[0].Left + offsetChange > selectedPageBounds.X + MaximumReversePageOffset && SelectedPageIndex >= 0) + { + offset -= (_PageTable[0].Left + offsetChange) - (selectedPageBounds.X + MaximumReversePageOffset); + overflow = true; + } + else if (_PageTable[_PageTable.Count - 1].Left + offsetChange < selectedPageBounds.X - MaximumReversePageOffset) + { + offset += (selectedPageBounds.X - MaximumReversePageOffset) - (_PageTable[_PageTable.Count - 1].Left + offsetChange); + overflow = true; + } + PageBoundsOffset = new Point(offset, 0); + if (overflow && e.IsInertia) EndTouchPan(); + } + else + { + int offset = e.Location.Y - _TouchStartLocation.Y; + int offsetChange = offset - _PageBoundsOffset.Y; + Rectangle firstPageBounds = GetPageBounds(_PageTable[0]); + bool overflow = false; + if (_PageTable[0].Top + offsetChange > selectedPageBounds.Y + MaximumReversePageOffset && SelectedPageIndex >= 0) + { + offset -= (_PageTable[0].Top + offsetChange) - (selectedPageBounds.Y + MaximumReversePageOffset); + overflow = true; + } + else if (_PageTable[_PageTable.Count - 1].Top + offsetChange < selectedPageBounds.Y - MaximumReversePageOffset) + { + offset += (selectedPageBounds.Y - MaximumReversePageOffset) - (_PageTable[_PageTable.Count - 1].Top + offsetChange); + overflow = true; + } + PageBoundsOffset = new Point(0, offset); + if (overflow && e.IsInertia) EndTouchPan(); + } + e.Handled = true; + } + } + + private eTouchHandling _TouchEnabled = eTouchHandling.Yes; + /// + /// Indicates whether native touch support in control is enabled if available on target system. + /// + [DefaultValue(eTouchHandling.Yes), Category("Behavior"), Description("Indicates whether native touch support in control is enabled if available on target system.")] + public eTouchHandling TouchEnabled + { + get { return _TouchEnabled; } + set + { + if (value != _TouchEnabled) + { + eTouchHandling oldValue = _TouchEnabled; + _TouchEnabled = value; + OnTouchEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when TouchEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTouchEnabledChanged(eTouchHandling oldValue, eTouchHandling newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TouchEnabled")); + } + #endregion + } + + /// + /// Specifies scrollbar visibility. + /// + public enum eScrollBarVisibility + { + /// + /// Scrollbars are not visible. + /// + Hidden, + /// + /// Scrollbars are visible only if mouse is inside of the control. + /// + AutoVisible, + /// + /// Scrollbars are always visible. + /// + AlwaysVisible + } + + /// + /// Specifies level of touch enabled on the control. + /// + public enum eTouchHandling + { + /// + /// Touch is enabled control wide. + /// + Yes, + /// + /// Touch is disabled control wide. + /// + No, + /// + /// Touch is enabled but only for the direct control client content. If touch input occurs on any child control it is not processed. + /// + ClientContentOnly + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/PageSlider/PageSliderPage.cs b/PROMS/DotNetBar Source Code/Controls/PageSlider/PageSliderPage.cs new file mode 100644 index 00000000..2c30e0ff --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/PageSlider/PageSliderPage.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false)] + [Designer("DevComponents.DotNetBar.Design.PageSliderPageDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class PageSliderPage : Panel + { + #region Constructor + + #endregion + + #region Implementation + private int _PageNumber = 1; + /// + /// Gets or sets page number. Page number determines the order in which pages are displayed inside of the PageSlider control. + /// + [DefaultValue(1), Category("Behavior"), Description("Indicates page number. Page number determines the order in which pages are displayed inside of the PageSlider control.")] + public int PageNumber + { + get { return _PageNumber; } + set + { + if (value != _PageNumber) + { + int oldValue = _PageNumber; + _PageNumber = value; + OnPageNumberChanged(oldValue, value); + } + } + } + /// + /// Called when PageNumber property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPageNumberChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("PageNumber")); + + } + + protected override void OnMouseDown(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + PageSlider parent = this.Parent as PageSlider; + if (parent != null) parent.StartPageDrag(); + } + + base.OnMouseDown(e); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/PageSlider/StepIndicator.cs b/PROMS/DotNetBar Source Code/Controls/PageSlider/StepIndicator.cs new file mode 100644 index 00000000..afff1f1c --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/PageSlider/StepIndicator.cs @@ -0,0 +1,267 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents control which visually indicates current step in a sequence. + /// + [ToolboxItem(true)] + [ToolboxBitmap(typeof(StepIndicator), "Controls.StepIndicator.ico")] + public class StepIndicator : Control + { + #region Constructor + /// + /// Initializes a new instance of the StepIndicator class. + /// + public StepIndicator() + { + this.SetStyle(ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.Opaque | + ControlStyles.ResizeRedraw | + ControlStyles.DoubleBuffer | + ControlStyles.StandardDoubleClick | ControlStyles.StandardClick, true); + this.SetStyle(ControlStyles.Selectable, false); + } + #endregion + + #region Implementation + protected override void OnPaint(PaintEventArgs e) + { + StepIndicatorColorTable colors = GetColors(); + Color backColor = colors.BackgroundColor; + Color indicatorColor = colors.IndicatorColor; + Graphics g = e.Graphics; + Rectangle r = this.ClientRectangle; + + using (SolidBrush brush = new SolidBrush(backColor)) + g.FillRectangle(brush, r); + + int currentStep = GetCurrentStep() - 1; + if (currentStep >= 0) + { + int stepCount = _StepCount; + Rectangle indicatorBounds; + if (_Orientation == eOrientation.Horizontal) + { + int indicatorWidth = (int)Math.Ceiling((double)r.Width / stepCount); + indicatorBounds = new Rectangle(r.X + indicatorWidth * currentStep, r.Y, indicatorWidth, r.Height); + } + else + { + int indicatorHeight = (int)Math.Ceiling((double)r.Height / stepCount); + indicatorBounds = new Rectangle(r.X, r.Y + indicatorHeight * currentStep, r.Width, indicatorHeight); + } + + if (r.Width > 0 && r.Height > 0) + { + using (SolidBrush brush = new SolidBrush(indicatorColor)) + g.FillRectangle(brush, indicatorBounds); + } + } + + base.OnPaint(e); + } + + private StepIndicatorColorTable GetColors() + { + if (!_IndicatorColor.IsEmpty && !_BackgroundColor.IsEmpty) + return new StepIndicatorColorTable(_BackgroundColor, _IndicatorColor); + if (GlobalManager.Renderer is Office2007Renderer) + { + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.StepIndicator; + } + else + return new StepIndicatorColorTable(Color.White, Color.MediumSeaGreen); + } + + private int GetCurrentStep() + { + return Math.Max(0, Math.Min(_StepCount, _CurrentStep)); + } + + private int _StepCount = 10; + /// + /// Gets or sets the total number of steps that control will track. Default value is 10. + /// + [DefaultValue(10), Category("Behavior"), Description("Indicates total number of steps that control will track.")] + public int StepCount + { + get { return _StepCount; } + set + { + value = Math.Max(1, value); + if (value != _StepCount) + { + int oldValue = _StepCount; + _StepCount = value; + OnStepCountChanged(oldValue, value); + } + } + } + /// + /// Called when StepCount property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnStepCountChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("StepCount")); + this.Invalidate(); + } + + private int _CurrentStep = 1; + /// + /// Gets or sets the current step in sequence. Current step should be less or equal than StepCount. + /// + [DefaultValue(1), Category("Behavior"), Description("Indicates current step in sequence..")] + public int CurrentStep + { + get { return _CurrentStep; } + set + { + if (value != _CurrentStep) + { + int oldValue = _CurrentStep; + _CurrentStep = value; + OnCurrentStepChanged(oldValue, value); + } + } + } + /// + /// Called when CurrentStep property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCurrentStepChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("CurrentStep")); + this.Invalidate(); + } + + private static readonly Color DefaultBackgroundColor = Color.Empty; + private Color _BackgroundColor = DefaultBackgroundColor; + /// + /// Gets or sets the background color of the control. + /// + [Category("Appearance"), Description("Indicates background color of control.")] + public Color BackgroundColor + { + get { return _BackgroundColor; } + set { _BackgroundColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackgroundColor() + { + return _BackgroundColor != DefaultBackgroundColor; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundColor() + { + this.BackgroundColor = DefaultBackgroundColor; + } + + private static readonly Color DefaultIndicatorColor = Color.Empty; + private Color _IndicatorColor = DefaultIndicatorColor; + /// + /// Gets or sets the color of the current step indicator. + /// + [Category("Appearance"), Description("Indicates color of current step indicator.")] + public Color IndicatorColor + { + get { return _IndicatorColor; } + set { _IndicatorColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeIndicatorColor() + { + return _IndicatorColor != DefaultIndicatorColor; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetIndicatorColor() + { + this.IndicatorColor = DefaultIndicatorColor; + } + + private eOrientation _Orientation = eOrientation.Horizontal; + /// + /// Indicates the control orientation. + /// + [Category("Appearance"), DefaultValue(eOrientation.Horizontal), Description("Indicates the control orientation.")] + public eOrientation Orientation + { + get { return _Orientation; } + set + { + if (value != _Orientation) + { + eOrientation oldValue = _Orientation; + _Orientation = value; + OnOrientationChanged(oldValue, value); + } + } + } + /// + /// Called when Orientation property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnOrientationChanged(eOrientation oldValue, eOrientation newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Orientation")); + this.Invalidate(); + } + + protected override Size DefaultSize + { + get + { + return new Size(400,4); + } + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] + public override System.Drawing.Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] + public override System.Drawing.Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/PopupControlHost.cs b/PROMS/DotNetBar Source Code/Controls/PopupControlHost.cs new file mode 100644 index 00000000..fcd59a81 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/PopupControlHost.cs @@ -0,0 +1,745 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.Security.Permissions; +using System.Runtime.InteropServices; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Controls +{ + internal class PopupControlHost : ToolStripDropDown + { + #region Constructor + private ePopupResizeEdge _ResizeEdge = ePopupResizeEdge.None; + private Rectangle _ResizeGripBounds = Rectangle.Empty; + private bool _CanResizeHostControl = false; + private bool _CanResizePopup = false; + private bool _RefreshSize = false; + private static readonly Size ResizeGripSize = new Size(16, 16); + + public PopupControlHost() + { + this.AutoSize = false; + this.Padding = System.Windows.Forms.Padding.Empty; + this.Margin = System.Windows.Forms.Padding.Empty; + } + + #endregion + + #region Implementation + + protected override void OnClosing(ToolStripDropDownClosingEventArgs e) + { + Control hostControl = GetHostedControl(); + if (hostControl != null) + hostControl.SizeChanged -= HostControlSizeChanged; + base.OnClosing(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + + ResizeGripBounds = Rectangle.Empty; + + Size resizeGripSize = Dpi.Size(ResizeGripSize); + if (IsResizeEnabled(ePopupResizeEdge.BottomLeft)) + { + ResizeGripColors colors = GetColors(); + + using (SolidBrush brush = new SolidBrush(colors.BackColor)) + e.Graphics.FillRectangle(brush, 1, Height - resizeGripSize.Height, Width - 2, resizeGripSize.Height - 1); + ResizeGripBounds = new Rectangle(1, Height - resizeGripSize.Height, resizeGripSize.Width, resizeGripSize.Height); + ResizeHandlePainter.DrawResizeHandle(e.Graphics, ResizeGripBounds, colors.GripLightColor, colors.GripColor, true); + } + else if (IsResizeEnabled(ePopupResizeEdge.BottomRight)) + { + ResizeGripColors colors = GetColors(); + using (SolidBrush brush = new SolidBrush(colors.BackColor)) + e.Graphics.FillRectangle(brush, 1, Height - resizeGripSize.Height, Width - 2, resizeGripSize.Height - 1); + ResizeGripBounds = new Rectangle(Width - resizeGripSize.Width - 1, Height - resizeGripSize.Height, resizeGripSize.Width, resizeGripSize.Height); + ResizeHandlePainter.DrawResizeHandle(e.Graphics, ResizeGripBounds, colors.GripLightColor, colors.GripColor, false); + } + + base.OnPaint(e); + } + private ResizeGripColors _ResizeGripColors; + private ResizeGripColors GetColors() + { + return _ResizeGripColors; + } + + #region ResizeGripColors + private struct ResizeGripColors + { + public Color BackColor; + public Color GripLightColor; + public Color GripColor; + /// + /// Initializes a new instance of the ResizeGripColors structure. + /// + /// + /// + /// + public ResizeGripColors(Color backColor, Color gripLightColor, Color gripColor) + { + BackColor = backColor; + GripLightColor = gripLightColor; + GripColor = gripColor; + } + } + #endregion + + private bool _PopupUserSize = false; + /// + /// Gets whether popup has been resized by end-user. + /// + public bool PopupUserSize + { + get { return _PopupUserSize; } + set { _PopupUserSize = value; } + } + + protected override void OnSizeChanged(EventArgs e) + { + base.OnSizeChanged(e); + + if (!_CanResizePopup) + { + UpdateHostControlSize(); + _PopupUserSize = true; + } + } + + protected void HostControlSizeChanged(object sender, EventArgs e) + { + if (!_CanResizeHostControl) + UpdateContentBasedSize(-1); + } + + public new void Show(int x, int y) + { + Show(x, y, -1, -1); + } + + public void Show(int x, int y, int width, int height) + { + if (GlobalManager.Renderer is Office2007Renderer) + { + Office2007ColorTable table = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + _ResizeGripColors = new ResizeGripColors(table.Form.BackColor, table.LegacyColors.SplitterBackground2, table.LegacyColors.BarStripeColor); + } + else + _ResizeGripColors = new ResizeGripColors(SystemColors.ButtonFace, Color.White, SystemColors.ControlDark); + + Control hostControl = GetHostedControl(); + if (hostControl == null) + return; + + _CanResizeHostControl = true; + _CanResizePopup = true; + + this.Size = new Size(1, 1); + base.Show(x, y); + + _CanResizeHostControl = false; + _CanResizePopup = false; + + UpdateContentBasedSize(width); + + if (_CloseButtonVisible && IsResizeGripShown) + { + if (_CloseButtonController == null) + { + ButtonItem button = new ButtonItem(); + button.Symbol = "\uf00d"; + button.SymbolSize = 8; + button.Style = eDotNetBarStyle.StyleManagerControlled; + button.ButtonStyle = eButtonStyle.ImageAndText; + button.LeftInternal = 1; + button.Click += new EventHandler(ClosePopupButtonClick); + _CloseButtonController = new BaseItemController(button, this); + button.RecalcSize(); + button.TopInternal = this.Height - button.HeightInternal - 1; + } + } + else if (_CloseButtonController != null) + { + _CloseButtonController.Dispose(); + _CloseButtonController = null; + } + + if (_RefreshSize) + UpdateHostControlSize(); + + if (y > Top && y <= Bottom) + { + if (_ParentControlBounds.IsEmpty) + Top = y - Height - (height != -1 ? height : 0); + else + Top = _ParentControlBounds.Y - Height; + + //ePopupResizeEdge previous = ResizeEdge; + //if (ResizeEdge == ePopupResizeEdge.BottomLeft) + // ResizeEdge = ePopupResizeEdge.None; // ePopupResizeEdge.TopLeft; + //else if (ResizeEdge == ePopupResizeEdge.BottomRight) + // ResizeEdge = ePopupResizeEdge.None; // ePopupResizeEdge.TopRight; + + //if (ResizeEdge != previous) + // UpdateHostControlSize(); + } + + hostControl.SizeChanged += HostControlSizeChanged; + } + private Rectangle _ParentControlBounds = Rectangle.Empty; + public Rectangle ParentControlBounds + { + get { return _ParentControlBounds; } + set { _ParentControlBounds = value; } + } + private void ClosePopupButtonClick(object sender, EventArgs e) + { + this.Close(ToolStripDropDownCloseReason.CloseCalled); + } + + BaseItemController _CloseButtonController = null; + + protected void UpdateContentBasedSize(int proposedWidth) + { + if (_CanResizePopup) + return; + + _CanResizeHostControl = true; + try + { + Rectangle bounds = Bounds; + bounds.Size = SizeFromContent(proposedWidth); + + if (!IsResizeEnabled(ePopupResizeEdge.None)) + { + if (proposedWidth > 0 && bounds.Width - 2 > proposedWidth) + if (!IsResizeEnabled(ePopupResizeEdge.Right)) + bounds.X -= bounds.Width - 2 - proposedWidth; + } + + Bounds = bounds; + } + finally + { + _CanResizeHostControl = false; + } + } + + protected void UpdateHostControlSize() + { + if (_CanResizeHostControl) + return; + + _CanResizePopup = true; + + try + { + Control hostedControl = GetHostedControl(); + if (hostedControl != null) + { + Rectangle bounds = hostedControl.Bounds; + if (IsResizeEnabled(ePopupResizeEdge.TopLeft) || IsResizeEnabled(ePopupResizeEdge.TopRight)) + bounds.Location = new Point(1, Dpi.Height(ResizeGripSize.Height)); + else + bounds.Location = new Point(1, 1); + + bounds.Width = ClientRectangle.Width - 2; + bounds.Height = ClientRectangle.Height - 2; + if (IsResizeGripShown) + bounds.Height -= Dpi.Height(ResizeGripSize.Height); + + if (bounds.Size != hostedControl.Size) + hostedControl.Size = bounds.Size; + if (bounds.Location != hostedControl.Location) + hostedControl.Location = bounds.Location; + + if (_CloseButtonController != null) + { + _CloseButtonController.Item.TopInternal = this.Height - _CloseButtonController.Item.HeightInternal - 1; + } + } + } + finally + { + _CanResizePopup = false; + } + } + + public Control GetHostedControl() + { + if (Items.Count > 0) + { + ToolStripControlHost host = Items[0] as ToolStripControlHost; + if (host != null) + return host.Control; + } + return null; + } + + public bool IsResizeEnabled(ePopupResizeEdge edge) + { + return (ResizeEdge & edge) == edge; + } + + protected Size SizeFromContent(int proposedWidth) + { + Size contentSize = Size.Empty; + + _RefreshSize = false; + + // Fetch hosted control. + Control hostedControl = GetHostedControl(); + if (hostedControl != null) + { + if (IsResizeEnabled(ePopupResizeEdge.TopLeft) || IsResizeEnabled(ePopupResizeEdge.TopRight)) + hostedControl.Location = new Point(1, Dpi.Height16); + else + hostedControl.Location = new Point(1, 1); + contentSize = SizeFromClientSize(hostedControl.Size); + + // Use minimum width (if specified). + if (proposedWidth > 0 && contentSize.Width < proposedWidth) + { + contentSize.Width = proposedWidth; + _RefreshSize = true; + } + } + + // If a grip box is shown then add it into the drop down height. + if (IsResizeGripShown) + contentSize.Height += Dpi.Height16; + + // Add some additional space to allow for borders. + contentSize.Width += 2; + contentSize.Height += 2; + + return contentSize; + } + + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + protected override void WndProc(ref Message m) + { + if (!ProcessResizeGripMessages(ref m, false)) + base.WndProc(ref m); + } + + /// + /// Processes the resizing messages. + /// + /// The message. + /// true, if the WndProc method from the base class shouldn't be invoked. + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + public bool ProcessResizeGripMessages(ref Message m) + { + return ProcessResizeGripMessages(ref m, true); + } + + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + private bool ProcessResizeGripMessages(ref Message m, bool contentControl) + { + if (ResizeEdge != ePopupResizeEdge.None) + { + if (m.Msg == (int)WinApi.WindowsMessages.WM_NCHITTEST) + return ProcessNcHitTest(ref m, contentControl); + else if (m.Msg == (int)WinApi.WindowsMessages.WM_GETMINMAXINFO) + return ProcessGetMinMaxInfo(ref m); + } + return false; + } + + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + private bool ProcessGetMinMaxInfo(ref Message m) + { + Control hostedControl = GetHostedControl(); + if (hostedControl != null) + { + WinApi.MINMAXINFO minmax = (WinApi.MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(WinApi.MINMAXINFO)); + + // Maximum size. + if (hostedControl.MaximumSize.Width != 0) + minmax.maxTrackSize.Width = hostedControl.MaximumSize.Width; + if (hostedControl.MaximumSize.Height != 0) + minmax.maxTrackSize.Height = hostedControl.MaximumSize.Height; + + // Minimum size. + minmax.minTrackSize = new Size(32, 32); + if (hostedControl.MinimumSize.Width > minmax.minTrackSize.Width) + minmax.minTrackSize.Width = hostedControl.MinimumSize.Width; + if (hostedControl.MinimumSize.Height > minmax.minTrackSize.Height) + minmax.minTrackSize.Height = hostedControl.MinimumSize.Height; + + Marshal.StructureToPtr(minmax, m.LParam, false); + } + return true; + } + + private bool ProcessNcHitTest(ref Message m, bool contentControl) + { + Point location = PointToClient(new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam))); + IntPtr transparent = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + + if (ResizeGripBounds.Contains(location)) + { + if (IsResizeEnabled(ePopupResizeEdge.BottomLeft)) + { + m.Result = contentControl ? transparent : (IntPtr)WinApi.WindowHitTestRegions.BottomLeftSizeableCorner; + return true; + } + else if (IsResizeEnabled(ePopupResizeEdge.BottomRight)) + { + m.Result = contentControl ? transparent : (IntPtr)WinApi.WindowHitTestRegions.BottomRightSizeableCorner; + return true; + } + else if (IsResizeEnabled(ePopupResizeEdge.TopLeft)) + { + m.Result = contentControl ? transparent : (IntPtr)WinApi.WindowHitTestRegions.TopLeftSizeableCorner; + return true; + } + else if (IsResizeEnabled(ePopupResizeEdge.TopRight)) + { + m.Result = contentControl ? transparent : (IntPtr)WinApi.WindowHitTestRegions.TopRightSizeableCorner; + return true; + } + } + else + { + Rectangle rectClient = ClientRectangle; + if (location.X > rectClient.Right - 3 && location.X <= rectClient.Right && IsResizeEnabled(ePopupResizeEdge.Right)) + { + m.Result = contentControl ? transparent : (IntPtr)WinApi.WindowHitTestRegions.RightSizeableBorder; + return true; + } + else if (location.Y > rectClient.Bottom - 3 && location.Y <= rectClient.Bottom && IsResizeEnabled(ePopupResizeEdge.Bottom)) + { + m.Result = contentControl ? transparent : (IntPtr)WinApi.WindowHitTestRegions.BottomSizeableBorder; + return true; + } + else if (location.X > -1 && location.X < 3 && IsResizeEnabled(ePopupResizeEdge.Left)) + { + m.Result = contentControl ? transparent : (IntPtr)WinApi.WindowHitTestRegions.LeftSizeableBorder; + return true; + } + else if (location.Y > -1 && location.Y < 3 && IsResizeEnabled(ePopupResizeEdge.Top)) + { + m.Result = contentControl ? transparent : (IntPtr)WinApi.WindowHitTestRegions.TopSizeableBorder; + return true; + } + } + return false; + } + + /// + /// Type of resize mode, grips are automatically drawn at bottom-left and bottom-right corners. + /// + public ePopupResizeEdge ResizeEdge + { + get { return _ResizeEdge; } + set + { + if (value != _ResizeEdge) + { + _ResizeEdge = value; + Invalidate(); + } + } + } + + private bool _CloseButtonVisible = true; + /// + /// Gets or sets whether Close button is visible in fotter. Resize handle must also be visible in order for close button to render. + /// + public bool CloseButtonVisible + { + get { return _CloseButtonVisible; } + set + { + _CloseButtonVisible = value; + } + } + + /// + /// Gets resize grip bounds. + /// + public Rectangle ResizeGripBounds + { + get { return _ResizeGripBounds; } + private set { _ResizeGripBounds = value; } + } + + private bool IsResizeGripShown + { + get + { + return (ResizeEdge == ePopupResizeEdge.BottomLeft || ResizeEdge == ePopupResizeEdge.BottomRight); + } + } + + #endregion + } + + #region ePopupResizeEdge + /// + /// Specifies the popup resize modes + /// + public enum ePopupResizeEdge + { + None = 0, + Left = 1, + Top = 2, + Right = 4, + Bottom = 8, + All = (Top | Left | Bottom | Right), + TopLeft = (Top | Left), + TopRight = (Top | Right), + BottomLeft = (Bottom | Left), + BottomRight = (Bottom | Right), + } + #endregion + + #region PopupHostController + internal class PopupHostController : IDisposable + { + #region Constructor + private ToolStripControlHost _ControlHost; + private PopupControlHost _PopupControlHost; + private System.Windows.Forms.Padding _Padding = System.Windows.Forms. Padding. Empty; + private System.Windows.Forms.Padding _Margin = new System.Windows.Forms.Padding(1, 1, 1, 1); + + public PopupHostController() + { + InitializePopupControlHost(); + } + + #endregion + + #region Implementation + /// + /// Occurs after popup is closed. + /// + public event ToolStripDropDownClosedEventHandler Closed; + /// + /// Raises Closed event. + /// + /// Provides event arguments. + protected virtual void OnClosed(ToolStripDropDownClosedEventArgs e) + { + ToolStripDropDownClosedEventHandler handler = Closed; + if (handler != null) + handler(this, e); + } + /// + /// Occurs before popup is closed and allows canceling. + /// + public event ToolStripDropDownClosingEventHandler Closing; + /// + /// Raises Closing event. + /// + /// Provides event arguments. + protected virtual void OnClosing(ToolStripDropDownClosingEventArgs e) + { + ToolStripDropDownClosingEventHandler handler = Closing; + if (handler != null) + handler(this, e); + } + + private void InitializeHost(Control control) + { + InitializePopupControlHost(); + + if (control != this.Control) + DisposeToolstripControlHost(); + + if (_ControlHost == null) + { + _ControlHost = new ToolStripControlHost(control); + _ControlHost.AutoSize = false; + _ControlHost.Padding = this.Padding; + _ControlHost.Margin = this.Margin; + } + _ControlHost.Size = control.Size; + _PopupControlHost.Items.Clear(); + _PopupControlHost.Padding = _PopupControlHost.Margin = System.Windows.Forms.Padding.Empty; + _PopupControlHost.Items.Add(_ControlHost); + } + + private void InitializePopupControlHost() + { + if (_PopupControlHost == null) + { + _PopupControlHost = new PopupControlHost(); + _PopupControlHost.Closed += new ToolStripDropDownClosedEventHandler(DropDownClosed); + _PopupControlHost.Closing += new ToolStripDropDownClosingEventHandler(DropDownClosing); + } + } + + private void DropDownClosed(object sender, ToolStripDropDownClosedEventArgs e) + { + OnClosed(e); + } + void DropDownClosing(object sender, ToolStripDropDownClosingEventArgs e) + { + OnClosing(e); + } + + /// + /// Show control on popup at specified location. + /// + public void Show(Control control, int x, int y) + { + Show(control, x, y, ePopupResizeEdge.None); + } + + /// + /// Shows control on popup at specified location with specified popup resize edges. + /// + public void Show(Control control, int x, int y, ePopupResizeEdge resizeEdge) + { + Show(control, x, y, -1, -1, resizeEdge); + } + + /// + /// Shows control on popup at specified location and size with specified popup resize edges. + /// + public void Show(Control control, int x, int y, int width, int height, ePopupResizeEdge resizeEdge) + { + Size controlSize = control.Size; + + InitializeHost(control); + + _PopupControlHost.ResizeEdge = resizeEdge; + _PopupControlHost.Show(x, y, width, height); + control.Focus(); + } + public Rectangle Bounds + { + get + { + return _PopupControlHost.Bounds; + } + } + /// + /// Hides popup if visible. + /// + public void Hide() + { + if (_PopupControlHost != null && _PopupControlHost.Visible) + { + _PopupControlHost.Hide(); + } + } + + private void DisposeToolstripControlHost() + { + if (_ControlHost != null) + { + if (_PopupControlHost != null) + _PopupControlHost.Items.Clear(); + + _ControlHost.Dispose(); + _ControlHost = null; + } + } + + public bool AutoClose + { + get + { + return _PopupControlHost.AutoClose; + } + set + { + _PopupControlHost.AutoClose = value; + } + } + + public Rectangle ParentControlBounds + { + get { return _PopupControlHost.ParentControlBounds; } + set { _PopupControlHost.ParentControlBounds = value; } + } + + /// + /// Gets whether popup is visible. + /// + public bool Visible + { + get { return (_PopupControlHost != null && _PopupControlHost.Visible) ? true : false; } + } + /// + /// Gets the control displayed on popup. + /// + public Control Control + { + get { return (_ControlHost != null) ? _ControlHost.Control : null; } + } + /// + /// Gets or sets the popup padding. + /// + public System.Windows.Forms.Padding Padding + { + get { return _Padding; } + set { _Padding = value; } + } + /// + /// Gets or sets popup margin. + /// + public System.Windows.Forms.Padding Margin + { + get { return _Margin; } + set { _Margin = value; } + } + + public bool PopupUserSize + { + get + { + if (_PopupControlHost == null) return false; + return _PopupControlHost.PopupUserSize; + } + set + { + if (_PopupControlHost != null) + _PopupControlHost.PopupUserSize = value; + } + } + + public bool CloseButtonVisible + { + get + { + if (_PopupControlHost == null) return false; + return _PopupControlHost.CloseButtonVisible; + } + set + { + if (_PopupControlHost != null) + _PopupControlHost.CloseButtonVisible = value; + } + } + #endregion + + #region IDisposable Members + + public void Dispose() + { + DisposeToolstripControlHost(); + if (_PopupControlHost != null) + { + _PopupControlHost.Closed -= new ToolStripDropDownClosedEventHandler(DropDownClosed); + _PopupControlHost.Closing -= new ToolStripDropDownClosingEventHandler(DropDownClosing); + _PopupControlHost.Dispose(); + _PopupControlHost = null; + } + + } + + #endregion + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressBarX.cs b/PROMS/DotNetBar Source Code/Controls/ProgressBarX.cs new file mode 100644 index 00000000..4cbb436c --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressBarX.cs @@ -0,0 +1,286 @@ +using System; +using System.Text; +using System.Drawing; +using System.ComponentModel; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the stand-alone progress bar control. + /// + [ToolboxBitmap(typeof(ProgressBarX), "Controls.ProgressBarX.ico"), ToolboxItem(true), DefaultEvent("Click"), System.Runtime.InteropServices.ComVisible(false)] + public class ProgressBarX : BaseItemControl + { + #region Private Variables + private ProgressBarItem m_ProgressBar = null; + #endregion + + #region Constructor, Dispose + public ProgressBarX() + { + m_ProgressBar = new ProgressBarItem(); + m_ProgressBar.Style = eDotNetBarStyle.Office2007; + m_ProgressBar.Minimum = 0; + m_ProgressBar.Maximum = 100; + m_ProgressBar.Value = 0; + m_ProgressBar.BackStyle = this.BackgroundStyle; + + this.HostItem = m_ProgressBar; + } + #endregion + + #region Internal Implementation + protected override void PaintBackground(PaintEventArgs e) + { + // ProgressBarItem shares same background style as control so it will paint itself. This avoids double painting... + Graphics g = e.Graphics; + Rectangle r = this.ClientRectangle; + ElementStyle style = this.GetBackgroundStyle(); + + if ((!style.Custom || style.BackColor.IsEmpty)&& !this.BackColor.IsEmpty && this.BackColor!=Color.Transparent) + { + DisplayHelp.FillRectangle(g, r, this.BackColor); + } + } + + /// + /// Gets or sets the maximum value of the range of the control. + /// + [Browsable(true), Description("Gets or sets the maximum value of the range of the control."), Category("Behavior"), DefaultValue(100)] + public int Maximum + { + get + { + return m_ProgressBar.Maximum; + } + set + { + m_ProgressBar.Maximum = value; + } + } + + /// + /// Gets or sets the minimum value of the range of the control. + /// + [DevCoBrowsable(true), Browsable(true), Description("Gets or sets the minimum value of the range of the control."), Category("Behavior"), DefaultValue(0)] + public int Minimum + { + get + { + return m_ProgressBar.Minimum; + } + set + { + m_ProgressBar.Minimum = value; + } + } + + /// + /// Gets or sets the current position of the progress bar. + /// + [DevCoBrowsable(true), Browsable(true), Description("Gets or sets the current position of the progress bar."), Category("Behavior"), DefaultValue(0)] + public int Value + { + get { return m_ProgressBar.Value; } + set + { + m_ProgressBar.Value = value; + //this.Invalidate(); + //this.Update(); + } + } + + /// + /// Gets or sets the amount by which a call to the PerformStep method increases the current position of the progress bar. + /// + [DevCoBrowsable(true), Browsable(true), Description("Gets or sets the amount by which a call to the PerformStep method increases the current position of the progress bar."), Category("Behavior"), DefaultValue(1)] + public int Step + { + get + { + return m_ProgressBar.Step; + } + set + { + m_ProgressBar.Step = value; + } + } + + /// + /// Advances the current position of the progress bar by the amount of the Step property. + /// + public void PerformStep() + { + this.Value += m_ProgressBar.Step; + } + + /// + /// Advances the current position of the progress bar by the specified amount. + /// + /// The amount by which to increment the progress bar's current position. + public void Increment(int value) + { + this.Value += value; + } + + /// + /// Gets or sets the color of the progress chunk. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Gets or sets the color of the progress chunk.")] + public Color ChunkColor + { + get + { + return m_ProgressBar.ChunkColor; + } + set + { + m_ProgressBar.ChunkColor = value; + this.Invalidate(); + } + } + /// + /// Gets whether ChunkColor property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeChunkColor() + { + return (!m_ProgressBar.ChunkColor.IsEmpty); + } + /// + /// Resets the ChunkColor property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetChunkColor() + { + m_ProgressBar.ChunkColor = Color.Empty; + } + + /// + /// Gets or sets the target gradient color of the progress chunk. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Gets or sets the target gradient color of the progress chunk.")] + public Color ChunkColor2 + { + get + { + return m_ProgressBar.ChunkColor2; + } + set + { + m_ProgressBar.ChunkColor2 = value; + this.Invalidate(); + } + } + /// + /// Gets whether ChunkColor property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeChunkColor2() + { + return (!m_ProgressBar.ChunkColor2.IsEmpty); + } + /// + /// Resets the ChunkColor property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetChunkColor2() + { + m_ProgressBar.ChunkColor2 = Color.Empty; + } + + /// + /// Gets or sets the gradient angle of the progress chunk. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Gets or sets the gradient angle of the progress chunk."), DefaultValue(0)] + public int ChunkGradientAngle + { + get + { + return (int)m_ProgressBar.ChunkGradientAngle; + } + set + { + m_ProgressBar.ChunkGradientAngle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets whether the text inside the progress bar is displayed. + /// + [Browsable(true), Description("Gets or sets whether the text inside the progress bar is displayed."), Category("Behavior"), DefaultValue(false)] + public bool TextVisible + { + get + { + return m_ProgressBar.TextVisible; + } + set + { + m_ProgressBar.TextVisible = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the type of progress bar used to indicate progress. The Standard style displays the progress based on Minimum, Maximum and current Value. + /// The Marquee type is automatically moving progress bar that is used to indicate an ongoing operation for which the actual duration cannot be estimated. + /// + [Browsable(true), Category("Behavior"), DefaultValue(eProgressItemType.Standard), Description("Indicates type of progress bar used to indicate progress.")] + public eProgressItemType ProgressType + { + get { return m_ProgressBar.ProgressType; } + set { m_ProgressBar.ProgressType = value; } + } + + /// + /// Gets or sets the marquee animation speed in milliseconds. + /// + [Browsable(true), DefaultValue(100), Category("Behavior"), Description("Indicates marquee animation speed in milliseconds.")] + public int MarqueeAnimationSpeed + { + get { return m_ProgressBar.MarqueeAnimationSpeed; } + set { m_ProgressBar.MarqueeAnimationSpeed = value; } + } + + /// + /// Gets or sets the predefined color state table for progress bar. Color specified applies to items with Office 2007 style only. It does not have + /// any effect on other styles. You can use ColorTable to indicate the state of the operation that Progress Bar is tracking. Default value is eProgressBarItemColor.Normal. + /// + [Browsable(true), DevCoBrowsable(false), DefaultValue(eProgressBarItemColor.Normal), Category("Appearance"), Description("Indicates predefined color of item when Office 2007 style is used.")] + public eProgressBarItemColor ColorTable + { + get { return m_ProgressBar.ColorTable; } + set + { + m_ProgressBar.ColorTable = value; + } + } + + [DefaultValue(eOrientation.Horizontal)] + public eOrientation Orientation + { + get { return m_ProgressBar.Orientation; } + set + { + if (m_ProgressBar.Orientation != value) + { + m_ProgressBar.Orientation = value; + this.Invalidate(); + } + } + } + + /// + /// Gets the underlying ProgressBarItem + /// + internal ProgressBarItem ProgressBarItem + { + get { return (m_ProgressBar); } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressBarX.ico b/PROMS/DotNetBar Source Code/Controls/ProgressBarX.ico new file mode 100644 index 00000000..06f95b78 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/ProgressBarX.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressStepper/MetroStepItemPainter.cs b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/MetroStepItemPainter.cs new file mode 100644 index 00000000..d032cf54 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/MetroStepItemPainter.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class MetroStepItemPainter : StepItemPainter + { + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressStepper/OfficeStepItemColorTable.cs b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/OfficeStepItemColorTable.cs new file mode 100644 index 00000000..459f5a20 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/OfficeStepItemColorTable.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + /// + /// Defines color table for the StepItem. + /// + public class OfficeStepItemColorTable + { + /// + /// Gets or sets the default state StepItem colors. + /// + public OfficeStepItemStateColorTable Default = new OfficeStepItemStateColorTable(); + /// + /// Gets or sets the mouse over state StepItem colors. + /// + public OfficeStepItemStateColorTable MouseOver = new OfficeStepItemStateColorTable(); + /// + /// Gets or sets the StepItem colors when mouse is pressed over the item. + /// + public OfficeStepItemStateColorTable Pressed = new OfficeStepItemStateColorTable(); + /// + /// Gets or sets the StepItem colors when Value property is greater than Minimum property value, i.e. item is reporting progress. + /// Note that only Background color is used when progress indicator is drawn. + /// + public OfficeStepItemStateColorTable Progress = new OfficeStepItemStateColorTable(); + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressStepper/OfficeStepItemPainter.cs b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/OfficeStepItemPainter.cs new file mode 100644 index 00000000..54f3405b --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/OfficeStepItemPainter.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class OfficeStepItemPainter : StepItemPainter + { + #region Implementation + /// + /// Paints StepItem. + /// + /// Provides arguments for the operation. + public override void Paint(StepItemRendererEventArgs e) + { + StepItem item = e.Item; + OfficeStepItemColorTable table = ColorTable.StepItem; + OfficeStepItemStateColorTable ct = table.Default; + if (item.HotTracking && item.IsMouseDown) + ct = table.Pressed; + else if (item.HotTracking && item.IsMouseOver) + ct = table.MouseOver; + + OfficeStepItemStateColorTable ctProgress = table.Progress; + Rectangle clip = Rectangle.Empty; + + Rectangle r = item.Bounds; + int pointerSize = item.GetPointerSize(); + Graphics g = e.ItemPaintArgs.Graphics; + GraphicsPath path = GetPath(item, pointerSize); + item.ItemPath = path; + using (Brush brush = DisplayHelp.CreateBrush(path.GetBounds(), (item.BackColors != null && item.BackColors.Length > 0) ? item.BackColors : ct.BackColors, ct.BackColorsGradientAngle, ct.BackColorsPositions)) + { + g.FillPath(brush, path); + } + if (item.Value > item.Minimum) // Render progress marker + { + float percent = Math.Min(1, (item.Value / (float)(item.Maximum - item.Minimum))); + if (percent > 0) + { + clip = item.Bounds; + clip.Width = (int)(clip.Width * percent); + } + if (!clip.IsEmpty) + { + Region oldClip = g.Clip; + g.SetClip(clip, CombineMode.Intersect); + using (Brush brush = DisplayHelp.CreateBrush(path.GetBounds(), + (item.ProgressColors != null && item.ProgressColors.Length > 0) ? item.ProgressColors : ctProgress.BackColors, ctProgress.BackColorsGradientAngle, ctProgress.BackColorsPositions)) + { + g.FillPath(brush, path); + } + g.Clip = oldClip; + oldClip.Dispose(); + } + } + + if (ct.BorderColors.Length > 0) + { + for (int i = ct.BorderColors.Length - 1; i > 0; i--) + { + Rectangle rb = item.Bounds; + rb.Inflate(-i, -i); + using (GraphicsPath borderPath = GetPath(item, pointerSize, rb)) + { + using (Pen pen = new Pen(ct.BorderColors[i])) + g.DrawPath(pen, borderPath); + } + } + using (Pen pen = new Pen(ct.BorderColors[0])) + g.DrawPath(pen, path); + } + + // Render content + r.X += item.Padding.Left; + r.Y += item.Padding.Top; + r.Width -= item.Padding.Horizontal; + r.Height -= item.Padding.Vertical; + + if (!item.IsFirst) + { + r.X += pointerSize; + r.Width -= pointerSize; + } + + Color textColor = ct.TextColor; + if (!string.IsNullOrEmpty(item.SymbolRealized)) + { + Color symbolColor = item.SymbolColor; + if (symbolColor.IsEmpty) symbolColor = textColor; + TextDrawing.DrawStringLegacy(g, item.SymbolRealized, Symbols.GetFont(item.SymbolSize, item.SymbolSet), symbolColor, new Rectangle(r.X, r.Y + r.Height / 2, 0, 0), eTextFormat.Default | eTextFormat.VerticalCenter); + int imageSize = item.ActualSymbolSize.Width + item.ImageTextSpacing; + r.Width -= imageSize; + r.X += imageSize; + } + else if (item.Image != null) + { + g.DrawImage(item.Image, new Rectangle(r.X, r.Y + (r.Height - item.Image.Height) / 2, item.Image.Width, item.Image.Height)); + int imageSize = item.Image.Width + item.ImageTextSpacing; + r.Width -= imageSize; + r.X += imageSize; + } + + if (!string.IsNullOrEmpty(item.Text)) + { + if (!item.TextColor.IsEmpty) textColor = item.TextColor; + Font font = e.ItemPaintArgs.Font; + if (item.TextMarkupBody == null) + { + eTextFormat textFormat = eTextFormat.Default | eTextFormat.VerticalCenter; + if (item.TextAlignment == eButtonTextAlignment.Center) + { + textFormat |= eTextFormat.HorizontalCenter; + if (!item.IsLast) + r.Width -= pointerSize; + } + else if (item.TextAlignment == eButtonTextAlignment.Right) + { + textFormat |= eTextFormat.Right; + if (!item.IsLast) + r.Width -= pointerSize; + } + TextDrawing.DrawString(g, item.Text, font, textColor, r, textFormat); + } + else + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, textColor, e.ItemPaintArgs.RightToLeft); + d.HotKeyPrefixVisible = false; + d.ContextObject = item; + Rectangle mr = new Rectangle(r.X, r.Y + (r.Height - item.TextMarkupBody.Bounds.Height) / 2, item.TextMarkupBody.Bounds.Width, item.TextMarkupBody.Bounds.Height); + item.TextMarkupBody.Bounds = mr; + item.TextMarkupBody.Render(d); + } + + } + } + + private GraphicsPath GetPath(StepItem item, int arrowSize) + { + Rectangle r = item.Bounds; + return GetPath(item, arrowSize, r); + } + + private GraphicsPath GetPath(StepItem item, int arrowSize, Rectangle r) + { + r.Width--; + r.Height--; + if (item.IsFirst) + return GetFirstItemPath(r, arrowSize); + else if (item.IsLast) + return GetLastItemPath(r, arrowSize); + else + return GetItemPath(r, arrowSize); + } + private GraphicsPath GetItemPath(Rectangle r, int arrowSize) + { + GraphicsPath path = new GraphicsPath(); + path.AddLine(r.X, r.Y, r.X + arrowSize, r.Y + r.Height / 2); + path.AddLine(r.X + arrowSize, r.Y + r.Height / 2, r.X, r.Bottom); + path.AddLine(r.X, r.Bottom, r.Right - arrowSize, r.Bottom); + path.AddLine(r.Right - arrowSize, r.Bottom, r.Right, r.Y + r.Height / 2); + path.AddLine(r.Right, r.Y + r.Height / 2, r.Right - arrowSize, r.Y); + path.CloseAllFigures(); + + return path; + } + private GraphicsPath GetLastItemPath(Rectangle r, int arrowSize) + { + GraphicsPath path = new GraphicsPath(); + + ArcData ad = ElementStyleDisplay.GetCornerArc(r, 2, eCornerArc.TopRight); + path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); + ad = ElementStyleDisplay.GetCornerArc(r, 2, eCornerArc.BottomRight); + path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); + + path.AddLine(r.X, r.Bottom, r.X + arrowSize, r.Y + r.Height / 2); + path.AddLine(r.X + arrowSize, r.Y + r.Height / 2, r.X, r.Y); + + path.CloseAllFigures(); + + return path; + } + private GraphicsPath GetFirstItemPath(Rectangle r, int arrowSize) + { + GraphicsPath path = new GraphicsPath(); + ArcData ad = ElementStyleDisplay.GetCornerArc(r, 2, eCornerArc.BottomLeft); + path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); + ad = ElementStyleDisplay.GetCornerArc(r, 2, eCornerArc.TopLeft); + path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle); + path.AddLine(r.Right - arrowSize, r.Y, r.Right, r.Y + r.Height / 2); + path.AddLine(r.Right, r.Y + r.Height / 2, r.Right - arrowSize, r.Bottom); + path.CloseAllFigures(); + return path; + + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressStepper/OfficeStepItemStateColorTable.cs b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/OfficeStepItemStateColorTable.cs new file mode 100644 index 00000000..4af373cb --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/OfficeStepItemStateColorTable.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.Rendering +{ + /// + /// Represents the color table for StepItem single state. + /// + public class OfficeStepItemStateColorTable + { + /// + /// Initializes a new instance of the OfficeStepItemStateColorTable class. + /// + public OfficeStepItemStateColorTable() + { + + } + /// + /// Initializes a new instance of the OfficeStepItemStateColorTable class. + /// + /// + /// + /// + public OfficeStepItemStateColorTable(Color[] backColors, Color textColor, Color[] borderColors) + { + BackColors = backColors; + TextColor = textColor; + BorderColors = borderColors; + } + /// + /// Initializes a new instance of the OfficeStepItemStateColorTable class. + /// + /// + /// + /// + /// + /// + public OfficeStepItemStateColorTable(Color[] backColors, int backColorsGradientAngle, float[] backColorsPositions, Color textColor, Color[] borderColors) + { + BackColors = backColors; + BackColorsGradientAngle = backColorsGradientAngle; + BackColorsPositions = backColorsPositions; + TextColor = textColor; + BorderColors = borderColors; + } + /// + /// Gets or sets the background colors for the step item. + /// + public Color[] BackColors= new Color[0]; + /// + /// Gets or sets the back colors gradient angle if there is more than one color in BackColors array. + /// + public int BackColorsGradientAngle = 90; + /// + /// Gets or sets the gradient colors positions if there is more than one color in BackColors array. + /// + public float[] BackColorsPositions = new float[0]; + /// + /// Gets or sets the text color for the step item. + /// + public Color TextColor = Color.Black; + /// + /// Gets or sets the border colors of the step item. + /// + public Color[] BorderColors = new Color[0]; + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressStepper/ProgressSteps.cs b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/ProgressSteps.cs new file mode 100644 index 00000000..6af72814 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/ProgressSteps.cs @@ -0,0 +1,304 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents the progress steps control. + /// + [ToolboxBitmap(typeof(ProgressSteps), "ProgressSteps.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.ProgressStepsDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.Runtime.InteropServices.ComVisible(false), DefaultEvent("ItemClick")] + public class ProgressSteps : ItemControl + { + #region Constructor + /// + /// Initializes a new instance of the ProgressSteps class. + /// + public ProgressSteps() + : base() + { + _ViewContainer = new StepItemContainer(); + _ViewContainer.GlobalItem = false; + _ViewContainer.ContainerControl = this; + _ViewContainer.Displayed = true; + _ViewContainer.Style = eDotNetBarStyle.StyleManagerControlled; + _ViewContainer.SetOwner(this); + this.SetBaseItemContainer(_ViewContainer); + } + private StepItemContainer _ViewContainer = null; + #endregion + + #region Implementation + /// + /// Returns collection of items on a bar. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] + public SubItemsCollection Items + { + get + { + return _ViewContainer.SubItems; + } + } + + /// + /// Gets/Sets the visual style for items and color scheme. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Specifies the visual style of the control."), DefaultValue(eDotNetBarStyle.StyleManagerControlled)] + public eDotNetBarStyle Style + { + get + { + return _ViewContainer.Style; + } + set + { + this.ColorScheme.SwitchStyle(value); + _ViewContainer.Style = value; + this.Invalidate(); + this.RecalcLayout(); + } + } + + private Size _PreferredSize = Size.Empty; + [Localizable(true), Browsable(false)] + public new System.Windows.Forms.Padding Padding + { + get { return base.Padding; } + set { base.Padding = value; } + } + + public override Size GetPreferredSize(Size proposedSize) + { + if (!_PreferredSize.IsEmpty) return _PreferredSize; + + if (!BarFunctions.IsHandleValid(this)) + return base.GetPreferredSize(proposedSize); + + if (this.Items.Count == 0 || !BarFunctions.IsHandleValid(this) || _ViewContainer.SubItems.Count == 0) + return new Size(base.GetPreferredSize(proposedSize).Width, Dpi.Height22); + + int height = GetAutoSizePreferredHeight(); + + _PreferredSize = new Size(proposedSize.Width, height); + return _PreferredSize; + } + + private int GetAutoSizePreferredHeight() + { + int height = ElementStyleLayout.VerticalStyleWhiteSpace(this.GetBackgroundStyle()); + height += _ViewContainer.CalculatedHeight > 0 ? _ViewContainer.CalculatedHeight : 20; + return height; + } + protected override void RecalcSize() + { + base.RecalcSize(); + if (this.AutoSize && this.IsHandleCreated && GetAutoSizePreferredHeight() != this.Height) + { + InvalidateAutoSize(); + this.AdjustSize(); + } + } + + /// + /// Gets or sets a value indicating whether the control is automatically resized to display its entire contents. You can set MaximumSize.Width property to set the maximum width used by the control. + /// + [Browsable(true), DefaultValue(false), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override bool AutoSize + { + get + { + return base.AutoSize; + } + set + { + if (this.AutoSize != value) + { + base.AutoSize = value; + InvalidateAutoSize(); + AdjustSize(); + } + } + } + + private void InvalidateAutoSize() + { + _PreferredSize = Size.Empty; + } + + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + if (this.AutoSize) + { + Size preferredSize = base.PreferredSize; + if (preferredSize.Width > 0) + width = preferredSize.Width; + if (preferredSize.Height > 0) + height = preferredSize.Height; + } + base.SetBoundsCore(x, y, width, height, specified); + } + + private void AdjustSize() + { + if (this.AutoSize) + { + System.Drawing.Size prefSize = base.PreferredSize; + if (prefSize.Width > 0 && prefSize.Height > 0) + this.Size = base.PreferredSize; + else if (prefSize.Height > 0) + this.Size = new Size(this.Width, base.PreferredSize.Height); + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Image BackgroundImage + { + get { return base.BackgroundImage; } + set { base.BackgroundImage = value; } + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + if (this.AutoSize) + this.AdjustSize(); + } + + /// + /// Gets or sets the arrow pointer width for the StepItem objects hosted within this container. + /// + [DefaultValue(10), Category("Appearance"), Description("Gets or sets the arrow pointer width for the StepItem objects hosted within this container.")] + public int PointerSize + { + get { return _ViewContainer.PointerSize; } + set + { + _ViewContainer.PointerSize = value; + + } + } + #endregion + + #region Property Hiding + [Browsable(false)] + public override eBarImageSize ImageSize + { + get + { + return base.ImageSize; + } + set + { + base.ImageSize = value; + } + } + [Browsable(false)] + public override System.Windows.Forms.ImageList ImagesLarge + { + get + { + return base.ImagesLarge; + } + set + { + base.ImagesLarge = value; + } + } + [Browsable(false)] + public override System.Windows.Forms.ImageList ImagesMedium + { + get + { + return base.ImagesMedium; + } + set + { + base.ImagesMedium = value; + } + } + [Browsable(false)] + public override Font KeyTipsFont + { + get + { + return base.KeyTipsFont; + } + set + { + base.KeyTipsFont = value; + } + } + [Browsable(false)] + public override bool ShowShortcutKeysInToolTips + { + get + { + return base.ShowShortcutKeysInToolTips; + } + set + { + base.ShowShortcutKeysInToolTips = value; + } + } + [Browsable(false)] + public override bool ThemeAware + { + get + { + return base.ThemeAware; + } + set + { + base.ThemeAware = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + #endregion + + #region Licensing +#if !TRIAL + private string m_LicenseKey = ""; + [Browsable(false), DefaultValue("")] + public string LicenseKey + { + get { return m_LicenseKey; } + set + { + if (NativeFunctions.ValidateLicenseKey(value)) + return; + m_LicenseKey = (!NativeFunctions.CheckLicenseKey(value) ? "9dsjkhds7" : value); + } + } +#endif + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); +#if !TRIAL + if (NativeFunctions.keyValidated2 != 266) + TextDrawing.DrawString(e.Graphics, "Invalid License", this.Font, Color.FromArgb(180, Color.Red), this.ClientRectangle, eTextFormat.Bottom | eTextFormat.HorizontalCenter); +#else + if (NativeFunctions.ColorExpAlt() || !NativeFunctions.CheckedThrough) + { + e.Graphics.Clear(SystemColors.Control); + return; + } +#endif + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItem.cs b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItem.cs new file mode 100644 index 00000000..e005f292 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItem.cs @@ -0,0 +1,845 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents a step item which is used to show single step in multi-step progress control. + /// + [ToolboxItem(false), DefaultEvent("Click")] + public class StepItem : BaseItem + { + #region Constructor, Copy + /// + /// Creates new instance of StepItem. + /// + public StepItem() : this("", "") { } + /// + /// Creates new instance of StepItem and assigns the name to it. + /// + /// Item name. + public StepItem(string sItemName) : this(sItemName, "") { } + /// + /// Creates new instance of StepItem and assigns the name and text to it. + /// + /// Item name. + /// item text. + public StepItem(string sItemName, string ItemText) + : base(sItemName, ItemText) + { + //this.ClickRepeatInterval = 200; + this.MouseUpNotification = true; + //this.MouseDownCapture = true; + _Padding.PropertyChanged += PaddingPropertyChanged; + } + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + StepItem objCopy = new StepItem(m_Name); + this.CopyToItem(objCopy); + return objCopy; + } + + /// + /// Copies the StepItem specific properties to new instance of the item. + /// + /// New StepItem instance. + internal void InternalCopyToItem(StepItem copy) + { + CopyToItem(copy); + } + + /// + /// Copies the StepItem specific properties to new instance of the item. + /// + /// New StepItem instance. + protected override void CopyToItem(BaseItem copy) + { + StepItem c = copy as StepItem; + c.Symbol = _Symbol; + c.SymbolSet = _SymbolSet; + c.SymbolColor = _SymbolColor; + c.SymbolSize = _SymbolSize; + + base.CopyToItem(c); + + + } + + protected override void Dispose(bool disposing) + { + if (_ItemPath != null) + { + _ItemPath.Dispose(); + _ItemPath = null; + } + base.Dispose(disposing); + } + #endregion + + #region Internal Implementation + public override void Paint(ItemPaintArgs p) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + StepItemRendererEventArgs e = new StepItemRendererEventArgs(this, p.Graphics); + e.ItemPaintArgs = p; + renderer.DrawStepItem(e); + } + else + { + Rendering.StepItemPainter painter = PainterFactory.CreateStepItemPainter(this); + if (painter != null) + { + StepItemRendererEventArgs e = new StepItemRendererEventArgs(this, p.Graphics); + e.ItemPaintArgs = p; + painter.Paint(e); + } + } + + if (this.DesignMode && this.Focused) + { + Rectangle r = Rectangle.Round(_ItemPath.GetBounds()); + r.Inflate(-1, -1); + DesignTime.DrawDesignTimeSelection(p.Graphics, r, p.Colors.ItemDesignTimeBorder); + } + + this.DrawInsertMarker(p.Graphics); + } + + public override void RecalcSize() + { + Font font = GetFont(null); + Size size = Size.Empty; + + Control objCtrl = this.ContainerControl as Control; + if (objCtrl == null || objCtrl.Disposing || objCtrl.IsDisposed) + return; + Graphics g = BarFunctions.CreateGraphics(objCtrl); + if (g == null) return; + try + { + if (!string.IsNullOrEmpty(_Symbol)) + { + _ActualSymbolSize = GetSymbolSize(g); + size = _ActualSymbolSize; + } + else if (_Image != null) + { + size = _Image.Size; + } + if (!string.IsNullOrEmpty(this.Text)) + { + Size textSize = ButtonItemLayout.MeasureItemText(this, g, 0, objCtrl.Font, eTextFormat.Default, objCtrl.RightToLeft == RightToLeft.Yes); + size.Width += textSize.Width; + size.Height = Math.Max(size.Height, textSize.Height); + if (_Image != null || !string.IsNullOrEmpty(_Symbol)) + size.Width += Dpi.Width(_ImageTextSpacing); + } + else if (string.IsNullOrEmpty(_Symbol) && _Image == null) + size = new System.Drawing.Size(Dpi.Width16, Dpi.Height16); + + size.Width += GetPointerSize(); + if(!_IsFirst && !_IsLast) + size.Width += Dpi.Width(GetPointerSize()); + + size.Width += Dpi.Width(_Padding.Horizontal); + size.Height += Dpi.Height(_Padding.Vertical); + + base.RecalcSize(); + } + finally + { + g.Dispose(); + } + + if (!_MinimumSize.IsEmpty) + { + if (size.Width < _MinimumSize.Width) size.Width = _MinimumSize.Width; + if (size.Height < _MinimumSize.Height) size.Height = _MinimumSize.Height; + } + + m_Rect.Size = size; + } + + internal int GetPointerSize() + { + if (this.Parent is StepItemContainer) + return ((StepItemContainer)this.Parent).PointerSize; + return 10; + } + + private Size GetSymbolSize(Graphics g) + { + Size symbolSize = Size.Empty; + if (g == null || string.IsNullOrEmpty(_Symbol)) return symbolSize; + Font symFont = Symbols.GetFont(this.SymbolSize, this.SymbolSet); + symbolSize = TextDrawing.MeasureString(g, "\uF00A", symFont); // Need to do this to get consistent size for the symbol since they are not all the same width we pick widest + int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) * + symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style))); + symbolSize.Height -= descent; + return symbolSize; + } + + private Size _ActualSymbolSize = Size.Empty; + internal Size ActualSymbolSize + { + get + { + return _ActualSymbolSize; + } + } + + /// + /// Returns the Font object to be used for drawing the item text. + /// + /// Font object. + private Font GetFont(ItemPaintArgs pa) + { + System.Drawing.Font font = null; + + if (pa != null) + font = pa.Font; + + if (font == null) + { + System.Windows.Forms.Control objCtrl = null; + if (pa != null) + objCtrl = pa.ContainerControl; + if (objCtrl == null) + objCtrl = this.ContainerControl as System.Windows.Forms.Control; + if (objCtrl != null && objCtrl.Font != null) + font = (Font)objCtrl.Font; + else + font = SystemFonts.DefaultFont; // (Font)System.Windows.Forms.SystemInformation.MenuFont; + } + + return font; + } + + private GraphicsPath _ItemPath = null; + /// + /// Gets the render path of the item. + /// + [Browsable(false)] + public GraphicsPath ItemPath + { + get { return _ItemPath; } + internal set + { + if (_ItemPath != null) + _ItemPath.Dispose(); + _ItemPath = value; + } + } + + private bool _IsFirst; + private int _Minimum = 0; + /// + /// Gets or sets the minimum value of the range of the control. + /// + [Browsable(true), Description("Gets or sets the minimum value of the range of the control."), Category("Behavior"), DefaultValue(0)] + public int Minimum + { + get { return _Minimum; } + set + { + if (value != _Minimum) + { + int oldValue = _Minimum; + _Minimum = value; + OnMinimumChanged(oldValue, value); + } + } + } + /// + /// Called when Minimum property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnMinimumChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Minimum")); + this.OnAppearanceChanged(); + this.Refresh(); + } + + private int _Maximum = 100; + [Browsable(true), Description("Gets or sets the maximum value of the range of the control."), Category("Behavior"), DefaultValue(100)] + public int Maximum + { + get { return _Maximum; } + set + { + if (value != _Maximum) + { + int oldValue = _Maximum; + _Maximum = value; + OnMaximumChanged(oldValue, value); + } + } + } + /// + /// Called when Maximum property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnMaximumChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Maximum")); + this.OnAppearanceChanged(); + this.Refresh(); + } + + private int _Value = 0; + [Browsable(true), Description("Gets or sets the current position of the progress bar."), Category("Behavior"), DefaultValue(0)] + public int Value + { + get { return _Value; } + set + { + if (value != _Value) + { + int oldValue = _Value; + _Value = value; + OnValueChanged(oldValue, value); + } + } + } + /// + /// Called when Value property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnValueChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Value")); + this.OnAppearanceChanged(); + this.Refresh(); + } + + private Color _SymbolColor = Color.Empty; + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return _SymbolColor; } + set { _SymbolColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return !_SymbolColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + this.SymbolColor = Color.Empty; + } + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get { return _SymbolRealized; } + } + private string _Symbol = "", _SymbolRealized = ""; + /// + /// Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return _Symbol; } + set + { + if (value != _Symbol) + { + string oldValue = _Symbol; + _Symbol = value; + OnSymbolChanged(oldValue, value); + } + } + } + /// + /// Called when Symbol property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolChanged(string oldValue, string newValue) + { + if (string.IsNullOrEmpty(newValue)) + _SymbolRealized = ""; + else + _SymbolRealized = Symbols.GetSymbol(newValue); + //OnPropertyChanged(new PropertyChangedEventArgs("Symbol")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return _SymbolSet; } + set + { + if (_SymbolSet != value) + { + eSymbolSet oldValue = _SymbolSet; + _SymbolSet = value; + OnSymbolSetChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSet property value changes. + /// + /// Indciates old value + /// Indicates new value + protected virtual void OnSymbolSetChanged(eSymbolSet oldValue, eSymbolSet newValue) + { + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + private float _SymbolSize = 13f; + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(12f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return _SymbolSize; } + set + { + if (value != _SymbolSize) + { + float oldValue = _SymbolSize; + _SymbolSize = value; + OnSymbolSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolSizeChanged(float oldValue, float newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SymbolSize")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + private Image _Image = null; + /// + /// Indicates the image that is displayed next to the item text label. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the image that is displayed next to the item text label.")] + public Image Image + { + get { return _Image; } + set + { + if (value != _Image) + { + Image oldValue = _Image; + _Image = value; + OnImageChanged(oldValue, value); + } + } + } + /// + /// Called when Image property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnImageChanged(Image oldValue, Image newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Image")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + /// + /// Gets or sets whether this is first item in StepControl. + /// + internal bool IsFirst + { + get { return _IsFirst; } + set + { + _IsFirst = value; + } + } + + private bool _IsLast = false; + /// + /// Gets or sets whether this is laste item in StepControl. + /// + internal bool IsLast + { + get { return _IsLast; } + set + { + _IsLast = value; + } + } + + private Size _MinimumSize = Size.Empty; + /// + /// Indicates minimum size of the item + /// + [Category("Appearance"), Description("Indicates minimum size of the item")] + public Size MinimumSize + { + get { return _MinimumSize; } + set + { + if (value != _MinimumSize) + { + Size oldValue = _MinimumSize; + _MinimumSize = value; + OnMinimumSizeChanged(oldValue, value); + } + } + } + /// + /// Called when MinimumSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnMinimumSizeChanged(Size oldValue, Size newValue) + { + // OnPropertyChanged(new PropertyChangedEventArgs("MinimumSize")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMinimumSize() + { + return !_MinimumSize.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetMinimumSize() + { + this.Size = Size.Empty; + } + + private bool _HotTracking = true; + /// + /// Specifies whether item changes its appearance when mouse is moved over the item + /// + [DefaultValue(true), Category("Behavior"), Description("Specifies whether item changes its appearance when mouse is moved over the item")] + public bool HotTracking + { + get { return _HotTracking; } + set + { + if (value != _HotTracking) + { + bool oldValue = _HotTracking; + _HotTracking = value; + OnHotTrackingChanged(oldValue, value); + } + } + } + /// + /// Called when HotTracking property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnHotTrackingChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("HotTracking")); + } + + private bool _MouseOver = false, _MouseDown = false; + public override void InternalMouseEnter() + { + base.InternalMouseEnter(); + if (!this.DesignMode) + { + _MouseOver = true; + if (this.GetEnabled() && _HotTracking) + this.Refresh(); + } + } + + public override void InternalMouseLeave() + { + base.InternalMouseLeave(); + if (!this.DesignMode) + { + _MouseOver = false; + _MouseDown = false; + if (this.GetEnabled() && _HotTracking) + this.Refresh(); + } + } + + public override void InternalMouseDown(MouseEventArgs objArg) + { + base.InternalMouseDown(objArg); + if (objArg.Button == MouseButtons.Left && !this.DesignMode) + { + _MouseDown = true; + if (this.GetEnabled() && _HotTracking) + this.Refresh(); + } + } + + public override void InternalMouseUp(MouseEventArgs objArg) + { + base.InternalMouseUp(objArg); + + if (_MouseDown && !this.DesignMode) + { + _MouseDown = false; + if (this.GetEnabled() && _HotTracking) + this.Refresh(); + } + } + + /// + /// Gets whether mouse is over the item. + /// + [Browsable(false)] + public bool IsMouseOver + { + get { return _MouseOver; } + internal set { _MouseOver = value; } + } + + /// + /// Gets whether left mouse button is pressed on the item. + /// + [Browsable(false)] + public bool IsMouseDown + { + get { return _MouseDown; } + internal set { _MouseDown = value; } + } + + + private int _ImageTextSpacing = 4; + /// + /// Indicates the spacing between image and text. + /// + [DefaultValue(4), Category("Appearance"), Description("Indicates the spacing between image and text.")] + public int ImageTextSpacing + { + get { return _ImageTextSpacing; } + set + { + if (value != _ImageTextSpacing) + { + int oldValue = _ImageTextSpacing; + _ImageTextSpacing = value; + OnImageTextSpacingChanged(oldValue, value); + } + } + } + /// + /// Called when ImageTextSpacing property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnImageTextSpacingChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("ImageTextSpacing")); + NeedRecalcSize = true; + OnAppearanceChanged(); + this.Refresh(); + } + + private const int DefaultPadding = 4; + private Padding _Padding = new Padding(DefaultPadding); + /// + /// Gets or sets padding around content of the item. + /// + [Browsable(true), Category("Appearance"), Description("Gets or sets padding around content of the item."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public Padding Padding + { + get { return _Padding; } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePadding() + { + return _Padding.Bottom != DefaultPadding || _Padding.Top != DefaultPadding || _Padding.Left != DefaultPadding || _Padding.Right != DefaultPadding; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetPadding() + { + _Padding.All = DefaultPadding; + } + private void PaddingPropertyChanged(object sender, PropertyChangedEventArgs e) + { + NeedRecalcSize = true; + this.Refresh(); + } + + private Color[] _ProgressColors = null; + /// + /// Indicates the array of colors that when set are used to draw the current progress, i.e. Value>Minimum + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the current progress, i.e. Value>Minimum"), TypeConverter(typeof(ArrayConverter))] + public Color[] ProgressColors + { + get + { + return _ProgressColors; + } + set + { + if (_ProgressColors != value) + { + _ProgressColors = value; + //OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + this.Refresh(); + } + } + } + + private Color[] _BackColors = null; + /// + /// Indicates the array of colors that when set are used to draw the background of the item. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the background of the item."), TypeConverter(typeof(ArrayConverter))] + public Color[] BackColors + { + get + { + return _BackColors; + } + set + { + if (_BackColors != value) + { + _BackColors = value; + //OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + this.Refresh(); + } + } + } + + private eButtonTextAlignment _TextAlignment = eButtonTextAlignment.Left; + /// + /// Gets or sets the text alignment. Default value is left. + /// + [Browsable(true), DefaultValue(eButtonTextAlignment.Left), Category("Appearance"), Description("Indicates text alignment.")] + public eButtonTextAlignment TextAlignment + { + get { return _TextAlignment; } + set + { + _TextAlignment = value; + this.Refresh(); + } + } + + /// + /// Gets or sets the text associated with this item. + /// + [System.ComponentModel.Browsable(true), DevCoBrowsable(true), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The text contained in the item."), System.ComponentModel.Localizable(true), System.ComponentModel.DefaultValue("")] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + private Color _TextColor = Color.Empty; + /// + /// Gets or sets the color of the text. + /// + [Category("Columns"), Description("Indicates color of text.")] + public Color TextColor + { + get { return _TextColor; } + set { _TextColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return !_TextColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + this.TextColor = Color.Empty; + } + #endregion + + #region Markup Implementation + /// + /// Gets whether item supports text markup. Default is false. + /// + protected override bool IsMarkupSupported + { + get { return _EnableMarkup; } + } + + private bool _EnableMarkup = true; + /// + /// Gets or sets whether text-markup support is enabled for items Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the item instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for items Text property.")] + public bool EnableMarkup + { + get { return _EnableMarkup; } + set + { + if (_EnableMarkup != value) + { + _EnableMarkup = value; + NeedRecalcSize = true; + OnTextChanged(); + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItemContainer.cs b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItemContainer.cs new file mode 100644 index 00000000..12d268aa --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItemContainer.cs @@ -0,0 +1,221 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar +{ + /// + /// Container for the StepItem objects. + /// + public class StepItemContainer : ImageItem, IDesignTimeProvider + { + #region Implementation + /// + /// Initializes a new instance of the StepContainer class. + /// + public StepItemContainer() + { + m_IsContainer = true; + this.AutoCollapseOnClick = true; + this.AccessibleRole = System.Windows.Forms.AccessibleRole.Grouping; + } + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + StepItemContainer objCopy = new StepItemContainer(); + objCopy.Name = this.Name; + this.CopyToItem(objCopy); + return objCopy; + } + + /// + /// Copies the StepContainer specific properties to new instance of the item. + /// + /// New StepContainer instance. + internal void InternalCopyToItem(StepItemContainer copy) + { + CopyToItem(copy); + } + + /// + /// Copies the StepContainer specific properties to new instance of the item. + /// + /// New StepContainer instance. + protected override void CopyToItem(BaseItem copy) + { + StepItemContainer c = copy as StepItemContainer; + base.CopyToItem(c); + + + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + } + + public override void RecalcSize() + { + bool first = true; + Point loc = this.Bounds.Location; + Size totalSize = Size.Empty; + bool uniformHeight = true; + SubItemsCollection subItems = this.SubItems; + bool last = true; + int startIndex = subItems.Count - 1; + for (int i = startIndex; i >= 0; i--) + { + StepItem item = subItems[i] as StepItem; + if (item != null && item.Visible) + { + item.IsLast = last; + last = false; + } + } + foreach (BaseItem item in subItems) + { + item.DesignMarkerOrientation = eDesignMarkerOrientation.Horizontal; + StepItem si = item as StepItem; + if (!item.Visible) + { + item.Displayed = false; + if (si != null) + { + si.IsLast = false; + } + continue; + } + item.Displayed = true; + if (si != null) + { + si.IsFirst = first; + first = false; + si.RecalcSize(); + si.SetDisplayRectangle(new Rectangle(loc, si.Size)); + int stepWidth = (si.Size.Width - _PointerSize - 1); // 1 is so right hand line overlaps + loc.X += stepWidth; + totalSize.Width += stepWidth; + } + else + { + first = true; + item.RecalcSize(); + item.SetDisplayRectangle(new Rectangle(loc, item.Size)); + loc.X += item.WidthInternal; + totalSize.Width += item.WidthInternal; + } + if (uniformHeight && totalSize.Height > 0 && totalSize.Height != item.HeightInternal) + uniformHeight = false; + totalSize.Height = Math.Max(totalSize.Height, item.HeightInternal); + } + totalSize.Width += _PointerSize; + + // Vertically center items if they are all not of same height + if (!uniformHeight) + { + foreach (BaseItem item in subItems) + { + if (!item.Visible) + continue; + if (item.HeightInternal < totalSize.Height) + item.TopInternal = (totalSize.Height - item.HeightInternal) / 2; + } + } + m_Rect.Size = totalSize; + _CalculatedHeight = totalSize.Height; + _CalculatedWidth = totalSize.Width; + base.RecalcSize(); + } + + public override void Paint(ItemPaintArgs p) + { + ItemDisplay display = GetItemDisplay(); + display.Paint(this, p); + } + + private ItemDisplay m_ItemDisplay = null; + internal ItemDisplay GetItemDisplay() + { + if (m_ItemDisplay == null) + { + m_ItemDisplay = new ItemDisplay(); + } + return m_ItemDisplay; + } + + private int _PointerSize = 10; + /// + /// Gets or sets the arrow pointer width for the StepItem objects hosted within this container. + /// + [DefaultValue(10), Category("Appearance"), Description("Gets or sets the arrow pointer width for the StepItem objects hosted within this container.")] + public int PointerSize + { + get { return _PointerSize; } + set + { + if (value != _PointerSize) + { + int oldValue = _PointerSize; + _PointerSize = value; + OnPointerSizeChanged(oldValue, value); + } + } + } + /// + /// Called when PointerSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPointerSizeChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("PointerSize")); + + } + + private int _CalculatedWidth; + internal int CalculatedWidth + { + get { return _CalculatedWidth; } + set + { + _CalculatedWidth = value; + } + } + + private int _CalculatedHeight; + internal int CalculatedHeight + { + get { return _CalculatedHeight; } + set + { + _CalculatedHeight = value; + } + } + + #endregion + + #region IDesignTimeProvider Implementation + protected virtual InsertPosition GetContainerInsertPosition(Point pScreen, BaseItem dragItem) + { + return DesignTimeProviderContainer.GetInsertPosition(this, pScreen, dragItem); + } + InsertPosition IDesignTimeProvider.GetInsertPosition(Point pScreen, BaseItem dragItem) + { + return GetContainerInsertPosition(pScreen, dragItem); + } + void IDesignTimeProvider.DrawReversibleMarker(int iPos, bool Before) + { + DesignTimeProviderContainer.DrawReversibleMarker(this, iPos, Before); + } + void IDesignTimeProvider.InsertItemAt(BaseItem objItem, int iPos, bool Before) + { + DesignTimeProviderContainer.InsertItemAt(this, objItem, iPos, Before); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItemPainter.cs b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItemPainter.cs new file mode 100644 index 00000000..934a51c1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItemPainter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class StepItemPainter: IOffice2007Painter + { + /// + /// Paints StepItem. + /// + /// Provides arguments for the operation. + public virtual void Paint(StepItemRendererEventArgs e) { } + + #region IOffice2007Painter Members + private Office2007ColorTable _ColorTable = null; //new Office2007ColorTable(); + public Office2007ColorTable ColorTable + { + get + { + return _ColorTable; + } + set + { + _ColorTable = value; + } + } + + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItemRendererEventArgs.cs b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItemRendererEventArgs.cs new file mode 100644 index 00000000..8efde40f --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ProgressStepper/StepItemRendererEventArgs.cs @@ -0,0 +1,35 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar +{ + /// + /// Provides data for the Slider item rendering events. + /// + public class StepItemRendererEventArgs : EventArgs + { + /// + /// Gets or sets the reference to the item being rendered. + /// + public StepItem Item = null; + + /// + /// Gets or sets the reference to graphics object. + /// + public Graphics Graphics = null; + + internal ItemPaintArgs ItemPaintArgs = null; + + /// + /// Creates new instance of the object and initializes it with default values. + /// + /// Reference to the Slider item being rendered. + /// Reference to the graphics object. + public StepItemRendererEventArgs(StepItem item, Graphics g) + { + this.Item = item; + this.Graphics = g; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/RangeSlider.cs b/PROMS/DotNetBar Source Code/Controls/RangeSlider.cs new file mode 100644 index 00000000..57981150 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/RangeSlider.cs @@ -0,0 +1,448 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents Range Slider Control. + /// + [ToolboxBitmap(typeof(RangeSlider), "Controls.RangeSlider.ico"), ToolboxItem(true), DefaultEvent("ValueChanged"), ComVisible(false), Designer("DevComponents.DotNetBar.Design.RangeSliderDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class RangeSlider : BaseItemControl + { + #region Private Variables + private RangeSliderItem _Slider = null; + #endregion + + #region Events + /// + /// Occurs before Value has changed and allow the cancellation of the change. + /// + [Description("Occurs before Value has changed and allow the cancellation of the change.")] + public event RangeSliderValueChangingEventHandler ValueChanging; + /// + /// Raises ValueChanging event. + /// + /// Provides event arguments. + protected virtual void OnValueChanging(RangeSliderValueChangingEventArgs e) + { + RangeSliderValueChangingEventHandler handler = ValueChanging; + if (handler != null) + handler(this, e); + } + /// + /// Occurs after Value property has changed + /// + [Description("Occurs after Value property has changed.")] + public event EventHandler ValueChanged; + /// + /// Raises ValueChanged event. + /// + /// Provides event arguments. + protected virtual void OnValueChanged(EventArgs e) + { + EventHandler handler = ValueChanged; + if (handler != null) + handler(this, e); + } + /// + /// Occurs when control is about to display the range tooltip and it allows you to customize tooltip + /// + [Description("Occurs when control is about to display the range tooltip and it allows you to customize tooltip")] + public event RangeTooltipEventHandler RangeTooltipText; + /// + /// Raises GetRangeTooltipText event. + /// + /// Provides event arguments. + protected virtual void OnRangeTooltipText(RangeTooltipEventArgs e) + { + RangeTooltipEventHandler handler = RangeTooltipText; + if (handler != null) + handler(this, e); + } + #endregion + + #region Constructor, Dispose + public RangeSlider() + { + _Slider = new RangeSliderItem(); + _Slider.Style = eDotNetBarStyle.StyleManagerControlled; + _Slider.ValueChanging += new RangeSliderValueChangingEventHandler(Slider_ValueChanging); + _Slider.ValueChanged += new EventHandler(Slider_ValueChanged); + _Slider.RangeTooltipText += new RangeTooltipEventHandler(Slider_RangeTooltipText); + this.HostItem = _Slider; + } + + void Slider_RangeTooltipText(object sender, RangeTooltipEventArgs e) + { + OnRangeTooltipText(e); + } + + void Slider_ValueChanged(object sender, EventArgs e) + { + OnValueChanged(e); + } + + void Slider_ValueChanging(object sender, RangeSliderValueChangingEventArgs e) + { + OnValueChanging(e); + } + + /// + /// Forces the button to perform internal layout. + /// + public override void RecalcLayout() + { + Rectangle r = GetItemBounds(); + _Slider.Width = r.Width; + _Slider.Height = r.Height; + base.RecalcLayout(); + } + + protected override void OnHandleCreated(EventArgs e) + { + this.RecalcLayout(); + base.OnHandleCreated(e); + } + + //protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + //{ + // if (keyData == System.Windows.Forms.Keys.Left) + // { + // m_Slider.Increment(-m_Slider.Step, eEventSource.Keyboard); + // return true; + // } + // else if (keyData == System.Windows.Forms.Keys.Right) + // { + // m_Slider.Increment(m_Slider.Step, eEventSource.Keyboard); + // return true; + // } + // return base.ProcessCmdKey(ref msg, keyData); + //} + + /// + /// Gets the RangeSliderItem. + /// + internal RangeSliderItem SliderItem + { + get { return (_Slider); } + } + + /// + /// Indicates whether clicking the area outside of the range change buttons moves the range change button to the clicked location if possible thus allowing range change. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether clicking the area outside of the range change buttons moves the range change button to the clicked location if possible thus allowing range change.")] + public bool ClientClickRangeChangeEnabled + { + get { return _Slider.ClientClickRangeChangeEnabled; } + set + { + _Slider.ClientClickRangeChangeEnabled = value; + } + } + + /// + /// Gets or sets the maximum value of the range of the control. + /// + [Description("Gets or sets the maximum value of the range of the control."), Category("Behavior"), DefaultValue(10)] + public int Maximum + { + get { return _Slider.Maximum; } + set + { + _Slider.Maximum = value; + } + } + + /// + /// Gets or sets the minimum value of the range of the control. + /// + [Description("Gets or sets the minimum value of the range of the control."), Category("Behavior"), DefaultValue(0)] + public int Minimum + { + get { return _Slider.Minimum; } + set + { + _Slider.Minimum = value; + } + } + + /// + /// Indicates image to be used as maximum range slider button instead of built-in button. Image is scaled to size set by RangeButtonSize. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates image to be used as maximum range slider button instead of built-in button. Image is scaled to size set by RangeButtonSize.")] + public Image MaxRangeSliderImage + { + get { return _Slider.MaxRangeSliderImage; } + set + { + _Slider.MaxRangeSliderImage = value; + } + } + + /// + /// Indicates image to be used as minimum range slider button instead of built-in button. Image is scaled to size set by RangeButtonSize. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates image to be used as minimum range slider button instead of built-in button. Image is scaled to size set by RangeButtonSize.")] + public Image MinRangeSliderImage + { + get { return _Slider.MinRangeSliderImage; } + set + { + _Slider.MinRangeSliderImage = value; + } + } + + /// + /// Specifies minimum absolute range that user can select. Absolute range is defined as Abs(Value.Max-Value.Min) Applies to user performed selection through mouse only. + /// + [DefaultValue(0), Category("Behavior"), Description("Specifies minimum absolute range that user can select. Absolute range is defined as Abs(Value.Max-Value.Min) Applies to user performed selection through mouse only.")] + public int MinimumAbsoluteRange + { + get { return _Slider.MinimumAbsoluteRange; } + set + { + _Slider.MinimumAbsoluteRange = value; + } + } + + /// + /// Gets current part that is pressed using mouse left button. + /// + [Browsable(false)] + public eRangeSliderPart MouseDownPart + { + get { return _Slider.MouseDownPart; } + } + + /// + /// Gets mouse over part. + /// + [Browsable(false)] + public eRangeSliderPart MouseOverPart + { + get { return _Slider.MouseOverPart; } + } + + /// + /// Gets bounds of maximum range sliding button. + /// + [Browsable(false)] + public Rectangle RangeButtonMaxBounds + { + get + { + return _Slider.RangeButtonMaxBounds; + } + } + + /// + /// Gets bounds of minimum range sliding button. + /// + [Browsable(false)] + public Rectangle RangeButtonMinBounds + { + get + { + return _Slider.RangeButtonMinBounds; + } + } + + /// + /// Indicates the size of the range change buttons. + /// + [Description("Indicates the size of the range change buttons."), Category("Appearance")] + public Size RangeButtonSize + { + get { return _Slider.RangeButtonSize; } + set + { + _Slider.RangeButtonSize = value; + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeRangeButtonSize() + { + return _Slider.ShouldSerializeRangeButtonSize(); + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetRangeButtonSize() + { + _Slider.ResetRangeButtonSize(); + } + + /// + /// Specifies the height of the range line + /// + [DefaultValue(7), Category("Appearance"), Description("Specifies the height of the range line")] + public int RangeLineHeight + { + get { return _Slider.RangeLineHeight; } + set + { + _Slider.RangeLineHeight = value; + } + } + + /// + /// Gets or sets the string that is used to format the range value to be displayed while user moves the range buttons. Value set here is used in string.Format(RangeTooltipFormat, Value.Min, Value.Max). + /// + [DefaultValue("{0} - {1}"), Description("Indicate string that is used to format the range value to be displayed while user moves the range buttons. Value set here is used in string.Format(RangeTooltipFormat, Value.Min, Value.Max)."), Localizable(true), Category("Behavior")] + public string RangeTooltipFormat + { + get { return _Slider.RangeTooltipFormat; } + set + { + _Slider.RangeTooltipFormat = value; + } + } + + /// + /// Gets or sets the color of the range value. + /// + [Category("Appearance"), Description("Indicates color of range value.")] + public Color RangeValueColor + { + get { return _Slider.RangeValueColor; } + set + { + _Slider.RangeValueColor = value; + } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeRangeValueColor() + { + return _Slider.ShouldSerializeRangeValueColor(); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetRangeValueColor() + { + _Slider.ResetRangeValueColor(); + } + + /// + /// Specifies whether range tooltip is shown while user is changing the range + /// + [DefaultValue(true), Category("Behavior"), Description("Specifies whether range tooltip is shown while user is changing the range")] + public bool ShowRangeTooltip + { + get { return _Slider.ShowRangeTooltip; } + set + { + _Slider.ShowRangeTooltip = value; + } + } + + /// + /// Gets or sets the slider orientation. Default value is horizontal. + /// + [DefaultValue(eOrientation.Horizontal), Category("Appearance"), Description("Indicates slider orientation.")] + public eOrientation SliderOrientation + { + get { return _Slider.SliderOrientation; } + set + { + _Slider.SliderOrientation = value; + } + } + + [Browsable(false)] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + /// + /// Gets tick marks bounds. + /// + [Browsable(false)] + public Rectangle TicksBounds + { + get + { + return _Slider.TicksBounds; + } + } + private Rectangle _TicksBounds2 = Rectangle.Empty; + /// + /// Gets tick marks bounds for second marker is visible. + /// + [Browsable(false)] + public Rectangle TicksBounds2 + { + get + { + return _Slider.TicksBounds2; + } + } + + /// + /// Specifies the ticks position inside of Range Slider. + /// + [DefaultValue(eTicksPosition.Bottom), Category("Appearance"), Description("Specifies the ticks position inside of Range Slider.")] + public eTicksPosition TicksPosition + { + get { return _Slider.TicksPosition; } + set + { + _Slider.TicksPosition = value; + } + } + + /// + /// Indicates tick display period + /// + [DefaultValue(1), Category("Appearance"), Description("Indicates tick display period")] + public int TicksStep + { + get { return _Slider.TicksStep; } + set + { + _Slider.TicksStep = value; + } + } + + /// + /// Indicates whether tick lines are shown + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether tick lines are shown")] + public bool TicksVisible + { + get { return _Slider.TicksVisible; } + set + { + _Slider.TicksVisible = value; + } + } + + /// + /// Gets or sets the range displayed by the control. + /// + [Description("Specifies range displayed by the control."), Category("Data")] + public RangeValue Value + { + get { return _Slider.Value; } + set + { + _Slider.Value = value; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/RangeSlider.ico b/PROMS/DotNetBar Source Code/Controls/RangeSlider.ico new file mode 100644 index 00000000..53bba306 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/RangeSlider.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/RatingStar.cs b/PROMS/DotNetBar Source Code/Controls/RatingStar.cs new file mode 100644 index 00000000..4c973b5c --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/RatingStar.cs @@ -0,0 +1,474 @@ +using System; +using System.Text; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.Editors; +using System.Drawing; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the Rating control. + /// + [ToolboxBitmap(typeof(RatingStar), "Controls.RatingStar.ico"), ToolboxItem(true), DefaultEvent("RatingChanged"), System.Runtime.InteropServices.ComVisible(true)] + public class RatingStar : BaseItemControl, ICommandSource + { + #region Private Variables + private RatingItem _RatingItem = null; + #endregion + + #region Events + /// + /// Occurs when Rating property has changed. + /// + [Description("Occurs when Rating property has changed.")] + public event EventHandler RatingChanged; + /// + /// Occurs when RatingValue property has changed. + /// + [Description("Occurs when Rating property has changed.")] + public event EventHandler RatingValueChanged; + /// + /// Occurs when Rating property is about to be changed and provides opportunity to cancel the change. + /// + [Description("Occurs when Rating property has changed.")] + public event RatingChangeEventHandler RatingChanging; + /// + /// Occurs when AverageRating property has changed. + /// + [Description("Occurs when AverageRating property has changed.")] + public event EventHandler AverageRatingChanged; + /// + /// Occurs when AverageRatingValue property has changed. + /// + [Description("Occurs when AverageRatingValue property has changed.")] + public event EventHandler AverageRatingValueChanged; + /// + /// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + public event MarkupLinkClickEventHandler MarkupLinkClick; + /// + /// Occurs when RatingValue property is set and it allows you to provide custom parsing for the values. + /// + public event ParseIntegerValueEventHandler ParseRatingValue; + /// + /// Occurs when AverageRatingValue property is set and it allows you to provide custom parsing for the values. + /// + public event ParseDoubleValueEventHandler ParseAverageRatingValue; + #endregion + + #region Constructor + /// + /// Initializes a new instance of the Rating class. + /// + public RatingStar() + { + this.SetStyle(ControlStyles.Selectable, false); + _RatingItem = new RatingItem(); + _RatingItem.Style = eDotNetBarStyle.Office2007; + _RatingItem.RatingChanging += new RatingChangeEventHandler(RatingItemRatingChanging); + _RatingItem.RatingChanged += new EventHandler(RatingItemRatingChanged); + _RatingItem.AverageRatingChanged += new EventHandler(RatingItemAverageRatingChanged); + _RatingItem.ParseAverageRatingValue += new DevComponents.Editors.ParseDoubleValueEventHandler(RatingItemParseAverageRatingValue); + _RatingItem.ParseRatingValue += new DevComponents.Editors.ParseIntegerValueEventHandler(RatingItemParseRatingValue); + this.HostItem = _RatingItem; + } + + #endregion + + #region Internal Implementation + /// + /// Indicates number of stars used for the rating. Minium value is 2 stars. + /// + [DefaultValue(5), Category("Appearance"), Description("Indicates number of stars used for the rating.")] + public int NumberOfStars + { + get { return _RatingItem.NumberOfStars; } + set + { + _RatingItem.NumberOfStars = value; + if (this.AutoSize) this.AdjustSize(); + } + } + + /// + /// Gets or sets the rating value represented by the control. Default value is 0 which indicates + /// that there is no rating set. Maximum value is 5. + /// + [DefaultValue(0), Category("Data"), Description("Indicates rating value represented by the control.")] + public int Rating + { + get + { + return _RatingItem.Rating; + } + set + { + _RatingItem.Rating = value; + } + } + /// + /// Gets or sets the average rating shown by control. Control will display average rating (if set) when no explicit + /// Rating value is set through Rating property. Minimum value is 0 and Maximum value is 5. + /// + [DefaultValue(0d), Category("Data"), Description("Indicates average rating shown by control.")] + public double AverageRating + { + get + { + return _RatingItem.AverageRating; + } + set + { + _RatingItem.AverageRating = value; + } + } + /// + /// Gets or sets the AverageRating property. This property is provided for Data-Binding with NULL value support. + /// + [Bindable(true), Browsable(false), RefreshProperties(RefreshProperties.All), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter))] + public object AverageRatingValue + { + get + { + return _RatingItem.AverageRatingValue; + } + set + { + _RatingItem.AverageRatingValue = value; + } + } + /// + /// Gets the reference to custom rating images. + /// + [Browsable(true), Category("Images"), Description("Gets the reference to custom rating images."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public RatingImages CustomImages + { + get { return _RatingItem.CustomImages; } + } + /// + /// Gets or sets whether text assigned to the check box is visible. Default value is true. + /// + [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates whether text assigned to the check box is visible.")] + public bool TextVisible + { + get { return _RatingItem.TextVisible; } + set + { + _RatingItem.TextVisible = value; + } + } + /// + /// Gets or sets whether text-markup support is enabled for items Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the item instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for items Text property.")] + public bool EnableMarkup + { + get { return _RatingItem.EnableMarkup; } + set + { + _RatingItem.EnableMarkup = value; + } + } + /// + /// Gets or sets whether rating can be edited. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether rating can be edited.")] + public bool IsEditable + { + get { return _RatingItem.IsEditable; } + set + { + _RatingItem.IsEditable = value; + } + } + /// + /// Gets or sets the orientation of rating control. + /// + [DefaultValue(eOrientation.Horizontal), Category("Appearance"), Description("Gets or sets the orientation of rating control.")] + public eOrientation RatingOrientation + { + get { return _RatingItem.RatingOrientation; } + set + { + _RatingItem.RatingOrientation = value; + } + } + /// + /// Gets or sets the Rating property value. This property is provided for Data-Binding with NULL value support. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), RefreshProperties(RefreshProperties.All), Bindable(true)] + public object RatingValue + { + get { return _RatingItem.RatingValue; } + set + { + _RatingItem.RatingValue = value; + } + } + /// + /// Gets or sets the text color. Default value is Color.Empty which indicates that default color is used. + /// + [Browsable(true), Category("Appearance"), Description("Indicates text color.")] + public Color TextColor + { + get { return _RatingItem.TextColor; } + set + { + _RatingItem.TextColor = value; + } + } + /// + /// Gets or sets the spacing between optional text and the rating. + /// + [DefaultValue(0), Category("Appearance"), Description("Gets or sets the spacing between optional text and the rating.")] + public int TextSpacing + { + get { return _RatingItem.TextSpacing; } + set + { + _RatingItem.TextSpacing = value; + } + } + + private void RatingItemParseRatingValue(object sender, DevComponents.Editors.ParseIntegerValueEventArgs e) + { + OnParseRatingValue(e); + } + /// + /// Raises the ParseRating event. + /// + /// Provides event arguments. + protected virtual void OnParseRatingValue(ParseIntegerValueEventArgs e) + { + if (ParseRatingValue != null) + ParseRatingValue(this, e); + } + + private void RatingItemParseAverageRatingValue(object sender, DevComponents.Editors.ParseDoubleValueEventArgs e) + { + OnParseAverageRatingValue(e); + } + /// + /// Raises the ParseAverageRatingValue event. + /// + /// Provides event arguments. + protected virtual void OnParseAverageRatingValue(ParseDoubleValueEventArgs e) + { + if (ParseAverageRatingValue != null) + ParseAverageRatingValue(this, e); + } + + private void RatingItemAverageRatingChanged(object sender, EventArgs e) + { + OnAverageRatingChanged(e); + } + /// + /// Raises the AverageRatingChanged event. + /// + /// Event data. + protected virtual void OnAverageRatingChanged(EventArgs eventArgs) + { + if (AverageRatingChanged != null) AverageRatingChanged(this, eventArgs); + if (AverageRatingValueChanged != null) AverageRatingValueChanged(this, eventArgs); + } + + private void RatingItemRatingChanged(object sender, EventArgs e) + { + OnRatingChanged(e); + } + /// + /// Raises the RatingChanged event. + /// + /// Event data. + protected virtual void OnRatingChanged(EventArgs eventArgs) + { + EventHandler handler = RatingChanged; + if (handler != null) handler(this, eventArgs); + + handler = RatingValueChanged; + if (handler != null) handler(this, eventArgs); + } + + private void RatingItemRatingChanging(object sender, RatingChangeEventArgs e) + { + OnRatingChanging(e); + } + /// + /// Raises RatingChanging event. + /// + /// Event data + protected virtual void OnRatingChanging(RatingChangeEventArgs e) + { + if (RatingChanging != null) + RatingChanging(this, e); + } + +#if FRAMEWORK20 + [Localizable(true), Browsable(false)] + public new System.Windows.Forms.Padding Padding + { + get { return base.Padding; } + set { base.Padding = value; } + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + } + + public override Size GetPreferredSize(Size proposedSize) + { + if (!BarFunctions.IsHandleValid(this)) + return base.GetPreferredSize(proposedSize); + + _RatingItem.RecalcSize(); + Size s = _RatingItem.CalcSize; + s.Width += 2; + s.Height += 2; + if (!this.TextVisible) s.Width += 2; + s.Width += ElementStyleLayout.HorizontalStyleWhiteSpace(this.GetBackgroundStyle()); + s.Height += ElementStyleLayout.VerticalStyleWhiteSpace(this.GetBackgroundStyle()); + _RatingItem.Bounds = GetItemBounds(); + return s; + } + + /// + /// Gets or sets a value indicating whether the control is automatically resized to display its entire contents. You can set MaximumSize.Width property to set the maximum width used by the control. + /// + [Browsable(true), DefaultValue(false), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override bool AutoSize + { + get + { + return base.AutoSize; + } + set + { + if (this.AutoSize != value) + { + base.AutoSize = value; + AdjustSize(); + } + } + } + + protected Size CalcSize + { + get { return (_RatingItem.CalcSize); } + } + + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + if (this.AutoSize) + { + Size preferredSize = base.PreferredSize; + width = preferredSize.Width; + height = preferredSize.Height; + } + base.SetBoundsCore(x, y, width, height, specified); + } + + private void AdjustSize() + { + if (this.AutoSize) + { + this.Size = base.PreferredSize; + } + } + + protected override void OnVisualPropertyChanged() + { + base.OnVisualPropertyChanged(); + this.AdjustSize(); + } + + protected override void OnTextChanged(EventArgs e) + { + base.OnTextChanged(e); + this.AdjustSize(); + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + if (this.AutoSize) + this.AdjustSize(); + } +#endif + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + CommandManager.ExecuteCommand(this); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + } + } + + private ICommand _Command = null; + //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if (changed) + OnCommandChanged(); + } + } + + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/RatingStar.ico b/PROMS/DotNetBar Source Code/Controls/RatingStar.ico new file mode 100644 index 00000000..67b9f137 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/RatingStar.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/ReflectionImage.cs b/PROMS/DotNetBar Source Code/Controls/ReflectionImage.cs new file mode 100644 index 00000000..6fa8bf96 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ReflectionImage.cs @@ -0,0 +1,261 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents an image control with built-in reflection. + /// + [ToolboxBitmap(typeof(ReflectionImage), "Controls.ReflectionImage.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.ReflectionImageDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ReflectionImage : ControlWithBackgroundStyle + { + #region Private Variables + private Bitmap _ReflectionBitmap = null; + private Bitmap _DisabledBitmap = null; + #endregion + + #region Events + /// + /// Initializes a new instance of the ReflectionImage class. + /// + public ReflectionImage() + { + } + #endregion + + #region Constructor + #endregion + + #region Internal Implementation + protected override void Dispose(bool disposing) + { + DisposeReflectionImage(); + DisposeDisabledImage(); + if (BarUtilities.DisposeItemImages && !this.DesignMode) + { + BarUtilities.DisposeImage(ref _Image); + } + base.Dispose(disposing); + } + private Image _Image = null; + /// + /// Gets or sets the image displayed on the control. + /// + [DefaultValue(null), Description("Indicates image displayed on the control."), Category("Appearance")] + public Image Image + { + get { return _Image; } + set + { + if (_Image != value) + { + _Image = value; + OnImageChanged(); + } + } + } + + private void OnImageChanged() + { + DisposeDisabledImage(); + CreateReflectionImage(); + } + + private void CreateReflectionImage() + { + DisposeReflectionImage(); + Image image = GetImage(); + if (image != null) + { + _ReflectionBitmap = ImageHelper.CreateReflectionImage(image); + } + this.Invalidate(); + } + + private Image GetImage() + { + if (this.Enabled) return _Image; + if (_DisabledBitmap == null) + { + _DisabledBitmap = ImageHelper.CreateGrayScaleImage(_Image); + } + return _DisabledBitmap; + } + + private void DisposeReflectionImage() + { + if (_ReflectionBitmap != null) + { + _ReflectionBitmap.Dispose(); + _ReflectionBitmap = null; + } + } + + private void DisposeDisabledImage() + { + if (_DisabledBitmap != null) + { + _DisabledBitmap.Dispose(); + _DisabledBitmap = null; + } + } + + protected override void PaintContent(PaintEventArgs e) + { + Image image = GetImage(); + if (image == null) return; + + Graphics g = e.Graphics; + SmoothingMode sm = g.SmoothingMode; + if (AntiAlias) + g.SmoothingMode = SmoothingMode.HighQuality; + + bool disposeStyle = false; + ElementStyle style = this.GetBackgroundStyle(out disposeStyle); + + Rectangle r = GetContentRectangle(); + Point imageLocation = r.Location; + + if (style.TextAlignment == eStyleTextAlignment.Center && r.Width > image.Width) + imageLocation.X += (r.Width - image.Width) / 2; + else if (style.TextAlignment == eStyleTextAlignment.Far && r.Width > image.Width) + imageLocation.X += (r.Width - image.Width); + float reflectionFactor = .52f; + if (style.TextLineAlignment == eStyleTextAlignment.Center && r.Height > (image.Height + image.Height * reflectionFactor)) + imageLocation.Y += (int)((r.Height - (image.Height + image.Height * reflectionFactor)) / 2); + else if (style.TextLineAlignment == eStyleTextAlignment.Far && r.Height > (image.Height + image.Height * reflectionFactor)) + imageLocation.Y += (int)(r.Height - (image.Height + image.Height * reflectionFactor)); + + g.DrawImage(image, imageLocation.X, imageLocation.Y, image.Width, image.Height); + + if (_ReflectionBitmap != null && _ReflectionEnabled) + { + imageLocation.Y += image.Height; + g.DrawImage(_ReflectionBitmap, imageLocation); + } + + if (disposeStyle) style.Dispose(); + + if (AntiAlias) + g.SmoothingMode = sm; + } + + protected override Size DefaultSize + { + get + { + return new Size(128, 128); + } + } + + private bool _ReflectionEnabled = true; + /// + /// Gets or sets whether reflection effect is enabled. Default value is true. + /// + [DefaultValue(true), Description("Indicates whether reflection effect is enabled.")] + public bool ReflectionEnabled + { + get { return _ReflectionEnabled; } + set + { + if (_ReflectionEnabled != value) + { + _ReflectionEnabled = value; + this.Invalidate(); + } + } + } + + protected override void OnEnabledChanged(EventArgs e) + { + CreateReflectionImage(); + base.OnEnabledChanged(e); + } + #endregion + + #region Property Hiding + [Browsable(false)] + public override Image BackgroundImage + { + get + { + return base.BackgroundImage; + } + set + { + base.BackgroundImage = value; + } + } + + [Browsable(false)] + public override Font Font + { + get + { + return base.Font; + } + set + { + base.Font = value; + } + } + [Browsable(false)] + public override Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + +#if FRAMEWORK20 + [Browsable(false)] + public override ImageLayout BackgroundImageLayout + { + get + { + return base.BackgroundImageLayout; + } + set + { + base.BackgroundImageLayout = value; + } + } + + [Browsable(false)] + public new System.Windows.Forms.Padding Padding + { + get + { + return base.Padding; + } + set + { + base.Padding = value; + } + } +#endif + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ReflectionImage.ico b/PROMS/DotNetBar Source Code/Controls/ReflectionImage.ico new file mode 100644 index 00000000..4a3e0846 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/ReflectionImage.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/ReflectionLabel.cs b/PROMS/DotNetBar Source Code/Controls/ReflectionLabel.cs new file mode 100644 index 00000000..7cf3ab93 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ReflectionLabel.cs @@ -0,0 +1,430 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents an single line of text label control with text-markup support and built-in reflection. + /// + [ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.ReflectionLabelDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), ToolboxBitmap(typeof(LabelX), "Controls.ReflectionLabel.ico")] + public class ReflectionLabel : ControlWithBackgroundStyle + { + #region Private Variables + private TextMarkup.BodyElement _TextMarkup = null; + private Bitmap _ReflectionBitmap = null; + private float _ReflectionFactor = .52f; + private Size _TextSize = Size.Empty; + #endregion + + #region Events + /// + /// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + public event MarkupLinkClickEventHandler MarkupLinkClick; + #endregion + + #region Constructor + #endregion + + #region Internal Implementation + protected override void Dispose(bool disposing) + { + DisposeReflectionImage(); + base.Dispose(disposing); + } + + protected override void PaintContent(PaintEventArgs e) + { + Graphics g = e.Graphics; + SmoothingMode sm = g.SmoothingMode; + if (AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + + Rectangle r = GetContentRectangle(); + Point reflectionLocation = r.Location; + bool disposeStyle = false; + ElementStyle style = this.GetBackgroundStyle(out disposeStyle); + + if (_TextMarkup != null) + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, (style.TextColor.IsEmpty?this.ForeColor:style.TextColor), + (this.RightToLeft == RightToLeft.Yes), Rectangle.Empty, true); + if (!this.Enabled) + { + d.IgnoreFormattingColors = true; + d.CurrentForeColor = SystemColors.ControlDark; + } + _TextMarkup.Render(d); + reflectionLocation.Y = _TextMarkup.Bounds.Bottom; + reflectionLocation.X = 0; + } + else + { + int totalHeight = (int)(_TextSize.Height * (1 + _ReflectionFactor)); + int y = r.Y, x = r.X; + if (style.TextLineAlignment == eStyleTextAlignment.Center) + { + y += (r.Height - totalHeight) / 2; + } + else if (style.TextLineAlignment == eStyleTextAlignment.Far) + { + y += (r.Height - totalHeight); + } + TextDrawing.DrawString(g, this.Text, this.Font, (style.TextColor.IsEmpty ? this.ForeColor : style.TextColor), new Rectangle(x, y, r.Width, r.Height), GetTextFormat(style)); + reflectionLocation.Y = y + _TextSize.Height; + } + + Rectangle rClip = new Rectangle(0, reflectionLocation.Y, this.Width, this.Height - reflectionLocation.Y); + g.SetClip(rClip, CombineMode.Replace); + + int fontBaseOffset = (int)Math.Floor(Font.Size * Font.FontFamily.GetCellDescent(Font.Style) / Font.FontFamily.GetEmHeight(Font.Style)); + reflectionLocation.Y -= fontBaseOffset; + + if (_ReflectionBitmap != null && _ReflectionEnabled) + { + g.DrawImage(_ReflectionBitmap, reflectionLocation); + } + g.ResetClip(); + if (disposeStyle) style.Dispose(); + if (AntiAlias) + g.SmoothingMode = sm; + } + + protected override void OnTextChanged(EventArgs e) + { + UpdateDisplay(); + base.OnTextChanged(e); + } + + protected override void OnFontChanged(EventArgs e) + { + UpdateDisplay(); + base.OnFontChanged(e); + } + + protected override void OnForeColorChanged(EventArgs e) + { + UpdateDisplay(); + base.OnForeColorChanged(e); + } + + protected override void OnVisualPropertyChanged() + { + UpdateDisplay(); + base.OnVisualPropertyChanged(); + } + + protected override void OnResize(EventArgs e) + { + UpdateDisplay(); + base.OnResize(e); + } + + private void UpdateDisplay() + { + string text = this.Text; + + if (_TextMarkup != null) + { + _TextMarkup.MouseLeave(this); + _TextMarkup.HyperLinkClick -= new EventHandler(TextMarkupLinkClicked); + _TextMarkup = null; + } + + if (TextMarkup.MarkupParser.IsMarkup(ref text)) + _TextMarkup = TextMarkup.MarkupParser.Parse(text); + + if (_TextMarkup != null) + { + _TextMarkup.HyperLinkClick += new EventHandler(TextMarkupLinkClicked); + } + + CreateReflection(); + this.Invalidate(); + } + + private void CreateReflection() + { + DisposeReflectionImage(); + if (Text.Length == 0 || this.Width <= 0 || this.Height <= 0 || this.Font == null) return; + + // Create image based on the control content + Bitmap bmp = null; + if (_TextMarkup == null) + { + using(Graphics g = this.CreateGraphics()) + { + if (AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + Size s = TextDrawing.MeasureString(g, this.Text, this.Font); + bmp = new Bitmap(this.Width, s.Height, PixelFormat.Format32bppArgb); + _TextSize = s; + } + bmp.MakeTransparent(); + + Color transparentColor = Color.Empty; + using (Graphics g = Graphics.FromImage(bmp)) + { + bool disposeStyle = false; + ElementStyle style = this.GetBackgroundStyle(out disposeStyle); + + if (AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + transparentColor = style.BackColor.IsEmpty ? this.BackColor : style.BackColor; + if (transparentColor.IsEmpty || transparentColor == Color.Transparent) transparentColor = Color.WhiteSmoke; + DisplayHelp.FillRectangle(g, new Rectangle(0, 0, bmp.Width, bmp.Height), transparentColor); + } + + TextDrawing.DrawString(g, this.Text, this.Font, (style.TextColor.IsEmpty ? this.ForeColor : style.TextColor), + new Rectangle(0, 0, bmp.Width, bmp.Height), GetTextFormat(style)); + + if (disposeStyle) style.Dispose(); + } + if (!transparentColor.IsEmpty) + bmp.MakeTransparent(transparentColor); + } + else + { + ResizeMarkup(); + if (_TextMarkup.Bounds.Height > 0) + { + bmp = new Bitmap(this.Width, _TextMarkup.Bounds.Height, PixelFormat.Format32bppArgb); + Color transparentColor = Color.Empty; + using (Graphics g = Graphics.FromImage(bmp)) + { + bool disposeStyle = false; + ElementStyle style = this.GetBackgroundStyle(out disposeStyle); + + if (AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + transparentColor = style.BackColor.IsEmpty ? this.BackColor : style.BackColor; + if (transparentColor.IsEmpty || transparentColor == Color.Transparent) transparentColor = Color.WhiteSmoke; + DisplayHelp.FillRectangle(g, new Rectangle(0, 0, bmp.Width, bmp.Height), transparentColor); + } + if (_TextMarkup.Bounds.Top > 0) + g.TranslateTransform(0, -(_TextMarkup.Bounds.Top - GetContentRectangle().Y)); + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, (style.TextColor.IsEmpty ? this.ForeColor : style.TextColor), + (this.RightToLeft == RightToLeft.Yes), Rectangle.Empty, true); + if (!this.Enabled) + { + d.IgnoreFormattingColors = true; + d.CurrentForeColor = SystemColors.ControlDark; + } + _TextMarkup.Render(d); + + if (disposeStyle) style.Dispose(); + } + if (!transparentColor.IsEmpty) + bmp.MakeTransparent(transparentColor); + } + } + + if (bmp != null) + { + _ReflectionBitmap = ImageHelper.CreateReflectionImage(bmp); + bmp.Dispose(); + } + } + + private eTextFormat GetTextFormat(ElementStyle style) + { + if (style.TextAlignment == eStyleTextAlignment.Center) + return eTextFormat.HorizontalCenter; + else if (style.TextAlignment == eStyleTextAlignment.Far) + return eTextFormat.Right; + return eTextFormat.Default; + } + + private void DisposeReflectionImage() + { + if (_ReflectionBitmap != null) + { + _ReflectionBitmap.Dispose(); + _ReflectionBitmap = null; + } + } + + private void TextMarkupLinkClicked(object sender, EventArgs e) + { + TextMarkup.HyperLink link = sender as TextMarkup.HyperLink; + if (link != null) + { + OnMarkupLinkClick(new MarkupLinkClickEventArgs(link.Name, link.HRef)); + } + } + + protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e) + { + if (this.MarkupLinkClick != null) + MarkupLinkClick(this, e); + } + + protected virtual void ResizeMarkup() + { + if (_TextMarkup != null) + { + Rectangle r = this.GetContentRectangle(); + if (r.Width <= 0 || r.Height <= 0) + return; + + Graphics g = this.CreateGraphics(); + try + { + if (AntiAlias) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; + } + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, SystemColors.Control, (this.RightToLeft == RightToLeft.Yes)); + Size measureSize = new Size(10000, r.Height); + _TextMarkup.Measure(measureSize, d); + bool disposeStyle = false; + ElementStyle style = this.GetBackgroundStyle(out disposeStyle); + + int totalHeight = (int)(_TextMarkup.Bounds.Height * (1 + _ReflectionFactor)); + if (totalHeight < r.Height) + { + if (style.TextLineAlignment == eStyleTextAlignment.Center) + { + r.Y += (r.Height - totalHeight) / 2; + r.Height = _TextMarkup.Bounds.Height; + } + else if (style.TextLineAlignment == eStyleTextAlignment.Far) + { + r.Y = (r.Bottom - totalHeight); + r.Height = _TextMarkup.Bounds.Height; + } + } + + if (_TextMarkup.Bounds.Width < r.Width) + { + if (style.TextAlignment == eStyleTextAlignment.Center) + { + r.X += (r.Width - _TextMarkup.Bounds.Width) / 2; + r.Width = _TextMarkup.Bounds.Width; + } + else if (style.TextAlignment == eStyleTextAlignment.Far && this.RightToLeft == RightToLeft.No || + style.TextAlignment == eStyleTextAlignment.Near && this.RightToLeft == RightToLeft.Yes) + { + r.X = (r.Right - _TextMarkup.Bounds.Width); + r.Width = _TextMarkup.Bounds.Width; + } + } + + _TextMarkup.Arrange(r, d); + + if (disposeStyle) style.Dispose(); + } + finally + { + g.Dispose(); + } + } + } + + protected override void OnEnabledChanged(EventArgs e) + { + CreateReflection(); + this.Invalidate(); + base.OnEnabledChanged(e); + } + + protected override Size DefaultSize + { + get + { + return new Size(175, 70); + } + } + + private bool _ReflectionEnabled = true; + /// + /// Gets or sets whether reflection effect is enabled. Default value is true. + /// + [DefaultValue(true), Description("Indicates whether reflection effect is enabled.")] + public bool ReflectionEnabled + { + get { return _ReflectionEnabled; } + set + { + if (_ReflectionEnabled != value) + { + _ReflectionEnabled = value; + this.Invalidate(); + } + } + } + #endregion + + #region Property hiding + [Browsable(false)] + public override Image BackgroundImage + { + get + { + return base.BackgroundImage; + } + set + { + base.BackgroundImage = value; + } + } + +#if FRAMEWORK20 + [Browsable(false)] + public override ImageLayout BackgroundImageLayout + { + get + { + return base.BackgroundImageLayout; + } + set + { + base.BackgroundImageLayout = value; + } + } + + [Browsable(false)] + public new System.Windows.Forms.Padding Padding + { + get + { + return base.Padding; + } + set + { + base.Padding = value; + } + } +#endif + [Browsable(true), DefaultValue(""), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), EditorBrowsable(EditorBrowsableState.Always), Category("Appearance"), Description("Gets or sets the text displayed on label.")] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ReflectionLabel.ico b/PROMS/DotNetBar Source Code/Controls/ReflectionLabel.ico new file mode 100644 index 00000000..9cc5d274 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/ReflectionLabel.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/RichTextBoxEx.cs b/PROMS/DotNetBar Source Code/Controls/RichTextBoxEx.cs new file mode 100644 index 00000000..0a782e17 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/RichTextBoxEx.cs @@ -0,0 +1,1270 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Windows.Forms; +using System.Drawing; +using System.IO; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(true), Docking(DockingBehavior.Ask)] + [Description("Provides rich-text, RTF text editing."), ToolboxBitmap(typeof(RichTextBoxEx), "Controls.RichTextBoxEx.ico"), DefaultEvent("TextChanged"), DefaultProperty("Text")] + [DefaultBindingProperty("Text")] + [Designer("DevComponents.DotNetBar.Design.RichTextBoxExDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class RichTextBoxEx : ScrollbarControl + { + #region Constructor + /// + /// Initializes a new instance of the RichTextBoxEx class. + /// + public RichTextBoxEx() + { + RichTextBoxScrollEx rtb = new RichTextBoxScrollEx(); + this.SetStyle(ControlStyles.Selectable, false); + rtb.AcceptsTabChanged += OnRichTextBoxAcceptsTabChanged; + rtb.TextChanged += OnRichTextBoxTextChanged; + rtb.HideSelectionChanged += OnRichTextBoxHideSelectionChanged; + rtb.ModifiedChanged += OnRichTextBoxModifiedChanged; + rtb.MultilineChanged += OnRichTextBoxMultilineChanged; + rtb.ReadOnlyChanged += OnRichTextBoxReadOnlyChanged; + rtb.GotFocus += OnRichTextBoxGotFocus; + rtb.LostFocus += OnRichTextBoxLostFocus; + rtb.KeyDown += OnRichTextBoxKeyDown; + rtb.KeyUp += OnRichTextBoxKeyUp; + rtb.KeyPress += OnRichTextBoxKeyPress; + rtb.PreviewKeyDown += OnRichTextBoxPreviewKeyDown; + rtb.LinkClicked += OnRichTextBoxLinkClicked; + rtb.Protected += OnRichTextBoxProtected; + rtb.SelectionChanged += OnRichTextBoxSelectionChanged; + rtb.HScroll += OnRichTextBoxHScroll; + rtb.VScroll += OnRichTextBoxVScroll; + rtb.Validating += OnRichTextBoxValidating; + rtb.Validated += OnRichTextBoxValidated; + RichTextBox = rtb; + rtb.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.ScrollOverrideControl = rtb; + } + #endregion + + #region Internals + + private RichTextBox _RichTextBox; + /// + /// Gets the reference to internal RichTextBox control. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public RichTextBox RichTextBox + { + get { return _RichTextBox; } + internal set { _RichTextBox = value; } + } + private void OnRichTextBoxAcceptsTabChanged(object sender, EventArgs e) + { + this.OnAcceptsTabChanged(e); + } + /// + /// Occurs when the value of the AcceptsTab property changes + /// + [Description("Occurs when the value of the AcceptsTab property changes.")] + public event EventHandler AcceptsTabChanged; + /// + /// Raises AcceptsTabChanged event. + /// + /// Provides event arguments. + protected virtual void OnAcceptsTabChanged(EventArgs e) + { + EventHandler handler = AcceptsTabChanged; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxTextChanged(object sender, EventArgs e) + { + this.OnTextChanged(e); + } + private void OnRichTextBoxHideSelectionChanged(object sender, EventArgs e) + { + this.OnHideSelectionChanged(e); + } + /// + /// Occurs when the value of the HideSelection property changes. + /// + [Description("Occurs when the value of the HideSelection property changes.")] + public event EventHandler HideSelectionChanged; + /// + /// Raises HideSelectionChanged event. + /// + /// Provides event arguments. + protected virtual void OnHideSelectionChanged(EventArgs e) + { + EventHandler handler = HideSelectionChanged; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxModifiedChanged(object sender, EventArgs e) + { + this.OnModifiedChanged(e); + } + /// + /// Occurs when the value of the Modified property changes. + /// + [Description("Occurs when the value of the Modified property changes.")] + public event EventHandler ModifiedChanged; + /// + /// Raises ModifiedChanged event. + /// + /// Provides event arguments. + protected virtual void OnModifiedChanged(EventArgs e) + { + EventHandler handler = ModifiedChanged; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxMultilineChanged(object sender, EventArgs e) + { + this.OnMultilineChanged(e); + } + /// + /// Occurs when the value of the Multiline property changes. + /// + [Description("Occurs when the value of the Multiline property changes.")] + public event EventHandler MultilineChanged; + /// + /// Raises MultilineChanged event. + /// + /// Provides event arguments. + protected virtual void OnMultilineChanged(EventArgs e) + { + EventHandler handler = MultilineChanged; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxReadOnlyChanged(object sender, EventArgs e) + { + this.OnReadOnlyChanged(e); + } + /// + /// Occurs when the value of the ReadOnly property changes. + /// + [Description("Occurs when the value of the ReadOnly property changes.")] + public event EventHandler ReadOnlyChanged; + /// + /// Raises ReadOnlyChanged event. + /// + /// Provides event arguments. + protected virtual void OnReadOnlyChanged(EventArgs e) + { + EventHandler handler = ReadOnlyChanged; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxGotFocus(object sender, EventArgs e) + { + this.OnGotFocus(e); + } + private void OnRichTextBoxLostFocus(object sender, EventArgs e) + { + this.OnLostFocus(e); + } + private void OnRichTextBoxKeyDown(object sender, KeyEventArgs e) + { + this.OnKeyDown(e); + } + private void OnRichTextBoxKeyUp(object sender, KeyEventArgs e) + { + this.OnKeyUp(e); + } + private void OnRichTextBoxKeyPress(object sender, KeyPressEventArgs e) + { + this.OnKeyPress(e); + } + private void OnRichTextBoxPreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + this.OnPreviewKeyDown(e); + } + private void OnRichTextBoxLinkClicked(object sender, LinkClickedEventArgs e) + { + this.OnLinkClicked(e); + } + /// + /// Occurs when a hyperlink in the text is clicked. + /// + [Description("Occurs when a hyperlink in the text is clicked."), Category("Behavior")] + public event LinkClickedEventHandler LinkClicked; + /// + /// Raises LinkClicked event. + /// + /// Provides event arguments. + protected virtual void OnLinkClicked(LinkClickedEventArgs e) + { + LinkClickedEventHandler handler = LinkClicked; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxProtected(object sender, EventArgs e) + { + this.OnProtected(e); + } + /// + /// Occurs when the user takes an action that would change a protected range of text. + /// + [Category("Behavior"), Description("Occurs when the user takes an action that would change a protected range of text.")] + public event EventHandler Protected; + /// + /// Raises Protected event. + /// + /// Provides event arguments. + protected virtual void OnProtected(EventArgs e) + { + EventHandler handler = Protected; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxSelectionChanged(object sender, EventArgs e) + { + this.OnSelectionChanged(e); + } + /// + /// Occurs when the current selection has changed. + /// + [Category("Behavior"), Description("Occurs when the current selection has changed.")] + public event EventHandler SelectionChanged; + /// + /// Raises SelectionChanged event. + /// + /// Provides event arguments. + protected virtual void OnSelectionChanged(EventArgs e) + { + EventHandler handler = SelectionChanged; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxHScroll(object sender, EventArgs e) + { + this.OnHScroll(e); + } + /// + /// Occurs when the horizontal scroll bar is clicked. + /// + [Description("Occurs when the horizontal scroll bar is clicked."), Category("Behavior")] + public event EventHandler HScroll; + /// + /// Raises HScroll event. + /// + /// Provides event arguments. + protected virtual void OnHScroll(EventArgs e) + { + EventHandler handler = HScroll; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxVScroll(object sender, EventArgs e) + { + this.OnVScroll(e); + } + /// + /// Occurs when the vertical scroll bar is clicked. + /// + [Description("Occurs when the vertical scroll bar is clicked."), Category("Behavior")] + public event EventHandler VScroll; + /// + /// Raises HScroll event. + /// + /// Provides event arguments. + protected virtual void OnVScroll(EventArgs e) + { + EventHandler handler = VScroll; + if (handler != null) + handler(this, e); + } + private void OnRichTextBoxValidating(object sender, CancelEventArgs e) + { + this.OnValidating(e); + } + private void OnRichTextBoxValidated(object sender, EventArgs e) + { + this.OnValidated(e); + } + + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting."), Browsable(false)] + public override bool AntiAlias + { + get { return base.AntiAlias; } + set { base.AntiAlias = value; } + } + + protected override void OnForeColorChanged(EventArgs e) + { + _RichTextBox.ForeColor = this.ForeColor; + base.OnForeColorChanged(e); + } + + //protected override void OnBackColorChanged(EventArgs e) + //{ + // _RichTextBox.BackColor = this.BackColor; + // base.OnBackColorChanged(e); + //} + + private Color _BackColorRichTextBox = SystemColors.Window; + /// + /// Gets or sets the back color of the RichTextBox. + /// + [Category("Columns"), Description("Indicates back color of RichTextBox.")] + public Color BackColorRichTextBox + { + get { return _BackColorRichTextBox; } + set { _BackColorRichTextBox = value; _RichTextBox.BackColor = value; } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColorRichTextBox() + { + return !_BackColorRichTextBox.Equals(SystemColors.Window); + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackColorRichTextBox() + { + this.BackColorRichTextBox = SystemColors.Window; + } + #endregion + + #region RichTextBox Forwarding + private BorderStyle _BorderStyle; + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public BorderStyle BorderStyle + { + get { return _BorderStyle; } + set { _BorderStyle = value; } + } + /// + /// Appends text to the current text of a text box + /// + public void AppendText(string text) + { + _RichTextBox.AppendText(text); + UpdateScrollBarsDelayed(); + } + /// + /// Determines whether you can paste information from the Clipboard in the specified data format. + /// + /// + /// + public bool CanPaste(DataFormats.Format clipFormat) + { + return _RichTextBox.CanPaste(clipFormat); + } + /// + /// Clears all text from the text box control. + /// + public void Clear() + { + _RichTextBox.Clear(); + UpdateScrollBarsDelayed(); + } + /// + /// Clears information about the most recent operation from the undo buffer of the text box. + /// + public void ClearUndo() + { + _RichTextBox.ClearUndo(); + UpdateScrollBarsDelayed(); + } + /// + /// Copies the current selection in the text box to the Clipboard. + /// + public void Copy() + { + _RichTextBox.Copy(); + } + /// + /// Moves the current selection in the text box to the Clipboard. + /// + public void Cut() + { + _RichTextBox.Cut(); + UpdateScrollBarsDelayed(); + } + /// + /// Specifies that the value of the SelectionLength property is zero so that no characters are selected in the control. + /// + public void DeselectAll() + { + _RichTextBox.DeselectAll(); + } + /// + /// Searches the text in a RichTextBox control for a string. + /// + /// + /// + public int Find(string str) + { + return _RichTextBox.Find(str); + } + /// + /// Searches the text of a RichTextBox control for the first instance of a character from a list of characters. + /// + /// + /// + public int Find(char[] characterSet) + { + return _RichTextBox.Find(characterSet); + } + /// + /// Searches the text in a RichTextBox control for a string with specific options applied to the search. + /// + /// + /// + /// + public int Find(string str, RichTextBoxFinds options) + { + return _RichTextBox.Find(str, options); + } + /// + /// Searches the text of a RichTextBox control, at a specific starting point, for the first instance of a character from a list of characters. + /// + /// + /// + /// + public int Find(char[] characterSet, int start) + { + return _RichTextBox.Find(characterSet, start); + } + /// + /// Searches the text in a RichTextBox control for a string at a specific location within the control and with specific options applied to the search. + /// + /// + /// + /// + /// + public int Find(string str, int start, RichTextBoxFinds options) + { + return _RichTextBox.Find(str, start, options); + } + /// + /// Searches a range of text in a RichTextBox control for the first instance of a character from a list of characters. + /// + /// + /// + /// + /// + public int Find(char[] characterSet, int start, int end) + { + return _RichTextBox.Find(characterSet, start, end); + } + /// + /// Searches the text in a RichTextBox control for a string within a range of text within the control and with specific options applied to the search. + /// + /// + /// + /// + /// + /// + public int Find(string str, int start, int end, RichTextBoxFinds options) + { + return _RichTextBox.Find(str, start, end, options); + } + public bool Focus() + { + return ((this.RichTextBox != null) && this.RichTextBox.Focus()); + } + /// + /// Retrieves the character that is closest to the specified location within the control. + /// + /// + /// + public int GetCharFromPosition(Point pt) + { + return _RichTextBox.GetCharFromPosition(pt); + } + /// + /// Retrieves the index of the character nearest to the specified location + /// + /// + /// + public int GetCharIndexFromPosition(Point pt) + { + return _RichTextBox.GetCharIndexFromPosition(pt); + } + /// + /// Retrieves the index of the first character of a given line. (Inherited from TextBoxBase.) + /// + /// + /// + public int GetFirstCharIndexFromLine(int lineNumber) + { + return _RichTextBox.GetFirstCharIndexFromLine(lineNumber); + } + /// + /// Retrieves the index of the first character of the current line. (Inherited from TextBoxBase.) + /// + /// + public int GetFirstCharIndexOfCurrentLine() + { + return _RichTextBox.GetFirstCharIndexOfCurrentLine(); + } + /// + /// Retrieves the line number from the specified character position within the text of the RichTextBox control. + /// + /// + /// + public int GetLineFromCharIndex(int index) + { + return _RichTextBox.GetLineFromCharIndex(index); + } + /// + /// Retrieves the location within the control at the specified character index. + /// + /// + /// + public Point GetPositionFromCharIndex(int index) + { + return _RichTextBox.GetPositionFromCharIndex(index); + } + /// + /// Loads a rich text format (RTF) or standard ASCII text file into the RichTextBox control. + /// + /// + public void LoadFile(string path) + { + _RichTextBox.LoadFile(path); + UpdateScrollBarsDelayed(); + } + /// + /// Loads the contents of an existing data stream into the RichTextBox control. + /// + /// + /// + public void LoadFile(Stream data, RichTextBoxStreamType fileType) + { + _RichTextBox.LoadFile(data, fileType); + UpdateScrollBarsDelayed(); + } + /// + /// Loads a specific type of file into the RichTextBox control. + /// + /// + /// + public void LoadFile(string path, RichTextBoxStreamType fileType) + { + _RichTextBox.LoadFile(path, fileType); + UpdateScrollBarsDelayed(); + } + /// + /// Replaces the current selection in the text box with the contents of the Clipboard. + /// + public void Paste() + { + _RichTextBox.Paste(); + UpdateScrollBarsDelayed(); + } + /// + /// Pastes the contents of the Clipboard in the specified Clipboard format. + /// + /// + public void Paste(DataFormats.Format clipFormat) + { + _RichTextBox.Paste(clipFormat); + UpdateScrollBarsDelayed(); + } + /// + /// Reapplies the last operation that was undone in the control. + /// + public void Redo() + { + _RichTextBox.Redo(); + UpdateScrollBarsDelayed(); + } + /// + /// Saves the contents of the RichTextBox to a rich text format (RTF) file. + /// + /// + public void SaveFile(string path) + { + _RichTextBox.SaveFile(path); + } + /// + /// Saves the contents of a RichTextBox control to an open data stream. + /// + /// + /// + public void SaveFile(Stream data, RichTextBoxStreamType fileType) + { + _RichTextBox.SaveFile(data, fileType); + } + /// + /// Saves the contents of the RichTextBox to a specific type of file. + /// + /// + /// + public void SaveFile(string path, RichTextBoxStreamType fileType) + { + _RichTextBox.SaveFile(path, fileType); + } + /// + /// Scrolls the contents of the control to the current caret position. + /// + public void ScrollToCaret() + { + _RichTextBox.ScrollToCaret(); + } + /// + /// Activates the control. (Inherited from Control.) + /// + public void Select() + { + _RichTextBox.Select(); + } + /// + /// Selects a range of text in the text box. + /// + /// + /// + public void Select(int start, int length) + { + _RichTextBox.Select(start, length); + } + /// + /// Selects all text in the text box. + /// + public void SelectAll() + { + _RichTextBox.SelectAll(); + } + /// + /// Undoes the last edit operation in the text box. + /// + public void Undo() + { + _RichTextBox.Undo(); + UpdateScrollBarsDelayed(); + } + + /// + /// Gets or sets whether tab characters are accepted as input + /// + [DefaultValue(false), Description("Indicates whether tab characters are accepted as input."), Category("Behavior")] + public bool AcceptsTab + { + get + { + return _RichTextBox.AcceptsTab; + } + set + { + _RichTextBox.AcceptsTab = value; + } + } + [Browsable(false)] + public override bool AllowDrop + { + get + { + return base.AllowDrop; + } + set + { + base.AllowDrop = value; + } + } + /// + /// Gets or sets whether automatic word selection is enabled. + /// + [Category("Behavior"), DefaultValue(false), Description("Indicates whether automatic word selection is enabled.")] + public bool AutoWordSelection + { + get + { + return _RichTextBox.AutoWordSelection; + } + set + { + _RichTextBox.AutoWordSelection = value; + } + } + [Bindable(false), Browsable(false)] + public override Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + /// + /// Gets or sets indent for bullets in the control. + /// + [DefaultValue(0), Category("Behavior"), Description("Indicates the indent for bullets in the control."), Localizable(true)] + public int BulletIndent + { + get + { + return _RichTextBox.BulletIndent; + } + set + { + _RichTextBox.BulletIndent = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool CanRedo + { + get + { + return _RichTextBox.CanRedo; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool CanUndo + { + get + { + return _RichTextBox.CanUndo; + } + } + public override ContextMenuStrip ContextMenuStrip + { + get + { + return base.ContextMenuStrip; + } + set + { + base.ContextMenuStrip = value; + _RichTextBox.ContextMenuStrip = value; + } + } + protected override Size DefaultSize + { + get + { + return new Size(100, 100); + } + } + /// + /// Gets or sets whether URLs are automatically formatted as links. + /// + [Category("Behavior"), DefaultValue(true), Description("Indicates whether URLs are automatically formatted as links.")] + public bool DetectUrls + { + get + { + return _RichTextBox.DetectUrls; + } + set + { + _RichTextBox.DetectUrls = value; + } + } + /// + /// Gets or sets whether drag/drop of text, pictures and other data is enabled. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether drag/drop of text, pictures and other data is enabled.")] + public bool EnableAutoDragDrop + { + get + { + return _RichTextBox.EnableAutoDragDrop; + } + set + { + _RichTextBox.EnableAutoDragDrop = value; + } + } + [Browsable(false)] + public override bool Focused + { + get + { + return _RichTextBox.Focused; + } + } + /// + /// Gets or sets whether selection should be hidden when the edit control loses focus. + /// + [Description("Indicates whether selection should be hidden when the edit control loses focus."), Category("Behavior"), DefaultValue(true)] + public bool HideSelection + { + get + { + return _RichTextBox.HideSelection; + } + set + { + _RichTextBox.HideSelection = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public RichTextBoxLanguageOptions LanguageOption + { + get + { + return _RichTextBox.LanguageOption; + } + set + { + _RichTextBox.LanguageOption = value; + } + } + /// + /// Gets or sets lines of text in a multi-line edit, as an array of String values. + /// + [Editor("System.Windows.Forms.Design.StringArrayEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor)), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), MergableProperty(false), Localizable(true), Category("Appearance"), Description("Indicates lines of text in a multi-line edit, as an array of String values.")] + public string[] Lines + { + get + { + return _RichTextBox.Lines; + } + set + { + _RichTextBox.Lines = value; + } + } + /// + /// Gets or sets maximum number of characters that can be entered into the edit control. + /// + [Localizable(true), Category("Behavior"), Description("Indicates maximum number of characters that can be entered into the edit control."), DefaultValue(0x7fffffff)] + public int MaxLength + { + get + { + return _RichTextBox.MaxLength; + } + set + { + _RichTextBox.MaxLength = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool Modified + { + get + { + return _RichTextBox.Modified; + } + } + /// + /// Gets or sets whether the text in the control can span more than one line. + /// + [RefreshProperties(RefreshProperties.All), Description("Indicates whether the text in the control can span more than one line."), DefaultValue(true), Localizable(true), Category("Behavior")] + public bool Multiline + { + get + { + return _RichTextBox.Multiline; + } + set + { + _RichTextBox.Multiline = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public new System.Windows.Forms.Padding Padding + { + get + { + return base.Padding; + } + set + { + base.Padding = value; + } + } + /// + /// Gets or sets whether the text in the edit control can be changed or not. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether the text in the edit control can be changed or not."), RefreshProperties(RefreshProperties.Repaint)] + public bool ReadOnly + { + get + { + return _RichTextBox.ReadOnly; + } + set + { + _RichTextBox.ReadOnly = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public string RedoActionName + { + get + { + return _RichTextBox.RedoActionName; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false), DefaultValue(true)] + public bool RichTextShortcutsEnabled + { + get + { + return _RichTextBox.RichTextShortcutsEnabled; + } + set + { + _RichTextBox.RichTextShortcutsEnabled = value; + } + } + + /// + /// Gets or sets right margin dimensions. + /// + [Description("Indicates the right margin dimensions."), Localizable(true), Category("Behavior"), DefaultValue(0)] + public int RightMargin + { + get + { + return _RichTextBox.RightMargin; + } + set + { + _RichTextBox.RightMargin = value; + } + } + /// + /// Gets or sets the text of the RichTextBox control, including all rich text format (RTF) codes. + /// + [Bindable(true), RefreshProperties(RefreshProperties.All), SettingsBindable(true), DefaultValue(""), Category("Appearance"), Description("Gets or sets the text of the RichTextBox control, including all rich text format (RTF) codes.")] + public string Rtf + { + get + { + return _RichTextBox.Rtf; + } + set + { + _RichTextBox.Rtf = value; + UpdateScrollBarsDelayed(); + } + } + /// + /// Gets or sets for multi-line edit control, which scroll bars will be shown. + /// + [Localizable(true), Description("Indicates, for multi-line edit control, which scroll bars will be shown."), DefaultValue(typeof(RichTextBoxScrollBars), "Both"), Category("Appearance")] + public RichTextBoxScrollBars ScrollBars + { + get + { + return _RichTextBox.ScrollBars; + } + set + { + _RichTextBox.ScrollBars = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), DefaultValue("")] + public string SelectedRtf + { + get + { + return _RichTextBox.SelectedRtf; + } + set + { + _RichTextBox.SelectedRtf = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public string SelectedText + { + get + { + return _RichTextBox.SelectedText; + } + set + { + _RichTextBox.SelectedText = value; + } + } + [DefaultValue(typeof(HorizontalAlignment), "Left"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public HorizontalAlignment SelectionAlignment + { + get + { + return _RichTextBox.SelectionAlignment; + } + set + { + _RichTextBox.SelectionAlignment = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public Color SelectionBackColor + { + get + { + return _RichTextBox.SelectionBackColor; + } + set + { + _RichTextBox.SelectionBackColor = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public bool SelectionBullet + { + get + { + return _RichTextBox.SelectionBullet; + } + set + { + _RichTextBox.SelectionBullet = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectionCharOffset + { + get + { + return _RichTextBox.SelectionCharOffset; + } + set + { + _RichTextBox.SelectionCharOffset = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color SelectionColor + { + get + { + return _RichTextBox.SelectionColor; + } + set + { + _RichTextBox.SelectionColor = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public Font SelectionFont + { + get + { + return _RichTextBox.SelectionFont; + } + set + { + _RichTextBox.SelectionFont = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public int SelectionHangingIndent + { + get + { + return _RichTextBox.SelectionHangingIndent; + } + set + { + _RichTextBox.SelectionHangingIndent = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public int SelectionIndent + { + get + { + return _RichTextBox.SelectionIndent; + } + set + { + _RichTextBox.SelectionIndent = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public int SelectionLength + { + get + { + return _RichTextBox.SelectionLength; + } + set + { + _RichTextBox.SelectionLength = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public int SelectionProtected + { + get + { + return _RichTextBox.SelectionLength; + } + set + { + _RichTextBox.SelectionLength = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectionRightIndent + { + get + { + return _RichTextBox.SelectionRightIndent; + } + set + { + _RichTextBox.SelectionRightIndent = value; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public int SelectionStart + { + get + { + return _RichTextBox.SelectionStart; + } + set + { + _RichTextBox.SelectionStart = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int[] SelectionTabs + { + get + { + return _RichTextBox.SelectionTabs; + } + set + { + _RichTextBox.SelectionTabs = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public RichTextBoxSelectionTypes SelectionType + { + get + { + return _RichTextBox.SelectionType; + } + } + /// + /// Gets or sets whether shortcuts defined for the control are enabled. + /// + [DefaultValue(true), Description("Indicates whether shortcuts defined for the control are enabled."), Category("Behavior")] + public bool ShortcutsEnabled + { + get + { + return _RichTextBox.ShortcutsEnabled; + } + set + { + _RichTextBox.ShortcutsEnabled = value; + } + } + /// + /// Gets or sets whether selection margin is visible. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether selection margin is visible.")] + public bool ShowSelectionMargin + { + get + { + return _RichTextBox.ShowSelectionMargin; + } + set + { + _RichTextBox.ShowSelectionMargin = value; + } + } + public new bool TabStop + { + get + { + return _RichTextBox.TabStop; + } + set + { + _RichTextBox.TabStop = value; + } + } + [Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))] + public override string Text + { + get + { + return _RichTextBox.Text; + } + set + { + _RichTextBox.Text = value; + UpdateScrollBarsDelayed(); + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public int TextLength + { + get + { + return _RichTextBox.TextLength; + } + } + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public string UndoActionName + { + get + { + return _RichTextBox.UndoActionName; + } + } + /// + /// Gets or sets whether lines are automatically word-wrapped. + /// + [DefaultValue(true), Description("Indicates whether lines are automatically word-wrapped."), Localizable(true), Category("Behavior")] + public bool WordWrap + { + get + { + return _RichTextBox.WordWrap; + } + set + { + _RichTextBox.WordWrap = value; + } + } + /// + /// Gets or sets current zoom factor for the control content. + /// + [Localizable(true), DefaultValue((float)1f), Category("Behavior"), Description("Indicates current zoom factor for the control content.")] + public float ZoomFactor + { + get + { + return _RichTextBox.ZoomFactor; + } + set + { + _RichTextBox.ZoomFactor = value; + } + } + + public override ContextMenu ContextMenu + { + get + { + return _RichTextBox.ContextMenu; + } + set + { + _RichTextBox.ContextMenu = value; + } + } + + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/RichTextBoxEx.ico b/PROMS/DotNetBar Source Code/Controls/RichTextBoxEx.ico new file mode 100644 index 00000000..0f0a6962 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/RichTextBoxEx.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/RichTextBoxScrollEx.cs b/PROMS/DotNetBar Source Code/Controls/RichTextBoxScrollEx.cs new file mode 100644 index 00000000..b7085426 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/RichTextBoxScrollEx.cs @@ -0,0 +1,1019 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar.Controls +{ + internal class RichTextBoxScrollEx : RichTextBox, IScrollBarOverrideSupport + { + #region Internal Implementation + protected override void WndProc(ref Message m) + { + //Console.WriteLine("{0} Message {1}", DateTime.Now, MapMessage(m.Msg)); + if (m.Msg == (int)WinApi.WindowsMessages.WM_VSCROLL || m.Msg == (int)WinApi.WindowsMessages.WM_HSCROLL || m.Msg == (int)WinApi.WindowsMessages.WM_MOUSEWHEEL) + { + base.WndProc(ref m); + OnScrollBarValueChanged(new ScrollValueChangedEventArgs(ScrollbarControl.MapMessageToScrollChange(m.Msg))); + return; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_NCCALCSIZE) + { + base.WndProc(ref m); + OnNonClientSizeChanged(EventArgs.Empty); + return; + } + else if (m.Msg == 206 || m.Msg == 8270) // Internal RichTextBox message we use to trigger scroll-bar update + { + base.WndProc(ref m); + OnScrollBarValueChanged(new ScrollValueChangedEventArgs(eScrollBarScrollChange.Horizontal | eScrollBarScrollChange.Vertical)); + return; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_MOVE) // Internal RichTextBox message we use to trigger scroll-bar update + { + base.WndProc(ref m); + OnControlMoved(EventArgs.Empty); + return; + } + base.WndProc(ref m); + } + + + //private static Array _EnumValues = Enum.GetValues(typeof(WM)); + //private object MapMessage(int msg) + //{ + // foreach (object item in _EnumValues) + // { + // if (item != null && (uint)item == msg) + // return item.ToString(); + // } + // return msg; + //} + #endregion + #region IScrollBarOverrideSupport Members + public event EventHandler NonClientSizeChanged; + /// + /// Raises NonClientSizeChanged event. + /// + /// Provides event arguments. + protected virtual void OnNonClientSizeChanged(EventArgs e) + { + EventHandler handler = NonClientSizeChanged; + if (handler != null) + handler(this, e); + } + + public event ScrollValueChangedHandler ScrollBarValueChanged; + /// + /// Raises ScrollBarValueChanged event. + /// + /// Provides event arguments. + protected virtual void OnScrollBarValueChanged(ScrollValueChangedEventArgs e) + { + ScrollValueChangedHandler handler = ScrollBarValueChanged; + if (handler != null) + handler(this, e); + } + + public event EventHandler ControlMoved; + /// + /// Raises NonClientSizeChanged event. + /// + /// Provides event arguments. + protected virtual void OnControlMoved(EventArgs e) + { + EventHandler handler = ControlMoved; + if (handler != null) + handler(this, e); + } + bool IScrollBarOverrideSupport.DesignMode + { + get + { + return this.DesignMode; + } + } + #endregion + } + + ///// + ///// Windows Messages + ///// Defined in winuser.h from Windows SDK v6.1 + ///// Documentation pulled from MSDN. + ///// + //public enum WM : uint + //{ + // /// + // /// The WM_NULL message performs no operation. An application sends the WM_NULL message if it wants to post a message that the recipient window will ignore. + // /// + // NULL = 0x0000, + // /// + // /// The WM_CREATE message is sent when an application requests that a window be created by calling the CreateWindowEx or CreateWindow function. (The message is sent before the function returns.) The window procedure of the new window receives this message after the window is created, but before the window becomes visible. + // /// + // CREATE = 0x0001, + // /// + // /// The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window procedure of the window being destroyed after the window is removed from the screen. + // /// This message is sent first to the window being destroyed and then to the child windows (if any) as they are destroyed. During the processing of the message, it can be assumed that all child windows still exist. + // /// /// + // DESTROY = 0x0002, + // /// + // /// The WM_MOVE message is sent after a window has been moved. + // /// + // MOVE = 0x0003, + // /// + // /// The WM_SIZE message is sent to a window after its size has changed. + // /// + // SIZE = 0x0005, + // /// + // /// The WM_ACTIVATE message is sent to both the window being activated and the window being deactivated. If the windows use the same input queue, the message is sent synchronously, first to the window procedure of the top-level window being deactivated, then to the window procedure of the top-level window being activated. If the windows use different input queues, the message is sent asynchronously, so the window is activated immediately. + // /// + // ACTIVATE = 0x0006, + // /// + // /// The WM_SETFOCUS message is sent to a window after it has gained the keyboard focus. + // /// + // SETFOCUS = 0x0007, + // /// + // /// The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus. + // /// + // KILLFOCUS = 0x0008, + // /// + // /// The WM_ENABLE message is sent when an application changes the enabled state of a window. It is sent to the window whose enabled state is changing. This message is sent before the EnableWindow function returns, but after the enabled state (WS_DISABLED style bit) of the window has changed. + // /// + // ENABLE = 0x000A, + // /// + // /// An application sends the WM_SETREDRAW message to a window to allow changes in that window to be redrawn or to prevent changes in that window from being redrawn. + // /// + // SETREDRAW = 0x000B, + // /// + // /// An application sends a WM_SETTEXT message to set the text of a window. + // /// + // SETTEXT = 0x000C, + // /// + // /// An application sends a WM_GETTEXT message to copy the text that corresponds to a window into a buffer provided by the caller. + // /// + // GETTEXT = 0x000D, + // /// + // /// An application sends a WM_GETTEXTLENGTH message to determine the length, in characters, of the text associated with a window. + // /// + // GETTEXTLENGTH = 0x000E, + // /// + // /// The WM_PAINT message is sent when the system or another application makes a request to paint a portion of an application's window. The message is sent when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage function when the application obtains a WM_PAINT message by using the GetMessage or PeekMessage function. + // /// + // PAINT = 0x000F, + // /// + // /// The WM_CLOSE message is sent as a signal that a window or an application should terminate. + // /// + // CLOSE = 0x0010, + // /// + // /// The WM_QUERYENDSESSION message is sent when the user chooses to end the session or when an application calls one of the system shutdown functions. If any application returns zero, the session is not ended. The system stops sending WM_QUERYENDSESSION messages as soon as one application returns zero. + // /// After processing this message, the system sends the WM_ENDSESSION message with the wParam parameter set to the results of the WM_QUERYENDSESSION message. + // /// + // QUERYENDSESSION = 0x0011, + // /// + // /// The WM_QUERYOPEN message is sent to an icon when the user requests that the window be restored to its previous size and position. + // /// + // QUERYOPEN = 0x0013, + // /// + // /// The WM_ENDSESSION message is sent to an application after the system processes the results of the WM_QUERYENDSESSION message. The WM_ENDSESSION message informs the application whether the session is ending. + // /// + // ENDSESSION = 0x0016, + // /// + // /// The WM_QUIT message indicates a request to terminate an application and is generated when the application calls the PostQuitMessage function. It causes the GetMessage function to return zero. + // /// + // QUIT = 0x0012, + // /// + // /// The WM_ERASEBKGND message is sent when the window background must be erased (for example, when a window is resized). The message is sent to prepare an invalidated portion of a window for painting. + // /// + // ERASEBKGND = 0x0014, + // /// + // /// This message is sent to all top-level windows when a change is made to a system color setting. + // /// + // SYSCOLORCHANGE = 0x0015, + // /// + // /// The WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown. + // /// + // SHOWWINDOW = 0x0018, + // /// + // /// An application sends the WM_WININICHANGE message to all top-level windows after making a change to the WIN.INI file. The SystemParametersInfo function sends this message after an application uses the function to change a setting in WIN.INI. + // /// Note The WM_WININICHANGE message is provided only for compatibility with earlier versions of the system. Applications should use the WM_SETTINGCHANGE message. + // /// + // WININICHANGE = 0x001A, + // /// + // /// An application sends the WM_WININICHANGE message to all top-level windows after making a change to the WIN.INI file. The SystemParametersInfo function sends this message after an application uses the function to change a setting in WIN.INI. + // /// Note The WM_WININICHANGE message is provided only for compatibility with earlier versions of the system. Applications should use the WM_SETTINGCHANGE message. + // /// + // SETTINGCHANGE = WM.WININICHANGE, + // /// + // /// The WM_DEVMODECHANGE message is sent to all top-level windows whenever the user changes device-mode settings. + // /// + // DEVMODECHANGE = 0x001B, + // /// + // /// The WM_ACTIVATEAPP message is sent when a window belonging to a different application than the active window is about to be activated. The message is sent to the application whose window is being activated and to the application whose window is being deactivated. + // /// + // ACTIVATEAPP = 0x001C, + // /// + // /// An application sends the WM_FONTCHANGE message to all top-level windows in the system after changing the pool of font resources. + // /// + // FONTCHANGE = 0x001D, + // /// + // /// A message that is sent whenever there is a change in the system time. + // /// + // TIMECHANGE = 0x001E, + // /// + // /// The WM_CANCELMODE message is sent to cancel certain modes, such as mouse capture. For example, the system sends this message to the active window when a dialog box or message box is displayed. Certain functions also send this message explicitly to the specified window regardless of whether it is the active window. For example, the EnableWindow function sends this message when disabling the specified window. + // /// + // CANCELMODE = 0x001F, + // /// + // /// The WM_SETCURSOR message is sent to a window if the mouse causes the cursor to move within a window and mouse input is not captured. + // /// + // SETCURSOR = 0x0020, + // /// + // /// The WM_MOUSEACTIVATE message is sent when the cursor is in an inactive window and the user presses a mouse button. The parent window receives this message only if the child window passes it to the DefWindowProc function. + // /// + // MOUSEACTIVATE = 0x0021, + // /// + // /// The WM_CHILDACTIVATE message is sent to a child window when the user clicks the window's title bar or when the window is activated, moved, or sized. + // /// + // CHILDACTIVATE = 0x0022, + // /// + // /// The WM_QUEUESYNC message is sent by a computer-based training (CBT) application to separate user-input messages from other messages sent through the WH_JOURNALPLAYBACK Hook procedure. + // /// + // QUEUESYNC = 0x0023, + // /// + // /// The WM_GETMINMAXINFO message is sent to a window when the size or position of the window is about to change. An application can use this message to override the window's default maximized size and position, or its default minimum or maximum tracking size. + // /// + // GETMINMAXINFO = 0x0024, + // /// + // /// Windows NT 3.51 and earlier: The WM_PAINTICON message is sent to a minimized window when the icon is to be painted. This message is not sent by newer versions of Microsoft Windows, except in unusual circumstances explained in the Remarks. + // /// + // PAINTICON = 0x0026, + // /// + // /// Windows NT 3.51 and earlier: The WM_ICONERASEBKGND message is sent to a minimized window when the background of the icon must be filled before painting the icon. A window receives this message only if a class icon is defined for the window; otherwise, WM_ERASEBKGND is sent. This message is not sent by newer versions of Windows. + // /// + // ICONERASEBKGND = 0x0027, + // /// + // /// The WM_NEXTDLGCTL message is sent to a dialog box procedure to set the keyboard focus to a different control in the dialog box. + // /// + // NEXTDLGCTL = 0x0028, + // /// + // /// The WM_SPOOLERSTATUS message is sent from Print Manager whenever a job is added to or removed from the Print Manager queue. + // /// + // SPOOLERSTATUS = 0x002A, + // /// + // /// The WM_DRAWITEM message is sent to the parent window of an owner-drawn button, combo box, list box, or menu when a visual aspect of the button, combo box, list box, or menu has changed. + // /// + // DRAWITEM = 0x002B, + // /// + // /// The WM_MEASUREITEM message is sent to the owner window of a combo box, list box, list view control, or menu item when the control or menu is created. + // /// + // MEASUREITEM = 0x002C, + // /// + // /// Sent to the owner of a list box or combo box when the list box or combo box is destroyed or when items are removed by the LB_DELETESTRING, LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT message. The system sends a WM_DELETEITEM message for each deleted item. The system sends the WM_DELETEITEM message for any deleted list box or combo box item with nonzero item data. + // /// + // DELETEITEM = 0x002D, + // /// + // /// Sent by a list box with the LBS_WANTKEYBOARDINPUT style to its owner in response to a WM_KEYDOWN message. + // /// + // VKEYTOITEM = 0x002E, + // /// + // /// Sent by a list box with the LBS_WANTKEYBOARDINPUT style to its owner in response to a WM_CHAR message. + // /// + // CHARTOITEM = 0x002F, + // /// + // /// An application sends a WM_SETFONT message to specify the font that a control is to use when drawing text. + // /// + // SETFONT = 0x0030, + // /// + // /// An application sends a WM_GETFONT message to a control to retrieve the font with which the control is currently drawing its text. + // /// + // GETFONT = 0x0031, + // /// + // /// An application sends a WM_SETHOTKEY message to a window to associate a hot key with the window. When the user presses the hot key, the system activates the window. + // /// + // SETHOTKEY = 0x0032, + // /// + // /// An application sends a WM_GETHOTKEY message to determine the hot key associated with a window. + // /// + // GETHOTKEY = 0x0033, + // /// + // /// The WM_QUERYDRAGICON message is sent to a minimized (iconic) window. The window is about to be dragged by the user but does not have an icon defined for its class. An application can return a handle to an icon or cursor. The system displays this cursor or icon while the user drags the icon. + // /// + // QUERYDRAGICON = 0x0037, + // /// + // /// The system sends the WM_COMPAREITEM message to determine the relative position of a new item in the sorted list of an owner-drawn combo box or list box. Whenever the application adds a new item, the system sends this message to the owner of a combo box or list box created with the CBS_SORT or LBS_SORT style. + // /// + // COMPAREITEM = 0x0039, + // /// + // /// Active Accessibility sends the WM_GETOBJECT message to obtain information about an accessible object contained in a server application. + // /// Applications never send this message directly. It is sent only by Active Accessibility in response to calls to AccessibleObjectFromPoint, AccessibleObjectFromEvent, or AccessibleObjectFromWindow. However, server applications handle this message. + // /// + // GETOBJECT = 0x003D, + // /// + // /// The WM_COMPACTING message is sent to all top-level windows when the system detects more than 12.5 percent of system time over a 30- to 60-second interval is being spent compacting memory. This indicates that system memory is low. + // /// + // COMPACTING = 0x0041, + // /// + // /// WM_COMMNOTIFY is Obsolete for Win32-Based Applications + // /// + // [Obsolete] + // COMMNOTIFY = 0x0044, + // /// + // /// The WM_WINDOWPOSCHANGING message is sent to a window whose size, position, or place in the Z order is about to change as a result of a call to the SetWindowPos function or another window-management function. + // /// + // WINDOWPOSCHANGING = 0x0046, + // /// + // /// The WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place in the Z order has changed as a result of a call to the SetWindowPos function or another window-management function. + // /// + // WINDOWPOSCHANGED = 0x0047, + // /// + // /// Notifies applications that the system, typically a battery-powered personal computer, is about to enter a suspended mode. + // /// Use: POWERBROADCAST + // /// + // [Obsolete] + // POWER = 0x0048, + // /// + // /// An application sends the WM_COPYDATA message to pass data to another application. + // /// + // COPYDATA = 0x004A, + // /// + // /// The WM_CANCELJOURNAL message is posted to an application when a user cancels the application's journaling activities. The message is posted with a NULL window handle. + // /// + // CANCELJOURNAL = 0x004B, + // /// + // /// Sent by a common control to its parent window when an event has occurred or the control requires some information. + // /// + // NOTIFY = 0x004E, + // /// + // /// The WM_INPUTLANGCHANGEREQUEST message is posted to the window with the focus when the user chooses a new input language, either with the hotkey (specified in the Keyboard control panel application) or from the indicator on the system taskbar. An application can accept the change by passing the message to the DefWindowProc function or reject the change (and prevent it from taking place) by returning immediately. + // /// + // INPUTLANGCHANGEREQUEST = 0x0050, + // /// + // /// The WM_INPUTLANGCHANGE message is sent to the topmost affected window after an application's input language has been changed. You should make any application-specific settings and pass the message to the DefWindowProc function, which passes the message to all first-level child windows. These child windows can pass the message to DefWindowProc to have it pass the message to their child windows, and so on. + // /// + // INPUTLANGCHANGE = 0x0051, + // /// + // /// Sent to an application that has initiated a training card with Microsoft Windows Help. The message informs the application when the user clicks an authorable button. An application initiates a training card by specifying the HELP_TCARD command in a call to the WinHelp function. + // /// + // TCARD = 0x0052, + // /// + // /// Indicates that the user pressed the F1 key. If a menu is active when F1 is pressed, WM_HELP is sent to the window associated with the menu; otherwise, WM_HELP is sent to the window that has the keyboard focus. If no window has the keyboard focus, WM_HELP is sent to the currently active window. + // /// + // HELP = 0x0053, + // /// + // /// The WM_USERCHANGED message is sent to all windows after the user has logged on or off. When the user logs on or off, the system updates the user-specific settings. The system sends this message immediately after updating the settings. + // /// + // USERCHANGED = 0x0054, + // /// + // /// Determines if a window accepts ANSI or Unicode structures in the WM_NOTIFY notification message. WM_NOTIFYFORMAT messages are sent from a common control to its parent window and from the parent window to the common control. + // /// + // NOTIFYFORMAT = 0x0055, + // /// + // /// The WM_CONTEXTMENU message notifies a window that the user clicked the right mouse button (right-clicked) in the window. + // /// + // CONTEXTMENU = 0x007B, + // /// + // /// The WM_STYLECHANGING message is sent to a window when the SetWindowLong function is about to change one or more of the window's styles. + // /// + // STYLECHANGING = 0x007C, + // /// + // /// The WM_STYLECHANGED message is sent to a window after the SetWindowLong function has changed one or more of the window's styles + // /// + // STYLECHANGED = 0x007D, + // /// + // /// The WM_DISPLAYCHANGE message is sent to all windows when the display resolution has changed. + // /// + // DISPLAYCHANGE = 0x007E, + // /// + // /// The WM_GETICON message is sent to a window to retrieve a handle to the large or small icon associated with a window. The system displays the large icon in the ALT+TAB dialog, and the small icon in the window caption. + // /// + // GETICON = 0x007F, + // /// + // /// An application sends the WM_SETICON message to associate a new large or small icon with a window. The system displays the large icon in the ALT+TAB dialog box, and the small icon in the window caption. + // /// + // SETICON = 0x0080, + // /// + // /// The WM_NCCREATE message is sent prior to the WM_CREATE message when a window is first created. + // /// + // NCCREATE = 0x0081, + // /// + // /// The WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY message. WM_DESTROY is used to free the allocated memory object associated with the window. + // /// The WM_NCDESTROY message is sent after the child windows have been destroyed. In contrast, WM_DESTROY is sent before the child windows are destroyed. + // /// + // NCDESTROY = 0x0082, + // /// + // /// The WM_NCCALCSIZE message is sent when the size and position of a window's client area must be calculated. By processing this message, an application can control the content of the window's client area when the size or position of the window changes. + // /// + // NCCALCSIZE = 0x0083, + // /// + // /// The WM_NCHITTEST message is sent to a window when the cursor moves, or when a mouse button is pressed or released. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is sent to the window that has captured the mouse. + // /// + // NCHITTEST = 0x0084, + // /// + // /// The WM_NCPAINT message is sent to a window when its frame must be painted. + // /// + // NCPAINT = 0x0085, + // /// + // /// The WM_NCACTIVATE message is sent to a window when its nonclient area needs to be changed to indicate an active or inactive state. + // /// + // NCACTIVATE = 0x0086, + // /// + // /// The WM_GETDLGCODE message is sent to the window procedure associated with a control. By default, the system handles all keyboard input to the control; the system interprets certain types of keyboard input as dialog box navigation keys. To override this default behavior, the control can respond to the WM_GETDLGCODE message to indicate the types of input it wants to process itself. + // /// + // GETDLGCODE = 0x0087, + // /// + // /// The WM_SYNCPAINT message is used to synchronize painting while avoiding linking independent GUI threads. + // /// + // SYNCPAINT = 0x0088, + // /// + // /// The WM_NCMOUSEMOVE message is posted to a window when the cursor is moved within the nonclient area of the window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCMOUSEMOVE = 0x00A0, + // /// + // /// The WM_NCLBUTTONDOWN message is posted when the user presses the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCLBUTTONDOWN = 0x00A1, + // /// + // /// The WM_NCLBUTTONUP message is posted when the user releases the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCLBUTTONUP = 0x00A2, + // /// + // /// The WM_NCLBUTTONDBLCLK message is posted when the user double-clicks the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCLBUTTONDBLCLK = 0x00A3, + // /// + // /// The WM_NCRBUTTONDOWN message is posted when the user presses the right mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCRBUTTONDOWN = 0x00A4, + // /// + // /// The WM_NCRBUTTONUP message is posted when the user releases the right mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCRBUTTONUP = 0x00A5, + // /// + // /// The WM_NCRBUTTONDBLCLK message is posted when the user double-clicks the right mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCRBUTTONDBLCLK = 0x00A6, + // /// + // /// The WM_NCMBUTTONDOWN message is posted when the user presses the middle mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCMBUTTONDOWN = 0x00A7, + // /// + // /// The WM_NCMBUTTONUP message is posted when the user releases the middle mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCMBUTTONUP = 0x00A8, + // /// + // /// The WM_NCMBUTTONDBLCLK message is posted when the user double-clicks the middle mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCMBUTTONDBLCLK = 0x00A9, + // /// + // /// The WM_NCXBUTTONDOWN message is posted when the user presses the first or second X button while the cursor is in the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCXBUTTONDOWN = 0x00AB, + // /// + // /// The WM_NCXBUTTONUP message is posted when the user releases the first or second X button while the cursor is in the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCXBUTTONUP = 0x00AC, + // /// + // /// The WM_NCXBUTTONDBLCLK message is posted when the user double-clicks the first or second X button while the cursor is in the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. + // /// + // NCXBUTTONDBLCLK = 0x00AD, + // /// + // /// The WM_INPUT_DEVICE_CHANGE message is sent to the window that registered to receive raw input. A window receives this message through its WindowProc function. + // /// + // INPUT_DEVICE_CHANGE = 0x00FE, + // /// + // /// The WM_INPUT message is sent to the window that is getting raw input. + // /// + // INPUT = 0x00FF, + // /// + // /// This message filters for keyboard messages. + // /// + // KEYFIRST = 0x0100, + // /// + // /// The WM_KEYDOWN message is posted to the window with the keyboard focus when a nonsystem key is pressed. A nonsystem key is a key that is pressed when the ALT key is not pressed. + // /// + // KEYDOWN = 0x0100, + // /// + // /// The WM_KEYUP message is posted to the window with the keyboard focus when a nonsystem key is released. A nonsystem key is a key that is pressed when the ALT key is not pressed, or a keyboard key that is pressed when a window has the keyboard focus. + // /// + // KEYUP = 0x0101, + // /// + // /// The WM_CHAR message is posted to the window with the keyboard focus when a WM_KEYDOWN message is translated by the TranslateMessage function. The WM_CHAR message contains the character code of the key that was pressed. + // /// + // CHAR = 0x0102, + // /// + // /// The WM_DEADCHAR message is posted to the window with the keyboard focus when a WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR specifies a character code generated by a dead key. A dead key is a key that generates a character, such as the umlaut (double-dot), that is combined with another character to form a composite character. For example, the umlaut-O character () is generated by typing the dead key for the umlaut character, and then typing the O key. + // /// + // DEADCHAR = 0x0103, + // /// + // /// The WM_SYSKEYDOWN message is posted to the window with the keyboard focus when the user presses the F10 key (which activates the menu bar) or holds down the ALT key and then presses another key. It also occurs when no window currently has the keyboard focus; in this case, the WM_SYSKEYDOWN message is sent to the active window. The window that receives the message can distinguish between these two contexts by checking the context code in the lParam parameter. + // /// + // SYSKEYDOWN = 0x0104, + // /// + // /// The WM_SYSKEYUP message is posted to the window with the keyboard focus when the user releases a key that was pressed while the ALT key was held down. It also occurs when no window currently has the keyboard focus; in this case, the WM_SYSKEYUP message is sent to the active window. The window that receives the message can distinguish between these two contexts by checking the context code in the lParam parameter. + // /// + // SYSKEYUP = 0x0105, + // /// + // /// The WM_SYSCHAR message is posted to the window with the keyboard focus when a WM_SYSKEYDOWN message is translated by the TranslateMessage function. It specifies the character code of a system character key that is, a character key that is pressed while the ALT key is down. + // /// + // SYSCHAR = 0x0106, + // /// + // /// The WM_SYSDEADCHAR message is sent to the window with the keyboard focus when a WM_SYSKEYDOWN message is translated by the TranslateMessage function. WM_SYSDEADCHAR specifies the character code of a system dead key that is, a dead key that is pressed while holding down the ALT key. + // /// + // SYSDEADCHAR = 0x0107, + // /// + // /// The WM_UNICHAR message is posted to the window with the keyboard focus when a WM_KEYDOWN message is translated by the TranslateMessage function. The WM_UNICHAR message contains the character code of the key that was pressed. + // /// The WM_UNICHAR message is equivalent to WM_CHAR, but it uses Unicode Transformation Format (UTF)-32, whereas WM_CHAR uses UTF-16. It is designed to send or post Unicode characters to ANSI windows and it can can handle Unicode Supplementary Plane characters. + // /// + // UNICHAR = 0x0109, + // /// + // /// This message filters for keyboard messages. + // /// + // KEYLAST = 0x0109, + // /// + // /// Sent immediately before the IME generates the composition string as a result of a keystroke. A window receives this message through its WindowProc function. + // /// + // IME_STARTCOMPOSITION = 0x010D, + // /// + // /// Sent to an application when the IME ends composition. A window receives this message through its WindowProc function. + // /// + // IME_ENDCOMPOSITION = 0x010E, + // /// + // /// Sent to an application when the IME changes composition status as a result of a keystroke. A window receives this message through its WindowProc function. + // /// + // IME_COMPOSITION = 0x010F, + // IME_KEYLAST = 0x010F, + // /// + // /// The WM_INITDIALOG message is sent to the dialog box procedure immediately before a dialog box is displayed. Dialog box procedures typically use this message to initialize controls and carry out any other initialization tasks that affect the appearance of the dialog box. + // /// + // INITDIALOG = 0x0110, + // /// + // /// The WM_COMMAND message is sent when the user selects a command item from a menu, when a control sends a notification message to its parent window, or when an accelerator keystroke is translated. + // /// + // COMMAND = 0x0111, + // /// + // /// A window receives this message when the user chooses a command from the Window menu, clicks the maximize button, minimize button, restore button, close button, or moves the form. You can stop the form from moving by filtering this out. + // /// + // SYSCOMMAND = 0x0112, + // /// + // /// The WM_TIMER message is posted to the installing thread's message queue when a timer expires. The message is posted by the GetMessage or PeekMessage function. + // /// + // TIMER = 0x0113, + // /// + // /// The WM_HSCROLL message is sent to a window when a scroll event occurs in the window's standard horizontal scroll bar. This message is also sent to the owner of a horizontal scroll bar control when a scroll event occurs in the control. + // /// + // HSCROLL = 0x0114, + // /// + // /// The WM_VSCROLL message is sent to a window when a scroll event occurs in the window's standard vertical scroll bar. This message is also sent to the owner of a vertical scroll bar control when a scroll event occurs in the control. + // /// + // VSCROLL = 0x0115, + // /// + // /// The WM_INITMENU message is sent when a menu is about to become active. It occurs when the user clicks an item on the menu bar or presses a menu key. This allows the application to modify the menu before it is displayed. + // /// + // INITMENU = 0x0116, + // /// + // /// The WM_INITMENUPOPUP message is sent when a drop-down menu or submenu is about to become active. This allows an application to modify the menu before it is displayed, without changing the entire menu. + // /// + // INITMENUPOPUP = 0x0117, + // /// + // /// The WM_MENUSELECT message is sent to a menu's owner window when the user selects a menu item. + // /// + // MENUSELECT = 0x011F, + // /// + // /// The WM_MENUCHAR message is sent when a menu is active and the user presses a key that does not correspond to any mnemonic or accelerator key. This message is sent to the window that owns the menu. + // /// + // MENUCHAR = 0x0120, + // /// + // /// The WM_ENTERIDLE message is sent to the owner window of a modal dialog box or menu that is entering an idle state. A modal dialog box or menu enters an idle state when no messages are waiting in its queue after it has processed one or more previous messages. + // /// + // ENTERIDLE = 0x0121, + // /// + // /// The WM_MENURBUTTONUP message is sent when the user releases the right mouse button while the cursor is on a menu item. + // /// + // MENURBUTTONUP = 0x0122, + // /// + // /// The WM_MENUDRAG message is sent to the owner of a drag-and-drop menu when the user drags a menu item. + // /// + // MENUDRAG = 0x0123, + // /// + // /// The WM_MENUGETOBJECT message is sent to the owner of a drag-and-drop menu when the mouse cursor enters a menu item or moves from the center of the item to the top or bottom of the item. + // /// + // MENUGETOBJECT = 0x0124, + // /// + // /// The WM_UNINITMENUPOPUP message is sent when a drop-down menu or submenu has been destroyed. + // /// + // UNINITMENUPOPUP = 0x0125, + // /// + // /// The WM_MENUCOMMAND message is sent when the user makes a selection from a menu. + // /// + // MENUCOMMAND = 0x0126, + // /// + // /// An application sends the WM_CHANGEUISTATE message to indicate that the user interface (UI) state should be changed. + // /// + // CHANGEUISTATE = 0x0127, + // /// + // /// An application sends the WM_UPDATEUISTATE message to change the user interface (UI) state for the specified window and all its child windows. + // /// + // UPDATEUISTATE = 0x0128, + // /// + // /// An application sends the WM_QUERYUISTATE message to retrieve the user interface (UI) state for a window. + // /// + // QUERYUISTATE = 0x0129, + // /// + // /// The WM_CTLCOLORMSGBOX message is sent to the owner window of a message box before Windows draws the message box. By responding to this message, the owner window can set the text and background colors of the message box by using the given display device context handle. + // /// + // CTLCOLORMSGBOX = 0x0132, + // /// + // /// An edit control that is not read-only or disabled sends the WM_CTLCOLOREDIT message to its parent window when the control is about to be drawn. By responding to this message, the parent window can use the specified device context handle to set the text and background colors of the edit control. + // /// + // CTLCOLOREDIT = 0x0133, + // /// + // /// Sent to the parent window of a list box before the system draws the list box. By responding to this message, the parent window can set the text and background colors of the list box by using the specified display device context handle. + // /// + // CTLCOLORLISTBOX = 0x0134, + // /// + // /// The WM_CTLCOLORBTN message is sent to the parent window of a button before drawing the button. The parent window can change the button's text and background colors. However, only owner-drawn buttons respond to the parent window processing this message. + // /// + // CTLCOLORBTN = 0x0135, + // /// + // /// The WM_CTLCOLORDLG message is sent to a dialog box before the system draws the dialog box. By responding to this message, the dialog box can set its text and background colors using the specified display device context handle. + // /// + // CTLCOLORDLG = 0x0136, + // /// + // /// The WM_CTLCOLORSCROLLBAR message is sent to the parent window of a scroll bar control when the control is about to be drawn. By responding to this message, the parent window can use the display context handle to set the background color of the scroll bar control. + // /// + // CTLCOLORSCROLLBAR = 0x0137, + // /// + // /// A static control, or an edit control that is read-only or disabled, sends the WM_CTLCOLORSTATIC message to its parent window when the control is about to be drawn. By responding to this message, the parent window can use the specified device context handle to set the text and background colors of the static control. + // /// + // CTLCOLORSTATIC = 0x0138, + // /// + // /// Use WM_MOUSEFIRST to specify the first mouse message. Use the PeekMessage() Function. + // /// + // MOUSEFIRST = 0x0200, + // /// + // /// The WM_MOUSEMOVE message is posted to a window when the cursor moves. If the mouse is not captured, the message is posted to the window that contains the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // MOUSEMOVE = 0x0200, + // /// + // /// The WM_LBUTTONDOWN message is posted when the user presses the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // LBUTTONDOWN = 0x0201, + // /// + // /// The WM_LBUTTONUP message is posted when the user releases the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // LBUTTONUP = 0x0202, + // /// + // /// The WM_LBUTTONDBLCLK message is posted when the user double-clicks the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // LBUTTONDBLCLK = 0x0203, + // /// + // /// The WM_RBUTTONDOWN message is posted when the user presses the right mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // RBUTTONDOWN = 0x0204, + // /// + // /// The WM_RBUTTONUP message is posted when the user releases the right mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // RBUTTONUP = 0x0205, + // /// + // /// The WM_RBUTTONDBLCLK message is posted when the user double-clicks the right mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // RBUTTONDBLCLK = 0x0206, + // /// + // /// The WM_MBUTTONDOWN message is posted when the user presses the middle mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // MBUTTONDOWN = 0x0207, + // /// + // /// The WM_MBUTTONUP message is posted when the user releases the middle mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // MBUTTONUP = 0x0208, + // /// + // /// The WM_MBUTTONDBLCLK message is posted when the user double-clicks the middle mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // MBUTTONDBLCLK = 0x0209, + // /// + // /// The WM_MOUSEWHEEL message is sent to the focus window when the mouse wheel is rotated. The DefWindowProc function propagates the message to the window's parent. There should be no internal forwarding of the message, since DefWindowProc propagates it up the parent chain until it finds a window that processes it. + // /// + // MOUSEWHEEL = 0x020A, + // /// + // /// The WM_XBUTTONDOWN message is posted when the user presses the first or second X button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // XBUTTONDOWN = 0x020B, + // /// + // /// The WM_XBUTTONUP message is posted when the user releases the first or second X button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // XBUTTONUP = 0x020C, + // /// + // /// The WM_XBUTTONDBLCLK message is posted when the user double-clicks the first or second X button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. + // /// + // XBUTTONDBLCLK = 0x020D, + // /// + // /// The WM_MOUSEHWHEEL message is sent to the focus window when the mouse's horizontal scroll wheel is tilted or rotated. The DefWindowProc function propagates the message to the window's parent. There should be no internal forwarding of the message, since DefWindowProc propagates it up the parent chain until it finds a window that processes it. + // /// + // MOUSEHWHEEL = 0x020E, + // /// + // /// Use WM_MOUSELAST to specify the last mouse message. Used with PeekMessage() Function. + // /// + // MOUSELAST = 0x020E, + // /// + // /// The WM_PARENTNOTIFY message is sent to the parent of a child window when the child window is created or destroyed, or when the user clicks a mouse button while the cursor is over the child window. When the child window is being created, the system sends WM_PARENTNOTIFY just before the CreateWindow or CreateWindowEx function that creates the window returns. When the child window is being destroyed, the system sends the message before any processing to destroy the window takes place. + // /// + // PARENTNOTIFY = 0x0210, + // /// + // /// The WM_ENTERMENULOOP message informs an application's main window procedure that a menu modal loop has been entered. + // /// + // ENTERMENULOOP = 0x0211, + // /// + // /// The WM_EXITMENULOOP message informs an application's main window procedure that a menu modal loop has been exited. + // /// + // EXITMENULOOP = 0x0212, + // /// + // /// The WM_NEXTMENU message is sent to an application when the right or left arrow key is used to switch between the menu bar and the system menu. + // /// + // NEXTMENU = 0x0213, + // /// + // /// The WM_SIZING message is sent to a window that the user is resizing. By processing this message, an application can monitor the size and position of the drag rectangle and, if needed, change its size or position. + // /// + // SIZING = 0x0214, + // /// + // /// The WM_CAPTURECHANGED message is sent to the window that is losing the mouse capture. + // /// + // CAPTURECHANGED = 0x0215, + // /// + // /// The WM_MOVING message is sent to a window that the user is moving. By processing this message, an application can monitor the position of the drag rectangle and, if needed, change its position. + // /// + // MOVING = 0x0216, + // /// + // /// Notifies applications that a power-management event has occurred. + // /// + // POWERBROADCAST = 0x0218, + // /// + // /// Notifies an application of a change to the hardware configuration of a device or the computer. + // /// + // DEVICECHANGE = 0x0219, + // /// + // /// An application sends the WM_MDICREATE message to a multiple-document interface (MDI) client window to create an MDI child window. + // /// + // MDICREATE = 0x0220, + // /// + // /// An application sends the WM_MDIDESTROY message to a multiple-document interface (MDI) client window to close an MDI child window. + // /// + // MDIDESTROY = 0x0221, + // /// + // /// An application sends the WM_MDIACTIVATE message to a multiple-document interface (MDI) client window to instruct the client window to activate a different MDI child window. + // /// + // MDIACTIVATE = 0x0222, + // /// + // /// An application sends the WM_MDIRESTORE message to a multiple-document interface (MDI) client window to restore an MDI child window from maximized or minimized size. + // /// + // MDIRESTORE = 0x0223, + // /// + // /// An application sends the WM_MDINEXT message to a multiple-document interface (MDI) client window to activate the next or previous child window. + // /// + // MDINEXT = 0x0224, + // /// + // /// An application sends the WM_MDIMAXIMIZE message to a multiple-document interface (MDI) client window to maximize an MDI child window. The system resizes the child window to make its client area fill the client window. The system places the child window's window menu icon in the rightmost position of the frame window's menu bar, and places the child window's restore icon in the leftmost position. The system also appends the title bar text of the child window to that of the frame window. + // /// + // MDIMAXIMIZE = 0x0225, + // /// + // /// An application sends the WM_MDITILE message to a multiple-document interface (MDI) client window to arrange all of its MDI child windows in a tile format. + // /// + // MDITILE = 0x0226, + // /// + // /// An application sends the WM_MDICASCADE message to a multiple-document interface (MDI) client window to arrange all its child windows in a cascade format. + // /// + // MDICASCADE = 0x0227, + // /// + // /// An application sends the WM_MDIICONARRANGE message to a multiple-document interface (MDI) client window to arrange all minimized MDI child windows. It does not affect child windows that are not minimized. + // /// + // MDIICONARRANGE = 0x0228, + // /// + // /// An application sends the WM_MDIGETACTIVE message to a multiple-document interface (MDI) client window to retrieve the handle to the active MDI child window. + // /// + // MDIGETACTIVE = 0x0229, + // /// + // /// An application sends the WM_MDISETMENU message to a multiple-document interface (MDI) client window to replace the entire menu of an MDI frame window, to replace the window menu of the frame window, or both. + // /// + // MDISETMENU = 0x0230, + // /// + // /// The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving or sizing modal loop. The window enters the moving or sizing modal loop when the user clicks the window's title bar or sizing border, or when the window passes the WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the message specifies the SC_MOVE or SC_SIZE value. The operation is complete when DefWindowProc returns. + // /// The system sends the WM_ENTERSIZEMOVE message regardless of whether the dragging of full windows is enabled. + // /// + // ENTERSIZEMOVE = 0x0231, + // /// + // /// The WM_EXITSIZEMOVE message is sent one time to a window, after it has exited the moving or sizing modal loop. The window enters the moving or sizing modal loop when the user clicks the window's title bar or sizing border, or when the window passes the WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the message specifies the SC_MOVE or SC_SIZE value. The operation is complete when DefWindowProc returns. + // /// + // EXITSIZEMOVE = 0x0232, + // /// + // /// Sent when the user drops a file on the window of an application that has registered itself as a recipient of dropped files. + // /// + // DROPFILES = 0x0233, + // /// + // /// An application sends the WM_MDIREFRESHMENU message to a multiple-document interface (MDI) client window to refresh the window menu of the MDI frame window. + // /// + // MDIREFRESHMENU = 0x0234, + // /// + // /// Sent to an application when a window is activated. A window receives this message through its WindowProc function. + // /// + // IME_SETCONTEXT = 0x0281, + // /// + // /// Sent to an application to notify it of changes to the IME window. A window receives this message through its WindowProc function. + // /// + // IME_NOTIFY = 0x0282, + // /// + // /// Sent by an application to direct the IME window to carry out the requested command. The application uses this message to control the IME window that it has created. To send this message, the application calls the SendMessage function with the following parameters. + // /// + // IME_CONTROL = 0x0283, + // /// + // /// Sent to an application when the IME window finds no space to extend the area for the composition window. A window receives this message through its WindowProc function. + // /// + // IME_COMPOSITIONFULL = 0x0284, + // /// + // /// Sent to an application when the operating system is about to change the current IME. A window receives this message through its WindowProc function. + // /// + // IME_SELECT = 0x0285, + // /// + // /// Sent to an application when the IME gets a character of the conversion result. A window receives this message through its WindowProc function. + // /// + // IME_CHAR = 0x0286, + // /// + // /// Sent to an application to provide commands and request information. A window receives this message through its WindowProc function. + // /// + // IME_REQUEST = 0x0288, + // /// + // /// Sent to an application by the IME to notify the application of a key press and to keep message order. A window receives this message through its WindowProc function. + // /// + // IME_KEYDOWN = 0x0290, + // /// + // /// Sent to an application by the IME to notify the application of a key release and to keep message order. A window receives this message through its WindowProc function. + // /// + // IME_KEYUP = 0x0291, + // /// + // /// The WM_MOUSEHOVER message is posted to a window when the cursor hovers over the client area of the window for the period of time specified in a prior call to TrackMouseEvent. + // /// + // MOUSEHOVER = 0x02A1, + // /// + // /// The WM_MOUSELEAVE message is posted to a window when the cursor leaves the client area of the window specified in a prior call to TrackMouseEvent. + // /// + // MOUSELEAVE = 0x02A3, + // /// + // /// The WM_NCMOUSEHOVER message is posted to a window when the cursor hovers over the nonclient area of the window for the period of time specified in a prior call to TrackMouseEvent. + // /// + // NCMOUSEHOVER = 0x02A0, + // /// + // /// The WM_NCMOUSELEAVE message is posted to a window when the cursor leaves the nonclient area of the window specified in a prior call to TrackMouseEvent. + // /// + // NCMOUSELEAVE = 0x02A2, + // /// + // /// The WM_WTSSESSION_CHANGE message notifies applications of changes in session state. + // /// + // WTSSESSION_CHANGE = 0x02B1, + // TABLET_FIRST = 0x02c0, + // TABLET_LAST = 0x02df, + // /// + // /// An application sends a WM_CUT message to an edit control or combo box to delete (cut) the current selection, if any, in the edit control and copy the deleted text to the clipboard in CF_TEXT format. + // /// + // CUT = 0x0300, + // /// + // /// An application sends the WM_COPY message to an edit control or combo box to copy the current selection to the clipboard in CF_TEXT format. + // /// + // COPY = 0x0301, + // /// + // /// An application sends a WM_PASTE message to an edit control or combo box to copy the current content of the clipboard to the edit control at the current caret position. Data is inserted only if the clipboard contains data in CF_TEXT format. + // /// + // PASTE = 0x0302, + // /// + // /// An application sends a WM_CLEAR message to an edit control or combo box to delete (clear) the current selection, if any, from the edit control. + // /// + // CLEAR = 0x0303, + // /// + // /// An application sends a WM_UNDO message to an edit control to undo the last operation. When this message is sent to an edit control, the previously deleted text is restored or the previously added text is deleted. + // /// + // UNDO = 0x0304, + // /// + // /// The WM_RENDERFORMAT message is sent to the clipboard owner if it has delayed rendering a specific clipboard format and if an application has requested data in that format. The clipboard owner must render data in the specified format and place it on the clipboard by calling the SetClipboardData function. + // /// + // RENDERFORMAT = 0x0305, + // /// + // /// The WM_RENDERALLFORMATS message is sent to the clipboard owner before it is destroyed, if the clipboard owner has delayed rendering one or more clipboard formats. For the content of the clipboard to remain available to other applications, the clipboard owner must render data in all the formats it is capable of generating, and place the data on the clipboard by calling the SetClipboardData function. + // /// + // RENDERALLFORMATS = 0x0306, + // /// + // /// The WM_DESTROYCLIPBOARD message is sent to the clipboard owner when a call to the EmptyClipboard function empties the clipboard. + // /// + // DESTROYCLIPBOARD = 0x0307, + // /// + // /// The WM_DRAWCLIPBOARD message is sent to the first window in the clipboard viewer chain when the content of the clipboard changes. This enables a clipboard viewer window to display the new content of the clipboard. + // /// + // DRAWCLIPBOARD = 0x0308, + // /// + // /// The WM_PAINTCLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and the clipboard viewer's client area needs repainting. + // /// + // PAINTCLIPBOARD = 0x0309, + // /// + // /// The WM_VSCROLLCLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and an event occurs in the clipboard viewer's vertical scroll bar. The owner should scroll the clipboard image and update the scroll bar values. + // /// + // VSCROLLCLIPBOARD = 0x030A, + // /// + // /// The WM_SIZECLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and the clipboard viewer's client area has changed size. + // /// + // SIZECLIPBOARD = 0x030B, + // /// + // /// The WM_ASKCBFORMATNAME message is sent to the clipboard owner by a clipboard viewer window to request the name of a CF_OWNERDISPLAY clipboard format. + // /// + // ASKCBFORMATNAME = 0x030C, + // /// + // /// The WM_CHANGECBCHAIN message is sent to the first window in the clipboard viewer chain when a window is being removed from the chain. + // /// + // CHANGECBCHAIN = 0x030D, + // /// + // /// The WM_HSCROLLCLIPBOARD message is sent to the clipboard owner by a clipboard viewer window. This occurs when the clipboard contains data in the CF_OWNERDISPLAY format and an event occurs in the clipboard viewer's horizontal scroll bar. The owner should scroll the clipboard image and update the scroll bar values. + // /// + // HSCROLLCLIPBOARD = 0x030E, + // /// + // /// This message informs a window that it is about to receive the keyboard focus, giving the window the opportunity to realize its logical palette when it receives the focus. + // /// + // QUERYNEWPALETTE = 0x030F, + // /// + // /// The WM_PALETTEISCHANGING message informs applications that an application is going to realize its logical palette. + // /// + // PALETTEISCHANGING = 0x0310, + // /// + // /// This message is sent by the OS to all top-level and overlapped windows after the window with the keyboard focus realizes its logical palette. + // /// This message enables windows that do not have the keyboard focus to realize their logical palettes and update their client areas. + // /// + // PALETTECHANGED = 0x0311, + // /// + // /// The WM_HOTKEY message is posted when the user presses a hot key registered by the RegisterHotKey function. The message is placed at the top of the message queue associated with the thread that registered the hot key. + // /// + // HOTKEY = 0x0312, + // /// + // /// The WM_PRINT message is sent to a window to request that it draw itself in the specified device context, most commonly in a printer device context. + // /// + // PRINT = 0x0317, + // /// + // /// The WM_PRINTCLIENT message is sent to a window to request that it draw its client area in the specified device context, most commonly in a printer device context. + // /// + // PRINTCLIENT = 0x0318, + // /// + // /// The WM_APPCOMMAND message notifies a window that the user generated an application command event, for example, by clicking an application command button using the mouse or typing an application command key on the keyboard. + // /// + // APPCOMMAND = 0x0319, + // /// + // /// The WM_THEMECHANGED message is broadcast to every window following a theme change event. Examples of theme change events are the activation of a theme, the deactivation of a theme, or a transition from one theme to another. + // /// + // THEMECHANGED = 0x031A, + // /// + // /// Sent when the contents of the clipboard have changed. + // /// + // CLIPBOARDUPDATE = 0x031D, + // /// + // /// The system will send a window the WM_DWMCOMPOSITIONCHANGED message to indicate that the availability of desktop composition has changed. + // /// + // DWMCOMPOSITIONCHANGED = 0x031E, + // /// + // /// WM_DWMNCRENDERINGCHANGED is called when the non-client area rendering status of a window has changed. Only windows that have set the flag DWM_BLURBEHIND.fTransitionOnMaximized to true will get this message. + // /// + // DWMNCRENDERINGCHANGED = 0x031F, + // /// + // /// Sent to all top-level windows when the colorization color has changed. + // /// + // DWMCOLORIZATIONCOLORCHANGED = 0x0320, + // /// + // /// WM_DWMWINDOWMAXIMIZEDCHANGE will let you know when a DWM composed window is maximized. You also have to register for this message as well. You'd have other windowd go opaque when this message is sent. + // /// + // DWMWINDOWMAXIMIZEDCHANGE = 0x0321, + // /// + // /// Sent to request extended title bar information. A window receives this message through its WindowProc function. + // /// + // GETTITLEBARINFOEX = 0x033F, + // HANDHELDFIRST = 0x0358, + // HANDHELDLAST = 0x035F, + // AFXFIRST = 0x0360, + // AFXLAST = 0x037F, + // PENWINFIRST = 0x0380, + // PENWINLAST = 0x038F, + // /// + // /// The WM_APP constant is used by applications to help define private messages, usually of the form WM_APP+X, where X is an integer value. + // /// + // APP = 0x8000, + // /// + // /// The WM_USER constant is used by applications to help define private messages for use by private window classes, usually of the form WM_USER+X, where X is an integer value. + // /// + // USER = 0x0400, + + // /// + // /// An application sends the WM_CPL_LAUNCH message to Windows Control Panel to request that a Control Panel application be started. + // /// + // CPL_LAUNCH = USER + 0x1000, + // /// + // /// The WM_CPL_LAUNCHED message is sent when a Control Panel application, started by the WM_CPL_LAUNCH message, has closed. The WM_CPL_LAUNCHED message is sent to the window identified by the wParam parameter of the WM_CPL_LAUNCH message that started the application. + // /// + // CPL_LAUNCHED = USER + 0x1001, + // /// + // /// WM_SYSTIMER is a well-known yet still undocumented message. Windows uses WM_SYSTIMER for internal actions like scrolling. + // /// + // SYSTIMER = 0x118 + + //} +} diff --git a/PROMS/DotNetBar Source Code/Controls/ScrollBarImplementation.cs b/PROMS/DotNetBar Source Code/Controls/ScrollBarImplementation.cs new file mode 100644 index 00000000..bf090bdf --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ScrollBarImplementation.cs @@ -0,0 +1,614 @@ +using System; +using System.Windows.Forms; +using System.Text; +using DevComponents.DotNetBar.ScrollBar; +using System.Drawing; +using DevComponents.DotNetBar.Rendering; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar.Controls +{ + internal class ScrollBarImplementation: IDisposable + { + #region Private Variables + private System.Windows.Forms.ScrollBar m_ParentScrollBar = null; + private ScrollBarCore m_ScrollBarCore = null; + private bool m_FirstPaint = true; + private int m_MouseDownTrackOffset = 0; + private Timer m_PaintTimer = null; + private bool m_IsVScrollBar = false; + private IScrollBarExtender m_ParentScrollBarWndProc = null; + private bool m_UseLockWindowUpdate = false; + #endregion + + #region Constructor + public ScrollBarImplementation(System.Windows.Forms.ScrollBar sb) + { + m_ParentScrollBar = sb; + m_ParentScrollBarWndProc = (IScrollBarExtender)m_ParentScrollBar; + m_IsVScrollBar = m_ParentScrollBar is VScrollBar; + + m_PaintTimer = new Timer(); + m_PaintTimer.Interval = 50; + m_PaintTimer.Tick += new EventHandler(PaintTimerTick); + + m_ScrollBarCore = new ScrollBarCore(m_ParentScrollBar, true); + //m_ScrollBarCore.IsAppScrollBarStyle = false; + if (m_ParentScrollBar is HScrollBar) + m_ScrollBarCore.Orientation = eOrientation.Horizontal; + else + m_ScrollBarCore.Orientation = eOrientation.Vertical; + m_ScrollBarCore.Minimum = m_ParentScrollBar.Minimum; + m_ScrollBarCore.Maximum = m_ParentScrollBar.Maximum; + m_ScrollBarCore.Value = m_ParentScrollBar.Value; + } + #endregion + + #region Internal Implementation + internal void OnHandleCreated() + { + Themes.SetWindowTheme(m_ParentScrollBar.Handle, "", ""); + UpdateScrollValues(); + } + + internal bool WndProc(ref Message m) + { + if (m.Msg == (int)WinApi.WindowsMessages.SBM_SETSCROLLINFO || m.Msg == 0x2114 || m.Msg == 0x2115 || m.Msg == (int)WinApi.WindowsMessages.WM_MOUSEMOVE) + { + CallBaseWndProc(ref m); + SendDelayPaintMessage(); + return false; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_SIZE) + { + CallBaseWndProc(ref m); + m_FirstPaint = true; + SendDelayPaintMessage(); + return false; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_ERASEBKGND) + { + //PaintUsingDC(); + //m.Result = new IntPtr(1); + return false; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONDOWN) + { + Point p = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam)); + InternalMouseDown(new MouseEventArgs(GetMouseButton(m.WParam.ToInt32()), 0, p.X, p.Y, 0)); + return false; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONUP) + { + Point p = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam)); + InternalMouseUp(new MouseEventArgs(GetMouseButton(m.WParam.ToInt32()), 0, p.X, p.Y, 0)); + return false; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONDBLCLK) + { + Point p = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam)); + InternalMouseDoubleClick(new MouseEventArgs(GetMouseButton(m.WParam.ToInt32()), 0, p.X, p.Y, 0)); + return false; + } + else if (m.Msg == NativeFunctions.WM_USER + 7) + { + PaintUsingDC(); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_SYSTIMER) + { + if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.Track && Control.MouseButtons == MouseButtons.Left) + { + Point p = m_ParentScrollBar.PointToClient(Control.MousePosition); + OnMouseMove(new MouseEventArgs(Control.MouseButtons, 0, p.X, p.Y, 0)); + } + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_CAPTURECHANGED) + { + // Recapture the mouse... + if (m.LParam == IntPtr.Zero && Control.MouseButtons == MouseButtons.Left && m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.Track) + { + m_ParentScrollBar.Capture = true; + } + } + + if (m.Msg == (int)WinApi.WindowsMessages.WM_PAINT) + { + if (m_FirstPaint) + { + // Call to base actually updates values returned by GetScrollBarInfo + CallBaseWndProc(ref m); + // Repaint the control once that is done + SendDelayPaintMessage(); + m_FirstPaint = false; + } + WinApi.PAINTSTRUCT ps = new WinApi.PAINTSTRUCT(); + IntPtr hdc = WinApi.BeginPaint(m.HWnd, ref ps); + try + { + Graphics g = Graphics.FromHdc(hdc); + try + { + PaintInternal(g, hdc); + } + finally + { + g.Dispose(); + } + } + finally + { + WinApi.EndPaint(m.HWnd, ref ps); + } + return false; + } + return true; + } + + private void CallBaseWndProc(ref Message m) + { + m_ParentScrollBarWndProc.CallBaseWndProc(ref m); + } + + private void SendDelayPaintMessage() + { + m_PaintTimer.Start(); + } + + void PaintTimerTick(object sender, EventArgs e) + { + m_PaintTimer.Stop(); + PaintUsingDC(); + } + + private void InternalMouseDoubleClick(MouseEventArgs me) + { + PerformThumbClick(me.X, me.Y); + } + + private void PerformThumbClick(int mouseX, int mouseY) + { + if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.ThumbDecrease) + this.SetValue(Math.Max(m_ParentScrollBar.Value - m_ParentScrollBar.SmallChange, m_ParentScrollBar.Minimum), ScrollEventType.SmallDecrement); + else if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.ThumbIncrease) + this.SetValue(Math.Min(m_ParentScrollBar.Value + m_ParentScrollBar.SmallChange, m_ParentScrollBar.Maximum), ScrollEventType.SmallIncrement); + else if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.Control) + { + if (this.IsVScroll) + { + if (mouseY < m_ScrollBarCore.TrackRectangle.Y) + this.SetValue(Math.Max(m_ParentScrollBar.Value - m_ParentScrollBar.LargeChange, m_ParentScrollBar.Minimum), ScrollEventType.LargeDecrement); + else if (mouseY > m_ScrollBarCore.TrackRectangle.Bottom) + this.SetValue(Math.Min(m_ParentScrollBar.Value + m_ParentScrollBar.LargeChange, m_ParentScrollBar.Maximum), ScrollEventType.LargeIncrement); + } + else + { + if (mouseX < m_ScrollBarCore.TrackRectangle.X) + this.SetValue(Math.Max(m_ParentScrollBar.Value - m_ParentScrollBar.LargeChange, m_ParentScrollBar.Minimum), ScrollEventType.LargeDecrement); + else if (mouseX > m_ScrollBarCore.TrackRectangle.Right) + this.SetValue(Math.Min(m_ParentScrollBar.Value + m_ParentScrollBar.LargeChange, m_ParentScrollBar.Maximum), ScrollEventType.LargeIncrement); + } + } + } + + private void SetValue(int newValue, ScrollEventType type) + { + //FieldInfo fi = typeof(System.Windows.Forms.ScrollBar).GetField("value", BindingFlags.NonPublic | BindingFlags.Instance); + //if (fi != null) + //{ + // fi.SetValue(this, newValue); + // UpdateSystemScrollInfo(); + //} + //else + + if (m_ParentScrollBar.Value == newValue) return; + + if (m_UseLockWindowUpdate && m_ParentScrollBar.Parent != null) + NativeFunctions.LockWindowUpdate(m_ParentScrollBar.Parent.Handle); + else + NativeFunctions.SendMessage(m_ParentScrollBar.Handle, NativeFunctions.WM_SETREDRAW, 0, 0); + + m_ParentScrollBarWndProc.SetValue(newValue, type); + if (m_UseLockWindowUpdate && m_ParentScrollBar.Parent != null) + NativeFunctions.LockWindowUpdate(IntPtr.Zero); + else + NativeFunctions.SendMessage(m_ParentScrollBar.Handle, NativeFunctions.WM_SETREDRAW, 1, 0); + + if (m_ParentScrollBar.Parent is DataGridView && type == ScrollEventType.ThumbTrack) + { + if (m_UseLockWindowUpdate) + m_ParentScrollBar.Parent.Refresh(); + else + { + Point p = m_ParentScrollBar.PointToClient(Control.MousePosition); + if (!m_ParentScrollBar.ClientRectangle.Contains(p)) + m_ParentScrollBar.Parent.Refresh(); + } + } + + PaintUsingDC(); + } + + //private void UpdateSystemScrollInfo() + //{ + // if (this.IsHandleCreated && this.Enabled) + // { + // WinApi.SCROLLINFO si = new WinApi.SCROLLINFO(); + // si.cbSize = Marshal.SizeOf(typeof(WinApi.SCROLLINFO)); + // si.fMask = 0x17; + // si.nMin = this.Minimum; + // si.nMax = this.Maximum; + // si.nPage = this.LargeChange; + // if (this.RightToLeft == RightToLeft.Yes) + // { + // MethodInfo mi = typeof(System.Windows.Forms.ScrollBar).GetMethod("ReflectPosition", BindingFlags.NonPublic | BindingFlags.Instance); + // if(mi!=null) + // si.nPos = (int)mi.Invoke(this, new object[]{this.Value}); + // //= this.ReflectPosition(this.value); + // } + // else + // { + // si.nPos = this.Value; + // } + // si.nTrackPos = 0; + // WinApi.SetScrollInfo(new HandleRef(this, this.Handle), 2, ref si, false); + // } + //} + + private void InternalMouseUp(MouseEventArgs mouseEventArgs) + { + StopAutoScrollTimer(); + m_ScrollBarCore.MouseUp(mouseEventArgs); + m_ParentScrollBar.Invalidate(); + m_MouseDownTrackOffset = 0; + + if (m_ParentScrollBar.Capture) + m_ParentScrollBar.Capture = false; + } + + private void InternalMouseDown(MouseEventArgs me) + { + m_MouseDownTrackOffset = 0; + m_ScrollBarCore.MouseDown(me); + if (m_ScrollBarCore.MouseOverPart != ScrollBarCore.eScrollPart.Track && m_ScrollBarCore.MouseOverPart != ScrollBarCore.eScrollPart.None) + { + PerformThumbClick(me.X, me.Y); + StartAutoScrollTimer(); + } + else if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.Track) + { + if (IsVScroll) + m_MouseDownTrackOffset = me.Y - m_ScrollBarCore.TrackRectangle.Y; + else + m_MouseDownTrackOffset = me.X - m_ScrollBarCore.TrackRectangle.X; + } + PaintUsingDC(); + } + + private Timer m_Timer = null; + private void StartAutoScrollTimer() + { + if (m_Timer == null) + { + m_Timer = new Timer(); + m_Timer.Interval = 150; + m_Timer.Tick += new EventHandler(TimerScrollTick); + } + m_Timer.Start(); + } + + private void TimerScrollTick(object sender, EventArgs e) + { + Point p = m_ParentScrollBar.PointToClient(Control.MousePosition); + PerformThumbClick(p.X, p.Y); + } + + private void StopAutoScrollTimer() + { + if (m_Timer != null) + { + m_Timer.Stop(); + m_Timer.Dispose(); + m_Timer = null; + } + } + + private MouseButtons GetMouseButton(int wParam) + { + MouseButtons mb = MouseButtons.None; + if ((wParam & (int)WinApi.MouseKeyState.MK_LBUTTON) != 0) + mb |= MouseButtons.Left; + if ((wParam & (int)WinApi.MouseKeyState.MK_MBUTTON) != 0) + mb |= MouseButtons.Middle; + if ((wParam & (int)WinApi.MouseKeyState.MK_RBUTTON) != 0) + mb |= MouseButtons.Right; + if ((wParam & (int)WinApi.MouseKeyState.MK_XBUTTON1) != 0) + mb |= MouseButtons.XButton1; + if ((wParam & (int)WinApi.MouseKeyState.MK_XBUTTON2) != 0) + mb |= MouseButtons.XButton2; + + return mb; + } + + private void PaintUsingDC() + { + IntPtr hdc = WinApi.GetWindowDC(m_ParentScrollBar.Handle); + try + { + Graphics g = Graphics.FromHdc(hdc); + try + { + PaintInternal(g, hdc); + } + finally + { + g.Dispose(); + } + } + finally + { + WinApi.ReleaseDC(m_ParentScrollBar.Handle, hdc); + } + } + + private void PaintInternal(Graphics g, IntPtr hdc) + { + UpdateScrollValues(); + using (BufferedBitmap bmp = new BufferedBitmap(g, new Rectangle(0, 0, m_ParentScrollBar.Width, m_ParentScrollBar.Height))) + { + m_ScrollBarCore.Paint(GetItemPaintArgs(bmp.Graphics)); + bmp.Render(g); + } + } + + private ItemPaintArgs GetItemPaintArgs(Graphics g) + { + ItemPaintArgs pa = new ItemPaintArgs(m_ParentScrollBar as IOwner, m_ParentScrollBar, g, GetColorScheme()); + pa.Renderer = this.GetRenderer(); + pa.DesignerSelection = false; + pa.GlassEnabled = false; + return pa; + } + + private ColorScheme m_ColorScheme = null; + /// + /// Returns the color scheme used by control. Color scheme for Office2007 style will be retrived from the current renderer instead of + /// local color scheme referenced by ColorScheme property. + /// + /// An instance of ColorScheme object. + protected virtual ColorScheme GetColorScheme() + { + BaseRenderer r = GetRenderer(); + if (r is Office2007Renderer) + return ((Office2007Renderer)r).ColorTable.LegacyColors; + if (m_ColorScheme == null) + m_ColorScheme = new ColorScheme(eDotNetBarStyle.Office2007); + return m_ColorScheme; + } + + private Rendering.BaseRenderer m_DefaultRenderer = null; + private Rendering.BaseRenderer m_Renderer = null; + private eRenderMode m_RenderMode = eRenderMode.Global; + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public virtual Rendering.BaseRenderer GetRenderer() + { + if (m_RenderMode == eRenderMode.Global && Rendering.GlobalManager.Renderer != null) + return Rendering.GlobalManager.Renderer; + else if (m_RenderMode == eRenderMode.Custom && m_Renderer != null) + return m_Renderer; + + if (m_DefaultRenderer == null) + m_DefaultRenderer = new Rendering.Office2007Renderer(); + + return m_DefaultRenderer; + } + + /// + /// Gets or sets the redering mode used by control. Default value is eRenderMode.Global which means that static GlobalManager.Renderer is used. If set to Custom then Renderer property must + /// also be set to the custom renderer that will be used. + /// + public eRenderMode RenderMode + { + get { return m_RenderMode; } + set + { + if (m_RenderMode != value) + { + m_RenderMode = value; + m_ParentScrollBar.Invalidate(true); + } + } + } + + /// + /// Gets or sets the custom renderer used by the items on this control. RenderMode property must also be set to eRenderMode.Custom in order renderer + /// specified here to be used. + /// + public DevComponents.DotNetBar.Rendering.BaseRenderer Renderer + { + get + { + return m_Renderer; + } + set { m_Renderer = value; } + } + + internal void OnMouseEnter(EventArgs e) + { + if (m_ParentScrollBar.Capture) + m_ParentScrollBar.Capture = false; + } + + internal void OnMouseLeave(EventArgs e) + { + StopAutoScrollTimer(); + if (m_ScrollBarCore.MouseOverPart != ScrollBarCore.eScrollPart.None && Control.MouseButtons == MouseButtons.Left) + m_ParentScrollBar.Capture = true; + if (m_ScrollBarCore.IsMouseDown && Control.MouseButtons == MouseButtons.None) + { + m_ScrollBarCore.MouseUp(new MouseEventArgs(MouseButtons.Left, 0, -10, -10, 0)); + SendDelayPaintMessage(); + } + else + m_ScrollBarCore.MouseLeave(); + } + + internal void OnMouseMove(MouseEventArgs e) + { + m_ScrollBarCore.MouseMove(e); + if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.Track && e.Button == MouseButtons.Left) + { + Point p = m_ParentScrollBar.PointToClient(Control.MousePosition); + SetValue(ValueFromMouseCoordinates(p), ScrollEventType.ThumbTrack); + } + } + + private int ValueFromMouseCoordinates(Point p) + { + if (IsVScroll) + { + int trackY = p.Y - m_MouseDownTrackOffset; + trackY = Math.Max(trackY, m_ScrollBarCore.ThumbDecreaseRectangle.Bottom); + trackY = Math.Min(trackY, m_ScrollBarCore.ThumbIncreaseRectangle.Y - GetTrackSize()); + trackY -= m_ScrollBarCore.ThumbDecreaseRectangle.Bottom; + + int totalSize = GetAvailableTrackArea() - GetTrackSize(); + return (int)((m_ParentScrollBar.Maximum - m_ParentScrollBar.Minimum) * ((float)trackY / (float)totalSize)); + } + else + { + int trackX = p.X - m_MouseDownTrackOffset; + trackX = Math.Max(trackX, m_ScrollBarCore.ThumbDecreaseRectangle.Right); + trackX = Math.Min(trackX, m_ScrollBarCore.ThumbIncreaseRectangle.X - GetTrackSize()); + trackX -= m_ScrollBarCore.ThumbDecreaseRectangle.Right; + + int totalSize = GetAvailableTrackArea() - GetTrackSize(); + return (int)((m_ParentScrollBar.Maximum - m_ParentScrollBar.Minimum) * ((float)trackX / (float)totalSize)); + } + } + + private int GetTrackSize() + { + if (IsVScroll) + return m_ScrollBarCore.TrackRectangle.Height; + else + return m_ScrollBarCore.TrackRectangle.Width; + } + + private int GetAvailableTrackArea() + { + if (IsVScroll) + return m_ScrollBarCore.DisplayRectangle.Height - m_ScrollBarCore.ThumbDecreaseRectangle.Height - m_ScrollBarCore.ThumbIncreaseRectangle.Height; + else + return m_ScrollBarCore.DisplayRectangle.Width - m_ScrollBarCore.ThumbDecreaseRectangle.Width - m_ScrollBarCore.ThumbIncreaseRectangle.Width; + } + + private bool IsVScroll + { + get + { + return m_IsVScrollBar; + } + } + + private void UpdateScrollValues() + { + WinApi.SCROLLBARINFO psbi = new WinApi.SCROLLBARINFO(); + psbi.cbSize = Marshal.SizeOf(psbi); + + WinApi.GetScrollBarInfo(m_ParentScrollBar.Handle, (uint)WinApi.eObjectId.OBJID_CLIENT, ref psbi); + + Rectangle displayRect = new Rectangle(0, 0, m_ParentScrollBar.Width, m_ParentScrollBar.Height); + + if (IsVScroll) + { + if (m_ScrollBarCore.DisplayRectangle != displayRect) + m_ScrollBarCore.DisplayRectangle = displayRect; + + Rectangle thumbRect = new Rectangle(displayRect.X, displayRect.Y, displayRect.Width, psbi.dxyLineButton); + if (m_ScrollBarCore.ThumbDecreaseRectangle != thumbRect) + m_ScrollBarCore.ThumbDecreaseRectangle = thumbRect; + + thumbRect = new Rectangle(displayRect.X, displayRect.Bottom - psbi.dxyLineButton, displayRect.Width, psbi.dxyLineButton); + if (m_ScrollBarCore.ThumbIncreaseRectangle != thumbRect) + m_ScrollBarCore.ThumbIncreaseRectangle = thumbRect; + + thumbRect = new Rectangle(displayRect.X, displayRect.Y + psbi.xyThumbTop, displayRect.Width, psbi.xyThumbBottom - psbi.xyThumbTop); + if (m_ScrollBarCore.TrackRectangle != thumbRect) + m_ScrollBarCore.TrackRectangle = thumbRect; + } + else + { + if (m_ScrollBarCore.DisplayRectangle != displayRect) + m_ScrollBarCore.DisplayRectangle = displayRect; + + Rectangle thumbRect = new Rectangle(displayRect.X, displayRect.Y, psbi.dxyLineButton, displayRect.Height); + if (m_ScrollBarCore.ThumbDecreaseRectangle != thumbRect) + m_ScrollBarCore.ThumbDecreaseRectangle = thumbRect; + + thumbRect = new Rectangle(displayRect.Right - psbi.dxyLineButton, displayRect.Y, psbi.dxyLineButton, displayRect.Height); + if (m_ScrollBarCore.ThumbIncreaseRectangle != thumbRect) + m_ScrollBarCore.ThumbIncreaseRectangle = thumbRect; + + thumbRect = new Rectangle(displayRect.X + psbi.xyThumbTop, displayRect.Y, psbi.xyThumbBottom - psbi.xyThumbTop, displayRect.Height); + if (m_ScrollBarCore.TrackRectangle != thumbRect) + m_ScrollBarCore.TrackRectangle = thumbRect; + } + + if (m_ScrollBarCore.Minimum != m_ParentScrollBar.Minimum) + m_ScrollBarCore.Minimum = m_ParentScrollBar.Minimum; + if (m_ScrollBarCore.Maximum != m_ParentScrollBar.Maximum) + m_ScrollBarCore.Maximum = m_ParentScrollBar.Maximum; + if (m_ScrollBarCore.SmallChange != m_ParentScrollBar.SmallChange) + m_ScrollBarCore.SmallChange = m_ParentScrollBar.SmallChange; + if (m_ScrollBarCore.LargeChange != m_ParentScrollBar.LargeChange) + m_ScrollBarCore.LargeChange = m_ParentScrollBar.LargeChange; + if (m_ScrollBarCore.Value != m_ParentScrollBar.Value) + m_ScrollBarCore.Value = m_ParentScrollBar.Value; + } + + internal void NotifyInvalidate(Rectangle invalidatedArea) + { + + } + + //public bool IsAppScrollBarStyle + //{ + // get { return m_ScrollBarCore.IsAppScrollBarStyle; } + // set + // { + // m_ScrollBarCore.IsAppScrollBarStyle = value; + // m_ParentScrollBar.Invalidate(); + // } + //} + #endregion + + #region IDisposable Members + + public void Dispose() + { + if (m_ScrollBarCore != null) + { + m_ScrollBarCore.Dispose(); + m_ScrollBarCore = null; + } + if (m_PaintTimer != null) + { + m_PaintTimer.Stop(); + m_PaintTimer.Dispose(); + m_PaintTimer = null; + } + StopAutoScrollTimer(); + } + + #endregion + + internal interface IScrollBarExtender + { + void CallBaseWndProc(ref Message m); + void SetValue(int newValue, ScrollEventType type); + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ScrollBarReplacement.cs b/PROMS/DotNetBar Source Code/Controls/ScrollBarReplacement.cs new file mode 100644 index 00000000..2fa62436 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ScrollBarReplacement.cs @@ -0,0 +1,257 @@ +#if FRAMEWORK20 +using System; +using System.Text; +using DevComponents.DotNetBar.ScrollBar; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Controls +{ + internal class ScrollBarReplacement:IDisposable + { + #region Private Variables + private ScrollBarCore m_ScrollBarCore = null; + private System.Windows.Forms.ScrollBar m_ParentScrollBar = null; + private IScrollBarExtender m_ParentScrollBarWndProc = null; + private bool m_IsVScrollBar = false; + #endregion + + #region Constructor + public ScrollBarReplacement(System.Windows.Forms.ScrollBar sb) + { + m_ParentScrollBar = sb; + m_ParentScrollBarWndProc = (IScrollBarExtender)m_ParentScrollBar; + m_IsVScrollBar = m_ParentScrollBar is VScrollBar; + + m_ScrollBarCore = new ScrollBarCore(m_ParentScrollBar, false); + m_ScrollBarCore.ValueChanged += new EventHandler(ScrollBarCore_ValueChanged); + if (m_ParentScrollBar is HScrollBar) + m_ScrollBarCore.Orientation = eOrientation.Horizontal; + else + m_ScrollBarCore.Orientation = eOrientation.Vertical; + m_ScrollBarCore.Minimum = m_ParentScrollBar.Minimum; + m_ScrollBarCore.Maximum = m_ParentScrollBar.Maximum; + m_ScrollBarCore.Value = m_ParentScrollBar.Value; + m_ScrollBarCore.Enabled = m_ParentScrollBar.Enabled; + m_ParentScrollBar.EnabledChanged += new EventHandler(ParentScrollBar_EnabledChanged); + } + #endregion + + #region Internal Implementation + private void ParentScrollBar_EnabledChanged(object sender, EventArgs e) + { + m_ScrollBarCore.Enabled = m_ParentScrollBar.Enabled; + } + + internal void OnHandleCreated() + { + UpdateScrollValues(); + } + + internal void UpdateScrollValues() + { + Rectangle r = new Rectangle(0, 0, m_ParentScrollBar.Width, m_ParentScrollBar.Height); + + if (m_ScrollBarCore.Minimum != m_ParentScrollBar.Minimum) + m_ScrollBarCore.Minimum = m_ParentScrollBar.Minimum; + if (m_ScrollBarCore.Maximum != m_ParentScrollBar.Maximum) + m_ScrollBarCore.Maximum = m_ParentScrollBar.Maximum; + if (m_ScrollBarCore.SmallChange != m_ParentScrollBar.SmallChange) + m_ScrollBarCore.SmallChange = m_ParentScrollBar.SmallChange; + if (m_ScrollBarCore.LargeChange != m_ParentScrollBar.LargeChange) + m_ScrollBarCore.LargeChange = m_ParentScrollBar.LargeChange; + if (m_ScrollBarCore.Value != m_ParentScrollBar.Value) + m_ScrollBarCore.Value = m_ParentScrollBar.Value; + if (r != m_ScrollBarCore.DisplayRectangle) + m_ScrollBarCore.DisplayRectangle = r; + } + + private bool IsVScroll + { + get + { + return m_IsVScrollBar; + } + } + + internal void OnMouseEnter(EventArgs e) + { + if (m_ParentScrollBar.Capture) + m_ParentScrollBar.Capture = false; + } + + internal void OnMouseLeave(EventArgs e) + { + m_ScrollBarCore.MouseLeave(); + } + + internal void OnMouseMove(System.Windows.Forms.MouseEventArgs e) + { + m_ScrollBarCore.MouseMove(e); + } + + internal void NotifyInvalidate(Rectangle invalidatedArea) + { + //UpdateScrollValues(); + m_ScrollBarCore.DisposeCashedView(); + } + + internal void OnMouseDown(MouseEventArgs e) + { + m_ScrollBarCore.MouseDown(e); + } + + internal void OnMouseUp(MouseEventArgs e) + { + m_ScrollBarCore.MouseUp(e); + } + + private void ScrollBarCore_ValueChanged(object sender, EventArgs e) + { + SetValue(m_ScrollBarCore.Value); + } + + private void SetValue(int v) + { + //Console.WriteLine(v + " " + m_ParentScrollBar.LargeChange +" "+m_ParentScrollBar.Maximum); + if (m_ParentScrollBar.Value == v && m_ParentScrollBar.Value != m_ScrollBarCore.GetMaximumValue()) return; + + ScrollEventType t = ScrollEventType.SmallIncrement; + if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.ThumbDecrease) + t = ScrollEventType.SmallDecrement; + else if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.Track) + t = ScrollEventType.ThumbTrack; + else if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.Control) + { + if (v > m_ParentScrollBar.Value) + t = ScrollEventType.LargeIncrement; + else + t = ScrollEventType.LargeDecrement; + } + if (t == ScrollEventType.SmallIncrement && m_ParentScrollBar.Value == v && m_ParentScrollBar.Value == m_ScrollBarCore.GetMaximumValue()) + { + t = ScrollEventType.Last; + } + m_ParentScrollBarWndProc.SetValue(v, t); + + //if (t == ScrollEventType.ThumbTrack && m_ParentScrollBar.Parent is DataGridView) + // m_ParentScrollBar.Parent.Refresh(); + } + #endregion + + #region IDisposable Members + public void Dispose() + { + m_ScrollBarCore.DisposeCashedView(); + } + #endregion + + #region Rendering + internal void OnPaint(System.Windows.Forms.PaintEventArgs e) + { + Graphics g = e.Graphics; + UpdateScrollValues(); + //using (BufferedBitmap bmp = new BufferedBitmap(g, new Rectangle(0, 0, m_ParentScrollBar.Width, m_ParentScrollBar.Height))) + //{ + m_ScrollBarCore.Paint(GetItemPaintArgs(g)); + //bmp.Render(g); + //} + } + + private ItemPaintArgs GetItemPaintArgs(Graphics g) + { + ItemPaintArgs pa = new ItemPaintArgs(m_ParentScrollBar as IOwner, m_ParentScrollBar, g, GetColorScheme()); + pa.Renderer = this.GetRenderer(); + pa.DesignerSelection = false; + pa.GlassEnabled = false; + return pa; + } + + private ColorScheme m_ColorScheme = null; + /// + /// Returns the color scheme used by control. Color scheme for Office2007 style will be retrived from the current renderer instead of + /// local color scheme referenced by ColorScheme property. + /// + /// An instance of ColorScheme object. + protected virtual ColorScheme GetColorScheme() + { + BaseRenderer r = GetRenderer(); + if (r is Office2007Renderer) + return ((Office2007Renderer)r).ColorTable.LegacyColors; + if (m_ColorScheme == null) + m_ColorScheme = new ColorScheme(eDotNetBarStyle.Office2007); + return m_ColorScheme; + } + + private Rendering.BaseRenderer m_DefaultRenderer = null; + private Rendering.BaseRenderer m_Renderer = null; + private eRenderMode m_RenderMode = eRenderMode.Global; + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public virtual Rendering.BaseRenderer GetRenderer() + { + if (m_RenderMode == eRenderMode.Global && Rendering.GlobalManager.Renderer != null) + return Rendering.GlobalManager.Renderer; + else if (m_RenderMode == eRenderMode.Custom && m_Renderer != null) + return m_Renderer; + + if (m_DefaultRenderer == null) + m_DefaultRenderer = new Rendering.Office2007Renderer(); + + return m_DefaultRenderer; + } + + /// + /// Gets or sets the redering mode used by control. Default value is eRenderMode.Global which means that static GlobalManager.Renderer is used. If set to Custom then Renderer property must + /// also be set to the custom renderer that will be used. + /// + public eRenderMode RenderMode + { + get { return m_RenderMode; } + set + { + if (m_RenderMode != value) + { + m_RenderMode = value; + m_ParentScrollBar.Invalidate(true); + } + } + } + + /// + /// Gets or sets the custom renderer used by the items on this control. RenderMode property must also be set to eRenderMode.Custom in order renderer + /// specified here to be used. + /// + public DevComponents.DotNetBar.Rendering.BaseRenderer Renderer + { + get + { + return m_Renderer; + } + set { m_Renderer = value; } + } + + internal ScrollBarCore ScrollBarCore + { + get { return m_ScrollBarCore; } + } + + public bool AppStyleScrollBar + { + get { return m_ScrollBarCore.IsAppScrollBarStyle; } + set { m_ScrollBarCore.IsAppScrollBarStyle = value; } + } + #endregion + + #region IScrollBarExtender + internal interface IScrollBarExtender + { + void SetValue(int newValue, ScrollEventType type); + } + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/ScrollbarControl.cs b/PROMS/DotNetBar Source Code/Controls/ScrollbarControl.cs new file mode 100644 index 00000000..f0e99da2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ScrollbarControl.cs @@ -0,0 +1,496 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.DotNetBar.ScrollBar; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents control which handles scroll-bars. + /// + [ToolboxItem(false)] + public class ScrollbarControl : ControlWithBackgroundStyle + { + private const int ScrollPositionUpdateDelay = 400; + private HScrollBarAdv _HScrollBar = null; + private VScrollBarAdv _VScrollBar = null; + private Control _Thumb = null; + /// + /// Initializes a new instance of the ScrollbarControl class. + /// + public ScrollbarControl() + { + this.SetStyle(ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.Opaque | + ControlStyles.ResizeRedraw | + DisplayHelp.DoubleBufferFlag, true); + + _HScrollBar = new HScrollBarAdv(); + _HScrollBar.Visible = false; + _HScrollBar.Appearance = _ScrollBarAppearance; + _HScrollBar.Scroll += HScrollBarScroll; + _VScrollBar = new VScrollBarAdv(); + _VScrollBar.Visible = false; + _VScrollBar.Appearance = _ScrollBarAppearance; + _VScrollBar.Scroll += VScrollBarScroll; + this.Controls.Add(_HScrollBar); + this.Controls.Add(_VScrollBar); + + _Thumb = new Control(); + _Thumb.Visible = false; + _Thumb.BackColor = SystemColors.Window; + this.Controls.Add(_Thumb); + } + + private eScrollBarAppearance _ScrollBarAppearance = eScrollBarAppearance.Default; + /// + /// Gets or sets the scroll-bar visual style. + /// + [DefaultValue(eScrollBarAppearance.Default), Category("Appearance"), Description("Gets or sets the scroll-bar visual style.")] + public eScrollBarAppearance ScrollBarAppearance + { + get { return _ScrollBarAppearance; } + set + { + _ScrollBarAppearance = value; + OnScrollBarAppearanceChanged(); + } + } + private void OnScrollBarAppearanceChanged() + { + if (_VScrollBar != null) _VScrollBar.Appearance = _ScrollBarAppearance; + if (_HScrollBar != null) _HScrollBar.Appearance = _ScrollBarAppearance; + } + + private void UpdateScrollOverrideControlBounds() + { + if (_ScrollOverrideControl != null) + _ScrollOverrideControl.Bounds = GetScrollOverrideControlBounds(); + } + protected override void OnResize(EventArgs e) + { + UpdateScrollOverrideControlBounds(); + UpdateScrollBars(); + base.OnResize(e); + } + + protected override void OnVisualPropertyChanged() + { + base.OnVisualPropertyChanged(); + UpdateScrollOverrideControlBounds(); + UpdateScrollBars(); + } + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + base.ScaleControl(factor, specified); + UpdateScrollOverrideControlBounds(); + } + + private bool _UpdatingScrollbars = false; + protected virtual void UpdateScrollBarsDelayed() + { + InvokeDelayed(new MethodInvoker(delegate { UpdateScrollBars(); }), ScrollPositionUpdateDelay); + } + protected virtual void UpdateScrollBars() + { + if (!IsHandleCreated || _UpdatingScrollbars) return; + _UpdatingScrollbars = true; + try + { + Control scrollOverrideControl = _ScrollOverrideControl; + if (scrollOverrideControl == null) + { + if (_HScrollBar.Visible) _HScrollBar.Visible = false; + if (_VScrollBar.Visible) _VScrollBar.Visible = false; + return; + } + WinApi.SCROLLBARINFO psbi = new WinApi.SCROLLBARINFO(); + psbi.cbSize = Marshal.SizeOf(psbi); + WinApi.GetScrollBarInfo(scrollOverrideControl.Handle, (uint)WinApi.eObjectId.OBJID_VSCROLL, ref psbi); + if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + { + Rectangle vsBounds = psbi.rcScrollBar.ToRectangle(); + vsBounds.Location = this.PointToClient(vsBounds.Location); + Rectangle scrollCountrolBounds = _ScrollOverrideControl.Bounds; + if (!scrollCountrolBounds.Contains(vsBounds)) + { + // We need to guess bounds for best performance and appearance + if (vsBounds.Right > scrollCountrolBounds.Right) + { + vsBounds.X = scrollCountrolBounds.Right - vsBounds.Width; + } + else if (vsBounds.X < scrollCountrolBounds.X) + { + vsBounds.X = 0; + } + } + if (_VScrollBar.Bounds != vsBounds) + { + _VScrollBar.Bounds = vsBounds; + UpdateVerticalScrollBarValues(); + } + if (!_VScrollBar.Visible) + { + _VScrollBar.Visible = true; + _VScrollBar.Refresh(); + InvokeDelayed(new MethodInvoker(delegate { UpdateVerticalScrollBarValues(); }), ScrollPositionUpdateDelay); + } + + if (psbi.rgstate[0] == (int)WinApi.eStateFlags.STATE_SYSTEM_UNAVAILABLE) + _VScrollBar.Enabled = false; + else if (!_VScrollBar.Enabled) + _VScrollBar.Enabled = true; + //Console.WriteLine("VscrollBar Bounds detection {0}", vsBounds); + } + else if (_VScrollBar.Visible) + _VScrollBar.Visible = false; + + psbi = new WinApi.SCROLLBARINFO(); + psbi.cbSize = Marshal.SizeOf(psbi); + WinApi.GetScrollBarInfo(scrollOverrideControl.Handle, (uint)WinApi.eObjectId.OBJID_HSCROLL, ref psbi); + if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + { + Rectangle hsBounds = psbi.rcScrollBar.ToRectangle(); + hsBounds.Location = this.PointToClient(hsBounds.Location); + Rectangle scrollCountrolBounds = _ScrollOverrideControl.Bounds; + if (!scrollCountrolBounds.Contains(hsBounds)) + { + // We need to guess bounds for best performance and appearance + if (hsBounds.Bottom > scrollCountrolBounds.Bottom) + { + hsBounds.Y = scrollCountrolBounds.Bottom - hsBounds.Height; + } + } + if (_VScrollBar.Visible && hsBounds.Width == scrollCountrolBounds.Width) + hsBounds.Width -= _VScrollBar.Width; + if (_HScrollBar.Bounds != hsBounds) + { + _HScrollBar.Bounds = hsBounds; + UpdateHorizontalScrollBarValues(); + } + if (!_HScrollBar.Visible) + { + _HScrollBar.Visible = true; + _HScrollBar.Refresh(); + InvokeDelayed(new MethodInvoker(delegate { UpdateHorizontalScrollBarValues(); }), ScrollPositionUpdateDelay); + } + + if (psbi.rgstate[0] == (int)WinApi.eStateFlags.STATE_SYSTEM_UNAVAILABLE) + _HScrollBar.Enabled = false; + else if (!_HScrollBar.Enabled) + _HScrollBar.Enabled = true; + } + else if (_HScrollBar.Visible) + _HScrollBar.Visible = false; + + if (_HScrollBar.Visible && _VScrollBar.Visible) + { + _Thumb.Bounds = new Rectangle(_VScrollBar.Left, _VScrollBar.Bounds.Bottom, _VScrollBar.Width, _HScrollBar.Height); + _Thumb.Visible = true; + } + else + { + _Thumb.Visible = false; + } + } + finally + { + _UpdatingScrollbars = false; + } + } + + private System.Drawing.Rectangle GetScrollOverrideControlBounds() + { + return GetContentRectangle(); + } + + private Control _ScrollOverrideControl = null; + internal Control ScrollOverrideControl + { + get { return _ScrollOverrideControl; } + set + { + if (value != _ScrollOverrideControl) + { + if (!(value is IScrollBarOverrideSupport)) + throw new ArgumentException("ScrollOverrideControl must implement IScrollBarOverrideSupport interface."); + Control oldValue = _ScrollOverrideControl; + _ScrollOverrideControl = value; + OnScrollOverrideControlChanged(oldValue, value); + } + } + } + /// + /// Called when ScrollOverrideControl property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnScrollOverrideControlChanged(Control oldValue, Control newValue) + { + if (oldValue != null) + { + IScrollBarOverrideSupport sbo = (IScrollBarOverrideSupport)newValue; + sbo.NonClientSizeChanged -= NonClientSizeChanged; + sbo.ScrollBarValueChanged -= ControlScrollBarValueChanged; + sbo.ControlMoved -= ScrollControlMoved; + this.Controls.Remove(oldValue); + } + if (newValue != null) + { + IScrollBarOverrideSupport sbo = (IScrollBarOverrideSupport)newValue; + sbo.NonClientSizeChanged += NonClientSizeChanged; + sbo.ScrollBarValueChanged += ControlScrollBarValueChanged; + sbo.ControlMoved += ScrollControlMoved; + this.Controls.Add(newValue); + } + UpdateScrollOverrideControlBounds(); + + if (IsHandleCreated) + { + //InitializeWindowOverride(); + UpdateScrollBars(); + } + } + + void ScrollControlMoved(object sender, EventArgs e) + { + UpdateScrollOverrideControlBounds(); + } + + private bool _InternalVScrollPositionUpdated = false; + private void VScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.NewValue == e.OldValue && e.Type != ScrollEventType.EndScroll) return; + _InternalVScrollPositionUpdated = true; + WinApi.SendMessage(_ScrollOverrideControl.Handle, (int)WinApi.WindowsMessages.WM_VSCROLL, WinApi.CreateLParam(MapVScrollType(e.Type), e.NewValue), IntPtr.Zero); + _InternalVScrollPositionUpdated = false; + + if (e.Type == ScrollEventType.EndScroll) + UpdateVerticalScrollBarValues(); + } + private bool _InternalHScrollPositionUpdated = false; + private void HScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.NewValue == e.OldValue && e.Type != ScrollEventType.EndScroll) return; + _InternalHScrollPositionUpdated = true; + //Console.WriteLine("{0} Setting Sys_HScrollBar value {1}, {2}", DateTime.Now, e.NewValue, e.Type); + WinApi.SendMessage(_ScrollOverrideControl.Handle, (int)WinApi.WindowsMessages.WM_HSCROLL, WinApi.CreateLParam(MapHScrollType(e.Type), e.NewValue), IntPtr.Zero); + _InternalHScrollPositionUpdated = false; + + if (e.Type == ScrollEventType.EndScroll) + UpdateHorizontalScrollBarValues(); + } + private static int MapVScrollType(ScrollEventType type) + { + if (type == ScrollEventType.EndScroll) + return (int)WinApi.ScrollBarCommands.SB_ENDSCROLL; + else if (type == ScrollEventType.First) + return (int)WinApi.ScrollBarCommands.SB_TOP; + else if (type == ScrollEventType.LargeDecrement) + return (int)WinApi.ScrollBarCommands.SB_PAGEUP; + else if (type == ScrollEventType.LargeIncrement) + return (int)WinApi.ScrollBarCommands.SB_PAGEDOWN; + else if (type == ScrollEventType.Last) + return (int)WinApi.ScrollBarCommands.SB_BOTTOM; + else if (type == ScrollEventType.SmallDecrement) + return (int)WinApi.ScrollBarCommands.SB_LINEUP; + else if (type == ScrollEventType.SmallIncrement) + return (int)WinApi.ScrollBarCommands.SB_LINEDOWN; + else if (type == ScrollEventType.ThumbPosition) + return (int)WinApi.ScrollBarCommands.SB_THUMBPOSITION; + else if (type == ScrollEventType.ThumbTrack) + return (int)WinApi.ScrollBarCommands.SB_THUMBTRACK; + + return 0; + } + private static int MapHScrollType(ScrollEventType type) + { + if (type == ScrollEventType.EndScroll) + return (int)WinApi.ScrollBarCommands.SB_ENDSCROLL; + else if (type == ScrollEventType.First) + return (int)WinApi.ScrollBarCommands.SB_LEFT; + else if (type == ScrollEventType.LargeDecrement) + return (int)WinApi.ScrollBarCommands.SB_PAGELEFT; + else if (type == ScrollEventType.LargeIncrement) + return (int)WinApi.ScrollBarCommands.SB_PAGERIGHT; + else if (type == ScrollEventType.Last) + return (int)WinApi.ScrollBarCommands.SB_RIGHT; + else if (type == ScrollEventType.SmallDecrement) + return (int)WinApi.ScrollBarCommands.SB_LINELEFT; + else if (type == ScrollEventType.SmallIncrement) + return (int)WinApi.ScrollBarCommands.SB_LINERIGHT; + else if (type == ScrollEventType.ThumbPosition) + return (int)WinApi.ScrollBarCommands.SB_THUMBPOSITION; + else if (type == ScrollEventType.ThumbTrack) + return (int)WinApi.ScrollBarCommands.SB_THUMBTRACK; + + return 0; + } + + + private void UpdateVerticalScrollBarValues() + { + if (_InternalVScrollPositionUpdated) return; + WinApi.SCROLLINFO scrollInfo = new WinApi.SCROLLINFO(); + scrollInfo.cbSize = Marshal.SizeOf(scrollInfo); + scrollInfo.fMask = WinApi.ScrollInfoMask.SIF_POS | WinApi.ScrollInfoMask.SIF_RANGE | WinApi.ScrollInfoMask.SIF_PAGE; + if (WinApi.GetScrollInfo(_ScrollOverrideControl.Handle, WinApi.SBOrientation.SB_VERT, ref scrollInfo)) + { + //Console.WriteLine("{0} TRACKPOS={1}", DateTime.Now, scrollInfo.nTrackPos); + if (_VScrollBar.Minimum != scrollInfo.nMin) + _VScrollBar.Minimum = scrollInfo.nMin; + if (_VScrollBar.Maximum != scrollInfo.nMax) + _VScrollBar.Maximum = scrollInfo.nMax; + if (_VScrollBar.Value != scrollInfo.nPos) + _VScrollBar.Value = scrollInfo.nPos; + if (_VScrollBar.LargeChange != scrollInfo.nPage) + _VScrollBar.LargeChange = scrollInfo.nPage; + } + } + private void UpdateHorizontalScrollBarValues() + { + if (_InternalHScrollPositionUpdated) return; + WinApi.SCROLLINFO scrollInfo = new WinApi.SCROLLINFO(); + scrollInfo.cbSize = Marshal.SizeOf(scrollInfo); + scrollInfo.fMask = WinApi.ScrollInfoMask.SIF_POS | WinApi.ScrollInfoMask.SIF_RANGE | WinApi.ScrollInfoMask.SIF_PAGE | WinApi.ScrollInfoMask.SIF_TRACKPOS; + if (WinApi.GetScrollInfo(_ScrollOverrideControl.Handle, WinApi.SBOrientation.SB_HORZ, ref scrollInfo)) + { + //Console.WriteLine("{0} TRACKPOS={1}", DateTime.Now, scrollInfo); + if (_HScrollBar.Minimum != scrollInfo.nMin) + _HScrollBar.Minimum = scrollInfo.nMin; + if (_HScrollBar.Maximum != scrollInfo.nMax) + _HScrollBar.Maximum = scrollInfo.nMax; + if (_HScrollBar.Value != scrollInfo.nPos) + _HScrollBar.Value = scrollInfo.nPos; + if (_HScrollBar.LargeChange != scrollInfo.nPage) + _HScrollBar.LargeChange = scrollInfo.nPage; + } + } + private void ControlScrollBarValueChanged(object sender, ScrollValueChangedEventArgs e) + { + if ((e.ScrollChange & eScrollBarScrollChange.Vertical) == eScrollBarScrollChange.Vertical) + { + UpdateVerticalScrollBarValues(); + } + if ((e.ScrollChange & eScrollBarScrollChange.MouseWheel) == eScrollBarScrollChange.MouseWheel) + { + UpdateVerticalScrollBarValues(); + InvokeDelayed(new MethodInvoker(delegate { UpdateVerticalScrollBarValues(); }), ScrollPositionUpdateDelay); + } + if ((e.ScrollChange & eScrollBarScrollChange.Horizontal) == eScrollBarScrollChange.Horizontal) + { + UpdateHorizontalScrollBarValues(); + } + UpdateScrollBars(); + } + + private void NonClientSizeChanged(object sender, EventArgs e) + { + UpdateScrollBars(); + } + + protected override void OnHandleCreated(EventArgs e) + { + UpdateScrollBars(); + base.OnHandleCreated(e); + } + + #region Child Control WndProc Override + internal static eScrollBarScrollChange MapMessageToScrollChange(int msg) + { + if (msg == (int)WinApi.WindowsMessages.WM_VSCROLL) + return eScrollBarScrollChange.Vertical; + else if (msg == (int)WinApi.WindowsMessages.WM_HSCROLL) + return eScrollBarScrollChange.Horizontal; + else if (msg == (int)WinApi.WindowsMessages.WM_MOUSEWHEEL) + return eScrollBarScrollChange.MouseWheel; + throw new ArgumentException("Message not recognized msg=" + msg.ToString()); + } + #endregion + + #region Invoke Delayed + protected void InvokeDelayed(MethodInvoker method) + { + InvokeDelayed(method, 10); + } + protected void InvokeDelayed(MethodInvoker method, int delayInterval) + { + if (delayInterval <= 0) { method.Invoke(); return; } + + Timer delayedInvokeTimer = new Timer(); + delayedInvokeTimer = new Timer(); + delayedInvokeTimer.Tag = method; + delayedInvokeTimer.Interval = delayInterval; + delayedInvokeTimer.Tick += new EventHandler(DelayedInvokeTimerTick); + delayedInvokeTimer.Start(); + } + void DelayedInvokeTimerTick(object sender, EventArgs e) + { + Timer timer = (Timer)sender; + MethodInvoker method = (MethodInvoker)timer.Tag; + timer.Stop(); + timer.Dispose(); + if (!this.IsDisposed) + method.Invoke(); + } + #endregion + } + + public interface IScrollBarOverrideSupport + { + /// + /// Should be fired when non-client size of the control changes, i.e. when WM_NCCALCSIZE message is received. + /// + event EventHandler NonClientSizeChanged; + /// + /// Should be fired when scroll-bar value on child control changes. + /// + event ScrollValueChangedHandler ScrollBarValueChanged; + /// + /// Should be fired when control receives WM_MOVE message. + /// + event EventHandler ControlMoved; + /// + /// Gets whether control is in design mode. + /// + bool DesignMode { get;} + } + /// + /// Defines arguments for IScrollBarOverrideSupport.ScrollBarValueChanged event. + /// + public class ScrollValueChangedEventArgs : System.EventArgs + { + /// + /// Initializes a new instance of the ScrollValueChangedEventArgs class. + /// + /// + public ScrollValueChangedEventArgs(eScrollBarScrollChange scrollChange) + { + ScrollChange = scrollChange; + } + + public readonly eScrollBarScrollChange ScrollChange; + } + /// + /// Defines information for IScrollBarOverrideSupport.ScrollBarValueChanged event. + /// + [Flags()] + public enum eScrollBarScrollChange + { + Vertical = 1, + Horizontal = 2, + MouseWheel = 4 + } + /// + /// Defines delegate for IScrollBarOverrideSupport.ScrollBarValueChanged event. + /// + /// Sender. + /// Event arguments + public delegate void ScrollValueChangedHandler(object sender, ScrollValueChangedEventArgs e); +} diff --git a/PROMS/DotNetBar Source Code/Controls/ScrollbarSkinner.cs b/PROMS/DotNetBar Source Code/Controls/ScrollbarSkinner.cs new file mode 100644 index 00000000..9bec3609 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/ScrollbarSkinner.cs @@ -0,0 +1,494 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.ScrollBar; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar.Controls +{ + internal class ScrollbarSkinner : IDisposable + { + #region Constructor + private const int ScrollPositionUpdateDelay = 400; + private HScrollBarAdv _HScrollBar = null; + private VScrollBarAdv _VScrollBar = null; + private Control _Thumb = null; + private Control _Parent = null; + public ScrollbarSkinner(Control parent) + { + if(parent == null) + throw new ArgumentNullException("Parent cannot be null"); + if (!(parent is IScrollBarOverrideSupport)) + throw new ArgumentException("parent must implement IScrollBarOverrideSupport interface."); + + _Parent = parent; + + _HScrollBar = new HScrollBarAdv(); + _HScrollBar.Visible = false; + _HScrollBar.Appearance = _ScrollBarAppearance; + _HScrollBar.Scroll += HScrollBarScroll; + _VScrollBar = new VScrollBarAdv(); + _VScrollBar.Visible = false; + _VScrollBar.Appearance = _ScrollBarAppearance; + _VScrollBar.Scroll += VScrollBarScroll; + _Thumb = new Control(); + _Thumb.Visible = false; + _Thumb.BackColor = SystemColors.Window; + + if (_Parent.Parent != null) + { + AttachScrollbars(); + } + WireParent(); + + if(_Parent.IsHandleCreated) + UpdateScrollBars(); + } + + #endregion + + #region Implementation + + private void WireParent() + { + _Parent.ParentChanged += ParentParentChanged; + _Parent.HandleCreated += ParentHandleCreated; + _Parent.Resize += ParentResize; + IScrollBarOverrideSupport sbo = (IScrollBarOverrideSupport)_Parent; + sbo.NonClientSizeChanged += NonClientSizeChanged; + sbo.ScrollBarValueChanged += ControlScrollBarValueChanged; + } + + void ParentResize(object sender, EventArgs e) + { + UpdateScrollBars(); + } + + void ParentHandleCreated(object sender, EventArgs e) + { + UpdateScrollBars(); + } + private void NonClientSizeChanged(object sender, EventArgs e) + { + UpdateScrollBars(); + } + private void ControlScrollBarValueChanged(object sender, ScrollValueChangedEventArgs e) + { + if ((e.ScrollChange & eScrollBarScrollChange.Vertical) == eScrollBarScrollChange.Vertical) + { + UpdateVerticalScrollBarValues(); + } + if ((e.ScrollChange & eScrollBarScrollChange.MouseWheel) == eScrollBarScrollChange.MouseWheel) + { + if (_VScrollBar.Visible) + { + UpdateVerticalScrollBarValues(); + InvokeDelayed(new MethodInvoker(delegate { UpdateVerticalScrollBarValues(); }), ScrollPositionUpdateDelay); + } + else if (_HScrollBar.Visible) + { + UpdateHorizontalScrollBarValues(); + InvokeDelayed(new MethodInvoker(delegate { UpdateHorizontalScrollBarValues(); }), ScrollPositionUpdateDelay); + } + } + if ((e.ScrollChange & eScrollBarScrollChange.Horizontal) == eScrollBarScrollChange.Horizontal) + { + UpdateHorizontalScrollBarValues(); + } + UpdateScrollBars(); + } + private void UnwireParent() + { + _Parent.ParentChanged -= ParentParentChanged; + _Parent.HandleCreated -= ParentHandleCreated; + _Parent.Resize -= ParentResize; + IScrollBarOverrideSupport sbo = (IScrollBarOverrideSupport)_Parent; + sbo.NonClientSizeChanged -= NonClientSizeChanged; + sbo.ScrollBarValueChanged -= ControlScrollBarValueChanged; + } + + void ParentParentChanged(object sender, EventArgs e) + { + AttachScrollbars(); + UpdateScrollBars(); + } + + private bool _UpdatingScrollbars = false; + protected virtual void UpdateScrollBarsDelayed() + { + InvokeDelayed(new MethodInvoker(delegate { UpdateScrollBars(); }), ScrollPositionUpdateDelay); + } + protected virtual void UpdateScrollBars() + { + if (_Parent == null || _Parent.Parent == null || !_Parent.IsHandleCreated || _UpdatingScrollbars) return; + _UpdatingScrollbars = true; + try + { + Control scrollOverrideControl = _Parent; + if (scrollOverrideControl == null || ((IScrollBarOverrideSupport)scrollOverrideControl).DesignMode) + { + if (_HScrollBar.Visible) _HScrollBar.Visible = false; + if (_VScrollBar.Visible) _VScrollBar.Visible = false; + return; + } + WinApi.SCROLLBARINFO psbi = new WinApi.SCROLLBARINFO(); + psbi.cbSize = Marshal.SizeOf(psbi); + WinApi.GetScrollBarInfo(scrollOverrideControl.Handle, (uint)WinApi.eObjectId.OBJID_VSCROLL, ref psbi); + if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + { + Rectangle vsBounds = psbi.rcScrollBar.ToRectangle(); + vsBounds.Location = scrollOverrideControl.Parent.PointToClient(vsBounds.Location); + Rectangle scrollCountrolBounds = scrollOverrideControl.Bounds; + if (!scrollCountrolBounds.Contains(vsBounds)) + { + // We need to guess bounds for best performance and appearance + if (vsBounds.Right > scrollCountrolBounds.Right) + { + vsBounds.X = scrollCountrolBounds.Right - vsBounds.Width; + } + else if (vsBounds.X < scrollCountrolBounds.X) + { + vsBounds.X = 0; + } + } + if (_VScrollBar.Bounds != vsBounds) + { + _VScrollBar.Bounds = vsBounds; + UpdateVerticalScrollBarValues(); + } + if (!_VScrollBar.Visible) + { + _VScrollBar.Visible = true; + _VScrollBar.BringToFront(); + _VScrollBar.Refresh(); + InvokeDelayed(new MethodInvoker(delegate { UpdateVerticalScrollBarValues(); }), ScrollPositionUpdateDelay); + } + else + { + _VScrollBar.BringToFront(); + } + + if (psbi.rgstate[0] == (int)WinApi.eStateFlags.STATE_SYSTEM_UNAVAILABLE) + _VScrollBar.Enabled = false; + else if (!_VScrollBar.Enabled) + _VScrollBar.Enabled = true; + //Console.WriteLine("VscrollBar Bounds detection {0}", vsBounds); + } + else if (_VScrollBar.Visible) + _VScrollBar.Visible = false; + + psbi = new WinApi.SCROLLBARINFO(); + psbi.cbSize = Marshal.SizeOf(psbi); + WinApi.GetScrollBarInfo(scrollOverrideControl.Handle, (uint)WinApi.eObjectId.OBJID_HSCROLL, ref psbi); + if (psbi.rgstate[0] != (int)WinApi.eStateFlags.STATE_SYSTEM_INVISIBLE) + { + Rectangle hsBounds = psbi.rcScrollBar.ToRectangle(); + hsBounds.Location = scrollOverrideControl.Parent.PointToClient(hsBounds.Location); + Rectangle scrollCountrolBounds = scrollOverrideControl.Bounds; + if (!scrollCountrolBounds.Contains(hsBounds)) + { + // We need to guess bounds for best performance and appearance + if (hsBounds.Bottom > scrollCountrolBounds.Bottom) + { + hsBounds.Y = scrollCountrolBounds.Bottom - hsBounds.Height; + } + } + if (_VScrollBar.Visible && hsBounds.Width == scrollCountrolBounds.Width) + hsBounds.Width -= _VScrollBar.Width; + if (_HScrollBar.Bounds != hsBounds) + { + _HScrollBar.Bounds = hsBounds; + UpdateHorizontalScrollBarValues(); + } + if (!_HScrollBar.Visible) + { + _HScrollBar.Visible = true; + _HScrollBar.BringToFront(); + _HScrollBar.Refresh(); + InvokeDelayed(new MethodInvoker(delegate { UpdateHorizontalScrollBarValues(); }), ScrollPositionUpdateDelay); + } + else + { + _HScrollBar.BringToFront(); + } + + if (psbi.rgstate[0] == (int)WinApi.eStateFlags.STATE_SYSTEM_UNAVAILABLE) + _HScrollBar.Enabled = false; + else if (!_HScrollBar.Enabled) + _HScrollBar.Enabled = true; + } + else if (_HScrollBar.Visible) + _HScrollBar.Visible = false; + + if (_HScrollBar.Visible && _VScrollBar.Visible) + { + _Thumb.Bounds = new Rectangle(_VScrollBar.Left, _VScrollBar.Bounds.Bottom, _VScrollBar.Width, _HScrollBar.Height); + _Thumb.Visible = true; + _Thumb.BringToFront(); + } + else + { + _Thumb.Visible = false; + } + } + finally + { + _UpdatingScrollbars = false; + } + } + private void AttachScrollbars() + { + DetachScrollbars(); + + Control host = _Parent.Parent; + if (host != null) + { + if (host is TableLayoutPanel) + { + while (host is TableLayoutPanel) + { + host = host.Parent; + } + } + if (host != null) + { + host.Controls.Add(_VScrollBar); + host.Controls.Add(_HScrollBar); + host.Controls.Add(_Thumb); + } + } + } + + private void DetachScrollbars() + { + if (_VScrollBar.Parent != null) + _VScrollBar.Parent.Controls.Remove(_VScrollBar); + if (_HScrollBar.Parent != null) + _HScrollBar.Parent.Controls.Remove(_HScrollBar); + if (_Thumb.Parent != null) + _Thumb.Parent.Controls.Remove(_Thumb); + + _VScrollBar.Visible = false; + _HScrollBar.Visible = false; + _Thumb.Visible = false; + } + + private eScrollBarAppearance _ScrollBarAppearance = eScrollBarAppearance.Default; + /// + /// Gets or sets the scroll-bar visual style. + /// + [DefaultValue(eScrollBarAppearance.Default), Category("Appearance"), Description("Gets or sets the scroll-bar visual style.")] + public eScrollBarAppearance ScrollBarAppearance + { + get { return _ScrollBarAppearance; } + set + { + _ScrollBarAppearance = value; + OnScrollBarAppearanceChanged(); + } + } + private void OnScrollBarAppearanceChanged() + { + if (_VScrollBar != null) _VScrollBar.Appearance = _ScrollBarAppearance; + if (_HScrollBar != null) _HScrollBar.Appearance = _ScrollBarAppearance; + } + + private bool _InternalVScrollPositionUpdated = false; + private void VScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.NewValue == e.OldValue && e.Type != ScrollEventType.EndScroll) return; + _InternalVScrollPositionUpdated = true; + //Console.WriteLine("{0} Setting Sys_VScrollBar value {1}, {2}", DateTime.Now, e.NewValue, e.Type); + if (e.Type == ScrollEventType.ThumbTrack) // We need to send this becouse ScrollableControl internally will get the current scroll position using GetScrollInfo instead from window message LParam + { + WinApi.SCROLLINFO si = new WinApi.SCROLLINFO(); + si.nTrackPos = e.NewValue; + si.nPos = e.NewValue; + si.fMask = WinApi.ScrollInfoMask.SIF_POS; + si.cbSize = Marshal.SizeOf(si); + WinApi.SetScrollInfo(_Parent.Handle, WinApi.SBOrientation.SB_VERT, ref si, false); + } + WinApi.SendMessage(_Parent.Handle, (int)WinApi.WindowsMessages.WM_VSCROLL, WinApi.CreateLParam(MapVScrollType(e.Type), e.NewValue), IntPtr.Zero); + _InternalVScrollPositionUpdated = false; + + if (e.Type == ScrollEventType.EndScroll) + UpdateVerticalScrollBarValues(); + } + private bool _InternalHScrollPositionUpdated = false; + private void HScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.NewValue == e.OldValue && e.Type != ScrollEventType.EndScroll) return; + _InternalHScrollPositionUpdated = true; + //Console.WriteLine("{0} Setting Sys_HScrollBar value {1}, {2}", DateTime.Now, e.NewValue, e.Type); + if (e.Type == ScrollEventType.ThumbTrack) // We need to send this becouse ScrollableControl internally will get the current scroll position using GetScrollInfo instead from window message LParam + { + WinApi.SCROLLINFO si = new WinApi.SCROLLINFO(); + si.nTrackPos = e.NewValue; + si.nPos = e.NewValue; + si.fMask = WinApi.ScrollInfoMask.SIF_POS; + si.cbSize = Marshal.SizeOf(si); + WinApi.SetScrollInfo(_Parent.Handle, WinApi.SBOrientation.SB_HORZ, ref si, false); + } + WinApi.SendMessage(_Parent.Handle, (int)WinApi.WindowsMessages.WM_HSCROLL, WinApi.CreateLParam(MapHScrollType(e.Type), e.NewValue), IntPtr.Zero); + _InternalHScrollPositionUpdated = false; + + if (e.Type == ScrollEventType.EndScroll) + UpdateHorizontalScrollBarValues(); + } + private static int MapVScrollType(ScrollEventType type) + { + if (type == ScrollEventType.EndScroll) + return (int)WinApi.ScrollBarCommands.SB_ENDSCROLL; + else if (type == ScrollEventType.First) + return (int)WinApi.ScrollBarCommands.SB_TOP; + else if (type == ScrollEventType.LargeDecrement) + return (int)WinApi.ScrollBarCommands.SB_PAGEUP; + else if (type == ScrollEventType.LargeIncrement) + return (int)WinApi.ScrollBarCommands.SB_PAGEDOWN; + else if (type == ScrollEventType.Last) + return (int)WinApi.ScrollBarCommands.SB_BOTTOM; + else if (type == ScrollEventType.SmallDecrement) + return (int)WinApi.ScrollBarCommands.SB_LINEUP; + else if (type == ScrollEventType.SmallIncrement) + return (int)WinApi.ScrollBarCommands.SB_LINEDOWN; + else if (type == ScrollEventType.ThumbPosition) + return (int)WinApi.ScrollBarCommands.SB_THUMBPOSITION; + else if (type == ScrollEventType.ThumbTrack) + return (int)WinApi.ScrollBarCommands.SB_THUMBTRACK; + + return 0; + } + private static int MapHScrollType(ScrollEventType type) + { + if (type == ScrollEventType.EndScroll) + return (int)WinApi.ScrollBarCommands.SB_ENDSCROLL; + else if (type == ScrollEventType.First) + return (int)WinApi.ScrollBarCommands.SB_LEFT; + else if (type == ScrollEventType.LargeDecrement) + return (int)WinApi.ScrollBarCommands.SB_PAGELEFT; + else if (type == ScrollEventType.LargeIncrement) + return (int)WinApi.ScrollBarCommands.SB_PAGERIGHT; + else if (type == ScrollEventType.Last) + return (int)WinApi.ScrollBarCommands.SB_RIGHT; + else if (type == ScrollEventType.SmallDecrement) + return (int)WinApi.ScrollBarCommands.SB_LINELEFT; + else if (type == ScrollEventType.SmallIncrement) + return (int)WinApi.ScrollBarCommands.SB_LINERIGHT; + else if (type == ScrollEventType.ThumbPosition) + return (int)WinApi.ScrollBarCommands.SB_THUMBPOSITION; + else if (type == ScrollEventType.ThumbTrack) + return (int)WinApi.ScrollBarCommands.SB_THUMBTRACK; + + return 0; + } + + + private void UpdateVerticalScrollBarValues() + { + if (_InternalVScrollPositionUpdated) return; + WinApi.SCROLLINFO scrollInfo = new WinApi.SCROLLINFO(); + scrollInfo.cbSize = Marshal.SizeOf(scrollInfo); + scrollInfo.fMask = WinApi.ScrollInfoMask.SIF_POS | WinApi.ScrollInfoMask.SIF_RANGE | WinApi.ScrollInfoMask.SIF_PAGE; + if (WinApi.GetScrollInfo(_Parent.Handle, WinApi.SBOrientation.SB_VERT, ref scrollInfo)) + { + //Console.WriteLine("{0} scrollInfo={1}", DateTime.Now, scrollInfo.ToString()); + if (_VScrollBar.Minimum != scrollInfo.nMin) + _VScrollBar.Minimum = scrollInfo.nMin; + if (_VScrollBar.Maximum != scrollInfo.nMax) + _VScrollBar.Maximum = scrollInfo.nMax; + if (_VScrollBar.Value != scrollInfo.nPos) + _VScrollBar.Value = scrollInfo.nPos; + if (_VScrollBar.LargeChange != scrollInfo.nPage) + _VScrollBar.LargeChange = scrollInfo.nPage; + } + } + private void UpdateHorizontalScrollBarValues() + { + if (_InternalHScrollPositionUpdated) return; + WinApi.SCROLLINFO scrollInfo = new WinApi.SCROLLINFO(); + scrollInfo.cbSize = Marshal.SizeOf(scrollInfo); + scrollInfo.fMask = WinApi.ScrollInfoMask.SIF_POS | WinApi.ScrollInfoMask.SIF_RANGE | WinApi.ScrollInfoMask.SIF_PAGE | WinApi.ScrollInfoMask.SIF_TRACKPOS; + if (WinApi.GetScrollInfo(_Parent.Handle, WinApi.SBOrientation.SB_HORZ, ref scrollInfo)) + { + //Console.WriteLine("{0} TRACKPOS={1}", DateTime.Now, scrollInfo); + if (_HScrollBar.Minimum != scrollInfo.nMin) + _HScrollBar.Minimum = scrollInfo.nMin; + if (_HScrollBar.Maximum != scrollInfo.nMax) + _HScrollBar.Maximum = scrollInfo.nMax; + if (_HScrollBar.Value != scrollInfo.nPos) + _HScrollBar.Value = scrollInfo.nPos; + if (_HScrollBar.LargeChange != scrollInfo.nPage) + _HScrollBar.LargeChange = scrollInfo.nPage; + } + } + + public VScrollBarAdv VScrollBar + { + get + { + return _VScrollBar; + } + } + + public HScrollBarAdv HScrollBar + { + get + { + return _HScrollBar; + } + } + + #endregion + + #region Invoke Delayed + protected void InvokeDelayed(MethodInvoker method) + { + InvokeDelayed(method, 10); + } + protected void InvokeDelayed(MethodInvoker method, int delayInterval) + { + if (delayInterval <= 0) { method.Invoke(); return; } + + Timer delayedInvokeTimer = new Timer(); + delayedInvokeTimer = new Timer(); + delayedInvokeTimer.Tag = method; + delayedInvokeTimer.Interval = delayInterval; + delayedInvokeTimer.Tick += new EventHandler(DelayedInvokeTimerTick); + delayedInvokeTimer.Start(); + } + void DelayedInvokeTimerTick(object sender, EventArgs e) + { + Timer timer = (Timer)sender; + MethodInvoker method = (MethodInvoker)timer.Tag; + timer.Stop(); + timer.Dispose(); + if (!this.IsDisposed) + method.Invoke(); + } + #endregion + + private bool _IsDisposed = false; + + public bool IsDisposed + { + get + { + return _IsDisposed; + } + } + public void Dispose() + { + UnwireParent(); + if(_VScrollBar.Parent == null) + _VScrollBar.Dispose(); + if (_HScrollBar.Parent == null) + _HScrollBar.Dispose(); + if (_Thumb.Parent == null) + _Thumb.Dispose(); + _IsDisposed = true; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SideNav.ico b/PROMS/DotNetBar Source Code/Controls/SideNav.ico new file mode 100644 index 00000000..61cd1bad Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/SideNav.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/SideNav/OfficeSideNavItemPainter.cs b/PROMS/DotNetBar Source Code/Controls/SideNav/OfficeSideNavItemPainter.cs new file mode 100644 index 00000000..0b4cad0c --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SideNav/OfficeSideNavItemPainter.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using DevComponents.DotNetBar.Controls; +using System.Drawing.Imaging; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class OfficeSideNavItemPainter : SideNavItemPainter + { + /// + /// Paints ListBoxItem. + /// + /// Provides arguments for the operation. + public override void Paint(SideNavItemRendererEventArgs e) + { + Graphics g = e.ItemPaintArgs.Graphics; + SideNavItem item = e.Item; + SideNavStrip navStrip = e.ItemPaintArgs.ContainerControl as SideNavStrip; + + SideNavItemColorTable table = ColorTable.SideNav.SideNavItem; + SideNavItemStateColorTable ct = item.IsMouseOver ? table.MouseOver : table.Default; + if (item.Checked) + ct = table.Selected; + else if (item.IsMouseDown) + ct = table.Pressed; + + Rectangle r = item.Bounds; + Rectangle textBounds = item.TextRenderBounds; + Rectangle imageBounds = item.ImageRenderBounds; + CompositeImage image = item.GetImage(); + + if (ct.BackColors != null && ct.BackColors.Length > 0 || item.BackColors != null && item.BackColors.Length > 0) + { + using (Brush brush = DisplayHelp.CreateBrush(r, (item.BackColors != null && item.BackColors.Length > 0) ? item.BackColors : ct.BackColors, ct.BackColorsGradientAngle, ct.BackColorsPositions)) + { + DisplayHelp.FillRoundedRectangle(g, brush, r, ct.CornerRadius); + //g.FillRectangle(brush, r); + } + } + + Region oldClip = null; + // For top item do not draw the top border + if (r.Y == 0 && item.Checked) + { + oldClip = g.Clip; + g.SetClip(new Rectangle(r.X, r.Y, r.Width, 1), CombineMode.Exclude); + } + if (item.BorderColors != null && item.BorderColors.Length > 0) + DisplayHelp.DrawRoundedRectangle(g, r, item.BorderColors, ct.CornerRadius); + else if (ct.BorderColors != null && ct.BorderColors.Length > 0) + DisplayHelp.DrawRoundedRectangle(g, r, ct.BorderColors, ct.CornerRadius); + if (r.Y == 0 && item.Checked) + { + g.Clip = oldClip; + oldClip.Dispose(); + } + + Color textColor = ct.TextColor; + bool hasImage = false; + if ((image != null || !string.IsNullOrEmpty(item.SymbolRealized)) && item.ButtonStyle != eButtonStyle.TextOnlyAlways) + { + if (imageBounds.IsEmpty) + imageBounds = GetImageRectangle(item, image); + if (textBounds.IsEmpty) + textBounds = GetTextRectangle(item, image, imageBounds); + hasImage = true; + + } + else if (textBounds.IsEmpty) + { + textBounds = r; + r.X += 2; + r.Width -= 2; + } + + if (!string.IsNullOrEmpty(item.SymbolRealized)) + { + Color symbolColor = item.SymbolColor; + if (symbolColor.IsEmpty) symbolColor = textColor; + TextDrawing.DrawStringLegacy(g, item.SymbolRealized, Symbols.GetFont(item.SymbolSize, item.SymbolSet), + symbolColor, new Rectangle(imageBounds.X, imageBounds.Y + imageBounds.Height / 2, 0, 0), eTextFormat.Default | eTextFormat.VerticalCenter); + } + else if (image != null) + { + if (!item.IsMouseOver && item.HotTrackingStyle == eHotTrackingStyle.Color) + { + // Draw gray-scale image for this hover style... + float[][] array = new float[5][]; + array[0] = new float[5] { 0.2125f, 0.2125f, 0.2125f, 0, 0 }; + array[1] = new float[5] { 0.5f, 0.5f, 0.5f, 0, 0 }; + array[2] = new float[5] { 0.0361f, 0.0361f, 0.0361f, 0, 0 }; + array[3] = new float[5] { 0, 0, 0, 1, 0 }; + array[4] = new float[5] { 0.2f, 0.2f, 0.2f, 0, 1 }; + ColorMatrix grayMatrix = new ColorMatrix(array); + ImageAttributes att = new ImageAttributes(); + att.SetColorMatrix(grayMatrix); + image.DrawImage(g, imageBounds, 0, 0, image.ActualWidth, image.ActualHeight, GraphicsUnit.Pixel, att); + } + else + { + image.DrawImage(g, imageBounds); + } + } + item.ImageRenderBounds = imageBounds; + + if (!string.IsNullOrEmpty(item.Text) && (item.ButtonStyle!= eButtonStyle.Default || !hasImage)) + { + if (!item.ForeColor.IsEmpty) textColor = item.ForeColor; + Font font = e.ItemPaintArgs.Font; + if (item.TextMarkupBody == null) + { + eTextFormat textFormat = eTextFormat.Default | eTextFormat.VerticalCenter; + //if (item.TextAlignment == eButtonTextAlignment.Center) + //{ + // textFormat |= eTextFormat.HorizontalCenter; + //} + //else if (item.TextAlignment == eButtonTextAlignment.Right) + //{ + // textFormat |= eTextFormat.Right; + //} + TextDrawing.DrawString(g, item.Text, font, textColor, textBounds, textFormat); + } + else + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, textColor, e.ItemPaintArgs.RightToLeft); + d.HotKeyPrefixVisible = false; + d.ContextObject = item; + Rectangle mr = new Rectangle(textBounds.X, textBounds.Y + (textBounds.Height - item.TextMarkupBody.Bounds.Height) / 2, item.TextMarkupBody.Bounds.Width, item.TextMarkupBody.Bounds.Height); + item.TextMarkupBody.Bounds = mr; + item.TextMarkupBody.Render(d); + } + + } + item.TextRenderBounds = textBounds; + } + + private Rectangle GetImageRectangle(SideNavItem item, CompositeImage image) + { + Rectangle imageRect = Rectangle.Empty; + // Calculate image position + if (image != null || !string.IsNullOrEmpty(item.SymbolRealized)) + { + Size imageSize = item.ImageSize; + + if (item.ImagePosition == eImagePosition.Top || item.ImagePosition == eImagePosition.Bottom) + imageRect = new Rectangle(item.ImageDrawRect.X, item.ImageDrawRect.Y, item.DisplayRectangle.Width, item.ImageDrawRect.Height); + else if (item.ImagePosition == eImagePosition.Left) + { + if (item.ButtonStyle == eButtonStyle.Default) + return new Rectangle(item.Bounds.X + (item.Bounds.Width - imageSize.Width)/2, + item.Bounds.Y + (item.Bounds.Height - imageSize.Height)/2, imageSize.Width, imageSize.Height); + else + imageRect = new Rectangle(item.ImageDrawRect.X + 4, item.ImageDrawRect.Y, + item.ImageDrawRect.Width, + item.ImageDrawRect.Height); + } + else if (item.ImagePosition == eImagePosition.Right) + imageRect = new Rectangle(item.ImageDrawRect.X + item.ImagePaddingHorizontal + 4, + item.ImageDrawRect.Y, item.ImageDrawRect.Width, item.ImageDrawRect.Height); + imageRect.Offset(item.DisplayRectangle.Left, item.DisplayRectangle.Top); + imageRect.Offset((imageRect.Width - imageSize.Width) / 2, (imageRect.Height - imageSize.Height) / 2); + + imageRect.Width = imageSize.Width; + imageRect.Height = imageSize.Height; + } + + return imageRect; + } + + private Rectangle GetTextRectangle(SideNavItem item, CompositeImage image, Rectangle imageBounds) + { + Rectangle itemRect = item.DisplayRectangle; + Rectangle textRect = item.TextDrawRect; + + if (item.ImagePosition == eImagePosition.Top || item.ImagePosition == eImagePosition.Bottom) + { + textRect = new Rectangle(1, textRect.Y, itemRect.Width - 2, textRect.Height); + } + textRect.Offset(itemRect.Left, itemRect.Top); + + if (item.ImagePosition == eImagePosition.Left) + textRect.X = imageBounds.Right + item.ImagePaddingHorizontal; + + if (textRect.Right > itemRect.Right) + textRect.Width = itemRect.Right - textRect.Left; + + return textRect; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SideNav/SideNav.cs b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNav.cs new file mode 100644 index 00000000..a8982757 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNav.cs @@ -0,0 +1,776 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Windows.Forms.VisualStyles; +using DevComponents.DotNetBar.Metro; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents SideNav control to create "hamburger" menus. + /// + [ToolboxBitmap(typeof(SideNav), "Controls.SideNav.ico"), ToolboxItem(true),Designer("DevComponents.DotNetBar.Design.SideNavDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.Runtime.InteropServices.ComVisible(false)] + public class SideNav : System.Windows.Forms.ContainerControl + { + #region Constructor + private SideNavStrip _Strip = null; + private Bar _TitleBar = null; + private LabelItem _TitleLabel = null; + private ButtonItem _CloseButton = null; + private ButtonItem _MaximizeButton = null; + private ButtonItem _RestoreButton = null; + private Control _Splitter = null; + public SideNav() + { + this.SetStyle(ControlStyles.AllPaintingInWmPaint + | ControlStyles.ResizeRedraw + | DisplayHelp.DoubleBufferFlag + | ControlStyles.UserPaint + | ControlStyles.Opaque + , true); + + this.Padding = new System.Windows.Forms.Padding(1); + + _Splitter = new Control(); + _Splitter.Width = 4; + _Splitter.Name = "splitter"; + _Splitter.Cursor = Cursors.VSplit; + _Splitter.Dock = DockStyle.Right; + _Splitter.MouseMove += SplitterMouseMove; + _Splitter.MouseDown += SplitterMouseDown; + this.Controls.Add(_Splitter); + + + // Title bar and fold/extend buttons + Bar titleBar = new Bar(); + titleBar.Name = "titleBar"; + titleBar.AntiAlias = true; + titleBar.Name = "titleBar"; + titleBar.PaddingBottom = 7; + titleBar.PaddingTop = 5; + titleBar.PaddingLeft = 6; + titleBar.RoundCorners = false; + titleBar.Dock = DockStyle.Top; + titleBar.Stretch = true; + titleBar.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + titleBar.TabIndex = 0; + titleBar.TabStop = false; + titleBar.BarType = eBarType.StatusBar; + titleBar.ItemsContainer.OverflowEnabled = false; + LabelItem titleLabel=new LabelItem(); + titleLabel.Name = "titleLabel"; + titleLabel.Text = "Title"; + titleLabel.FontBold = true; + _TitleLabel = titleLabel; + titleBar.Items.Add(titleLabel); + _TitleBar = titleBar; + _CloseButton = new ButtonItem("openCloseButton"); + _CloseButton.Symbol = "\uf0d9"; + _CloseButton.ImagePaddingHorizontal = 18; + _CloseButton.ItemAlignment= eItemAlignment.Far; + _CloseButton.SymbolSize = 12f; + _CloseButton.Click+=CloseButtonClick; + titleBar.Items.Add(_CloseButton); + _MaximizeButton = new ButtonItem("maximizeButton"); + _MaximizeButton.Symbol = "\uf090"; + _MaximizeButton.ItemAlignment = eItemAlignment.Far; + _MaximizeButton.SymbolSize = 12f; + _MaximizeButton.Click += MaximizeButtonClick; + titleBar.Items.Add(_MaximizeButton); + _RestoreButton = new ButtonItem("restoreButton"); + _RestoreButton.Symbol = "\uf100"; + _RestoreButton.ItemAlignment = eItemAlignment.Far; + _RestoreButton.SymbolSize = 12f; + _RestoreButton.Click += RestoreButtonClick; + _RestoreButton.Visible = false; + titleBar.Items.Add(_RestoreButton); + + this.Controls.Add(titleBar); + + _Strip = new SideNavStrip(); + _Strip.Dock = DockStyle.Left; + _Strip.AutoSize = true; + _Strip.AutoSyncSizeOrientation = eOrientation.Horizontal; + _Strip.ButtonCheckedChanged += StripButtonCheckedChanged; + + //SideNavItem menuItem=new SideNavItem(); + //menuItem.Name = "menuItem"; + //menuItem.Text = "Menu"; + //menuItem.Symbol = "\uf0c9"; + //menuItem.IsSystemMenu = true; + //_Strip.Items.Add(menuItem); + + //Separator sep = new Separator(); + //sep.SeparatorOrientation = eDesignMarkerOrientation.Vertical; + //sep.FixedSize = new Size(3,1); + //sep.Padding.Left = 6; + //sep.Padding.Right = 6; + //_Strip.Items.Add(sep); + + //SideNavItem item = new SideNavItem(); + //item.Text = "Home"; + //item.Symbol = "\uf015"; + //_Strip.Items.Add(item); + //SideNavPanel panel=new SideNavPanel(); + //panel.Dock = DockStyle.Fill; + //this.Controls.Add(panel); + //item.Panel = panel; + + //item = new SideNavItem(); + //item.Text = "Explore"; + //item.Symbol = "\uf002"; + //_Strip.Items.Add(item); + + //ButtonItem button=new ButtonItem(); + //button.Text = "Button"; + //button.Symbol = "\uf003"; + //button.ButtonStyle = eButtonStyle.ImageAndText; + //_Strip.Items.Add(button); + + this.Controls.Add(_Strip); + _Strip.Width = 48; + + StyleManager.Register(this); + UpdateColors(); + } + + protected override void Dispose(bool disposing) + { + if (_IsMaximized && disposing && this.Parent!=null) + { + this.Parent.Resize -= ParentResize; + } + base.Dispose(disposing); + } + + #endregion + + #region Implementation + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + UpdateColors(); + } + /// + /// Updates the control colors from the global color table. + /// + public void UpdateColors() + { + SideNavColorTable ct = GetColorTable(); + _TitleBar.BackColor = ct.TitleBackColor; + _TitleBar.BorderColors = ct.TitleBorderColors; + this.Invalidate(true); + } + + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + DisplayHelp.FillRectangle(g,this.ClientRectangle, this.BackColor); + SideNavColorTable table = GetColorTable(); + DisplayHelp.DrawRoundedRectangle(g, this.ClientRectangle, table.BorderColors, 0); + } + + private SideNavColorTable GetColorTable() + { + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.SideNav; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetDesignMode() + { + _Strip.SetDesignMode(true); + } + + private bool _EnableSplitter = true; + /// + /// Indicates whether splitter that is located on right hand side of open control is visible and enabled. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether splitter that is located on right hand side of open control is visible and enabled.")] + public bool EnableSplitter + { + get { return _EnableSplitter; } + set + { + if (_EnableSplitter != value) + { + bool oldValue = _EnableSplitter; + _EnableSplitter = value; + OnEnableSplitterChanged(value, oldValue); + } + } + } + protected virtual void OnEnableSplitterChanged(bool newValue, bool oldValue) + { + _Splitter.Visible = newValue; + } + + private bool _EnableClose = true; + /// + /// Indicates whether button which folds/closes the control is visible. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether button which folds/closes the control is visible.")] + public bool EnableClose + { + get { return _EnableClose; } + set + { + if (_EnableClose != value) + { + bool oldValue = _EnableClose; + _EnableClose = value; + OnEnableCloseChanged(value, oldValue); + } + } + } + protected virtual void OnEnableCloseChanged(bool newValue, bool oldValue) + { + _CloseButton.Visible = newValue; + _TitleBar.RecalcLayout(); + } + + private bool _EnableMaximize = true; + // + /// Indicates whether buttons which maximize and restore the control are visible. + /// + [DefaultValue(true), Category("Apeparance"), Description("Indicates whether buttons which maximize and restore the control are visible.")] + public bool EnableMaximize + { + get { return _EnableMaximize; } + set + { + if (_EnableMaximize != value) + { + bool oldValue = _EnableMaximize; + _EnableMaximize = value; + OnEnableMaximizeChanged(value, oldValue); + } + } + } + protected virtual void OnEnableMaximizeChanged(bool newValue, bool oldValue) + { + if (!newValue) + { + _MaximizeButton.Visible = false; + _RestoreButton.Visible = false; + } + else + { + if (_IsMaximized) + _RestoreButton.Visible = true; + else + _MaximizeButton.Visible = true; + } + _TitleBar.RecalcLayout(); + } + + /// + /// Returns collection of items on a bar. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] + public SubItemsCollection Items + { + get + { + return _Strip.Items; + } + } + + private void CloseButtonClick(object sender, EventArgs e) + { + Close(eEventSource.Mouse); + } + + private void MaximizeButtonClick(object sender, EventArgs e) + { + Maximize(eEventSource.Mouse); + } + + private bool _IsMaximized = false; + private int _RestoredWidth = 0; + /// + /// Maximizes control width so it fills up space to the right of the control. + /// + /// Source of the event. + public void Maximize(eEventSource source) + { + if(_IsMaximized) return; + + if (this.Parent == null) + return; + if (this.Bounds.Right >= this.Parent.ClientRectangle.Right) + return; + + CancelSourceEventArgs args=new CancelSourceEventArgs(source); + OnBeforeMaximize(args); + if(args.Cancel) return; + + _IsMaximized = true; + int maxWidth = GetMaxWidth(); + _RestoredWidth = this.Width; + BarFunctions.AnimateControl(this, true, _AnimationTime, this.Bounds, new Rectangle(this.Location, new Size(maxWidth, this.Height))); + _RestoreButton.Visible = true; + _MaximizeButton.Visible = false; + _TitleBar.RecalcLayout(); + _Splitter.Visible = false; + this.Invalidate(); + this.Parent.Resize += ParentResize; + } + + void ParentResize(object sender, EventArgs e) + { + if (this.Parent.Width > 0) + this.Width = GetMaxWidth(); + } + + private int GetMaxWidth() + { + int width = this.Width + this.Parent.ClientRectangle.Right - this.Bounds.Right; + if (this.Parent is MetroAppForm) + { + MetroAppForm form = (MetroAppForm) this.Parent; + if (form.BorderThickness.Right > 0) + width -= (int)form.BorderThickness.Right; + else + width -= 3; + } + + return width; + } + + private void RestoreButtonClick(object sender, EventArgs e) + { + Restore(eEventSource.Mouse); + } + + /// + /// Restores the control to previous size if it was maximized before. + /// + /// Source of event. + public void Restore(eEventSource source) + { + if (!_IsMaximized || _RestoredWidth == 0) return; + _IsMaximized = false; + + CancelSourceEventArgs args = new CancelSourceEventArgs(source); + OnBeforeRestore(args); + if (args.Cancel) return; + + BarFunctions.AnimateControl(this, true, _AnimationTime, this.Bounds, new Rectangle(this.Location, new Size(_RestoredWidth, this.Height))); + _RestoredWidth = 0; + _RestoreButton.Visible = false; + _MaximizeButton.Visible = true; + _TitleBar.RecalcLayout(); + _Splitter.Visible = _EnableSplitter; + this.Invalidate(); + if(this.Parent!=null) + this.Parent.Resize -= ParentResize; + } + + private bool _IsOpen = true; + private int _OpenWidth = 0; + /// + /// Gets or sets whether control is closed, i.e. whether selected item panel is shown or not. When closed + /// any selected item is unselected and selected panel hidden. + /// + [DefaultValue(false), Browsable(false)] + public bool IsClosed + { + get { return !_IsOpen; } + set + { + if (value) + { + if(_IsOpen) + Close(eEventSource.Code); + } + else + { + if (!_IsOpen) + { + SideNavItem item = FirstVisibleSideNavItem??_LastOpenItem; + if (item != null) + Open(item, eEventSource.Code); + } + } + } + } + + private SideNavItem FirstVisibleSideNavItem + { + get + { + for (int i = 0; i < _Strip.Items.Count; i++) + { + if (_Strip.Items[i] is SideNavItem && _Strip.Items[i].Visible) + return (SideNavItem)_Strip.Items[i]; + } + return null; + } + } + + private void StripButtonCheckedChanged(object sender, EventArgs e) + { + if (sender is SideNavItem && ((SideNavItem)sender).Checked) + { + OnSelectedItemChanged(EventArgs.Empty); + if (!_IsOpen) + Open((SideNavItem)sender, eEventSource.Code); + } + } + + /// + /// Opens the control, i.e. expands it, selects specified item and shows its associated panel. + /// + /// Item to select. + /// Source of the event. + public void Open(SideNavItem item, eEventSource source) + { + if (item == null) + throw new ArgumentException("item must be set to valid item to select"); + + if (_IsOpen) return; + + CancelSourceEventArgs args=new CancelSourceEventArgs(source, item); + OnBeforeOpen(args); + if(args.Cancel) return; + + if (!item.Checked) + item.Checked = true; + BarFunctions.AnimateControl(this, true, _AnimationTime, this.Bounds, new Rectangle(this.Location, new Size(_OpenWidth, this.Height))); + _IsOpen = true; + _Splitter.Visible = _EnableSplitter; + this.Invalidate(); + } + + private SideNavItem _LastOpenItem = null; + /// + /// Closes the control, i.e. unselects any selected item, hide its associated panel and folds the control. + /// + /// Source of the event. + public void Close(eEventSource source) + { + if(!_IsOpen) return; + + CancelSourceEventArgs args = new CancelSourceEventArgs(source); + OnBeforeClose(args); + if (args.Cancel) return; + + _OpenWidth = this.Width; + int closedWidth = _Strip.Width + this.Padding.Horizontal; + _Splitter.Visible = false; + BarFunctions.AnimateControl(this, true, _AnimationTime, this.Bounds, new Rectangle(this.Location, new Size(closedWidth, this.Height))); + _IsOpen = false; + if (_Strip.SelectedItem != null) + { + _LastOpenItem = _Strip.SelectedItem; + _Strip.SelectedItem.Checked = false; + } + else + _LastOpenItem = null; + + this.Invalidate(); + } + + private bool _IsMenuExpanded = true; + /// + /// Indicates whether side menu is expanded, i.e. shows both image and text. When menu is collapsed only image is shown. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether side menu is expanded, i.e. shows both image and text. When menu is collapsed only image is shown.")] + public bool IsMenuExpanded + { + get { return _IsMenuExpanded; } + set + { + if (_IsMenuExpanded != value) + { + bool oldValue = _IsMenuExpanded; + _IsMenuExpanded = value; + OnIsMenuExpandedChanged(value, oldValue); + } + } + } + + protected virtual void OnIsMenuExpandedChanged(bool newValue, bool oldValue) + { + ExpandMenu(newValue); + OnIsMenuExpandedChanged(EventArgs.Empty); + } + + /// + /// Occurs when IsMenuExpanded property has changed its value. + /// + [Description("Occurs when IsMenuExpanded property has changed.")] + public event EventHandler IsMenuExpandedChanged; + + /// + /// Raises IsMenuExpandedChanged event. + /// + /// Provides event arguments. + protected virtual void OnIsMenuExpandedChanged(EventArgs e) + { + EventHandler h = IsMenuExpandedChanged; + if (h != null) + h(this, e); + } + + private bool _IsMenuExpandedDelayedSet = false; + /// + /// Expands or collapses the control items menu. + /// + /// + private void ExpandMenu(bool expand) + { + if (!this.IsHandleCreated) + { + _IsMenuExpandedDelayedSet = true; + return; + } + for (int i = 0; i < _Strip.Items.Count; i++) + { + ButtonItem button = _Strip.Items[i] as ButtonItem; + if (button != null) + { + button.ButtonStyle = (expand ? eButtonStyle.ImageAndText : eButtonStyle.Default); + } + } + _Strip.RecalcLayout(); + if (!_IsOpen) + this.Width = _Strip.Width + this.Padding.Horizontal; + } + + private int _AnimationTime = 250; + /// + /// Indicates the animation time in milliseconds for operations that perform visual animation of transition. Set to zero to disable animation. + /// + [DefaultValue(250), Category("Behavior"), Description("Indicates the animation time in milliseconds for operations that perform visual animation of transition. Set to zero to disable animation.")] + public int AnimationTime + { + get { return _AnimationTime; } + set + { + if (value != _AnimationTime) + { + int oldValue = _AnimationTime; + _AnimationTime = value; + OnAnimationTimeChanged(oldValue, value); + } + } + } + /// + /// Called when AnimationTime property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnAnimationTimeChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("AnimationTime")); + + } + + /// + /// Occurs before the control is maximized and allows you to cancel that. + /// + [Description("Occurs before the control is maximized and allows you to cancel that.")] + public event CancelSourceEventHandler BeforeMaximize; + /// + /// Raises BeforeMaximize event. + /// + /// Provides event arguments. + protected virtual void OnBeforeMaximize(CancelSourceEventArgs e) + { + CancelSourceEventHandler h = BeforeMaximize; + if (h != null) + h(this, e); + } + /// + /// Occurs before the control is restored and allows you to cancel that. + /// + [Description("Occurs before the control is restored and allows you to cancel that.")] + public event CancelSourceEventHandler BeforeRestore; + /// + /// Raises BeforeRestore event. + /// + /// Provides event arguments. + protected virtual void OnBeforeRestore(CancelSourceEventArgs e) + { + CancelSourceEventHandler h = BeforeRestore; + if (h != null) + h(this, e); + } + + /// + /// Occurs before the control is opened and allows you to cancel that. + /// + [Description("Occurs before the control is opened and allows you to cancel that.")] + public event CancelSourceEventHandler BeforeOpen; + /// + /// Raises BeforeOpen event. + /// + /// Provides event arguments. + protected virtual void OnBeforeOpen(CancelSourceEventArgs e) + { + CancelSourceEventHandler h = BeforeOpen; + if (h != null) + h(this, e); + } + + /// + /// Occurs before the control is closed and allows you to cancel that. + /// + [Description("Occurs before the control is closed and allows you to cancel that.")] + public event CancelSourceEventHandler BeforeClose; + /// + /// Raises BeforeClose event. + /// + /// Provides event arguments. + protected virtual void OnBeforeClose(CancelSourceEventArgs e) + { + CancelSourceEventHandler h = BeforeClose; + if (h != null) + h(this, e); + } + + protected override void OnHandleCreated(EventArgs e) + { + UpdateSelectedItemTitle(); + UpdateColors(); + if (_IsMenuExpandedDelayedSet) + { + ExpandMenu(_IsMenuExpanded); + _IsMenuExpandedDelayedSet = false; + } + base.OnHandleCreated(e); + } + + internal void UpdateSelectedItemTitle() + { + SideNavItem item = _Strip.SelectedItem; + if (item == null) return; + + if (!string.IsNullOrEmpty(item.Title)) + _TitleLabel.Text = item.Title; + else + _TitleLabel.Text = item.Text; + } + + private Point _SplitterMouseDownPoint = Point.Empty; + private void SplitterMouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + _SplitterMouseDownPoint = e.Location; + } + private void SplitterMouseMove(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + int maxWidth = GetMaxWidth(); + int minWidth = _Strip.Width + 64; + int newWidth = this.Width + (e.X - _SplitterMouseDownPoint.X); + if (newWidth > maxWidth) + newWidth = maxWidth; + else if (newWidth < minWidth) + newWidth = minWidth; + this.Width = newWidth; + } + } + + /// + /// Gets currently selected item. Only items with Panel assigned can be selected. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SideNavItem SelectedItem + { + get + { + foreach (BaseItem item in this.Items) + { + if (item is SideNavItem && ((SideNavItem)item).Checked) + { + return (SideNavItem)item; + } + } + return null; + } + set + { + if (value != null && value.Panel != null) + value.Checked = true; + } + } + + /// + /// Occurs when SelectedItem changes. + /// + [Description("Occurs when SelectedItem changes.")] + public event EventHandler SelectedItemChanged; + + /// + /// Raises SelectedItemChanged event. + /// + /// Provides event arguments. + protected virtual void OnSelectedItemChanged(EventArgs e) + { + EventHandler h = SelectedItemChanged; + if (h != null) + h(this, e); + } + /// + /// Gets reference to internal SideNavStrip control. + /// + [Browsable(false)] + public SideNavStrip SideNavStrip + { + get { return _Strip; } + } + #endregion + } + + /// + /// Defines delegate for the CancelSource events. + /// + /// + /// + public delegate void CancelSourceEventHandler(object sender, CancelSourceEventArgs e); + /// + /// Event arguments for CancelSourceEventHandler + /// + public class CancelSourceEventArgs : CancelEventArgs + { + /// + /// Gets the source of the event. + /// + public eEventSource Source = eEventSource.Code; + /// + /// Gets any optional data that is associated with the event. + /// + public object Data = null; + /// + /// Creates new instance of the object. + /// + /// Source of event + public CancelSourceEventArgs(eEventSource source) + { + this.Source = source; + } + /// + /// Creates new instance of the object. + /// + /// Source of event + /// Optional data associated with the event. + public CancelSourceEventArgs(eEventSource source, object data) + { + this.Source = source; + this.Data = data; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItem.cs b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItem.cs new file mode 100644 index 00000000..a1249ac6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItem.cs @@ -0,0 +1,791 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), DesignTimeVisible(false)] + public class SideNavItem : ButtonItem + { + #region Private Variables & Constructor + private SideNavPanel _Panel = null; + + /// + /// Initializes a new instance of the MetroTabItem class. + /// + public SideNavItem() + { + this.ButtonStyle = eButtonStyle.ImageAndText; + } + #endregion + + #region Internal Implementation + public override void Paint(ItemPaintArgs p) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + SideNavItemRendererEventArgs args = new SideNavItemRendererEventArgs(this, p.Graphics); + args.ItemPaintArgs = p; + renderer.DrawSideNavItem(args); + } + + if (!string.IsNullOrEmpty(NotificationMarkText)) + DevComponents.DotNetBar.Rendering.NotificationMarkPainter.Paint(p.Graphics, this.Bounds, NotificationMarkPosition, + NotificationMarkText, new Size(NotificationMarkSize, NotificationMarkSize), NotificationMarkOffset, NotificationMarkColor); + + if (this.DesignMode && this.Focused) + { + Rectangle r = this.Bounds; + r.Inflate(-1, -1); + DesignTime.DrawDesignTimeSelection(p.Graphics, r, p.Colors.ItemDesignTimeBorder); + } + + this.DrawInsertMarker(p.Graphics); + } + + public override void RecalcSize() + { + _ImageRenderBounds = Rectangle.Empty; + _TextRenderBounds = Rectangle.Empty; + base.RecalcSize(); + } + + private Rectangle _ImageRenderBounds = Rectangle.Empty; + /// + /// Gets or sets cached image rendering bounds. + /// + internal Rectangle ImageRenderBounds + { + get { return _ImageRenderBounds; } + set { _ImageRenderBounds = value; } + } + + private Rectangle _TextRenderBounds = Rectangle.Empty; + /// + /// Gets or sets cached text rendering bounds. + /// + internal Rectangle TextRenderBounds + { + get { return _TextRenderBounds; } + set { _TextRenderBounds = value; } + } + + protected override bool IsFadeEnabled + { + get + { + return false; + } + } + + /// + /// Selects the tab. + /// + public void Select() + { + if (AllowSelection) + this.Checked = true; + } + + /// + /// Gets or sets the panel assigned to this tab item. + /// + [Browsable(false), DefaultValue(null)] + public SideNavPanel Panel + { + get { return _Panel; } + set + { + _Panel = value; + OnPanelChanged(); + } + } + + private void OnPanelChanged() + { + ChangePanelVisibility(); + } + + /// + /// Called after Checked property has changed. + /// + protected override void OnCheckedChanged() + { + if (this.Checked && this.Parent != null) + { + ChangePanelVisibility(); + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this) + continue; + SideNavItem b = item as SideNavItem; + if (b != null && b.Checked) + { + if (this.DesignMode) + TypeDescriptor.GetProperties(b)["Checked"].SetValue(b, false); + else + b.Checked = false; + } + } + } + + if (BarFunctions.IsOffice2007Style(this.EffectiveStyle) && this.ContainerControl is System.Windows.Forms.Control) + ((System.Windows.Forms.Control)this.ContainerControl).Invalidate(); + if (!this.Checked) + ChangePanelVisibility(); + + InvokeCheckedChanged(); + } + + private void ChangePanelVisibility() + { + if (this.Checked && _Panel != null) + { + if (this.DesignMode) + { + if (!_Panel.Visible) _Panel.Visible = true; + TypeDescriptor.GetProperties(_Panel)["Visible"].SetValue(_Panel, true); + _Panel.BringToFront(); + } + else + { + if (!_Panel.IsDisposed) + { + // Had to remove this optimization since in certain use-cases it caused + // .NET WinForms layout framework to move child controls inside of the panel + // Following 3 lines reduce flashing of panel's child controls when Dock panel is shown + //System.Windows.Forms.DockStyle oldDock = _Panel.Dock; + //_Panel.Dock = System.Windows.Forms.DockStyle.None; + //_Panel.Location = new Point(-32000, 32000); + _Panel.Enabled = true; + _Panel.Visible = true; + _Panel.BringToFront(); + //if (_Panel.Dock != oldDock) + // _Panel.Dock = oldDock; + } + + } + } + else if (!this.Checked && _Panel != null) + { + if (this.DesignMode) + TypeDescriptor.GetProperties(_Panel)["Visible"].SetValue(_Panel, false); + else + { + _Panel.Visible = false; + _Panel.Enabled = false; + } + } + } + + private bool AllowSelection + { + get { return _Panel != null; } + } + + /// + /// Occurs just before Click event is fired. + /// + protected override void OnClick() + { + base.OnClick(); + if (_IsSystemMenu) + { + SideNavStrip strip = this.ContainerControl as SideNavStrip; + if(strip!=null && strip.Parent is SideNav) + ((SideNav)strip.Parent).IsMenuExpanded = !((SideNav)strip.Parent).IsMenuExpanded; + } + else if (!this.Checked && AllowSelection) + { + if (this.DesignMode) + TypeDescriptor.GetProperties(this)["Checked"].SetValue(this, true); + else + { + SideNav nav = GetSideNav(); + if (nav != null && !nav.ValidateChildren()) + return; + this.Checked = true; + } + } + } + private SideNav GetSideNav() + { + SideNavStrip strip = this.ContainerControl as SideNavStrip; + if (strip == null) return null; + return strip.Parent as SideNav; + } + /// + /// Called when Visibility of the items has changed. + /// + /// New Visible state. + protected internal override void OnVisibleChanged(bool bVisible) + { + base.OnVisibleChanged(bVisible); + if (!bVisible && this.Checked) + { + TypeDescriptor.GetProperties(this)["Checked"].SetValue(this, false); + // Try to check first item in the group + if (this.Parent != null) + { + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this || !item.GetEnabled() || !item.Visible) + continue; + SideNavItem b = item as SideNavItem; + if (b != null) + { + TypeDescriptor.GetProperties(b)["Checked"].SetValue(this, true); + break; + } + } + } + } + } + + /// + /// Gets or set the Group item belongs to. The groups allows a user to choose from mutually exclusive options within the group. The choice is reflected by Checked property. + /// + [Browsable(false), DevCoBrowsable(false), DefaultValue(""), EditorBrowsable(EditorBrowsableState.Never)] + public override string OptionGroup + { + get { return base.OptionGroup; } + set { base.OptionGroup = value; } + } + + /// + /// Returns the collection of sub items. + /// + [Browsable(false), DevCoBrowsable(false), DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)] + public override SubItemsCollection SubItems + { + get { return base.SubItems; } + } + + internal override void DoAccesibleDefaultAction() + { + if (AllowSelection) + this.Checked = true; + } + + protected override void Invalidate(System.Windows.Forms.Control containerControl) + { + Rectangle r = m_Rect; + r.Width++; + r.Height++; + if (containerControl.InvokeRequired) + containerControl.BeginInvoke(new MethodInvoker(delegate { containerControl.Invalidate(r, true); })); + else + containerControl.Invalidate(r, true); + } + + public override bool UseParentSubItemsImageSize + { + get + { + return false; + } + } + + private Color[] _BackColors = null; + /// + /// Indicates the array of colors that when set are used to draw the background of the item. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the background of the item."), TypeConverter(typeof(ArrayConverter))] + public Color[] BackColors + { + get + { + return _BackColors; + } + set + { + if (_BackColors != value) + { + _BackColors = value; + //OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + this.Refresh(); + } + } + } + + private Color[] _BorderColors = null; + /// + /// Indicates the array of colors that when set are used to draw the border of the item. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the border of the item."), TypeConverter(typeof(ArrayConverter))] + public Color[] BorderColors + { + get + { + return _BorderColors; + } + set + { + if (_BorderColors != value) + { + _BorderColors = value; + //OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + this.Refresh(); + } + } + } + + /// + /// Occurs after item visual style has changed. + /// + protected override void OnStyleChanged() + { + base.OnStyleChanged(); + UpdateItemAppearance(); + } + + private int _PaddingHorizontal = 0; + /// + /// Gets or sets the additional padding added around the tab item in pixels. Default value is 0. + /// + [Browsable(true), DefaultValue(0), Category("Layout"), Description("Indicates additional padding added around the tab item in pixels.")] + public int PaddingHorizontal + { + get { return _PaddingHorizontal; } + set + { + _PaddingHorizontal = value; + UpdateItemAppearance(); + } + } + private void UpdateItemAppearance() + { + this.VerticalPadding = 6; + this.HorizontalPadding = 14 + _PaddingHorizontal; + + this.NeedRecalcSize = true; + this.OnAppearanceChanged(); + } + + private string _Title = ""; + /// + /// Indicates an optional title for the associated panel. If not set item text is used. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates an optional title for the associated panel. If not set item text is used.")] + public string Title + { + get { return _Title; } + set + { + if (value == null) value = ""; + if (_Title != value) + { + string oldValue = _Title; + _Title = value; + OnTitleChanged(value, oldValue); + } + } + } + + protected virtual void OnTitleChanged(string newValue, string oldValue) + { + if (this.Checked) + { + SideNavStrip strip = this.ContainerControl as SideNavStrip; + if (strip != null && strip.Parent is SideNav) + ((SideNav)strip.Parent).UpdateSelectedItemTitle(); + } + } + + private bool _IsSystemMenu = false; + /// + /// Gets or sets whether this item acts as the SideNav control system menu which collapses and expands the SideNav items. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether this item acts as the SideNav control system menu which collapses and expands the SideNav items.")] + public bool IsSystemMenu + { + get { return _IsSystemMenu; } + set + { + if (_IsSystemMenu != value) + { + bool oldValue = _IsSystemMenu; + _IsSystemMenu = value; + OnIsSystemMenuChanged(value, oldValue); + } + } + } + + protected virtual void OnIsSystemMenuChanged(bool newValue, bool oldValue) + { + if (newValue && this.DesignMode) + { + if (string.IsNullOrEmpty(this.Symbol)) + this.Symbol = "\uf0c9"; + if (string.IsNullOrEmpty(this.Text)) + this.Text = "Menu"; + } + + //throw new NotImplementedException(); + } + #endregion + + #region Hidden Properties + /// + /// Indicates whether the item will auto-collapse (fold) when clicked. + /// When item is on popup menu and this property is set to false, menu will not + /// close when item is clicked. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Behavior"), DefaultValue(true), Description("Indicates whether the item will auto-collapse (fold) when clicked.")] + public override bool AutoCollapseOnClick + { + get + { + return base.AutoCollapseOnClick; + } + set + { + base.AutoCollapseOnClick = value; + } + } + + /// + /// Indicates whether the item will auto-expand when clicked. + /// When item is on top level bar and not on menu and contains sub-items, sub-items will be shown only if user + /// click the expand part of the button. Setting this propert to true will expand the button and show sub-items when user + /// clicks anywhere inside of the button. Default value is false which indicates that button is expanded only + /// if its expand part is clicked. + /// + [DefaultValue(false), Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DevCoBrowsable(false), Category("Behavior"), Description("Indicates whether the item will auto-collapse (fold) when clicked.")] + public override bool AutoExpandOnClick + { + get + { + return base.AutoExpandOnClick; + } + set + { + base.AutoExpandOnClick = value; + } + } + + /// + /// Gets or sets whether item can be customized by end user. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(true), System.ComponentModel.Category("Behavior"), System.ComponentModel.Description("Indicates whether item can be customized by user.")] + public override bool CanCustomize + { + get + { + return base.CanCustomize; + } + set + { + base.CanCustomize = value; + } + } + + /// + /// Gets or set a value indicating whether the button is in the checked state. + /// + [Browsable(false), DevCoBrowsable(false), Category("Appearance"), Description("Indicates whether item is checked or not."), DefaultValue(false)] + public override bool Checked + { + get + { + return base.Checked; + } + set + { + base.Checked = value; + } + } + + /// + /// Gets or sets whether Click event will be auto repeated when mouse button is kept pressed over the item. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(false), Category("Behavior"), Description("Gets or sets whether Click event will be auto repeated when mouse button is kept pressed over the item.")] + public override bool ClickAutoRepeat + { + get + { + return base.ClickAutoRepeat; + } + set + { + base.ClickAutoRepeat = value; + } + } + + /// + /// Gets or sets the auto-repeat interval for the click event when mouse button is kept pressed over the item. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(600), Category("Behavior"), Description("Gets or sets the auto-repeat interval for the click event when mouse button is kept pressed over the item.")] + public override int ClickRepeatInterval + { + get + { + return base.ClickRepeatInterval; + } + set + { + base.ClickRepeatInterval = value; + } + } + + /// + /// Gets or sets a value indicating whether the item is enabled. + /// + [Browsable(false), DevCoBrowsable(false), DefaultValue(true), Category("Behavior"), Description("Indicates whether is item enabled.")] + public override bool Enabled + { + get + { + return base.Enabled; + } + set + { + base.Enabled = value; + } + } + + /// + /// Indicates item's visiblity when on pop-up menu. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Appearance"), Description("Indicates item's visiblity when on pop-up menu."), DefaultValue(eMenuVisibility.VisibleAlways)] + public override eMenuVisibility MenuVisibility + { + get + { + return base.MenuVisibility; + } + set + { + base.MenuVisibility = value; + } + } + + /// + /// Indicates when menu items are displayed when MenuVisiblity is set to VisibleIfRecentlyUsed and RecentlyUsed is true. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DevCoBrowsable(false), Category("Appearance"), Description("Indicates when menu items are displayed when MenuVisiblity is set to VisibleIfRecentlyUsed and RecentlyUsed is true."), DefaultValue(ePersonalizedMenus.Disabled)] + public override ePersonalizedMenus PersonalizedMenus + { + get + { + return base.PersonalizedMenus; + } + set + { + base.PersonalizedMenus = value; + } + } + + /// + /// Indicates Animation type for Popups. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Behavior"), Description("Indicates Animation type for Popups."), DefaultValue(ePopupAnimation.ManagerControlled)] + public override ePopupAnimation PopupAnimation + { + get + { + return base.PopupAnimation; + } + set + { + base.PopupAnimation = value; + } + } + + /// + /// Indicates the font that will be used on the popup window. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Appearance"), Description("Indicates the font that will be used on the popup window."), DefaultValue(null)] + public override System.Drawing.Font PopupFont + { + get + { + return base.PopupFont; + } + set + { + base.PopupFont = value; + } + } + + /// + /// Indicates whether sub-items are shown on popup Bar or popup menu. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Appearance"), Description("Indicates whether sub-items are shown on popup Bar or popup menu."), DefaultValue(ePopupType.Menu)] + public override ePopupType PopupType + { + get + { + return base.PopupType; + } + set + { + base.PopupType = value; + } + } + + /// + /// Specifies the inital width for the Bar that hosts pop-up items. Applies to PopupType.Toolbar only. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Layout"), Description("Specifies the inital width for the Bar that hosts pop-up items. Applies to PopupType.Toolbar only."), DefaultValue(200)] + public override int PopupWidth + { + get + { + return base.PopupWidth; + } + set + { + base.PopupWidth = value; + } + } + + /// + /// Gets or sets whether item will display sub items. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(true), Category("Behavior"), Description("Determines whether sub-items are displayed.")] + public override bool ShowSubItems + { + get + { + return base.ShowSubItems; + } + set + { + base.ShowSubItems = value; + } + } + + /// + /// Gets or sets whether the item expands automatically to fill out the remaining space inside the container. Applies to Items on stretchable, no-wrap Bars only. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(false), Category("Appearance"), Description("Indicates whether item will stretch to consume empty space. Items on stretchable, no-wrap Bars only.")] + public override bool Stretch + { + get + { + return base.Stretch; + } + set + { + base.Stretch = value; + } + } + + /// + /// Gets or sets the width of the expand part of the button item. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Behavior"), Description("Indicates the width of the expand part of the button item."), DefaultValue(12)] + public override int SubItemsExpandWidth + { + get { return base.SubItemsExpandWidth; } + set + { + base.SubItemsExpandWidth = value; + } + } + + /// + /// Gets or set the alternative shortcut text. + /// + [System.ComponentModel.Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DevCoBrowsable(false), System.ComponentModel.Category("Design"), System.ComponentModel.Description("Gets or set the alternative Shortcut Text. This text appears next to the Text instead of any shortcuts"), System.ComponentModel.DefaultValue("")] + public override string AlternateShortCutText + { + get + { + return base.AlternateShortCutText; + } + set + { + base.AlternateShortCutText = value; + } + } + + /// + /// Gets or sets whether item separator is shown before this item. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false), System.ComponentModel.DefaultValue(false), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Indicates whether this item is beginning of the group.")] + public override bool BeginGroup + { + get + { + return base.BeginGroup; + } + set + { + base.BeginGroup = value; + } + } + + /// + /// Returns category for this item. If item cannot be customzied using the + /// customize dialog category is empty string. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false), System.ComponentModel.DefaultValue(""), System.ComponentModel.Category("Design"), System.ComponentModel.Description("Indicates item category used to group similar items at design-time."), EditorBrowsable(EditorBrowsableState.Never)] + public override string Category + { + get + { + + return base.Category; + } + set + { + base.Category = value; + } + } + + /// + /// Gets or sets the text color of the button when mouse is over the item. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The foreground color used to display text when mouse is over the item."), EditorBrowsable(EditorBrowsableState.Never)] + public override Color HotForeColor + { + get + { + return base.HotForeColor; + } + set + { + base.HotForeColor = value; + } + } + + /// + /// Indicates the way item is painting the picture when mouse is over it. Setting the value to Color will render the image in gray-scale when mouse is not over the item. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Indicates the way item is painting the picture when mouse is over it. Setting the value to Color will render the image in gray-scale when mouse is not over the item."), System.ComponentModel.DefaultValue(eHotTrackingStyle.Default), EditorBrowsable(EditorBrowsableState.Never)] + public override eHotTrackingStyle HotTrackingStyle + { + get { return base.HotTrackingStyle; } + set + { + base.HotTrackingStyle = value; + } + } + + /// + /// Gets/Sets the button style which controls the appearance of the button elements. Changing the property can display image only, text only or image and text on the button at all times. + /// + [Browsable(false), Category("Appearance"), Description("Determines the style of the button."), DefaultValue(eButtonStyle.ImageAndText), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override eButtonStyle ButtonStyle + { + get + { + return base.ButtonStyle; + } + set + { + base.ButtonStyle = value; + } + } + + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItemPainter.cs b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItemPainter.cs new file mode 100644 index 00000000..bd94e056 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItemPainter.cs @@ -0,0 +1,33 @@ +using DevComponents.DotNetBar.Controls; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class SideNavItemPainter : IOffice2007Painter + { + /// + /// Paints ListBoxItem. + /// + /// Provides arguments for the operation. + public virtual void Paint(SideNavItemRendererEventArgs e) { } + + #region IOffice2007Painter Members + private Office2007ColorTable _ColorTable = null; //new Office2007ColorTable(); + public Office2007ColorTable ColorTable + { + get + { + return _ColorTable; + } + set + { + _ColorTable = value; + } + } + + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItemRendererEventArgs.cs b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItemRendererEventArgs.cs new file mode 100644 index 00000000..55830f2e --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItemRendererEventArgs.cs @@ -0,0 +1,42 @@ +using DevComponents.DotNetBar.Controls; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + /// + /// Provides data for the SideNavItem rendering events. + /// + public class SideNavItemRendererEventArgs : EventArgs + { + /// + /// Gets or sets the reference to the item being rendered. + /// + public SideNavItem Item = null; + + /// + /// Gets or sets the reference to graphics object. + /// + public Graphics Graphics = null; + + /// + /// Indicates whether to cancel system rendering of the item. + /// + public bool Cancel = false; + + internal ItemPaintArgs ItemPaintArgs = null; + + /// + /// Creates new instance of the object and initializes it with default values. + /// + /// Reference to the ListBoxItem being rendered. + /// Reference to the graphics object. + public SideNavItemRendererEventArgs(SideNavItem item, Graphics g) + { + this.Item = item; + this.Graphics = g; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItemStateColorTable.cs b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItemStateColorTable.cs new file mode 100644 index 00000000..d438cad1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavItemStateColorTable.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + /// + /// Defines color table for SideNav control. + /// + public class SideNavColorTable + { + /// + /// Gets or sets the color table for SideNavItem + /// + public SideNavItemColorTable SideNavItem = new SideNavItemColorTable(); + /// + /// Gets or sets the background color of SideNav title bar. + /// + public Color TitleBackColor = Color.Empty; + /// + /// Gets or sets the border color of the title of SideNav control. + /// + public Color[] TitleBorderColors = new Color[0]; + /// + /// Gets or sets the color of the strip which hosts the items. + /// + public Color ItemsBackColor = Color.Empty; + /// + /// Gets or sets the border color of the SideNav control. + /// + public Color[] BorderColors = new Color[0]; + /// + /// Gets or sets the back color of panels that are attached to SideNavItem and displayed when SideNavItem is selected. + /// + public Color PanelBackColor = Color.Empty; + } + + /// + /// Defines color table for SideNavItem + /// + public class SideNavItemColorTable + { + /// + /// Gets or sets the color table for Default state. + /// + public SideNavItemStateColorTable Default = new SideNavItemStateColorTable(); + /// + /// Gets or sets the color table for MouseOver state. + /// + public SideNavItemStateColorTable MouseOver = new SideNavItemStateColorTable(); + /// + /// Gets or sets the color table for Pressed state. + /// + public SideNavItemStateColorTable Pressed = new SideNavItemStateColorTable(); + /// + /// Gets or sets the color table for Selected state. + /// + public SideNavItemStateColorTable Selected = new SideNavItemStateColorTable(); + } + + /// + /// Defines state color table for SideNavItem + /// + public class SideNavItemStateColorTable + { + public SideNavItemStateColorTable() + { + + } + public SideNavItemStateColorTable(Color textColor) + { + this.TextColor = textColor; + } + public SideNavItemStateColorTable(Color textColor, Color[] backColors, Color[] borderColors) + { + this.TextColor = textColor; + this.BackColors = backColors; + this.BorderColors = borderColors; + } + + public SideNavItemStateColorTable(Color textColor, Color[] backColors, Color[] borderColors, int cornerRadius) + { + this.TextColor = textColor; + this.BackColors = backColors; + this.BorderColors = borderColors; + this.CornerRadius = cornerRadius; + } + + /// + /// Indicates item text color. + /// + public Color TextColor = Color.Black; + /// + /// Gets or sets the background colors for the item. + /// + public Color[] BackColors = new Color[0]; + /// + /// Gets or sets the back colors gradient angle if there is more than one color in BackColors array. + /// + public int BackColorsGradientAngle = 90; + /// + /// Gets or sets the gradient colors positions if there is more than one color in BackColors array. + /// + public float[] BackColorsPositions = new float[0]; + /// + /// Gets or sets the border colors for the item. + /// + public Color[] BorderColors = new Color[0]; + /// + /// Indicates the corner radius. + /// + public int CornerRadius = 0; + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavPanel.cs b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavPanel.cs new file mode 100644 index 00000000..0a46ac77 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavPanel.cs @@ -0,0 +1,148 @@ +using DevComponents.DotNetBar.Rendering; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Reflection; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents a panel which hosts controls for the SideNavItem. + /// + [ToolboxItem(false)] + public class SideNavPanel : Panel, IScrollBarOverrideSupport + { + private ScrollbarSkinner _ScrollSkinner = null; + public SideNavPanel() + { + this.SetStyle(ControlStyles.AllPaintingInWmPaint + | ControlStyles.ResizeRedraw + | DisplayHelp.DoubleBufferFlag + | ControlStyles.UserPaint + | ControlStyles.Opaque + , true); + + _ScrollSkinner = new ScrollbarSkinner(this); + } + + protected override void Dispose(bool disposing) + { + _ScrollSkinner.Dispose(); + base.Dispose(disposing); + } + + protected override void OnPaint(PaintEventArgs e) + { + Color backColor = GetBackColor(); + if (!backColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(backColor)) + e.Graphics.FillRectangle(brush, this.ClientRectangle); + } + base.OnPaint(e); + } + + private Color _BackColor = Color.Empty; + protected override void OnBackColorChanged(EventArgs e) + { + PropertyInfo prop = typeof (Control).GetProperty("RawBackColor", + BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance); + if (prop != null) + { + _BackColor = (Color)prop.GetValue(this, null); + } + base.OnBackColorChanged(e); + } + + private Color GetBackColor() + { + if(!_BackColor.IsEmpty) + return _BackColor; + return GetColorTable().PanelBackColor; + } + + private SideNavColorTable GetColorTable() + { + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.SideNav; + } + + protected override void WndProc(ref Message m) + { + //Console.WriteLine("{0} Message {1}", DateTime.Now, MapMessage(m.Msg)); + if (m.Msg == (int)WinApi.WindowsMessages.WM_VSCROLL || m.Msg == (int)WinApi.WindowsMessages.WM_HSCROLL || m.Msg == (int)WinApi.WindowsMessages.WM_MOUSEWHEEL) + { + base.WndProc(ref m); + OnScrollBarValueChanged(new ScrollValueChangedEventArgs(ScrollbarControl.MapMessageToScrollChange(m.Msg))); + return; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_NCCALCSIZE) + { + base.WndProc(ref m); + OnNonClientSizeChanged(EventArgs.Empty); + return; + } + else if (m.Msg == 206 || m.Msg == 8270) // Internal RichTextBox message we use to trigger scroll-bar update + { + base.WndProc(ref m); + OnScrollBarValueChanged(new ScrollValueChangedEventArgs(eScrollBarScrollChange.Horizontal | eScrollBarScrollChange.Vertical)); + return; + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_MOVE) // Internal RichTextBox message we use to trigger scroll-bar update + { + base.WndProc(ref m); + OnControlMoved(EventArgs.Empty); + return; + } + base.WndProc(ref m); + } + + #region IScrollBarOverrideSupport Members + [Browsable(false)] + public event EventHandler NonClientSizeChanged; + /// + /// Raises NonClientSizeChanged event. + /// + /// Provides event arguments. + protected virtual void OnNonClientSizeChanged(EventArgs e) + { + EventHandler handler = NonClientSizeChanged; + if (handler != null) + handler(this, e); + } + + public event ScrollValueChangedHandler ScrollBarValueChanged; + /// + /// Raises ScrollBarValueChanged event. + /// + /// Provides event arguments. + protected virtual void OnScrollBarValueChanged(ScrollValueChangedEventArgs e) + { + ScrollValueChangedHandler handler = ScrollBarValueChanged; + if (handler != null) + handler(this, e); + } + [Browsable(false)] + public event EventHandler ControlMoved; + /// + /// Raises NonClientSizeChanged event. + /// + /// Provides event arguments. + protected virtual void OnControlMoved(EventArgs e) + { + EventHandler handler = ControlMoved; + if (handler != null) + handler(this, e); + } + bool IScrollBarOverrideSupport.DesignMode + { + get + { + return this.DesignMode; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavStrip.cs b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavStrip.cs new file mode 100644 index 00000000..ae859976 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SideNav/SideNavStrip.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; +using DevComponents.DotNetBar.Rendering; +using System.Drawing; +using DevComponents.AdvTree.Layout; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false)] + public class SideNavStrip : ItemControl + { + #region Constructor + private SimpleItemContainer _ItemContainer = null; + + public SideNavStrip() + { + _ItemContainer = new SimpleItemContainer(); + _ItemContainer.GlobalItem = false; + _ItemContainer.ContainerControl = this; + _ItemContainer.Stretch = true; + _ItemContainer.Displayed = true; + _ItemContainer.Style = eDotNetBarStyle.StyleManagerControlled; + _ItemContainer.LayoutOrientation = eOrientation.Vertical; + //base.AutoSize = true; + this.ColorScheme.Style = eDotNetBarStyle.StyleManagerControlled; + _ItemContainer.SetOwner(this); + this.SetBaseItemContainer(_ItemContainer); + this.BackgroundStyle.Class = ElementStyleClassKeys.SideNavStripKey; + StyleManager.Register(this); + } + #endregion + + #region Implementation + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + _ItemContainer.NeedRecalcSize = true; + } + + /// + /// Returns collection of items on a bar. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] + public SubItemsCollection Items + { + get + { + return _ItemContainer.SubItems; + } + } + + /// + /// Gets currently selected item. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SideNavItem SelectedItem + { + get + { + foreach (BaseItem item in this.Items) + { + if (item is SideNavItem && ((SideNavItem)item).Checked) + { + return (SideNavItem)item; + } + } + return null; + } + set + { + if (value != null && value.Panel != null) + value.Checked = true; + } + } + + protected override void PaintControl(ItemPaintArgs pa) + { + base.PaintControl(pa); + SideNavItem selectedItem = this.SelectedItem; + if (selectedItem != null) + { + Color color = GetBorderColor(); + if (!color.IsEmpty) + { + Graphics g = pa.Graphics; + using (Pen pen = new Pen(color)) + { + if (selectedItem.TopInternal > 0) + g.DrawLine(pen, this.Width - 1, 0, this.Width - 1, selectedItem.TopInternal - 1); + if (selectedItem.Bounds.Bottom < this.Height) + g.DrawLine(pen, this.Width - 1, selectedItem.Bounds.Bottom, this.Width - 1, this.Height); + } + + + } + } + } + + private Color GetBorderColor() + { + SideNavColorTable ct = GetColorTable(); + if (ct.BorderColors != null && ct.BorderColors.Length > 0) + return ct.BorderColors[0]; + return Color.Empty; + } + + private SideNavColorTable GetColorTable() + { + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.SideNav; + } + internal void SelectFirstItem() + { + foreach (BaseItem item in this.Items) + { + if (item.Visible && item.Enabled && item is SideNavItem) + { + ((SideNavItem)item).Checked = true; + break; + } + } + } + + protected override void OnButtonCheckedChanged(ButtonItem item, EventArgs e) + { + if (this.Parent is SideNav) + ((SideNav)this.Parent).UpdateSelectedItemTitle(); + base.OnButtonCheckedChanged(item, e); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SlidePanel.ico b/PROMS/DotNetBar Source Code/Controls/SlidePanel.ico new file mode 100644 index 00000000..06730849 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/SlidePanel.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/SlidePanel/SlidePanel.cs b/PROMS/DotNetBar Source Code/Controls/SlidePanel/SlidePanel.cs new file mode 100644 index 00000000..e3e082af --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SlidePanel/SlidePanel.cs @@ -0,0 +1,772 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the panel which can slide out and into the view. + /// + [ToolboxBitmap(typeof(CircularProgress), "Controls.SlidePanel.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.SlidePanelDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class SlidePanel : UserControl + { + internal const int DefaultAnimationTime = 500; + #region Events + /// + /// Occurs when IsOpen property value has changed, i.e. slide-panel is shown or hidden. + /// + [Description("Occurs when IsOpen property value has changed, i.e. slide-panel is shown or hidden.")] + public event EventHandler IsOpenChanged; + /// + /// Raises IsOpenChanged event. + /// + /// Provides event arguments. + protected virtual void OnIsOpenChanged(EventArgs e) + { + EventHandler handler = IsOpenChanged; + if (handler != null) + handler(this, e); + } + #endregion + + #region Constructor + protected override void Dispose(bool disposing) + { + DisposeSlideOutButton(); + base.Dispose(disposing); + } + #endregion + + #region Implementation + + private eSlideSide _SlideSide = eSlideSide.Left; + /// + /// Gets or sets side panel slides into. + /// + [DefaultValue(eSlideSide.Left), Category("Behavior"), Description("Indicates side panel slides into.")] + public eSlideSide SlideSide + { + get { return _SlideSide; } + set + { + if (value != _SlideSide) + { + eSlideSide oldValue = _SlideSide; + _SlideSide = value; + OnSlideSideChanged(oldValue, value); + } + } + } + /// + /// Called when SlideSide property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSlideSideChanged(eSlideSide oldValue, eSlideSide newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SlideSide")); + if (!this.IsOpen) + { + WaitForCurrentAnimationFinish(); + this.Bounds = GetSlideOutBounds(this.Parent, _OpenBounds); + + if (_SlideOutButtonVisible) + CreateSlideOutButton(); + } + } + + private bool _IsOpen = true; + /// + /// Gets or sets whether panel is open. When this property is changed panel will slide in or out of the view. + /// + [Browsable(false), DefaultValue(true), Description("Indicates whether panel is open. When this property is changed panel will slide in or out of the view.")] + public bool IsOpen + { + get { return _IsOpen; } + set + { + if (_UsesBlockingAnimation && _CurrentAnimation != null || _IsWaiting) return; + if (value != _IsOpen) + { + bool oldValue = _IsOpen; + _IsOpen = value; + OnIsOpenChanged(oldValue, value); + } + } + } + /// + /// Called when IsOpen property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnIsOpenChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("IsOpen")); + if (!newValue) + SlideOutOfView(); + else + SlideIntoView(); + OnIsOpenChanged(EventArgs.Empty); + } + + private bool _UsesBlockingAnimation = false; + /// + /// Gets or sets whether panel uses modal animation, meaning when IsOpen property is set the call is not returned until animation is complete. + /// + [Browsable(false)] + public bool UsesBlockingAnimation + { + get { return _UsesBlockingAnimation; } + set + { + _UsesBlockingAnimation = value; + } + } + + private Rectangle _OpenBounds = Rectangle.Empty; + /// + /// Gets or sets the open panel bounds. When control IsOpen=false and panel is collapsed its original bounds are stored in OpenBounds property and restored once panel is open. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle OpenBounds + { + get { return _OpenBounds; } + set + { + _OpenBounds = value; + if (!this.Visible && this.Bounds.Size != _OpenBounds.Size) + this.Bounds = GetSlideOutBounds(this.Parent, _OpenBounds); + } + } + /// + /// Slides panel into the view. + /// + private void SlideIntoView() + { + Animation.Animation current = _CurrentAnimation; + if (current != null) + { + current.Stop(); + WaitForCurrentAnimationFinish(); + } + + Rectangle bounds = this.Bounds; + Rectangle targetBounds = _OpenBounds; + if (_SlideOutButton != null) _SlideOutButton.Visible = false; + + if (_AnimationTime > 0) + { + _IsAnimating = true; + //BarFunctions.AnimateControl(this, true, _AnimationTime, bounds, targetBounds); + this.Visible = true; + Animation.AnimationRectangle anim = new DevComponents.DotNetBar.Animation.AnimationRectangle( + new Animation.AnimationRequest(this, "Bounds", bounds, targetBounds), + Animation.AnimationEasing.EaseOutExpo, _AnimationTime); + anim.AnimationCompleted += new EventHandler(AnimationCompleted); + anim.Start(); + _CurrentAnimation = anim; + } + else + this.Bounds = targetBounds; + if (_SlideOutButtonVisible && _SlideOutButton != null) + { + DisposeSlideOutButton(); + } + } + + internal void AbortAnimation() + { + Animation.Animation anim = _CurrentAnimation; + _CurrentAnimation = null; + if (anim != null) + { + anim.Stop(); + anim.Dispose(); + //Console.WriteLine("{0} Animation Forcefully Stopped", DateTime.Now); + } + } + + private bool _IsWaiting = false; + /// + /// Waits for current slide animation to finish and then returns control. + /// + public void WaitForCurrentAnimationFinish() + { + if (_IsWaiting) return; + + _IsWaiting = true; + try + { + if (_CurrentAnimation == null) return; + DateTime start = DateTime.Now; + while (_CurrentAnimation != null) + { + Application.DoEvents(); + if (DateTime.Now.Subtract(start).TotalMilliseconds > _AnimationTime * 1.5f) + { + AbortAnimation(); + break; + } + } + } + finally + { + _IsWaiting = false; + } + } + private void DisposeSlideOutButton() + { + if (_SlideOutButton == null) return; + + Control parent = _SlideOutButton.Parent; + if (parent != null) + { + parent.Resize -= ParentResize; + parent.Controls.Remove(_SlideOutButton); + } + _SlideOutButton.Dispose(); + _SlideOutButton = null; + } + + private Animation.Animation _CurrentAnimation = null; + /// + /// Slides panel out of the view. + /// + private void SlideOutOfView() + { + Animation.Animation current = _CurrentAnimation; + if (current != null) + { + current.Stop(); + WaitForCurrentAnimationFinish(); + } + + Rectangle bounds = this.Bounds; + Rectangle targetBounds = GetSlideOutBounds(); + + if (_AnimationTime > 0 && this.Visible) + { + _IsAnimating = true; + //BarFunctions.AnimateControl(this, true, _AnimationTime, bounds, targetBounds); + Animation.AnimationRectangle anim = new DevComponents.DotNetBar.Animation.AnimationRectangle( + new Animation.AnimationRequest(this, "Bounds", bounds, targetBounds), + Animation.AnimationEasing.EaseOutExpo, _AnimationTime); + anim.AnimationCompleted += new EventHandler(AnimationCompleted); + anim.Start(); + _CurrentAnimation = anim; + //this.Visible = false; + } + else + this.Bounds = targetBounds; + _OpenBounds = bounds; + + if (_SlideOutButtonVisible) + CreateSlideOutButton(); + } + + private bool _IsAnimating = false; + internal bool IsAnimating + { + get + { + return _IsAnimating; + } + } + + private void AnimationCompleted(object sender, EventArgs e) + { + //Console.WriteLine("{0} Animation Completed", DateTime.Now); + Animation.Animation anim = _CurrentAnimation; + _CurrentAnimation = null; + if (anim != null) + anim.Dispose(); + if (!_IsOpen) + { + this.Visible = false; + } + _IsAnimating = false; + } + public void SlideOutOfViewSilent(Control parent) + { + _OpenBounds = this.Bounds; + this.Bounds = GetSlideOutBounds(parent); + _IsOpen = false; + } + + private SliderButton _SlideOutButton = null; + private void CreateSlideOutButton() + { + DisposeSlideOutButton(); + Control parent = this.Parent; + if (parent == null) return; + + _SlideOutButton = new SliderButton(this); + if (_SlideOutButtonStyle != null) + _SlideOutButton.Style = _SlideOutButtonStyle; + else + _SlideOutButton.Style = new ElementStyle(DevComponents.DotNetBar.Rendering.ElementStyleClassKeys.SlideOutButtonKey); + + Size activeSlideOutSize = Dpi.Size(_SlideOutActiveButtonSize); + Size slideOutSize = Dpi.Size(_SlideOutButtonSize); + if (_SlideSide == eSlideSide.Top || _SlideSide == eSlideSide.Bottom) // Flip width/height + { + activeSlideOutSize = new Size(activeSlideOutSize.Height, activeSlideOutSize.Width); + slideOutSize = new Size(slideOutSize.Height, slideOutSize.Width); + } + _SlideOutButton.ActiveSliderSize = activeSlideOutSize; + _SlideOutButton.SliderSize = slideOutSize; + _SlideOutButton.Symbol = _Symbol; + _SlideOutButton.SymbolColor = _SymbolColor; + _SlideOutButton.SymbolSet = _SymbolSet; + _SlideOutButton.SymbolSize = _SymbolSize; + parent.Controls.Add(_SlideOutButton); + parent.Controls.SetChildIndex(_SlideOutButton, 0); + parent.Resize += ParentResize; + } + + private void ParentResize(object sender, EventArgs e) + { + if (_SlideOutButton != null) _SlideOutButton.UpdatePosition(); + } + + private Rectangle GetSlideOutBounds() + { + return GetSlideOutBounds(this.Parent); + } + private Rectangle GetSlideOutBounds(Control parent) + { + return GetSlideOutBounds(parent, this.Bounds); + } + private Rectangle GetSlideOutBounds(Control parent, Rectangle panelBounds) + { + if (parent == null) return panelBounds; + + Rectangle r = panelBounds; + if (_SlideSide == eSlideSide.Left) + { + r.X = -r.Width; + } + else if (_SlideSide == eSlideSide.Right) + { + r.X = parent.Width; + } + else if (_SlideSide == eSlideSide.Top) + { + r.Y = -r.Height; + } + else if (_SlideSide == eSlideSide.Bottom) + { + r.Y = parent.Height; + } + return r; + } + + private int _AnimationTime = DefaultAnimationTime; + /// + /// Gets or sets the animation duration time in milliseconds. Setting this property to 0 will disable slide animation. + /// + [DefaultValue(DefaultAnimationTime), Category("Behavior"), Description("Indicates animation duration time in milliseconds. Setting this property to 0 will disable slide animation.")] + public int AnimationTime + { + get { return _AnimationTime; } + set + { + if (value != _AnimationTime) + { + int oldValue = _AnimationTime; + _AnimationTime = value; + OnAnimationTimeChanged(oldValue, value); + } + } + } + /// + /// Called when AnimationTime property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnAnimationTimeChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("AnimationTime")); + + } + + private bool _SlideOutButtonVisible = true; + /// + /// Gets or sets whether slide out button is shown when panel is out of the view and which allows panel to be shown. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether slide out button is shown when panel is out of the view and which allows panel to be shown.")] + public bool SlideOutButtonVisible + { + get { return _SlideOutButtonVisible; } + set + { + if (value != _SlideOutButtonVisible) + { + bool oldValue = _SlideOutButtonVisible; + _SlideOutButtonVisible = value; + OnSlideOutButtonVisibleChanged(oldValue, value); + } + } + } + /// + /// Called when SlideOutButtonVisible property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSlideOutButtonVisibleChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SlideOutButtonVisible")); + if (_IsOpen) return; + if (newValue) + CreateSlideOutButton(); + else + DisposeSlideOutButton(); + } + + private Size _SlideOutButtonSize = SliderButton.DefaultSliderSize; + /// + /// Gets or sets the slide-out buttton size in default state. + /// + [Category("Appearance"), Description("Indicates slide-out buttton size in default state.")] + public Size SlideOutButtonSize + { + get { return _SlideOutButtonSize; } + set + { + if (value != _SlideOutButtonSize) + { + Size oldValue = _SlideOutButtonSize; + _SlideOutButtonSize = value; + OnSlideOutButtonSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SlideOutButtonSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSlideOutButtonSizeChanged(Size oldValue, Size newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SlideOutButtonSize")); + if (_SlideOutButton != null) + { + _SlideOutButton.SliderSize = newValue; + _SlideOutButton.UpdatePosition(); + } + } + /// + /// Returns whether property should be serialized. + /// + public bool ShouldSerializeSlideOutButtonSize() + { + return _SlideOutButtonSize != SliderButton.DefaultSliderSize; + } + /// + /// Resets property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSlideOutButtonSize() + { + SlideOutButtonSize = SliderButton.DefaultSliderSize; + } + + private Size _SlideOutActiveButtonSize = SliderButton.DefaultActiveSliderSize; + /// + /// Gets or sets active (mouse over) slide out button size. + /// + [Category("Appearance"), Description("Indicates active (mouse over) slide out button size.")] + public Size SlideOutActiveButtonSize + { + get { return _SlideOutActiveButtonSize; } + set + { + if (value != _SlideOutActiveButtonSize) + { + Size oldValue = _SlideOutActiveButtonSize; + _SlideOutActiveButtonSize = value; + OnSlideOutActiveButtonSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SlideOutActiveButtonSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSlideOutActiveButtonSizeChanged(Size oldValue, Size newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SlideOutActiveButtonSize")); + if (_SlideOutButton != null) + { + _SlideOutButton.ActiveSliderSize = newValue; + _SlideOutButton.UpdatePosition(); + } + } + /// + /// Returns whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSlideOutActiveButtonSize() + { + return _SlideOutActiveButtonSize != SliderButton.DefaultActiveSliderSize; + } + /// + /// Resets property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSlideOutActiveButtonSize() + { + SlideOutActiveButtonSize = SliderButton.DefaultActiveSliderSize; + } + + private ElementStyle _SlideOutButtonStyle = null; + /// + /// Gets or sets slide-out button style. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates slide-out button style.")] + public ElementStyle SlideOutButtonStyle + { + get { return _SlideOutButtonStyle; } + set + { + if (value != _SlideOutButtonStyle) + { + ElementStyle oldValue = _SlideOutButtonStyle; + _SlideOutButtonStyle = value; + OnSlideOutButtonStyleChanged(oldValue, value); + } + } + } + /// + /// Called when SlideOutButtonStyle property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSlideOutButtonStyleChanged(ElementStyle oldValue, ElementStyle newValue) + { + if (newValue != null) + { + if (_SlideOutButton != null) + _SlideOutButton.Style = newValue; + } + //OnPropertyChanged(new PropertyChangedEventArgs("SlideOutButtonStyle")); + } + + private bool _CenterContent = false; + /// + /// Gets or sets whether panel centers the Controls inside of it. Default value is false. + /// + internal bool CenterContent + { + get { return _CenterContent; } + set + { + if (value != _CenterContent) + { + bool oldValue = _CenterContent; + _CenterContent = value; + OnCenterContentChanged(oldValue, value); + } + } + } + /// + /// Called when CenterContent property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCenterContentChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("CenterContent")); + if (newValue) + CenterControls(); + } + + protected override void OnResize(EventArgs e) + { + if (_CenterContent) + CenterControls(); + base.OnResize(e); + } + + protected override void OnControlAdded(ControlEventArgs e) + { + if (_CenterContent) + CenterControl(e.Control); + base.OnControlAdded(e); + } + + private void CenterControl(Control item) + { + Point loc = new Point(Math.Max(0, (this.Width - item.Width) / 2), Math.Max(0, (this.Height - item.Height) / 2)); + if (item.Location != loc) + item.Location = loc; + } + private void CenterControls() + { + foreach (Control item in this.Controls) + { + CenterControl(item); + } + } + + [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), EditorBrowsable(EditorBrowsableState.Always), Bindable(true)] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + + + + + + private Color _SymbolColor = Color.Empty; + /// + /// Gets or sets the color of the Symbol displayed on slideout button. + /// + [Category("Appearance"), Description("Indicates color of the Symbol displayed on slideout button.")] + public Color SymbolColor + { + get { return _SymbolColor; } + set { _SymbolColor = value; this.Invalidate(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return !_SymbolColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + this.SymbolColor = Color.Empty; + } + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get { return _SymbolRealized; } + } + private string _Symbol = "", _SymbolRealized = ""; + /// + /// Indicates the symbol displayed on face of the slideout button. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the slideout button.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return _Symbol; } + set + { + if (value != _Symbol) + { + string oldValue = _Symbol; + _Symbol = value; + OnSymbolChanged(oldValue, value); + } + } + } + /// + /// Called when Symbol property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolChanged(string oldValue, string newValue) + { + if (string.IsNullOrEmpty(newValue)) + _SymbolRealized = ""; + else + _SymbolRealized = Symbols.GetSymbol(newValue); + this.Invalidate(); + } + + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return _SymbolSet; } + set + { + if (_SymbolSet != value) + { + eSymbolSet oldValue = _SymbolSet; + _SymbolSet = value; + OnSymbolSetChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSet property value changes. + /// + /// Indciates old value + /// Indicates new value + protected virtual void OnSymbolSetChanged(eSymbolSet oldValue, eSymbolSet newValue) + { + this.Invalidate(); + this.Refresh(); + } + + + private float _SymbolSize = 10f; + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(10f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return _SymbolSize; } + set + { + if (value != _SymbolSize) + { + float oldValue = _SymbolSize; + _SymbolSize = value; + OnSymbolSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolSizeChanged(float oldValue, float newValue) + { + this.Invalidate(); + } + #endregion + } + + /// + /// Defines the side SlidePanel slides into. + /// + public enum eSlideSide + { + Left, + Right, + Top, + Bottom + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SlidePanel/SliderButton.cs b/PROMS/DotNetBar Source Code/Controls/SlidePanel/SliderButton.cs new file mode 100644 index 00000000..f1190721 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SlidePanel/SliderButton.cs @@ -0,0 +1,627 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the slider button that is used by SlidePanel when collapsed to slide it back into the view. + /// + [ToolboxItem(false)] + public class SliderButton : Control + { + #region Events + + #endregion + + #region Constructor + private SlidePanel _SlidePanel = null; + /// + /// Initializes a new instance of the SliderButton class. + /// + /// + public SliderButton(SlidePanel slidePanel) + { + _SlidePanel = slidePanel; + this.Margin = new System.Windows.Forms.Padding(); + } + + protected override void Dispose(bool disposing) + { + if (_Style != null) + _Style.StyleChanged -= this.ElementStyleChanged; + DestroyTopmostCheckTimer(); + base.Dispose(disposing); + } + #endregion + + #region Implementation + protected override void OnParentChanged(EventArgs e) + { + if (this.Parent != null) + UpdatePosition(); + base.OnParentChanged(e); + } + protected override void OnClick(EventArgs e) + { + if (!_IsSlidingActive) + _SlidePanel.IsOpen = true; + base.OnClick(e); + } + private Point _MouseOffset = Point.Empty; + private Point _MouseDownPoint = Point.Empty; + protected override void OnMouseDown(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + _MouseDownPoint = Control.MousePosition; + IsMouseDown = true; + } + base.OnMouseDown(e); + } + private Point _OriginalSlidePanelLocation = Point.Empty; + private bool _IsSlidingActive = false; + private int MaximizedOffset = SystemInformation.FrameBorderSize.Width * 2 - 2; + private static readonly Point SlideOffsetStart = new Point(4, 4); + private static readonly Point SlideOutSnapOffset = new Point(96, 96); + protected override void OnMouseMove(MouseEventArgs e) + { + if (IsMouseDown && !_IsSlidingActive) + { + eSlideSide side = _SlidePanel.SlideSide; + if (side == eSlideSide.Left && Control.MousePosition.X - _MouseDownPoint.X > SlideOffsetStart.X) + _IsSlidingActive = true; + else if (side == eSlideSide.Right && _MouseDownPoint.X - Control.MousePosition.X > SlideOffsetStart.X) + _IsSlidingActive = true; + else if (side == eSlideSide.Top && Control.MousePosition.Y - _MouseDownPoint.Y > SlideOffsetStart.Y) + _IsSlidingActive = true; + else if (side == eSlideSide.Bottom && _MouseDownPoint.Y - Control.MousePosition.Y > SlideOffsetStart.Y) + _IsSlidingActive = true; + } + if (IsMouseDown && _IsSlidingActive) + { + if (!this.Capture) + this.Capture = true; + Point p = Control.MousePosition; + eSlideSide side = _SlidePanel.SlideSide; + if (side == eSlideSide.Left) + _MouseOffset = new Point(Math.Max(0, p.X - _MouseDownPoint.X), 0); + else if (side == eSlideSide.Right) + _MouseOffset = new Point(Math.Max(0, _MouseDownPoint.X - p.X), 0); + else if (side == eSlideSide.Top) + _MouseOffset = new Point(0, Math.Max(0, p.Y - _MouseDownPoint.Y)); + else if (side == eSlideSide.Bottom) + _MouseOffset = new Point(0, Math.Max(0, _MouseDownPoint.Y - p.Y)); + + if (!_MouseOffset.IsEmpty) + { + UpdatePosition(); + + // Slide panel out + if (!_SlidePanel.Visible) + { + _SlidePanel.Visible = true; + _OriginalSlidePanelLocation = _SlidePanel.Location; + } + if (side == eSlideSide.Left) + _SlidePanel.Left = _OriginalSlidePanelLocation.X + _MouseOffset.X; + else if (side == eSlideSide.Right) + _SlidePanel.Left = _OriginalSlidePanelLocation.X - _MouseOffset.X; + else if (side == eSlideSide.Top) + _SlidePanel.Top = _OriginalSlidePanelLocation.Y + _MouseOffset.Y; + else if (side == eSlideSide.Bottom) + _SlidePanel.Top = _OriginalSlidePanelLocation.Y - _MouseOffset.Y; + } + } + base.OnMouseMove(e); + } + protected override void OnMouseUp(MouseEventArgs e) + { + if (IsMouseDown) + { + Point mousePosition = Control.MousePosition; + if (this.Capture) this.Capture = false; + + eSlideSide side = _SlidePanel.SlideSide; + if (side == eSlideSide.Left && mousePosition.X - _MouseDownPoint.X > SlideOutSnapOffset.X) + _SlidePanel.IsOpen = true; + else if (side == eSlideSide.Right && _MouseDownPoint.X - mousePosition.X > SlideOutSnapOffset.X) + _SlidePanel.IsOpen = true; + else if (side == eSlideSide.Top && mousePosition.Y - _MouseDownPoint.Y > SlideOutSnapOffset.Y) + _SlidePanel.IsOpen = true; + else if (side == eSlideSide.Bottom && _MouseDownPoint.Y - mousePosition.Y > SlideOutSnapOffset.Y) + _SlidePanel.IsOpen = true; + else if (_IsSlidingActive) + { + _SlidePanel.Location = _OriginalSlidePanelLocation; + _SlidePanel.Visible = false; + } + + IsMouseDown = false; + UpdatePosition(); + } + base.OnMouseUp(e); + } + protected override void OnMouseCaptureChanged(EventArgs e) + { + if (this.IsMouseDown && !this.Capture) + { + } + base.OnMouseCaptureChanged(e); + } + protected override void OnMouseEnter(EventArgs e) + { + Size newSize = ActiveSliderSize; + if (newSize != this.Size) + { + this.Size = newSize; + UpdatePosition(); + } + base.OnMouseEnter(e); + } + protected override void OnMouseLeave(EventArgs e) + { + Size newSize = this.SliderSize; + if (newSize != this.Size) + { + this.Size = newSize; + UpdatePosition(); + } + base.OnMouseLeave(e); + } + protected override void OnResize(EventArgs e) + { + this.Invalidate(); + base.OnResize(e); + } + internal void UpdatePosition() + { + Control parent = this.Parent; + if (parent == null) return; + eSlideSide side = _SlidePanel.SlideSide; + Point loc = new Point(); + //bool maximized = false; + //if (this.Parent is DevComponents.DotNetBar.Metro.MetroAppForm && ((Form)this.Parent).WindowState == FormWindowState.Maximized) maximized = true; + if (side == eSlideSide.Left) + { + loc.X = this.Margin.Left + _MouseOffset.X; + loc.Y = (parent.ClientRectangle.Height - this.Height) / 2 + this.Margin.Top; + //if (maximized) loc.X += MaximizedOffset; + } + else if (side == eSlideSide.Right) + { + loc.X = parent.ClientRectangle.Width - this.Margin.Right - this.Width - _MouseOffset.X; + loc.Y = (parent.ClientRectangle.Height - this.Height) / 2 + this.Margin.Top; + //if (maximized) loc.X -= MaximizedOffset; + } + else if (side == eSlideSide.Top) + { + loc.X = (parent.ClientRectangle.Width - this.Width) / 2 + this.Margin.Top; + loc.Y = this.Margin.Top + _MouseOffset.Y; + } + else if (side == eSlideSide.Bottom) + { + loc.X = (parent.ClientRectangle.Width - this.Width) / 2 + this.Margin.Top; + loc.Y = parent.ClientRectangle.Height - this.Margin.Bottom - this.Height - _MouseOffset.Y; + } + + this.Location = loc; + } + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + if (_Style != null) + { + ElementStyleDisplayInfo di = new ElementStyleDisplayInfo(_Style, g, this.ClientRectangle); + ElementStyleDisplay.Paint(di); + } + + if (!string.IsNullOrEmpty(_SymbolRealized)) + { + Font symFont = Symbols.GetFont(_SymbolSize, _SymbolSet); + Color foreColor = this.ForeColor; + bool disposeStyle = false; + ElementStyle style = null; + if (_Style != null) + { + style = ElementStyleDisplay.GetElementStyle(_Style, out disposeStyle); + } + if (style != null && !style.TextColor.IsEmpty) foreColor = style.TextColor; + if(disposeStyle) + style.Dispose(); + TextDrawing.DrawStringLegacy(g, _SymbolRealized, symFont, _SymbolColor.IsEmpty ? foreColor : _SymbolColor, + this.ClientRectangle, + eTextFormat.HorizontalCenter | eTextFormat.NoClipping | eTextFormat.VerticalCenter); + } + + base.OnPaint(e); + } + + + protected override void OnHandleCreated(EventArgs e) + { + SetupTopmostCheckTimer(); + base.OnHandleCreated(e); + } + + protected override void OnHandleDestroyed(EventArgs e) + { + DestroyTopmostCheckTimer(); + base.OnHandleDestroyed(e); + } + private Timer _Timer = null; + private void SetupTopmostCheckTimer() + { + if (_Timer != null || !_AutoTopMostEnabled) return; + _Timer = new Timer(); + _Timer.Interval = 800; + _Timer.Tick += new EventHandler(CheckAutoTopMostTimerTick); + _Timer.Start(); + } + void CheckAutoTopMostTimerTick(object sender, EventArgs e) + { + if (!this.Visible || this.Parent == null) return; + + Control parent = this.Parent; + if (parent.Controls.IndexOf(this) != 0) + { + parent.Controls.SetChildIndex(this, 0); + } + } + private void DestroyTopmostCheckTimer() + { + Timer timer = _Timer; + _Timer = null; + if (timer == null) return; + timer.Stop(); + timer.Dispose(); + } + + private bool _AutoTopMostEnabled = true; + /// + /// Gets or sets whether slider button automatically checks whether its top-most control on the form, i.e. visible at all times on top of other controls + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether slider button automatically checks whether its top-most control on the form, i.e. visible at all times on top of other controls")] + public bool AutoTopMostEnabled + { + get { return _AutoTopMostEnabled; } + set + { + if (value != _AutoTopMostEnabled) + { + bool oldValue = _AutoTopMostEnabled; + _AutoTopMostEnabled = value; + OnAutoTopMostEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when AutoTopMostEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnAutoTopMostEnabledChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("AutoTopMostEnabled")); + if (!newValue) + DestroyTopmostCheckTimer(); + else if (this.IsHandleCreated) + SetupTopmostCheckTimer(); + } + + internal static readonly Size DefaultSliderSize = new Size(16, 36); + private Size _SliderSize = DefaultSliderSize; + /// + /// Gets or sets the slider size in default state. Notice that size specified here applies to Left and Right SlidePanel positions. For Top and Bottom positions the Width and Height are interchaged. + /// + [Category("Appearance"), Description("Indicates slider size in default state. Notice that size specified here applies to Left and Right SlidePanel positions. For Top and Bottom positions the Width and Height are interchaged.")] + public Size SliderSize + { + get { return _SliderSize; } + set + { + if (value != _SliderSize) + { + Size oldValue = _SliderSize; + _SliderSize = value; + OnSliderSizeChanged(oldValue, value); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSliderSize() + { + return _SliderSize != DefaultSliderSize; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSliderSize() + { + SliderSize = DefaultSliderSize; + } + /// + /// Called when SliderSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSliderSizeChanged(Size oldValue, Size newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SliderSize")); + this.Size = newValue; + } + + internal static readonly Size DefaultActiveSliderSize = new Size(24, 36); + private Size _ActiveSliderSize = DefaultActiveSliderSize; + /// + /// Gets or sets the slider size in active state. Notice that size specified here applies to Left and Right SlidePanel positions. For Top and Bottom positions the Width and Height are interchaged. + /// + [Category("Appearance"), Description("Indicates slider size in active state. Notice that size specified here applies to Left and Right SlidePanel positions. For Top and Bottom positions the Width and Height are interchaged.")] + public Size ActiveSliderSize + { + get { return _ActiveSliderSize; } + set + { + if (value != _ActiveSliderSize) + { + Size oldValue = _ActiveSliderSize; + _ActiveSliderSize = value; + OnActiveSliderSizeChanged(oldValue, value); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeActiveSliderSize() + { + return _ActiveSliderSize != DefaultActiveSliderSize; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetActiveSliderSize() + { + ActiveSliderSize = DefaultActiveSliderSize; + } + /// + /// Called when ActiveSliderSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnActiveSliderSizeChanged(Size oldValue, Size newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("ActiveSliderSize")); + + } + + private bool _IsActive; + /// + /// Gets or sets whether slider button is in active state. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether slider button is in active state.")] + public bool IsActive + { + get { return _IsActive; } + set + { + if (value != _IsActive) + { + bool oldValue = _IsActive; + _IsActive = value; + OnIsActiveChanged(oldValue, value); + } + } + } + /// + /// Called when IsActive property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnIsActiveChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("IsActive")); + + } + + protected override Size DefaultSize + { + get + { + return GetSliderSize(); + } + } + private Size GetSliderSize() + { + Size sliderSize = this.IsActive ? ActiveSliderSize : SliderSize; + + if (_SlidePanel != null) + { + eSlideSide slideSide = _SlidePanel.SlideSide; + if (slideSide == eSlideSide.Left || slideSide == eSlideSide.Right) + return sliderSize; + else + return new Size(sliderSize.Height, sliderSize.Width); + } + + return sliderSize; + } + + private bool _IsMouseDown = false; + internal bool IsMouseDown + { + get { return _IsMouseDown; } + set + { + if (value != _IsMouseDown) + { + bool oldValue = _IsMouseDown; + _IsMouseDown = value; + OnIsMouseDownChanged(oldValue, value); + } + } + } + /// + /// Called when IsMouseDown property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnIsMouseDownChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("IsMouseDown")); + if (!newValue) + { + _IsSlidingActive = false; + _MouseOffset = Point.Empty; + } + this.Invalidate(); + } + + private ElementStyle _Style = null; + /// + /// Gets or sets the style associated with the control. + /// + public ElementStyle Style + { + get { return _Style; } + set + { + if (_Style != null) + _Style.StyleChanged -= this.ElementStyleChanged; + _Style = value; + if(_Style!=null) + _Style.StyleChanged += ElementStyleChanged; + this.Invalidate(); + } + } + + void ElementStyleChanged(object sender, EventArgs e) + { + this.Invalidate(); + } + + private Color _SymbolColor = Color.Empty; + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return _SymbolColor; } + set { _SymbolColor = value; this.Invalidate(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return !_SymbolColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + this.SymbolColor = Color.Empty; + } + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get { return _SymbolRealized; } + } + private string _Symbol = "", _SymbolRealized = ""; + /// + /// Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return _Symbol; } + set + { + if (value != _Symbol) + { + string oldValue = _Symbol; + _Symbol = value; + OnSymbolChanged(oldValue, value); + } + } + } + /// + /// Called when Symbol property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolChanged(string oldValue, string newValue) + { + if (string.IsNullOrEmpty(newValue)) + _SymbolRealized = ""; + else + _SymbolRealized = Symbols.GetSymbol(newValue); + this.Invalidate(); + } + + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return _SymbolSet; } + set + { + if (_SymbolSet != value) + { + eSymbolSet oldValue = _SymbolSet; + _SymbolSet = value; + OnSymbolSetChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSet property value changes. + /// + /// Indciates old value + /// Indicates new value + protected virtual void OnSymbolSetChanged(eSymbolSet oldValue, eSymbolSet newValue) + { + this.Invalidate(); + this.Refresh(); + } + + + private float _SymbolSize = 10f; + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(10f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return _SymbolSize; } + set + { + if (value != _SymbolSize) + { + float oldValue = _SymbolSize; + _SymbolSize = value; + OnSymbolSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolSizeChanged(float oldValue, float newValue) + { + this.Invalidate(); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Slider.cs b/PROMS/DotNetBar Source Code/Controls/Slider.cs new file mode 100644 index 00000000..7eb5f43b --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Slider.cs @@ -0,0 +1,450 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the Slider control. + /// + [ToolboxBitmap(typeof(Slider), "Controls.Slider.ico"), ToolboxItem(true), DefaultEvent("ValueChanged"), ComVisible(false), Designer("DevComponents.DotNetBar.Design.SliderDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class Slider : BaseItemControl, ICommandSource + { + #region Private Variables + private SliderItem m_Slider = null; + #endregion + + #region Events + /// + /// Occurs after Value property has changed. + /// + public event EventHandler ValueChanged; + + /// + /// Occurs before Value property has changed. + /// + public event CancelIntValueEventHandler ValueChanging; + + /// + /// Occurs when Increase button is clicked using mouse. + /// + public event EventHandler IncreaseButtonClick; + /// + /// Occurs when Decrease button is clicked using mouse. + /// + public event EventHandler DecreaseButtonClick; + #endregion + + #region Constructor, Dispose + public Slider() + { + m_Slider = new SliderItem(); + m_Slider.Style = eDotNetBarStyle.Office2007; + m_Slider.ValueChanged += new EventHandler(SliderValueChanged); + m_Slider.ValueChanging += new CancelIntValueEventHandler(SliderValueChanging); + m_Slider.IncreaseButtonClick += new EventHandler(SliderIncreaseButtonClick); + m_Slider.DecreaseButtonClick += new EventHandler(SliderDecreaseButtonClick); + this.HostItem = m_Slider; + } + + void SliderDecreaseButtonClick(object sender, EventArgs e) + { + OnDecreaseButtonClick(e); + } + + void SliderIncreaseButtonClick(object sender, EventArgs e) + { + OnIncreaseButtonClick(e); + } + + /// + /// Raises the IncreaseButtonClick event. + /// + /// Provides event arguments + protected virtual void OnIncreaseButtonClick(EventArgs e) + { + EventHandler handler = IncreaseButtonClick; + if (handler != null) handler(this, e); + } + /// + /// Raises the DecreaseButtonClick event. + /// + /// Provides event arguments + protected virtual void OnDecreaseButtonClick(EventArgs e) + { + EventHandler handler = DecreaseButtonClick; + if (handler != null) handler(this, e); + } + + + /// + /// Gets or sets whether text-markup support is enabled for controls Text property. Default value is true. + /// Set this property to false to display HTML or other markup in the control instead of it being parsed as text-markup. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether text-markup support is enabled for controls Text property.")] + public bool EnableMarkup + { + get { return m_Slider.EnableMarkup; } + set + { + m_Slider.EnableMarkup = value; + } + } + + private void SliderValueChanging(object sender, CancelIntValueEventArgs e) + { + OnValueChanging(e); + } + + private void SliderValueChanged(object sender, EventArgs e) + { + OnValueChanged(e); + ExecuteCommand(); + } + + /// + /// Raises the ValueChanged event. + /// + /// Provides event arguments + protected virtual void OnValueChanged(EventArgs e) + { + if (ValueChanged != null) + ValueChanged(this, e); + } + + /// + /// Raises the ValueChanging event. + /// + protected virtual void OnValueChanging(CancelIntValueEventArgs e) + { + if (ValueChanging != null) + ValueChanging(this, e); + } + + /// + /// Gets or sets the text label position in relationship to the slider. Default value is Left. + /// + [Browsable(true), DefaultValue(eSliderLabelPosition.Left), Category("Layout"), Description("Indicates text label position in relationship to the slider")] + public eSliderLabelPosition LabelPosition + { + get { return m_Slider.LabelPosition; } + set + { + m_Slider.LabelPosition = value; + } + } + + /// + /// Gets or sets whether the text label next to the slider is displayed. + /// + [DevCoBrowsable(true), Browsable(true), Description("Gets or sets whether the label text is displayed."), Category("Behavior"), DefaultValue(true)] + public bool LabelVisible + { + get + { + return m_Slider.LabelVisible; + } + set + { + m_Slider.LabelVisible = value; + } + } + + /// + /// Gets or sets the width of the label part of the item in pixels. Value must be greater than 0. Default value is 38. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(38), System.ComponentModel.Category("Layout"), System.ComponentModel.Description("Indicates width of the label part of the item in pixels.")] + public int LabelWidth + { + get + { + return m_Slider.LabelWidth; + } + set + { + m_Slider.LabelWidth = value; + } + } + + /// + /// Gets or sets the maximum value of the range of the control. + /// + [DevCoBrowsable(true), Browsable(true), Description("Gets or sets the maximum value of the range of the control."), Category("Behavior"), DefaultValue(100)] + public int Maximum + { + get + { + return m_Slider.Maximum; + } + set + { + m_Slider.Maximum = value; + } + } + + /// + /// Gets or sets the minimum value of the range of the control. + /// + [DevCoBrowsable(true), Browsable(true), Description("Gets or sets the minimum value of the range of the control."), Category("Behavior"), DefaultValue(0)] + public int Minimum + { + get + { + return m_Slider.Minimum; + } + set + { + m_Slider.Minimum = value; + } + } + + /// + /// Gets or sets the current position of the slider. + /// + [DevCoBrowsable(true), Browsable(true), Description("Gets or sets the current position of the slider."), Category("Behavior")] + public int Value + { + get { return m_Slider.Value; } + set + { + m_Slider.Value = value; + } + } + + /// + /// Gets or sets the amount by which a call to the PerformStep method increases the current position of the slider. Value must be greater than 0. + /// + [DevCoBrowsable(true), Browsable(true), Description("Gets or sets the amount by which a call to the PerformStep method increases the current position of the slider."), Category("Behavior"), DefaultValue(1)] + public int Step + { + get + { + return m_Slider.Step; + } + set + { + m_Slider.Step = value; + } + } + + /// + /// Advances the current position of the slider by the amount of the Step property. + /// + public void PerformStep() + { + m_Slider.PerformStep(); + } + + /// + /// Gets or sets the color of the label text. + /// + [Browsable(true), Category("Appearance"), Description("Indicates color of the label text.")] + public Color TextColor + { + get { return m_Slider.TextColor; } + set + { + m_Slider.TextColor = value; + } + } + /// + /// Returns whether property should be serialized. Used by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return m_Slider.ShouldSerializeTextColor(); + } + /// + /// Resets the property to default value. Used by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + m_Slider.ResetTextColor(); + } + + [Browsable(false)] + public override Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + + /// + /// Gets or sets whether vertical line track marker is displayed on the slide line. Default value is true. + /// + [Browsable(true), Category("Appearance"), DefaultValue(true), Description("Indicates whether vertical line track marker is displayed on the slide line.")] + public virtual bool TrackMarker + { + get { return m_Slider.TrackMarker; } + set + { + m_Slider.TrackMarker = value; + } + } + + /// + /// Forces the button to perform internal layout. + /// + public override void RecalcLayout() + { + Rectangle r = GetItemBounds(); + m_Slider.Width = Math.Max(r.Width - (m_Slider.LabelVisible ? m_Slider.LabelWidth : 0), 30); + base.RecalcLayout(); + } + + protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + { + if (keyData == System.Windows.Forms.Keys.Left) + { + m_Slider.Increment(-m_Slider.Step, eEventSource.Keyboard); + return true; + } + else if (keyData == System.Windows.Forms.Keys.Right) + { + m_Slider.Increment(m_Slider.Step, eEventSource.Keyboard); + return true; + } + return base.ProcessCmdKey(ref msg, keyData); + } + + /// + /// Gets or sets the tooltip for the Increase button of the slider. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates tooltip for the Increase button of the slider.")] + public string IncreaseTooltip + { + get { return m_Slider.IncreaseTooltip; } + set { m_Slider.IncreaseTooltip = value; } + } + + /// + /// Gets or sets the tooltip for the Decrease button of the slider. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates tooltip for the Increase button of the slider.")] + public string DecreaseTooltip + { + get { return m_Slider.DecreaseTooltip; } + set { m_Slider.DecreaseTooltip = value; } + } + + /// + /// Gets or sets the slider orientation. Default value is horizontal. + /// + [DefaultValue(eOrientation.Horizontal), Category("Appearance"), Description("Indicates slider orientation.")] + public eOrientation SliderOrientation + { + get { return m_Slider.SliderOrientation; } + set + { + m_Slider.SliderOrientation = value; + this.RecalcLayout(); + } + } + + /// + /// Gets the SliderItem. + /// + internal SliderItem SliderItem + { + get { return (m_Slider); } + } + + /// + /// Gets or sets the custom color table for the item. Color table here will override all system color table settings. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DevComponents.DotNetBar.Rendering.Office2007SliderColorTable ColorTable + { + get + { + return m_Slider.ColorTable; + } + set + { + m_Slider.ColorTable = value; + } + } + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + CommandManager.ExecuteCommand(this); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + } + } + + private ICommand _Command = null; + //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if (changed) + OnCommandChanged(); + } + } + + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Slider.ico b/PROMS/DotNetBar Source Code/Controls/Slider.ico new file mode 100644 index 00000000..64e7a6eb Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/Slider.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/StepIndicator.ico b/PROMS/DotNetBar Source Code/Controls/StepIndicator.ico new file mode 100644 index 00000000..6ff9cd13 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/StepIndicator.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/SwitchButton.ico b/PROMS/DotNetBar Source Code/Controls/SwitchButton.ico new file mode 100644 index 00000000..b0c869e7 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/SwitchButton.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/SymbolBox.cs b/PROMS/DotNetBar Source Code/Controls/SymbolBox.cs new file mode 100644 index 00000000..c0531f89 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/SymbolBox.cs @@ -0,0 +1,265 @@ +using DevComponents.DotNetBar.Rendering; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents the control which displays symbol from symbols library. + /// + [ToolboxBitmap(typeof(SymbolBox), "Controls.SymbolBox.ico"), ToolboxItem(true)] + public class SymbolBox : Control + { + #region Constructor + /// + /// Initializes a new instance of the SymbolBox class. + /// + public SymbolBox() + { + this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | + ControlStyles.Opaque | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | + ControlStyles.StandardDoubleClick | DisplayHelp.DoubleBufferFlag, true); + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + } + #endregion + + #region Implementation + protected override void OnPaint(PaintEventArgs e) + { + if ((this.BackColor.IsEmpty || this.BackColor == Color.Transparent)) + { + base.OnPaintBackground(e); + } + + if (_BackgroundStyle != null) + _BackgroundStyle.SetColorScheme(this.GetColorScheme()); + + PaintBackground(e); + PaintContent(e); + + base.OnPaint(e); + } + + private void PaintContent(PaintEventArgs e) + { + float symbolSize = _SymbolSize; + Graphics g = e.Graphics; + + Rectangle r = ElementStyleLayout.GetInnerRect(_BackgroundStyle, this.ClientRectangle); + + if (symbolSize <= 0) + symbolSize = Math.Max(1, Math.Min(r.Width, r.Height) * 72 / g.DpiX - 1); + + Color symbolColor = _SymbolColor; + if (_SymbolColor.IsEmpty) + { + if (!_BackgroundStyle.TextColor.IsEmpty) + symbolColor = _BackgroundStyle.TextColor; + else if (!this.ForeColor.IsEmpty) + symbolColor = this.ForeColor; + else + symbolColor = SystemColors.ControlText; + } + TextDrawing.DrawStringLegacy(g, _SymbolRealized, Symbols.GetFont(symbolSize, _SymbolSet), + symbolColor, r, eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter); + } + + protected virtual void PaintBackground(PaintEventArgs e) + { + Graphics g = e.Graphics; + Rectangle r = this.ClientRectangle; + ElementStyle style = _BackgroundStyle; + + if (!this.BackColor.IsEmpty && this.BackColor != Color.Transparent) + { + DisplayHelp.FillRectangle(g, r, this.BackColor); + } + + if (this.BackgroundImage != null) + base.OnPaintBackground(e); + + if (style.Custom) + { + SmoothingMode sm = g.SmoothingMode; + //if (m_AntiAlias) + // g.SmoothingMode = SmoothingMode.HighQuality; + ElementStyleDisplayInfo displayInfo = new ElementStyleDisplayInfo(style, e.Graphics, r); + ElementStyleDisplay.Paint(displayInfo); + //if (m_AntiAlias) + // g.SmoothingMode = sm; + } + } + + /// + /// Returns the color scheme used by control. Color scheme for Office2007 style will be retrieved from the current renderer instead of + /// local color scheme referenced by ColorScheme property. + /// + /// An instance of ColorScheme object. + protected virtual ColorScheme GetColorScheme() + { + BaseRenderer r = Rendering.GlobalManager.Renderer; + if (r is Office2007Renderer) + return ((Office2007Renderer)r).ColorTable.LegacyColors; + return new ColorScheme(); + } + + private ElementStyle _BackgroundStyle = null; + /// + /// Specifies the background style of the control. + /// + [Browsable(true), Category("Style"), Description("Gets or sets bar background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return _BackgroundStyle; } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _BackgroundStyle.StyleChanged -= new EventHandler(this.VisualPropertyChanged); + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + this.Invalidate(); + } + private void VisualPropertyChanged(object sender, EventArgs e) + { + this.Invalidate(); + } + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get { return _SymbolRealized; } + } + private string _Symbol = "\uf015", _SymbolRealized = "\uf015"; + /// + /// Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue("\uf015"), Category("Appearance"), Description("Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return _Symbol; } + set + { + if (value != _Symbol) + { + string oldValue = _Symbol; + _Symbol = value; + OnSymbolChanged(oldValue, value); + } + } + } + /// + /// Called when Symbol property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolChanged(string oldValue, string newValue) + { + if (string.IsNullOrEmpty(newValue)) + _SymbolRealized = ""; + else + _SymbolRealized = Symbols.GetSymbol(newValue); + //OnPropertyChanged(new PropertyChangedEventArgs("Symbol")); + this.Invalidate(); + } + + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return _SymbolSet; } + set + { + if (_SymbolSet != value) + { + eSymbolSet oldValue = _SymbolSet; + _SymbolSet = value; + OnSymbolSetChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSet property value changes. + /// + /// Indciates old value + /// Indicates new value + protected virtual void OnSymbolSetChanged(eSymbolSet oldValue, eSymbolSet newValue) + { + this.Invalidate(); + } + + private Color _SymbolColor = Color.Empty; + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return _SymbolColor; } + set { _SymbolColor = value; this.Refresh(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return !_SymbolColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + this.SymbolColor = Color.Empty; + } + + private float _SymbolSize = 0f; + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(0f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return _SymbolSize; } + set + { + if (value != _SymbolSize) + { + float oldValue = _SymbolSize; + _SymbolSize = value; + OnSymbolSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolSizeChanged(float oldValue, float newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SymbolSize")); + this.Invalidate(); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/SymbolBox.ico b/PROMS/DotNetBar Source Code/Controls/SymbolBox.ico new file mode 100644 index 00000000..d50d1b7e Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/SymbolBox.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/TabFormControl.ico b/PROMS/DotNetBar Source Code/Controls/TabFormControl.ico new file mode 100644 index 00000000..39973b9e Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/TabFormControl.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/MultiFormAppContext.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/MultiFormAppContext.cs new file mode 100644 index 00000000..980c0764 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/MultiFormAppContext.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + public class MultiFormAppContext : ApplicationContext + { + private List _OpenedForms = new List(); + + public MultiFormAppContext(Form initialForm) + { + // Handle the ApplicationExit event to know when the application is exiting. + Application.ApplicationExit += new EventHandler(this.OnApplicationExit); + WeakReference reference=new WeakReference(initialForm); + _OpenedForms.Add(reference); + initialForm.FormClosed += FormClosed; + initialForm.Show(); + } + + public void RegisterOpenForm(Form form) + { + bool opened = false; + foreach (WeakReference item in _OpenedForms) + { + object target = item.Target; + + if (target != null && target.Equals(form)) + { + opened = true; + break; + } + } + + if (!opened) + { + WeakReference reference = new WeakReference(form); + _OpenedForms.Add(reference); + form.FormClosed += FormClosed; + } + } + /// + /// Returns read-only list of opened forms. + /// + public List
OpenedForms + { + get + { + List list=new List(); + foreach (WeakReference item in _OpenedForms) + { + object target = item.Target; + if (target != null && target is Form) + { + list.Add((Form)target); + } + } + + return list; + } + } + + private void FormClosed(object sender, FormClosedEventArgs e) + { + Form form = (Form) sender; + form.FormClosed -= FormClosed; + foreach (WeakReference item in _OpenedForms) + { + object target = item.Target; + + if (target != null && target.Equals(form)) + { + _OpenedForms.Remove(item); + break; + } + } + + if(_OpenedForms.Count==0) + ExitThread(); + } + + protected virtual void OnApplicationExit(object sender, EventArgs e) + { + + } + + private static MultiFormAppContext _CurrentMultiFormAppContext=null; + /// + /// Gets or sets current MultiFormAppContext context. If you are using MultiFormAppContext to start your app then you should also + /// set that instance of MultiFormAppContext to this property so internally TabFormControl can register any new deattached forms + /// and prevent application from closing if startup form is closed first. + /// + public static MultiFormAppContext Current + { + get { return _CurrentMultiFormAppContext; } + set { _CurrentMultiFormAppContext = value; } + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/NewTabFormItem.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/NewTabFormItem.cs new file mode 100644 index 00000000..0e425e06 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/NewTabFormItem.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Controls +{ + public class NewTabFormItem : TabFormItemBase + { + #region Internal Implementation + public override void Paint(ItemPaintArgs p) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + p.ButtonItemRendererEventArgs.Graphics = p.Graphics; + p.ButtonItemRendererEventArgs.ButtonItem = this; + p.ButtonItemRendererEventArgs.ItemPaintArgs = p; + renderer.DrawNewTabFormItem(p.ButtonItemRendererEventArgs); + } + + if (!string.IsNullOrEmpty(NotificationMarkText)) + DevComponents.DotNetBar.Rendering.NotificationMarkPainter.Paint(p.Graphics, this.Bounds, NotificationMarkPosition, + NotificationMarkText, new Size(NotificationMarkSize, NotificationMarkSize), NotificationMarkOffset, NotificationMarkColor); + this.DrawInsertMarker(p.Graphics); + } + + public override void RecalcSize() + { + m_Rect.Width = Dpi.Width32 + TabFormItem.TabOverlap/2; + m_Rect.Height = Dpi.Height16; + m_NeedRecalcSize = false; + + } + + private string _CashedColorTableName = "Default"; + internal override string GetColorTableName() + { + return this.CustomColorName != "" ? this.CustomColorName : _CashedColorTableName; + } + + private Color[] _BackColors = null; + /// + /// Indicates the array of colors that when set are used to draw the background of the item. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the background of the item."), TypeConverter(typeof(ArrayConverter))] + public Color[] BackColors + { + get + { + return _BackColors; + } + set + { + if (_BackColors != value) + { + _BackColors = value; + //OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + this.Refresh(); + } + } + } +#endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/OfficeNewTabFormItemPainter.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/OfficeNewTabFormItemPainter.cs new file mode 100644 index 00000000..8ff823fb --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/OfficeNewTabFormItemPainter.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class OfficeNewTabFormItemPainter : Office2007ButtonItemPainter + { + protected override void PaintState(ButtonItem button, ItemPaintArgs pa, CompositeImage image, Rectangle r, bool isMouseDown) + { + if (r.IsEmpty || !IsItemEnabled(button, pa) || r.Width == 0 || r.Height == 0) + return; + + NewTabFormItem tab = button as NewTabFormItem; + if (tab == null || IsOnMenu(button, pa)) + { + base.PaintState(button, pa, image, r, isMouseDown); + return; + } + + bool isOnMenu = pa.IsOnMenu; + TabFormItemColorTable tabColorTable = GetColorTable(tab); + if (tabColorTable == null) + return; + + TabFormItemStateColorTable stateColors = GetStateColorTable(tabColorTable, tab); + + if (stateColors == null) + return; + + r.X += Overlap; + r.Width -= Overlap; + + Graphics g = pa.Graphics; + Region oldClip = g.Clip; + try + { + Rectangle rClip = GetTabBounds(tab); + rClip.Inflate(2, 1); + g.SetClip(rClip, CombineMode.Intersect); + + if (stateColors.BackColors != null && stateColors.BackColors.Length > 0 || tab.BackColors != null && tab.BackColors.Length > 0) + { + using (Brush brush = DisplayHelp.CreateBrush(r, (tab.BackColors != null && tab.BackColors.Length > 0) ? tab.BackColors : stateColors.BackColors, stateColors.BackColorsGradientAngle, stateColors.BackColorsPositions)) + { + GraphicsPath path = GetTabPath(r); + g.FillPath(brush, path); + tab.TabPath = path; + } + } + + if (stateColors.BorderColors.Length > 0) + { + Rectangle borderRect = r; + foreach (Color color in stateColors.BorderColors) + { + using (GraphicsPath path = GetTabPath(borderRect)) + { + using (Pen pen = new Pen(color, Dpi.Width1)) + { + pen.LineJoin = LineJoin.Round; + g.DrawPath(pen, path); + } + } + borderRect.Inflate(-Dpi.Width1, -Dpi.Width1); + } + } + + g.Clip = oldClip; + } + finally + { + if (oldClip != null) oldClip.Dispose(); + } + } + + private int Overlap + { + get { return TabFormItem.TabOverlap / 2; } + } + + private Rectangle GetTabBounds(NewTabFormItem tab) + { + Rectangle r = tab.DisplayRectangle; + r.X += Overlap; + r.Width -= Overlap; + using (GraphicsPath tabPath = GetTabPath(r)) + r = Rectangle.Round(tabPath.GetBounds()); + return r; + } + + private GraphicsPath GetTabPath(Rectangle r) + { + GraphicsPath path = new GraphicsPath(); + //float factor = r.Height / 13.5f; + + path.AddLine(2, 0, 5, 14); + path.AddLine(31, 14, 28, 0); + + //path.AddLine(29.5f, 14.5f, 6.5f, 14.5f); + //path.AddCurve(new PointF[] + //{ + // new PointF(5.83333f,14.1667f ), + // new PointF(5.16667f,13.8333f), + // new PointF(4.66667f,13.1667f) + //}); + //path.AddCurve(new PointF[] + //{ + // new PointF(4.16667f,12.5f), + // new PointF(3.83333f,11.5f), + // new PointF(3.16667f,9.83333f) + //}); + //path.AddCurve(new PointF[] + //{ + // new PointF(2.5f,8.16667f ), + // new PointF(1.5f,5.83333f ), + // new PointF(1f,4.16667f) + //}); + //path.AddCurve(new PointF[] + //{ + // new PointF(0.5f,2.5f), + // new PointF(0.5f,1.5f ), + // new PointF(0.5f,0.5f) + //}); + //path.AddLine(0.5f, 0.5f, 25.5f, 0.5f); + //path.AddCurve(new PointF[] + //{ + // new PointF(26.8333f,2.5f ), + // new PointF(28.1667f,4.5f ), + // new PointF(29.1667f,6.83333f) + //}); + //path.AddCurve(new PointF[] + //{ + // new PointF(30.1667f,9.16667f ), + // new PointF(30.8333f,11.8333f ), + // new PointF(30.8333f,13.1667f) + //}); + //path.AddCurve(new PointF[] + //{ + // new PointF(30.8333f,14.5f ), + // new PointF(30.1667f,14.5f ), + // new PointF(30.1667f,14.5f ) + //}); + + path.CloseAllFigures(); + + Matrix translateMatrix = new Matrix(); + translateMatrix.Translate(r.X, r.Y); + if (Dpi.Factor.Width > 1) + translateMatrix.Scale(Dpi.Factor.Width, Dpi.Factor.Width); + path.Transform(translateMatrix); + + return path; + } + + + private TabFormItemColorTable GetColorTable(NewTabFormItem tab) + { + return this.ColorTable.TabFormItemColorTables[tab.GetColorTableName()]; + } + + internal static TabFormItemStateColorTable GetStateColorTable(TabFormItemColorTable tabColorTable, NewTabFormItem tab) + { + if (tabColorTable == null) + return null; + + TabFormItemStateColorTable stateColors = null; + + if (!tab.RenderTabState) + stateColors = tabColorTable.Default; + else if (!tab.GetEnabled()) + stateColors = tabColorTable.Disabled; + else if (tab.Checked) + stateColors = tabColorTable.Selected; + else if (tab.IsMouseOver) + stateColors = tabColorTable.MouseOver; + else + stateColors = tabColorTable.Default; + + return stateColors; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/OfficeTabFormItemPainter.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/OfficeTabFormItemPainter.cs new file mode 100644 index 00000000..83b7968f --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/OfficeTabFormItemPainter.cs @@ -0,0 +1,426 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class OfficeTabFormItemPainter : Office2007ButtonItemPainter + { + protected override Rectangle GetTextRectangle(ButtonItem button, ItemPaintArgs pa, eTextFormat stringFormat, CompositeImage image) + { + Rectangle r = base.GetTextRectangle(button, pa, stringFormat, image); + if (image == null && string.IsNullOrEmpty(button.SymbolRealized)) + { + r.Inflate(-(TabFormItem.TabOverlap / 2), 0); + //r.Inflate(-3, 0); + } + else + r.X += TabFormItem.TabOverlap / 2 - TabFormItem.Offset; + + return r; + } + + public override Rectangle GetImageRectangle(ButtonItem button, ItemPaintArgs pa, CompositeImage image) + { + Rectangle r = base.GetImageRectangle(button, pa, image); + //if (button.ImagePosition == eImagePosition.Left) + r.X += TabFormItem.TabOverlap / 2 - TabFormItem.Offset; + //else if (button.ImagePosition == eImagePosition.Right) + // r.X -= TabOverlap/2 - Offset; + return r; + } + + public override eTextFormat GetStringFormat(ButtonItem button, ItemPaintArgs pa, CompositeImage image) + { + eTextFormat sf = base.GetStringFormat(button, pa, image); + sf &= ~(sf & eTextFormat.EndEllipsis); + return sf; + } + + protected override void PaintState(ButtonItem button, ItemPaintArgs pa, CompositeImage image, Rectangle r, bool isMouseDown) + { + if (r.IsEmpty || !IsItemEnabled(button, pa) || r.Width == 0 || r.Height == 0) + return; + + TabFormItem tab = button as TabFormItem; + if (tab == null || IsOnMenu(button, pa)) + { + base.PaintState(button, pa, image, r, isMouseDown); + return; + } + + bool isOnMenu = pa.IsOnMenu; + TabFormItemColorTable tabColorTable = GetColorTable(tab); + if (tabColorTable == null) + return; + + TabFormItemStateColorTable stateColors = GetStateColorTable(tabColorTable, tab); + + if (stateColors == null) + return; + + Graphics g = pa.Graphics; + Region oldClip = g.Clip; + try + { + Rectangle rClip = GetTabBounds(tab); + rClip.Inflate(1, 0); + g.SetClip(rClip, CombineMode.Intersect); + + eTabFormStripControlDock tabAlign = tab.TabAlignment; + tab.TabPath = GetTabPath(r, tabAlign, true); + if (stateColors.BackColors != null && stateColors.BackColors.Length > 0 || tab.BackColors != null && tab.BackColors.Length > 0) + { + using (Brush brush = DisplayHelp.CreateBrush(r, (tab.BackColors != null && tab.BackColors.Length > 0) ? tab.BackColors : stateColors.BackColors, stateColors.BackColorsGradientAngle, stateColors.BackColorsPositions)) + { + using (GraphicsPath path = GetTabPath(r, tabAlign, true)) + { + g.FillPath(Brushes.White, path); + g.FillPath(brush, path); + } + } + } + + if (stateColors.BorderColors.Length > 0) + { + Rectangle borderRect = r; + foreach (Color color in stateColors.BorderColors) + { + using (GraphicsPath path = GetTabPath(borderRect, tabAlign, false)) + { + using (Pen pen = new Pen(color, Dpi.Width1)) + g.DrawPath(pen, path); + } + borderRect.Inflate(-Dpi.Width1, -Dpi.Width1); + } + + } + + if (tab.CloseButtonVisible) + { + int closeButtonSize = Dpi.Width(TabFormItem.CloseButtonSize); + Rectangle closeBounds = new Rectangle(r.Right - (TabFormItem.TabOverlap + TabFormItem.Radius - TabFormItem.Offset), r.Y + (r.Height - closeButtonSize) / 2 + Dpi.Height1, closeButtonSize, closeButtonSize); + TabCloseButtonStateColorTable closeButtonColorTable = GetCloseButtonColorTable(tabColorTable, tab); + if (closeButtonColorTable.BackColors.Length > 0) + { + using ( + Brush brush = DisplayHelp.CreateBrush(closeBounds, closeButtonColorTable.BackColors, + closeButtonColorTable.BackColorsGradientAngle, closeButtonColorTable.BackColorsPositions) + ) + { + g.FillEllipse(brush, closeBounds); + } + } + + if (!closeButtonColorTable.BorderColor.IsEmpty) + { + using (Pen pen = new Pen(closeButtonColorTable.BorderColor, Dpi.Width1)) + { + g.DrawEllipse(pen, closeBounds); + } + } + Color fc = stateColors.TextColor; + if (!closeButtonColorTable.ForeColor.IsEmpty) + fc = closeButtonColorTable.ForeColor; + + + using (Pen pen = new Pen(fc, Dpi.Width2)) + { + Rectangle rc = closeBounds; + rc.Inflate(-Dpi.Width3, -Dpi.Width3); + + g.DrawLine(pen, rc.X, rc.Y, rc.Right, rc.Bottom); + g.DrawLine(pen, rc.Right, rc.Y, rc.X, rc.Bottom); + + } + + tab.CloseButtonBounds = closeBounds; + } + else + tab.CloseButtonBounds = Rectangle.Empty; + + if (tab.Checked) + { + g.ResetClip(); + using (Pen pen = new Pen(stateColors.BorderColors[0], Dpi.Width1)) + { + Rectangle tb = GetTabBounds(tab); + tb.Inflate(-Dpi.Width2, 0); + TabFormItemsSimpleContainer cont = tab.Parent as TabFormItemsSimpleContainer; + if (cont == null || cont.ClippingRectangle.IsEmpty || cont.ClippingRectangle.IntersectsWith(tb)) + { + if (cont != null && !cont.ClippingRectangle.IsEmpty && cont.ClippingRectangle.IntersectsWith(tb) && tb.Right > cont.ClippingRectangle.Right) + tb.Width = Math.Max(1, cont.ClippingRectangle.Right - tb.X); + + if (tabAlign == eTabFormStripControlDock.Bottom) + { + g.DrawLine(pen, 0, tb.Y, tb.X, tb.Y); + g.DrawLine(pen, tb.Right, tb.Y, pa.ContainerControl.Width, tb.Y); + } + else + { + g.DrawLine(pen, 0, tb.Bottom - 1, tb.X, tb.Bottom - 1); + g.DrawLine(pen, tb.Right, tb.Bottom - 1, pa.ContainerControl.Width, tb.Bottom - 1); + } + } + else + { + if (tabAlign == eTabFormStripControlDock.Bottom) + { + g.DrawLine(pen, 0, tb.Y, pa.ContainerControl.Width, tb.Y); + } + else + { + g.DrawLine(pen, 0, tb.Bottom - 1, pa.ContainerControl.Width, tb.Bottom - 1); + } + } + } + } + + g.Clip = oldClip; + } + finally + { + if (oldClip != null) oldClip.Dispose(); + } + } + + private TabCloseButtonStateColorTable GetCloseButtonColorTable(TabFormItemColorTable tabColorTable, TabFormItem tab) + { + if (tab.CloseButtonState == eButtonState.MouseDownLeft) + return tabColorTable.CloseButton.Pressed; + else if (tab.CloseButtonState == eButtonState.MouseOver) + return tabColorTable.CloseButton.MouseOver; + + return tabColorTable.CloseButton.Normal; + } + + private Rectangle GetTabBounds(TabFormItem tab) + { + Rectangle r = tab.DisplayRectangle; + using (GraphicsPath tabPath = GetTabPath(r, tab.TabAlignment, false)) + r = Rectangle.Round(tabPath.GetBounds()); + return r; + } + private GraphicsPath GetTabPath(Rectangle r, eTabFormStripControlDock align, bool bCloseFigure) + { + return GetTopTabPath(r); + Rectangle rbox = r; + + //if (align == eTabFormStripControlDock.Left) + //{ + // // Left + // rbox = new Rectangle(r.X, r.Y, r.Height, r.Width); + //} + //else if (align == eTabFormStripControlDock.Right) + //{ + // // Right + // rbox = new Rectangle(r.Right - r.Height, r.Y, r.Height, r.Width); + //} + + GraphicsPath path = new GraphicsPath(); + + if (align != eTabFormStripControlDock.Bottom) + { + Point[] p = new Point[4]; + int slope = Math.Min(rbox.Width > rbox.Height ? 16 : 10, rbox.Height / 2); + p[0].X = rbox.X - (slope + Dpi.Width6); + p[0].Y = rbox.Bottom - 1; + p[1].X = p[0].X + Dpi.Width6; + p[1].Y = p[0].Y - Dpi.Height4; + p[2].X = p[1].X + slope - Dpi.Width4; + p[2].Y = rbox.Y + Dpi.Height3; + p[3].X = rbox.X + Dpi.Width3; + p[3].Y = rbox.Y; + path.AddCurve(p, 0, 3, Math.Max(.3f, 1f * Math.Min(1, slope / (float)rbox.Height))); + + //path.AddLine(p[3].X + 1, rbox.Y, rbox.Right-Dpi.Width4, rbox.Y); + + p = new Point[4]; + p[0].X = rbox.Right - Dpi.Width3; + p[0].Y = rbox.Y; + p[1].X = p[0].X + Dpi.Width7; + p[1].Y = p[0].Y + Dpi.Height3; + p[2].X = p[1].X + slope - Dpi.Width4; + p[2].Y = rbox.Bottom - Dpi.Height4 - 1; + p[3].X = p[2].X + Dpi.Width6; + p[3].Y = rbox.Bottom - 1; + path.AddCurve(p, 0, 3, Math.Max(.1f, 1f * Math.Min(1, slope / (float)rbox.Height))); + + if (bCloseFigure) + { + path.AddLine(p[0].X, rbox.Bottom, rbox.Right, rbox.Bottom); + path.CloseAllFigures(); + } + } + else + { + Point[] p = new Point[4]; + int slope = Math.Min(18, rbox.Height / 2); + + p[0].X = rbox.X - (slope + Dpi.Width6); + p[0].Y = rbox.Y; + p[1].X = p[0].X + Dpi.Width6; + p[1].Y = p[0].Y + Dpi.Height4; + p[2].X = p[1].X + slope - Dpi.Width4; + p[2].Y = rbox.Bottom - Dpi.Height3 - 1; + p[3].X = rbox.X + Dpi.Width3; + p[3].Y = rbox.Bottom - 1; + path.AddCurve(p, 0, 3, Math.Max(.1f, 1f * Math.Min(1, slope / (float)rbox.Height))); + + //path.AddLine(p[3].X + 1, rbox.Y, rbox.Right-Dpi.Width4, rbox.Y); + + p = new Point[4]; + p[0].X = rbox.Right - Dpi.Width3; + p[0].Y = rbox.Bottom; + p[1].X = p[0].X + Dpi.Width6; + p[1].Y = p[0].Y - Dpi.Height3; + p[2].X = p[1].X + slope - Dpi.Width4; + p[2].Y = rbox.Y + Dpi.Height4; + p[3].X = p[2].X + Dpi.Width6; + p[3].Y = rbox.Y; + path.AddCurve(p, 0, 3, Math.Max(.1f, 1f * Math.Min(1, slope / (float)rbox.Height))); + + if (bCloseFigure) + { + path.AddLine(p[0].X, rbox.Bottom, rbox.Right, rbox.Bottom); + path.CloseAllFigures(); + } + } + + //if (align == eTabStripAlignment.Left) + //{ + // // Left + // Matrix m = new Matrix(); + // //RectangleF rf=path.GetBounds(); + // m.RotateAt(-90, new PointF(rbox.X, rbox.Bottom)); + // m.Translate(rbox.Height, rbox.Width - rbox.Height, MatrixOrder.Append); + // path.Transform(m); + //} + //else if (align == eTabStripAlignment.Right) + //{ + // // Right + // Matrix m = new Matrix(); + // //RectangleF rf=path.GetBounds(); + // m.RotateAt(90, new PointF(rbox.Right, rbox.Bottom)); + // m.Translate(-rbox.Height, rbox.Width - (rbox.Height - 1), MatrixOrder.Append); + // path.Transform(m); + //} + + return path; + } + + private GraphicsPath GetTopTabPath(Rectangle tabRect) + { + Rectangle r = tabRect; + r.Width -= Dpi.Width1; + //r.Height -= Dpi.Height(StripeBot); + + int k = Math.Min(20, r.Height); + float scale = (float)k / 20; + + int delta = (int)(90 * scale) - 25; + int n = (int)((TabFormItem.TabOverlap / 2f) * scale); + + // Create the path + + GraphicsPath path = new GraphicsPath(); + + int dia = TabFormItem.Dia; + Rectangle ar = new Rectangle(r.X - TabFormItem.Radius, r.Bottom - dia, dia, dia); + path.AddArc(ar, 90, -delta); + + int offset = TabFormItem.Offset; + ar = new Rectangle(r.X + TabFormItem.Radius + offset, r.Y, dia, dia); + path.AddArc(ar, 270 - delta, delta); + + ar = new Rectangle(r.Right - (dia + offset + n), r.Y, dia, dia); + path.AddArc(ar, 270, delta); + + ar = new Rectangle(r.Right - (dia - offset * 2), r.Bottom - dia, dia, dia); + path.AddArc(ar, 90 + delta, -delta); + + return (path); + } + + + + protected override Color GetTextColor(ButtonItem button, ItemPaintArgs pa) + { + if (!IsItemEnabled(button, pa) || !(button is TabFormItem)) + return base.GetTextColor(button, pa); + + TabFormItem tab = button as TabFormItem; + if (!tab.ForeColor.IsEmpty) + return tab.ForeColor; + + Color textColor = Color.Empty; + + TabFormItemStateColorTable ct = GetStateColorTable(GetColorTable(tab), tab); + + if (ct != null) + { + //if (pa.GlassEnabled && !ct.GlassText.IsEmpty) + // return ct.GlassText; + textColor = ct.TextColor; + } + + if (textColor.IsEmpty) + return base.GetTextColor(button, pa); + + return textColor; + } + + private TabFormItemColorTable GetColorTable(TabFormItem tab) + { + return this.ColorTable.TabFormItemColorTables[tab.GetColorTableName()]; + } + + internal static TabFormItemStateColorTable GetStateColorTable(TabFormItemColorTable tabColorTable, TabFormItem tab) + { + if (tab.CustomColorTable != null) + tabColorTable = tab.CustomColorTable; + + if (tabColorTable == null) + return null; + + TabFormItemStateColorTable stateColors = null; + + if (!tab.RenderTabState) + stateColors = tabColorTable.Default; + else if (!tab.GetEnabled()) + stateColors = tabColorTable.Disabled; + else if (tab.Checked) + stateColors = tabColorTable.Selected; + else if (tab.IsMouseOver) + stateColors = tabColorTable.MouseOver; + else + stateColors = tabColorTable.Default; + + return stateColors; + } + //#if FRAMEWORK20 + // public override void PaintButtonText(ButtonItem button, ItemPaintArgs pa, Color textColor, CompositeImage image) + // { + // eDotNetBarStyle effectiveStyle = button.EffectiveStyle; + // if (!((effectiveStyle == eDotNetBarStyle.Office2010 || StyleManager.IsMetro(effectiveStyle)) && pa.GlassEnabled)) + // { + // base.PaintButtonText(button, pa, textColor, image); + // return; + // } + + // Rectangle r = GetTextRectangle(button, pa, eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter, image); + // //r.Offset(0, 3); + // //r.Height -= 2; + // ThemeTextFormat textFormat = ThemeTextFormat.Center | ThemeTextFormat.VCenter | ThemeTextFormat.HidePrefix | ThemeTextFormat.SingleLine; + // bool renderGlow = true; + // //if (effectiveStyle == eDotNetBarStyle.Office2010 && StyleManager.Style == eStyle.Office2010Black) + // // renderGlow = false; + // Office2007RibbonControlPainter.PaintTextOnGlass(pa.Graphics, button.Text, pa.Font, r, textFormat, textColor, true, renderGlow, 10); + // } + //#endif + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/OfficeTabFormStripPainter.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/OfficeTabFormStripPainter.cs new file mode 100644 index 00000000..b0dea7a8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/OfficeTabFormStripPainter.cs @@ -0,0 +1,204 @@ +using System; +using System.Collections.Generic; +using System.Text; +using DevComponents.DotNetBar.Controls; +using System.Drawing; +using System.Windows.Forms; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Rendering +{ + internal class OfficeTabFormStripPainter : TabFormStripPainter, IOffice2007Painter + { + #region IOffice2007Painter + private Office2007ColorTable _ColorTable = null; + + /// + /// Gets or sets color table used by renderer. + /// + public Office2007ColorTable ColorTable + { + get { return _ColorTable; } + set { _ColorTable = value; } + } + #endregion + + public override void Paint(TabFormStripPainterArgs renderingInfo) + { + TabFormStripControl strip = renderingInfo.TabFormStrip; + Graphics g = renderingInfo.Graphics; + Rectangle bounds = strip.ClientRectangle; + bool isFormActive = true; + Form form = strip.FindForm(); + if (form != null && (form != System.Windows.Forms.Form.ActiveForm && form.MdiParent == null || + form.MdiParent != null && form.MdiParent.ActiveMdiChild != form)) + isFormActive = false; + + //if (ct.BackgroundStyle != null) + //{ + // ElementStyleDisplayInfo di = new ElementStyleDisplayInfo(ct.BackgroundStyle, g, bounds); + // ElementStyleDisplay.PaintBackground(di); + //} + TabFormControl tabControl = strip.Parent as TabFormControl; + TabFormColorTable formColorTable = ColorTable.TabForm; + if (tabControl != null && tabControl.ColorTable != null) + formColorTable = tabControl.ColorTable; + + TabFormStateColorTable stateColorTable = isFormActive ? formColorTable.Active : formColorTable.Inactive; + if (stateColorTable.CaptionBackColors.Length > 0) + { + Rectangle cb = strip.ClientRectangle; + cb.Inflate(1, 1); + using ( + Brush brush = DisplayHelp.CreateBrush(cb, stateColorTable.CaptionBackColors, + stateColorTable.CaptionBackColorsGradientAngle, stateColorTable.CaptionBackColorsPositions)) + g.FillRectangle(brush, cb); + } + + if (strip.CaptionVisible) + { + if (strip.CaptionBounds.IsEmpty || strip.SystemCaptionItemBounds.IsEmpty) + SetCaptionItemBounds(strip, renderingInfo); + Color captionTextColor = stateColorTable.CaptionText; + eTextFormat textFormat = formColorTable.CaptionTextFormat; + + Font font = SystemFonts.DefaultFont; + bool disposeFont = true; + if (strip.CaptionFont != null) + { + font.Dispose(); + font = strip.CaptionFont; + disposeFont = false; + } + string text = strip.TitleText; + if (string.IsNullOrEmpty(text) && form != null) text = form.Text; + bool isTitleTextMarkup = strip.TitleTextMarkupBody != null; + Rectangle captionRect = strip.CaptionBounds; + const int CAPTION_TEXT_PADDING = 12; + captionRect.X += CAPTION_TEXT_PADDING; + captionRect.Width -= CAPTION_TEXT_PADDING; + + if (StyleManager.Style == eStyle.OfficeMobile2014) + { + captionRect.Y -= 2; + captionRect.Height -= 2; + // Center text in center of window instead of center of available space + if (!strip.SystemCaptionItemBounds.IsEmpty && captionRect.Width > strip.SystemCaptionItemBounds.Width) + { + captionRect.X += strip.SystemCaptionItemBounds.Width / 2 + 18; + captionRect.Width -= strip.SystemCaptionItemBounds.Width / 2 + 18; + } + } + + if (!isTitleTextMarkup) + TextDrawing.DrawString(g, text, font, captionTextColor, captionRect, textFormat); + else + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, captionTextColor, strip.RightToLeft == System.Windows.Forms.RightToLeft.Yes, captionRect, false); + d.AllowMultiLine = false; + d.IgnoreFormattingColors = !isFormActive; + TextMarkup.BodyElement body = strip.TitleTextMarkupBody; + if (strip.TitleTextMarkupLastArrangeBounds != captionRect) + { + body.Measure(captionRect.Size, d); + body.Arrange(captionRect, d); + strip.TitleTextMarkupLastArrangeBounds = captionRect; + Rectangle mr = body.Bounds; + if (mr.Width < captionRect.Width) + mr.Offset((captionRect.Width - mr.Width) / 2, 0); + if (mr.Height < captionRect.Height) + mr.Offset(0, (captionRect.Height - mr.Height) / 2); + body.Bounds = mr; + } + Region oldClip = g.Clip; + g.SetClip(captionRect, CombineMode.Intersect); + body.Render(d); + g.Clip = oldClip; + if (oldClip != null) oldClip.Dispose(); + } + + if (disposeFont) font.Dispose(); + } + + } + + private void SetCaptionItemBounds(TabFormStripControl strip, TabFormStripPainterArgs renderingInfo) + { + if (!strip.CaptionVisible) + return; + bool rightToLeft = (strip.RightToLeft == System.Windows.Forms.RightToLeft.Yes); + + System.Windows.Forms.Form form = strip.FindForm(); + + // Get right most X position of the Quick Access Toolbar + int right = 0, sysLeft = 0; + for (int i = strip.CaptionContainerItem.SubItems.Count - 1; i >= 0; i--) + { + BaseItem item = strip.CaptionContainerItem.SubItems[i]; + if (!item.Visible || !item.Displayed) + continue; + if (item.ItemAlignment == eItemAlignment.Near && item.Visible && i > 0) + { + if (rightToLeft) + right = item.DisplayRectangle.X; + else + right = item.DisplayRectangle.Right; + break; + } + else if (item.ItemAlignment == eItemAlignment.Far && item.Visible) + { + if (rightToLeft) + sysLeft = item.DisplayRectangle.Right; + else + sysLeft = item.DisplayRectangle.X; + } + } + + if (strip.CaptionContainerItem is CaptionItemContainer && ((CaptionItemContainer)strip.CaptionContainerItem).MoreItems != null) + { + if (rightToLeft) + right = ((CaptionItemContainer)strip.CaptionContainerItem).MoreItems.DisplayRectangle.X; + else + right = ((CaptionItemContainer)strip.CaptionContainerItem).MoreItems.DisplayRectangle.Right; + } + + Rectangle r = new Rectangle(right, 2, strip.CaptionContainerItem.WidthInternal - right - (strip.CaptionContainerItem.WidthInternal - sysLeft), strip.GetTotalCaptionHeight()); + strip.CaptionBounds = r; + + if (sysLeft > 0) + { + if (rightToLeft) + strip.SystemCaptionItemBounds = new Rectangle(r.X, r.Y, sysLeft, r.Height); + else + strip.SystemCaptionItemBounds = new Rectangle(sysLeft, r.Y, strip.CaptionContainerItem.WidthInternal - sysLeft, r.Height); + } + + //if (right == 0 || r.Height <= 0 || r.Width <= 0) + // return; + + //BaseItem startButton = strip.GetApplicationButton(); + //if (startButton != null) + //{ + // int startIndex = strip.QuickToolbarItems.IndexOf(startButton); + // if (strip.QuickToolbarItems.Count - 1 > startIndex) + // { + // BaseItem firstItem = strip.QuickToolbarItems[startIndex + 1]; + // if (rightToLeft) + // { + // r.Width -= r.Right - firstItem.DisplayRectangle.Right; + // } + // else + // { + // r.Width -= firstItem.DisplayRectangle.X - r.X; + // r.X = firstItem.DisplayRectangle.X; + // } + // } + //} + + //r.Height = ((CaptionItemContainer)strip.CaptionContainerItem).MaxItemHeight + 6; + //r.X = 0; + //r.Width = right; + //strip.QuickToolbarBounds = r; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormColorTable.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormColorTable.cs new file mode 100644 index 00000000..db4361ac --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormColorTable.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using DevComponents.DotNetBar.Metro; + +namespace DevComponents.DotNetBar.Rendering +{ + public class TabFormColorTable + { + /// + /// Gets or sets the color table for form in active state. + /// + public TabFormStateColorTable Active = new TabFormStateColorTable(); + + /// + /// Gets or sets the color table for from in inactive state. + /// + public TabFormStateColorTable Inactive = new TabFormStateColorTable(); + + /// + /// Gets or sets the border thickness. + /// + public Thickness BorderThickness = new Thickness(1, 1, 1, 1); + + /// + /// Gets or sets the background color of the form. + /// + public Color BackColor = Color.Empty; + + /// + /// Gets or sets the text color of the form. + /// + public Color TextColor = Color.Empty; + + /// + /// Gets or sets the text formatting for caption text. + /// + public eTextFormat CaptionTextFormat = eTextFormat.VerticalCenter | eTextFormat.Left | eTextFormat.EndEllipsis | eTextFormat.NoPrefix; + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormControl.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormControl.cs new file mode 100644 index 00000000..19cc401c --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormControl.cs @@ -0,0 +1,905 @@ +using DevComponents.DotNetBar.Rendering; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.Metro; +using DevComponents.DotNetBar.Primitives; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents Tabbed Forms control for creating tabbed user interface as replacement for MDI child forms. + /// + [ToolboxBitmap(typeof(TabFormControl), "TabFormControl.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.TabFormControlDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.Runtime.InteropServices.ComVisible(false)] + public class TabFormControl : System.Windows.Forms.ContainerControl + { + #region Events + + /// + /// Occurs + /// + [Description("Occurs ")] + public event PaintTabFormItemEventHandler PaintTabFormItem; + + /// + /// Raises RemovingToken event. + /// + /// Provides event arguments. + protected virtual void OnPaintTabFormItem(PaintTabFormItemEventArgs e) + { + PaintTabFormItemEventHandler handler = PaintTabFormItem; + if (handler != null) + handler(this, e); + } + /// + /// Occurs when DotNetBar is looking for translated text for one of the internal text that are + /// displayed on menus, toolbars and customize forms. You need to set Handled=true if you want + /// your custom text to be used instead of the built-in system value. + /// + public event DotNetBarManager.LocalizeStringEventHandler LocalizeString; + + /// + /// Occurs when Item on control is clicked. + /// + [Description("Occurs when Item on control is clicked.")] + public event EventHandler ItemClick; + + /// + /// Occurs after selected tab has changed. You can use + /// TabFormControl.SelectedTab + /// property to get reference to newly selected tab. + /// + public event EventHandler SelectedTabChanged; + + /// + /// Occurs when text markup link from TitleText markup is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + [Description("Occurs when text markup link from TitleText markup is clicked.")] + public event MarkupLinkClickEventHandler TitleTextMarkupLinkClick; + + /// + /// Occurs before TabFormItem is detached and gives you opportunity to cancel the action or provide your own new TabParentForm and TabFormControl. + /// + [Description("Occurs before TabFormItem is detached and gives you opportunity to cancel the action or provide your own new TabParentForm and TabFormControl.")] + public event TabFormItemDetachEventHandler BeforeTabFormItemDetach; + + /// + /// Raises BeforeTabFormItemDetach event. + /// + /// Provides event arguments. + protected virtual void OnBeforeTabFormItemDetach(TabFormItemDetachEventArgs e) + { + TabFormItemDetachEventHandler handler = BeforeTabFormItemDetach; + if (handler != null) + handler(this, e); + } + + /// + /// Occurs after TabFormItem has been detached and is added to the new form and tab control. + /// + [Description("Occurs after TabFormItem has been detached and is added to the new form and tab control.")] + public event TabFormItemDetachEventHandler TabFormItemDetach; + /// + /// Raises TabFormItemDetach event. + /// + /// Provides event arguments. + protected virtual void OnTabFormItemDetach(TabFormItemDetachEventArgs e) + { + TabFormItemDetachEventHandler handler = TabFormItemDetach; + if (handler != null) + handler(this, e); + } + #endregion + + #region Private Variables and Constructor + private TabFormStripControl _TabStrip = null; + private bool m_AutoSize = false; + private ShadowPaintInfo m_ShadowPaintInfo = null; + private bool _UseCustomizeDialog = true; + //private bool m_EnableQatPlacement = true; + + private int DefaultBottomDockPadding = 0; + private DevComponents.DotNetBar.Ribbon.SubItemsQatCollection m_QatSubItemsCollection = null; + private RibbonLocalization m_SystemText = new RibbonLocalization(); + private bool m_MenuTabsEnabled = true; + private ContextMenuBar m_GlobalContextMenuBar = null; + + public TabFormControl() + { + // This forces the initialization out of paint loop which speeds up how fast components show up + BaseRenderer renderer = DevComponents.DotNetBar.Rendering.GlobalManager.Renderer; + + this.SetStyle(ControlStyles.AllPaintingInWmPaint + | ControlStyles.ResizeRedraw + | DisplayHelp.DoubleBufferFlag + | ControlStyles.UserPaint + | ControlStyles.Opaque + , true); + _TabStrip = new TabFormStripControl(); + _TabStrip.Dock = DockStyle.Top; + _TabStrip.Height = 40; + _TabStrip.ItemAdded += new System.EventHandler(TabStripItemAdded); + _TabStrip.LocalizeString += new DotNetBarManager.LocalizeStringEventHandler(TabStripLocalizeString); + _TabStrip.ItemClick += new System.EventHandler(TabStripItemClick); + _TabStrip.ButtonCheckedChanged += new EventHandler(TabStripButtonCheckedChanged); + _TabStrip.TitleTextMarkupLinkClick += new MarkupLinkClickEventHandler(TabStripTitleTextMarkupLinkClick); + _TabStrip.BeforeTabFormItemDetach += TabStripBeforeTabFormItemDetach; + _TabStrip.TabFormItemDetach += TabStripTabFormItemDetach; + this.Controls.Add(_TabStrip); + this.TabStop = false; + this.DockPadding.Bottom = DefaultBottomDockPadding; + StyleManager.Register(this); + } + + protected override void Dispose(bool disposing) + { + StyleManager.Unregister(this); + base.Dispose(disposing); + } + #endregion + + #region Internal Implementation + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + this.DockPadding.Left = 0; + } + + internal bool IsDesignMode + { + get { return this.DesignMode; } + } + + internal bool InternalPaintTabFormItem(TabFormItem tab, ItemPaintArgs itemPaintArgs) + { + PaintTabFormItemEventArgs p = new PaintTabFormItemEventArgs(tab, itemPaintArgs.Graphics); + OnPaintTabFormItem(p); + return p.PaintDefault; + } + protected virtual void OnSelectedTabChanged(EventArgs e) + { + if (SelectedTabChanged != null) + SelectedTabChanged(this, e); + } + + void TabStripButtonCheckedChanged(object sender, EventArgs e) + { + if (sender is TabFormItem && ((TabFormItem)sender).Checked) + { + OnSelectedTabChanged(new EventArgs()); + } + } + + private void TabStripItemClick(object sender, System.EventArgs e) + { + if (ItemClick != null) + ItemClick(sender, e); + } + + private void TabStripLocalizeString(object sender, LocalizeEventArgs e) + { + if (LocalizeString != null) + LocalizeString(this, e); + } + + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is false. + /// + [DefaultValue(true), Browsable(true), Category("Appearance"), Description("Gets or sets whether anti-aliasing is used while painting.")] + public bool AntiAlias + { + get { return _TabStrip.AntiAlias; } + set + { + _TabStrip.AntiAlias = value; + this.Invalidate(); + } + } + + internal DevComponents.DotNetBar.Rendering.Office2007ColorTable GetOffice2007ColorTable() + { + DevComponents.DotNetBar.Rendering.Office2007Renderer r = DevComponents.DotNetBar.Rendering.GlobalManager.Renderer as DevComponents.DotNetBar.Rendering.Office2007Renderer; + if (r != null) + return r.ColorTable; + return new DevComponents.DotNetBar.Rendering.Office2007ColorTable(); + } + + /// + /// Performs the setup of the TabFormPanel with the current style of the TabFormControl Control. + /// + /// Panel to apply style changes to. + public void SetTabPanelStyle(TabFormPanel panel) + { + if (this.DesignMode) + { + TypeDescriptor.GetProperties(panel.DockPadding)["Left"].SetValue(panel.DockPadding, 3); + TypeDescriptor.GetProperties(panel.DockPadding)["Right"].SetValue(panel.DockPadding, 3); + TypeDescriptor.GetProperties(panel.DockPadding)["Bottom"].SetValue(panel.DockPadding, 3); + } + else + { + panel.DockPadding.Left = 3; + panel.DockPadding.Right = 3; + panel.DockPadding.Bottom = 3; + } + panel.Style.Class = ElementStyleClassKeys.TabFormPanelKey; + } + + /// + /// Creates new Tab at specified position, creates new associated panel and adds them to the control. + /// + /// Specifies the text displayed on the tab. + /// Specifies the name of the tab + /// Specifies the position of the new tab inside of Items collection. + /// New instance of the TabFormItem that was created. + public TabFormItem CreateTab(string text, string name, int insertPosition) + { + TabFormItem item = new TabFormItem(); + item.Text = text; + item.Name = name; + + TabFormPanel panel = new TabFormPanel(); + panel.Dock = DockStyle.Fill; + SetTabPanelStyle(panel); + this.Controls.Add(panel); + panel.SendToBack(); + + item.Panel = panel; + if (insertPosition < 0) + { + insertPosition = this.Items.Count; + for (int i = 0; i < this.Items.Count; i++) + { + if (this.Items[i].ItemAlignment == eItemAlignment.Far) + { + insertPosition = i; + break; + } + } + if (insertPosition >= this.Items.Count) + this.Items.Add(item); + else + this.Items.Insert(insertPosition, item); + } + else if (insertPosition > this.Items.Count - 1) + this.Items.Add(item); + else + this.Items.Insert(insertPosition, item); + + return item; + } + + /// + /// Creates new Tab and associated panel and adds them to the control. + /// + /// Specifies the text displayed on the tab. + /// Specifies the name of the tab + /// New instance of the TabFormItem that was created. + public TabFormItem CreateTab(string text, string name) + { + return CreateTab(text, name, -1); + } + + /// + /// Recalculates layout of the control and applies any changes made to the size or position of the items contained. + /// + public void RecalcLayout() + { + _TabStrip.RecalcLayout(); + } + + protected override void OnHandleCreated(System.EventArgs e) + { + base.OnHandleCreated(e); + foreach (Control c in this.Controls) + { + IntPtr h = c.Handle; + if (c is TabFormPanel) + { + foreach (Control r in c.Controls) + h = r.Handle; + } + } + this.RecalcLayout(); + } + + protected override void OnControlAdded(ControlEventArgs e) + { + base.OnControlAdded(e); + + if (this.DesignMode) + return; + TabFormPanel panel = e.Control as TabFormPanel; + if (panel == null) + return; + if (panel.TabFormItem != null) + { + if (this.Items.Contains(panel.TabFormItem) && this.SelectedTab == panel.TabFormItem) + { + panel.Visible = true; + panel.BringToFront(); + } + else + panel.Visible = false; + } + else + panel.Visible = false; + } + + private void TabStripItemAdded(object sender, System.EventArgs e) + { + if (this.DesignMode) + return; + + if (sender is TabFormItem) + { + TabFormItem tab = sender as TabFormItem; + if (tab.Panel != null) + { + if (this.Controls.Contains(tab.Panel) && tab.Checked) + { + tab.Panel.Visible = true; + tab.Panel.BringToFront(); + } + else + tab.Panel.Visible = false; + } + } + } + + protected override void OnControlRemoved(ControlEventArgs e) + { + base.OnControlRemoved(e); + TabFormPanel panel = e.Control as TabFormPanel; + if (panel == null) + return; + if (panel.TabFormItem != null) + { + if (this.Items.Contains(panel.TabFormItem)) + this.Items.Remove(panel.TabFormItem); + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetDesignMode() + { + _TabStrip.SetDesignMode(true); + } + + private ElementStyle GetBackgroundStyle() + { + return _TabStrip.InternalGetBackgroundStyle(); + } + + protected override void OnPaint(PaintEventArgs e) + { + ElementStyle style = GetBackgroundStyle(); + if (style.BackColor.A < 255 && !style.BackColor.IsEmpty || + this.BackColor == Color.Transparent || this.BackgroundImage != null) + { + base.OnPaintBackground(e); + } + else + { + using (SolidBrush brush = new SolidBrush(this.BackColor)) + e.Graphics.FillRectangle(brush, this.ClientRectangle); + } + + ElementStyleDisplayInfo info = new ElementStyleDisplayInfo(style, e.Graphics, this.ClientRectangle); + ElementStyleDisplay.PaintBackground(info); + } + + protected override void WndProc(ref Message m) + { + if (m.Msg == (int)WinApi.WindowsMessages.WM_NCHITTEST && !this.DesignMode) + { + // Get position being tested... + int x = WinApi.LOWORD(m.LParam); + int y = WinApi.HIWORD(m.LParam); + Point p = PointToClient(new Point(x, y)); + + if (this.CaptionVisible && _TabStrip != null && !_TabStrip.IsMaximized) + { + TabParentForm form = this.FindForm() as TabParentForm; + if (form == null || form.Sizable) + { + int formBorderSize = 4; + Rectangle r = new Rectangle(0, 0, this.Width, formBorderSize); + if (r.Contains(p)) // Top side form resizing + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + r = new Rectangle(0, 0, formBorderSize, this.Height); // Left side form resizing + if (r.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + r = new Rectangle(this.Width - formBorderSize, 0, formBorderSize, this.Height); // Right side form resizing + if (r.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + } + } + else if (_TabStrip != null) + { + Point pts = _TabStrip.PointToClient(new Point(x, y)); + if (_TabStrip.HitTest(pts.X, pts.Y) == null) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + } + //if (BarFunctions.IsWindows7 && _TabStrip != null && _TabStrip.IsMaximized) + //{ + // Rectangle r = _TabStrip.CaptionBounds; + // if (r.Contains(p)) + // { + // m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + // return; + // } + //} + //// System Icon + //if ((p.X < 28 && this.RightToLeft == RightToLeft.No || p.X > this.Width - 28 && this.RightToLeft == RightToLeft.Yes) && p.Y < 28) + //{ + // m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + // return; + //} + } + base.WndProc(ref m); + } + + /// + /// Returns current number of tabs visible and hidden on the tab strip. + /// + [Browsable(false)] + public int TabsCount + { + get { return _TabStrip.TabsCount; } + } + + private void TabStripTabFormItemDetach(object sender, TabFormItemDetachEventArgs e) + { + OnTabFormItemDetach(e); + } + + private void TabStripBeforeTabFormItemDetach(object sender, TabFormItemDetachEventArgs e) + { + OnBeforeTabFormItemDetach(e); + } + #endregion + + #region Properties + /// + /// Indicates whether Form.Icon is shown in top-left corner. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether Form.Icon is shown in top-left corner.")] + public bool ShowIcon + { + get + { + return _TabStrip.ShowIcon; + } + set + { + _TabStrip.ShowIcon = value; + } + } + + /// + /// Gets or sets the rich text displayed on title bar instead of the Form.Text property. This property supports text-markup. + /// You can use markup to instruct the markup renderer to use Office 2007 system caption extra text color which + /// changes depending on the currently selected color table. Note that when using this property you should manage also the Form.Text property since + /// that is the text that will be displayed in Windows task-bar and elsewhere where system Form.Text property is used. + /// You can also use the hyperlinks as part of the text markup and handle the TitleTextMarkupLinkClick event to be notified when they are clicked. + /// + [Browsable(true), DefaultValue(""), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), EditorBrowsable(EditorBrowsableState.Always), Category("Appearance"), Description("Indicates text displayed on Title bar instead of the Form.Text property.")] + public string TitleText + { + get { return _TabStrip.TitleText; } + set { _TabStrip.TitleText = value; } + } + + /// + /// Occurs when text markup link is clicked. + /// + private void TabStripTitleTextMarkupLinkClick(object sender, MarkupLinkClickEventArgs e) + { + if (TitleTextMarkupLinkClick != null) + TitleTextMarkupLinkClick(this, new MarkupLinkClickEventArgs(e.Name, e.HRef)); + } + + /// + /// Gets or sets the Context menu bar associated with the this control which is used as part of Global Items feature. The context menu + /// bar assigned here will be used to search for the items with the same Name or GlobalName property so global properties can be propagated when changed. + /// You should assign this property to enable the Global Items feature to reach your ContextMenuBar. + /// + [DefaultValue(null), Description("Indicates Context menu bar associated with the TabFormControl control which is used as part of Global Items feature."), Category("Data")] + public ContextMenuBar GlobalContextMenuBar + { + get { return m_GlobalContextMenuBar; } + set + { + if (m_GlobalContextMenuBar != null) + m_GlobalContextMenuBar.GlobalParentComponent = null; + m_GlobalContextMenuBar = value; + if (m_GlobalContextMenuBar != null) + m_GlobalContextMenuBar.GlobalParentComponent = this; + } + } + + /// + /// Gets or sets whether custom caption and quick access toolbar provided by the control is visible. Default value is false. + /// This property should be set to true when control is used on MetroAppForm. + /// + [Browsable(true), DefaultValue(false), Category("Caption"), Description("Indicates whether custom caption and quick access toolbar provided by the control is visible.")] + public bool CaptionVisible + { + get { return _TabStrip.CaptionVisible; } + set + { + _TabStrip.CaptionVisible = value; + } + } + + /// + /// Gets or sets the font for the form caption text when CaptionVisible=true. Default value is NULL which means that system font is used. + /// + [Browsable(true), DefaultValue(null), Category("Caption"), Description("Indicates font for the form caption text when CaptionVisible=true.")] + public Font CaptionFont + { + get { return _TabStrip.CaptionFont; } + set + { + _TabStrip.CaptionFont = value; + } + } + + /// + /// Gets or sets the explicit height of the caption provided by control. Caption height when set is composed of the TabGroupHeight and + /// the value specified here. Default value is 0 which means that system default caption size is used. + /// + [Browsable(true), DefaultValue(0), Category("Caption"), Description("Indicates explicit height of the caption provided by control")] + public int CaptionHeight + { + get { return _TabStrip.CaptionHeight; } + set + { + _TabStrip.CaptionHeight = value; + this.RecalcLayout(); + } + } + + /// + /// Specifies the background style of the control. + /// + [Browsable(true), DevCoBrowsable(true), Category("Style"), Description("Gets or sets bar background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return _TabStrip.BackgroundStyle; } + } + + /// + /// Gets or sets the currently selected TabFormItem. TabFormItems are selected using the Checked property. Only a single + /// TabFormItem can be selected (Checked) at any given time. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TabFormItem SelectedTab + { + get { return _TabStrip.SelectedTab; } + set + { + if (value != null) + { + if(!value.Checked) + value.Checked = true; + else if (value.Panel != null && !value.Panel.Visible) + value.Panel.Visible = true; + } + } + } + + /// + /// Indicates whether new tab item which allows creation of new tab when clicked is visible. When visible you need to handle CreateNewTab event and create your new tab in event handler. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether new tab item which allows creation of new tab when clicked is visible. When visible you need to handle CreateNewTab event and create your new tab in event handler.")] + public bool NewTabItemVisible + { + get { return _TabStrip.NewTabItemVisible; } + set { _TabStrip.NewTabItemVisible = value; } + } + + /// + /// Occurs when new tab item is clicked by end user and allows you to create and add new tab to the control. + /// + [Description("Occurs when new tab item is clicked by end user and allows you to create and add new tab to the control.")] + public event EventHandler CreateNewTab; + + /// + /// Raises CreateNewTab event. + /// + /// Provides event arguments. + protected internal virtual void OnCreateNewTab(EventArgs e) + { + EventHandler handler = CreateNewTab; + if (handler != null) + handler(this, e); + } + + internal void RaiseCreateNewTab(EventArgs e) + { + OnCreateNewTab(e); + } + + /// + /// Returns reference to internal tab-strip control. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TabFormStripControl TabStrip + { + get { return _TabStrip; } + } + + /// + /// Returns collection of items on a bar. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] + public SubItemsCollection Items + { + get { return _TabStrip.Items; } + } + + ///// + ///// Returns collection of quick toolbar access and caption items. + ///// + //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] + //public SubItemsCollection QuickToolbarItems + //{ + // get { return GetQatSubItemsCollection(); } + //} + + //private SubItemsCollection GetQatSubItemsCollection() + //{ + // return _TabStrip.QuickToolbarItems; + //} + /// + /// Gets collection of items displayed in control captions, if it is visible (CaptionVisible=true). + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] + public SubItemsCollection CaptionItems + { + get { return _TabStrip.TabStripContainer.CaptionItems; } + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public eDotNetBarStyle EffectiveStyle + { + get + { + return _TabStrip.EffectiveStyle; + } + } + + private TabFormColorTable _ColorTable; + /// + /// Gets or sets the custom color table for the control. When set this color table overrides all system color settings for control. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TabFormColorTable ColorTable + { + get { return _ColorTable; } + set { _ColorTable = value; } + } + //private static BaseItem GetAppButton(TabFormControl tab) + //{ + // BaseItem appButton = null; + // for (int i = 0; i < tab.QuickToolbarItems.Count; i++) + // { + // if (tab.QuickToolbarItems[i] is MetroAppButton) + // { + // appButton = tab.QuickToolbarItems[i]; + // break; + // } + + // } + // return appButton; + //} + //protected override void OnBackColorChanged(EventArgs e) + //{ + // base.OnBackColorChanged(e); + //} + +#if TRIAL + private bool _ShownOnce = false; +#endif + protected override void OnVisibleChanged(EventArgs e) + { +#if TRIAL + if(!this.DesignMode && !_ShownOnce) + { + RemindForm frm=new RemindForm(); + frm.ShowDialog(); + frm.Dispose(); + _ShownOnce = true; + } +#endif + + base.OnVisibleChanged(e); + } + + private bool _MouseWheelTabScrollEnabled = true; + /// + /// Gets or sets whether mouse wheel scrolls through the tabs. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether mouse wheel scrolls through the tabs.")] + public bool MouseWheelTabScrollEnabled + { + get { return _MouseWheelTabScrollEnabled; } + set + { + _MouseWheelTabScrollEnabled = value; + } + } + + /// + /// ImageList for images used on Items. Images specified here will always be used on menu-items and are by default used on all Bars. + /// + [Browsable(true), Category("Data"), DefaultValue(null), Description("ImageList for images used on Items. Images specified here will always be used on menu-items and are by default used on all Bars.")] + public ImageList Images + { + get { return _TabStrip.Images; } + set { _TabStrip.Images = value; } + } + + /// + /// ImageList for medium-sized images used on Items. + /// + [Browsable(true), Category("Data"), DefaultValue(null), Description("ImageList for medium-sized images used on Items.")] + public ImageList ImagesMedium + { + get { return _TabStrip.ImagesMedium; } + set { _TabStrip.ImagesMedium = value; } + } + + /// + /// ImageList for large-sized images used on Items. + /// + [Browsable(true), Category("Data"), DefaultValue(null), Description("ImageList for large-sized images used on Items.")] + public ImageList ImagesLarge + { + get { return _TabStrip.ImagesLarge; } + set { _TabStrip.ImagesLarge = value; } + } + + protected override void OnTabStopChanged(System.EventArgs e) + { + base.OnTabStopChanged(e); + _TabStrip.TabStop = this.TabStop; + } + + /// + /// Gets or sets a value indicating whether the user can give the focus to this control using the TAB key. Default value is false. + /// + [Browsable(true), DefaultValue(false), Category("Behavior"), Description("Indicates whether the user can give the focus to this control using the TAB key.")] + public new bool TabStop + { + get { return base.TabStop; } + set { base.TabStop = value; } + } + #endregion + + #region Metro Customization + + ///// + ///// Gets the reference to the localization object which holds all system text used by the component. + ///// + //[Browsable(true), DevCoBrowsable(true), NotifyParentPropertyAttribute(true), Category("Localization"), Description("Gets system text used by the component.."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + //public RibbonLocalization SystemText + //{ + // get { return m_SystemText; } + //} + + protected override Size DefaultSize + { + get + { + return new Size(200, 100); + } + } + + private eTabFormStripControlDock _TabStripDock = eTabFormStripControlDock.Top; + /// + /// Gets or sets the side tab-strip is docked to. + /// + [DefaultValue(eTabFormStripControlDock.Top), Category("Appearance"), Description("Indicates side tab-strip is docked to.")] + public eTabFormStripControlDock TabStripDock + { + get { return _TabStripDock; } + set + { + _TabStripDock = value; + if (_TabStripDock == eTabFormStripControlDock.Top) + _TabStrip.Dock = DockStyle.Top; + else if (_TabStripDock == eTabFormStripControlDock.Bottom) + _TabStrip.Dock = DockStyle.Bottom; + } + } + + /// + /// Gets or sets the font tab items are displayed with. + /// + [AmbientValue((string) null), Localizable(true) , Category("Appearance"), Description("Indicates the font tab items are displayed with.")] + public Font TabStripFont + { + get { return _TabStrip.Font; } + set + { + _TabStrip.Font = value; + } + } + + /// + /// Gets or sets whether this TabFormControl was auto-created as result of end-user tearing off the tab. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsAutoCreated { get; set; } + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + if (Dpi.RecordScalePerControl) + Dpi.SetScaling(factor); + base.ScaleControl(factor, specified); + } + #endregion + + } + /// + /// Specifies dock side for tab form strip control. + /// + public enum eTabFormStripControlDock + { + Top, + Bottom + } + + /// + /// Defines delegate for the PaintTabFormItem event. + /// + public delegate void PaintTabFormItemEventHandler(object sender, PaintTabFormItemEventArgs e); + + /// + /// Defines delegate for the PaintTabFormItem event. + /// + public class PaintTabFormItemEventArgs : EventArgs + { + /// + /// Gets reference to the tab being painted. + /// + public readonly TabFormItem Tab; + /// + /// Gets reference to the graphic canvas for painting. + /// + public readonly Graphics Graphics; + /// + /// Gets or sets whether default painting for the item is performed, default value is true. Set to false to disable internal painting. + /// + public bool PaintDefault = true; + public PaintTabFormItemEventArgs(TabFormItem tab, Graphics g) + { + this.Tab = tab; + this.Graphics = g; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormItem.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormItem.cs new file mode 100644 index 00000000..4a9bf42d --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormItem.cs @@ -0,0 +1,1076 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents a tab in Tabbed Form user interface. + /// + public class TabFormItem : TabFormItemBase + { + #region Private Variables & Constructor + private TabFormPanel _Panel = null; + private string _CashedColorTableName = "Default"; + private bool _ReducedSize = false; + private int _PaddingHorizontal = 0; + /// + /// Initializes a new instance of the TabFormItem class. + /// + public TabFormItem() + { + this.ButtonStyle = eButtonStyle.ImageAndText; + //this.MouseDownCapture = true; + //this.MouseUpNotification = true; + } + #endregion + + #region Internal Implementation + public override void Paint(ItemPaintArgs p) + { + if (!PaintCustom(p)) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + p.ButtonItemRendererEventArgs.Graphics = p.Graphics; + p.ButtonItemRendererEventArgs.ButtonItem = this; + p.ButtonItemRendererEventArgs.ItemPaintArgs = p; + renderer.DrawTabFormItem(p.ButtonItemRendererEventArgs); + } + } + + if (!string.IsNullOrEmpty(NotificationMarkText)) + DevComponents.DotNetBar.Rendering.NotificationMarkPainter.Paint(p.Graphics, this.Bounds, NotificationMarkPosition, + NotificationMarkText, new Size(NotificationMarkSize, NotificationMarkSize), NotificationMarkOffset, NotificationMarkColor); + this.DrawInsertMarker(p.Graphics); + } + + /// + /// Returns true if custom painting is performed and internal painting should be bypassed. + /// + /// + /// + private bool PaintCustom(ItemPaintArgs itemPaintArgs) + { + TabFormControl tc = GetTabFormControl(); + if (tc == null) return false; + + return !tc.InternalPaintTabFormItem(this,itemPaintArgs); + } + + public override void RecalcSize() + { + _ImageRenderBounds = Rectangle.Empty; + _TextRenderBounds = Rectangle.Empty; + base.RecalcSize(); + + } + + private bool _ItemDrag = false; + private InsertPosition _DragInsertPosition = null; + public override void InternalMouseMove(MouseEventArgs objArg) + { + //if (_ItemDrag) + //{ + // IDesignTimeProvider dtp = (IDesignTimeProvider)this.Parent; + // Point pScreen = this.PointToScreen(objArg.Location); + // InsertPosition pos = dtp.GetInsertPosition(pScreen, this); + // if (_DragInsertPosition != null) + // { + // dtp.DrawReversibleMarker(_DragInsertPosition.Position, _DragInsertPosition.Before); + // _DragInsertPosition = null; + // } + // if (pos != null) + // { + // if (pos.TargetProvider == null) + // { + // // Cursor is over drag item + // System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.No; + // } + // else + // { + // pos.TargetProvider.DrawReversibleMarker(pos.Position, pos.Before); + // System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Hand; + // _DragInsertPosition = pos; + // } + // } + // else + // { + // System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.No; + // } + //} + //else + if (objArg.Button == MouseButtons.Left && + (CloseButtonState == eButtonState.Normal || CloseButtonState == eButtonState.Disabled || CloseButtonState == eButtonState.Hidden) && + (Math.Abs(objArg.X - this.MouseDownPt.X) > Dpi.Width6 || Math.Abs(objArg.Y - this.MouseDownPt.Y) > Dpi.Width6) && IsItemDragEnabled) + { + TabFormStripControl parent = this.ContainerControl as TabFormStripControl; + if (parent != null) + { + parent.StartItemDrag(this); + } + //IDesignTimeProvider dtp = this.Parent as IDesignTimeProvider; + //if (dtp != null) + //{ + // TabFormStripControl c = this.ContainerControl as TabFormStripControl; + // if (c != null) + // { + // _ItemDrag = true; + // c.DragInProgress = true; + // } + //} + } + else if (_CloseButtonVisible && !_CloseButtonBounds.IsEmpty) + { + if (_CloseButtonBounds.Contains(objArg.Location)) + CloseButtonState = eButtonState.MouseOver; + else + CloseButtonState = eButtonState.Normal; + } + base.InternalMouseMove(objArg); + } + + private bool IsItemDragEnabled + { + get + { + TabFormStripControl c = this.ContainerControl as TabFormStripControl; + if (c == null) return false; + return c.IsTabDragEnabled; + } + } + + public override void InternalMouseDown(MouseEventArgs objArg) + { + if (_CloseButtonState == eButtonState.MouseOver && objArg.Button == MouseButtons.Left) + { + CloseButtonState = eButtonState.MouseDownLeft; + } + base.InternalMouseDown(objArg); + } + + public override void InternalMouseUp(MouseEventArgs objArg) + { + //if (_ItemDrag) + //{ + // _ItemDrag = false; + // TabFormStripControl c = this.ContainerControl as TabFormStripControl; + // if (c != null) + // c.DragInProgress = false; + // if (_DragInsertPosition != null) + // { + // IDesignTimeProvider dtp = (IDesignTimeProvider) this.Parent; + // // Removes drag marker + // int insertPosition = _DragInsertPosition.Position; + // bool insertBefore = _DragInsertPosition.Before; + // dtp.DrawReversibleMarker(insertPosition, insertBefore); + // if (insertPosition > 0 && dtp == this.Parent) + // { + // if (this.Parent.SubItems.IndexOf(this) < insertPosition) + // insertPosition--; + // } + // BaseItem parent = this.Parent; + // parent.SubItems.Remove(this); + // this.Checked = false; + // dtp.InsertItemAt(this, insertPosition, insertBefore); + // this.Checked = true; + // _DragInsertPosition = null; + // } + //} + //else + if (_CloseButtonState == eButtonState.MouseDownLeft) + { + CloseButtonState = eButtonState.Normal; + CloseTab(eEventSource.Mouse); + } + base.InternalMouseUp(objArg); + } + + private void CloseTab(eEventSource source) + { + TabFormStripControl strip = this.ContainerControl as TabFormStripControl; + if (strip != null) + { + strip.CloseTab(this, source); + } + } + + public override void InternalMouseLeave() + { + if (_CloseButtonVisible) + CloseButtonState = eButtonState.Normal; + base.InternalMouseLeave(); + } + + private eButtonState _CloseButtonState = eButtonState.Hidden; + internal eButtonState CloseButtonState + { + get { return _CloseButtonState; } + set + { + if (value != _CloseButtonState) + { + _CloseButtonState = value; + if (!_CloseButtonBounds.IsEmpty) + this.Invalidate(); + } + } + } + + private Rectangle _CloseButtonBounds = Rectangle.Empty; + /// + /// Gets or sets the close button bounds. + /// + internal Rectangle CloseButtonBounds + { + get { return _CloseButtonBounds; } + set { _CloseButtonBounds = value; } + } + + private Rectangle _ImageRenderBounds = Rectangle.Empty; + /// + /// Gets or sets cached image rendering bounds. + /// + internal Rectangle ImageRenderBounds + { + get { return _ImageRenderBounds; } + set { _ImageRenderBounds = value; } + } + + private Rectangle _TextRenderBounds = Rectangle.Empty; + /// + /// Gets or sets cached text rendering bounds. + /// + internal Rectangle TextRenderBounds + { + get { return _TextRenderBounds; } + set { _TextRenderBounds = value; } + } + + protected override bool IsFadeEnabled + { + get + { + return false; + } + } + /// + /// Gets or sets the additional padding added around the tab item in pixels. Default value is 0. + /// + [Browsable(true), DefaultValue(0), Category("Layout"), Description("Indicates additional padding added around the tab item in pixels.")] + public int PaddingHorizontal + { + get { return _PaddingHorizontal; } + set + { + _PaddingHorizontal = value; + UpdateTabAppearance(); + } + } + + private bool _CloseButtonVisible = true; + + /// + /// Indicates whether close button is visible on the tabs which when clicked closes the tab. Default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether close button is visible on the tabs which when clicked closes the tab.")] + public bool CloseButtonVisible + { + get { return _CloseButtonVisible; } + set + { + _CloseButtonVisible = value; + if (!value) + _CloseButtonState = eButtonState.Hidden; + NeedRecalcSize = true; + UpdateTabAppearance(); + } + } + + /// + /// Selects the tab. + /// + public void Select() + { + this.Checked = true; + } + /// + /// Gets or sets whether size of the tab has been reduced below the default calculated size. + /// + internal bool ReducedSize + { + get { return _ReducedSize; } + set { _ReducedSize = value; } + } + + private eTabFormItemColor _ColorTable = eTabFormItemColor.Default; + /// + /// Gets or sets the predefined color of the tab. Default value is eTabFormItemColor.Default + /// + [Browsable(true), DefaultValue(eTabFormItemColor.Default), Category("Appearance"), Description("Indicates predefined color of the tab.")] + public new eTabFormItemColor ColorTable + { + get { return _ColorTable; } + set + { + if (_ColorTable != value) + { + _ColorTable = value; + _CashedColorTableName = Enum.GetName(typeof(eTabFormItemColor), _ColorTable); + this.Refresh(); + } + } + } + + internal override string GetColorTableName() + { + return this.CustomColorName != "" ? this.CustomColorName : _CashedColorTableName; + } + + /// + /// Gets or sets the panel assigned to this tab item. + /// + [Browsable(false), DefaultValue(null)] + public TabFormPanel Panel + { + get { return _Panel; } + set + { + _Panel = value; + OnPanelChanged(); + } + } + + private void OnPanelChanged() + { + ChangePanelVisibility(); + } + + /// + /// Called after Checked property has changed. + /// + protected override void OnCheckedChanged() + { + if (this.Checked && this.Parent != null) + { + ChangePanelVisibility(); + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this) + continue; + TabFormItem b = item as TabFormItem; + if (b != null && b.Checked) + { + if (this.DesignMode) + TypeDescriptor.GetProperties(b)["Checked"].SetValue(b, false); + else + b.Checked = false; + } + } + } + + if (BarFunctions.IsOffice2007Style(this.EffectiveStyle) && this.ContainerControl is System.Windows.Forms.Control) + ((System.Windows.Forms.Control)this.ContainerControl).Invalidate(); + if (!this.Checked) + ChangePanelVisibility(); + InvokeCheckedChanged(); + } + + private void ChangePanelVisibility() + { + if (this.Checked && _Panel != null) + { + if (this.DesignMode) + { + if (!_Panel.Visible) _Panel.Visible = true; + TypeDescriptor.GetProperties(_Panel)["Visible"].SetValue(_Panel, true); + _Panel.BringToFront(); + } + else + { + if (!_Panel.IsDisposed) + { + // Following 3 lines reduce flashing of panel's child controls when Dock panel is shown + System.Windows.Forms.DockStyle oldDock = _Panel.Dock; + _Panel.Dock = System.Windows.Forms.DockStyle.None; + _Panel.Location = new Point(-32000, 32000); + _Panel.Enabled = true; + _Panel.Visible = true; + _Panel.BringToFront(); + if (_Panel.Dock != oldDock) + _Panel.Dock = oldDock; + } + + } + } + else if (!this.Checked && _Panel != null) // Panels in popup mode will be taken care of by Ribbon + { + if (this.DesignMode) + TypeDescriptor.GetProperties(_Panel)["Visible"].SetValue(_Panel, false); + else + { + _Panel.Visible = false; + _Panel.Enabled = false; + } + } + } + + /// + /// Occurs just before Click event is fired. + /// + protected override void OnClick() + { + base.OnClick(); + if (!this.Checked) + { + if (this.DesignMode) + TypeDescriptor.GetProperties(this)["Checked"].SetValue(this, true); + else + { + TabFormControl shell = GetTabFormControl(); + if (shell != null && !shell.ValidateChildren()) + return; + this.Checked = true; + } + } + } + private TabFormControl GetTabFormControl() + { + TabFormStripControl strip = this.ContainerControl as TabFormStripControl; + if (strip == null) return null; + return strip.Parent as TabFormControl; + } + /// + /// Called when Visibility of the items has changed. + /// + /// New Visible state. + protected internal override void OnVisibleChanged(bool bVisible) + { + base.OnVisibleChanged(bVisible); + if (!bVisible && this.Checked) + { + TypeDescriptor.GetProperties(this)["Checked"].SetValue(this, false); + // Try to check first item in the group + if (this.Parent != null) + { + foreach (BaseItem item in this.Parent.SubItems) + { + if (item == this || !item.GetEnabled() || !item.Visible) + continue; + TabFormItem b = item as TabFormItem; + if (b != null) + { + TypeDescriptor.GetProperties(b)["Checked"].SetValue(this, true); + break; + } + } + } + } + } + + /// + /// Gets or set the Group item belongs to. The groups allows a user to choose from mutually exclusive options within the group. The choice is reflected by Checked property. + /// + [Browsable(false), DevCoBrowsable(false), DefaultValue(""), EditorBrowsable(EditorBrowsableState.Never)] + public override string OptionGroup + { + get { return base.OptionGroup; } + set { base.OptionGroup = value; } + } + + /// + /// Occurs after item visual style has changed. + /// + protected override void OnStyleChanged() + { + base.OnStyleChanged(); + UpdateTabAppearance(); + } + + private void UpdateTabAppearance() + { + this.VerticalPadding = 2; + this.HorizontalPadding = 28 + _PaddingHorizontal + (_CloseButtonVisible ? CloseButtonSize : 0); + + this.NeedRecalcSize = true; + this.OnAppearanceChanged(); + } + + /// + /// Returns the collection of sub items. + /// + [Browsable(false), DevCoBrowsable(false), DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)] + public override SubItemsCollection SubItems + { + get { return base.SubItems; } + } + + internal override void DoAccesibleDefaultAction() + { + this.Checked = true; + } + + protected override void Invalidate(System.Windows.Forms.Control containerControl) + { + Rectangle r = m_Rect; + r.Width++; + r.Height++; + if (containerControl.InvokeRequired) + containerControl.BeginInvoke(new MethodInvoker(delegate { containerControl.Invalidate(r, true); })); + else + containerControl.Invalidate(r, true); + } + + public override bool UseParentSubItemsImageSize + { + get + { + return false; + } + } + + protected override bool ShouldDrawInsertMarker() + { + IOwner owner = GetOwner() as IOwner; + + return DesignInsertMarker != eDesignInsertPosition.None && this.Visible && this.Displayed && + !this.DesignMode; + } + #endregion + + #region Hidden Properties + /// + /// Indicates whether the item will auto-collapse (fold) when clicked. + /// When item is on popup menu and this property is set to false, menu will not + /// close when item is clicked. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Behavior"), DefaultValue(true), Description("Indicates whether the item will auto-collapse (fold) when clicked.")] + public override bool AutoCollapseOnClick + { + get + { + return base.AutoCollapseOnClick; + } + set + { + base.AutoCollapseOnClick = value; + } + } + + /// + /// Indicates whether the item will auto-expand when clicked. + /// When item is on top level bar and not on menu and contains sub-items, sub-items will be shown only if user + /// click the expand part of the button. Setting this propert to true will expand the button and show sub-items when user + /// clicks anywhere inside of the button. Default value is false which indicates that button is expanded only + /// if its expand part is clicked. + /// + [DefaultValue(false), Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DevCoBrowsable(false), Category("Behavior"), Description("Indicates whether the item will auto-collapse (fold) when clicked.")] + public override bool AutoExpandOnClick + { + get + { + return base.AutoExpandOnClick; + } + set + { + base.AutoExpandOnClick = value; + } + } + + /// + /// Gets or sets whether item can be customized by end user. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(true), System.ComponentModel.Category("Behavior"), System.ComponentModel.Description("Indicates whether item can be customized by user.")] + public override bool CanCustomize + { + get + { + return base.CanCustomize; + } + set + { + base.CanCustomize = value; + } + } + + /// + /// Gets or set a value indicating whether tab is selected. + /// + [Browsable(false), DevCoBrowsable(false), Category("Appearance"), Description("Indicates whether item is checked or not."), DefaultValue(false)] + public override bool Checked + { + get + { + return base.Checked; + } + set + { + base.Checked = value; + } + } + + /// + /// Gets or sets whether Click event will be auto repeated when mouse button is kept pressed over the item. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(false), Category("Behavior"), Description("Gets or sets whether Click event will be auto repeated when mouse button is kept pressed over the item.")] + public override bool ClickAutoRepeat + { + get + { + return base.ClickAutoRepeat; + } + set + { + base.ClickAutoRepeat = value; + } + } + + /// + /// Gets or sets the auto-repeat interval for the click event when mouse button is kept pressed over the item. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(600), Category("Behavior"), Description("Gets or sets the auto-repeat interval for the click event when mouse button is kept pressed over the item.")] + public override int ClickRepeatInterval + { + get + { + return base.ClickRepeatInterval; + } + set + { + base.ClickRepeatInterval = value; + } + } + + /// + /// Gets or sets a value indicating whether the item is enabled. + /// + [Browsable(false), DevCoBrowsable(false), DefaultValue(true), Category("Behavior"), Description("Indicates whether is item enabled.")] + public override bool Enabled + { + get + { + return base.Enabled; + } + set + { + base.Enabled = value; + } + } + + /// + /// Indicates item's visiblity when on pop-up menu. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Appearance"), Description("Indicates item's visiblity when on pop-up menu."), DefaultValue(eMenuVisibility.VisibleAlways)] + public override eMenuVisibility MenuVisibility + { + get + { + return base.MenuVisibility; + } + set + { + base.MenuVisibility = value; + } + } + + /// + /// Indicates when menu items are displayed when MenuVisiblity is set to VisibleIfRecentlyUsed and RecentlyUsed is true. + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DevCoBrowsable(false), Category("Appearance"), Description("Indicates when menu items are displayed when MenuVisiblity is set to VisibleIfRecentlyUsed and RecentlyUsed is true."), DefaultValue(ePersonalizedMenus.Disabled)] + public override ePersonalizedMenus PersonalizedMenus + { + get + { + return base.PersonalizedMenus; + } + set + { + base.PersonalizedMenus = value; + } + } + + /// + /// Indicates Animation type for Popups. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Behavior"), Description("Indicates Animation type for Popups."), DefaultValue(ePopupAnimation.ManagerControlled)] + public override ePopupAnimation PopupAnimation + { + get + { + return base.PopupAnimation; + } + set + { + base.PopupAnimation = value; + } + } + + /// + /// Indicates the font that will be used on the popup window. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Appearance"), Description("Indicates the font that will be used on the popup window."), DefaultValue(null)] + public override System.Drawing.Font PopupFont + { + get + { + return base.PopupFont; + } + set + { + base.PopupFont = value; + } + } + + /// + /// Indicates whether sub-items are shown on popup Bar or popup menu. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Appearance"), Description("Indicates whether sub-items are shown on popup Bar or popup menu."), DefaultValue(ePopupType.Menu)] + public override ePopupType PopupType + { + get + { + return base.PopupType; + } + set + { + base.PopupType = value; + } + } + + /// + /// Specifies the inital width for the Bar that hosts pop-up items. Applies to PopupType.Toolbar only. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Layout"), Description("Specifies the inital width for the Bar that hosts pop-up items. Applies to PopupType.Toolbar only."), DefaultValue(200)] + public override int PopupWidth + { + get + { + return base.PopupWidth; + } + set + { + base.PopupWidth = value; + } + } + + /// + /// Gets or sets whether item will display sub items. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(true), Category("Behavior"), Description("Determines whether sub-items are displayed.")] + public override bool ShowSubItems + { + get + { + return base.ShowSubItems; + } + set + { + base.ShowSubItems = value; + } + } + + /// + /// Gets or sets whether the item expands automatically to fill out the remaining space inside the container. Applies to Items on stretchable, no-wrap Bars only. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), DefaultValue(false), Category("Appearance"), Description("Indicates whether item will stretch to consume empty space. Items on stretchable, no-wrap Bars only.")] + public override bool Stretch + { + get + { + return base.Stretch; + } + set + { + base.Stretch = value; + } + } + + /// + /// Gets or sets the width of the expand part of the button item. + /// + [Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), Category("Behavior"), Description("Indicates the width of the expand part of the button item."), DefaultValue(12)] + public override int SubItemsExpandWidth + { + get { return base.SubItemsExpandWidth; } + set + { + base.SubItemsExpandWidth = value; + } + } + + /// + /// Gets or set the alternative shortcut text. + /// + [System.ComponentModel.Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DevCoBrowsable(false), System.ComponentModel.Category("Design"), System.ComponentModel.Description("Gets or set the alternative Shortcut Text. This text appears next to the Text instead of any shortcuts"), System.ComponentModel.DefaultValue("")] + public override string AlternateShortCutText + { + get + { + return base.AlternateShortCutText; + } + set + { + base.AlternateShortCutText = value; + } + } + + /// + /// Gets or sets whether item separator is shown before this item. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false), System.ComponentModel.DefaultValue(false), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Indicates whether this item is beginning of the group.")] + public override bool BeginGroup + { + get + { + return base.BeginGroup; + } + set + { + base.BeginGroup = value; + } + } + + /// + /// Returns category for this item. If item cannot be customzied using the + /// customize dialog category is empty string. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false), System.ComponentModel.DefaultValue(""), System.ComponentModel.Category("Design"), System.ComponentModel.Description("Indicates item category used to group similar items at design-time."), EditorBrowsable(EditorBrowsableState.Never)] + public override string Category + { + get + { + + return base.Category; + } + set + { + base.Category = value; + } + } + + /// + /// Gets or sets the text color of the button when mouse is over the item. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The foreground color used to display text when mouse is over the item."), EditorBrowsable(EditorBrowsableState.Never)] + public override Color HotForeColor + { + get + { + return base.HotForeColor; + } + set + { + base.HotForeColor = value; + } + } + + /// + /// Indicates the way item is painting the picture when mouse is over it. Setting the value to Color will render the image in gray-scale when mouse is not over the item. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("Indicates the way item is painting the picture when mouse is over it. Setting the value to Color will render the image in gray-scale when mouse is not over the item."), System.ComponentModel.DefaultValue(eHotTrackingStyle.Default), EditorBrowsable(EditorBrowsableState.Never)] + public override eHotTrackingStyle HotTrackingStyle + { + get { return base.HotTrackingStyle; } + set + { + base.HotTrackingStyle = value; + } + } + + ///// + ///// Gets or sets the text color of the button. + ///// + //[System.ComponentModel.Browsable(false), DevCoBrowsable(false), EditorBrowsable(EditorBrowsableState.Never), System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("The foreground color used to display text.")] + //public override Color ForeColor + //{ + // get + // { + // return base.ForeColor; + // } + // set + // { + // base.ForeColor = value; + // } + //} + + /// + /// Gets/Sets the button style which controls the appearance of the button elements. Changing the property can display image only, text only or image and text on the button at all times. + /// + [Browsable(false), Category("Appearance"), Description("Determines the style of the button."), DefaultValue(eButtonStyle.ImageAndText), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override eButtonStyle ButtonStyle + { + get + { + return base.ButtonStyle; + } + set + { + base.ButtonStyle = value; + } + } + + public eTabFormStripControlDock TabAlignment + { + get + { + TabFormStripControl tabStrip = this.ContainerControl as TabFormStripControl; + if (tabStrip == null) return eTabFormStripControlDock.Top; + return tabStrip.TabAlignment; + } + } + + private Color[] _BackColors = null; + /// + /// Indicates the array of colors that when set are used to draw the background of the item. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that when set are used to draw the background of the item."), TypeConverter(typeof(ArrayConverter))] + public Color[] BackColors + { + get + { + return _BackColors; + } + set + { + if (_BackColors != value) + { + _BackColors = value; + //OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + this.Refresh(); + } + } + } + + private TabFormItemColorTable _CustomColorTable = null; + /// + /// Gets or sets the custom color table for the tab. When set this color table overrides all color settings for a tab. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TabFormItemColorTable CustomColorTable + { + get { return _CustomColorTable; } + set { _CustomColorTable = value; } + } + + internal static int Radius + { + get { return Dpi.Width8; } + } + + internal static int Dia + { + get { return Radius * 2; } + } + + internal static int Offset { get { return Dpi.Width2; } } + + internal static int TabOverlap + { + get { return Dpi.Width25; } + } + + internal static int CloseButtonSize + { + get { return 13; } + } + + /// + /// Gets color table key for the default tab color table. + /// + public static readonly string DefaultColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Default); + /// + /// Gets color table key for the green tab color table. + /// + public static readonly string GreenColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Green); + /// + /// Gets color table key for the magenta tab color table. + /// + public static readonly string MagentaColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Magenta); + /// + /// Gets color table key for the orange tab color table. + /// + public static readonly string OrangeColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Orange); + /// + /// Gets color table key for the red tab color table. + /// + public static readonly string RedColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Red); + /// + /// Gets color table key for the blue tab color table. + /// + public static readonly string BlueColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Blue); + /// + /// Gets color table key for the yellow tab color table. + /// + public static readonly string YellowColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Yellow); + /// + /// Gets color table key for the purple tab color table. + /// + public static readonly string PurpleColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Purple); + /// + /// Gets color table key for the cyan tab color table. + /// + public static readonly string CyanColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Cyan); + /// + /// Gets color table key for the blue mist tab color table. + /// + public static readonly string BlueMistColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.BlueMist); + /// + /// Gets color table key for the purple mist tab color table. + /// + public static readonly string PurpleMistColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.PurpleMist); + /// + /// Gets color table key for the tan tab color table. + /// + public static readonly string TanColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Tan); + /// + /// Gets color table key for the lemon lime tab color table. + /// + public static readonly string LemonLimeColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.LemonLime); + /// + /// Gets color table key for the apple tab color table. + /// + public static readonly string AppleColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Apple); + /// + /// Gets color table key for the teal tab color table. + /// + public static readonly string TealColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Teal); + /// + /// Gets color table key for the red chalk tab color table. + /// + public static readonly string RedChalkColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.RedChalk); + /// + /// Gets color table key for the silver tab color table. + /// + public static readonly string SilverColorTableKey = Enum.GetName(typeof(eTabFormItemColor), eTabFormItemColor.Silver); + #endregion + } + + /// + /// Specifies predefined color assigned to Tab Form Item. + /// + public enum eTabFormItemColor + { + Default, + Blue, + Yellow, + Green, + Red, + Purple, + Cyan, + Orange, + Magenta, + BlueMist, + PurpleMist, + Tan, + LemonLime, + Apple, + Teal, + RedChalk, + Silver + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormItemBase.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormItemBase.cs new file mode 100644 index 00000000..c5bf642e --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormItemBase.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using System.Text; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), DesignTimeVisible(false), Designer("DevComponents.DotNetBar.Design.TabFormItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class TabFormItemBase : ButtonItem + { + protected override void Dispose(bool disposing) + { + if (_TabPath != null) + { + _TabPath.Dispose(); + _TabPath = null; + } + base.Dispose(disposing); + } + + private bool _RenderTabState = true; + /// + /// Gets or sets whether tab renders its state. Used internally by DotNetBar. Do not set. + /// + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + internal bool RenderTabState + { + get { return _RenderTabState; } + set + { + _RenderTabState = value; + if (this.ContainerControl is System.Windows.Forms.Control) + ((System.Windows.Forms.Control)this.ContainerControl).Invalidate(); + else + this.Refresh(); + } + } + + private GraphicsPath _TabPath = null; + /// + /// Gets the actual tab path. + /// + [Browsable(false)] + public GraphicsPath TabPath + { + get { return _TabPath; } + internal set + { + if(_TabPath!=null) + _TabPath.Dispose(); + _TabPath = value; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormItemColorTable.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormItemColorTable.cs new file mode 100644 index 00000000..2e4913ab --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormItemColorTable.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + public class TabFormItemColorTable + { + /// + /// Gets or sets the name of the color table. + /// + public string Name = ""; + /// + /// Gets or sets the default tab colors. + /// + public TabFormItemStateColorTable Default = new TabFormItemStateColorTable(); + /// + /// Gets or sets the disabled tab colors. + /// + public TabFormItemStateColorTable Disabled = new TabFormItemStateColorTable(); + /// + /// Gets or sets the selected tab colors. + /// + public TabFormItemStateColorTable Selected = new TabFormItemStateColorTable(); + /// + /// Gets or sets the colors when mouse is over the tab but tab is not selected. + /// + public TabFormItemStateColorTable MouseOver = new TabFormItemStateColorTable(); + /// + /// Gets or sets colors for the tab close button. + /// + public TabCloseButtonColorTable CloseButton = new TabCloseButtonColorTable(); + } + + /// + /// Defines the color table for RibbonTabItem states. + /// + public class TabFormItemStateColorTable + { + /// + /// Indicates item text color. + /// + public Color TextColor = Color.Black; + /// + /// Gets or sets the background colors for the item. + /// + public Color[] BackColors = new Color[0]; + /// + /// Gets or sets the back colors gradient angle if there is more than one color in BackColors array. + /// + public int BackColorsGradientAngle = 90; + /// + /// Gets or sets the gradient colors positions if there is more than one color in BackColors array. + /// + public float[] BackColorsPositions = new float[0]; + /// + /// Gets or sets the item border colors. + /// + public Color[] BorderColors = new Color[0]; + + /// + /// Creates a copy of the state color table. + /// + public TabFormItemStateColorTable Clone() + { + TabFormItemStateColorTable t=new TabFormItemStateColorTable(); + t.BorderColors = BorderColors; + t.BackColors = BackColors; + t.TextColor = TextColor; + t.BackColorsGradientAngle = BackColorsGradientAngle; + t.BackColorsPositions = BackColorsPositions; + return t; + } + + } + + /// + /// Defines color table for TabFormItem close button displayed on tabs. + /// + public class TabCloseButtonColorTable + { + /// + /// Colors for the button in default state. + /// + public TabCloseButtonStateColorTable Normal = new TabCloseButtonStateColorTable(); + /// + /// Colors for button in mouse over state. + /// + public TabCloseButtonStateColorTable MouseOver = new TabCloseButtonStateColorTable(new Color[] { ColorScheme.GetColor(0xDB4336) }, ColorScheme.GetColor(0xFDFBFA), ColorScheme.GetColor(0xDB4336)); + /// + /// Colors for button when pressed with mouse state. + /// + public TabCloseButtonStateColorTable Pressed = new TabCloseButtonStateColorTable(new Color[] { ColorScheme.GetColor(0xA8352A) }, ColorScheme.GetColor(0xFDFBFA), ColorScheme.GetColor(0xA8352A)); + } + /// + /// Defines state color table for TabFormItem close button displayed on tabs. + /// + public class TabCloseButtonStateColorTable + { + /// + /// Gets or sets the background colors for the item. + /// + public Color[] BackColors = new Color[0]; + /// + /// Gets or sets the back colors gradient angle if there is more than one color in BackColors array. + /// + public int BackColorsGradientAngle = 90; + /// + /// Gets or sets the gradient colors positions if there is more than one color in BackColors array. + /// + public float[] BackColorsPositions = new float[0]; + /// + /// Indicates item sign color. + /// + public Color ForeColor = Color.Empty; + /// + /// Indicates item border color. + /// + public Color BorderColor = Color.Empty; + + public TabCloseButtonStateColorTable() + { + + } + + public TabCloseButtonStateColorTable(Color[] backColors, Color foreColor, Color borderColor) + { + BackColors = backColors; + ForeColor = foreColor; + BorderColor = borderColor; + } + + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormPainter.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormPainter.cs new file mode 100644 index 00000000..1b2c6ae8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormPainter.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.Metro; +using DevComponents.DotNetBar.Metro.Rendering; + +namespace DevComponents.DotNetBar.Rendering +{ + internal abstract class TabFormPainter + { + public abstract void Paint(TabFormPainterArgs args); + } + + internal class OfficeTabFormPainter : TabFormPainter, IOffice2007Painter + { + #region IOffice2007Painter + private Office2007ColorTable _ColorTable = null; + + /// + /// Gets or sets color table used by renderer. + /// + public Office2007ColorTable ColorTable + { + get { return _ColorTable; } + set { _ColorTable = value; } + } + #endregion + + public override void Paint(TabFormPainterArgs args) + { + TabParentForm form = args.TabParentForm; + Graphics g = args.Graphics; + TabFormColorTable colorTable = GetFormColorTable(); + if (form.FormTabsControl != null && form.FormTabsControl.ColorTable != null) + colorTable = form.FormTabsControl.ColorTable; + + Thickness borderThickness = form.BorderThickness; + BorderColors colors = form.BorderColor; + if (borderThickness.IsZero && colors.IsEmpty) + { + // Get it from table + borderThickness = colorTable.BorderThickness; + colors = form.IsActive ? colorTable.Active.BorderColors : colorTable.Inactive.BorderColors; + } + + using (SolidBrush brush = new SolidBrush(colorTable.BackColor.IsEmpty ? form.BackColor : colorTable.BackColor)) + g.FillRectangle(brush, new Rectangle(0, 0, form.Width, form.Height)); + + if (!borderThickness.IsZero && !colors.IsEmpty) + { + RectangleF br = new RectangleF(0, 0, form.Width, form.Height); + DrawingHelpers.DrawBorder(g, br, borderThickness, colors); + } + } + + private TabFormColorTable GetFormColorTable() + { + return _ColorTable.TabForm; + } + } + + public class TabFormPainterArgs : EventArgs + { + /// + /// Gets or sets Graphics object group is rendered on. + /// + public Graphics Graphics = null; + + /// + /// Gets or sets the reference to TabParentForm being rendered. + /// + public TabParentForm TabParentForm = null; + + + /// + /// Indicates whether to cancel system rendering of the item. + /// + public bool Cancel = false; + + public TabFormPainterArgs(TabParentForm form, Graphics graphics) + { + Graphics = graphics; + TabParentForm = form; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormPanel.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormPanel.cs new file mode 100644 index 00000000..6189a45e --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormPanel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Controls +{ + public class TabFormPanel : PanelControl + { + #region Internal Implementation + + private TabFormItem _TabFormItem; + /// + /// Gets the TabFormItem this panel is associated with + /// + public TabFormItem TabFormItem + { + get { return _TabFormItem; } + internal set { _TabFormItem = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStateColorTable.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStateColorTable.cs new file mode 100644 index 00000000..9d3a2ba6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStateColorTable.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using DevComponents.DotNetBar.Metro; + +namespace DevComponents.DotNetBar.Rendering +{ + /// + /// Defines state color table for TabParentForm. + /// + public class TabFormStateColorTable + { + /// + /// Gets or sets the colors for the top part of the background. + /// + public Color[] CaptionBackColors = new Color[0]; + /// + /// Gets or sets the back colors gradient angle if there is more than one color in BackColors array. + /// + public int CaptionBackColorsGradientAngle = 90; + /// + /// Gets or sets the gradient colors positions if there is more than one color in BackColors array. + /// + public float[] CaptionBackColorsPositions = new float[0]; + + /// + /// Gets or sets the color of caption text. + /// + public Color CaptionText = Color.Empty; + + /// + /// Gets or sets the border colors. + /// + public BorderColors BorderColors = new BorderColors(ColorScheme.GetColor("696969")); + + public TabFormStateColorTable() + { + + } + + public TabFormStateColorTable(Color[] captionBackColors, Color captionText, BorderColors borderColors) + { + CaptionBackColors = captionBackColors; + CaptionText = captionText; + BorderColors = borderColors; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStripContainerItem.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStripContainerItem.cs new file mode 100644 index 00000000..e804559b --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStripContainerItem.cs @@ -0,0 +1,1147 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using DevComponents.UI.ContentManager; +using DevComponents.DotNetBar.Primitives; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Defines the internal container item for the ribbon strip control. + /// + [System.ComponentModel.ToolboxItem(false), System.ComponentModel.DesignTimeVisible(false)] + internal class TabFormStripContainerItem : ImageItem, IDesignTimeProvider + { + #region Private Variables + private TabFormItemsSimpleContainer _ItemContainer = null; + private CaptionItemContainer _CaptionContainer = null; + private SystemCaptionItem _SystemCaptionItem = null; + private TabFormStripControl _TabStrip = null; + private SystemCaptionItem _WindowIcon = null; + private Separator _IconSeparator = null; + #endregion + + #region Constructor + /// + /// Creates new instance of the class and initializes it with the parent RibbonStrip control. + /// + /// Reference to parent RibbonStrip control + public TabFormStripContainerItem(TabFormStripControl parent) + { + _TabStrip = parent; + + // We contain other controls + m_IsContainer = true; + this.AccessibleRole = System.Windows.Forms.AccessibleRole.Grouping; + _ItemContainer = new TabFormItemsSimpleContainer(); + _ItemContainer.ContainerControl = parent; + _ItemContainer.GlobalItem = false; + _ItemContainer.OverlapSpacing = TabFormItem.TabOverlap; + _ItemContainer.OverlapType = typeof(TabFormItemBase); + //_ItemContainer.WrapItems = false; + //_ItemContainer.EventHeight = false; + //_ItemContainer.UseMoreItemsButton = false; + _ItemContainer.Stretch = true; + _ItemContainer.Displayed = true; + //_ItemContainer.SystemContainer = true; + //_ItemContainer.PaddingTop = 0; + //_ItemContainer.PaddingBottom = 0; + //_ItemContainer.PaddingLeft = 0; + //_ItemContainer.ItemSpacing = 1; + + _CaptionContainer = new CaptionItemContainer(); + _CaptionContainer.ContainerControl = parent; + _CaptionContainer.GlobalItem = false; + _CaptionContainer.WrapItems = false; + _CaptionContainer.EventHeight = false; + _CaptionContainer.EqualButtonSize = false; + _CaptionContainer.ToolbarItemsAlign = eContainerVerticalAlignment.Top; + _CaptionContainer.UseMoreItemsButton = false; + _CaptionContainer.Stretch = true; + _CaptionContainer.Displayed = true; + _CaptionContainer.SystemContainer = true; + _CaptionContainer.PaddingBottom = 0; + _CaptionContainer.PaddingTop = 0; + _CaptionContainer.PaddingLeft = 6; + _CaptionContainer.ItemSpacing = 1; + _CaptionContainer.TrackSubItemsImageSize = false; + _CaptionContainer.ItemAdded += new EventHandler(this.CaptionContainerNewItemAdded); + + _CaptionItemsContainer = new CaptionItemContainer(); + _CaptionItemsContainer.ContainerControl = parent; + _CaptionItemsContainer.GlobalItem = false; + _CaptionItemsContainer.WrapItems = false; + _CaptionItemsContainer.EventHeight = false; + _CaptionItemsContainer.EqualButtonSize = false; + _CaptionItemsContainer.ToolbarItemsAlign = eContainerVerticalAlignment.Top; + _CaptionItemsContainer.UseMoreItemsButton = false; + _CaptionItemsContainer.Stretch = true; + _CaptionItemsContainer.Displayed = true; + _CaptionItemsContainer.SystemContainer = true; + _CaptionItemsContainer.PaddingBottom = 0; + _CaptionItemsContainer.PaddingTop = 0; + _CaptionItemsContainer.PaddingLeft = 6; + _CaptionItemsContainer.ItemSpacing = 1; + _CaptionItemsContainer.TrackSubItemsImageSize = false; + + this.SubItems.Add(_CaptionContainer); + this.SubItems.Add(_CaptionItemsContainer); + this.SubItems.Add(_ItemContainer); + + SystemCaptionItem sc = new SystemCaptionItem(); + sc.RestoreEnabled = false; + sc.IsSystemIcon = false; + sc.ItemAlignment = eItemAlignment.Far; + sc.SetSystemItem(true); + _SystemCaptionItem = sc; + this.SubItems.Add(_SystemCaptionItem); + } + + + #endregion + + #region Internal Implementation + internal void OnCaptionVisibleChanged(bool newCaptionVisible) + { + if (_SystemCaptionItem != null) + { + if (newCaptionVisible) + { + if (_SystemCaptionItem.Parent != _CaptionContainer) + { + if (_SystemCaptionItem.Parent != null) + _SystemCaptionItem.Parent.SubItems.Remove(_SystemCaptionItem); + _CaptionContainer.SubItems.Add(_SystemCaptionItem); + } + } + else + { + if (_SystemCaptionItem.Parent != this) + { + if (_SystemCaptionItem.Parent != null) + _SystemCaptionItem.Parent.SubItems.Remove(_SystemCaptionItem); + this.SubItems.Add(_SystemCaptionItem); + } + } + } + } + + private CaptionItemContainer _CaptionItemsContainer = null; + /// + /// Gets the list of the items displayed in form caption if its visible. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), MergableProperty(false)] + public SubItemsCollection CaptionItems + { + get { return _CaptionItemsContainer.SubItems; } + } + + /// + /// Occurs after an item has been added to the container. This procedure is called on both item being added and the parent of the item. To distinguish between those two states check the item parameter. + /// + /// When occurring on the parent this will hold the reference to the item that has been added. When occurring on the item being added this will be null (Nothing). + protected internal override void OnItemAdded(BaseItem item) + { + if (_SystemCaptionItem != null && _SystemCaptionItem.Parent == this && item != _SystemCaptionItem) + { + this.SubItems._Remove(_SystemCaptionItem); + this.SubItems._Add(_SystemCaptionItem); + } + base.OnItemAdded(item); + } + + private void CaptionContainerNewItemAdded(object sender, EventArgs e) + { + if (sender is BaseItem) + { + BaseItem item = sender as BaseItem; + if (!(item is SystemCaptionItem)) + { + if (_CaptionContainer.SubItems.Contains(_SystemCaptionItem)) + { + _CaptionContainer.SubItems._Remove(_SystemCaptionItem); + _CaptionContainer.SubItems._Add(_SystemCaptionItem); + } + } + } + } + + internal void ReleaseSystemFocus() + { + _ItemContainer.ReleaseSystemFocus(); + if (_TabStrip.CaptionVisible) + { + _CaptionContainer.ReleaseSystemFocus(); + _CaptionItemsContainer.ReleaseSystemFocus(); + } + } + + public override void ContainerLostFocus(bool appLostFocus) + { + base.ContainerLostFocus(appLostFocus); + _ItemContainer.ContainerLostFocus(appLostFocus); + if (_TabStrip.CaptionVisible) + { + _CaptionContainer.ContainerLostFocus(appLostFocus); + _CaptionItemsContainer.ContainerLostFocus(appLostFocus); + } + } + + internal void SetSystemFocus() + { + if (_TabStrip.CaptionVisible && _ItemContainer.ExpandedItem() == null) + _CaptionContainer.SetSystemFocus(); + else + _ItemContainer.SetSystemFocus(); + } + + /// + /// Paints this base container + /// + public override void Paint(ItemPaintArgs pa) + { + if (this.SuspendLayout) + return; + if (_ScrollEnabled) + { + pa.Graphics.SetClip(_ScrollClipBounds); + _ItemContainer.ClippingRectangle = _ScrollClipBounds; + } + else + _ItemContainer.ClippingRectangle = Rectangle.Empty; + _ItemContainer.Paint(pa); + if (_TabStrip.CaptionVisible) + { + _CaptionContainer.Paint(pa); + _CaptionItemsContainer.Paint(pa); + } + if (_SystemCaptionItem.Parent == this) + _SystemCaptionItem.Paint(pa); + + } + + private int _ScrollButtonWidth = 22; + /// + /// Gets or sets the scroll button width. + /// + public int ScrollButtonWidth + { + get { return _ScrollButtonWidth; } + set { _ScrollButtonWidth = value; } + } + private bool _ScrollEnabled = false; + private ButtonX _LeftScrollButton = null, _RightScrollButton = null; + private Rectangle _ScrollClipBounds = Rectangle.Empty; + private int _MaxScrolPos = 0; + private void RepositionScrollButtons() + { + if (_LeftScrollButton == null || _RightScrollButton == null) return; + Rectangle tabsBounds = GetItemContainerBounds(); + Rectangle itemsBounds = _ItemContainer.Bounds; + int scrollButtonWidth = Dpi.Width(_ScrollButtonWidth); + _LeftScrollButton.Bounds = new Rectangle(tabsBounds.X, itemsBounds.Y + Dpi.Height2, scrollButtonWidth, itemsBounds.Height - Dpi.Height3); + _RightScrollButton.Bounds = new Rectangle(tabsBounds.Right - scrollButtonWidth, itemsBounds.Y + Dpi.Height2, scrollButtonWidth, itemsBounds.Height - Dpi.Height3); + } + + public override void RecalcSize() + { + if (this.SuspendLayout) + return; + TabFormStripControl strip = this.ContainerControl as TabFormStripControl; + Form form = null; + if (strip != null) + form = strip.FindForm(); + if (_SystemCaptionItem.Parent == this) + { + _SystemCaptionItem.Displayed = true; + _SystemCaptionItem.RecalcSize(); + _SystemCaptionItem.LeftInternal = this.Bounds.Right - _SystemCaptionItem.WidthInternal; + _SystemCaptionItem.TopInternal = this.Bounds.Y + (IsParentFormMaximized ? Dpi.Height4 : Dpi.Height1); + } + Rectangle tabsBounds = GetItemContainerBounds(); + _ItemContainer.Bounds = tabsBounds; + _ItemContainer.RecalcSize(); + if (_ItemContainer.WidthInternal > tabsBounds.Width) // Using scroll buttons + { + _MaxScrolPos = (tabsBounds.Width - Dpi.Width(_ScrollButtonWidth * 2)) - _ItemContainer.WidthInternal; + if (_ScrollEnabled) + { + // Just check scroll position + //throw new NotImplementedException(); + RepositionScrollButtons(); + } + else + { + if (strip != null) + { + _LeftScrollButton = new ButtonX(); + _LeftScrollButton.Name = "sysLeftScrollButton"; + _LeftScrollButton.Symbol = "\ue314"; + _LeftScrollButton.SymbolSet = eSymbolSet.Material; + _LeftScrollButton.Shape = new RoundRectangleShapeDescriptor(0); + _LeftScrollButton.Click += LeftScrollButtonClick; + _RightScrollButton = new ButtonX(); + _RightScrollButton.Name = "sysRightScrollButton"; + _RightScrollButton.Symbol = "\ue315"; + _RightScrollButton.SymbolSet = eSymbolSet.Material; + _RightScrollButton.Shape = new RoundRectangleShapeDescriptor(0); + _RightScrollButton.Click += RightScrollButtonClick; + RepositionScrollButtons(); + strip.Controls.Add(_LeftScrollButton); + strip.Controls.Add(_RightScrollButton); + _ScrollEnabled = true; + } + } + tabsBounds.X += Dpi.Width(_ScrollButtonWidth); + tabsBounds.Width -= Dpi.Width(_ScrollButtonWidth) * 2; + _ItemContainer.Bounds = tabsBounds; + _ItemContainer.RecalcSize(); + if (_ScrollPos < _MaxScrolPos) _ScrollPos = _MaxScrolPos; + _ItemContainer.ScrollPosition = _ScrollPos; + _ScrollClipBounds = tabsBounds; + //_ScrollClipBounds.X += Dpi.Width(_ScrollButtonWidth); + //_ScrollClipBounds.Width -= Dpi.Width(_ScrollButtonWidth) * 2; + } + else if (_ScrollEnabled) + { + // Remove scrolling + if (_LeftScrollButton != null) + { + if (_LeftScrollButton.Parent != null) + _LeftScrollButton.Parent.Controls.Remove(_LeftScrollButton); + _LeftScrollButton.Click -= LeftScrollButtonClick; + _LeftScrollButton.Dispose(); + _LeftScrollButton = null; + } + if (_RightScrollButton != null) + { + if (_RightScrollButton.Parent != null) + _RightScrollButton.Parent.Controls.Remove(_RightScrollButton); + _RightScrollButton.Click -= RightScrollButtonClick; + _RightScrollButton.Dispose(); + _RightScrollButton = null; + } + _ScrollEnabled = false; + } + + if (_ItemContainer.HeightInternal < 0) _ItemContainer.HeightInternal = 0; + bool isMaximized = false; + if (_TabStrip.CaptionVisible) + { + Rectangle captionContainerBounds = GetCaptionContainerBounds(); + _CaptionContainer.Bounds = captionContainerBounds; + _CaptionContainer.RecalcSize(); + Size frameBorderSize = SystemInformation.FrameBorderSize; + if (strip != null) + { + if (form != null) + { + if (_WindowIcon != null) + _WindowIcon.SetVisibleDirect(form.ShowIcon && _TabStrip.ShowIcon); + if (_IconSeparator != null) + _IconSeparator.SetVisibleDirect(form.ShowIcon && _TabStrip.ShowIcon); + } + TabParentForm appForm = form as TabParentForm; + if (appForm != null) + { + NonClientInfo nci = appForm.GetNonClientInfo(); + frameBorderSize.Width = nci.LeftBorder; + frameBorderSize.Height = nci.BottomBorder; + } + } + if (_TabStrip.CaptionHeight == 0 && _SystemCaptionItem.TopInternal < (frameBorderSize.Height - 1)) + { + if (form != null && form.WindowState == FormWindowState.Maximized) + isMaximized = true; + + if (isMaximized) + { + _SystemCaptionItem.TopInternal = 1; + if (_WindowIcon != null) _WindowIcon.TopInternal = 1; + } + else + { + _SystemCaptionItem.TopInternal = Math.Max(1, frameBorderSize.Height - 6); + if (_WindowIcon != null) _WindowIcon.TopInternal = frameBorderSize.Height - 5; + } + } + + // Adjust the Y position of the items inside of the caption container since they are top aligned and + // quick access toolbar items should be aligned with the bottom of the system caption item. + if (System.Environment.OSVersion.Version.Major >= 6) + { + int topOffset = 3; + if (isMaximized) + topOffset += 1; + int maxBottom = 0; + foreach (BaseItem item in _CaptionContainer.SubItems) + { + if (!(item is ApplicationButton || item is DevComponents.DotNetBar.Metro.MetroAppButton) && item != _SystemCaptionItem && item != _IconSeparator) + item.TopInternal += topOffset; + else if (item == _IconSeparator) + item.TopInternal += (isMaximized ? 2 : Dpi.Height4); + maxBottom = Math.Max(item.Bounds.Bottom, maxBottom); + } + if (_CaptionContainer.MoreItems != null) + _CaptionContainer.MoreItems.TopInternal += topOffset; + if (maxBottom > _CaptionContainer.HeightInternal) _CaptionContainer.SetDisplayRectangle(new Rectangle(_CaptionContainer.Bounds.X, _CaptionContainer.Bounds.Y, _CaptionContainer.Bounds.Width, maxBottom)); + } + else + { + int maxBottom = 0; + foreach (BaseItem item in _CaptionContainer.SubItems) + { + if (item.HeightInternal < _SystemCaptionItem.HeightInternal && (item != _IconSeparator && item != _WindowIcon)) + { + //item.TopInternal += (m_SystemCaptionItem.HeightInternal - item.HeightInternal); + item.TopInternal = (_SystemCaptionItem.Bounds.Bottom - (item.HeightInternal + ((item is LabelItem) ? 2 : 0))); + maxBottom = Math.Max(item.Bounds.Bottom, maxBottom); + } + } + if (_CaptionContainer.MoreItems != null) + _CaptionContainer.MoreItems.TopInternal += (_SystemCaptionItem.HeightInternal - _CaptionContainer.MoreItems.HeightInternal); + if (maxBottom > _CaptionContainer.HeightInternal) _CaptionContainer.SetDisplayRectangle(new Rectangle(_CaptionContainer.Bounds.X, _CaptionContainer.Bounds.Y, _CaptionContainer.Bounds.Width, maxBottom)); + } + + // Items contained in caption are inside their own container + Rectangle captionItemsContainerBounds = captionContainerBounds; + if (_IconSeparator != null) + { + captionItemsContainerBounds.X = _IconSeparator.Bounds.Right + Dpi.Width6; + captionItemsContainerBounds.Width -= _IconSeparator.Bounds.Right + Dpi.Width6; + } + if (_SystemCaptionItem != null) + { + captionItemsContainerBounds.Width -= (captionItemsContainerBounds.Right - + _SystemCaptionItem.Bounds.Left) + Dpi.Width6; + } + + if (strip != null) + { + Size titleSize = Size.Empty; + using (Graphics g = strip.CreateGraphics()) + { + string text = strip.TitleText; + if (string.IsNullOrEmpty(text) && form != null) text = form.Text; + bool isTitleTextMarkup = strip.TitleTextMarkupBody != null; + if (isTitleTextMarkup) + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, strip.Font, Color.Black, + strip.RightToLeft == System.Windows.Forms.RightToLeft.Yes, captionItemsContainerBounds, false); + d.AllowMultiLine = false; + TextMarkup.BodyElement body = strip.TitleTextMarkupBody; + body.Measure(captionItemsContainerBounds.Size, d); + titleSize = body.Bounds.Size; + strip.TitleTextMarkupLastArrangeBounds=Rectangle.Empty; + } + else + { + titleSize = TextDrawing.MeasureString(g, text, strip.Font); + } + } + captionItemsContainerBounds.X += titleSize.Width + Dpi.Width4; + captionItemsContainerBounds.Width -= titleSize.Width + Dpi.Width4; + } + + if (captionItemsContainerBounds.Width > 0) + { + _CaptionItemsContainer.Bounds = captionItemsContainerBounds; + _CaptionItemsContainer.RecalcSize(); + // Adjust the Y position of the items inside of the caption container since they are top aligned and + // quick access toolbar items should be aligned with the bottom of the system caption item. + if (_CaptionItemsContainer.SubItems.Count > 0) + { + int topOffset = 3; + if (isMaximized) + topOffset += 1; + int maxBottom = 0; + foreach (BaseItem item in _CaptionItemsContainer.SubItems) + { + item.TopInternal += topOffset; + maxBottom = Math.Max(item.Bounds.Bottom, maxBottom); + } + if (_CaptionItemsContainer.MoreItems != null) + _CaptionItemsContainer.MoreItems.TopInternal += topOffset; + if (maxBottom > _CaptionItemsContainer.HeightInternal) + _CaptionItemsContainer.SetDisplayRectangle(new Rectangle(_CaptionItemsContainer.Bounds.X, + _CaptionItemsContainer.Bounds.Y, _CaptionItemsContainer.Bounds.Width, maxBottom)); + } + } + + if (_ItemContainer.HeightInternal == 0) + this.HeightInternal = _CaptionContainer.HeightInternal; + else + this.HeightInternal = _ItemContainer.Bounds.Bottom;// -m_CaptionContainer.Bounds.Top; + } + else + { + int h = _ItemContainer.HeightInternal; + this.HeightInternal = h; + } + + base.RecalcSize(); + } + + private bool IsParentFormMaximized + { + get + { + Control c = (Control)this.ContainerControl; + if (c != null) + { + Form form = c.FindForm(); + if (form != null) + return (form.WindowState == FormWindowState.Maximized); + } + return false; + } + } + private int _ScrollStep = 96; + /// + /// Indicates the scroll in pixels each time scroll button is pressed. + /// + public int ScrollStep + { + get { return _ScrollStep; } + set { _ScrollStep = value; } + } + + private Animation.AnimationInt _Animation = null; + private int _ScrollPos = 0; + void RightScrollButtonClick(object sender, EventArgs e) + { + int newScrollPos = Math.Max(_MaxScrolPos, _ScrollPos - Dpi.Width(_ScrollStep)); + if (newScrollPos != _ScrollPos) + { + WaitForCurrentAnimationToComplete(); + EnsureAnimation(); + _ScrollPos = newScrollPos; + _Animation.Animations.Add(new Animation.AnimationRequest(_ItemContainer, "ScrollPosition", _ItemContainer.ScrollPosition, newScrollPos)); + _Animation.Start(); + } + } + + void LeftScrollButtonClick(object sender, EventArgs e) + { + int newScrollPos = Math.Min(0, _ScrollPos + Dpi.Width(_ScrollStep)); + if (newScrollPos != _ScrollPos) + { + WaitForCurrentAnimationToComplete(); + EnsureAnimation(); + _ScrollPos = newScrollPos; + _Animation.Animations.Add(new Animation.AnimationRequest(_ItemContainer, "ScrollPosition", _ItemContainer.ScrollPosition, newScrollPos)); + _Animation.Start(); + } + } + + private void EnsureAnimation() + { + if (_Animation == null) + { + _Animation = new Animation.AnimationInt(Animation.AnimationEasing.EaseOutQuint, 300); + _Animation.AnimationCompleted += AnimationCompleted; + } + } + private void AnimationCompleted(object sender, EventArgs e) + { + Animation.Animation anim = (Animation.Animation)sender; + anim.AnimationCompleted -= AnimationCompleted; + anim.Dispose(); + } + private void WaitForCurrentAnimationToComplete() + { + if (_Animation != null) + { + DateTime start = DateTime.Now; + while (!_Animation.IsDisposed) + { + Application.DoEvents(); + if (DateTime.Now.Subtract(start).TotalMilliseconds > 1000) + { + AbortCurrentAnimation(); + break; + } + } + _Animation = null; + } + } + private void AbortCurrentAnimation() + { + Animation.Animation anim = _Animation; + _Animation = null; + if (anim != null) + { + anim.Stop(); + anim.Dispose(); + } + } + + private Rectangle GetItemContainerBounds() + { + Rectangle r = _TabStrip.GetItemContainerBounds(); + if (_SystemCaptionItem.Parent == this) + r.Width -= _SystemCaptionItem.WidthInternal + Dpi.Width2; + return r; + } + + private Rectangle GetCaptionContainerBounds() + { + return _TabStrip.GetCaptionContainerBounds(); + } + + /// + /// Gets reference to internal ribbon strip container that contains tabs and/or other items. + /// + public TabFormItemsSimpleContainer TabsContainer + { + get { return _ItemContainer; } + } + + /// + /// Gets reference to internal caption container item that contains the quick toolbar, start button and system caption item. + /// + public GenericItemContainer CaptionContainer + { + get { return _CaptionContainer; } + } + + public SystemCaptionItem SystemCaptionItem + { + get { return _SystemCaptionItem; } + } + + /// + /// Returns copy of GenericItemContainer item + /// + public override BaseItem Copy() + { + TabFormStripContainerItem objCopy = new TabFormStripContainerItem(_TabStrip); + this.CopyToItem(objCopy); + + return objCopy; + } + protected override void CopyToItem(BaseItem copy) + { + TabFormStripContainerItem objCopy = copy as TabFormStripContainerItem; + base.CopyToItem(objCopy); + } + + + public override void InternalClick(MouseButtons mb, Point mpos) + { + _ItemContainer.InternalClick(mb, mpos); + if (_SystemCaptionItem.Parent == this) + _SystemCaptionItem.InternalClick(mb, mpos); + if (_TabStrip.CaptionVisible) + { + _CaptionContainer.InternalClick(mb, mpos); + _CaptionItemsContainer.InternalClick(mb, mpos); + } + } + + public override void InternalDoubleClick(MouseButtons mb, Point mpos) + { + _ItemContainer.InternalDoubleClick(mb, mpos); + if (_TabStrip.CaptionVisible) + { + _CaptionContainer.InternalDoubleClick(mb, mpos); + _CaptionItemsContainer.InternalDoubleClick(mb, mpos); + } + } + + public override void InternalMouseDown(MouseEventArgs objArg) + { + _ItemContainer.InternalMouseDown(objArg); + if (_SystemCaptionItem.Parent == this) + _SystemCaptionItem.InternalMouseDown(objArg); + if (_TabStrip.CaptionVisible) + { + if (this.DesignMode && _CaptionContainer.ItemAtLocation(objArg.X, objArg.Y) != null || !this.DesignMode) + _CaptionContainer.InternalMouseDown(objArg); + if (this.DesignMode && _CaptionItemsContainer.ItemAtLocation(objArg.X, objArg.Y) != null || !this.DesignMode) + _CaptionItemsContainer.InternalMouseDown(objArg); + } + } + + public override void InternalMouseHover() + { + _ItemContainer.InternalMouseHover(); + if (_SystemCaptionItem.Parent == this) + _SystemCaptionItem.InternalMouseHover(); + if (_TabStrip.CaptionVisible) + { + _CaptionContainer.InternalMouseHover(); + _CaptionItemsContainer.InternalMouseHover(); + } + } + + public override void InternalMouseLeave() + { + _ItemContainer.InternalMouseLeave(); + if (_SystemCaptionItem.Parent == this) + _SystemCaptionItem.InternalMouseLeave(); + if (_TabStrip.CaptionVisible) + { + _CaptionContainer.InternalMouseLeave(); + _CaptionItemsContainer.InternalMouseLeave(); + } + } + + public override void InternalMouseMove(MouseEventArgs objArg) + { + _ItemContainer.InternalMouseMove(objArg); + if (_SystemCaptionItem.Parent == this) + _SystemCaptionItem.InternalMouseMove(objArg); + if (_TabStrip.CaptionVisible) + { + _CaptionContainer.InternalMouseMove(objArg); + _CaptionItemsContainer.InternalMouseMove(objArg); + } + } + + public override void InternalMouseUp(MouseEventArgs objArg) + { + _ItemContainer.InternalMouseUp(objArg); + if (_SystemCaptionItem.Parent == this) + _SystemCaptionItem.InternalMouseUp(objArg); + if (_TabStrip.CaptionVisible) + { + _CaptionContainer.InternalMouseUp(objArg); + _CaptionItemsContainer.InternalMouseUp(objArg); + } + } + + public override void InternalKeyDown(KeyEventArgs objArg) + { + BaseItem expanded = this.ExpandedItem(); + if (expanded == null) + expanded = _CaptionContainer.ExpandedItem(); + if (expanded == null) + expanded = _ItemContainer.ExpandedItem(); + + if (expanded == null || !_TabStrip.CaptionVisible) + { + _ItemContainer.InternalKeyDown(objArg); + if (!objArg.Handled && _TabStrip.CaptionVisible) + { + _CaptionContainer.InternalKeyDown(objArg); + _CaptionItemsContainer.InternalKeyDown(objArg); + } + } + else + { + if (expanded.Parent == _ItemContainer) + { + _ItemContainer.InternalKeyDown(objArg); + } + else + { + _CaptionContainer.InternalKeyDown(objArg); + } + } + } + + private bool _NewTabItemVisible = false; + /// + /// Indicates whether new tab item which allows creation of new tab when clicked is visible. When visible you need to handle CreateNewTab event and create your new tab in event handler. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether new tab item which allows creation of new tab when clicked is visible. When visible you need to handle CreateNewTab event and create your new tab in event handler.")] + public bool NewTabItemVisible + { + get { return _NewTabItemVisible; } + set + { + _NewTabItemVisible = value; + UpdateNewTabItemVisibility(); + } + } + + private NewTabFormItem _NewTabFormItem = null; + private void UpdateNewTabItemVisibility() + { + if (_NewTabItemVisible) + { + if (_NewTabFormItem == null) + { + _NewTabFormItem = new NewTabFormItem(); + _ItemContainer.SubItems.Add(_NewTabFormItem); + _NewTabFormItem.Click += NewTabFormItemClick; + } + } + else + { + if (_NewTabFormItem != null) + { + _NewTabFormItem.Parent.SubItems.Remove(_NewTabFormItem); + _NewTabFormItem.Dispose(); + _NewTabFormItem = null; + } + } + + NeedRecalcSize = true; + this.RecalcSize(); + } + + private void NewTabFormItemClick(object sender, EventArgs e) + { + OnCreateNewTab(EventArgs.Empty); + } + + /// + /// Occurs when new tab item is clicked by end user and allows you to create and add new tab to the control. + /// + [Description("Occurs when new tab item is clicked by end user and allows you to create and add new tab to the control.")] + public event EventHandler CreateNewTab; + + /// + /// Raises CreateNewTab event. + /// + /// Provides event arguments. + protected virtual void OnCreateNewTab(EventArgs e) + { + EventHandler handler = CreateNewTab; + if (handler != null) + handler(this, e); + } + + /// + /// Return Sub Item at specified location + /// + public override BaseItem ItemAtLocation(int x, int y) + { + if (_ItemContainer.DisplayRectangle.Contains(x, y)) + return _ItemContainer.ItemAtLocation(x, y); + + if (_CaptionContainer.DisplayRectangle.Contains(x, y)) + return _CaptionContainer.ItemAtLocation(x, y); + + return null; + } + + protected override void OnStyleChanged() + { + eDotNetBarStyle effectiveStyle = this.EffectiveStyle; + //if (effectiveStyle == eDotNetBarStyle.Office2010) + //{ + if (_WindowIcon == null) + { + _IconSeparator = new Separator("sys_caption_separator"); + _IconSeparator.SetSystemItem(true); + _IconSeparator.DesignTimeVisible = false; + _IconSeparator.CanCustomize = false; + _CaptionContainer.SubItems._Add(_IconSeparator, 0); + _WindowIcon = new SystemCaptionItem(); + _WindowIcon.Name = "sys_caption_icon"; + _WindowIcon.Enabled = false; + _WindowIcon.Style = this.Style; + _WindowIcon.IsSystemIcon = true; + _WindowIcon.DesignTimeVisible = false; + _WindowIcon.CanCustomize = false; + _WindowIcon.QueryIconOnPaint = true; + _WindowIcon.MouseDown += WindowIconMouseDown; + _WindowIcon.DoubleClick += WindowIconDoubleClick; + _WindowIcon.SetSystemItem(true); + _CaptionContainer.SubItems._Add(_WindowIcon, 0); + } + //} + //else if (effectiveStyle == eDotNetBarStyle.Windows7) + //{ + // if (_WindowIcon == null) + // { + // _IconSeparator = new Separator("sys_caption_separator"); + // _IconSeparator.FixedSize = new Size(3, 12); + // _IconSeparator.SetSystemItem(true); + // _IconSeparator.DesignTimeVisible = false; + // _IconSeparator.CanCustomize = false; + // _CaptionContainer.SubItems._Add(_IconSeparator, 0); + // _WindowIcon = new SystemCaptionItem(); + // _WindowIcon.Name = "sys_caption_icon"; + // _WindowIcon.Enabled = false; + // _WindowIcon.Style = this.Style; + // _WindowIcon.IsSystemIcon = true; + // _WindowIcon.QueryIconOnPaint = true; + // _WindowIcon.DesignTimeVisible = false; + // _WindowIcon.CanCustomize = false; + // _WindowIcon.SetSystemItem(true); + // _WindowIcon.MouseDown += WindowIconMouseDown; + // _CaptionContainer.SubItems._Add(_WindowIcon, 0); + // } + //} + //else if (StyleManager.IsMetro(effectiveStyle)) + //{ + // if (_WindowIcon == null) + // { + // _IconSeparator = new Separator("sys_caption_separator"); + // _IconSeparator.FixedSize = new Size(3, 14); + // _IconSeparator.SetSystemItem(true); + // _IconSeparator.DesignTimeVisible = false; + // _IconSeparator.CanCustomize = false; + // _CaptionContainer.SubItems._Add(_IconSeparator, 0); + // _WindowIcon = new SystemCaptionItem(); + // _WindowIcon.Name = "sys_caption_icon"; + // _WindowIcon.Enabled = false; + // _WindowIcon.Style = this.Style; + // _WindowIcon.IsSystemIcon = true; + // _WindowIcon.DesignTimeVisible = false; + // _WindowIcon.CanCustomize = false; + // _WindowIcon.QueryIconOnPaint = true; + // _WindowIcon.MouseDown += WindowIconMouseDown; + // _WindowIcon.DoubleClick += WindowIconDoubleClick; + // _WindowIcon.SetSystemItem(true); + // _CaptionContainer.SubItems._Add(_WindowIcon, 0); + // } + //} + //else if (_WindowIcon != null) + //{ + // if (_CaptionContainer.SubItems.Contains(_WindowIcon)) + // _CaptionContainer.SubItems._Remove(_WindowIcon); + // _WindowIcon.MouseDown -= WindowIconMouseDown; + // _WindowIcon.DoubleClick -= WindowIconDoubleClick; + // _WindowIcon.Dispose(); + // _WindowIcon = null; + // if (_CaptionContainer.SubItems.Contains(_IconSeparator)) + // _CaptionContainer.SubItems._Remove(_IconSeparator); + // _IconSeparator.Dispose(); + // _IconSeparator = null; + //} + base.OnStyleChanged(); + } + + void WindowIconDoubleClick(object sender, EventArgs e) + { + if (_TabStrip != null) + { + _TabStrip.CloseParentForm(); + } + } + + void WindowIconMouseDown(object sender, MouseEventArgs e) + { + TabFormStripControl mts = this.ContainerControl as TabFormStripControl; + if (mts != null) + { + Point p = new Point(_WindowIcon.LeftInternal, _WindowIcon.Bounds.Bottom + 1); + p = mts.PointToScreen(p); + mts.ShowSystemMenu(p); + } + } + #endregion + + #region IDesignTimeProvider Members + + public InsertPosition GetInsertPosition(Point pScreen, BaseItem DragItem) + { + InsertPosition pos = _ItemContainer.GetInsertPosition(pScreen, DragItem); + //if (pos == null && _TabStrip.CaptionVisible) + // pos = _CaptionItemsContainer.GetInsertPosition(pScreen, DragItem); + return pos; + } + + public void DrawReversibleMarker(int iPos, bool Before) + { + //DesignTimeProviderContainer.DrawReversibleMarker(this, iPos, Before); + } + + public void InsertItemAt(BaseItem objItem, int iPos, bool Before) + { + //DesignTimeProviderContainer.InsertItemAt(this, objItem, iPos, Before); + } + + /// + /// Gets or sets a value indicating whether the item is expanded or not. For Popup items this would indicate whether the item is popped up or not. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DefaultValue(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public override bool Expanded + { + get + { + return base.Expanded; + } + set + { + base.Expanded = value; + if (!value) + { + foreach (BaseItem item in this.SubItems) + item.Expanded = false; + } + } + } + + /// + /// When parent items does recalc size for its sub-items it should query + /// image size and store biggest image size into this property. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override System.Drawing.Size SubItemsImageSize + { + get + { + return base.SubItemsImageSize; + } + set + { + //m_SubItemsImageSize = value; + } + } + #endregion + } + + // + /// Represents simple item container which orders items horizontally and support all ItemAlignment settings. + /// + [ToolboxItem(false), EditorBrowsable(EditorBrowsableState.Never)] + public class TabFormItemsSimpleContainer : SimpleItemContainer + { + public override void Paint(ItemPaintArgs p) + { + TabFormItem selectedTab = null; + //foreach (BaseItem item in this.SubItems) + for (int i = this.SubItems.Count - 1; i >= 0; i--) + { + BaseItem item = this.SubItems[i]; + if (!item.Displayed) continue; + if (item.BeginGroup) + { + DisplayHelp.DrawLine(p.Graphics, item.LeftInternal - 3, this.TopInternal + 4, item.LeftInternal - 3, this.Bounds.Bottom - 8, p.Colors.ItemSeparator, 1); + } + TabFormItem tab = item as TabFormItem; + if (tab != null && tab.Checked && selectedTab == null) + selectedTab = tab; + else + { + if (_ClippingRectangle.IsEmpty || _ClippingRectangle.IntersectsWith(item.Bounds)) + item.Paint(p); + } + } + if (selectedTab != null) + { + selectedTab.Paint(p); + } + } + + public override void RecalcSize() + { + _ScrollPosition = 0; + base.RecalcSize(); + } + + /// + /// Return Sub Item at specified location + /// + public override BaseItem ItemAtLocation(int x, int y) + { + foreach (BaseItem objSub in SubItems) + { + TabFormItemBase tab = objSub as TabFormItemBase; + if (tab != null && tab.Visible && tab.Displayed && tab.TabPath != null) + { + if (tab.TabPath.IsVisible(x, y)) + return tab; + } + } + + return base.ItemAtLocation(x, y); + } + + private NewTabFormItem _NewTabFormItem = null; + /// + /// Occurs after an item has been added to the container. This procedure is called on both item being added and the parent of the item. To distinguish between those two states check the item parameter. + /// + /// When occurring on the parent this will hold the reference to the item that has been added. When occurring on the item being added this will be null (Nothing). + protected internal override void OnItemAdded(BaseItem item) + { + if (item is NewTabFormItem) + _NewTabFormItem = (NewTabFormItem)item; + else if (_NewTabFormItem != null) + { + this.SubItems._Remove(_NewTabFormItem); + this.SubItems._Add(_NewTabFormItem); + } + base.OnItemAdded(item); + } + + /// + /// Occurs after an item has been removed. + /// + /// Item being removed. + protected internal override void OnAfterItemRemoved(BaseItem item, int itemIndex) + { + if (item == _NewTabFormItem) + _NewTabFormItem = null; + base.OnAfterItemRemoved(item, itemIndex); + } + + protected override bool IsVerticallyCentered(BaseItem item) + { + return !(item is TabFormItem); + } + + /// + /// Gets or sets a value indicating whether the item is expanded or not. For Popup items this would indicate whether the item is popped up or not. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DefaultValue(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public override bool Expanded + { + get + { + return base.Expanded; + } + set + { + base.Expanded = value; + if (!value) + { + foreach (BaseItem item in this.SubItems) + item.Expanded = false; + } + } + } + + private Rectangle _ClippingRectangle; + public Rectangle ClippingRectangle + { + get { return _ClippingRectangle; } + set { _ClippingRectangle = value; } + } + + private int _ScrollPosition = 0; + [System.Reflection.Obfuscation(Exclude = true)] + public int ScrollPosition + { + get + { + return _ScrollPosition; + } + set + { + value = Math.Min(0, value); // Must be negative number + if (_ScrollPosition != value) + { + Point offset = new Point(value - _ScrollPosition, 0); + _ScrollPosition = value; + OffsetSubItems(offset); + this.Refresh(); + } + } + } + + private void OffsetSubItems(Point offset) + { + if (offset.IsEmpty) + return; + + BaseItem[] items = new BaseItem[this.SubItems.Count]; + this.SubItems.CopyTo(items, 0); + foreach (IBlock b in items) + { + Rectangle r = b.Bounds; + r.Offset(offset); + b.Bounds = r; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStripControl.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStripControl.cs new file mode 100644 index 00000000..7afd00bc --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStripControl.cs @@ -0,0 +1,1642 @@ +using DevComponents.DotNetBar.Rendering; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Windows.Forms; +using System.Windows.Forms.VisualStyles; +using DevComponents.DotNetBar.Metro; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents tabbed UI strip control. + /// + [ToolboxItem(false), ComVisible(false)] + public class TabFormStripControl : ItemControl + { + #region Private Variables & Constructor + private TabFormStripContainerItem _StripContainer = null; + private int _CaptionHeight = 0; + private bool _CaptionVisible = false; + private Rectangle _CaptionBounds = Rectangle.Empty; + private Rectangle _SystemCaptionItemBounds = Rectangle.Empty; + private Font _CaptionFont = null; + private bool _CanCustomize = true; + private ElementStyle _DefaultBackgroundStyle = new ElementStyle(); + private string _TitleText = ""; + + public TabFormStripControl() + { + this.SetStyle(ControlStyles.StandardDoubleClick, true); + + _StripContainer = new TabFormStripContainerItem(this); + _StripContainer.GlobalItem = false; + _StripContainer.ContainerControl = this; + _StripContainer.Displayed = true; + _StripContainer.SetOwner(this); + _StripContainer.Style = eDotNetBarStyle.StyleManagerControlled; + _StripContainer.CreateNewTab += StripContainerCreateNewTab; + this.SetBaseItemContainer(_StripContainer); + + this.ColorScheme.Style = eDotNetBarStyle.Office2003; + + this.AutoSize = true; + this.DragDropSupport = true; + this.AllowDrop = true; + this.AllowExternalDrop = true; + + // Setup system caption item + _StripContainer.SystemCaptionItem.Click += new EventHandler(SystemCaptionClick); + + StyleManager.Register(this); + } + + void StripContainerCreateNewTab(object sender, EventArgs e) + { + if (this.Parent is TabFormControl) + ((TabFormControl)this.Parent).RaiseCreateNewTab(e); + } + protected override void Dispose(bool disposing) + { + StyleManager.Unregister(this); + base.Dispose(disposing); + } + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + this.Style = StyleManager.GetEffectiveStyle(); + } + #endregion + + #region Events + /// + /// Occurs when text markup link from TitleText markup is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + [Description("Occurs when text markup link from TitleText markup is clicked.")] + public event MarkupLinkClickEventHandler TitleTextMarkupLinkClick; + #endregion + + #region Internal Implementation + private TextMarkup.BodyElement _TitleTextMarkup = null; + /// + /// Gets or sets the rich text displayed on Ribbon Title instead of the Form.Text property. This property supports text-markup. + /// You can use markup to instruct the markup renderer to use Office 2007 system caption extra text color which + /// changes depending on the currently selected color table. Note that when using this property you should manage also the Form.Text property since + /// that is the text that will be displayed in Windows task-bar and elsewhere where system Form.Text property is used. + /// You can also use the hyperlinks as part of the text markup and handle the TitleTextMarkupLinkClick event to be notified when they are clicked. + /// + [Browsable(true), DefaultValue(""), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), EditorBrowsable(EditorBrowsableState.Always), Category("Appearance"), Description("Indicates text displayed on Ribbon Title instead of the Form.Text property.")] + public string TitleText + { + get { return _TitleText; } + set + { + if (value == null) value = ""; + _TitleText = value; + _TitleTextMarkup = null; + + if (!TextMarkup.MarkupParser.IsMarkup(ref _TitleText)) + return; + + _TitleTextMarkup = TextMarkup.MarkupParser.Parse(_TitleText); + + if (_TitleTextMarkup != null) + _TitleTextMarkup.HyperLinkClick += new EventHandler(InternalTitleTextMarkupLinkClick); + TitleTextMarkupLastArrangeBounds = Rectangle.Empty; + this.Invalidate(); + } + } + + /// + /// Occurs when text markup link is clicked. + /// + private void InternalTitleTextMarkupLinkClick(object sender, EventArgs e) + { + TextMarkup.HyperLink link = sender as TextMarkup.HyperLink; + if (link != null) + { + if (TitleTextMarkupLinkClick != null) + TitleTextMarkupLinkClick(this, new MarkupLinkClickEventArgs(link.Name, link.HRef)); + } + } + + /// + /// Gets reference to parsed markup body element if text was markup otherwise returns null. + /// + internal TextMarkup.BodyElement TitleTextMarkupBody + { + get { return _TitleTextMarkup; } + } + + internal Rectangle TitleTextMarkupLastArrangeBounds = Rectangle.Empty; + + /// + /// Gets or sets whether control can be customized and items added by end-user using context menu to the quick access toolbar. + /// Caption of the control must be visible for customization to be enabled. Default value is true. + /// + [DefaultValue(true), Browsable(true), Category("Customization"), Description("Indicates whether control can be customized. Caption must be visible for customization to be fully enabled.")] + public bool CanCustomize + { + get { return _CanCustomize; } + set { _CanCustomize = value; } + } + + /// + /// Gets or sets the explicit height of the caption provided by control. Caption height when set is composed of the TabGroupHeight and + /// the value specified here. Default value is 0 which means that system default caption size is used. + /// + [Browsable(true), DefaultValue(0), Category("Appearance"), Description("Indicates explicit height of the caption provided by control")] + public int CaptionHeight + { + get { return _CaptionHeight; } + set + { + _CaptionHeight = value; + _StripContainer.NeedRecalcSize = true; + } + } + + internal bool HasVisibleTabs + { + get + { + foreach (BaseItem item in this.Items) + { + if (item.Visible) return true; + } + return false; + } + } + + internal Rectangle CaptionBounds + { + get { return _CaptionBounds; } + set { _CaptionBounds = value; } + } + + internal Rectangle SystemCaptionItemBounds + { + get { return _SystemCaptionItemBounds; } + set { _SystemCaptionItemBounds = value; } + } + + internal SystemCaptionItem SystemCaptionItem + { + get { return _StripContainer.SystemCaptionItem; } + } + + /// + /// Gets or sets whether custom caption line provided by the control is visible. Default value is false. + /// This property should be set to true when control is used on Office2007RibbonForm. + /// + [Browsable(true), DefaultValue(false), Category("Appearance"), Description("Indicates whether custom caption line provided by the control is visible.")] + public bool CaptionVisible + { + get { return _CaptionVisible; } + set + { + _CaptionVisible = value; + OnCaptionVisibleChanged(); + } + } + + /// + /// Gets or sets the font for the form caption text when CaptionVisible=true. Default value is NULL which means that system font is used. + /// + [Browsable(true), DefaultValue(null), Category("Appearance"), Description("")] + public Font CaptionFont + { + get { return _CaptionFont; } + set + { + _CaptionFont = value; + _StripContainer.NeedRecalcSize = true; + this.Invalidate(); + } + } + + private void OnCaptionVisibleChanged() + { + _StripContainer.NeedRecalcSize = true; + _StripContainer.OnCaptionVisibleChanged(_CaptionVisible); + this.RecalcLayout(); + } + + internal eDotNetBarStyle EffectiveStyle + { + get + { + return _StripContainer.EffectiveStyle; + } + } + /// + /// Gets/Sets the visual style of the control. + /// + [Browsable(true), DevCoBrowsable(true), Category("Appearance"), Description("Specifies the visual style of the control."), DefaultValue(eDotNetBarStyle.Metro)] + public eDotNetBarStyle Style + { + get + { + return _StripContainer.Style; + } + set + { + this.ColorScheme.Style = value; + _StripContainer.Style = value; + this.Invalidate(); + this.RecalcLayout(); + } + } + + /// + /// Returns collection of items on a bar. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] + public SubItemsCollection Items + { + get + { + return _StripContainer.TabsContainer.SubItems; + } + } + + /// + /// Returns currently selected TabFormItem. TabFormItems are selected using the Checked property. Only a single + /// TabFormItem can be Checked at any given time. + /// + [Browsable(false)] + public TabFormItem SelectedTab + { + get + { + foreach (BaseItem item in this.Items) + { + if (item is TabFormItem && ((TabFormItem)item).Checked) + return (TabFormItem)item; + } + return null; + } + } + + protected override void WndProc(ref Message m) + { + if (m.Msg == (int)WinApi.WindowsMessages.WM_NCHITTEST) + { + int borderSize = Dpi.Width6; + // Get position being tested... + int x = WinApi.LOWORD(m.LParam); + int y = WinApi.HIWORD(m.LParam); + Point p = PointToClient(new Point(x, y)); + if (IsGlassEnabled && this.CaptionVisible) + { + Rectangle r = new Rectangle(this.Width - BarFunctions.CaptionButtonSize.Width * 3, 0, BarFunctions.CaptionButtonSize.Width * 3, BarFunctions.CaptionButtonSize.Height + 6); + if (r.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + + r = new Rectangle(0, 0, this.Width, 4); + if (r.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + + if (_CaptionBounds.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + } + else if (this.CaptionVisible && !this.IsMaximized) + { + Rectangle r = new Rectangle(0, 0, this.Width, 4); + if (r.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + } + else if (!SystemCaptionItem.Bounds.Contains(p)) + { + BaseItem item = HitTest(p.X, p.Y); + if (item == null) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + } + else if (p.X <= borderSize || p.X >= this.Width - borderSize || p.Y <= borderSize || p.Y >= this.Height - borderSize) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + if (BarFunctions.IsWindows7 && this.IsMaximized) + { + if (this.CaptionBounds.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TransparentOrCovered); + return; + } + } + } + + base.WndProc(ref m); + } + + internal bool IsMaximized + { + get + { + Form f = this.FindForm(); + return (f != null && f.WindowState == FormWindowState.Maximized); + } + } + + /// + /// Returns the color scheme used by control. Color scheme for Office2007 style will be retrived from the current renderer instead of + /// local color scheme referenced by ColorScheme property. + /// + /// An instance of ColorScheme object. + protected override ColorScheme GetColorScheme() + { + BaseRenderer r = GetRenderer(); + if (r is Office2007Renderer) + return ((Office2007Renderer)r).ColorTable.LegacyColors; + return base.GetColorScheme(); + } + + protected override void PaintControlBackground(ItemPaintArgs pa) + { + base.PaintControlBackground(pa); + + _CaptionBounds = Rectangle.Empty; + _SystemCaptionItemBounds = Rectangle.Empty; + + Rendering.BaseRenderer render = GetRenderer(); + render.DrawTabFormStrip(new TabFormStripPainterArgs(this, pa.Graphics, pa)); + +#if TRIAL + if (NativeFunctions.ColorExpAlt()) + { + pa.Graphics.Clear(Color.White); + TextDrawing.DrawString(pa.Graphics, "Your DotNetBar trial has expired :-(", this.Font, Color.FromArgb(128, Color.Black), this.ClientRectangle, eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter); + } +#endif + } + + protected override ElementStyle GetBackgroundStyle() + { + if (this.BackgroundStyle.Custom) + return base.GetBackgroundStyle(); + return _DefaultBackgroundStyle; + } + + internal void InitDefaultStyles() + { + _DefaultBackgroundStyle = new ElementStyle(); + } + + internal ElementStyle InternalGetBackgroundStyle() + { + return this.GetBackgroundStyle(); + } + + internal Rectangle GetItemContainerBounds() + { + Rectangle r = base.GetItemContainerRectangle(); + if (_CaptionVisible) + { + r.Y += GetAbsoluteCaptionHeight(); + } + else + r.Y += TopNormalPadding; + return r; + } + + internal Rectangle GetCaptionContainerBounds() + { + Rectangle baseRect = base.GetItemContainerRectangle(); + if (this.IsGlassEnabled) + baseRect.Y += 3; + return new Rectangle(baseRect.X, baseRect.Y, baseRect.Width, GetAbsoluteCaptionHeight()); + } + /// + /// Returns effective caption height. + /// + /// Caption height. + public int GetCaptionHeight() + { + if (_CaptionHeight == 0) + { + //if (StyleManager.Style == eStyle.OfficeMobile2014 || StyleManager.Style == eStyle.Office2016) + return Dpi.Height24; + //else + // return Dpi.Height28; + } + else + { + return Dpi.Height(_CaptionHeight); + } + } + + internal int GetAbsoluteCaptionHeight() + { + return GetCaptionHeight(); + } + + internal int GetTotalCaptionHeight() + { + return GetCaptionHeight(); + } + + internal override bool IsGlassEnabled + { + get + { + return false; + } + } + + protected override void OnPaint(PaintEventArgs e) + { + if (_StripContainer.NeedRecalcSize) this.RecalcSize(); + InitDefaultStyles(); + base.OnPaint(e); + } + + protected override void RecalcSize() + { + _CaptionBounds = Rectangle.Empty; + _SystemCaptionItemBounds = Rectangle.Empty; + InitDefaultStyles(); + base.RecalcSize(); + } + + /// + /// Returns automatically calculated height of the control given current content. + /// + /// Height in pixels. + public override int GetAutoSizeHeight() + { + int i = base.GetAutoSizeHeight(); + if (!_CaptionVisible) + i += TopNormalPadding; + return i; + } + + private int TopNormalPadding = 4; + + protected override bool OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + Rectangle r = this.DisplayRectangle; + r.Location = this.PointToScreen(r.Location); + + TabFormControl rc = this.Parent as TabFormControl; + + if (rc != null && !rc.MouseWheelTabScrollEnabled) return false; + + Point mousePos = Control.MousePosition; + + bool parentActive = true; + Form parentForm = this.FindForm(); + if (parentForm != null && !BarFunctions.IsFormActive(parentForm)) + parentActive = false; + + if (parentActive && r.Contains(mousePos) && !this.ShowKeyTips && this.Items.Count > 0) + { + IntPtr handle = NativeFunctions.WindowFromPoint(new NativeFunctions.POINT(mousePos)); + Control c = Control.FromChildHandle(handle); + if (c == null) + c = Control.FromHandle(handle); + if (c is TabFormStripControl || c is TabFormControl || c is TabFormPanel) + { + TabFormItem selectedTab = this.SelectedTab; + int start = 0; + int end = this.Items.Count - 1; + + int direction = 1; + if ((wParam.ToInt64() & 0x80000000) > 0) + { + direction = -1; + end = 0; + } + if (selectedTab != null) + { + start = this.Items.IndexOf(selectedTab) + direction; + if (direction < 0 && start < 0) return false; + + if (start == this.Items.Count) + start = 0; + else if (start < 0) + start = this.Items.Count - 1; + } + + int index = start - direction; + do + { + index += direction; + if (index < 0 || index > this.Items.Count - 1) break; + + if (this.Items[index] is TabFormItem && this.Items[index].Visible) + { + ((TabFormItem)this.Items[index]).Checked = true; + return true; + } + } while (index != end); + } + } + + return false; + } + + /// + /// Returns the collection of items with the specified name. + /// + /// Item name to look for. + /// + public override ArrayList GetItems(string ItemName) + { + ArrayList list = new ArrayList(15); + BarFunctions.GetSubItemsByName(GetBaseItemContainer(), ItemName, list); + + TabFormControl rc = this.GetTabFormControl(); + + if (rc != null && rc.GlobalContextMenuBar != null) + BarFunctions.GetSubItemsByName(rc.GlobalContextMenuBar.ItemsContainer, ItemName, list); + + return list; + } + + /// + /// Returns the collection of items with the specified name and type. + /// + /// Item name to look for. + /// Item type to look for. + /// + public override ArrayList GetItems(string ItemName, Type itemType) + { + ArrayList list = new ArrayList(15); + BarFunctions.GetSubItemsByNameAndType(GetBaseItemContainer(), ItemName, list, itemType); + + TabFormControl rc = this.GetTabFormControl(); + if (rc != null && rc.GlobalContextMenuBar != null) + BarFunctions.GetSubItemsByNameAndType(rc.GlobalContextMenuBar.ItemsContainer, ItemName, list, itemType); + + return list; + } + + /// + /// Returns the collection of items with the specified name and type. + /// + /// Item name to look for. + /// Item type to look for. + /// Indicates whether GlobalName property is used for searching. + /// + public override ArrayList GetItems(string ItemName, Type itemType, bool useGlobalName) + { + ArrayList list = new ArrayList(15); + BarFunctions.GetSubItemsByNameAndType(GetBaseItemContainer(), ItemName, list, itemType, useGlobalName); + + TabFormControl rc = this.GetTabFormControl(); + + if (rc != null && rc.GlobalContextMenuBar != null) + BarFunctions.GetSubItemsByNameAndType(rc.GlobalContextMenuBar.ItemsContainer, ItemName, list, itemType, useGlobalName); + + return list; + } + + /// + /// Returns the first item that matches specified name. + /// + /// Item name to look for. + /// + public override BaseItem GetItem(string ItemName) + { + BaseItem item = BarFunctions.GetSubItemByName(GetBaseItemContainer(), ItemName); + if (item != null) + return item; + + TabFormControl rc = this.GetTabFormControl(); + if (rc != null && rc.GlobalContextMenuBar != null) + return BarFunctions.GetSubItemByName(rc.GlobalContextMenuBar.ItemsContainer, ItemName); + + return null; + } + #endregion + + #region Caption Container Support + private bool _ShowIcon = true; + /// + /// Indicates whether Form.Icon is shown in top-left corner. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether Form.Icon is shown in top-left corner.")] + public bool ShowIcon + { + get + { + return _ShowIcon; + } + set + { + if (_ShowIcon != value) + { + _ShowIcon = value; + _StripContainer.NeedRecalcSize = true; + this.RecalcLayout(); + } + } + } + + /// + /// Called when item on popup container is right-clicked. + /// + /// Instance of the item that is right-clicked. + protected override void OnPopupItemRightClick(BaseItem item) + { + //TabFormControl rc = this.GetTabFormControl(); + //if (rc != null) + // rc.ShowCustomizeContextMenu(item, false); + } + //private MetroTab GetTabFormControl() + //{ + // Control parent = this.Parent; + // while (parent != null && !(parent is MetroTab)) + // parent = parent.Parent; + // if (parent is MetroTab) + // return parent as MetroTab; + // return null; + //} + protected override void OnMouseLeave(EventArgs e) + { + if (_TitleTextMarkup != null) + _TitleTextMarkup.MouseLeave(this); + base.OnMouseLeave(e); + } + + internal bool MouseDownOnCaption + { + get + { + return _MouseDownOnCaption; + } + } + + private TabFormControl GetTabFormControl() + { + return this.Parent as TabFormControl; + } + + internal void ShowSystemMenu(Point p) + { + Form form = this.FindForm(); + if (form is TabParentForm) + ((TabParentForm)form).ShowSystemWindowMenu(p); + else + { + const int TPM_RETURNCMD = 0x0100; + byte[] bx = BitConverter.GetBytes(p.X); + byte[] by = BitConverter.GetBytes(p.Y); + byte[] blp = new byte[] { bx[0], bx[1], by[0], by[1] }; + int lParam = BitConverter.ToInt32(blp, 0); + this.Capture = false; + NativeFunctions.SendMessage(form.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.TrackPopupMenu( + NativeFunctions.GetSystemMenu(form.Handle, false), TPM_RETURNCMD, p.X, p.Y, 0, form.Handle, IntPtr.Zero), lParam); + } + } + + private bool _MouseDownOnCaption = false; + private Point _MouseDownPoint = Point.Empty; + protected override void OnMouseDown(MouseEventArgs e) + { + _MouseDownOnCaption = false; + _MouseDownPoint = e.Location; + if (_CaptionVisible) + { + _MouseDownOnCaption = HitTestCaption(new Point(e.X, e.Y)); + if (e.Button == MouseButtons.Right && _MouseDownOnCaption) + { + ShowSystemMenu(Control.MousePosition); + return; + } + + if (_TitleTextMarkup != null) + _TitleTextMarkup.MouseDown(this, e); + + e = TranslateMouseEventArgs(e); + } + + base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + if (_CaptionVisible) + { + if (_TitleTextMarkup != null) + _TitleTextMarkup.MouseUp(this, e); + + e = TranslateMouseEventArgs(e); + } + _MouseDownOnCaption = false; + base.OnMouseUp(e); + } + + //internal BaseItem GetApplicationButton() + //{ + // if (!this.CaptionVisible) + // return null; + // BaseItem cont = this.CaptionContainerItem; + + // if (this.EffectiveStyle == eDotNetBarStyle.Office2010 && this.Items.Count > 0 && this.Items[0] is MetroAppButton) + // return this.Items[0]; + + // if (cont.SubItems.Count > 0 && cont.SubItems[0] is MetroAppButton) + // return cont.SubItems[0]; + + // if (cont.SubItems.Count > 0 && cont.SubItems[0] is ButtonItem && ((ButtonItem)cont.SubItems[0]).HotTrackingStyle == eHotTrackingStyle.Image) + // return cont.SubItems[0]; + + // return null; + //} + /// + /// Starts moving of the parent form action which happens when user attempts to drag the form caption. + /// + public void StartFormMove() + { + Form form = this.FindForm(); + if (form != null && form.WindowState == FormWindowState.Normal) + { + //PopupItem popup = GetApplicationButton() as PopupItem; + //if (popup != null && popup.Expanded) popup.Expanded = false; + + const int HTCAPTION = 2; + Point p = Control.MousePosition; + byte[] bx = BitConverter.GetBytes(p.X); + byte[] by = BitConverter.GetBytes(p.Y); + byte[] blp = new byte[] { bx[0], bx[1], by[0], by[1] }; + int lParam = BitConverter.ToInt32(blp, 0); + this.Capture = false; + NativeFunctions.SendMessage(form.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_MOVE + HTCAPTION, lParam); + _MouseDownOnCaption = false; + } + } + protected override void OnMouseMove(MouseEventArgs e) + { + if (_CaptionVisible) + { + if (e.Button == MouseButtons.Left && (_MouseDownOnCaption && HitTestCaption(new Point(e.X, e.Y)) || HitTest(_MouseDownPoint.X, _MouseDownPoint.Y) == null)) + { + Form form = this.FindForm(); + if (form != null && form.WindowState == FormWindowState.Normal) + { + StartFormMove(); + return; + } + } + if (_TitleTextMarkup != null) + _TitleTextMarkup.MouseMove(this, e); + e = TranslateMouseEventArgs(e); + } + base.OnMouseMove(e); + } + + protected override void InternalOnClick(MouseButtons mb, Point mousePos) + { + if (_CaptionVisible) + { + MouseEventArgs e = new MouseEventArgs(mb, 0, mousePos.X, mousePos.Y, 0); + e = TranslateMouseEventArgs(e); + mousePos = new Point(e.X, e.Y); + } + + base.InternalOnClick(mb, mousePos); + } + + private MouseEventArgs TranslateMouseEventArgs(MouseEventArgs e) + { + if (e.Y <= 6) + { + Form form = this.FindForm(); + if (form != null && form.WindowState == FormWindowState.Maximized && form is RibbonForm) + { + if (e.X <= 4) + { + //BaseItem sb = GetApplicationButton(); + //if (sb != null) + //{ + // e = new MouseEventArgs(e.Button, e.Clicks, sb.LeftInternal + 1, sb.TopInternal + 1, e.Delta); + //} + } + else if (e.X >= this.Width - 6) + e = new MouseEventArgs(e.Button, e.Clicks, this.SystemCaptionItem.DisplayRectangle.Right - 4, this.SystemCaptionItem.DisplayRectangle.Top + 4, e.Delta); + else + e = new MouseEventArgs(e.Button, e.Clicks, e.X, this.CaptionContainerItem.TopInternal + 5, e.Delta); + } + } + return e; + } + + protected override void OnClick(EventArgs e) + { + if (_CaptionVisible) + { + if (_TitleTextMarkup != null) + _TitleTextMarkup.Click(this); + } + base.OnClick(e); + } + + protected override void OnDoubleClick(EventArgs e) + { + if (_CaptionVisible) + { + // Check whether double click is on caption so window can be maximized/restored + Point p = this.PointToClient(Control.MousePosition); + if (HitTestCaption(p)) + { + Form form = this.FindForm(); + if (form != null && form.MaximizeBox && (form.FormBorderStyle == FormBorderStyle.Sizable || form.FormBorderStyle == FormBorderStyle.SizableToolWindow)) + { + if (form.WindowState == FormWindowState.Normal) + { + NativeFunctions.PostMessage(form.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_MAXIMIZE, 0); + } + else if (form.WindowState == FormWindowState.Maximized) + { + NativeFunctions.PostMessage(form.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_RESTORE, 0); + } + } + } + } + base.OnDoubleClick(e); + } + + /// + /// Returns true if point is inside the caption area. + /// + /// Client point coordinates. + /// True if point is inside of caption area otherwise false. + protected bool HitTestCaption(Point p) + { + return _CaptionBounds.Contains(p); + } + + private void SystemCaptionClick(object sender, EventArgs e) + { + SystemCaptionItem sci = sender as SystemCaptionItem; + Form frm = this.FindForm(); + + if (frm == null) + return; + + if (sci.LastButtonClick == sci.MouseDownButton) + { + if (sci.LastButtonClick == SystemButton.Minimize) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_MINIMIZE, 0); + } + else if (sci.LastButtonClick == SystemButton.Maximize) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_MAXIMIZE, 0); + } + else if (sci.LastButtonClick == SystemButton.Restore) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_RESTORE, 0); + } + else if (sci.LastButtonClick == SystemButton.Close) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_CLOSE, 0); + } + else if (sci.LastButtonClick == SystemButton.Help) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_CONTEXTHELP, 0); + } + } + } + + internal void CloseParentForm() + { + Form frm = this.FindForm(); + + if (frm == null) + return; + + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_CLOSE, 0); + } + + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + + Form frm = this.FindForm(); + if (frm == null) + return; + + if (frm.WindowState == FormWindowState.Maximized || frm.WindowState == FormWindowState.Minimized) + _StripContainer.SystemCaptionItem.RestoreEnabled = true; + else + _StripContainer.SystemCaptionItem.RestoreEnabled = false; + } + + /// + /// Gets the reference to the internal container item for the items displayed in control caption. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GenericItemContainer CaptionContainerItem + { + get { return _StripContainer.CaptionContainer; } + } + + /// + /// Gets the reference to the internal container for the ribbon tabs and other items. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SimpleItemContainer StripContainerItem + { + get { return _StripContainer.TabsContainer; } + } + + internal TabFormStripContainerItem TabStripContainer + { + get + { + return _StripContainer; + } + } + + private Cursor _FloatDragCursor = null; + protected override void OnGiveFeedback(GiveFeedbackEventArgs e) + { + if (e.Effect == DragDropEffects.None) + { + if (_FloatDragCursor == null) // Try to create drag cursor + { + + } + if (_FloatDragCursor != null) + { + e.UseDefaultCursors = false; + Cursor.Current = _FloatDragCursor; + } + } + base.OnGiveFeedback(e); + } + + protected override void OnItemDragAndDropped(BaseItem dragItem) + { + base.OnItemDragAndDropped(dragItem); + + TabFormItem tab = dragItem as TabFormItem; + if (tab != null && tab.Enabled && tab.Visible) + { + if (tab.Checked) tab.Checked = false; + tab.Checked = true; + } + } + + //protected override void PaintKeyTips(Graphics g) + //{ + // if (!this.ShowKeyTips) + // return; + + // KeyTipsRendererEventArgs e = new KeyTipsRendererEventArgs(g, Rectangle.Empty, "", GetKeyTipFont(), null); + + // DevComponents.DotNetBar.Rendering.BaseRenderer renderer = GetRenderer(); + // PaintContainerKeyTips(_StripContainer.TabsContainer, renderer, e); + // if (_CaptionVisible) + // PaintContainerKeyTips(_StripContainer.CaptionContainer, renderer, e); + //} + + //protected override Rectangle GetKeyTipRectangle(Graphics g, BaseItem item, Font font, string keyTip) + //{ + // Rectangle r = base.GetKeyTipRectangle(g, item, font, keyTip); + // if (this.QuickToolbarItems.Contains(item)) + // r.Y += 4; + // return r; + //} + #endregion + + #region Mdi Child System Item + internal void ClearMDIChildSystemItems(bool bRecalcLayout) + { + if (_StripContainer.TabsContainer == null) + return; + bool recalc = false; + try + { + if (this.Items.Contains("dotnetbarsysiconitem")) + { + this.Items.Remove("dotnetbarsysiconitem"); + recalc = true; + } + if (this.Items.Contains("dotnetbarsysmenuitem")) + { + this.Items.Remove("dotnetbarsysmenuitem"); + recalc = true; + } + if (bRecalcLayout && recalc) + this.RecalcLayout(); + } + catch (Exception) + { + } + } + + internal void ShowMDIChildSystemItems(System.Windows.Forms.Form objMdiChild, bool bRecalcLayout) + { + ClearMDIChildSystemItems(bRecalcLayout); + + if (objMdiChild == null) + return; + + MDISystemItem mdi = new MDISystemItem("dotnetbarsysmenuitem"); + if (!objMdiChild.ControlBox) + mdi.CloseEnabled = false; + if (!objMdiChild.MinimizeBox) + mdi.MinimizeEnabled = false; + if (!objMdiChild.MaximizeBox) + { + mdi.RestoreEnabled = false; + } + mdi.ItemAlignment = eItemAlignment.Far; + mdi.Click += new System.EventHandler(this.MDISysItemClick); + + this.Items.Add(mdi); + + if (bRecalcLayout) + this.RecalcLayout(); + } + + private void MDISysItemClick(object sender, System.EventArgs e) + { + MDISystemItem mdi = sender as MDISystemItem; + Form frm = this.FindForm(); + if (frm != null) + frm = frm.ActiveMdiChild; + if (frm == null) + { + ClearMDIChildSystemItems(true); + return; + } + if (mdi.LastButtonClick == SystemButton.Minimize) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_MINIMIZE, 0); + } + else if (mdi.LastButtonClick == SystemButton.Restore) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_RESTORE, 0); + } + else if (mdi.LastButtonClick == SystemButton.Close) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_CLOSE, 0); + } + else if (mdi.LastButtonClick == SystemButton.NextWindow) + { + NativeFunctions.PostMessage(frm.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_NEXTWINDOW, 0); + } + } + + private eTabFormStripControlDock _TabAlignment = eTabFormStripControlDock.Top; + /// + /// Indiciates the appearance of the tab form items rendered on the strip + /// + [DefaultValue(eTabFormStripControlDock.Top), Category("Appearance"), Description("Indiciates the appearance of the tab form items rendered on the strip")] + public eTabFormStripControlDock TabAlignment + { + get { return _TabAlignment; } + set + { + _TabAlignment = value; + } + } + + private bool _IsTabDragEnabled = true; + + /// + /// Indicates whether end-user tab reordering is enabled, default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether end-user tab reordering is enabled.")] + public bool IsTabDragEnabled + { + get { return _IsTabDragEnabled; } + set { _IsTabDragEnabled = value; } + } + + private bool _TabDetachEnabled = true; + /// + /// Indicates whether user can detach the tabs into the new forms using drag and drop. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether user can detach the tabs into the new forms using drag and drop. Default value is true.")] + public bool TabDetachEnabled + { + get { return _TabDetachEnabled; } + set { _TabDetachEnabled = value; } + } + #endregion + + internal void InvokeMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + internal void InvokeMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + internal void InvokeMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + internal void InvokeClick(EventArgs e) + { + OnClick(e); + } + /// + /// Closes specified tab. + /// + /// Tab to close + /// Source of the event + public void CloseTab(TabFormItem tab, eEventSource source) + { + TabFormTabCloseEventArgs e = new TabFormTabCloseEventArgs(tab, source); + OnTabClosing(e); + if (e.Cancel) return; + + // Close the tab + this.Items.Remove(tab); + Control c = tab.Panel; + if (c != null) + { + if (c.Parent != null) + c.Parent.Controls.Remove(c); + c.Dispose(); + } + tab.Dispose(); + + OnTabClosed(e); + } + + protected override void OnItemRemoved(BaseItem item, ItemRemovedEventArgs e) + { + TabFormItem tab = item as TabFormItem; + if (tab != null && tab.Checked && this.Items.Count > 0) + { + bool selected = false; + int count = this.Items.Count; + int index = Math.Min(Math.Max(0, e.ItemIndex), count - 1); + for (int i = index; i < count; i++) + { + TabFormItem t1 = this.Items[i] as TabFormItem; + if (t1 != null && t1.Enabled && t1.Visible) + { + t1.Checked = true; + selected = true; + break; + } + } + if (!selected) + { + for (int i = index; i >= 0; i--) + { + TabFormItem t1 = this.Items[i] as TabFormItem; + if (t1 != null && t1.Enabled && t1.Visible) + { + t1.Checked = true; + selected = true; + break; + } + } + } + } + base.OnItemRemoved(item, e); + } + + protected override void OnItemAdded(BaseItem item, EventArgs e) + { + TabFormItem tab = item as TabFormItem; + if (tab != null && this.SelectedTab == null && tab.Visible && tab.Enabled) + tab.Checked = true; + + base.OnItemAdded(item, e); + } + + /// + /// Occurs before tab is closed and it allows canceling of the event. + /// + [Description("Occurs before tab is closed and it allows canceling of the event.")] + public event TabFormTabCloseEventHandler TabClosing; + + /// + /// Raises RemovingToken event. + /// + /// Provides event arguments. + protected virtual void OnTabClosing(TabFormTabCloseEventArgs e) + { + TabFormTabCloseEventHandler handler = TabClosing; + if (handler != null) + handler(this, e); + } + + /// + /// Occurs after tab is closed. + /// + [Description("Occurs after tab is closed.")] + public event TabFormTabCloseEventHandler TabClosed; + + /// + /// Raises RemovingToken event. + /// + /// Provides event arguments. + protected virtual void OnTabClosed(TabFormTabCloseEventArgs e) + { + TabFormTabCloseEventHandler handler = TabClosed; + if (handler != null) + handler(this, e); + } + + private Form _OutlineDragForm = null; + protected override void MouseDragOver(int x, int y, DragEventArgs dragArgs) + { + if (!DragInProgress && !ExternalDragInProgress) + return; + BaseItem dragItem = DragItem; + if (!(dragItem is TabFormItem) || UseNativeDragDrop || !_TabDetachEnabled) + { + base.MouseDragOver(x, y, dragArgs); + return; + } + + if (ExternalDragInProgress && dragArgs != null) + dragItem = dragArgs.Data.GetData(typeof(ButtonItem)) as BaseItem; + + if (DesignTimeProvider != null) + { + DesignTimeProvider.DrawReversibleMarker(InsertPosition, InsertBefore); + DesignTimeProvider = null; + } + + if (ExternalDragInProgress && dragItem == null) + return; + + Point pScreen = this.PointToScreen(new Point(x, y)); + BaseItem baseItemContainer = GetBaseItemContainer(); + InsertPosition pos = ((IDesignTimeProvider)baseItemContainer).GetInsertPosition(pScreen, dragItem); + + if (pos == null || pos.TargetProvider == null) + { + Rectangle rScreen = new Rectangle(this.PointToScreen(Point.Empty), this.Size); + if (!rScreen.Contains(pScreen)) + { + IntPtr windowAtHandle = NativeFunctions.WindowFromPoint(new NativeFunctions.POINT(pScreen)); + if (windowAtHandle != IntPtr.Zero) + { + //Control cat = Control.FromChildHandle(windowAtHandle); + //if(cat!=null) + // Console.WriteLine("{0} - {1}", cat.Name,cat); + TabFormStripControl stripAt = Control.FromChildHandle(windowAtHandle) as TabFormStripControl; + if (stripAt != null) + { + BaseItem cont = stripAt.GetBaseItemContainer(); + pos = ((IDesignTimeProvider)cont).GetInsertPosition(pScreen, dragItem); + } + } + } + } + + if (pos != null && pos.TargetProvider != null) + { + DisposeOutlineDragForm(); + pos.TargetProvider.DrawReversibleMarker(pos.Position, pos.Before); + InsertPosition = pos.Position; + InsertBefore = pos.Before; + DesignTimeProvider = pos.TargetProvider; + Cursor.Current = Cursors.Hand; + } + else + { + Cursor.Current = Cursors.Hand; + if (_OutlineDragForm == null) + { + _OutlineDragForm = BarFunctions.CreateTransparentOutlineForm(); + _OutlineDragForm.Name = "TabFormItemDragOutline"; + } + Rectangle r = new Rectangle(pScreen.X - 200 / 2, pScreen.Y - 22, 200, 150); + NativeFunctions.SetWindowPos(_OutlineDragForm.Handle, + new IntPtr(NativeFunctions.HWND_TOP), r.X, r.Y, r.Width, r.Height, NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); + } + OnMouseDragOverProcessed(x, y, dragArgs); + } + + protected override void MouseDragDrop(int x, int y, DragEventArgs dragArgs) + { + if (!DragInProgress && !ExternalDragInProgress) + return; + DisposeOutlineDragForm(); + TabFormControl currentTabControl = GetTabFormControl(); + if (x == -1 && y == -1 || !(DragItem is TabFormItem) || currentTabControl == null || !_TabDetachEnabled || DesignTimeProvider == _StripContainer.TabsContainer) + { + base.MouseDragDrop(x, y, dragArgs); + return; + } + + TabFormItem dragItem = (TabFormItem)DragItem; + if (ExternalDragInProgress) + dragItem = dragArgs.Data.GetData(typeof(ButtonItem)) as TabFormItem; + + if (dragItem != null) + dragItem.InternalMouseLeave(); + + if (DesignTimeProvider != null) + DesignTimeProvider.DrawReversibleMarker(InsertPosition, InsertBefore); + + if (DesignTimeProvider != null && DesignTimeProvider != _StripContainer.TabsContainer) + { + // Moving to different form or tab strip + int index = currentTabControl.Items.IndexOf(dragItem); + currentTabControl.Items.Remove(dragItem); + if (dragItem.Checked) + { + // Select some other tab + if (index < currentTabControl.Items.Count) + { + for (int i = index; i >=0; i--) + { + if (currentTabControl.Items[i] is TabFormItem && currentTabControl.Items[i].Enabled && + currentTabControl.Items[i].Visible) + ((TabFormItem) currentTabControl.Items[i]).Checked = true; + } + } + } + if (dragItem.Panel != null && dragItem.Panel.Parent != null) + dragItem.Panel.Parent.Controls.Remove(dragItem.Panel); + + Form formToClose = null; + if (currentTabControl.TabsCount == 0 && currentTabControl.IsAutoCreated) + formToClose = currentTabControl.FindForm(); + else + currentTabControl.RecalcLayout(); + + DesignTimeProvider.InsertItemAt(dragItem, InsertPosition, InsertBefore); + if (dragItem.Panel != null && DesignTimeProvider is BaseItem) + { + TabFormStripControl targetStrip = + ((BaseItem)DesignTimeProvider).ContainerControl as TabFormStripControl; + if (targetStrip != null && targetStrip.Parent is TabFormControl) + targetStrip.Parent.Controls.Add(dragItem.Panel); + } + OnItemDragAndDropped(dragItem); + ((IOwner)this).InvokeUserCustomize(dragItem, new EventArgs()); + + if (formToClose != null) + { + formToClose.Close(); + } + } + else + { + if (currentTabControl.TabsCount == 1) // There is nothing to detach here just moved the form... + { + Form form = currentTabControl.FindForm(); + if (form != null) + form.Location = new Point(Control.MousePosition.X - form.Width / 2, + Control.MousePosition.Y - Dpi.Height16); + } + else + { + TabFormItemDetachEventArgs detachArgs = new TabFormItemDetachEventArgs(dragItem); + OnBeforeTabFormItemDetach(detachArgs); + if (!detachArgs.Cancel) + { + TabParentForm form = null; + TabFormControl tabControl = null; + if (detachArgs.TabForm != null && detachArgs.TabControl != null) + { + form = detachArgs.TabForm; + tabControl = detachArgs.TabControl; + } + else + { + form = new TabParentForm(); + form.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + form.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + form.Text = dragItem.Text; + tabControl = new TabFormControl(); + tabControl.IsAutoCreated = true; + tabControl.Dock = DockStyle.Fill; + form.Controls.Add(tabControl); + } + + int index = currentTabControl.Items.IndexOf(dragItem); + currentTabControl.Items.Remove(dragItem); + if (dragItem.Checked) + { + // Select some other tab + if (index < currentTabControl.Items.Count) + { + for (int i = index; i >= 0; i--) + { + if (currentTabControl.Items[i] is TabFormItem && currentTabControl.Items[i].Enabled && + currentTabControl.Items[i].Visible) + ((TabFormItem)currentTabControl.Items[i]).Checked = true; + } + } + } + if (dragItem.Panel != null && dragItem.Panel.Parent != null) + dragItem.Panel.Parent.Controls.Remove(dragItem.Panel); + + // Its key to add panel to the new control first otherwise new form could not be moved + if (dragItem.Panel != null) + { + tabControl.Controls.Add(dragItem.Panel); + dragItem.Panel.SendToBack(); + } + tabControl.Items.Add(dragItem); + tabControl.SelectedTab = dragItem; + tabControl.RecalcLayout(); + form.StartPosition = FormStartPosition.Manual; + form.Location = new Point(Control.MousePosition.X - 800 / 2, + Control.MousePosition.Y - Dpi.Height16); + form.Size = new Size(800, 600); + + detachArgs.TabForm = form; + detachArgs.TabControl = tabControl; + OnTabFormItemDetach(detachArgs); + if (MultiFormAppContext.Current!=null) + MultiFormAppContext.Current.RegisterOpenForm(form); + form.Show(); + + ((IOwner)this).InvokeUserCustomize(dragItem, EventArgs.Empty); + } + } + } + + DesignTimeProvider = null; + DragInProgress = false; + ExternalDragInProgress = false; + Cursor.Current = Cursors.Default; + this.Capture = false; + if (dragItem != null) + { + dragItem._IgnoreClick = true; + dragItem.DragStartPoint = Point.Empty; + } + GetBaseItemContainer().InternalMouseUp(new MouseEventArgs(MouseButtons.Left, 0, x, y, 0)); + if (dragItem != null) + dragItem._IgnoreClick = false; + + DragItem = null; + + //OnUserCustomize(EventArgs.Empty); + } + + /// + /// Returns current number of tabs visile and hiden on the tab strip. + /// + [Browsable(false)] + public int TabsCount + { + get + { + int count = 0; + foreach (BaseItem item in Items) + { + if (item is TabFormItem) + count++; + } + return count; + } + } + + /// + /// Indicates whether new tab item which allows creation of new tab when clicked is visible. When visible you need to handle CreateNewTab event and create your new tab in event handler. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether new tab item which allows creation of new tab when clicked is visible. When visible you need to handle CreateNewTab event and create your new tab in event handler.")] + public bool NewTabItemVisible + { + get { return _StripContainer.NewTabItemVisible; } + set { _StripContainer.NewTabItemVisible = value; } + } + + /// + /// Occurs before TabFormItem is detached and gives you opportunity to cancel the action or provide your own new TabParentForm and TabFormControl. + /// + [Description("Occurs before TabFormItem is detached and gives you opportunity to cancel the action or provide your own new TabParentForm and TabFormControl.")] + public event TabFormItemDetachEventHandler BeforeTabFormItemDetach; + + /// + /// Raises BeforeTabFormItemDetach event. + /// + /// Provides event arguments. + protected virtual void OnBeforeTabFormItemDetach(TabFormItemDetachEventArgs e) + { + TabFormItemDetachEventHandler handler = BeforeTabFormItemDetach; + if (handler != null) + handler(this, e); + } + + /// + /// Occurs after TabFormItem has been detached and is added to the new form and tab control. + /// + [Description("Occurs after TabFormItem has been detached and is added to the new form and tab control.")] + public event TabFormItemDetachEventHandler TabFormItemDetach; + /// + /// Raises TabFormItemDetach event. + /// + /// Provides event arguments. + protected virtual void OnTabFormItemDetach(TabFormItemDetachEventArgs e) + { + TabFormItemDetachEventHandler handler = TabFormItemDetach; + if (handler != null) + handler(this, e); + } + + private void DisposeOutlineDragForm() + { + if (_OutlineDragForm != null) + { + _OutlineDragForm.Close(); + _OutlineDragForm.Dispose(); + _OutlineDragForm = null; + } + } + } + + /// + /// Defines delegate for the TabFormCloseTab event. + /// + public delegate void TabFormTabCloseEventHandler(object sender, TabFormTabCloseEventArgs e); + + /// + /// Defines delegate for the TabFormCloseTab event. + /// + public class TabFormTabCloseEventArgs : EventArgs + { + /// + /// Allows to cancel the closing of the tab. + /// + public bool Cancel = false; + /// + /// Reference to tab being closed. + /// + public readonly TabFormItem Tab; + /// + /// Source of the event. + /// + public readonly eEventSource Source; + + public TabFormTabCloseEventArgs(TabFormItem tab, eEventSource source) + { + Tab = tab; + Source = source; + } + } + + /// + /// Defines delegate for the TabFormItemDetach event. + /// + public delegate void TabFormItemDetachEventHandler(object sender, TabFormItemDetachEventArgs e); + + /// + /// Defines delegate for the TabFormItemDetach event. + /// + public class TabFormItemDetachEventArgs : EventArgs + { + /// + /// Gets or sets the reference to the form which will host newly detached TabFormItem and its panel, an instance of TabParentForm. You can provide your own instance of TabParentForm and TabControl to use instead of controls creating them. You must provide both TabParentForm and TabControl. Provide these in BeforeTabFormItemDetach event. + /// + public TabParentForm TabForm = null; + /// + /// Gets or sets the reference to TabFormControl which will receive TabFormItem being dragged. If you provide your own TabParentForm and TabControl you must provide both. Provide these in BeforeTabFormItemDetach event. + /// + public TabFormControl TabControl = null; + /// + /// Gets reference to the TabFormItem being detached. + /// + public readonly TabFormItem TabFormItem; + /// + /// Enables canceling of TabFormItem detachment from its parent. + /// + public bool Cancel = false; + public TabFormItemDetachEventArgs(TabFormItem tab) + { + this.TabFormItem = tab; + } + } + +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStripPainter.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStripPainter.cs new file mode 100644 index 00000000..1ca0c7c6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabFormStripPainter.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.Rendering +{ + internal abstract class TabFormStripPainter + { + public abstract void Paint(TabFormStripPainterArgs renderingInfo); + } + + public class TabFormStripPainterArgs : EventArgs + { + /// + /// Gets or sets Graphics object group is rendered on. + /// + public Graphics Graphics = null; + + /// + /// Gets or sets the reference to SwitchButtonItem being rendered. + /// + public TabFormStripControl TabFormStrip = null; + + /// + /// Gets or sets the ItemPaintArgs reference. + /// + internal ItemPaintArgs ItemPaintArgs; + + /// + /// Indicates whether to cancel system rendering of the item. + /// + public bool Cancel = false; + + public TabFormStripPainterArgs(TabFormStripControl tabFormStrip, Graphics graphics, ItemPaintArgs itemPaintArgs) + { + Graphics = graphics; + TabFormStrip = tabFormStrip; + ItemPaintArgs = itemPaintArgs; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabParentForm.cs b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabParentForm.cs new file mode 100644 index 00000000..8533b6e2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TabbedForm/TabParentForm.cs @@ -0,0 +1,1321 @@ +using DevComponents.DotNetBar.Metro; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.Metro.Rendering; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Controls +{ + public class TabParentForm : Form + { + #region System Menu Constants + private const string SysMenuRestore = "restore"; + private const string SysMenuMove = "move"; + private const string SysMenuSize = "size"; + private const string SysMenuMinimize = "minimize"; + private const string SysMenuMaximize = "maximize"; + private const string SysMenuClose = "close"; + private const string SysMenu = "sysMenu"; + #endregion + + #region Events + /// + /// Occurs before modal panel is shown and allows change of modal panel bounds. + /// + [Description("Occurs before modal panel is shown and allows change of modal panel bounds.")] + public event ModalPanelBoundsEventHandler PrepareModalPanelBounds; + /// + /// Raises PrepareModalPanelBounds event. + /// + /// Provides event arguments. + protected virtual void OnPrepareModalPanelBounds(ModalPanelBoundsEventArgs e) + { + ModalPanelBoundsEventHandler handler = PrepareModalPanelBounds; + if (handler != null) + handler(this, e); + } + #endregion + + #region Constructor + private System.Windows.Forms.Padding GlassDefaultPadding = new System.Windows.Forms.Padding(1, 1, 1, 1); //new System.Windows.Forms.Padding(0, 1, 1, 1); + private System.Windows.Forms.Padding PlainDefaultPadding = new System.Windows.Forms.Padding(1, 1, 1, 1); + + /// + /// Initializes a new instance of the MetroForm class. + /// + public TabParentForm() + { + StyleManager.Register(this); + _IsGlassEnabled = WinApi.IsGlassEnabled; + this.ControlBox = false; + if (_IsGlassEnabled) + this.Padding = GlassDefaultPadding; + else + this.Padding = PlainDefaultPadding; + //_BorderOverlay = new BorderOverlay(); + //this.Controls.Add(_BorderOverlay); + //UpdateBorderOverlay(); + } + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) StyleManager.Unregister(this); + base.Dispose(disposing); + } + + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + UpdateColorScheme(); + } + + private void UpdateColorScheme() + { + StyleManager.UpdateMetroAmbientColors(this); + } + protected override void OnShown(EventArgs e) + { + if (this.DesignMode) + UpdateColorScheme(); + else if (_PreRenderShell && _FormTabs != null) + { + using (Bitmap bmp = new Bitmap(16, 16)) + _FormTabs.DrawToBitmap(bmp, new Rectangle(0, 0, this.Width, this.Height)); + } + base.OnShown(e); + } + private bool _PreRenderShell = true; + /// + /// Gets or sets whether MetroShell is pre-rendered when form is shown to make first rendering smoother. Default value is true. + /// + [DefaultValue(true), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool PreRenderShell + { + get { return _PreRenderShell; } + set { _PreRenderShell = value; } + } + protected override void OnHandleCreated(EventArgs e) + { + UpdateColorScheme(); + base.OnHandleCreated(e); + } + #endregion + + #region Implementation + /// + /// Gets whether at least one modal panel is displayed. + /// + [Browsable(false)] + public bool IsModalPanelDisplayed + { + get + { + return _ModalPanels.Count > 0; + } + } + + private bool _ModalPanelBoundsExcludeStatusBar = false; + /// + /// Indicates whether modal panel when displayed shows MetroStatusBar. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether modal panel when displayed shows MetroStatusBar.")] + public bool ModalPanelBoundsExcludeStatusBar + { + get { return _ModalPanelBoundsExcludeStatusBar; } + set + { + _ModalPanelBoundsExcludeStatusBar = value; + } + } + + + /// + /// Shows the panel control in the center of the form and covers all non system controls making the panel effectively modal. + /// + /// Control to show. + public void ShowModalPanel(Control panel) + { + ShowModalPanel(panel, false, eSlideSide.Left, SlidePanel.DefaultAnimationTime); + } + /// + /// Shows the panel control in the center of the form by sliding it in from specified side and covers all non system controls making the panel effectively modal. + /// + /// Panel to show. + /// Side to slide panel into the view from. + public void ShowModalPanel(Control panel, eSlideSide slideFromSide) + { + ShowModalPanel(panel, true, slideFromSide, SlidePanel.DefaultAnimationTime); + } + /// + /// Shows the panel control in the center of the form by sliding it in from specified side and covers all non system controls making the panel effectively modal. + /// + /// Panel to show. + /// Side to slide panel into the view from. + /// Slide animation speed in milliseconds. + public void ShowModalPanel(Control panel, eSlideSide slideFromSide, int animationTimeMilliseconds) + { + ShowModalPanel(panel, true, slideFromSide, SlidePanel.DefaultAnimationTime); + } + private List _ModalPanels = new List(); + private List _DisabledItemIds = new List(); + private void ShowModalPanel(Control panel, bool slideIn, eSlideSide slideFromSide, int animationTimeMilliseconds) + { + StyleManager.UpdateAmbientColors(panel); + + SlidePanel slidePanel = new SlidePanel(); + slidePanel.CenterContent = true; + slidePanel.AnimationTime = animationTimeMilliseconds; + slidePanel.SlideSide = slideFromSide; + slidePanel.SlideOutButtonVisible = false; + + if (slideIn) + { + slidePanel.Bounds = GetModalPanelBounds(); + slidePanel.SlideOutOfViewSilent(this); + } + else + { + slidePanel.Bounds = GetModalPanelBounds(); + } + + slidePanel.Controls.Add(panel); + this.Controls.Add(slidePanel); + this.Controls.SetChildIndex(slidePanel, 0); + _ModalPanels.Add(slidePanel); + + if (_ModalPanels.Count == 1 && _FormTabs != null) + { + //_FormTabs.MetroTabStrip.Enabled = false; + _FormTabs.TabStrip.StripContainerItem.Enabled = false; + for (int i = 0; i < _FormTabs.TabStrip.CaptionContainerItem.SubItems.Count; i++) + { + BaseItem item = _FormTabs.TabStrip.CaptionContainerItem.SubItems[i]; + if (item.SystemItem && !(item is QatCustomizeItem)) continue; + item.Enabled = false; + _DisabledItemIds.Add(item.Id); + } + _FormTabs.TabStrip.Invalidate(); + } + + this.Update(); + if (slideIn) + slidePanel.IsOpen = true; + + } + /// + /// Hides the panel control that was previously shown using ShowModalPanel method. + /// + /// Control to hide. + public void CloseModalPanel(Control panel) + { + CloseModalPanel(panel, false, eSlideSide.Left); + } + /// + /// Hides the panel control that was previously shown using ShowModalPanel method by sliding it out of the view to the specified side. + /// + /// Control to hide. + /// Side to slide control into. + public void CloseModalPanel(Control panel, eSlideSide slideOutToSide) + { + CloseModalPanel(panel, true, slideOutToSide); + } + private void CloseModalPanel(Control panel, bool slideOut, eSlideSide slideOutToSide) + { + SlidePanel slidePanel = null; + foreach (Control modalPanel in _ModalPanels) + { + if (modalPanel.Contains(panel)) + { + slidePanel = (SlidePanel)modalPanel; + break; + } + } + if (slidePanel == null) throw new ArgumentException("panel was not shown previously using ShowModalPanel method"); + + if (slideOut) + { + slidePanel.SlideSide = slideOutToSide; + slidePanel.IsOpen = false; + DateTime start = DateTime.Now; + while (slidePanel.IsAnimating) + { + Application.DoEvents(); + if (DateTime.Now.Subtract(start).TotalMilliseconds > 950) + { + slidePanel.AbortAnimation(); + slidePanel.Visible = false; + break; + } + } + } + else + slidePanel.Visible = false; + slidePanel.Controls.Remove(panel); + if (slidePanel.Parent != null) + slidePanel.Parent.Controls.Remove(slidePanel); + if (_ModalPanels.Contains(slidePanel)) + _ModalPanels.Remove(slidePanel); + if(!slidePanel.IsDisposed) + slidePanel.Dispose(); + + if (_ModalPanels.Count == 0 && _FormTabs != null) + { + //_FormTabs.MetroTabStrip.Enabled = true; + _FormTabs.TabStrip.StripContainerItem.Enabled = true; + for (int i = 0; i < _FormTabs.TabStrip.CaptionContainerItem.SubItems.Count; i++) + { + BaseItem item = _FormTabs.TabStrip.CaptionContainerItem.SubItems[i]; + if (item.SystemItem) continue; + if(_DisabledItemIds.Contains(item.Id)) + item.Enabled = true; + } + + _FormTabs.TabStrip.Refresh(); + } + } + + internal NonClientInfo GetNonClientInfo() + { + WinApi.RECT rect = new WinApi.RECT(0, 0, 200, 200); + CreateParams params1 = this.CreateParams; + WinApi.AdjustWindowRectEx(ref rect, params1.Style, false, params1.ExStyle); + + NonClientInfo n = new NonClientInfo(); + n.CaptionTotalHeight = Math.Abs(rect.Top); + n.BottomBorder = rect.Height - 200 - n.CaptionTotalHeight; + n.LeftBorder = Math.Abs(rect.Left); + n.RightBorder = rect.Width - 200 - n.LeftBorder; + + return n; + } + + private void UpdateModalPanelsSize() + { + foreach (Control modalPanel in _ModalPanels) + { + modalPanel.Bounds = GetModalPanelBounds(); + if (this.WindowState == FormWindowState.Maximized) + { + NonClientInfo nci = GetNonClientInfo(); + modalPanel.Padding = new System.Windows.Forms.Padding(nci.LeftBorder + 1); + } + else + modalPanel.Padding = new System.Windows.Forms.Padding(); + } + } + private Rectangle GetModalPanelBounds() + { + Thickness borderThickness = GetBorderThickness(); + + int statusBarHeight = 0; + if (_ModalPanelBoundsExcludeStatusBar) + { + foreach (Control item in this.Controls) + { + if (item is MetroStatusBar && item.Dock == DockStyle.Bottom) + { + statusBarHeight = item.Height; + break; + } + } + } + + Rectangle bounds = Rectangle.Empty; + if (_FormTabs != null && _FormTabs.CaptionVisible) + { + int captionHeight = _FormTabs.TabStrip.GetCaptionHeight() + 2; + bounds = new Rectangle((int)borderThickness.Left, captionHeight, this.Width - (int)borderThickness.Horizontal, this.Height - captionHeight - (int)borderThickness.Bottom - statusBarHeight); + } + else + { + bounds = new Rectangle((int)borderThickness.Left, (int)borderThickness.Top, this.Width - (int)borderThickness.Horizontal, this.Height - (int)borderThickness.Vertical - statusBarHeight); + } + + ModalPanelBoundsEventArgs args = new ModalPanelBoundsEventArgs(bounds); + OnPrepareModalPanelBounds(args); + bounds = args.ModalPanelBounds; + + return bounds; + } + + private bool _IsGlassEnabled = false; + /// + /// Returns whether Windows Glass effects are enabled. + /// + [Browsable(false)] + public bool IsGlassEnabled + { + get + { + return _IsGlassEnabled; + } + } + private void UpdateIsGlassEnabled() + { + bool glassEnabled = WinApi.IsGlassEnabled; + if (glassEnabled != _IsGlassEnabled) + { + _IsGlassEnabled = glassEnabled; + OnGlassEnabledChanged(); + } + } + private void OnGlassEnabledChanged() + { + if (_IsGlassEnabled) + this.Padding = GlassDefaultPadding; + else + this.Padding = PlainDefaultPadding; + if (_IsGlassEnabled && this.Region != null) + this.Region = null; + else + this.Region = GetPlainFormRegion(); + this.Refresh(); + } + private Region GetPlainFormRegion() + { + Region reg = new Region(new Rectangle(0, 0, this.Width, this.Height)); + return reg; + } + + private TabFormControl _FormTabs = null; + /// + /// Gets or sets the TabFormControl that is hosted by this form. This property is for internal use only. + /// + [Browsable(false)] + public virtual TabFormControl FormTabsControl + { + get { return _FormTabs; } + internal set + { + _FormTabs = value; + } + } + + protected override void OnStyleChanged(EventArgs e) + { + UpdateSystemCaptionItem(); + base.OnStyleChanged(e); + } + + protected override void OnControlAdded(ControlEventArgs e) + { + if (e.Control is TabFormControl) + { + _FormTabs = e.Control as TabFormControl; + UpdateSystemCaptionItem(); + } + base.OnControlAdded(e); + } + + protected override void OnControlRemoved(ControlEventArgs e) + { + if (e.Control == _FormTabs) + { + _FormTabs = null; + } + base.OnControlRemoved(e); + } + + private bool _Sizable = true; + /// + /// Gets or sets whether form can be resized. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether form can be resized.")] + public bool Sizable + { + get { return _Sizable; } + set { _Sizable = value; } + } + + /// + /// Gets effective Border Thickness for the form. + /// + /// Thickness + public Thickness GetBorderThickness() + { + if (!_BorderThickness.IsZero) return _BorderThickness; + TabFormColorTable ct = GetFormColorTable(); + + return ct.BorderThickness; + } + + private TabFormColorTable GetFormColorTable() + { + if (_FormTabs != null && _FormTabs.ColorTable != null) + return _FormTabs.ColorTable; + Office2007ColorTable table = ((Office2007Renderer) GlobalManager.Renderer).ColorTable; + return table.TabForm; + } + + private Thickness _BorderThickness = new Thickness(); + /// + /// Gets or sets the form border thickness. Default value is empty thickness which indicates that thickness is taken from color table. + /// + [Category("Appearance"), Description("Indicates form border thickness.")] + public Thickness BorderThickness + { + get { return _BorderThickness; } + set + { + if (value != _BorderThickness) + { + Thickness oldValue = _BorderThickness; + _BorderThickness = value; + OnBorderThicknessChanged(oldValue, value); + } + } + } + /// + /// Called when BorderThickness property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnBorderThicknessChanged(Thickness oldValue, Thickness newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("BorderThickness")); + this.Invalidate(); + } + + private BorderColors _BorderColor; + /// + /// Gets or sets the form border colors. + /// + public BorderColors BorderColor + { + get { return _BorderColor; } + set + { + if (value != _BorderColor) + { + BorderColors oldValue = _BorderColor; + _BorderColor = value; + OnBorderColorChanged(oldValue, value); + } + } + } + /// + /// Called when BorderColor property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnBorderColorChanged(BorderColors oldValue, BorderColors newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("BorderColor")); + this.Invalidate(); + } + + protected override void OnPaint(PaintEventArgs e) + { + if (!_IsGlassEnabled && this.Region == null) + this.Region = GetPlainFormRegion(); + Office2007Renderer renderer = GetRenderer(); + Graphics g = e.Graphics; + renderer.DrawTabParentForm(new TabFormPainterArgs(this, g)); + base.OnPaint(e); + } + + private Office2007Renderer GetRenderer() + { + return ((Office2007Renderer) GlobalManager.Renderer); + } + + protected override void OnActivated(EventArgs e) + { + ExtendGlass(); + this.Invalidate(); + base.OnActivated(e); + } + + protected override void OnDeactivate(EventArgs e) + { + this.Invalidate(); + base.OnDeactivate(e); + } + + private void ExtendGlass() + { + if (!WinApi.IsGlassEnabled) return; + + WinApi.MARGINS m = new WinApi.MARGINS(); + m.cyTopHeight = 0; + m.cxLeftWidth = 0; + m.cxRightWidth = 0; + m.cyBottomHeight = NativeFunctions.IsTerminalSession() ? 0 : 1; + WinApi.DwmExtendFrameIntoClientArea(this.Handle, ref m); + } + + protected virtual bool WindowsMessageSetText(ref Message m) + { + if (WinApi.IsGlassEnabled) return true; + + bool modified = WinApi.ModifyHwndStyle(m.HWnd, (int)WinApi.WindowStyles.WS_VISIBLE, 0); + + base.DefWndProc(ref m); + + if (_FormTabs != null) _FormTabs.Refresh(); + if (modified) + { + WinApi.ModifyHwndStyle(m.HWnd, 0, (int)WinApi.WindowStyles.WS_VISIBLE); + } + return false; + } + protected virtual bool WindowsMessageWindowsPosChanged(ref Message m) + { + if (this.WindowState == FormWindowState.Minimized || this.WindowState == FormWindowState.Maximized) + { + _TrackSetBoundsCore = true; + base.WndProc(ref m); + _TrackSetBoundsCore = true; + return false; + } + return true; + } + protected override void WndProc(ref Message m) + { + bool callBase = true; + if (!PreProcessWndProc(ref m)) + return; + + if (m.Msg == (int)WinApi.WindowsMessages.WM_NCCALCSIZE) + { + callBase = WindowsMessageNCCalcSize(ref m); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_NCACTIVATE) + { + callBase = WindowsMessageNCActivate(ref m); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_DWMCOMPOSITIONCHANGED) + { + callBase = WindowsMessageDwmCompositionChanged(ref m); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_NCHITTEST) + { + callBase = WindowsMessageNCHitTest(ref m); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_SETTEXT) + { + callBase = WindowsMessageSetText(ref m); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_NCPAINT) + { + callBase = WindowsMessageNCPaint(ref m); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_ERASEBKGND) + { + if (!WinApi.IsGlassEnabled) + { + callBase = false; + m.Result = new IntPtr(1); + } + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_SETICON) + { + callBase = WindowsMessageSetIcon(ref m); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_SETTEXT) + { + callBase = WindowsMessageSetText(ref m); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_SETCURSOR) + { + callBase = WindowsMessageSetCursor(ref m); + } + else if (m.Msg == (int)WinApi.WindowsMessages.WM_WINDOWPOSCHANGED) + { + callBase = WindowsMessageWindowsPosChanged(ref m); + } + + if (callBase) + base.WndProc(ref m); + } + protected virtual bool WindowsMessageSetCursor(ref Message m) + { + // Button down on client area while there is a modal form displayed + if (!_IsActive && (WinApi.HIWORD(m.LParam) == (int)WinApi.WindowsMessages.WM_LBUTTONUP || WinApi.HIWORD(m.LParam) == (int)WinApi.WindowsMessages.WM_LBUTTONDOWN) && WinApi.LOWORD(m.LParam) == (int)WinApi.WindowHitTestRegions.Error || + !this.Enabled || BarUtilities.IsModalFormOpen) + return true; + + bool modified = WinApi.ModifyHwndStyle(m.HWnd, (int)WinApi.WindowStyles.WS_VISIBLE, 0); + + base.DefWndProc(ref m); + + if (_FormTabs != null && this.DesignMode) _FormTabs.Refresh(); + if (modified) + { + WinApi.ModifyHwndStyle(m.HWnd, 0, (int)WinApi.WindowStyles.WS_VISIBLE); + } + + return false; + } + protected virtual bool WindowsMessageSetIcon(ref Message m) + { + bool modified = WinApi.ModifyHwndStyle(m.HWnd, (int)WinApi.WindowStyles.WS_VISIBLE, 0); + + base.DefWndProc(ref m); + + if (_FormTabs != null) _FormTabs.Refresh(); + if (modified) + { + WinApi.ModifyHwndStyle(m.HWnd, 0, (int)WinApi.WindowStyles.WS_VISIBLE); + } + + return false; + } + + protected virtual bool WindowsMessageNCPaint(ref Message m) + { + if (WinApi.IsGlassEnabled) + { + return true; + } + else + { + m.Result = IntPtr.Zero; + return false; + } + } + + /// + /// Called when WM_NCHITTEST message is received. + /// + /// Reference to message data. + /// Return true to call base form implementation otherwise return false. + protected virtual bool WindowsMessageNCHitTest(ref Message m) + { + // Get position being tested... + int x = WinApi.LOWORD(m.LParam); + int y = WinApi.HIWORD(m.LParam); + Point p = PointToClient(new Point(x, y)); + + Thickness borderResize = FormResizeBorder; + if (this.Sizable && !borderResize.IsZero && this.WindowState == FormWindowState.Normal) + { + Rectangle hitTest = new Rectangle(0, 0, (int)borderResize.Left, (int)borderResize.Top); hitTest.Inflate(1, 1); + if (hitTest.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TopLeftSizeableCorner); + return false; + } + hitTest = new Rectangle(this.Width - (int)borderResize.Right, 0, (int)borderResize.Right, (int)borderResize.Top); hitTest.Inflate(1, 1); + if (hitTest.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TopRightSizeableCorner); + return false; + } + hitTest = new Rectangle(this.Width - (int)borderResize.Right, this.Height - (int)borderResize.Bottom, (int)borderResize.Right, (int)borderResize.Bottom); hitTest.Inflate(2, 2); + if (hitTest.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.BottomRightSizeableCorner); + return false; + } + hitTest = new Rectangle(0, this.Height - (int)borderResize.Bottom, (int)borderResize.Left, (int)borderResize.Bottom); hitTest.Inflate(1, 1); + if (hitTest.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.BottomLeftSizeableCorner); + return false; + } + + hitTest = new Rectangle(0, 0, (int)borderResize.Left, this.Height); + if (hitTest.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.LeftSizeableBorder); + return false; + } + hitTest = new Rectangle(0, 0, this.Width, (int)borderResize.Top); + if (hitTest.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TopSizeableBorder); + return false; + } + hitTest = new Rectangle(this.Width - (int)borderResize.Right, 0, (int)borderResize.Right, this.Height); + if (hitTest.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.RightSizeableBorder); + return false; + } + + hitTest = new Rectangle(0, this.Height - (int)borderResize.Bottom, this.Width, (int)borderResize.Bottom); + if (hitTest.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.BottomSizeableBorder); + return false; + } + } + + TabFormControl tab = _FormTabs; + //if (tab != null) + //{ + // Rectangle r = new Rectangle((RightToLeft == RightToLeft.No ? (int)borderResize.Left : this.Width - (int)borderResize.Right - 24), (int)borderResize.Left, 24, 24); + // if (r.Contains(p)) + // { + // m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.Menu); + // return false; + // } + //} + + if (/*BarFunctions.IsWindows7 && this.WindowState == FormWindowState.Maximized &&*/ tab != null) + { + p = tab.TabStrip.PointToClient(new Point(x, y)); + if (tab.TabStrip.CaptionBounds.Contains(p) || tab.TabStrip.HitTest(p.X, p.Y) == null) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.TitleBar); + return false; + } + } + + + return true; + } + + /// + /// Called when WM_DWMCOMPOSITIONCHANGED message is received. + /// + /// Reference to message data. + /// Return true to call base form implementation otherwise return false. + protected virtual bool WindowsMessageDwmCompositionChanged(ref Message m) + { + UpdateIsGlassEnabled(); + ExtendGlass(); + return true; + } + + private bool _IsActive = false; + /// + /// Gets whether form is active. + /// + [Browsable(false)] + public bool IsActive + { + get { return _IsActive; } + internal set + { + if (_IsActive != value) + { + _IsActive = value; + OnIsActiveChanged(); + } + } + } + private void OnIsActiveChanged() + { + if (_FormTabs != null) + _FormTabs.TabStrip.Invalidate(_FormTabs.TabStrip.CaptionBounds); + } + + /// + /// Called when WM_NCACTIVATE message is received. + /// + /// Reference to message data. + /// Return true to call base form implementation otherwise return false. + protected virtual bool WindowsMessageNCActivate(ref Message m) + { + if (m.WParam != IntPtr.Zero) + IsActive = true; + else + IsActive = false; + + m.Result = WinApi.DefWindowProc(m.HWnd, WinApi.WindowsMessages.WM_NCACTIVATE, m.WParam, new IntPtr(-1)); + if (this.DesignMode) + RefreshAll(); + + return false; + } + private void RefreshAll() + { + if (this.IsHandleCreated) + { + this.Invalidate(true); + this.Refresh(); + } + } + + protected override void OnTextChanged(EventArgs e) + { + if (this.DesignMode) + { + if (_FormTabs != null) _FormTabs.Refresh(); + } + base.OnTextChanged(e); + } + + private bool _Minimized = false; + private bool _Maximized = false; + private bool _ChangingSize = false; + protected override void OnResize(EventArgs e) + { + if (!_IsGlassEnabled) + { + this.Region = GetPlainFormRegion(); + this.Invalidate(); + } + + UpdateModalPanelsSize(); + + base.OnResize(e); + } + + private bool _TrackSetBoundsCore = false; + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + if (_TrackSetBoundsCore || + this.DesignMode && ((specified & BoundsSpecified.Height) == BoundsSpecified.Height || (specified & BoundsSpecified.Width) == BoundsSpecified.Width)) + { + if (width != this.Width || height != this.Height) + { + AdjustBounds(ref width, ref height, specified); + } + _TrackSetBoundsCore = false; + } + //else if ((specified & BoundsSpecified.Width) == BoundsSpecified.None) + //{ + // specified |= BoundsSpecified.Width; + // AdjustBounds(ref width, ref height, specified); + //} + + base.SetBoundsCore(x, y, width, height, specified); + } + + protected virtual void AdjustBounds(ref int width, ref int height) + { + AdjustBounds(ref width, ref height, BoundsSpecified.Width | BoundsSpecified.Height); + } + protected virtual void AdjustBounds(ref int width, ref int height, BoundsSpecified specified) + { + WinApi.RECT rect = new WinApi.RECT(0, 0, width, height); + CreateParams params1 = this.CreateParams; + WinApi.AdjustWindowRectEx(ref rect, params1.Style, false, params1.ExStyle); + + if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height) + { + height -= (rect.Height - height); + //if (IsGlassEnabled) + //{ + // if (this.FormBorderStyle == FormBorderStyle.FixedDialog) + // height += SystemInformation.FixedFrameBorderSize.Height; + // else if (this.FormBorderStyle == FormBorderStyle.Fixed3D) + // height += SystemInformation.FixedFrameBorderSize.Height; + // else if (this.FormBorderStyle == FormBorderStyle.FixedSingle) + // height += 1; + // else if (this.FormBorderStyle == FormBorderStyle.FixedToolWindow) + // height += SystemInformation.FixedFrameBorderSize.Height; + // else + // height += SystemInformation.FrameBorderSize.Height /* * NativeFunctions.BorderMultiplierFactor*/; + //} + } + + if ((specified & BoundsSpecified.Width) == BoundsSpecified.Width) + { + width -= (rect.Width - width); + } + } + protected override void SetClientSizeCore(int x, int y) + { + if (!this.DesignMode) + { + this.Size = new Size(x, y); + + Type type = typeof(Control); + try // try with ignore catch is bad idea but in this case its for future proofing, just in case M$ removes these members + { + type.InvokeMember("clientWidth", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField, null, this, new object[] { x }); + type.InvokeMember("clientHeight", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField, null, this, new object[] { y }); + } + catch { } + OnClientSizeChanged(EventArgs.Empty); + return; + } + base.SetClientSizeCore(x, y); + } + private FormWindowState GetWindowState() + { + WinApi.WINDOWPLACEMENT wp = new WinApi.WINDOWPLACEMENT(); + if (WinApi.GetWindowPlacement(this.Handle, out wp)) + { + if (wp.showCmd == (int)WinApi.ShowWindowCommands.Maximize) + return FormWindowState.Maximized; + else if (wp.showCmd == (int)WinApi.ShowWindowCommands.Minimize) + return FormWindowState.Minimized; + else if (wp.showCmd == (int)WinApi.ShowWindowCommands.Normal) + return FormWindowState.Normal; + } + + return this.WindowState; + } + /// + /// Called when WM_NCCALCSIZE message is received. + /// + /// Message structure. + /// true to call base WndProc otherwise false. + protected virtual bool WindowsMessageNCCalcSize(ref Message m) + { + // Default implementation of ribbon form does not have non-client area at all... + if (m.WParam != IntPtr.Zero && GetWindowState() == FormWindowState.Maximized) + { + WinApi.NCCALCSIZE_PARAMS csp; + csp = (WinApi.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(WinApi.NCCALCSIZE_PARAMS)); + NonClientInfo nci = GetNonClientInfo(); + Size reduction = new Size(nci.LeftBorder, nci.BottomBorder); //SystemInformation.FrameBorderSize; + Size frameBorderSize = reduction; + if (reduction.Width > 2) + reduction.Width -= reduction.Width - 2; + if (reduction.Height > 2) + reduction.Height -= reduction.Height - 2; + + WinApi.WINDOWPOS pos = (WinApi.WINDOWPOS)Marshal.PtrToStructure(csp.lppos, typeof(WinApi.WINDOWPOS)); + //Console.WriteLine(pos); + WinApi.RECT newClientRect = WinApi.RECT.FromRectangle(new Rectangle(pos.x + frameBorderSize.Width - 1, pos.y + reduction.Height, + pos.cx - frameBorderSize.Width * 2 + 3, pos.cy - frameBorderSize.Height - 1)); + if (_AutoHideTaskBarReduction > 0) + { + Taskbar taskBar = new Taskbar(); + if (taskBar.AutoHide) + { + if (taskBar.Position == TaskbarPosition.Bottom) + newClientRect.Bottom -= _AutoHideTaskBarReduction; + else if (taskBar.Position == TaskbarPosition.Top) + { + newClientRect.Bottom -= _AutoHideTaskBarReduction; + newClientRect.Top += _AutoHideTaskBarReduction; + } + else if (taskBar.Position == TaskbarPosition.Left) + { + newClientRect.Right -= _AutoHideTaskBarReduction; + newClientRect.Left += _AutoHideTaskBarReduction; + } + else if (taskBar.Position == TaskbarPosition.Right) + newClientRect.Right -= _AutoHideTaskBarReduction; + } + } + + csp.rgrc0 = newClientRect; + csp.rgrc1 = newClientRect; + Marshal.StructureToPtr(csp, m.LParam, false); + m.Result = new IntPtr((int)WinApi.WindowsMessages.WVR_VALIDRECTS); + this.Invalidate(); + return false; + } + + m.Result = IntPtr.Zero; + this.Invalidate(); + return false; + } + private int _AutoHideTaskBarReduction = 4; + /// + /// Indicates the number of pixels subtracted from form's height or width (depending on taskbar position) when form is maximized and taskbar is in auto-hide state. Default value is 4. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int AutoHideTaskBarReduction + { + get { return _AutoHideTaskBarReduction; } + set { _AutoHideTaskBarReduction = value; } + } + private bool PreProcessWndProc(ref Message m) + { + return true; + } + + /// + /// This property is not to be used with MetroForm. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public new FormBorderStyle FormBorderStyle + { + get { return base.FormBorderStyle; } + set { base.FormBorderStyle = value; } + } + + private Thickness _FormResizeBorder = new Thickness(5); + /// + /// Gets or sets the size of the border on the edges of the form that when mouse is over allow for form resizing. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Thickness FormResizeBorder + { + get { return _FormResizeBorder; } + set { _FormResizeBorder = value; } + } + + private void UpdateSystemCaptionItem() + { + SystemCaptionItem captionItem = GetSystemCaptionItem(); + if (captionItem != null) + { + captionItem.MinimizeVisible = this.MinimizeBox; + captionItem.RestoreMaximizeVisible = this.MaximizeBox; + captionItem.CloseVisible = this.CloseBoxVisible; + captionItem.HelpVisible = this.HelpButton; + if (!this.MaximizeBox && !this.MinimizeBox && !this.CloseBoxVisible) + captionItem.Visible = false; + else + captionItem.Visible = true; + if (_FormTabs != null) + _FormTabs.RecalcLayout(); + } + } + private SystemCaptionItem GetSystemCaptionItem() + { + if (_FormTabs != null) + { + return _FormTabs.TabStrip.SystemCaptionItem; + } + return null; + } + + private bool _CloseBoxVisible = true; + /// + /// Indicates whether Close button in top-right corner of the form is visible. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether Close button in top-right corner of the form is visible.")] + public bool CloseBoxVisible + { + get { return _CloseBoxVisible; } + set { _CloseBoxVisible = value; UpdateSystemCaptionItem(); } + } + + /// + /// This property cannot be used on MetroAppForm + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool AutoScroll + { + get + { + return base.AutoScroll; + } + set + { + if (value) value = false; + base.AutoScroll = value; + } + } + /// + /// This property cannot be used on MetroAppForm + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Point AutoScrollOffset + { + get + { + return base.AutoScrollOffset; + } + set + { + base.AutoScrollOffset = value; + } + } + /// + /// This property cannot be used on MetroAppForm + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMargin + { + get + { + return base.AutoScrollMargin; + } + set + { + base.AutoScrollMargin = value; + } + } + /// + /// This property cannot be used on MetroAppForm + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMinSize + { + get + { + return base.AutoScrollMinSize; + } + set + { + base.AutoScrollMinSize = value; + } + } + + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + Dpi.SetScaling(factor); + base.ScaleControl(factor, specified); + } + + + #endregion + + #region System Menu Handling + private ContextMenuBar _ContextMenuBar = null; + internal void ShowSystemWindowMenu(Point p) + { + if (this.DesignMode) return; + CreateContextMenuBar(); + + // Update items enabled state + ButtonItem sysMenu = ((ButtonItem)_ContextMenuBar.Items[SysMenu]); + sysMenu.SubItems[SysMenuRestore].Enabled = this.WindowState != FormWindowState.Normal; + sysMenu.SubItems[SysMenuMove].Enabled = this.WindowState == FormWindowState.Normal; + sysMenu.SubItems[SysMenuSize].Enabled = this.WindowState == FormWindowState.Normal && this.Sizable; + sysMenu.SubItems[SysMenuMinimize].Enabled = this.WindowState != FormWindowState.Minimized && this.MinimizeBox; ; + sysMenu.SubItems[SysMenuMaximize].Enabled = this.WindowState != FormWindowState.Maximized && this.Sizable && this.MaximizeBox; ; + sysMenu.SubItems[SysMenuClose].Enabled = true; + + sysMenu.Popup(p); + } + internal void ShowSystemWindowMenu() + { + ShowSystemWindowMenu(Control.MousePosition); + } + + private string GetLocalizedString(string key) + { + string text = ""; + if (key == LocalizationKeys.FormSystemMenuRestore) + text = _SystemMenuRestore; + else if (key == LocalizationKeys.FormSystemMenuMove) + text = _SystemMenuMove; + else if (key == LocalizationKeys.FormSystemMenuSize) + text = _SystemMenuSize; + else if (key == LocalizationKeys.FormSystemMenuMinimize) + text = _SystemMenuMinimize; + else if (key == LocalizationKeys.FormSystemMenuMaximize) + text = _SystemMenuMaximize; + else if (key == LocalizationKeys.FormSystemMenuClose) + text = _SystemMenuClose; + + return LocalizationManager.GetLocalizedString(key, text); + } + private void CreateContextMenuBar() + { + if (_ContextMenuBar != null || this.DesignMode) return; + _ContextMenuBar = new ContextMenuBar(); + _ContextMenuBar.Style = eDotNetBarStyle.StyleManagerControlled; + this.Controls.Add(_ContextMenuBar); + + ButtonItem sysMenu = new ButtonItem(SysMenu); + _ContextMenuBar.Items.Add(sysMenu); + ButtonItem sysItem = new ButtonItem(SysMenuRestore, GetLocalizedString(LocalizationKeys.FormSystemMenuRestore)); + sysItem.Image = BarFunctions.LoadBitmap("SystemImages.WinRestore.png"); + sysItem.Click += new EventHandler(SysItemClick); + sysMenu.SubItems.Add(sysItem); + sysItem = new ButtonItem(SysMenuMove, GetLocalizedString(LocalizationKeys.FormSystemMenuMove)); + sysItem.Click += new EventHandler(SysItemClick); + sysMenu.SubItems.Add(sysItem); + sysItem = new ButtonItem(SysMenuSize, GetLocalizedString(LocalizationKeys.FormSystemMenuSize)); + sysItem.Click += new EventHandler(SysItemClick); + sysMenu.SubItems.Add(sysItem); + sysItem = new ButtonItem(SysMenuMinimize, GetLocalizedString(LocalizationKeys.FormSystemMenuMinimize)); + sysItem.Click += new EventHandler(SysItemClick); + sysItem.Image = BarFunctions.LoadBitmap("SystemImages.WinMin.png"); + sysMenu.SubItems.Add(sysItem); + sysItem = new ButtonItem(SysMenuMaximize, GetLocalizedString(LocalizationKeys.FormSystemMenuMaximize)); + sysItem.Click += new EventHandler(SysItemClick); + sysItem.Image = BarFunctions.LoadBitmap("SystemImages.WinMax.png"); + sysMenu.SubItems.Add(sysItem); + sysItem = new ButtonItem(SysMenuClose, GetLocalizedString(LocalizationKeys.FormSystemMenuClose)); + sysItem.Click += new EventHandler(SysItemClick); + sysItem.Image = BarFunctions.LoadBitmap("SystemImages.WinClose.png"); + sysItem.BeginGroup = true; + sysItem.FontBold = true; + sysItem.HotFontBold = true; + sysItem.Shortcuts.Add(eShortcut.CtrlF4); + sysMenu.SubItems.Add(sysItem); + } + + void SysItemClick(object sender, EventArgs e) + { + BaseItem item = sender as BaseItem; + if (item == null) return; + if (item.Name == SysMenuRestore) + NativeFunctions.PostMessage(this.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_RESTORE, 0); + else if (item.Name == SysMenuMove) + NativeFunctions.PostMessage(this.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_MOVE, 0); + else if (item.Name == SysMenuSize) + NativeFunctions.PostMessage(this.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_SIZE, 0); + else if (item.Name == SysMenuMinimize) + NativeFunctions.PostMessage(this.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_MINIMIZE, 0); + else if (item.Name == SysMenuMaximize) + NativeFunctions.PostMessage(this.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_MAXIMIZE, 0); + else if (item.Name == SysMenuClose) + NativeFunctions.PostMessage(this.Handle, NativeFunctions.WM_SYSCOMMAND, NativeFunctions.SC_CLOSE, 0); + + } + + private string _SystemMenuRestore = "Restore"; + /// + /// Gets or sets text for form system menu Restore item. + /// + [DefaultValue("Restore"), Description("Indicates text for form system menu Restore item."), Localizable(true), Category("System Menu")] + public string SystemMenuRestore + { + get { return _SystemMenuRestore; } + set { _SystemMenuRestore = value; } + } + private string _SystemMenuMove = "Move"; + /// + /// Gets or sets text for form system menu Move item. + /// + [DefaultValue("Move"), Description("Indicates text for form system menu Move item."), Localizable(true), Category("System Menu")] + public string SystemMenuMove + { + get { return _SystemMenuMove; } + set { _SystemMenuMove = value; } + } + private string _SystemMenuSize = "Size"; + /// + /// Gets or sets text for form system menu Size item. + /// + [DefaultValue("Size"), Description("Indicates text for form system menu Size item."), Localizable(true), Category("System Menu")] + public string SystemMenuSize + { + get { return _SystemMenuSize; } + set { _SystemMenuSize = value; } + } + private string _SystemMenuMinimize = "Minimize"; + /// + /// Gets or sets text for form system menu Minimize item. + /// + [DefaultValue("Minimize"), Description("Indicates text for form system menu Minimize item."), Localizable(true), Category("System Menu")] + public string SystemMenuMinimize + { + get { return _SystemMenuMinimize; } + set { _SystemMenuMinimize = value; } + } + private string _SystemMenuMaximize = "Maximize"; + /// + /// Gets or sets text for form system menu Maximize item. + /// + [DefaultValue("Maximize"), Description("Indicates text for form system menu Maximize item."), Localizable(true), Category("System Menu")] + public string SystemMenuMaximize + { + get { return _SystemMenuMaximize; } + set { _SystemMenuMaximize = value; } + } + private string _SystemMenuClose = "Close"; + /// + /// Gets or sets text for form system menu Close item. + /// + [DefaultValue("Close"), Description("Indicates text for form system menu Close item."), Localizable(true), Category("System Menu")] + public string SystemMenuClose + { + get { return _SystemMenuClose; } + set { _SystemMenuClose = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TextBoxDropDown.cs b/PROMS/DotNetBar Source Code/Controls/TextBoxDropDown.cs new file mode 100644 index 00000000..dee29461 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TextBoxDropDown.cs @@ -0,0 +1,1812 @@ +#if FRAMEWORK20 +using System; +using System.Text; +using System.ComponentModel; +using System.Drawing; +using DevComponents.Editors; +using System.Windows.Forms; +using System.Drawing.Drawing2D; +using System.Collections; +using System.Drawing.Design; +using System.Security.Permissions; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents single line text box control with the drop down button to display custom control on popup and additional custom buttons. + /// + [ToolboxBitmap(typeof(TextBoxDropDown), "Controls.TextBoxDropDown.ico"), ToolboxItem(true), DefaultProperty("Text"), DefaultBindingProperty("Text"), DefaultEvent("TextChanged"), Designer("DevComponents.DotNetBar.Design.TextBoxDropDownDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class TextBoxDropDown : PopupItemControl, IInputButtonControl, ICommandSource + { + #region Private Variables + private TextBoxX _TextBox = null; + private ButtonItem _PopupItem = null; + private static string _DropDownItemContainerName = "sysPopupItemContainer"; + private static string _DropDownControlContainerName = "sysPopupControlContainer"; + private Color _FocusHighlightColor = ColorScheme.GetColor(0xFFFF88); + private bool _FocusHighlightEnabled = false; + #endregion + + #region Events + /// + /// Occurs when Clear button is clicked and allows you to cancel the default action performed by the button. + /// + public event CancelEventHandler ButtonClearClick; + /// + /// Occurs when Drop-Down button that shows popup is clicked and allows you to cancel showing of the popup. + /// + public event CancelEventHandler ButtonDropDownClick; + /// + /// Occurs when ButtonCustom control is clicked. + /// + public event EventHandler ButtonCustomClick; + /// + /// Occurs when ButtonCustom2 control is clicked. + /// + public event EventHandler ButtonCustom2Click; + /// + /// Occurs when the text alignment is changed. + /// + [Description("Occurs when the text alignment is changed.")] + public event EventHandler TextAlignChanged; + /// + /// Occurs when the value of the Modified property has changed. + /// + public event EventHandler ModifiedChanged; + + /// + /// Occurs before the popup is opened and it allows canceling of popup by setting CancelEventArgs.Cancel=true. + /// + [Description("Occurs before the popup is opened and it allows canceling of popup by setting CancelEventArgs.Cancel=true.")] + public event CancelEventHandler BeforePopupOpen; + /// + /// Raises BeforeMultiColumnPopupOpen event. + /// + /// Provides event arguments. + protected virtual void OnBeforePopupOpen(CancelEventArgs e) + { + CancelEventHandler handler = BeforePopupOpen; + if (handler != null) + handler(this, e); + } + #endregion + + #region Constructor + /// + /// Initializes a new instance of the TextBoxDropDown class. + /// + public TextBoxDropDown() + { + this.SetStyle(ControlStyles.Selectable, false); + _TextBox = new TextBoxX(); + base.BackColor = SystemColors.Window; + InitControl(); + } + private void InitControl() + { + _BackgroundStyle.SetColorScheme(this.ColorScheme); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + + _ButtonCustom = new InputButtonSettings(this); + _ButtonCustom2 = new InputButtonSettings(this); + _ButtonClear = new InputButtonSettings(this); + _ButtonDropDown = new InputButtonSettings(this); + CreateButtonGroup(); + + _TextBox.BorderStyle = BorderStyle.None; + _TextBox.TextChanged += new EventHandler(TextBoxTextChanged); + _TextBox.TextAlignChanged += new EventHandler(TextBoxTextAlignChanged); + _TextBox.SizeChanged += new EventHandler(TextBoxSizeChanged); + _TextBox.ModifiedChanged += new EventHandler(TextBoxModifiedChanged); + _TextBox.KeyPress += new KeyPressEventHandler(TextBoxKeyPress); + _TextBox.KeyDown += new KeyEventHandler(TextBoxKeyDown); + this.Controls.Add(_TextBox); + } + #endregion + + #region Internal Implementation + private bool _AutoSelectAll = false; + /// + /// Indicates whether all text is auto-selected when control gets input focus. Default value is false. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether all text is auto-selected when control gets input focus.")] + public bool AutoSelectAll + { + get { return _AutoSelectAll; } + set { _AutoSelectAll = value; } + } + + protected override void OnBindingContextChanged(EventArgs e) + { + if (_DropDownControl != null) _DropDownControl.BindingContext = this.BindingContext; + base.OnBindingContextChanged(e); + } + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (keyData == Keys.F4) + { + if (_PopupItem.Expanded) + CloseDropDown(); + else + InvokeShowDropDown(); + return true; + } + else if (keyData == Keys.Escape && this.IsPopupOpen) + { + CloseDropDown(); + return true; + } + else if (_ButtonGroup.ProcessCmdKey(ref msg, keyData)) + return true; + return base.ProcessCmdKey(ref msg, keyData); + } + + void TextBoxKeyPress(object sender, KeyPressEventArgs e) + { + if (_InternalReadOnly) e.Handled = true; + } + void TextBoxKeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Down && e.Modifiers == Keys.Alt) + { + if (ButtonDropDown.Visible) + { + InvokeShowDropDown(); + e.Handled = true; + } + } + } + + private void TextBoxModifiedChanged(object sender, EventArgs e) + { + OnModifiedChanged(e); + } + protected virtual void OnModifiedChanged(EventArgs e) + { + EventHandler handler = ModifiedChanged; + if (handler != null) + { + handler(this, e); + } + } + + private void TextBoxSizeChanged(object sender, EventArgs e) + { + if (!_InternalSizeUpdate) + UpdateLayout(); + } + + private void TextBoxTextChanged(object sender, EventArgs e) + { + base.Text = _TextBox.Text; + ExecuteCommand(); + } + + private void TextBoxTextAlignChanged(object sender, EventArgs e) + { + OnTextAlignChanged(e); + } + /// + /// Raises the TextAlignChanged event. + /// + protected virtual void OnTextAlignChanged(EventArgs e) + { + EventHandler eh = TextAlignChanged; + if (eh != null) + eh(this, e); + } + + protected override void OnEnabledChanged(EventArgs e) + { + if (!this.Enabled) + _TextBox.ResetBackColor(); + else if (_TextBox.BackColor != this.BackColor) + _TextBox.BackColor = this.BackColor; + + base.OnEnabledChanged(e); + } + + private Color _OldBackColor = Color.Empty; + protected override void OnEnter(EventArgs e) + { + if (_FocusHighlightEnabled) + { + _OldBackColor = this.BackColor; + this.BackColor = _FocusHighlightColor; + } + if (_AutoSelectAll) + _TextBox.SelectAll(); + base.OnEnter(e); + } + + protected override void OnLeave(EventArgs e) + { + if (_FocusHighlightEnabled && !_OldBackColor.IsEmpty) + { + this.BackColor = _OldBackColor; + if (_OldBackColor == SystemColors.Window) + _TextBox.ResetBackColor(); + _OldBackColor = Color.Empty; + } + base.OnLeave(e); + } + + protected override bool QueryPopupCloseMouseDown() + { + Point p = this.PointToClient(MousePosition); + if(this.ClientRectangle.Contains(p)) + return false; + return base.QueryPopupCloseMouseDown(); + } + /// + /// Gets or sets whether FocusHighlightColor is used as background color to highlight text box when it has input focus. Default value is false. + /// + [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Indicates whether FocusHighlightColor is used as background color to highlight text box when it has input focus.")] + public bool FocusHighlightEnabled + { + get { return _FocusHighlightEnabled; } + set + { + if (_FocusHighlightEnabled != value) + { + _FocusHighlightEnabled = value; + //_TextBox.FocusHighlightEnabled = value; + if (this.Focused) + this.Invalidate(true); + } + } + } + + /// + /// Gets or sets the color used as background color to highlight text box when it has input focus and focus highlight is enabled. + /// + [Browsable(true), Category("Appearance"), Description("Indicates color used as background color to highlight text box when it has input focus and focus highlight is enabled.")] + public Color FocusHighlightColor + { + get { return _FocusHighlightColor; } + set + { + if (_FocusHighlightColor != value) + { + _FocusHighlightColor = value; + _TextBox.FocusHighlightColor = value; + if (this.Focused) + this.Invalidate(true); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFocusHighlightColor() + { + return !_FocusHighlightColor.Equals(ColorScheme.GetColor(0xFFFF88)); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFocusHighlightColor() + { + FocusHighlightColor = ColorScheme.GetColor(0xFFFF88); + } + + private ElementStyle _BackgroundStyle = new ElementStyle(); + /// + /// Specifies the background style of the control. + /// + [Category("Style"), Description("Gets or sets control background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return _BackgroundStyle; } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _BackgroundStyle.StyleChanged -= new EventHandler(this.VisualPropertyChanged); + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + this.Invalidate(); + } + + private void VisualPropertyChanged(object sender, EventArgs e) + { + OnVisualPropertyChanged(); + } + + protected virtual void OnVisualPropertyChanged() + { + _ButtonGroup.InvalidateArrange(); + this.Invalidate(); + } + + protected override void Dispose(bool disposing) + { + if (_BackgroundStyle != null) _BackgroundStyle.StyleChanged -= new EventHandler(VisualPropertyChanged); + base.Dispose(disposing); + } + + private InputButtonSettings _ButtonDropDown = null; + /// + /// Gets the object that describes the settings for the button that shows drop-down when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the button that shows drop-down when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonDropDown + { + get + { + return _ButtonDropDown; + } + } + + private InputButtonSettings _ButtonClear = null; + /// + /// Gets the object that describes the settings for the button that clears the content of the control when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the button that clears the content of the control when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonClear + { + get + { + return _ButtonClear; + } + } + + + private InputButtonSettings _ButtonCustom = null; + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get + { + return _ButtonCustom; + } + } + + private InputButtonSettings _ButtonCustom2 = null; + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get + { + return _ButtonCustom2; + } + } + + + void IInputButtonControl.InputButtonSettingsChanged(InputButtonSettings inputButtonSettings) + { + OnInputButtonSettingsChanged(inputButtonSettings); + } + + protected virtual void OnInputButtonSettingsChanged(InputButtonSettings inputButtonSettings) + { + UpdateButtons(); + } + + private VisualGroup _ButtonGroup = null; + private void UpdateButtons() + { + RecreateButtons(); + _ButtonGroup.InvalidateArrange(); + this.Invalidate(); + } + + internal VisualGroup ButtonGroup + { + get { return (_ButtonGroup); } + } + + protected virtual void RecreateButtons() + { + VisualItem[] buttons = CreateOrderedButtonList(); + // Remove all system buttons that are already in the list + VisualGroup group = _ButtonGroup; + VisualItem[] items = new VisualItem[group.Items.Count]; + group.Items.CopyTo(items); + foreach (VisualItem item in items) + { + if (item.ItemType == eSystemItemType.SystemButton) + { + group.Items.Remove(item); + if (item == _ButtonCustom.ItemReference) + item.MouseUp -= new MouseEventHandler(CustomButtonMouseUp); + else if (item == _ButtonCustom2.ItemReference) + item.MouseUp -= new MouseEventHandler(CustomButton2MouseUp); + } + } + + // Add new buttons to the list + group.Items.AddRange(buttons); + } + + private void CustomButtonMouseUp(object sender, MouseEventArgs e) + { + if (_ButtonCustom.ItemReference.RenderBounds.Contains(e.X, e.Y)) + OnButtonCustomClick(e); + } + + protected virtual void OnButtonCustomClick(EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + private void CustomButton2MouseUp(object sender, MouseEventArgs e) + { + if (_ButtonCustom2.ItemReference.RenderBounds.Contains(e.X, e.Y)) + OnButtonCustom2Click(e); + } + + protected virtual void OnButtonCustom2Click(EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + private VisualItem[] CreateOrderedButtonList() + { + SortedList list = CreateSortedButtonList(); + + VisualItem[] items = new VisualItem[list.Count]; + list.Values.CopyTo(items, 0); + + return items; + } + + private void CustomButtonClick(object sender, EventArgs e) + { + OnButtonCustomClick(e); + } + private void CustomButton2Click(object sender, EventArgs e) + { + OnButtonCustom2Click(e); + } + private void ClearButtonClick(object sender, EventArgs e) + { + ClearButtonClick(); + } + protected virtual SortedList CreateSortedButtonList() + { + SortedList list = new SortedList(4); + if (_ButtonCustom.Visible) + { + VisualItem button = CreateButton(_ButtonCustom); + if (_ButtonCustom.ItemReference != null) + { + _ButtonCustom.ItemReference.MouseUp -= CustomButtonMouseUp; + _ButtonCustom.ItemReference.Click -= CustomButtonClick; + } + _ButtonCustom.ItemReference = button; + button.Click += CustomButtonClick; + button.MouseUp += CustomButtonMouseUp; + button.Enabled = _ButtonCustom.Enabled; + list.Add(_ButtonCustom, button); + } + + if (_ButtonCustom2.Visible) + { + VisualItem button = CreateButton(_ButtonCustom2); + if (_ButtonCustom.ItemReference != null) + { + _ButtonCustom.ItemReference.MouseUp -= CustomButton2MouseUp; + _ButtonCustom.ItemReference.Click -= CustomButton2Click; + } + _ButtonCustom2.ItemReference = button; + button.Click += CustomButton2Click; + button.MouseUp += CustomButton2MouseUp; + button.Enabled = _ButtonCustom2.Enabled; + list.Add(_ButtonCustom2, button); + } + + if (_ButtonClear.Visible) + { + VisualItem button = CreateButton(_ButtonClear); + if (_ButtonClear.ItemReference != null) + { + _ButtonClear.ItemReference.MouseUp -= ClearButtonMouseUp; + _ButtonClear.ItemReference.Click -= ClearButtonClick; + } + _ButtonClear.ItemReference = button; + button.MouseUp += ClearButtonMouseUp; + button.Click += ClearButtonClick; + list.Add(_ButtonClear, button); + } + + if (_ButtonDropDown.Visible) + { + VisualItem button = CreateButton(_ButtonDropDown); + if (_ButtonDropDown.ItemReference != null) + { + _ButtonDropDown.ItemReference.MouseDown -= DropDownButtonMouseDown; + _ButtonDropDown.ItemReference.Click -= DropDownButtonClick; + } + _ButtonDropDown.ItemReference = button; + button.MouseDown += DropDownButtonMouseDown; + button.Click += DropDownButtonClick; + list.Add(_ButtonDropDown, button); + } + + return list; + } + + private void DropDownButtonClick(object sender, EventArgs e) + { + if (e is KeyEventArgs) // Only if invoked through keyboard shortcut + { + if (_PopupItem.Expanded) + CloseDropDown(); + else + InvokeShowDropDown(); + } + } + + protected virtual VisualItem CreateButton(InputButtonSettings buttonSettings) + { + VisualItem item = null; + + if (buttonSettings == _ButtonDropDown) + { + item = new VisualDropDownButton(); + ApplyButtonSettings(buttonSettings, item as VisualButton); + } + else + { + item = new VisualCustomButton(); + ApplyButtonSettings(buttonSettings, item as VisualButton); + } + + VisualButton button = item as VisualButton; + button.ClickAutoRepeat = false; + + if (buttonSettings == _ButtonClear) + { + if (buttonSettings.Image == null && string.IsNullOrEmpty(buttonSettings.Text)) + { + //if (Dpi.Factor.Width > 1) + button.Symbol = "\uf00d"; + //else + // button.Image = DevComponents.DotNetBar.BarFunctions.LoadBitmap("SystemImages.DateReset.png"); + } + } + + return item; + } + + protected virtual void ApplyButtonSettings(InputButtonSettings buttonSettings, VisualButton button) + { + button.Text = buttonSettings.Text; + button.Image = buttonSettings.Image; + button.ItemType = eSystemItemType.SystemButton; + button.Enabled = buttonSettings.Enabled; + button.Shortcut = buttonSettings.Shortcut; + button.Tooltip = buttonSettings.Tooltip; + button.Symbol = buttonSettings.Symbol; + button.SymbolSet = buttonSettings.SymbolSet; + button.SymbolColor = buttonSettings.SymbolColor; + } + + private void CreateButtonGroup() + { + VisualGroup group = new VisualGroup(); + group.HorizontalItemSpacing = 0; + group.ArrangeInvalid += new EventHandler(ButtonGroupArrangeInvalid); + group.RenderInvalid += new EventHandler(ButtonGroupRenderInvalid); + group.ResetMouseHover += ButtonGroupResetMouseHover; + _ButtonGroup = group; + } + + private void ButtonGroupRenderInvalid(object sender, EventArgs e) + { + Invalidate(); + } + + private void ButtonGroupArrangeInvalid(object sender, EventArgs e) + { + Invalidate(); + } + + private void ButtonGroupResetMouseHover(object sender, EventArgs e) + { + DevComponents.AdvTree.Interop.WinApi.ResetHover(this); + } + + private bool _MouseOver = false; + private PaintInfo CreatePaintInfo(Graphics g) + { + PaintInfo p = new PaintInfo(); + p.Graphics = g; + p.DefaultFont = this.Font; + p.ForeColor = this.ForeColor; + p.RenderOffset = new System.Drawing.Point(); + Size s = this.Size; + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + int styleSpace = (ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.BottomWhiteSpace(style, eSpacePart.Border)); + if (styleSpace > 0) styleSpace += 2; + s.Height -= styleSpace; + styleSpace = (ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border)); + if (styleSpace > 0) styleSpace += 2; + s.Width -= styleSpace; + p.AvailableSize = s; + p.ParentEnabled = this.Enabled; + p.MouseOver = _MouseOver || this.Focused; + if (disposeStyle) style.Dispose(); + return p; + } + + private ElementStyle GetBackgroundStyle(out bool disposeStyle) + { + disposeStyle = false; + _BackgroundStyle.SetColorScheme(this.GetColorScheme()); + return ElementStyleDisplay.GetElementStyle(_BackgroundStyle, out disposeStyle); + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + Graphics g = e.Graphics; + Rectangle clientRect = this.ClientRectangle; + bool enabled = this.Enabled; + + if (!this.Enabled) + e.Graphics.FillRectangle(SystemBrushes.Control, clientRect); + else + { + using (SolidBrush brush = new SolidBrush(this.BackColor)) + e.Graphics.FillRectangle(brush, clientRect); + } + + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + + if (style.Custom) + { + SmoothingMode sm = g.SmoothingMode; + if (this.AntiAlias) + g.SmoothingMode = SmoothingMode.AntiAlias; + ElementStyleDisplayInfo displayInfo = new ElementStyleDisplayInfo(style, g, clientRect); + if (!enabled) + { + ElementStyleDisplay.PaintBorder(displayInfo); + } + else + ElementStyleDisplay.Paint(displayInfo); + if (this.AntiAlias) + g.SmoothingMode = sm; + } + + PaintButtons(g); + + if (disposeStyle) style.Dispose(); + } + + + public override Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColor() + { + return this.BackColor != SystemColors.Window; + } + + protected override void OnBackColorChanged(EventArgs e) + { + base.OnBackColorChanged(e); + if (_TextBox.Parent != null) + _TextBox.BackColor = this.BackColor; + } + + private void PaintButtons(Graphics g) + { + PaintInfo p = CreatePaintInfo(g); + + if (!_ButtonGroup.IsLayoutValid) + { + UpdateLayout(p); + } + + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + _ButtonGroup.RenderBounds = GetButtonsRenderBounds(style); + _ButtonGroup.ProcessPaint(p); + if (disposeStyle) style.Dispose(); + } + + private Rectangle GetButtonsRenderBounds(ElementStyle style) + { + int y = ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border); + if (y > 0) y += 1; + + if (this.RightToLeft == RightToLeft.Yes) + { + return new Rectangle((ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + 1), y, + _ButtonGroup.Size.Width, _ButtonGroup.Size.Height); + } + + return new Rectangle(this.Width - (ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border) + 1) - _ButtonGroup.Size.Width, y, + _ButtonGroup.Size.Width, _ButtonGroup.Size.Height); + } + + protected override void OnResize(EventArgs e) + { + if (BarFunctions.IsHandleValid(this)) + { + _ButtonGroup.InvalidateArrange(); + UpdateLayout(); + this.Invalidate(); + } + base.OnResize(e); + } + + protected override void OnGotFocus(EventArgs e) + { + _TextBox.Focus(); + base.OnGotFocus(e); + } + + protected override void OnRightToLeftChanged(EventArgs e) + { + _ButtonGroup.InvalidateArrange(); + UpdateLayout(); + this.Invalidate(); + base.OnRightToLeftChanged(e); + } + + protected override void OnFontChanged(EventArgs e) + { + _ButtonGroup.InvalidateArrange(); + UpdateLayout(); + this.Invalidate(); + base.OnFontChanged(e); + } + + protected override void OnForeColorChanged(EventArgs e) + { + _TextBox.ForeColor = this.ForeColor; + base.OnForeColorChanged(e); + } + + private void UpdateLayout() + { + if (!BarFunctions.IsHandleValid(this)) + return; + using (Graphics g = BarFunctions.CreateGraphics(this)) + UpdateLayout(CreatePaintInfo(g)); + } + + private bool _InternalSizeUpdate = false; + private void UpdateLayout(PaintInfo p) + { + if (_InternalSizeUpdate) return; + + _InternalSizeUpdate = true; + + try + { + if (!_ButtonGroup.IsLayoutValid) + { + _ButtonGroup.PerformLayout(p); + } + + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + Rectangle textBoxControlRect = ElementStyleLayout.GetInnerRect(style, this.ClientRectangle); + if (RenderButtons) + { + Rectangle buttonsRect = GetButtonsRenderBounds(style); + if (this.RightToLeft == RightToLeft.Yes) + { + textBoxControlRect.X += buttonsRect.Right; + textBoxControlRect.Width -= buttonsRect.Right; + } + else + { + textBoxControlRect.Width -= (textBoxControlRect.Right - buttonsRect.X); + } + } + if (_TextBox.Multiline == false && (_TextBox.PreferredHeight < textBoxControlRect.Height)) + { + textBoxControlRect.Y += (textBoxControlRect.Height - _TextBox.PreferredHeight) / 2; + } + _TextBox.Bounds = textBoxControlRect; + + if (disposeStyle) style.Dispose(); + } + finally + { + _InternalSizeUpdate = false; + } + } + + private Control _PreviousDropDownControlParent = null; + private void DropDownButtonMouseDown(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Left || _CloseTime != DateTime.MinValue && DateTime.Now.Subtract(_CloseTime).TotalMilliseconds < 250) + { + _CloseTime = DateTime.MinValue; + return; + } + + InvokeShowDropDown(); + + if ((Control.MouseButtons & MouseButtons.Left) == 0) + _ButtonGroup.ProcessMouseUp(e); + } + + private void InvokeShowDropDown() + { + CancelEventArgs cancelArgs = new CancelEventArgs(); + OnButtonDropDownClick(cancelArgs); + if (cancelArgs.Cancel) return; + if (IsPopupOpen) + CloseDropDown(); + else + ShowDropDown(); + } + + /// + /// Gets or sets a value indicating whether the drop-down is open. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPopupOpen + { + get + { + return _PopupItem.Expanded; + } + set + { + if (value != _PopupItem.Expanded) + { + if (value) + ShowDropDown(); + else + CloseDropDown(); + } + } + } + + private bool _ShowingPopup = false; + /// + /// Shows drop-down popup. Note that popup will be shown only if there is a DropDownControl assigned or DropDownItems collection has at least one item. + /// + public void ShowDropDown() + { + if (_DropDownControl == null && _PopupItem.SubItems.Count == 0 || _ShowingPopup || _PopupItem.Expanded) + return; + + CancelEventArgs ce = new CancelEventArgs(); + OnBeforePopupOpen(ce); + if (ce.Cancel) return; + + _ShowingPopup = true; + try + { + ControlContainerItem cc = null; + ItemContainer ic = null; + if (_DropDownControl != null) + { + ic = new ItemContainer(); + ic.Name = _DropDownItemContainerName; + cc = new ControlContainerItem(_DropDownControlContainerName); + ic.SubItems.Add(cc); + _PopupItem.SubItems.Insert(0, ic); + } + + if (_PopupItem.SubItems.Count == 0) + { + if (ic != null) + _PopupItem.SubItems.Remove(ic); + return; + } + if (_DropDownControl != null) + { + _PreviousDropDownControlParent = _DropDownControl.Parent; + cc.Control = _DropDownControl; + if (!_DropDownControl.IsHandleCreated) + { + IntPtr handle = _DropDownControl.Handle; // Forces creation of the control so its size etc. can be accessed reliably + } + } + + _PopupItem.SetDisplayRectangle(this.ClientRectangle); + if (this.RightToLeft == RightToLeft.No) + { + Point pl = new Point(this.Width - _PopupItem.PopupSize.Width, this.Height); + ScreenInformation screen = BarFunctions.ScreenFromControl(this); + Point ps = PointToScreen(pl); + if (screen != null && screen.WorkingArea.X > ps.X) + { + pl.X = 0; + } + _PopupItem.PopupLocation = pl; + } + + _PopupItem.Expanded = !_PopupItem.Expanded; + } + finally + { + _ShowingPopup = false; + } + + if (_DropDownControl != null && _AutoFocusDropDownControl && _DropDownControl.CanFocus) + BarUtilities.InvokeDelayed(new MethodInvoker(delegate { _DropDownControl.Focus(); })); + } + + /// + /// Closes the drop-down popup if it is open. + /// + public void CloseDropDown() + { + if (_PopupItem.Expanded) _PopupItem.Expanded = false; + } + + private DateTime _CloseTime = DateTime.MinValue; + private void DropDownPopupClose(object sender, EventArgs e) + { + _CloseTime = DateTime.Now; + + ItemContainer ic = null; + if (_PopupItem.SubItems.Contains(_DropDownItemContainerName)) + ic = _PopupItem.SubItems[_DropDownItemContainerName] as ItemContainer; + if (ic != null) + { + ControlContainerItem cc = ic.SubItems[_DropDownControlContainerName] as ControlContainerItem; + if (cc != null) + { + cc.Control = null; + ic.SubItems.Remove(cc); + if (_DropDownControl != null) + { + _DropDownControl.Parent = _PreviousDropDownControlParent; + _PreviousDropDownControlParent = null; + } + } + _PopupItem.SubItems.Remove(ic); + ic.Dispose(); + } + } + + private bool _AutoFocusDropDownControl = false; + /// + /// Indicates whether DropDownControl is automatically focused when popup is open. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether DropDownControl is automatically focused when popup is open.")] + public bool AutoFocusDropDownControl + { + get { return _AutoFocusDropDownControl; } + set + { + _AutoFocusDropDownControl = value; + } + } + + + private void ClearButtonClick() + { + CancelEventArgs cancelArgs = new CancelEventArgs(); + OnButtonClearClick(cancelArgs); + if (cancelArgs.Cancel) return; + + _TextBox.Text = ""; + } + private void ClearButtonMouseUp(object sender, EventArgs e) + { + ClearButtonClick(); + } + + /// + /// Raises the ButtonClearClick event. + /// + /// + protected virtual void OnButtonClearClick(CancelEventArgs e) + { + if (ButtonClearClick != null) + ButtonClearClick(this, e); + } + + /// + /// Raises the ButtonDropDownClick event. + /// + /// + protected virtual void OnButtonDropDownClick(CancelEventArgs e) + { + if (ButtonDropDownClick != null) + ButtonDropDownClick(this, e); + } + + private Control _DropDownControl = null; + /// + /// Gets or sets the reference of the control that will be displayed on popup that is shown when drop-down button is clicked. + /// + [DefaultValue(null), Description("Indicates reference of the control that will be displayed on popup that is shown when drop-down button is clicked.")] + public Control DropDownControl + { + get { return _DropDownControl; } + set + { + if (value == this) return; + _DropDownControl = value; + OnDropDownControlChanged(); + } + } + /// + /// Called when DropDownControl property has changed. + /// + protected virtual void OnDropDownControlChanged() + { + if (_DropDownControl != null) + { + _DropDownControl.BindingContext = this.BindingContext; + if (!this.DesignMode) + _DropDownControl.Visible = false; + } + } + + protected override PopupItem CreatePopupItem() + { + ButtonItem button = new ButtonItem("sysPopupProvider"); + button.PopupFinalized += new EventHandler(DropDownPopupClose); + _PopupItem = button; + return button; + } + + /// + /// Gets the collection of BaseItem derived items displayed on popup menu. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SubItemsCollection DropDownItems + { + get { return _PopupItem.SubItems; } + } + + protected override void RecalcSize() + { + } + + public override void PerformClick() + { + } + + private bool RenderButtons + { + get + { + return _ButtonCustom != null && _ButtonCustom.Visible || _ButtonCustom2 != null && _ButtonCustom2.Visible || + _ButtonDropDown != null && _ButtonDropDown.Visible || _ButtonClear != null && _ButtonClear.Visible; + } + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseMove(e); + } + base.OnMouseMove(e); + } + protected override void OnMouseLeave(EventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseLeave(); + } + base.OnMouseLeave(e); + } + protected override void OnMouseHover(EventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseHover(e); + } + base.OnMouseHover(e); + } + protected override void OnMouseDown(MouseEventArgs e) + { + if (RenderButtons) + _ButtonGroup.ProcessMouseDown(e); + base.OnMouseDown(e); + } + protected override void OnMouseUp(MouseEventArgs e) + { + if (RenderButtons) + _ButtonGroup.ProcessMouseUp(e); + base.OnMouseUp(e); + } + + internal void ProcessMouseUpOnGroup() + { + if (RenderButtons) + _ButtonGroup.ProcessMouseUp(new MouseEventArgs(MouseButtons.Left, 0, -10, -10, 0)); + this.Invalidate(); + } + + /// + /// Gets the reference to internal TextBox control. Use it to get access to the text box events and properties. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TextBoxX TextBox + { + get + { + return _TextBox; + } + } + + private bool _InternalReadOnly = false; + internal bool InternalReadOnly + { + get { return _InternalReadOnly; } + set + { + _InternalReadOnly = value; + } + } + + + /// + /// Gets or sets whether watermark text is displayed when control is empty. Default value is true. + /// + [DefaultValue(true), Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return _TextBox.WatermarkEnabled; } + set { _TextBox.WatermarkEnabled = value; this.Invalidate(true); } + } + + /// + /// Gets or sets the watermark (tip) text displayed inside of the control when Text is not set and control does not have input focus. This property supports text-markup. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus."), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string WatermarkText + { + get { return _TextBox.WatermarkText; } + set + { + if (value == null) value = ""; + _TextBox.WatermarkText = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark font."), DefaultValue(null)] + public Font WatermarkFont + { + get { return _TextBox.WatermarkFont; } + set { _TextBox.WatermarkFont = value; this.Invalidate(true); } + } + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return _TextBox.WatermarkColor; } + set { _TextBox.WatermarkColor = value; this.Invalidate(); } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return _TextBox.WatermarkColor != SystemColors.GrayText; + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + this.WatermarkColor = SystemColors.GrayText; + } + + /// + /// Gets or sets the watermark hiding behaviour. Default value indicates that watermark is hidden when control receives input focus. + /// + [DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior"), Description("Indicates watermark hiding behaviour.")] + public eWatermarkBehavior WatermarkBehavior + { + get { return _TextBox.WatermarkBehavior; } + set { _TextBox.WatermarkBehavior = value; this.Invalidate(true); } + } + + /// + /// Gets or sets the watermark image displayed inside of the control when Text is not set and control does not have input focus. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates watermark image displayed inside of the control when Text is not set and control does not have input focus.")] + public Image WatermarkImage + { + get { return _TextBox.WatermarkImage; } + set { _TextBox.WatermarkImage = value; } + } + /// + /// Gets or sets the watermark image alignment. + /// + [DefaultValue(ContentAlignment.MiddleLeft), Category("Appearance"), Description("Indicates watermark image alignment.")] + public ContentAlignment WatermarkImageAlignment + { + get { return _TextBox.WatermarkImageAlignment; } + set { _TextBox.WatermarkImageAlignment = value; } + } + + #endregion + + #region ICommandSource Members + protected virtual void ExecuteCommand() + { + if (_Command == null) return; + CommandManager.ExecuteCommand(this); + } + + /// + /// Gets or sets the command assigned to the item. Default value is null. + /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. + /// + [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] + public Command Command + { + get { return (Command)((ICommandSource)this).Command; } + set + { + ((ICommandSource)this).Command = value; + } + } + + private ICommand _Command = null; + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + ICommand ICommandSource.Command + { + get + { + return _Command; + } + set + { + bool changed = false; + if (_Command != value) + changed = true; + + if (_Command != null) + CommandManager.UnRegisterCommandSource(this, _Command); + _Command = value; + if (value != null) + CommandManager.RegisterCommand(this, value); + if (changed) + OnCommandChanged(); + } + } + + /// + /// Called when Command property value changes. + /// + protected virtual void OnCommandChanged() + { + } + + private object _CommandParameter = null; + /// + /// Gets or sets user defined data value that can be passed to the command when it is executed. + /// + [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] + public object CommandParameter + { + get + { + return _CommandParameter; + } + set + { + _CommandParameter = value; + } + } + + #endregion + + #region TextBox Property Forwarding + /// + /// Gets or sets the text as it is currently displayed to the user. + /// + [Category("Appearance"), DefaultValue("Indicates text as it is currently displayed to the user"), Bindable(true), RefreshProperties(RefreshProperties.Repaint), Localizable(true)] + public override string Text + { + get + { + return base.Text; + } + set + { + _TextBox.Text = value; + } + } + + + /// + /// Returns a string that represents the current text in text box. This method overrides ToString. + /// + /// A String that contains information about the current TextBox. The string includes the type, a simplified view of the input string, and the formatted input string. + public override string ToString() + { + return _TextBox.ToString(); + } + + /// + /// Gets the preferred height for a text box. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] + public int PreferredHeight + { + get + { + int height = _TextBox.PreferredHeight; + bool disposeStyle = false; + ElementStyle style = GetBackgroundStyle(out disposeStyle); + height += ElementStyleLayout.VerticalStyleWhiteSpace(style); + if (disposeStyle) + { + style.Dispose(); + } + return height; + } + } + protected override void OnHandleCreated(EventArgs e) + { + UpdateLayout(); // Fixes an issue where button if visible is not showing under certain use cases + base.OnHandleCreated(e); + } + public override Size GetPreferredSize(Size proposedSize) + { + Size ps = _TextBox.GetPreferredSize(proposedSize); + ps.Height = PreferredHeight; + return ps; + } + + /// + /// Gets or sets a custom StringCollection to use when the AutoCompleteSource property is set to CustomSource. + /// A StringCollection to use with AutoCompleteSource. + /// + [Browsable(true), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Localizable(true), Description("Indicates custom StringCollection to use when the AutoCompleteSource property is set to CustomSource."), Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + public AutoCompleteStringCollection AutoCompleteCustomSource + { + get + { + return _TextBox.AutoCompleteCustomSource; + } + set + { + _TextBox.AutoCompleteCustomSource = value; + } + } + + /// + /// Gets or sets an option that controls how automatic completion works for the TextBox. + /// One of the values of AutoCompleteMode. The values are Append, None, Suggest, and SuggestAppend. The default is None. + /// + [Description("Gets or sets an option that controls how automatic completion works for the TextBox."), Browsable(true), EditorBrowsable(EditorBrowsableState.Always), DefaultValue(0)] + public AutoCompleteMode AutoCompleteMode + { + get + { + return _TextBox.AutoCompleteMode; + } + set + { + _TextBox.AutoCompleteMode = value; + } + } + + /// + /// Gets or sets a value specifying the source of complete strings used for automatic completion. + /// One of the values of AutoCompleteSource. The options are AllSystemSources, AllUrl, FileSystem, HistoryList, RecentlyUsedList, CustomSource, and None. The default is None. + /// + [DefaultValue(0x80), TypeConverter(typeof(TextBoxAutoCompleteSourceConverter)), Browsable(true), EditorBrowsable(EditorBrowsableState.Always), Description("Gets or sets a value specifying the source of complete strings used for automatic completion.")] + public AutoCompleteSource AutoCompleteSource + { + get + { + return _TextBox.AutoCompleteSource; + } + set + { + _TextBox.AutoCompleteSource = value; + } + } + + /// + /// Gets or sets whether the TextBox control modifies the case of characters as they are typed. + /// One of the CharacterCasing enumeration values that specifies whether the TextBox control modifies the case of characters. The default is CharacterCasing.Normal. + /// + [Category("Behavior"), Description("Indicates whether the TextBox control modifies the case of characters as they are typed."), DefaultValue(0)] + public CharacterCasing CharacterCasing + { + get + { + return _TextBox.CharacterCasing; + } + set + { + _TextBox.CharacterCasing = value; + } + } + + /// + /// Gets or sets the character used to mask characters of a password in a single-line TextBox control. + /// The character used to mask characters entered in a single-line TextBox control. Set the value of this property to 0 (character value) if you do not want the control to mask characters as they are typed. Equals 0 (character value) by default. + /// + [RefreshProperties(RefreshProperties.Repaint), Localizable(true), Description("Gets or sets the character used to mask characters of a password in a single-line TextBox control."), Category("Behavior"), DefaultValue('\0')] + public char PasswordChar + { + get + { + return _TextBox.PasswordChar; + } + set + { + _TextBox.PasswordChar = value; + } + } + + /// + /// Gets or sets how text is aligned in a TextBox control. + /// One of the HorizontalAlignment enumeration values that specifies how text is aligned in the control. The default is HorizontalAlignment.Left. + /// + [DefaultValue(0), Category("Appearance"), Localizable(true), Description("Indicates how text is aligned in a TextBox control.")] + public HorizontalAlignment TextAlign + { + get + { + return _TextBox.TextAlign; + } + set + { + _TextBox.TextAlign = value; + } + } + + /// + /// Gets or sets a value indicating whether the text in the TextBox control should appear as the default password character. + /// true if the text in the TextBox control should appear as the default password character; otherwise, false. + /// + [Category("Behavior"), DefaultValue(false), Description("Gets or sets a value indicating whether the text in the TextBox control should appear as the default password character."), RefreshProperties(RefreshProperties.Repaint)] + public bool UseSystemPasswordChar + { + get + { + return _TextBox.UseSystemPasswordChar; + } + set + { + _TextBox.UseSystemPasswordChar = value; + } + } + + /// + /// Gets or sets a value indicating whether the selected text in the text box control remains highlighted when the control loses focus. + /// true if the selected text does not appear highlighted when the text box control loses focus; false, if the selected text remains highlighted when the text box control loses focus. The default is true. + /// + [Category("Behavior"), DefaultValue(true), Description("Gets or sets a value indicating whether the selected text in the text box control remains highlighted when the control loses focus.")] + public bool HideSelection + { + get + { + return _TextBox.HideSelection; + } + set + { + _TextBox.HideSelection = value; + } + } + + /// + /// Gets or sets the maximum number of characters the user can type or paste into the text box control. + /// The number of characters that can be entered into the control. The default is 32767. + /// + [Category("Behavior"), Description("Gets or sets the maximum number of characters the user can type or paste into the text box control."), DefaultValue(0x7fff), Localizable(true)] + public virtual int MaxLength + { + get + { + return _TextBox.MaxLength; + } + set + { + _TextBox.MaxLength = value; + } + } + + /// + /// Gets or sets a value that indicates that the text box control has been modified by the user since the control was created or its contents were last set. + /// true if the control's contents have been modified; otherwise, false. The default is false. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public bool Modified + { + get + { + return _TextBox.Modified; + } + set + { + _TextBox.Modified = value; + } + } + + + /// + /// Gets or sets a value indicating whether text in the text box is read-only. + /// true if the text box is read-only; otherwise, false. The default is false. + /// + [DefaultValue(false), RefreshProperties(RefreshProperties.Repaint), Category("Behavior"), Description("Gets or sets a value indicating whether text in the text box is read-only.")] + public bool ReadOnly + { + get + { + return _TextBox.ReadOnly; + } + set + { + _TextBox.ReadOnly = value; + } + } + + /// + /// Gets or sets a value indicating the currently selected text in the control. + /// A string that represents the currently selected text in the text box. + /// + [Description("Gets or sets a value indicating the currently selected text in the control."), Browsable(false), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual string SelectedText + { + get + { + return _TextBox.SelectedText; + } + set + { + _TextBox.SelectedText = value; + } + } + + /// + /// Gets or sets the number of characters selected in the text box. + /// The number of characters selected in the text box. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Description("Gets or sets the number of characters selected in the text box."), Category("Appearance")] + public virtual int SelectionLength + { + get + { + return _TextBox.SelectionLength; + } + set + { + _TextBox.SelectionLength = value; + } + } + + /// + /// Gets or sets the starting point of text selected in the text box. + /// The starting position of text selected in the text box. + /// + [Description("Gets or sets the starting point of text selected in the text box."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Category("Appearance"), Browsable(false)] + public int SelectionStart + { + get + { + return _TextBox.SelectionStart; + } + set + { + _TextBox.SelectionStart = value; + } + } + + /// + /// Gets the length of text in the control.Returns number of characters contained in the text of the control. + /// + [Browsable(false)] + public virtual int TextLength + { + get + { + return _TextBox.TextLength; + } + } + + /// + /// Appends text to the current text of a text box. + /// + /// The text to append to the current contents of the text box. + public void AppendText(string text) + { + _TextBox.AppendText(text); + } + + /// + /// Clears all text from the text box control. + /// + public void Clear() + { + _TextBox.Clear(); + } + + /// + /// Clears information about the most recent operation from the undo buffer of the text box. + /// + public void ClearUndo() + { + _TextBox.ClearUndo(); + } + + /// + /// Copies the current selection in the text box to the Clipboard. + /// + [UIPermission(SecurityAction.Demand, Clipboard = UIPermissionClipboard.OwnClipboard)] + public void Copy() + { + _TextBox.Copy(); + } + /// + /// Moves the current selection in the text box to the Clipboard. + /// + public void Cut() + { + _TextBox.Cut(); + } + /// + /// Specifies that the value of the SelectionLength property is zero so that no characters are selected in the control. + /// + public void DeselectAll() + { + _TextBox.DeselectAll(); + } + /// + /// Retrieves the character that is closest to the specified location within the control. + /// + /// The location from which to seek the nearest character. + /// The character at the specified location. + public virtual char GetCharFromPosition(Point pt) + { + return _TextBox.GetCharFromPosition(pt); + } + /// + /// Retrieves the index of the character nearest to the specified location. + /// + /// The location to search. + /// The zero-based character index at the specified location. + public virtual int GetCharIndexFromPosition(Point pt) + { + return _TextBox.GetCharIndexFromPosition(pt); + } + /// + /// Retrieves the index of the first character of a given line. + /// + /// The line for which to get the index of its first character. + /// The zero-based character index in the specified line. + public int GetFirstCharIndexFromLine(int lineNumber) + { + return _TextBox.GetFirstCharIndexFromLine(lineNumber); + } + /// + /// Retrieves the index of the first character of the current line. + /// + /// The zero-based character index in the current line. + public int GetFirstCharIndexOfCurrentLine() + { + return _TextBox.GetFirstCharIndexOfCurrentLine(); + } + /// + /// Retrieves the line number from the specified character position within the text of the control. + /// + /// The character index position to search. + /// The zero-based line number in which the character index is located. + public virtual int GetLineFromCharIndex(int index) + { + return _TextBox.GetLineFromCharIndex(index); + } + + /// + /// Retrieves the location within the control at the specified character index. + /// + /// The index of the character for which to retrieve the location. + /// The location of the specified character. + public virtual Point GetPositionFromCharIndex(int index) + { + return _TextBox.GetPositionFromCharIndex(index); + } + + /// + /// Replaces the current selection in the text box with the contents of the Clipboard. + /// + [UIPermission(SecurityAction.Demand, Clipboard = UIPermissionClipboard.OwnClipboard)] + public void Paste() + { + _TextBox.Paste(); + } + + /// + /// Selects a range of text in the text box. + /// + /// The position of the first character in the current text selection within the text box. + /// The number of characters to select. + public void Select(int start, int length) + { + _TextBox.Select(start, length); + } + + /// + /// Selects all text in the text box. + /// + public void SelectAll() + { + _TextBox.SelectAll(); + } + + /// + /// Undoes the last edit operation in the text box. + /// + public void Undo() + { + _TextBox.Undo(); + } + + /// + /// Replaces the specified selection in the TextBox with the contents of the Clipboard. + /// + /// The text to replace. + public void Paste(string text) + { + _TextBox.Paste(text); + } + + #endregion + } + + #region TextBoxAutoCompleteSourceConverter + internal class TextBoxAutoCompleteSourceConverter : EnumConverter + { + // Methods + public TextBoxAutoCompleteSourceConverter(Type type) + : base(type) + { + } + + public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + TypeConverter.StandardValuesCollection standardValues = base.GetStandardValues(context); + ArrayList values = new ArrayList(); + int count = standardValues.Count; + for (int i = 0; i < count; i++) + { + if (!standardValues[i].ToString().Equals("ListItems")) + { + values.Add(standardValues[i]); + } + } + return new TypeConverter.StandardValuesCollection(values); + } + } + #endregion +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/TextBoxDropDown.ico b/PROMS/DotNetBar Source Code/Controls/TextBoxDropDown.ico new file mode 100644 index 00000000..6533e2af Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/TextBoxDropDown.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/TextBoxX.cs b/PROMS/DotNetBar Source Code/Controls/TextBoxX.cs new file mode 100644 index 00000000..517159eb --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TextBoxX.cs @@ -0,0 +1,1308 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using DevComponents.DotNetBar.Rendering; +using System.Drawing; +using DevComponents.DotNetBar.TextMarkup; +using System.Reflection; +using DevComponents.Editors; +using System.Collections; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxBitmap(typeof(TextBoxX), "Controls.TextBoxX.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.TextBoxXDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class TextBoxX : TextBox, INonClientControl +#if FRAMEWORK20 +, IInputButtonControl +#endif + { + #region Private Variables + private NonClientPaintHandler m_NCPainter = null; + private string m_WatermarkText = ""; + private bool m_Focused = false; + private Font m_WatermarkFont = null; + private Color m_WatermarkColor = SystemColors.GrayText; + private ElementStyle m_BorderStyle = null; + private IntPtr m_LastFocusWindow; + private string m_OriginalText; + private bool m_IsTextBoxItem = false; + private Color m_FocusHighlightColor = ColorScheme.GetColor(0xFFFF88); + private bool m_FocusHighlightEnabled = false; + private Color m_LastBackColor = Color.Empty; + #endregion + + #region Events +#if FRAMEWORK20 + /// + /// Occurs when ButtonCustom control is clicked. + /// + public event EventHandler ButtonCustomClick; + + /// + /// Occurs when ButtonCustom2 control is clicked. + /// + public event EventHandler ButtonCustom2Click; +#endif + #endregion + + #region Constructor + public TextBoxX() + { +#if FRAMEWORK20 + _ButtonCustom = new InputButtonSettings(this); + _ButtonCustom2 = new InputButtonSettings(this); + CreateButtonGroup(); +#endif + + m_BorderStyle = new ElementStyle(); + m_BorderStyle.StyleChanged += new EventHandler(BorderStyle_StyleChanged); + m_NCPainter = new NonClientPaintHandler(this, eScrollBarSkin.Optimized); + base.BorderStyle = BorderStyle.None; + this.AutoSize = false; + StyleManager.Register(this); + } + + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + // Metro needs BackColor and ForeColor set + if (StyleManager.IsMetro(newStyle) || StyleManager.IsMetro(StyleManager.PreviousStyle) && !StyleManager.IsMetro(newStyle)) + StyleManager.UpdateAmbientColors(this); + UpdateEnabledBackColor(); + } + + internal TextBoxX(bool isTextBoxItem) + : this() + { + m_IsTextBoxItem = isTextBoxItem; + } + + protected override void Dispose(bool disposing) + { + if (m_NCPainter != null) + { + m_NCPainter.Dispose(); + //m_NCPainter = null; + } + if (m_BorderStyle != null) m_BorderStyle.StyleChanged -= new EventHandler(BorderStyle_StyleChanged); + StyleManager.Unregister(this); + base.Dispose(disposing); + } + #endregion + + #region Windows Messages Handling + private bool m_IgnoreFocus = false; + private bool _MouseOverButtons = false; + protected override void WndProc(ref Message m) + { + if (this.IsDisposed) + { + base.WndProc(ref m); + return; + } + if (m_NCPainter != null) + { + bool callBase = m_NCPainter.WndProc(ref m); + + if (callBase) + base.WndProc(ref m); + } + else + { + base.WndProc(ref m); + } + +#if FRAMEWORK20 + if (RenderButtons) + { + switch (m.Msg) + { + case (int)WinApi.WindowsMessages.WM_NCMOUSEMOVE: + case (int)WinApi.WindowsMessages.WM_NCHITTEST: + { + Point p = PointToClient(new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam))); + if (_ButtonGroup.RenderBounds.Contains(p)) + { + m.Result = new IntPtr((int)WinApi.WindowHitTestRegions.ClientArea); + return; + } + break; + } + } + } +#endif + + switch (m.Msg) + { + case (int)WinApi.WindowsMessages.WM_SETFOCUS: + { + if (m_IgnoreFocus) + { + m_IgnoreFocus = false; + } + else + { + m_Focused = true; + m_LastFocusWindow = m.WParam; + m_OriginalText = this.Text; + if (this.FocusHighlightEnabled && this.Enabled) + { + m_LastBackColor = this.BackColor; + this.BackColor = this.FocusHighlightColor; + this.InvalidateNonClient(); + } + } + break; + } + case (int)WinApi.WindowsMessages.WM_KILLFOCUS: + { + if (!m_Focused) + { + m_IgnoreFocus = true; + } + else + { + m_Focused = false; + if (this.Text.Length == 0) + this.Invalidate(); + if (this.FocusHighlightEnabled && !m_LastBackColor.IsEmpty) + { + this.BackColor = m_LastBackColor; + this.InvalidateNonClient(); + } + } + break; + } + case (int)WinApi.WindowsMessages.WM_PAINT: + { + if (RenderWatermark) + DrawWatermark(); + if (this.Parent is ItemControl) + ((ItemControl)this.Parent).UpdateKeyTipsCanvas(); + break; + } + } + } + + private bool RenderWatermark + { + get + { + if (!_WatermarkEnabled) + return false; + if (_WatermarkBehavior == eWatermarkBehavior.HideOnFocus) + return !m_Focused && this.Enabled && this.Text != null && this.Text.Length == 0 && (m_WatermarkText.Length > 0 || _WatermarkImage != null); + else + return this.Enabled && this.Text != null && this.Text.Length == 0 && (m_WatermarkText.Length > 0 || _WatermarkImage != null); + } + } + #endregion + + #region Internal Implementation + + private bool _IsEnterInputKey = false; + /// + /// Indicates whether internal override for IsInputKey returns true for the Enter key. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether internal override for IsInputKey returns true for the Enter key.")] + public bool IsEnterInputKey + { + get { return _IsEnterInputKey; } + set { _IsEnterInputKey = value; } + } + + protected override bool IsInputKey(Keys keyData) + { + if (keyData == Keys.Enter && _IsEnterInputKey) + return true; + return base.IsInputKey(keyData); + } + + private bool _AutoSelectAll = false; + /// + /// Indicates whether all text is auto-selected when control gets input focus. Default value is false. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether all text is auto-selected when control gets input focus.")] + public bool AutoSelectAll + { + get { return _AutoSelectAll; } + set { _AutoSelectAll = value; } + } + protected override void OnKeyPress(KeyPressEventArgs e) + { + _ButtonGroup.ProcessKeyPress(e); + if (!this.Multiline && _PreventEnterBeep && e.KeyChar == (char)Keys.Enter) + { + e.Handled = true; + } + base.OnKeyPress(e); + } + + private bool _PreventEnterBeep = false; + /// + /// Gets or sets whether control prevents Beep sound when Enter key is pressed. + /// + [DefaultValue(false), Category("Behavior"), Description("Gets or sets whether control prevents Beep sound when Enter key is pressed.")] + public bool PreventEnterBeep + { + get { return _PreventEnterBeep; } + set + { + _PreventEnterBeep = value; + } + } + + /// + /// Gets or sets whether FocusHighlightColor is used as background color to highlight text box when it has input focus. Default value is false. + /// + [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Indicates whether FocusHighlightColor is used as background color to highlight text box when it has input focus.")] + public bool FocusHighlightEnabled + { + get { return m_FocusHighlightEnabled; } + set + { + if (m_FocusHighlightEnabled != value) + { + m_FocusHighlightEnabled = value; + if (this.Focused) + this.Invalidate(); + if (!m_FocusHighlightEnabled) + this.ResetBackColor(); + } + } + } + + /// + /// Gets or sets the color used as background color to highlight text box when it has input focus and focus highlight is enabled. + /// + [Browsable(true), Category("Appearance"), Description("Indicates color used as background color to highlight text box when it has input focus and focus highlight is enabled.")] + public Color FocusHighlightColor + { + get { return m_FocusHighlightColor; } + set + { + if (m_FocusHighlightColor != value) + { + m_FocusHighlightColor = value; + if (this.Focused) + this.Invalidate(); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFocusHighlightColor() + { + return !m_FocusHighlightColor.Equals(ColorScheme.GetColor(0xFFFF88)); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFocusHighlightColor() + { + FocusHighlightColor = ColorScheme.GetColor(0xFFFF88); + } + + internal void ReleaseFocus() + { + if (this.Focused && m_LastFocusWindow != IntPtr.Zero) + { + IntPtr focus = m_LastFocusWindow; + m_LastFocusWindow = IntPtr.Zero; + Control ctrl = Control.FromChildHandle(focus); + if (ctrl != this) + { + Control p = this.Parent; + while (p != null) + { + if (p == ctrl) + { + if (ctrl is MenuPanel) + ctrl.Focus(); + return; + } + p = p.Parent; + } + + if (ctrl != null) + ctrl.Focus(); + else + { + NativeFunctions.SetFocus(focus); + } + } + } + } + + protected override void OnKeyUp(KeyEventArgs e) + { + _ButtonGroup.ProcessKeyUp(e); + base.OnKeyUp(e); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + _ButtonGroup.ProcessKeyDown(e); + + base.OnKeyDown(e); + if (m_IsTextBoxItem) + { + /*if (e.KeyCode == Keys.Enter) + ReleaseFocus(); + else*/ + if (!e.Handled && e.KeyCode == Keys.Escape) + { + this.Text = m_OriginalText; + this.SelectionStart = 0; + ReleaseFocus(); + } + } + } + + /// + /// Occurs during preprocessing to handle command keys. Command keys are keys that always take precedence over regular input keys. Examples of command keys include accelerators and menu shortcuts. Set Handled=true to indicate that you handled the key and that it should not be passed for further processing. + /// + [Description("Occurs during preprocessing to handle command keys. Command keys are keys that always take precedence over regular input keys. Examples of command keys include accelerators and menu shortcuts. Set Handled=true to indicate that you handled the key and that it should not be passed for further processing.")] + public event KeyEventHandler CommandKeyDown; + /// + /// Raises CommandKeyDown event. + /// + /// Provides event arguments. + protected virtual void OnCommandKeyDown(KeyEventArgs e) + { + KeyEventHandler handler = CommandKeyDown; + if (handler != null) + handler(this, e); + } + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if ((keyData & Keys.A) == Keys.A && Control.ModifierKeys == Keys.ControlKey) + { + this.SelectAll(); + return true; + } + if (_ButtonGroup.ProcessCmdKey(ref msg, keyData)) + return true; + if (CommandKeyDown != null) + { + KeyEventArgs args = new KeyEventArgs(keyData); + OnCommandKeyDown(args); + if (args.Handled) return true; + } + return base.ProcessCmdKey(ref msg, keyData); + } + + protected override void OnGotFocus(EventArgs e) + { + if (_AutoSelectAll) + this.SelectAll(); + base.OnGotFocus(e); + } + + protected override void OnLostFocus(EventArgs e) + { + m_LastFocusWindow = IntPtr.Zero; + base.OnLostFocus(e); + } + + /// + /// Gets or sets the scrollbar skinning type when control is using Office 2007 style. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public eScrollBarSkin ScrollbarSkin + { + get { return m_NCPainter.SkinScrollbars; } + set { m_NCPainter.SkinScrollbars = value; } + } + + /// + /// Specifies the control border style. Default value has Class property set so the system style for the control is used. + /// + [Browsable(true), Category("Style"), Description("Specifies the control border style. Default value has Class property set so the system style for the control is used."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle Border + { + get { return m_BorderStyle; } + } + + private void BorderStyle_StyleChanged(object sender, EventArgs e) + { + InvalidateNonClient(); + } + + protected override void OnReadOnlyChanged(EventArgs e) + { + InvalidateNonClient(); + base.OnReadOnlyChanged(e); + } + + /// + /// Invalidates non-client area of the text box as response to the border changes. + /// + public void InvalidateNonClient() + { + if (!BarFunctions.IsHandleValid(this)) return; + NativeFunctions.SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0, NativeFunctions.SWP_FRAMECHANGED | + NativeFunctions.SWP_NOACTIVATE | NativeFunctions.SWP_NOMOVE | NativeFunctions.SWP_NOSIZE | NativeFunctions.SWP_NOZORDER); + SetAutoHeight(); + const int RDW_INVALIDATE = 0x0001; + const int RDW_FRAME = 0x0400; + NativeFunctions.RECT r = new NativeFunctions.RECT(0, 0, this.Width, this.Height); + NativeFunctions.RedrawWindow(this.Handle, ref r, IntPtr.Zero, RDW_INVALIDATE | RDW_FRAME); + } + + private TextMarkup.BodyElement m_TextMarkup = null; + private void MarkupTextChanged() + { + m_TextMarkup = null; + + if (!TextMarkup.MarkupParser.IsMarkup(ref m_WatermarkText)) + return; + + m_TextMarkup = TextMarkup.MarkupParser.Parse(m_WatermarkText); + ResizeMarkup(); + } + + private void ResizeMarkup() + { + if (m_TextMarkup != null) + { + using (Graphics g = this.CreateGraphics()) + { + MarkupDrawContext dc = GetMarkupDrawContext(g); + m_TextMarkup.Measure(GetWatermarkBounds().Size, dc); + Size sz = m_TextMarkup.Bounds.Size; + m_TextMarkup.Arrange(new Rectangle(GetWatermarkBounds().Location, sz), dc); + } + } + } + + private Rectangle GetWatermarkBounds() + { + Rectangle r = this.ClientRectangle; + r.Inflate(-1, 0); + return r; + } + + private void DrawWatermark() + { + using (Graphics g = this.CreateGraphics()) + { + Rectangle bounds = GetWatermarkBounds(); + if (_WatermarkImage != null) + { + Rectangle imageBounds = new Rectangle(Point.Empty, _WatermarkImage.Size); + if (_WatermarkImageAlignment == ContentAlignment.BottomCenter) + imageBounds.Location = new Point(bounds.X + (bounds.Width - imageBounds.Width) / 2, bounds.Bottom - imageBounds.Height); + else if (_WatermarkImageAlignment == ContentAlignment.BottomLeft) + imageBounds.Location = new Point(bounds.X, bounds.Bottom - imageBounds.Height); + else if (_WatermarkImageAlignment == ContentAlignment.BottomRight) + imageBounds.Location = new Point(bounds.Right - imageBounds.Width, bounds.Bottom - imageBounds.Height); + else if (_WatermarkImageAlignment == ContentAlignment.MiddleCenter) + imageBounds.Location = new Point(bounds.X + (bounds.Width - imageBounds.Width) / 2, bounds.Y + (bounds.Height - imageBounds.Height) / 2); + else if (_WatermarkImageAlignment == ContentAlignment.MiddleLeft) + imageBounds.Location = new Point(bounds.X, bounds.Y + (bounds.Height - imageBounds.Height) / 2); + else if (_WatermarkImageAlignment == ContentAlignment.MiddleRight) + imageBounds.Location = new Point(bounds.Right - imageBounds.Width, bounds.Y + (bounds.Height - imageBounds.Height) / 2); + else if (_WatermarkImageAlignment == ContentAlignment.TopCenter) + imageBounds.Location = new Point(bounds.X + (bounds.Width - imageBounds.Width) / 2, bounds.Y); + else if (_WatermarkImageAlignment == ContentAlignment.TopLeft) + imageBounds.Location = new Point(bounds.X, bounds.Y); + else if (_WatermarkImageAlignment == ContentAlignment.TopRight) + imageBounds.Location = new Point(bounds.Right - imageBounds.Width, bounds.Y); + g.DrawImage(_WatermarkImage, imageBounds); + + if (_WatermarkImageAlignment == ContentAlignment.BottomLeft || _WatermarkImageAlignment == ContentAlignment.MiddleLeft || _WatermarkImageAlignment == ContentAlignment.TopLeft) + { + bounds.X = imageBounds.Right; + bounds.Width = Math.Max(0, bounds.Width - imageBounds.Width); + } + else if (_WatermarkImageAlignment == ContentAlignment.BottomRight || _WatermarkImageAlignment == ContentAlignment.MiddleRight || _WatermarkImageAlignment == ContentAlignment.TopRight) + { + bounds.Width = Math.Max(0, bounds.Width - imageBounds.Width); + } + } + + if (bounds.Width <= 0) return; + + if (m_TextMarkup != null) + { + MarkupDrawContext dc = GetMarkupDrawContext(g); + m_TextMarkup.Render(dc); + } + else + { + eTextFormat tf = eTextFormat.Left; + if (this.Multiline) + { + if (this.TextAlign == HorizontalAlignment.Center) + tf |= eTextFormat.VerticalCenter; + else if (TextAlign == HorizontalAlignment.Right) + tf |= eTextFormat.Bottom; + } + + if (this.RightToLeft == RightToLeft.Yes) tf |= eTextFormat.RightToLeft; + if (this.TextAlign == HorizontalAlignment.Left) + tf |= eTextFormat.Left; + else if (this.TextAlign == HorizontalAlignment.Right) + tf |= eTextFormat.Right; + else if (this.TextAlign == HorizontalAlignment.Center) + tf |= eTextFormat.HorizontalCenter; + tf |= eTextFormat.EndEllipsis; + tf |= eTextFormat.WordBreak; + TextDrawing.DrawString(g, m_WatermarkText, (m_WatermarkFont == null ? this.Font : m_WatermarkFont), + m_WatermarkColor, bounds, tf); + } + } + } + + protected override void OnFontChanged(EventArgs e) + { + SetAutoHeight(); + base.OnFontChanged(e); + } + /// + /// Calculates and sets the text-box height based on font and style. This method is used internally and should not be used. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetAutoHeight() + { + if (!this.AutoSize && this.Multiline == false && this.BorderStyle == BorderStyle.None && !this.IsDisposed && this.Parent != null && !m_IsTextBoxItem) + { + int h = this.FontHeight; + if (this.Font != null) h = Math.Max(h, this.Font.Height); + h++; + // Adjust for DPI other than 96 + //using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero)) + //{ + // if (graphics.DpiX != 96f) + // { + // h = (int)Math.Ceiling(h * (graphics.DpiX / 96f)); + // } + //} + bool disposeStyle = false; + ElementStyle style = GetBorderStyle(out disposeStyle); + if (style != null) + { + if (style.PaintTopBorder) + { + if (style.CornerType == eCornerType.Rounded || style.CornerType == eCornerType.Diagonal) + h += Math.Max(style.BorderTopWidth, style.CornerDiameter / 2 + 1); + else + h += style.BorderTopWidth; + } + + if (style.PaintBottomBorder) + { + if (style.CornerType == eCornerType.Rounded || style.CornerType == eCornerType.Diagonal) + h += Math.Max(style.BorderBottomWidth, style.CornerDiameter / 2 + 1); + else + h += style.BorderBottomWidth; + } + h += style.PaddingTop + style.PaddingBottom; + if (disposeStyle) style.Dispose(); + } +#if (FRAMEWORK20) + if (_ButtonCustom != null && _ButtonCustom.Visible && _ButtonCustom.Image != null) + { + h = Math.Max(h, _ButtonCustom.Image.Height + 6); + } + if (_ButtonCustom2 != null && _ButtonCustom2.Visible && _ButtonCustom2.Image != null) + { + h = Math.Max(h, _ButtonCustom2.Image.Height + 6); + } +#endif + this.Height = h; + } + } + + protected override void OnResize(EventArgs e) + { + ResizeMarkup(); +#if (FRAMEWORK20) + _ButtonGroup.InvalidateArrange(); +#endif + base.OnResize(e); + } + + private MarkupDrawContext GetMarkupDrawContext(Graphics g) + { + return new MarkupDrawContext(g, (m_WatermarkFont == null ? this.Font : m_WatermarkFont), m_WatermarkColor, this.RightToLeft == RightToLeft.Yes); + } + + protected override void OnTextAlignChanged(EventArgs e) + { + if (m_WatermarkText.Length > 0) + this.Invalidate(); + base.OnTextAlignChanged(e); + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + } + + private Color _EnabledBackColor = Color.Empty; + protected override void OnEnabledChanged(EventArgs e) + { + if (m_WatermarkText.Length > 0) + this.Invalidate(); + UpdateEnabledBackColor(); + base.OnEnabledChanged(e); + } + + private void UpdateEnabledBackColor() + { + if (!_DisabledBackColor.IsEmpty) + { + if (!this.Enabled) + { + _EnabledBackColor = this.BackColor; + this.BackColor = _DisabledBackColor; + } + else if (!_EnabledBackColor.IsEmpty) + { + this.BackColor = _EnabledBackColor; + _EnabledBackColor = Color.Empty; + } + } + } + + protected override void OnTextChanged(EventArgs e) + { + if (m_WatermarkText.Length > 0) + this.Invalidate(); + base.OnTextChanged(e); + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new BorderStyle BorderStyle + { + get { return base.BorderStyle; } + set { } + } + + private Rendering.BaseRenderer m_DefaultRenderer = null; + private Rendering.BaseRenderer m_Renderer = null; + private eRenderMode m_RenderMode = eRenderMode.Global; + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public virtual Rendering.BaseRenderer GetRenderer() + { + if (m_RenderMode == eRenderMode.Global && Rendering.GlobalManager.Renderer != null) + return Rendering.GlobalManager.Renderer; + else if (m_RenderMode == eRenderMode.Custom && m_Renderer != null) + return m_Renderer; + + if (m_DefaultRenderer == null) + m_DefaultRenderer = new Rendering.Office2007Renderer(); + + return m_DefaultRenderer; + } + + /// + /// Gets or sets the rendering mode used by control. Default value is eRenderMode.Global which means that static GlobalManager.Renderer is used. If set to Custom then Renderer property must + /// also be set to the custom renderer that will be used. + /// + [Browsable(false), DefaultValue(eRenderMode.Global)] + public eRenderMode RenderMode + { + get { return m_RenderMode; } + set + { + if (m_RenderMode != value) + { + m_RenderMode = value; + this.Invalidate(true); + } + } + } + + /// + /// Gets or sets the custom renderer used by the items on this control. RenderMode property must also be set to eRenderMode.Custom in order renderer + /// specified here to be used. + /// + [Browsable(false), DefaultValue(null)] + public DevComponents.DotNetBar.Rendering.BaseRenderer Renderer + { + get + { + return m_Renderer; + } + set { m_Renderer = value; } + } + + private bool _WatermarkEnabled = true; + /// + /// Gets or sets whether watermark text is displayed when control is empty. Default value is true. + /// + [DefaultValue(true), Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return _WatermarkEnabled; } + set { _WatermarkEnabled = value; this.Invalidate(); } + } + + private Image _WatermarkImage = null; + /// + /// Gets or sets the watermark image displayed inside of the control when Text is not set and control does not have input focus. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates watermark image displayed inside of the control when Text is not set and control does not have input focus.")] + public Image WatermarkImage + { + get { return _WatermarkImage; } + set { _WatermarkImage = value; this.Invalidate(); } + } + private ContentAlignment _WatermarkImageAlignment = ContentAlignment.MiddleLeft; + /// + /// Gets or sets the watermark image alignment. + /// + [DefaultValue(ContentAlignment.MiddleLeft), Category("Appearance"), Description("Indicates watermark image alignment.")] + public ContentAlignment WatermarkImageAlignment + { + get { return _WatermarkImageAlignment; } + set { _WatermarkImageAlignment = value; this.Invalidate(); } + } + + /// + /// Gets or sets the watermark (tip) text displayed inside of the control when Text is not set and control does not have input focus. This property supports text-markup. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus."), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string WatermarkText + { + get { return m_WatermarkText; } + set + { + if (value == null) value = ""; + m_WatermarkText = value; + MarkupTextChanged(); + this.Invalidate(); + } + } + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark font."), DefaultValue(null)] + public Font WatermarkFont + { + get { return m_WatermarkFont; } + set { m_WatermarkFont = value; this.Invalidate(); } + } + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return m_WatermarkColor; } + set { m_WatermarkColor = value; this.Invalidate(); } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return m_WatermarkColor != SystemColors.GrayText; + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + this.WatermarkColor = SystemColors.GrayText; + } + + private eWatermarkBehavior _WatermarkBehavior = eWatermarkBehavior.HideOnFocus; + /// + /// Gets or sets the watermark hiding behaviour. Default value indicates that watermark is hidden when control receives input focus. + /// + [DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior"), Description("Indicates watermark hiding behaviour.")] + public eWatermarkBehavior WatermarkBehavior + { + get { return _WatermarkBehavior; } + set { _WatermarkBehavior = value; this.Invalidate(); } + } + + private ElementStyle GetBorderStyle(out bool disposeStyle) + { + disposeStyle = false; + m_BorderStyle.SetColorScheme(this.GetColorScheme()); + return ElementStyleDisplay.GetElementStyle(m_BorderStyle, out disposeStyle); + } + +#if FRAMEWORK20 + private InputButtonSettings _ButtonCustom = null; + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom + { + get + { + return _ButtonCustom; + } + } + + private InputButtonSettings _ButtonCustom2 = null; + /// + /// Gets the object that describes the settings for the custom button that can execute an custom action of your choosing when clicked. + /// + [Category("Buttons"), Description("Describes the settings for the custom button that can execute an custom action of your choosing when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public InputButtonSettings ButtonCustom2 + { + get + { + return _ButtonCustom2; + } + } + + + void IInputButtonControl.InputButtonSettingsChanged(InputButtonSettings inputButtonSettings) + { + OnInputButtonSettingsChanged(inputButtonSettings); + } + + protected virtual void OnInputButtonSettingsChanged(InputButtonSettings inputButtonSettings) + { + UpdateButtons(); + } + + private VisualGroup _ButtonGroup = null; + private void UpdateButtons() + { + RecreateButtons(); + _ButtonGroup.InvalidateArrange(); + this.InvalidateNonClient(); + } + + protected virtual void RecreateButtons() + { + VisualItem[] buttons = CreateOrderedButtonList(); + // Remove all system buttons that are already in the list + VisualGroup group = _ButtonGroup; + VisualItem[] items = new VisualItem[group.Items.Count]; + group.Items.CopyTo(items); + foreach (VisualItem item in items) + { + if (item.ItemType == eSystemItemType.SystemButton) + { + group.Items.Remove(item); + if (item == _ButtonCustom.ItemReference) + item.MouseUp -= new MouseEventHandler(CustomButtonClick); + else if (item == _ButtonCustom2.ItemReference) + item.MouseUp -= new MouseEventHandler(CustomButton2Click); + } + } + + // Add new buttons to the list + group.Items.AddRange(buttons); + } + + private void CustomButtonClick(object sender, MouseEventArgs e) + { + if (_ButtonCustom.ItemReference.RenderBounds.Contains(e.X, e.Y)) + OnButtonCustomClick(e); + } + + /// + /// Invokes ButtonCustomClick event. + /// + public void PerformButtonCustomClick() + { + OnButtonCustomClick(EventArgs.Empty); + } + + protected virtual void OnButtonCustomClick(EventArgs e) + { + if (ButtonCustomClick != null) + ButtonCustomClick(this, e); + } + + private void CustomButton2Click(object sender, MouseEventArgs e) + { + if (_ButtonCustom2.ItemReference.RenderBounds.Contains(e.X, e.Y)) + OnButtonCustom2Click(e); + } + + /// + /// Invokes ButtonCustomClick2 event. + /// + public void PerformButtonCustom2Click() + { + OnButtonCustom2Click(EventArgs.Empty); + } + + protected virtual void OnButtonCustom2Click(EventArgs e) + { + if (ButtonCustom2Click != null) + ButtonCustom2Click(this, e); + } + + private VisualItem[] CreateOrderedButtonList() + { + SortedList list = CreateSortedButtonList(); + + VisualItem[] items = new VisualItem[list.Count]; + list.Values.CopyTo(items, 0); + + return items; + } + + private void CustomButtonKeyClick(object sender, EventArgs e) + { + if (e is KeyEventArgs) + OnButtonCustomClick(e); + } + private void CustomButton2KeyClick(object sender, EventArgs e) + { + if (e is KeyEventArgs) + OnButtonCustom2Click(e); + } + protected virtual SortedList CreateSortedButtonList() + { + SortedList list = new SortedList(4); + if (_ButtonCustom.Visible) + { + VisualItem button = CreateButton(_ButtonCustom); + if (_ButtonCustom.ItemReference != null) + { + _ButtonCustom.ItemReference.MouseUp -= CustomButtonClick; + _ButtonCustom.ItemReference.Click -= CustomButtonKeyClick; + } + _ButtonCustom.ItemReference = button; + button.Click += CustomButtonKeyClick; + button.MouseUp += new MouseEventHandler(CustomButtonClick); + button.Enabled = _ButtonCustom.Enabled; + list.Add(_ButtonCustom, button); + } + + if (_ButtonCustom2.Visible) + { + VisualItem button = CreateButton(_ButtonCustom2); + if (_ButtonCustom2.ItemReference != null) + { + _ButtonCustom2.ItemReference.MouseUp -= CustomButton2Click; + _ButtonCustom2.ItemReference.Click -= CustomButton2KeyClick; + } + _ButtonCustom2.ItemReference = button; + button.Click += CustomButton2KeyClick; + button.MouseUp += new MouseEventHandler(CustomButton2Click); + button.Enabled = _ButtonCustom2.Enabled; + list.Add(_ButtonCustom2, button); + } + + return list; + } + + protected virtual VisualItem CreateButton(InputButtonSettings buttonSettings) + { + VisualCustomButton button = new VisualCustomButton(); + ApplyButtonSettings(buttonSettings, button); + return button; + } + + protected virtual void ApplyButtonSettings(InputButtonSettings buttonSettings, VisualButton button) + { + button.Text = buttonSettings.Text; + button.Image = buttonSettings.Image; + button.ItemType = eSystemItemType.SystemButton; + button.Enabled = buttonSettings.Enabled; + button.Shortcut = buttonSettings.Shortcut; + button.Tooltip = buttonSettings.Tooltip; + button.Symbol = buttonSettings.Symbol; + button.SymbolSet = buttonSettings.SymbolSet; + button.SymbolColor = buttonSettings.SymbolColor; + button.Checked = buttonSettings.Checked; + } + + private void CreateButtonGroup() + { + VisualGroup group = new VisualGroup(); + group.HorizontalItemSpacing = 0; + group.ArrangeInvalid += ButtonGroupArrangeInvalid; + group.RenderInvalid += ButtonGroupRenderInvalid; + group.ResetMouseHover += ButtonGroupResetMouseHover; + _ButtonGroup = group; + } + + private void ButtonGroupRenderInvalid(object sender, EventArgs e) + { + InvalidateNonClient(); + } + + private void ButtonGroupArrangeInvalid(object sender, EventArgs e) + { + InvalidateNonClient(); + } + + private void ButtonGroupResetMouseHover(object sender, EventArgs e) + { + DevComponents.AdvTree.Interop.WinApi.ResetHover(this); + } + + private bool _MouseOver = false; + private PaintInfo CreatePaintInfo(Graphics g) + { + PaintInfo p = new PaintInfo(); + p.Graphics = g; + p.DefaultFont = this.Font; + p.ForeColor = this.ForeColor; + p.RenderOffset = new System.Drawing.Point(); + Size s = this.Size; + bool disposeStyle = false; + ElementStyle style = GetBorderStyle(out disposeStyle); + s.Height -= (ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.BottomWhiteSpace(style, eSpacePart.Border)) + 2; + s.Width -= (ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border)) + 2; + p.AvailableSize = s; + p.ParentEnabled = this.Enabled; + p.MouseOver = _MouseOver || this.Focused; + if (disposeStyle) style.Dispose(); + return p; + } + + private bool RenderButtons + { + get + { + return (this.ScrollBars == ScrollBars.None) && (_ButtonCustom != null && _ButtonCustom.Visible || _ButtonCustom2 != null && _ButtonCustom2.Visible); + } + } + + private void PaintButtons(Graphics g) + { + PaintInfo p = CreatePaintInfo(g); + if (!_ButtonGroup.IsLayoutValid) + { + _ButtonGroup.PerformLayout(p); + } + bool disposeStyle = false; + ElementStyle style = GetBorderStyle(out disposeStyle); + //p.RenderOffset = new Point(this.Width - ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border) - _ButtonGroup.Size.Width, ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border)); + _ButtonGroup.RenderBounds = new Rectangle(this.Width - (ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border) + 1) - _ButtonGroup.Size.Width, ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + 1, + _ButtonGroup.Size.Width, _ButtonGroup.Size.Height); + _ButtonGroup.ProcessPaint(p); + if (disposeStyle) style.Dispose(); + } + + private Cursor _ControlCursor = null; + protected override void OnMouseMove(MouseEventArgs e) + { + if (RenderButtons) + { + _ButtonGroup.ProcessMouseMove(e); + if (_ButtonGroup.RenderBounds.Contains(e.X, e.Y)) + { + if (_ControlCursor == null) + { + _InternalCursorChange = true; + _ControlCursor = this.Cursor; + this.Cursor = Cursors.Arrow; + _InternalCursorChange = false; + } + } + else if (_ControlCursor != null) + { + _InternalCursorChange = true; + this.Cursor = _ControlCursor; + _ControlCursor = null; + _InternalCursorChange = false; + } + } + base.OnMouseMove(e); + } + protected override void OnMouseEnter(EventArgs e) + { + _MouseOver = true; + base.OnMouseEnter(e); + } + protected override void OnMouseLeave(EventArgs e) + { + _MouseOver = false; + if (RenderButtons) + { + _ButtonGroup.ProcessMouseLeave(); + if (_ControlCursor != null) + { + _InternalCursorChange = true; + this.Cursor = _ControlCursor; + _ControlCursor = null; + _InternalCursorChange = false; + } + } + base.OnMouseLeave(e); + } + private bool _InternalCursorChange = false; + protected override void OnCursorChanged(EventArgs e) + { + if (_ControlCursor != null && !_InternalCursorChange) + _ControlCursor = this.Cursor; + base.OnCursorChanged(e); + } + protected override void OnMouseDown(MouseEventArgs e) + { + if (RenderButtons) + _ButtonGroup.ProcessMouseDown(e); + base.OnMouseDown(e); + } + protected override void OnMouseUp(MouseEventArgs e) + { + if (RenderButtons) + _ButtonGroup.ProcessMouseUp(e); + base.OnMouseUp(e); + } + protected override void OnMouseHover(EventArgs e) + { + if (RenderButtons) + _ButtonGroup.ProcessMouseHover(e); + base.OnMouseHover(e); + } +#endif + #endregion + + #region INonClientControl Members + void INonClientControl.BaseWndProc(ref Message m) + { + base.WndProc(ref m); + } + + //CreateParams INonClientControl.ControlCreateParams + //{ + // get { return base.CreateParams; } + //} + + ItemPaintArgs INonClientControl.GetItemPaintArgs(System.Drawing.Graphics g) + { + ItemPaintArgs pa = new ItemPaintArgs(this as IOwner, this, g, GetColorScheme()); + pa.Renderer = this.GetRenderer(); + pa.DesignerSelection = false; // m_DesignerSelection; + pa.GlassEnabled = !this.DesignMode && WinApi.IsGlassEnabled; + return pa; + } + + ElementStyle INonClientControl.BorderStyle + { + get { bool disposeStyle = false; return GetBorderStyle(out disposeStyle); } + } + + void INonClientControl.PaintBackground(PaintEventArgs e) + { + if (this.Parent == null) return; + Type t = typeof(Control); + MethodInfo mi = t.GetMethod("PaintTransparentBackground", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(PaintEventArgs), typeof(Rectangle) }, null); + if (mi != null) + { + mi.Invoke(this, new object[] { e, new Rectangle(0, 0, this.Width, this.Height) }); + } + } + + private ColorScheme m_ColorScheme = null; + /// + /// Returns the color scheme used by control. Color scheme for Office2007 style will be retrived from the current renderer instead of + /// local color scheme referenced by ColorScheme property. + /// + /// An instance of ColorScheme object. + protected virtual ColorScheme GetColorScheme() + { + BaseRenderer r = GetRenderer(); + if (r is Office2007Renderer) + return ((Office2007Renderer)r).ColorTable.LegacyColors; + if (m_ColorScheme == null) + m_ColorScheme = new ColorScheme(eDotNetBarStyle.Office2007); + return m_ColorScheme; + } + + IntPtr INonClientControl.Handle + { + get { return this.Handle; } + } + + int INonClientControl.Width + { + get { return this.Width; } + } + + int INonClientControl.Height + { + get { return this.Height; } + } + + bool INonClientControl.IsHandleCreated + { + get { return this.IsHandleCreated; } + } + + Point INonClientControl.PointToScreen(Point client) + { + return this.PointToScreen(client); + } + + Color INonClientControl.BackColor + { + get { return this.BackColor; } + } + + void INonClientControl.AdjustClientRectangle(ref Rectangle r) + { +#if FRAMEWORK20 + if (RenderButtons) + { + if (!_ButtonGroup.IsLayoutValid) + { + using (Graphics g = this.CreateGraphics()) + { + PaintInfo p = CreatePaintInfo(g); + _ButtonGroup.PerformLayout(p); + } + } + r.Width -= _ButtonGroup.Size.Width + 1; + } +#endif + } + + void INonClientControl.AdjustBorderRectangle(ref Rectangle r) { } + + void INonClientControl.RenderNonClient(Graphics g) + { +#if FRAMEWORK20 + if (RenderButtons) + PaintButtons(g); +#endif + } + + private Color _DisabledBackColor = Color.Empty; + /// + /// Specifies back color when Enabled=false + /// + [Browsable(true), Category("Appearance"), Description("Specifies back color when Enabled=false")] + public Color DisabledBackColor + { + get { return _DisabledBackColor; } + set + { + _DisabledBackColor = value; + if (!Enabled) this.Invalidate(); + } + } + public bool ShouldSerializeDisabledBackColor() + { + return !_DisabledBackColor.IsEmpty; + } + public void ResetDisabledBackColor() + { + DisabledBackColor = Color.Empty; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TextBoxX.ico b/PROMS/DotNetBar Source Code/Controls/TextBoxX.ico new file mode 100644 index 00000000..71065394 Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/TextBoxX.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/TokenEditor.ico b/PROMS/DotNetBar Source Code/Controls/TokenEditor.ico new file mode 100644 index 00000000..58a96c2b Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/TokenEditor.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/TokenEditor/EditToken.cs b/PROMS/DotNetBar Source Code/Controls/TokenEditor/EditToken.cs new file mode 100644 index 00000000..0a18ca01 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TokenEditor/EditToken.cs @@ -0,0 +1,407 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Class represents single token in TokenEditor control. + /// + [ToolboxItem(false)] + public class EditToken : Component + { + #region Constructor + /// + /// Initializes a new instance of the EditToken class. + /// + /// Indicates token value. + public EditToken(string value) + { + _Value = value; + } + /// + /// Initializes a new instance of the EditToken class. + /// + /// Indicates token value + /// Indicates token text + public EditToken(string value, string text) + { + _Value = value; + _Text = text; + } + /// + /// Initializes a new instance of the EditToken class. + /// + /// Indicates token value + /// Indicates token text + /// Indicates token image + public EditToken(string value, string text, Image image) + { + _Value = value; + _Text = text; + _Image = image; + } + #endregion + + #region Implementation + private eTokenPart _MouseOverPart; + private string _Value = ""; + /// + /// Indicates the token value, for example an email token has email address as token Value and full name as token Text. + /// + [DefaultValue(""), Category("Data"), Description("Indicates the token value, for example an email token has email address as token Value and full name as token Text.")] + public string Value + { + get { return _Value; } + set + { + if (value != _Value) + { + string oldValue = _Value; + _Value = value; + OnValueChanged(oldValue, value); + } + } + } + /// + /// Called when Value property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnValueChanged(string oldValue, string newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Value")); + } + + private string _Text = ""; + /// + /// Indicates the token text, for example an email token has email address as token Value and full name as token Text. + /// + [DefaultValue(""), Category("Data"), Description("Indicates the token text, for example an email token has email address as token Value and full name as token Text.")] + public string Text + { + get { return _Text; } + set + { + if (value != _Text) + { + string oldValue = _Text; + _Text = value; + OnTextChanged(oldValue, value); + } + } + } + /// + /// Called when Text property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextChanged(string oldValue, string newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Text")); + + } + + private object _Tag = null; + /// + /// Gets or sets custom data associated with the object. + /// + [DefaultValue((string)null), Localizable(false), TypeConverter(typeof(StringConverter)), Category("Data"), Description("Custom data associated with the object")] + public object Tag + { + get { return _Tag; } + set { _Tag = value; } + } + + private Rectangle _Bounds = Rectangle.Empty; + /// + /// Gets the display bounds of the token, if displayed, inside of TokenEditor control. + /// + [Browsable(false)] + public Rectangle Bounds + { + get { return _Bounds; } + internal set { _Bounds = value; } + } + + private Image _Image = null; + /// + /// Indicates the image that is displayed next to the token + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the image that is displayed next to the token")] + public Image Image + { + get { return _Image; } + set + { + if (value != _Image) + { + Image oldValue = _Image; + _Image = value; + OnImageChanged(oldValue, value); + } + } + } + /// + /// Called when Image property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnImageChanged(Image oldValue, Image newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Image")); + } + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get { return _SymbolRealized; } + } + private string _Symbol = "", _SymbolRealized = ""; + /// + /// Indicates the symbol displayed on face of the token instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the token instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return _Symbol; } + set + { + if (value != _Symbol) + { + string oldValue = _Symbol; + _Symbol = value; + OnSymbolChanged(oldValue, value); + } + } + } + /// + /// Called when Symbol property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolChanged(string oldValue, string newValue) + { + if (string.IsNullOrEmpty(newValue)) + _SymbolRealized = ""; + else + _SymbolRealized = Symbols.GetSymbol(newValue); + //OnPropertyChanged(new PropertyChangedEventArgs("Symbol")); + this.Invalidate(); + } + + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [Browsable(false), DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return _SymbolSet; } + set + { + if (_SymbolSet != value) + { + eSymbolSet oldValue = _SymbolSet; + _SymbolSet = value; + OnSymbolSetChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSet property value changes. + /// + /// Indciates old value + /// Indicates new value + protected virtual void OnSymbolSetChanged(eSymbolSet oldValue, eSymbolSet newValue) + { + this.Invalidate(); + } + + private void Invalidate() + { + //throw new NotImplementedException(); + } + + private Color _SymbolColor = Color.Empty; + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return _SymbolColor; } + set { _SymbolColor = value; this.Invalidate(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return !_SymbolColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + this.SymbolColor = Color.Empty; + } + + private string _Tooltip = ""; + /// + /// Indicates tooltip that is displayed when mouse is over the token and token is selected. + /// + [DefaultValue(""), Category("Behavior"), Description("Indicates tooltip that is displayed when mouse is over the token and token is selected")] + public string Tooltip + { + get { return _Tooltip; } + set + { + if (value !=_Tooltip) + { + string oldValue = _Tooltip; + _Tooltip = value; + OnTooltipChanged(oldValue, value); + } + } + } + /// + /// Called when Tooltip property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTooltipChanged(string oldValue, string newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("Tooltip")); + + } + + /// + /// Gets the part of the token mouse is over. Valid only when token is selected. + /// + [Browsable(false)] + public eTokenPart MouseOverPart + { + get { return _MouseOverPart; } + internal set + { + if (value !=_MouseOverPart) + { + eTokenPart oldValue = _MouseOverPart; + _MouseOverPart = value; + OnMouseOverPartChanged(oldValue, value); + } + } + } + /// + /// Called when MouseOverPart property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnMouseOverPartChanged(eTokenPart oldValue, eTokenPart newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("MouseOverPart")); + + } + + private Rectangle _RemoveButtonBounds = Rectangle.Empty; + /// + /// Gets the bounds of the remove button if displayed. Valid only when token is selected. + /// + [Browsable(false)] + public Rectangle RemoveButtonBounds + { + get + { + return _RemoveButtonBounds; + } + internal set + { + _RemoveButtonBounds = value; + } + } + private Rectangle _ImageBounds = Rectangle.Empty; + /// + /// Gets the bounds of the image if displayed. Valid only when token is selected. + /// + [Browsable(false)] + public Rectangle ImageBounds + { + get + { + return _ImageBounds; + } + internal set + { + _ImageBounds = value; + } + } + + private bool _IsSelected = false; + /// + /// Indicates whether token is selected. + /// + [Browsable(false)] + public bool IsSelected + { + get + { + return _IsSelected; + } + internal set + { + _IsSelected = value; + } + } + + private bool _IsFocused = false; + /// + /// Indicates whether token is focused while selected. + /// + [Browsable(false)] + public bool IsFocused + { + get + { + return _IsFocused; + } + internal set + { + _IsFocused = value; + } + } + #endregion + } + + /// + /// Defines the token parts. + /// + public enum eTokenPart + { + /// + /// Identifies no token part. + /// + None, + /// + /// Identifies the token body/text. + /// + Token, + /// + /// Identifies the remove token button. + /// + RemoveButton, + /// + /// Identifies the token image. + /// + Image + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TokenEditor/TokenEditor.cs b/PROMS/DotNetBar Source Code/Controls/TokenEditor/TokenEditor.cs new file mode 100644 index 00000000..28731701 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TokenEditor/TokenEditor.cs @@ -0,0 +1,2382 @@ +using DevComponents.DotNetBar.Primitives; +using DevComponents.DotNetBar.Rendering; +using DevComponents.DotNetBar.TextMarkup; +using DevComponents.Editors; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(true), ToolboxBitmap(typeof(TokenEditor), "Controls.TokenEditor.ico")] + [Designer("DevComponents.DotNetBar.Design.TokenEditorDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + [DefaultEvent("SelectedTokensChanged")] + public class TokenEditor : Control, IMessageHandlerClient + { + #region Constructor + private TextBoxX _EditBox; + private VScrollBarAdv _VScrollBar = null; + /// + /// Initializes a new instance of the TokenEditor class. + /// + public TokenEditor() + { + _SelectedTokens = new CustomCollection(); + _SelectedTokens.CollectionChanged += SelectedTokensCollectionChanged; + _Tokens = new CustomCollection(); + _Tokens.CollectionChanged += TokensCollectionChanged; + this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | + ControlStyles.Opaque | ControlStyles.ResizeRedraw | ControlStyles.Selectable | + ControlStyles.StandardDoubleClick | DisplayHelp.DoubleBufferFlag, true); + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.Class = ElementStyleClassKeys.DateTimeInputBackgroundKey; + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + + _EditBox = new TextBoxX(); + _EditBox.BorderStyle = BorderStyle.None; + _EditBox.Visible = false; + _EditBox.TextChanged += EditBoxTextChanged; + _EditBox.KeyDown += EditBoxKeyDown; + _EditBox.GotFocus += EditBoxGotFocus; + this.Controls.Add(_EditBox); + _EditBox.SetAutoHeight(); + + _VScrollBar = new VScrollBarAdv(); + _VScrollBar.Visible = false; + _VScrollBar.Scroll += VScrollBarScroll; + this.Controls.Add(_VScrollBar); + + VisualGroup group = new VisualGroup(); + group.HorizontalItemSpacing = 0; + group.ArrangeInvalid += ButtonGroupArrangeInvalid; + group.RenderInvalid += ButtonGroupRenderInvalid; + group.ResetMouseHover += ButtonGroupResetMouseHover; + _ButtonGroup = group; + CreateButtons(); + } + + protected override void Dispose(bool disposing) + { + if (_MessageHandlerInstalled) + { + MessageHandler.UnregisterMessageClient(this); + _MessageHandlerInstalled = false; + } + base.Dispose(disposing); + } + #endregion + + #region Implementation + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + if (Dpi.RecordScalePerControl) + Dpi.SetScaling(factor); + base.ScaleControl(factor, specified); + _EditBox.SetAutoHeight(); + LayoutTokens(); + } + + private void EditBoxGotFocus(object sender, EventArgs e) + { + FocusToken = null; + } + private TokenEditorColorTable GetTokenColorTable() + { + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.TokenEditor; + } + protected override void OnPaint(PaintEventArgs e) + { + if ((this.BackColor.IsEmpty || this.BackColor == Color.Transparent)) + { + base.OnPaintBackground(e); + } + + if (_BackgroundStyle != null) + _BackgroundStyle.SetColorScheme(this.GetColorScheme()); + TokenEditorColorTable colorTable = GetTokenColorTable(); + PaintBackground(e); + Rectangle clientBounds = GetClientBounds(); + e.Graphics.SetClip(clientBounds); + + if (this.WatermarkEnabled && this.WatermarkText.Length > 0 && this.IsWatermarkRendered) + { + DrawWatermark(e.Graphics); + } + + foreach (EditToken token in _SelectedTokens) + { + PaintToken(token, e, colorTable); + } + + PaintButtons(e.Graphics); + + e.Graphics.ResetClip(); + base.OnPaint(e); + } + + private void PaintToken(EditToken token, PaintEventArgs e, TokenEditorColorTable colorTable) + { + Graphics g = e.Graphics; + Rectangle r = token.Bounds; + r.Offset(_AutoScrollPosition); + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.HighQuality; + + Color textColor = colorTable.Normal.TextColor; + LinearGradientColorTable background = colorTable.Normal.Background; + + if (token.IsFocused) + { + textColor = colorTable.Focused.TextColor; + background = colorTable.Focused.Background; + } + else if (token.MouseOverPart == eTokenPart.Token || token.MouseOverPart == eTokenPart.Image) + background = colorTable.MouseOver.Background; + + DisplayHelp.FillRoundedRectangle(g, r, 2, background.Start, background.End, background.GradientAngle); + + g.SmoothingMode = sm; + string text = GetTokenText(token); + Rectangle rText = r; + + if (EffectiveRemoveTokenButtonVisible) + { + Rectangle removeBounds = new Rectangle(r.X, r.Y + (r.Height - _RemoveTokenButtonSize.Height) / 2, + _RemoveTokenButtonSize.Width, _RemoveTokenButtonSize.Height); + Color closeTextColor = textColor; + if (token.MouseOverPart == eTokenPart.RemoveButton) + { + Office2007ColorTable ct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + Office2007ButtonItemColorTable buttonColorTable = ct.ButtonItemColors[Enum.GetName(typeof(eButtonColor), eButtonColor.OrangeWithBackground)]; + Office2007ButtonItemPainter.PaintBackground(g, buttonColorTable.MouseOver, removeBounds, RoundRectangleShapeDescriptor.RectangleShape); + closeTextColor = buttonColorTable.MouseOver.Text; + //g.FillRectangle(Brushes.Red, removeBounds); + } + + float symbolSize = Math.Max(1, Math.Min(removeBounds.Width, removeBounds.Height) * 72 / g.DpiX - 1.5f); + TextDrawing.DrawStringLegacy(g, "\uf00d", Symbols.GetFont(symbolSize, eSymbolSet.Awesome), + closeTextColor, removeBounds, eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter); + + token.RemoveButtonBounds = removeBounds; + rText.X = removeBounds.Right + _TokenPartSpacing; + rText.Width -= rText.Right - r.Right; + } + + if (!string.IsNullOrEmpty(token.SymbolRealized)) + { + Rectangle imageBounds = new Rectangle(rText.X, r.Y, r.Height, r.Height); + float symbolSize = Math.Max(1, Math.Min(imageBounds.Width, imageBounds.Height) * 72 / g.DpiX - 1.5f); + TextDrawing.DrawStringLegacy(g, token.SymbolRealized, Symbols.GetFont(symbolSize, token.SymbolSet), + (token.SymbolColor.IsEmpty ? textColor : token.SymbolColor), + imageBounds, eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter); + token.ImageBounds = imageBounds; + rText.X = imageBounds.Right + _TokenPartSpacing; + rText.Width -= rText.Right - r.Right; + } + else if (token.Image != null) + { + Rectangle imageBounds = new Rectangle(rText.X, r.Y, token.ImageBounds.Width, token.Image.Height); + g.DrawImage(token.Image, imageBounds); + token.ImageBounds = imageBounds; + rText.X = imageBounds.Right + _TokenPartSpacing; + rText.Width -= rText.Right - r.Right; + } + TextDrawing.DrawString(g, text, this.Font, textColor, rText, eTextFormat.Default | eTextFormat.VerticalCenter); + } + + protected virtual void PaintBackground(PaintEventArgs e) + { + Graphics g = e.Graphics; + Rectangle r = this.ClientRectangle; + ElementStyle style = _BackgroundStyle; + + if (!this.BackColor.IsEmpty && this.BackColor != Color.Transparent) + { + DisplayHelp.FillRectangle(g, r, this.BackColor); + } + + if (this.BackgroundImage != null) + base.OnPaintBackground(e); + + if (style.Custom) + { + SmoothingMode sm = g.SmoothingMode; + //if (m_AntiAlias) + // g.SmoothingMode = SmoothingMode.HighQuality; + ElementStyleDisplayInfo displayInfo = new ElementStyleDisplayInfo(style, e.Graphics, r); + ElementStyleDisplay.Paint(displayInfo); + //if (m_AntiAlias) + // g.SmoothingMode = sm; + } + } + + protected override void OnResize(EventArgs e) + { + LayoutTokens(); + base.OnResize(e); + } + + /// + /// Gets or sets the location of the auto-scroll position. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false), Description("Indicates location of the auto-scroll position.")] + public Point AutoScrollPosition + { + get + { + return _AutoScrollPosition; + } + set + { + if (_AutoScrollPosition == value) return; + _AutoScrollPosition = value; + if (_VScrollBar != null && _VScrollBar.Value != -_AutoScrollPosition.Y) + _VScrollBar.Value = Math.Min(_VScrollBar.Maximum, Math.Max(_VScrollBar.Minimum, -_AutoScrollPosition.Y)); + RepositionEditTextBox(); + Invalidate(); + } + } + + private Rectangle GetClientBounds() + { + bool disposeStyle = false; + ElementStyle style = ElementStyleDisplay.GetElementStyle(_BackgroundStyle, out disposeStyle); + Rectangle clientRect = this.ClientRectangle; + clientRect.X += style.PaddingLeft; + clientRect.Width -= style.PaddingHorizontal; + clientRect.Y += style.PaddingTop; + clientRect.Height -= style.PaddingVertical; + if (disposeStyle) + style.Dispose(); + style = null; + + return clientRect; + } + + private Point _AutoScrollPosition = Point.Empty; + private int _TokenSpacing = 2; + private int _TokenPartSpacing = 2; // Spacing between different parts of the token, like between image and text and image and close button etc. Its spacing between each part. + private readonly Size _TokenPadding = new Size(2, 2); + private void LayoutTokens() + { + if (!this.IsHandleCreated || this.IsDisposed || this.Width == 0 || this.Height == 0) return; + + int lineCount = 0; + Rectangle clientRect = GetClientBounds(); + Graphics g = this.CreateGraphics(); + Size totalSize = LayoutTokens(g, clientRect, out lineCount); + + if (_AutoSizeHeight) + { + int heightLines = Math.Min(_MaxHeightLines, lineCount); + int newHeight = (int)(Math.Ceiling((double)totalSize.Height / lineCount) * heightLines) + (this.Height - clientRect.Height); + if (_MaxHeightLines == 1) + newHeight = GetSingleLineTextBoxHeight(); + if (newHeight != this.Height) + { + g.Dispose(); + this.Height = newHeight; + return; + } + } + + if (totalSize.Height > clientRect.Height) + { + Rectangle reducedBounds = clientRect; + + int visibleLines = (int)(clientRect.Height / (Math.Ceiling((double)totalSize.Height / lineCount))); + if (_DropDownButtonVisible && visibleLines <= 2 || visibleLines == 1) + { + // Using scroll button due to space limitation + _VScrollBar.Visible = false; + _ScrollButton.Visible = true; + reducedBounds.Width -= SystemInformation.VerticalScrollBarWidth * (_DropDownButtonVisible ? 2 : 1); + if (visibleLines > 1) + _ButtonGroup.Orientation = eOrientation.Vertical; + else + _ButtonGroup.Orientation = eOrientation.Horizontal; + } + else + { + int buttonOffset = (_DropDownButtonVisible ? GetButtonHeight() + 1 : 0); + // Activate Scroll-bar + _VScrollBar.Bounds = new Rectangle(clientRect.Right - SystemInformation.VerticalScrollBarWidth, + clientRect.Y + buttonOffset, + SystemInformation.VerticalScrollBarWidth, + clientRect.Height - buttonOffset); + _VScrollBar.Visible = true; + _ScrollButton.Visible = false; + reducedBounds.Width -= _VScrollBar.Width; + } + + totalSize = LayoutTokens(g, reducedBounds, out lineCount); + + _VScrollBar.Maximum = totalSize.Height; + _VScrollBar.LargeChange = clientRect.Height; + if (this.SelectedTokens.Count > 0) + _VScrollBar.SmallChange = this.SelectedTokens[0].Bounds.Height; + else + _VScrollBar.SmallChange = 17; + } + else + { + _VScrollBar.Visible = false; + _AutoScrollPosition = Point.Empty; + _ScrollButton.Visible = false; + } + + g.Dispose(); + + RepositionEditTextBox(); + EnsureTextBoxScrollPosition(); + UpdateButtons(); + + this.Invalidate(); + } + + private int GetSingleLineTextBoxHeight() + { + Font font = this.Font; + return font.Height + ((SystemInformation.BorderSize.Height * 4) + 4); + } + private Size LayoutTokens(Graphics g, Rectangle clientRect, out int lineCount) + { + lineCount = 0; + if (!this.IsHandleCreated || this.IsDisposed) return Size.Empty; + + clientRect.Inflate(-1, -1); + Font font = this.Font; + Size totalSize = Size.Empty; + int singleLineTextBoxHeight = GetSingleLineTextBoxHeight() - 2; // 2 is for top and bottom border + + if (_SelectedTokens.Count == 0) + { + lineCount = 1; + totalSize = new Size(clientRect.Width, singleLineTextBoxHeight); + _EditBoxLocation = new Point(clientRect.X, clientRect.Y + (totalSize.Height - _EditBox.Height) / 2); + _EditBox.Width = clientRect.Width - (_DropDownButtonVisible ? SystemInformation.VerticalScrollBarWidth : 0); + + return totalSize; + } + + int largestTokenHeight = 0; + foreach (EditToken token in _SelectedTokens) + { + token.RemoveButtonBounds = Rectangle.Empty; + token.ImageBounds = Rectangle.Empty; + string text = GetTokenText(token); + Size size = TextDrawing.MeasureString(g, (string.IsNullOrEmpty(text) ? "A" : text), font); + size.Width += _TokenPadding.Width * 2; + size.Height += _TokenPadding.Height * 2; + if (EffectiveRemoveTokenButtonVisible) + { + size.Width += _RemoveTokenButtonSize.Width + _TokenPartSpacing; + if (_RemoveTokenButtonSize.Height > size.Height) + size.Height = _RemoveTokenButtonSize.Height; + } + + if (!string.IsNullOrEmpty(token.SymbolRealized)) + { + size.Width += size.Height + _TokenPartSpacing; + } + else if (token.Image != null) + { + size.Width += token.Image.Width + _TokenPartSpacing; + if (token.Image.Height > size.Height) + size.Height = token.Image.Height; + } + largestTokenHeight = Math.Max(largestTokenHeight, size.Height); + token.Bounds = new Rectangle(Point.Empty, size); + } + + lineCount = 1; + totalSize.Height = largestTokenHeight; + Point currentPos = clientRect.Location; + + foreach (EditToken token in _SelectedTokens) + { + Rectangle tokenBounds = new Rectangle(currentPos.X, currentPos.Y, token.Bounds.Width, largestTokenHeight); + if (tokenBounds.Right > clientRect.Right && currentPos.X > clientRect.X) + { + currentPos.Y += largestTokenHeight + _TokenSpacing; + currentPos.X = clientRect.X; + tokenBounds.Y = currentPos.Y; + tokenBounds.X = currentPos.X; + totalSize.Height += largestTokenHeight + _TokenSpacing; + lineCount++; + } + currentPos.X += tokenBounds.Width + _TokenSpacing; + token.Bounds = tokenBounds; + + if (tokenBounds.Right - clientRect.X > totalSize.Width) + totalSize.Width = tokenBounds.Right - clientRect.X; + } + + if (clientRect.Right - currentPos.X < _TextBoxMinWidth) + { + currentPos.Y += largestTokenHeight + _TokenSpacing; + currentPos.X = clientRect.X; + lineCount++; + totalSize.Height += largestTokenHeight + _TokenSpacing; + } + + if (lineCount == 1) + totalSize.Height = Math.Max(totalSize.Height, singleLineTextBoxHeight); + + _EditBoxLocation = new Point(currentPos.X, currentPos.Y + (largestTokenHeight - _EditBox.Height) / 2); + _EditBox.Width = clientRect.Right - currentPos.X - (lineCount == 1 && _DropDownButtonVisible ? SystemInformation.VerticalScrollBarWidth : 0); + + return totalSize; + } + + private Point _EditBoxLocation = Point.Empty; + private void RepositionEditTextBox() + { + Point loc = _EditBoxLocation; + loc.Offset(_AutoScrollPosition); + _EditBox.Location = loc; + } + + private void VScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.NewValue != e.OldValue) + { + _AutoScrollPosition.Y = -e.NewValue; + RepositionEditTextBox(); + this.Invalidate(); + } + } + private const int _TextBoxMinWidth = 36; + + protected override void OnHandleCreated(EventArgs e) + { + _EditBox.SetAutoHeight(); + LayoutTokens(); + base.OnHandleCreated(e); + } + + private string GetTokenText(EditToken token) + { + if (!string.IsNullOrEmpty(token.Text)) + return token.Text; + return token.Value; + } + + /// + /// Returns the color scheme used by control. Color scheme for Office2007 style will be retrieved from the current renderer instead of + /// local color scheme referenced by ColorScheme property. + /// + /// An instance of ColorScheme object. + protected virtual ColorScheme GetColorScheme() + { + BaseRenderer r = Rendering.GlobalManager.Renderer; + if (r is Office2007Renderer) + return ((Office2007Renderer)r).ColorTable.LegacyColors; + return new ColorScheme(); + } + + private ElementStyle _BackgroundStyle = null; + /// + /// Specifies the background style of the control. + /// + [Browsable(true), Category("Style"), Description("Gets or sets bar background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return _BackgroundStyle; } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _BackgroundStyle.StyleChanged -= new EventHandler(this.VisualPropertyChanged); + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + this.Invalidate(); + } + private void VisualPropertyChanged(object sender, EventArgs e) + { + this.Invalidate(); + } + + private CustomCollection _SelectedTokens; + /// + /// Gets the collection of the selected tokens. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CustomCollection SelectedTokens + { + get + { + return _SelectedTokens; + } + } + private void SelectedTokensCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + foreach (object item in e.NewItems) + { + ((EditToken)item).IsSelected = true; + } + } + else if (e.Action == NotifyCollectionChangedAction.Remove) + { + foreach (object item in e.OldItems) + { + ((EditToken)item).IsSelected = false; + } + } + else if (e.Action == NotifyCollectionChangedAction.Replace) + { + foreach (object item in e.NewItems) + { + ((EditToken)item).IsSelected = true; + } + foreach (object item in e.OldItems) + { + ((EditToken)item).IsSelected = false; + } + } + else if (e.Action == NotifyCollectionChangedAction.Reset) + { + foreach (EditToken item in _Tokens) + { + item.IsSelected = false; + } + } + + LayoutTokens(); + UpdateText(); + UpdateEditBoxWatermark(); + OnSelectedTokensChanged(EventArgs.Empty); + } + + /// + /// Occurs when SelectedTokens collection changes. + /// + [Description("Occurs when SelectedTokens collection changes.")] + public event EventHandler SelectedTokensChanged; + /// + /// Raises SelectedTokensChanged event. + /// + /// Provides event arguments. + protected virtual void OnSelectedTokensChanged(EventArgs e) + { + EventHandler handler = SelectedTokensChanged; + if (handler != null) + handler(this, e); + } + + private CustomCollection _Tokens; + /// + /// Gets the collection of the tokens available for selection. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CustomCollection Tokens + { + get + { + return _Tokens; + } + } + private void TokensCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + + } + + private bool EffectiveRemoveTokenButtonVisible + { + get + { + return _RemoveTokenButtonVisible && !_ReadOnly; + } + } + private Size _RemoveTokenButtonSize = new Size(14, 14); + private bool _RemoveTokenButtonVisible = true; + /// + /// Indicates whether remove token button is displayed on individual tokens so they can be removed from the selection. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether remove token button is displayed on individual tokens so they can be removed from the selection.")] + public bool RemoveTokenButtonVisible + { + get { return _RemoveTokenButtonVisible; } + set + { + if (value != _RemoveTokenButtonVisible) + { + bool oldValue = _RemoveTokenButtonVisible; + _RemoveTokenButtonVisible = value; + OnRemoveTokenButtonVisibleChanged(oldValue, value); + } + } + } + /// + /// Called when RemoveTokenButtonVisible property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnRemoveTokenButtonVisibleChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("RemoveTokenButtonVisible")); + if (_SelectedTokens.Count > 0) + LayoutTokens(); + } + + /// + /// Returns the token from SelectedTokens at specified position or null/nothing if no token is at given location. + /// + /// Location in client coordinates to test. + /// EditToken instance or null/nothing + public EditToken GetSelectedTokenAt(Point p) + { + foreach (EditToken token in _SelectedTokens) + { + Rectangle tokenBounds = token.Bounds; + tokenBounds.Offset(_AutoScrollPosition); + if (tokenBounds.Contains(p)) + return token; + } + return null; + } + + private EditToken _MouseOverToken = null; + private EditToken MouseOverToken + { + get + { + return _MouseOverToken; + } + set + { + if (_MouseOverToken != value) + { + if (_MouseOverToken != null) + _MouseOverToken = value; + this.Invalidate(); + } + } + } + + /// + /// Occurs when mouse enters one of the SelectedTokens token. + /// + [Description("Occurs when mouse enters one of the SelectedTokens token.")] + public event EventHandler TokenMouseEnter; + /// + /// Raises TokenMouseEnter event. + /// + /// Provides event arguments. + protected virtual void OnTokenMouseEnter(object sender, EventArgs e) + { + EventHandler handler = TokenMouseEnter; + if (handler != null) + handler(sender, e); + } + /// + /// Occurs when mouse leaves one of the SelectedTokens token. + /// + [Description("Occurs when mouse leaves one of the SelectedTokens token.")] + public event EventHandler TokenMouseLeave; + /// + /// Raises TokenMouseLeave event. + /// + /// Provides event arguments. + protected virtual void OnTokenMouseLeave(object sender, EventArgs e) + { + HideToolTip(); + EventHandler handler = TokenMouseLeave; + if (handler != null) + handler(sender, e); + } + + /// + /// Occurs when mouse clicks one of the SelectedTokens token. + /// + [Description("Occurs when mouse clicks one of the SelectedTokens token.")] + public event MouseEventHandler TokenMouseClick; + /// + /// Raises TokenMouseClick event. + /// + /// Provides event arguments. + protected virtual void OnTokenMouseClick(object sender, MouseEventArgs e) + { + MouseEventHandler handler = TokenMouseClick; + if (handler != null) + handler(sender, e); + } + + /// + /// Occurs when mouse double clicks one of the SelectedTokens token. + /// + [Description("Occurs when mouse double clicks one of the SelectedTokens token.")] + public event MouseEventHandler TokenMouseDoubleClick; + /// + /// Raises TokenMouseClick event. + /// + /// Provides event arguments. + protected virtual void OnTokenMouseDoubleClick(object sender, MouseEventArgs e) + { + MouseEventHandler handler = TokenMouseDoubleClick; + if (handler != null) + handler(sender, e); + } + + /// + /// Occurs when mouse hovers one of the SelectedTokens token. + /// + [Description("Occurs when mouse hovers one of the SelectedTokens token.")] + public event EventHandler TokenMouseHover; + /// + /// Raises TokenMouseHover event. + /// + /// Provides event arguments. + protected virtual void OnTokenMouseHover(object sender, EventArgs e) + { + EventHandler handler = TokenMouseHover; + if (handler != null) + handler(sender, e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + EditToken token = GetSelectedTokenAt(e.Location); + if (token != _MouseOverToken) + { + if (_MouseOverToken != null) + { + _MouseOverToken.MouseOverPart = eTokenPart.None; + OnTokenMouseLeave(_MouseOverToken, e); + } + _MouseOverToken = token; + this.Invalidate(); + DevComponents.AdvTree.Interop.WinApi.ResetHover(this); + if (_MouseOverToken != null) + OnTokenMouseEnter(_MouseOverToken, e); + } + if (_MouseOverToken != null) + { + eTokenPart oldMouseOverPart = _MouseOverToken.MouseOverPart; + if (EffectiveRemoveTokenButtonVisible && !_MouseOverToken.RemoveButtonBounds.IsEmpty && _MouseOverToken.RemoveButtonBounds.Contains(e.Location)) + _MouseOverToken.MouseOverPart = eTokenPart.RemoveButton; + else if (!_MouseOverToken.ImageBounds.IsEmpty && _MouseOverToken.ImageBounds.Contains(e.Location)) + _MouseOverToken.MouseOverPart = eTokenPart.Image; + else + _MouseOverToken.MouseOverPart = eTokenPart.Token; + if (oldMouseOverPart != _MouseOverToken.MouseOverPart) + this.Invalidate(); + } + if (_ButtonGroup.Visible) + _ButtonGroup.ProcessMouseMove(e); + base.OnMouseMove(e); + } + protected override void OnMouseDown(MouseEventArgs e) + { + HideToolTip(); + if (_MouseOverToken == null && !_ReadOnly && !(_ButtonGroup.Visible && _ButtonGroup.RenderBounds.Contains(e.Location))) + { + ShowEditTextBox(); + } + else + this.Select(); + if (_ButtonGroup.Visible) + _ButtonGroup.ProcessMouseDown(e); + base.OnMouseDown(e); + } + protected override void OnMouseUp(MouseEventArgs e) + { + if (_ButtonGroup.Visible) + _ButtonGroup.ProcessMouseUp(e); + base.OnMouseUp(e); + } + protected override void OnMouseClick(MouseEventArgs e) + { + if (_MouseOverToken != null && _MouseOverToken.MouseOverPart == eTokenPart.RemoveButton) + { + EditToken token = _MouseOverToken; + RemovingTokenEventArgs args = new RemovingTokenEventArgs(token, eEventSource.Mouse); + OnRemovingToken(args); + if (args.Cancel) return; + + LeaveMouseOverToken(); + this.SelectedTokens.Remove(token); + } + else if (_MouseOverToken != null) + { + OnTokenMouseClick(_MouseOverToken, e); + } + if (_ButtonGroup.Visible) + _ButtonGroup.ProcessMouseClick(e); + base.OnMouseClick(e); + } + protected override void OnMouseDoubleClick(MouseEventArgs e) + { + if (_MouseOverToken != null) + { + OnTokenMouseDoubleClick(_MouseOverToken, e); + } + base.OnMouseDoubleClick(e); + } + protected override void OnMouseHover(EventArgs e) + { + if (_MouseOverToken != null) + { + OnTokenMouseHover(_MouseOverToken, e); + ShowToolTip(_MouseOverToken); + } + + if (_ButtonGroup.Visible) + _ButtonGroup.ProcessMouseHover(e); + base.OnMouseHover(e); + } + /// + /// Occurs before token is removed from the SelectedTokens by end user. + /// + [Description("Occurs before token is removed from the SelectedTokens by end user.")] + public event RemovingTokenEventHandler RemovingToken; + /// + /// Raises RemovingToken event. + /// + /// Provides event arguments. + protected virtual void OnRemovingToken(RemovingTokenEventArgs e) + { + RemovingTokenEventHandler handler = RemovingToken; + if (handler != null) + handler(this, e); + } + private void LeaveMouseOverToken() + { + HideToolTip(); + if (_MouseOverToken != null) + { + _MouseOverToken.MouseOverPart = eTokenPart.None; + OnTokenMouseLeave(_MouseOverToken, EventArgs.Empty); + _MouseOverToken = null; + this.Invalidate(); + } + } + + private bool _IsMouseOver = false; + protected override void OnMouseLeave(EventArgs e) + { + _IsMouseOver = false; + LeaveMouseOverToken(); + if (_ButtonGroup.Visible) + _ButtonGroup.ProcessMouseLeave(); + base.OnMouseLeave(e); + } + protected override void OnMouseEnter(EventArgs e) + { + _IsMouseOver = true; + base.OnMouseEnter(e); + } + + private EditToken _FocusToken = null; + private EditToken FocusToken + { + get { return _FocusToken; } + set + { + if (_FocusToken != value) + { + if (_FocusToken != null) + _FocusToken.IsFocused = false; + _FocusToken = value; + if (_FocusToken != null) + _FocusToken.IsFocused = true; + this.Invalidate(); + } + } + } + + private void FocusPreviousToken() + { + if (this.SelectedTokens.Count == 0) return; + int index = _SelectedTokens.Count - 1; + if (_FocusToken != null) + index = Math.Max(0, _SelectedTokens.IndexOf(_FocusToken) - 1); + FocusToken = _SelectedTokens[index]; + } + private void FocusNextToken() + { + if (this.SelectedTokens.Count == 0) return; + int index = 0; + if (_FocusToken != null) + { + if (_SelectedTokens.IndexOf(_FocusToken) == _SelectedTokens.Count - 1) + { + FocusToken = null; + _EditBox.Select(); + return; + } + index = Math.Min(_SelectedTokens.Count - 1, _SelectedTokens.IndexOf(_FocusToken) + 1); + } + FocusToken = _SelectedTokens[index]; + } + private void DeleteFocusedToken(bool isBackspace, eEventSource eventSource) + { + EditToken focusToken = _FocusToken; + if (focusToken == null) return; + RemovingTokenEventArgs e = new RemovingTokenEventArgs(focusToken, eventSource); + OnRemovingToken(e); + if (e.Cancel) return; + FocusToken = null; + int index = Math.Max(0, _SelectedTokens.IndexOf(focusToken) - 1); + _SelectedTokens.Remove(focusToken); + if (_SelectedTokens.Count > 0) + { + FocusToken = _SelectedTokens[index]; + } + else + { + _EditBox.Select(); + } + } + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (!_EditBox.Focused) + { + if (keyData == Keys.Left) + { + FocusPreviousToken(); + return true; + } + else if (keyData == Keys.Right) + { + FocusNextToken(); + return true; + } + else if (keyData == Keys.Back) + { + DeleteFocusedToken(true, eEventSource.Keyboard); + return true; + } + else if (keyData == Keys.Delete) + { + DeleteFocusedToken(false, eEventSource.Keyboard); + return true; + } + } + return base.ProcessCmdKey(ref msg, keyData); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if (_FocusToken != null) + { + FocusToken = null; + _EditBox.Select(); + } + base.OnKeyDown(e); + } + + protected override void OnLeave(EventArgs e) + { + if (_EditBox.Visible) + { + _EditBox.Visible = false; + if (_ValidateTokenTextOnLostFocus && !string.IsNullOrEmpty(_EditBox.Text)) + { + ValidateAndConvertEditText(_EditBox.Text); + } + } + _EditBox.Text = ""; + FocusToken = null; + if (IsPopupOpen) + CloseAutoCompleteDropDown(); + HideToolTip(); + base.OnLeave(e); + } + protected override void OnEnter(EventArgs e) + { + if (!_ReadOnly) + { + ShowEditTextBox(); + } + base.OnEnter(e); + } + + private bool _ReadOnly = false; + /// + /// Indicates whether tokens can be added or removed by end user. Default value is false. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether tokens can be added or removed by end user. Default value is false.")] + public bool ReadOnly + { + get { return _ReadOnly; } + set + { + if (value != _ReadOnly) + { + bool oldValue = _ReadOnly; + _ReadOnly = value; + OnReadOnlyChanged(oldValue, value); + } + } + } + private void ShowEditTextBox() + { + _EditBox.Visible = true; + _EditBox.Focus(); + EnsureTextBoxScrollPosition(); + } + private void EnsureTextBoxScrollPosition() + { + if (!_EditBox.Visible) return; + Rectangle clientBounds = GetClientBounds(); + if (clientBounds.Contains(_EditBox.Bounds)) + return; + // Scroll content vertically to ensure text-box is withing client bounds + AutoScrollPosition = new Point(0, AutoScrollPosition.Y + (clientBounds.Bottom - _EditBox.Bounds.Bottom)); + } + /// + /// Called when ReadOnly property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnReadOnlyChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("ReadOnly")); + if (_ReadOnly) + { + if (_EditBox.Visible) + _EditBox.Visible = false; + } + else if (this.Focused) + { + ShowEditTextBox(); + _EditBox.Focus(); + } + if (_RemoveTokenButtonVisible) + LayoutTokens(); + } + + private int _DropDownHeight = 120; + /// + /// Indicates the height of the auto-complete drop-down. + /// + [DefaultValue(120), Category("Appearance"), Description("Indicates the height of the auto-complete drop-down")] + public int DropDownHeight + { + get { return _DropDownHeight; } + set + { + if (value != _DropDownHeight) + { + int oldValue = _DropDownHeight; + _DropDownHeight = value; + OnDropDownHeightChanged(oldValue, value); + } + } + } + /// + /// Called when DropDownHeight property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDropDownHeightChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("DropDownHeight")); + } + + private int _DropDownWidth = 180; + /// + /// Indicates the width of the auto-complete drop-down. + /// + [DefaultValue(180), Category("Appearance"), Description("Indicates the width of the auto-complete drop-down.")] + public int DropDownWidth + { + get { return _DropDownWidth; } + set + { + if (value != _DropDownWidth) + { + int oldValue = _DropDownWidth; + _DropDownWidth = value; + OnDropDownWidthChanged(oldValue, value); + } + } + } + /// + /// Called when DropDownWidth property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDropDownWidthChanged(int oldValue, int newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("DropDownWidth")); + + } + + private bool _EnterKeyValidatesToken = true; + /// + /// Indicates whether when token text is entered into the text-box pressing the Enter key attempts to validate the token and converts the text to token. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether when token text is entered into the text-box pressing the Enter key attempts to validate the token and converts the text to token.")] + public bool EnterKeyValidatesToken + { + get + { + return _EnterKeyValidatesToken; + } + set + { + _EnterKeyValidatesToken = value; + } + } + + private void EditBoxKeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Escape && IsPopupOpen) + { + CloseAutoCompleteDropDown(); + } + else if (e.KeyCode == Keys.Enter && IsPopupOpen && _AutoCompleteListBox != null && _AutoCompleteListBox.SelectedIndex >= 0) + { + SelectToken(_Tokens[_AutoCompleteListBox.SelectedIndex]); + } + else if (e.KeyCode == Keys.Enter && EnterKeyValidatesToken) + { + ValidateAndConvertEditText(_EditBox.Text); + } + else if (e.KeyCode == Keys.Down) + { + if (IsPopupOpen && _AutoCompleteListBox != null) + { + _AutoCompleteListBox.SelectNextItem(); + e.Handled = true; + } + else if (!IsPopupOpen && string.IsNullOrEmpty(_EditBox.Text)) + { + IsPopupOpen = true; + e.Handled = true; + } + } + else if (_AutoCompleteListBox != null && e.KeyCode == Keys.Up) + { + _AutoCompleteListBox.SelectPreviousItem(); + e.Handled = true; + } + else if ((e.KeyCode == Keys.Left || e.KeyCode == Keys.Back) && string.IsNullOrEmpty(_EditBox.Text)) + { + CloseAutoCompleteDropDown(); + if (this.SelectedTokens.Count > 0) + { + this.Select(); + FocusPreviousToken(); + } + e.Handled = true; + } + + } + + + private void AutoCompleteListBoxItemClick(object sender, EventArgs e) + { + if (_AutoCompleteListBox.SelectedIndex >= 0) + SelectToken(_Tokens[_AutoCompleteListBox.SelectedIndex]); + } + + private bool SelectToken(EditToken token) + { + if (token.IsSelected) return false; + + ValidateTokenEventArgs args = new ValidateTokenEventArgs(token, false); + if (args.IsValid && args.Token != null) + { + token = args.Token; + this.SelectedTokens.Add(token); + _EditBox.Text = ""; + CloseAutoCompleteDropDown(); + return true; + } + return false; + } + + private bool ValidateAndConvertEditText(string text) + { + if (string.IsNullOrEmpty(text)) + return false; + IsPopupOpen = false; + bool isNewToken = false; + EditToken token = FindOrCreateToken(text, out isNewToken); + ValidateTokenEventArgs args = new ValidateTokenEventArgs(token, isNewToken); + OnValidateToken(args); + if (args.IsValid && args.Token != null) + { + token = args.Token; + this.SelectedTokens.Add(token); + _EditBox.Text = ""; + CloseAutoCompleteDropDown(); + return true; + } + return false; + } + + private bool IsSelected(EditToken item) + { + return item.IsSelected; + + //foreach (EditToken selectedToken in _SelectedTokens) + //{ + // if(selectedToken == item) + // return true; + //} + //return false; + } + private EditToken FindOrCreateToken(string text, out bool isNew) + { + isNew = false; + foreach (EditToken item in _Tokens) + { + if (!item.IsSelected && TokenExactMatch(text, item, _TokenFilterBehavior)) + { + return item; + } + } + isNew = true; + return new EditToken(text); + } + + private void EditBoxTextChanged(object sender, EventArgs e) + { + string text = _EditBox.Text; + + if (!_DroppedDown && FilteredTokenExists(text)) + { + OpenAutoCompleteDropDown(); + } + if (_AutoCompleteListBox != null) + { + FilterAutoCompleteBox(_AutoCompleteListBox, text); + } + + foreach (string separator in _Separators) + { + if (text.EndsWith(separator)) + { + text = text.Substring(0, text.Length - separator.Length); + ValidateAndConvertEditText(text); + break; + } + } + } + + private PopupHostController _PopupController = null; + private ListBoxAdv _AutoCompleteListBox = null; + private DateTime _MultiDropDownOpenedAtTime = DateTime.MinValue; + private DateTime _MultiDropDownClosedAtTime = DateTime.MinValue; + + /// + /// Occurs before token auto-complete popup is displayed and allows cancelation of popup display. + /// + [Description("Occurs before token auto-complete popup is displayed and allows cancelation of popup display.")] + public event CancelEventHandler BeforeAutoCompletePopupOpen; + /// + /// Occurs after auto-complete popup is open. + /// + [Description("Occurs after auto-complete popup is open.")] + public event EventHandler AutoCompletePopupOpened; + /// + /// Raises AutoCompletePopupOpened event. + /// + /// Provides event arguments. + protected virtual void OnAutoCompletePopupOpened(EventArgs e) + { + EventHandler handler = AutoCompletePopupOpened; + if (handler != null) + handler(this, e); + } + /// + /// Raises BeforeAutoCompletePopupOpen event. + /// + /// Provides event arguments. + protected virtual void OnBeforeAutoCompletePopupOpen(CancelEventArgs e) + { + CancelEventHandler handler = BeforeAutoCompletePopupOpen; + if (handler != null) + handler(this, e); + } + + private void OpenAutoCompleteDropDown() + { + if (_PopupController == null) + { + _PopupController = new PopupHostController(); + _PopupController.Closed += PopupControllerClosed; + } + + if (_AutoCompleteListBox == null) + { + _AutoCompleteListBox = CreateAutoCompleteListBox(); + //_AutoCompleteListBox.Resize += _AutoCompleteListBox_Resize; + //this.Parent.Controls.Add(_AutoCompleteListBox); + //_AutoCompleteListBox.Location = new Point(10,100); + } + + if (!_MessageHandlerInstalled && _DropDownButtonVisible) + { + MessageHandler.RegisterMessageClient(this); + _MessageHandlerInstalled = true; + } + + LoadAutoCompleteBox(_AutoCompleteListBox); + + if (!_PopupController.PopupUserSize || !_PreservePopupSize) + { + _AutoCompleteListBox.Height = Dpi.Height(this.DropDownHeight); + _AutoCompleteListBox.Width = (this.DropDownWidth > 0 ? Dpi.Width(this.DropDownWidth) : this.Width); + //_AutoCompleteListBox.MinimumSize = _AutoCompleteListBox.Size; + } + + CancelEventArgs cancelArgs = new CancelEventArgs(); + OnBeforeAutoCompletePopupOpen(cancelArgs); + if (cancelArgs.Cancel) + return; + + Point location = PointToScreen(new Point(0, Height)); + TokenEditorPopupEventArgs popupArgs = new TokenEditorPopupEventArgs(location, _AutoCompleteListBox.Size); + OnBeforePopupOpen(popupArgs); + location = popupArgs.PopupLocation; + ePopupResizeEdge resize = _EnablePopupResize ? ePopupResizeEdge.BottomRight : ePopupResizeEdge.None; + _PopupController.AutoClose = false; + + _PopupController.ParentControlBounds = new Rectangle(PointToScreen(Point.Empty), this.Size); + _PopupController.Show(_AutoCompleteListBox, location.X, location.Y, 0, 0, resize); + + _EditBox.Focus(); + _EditBox.SelectionLength = 0; // Clear selection that happens upon focus + if (_EditBox.TextLength > 0) + _EditBox.SelectionStart = _EditBox.TextLength; + _PopupController.AutoClose = true; + _DroppedDown = true; + _MultiDropDownOpenedAtTime = DateTime.Now; + + OnAutoCompletePopupOpened(EventArgs.Empty); + } + + /// + /// Occurs before the auto-complete popup is displayed and allows you to adjust popup location. + /// + [Description("Occurs before the auto-complete popup is displayed and allows you to adjust popup location.")] + public event TokenEditorPopupEventHandler BeforePopupOpen; + /// + /// Raises BeforePopupOpen event. + /// + /// Provides event arguments. + protected virtual void OnBeforePopupOpen(TokenEditorPopupEventArgs e) + { + TokenEditorPopupEventHandler handler = BeforePopupOpen; + if (handler != null) + handler(this, e); + } + + private void LoadAutoCompleteBox(ListBoxAdv listBox) + { + listBox.BeginUpdate(); + listBox.Items.Clear(); + listBox.CheckBoxesVisible = _CheckBoxesVisible; + listBox.ShowToolTips = _ShowToolTips; + foreach (EditToken item in _Tokens) + { + ListBoxItem listItem = new ListBoxItem(); + listItem.Text = GetTokenText(item); + listItem.Tooltip = item.Tooltip; + if (_CheckBoxesVisible) + listItem.CheckState = (item.IsSelected ? CheckState.Checked : CheckState.Unchecked); + else + listItem.Visible = !item.IsSelected; + listBox.Items.Add(listItem); + } + listBox.EndUpdate(); + } + private bool FilteredTokenExists(string text) + { + foreach (EditToken item in _Tokens) + { + if (item.IsSelected) continue; + if (TokenMatch(text, item, _TokenFilterBehavior)) + return true; + } + return false; + } + + private eTokenFilterBehavior _TokenFilterBehavior = eTokenFilterBehavior.TextAndValue; + /// + /// Indicates how tokens are filtered based on the entered text + /// + [DefaultValue(eTokenFilterBehavior.TextAndValue), Category("Behavior"), Description("Indicates how tokens are filtered based on the entered text")] + public eTokenFilterBehavior TokenFilterBehavior + { + get { return _TokenFilterBehavior; } + set { _TokenFilterBehavior = value; } + } + private static bool TokenMatch(string filterText, EditToken token, eTokenFilterBehavior behavior) + { + filterText = filterText.ToLower(); + if(behavior == eTokenFilterBehavior.Text) + return !string.IsNullOrEmpty(token.Text) && token.Text.ToLower().Contains(filterText); + else if(behavior == eTokenFilterBehavior.Value) + return !string.IsNullOrEmpty(token.Value) && token.Value.ToLower().Contains(filterText); + return !string.IsNullOrEmpty(token.Text) && token.Text.ToLower().Contains(filterText) || !string.IsNullOrEmpty(token.Value) && token.Value.ToLower().Contains(filterText); + } + private static bool TokenExactMatch(string filterText, EditToken token, eTokenFilterBehavior behavior) + { + filterText = filterText.ToLower(); + if (behavior == eTokenFilterBehavior.Text) + return !string.IsNullOrEmpty(token.Text) && token.Text.ToLower() == filterText; + else if (behavior == eTokenFilterBehavior.Value) + return !string.IsNullOrEmpty(token.Value) && token.Value.ToLower() == filterText; + return !string.IsNullOrEmpty(token.Text) && token.Text.ToLower() == filterText || !string.IsNullOrEmpty(token.Value) && token.Value.ToLower() == filterText; + } + private void FilterAutoCompleteBox(ListBoxAdv listBox, string filterText) + { + bool oneVisible = false; + listBox.BeginUpdate(); + if (string.IsNullOrEmpty(filterText)) + { + if (!_CheckBoxesVisible) + { + foreach (ListBoxItem item in listBox.Items) + { + item.IsSelected = false; + item.Visible = !item.IsSelected; + if (item.Visible) + oneVisible = true; + } + } + } + else + { + for (int i = 0; i < listBox.Items.Count; i++) + { + ListBoxItem item = (ListBoxItem)listBox.Items[i]; + EditToken token = _Tokens[i]; + if (!token.IsSelected && TokenMatch(filterText, token, _TokenFilterBehavior)) + { + if (!_CheckBoxesVisible) + item.Visible = true; + if (!oneVisible) + item.IsSelected = true; + else + item.IsSelected = false; + oneVisible = true; + } + else if (!_CheckBoxesVisible) + item.Visible = false; + else + item.IsSelected = false; + } + } + + listBox.EndUpdate(); + + if (!oneVisible && !_CheckBoxesVisible) + CloseAutoCompleteDropDown(); + } + + private ListBoxAdv CreateAutoCompleteListBox() + { + ListBoxAdv listBox = new ListBoxAdv(); +#if (!TRIAL) + listBox.LicenseKey = "F962CEC7-CD8F-4911-A9E9-CAB39962FC1F"; +#endif + //listBox.BackColor = Color.White; + listBox.BackgroundStyle.Class = ElementStyleClassKeys.ListBoxAdvKey; + listBox.ItemClick += AutoCompleteListBoxItemClick; + listBox.ItemCheck += AutoCompleteListBoxItemCheck; + listBox.AutoScroll = true; + //listBox.BackgroundStyle.Reset(); + //listBox.BackgroundStyle.BackColor = SystemColors.Window; + //listBox.BackgroundStyle.Border = eStyleBorderType.None; + return listBox; + + } + + void AutoCompleteListBoxItemCheck(object sender, ListBoxAdvItemCheckEventArgs e) + { + int index = _AutoCompleteListBox.Items.IndexOf(e.Item); + EditToken token = _Tokens[index]; + if (e.Item.CheckState == CheckState.Unchecked && token.IsSelected) + this.SelectedTokens.Remove(token); + else if (!token.IsSelected) + this.SelectedTokens.Add(token); + } + private void PopupControllerClosed(object sender, ToolStripDropDownClosedEventArgs e) + { + _DroppedDown = false; + + //m_SelectedIndexInternal = this.SelectedIndex; + _MultiDropDownClosedAtTime = DateTime.Now; + //OnDropDownClosed(e); + } + private void CloseAutoCompleteDropDown() + { + if (_PopupController != null && _DroppedDown) + { + _PopupController.Hide(); + } + } + + private bool _PreservePopupSize = true; + /// + /// Indicates whether auto-complete popup size is preserved between popup displays if popup is resized by end-user. + /// + [DefaultValue(true), Category("Auto-Complete"), Description("Indicates whether auto-complete popup size is preserved between popup displays if popup is resized by end-user.")] + public bool PreservePopupSize + { + get { return _PreservePopupSize; } + set + { + _PreservePopupSize = value; + } + } + + private bool _EnablePopupResize = true; + /// + /// Indicates whether auto-complete popup can be resized by end user. + /// + [DefaultValue(true), Category("Auto-Complete"), Description("Indicates whether auto-complete popup can be resized by end user.")] + public bool EnablePopupResize + { + get { return _EnablePopupResize; } + set + { + _EnablePopupResize = value; + } + } + + private bool _PopupCloseButtonVisible = true; + /// + /// Indicates whether multi-column popup close button is visible. + /// + [DefaultValue(true), Category("Auto-Complete"), Description("Indicates whether multi-column popup close button is visible.")] + public bool PopupCloseButtonVisible + { + get { return _PopupCloseButtonVisible; } + set + { + _PopupCloseButtonVisible = value; + } + } + + private bool _DroppedDown = false; + /// + /// Gets or sets whether auto-complete popup window is open. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPopupOpen + { + get { return _DroppedDown; } + set + { + if (value != _DroppedDown) + { + if (value) + OpenAutoCompleteDropDown(); + else + CloseAutoCompleteDropDown(); + } + } + } + + private List _Separators = new List(); + /// + /// Gets the list of separators which are used to divide entered text into the tokens. + /// + [Category("Behavior"), Description("Gets the list of separators which are used to divide entered text into the tokens."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), MergableProperty(false), Localizable(true)] + [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version= 2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + public List Separators + { + get { return _Separators; } + } + + /// + /// Occurs when an token is selected from the auto-complete list or when text entry by end user is parsed into token to validate it. + /// + [Description("Occurs when an token is selected from the auto-complete list or when text entry by end user is parsed into token to validate it.")] + public event ValidateTokenEventHandler ValidateToken; + /// + /// Raises ValidateToken event. + /// + /// Provides event arguments. + protected virtual void OnValidateToken(ValidateTokenEventArgs e) + { + ValidateTokenEventHandler handler = ValidateToken; + if (handler != null) + handler(this, e); + } + + private bool _AutoSizeHeight = true; + /// + /// Indicates whether control automatically increases its height as more tokens are selected. MaxHeightLines property controls the maximum number of lines control will grow to before showing scroll-bar. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether control automatically increases its height as more tokens are selected. MaxHeightLines property controls the maximum number of lines control will grow to before showing scroll-bar.")] + public bool AutoSizeHeight + { + get { return _AutoSizeHeight; } + set + { + if (_AutoSizeHeight != value) + { + _AutoSizeHeight = value; + if (_AutoSizeHeight) + LayoutTokens(); + } + } + } + + private int _MaxHeightLines = 5; + /// + /// Indicates maximum number of lines control will grow to when AutoSizeHeight=true. Set to 0 to indicates unlimited growth. + /// Default value is 5. + /// + [DefaultValue(5), Category("Behavior"), Description("Indicates maximum number of lines control will grow to when AutoSizeHeight=true. Set to 0 to indicates unlimited growth.")] + public int MaxHeightLines + { + get { return _MaxHeightLines; } + set { _MaxHeightLines = value; } + } + + /// + /// Gets reference to internal text-box control that is used to input the token text. + /// + [Browsable(false)] + public TextBox EditTextBox + { + get + { + return _EditBox; + } + } + + private bool _ValidateTokenTextOnLostFocus = true; + /// + /// Indicates whether any text entered into the token editor is validated and converted to token when control loses focus. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether any text entered into the token editor is validated and converted to token when control loses focus.")] + public bool ValidateTokenTextOnLostFocus + { + get { return _ValidateTokenTextOnLostFocus; } + set { _ValidateTokenTextOnLostFocus = value; } + } + + private string _WatermarkText = ""; + private Font _WatermarkFont = null; + private Color _WatermarkColor = SystemColors.GrayText; + + private bool _WatermarkEnabled = true; + /// + /// Gets or sets whether watermark text is displayed when control is empty. Default value is true. + /// + [DefaultValue(true), Description("Indicates whether watermark text is displayed when control is empty.")] + public virtual bool WatermarkEnabled + { + get { return _WatermarkEnabled; } + set { _WatermarkEnabled = value; this.Invalidate(); UpdateEditBoxWatermark(); } + } + + private Image _WatermarkImage = null; + /// + /// Gets or sets the watermark image displayed inside of the control when Text is not set and control does not have input focus. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates watermark image displayed inside of the control when Text is not set and control does not have input focus.")] + public Image WatermarkImage + { + get { return _WatermarkImage; } + set { _WatermarkImage = value; this.Invalidate(); UpdateEditBoxWatermark(); } + } + private ContentAlignment _WatermarkImageAlignment = ContentAlignment.MiddleLeft; + /// + /// Gets or sets the watermark image alignment. + /// + [DefaultValue(ContentAlignment.MiddleLeft), Category("Appearance"), Description("Indicates watermark image alignment.")] + public ContentAlignment WatermarkImageAlignment + { + get { return _WatermarkImageAlignment; } + set { _WatermarkImageAlignment = value; this.Invalidate(); UpdateEditBoxWatermark(); } + } + + /// + /// Gets or sets the watermark (tip) text displayed inside of the control when Text is not set and control does not have input focus. This property supports text-markup. + /// + [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus."), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string WatermarkText + { + get { return _WatermarkText; } + set + { + if (value == null) value = ""; + _WatermarkText = value; + MarkupTextChanged(); + UpdateEditBoxWatermark(); + this.Invalidate(); + } + } + + /// + /// Gets or sets the watermark font. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark font."), DefaultValue(null)] + public Font WatermarkFont + { + get { return _WatermarkFont; } + set { _WatermarkFont = value; this.Invalidate(); UpdateEditBoxWatermark(); } + } + + /// + /// Gets or sets the watermark text color. + /// + [Browsable(true), Category("Appearance"), Description("Indicates watermark text color.")] + public Color WatermarkColor + { + get { return _WatermarkColor; } + set { _WatermarkColor = value; this.Invalidate(); UpdateEditBoxWatermark(); } + } + /// + /// Indicates whether property should be serialized by Windows Forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeWatermarkColor() + { + return _WatermarkColor != SystemColors.GrayText; + } + /// + /// Resets the property to default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetWatermarkColor() + { + this.WatermarkColor = SystemColors.GrayText; + } + + protected virtual bool IsWatermarkRendered + { + get + { + return (!this.Focused || _WatermarkBehavior == eWatermarkBehavior.HideNonEmpty) && this.SelectedTokens.Count == 0; + } + } + + private eWatermarkBehavior _WatermarkBehavior = eWatermarkBehavior.HideOnFocus; + /// + /// Gets or sets the watermark hiding behaviour. Default value indicates that watermark is hidden when control receives input focus. + /// + [DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior"), Description("Indicates watermark hiding behaviour.")] + public eWatermarkBehavior WatermarkBehavior + { + get { return _WatermarkBehavior; } + set { _WatermarkBehavior = value; this.Invalidate(); + UpdateEditBoxWatermark(); + } + } + private void UpdateEditBoxWatermark() + { + _EditBox.WatermarkText = _WatermarkText; + _EditBox.WatermarkColor = _WatermarkColor; + _EditBox.WatermarkFont = _WatermarkFont; + _EditBox.WatermarkImage = _WatermarkImage; + _EditBox.WatermarkImageAlignment = _WatermarkImageAlignment; + if (this.SelectedTokens.Count > 0 || !_WatermarkEnabled) + _EditBox.WatermarkEnabled = false; + else if (_WatermarkBehavior == eWatermarkBehavior.HideNonEmpty) + { + _EditBox.WatermarkEnabled = true; + _EditBox.WatermarkBehavior = eWatermarkBehavior.HideNonEmpty; + } + else + { + _EditBox.WatermarkBehavior = eWatermarkBehavior.HideOnFocus; + } + + } + + private TextMarkup.BodyElement _TextMarkup = null; + private void MarkupTextChanged() + { + _TextMarkup = null; + + if (!TextMarkup.MarkupParser.IsMarkup(ref _WatermarkText)) + return; + + _TextMarkup = TextMarkup.MarkupParser.Parse(_WatermarkText); + ResizeMarkup(); + } + + private MarkupDrawContext GetMarkupDrawContext(Graphics g) + { + return new MarkupDrawContext(g, (_WatermarkFont == null ? this.Font : _WatermarkFont), _WatermarkColor, this.RightToLeft == RightToLeft.Yes); + } + private void ResizeMarkup() + { + if (_TextMarkup != null) + { + using (Graphics g = this.CreateGraphics()) + { + MarkupDrawContext dc = GetMarkupDrawContext(g); + _TextMarkup.Measure(GetWatermarkBounds().Size, dc); + Size sz = _TextMarkup.Bounds.Size; + _TextMarkup.Arrange(new Rectangle(GetWatermarkBounds().Location, sz), dc); + } + } + } + + private Rectangle GetWatermarkBounds() + { + Rectangle r = this.ClientRectangle; + r.Inflate(-1, 0); + r.X += 2; + r.Width -= 2; + return r; + } + + private void DrawWatermark(Graphics g) + { + + Rectangle bounds = GetWatermarkBounds(); + if (_WatermarkImage != null) + { + Rectangle imageBounds = new Rectangle(Point.Empty, _WatermarkImage.Size); + if (_WatermarkImageAlignment == ContentAlignment.BottomCenter) + imageBounds.Location = new Point(bounds.X + (bounds.Width - imageBounds.Width) / 2, bounds.Bottom - imageBounds.Height); + else if (_WatermarkImageAlignment == ContentAlignment.BottomLeft) + imageBounds.Location = new Point(bounds.X, bounds.Bottom - imageBounds.Height); + else if (_WatermarkImageAlignment == ContentAlignment.BottomRight) + imageBounds.Location = new Point(bounds.Right - imageBounds.Width, bounds.Bottom - imageBounds.Height); + else if (_WatermarkImageAlignment == ContentAlignment.MiddleCenter) + imageBounds.Location = new Point(bounds.X + (bounds.Width - imageBounds.Width) / 2, bounds.Y + (bounds.Height - imageBounds.Height) / 2); + else if (_WatermarkImageAlignment == ContentAlignment.MiddleLeft) + imageBounds.Location = new Point(bounds.X, bounds.Y + (bounds.Height - imageBounds.Height) / 2); + else if (_WatermarkImageAlignment == ContentAlignment.MiddleRight) + imageBounds.Location = new Point(bounds.Right - imageBounds.Width, bounds.Y + (bounds.Height - imageBounds.Height) / 2); + else if (_WatermarkImageAlignment == ContentAlignment.TopCenter) + imageBounds.Location = new Point(bounds.X + (bounds.Width - imageBounds.Width) / 2, bounds.Y); + else if (_WatermarkImageAlignment == ContentAlignment.TopLeft) + imageBounds.Location = new Point(bounds.X, bounds.Y); + else if (_WatermarkImageAlignment == ContentAlignment.TopRight) + imageBounds.Location = new Point(bounds.Right - imageBounds.Width, bounds.Y); + g.DrawImage(_WatermarkImage, imageBounds); + + if (_WatermarkImageAlignment == ContentAlignment.BottomLeft || _WatermarkImageAlignment == ContentAlignment.MiddleLeft || _WatermarkImageAlignment == ContentAlignment.TopLeft) + { + bounds.X = imageBounds.Right; + bounds.Width = Math.Max(0, bounds.Width - imageBounds.Width); + } + else if (_WatermarkImageAlignment == ContentAlignment.BottomRight || _WatermarkImageAlignment == ContentAlignment.MiddleRight || _WatermarkImageAlignment == ContentAlignment.TopRight) + { + bounds.Width = Math.Max(0, bounds.Width - imageBounds.Width); + } + } + + if (bounds.Width <= 0) return; + + if (_TextMarkup != null) + { + MarkupDrawContext dc = GetMarkupDrawContext(g); + if (_TextMarkup.Bounds.Height < bounds.Height) + _TextMarkup.Bounds = new Rectangle(bounds.X, bounds.Y + (bounds.Height - _TextMarkup.Bounds.Height) / 2, _TextMarkup.Bounds.Width, _TextMarkup.Bounds.Height); + _TextMarkup.Render(dc); + } + else + { + eTextFormat tf = eTextFormat.Left | eTextFormat.VerticalCenter; + + if (this.RightToLeft == RightToLeft.Yes) tf |= eTextFormat.RightToLeft; + + tf |= eTextFormat.EndEllipsis; + tf |= eTextFormat.WordBreak; + TextDrawing.DrawString(g, _WatermarkText, (_WatermarkFont == null ? this.Font : _WatermarkFont), + _WatermarkColor, bounds, tf); + } + + } + + protected override void OnTextChanged(EventArgs e) + { + if (!_UpdatingText) + { + this.SelectedTokens.Clear(); + if (!string.IsNullOrEmpty(this.Text)) + { + if (!string.IsNullOrEmpty(_TextSeparator)) + { + string[] tokens = this.Text.Split(new string[] { _TextSeparator }, StringSplitOptions.RemoveEmptyEntries); + foreach (string item in tokens) + { + bool isNew = false; + SelectToken(FindOrCreateToken(this.Text, out isNew)); + } + } + else + { + bool isNew = false; + SelectToken(FindOrCreateToken(this.Text, out isNew)); + } + } + } + + base.OnTextChanged(e); + } + + private bool _UpdatingText = false; + private void UpdateText() + { + _UpdatingText = true; + string text = ""; + for (int i = 0; i < _SelectedTokens.Count; i++) + { + text += GetTokenText(_SelectedTokens[i]); + if (i < _SelectedTokens.Count - 1) + text += _TextSeparator; + } + + this.Text = text; + + _UpdatingText = false; + } + + private string _TextSeparator = ","; + /// + /// Indicates the character separator that is used to separate tokens when controls Text property is updated or parsed. + /// + [DefaultValue(","), Category("Behavior"), Description("Indicates the character separator that is used to separate tokens when controls Text property is updated or parsed.")] + public string TextSeparator + { + get { return _TextSeparator; } + set + { + if (value != _TextSeparator) + { + string oldValue = _TextSeparator; + _TextSeparator = value; + OnTextSeparatorChanged(oldValue, value); + } + } + } + /// + /// Called when TextSeparator property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextSeparatorChanged(string oldValue, string newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TextSeparator")); + UpdateText(); + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + private bool _DropDownButtonVisible = false; + /// + /// Indicates whether drop-down button which shows available token popup is displayed + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether drop-down button which shows available token popup is displayed")] + public bool DropDownButtonVisible + { + get { return _DropDownButtonVisible; } + set + { + if (value != _DropDownButtonVisible) + { + bool oldValue = _DropDownButtonVisible; + _DropDownButtonVisible = value; + OnDropDownButtonVisibleChanged(oldValue, value); + } + } + } + /// + /// Called when DropDownButtonVisible property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnDropDownButtonVisibleChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("DropDownButtonVisible")); + UpdateButtons(); + LayoutTokens(); + Invalidate(); + } + + private bool _CheckBoxesVisible = false; + /// + /// Indicates whether check-boxes are displayed on popup token selection list and used for token selection. + /// + [DefaultValue(false), Category("Behavior"), Description("Indicates whether check-boxes are displayed on popup token selection list and used for token selection.")] + public bool CheckBoxesVisible + { + get { return _CheckBoxesVisible; } + set + { + if (value != _CheckBoxesVisible) + { + bool oldValue = _CheckBoxesVisible; + _CheckBoxesVisible = value; + OnCheckBoxesVisibleChanged(oldValue, value); + } + } + } + /// + /// Called when CheckBoxesVisible property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCheckBoxesVisibleChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("CheckBoxesVisible")); + + } + + private VisualGroup _ButtonGroup = null; + private VisualDropDownButton _DropDownButton = null; + private VisualUpDownButton _ScrollButton = null; + private int GetButtonHeight() + { + return GetSingleLineTextBoxHeight() - 4; + } + private void UpdateButtons() + { + if (!_DropDownButtonVisible && !_ScrollButton.Visible) + _ButtonGroup.Visible = false; + else + { + _ButtonGroup.Visible = true; + _DropDownButton.Height = GetButtonHeight(); + } + _DropDownButton.Visible = _DropDownButtonVisible; + _ButtonGroup.InvalidateArrange(); + } + + protected virtual void CreateButtons() + { + _DropDownButton = new VisualDropDownButton(); + _DropDownButton.MouseClick += DropDownButtonClick; + _DropDownButton.Visible = false; + _ButtonGroup.Items.Add(_DropDownButton); + + _ScrollButton = new VisualUpDownButton(); + _ScrollButton.UpClick += ScrollButtonUpClick; + _ScrollButton.DownClick += ScrollButtonDownClick; + _ScrollButton.Visible = false; + _ButtonGroup.Items.Add(_ScrollButton); + } + + void ScrollButtonDownClick(object sender, EventArgs e) + { + if (Math.Abs(_AutoScrollPosition.Y) < (_VScrollBar.Maximum - _VScrollBar.LargeChange - 1)) + AutoScrollPosition = new Point(_AutoScrollPosition.X, _AutoScrollPosition.Y - _VScrollBar.SmallChange); + } + + void ScrollButtonUpClick(object sender, EventArgs e) + { + if (_AutoScrollPosition.Y < 0) + AutoScrollPosition = new Point(_AutoScrollPosition.X, Math.Min(0, _AutoScrollPosition.Y + _VScrollBar.SmallChange)); + } + + void DropDownButtonClick(object sender, MouseEventArgs e) + { + IsPopupOpen = !IsPopupOpen; + } + private void ButtonGroupRenderInvalid(object sender, EventArgs e) + { + Invalidate(); + } + + private void ButtonGroupArrangeInvalid(object sender, EventArgs e) + { + Invalidate(); + } + + private void ButtonGroupResetMouseHover(object sender, EventArgs e) + { + DevComponents.AdvTree.Interop.WinApi.ResetHover(this); + } + + private void PaintButtons(Graphics g) + { + PaintInfo p = CreatePaintInfo(g); + if (!_ButtonGroup.IsLayoutValid) + { + _ButtonGroup.PerformLayout(p); + } + bool disposeStyle = false; + ElementStyle style = ElementStyleDisplay.GetElementStyle(_BackgroundStyle, out disposeStyle); + _ButtonGroup.RenderBounds = new Rectangle(this.Width - (ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border) + 1) - _ButtonGroup.Size.Width, ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + 1, + _ButtonGroup.Size.Width, _ButtonGroup.Size.Height); + _ButtonGroup.ProcessPaint(p); + if (disposeStyle) style.Dispose(); + } + private PaintInfo CreatePaintInfo(Graphics g) + { + PaintInfo p = new PaintInfo(); + p.Graphics = g; + p.DefaultFont = this.Font; + p.ForeColor = this.ForeColor; + p.RenderOffset = new System.Drawing.Point(); + Size s = this.Size; + bool disposeStyle = false; + ElementStyle style = ElementStyleDisplay.GetElementStyle(_BackgroundStyle, out disposeStyle); + s.Height -= (ElementStyleLayout.TopWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.BottomWhiteSpace(style, eSpacePart.Border)) + 2; + s.Width -= (ElementStyleLayout.LeftWhiteSpace(style, eSpacePart.Border) + ElementStyleLayout.RightWhiteSpace(style, eSpacePart.Border)) + 2; + p.AvailableSize = s; + p.ParentEnabled = this.Enabled; + p.MouseOver = _IsMouseOver || this.Focused; + if (disposeStyle) style.Dispose(); + return p; + } + #endregion + + #region Tooltip Support + private DevComponents.DotNetBar.ToolTip _ToolTipWnd = null; + /// + /// Shows tooltip for this item. + /// + public virtual void ShowToolTip(EditToken token) + { + if (this.DesignMode || token==null || !token.IsSelected) + return; + + if (this.Visible && this.ShowToolTips ) + { + string tooltip = token.Tooltip; + if (!string.IsNullOrEmpty(tooltip)) + { + if (_ToolTipWnd == null) + _ToolTipWnd = new DevComponents.DotNetBar.ToolTip(); + _ToolTipWnd.Style = StyleManager.GetEffectiveStyle(); + _ToolTipWnd.Text = tooltip; + _ToolTipWnd.ReferenceRectangle = new Rectangle(PointToScreen(token.Bounds.Location), token.Bounds.Size); + + OnToolTipVisibleChanged(new EventArgs()); + _ToolTipWnd.ShowToolTip(); + } + } + } + /// + /// Destroys tooltip window. + /// + internal protected void HideToolTip() + { + if (_ToolTipWnd != null) + { + System.Drawing.Rectangle tipRect = _ToolTipWnd.Bounds; + tipRect.Width += 5; + tipRect.Height += 6; + + OnToolTipVisibleChanged(new EventArgs()); + try + { + if (_ToolTipWnd != null) + { + _ToolTipWnd.Hide(); + _ToolTipWnd.Dispose(); + _ToolTipWnd = null; + } + } + catch { } + this.Invalidate(); + } + } + /// + /// Occurs when item's tooltip visibility has changed. + /// + [System.ComponentModel.Description("Occurs when item's tooltip visibility has changed.")] + public event EventHandler ToolTipVisibleChanged; + private void OnToolTipVisibleChanged(EventArgs eventArgs) + { + EventHandler h = ToolTipVisibleChanged; + if (h != null) + ToolTipVisibleChanged(this, eventArgs); + } + + private bool _ShowToolTips = true; + /// + /// Gets or sets whether tooltips are shown when mouse is over the selected token when Tooltip property is set. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether tooltips are shown when mouse is over the cell when Tooltip property is set.")] + public bool ShowToolTips + { + get { return _ShowToolTips; } + set + { + _ShowToolTips = value; + } + } + + #endregion + + #region IMessageHandlerClient + private bool _MessageHandlerInstalled = false; + bool IMessageHandlerClient.OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.OnMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + if (IsPopupOpen && _PopupController != null) + { + if (!_PopupController.Bounds.Contains(Control.MousePosition)) + { + IsPopupOpen = false; + } + } + return false; + } + + bool IMessageHandlerClient.OnMouseMove(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + return false; + } + + bool IMessageHandlerClient.IsModal + { + get { return false; } + } + #endregion + } + + /// + /// Delegate for the ValidateTokenEvent event. + /// + public delegate void ValidateTokenEventHandler(object sender, ValidateTokenEventArgs ea); + /// + /// Arguments for the ValidateTokenEvent event. + /// + public class ValidateTokenEventArgs : EventArgs + { + /// + /// Indicates whether validated token is valid. Default value is true. When you set this property to false the token being validated will be discared. + /// + public bool IsValid = true; + /// + /// Indicates the Token that will be accepted by the control if IsValid=true. + /// + public EditToken Token = null; + /// + /// Indicates whether token is newly created. When false it means that token was taken from Tokens collection. + /// + public readonly bool IsNewToken; + /// + /// Initializes a new instance of the ValidateTokenEventArgs class. + /// + /// + public ValidateTokenEventArgs(EditToken token, bool isNewToken) + { + Token = token; + IsNewToken = isNewToken; + } + } + /// + /// Delegate for RemovingToken event. + /// + public delegate void RemovingTokenEventHandler(object sender, RemovingTokenEventArgs ea); + /// + /// Defines event arguments for RemovingToken event. + /// + public class RemovingTokenEventArgs : EventArgs + { + /// + /// Indicates the Token that will be removed. + /// + public readonly EditToken Token; + /// + /// Set to true to cancel removal of the token. + /// + public bool Cancel = false; + /// + /// Indicates the source of the event. + /// + public readonly eEventSource EventSource; + /// + /// Initializes a new instance of the RemovingTokenEventArgs class. + /// + /// + public RemovingTokenEventArgs(EditToken token, eEventSource eventSource) + { + Token = token; + EventSource = eventSource; + } + } + + /// + /// Specifies the filter behavior on token editor popup list. + /// + public enum eTokenFilterBehavior + { + /// + /// Token text is searched for the match. + /// + Text, + /// + /// Token value is searched for the match. + /// + Value, + /// + /// Both token text and value are searched for the match. + /// + TextAndValue + } + + /// + /// Delegate for TokenEditor.BeforePopupOpen event. + /// + public delegate void TokenEditorPopupEventHandler(object sender, TokenEditorPopupEventArgs ea); + /// + /// Defines event arguments for BeforePopupOpen event. + /// + public class TokenEditorPopupEventArgs : EventArgs + { + /// + /// Gets or sets the screen location of the popup in relation to the TokenEditor control. + /// + public Point PopupLocation = Point.Empty; + /// + /// Gets the suggested popup size. + /// + public readonly Size PopupSize; + /// + /// Initializes a new instance of the TokenEditorPopupEventArgs class. + /// + /// + public TokenEditorPopupEventArgs(Point popupLocation, Size popupSize) + { + PopupLocation = popupLocation; + PopupSize = popupSize; + } + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/TokenEditor/TokenEditorColorTable.cs b/PROMS/DotNetBar Source Code/Controls/TokenEditor/TokenEditorColorTable.cs new file mode 100644 index 00000000..1b4fb127 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/TokenEditor/TokenEditorColorTable.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Rendering +{ + /// + /// Represents the color table for TokenEditor control tokens. + /// + public class TokenEditorColorTable + { + /// + /// Initializes a new instance of the TokenEditorColorTable class. + /// + public TokenEditorColorTable() + { + + } + /// + /// Initializes a new instance of the TokenEditorColorTable class. + /// + public TokenEditorColorTable(int normalTextColor, int normalBackground, int mouseOverTextColor, int mouseOverBackground, int focusedTextColor, int focusedBackground) + { + Normal = new TokenColorTable(normalTextColor, normalBackground); + MouseOver = new TokenColorTable(mouseOverTextColor, mouseOverBackground); + Focused = new TokenColorTable(focusedTextColor, focusedBackground); + } + /// + /// Initializes a new instance of the TokenEditorColorTable class. + /// + public TokenEditorColorTable(Color normalTextColor, Color normalBackground, Color mouseOverTextColor, Color mouseOverBackground, Color focusedTextColor, Color focusedBackground) + { + Normal = new TokenColorTable(normalTextColor, normalBackground); + MouseOver = new TokenColorTable(mouseOverTextColor, mouseOverBackground); + Focused = new TokenColorTable(focusedTextColor, focusedBackground); + } + /// + /// Gets or sets token default state colors. + /// + public TokenColorTable Normal = new TokenColorTable(0x000000, 0xDBE9FC); + /// + /// Gets or sets token mouse over state colors. + /// + public TokenColorTable MouseOver = new TokenColorTable(0x000000, 0xBFDBFF); + /// + /// Gets or sets token focused state colors. + /// + public TokenColorTable Focused = new TokenColorTable(0xFFFFFF, 0x0072C6); + } + + /// + /// Represents the state color table for token in TokenEditor control. + /// + public class TokenColorTable + { + /// + /// Initializes a new instance of the TokenColorTable class. + /// + public TokenColorTable() + { + } + /// + /// Initializes a new instance of the TokenColorTable class. + /// + /// + /// + public TokenColorTable(Color textColor, Color background) + { + TextColor = textColor; + Background = new LinearGradientColorTable(background); + } + /// + /// Initializes a new instance of the TokenColorTable class. + /// + /// + /// + public TokenColorTable(int textColor, int background) + { + TextColor = ColorScheme.GetColor(textColor); + Background = new LinearGradientColorTable(background); + } + /// + /// Gets or sets token text color. + /// + public Color TextColor = Color.Black; + /// + /// Gets or sets the background color table. + /// + public LinearGradientColorTable Background = new LinearGradientColorTable(0xE5EEF8); + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Toolbox/ToolboxControl.cs b/PROMS/DotNetBar Source Code/Controls/Toolbox/ToolboxControl.cs new file mode 100644 index 00000000..af74dcf1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Toolbox/ToolboxControl.cs @@ -0,0 +1,1162 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Xml; +using DevComponents.AdvTree; +using DevComponents.DotNetBar.Primitives; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents Toolbox control to create. + /// + [ToolboxBitmap(typeof(ToolboxControl), "Controls.ToolboxControl.bmp"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.ToolboxControlDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.Runtime.InteropServices.ComVisible(false)] + public class ToolboxControl : ContainerControl + { + #region Implementation + + private ItemPanel _ItemPanel = null; + private Bar _TitleBar = null; + private TextBoxX _SearchBox = null; + private Bar _MenuBar = null; + + public ToolboxControl() + { + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + _BackgroundStyle.Class = ElementStyleClassKeys.ToolboxControlKey; + this.Padding = new System.Windows.Forms.Padding(2); + + this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque | + ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.Selectable, true); + + _ItemPanel = CreateItemsPanel(); + this.Controls.Add(_ItemPanel); + + _MenuBar = CreateMenuBar(); + this.Controls.Add(_MenuBar); + + _SearchBox = CreateSearchBox(); + this.Controls.Add(_SearchBox); + + _TitleBar = CreateTitleBar(); + this.Controls.Add(_TitleBar); + + _SelectedItems = new CustomCollection(); + + _Groups.CollectionChanged += GroupsCollectionChanged; + } + + private void GroupsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + int index = e.NewStartingIndex; + foreach (ToolboxGroup group in e.NewItems) + { + _ItemPanel.Items.Insert(index, group); + index++; + } + } + else if (e.Action == NotifyCollectionChangedAction.Remove) + { + foreach (ToolboxGroup group in e.OldItems) + _ItemPanel.Items.Remove(group); + } + else if (e.Action == NotifyCollectionChangedAction.Reset) + { + _ItemPanel.Items.Clear(); + if (e.NewItems != null) + { + foreach (ToolboxGroup group in e.NewItems) + _ItemPanel.Items.Add(group); + } + } + else if (e.Action == NotifyCollectionChangedAction.Replace) + { + _ItemPanel.Items.Remove(e.NewStartingIndex); + _ItemPanel.Items.Insert(e.NewStartingIndex, (BaseItem)e.NewItems[0]); + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + } + + private ButtonItem _MenuButton = null; + private Bar CreateMenuBar() + { + Bar menuBar = new Bar(); + menuBar.Name = "menuBar"; + menuBar.AntiAlias = true; + menuBar.BackColor = System.Drawing.Color.Transparent; + menuBar.Dock = System.Windows.Forms.DockStyle.Top; + menuBar.Font = new System.Drawing.Font("Segoe UI", 9F); + menuBar.IsMaximized = false; + menuBar.Location = new System.Drawing.Point(6, 93); + menuBar.PaddingBottom = 4; + menuBar.PaddingTop = 4; + menuBar.Size = new System.Drawing.Size(365, 61); + menuBar.Stretch = true; + menuBar.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + menuBar.TabIndex = 2; + menuBar.TabStop = false; + + ButtonItem menuButton = new ButtonItem("menuButton"); + menuButton.AutoExpandOnClick = true; + menuButton.ButtonStyle = DevComponents.DotNetBar.eButtonStyle.ImageAndText; + menuButton.ImagePaddingHorizontal = 30; + menuButton.ImagePaddingVertical = 12; + menuButton.ImagePosition = DevComponents.DotNetBar.eImagePosition.Right; + menuButton.PopupSide = DevComponents.DotNetBar.ePopupSide.Right; + menuButton.Text = "Menu"; + menuButton.SubItems.Add(new ButtonItem()); // Just placeholder + menuButton.PopupOpen += MenuButtonPopupOpen; + menuButton.PopupClose += MenuButtonPopupClose; + _MenuButton = menuButton; + + menuBar.Items.AddRange(new DevComponents.DotNetBar.BaseItem[] { + menuButton}); + + return menuBar; + } + + /// + /// Gets the Bar control used as menu bar. + /// + [Browsable(false)] + public Bar MenuBar + { + get { return _MenuBar; } + } + + private void MenuButtonPopupClose(object sender, EventArgs e) + { + ClearAndDisposeMenuItems(); + _MenuButton.SubItems.Add(new ButtonItem()); + } + + private void ClearAndDisposeMenuItems() + { + foreach (BaseItem item in _MenuButton.SubItems) + { + item.Dispose(); + } + _MenuButton.SubItems.Clear(); + } + + private void MenuButtonPopupOpen(object sender, PopupOpenEventArgs e) + { + ClearAndDisposeMenuItems(); + foreach (BaseItem item in this.Groups) + { + ToolboxGroup group = item as ToolboxGroup; + if (group != null) + { + ButtonItem menuItem = new ButtonItem(); + menuItem.Text = group.TitleText; + menuItem.Click += MenuItemClick; + menuItem.Tag = group; + _MenuButton.SubItems.Add(menuItem); + } + } + } + + private void MenuItemClick(object sender, EventArgs e) + { + ToolboxGroup group = ((BaseItem)sender).Tag as ToolboxGroup; + if (group != null) + group.Expanded = true; + } + + private string _SearchBoxWatermark = "Enter text to search..."; + + /// + /// Indicates the search-box watermark text. + /// + [DefaultValue("Enter text to search..."), Category("Appearance"), Description("Indicates the search-box watermark text."), Localizable(true)] + public string SearchBoxWatermark + { + get { return _SearchBoxWatermark; } + set + { + if (_SearchBoxWatermark != value) + { + string oldValue = value; + _SearchBoxWatermark = value; + OnSearchBoxWatermarkChanged(oldValue, value); + } + } + } + + protected virtual void OnSearchBoxWatermarkChanged(string oldValue, string newValue) + { + _SearchBox.WatermarkText = newValue; + } + + private TextBoxX CreateSearchBox() + { + TextBoxX searchBox = new TextBoxX(); + searchBox.Name = "searchBox"; + searchBox.Border.Class = "TextBoxBorder"; + searchBox.Border.CornerType = DevComponents.DotNetBar.eCornerType.Square; + searchBox.ButtonCustom.Symbol = ""; + searchBox.ButtonCustom.Visible = true; + searchBox.ButtonCustomClick += SearchBoxButtonCustomClick; + searchBox.Dock = System.Windows.Forms.DockStyle.Top; + searchBox.Location = new System.Drawing.Point(6, 55); + searchBox.PreventEnterBeep = true; + searchBox.Size = new System.Drawing.Size(365, 38); + searchBox.TabIndex = 0; + searchBox.WatermarkText = "Enter text to search..."; + searchBox.TextChanged += SearchBoxTextChanged; + searchBox.WordWrap = false; + + return searchBox; + } + /// + /// Returns reference to internal search text-box. + /// + [Browsable(false)] + public TextBoxX SearchBoxTextBox + { + get { return _SearchBox; } + } + + void SearchBoxButtonCustomClick(object sender, EventArgs e) + { + _SearchBox.Text = string.Empty; + } + + private void SearchBoxTextChanged(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(_SearchBox.Text)) + _SearchBox.ButtonCustom.Symbol = "\uf002"; + else + _SearchBox.ButtonCustom.Symbol = "\uf00d"; + Search(_SearchBox.Text); + } + + private ButtonItem _ExpandButton = null; + private LabelItem _TitleLabel = null; + private Bar CreateTitleBar() + { + Bar titleBar = new Bar(); + titleBar.Name = "titleBar"; + titleBar.AntiAlias = true; + titleBar.BackColor = System.Drawing.Color.Transparent; + titleBar.Dock = System.Windows.Forms.DockStyle.Top; + titleBar.IsMaximized = false; + titleBar.Location = new System.Drawing.Point(6, 6); + titleBar.PaddingBottom = 4; + titleBar.PaddingTop = 4; + titleBar.Size = new System.Drawing.Size(365, 49); + titleBar.Stretch = true; + titleBar.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + titleBar.TabIndex = 0; + titleBar.TabStop = false; + + LabelItem toolboxLabel = new LabelItem("toolboxLabel"); + toolboxLabel.Text = "Toolbox"; + _TitleLabel = toolboxLabel; + + ButtonItem expandButton = new ButtonItem("expandButton"); + expandButton.ItemAlignment = DevComponents.DotNetBar.eItemAlignment.Far; + expandButton.Symbol = "\uf053"; + expandButton.SymbolSize = 10F; + expandButton.Click += ExpandButtonClick; + _ExpandButton = expandButton; + + titleBar.Items.AddRange(new DevComponents.DotNetBar.BaseItem[] { + toolboxLabel, + expandButton}); + + return titleBar; + } + + private string _TitleText = "Toolbox"; + + /// + /// Indicates the title label text. + /// + [DefaultValue("Toolbox"), Category("Appearance"), Description("Indicates the title label text."), Localizable(true)] + public string TitleText + { + get { return _TitleText; } + set + { + if (_TitleText != value) + { + string oldValue = value; + _TitleText = value; + OnTitleTextChanged(oldValue, value); + } + } + } + + protected virtual void OnTitleTextChanged(string oldValue, string newValue) + { + _TitleLabel.Text = newValue; + } + + /// + /// Gets the Bar control used as title bar. + /// + [Browsable(false)] + public Bar TitleBar + { + get { return _TitleBar; } + } + + private void ExpandButtonClick(object sender, EventArgs e) + { + this.Expanded = !this.Expanded; + } + + private ItemPanel CreateItemsPanel() + { + ItemPanel itemPanel = new ItemPanel(); + itemPanel.Dock = DockStyle.Fill; + itemPanel.LayoutOrientation = eOrientation.Vertical; + itemPanel.AutoScroll = true; +#if !TRIAL + itemPanel.LicenseKey = "F962CEC7-CD8F-4911-A9E9-CAB39962FC1F"; +#endif + itemPanel.ItemClick += ItemPanelItemClick; + itemPanel.DragDropSupport = true; + itemPanel.EnableDragDrop = true; + itemPanel.UseNativeDragDrop = true; + itemPanel.AllowDrop = true; + itemPanel.BeforeItemDrag += ItemsPanelBeforeItemDrag; + itemPanel.GetBaseItemContainer().SubItemsChanged += ItemsChanged; + itemPanel.DragDropAllowedContainerTypes.Add(typeof(ToolboxGroup)); + return itemPanel; + } + + private void ItemsChanged(object sender, CollectionChangeEventArgs e) + { + if (!IsUpdateSuspended) + this.RecalcLayout(); + } + + private int _UpdateSuspended = 0; + /// + /// Disables any redrawing of the tree control. To maintain performance while items + /// are added one at a time to the control, call the BeginUpdate method. The BeginUpdate + /// method prevents the control from painting until the + /// EndUpdate method is called. + /// + public void BeginUpdate() + { + _UpdateSuspended++; + } + + /// + /// Enables the redrawing of the tree view. To maintain performance while items are + /// added one at a time to the control, call the BeginUpdate + /// method. The BeginUpdate method prevents the control from painting until the EndUpdate + /// method is called. + /// + /// + /// Call to EndUpdate will enable the layout and painting in tree control. If there + /// are any pending layouts the EndUpdate will call + /// RecalcLayout method to perform the layout and it will + /// repaint the control. + /// + public void EndUpdate() + { + EndUpdate(true); + } + + /// + /// Enables the redrawing of the tree view. To maintain performance while items are + /// added one at a time to the control, call the BeginUpdate + /// method. The BeginUpdate method prevents the control from painting until the EndUpdate + /// method is called. + /// + /// Gets or sets whether layout and refresh of control is performed if there are no other update blocks pending. + public void EndUpdate(bool performLayoutAndRefresh) + { + if (_UpdateSuspended > 0) _UpdateSuspended--; + if (_UpdateSuspended == 0 && performLayoutAndRefresh) + { + this.RecalcLayout(); + this.Invalidate(true); + } + } + + /// + /// Gets whether layout is suspended for tree control. Layout is suspended after + /// call to BeginUpdate method and it is resumed after the + /// call to EndUpdate method. + /// + [Browsable(false)] + public bool IsUpdateSuspended + { + get { return (_UpdateSuspended > 0); } + } + + public void RecalcLayout() + { + _ItemPanel.RecalcLayout(); + } + + /// + /// Returns reference to internal item panel used to display the toolbox items and groups. + /// + [Browsable(false)] + public ItemPanel ItemsPanel + { + get { return _ItemPanel; } + } + + private void ItemsPanelBeforeItemDrag(object sender, CancelEventArgs e) + { + OnBeforeItemDrag(sender, e); + } + + /// + /// Returns collection of toolbox control groups, collection of ToolboxGroup items. + /// + //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] + //[System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ToolboxControlGroupsEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + //public SubItemsCollection Groups + //{ + // get { return _ItemPanel.GetBaseItemContainer().SubItems; } + //} + + private CustomCollection _Groups = new CustomCollection(); + /// + /// Gets the list of items displayed in list box. + /// + [Category("Appearance"), Description("List of items displayed in list box."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), MergableProperty(false), Localizable(false)] + public CustomCollection Groups + { + get { return _Groups; } + } + + private bool _ExpandSingleGroupOnly = true; + + /// + /// Indicates whether single group only is expanded at a time. When new group is expanded currently expanded group is collapsed. + /// + [DefaultValue(true), Category("Behavior"), + Description("Indicates whether single toolbox group only is expanded at a time")] + public bool ExpandSingleGroupOnly + { + get { return _ExpandSingleGroupOnly; } + set { _ExpandSingleGroupOnly = value; } + } + + /// + /// Occurs after Expanded property value has changed + /// + [Description("Occurs after Expanded property value has changed")] + public event EventHandler ExpandedChanged; + + /// + /// Raises ExpandedChanged event. + /// + /// Provides event arguments. + protected virtual void OnExpandedChanged(EventArgs e) + { + EventHandler handler = ExpandedChanged; + if (handler != null) + handler(this, e); + } + + private bool _Expanded = true; + /// + /// Gets or sets whether control is expanded and shows items in full size with image and text. When collapsed + /// control will show only images for toolbox items and will hide other UI elements to minimize its size. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether control is expanded and shows items in full size with images and text")] + public bool Expanded + { + get { return _Expanded; } + set + { + if (_Expanded != value) + { + _Expanded = value; + OnExpandedChanged(); + } + } + } + + private Color _CollapsedSeparatorColor = Color.Gray; + + /// + /// Indicates the collapsed toolbox separator color, the line drawn between the toolbox and menu/expand buttons above. + /// + [Category("Appearance"), Description("Indicates the collapsed toolbox separator color, the line drawn between the toolbox and menu/expand buttons above.")] + public Color CollapsedSeparatorColor + { + get { return _CollapsedSeparatorColor; } + set + { + _CollapsedSeparatorColor = value; + if (!_Expanded) + { + _MenuBar.Invalidate(); + _MenuBar.BorderColors = new Color[] { Color.Empty, Color.Empty, Color.Empty, _CollapsedSeparatorColor }; + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCollapsedSeparatorColor() + { + return _CollapsedSeparatorColor != Color.Gray; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetCollapsedSeparatorColor() + { + CollapsedSeparatorColor = Color.Gray; + } + + /// + /// Gets or sets the expanded width of the control. This property value is valid after control has been collapsed. + /// + [Browsable(false)] + public int ExpandedWidth + { + get { return _ExpandedWidth; } + set { _ExpandedWidth = value; } + } + + private List _CollapsedList = new List(); + private int _ExpandedWidth = 0; + protected virtual void OnExpandedChanged() + { + OnExpandedChanged(EventArgs.Empty); + if (!_Expanded) + { + _ExpandedWidth = this.Width; + _ExpandButton.Symbol = "\uf054"; + _MenuButton.ButtonStyle = eButtonStyle.Default; + _TitleLabel.Visible = false; + + _MenuButton.Symbol = "\ue037"; + _MenuButton.SymbolSet = eSymbolSet.Material; + _MenuButton.SymbolSize = 10f; + _MenuButton.ButtonStyle = eButtonStyle.Default; + _MenuButton.ImagePaddingHorizontal = 8; + _MenuButton.ImagePaddingVertical = 6; + _MenuButton.ImagePosition = eImagePosition.Left; + _MenuButton.ShowSubItems = false; + _MenuBar.BorderColors = new Color[] { Color.Empty, Color.Empty, Color.Empty, _CollapsedSeparatorColor }; + + _SearchBox.Visible = false; + + // Collapse everything + foreach (BaseItem item in _ItemPanel.Items) + { + if (!(item is ToolboxGroup)) continue; + + ToolboxGroup group = (ToolboxGroup)item; + BaseItemAutoSizeBag bagGroup = AutoSizeBagFactory.CreateAutoSizeBag(group); + bagGroup.RecordSetting(item); + _CollapsedList.Add(bagGroup); + group.TitleVisible = false; + group.LayoutOrientation = eOrientation.Vertical; + group.MultiLine = false; + foreach (BaseItem ti in group.SubItems) + { + ButtonItem tbItem = ti as ButtonItem; + if (tbItem != null) + { + BaseItemAutoSizeBag bagItem = AutoSizeBagFactory.CreateAutoSizeBag(tbItem); + bagItem.RecordSetting(tbItem); + _CollapsedList.Add(bagItem); + tbItem.ButtonStyle = eButtonStyle.Default; + } + } + } + } + else + { + // Expand everything + _ExpandButton.Symbol = "\uf053"; + _MenuBar.BorderColors = new Color[0]; + _MenuButton.ButtonStyle = eButtonStyle.ImageAndText; + _TitleLabel.Visible = true; + + _MenuButton.Symbol = string.Empty; + _MenuButton.ButtonStyle = eButtonStyle.Default; + _MenuButton.ImagePaddingHorizontal = 30; + _MenuButton.ImagePaddingVertical = 12; + _MenuButton.ImagePosition = DevComponents.DotNetBar.eImagePosition.Right; + _MenuButton.ShowSubItems = true; + _MenuBar.BorderColors = new Color[0]; + + _SearchBox.Visible = true; + + BaseItemAutoSizeBag[] bagItems = new BaseItemAutoSizeBag[_CollapsedList.Count]; + _CollapsedList.CopyTo(bagItems); + foreach (BaseItemAutoSizeBag ab in bagItems) + ab.RestoreSettings(); + + _CollapsedList.Clear(); + + this.Width = _ExpandedWidth; + } + + _ItemPanel.RecalcLayout(); + + if (_Expanded) + { + _MenuButton.FixedSize = Size.Empty; + _ExpandButton.FixedSize = Size.Empty; + } + else + { + int itemsWidth = UpdateCollapsedWidth(); + _MenuButton.FixedSize = new Size(itemsWidth - Dpi.Width2, _MenuButton.HeightInternal); + _ExpandButton.FixedSize = new Size(itemsWidth - Dpi.Width2, _ExpandButton.HeightInternal); + + } + + _MenuBar.RecalcLayout(); + _TitleBar.RecalcLayout(); + } + + private int UpdateCollapsedWidth() + { + int itemsWidth = GetItemsWidth(); + int width = itemsWidth + + ElementStyleLayout.LeftWhiteSpace(_ItemPanel.BackgroundStyle, eSpacePart.Margin | eSpacePart.Padding) + + ElementStyleLayout.RightWhiteSpace(_ItemPanel.BackgroundStyle, eSpacePart.Padding | eSpacePart.Margin) + this.Padding.Horizontal; + _MenuButton.FixedSize = new Size(itemsWidth - Dpi.Width2, _MenuButton.HeightInternal); + _ExpandButton.FixedSize = new Size(itemsWidth - Dpi.Width2, _ExpandButton.HeightInternal); + this.Width = width; + return itemsWidth; + } + + private int GetItemsWidth() + { + int width = 0; + bool scrollBar = false; + foreach (BaseItem item in _ItemPanel.Items) + { + if (item is ToolboxGroup) + { + foreach (BaseItem ti in item.SubItems) + { + if (ti is ButtonItem && ti.WidthInternal > width) + width = ti.WidthInternal; + } + } + if (item.Bounds.Bottom > this.ClientRectangle.Height) scrollBar = true; + } + + if (scrollBar) + width += SystemInformation.VerticalScrollBarWidth; + + if (width == 0) + width = 32; + + return width; + } + + /// + /// Occurs after toolbox group is expanded + /// + [Description("Occurs after toolbox group is expanded")] + public event EventHandler ToolboxGroupExpanded; + + /// + /// Raises RemovingToken event. + /// + /// Provides source of the event. + /// Provides event arguments. + protected virtual void OnToolboxGroupExpanded(object sender, EventArgs e) + { + EventHandler handler = ToolboxGroupExpanded; + if (handler != null) + handler(sender, e); + } + internal void InvokeToolboxGroupExpanded(ToolboxGroup toolboxGroup) + { + if (!_Expanded) + { + // Adjust width of collapsed control if needed + UpdateCollapsedWidth(); + } + OnToolboxGroupExpanded(toolboxGroup, EventArgs.Empty); + } + + private eToolboxItemSelectionMode _SelectionMode = eToolboxItemSelectionMode.Single; + + /// + /// Indicates toolbox item selection mode. + /// + [DefaultValue(eToolboxItemSelectionMode.Single), Category("Behavior"), Description("Indicates toolbox item selection mode.")] + public eToolboxItemSelectionMode SelectionMode + { + get { return _SelectionMode; } + set + { + if (_SelectionMode != value) + { + _SelectionMode = value; + OnSelectionModeChanged(); + } + } + } + + protected virtual void OnSelectionModeChanged() + { + + } + + void ItemPanelItemClick(object sender, EventArgs e) + { + if (_SelectionMode == eToolboxItemSelectionMode.NoSelection) return; + + ToolboxItem item = sender as ToolboxItem; + if (item == null || item.AutoCheckOnClick || item.Checked && (Control.ModifierKeys & Keys.Control) == Keys.None) return; + + if (item.Checked) + SetSelectedItem(item, false); + else + SetSelectedItem(item, true); + + } + + /// + /// Selects or deselects an item. + /// + /// Item to select or deselect. + /// Selection state. + public void SetSelectedItem(ToolboxItem item, bool isSelected) + { + if (_SelectionMode == eToolboxItemSelectionMode.Single) + { + if (_SelectedItem == item && !isSelected) + this.SelectedItem = null; + else if (isSelected) + this.SelectedItem = item; + } + else if (item.Checked != isSelected) + { + item.Checked = isSelected; + } + } + + /// + /// Occurs after selected item has changed. + /// + [Description("Occurs after selected item has changed. ")] + public event EventHandler SelectedItemChanged; + + /// + /// Raises RemovingToken event. + /// + /// Provides event arguments. + protected virtual void OnSelectedItemChanged(EventArgs e) + { + EventHandler handler = SelectedItemChanged; + if (handler != null) + handler(this, e); + } + + private CustomCollection _SelectedItems; + /// + /// Gets a collection containing the currently selected items in the ToolboxControl. Do not modify items in this collection. To select or deselect list items while in multi-selection mode use SetSelected method. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CustomCollection SelectedItems + { + get + { + return _SelectedItems; + } + } + + private ToolboxItem _SelectedItem; + /// + /// Gets or sets selected item in toolbox control. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ToolboxItem SelectedItem + { + get { return _SelectedItem; } + set + { + if (_SelectedItem != value) + { + ToolboxItem oldValue = _SelectedItem; + _SelectedItem = value; + OnSelectedItemChanged(oldValue, value); + } + } + } + + private bool _IgnoreCheckedChange = false; + protected virtual void OnSelectedItemChanged(ToolboxItem oldValue, ToolboxItem newValue) + { + if (oldValue != null) + { + if (newValue != null) _IgnoreCheckedChange = true; + oldValue.Checked = false; + _IgnoreCheckedChange = false; + } + if (newValue != null) newValue.Checked = true; + } + + internal void ToolboxItemCheckedChanged(ToolboxItem toolboxItem) + { + if (_SelectionMode == eToolboxItemSelectionMode.Single) + { + _SelectedItems.Clear(); + if (toolboxItem.Checked) + _SelectedItem = toolboxItem; + } + else + { + if (!toolboxItem.Checked && _SelectedItems.Contains(toolboxItem)) + _SelectedItems.Remove(toolboxItem); + else if (toolboxItem.Checked) + _SelectedItems.Add(toolboxItem); + } + if (!_IgnoreCheckedChange) + OnSelectedItemChanged(EventArgs.Empty); + } + + private bool _TitleVisible = true; + + /// + /// Indicates whether title bar of the control is visible, default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether title bar of the control is visible.")] + public bool TitleVisible + { + get { return _TitleVisible; } + set + { + if (_TitleVisible != value) + { + bool oldValue = value; + _TitleVisible = value; + OnTitleVisibleChanged(oldValue, value); + } + } + } + + protected virtual void OnTitleVisibleChanged(bool oldValue, bool newValue) + { + _TitleBar.Visible = newValue; + } + + private bool _MenuVisible = true; + + /// + /// Indicates whether menu bar of the control is visible, default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether menu bar of the control is visible")] + public bool MenuVisible + { + get { return _MenuVisible; } + set + { + if (_MenuVisible != value) + { + bool oldValue = value; + _MenuVisible = value; + OnMenuVisibleChanged(oldValue, value); + } + } + } + + protected virtual void OnMenuVisibleChanged(bool oldValue, bool newValue) + { + _MenuBar.Visible = newValue; + } + + private bool _SearchBoxVisible = true; + /// + /// Gets or set whether search text-box which allows searching for the toolbox items is visible. Default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether search text-box which allows searching for the toolbox items is visible.")] + public bool SearchBoxVisible + { + get { return _SearchBoxVisible; } + set + { + if (_SearchBoxVisible != value) + { + _SearchBoxVisible = value; + OnSearchBoxVisibleChanged(); + } + } + } + + private bool _SearchForEachWord = true; + + /// + /// Indicates whether search text when entered is split into separate words and items returned that match any of the words entered. + /// + [Category("Behavior"), DefaultValue(true), Description("Indicates whether search text when entered is split into separate words and items returned that match any of the words entered.")] + public bool SearchForEachWord + { + get { return _SearchForEachWord; } + set + { + if (_SearchForEachWord != value) + { + bool oldValue = value; + _SearchForEachWord = value; + OnSearchForEachWordChanged(oldValue, value); + } + } + } + + protected virtual void OnSearchForEachWordChanged(bool oldValue, bool newValue) + { + + } + + private void OnSearchBoxVisibleChanged() + { + _SearchBox.Visible = _SearchBoxVisible; + } + + private bool _IsSearching = false; + private List _HiddenItems = new List(); + private List _ExpandedGroups = new List(); + private string _LastSearchText = string.Empty; + /// + /// Filters control toolbox items based on specified text. To clear last search and show all items pass string.empty or null/nothing as search text. + /// + /// Text to search for + public void Search(string text) + { + _IsSearching = true; + RestoreHiddenItems(); + + if (!string.IsNullOrEmpty(text)) + { + text = text.ToLower(); + string[] wordList = text.Split(' '); + foreach (BaseItem item in _ItemPanel.Items) + { + ToolboxGroup group = item as ToolboxGroup; + if (group == null) continue; + if (group.Expanded) _ExpandedGroups.Add(group); + group.Expanded = true; + foreach (BaseItem groupItem in group.SubItems) + { + ToolboxItem ti = groupItem as ToolboxItem; + if (ti == null) + { + ti.Visible = false; + _HiddenItems.Add(ti); + continue; + } + if (!((!_SearchForEachWord || wordList.Length < 2) && ti.Text.ToLower().Contains(text) || + _SearchBoxVisible && ContainsAny(ti.Text.ToLower(), wordList))) + { + ti.Visible = false; + _HiddenItems.Add(ti); + } + } + if (group.VisibleSubItems == 0) + { + group.Visible = false; + _HiddenItems.Add(group); + } + } + } + _ItemPanel.RecalcLayout(); + _IsSearching = false; + _LastSearchText = text; + } + + /// + /// Gets whether control is performing search operation. + /// + [Browsable(false)] + public bool IsSearching + { + get { return _IsSearching; } + } + + private void RestoreHiddenItems() + { + bool restoreExpanded = _HiddenItems.Count > 0 || !string.IsNullOrEmpty(_LastSearchText); + if (_HiddenItems.Count > 0) + { + foreach (BaseItem item in _HiddenItems) + { + item.Visible = true; + } + _HiddenItems.Clear(); + } + + if (restoreExpanded) + { + foreach (BaseItem item in _ItemPanel.Items) + { + ToolboxGroup group = item as ToolboxGroup; + if (group == null) continue; + if (_ExpandedGroups.Contains(group)) + group.Expanded = true; + else + group.Expanded = false; + } + _ExpandedGroups.Clear(); + } + } + + private ElementStyle _BackgroundStyle = new ElementStyle(); + /// + /// Specifies the background style of the control. + /// + [Browsable(true), DevCoBrowsable(true), Category("Style"), Description("Gets or sets bar background style."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle BackgroundStyle + { + get { return _BackgroundStyle; } + } + + /// + /// Resets style to default value. Used by windows forms designer. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackgroundStyle() + { + _BackgroundStyle.StyleChanged -= new EventHandler(this.VisualPropertyChanged); + _BackgroundStyle = new ElementStyle(); + _BackgroundStyle.StyleChanged += new EventHandler(this.VisualPropertyChanged); + this.Invalidate(); + } + + private void VisualPropertyChanged(object sender, EventArgs e) + { + OnVisualPropertyChanged(); + } + + protected virtual void OnVisualPropertyChanged() + { + this.Invalidate(); + } + + private void PaintStyleBackground(Graphics g) + { + if (!this.BackColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(this.BackColor)) + g.FillRectangle(brush, this.ClientRectangle); + } + + ElementStyleDisplayInfo info = new ElementStyleDisplayInfo(); + info.Bounds = this.ClientRectangle; + info.Graphics = g; + bool disposeStyle = false; + ElementStyle style = ElementStyleDisplay.GetElementStyle(_BackgroundStyle, out disposeStyle); + info.Style = style; + ElementStyleDisplay.Paint(info); + if (disposeStyle) + style.Dispose(); + } + + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + + PaintStyleBackground(g); + + base.OnPaint(e); + } + + // + /// Occurs before an item drag & drop operation is started and allows cancellation. + /// + [Description("Occurs before an item drag & drop operation is started and allows cancellation")] + public event CancelEventHandler BeforeItemDrag; + /// + /// Raises BeforeItemDrag event. + /// + /// Item being dragged. + /// Provides event arguments. + protected virtual void OnBeforeItemDrag(object itemSource, CancelEventArgs e) + { + CancelEventHandler handler = BeforeItemDrag; + if (handler != null) + handler(itemSource, e); + } + + private static bool ContainsAny(string textToSearch, params string[] wordsList) + { + foreach (string word in wordsList) + { + if (textToSearch.Contains(word)) + return true; + } + + return false; + } + + /// + /// Indicates whether item drag and drop is enabled. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether item drag and drop is enabled. Default value is true.")] + public bool ItemDragDropEnabled + { + get { return _ItemPanel.EnableDragDrop; } + set { _ItemPanel.EnableDragDrop = value; } + } + + /// + /// Indicates whether toolbox items can be rearranged using drag & drop. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether toolbox items can be rearranged using drag & drop.")] + public bool ItemRearrangeEnabled + { + get { return _ItemPanel.AllowDrop; } + set { _ItemPanel.AllowDrop = value; } + } + #endregion + + #region Licensing +#if !TRIAL + private string m_LicenseKey = ""; + private bool m_DialogDisplayed = false; + [Browsable(false), DefaultValue("")] + public string LicenseKey + { + get { return m_LicenseKey; } + set + { + if (NodeOperations.ValidateLicenseKey(value)) + return; + m_LicenseKey = (!NodeOperations.CheckLicenseKey(value) ? "9dsjkhds7" : value); + } + } +#endif + #endregion + + } + + /// + /// Defines selection modes for toolbox control items. + /// + public enum eToolboxItemSelectionMode + { + /// + /// No item selection is allowed. + /// + NoSelection, + /// + /// Only single item can be selected. + /// + Single, + /// + /// Multiple items can be selected. + /// + Multiple + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Toolbox/ToolboxGroup.cs b/PROMS/DotNetBar Source Code/Controls/Toolbox/ToolboxGroup.cs new file mode 100644 index 00000000..52b9445f --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Toolbox/ToolboxGroup.cs @@ -0,0 +1,297 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using DevComponents.UI.ContentManager; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents a group in ToolboxControl + /// + [ToolboxItem(false), DesignTimeVisible(false), DefaultEvent("Click"), Designer("DevComponents.DotNetBar.Design.ToolboxGroupDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ToolboxGroup : ItemContainer + { + #region Constructor + + /// + /// Creates new instance of the ItemContainer object. + /// + public ToolboxGroup() + { + this.MultiLine = true; + this.ResizeItemsToFit = false; + this.TitleStyle.Class = ElementStyleClassKeys.ToolboxGroupTitleKey; + this.TitleMouseOverStyle.Class = ElementStyleClassKeys.ToolboxGroupTitleMouseOverKey; + this.GlobalItem = false; + this.EqualItemSize = true; + _TitleGroupExpandedStyle = new ElementStyle(); + _TitleGroupExpandedStyle.StyleChanged += TitleGroupExpandedStyleChanged; + _TitleGroupExpandedStyle.Class = ElementStyleClassKeys.ToolboxGroupExpandedTitleKey; + //this.CanCustomize = false; + } + /// + /// Creates new instance of the ItemContainer object. + /// + public ToolboxGroup(string groupText) + : this() + { + this.TitleText = groupText; + } + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + ToolboxGroup objCopy = new ToolboxGroup(this.Name); + this.CopyToItem(objCopy); + return objCopy; + } + + /// + /// Copies the ButtonItem specific properties to new instance of the item. + /// + /// New ButtonItem instance. + internal void InternalCopyToItem(ButtonItem copy) + { + CopyToItem((BaseItem)copy); + } + + /// + /// Copies the ButtonItem specific properties to new instance of the item. + /// + /// New ButtonItem instance. + protected override void CopyToItem(BaseItem copy) + { + ToolboxGroup copyGroup = copy as ToolboxGroup; + base.CopyToItem(copyGroup); + if (copyGroup != null) + { + copyGroup.ResizeItemsToFit = this.ResizeItemsToFit; + } + } + + #endregion + + #region Implementation + private List _HiddenItems = new List(); + /// + /// Occurs when Expanded state changes. If overridden base implementation must be called so default processing can occur. + /// + protected internal override void OnExpandChange() + { + ApplyExpandedProperty(); + base.OnExpandChange(); + } + + private void ApplyExpandedProperty() + { + ToolboxControl tc = GetToolboxControl(); + bool supressRecalcLayout = false; + if (tc != null && tc.IsSearching) supressRecalcLayout = true; + + if (this.Expanded) + { + foreach (BaseItem item in _HiddenItems) + { + item.Visible = true; + } + _HiddenItems.Clear(); + if (tc != null) + { + if (tc.ExpandSingleGroupOnly && !tc.IsSearching) + { + foreach (BaseItem item in tc.Groups) + { + ToolboxGroup group = item as ToolboxGroup; + if (group != null && group != this && group.Expanded) + group.Expanded = false; + } + } + if (!supressRecalcLayout) + this.RecalcLayout(); + tc.InvokeToolboxGroupExpanded(this); + } + } + else + { + foreach (BaseItem item in this.SubItems) + { + if (item.Visible) + { + item.Visible = false; + _HiddenItems.Add(item); + } + } + } + this.NeedRecalcSize = true; + if (!supressRecalcLayout) + this.RecalcLayout(); + } + + /// + /// Returns reference to the parent ToolboxControl. + /// + /// + public ToolboxControl GetToolboxControl() + { + ItemPanel c = this.ContainerControl as ItemPanel; + if (c != null) + return c.Parent as ToolboxControl; + return null; + } + + private void RecalcLayout() + { + System.Windows.Forms.Control c = this.ContainerControl as System.Windows.Forms.Control; + if (c != null) + { + BarFunctions.InvokeRecalcLayout(c, true); + } + } + + protected override void OnSubItemsChanged(CollectionChangeAction action, BaseItem item) + { + if (action == CollectionChangeAction.Add) + { + if (!this.Expanded && item != null && item.Visible) + { + item.Visible = false; + _HiddenItems.Add(item); + } + else if (this.Expanded && item != null && !item.Visible) + item.Visible = true; + } + else if (action == CollectionChangeAction.Remove) + { + if (!this.Expanded && item != null && _HiddenItems.Contains(item)) + { + _HiddenItems.Remove(item); + } + } + else if (action == CollectionChangeAction.Refresh) + { + _HiddenItems.Clear(); + if (!this.Expanded) + ApplyExpandedProperty(); + } + base.OnSubItemsChanged(action, item); + } + + public override void InternalMouseDown(MouseEventArgs objArg) + { + if (TitleRectangle.Contains(objArg.Location)) + { + this.Expanded = !this.Expanded; + } + base.InternalMouseDown(objArg); + } + + protected override ElementStyle GetActiveTitleStyle() + { + if (this.Expanded && _TitleGroupExpandedStyle.Custom) + return _TitleGroupExpandedStyle; + return base.GetActiveTitleStyle(); + } + + private ElementStyle _TitleGroupExpandedStyle = null; + /// + /// Specifies the title background style when toolbox group is expanded. + /// + [Browsable(true), DevCoBrowsable(true), Category("Style"), Description("Specifies the title background style when toolbox group is expanded."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ElementStyle TitleGroupExpandedStyle + { + get { return _TitleGroupExpandedStyle; } + } + private void TitleGroupExpandedStyleChanged(object sender, EventArgs e) + { + this.OnAppearanceChanged(); + } + + protected override IContentLayout GetContentLayout() + { + SerialContentLayoutManager manager = (SerialContentLayoutManager)base.GetContentLayout(); + ToolboxControl tc = GetToolboxControl(); + if (_StretchItems && this.LayoutOrientation == eOrientation.Vertical && !this.MultiLine && tc != null && tc.Expanded) + { + manager.VerticalFitContainerWidth = true; + } + return manager; + } + + private bool _StretchItems = true; + /// + /// Indicates whether items in vertical layout orientation with MultiLine=false are stretched to fill group width. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether items in vertical layout orientation with MultiLine=false are stretched to fill group width. Default value is true.")] + public bool StretchItems + { + get { return _StretchItems; } + set { _StretchItems = value; } + } + + /// + /// Gets or sets a value indicating whether the item is expanded or not. For Popup items this would indicate whether the item is popped up or not. + /// + [DefaultValue(false), DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Visible)] + public override bool Expanded + { + get { return base.Expanded; } + + set { base.Expanded = value; } + } + + public override bool CanExpand + { + get { return true; } + } + + /// + /// Gets or sets whether items in horizontal layout are wrapped into the new line when they cannot fit allotted container size. Default value is false. + /// + [Browsable(true), DefaultValue(true), Category("Layout"), Description("Indicates whether items in horizontal layout are wrapped into the new line when they cannot fit allotted container size.")] + public override bool MultiLine + { + get { return base.MultiLine; } + set + { + base.MultiLine = value; + } + } + + /// + /// Gets or sets whether items contained by container are resized to fit the container bounds. When container is in horizontal + /// layout mode then all items will have the same height. When container is in vertical layout mode then all items + /// will have the same width. Default value is true. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(false), Category("Layout"), Description("Indicates whether items contained by container are resized to fit the container bounds. When container is in horizontal layout mode then all items will have the same height. When container is in vertical layout mode then all items will have the same width.")] + public override bool ResizeItemsToFit + { + get { return base.ResizeItemsToFit; } + set { base.ResizeItemsToFit = value; } + } + + /// + /// Gets or sets whether all items are equally sized based on the size of the largest item in the list. + /// + [DefaultValue(false), Category("Layout"), Description("Indicates whether all items are equally sized based on the size of the largest item in the list.")] + public override bool EqualItemSize + { + get { return base.EqualItemSize; } + set { base.EqualItemSize = value; } + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool Visible + { + get { return base.Visible; } + set { base.Visible = value; } + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/Toolbox/ToolboxItem.cs b/PROMS/DotNetBar Source Code/Controls/Toolbox/ToolboxItem.cs new file mode 100644 index 00000000..defa993b --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/Toolbox/ToolboxItem.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Controls +{ + [ToolboxItem(false), DesignTimeVisible(false), DefaultEvent("Click"), Designer("DevComponents.DotNetBar.Design.ToolboxItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ToolboxItem : ButtonItem + { + #region Constructor + public ToolboxItem() + { + //this.GlobalItem = false; + } + public ToolboxItem(string text) + { + this.Text = text; + this.ButtonStyle = eButtonStyle.ImageAndText; + } + public ToolboxItem(string text, Image image) + { + this.Text = text; + this.Image = image; + this.ButtonStyle = eButtonStyle.ImageAndText; + } + + public ToolboxItem(string text, string symbol, eSymbolSet symbolSet) + { + this.Text = text; + this.SymbolSet = symbolSet; + this.Symbol = symbol; + this.ButtonStyle = eButtonStyle.ImageAndText; + } + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + ToolboxItem objCopy = new ToolboxItem(this.Name); + this.CopyToItem(objCopy); + return objCopy; + } + + /// + /// Copies the ButtonItem specific properties to new instance of the item. + /// + /// New ButtonItem instance. + internal void InternalCopyToItem(ToolboxItem copy) + { + CopyToItem((BaseItem)copy); + } + + protected override void OnCheckedChanged() + { + base.OnCheckedChanged(); + ToolboxControl tc = GetToolboxControl(); + if (tc != null) + tc.ToolboxItemCheckedChanged(this); + } + + /// + /// Returns reference to parent ToolboxControl, if group is parented to it. + /// + /// reference to ToolboxControl or null + public ToolboxControl GetToolboxControl() + { + ItemPanel c = this.ContainerControl as ItemPanel; + if (c != null) + return c.Parent as ToolboxControl; + return null; + } + + #endregion + + #region Implementation + protected override bool ShouldDrawInsertMarker() + { + return DesignInsertMarker != eDesignInsertPosition.None && this.Visible && this.Displayed && !this.DesignMode; + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool Visible + { + get { return base.Visible; } + set { base.Visible = value; } + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/Controls/ToolboxControl.bmp b/PROMS/DotNetBar Source Code/Controls/ToolboxControl.bmp new file mode 100644 index 00000000..00a1b33a Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/ToolboxControl.bmp differ diff --git a/PROMS/DotNetBar Source Code/Controls/WarningBox.Designer.cs b/PROMS/DotNetBar Source Code/Controls/WarningBox.Designer.cs new file mode 100644 index 00000000..8f301ed8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/WarningBox.Designer.cs @@ -0,0 +1,154 @@ +#if FRAMEWORK20 +namespace DevComponents.DotNetBar.Controls +{ + partial class WarningBox + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) StyleManager.Unregister(this); + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.OptionsButton = new DevComponents.DotNetBar.PanelEx(); + this.PanelWarning = new DevComponents.DotNetBar.PanelEx(); + this.WarningLabel = new DevComponents.DotNetBar.LabelX(); + this.PanelClose = new System.Windows.Forms.Panel(); + this.CloseButton = new DevComponents.DotNetBar.ButtonX(); + this.PanelWarning.SuspendLayout(); + this.PanelClose.SuspendLayout(); + this.SuspendLayout(); + // + // OptionsButton + // + this.OptionsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.OptionsButton.CanvasColor = System.Drawing.SystemColors.Control; + this.OptionsButton.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.Office2007; + this.OptionsButton.Location = new System.Drawing.Point(311, 5); + this.OptionsButton.Name = "OptionsButton"; + this.OptionsButton.Size = new System.Drawing.Size(88, 23); + this.OptionsButton.Style.Alignment = System.Drawing.StringAlignment.Center; + this.OptionsButton.Style.BackColor1.Color = System.Drawing.Color.White; + this.OptionsButton.Style.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(229)))), ((int)(((byte)(244)))), ((int)(((byte)(254))))); + this.OptionsButton.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; + this.OptionsButton.Style.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.Custom; + this.OptionsButton.Style.BorderColor.Color = System.Drawing.Color.FromArgb(((int)(((byte)(162)))), ((int)(((byte)(188)))), ((int)(((byte)(213))))); + this.OptionsButton.Style.ForeColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemText; + this.OptionsButton.Style.GradientAngle = 90; + this.OptionsButton.StyleMouseDown.Alignment = System.Drawing.StringAlignment.Center; + this.OptionsButton.StyleMouseDown.BackColor1.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemPressedBackground; + this.OptionsButton.StyleMouseDown.BackColor2.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemPressedBackground2; + this.OptionsButton.StyleMouseDown.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemPressedBorder; + this.OptionsButton.StyleMouseDown.ForeColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemPressedText; + this.OptionsButton.StyleMouseOver.Alignment = System.Drawing.StringAlignment.Center; + this.OptionsButton.StyleMouseOver.BackColor1.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemHotBackground; + this.OptionsButton.StyleMouseOver.BackColor2.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemHotBackground2; + this.OptionsButton.StyleMouseOver.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemHotBorder; + this.OptionsButton.StyleMouseOver.ForeColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemHotText; + this.OptionsButton.TabIndex = 1; + this.OptionsButton.Text = "Options..."; + this.OptionsButton.Click += new System.EventHandler(this.OptionsButton_Click); + // + // PanelWarning + // + this.PanelWarning.CanvasColor = System.Drawing.SystemColors.Control; + this.PanelWarning.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.Office2007; + this.PanelWarning.Controls.Add(this.WarningLabel); + this.PanelWarning.Controls.Add(this.OptionsButton); + this.PanelWarning.Dock = System.Windows.Forms.DockStyle.Fill; + this.PanelWarning.Location = new System.Drawing.Point(0, 0); + this.PanelWarning.Name = "PanelWarning"; + this.PanelWarning.Padding = new System.Windows.Forms.Padding(4); + this.PanelWarning.Size = new System.Drawing.Size(405, 33); + this.PanelWarning.Style.BackColor1.Color = System.Drawing.Color.White; + this.PanelWarning.Style.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(229)))), ((int)(((byte)(244)))), ((int)(((byte)(254))))); + this.PanelWarning.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; + this.PanelWarning.Style.BorderColor.Color = System.Drawing.Color.FromArgb(((int)(((byte)(162)))), ((int)(((byte)(188)))), ((int)(((byte)(213))))); + this.PanelWarning.Style.ForeColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelText; + this.PanelWarning.Style.GradientAngle = 90; + this.PanelWarning.Style.MarginLeft = 5; + this.PanelWarning.TabIndex = 11; + // + // WarningLabel + // + this.WarningLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.WarningLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50))))); + this.WarningLabel.Location = new System.Drawing.Point(4, 5); + this.WarningLabel.Margin = new System.Windows.Forms.Padding(5); + this.WarningLabel.Name = "WarningLabel"; + this.WarningLabel.PaddingLeft = 2; + this.WarningLabel.Size = new System.Drawing.Size(304, 22); + this.WarningLabel.TabIndex = 0; + this.WarningLabel.MarkupLinkClick += new DevComponents.DotNetBar.MarkupLinkClickEventHandler(this.WarningLabel_MarkupLinkClick); + // + // PanelClose + // + this.PanelClose.BackColor = System.Drawing.Color.Transparent; + this.PanelClose.Controls.Add(this.CloseButton); + this.PanelClose.Dock = System.Windows.Forms.DockStyle.Right; + this.PanelClose.Location = new System.Drawing.Point(405, 0); + this.PanelClose.Name = "PanelClose"; + this.PanelClose.Size = new System.Drawing.Size(22, 33); + this.PanelClose.TabIndex = 12; + // + // CloseButton + // + this.CloseButton.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + this.CloseButton.ColorTable = DevComponents.DotNetBar.eButtonColor.Flat; + this.CloseButton.Dock = System.Windows.Forms.DockStyle.Top; + this.CloseButton.FocusCuesEnabled = false; + this.CloseButton.Location = new System.Drawing.Point(0, 0); + this.CloseButton.Name = "CloseButton"; + this.CloseButton.Size = new System.Drawing.Size(22, 17); + this.CloseButton.TabIndex = 1; + this.CloseButton.Tooltip = "Close"; + this.CloseButton.AntiAlias = true; + this.CloseButton.Click += new System.EventHandler(this.CloseButton_Click); + // + // WarningBox + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(196)))), ((int)(((byte)(219)))), ((int)(((byte)(249))))); + this.Controls.Add(this.PanelWarning); + this.Controls.Add(this.PanelClose); + this.Name = "WarningBox"; + this.Size = new System.Drawing.Size(427, 33); + this.PanelWarning.ResumeLayout(false); + this.PanelClose.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + internal PanelEx PanelWarning; + internal System.Windows.Forms.Panel PanelClose; + internal ButtonX CloseButton; + private PanelEx OptionsButton; + private LabelX WarningLabel; + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/WarningBox.cs b/PROMS/DotNetBar Source Code/Controls/WarningBox.cs new file mode 100644 index 00000000..2a8426e8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/WarningBox.cs @@ -0,0 +1,450 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Controls +{ + /// + /// Represents non-intrusive Warning Box control with Options and Close button. + /// + [ToolboxBitmap(typeof(WarningBox), "Controls.WarningBox.ico"), ToolboxItem(true), DefaultEvent("OptionsClick"), System.Runtime.InteropServices.ComVisible(false), Designer("DevComponents.DotNetBar.Design.WarningBoxDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public partial class WarningBox : UserControl + { + #region Events + /// + /// Occurs when Close button is clicked. + /// + [Description("Occurs when Close button is clicked.")] + public event EventHandler CloseClick; + /// + /// Occurs when Options button is clicked. + /// + [Description("Occurs when Options button is clicked.")] + public event EventHandler OptionsClick; + /// + /// Occurs when warning text markup link is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + public event MarkupLinkClickEventHandler MarkupLinkClick; + #endregion + + #region Constructors + public WarningBox() + { + InitializeComponent(); + CloseButton.Image = BarFunctions.LoadBitmap("SystemImages.CloseButton.png"); + StyleManager.Register(this); + } + #endregion + + #region Internal Implementation + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + UpdateColorScheme(); + } + + /// + /// Raises the CloseClick event. + /// + /// Event arguments. + protected virtual void OnCloseClick(EventArgs e) + { + EventHandler handler = CloseClick; + if (handler != null) handler(this, e); + } + + /// + /// Raises the OptionsClick event. + /// + /// Event arguments. + protected virtual void OnOptionsClick(EventArgs e) + { + EventHandler handler = OptionsClick; + if (handler != null) handler(this, e); + } + + private void OptionsButton_Click(object sender, EventArgs e) + { + OnOptionsClick(e); + } + + private void CloseButton_Click(object sender, EventArgs e) + { + OnCloseClick(e); + } + + /// + /// Gets or sets the text displayed on close button tooltip. + /// + [Browsable(true), Category("Warning"), Localizable(true), DefaultValue("Close")] + public string CloseButtonTooltip + { + get + { + return CloseButton.Tooltip; + } + set + { + CloseButton.Tooltip = value; + } + } + + /// + /// Gets or sets the text displayed on warning control label. Supports text-markup. + /// + [Browsable(true), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), Category("Warning"), Localizable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), DefaultValue("")] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + protected override void OnTextChanged(EventArgs e) + { + WarningLabel.Text = this.Text; + base.OnTextChanged(e); + } + + /// + /// Gets or sets whether text is wrapped on multiple lines if it cannot fit the space allocated to the control. + /// + [DefaultValue(false), Category("Appearance"), Description("Indicates whether text is wrapped on multiple lines if it cannot fit the space allocated to the control.")] + public bool WordWrap + { + get { return WarningLabel.WordWrap; } + set + { + WarningLabel.WordWrap = value; + } + } + + + /// + /// Gets or sets the image displayed next to the warning label text. Default value is null. + /// + [Browsable(true), Category("Warning"), DefaultValue(null), Localizable(true)] + public Image Image + { + get { return WarningLabel.Image; } + set + { + WarningLabel.Image = value; + } + } + /// + /// Gets or sets the text for the Options buttons. + /// + [Browsable(true), Category("Warning"), DefaultValue("Options..."), Localizable(true)] + public string OptionsText + { + get { return OptionsButton.Text; } + set + { + OptionsButton.Text = value; + } + } + + private bool _OptionsButtonVisible = true; + /// + /// Gets or sets whether Options button is visible. Default value is true. + /// + [Browsable(true), Category("Warning"), DefaultValue(true)] + public bool OptionsButtonVisible + { + get { return _OptionsButtonVisible; } + set + { + if (_OptionsButtonVisible != value) + { + _OptionsButtonVisible = value; + OptionsButton.Visible = _OptionsButtonVisible; + OnOptionsButtonVisibleChanged(); + } + } + } + + private void OnOptionsButtonVisibleChanged() + { + if (_OptionsButtonVisible) + { + WarningLabel.Width = PanelWarning.Width - (OptionsButton.Width + 3 + PanelWarning.Padding.Horizontal); + } + else + { + WarningLabel.Width = PanelWarning.Width - (PanelWarning.Padding.Right + WarningLabel.Left); + } + } + + private bool _CloseButtonVisible = true; + /// + /// Gets or sets whether Close button is visible. Default value is true. + /// + [Browsable(true), Category("Warning"), DefaultValue(true)] + public bool CloseButtonVisible + { + get { return _CloseButtonVisible; } + set + { + if (_CloseButtonVisible != value) + { + _CloseButtonVisible = value; + PanelClose.Visible = _CloseButtonVisible; + } + } + } + + /// + /// Updates control color scheme based on currently selected Office 2007 Color Table. Usually it is not necessary to + /// call this method manually. You need to call it to update the colors on control if you customize the Office2007ColorTable.WarningBox values. + /// + public void UpdateColorScheme() + { + Office2007Renderer renderer = (Office2007Renderer)GlobalManager.Renderer; + Office2007WarningBoxColorTable colorTable = null; + if (renderer == null) + colorTable = new Office2007WarningBoxColorTable(); // Default blue + else + colorTable = renderer.ColorTable.WarningBox; + + if (_ColorScheme == eWarningBoxColorScheme.Default) + { + this.BackColor = colorTable.BackColor; + + this.PanelWarning.Style.BorderColor.Color = colorTable.WarningBorderColor; + this.PanelWarning.Style.BackColor1.Color = colorTable.WarningBackColor1; + this.PanelWarning.Style.BackColor2.Color = colorTable.WarningBackColor2; + + this.OptionsButton.Style.BackColor1.ColorSchemePart = eColorSchemePart.Custom; + this.OptionsButton.Style.BackColor1.Color = colorTable.WarningBackColor1; + this.OptionsButton.Style.BackColor2.ColorSchemePart = eColorSchemePart.Custom; + this.OptionsButton.Style.BackColor2.Color = colorTable.WarningBackColor2; + this.OptionsButton.Style.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.Custom; + this.OptionsButton.Style.BorderColor.Color = colorTable.WarningBorderColor; + } + else if (_ColorScheme == eWarningBoxColorScheme.Green) + { + this.BackColor = colorTable.GreenBackColor; + + this.PanelWarning.Style.BorderColor.Color = colorTable.GreenWarningBorderColor; + this.PanelWarning.Style.BackColor1.Color = colorTable.GreenWarningBackColor1; + this.PanelWarning.Style.BackColor2.Color = colorTable.GreenWarningBackColor2; + + this.OptionsButton.Style.BackColor1.ColorSchemePart = eColorSchemePart.Custom; + this.OptionsButton.Style.BackColor1.Color = colorTable.GreenWarningBackColor1; + this.OptionsButton.Style.BackColor2.ColorSchemePart = eColorSchemePart.Custom; + this.OptionsButton.Style.BackColor2.Color = colorTable.GreenWarningBackColor2; + this.OptionsButton.Style.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.Custom; + this.OptionsButton.Style.BorderColor.Color = colorTable.GreenWarningBorderColor; + } + else if (_ColorScheme == eWarningBoxColorScheme.Yellow) + { + this.BackColor = colorTable.YellowBackColor; + + this.PanelWarning.Style.BorderColor.Color = colorTable.YellowWarningBorderColor; + this.PanelWarning.Style.BackColor1.Color = colorTable.YellowWarningBackColor1; + this.PanelWarning.Style.BackColor2.Color = colorTable.YellowWarningBackColor2; + + this.OptionsButton.Style.BackColor1.ColorSchemePart = eColorSchemePart.Custom; + this.OptionsButton.Style.BackColor1.Color = colorTable.YellowWarningBackColor1; + this.OptionsButton.Style.BackColor2.ColorSchemePart = eColorSchemePart.Custom; + this.OptionsButton.Style.BackColor2.Color = colorTable.YellowWarningBackColor2; + this.OptionsButton.Style.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.Custom; + this.OptionsButton.Style.BorderColor.Color = colorTable.YellowWarningBorderColor; + } + else if (_ColorScheme == eWarningBoxColorScheme.Red) + { + this.BackColor = colorTable.RedBackColor; + + this.PanelWarning.Style.BorderColor.Color = colorTable.RedWarningBorderColor; + this.PanelWarning.Style.BackColor1.Color = colorTable.RedWarningBackColor1; + this.PanelWarning.Style.BackColor2.Color = colorTable.RedWarningBackColor2; + + this.OptionsButton.Style.BackColor1.ColorSchemePart = eColorSchemePart.Custom; + this.OptionsButton.Style.BackColor1.Color = colorTable.RedWarningBackColor1; + this.OptionsButton.Style.BackColor2.ColorSchemePart = eColorSchemePart.Custom; + this.OptionsButton.Style.BackColor2.Color = colorTable.RedWarningBackColor2; + this.OptionsButton.Style.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.Custom; + this.OptionsButton.Style.BorderColor.Color = colorTable.RedWarningBorderColor; + } + + this.Invalidate(true); + } + + private void WarningLabel_MarkupLinkClick(object sender, MarkupLinkClickEventArgs e) + { + OnMarkupLinkClick(e); + } + + /// + /// Invokes the MarkupLinkClick event. + /// + /// Provides additional data about event. + protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e) + { + if (MarkupLinkClick != null) + MarkupLinkClick(this, e); + } + + private int _AutoCloseTimeout = 0; + /// + /// Gets or sets the timeout in seconds after which the control automatically closes itself. Default value is 0 which indicates that auto-close + /// is disabled. + /// + [DefaultValue(0), Category("Behavior"), Description("Indicates timeout in seconds after which the control automatically closes itself.")] + public int AutoCloseTimeout + { + get { return _AutoCloseTimeout; } + set + { + if (value < 0) value = 0; + _AutoCloseTimeout = value; + OnAutoCloseTimeoutChanged(); + } + } + + protected override void OnHandleDestroyed(EventArgs e) + { + DestroyAutoCloseTimer(); + base.OnHandleDestroyed(e); + } + + private void OnAutoCloseTimeoutChanged() + { + if (_AutoCloseTimeout == 0) + DestroyAutoCloseTimer(); + else if (this.Visible) + SetupAutoCloseTimer(); + } + + private Timer _AutoCloseTimer = null; + private void SetupAutoCloseTimer() + { + if (_AutoCloseTimeout == 0 || _AutoCloseTimer != null || this.DesignMode) return; + + _AutoCloseTimer = new Timer(); + _AutoCloseTimer.Interval = _AutoCloseTimeout * 1000; + _AutoCloseTimer.Tick += new EventHandler(AutoCloseTimerTick); + _AutoCloseTimer.Start(); + } + + void AutoCloseTimerTick(object sender, EventArgs e) + { + _AutoCloseTimer.Stop(); + DestroyAutoCloseTimer(); + AutoClose(); + } + + private void AutoClose() + { + OnCloseClick(EventArgs.Empty); + this.Visible = false; + } + + private void DestroyAutoCloseTimer() + { + Timer timer = _AutoCloseTimer; + _AutoCloseTimer = null; + if (timer == null) return; + timer.Stop(); + timer.Dispose(); + } + + protected override void OnVisibleChanged(EventArgs e) + { + if (this.Visible) + { + if (_AutoCloseTimeout > 0) SetupAutoCloseTimer(); + } + else + DestroyAutoCloseTimer(); + + base.OnVisibleChanged(e); + } + + protected override void OnHandleCreated(EventArgs e) + { + if (_ColorScheme == eWarningBoxColorScheme.Default) + UpdateColorScheme(); + base.OnHandleCreated(e); + } + + private eWarningBoxColorScheme _ColorScheme = eWarningBoxColorScheme.Default; + /// + /// Gets or sets the control's color scheme. + /// + [DefaultValue(eWarningBoxColorScheme.Default), Category("Appearance"), Description("Indicates control's color scheme.")] + public eWarningBoxColorScheme ColorScheme + { + get { return _ColorScheme; } + set + { + _ColorScheme = value; + UpdateColorScheme(); + this.Invalidate(true); + } + } + + private bool _AntiAlias = true; + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is true. + /// + [DefaultValue(true), Category("Appearance")] + public bool AntiAlias + { + get { return _AntiAlias; } + set + { + if (value != _AntiAlias) + { + bool oldValue = _AntiAlias; + _AntiAlias = value; + OnAntiAliasChanged(oldValue, value); + } + } + } + /// + /// Called when AntiAlias property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnAntiAliasChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("AntiAlias")); + PanelWarning.AntiAlias = newValue; + CloseButton.AntiAlias = newValue; + OptionsButton.AntiAlias = newValue; + WarningLabel.AntiAlias = newValue; + this.Invalidate(true); + } + #endregion + } + /// + /// Defines available WarningBox control color schemes. + /// + public enum eWarningBoxColorScheme + { + Default, + Green, + Yellow, + Red + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/Controls/WarningBox.ico b/PROMS/DotNetBar Source Code/Controls/WarningBox.ico new file mode 100644 index 00000000..bf1e413e Binary files /dev/null and b/PROMS/DotNetBar Source Code/Controls/WarningBox.ico differ diff --git a/PROMS/DotNetBar Source Code/Controls/WarningBox.resx b/PROMS/DotNetBar Source Code/Controls/WarningBox.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Controls/WarningBox.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/CrumbBar/CrumbBar.cs b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBar.cs new file mode 100644 index 00000000..51980249 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBar.cs @@ -0,0 +1,663 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Design; +using System.ComponentModel; +using System.Collections; +using DevComponents.DotNetBar.Rendering; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents compact tree bread-crumb control. + /// + [ToolboxBitmap(typeof(CrumbBar), "CrumbBar.CrumbBar.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.CrumbBarDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), System.Runtime.InteropServices.ComVisible(false), DefaultEvent("SelectedItemChanged")] + public class CrumbBar : ItemControl + { + #region Private Variables + private CrumbBarItemsCollection _Items = null; + private CrumbBarViewContainer _ViewContainer = null; + private Office2007Renderer _VistaRenderer = null; + #endregion + + #region Events + /// + /// Occurs before SelectedItem has changed and provides opportunity to cancel the change. Set Cancel property on event arguments to true to cancel the change. + /// + [Description("Occurs before SelectedItem has changed and provides opportunity to cancel the change.")] + public event CrumBarSelectionEventHandler SelectedItemChanging; + /// + /// Occurs after SelectedItem has changed. The change of the selected item at this point cannot be canceled. For that use SelectedItemChanging event. + /// + public event CrumBarSelectionEventHandler SelectedItemChanged; + #endregion + + #region Constructor + /// + /// Initializes a new instance of the CrumbBar class. + /// + public CrumbBar() + : base() + { + _Items = new CrumbBarItemsCollection(this); + + _ViewContainer = new CrumbBarViewContainer(); + _ViewContainer.GlobalItem = false; + _ViewContainer.ContainerControl = this; + _ViewContainer.Displayed = true; + _ViewContainer.Style = eDotNetBarStyle.StyleManagerControlled; + this.ColorScheme.Style = eDotNetBarStyle.StyleManagerControlled; + _ViewContainer.SetOwner(this); + InitializeVistaRenderer(); + this.SetBaseItemContainer(_ViewContainer); + } + #endregion + + #region Internal Implementation + private CrumbBarItem FindCrumbBarItem(IList subitems, string name) + { + foreach (CrumbBarItem item in subitems) + { + if (item.Name == name) + { + return item; + } + CrumbBarItem childItem = FindCrumbBarItem(item.SubItems, name); + if ((childItem != null)) return childItem; + } + return null; + } + /// + /// Finds CrumbBarItem with specified name. + /// + /// Name of item to look for + /// Item or null if no item was found. + public CrumbBarItem FindByName(string name) + { + return FindCrumbBarItem(this.Items, name); + } + + + private CrumbBarItem _SelectedItem; + /// + /// Gets or sets currently selected item. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates currently selected item")] + public CrumbBarItem SelectedItem + { + get { return _SelectedItem; } + set + { + SetSelectedItem(value, eEventSource.Code); + } + } + + internal void OnItemsCleared() + { + this.SelectedItem = null; + } + /// + /// Sets the currently selected item in the control. + /// + /// Reference to selected item. + /// Source of the event. + public void SetSelectedItem(CrumbBarItem selection, eEventSource source) + { + bool raiseChangedEvents = selection != _SelectedItem; + + if (raiseChangedEvents) + { + CrumbBarSelectionEventArgs eventArgs = new CrumbBarSelectionEventArgs(selection); + OnSelectedItemChanging(eventArgs); + if (eventArgs.Cancel) return; + selection = eventArgs.NewSelectedItem; + } + + if (_SelectedItem != null) + _SelectedItem.IsSelected = false; + + ArrayList newItems = new ArrayList(); + if (selection == null) + selection = GetFirstVisibleItem(); + _ViewContainer.Expanded = false; // closes any open popups + _ViewContainer.RestoreOverflowItems(); + + if (selection != null) + { + CrumbBarItem current = selection; + while (current != null) + { + newItems.Insert(0, GetItemView(current, true)); + current = current.Parent as CrumbBarItem; + } + + UpdateSelectedItemImage(selection); + } + else + UpdateSelectedItemImage(null); + + // Remove current view items + _ViewContainer.ClearViewItems(); + if (selection != null) + { + _ViewContainer.SubItems.AddRange((BaseItem[])newItems.ToArray(typeof(BaseItem))); + } + _ViewContainer.NeedRecalcSize = true; + + _SelectedItem = selection; + if (_SelectedItem != null) + _SelectedItem.IsSelected = true; + + this.RecalcLayout(); + + if (raiseChangedEvents) + { + CrumbBarSelectionEventArgs eventArgs = new CrumbBarSelectionEventArgs(selection); + OnSelectedItemChanged(eventArgs); + } + } + + internal void RefreshView() + { + UpdateSelectedItemImage(_SelectedItem); + } + + private void UpdateSelectedItemImage(CrumbBarItem selection) + { + if (selection == null) + { + _ViewContainer.ImageLabel.Visible = false; + return; + } + + CompositeImage image = selection.GetImage(); + if (image != null) + { + _ViewContainer.ImageLabel.Visible = true; + if (image.IsIcon) + _ViewContainer.ImageLabel.Icon = image.Icon; + else + _ViewContainer.ImageLabel.Image = image.Image; + } + else + { + _ViewContainer.ImageLabel.Visible = false; + } + } + + /// + /// Shows the selected item popup menu if it has menu items. + /// + /// true if popup was shown otherwise false + public bool ShowSelectedItemPopupMenu() + { + CrumbBarItem selectedItem = this.SelectedItem; + if (selectedItem == null) throw new NullReferenceException("SelectedItem is null"); + CrumbBarItemView view = GetItemView(selectedItem, false) as CrumbBarItemView; + if (view != null && !view.Expanded && view.AttachedItem != null && view.AttachedItem.SubItems.Count > 0) + { + view.Expanded = true; + return true; + } + return false; + } + + private object GetItemView(CrumbBarItem current, bool canCreateNewView) + { + for (int i = 2; i < _ViewContainer.SubItems.Count; i++) + { + CrumbBarItemView view = _ViewContainer.SubItems[i] as CrumbBarItemView; + if (view != null && view.AttachedItem == current) return view; + } + if(canCreateNewView) + return CrumbBarItemView.CreateViewForItem(current); + return null; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public CrumbBarItem GetFirstVisibleItem() + { + foreach (CrumbBarItem crumbBarItem in Items) + { + if (crumbBarItem.Visible) return crumbBarItem; + } + return null; + } + + /// + /// Gets whether an item is in selected path to the currently selected item as either one of the parents of selected item + /// or selected item itself. + /// + /// Item to test. + /// true if item is in selected path otherwise false. + public bool GetIsInSelectedPath(CrumbBarItem item) + { + for (int i = 2; i < _ViewContainer.SubItems.Count; i++) + { + CrumbBarItemView view = _ViewContainer.SubItems[i] as CrumbBarItemView; + if (view != null && view.AttachedItem == item) return true; + } + return false; + } + + /// + /// Gets collection of items assigned to the control. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Editor("DevComponents.DotNetBar.Design.CrumbBarItemCollectionEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] +#if FRAMEWORK20 + [Browsable(false)] +#else + [Browsable(true)] +#endif + public CrumbBarItemsCollection Items + { + get { return _Items; } + } + + private eCrumbBarStyle _Style = eCrumbBarStyle.Vista; + /// + /// Gets or sets the visual style of the control. Default value is Windows Vista style. + /// + [DefaultValue(eCrumbBarStyle.Vista), Category("Appearance"), Description("Indicates visual style of the control.")] + public eCrumbBarStyle Style + { + get { return _Style; } + set + { + if (value != _Style) + { + eCrumbBarStyle oldValue = _Style; + _Style = value; + OnStyleChanged(oldValue, value); + } + } + } + protected virtual void OnStyleChanged(eCrumbBarStyle oldValue, eCrumbBarStyle newValue) + { + this.Invalidate(); + } + + /// + /// Gets the color table used by the Vista style renderer. + /// + [Browsable(false)] + public Office2007ColorTable VistaColorTable + { + get { return _VistaRenderer.ColorTable; } + } + + /// + /// Returns the renderer control will be rendered with. + /// + /// The current renderer. + public override Rendering.BaseRenderer GetRenderer() + { + if (this.RenderMode == eRenderMode.Global && _Style == eCrumbBarStyle.Vista) + return _VistaRenderer; + return base.GetRenderer(); + } + + private void InitializeVistaRenderer() + { + _VistaRenderer = new Office2007Renderer(); + Office2007ColorTable colorTable = _VistaRenderer.ColorTable; + colorTable.CrumbBarItemView = GetCrumbBarVistaColorTable(); + // Popup menu style + colorTable.Menu.Background = new LinearGradientColorTable(ColorScheme.GetColor("FFF0F0F0")); + colorTable.Menu.Border = new LinearGradientColorTable(ColorScheme.GetColor("FF646464")); + colorTable.Menu.Side = new LinearGradientColorTable(ColorScheme.GetColor("FFF1F1F1")); + colorTable.Menu.SideBorder = new LinearGradientColorTable(ColorScheme.GetColor("FFE2E3E3")); + colorTable.Menu.SideBorderLight = new LinearGradientColorTable(ColorScheme.GetColor("FFFFFFFF")); + Office2007ButtonItemColorTable menu = colorTable.ButtonItemColors[0]; + menu.Default.Text = Color.Black; + menu.MouseOver.Background = new LinearGradientColorTable(ColorScheme.GetColor("34C5EBFF"), ColorScheme.GetColor("7081D8FF"), 90); + menu.MouseOver.OuterBorder = new LinearGradientColorTable(ColorScheme.GetColor("FF96DBFA")); + menu.MouseOver.InnerBorder = new LinearGradientColorTable(ColorScheme.GetColor("A0FFFFFF")); + menu.MouseOver.Text = Color.Black; + menu.Pressed = menu.MouseOver; + } + + private CrumbBarItemViewColorTable GetCrumbBarVistaColorTable() + { + return GetCrumbBarVistaColorTable(new ColorFactory()); + } + + internal static CrumbBarItemViewColorTable GetCrumbBarVistaColorTable(ColorFactory factory) + { + CrumbBarItemViewColorTable viewColorTable = new CrumbBarItemViewColorTable(); + CrumbBarItemViewStateColorTable crumbBarViewTable = new CrumbBarItemViewStateColorTable(); + viewColorTable.Default = crumbBarViewTable; + crumbBarViewTable.Foreground = Color.Black; + crumbBarViewTable = new CrumbBarItemViewStateColorTable(); + viewColorTable.MouseOver = crumbBarViewTable; + crumbBarViewTable.Foreground = Color.Black; + crumbBarViewTable.Background = new BackgroundColorBlendCollection(); + crumbBarViewTable.Background.AddRange(new BackgroundColorBlend[]{ + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("EAF6FD")), 0f), + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("D7EFFC")), .5f), + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("BDE6FD")), .5f), + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("A6D9F4")), 1f)}); + crumbBarViewTable.Border = factory.GetColor(ColorScheme.GetColor("3C7FB1")); + crumbBarViewTable.BorderLight = factory.GetColor(ColorScheme.GetColor("E0FFFFFF")); + crumbBarViewTable = new CrumbBarItemViewStateColorTable(); + viewColorTable.MouseOverInactive = crumbBarViewTable; + crumbBarViewTable.Foreground = Color.Black; + crumbBarViewTable.Background = new BackgroundColorBlendCollection(); + crumbBarViewTable.Background.AddRange(new BackgroundColorBlend[]{ + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("FFF2F2F2")), 0f), + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("FFEAEAEA")), .5f), + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("FFDCDCDC")), .5f), + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("FFCFCFCF")), 1f)}); + crumbBarViewTable.Border = factory.GetColor(ColorScheme.GetColor("FF8E8F8F")); + crumbBarViewTable.BorderLight = factory.GetColor(ColorScheme.GetColor("E0FFFFFF")); + crumbBarViewTable = new CrumbBarItemViewStateColorTable(); + viewColorTable.Pressed = crumbBarViewTable; + crumbBarViewTable.Foreground = Color.Black; + crumbBarViewTable.Background = new BackgroundColorBlendCollection(); + crumbBarViewTable.Background.AddRange(new BackgroundColorBlend[]{ + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("FFC2E4F6")), 0f), + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("FFC2E4F6")), .5f), + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("FFA9D9F2")), .5f), + new BackgroundColorBlend(factory.GetColor(ColorScheme.GetColor("FF90CBEB")), 1f)}); + crumbBarViewTable.Border = factory.GetColor(ColorScheme.GetColor("FF6E8D9F")); + crumbBarViewTable.BorderLight = factory.GetColor(ColorScheme.GetColor("906E8D9F")); + + return viewColorTable; + } + + /// + /// Raises the SelectedItemChanging event. + /// + /// Provides event arguments. + protected virtual void OnSelectedItemChanging(CrumbBarSelectionEventArgs e) + { + CrumBarSelectionEventHandler eh = SelectedItemChanging; + if (eh != null) eh(this, e); + } + + /// + /// Raises the SelectedItemChanged event. + /// + /// Provides event arguments. + protected virtual void OnSelectedItemChanged(CrumbBarSelectionEventArgs e) + { + CrumBarSelectionEventHandler eh = SelectedItemChanged; + if (eh != null) eh(this, e); + } + + protected override Size DefaultSize + { + get + { + return new Size(200, 22); + } + } + +#if FRAMEWORK20 + + private Size _PreferredSize = Size.Empty; + [Localizable(true), Browsable(false)] + public new System.Windows.Forms.Padding Padding + { + get { return base.Padding; } + set { base.Padding = value; } + } + + public override Size GetPreferredSize(Size proposedSize) + { + if (!_PreferredSize.IsEmpty) return _PreferredSize; + + if (!BarFunctions.IsHandleValid(this)) + return base.GetPreferredSize(proposedSize); + + if (this.Items.Count == 0 || !BarFunctions.IsHandleValid(this) || _ViewContainer.SubItems.Count == 0) + return new Size(base.GetPreferredSize(proposedSize).Width, 22); + + int height = ElementStyleLayout.VerticalStyleWhiteSpace(this.GetBackgroundStyle()); + height += _ViewContainer.CalculatedHeight > 0 ? _ViewContainer.CalculatedHeight : 20; + + _PreferredSize = new Size(proposedSize.Width, height); + return _PreferredSize; + } + + /// + /// Gets or sets a value indicating whether the control is automatically resized to display its entire contents. You can set MaximumSize.Width property to set the maximum width used by the control. + /// + [Browsable(true), DefaultValue(false), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override bool AutoSize + { + get + { + return base.AutoSize; + } + set + { + if (this.AutoSize != value) + { + base.AutoSize = value; + InvalidateAutoSize(); + AdjustSize(); + } + } + } + + private void InvalidateAutoSize() + { + _PreferredSize = Size.Empty; + } + + protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) + { + if (this.AutoSize) + { + Size preferredSize = base.PreferredSize; + if (preferredSize.Width > 0) + width = preferredSize.Width; + if (preferredSize.Height > 0) + height = preferredSize.Height; + } + base.SetBoundsCore(x, y, width, height, specified); + } + + private void AdjustSize() + { + if (this.AutoSize) + { + System.Drawing.Size prefSize = base.PreferredSize; + if (prefSize.Width > 0 && prefSize.Height > 0) + this.Size = base.PreferredSize; + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Image BackgroundImage + { + get { return base.BackgroundImage; } + set { base.BackgroundImage = value; } + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); +#if FRAMEWORK20 + if (this.AutoSize) + this.AdjustSize(); +#endif + } +#endif + private string _PathSeparator = System.IO.Path.PathSeparator.ToString(); + /// + /// Gets or sets the delimiter string that the tree node path uses. + /// + [DefaultValue("\\"), Browsable(false), Description("Indicates the delimiter string that the tree node path uses.")] + public string PathSeparator + { + get { return _PathSeparator; } + set { _PathSeparator = value; } + } + /// + /// Returns full path to the given node. + /// + /// Node to return path to. + /// Full path to the node. + internal static string GetFullPath(CrumbBarItem item, string pathSeparator) + { + if (item == null) + throw new ArgumentNullException("node"); + + StringBuilder sb = new StringBuilder(item.Text); + item = item.Parent as CrumbBarItem; + while (item != null) + { + sb.Insert(0, item.Text + pathSeparator); + item = item.Parent as CrumbBarItem; + } + + return sb.ToString(); + } + #endregion + + #region Property Hiding + [Browsable(false)] + public override eBarImageSize ImageSize + { + get + { + return base.ImageSize; + } + set + { + base.ImageSize = value; + } + } + [Browsable(false)] + public override System.Windows.Forms.ImageList ImagesLarge + { + get + { + return base.ImagesLarge; + } + set + { + base.ImagesLarge = value; + } + } + [Browsable(false)] + public override System.Windows.Forms.ImageList ImagesMedium + { + get + { + return base.ImagesMedium; + } + set + { + base.ImagesMedium = value; + } + } + [Browsable(false)] + public override Font KeyTipsFont + { + get + { + return base.KeyTipsFont; + } + set + { + base.KeyTipsFont = value; + } + } + [Browsable(false)] + public override bool ShowShortcutKeysInToolTips + { + get + { + return base.ShowShortcutKeysInToolTips; + } + set + { + base.ShowShortcutKeysInToolTips = value; + } + } + [Browsable(false)] + public override bool ThemeAware + { + get + { + return base.ThemeAware; + } + set + { + base.ThemeAware = value; + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + #endregion + + #region Licensing +#if !TRIAL + private string m_LicenseKey = ""; + [Browsable(false), DefaultValue("")] + public string LicenseKey + { + get { return m_LicenseKey; } + set + { + if (NativeFunctions.ValidateLicenseKey(value)) + return; + m_LicenseKey = (!NativeFunctions.CheckLicenseKey(value) ? "9dsjkhds7" : value); + } + } +#endif + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); +#if !TRIAL + if (NativeFunctions.keyValidated2 != 266) + TextDrawing.DrawString(e.Graphics, "Invalid License", this.Font, Color.FromArgb(180, Color.Red), this.ClientRectangle, eTextFormat.Bottom | eTextFormat.HorizontalCenter); +#else + if (NativeFunctions.ColorExpAlt() || !NativeFunctions.CheckedThrough) + { + e.Graphics.Clear(SystemColors.Control); + return; + } +#endif + } + #endregion + } + + #region Event support + /// + /// Defines delegate for CrumbBar selection events. + /// + public delegate void CrumBarSelectionEventHandler(object sender, CrumbBarSelectionEventArgs e); + /// + /// Provides data for CrumbBar selection events. + /// + public class CrumbBarSelectionEventArgs : CancelEventArgs + { + /// + /// Gets or sets newly selected item. + /// + public CrumbBarItem NewSelectedItem = null; + /// + /// Initializes a new instance of the CrumbBarSelectionEventArgs class. + /// + /// + public CrumbBarSelectionEventArgs(CrumbBarItem newSelectedItem) + { + NewSelectedItem = newSelectedItem; + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/CrumbBar/CrumbBar.ico b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBar.ico new file mode 100644 index 00000000..c4ff831d Binary files /dev/null and b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBar.ico differ diff --git a/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarIcon.psd b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarIcon.psd new file mode 100644 index 00000000..8b81aca0 Binary files /dev/null and b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarIcon.psd differ diff --git a/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItem.cs b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItem.cs new file mode 100644 index 00000000..16dfae5b --- /dev/null +++ b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItem.cs @@ -0,0 +1,713 @@ +using System; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents an item for CrumbBar control. + /// + [Designer("DevComponents.DotNetBar.Design.CrumbBarItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"), ToolboxItem(false), DesignTimeVisible(false)] + public class CrumbBarItem : ButtonItem + { + #region Internal Implementation + protected override void OnClick() + { + Select(eEventSource.Mouse); + base.OnClick(); + } + + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool ShowSubItems + { + get + { + return false; + } + set + { + base.ShowSubItems = value; + } + } + + private bool _IsSelected = false; + /// + /// Gets whether item is selected item in CrumbBar control. + /// + [Browsable(false)] + public bool IsSelected + { + get { return _IsSelected; } +#if FRAMEWORK20 + internal set +#else + set +#endif + { + _IsSelected = value; + if (_IsSelected) + this.FontBold = true; + else + this.FontBold = false; + } + } + + + private void Select(eEventSource source) + { + CrumbBar bar = this.GetOwner() as CrumbBar; + if (bar != null) bar.SetSelectedItem(this, source); + } + + /// + /// Returns the collection of sub items. + /// + [Browsable(false), Editor("DevComponents.DotNetBar.Design.CrumbBarItemCollectionEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)] + public override SubItemsCollection SubItems + { + get + { + return base.SubItems; + } + } + + public override void OnImageChanged() + { + base.OnImageChanged(); + CrumbBar bar = this.GetOwner() as CrumbBar; + if (bar != null && bar.SelectedItem == this) + { + bar.RefreshView(); + } + } + + protected override void OnParentChanged() + { + CrumbBar bar = this.GetOwner() as CrumbBar; + if (bar != null) + { + if (bar.SelectedItem == this || bar.GetIsInSelectedPath(this)) + bar.SetSelectedItem(bar.SelectedItem, eEventSource.Code); + } + base.OnParentChanged(); + } + + protected internal override void OnAfterItemRemoved(BaseItem objItem, int itemIndex) + { + if (objItem is CrumbBarItem && ((CrumbBarItem)objItem).IsSelected) + { + CrumbBar bar = this.GetOwner() as CrumbBar; + if (bar != null) + bar.SetSelectedItem(this, eEventSource.Code); + } + base.OnAfterItemRemoved(objItem, itemIndex); + } + + /// + /// Gets the path from the root tree node to the current tree node. The path consists of the labels of all the tree nodes that must be navigated to get to this tree node, starting at the root tree node. The node labels are separated by the delimiter character specified in the PathSeparator property of the Tree control that contains this node. + /// + [Browsable(false)] + public string FullPath + { + get + { + CrumbBar bar = this.GetOwner() as CrumbBar; + if (bar == null) + return ""; + return CrumbBar.GetFullPath(this, bar.PathSeparator); + } + } + #endregion + + #region Property Hiding + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string AlternateShortCutText + { + get + { + return base.AlternateShortCutText; + } + set + { + base.AlternateShortCutText = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool AutoCheckOnClick + { + get + { + return base.AutoCheckOnClick; + } + set + { + base.AutoCheckOnClick = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool AutoCollapseOnClick + { + get + { + return base.AutoCollapseOnClick; + } + set + { + base.AutoCollapseOnClick = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool AutoExpandOnClick + { + get + { + return base.AutoExpandOnClick; + } + set + { + base.AutoExpandOnClick = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool BeginGroup + { + get + { + return base.BeginGroup; + } + set + { + base.BeginGroup = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override eButtonStyle ButtonStyle + { + get + { + return base.ButtonStyle; + } + set + { + base.ButtonStyle = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool CanCustomize + { + get + { + return base.CanCustomize; + } + set + { + base.CanCustomize = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string Category + { + get + { + return base.Category; + } + set + { + base.Category = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool Checked + { + get + { + return base.Checked; + } + set + { + base.Checked = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool ClickAutoRepeat + { + get + { + return base.ClickAutoRepeat; + } + set + { + base.ClickAutoRepeat = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override int ClickRepeatInterval + { + get + { + return base.ClickRepeatInterval; + } + set + { + base.ClickRepeatInterval = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override eButtonColor ColorTable + { + get + { + return base.ColorTable; + } + set + { + base.ColorTable = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string CustomColorName + { + get + { + return base.CustomColorName; + } + set + { + base.CustomColorName = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string Description + { + get + { + return base.Description; + } + set + { + base.Description = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool FontBold + { + get + { + return base.FontBold; + } + set + { + base.FontBold = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool FontItalic + { + get + { + return base.FontItalic; + } + set + { + base.FontItalic = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool FontUnderline + { + get + { + return base.FontUnderline; + } + set + { + base.FontUnderline = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool GlobalItem + { + get + { + return base.GlobalItem; + } + set + { + base.GlobalItem = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string GlobalName + { + get + { + return base.GlobalName; + } + set + { + base.GlobalName = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool HotFontBold + { + get + { + return base.HotFontBold; + } + set + { + base.HotFontBold = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool HotFontUnderline + { + get + { + return base.HotFontUnderline; + } + set + { + base.HotFontUnderline = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override eHotTrackingStyle HotTrackingStyle + { + get + { + return base.HotTrackingStyle; + } + set + { + base.HotTrackingStyle = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override System.Drawing.Image HoverImage + { + get + { + return base.HoverImage; + } + set + { + base.HoverImage = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override int HoverImageIndex + { + get + { + return base.HoverImageIndex; + } + set + { + base.HoverImageIndex = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override System.Drawing.Icon Icon + { + get + { + return base.Icon; + } + set + { + base.Icon = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override eButtonImageListSelection ImageListSizeSelection + { + get + { + return base.ImageListSizeSelection; + } + set + { + base.ImageListSizeSelection = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override int ImagePaddingHorizontal + { + get + { + return base.ImagePaddingHorizontal; + } + set + { + base.ImagePaddingHorizontal = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override int ImagePaddingVertical + { + get + { + return base.ImagePaddingVertical; + } + set + { + base.ImagePaddingVertical = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override eImagePosition ImagePosition + { + get + { + return base.ImagePosition; + } + set + { + base.ImagePosition = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override System.Drawing.Image ImageSmall + { + get + { + return base.ImageSmall; + } + set + { + base.ImageSmall = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override eItemAlignment ItemAlignment + { + get + { + return base.ItemAlignment; + } + set + { + base.ItemAlignment = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string KeyTips + { + get + { + return base.KeyTips; + } + set + { + base.KeyTips = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override eMenuVisibility MenuVisibility + { + get + { + return base.MenuVisibility; + } + set + { + base.MenuVisibility = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override string OptionGroup + { + get + { + return base.OptionGroup; + } + set + { + base.OptionGroup = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override ePersonalizedMenus PersonalizedMenus + { + get + { + return base.PersonalizedMenus; + } + set + { + base.PersonalizedMenus = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override ePopupSide PopupSide + { + get + { + return base.PopupSide; + } + set + { + base.PopupSide = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override ePopupType PopupType + { + get + { + return base.PopupType; + } + set + { + base.PopupType = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override int PopupWidth + { + get + { + return base.PopupWidth; + } + set + { + base.PopupWidth = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override System.Drawing.Image PressedImage + { + get + { + return base.PressedImage; + } + set + { + base.PressedImage = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override int PressedImageIndex + { + get + { + return base.PressedImageIndex; + } + set + { + base.PressedImageIndex = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool RibbonWordWrap + { + get + { + return base.RibbonWordWrap; + } + set + { + base.RibbonWordWrap = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override ShapeDescriptor Shape + { + get + { + return base.Shape; + } + set + { + base.Shape = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool SplitButton + { + get + { + return base.SplitButton; + } + set + { + base.SplitButton = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool Stretch + { + get + { + return base.Stretch; + } + set + { + base.Stretch = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override int SubItemsExpandWidth + { + get + { + return base.SubItemsExpandWidth; + } + set + { + base.SubItemsExpandWidth = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool ThemeAware + { + get + { + return base.ThemeAware; + } + set + { + base.ThemeAware = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override System.Drawing.Size FixedSize + { + get + { + return base.FixedSize; + } + set + { + base.FixedSize = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override int PulseSpeed + { + get + { + return base.PulseSpeed; + } + set + { + base.PulseSpeed = value; + } + } + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool StopPulseOnMouseOver + { + get + { + return base.StopPulseOnMouseOver; + } + set + { + base.StopPulseOnMouseOver = value; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItemView.cs b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItemView.cs new file mode 100644 index 00000000..6fbf2df7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItemView.cs @@ -0,0 +1,235 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.Drawing; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents a view of CrumbBarItem displayed inside of CrumbBar control. + /// + public class CrumbBarItemView : ButtonItem + { + #region Internal Implementation + /// + /// Initializes a new instance of the CrumbBarItemView class. + /// + public CrumbBarItemView():base() + { + this.SubItemsExpandWidth = 15; + this.HorizontalPadding = 2; + } + + private CrumbBarItem _AttachedItem; + /// + /// Gets the item attached to the view. + /// + public CrumbBarItem AttachedItem + { + get { return _AttachedItem; } + internal set + { + if (_AttachedItem != null) + { + _AttachedItem.TextChanged -= new EventHandler(AttachedItemTextChanged); + _AttachedItem.SubItemsChanged -= new System.ComponentModel.CollectionChangeEventHandler(AttachedItemSubItemsChanged); + _AttachedItem.PopupClose -= new EventHandler(AttachedItemPopupClose); + } + _AttachedItem = value; + + if (_AttachedItem != null) + { + this.Text = _AttachedItem.Text; + this.Cursor = _AttachedItem.Cursor; + this.ForeColor = _AttachedItem.ForeColor; + this.HotForeColor = _AttachedItem.HotForeColor; + this.Tooltip = _AttachedItem.Tooltip; + + _AttachedItem.TextChanged += new EventHandler(AttachedItemTextChanged); + _AttachedItem.SubItemsChanged += new System.ComponentModel.CollectionChangeEventHandler(AttachedItemSubItemsChanged); + _AttachedItem.PopupClose += new EventHandler(AttachedItemPopupClose); + if (AnyVisibleItems) + this.PopupType = ePopupType.Container; + else + this.PopupType = ePopupType.Menu; + } + else + this.PopupType = ePopupType.Menu; + } + } + + private DateTime _PopupCloseTime = DateTime.MinValue; + private void AttachedItemPopupClose(object sender, EventArgs e) + { + _Expanded = false; + CrumbBarViewContainer c = this.Parent as CrumbBarViewContainer; + if (c != null) + c.OnSubItemExpandChange(this); + + _PopupCloseTime = DateTime.Now; + this.Refresh(); + } + + public override void InternalMouseDown(MouseEventArgs objArg) + { + if (_PopupCloseTime != DateTime.MinValue && DateTime.Now.Subtract(_PopupCloseTime).TotalMilliseconds < 200) + { + _PopupCloseTime = DateTime.MinValue; + return; + } + base.InternalMouseDown(objArg); + } + + public override void InternalMouseEnter() + { + CrumbBarViewContainer parent = this.Parent as CrumbBarViewContainer; + if (parent != null && parent.Expanded && AnyVisibleItems) + { + parent.Expanded = false; + this.Expanded = true; + } + base.InternalMouseEnter(); + } + + private bool AnyVisibleItems + { + get + { + if (_AttachedItem != null) + { + foreach (BaseItem item in _AttachedItem.SubItems) + { + if (item.Visible) return true; + } + } + return false; + } + } + + private void AttachedItemSubItemsChanged(object sender, System.ComponentModel.CollectionChangeEventArgs e) + { + UpdatePopupType(); + } + + private void UpdatePopupType() + { + if (AnyVisibleItems && !(this.Parent is CrumbBarOverflowButton)) + this.PopupType = ePopupType.Container; + else + this.PopupType = ePopupType.Menu; + } + + protected override void OnParentChanged() + { + UpdatePopupType(); + base.OnParentChanged(); + } + + void AttachedItemTextChanged(object sender, EventArgs e) + { + this.Text = _AttachedItem.Text; + } + + protected override void Dispose(bool disposing) + { + this.AttachedItem = null; + base.Dispose(disposing); + } + + internal static object CreateViewForItem(CrumbBarItem item) + { + CrumbBarItemView view = new CrumbBarItemView(); + view.AttachedItem = item; + return view; + } + + private bool _Expanded = false; + /// + /// Gets or sets a value indicating whether the item is expanded or not. For Popup items this would indicate whether the item is popped up or not. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DefaultValue(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public override bool Expanded + { + get + { + return _Expanded; + } + set + { + if (_Expanded != value) + { + _Expanded = value; + InternalExpandedChanged(); + } + } + } + + private void InternalExpandedChanged() + { + if (!_Expanded) + { + _AttachedItem.Expanded = false; + } + else + { + Control parent=this.ContainerControl as Control; + if(parent==null) return; + Point p = new Point(this.SubItemsRect.X - 10, this.SubItemsRect.Bottom - 1); + p.Offset(this.DisplayRectangle.Location.X, this.DisplayRectangle.Location.Y); + p = parent.PointToScreen(p); + _AttachedItem.PopupMenu(p); + } + + CrumbBarViewContainer c = this.Parent as CrumbBarViewContainer; + if (c != null) + c.OnSubItemExpandChange(this); + } + + protected override void OnClick() + { + CrumbBar bar = this.ContainerControl as CrumbBar; + if (bar == null) bar = this.GetOwner() as CrumbBar; + + base.OnClick(); + + if (bar != null) + { + bar.SelectedItem = _AttachedItem; + } + } + + protected override void RenderButton(ItemPaintArgs p) + { + if (!p.IsOnMenu) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + p.ButtonItemRendererEventArgs.Graphics = p.Graphics; + p.ButtonItemRendererEventArgs.ButtonItem = this; + p.ButtonItemRendererEventArgs.ItemPaintArgs = p; + renderer.DrawCrumbBarItemView(p.ButtonItemRendererEventArgs); + return; + } + } + base.RenderButton(p); + } + + /// + /// Returns copy of ExplorerBarContainerItem item + /// + public override BaseItem Copy() + { + CrumbBarItemView objCopy = new CrumbBarItemView(); + this.CopyToItem(objCopy); + return objCopy; + } + protected override void CopyToItem(BaseItem copy) + { + CrumbBarItemView objCopy = copy as CrumbBarItemView; + base.CopyToItem(objCopy); + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItemViewPainter.cs b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItemViewPainter.cs new file mode 100644 index 00000000..88bd49a6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItemViewPainter.cs @@ -0,0 +1,253 @@ +using System; +using System.Text; +using DevComponents.DotNetBar.Rendering; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar +{ + internal class CrumbBarItemViewPainter: IOffice2007Painter + { + #region IOffice2007Painter + private Office2007ColorTable _ColorTable = null; + + /// + /// Gets or sets color table used by renderer. + /// + public Office2007ColorTable ColorTable + { + get { return _ColorTable; } + set { _ColorTable = value; } + } + #endregion + + #region Internal Implementation + public void Paint(ButtonItem item, ItemPaintArgs pa) + { + Paint(item, pa, _ColorTable.CrumbBarItemView); + } + + public void Paint(ButtonItem item, ItemPaintArgs pa, CrumbBarItemViewColorTable itemColorTable) + { + Graphics g =pa.Graphics; + + CrumbBarItemViewStateColorTable stateTable = itemColorTable.Default; + CrumbBarItemViewStateColorTable stateTable2 = null; + bool isPressed = false; + if (item.IsMouseDown || item.Expanded) + { + stateTable = itemColorTable.Pressed; + isPressed = true; + } + else if (item.IsMouseOverExpand) + { + stateTable = itemColorTable.MouseOverInactive; + stateTable2 = itemColorTable.MouseOver; + } + else if (item.IsMouseOver) + stateTable = itemColorTable.MouseOver; + + Rectangle rect = item.DisplayRectangle; + rect.Width--; + rect.Height--; + Rectangle expandRect = item.GetTotalSubItemsRect(); + if (!expandRect.IsEmpty) + { + expandRect.Offset(rect.Location); + expandRect.Width--; + expandRect.Height--; + } + + PaintBackground(item, g, stateTable, stateTable2, isPressed, ref rect, ref expandRect); + + Color textColor = stateTable.Foreground; + if (!item.ForeColor.IsEmpty) + textColor = item.ForeColor; + if (!textColor.IsEmpty) + { + // Render text + Font font = item.GetFont(pa, false); + bool rightToLeft = pa.RightToLeft; + rect = GetTextRectangle(item); + eTextFormat stringFormat = eTextFormat.Left | eTextFormat.VerticalCenter | eTextFormat.HidePrefix; + if (item.TextMarkupBody == null) + { + TextDrawing.DrawString(g, ButtonItemPainter.GetDrawText(item.Text), font, textColor, rect, stringFormat); + } + else + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, textColor, rightToLeft); + d.HotKeyPrefixVisible = !((stringFormat & eTextFormat.HidePrefix) == eTextFormat.HidePrefix); + d.ContextObject = item; + Rectangle mr = new Rectangle(rect.X, rect.Y + (rect.Height - item.TextMarkupBody.Bounds.Height) / 2 + 1, item.TextMarkupBody.Bounds.Width, item.TextMarkupBody.Bounds.Height); + item.TextMarkupBody.Bounds = mr; + item.TextMarkupBody.Render(d); + } + + if ((item.SubItems.Count > 0 || item.PopupType == ePopupType.Container) && item.ShowSubItems) + { + // Render expand sign + GraphicsPath path = GetExpandPath(item, expandRect); + if (path != null) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + using(Brush brush=new SolidBrush(stateTable.Foreground)) + g.FillPath(brush, path); + g.SmoothingMode = sm; + } + } + } + } + + private static void PaintBackground(ButtonItem item, Graphics g, CrumbBarItemViewStateColorTable stateTable, CrumbBarItemViewStateColorTable stateTable2, bool isPressed, ref Rectangle rect, ref Rectangle expandRect) + { + if (stateTable.Background != null && stateTable.Background.Count > 0) + { + using (Brush brush = DisplayHelp.CreateBrush(rect, stateTable.Background, 90, eGradientType.Linear)) + g.FillRectangle(brush, rect); + if (item.IsMouseOverExpand && stateTable2 != null && stateTable2.Background != null && stateTable2.Background.Count > 0) + { + using (Brush brush = DisplayHelp.CreateBrush(rect, stateTable2.Background, 90, eGradientType.Linear)) + g.FillRectangle(brush, expandRect); + } + } + + if (!stateTable.Border.IsEmpty) + { + using (Pen pen = new Pen(stateTable.Border, 1)) + { + g.DrawLine(pen, rect.X, rect.Y, rect.X, rect.Bottom); + Pen pen2 = stateTable2 != null ? new Pen(stateTable2.Border, 1) : pen; + if (!expandRect.IsEmpty) + { + g.DrawLine(pen2, expandRect.X, expandRect.Y, expandRect.X, expandRect.Bottom); + } + if (isPressed) + g.DrawLine(pen, rect.X, rect.Y, rect.Right, rect.Y); + + g.DrawLine(pen2, rect.Right, rect.Y, rect.Right, rect.Bottom); + if (stateTable2 != null) pen2.Dispose(); + } + } + + if (!stateTable.BorderLight.IsEmpty) + { + Rectangle rectLight = rect; + if (!expandRect.IsEmpty) + rectLight.Width -= expandRect.Width; + rectLight.Inflate(-1, 0); + using (Pen pen = new Pen(stateTable.BorderLight, 1)) + { + if (isPressed) + { + g.DrawLine(pen, rectLight.X, rectLight.Y, rectLight.Right, rectLight.Y); + g.DrawLine(pen, rectLight.X, rectLight.Y, rectLight.X, rectLight.Bottom); + if (!expandRect.IsEmpty) + { + rectLight = expandRect; + rectLight.Inflate(-1, 0); + g.DrawLine(pen, rectLight.X, rectLight.Y, rectLight.Right, rectLight.Y); + g.DrawLine(pen, rectLight.X, rectLight.Y, rectLight.X, rectLight.Bottom); + } + } + else + { + g.DrawRectangle(pen, rectLight); + if (!expandRect.IsEmpty) + { + rectLight = expandRect; + rectLight.Inflate(-1, 0); + g.DrawRectangle(pen, rectLight); + } + } + } + } + } + + private GraphicsPath GetExpandPath(ButtonItem item, Rectangle expandRect) + { + GraphicsPath path = new GraphicsPath(); + if (item.Expanded) + { + Point p = new Point(expandRect.X + (expandRect.Width - Dpi.Width6) / 2, expandRect.Y + (expandRect.Height - 1) / 2); + if (item.IsMouseDown) p.Offset(1, 1); + path.AddLine(p.X, p.Y, p.X + Dpi.Width8, p.Y); + path.AddLine(p.X + Dpi.Width8, p.Y, p.X + Dpi.Width4, p.Y + Dpi.Height4); + path.CloseAllFigures(); + } + else + { + Point p = new Point(expandRect.X + (expandRect.Width - Dpi.Width2) / 2, expandRect.Y + (expandRect.Height - Dpi.Height7) / 2); + if (item.IsMouseDown) p.Offset(1, 1); + path.AddLine(p.X, p.Y, p.X, p.Y + Dpi.Height8); + path.AddLine(p.X, p.Y + Dpi.Height8, p.X + Dpi.Width4, p.Y + Dpi.Height4); + path.CloseAllFigures(); + } + return path; + } + + protected virtual Rectangle GetTextRectangle(ButtonItem button) + { + Rectangle itemRect = button.DisplayRectangle; + Rectangle textRect = button.TextDrawRect; + //Rectangle imageRect = button.ImageDrawRect; + + textRect.Offset(itemRect.Left, itemRect.Top); + + if (textRect.Right > itemRect.Right) + textRect.Width = itemRect.Right - textRect.Left; + textRect.X += 2; + textRect.Y--; + if (button.IsMouseDown) textRect.Offset(1, 1); + return textRect; + } + + public void PaintOverflowButton(ButtonItem item, ItemPaintArgs pa) + { + PaintOverflowButton(item, pa, _ColorTable.CrumbBarItemView); + } + + public void PaintOverflowButton(ButtonItem item, ItemPaintArgs pa, CrumbBarItemViewColorTable itemColorTable) + { + Graphics g =pa.Graphics; + + CrumbBarItemViewStateColorTable stateTable = itemColorTable.Default; + CrumbBarItemViewStateColorTable stateTable2 = null; + bool isPressed = false; + if (item.IsMouseDown || item.Expanded) + { + stateTable = itemColorTable.Pressed; + isPressed = true; + } + else if (item.IsMouseOver) + stateTable = itemColorTable.MouseOver; + + Rectangle rect = item.DisplayRectangle; + rect.Width--; + rect.Height--; + Rectangle expandRect = Rectangle.Empty; + + PaintBackground(item, g, stateTable, stateTable2, isPressed, ref rect, ref expandRect); + + Color textColor = stateTable.Foreground; + if (!textColor.IsEmpty) + { + SmoothingMode sm = g.SmoothingMode; + Point p = new Point(rect.X + (rect.Width - 7) / 2, rect.Y + (rect.Height - 5) / 2); + if (isPressed) + p.Offset(1, 1); + using (Pen pen = new Pen(textColor, 1)) + { + for (int i = 0; i < 2; i++) + { + g.DrawLine(pen, p.X + 3, p.Y, p.X, p.Y + 2); + g.DrawLine(pen, p.X, p.Y + 2, p.X + 3, p.Y + 4); + p.X += 4; + } + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItemsCollection.cs b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItemsCollection.cs new file mode 100644 index 00000000..bba9eb36 --- /dev/null +++ b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarItemsCollection.cs @@ -0,0 +1,203 @@ +using System; +using System.Text; +using System.Collections; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents collection of CrumbBarItem buttons. + /// + public class CrumbBarItemsCollection : CollectionBase + { + #region Private Variables + private CrumbBar _Parent = null; + #endregion + + #region Internal Implementation + /// + /// Initializes a new instance of the CrumbBarItemsCollection class. + /// + /// + public CrumbBarItemsCollection(CrumbBar parent) + { + _Parent = parent; + } + + /// + /// Gets or sets the node this collection is associated with. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CrumbBar Parent + { + get { return _Parent; } + } + /// + /// Sets the node collection belongs to. + /// + /// CrumbBarItem that is parent of this collection. + internal void SetParent(CrumbBar parent) + { + _Parent = parent; + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(CrumbBarItem ch) + { + return List.Add(ch); + } + /// + /// Returns reference to the object in collection based on it's index. + /// + public CrumbBarItem this[int index] + { + get { return (CrumbBarItem)(List[index]); } + set { List[index] = value; } + } + /// + /// Returns reference to the object in collection based on it's name. + /// + public CrumbBarItem this[string name] + { + get { return GetByName(name); } + set + { + int index = GetIndexByName(name); + if (index == -1) + throw new ArgumentException("name cannot be found in this collection"); + + List[index] = value; + } + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, CrumbBarItem value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(CrumbBarItem value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(CrumbBarItem value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + public void Remove(CrumbBarItem value) + { + List.Remove(value); + } + + protected override void OnSet(int index, object oldValue, object newValue) + { + CrumbBarItem item = (CrumbBarItem)oldValue; + item.SetOwner(null); + item = (CrumbBarItem)newValue; + item.SetOwner(_Parent); + + base.OnSet(index, oldValue, newValue); + } + + protected override void OnRemoveComplete(int index, object value) + { + CrumbBarItem item = (CrumbBarItem)value; + item.SetOwner(null); + if (item.IsSelected) + _Parent.SetSelectedItem(null, eEventSource.Code); + + base.OnRemoveComplete(index, value); + } + protected override void OnInsertComplete(int index, object value) + { + CrumbBarItem item = (CrumbBarItem)value; + item.SetOwner(_Parent); + item.ContainerControl = _Parent; + item.Style = eDotNetBarStyle.Office2007; + base.OnInsertComplete(index, value); + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(CrumbBarItem[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the CrumbBarItem array. + /// + /// Array to copy to. + internal void CopyTo(CrumbBarItem[] array) + { + List.CopyTo(array, 0); + } + + protected override void OnClear() + { + foreach (CrumbBarItem item in List) + { + item.SetOwner(null); + } + + base.OnClear(); + } + + protected override void OnClearComplete() + { + if (_Parent != null) + _Parent.OnItemsCleared(); + base.OnClearComplete(); + } + + private CrumbBarItem GetByName(string name) + { + foreach (CrumbBarItem d in this.List) + { + if (d.Name == name) + return d; + } + return null; + } + + private int GetIndexByName(string name) + { + for (int i = 0; i < this.List.Count; i++) + { + CrumbBarItem item = this[i]; + if (item.Name == name) + return i; + } + + return -1; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarOverflowButton.cs b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarOverflowButton.cs new file mode 100644 index 00000000..91d4082c --- /dev/null +++ b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarOverflowButton.cs @@ -0,0 +1,81 @@ +using System; +using System.Text; + +namespace DevComponents.DotNetBar +{ + public class CrumbBarOverflowButton : ButtonItem + { + #region Internal Implementation + protected override void RenderButton(ItemPaintArgs p) + { + if (!p.IsOnMenu) + { + Rendering.BaseRenderer renderer = p.Renderer; + if (renderer != null) + { + p.ButtonItemRendererEventArgs.Graphics = p.Graphics; + p.ButtonItemRendererEventArgs.ButtonItem = this; + p.ButtonItemRendererEventArgs.ItemPaintArgs = p; + renderer.DrawCrumbBarOverflowItem(p.ButtonItemRendererEventArgs); + return; + } + } + base.RenderButton(p); + } + + public override void RecalcSize() + { + m_Rect.Width = 16; + m_Rect.Height = 11; + m_NeedRecalcSize = false; + } + + public override void InternalMouseEnter() + { + CrumbBarViewContainer parent = this.Parent as CrumbBarViewContainer; + if (parent != null && parent.Expanded) + { + parent.Expanded = false; + this.Expanded = true; + } + base.InternalMouseEnter(); + } + + /// + /// Creates new instance of BaseItem. + /// + public CrumbBarOverflowButton():this("","") {} + /// + /// Creates new instance of BaseItem and assigns item name. + /// + /// Item name. + public CrumbBarOverflowButton(string sItemName) : this(sItemName, "") { } + /// + /// Creates new instance of BaseItem and assigns item name and item text. + /// + /// Item Name + /// Item Text + public CrumbBarOverflowButton(string itemName, string itemText) + : base(itemName, itemText) + { + this.AutoExpandOnClick = true; + this.ShowSubItems = false; + } + + /// + /// Returns copy of ExplorerBarContainerItem item + /// + public override BaseItem Copy() + { + CrumbBarOverflowButton objCopy = new CrumbBarOverflowButton(); + this.CopyToItem(objCopy); + return objCopy; + } + protected override void CopyToItem(BaseItem copy) + { + CrumbBarOverflowButton objCopy = copy as CrumbBarOverflowButton; + base.CopyToItem(objCopy); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarViewContainer.cs b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarViewContainer.cs new file mode 100644 index 00000000..bbd8763d --- /dev/null +++ b/PROMS/DotNetBar Source Code/CrumbBar/CrumbBarViewContainer.cs @@ -0,0 +1,255 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar +{ + /// + /// Represents internal CrumbBar view container. + /// + internal class CrumbBarViewContainer : ImageItem + { + #region Internal Implementation + /// + /// Initializes a new instance of the CrumbBarViewContainer class. + /// + public CrumbBarViewContainer() + : base() + { + LabelItem imageLabel = new LabelItem("sys_crumbbarimagelabel"); + this.SubItems.Add(imageLabel); + + CrumbBarOverflowButton overflowButton = new CrumbBarOverflowButton("sys_crumbbaroverflowbutton"); + this.SubItems.Add(overflowButton); + m_IsContainer = true; + } + + /// + /// Recalculates the size of the item + /// + public override void RecalcSize() + { + if (_InternalRemove) return; + + Point pos = m_Rect.Location; + Size containerSize = m_Rect.Size; + _CalculatedHeight = 0; + + if (m_SubItems == null) + return; + + RestoreOverflowItems(); + ButtonItem overflowButton = this.OverflowButton; + LabelItem imageLabel = this.ImageLabel; + + // Overflow button is hidden by default + overflowButton.Visible = false; + + Rectangle itemsRect = m_Rect; + + // Label may be hidden if there is no image assigned to current item + if (imageLabel.Visible) + { + imageLabel.RecalcSize(); + if (imageLabel.HeightInternal > _CalculatedHeight) _CalculatedHeight = imageLabel.HeightInternal; + imageLabel.HeightInternal = containerSize.Height; + itemsRect.X += imageLabel.WidthInternal; + itemsRect.Width -= imageLabel.WidthInternal; + imageLabel.Displayed = true; + } + Point itemsPos = itemsRect.Location; + + bool overflowState = false; + BaseItem[] items = new BaseItem[m_SubItems.Count - 2]; + if(m_SubItems.Count>2) + m_SubItems.CopyToFromIndex(items, 2); + + for (int i = items.Length - 1; i >= 0; i--) + { + BaseItem item = items[i]; + if (!item.Visible) + { + item.Displayed = false; + continue; + } + + if (!overflowState) + { + item.LeftInternal = itemsPos.X; + item.TopInternal = itemsPos.Y; + item.HeightInternal = itemsRect.Height; + item.RecalcSize(); + if (item.HeightInternal > _CalculatedHeight) _CalculatedHeight = item.HeightInternal; + item.HeightInternal = itemsRect.Height; + if (itemsPos.X + item.WidthInternal > itemsRect.Right || itemsPos.X + item.WidthInternal + 16 > itemsRect.Right && i > 0) + { + // Overflow mode + overflowState = true; + } + else + { + itemsPos.X += item.WidthInternal; + item.Displayed = true; + } + } + + if (overflowState) + { + _InternalRemove = true; + m_SubItems.Remove(item); + overflowButton.SubItems.Insert(0, item); + _InternalRemove = false; + } + } + + // Now position the items left inside + if (overflowState) + { + overflowButton.Visible = true; + overflowButton.Displayed = true; + overflowButton.HeightInternal = itemsRect.Height; + overflowButton.RecalcSize(); + overflowButton.LeftInternal = itemsRect.X; + overflowButton.TopInternal = itemsRect.Y; + overflowButton.HeightInternal = itemsRect.Height; + itemsRect.X += overflowButton.WidthInternal; + itemsRect.Width -= overflowButton.WidthInternal; + } + + itemsPos = itemsRect.Location; + for (int i = 2; i < m_SubItems.Count; i++) + { + BaseItem item = m_SubItems[i]; + if (!item.Visible) + continue; + if (item.WidthInternal + itemsPos.X > itemsRect.Right) + { + item.Displayed = false; + itemsPos.X = itemsRect.Right; + continue; + } + + item.LeftInternal = itemsPos.X; + itemsPos.X += item.WidthInternal; + } + + base.RecalcSize(); + } + + private int _CalculatedHeight = 0; + internal int CalculatedHeight + { + get { return _CalculatedHeight; } + } + + internal void RestoreOverflowItems() + { + ButtonItem overflowButton = this.OverflowButton; + if (overflowButton.SubItems.Count == 0) return; + + BaseItem[] overflowItems = new BaseItem[overflowButton.SubItems.Count]; + overflowButton.SubItems.CopyTo(overflowItems, 0); + overflowButton.SubItems.Clear(); + + for (int i = 0; i < overflowItems.Length; i++) + { + m_SubItems.Insert(i + 2, overflowItems[i]); + } + } + + internal LabelItem ImageLabel + { + get + { + return m_SubItems[0] as LabelItem; + } + } + + internal CrumbBarOverflowButton OverflowButton + { + get + { + return (CrumbBarOverflowButton)m_SubItems[1]; + } + } + + private bool _InternalRemove = false; + internal void ClearViewItems() + { + _InternalRemove = true; + while (m_SubItems.Count > 2) + m_SubItems.RemoveAt(m_SubItems.Count - 1); + _InternalRemove = false; + } + + /// + /// Paints this base container + /// + public override void Paint(ItemPaintArgs pa) + { + if (this.SuspendLayout) + return; + System.Drawing.Graphics g = pa.Graphics; + if (m_NeedRecalcSize) + RecalcSize(); + + if (m_SubItems == null) + return; + + foreach (BaseItem item in m_SubItems) + { + if (item.Visible && item.Displayed) + { + item.Paint(pa); + } + } + } + + /// + /// Returns copy of ExplorerBarContainerItem item + /// + public override BaseItem Copy() + { + CrumbBarViewContainer objCopy = new CrumbBarViewContainer(); + this.CopyToItem(objCopy); + return objCopy; + } + protected override void CopyToItem(BaseItem copy) + { + CrumbBarViewContainer objCopy = copy as CrumbBarViewContainer; + base.CopyToItem(objCopy); + } + + /// + /// Gets or sets a value indicating whether the item is expanded or not. For Popup items this would indicate whether the item is popped up or not. + /// + [System.ComponentModel.Browsable(false), System.ComponentModel.DefaultValue(false), System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public override bool Expanded + { + get + { + return m_Expanded; + } + set + { + base.Expanded = value; + if (!value) + BaseItem.CollapseSubItems(this); + } + } + + /// + /// Occurs when sub item expanded state has changed. + /// + /// Sub item affected. + protected internal override void OnSubItemExpandChange(BaseItem item) + { + base.OnSubItemExpandChange(item); + if (item.Expanded) + this.Expanded = true; + else + base.Expanded = false; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/CustomizeItem.cs b/PROMS/DotNetBar Source Code/CustomizeItem.cs new file mode 100644 index 00000000..5a1df3ea --- /dev/null +++ b/PROMS/DotNetBar Source Code/CustomizeItem.cs @@ -0,0 +1,932 @@ +namespace DevComponents.DotNetBar +{ + using System; + using System.Drawing; + using System.Resources; + using System.ComponentModel; + using DevComponents.DotNetBar.Rendering; + + /// + /// Defines an item that allows the toolbar customization. + /// + [System.ComponentModel.ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false)] + public class CustomizeItem:PopupItem + { + private bool m_MouseOver; + private string m_CustomizeStr="",m_ResetStr=""; + + private string m_ThisToolTip; + + private bool m_Localized=false; + + private bool m_CustomizeItemVisible=true; + private bool m_AutoSizeMenuImages=true; + private System.Drawing.Size m_MenuImageSize=Size.Empty; + + /// + /// Creates new instance of CustomizeItem object. + /// + public CustomizeItem()//:base() + { + this.GlobalItem=false; + m_MouseOver=false; + m_SystemItem=true; + this.CanCustomize=false; + + LoadResources(); + + this.AutoCollapseOnClick=false; + + m_MenuImageSize=new Size(16,16); + } + + /// + /// Returns copy of CustomizeItem item + /// + public override BaseItem Copy() + { + CustomizeItem objCopy=new CustomizeItem(); + this.CopyToItem(objCopy); + objCopy.CustomizeItemVisible=m_CustomizeItemVisible; + return objCopy; + } + + /// + /// Called when item container has changed. If you override this method you must call the base implementation to allow default processing to occur. + /// + /// Previous container of the item. + protected internal override void OnContainerChanged(object objOldContainer) + { + base.OnContainerChanged(objOldContainer); + LoadResources(); + } + + /// + /// Occurs when tooltip is about to be shown or hidden. + /// + /// Specifies whether tooltip is shown or hidden. + protected override void OnTooltip(bool bShow) + { + LoadResources(); + base.OnTooltip(bShow); + } + + /// + /// Loads the resources (text) used by this item. + /// + protected virtual void LoadResources() + { + if(!m_Localized) + { + if(this.GetOwner()!=null) + m_Localized=true; + using(LocalizationManager lm=new LocalizationManager(this.GetOwner() as IOwnerLocalize)) + { + m_ThisToolTip=lm.GetLocalizedString(LocalizationKeys.CustomizeItemTooltip); + this.Text=lm.GetLocalizedString(LocalizationKeys.CustomizeItemAddRemove); + m_CustomizeStr = lm.GetLocalizedString(LocalizationKeys.CustomizeItemCustomize); + m_ResetStr=lm.GetLocalizedString(LocalizationKeys.CustomizeItemReset); + } + } + } + + /// + /// Overriden. Draws the item. + /// + /// Target Graphics object. + public override void Paint(ItemPaintArgs pa) + { + if (this.SuspendLayout) + return; + eDotNetBarStyle effectiveStyle = EffectiveStyle; + if (effectiveStyle == eDotNetBarStyle.Office2000) + PaintOffice(pa); + else + { + if (this.IsThemed && !this.IsOnMenu) + PaintThemed(pa); + else if (effectiveStyle == eDotNetBarStyle.Office2003 || effectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(effectiveStyle)) + { + PaintOffice2003(pa); + return; + } + else + PaintDotNet(pa); + } + if (BaseItem.IsOnPopup(this)) + return; + + Point[] p = new Point[3]; + if (m_Orientation == eOrientation.Vertical) + { + p[0].X = m_Rect.Left + Dpi.Width7; + p[0].Y = m_Rect.Top + Dpi.Height4; + p[1].X = p[0].X - Dpi.Width3; + p[1].Y = p[0].Y + Dpi.Height3; + p[2].X = p[0].X; + p[2].Y = p[0].Y + Dpi.Height6; + pa.Graphics.FillPolygon(SystemBrushes.ControlText, p); + } + else + { + p[0].X = m_Rect.Left + (m_Rect.Width / 2) - Dpi.Width1; + p[0].Y = m_Rect.Bottom - Dpi.Height4; + p[1].X = p[0].X - Dpi.Width2; + p[1].Y = p[0].Y - Dpi.Height3; + p[2].X = p[1].X + Dpi.Width5; + p[2].Y = p[1].Y; + pa.Graphics.FillPolygon(SystemBrushes.ControlText, p); + } + + if (this.DesignMode && this.Focused) + { + Rectangle r = m_Rect; + //r.Inflate(-1,-1); + DesignTime.DrawDesignTimeSelection(pa.Graphics, r, pa.Colors.ItemDesignTimeBorder); + } + } + + private void PaintThemed(ItemPaintArgs pa) + { + ThemeToolbar theme=pa.ThemeToolbar; + ThemeToolbarParts part=ThemeToolbarParts.Button; + ThemeToolbarStates state=ThemeToolbarStates.Normal; + if(m_Expanded) + state=ThemeToolbarStates.Pressed; + else if(m_MouseOver) + state=ThemeToolbarStates.Hot; + + theme.DrawBackground(pa.Graphics,part,state,m_Rect); + + theme=null; + + if(!BaseItem.IsOnPopup(this)) + return; + + Font objFont=null; + eTextFormat objStringFormat=GetStringFormat(); + Point[] p; + + objFont=GetFont(); + Rectangle rect=m_Rect; + rect.Inflate(-1,-1); + rect.Width-=6; + + TextDrawing.DrawString(pa.Graphics,m_Text,objFont,SystemColors.ControlText,rect,objStringFormat); + + p=new Point[3]; + p[0].X=m_Rect.Right-8; + p[0].Y=m_Rect.Top+m_Rect.Height/2+3; + p[1].X=p[0].X-2; + p[1].Y=p[0].Y-3; + p[2].X=p[1].X+5; + p[2].Y=p[1].Y; + pa.Graphics.FillPolygon(SystemBrushes.ControlText,p); + + } + + private void PaintDotNet(ItemPaintArgs pa) + { + Rectangle r = m_Rect; + System.Drawing.Graphics g=pa.Graphics; + + eDotNetBarStyle effectiveStyle = EffectiveStyle; + if (effectiveStyle == eDotNetBarStyle.Office2010 || effectiveStyle == eDotNetBarStyle.Office2007 || effectiveStyle == eDotNetBarStyle.Windows7) + { + Office2007ButtonItemStateColorTable stateColors = null; + if (pa.Renderer is Office2007Renderer) + { + Office2007ButtonItemColorTable ct = ((Office2007Renderer)pa.Renderer).ColorTable.ButtonItemColors[0]; + if (this.Expanded) + stateColors = ct.Expanded; + else if (m_MouseOver) + stateColors = ct.MouseOver; + else + stateColors = ct.Default; + } + if (stateColors != null) + Office2007ButtonItemPainter.PaintBackground(g, stateColors, r, RoundRectangleShapeDescriptor.RoundCorner2, false, true); + } + else + { + if (this.Expanded) + { + r = new Rectangle(m_Rect.Left + Dpi.Width2, m_Rect.Top + Dpi.Height2, m_Rect.Width - Dpi.Width2, m_Rect.Height - Dpi.Height2); + g.FillRectangle(SystemBrushes.ControlDark, r); + r.Offset(-Dpi.Width2, -Dpi.Height2); + r.Height += Dpi.Height2; + DisplayHelp.FillRectangle(g, r, pa.Colors.ItemExpandedBackground, pa.Colors.ItemExpandedBackground2, pa.Colors.ItemExpandedBackgroundGradientAngle); + DisplayHelp.DrawRectangle(g, pa.Colors.MenuBorder, r); + } + else if (m_MouseOver) + { + r = new Rectangle(m_Rect.Left, m_Rect.Top, m_Rect.Width - Dpi.Width2, m_Rect.Height); + + DisplayHelp.FillRectangle(g, r, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + DisplayHelp.DrawRectangle(g, pa.Colors.ItemHotBorder, r); + } + if (!BaseItem.IsOnPopup(this)) + return; + + if (this.Expanded) + { + DisplayHelp.FillRectangle(g, m_Rect, pa.Colors.ItemExpandedBackground, pa.Colors.ItemExpandedBackground2, pa.Colors.ItemExpandedBackgroundGradientAngle); + DisplayHelp.DrawRectangle(g, pa.Colors.MenuBorder, m_Rect); + } + } + Font objFont = null; + eTextFormat objStringFormat = GetStringFormat(); + Point[] p; + objFont=GetFont(); + Rectangle rect=m_Rect; + rect.Inflate(-Dpi.Width1, -Dpi.Height1); + rect.Width -= Dpi.Width6; + rect.X += Dpi.Width4; + + TextDrawing.DrawString(g,m_Text,objFont,SystemColors.ControlText,rect,objStringFormat); + + p=new Point[3]; + p[0].X = m_Rect.Right - Dpi.Width6; + p[0].Y = m_Rect.Top + m_Rect.Height / 2 + Dpi.Height3; + p[1].X = p[0].X - Dpi.Width2; + p[1].Y = p[0].Y - Dpi.Height3; + p[2].X = p[1].X + Dpi.Width5; + p[2].Y=p[1].Y; + g.FillPolygon(SystemBrushes.ControlText,p); + + } + + private void PaintOffice2003(ItemPaintArgs pa) + { + // When on popup the Customize Item is painted same as in .NET style... + if (BaseItem.IsOnPopup(this)) + { + PaintDotNet(pa); + return; + } + + Graphics g = pa.Graphics; + Rectangle r = m_Rect; + + System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); + if (this.Orientation == eOrientation.Vertical) + { + // When on docked toolbar it has a special look... + r.Y += Dpi.Height2; + r.Height -= Dpi.Height1; + r.X -= Dpi.Width2; + r.Width += Dpi.Width2; + + if (pa.RightToLeft) + { + path.AddLine(r.Right, r.Y, r.Right - Dpi.Width2, r.Y + Dpi.Height2); + path.AddLine(r.X + Dpi.Width2, r.Y + Dpi.Height2, r.X, r.Y); + path.AddLine(r.X, r.Bottom - Dpi.Height2, r.X + Dpi.Width2, r.Bottom); + path.AddLine(r.Right - Dpi.Width2, r.Bottom, r.Right, r.Bottom - Dpi.Height2); + } + else + { + path.AddLine(r.X, r.Y, r.X + Dpi.Width2, r.Y + Dpi.Height2); + path.AddLine(r.Right - Dpi.Width2, r.Y + Dpi.Height2, r.Right, r.Y); + path.AddLine(r.Right, r.Bottom - Dpi.Height2, r.Right - Dpi.Width2, r.Bottom); + path.AddLine(r.X + Dpi.Width2, r.Bottom, r.X, r.Bottom - Dpi.Height2); + } + path.CloseAllFigures(); + } + else + { + // When on docked toolbar it has a special look... + r.X += Dpi.Width2; + r.Width -= Dpi.Width1; + r.Y -= Dpi.Height2; + r.Height += Dpi.Height3; + + if (pa.RightToLeft) + { + r.X -= Dpi.Width2; + path.AddLine(r.Right, r.Y, r.Right - Dpi.Width2, r.Y + Dpi.Height2); + path.AddLine(r.Right - Dpi.Width2, r.Bottom - Dpi.Height2, r.Right, r.Bottom); + path.AddLine(r.X + Dpi.Width2, r.Bottom, r.X, r.Bottom - Dpi.Height2); + path.AddLine(r.X, r.Y + Dpi.Height2, r.X + Dpi.Width2, r.Y); + } + else + { + path.AddLine(r.X, r.Y, r.X + Dpi.Width2, r.Y + Dpi.Height2); + path.AddLine(r.X + Dpi.Width2, r.Bottom - Dpi.Height2, r.X, r.Bottom); + path.AddLine(r.Right - Dpi.Width2, r.Bottom, r.Right, r.Bottom - Dpi.Height2); + path.AddLine(r.Right, r.Y + Dpi.Height2, r.Right - Dpi.Width2, r.Y); + } + path.CloseAllFigures(); + } + + System.Drawing.Drawing2D.SmoothingMode smooth = g.SmoothingMode; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + + if (this.Expanded) + DisplayHelp.FillPath(g, path, pa.Colors.ItemPressedBackground, pa.Colors.ItemPressedBackground2, pa.Colors.ItemPressedBackgroundGradientAngle); + else if (m_MouseOver) + DisplayHelp.FillPath(g, path, pa.Colors.ItemHotBackground, pa.Colors.ItemHotBackground2, pa.Colors.ItemHotBackgroundGradientAngle); + else + DisplayHelp.FillPath(g, path, pa.Colors.CustomizeBackground, pa.Colors.CustomizeBackground2, pa.Colors.CustomizeBackgroundGradientAngle); + + g.SmoothingMode = smooth; + + //using(Pen pen=new Pen(SystemColors.Window,1)) + // g.DrawLine(pen,r.Left+(m_Rect.Width-4)/2+1,r.Bottom-11+1,r.Left+(m_Rect.Width-4)/2+4+1,r.Bottom-11+1); + + if (this.Orientation == eOrientation.Vertical) + { + // Draw Arrow Shade + Point[] p = new Point[3]; + p[0].X = r.Left + (m_Rect.Width - Dpi.Width4) / 2 + Dpi.Width3; + p[0].Y = r.Bottom - Dpi.Height3 + Dpi.Height1; + p[1].X = p[0].X - Dpi.Width2; + p[1].Y = p[0].Y - Dpi.Height3; + p[2].X = p[1].X + Dpi.Width5; + p[2].Y = p[1].Y; + using (SolidBrush brush = new SolidBrush(SystemColors.Window)) // SystemColors.HighlightText)) + g.FillPolygon(brush, p); + + // Draw Arrow + using (Pen pen = new Pen(pa.Colors.CustomizeText, 1)) + g.DrawLine(pen, r.Left + (m_Rect.Width - Dpi.Width4) / 2, r.Bottom - Dpi.Height9, r.Left + (m_Rect.Width - Dpi.Width4) / 2 + Dpi.Width4, r.Bottom - Dpi.Height9); + p = new Point[3]; + p[0].X = r.Left + (m_Rect.Width - Dpi.Width4) / 2 + Dpi.Width2; + p[0].Y = r.Bottom - Dpi.Height3; + p[1].X = p[0].X - Dpi.Width2; + p[1].Y = p[0].Y - Dpi.Height3; + p[2].X = p[1].X + Dpi.Width5; + p[2].Y = p[1].Y; + using (SolidBrush brush = new SolidBrush(pa.Colors.CustomizeText)) + g.FillPolygon(brush, p); + } + else + { + // Draw Arrow Shade + Point[] p = new Point[3]; + p[0].X = r.Left + (m_Rect.Width - Dpi.Width4) / 2 + Dpi.Width3; + p[0].Y = r.Bottom - Dpi.Height5 + Dpi.Height1; + p[1].X = p[0].X - Dpi.Width2; + p[1].Y = p[0].Y - Dpi.Height3; + p[2].X = p[1].X + Dpi.Width5; + p[2].Y = p[1].Y; + using (SolidBrush brush = new SolidBrush(SystemColors.Window)) // SystemColors.HighlightText)) + g.FillPolygon(brush, p); + + // Draw Arrow + using (Pen pen = new Pen(pa.Colors.CustomizeText, 1)) + g.DrawLine(pen, r.Left + (m_Rect.Width - Dpi.Width4) / 2, r.Bottom - Dpi.Height11, r.Left + (m_Rect.Width - Dpi.Width4) / 2 + Dpi.Width4, r.Bottom - Dpi.Height11); + p = new Point[3]; + p[0].X = r.Left + (m_Rect.Width - Dpi.Width4) / 2 + Dpi.Width2; + p[0].Y = r.Bottom - Dpi.Height5; + p[1].X = p[0].X - Dpi.Width2; + p[1].Y = p[0].Y - Dpi.Height3; + p[2].X = p[1].X + Dpi.Width5; + p[2].Y = p[1].Y; + using (SolidBrush brush = new SolidBrush(pa.Colors.CustomizeText)) + g.FillPolygon(brush, p); + } + } + + private void PaintOffice(ItemPaintArgs pa) + { + System.Drawing.Graphics g=pa.Graphics; + if(this.Expanded) + { + System.Windows.Forms.ControlPaint.DrawBorder3D(g,m_Rect,System.Windows.Forms.Border3DStyle.SunkenOuter); + } + else if(m_MouseOver) + { + System.Windows.Forms.ControlPaint.DrawBorder3D(g,m_Rect,System.Windows.Forms.Border3DStyle.RaisedInner); + } + if(!BaseItem.IsOnPopup(this)) + return; + + Font objFont=null; + eTextFormat objStringFormat=GetStringFormat(); + + objFont=GetFont(); + Rectangle rect=m_Rect; + rect.Inflate(-Dpi.Width1,-Dpi.Height1); + rect.Width-=Dpi.Width6; + if(this.Expanded) + { + rect.Offset(Dpi.Width1, Dpi.Height1); + rect.Width -= Dpi.Width1; + rect.Height -= Dpi.Height1; + } + TextDrawing.DrawString(g,m_Text,objFont,SystemColors.ControlText,rect,objStringFormat); + + Point[] p=new Point[3]; + p[0].X = m_Rect.Right - Dpi.Width8; + p[0].Y = m_Rect.Top + m_Rect.Height / 2 + Dpi.Height3; + p[1].X = p[0].X - Dpi.Width2; + p[1].Y = p[0].Y - Dpi.Height3; + p[2].X = p[1].X + Dpi.Width5; + p[2].Y=p[1].Y; + g.FillPolygon(SystemBrushes.ControlText,p); + } + + /// + /// Sets the custom system tooltip text for the item. + /// + /// Tooltip text. + protected virtual void SetCustomTooltip(string text) + { + this.Tooltip = text; + } + + /// + /// Overriden. Recalculates the size of the item. + /// + public override void RecalcSize() + { + if(this.SuspendLayout) + return; + + if(!BaseItem.IsOnPopup(this)) + { + if(m_Orientation==eOrientation.Vertical) + { + // Take suggested width + m_Rect.Height=Dpi.Width14; + m_Rect.Width=Dpi.Height22; + } + else + { + // Take suggested height + m_Rect.Width = Dpi.Width14; + m_Rect.Height=Dpi.Height22; + } + m_BeginGroup=false; + SetCustomTooltip(GetTooltipText()); + } + else + { + SetCustomTooltip(""); + m_BeginGroup=true; + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(!IsHandleValid(objCtrl)) + return; + Graphics g=Graphics.FromHwnd(objCtrl.Handle); + // Get the right image size that we will use for calculation + Size objImageSize=Size.Empty; + if(m_Parent!=null) + { + ImageItem objParentImageItem=m_Parent as ImageItem; + if(objParentImageItem!=null) + objImageSize=new Size(objParentImageItem.SubItemsImageSize.Width,objParentImageItem.SubItemsImageSize.Height); + else + objImageSize=this.ImageSize; + } + else + objImageSize=this.ImageSize; + + // Measure string + Font objCurrentFont=null; + objCurrentFont=GetFont(); + + Size objStringSize=Size.Empty; + eTextFormat objStringFormat=GetStringFormat(); + + if(m_Text!="") + { + objStringSize=TextDrawing.MeasureString(g,m_Text,objCurrentFont,512,objStringFormat); + objStringSize.Width+=Dpi.Width2; + } + + // Calculate item height + if(objStringSize.Height>objImageSize.Height) + m_Rect.Height=(int)objStringSize.Height+Dpi.Height4; + else + m_Rect.Height=objImageSize.Height+Dpi.Height4; + m_Rect.Width=(int)objStringSize.Width+Dpi.Width15; + } + + base.RecalcSize(); + } + + /// + /// Gets localized tooltip text for this instance of the item. + /// + /// Tooltip text. + protected virtual string GetTooltipText() + { + return m_ThisToolTip; + } + + /*private bool IsOnPopUp() + { + if(this.ContainerControl is PopupMenu) + return true; + Bar objTlb=this.ContainerControl as Bar; + if(objTlb!=null && objTlb.BarState==eBarState.Popup) + return true; + return false; + }*/ + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseEnter() + { + base.InternalMouseEnter(); + m_MouseOver=true; + this.Refresh(); + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseHover() + { + base.InternalMouseHover(); + MouseHoverCustomize(); + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseLeave() + { + base.InternalMouseLeave(); + m_MouseOver=false; + this.Refresh(); + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseDown(System.Windows.Forms.MouseEventArgs objArg) + { + base.InternalMouseDown(objArg); + if(objArg.Button != System.Windows.Forms.MouseButtons.Left || this.DesignMode) + return; + MouseDownAction(); + } + + protected virtual void MouseDownAction() + { + this.Expanded = !m_Expanded; + } + + /// + /// Called when mouse hovers over the customize item. + /// + protected virtual void MouseHoverCustomize() + { + if (!this.Expanded && BaseItem.IsOnPopup(this)) + this.Expanded = true; + } + + /// + /// Gets whether the mouse is over the item. + /// + [Browsable(false)] + public bool IsMouseOver + { + get { return m_MouseOver; } + } + + protected internal override void OnExpandChange() + { + if (this.Expanded) + SetupCustomizeItem(); + + base.OnExpandChange(); + if (!this.Expanded) + ClearCustomizeItem(); + } + + protected virtual void SetupCustomizeItem() + { + if (BaseItem.IsOnPopup(this)) + { + AddCustomizeItems(); + this.PopupType = ePopupType.Menu; + } + else + { + this.SubItems.Clear(); + CustomizeItem btn = new CustomizeItem(); + btn.CustomizeItemVisible = this.CustomizeItemVisible; + btn.IsRightToLeft = this.IsRightToLeft; + this.SubItems.Add(btn); + this.PopupType = ePopupType.ToolBar; + } + } + + protected virtual void ClearCustomizeItem() + { + this.SubItems.Clear(); + } + + private void AddRemoveClick(object sender) + { + ((ButtonItem)sender).Expanded=!((ButtonItem)sender).Expanded; + } + + private void ShowHideClick(object sender, System.EventArgs e) + { + BaseItem objBtn=((BaseItem)sender).Tag as BaseItem; + bool bGlobal=objBtn.GlobalItem; + objBtn.GlobalItem=false; + objBtn.SetVisibleDirect(!objBtn.Visible); + if (objBtn is TextBoxItem || objBtn is ComboBoxItem || objBtn is ControlContainerItem || objBtn.ContainerControl is NavigationBar) + objBtn.OnVisibleChanged(objBtn.Visible); + objBtn.UserCustomized = true; + objBtn.GlobalItem=bGlobal; + ((BaseItem)sender).Visible=!((BaseItem)sender).Visible; + + if(objBtn.ContainerControl is Bar) + ((Bar)objBtn.ContainerControl).RecalcLayout(); + else if(objBtn.ContainerControl is MenuPanel) + ((MenuPanel)objBtn.ContainerControl).RecalcSize(); + else if(objBtn.ContainerControl is BarBaseControl) + ((BarBaseControl)objBtn.ContainerControl).RecalcLayout(); + + ((BaseItem)sender).Refresh(); + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null) + { + owner.InvokeUserCustomize(objBtn,new EventArgs()); + owner.InvokeEndUserCustomize(objBtn,new EndUserCustomizeEventArgs(eEndUserCustomizeAction.ItemVisibilityChanged)); + } + } + + private void CustomizeClick(object sender, System.EventArgs e) + { + IOwner owner=this.GetOwner() as IOwner; + if(owner==null) + return; + CollapseAll(this); + owner.Customize(); + } + + private void ResetClick(object sender, System.EventArgs e) + { + IOwner owner=this.GetOwner() as IOwner; + if(owner==null) + return; + BaseItem item=this; + if(BaseItem.IsOnPopup(this) && this.Parent!=null) + item=this.Parent; + CollapseAll(this); + owner.InvokeResetDefinition(item,new EventArgs()); + } + + /// + /// Forces the repaint the item. + /// + public override void Refresh() + { + if(this.SuspendLayout) + return; + if ((EffectiveStyle == eDotNetBarStyle.Office2003 || EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(this.EffectiveStyle)) && !BaseItem.IsOnPopup(this)) + { + if((m_Visible || this.IsOnCustomizeMenu) && m_Displayed) + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null && IsHandleValid(objCtrl) && !(objCtrl is ItemsListBox)) + { + if(m_NeedRecalcSize) + { + RecalcSize(); + if(m_Parent!=null) + m_Parent.SubItemSizeChanged(this); + } + Rectangle r=m_Rect; + r.Inflate(2,2); + objCtrl.Invalidate(r,true); + } + } + } + else + base.Refresh(); + } + + private void AddCustomizeItems() + { + BaseItem objTmp; + BaseItem objParent; + + this.SubItems.Clear(); + + // Find the right parent item + /*System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl is Bar) + { + Bar objTlb=objCtrl as Bar; + if(objTlb.Parent==null) + objParent=this.Parent; + else + objParent=objTlb.Parent; + } + else + { + objParent=this.Parent; + }*/ + objParent=this.Parent; + + while(objParent!=null && objParent.SystemItem && !(objParent.SystemItem && objParent is GenericItemContainer)) + objParent=objParent.Parent; + + if(objParent==null) + return; + + foreach(BaseItem objItem in objParent.SubItems) + { + if(!objItem.SystemItem && objItem.CanCustomize) + { + objTmp=objItem.Copy(); + objTmp.GlobalItem=false; + objTmp.ClearClick(); + objTmp.BeginGroup=false; + objTmp.Enabled=true; + objTmp.SubItems.Clear(); + objTmp.Tooltip=""; + objTmp.SetIsOnCustomizeMenu(true); + if(objItem is ButtonItem) + { + ((ButtonItem)objTmp).HotTrackingStyle=eHotTrackingStyle.Default; + if (m_AutoSizeMenuImages && !m_MenuImageSize.IsEmpty && ((ButtonItem)objTmp).ImageSize != m_MenuImageSize) + { + ((ButtonItem)objTmp).ImageFixedSize = m_MenuImageSize; + ((ButtonItem)objTmp).UseSmallImage = true; + } + } + objTmp.Click+=new System.EventHandler(ShowHideClick); + objTmp.Tag=objItem; + this.SubItems.Add(objTmp); + } + } + if(objParent is GenericItemContainer && ((GenericItemContainer)objParent).MoreItems!=null) + { + BaseItem objMore=((GenericItemContainer)objParent).MoreItems; + foreach(BaseItem objItem in objMore.SubItems) + { + if(!objItem.SystemItem) + { + objTmp=objItem.Copy(); + objTmp.GlobalItem=false; + objTmp.ClearClick(); + objTmp.BeginGroup=false; + objTmp.Enabled=true; + objTmp.SubItems.Clear(); + objTmp.Tooltip=""; + objTmp.SetIsOnCustomizeMenu(true); + objTmp.Click+=new System.EventHandler(ShowHideClick); + objTmp.Tag=objItem; + this.SubItems.Add(objTmp); + } + } + } + + objTmp=null; + + ButtonItem objBtn=null; + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null && owner.ShowResetButton) + { + // Reset Bar Item + objBtn=new ButtonItem(); + objBtn.GlobalItem=false; + objBtn.BeginGroup=true; + objBtn.Text=m_ResetStr; // "&Reset Bar"; + objBtn.SetIsOnCustomizeMenu(true); + objBtn.SetSystemItem(true); + objBtn.Orientation=eOrientation.Horizontal; + objBtn.Click+=new System.EventHandler(ResetClick); + this.SubItems.Add(objBtn); + } + if(m_CustomizeItemVisible) + { + // Customize + objBtn=new ButtonItem(); + objBtn.GlobalItem=false; + if(owner==null || owner!=null && !owner.ShowResetButton) + objBtn.BeginGroup=true; + objBtn.Text=m_CustomizeStr; //"&Customize..."; + objBtn.SetIsOnCustomizeMenu(true); + objBtn.SetSystemItem(true); + objBtn.Click+=new System.EventHandler(CustomizeClick); + this.SubItems.Add(objBtn); + } + + m_NeedRecalcSize=false; + } + + private eTextFormat GetStringFormat() + { + eTextFormat format = eTextFormat.Default; + format |= eTextFormat.SingleLine; + //format |= eTextFormat.EndEllipsis; + format |= eTextFormat.VerticalCenter; + return format; + //StringFormat sfmt=BarFunctions.CreateStringFormat(); //new StringFormat(StringFormat.GenericDefault); + //sfmt.HotkeyPrefix=System.Drawing.Text.HotkeyPrefix.Show; + ////sfmt.FormatFlags=sfmt.FormatFlags & ~(sfmt.FormatFlags & StringFormatFlags.DisableKerning); + //sfmt.FormatFlags=sfmt.FormatFlags | StringFormatFlags.NoWrap; + //sfmt.Alignment=System.Drawing.StringAlignment.Near; + //sfmt.LineAlignment=System.Drawing.StringAlignment.Center; + //return sfmt; + } + + /// + /// Returns the Font object to be used for drawing the item text. + /// + /// Font object. + protected virtual Font GetFont() + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null) + return (Font)objCtrl.Font; + return SystemFonts.DefaultFont;// (Font)System.Windows.Forms.SystemInformation.MenuFont; + } + + /// + /// Gets or sets a value indicating whether the item is visible. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(true), Category("Behavior"), Description("Determines whether the item is visible or hidden.")] + public override bool Visible + { + get + { + Bar objTlb=this.ContainerControl as Bar; + if(objTlb!=null) + { + if(objTlb.BarState==eBarState.Docked || objTlb.BarState==eBarState.Popup) + return base.Visible; + else + return false; + } + return base.Visible; + } + set + { + base.Visible=value; + } + } + + /// + /// Gets or sets whether Customize menu item is visible. + /// + [Browsable(true),DevCoBrowsable(true),Category("Behavior"),Description("Indicates whether Customize menu item is visible."),DefaultValue(true)] + public virtual bool CustomizeItemVisible + { + get {return m_CustomizeItemVisible;} + set {m_CustomizeItemVisible=value;} + } + + /// + /// Overloaded. Serializes the item and all sub-items into the XmlElement. + /// + /// XmlElement to serialize the item to. + protected internal override void Serialize(ItemSerializationContext context) + { + base.Serialize(context); + System.Xml.XmlElement ThisItem = context.ItemXmlElement; + if(!m_CustomizeItemVisible) + ThisItem.SetAttribute("customizeitemvisible",System.Xml.XmlConvert.ToString(m_CustomizeItemVisible)); + } + + /// + /// Overloaded. Deserializes the Item from the XmlElement. + /// + /// Source XmlElement. + public override void Deserialize(ItemSerializationContext context) + { + base.Deserialize(context); + System.Xml.XmlElement ItemXmlSource = context.ItemXmlElement; + if(ItemXmlSource.HasAttribute("customizeitemvisible")) + m_CustomizeItemVisible=System.Xml.XmlConvert.ToBoolean(ItemXmlSource.GetAttribute("customizeitemvisible")); + } + + /// + /// Indicates whether the item will auto-collapse (fold) when clicked. + /// When item is on popup menu and this property is set to false, menu will not + /// close when item is clicked. + /// + [Browsable(false), DevCoBrowsable(false), Category("Behavior"), DefaultValue(false), Description("Indicates whether the item will auto-collapse (fold) when clicked.")] + public override bool AutoCollapseOnClick + { + get { return base.AutoCollapseOnClick; } + set {base.AutoCollapseOnClick = value; } + } + + /// + /// Gets or sets whether item can be customized by end user. + /// + [Browsable(false), DevCoBrowsable(false), DefaultValue(false), Category("Behavior"), Description("Indicates whether item can be customized by user.")] + public override bool CanCustomize + { + get { return base.CanCustomize; } + set { base.CanCustomize = value; } + } + + /// + /// Gets or sets whether item is global or not. + /// This flag is used to propagate property changes to all items with the same name. + /// Setting for example Visible property on the item that has GlobalItem set to true will + /// set visible property to the same value on all items with the same name. + /// + [Browsable(false), DevCoBrowsable(false), DefaultValue(false), Category("Behavior"), Description("Indicates whether certain global properties are propagated to all items with the same name when changed.")] + public override bool GlobalItem + { + get { return base.GlobalItem; } + set { base.GlobalItem = value; } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DRAGCOPY.CUR b/PROMS/DotNetBar Source Code/DRAGCOPY.CUR new file mode 100644 index 00000000..981784bf Binary files /dev/null and b/PROMS/DotNetBar Source Code/DRAGCOPY.CUR differ diff --git a/PROMS/DotNetBar Source Code/DRAGMOVE.CUR b/PROMS/DotNetBar Source Code/DRAGMOVE.CUR new file mode 100644 index 00000000..b583cf99 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DRAGMOVE.CUR differ diff --git a/PROMS/DotNetBar Source Code/DRAGNONE.CUR b/PROMS/DotNetBar Source Code/DRAGNONE.CUR new file mode 100644 index 00000000..a82ee45f Binary files /dev/null and b/PROMS/DotNetBar Source Code/DRAGNONE.CUR differ diff --git a/PROMS/DotNetBar Source Code/DateTimeInput.ico b/PROMS/DotNetBar Source Code/DateTimeInput.ico new file mode 100644 index 00000000..2b2c4cc3 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DateTimeInput.ico differ diff --git a/PROMS/DotNetBar Source Code/DefinitionPreviewControl.cs b/PROMS/DotNetBar Source Code/DefinitionPreviewControl.cs new file mode 100644 index 00000000..6c5da38d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DefinitionPreviewControl.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Design +{ + /// + /// Summary description for DefinitionPreviewControl. + /// + [ToolboxItem(false)] + internal class DefinitionPreviewControl : System.Windows.Forms.UserControl + { + private DevComponents.DotNetBar.DockSite barLeftDockSite; + private DevComponents.DotNetBar.DockSite barRightDockSite; + private DevComponents.DotNetBar.DockSite barTopDockSite; + private DevComponents.DotNetBar.DockSite barBottomDockSite; + internal DevComponents.DotNetBar.DotNetBarManager previewManager; + private System.ComponentModel.IContainer components; + + public event EventHandler DataChanged; + + public DefinitionPreviewControl() + { + // This call is required by the Windows.Forms Form Designer. + InitializeComponent(); + + previewManager.DefinitionLoaded+=new EventHandler(this.DefinitionLoaded); + + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Component Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + #if !TRIAL + this.previewManager = new DevComponents.DotNetBar.DotNetBarManager(this.components,true); + #else + this.previewManager = new DevComponents.DotNetBar.DotNetBarManager(this.components); + #endif + this.barBottomDockSite = new DevComponents.DotNetBar.DockSite(); + this.barLeftDockSite = new DevComponents.DotNetBar.DockSite(); + this.barRightDockSite = new DevComponents.DotNetBar.DockSite(); + this.barTopDockSite = new DevComponents.DotNetBar.DockSite(); + this.SuspendLayout(); + // + // previewManager + // + this.previewManager.AutoDispatchShortcuts.Add(DevComponents.DotNetBar.eShortcut.F1); + this.previewManager.AutoDispatchShortcuts.Add(DevComponents.DotNetBar.eShortcut.CtrlC); + this.previewManager.AutoDispatchShortcuts.Add(DevComponents.DotNetBar.eShortcut.CtrlA); + this.previewManager.AutoDispatchShortcuts.Add(DevComponents.DotNetBar.eShortcut.CtrlV); + this.previewManager.AutoDispatchShortcuts.Add(DevComponents.DotNetBar.eShortcut.CtrlX); + this.previewManager.AutoDispatchShortcuts.Add(DevComponents.DotNetBar.eShortcut.CtrlZ); + this.previewManager.AutoDispatchShortcuts.Add(DevComponents.DotNetBar.eShortcut.Del); + this.previewManager.AutoDispatchShortcuts.Add(DevComponents.DotNetBar.eShortcut.Ins); + this.previewManager.BottomDockSite = this.barBottomDockSite; + this.previewManager.DefinitionName = ""; + this.previewManager.LeftDockSite = this.barLeftDockSite; + this.previewManager.ParentForm = null; + this.previewManager.RightDockSite = this.barRightDockSite; + this.previewManager.Style = DevComponents.DotNetBar.eDotNetBarStyle.Office2003; + this.previewManager.TopDockSite = this.barTopDockSite; + this.previewManager.UseCustomCustomizeDialog = true; + this.previewManager.UseHook = true; + this.previewManager.BarClosing += new DevComponents.DotNetBar.DotNetBarManager.BarClosingEventHandler(this.OnBarClosing); + this.previewManager.BarUndock += new System.EventHandler(this.OnDefinitionChanged); + this.previewManager.BarTearOff += new System.EventHandler(this.OnDefinitionChanged); + this.previewManager.BarDock += new System.EventHandler(this.OnDefinitionChanged); + this.previewManager.AutoHideChanged += new System.EventHandler(this.OnDefinitionChanged); + this.previewManager.EnterCustomize += new System.EventHandler(this.previewManager_EnterCustomize); + // + // barBottomDockSite + // + this.barBottomDockSite.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; + this.barBottomDockSite.BackgroundImageAlpha = ((System.Byte)(255)); + this.barBottomDockSite.Dock = System.Windows.Forms.DockStyle.Bottom; + this.barBottomDockSite.Location = new System.Drawing.Point(0, 176); + this.barBottomDockSite.Name = "barBottomDockSite"; + this.barBottomDockSite.Size = new System.Drawing.Size(240, 0); + this.barBottomDockSite.TabIndex = 3; + this.barBottomDockSite.TabStop = false; + // + // barLeftDockSite + // + this.barLeftDockSite.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; + this.barLeftDockSite.BackgroundImageAlpha = ((System.Byte)(255)); + this.barLeftDockSite.Dock = System.Windows.Forms.DockStyle.Left; + this.barLeftDockSite.Location = new System.Drawing.Point(0, 0); + this.barLeftDockSite.Name = "barLeftDockSite"; + this.barLeftDockSite.Size = new System.Drawing.Size(0, 176); + this.barLeftDockSite.TabIndex = 0; + this.barLeftDockSite.TabStop = false; + // + // barRightDockSite + // + this.barRightDockSite.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; + this.barRightDockSite.BackgroundImageAlpha = ((System.Byte)(255)); + this.barRightDockSite.Dock = System.Windows.Forms.DockStyle.Right; + this.barRightDockSite.Location = new System.Drawing.Point(240, 0); + this.barRightDockSite.Name = "barRightDockSite"; + this.barRightDockSite.Size = new System.Drawing.Size(0, 176); + this.barRightDockSite.TabIndex = 1; + this.barRightDockSite.TabStop = false; + // + // barTopDockSite + // + this.barTopDockSite.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; + this.barTopDockSite.BackgroundImageAlpha = ((System.Byte)(255)); + this.barTopDockSite.Dock = System.Windows.Forms.DockStyle.Top; + this.barTopDockSite.Location = new System.Drawing.Point(0, 0); + this.barTopDockSite.Name = "barTopDockSite"; + this.barTopDockSite.Size = new System.Drawing.Size(240, 0); + this.barTopDockSite.TabIndex = 2; + this.barTopDockSite.TabStop = false; + // + // DefinitionPreviewControl + // + this.BackColor = System.Drawing.SystemColors.Control; + this.Controls.Add(this.barLeftDockSite); + this.Controls.Add(this.barRightDockSite); + this.Controls.Add(this.barTopDockSite); + this.Controls.Add(this.barBottomDockSite); + this.Name = "DefinitionPreviewControl"; + this.Size = new System.Drawing.Size(240, 176); + this.ResumeLayout(false); + + } + #endregion + + #region Event Handlers + private void DefinitionLoaded(object sender, EventArgs e) + { + foreach(Bar bar in previewManager.Bars) + { + bar.SizeChanged+=new EventHandler(this.BarSizeChanged); + bar.Disposed+=new EventHandler(this.BarDisposed); + } + } + private void BarDisposed(object sender, EventArgs e) + { + try + { + if(sender is Bar) + ((Bar)sender).SizeChanged-=new EventHandler(this.BarSizeChanged); + } + catch{} + } + private void BarSizeChanged(object sender, EventArgs e) + { + this.InvokeDataChanged(); + } + private void OnBarClosing(object sender, BarClosingEventArgs e) + { + InvokeDataChanged(); + } + private void OnDefinitionChanged(object sender, EventArgs e) + { + InvokeDataChanged(); + } + #endregion + + private void InvokeDataChanged() + { + if(DataChanged!=null) + DataChanged(this,new EventArgs()); + } + + private void previewManager_EnterCustomize(object sender, System.EventArgs e) + { + + } + } +} diff --git a/PROMS/DotNetBar Source Code/DefinitionPreviewControl.resx b/PROMS/DotNetBar Source Code/DefinitionPreviewControl.resx new file mode 100644 index 00000000..a33028a1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DefinitionPreviewControl.resx @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + Private + + + Assembly + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + False + + + True + + + True + + + 80 + + + (Default) + + + False + + + Private + + + DefinitionPreviewControl + + + 8, 8 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DesignTime.cs b/PROMS/DotNetBar Source Code/DesignTime.cs new file mode 100644 index 00000000..f3fa107c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DesignTime.cs @@ -0,0 +1,54 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Collections; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Statis functions for design-time support. + /// + internal class DesignTime + { + public static void DrawDesignTimeSelection(Graphics g, Rectangle r, Color c) + { + bool antiAlias=false; + if(g.SmoothingMode==System.Drawing.Drawing2D.SmoothingMode.AntiAlias) + { + antiAlias=true; + g.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.Default; + } + g.DrawRectangle(Pens.White, r); + using(Pen pen=new Pen(c,1)) + { + pen.DashStyle=DashStyle.Dot; + g.DrawRectangle(pen,r); + //r.Inflate(-1,-1); + //g.DrawRectangle(pen,r); + } + + if(antiAlias) + g.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + } + + public static void DrawDesignTimeSelection(Graphics g, GraphicsPath path, Color c) + { + bool antiAlias = false; + if (g.SmoothingMode == System.Drawing.Drawing2D.SmoothingMode.AntiAlias) + { + antiAlias = true; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + } + g.DrawPath(Pens.White, path); + using (Pen pen = new Pen(c, 1)) + { + pen.DashStyle = DashStyle.Dot; + g.DrawPath(pen, path); + } + + if (antiAlias) + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DesignTimeDte.cs b/PROMS/DotNetBar Source Code/DesignTimeDte.cs new file mode 100644 index 00000000..ce3de38d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DesignTimeDte.cs @@ -0,0 +1,427 @@ +using System; +using System.Reflection; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for DesignTimeDte. + /// + public class DesignTimeDte + { + public static string GetProjectPath(IServiceProvider service) + { + object dte=DesignTimeDte.GetDTE(service); + //EnvDTE.DTE dte=System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE") as EnvDTE.DTE; + if(dte!=null) + { + System.Array pjs=dte.GetType().InvokeMember("ActiveSolutionProjects",BindingFlags.GetProperty,null,dte, new object []{}) as System.Array; + if(pjs==null) + { + //MessageBox.Show("Failed to get ActiveSolutionProjects"); + return ""; + } + if(pjs.Length>0) + { + object project=pjs.GetValue(0); + //MessageBox.Show(((EnvDTE.Project)project).Properties.Item("FullPath").Value.ToString()); + object properties=project.GetType().InvokeMember("Properties",BindingFlags.GetProperty,null,project, new object []{}); + if(properties!=null) + { + object item=properties.GetType().InvokeMember("Item",BindingFlags.InvokeMethod,null,properties, new object []{"FullPath"}); + if(item!=null) + { + object val=item.GetType().InvokeMember("Value",BindingFlags.GetProperty,null,item, new object []{}); + if(val!=null && val is string) + return val.ToString(); + } + //else + // MessageBox.Show("Failed to get item"); + } + //else + // MessageBox.Show("Failed to get properties"); + } + //else + // MessageBox.Show("PJS length is ZERO"); + } + //else + // MessageBox.Show("Failed to get DTE"); + return ""; + } + + public static string GetDefinitionPath(string definitionName, IServiceProvider service) + { + // In design-time our document has to be open for definition to be loaded + //EnvDTE.DTE dte=GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()) as EnvDTE.DTE; + object dte=DesignTimeDte.GetDTE(service); //GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()); + if(dte==null) + return ""; + //EnvDTE.Document doc=dte.ActiveDocument; + object doc=dte.GetType().InvokeMember("ActiveDocument",BindingFlags.GetProperty,null,dte, new object []{}); + if(doc!=null) + { + //string docPath=doc.Path; + string docPath=(string)doc.GetType().InvokeMember("Path",BindingFlags.GetProperty,null,doc, new object []{}); + if(!docPath.EndsWith("\\")) + docPath+="\\"; + if(System.IO.File.Exists(docPath+definitionName)) + return docPath; + } + // Enumerate open documents and try to find our definition in thier path + object documents=dte.GetType().InvokeMember("Documents",BindingFlags.GetProperty,null,dte, new object []{}); + //foreach(EnvDTE.Document doc1 in dte.Documents) + int count=(int)documents.GetType().InvokeMember("Count",BindingFlags.GetProperty,null,documents, new object []{}); + for(int i=1;i<=count;i++) + { + object doc1=documents.GetType().InvokeMember("Item",BindingFlags.InvokeMethod,null,documents, new object []{i}); + //string docPath=doc1.Path; + string docPath=(string)doc1.GetType().InvokeMember("Path",BindingFlags.GetProperty,null,doc1, new object []{}); + if(!docPath.EndsWith("\\")) + docPath+="\\"; + if(System.IO.File.Exists(docPath+definitionName)) + return docPath; + } + // In need just return project path... + return GetProjectPath(service); + } + + public static string GetActiveDocumentPath(IServiceProvider service) + { + // In design-time our document has to be open for definition to be loaded + //EnvDTE.DTE dte=GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()) as EnvDTE.DTE; + //EnvDTE.Document doc=dte.ActiveDocument; + object dte=DesignTimeDte.GetDTE(service); //GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()); + if(dte==null) + return ""; + object doc=dte.GetType().InvokeMember("ActiveDocument",BindingFlags.GetProperty,null,dte, new object []{}); + if(doc!=null) + { + string docPath=(string)doc.GetType().InvokeMember("Path",BindingFlags.GetProperty,null,doc, new object []{}); //doc.Path; + if(!docPath.EndsWith("\\")) + docPath+="\\"; + return docPath; + } + // In need just return project path... + return GetProjectPath(service); + } + + public static bool AddFileToProject(string filename, IServiceProvider service) + { + bool ret=false; + object dte=DesignTimeDte.GetDTE(service); //GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()); + if(dte!=null) + { +// System.Array pjs=dte.GetType().InvokeMember("ActiveSolutionProjects",BindingFlags.GetProperty,null,dte, new object []{}) as System.Array; +// if(pjs==null) +// return false; +// +// if(pjs.Length>0) +// { +// object project=pjs.GetValue(0); +// } + object itemOperations=dte.GetType().InvokeMember("ItemOperations",BindingFlags.GetProperty,null,dte, new object []{}); + if(itemOperations!=null) + { + object projectItem=itemOperations.GetType().InvokeMember("AddExistingItem",BindingFlags.InvokeMethod,null,itemOperations, new object []{filename}); + if(projectItem!=null) + { + try + { + object props=projectItem.GetType().InvokeMember("Properties",BindingFlags.GetProperty,null,projectItem, new object []{}); + if(props!=null) + { + object item=props.GetType().InvokeMember("Item",BindingFlags.InvokeMethod,null,props, new object []{"BuildAction"}); + if(item!=null) + { + item.GetType().InvokeMember("Value",BindingFlags.SetProperty,null,item, new object []{3}); + ret=true; + } + } + } + catch + { + ret=true; + } + } + } + //EnvDTE.ProjectItem item=dte.ItemOperations.AddExistingItem(filename); + //item.Properties.Item("BuildAction").Value=3; +// foreach(EnvDTE.Property prop in item.Properties) +// { +// MessageBox.Show(prop.Name+" "+prop.Value); +// } + } + return ret; + } + + //public static bool DeleteFromProject(string filename, IServiceProvider service) + //{ + // try + // { + // object dte=DesignTimeDte.GetDTE(service); //GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()); + // if(dte==null) + // return false; + + // System.Array pjs=dte.GetType().InvokeMember("ActiveSolutionProjects",BindingFlags.GetProperty,null,dte, new object []{}) as System.Array; + // if(pjs==null) + // return false; + + // object project=null; + // if(pjs.Length>0) + // project=pjs.GetValue(0); + // if(project==null) + // return false; + + // object pjItems=project.GetType().InvokeMember("ProjectItems",BindingFlags.GetProperty,null,project, new object []{}); + // if(pjItems==null) + // return false; + + // object pjItem=pjItems.GetType().InvokeMember("Item",BindingFlags.InvokeMethod,null,pjItems, new object []{filename}); + // //project.ProjectItems.Item(filename) as EnvDTE.ProjectItem; + // if(pjItem==null) + // return false; + + // pjItem.GetType().InvokeMember("Delete",BindingFlags.InvokeMethod,null,pjItem, new object []{}); + // return true; + // } + // catch(Exception){} + // return false; + //} + + public static bool ExistInProject(string filename, IServiceProvider service) + { +// EnvDTE.DTE dte=GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()) as EnvDTE.DTE; +// if(dte==null) +// return false; +// Array projects=dte.ActiveSolutionProjects as Array; + object dte=DesignTimeDte.GetDTE(service); //GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()); + if(dte==null) + return false; + + System.Array projects=dte.GetType().InvokeMember("ActiveSolutionProjects",BindingFlags.GetProperty,null,dte, new object []{}) as System.Array; + if(projects==null) + return false; + foreach(object pj in projects) + { + object pji=pj.GetType().InvokeMember("ProjectItems",BindingFlags.GetProperty,null,pj, new object []{}); + int count=(int)pji.GetType().InvokeMember("Count",BindingFlags.GetProperty,null,pji, new object []{}); + //foreach(EnvDTE.ProjectItem pi in pj.ProjectItems) + for(int i=1;i<=count;i++) + { + object pi=pji.GetType().InvokeMember("Item",BindingFlags.InvokeMethod,null,pji, new object []{i}); + if(CheckProjectItem(pi,filename)) + return true; + } + } + return false; + } + + private static bool CheckProjectItem(object pi,string filename) + { + try + { + string name=(string)pi.GetType().InvokeMember("Name",BindingFlags.GetProperty,null,pi, new object []{}); + if(name.ToLower()==filename.ToLower()) + return true; + short fileCount=(short)pi.GetType().InvokeMember("FileCount",BindingFlags.GetProperty,null,pi, new object []{}); + for(short i=0;i0) + project=pjs.GetValue(0); + if(project==null) + return false; + + object pjItems=project.GetType().InvokeMember("ProjectItems",BindingFlags.GetProperty,null,project, new object []{}); + if(pjItems==null) + return false; + + object pjItem=pjItems.GetType().InvokeMember("Item",BindingFlags.InvokeMethod,null,pjItems, new object []{filename}); + if(pjItem==null) + return false; + } + catch(Exception) + { + return false; + } + + return true; + } + + public static bool CheckOutFile(string filename, IServiceProvider service) + { + try + { + object dte=DesignTimeDte.GetDTE(service); //GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()); + if(dte==null) + return false; + object sctrl=dte.GetType().InvokeMember("SourceControl",BindingFlags.GetProperty,null,dte, new object []{}); + if(sctrl==null) + { + return false; + } + object res=sctrl.GetType().InvokeMember("IsItemUnderSCC",BindingFlags.InvokeMethod,null,sctrl, new object []{filename}); + if(res!=null && res is bool && (bool)res==true) + { + res=sctrl.GetType().InvokeMember("CheckOutItem",BindingFlags.InvokeMethod,null,sctrl, new object []{filename}); + if(res!=null && res is bool) + return (bool)res; + else + return false; + } + return true; + } + catch(Exception){} + return false; + } + + public static object GetDTE(IServiceProvider service) + { + object dte=GetMSDEVFromGIT("VisualStudio.DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()); + if(dte==null) + dte=GetMSDEVFromGIT(".DTE",System.Diagnostics.Process.GetCurrentProcess().Id.ToString()); + if(dte==null && service!=null) + { + Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (Assembly a in loadedAssemblies) + { + if (a.FullName.ToLower().StartsWith("envdte")) + { + Type t=a.GetType("EnvDTE._DTE", false, true); + if (t != null) + { + dte=service.GetService(t); + break; + } + } + } + } + return dte; + } + +#if FRAMEWORK20 + [DllImport("ole32.dll")] + public static extern int GetRunningObjectTable(int reserved, out + System.Runtime.InteropServices.ComTypes.IRunningObjectTable prot); + [DllImport("ole32.dll")] + public static extern int CreateBindCtx(int reserved, out System.Runtime.InteropServices.ComTypes.IBindCtx + ppbc); + + [STAThread] + public static object GetMSDEVFromGIT(string strProgID, string processId) + { + System.Runtime.InteropServices.ComTypes.IRunningObjectTable prot; + System.Runtime.InteropServices.ComTypes.IEnumMoniker pMonkEnum; + try + { + GetRunningObjectTable(0, out prot); + prot.EnumRunning(out pMonkEnum); + pMonkEnum.Reset(); // Churn through enumeration. + IntPtr fetched=IntPtr.Zero; + System.Runtime.InteropServices.ComTypes.IMoniker[] pmon = new System.Runtime.InteropServices.ComTypes.IMoniker[1]; + while (pMonkEnum.Next(1, pmon, fetched) == 0) + { + System.Runtime.InteropServices.ComTypes.IBindCtx pCtx; + CreateBindCtx(0, out pCtx); + string str; + pmon[0].GetDisplayName(pCtx, null, out str); + // #if DEBUG + // System.Windows.Forms.MessageBox.Show(str+" strProgId="+strProgID+" processId="+processId); + // #endif + if (str.IndexOf(strProgID) > 0 && (str.IndexOf(":" + processId) > 0 || processId == "")) + { + object objReturnObject; + prot.GetObject(pmon[0], out objReturnObject); + object ide = (object)objReturnObject; + return ide; + } + } + } + catch + { + return null; + } + return null; + } +#else + [DllImport("ole32.dll")] + public static extern int GetRunningObjectTable(int reserved, out + UCOMIRunningObjectTable prot); + [DllImport("ole32.dll")] + public static extern int CreateBindCtx(int reserved, out UCOMIBindCtx + ppbc); + + [STAThread] + public static object GetMSDEVFromGIT(string strProgID, string processId) + { + UCOMIRunningObjectTable prot; + UCOMIEnumMoniker pMonkEnum; + try + { + GetRunningObjectTable(0,out prot); + prot.EnumRunning(out pMonkEnum); + pMonkEnum.Reset(); // Churn through enumeration. + int fetched; + UCOMIMoniker []pmon = new UCOMIMoniker[1]; + while(pMonkEnum.Next(1, pmon, out fetched) == 0) + { + UCOMIBindCtx pCtx; + CreateBindCtx(0, out pCtx); + string str; + pmon[0].GetDisplayName(pCtx,null,out str); +// #if DEBUG +// System.Windows.Forms.MessageBox.Show(str+" strProgId="+strProgID+" processId="+processId); +// #endif + if(str.IndexOf(strProgID)>0 && (str.IndexOf(":"+processId)>0 || processId=="")) + { + object objReturnObject; + prot.GetObject(pmon[0],out objReturnObject); + object ide = (object)objReturnObject; + return ide; + } + } + } + catch + { + return null; + } + return null; + } +#endif + + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevCoLicenseProvider.cs b/PROMS/DotNetBar Source Code/DevCoLicenseProvider.cs new file mode 100644 index 00000000..95fe6534 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevCoLicenseProvider.cs @@ -0,0 +1,221 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Security.Cryptography; +using System.Windows.Forms; +namespace DevComponents.DotNetBar +{ + [System.ComponentModel.ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false)] + public class DevCoLicenseProvider:LicenseProvider + { + const string DOTNETBAR="dotnetbar"; + public DevCoLicenseProvider() + { + } + public override License GetLicense(LicenseContext context,Type type,object instance,bool allowExceptions) + { + DevCoLicense lic = null; + Debug.Assert(context!=null, "No context provided!"); + #if !TRIAL + //if no context is provided, do nothing + if (context != null) + { + //if this control is in runtime mode + if (context.UsageMode == LicenseUsageMode.Runtime) + { + //retreive the stored license key + string key = context.GetSavedLicenseKey(type, null); + //check if the stored license key is null + // and call IsKeyValid to make sure its valid + if (key != null && IsKeyValid2(key, type)) + { + //if the key is valid create a new license + lic = new DevCoLicense(key); + } + else + { + try + { + System.Reflection.Assembly[] assemblies=System.AppDomain.CurrentDomain.GetAssemblies(); + foreach(System.Reflection.Assembly a in assemblies) + { + string codeBase = a.CodeBase; + codeBase = codeBase.Substring(codeBase.LastIndexOf("/") + 1)+".licenses"; + System.IO.Stream stream=this.GetManifestResourceStream(a,codeBase); + if(stream==null) + codeBase=codeBase.Replace(".DLL.",".dll."); + stream=this.GetManifestResourceStream(a,codeBase); + if(stream!=null) + { + key=DeserializeLicenseKey(stream); + if (key != null && key!="") //IsKeyValid2(key, type)) + { + lic = new DevCoLicense(key); + break; + } + } + } + } + catch + { + lic=new DevCoLicense(""); + } + } + } + else + { + string sKey=""; + Microsoft.Win32.RegistryKey regkey=Microsoft.Win32.Registry.LocalMachine; + regkey=regkey.OpenSubKey("Software\\DevComponents\\Licenses",false); + if(regkey!=null) + { + sKey=regkey.GetValue("DevComponents.DotNetBar.DotNetBarManager2").ToString(); + } + //check if the key is valid + if (IsKeyValid(sKey, type)) + { + //valid key so create a new License + lic = new DevCoLicense(Key(type)); + } + + //if we managed to create a license, stuff it into the context + if (lic != null) + { + context.SetSavedLicenseKey(type, lic.LicenseKey); + } + } + } + #else + if (context != null) + { + lic=new DevCoLicense(""); + //if this control is in runtime mode + if (context.UsageMode == LicenseUsageMode.Runtime) + { + RemindForm frm=new RemindForm(); + frm.ShowDialog(); + } + else + { + context.SetSavedLicenseKey(type, lic.LicenseKey); + } + } + #endif + + if(lic==null && context!=null) + { + RemindForm frm=new RemindForm(); + frm.ShowDialog(); + lic=new DevCoLicense(""); + } + return lic; + + } + + private System.IO.Stream GetManifestResourceStream(System.Reflection.Assembly a, string resourceName) + { + resourceName=resourceName.ToLower(); + string[] resources=a.GetManifestResourceNames(); + foreach(string name in resources) + { + if(name.ToLower()==resourceName) + { + return a.GetManifestResourceStream(name); + //break; + } + } + return null; + } + + private string DeserializeLicenseKey(System.IO.Stream o) + { + System.Runtime.Serialization.IFormatter formatter1; + object obj1=null; + object[] array1; + formatter1 = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); + try + { + obj1 = formatter1.Deserialize(o); + + if((obj1 as object[]) == null) + return null; + array1 = ((object[]) obj1); + if((array1[0] as string) == null) + return null; + + System.Collections.Hashtable h=((System.Collections.Hashtable)array1[1]); + + //Type t=typeof(DotNetBarManager); + string s=DOTNETBAR; + foreach(System.Collections.DictionaryEntry entry in h) + { + string key=entry.Key.ToString().ToLower(); + if(key.IndexOf(s)>=0) + return entry.Value as string; + } + } + catch{} + return null; + } + + #if !TRIAL + private bool IsKeyValid2(string key, Type type) + { + if(key==null || key=="") + return false; + + return (Key(type)==key); + } + + internal static string Key(Type type) + { + Byte[] bi=(new System.Text.UnicodeEncoding()).GetBytes(type.ToString()); + byte[] res; + SHA256 shaM = new SHA256Managed(); + res = shaM.ComputeHash(bi); + 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(res,0,(int)res.Length); + xt.Close(); + return sb.ToString(); + } + + private bool IsKeyValid(string key, Type type) + { + if(key==null || key=="") + return false; +// Byte[] bi=(new System.Text.UnicodeEncoding()).GetBytes(type.ToString()+System.Windows.Forms.SystemInformation.ComputerName); +// byte[] res; +// SHA256 shaM = new SHA256Managed(); +// res = shaM.ComputeHash(bi); +// +// 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(res,0,(int)res.Length); +// xt.Close(); + return ("F962CEC7-CD8F-4911-A9E9-CAB39962FC1F"==key); + } + #endif + } + internal class DevCoLicense:License + { + private string key; + public DevCoLicense(string key) + { + this.key = key; + } + public override string LicenseKey + { + get + { + return key; + } + } + public override void Dispose() + { + } + } + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/App.config b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/App.config new file mode 100644 index 00000000..343984d0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/AxisListTypeEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/AxisListTypeEditor.cs new file mode 100644 index 00000000..71bb10a7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/AxisListTypeEditor.cs @@ -0,0 +1,116 @@ +using System; +using System.ComponentModel; +using System.Drawing.Design; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class AxisListTypeEditor : UITypeEditor + { + #region Private variables + + IWindowsFormsEditorService _EditorService; + + #endregion + + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return (UITypeEditorEditStyle.DropDown); + } + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (false); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _EditorService = + provider.GetService(typeof (IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (_EditorService != null) + { + ChartSeries series = context.Instance as ChartSeries; + + if (series != null) + { + ChartXy chartXy = series.Parent as ChartXy; + + if (chartXy != null) + { + ListBox lb = new ListBox(); + lb.Dock = DockStyle.Fill; + lb.BorderStyle = BorderStyle.None; + + lb.MouseClick += ListBoxMouseClick; + + lb.Items.Add("NotSet"); + + if (context.PropertyDescriptor.Name.Equals("AxisX") == true) + return (EditValueEx(lb, chartXy.AncillaryAxesX, value)); + + return (EditValueEx(lb, chartXy.AncillaryAxesY, value)); + } + } + } + + return (base.EditValue(context, provider, value)); + } + + private object EditValueEx(ListBox lb, ChartAxesCollection axes, object value) + { + for (int i = 0; i < axes.Count; i++) + { + ChartAxis axis = axes[i]; + + string s = GetAxisText(axis, i); + + lb.Items.Add(s); + } + + _EditorService.DropDownControl(lb); + + if (lb.SelectedIndex >= 0) + { + if (lb.SelectedIndex == 0) + return (null); + + ChartAxis axis = axes[lb.SelectedIndex - 1]; + + return (axis); + } + + return (value); + } + + private string GetAxisText(ChartAxis axis, int index) + { + string s = index + " "; + + if (string.IsNullOrEmpty(axis.Name) == false) + return (s + "-" + axis.Name); + + return (s + "-" + "(No Name)"); + } + + private void ListBoxMouseClick(object sender, MouseEventArgs e) + { + _EditorService.CloseDropDown(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/AxisReferenceCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/AxisReferenceCollectionEditor.cs new file mode 100644 index 00000000..990a07c7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/AxisReferenceCollectionEditor.cs @@ -0,0 +1,111 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class AxisReferenceCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private ChartAxis _ChartAxis; + + #endregion + + public AxisReferenceCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _ChartAxis = context.Instance as ChartAxis; + + IComponentChangeService cs = BeforeEditValue(context); + + object retval = value; + + try + { + retval = base.EditValue(context, provider, value); + } + finally + { + AfterEditValue(context, cs); + } + + return (retval); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + if (itemType == typeof(ReferenceLine)) + { + ReferenceLine line = (ReferenceLine)base.CreateInstance(itemType); + + line.Name = _ChartAxis.ReferenceLines.GetUniqueName(); + + if (_ChartAxis != null) + line.AxisValue = _ChartAxis.ActualMinValue; + + return (line); + } + + return (base.CreateInstance(itemType)); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + ReferenceLine item = ChartItem as ReferenceLine; + + if (item != null) + { + if (AddButton != null) + { + ChartControlDesigner ccd = GetDesigner(_ChartAxis.ChartControl); + + ccd.InCopyItem = true; + + try + { + AddButton.PerformClick(); + + ReferenceLineCollection rlc = _ChartAxis.ReferenceLines; + ReferenceLine clone = rlc[rlc.Count - 1]; + + string name = clone.Name; + item.CopyTo(clone); + clone.Name = name; + } + finally + { + ccd.InCopyItem = false; + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(ReferenceLine); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/AxisStripeCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/AxisStripeCollectionEditor.cs new file mode 100644 index 00000000..899c982b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/AxisStripeCollectionEditor.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.ComponentModel.Design.Serialization; +using System.Globalization; +using System.Reflection; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class AxisStripeCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private ChartAxis _ChartAxis; + + #endregion + + public AxisStripeCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _ChartAxis = context.Instance as ChartAxis; + + IComponentChangeService cs = BeforeEditValue(context); + + object retval = value; + + try + { + retval = base.EditValue(context, provider, value); + } + finally + { + AfterEditValue(context, cs); + } + + return (retval); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + if (itemType == typeof(AxisStripe)) + { + AxisStripe stripe = (AxisStripe)base.CreateInstance(itemType); + + stripe.Name = _ChartAxis.AxisStripes.GetUniqueName(); + + stripe.MinValue = _ChartAxis.ActualMinValue; + stripe.MaxValue = _ChartAxis.ActualMaxValue; + + return (stripe); + } + + return (base.CreateInstance(itemType)); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + AxisStripe item = ChartItem as AxisStripe; + + if (item != null) + { + if (AddButton != null) + { + ChartControlDesigner ccd = GetDesigner(_ChartAxis.ChartControl); + + ccd.InCopyItem = true; + + try + { + AddButton.PerformClick(); + + AxisStripeCollection asc = _ChartAxis.AxisStripes; + AxisStripe clone = asc[asc.Count - 1]; + + string name = clone.Name; + item.CopyTo(clone); + clone.Name = name; + } + finally + { + ccd.InCopyItem = false; + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(AxisStripe); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/BaseCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/BaseCollectionEditor.cs new file mode 100644 index 00000000..d682a261 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/BaseCollectionEditor.cs @@ -0,0 +1,383 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Reflection; +using System.Resources; +using System.Windows.Forms; +using DevComponents.Charts.Design.Properties; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class BaseCollectionEditor : CollectionEditor + { + #region Static variables + + static Size _lastSize = Size.Empty; + static Point _lastLoc = Point.Empty; + + #endregion + + #region Private variables + + private ListBox _ListBox; + private object _ChartItem; + private object _LastChartItem; + private PropertyGrid _PropertyGrid; + + private Button _AddButton; + private Button _RemButton; + private Button _CopyButton; + private ToolTip _ToolTip; + + private List _RemovedItems; + + private bool _EditCancelled; + private bool _ComponentChanged; + + #endregion + + private ChartControlDesigner _ControlDesigner; + + public BaseCollectionEditor(Type type) + : base(type) + { + } + + #region Protected properties + + protected Button AddButton + { + get { return (_AddButton); } + } + + protected object ChartItem + { + get { return (_ChartItem); } + set { _ChartItem = value; } + } + + protected bool ComponentChanged + { + get { return (_ComponentChanged); } + } + + protected bool EditCancelled + { + get { return (_EditCancelled); } + } + + protected ListBox ListBox + { + get { return (_ListBox); } + } + + #endregion + + #region Private properties + + #region RemovedItems + + private List RemovedItems + { + get + { + if (_RemovedItems == null) + _RemovedItems = new List(); + + return (_RemovedItems); + } + } + + #endregion + + #endregion + + #region CreateCollectionForm + + protected override CollectionForm CreateCollectionForm() + { + _EditCancelled = false; + + CollectionForm collectionForm = base.CreateCollectionForm(); + + _ChartItem = null; + + if (collectionForm.Controls[0] is TableLayoutPanel) + { + TableLayoutPanel tlpf = collectionForm.Controls["overArchingTableLayoutPanel"] as TableLayoutPanel; + + if (tlpf != null) + { + TableLayoutPanel tlp2 = tlpf.Controls["addRemoveTableLayoutPanel"] as TableLayoutPanel; + + if (tlp2 != null) + { + _RemButton = tlp2.Controls["removeButton"] as Button; + + if (_RemButton != null) + _RemButton.Click += CollectionEditor_RemoveClick; + + _AddButton = tlp2.Controls["addButton"] as Button; + + if (_AddButton != null) + { + _AddButton.Click += CollectionEditor_AddClick; + + AddCopyButton(collectionForm); + } + } + + _ListBox = tlpf.Controls["listbox"] as ListBox; + + if (_ListBox != null) + _ListBox.SelectedIndexChanged += ListBox_SelectedIndexChanged; + + _PropertyGrid = tlpf.Controls["propertyBrowser"] as PropertyGrid; + + if (_PropertyGrid != null) + _PropertyGrid.HelpVisible = true; + } + } + + collectionForm.Load += CollectionFormLoad; + collectionForm.Resize += CollectionFormResize; + collectionForm.LocationChanged += CollectionFormLocationChanged; + + return (collectionForm); + } + + #region CollectionFormLoad + + void CollectionFormLoad(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null) + { + if (_lastSize != Size.Empty) + form.Size = _lastSize; + + if (_lastLoc != Point.Empty) + form.Location = _lastLoc; + } + } + + #endregion + + #region CollectionFormResize + + void CollectionFormResize(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastSize = form.Size; + } + + #endregion + + #region CollectionFormLocationChanged + + void CollectionFormLocationChanged(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastLoc = form.Location; + } + + #endregion + + #endregion + + #region AddCopyButton + + private void AddCopyButton(CollectionForm collectionForm) + { + _CopyButton = new Button(); + + _CopyButton.Size = new Size(24, 24); + _CopyButton.Enabled = false; + _CopyButton.Click += CopyButton_Click; + + ResourceManager rm = Resources.ResourceManager; + _CopyButton.Image = (Image)rm.GetObject("Copy"); + + collectionForm.Controls.Add(_CopyButton); + + _CopyButton.Location = new Point(204, 85); + _CopyButton.BringToFront(); + + _ToolTip = new ToolTip(); + _ToolTip.SetToolTip(_CopyButton, "Clone the selected item"); + } + + #endregion + + #region CopyButton_Click + + protected virtual void CopyButton_Click(object sender, EventArgs e) + { + } + + #endregion + + #region ListBox_SelectedIndexChanged + + void ListBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (_ListBox.SelectedItem != null) + { + PropertyInfo p = _ListBox.SelectedItem.GetType().GetProperty("Value"); + + _LastChartItem = _ChartItem; + _ChartItem = p.GetValue(_ListBox.SelectedItem, null); + + _CopyButton.Enabled = true; + } + else + { + _CopyButton.Enabled = false; + } + } + + #endregion + + #region CollectionEditor_AddClick + + protected virtual void CollectionEditor_AddClick(object sender, EventArgs e) + { + } + + #endregion + + #region CollectionEditor_RemoveClick + + protected virtual void CollectionEditor_RemoveClick(object sender, EventArgs e) + { + if (_LastChartItem != null) + { + RemovedItems.Add(_LastChartItem); + + if (_LastChartItem is ChartVisualElement) + ((ChartVisualElement)_LastChartItem).Visible = false; + + else if (_LastChartItem is SeriesPoint) + ((SeriesPoint)_LastChartItem).Visible = false; + + _LastChartItem = null; + } + else if (_ChartItem != null) + { + RemovedItems.Add(_ChartItem); + + if (_ChartItem is ChartVisualElement) + ((ChartVisualElement)_ChartItem).Visible = false; + + else if (_LastChartItem is SeriesPoint) + ((SeriesPoint)_LastChartItem).Visible = false; + + _ChartItem = null; + } + } + + #endregion + + #region CancelChanges + + protected override void CancelChanges() + { + _EditCancelled = true; + + if (_RemovedItems != null) + { + foreach (object item in _RemovedItems) + { + if (item is ChartVisualElement) + ((ChartVisualElement)item).Visible = true; + + else if (item is SeriesPoint) + ((SeriesPoint)item).Visible = true; + } + } + + ChartVisualElement cve = _ChartItem as ChartVisualElement; + + if (cve != null) + cve.InvalidateLayout(); + + base.CancelChanges(); + } + + #endregion + + #region BeforeEditValue + + protected IComponentChangeService BeforeEditValue(ITypeDescriptorContext context) + { + ChartVisualElement cve = context.Instance as ChartVisualElement; + + if (cve != null) + { + ISite site = cve.ChartControl.Site; + IComponentChangeService cs = (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); + + if (cs != null) + cs.ComponentChanged += cs_ComponentChanged; + + return (cs); + } + + return (null); + } + + void cs_ComponentChanged(object sender, ComponentChangedEventArgs e) + { + _ComponentChanged = true; + } + + #endregion + + #region AfterEditValue + + protected void AfterEditValue(ITypeDescriptorContext context, IComponentChangeService cs) + { + if (cs != null) + cs.ComponentChanged -= cs_ComponentChanged; + + if (_ComponentChanged == true) + { + ChartContainer chCont = ((ChartVisualElement)context.Instance).ParentChartContainer; + + if (chCont != null) + { + PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(chCont); + PropertyDescriptor pd = pdc["Name"]; + + cs.OnComponentChanged(chCont, pd, null, null); + } + } + } + + #endregion + + #region GetDesigner + + internal ChartControlDesigner GetDesigner(IComponent component) + { + if (_ControlDesigner == null) + { + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + + _ControlDesigner = dh.GetDesigner(component) as ChartControlDesigner; + } + + return (_ControlDesigner); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartAxesCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartAxesCollectionEditor.cs new file mode 100644 index 00000000..bc5feeb6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartAxesCollectionEditor.cs @@ -0,0 +1,94 @@ +using System; +using System.ComponentModel; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class ChartAxesCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private ChartXy _ChartXy; + private Type _CollectionType; + + #endregion + + public ChartAxesCollectionEditor(Type type) + : base(type) + { + _CollectionType = type; + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _ChartXy = context.Instance as ChartXy; + + return (base.EditValue(context, provider, value)); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + ChartAxis axis = (ChartAxis)base.CreateInstance(itemType); + + axis.Name = (_CollectionType == typeof(ChartAxesXCollection)) + ? _ChartXy.AncillaryAxesX.GetUniqueName() : _ChartXy.AncillaryAxesY.GetUniqueName(); + + return (axis); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + ChartAxis item = ChartItem as ChartAxis; + + if (item != null) + { + if (AddButton != null) + { + AddButton.PerformClick(); + + if (_CollectionType == typeof(ChartAxesXCollection)) + { + ChartAxesXCollection cac = _ChartXy.AncillaryAxesX; + ChartAxis clone = cac[cac.Count - 1]; + + string name = clone.Name; + item.CopyTo(clone); + clone.Name = name; + } + else + { + ChartAxesYCollection cac = _ChartXy.AncillaryAxesY; + ChartAxis clone = cac[cac.Count - 1]; + + item.CopyTo(clone); + + clone.Name = cac.GetUniqueName(); + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return (_CollectionType == typeof(ChartAxesXCollection) + ? typeof(ChartAxisX) : typeof(ChartAxisY)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartContainerCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartContainerCollectionEditor.cs new file mode 100644 index 00000000..e85d8e43 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartContainerCollectionEditor.cs @@ -0,0 +1,174 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Design; +using System.Reflection; +using DevComponents.DotNetBar.Charts; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.Charts.Design +{ + public class ChartContainerCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private ChartPanel _ChartPanel; + + #endregion + + public ChartContainerCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _ChartPanel = context.Instance as ChartPanel; + + object retval = base.EditValue(context, provider, value); + + return (retval); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + if (itemType == typeof(ChartXy)) + { + ChartXy chartXy = (ChartXy)base.CreateInstance(itemType); + + if (_ChartPanel != null) + chartXy.Name = _ChartPanel.ChartContainers.GetUniqueName("ChartXy"); + + SetChartDefaults(chartXy); + + return (chartXy); + } + + if (itemType == typeof(PieChart)) + { + PieChart pieChart = (PieChart)base.CreateInstance(itemType); + + if (_ChartPanel != null) + pieChart.Name = _ChartPanel.ChartContainers.GetUniqueName("PieChart"); + + SetChartDefaults(pieChart); + + return (pieChart); + } + + if (itemType == typeof(ChartPanel)) + { + ChartPanel panel = (ChartPanel)base.CreateInstance(itemType); + + if (_ChartPanel != null) + panel.Name = _ChartPanel.ChartContainers.GetUniqueName("ChartPanel"); + + SetPanelDefaults(panel); + + return (panel); + } + + return (base.CreateInstance(itemType)); + } + + private void SetPanelDefaults(ChartPanel panel) + { + panel.ContainerVisualStyles.Default.BorderThickness = new Thickness(1); + panel.ContainerVisualStyles.Default.BorderColor = new BorderColor(Color.Black); + panel.ContainerVisualStyles.Default.Background = new Background(Color.Gray); + panel.ContainerVisualStyles.Default.Margin = new Padding(4); + } + + private void SetChartDefaults(ChartXy chartXy) + { + chartXy.ContainerVisualStyles.Default.BorderThickness = new Thickness(1); + chartXy.ContainerVisualStyles.Default.BorderColor = new BorderColor(Color.Black); + chartXy.ContainerVisualStyles.Default.Background = new Background(Color.White); + chartXy.ContainerVisualStyles.Default.Margin = new Padding(4); + } + + private void SetChartDefaults(PieChart pieChart) + { + pieChart.ContainerVisualStyles.Default.BorderThickness = new Thickness(1); + pieChart.ContainerVisualStyles.Default.BorderColor = new BorderColor(Color.Black); + pieChart.ContainerVisualStyles.Default.Background = new Background(Color.White); + pieChart.ContainerVisualStyles.Default.Margin = new Padding(4); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + ChartContainer item = ChartItem as ChartContainer; + + if (item != null) + { + if (AddButton != null) + { + ChartControlDesigner ccd = GetDesigner(_ChartPanel.ChartControl); + ChartContainerCollection ccc = _ChartPanel.ChartContainers; + + ccd.InCopyItem = true; + + if (item is ChartPanel) + _ItemTypes[0] = typeof(ChartPanel); + + try + { + AddButton.PerformClick(); + + ChartContainer clone = ccc[ccc.Count - 1]; + + string name = clone.Name; + item.CopyTo(clone); + clone.Name = name; + } + finally + { + if (item is ChartPanel) + _ItemTypes[0] = typeof(ChartXy); + + ccd.InCopyItem = false; + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(ChartContainer); + } + + #endregion + + #region CreateNewItemTypes + + private Type[] _ItemTypes = new Type[] + { + typeof(ChartXy), + typeof(PieChart), + typeof(ChartPanel), + }; + + protected override Type[] CreateNewItemTypes() + { + return (_ItemTypes); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartControlActionList.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartControlActionList.cs new file mode 100644 index 00000000..acbcc259 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartControlActionList.cs @@ -0,0 +1,192 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class ChartControlActionList : DesignerActionList, + ITypeDescriptorContext, IWindowsFormsEditorService, IServiceProvider + { + #region Private variables + + private ChartControl _ChartControl; + private PropertyDescriptor _PropertyDescriptor; + private IComponentChangeService _ChangeService; + + #endregion + + /// + /// ChartControlActionList + /// + /// Associated ChartControl + public ChartControlActionList(ChartControl chartControl) + : base(chartControl) + { + _ChartControl = chartControl; + + _ChangeService = Component.Site.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + } + + #region Public properties + + /// + /// Gets or sets the GridPanel DataSource + /// + [AttributeProvider(typeof(IListSource))] + public object DataSource + { + get { return (_ChartControl.DataSource); } + set { SetValue("DataSource", value); } + } + + /// + /// Gets or sets the GridPanel DataMember + /// + public string DataMember + { + get { return (_ChartControl.DataMember); } + set { SetValue("DataMember", value); } + } + + #endregion + + #region GetSortedActionItems + + public override DesignerActionItemCollection GetSortedActionItems() + { + DesignerActionItemCollection items = new DesignerActionItemCollection(); + + items.Add(new DesignerActionHeaderItem("Data")); + + items.Add(new DesignerActionPropertyItem("DataSource", + "DataSource", "Data", + "Sets the default Chart DataSource.")); + + items.Add(new DesignerActionPropertyItem("DataMember", + "DataMember", "Data", + "Sets the default Chart DataMamber.")); + return items; + } + + #endregion + + #region SetValue + + private void SetValue(string property, object value) + { + _ChangeService.OnComponentChanging(_ChartControl, null); + + GetPropertyByName(property).SetValue(_ChartControl, value); + + _ChangeService.OnComponentChanged(_ChartControl, null, null, null); + } + + #endregion + + #region GetPropertyByName + + /// + /// Gets the property via the given name + /// + /// Property name + /// PropertyDescriptor + private PropertyDescriptor GetPropertyByName(string propName) + { + PropertyDescriptor prop = + TypeDescriptor.GetProperties(_ChartControl)[propName]; + + if (prop == null) + throw new ArgumentException("Matching property not found.", propName); + + return (prop); + } + + #endregion + + #region EditChartContainers + + /// + /// EditChartContainers + /// + private void EditChartContainers() + { + _PropertyDescriptor = TypeDescriptor.GetProperties(_ChartControl.ChartPanel)["ChartContainers"]; + + UITypeEditor editor = (UITypeEditor)_PropertyDescriptor.GetEditor(typeof(UITypeEditor)); + + if (editor != null) + editor.EditValue(this, this, _ChartControl.ChartPanel.ChartContainers); + } + + #endregion + + #region ITypeDescriptorContext Members + + public IContainer Container + { + get { return (Component.Site.Container); } + } + + public object Instance + { + get { return (Component); } + } + + public void OnComponentChanged() + { + object value = _ChartControl.ChartPanel.ChartContainers; + + _ChangeService.OnComponentChanged(Component, _PropertyDescriptor, value, value); + } + + public bool OnComponentChanging() + { + _ChangeService.OnComponentChanging(Component, _PropertyDescriptor); + + return true; + } + + public PropertyDescriptor PropertyDescriptor + { + get { return (_PropertyDescriptor); } + } + + #endregion + + #region IWindowsFormsEditorService Members + + public void CloseDropDown() + { + throw new Exception("The method or operation is not implemented."); + } + + public void DropDownControl(Control control) + { + throw new Exception("The method or operation is not implemented."); + } + + public DialogResult ShowDialog(Form dialog) + { + return (dialog.ShowDialog()); + } + + #endregion + + #region IServiceProvider + + object IServiceProvider.GetService(Type serviceType) + { + if (serviceType.Equals(typeof(IWindowsFormsEditorService))) + return (this); + + return GetService(serviceType); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartControlDesignTime.snk b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartControlDesignTime.snk new file mode 100644 index 00000000..33a02ddf Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartControlDesignTime.snk differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartControlDesigner.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartControlDesigner.cs new file mode 100644 index 00000000..954abebe --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartControlDesigner.cs @@ -0,0 +1,2612 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using System.Windows.Forms.Design.Behavior; +using DevComponents.DotNetBar; +using DevComponents.DotNetBar.Charts; +using DevComponents.DotNetBar.Charts.Style; +using Microsoft.Win32; + +namespace DevComponents.Charts.Design +{ + /// + /// ChartControlDesigner + /// + public class ChartControlDesigner : ControlDesigner + { + static Random _Rand = new Random(); + + #region Private variables + + private ChartControl _ChartControl; + + private IDesignerHost _DesignerHost; + private DesignerActionListCollection _ActionLists; + private DesignerActionUIService _ActionUIService; + + private IComponentChangeService _ChangeService; + private ISelectionService _SelectionService; + private IMenuCommandService _MenuCommandService; + private IMenuEditorService _MenuEditorService; + private IToolboxService _ToolboxService; + + private bool _InCopyItem; + private bool _DragMoving; + + private bool _UseGlyphs; + + #endregion + + #region Public properties + + #region ChangeService + + public IComponentChangeService ChangeService + { + get { return (_ChangeService); } + } + + #endregion + + #region ControlDesigner + + public ControlDesigner ControlDesigner + { + get { return (this); } + } + + #endregion + + #region DesignerHost + + public IDesignerHost DesignerHost + { + get { return (_DesignerHost); } + } + + #endregion + + #region InCopyItem + + public bool InCopyItem + { + get { return (_InCopyItem); } + set { _InCopyItem = value; } + } + + #endregion + + #region InCopyItem + + public bool DragMoving + { + get { return (_DragMoving); } + set { _DragMoving = value; } + } + + #endregion + + #region SelectionService + + public ISelectionService SelectionService + { + get { return (_SelectionService); } + } + + #endregion + + #region MenuEditorService + + public IMenuEditorService MenuEditorService + { + get { return (_MenuEditorService); } + } + + #endregion + + #region MenuCommandService + + public IMenuCommandService MenuCommandService + { + get { return (_MenuCommandService); } + } + + #endregion + + #region ToolboxService + + public IToolboxService ToolboxService + { + get { return (_ToolboxService); } + } + + #endregion + + #endregion + + #region Initialize + + /// + /// Initializes our designer + /// + /// + public override void Initialize(IComponent component) + { + base.Initialize(component); + + if (component.Site.DesignMode == true) + _ChartControl = component as ChartControl; + + _DesignerHost = GetService(typeof(IDesignerHost)) as IDesignerHost; + + if (_DesignerHost != null) + _DesignerHost.LoadComplete += DhLoadComplete; + + InitializeServices(); + } + + #region InitializeServices + + private void InitializeServices() + { + _ChangeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService; + _SelectionService = GetService(typeof(ISelectionService)) as ISelectionService; + _ActionUIService = GetService(typeof(DesignerActionUIService)) as DesignerActionUIService; + _MenuCommandService = GetService(typeof(IMenuCommandService)) as IMenuCommandService; + _MenuEditorService = GetService(typeof(IMenuEditorService)) as IMenuEditorService; + _ToolboxService = GetService(typeof(IToolboxService)) as IToolboxService; + + _ChangeService.ComponentChanged += ChangeService_ComponentChanged; + _ChangeService.ComponentAdded += ChangeService_ComponentAdded; + _ChangeService.ComponentRemoved += ChangeService_ComponentRemoved; + } + + #endregion + + #endregion + + #region InitializeNewComponent + + public override void InitializeNewComponent(IDictionary defaultValues) + { + base.InitializeNewComponent(defaultValues); + + ChartStyleDialog csd = new ChartStyleDialog(); + + csd.ShowDialog(); + + if (Component != null && Component.Site != null && Component.Site.DesignMode == true) + { + if (_ChartControl != null) + { + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + + if (dh == null) + return; + + DesignerTransaction dt = dh.CreateTransaction(); + + try + { + IComponentChangeService change = + GetService(typeof(IComponentChangeService)) as IComponentChangeService; + + if (change != null) + change.OnComponentChanging(this.Component, null); + + CreateNewChart(csd); + + if (change != null) + change.OnComponentChanged(_ChartControl, null, null, null); + } + finally + { + dt.Commit(); + } + } + } + +#if !TRIAL + ChartControl chartControl = Control as ChartControl; + + if (chartControl != null) + chartControl.LicenseKey = GetLicenseKey(); +#endif + } + + #region CreateNewChart + + private void CreateNewChart(ChartStyleDialog csd) + { + SetupScrollBarStyles(); + + switch (csd.CbSelected) + { + case "cbPointPlot": + InitDefaultPlot(SeriesType.Point); + break; + + case "cbLinePlot": + InitDefaultPlot(SeriesType.Line); + break; + + case "cbMultiAxis": + InitMultiAxis(); + break; + + case "cbVDotPlot": + InitDotPlot(SeriesType.HorizontalDot); + break; + + case "cbHDotPlot": + InitDotPlot(SeriesType.VerticalDot); + break; + + case "cbMultiChart": + InitMultiChart(); + break; + + case "cbBubblePlot": + InitBubblePlot(); + break; + + case "cbStepLine": + ChartSeries series1 = InitDefaultPlot(SeriesType.Line); + + if (series1 != null) + series1.ChartLineDisplayMode = ChartLineDisplayMode.DisplayStepLine; + break; + + case "cbLineArea": + ChartSeries series2 = InitDefaultPlot(SeriesType.Line); + + if (series2 != null) + series2.ChartLineAreaDisplayMode = ChartLineAreaDisplayMode.DisplayLine; + break; + + case "cbBarV": + InitBar(SeriesType.VerticalBar, false); + break; + + case "cbBarH": + InitBar(SeriesType.HorizontalBar, false); + break; + + case "cbRangeBarV": + InitBar(SeriesType.VerticalBar, true); + break; + + case "cbRangeBarH": + InitBar(SeriesType.HorizontalBar, true); + break; + + case "cbHiLoVBox": + InitHiLoBar(SeriesType.VerticalHiLoBar, HiLoBarType.Box); + break; + + case "cbHiLoHBox": + InitHiLoBar(SeriesType.HorizontalHiLoBar, HiLoBarType.Box); + break; + + case "cbHiLoVLine": + InitHiLoBar(SeriesType.VerticalHiLoBar, HiLoBarType.Line); + break; + + case "cbHiLoHLine": + InitHiLoBar(SeriesType.HorizontalHiLoBar, HiLoBarType.Line); + break; + + case "cbPieSimple": + InitPieSimple(); + break; + + case "cbPieDonut": + InitPieDonut(); + break; + + case "cbPieExtent": + InitPieExtent(); + break; + + case "cbPieExtentFill": + InitPieExtentFill(); + break; + + case "cbPieMultiRing": + InitPieMultiRing(); + break; + + case "cbPieMultiRingRev": + InitPieMultiRingRev(); + break; + + case "cbPieMultiSeries": + InitPieMultiSeries(); + break; + + case "cbPieShowSingleRing": + InitPieShowSingleRing(); + break; + + case "cbPieGridAngle": + InitPieGridAngle(); + break; + + case "cbPieOverlay": + InitPieOverlay(); + break; + + default: + InitBlankChart(); + break; + } + } + + #region InitDefaultPie + + private PieChart InitDefaultPie(int seriesCount, int ringCount, bool extent) + { + PieChart pieChart = AddPieChart(); + + if (pieChart != null) + { + for (int i = 0; i < seriesCount; i++) + { + PieSeries series = GetNewPieSeries(pieChart); + + if (series != null) + AddSimulatedPieData(series, ringCount, extent); + + pieChart.ChartSeries.Add(series); + } + + _ChartControl.ChartPanel.ChartContainers.Add(pieChart); + } + + return (pieChart); + } + + #endregion + + #region InitPieSimple + + private void InitPieSimple() + { + InitDefaultPie(1, 1, false); + } + + #endregion + + #region InitPieDonut + + private void InitPieDonut() + { + PieChart pieChart = InitDefaultPie(1, 1, false); + + pieChart.InnerRadius = .2; + } + + #endregion + + #region InitPieExtent + + private void InitPieExtent() + { + InitDefaultPie(1, 1, true); + } + + #endregion + + #region InitPieExtentFill + + private void InitPieExtentFill() + { + PieChart pieChart = InitDefaultPie(1, 1, true); + + pieChart.SubSliceVisualLayout.ShowSliceWhiteSpace = Tbool.True; + } + + #endregion + + #region InitPieMultiRing + + private void InitPieMultiRing() + { + InitDefaultPie(1, 2, false); + } + + #endregion + + #region InitPieMultiRingRev + + private void InitPieMultiRingRev() + { + PieChart pieChart = InitDefaultPie(1, 2, false); + + pieChart.ReverseRingOrder = true; + } + + #endregion + + #region InitPieMultiSeries + + private void InitPieMultiSeries() + { + InitDefaultPie(2, 1, false); + } + + #endregion + + #region InitPieShowSingleRing + + private void InitPieShowSingleRing() + { + PieChart pieChart = InitDefaultPie(1, 2, false); + + pieChart.InnerRadius = .3; + pieChart.ShowAllRings = Tbool.False; + pieChart.MouseDoubleClickSliceAction = MouseDoubleClickSliceAction.ChangeActiveRing; + } + + #endregion + + #region InitPieGridAngle + + private void InitPieGridAngle() + { + PieChart pieChart = InitDefaultPie(1, 1, true); + + pieChart.ShowPieGrid = true; + pieChart.SubSliceVisualLayout.AngleMargin = 2; + } + + #endregion + + #region InitPieOverlay + + private void InitPieOverlay() + { + PieChart pieChart = InitDefaultPie(2, 1, true); + + pieChart.ShowPieGrid = true; + pieChart.SeriesOverlayEnabled = true; + + pieChart.ChartControl.UpdateLayout(); + + pieChart.SubSliceVisualLayout.AngleMargin = 2; + + for (int i = 0; i < pieChart.ChartSeries.Count; i++) + { + PieSeries series = pieChart.ChartSeries[i]; + + UpdateOverlayBackground(series.SeriesPoints); + } + } + + #region UpdateOverlayBackground + + private void UpdateOverlayBackground(PieSeriesPointCollection spc) + { + if (spc.Count > 0) + { + foreach (PieSeriesPoint psp in spc) + { + psp.SliceVisualStyles.Default.Background = + new Background(Color.FromArgb(110, psp.DefaultPaletteColor)); + + UpdateOverlayBackground(psp.SeriesPoints); + } + } + } + + #endregion + + #endregion + + #region AddPieChart + + private PieChart AddPieChart() + { + PieChart pieChart = new PieChart(); + + if (pieChart != null) + { + pieChart.Name = _ChartControl.ChartPanel.ChartContainers.GetUniqueName("PieChart"); + + pieChart.IsExploded = true; + + SetupPieChartStyle(pieChart); + SetupContainerStyle(pieChart); + SetupPieLegend(pieChart); + + AddChartTitle(pieChart); + } + + return (pieChart); + } + + #region SetupPieChartStyle + + private void SetupPieChartStyle(PieChart pieChart) + { + PieChartVisualStyle pstyle = pieChart.ChartVisualStyle; + + pstyle.Background = new Background(Color.White); + pstyle.BorderThickness = new Thickness(1); + pstyle.BorderColor = new BorderColor(Color.Black); + + pstyle.Padding = new DevComponents.DotNetBar.Charts.Style.Padding(6); + } + + #endregion + + #region SetupPieLegend + + private void SetupPieLegend(BaseChart baseChart) + { + ChartLegend legend = baseChart.Legend; + + legend.ShowCheckBoxes = false; + + legend.Placement = Placement.Outside; + legend.Alignment = Alignment.BottomCenter; + legend.Direction = Direction.LeftToRight; + + legend.AlignVerticalItems = true; + + legend.MaxVerticalPct = 90; + + ChartLegendVisualStyle lstyle = legend.ChartLegendVisualStyles.Default; + + lstyle.BorderThickness = new Thickness(1); + lstyle.BorderColor = new BorderColor(Color.Black); + + lstyle.Margin = new DevComponents.DotNetBar.Charts.Style.Padding(4); + lstyle.Padding = new DevComponents.DotNetBar.Charts.Style.Padding(4); + + lstyle.Background = new Background(Color.FromArgb(200, Color.White)); + } + + #endregion + + #region AddPieTitle + + private void AddPieTitle(ChartXy chartXy) + { + ChartTitle title = new ChartTitle(); + + title.Name = chartXy.Titles.GetUniqueName(); + + title.Text = "PieChart Title"; + title.XyAlignment = XyAlignment.Top; + + ChartTitleVisualStyle tstyle = title.ChartTitleVisualStyle; + + tstyle.Padding = new DevComponents.DotNetBar.Charts.Style.Padding(8); + tstyle.Font = new Font("Georgia", 16); + tstyle.TextColor = Color.Navy; + tstyle.Alignment = Alignment.MiddleCenter; + + chartXy.Titles.Add(title); + } + + #endregion + + #endregion + + #region InitBlankChart + + private void InitBlankChart() + { + ChartPanel chartPanel = _ChartControl.ChartPanel; + + chartPanel.EmptyText = "No Charts Defined."; + + chartPanel.ContainerVisualStyles.Default.BorderColor = new BorderColor(Color.Black); + chartPanel.ContainerVisualStyles.Default.BorderThickness = new Thickness(1); + } + + #endregion + + #region InitDefaultPlot + + private ChartSeries InitDefaultPlot(SeriesType seriesType) + { + ChartXy chartXy = AddChartXy(); + + if (chartXy != null) + { + ChartSeries series = GetNewChartSeries(chartXy, seriesType); + + if (series != null) + AddSimulatedData(series); + + _ChartControl.ChartPanel.ChartContainers.Add(chartXy); + + chartXy.ChartSeries.Add(series); + + return (series); + } + + return (null); + } + + #endregion + + #region InitMultiAxis + + private void InitMultiAxis() + { + ChartXy chartXy = AddChartXy(); + + if (chartXy != null) + { + ChartAxisX axisX = new ChartAxisX(); + axisX.Name = chartXy.AncillaryAxesX.GetUniqueName(); + + chartXy.AncillaryAxesX.Add(axisX); + + ChartAxisY axisY = new ChartAxisY(); + axisY.Name = chartXy.AncillaryAxesY.GetUniqueName(); + axisY.AxisAlignment = AxisAlignment.Near; + + chartXy.AncillaryAxesY.Add(axisY); + + ChartSeries series = GetNewChartSeries(chartXy, SeriesType.Line); + + if (series != null) + { + series.ChartLineDisplayMode = ChartLineDisplayMode.DisplayPoints; + + AddSimulatedData(series); + + series.SeriesPoints.Add(new SeriesPoint(0d, 50d)); + series.SeriesPoints.Add(new SeriesPoint(12d, 0d)); + + chartXy.ChartSeries.Add(series); + } + + series = GetNewChartSeries(chartXy, SeriesType.Line); + + if (series != null) + { + series.ChartLineDisplayMode = ChartLineDisplayMode.DisplaySpline; + + AddSimulatedData(series); + + series.SeriesPoints.Add(new SeriesPoint(0d, 0d)); + series.SeriesPoints.Add(new SeriesPoint(12d, 50d)); + + series.AxisX = axisX; + series.AxisY = axisY; + + chartXy.ChartSeries.Add(series); + } + + _ChartControl.ChartPanel.ChartContainers.Add(chartXy); + } + } + + #endregion + + #region InitDotPlot + + private void InitDotPlot(SeriesType chartType) + { + ChartXy chartXy = AddChartXy(); + + if (chartXy != null) + { + chartXy.Legend.Alignment = Alignment.TopRight; + + chartXy.AxisX.MinGridInterval = 20; + chartXy.AxisY.MinGridInterval = 20; + + chartXy.AxisX.MinorTickmarks.TickmarkCount = 0; + chartXy.AxisY.MinorTickmarks.TickmarkCount = 0; + + chartXy.MinContentSize = new Size(100, 100); + + ChartSeries series = GetNewChartSeries(chartXy, chartType); + + if (series != null) + { + PointMarkerVisualStyle mstyle = series.ChartSeriesVisualStyle.MarkerVisualStyle; + + mstyle.Size = new Size(10, 10); + mstyle.Background = new Background(Color.CornflowerBlue); + mstyle.BorderColor = Color.Black; + mstyle.BorderWidth = 1; + + AddSimulatedDotPlotData(series); + } + + _ChartControl.ChartPanel.ChartContainers.Add(chartXy); + + chartXy.ChartSeries.Add(series); + } + } + + #endregion + + #region InitMultiChart + + private void InitMultiChart() + { + for (int i = 0; i < 4; i++) + InitDefaultPlot(SeriesType.Line); + } + + #endregion + + #region InitBubblePlot + + private void InitBubblePlot() + { + ChartXy chartXy = AddChartXy(); + + if (chartXy != null) + { + ChartSeries series = GetNewChartSeries(chartXy, SeriesType.Bubble); + + if (series != null) + { + PointMarkerVisualStyle mstyle = + series.ChartSeriesVisualStyle.MarkerVisualStyle; + + mstyle.Background = new Background(Color.FromArgb(150, Color.DarkGreen)); + mstyle.BorderWidth = 1; + mstyle.BorderColor = Color.DarkGreen; + + AddSimulatedBubbleData(series); + + chartXy.ChartSeries.Add(series); + } + + series = GetNewChartSeries(chartXy, SeriesType.Bubble); + + if (series != null) + { + PointMarkerVisualStyle mstyle = + series.ChartSeriesVisualStyle.MarkerVisualStyle; + + mstyle.Background = new Background(Color.FromArgb(150, Color.DarkBlue)); + mstyle.BorderWidth = 1; + mstyle.BorderColor = Color.DarkBlue; + + AddSimulatedBubbleData(series); + + chartXy.ChartSeries.Add(series); + } + + _ChartControl.ChartPanel.ChartContainers.Add(chartXy); + } + } + + #endregion + + #region InitBar + + private void InitBar(SeriesType seriesType, bool rangeBar) + { + ChartXy chartXy = AddChartXy(); + + if (chartXy != null) + { + chartXy.BarShadingEnabled = Tbool.True; + + ChartSeries series = GetNewChartSeries(chartXy, seriesType); + + if (series != null) + { + if (rangeBar == true) + AddSimulatedRangeData(series); + else + AddSimulatedData(series); + + _ChartControl.ChartPanel.ChartContainers.Add(chartXy); + + chartXy.ChartSeries.Add(series); + } + } + } + + #endregion + + #region InitHiLoBar + + private void InitHiLoBar(SeriesType seriesType, HiLoBarType hiloType) + { + ChartXy chartXy = AddChartXy(); + + if (chartXy != null) + { + chartXy.BarShadingEnabled = Tbool.True; + + chartXy.AxisX.GridSpacing = 1; + chartXy.AxisY.GridSpacing = 1; + + if (seriesType == SeriesType.VerticalHiLoBar) + { + chartXy.AxisX.AxisMargins = 0; + chartXy.AxisX.MinorTickmarks.TickmarkCount = 0; + chartXy.AxisY.MinorTickmarks.TickmarkCount = 1; + } + else + { + chartXy.AxisY.AxisMargins = 0; + chartXy.AxisX.MinorTickmarks.TickmarkCount = 1; + chartXy.AxisY.MinorTickmarks.TickmarkCount = 0; + } + + ChartSeries series = GetNewChartSeries(chartXy, seriesType); + + if (series != null) + { + series.HiLoBarType = hiloType; + + ChartHiLoBarVisualStyle style = series.ChartSeriesVisualStyle.HiLoBarVisualStyle; + + style.ShowWhiskerCaps = Tbool.True; + style.UseAlternateSegmentStyle = Tbool.True; + + style.DefaultSegmentStyle.BoxBackground = new Background(Color.Green); + style.DefaultSegmentStyle.Default.LineColor = Color.Green; + style.DefaultSegmentStyle.Default.LineWidth = 2; + + style.AlternateSegmentStyle.BoxBackground = new Background(Color.Red); + style.AlternateSegmentStyle.Default.LineColor = Color.Crimson; + style.AlternateSegmentStyle.Default.LineWidth = 2; + + AddSimulatedHiLoData(series); + + _ChartControl.ChartPanel.ChartContainers.Add(chartXy); + + chartXy.ChartSeries.Add(series); + } + } + } + + #endregion + + #region SetupScrollBarStyles + + private void SetupScrollBarStyles() + { + ScrollBarVisualStyle moStyle = + _ChartControl.DefaultVisualStyles.HScrollBarVisualStyles.MouseOver; + + moStyle.ArrowBackground = new Background(Color.AliceBlue); + moStyle.ThumbBackground = new Background(Color.AliceBlue); + + ScrollBarVisualStyle smoStyle = + _ChartControl.DefaultVisualStyles.HScrollBarVisualStyles.SelectedMouseOver; + + smoStyle.ArrowBackground = new Background(Color.White); + smoStyle.ThumbBackground = new Background(Color.White); + + moStyle = _ChartControl.DefaultVisualStyles.VScrollBarVisualStyles.MouseOver; + + moStyle.ArrowBackground = new Background(Color.AliceBlue); + moStyle.ThumbBackground = new Background(Color.AliceBlue); + + smoStyle = _ChartControl.DefaultVisualStyles.VScrollBarVisualStyles.SelectedMouseOver; + + smoStyle.ArrowBackground = new Background(Color.White); + smoStyle.ThumbBackground = new Background(Color.White); + } + + #endregion + + #region AddChartXy + + private ChartXy AddChartXy() + { + ChartXy chartXy = new ChartXy(); + + if (chartXy != null) + { + chartXy.Name = _ChartControl.ChartPanel.ChartContainers.GetUniqueName("ChartXy"); + + chartXy.ChartCrosshair.AxisOrientation = AxisOrientation.X; + + chartXy.ChartCrosshair.ShowValueXLine = true; + chartXy.ChartCrosshair.ShowValueYLine = true; + chartXy.ChartCrosshair.ShowValueXLabels = true; + chartXy.ChartCrosshair.ShowValueYLabels = true; + + chartXy.ChartCrosshair.HighlightPoints = true; + + chartXy.ChartCrosshair.ShowCrosshairLabels = true; + chartXy.ChartCrosshair.CrosshairLabelMode = CrosshairLabelMode.NearestSeries; + + chartXy.ChartCrosshair.CrosshairVisualStyle.Background = new Background(Color.White); + + SetupChartStyle(chartXy); + SetupContainerStyle(chartXy); + SetupChartAxes(chartXy); + SetupChartLegend(chartXy); + + AddChartTitle(chartXy); + } + + return (chartXy); + } + + #region SetupChartAxes + + private void SetupChartAxes(ChartXy chartXy) + { + // X Axis + + ChartAxis axis = chartXy.AxisX; + + axis.MajorGridLines.GridLinesVisualStyle.LineColor = Color.Gainsboro; + axis.MinorGridLines.GridLinesVisualStyle.LineColor = Color.WhiteSmoke; + + // Y Axis + + axis = chartXy.AxisY; + + axis.AxisAlignment = AxisAlignment.Far; + + axis.MajorGridLines.GridLinesVisualStyle.LineColor = Color.Gainsboro; + axis.MinorGridLines.GridLinesVisualStyle.LineColor = Color.WhiteSmoke; + } + + #endregion + + #region SetupChartStyle + + private void SetupChartStyle(ChartXy chartXy) + { + ChartXyVisualStyle xystyle = chartXy.ChartVisualStyle; + + xystyle.Background = new Background(Color.White); + xystyle.BorderThickness = new Thickness(1); + xystyle.BorderColor = new BorderColor(Color.Black); + + xystyle.Padding = new DevComponents.DotNetBar.Charts.Style.Padding(6); + + ChartSeriesVisualStyle cstyle = chartXy.ChartSeriesVisualStyle; + PointMarkerVisualStyle pstyle = cstyle.MarkerHighlightVisualStyle; + + pstyle.Background = new Background(Color.Yellow); + pstyle.Type = PointMarkerType.Ellipse; + pstyle.Size = new Size(15, 15); + } + + #endregion + + #endregion + + #region SetupContainerStyle + + private void SetupContainerStyle(BaseChart baseChart) + { + ContainerVisualStyle dstyle = baseChart.ContainerVisualStyles.Default; + + dstyle.Background = new Background(Color.White); + dstyle.BorderColor = new BorderColor(Color.DimGray); + dstyle.BorderThickness = new Thickness(1); + + dstyle.DropShadow.Enabled = Tbool.True; + dstyle.Padding = new DevComponents.DotNetBar.Charts.Style.Padding(6); + } + + #endregion + + #region SetupChartLegend + + private void SetupChartLegend(BaseChart baseChart) + { + ChartLegend legend = baseChart.Legend; + + legend.ShowCheckBoxes = false; + legend.Placement = Placement.Inside; + legend.Alignment = Alignment.TopLeft; + legend.AlignVerticalItems = true; + legend.Direction = Direction.LeftToRight; + + legend.MaxHorizontalPct = 75; + + ChartLegendVisualStyle lstyle = legend.ChartLegendVisualStyles.Default; + + lstyle.BorderThickness = new Thickness(1); + lstyle.BorderColor = new BorderColor(Color.Black); + + lstyle.Margin = new DevComponents.DotNetBar.Charts.Style.Padding(8); + lstyle.Padding = new DevComponents.DotNetBar.Charts.Style.Padding(4); + + lstyle.Background = new Background(Color.FromArgb(200, Color.White)); + } + + #endregion + + #region AddChartTitle + + private void AddChartTitle(BaseChart baseChart) + { + ChartTitle title = new ChartTitle(); + + title.Name = baseChart.Titles.GetUniqueName(); + + title.Text = "Chart Title"; + title.XyAlignment = XyAlignment.Top; + + ChartTitleVisualStyle tstyle = title.ChartTitleVisualStyle; + + tstyle.Padding = new DevComponents.DotNetBar.Charts.Style.Padding(8); + tstyle.Font = new Font("Georgia", 16); + tstyle.TextColor = Color.Navy; + tstyle.Alignment = Alignment.MiddleCenter; + + baseChart.Titles.Add(title); + } + + #endregion + + #region GetNewChartSeries + + private ChartSeries GetNewChartSeries(ChartXy chartXy, SeriesType chartType) + { + ChartSeries series = new ChartSeries(chartType); + + if (series != null) + { + series.Name = chartXy.ChartSeries.GetUniqueName(); + + series.CrosshairHighlightPoints = Tbool.True; + } + + return (series); + } + + #endregion + + #region GetNewPieSeries + + private PieSeries GetNewPieSeries(PieChart pieChart) + { + PieSeries series = new PieSeries(); + + if (series != null) + series.Name = pieChart.ChartSeries.GetUniqueName(); + + return (series); + } + + #endregion + + #region AddSimulatedData + + private void AddSimulatedData(ChartSeries series) + { + for (int i = 0; i < 10; i++) + { + double d = Convert.ToDouble(i); + + series.SeriesPoints.Add( + new SeriesPoint(d, Convert.ToDouble(_Rand.Next(2, 50)))); + } + } + + #endregion + + #region AddSimulatedDotPlotData + + private void AddSimulatedDotPlotData(ChartSeries series) + { + for (int i = 0; i < 10; i++) + { + series.SeriesPoints.Add( + new SeriesPoint(i, _Rand.Next(0, 10))); + } + } + + #endregion + + #region AddSimulatedBubbleData + + private void AddSimulatedBubbleData(ChartSeries series) + { + for (int i = 0; i < 5; i++) + { + double d = Convert.ToDouble(i); + + series.SeriesPoints.Add( + new SeriesPoint(d, + Convert.ToDouble(_Rand.Next(0, 10)), + Convert.ToDouble(_Rand.Next(10, 1000)))); + } + } + + #endregion + + #region AddSimulatedRangeData + + private void AddSimulatedRangeData(ChartSeries series) + { + for (int i = 0; i < 10; i++) + { + double d = Convert.ToDouble(i); + + double v1 = Convert.ToDouble(_Rand.Next(2, 50)); + double v2 = v1 + Convert.ToDouble(_Rand.Next(10, 20)); + + series.SeriesPoints.Add(new SeriesPoint(d, v1, v2)); + } + } + + #endregion + + #region AddSimulatedHiLoData + + private void AddSimulatedHiLoData(ChartSeries series) + { + for (int i = 0; i < 5; i++) + { + double d = Convert.ToDouble(i); + + double lo = _Rand.NextDouble() * 5; + double hi = lo + _Rand.NextDouble() * 5 + 10; + + double mid = Math.Floor((hi + lo) / 2); + + double open = mid - _Rand.NextDouble() * 5; + double close = mid + _Rand.NextDouble() * 5; + + if (i % 2 == 1) + { + double swap = open; + + open = close; + close = swap; + } + + series.SeriesPoints.Add(new SeriesPoint(d, new object[] { hi, lo, close, open })); + } + } + + #endregion + + #region AddSimulatedPieData + + private void AddSimulatedPieData(PieSeries series, int ringCount, bool extent) + { + for (int i = 0; i < 5; i++) + { + PieSeriesPoint psp = (extent == true) ? + new PieSeriesPoint("PX" + i, _Rand.Next(30, 100), _Rand.Next(30, 100)) : + new PieSeriesPoint("P" + i, _Rand.Next(30, 100)); + + series.SeriesPoints.Add(psp); + + AddPieRing(psp, ringCount - 1); + } + } + + #region AddPieRing + + private void AddPieRing(PieSeriesPoint psp, int ringCount) + { + if (ringCount > 0) + { + for (int i = 0; i < 2; i++) + { + PieSeriesPoint psp2 = new PieSeriesPoint("P" + i, 50); + + psp.SeriesPoints.Add(psp2); + + AddPieRing(psp, ringCount - 1); + } + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region ChangeService + + #region ChangeService_ComponentChanged + + void ChangeService_ComponentChanged(object sender, ComponentChangedEventArgs e) + { + if (InCopyItem == false) + { + _ChartControl.UpdateLayout(); + + if (e.Member != null) + { + switch (e.Member.Name) + { + case "AncillaryAxesX": + case "AncillaryAxesY": + case "ChartContainers": + case "Location": + case "Titles": + case "Visible": + UpdateGlyphs(); + break; + } + } + else + { + UpdateGlyphs(); + } + } + } + + #endregion + + #region ChangeService_ComponentAdded + + void ChangeService_ComponentAdded(object sender, ComponentEventArgs e) + { + CheckGlyphUse(); + + UpdateGlyphs(); + } + + #endregion + + #region ChangeService_ComponentRemoved + + void ChangeService_ComponentRemoved(object sender, ComponentEventArgs e) + { + CheckGlyphUse(); + + UpdateGlyphs(); + } + + #endregion + + #region CheckGlyphUse + + private void CheckGlyphUse() + { + _UseGlyphs = true; + + if (_DesignerHost is IContainer) + { + foreach (IComponent comp in ((IContainer)_DesignerHost).Components) + { + if (comp is ContextMenuStrip) + { + _UseGlyphs = false; + break; + } + } + } + } + + #endregion + + #endregion + + #region UpdateGlyphs + + private void UpdateGlyphs() + { + RemoveAdorners(); + + AddContainerGlyphs(_ChartControl.ChartPanel); + + ICollection ic = _SelectionService.GetSelectedComponents(); + + if (ic != null) + { + _SelectionService.SetSelectedComponents(null); + _SelectionService.SetSelectedComponents(ic); + } + } + + #endregion + + #region RemoveAdorners + + private void RemoveAdorners() + { + List adornerList = new List(); + + for (int i = 0; i < BehaviorService.Adorners.Count; i++) + { + Adorner adorner = BehaviorService.Adorners[i]; + + if (adorner.Glyphs != null && adorner.Glyphs.Count > 0) + { + SelectionGlyph sg = adorner.Glyphs[0] as SelectionGlyph; + + if (sg != null && sg.ControlDesigner == this) + adornerList.Add(adorner); + } + } + + foreach (Adorner ad in adornerList) + { + for (int i = ad.Glyphs.Count - 1; i >= 0; i--) + { + SelectionGlyph sg = (SelectionGlyph)ad.Glyphs[i]; + + ad.Glyphs.RemoveAt(i); + + sg.Dispose(); + } + + BehaviorService.Adorners.Remove(ad); + } + } + + #endregion + + #region ActionLists + + /// + /// Gets our DesignerActionListCollection list + /// + public override DesignerActionListCollection ActionLists + { + get + { + if (_ActionLists == null) + { + _ActionLists = new DesignerActionListCollection(); + + _ActionLists.Add(new ChartControlActionList(_ChartControl)); + } + + return (_ActionLists); + } + } + + #endregion + + #region Load complete + + private void DhLoadComplete(object sender, EventArgs e) + { + IDesignerHost dh = GetService(typeof(IDesignerHost)) as IDesignerHost; + + if (dh != null) + dh.LoadComplete -= DhLoadComplete; + + ChartControl chartControl = Control as ChartControl; + + if (chartControl != null) + { + CheckGlyphUse(); + + ValidateLicenseKey(chartControl); + + AddContainerGlyphs(chartControl.ChartPanel); + } + } + + #endregion + + #region AddContainerGlyphs + + private void AddContainerGlyphs(ChartContainer cc) + { + if (_UseGlyphs == true) + { + if (cc.Visible == true) + { + AddSelectionAdorner(cc); + + if (cc.Legend.Visible == true) + AddSelectionAdorner(cc.Legend); + + if (cc.Titles != null) + { + foreach (ChartTitle title in cc.Titles) + { + if (title.Visible == true) + AddSelectionAdorner(title); + } + } + + if (cc is ChartPanel) + { + ChartPanel cp = (ChartPanel)cc; + + foreach (ChartContainer cont in cp.ChartContainers) + { + if (cont.Visible == true) + AddContainerGlyphs(cont); + } + } + else if (cc is ChartXy) + { + ChartXy chartXy = (ChartXy)cc; + + if (chartXy.AxisX.Visible == true) + AddSelectionAdorner(chartXy.AxisX); + + if (chartXy.AxisY.Visible == true) + AddSelectionAdorner(chartXy.AxisY); + + foreach (ChartAxis axis in chartXy.AncillaryAxesX) + { + if (axis.Visible == true) + AddSelectionAdorner(axis); + } + + foreach (ChartAxis axis in chartXy.AncillaryAxesY) + { + if (axis.Visible == true) + AddSelectionAdorner(axis); + } + } + } + } + } + + #region AddSelectionAdorner + + private void AddSelectionAdorner(ChartVisualElement visualItem) + { + if (visualItem.Visible == true) + { + Adorner adorner = new Adorner(); + + adorner.Glyphs.Add(new SelectionGlyph(this, visualItem, adorner)); + + BehaviorService.Adorners.Add(adorner); + } + } + + #endregion + + #endregion + + #region OnSetCursor + + protected override void OnSetCursor() + { + if (ToolboxService == null || + ToolboxService.GetSelectedToolboxItem() == null) + { + if (DragMoving == true) + { + Cursor.Current = Cursors.SizeAll; + } + else + { + if (SelectionBehavior.ContextMenuActive == true) + Cursor.Current = Cursors.Arrow; + else + base.OnSetCursor(); + } + } + else + { + Control ctl1 = (Control)Component; + + Form form = ctl1.FindForm(); + + if (form != null) + base.OnSetCursor(); + } + } + + #endregion + + #region OnMouseDragBegin + + protected override void OnMouseDragBegin(int x, int y) + { + DragMoving = true; + + base.OnMouseDragBegin(x, y); + } + + #endregion + + #region OnMouseDragEnd + + protected override void OnMouseDragEnd(bool cancel) + { + DragMoving = false; + + base.OnMouseDragEnd(cancel); + } + + #endregion + + #region GetLicenseKey + +#if !TRIAL + private string GetLicenseKey() + { + string key = ""; + + RegistryKey regkey = + Registry.LocalMachine.OpenSubKey("Software\\DevComponents\\Licenses", false); + + if (regkey != null) + { + object keyValue = regkey.GetValue("DevComponents.DotNetBar.DotNetBarManager2"); + + if (keyValue != null) + key = keyValue.ToString(); + } + + return (key); + } +#endif + + #endregion + + #region ValidateLicenseKey + + private void ValidateLicenseKey(ChartControl chartControl) + { +#if !TRIAL + string key = GetLicenseKey(); + + if (key != "" && chartControl != null && chartControl.LicenseKey == "" && chartControl.LicenseKey != key) + TypeDescriptor.GetProperties(chartControl)["LicenseKey"].SetValue(chartControl, key); +#endif + } + + #endregion + + #region SelectionGlyph + + public class SelectionGlyph : Glyph, IDisposable + { + #region Private variables + + private ChartControlDesigner _ControlDesigner; + + private Adorner _SelectionAdorner; + private Control _RelatedControl; + + private Rectangle _Bounds; + private ChartVisualElement _VisualItem; + + private bool _IsSelected; + + private Brush _SelBrush; + private Brush _SelBrush2; + + #endregion + + public SelectionGlyph(ChartControlDesigner controlDesigner, ChartVisualElement visualItem, Adorner selectionAdorner) + : base(new SelectionBehavior(controlDesigner)) + { + _VisualItem = visualItem; + _ControlDesigner = controlDesigner; + _SelectionAdorner = selectionAdorner; + + _RelatedControl = _ControlDesigner.Component as Control; + + _ControlDesigner.SelectionService.SelectionChanged += SelectionService_SelectionChanged; + _ControlDesigner.ChangeService.ComponentChanged += ChangeService_ComponentChanged; + + _VisualItem.ChartControl.UpdateLayout(); + + CalcGlyphBounds(); + } + + #region Public properties + + #region Bounds + + public override Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + + #region ControlDesigner + + public ChartControlDesigner ControlDesigner + { + get { return (_ControlDesigner); } + } + + #endregion + + #region SelectionAdorner + + public Adorner SelectionAdorner + { + get { return (_SelectionAdorner); } + } + + #endregion + + #region VisualItem + + public ChartVisualElement VisualItem + { + get { return (_VisualItem); } + } + + #endregion + + #endregion + + #region Private properties + + #region SelBrush + + private Brush SelBrush + { + get + { + if (_SelBrush == null) + { + _SelBrush = new HatchBrush(HatchStyle.BackwardDiagonal, + Color.FromArgb(20, Color.Purple), Color.Transparent); + } + + return (_SelBrush); + } + + set + { + if (_SelBrush != null) + _SelBrush.Dispose(); + + _SelBrush = null; + } + } + + #endregion + + #region SelBrush2 + + private Brush SelBrush2 + { + get + { + if (_SelBrush2 == null) + { + _SelBrush2 = new HatchBrush(HatchStyle.BackwardDiagonal, + Color.FromArgb(60, Color.White), Color.Transparent); + } + + return (_SelBrush2); + } + + set + { + if (_SelBrush2 != null) + _SelBrush2.Dispose(); + + _SelBrush2 = value; + } + } + + #endregion + + #endregion + + #region Paint + + public override void Paint(PaintEventArgs e) + { + if (_ControlDesigner.SelectionService.GetComponentSelected(_VisualItem) == true) + { + Graphics g = e.Graphics; + + int n = (_VisualItem is ChartPanel || _VisualItem is ChartXy) ? -2 : 2; + + Rectangle r = Bounds; + r.Inflate(n, n); + + g.RenderingOrigin = new Point(1, 0); + g.FillRectangle(SelBrush, r); + + g.RenderingOrigin = new Point(0, 0); + g.FillRectangle(SelBrush2, r); + + ControlPaint.DrawFocusRectangle(g, r); + + r.Inflate(1, 1); + + using (Pen pen = new Pen(Color.FromArgb(170, Color.White))) + { + pen.DashStyle = DashStyle.Dot; + + r.Height--; + r.Width--; + + g.DrawRectangle(pen, r); + } + } + } + + #endregion + + #region GetHitTest + + public override Cursor GetHitTest(Point p) + { + Control control = GetIt(p); + + if (control == _RelatedControl) + { + if (control.Parent != null && control.Parent.Visible == true) + { + ChartControlDesigner ccd = _ControlDesigner; + + if (ccd.ToolboxService == null || + ccd.ToolboxService.GetSelectedToolboxItem() == null) + { + if (ccd.DragMoving == false) + { + if (Bounds.Contains(p)) + return (Cursors.Hand); + } + } + } + } + + return (null); + } + + #region GetIt + + private Control GetIt(Point pt) + { + if (_RelatedControl != null) + { + Control ctl = _RelatedControl.Parent; + Control ctl2 = _ControlDesigner.DesignerHost.RootComponent as Control; + + if (ctl != null && ctl2 != null && ctl2.Parent != null) + { + Point pt1 = ctl.PointToScreen(Point.Empty); + Point pt2 = ctl2.Parent.PointToScreen(ctl2.Parent.Location); + + pt.X -= (pt1.X - pt2.X); + pt.Y -= (pt1.Y - pt2.Y); + + return (ctl.GetChildAtPoint(pt)); + } + } + + return (null); + } + + #endregion + + #endregion + + #region SelectionService_SelectionChanged + + void SelectionService_SelectionChanged(object sender, EventArgs e) + { + bool selected = _ControlDesigner.SelectionService.GetComponentSelected(_VisualItem); + + if (selected == true) + CalcGlyphBounds(); + + if (_IsSelected != selected) + { + _IsSelected = selected; + + Control ctl = _ControlDesigner.DesignerHost.RootComponent as Control; + + if (ctl != null) + ctl.Invalidate(true); + } + } + + #endregion + + #region ChangeService_ComponentChanged + + void ChangeService_ComponentChanged(object sender, ComponentChangedEventArgs e) + { + if (_ControlDesigner.InCopyItem == false) + { + if (_IsSelected == true) + { + if (_VisualItem != null && _VisualItem.ChartControl != null) + { + _VisualItem.ChartControl.UpdateLayout(); + + CalcGlyphBounds(); + + _RelatedControl.Invalidate(); + } + } + } + } + + #endregion + + #region CalcGlyphBounds + + private void CalcGlyphBounds() + { + Rectangle bounds = _VisualItem.Bounds; + + if (_RelatedControl != null) + { + if (_VisualItem is ChartContainer) + { + ChartContainer cc = (ChartContainer)_VisualItem; + + bounds = GetAdjustedBounds(bounds, cc.EffectiveContainerStyles[StyleType.Default].Margin); + } + else if (_VisualItem is ChartXy) + { + ChartXy bc = (ChartXy)_VisualItem; + + bounds = GetAdjustedBounds(bounds, bc.EffectiveChartStyle.Margin); + } + else if (_VisualItem is ChartTitle) + { + ChartTitle ct = (ChartTitle)_VisualItem; + + bounds = GetAdjustedBounds(bounds, ct.EffectiveTitleStyle.Margin); + } + + Point pt = _ControlDesigner.BehaviorService.ControlToAdornerWindow(_RelatedControl); + + bounds.Offset(pt); + } + + _Bounds = bounds; + } + + #region GetAdjustedBounds + + internal Rectangle GetAdjustedBounds(Rectangle bounds, Thickness padding) + { + if (padding.IsEmpty == false) + { + if (bounds.Height > padding.Vertical) + { + bounds.Y += padding.Top; + bounds.Height -= padding.Vertical; + } + + if (bounds.Width > padding.Horizontal) + { + bounds.X += padding.Left; + bounds.Width -= padding.Horizontal; + } + } + + return (bounds); + } + + #endregion + + #endregion + + #region Dispose + + public void Dispose() + { + SelBrush = null; + SelBrush2 = null; + + if (_ControlDesigner != null) + { + _ControlDesigner.SelectionService.SelectionChanged -= SelectionService_SelectionChanged; + _ControlDesigner.ChangeService.ComponentChanged -= ChangeService_ComponentChanged; + } + } + + #endregion + } + + #endregion + + #region SelectionBehavior + + internal class SelectionBehavior : Behavior + { + #region Static variables + + static public bool ContextMenuActive; + + #endregion + + #region Private variables + + private IDesigner _ControlDesigner; + private Control _RelatedControl; + private Point _DragPoint; + private bool _MouseDown; + + #endregion + + internal SelectionBehavior(IDesigner controlDesigner) + { + _ControlDesigner = controlDesigner; + _RelatedControl = controlDesigner.Component as Control; + } + + #region OnMouseDown + + public override bool OnMouseDown(Glyph g, MouseButtons button, Point mouseLoc) + { + SelectionGlyph sg = g as SelectionGlyph; + + if (button == MouseButtons.Left) + { + if (sg.ControlDesigner.SelectionService.GetComponentSelected(sg.VisualItem) == false) + { + if (ContextMenuActive == false) + SelectVisualElement(sg, sg.VisualItem); + } + } + else if (button == MouseButtons.Right) + { + object primarySelection = sg.ControlDesigner.SelectionService.PrimarySelection; + + if (CanSelectVisualItem(primarySelection, sg.VisualItem) == true) + SelectVisualElement(sg, sg.VisualItem); + } + + ContextMenuActive = false; + + _DragPoint = Control.MousePosition; + + _MouseDown = true; + + return (true); + } + + #region CanSelectVisualItem + + private bool CanSelectVisualItem( + object primarySelection, ChartVisualElement cve) + { + if (cve is ChartLegend || cve is ChartTitle || cve is ChartAxis) + return (true); + + if (primarySelection == null) + return (true); + + if (primarySelection is ChartControl) + return (false); + + ChartVisualElement pcve = primarySelection as ChartVisualElement; + + if (pcve == null) + return (true); + + return (IsChildItem(cve, pcve) == false); + } + + #region IsChildItem + + private bool IsChildItem(ChartVisualElement cve, ChartVisualElement pcve) + { + ChartVisualElement parent = cve.Parent as ChartVisualElement; + + while (parent != null) + { + if (parent == pcve) + return (true); + + parent = parent.Parent as ChartVisualElement; + } + + return (false); + } + + #endregion + + #endregion + + #region SelectVisualElement + + private void SelectVisualElement(SelectionGlyph sg, ChartVisualElement cve) + { + if (cve != null) + sg.ControlDesigner.SelectionService.SetSelectedComponents(new object[] { cve }); + else + sg.ControlDesigner.SelectionService.SetSelectedComponents(new object[] { _RelatedControl }); + + _RelatedControl.Invalidate(); + } + + #endregion + + #endregion + + #region OnMouseUp + + public override bool OnMouseUp(Glyph g, MouseButtons button) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + + _MouseDown = false; + + bool value = base.OnMouseUp(g, button); + + if (button == MouseButtons.Right) + { + SelectionGlyph sg = g as SelectionGlyph; + + if (sg != null) + { + if (ShowGlyphContextMenu(g as SelectionGlyph) == true) + return (true); + + return (true); + } + } + + return (value); + } + + #region ShowGlyphContextMenu + + private bool ShowGlyphContextMenu(SelectionGlyph sg) + { + if (sg != null) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + + Point pt = _RelatedControl.PointToClient(Control.MousePosition); + + ContextMenu cm = GetContextMenu(sg, ccd); + + if (cm != null) + { + ContextMenuActive = true; + + cm.Show(_RelatedControl, pt); + + return (true); + } + } + + return (false); + } + + #region GetContextMenu + + private ContextMenu GetContextMenu(SelectionGlyph sg, ChartControlDesigner ccd) + { + ContextMenu cm = new ContextMenu(); + + MenuItem mi = AddMenuItem(cm, null, "View Code", new EventHandler(MenuViewCode)); + + ChartVisualElement cve = ccd.SelectionService.PrimarySelection as ChartVisualElement; + + if (cve != null) + { + AddMenuItem(cm, cve, "-", null); + + if (cve is ChartPanel) + { + AddMenuItem(cm, cve, "Hide Panel", new EventHandler(HideVisualItem)); + + if (cve.Parent != null) + AddMenuItem(cm, cve, "Delete Panel", new EventHandler(DeleteChartPanel)); + } + else if (cve is BaseChart) + { + AddMenuItem(cm, cve, "Hide Chart", new EventHandler(HideVisualItem)); + AddMenuItem(cm, cve, "Delete Chart", new EventHandler(DeleteChartPanel)); + } + else if (cve is ChartTitle) + { + AddMenuItem(cm, cve, "Hide Title", new EventHandler(HideVisualItem)); + AddMenuItem(cm, cve, "Delete Title", new EventHandler(DeleteTitle)); + AddMenuItem(cm, cve, "-", null); + + mi = AddMenuItem(cm, cve, "XyAlignment", null); + + AddSubMenuItem(mi, cve, "Top", new EventHandler(AlignTitleTop)); + AddSubMenuItem(mi, cve, "Left", new EventHandler(AlignTitleLeft)); + AddSubMenuItem(mi, cve, "Bottom", new EventHandler(AlignTitleBottom)); + AddSubMenuItem(mi, cve, "Right", new EventHandler(AlignTitleRight)); + } + else if (cve is ChartAxis) + { + ChartAxis axis = (ChartAxis)cve; + + AddMenuItem(cm, cve, "Hide Axis", new EventHandler(HideVisualItem)); + + if (axis.IsPrimaryAxis == false) + AddMenuItem(cm, cve, "Delete Axis", new EventHandler(DeleteAxis)); + + AddMenuItem(cm, cve, "-", null); + + mi = AddMenuItem(cm, cve, "Alignment", null); + + AddSubMenuItem(mi, cve, "Near", new EventHandler(AlignAxisNear)); + AddSubMenuItem(mi, cve, "Far", new EventHandler(AlignAxisFar)); + } + else if (cve is ChartLegend) + { + ChartLegend legend = (ChartLegend)cve; + + AddMenuItem(cm, cve, "Hide Legend", new EventHandler(HideVisualItem)); + } + } + + AddMenuItem(cm, null, "-", null); + + int n = cm.MenuItems.Count; + + AddParentSelect(cm, ccd.SelectionService.PrimarySelection); + + if (cm.MenuItems.Count == n) + cm.MenuItems.RemoveAt(cm.MenuItems.Count - 1); + + return (cm); + } + + #region AddMenuItem + + private MenuItem AddMenuItem(ContextMenu cm, + ChartVisualElement cve, string text, EventHandler e) + { + MenuItem mi = new MenuItem(text, e); + + mi.Tag = cve; + + cm.MenuItems.Add(mi); + + return (mi); + } + + #endregion + + #region AddSubMenuItem + + private MenuItem AddSubMenuItem(MenuItem mi, + ChartVisualElement cve, string text, EventHandler e) + { + MenuItem submi = new MenuItem(text, e); + + submi.Tag = cve; + + mi.MenuItems.Add(submi); + + return (submi); + } + + #endregion + + #region AddParentSelect + + private void AddParentSelect(ContextMenu cm, object psel) + { + ChartVisualElement cve = psel as ChartVisualElement; + + if (cve != null) + { + ChartVisualElement parent = cve.Parent as ChartVisualElement; + + while (parent != null) + { + if (string.IsNullOrEmpty(parent.Name) == false) + { + AddMenuItem(cm, parent, + "Select '" + parent.Name + "'", new EventHandler(SelectVisualItem)); + } + + parent = parent.Parent as ChartVisualElement; + } + + string s = string.IsNullOrEmpty(_RelatedControl.Name) + ? "ChartControl" : _RelatedControl.Name; + + AddMenuItem(cm, null, + "Select '" + s + "'", new EventHandler(SelectVisualItem)); + } + + Control ctl = _RelatedControl.Parent; + + while (ctl != null) + { + if (string.IsNullOrEmpty(ctl.Name) == false) + { + MenuItem mi = AddMenuItem(cm, null, + "Select '" + ctl.Name + "'", new EventHandler(SelectControl)); + + mi.Tag = ctl; + } + + ctl = ctl.Parent; + } + } + + #endregion + + #region Item click support + + #region SelectVisualItem + + private void SelectVisualItem(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + + ChartVisualElement cve = mi.Tag as ChartVisualElement; + + if (cve != null) + ccd.SelectionService.SetSelectedComponents(new object[] { cve }); + else + ccd.SelectionService.SetSelectedComponents(new object[] { _RelatedControl }); + } + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #region SelectControl + + private void SelectControl(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + + ccd.SelectionService.SetSelectedComponents(new object[] { mi.Tag }); + } + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #region AlignAxis + + #region AlignAxisNear + + private void AlignAxisNear(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + { + ChartAxis axis = mi.Tag as ChartAxis; + + if (axis != null) + SetValue(axis, "AxisAlignment", AxisAlignment.Near); + } + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #region AlignAxisFar + + private void AlignAxisFar(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + { + ChartAxis axis = mi.Tag as ChartAxis; + + if (axis != null) + SetValue(axis, "AxisAlignment", AxisAlignment.Far); + } + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #endregion + + #region AlignTitle + + private void AlignTitleTop(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + AlignTitle(mi.Tag as ChartTitle, XyAlignment.Top); + } + + private void AlignTitleLeft(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + AlignTitle(mi.Tag as ChartTitle, XyAlignment.Left); + } + + private void AlignTitleBottom(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + AlignTitle(mi.Tag as ChartTitle, XyAlignment.Bottom); + } + + private void AlignTitleRight(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + AlignTitle(mi.Tag as ChartTitle, XyAlignment.Right); + } + + private void AlignTitle(ChartTitle title, XyAlignment xyAlignment) + { + if (title != null) + SetValue(title, "XyAlignment", xyAlignment); + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #region DeleteAxis + + private void DeleteAxis(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + { + ChartAxis axis = mi.Tag as ChartAxis; + + if (axis != null) + { + ChartXy chartXy = axis.Parent as ChartXy; + + if (chartXy != null) + { + DialogResult result = MessageBoxEx.Show( + "Are you sure you want to delete the selected Axis?", + "Confirm Delete", MessageBoxButtons.YesNo); + + if (result == DialogResult.Yes) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + + ccd.ChangeService.OnComponentChanging(chartXy, null); + + if (axis.AxisOrientation == AxisOrientation.X) + chartXy.AncillaryAxesX.Remove(axis); + else + chartXy.AncillaryAxesY.Remove(axis); + + //axis.Dispose(); + + ccd.ChangeService.OnComponentChanged(chartXy, null, null, null); + } + } + } + } + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #region DeleteTitle + + private void DeleteTitle(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + { + ChartTitle title = mi.Tag as ChartTitle; + + if (title != null) + { + ChartContainer parent = title.Parent as ChartContainer; + + if (parent != null) + { + DialogResult result = MessageBoxEx.Show( + "Are you sure you want to delete the selected Title?", + "Confirm Delete", MessageBoxButtons.YesNo); + + if (result == DialogResult.Yes) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + + ccd.ChangeService.OnComponentChanging(parent.Titles, null); + + parent.Titles.Remove(title); + //title.Dispose(); + + ccd.ChangeService.OnComponentChanged(parent.Titles, null, null, null); + } + } + } + } + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #region DeleteChartPanel + + private void DeleteChartPanel(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + { + ChartContainer cc = mi.Tag as ChartContainer; + + if (cc != null) + { + ChartPanel parent = cc.Parent as ChartPanel; + + if (parent != null) + { + DialogResult result = MessageBoxEx.Show( + "Are you sure you want to delete the selected " + + (cc is ChartPanel ? "ChartPanel?" : "Chart?"), + "Confirm Delete", MessageBoxButtons.YesNo); + + if (result == DialogResult.Yes) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + + ccd.ChangeService.OnComponentChanging(parent.ChartContainers, null); + + parent.ChartContainers.Remove(cc); + //cc.Dispose(); + + ccd.ChangeService.OnComponentChanged(parent.ChartContainers, null, null, null); + } + } + } + } + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #region HideVisualItem + + private void HideVisualItem(object sender, EventArgs e) + { + MenuItem mi = sender as MenuItem; + + if (mi != null) + { + ChartVisualElement cve = mi.Tag as ChartVisualElement; + + if (cve != null) + SetValue(cve, "Visible", false); + } + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #region MenuViewCode + + private void MenuViewCode(object sender, EventArgs e) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + IMenuCommandService mcs = ccd.MenuCommandService; + + mcs.GlobalInvoke(StandardCommands.ViewCode); + + SelectionBehavior.ContextMenuActive = false; + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region OnMouseMove + + public override bool OnMouseMove(Glyph g, MouseButtons button, Point mouseLoc) + { + if (Control.MouseButtons == 0) + _MouseDown = false; + + if (_MouseDown == true && Control.MouseButtons != 0) + { + Point pt = Control.MousePosition; + + if (Math.Abs(_DragPoint.X - pt.X) > 4 || Math.Abs(_DragPoint.Y - pt.Y) > 4) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + + ccd.OnMouseDragBegin(pt.X, pt.Y); + + return (true); + } + } + + return base.OnMouseMove(g, button, mouseLoc); + } + + #endregion + + #region SetValue + + private void SetValue(object item, string property, object value) + { + ChartControlDesigner ccd = (ChartControlDesigner)_ControlDesigner; + + ccd.ChangeService.OnComponentChanging(item, null); + + GetPropertyByName(item, property).SetValue(item, value); + + ccd.ChangeService.OnComponentChanged(item, null, null, null); + } + + #endregion + + #region GetPropertyByName + + private PropertyDescriptor GetPropertyByName(object item, string propName) + { + PropertyDescriptor prop = + TypeDescriptor.GetProperties(item)[propName]; + + if (prop == null) + throw new ArgumentException("Matching property not found.", propName); + + return (prop); + } + + #endregion + } + + #endregion + + #region Dispose + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (ChangeService != null) + { + ChangeService.ComponentChanged -= ChangeService_ComponentChanged; + ChangeService.ComponentAdded -= ChangeService_ComponentAdded; + ChangeService.ComponentRemoved -= ChangeService_ComponentRemoved; + } + + if (BehaviorService != null) + RemoveAdorners(); + } + + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartSeriesCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartSeriesCollectionEditor.cs new file mode 100644 index 00000000..e9609bda --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartSeriesCollectionEditor.cs @@ -0,0 +1,84 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class ChartSeriesCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private BaseChart _BaseChart; + + #endregion + + public ChartSeriesCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _BaseChart = context.Instance as BaseChart; + + return (base.EditValue(context, provider, value)); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + if (itemType == typeof(PieSeries) || itemType == typeof(ChartSeries)) + { + BaseSeries series = (BaseSeries)base.CreateInstance(itemType); + + series.Name = _BaseChart.BaseSeries.GetUniqueName(); + + return (series); + } + + return (base.CreateInstance(itemType)); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + BaseSeries item = ChartItem as BaseSeries; + + if (item != null) + { + if (AddButton != null) + { + AddButton.PerformClick(); + + ChartBaseSeriesCollection csc = _BaseChart.BaseSeries; + BaseSeries clone = csc[csc.Count - 1]; + + string name = clone.Name; + item.CopyTo(clone); + clone.Name = name; + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return (_BaseChart is PieChart ? typeof(PieSeries) : typeof(ChartSeries)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartStyleDialog.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartStyleDialog.Designer.cs new file mode 100644 index 00000000..a85ae423 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartStyleDialog.Designer.cs @@ -0,0 +1,688 @@ +namespace DevComponents.Charts.Design +{ + partial class ChartStyleDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ChartStyleDialog)); + this.label1 = new System.Windows.Forms.Label(); + this.cbLinePlot = new System.Windows.Forms.CheckBox(); + this.cbPointPlot = new System.Windows.Forms.CheckBox(); + this.btnOk = new System.Windows.Forms.Button(); + this.cbBlankChart = new System.Windows.Forms.CheckBox(); + this.cbMultiAxis = new System.Windows.Forms.CheckBox(); + this.cbMultiChart = new System.Windows.Forms.CheckBox(); + this.cbHDotPlot = new System.Windows.Forms.CheckBox(); + this.cbVDotPlot = new System.Windows.Forms.CheckBox(); + this.cbBubblePlot = new System.Windows.Forms.CheckBox(); + this.label2 = new System.Windows.Forms.Label(); + this.pageSlider1 = new DevComponents.DotNetBar.Controls.PageSlider(); + this.pageSliderPage1 = new DevComponents.DotNetBar.Controls.PageSliderPage(); + this.cbStepLine = new System.Windows.Forms.CheckBox(); + this.cbLineArea = new System.Windows.Forms.CheckBox(); + this.pageSliderPage2 = new DevComponents.DotNetBar.Controls.PageSliderPage(); + this.cbRangeBarH = new System.Windows.Forms.CheckBox(); + this.cbRangeBarV = new System.Windows.Forms.CheckBox(); + this.cbBarH = new System.Windows.Forms.CheckBox(); + this.cbBarV = new System.Windows.Forms.CheckBox(); + this.pageSliderPage3 = new DevComponents.DotNetBar.Controls.PageSliderPage(); + this.cbHiLoHBox = new System.Windows.Forms.CheckBox(); + this.cbHiLoVBox = new System.Windows.Forms.CheckBox(); + this.cbHiLoHLine = new System.Windows.Forms.CheckBox(); + this.cbHiLoVLine = new System.Windows.Forms.CheckBox(); + this.pageSliderPage4 = new DevComponents.DotNetBar.Controls.PageSliderPage(); + this.cbPieMultiRingRev = new System.Windows.Forms.CheckBox(); + this.cbPieMultiRing = new System.Windows.Forms.CheckBox(); + this.cbPieExtentFill = new System.Windows.Forms.CheckBox(); + this.cbPieExtent = new System.Windows.Forms.CheckBox(); + this.cbPieDonut = new System.Windows.Forms.CheckBox(); + this.cbPieSimple = new System.Windows.Forms.CheckBox(); + this.pageSliderPage5 = new DevComponents.DotNetBar.Controls.PageSliderPage(); + this.cbPieOverlay = new System.Windows.Forms.CheckBox(); + this.cbPieGridAngle = new System.Windows.Forms.CheckBox(); + this.cbPieShowSingleRing = new System.Windows.Forms.CheckBox(); + this.cbPieMultiSeries = new System.Windows.Forms.CheckBox(); + this.pageSlider1.SuspendLayout(); + this.pageSliderPage1.SuspendLayout(); + this.pageSliderPage2.SuspendLayout(); + this.pageSliderPage3.SuspendLayout(); + this.pageSliderPage4.SuspendLayout(); + this.pageSliderPage5.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.BackColor = System.Drawing.SystemColors.ControlLight; + this.label1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.Location = new System.Drawing.Point(0, 445); + this.label1.Name = "label1"; + this.label1.Padding = new System.Windows.Forms.Padding(10, 0, 0, 0); + this.label1.Size = new System.Drawing.Size(648, 55); + this.label1.TabIndex = 4; + this.label1.Text = "Please select your starting Chart template"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // cbLinePlot + // + this.cbLinePlot.Appearance = System.Windows.Forms.Appearance.Button; + this.cbLinePlot.AutoSize = true; + this.cbLinePlot.Image = ((System.Drawing.Image)(resources.GetObject("cbLinePlot.Image"))); + this.cbLinePlot.Location = new System.Drawing.Point(347, 3); + this.cbLinePlot.Name = "cbLinePlot"; + this.cbLinePlot.Size = new System.Drawing.Size(166, 173); + this.cbLinePlot.TabIndex = 3; + this.cbLinePlot.Text = "Line Plot"; + this.cbLinePlot.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbLinePlot.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbLinePlot.UseVisualStyleBackColor = true; + this.cbLinePlot.Click += new System.EventHandler(this.CbClicked); + // + // cbPointPlot + // + this.cbPointPlot.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPointPlot.AutoSize = true; + this.cbPointPlot.Checked = true; + this.cbPointPlot.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbPointPlot.Image = ((System.Drawing.Image)(resources.GetObject("cbPointPlot.Image"))); + this.cbPointPlot.Location = new System.Drawing.Point(175, 3); + this.cbPointPlot.Name = "cbPointPlot"; + this.cbPointPlot.Size = new System.Drawing.Size(166, 173); + this.cbPointPlot.TabIndex = 2; + this.cbPointPlot.Text = "Point Plot"; + this.cbPointPlot.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPointPlot.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPointPlot.UseVisualStyleBackColor = true; + this.cbPointPlot.Click += new System.EventHandler(this.CbClicked); + // + // btnOk + // + this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOk.Location = new System.Drawing.Point(546, 461); + this.btnOk.Name = "btnOk"; + this.btnOk.Size = new System.Drawing.Size(75, 23); + this.btnOk.TabIndex = 1; + this.btnOk.Text = "Select"; + this.btnOk.UseVisualStyleBackColor = true; + // + // cbBlankChart + // + this.cbBlankChart.Appearance = System.Windows.Forms.Appearance.Button; + this.cbBlankChart.AutoSize = true; + this.cbBlankChart.Image = ((System.Drawing.Image)(resources.GetObject("cbBlankChart.Image"))); + this.cbBlankChart.Location = new System.Drawing.Point(3, 3); + this.cbBlankChart.Name = "cbBlankChart"; + this.cbBlankChart.Size = new System.Drawing.Size(166, 173); + this.cbBlankChart.TabIndex = 9; + this.cbBlankChart.Text = "Blank Chart"; + this.cbBlankChart.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbBlankChart.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbBlankChart.UseVisualStyleBackColor = true; + this.cbBlankChart.Click += new System.EventHandler(this.CbClicked); + // + // cbMultiAxis + // + this.cbMultiAxis.Appearance = System.Windows.Forms.Appearance.Button; + this.cbMultiAxis.AutoSize = true; + this.cbMultiAxis.Image = ((System.Drawing.Image)(resources.GetObject("cbMultiAxis.Image"))); + this.cbMultiAxis.Location = new System.Drawing.Point(347, 182); + this.cbMultiAxis.Name = "cbMultiAxis"; + this.cbMultiAxis.Size = new System.Drawing.Size(166, 173); + this.cbMultiAxis.TabIndex = 4; + this.cbMultiAxis.Text = "Multi Axis"; + this.cbMultiAxis.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbMultiAxis.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbMultiAxis.UseVisualStyleBackColor = true; + this.cbMultiAxis.Click += new System.EventHandler(this.CbClicked); + // + // cbMultiChart + // + this.cbMultiChart.Appearance = System.Windows.Forms.Appearance.Button; + this.cbMultiChart.AutoSize = true; + this.cbMultiChart.Image = ((System.Drawing.Image)(resources.GetObject("cbMultiChart.Image"))); + this.cbMultiChart.Location = new System.Drawing.Point(3, 3); + this.cbMultiChart.Name = "cbMultiChart"; + this.cbMultiChart.Size = new System.Drawing.Size(166, 173); + this.cbMultiChart.TabIndex = 5; + this.cbMultiChart.Text = "Multi Chart"; + this.cbMultiChart.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbMultiChart.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbMultiChart.UseVisualStyleBackColor = true; + this.cbMultiChart.Click += new System.EventHandler(this.CbClicked); + // + // cbHDotPlot + // + this.cbHDotPlot.Appearance = System.Windows.Forms.Appearance.Button; + this.cbHDotPlot.AutoSize = true; + this.cbHDotPlot.Image = ((System.Drawing.Image)(resources.GetObject("cbHDotPlot.Image"))); + this.cbHDotPlot.Location = new System.Drawing.Point(347, 3); + this.cbHDotPlot.Name = "cbHDotPlot"; + this.cbHDotPlot.Size = new System.Drawing.Size(166, 173); + this.cbHDotPlot.TabIndex = 6; + this.cbHDotPlot.Text = "Vertical DotPlot"; + this.cbHDotPlot.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbHDotPlot.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbHDotPlot.UseVisualStyleBackColor = true; + this.cbHDotPlot.Click += new System.EventHandler(this.CbClicked); + // + // cbVDotPlot + // + this.cbVDotPlot.Appearance = System.Windows.Forms.Appearance.Button; + this.cbVDotPlot.AutoSize = true; + this.cbVDotPlot.Image = ((System.Drawing.Image)(resources.GetObject("cbVDotPlot.Image"))); + this.cbVDotPlot.Location = new System.Drawing.Point(347, 184); + this.cbVDotPlot.Name = "cbVDotPlot"; + this.cbVDotPlot.Size = new System.Drawing.Size(166, 173); + this.cbVDotPlot.TabIndex = 7; + this.cbVDotPlot.Text = "Horizontal DotPlot"; + this.cbVDotPlot.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbVDotPlot.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbVDotPlot.UseVisualStyleBackColor = true; + this.cbVDotPlot.Click += new System.EventHandler(this.CbClicked); + // + // cbBubblePlot + // + this.cbBubblePlot.Appearance = System.Windows.Forms.Appearance.Button; + this.cbBubblePlot.AutoSize = true; + this.cbBubblePlot.Image = ((System.Drawing.Image)(resources.GetObject("cbBubblePlot.Image"))); + this.cbBubblePlot.Location = new System.Drawing.Point(3, 182); + this.cbBubblePlot.Name = "cbBubblePlot"; + this.cbBubblePlot.Size = new System.Drawing.Size(166, 173); + this.cbBubblePlot.TabIndex = 8; + this.cbBubblePlot.Text = "Bubble Plot"; + this.cbBubblePlot.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbBubblePlot.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbBubblePlot.UseVisualStyleBackColor = true; + this.cbBubblePlot.Click += new System.EventHandler(this.CbClicked); + // + // label2 + // + this.label2.BackColor = System.Drawing.SystemColors.Control; + this.label2.Dock = System.Windows.Forms.DockStyle.Bottom; + this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label2.ForeColor = System.Drawing.Color.DarkBlue; + this.label2.Location = new System.Drawing.Point(0, 370); + this.label2.Name = "label2"; + this.label2.Padding = new System.Windows.Forms.Padding(10, 0, 0, 0); + this.label2.Size = new System.Drawing.Size(648, 75); + this.label2.TabIndex = 48; + this.label2.Text = "In the designer you can click and drag to move the chart, or single click to sele" + + "ct individual elements for design.\r\nContext menus are also available for each se" + + "lected item."; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // pageSlider1 + // + this.pageSlider1.Controls.Add(this.pageSliderPage1); + this.pageSlider1.Controls.Add(this.pageSliderPage2); + this.pageSlider1.Controls.Add(this.pageSliderPage3); + this.pageSlider1.Controls.Add(this.pageSliderPage4); + this.pageSlider1.Controls.Add(this.pageSliderPage5); + this.pageSlider1.Location = new System.Drawing.Point(2, 2); + this.pageSlider1.Name = "pageSlider1"; + this.pageSlider1.SelectedPage = this.pageSliderPage1; + this.pageSlider1.Size = new System.Drawing.Size(644, 379); + this.pageSlider1.TabIndex = 49; + this.pageSlider1.Text = "pageSlider1"; + // + // pageSliderPage1 + // + this.pageSliderPage1.Controls.Add(this.cbStepLine); + this.pageSliderPage1.Controls.Add(this.cbBlankChart); + this.pageSliderPage1.Controls.Add(this.cbMultiAxis); + this.pageSliderPage1.Controls.Add(this.cbPointPlot); + this.pageSliderPage1.Controls.Add(this.cbLinePlot); + this.pageSliderPage1.Controls.Add(this.cbLineArea); + this.pageSliderPage1.Location = new System.Drawing.Point(4, 8); + this.pageSliderPage1.Name = "pageSliderPage1"; + this.pageSliderPage1.Size = new System.Drawing.Size(538, 367); + this.pageSliderPage1.TabIndex = 3; + // + // cbStepLine + // + this.cbStepLine.Appearance = System.Windows.Forms.Appearance.Button; + this.cbStepLine.AutoSize = true; + this.cbStepLine.Image = ((System.Drawing.Image)(resources.GetObject("cbStepLine.Image"))); + this.cbStepLine.Location = new System.Drawing.Point(3, 182); + this.cbStepLine.Name = "cbStepLine"; + this.cbStepLine.Size = new System.Drawing.Size(166, 173); + this.cbStepLine.TabIndex = 50; + this.cbStepLine.Text = "Step Line"; + this.cbStepLine.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbStepLine.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbStepLine.UseVisualStyleBackColor = true; + this.cbStepLine.Click += new System.EventHandler(this.CbClicked); + // + // cbLineArea + // + this.cbLineArea.Appearance = System.Windows.Forms.Appearance.Button; + this.cbLineArea.AutoSize = true; + this.cbLineArea.Image = ((System.Drawing.Image)(resources.GetObject("cbLineArea.Image"))); + this.cbLineArea.Location = new System.Drawing.Point(175, 182); + this.cbLineArea.Name = "cbLineArea"; + this.cbLineArea.Size = new System.Drawing.Size(166, 173); + this.cbLineArea.TabIndex = 50; + this.cbLineArea.Text = "Line Area"; + this.cbLineArea.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbLineArea.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbLineArea.UseVisualStyleBackColor = true; + this.cbLineArea.Click += new System.EventHandler(this.CbClicked); + // + // pageSliderPage2 + // + this.pageSliderPage2.Controls.Add(this.cbRangeBarH); + this.pageSliderPage2.Controls.Add(this.cbRangeBarV); + this.pageSliderPage2.Controls.Add(this.cbBarH); + this.pageSliderPage2.Controls.Add(this.cbBubblePlot); + this.pageSliderPage2.Controls.Add(this.cbBarV); + this.pageSliderPage2.Controls.Add(this.cbMultiChart); + this.pageSliderPage2.Location = new System.Drawing.Point(590, 8); + this.pageSliderPage2.Name = "pageSliderPage2"; + this.pageSliderPage2.Size = new System.Drawing.Size(538, 367); + this.pageSliderPage2.TabIndex = 4; + // + // cbRangeBarH + // + this.cbRangeBarH.Appearance = System.Windows.Forms.Appearance.Button; + this.cbRangeBarH.AutoSize = true; + this.cbRangeBarH.Image = ((System.Drawing.Image)(resources.GetObject("cbRangeBarH.Image"))); + this.cbRangeBarH.Location = new System.Drawing.Point(347, 182); + this.cbRangeBarH.Name = "cbRangeBarH"; + this.cbRangeBarH.Size = new System.Drawing.Size(166, 173); + this.cbRangeBarH.TabIndex = 50; + this.cbRangeBarH.Text = "Horizontal Range Bar"; + this.cbRangeBarH.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbRangeBarH.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbRangeBarH.UseVisualStyleBackColor = true; + this.cbRangeBarH.Click += new System.EventHandler(this.CbClicked); + // + // cbRangeBarV + // + this.cbRangeBarV.Appearance = System.Windows.Forms.Appearance.Button; + this.cbRangeBarV.AutoSize = true; + this.cbRangeBarV.Image = ((System.Drawing.Image)(resources.GetObject("cbRangeBarV.Image"))); + this.cbRangeBarV.Location = new System.Drawing.Point(347, 3); + this.cbRangeBarV.Name = "cbRangeBarV"; + this.cbRangeBarV.Size = new System.Drawing.Size(166, 173); + this.cbRangeBarV.TabIndex = 50; + this.cbRangeBarV.Text = "Vertical Range Bar"; + this.cbRangeBarV.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbRangeBarV.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbRangeBarV.UseVisualStyleBackColor = true; + this.cbRangeBarV.Click += new System.EventHandler(this.CbClicked); + // + // cbBarH + // + this.cbBarH.Appearance = System.Windows.Forms.Appearance.Button; + this.cbBarH.AutoSize = true; + this.cbBarH.Image = ((System.Drawing.Image)(resources.GetObject("cbBarH.Image"))); + this.cbBarH.Location = new System.Drawing.Point(175, 182); + this.cbBarH.Name = "cbBarH"; + this.cbBarH.Size = new System.Drawing.Size(166, 173); + this.cbBarH.TabIndex = 50; + this.cbBarH.Text = "Horizontal Bar"; + this.cbBarH.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbBarH.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbBarH.UseVisualStyleBackColor = true; + this.cbBarH.Click += new System.EventHandler(this.CbClicked); + // + // cbBarV + // + this.cbBarV.Appearance = System.Windows.Forms.Appearance.Button; + this.cbBarV.AutoSize = true; + this.cbBarV.Image = ((System.Drawing.Image)(resources.GetObject("cbBarV.Image"))); + this.cbBarV.Location = new System.Drawing.Point(175, 3); + this.cbBarV.Name = "cbBarV"; + this.cbBarV.Size = new System.Drawing.Size(166, 173); + this.cbBarV.TabIndex = 50; + this.cbBarV.Text = "Vertical Bar"; + this.cbBarV.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbBarV.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbBarV.UseVisualStyleBackColor = true; + this.cbBarV.Click += new System.EventHandler(this.CbClicked); + // + // pageSliderPage3 + // + this.pageSliderPage3.Controls.Add(this.cbHiLoHBox); + this.pageSliderPage3.Controls.Add(this.cbHiLoVBox); + this.pageSliderPage3.Controls.Add(this.cbHiLoHLine); + this.pageSliderPage3.Controls.Add(this.cbHiLoVLine); + this.pageSliderPage3.Controls.Add(this.cbVDotPlot); + this.pageSliderPage3.Controls.Add(this.cbHDotPlot); + this.pageSliderPage3.Location = new System.Drawing.Point(1176, 8); + this.pageSliderPage3.Name = "pageSliderPage3"; + this.pageSliderPage3.Size = new System.Drawing.Size(538, 367); + this.pageSliderPage3.TabIndex = 5; + // + // cbHiLoHBox + // + this.cbHiLoHBox.Appearance = System.Windows.Forms.Appearance.Button; + this.cbHiLoHBox.AutoSize = true; + this.cbHiLoHBox.Image = ((System.Drawing.Image)(resources.GetObject("cbHiLoHBox.Image"))); + this.cbHiLoHBox.Location = new System.Drawing.Point(175, 182); + this.cbHiLoHBox.Name = "cbHiLoHBox"; + this.cbHiLoHBox.Size = new System.Drawing.Size(166, 173); + this.cbHiLoHBox.TabIndex = 11; + this.cbHiLoHBox.Text = "Horizontal HiLoBar (Box)"; + this.cbHiLoHBox.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbHiLoHBox.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbHiLoHBox.UseVisualStyleBackColor = true; + this.cbHiLoHBox.Click += new System.EventHandler(this.CbClicked); + // + // cbHiLoVBox + // + this.cbHiLoVBox.Appearance = System.Windows.Forms.Appearance.Button; + this.cbHiLoVBox.AutoSize = true; + this.cbHiLoVBox.Image = ((System.Drawing.Image)(resources.GetObject("cbHiLoVBox.Image"))); + this.cbHiLoVBox.Location = new System.Drawing.Point(175, 3); + this.cbHiLoVBox.Name = "cbHiLoVBox"; + this.cbHiLoVBox.Size = new System.Drawing.Size(166, 173); + this.cbHiLoVBox.TabIndex = 10; + this.cbHiLoVBox.Text = "Vertical HiLoBar (Box)"; + this.cbHiLoVBox.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbHiLoVBox.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbHiLoVBox.UseVisualStyleBackColor = true; + this.cbHiLoVBox.Click += new System.EventHandler(this.CbClicked); + // + // cbHiLoHLine + // + this.cbHiLoHLine.Appearance = System.Windows.Forms.Appearance.Button; + this.cbHiLoHLine.AutoSize = true; + this.cbHiLoHLine.Image = ((System.Drawing.Image)(resources.GetObject("cbHiLoHLine.Image"))); + this.cbHiLoHLine.Location = new System.Drawing.Point(6, 182); + this.cbHiLoHLine.Name = "cbHiLoHLine"; + this.cbHiLoHLine.Size = new System.Drawing.Size(166, 173); + this.cbHiLoHLine.TabIndex = 9; + this.cbHiLoHLine.Text = "Horizontal HiLoBar (Line)"; + this.cbHiLoHLine.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbHiLoHLine.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbHiLoHLine.UseVisualStyleBackColor = true; + this.cbHiLoHLine.Click += new System.EventHandler(this.CbClicked); + // + // cbHiLoVLine + // + this.cbHiLoVLine.Appearance = System.Windows.Forms.Appearance.Button; + this.cbHiLoVLine.AutoSize = true; + this.cbHiLoVLine.Image = ((System.Drawing.Image)(resources.GetObject("cbHiLoVLine.Image"))); + this.cbHiLoVLine.Location = new System.Drawing.Point(3, 3); + this.cbHiLoVLine.Name = "cbHiLoVLine"; + this.cbHiLoVLine.Size = new System.Drawing.Size(166, 173); + this.cbHiLoVLine.TabIndex = 8; + this.cbHiLoVLine.Text = "Vertical HiLoBar (Line)"; + this.cbHiLoVLine.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbHiLoVLine.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbHiLoVLine.UseVisualStyleBackColor = true; + this.cbHiLoVLine.Click += new System.EventHandler(this.CbClicked); + // + // pageSliderPage4 + // + this.pageSliderPage4.Controls.Add(this.cbPieMultiRingRev); + this.pageSliderPage4.Controls.Add(this.cbPieMultiRing); + this.pageSliderPage4.Controls.Add(this.cbPieExtentFill); + this.pageSliderPage4.Controls.Add(this.cbPieExtent); + this.pageSliderPage4.Controls.Add(this.cbPieDonut); + this.pageSliderPage4.Controls.Add(this.cbPieSimple); + this.pageSliderPage4.Location = new System.Drawing.Point(1762, 8); + this.pageSliderPage4.Name = "pageSliderPage4"; + this.pageSliderPage4.Size = new System.Drawing.Size(538, 367); + this.pageSliderPage4.TabIndex = 6; + // + // cbPieMultiRingRev + // + this.cbPieMultiRingRev.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieMultiRingRev.AutoSize = true; + this.cbPieMultiRingRev.Image = ((System.Drawing.Image)(resources.GetObject("cbPieMultiRingRev.Image"))); + this.cbPieMultiRingRev.Location = new System.Drawing.Point(350, 182); + this.cbPieMultiRingRev.Name = "cbPieMultiRingRev"; + this.cbPieMultiRingRev.Size = new System.Drawing.Size(166, 173); + this.cbPieMultiRingRev.TabIndex = 16; + this.cbPieMultiRingRev.Text = "Multi Ring Reversed"; + this.cbPieMultiRingRev.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieMultiRingRev.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieMultiRingRev.UseVisualStyleBackColor = true; + this.cbPieMultiRingRev.Click += new System.EventHandler(this.CbClicked); + // + // cbPieMultiRing + // + this.cbPieMultiRing.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieMultiRing.AutoSize = true; + this.cbPieMultiRing.Image = ((System.Drawing.Image)(resources.GetObject("cbPieMultiRing.Image"))); + this.cbPieMultiRing.Location = new System.Drawing.Point(350, 5); + this.cbPieMultiRing.Name = "cbPieMultiRing"; + this.cbPieMultiRing.Size = new System.Drawing.Size(166, 173); + this.cbPieMultiRing.TabIndex = 15; + this.cbPieMultiRing.Text = "Multi Ring"; + this.cbPieMultiRing.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieMultiRing.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieMultiRing.UseVisualStyleBackColor = true; + this.cbPieMultiRing.Click += new System.EventHandler(this.CbClicked); + // + // cbPieExtentFill + // + this.cbPieExtentFill.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieExtentFill.AutoSize = true; + this.cbPieExtentFill.Image = ((System.Drawing.Image)(resources.GetObject("cbPieExtentFill.Image"))); + this.cbPieExtentFill.Location = new System.Drawing.Point(178, 182); + this.cbPieExtentFill.Name = "cbPieExtentFill"; + this.cbPieExtentFill.Size = new System.Drawing.Size(166, 173); + this.cbPieExtentFill.TabIndex = 14; + this.cbPieExtentFill.Text = "Pie Chart - Extent Fill"; + this.cbPieExtentFill.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieExtentFill.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieExtentFill.UseVisualStyleBackColor = true; + this.cbPieExtentFill.Click += new System.EventHandler(this.CbClicked); + // + // cbPieExtent + // + this.cbPieExtent.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieExtent.AutoSize = true; + this.cbPieExtent.Image = ((System.Drawing.Image)(resources.GetObject("cbPieExtent.Image"))); + this.cbPieExtent.Location = new System.Drawing.Point(178, 5); + this.cbPieExtent.Name = "cbPieExtent"; + this.cbPieExtent.Size = new System.Drawing.Size(166, 173); + this.cbPieExtent.TabIndex = 13; + this.cbPieExtent.Text = "Pie Chart - Varried Extent"; + this.cbPieExtent.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieExtent.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieExtent.UseVisualStyleBackColor = true; + this.cbPieExtent.Click += new System.EventHandler(this.CbClicked); + // + // cbPieDonut + // + this.cbPieDonut.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieDonut.AutoSize = true; + this.cbPieDonut.Image = ((System.Drawing.Image)(resources.GetObject("cbPieDonut.Image"))); + this.cbPieDonut.Location = new System.Drawing.Point(6, 182); + this.cbPieDonut.Name = "cbPieDonut"; + this.cbPieDonut.Size = new System.Drawing.Size(166, 173); + this.cbPieDonut.TabIndex = 12; + this.cbPieDonut.Text = "Donut"; + this.cbPieDonut.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieDonut.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieDonut.UseVisualStyleBackColor = true; + this.cbPieDonut.Click += new System.EventHandler(this.CbClicked); + // + // cbPieSimple + // + this.cbPieSimple.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieSimple.AutoSize = true; + this.cbPieSimple.Image = ((System.Drawing.Image)(resources.GetObject("cbPieSimple.Image"))); + this.cbPieSimple.Location = new System.Drawing.Point(6, 5); + this.cbPieSimple.Name = "cbPieSimple"; + this.cbPieSimple.Size = new System.Drawing.Size(166, 173); + this.cbPieSimple.TabIndex = 11; + this.cbPieSimple.Text = "Pie Chart"; + this.cbPieSimple.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieSimple.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieSimple.UseVisualStyleBackColor = true; + this.cbPieSimple.Click += new System.EventHandler(this.CbClicked); + // + // pageSliderPage5 + // + this.pageSliderPage5.Controls.Add(this.cbPieOverlay); + this.pageSliderPage5.Controls.Add(this.cbPieGridAngle); + this.pageSliderPage5.Controls.Add(this.cbPieShowSingleRing); + this.pageSliderPage5.Controls.Add(this.cbPieMultiSeries); + this.pageSliderPage5.Location = new System.Drawing.Point(2348, 8); + this.pageSliderPage5.Name = "pageSliderPage5"; + this.pageSliderPage5.Size = new System.Drawing.Size(538, 367); + this.pageSliderPage5.TabIndex = 7; + // + // cbPieOverlay + // + this.cbPieOverlay.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieOverlay.AutoSize = true; + this.cbPieOverlay.Image = ((System.Drawing.Image)(resources.GetObject("cbPieOverlay.Image"))); + this.cbPieOverlay.Location = new System.Drawing.Point(178, 184); + this.cbPieOverlay.Name = "cbPieOverlay"; + this.cbPieOverlay.Size = new System.Drawing.Size(166, 173); + this.cbPieOverlay.TabIndex = 16; + this.cbPieOverlay.Text = "PieChart - Series Overlay"; + this.cbPieOverlay.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieOverlay.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieOverlay.UseVisualStyleBackColor = true; + this.cbPieOverlay.Click += new System.EventHandler(this.CbClicked); + // + // cbPieGridAngle + // + this.cbPieGridAngle.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieGridAngle.AutoSize = true; + this.cbPieGridAngle.Image = ((System.Drawing.Image)(resources.GetObject("cbPieGridAngle.Image"))); + this.cbPieGridAngle.Location = new System.Drawing.Point(178, 5); + this.cbPieGridAngle.Name = "cbPieGridAngle"; + this.cbPieGridAngle.Size = new System.Drawing.Size(166, 173); + this.cbPieGridAngle.TabIndex = 15; + this.cbPieGridAngle.Text = "PieChart - Angle Margin"; + this.cbPieGridAngle.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieGridAngle.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieGridAngle.UseVisualStyleBackColor = true; + this.cbPieGridAngle.Click += new System.EventHandler(this.CbClicked); + // + // cbPieShowSingleRing + // + this.cbPieShowSingleRing.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieShowSingleRing.AutoSize = true; + this.cbPieShowSingleRing.Image = ((System.Drawing.Image)(resources.GetObject("cbPieShowSingleRing.Image"))); + this.cbPieShowSingleRing.Location = new System.Drawing.Point(6, 184); + this.cbPieShowSingleRing.Name = "cbPieShowSingleRing"; + this.cbPieShowSingleRing.Size = new System.Drawing.Size(166, 173); + this.cbPieShowSingleRing.TabIndex = 13; + this.cbPieShowSingleRing.Text = "Multi Ring, Single Display"; + this.cbPieShowSingleRing.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieShowSingleRing.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieShowSingleRing.UseVisualStyleBackColor = true; + this.cbPieShowSingleRing.Click += new System.EventHandler(this.CbClicked); + // + // cbPieMultiSeries + // + this.cbPieMultiSeries.Appearance = System.Windows.Forms.Appearance.Button; + this.cbPieMultiSeries.AutoSize = true; + this.cbPieMultiSeries.Image = ((System.Drawing.Image)(resources.GetObject("cbPieMultiSeries.Image"))); + this.cbPieMultiSeries.Location = new System.Drawing.Point(6, 5); + this.cbPieMultiSeries.Name = "cbPieMultiSeries"; + this.cbPieMultiSeries.Size = new System.Drawing.Size(166, 173); + this.cbPieMultiSeries.TabIndex = 12; + this.cbPieMultiSeries.Text = "Multi Series"; + this.cbPieMultiSeries.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.cbPieMultiSeries.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText; + this.cbPieMultiSeries.UseVisualStyleBackColor = true; + this.cbPieMultiSeries.Click += new System.EventHandler(this.CbClicked); + // + // ChartStyleDialog + // + this.AcceptButton = this.btnOk; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(648, 500); + this.ControlBox = false; + this.Controls.Add(this.pageSlider1); + this.Controls.Add(this.label2); + this.Controls.Add(this.btnOk); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ChartStyleDialog"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Initial Chart Style"; + this.pageSlider1.ResumeLayout(false); + this.pageSliderPage1.ResumeLayout(false); + this.pageSliderPage1.PerformLayout(); + this.pageSliderPage2.ResumeLayout(false); + this.pageSliderPage2.PerformLayout(); + this.pageSliderPage3.ResumeLayout(false); + this.pageSliderPage3.PerformLayout(); + this.pageSliderPage4.ResumeLayout(false); + this.pageSliderPage4.PerformLayout(); + this.pageSliderPage5.ResumeLayout(false); + this.pageSliderPage5.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.CheckBox cbLinePlot; + private System.Windows.Forms.CheckBox cbPointPlot; + private System.Windows.Forms.Button btnOk; + private System.Windows.Forms.CheckBox cbBlankChart; + private System.Windows.Forms.CheckBox cbMultiAxis; + private System.Windows.Forms.CheckBox cbMultiChart; + private System.Windows.Forms.CheckBox cbHDotPlot; + private System.Windows.Forms.CheckBox cbVDotPlot; + private System.Windows.Forms.CheckBox cbBubblePlot; + private System.Windows.Forms.Label label2; + private DotNetBar.Controls.PageSlider pageSlider1; + private DotNetBar.Controls.PageSliderPage pageSliderPage1; + private System.Windows.Forms.CheckBox cbStepLine; + private DotNetBar.Controls.PageSliderPage pageSliderPage2; + private System.Windows.Forms.CheckBox cbRangeBarV; + private System.Windows.Forms.CheckBox cbBarH; + private System.Windows.Forms.CheckBox cbBarV; + private System.Windows.Forms.CheckBox cbLineArea; + private System.Windows.Forms.CheckBox cbRangeBarH; + private DotNetBar.Controls.PageSliderPage pageSliderPage3; + private System.Windows.Forms.CheckBox cbHiLoHBox; + private System.Windows.Forms.CheckBox cbHiLoVBox; + private System.Windows.Forms.CheckBox cbHiLoHLine; + private System.Windows.Forms.CheckBox cbHiLoVLine; + private DotNetBar.Controls.PageSliderPage pageSliderPage4; + private System.Windows.Forms.CheckBox cbPieSimple; + private System.Windows.Forms.CheckBox cbPieMultiRing; + private System.Windows.Forms.CheckBox cbPieExtentFill; + private System.Windows.Forms.CheckBox cbPieExtent; + private System.Windows.Forms.CheckBox cbPieDonut; + private System.Windows.Forms.CheckBox cbPieMultiRingRev; + private DotNetBar.Controls.PageSliderPage pageSliderPage5; + private System.Windows.Forms.CheckBox cbPieShowSingleRing; + private System.Windows.Forms.CheckBox cbPieMultiSeries; + private System.Windows.Forms.CheckBox cbPieGridAngle; + private System.Windows.Forms.CheckBox cbPieOverlay; + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartStyleDialog.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartStyleDialog.cs new file mode 100644 index 00000000..13fa2af2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartStyleDialog.cs @@ -0,0 +1,60 @@ +using System; +using System.Windows.Forms; + +namespace DevComponents.Charts.Design +{ + public partial class ChartStyleDialog : Form + { + #region Private variables + + private CheckBox _CheckedBox; + private DateTime _LastClick; + + #endregion + + public ChartStyleDialog() + { + InitializeComponent(); + + _CheckedBox = cbPointPlot; + } + + #region Public properties + + public string CbSelected + { + get { return (_CheckedBox.Name); } + } + + #endregion + + #region CbClicked + + private void CbClicked(object sender, EventArgs e) + { + CheckBox cb = sender as CheckBox; + + if (cb != null) + { + if (_CheckedBox != cb) + { + _CheckedBox.Checked = false; + + _CheckedBox = cb; + _CheckedBox.Checked = true; + } + else + { + TimeSpan ts = DateTime.Now - _LastClick; + + if (ts.TotalMilliseconds < SystemInformation.DoubleClickTime) + btnOk.PerformClick(); + } + } + + _LastClick = DateTime.Now; + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartStyleDialog.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartStyleDialog.resx new file mode 100644 index 00000000..e1f25785 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartStyleDialog.resx @@ -0,0 +1,5463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QECRXhpZgAATU0AKgAAAAgABwEaAAUAAAABAAAAYgEbAAUAAAAB + AAAAagEoAAMAAAABAAIAAAExAAIAAAAQAAAAcgE7AAIAAAAIAAAAgodpAAQAAAABAAAAipydAAEAAAAQ + AAAA6gAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMC42AEJyaWFudGEAAASQAwACAAAAFAAA + AMCQBAACAAAAFAAAANSSkQACAAAAAzc3AACSkgACAAAAAzc3AAAAAAAAMjAxNTowOTowMyAxMTo0MToy + OAAyMDE1OjA5OjAzIDExOjQxOjI4AAAAQgByAGkAYQBuAHQAYQAAAP/bAEMAAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/A + ABEIAJYAoAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMD + AgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp + KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOk + paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQAD + AQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFR + B2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ + WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfI + ycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP6d/gj+zb8CNd+GnhG913Rt + B0FodB+03useJPH3xN0ywvGvfGnj/wAPaPpdhZaP8SPCukaYulaV4LWOKG2if7VEykQwm2lkm9A1X9nf + 9lPRNSXSdVv/AATZXcmiP4jgaXxj8eDZXOioyL9ttdRT40Pp90JGkjS3t7e5kurp3VLaCVztr1D9kO91 + b/hW+gzWGgtcXTeC9LVrHUNQtbFkj/4Wn8cC8n2i1/tWIvGxjBjGc78hwRg+oePJ7r/hKIzrvwHsvHll + PpNjJJeWfh+HWr7T7oyXouLWbVdQ037JfRhI0ks7W1SMQQ2N7JqF3b32r+GdI1nqoRw8n++9pbldvZVq + dOXNaHLeE07xbeuzkl7sk1demsNja84UMBTy7ndChUj9bqYaHN+6oTrc06+Io8snKclTU5Rjo4wjK3Kf + L8n7PH7J0F9f6Ze6z8O9L1DTLoWV9aax8QfjXo00F211qlpHbFNU+OFp5k00ui6lJAkPmGe0t1v4d9jc + WtxNu6b+yl+zTq+k2+u6fdfD6fR7p4o4NSHxE+My2kks9nBqEUImb45hFuHsLq2vBbsVn+y3EM5jEcqM + fUvCMC6vrtta69+x/pOg3t/eWV9q3ic6Z4UfSoxqF9qMBvFuZNHt9XvdQs9Kkaa+S6srG7+03FzbTCC3 + ntru9+n7Lw/pnhHTodN8F+DtH06yDhv7M0xLPQbCH90kYkSCztXgLhIYotojT5I4+SEUVOL+q0qLdD2/ + trwt7SpGrBJKPP7tB87fNrC32d7ONzKvRzLL8TCjjqWTzhLmd8FWweKbXNaD9rha+Kow0UW1N3km5LR3 + PgK8/Zg/Zj06fU7a/uPA1jNpEVjPfLe+OfjfZoIdTsRqVhJbS3PxvihvkurFhPE1jJcBlO3If5ahT9mL + 9mZbeK/nl8HW+l3y289jq194x+OdhosourWS4isodau/jXBpk2pGC0ur2TShdtqsFqklxNaR2y+bX1D4 + 4ku7DXLrUZv2f4PG/wBqhggbWNOt9GvNWmNro5uRFeG8tPtD2ljJJcabZzLJcS3Ek/k29pGYilza8Kw2 + viXU7LTtf+AEOgWVnJNCupajb6Fc2tjdWVvcTxzWlsLSOT7FdSXE4srr9xdGS9Y3FnbyGdU+cePxUqsq + VN0FLn5Ic+FzVRT5oxTnU5FTUbtXkpqNle6SuvSUsu9jCpKjUT5KbquE8skr+yj7T2cdZtSqpygmuaMG + oyUpJuXzFY/ssfszan5rWF38P7qO3099UupoPiF8aJLeysEuIbT7Tfzp8cjFYpJdTpbxC7eFpZVmSNWa + 3n8uO8/Zd/ZjsH0xbq78BpFrCag+nXq+PPjbJpk40p7KK/B1SP43tp8LwS6jZReXPcxSSS3MUUSvI22v + 0D0nwd4T0G5kvNE8LaNpF3NAtrLc6bpthZTy2yyidbeSW2WN5IBMBKImYp5nz7d3NLrvg/wn4oFoPEnh + XRdfFhJJLYjWdL07UxZyzR+VLLaC8WYW8ksX7uR4djPGAjEqAK9SnKv7L966Htk3/DlW9m4prl+KfMpN + L3t0ntdHjY/ET53/AGZTwyp8kbLH4aEpupze9eWHcYqHJpH3ZS5ved03E/Oe0/Z2/ZRv7O51Gx1TwBea + faXd9YXGoW3jz43TWEV5p0Nnc3du18nxuNp5sdtf2tyg879/byGeDzIopnj29E/ZZ/Zt1i+8PPo+meFP + GWjat4hn8P3tz4V+Jfxkl+yTR6B4h1dXjv4fjDrdm0iXGhm0lgaEkbpxvSSEofu4fDvwCtjcaYvgbwyN + Ou5muLuxGh6SLS5uGbe09xbiLyppmf52lkVnZ/mLEjNc1q/hzw74Uv8AwDF4c8N6ZokNz4+muLmDRrHT + 9NS5uG8DeNwZpkgNvFLMdxJklO8gn5ieDpFy5mnyOO0UpT5m7q105W2S23fTRHNgqmZ1K1GnjKeUulKh + V+sPD0K1OoqqoyalQc5SSipRT95qSu/ie/jVl+w1+zFJZ20knw/1d5JIIpHb/hZ/xaGWdAxOF8dADk9A + OOlWv+GF/wBl/wD6J7q//h0Pi3/83dfT9hdTCxsx/Z94cWtuMh7Eg4iTkZvQf0FW/tc3/QOvf++rH/5N + qylsj5V/4YX/AGX/APonur/+HQ+Lf/zd0h/YY/ZeUZPw+1fqB/yVD4t9z/2PdfVZu5R10+9H1aw/+Tq8 + F8Y69qPxI1TXfh/4fvtV0HwloaTWfxN8eeGvFOk6N4h8Pavbjw5rsHgjSp0+1XWnXut+GNUkufEHiC1u + 9H1Hwzo9/YT+H9Si1+8jvdE5cVio4aCfK6lWo3ChRi0p1alm1FX+GMUnOpUa5KVOM6k2oQbNaVN1ZWvy + xiuac2rqEb2bstZPW0YRvKcmoxTbPCNU/Zu/YY03XNN8L3K6HZ+JtV1iXRtP0G5+O3j+HWb7UtOXTbzV + 9LtNNl+JIvZ9QsNM1OyvL2zhga6trO/tLmWNYbiN29FX9hn9l1hlfh9q5Hr/AMLQ+Lf/AM3dd1J8NfCG + veFtV0WbwDpumeEdae8Wy8MRaHoFtZPJr10P7V8R6lpMmbSfXdceeWaQ6jaT3C29xImoILrUdVt653wH + q+t/DbVNJ8G3dhr154G1i5tPC3hKys9LGoD4Y694f8Pyy6j4b8Qa/ca1fao/hHxHa6b/AG54F1nXYHls + XvW0LUtZSHVfBemDhhjcXRqweNp0fq1eUIUquH570p1HCEI1o1LOdOdR8sa8ORx54OpQjT9pVpbOjSqR + aoOp7SCblCpyvnS5pPkcUlGUYaum+Ze5O1ST5Yyyf+GF/wBl/wD6J7q//h0Pi3/83dH/AAwv+y//ANE9 + 1f8A8Oh8W/8A5u6+qvtcx6afe/8AfVj/APJtH2ub/oHXv/fVj/8AJtewch8q/wDDC/7L/wD0T3V//Dof + Fv8A+buvD/2h/wBjr9nbwt8G/ilr2ieBtRt9T0XwZPqOnyXPxA+JWq2q3KyTqwutM1bxhfaZqNrNGvk3 + NjqNndWN1AzwXNvLFJIjfePjLx9oHgHw9qfijxVJcaVo+k20tzczGOK8u5fKieVbXTtL0+e71TV9SuAj + JY6TpVnealqE+22sbW4uHSJvkf4s+JviV4u+A3x88UeK/DkPhTwdrfw60u48AeGLyxuLfx9pmmXFjc3u + o6h8RjdX6Wel6xd3V5DZx+ENM026fw5HpMk2oeItWvdWl0zQFzLm5b+9a9u0bbvsm7JX3bVr624546hD + GUsCnKpiasJVZU6Uef2FCMZv2+Jd0qNKco+ypOT5q1V8lKM+Wbh1P7MPgnwj4j+BHwxvPEPhjw5rtzHb + +L7aKfWdD03U54rdfHfiWUQxzXtvO6RCSWRxGpCB3dwNzsT9Cf8ACp/hh/0TrwJ/4SGgf/IFfNH7OXgU + eJP2bvhFZ2fizxz4UudJ1PxNq9pqvhjxLcwX0ktr428To1jqUerJq+m63pN3DcSxXemazp9/aufJuolg + vrOyurf04XXxv8BQp/wkOi2fxl0K2t9Qnutb8EX0vg3x/H5W99OtB4E1/XLjwv4hleFQL/V7Dx14allu + X26d4N27Ixy1sdPD1OWphsQ6Fo2xNCn9YhH4VapSpKWJhZ/ajRqU1GPPUqQW3s0JV3TjCjjp03DSNCWI + q0Uo3v8Au5ykqFla/I6kJ3tGEJXPSf8AhU/ww/6J14E/8JDQP/kCj/hU/wAMP+ideBP/AAkNA/8AkCsj + wf8AFH4deNb240XSfEc9t4qsbawutV8F65Pq/h/xpo8WqWv2yybU/C2stZa1bRzQiVY7k2bWkk1teQRX + EktpcLH6ULS3IyJrwjr/AMf19/8AH62oYqhiYRqYevSrQle0qU4TV4tJr3b2lFpRlF2lGStJJqxNTEY6 + jJwq4jF05KztKtWi7OzT96SumknF7NWa3OM/4VP8MP8AonXgT/wkNA/+QKq2/wAKfhk0t8G+HngUhLpV + UHwjoHyr9jtGwP8AQOBuZjj1JPeu/wDsMX/PS8/8D73/AOP1UtrOIy3w33YxdqOL69BP+h2hyf3/ACec + Z9ABW135fcv8iPreL/6CsT/4Pq+X9/yRyv8Awqf4Yf8AROvAn/hIaB/8gUf8Kn+GH/ROvAn/AISGgf8A + yBXZm0gXOZbwY6/6dff/AB+vLfHfxU8AeAZX0zUdX1LVvFraTJrem/D7wqdY8U/ETXNMi1Gz0iW+0TwV + or3evX9hBqOo2dve6qLOPR9LSSS91bUbCwtLu7txzUdZSjFaauyXRf5fgc+JzWWDpSr4rMamHowtzVKu + LnTitrJOVRXk2koxV5SekU27Pf8A+FT/AAw/6J14E/8ACQ0D/wCQKtWHw1+H2lX9pqul+BvB2m6pp8kk + 1hqNh4Z0azv7Gaa2nspZbS7trOK4tpJbO6ubWR4ZEaS2uJ4HJimkRvBJ/G/xe8S6ubHQtJ0TwZZ6f4j0 + 4y6bLeat8TfHWveGRA1xqtnqVrpHiHwf4F+EXiG6wsOi3fiTxr4ztnjF1LJo8t3DHp0sWm/s/fEHXGs5 + /iJ8fPjJerDpmpabdWXh7xpbeEZdUj1G5vJvtN5e/DzQfAttp1zbWl6un2LaLpkGt6VHp9jPD4wv7+Ob + UrrN1Zu3JTlJNtKUlGEXa17N3dk1ZNpXtppqeQ+JMfieanl+DzbGxcpUpVa1f6lhfdnTpVI1PrVVYqOk + pS5ZYJ+0p0pTipU6lGVb6s0//jxs/wDr2g/9FrVuvke8/Z28X6fbHUfhh+0B8afCd/dWHhyL7D4l8Z3P + xM0WO28P2FraxWdhb/EePxVJp0uuxW6R+I9Yl/tPVr6R7jUUmh1e4nv5VT4p/FT4bXn2T44fDrULzw5L + f+KbyT4rfCeXVNe8G+GvDWl6XBrOkf8ACY+GLjXb/wCIVpeyxLq+lXeraNoGraRLfaXZ3skOkw62tlpk + e1cf4sJU1/NpOCXS8o/D53SS6s5v7cqYWXLm+V4zLad1F46Dhj8tXNVdODqYnC3rYaFuSpUr43CYXDUo + z9+uuSbj7p8SPE2o+HtBii0KwvtS8S+INT07w3oMNhpzar/Z17rV5DYv4l1S0+1afD/wj3hS1ml8Ra61 + zqOnxz2Gnyadb3Q1K/sIZ8LwN4UtbHRdJ8N21zJqWi6Fs/trXbmC1i1L4geMICj6z4j1w2MFrZzTXmsx + z6prNxFCDq/iCWZW8izspY9U8p8C3ui/HLxbdfE3w/qOma74OsIdQ8L/AA68ZeH9Y8STO/hG+/sb/hNL + yG4ub220+PVfFHifQTp2kXui2LTWng3RLTxHa69dWfjDQwn1FbaVZWkEFtbCeCCCGKCGKG6u4Yo4oYxH + HHFGkypHHHGoVEQBUQBVAAArzsI/r9aePvfDvmo4RqUnCdGMo81WCTUWsVOKn7SPMp0IUIp2lUR9TUkq + dKFKDV5Wq1WukmvchdSkm6UXZbctSdT4lGnNzXoxFEBx/pdj0H/T9bfWvNviF4P0LxDa6loviWza+8I+ + OrJfDPia2S4uLN4L2Zwnh/WrW8tJre503UI7to9Pg1WwkTVbXU28NXlpc2h0iOeP0C9s4hHH892c3VkO + b69OM3tuMjM/BGc/UA9QKi1TRtOv7C7sb5r1rS6t5ILjGo6hGwjlUqTHJHcrJDIv345o2WSJ1WSNldVY + ehiKEcRSlSlCM001yTV6c04uMqVSLTUqdWDlTqRcXeEnZXSaxhNwkp3ceVp8ybTjZqSkn0lCSU4vpKKZ + wvwu8W6pq8GteEvFtzozfEHwPfNYeJrXRv7UjtptMv57u58GeI4IdYVrpbfxP4ajtNQnEF7rNlp+vJr3 + hxda1C+0HUHQ+I/xa8OfDyxla9kivdWZoLaw0eK5SO5vtUvneHR9HhVUmuJ9Z168T7D4e0HTrXUPEPiK + 88y10DR9TuILiOL5X+KnxRuPCOr+CfFHh+fxVqXiS5vr34ZX2g+E7YaprXxahvJLO803VvD9pI62tnp3 + gyGRPGc/j3W/M8C+DtA8S+I7ADVZdZurnS/b/hx8F5U1G28f/EmOG/8AF8w0vVNI8Lrqv/CT+G/hZq39 + gXGla7J4M8R3+j6P4h1nxBr76lqg8SeOtahj17XLGa10gJZaPp8Fm/Bl2InOE8K5c9XD2SqVLuUsNPWh + UnrJuvGKnh63O4yniqNWqqcKE4M8fMsdXxFf6rk0YSq1JuGKxbXNhcskowqVOZcqjUqSp1KNbB4VXnOl + isNOV8P7bF0sDwJ8Jdb8e+J9L+MXxwt/7S1mwk0LXvhj8Otb0nTIE+Dd8NCnttYubiPS9e8RaPqvjW9v + dUvo21WO+v4NC06x0iz0e4fUodW1rVei/amGPgD8ZwOg+H11/wCjbmvf/sEP/PS7/wDA69/+P188ftS2 + kafAT4zEPckr4AuWG68u3BPmXIwyvMVZe+1gynuK9SEIwVord3bespPRXk927JJdEkopJJI1y7LcPllK + dOhz1Ktao6+LxVeTq4rGYiSSlXxFaXvTlZKFOC5aOHoxp4fDU6WHpUqUMr9kK4uX/Z7+GbSWE8LFPGJ8 + tpbNmU/8Jx4hABaO5dCcYOQ2PfNfT3nXHezlx/10tv8A5Ir5u/ZH/wCTfvhp/u+Mf/U48Q19OVR6Bw/i + zwT4U8d2dpYeMfBuleJLXT9StNY06PWLDSr86bq9jv8AsWq6ZJcmSTTtTs/Mk+y6hZvDdwCSVY5lEkgb + y0fD74n+BhGfhj45v9Y0q1g1ORfBHxfurvxbaXVzOjvp9tp/xGS+fx3oUNvdmPzrnXB8REWwElvbaVDI + YriH6KpCcdf6f1NcVfL8LXn7ZwdLEaWxWHlKhidPhUqtNqVSCaX7qt7SjJLlnTlBuL2hiKtOPs01Kle7 + o1IqpSf/AG5K6i3/ADw5Jr7M09T5/f45z+F2EHxY8A+I/h6IzottL4ogMXjD4cXOo6taGaWOz8XaGPt+ + k6bp92k2nT6x8QPDHgO2kuBbeWmNQsRP1eqfFnwN4b8K6t491TxDpKeE7dL7Um1mzv7TVbe6ttL0Y6jf + DSo9MnurnWrmGw0+9uhZaTBe30sdrP5NtI0bKOL+IXxnvxr9x8Lvg/ocPjb4tyaQNTDatHrFp8MvBltJ + q1vpL3nxA8Z6VYahb2V9Ch1LUbDwZpn2jxVro0eW1EWi2d3HrkHmWnfsWfD46zfePL3Ub7/hcdt4n8Te + KdA+I2ladoej23gzxB4q0Kx065n8MeAoNMk8DyWunwQWMVrN4p0XxP4j1H7BDceI/Eet3slzdTcrlmdD + mVGVLM6cb39slhcTGzTko1qUfqmIq8r5YUXRwiuoqpiY88px8meaUcfUr4TKaaWIotU62Plz1sowlZpJ + 0qiU44jEV6aftKmGwtSs4XUcRVwspUlU1E+Ifxi+Md5ZT/Drw/qPgD4eJeeDNfsvFeuW8Wn+J/HeiXGl + HW9b8PS6N4m0eSTwBYXct1pWkDX7TSPG2vTC08S6cumeC7uTRfFcPf8AgD4HaH4O0uPT3XU7xBGUuo11 + TUJ59U3ahfao0niTxNruu67488ZTXF9qepXN8vivxbqul3k+oXko0e188xri2/jf4u/DW+ttG+JWmaP4 + u0Oe+8J+HtD+IHhjS9egl1jUtV0uVNU1Dxbomj6Rrdr4Hx4iszaWzXbL4Rt7bXNCF34yiujfxWvsenfE + Tw5e2dne3cs2jW9/b29zaXeqfZRpF1DeIslo9l4msLq+8LagbuJ1mt4tO1u6mkiJYRgo6reGx2Erycav + tKWKin7Sji4qlUpe8oyjya0uSUmlTlTqVKdaNpQqVE+Z5UuGvZ1YYvMMRLOsW41FDFzS+rwhVlGpUo4L + C0+WGHoJRpQq0JRnVl7ClLGyq4iCqvo7G0g0y0gsNO0hLCytUEVtaWkdhbW1vEM4igghlSKKMZJCIgAO + T1q751x/z5y/9/Lb/wCSKsK6sAVO4MAVKkEEEAhgQSCCDkEE8c9KfXppp7anqJKKUYpRjFWUUrJJaJJW + Vku3QyrGaf7FaYtJSPs0HO+2/wCea/8ATwK8d+M2r+JdQsdO+Gng+TXNF8VfEYX2l/8ACWaLBazzeAfD + draS3OveMJp3vIY7K5jhWPQvDUu9rk+KtZ0m5htp7Sw1F7fufF/jrw/8OfA994u8TXiWWk6NpD3s8jkg + yC2s3uGjiRVeWRxFDLK4hildIYppihjicjgvhL4Rv4LzxB8UvHdppi/ETxyRaS3dg2uLFpfw/wBI1XWr + vwL4dS28QNDLpVxb6dq0mo67bW2kaEZNbv7mLU7a/vrA6rd+Zj6rrTjllJtTxFOU8VUjNwlh8E7wm1KP + vRrYl82Hw7jKEoL22IjNPDcsuuhGNJfWqluWnJKjFpSVXELlcE09HCm3GdS6kn7tOUWqjtxWofsweGNI + 1a38VfCi61z4UeK59U8I3Piq+8MXNrDpvxA0fwnZ3OlQ6D4r0aK4t7JVudJult/7b0BdG1lZtI8MR6hc + avoGgW/hyfFt/jF8W/hnbw2/xh8GS7LTQ7jVtY8W6Ql94p8Dwi11WTTpwPGnhXw7aataXzWq2msLo+v/ + AAj8Naba2Oqi3j8a6vLourzReuX3x28LXYuLb4f6drvxV1KPT7+9g/4QW0trzww0unX02m3enXXxH1K7 + 034b6Zq1te2t3Hc6Pf8AiyDWoVs7hxpsjCFJuR/4TH4x+IpZT4esvAmkwG70K5t1022134o3Fxp4sp5f + E+lahqMepfDLwRomvW1/Ja2libXxd4liWGC5uZbK8N3bw2uLzHAUFClgvaV9owpYCk61BtRUlDnShhFN + RSbj9Zp1Fz0+eLVWmpefLgfHKrWxmCrrhqrVnWr4n61KNPDVa1avTnUxWKyZ/wC11JTrzq1KlfD0KCxL + qYurWqVqtLno47/tkfASX7TZ33j7w9pusaddeFxdaE+saPqerRT+KEbVvCtgLfw9qetRzav4l0yxu9R0 + XQ4Zn1q/sbW6uY9PCW8oXLn8W/Fz42qYPCvgTUvAfhK5bxLpUuvfE7TL7RLjSbrT7QR6XrL/AAx1BdO1 + r4hx3uqzLb2+j6pqngnwfFY2up6rJqvjZTotlL2ieE/2hrhVu774oeBtOdNRv5Laxj+G0mqxXEN62nR6 + AmouPFWlT239hXC3cl3BYX07astwsZ1K1WHMmfP45+O/gS1nfxz4O8JePLex0eKRtV8A3Vx4Un1jWjrE + C3ENlp3jHVLzw7omnRaDPNctdeLPHXh+FtYsV0+1uLy31MXmmJ5pUilLF4HMcLQ1ftHhqdS/Koy5ZxwW + LxtdcyvD+CruMmt48z/1RzXHpYarxfkWOXOoyweVUcVk2IxEXWbgqmPzeX1ZwVGCjWlgqtCpH2zr06tC + cYrC6tn8JPDPguHWNS1Gz1HxdcfEDTdP8L/GLxD4ru7PUNR8bWI0v+wLLUdVt08nSNL0uzkub4N4Z8N6 + d4e8G6PaeJvEl9p2i2KmSKXpvg/rWpwaNfeANahtv7f+G19J4ZMFvrQ1e/uPB8Mtwvw51/V577UbrUjq + viDwdBptzrU9/IHn8SQa8sBeGFTWtoXxR8DeN5b/AMNiW70/V2mv9IuPDXizSbzQL/UvJtg98dGg1eGC + 28W6MbSdJf7c8Kz65oFzbTpJBqU0cgJ+Wvih8ZrL4R+PbZtGt08a/EWw0HTfBvivwXpdhaw6l4i0jxJ4 + u0fQ/gt4r8X/ABCuLGdvDVjpPiHxBr2jQaddS3Woa/e+JfHF14P8G+JrzRljjfPQ9vRx2EqU6uH5nRxM + 6TpSjTpVJR9o6k9ORYerFYqs6lSLpU441uM6k1GPuZbw/j245DhMsq0a/LGtRw9SDwtKHPV/3zEYivKn + QpUa860lWzDF1I0J1atGtXxMY805fb+pazBo+n3uq6q0Om6Zp1rPfX+oX95YWllZWdrE01zd3d1cXccF + tbW8KPLPPNIkUUas7sqgmvjD4w/F3Tfih8Cv2gbnwtoev3HhCw+HuntofxDmg0+HwZ48j1e0utTe78CX + o1OXUPEejadaS2DS+JrfTIvDWqSX6Q+HtX1l7LVPsPX6Z8EPFHxT1eDxX8f/ABB/wkWjadrHiebwr8LN + Fj1nwr4Ck8O6zBBpunW3xI8Ir4i1rT/Ht/ZabDdGO38TS32nfaNX1G7l0jT2mtND0Hp/2oIVg/Z/+M0S + IiRp8PbhI0RQqIqPcKFRRwqqoCqigKoGAAK+glGnBOKlz1NNVdQiuy09+XfVJdmb47D5Nl+H+rUsS84z + OrBe2xOH9pQyvLZRrxlyYaVSEMRmderQg4Tr1KWFwmH9rUhTpYyoqWJp5X7IlhZx/s+fDNI4EVAnjABR + uwB/wm/iHjrX079itf8Aniv5t/jXzD+yHJfN+z38MjLa2ySbPGO5UvZJEB/4TjxD912somYY6Exqc8Y7 + n6K1jXrXw/p11q2t3OlaTpdkgku9R1LVY7GxtkaRY1ae6uYI4YgzuiKXdQ0jLGuWYZxv30XVvRL1b2Pn + 5TjCMpzlGEIpylKTUYxitXKUnZJJbtuy6mhJb2UasWSMbRkgvtOOvdvTnnj8K+Prnx34n/aMuZdA+A+q + yeG/hX5P/E5/aJ0l9Pu5r7U9L8Uy6dq3hD4ZaNrOj6haa0bvT9K1CO7+ILsNBsbbUtNvvC516adLqzSC + z8dftSSWuq63put/D39niVbDUNJ8L37eJfBXxU+JWq6Tr889tqviKWx1CxvvCvwx1SxstOu7LwjqVjbe + KfE1rfyf8JPa+H7SIaVffXOm2CaRZW+nabpmn2FhZwx29pZ2cn2e1treFAkUMEEVosUMSKAFjjVVUdOt + Y3lW+FuFLR8yfLUqdfcknenT7Ti1Od3yuCinP5vnxXEOlGdfA5DKLviKUp0MfnMJ2/3aonGrgMsnTuvr + UOXH4xVVLCTwFKjDE43j/h58KfAfwv0AeHPBfhrTNC0572+1S9Wyto4ZtU1jU7hrzVNb1SaJIzfatql3 + JJc317MDJNKwUbYo4407K2s7Yy32Yl+W7UDluB9jtDjr6k1c33f/ADwg/wDAp/8A5FqpbPdebf8A7iD/ + AI+xn/SX4/0O0/6dfTB7dfxOqSikopJLRJKyS7JI+gw+HoYWjSw2Go06GHowjTpUaMI06dOEVaMYQilG + KS2SRYbT7Ngwa3QhhhgckMOhU5PII4I6da8M1D4MTeFlu7/4J6hpngW5/sqSytvAt/phvPhBdXNx4j/4 + SC/1O48JaVLpV7oniDURda3p7694Z1TT45G1r+0vEOieLH0fSrKH3bfd/wDPCD/wKf8A+RaN93/z7wf+ + BT//ACLXPiMJQxSXtYe9Dm9nVhKVOtSclaTpVqbjUptpK/LJKVkpJpWOunWqUr8rTjK3NCaU6c7bc8JX + jK3RtXj9lo+av7VTQLwWfiD4cfEH4dXU2v3ejaRrnw80+78ceD9Ttg8dxD4hu9N8LWGuWPh601FJzFe3 + vjzwZpMtjcJdQpqU9va2uqy1IvjzokEEE2m2utfEdbjRr7XbXTvCnw6+INl4pn0+wvrzSjD/AGfeaHLo + f9qS6hY3EBj1vW/BqyywzPb2aW/l16547+J+j+A4NMi1GCfUtd8RXU2m+FfCuiJc6n4i8T6rHbS3RsNL + sILMhESGIyX2rajNYaDo1uft2uarpunpJdJ5jZ/Dbxv8T3GrfG0WlroFydJ1DT/gno+sC+8L6VfWAkm8 + 3xt4httM0+9+IF680ga40KZYfANq8VvGNF8QXen2niOXwcQ8dSrPCZZio4jFcz51PDKMcNzKMlLG16VS + lgqTt7tOmsBiMbVU4S+r1qVGtVXtYXCUKmHjjszvgsA7ulPm9pXxzhP2c6eWYSajXxKi4zVas8ZhsDQn + CdGrjaGJq4ejU+e9N+IPir4reLLPxF4d8F6v4yXQI9Rf4daL4U8SSQfDew1C30T7DfxfHPx5aW76E/iK + DULq4sbTwL4MuPGmjWGp2i33iC81Oay0HUtA99tvhF428X3kGsfEzxCl0bfU/D+u6Z4XtBIvh3w5qOkW + knz6VpOm/wBkRX066nPLqUZ8far8T9Pt7610i70+zs7nS0ln+hdHt3s9MsLe2sbG3ghs7aKKK3lMEKRR + xRrGiRR2gSNUVQqooCqBtUADFam+7/54Qf8AgU//AMi1rhchaVSeY46vj6tasq1aCX1fC1JxgoRdSjCU + qlbktH2arVp06Xs6XsaVJ04sqrn0aSjHKMDSy3kpulHFVJ/W8xUHJS9zEThTo4Z2XJOWEwuHqVYuarVa + qqSicLpXwz8KWFnaWlzpw1WKyigitYNUMcun2i2rH7KdO0C2jtfDekNboRFE2j6RYFY0RcnaDXcCws1A + CwIAOABkYHtzTt93/wA8IP8AwKf/AORaN93/AM8IP/Ap/wD5Fr3adGjRSjSpQppJR9yKWkVaKb3dl1bb + 8zw6tetXfNWq1KrTbTnJys5O8uVPSN30ikvKxSvbO2EceIV5u7IHrzm9twe/cEipLm30y3hlnuvIt7eG + N5Z5ppfJhiiRS0kssjuqJGiAs7uQqqpLHAqHUZrmO3Erw26pHcWbsxumCgLeQMSSbYADjqeB19j8bSeK + Ne/ah1WKTwRdj/hRuj6npd/pvibRtd1Sy074n6npdxrlprGm+J7STQ7C81r4ZR3yabeaXoei6rDY/E2L + TXu/EV+PhbrejwfEDqpUnO7+GELc0tNF2Xm+iXa+yPTyrKKmZLE4mrUWDyvL1SnmGY1Yt0aDrSksPhqV + 3CNfMcY6dX6ngozjVrRoYjEPlwuExVajzPi1Lb443+jw/CawsNK8EQaxoPinRfiDY6foXiq2+KdukWq3 + Gut8LdNXV44fA1rZahPo1vq3x1ZNH1l0udQ0vwLcXGqXWheI4uNuPgX4t+CfgvULJNMv/E/gePw54j0a + W08J3l+vjrwsnjPU9YuvEXi/Q/iP4h1+31HUPFVi2u3/AIhuPEfjy2bV5biLVrm++Jkaa7Np0P6EeGvC + 1t4XtvIsbWCSaSK3jur+edReXn2RSlqsnkWMNvBbWqM0dlp1jBa6XpsLta6bZWdrthXpXFxIhjktrd1Y + bWVrhypBGCCv2XBBBIIORg4IIry8xy3D4unOGFc8vnKMk62F5acqsnDkTxNNL2WIirJuFSEl25dj6Cpx + piKND+x8Dh6b4djVpTll2LvWrYuVCM6cMRiccuXFPFyhVxC+s0pUHRWMxtLAUMvwOKngI+MfAr4meHPi + 34Ds9bs5AutaVqGp+F/Fml3c0Z1TS/E/h28fTNSivoFtNMeNNR8u31zSbhtK01NS0LV9K1W3sre1v4Er + n/2pba2X4B/GYrGuU8AXLKQScN5txz1PNeNX3wj8P6V8d7iKL7H8P/E/i7RblvBHxG8K6rcWHjv/AISK + DR2sbzTTZazaa14O8Qadd+AfD1nGmkan4dvhFd/DfUPFWrJcajrOlXGm9H8bj8T7P4D/AB70vx7F4W1S + 2sfh/bx6J4t0K9vbS+8QxGK7TUbjXfC02lmz0HUIbqFZFXS9d1WwvorrfDFpf2c2Z87J8bj5Qjg8xoKV + fD1Hg5Y3DN1KVapQpp+0xFJqNXBVa0LVmmq2EiqlOEMZOpUVKPh5lg8tcXjMsxTjSnCNaeX41wp4qh7W + qoKGErQ/cZjQpucIOajhMYpQxEp5fHDYeWKn5t4X+L//AAor9kr4NfEu/wBZ8MaV4R0Pxlqdv8QI/EUs + 8N5qHgzVfG3i3TNTHhA2sv2i78XaLdXNh4nstGt7LVrrxHpmg6x4b0/TxqmrWN/Ye9eGfBGvfGm80L4j + fGTTYLXwzCdM8ReAPghcz+G/E+ieHNWsdQudR0D4geLNd06G7tfEfjv7C+m3WnaXpmp3/gzwPeiZ9Gu/ + FGsQ2Pi6HJ/ZU8LeGtQ/Z5+FcF74e0S6ism8azWUdxpNhOlnNL4s8V6fJNapLbutvK9jfXtm7xBGe1u7 + m3YmGeVHv/BAHwP4t8Z/s+63bahfx+C8eLfhzr9/4Vs9J0TUPhd4s1jXH0HwZod9p0txpd9c/Cd7M+C7 + m3NvouoQeHoPCd3Lo7Q30eqX30fs1Vg72vSTlyrTnjJpOU+snTdko7OMm5K0LrzamS0c/wArrzqqLnw/ + NYurgKScaebZZiqtCjLFZjHl5cXUybMKlOFPDuooVcJmX1ivQxCymhPB/VKqFUKFAA7AcZ7kfjTqp/2f + p/8Az42f/gLD/wDEUf2fp/8Az42f/gLD/wDEVBylyqdr/rb/AP6/F/8ASKz/AMKP7P0//nxs/wDwFh/+ + IrifFPibwN8PtE17xV411Pw54Y8O6XcI97q+tvaWVlbq1rZpFEJJgvm3E8rLDbWsIe4ubh0ht4pZpERo + qVKdGnUrVpwpUqUJVKtWpJQp06cFzTnOcmowhFJuUpNJJXbsaUaVbEVaVDD0qtevWnGnRo0acqlWrUnJ + RhTp04JynOcmoxjFNybsj0AsFyScY56Ht+FeG+Jfipd6zrd/4D+EMdh4q8YWEt1pniXWzNb3fg/4W6j/ + AGd9sspPHIg1Kxv77UZWns3tvBuizLrd7DMJb650HTnGqpwctt4/+Oc8lna6bqnwg+E63viLRNavJ7OX + Qfix42it7eGysdR8H3FtcMfBHhq7vpr6RNYv4h4ov7bSo5NMsNPsdatdXi+hPDPgXwl4P0ay0Dw5oOna + ZpVhEkUEEVukkkhSNI2ur27nEt5qOoXAQSXupX89zf385e5vLie4kkkfyFXxeZy5cJz4TL01z46cHDFY + pWu44CjNXo0pNqEsbXgpSjGosNQkqlPFU/blhcFlCUsa6WPzOzcMup1FUweCne0Z5lXoztiK8dakcvw8 + vZxl7J42u0q2BnzfgH4Y6X4Nn1HXb64n8TeO/EVvpieLfHOrIv8AaeuS6XbLBbQWlqrPaeHtAtpPtF1p + /hjREtNFsLm8vbtLaXUb6/v7v0/A9B+VVP7P0/8A58bP/wABYf8A4ij+z9P/AOfGz/8AAWH/AOIr1MPh + 6OFpRo4enGnTjzOy3lKT5p1Jyd5VKlSbc6tSblUqTbnOUpNt+PiMTXxdaVfE1JVaslCPNKyUYU4KnSpU + 4RUYUqNGlGNKhQpRhRoUYQpUYQpwjBLYf8eVp/17Q/8Aotat1k2NhYGytCbK0JNtDkm2hJP7tep2Va/s + /T/+fGz/APAWH/4itjAuUhYKMnp9Cf0GTVT+z9P/AOfGz/8AAWH/AOIrzz4seNvCnwk+Hfir4i+IdLmu + tL8L6abx7DRdKi1HWtWvJ54bHStE0XT1MH27WNb1a6stI0u0ae3jnv723jluIImeZHFOUoxSu5NJJdW3 + Y6MJhcTj8VhsDg6NTE4zGYijhcLh6UXKrXxOIqRo0KNOK+KpVqzjCC6ykkeS/FPVbv4seO7f4D+HdV1K + w8OaZBpPib4z+KPB/jG30TxHoNsNY0G88I/Dcf2ZI/iXRrr4lW7alfahqls+iXMPg7RdTj0jVo9Q1e3n + s/pXSNG0zQ9OstJ0jTrLTNM063itLCwsLWC0s7S2gQRxQW1rbokMMSKMIiKAOwrwX4E/C2+8C+A49Q8c + Lo2q/FPx7rdp40+KWu6doOk6Nb6n4t1AaTp4tYLTT4Qh0/w3oOnaP4R0qW4lub+50vQ7a61K8vNSuby8 + n+gv7P0//nxs/wDwFh/+IrWs0n7KDvCFl/iml70/nJtR10ikrJ3v7Of4nD06lLJMurwr5XlDlSWJoe1V + HNcycYRzHOLVmpzp4ivT9jlrlRw86WUYfAwqUYYmWLlVuUVT/s/T/wDnxs//AAFh/wDiKP7P0/8A58bP + /wABYf8A4isT548d+OnhnVtU8L2nivwrFH/wmfw51ay8aaBKuh6br2oXNvpU8M3iPQNLtdQ2tHeeKfDc + ep+HVm0+60zVHTUXtLTVtPW6lmrz748eJdJ8afss/ETxfoUzXOi+KvhDZeItIuHjaJ5tN1q0Op2MkkL/ + ADwyNa3MbPG/zxsSjfMpA+oW07TyrD7DZ8g/8u0Pp/uV8KfFjw9deDfhB+1D4JOi6ifDFn4YuvGfgvxD + qE8F/ayWvjjVvEmq6z4UsZfIiubD/hEPENtftY6dK1zDYeGdc8NWen3K2tsLDT/MlB4fMo1oqTo46l7G + tGMZyUMVh1KpQryUE4wjVoe2o1a00k50cFS5ruCOlNVMM4Ssp4eTnTbaTlSqOMalNXV241OWpGKe06ra + elvS/wBkOfVR+zz8MmubPT45dnjEukOp3M0Sn/hOPEPCyvpMDMAOQTChPI28ZMn7RnhLXbqx8K/GHwpp + WmT/ABE+C+pz65oTXXiK50qyu/CGuTabY/E7Q9TlNnFbXVhe+FbV9Yt7K6mhgm1/w7oEklzbrC0gwP2e + /DD+L/2Zvhroy+JPE3hdJJvFU0+oeEr+20vV5IofHPiF2s0v57K9ltYLjgTS2X2W9CqBDdw5bd6of2dP + hPc3lvquuaLrPi/U7TW7LxJZXHjjxx458brpus2DSPZz6VaeKvEerWWlW9tLK08em6dbWumCdYpzZma3 + gePpnXzGlXj9UwmGqwThepisZLDwlGV1VgoUsLi5ztHS0/YqXPa6UeaXsZBjMFleNw2ZV8ZiYVKM61Or + g8PgXiI4rBV6Tw2MwWKqyzLLbYTM8HXxWBxUKc6kpYepVjJRU1fFtP2o/g5J4Y0jxRL498Gpp2r6HL4g + hWDxEup3FvptpZTX+oT3aaTY33kxafb2t5Lc3UjC2EFpcXSzNbRPMMm7/aSuNTW5T4e/Czx34/nh07Rd + WtpNK026tNC1qx1+OGfTm0Txjd6efCNxcm1uYbu6tLzWrCXT7eRZb77MolMfnnwj8F+FfgL8XNe+FsHh + nRtM8N6yZ/Gfw3vtF+HPhvwp4f8ADPhzXdQh0qXwZY6xoMNtb3F5oOvt/ZGqiax0qR9I8UfC6NR4i1rU + vF+tL9xhYWHylcHurdfxB54rnxOEzmdSf/CjhMNRm5Ol9XwMqtZQlD3H7fE15UueM5Xb+qNS5LWipSS9 + POsPw1k+NSwGXZjmWBxFKljctr4/MPq9Cvg68o1aEatDDYGhiOelRvhcVGGMg4YqNXllywUZfNxn/ac8 + WXUsNtZfDb4X6KmsapaSXV5PqHjPxXcaLapHFp2q6RHbi38OW8mq3HnTrFq8dxJa6etv59gl7cyxWGt4 + T+DcVjqi+I/Geq6j8TvGtjFBYHxJ4x1SM2UJhuLTWEudE8F6Noml+B/Dt5HdpZLHqmk+HrfXpbTTdNh1 + LWdSmtTdS+/DaDkEZ6de3pVS2I82/wCRzeKf/JKzqaWU0FNVcTVxWPqxnzxeNryq0qcrxcXTwkI0sDTl + DlXJOnhYzinNKVpz5vDq53iXTdDB0cHlVGUeSay3DqhiKsLybhWx9SVbMqtOXNapSnjHQq8sHOleFPka + raiBj7JY8dP9On9eP+Yaf8+lO8zUf+fWy/8AA+f/AOVtXNw9R+dG4eo/OvUPHKfmaj/z62X/AIHz/wDy + to8zUf8An1sv/A+f/wCVtXNw9R+dG4eo/OgDJsZNQ+xWmLWzx9mhxm/nBx5a9R/Zx5/E1a8zUf8An1sv + /A+f/wCVtLYECys8kf8AHtB/6LWrTOiglnVQASSzAAAdSSTgAd6P6/r7wuVDJqIGTa2X/gfP/wDK2vhT + 40/E7wlqPx98DeA/FesGx0v4TxXfxZPh7w74pbUvEnxM+Idp4a8Tvonw30r4a+HdG1Hxx41u/CXhd7n4 + napo+nWyPFd3nwyddN1oa/ZG3sfFT9p46n4E8TeKvAPiKTwh8I7LwRq/iVv2gLPSLTxbrGrSaB4k/s3W + tL+EPw0v7KRvFRm0jT9UbS/ijrsEvw4h1XWfBV34f0r4nabqmo22n9f+z18Ab3wt4S/tP4kQ6W3jXx3q + 2u+PviNZaVqOvayuqeK/Gcmn3Go2Ot+K/Ecn/CReItI0XSNI8N+D9L0J49H8Nx+G/DWlaTd6FfW2m6d9 + j9anhY4KLr45uM71aUcHCXJioTULOVSUqdSnRlCb9nOi1OvBqarU8O5UJz9fKMVUwmW5lnmFhecoyyTJ + 8ZUjU9hPHZhRSzPE4Vxq0VXeWZPWkp1l7WGHxecZRWp06z5pUmL8a/jl46S9Pwq+ANh/ZUWn6Ff6Z4m+ + LnxMTwFpGoard3lm15oBsfCXg74m67bX+jl5bbUhJp6raarZXul332CZY5Gvt8Wv2gdG1Ar4r+D/AMPd + H0Y+Jp4n1G4+KPimA2XgUTCKHxBc6lbfCTWvBlvr21w0nh3WfGPh61lIBTW4/OCxfUU8EFva21vbxRww + Qz6fHHFEqpHFEl5bKkaIgCpGiAKiqAqqAAABWgQh64598fyNZPGYS/LHKcH7PWzdXH+22jHmdV4yUOZ2 + 5moUYQUm1GCi+VfMrCYqyf8AaWJ5uZNr2WE9kle/JGmsPGSh0XNUlNpJubauvlvTv2odJ07S9P1L4o+C + PFPwhs7nw9feJL7xH4nFn4g+Gmj6dYald6fNLrHxd+HsvjD4aaIs8VtFqtiniHxNo1zc6ZqFkzW0N/8A + a9PtPoXR9fh8QaZYa3odxomsaNqtnbahperaXrQv9N1KwvYUuLO+sL60sZra8s7u3ljntbq3kkgngkSW + J2jdWOde+A/Cl3cz3yad/ZmpXUnm3eqaDeX3h/Ur6RfunUb7Q7mwuNTjU4Y2+pPd2zty8L5bPgupfs4D + StduPFvw78RyeE/El/4h8N+J/Ed/okFh4O1Lx5f+Go7vTrPTPGt94c0lvDGuaFdaHfXGj6gNd+HfiDXJ + rWLT5bXW9P1PSNB1TR21lmIfuupl825NRlz4jDXlJclOPM54ilTgnKLq1K+Im+WN4S5pTpl8fQ1kqeLp + q3w2pV+VRs5bKlKTaT5VCEfek+ZWSf1B5mo/8+tl/wCB8/8A8ra+dv2pXvj8BPjNvt7VV/4QC63lbyZy + F8y55VTYxhmz/CXQEfxCuNsfjH8cvhSttZ/Hf4Zat418PWekXk+pfF74I+FNT12E6lBqtzHBZXPwa0LU + PHHxBW1OhnTrlvEWjPqX9oap/aol8H+F7G2tftD/AI2fEvwD8TP2cvjfqngLxhoHiu1s/AclvqSaPqVr + d3mi3syS3S6Zr2nI41DQdXSCRXuNH1m1sdUtCTHdWkMiui5V8BicPD2rjGvh38OLw0vbYaWqjZ1I60Zt + tfucRGlXSlFypRUo30oY7D15ezUpUq+l8NiIujXWnNpTnZ1IpJ3qUnUp3TSm7M1/2QtG0i3/AGevhlDB + pWnQwqnjBViisraONV/4TnxCwVUWIKqgnIUAAdgK+n/7K0z/AKBth/4B2/8A8br5i/ZBk1Vv2evhkZ7O + wim2eMSyRalcTRqf+E48RcLK+lQMwxg5MSHPG3ufqDzNQ/59bP8A8Dpv/ldXEdZ4F+0D8LB4u8IRa94Z + 8OprPjn4d3V/4z8EaFaatD4Xi8SaxH4c1nQrnwlqWqmF7aLT/E2kazqWlpNeqkGlarPpfiCG5sdQ0eyv + 7Xq/hV4n8OeOvDFpqFs2h6rLHDAG1CzGkXUOqWsiuLPWIW00z2YW9EM0V7DaySWuna5Z6zosU076VLIf + UWfUCpH2Wy5BGDezEHI6Ef2fXyFdRav8FviysdnYqPBPxIufEOu+HtI0DwzBa6R4b1uNLjxL8UNG1PVt + DsY57zUPGN1cX3xb8J/2lod/qF34h0v4r6TJ4jSbxZ4Z0lemH72m6b+KL5qfTRJKce21pJvtK7Ttf6jA + N5zlNTJpPmx2WRxWY5Q5uvKVTC2dfNMup/xKVNQ5Z5pRhy4WiorNa1avWrfVMNP67/srTP8AoG2H/gHb + /wDxuqltpmmmW+B0+xIW7UKDaW5wPsdocD93wMknHvU9ve3N1FHPbRWE0MsaTRSx6hK8UsUqh45I5F08 + o6OhV0ZSVZWVgSCDUds9/wCbf4trT/j7XOb2YYP2O04H/EvOeMHPHX2rmPl9m0907NdU+z8yx/ZWmf8A + QNsP/AO3/wDjdH9laZ/0DbD/AMA7f/43T/M1D/n1s/8AwOm/+V1Hmah/z62f/gdN/wDK6gBn9laZ/wBA + 2w/8A7f/AON0f2Vpn/QNsP8AwDt//jdP8zUP+fW0/wDA2c/y06vKfiT8Vz4C/sXSLHQJ/FnjjxbfPpPg + /wAH6LNqEtxqWoi2ublrzW9Sh0O8s/CXhPT47WWbXPFutrHpmnRKtvbrqOtXel6NqOlKlUr1I0qMHOpK + 9oqysopylOTbUYQhFOdSpJqEIRlOclGLazq1adGEqlWShCNrt3u22oxjFK7lKUmowjFOU5NRinJpGx4p + 8V/D74d+GbXxD431Dw14c0p5NK0uC91qbTtPjvtY1aWCx0jR7F7ry/tmr6vfzw2OmadbmS7vruWOC2ik + kcLXzHpfhTxj+00+leJPGPhm4+H3wiaTQfEnhz4da/pMOm+K21rRtVvrqz1jxo+heJr/AErxda3EEWm6 + lpfg7WLb/hCNHvBY6lrNh8SpPs0Xh7vvA3wS1rWNW0P4n/G+60zx78QbaPQtT0Hw3HfX0/wq+E+p6bpd + 5YLN8NPDmpaazN4hkt9X1SLVfiPr6XPi/V2vr2LTG8KeGJbLwfpfu/inxI/hPQtR1u6tdP8ALsLdXjhf + VWtI7i4mkS1srVrqbT1t7UXN5Lb2/wBpuXjtrYSGe5kjgjkdfRVajgbRwT9vjm4qWNV/ZUXo+TARaU5T + 5rKeLnyybjyYeEaLnPEcsMLicyqwp1YyjQqVIU6GCjdVMRKpKMKf1tp2tJu0cMrxTmnVlKcYxp/KnjHw + lpvir4xfDj4S6DaazBoPh67f4wfFnxMnh+31Wx8YTeEZ7K08HfDXxL4nvZoktJr/AF/xFpvjT+x7S1vY + 4tC8KR6TZWGkaVexTW/2VHpWmbFzptjnaM7rS3J/EmIZPvXzT+zN4a1RdE8UfFfWdP04+KvjHrsviG7v + LfxSuv2N54O0qe90z4cXGkXdnb3lla6TrfhgxeN10myvdQtNK1bxnrNna38tpHbxQfTm/UP+fWz/APA6 + b/5XVx4mbclC7l7P3XJvmbnZc75nq/evFX+zGK0tZfYcRSpYatg8iwsoSwvD2GlgJTpqgoYjM6lWVfOM + Vz4dzp108bKWCw+J9rVdbAYHBNShBQo0qF7pmmiOPGn2IzdWQOLS3GQb23BB/d9wSPxq5/ZWmf8AQNsP + /AO3/wDjdVr177y4s21oP9KssYvZjz9tt8A/8S8dTjnsM8Vc8zUP+fWz/wDA6b/5XVzHzoz+ytM/6Bth + /wCAdv8A/G6P7K0z/oG2H/gHb/8Axun+ZqH/AD62f/gdN/8AK6jzNQ/59bP/AMDpv/ldQAz+ytM/6B1g + PpZ2/wD8br5k/ab8K+GNP+C3x11uw8O6FZazqXw8jTUdXtNJsbbU7+PTJdR/s1L2+hgS5u10/wC2Xf2J + Z5HW1N1cG3EfnSbvp7zNQ/59bP8A8Dpv/ldXzt+1K97/AMKE+M2+3tgp8AXIcpdyuyp5lzllU2UYZvRd + y5/vCmpNJpNpSVpJNpSSd0n3Setn11E0nZtJ8rurq9m1a67O2l1rbQyv2QtU02f9nr4ZSwahYzRMnjEr + JHdQPGwHjjxCMq6uVIyCMg4z3r6f+32P/P7af+BMP/xdfN37I/8Ayb98NP8Ad8Y/+px4hr6cpDKn2+x/ + 5/bT/wACYf8A4uuC+JPhDw38S/CWoeFNY1F7aG5uNH1Sw1HTNSSy1TRdf8NazYeJPDWvaVeI5NvqWheI + NL03VrJ2WSFp7NI7iG4t3lgk9Iopxk4tSWjTumb4bE18HicPjMLVnQxWFr0sThq9N2nRr0JxqUqsH0nT + nGMovo0fMHwD+Jc1/Dqnw+8ZTeHNK8f+DZFsfEug6FqMl5pGjarLa2OqXFjpFxdEXH/COXmnavpHibwY + lx89r4U8Qad4ZkeXXPCXiWGz+iLW/svNviby1GbtSM3EIyPsdoP7/qCPwr52+PXgnxPYT6f8Z/hnZajq + njrwLaXc2oeB9IbTLT/haeiRwy/Z9Guri8SPzNf8NefqN94PklvLVrm31XxZ4Hj1HQbLx/qWu6b6/wDD + bx34c+Ivhi38W+GNStNT0rU55oxNZ3drfR22o6b5ela3pUtzYyzWrX2i6zZX+k6ikMjrDfWVxFuJSt60 + VJKrCzjKykl9ipbWL62lvF9Vpume7neGoYqhR4iy6lClgsdV9hj8LTqOTyrOOWU6uFlCaVaGExsITxuV + VKkq6q4f22Gli8TjcBj/AGfbfb7H/n9tP/AmH/4uj7fY/wDP7af+BMP/AMXVrPGa8M+LHxlXwO1h4Z8J + aHfeO/iXr89pBofgzRVtLi9t7K41XS9J1DxZrUdxqGmx2fhXw0dYs77W76e9s4kge3gN3atfW89RQoVc + TVjRox5pyu9WoxjGOsqlScmoU6cFrOpNqMVq2j5atWp0IOpVlyxVtk5Sk3oowhFOU5N7Rim32LHxR+Lt + v4PbQvDPhmwPi/4h+Mr+HSvDfh3T8T2+mR3AcXXjPxrexTJF4Z8AeHEjku9c1u8mjmvZEtvDXhm31rxh + reg6HqMfwr+GmkeB21Xxb4j13T/F/wAXfG1noa/Ej4hvDFpz69Podm9tpmkaFo732oReFPBGg/aLweG/ + CWn3UttaS3up65qt1rXi7X/EviTWovgr8G5fhzaX3iPxnrVp4/8AjP4ut4U+IvxQbRLPR73xClpqWr6n + o3h/TLKAzNo3grwgutXeleEfDwurn7FYA3eoXWpa5e6rq1/7rXXialKhGeCwdT2tJ2jisXFSh9elCUZe + 5GcY1IYKNSEZ0aVSMJ1pRp4jE04VI0aGF5qFKrVnHFYuHLUWuHw7amsLGUbOUmnKEsXOLcatSDcKceaj + QlKDqVK+RZX9ithaj7ZaAraw8G4i4xEvBG/P1r5O+OGs2fxL8WeGvgnZanogTxJcX669Z6laS6pZat4G + 0htEj+McLxRo1rbB/A3iyz+HdlqF/ILAa38U1ubeSPWPDVvHJ9JeI/EcXhnwm2oF7ZLo2cNvpwvZlgs2 + vpoCYpL2Yspg0yyRZNR1m7Ab7Bo9nf6g4MVrIR47+z7oGoXsfiP4m6r/AMJRZS+MLldJ8PaB4g1eC8s7 + Lwb4Y1jX00nxbZaVYwQadpmqfFa71HUPiXrcuLnVZIPEWhaHqN68HhjTLSw56S5YyqvTluoP+87JW72e + r8k1c+0yFrLaWK4iqW5svtRy2HPTU6mbV4TWFnGlUp1/aUsHaeNrqdCeHrUsNVwc62GxGIw1Q+hLSTSr + KGK2tbiwgt4Io4ILeGW2ihhhhRY4oooo2WOOOKNVjjSNVREVVUAAVZ+32P8Az+2n/gTD/wDF1borBtt3 + erPmbt6tttu7bbbberbbu231bZkXt9ZGOLF5anF1ZE4uIegvbck/f7AE1c+32P8Az+2n/gTD/wDF02+/ + 1cX/AF92P/pbbVdpAVPt9j/z+2n/AIEw/wDxdH2+x/5/bT/wJh/+Lq3RQBU+32P/AD+2n/gTD/8AF187 + ftTXtm/wE+MypdW7s/gC5RFSeJmZjLckKArEknsK+lK+dP2p/wDkgfxo/wCyfXX/AKNuaAOf/ZCj1Rf2 + e/hmJruxklCeMMvHp88SM3/CceIeRG2pzMoxgAeaxHUsa+ntmo/8/Nl/4BT/APyfXxP8A/it4T+Hn7MX + wp8Q6vH4o1vTry/8VaZGvw/8D+M/ibqUc1x4y8Uypc3Gi/DvQfE+s2+mKLaRJ9VlsF063meCCa5Sa5t4 + 5eqP7dX7MUGow6Rqnj7VvDeqXXiLWPCdjYeMPhr8VfBl3qfiDQLbT7zVtN0e38V+CNGk1ia0tNV065Mm + lrd281vdxS280yHI7aOXZhiaTrYfA4zEUU5J1aGGrVaacFeSc4QlFOK1km7pXb0Ry1cdgqE/Z18ZhaNT + 3f3dWvSpz974fdnNP3vs6a9D6u2aj/z82X/gFP8A/J9GzUf+fmy/8Ap//k+vHNF/aL+FHiS1t77w9rGv + 67Z3cDXVpd6N4A+IWp2t1bLPLam4triy8Kzwzwi5t57cyxuyCeGWItvjdRtf8Lm8F97fxyPr8LPij07H + /kTehrB4fERbUqFaEk7OM6VSMk1ZNOMoqSabs00mno0aLE4eUVKNejKLV1KNSEotW5rqSbTVk3e+yb6O + 3ozw38ilWuLPBz0s5x1BB/5f/Q18jeN/hD4s8GeJ/E3xU+C76o+oag27xT8IPD+uWHg3w14v12/1XRbz + VfiJpEWpx3XhqP4oJoh1e0b/AIST7F4f8cXD6Rb+KNZ0Z9MtNes/U/EP7SXwi8I2pvfFWu634bs/Ju7j + 7Tr3gP4g6RAYLC3e7vpVlv8Awtbo0dnaRyXNy6sVgt0aWUqgLV41L8fvE/xv0ye0/Zi0mR9J1u1ttUX4 + 1fE3w/4l8H/Dq0sp9RstIntfDuj6pa6H488a699hi1PW7IaTpWleE7i106G2m8faJd6zpt6nZhcFjXar + 7KVHCuShUxWKi6OCjzNu069SKpudoTcIQk60pQlyRcotLty/ib+xMRUeHqUcZ7al7PGZPJSxNPM8NeEn + hsThaM4V3SlJQaxFKdCvhKns8Rh8Thq8KdWOPr/7ROuT6Q+l/Bfxppfxb8bXUuvaPZeBtW8N6f4d+IEv + iDQtW0zQdc0uaK/1bwZFol14Uv8AWtNvPGEuqeCLmPwV4auIvE2t2179r8NaF4v7b4UfDnxr8OL7VfF/ + jfwzYfED4n+I21Cy1Hx54Yg8PNcad4VbWrzWdH8E2jeILzwbrEWg6TJeFzLcXPiHV9d1NJdV1rVJNulW + enxWn7LnhLw6brxZ4O+IvinSfjObbXbax+MOr6ra+JNa/s/WtYg1v/hGNY8LTfYPBWt+BbK5txHp/hV9 + CtE0mS81fxDoN/o3jrW9X8X3nY2HxR+JHhK9j0r4ifDc+IbS78RWGiad46+Eup2/iDS5tNuYQh8UeLvB + msy6V4q8GQLdqVvNJ8PyfE2DTY5Y5n1+6t1uLmParXoqjPC4BRlCcr4irUgqeJxLi/djDWHJhIq0o0VF + TnO88RGXLSVP1/7Pw2bSjjcFHBVakFOcMlzKrh8Dj8tsrNYfEYepl2Az+dSM4RhWpU45gpU8RFZTh8PH + 61jvRB8R9EhI/tbWE8MqWVFk8X+G9d8I28kjf8s4LzxL/ZdndyqeGWzuLgdGDFGVj2sF1Nd28V1Z6npV + 1bTIskNxbQmeGaNhlXjmi1F4pEYEFWRiCCCDivAl/al+Ft9a2klrpnxemub3SNX1u20t/wBn3472upm0 + 0SS9hvILi0vvhxanT9Tlk0+4TTNK1JrTUNZ8yyl0i2vYdR0+S54270vxP8UdVWTwt4M0r4G6DPf+C9a1 + H4ia7Dp8HxM8XaFd2MeueJPDmi6D4V13StW8D6tBJJZeFr7X/GWrXF5azp4hW08G3kEWka3ccPsdnOLo + W359rLl15XaT1eyTevk2dT4axNKbWaYXG8N0Ic0qmJzrlpRahWjQqRw+Fr0sHj8ZUp1XyToZfRx+ISjU + m6UaWHr1KeP4ua6/aA8f3XwdsH0+9+H/AISsrGw+Mbal4f1yTSNZ0DxTomv2Wq+DtD1i2voNNl8S6nPZ + WWg619nv0v8Aw74QuvGNtf2u/wAV+H5a+zLezurSGO3tpNPhghRIoYYrCZIooo1CRxRRrfBI441AVEQB + VUYUAVwnwu8E+CPhb4J0Twb4NjttN0TTYrm4CXGq3Gp6he6lq99cazresaxq2qXd3qmsa7res31/q+ta + xqd3dajqeqXt3e3txLcTySH0P7fY/wDP7af+BMP/AMXWdWafLCF1TgrJPeT0vKS2vJ9Lu2ydjjzrMsPi + nhsBlqrQybK4zpYCOIjCnXxNSpyLF5pi6NKU6dLF5hOnGpKjGriFhMPDD4GOLxUcMsTVbs1H/n5sv/AK + f/5Po2aj/wA/Nl/4BT//ACfTvt9j/wA/tp/4Ew//ABdH2+x/5/bT/wACYf8A4usTwylepf8Alx7riz/4 + +rLGLKbr9tt8Z/0/1x+GRVvZqP8Az82X/gFP/wDJ9Vb2+sjHFi8tT/pdkf8Aj4h6C9tyf4+wBP0FXPt9 + j/z+2n/gTD/8XQA3ZqP/AD82X/gFP/8AJ9GzUf8An5sv/AKf/wCT6d9vsf8An9tP/AmH/wCLo+32P/P7 + af8AgTD/APF0AN2aj/z82X/gFP8A/J9fO/7Uq3o+Anxm8ye1KjwBclwlpKpZPMuchWa9cK2f4irAf3TX + 0V9vsf8An9tP/AmH/wCLr52/alvLR/gJ8ZlS6tnZvAFyqhZ4mLN5tx8qgMSzf7IyfagD85/gf+3zZeBf + hd8OvDFp8LLjW7P+ytQ1Wz1O68YxaPcTWviLULjxLElzpsXhjWI7SeCLWUtJUh1O8jZ4GlSXa4RfZJf+ + Ci9tPE8M3wShmhkRo5IpPiArxPG4Kujxt4EKMrqSrBgQwJByCaKKA30ez3Xc8i1v9pf9n/xKXbxB+xV8 + JNZeTRp/DjS6l/wiV3OPD91q0mvXOhpPN8L3mj0i41yWXWZtOjdbOXVpZdReFryR5mxp/j9+z/cCZH/Z + G8LrDPceGrqS1g8eXNtZef4N0yfRvCzLY23hCK0jGh6Vcy2GnxxwJHDb+WmwiCDyyiuyOYY+C5Y43GRS + d0o4mslduEm7KaV+anTd+8IPeMbczwWDk+aWEw0na13h6TdmmmruF7NSkvSTXVnU+Hf2rfgr4Svo9V8M + fsffDfQdWh13XPFEWr6Xf+HLPVo/EviaLTIPEfiBNUh+Gi3661rtvoujW+r6oLgXuo22kaXb3c8sOnWa + Q+gWH/BSSJ7nV40+C237LqKQn/i4YAJfS9OuMqB4G6bZwOcHcG4wASUVhVr1sRLnr1ataVmuarUnUlZt + yavNydm221fdt7tmtOlSoxcaNKnSi9XGnCMIuySV1FJaJJeiS6Gp/wAPIRjH/CmeDz/yUT/8BaT/AIeP + p1/4UwPx+Imfb/oRfeiisrmny/rf80J/w8djzn/hSy59f+Fhgn/1BffP15pR/wAFH1U5HwYAP/ZRPw/6 + EaiigLdbfh8vyKGj/wDBSkXWk6bcr8GCqz2NrKob4iDcA8KMAceBiM4POCee5rR/4eRf9UZ/8yJ/+AtF + FAB/w8i/6oz/AOZE/wDwFo/4eRf9UZ/8yJ/+AtFFAGZqv/BSlbeCCRvgwxDajpMAC/EME7rnVbG2QnPg + YcK0oZu+0HAJwK0/+HkX/VGf/Mif/gLRRQAf8PIv+qM/+ZE//AWj/h5F/wBUZ/8AMif/AIC0UUAH/DyL + /qjP/mRP/wABa8V+OX/BQaDxd8NPil4Un+E8ulw3/gKZrrUovG6ajJaWh/tae4mt7B/CWnreXMcFhMYb + aS+sop5Wiie7t0Z5oyigD//Z + + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QECRXhpZgAATU0AKgAAAAgABwEaAAUAAAABAAAAYgEbAAUAAAAB + AAAAagEoAAMAAAABAAIAAAExAAIAAAAQAAAAcgE7AAIAAAAIAAAAgodpAAQAAAABAAAAipydAAEAAAAQ + AAAA6gAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMC42AEJyaWFudGEAAASQAwACAAAAFAAA + AMCQBAACAAAAFAAAANSSkQACAAAAAzU5AACSkgACAAAAAzU5AAAAAAAAMjAxNTowOTowMyAxMTo0Mzo0 + NwAyMDE1OjA5OjAzIDExOjQzOjQ3AAAAQgByAGkAYQBuAHQAYQAAAP/bAEMAAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/A + ABEIAJYAoAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMD + AgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp + KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOk + paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQAD + AQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFR + B2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ + WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfI + ycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP7Hv2ev2cP2ebr4CfAm5uvg + b8ILi5vPhF8Nri5nn+G/g+WaWebwLpMs0sssmjs8ksshMkkkjM7yMzMxY165cfs1fs5pDelfgN8G8rFI + QT8NPBhxtt1bJB0UggdfTjkHmrf7Occf/DP3wA/dr/yRz4Y5JUf9CFpHX3xj8jXr92kYgvSFUERyEEAL + 0tlPUY+vpQB40f2aP2ch9nH/AAob4Nncw3f8W08GcDyn5/5Avr+uPamP+zV+zkFul/4UP8G8An/mmng3 + vBGeCNG9fTpXt7JHm2wifeGflXGPKkxn6VHIkf8ApX7tTz2Vef3EXT+tAHjTfsz/ALOIkQf8KG+DeCGz + /wAW08Gccrj/AJg3c8Vn6n+zX+zpHpursnwH+DYeO0umRv8AhWngw7StkXUj/iTYHzfhwSe9e+skXmx/ + u0+6+TtXHVcfrzWbqqoNM1khVB+yXRUqAORY5Xpjo4zzxxzQB5E/7NP7OSzRkfAf4N8pL/zTTwZjO6Ln + A0bHGT7CmD9mj9nLyQ3/AAob4N587p/wrTwYf+XjHP8AxJemPXj8K9vlSMyxfIh/dzc7VP8AFD19f1pg + SL7Ov7tcmb+6uf8Aj6OSfbrQB4wf2aP2cQ4/4sP8G8GNj/yTTwZ1yMf8wb0Jqjdfs1/s6LaI6fAf4Nhj + qFlH/wAk08Fn5X1aCJhzop+8rEY98CvenSLeP3akeW3RV65XGff8aoXiILJMKoJ1KyHAAO1tYgVh2PKk + igDyBP2af2cmlk3fAb4NjEcRwPhp4N6lps/8wbnp259aRP2aP2cfKgY/Af4NjITP/FtPBh/gP/UFzXtk + SR+bLlFyYocnA5+abke/5HvRGkXkW48tOiZG1c42GgDxUfs0fs4s8g/4UN8G+EUj/i2ng3uZB0Ojc9Px + r53+LX7Dvwq8eeLPhLrnhnwd8NfBWl+D9Znvtb0PTPh7ZWtt4sMmpeFtZgi1AaBqPhy0uo7fTPC+vaKt + p4isvEWkS23i2+ll04mAxXH3rGkfmSfu1xtjwCq/3puOf0rPZYw+kDaq5uiGBAAI/sq+IGOh5UHp1Xvi + s6tKFaDpzT5ZOLfLJxb5JKcVzRs7cyV1ezWjOzL8fissxUMbg5whXp08RTi6lGjiKfLisPVwtXmo4mnV + oybpVZqMpU3KDalBxkkzxqL9mn9nXZc+Z8Bfg7lMld3w08Fgn9yrY40bHBOBgDIGSNxNTP8As0/s5grs + +AvwbJHOP+FZ+DDlhn10bBGO2CMdc12fjj4ieCfhxaQXvjHU10m21bUG0+0mGn31+iSR2P2m5vL46faX + f9l6Np9vE9xquu6l9k0XSYNs2p39pE6M3cxiF2jZUXbg8lVweCQR1HQ/XscHiq9pCc5RU4ucHFzgpLmj + zJuLlG97SSbXMrOz3sYyw1elRoYieHq08PiXW+rVnSnCjXdCUIV1Rm1yT9lOcIzUG1TcoxaWiPjv4c/s + c/CrwrqnxKvvF3gX4OeM7TxV4svvEfh/Tz8GvDWlHwhY3ESwW/h63nurnXLe6srPTINJtIv7Ms9Bsmur + O91V7CTUta1G4f1N/wBmn9nMahbRj4EfBvY9lfsw/wCFaeC+WSfTQhz/AGLkYDvjGPvHOeMe3NHH/pmI + 1ztbB2rjH2eP8PQ9DTJFj/tO0G1dv2HUCQANpIuNM25A4yBu6j+lb161TEVZVavJzyUE/Z0qdKFoQjTj + anSjGEfdjG9oq7vJ3k2yatWdabqT5OZqKfJThSj7kI00+Smox5nGEeaVrya5pNttnjB/Zp/ZxCY/4UP8 + G8+ay/8AJNPBvA85gP8AmDemOe3HavIf2iP2b/2ebP4C/G+4tPgX8IILmD4O/E24t54Phv4Pjngng8Ga + zJDNDJHo4eOWKRVeORCro6qykFQa+yikWB+7Xd5zYOFwB5/5f3e1eN/tJJGf2fvjphF/5Iv8U+gA/wCZ + J1o9u/ArIzIv2cxa/wDDP3wABFvn/hTvwxzkR5z/AMIHpJ59+n6V7Bcrb+TehVh3COTaFEeQfsy4xjnP + pjmvIv2dZYx+z78APnTd/wAKc+GH8Y/6EPR/9ruMdO2elbvxG+KPgj4cacbvxhrg0uK/N2lsItO1bV52 + S1sVku7ma00ey1C5ttPtEkhF1qdxDDp9rNcWVvcXMc97axypyUbczsm4xTeicpvljG+15SskuraNqGHx + GKqwoYXD1sTXqX5KOHpSq1Z8sZTfLCCcnaMW3ZOyTb0Ta9GZbXNr8tv9/niP/ni/WvP/ABkfGaaj4bPg + 6HwtNpX/AAkir45j1trqO8HhV9HuFkl8ONZB4n1mHVG091gv0W1lslu83EcyRQXfhP7Ln7Ucn7T3gC++ + Iuh+DpNE8O4gl8I6jPdeKUtfE6Ftd0+8ty/izwD4Fmtb/SdU0WW01P8Asy28QaKn2u1uLHXL6CQNXsPw + s8SePvEXhq9v/iX4bsvCeu/2ldQwWVpOhFzp8drYsly1uuoat9ikhvJbzTPm1K6F/HpsetQi0t9UisbO + KylGq8JUjicNiI1a1OpTnRq0K9Crg6/s61GvSqwjUo1FUhKm6VWEZpqSlGLiduZZFjsvWPo42pQwlfL6 + 2Dp4ilTzDBTxN8VT+tUp4eNOrWhiaUKcY/WpUvaRw6qctb2clOVL1gra+ZD8tv8AdfPEfouP1rO1Rbf+ + zdZ2rBu+yXZXaI92RYArtxznfgrjndjHOK0pZY8r5cibtkm0s2fmwpUH5gcbsZ56d+9eLfDq7+KUngfX + v+Fvf2IniZr3U0s00TyRC1iNIs1y32WWa38mTWhq7aAS66g/hdtB/tyOHxGdWhjbnapCnyTfPGb50lyR + UOVe+7ppycko2TTd72OWGGU8JisX9ZwsHhqmGprC1KvLjMS8S6qUsLR5WqsaTpWrPni4OpSSUnPT2SYW + omiwtt/q5u0efvQ9OPy568Vydh4y8I6lrereFNP1jQr3xBoP2WfWNItr2zm1LTo7uSKe3a7tI3aWDfDc + W0v7wKVS5tXZQtzAZILnxrpuq2HipvBF/oXjDxB4Xh1nT5tDsddsB5fiaztFntfD2rXUclyNFuri48mG + Y3sQe0STznhZUYV4JouveFvhroUPxi+J/hN/DHxD8banf+HNSTQ7PWdTmuvsk2q6rHNp/h2HVvEVr4aG + t+HvCcOveIIrK6D3kml6emt3V9f6fYJBhWxMaUqesFS5alStWqc6pRpQ5U+WrFcjqqco2g3rH2javCx6 + mX5PPFUMZz0cXUx3PhsHluX4R4d46vj8Vy4im6uAqv65LA/UqdeUsRRpNKrVwq5uSba+siLXeDttxmJj + 0j9VqheLb/Yl2rDn+0rIHAjzt/tiAODjts3Bu23IPGa5LxD8U/h14TsND1bxZ428M+FdN8Rog0O78T63 + p+gR6lJLbxXaQ2h1W5tfOnFvIsrwpmVEYb1BOK6q4mSSzjKyo6nULBgQ2AV/ta3LHqBjaGJPQgnHAyer + TX3o3Vrq+qu0lded1b/M8edDEUoUqtXD16VOs6ipVKlGpTp1XRlyVvZTmlGp7GpanVUHJ05tRlZs0Ilt + fNkysG4Rw7siPIIabOc85+tJELTybckW/RB0j/uGnxyxCWXMig+XDkb++6b3xRHND5NvmReidH4+4ff/ + AD9aDIEFqZZeLcgLH2j4+aX/AAqgVt92kbVhx9qYSbRHjb/Zd5gPjjG4JjPG4L3xWF4o8feEfBMmif8A + CT67Z6MvifXtN8LaCbp5B/afiDVHuv7N0i2KJIHvr7yZRawMRJOyMkQZhtreZ4t+kMHU4uSXIfIA/su+ + Azg8DLKPTlR6VKnFylBSi5w5eeKacoc1+XmjfmjzJNrmSutrkKpCU5wjOLnT5faQUk5w5ruPPHePMk2u + ZK9nY+S/jv8AHz4I+GtTPhXxd4f0bxVr3hvxRazxw+KtFbTvCfhjWLTwvZ+IrTWpvHHiDQ5/CumalDp2 + r6Tb6c1hez6s2o+IdM0+BI3nvDbfT3hfXrHxJ4e8PeI47NrGHXtG0zWYrK9jiS8tItV0+3vo7e8jXcqX + NulwsVyoZlSVGUM2Mnh/Hdp4L8CW/jP4vWXw4g8R+NbTRp1up/CHhnS7z4ieKLeK106OLQrW/WO31LUn + uvsGmW8VjcX5jeOwsY0QmztVj4z456T8a/GXgnw6vwC8T6V4J8UyauNS1a81+/0qwb+xJfCfiKK302O4 + vfAHxSs47uLxVd+Fr+/iTQ4/tGnaZqVrb6rb/aQJsa06dOvUnh4VqklhaE6uFjThKrOcZShKpCrGME4P + mtGlJuUFFtycT28LVwWZrLMi56WX42FfEVa2a5jmWKhl0MHieXkg8O6FWhhJKrRl79FVJ4irKnGpGKac + foQvaH7UoW2JZWIwqHgQIOCBjrjGSMkg96fItsNStPlgCfYdQ3cR7dwuNM257ZwWxnnk47188a54d+Ok + 3xo8J69ovi7QrX4O6do1lb+MPC8moaZDqmq6zHp/jFNQvYrKb4c6rqF1HNdXvgWWzez+IXhaOzTRtUaT + Tr4TiK+9c1nxv4W0PxT4Z0XWfEelaZqfiS11SHQtNvLlIbvUporrSYmFuHYZHmXEFuGbar3lzbWkZa5u + reKS41uZVJTpzw6hPkTre6p6QtON2rxcp8qWknKLVlpfnrZbVpywcMPXw+Z1cXgP7QdHLPbYqrhacfaO + tDFUlSU6NXD0aTxFeCVSNHD/AL2dS11HD8ffFn4ffDbVPAWheK9Ts9P1P4keLo/CXhiBns1e41O4kVYH + ljkmjn+xyald6Povn20VyY9V1/RYZY44btriHG/aQ+y/8M//AB02iDI+DHxSxgRg/wDIka307+n4163J + 9ldRIzKzLMSCcHb++ZjtzkqSXO7GPQkDIryL9ou4gm/Z6+ObJJGwb4L/ABSwQ4Ib/iiNa5HODz6D2PSu + qpKi4UY06VWFWEZ/WKkqkZ060pS5oSpU1CMqKhTlGElKdRTmuZSjfkXFKdFwpRhCcasYSdaUp80ajlO9 + KUIqCVOKptRac6jnL304p8q+e/2Tvhz4s0S0+G/xRv8A4n+KNZ8IeJPgV8ONO0v4aTw+PJtF8Pzn4afC + qzjubO0u/FWoeDoGtLnwnr17FPongvRL+5l8Z6kLzUbnyZZNS+vPE+heD/FEUb+I/DFjrr6PdjVNIbWP + DMmoNpupwW6GC+smvNPk+yXUTAGO4iKOjBSHGMjxH9kT4j+E/Hn7O3wVu/C+ovqNto3wv+GelXsz2Goa + couV+HugXMUtsNUtrJr7T7u3uIZ7DVbFbnTNQgfzbK8nQMR638UviFpPw18DeIvGuuWt/daXpK2qXEOm + pZSXTvqVzZ6TaBGvdQsNPt4ze3sC3F7qN9Y6dYQebeX95a2cE1xHwx+qwoSnCUZ0JSnXlOUvaRblNzqT + i/eulLm5IR0i1yQtbT2q9TPsVm2DwdWniKOc0oYHKMJhqNCnl+MSVKGHweHcKUMM3Xqxmo+1q/vKymnO + bWp2UN/piiBLaGVFSQmRINMvQA7RzM4ZY7TG4tuZtwBLZJ5qR761xdYhvMZPH9l6l/zxjJ/5dCM5JP1z + Xzl8APhJ4F8Ht4i+K3gu78Q3CfHN7Dx3f2+tab4W0t7b+3dT8WeObfzIdD0DRb+a9SXx5fWU83iK91vV + I7Ky06yN8TazSXH0iLgEXSqpJUtx8meIow2f3nBDdQec81rRqVJ01UqwVOc3NuMajqRcOZ8sudwpt88U + qjTjpzLV7vgzTC4bBY6vg8LiZ4ujQcaarVcLPB1PaqlT+sU5YapOpKm6GIdah8b5lSU2o8/KnS39uzKA + l8vyOAw0zUcjO0Ar/oh6feGePUevzP4f8DfEWz074yWvjLxvrT6f4v0ubT/DE+j6r4w1fVNCu5YfFy3/ + AIm0+fXtFtIPC99e2eseHYrTw5pH27QtEuPDiz2txKb2Vl6P4s/tD+Efg14g8Mab4v0/xILHX4pZBquj + 6Jfa6bZmvLbT7e3stD0hL7xN4nu3vLi2S7sfC+j6xe6VbXNvqOpwW9lcwTN0ln8VPBfjX4N/8Le8Paq8 + /wAP9d8GT+NNN8QSWN/bbvDk2hPfJqh02eCPVAn2INcfZ2sWuSuDFBK2wPbrx+r4ql7soTg4VrwjzXgo + 1XCFWVpQvGUOadKaVpJOVmmZVKWIwH9n4qvyYVYuk8fgqlSVGXtMNQxEqNTEKHNJ8kK1KpCUasErKLlC + VOcefzD9mTw38JvCWieJ7bwD4xsfiLrlv4m1nRPiH4m0e51nV0tvE2m6vqGrSeFXsZ9a8UnwrbeHH8R3 + SWPhYaj/AKDDfPez+fd6jc3lz6Z8XZ/AB+H2uah8QvBMHjrw14fVtduNB1nwfBr9rLLYSSeXcJaa9YnS + rd4Fmm3alfTWlppts9zdXt5a2UdzMnjn7GXwxT4W/DbVSNR03WpviH4uuviJqOs6dFqUc2ta7q/hrwfo + niPXdZbWhFqU2v8AiHxJ4f1XXdVM4dYJ9SFpFNNFbpPJ7F8ZviLY+BPAGvPF4n8J+GvG2q6Rr9n8Nrbx + b4h8NeH4de8bpYXL+H9Ksn8S6ppun3c0+ptZxvFJOIAkha5aODzHVcuXzp+zyxVsPgKsILD/ANofV51a + arKN6tf2DdCcZVXKonF2dNxcrSUre1jMbjMw4lqZjPM63FGLr42njJZnlssRRrZnCKhXlLByVOVbDxVC + LpU/Z0XTw9KmvY01RpwiuRvPD3wv/aO8F+E9a17w54oj0K40q+bTdNS78X+GZl0zVY003UNOuX8IanZW + es6FqNvZQmFPtepeH9X002moWP2qyntriT2+e8tkso0Ed6Nmo2OMabqI+VNXt+cNaDkrkkL6lUDHAb5h + 8JeLPEFz47+FGg/ETx14m8KfEhbLxtdar8Lv7H0S/wBN8X6DrWr+MJfAN34o1/wza6z4R0nxFYeHvAV7 + qkEei+JbU3c+n6/aJDJFK0VfU2pzstgoCfMNSsiAzICxXV4H2rhz8xwNo4B7sBlgLDzw0qsalJKo+W+J + hCKhjoQpQX1ily/FSnJTUNd4uyaevjYnHVcXOdBfWqeW4XFYh5Xg8RjViqWEo4uca8lRnywUbqpCFetK + nSniHTVarTUrWuR6hbiSUeXen91CD/xLdR5+afv9l6H6muSj+IvgtvEqeCF8SaY/i+Kxh1CTwqtyD4jj + sWiVxfSaD/yFUsykkTi6a08nEkZ34dc/N/7OX7Rvin4la74g8CfEbwbqPhPx9o0Yu5YP+EbvPDWkmzsv + DXw41nWdPNlrXiPV9bGp6JqfxIs9Ne6mt4NM1i3jh1LT38uSWOPr/ifZ/D/4SnXP2gtQ0vxHqPiCzm0V + YdK06513UbfVfFHiC30T4Y+HltPD2kW2rzm81L7boehTTafpV75NtI18bGa5RpG5qWK+tU6dTBL2qdZ0 + qkalOtGpFR0nGNH2TqyrczjGFNQvKUkk9Vf08xydcP4vMMDxE8Tha9DLfreCnl7w+Mo4mrWjTrYOcqqm + 41MBWoe1dSrQVSrGahCNOTdjH8T+KvFetfHjTNM8P+J9NbwJ4KsNJ1Lxv4fu7CwaSyvT/wAJPPqWoXZ1 + Twrd6t51nZXXg+fTpPD3iDTBpE01zLr0Yt7yzjuvoOx8TaJrdpoWpaPfjUtOuHFza3+mxXF7aXVvNpl9 + 5VxbXVtFLBPFKDlJYpHRwSyOygsvzR4y+MnwS074XaD4/wDiToF5oWiftDeGNA07U49N8OavqOv6to/i + TRStvHq39g6bH4nawsdK1wIJLyytNU0q0vWMun6bPDd21tx/h34H/Az4W+AfiP8AEjSPFHihvBHxH8Fe + JtY8R67FbaFeajF4V8Waf4q8WXmuWd7pvhSLxNq93BB4kvJNHn8Tza8+laakNpFFFaxzxyYRlisNOrU5 + I1aLnUq4mdarUofVfd9pQh7OvSlyL2abrQdSLpS9peN4cst40sBieHMNmOc1JZPXpx9jk1XCZCoYDOst + o4qUsXXxmOq4qnUlmeBp4mj9YlUoxp2hGhzQk4QPaNH+Hvie0+Nvir4p3HxK8S6n4R1rSZtOsPhzLD49 + l0bR5m0fwZZR3FtZ3Him58Fhre98OaxqUd7ZeB9P1x5vFF7BPrEkMUiXvl/xT/bS8J+AtXh8KaF4J8de + JvEup6vqHhzRbix0vS49Ek1nTfGPh/wHqW+zk16Hxfqsel+IvEVnbPpvhzwvq2san5E/9mWcsTwXMnoP + gPwH8MvhZ8J28Jab4vn0bwp48u7iDRtWub7w54Ev5L/xrpMFtY2PhKPw3pvhGz0jVruNBdaTb6Rplvq7 + 6m09+hlv5XmX5E+D/hzxF8IPAXxX+FHgbwVp/ij9pLwDpOuN4M17X7DwjeeMvGNtbReHddh+2+NLi70X + R9ek8PL420V/BWk67rHg3T00S/8ADHhm8PhSDTtWbQ6qKEcBTdHGxwGY4vHxvh3RnjqUqVWhOeJq0sXK + SjGpCdPD06ND6s1OFSpWjKCpSjL6bJKGX5rjsVjswwr4mybJMBgsJltR4mlw3SxeX0sTSwWFxuLjSpym + 8vwzr0XmWKnW9vhKdWk60uWo6lH6q/Z6+Per/GFPH0fiLwrL4W1HwjqVnpdxZwxa3cEXU7aja3EDwahp + Nlcy/Zm0iOQ6raRSaOby81DwzFO/iLwp4mgtsn9ovwn8QfF/iz4bal8PdD0q4Ph+PWLzUPEM8s+neK9E + uIdQ8P3ekjQ9M1rw54h8I+IrWW5tJJp7fxLpki6JqNvpmu6E8WtWtvc23Y/s1+FPFmgfDaPW/iT4K03w + j8VvFlxq+rePbXTG0h381tc1m40RLv8AsXWNb0Syu20i8t9T1TSvD2qXugWXiPVtfmsbi6mvby+u/Qfi + jofi3xXokmmeBPFn/CE+JWgmksNdOnW+qx20sF3psgMlnJKgmiUlJXi82OO48tLa48y0mnjfOphKry2W + HxM62MrQXP7XCezo16zp1lVoxj7aMIRm0oRlFqPvt++tWvmc+zXCZbxLjs04XwMcJhMFWpPCZVh8SsZQ + rfVsPSw2OwyrVa8li8vzKrTxMPfryWIwWJ9nOo03UfL6hoF146+D2i+AviZqiweLNe8L+H7fxfPpmleb + aX/iCxXS7zxELLTb3SjZ3+j3WrQzQ3FjLYpBcaXcm2khgjm2D5i8Uz6t8M/gh+0X8I5PDOs2fwy8DfAf + 4wavo3xA1Syl07T7s6/4e1rxHNbKsek2Gg2mk2lxrfiDS7DTNJmKeEdG8H239siK313QnHO/tA/BTwB4 + 31D9n3Sf2gvE/j7W/iRo1lB4ZuPGvgPRPAuneH9V1bxDrWi+CrXXNU0XxTp3iO48Kz3HinxLp82lz+B9 + uo6Zd3IbU9Ru9K02GWL6v/ao0rTPFH7Mf7R/hjV4Wu9J1/4CfGLRtUto7hreWXTNU+H2vWV7Es9vMlxA + ZbeWZFmhZJo9wkjdGRWCw/tK1etV9gsPPCKlShP28atfEU/q8KsqWLj7NRoyjUbTSnUbd5pq9j1a9XC4 + Ph3JlUniauE4mjjMxzDLK2UvBUOHM0p5gsFDE5TisNjJwzStTyynUozpynDCYaVaNKdGc6arT85+FXwc + 8PeJP2UPgx4U8Ow2/gSPW/h58LPE2pXHhrTNMs4tT1c+DdCu7271mytRZpq8uqGFPt0t04uJpYre5knd + 7cBvWPBfgf4leHPFXxDufFPxJufGXw3u9D8G6T8OfB9/o2jJqnhOTQfDn2HxPqmueJ7e1j1bxPqPijUt + moNLeTNHaqvkxQBmaRl+A19Bp37NvwNv9QuLXTrCy+Cfw3urzULu8jtLWztYPh/pUs93cXM4jgt4beMN + JLLNIkSIjM7hQSIPD/jfRPCl1q3hnxz8avAviLxF4j1HVvEfg7TLnVPDmg6yngzWIbvU9DsrTS01FrjX + 4rGzsdVEGv2sMMOpWWmzTmBGs7qavWw9V4eriaVDDUaksfgo4fEVJYfD4iVDD4fFYbEQqUY1ozng6sql + NUfreEhSrSw88ThqlZUK9aE/jcTmeNr08Nga9fEVaFGvi8wU3Up81LEVqdGnVr16rf1up7SFGnGmm6lG + m6V+WD1fuDqAlsgikCjA4MeSBCwGP3vfbt5IAyfcj88/Cnj3QL34zftb/s9/C7xh4vX41f8ACO+JNaTU + fEN/4Zi8NeENe1Lw7ofiTw9fWlpa67qnjJktLj4w+H9Pt/Elx4JXSZtE8H2/hi1e+u/Bo/tTQ0P4x/FJ + vjnJ8HvBt03xFjTxn4o8TeLNX8TN4Ntj4K8EW2q+AYF0CxtND17TNWi0+DSvFevTeH9W1XStS1XV7200 + mOHTH0SPVNQg1dY8D/B34X/E74sftQ+DLifxN8SdPsNG+FvjPwpB40tIPDOhy+L/ABf4e1Oe812C20PU + 9S0e4sbrXm8R6pqV6b+Ox0KXU0hsI7azsoNM4cJOGZ4nDulVjhXhcXWhH2+HhiFia1PDzVPDUHHFUKcP + aVeRVK7+sKhS53PD1HovqaGHfDmWY2lxDB0MRxRkFLEZVllHE4PEV1WWY0JYLEZnGFZywkPqdGrmFGgo + 1qmJpSgqlOl8R0HxR+HWtat+zpbeGfjb4zg0+Wz8Wxaz4hvrDRdV+LkF5C/xBuL/AOHXh22spdF0vxD4 + pudF1O98EJbNN4dkbU9T0KCz1jSNb0a81O1vfRf+F4fAXw74Gmgj8WeF/BXhPR/ClpdWraxbHwN4d8Pa + LPo2lHR7G5Os2mi6d4fuRZazoxi8NXKWWq20F7bRtpMSssdc/wDDHWPiV8X1vJfin8O9Jg+GHiPSYdf0 + Oy1P/hHtY06dJdXsNZ8Iiwlt9Z1DV9Q+yaXHb6hqV34i8M+G3t9dt7W40mFYUCw/J37Sq/sv3vxGj+Aw + sG0rx/qs/hDTr2zudO1DXPhVAmoQeF9A8N6Jqvw8vviH4D0PXdU8q+8E3kVz4M0/VNW0KKw0DUdZdNLs + ri2b6api8roVMLheIsY8Ng3j3KU8vjg3CnLMJYf6xGjC1FVsS4QlBUnKcE6cIRapxbXjZflmc54pZflW + Ar5jLA4fF5hVo4XDqo6OFpKi8Zia0oQjP2NONOn7Sc5OMfdVleKf1rZ+A/hDpnxo1z4p6Frov/HmkeGH + vbvwN4em+HlzeWWg2/hfQ9Eslt7Kz0ePxvBpdxpVtpc2maXN4jj8Ozahf297DZCS5tJV6fVvB/gz49eC + vCfi3xx4Z8VeH4J9B1KZtD1vVNS8Ia3pGm+KIrL/AISDw74qs9G1W2KFo9OtoNU0+8mcWstqY5Ft5UmA + +YfEn7H3xB8AeF9Ul/Zk+LWuaH8WvEGmeJ7XVPE/jvxLbXtjLc+J/BOl6PqGt2l1q3w8+JGs2N5d+L/B + fw51yWx33KWmnaNqmnaFeaSLsmTxvw/8RdQ/YW/ZT+J3hj9pD4s6D4i+Ll/rnxP1bwL4d8O+IvHXxz8U + fb/E/hTWfGWk6TqCWvw+0DxnqFi97pHivxLf6tqPhLSvDfh7Q5vLu9XtNIso7iL5nOcZRoVsH9bkquWP + AVI4itiHh6OGwmIwlWh7HDSnW5IuVecp/VnOVONqUbptT5fY4N4X4hzxYfGcM5jD/WSnmWCyrCcMZZHM + cRxFiHmVOrB5pgY4HAtzwGHhzYfHOM4ToxxEWoz5qftfpL4FweF73x1dfETxz8UPhJ8RfE2o3Ol+Fvhx + rXhj4k6b4xvJ7/Qh4pbWXsZzaaJDY6jfab8RraFfBWlJrlr4Wt9UuPsWolPEczTZn7aniCy+FFp4f+OP + 2LU9f8QaVqmhaP4Y8LWml6ZczS6n4Yu/E3xCuLqLXbzXtKbw3o9zomlauPGy2EGqaj4k0TS7PRLC0F5J + bvXxv8E/FmqeD/hz8Bbr4xfCX4yy/FLxT4j1/wAf+LE8LvNd+DvCf/CJ694P1LwDd/G3WPFtz4t8W/D3 + w/daN4H8IyeGJ7j/AIR++1nTNMb7docU9xqmm2P3N+1L4t8O3nwu+GuveK/BPiG90658TeG/iGvhebxF + L4P1hLzw5bR+JYPCmp2a6dqo1bX7/edNi8Ib7H+076G4tv7Th+zyed6OLnXyDC4PEx+tRm8D9dpYfNZ0 + 6yeDeZV8JLDVKmFq4pPD1J4bGUJug4VFG8qL5XSrP0sTk+KnxjP2mW5XxRhaPEGNyapheH8xwOV5Vndb + JqVP2sMBjP3f1bDYjDwp4l4udGmqzquFOft6ntKfhKfEH9pT4aeMPiD+0N8QPgl4T07wlfaB4e0yz022 + 0LS9P8dtHPNqt9dXPiPVvhbo/wAcfHerW+iaTougaYrymKG7vrzS9LtvBFtPDJrVhe8IeMdH+Pa+B/2l + fjL4lHwk+D0k8/g3xH8C/jW+r6b4M13xB4esvF89nbT6d44vvC3gvWNY0bXJtJ1i/vbjwFfaho3jb4aa + rp2i6xe2WiW+sr4xP+2B8S9B8ZePPgB8YvAeqaX8O9SW8nb48/GPSvEVr4NudD+IfjnxLpUc194h1D4Z + eCPhn4Y8M+A7MxXmnS6zq2v2PiKB9H8LaDqeov8AZ9SbtPATaH8Yv2Kdd134f6BB4u0nwz8SB4h8AeHf + C3xO1Aafpuj3ltoem/EQaF8QrHxT4HfW7y40Hxf8T9V1Oz1rWbdNL8YazqnhO/0661DQY7JvnMnrYfMo + 16OExsZ4h4+ksJhsyrYzD4zDZhQxntsTKGJoxUKmX8tehCakqlOShSrUJRdWo6n6Pn+AzXI8nwWc8UcB + UuGq2aYLJqFfO+GHl2bYChwdnOTV8NhMBRwssxzXA0+IcVVwsaksdTxMcbQnRxMU8JXgqJ+i/imy+Cd1 + 4XuvCviPTPCcvhj4ZaDovi1fDNtDp6DwRofhuy1Cbw9rOlaFozLe6Ja6dY6Nfx+H5NKtIQbbT7q00tXi + ilhH5V6x420r9jWXx18dPhX4c1y6/Zy8XQsmv6xf/DHQtPvvB3j37X8fNXtdJk8KHU/hd4//ALD0DxT4 + r8E2sCa/4X1u71HwjdrpWj+J21MaeLj460nxX+07+0J+0f8ADr42fAb4Dz6Ta+IvBvgPQvj3a6v4T18+ + HPH+vRfDa7/4Sm7c/G7wj8N5tC0yHwHr/g/SNM07wp4jsvD3jF0iGq6l450v+xLy9/V/4p/ADV/DPwc/ + aEfxF4m8Na58L/F2k+HvE9n8HtX8DeHLbwh8PNO8K+Hb3UPiZDpV2dA8YDV9Q8WwWs17pt9deFLh9G1W + ys547S91W6utdPoYuCxWJzH2WKeEjkFDDZhhq2MwyxVHPcwnDAQxlHLHg54rA4jBReKx9/r+KwksTgcL + b2mHxOIhSOTKsky7gijwpl2e5hheIKXiG6GE4j4Vp4uVDHcKYGOa+wq4XOsHVwzzDJeI4+zy/H5Pj8LT + xeHnRqv2mHrawPm62+Gnx8/bFsP2R/jRY/FbwZ42+GOj6nFf+Ph4WvfHvhXSvFek2mpW2naxo994E1Kz + +HMCaXeWHh++0/xRqV7pLXus6rqr22leBNE8Hk2x/W/xnrng34a6Zr3xL13S2tXhtdMstW1TR9Am1nxL + q8Y1D+z9A0iG20W1utd1udtW1kWmjaZBFclLnUpBbxRvPI5/Oj/gnNqf7Onwk/ZVkfwNrOu+EfBMnjqw + 8K61efEnW/CdlInxE1fT/DWg31rpj+Hbm5g08ar4hvElgstU1K81e3u7mee6vv7PW3u69X/Z3+JPwg8W + +CNM+DGm+NPE37RfhGyk8SSa/wDGf4gajY+JPD9/rP8AwkGn+KvDmg6nrmsahM97qk+na7puqeELSxhu + PI0LSrG9jFvtDW/pY7F4fEPF4+piMFgczxNfCxwOVwwVGhCVDEU8ZVhiKccCnh6NLDT9kvYyrV5SWLtQ + k6eHquH57xO6WGzmvw3goZvj+D+DM4xGVSrRwk8Pm1PB5tm6qUsPm7SlRhjcTUoVsPhsRXpUcHOthIz9 + koeypR+h/hT8c/D/AMY/hNqPxM06y8SeHNDntNYDyX+nMNRs4bLT1mlv7aza3lurie0glRJ7T+z2uLTW + LW90iW0nu7WVH8y8HfETQ/gt8ANK+K2veKPGnxN8MagNG1Gwu7+zTw/rcdp8QPE3gnwlolqsPxL8WWk2 + l20GpavbarrVz4t8XgQy3ur3tjLBpn9naPafnZ8TvFHxV+AP7X2va1+zt8I/F/i/wPbPYQfEH4eeELe5 + tfA9l4Z0Xwt4U0q617VdP0HTNaufD+sagmu6xNokGr6d4a0zxNb+G9I8Z6RL4pt/Cuvabqvsnx2/4KL+ + B7v4fePvDvhbwRZ614nuPDut6Dp+iax4q8D6po2t/wBoWHgG+u4li8PePdOv5lnsPGdtY2TWupadNc6/ + aX+l6dPc61b2Gmap85WxdfC5dhsxzGeHoYqus5wWBp0av1mvja+AnSjLEUcJhpTrQo4iooLDUa2FnVxM + nOnRbVOXN9JDgHPsxzqhgOF8rw2b8PZvTyPiPGZHTzDDwr5XhcwxOJxGU5XmXEWMpUqmDr0snlJ5ji6G + Hq4en9Z+sSc40lz9B46/at+E3xmuBZTeA44dN0XwcvjbXfHWtN4a1Dxv8GfB+vWGha7J4wnh0dfE0fg+ + 2g0O5bxVNqN1rljpPijw5plgnhrVdUudf0hFxNI0L4K/BD4FftR6zD4lv/Dcvxg8B/EPSvC2o/EC9+F3 + h6x+LTw6F438U2fif4ZReHEtNW8R6LrGt/Fm707Rptb1HxDqsmlp4btLe8kLF7nyzXPhx8SFk8XfEOz8 + KRL8DfiT+zdoGg+KrC38X6ZJBonjPU9S+Dvwm+IHwg0Xw/4q0uLxTN4xt/BvgLxVZL4z8Rxafp8mvajB + /bTaLqvh/dccdrPxT8PfFv8AY88E2/h/4A+JfEuk+BPhX49+Fj+IPC3jj4of2Z4Ik8O+GPhQNUk1u68C + eDH8N69FaahdDV9fsfiDqekeHZrn4c679m1XVbW7urtKlh/qdHBY7NMwwv8ArDiq1SpgstpwpVuXKkoU + IYrEvB18RiMNXlUqqM8LicNSqU5R563srypw9DEZfjs2wVHB8LU8Vg/DenleXUuMKGBx2Hxk48YVsBjs + 8eWzzLP54OlWp4HEYacozy10qNSNOUlGrUrQUv1W+H2u/D3RP2VfgWnxU8SeFPDPhLWPg/8AC/SZr3xb + r1n4X06a6l+HunXkFrbavfalpnkaoiWVxfWUljdxajbNYtf2bwvZiePnvHHwa/Z1+Juvw6bp3iuz074h + fCmDTZ7Oy8GeObW81jwjaaNoOu+HrSTVfh9rN54k8JDGi+Ntd0s6t4n8FXt6kOsrPDeRXsOnXVt/Pj8b + vjT+0z+1fcfsi/AL4DfDf4hR6L8Kvh/4H0Xx5rnhi6+M+haHpvjbxN4F03SrWTxT4p8Pv4Fs9M0OPwgG + itj4sstMt57PxF4nFlqGqeHbpb3VPrD9m+w0Txh/w0n8H/2o/Eviq3+MPhCXxXr+qa14l1nwangfw7Y3 + EfgRr3wjZp8QPH3xL0z+2fE2va54Y8QXF7f+DbeyhNxpk+k69NdCz1DV/Zy/MpUc5xeBr4PPMlxuGwtC + vSx+Iy6vhcNXwOLwmGzGlUVavHC1HQWFxNKtUjD2rlGpGXLpLl+Xzjw1xGS8P8OcTLM8rzOvmtbF4XPc + syuvgcXmXDNKjmUcvwX1qNPGynmMMyxMq2HhDBQccLjo/VMVOnUmpr9Lf2TNQ0LwB4V8ceFtX+LkPiTw + z8G7TwF4SuvE+v65r934ftLfR/CQifxJH4v8UrY6EttrsElja6hpPhy5fw9oeq6Lcw2giS6j3+U/G/8A + bP8A2O/C3inxb8LvEfibxp4Ms/ES6X471j4yfCbQdfvfDOravolt4U12G4/4TT4Zx+INZvrmy0a40d9f + 1qbSLjQNJ8O2Yt/EGrWVjbWQHxd4M+P/AI/+H3wK8W+HPhl8LdZ+L3w58BeNfAF74/8AGXjGw8QeBb27 + 8FW/gH4dajpPjie/0C/02T4c2vhfw74f0LUBqV5oOrpquiJaeNLyytrP+3YK++rvwF+wj8af2etA+I/i + T4eeCfFvgXxxDqhsPEM+hXXib4iR6z4ij1tPFemp4r0FtQ8dReJdLuJfE9hrB0/WGm0UaffRLLBZad+6 + 82pSxE8uzOhRS+vZdi5UK2MzHB4x5NReMqVayUsbCpGVXEyp069J0qeJi7RqVNaSin6ebcG0KOcYLMOM + 8Nic3yfiyvisPllLhSeQ0+JIulQyt0liOHqOLqTwWIq5Xi6HJTrRpLE+3+sJe0VXCx6rUf2+fgf8LPhB + 4d+KPxq8feDtE0/xTDqupeFl8FXN547i17w3Za5FoK6lbSaC+sJm0vJH069lu76GeaTT5rm/sfD+tPqf + hPQfM/Fnj39knx5458RfEezh0vxBrUOmWmt2XjnRPF+uanbeIr2ax+HGi6RbR+ENBu9cvLTT9S18+DfA + uo6jZ+GV1GHxR4el0PVoC9lfW8xZeIf+CeFr4Q8H30uveEtM8JfBLX9Vi8Cf2j4h1a8e6vvF/jbSvFF4 + fDlja6tqms+Mk1nxhBpt5Lo622o6lFazQRXuk2nh/WoF1DwX9p/9pf4Fa5+zV4Ei/ZI8VfDXVPCHh/4q + aGNS+Gujxp8O9OHhXwx4f1z4t6hLonhrUtY+GdwLizn8L20mjQRP/YN9q2pSWcUC+IxpOo6N9LSw+QY7 + I8NgcPTrYzifmq1Vi8wx+HoZJOHLOjQrKE8MqlDFUMXheenWc50cTz16Kw1KcISn8Pw3l3GvDmbU54mj + nuDwbx2EyfHV8uWIyjHRweJp4TE47AY/MK7oYGFWpg5PHezxDo4f6n7LE1YOEFJ+nfs9+D/iT46+Mnib + 9t74x3N18N9C0jw5FcWeh2WmanPpPizwbZ+Edcs7TUbe1t/EviG6ttKtdEvNK8TLoti/inT5/EGoXdzp + dxY6/c+INLtPDf8AgqF4p+HHiL4f2f8Awo74MW/x/wD2lPiNc3eqeHfDd34A+MXia40jwtYR638LfGvj + 2y8JaJe+H7Wx8WaBHo8Xhu9h1O3lu73S9Ga21zQPEGmafY6dP4ZrMX7UV3eeIv2cviV8RfA37OWo/FD9 + njxv4qsNA1r4i+INU8P+ELDVfHnjlrP4eJ4Uj8Z+Mn1JNI+CGmeLhp0mj2tnoNtoXh+CO7s18T6NYPoP + Y/BH4gfFX9lr4N3tt428F6ddeOl+F3jrSvDnxo8Ima9g8Qnw54p1nxTqtxofhjSoPFVhDrWk+INa+JWj + 2tu3w/juvDs2h+C7z4rw/wDCPeJY4tB8B5BleHoR4WzuLxma53Xq0cPXweYYHNcDSxOZ0KtHC5zicbgK + OaYejGhmE6KngKscDi/YxqNvC3p1Jf0fGvxXgeL+H/FXhvHcM47LeEKmUYanwksxznhGlPg7JlUlVynA + 1qkcNiOIcrqUcHiXip5XmeYvG0p1Zwc8NCNJfWX7PHg7xN8M5fEfxc8Z/B7TfA37QGvfBmbUPFfxb8Ra + 14qtvCLW/iLxHoHinT/BEmjanpvhjwnp2paW+p2+hSWi3dh4nvPEfg6fS9fuLfQpNG12bh76z/ag/bE8 + C/tKfAPxfJ/wi8Z8XHVvhv8AFiDRrm3+GOseENclTw7b+ENMnTwvp76xZ3em6pqHi3w54khvfHM8Mg0f + xBqqwvPpeix1f2Hf2jdT/aH8JfFLWPj/AKgtxpvxTOlan8O/B+s6pb+Gopte0/xZ4nv5/DXg/wARJ8UN + eQa3B/bHwyHhW/sI/hveuYdNbTPDq6r4d1rWF8m+IP7S/wATNH8M+L/jh+yt4utfFfgX4T6xN4N+L3w+ + 8O3Ul7a/C/RU0LwRB4FuNNPxc8a6H4e1qxu9Z8Npt1HQvBFtq0UureJ7G4up4JrvxJHpUjm2Ey/OMLjM + VjcRh8jpf2NmWEnhKWZ5xRp5bmNTK4YTCVFSVbLKFOu6k5Yug6ftcPCEKq5Gov47C5Fh8L4lU8JkWSZF + huKM1r5VnPDedrFY/L/DHKMyrVsq4moZrh8xxDxGDr5hmGYzr5FQy3MHLLcTV9l9QoTqwvDW8XeCPhFo + 3h34RfsKXPiXV/jH4++CWpR23xm1LRPDHizR9Q8NaF8R/EmgeKzPD4gbUoW8P2j2HiyMaP8AYfEet6BY + afFBBceCwP7Eg0D0v9pf9lKXXvE3gP8AZs8L/D3xI3wg1PwXp+o6D44ufHx1a4k8YWvxet/Gnj3RtXl8 + SWXizxlZ6rrOi6rqmuQ69pyLpH9qWXhsa9KNE0a3GgcB8K/2t9M+OHifwV8RPDf7O/g3xN8Vde8eWMHx + Futc+HnizVr/AMH6BZX3w88Jx+ItKbw5rvxO8LaZrceuaL4g07R/GreIrXRNUsfh9Z3CXlrc2eqaZYZP + 7Wk0nwT8Y/C26i+I2pePf2gNJ8RvZ6N4uu/G2v6Ungfw7rum+FvD3i+CC38afEnS7DXfEWsx+N9C8W2/ + gbw94ht9A8NRWVjqusaJb+Fr+4uLrtyKjgMLjoYbKKtKhi3D6vl+ZUsxpxWT5zl2X4R5ficFmc8wyOOG + xqxWCgqeMeJr/VFKKnQxmIw0Kc9sfjuM88xmW0amZYnK8Vh8dm2ZZtg83y7+25ZzmeMzmvV41lmOQ5VQ + r0cDluHxWIxGFowxWFwVSvgsxcsJKcUpvyD9sb4rWv7FXxD/AGZPFN98PLrw5B8H9R+F2nfEh/gufCnh + nQPHXiG68H6NrHiy9udMutG8B+GNNaTStF1rwpoN9ous6Y1/pH23w94g8O/8I/c6Ba6V+wMH7aP7L/jT + w78N9P8AEHjjRLb/AIXD4e0m80jwZ4u0rzP7X03xn4Q1W8XQ9YmMeo+DbpXtYNb0jWXOuXHh6O/0bxFp + 02oS/wBjar9m+UPE3hDRf+Ew1P8AaA+PnxL8MKNI8dz6x4h+FuleBrf4gWulW+kaDo63Go3/AIS0+z1X + xV4X1jV/hh8FZoLvQPEupeMLPSDfeI9ctrhta/sfSdE/Pf8A4KA+NfgH8W/2jPgp8Z/Bep+H9Em8FWd5 + e6xruuwaPpFh4q0f4c634O8Y6vaaRF4P8Ynx5rPi/wATvfeHPDOm6J4t8OeH5tS0PQvENr4e1nGEl8PK + sFGhnmOp18fHD5XjIwoqn9RwUsVh8z9hiKf1rFV6WMdPEZevY0HUqVKEcT7KnWUE5SsscfV/4iFwzwNi + MVw7nWXS4ZyvirE59nWCWeYvGYqjg8Tj8fhssy7B4rC1sup4ivjcXhszpTwuJrYbCZbiaiqfVqVOisH+ + lfif4v8A7OP7SPwxsf2YfCo8a/s+6x8TdIvLH4cX9j8ORoOm/D/xt4g0DxDqvhfUrTT9NubbSJJ52bUP + FHh27A0/S9Y1JItR8PeJtL8XWtrqmkc34m/Y4+Hfhr4At+xnpPjnxO/xG1ebxP431DxDoa61pQ8ay+Jz + qrap4dutf8dL8aL7SL/Uvhl4YvPDen+Rc3xjXw1bXVx9lttVn0nUvmb9lvx/+z7N8b/EvxQi0VvEvhv4 + V+BNTtdM8Q6loPifSfF9raeAvhtZ+LJPE83hzxb4luJdP8O6Za/C7WdZ8MaO0k1p4fn+LnhpRq9xdajc + Gx+3f2oPjX+zv8Uv2c/FnjXUfiQ/gLShpPjLwn4x8QeHNH1LxP44sPBwtvGGg61olxqXwtvNfurLw5qG + q6Pcaxa3z6te+BtXvNDtrDXvtdvNfWK82R4XMc1bx+BoUc3zCpj45RgIZdTr2zaWFm6+Fw1HDSfJUxNS + rThXw81RqzjhqcoyUY3iuTNMFkvBue5LluXY3ijLMFmnDnDnFPEOe5gstxmKw+aY7CYqOXcQYmrlWBq1 + MTleHwuaVYywaxFNYjFYirUjXoQqxlHyr4M/tG2Hwi+Efj34SeMPG3xai+JnhT4ea3NL8RviPd3nxEtN + B1Tw14I8H3MOp65qOmaRqvxHsbbT9N8X+Hr/AFfxZ4l+DmieGnbT7pbe11C4sy/iRbxvh5rms+APjp8Y + fEvxF+N/hTxhoMulRX3g/wAU6z/wqXRLzR/jWw+H19oUr+H/AIdzWHiLwr4ksPDdn4g8S3934FGnavDp + OteVqMzXN3D0P7KXwW/ZY+MnhHW/CVlpPiXx0PBXgttK1TX/ABdpvgDRbfXH+JWp+Mku/F/hex8D3s3i + P4fazPNoOriw0jUm8H+IvDdkdH1O50SPxhLqetP0sPx1+Gfg7xjr37Ffw3+DF78Uz4Ih8WTa94N11/FH + jGM2M2t+GPFupXfieTxJ4X123vm17xH4/wDDk+i3TazrtjYW2sLr2vT+G9I0d44+3CZ3m+BVX+1a2W0M + NmWMrUq0aWBdXNKuLeYRxeIwXPONWNGo6mFc3Xw9OnVo4inOtSlFOcZdVbhThWhmWYYHw7yXjGWd5Jhs + VXzdVc0jl2UYLh/HYGthqmeU8fisXVzKg3PMstrxwuZYt0atHGVMDioyqzp8+l+0F8N4fj/+zH4O1/8A + Z+0PSvGHg/QNN1j4haL4F1mS/vNZ8R62JovFGm6df2HiOPxDa69rsviBLy71Ww1+WLUtX1mWO2uNevvD + +seJNF8R9F8MPhJL8Jf2Cvi/o1xaX2m39/8ACz4xz3Okal4ftvDY0u10HwTqvg7QIrHR4NA8MX9pZ3nh + rw1o+riTXdOk127utRub3ULhnnSGD8hP2jP2sf2pPFcmtfBf9mjwJr37LPwu+A3xL+Jvgw694XudS8PT + eN7XQNf1HR9DfSZPFnhHw9bXV9aaHpjeIpPBfhbxJrOs2kXjHRvtuk3Z020vbH9UfiPo3xx8Ofsuww+O + /iX4Z8EeK/Enw2+L2p+O/AepeI73VWup7nwNHf3Hg/wbd+Kb3xNrPjEabpum61pUkMWt6bFaT+J5PE8E + 0p8P6fo99xZVj8qzHE5tmtDD4ieOjicFh3jKtCpCOJVp0MU8FXr+ycqNKvCCrOq5Sq1IRdHRK/l8ZeGf + Evh1Qy3JcZxPRwmWceRzfiR8KvMaebSyOHD+FwlTKa/EE8kw+OwuFzXNsqr4WphIYGtKnGlzrFU6M6da + UPzc8U+Of2+LD9j79lX4xWV/F4IWTQPBmmaLZ6OPAWq6JrPhu/8Ahz4U1rwL4ltbLS7LXdbFzq9l4T1/ + UG/t3Vp7vQT4jsdHt3uoZdUlm++/2yfjr8H/AA1Do1x4pGs3PxX8Pax4M0zxt4V8/wAXeHfDuj2CaPp/ + i3W49F+JWneH/DNhrfizRNE8bjS/C9h4W8WWVxret+N9Hs/E9g2nhxo8fwt/ar/Y18aeFv2efg7dfE69 + Txl8LPgt8OfGiW/hnw/r+q+HbyPw/p2jeF9e0PS9Ys/DWtaXqOq+HvEGkJa6vH4Uli8QaGtpqttbanZR + af4ttrb8gfjl8SJf2uv2sf2hPBXww+IOiQfDG08GfFPVrTx78OvDWva9q3jrQBf/AAevfEOo+ItTHj7Q + tJ8eXHgybw1oFl8PLawto7jTrP7Klvp+r/2Va38P0/EMM8qSjg8FSlSUsNRlXwKo4ajiMvyPGY/2GIzG + bq1o47MoQpYuk61qGNqQw2Hqulh5SjUmu7w04QyrjXO8RS4zy58CYPJcLjuMcr4gw2IzjKqua18PLKp4 + bB5dGjgcTVwlHLarjUw1bBTeJnVzJ4ipjKdHkpV/1B+HS/ALx38WPGPwnT4gaN8IfCfx/wDgzqvhz4bf + Byx0rw74I1/xH4Z8Y+B/+ELj16106y8L6W0Zm0WHUmOl6lrviGfXPEWjW19ZxaBc+F7q11HvviB4A+Df + wl8AeHPgV4d+IHi+20L4PazeW954V0vwzouu2bX/AMSNT1X4o6eDYeItUsdBu5NEuRDasmqW3iS8lsPF + OkeF9Da18XeJdO1aDwSf9nL4SfDTw58Bp9JtNb0r4t/8IrqFs3xA8cW+p+HfC/gzR9A13XtJF7DH4a/4 + QDwaml65rnjTxDrvhS+1a3174kW3hdrC98KWVtqcNhNY/Xv7GnxZnn+F3xg+LvxG8eaXrXwr8Mahf2nh + 3xxMullv+EZ0u/17XILlp9L0G3167sYPAuufDrRorDWvEPjzUl8Q6RrdnpGv67pradrGs+DgaeY43AZ7 + lH9pYSrltHMsJmU51q1SNbFLF01CnGnha1WlUqYzDSnUjVqUVHD4fC1KdKUadSSPCzOGLpR4e4ow2Nnn + OOyjG4zgjPsDhcvwmCqShg5ZlleA+o47AUsVHDY/M8trYDE1KuIp1M3rYqvjMVCUI/VZHztN+wX8N/gH + 4v03w3rNl4n8Ufs46/pGo+OPjB4g1zxbrem2C+LJ0vk1u1TRvDmm2unf2brXirQvgnfWNvrHiGDXtMvP + DVsdMHiexvfHeqeHvkT4Xf8ACo/2Wv2wPDHjLVvDfjqx+DXjnw1quufDvx14c1jSvGehaJ45v/APijwZ + eDUPCOnfDvXPjC2hf8IZ4Ti8Ix6XeeKHHhvXknutd8KNfafq+seHvZPgf+1z4xi+Av7X1t8XPiv4Z8cm + 68VTWfwb1H442Ftb6H408IeMvGPi3wNqU9v4MsPFSeN7jwzNo3hxNdn8H6xaeFtR8P3d/qGmLp1np0CB + OO+KHxv1j/hSt7+x98KP2ZobTxL4Ll8N+LNI1LXb+78SeB7bRdb0nxf4j8ZeJ9L1Hx/oHheHSrS7sE1Z + 28Tm8uvD+seEdX8f6jD4wurm0v77VPQ4kzmnQwlDOeKo1M2zqhHEUsDlTzGpWzLD46GVUquUVcZhcpUq + +MlB4qtiMBWxONcK1ejWhUjP2TgvQ4AyPjnAcdcW8E5dnmDzTw9w+Q1I8ZZ1SxcMnx+T5HisZg8tx2aZ + VLielQdDK5QwtXLs/rYnLKmPq/VauE9pGjDmPpH/AIKPfA3Wvjt8RfCmkeB9O1GbX4vAsS6trtnD4tju + PGnhqLRfi5qNz8Om8Q+HNH1vRPCF7aPPb3+ii50CbxNr/iPxb4Zeyu3t/D66fqHw1pn7X3jv4T/HDRP2 + arr9mX4o+J9F8NeD7nwZ8B/hZb+FvHWuan421zTddW+1b4jeI/EnieztZPEOl2z3PijxN4ms9M8GaX4l + BsvDs15p2l3/AIUn0qH6f8JH4A/GTxX4E1DS7Lx98S/2lPDp8BeNNJ8P+L7BrfwVYfE/wBofww0Dxdq+ + n6jpt54Hm8QXXg26+H9lov8AwjXjb4tzeFr/AFO212K0t9f1JbazvfqLxL8DdJ+I3jTwZ+1v45j1v9mb + xj4E1TSPDPi7S9C0zxTrOpeK7rVbu0tLE6Xd6UPCsup6vN4j8by+FIdWvPA3jSLVb3SbWTRhe6RILnUc + MhoZJ9ffEVbDZrnuYzhQeIynB4vB4TDQmqsZ5JCGbRqVcQ8NKlNYrN8DhcJg8Y6cXSo14VcUsZT+Rz/M + Mk4iyXhDgzC8eVcs4WyjN8dxDSzClTzHHfWs+weQxdTDYrh2UsVWo5XmEK2U08szCEcJhqlaeJxHJSoz + cZ/F3i79si3+E/hyXw7+0l8Ef7d1zw/dXv8AwidjoI1r4XanP4I8G+E/C+pXdlq3hrRPhZo8Mvw60Xwr + f+K7i68J3WseObrQf7Kg8JeKtHvxY3niW2+fPgv8HdB+N3xC8SaV+zX4+8b/AAYg8a6PZ6x8QvgH4s8c + Ta1q2sy+FfFofxNpeq+FvFei+FrO+0LTL34t3fhTQYvit4G8b2lzf/DbxoZVv5Y5Z5PStCvf2crq6+P/ + AMXfgx8KPF2r/EfWPiT8R7rWvh/8fB4U1/TPHdnfa74z1zUV034d6d4s8M6je2PjTxj4i0Hw34c0/VtX + urzV7F4bbSNI8SR2Ah1b01fAHwD8ffEbwv8AtF2MGm/A74qafcSeAb/4RP4Q03XPCfiXxJ/wmPxR+H+s + a34Ogfxt8LdSm0rWLzwJ4gvZ49cFtZf2hpVhrGhR/wBpeKtQ1bxZ8jxHl2YYfiDFSo4jC4illOYUMXVp + VeXCYzL6bqr21Snn0lUVWth5VvZqnXajUi7VJyjCdQ/q/hTiXL8j4GwtSjk+Y8JcR57llDD4jGuv/rVw + djs0w0cJnGAwP/EOsPU+q4bAZjRhVxOGzKi44bLMbRqzq+yqXpHov7Sn/CIfseQfAn4bR6Rp48A+IpPh + 1pHxR8U+J/GlrJdJfpc6z4L8Hr4OtfHui+L/AAvp3gfwZrXibxP4t8bpB4NOjeC/Dd1BqOn6RaX9zp6L + 7349+G/7IHx0+Enhz4T/ABFv08IaxLonw4gbxLqFleadC/8Awh1v4Z1PRdDu/jBD4a8I+GfEH/CR+G9L + 0iGfSItf0/Utf8MXlndx6NaiCxWx+A3+DXxy+PPiDxV8NrLTtd+JHwO1e6Txf4D+MEfhLXrfVdZv9Jsf + jJPZRXXjrU/ifc+ErnxBqHhr4g/2KmpahpnhG10fW4vDOh3cD3PhjUBe/fB8c/DfW/hOvi39pT4d+AZv + i1pfj3XPDGuXHhLxZ4Rs/FmhWNtpfxEs/C194k8ceFtXsYdJvNa8GeDdY8ES2ml+ILi08RzhtEmtNLj1 + PU/CuhfU5ZxBXz9vKa+URpQX1ytk1aNOdCOMzH63VniamPqQ58JiJVHKlicNjML7KtVwloQTlQcz8e4w + yzLOB8RwRxRkfGeZ43iqVT+0+Ms+4Zx9XGYulQxVLK8xyDHxp1sVUeXYmNSWMyvMsuxmIp4eGMwGCjUp + 89SXtPBPgjJ8K/FHhT4tfsw6b4J8c+LviFpel+IPhtpGifFCw+HuueCxeaNp/jjWbF9J8QyomoX/AIwu + bG98USazrEmqatodn4utbjTrHxro+garol/dcr8G/wBlv4eaz4R8PaL8a/D9p8Mf25/EXhnxtbeBW0rx + P4h8C6TLLLb+Jdf8G6ovg7wdo/gDw5YQaZ4k0DVtKmgPhPUbbVV8Gzaouq+KrDWdA1bWfOvCPxr8A/8A + BNrTPCekeB5dJ+MnhrxZ8TNJ0r4h/G61+G2kXvifW7PxHF4FvvC/hzSNV0HxD8PvDWiWFv4CuPEt3oob + xX8XNW1TxDNaXUmhaNZ6x/Y6/cX7Wv7J9j+1V41+C/7Rnhf47Xfwt8PfD3QNf8P3mpQ6frEGotNp2uS6 + pYy28VzdaLe6drFj4j0y70O5ttRiS6sJXuLcaVqd9LFBa45qngMxzz+yqNWKo0auVYrJ8txP9nZVUwGZ + 4nB46k69XGxlVr/VfZwx6p41+1hKEVO9WipvunnVPG4rJMfieMK/BXCPFGPzPP8AB+IubZdn+PzCvmfC + uX4zKc5ox4ewuKp1qOX8QY6nhstgqtLMKHsJyq1MXiqTnGn8/fsLeO7b4daR+0n8IP2l7bQPh34L8M+G + YV1HS9L1LT9U+Flt4e17xf4y8PX/AIdsvLhl1oXj+Gde+HGlauuuWEXiO61XUbi1vjbaj5unW3vHirwZ + +y3e3fw60P4QeI/CjeDPE2n6p8RdTa/n8f6j4IuNFnvfFOuz69P4ltfBvirwZElpb+Efjc+qfDnxXr3h + iw13X9V8S3GtQrrtw7Xnxj8Y/wBl/wDaO/aNsvAY/ay1a4vvh/4f8SR6t/wm/hGHwx4uivfCf9o/DLX9 + Ynj8feCLfRD8MvDs48O3XiPQvH3ibS0u9E8F6h4z0S8SG61vTda0HW+NPwx8E6/42+Gv7FfwF8D3emQf + A7w3ZWGi+LNa0HSvG+o/EW016wn1ZpLzW/GngPVdMu4rTw/rP7Quvaboms/Ef4eW2ueJVvta8NXllFL4 + R/tWeHc1ll+Grr6tjMGsvdSplEMwnfFV8TicHKph5VW41HCrKpVxWFdVtzrSklGpGL14OJeCuCsyzrJs + RlXFWTRzniehjMw42p8JVaGI4UybKcvxkPr+PpVa9ejXzCONzCdHOsRh8PCth8sjLE06iq/2bXt+gX7L + Pxj+NfxQ+Avxm8VyXumeLPiD4f1/xmvwvjtNE0jR7HxFo0Hh+0Pg1dR0MjwvcItz4jtda094b640GaO3 + tk0u41g31leatXR/syapqHxO8f3PxWvYfCui65ceEdd07xpHbfCnVvBPjXUtTuPFceleEfFVvq2uPqlr + qng/xb8PPBfhh4l07VfE8Ru9Ds7aHXvI05LSH5Y+O+jftR/s5fs/+DYv2XfDng74J3+onQtQ+J+oppMf + iW30O+kfVLa70vRNE1nxT8XJ9I0W0M9n4gm8K+DfCXjzbbTa7/Z2s6bLDNPqfo37F37QFn8e/wBoj43a + T8NPA1l8MPhv8K4tF0TULU6L4f08/EIappovNK8S2beGdI8qN5dUi1LUrK+PjPU7AeFrnS7aDw39v1S+ + 1TSdsBh8PTyzK/7QzKni83jVjQhgKeMisT7WioV62YV6NejRxFXD1I4qcaNSEmuXB4mFWHOqbq/I8ScO + 1q+H4ozrhyNKlwfHMMZjKXEE61GhjnhcNXp5fT4Xx/8AYCpZVJ42bwmNpYKGHeFxFqGIrTaV4fSHw2+L + Xi/x3+0N8TfhxcRXQ8BeCYPEKW2t3Hg+LR4L3XLHX/D2kW0OgeILuWRPE4guP+E0tPFE1poltb6dqNjp + kMN5JHMDddN+1v8ACrwr4x+DfxK8R+IY9R1HVPBnwj+KF94flN9JZw21wvhmTVwbuy08WVnqkKanoWj6 + jBb6rBewwX2m2t5bxxXEKSD4p+Hnwa0f4eft/wDjLxZ42DaT9t1LUpPhp4rl0ibw5p3iS91e68TeKbrR + 11TXfDF/aa9qWqal+0t4h8Lyv4R+IWlXV7c/Czw0NW8JtLCfJ/Rz9o1Af2fPjmSJFP8Awpf4p5Bmkb/m + SNaP97Hc5688ZNVlVStiaGJjjaf72jmFdOE5Rqfu1WlVw2llJJQUHDm5tOt7W8rj3C4PIc3yLE8MY3EQ + weO4SybE0sbhqDy6c62My5UsziqtCrJ16tWrPEUsbUk6ddylOjiaMZqUqn42+Kv2Q/2Z9e+D37Enh7w9 + A/hGT4p+B/hjdJNoup2uq+GtblGjeBPCyNFpd/eR6veX0eq/Euz8Um28KeJ9Csr2w8L3N3rdnrEWl2ME + X03p/wDwTB+E3w18U3PiL4Saha+GrW6vvD17FDrlra3zeGW8O6ldX7WvhGz0KHwzYzx3miXMOg203ihN + c1XSIdO03U7LUXvoTJXn/gPVP2xvBv7OPwH0X4SeA/Dmi+E9K8C/Cu51LWNB0jTvH2o2Gm6toXgfWdUv + b7RV8fXXjLU9aun1/wAU+I/FNhpnhbXrvZbWthoV1rX9rvrtv91eKfg/o37RPhP4feKPHsOveFNa0Ow1 + HUIdKtdK0qzmD6nJo12xutL8d+Fda1jw9dOfD9hc232dNF8U6H9purM6lbzSStXrY6NavLE1/q7rY+ss + K8bjvrsZf2lWc54nl+s1OavzUY8yxPuKVScoKpJzpp0+TB8V5w5ZFSxvEWIXD+EpZwslljKGDzfF5bhM + fTpUsThcZlUqlapQr4v6hgqNXC167p08PTg6cpYehOK4fxB4V+H/AMJfhpp/gf8AaR+JOreLtK+JnxR0 + rT9Av5/Efjfw5daZfX2iadaadp1prd98Rtb8W2GlWtzol/rGqXqeKlso5NcvYJbWCxmMUvwl+wHoXw98 + c/BT4+fAPUPjEut2fjjW9H0XwZ4d1fXPEuoapaeHYPhz4cvfCmqxQ6lqNpq2nReI/A8XhOeHwpp3iSTU + dG0PRre207xZeSCHW6/U343fFSz+E2q+BLzxpZ6aPhN4jj8S6B4s1aPSvGPiDxRYa7H4eu/EGijTNA8G + +HfEE9zok2jaF4qbxFqN9/ZlrpEcVlcfapA7wN5h8Kv2M/2a/hv8W9Z+JPw+sZofEOi2lxYf8I1/bGn6 + rYeG5tc0XwWivdSXNlceNriY2nhLTdS0Ww8WeJ9W03S7rUtV1HQtOs2uLOSz86jSor+0MNSeBinHD4ec + a+B9piHhlBTlSoZhCr7ajUlz1qinGm4VEp4ecoXVSXnYDO8a5V80z/MeMsGpZrLNeFpZXXeV8PYjiLL8 + NGVfGYzJ6lOnk+e1MPX/ALMVLFYemquVqhV5KdSpOEYfHfww/Zt+BXwn+HfjT4YfEHQNW8G3ngzx34wk + 8CfGFdG8UeAHu9W8S614zvNJ1zUZfA1xpdx4hsvAN7Ne6xoGveNfEnjRtO8H+I/Ds2p+LLTVtb1LTYvt + HwLpvw7+BH/CMfDX4geP/BEvxL8a2fifRfg3pOu69PdeMr3wl4f8MaFc634O8F33jPWNW8ZeINH0qbTz + 4h1CzS7ktdP/ALRtbX7OLa0sgfkn4/eD7i38d/tF+Cvi98TprT4bfELQJPiL4A1X4n+ILK0+HXwu8WaT + p2nz+CrzSNTgv38R+GrSWPwz8S7XVNOFkvh5zoXh9jYXGteIY21z5r8JXB/bq8FfBHXvCfxJaX4z/COD + 4w2Oj+M/FWs3tmt9ZXepaC/im38KeJdN0zxPoPjr7T8PvE3hPwr4gOq6EstzYw6rZ6vp0mqw61YaKszo + 4bh2vl2DlQxmd0quWe1yrHU6zw9LH4xwoxqZVTnmCqJ4nLJYihh68ak69TF06Maiqx/2drtyrE8Tcf43 + PovPslyrhynj8pebYzNcVmeaVsknVlWrZ3jMzxHsMVisPgsyr4yvisJQwXssNLHY6phsT9XoOnOp7noH + jf4d+G/2mf2hfC3gjwNoXxL/AGhPDnijwg1jr2o+F9B8SXPhyPW/Fl5q3jLXtJjbx7J8VYWs/CWu32nz + aZoGieHPD8+q/C/yLG6uU1Gwa59I+KfhL4h/DH4B6N4j0jTtPe7+Ieu+G/GvxX0Tx/4y8D+BND8L+OLz + V/DGs6RBea74ol0Z4rHQNfj1Oe81iLUtU+LWsanpvhe3k8VX81lDPb/ZL/AnQPFPhT4WaJ4k8Q6hqup/ + DE2Ltrujvp8Kavq2jeTZ6om3ULTXJdJaPULWaCyu9IuNO8WeHIlmsdK8Raf5t8byX4pfCXX/AIl+LPB5 + vNfeD4ZaZJLeeIvDdjrOt+HtUutVtvty2E9vqPh77LqVz9pkvbUvINf0b+xk0uQQ2+sxa9fW9py1sLml + eGKxVSty42ag8FVy+jRwkcO63I+eVOPtP32HjGFCrXc6jrU6arToupKXN6mWZ1w/ho4HLnisHXoVJ4+v + xLj8dgK+J/tijldKtQyehhsNVqVKdWFfCRoVsqoVI4elgMdCjHEV1S/dR+CP2vtA8E/Czwn8Ml+FXhPS + IdJvPsPjDwp4q0/4i/EiHTza+FpdC8eSm0i8Ca7cX2saFHo3w+8J6Hok0unatEket6Knhm40WewaW58S + +HvhH4M/thW2geEtN1HWfhv+0l4Y+H3w58V/F/QLvwd4M8XeA/FfiPwbrHiPTo9b8Va1r3hzxFe+J/Er + eIviVNqdx4ql17UpNQa5Cpd+I9c8Na6+nfTv7RnwR8a/FWPTtH/Z91bXPAms/st6HpVj4Q8FXTrqXhv4 + gL4d13wdrXhvw9r9vrmuJY3aGz8Cm20E+Mv7TtbqDWbLxLcyzxPdWs3zB+z58M/j1o9prdp4BiisdW8e + yaevxD8LanpU2m6fofgfxD8VNIHhT/ibWfjPVvCnha0v9Dsfi3PYx+CvAesjw2t54kQ6Xd3+vaDLB6ry + /EVKGJwVTKFi8vlTrV8ZTeKw2Cp/X6uHoyy6vGaovEYqjCWGq0XhKlWj9ZeLrKVRS9hKnrk+YcIYvhLD + wy7jDF5Pn+HoYrKMjp4WOeYbCYPAzz+tSzSjnMVh8ThcI8VTnSxMcXk2IdONSklPC/DXxXQeI/Efwc8Z + eHbD9nDS/G/gnWvG198VPEy+FovAniLwd8XNKt2sPh/ZWviTRPDya7Yad468Za74UtLyL7Df6D4U0uLw + NZXdjoOja7Fo3hCLSm5jw18WfH8EPgT9oj4eeDfGWm6H4j+JPg3SfixaaXp/x40SLYt98MPiVc6XF4Z+ + IXxDTSLTTfFNl8Y/iTpHh3Ur3SLvwdqdzplgvhOys7/xJZyQ914Z/Zu1zwJ4N+H2jaP+zB4D8O/FyDxO + bvTviPonw5ubw6JJe+D9G0DxFaXt9YeN9evtK0nXdY8Qai9zNbeOvhp4Pn0Xw3ql5a6OJ4rTw7r3jv7I + n7OH7cvw8/aK8UfD7V/G/inw78AI7WA6npXiNPEH9meIdGt1+H1rq01u+oeDviN8OofEWq+CPEL+HvDy + eB/i/dTafd+BLiG4/wCEfs9MudDg9mticizTDV5ZZjMZkVXDYLDU8HLNcLgZKjmVepiK+YUcrwWGwdR4 + WnVwUMPG1Sao05OpT9opzgqWWTYPMOEsmwkcfl3CvFHssZj6+f5PkOfVqOW5lw3h28vWLWNlXw9PF0MF + jJ0sThMDDBRzWliqMMTSwzhOpUn6z4z/AGFbn4c+PvGrab8IvDfxT/Zr1fw/B8QfENpq62T+NdIvfDCf + F7xUvhXQvEniTxF4g+JGl+IrC50v4I6F4Z1vwc1np1/YWOpW+s6WLuyE955ZYXfjj9sr4G/Df4IaT8J/ + FXw9uPB2m/F6O+8GahoWs+KPCPiO8utD8V6P4V1GPxn8RdNuPDms3WnNeano3iLxH43v49Xfxjqeu6xp + kc3iS0hnh+jviF8Gvir8K7DxL4esvE2laF8FPEuueJrCy02yv10nxFqviDUfC9jPp/jCDRPh54CtvDOp + 23hDwt8N4dbGgeILbQNC1/V7jxvoPiTw3rkM/h7xXfe4ap8Mj+zx4v8ADHxl+HFppkPwksfD2jw+KtMX + xBqWj69rWo66/wASLjWvEHiDTW0P/hFRpep+IvHPhjxl4h8QX15p7eHYPDOpNp+ipbFbeX4POMBh8TOr + Tw88T/Z9Sq45nGTrU8ZXwqlhatDFexU6mIWG5qNadGccRzx5sVSlhnTqRb9bh3PcLxRSo57xDlWIjxpg + IrKOB8RiqNTKcqx9XJHGrBYurh8dTpY7HV8fWwuFw9OvSw+GrrBwni5xpV5Qfx9pPwc/a8/Zp+Emu/Dn + 4Y/CPVviF4H+IXxH13WvGGi+KF8FtrHhjQ9WTxNJaz6TL8Fvir8N7iKaWHQfh1oupaNoei3djDFquq6u + /iMpDd6ZJ+qvgzwh8ItNk+E0mueF/AGg/FzR/AHh/TPDFjq82lax8SPD+lafoF/by6HofiDWp9Q8aXmn + 6LZ6j4l057ldRumltrnWpLu5lF7qMknzbZ+B/wBor4+6HpV54m1nSdG8GS6/4R8Xx6P4w0vwVfX0iz2W + tp4i0mfRdB0DULO78P6ZpWpaZFpegeJLnT/FsPieI6jd+KLA6KltqHReNfCN14G/aC+BV9o3gzx74yj0 + bw34D8Jal4mgm1N9HENrL418DWWt61/Z/wAL/EtpLqfhzS/HniXxHrraj8QfAlpNbX1rdLDqstrFEu+C + yjLsowVDGYWpVq0sSsPhaWXY2jFRy3DYepU9nVo8tD2zdf21WqouvKHLyOm47HzeN5c64ozjAzwGUZJm + mW5PmVKtmnCjpUcBn1d4bE5rLCzxVfHRXLGpi8TleYckqUIzwlLDUsDVqUpVpZXwk1LxnqXj/wCM/wAI + f2l9d+GXi/wpYXPgrStD0vXbqPWbbxB4g1nS9P1TT7e2tPEujaRZX19q11a3mp3PhddJlj0a8t9Gi8MX + erRLqVzY95+yL8D/AIlfBL/hNdA8f+JPCOq6RrniXV9d8FaL4LsU0vTfD+nXD2v21HsoNE0OCzlvm+x4 + sbSO506zjgEdnIkcqoe18A/s6Wmj2mqH4i+J9T+Jd+dRstX07UNQ1fxrHNBPbafCl9DcPq3jbX55dJ1i + 6itry98Kwz23g5JLaERaArAuaXwc0Px1rvxM8SfFTxjL4j8MWupW+p+HLL4Z6rPqc2m2L21n4IF1qtob + ma1sJIbLU9P1TTdNms9DWO+vrjxX4k07xHrXhvxPoNvpvu4rL4yxVDH+0eNxOHrV4yr0nHB0I4fFtOH+ + zubqYj2CpQhFNL2cm5xUYymn8jDO8Tip5hlOZV8ty7B1MHh8RlNDAYLMXRx2LyulhqM1Uo01VwmAzDFQ + l7Svj69WdPGSpTnbCVq1KhH3TxT8MvBvjK/8O6x4j0o3+qeFNVOpaBeLfalZTWNyuoWN9skNhe2qX9k2 + oaVpOovpepJd6ZLf6Vpl9LZyXdhaTw8n+0hAqfs/fHQbnIHwX+KXDO+P+RJ1rHAYemK9k8uHYP3aZ85s + ZVennn/7H8efevG/2kUhH7P3x0xGg/4sv8U/4R/0JGtfX2x9K3UYpyajFObvNqKTk0kk5NJN2SSV9krI + 5J4jEVaVChUr1qlDCqpHC0J1ak6OGjVqSq1Vh6UpOnR9rVlKpV9nGPtKjc580tTzP9kT4beHvBfwk+HX + ijTdT1W7vvH/AMMfhRrOuw6rqMVzZw3lr4FtRE1nAkMJQpZ3sGlxzXcl3dRaPpOg6NHcLpeiaZaW31JJ + dWFxb3z2txaTgC4i3280MgEsUXlSx7o2bEkcqPHImdySKyMAwIr8xbH4keOvgb8L/wBlXx/Nqtjc/B4/ + Cr4Z6BqmkX3iy5sNTmmtP2ffFmpLYzxar4VvbWefUNW0XRJdP12fxiuqX+srZaH/AGeYtQubub7y+Hfg + Lwp8MfDOp6H4cm1KW0vrqfUpH1N/tM+9tJ0/TLS2EsFnbRPFYaTpmnadHPIkl7epanUNXvNS1e6v9Su9 + o4KnhMLSnB04RrudSlChH3FUc5TxVOom04VoylzzcVKE5TclJ3Z58KUsPUo0cLhqMcJL6zUryjPklCrU + kppwo8kvautUqVHWk5xafva8zS87/ap+Dfhj44+BPD/hbxD4p8PeFbSx8WW2pW9/ryahLZXF9e+G/E/h + W306M6N4y8C6lHd3Z8St9nW315RfeVJpVxZ3tnf3MJ5nV/DHw18W+JfEnw+8I+OdS8K/EyG5sNZ8X6pp + Nt4jtZtbt/D2kWemaiLa6nnsNFe5sZ/GWn69/wAU9ql1HpPje50XXvEOn6rdC6s731n4xXPwiv8ATPDu + l/FLUUtdOu9Wc6ary6zZM076RqWk38k82loJYNJ/snWr6x1e+vWh0qytdRD3d1ayyW0w5X4g/AjwR4yt + vF+paKq6F4s8VNo4vPEN7Fr/AIg0+W007W/B3iDUNNufC1xrWn6adI8T/wDCF6Ppfiez0ttIk1uwQreX + LsN5yVSM6uDjTqYeM8NivaV6ksPSnWw9OrTcVOE4fvp1OV/u1K6hTlU5YtSk16U8NHG4OvhOIaGZVMol + hKsuGZUa9RYb+0516NPMJ1KWIUKVHCRppwxFTLJvFVKrhGr8Nn5Z8WfEF18UZfFOl6l4dg8LfDn4Y+Jo + 7X4iz/E/wPfvonxF8Dw3unT3Vx4ZbXvAupW/iaL+1fDWv2CeG/Dc+dahuvBXie18WWh1Cy0e5/Nmax1/ + 4i3fxA+IHjmx8O/DDxZ8HWl/4V58VfhVpGteCNQ1nwfrOpyfC2Cz8YXXhL46eAbhofDem3XgRtOX4meG + 9Mg0bTdA8VeGPEGgX+t+E9d0rRP05+On7LOn/HL4FeCPgdq3jNtOs/CR0j7XqzeFV1ux19dK8Ga34PaK + 88J6nqn9mSWxbXRrel22rz67a6RrWl6Perb3dzp1rdxdj8aL2P4XfBO58N+APCly9tLpreBNKs9BvtW8 + OJ4T0258NakketRarpfhXxfe6fNpotY4tOuhod/5+uXWnrdSRieS5XLGUqf9kYzC4zERzTD1XVxVGliK + OIvl2Mw9enLDY/BwhVVOk6+HjChWp4elTq1oUr158rUF6PDcsbWzbhbDYaKWYZZntLnVOGWUMu4iyjGY + h4jEZdnVDEUJOpjsBWp4OWWY/F16v1KlSdSilXm5x8Z/Yd8SeGtcj+Ir+EvH/iHxd4Xn1ifWdP0fxJpG + uWz6Jc3nibxbo+svaa7eeH9K8KeIVk1jw/f6Pfap4I1XxNp3iXVfDt/8QdV1T+3vHOpeb+gCta/Zxk2+ + fO45jz/x9HH9RXzl+zX8N/B/w5+HugX+neGLDw/4m8Z6RD4o8XXaeFYPD+v3epeIL+98XyaRr5hgOpXH + /CM6j4n1bTdPttYu76606FpoXuHlkndvooXtsbcfvH4nz/qpuv2nnJ8v3pYajh8PhsPSwtOrSpRoU/3d + V80oVJwUqsU1tTU21TTfN7PlUtUxcQTwrzrMaeBhQp4LD4qrhMFTw2HpYaisJgpPC4aUaNKlRSnKhTg6 + 1SVNTq1G5ztJyv4brXijU/iBr/xT+EWmaV4v8CS6V4ctIdF+J02ga/DoGp6hqtnE9++gamLbRNPvV0Zb + 7TbYvovi231q7uTrcWny6JPoUerN8eftL/Db4i/CT9nXQdI+Aep6DpXxJv8AxtHH4u8dWz6p8NYdelvP + D3j0WGt+LfEHhDRvGHia7i0PX7zRbmzfxDJ4gvtdu7KwtPE3iG9vNV1LVrz9O2vbXePnfHltj9zP1yuP + +Wf1rPvLy3NkgDMSNSsm/wBTMeF1i3YkZjxkKCRjnPTnFc1fBVMRhsTReLrUquIpVqMcTR9yVGnOr7Sk + 40nKVKdShtCdSMr7tWun0cK8Q4nhvH5ZisThcvz3B5dncM6eV5hgsL9XxjpxdGGDxVWNGVeeG+rP2M4c + /LOUYV3BV6dOcPB9C+Inizw58CdD+IHjbw5caz4vl0DQdR1HQ7K3+xX9r/wkOqxQ2R19ILBvsE2haZqN + re+OLyy0lbWwlsdcu9P0lbSK2sl+aPE/xs8W/F/406d+zf8A8Ijc+HfhX8RPhclr411fVNK8LR+LvDd9 + 4q+FfiDxZcaaV1H4kz6lbalp/wBs8I6VcabefBrW9Cmub/V7e48TiW1Wzh/RyO8tvNlBdwTFCCBDPgfN + N0/d4H4V8+fGP4OQfFe/8E6pDr8OhTeF3vGZp/Dba1LKL+bRLj+0NIn/ALR0qTQvFGmDRTBofiENf/2X + FqWpgafcC5IXHGYXGSpUo0cTOcKTwsZ0ZKCqYmFNuNZVK8l8VdOM6jSi/wB37sk3r7fDud8PUcwzGvmm + TYPDVsdDOqmBzKMsbVw3D+LxlKNXLK+DyqhGqqry3FUpRwkW+VPEU5VmqeGu+N+Hmj/s+2gvP2Vbq1sf + iBd+BJdc8TXnh7xn8NmufDdo+qarp/jC4Wxv7nwfafDaWXSIfix4fjsNK0G7kvNL0rVra2NsPs2omDzX + 9umTxDD4K8EW3hCz8UXk8d3q8n9leF722srS/tDpUWhanpVxZDTLg69qWoeG9c17S9C8Mf2t4ct9Vju9 + WkS/Gq2GjTWuz48+DHxiPxm8R/FD4U3Pw28N3etxabb3fiR9P0u08b6noI8OaLoeqeGb24uPhX4hM0k2 + peHdG1q18Rarr+tqtpoGh+H38Px2mn2V3Z/X+gz6jDpHhJPEVzaXWvx29mNcudMtLyDTZtVXQbpL+bTo + LnzriCzkuzKbWGWaaaKBlSWWRwzt0VoYXFRq4Olgq+HowhhoTniYqVOrOhKlJxpOlUhUlQcotQ9+Eoxc + 3zXvbycxowcMDmmaZvhuIFmdWvmOKwGAzLG4HMcvzLFU6eMeIrOnQjHB4mlinQqOeGlVpzr4dUJRcabb + +Rfhr4E+Kfwl/Z0+JVt4j1nSdJ8Xw3Wv+O7G88Ltpus3VtpyaFomo3nh6aK08IeBdDg1eNdM1Tw1aXWj + 6Mtult/Z+tteXusNd3Mvv/wJ+KWk/FfwYNctJFuX0jUT4cv9Va50G7tNa1G00XR9RutU0650DUNS0t7W + c6qsU0MFyTY6lDf6fIiyWjFvX3urVluwS7Ak8eVOP+WEfB/djgn6cVyv/CeeCNM8SWXg2bXrG18SX+97 + LRW89bm6Y2N9qIitk8kRNctp2l6jqAs42FybKxurwQ+RDJIHhsv9hKmsPOq6NDDKk6M+aq3GE3KE+e+n + s+ZqUpRcnpeW7fhxrUp0cXVx6xuZ51ialCSznF5hVlUVGkqssQquEjSWGq1sRKcebEL2VSMKcYJOlThC + Pxv+014hm8PfHX4AxJ4+8ReHYfE3iPSrODQ9IvtQs9N1X+zfiX8OdM1G1ubeH4k+FNI1dtdtPGlrpWoW + Wo+DvHE9r4atdd1XTrW2urSOO6+kfiTe/FODxd8No/h5p+gXfh+51WaLx5dahLALrTtF/tbw4Z7mCObU + bENAdEHiDy5LFdR1P/hIU8M240xtGudcvLL1WWSxma4lILMC7I5t5G2/uQdylosqW3DJXDMNo+6vFmS8 + tv7TtG3tgWOoDPkzdTPpuMfu88jd049ecU1hLVMTP200sTUo1Y+zfLKn7KMU1zXkmqtmpJJab7nsVM/j + Uw2Q0JZZhK0skwWOwc3jEsRh8asZWr1KdSpRp0cLJSwirJ03UrYiXt4e1bt/EfC0XlDe8JYSEZyoz+/y + TgnPp9M15F+0i9uf2f8A46YeHP8Awpf4p4wyf9CRrfv9K9fN5bbcl5M+c2P3U+Meef8Apn9ODXjn7SN5 + bn9n/wCOmHf/AJIx8UgP3U45PgnWgP8AlmMckAGuxu7PnUrK2+rf3tu3yvYd+zoVb9n34Ar5bH/iznwx + B+XOceAtHIz6jkc9scVgfGXQvjb4i8QeBrT4a+JNA8J+CrHVrvUfiRe3Nzep4nv7SK1t10qw0G0j0HUL + CWGCZrjU7yK/1TT7XUbi30/T9Sh1HQ5dW0y+6D9nOSX/AIZ++AGIHP8AxZz4Y4+aIZ/4oLSD3f3IPHUd + uteu3LOYL8NCy5jl5zEcf6MuM4fJA74BOOgJ4rnxNBYmm6Up1qcXOE5SoT9nN8klPl51aVp2tJJq60bs + YYnDrFUZUZVK1KMp05SlQm6dRqnNT5OdWkoytaVmrq6d02jgPiVb+AY9E03XfiFpFhqmm6Bq2l3Fg19p + H9rzQ6vqN1BpGlxWFrFBPcS3epajfWVjHBGjJcSzQrMrIu5eu0PW9N8QaFZa9o8j3Ok61YWmraZceTND + 9o0/UbG3vLO48q4jinhM1vNHL5U8cc0ZbZKiuCKs6tpthrenvpGs6Ra6rpeoRPaXunajBZ31he28kDrJ + Bd2lyJLe5gkXh4Z4pI27r6SwQx2Nq9nZ2C21raxpb21tALeGCCCK1hSKKGONljijjQBERFVVVQFAGBW6 + jSSbjDlqSk3Kat70Uko8ztzSkkrXbasaupjp1YU6mIVTL6FFxw2Hk68qlCtUqudaUXOrKjGnVSg5RpUq + cpVI81RytE868b+C/F/iLxb8Pta0Hx1qHhbSfC+qy32vaFa211JD4mtXvdImNrdeTqNpbXCyafZanoxi + 1W11K1t4ddm1azt4NZ0vTbuP0DWh5mlawm0qTa3JBZcBf9BIz7YOSSOgJJ9DqNJL5sf+jvwHwN8XP3c/ + 8tKztVeQ6ZrAMLKDZ3m4loztzYbT0cnAX5jwTjOATgVEacYyqSXNeq053lJq6io+7FtxhdLVQUU3q7u7 + Oyti61fD4PC1PZOjgadSlh1HD0IT5KtepiZqtUhTjUxD9rUnyuvKo6cLU6fLBKJ88SeDfEPw7+LPxH+O + ni74q63L8MB4Q1i+/wCEGmn8YXekeFdP0rw/8Pxdahb6Mdf1Lw/v0+Twd4r1lZdB8J2etX8njO9tpZrm + S3/072bwL458OfELwtbeKPC0uo3OkXOoalZRvqWha54cv4rvStYudMv7a60XxHp2k6zZSwXtrPDsvLCD + zVVZ4PMt5YpX29e06y1yxvdF1jS4NS0jV9Nv9L1PTb+O1urHUdPvoxa3dleW05eG4tbu3lkguIJVaKaF + 3jkVlYivmn4FfFHR5te8RfBy0+HR+Hs3hzUPFmoaNY2FpFDouqWmjeJ9NtPFUlvKPIWXULHWvE+lSahf + Rwf2drE2rPPpN7qDWWptbZxg6MvdnCNGpUm5Rq1Kkq08TWlBwVFybXsuVVOamvgfLy2imj0a+LWaYaEK + uFzDEZrg8PhaNCvgsLQjlWFyLLsM6M5ZnKhhoTp411ZYaNLF4is1iIxrc8qlZTkvq9pAHB2OP3b/AMPq + V5461n3b5skwrD/iZWJ3FcDjWbdsAnucYUd2IAq8ZZS4/cP/AKps/PF0yuSP3n6fzqhePIbJQYXA/tKx + Od8RyRrNuQMBzyT8ozgZ6kDJG54peR/3soKOSI4udvH3puQfT3pI5P3FufLfomTtIz8h79aSOSQSyhYH + IEcIDb4ufmm5xvpI5JfJt8W79I8fPF/cPX94Pf8AwoAmRx5shCOflQjCdPml/I1nM4Z9Iwp+W6JPHLf8 + Sq+AwP4iM59gGI6Gr6SS+bJ/o78qmfni4+aX/bNZ7PIW0cmFwRdEqpaP5idKvQQGDkZAJPzBRhTznaGA + L2/i7xG/U4+XofIT8vw6V4V8S/gB4K+Jeu2Xiq8OtaZ4t042jWGqWut+IH0uN7S01XTw974P/teHwrqU + 0mla3qunG+udL/tNLe62R3yxxRRj3PzJMXebd+Sc/PEMDyE9X9KeJJN6fuH4DY+eIZ4P/TTtmtKVarQl + z0akqcrOLcG03F7xfeL6xd0+qMq9GliaNXD1489GtB06sLySnB7xbi07aLZrYzNMtF0rS4tLE9/enT9P + trFb3UJmutQuxaWFvALm+uSqG4vLjYJbmfapmmZ32rnA8l+OXxitvgzo2k+KLnRbfVI7u8u9GC6lrkPh + rSrR5rCfV1udQ1qew1KO0jl/sQ6ZZJ9kla71fUtMslMYuGlj9oaSbF4PIfBDbvmi4/0ePv5nXHtUEys+ + o2mYXDCy1DCloiTmfTckNuwMcZ5BwcDOeMKsalSE1Tq+yqSWlTkU7Scou/K/denMrNW17pHdgKmFw2Kw + 1TF4NY7B0pxdbB+3q4b29KOjpKvSvVpOS0543at1ItL1NNU0ywvxbT2v26C3vBbzgCaAXWycQTBTgTRe + Z5cgGQGU4OCM+VftJMp/Z++OgKNg/Bf4pggrx/yJOtDp+PXrxxXsIMirxA4BmOfniIz5+P8Anpgd/wAu + +K8d/aRklP7P3x0zA4H/AApf4p/xxH/mSNa9JPr+VX/kvvtr+Jzt3cmo8qcm4xvflXRX1bt3erPzV+BX + /BU74AaL8EvgrpF14O+MUlzo/wAKvh5p9y9voHgloHns/BulWcrQNJ4/jkaJpVZkaSONzGQWRG+Qeo3H + /BV79np4rxR4L+M+XilIz4f8D4A8gJ2+IQ5zz9O+aKKBEh/4Kw/s8kwf8UX8aPkIb/kX/A/OUZOP+Lh+ + pB5zx60x/wDgrB+z1+/H/CF/GfMh+X/in/A2B+6ROf8Ai4Q5yp/AjvRRQBM3/BWL9nnzEP8Awhfxo4Bx + /wAU/wCBv4iB/wBFC9Afp71S1D/gq7+z3NY6lCvgz4zAz2tyoLeH/A+BvtDFk7fiECcYzgdRxkUUUAWp + v+Cr/wCzw0iMfBfxowqyqQNA8EZyxjIwR8Qx/dOe/T8OS07/AIKSfsh6Rruq+LtL+DvxC07xbr5RNc8T + 2XgT4a23iDWYI5YXjh1TWIfHKahfxxpbW6xx3VxMieREFAEa4KKTSbi2k3F3i2ruL7xvs/Q0hVq041I0 + 6lSnGtD2daMJyjGrT5oy5Kii0pw5oQlyyvHmjF2vFW68/wDBWL9ngFSPBfxoA2FcDw/4G6Hbj/moWAOP + 8iqtx/wVc/Z7ktkjHgz4zZ+3WUoLeH/A+MLqkEwHHxCyCQNueQCc4YDBKKZmWU/4Kw/s8q8jDwX8Z8bE + UD/hH/A3BQyk/wDNQumGGOc8HNNT/grF+zysUS/8IX8aMx7QT/wj/gbBIXBx/wAXCH4UUUAPT/grF+zy + Gd/+EL+NGCqg/wDFP+BgeDITx/wsLHRh3HTtVR/+Crn7PedMY+DPjNiG6P8AzL/gjJP9nXsZA/4uFjq2 + QSOgxjJBUooAs/8AD2D9nk/aP+KL+NH7wn/mAeBuB5apz/xcL1U/hj6BV/4Kxfs8l1P/AAhfxo4zj/in + /Aw7H/qoZ/lRRQAxv+CsP7PJNwP+EM+NGJQwA/4R/wADdTEkfJ/4WF6qemeD6nAa/wDwVf8A2ejfW0v/ + AAhfxnwlpex4/wCEf8D5JklsGyP+LhYwPK9zk+mclFADz/wVi/Z5xt/4Qv40YEjNj/hH/A3OZd/X/hYW + emfTk/jXlvx5/wCCp3wA1z4KfGHR7Xwb8Yo7nVfhT8RNMt3uNB8FJAk+oeEdXtYXmeLx9LIsKySAyskM + rhMlUdgFJRQB/9k= + + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QECRXhpZgAATU0AKgAAAAgABwEaAAUAAAABAAAAYgEbAAUAAAAB + AAAAagEoAAMAAAABAAIAAAExAAIAAAAQAAAAcgE7AAIAAAAIAAAAgodpAAQAAAABAAAAipydAAEAAAAQ + AAAA6gAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMC42AEJyaWFudGEAAASQAwACAAAAFAAA + AMCQBAACAAAAFAAAANSSkQACAAAAAzc3AACSkgACAAAAAzc3AAAAAAAAMjAxNTowOTowMyAxMTo0MToy + OAAyMDE1OjA5OjAzIDExOjQxOjI4AAAAQgByAGkAYQBuAHQAYQAAAP/bAEMAAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/A + ABEIAJYAoAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMD + AgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp + KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOk + paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQAD + AQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFR + B2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ + WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfI + ycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP73YfDXhy2hit7fw/olvbwR + pDBBDpVhFDDFEgjjiiiSBUjjjRQiIihUQBVAAAqX+wdC/wCgLpP/AILrP/4zWtRQBk/2DoX/AEBdJ/8A + BdZ//GaP7A0L/oC6T/4LbP8A+M1rUUAZP9g6F/0BdJ/8F1n/APGaP7B0L/oC6T/4LrP/AOM1rUUAZP8A + YOhf9AXSf/BdZ/8Axmj+wdC/6Auk/wDgus//AIzWtRQBk/2DoX/QF0n/AMF1n/8AGaP7B0L/AKAuk/8A + gus//jNa1FAGT/YGhf8AQF0n/wAFtn/8Zo/sHQv+gLpP/gus/wD4zWtRQBk/2DoX/QF0n/wXWf8A8Zo/ + sHQv+gLpP/gus/8A4zWtRQBk/wBgaF/0BdJ/8Ftn/wDGaP7B0L/oC6T/AOC6z/8AjNa1FAGT/YOhf9AX + Sf8AwXWf/wAZo/sHQv8AoC6T/wCC6z/+M1rUUAZP9g6F/wBAXSf/AAXWf/xmop/DXhy5hlt7nw/olxbz + xvDPBPpVhLDNDKhSWKWKSBkkjkRmR0dSroxVgQSK26KACiiigAooooAKKKKACiiigAooooAKKKKACiii + gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiii + gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiii + gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiii + gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiii + gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA8q074v+Gt + TsdKv4LHXEh1ixt9QtlmtrBZUhubeG5RZ1TU5FWURzKHWN5UDhgHYAMdP/hZWhf8+mrf9+LP/wCT6KKA + D/hZWhf8+mrf9+LP/wCT6T/hZehZx9k1b/vxZ+3/AE/+9FFAC/8ACytC/wCfTVv+/Fn/APJ9QxfFHQJn + uEWz1gG2mEEm63sgC5gguMpjUCSuy4QZIU7gwxgBiUUATf8ACytC/wCfTVv+/Fn/APJ9H/CytC/59NW/ + 78Wf/wAn0UUAH/CytC/59NW/78Wf/wAn0f8ACytC/wCfTVv+/Fn/APJ9FFAEFt8UfD91bw3MdnrASeNJ + UD29kHCuoYBguoMA2DzhiM9Can/4WVoX/Ppq3/fiz/8Ak+iigA/4WVoX/Ppq3/fiz/8Ak+j/AIWVoX/P + pq3/AH4s/wD5PoooAguPil4ftkR3s9YIea3gGy3sid9zcRW0ZOdQX5RJMpc5JCBiAxAUz/8ACytC/wCf + TVv+/Fn/APJ9FFAB/wALK0L/AJ9NW/78Wf8A8n0f8LK0L/n01b/vxZ//ACfRRQAf8LK0L/n01b/vxZ// + ACfWVqfxh8M6Va6pd3Fjrrx6Tpkmq3Kw22ns728Ud3KyQB9TjVpitlKAsjRplo8yAFihRQB//9k= + + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QECRXhpZgAATU0AKgAAAAgABwEaAAUAAAABAAAAYgEbAAUAAAAB + AAAAagEoAAMAAAABAAIAAAExAAIAAAAQAAAAcgE7AAIAAAAIAAAAgodpAAQAAAABAAAAipydAAEAAAAQ + AAAA6gAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMC42AEJyaWFudGEAAASQAwACAAAAFAAA + AMCQBAACAAAAFAAAANSSkQACAAAAAzQ2AACSkgACAAAAAzQ2AAAAAAAAMjAxNTowOToyMyAwNzowMjo0 + MgAyMDE1OjA5OjIzIDA3OjAyOjQyAAAAQgByAGkAYQBuAHQAYQAAAP/bAEMAAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/A + ABEIAJYAoAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMD + AgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp + KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOk + paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQAD + AQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFR + B2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ + WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfI + ycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP7uPiLd3n9gPp+jeIrvw5rV + 3rPgyxXU9ITQrrWNMstd8ZaNo1xd2tl4h0vXdKLzWs17bwS6jo19bCQSMkTTQgpxVt8PPG0qylv2hvi8 + Sl1eRADRPgECEgupYUz/AMWP67EGT3bNWviR4I0i81Cz8Xzz6oNTl1b4aaCqWuo3WnW62cHxK0O8Zv8A + iXta3c0kr3OJYri7mtFFvbywWsNwJZ5fJPhbHqPh34zfFv4QeJdf8Va5pl0V+M3wy1TV/F3iW4vo/DHj + HxH4g0jxn4ESeTVTPfQfD3xnpSalYTO4j0zwr8RfCPhmCEQaBHNJ20sNCth61SnWvUw8HXlSdJtzp3w9 + Op7OSqK7pOrGclypOl7SfMvZ2lxTxM6VeFOVK8a1RUYSVRJRm4VqkHJcjsqsaUorW/tOSCu5JHq8Pw58 + aPczxP8AtC/F/bHDbSLjQ/gHndK90r8/8KP5GIkwMcHPJzwtz8OfGkXkBP2hvi/+8mZGzonwD+6La4l4 + z8DuDujU59MjvXeweHNNa8ug0+t4FtZn/kZ/EY5Mt9nJ/tbJ4VeKW88N6YrWhFxreftLf8zR4kP/AC53 + eP8AmLdc9K5Pd/mf/gGnT/p56/8AAOpOr/z7j/4G/LtT8/6ujgv+Fb+Nf+jhfi//AOCT4Bf/ADj6da/D + fxnLbW0r/tC/F/fJBDI+NE+AYG541ZsD/hR3AyTgV33/AAjmnf8APbWvx8TeJO3r/wATalsfDWlmytCb + jW8ta25P/FUeJBz5Sdv7W/TtSVurfyh/nP8Ar8ATq/8APtf+B+nan53+fojzlfh142ae6T/hoX4v7YpU + RP8AiSfALO028Ehz/wAWP5O+RufTApy/Drxr9qihb9oX4v7Ht7iQ/wDEk+Aed0clqqYP/Cj+mJXyPp6c + 95H4c077RfAT62QLiP8A5mbxIetnank/2tz179uOlKvhzTTfQBp9bwbS7P8AyM3iMHImscc/2rnueB1o + 07u3lDXp/wBPLf19xer/AM+1/wCB+n/Tu/8Aw/ocRcfDfxlHEzp+0L8YNwKAZ0T4Bn7zqp4/4Ud6Gmf8 + K38a/wDRwvxf/wDBJ8Av/nH16Fd+GtLFvIftGt9Y858UeJD/AMtE651bB/Gm/wDCOad/z21v0/5GbxJz + /wCVX3o06Nv1h6dp+v8AWor1dP3cf/A/R/8APv8AL/Jnn1n8OfGc0JeT9oX4v7hcXcfGh/AMfLDdzwpx + /wAKO67I1ye5ye9Nb4deNRdSRD9oX4v7FggkH/Ek+Aed8klyrZP/AAo7ptiTA+vrXoGn+G9La2Ja41v/ + AI+tQH/Iz+Ixwt/cgcDVgOKa3hvTRezgT62R9ltCf+Km8SHky3o6/wBregHH+NOy11fzh6b/ALz5P1C9 + T+SP/gz0/wCnduv9aHn7fDrxss1qn/DQvxf2zTvG/wDxI/gH90WtxKMH/hR/B3xp+GRV7/hWnjD/AKOF + +MH/AIJPgH/846uvl8O6b9osQ1xrQBuZASfE3iMcfYbw9Tq3HNaP/CN6T/z861z/ANTT4j54z/0FvTn6 + c0ly/wAz03tD0/v/ANN/IL1P5I99anTvpT20b+TPL7b4d+N5baCV/wBoX4vbpIY3bGh/AIDcyAnA/wCF + H8cnpU1t8OfGkjXIf9oX4v8A7q4EaY0P4Bj5TbW8vP8AxY7k75G59MDtXbWPh3TjZ2p8/Wjut4ef+Em8 + R4P7pcYxquMY9OKntPDulFr3dc61/wAfagf8VR4iHWztCB/yFhnknGcmnpd6tL/Br6az9fn9wc1TrCK9 + ane3/Tv5/wBI4Gf4c+NEnhjT9oX4v7Xinds6J8A85SS2VcH/AIUd6Stx3JHpTJvh143RQw/aF+L+d8a8 + 6J8Ajwzqp/5of1wTXoNx4c0xbq323GtnMFyD/wAVR4jP/LWzwP8AkLZ6Z47/AIVHceHtNCf8fGtf6yHO + fE3iPp5qdQdW9fWjRdXbreFvyqdtv1C9S/wR/wDBn/2l9Djz8NPGIBP/AA0L8YOAf+YL8A//AJx1bXw6 + vbyz8MGDxH4lvvEWoWninxdoh17XY/D9hqWox2HjTWdJ0pbuDw7pHh3Q1uEtIrKyQWGj2RuCkTyRS3c0 + ks3Uf8I1pR/5eNb5/wCpo8Sc/wDlWryDQPhh4b8SWH26+k1s3WkeP/iPNat/wkGs3Ee2bx1qsVzA9pfX + l5ZtHdQafBE8n2cXNuXuLyxntdQme8rkxM60HSeHiq05OS9nUn7GEl7t5OaVV+6rtKy6rmO3CRoz9p9b + lKhTTjarRprE1E+Wo1BQc6CUZyUYzkptxXvKMmkn6L8RUjn0Gygd2Afxj8PA3lTSQyhT4/8ADGSksEkc + 0bDjDxurDswzmvC/ir8GPGvifWvB/wAQfhD470LwP8RPA0fxA0CC58daB4t8feGvEXhLxnc6Xd6x4Y1C + x0T4j+Ada0p7nxD4P8HavDrllrV4bJ9Gljm0XU0uisXc/ED4caHJrZ8evda8NZ1TU/hX4buoYdc1C0sT + YaX8TNKvbIxxWk0FxG8U2ragRAt19gD3D3IsxeE3R9As/DmnGOXM+t8Xt+OPE/iUdL2fHTVuvfPUnk8n + NerQq/Vp0a9GadSP1iElUwtGvTca+Hp0a9KVOu5wnGdOpUpvmg7xfMuVpW8qpCdf21GopRpt0ZJ08VWo + zUqVV1aNWMqKUozjOMJrlnFprlb3v5N8EfHNp8TtN12PXNI1Xwb8QvBWrf8ACG/EvwQ/irWr8+F/FtjG + 19tsdTW6sjrPhjxFouoaR4r8Ga+1jYya14V1zSb270/S9Te/0my9mu9DsQ1pifU2zcsMf2/rjZ/0O77H + UT3xXzx8Sf2d21zxLdfEv4U+L9d+G/xk0/RdIsotdbXPE+q+EvHWlaXc6zcaf4O+KnhYa9br4j8NrLfX + y2Gqadc6V4z8KPf3Vz4X8QWMVxqWnanwFt+1P8JNCig0L42S+Lfgz8TdEuPJ8aeC9c1T4i63Z6RGlrdw + nxfpnivRoLjRNU+FeqSqZdE+I1xJpOkFPN0nxHF4a8VafrfhrS+qplFDMHLEZPh6ldOUfb5dSwftsVgp + yjGUnCm6lWtiMC6ikqOITqTpRUKeMcak6NTE4RzKvhLUcyrQhJJqljKuKdKjiYxa5XKfso0qWK5OX2tG + SgpvnqYdOmpxpfZP9hWH/PTVP/B7rn/yxpLHQrD7Faf6Rqf/AB62/wDzMGuj/lknb+0ePpXKeEdR+H3j + /QLDxX4E8YweNPDGqxtLpniLwr8QtT8QaHqEccjRSPZarpWv3djdLHKrRSGGdwkqtG+HVlHUWPhrSzZW + ZM+uZNrbk/8AFU+JhyYkzwNYAH0AAFeRPC0qU5U6lP2dSnJxnCeEpxnCUXZxlGUlKMouNmmk01Z9T0Y4 + mrUjGcJQnCSjKMo4upKMovltKLUGmmrWabTT69WR6HY/aL4ebqjYuI+f7e1w/wDLnanr/aPPXv8AToBQ + NCsft8H73U1H2S7OTr2uDpNZdD/aIx1/Hv0FRJ4c037RfAT65gXEeP8Aip/EveztScn+1sk57kk4wOgA + pV8O6Z9ugVrjW8G0uz/yNHiUHPnWIGCNXyOpzg4PGegwvq9BK9lZLf6tSstuvNtp/WpSr4j+sTV293/p + 32t8rfO3d6HYiByJ9TOGj4/4SDXCP9anUHUsY+tfPE+gfEXxvqHxD1Twl4913wRZaHf6p4P8EafeHTPE + vhjXdT0jTtLln8X6kPsqeJYraHxZNrnhLUNFtvEoJtNBnu4307UrnyrP13x6uieE/B/iLxHPc6l5ei6T + e6l5d5421vTre4ltIWlgtZL/AFDW4rKzF1cLHbi4upY4IjIGldVBIyPhr8OLLwx4F8NaTeQXdjq39njU + /EVvpXifxadNPivXppde8WXNmbvXrq6eC98S6lqt6r3V1c3MhuDJcXE0zvK/mYnC0MXiaOD561OlTo1M + TiXhebC1LyccPhYOrh5wqxjN/Wqi5a1KXtMNDSa5+T18DisRgcHiMeqWGq4ieIoYPCwxkKWMo2jF4jHV + Y0sTCpT9rSUcHS/eYWrF08ZVcZ0qsKbn5m/jCfxX4c0bw54Ml8W+GvHnizxP4x8JXGqta6tq1v8ADy78 + HanqEXizxDrNlqWuWti9hF9khsfCt1K+oW+taj4h8MahHpuq6LcX5i61fhR4yTWJpm+OHjua2/tjSdYN + g1h4SMP9jwS6iLjwt5w0IXf9nX25PO1ATrrcPlj7NqMO+Tf1+gfCnwXYeJNf8bWttq8XiLxJbWmjatqA + 8V+Kd1xYeHdS1ttMhETayY4PKbVLoyvAkbXOIDcGU28JTp38OaaL2ZRPrmPstqf+Ro8THnzb0HJ/tcns + MAnAycDJOYo5SqycsxrValWMlToxwtXE4aiqFG8aU3Sw+Koxdau3OtW51UcPaRwvtK1PDwqT0xOcqk40 + 8pw9CGGlD2lX69h8HisR9ZruFWrShWxOExM/q+Dap4XCTU4Sqxpzxjp4erja9CHjLfCDx7GumxH4/wDx + AnnSPxDbtc3GkeDF8661LRdQg0i+mjtdBtgH8OXTR31lBbNbRX8sKw6t9stnkibI8O+E/i142TVG1rxt + 4v8Ahk+iWf8AwhQjsNO0aVPFPibR5Lf+2vivpD6zqvjB7fw1r0yzWHhLw7qAt7mz0yG41HWUurzULCHS + PepPDmm/aLAGfXMG5kB/4qfxL/z5Xh4P9rZU5xyCDjI6ZrT/AOEY0r/nvrn/AIVXif3/AOox7k/XmreR + 4JShy18whTimp0vruOftHyU4U26lTGzrU/ZqmpJUalJTk71OfS2ceIcw5Z82FyipUfL7Kq8vy+Lor2rq + 1FGlTy+GHqKpzKCVejWVOnGEKPs1FHh0Pwj8czW6NF8ePH9skv8Awjs8aRaX4LYW0OnacbfVbWMy+HH3 + xeI7lotRvWk3TWM8Cw6TLZWby272LX4SeNDNI3/C9fHipBrutXk0X9n+EQt1Y6npulppWjyH+wg8dp4b + mhuJ7C6gaLUL1r2aPVrq9hhtY4PU7Lw7pxs7U+frnNvD08T+JR/yzXsNWAH0xVmz8N6Yz3u6fXPlulA/ + 4qjxMvH2O0PONXGevU5PbOBir/sXL1Z82O02vjcxtrLn0/4ULLXSy0cLU/4cYxWf9vZo96eWbWt/Z2VW + 1gqf/QrV5cuqm/ejUarxar3qPxqT4P8AjtVtrZv2gPiDLcDw9faeb06Z4JMz6m2sw3qeIPJ/4Rz7Ot7D + YSw6Mtmka6W1papdyWbalJNeO68+EXjkpKY/jv4/hEl54dkRE0vwYwih0y2a21W3Qv4dYsviS6aLUr6S + TfLY3ECQaQ9jZtLBJ7Dc+G9MW6tws+ucwXOf+Ko8TMeJrLudXOOvQYycHqowyfw5pwjH7/XP9ZDnPifx + KRjzU9dWo/sTL2tZY9qyTf17Mm7Ri425v7RUlo22003K02+dKSf9v5p0hlier0y3KbJuUJpxX9lWjaUI + 8vKk1BypJqlVqwqee/DmW+mvvFfgjxfrNzq/izwfqAurjUbDUPEWmwX/AIW8UX+s3vgq6ltm1BYI9Ti0 + myfStZNkWs5tV0u7urYQR3C2tv1/w2hgsNE1eJHmw/jr4hsftN5cXT7h431+MbXu55pACkakqrAPIXmY + GWWV24e20qxtPjpr2lT654qkttd+F3hTUdM0RtZ19NMsp/DPinxbaa5qsGqrr5up9Q1SPxX4es7ywltF + gtbbR7C4guXe8uYo6GmfCfw/4v063uL661yKXQPid431uzMeqPdt9u074h6lcWhaXWI9UnggD6XavPb2 + Etml5MDc3i3F0I5o+bCqVOnShRjHEV8PicZhX7Zxp1HSpVpQpSqVuetKpVeFVGUpzkp1ZOU5cspezj04 + tU6mIqTrTeGw2Lw2X4y9CFSpS9vWwnPiVToezw0KVH68sRTpwpQlRoJKFJzpwVSfqPxCCXGg2MRZgreM + fh2GMUskMgz8QPDI+WSJo5YyCM7kZW7A85q7Z6RbeXL+/wBT4vdQH/IY1cf8v1x6XwGfU4yTya8k8Q/D + jUdDWbU18d+JbhNU8a/D2QpN9kuboSz/ABN0u+njmm1SLVLD7DFLfK+mWWmaTpEemOt3DAz6Xc22maf6 + ZaaHqTRykeL/ABEv+m6gMC38Ldr645OfDR5PfHGenGK9+pSouMPfjVtKWroz0coUHJK8b+7JtXaXM1or + WPm6VatGpU9xwuoLWpBXs52d02tt+xr2+jWzXl0Dcan/AMetn/zGNXzzLe9/t2e3TPXnikvNCs1NqRNq + QzcvnGsatyfsl0ev2725HcEjjOaoQaFqZvLgDxj4iUi2tCT5HhcE5lveD/xTWOMcfU0t5oWphrTPjLxE + 2blxjyfC5wfsd2c/8i17d+MViqNHoktvhpzXa3wxWqb06p3tqzf29Zrd73/ixWui8ujf3M+ZPF3wo8Z/ + Cbxrq3xV+A+iS+KNI8Xzx3nxf+CMXiU+GZPFWrWtpHaQfEn4c61qN7baJp/xOawtbLRdf0bxNqGk+F/H + 2lWOkNea/wCF9a0NdT1fsfhl8ePhf481iz8CyyePPAXxFbSmvl+H3xQ0fxv4B8UX1rp6QjU7nw4uvra6 + J44sdM86E6hqvgHWvFOkWizRPLqAjljZvbP7B1Lv4w8REZHBt/C2Ov8A2LX+fUVwvjP4IeDPiz4YsPDv + xLjTxtokMljqlnYeItD8F6kmm6rb2zx2uraXLceFWn0vVrWO4njttT0+a2v7dJ5kiuEWWQN6qr4HFxp0 + 8zo1JVIU6dGGPwybxUKdOEYUlXoVUqGMjQhy06a9pha7pRhTljHSp0KdPzXTxtBylga0Y05TlVlgq9RS + w8qk2pVHRqRTqYWVWTcpyUMRS9pzTWHUpTlLL1/4wfArwifFVz4p+MvgPw5D4Y1a20vxFJrvxX0zR00L + VLiws5bbS9YN74igOm6lcxur21leiK7uFZPJhcMK4nw5461343S6H4g+BuqWumfDq60yx1u1+JnjXRfH + Wt2fjWym1S+stV0Dwn4VPjL4da5pclslhaXo8aavcXekvHe2sWleHtfguJtRsOS8a/s3fC3wZ4TTR/AP + gq10PWbqfSvhh4Z1vwJ4E+HeneLvB2k/EC+07RvEGvaR4isfBMeraNHotlqmq+L9X1KDUbO4nlsLq9kv + P7UuI7h9K9/Za1zw5rWq6x8Cfjv8Q/glf+JLvVPEGu+HrDRfAHjX4Zaz4gu7izmvtZm8A+KfDE0Xh6+1 + m7d7/wASXHw91nwRc+JtSnvNX12e/wBbu5NUHnV8Dk2YYv6jQzDFZfRoUqFetiMRhakYYmrWqVYwoutl + 3tsbgqdKOGeIqPC08VVrutQw7qUqUatTE+zhsbmOW4CGPrYHDY/F4rE1aGGpQrU5QwdHD06FSrilhsZC + OHx9WrUxEcNSjiKlGhQjRxFT2OKr1Kawfo118JfH3iCXR4viR8QvDHiTwxpevXGuX/hnw94C8QeH4fED + 2Vxpl54HtdSvvEnxQ8fPbp4U1u1l8RXNzpVvYXetazaeHWjl0jTtK1bTfEntA0e2AAE+pgeg1nWMD6f6 + eOPSvkqfw3+3Zp1v9if4kfADxVt2bvEjeF/FvgcttkUgN4MQ/EAM03AZ08eQrbcssFyD5dQz+JP2vfBY + j1bxt4A8O+PfC8cijVR8EPiJZX3xB023b5Tf6d4G+IXwg8JaL4mtbf8A4+NQtrP4g2Gux2yuui6H4ivv + Ls5enD8L4XDc7wmNy3Ezq8l3UzKpUrVI0oKNKKlmcoVYxXvOnQbhL2s6kvZKrWk58eJ4mxmK9ksVhsXQ + p0FUVOFHL6FChTdWXPVm6WV0nQlUnaEZ11Gc3Ro4eg6nsMNQp0vrvTdFtTan9/qX/H3qAP8AxN9W5xf3 + I5/03r/WmyaPbC+mHn6n/wAetof+Qvqw6y3o6i+z29cD8ePmjwV+0b8I/EV5L4fv/i34w+HXihFvL8eF + PjD4Pl+DPiG6tDqctvNdaPpvxQ+H3hV/EtpZ3U0NpqGoeGH1jTrO6uLaGe7ja7tfO99g0+4vZTcWfjrW + 7y2mtLSSG6th4TnglRpb3Bimj8NtFIh6hkYg54J4rPE5dUwclHFYWphm7NKvha1JPazjz00pJ7pq6fTc + VDHrErnw9anW3u6eIhO2qT5lFtxaekk0mmmnrc1pNHtjcWA8/UubqTrrGrn/AJcrw974+mK1f7Ftf+e+ + p89f+Jxq3/ydXNSaFqf2ixH/AAmHiLm5kwTB4XGP9Cu+ePDXXqOfXpWl/YOqf9Dn4i/78+Fv/marm9jR + 092PTalL+72j/Xo1fb21V2v5f8vY/wB1/r+DI7LSLY2dr+/1Mf6PD/zGNXH/ACzXsL4AfgB9KsWWi2xa + +zPqf/H2v/MX1b/nztDz/pvPXv2ArHstD1I2dqR4w8RAG2g4EHhcgfu17nw1n86ntNC1Mve48Y+IlxdK + D+58L8/6HaHJ/wCKa64IH4UexorRRha//PqWu39zz+dvMPb1nu9NP+XsfL/P8GaNzo9qt1b/AL/U+be6 + /wCYxq3XzrLGT9tzx7Ec4qK40i28sfv9T5khH/IY1c/8tU7G/I6cVSn0LUxdQA+MfETZt7rH7jwucfvr + L/qWsd8/hxTJ9D1IIM+MPEX+si62/hb/AJ6p6eGv8KPY0X9mHT/l1L+7/c16etl3Qe3rJaP/AMqx8v8A + P8GcR4i06Oy+L/w3kOpeMFtdU8M/EXQjYWmp6rJ4fnv5JvA+uWd/rMh1VTb6hY2mhapa6Iy2syyR6pqy + NcWzFI7vrvhvDHaaJqyK8zB/HXxEbNxcT3DDb468QR4ElxJKwBCAlFIBcs+DJI7NwHxA0PV4PGPwXuov + Efj69J+IWp6fdzaTF4dNjp1pffC/4iOmoeIoovDRR9HOoWlhp0LTr5cWt32kSqyyIuaui/D7WPEOnxzx + +ONZtU0n4l/EHUHR7e0ElwsfjXWoDaLJo50KMQO8Umo7b631ONdXFndJGtrZtY3PjU17LF4x0KTrTWOT + VNP2T5KmXZepSjKtaLipKbag1eUJLl5uaUvdnbEYLK44iusPT/s+SlWcXWSnTzXOHCDjRvUnNqVNc0/h + i4r4YRPUfiMjS+H7KNJpLd28Y/DwLPCIjLET4/8ADI3oJ4p4SwGcebDInqh6VLZ6Re+XL/xUmtf8fl+P + 9R4cOcXtxz82gE5Pfn6V5V4g8AeIdHmvtWn+Inii+sNX8W/DJbbSZ3gu4NPmi+KMF/NNajVv7VtbcXa6 + 5Dbzw2FhYRpFo+k21n9l020i05fUrPR9Q8uX/iqNcX/TdQGBb+G/+f645P8AxT55PU9vQAcV79SlS5Y2 + rKVpzd4qvHV08O2tIJ+7L3XdWbV43VmfO061SM6n7l3ahpy4eo7JztLmnLS6SaSd1e0rNNK1b6NeteXX + /FS62MW1mc/Z/DneW9GP+QABgY+uSeafeaNeKbU/8JJrZzcMOYPDnH+h3Rz/AMgDrx9Mdqhg0bUTeXAH + ijXeLazOfI8N55lvcf8AMAxxjjHPJz2pbzRdSBtM+KNd/wCPl/8Alh4b4/0O65H/ABIOvGPoax9jS/5+ + f+TYn/5H+rG3t6m/sVf/AK9YW/Tzt0+fUm/si9/6GTWv/Afw3/8AM/S2Oi3hsrM/8JLrYza25A8jw5xm + JOP+QB+VR/2PqH/Q067/AOA/hv8A+Z+iz0fUfsVox8U66FNtbn/UeG8DMSHvoH8z9TR7Gn0qNvoubE+X + 93yX3IPbz60krdXSwtlb0b2PH9b0C51340eE9Onv9aubTwNpOueOo9WF54bQ6Z4l1nT7bwRoMUujx6CZ + Lj+0fDeq/EGOK+ufJt7f7K8Nul1NLcNaeuro961/AP8AhJNa/wCPS8Ofs/hztNY+mgDrn9BXj/gTQZ9X + +I/xh8YprdwGbVfC3w+stZ0+68OX9zq+leBtCbVJIdShjsb210260Hxl448baM1kLLS73dbSTXkVzG9n + ct66ujaib6ADxRrufsl2c/Z/DeRiax6f8SD3/QVwZfQpOOJr+0V8TjcRUbi8RaUaMlgqM1L2NNyUqGEp + SUnzpr4KkocrPUzXEVYVMHhPYvlwWW4Kkrww0uWeJp/2liINe2q8jpYrH16UoLkcXC06NKfNCNy60W8E + Dn/hJdbPMfBg8Of89E/6gH5dMUz+yL3j/ipdaGPS38N//M/SXWi6kIH/AOKo1370fWDw3/z0T00AH8ua + aNH1HA/4qnXf/Afw3/8AM/Xf7Gl/z8/8mxP/AMj/AFY8v29RaexVn2pYXy3u10/I5vVvhl4d8b6Umn+M + orXxZp8Go6hcQ2Hibw14J1+zhuPtd7AZ4rbVfC13DHM0MssRlRFfypZI87HZT86al+ybceBtbudZ/Zd+ + IcX7POp6jbqPEnh2w8BeH/Efwj8RpM160WoXHwo0688E6Jovim0u445R4q8LXmhajqVpcahY+Il1tJdO + l0r6s0/RtTNuT/wlOu/8feoYxB4b7X9zzzoHU9T701tG1EXswPijXf8Aj1tT/wAe/hs5/e3uAf8AiQEc + YyMDPqelduGxeIwilChjJxpTTjUw8/bV8LVi9Wq2Er06mFrWdpR9rRny1FGorTimcmIo0cTaVXCRdVNO + NaFPD0sRBrS8MRSnTrQ928XyVFeLcGnBtHyN/wALv+JPw2/sdf2lPBHibwJodvfRafq3xq8D6x4G8Z/B + m1uZVm0+LW9fWTS7D4ifD7w/qM80F02peJPCV34a8L2080fiXxhBb2R1a8+w7TT5L63iu7PxZqtzbTxp + LBPAnhqaKaKRdySxyJoJR43BDIykqynIJHXLvvDk18ILG91/VbyzvHubW7tLqx8Lz21zbT6dexTwTwS+ + HWjmhmiZo5YpEaOSNmR1KnFfM97+yZdfDe9/4Sr9lXxda/BnxCXm/tfwLNodpcfA7xrZzlZJrbVPhx4e + Hh/SfCPiNriNZLD4g+DrO11myknuv7c0vxdp0z6Q3UqeUY7RyjlOJd1GVJ5hXy6tLRx9sq062LwDumnO + k8bQlKUIqjhKcJzeCq5lhLNU1mGHVrxqU8FTx1JLf2bp04YfFx2koz+r1opS/eV5OEV9QWWk3v2O1I8S + a0P9Hh4+z+HMD92o4z4fJ/Mk+pNWLPRbxnvf+Kl1sf6WvS38Of8APnaHn/iQe+OMdO9fP/wg+J+q+LtT + v/hx4/HiL4afGPwzpNpqureC5rrwxreja/4cmaG0g8d/DbxSvhXT18ZeBp750024u5tM0XxH4e1VodM8 + XeG9Aur/AEgan77aaNqTPeY8Ua78t0oz9n8NjP8Aodmc86BjvjjHTn1rgxOAlhKzoV5KM4qMk41a1SE4 + TipU6tKrT56VWlUhaVOrTnKE42cZNHbRx31imqlOnzRcpRd6OHi4Tg7ThOElGcKkJLlnCUVKElaSTVh1 + zo14t1b/APFSa2cwXOMweHMj99Zf9QDBz9PT05juNJvfLA/4STWuZIR/x7+G/wDnqn/Uv0XGjakLq3z4 + o13mC558jw3/AM9rH00DHPfI7Cmz6PqGwZ8U66f3kP8Ay7+G/wDnqnpoArD2NP8A5+P/AMCxP/yPkvuN + frFRf8ufupYW3TvJfd5HnXxZ8P3v2XwPqK3XjHXZdH+Kfw7uYYNGfQba5sP7U8RWnhe51u8EXhDUWudI + 0Ox8QXeq6zamK2jfTLS5kk1HTo43vYe2+GUEtvoWriW9ub5n8dfERhLdJaI6AeONfj2KLO1tI9rMjTHd + Gz+bLIA4iEccfMfFPwTreveEXtLK913xFe2XiPwR4hsdJF74W0Zp7zwr428O+JraYajN4eaKIWU2kR37 + QyDZeramxLRm48xeZ0nwL4l1/ToZtN8e69pUWmfEXxzf3CW7/Y5L02XxJu7lbCb+xp9Gs7nS7+PT7yHU + 7XU7DUZpRqDJZXWn2f2uzv8Axp054fMq1SjTlXjUpYWUUnOCc28TSrNyq0oqTp06dJ2jOtOzheFGElKX + twqUsTlWGpV6sMN7PGYyDk6dObhSVHC1qVqVCrOpFVK1TERjJ0KUZNVbVazi6dL1f4hqz6DYokhiZvGP + w8CyKFYo3/Cf+GcEK4ZWOexGMZq5ZWl/5UudVmz9sv8AP+i2fUX1wCf9T0PX8cdsnxLVPDvxc09NRvNf + 8U+G5rC98ffD1tItFtb3V4bWyX4j6MsEMVsIPDd1p0hT7NqExudZ8SHdf3GiRyLb6NZarqHrVna+MPLl + xrnhwf6bqGc+FtSPP264yRjxeOD1API6EnGT79WhBKK9vSnac9YzxEV70MO2rwjG7jezeqTTtdK7+bpV + 581R+wmrqC5ZQot6Oor3m/hfa6drOyNu3tNQ+2XIXVph/o1nkm0syMebe4A/c4GPmzzzkfg69tNRzabt + WlINy/Szsxj/AEO75/1P4YPXNZUFn4xa7uNuu+GwwtrPcT4W1Mggy320ADxfkEc5JPOQABjlbuy8ZBrQ + trvhoj7S/TwtqYOfsd36+Lz2yPxz2wcPYxul7WOv/T3F26dWm/x9NLm/t57+xl5L2eH/ALtvtW/Do+7N + Y2l//wBBWb/wEs//AIz+dcD4t8ReKfDlh4Ps/DtjJ4m1jxNrem6Fa2k9zbaRYafZ/wBmXuqaprWqajFo + msSwWWmadptwQEsJDd6hLYab5tvJfRzp1X2Xxh313w3j/sVtT/8Amv8A8+hryNdO8V6z8YfDay3vg+Ye + Cvhpe6nZXzaddvfaff8AjjVrbS1Mnh+Px0bmOO507wjqMFhrl1YxREHWNP066kL6tDFyY6EoUYQo1+St + XxGHownCpiZShGdWDrTSnSrQ5oUFVlF1IcnPGMZNXu/Qy2cJ4idTEYWNTD4bDYnEVKVWFFQqyhRksPTk + 6eIw1XlqYqWHpz9lWjUVOU3BSa5X1vwv8G6x4R8Iafo2p32mw6+Xm1fxc/h+xij0a/8AG3iJ/wDhIPGu + rael3ALpbbV/FWp6vqcQuAk2y6AkSNsxr3q2mofb4NurSgm0u+TaWZGPOss8eT16d+x/HKjtPGAuL4f2 + 74b3C4jyf+EW1PB/0O1IwP8AhL8jg4Iyemc84Vy2njBr2EDXfDe77LdkE+FtT2gedY5BH/CX5JORjkYx + 3zW9DBUsPQo0KdSKhRpwpwXtsVdRhGMY391Ju2/uq7vojlr46visRWxNak3WxFWpWqy9nhknOrJzm7c2 + mstF0+Wm5d2mpfZ3zq8pGU4+x2g/5aJ/0x4/rTBaX3/QVm/8BLP/AOM1m3Vl4yELE694aIDR5A8K6mD/ + AK1OhPi8/wAqb9k8Yjj+3fDfH/Uran/819aKjF71I9N6uLXbyXn/AMOmY+3n/wA+Zf8AgvD9Uu8uj/Xb + VmjptpqRtjjV5QPteodbOzPS/uQf+WPHOcZ7e9I1pf8A22bdqsxP2W15FpZjjzb3AI8njBzz3z7VmWFl + 4xNuxXXfDQH2vUOG8Lamxz9vuc8jxevU5IGOBxz1pGtPGK3s4Ou+G932W0OR4W1PGPNveMf8JfnIwec8 + 56DHIqMb/wARW/6+4tW268v6/jcPbz39jK76ezwytt/et5adnY0ZLS/+0WGNVmz9qkwTaWeB/oV3z/qD + njPcevbjS+x6l/0F5f8AwDtO3/bHj8etc1JaeMDPYg654cybmTb/AMUtqYAP2G8OT/xV5yOMY465zxzo + fYfGf/Qe8M/+Erqn/wA2FDox0/eLbW1XF91/df56feHtpv8A5cyX/cPD7XXaS19e33eP/Ev4OXfxGsvB + 2u6L421LwP8AEb4f3Umt/D/xzYaPpWpyaReX2mPpuraLr2jXUcMPifwR4msZFs/FXhaa809tQW103VNL + 1XQ/E2ieH9f0jzCz+Ifx++DviLSbT4/6r8PPGXw98XeJdK8K2/xa+FPgzxB4Cj8EeLvEDaZpXhbS/Hvw + 98T+LPie9v4Y8S6vc22gWnj3TPH0sWneI9R0XT9b8L6dpV/L4hs/pyytfGH2O12654cA+zw4DeFtSJH7 + teCR4vAPPfAzXM+Mvh5qPxL8GeOPh/4p1Lw7e+G/Gmk6n4Z162Tw3q0E8mnaxo8NjdNaXMXi9ZrO7iin + MtneQutzZ3ccNzbyRzRRuvq4XEwjGjhMb7HEZfFuFuWbxWGp1Jc854PFOnHEQdOcp16eHlVeFlXlN1aM + 41ailwYilVbq4jCQnh8ZJRne1H6vXnTUVGOIw6n7KSqRjGhUrKEcRGikoVoypwlH0C5tNQ+1WwbVpTmC + 6wRaWYxiayz/AMsec5H5e9R3FpfeWP8Aiazf62L/AJdbMc+Yv/TGvln4MfEH4krrs3wL+KviDQbb4weB + NFuri11S78K6nHZ/F/4f2l9pmn6X8WfDU/8Awk1ta3VxeCawtPiR4etFW78BeNriTT7i2PhzWvBmu+If + pOe18X+WN2ueHCDJCMDwtqYPMqf9Tf269PbjqOTFZfPCVnRqzi3yxnTqxrYx0q9Gor0cRRlypVKNWPvQ + ktbJqXLOMorow2P+s0lUhQmtXGdOUMNGpSqR0qUasXK8atNtKcXqtHtJM6U2mpY/5C8v/gHZj/2jx+OK + 5T4apLHomsCac3BPjn4hkOyJGVH/AAnHiBSuI1VSN6vJkjOZCvCqoGt9h8Z99e8M4/7FXVP/AJsDXjuh + 6F8TdQsUbRvEmhWdrb/ET4gzai8FncaZLLbJ471NHtntruPxOl8Hl/tG9DQ3WiSIkdrpXmst5c6pZ+VX + /cSo1IwqYiV5x9nSlUlL3ox1/fypxstbvVpau12z08KniIVacp0sNG9OXtMRGMYNxjUfKpUYVZqTdoq6 + jFt6ve3qXxGEzeH7JbeSOKY+Mfh6I5JYmnjR/wDhP/DO1niSa3aRQeqLNGT/AHxipLODxJ5cuNU0c4vd + QBJ0K85IvrgEj/ioV4J5Axx0ycZPj+p6d8YIpNXufE3iTQ5tDvPHPw4bw3pr6bDqEukww/E+yEqC706z + 8Ly3KahaTaNcRpfPdzaRHaSaU9xrVy8/iCf160tvE/ly41fQsfbdQ6+H9R6/brjJ+XxOoGew5wABk9a9 + GrRiowXtYSanN3p1Kqj71LDyavCK5uVvld9Lp2utTzaVeanUapTV+VWqUaTdoSqRvapryzteL6pprQtW + 8HiX7Zc7dT0fP2azz/xIrvGPNvcD/kYs5Hzd+c9OKdeQ+Js2m7U9Hwbl8Y0K7HP2O7PP/FRHsD+OKit7 + XxSby5C6xoQItrMn/in9QwQZb3GB/wAJOSCMHJJOcjAGOXXlr4qDWhbWdCI+0twPD+oD/lzu/wDqZjkY + yMcdc9sHH2Mf53b/AK/Yjyv0+7+r7/WJ/wDPv5eww3l/dv3+59yTyPEv/QU0b/wQ3n/zRGvI/A1lrt38 + TfiVrcUvhBLi20X4beCZdTtLK/u9VuF0PS9e8XR6ZrFkvi+a10r+zh8QnvNPjaysb68ttYa7uHu7VrAw + +n3smvabZ3WoX2u+Hraysrea7u7mTQNRSK3treNpp55XbxTtjjhiR5HdvlVVJPArzH4L2Xi3UdD1nx09 + 34VsI/iZrsPjXS1tvDPiCK5uPDkvhjw74e8J3usx6prGmX1trd94V8PaNd6np0lhB/Y9xMdHL3sljJqF + 152KpUqmLy2lzp1KWIq4tp1azcadPCYjDc+sW4t1cVTinHlck5LmspRn6eDr1oYDN6zhyU6tDC4FS9jS + XPWqY/CYxUrRlGM17HAVqslNVIxcINwbcJR9VSDxJ9ovs6no+77RHu/4kV3g/wCh2uMY8RDHGBjnnnPO + Aqw+Jft8GNU0fP2S8/5gV3jHnWORg+Ivoc5HTvmo0tvFP2i9B1jQiRcR5P8Awj+o4ObO1IxjxOuMDsSe + cnvgOS28UG+hA1jQg32S7IP/AAj+o4wJrHIIPic5PIxgjGDnOePQ9jH+d/OtiPn0PM+sVP8An3b/ALl8 + M+3l5P7y3dweJ/IfOp6PjMecaFd5/wBYn/UxH+VRiHxJgf8AEz0b/wAEV5/80Q/lS3Vp4r8h86zoRGY8 + 48PagD/rE6H/AISY/wAqj+zeKP8AoL6D/wCE9qX/AM1NHso/zv8A8HYj/IPrFRf8u77f8w+Gv08kvL73 + 1F06HxP9mONT0bH2vUB/yArvqNQuQf8AmYh3zjimvB4l+2zZ1PR932W1/wCYFd4x5t7jgeIuCDnnPOcY + 9U0+18VG2bbrOhAfa9Q4Ph/UCf8Aj/uc8/8ACTDqckeg4yetNe18Ui9mB1jQifstqf8AkX9Qxgy3vYeJ + wc8HnPpxwcnso3+N/wDg2v8A1/T+b+sT39nfy9hhtNn/AC/L7+4SQ+JftFhjU9Hz9qkx/wASG8/58bz/ + AKmL0+nr2rT8jxR/0FNG/wDBDd//ADR1lPbeKPtFiP7X0LJuZNpHh/URg/Yrzk58TtkYyMDB5HPrpfZP + Fn/Qa0H/AMJ7UP8A5p6PZR/nf/g6v/X9P5pYifWnbZf7vhultdnfr91jNsofEZs7Urqej4+zw4zoV4T/ + AKte/wDwkQz+Q+lT2cHiffe41PRv+Ptc/wDEhu/+fO0xjPiIdsevNVbK28UGztcavoWPs8OAfD+okgCN + e48UKD+QqxZ2vikvebdY0If6Uuc+H9ROT9jtOR/xU3AxgYyehOecA9lH+d/+DsR+q/rX5n1ip1p/P6vh + vLy8r/Nq2tzwz49/Db4h+KbLwn4t8Bal4bX4q/CnWp/HHw8XULC+0vS9bukszoviPwLr+oQ6tqD2vh7x + 54W1TVfDt3dNYX8ei6lc6P4qisLvUPDmnoNv4WfFdPi/4cutS0a/j0XXtA1KDQvHHgbxN4VvNI8aeAPF + UUVrdXfhvxXo0niWVrW7ihuIbuw1G1kvNC8R6RcWXiDwxqusaBqWnanc+rXFr4qF1b7tY0I/uLrH/FP6 + hj/W2XUf8JNk9iORjHfOR80/G34WfEKz1Fvjz8JNQ0hPjF4Q0CSzu/DtroVxbab8bfCOnSXWpw/C3xY1 + x4jeJbr7dcXlx8PfFh26j4G8R6jcyQzT+Gde8X6Dr/rYWOHxtCll2Jqxo1ISmsBjJVqyjSlWkm8HiZP4 + cJVqtzhUjb6rXqTqy/c1a559apiMLVnjcPSdSEow+uYZYfDt1I01b2+Hja31mnB8soWf1mlThTVqkKcl + 9UeR4nP/ADFdGA9RoN0cf+XFXN/DNbxND1hb24trh/8AhOviHse2tJLNFT/hONfDK0cl5el2MwldXEig + RvHGULxtLLQ8AeLrn4l+CvC3j7wn4m0O98N+MdB0zxFo1w/hnUredrDVbSK7gS7tZPEwmsr2ES+RfWNw + FurK7jmtbmOOeGSNeS0PTviHLod0+geIdLtnT4jeM5LhE0ZYYpbCH4l3c2qW0gvZtbdpbyytNWs7e4tn + szZx6oJDDd3VrBcp4WKhPCV4RnSrSq0qlWjUoxdSVSE1aE1KFaULODTUk/eWt0tT2cJOOMoytVo0qdX2 + E6derGnTpSg4zlF81GE2lKLUoysk11ex6N8Q9/8AYNj5Qj8z/hMfh5s8zIjz/wAJ/wCGcb9oJ2564Bq5 + Z/2x5Uv/ACD/APj91DIzOcH7bcZ7Dj0/p0rxTVdV+Mtw+rw+JPC3h610S3+IHw6Tw3M2qrZNc6f/AMJ9 + oBE/2uxu/E9xfzeciwst5oXhf/QzZ6gEa7u73SNJ9cs7vxZ5cv8AxJPD5H2y/wD+Zm1LIP264yMf8Iie + nY55HOB0r0J4eSjG1WFuaTUqdanZ81PDz6396Kdpae7JSWskzz6VePPUfs5L4Y2qUZN+7OcbpcrXK2rx + f2k01vY1YP7a+2XO02H/AB7Wef8Aj4PHm3uOBjHf1z+FOu/7b3Wm42GPtDdrgc/ZLr1Jzxn+dZ9veeLB + eXOND8PZNtZ5B8T6kMAS32Mf8Ujzkk9hj3p15eeLSbXOh+Hh/pD4x4n1I/8ALnd9f+KR44+vPFYewd7e + 1fn+9pf3b/1bq9zb260fs+3/AC4fl/d/q3pfzr41X2r23w71fS11ZdDu/GV5oXw80zVtM099Vv8ATtU+ + Ievab4MsNQgsJbm1ilXT7jW0vrqWSR0s7K3uL54LlbY20vqWmxaxDp9hFCmmxxR2dqkUaJOqRxrBGqIi + rhFVVAUKgCgDC8Yr591TxrqHjr4p+DvCXhm90e9PgDUfFXinxwvhXxvcXmlWeqaRokHhfT/APj2Wy8Pi + TT9QvJPHw8XWPh68geeWXwjDe3dvBDFbSye8WN74tFlZhdD8Olfstvg/8JRqIyPJTBwPCR6/X8a87CxW + IxmOxFOuqlOH1fAwnDEUpxlLDxlXqyi4zdNfvMYqEkoRmp4eam2lG3rY6UsLgMswtSg6dWosTmU4zwvs + 6kI4qVLC0ITToRrfwcCsTTc6k6UqOLpzoQi51ZVZ4/7Z+0X2f7Pz9ojz/r/+fO1xx9Pf9MUo/tr7dBj+ + zwfst30+0dPOss8DHfHOaz0u/FhuL4nQ/D+TcR5x4n1I4xZ2uMf8UjzkY645yOcZLlvPFgvoCND8P5+y + XgwfE+pY/wBdY9/+ESHt27+1el7GVv4rei/5fUv7vl5d/wAlfyfbr/n2v/BD/u/3Omn3eavq3X9ueQ+T + YYzH2uB/y0T3pP8Aic/9Q/8A8j1Tur3xcYHB0Pw6BujyR4n1I/8ALROg/wCESGT7cfWo/tfizj/iR+H/ + AH/4qbUv0/4pGkqMulZ9P+XtLy8n019fuD26Wns+3/MO/LryeS08vS9zT/7c+ztg2GPteodrg/8AL/c5 + 7+v5dKQ/219tm3f2fn7La/8APx0829x1z71S0+98Wi3YDQ/DxH2vUOvifUgf+P8Auc8f8Ij68frTWvPF + hvZidD8P5+y2gwPE+onjzb3B/wCRSzn14wPU0KjK/wDFd/8Ar7S8vXy6dWCrrf2f/lu/Lpyaf8D0Lsn9 + s+fY4/s/P2mTGPtHX7FeentnuK0P+J762H5XP+NYD3fiz7RYH+xPD4IuZMZ8Talgn7DecZ/4REds/wCe + a0vtvi//AKAXh3/wqNS/+ZGh0ZaXqvp/y9peXp109G/UPbp2/d9v+XD8u0f6t6EVl/bAs7TH9n4+zQ/8 + 9/8AnmvX39altP7b33uDYf8AH2va4P8Ay52noRjjH8+9ZVld+LBZ2v8AxJNAx9nh5/4SbUh/yzUjj/hE + T+WePU1Ys7zxaHvMaH4eObpSc+J9SGD9jtP+pR54APbr7ct0Zf8AP1vVf8vaXl5Lrp6eVm37df8APtf+ + E7027Q06fd6XuzjW/tVvuOn/APHvdYz9oH/Lay9c8024/tjyx/yD/wDWRY5uBz5qelU7i88Wm6t86H4e + GILnp4n1I5/fWX/UpdfbHPPPHMc914sKD/iSeHx+8h/5mbUv+eqY6+Eh/MUvYSa/iuzW3tqSutN7a663 + 1Xy6r28dvZ/+W78v7mttPut2v8xT6drf7NnxQi1XQ7BB8CvjX4sgs/FGlWEN3Pp3wn+M3ivVfLsfGdjY + xBpdO8E/FzW9Qh0vxrHZRHT9C+I9xpHi+S0hh8a+O9dsvpX4bG4/sPVvtJh3/wDCc/ETb5BfZt/4TjX9 + xO/BLGTzCOMbNnO7IGs9z4sf72g+HW9j4p1LGP8AwkfYHp1zXlXh+6+I6aNdtoej6CQPiF45iuIVv7jU + Wkt5fiDqX2qd5bpPDa2SWqtqMTCJdSmlhWLUYYJbiBdEvzMsX7SeDr1oVKlenTnRrVaU/bTxSio+xq1a + STbr06X7udZTTqwp0nOEq7qVa15bhVyYqhSlSpUp1qdWlGtGGHhh+bndWEJtK9OdVurGCTdOVSaVqXJG + n6J8RTKugWJt445Jh4x+HpjSWUwRM/8Awn/hnaJJVhuGjU93WCUj+4Qans5vEHly/wDEt0rm8vyR/bt4 + MMb643DH/CPngHoQfmGDgdB5Fq/iP4p6lLrFprXhLRbPQrPx38M/+EavXu7rTbu8tX+IekG6N/5cniCG + Se3P9nWcP2RI4rr7PqWrObS1u9HtLn1uyufEvly/8SfRD/puoZ/4qK+HP265yB/xTDZA9eM9cDoNa1CU + YxUqtONpyd41aLvzU8PJL3ubVJ2krJp8yeqOajiKblUm6U5J8kVz06yd4yqRbSha8W07Saaas07FmCfx + Ct3ckaZpRxa2hbOu3mAvmXuDkeHj6NkewPOePFtY/aG8KG3vpPD02m+Oda0PxR4g8JzeEPBWq3ut+Lbv + xH4Wit4PE+l6fob6FaTXkvh1NYsLvV54pPslpaXEc7TlZI93rs2pa/Z/2pdXGl6DDb2+mxXFxNL4jvhH + DBB/aEskrv8A8IxwqIrs52/Kq5rxT4PeELe08JeA/HVt4I+G48YeJfC9lqOreLdBM2l3mqr4otZfFeox + peTeEIdYOmXmrXZ1FbW+dX81YnmgjnQqnh4xY54rDYXA4rC0ozo162Kr1vZVatKnGph6cHh4xlGHtW6t + S3tounzRT1UZwn9Bl7ylYPGY7McHja7o18JQwdHDOtQpVKtani6s1ip1KdSp7FLDQUnh2q0edpRfMp0+ + 8+GWieLfDfgnQ7LV9P8AD9zr9zBNq/ia8tpU0RNQ8Ta5dza1r982nWHhxYYJLnV768lczG4vJCVlv729 + vGnvJ/QLGfxH9is8aVpOPstvj/ie3o48pMcDw9gfQcVH9p8Sgf8AIG0Tt08R338v+EXH86Wxu/E4srQD + R9DIFrbgE+Ir/OPKTGf+KZ6130cLTw9CjQp1/wB3RpwpQ5qtGcuWnCMU5SknKcna85zcpTlzOTbbb8zE + 4/65iK+Jq0E6letUrz5MPiYRUqtR1HGEIWjCmm7QpxSjCKUIpJJKNJvEBuL4nTdKybiPI/t284P2O1xj + /in+QRg54OcjGACRZvEIvoMaZpRP2W7wP7dvOnm2WeR4fyO2Bg5z1GBlkd14lNzfH+x9EybiPP8AxUV8 + AP8AQ7XGP+KYJPHPQfpyq3XiYX0BGjaJn7JdjnxFfEY86xyc/wDCMDpgdu9a+yX/AD/j6e0w/k/5f61R + j9Ypbewemn8LFdLf1/Tvbup/EfkPnS9JAzHk/wBu3p/5aJ2/4R4fzpnneIP+gZpX/g9vP/mfou7zxP5D + 50fQ8Zj6eIr8n/WJ/wBSyKaLnxKRn+xtE/8ACjvv/mXP86PZJ/8AL+K/7iYfuv7v9K4KvTj/AMuH03pY + rpZd/L+loJp0/iL7Mdul6Vj7XqHXXb0HP2+5z/zL3rnnuOeOlNabxCb2bdpmlA/ZbTj+3bzGPNvcHP8A + wj3rnqB2wTk4TTrzxN9mO3R9DI+16h18Q34P/H/c5/5lk01rrxMb6XOj6Jk2trwPEV8BgS3vOf8AhGTz + k+n480Kktvbx06uph/8AKzD29Ne97B/+CsX1t5+S3+Ysk3iAXFhjTNKJ+0yY/wCJ7eHkWV3/ANS/xxnk + ZPt1I0vP8Sf9ArSf/B9e/wDzO1lyXXiUXFh/xJtEz9pkx/xUV8Rn7FeDB/4pgY4J9a0ftnij/oDaF/4U + V/8A/MzR7JL/AJfR6f8ALzD+Xlv3+fcPb05a+welv+XWL8n38v8APUzrKXX/ALHa403SiPs8OD/bl4pP + 7teo/wCEfOD6jJ57mp7OfxEHvdul6Uf9LGc67ejB+x2nT/inuRjBz65HQAmrY3PiT7Ha40fRSPs8OCfE + V8M/u17f8Iw2Pzqezu/Ewe926Pof/H2M58RX3B+x2g4P/CMc8YPQdaPZL/n/AB9PaYfsvLX8dbh7em9P + YPvpSxfS3n/XrcdcT+IjdW+7S9JH+j3WP+J5eEHM1lnk+HuD0x685Ixyy4m8QCMf8SzSv9ZD/wAx28P/ + AC1T/qX/APPueCXF34mN1bg6Pon+oucY8RX3/Payzknwz9AMA9c9uWXFz4l8sf8AEn0QfvYf+ZjvT/y1 + X/qWB/Oj2Sdv38f/AAZh+630v/wLh7emtPYO+38LF+Vuv9fJmp5/iT/oFaT+Ou3uPx/4p6ub+GbXjaHq + 5vILa3f/AITn4hhFtrqS7Rk/4TfXyxZ5LSzKMspkjCCNg0aRyl1aRoouhN54oAz/AGNoX/hRX39fDIH6 + 15t4B1LxilxFZtomkL4fufGfxYOq31vqV1e3lpJF4v1abTnRZbLTIY4Zrxr2zlXbdzyKLSeNIkN15GFS + 1Krh5c8ppylTtDkqaz5Ypy9lFuMYuzlKTUUrtts6aCVWjiIxhGm4KFS9T2tK6pxqNqHtpJTnJKyhFOTd + rJHYfERjHoFi8cLTMvjH4eFYo/LWRyPH/hnCoZXijBJ4+eRFwT8wpH11tN03UL+/0y8tLKxk1a9vbqa7 + 0dILa2t7u6muZpXbUhsjgiRnkbGNqEgmvJdU+JHiXxCdT0u/+GXinRLPRvHnw9t7G+u/KgfU1T4kaLCb + pG1GPS9EltZ0t4HtX0LX/EMu+WQ38NhZnTb7VYtR+GEHiI66NXvfjLeaZrviW91TUvD8njTw9L4cmsjc + 6rb3nhU6RNqkls/hLU4L6a21bQpPMt72GOGORykY3b46njqNKH1alGpV9pUsvrGFjGLlRozhKblzuavy + xlGnJNXet0Y5fPLq1aq8XXqUaS9heUcJiK1SS55KcYxjKlGMlFtxlNOLlpdatc7pun/HP4j+ELy/Xxro + GgW/jfwPJ9gt9O+HukeI7fSYvEWsahf6NqSzeIvGenx6wsHg25i0efTNV0KC1utTeXVbuH7ODpEn0RAL + jSdP0bTLbw/dw2unJBY2scD6FbQx29pptxbQRRW9tfRW8CJFGu2GGKKCMBY4lRFUBthqd1aTSQW3hPWY + oIbOxhht4pvDKRwxRPeLHHGia8ESNFwiImAqqBgADM95rWoE2gPhfXR/pLdbjw1libO7AA/4n4579RwD + 1OAeLB5Z9UtJ4jF1sROjSpVatfGyxPNyXk3ThiKtWFHnnOUpeyjC6cYP3IU4w7sdm6xrcI4TC4fCwr1q + 1DD4bAQw3IqqhCMalTDUaNbEezpU4RhLETqyhepKLjOvWlUufb73tomo57f6RpH/AMtKWxv7/wCxWeNB + viPstvg/aNH5/dJzzqeeRzVP+2b/AP6FfXP/AAI8N/08QEn8qfY61qIsrMf8Itrpxa24yLnw3g/uU/6j + +fp0PrXc6VTrVn/4FhvL+7934Hne2ptfwluteTE+Vt310fz+Q5L+9+0X2dD1AH7RHwLjSOP9DteP+QmB + 78E9exyKFv777dBjQ9QJFpd/KbjSOf31lk/8hPHHHvzx0NVE1m/+0XxPhjXMm4jyPtHhvIxZ2uM/8VAo + 568cYPXOQHJrV+L6AjwvrhP2W7GPtHhvnMtkf+hgPTA9Dz0IzT9jUt/Fnt/NhtrL+7bZ/wBN6ntqf/Pp + bae5ifJd7dvv+7Su7+/MD50G/HMfIudHGD5iempk9fY/SmC/vf8AoB6j/wCBGj//ACzqC71vUPs758La + 6OUyTceGv+eif9R7/D39ajGs3/H/ABTGu+/+keGv/mhH9KSoz6VZfKWG8u0fT9AVakv+XS6a8mJ8klpL + rovx8yxp1/qAtj/xIb9v9L1Dn7RpHU39zkc6nnjpn2pkmoXq3spbQtRH+i2vyrcaQf8Alre8kDU8HPOO + c8ZI7iHT9a1AW5x4W11h9r1A5Fz4bwc39zxzr+eOn4dxzXH+PNTvrrRNYtn0TxLpqXdrpFlNeWmq6Zp1 + 1bQXerG2nlhv9I8RRanZuYZpUW506RL2Hl7d0mEbBxozcknVlvr72Fv0vZKOr20XlYulKFWrTpqnGLqV + IQvKGItHnnCLdueF2k07OUb2tdXOzk1G8NxYY0TUOLmQ4M+kYP8AoV3x/wAhP/PTvkaX9pX3/QBvv+/+ + kf8Ayzr84/BGv6/4sj1q50S08fate6ZotzJZaLqHxt8V6xrF7rGmal4astR1i30HwZ8Q7a50LwxqFvre + ow+HYfEevr4mvvsN7caho+lJpgXWPSJbnx0tjdlPgj8YW1C1SztUb/hfPxJNtd3941pA19DEPHhI0e0l + muJ5VW8lv/ItZBLHBC0d83fPKcVCTi69Jyi4pr63gI2clF71OVWV7SabUJXjLllCSWCzHKJxVS+PUfet + /wAJVaTfLJX0hj56tp2va+llbV/YFlqV39jtB/YuonFtDz9o0g/8s1/6iYP4EA+1T2eo3u+9xoV+2bsH + m40jj/Q7TjnUvTB4yMnH0+MNGk8fQTR6X4h+B3xX85E0fOpaJ8fviI2jhL1Fiu/JB8f3kpWzlhmuyksk + EkVrcWttdJBPG009DwnLfa7qGvW2nN47urjT9B+0DTrn40eOb67n1yG+8Mx6rfW2h+GviCuo2vh+xsdY + aKwj1fWP+Eg1DUbbVNMutLsJtGiudW8nMJrLZ4eniKlSo8U6nsnhZ4PFRfsoxlLndHnVNNP3HOyk3yxb + dk/Zy/C4TNI4qWHqTprBuj7b6zhZYZr2tTkj7P2uYr2tpJufJzckffnaCbPt241G9+12+dDv1/0e64Fx + pHP76xz/AMxPnH1HX8KZcaleeWMaJqP+sh/5eNIAx5qf9RPv0+uK+ULqDxMtpcSw/Cb4uT39obe2jRvj + l8SEW7e9t7RpLi3T/hPpVitLG6nSO8Vr2R5BA4ifYJriyiuLDxnYxz2U/wALfiTqmpCET2uoab8cfihD + oZe4trm6tYZVm8f3l2ZLSSO3sr11eNHu3c5sYDBNNxSzPDw3eYuyV3HL67WraSTWEs9YT1jeMUuaTUXF + y745JF8sVXwt3JxSeKy1X5VTlKd3nqShGNSHvSau5OMVKcJxj9i/2lff9AG+9f8AX6R257an/wDrrl/h + pLJNoesPLay2p/4Tn4iBUma3d2U+ONfYtm3nnUAOWjIZlJaNiqmMo7fMupw6s+keL4bnwR8XfC8+k+Bv + EGtJr5+NPxTv7Ky1K30a8vdOSLz/ABXHp99NvjiM0MF1fLaXAaC8iNv5Nzde2/D/AMS6uk9roq+FdUjs + NT8ZfFVrzWLqW3aHTzZ+LdavLcv/AGYdTtsXM872GL680yQ3MTPZx38JLrrGvSnKhVhOvKDr1MOuejKD + 9o+WF/ZuhTqcnNoqtvZqzTlexy4jLnh6MowdGcpJVW1VoWVOlR9s3GpSx+KozlKnK8aXN7aWnJBt6+k+ + MdD1HxDoUmnaRqdlo+pJqWharY3+o6VPrdhDc6Frum65Ct3pdtq2hXF3BO+nC3kSHV7GRVl8xZspsfio + fDvxohV1HxD+GB3zTzHPwf8AFfBnmeZhx8cOitIQO+AM5PNFFeld2S6JtrTva/nrZfceJZXbtq0k33Sv + b7rv7x8eg/GmOaSYfEL4XkyRxRFT8HvFeAIWmZSMfHEHJMzA9sBcAHOXTaF8apvK3fEL4XjypDINvwe8 + V8kxSxYOfjieMSk8dwO2aKKQw/sH40/9FC+F/wD4Z/xX/wDPxpYNE+NUEMUK/EL4XMsMaRBm+D3ivcRG + oUE4+OIGSBzgAUUUARjw/wDGgSTSf8LC+GGZnV2H/Cn/ABXgFYo4QF/4vhnG2IHknkntgBRoHxpWdJx8 + QvhfuSKWIL/wp/xXgrK0TsT/AMXxzkGFNuMcFs5yMFFAEkuifGqWMxn4hfC5QxXkfB7xZn5WDd/jiRzj + HSm/2F8af+ihfC//AMM/4r/+fhRRQAW+hfGq3j8tfiF8L2Blnly3we8V5zPNJOw4+OIGA0hC98AZJPNZ + +qeDvi3rMF1aan45+Fd3Z3tvHbXVpN8HfFbQzRRSSSKGH/C8c53yFs5yGSNk2suSUUXGm0002mmpJptN + Si04uLWqaaTTTTTWhzjfCDxyzRt/wk/wnXy3L4X4R+NAHyjptf8A4vvynzlsDB3qhyMYMn/CpPHH/Qyf + CT/w0fjb/wCfzRRR9/3vy/y/q7N/reL/AOgnEf8Ag6r/APJEcfwg8cRxpH/wk/wnfYipub4R+NCzbQBu + b/i+/U4yaI/hD45RpD/wk/wmbzH3gN8I/Gvyfu0QqmPjwPlOzfg5+ZmPeiij79PN+X+SD63i/wDoJxH/ + AIOq/wDyQN8IfHLSI/8Awk/wmARXXYPhH412tvMZyc/Hg4K+XgEfws478D/CDxy67f8AhJ/hOvKnK/CP + xoD8rBsf8l36HGD6qSO9FFH3/e/L/JB9bxf/AEFYjT/p/V/+SCb4PeM7mGa3uNf+EE8FxG8M8E/wf8Zz + QzQyKUkimil+O7xyxSIxR45FZHQlWUqSK9e8E+H9T8NaENO1nVbDWtUm1XxBq19qGl6PcaDp8s+u69qW + tmO00q61rxDcWsVquoLaATaxevM0DXG6ISiCIopWV07axvZ3el7X++yv6X3InXr1Fy1K1Wot0qk5TS9F + Ju1+trXsr3srf//Z + + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QECRXhpZgAATU0AKgAAAAgABwEaAAUAAAABAAAAYgEbAAUAAAAB + AAAAagEoAAMAAAABAAIAAAExAAIAAAAQAAAAcgE7AAIAAAAIAAAAgodpAAQAAAABAAAAipydAAEAAAAQ + AAAA6gAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMC42AEJyaWFudGEAAASQAwACAAAAFAAA + AMCQBAACAAAAFAAAANSSkQACAAAAAzQ2AACSkgACAAAAAzQ2AAAAAAAAMjAxNTowOToyMyAwOTozNzow + NQAyMDE1OjA5OjIzIDA5OjM3OjA1AAAAQgByAGkAYQBuAHQAYQAAAP/bAEMAAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/A + ABEIAJYAoAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMD + AgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp + KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOk + paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQAD + AQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFR + B2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ + WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfI + ycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP7m/B3hLRta0MajqP8Aa013 + Nq/iWN3j8R+I7WPy7TxLq1nbRx29pqsFtDHDbQQwokUKKFQcZyT1H/CvvDH/ADx1n/wq/Ff/AMu64nw/ + 8QfB/hDSvDGi+JNctNH1LxVr/jiDw/DeieKPUriy8XakLm3hu/JNklxGt5DIIJ7iKWSHzp40eG2uXi1/ + DfxF1HxT4f8AD/iTTvDVtFYeJNF07XrCO88T6dFdR2ep2dve20d3HDbXEUdysNzGJY4ppo1kDqksiqHY + /wA7fOydvWzTt2afUPLrZP5O6T9HZ2fk+xv/APCvvDH/ADx1n/wq/Ff/AMu64PxHffBfwfrUGgeK/FC+ + G9RuPD2qeK1GueOPE+mWMXh/RtV0DQ9Q1O81a81yLStPhTV/FGhafbR315bT39xesthFdC0vTbduPE+u + nH/FPaZyEP8AyNdl/GcAf8ePX1HavH/Gvws8CfEjxFYeLPGfww0bXPEej3ejXGk6vcePLqC70q58NzXt + 9okunNaGBbJdO1C/m1e3SBY4v7aisdaeN9U0zTby02ofV3U/2l1lS5ZXdCMJVOa3uWVSUY25rc2t7aJX + d0ne2iV+l9Fvr0fS/Tf7ixN47/Zvi0S68QJ8SvD91Y2se5o7P4paldajNcNYyalbaba6XF4na/uNYv7O + MzabpMVu2oX6tH9lt5fMTONffFT9mzTrzxhpt541uLbU/Aml6NqniTT7vxJ47s57ceI/DbeLfD2mWL3m + oQWus+INb8PI+pab4d0i4vtbuYVYLYh45FXF1f8AZ5+DusMtzqvwc0S8NrqFlr0SH4jaukMOpaXbw22n + XUVrFdxW0cthZ2NnZWSrEsdtY2Gn2UKpaWNpFDoeKPgN8K/Gl1HeeKvhLomu3kFxo8ttdX/xD1KWezbQ + NLttL0yOylEwaxtI7Oys2ubW0MFrqN9aW+p6lDd6jBHdr3QWSc0OeeauL5udwp4O8daXK4p1f3l4qspX + dK0nSaUkppr3+0bXVtW7rS6eit11V+m256loKfB/xRfXOleHfFdjrerWUUk1/o+lfEnV7/VtOSCdbS4/ + tDTLXxLLe2LW12ws7lbqCJre7/0aYJN8ldd/wr7wx/zx1n/wq/Ff/wAu68W8C/Cr4e/DLxJd+KfA3wm8 + M+HfEWp6dq9nd6nZ+LlaWay1XXV8R6xBtuIpoozqWuTpqV0YY0a5lig8xzFaWscXsv8Awk2vc/8AFPaZ + w23/AJGuy9Ac/wDHh055NcNf2HtH9WdaVKys68IQqX63VOdSNuzUvVDXN9q1/K+1l+Kd18r9ST/hX3hj + /njrP/hV+K//AJd15v8AFfQdP8KeEYtb0KTVbTUo/GXw109ZpfEGv38Rs9c+I/hTQ9Vt5LS/1S5tJku9 + L1G8tW82Fygm82IpMkciegp4q1x1LDw9poAMqkHxXZA5hkaNsf6DzllJT1XnjpXkHxn8XXFz4fs/Deoa + Ollc33iP4b63a3Nrq1pqlsYNE+NfwosLuC48qOCaCd5PENnJb4ikjkSK63vEyRrLiM7/AMH+EdF1jQ11 + HUf7Xnu59W8RpJIniTxHapstvEeq2lvHHb2mrQW8McNvBFDHHDEiKkagLXT/APCvvDH/ADx1n/wq/Ff/ + AMu64nw98RPBvhOx8NeHvEeu2mj6r4o1jxwugwXonhh1GTTfEetXd7DFemE2Mc8FruujBPcxTPbRXFxH + G8NvO8er4a+I+o+KdA8P+ItP8NW0Nl4j0Sw16xivPFGnRXUVnqNpa3kEV3HFbTxRXSxXcayxRzzIsiyK + srhQzCd721s7O3R2Ts/OzTt2a7hfp13+Tuk/wf3Psa194K8JadZ3N9cRa4LezgmuZzF4l8ZXMohgieWT + yra21eW4uJNiHZBBFLNK2Eijd2VT4F4P+OP7JfjnwNb/ABH8P/FfSG8KXen3mqwT6x458YeGdZOn2N5q + unzXUnhXxNqmkeKoEmutE1VNPWfRYpNVSzkn0xLyBopZPe7vXNYv7WezuPD1h5F1A8Ewi8YW0EhiuUaF + ws0NmksL7XOJInSWI4eN1cAjwLxD8A/hn4o8OHw1dfDTTbOxTQdD8I2k9p46Vr2w0LwnbWtloen2r6la + ajB9nsk0rTLiNbm2uPO1TSdE12YSa7oukalY9eG+oNSWM+tqTq0uSeG9i4Ro++q7qQqpSlPWm6XJOKXL + OM1Lni6afNpa3W9/+3eVLt9q7afTTdnbah4x/Zy0q/s9Lv8A4oeFbbUb6e8t7exk+Ll4LrzNOsNV1O/8 + 6AeKjJax2Vjoerz3U1ysMNuNPuklkSSMpXOap8Vv2a9Ie6W68by3MdtrnhPw2lzofiXx14mtb7XvHEGr + XHhjSdNn8N6jqyX1/qiaFqqx2tuWmie2RbiOIXdk1zkP+zz8GGsdTsB8EfCSaXrFrNZanplv4xlttOvL + S9tvEmmy2sljbiG2FuumeLvEukRwxxrDa6Nq91pFskWmmO1TXtfgn8MrLS7zQLX4TaDBoeoXFvLf6JH4 + 8vRo18LdPErG0u9K3f2dc6Vev4x8UTatpMts+l61d67qF1q1ne3M3mjf/hHT1lmc17uihhIX9+DnLWc7 + fu/aKMLu8lGTqJNxivf0+Hzbv52/G1/K/ka9n49/ZxvdQvNOT4jaJDJaRwTR3d38T9TtdL1OGZbjfLoe + rT+J007W0spbS6tdU/su5um0q7ga31BbaUorewf8K+8LnkRayR/2Nfiv/wCXdfK6/srfs/Lb2dkfgH4Q + mgsdL1jTLNbjxvf3TQaTrmpJq+u6Yk1xNLMLPWNTK3mqWhcw6hKP9LWVAVr6iXxJriKFHh7TAq4Qf8VX + ZYAC5AGLDGAMAADjpiufErBJw+pSxc4u/P8AWqdGElZRUeX2NWonzPnk00uT3YqU9ZN3d9UkrLrfWy5v + le9vIm/4V94Y/wCeOs/+FX4r/wDl3Xlfxk0Oy8I+CoNa8Py6rZ6kPHnwn0nzpdf16/ibT/EnxU8GeHNZ + tpLTUNTurSVLzR9Wv7RjJAzRCfzoWjnjilT0xPFeuOCR4e00YMy4PiuyBzC5jb/lx7kEr3K4PHSvFfjt + 4unufC+n+G9Q0hLK6vvGnwi1u0uLXVbXU7c2+i/H34PWN5DceXHbzQTPJ4hsntsRSxSpFdb5ImjjWbnj + 8cf8UfzQz0nwhfeEbLTdBTWbvw/aeIr7VPHVj4eGozWEOtXkL+NL2a/tNGE7pf3EbXMOly3dtYlg08Ng + 8q+ZHbsMT4bNdW/wf+Ed7YvPLJp/w98HXU1nGkrNqNovhrTEvbNYyzs9z5DyT2CBoy2oW1pFJKsEk2dP + w14G8KeJ9I8P65r+jW+qal4b1jxz/Yst5Lcvb2LXvjHUJriX7D539nzytLp9m6T3VpcSweT+4aMPKH4D + w78KPBXxR+CnwU0rxZbajJDovhDwL4l0i98N+LfE/gnWNN1qy8LWdtBe2XiDwTqvh7Woc2t/eWs9ul8L + S9tbi4tryCaCV42wrqbpVFSjGVVq8FKpKjFyTTjzVI0qzjZpO/spp2SaSu11YFYR4uisfWr4fBuVq9bC + 4SljsRCnyyv7PC1sZl9Ks5O0bSxlDljJyjJyjGMvoy2ngu7aC5t5kmt57azmgljLvHNFLtdJI3WTayOr + Aq4+VlYEHFZ2s30mmaXeXcCrLdpIYLCGQSKlxqN2Y7TTbZj5q7Fub6e3gLF1VBJud0UFh812nw9+Mvw7 + 1TTbDwj8VdJ8Y+F7vxFq+tXWkfGXwtp9/qb6dq4s7i18DeFPHfw/h8F/8Ipb6LfQare6Xq3izwb8Tr+/ + s9ZbR5TEmhWD3VQ/GbWdE1LQLL40fB/xD4EGm6HrnjPxT4j8G4+LXwy0mbSDrllZ6TP4i0DRdO8XZu7P + T5vE2mXet/DjQLa4J0fT7WV9e/tHS9N4JZjGNNxxFKvg6rapc1WClRjN+zi6n1ijKrRpwUqnNBV50Zzh + CU4w5E5L6SHClbE1IzyTMMr4hopOr7DAYiph8zaj9aqRw8MozSjluZ42vKlhJOrPKMLmWEoVK2HoVMVH + E1oUX9E28l5okCadql5Pf2klokFhrN0P9Je4MboLPVGjEUSzzuT9hvQqpdcWVwq3ywS6r2IA3fe4M5/h + k6eVx/y0/Tr689fMNJ8T/Dv4o+Fb248GeJfDHijStU0COYX3hzVNK1Ix2ms6Y13YXX+i+a9tJcWd1DeW + X2hI3ZGjlVdprsNCeHUdLsbq4trJLth5N9GqRbYNQtka21G1G6EsRbX0Nxb7iWBMZIZhhj2UZxvGMKka + lKdP2lGcZe0vCLUZLnTlzpc0HGTbcuZpt8t385isPiMPUq08Xh6uFxdGr7LFYevRnh6lKpJOUVKhUjCd + KTUZc0OVKNk7JTSNVx++iG7rZ3WOJOoksunz/qDxjHJxiy2P3nzH764wsnH7sf7fH+TWa9pa+dH+4teL + S6OdkOAQ9kP+ePUjpx0yc9mpeIXh03RNbvoILMT2Om393BmOB1WW2sJJ0LKYl3LvRdwyMjit5S5Iyl/K + nL7lf9DmhFzlGC3lJRXrJpL8Wc/4E1S7u9PuYtRuXuLmbz9dtXkBMn9k+I7m61CyhZo/LjA066GoaPAg + USi0021lny83myeT/tCcXnhLByP+JF/eHP8Awv39nbszN9cjHWvVpdKstCg8PXkFvCLbSmm0C5DrFI/9 + lX93FZwyt+7VDJbajbaVPNcysVgsBqLogMoWvI/j/FDHeeE/KjiTd/YOTGqDP/F/v2d+uyNDnvzmsMPz + Rh7KbcpUlFc0neUoOKcW+t0+aDbbcnByerNsS4TqOtTSjCs5NRjFRUZRdpJRjZLmXLV5UkoqrFLSzftP + gLTtPk0K01OWysm1G3v/ABjaQajLbQvd29rP4v1See3iumXz47aWa1tppoUlSOWS3hkcFokZfI9FOs6b + 8F/gz4u0BtXvbzwb4B8J61d6Bo5up28TaC3hrSbPxDpDaPbOx1nUU0u4m1Xw7aRQS30niHTNMt7MOLq4 + t7j1zwLqWn2vh2xtLi+sre7vNZ8WpZWtxcxQzXcieKNbdkt4nYSTFVwziJJGVfmIxWV8HAx+FnwmBSM/ + 8Wy8K8Fjtx/YOhjJ+Tr6g5GM888buN01tfqt11T+T1XRmdKp7KpGpyqSi/ejLacGrTg+qU4txbWqTumm + kzqtJ8XeGtasrPUNJ8SaJqNnd6Tous21zZajZXMM+k61H9q0jUopYbh1ksdTtVa40+5UmG8hVngeRVYj + zv4o/EG20TwnLaaLrdxa+IvEms2nhDw7eaXp9vqV5Yax4m1M6VDrNpaX0U9jdf8ACPW1xd+JLr7Vb3lh + bafpF7e6ha3Fha3ETeCWzQeC/jPrGlR2Vna+GfiBLq1v4T1YTIjf8JD4au7rWdW8CvC0cRilS+1H4ieM + PDsVr9oF3pqeJzKlmmiRPf7eoztrPxL8KaJBegQ+ENO13xvrFjDGGlF7rLah4Q8Ite3DRusFjeWsnj+S + G2QJcXl9o0U6TJDptzDcedDGVKtOp7qhKNedFy1a5XJezqJ6fFRlGomtLv3eh3/V6VLFRlBupho0PrkH + U5HzxhTclSrW92LliYPCzTV1O6a6mq+pSfCq/wBEuPCk91/wgmr3WmeHfEWjeJNd1jxBPp2t6tfGHRfG + mmatrN9f6lJqGs69dx6Z4xsL+9mXxHf63beLjf2ev2OtweNd3xD4p1i813TNWN/tsvBes2OqXUUU0lpY + zXF/aNpt6l8LeaMz2mkeG9TvtUmgu/Otzc3Wl3uC9gQMrx9FpNz4J8S2HiHTZ9W0XVdIl0fUdKsUvZbz + UoNYH9l/YLZbBDerPdPdpBFPbFJrZ5BcJJEYvMXC+GrXus/D6zsPEcdy+txtrHhvxk13iCe+8RaTc3uh + eI9RhEMcQXTtYvrW51PQZo4oEk0K90y4t4IYJIY1560pVJyw0Z7U44hRTsoShP8Ac8yVrRlWhzpK6fsp + xslIOac8OsbPmdWNaWFq1Ho60KtPmcnLVzqRpzqUardmoTw7bcm2/rGw1O31OGK5t5lwbKZZEbG6KQGD + dE43feGcq38SkMOGFGv6xaaBo+sa5qF3bW9ho1hearfT3EkcEEFnp1lLd3U888jeXDDDBDJJLK+EjRS7 + FVBNeK+Etdv7W3027kZZrkafLa6tEDsjlvbKSOz1FMKm1XhvoLhY2jBRSvy7oyVbpvi/fx6l8J/GNvZ3 + Gkwt4m06PwdZy6vGbmwi1HxtPa+ErGG+shG32vffa1BD/Z54vneO13bJwx9OnWU6SqR35FNJ7tcqkno+ + t+979Tio0lUxFKhJ2U60KUpRV7KU1BtLW+julr8zzr4SWOseBtR8H2uq3uj7fih4Lv8AXfE6Wn2q0ik+ + L+nTQ6t4l1PR7a9Z57qPxjZazqt5dx3UkN/p9v4LtJ5V1CXUNRubSv8AtJkmXwZ8yt/xMfB/Kj/q479m + fr8x7fSvRvilbyWfhrQvFdtaaZLdeAvGul+J1n1G4FrFp2jPq8/hzxtqMF0yBYbu08AeIfFZtQ7Rw3Tk + WN1LDa3U0iecftJEmTwWcKAdQ8H42kn/AJuO/Znx1UH9a2pLlmoavllC27VnbZtu95KT6eiNsXUddUsU + 0lOs6sKvwpupRlFp8sbJKNCrh4JqMVJwk7OXMz0LR/AWleLdL8H63f3usWd34P8AE/jm+04aVqM9jFct + e+KNWiuLfUY4BuvLVlt4nSLcjwzpHc28kV1DBNHofBq3Q/Cf4UfvLg/8W28INkPfLz/wjuj9vPyM5PA6 + Yyf4aqaF4d1vWtH8L32leKrvw/aaR4h8cSatY28LyprVtP4u1GSOIsbyG1gmge0MSzX9jrFr9ivdQjXT + 0vJLTULGx8GoT/wqf4UAXQAPw18IEbPshX/kXdIOB/onc9D1ODjocv8Az/y/r5HH/lv83p8t/n6nol1p + lpe20ltcedLFLFAHRpL/AP56blIYXAZHRgrxSKQ8cgWSNldQwytF8Ptp8+oT3Wo3Go3F7eqFupUuoriO + xtLNIbOzkZLk+d5Tm7u5JAsKPdX91KlvAspStwQttH+l/wDLOD/n05+bp/x6dsdOvvzw2OFix/0sj9/J + xmz4/dc8/ZDkE9D78AdKhwi5xqNe9FNJ3fVNarZ2Tdrp2u2rMtTkoSpp+5O3NFpO9nF6XTau4xbtbm5Y + 3vZW8c8dfs+/Cbx3ca1r+s+FUsfF+saHa6TffEDwhqHiDwD8TG0vT7uy1Wx0yH4l+CdT8P8Ajq20221P + R9KvEsIPEMdk82nWnmwPHEiDhbf4f/Gnwf4g8RWvgL4vR+JtLvfFeheJIfC/xj8PtrFrovhS/TW7fxJ4 + Z8H+LPA0/gvxHa6hNqKWuqW2ueOofiZdxGD7HefaJtak1Ow+mp4WFtN/pR/49G4H2Qkfu5SBgWgJP456 + +nODrUDWep6JrAu8Kl/Jol3IVtX8uz1wQLCyIlsCZX1y00WAPtdIoJrhnQLmWLixGBw3MsRGDoVY1FKp + Vw054edSMnOMvbSouHtoQdWdblre0gppz5eezPosDxPnVLDrLq2KjmWAjS5MPgM5w+HznB4Xk+qy5cvo + 5lTxP9mVa9PBYfByr5Y8JiXh4Qw6reyioHi0Xxm8R+HbjTbX4t/CLxx4MlvL/wAU6cuveDJdU+LngW00 + 3RoNFvbLxFq+u+F7C28Q+HdH1uC6uo7e58TeDdFi0+80fU4tWksrd9IvNU7XTPiJ8Ovij4Ps/EHw98aa + B448Oa1qWiW0d/4d1z+2LO6sbrxXF4d1WCYWl5K0TQ3VjrWkajbTpHNZ32n6np93HDdWN3DD6e0TedEP + tZP+h3OT/omG+eyxk/ZMDPJA5JGcHGQfDvib8Cfhd4+8T+G9c8Q+GNPbxgyap4ci+IOgSv4P+Jek+Gbr + Q9ZuLvTdC+JPhH+w/Hfh+wk1Oe2maPRPENiq3kwmAEzl2zr08fSpSUK9LFxly0+XFRVCreo6dNSeIw1O + VK0W5y5Pqa5uaEXVgoSlPpw+J4Vx9am8XluPyCrByrSr5JWebYDlofWq/so5PnOLpY5TqJ4al9ZfE040 + Y4epP6liZ4hex9sbTrS9sbu0ufOltrqPVLe4hM19tkgmuJ4pI2K3CkCSN2U4IIz13DNfPf7QEQivPCe0 + yMD/AGDkyPO3T4+/s74/10j4PuuMjr2w1vht8a/BsV9N8M/jOfE9kmnaPp2j+CvjbpFj4k0/T/7EksdO + 1K4h+IHhmx0T4hXN/wCIrCxur691PxleePrhPEOp3Woxp/ZgttFtk+Pyut54T3yGRj/YOf8AU4GPj7+z + tnHlQxd8/eycAdOc9tGpObl7TD1KE42XvulJVI800nTnSqT5o6OSU1Tmozi5U4uTS8XMcDhsGqEsJnGB + zWhXc3H6rDH0a+GkqWGqyp4zDY7CYV0qy9uqMpYaeLwlSth8RHD4vEUqUa0/S/D3gfwt4p0jwzq+vaNb + anqPhbxD42vdAuJ2nV7C5v8AxBrljesgimjjlS8sme0uIbmOaCW3kkjeNldw1f4WvYaZ8HPhrqN1bRLb + WHwn8PX1ywijdxBa+GtHnlcAqNzBEbCZ+ZuM12fw/wCfCkQwTnVvFnCnDH/iqtb4U5XBPY7hg85HWvJP + D86p8C/hNp4B3614D8DaX5UjER3Fs2jaJe6tbyfMcpPollqcW0jbIWETFQ5YXVm4U5y6xi+W+3Na0V85 + WR5sUnJJ6Jtcz/urVv5K7OA8WeE7DW/C2m2mt2cS3MOqaBqV1d2rJDPZaxcaii3mvWd2kYe11DSrzULn + XrG/UAWuoWkF2wEcbqdTwf4P/wCEfTU7rUtSk8S63rWqS3F/rN7p+l2Ej2tmJbTSrCG0022t7WG3sbRd + 0m1D9p1G51C+UW8V3HZWvUahZLqOnXunv50a39hLZtIrZKLcxSQlwPMxlA5bnrjHINRaNdtqGl6bfvBJ + C97Ct08IkJ8l7hHleIkuCTEzlDkZyMkZryoUoU61uXV0oOLd226V6c2/NRnSSe6TaW5u8RWeHdLntTlU + m5QtH7Xs5pRdueMXOmpTjFqM3ClKSk6cOXM162t5U0eya0hVL3WtNy4WPcp0tbnX0ACr8yyy6RHbyZIH + lzu2cgA8rocFnoXxJ8Y+HzDceX4qtNM+IGlR3cayWLXNvZ2vhHxXZ6LJgx21vpv9m+EdW1LT9kYGp+MJ + dTSS5l1O7W06+cedr1uqK+3TtGkkuFd2+WTVr+1jspI1LspYR6RqccjZDIsqqu5ZZMcv8QZV0K88H+NW + vbiwtfD/AImtdI1xcCW2vvD/AI2Fv4Zlhu2ZpP7PttP8RXfhnxLcaqiobS10CeK6uLXSbvU50LJyqVbX + 5KsVe3/LuEIqf/guU6rkn1i1o1pph/fl9WS5niKEopJXbqykq1GEUlK8qk6NKns/dqySWt30Wm20Fvqm + sacbWHaqjVbaIRReXHa6qkYlG4JkySaxZaxcyK24qtxGVcI6pHneNb9LGHwjo6HTrYeIfid4AjWG6s0u + zd/8I1rdr47vLayh2FVv5dK8J6gYrp8CyjSa9yHtkZbup2VvZa/pfiRY7gSvYP4cviLq58v7DqF5bPYS + m0W4NvJNb6ubeBJzF5kNtqN87yeSrAYfiyVpvHXwq0uG7NvNFr/ifxNPZm3NzLf6ZpPgXW/Ds6rMSy6f + Fbal4y0eeW8DRyvIILBWMd9MjODnCM4P3XGqoxcXdyp1ai5XblSS96UFG7V4O7to6w6i8RSqxlJuFGrX + 1ja1XC0KlS2jnzJOkpuTSumnZfEfUP8AZmheIdEvLC/0rStZ0fV7XWbG/sL+ztbyw1HT7yae2u7G+srm + GW3uba4t5JLa6tLiN4pYneKZGRmU/O37SEMcMng0RwRwj+0fBwPloq5x+0d+zRjO0D1JAPTJx3ruNK8T + zeH1mWLT9S1uWddWkt9B0swzapqE0E7krp0dxd2tskpJjikuLy7s9Oh8xJNQvbWBftEfCftFSNMngaZ7 + ae0eW88FyPbXLRma3d/2i/2ZmaGXypp4fNiYlHMUskRYHy5JEwx9WjVjUqcq+OMoc6s7Ru9FzWtfra/M + lq1qm+Nqfs4yb9xylyrmXxWjeXJe6TXKuflSlaybcWl63ocPiufwboq+ErzSbKdfGutyaw+rQT3CS+Hk + 8Za8dVgsY4MMdRmj2La+ZLbx53Zurc7ZBH8Go7wfCf4UjzEU/wDCtvCOA0UhOP8AhHdIzz9tJzyCeTj3 + qbQdQ8Qad4K0t/Dvh9PENzdeMtYsb2CTU7XS49O0m78c6xFqmtSS3Qf7Qml2ZlufsVtFPeXTBY7eCZ/3 + bVvgyLgfCb4UgQwcfDbwhjMhHH/CO6Rg8WQGem0YHHp3vv6/otvL9b9bkf1/X9foenCO82j97F/q7fJ8 + mXpv46XmPx9umBTY47zccSx8TyDmCTP+q5BH2z/IHU0g+07R+4t/9XAT++P9/g/8eXXrn2zz1pI/tG7i + C3/10g/1pH/LIZ4+xcYPA460ANnS7+zTEyRY+yMR+5l/uS/9PnT8PwxUGq6Zc6pp97p7zrGLtJ4BNFDI + JbeWSBhHcwH7Ydk9u+2aFxho5UV1YMualm+0fZ5v3EAH2RiP3p/uS45+x8fUnGMcirA+0bv9Rb/64/8A + LU8fu+R/x5dP844pSSlFxkrqSaa8mNScWpRbUotSi1umndP5NddO5haPeXupWWn3MxhiujYXkN9AsUpW + 3v7S4trTUbVGN2C62t/BcQeYPlcRh0LoyvUVyl1N4ssQssbGx0TVDcEQyfun1O+0QWOVN4DmZdL1DawJ + wIJASpK5zkuG0TW9Rt7qJIrLUYH1aykH2iSFLiY2ttqVnEkGnSJF5c1rDqUhcq1xcavcyYLrM729Jllv + 9c17UoYoja/ZtD0pGkNxFvmsf7Uv5pYhLYIZISmsW8O5FKefBcJuZlYDk5+dUqLknUVVRqK65v3N5+0a + etqkqcXore+ltv1cvI61WMeWDouVPS8V7fkg6altKVOFWcXa7UqcnpynRQJd+VJiWL79/wD8sZOgvJsj + /j99fr+PU/Of7QKzLeeEhK6vn+wSNqOmMfH39ncZ+aeYHPsFxjvnj6Kg+0eVJ+4t+Hv/APlsc4+1zetl + 1GOAcY9ug+dP2gPN+2eE/MSNP+QFjy3Lf819/Z2zn9xDj825zXYch6bovhlPE3hHQo5dY1/R00fxnruu + 58P6lJpk2omw8UeIVGl6hLDG88+lXYnb7Xa27288jJC0VzC6Bq5j4deEdO8QfDT4J3V1da1FJpHw10Ge + 0ig1C+S0a5vfDOiWpnurQuUuXgheVLVso1uLi4EbL5jV6d8Pv+RVi5I/4m/ivlRlh/xVWt8gYbJHYbTk + 8YPSud+DhP8Awqz4T/NJn/hWXhX/AJZHPOg6HwBs5x68jpk81M4RqR5ZxUo3jKzV1eElOL9YyipLzSKj + KUXeLs2pR+U4uEl84ya+ehg6n4euNKKmYXUluRDsuIp70xkM2AGHmZic9NjEZOQhbGa8/wDDUE9nJqul + ag2JI9e1rUtNa2n1ICfRdV1K9vbdpPNl2/a7S5nubK7ihPlxLHaS7Uju4A31MyrIixybpEaOEMjwbkYF + sEMDGQw9jkHj3ryzxT4Nb7ONa0HzPt+mXF/dx2BTAu4N0xvNOilIGBewoPKilfyY7+Kyun3i1SJuLEUH + HlrQcn7K/NH+anJx51ZfE1yqUVb4opa3Lpy0lTajapy2k1rGUW+Vp9L3cZf3W3ukeaWEMU9/4gu2NzuS + 503TIJRPd7Hs7GzgufLB80qxg1PU9UjZuqyb4mAaEirXiHQLLxFoet+H7uS8S11zTNR0i4dZJ5WS31LT + ZbOWRYrnzbd3SOYskc8UsLkASo6bgdXwZoOpat4Y0zVYYpoLXW4R4gg+3QSWUsMPiC9n1mK3ltZoVvIp + bZL5YJEnt4pt8Tb4omLRp6Pb+Cxu3XeoTE+aAY7a2Ix+5HAlkQ/rDnnn2zoU5VKUHy3jVTqN7JxrN1NN + rpqejWjWw5udKv1hUozjG+qcZ0bRv3TUoX2Tv0Wx8+eC7s+LfBOlS63cRXmqTaPqegeKjpVxqMennxNo + tzL4b8XW1krXMtzb21v4g07VbWOG4lN5aiIQ3Wy6jkC4WiPfeLPi7p2gabqc82teDvAet2/iyx8m4axs + LnxZr3h5NH8QardJLHLaSXVr4I1m70Dw/BNFPrFlqj3E/wBktLRdRtfVl03RPhp8QpotR0+O38IfEye1 + n0/XJI2ez074kyw2GjS6LrqEJBpo8a2lno58L6iIRpup+KbTVdC1C4svE/iTwlZeK+h+G8Om6l45+K3j + LR3i/s+913R/A0T2Olw2tne3Xw70+9s9bvjeRW6yatqFn4m1nXfCWo3LTSx2UnhJNFRYptLulKeFnKVB + e0UeVqFZK7m4QXOpJ6JS5407S95RVSVve5behaEPrmJUH7KdB1sLp+7jUxNWnRqUG1o3TpVMRDl92Unh + 1O3Jc63wb4L0jwppr29rNrGoXs0upPfazql/e3erag39o3UsYuLoFAsFuZnjtLKBIrOzjOy3hTMhfw39 + pCNEl8HFTMSdS8H582W4kGB+0f8As0YwJnYDr1UZxgE9K+orcnym+eQfvNR6RFv+XyTvsIPqcdDxx0r5 + g/aTJ83wbyzf8THwf95Nv/Nx37M/bav+cfj6dCnCl7KnTiowg4xjFdEmkvNvu2229W2zy5zlUlKc25Tn + JylJ9ZN3b0sld9Eklskke9/DwE+FIgOCdZ8XAHkYz4t1znIIP5EH0NeXaPp3xB+H0fw0+HKeKPDupxHQ + ZfDen6unw28QPbwJ4X0ezFvLrNwPirGltLfWdowjEMchuLtGEcCQo7Q4tl8ONY8Sx3Gs6ZfeINLtLnVN + aiS0074y/E7w5a+bZ61qFndXKaLoTR6TYNe3UE95JFZrsMk7O7PKzubf/CmvExIJ17xaSOh/4aA+MmR9 + P3vFP/NfdfX71p5Enqa6P8UQqg+MvAZIjtlbHw78SgFo3JnIB+KpIV14iUkmNssxkB2jnfD158RPEFxr + 8Vr4p8HQf8I74ku9Du2n+H2ulbmWHTrG7M1o0Hxam/dj7fFGxuBDMJYbhGtlQxStx/8AwpvxP/0H/F3/ + AIkB8ZP/AI7Sf8Kb8TL/AMx/xaM/9XAfGQZ/8i+/60f5fjda/ddW8/IDsfFknxM8M+Ftd12bxF4Y1YaT + otxc/wBm6H8KvGGrarfTwQTN9nsNNsfidc3V1LcuY4oYY4z5eWkmlESvInRrpPxOJVx4w8C7TN5mP+Fe + +JN3lNDt27v+FqY3+Yd27bjy/wB3jd+8rys/BzxN38QeLce/7QPxk/8AjtA+Dfiftr/i38P2gfjJ/wDH + aAOmuL34jxeNNM8HHxF4V+23/hLXdeTVB8MPFP8AY6rpmqeHdOeza/8A+FpGIXsj6olwtgZPPa1iecZR + WdOuOkfE5fMYeL/Au0urgD4e+JAfLWMBlJ/4WpjeXDMH4UKwUrlSzeV/8Ka8TE5/t7xaT/2cB8ZM/wDo + 2l/4U34n/wCg/wCLv/EgPjJ/8doD+vyv971Oo8H3nxJ8V6Ncapa+I/CenJHrfjLRBb6p8NfElvcmfQfF + WraF9r8gfFbP2S7fTXvLdiwe4tLi3l/dMzLXF/GTwz4oXRrHxL4i8Q6Dqaadrvw50OystF8MalojBtc+ + N3wlv7m6ubrUPF/iQTrEPDlvFBBDbWhBuJpJJZAI0W2Pgz4mHTXvFo+nx/8AjIP5S1y3jD4czeGdLsNa + 8UXXinWtJtfFvgOL7DP8aPihr8H9qX/jjw9p+g3s2ja1cJpeow6Xr11pupy294WjZLMkRyyKkbn9f1/X + zYHuHhmw1i/8JaUNF1s6HNbeKPEd1cubC31CLULOLxTrwl0y4inaN4oLlmjaS4tJre8QR7YZ497GuA0i + w+Jvw/Pw1+HUfi3wjqUS+G7vw9Yaunwn8QtBBF4V0vTPIl1mRPi8iWr31nblUeKN0mvgY4440YmPMsvh + vrPiSO41jTb7xDpdpdaprSJaaf8AGb4n+HbXzLTWb+zublNG0No9KsDe3ME15JDZr5fmXDuzPK0jtbPw + a8TdTr3i36n9oD4yfz836Ua9Py/4K/roH9fiv+GPTRpPxd2p/wAVt8OOEtgf+LX+J+TG+6Ygf8Le4DqA + Ixk+W2WYyDC1znhy9+KHiFtYS28XeAIT4e8T6tol4Z/hlrrpcTWyiYyWjW/xjlIixfQI32lIZlmiuIjb + 7RHO/Kj4OeJu3iDxb+H7QPxk/wDjtA+DXiYcjX/FvuR+0B8ZP6S0f187rX+u/kH5/wBXOs8Uz/Ffwt4b + 1bX7nxN4O1WLSrKO7k07QPg74x1bV7xreTfLFp+m2XxZnubueYsqwRKgSLDSXNxFbiW4h6IaX8WyS6+N + vhwVabzB/wAWw8TZ8sQBAuf+Fu4LmUb9+NvlnYF3fPXmB+DniXv4g8Wfj+0D8ZP6y0o+Dnibt4g8W/h+ + 0D8ZP6S0AamsReP9X8Q/8K31vVvh/q0Ws+B9V1G9bUvgt4lv/Cd9p63+n6Ne6TeSXXxZlsbqef7eHn0e + fe8lhIHkVonyet0zwv8AEnQ7Cx0nRfEvwr0jRdKt7ax0zSdM+Euv2Nhp2mWVklpZ2FjZ2vxZitbS2tEj + SO3gt4Y7eC1jjt4okVAR59/wprxLnJ17xbn1/wCGgPjJnj383tR/wpzxN/0MHi31/wCTgfjJ+f8AraVt + b2V9r21t2K5pcvJzS5OZS5Lvl5uXl5rbc1rq9r2dtjo/Bt98VvFehf2xa+J/BOmxvqfizTltdW+E/ie2 + vEl0nxNqmj+fLB/wt8lYZ3097mIZzNbzQyBo84PA/G/wz4vXw9p/iTxT4k8OaquneMPhNomn2fh/wlqf + h0qNd+P3wXvbq5vLjUfGfigXBi/4Rq3jgightMfaZmkkk2oo2x8GvEw6a94tH0/aA+Mg/lLXHeOvh7J4 + V0bT9c8VT+KNd0m28Z/Dq2SwufjN8TvEVuutap8QPDOleGdRm0XXbhNJ1CLR/El7pOryQ3hKBbEyJHLK + kcb3D4of4o/mv6/Vk/1/kvl3672Wx9I/DtlXwrDuIH/E68Wnkgf8zbrnrS/8LN+Gw4/4WD4HyDg/8VZo + PBHBH/H/ANRXn2jeCr7xHaeEtdtvGfi3w3D4a1jx8bjR/D97b2+meIje+NLmaNNftLy2vre9hsl0+RbY + LapdR/bLhI7tLee6trr5w174n/Hn4Z+E/wBkib4cfDzwd4y+F3iHwhpuifGDxV4t8dt4NvfAVzeeD/Dt + r8Nm0q2tfCXiG61O38V+MLqPw7ez2+kanNY3VzpcctlaWV9c6zpkNtciUZzlUrUaEI04SqScq9WnRptq + KfLBTqXqzlanRpRnWqTjTjKUbjGLhi6tSvhcNQwWXZjmeIr4zFUMHRjhsrwGKzHFQjUxFSnGrip4fCTh + gsHSc8VmOMqYfL8DRxGNxFCjU+0P+FnfDb/ooXgf/wAKzQf/AJPr5o/aMgv/AImWegf8Ko/aR8L/AA01 + XRrTxQXu7f4h2tlp1/qGpWmnR6IdZ0zTHmfWLXT57S5mtP8AT9NOl6lPaajeQ+KvD0OveBPFW7/wuH4m + BwB4K8D+XvjUufipq4kES3UAMgj/AOFKlS5smuZxF5qqbmGC087yrmS9tKVx8Zfi1FZXMtr4B8ATagsE + s9vat8XNYS3lvPsunlLZ7o/A4MkLXUuqxfaTAGMNlp05gRtUuoNG9qhlma4arCvTwsXOm24+0+rVoaxc + HelOU4z92bsnGWrTSbR8CvEvgedorPqXvtRu8JmEI+84pNzlhFGKTkm5SajGzbaSuebPY/F2bwP8S/CV + 7+1z8Nby/wDE9roml+APEo1rQtM1v4e2tppl1FrmtHU9AtNHvPEOv6xrK2+owfbJYLLTLC8TSUW6k0K4 + 1PxdN5vx3mmuL1/2wvhNYyXl0k7aRbQfDm70fSrebxHqN1eWGkTXHhWDWZYrXw5caJp2i3WsXupXEU+h + 64urHVp/Gml6t8ObPwy+Of7SutfDjw9f/FX4TfC7wt8Rr3Sbn/hJfD2j/GPVLvSNN1JZdYjtIoLq3+Ee + uxeXcQRaHLcLBqurJZNqOpJHe6idJt/7X9IPxj+JfmNt8FeCDH5zlSfinqwdohLfRxsyD4LELI1tHps7 + xh3WOe6vrZZJI9Pt7vU9aVLOa1KFVZfhlGv7PExjWy/L6VSHtKdL3Z0a1ONShJxjD21GcYSVTn9rD2kq + nN05hx7wVl2PxuXVuI8DXrYDFYnA1a+XSxGZYCrUwteVGdTBZjl9HEYDH4Wc4OeFxuCxFfCYmjKNfDVq + lKpCo1+CHiXxh4ah8Qj44ftG/Cf4iTXieHP+EeOhXHhTQBpElrpAh8SNdPZrpi3o1TViLi23237hIZJo + hZw3qaTpnvH/AAs74bf9FC8D/wDhWaD/APJ9fP4+L/xPaaFn8FeBVQR+TKU+KusO6rNLpHnPGp+CcSyG + GP8Ath4o2aITvZ6cjyW66pdPozv+FyfFLyy3/CDeA/OKK/l/8LY1gxCb7HAzRCY/A/cYhfG4gWfyFc2k + cN4bdZp3sYMauVZpWqOpLBwjKXLeNL6tRpq0YxXLTpzjCN9G7JXbcndtt8i8S+Boqyz2Fl1eDzST6dZY + Nvqj37/hZ3w2/wCiheB//Cs0H/5PrzP4w+LfCviLwDLb+H/E3h/XJ7fx18Hpp4NH1nTtTmghb4v+BkEs + 0VlczvHGXIQO6qpYhQcnFct+y18SPi78T/h5rmq/Gzwj4c+HnxB0Tx54z8OX3hjwX4iuPFujW+lW17Bq + fhm9XW9Q8M6Mbq51Pw5q2l38r2sElvNFPDdSR6RfXN74b0V37QKMt74TLSyS5/sHHmLGMf8AF/v2dycF + LeE856Et07V40XJpOVOrSk0m6delOjWg39mpSqRjUpzW0oTjGUXo0mfoNWMKdSpClisDjqcJyjDGZZjs + LmeX4mMW0q+CzDA1a+DxuGqL3qOJw1arRqwanTnKLTPdfh4f+KXgHf8AtjxVx/3Net1E/wATfhsyMB8Q + fAxyDwfFmg4PH/X+e+O1cFofgi+19PCviS38beLvDsPh3UvHqS6HoF7BFpGvtqHifVI1OvWF5bX1pfpY + iJprLFqt1DclSl0LV7yzvP5nP2lP2sb2x8G+GfhxrWmeMvC/7RPha30a08FXmhT+ILLxdfWt1b2w8B3P + gOPTJI72aw1LTTpj6A3h+ENqPmeZIs2ozXW76vhDhTGcX5jPAYWoqDpRU6s1BVp06U24rESpe1oS+rwn + aNepGcpUFKMuSXNFPkxFZUI8zTktNtNbu8f8VldbJt2voz9n/D/gr4zeG7/UYtP/AG0fCX/CN6v8W/F/ + xM1LT9Q8b2ninXP7B1fxJ4U1Hw18LtG8SeN4PFB8O+EfDuh+G9Y0of2LpFlb3R8a3CzaNKvh2Sbxb0+j + j9oW2uPB0+q/tlfC/UP7E1bwvJ4stYpvhZa6f420ez1bx/feK4Z4ovhpHqWhXWs2GqfDzRtPGjazALC0 + 8Mavc/av7S1dr1vq/wCB8/xBv/gv8Ib74rvc2XxRvfhf8Prr4kWYt7CL7L47uPDWly+Lrdore0NtC8Gu + vqEbxW5METqUhLRqhPn37Uvj7xj8LfhFf+M/CWg+KvF0Wma5Gvi3T/CdvcT+JbPwhcf2lDqOraRDo9od + XaSwvG0yS9m0wfa7DSmv9SV4IrOW4i5YVsbisyeWpZTWr18WsHGs8Fl7o1JqcqEZ08TKhG8Kl0o1OZc8 + FS19ym404wUXO00rc1lKTa62sn0bvZaXV9DzW2uPix/wk+vz61+1R8Ltd8E6tqHiz7B4dg1Hwf4ZutJ0 + HU/Dvi2x8PaXa6romgjxBDfab4gv/CWqDW4/Ewv7Gy0e+t2bWLudbubhND0T9obStDsNOT9uD4bQS6Lo + UWm2cN4vw+8WNq13Fr8l0k+peI9a8N2viGKW28KWmm+GrbVNRl8U6pealfaz4s8Qya9fLaWbeG/sIftR + eObnwx8b/Fvx+8Q+OPD/AMHoPFXh7/hSmsfEnTdevvFuq25i1qTx8mnf2hpd/wCLdd8I6FcDwzDZazPF + d6ba6neavpVrqLGzezsf1b8DeOvBfxM8OWXjH4f+NNP8X+F9SmlWy1vQbqwv7GWS2/cXdq8kNqWgvbK5 + jltr2xuVivLK5jkt7qCGeN0HZnmBzXIMXicFicPgK9LDTwtCWLoZbhp4CVf6usRGkqrwyo/XKcMROli4 + a1o1aU6c5SdCMozTcK0Y1E5xu3JRcmpL4YO6u/dfs4vl+Fv3rXk2fCl5p37SZvNSvrT9tv4XrcX2m6XY + 2scZ+G1rp+mNp3jPXdQlvI9NvPAevw3N9qfg3UbHSry4SWxzqVlb74riGyhup9vyvj9c+IBd6j+2P8K3 + 8Ov498P+IG0XSJ/AWi/ZvBek+MdZ16/8G21z/wAIlf6tLPrHh8eGPC11rN/rdzutLXXpm09p9Vie2++W + ibehN5c/8ecxJ8u2zuzD/wBOnT8PSpzE24gXl194YzHbY/1Z7/Y+Ocfzwea8R5nXa1oZfdJpSWW4FSSa + S0aoK3Lyrl5bcu6s229PZqzV52b/AJ533vu5dXv3Wj00OZX4m/DYAD/hYXgfp/0Nmg//ACfXk/xw8WeF + fEXw68jw/wCJfD+uz2/xJ+BUtxDo+s6dqcsETfHL4doss0dlczvFGzkKruFUt8oOeK7b4Y3nxH1Pw/eX + XxO0nS/C+vHX/E0dlpfh7U4tbthoMOqSR6Rc3V4+nxqL+5hDyyxxbkMRt5pI7K6ln02z8i/aQQrN4OYz + Sy51HweP3qRLj/jI/wDZoPHlwxE5PruA7Yyc8kqbpV3TlKEnCpyuVKpCrTbUrXhUpylCcX0lCTi1qmUn + otGvJq34Hd6VpHxD1C08G3fhLxZY+HvD2na548k8Wadd6XZao+vI/jO7axtkW4svtNtHFDDqSSzWWs6X + IDdRlluNimJ/w30Sx8S/AzwB4e1mCw1HRNe+EWgaPq2n3Noz297pup+E9Nsr6zmVNQG6K4trieB9rAhH + O055E2kXvj200vwdH4T0jQ9T0S68T+OIfGEuqXs9leabYf8ACVaq1neaWYpCtw5lE8N1A9rcOI3jnhBa + Fra70vg083/Cp/hRiOIj/hWvhHrPPn/kXdI6hrTdnsc85BzjjOSbVmtGnpbfS2vf080xOMZKUZJSjJWl + GVpRcWrOLTutdbxfR67n5zXfxFsPBnxI8T/AjXvGenan8R/AtjaarLZXOraK3ibXvAmpeSfDPju90nTJ + Ynt/7St7m1sNfkGlaRaQeKYtQSx0630a70Oe93v+E7H/AD8j/v5/9evqn45/szeDfimmpeNdE8PeFvC/ + xtj0XT9P0f4oWunR22v6lY6XNPcaf4Q8ZarZaX/aXiPwRNJcXUD6PqL30eiSX8uueHorHXrazvY/xZ8O + /HHRvEviP4leD7Se8tPFPwi8fa78MviDomoWsttNofjHw5ObfVLCK6YNY6taLIrNaarpN1e6dfQ7Z7a4 + kidGb9ByDNaWPpww2Mr4anmUqlWNKhzKFTFUaalNVKUKknKrUhRjz4n2ekJXlyxptM/j3xa8PsbwnjMV + nfDmV51ieDKeGwFfHZnOk8VhsjzDGTo4athMdiMJhlSwGBrZlV+r5JLGy9piaUqVCVavi41VL62+LniL + 4k+IPh14m0f4P+O9H+H3xIvba0Twx4w17Q4fFOlaLcR6nZT30lzodxIILtrvSor/AE+2kmS5isbu7g1C + Sxv0tGsrjvbDxvdxWNnFqOpwXuoRWtvHfXltCbG3u7xIUW5uYLJrq8azhnnDyxWrXd01ujrEbicp5rfH + v/CcN/z3H/fa/wCNH/CcN/z3H/fa/wCNfRLL4KtOverz1KVKk4urUdFRpSqTjKGHcvYU6snXkqtaFONW + rGFKFWcoUaap/jc+K6lTLMJlLhl6w+Ex+OzCniIZfgKeaVK2YYfLMNVo4rN4YWOZ4vAUYZbQngcuxOLq + 4HL8RiMxxOCw9GvmWPqYn7M/4Tsf8/I/7+f/AF6P+E7H/PyP+/n/ANevjP8A4Thv+e4/77X/ABo/4Thv + +e4/77X/ABrX6r5fgvLy8/w9bcH9tLT3+32v8P8Ad8/61v8Aod8CfiAunfF0aP8Aa4Y9P+JWh3GnNG1v + JOreMvCltc6vpEyeVqFtFby6p4TXxNb6nez2VxJdp4Z8L6eb62Wzs7W69v8A2gBKL3wn5jxP/wAgHHlx + GMj/AIv7+zvnObmfIxjHC8569vxk8SeP/Gtpp0V78NtMs/EnxNsNW0C9+GPh691Cx022174k22uafL4C + 0KTUNQjksbQa54rXSdIMt21vb7b4pPfWETtewfrX4+1Hxtq/g/4P6n8R/D2meE/HuoeFvAV9418M6LrL + +INI8O+Lbr40fs2T+ItD0zWmtbQatYaVqz3djZ6msYW+ggS5A2yAn844poU8NmdNQUlLE4ZYif7ufs1K + E3R/i8vs+eaipez5vaK0p8vLJM/s/wABM3xWdcDYmVaeHlRyXOqmV4dvG4aWLlSxGHjmEV9R9t9eWHoy + qVYfW3Q+qc0oUI1faxlBfUvw+/5FSLkr/wATfxX8wxlf+Kq1vkZBGR15BHqD0rkPhFpumz/Db4PX9xZ2 + s99Z/DHwytpfS2sEl1aLNoGhrKLed4mlhWVeJBE67gMNkVU0bTvHd1YeD7vwr4h0jSdEsvEfjlvFthql + i93JqljLr2uJYfYJY1WS3uLO/CXEw+1W0dzaGa3MkUrRXMGj8HDcf8Ks+E+bi0/5Jl4VHNtJjH9g6H8p + /wBL5OMc8DrxXzybV2m03daO101Z3t0d2muquftH/D/156X+4+boP27fhxJ8c/hx8GxZG6tfile32heE + /Fml6za6iY/EOmW2o3q6d4i8P/2fbXWjw36aTdQWt5b32pvFdyWSahaWUEt1cWP3DCeE+dv+Pq76hf79 + x0+Un+ff0zXwd4n+CP7JvwA+K5/aEsfhTb3/AMcdZbWtT0aLwyviHXNXN5qsMsPiXWvDnhLVPFaeCPCV + xf293c2+seJLPT9BkuE1K+tDfTTardW915laf8FS/hB4f8bWHg34veFfGfwgtNR1M2tp408Q2Gmap4Ps + prqaSOD/AISO90nW31DQrd5J0V9QbS7vSbFN9zqeo2NpE84+wxGQrOY4etwjk2cVsPQy+Dx/1j2VSviM + ZGpWlXqYTC08RXq1aEKfs6PNQjapUpVJKhR+A51WVNtV6tNScvdtdJRdklJtJKTb2drJrV7njn/BQjxf + +0Z8J/HPiDXfCvwt8c/FP4VfEXwf4f0qO/8AAvhbVfGdx4X1jRlvre50PWdL0Gx1DUtLtbqe5XV9O1Oa + 1j0q8udWubOO5+3QSwnpP+CPvwh+OHw7+F/xe8Z/F/w14g+HVl8W/iXZ+J/BHw38T2k+l6/o+m6foEOl + 6h4m1fw/eKl14evfFMy2tsul6jb2eqmx8OWF7eWscN3Z5/W9bg3VnHcQXthcQXEVpNDNDE0kM0Mjh4po + pVvGSSN0YOjruV42BViCDVrdOGb/AEm0H74f8u0mD+5XGP8ATOnr75q6/GVSpwp/qvTynAYd1JYNYzM4 + e1+s4mjl8oyw0PYyfsqNdShTjXxELyrU6fKoU3UquYsOlXVfnk7c3LTaXKnL4td2t2ovZ9baJzMN6fM3 + /HjN0C+sHA+XGP8ADrVjP7w/vHxvH8Kf88j/ALPr7d6oMZ/MTFza/wDHnMAfs8mOsHy/8fnX3zj2qffP + vP8ApVp98f8ALtJ/zyP/AE+V8WdBh6v4l8PeFNIn1nxP4g0nw3pEEuoCfVNc1Kw0nToWe8l2CW91GW3t + 42cj5Q8gLEEDPQfMPx08SeHvFmn+A9e8La/pHibRL7UPCTWWsaDqdjq+lXaJ+0j+zVE7WuoabLcWdwqS + I0btFM4V1ZThgQPj/wD4KKfHbxL+z/r2ieJfFnhhtd+DPiDwXqnhyHxA+lNfaN4W8cv4l1afUo9TnYXM + GiXmu6O+gJo93dPbnUU07U7S0Z2tbtH/ADy/4J1XnxF8Vax8ZviOmk65ovwD8Y+Jfg03w9/tGG5tNC8Q + +M7D9pD4Hx+Mdd8IWtxGiT2sOmP4b0vW9asgLHUbq30/TkuLy60K7i0772lwTUfB9fi6eOpU6VGeF9hT + fs5U8XKtjYYOrg6c1VVWGOw7l9YlSlSkpUadV2jGKqnM8R/tEaCg22m5PW8bK6k1a3I9lK61dnrof0Va + J4m1fQtI8K6fYeFr/XrTXfEXji1vtQsnnC6K0Pi7UTA9yqWE9qkVxDNeTC51LUNHsozYG2+2Nd3dpBJb + +DUkg+E3woHksf8Ai2vhA5Vrbbj/AIR3SDx/prdiMc9c4JxxJonivTfCfg3RZtTjvpV1rxtrfh2zXT7O + S9lGoav4y16G1aWGHMi2ysrNNKiSMij5IpHKozPgzNj4T/CgMk24/DXwif8Aj3uj/wAy7pHORbL6jJx3 + GQDyfgk9/J29NE7fjf5nT1+S0+b1+e3bTQ9JEkm0fuH+5B3tem88/wDH514/xr5M/ah/Zj0j4+6A2p6Q + kPh74q6Da3UHhXxQ7rDaahACbtfC/i1LSed77w5c3Jke2uvsl7qfhi7urvUtBBS/1zS9c+tRN8o+Sf8A + 1cH/AC73WPvdf+Pf2POfy7JHMA3CT/6+T/l2uv8Ann/179R34HfIrbD4itha1PEUJunVpSUoTjumu/Rp + q6lF6STaaaZ5ub5Rl2fZbjMozbC0sZl+Ooyo4jD1Y3jKLs1KL+KnVpyUalKrBqpSqRjOElKKZ/J94k1H + xN4L17VfCfjPRdS8L+KtBu3sNb0DVRCl7p14mCYzJbz3Fle2s0bLcafqumXd9pGr2MlvqWkX99p11b3U + vE6t8XPD2gTaRb654h0rR59f1OHRdDh1LUbWzk1bV7kE2+m6ck8qG7vZyNsNtDvlkcoiKzuit/QX+21+ + x1oH7THhH/hIdAK+G/jN4S0qb/hFPEpgvIbHxBp6LcXL+CvGCx2cgutEu7g/adK1UQtqvhXVS13pkx0r + UvEuieIP5UfiDp1/4Z8WXfg74p+CRo/jb4feISt1oPi3SLKXVvCviXTsGK9sWnS6iin8mWO80jX9GuZr + LVNLurTV9E1O+0m/sr24/XsmzhZ1g2sM8PSzKl7P21Cv7R0uT2kFUq01TkpyhOnz8mv7uq4xm5Rs5f52 + +JXh5Pwx4lpTzv8AtfH8D5i8Z/ZuaZV9XWPjiPqlaeEy7FzxNOWEo4qhi1hpV+eEVjcujXrYTkrqdOh9 + ff8ACb/9NT/30P8AGj/hN/8Apqf++h/8VXxp/wAJ6P8Anqv/AH0v+FH/AAnjH5Y/NnkbiOC2je4uZnPC + xW8EEck088jYSKGGN5ZJGWONGdlU/S+xSV3ZWV23zJJJJtt9Et79rdz8Njm9ScowhNynOUYwjG7lKTcV + GMUndtuySWrdu5+6X/BOjwNcfEv4uan8SLyJp/DXwgspPsr+balbvx/4m065sdPtfJlSQSJoHhe51bVr + 9Tc6fdWl7rPhC7tRfQTXIt/1C/aAYte+E8xsmP7COSYjuz8ff2dv+eU0uDwOoWsz9jH4NSfAT9nnwR4J + 1O3kj8XXlldeKfH7oL65U+N/EDR3OsWkc8lnD51roEaWfhfTp1trTz9L0OynntY7qW4zq/tAyB73wkMS + Aj+wvvxzJnPx9/Z25XzY0z05wTX4dnuYPMszxFeLvRjL2OHXRUaV4xa/6+O9R+c2f6o+FXCT4M4HybKa + 8OXMq1BZjnD+08zxsIVK1KTsub6pTVLBRf2oYaMup7n8Ps/8IrDtAJ/tfxXgEkAn/hKtbwCQGIBPUhTj + rg9K5/4Ns/8Awq34THYv/JMvCv8AH2/sLQ+c7P8APrVbRr/xPYeEdA/4RfQbXX5LvxprtlrEd5fx6dFp + 2hz+KfEP27VfNcO07WjLCBawQXM8qysY4JNhFHweW5Pwr+FCi3tf+SZeFT/r3AP/ABIdEGSPshw3I7nv + zXj+fnb/AIPp5+R+i9fu/P8AP1t0PyT/AGgP2p7v4N/tpfFXQPEs0cCnwl4Eh8JC5eNt3hG98J2FxcNa + LIdwtm8WTeKkkwqj7YlyBkDJ/Hb9uL43+FvG1jql0klqxmjuG+VkOSwbpjGcjr14r9dP2h/+CZPxd/az + +MGh3nxT1/wt4N8L+CG8QHRPjB4H1Bj8Rtc0nVlvpdJ0e+0K60AWNwp1G4s7rxDFrNzLb26wXw0C/a4v + hdr8Mr/wSX+APhv4uHwz8Wf2ptY+MdroOiyeIrvwrpGj6N4Q00X39o3lnpGieJ5bbXPFeo3cFx/Zt3c3 + trBLoTzwNaDMltPNEf27gDxF4CyrLoZxxFSzDI83yiGGy2jl1PDVcRXz1YPDUI08RhKqjTwVCVep7SM4 + 4zE0YxnGdWNSVOUW/kKmYYp0sXUxWDng6Sxs8PhlialKnPEcypyUoxnKHuqc6kFJOUJKm5wk4tM/XL9g + H4x674N/4J2fsyav8SdO8ReIPFQ+E6arbaVZGxfXX+Hmn+JtXsvAGpyf23qGlW/2ObwMvhddPMl6Z7u2 + KSW6TRQzyRdj8Qf+Cl3wX8HeFfDPivRrDUPEj+INbt9MuPCks8mj+MILuPV4tB1fRdI0pNO1a017xZpE + stldNoEGp20d9a6toU1nqb2+sWlzX5nW+qfFr41/tCeGPgHo/wAXLHRftXg7XfD/AIK1WTwtYXFhZaP4 + Zspdet/DF7ZeGl8Nxx6TZ6ZZas+kXixXNxZT+Xphjlsri2bTf2a/Zk/ZW8Pfs9fDmx8HX0mmfETxGvjP + UfH2r+Mdb0u3gmk8ZatYafp8+paBp08Opv4dgttL0zTdOtI7fUJ7ryrVpp7uWa5lI/C8DxVR4h4uzXOK + +SSlw7XzDNcRWwNPGU8JOnicRW+tUMJRr0o1qkYUliYqf7lKVFRlTnCfumeTZzmWb4yccLh1SynCxqYW + tia7w8qn1ujHDSUIQpV6lTnlCq5SU17L2bhKM+dtS+qN7lozsAzYy8bz0zByfk6g8Yx796tZk8z/AFa/ + fH/LT/pk3+xWeRceYn+j2uPsUxA89+mYBn/j0Hzf4nnjBsbbjef9FtPvj/lvJj/VEf8APp7dMf4nb8T7 + MiiTzbeSKSGKWJ21NHSQhkdWvJAysjRsrKehDZDDqO1fMP7SQ2v4LQIsarqHg5VVD8qqP2jf2ZwFACqA + AMYA4A4xX0zbi4MTf6NanMmojmd+15IP+fTt0HsOo6D5k/aR8wTeDt8cUf8AxMfB+PKdnz/xkd+zR97M + MWMcf3sknpjmoN80V05k7fNAezeFNa0fQ/Bdpc61qFnpsFz4m8RabbS3syQpPqGo+NNatbK0iLsu+e4n + dURFOQA8jFI43dcr4M3Fv/wqf4UZltgf+Fa+Efl3wgf8i7pGOPPbjsBk4Xoetb/gnTrDUfCNmt/ZWt6L + XxH4mvrVbq3juBb31n4y1qezvIBKknlXdrOiTW1xGvnQSqskTK4Brzz4X+M9P0P4ffDjQdY0bx9p+saV + 4F0HSr+xn+GvxMaWC/0vSNLsb623r4SKymG5iaPzYneGYKJYpJI2R2n/AD/Rfj+lgPbxc2+0fvbf7kH/ + AC0hxneeP9b0/wA5psdxb5/11vxM/wDy0iP/ACz4x+971xy/EfQiikaX8QeYrNsH4WfFQNiWQqFIPg3K + unJmVgGgX55hGhDU2H4keH3chLDx25F3LG+34Y/E9vLcQF/3hTwiQisFwHfapYomd7KpAOwnuLb7NN+9 + t/8Aj0bpJCMfu5en70/XGDxX5q/8FEP2B/Df7W/g2bxX4Im0zwz+0B4TtJD4U15pre103xlp9vG87+B/ + GR37JbS8BceH9d/d33hvVmt5WuZtAm1nSdR+9Lr4k+H0sriWXTvHscaaeZXaT4XfFFFSPypid/m+Dl+Z + FQtLH/rYxjeqlk3XP+FiaFvx/Zvj7m52hh8L/iltObbzPM3DweV8vHyeZny/N/dbvM+SunCYvEYHE0sX + hajpV6MuaE1+MZJ6ShNe7ODvGUW00eJxHw7k/FmTY7IM+wVPH5XmNF0cRQqXTX2qdajUVp0MTQqKNXD1 + 6bjUo1YxnCSaP89zxjc+K/h54r8Q+BfHGjal4X8X+FNUudF8ReHtZt3tNS0rUrQjzILiFjhkkjaO6tLq + FpbO/sZ7bULCe5sbq3uJf0i/4JH/AAZf9ov9q3Qtc1y1+0/D34HwwfEnxO06Xa2N94ht52g+HugTXcMs + EEU9x4lRfE/2K7llt9X0nwhrOmXFldWdzdBP3d/aU/YH/Y3/AGr/AI/+H/jp8a/DXxs1vXtM+GVz4Kk8 + F6L4d+Lvg/wt4ittP1WS+07xJr8fhXwVpPjHUfE+kJrdxptnKfE0dm2nrplrNpk39mW+z0X9kP8AZH/Z + x/Yi17406l8DrX482ei/GTVfBF9f+DPE/hr4seKvDnhCXwXpOsWdsngy61bwNJ4lit9WbxBe3mtya/4i + 8Q7ruO1gsJNPtrQWh+6x/H0sZlVTCUstq0MdiW8NVrqtR+r0sPKheriaevtnKpO+GhR5VKm5+2c5wg7/ + AMq8IfRGp8OcfYHiHHcbZdm/C2S06efYDKp5XmNPOcbnFHNYUsBkOOfsI5bCngsLyZzis0hiJYbG/VJZ + dTwdGpiYun+g9vcW3lv++t/vX/8AHD/z9y/9NB1/L36GvnX9oCWKS88J+W8TEf2Fu8tkbGfj9+zt12O3 + pxnGPfNeq2vxK8PS28skVh48lVX1ZSYvhf8AFGTD29/LHLF+68HsDLvBVIx88pVjGrgHHjPxo1ePxDJo + V7p+m+JobPS5/CNre3ms+EvFnh20judW+PXwIm0+1iufEei6VDdXM8WkalKYLSSeWKO1aSdIleIyfnh/ + Yp9CfD//AJFSLgn/AIm/ivgcE/8AFVa3wDxgnsSQB1JFfNXh/wDaN+E3wr+Gvwii8ca5faRYnwB4V067 + 1xdG1q+0DTbw6HokbR6hrFlaXFrbpBJmO+kDvFprhhqLWvlS7PevDesnRfB+my/2PrmrpeeKPEdhMNCs + 0vZtOhn8U6+0mp3kP2iC5NhbCPE5sI72/LyRLbWNwzEL+DPxB+B/7WWsaF4c+EXhzRdW1TwRqmkQzW3i + DxH4N+KWm3Hg6K8SyfWNP8R6M/gafVLy70K/upLQ3Xhu11q21mKO3v43ge7ltrbyM5xmNwWGVTA4Opi6 + 0pcqjTpSrWlo4KpCE4TVOesZVItqDtzWTuvCz/MMxy/CxqZbgKuOrylyqFOjPEKMnb2aqU6c4VFTqPmU + qqfLStefKmpL+hsiz1rS0MUn2vTdV06Dy7m0uw0N1Y30XyTW1zbzDdHPBMHhnglGVdZIpOjD80PGv/BM + fwn4sbXfEdj8ZfidY/EvUryO00nxvrI0XXItN8O6a+oC08NahoFlF4eh1u133U1zJfyX9jqYuo7c213a + 2rX1pf8A198K9b8L/DX4Y/Df4dJH8UtZTwH4D8E+Dl1a5+DPxfhn1NfDuj2OiLqE8J8GyfZ5roWP2m4t + /Mf7F5gEriMB27m3+KfhdxHs034kSA319GSnwi+LbBHjlu1cOy+C8RhWRkLPtTzCI872RTticvwuZUaS + zDDRnJQvyOcv3U5wXOoThKPvRekaifNFrmhKNzoxmVYLN6FBZpg4VJRp83s3Un+4q1IRVTkqUpQfPBrl + hVi1KNuam4t3PjX9lD/gnz4Y/Zt8Xar8UvEvjvV/iz8TrzS20PTNdv8ARrbw5o3hnR7+4ibUE0TQI9V1 + ydNW1IQR217rF3rN1KLFZLOwt7CC71Fb/wC3/iP430r4beCPFfjvW0mbTPC+m3WrXEUcypJctBaqLezj + d22JLe3TwWsckmESSdWchFYjHl+Kfhhbcu+m/EmJdlm26X4QfF2LHmzEKp8zwUvzg/fiOJIyyiRV3Lu5 + D4l6j8PPip4D8afDfxPpHxUOheNdG1Xwzqcll8Jfi7b3tvb6ppTwm+067bwPLFb3tizJdaffGOaG31G3 + gDLJKhhbsyjAZblrwuGhRdDL44mnLExpOU6rpSqxeImp1JSnUrOnzcsqk5NyUU3ZGuX5ZgsowaweWYeG + Goxc5xhzVKjlVnvUq1Ks51as5NLmnUnKXKlG9oxS/M39p79s/wCP/wAHrbSviN4L8efD3xJpJsoNQvPh + /ceF420J7SVYpp9KbWkuYvFIukiUwjU4dVji+1L9pXTjAfsVfo1+zl+1D8O/2jvDHhfVvDktxpHi3Wvh + 54N+I2teBNSNz/avh7TPF+m+ZAhvJLe2stYgtb6O5sJb3TWcK620t1BZ/b7WJ/57/HH/AATR/aq8XeIo + /BE/x10hvhJIzuvi26+DH7RzfEdPDqSRxvL/AMK6X4W/2LNryQyoosR8QIbOWbJN7AT5I/dX9nP4Ufs5 + /sveFdK8K/Cz4fePdNvLTw54Z8Ka14wuPgz8WZ/FXi6HwvpH2e01DxFrA8DoLia4mkvNRuI7SO00ldW1 + C9NtZ28kpiH65xhS4Bw+QZfSynHUMxz3nqzpYjKMLLC0VhJSpOEM4VWlRi6qj7T2MYQqY1Ti/b1KdKyq + Vh3ipVZOpBwp2SaqSUm5d6dpSsu7bUbPSN1p9jW4zE3yOfn1Lo+P+XyQf3wOM4+vPvXzB+0mMS+DflK/ + 8TLwf1bd/wA3Hfs0dOTge30969Xtfir4WeB2j034kyKsmrgmL4QfFyQboL+WORP3fgpsyh1ZVj/1kjKw + jVyr48P+OWuW/ieLw/f6XpfiyCx0jW/h9ZX154g8F+MfC1st3q37RP7PE+n29vN4p0TSI72WeHSdRk2W + LXDRLauZxHlN35VD44/4o/mjuudjY+OviJ4ahl0jRfBHgvW9Miv9WvLXUtU+IuuaBfTpqurX2q7LjSrT + 4Y+Ire2e3N4bfMer3QmEQn/deZ5MeRqfizx9rGu+G/El/wDCn4ey6v4TfU5NCuR8ZPFSLaNrFn/Z+oEw + p8GRDMZ7QmHMyOYwSYihZixRWnJHt279HdfijmjOb3d9+i6ctunmdH/wtf4s/wDRM/h3/wCHe8S//OWr + B0Txl8Q/D82uT6Z8Lfh9FL4i1ubxDqzv8YvE8huNUuLOy0+SYbvgt8i/ZNOtIVjX5VWFQO9FFNQjZ6dP + PuvMfPNrf7UXsuy8vN/eO8TeNPiH4v0DV/DGu/C3wHcaNrljcabqlva/G3xnpk1zY3cZiubcX2mfB+zv + oEniZopTb3MTPE7xsxR2U7Y+K3xZUBR8M/h5gAAZ+L3iUngY5P8Awpbk0UUuSPb8/wDMSqT017dF/c8v + NnPS+LfiBN4rs/Gj/C3wH/wkFhoGpeGba5X41+MFtl0fVdQ0vVLyF9PHwc+wyTteaPYyR3j25u4UWWCO + ZYZ5Y26I/Ff4skEf8Kz+HfPH/JXvEv8A85aiijlj2/MOeWmu9m9Fq/dXbtoc74X8W+PvBulyaN4f+FXw + +tNPl1fxBrrxSfGbxZdM2p+KNd1HxLrVx5tz8GpZcXesatfXQj3+XD53lRKkSKor+MvFHxO8daRaeHr/ + AME+BNDsG8UeCNZvdTs/iT4g1q7gtPC3jTQPFFylrpc3wq0SG7uLqHR3tIEl1WyjWWdJZJgiMrFFHJHt + +L/zF7Sdt+l9l/d8vNm9ZeOfiN4bhm0fR/A/gnWtMh1DVbq01HU/iPruhX1xHqmqXmqbbjSrX4X+ILe1 + eA3pt8R6veLKIhPujMhhjx9S8V+PdW1/w74mvvhT8PZdY8K/2t/YdyPjL4sjFmdbtI7LUiYY/gysM/n2 + 0SIPtEcnlH54tjksSihQi2rrqur77rXR9mtUCqTa1d7uz0W14+XmzpB8V/iyOP8AhWfw74/6q94l/wDn + LVg6H4z+Ifh19ak0v4W/D6J/EGt3fiHVGf4xeJ5DPql7FbQTzfN8FvlXybO2hjTkRRRJGmEAFFFHJHt+ + f+ZSnN6N+ey3tHy/vP7xfE3jT4h+L9A1Xwzr3wt8B3Gja1aSWGpW9r8bfGmlzT2kwxLCt9pfwfs76BZV + +SX7PcxGSJnhkLRSOjbi/Fb4sqAP+FafDw4GMt8X/EpJ+pPwWyT7miijkj2/P/MSqT017dF/c8vNnOP4 + r8fSeLbfxu3wt8B/8JFbeH7nwxHcD42eMha/2PdajaarLC+mj4O/2c8/22zheO+a2+2xxmW3WcQSvGek + /wCFr/Fn/omfw7/8O74l/wDnLUUVXJG60/l79bN9R88/d13Svov7q7djnPCvizx94L0ddB8PfCr4f2mm + JqGtaosEnxm8W3TC88Qa1qHiDVJPOufg1LMRPqmqXk6ozlYlkEUQWNEUUfHXiP4m/EDRLLw5qHgzwJoF + gPF/w+8QXuqWXxI8Qa5eQ2ng3x74b8Y3ENrpU/ws0KG7uL6LQWsYRLq1lHFJcrO8jLEY3KKUYxTjps1b + V9LW6kupOzfNrvst3ytvbu395//Z + + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QECRXhpZgAATU0AKgAAAAgABwEaAAUAAAABAAAAYgEbAAUAAAAB + AAAAagEoAAMAAAABAAIAAAExAAIAAAAQAAAAcgE7AAIAAAAIAAAAgodpAAQAAAABAAAAipydAAEAAAAQ + AAAA6gAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMC42AEJyaWFudGEAAASQAwACAAAAFAAA + AMCQBAACAAAAFAAAANSSkQACAAAAAzQ5AACSkgACAAAAAzQ5AAAAAAAAMjAxNTowOToyMyAwNzowNToz + MgAyMDE1OjA5OjIzIDA3OjA1OjMyAAAAQgByAGkAYQBuAHQAYQAAAP/bAEMAAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/A + ABEIAJYAoAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMD + AgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp + KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOk + paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQAD + AQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFR + B2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ + WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfI + ycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP7WNR8cWXxJ8XaNpFo3jnQL + DSIfiBZaxZQX+t+FpbnWtDl+G0lvcHUPDOowyXlra23ia6t7eJr/AMiaae5m+zTLb21yNN/CunmHcNd+ + Igb7LcyZ/wCFk/Es/PGU2HafEpwRkkg8c8jpU2oeIbrX/iD4TludA1zw+bLw38RbVINWgt45LlTefCm5 + NzH5MtxE6o91LZ5hmmhNxa3IWVwqNXSO37gndN/x53gJ2J6ocY28dOfx6ZFerhacHQg5QhJty1cU3uu9 + 7Lql066o8rE1Kka80pzSTiklJpL3U9r233dtd+xy7+E9OViBrvxFUBrQAf8ACyfiXyJbkpIT/wAVLwSn + ygZzkZX5jSnwpp3mov8AbvxGUG6MRH/CyfiWcp9jeUZ/4qTIPmLv4wQBgnacHq5WwznM3+ssCflTPF0p + y3y8Edh3J7jgKzETR8zjN6T/AKtDknT5TuPy98ZxxgV0eyp/8+4f+AR/y8l9xh7Wr/z8qb3+OXl5+SOT + HhTTtyj+3fiLzHdsR/wsr4mfehliVMf8VKDwrMG6jJGe2UPhPT/MYDXPiN8sdowU/En4lghpZZkkG4+J + O6oPYY+UAnnqwx3oMy/6i+HCIes8B7LyD0Jxnd044pScyyDdNgQ2PBWPoJ7jgnaPTg5HbrS9lT/59w/8 + Aj0t5eS+4Pa1f+fk/wDwKX+fkcr/AMInp3mOP7d+IpC3IjA/4WV8Sx8htY5Dn/ipSQd7Er0JGAMqaSHw + ppzkbtd+IxG+7BJ+JPxLGBHdeXFkDxKOifKcEZxuOSQaj8efEDwl8MfDOreNvHWsSaH4W0jUdKh1HU2s + L7UPJl1m50vQdLj+x6VY3+oTyXWr6lYWUSW1pKTLcIz7IhJIvBfDD9o74N/FvxBceGPh94yuNe16z0zV + 9fnsH8NeKNFkTSLbV9Psbi8WbXtA0u1mjhvNW06CSKKZ7gG6iby9gkYYyqYKnVp4ec8LCvUV6dGUqUat + Raq9Ok2pyV4vWKfwvsejQyvPMTgMTm2Gy7NsRleCn7PGZlQweMrZfhKlqT9nicbTpyw2HnarRfJVqwl+ + 9pO3vwv3R8LWP2J5v7e+InmLp0dwGHxI+JTATNDIzED/AISUrw6rjqpGMDGcwano2iaXHG9zrnxPZrjU + ILG1gsfHPxb1W7uZGhN1JHb2Oma5d3kzLa293cy+XAwhgikldkWMsOxLY0yTmYf8SiLosZz/AKNLj+E/ + KOdpPJGOTiszWNSsNL1bwhqGqX8Gm6fb+LLg3F9qE1vaWcHneDPE1tE09zO0cMHm3E0cEfmOqtNLFEMu + 6hrnCnCEpKnTvGLkrwj0+5vp1OfCc+IxFKlOdeUZOTapTtUlyRdTlg3Cok5cnLrCW+ivZnIi10PKZuvj + oATMG/0z9oM9H/ddJO688dMfNk5pn2fRQkh+0/HMsLZHQfbP2g8+dtmL4/eEYyE5OVyMAjnPlXgzTPjB + pWiXFt4k/bK8EajrqfETxbr9hqVxo3gfXLObwNrzaVd6d4SvbKG48Isl5oN+uuJZajFNPDDZX9vb2ttb + WVnY6bp/pkl1rh1TTb2L9qPwrFZxQ6XJrGlvpXgiaHUrm20q3sNQ+wTPrZfSLHUb8ajrUdsw1Ke0vLy2 + txfXGm6ZDZSbSw2Gi2lmeSyt7W3Lh83XN7OVoNc2VqyrxtKk3ttV9k1r6jwlrf7DnTbcdFiKb5U2t74J + fCkpNbapJt6Fv7Log84/afjp/r4tn+mftBj90Vt9/wDHyNzS8t82TwwwAFS20Q7d118c8madT/pv7Qf+ + rVpvLPEvJ2qnTn+9yTXEWeneN7CPWYrb9sTwvJFqTaubZb/w94R1KXQTe6HqOmaLBpF3e+MJblrbw7fS + 6Hq1u2ryarqesS6Zfx6/qepTa2byw1J9Q8fz6xpd0P2lvheNC/sK5t9e0ddN8Pw3N9rq20EcZ03V18QP + Jp1pPdvfz/b4LSO50+CG0tn0/VpLg3mmKWGwyc+TM8mmo0nUhbDZtF1JRpqfsoqWWqKqSalCLlJUuZR5 + qqTuhYRyk19RzvdWksRT5XqtVfBJ2tq/dUkle2mm/wDZ9HFsD9p+Ohm+yK3N5+0Hn7R5eT8ok25L4yOF + XpgU+S20LD7bn458T24XF5+0G37pmt/MPMh/haX/AGhyVxhcfNfwG8I/G7wT4dvbX4gftZeBn1lvEEeo + QzP49vvjRZXuiNp+mwz2c178QT4S1TR5/OtLgWsWntc2EK3c128Ut46G3+lZtQvf7Qt7qD9pPwpHZCO0 + F9pz2ng2QT3q6fbWd1Ja3R1iOSys7m8N5qkVm6XlxbXN3Bbrfy2Gn21m3hUsfWqUqdSWVzpTmoOVKUMP + zw5r3TtibXhypyte6ceTn1t9NmHC+W4HGV8NQ4gpZjTozrQhi8LLO/Y11SsoTpKpwtCXLiLL2LlGL1/e + +yfuB9m0P91/pPx05mkDgXv7QZPlBZ9gH7zk7hCDtBYdWGN1RtbaN+7K3Xx0GbSd2X7Z+0Ef36iDy+S/ + BOZeB8nJyMAYw7OPxJYJqEUf7VnhWeO/l1eS1F9pfhK9m0k3mjajY6XbWF1ceJZJ5bbQr+XStShGom9v + 9RGnXcGrX93Jqj3lpoS6z4qfWrO4/wCGh/htHoT6JOmpaSlp4dN3LrJ0q3tElstUbXT5Fj/ajzanHIlr + C1tbxRafPaalJdSaja39cqq3/CffWKdoUbK+8l+/vyRSV3ZSvZqDSbXK+HsC5SUM35oxpymp8+cxjKUY + qSoq/DP8SduWD/hOSSlVheN9BrbRPOcLc/HPy9tqV/039oPq88iz8mQnAiEZ/MrzkU1o7S0Oj6voevfE + NbiD4heBNHmg1zxX8RyFt9S8VeG7HUbHUtC8UamUZLuw1GZPLv8ATzuguUuICAYJRneG9V8X2uqQXfir + 9pT4ca1YW9xp3maVpmk+GNFa+t7e6iN5NLqB8Q3T27anFFIVs47aT7FI/kR6nPEJWm3dW1Cy1R7y/wBN + vYdQsLn4y/DJrW9s5re6srlYvEnw7t5Wt7mBpI5gk8MsLtHIyrLHIh+dCB0Yes8RTqyqYRYe0JcsakKf + tG1FPmXs6lWKXa8ubTWMbJvzM0yyll6g6GLqYr3qN61GrjJYZc84x9lJYzKctqOdnzXhzQ5YvWS2m/4S + jXPE/wAQfDz634N1fwpPpOl/FDSLeK9uRJHqltbah8KZV1iykK2Pn2N7JcSrYyrBKoigJuHs743WnWna + vnyD+6uMGzvMHzh2KH/nv7/jj0zXGPrfizXPiD4dPizwaPCdzp+lfE+w02O219dbg1bSY7/4US2+sCf7 + Bo727XU09zELQ20/2dLQlrwyTvbxdm6nyOY5SBZXmMTnAOY+n7zk8fkM5NdeDd8NT6/FrrrrvZ7N7tWV + m/kvncV/vFT1X/pMdu67PW61u9x8xO5v3NwP3mn/APLUY5vAOR9oPzHp3wQDnvQSTNH+5uR/pz4/fD/o + HynP/Hxg45PccdSKJQ25v3Uv+tsP+W3b7Wo4Pm8jqB1wRkEHmgqfOj/dS/8AH6x/4+Dj/kHy/wDTXp1H + 5/j0nOICd0f7mcfuL7/lqCMefAM/8fH3T0I655xxmlyfNk/c3P8AqNP6zAgfv7j0uMn1HHOR2xhAGymY + pOYL4n99j/ltBg8Scew7nnk80FT5j4ik/wBRYY/fk/8ALe4PI83vxn0HPbgA+Mv+Cg05tv2T/ibOLS+n + MPin4PusEBWWeYj4u/DYiKNDchXlkOFTeyou4GR40DMvwN/wTT1aTUf2ifECvouu6b5XwZ8bkHUY7aBZ + d/j/AOF4PlPBqE4PlbcujlPvKVVwHK/fH/BQeWWD9k74mzQ2N1eyQ+KPhC8Vpbz24uLiRfi78NisELXd + 3bWqyyn5Ea5nihVmHmTRryvwJ/wTR1LUNQ/aK8QLeeGtZ0VYvgz42Mb6je6HKLgt4/8AheGWL+x9c1Rl + 8oAeb9oEKNvXyjKdwX89zqKfHXDj5YN/VZWk60YzVpY26jSc1Ka/wwdtW9mf114cVXH6LfjDTWJx1NTz + 6lfD0ssq18HV/d8L+9XzCOCq08LJWtyTxdC9o+63Ujf9wjn+zJB5Vwf+JRF92UKD/o8q9PtA4OOBxgHg + LVqRjtl/dXH/AB+WoyJVOf3lscj/AEjGe7cYz7HioVJ02U+XL/yB4cHzyP8Al3l5A8wYGCMAYwf4Rnm2 + 4IWT91J/x+W3Wbt5ttxnzOe3JzwQP4cV+hH8igucxZhuPvXfHnAA/vP+vgcHvx2PHJzGSfKn/cz/APIP + gP8ArRj7tz/03+7x8q/+O8jL1Ukx/upeWvOs/UGU8j97/wB89ePWoyr+VOPLl/48YekxGTtuecCTA3d1 + xwP4cUAPOc3X7m5J+223WYc/u7Lgf6QefxHQ5PUF0ROI/wB1cH/Srv8A5arg/vbnJAFx95emffOSMGml + Tm5xFL/x+2+P35P/ACzsuMeYefUjuOtOQHEf7qT/AI+rvBE/GPNuev7wcAnnjk4570AV/wDlxA8m4z/Z + Y5MwOP3PtcH0546DvzU8p+WX9zcf8flnjEw5/eWf/Tx1HOexODnOKg2kWK4ik/5Bg/5an/niO/mH06dy + O54qeZDiU+VL/wAflnjM5/56WYwP3o+UY6/SgAyf9GBhnGbu4H+tGOI7zgfv8gjvwMjPXmoXOBDmG4z/ + AGZdnBmGOlnx/r+h+nce1S4bFt+7kObqfP74g/6u84P737wwPm4yQeWycxOpxAPLl/5Bt0Mmck5xZ9V8 + w5PtjnIGOtAErk/aJR5M/wDq9P4Mi8ZurnjPnnJxwvXBU5Ayc814r/499IPlzr/xcj4YjLy5A/4rjwl1 + HnsT6fdbg4+nSup+0SfupMCPTv8AlucjF3cd/M6nHPphu5rmfFakW2kfu3X/AIuR8MSSZSw/5Hrwjjjz + Gz1GPwHTioqfw6n+CX/pLLp/xKf+OP8A6Uincah4w1L4ieHR4t8N6dosllo3xIstImg1CK6/tjS0ufhH + OurrbxG9awiudQlv7YWd1dLdwfYo2kidJI7iTr3RvIb9zbn/AEO7GcnGQVwMeV15456VxNxceOZfiP4e + TxxZeGY3g0X4kxaBc6R9rtftmiif4Qv513aXV3qzJK+qPqauy3kAWCCwQ2LEG7uOxkI8j/V2ZJsrvgy4 + X/lnjB8jJP8Ad6fL+VY4T/d4b3vLy69fO979Pka4r/eKnrH/ANIjt5dvLfUszK298QW4+fT+jH/n7HT9 + z93senU59KCj+dH+4tgRet1J4/4l8vIHk9PT155qKQ/M/wC7tM+ZY9Jf+npeR+4zg8h+mB69KaSBNHiK + y/4/W+9Nj/mHyZ24g+71xxz6Cuk5yYI25P3MABgv+Nx5Hnwd/JHzdAOO5+hNjebIfItv9RYfxHP/AB8X + BH/LDr3IwO/1qIEZT5LTHkXoyZc8edBjdiHhh/AOhGfu4xSEjzJP3dljyLAcTDf/AMfFxjjyB83TIz6j + J7gHxr/wUJkuLb9k34nzwaaL+4i8T/CBoLO1mtop7ib/AIW78NikUcl41rbRhiR5kks6BVLsBIwWN/gH + /gmdqWsX/wC0X4gTUvCtzoax/Bjxs0Ut5qOjXsU5Pj74XiRFGmXl3LHJH8hBkiWJ1L/vQVUP98/8FCpL + xP2TPia+n2mlXV8vij4QNaW91qMtjbTTj4u/Dby45LyDS9RmtonbiSaOwunjyxW3lxtPwB/wTNuvFM/7 + RXiEeItC8LaXEvwX8bG2fSfFWo6600h8f/C/zVnjvfBvh1bZUTaYnjku2l3MGSEKC/57nS/4zrh1uFJ/ + 7LK0pVGqqs8bfkpqtHmjqrt0pL4te39d+HE2vot+MMPrOZ008+pt4ehgY1cuq/u+FvexWMeX15UJrS0Y + 47DaRptxfO+f9zCjnTJP3Nuf+JREQWY5JNtJz/qfvEYJ5PJ6nirTq+2T9zbD/TLUZ3Hn97bEkYh6EHOC + T1OTVBjjTZf3dn/yCIvvS45+zzHtB9/n5+4O3OetWnOVl+Sz4u7Y/wCt7ebbZH+o4Tpj+Q7/AKEfyISh + G3R/uLbG67+8x5Hmdc+TwfTrxUZV/Ln/AHMGPsMBxuOR8tzz/qvvYBz0wB19GqQDEBHZYzd/emw2PMP/ + AEw6/wB3nGO4phP7if8Ad2pzYwD/AFvzE7Lnk/uf9Z6jHTv2oAnKN/pP7i2Ob22AwTk/u7ED/lgen07D + pnAfGrER/ubc/wCl3X8R6CW5zn9ycADHHv2quWGbr93Zf8ftv92bn/V2WM/uOh7+nvT4yMR/JZ/8fN3j + 97jrJc8H9xwnvyT6UAR7H+wLmG3H/EsHOTx+47fuRz6cjP8AKeVH2y/uLb/j9tOpPP72zz/yx4X8+c56 + c0wf9BXEdl/yDB0l7eT/ANcPvf3fyyM1PNgCXEdmf9Msz80uP+WlmDt/cHC8A/7xbjigCXY2Lb9xb4+1 + Tj7x7R3nB/c9B/D7gcc8RSI4EH7i2402743HPAs8D/U9f8enqAjFviO0x9qnyDLz/q7zhv3J+UfwHnd8 + vAzULniD93Zj/iWXXPnfvAMWeD/qPv8AoM9ehoAtujefL+5t+ItP43cAm6uB3h4B6NwOF6HoOY8VoRb6 + QTDbgD4kfDHDIxypPjnwlyP3Qzn6jk10UhHnyfu7PBTT+kuQCLu46ZhGegD9OAOTnjmfFLDyNI+SzXPx + J+GP+ql3Nn/hOfCXQeSue56jBA+tRU/h1P8ABL/0ll0/4lP/ABx/9KRBcR+Nbf4ieHx4x1HQ53fRviW2 + hjTkkZxoi3vwmigN4z2ulCK5a+W+nntUiv1hS5t1XVJgBHH1zu/kH/Sbb/jzux93uSmMf6R1J/TA61zG + o6d4l0v4ieE49d8Rprvn+G/iJNYPJpdvbz2lol18KIDbySaetnbyqbqK9uzvtjMZL0qs4t4Y4I+mdphA + f3qf8ed5z9mlIJ/d9MT8HPPt046nHCf7vD1l+fXz7+aNsXpiKm32dttYRehJNI+5j9otj+8sP4D1F2OV + P2g4UZyRycH+HNDSP50X+k23/H63VDyf7Plzj/SeFzwOuKJmm3OPNT/WWB5tpeR9rABAM3y4IPrnoAMU + m6fzo/3yA/bXP/HrNz/xL5ckDz+Af7voPQ10nMLvfen+kW3EF8MlTwDLbnBP2k4Y9QemB054PMfzZALm + 2x5Fj0Q7tvn3OOftB56bjgjGeKQNNuT96g/cX/8Ay7S55ng4H77Jyec9hwe2DdMZH/eof3NhwLWUH/X3 + HrMenXPfGOpoA+Kf+CiVzfW/7IvxVuLKbSjdw+I/hHNB9va4hst8Xxc+Gz77mW2a5uFhjRWaTyYJHO3C + gZyPzW/4JN+Or7x38e/FGqrfeFLjTLX4S/EDTo59GfW2mW9tfiJ8L1lS5g1az0/ZDc23k31jNG7mazuI + JzGFnUp+lX/BRB9QT9kb4qNZXltBdr4j+EjwTT6Nf6pDHKnxb+G7I8mm2OoWd5fIm3m0tbq3uLgjZDIr + stfll/wRwv8AStQ+Mviqfwpe+HP+Ech+F/xBtEtNE8A+IPCSpqFr46+E0D3kn9reLvEKXy6npkWmahC0 + C29ysdzHJqwTVJbu2i+FzanGXGOS1HBudOjQjGooycKaqvNXKNSSpSUZ1fZL2C9pTTVKvzc2iP668OFV + /wCJW/F9xpZnKn/b0OepQxGDhl8WqfCumJoVMTTxU5q6u6WHqxadKz92fL/Q2ZGGmPi4th/xKIhyp6i2 + k4GLgDcOc8DJ7CrUjvtk/wBItSftdqeUP/PS2BIP2jpwB7EEHpgVC0w02QCVB/xJ4cf6NMf+XeXjImAy + MYJHB6jmrTtNtlHmoP8ATLU/8esvTzLY5/13cEHH498D7o/kUUSNuixc22N13jKEnb5nPP2n73XHTio9 + 8myb/SLbH2GAY2HOMXPGftI+YHr69Pq9GmzF+9QDdd8fZZs48zgZ8/qeoPbNR7pvKnIlT/jwgwPs0pbG + y5OOJxyOpbgdsccgD/Mcm6/0m2P+m233UI/5Z2Xf7TyPWnRyPiP/AEi2H+lXZACH/ntc5Lf6QMqcccdf + XrTC0+br98h/023xi2lB/wBXZdT5+Mfln9adE02I/wB6n/H1d9LWbj97dcn98Bz3Xjt1xmgCASSGwH+k + 2xH9mDGEPP7k9f8ASOSR930PPIqeaRwsn+kWv/H3aYyh6+baDI/0k/LnHHB61BumNiP3qH/iWD/l2lA5 + h6f67qe2enUippWmxL+9jH+mWf8Ay6zEH95Z8g+d0x29QfpQAF5P9HP2i2x9qnPKHIzFeZJP2joQfl+o + 5PeN5HzAPPtv+QbdfKEO7kWeAD9o6ntUmZv9G/eoMXVxwbaUkHy70Hnz+QTxjquRk8VC7TAQ/vU/5Bl1 + 8v2WUN0s+N3nYz7kHHegCZ5H+0yH7RbcxWHRSOl1c45+09s/Nyc5GCOp5nxU7G30kG4t2H/CyPhjkRqQ + Sf8AhOvCXAPntjnjG1uT2xmulkaYXEuZkP7vTh/x7TZz9suOTifoPr8w6cjJ5rxW0pt9I3So4PxI+GPC + 28iHjxz4S7mVgPQ5U+vGDUVP4dT/AAS/9JZdP+JT/wAcf/SkZzeHfEXh74geHYvEPjTUPFs1/pPxR1HT + pbjSrPTzpulzan8K4rTSmS1NzFcNYGGUrcwDT4roTmSXT/tS3F1cdm4IgP76cD7HdjIhU5yUzx5JAzjP + AHOfeud1vQr/AEr4uWF/ceItV1WDxFpPjzVNP0u4RHs/DdtBbfBjRn0zTmkM8vkT3uk3etMiPbW/2zWb + wrZmUSXE/Ryb/IP7ybmyvOREh5ynGPLJ7/QcjnjGOD/3amuzktXd79X1fnu3u2a4r/eKnrH8Yx/Dsui0 + sth8oIZj503L2HWJRn/Sxlv9QMAHgDjJHQ9KCD50X7+4H+mnnyU/6B8vP/HvgZx04Ax05pZhJufMs3Mm + nnJijGf9LUD/AJZgAjHC4BLHnI4oPmedF+8nH+msf9Shz/xL5ecCPjPXHXGOma6TnEwd6Dzp/wDUX3WJ + cjM0HH+p/i7nnB4yOlJ/y2f9/P8A6mwxmFQeLi54LeQOR+BPTvgrh9yfvJh+4vuPLjJwZoOP9X0PUt2b + HQZWg+Z5sn7yfPk2AwYo+Mz3HfywPl6g8A4wc0AfFX/BQ8Tn9kf4qfZr+9tJ/wDhI/hI0NzbafHezxSL + 8W/huyyR2b2si3LqRhbfZun+4uHdXH5Y/wDBHHU9C1r4z+KtQ8LXkkOhx/C/4h6emnweDdE8LWyXdl48 + +E8S3qRaRZpBdNd6UmmPw5ksojFY3Sx3VvJDF+qH/BQ2O5k/ZI+KaW93qUE7eJPhGIprCHTWvo5P+Ft/ + DfY1qup2lxp/2nOBCL2CS1Z9pmXyyxH5af8ABHTxHp3i/wCMvinW9DvPEi6Ynwu8fabHZatpvge0gUWX + jb4SNZ3NqvhHw/o5Mlxocuj/AGmO7E0Vkyrp1lJcw2gu5fhc2jfjDJZ8l+Wlho+0TglTc/7XfJKP1ec5 + SqqCdKSxFFUlRqpxn7VH9deHEL/Rb8X5/VsyqWz6C+sUMe6WX0rU+FnbE4JZjQ9vPXWcsBik1KilNeza + p/0KnP8AZsn76cA6TEMCFWBxbSd/IPIyOR14PPWrcgO2QefNzeWp5iT/AJ623zD9xweOAe2COCKqkP8A + 2ZIBLMP+JPDjEUbD/j2lGB+7J44Gc89fWrUgk2y/vZh/plqf9VHz+9tjnHl55/ujkADvkn7o/kUFzui/ + fzj5rvjyVPWTOP8AUd+ue3T6RkHy5wJ5v+PGADEa54W5wMiA8DruHJPAapUD5i/eT/eu+PKjJ5kzjIix + z684Oaiw/lz/ALyb/jwg+Xyk7C5OMmM/KOxOc++KAF6m5/fTt/pltj9yoB/dWRHPkDp2A6njBJp8ecJ+ + +m/4+ro/LCvH725+Y/uOpyMjkZxxnFNIf/Sv3k5/0y2/5ZIP+Wdlz9zr3Gc884I4Do9+I8ST/wDH1ddI + o+P3tzz/AKvJOeq5yPagCuM/YAfOnP8AxLFH+pUAfuD1/cd+nPTJxg1NNnbJ+/nGbuzOPIUjHm2YJGYD + xxjHTjpniohv+wj97PgaWM5iQDmEcHEY69/TnpxiaXftl/ez/wDH5Z4/dIQcSWfzD93+YycY7Ud/X9EA + EEfZx504xdT/APLJcjMV53MHJOeRzjJ4GKhcH9wvnzj/AIlt0MeUo7WfG7yOPrnOec81Ph/9GzJNkXU/ + Ajj6+XeA4/dck9cdsk9MYhcSfufnmP8AxLLv5DEmDkWZAz5fTtke3fqASPn7RJ++nH7rT+kS5OLu56jy + M4X/AMe+YdjXMeKj/o+kfvpmx8SPhjw0SoDnx14RHJ8lc/QEcHd2yOnk3i4l/ez58rThjyo85+13HJ/d + 9uo4AbnGe3M+K9/2fSMySt/xcj4YcNEqj/kefCXcIOeMdehyBnBqKn8Op/gl/wCksun/ABKf+OP/AKUh + db8NRaN8WtN1RdT13UZPFWlePdbmtb/UFnsNFlt7X4MeHU07QrVUt1sdNlg0KLU5IH+0yNq19q92bhRe + Rwx9E6nyCdsxIs7zJEq9Pk7eYB157k/SsfxJo2m6f8VtC1CyikFxrvh/x/qGqtFMEU3kLfCHSY2liSSM + ea1hpdiFllSSfYuzzkhMUVbDqPIPy3B/0O86Ttjqmf8Al468Zxzn8zWOE/3eHrL8/T+uyNcV/Hqf9u/+ + kRJJV+Z8LN/rNP3fvByftg5J808kcccZHUcGgqfOjwtxzfNn94v3v7Pl9ZfXB4yMdM8iklVdzDZOMSWJ + /wBe3e7A6/aMkfKACc4OTkdaCq+fH8tx/wAfp5+0N1Gny/8ATzzxz+fJrpOcAh3JgT48i/OPNHQzwE8m + ToOnY5I4wM0bT5kmVnA8iw4MgwB59xjP73PB6d+me+AIu5PknH7i+yPObOfOgB6TgfgcZPOD1oKgyyHZ + cH9zYcGcnrPcggg3BHrxjpxjjg/rr/Xz/wAwPi7/AIKFwmT9kr4pIYtQl3eJPhHiOyvPsl4z/wDC2vhu + Yxa3C3lsI7nftNu0k8dv5mwXLGDzEP5gf8EgvE8fjX40eKNej0rxXpJHwt8fWEdv4h1d74vaJ44+E97p + 11aRm8IX7RpV9ppvGmto9l0skWnTX2nLFfXf6e/8FC7cz/slfFKFEuzJJ4k+EaIItSnsJCzfFv4bhVS9 + guDNaMxwFuocy25IkjIdFFfmF/wSD1bVfEnxp8T61rPh3xP4Yu2+F3xAtI9N8Qa54lvrhrFfHXwpv9Pu + UtvELwzWx+xX9va3E8KrHf3VvcTpFDAIYIfhs2UP9cMmk4Rc40sOo1LwU6fP/a14Rg5qdSNb2a55xpz9 + h7FJyj7ez/rrw4w9Sp9Fvxgrxw6nCln8FOu8wxdF0/3fCtrYGnSlhq7XPbmq1INqez9nC/8AQQVP9myk + LPzpEI4lGMfZ5iMZkHGCQAOfXBq06kLJgT/8fltn96PveZbE/wDLX157ADgZ5qqVU6bJlLg/8SiI589h + wbaTkD7QMA9Qv8J4GKtSKCsnyzjF3a8mdu0ttj/l4zzk4PoQM8V9yfyKCKcxfJOBuuyR5i9DJz1kzgn8 + eeB6xlP3M4Inx9ggHEi9NtyBz5mdvp/F6qKlVAXh+S4Pz3f/AC8N2k7D7QBx6enavwAu/wBqD9oNPFt5 + GnxU8TrbrrTRLaBdF+zCBdSnRbb7P/Zfl/ZghMYgA8sIduCCRXiZzn2EyNYJ4unXn9exDw9H2Eacmprk + u5qdSnaPvr4eZ6PQ/TPDjwq4h8T3xGsgxeT4T/VfKXnGYPNsRjMP7XCr2vuYT6pgMc6lf91L3KqoQ2/e + a6fv6VObrctxj7bb/wDLRf8AnnZY6S9fyH9VjVsR5E5P2u7xiRTyJbn/AKaDp3zxnnnPDNi5ufknP+mW + +f35z/qrLsbg4PA5AyOxFcx4112+8J+CvFPinS9AvvE+o+HNG8Sa7Z+HLS+mtrrX59Js9Rv49Hs5YotS + lS81E25tbTZY3JkupYk8slyR7sYucowVrykormlGKvJ2V5SajFXespNRS1bS1PzM6PafsIO2f/kGdPMG + MeTk/wDLXHpnvwcZ7zSqcS4Wfm9s8/vF+95lmO8oyeO3Gfxrwr9nX4jeNvix8FvDfjf4i/DvU/hj4s1G + x1Wx1TwnqDa3a3ltd6DqF5oV5fSaX4hsdH1rR7bVL7Tbq/0rTdQhuZl0efT7j+0L9boTN7rMoKyDZcYF + 5aD/AI+GA4ltDwPtA45PPfua1xWGq4PFYnB1/Z+2wterhq3sa1HE0lVozdOoqeIw9Srh68OeL5K1CrUo + 1Y2nSnOEoyaTuk1ezSaumnZ907NPyaTXUNpxb4WcD7VcYHmD/nleZGTJnPXJOO+M8VDIhxCMT7f7Muxz + KMbcWQJJEu7A9hn0qYqp+znZOP8AS5+POYHIjvOMeeBuGOTgbsfxZwYXUfuDsnJGm3ZwZ2P/AD6E5U3G + Cfw5J6VgMldT9pl4nx5enYHmDI/0u5IJxIPTgZPIOeuDzXitW+z6QWE3HxI+GGN0gx/yPPhLkhZDngng + gj37V0joouJCFnz5Wn/8t2zj7Vcj/nufp0wMH1xXNeKlAt9IASbj4j/DH7029R/xXPhI5IM7Z59j1A56 + VFT+HU/wS/8ASWXT/iU/8cf/AEpEOr6H4Z034vW1/oQt31LXdP8AHupeLxHqs928XiBLD4J6XbJcWbT3 + EelyyeGtN0Cf7HHHZq1ubW/Fu7ag9xL1Lxgwn5IzizvMfO+AMx5x8nUY98/y5nWtK8LWvxcs77QbfSn1 + fU9K8e3PjGWC6W4vV11bP4J2dpFqKBrhrGZ/DNl4ckWzYWwNj/Z98tvILwTydK8Y+zkCC2x9ju+CeOq5 + 2nyTyOMHHIOTjoccH/u8PWW23xP+tzXFfx5/9u/+kRJZY1DP8kfEmnj77dPtYwB8vTOc/mM0GMGaP5Ij + /prD77YH/Evlxj5OgH49eetJLGAzfuLbG+w6N63ag7f3X3SMBunfrgCkaJfOi/0e1/4/G6t6WEuMfuOR + 0x3HNdJzirGMoQkf+pvyPnbkieDn7nUdB6gg9uTywJJG8uLiDTzne3Xz7jOfk79/QZzSCMbl/cW2fIve + M+k0HX9z94DhBjp6dKDGPOk/0e1B8mx78j9/c548gc9c89Mg+tH9ID4w/wCChNsZ/wBkv4pQrb287S+J + PhJEsL3c9qkjSfFn4cBIzdQQTT2odmX/AEqCKSe3LedAjSxoD+YH/BIO58Q6t8afFOpeKfB0vg/U3+F/ + j+GGxvNR164mn04+OfhVfWUht9bhSW1NrDqA0uaWCSRdSudPnvZ4dOlYaXZfp5/wUMslvP2SvijamC1/ + f+JPhJCQZZo0/e/Fv4boFZrYQTmFywWdY5YmdWddwBNfl/8A8EgrHxUvxp8UXnjfwxZeGtduPhb4/WPT + 0uppUfTH8dfCi/09pFOpata+ZZ/bpNNiKSfalSzk+2EXclwtfC5tNLjDJU5xjelh0o+0lGo7/wBq3VOk + sTTVSEnGP1icsNX9k6eGSnT9o0/668OMMqn0W/F/EPLstrOln0F9fr1Esfh/3fC1o4an/Z9ZuPvOz+vY + dv2tVcui9p/QWYwdNkOyM50eHOXbOPs83P3eCSSCOgIwKtPGu2X5Iv8Aj9tf+WjdRJbYH3eR3Hpz161U + aMf2a5MFsf8AiURE7z82DbSdP3J5PO7r82ferUkY2y5gtf8Aj7tO/Q+bbYH+p+71I+p4PNfdH8ijkj5i + /dxk7rskmRuT5nsnYAAf7Nfy13vhvST4/vdUW3mN4fFUl/n+0dSFqbj+2prjP9n/AGk2HkGX/lxNt9jE + X7jyPJ+Sv6kliBeL/R7YndddW+YnzP8Arh16bR3GPav5Z73wpoX/AAsC91kWJOpf8JZJqgvPt+ob/t39 + tTXX2kD7RsMn2j96BsCdBtC/LX55x9Pl/sBe1r0ubM7fuEm5v9z7s/3lNqOu/vW1ai9j+ufopYVYl+K9 + 8tyzMVT4Kcmsyqciw6vi/wB9h1/Z+OvWVtv3Kso3m9l/UpLGwS9MMUDSfaoPLV5pURn8qy2LJIsMrIhb + aHcRyMoJYI5wh+Pvgz8ZP2jPFnwo+L3jL4ifs/2XhTxp4J13xl/wgHgY654wsrjx7bWWkzeJ9I06Ka++ + Hz6gLIJqNl4SsvFWlaLqd14l1uw1iebwX4XubZdGm7H9rzUNU0X9nT4qaloN/d6FqkH/AAjKWer6Jql9 + pGq2n2rxT4TtJmtdS0xrK/tmmgnlt5mtbqB3hlli37XZT+PH/BP/AOKP7UOseN/Hlx4wvfEXiHxTpfgv + 4nX3gXwb4o8b+MPEeieI7yx02z1jw9Hc6ffeLNWtM3GozR6HZXn+gaxbiK4e7jiklkM/2tTP8LgcdQyO + rl2FxOJzStgfYY3EYqpQng0q2IjOFKnDF0IVKOI5FHG1Z0a0sPTjSlRqYZynOX41wx4UZnxT4e8Z+ImH + zfA4TL+C6ipYzLq1OtLF41zoYWspYecKcqUOVYlRSqyinKMrqVon7S/s5+MPij4/+C3hvxN8ZPAVp8O/ + H9xZatp+r+HYm1i3djoV/d6KuuTaRrOm2t3oC+IJNPl1nTNHS+8RW8Oi3umXEPiPU1uiYuf/AGpviP8A + Gj4XeCtF1z4JfCaD4ta7eePfD2n61oy3HiF7qw8OWyf27q08NloPhzWpmTVrHRrnwxDrE8sSeHNV1/Sd + Wi0jxdPCnhjUvy2/bM+If7Xum/s4/AjUtfS+8A/He+034oadrPh7wT4m1DwrFfyaNrvgrw5pOs6uPCvi + 8+H769n017nxbZqmuT+HobfVWggis43nhXrf2aPiZ+19L+yfqniT4b6DJ8Ufig/7R+h2vijRvGviLVPE + 954f8I2/wr+Fvi/XNJ0zUPF/ipfsumvfW934duLS31K6uVu/FN5f+HLR9akheb1aWa4WfiDVyD6hkMuT + M6/+z1M5S4bVOMqdWNH6+syjjP7FUK8aWHzGWYWr0aTl9cqSUpyVfwpzOh4Q4Hxceb4SWWY7N5ZNDK40 + a39pwrRxeLwjrym6f1Vpzwc5+zj7y54x5U+ZL9rLVZmt9Pe8t7WC7eVzdQW93NdQRXJguzPBDdSWlnLc + QRS70huHs7aSZFWR7WBnMafzs/Er42/Giy+I/wAYYrP4s/Eqzt9G+K3xv0rSbK08eeJ7fT9O0zQ/ib4n + 03SNNs7CHUEsobDT9PsbOytrRLcW621tFF5exTn+ieGKYQWAu4bF7nzGW4eAPHC84guvO8pJElkjh8wN + 5CPJK6KEVmZgWr+Wf4seFNDuPi18dNTlsC1//wALu/aAuBcC/wBRXbcQ/Fzxf5LIq3CxqsRRREqIqIqq + ioFGK/OuP8RWw2Eyp0sVisJz5lCEpYWUoucXSk+SpatRbg92pOW13G+q/XPoo5Nl+dZ7x3Sx/D+Q8QQw + /BtbEUaWfUqVWjhKqxlCKxOF9tluZxhiUm4qUadGXK3astn/AFOyxj7RL8kQxHp3WRuAby4zzs6HHPA4 + HXnI5nxYmLfSDsjBHxJ+GGCrseP+E58Jeq/XHP3sCulkjU3MmILY4i0/HzdP9KuMY/cnIPG72HfjHMeK + o8W+kEQWy4+JHwxO6NskD/hOfCJ4Hkr3wfvcHHpX3dV/u6nT3Jfkz+UqPxUuvvQ1+aINbj8HJ8YLD+w7 + TRLTW20jx8/i97fToLS/u9ae1+Cxt7vUZhFBJqMn/CN/8I/bfbi1yv2aCwsftCtYG3h6ZxB5BGbP/jzv + M/u024ynT5xz6eg9awNd1Xw1P8XdOsdIewttW07R/H0PiqMac9jdXWryW/wXvLa6uJ5I7Uavs0C90OD+ + 0oWvoEjS30w3cc+mTWcHRPNH5B/0i1/487vg4xzs7eaMcfd9uM5rHCP/AGeHrLb/ABPby7fM2xX8ep/2 + 7/6REWUW+5+bP/WWH8CYI+1r9z9590fxeo4460hFv50fzWX/AB+tjMaf9A+X7v7zheeOvf1qSWaPc/8A + pFtzJYHAx0F2Pu/vfujgke3brQ00XnRf6Tan/TG6gHj+z5cY/fcKOgHpn1rpOcjAg3JzaA+TfYzGnXzo + Ovz/AHscp/s54pMQeZJzZn9xY8CJN+RPcZ/5afeHJbjjBqQSxhk/f23+pvsnA4JngOD++5bHI54x6dDz + o/NkH2m1/wBTYDPAYnz7jP8Ay269c8nPP4gHxN/wUStbC9/ZE+K1rdJos1vceIfhNHPHqVlBe6c6N8Wf + hxuN5ZyTwx3NmuN1zA80ayxo6maLdvT8tv8AgjrpGp6f8afFlx4q0DwBoPiGf4W+PgU8K6T4dsidLn8d + /Cq/tLa+uNB1G9t7lLG7ub3TdPV2imSy0+Jrl9RuWk1W9/Ub/go1No//AAx98WTrN9ottpQ8Q/CVr241 + dLNtNggX4t/DcvcXi38wszbwMFklFyfJOw7yo5H5U/8ABGiS1i+N3i6PU/EHwy1jxOfhT4/uJ5PA9z4Z + uzbaRfePPhReW9reSaClrJsg1CW9tbaKeFYoILSKC2e5hijupfiM1cv9bcnS0XssPe6nzNXzS/s2ouCh + e31hTkm39W5E9bf1j4efVP8AiWPxb9pLJViv7ch7KOKjSebOPJwx/uUpSVVQ0lZQi9q76u39E7C3/s2Q + ZswRo8Od0ceR/o8vH3x82Rls98VbcW+2U5s/+Pu25MacnzbbkfvPuZzj8enQV2mjGmSZuLYf8SiIYOCR + i1k/6a8NnAbgcgHFWnlj2y/6RbH/AEy17djJbbf+Wp47Y/UV9ufyc3bUZGLc+Ud1l9685Mcec+YeT+84 + J7c9MjNfyNfGXw74Bit/izqttoXg6PxdHZ+N9Rg1GHS9FXxJH4jVNYuI72O8jhXU11xdTCzrcpIL8X4E + isLgA17t+1zqvwdtf2mPjFB4u1T4X2/iEeNtSe+i8RXXhaHWFWWO3lsWu49TnW9Ak0+S0ktGmGGtHt2h + zA0ZP5ryDQP7K1Df4k+Ef9iN8Em0uHw2sng9vGH/AAnK+EfIFt9i2rrC6u+syT5uBctqZvUTTW0vdtux + +QcS5xVzjFPBrDYjBLJ8yrU1WVWpy45RqTpJQUcOrOfseaEXJwanrUVk3/oh4JeGGWcDcPYjiWtxZwrn + c+O/Dunmv9mZjg8PSq5DVeDwON+qRqzzPEOvik80eHc/q+FmpYRydL3+Sn7bqmq+PNSvfG9h4svvCtx4 + LufGnw8g8N21qthPLqGkTePPD9tq0OoQw+Ir6VtLj0C3Mmu2+qWXl6ouo3cscmmafBPpi/YP/BM/SviF + o3xL+IOo6N4a+Elh8VIfh/8AFL/hX9tpXhvQI7LU2FjpeqaNZa4NA8Y6aZtCufETWukQ6fdeItGuLSHT + obnUNbu3ki1Ffz1kl8InWvGE2p+KvgtqHh+68a/D248J6do8/gabUbLSLbx1oT69NeJahJ7WxsvD1kbn + Ug1xeWdzZzalf37aesdzbtBoU2h2+j3H9v8Ai34H6h4gHiXxLeaNPp8/gOfTtP0258Ka0+mHWnhFtBFZ + DxTfWenJaX5mtrR4dNhttRvPPtXXycsxtXAYnC450oYl4WrhsQqDlXSrewwNGcqUHKhJJuSccy5l/vHO + 6UZ9P2zjzIMl4nybinhulmnA2VPPcr4cyqOY4XD4SdTBfXs6xeHnjKMFi6PNOhGopziq1JyoxgpVIXuf + rH+37pfx31X9mr9nm3+N2m/DvUfjfBZ/Fix8nUND8J3FnHb2ms+BdD0vXJ5f+Ek1DwhceLNS8MQyeLm1 + HTo9M0qCfUP7K/4Q6FrS50+b80DdfELQPCssHw+g8BaN4in8ReEtT8QaFp1ro2l+H4LlvC2j3uuRaZA/ + iaHTMS39hYeH9Xmtry8vL6znM1nqGlyR2+o2XC2yaMfh5dabJ41+CT+Of+Eej0t/EC33gd9Fink166tr + J5tSW1WA6s/hyK71KC9fS/7SE4uClhO8UquzWJtGufDjf2B4s+Btl4nbXfClzrF3d3HgW30W9ksfDGkX + uvWmlSutxay/8TaKx027is40S8tbkpdz2MMplj789zapnec43NlhcHgI4zFzq/VMOsUsDQjHEYOmo0ks + PGSyp+zbwsOX2sIOcZw91yl5Xhvwbk/APDWQcIVc94K4geTcRZnGWb43DYSlXxccZlWa5gp1KUsfi+Wn + SljFhofv5x9pSpSUo/BH+sT9gycXX7KnwrmuLuzvJm1n4oqbkLuSWOL4p/EWKFod9zO4tlijRLSMzSCK + FYo1kZUBP4JfFvw18O5/jF8dL670DwRL4gf44fHy4+2XGkaG+rtfL8W/FxtJ/tEsJvTcqRGbaTeZRiMx + tnbX6f8A7Lej/HfVvgX+xnqHwA8beC9M+EWj+Ofi/f8AxTs7ddEWHWNEf4z+MtMiGiJBaXkGrR3Gj6z4 + q1NbCG90ewstT0TTNSW7v9QWy0y5/Kf4wal8HE+NXx4tdR1H4Xp4oPx2+P6S295ceFl11tVm+Lvi82wa + KeYag19LK8bQKym4dmj2ZZlJ93jDDypcMcE1oYmVeeKp4OrUo4SdWWLwfs6E6HssyjKlGEatRUliIqnO + tGVGrRnKcJzlCP8APHgfLAvxe8dlXlw7Gio8VrDzzGFD+z534mrODyuM6igvdaVBRk7U1ZJpJv8ArElF + v9pl5sv9Xp3/ACzTobu46fP067uTla5rxSIRBpG02hb/AIWR8MceVGoYZ8c+EuhEhPPTp94j6V4d4G0X + 9oux/aN+LWteOPGPh/VPgNqmj6Hb/DLQ7VLBNW0y8tJ9Nune+tIbS3nsFWfUfE+nPctqmrz69Fp2nX18 + ujCCytLn3LxTKjW+kBZ7Zj/wsj4Y/LGACR/wnPhLp+9P48H6V+n47Dxw3uRxOGxanhMPiHUwsqk6dOWJ + wtOvLDVHVpUZLE4V1Hh8VFRlThiKdSNOpVgo1JfxBQd5U9GrTitba2kldWurPdeT2Wxg/Erx78OPA/j+ + x1vxPrvhz4f6Vpul+NrbxP4k8S3GmeFNDu9bvx8GHsZ73xBqps9OvbybTbrSNMtpJ7w3MnkLp6BxZRpE + zwb8ZPhD8SZb7Tvh18Vvh94+1DTtJub3UbDwV4x8NeKbuws3mihS7vLbQ7y+mtbZ5nWFbidI4TKwRWLE + Kfk7/goh4it/FGi2PhnTLPVV1jw5quvaU9q9mhfWZSvwk1qS50VIWuLi+itYPEdjbyweXBfpKlxdmxbS + /seo3XzL+wYr+C/iP4x1Txetz4V06f4eahplvd+ILd9IhudQuPEGg3MVrbtqEMPnztb2dzIUh37EjJcr + uTd8hHNsbRzfAZXTy6VXA4ijOtWzFe15MPO2Il7OdqbpKUlSp6TqQl+8Ts7xR+v5fwFwzmXhjxTx1i+N + cHgOJ8lzahgMt4LnPL1js6wsp5HTnjaFOrjYY+cIrMca39XwVaEf7Oq3npVdP9lZZE3N88v+ssM/ujz/ + AKWvP+p4APPYEnbyRikMiGaP55f+P5v+WJ5/0CX/AKYdMfpzgVxMvxN+HZZivjrw6Qz2LD/ia2GCI7rc + 5HI5ROSM4xg7ccV8zftAadefE/xR8GtW+Hv7Sll8NdM8B/ECHxJ4vsNP1lIX8W6Mw02xvbGGW2jaOK9X + w7J4psbGTVU1HQvtWpwx6joN9vivdL+xwlLD4jERpYjHYfA0pRqyliq6rVaUJU6M6lOEoYSniK7depGN + CDhRlGM6kZVHCnGc4/j7U0tKdST00UJJu9trpLS99/TXQ+zhIpZPml/1F+eYif8AltB38juOcnkHjIqj + qmr6XollqmtazqltpOj6Tpcep6rqupyw2GnaZptgLy7v9R1C/ukitbKysbaGa5u7u5ljt7e3ikmmkSNG + YclJ8VvhpBNaRTfEHwzE919utbVZtY06OS4uT/pX2eBGcNNK1tbXNz5cYaQQW80v+rikI+G/if4Y8QXX + jT9pf4hQftCw+JvA3jz9nzxR4J8I/By31VJGg8RQ+FpYdDEEJjGnTCXWNX8byRQWUNpqaz6ppH23V9Yt + mi07RM6caM6ONqTxmHoVMNg6mIw9Koq9SWOrwqUoxwVF4ejWVOtOE51YzxHsqHLRnB1Y1JU4z6MNRVbF + YWhUcqVKviaFGrWcbRoU6lSMJ1pOfLHlpxbk7vZa6XazP27P2j/2e/E37MXxF0Pwx8fPhTruu3/iT4Wv + YaX4X+IPgvxBr1wtj8T/AADf3lxp2j6de6leXr6dY2V5qU6xWF1HDa2Nxc3ETW8E5Hwp/wAEedV1iX42 + eK9N8VeO7Pxtr8fws+IGotPpq3M1vZ2OoePPhRObdZLnw/o02was+pmCJoZYbSy+xWlktnZww2Ft87eM + fhz481iHRYbDwn4t3Wvi7Q9QuZotDv4ZbaxtlP2i7iNxZ7WeAHdGqLM7yAbIJSCp+tv+CXfgzxh8HPij + 4hvPi54i1AwXPgDxxDD4h8R2t5pNkmoa94w+G2rpo1tNrUEU000t3p/iG+jVZJFa1i8yGPT4DHYwflOD + xuYZzn2V4/G5RXy+VGpSpOE8PWlaEIZhJVliK2BToU1Kvy1oPEUVWcqHu1HS93+9c5yPgrw28D/FHgzh + 3xQ4U4rjmlTBZrRpQxOUzzbGYitWyWhVwuX08Bn1dVFQp5fGtLkwmJqRTq83LFpx/anxz8W/hT8MrHTo + fiT8TvA3w+m17R7htEh8ceLPD3hSTWV02CBNSOkpr13YNqI05tR05b57RZhbNfWQuChuod/Hv+1b+y4R + IB+0n8CSftdq2P8Ahbfw96eZbndxrXT5XwTx8p96/Mn/AIKk+Gtd+N2nfCXRvhJr99e6jY+GfHVtqWp+ + FILvWzpcd5qvw1aSy1CHQle/jj1HT7HVY7fy7izaS6to1e7WISxyfmP4g/Z5+Per2dpDp6ePtDv7LxB4 + b1TUdVj8O65I3iKHTPDGiafdSyLZ6UhiuDremySRNe262iRedJPo95HNbAfRZlxFmGDx1fC0Mr+sUabi + o4j2eYzi06eEmpt4bA1qcoznXrUYxo1KtWMqEpVacINSPx/w98FPDni3hLh3Ps/8Xcn4XzTN8ZmOHzDI + 8ZiMip4jK6ODq5tToVqsMZnGExUY4qGAwtWEq1GlGUcdT9lKS5Pae6/tF/GT4Xaj8dvihfaT498P61p1 + 54x1i4stV0O7XW9KvreeUPHPZarpKXenXkRB2l7W5lRHDxORJG6r+ecniC9/4R6/dviRbN4Wf4EN4dj8 + FhHNyPEg8GmxSAxnw2IFg/tBrmY3Y1pr83JihNydKAsY/qVfgB8cJfEvhXWbew8faHpWieJ/HOoat4ej + 8O648Os2WteNNc1bT5z9m06S1U3elXsP2lL4XMoidIII9Iv4Zpzykn7N3x9bSr6X+yvHr28vwSPguLwI + NC1X7MfEv/CI/wBlLGbv7IdHa3GpNcusomDi6kS6/to6d/oA/N55fiquMx+Mll+MjUx2JniqlOWExFSF + OVXF4q9CnKrlc4wq8nJWpYqMvZ06dWKliKc+ZH9q5ZxXwrk/CHDuR0PE7w8r08m8OsVkdN1MXlv1mTwu + W5BhaNGuocVRX17ELDvljCnD95TrOGHklaHlt14rnTV/F17rPxOtNa8P6n45+G1/4X0WCKQy6TZ6d4/8 + PXuozXKP4XsEtTp+j2VqLeK0vbqO6KX82oR3+oOl5NBonibWbLSng174sWWseIn8UeJ9R0DVooTPa6Fb + 33g/X4LG4uzceD7bH/FS6mY5bIafqenWmn/YYNMs4LdZLRPfJf2ffjjFrPi/VLmw8fa9p2u+NPh9rGka + E/h7WoYdDsNE8c6Hquqyk3Wnw2zPZ6Dp0QsxY/ZpHS2ntZoNWvZLa4eroX7O/wAftJ0iayv08f65qtx4 + n8S6vYazJ4d1uP8A4R+DVfCWuWVrKkd5pTyPMviTU2klSygktGtpYJbbSrCFLqNMVluKVGcf7PxDtCCt + DLalNzay6lC1J/2ND2bpSTpYz4frtdOcfrV7n0WYeIHC88diZR8TPDacHU4PfPHG5c4yWH4hxFaq4tcX + NP6tTlGtiNXy0JJS9krTfg1vrurf8IDc6DJ8W7R/Gg8NrpJ8ViS98iG2n1+4FvaLqJ8LjVvtUnha3lZt + T+xPrCa0JJ49YUrDdK3VfE2u3+gTQaJ8WtN03xYuu+D7jXddkjlt7DWbjSfDGlXOpR2zWfg+WX7PHr62 + CrbHTNPtb7Rzc2mq2t5BcT2Nz7tB+zb8dk+H83hJx4/k1k+Hf7EHi9vDfiLz1tZNflkjs47Z7Y626L4Z + Q28u28NxFeuEGtwtJbT0ms/s6/tAapoB0yyHj3SNci1nwhf3viIeHNec6/NoXh7T/tjPFaabFdpA/iO3 + tmhe5jjhFvDL9ptdTjimspt1l2K5/wDcqn+81Zczyqq6VnjaElXdFZG28FUs50sB7OU6MVUf1WndyYvE + Dhf6/Tl/xE3w25VxJVrubxuA5OR8MYmgq7f+t/8ABlUmsNzKSj9YqL962nSl+lPwL+KUNx8Mf2RZfBf7 + Znwf+FvhzwH48+K2q/GTwN4t+JXgTwz4l1zT7/4s+Jzp6jw/qfhvUbm5n1bwNr/iy5/s7xLcaXosV5de + C/EGjadbarBp/iPR/gv4k/Fb4d6h8SfjM+n+MdI1CDU/jB8drnTL3T5XvtO1G11T4qeLLnTb2w1G1iks + Lyxv7a4gubW8triS0nt5knimaJg55Of9nv46XnifStVsbDx/oOmaT4/1nXr6w/4RzW5T4i0+5g0mzglY + WenNBDLcac2v28/9oxyYkktPIsbaV0vrappn7O3x4j1y01dtM8d2mjwaD4z0qbwc/h/WTBc3utaz4huI + pxcJYtpcVvch/Dl0pkdrrfFdF7+ztlezuPazfHZnnmU8PZTiMoqYajw/h6VPDVcPgMRTxVdxlipKlmFW + llKeMxNRyvSxNWpVhQozoYadajSoxow/HuCck4C4I4p424xwPi7wVjcdx9gOKMVmGDxmNyf6rgK2Izeh + j6eGwSpcTQqJ4iWJn7BVnOUqVFyjGtLmmfvd8KfipY3n7UXxK1y9/bP+CfxD+Ffj6y8NaN8IvhfofxT+ + H+seI7TVvtGlS2dvDoWl6FYt9qj1C+8W2FgNC13U9S1vTLnQn8Strup29o+ifb/itx9n0gB5Dn4k/DEY + MRUY/wCE58JY58pfXHXuWHTI/mm/Zl+Cvxd8JftI+BPGvigeMo/CH/CWfCyVtL1XQ9XtbDw3baBr/h++ + 1C8ur25sU02K208Q666GBrXy7SZPtMmp3MqSW/7J/B7w7rnwy1Xxjb/EH9oi3+Kc3xJ+P/w513wJpWo6 + qr3ei6efiFokKaTBHdor3movpr6Jb38ukfYdGllsI/7M8O6MqTSal+oZbm9fiHAY/H5nDAZRisDhstwm + FwNPA4jByzCnTwOFoScIxy7C0HicNBN4/F4jklj8RCrXjiMZXqzm/wCJfFbgHhrgDPsmy3hTjHC8c4HH + 5VSzLF5hgKuAr0svxdTG4qjLAVJZfjsfCMo0qFKsoTqQqQhWjemoWk/vb4m/Bn4efFn+xJ/G+k6lfXfh + dtRm0C+0jxX4x8I3unyaktmb0C98G+IPD17cwzSabp87W9zcyxLcWVtcRLHPEkq/Jfgn9n7wZ4k+D+u+ + KNRtPFkHjGxb4hWVi9l8fP2jl0OWTw9res6bpU1xDN8UJLyIyxadb/a2V7poZGmmtg0bi1BRXlttKbX2 + Ycy8nfc+HW69USv+z/4Iv/gh4a8eWVv4tsPGOs+G/BetXkUvx0/aOvPDkV5qx0241GC3tV+LVpfGzDXs + 6xBrpLmaBI4JrhHIuYtz4l/s5/DnwungW50G18cSJrXj7wvoGuRan8e/2h3J0vXbuHTLqXT2t/iiqpdW + 0crXFtDIgge8WCaV/KimtrwopvS9ulSEV/hbSa+4lN/+Ur/P95r66L7ip4v/AGYfhVbfE34Z6ONI8XX+ + iajc67cSPqPxy/aBm1jRtSt/DviGZdW0O7b4nSxQ3rQqdGDKlrLDpGra5EtzILmOBM/QfgZ8NNX+N3jj + wDLZeOx4b8N6FpU9s6/Hb9oaLVTqrQaJqU++f/hbMttNZPa+IoE3i3t5neDyGiCW7XGoFFOOqv5z/Baf + cKTabt3p/wDk3Lf77v8AQ2fh7+zz8L/FF541k1K28fnT9J8QazY6OLf46/tCW1zCui+I/FXha4hvEb4s + XMFzGy+Hre9hmVovOubu7ka1tVFvBD5x4G+Gfwx8Q/ADxT8XLqx8fPqejaP4s1awhHxr/aFt7MyaVpC6 + pHDdab/wuq5eaCG+EttEqavDNJpqQp9pt7h5pKKKGrKTW/Kn8/d19f8Ahti38Vv7yXXZySt5mrqHwO8B + W/wU0rxto9h4xuvGetTaF4f0ibVPjt+0FbafKfEPi+18PWs15JF8TNSuNGlurWW2u7+5s4NbSx1GNJRp + +uW1nFaXGx8U/gz8P/B2nfDRtF0vxe+qeMfGnhXSNWhvvjp+0DJZRWF4IJdVTT7uH4mxS2sxIjitpJNP + uYZY5Lh5raKVgxKKS2/7el+FjPmeuv8Ay7cvmk2n969CTxl8GPh5oXxe+F3gTSdN8Yy6P4qOty+I5L/4 + 4/H77dBbRaTqt7pz6RcRfE9omnF9pjR3MF5aCKK0b9xO0kipbbmm/s/fDXUfir4i8JJD44Xw1ofhrT3l + ib41fH5dYOsXcttKktvqS/Fp4WsxYXm2dpLGO7e5EPlyRLavLfFFJfq/zYXfNJdFyWXa7d/6+4xPh18G + Phx4s+IHxZ8OX9h43XRPB99osegzW3xv+PltqbSyXPiLTtVhv8/FG5tmtluPDsEtm9v5bXC3N291DGss + drb5fwu+E3w88W/Drx94w1qw8ZRzeG9b8Tf2G9j8afj8Fm0e18O6Z4gsG1TTZvi1ta9gk1S4tJLS31QW + 8lvbWrJeRzvJMhRSelO6vfkbvq9bPXXrovuL2qNLbnivlyRdvvbYmgfBnwTf/ADSPHOpWfi638Z6hbWm + m3DWXxv/AGgbnRotTuvFQ8MLLClx8UbW6kjDOjteuUkD5vhpzKo0pp/iV8H/AIe+Dvhx4E8SW9l4zGu+ + J9a8I6dqEZ+NXx/u9MF1q2lT3tzFao3xZs7i1sjd2aJ5jNdyfYjNF9mN1cC8tyiqf2/8cV8uxEG3BNvX + 2Slfz5W7+tza+InwQ+Gnhfxt8K/DWlWfjlrfxhqWqpqS3nxr+PksjwWl/wCG7WQQXifFaMWgitNdv7mG + JtPvhPe2+mx+bZWsM4ntT/ADwE3xig8HWum+L38IWvg6wv8AVJ5vj7+0HBrsWq63eeJorJrRE+IV1a6j + btD4XZZJZbnR7jS2kmZRrh1KM6IUUuq85yXyVLmX4q4SbUYvq5U1/wCBTin96b/QoeE/gh8PNe+LvxP8 + H3dh4zHh3wjbeGV0qWD45fH621P7XdWEepXYuwfidcW1xHLLeFVnhazPkWttbyWUhaa4eX4HfBT4ceLP + EPiXxLrvh7WLq8+G/wAV7oeA5rn4q/GbW4bdPDkum3Wk3+p6H4m8f63pEuow6hbreSQOl9p8lxFDceSp + VIoSii750unJJ/NSppfhJ/f6C5neKvvUcX6KEnb70n8j/9k= + + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QECRXhpZgAATU0AKgAAAAgABwEaAAUAAAABAAAAYgEbAAUAAAAB + AAAAagEoAAMAAAABAAIAAAExAAIAAAAQAAAAcgE7AAIAAAAIAAAAgodpAAQAAAABAAAAipydAAEAAAAQ + AAAA6gAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMC42AEJyaWFudGEAAASQAwACAAAAFAAA + AMCQBAACAAAAFAAAANSSkQACAAAAAzcyAACSkgACAAAAAzcyAAAAAAAAMjAxNTowOToyMyAwNzowNjoz + MQAyMDE1OjA5OjIzIDA3OjA2OjMxAAAAQgByAGkAYQBuAHQAYQAAAP/bAEMAAQEBAQEBAQEBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEB + AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/A + ABEIAJYAoAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMD + AgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp + KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOk + paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQAD + AQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFR + B2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ + WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfI + ycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP7Hv2nvjp8Q/BHw8+MN14P0 + fW/B+p+BPDXivV9B8cT6ZZ3+l61c6J8I/iJ48h+xW3ibQm0q5tLPW/C2k6bqi2n9rTzR3F5DEbFTb6g/ + 5V/sn/8ABQL9qj43/GyfwB4o1nxJZ6Rpur+NLH7JY+GPhbp2peJ08N+AvG2sW0Gk6rqXg+PTYZ7jxL4S + e2N7vl0f7LNFGdQLrdSw/ox+294p8Sa38GPj54X1bwNqWjaDoPgL4mpofiyLVroReJo9U/Zy+NUt7NBE + 2naStidImt47ORbDVtYu/tF1b3BhtI1SY/zJ/Dfxj8RfBvje58TaBpvj7wL4g8L+Ob7QvCuq3PxH+Jl4 + mtWNz4d8VaTefYZ/Etxc2pjvzp0zp4g0uxeY6PrUMMFq0RNxqny+eZlLLcXl1Z1Kn1eC9viaUK0abq0q + OIw7mo0ZYiisQ6lOUqUoclRUoTdWTppc8f6n8CuAMFx14feJ+G/sLIsdnkpZbleR51m9SrTrZJjMzw+J + w9DEYd0cBjKqhDEzo1qsqcoTSp3hGclE/ox8DftPfF/xf+zN4y+PVxonxl0nxB4YPif7F8NrrT/hnBre + uQ6dPpcuj3lpb33wvstaEM2m6xbyTWj6LHrGqT2V6fDul6lHeaJ/aP0V8H/F/wARPid8NPBvj7VfE/xL + 8Gah4p0DTtXuvCup2Pwrk1HR5ru4uYHt7kn4dQzRmRYBcR215a2ep2kcyW2qWFjqMd1Z2/8ANBp37bP7 + Yd7oses3Wv8AxO07Xf8AhGPiJqMHgq48TeKobzU59J1v4fRaPOEnsDrMcsFn4g1OE6faLJbavcRCSea2 + dov7KbqX7bn7YdnpV1q1p4g+JupayvhT4catP4Kg8S+LJr7S7nV9d+IsetThLfT21qea4sfDmlW8dheo + ltpFzJ5sEl3IJhq/0GL494ar/WYYbh36jOtm1WWHlDH4StDC0HUeGhlsamJzWdKrhKdW045nVlLnUbTx + LT5Tgj9DzxQ+sLDPibg51Fjllrbx2eqDxCytZw5trIeZU/qrVPSLk62ns+Rub/qrWy8aeZIp+J/jzC3C + xDGm/CvO02qTcn/hX3UOx54BXjrSRWfjRhz8T/Hn+svFyNM+FYwILhokOP8AhXx6KPm/vNgjrgfmD8EP + 2j/2jrX4d/BZtO+Guu/Gm48cfGjUfCvj3xBe6x4t1N/A2gzWHhLTbd7/AFrSPCusHT9M0/WfFg1248Ua + 8nlW3h7w1rVj/YscNz/a3hz7D8SfFr4u6N+0n8P/AITaL8GNR1v4V+JvDfiTUfEnxXS58SDTfDurvc6z + fafb3d/aeHbvw5p0ljb+EdV0+TR77VWm1/UPGHhCRdW8OeSLLxH9bl2WyzPL8BmWGp4ONDMcrxGb0I18 + bllOtDC4SFSpXjXpSxd6WKcaUvq+Fl/tONbp/U6WI9rT5/5i4jyzH8McQ59w1jsRGrjuHs5zDI8bVwsq + 88NUxeW4yrgq9TDzqU6VSeHlVoylTnUpU5ODTqQpycor3OPSvFkcj3UfxH8axXV4mn/arlNI+FCzTjzP + JjWaRfh5vkEKO4gV2YRb2wAGOY7LQvEmlr9l034g+MNOtp9U1C7nhstE+E1tHLeam11rGpX0iQ/DxFe7 + 1HU7m5v724KmW6u7ie4nZ55pJG6fD7Iv3U3+r07jzsgf6QOf9fzkgcdhzxmlKt5yYhn/AOP48+fzj+zn + 9J+fpz0xgg8cvsaX/PqH/gC/HT+tTyfbVv8An7U/8Cf+f9a92YZs/GmVx8T/AB5tMNy+DpnwrzuikiVP + +afHghyCMZzgnpg5Wo6nq2j3S22r/GrxLpcrw208UOoj4PWUskck80Ujolz4FiZ0/dEblDKjKQT1x2DB + js/dT8218SfO5/1kHT9/69eMD5SemRwPi1PHstl8WbT4W6r4d0D4mXfwz8NReBdS8Z+bceHrXxEdR8fi + wl1SO3a4uFs1mdFluo7PUhYvIl7Jo+tRwtpN4OjRvFONCmpTpwc6q5acFOcYc85RjKUYwvzScYydk/dl + s+nC89ac+epXcadN1OWnU5ZytOELJyU19u/wu7VtLtjV8UEySKfj7qpUTBFP2z4LD5PIjkzk+CSCfMLL + uHy/wfeHLI/FTMpLfH3VQQ12P+Pz4LdIrho4f+ZK5JjAY/385X2o+GLf9p+3j8Gy+J/HnwRvJn0DwjH8 + QLW28PeIX8nxJFptunjOXwheW+v6Yr2E16biXSG1mzczmKJ5LXSoLk2djoix/aBP9p2z/EP4YNbDS0h0 + W9g0a7tdaGtDU9Pmm1LVpZ59S0efS0szqVsdFsdGs7m8hjtraPXdLvLmTW7LR4XDXSWNyZ6J39pikleS + i028DrKLs5aW5XdNpSZ2OnTi7WzJ6wV1XpuPvKD1bwydo3alZX5lJJSvG7W8UsFGPj7qpybXkXfwW/5a + zBJeP+EK/hjOfRTywIFOPik70X/hfuqBTMUJ+2fBUfJ9maXqfBWP9YAN5O3HyD5+Ko6PB+03aQaNbaz4 + 6+B+rvZ3fh1NV1GLQfE2n3es6fHZ6zD4nupLWLXXsrTULi8n0K80W0skgtbb7BqUN7dzRX0CWvAfFGD9 + sK48IeNrXwl4q+GT6sur6EfAk3gsxaX4tk0xrizn13+3rvx3eTeEYBCst9ZWltZW32mXTrK2vG1BtQvp + rCDHF0qOFw+LrwrZXjHhqUqsKODqVamIxXLJR9nhKdbC0faVXeMlTqSpXi5c1nGR1ZZgaWY5hgMBPEV8 + vWNx2FwUsfmWNhRy7ArEV4UXjMdXo4LEVKWCwybq4mrGjUnChGU40py9yXpjeKWBH/F/dVwYbhji7+Cx + HmI0IQf8iV3DvxwTjIHGaVvFJEjqPj9qhVRb7T9s+C3JeWVZBkeCTkhFU/7I5YAEZyPhxbftGW+l+Ck8 + a+NvAEqP4V8OJ40h1GwjufGNnr6abpcHiH+z9U0C+t/Cc08t2mq3YuH0/UbE3c1tHbwfYbZ/tfRPZ/HO + W1v4H8efDe3uma1j0m/sNJvIXtxFJOJLrVIb+61S3vzdiSKS6srNNKG21S0s7+ya6lv4/LjjoNR/4T6l + 3Z2cKKa92Mrtc/nZ2v7yafRv0qmRYWlVlSee4KpyOFqlPMcTKlPmrKlLkl/Yq5lTUXUm7a0ryhzyajKm + nihjJIp+Puq7VuBGp+2fBYZjNskm7P8AwhWCBKWXP/Aeo5aPFLlGb/hfuqkj7WR/pfwX5EUpWHj/AIQo + feTGf733lGCBWnon/C9bRtITXfFXwi1OK2OiW+rvZadr2n3OpwrEU8SahCf7UuLa1v5mEU2i28cCWUTN + eR3ayrJbNZ5Ekv7ScOl6wkPiL4GXerQXOnL4bmurXxZa2eoWVvHqCavN4oW2v5ntrzUidLNhBokccGk3 + C3ss0uq25hsGJY6CV/7PqP4tFTpN+6lLT94o2ktIu/K5aNq+qWQ0HJxjnWClyuklL+1KkYS9pNQclKpl + MGo07KpUc1BqnLmipNVIQkm8VrGrOf2gNTRFEDM73vwVCorS7ZWYnwUFAWL5iScR/efC81xnxF8VfFfw + b4v+E8ej/EnX7zRtZ+IfhPRfFOm65o/w6kj1PR9a8ceAvDNxaQS6X4Gsb+2kNt4nvX+0Wuo2c0bRxsjl + l2n0gz/EaLwf43PxC134f3sbeDvEQtYfCVrqllsumt78wFm1bU713RLHbHLg5muCpiWJYWe68w+NYI8T + fCPKSp/xdL4c43vvHPxg+DvQ+Y/1PvwOK2VSnWw1SoqCoyXs2k4xU1zTS1Sva6XfVPzPMxmEjgq9GFLF + PFJ1KsJVKeIeIoVFClSmnTk8PhZaObUuam7Nbpp35n9uO58Yal8BPjrYa/oOnW3ha38F/Fe38NXyXRj1 + DVLGf9m74xNqt1PFBd35heG/dLG0Rl0ud7ZZb04aSO3T+VGw8Javdalq1v4i8CwaPDB4+Gn+FpD4g8Tf + Z9b02DS/EMURaT+0bu4W0nvdEtdQS8EVrqT22oqgsY7VoPtP9TX7cU/xFn+DPx7tPF2m+Cv+Fcp4B+KK + eDbiAX0evXEcn7OPxnOvHXRd3eoadd7ZjFBbRQ2WjrHaGeWSW/MjRW/8qWm+G7VtR1uPxJ4Q+C+n2j+O + ha+FpNP8PeD/ALLe6JHp2vwW7atb6dq1zPJotxdadoWtf2dqs1teLf6gY5L2KSO2ttM/PeLnJPC2k4/7 + JiGrKftV79BP2MVisPGVV6qqpwqKNLnlH2crVIf2r9FWnh6nDfHDrZdkONaz/hZKWcYiFCrC9WonGgp5 + Zj+elPas1OnaLfuVNipp/hrxNcaZbXmqfD2Ox8bf8In8SbvTfDj654gH21rXXfhuNKdymt3IhnjttWv4 + I7aLVTZ3EkMD6pc2syTfYW6j4b8UQWV9d6X8PYb3xovg74aX2oeG11zxGRZSXmvfEw6s0bPrVu000ttp + Gn2z2z6q1paySzNplxdTNH9vz9N8P3LaNANX8E/Bm18cSeF/iLc2OlRaJ4GbQ5ryLWvh62hHUEttUbRJ + 9Ts7W/8AEFlpF5cXdubS2a4L216g1BtS/Uj9j7wN8Tb39nf4k3nwU+EPwI8WfGOz8QfCiXVNH1Hwf8PL + vRo7YJ40u9ettNl1fxBpvhyw1PU/7P0DStVvP7SvPtenzzmystNmk07UND4Mgyief51g8ohjsBgXi8bU + prE4urXhl1FQxdSpy1qv9pxlDKbR5JYqVSNSnF8zxPus/dvErjHK/DfIM44xr8GcK51TynifL4SyzAZp + hoYmusfkGCy9QpTnw1OPs6VTFLFTbg1KpTnFU037RfFuiePvj94B1A+E/hX4l+Iek+GLb4m2Frr+keGP + i58UdB0Dw7Z6j4A+HlzqM9pY6T4n0hBFJrHiC/1efUPstxqrx2bLLYy2guPsv9U37Nl5qWqfs/8AwV1L + Vru61nVL74YeFrrUNX1jU73VtW1K8uNG097q/wBU1TUTdX+o391MzTXV/fXNxdXdw7zXE8s0jO3zr8ZP + hL8SLXXPgXb/AAe+C37PGradL4x06D443198MPBK2Nlok9pomk6je6dp+seJ9I1OPRLRNb8QeLotE0O7 + 1LxHJeeGdJtRr08Et7pPiX0rVf8AhorSP2h/hr4f8BeGvAdp+y7a+EtcsPF9yun6Nb3ej6m0urT6fa2N + qPFWm6uG0lvDHh7RfD76H4cGhafZ+O9UbV9L199Msrzw1+p8PcIYrLYwrVuIMvxcK+V4qrGnVxNajUpP + LJ1JOliKVfF4iFPG4uNJwy7D0qVF4mnPD2lOc3OX8C+Lfi/kPiRl2V4PK/D3AcIYvAZxmmZYzMMHiMFi + a2ZLNKs6sMPWlhslyuq4YN1XH2tatX5+Vy9nS2X1KFfy4f8AR7cfJpv8eQR9oXBX9z1Hcf3cY6U9kbzo + x9ntz/pp/ix10+TkAwHj0HPOOTXzB4Pvv2mJf2jviJY+L9H8HQ/s5QeG/Dcfw71ezttKTVb7XLY6JfTP + +48W3+v291eT+I9f0bWbnWNAi0u9j8A6Tc6Fp3h77fd3XiX6afHnR/u7L/j9bgycgf2e4AX9z04498fS + vcxWGeFnSg6+GxHtMNhcTzYWsq8IfWqFOuqFSUUlDE0FU9liqOsqFeNSlJ80Gfhad76NWbWqts7XXk90 + +q1HlXOzMEGPs17n5jn/AFsBBP7nrkjIx3J471L7StPv591/o+k3pijsxGbuCC5Kb7iYME861faH2rv2 + kbtoyDtG2w235P3doQLe9zmQbtwkg25/ckbhznrxnGKV9vnSfu7LPl2P3ZBvJ+0z/wDTHuOG6kZPXvzF + xlKDUoSlCS2lGTi1800zLXwz4fE0n/FM+HSDdDAOnWPB+wxHAP2IjaeSSAOSeM81FD4Z0AIw/wCEY8O/ + f1Ppp1jwBev/ANOPY4x0z04xW0Mec/7uyz9rH/LQYx9gj/6Y/cznPvmo4cbG/d2X39T4Egx/x+vyT5PB + H8PH3ifTk/rY1+s4n/oIr9P+X1Tpt9oy5fDWgYX/AIpnw6f+Qfz/AGbYgf8AH0uM/wChcEgkEdxk5OKc + fDPh83CA+GfD3/H4Qf8AiW2JBxp7nH/HiPl/PDjkcjGlLjC5jsv+YbnMny5+1jGf3P3hn6lSakIX7TH+ + 7tD/AKb0EgAH/EvkyB+5Py9yeP3h6HGS1ul3aX5B9ZxP/QRX7/xqnl/eMaTwzoA2E+GPDvFpedNNsQ3D + 256fYeWHTp+IFSv4a0Dz3/4pnw7ytlj/AIltjgH7TMMj/QeScDd0wAoJPbQkxlMx2efst5kiT959+25/ + 1X3s89foepqV8ee/7uzHFjgiQYB+1TZIHk9+jjIP3eaQfWcS/wDmIr/+Dqn/AMkY6eGdAE83/FM+Hf8A + j+XBGm2PQ6dGxz/oPAzk5zgnn3pg8NeH9kg/4Rnw7nGpYJ06yHAuSAP+PLjA4HP3RkYHy1sR7fPm/d2X + /H8MbZBgj+zovvfuRgDrxn5gOnUM42vujss41T70nH/HyMZzD16Y5+726Uf1t6f5IPrOJ/6CK/f+NU/+ + SM6Tw1oAYY8NeHkObA/Lp1jjP2sYwRZAnOOnYY6g14x8bFI8S/CPMcaH/haXw5/1fIJHxg+D2cHYnA4z + 156gd/fH27hiOy5NhgLJ8uftfBXEXXGN3A+XnPWvAfjTj/hJfhHhYV/4ul8OP9SwYH/i7/wdz/AmB+J5 + /Tnxf8Cp/wBufhOJdCpUqV6XtJ1KlnK3POU2rxd7OTbWy8tDhv247P4gW3wX+Pl94u13wvJ8O7z4dfFR + PC+jeSZtRsI4P2ePjf8A26+q3slhpFskN6HsZo4JW1pYILeeBrhdr3N1/KNplx4aj1DWz4i8V/BG7s5/ + HQufDk+lyeCJ003Qf7O1/T7a41m2tpYI4LFpofD901jdTzW66hfbX1KS7uPLt/6uf23dH8d6P8Gfj74g + 8SeObTUvA+ofDv4nf8Iz4VbQ7KI+F10/9nv44vrN0+s2tvZXtw2q+dpjOuqS6rDZjTD9ka3a7mLfyy6f + 4pubPUtXl8RfFrTNYtL/AMff2h4Zmt9kk/h/TTpfiLTbS5mhn8OWNpHdraSeHvNsbeO/0r+0VvLhLOQ3 + F5dX/wCX8X8zlhlGPO3hMQoqKqe1b9pQk40JxwmIjCaScqrnUpqdFSpx9o5KJ/dv0Vq2Hp8OccqtmGRY + OUs94UcYZxh6dapNKtUvPDc+ZYHlpwv++ShUTV/fp3ucJp0unpo8Nvqniz4IP4xbwz8QktNUtrvwPNoF + pqF/rPw+udDtdQu41gsRftbp4kTTppbBZ7W0ivmsbPUILGVrluoy2DaZdRaR4s+CEfi9fCnw4W41O4uv + A8Ph+81LT9b+It1r1rYXki3GntfeRJ4ai1OWCxM1zZz2P2yy02C+he139P8AEOtwaXbaZqvxf0W78Zye + E/iTbWfimGSVrTTbjV9c+HF3aWfn3HhqK98mVrDWP3n9n3lxaW7FLC6simnR2LNS8Ra5PY32naX8YNFt + PGaeD/hjb3nimeWSOy1W60fxB8TLy9smnh8Nz3ogja/0RjINMtbm8t18i/u70SajHefMe8pJ2opfW2+Z + 0a7oKDx/8X2byr/kWpSfLhXBVHHSOGtqv6y+tYJZpL/hc4Lt/rNq3gKHK7cHRXMl/rArxUn7O7dvrGvt + G/dOqt/AmueJtWXVvh7a+BdR8ND4i6fLrGsx+HNCvNL1nQ4PAvgDSNUk8PSR2+oWN1aQak3imabTrG6i + t4tbsJ4zqiahbPBcf0hfAfw7+0dby/sk3nhbxF4a0f8AZ30b9n/w/pPjjwrc2VlBrB1q58PSTQtZ6e8S + 3Lrp8+g+GNOtbtL7TX0WDxDqkdvpOswz3k2k+bfsDftHfALwp8Cv7K8WfH/4SaHrKeOdXlntfFnj7wd4 + b1udf7C0GAahd6RqGqaRcWy3ssEksZGnWlvOGElrCLdogftGP9rX9ltIzM37Tf7PqRD+0ZfMb4u/D9U8 + l7kyrKX/AOEmCmNosSK+duzD7sDcP1Pgujh8loxzFV8JXqZhk6wlTDZhh8LUlhvrtCTnUbmoyeNw/tZf + Va86cKuGqU4SpKDgkv8APbx+47z7jbH4jg6PCdCjguDuL+KfqWeZLhcbKGdUf7UxOHWIUI06lGGFnGEK + lJUsRiIeznGLq1E1N+/iRtkX762+5pvIU4P+kL/026juO4OMjs5pD50f762/4/T/AAnJH9nOeD5x/D/J + rw7Rv2nP2c/EWo6NoegftDfA/XNb1u70HS9G0jR/if4I1LVNX1LUNQhtdP03S9Ps/EM13fX99dTw21pa + WsM1xdTzRQwRvI6q3uTNL50f7wf8frdLaY/8w9xwd/Ax7jH54+phUp1LunOE0m0+Sakk9NHyt6+uq+Z/ + NGJweLwcowxmFxOFnOPPCOJoVaEpwu1zxjVjFyjdNcyTV01fQazt8hM9sB9nvc/LyMywY/5bdT356DI6 + U55G86T9/bf6uw6Kc83Vx/02GOOvPr+KFpfkG8f8e16MfZ5Qf9bAP7+eD1OeOAeSCXO8vnyDzB/q7Hpb + TA8XM5HO7GOD35AOKs5gWRhNJ+/tubxf4eM/YIs/8th8nBzwTnntxFFI20/v7YjfqhPyHj/TH6/vuvJ2 + +vPNTK0vnSfvP+XtT/x7zdfsEYyRu/8AHTz0OOlRQtLtY+YMb9UH/HrMOt6+cjdyT+mDn1oAWWRsL++t + v+Yb1U45uxjP77qf5Zpxkb7SmZrf/j8zkL/1D35/1/I6jthgDzTZWlG0eZ207/l2m/5+xjo2DjqDz3Hs + Xky/aUy+f9M/59puv9nP0+fp1GOufm+jW69V+YEUkjYTM9t/x6Xn8J3Z323/AE2+9+I49alkdvPf99b8 + rYAYUjn7VPwMzds5b8OKjkaX5QZBj7JecC2mzjfbfxBwDnuc4Ge/eWQy+fJ84J22PP2eUdLmfHG7sSf9 + 4dOhpAMSRvtEv7+1/wCP5ei9v7Nizn9/93t35PTvUYkba+Z7UErqhyVJBH2r08/rzkcH5e9So0v2ib94 + OL4EYtpv+gdECT84yBn3HI9ssDS7ZPnH3dUH/HtMR/x9EnjdjJx6ccjqKAHyyMWH7+14+wE4XjP2vIx+ + ++mR128givn/AONbFvE3wj/eRPj4pfDn/VjGP+Lv/B3p+8fj16c+tfQEjS7v9YP+XAf8e0oHF3x34P4c + ggDqK+f/AI2Fz4l+Ee5s/wDF0vhyeIpIxn/hb/we/vMR9RgHPOa58V/Aqf8Abv8A6XE3wv8AHp+sv/SZ + HK/tv+GdS0P4DfHLxFqHinWNVtta8F/Fyex0SKLU5rDRbGy/Z0+Mkf2KzsJ7/Wkaa7lc3lzc6baaZLdX + iRQJCLZYLJf5WNPmudI1LVp9V8T/ABI1u317x6uqaaJ/hv8AE21u9As5NL8Q6dbQ2baj4Vk+3apFp9xo + qtHpkAbFncXMWkC1s7m8m/qZ/be8EXfhz4LfHvxnJ4z8aa3beJfh78UWXwld3h1Dw54dXRv2evjeGfw7 + pLx3E9nc6p9ujGoR6c0R1CWw07Ns0kcjS/zSfBb4ZeL/ABp8T/8AhE/Adt8Q/G/ifxh8QrvxHYaD4gsp + /DsGmxaR4Z8T6rcaeNY8beJIdFfUrXws1ghuL+90y+1Kx0S1SJJt+n2MX5jxdTVargqMYzq1q2HxFOlQ + p0qc6uIm6tC1GlOdCtKlPmtJOm6cq38KXMp8j/u/6LWaQyrhLxBxWIzTLspwWHzfhnF4zEZjgcTiaFHD + 4edepVxVXE0sbhKOFw+HpRlPESr3tTjOSnTUZSfkun2+q2GmW3he98ZfES91+78J/EeCHxQ3w0+KMeoW + Uus658N7tBaabc+HJddurCKSw1IX91bXE0Vu93BBcajpE+raZFX01+z/APC/4meMrrXbnwt4a+JHxAh0 + LwZ8OfDeq68fAvi+2u5tXs9Z+It/N59hq+jW2rQW7Wuq2X2K4uIZreZFltYdRv7mwvmi+qLr9iT9rKXx + hoetL8FtW+xWHhjxpps4Pjr4PiYXOqax4Kubby0/4WJho/K0W8ErlsowiChvMLD9Mv2GPg18UvhLafE9 + fiV4RvPCMviCfwO2k28+teEdZku4tLfxN9sl3eGde16C3jjfULZEFzNDNIS+2MxoXPkZXw9jc2xdPB5p + luZYHCYmGIxGIxUcPhsP7PEe2q1YRjL+z4wpxqaKNGHLRjGS5aXNaR+p+JHjzlfC2QZvxBwfxr4e8VZ/ + hOJcvrYDJ6ca2I+u4evkmCyrE4pUsHxH9YlSw1KrXu4Suq9BudTkUqZ+SXh39mv9oKw1rx3dXfwc+Jsc + GteMLPU9NZfB2tSm4s4vAXg3R3lZIrGSS1ZdQ0m/g+z3SQTskC3KxNa3FvNNSt/2Zv2hY/A2oaM3wb+J + Z1K403xRBDbp4P1aRWlvrjUXtUM8dm1srsLiESB5l+zOzR3PlSxyLH/TqBIZps/aD/pqYx9m4P2CLGB0 + 65zkgfXApkAkweZ/9bqZ4+z4H+mtlecHHr+mcg19a/DjJmn/ALXmms8PN2rYVa4aDpw/5g76xk2/O1ml + dP8AmqH0x/EqnJSjkPA91Szekl/Z+fW5c5xtLH4p6cRp3hWoxjQtZRptqoqsrSX88/wN/Z9+OWieOvgV + Jq/wp+IWmW/h74gfBe/1u7vPCuqQWOmWOg+NPDF5q13dX8lmtmltZWtjdzyXAnaORYGELSFlDf0MMW85 + P3txj7a3H2cnOdPfq3kcDJ+gySCB0TEmyLmf/V6byfs3P+kLwcZHBORgfXgDD2Ehmj5uB/prZH+jdf7P + kGD3xjnj1PGRz9JkeQYTIKOIo4SriKscTiHiJvESpykqjhGDUfZUqS5bRT95Sknf3raH4x4n+KvEHivm + OUZnxBgsnwNfJcop5LhYZNQxlClUwtOvWxEZ11jcfj5zr89eacoVKdPlUUqSd242JGzMs/8Ax7XvHkdc + yQY58nnH97IBO0ZGcM92PnSfvZ8+XYcfZyvS5n/iMPH584OOTSMsnyYM+Ps16MfuOf3sGPXv75+70GcP + cSefJlrjHl2PX7N/z8z4OBzxge3BJHWvcPzIaC3nP+9nObwYxb9xYR8keTnIwfk69DjHWOIttP724+/q + n/Lvj/l8cHgwDOe5xgEEnHFTASedJzP/AMfY6fZ/vfYIhz745/ujjkmo4lkKsc3H39U/59+P9NfPTjpg + EEfTvQAkpb5f3s/TTulv63a448k5HfI+meQKeS32lf3s/wDx+/8APA/9A5wTjyeGx8u3HQ79uMGklEmF + 5uM400A/6NjH2sdM98468nPpk09g/wBpjJ8/m9/6dxk/2dJyMZGdvB7YBI+bGWt16oCGQthf3s//AB6X + nH2fA/1ltwGMB49846ZPcyyFvPk/fXByLDH+j8j/AEqfsIO3bI+Y5xnGAyRZMJzcY+yXhx/o/Pz23HY4 + B69CM1JIsn2iTmduLE4/0fP/AB83GPbGM4GT33Y4zK2XXQBiFvPl/fTnN+v/AC744/s2PsYQSOxHJxz0 + 5pgJCv8AvrjO3Vfm+z5wPtQOOIMd857HIJ42iVBJ582TcE/b1I/49uD/AGdF6cYxnk5x7nG2NVl2yYNw + eNUAP+j4wbr34zkAdjkEjK9WA+Qktnzp/wDlwyTb4yTdkjjyBgjjH97gcnr8/wDxrJPib4R/PI3/ABdL + 4cffj2D/AJK/8HeQNicjofXqBX0DKsm7kz5/0AE/6P0N4cAkd89Mde+ATXz/APGwMPEvwi3eZn/haXw5 + yX8vt8X/AIOgYEffHXt+Oa58V/Aqf9u/+lxN8N/Hp+r/APSWcH+238ONH8MfBr49+PrG91/U9c8Y/D34 + npqdg+oWMOmwR6D+z38cv7Pi07T7aLS7VXZdVuY5pdRmupbuUWs93cGaJrqvxD/4JseH7bQP2xfDclno + fjW2/wCEg8V+Pb/VX8Qav4EvLPRNSHwt+IOoRaHCnhnxnrGpwzrpmr6eqfb7SS4ks7a3mur/AGS2sC/v + P+0d8HvCHjPw58TvDvw91HRl+J/xcsvEXgzxDLqHirUZbHT9S1b4KfGfw/4Sn13SLCTVP7DsILjXNRea + 4tdCN/d2q3DeXqL6bZW0PwF+yB/wTc8ffs2fHzTfinf6n8O5tIn8QeJ9V1uz0bxNrmo6ikmseE/HGn2V + hollL8NPC9rDptpe+LPlhutVYwWFqvli4ud7XHx+NwWNxGZ5PXw9GpUoUa9F4iUFH2ajDG4Sq/ayeJpO + MaUITrU3GhiXOdNU7U03I/pvwz4x4ayHwo8Y8hzbib+yM44hyr2OTZR9WVZZzV/s3MKHs1V/szFOhJ1K + tOjzLGYNJVXLmbSnH9iii7lGyf8A499R5888fv7f/p4zke3X+bnUb3+ScHyrDpMc/wDHzPn/AJeOc9O+ + MdBR5fzqQi/6jUDzLJuBFxb5/h5I6DjnjNOdB5kg2Kf3ViQBK+ebmfnleSSOeO3HUgfcH8ujQq+dL+7u + ADfJ0uDk4sIuM/aOMd+ny9+xbCq/3J/9ZqZyJyORetjP+kdPw5I9wDKseJpfkTBvVHEsnT+z4evydPX1 + GORTIE4PyIf3up/8tnyCL1uo2nPIwOnQeuKAGBV2xfJP9zTes5wM3IBz/pBB3DOP7uM4708qBPGNlxxf + Nj9+cg/2c56faOef5e+Agj/dw/IgwmmkfvZCP+Phc4+UduvI4I4p5jBmjxGh/wBNY/6185/s98Y+Q8Hj + 68depAGMoOw7Jz/o17jM5ycyW+ePtGOnUcYJGB3pZEHmudk4Pl2HWdj/AMvU/GPtB5J4zjqTkgdAxjKH + YpP2a+x+9fOPNgzn5eD6nb78YAL2jAmk+RB+7sRkSvuA+0z9fl+mT1xmgBoRfOkwk/8Ax+AH9+en2CPr + /pGc9DuznHGe1RxIuD8k+d+q8eeTki9Yf8/HBGTn1J6HHEwjHnSfIh/0tR/rZOB9gixxt+7754z+NRxR + /Kw2Jnfqf/LWTtev1+UkYOMD1z7CgBJUX5fkn5Gm9Jzz/pYyc/aBggH8c556h+1ftKgJcE/bcYEx/wCg + c52j/SOD0YsD0+X2pssY+XCJyNO/5ayYP+lgEn5evJzzyCc881IU/wBJT5VH+mY4lfkf2fIeDt6Z75zv + GOM01uvVfmv6/wAtwIZFTCHbOP8ARLznzyT9+2GQPtP6YP0qWVF89/3c/K2HHnkn/j6n5z9oPBPHseeO + pY8Y+QhE/wCPS8I/fSbvv23P3eo78duoqR4x58nyJ92xziV+AbqfnO38wcDpg8nCAYqr9ol+Wcf6ev8A + y3Jyf7NiOP8Aj5OBnk5IHHXPBjCKFcCOc/Lqn/Lc4z9q9ftA57YyO7YNTJH+/m+SP/j+XJEsh5/s6IjP + ynA6/p07MEY2vhE+7qnWWTGftRGD8nXsOegzgdCALIq7/uTD/kH8eeSRm7Ocn7Rz3AOSRjoOtfP/AMax + jxN8I/lkX/i6Xw5x5knmcD4v/B0DafMk/HkdAD2r6CljGcbIxg2H/LWQjm6wcHaOvp2HPU18/wDxsG3x + L8IxgAf8LS+HHR2YcfF/4PdMqPbPPXt3PPiv4FT/ALd/9Lib4b+PT9X/AOkstfHzxD8NPhbY+KPinpEV + h4l8WeCLrXvHPjbQo/FMt7q8kfhP4N/FbW7Gw+yXt1qcPh6e+sbO6sLNoLC0jFoyI0ctraQwL+eEH/BX + f4a3lxeJp/w50vURpeuDTdWks/iXpzW+mO+jXd99rv7l/CcUUekR29neK2pwm4tFvLO7stxlsr02v2X+ + 24/gCP4LfH3/AIRmx0iDxtH4F+J8fiuWTTbjTLvUbp/2c/jbd6JBc6rLZL9uYW0l9PFNZnUjZ2k803kh + LlfN/AP9n79ne9+J3xo8O+AhL4Q8ADx74r8QeItY8TabP4j8YTyatpfhLxr4meSbQtVufD8MkF/K2oWz + Cy1rS1svtkMsMU1vZQ2DfD5xnGY4HE4DA5bXhTxGOVSNCnOnQnGriXUowgpSqp+zjaTUbSSdRrnagpNf + 1L4M+Hvh7xRwnx1xRx5l2cYjDcJ18qrzx2WYrF0aOByqUcRXzOpiKGEqRq16iw9GUqap0a1X3bUo81k/ + 0ki/4LB/C65t11S3+HWnT6MumeKry51pPiPYDTrL+wtV8N2F1a3kj+EEuIdQup/EektpNn9maTUoLmGW + A4ubBbxbj/gsP8LbdJdRuPh1p1vo503wpf22tSfEiwGmXw8Q6v4l0+0tbKRPCD3E2oW0/hnVn1e0Nqra + bb2zz3DYtdQFlg2n/BHTwxp9nBoth8adItfDqaF4u0efQx8NNYkt7m28QX/hie+Ml1N8Y5NQjc/8I7Zo + nk3caFZ7hnR2k3Ut7/wRy8M31vd6RffGrSbrw/JoHhHQodDb4ZavFbW1r4d1DxVNYmO7g+McWoNID4mv + EfzbuQAQ2zIEkQsdebja/wAEuT2q6ZN7R4f2+tk63J9a9hqlf2F92pHvKh9Db6z/AL5xN9W/tKy04uT/ + ALO/siL5rfVeZS/thON/4vstbeydzpJf+CvvwzstRez1D4caZpslz4ittH06W8+JWmpaavLceEdC8Rw3 + mn3EfhOVJNIaw13TLf8AtS4FvanVLm209XL32nNdkn/BXr4dWc0Vjc/DG0h1i407xFq9todx8RtPi1We + HTLyRZoEg/4RN4kubiRJzpFvLPFc6rbWl5dWsRTT9TFnlXP/AASF0bUtbn1jV/jlpOpXcPjCx8T6W0nw + v1O3XSdTsvD3hTT4XhWz+MEC3EYHhXTbkx3ouFaUzRsDbyyRyQSf8EgdGvJrbUbj45aW+u2OmeItEsNY + f4Xaj51pa6lLrcN0Fs4/i7Dp8of+3tRZFmtpXAlh3ySyW8E0eXNx3yRvGKnyLm5VlHL7V06tuXmqc3sf + aew9tzfvVeoqKkrEQw/0OeZc+N4lUPZZvzf8lZf2kcbRWTbYXXmwPtXU+yp2dZxnyp6h/wCCwHw4MV/F + bfC63vNU0fQtI1290K1+ImnSavDa3Eu5IvIPhRYDeW5MI1e1iuZZdIjurGW8VU1CwN1dtv8Agrx8Nr+5 + nTTfhxpWojTtffTtVns/iVpsltpTx+HdS1V72/uZPCcUcOkrZ6Xfr/acRntPt1ndWgfdZXzWvKv/AMEe + NDMOqXFv8dNMttc17w/o+galrqfC/Upbi5s7WHSbCDdZy/F99NjMcWh6aXFtaW5bypiGjkubiWXTtf8A + gkToumalNfaT8b9J0241LxXd+I9XaL4Y6nP/AGnqd3pevrcvMt38X5lt0lfxBfyBLH7KkTGBEXyIIoEc + pcd2lyxXM0uTmWUcvMoUHPnaqt+ydT23seW9RpQVVJXYvYfQ5s/9s4lv9Wym2nFn+8vFVlmqV8LtHC+w + 5G/cUub2XNJWVpP+CwvwvmtE1S3+HenT6KNL8UXtxrSfEayXT7I6FqXhuwvLO9aXwglzBqd3P4k0k6VY + /ZWl1KG5SSEj7TYLercf8Fh/hba+bfXPw50230htM8JX9rrb/EiwOmX6+IdY8UadZ2llKnhFria9tbjw + xq0msWxtk/sq0t5Li5fZbagLDBt/+COnhixsrbRrH406Ra+Ho9B8WaTLoafDPV5Le4t/EOoeF7u+L3Uv + xie/jbf4ctQohu449s1zuRi5akv/APgjj4Y1GK70nUPjXpN34ffw74N8P2+hN8MtYigtbPw1eeLDYPHe + QfGSLUpJdnie7iczXkoxBbuAJQXq+bjfmvyScPa7Wyb2n1f2+n/L1w+tLD20v9Xvd819DT6v9DX6wv8A + bOJfq/8AaKT04uv/AGcsoTu/9l5uZ5v7ui9rydFS946mb/gr18NLLUUstR+HGl6fLea/DpOmPefEzTY7 + fVJJ/C2k6/DdafcR+EpUfSXstXsIRqVx9ltX1S6ttORmmvdON90dt/wVF0SXw+3iBPgjdCzWy1bUGibx + zaC5CQyzzTIEHhJomZGikSDMyCUbWcwbyicRdf8ABIjR9T1o6xq/xx0nUb618WW3iXSpZPhdqVummanb + aJ4Xs4ZreOz+L9uk6L/wi+mylLwXKtJ58bZt5pIG2rX/AIJZXUXhx/Dy/tC6YYHsdY09p2+EshlxNLPD + JIB/wtUKCWld4lKsEARWMxUu3POXiCoUnShQ9pen7b2n9lqC+Pn9ly1G2rKm25+9z86gnAiND6HOnNjO + Jl+5zduy4sT+sLF0FlC/3VxtLCe2dXlvHnUfa2nY17j/AIKmaFH4Zg8Ut8D7s2E+naLqUcK+OrQ3fl3c + kEsCPGfCKwiT/SI1m23DKi72Rptqh9G//wCCn2kadf6NbzfBKdpNa1ttOtTF46tiiTx6BqmpsZ2bwejJ + B9l0m42tEkzm6e3jMaxvJPFyFz/wSquJPCsHhQ/tDaYLaHS9E01bofCNxNizkt4IZWU/FYpuJgR5Fxhl + LopTIYamo/8ABLq91C/0OeT9oLS0k0XXX1GAR/CSXbK8nh3V9MZJc/FYsI/K1aZhtIPnxwkkoXjbNS8S + Lr93hH71fRPLr8ns4/V7Pm3c+ZS6pWcktglh/ob62xnE7/c5PbTivWtLF1VnF74Ve7DB+ydJNWcr+yTn + zJa1z/wU+0eLWdO0JvgjObzUdD8QapBIvjm2NutvpF54dtLpZZD4QEq3Dya5Zm2VYZUljjuTJLA0cSz/ + AGJ+zl+0ZY/tDW/i67g8GDwlL4VuvDlvNby61DrUd3Fqz6pLDNHcLpGltFIj6fcJPC9uyhDbus7l3SL4 + fuf+CXN5Lrul68f2g9LFxp2geJNMjgX4Sy+XLHrF94avJpJCfirv86F9Ct1iKsF2TTblJ2FPtP8AZm/Z + wP7Otv4ytLjx5Y+NZvFV14ZuTcQ+Fz4YisI9IfVo0hFs/ifxG9zJM+oyPJN9pgCqsSCDO529TJHxm8dQ + /tqGHjgfYVfbun9T5vb80/ZKKoTlNLl5L29297vv8R4k0fo3Q4XzSXhric8qcULNcvWVwx6z/wBhLKXQ + wrzCVT+0KEMMqqr/AFpR9pJVeVR5E4tN/UaJGZ5f3Fn/AMfynhlIJ/s6MfMfJ4XnIPJ3ADvkM2IVfENo + RjVB8zDH/HyM5/cnBwMLj+Ec+0iPELib97ac3yjgKOf7NiIB/e9On88YpgeLbJ+9tOmp9Qp6XR/6adec + j/Z47Zr7Q/m8fIibh+5tB/x4DhgRj7Wc4PlDk/xDHA5JPNeAfGtQPEvwjISJM/FL4c/6ogjH/C3/AIO4 + wQicevv0r3+R4y2PNtD/AMeB4Vcc3eD/AMtDzxz7dx1Hz38b7iGPxN8JP4wvxP8Aho8j21tNLHDHN8bf + ghp0UlxLCssdtFJfalY2qNO8aST3MaISxIrnxX8Cp/27/wClxOjC/wAen6y/9Jf57F/44/8ACs/i5a+K + /gTo19Bouu+IL7xB4V8e3mlaA0V3Zp49+EHxU0YaobtrS3sNW1GCCa7uFMlzdFZYRFchBOpPwp+x58K/ + g7qnxr8R+Jvh/wDErxvr2tfALxhrHhvXNK8R/C/WvBtpdajrHhPxH4WnmjvNXk3hbHUJPE2lXOi3EVj4 + is9T8PvdX+mWujX+jXur/ph468d6LqPxD0HwHb6frNnrXhfxjompajevpanS7628Q/Dz4my2DWmoWxug + zINNu1mF6lkwnVYYfPYyol7QvCHg3wtqOsX/AIY8MaF4bvfEmuXOreI7vQvDum6Tda9qt2up6lc6prVx + p+n28uqaldajqup6hPeXzXNxLd6jf3UjtNdXEr82Ey/JcVSlisfgKmJzPDSpvKMVHERpU8FVVahUr1a1 + GVCpPERqUqcqdGnCth/ZVHGrOdaMfZT+qwvGfFeQ5bnGQZNnmMy7JeIqKo57l2H9n7DM6PsqlKNPEc8J + OypVakHyOLcZtaXudH5mHUean/HvqPWJ883FuOD5nP8ATjJ4pzyZkk/eJ/q7D/lk4z/pM5xnzPX+LPPq + e8ZkXco8yYf6PqPy+SepuLfgfuOhz+o6GnvIvmSjzJj+6sOPKIzi4m4/1PQZB459yOnonxookJll/erx + eqf9RIOlhFycyc4HYflxTYZDjPmqAJNTH+pk6m9b/pqM57DPHHTBNKJV86X95OcXq5/cnI/4l8XPEA6d + xg9enamwyLjHmS/63U+kJ4JvGwf9UfvevQe2OAAEh2QnzU5TTR/qXGcXCnj5+vPJ6HgDpTmkImj/AHqc + 3pPEMh/5h8mdp8w9x3PB9DTPMXZF+9mx5em4zCcf8fA6/uRjA5B4B3Y9qcZF86MCWfi9bjyDznT35/1G + QDn2xzyAOAALn5R5iZ+z3o/1T5/1sBIz5g6+ufXqae0h86Qean+rsDxC4PF1OevmAYz+f48xtIuU+eYn + 7NfYBgORiWAld3k9u+TkkLzz8z3kXzn/AHsx/d2Py+Qen2qYf88c5BxwTk4P4ACrJ+9k/epj7WG/1MnI + /s+MdPMH024J9uRiKKTKN+9TIfVCP3MgAzev28zk8Ed8ck+tSLIvnSfvJj/pgP8AqT0+wRncf3PUdMfQ + 4xnMcUi7W/ezn59U58kjH+mMAP8AUdT0/A9KAHSyHCnzUGP7NH+pc4/0tSf+WnuMHHtnnBcXP2lCJFJ+ + 25/1Mn/QOkHaTIHGMHBJ56YNRySJ8v72YYGnDiE4H+mLx/qPx/r2qTzF+0p+8m/4/f8AnkRn/iXPg/6n + k5+XGPU444a3Vu6/roAyR/ujzVOLW8AHkuD9+2wN3mYHUc5xzznpUjyEzufNQjZYZ/cuBgXM/wDt8Y79 + j6cVDJIuFxLN/wAed78vkn+/bHAPkdMd89MdetSySJ58n7yY/LYZ/ckZ/wBJnHTye3bHPXrjiVsvRAIk + h8+b96vF8vPkSDH/ABLoxn/WDP3unPrjrTBIdsn72PhdUz+5cjJus9PM9s9DgZGeOHLKv2iX97OR9vUE + +SeCdNiwc+QOOxx2I5HdiyJtfEkwG3VBnyDgf6V0/wBT3zn68ewYEskhLBvNQ/8AIPGfJfGftZ/6aZB5 + z244r59+OMn/ABN/h+C6sX8ffB4DCMmcftVfsstwGduMDnAGcZ55x9ASyKW/1sxB+wcmA4OLs548gc55 + GOvHWvnf46uDrnw1AZ2DfEP4QjLoU6ftRfsvHgeWnPGCO3oM1z4r+BU/7d/9Lib4X+PT9Zf+kyPXPHXj + OfVPH+g+Dm8KeLtLTwx4y0W8i8U3um28fhfxIut/Dz4myNb6BqQnn+2T6S1gsWrwPFbz2k15YjY8czlf + EfgD+0rD8d/Fvxj8Mw/D/wAZeCpPhB8QbjwjcXfiG48LXUWsS2g13Qb/AMsaHrGqGDU7DxJ4X8S2t3FB + 9v0J9Mj0e8sNfvb+81TStD988fa1rl34v8LaPd+Gbiz0fSvH2n/2Zr8eolhrLXvw0+INzdsLOS1skgh0 + +VI7J/Iv9RlkuZQ0kFtFGJm3+kqYhn/4/GPMq/8APhL0/wBIGPXORkE85JzrldXDwwOLp1cN7etW9nHC + 4j21Sn9UnCpSqVavsYLkruvRjKhyVLRpqTqxXOo20xyftoWdkoptWvfR6Xe2tpaegmTvUbp/9RqIxsiw + M3Fv38voc+vfg4FOYkvIN0xzHYD7sY4+0TfL9wcDPB6881Hk7h+5uf8Aj31Ef69QcC4t/wDp4yCOM8cn + B5Jp7k+ZJ+6n/wBXYYPmqT/x8z8/6/r1wOduOgFWcg4FvNl+ac/6ap+5FwPsEPzDEfUdecjngdKbCTg/ + NOMS6mPux45vW5+5nnuCOMnGMA0oz50n7m4yb1MYnUk/6BF0P2jj3PGR1OSBTID0xFP/AK3UxkSoOPtj + np9o5A684zjvk5ADJ2QndOcppo+5Fk4uFPP7sDHORjBzkEngU9i3nxjdcZN63GyLB/4l7jn93kA9MAjq + e4qMcrF+5n/1emZzMpAzcDGf9IOc4wOvPPHWnH/XR/ubji+YZMy5A/s+Q8j7RyO+OfQdSAAKxPyKDOP9 + GvcDZGeklvxnZ+PPOcc4zlzlvOkG64/1Vj8pSPtcz9xGDkY+nHIINRsT8v7qc/6NfZLTLk/vYBz/AKQT + zwMY4JXgY4e/E0h8q4Hyafz5ynk3U4PH2nr+HrmgBykmaT5p+LsH7kYOPsEY3fc5IyOAMHH3c5qKInaf + mn4fVBykfGb1+gEffGD1PcYp4z5z/uZ/+Pwf8tl/58IjjP2jqeu7nsN1RRcAjybj7+qf8tlx/wAfr8n/ + AEg9M8+pOBmgB8pOFO6cf8g0Z2RZ/wCPtSQMx8jv0J9+uXnP2mPBnyb3P3Ysn/iXSDJ+TqMbeMDBzjPN + Ryk/L+5uM407jz1GcXY5H+kcdenHXODgGnf8vKjyrgf6dj/Wqef7NY4H7/rzuJJ6ZXPzYLW69UA2QnCA + tOf9EvBt2R7eHt8jIj3YxznOfepZCTO/zTn5bE/diBOLqf8A2McY4wOcnORjEMh4T91cDNpeAkTKT962 + 6AXH4EY9CRgVLKSbiT91cfdsf+Wy5P8ApU/cXB4+p+XB4GeZWy9AEQnz5juuDi+HVIhj/iXRDIxGM8E9 + cjAPcZDFLFJDunGBqg4SPjN36FD6Z78kgYHFKpxcS/up+b9f+Wy9Dpsf/TwQB+QPT0poyVkzDP8Ad1Tj + zlxxdYBz54HXjHXILcnmmBJIx3A7pyT9g5MceTi75GAnbkgj/wAer5e/aG1SKy8V/Bazlh1KZ9a+Kfws + sbeWDT57m2t5IP2i/wBnDVGm1K4tYGh0y1aHTZraO7vngtpb+Wy0+N2vL21hl+oJfvDMUw/48MgzKQP9 + LOP+Xg5JHTk44PGK+Zv2gGx4o+EY2Spu+JfwpH7xw/I/aV/ZmbgiST0bPI5HU9Bz4r+BU/7d/wDS4nRh + f49P/t7/ANIke2+OtZ8aXfj7QNE1TwbBp3hHS/GmjXHhfxfF4ht7lvEk958O/iU2t2s+ixwR32ky6LPF + YRJ9o823v47x7i2uN1s0ddcyyCWP5B/x9sOZ5Bk/YpeDx0xgg+nGMdfl39tXXvihpnww+Mlwbaw0Twvo + PgHxzrHw98Y6Fq+o6T4ut/EEX7P/AMcLrV7hJ7O7kubC/wBCvrbRLjRdUsTo08LzTXNvcS3Nsoj/ADD/ + AGPPHvj3Vv2m/hbpOqfEbx/4g02+v/Gcd7o2v/Ejxnr+k3yQfDDxneQi80rVtav7C5WC7tba8gee0kMF + zbwTxbZYkkX52pn9HLcXleWTw9erUzSvyU6sORQpNzpUuaqm1L7V7RT29bfrfDXhRmfGnB3HPG2EzbLs + FhOBMFHF43A4qGIliswi8JiMXyYN0oOnGajh5QbqyilKcX8KZ+7eJPMX5B/qNQ6zybgPtFuOm3qOmP4j + tzTmD+ZINv8AyysDxPJnH2mfkDb1OOnbB/BhSTcv7i3/AOPfUerkt/x8Qf8ATDt/Dyc8dKdIknmSDyYP + 9XY5w5z/AMfE3I/cY3EcMOwAIJ6D6o/HLiqJPNm+Uf8AH6vS4kIOLCHg8HAA6n044FJAH+YhRjzdSGfP + k5H21s5GPbgd8DnBOVCSedL+4ts/bl6OeT/Z8R+b/R+g79SRimQo+P8AUQcS6oB856fbHzn9we33R06c + jpQAAP5cPyqPk07/AJbyED/SE6cc5wOOwweacwk8+PCAf6cf+XiXP/IPk5A2jtjHHPHPNMCybYv3FuP3 + em9HbAH2kYx+4HOevtinsknnJmC3P+mt0Y9Dpz5x+459ueeOfQC4MHJQbetve5/fuG4kgA4xwxPX06nk + CnMH86T5VH7qxz/pEhOftM4xjHoeT1HPFRskmEBhgANtfZG9t3+tg5P7nGR344yeexe6SedJ+4t/9XYc + hmLf8fU3/TD69x36daAv/X9eq+8VQ/nSDaOLtePtEmAfsEfH3fu89evIFRQh9jfKv39TwBPIePtrnk44 + x2H8TemKlCSec/7i3/4/AMbjgf6AmV/1H3O56c5GOMmKJJNp/cW2N2qcB2x/x+PnP+j9Rng9yW4FACyh + 8L8o5/s7/l4kxxdrj+HAPPOOx5HSpCH+0x5X/l8x/r5Of+JfJ8oO0/XPrhelRypJ8v7i3ORpufmbB/0t + cZ/cHntjuM88U8rILlcwwD/TRn5jj/kHP38gfL6f7Y6cnDW69V+aC/p/Vv8ANfeMcSZT5Rxa3uT58u4f + Pb5OMdcdR+oqRw/nv8g4SxxieQ/8vM/T5c9ufTHHWopEkwv7i3x9jvOjNuPz23OPJ+9ntz9e1SyJJ57/ + ALi34WwIw5wD9qn55gxz0bpjjk0ley9FcBsYfz5vlA/05ek8hz/xL4jz7d8+uOQKYA5SQ7QeNT6zyYx9 + qPJOOoPHpjnvinKkv2iT9xbf8f46Mf8AoGR5zmDp/XApoVyrHybc/LquMscY+1Dv5B56gf7IJx2AFySQ + OCMqOth0nk4/0vHDEZJx27Y9818v/tCll8WfBkEAb/id8LhjzGfJ/wCGkf2aW+Xdg4G3J9/xr6glSTdx + Bb/8uGcO23/j74x+46kdenGOuOflL9oyYReOfgNbMsaTX/xW+HEFtHFvczS2vx8/Z61W4RcRLgQ2GnXl + 25YgeXbynjaa58V/Aqf9u/8ApcTfDfx6fq//AEln2N8VPC0ni/wde6TbafoOo6kLi0udMi8SfbV0qO4S + Tybtp5dOR76IT6RcalYP5CMtxDeS2d0ktjc3UT8ZP8BPhtp17o+o+G/Bvh/S72LV4bm+nxqkUsunTWc9 + jfW9nLZX8DW8zwyq8SuJbNpUZpIBNJ9pQoryE2rWbX7xbNr/AJ9nrNJuSa+xJ/OzV/u0NC++FWjf8JH4 + eax0q0Xw8LLxDHr5udf8SnUpLi8k02TSYtMtY7n7OR5sV9Nc6jcajC2mwwRWFlpl6NUe80aeL4U6I3ij + UZZtLtT4afQ9Dis401zxIuqw67ZalrM99LJGLtbT7Bc2dxpiq63BuJJbWaK4ha3ZDRRRzz09+Wr1959n + 5+RShDX3I7X2XdIbovwq0j+0vFT63o+nfYT4jgn8J/2Zrvih7n+wl8LaBazDXo7m7it49SPiGPxBJHba + eZ9PGltpM7N/af2wrm6R8Jbe38LakuoWWk3Hi4T+M5NNuE1fxW2hbb/XNWvPDUd7E2oRXvlW2nPpMF/F + EXe1kiu7fT7iSERzSlFLnny355X5f5n29RRjFtXjF+9/Ku9uxInwk01/BunwzWdrb+Lxo+iR3l5ba34i + uNJj1m0FvNdT24nninubE3izkLLaWlxf2myC4NqWD27/ABR8K9N87w1N4Y0zTUZfFFhdeIhrWteKCkvh + z7DdWWpxaZHaX0inVNkls9hBceTp3nI9xOwmAZyinzztfml8aW729z/Ni5YqN+WN+XflXYk1H4TaW3if + w6+nWOnp4YTTvEVv4mtbzVfFLaxcXF82mSaLPo88GrLawm2mtb9b1rtHdYLiNLExMHIzrT4Vf8V9rT39 + hoT+BZtKsRotvZ6r4th8SW+pWhtJW/tHfqL6ZNbSXEuru09q9vLLbPp1nc2sy28s0hRQ5z096W/8z7Pz + CUYpS92O9P7K6unfp1u/vL3hz4UWaXGvP4ls9JuTJruoXWhjR7/xXbLa6UXltdMtdRS81y4We6j0tLP7 + e9sLeyn1E3VxBaQny3bnNB+FGow+B9Th12z8MHx9jxEunXWn6r4zufCyXF9cXFxpct1FcajY6mbd5Ghu + JbSLMujW8raPZ3+qizOr6kUUlOd/jlrFfaf8sH301b2K5Y2l7sfjf2V3l5EOufCnXv8AhWcC6FYeDT8V + ItO0NJJtY1rxz/whF1q+n3EE947Pp95HrNtZXLLcOrJZTTujpaXEckZE0W14s+FSSXvhZ/CNpotrBH4m + sLzxVDrepeK5JLrw+FS01GDRJrTVHgtr/wCyPK0EF3ZSWdxclJjNY3Aa6JRQpzdrylryX1fV2f3oiUYq + EWoxu3vyrsvL8VqJqPwo3+N9AfTrDQv+EEGk6jbeIbW61bxfF4oN9dLcPDcaXcwanLp01v58OmKY7hLO + 9tEW8mt7+QSraG/Y/CnTH8Wa5PqFrZt4eKWUej2NnqPiKK8jW3g0+dZb6R9S8r7SNTbXTM9swgvtOutJ + tJraKXTLifUSinGc/dXNL4W930St1L5Ytu8Y/D/Ku8V27GZ4V+FM0eseNX8V2Ph240yTXnu/Bv8AYmqe + MI7qDSzHPZRW2vwXuptbfaIbGLThIthNJaXOoC/1BY7UzW9vBgaV8J/EUfw51aLVrfwdf/EeR9fTR7yw + 1TxxpnhVV1K+km09b5LnUdX1OM2isEaSGG4MUcaRWyKpkdyilzz5fjl8DfxPe8ddxcsbx92Pxx+zH/Im + 1L4U+IJPAGhR2Nl4Ph+JBttCGv3txrXjZ/CKXdipub+XTraC4h1O9gkv1SJIJRpEl5ZyObm4gEUdm93x + t8GbG58VfDXWPDXhbwXdx+HvGWn6/rF54vvddv8AUNPhs7vSmjl8JWr2+qWkOqx/ZjqVvNcXFlbW+q6X + pkwie7mTVdIKKFObbTlJr2kVZt2s1C6t28ttyYpKMWkk/ZRd0tb+9r6+Z//Z + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAIAAADWjhTKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAAKH5JREFUeF7tfflX + lFe2dv8p37q31+1O9/r6++Wude93v77daU1ueoozoIAMxSAJSUxi4jwkMeloBjVOKIMFCDHGCRAEHHCe + iWBUxCHigANjMc+a73nrqd7uFKeqqAIVCc86q9bjZr/77LOf95zz1mvVW79ITEzc7ER6eroQzUkA4ZlO + kKekpJAARgcdITk5mSQjI4MEMHZht9vFx+igI/QPi85feWXe2LFz3NqLL74nfMyY2ST/9V+z1q9P44E6 + rAxND8eYuc9sdQS/KibOxn59Zgtxf7Fly5Yfnejt7SXpcYJcjIDwR06Qt7a2kgDi8PDhQ3HQEZqbm0n6 + +vpIAGMX3d3d4mN00BGamppIxJiXdz0qas9rr+1jS0jYSxIb+9g4Y0bxP8ne2bMP9/VZCeuwMjQ9XmPm + PrPVBfGrYi0tLSTGfn1mC3EtgfHvzs7Omzdv3nGiyglyMQLCbztBfuXKFRLA6KAjXL58mcQYFiDHqLq6 + upA9c8XZRgJgbG4EwHlDQmNTU9ekSbmiH9T1LjD+irPh4MHbEoFAyUhQfQoAaAdJDAKLXWcrHGORCBIW + kKO0g46AUpAY+/WZrSXw119/jX8fOHCgtLT0eyfOOyGcBNBcUF5e7mIeHLSxrKyMxFNY8jVr1kBgZM9c + MR4SQLg2QmASHpKaej4+vhj6UVrdILBwNwebrRBF1mFRMhJUnwIAxmQgsDEx4XI4IGEBo4OOIM7GsFIi + wJgtxHUt0SUlJagp5zXFF04CaC5ALBfz4KCN4uwpLPn69esHs0THxBRxXnKCau5pBqOFheVXVTXpsCgZ + CbKSJLWDJDPcl2gwEfjRj4/yyvNCNoZEbYr67uZ3cK28fsR+cktNZ7frsL6OC7V1FnECfVTXnjt57So4 + HfCya9fV4OA8m62ovLwWxktHqzZtqahrg68zoZ6eC7faLOIE1pQDxZdzSu5Y3BlhMALX1naMG7eLslE/ + zb0IHBdXvHVrpQ47MgUuu102PXX6a1mvoU1NntrQWv91SVplbVV9053Mk99eqP6++OLBo7dvHb6Yt//6 + 9/tKt566daOru7bw7EEcy7hnztyPiHDVMTQ03+HoSF//XeWNproaR3p2xfcV9/cfuHn0ouPg3islpTVF + WytKLzd39zzcveeSRBiMwGfPPsBcpGzMQXMvAuNSa9my0z5Lph0kmWEtcHZ2Ng7Yt28fBMYfkg8nx2fG + J2xOgMA2u+1Q5aGOjsbyKznR9pnLCj7+tDj7luPmkuKvbVnvfbovee2+z74tPfHoUdve0hLGBdatK0Ox + WNPIyD1nztxrb+koO1oZ9Vbxsn8cX5p07l5tw+Kk8qiZh5YnnVu16tSOgurLx67vL290Hf/oEfZgXPSh + akgM4H5MiFEIgCqQwFhY+AN2U4gXH1+EV7cWF2f9ia2/w9y5h3TYtrY2Eux5ALl2kMQ8ZStcR5CwgNFB + R4BsJMZ+fWYLcd1n8P7L+6Pt0ZzB05Kn/VB7fd+5b9ccSr508/zKkpQ9FScb2ut2VlzaciR183f7txxa + l/d96Y8/dp3/4SKOhTZ4LSy8wV0QDTP49q3mwrwLa1LKL5XdXZF0Lv/IzaaWtp3HHmSlncsu/CEr6VzB + 3rurPz2eueOGRBjMDD5x4u706dY09XcGoy1desLnnNAOkozPbIfREt33sG9p/tKJ6ydOSZqSdTJLXAHN + BboPOuDK7oMPjk+cmBMUlPfNN5X6KHH2FJZ8MALfutWC90iUjfpp7n0Pttsv6rAjU2AAnbV3tXf2dIKL + K6C5QPchDsi2owMLl/UnfZQ4ewpLPsiraFzfUTbqp7kXgXHdcOFCnQ47QgTGWyX4HT58ODU1Nd1/2O12 + FxsABui8YcOGjo4ObCRIDGD5COHa6HA4SGj87LPTuAiAflQOTTgEFiP2YBL8Ff5Tp+ZhR9Nh8faaBAUF + yI3JcA8mNzrI4YCEBYwOOoI4G8MaPZ3JuqJZ74MzMzORH4BdmgTnAkAuRkA4qg+QNzY2kgBGBx2hvr6e + 5NKtS5sOb1q8c3HcprjYTbF4ff+b95MOJB2vPE4HnLnt7e3kxhyMYWm8dq1u4sSduJ6ChGggwm22fBLa + hURFFWRlXZAIhAzN03CEo1zCjQ46grFiGKyxi4aGBhJjWG00ZgtxXUs0ANlJeBlGLkZAuF4EMDYSQBw8 + LThX7lxJPpIclho2cd1EXqijzcicQYIWvCEYf/qs6LOyqjKcgDzKmIP8FXBbooE1a87Fxbku9LgIk3ha + orEBd3ZakXVYGZoer3aQZDiTyI3ZPssl+ukI3NLZknQoadzqcdRV1EXTApMnZCVA6UU5i6od1RKBEK7H + 1l/gnp6Hb711QHT1LnBU1J6qKvcIwKjAFgaSbsW9ivDUcLy9jrXHUkjvAqPFZ8SD431a0cUiSQaQLvTY + +gsMNDS0z5xZgqkJCT0JnJAAdQvLy2skW58lMxZ6WAvMGx2AvH0GEY7USQAx8gwgxzZAAhgdSi6VhKWE + QS00CExC/bxwIRFpEamHUyWa5KMTQxVItBEcFxJffnlm8uQc/t8DGrZbErTw8N1vvrm/qqpRZ6sjyNA8 + Och4QcQuRsBnxeQo7aAjQDYSY78+s318owPAv0noQS5GQLg+R7yfjzvO7ZAbn2h+zWDxid4UvWLvikc/ + WgGlC33yGmew8Bs3HF98cSYmpmj8+F2vvPLtq6/uDA3NX7jw6IEDNzkIPRyfc0I7SDIotNiNFXuWM/jJ + CVx6sxTzT+sXmMAwxmTEZJ3M0l3osXkXGJkgn6b2pus1N05VnsFrU7v1uQPjcHyWTDtIhJ+jwPcc96Cu + 1gwtYIHxOj1t+qkbp4xj8yJwZ0/n7vLdr2e/Pn7t+KANQcFJwXgFf/PrN/PL87t6rXs7ejg+S6YdJJmR + JrDPdHt6e17Peh0XwyIP22AERsNe7mhzsAudGN7jk7hliyUkclNktD1aQkkCaJFpkbZ027lb5zAcQI4i + AWRoerxuXZBwLyQ3OugIgQlsDKuNOluA3BKYd7IAnoYkmpMAwhEXIMfeTgKIw96Le6M2RaGsaJCHBA31 + 7W80cggs/LExM375nuXsAqcgCYAqkGjjtrPbQlNCebhEkARoxysu73eW7pTh6AgyND1e7SDjxVWP2AOr + mPwV0BEgG4mxX5/ZPv5EBwArCQ4DyMUICMe55uV87O7r1hdWqKPwQc5gNLw/bmhrQC/I3tmnhf5LdE5Z + DjcINgmlZ7CExSzPLcvlgTqsDE2PVztIQVhxcmPF9AQNbAYb+/WZbYBLtA7RP91j145hVexfR7TBCwz+ + 1f6v0Isem5vAF6ovcO7KUd4Fxl9xNuDNukQgRgW20D/dpflLPek3eIFhxEL98JH10TJ2CmiB8afYDKsX + 3YVwTwKjxWXEuYUdIQIP/EaHcJ4B5PL+GoBDe1f7q2teRe2kcTdlQ32FS9MOwo1G8snrJ99tvKsTQxVI + YCw4X4DtX/zdWlx6nHAdFg1H4dJBh5Wh6fFqB+Eol3Cjg47gVjES7SDFByAbiQ5rVMeY7dDf6MBCh2td + PXtQO+FDMoMxQbNPZeuTV8/gOTvmiKc+isTLDAZ5d+u7PueEcSah0GI3VmzkLNFFF4vkI11sQy4wXv9R + 8A89NhEY68e4NeO0pxv3LvCk9ZNaOx4PZ2QKXNtS+/Y3bydmJd5ptD7HqjsTrkO4pZtyJGXGZuvtB2uH + 9iQEnrllplHgi9UXgzcGa0837l1gXJohgjOShZEpMJYpTEEMHhcdYiSE6xBu6a7ct1LqxablGSqBE7IS + jALvr9iPrVR7unHvAkfbow9dPsRQwAgR2G63IwqAMuF10tpJMZti0CasmSBGQnhzczMJUFdX52JOh0/y + Pomxx6CO0hBKeFRKVH+jkdvSbML7O9g22XRiNTU1JNtPb49MjdSebi06NVp4f4eI1IjdpbsZCpCh6fEa + C+JwOIQbHbxUjMRTF7W1tSTGsNqow0o0iOs+g/dd2he8ITgoKWjr2a1iJITrc8TtfMSbVJkQbE9iBqMZ + Z/DZqrNYZt08NZcE0PrP4PDU8NKqUoYCRsgMdhMYqG+pr2uuc/vvOUC4DuGWbuaJzKewB8/6dpZR4PtN + 9yesm6A93bh3gXFmVzdUMxQwYgUezFX0wcqDcZlxurhPQuDPiz43CgxjbLqhC+HeBcb+7bNkxkIPa4Hl + RgeyJLFucwR6o+Pa/WuYB6idNEglHPUVLk07SNNGN4fITZG7vtulE0MVSGBce2CtdnZrXm504KISx+qw + Q3ujgwTwdKODBNARIBtJ/7DdPd2lN0q3nNqCN40Ldy2c8+2cxTmLkw4m5Zfn32u8R8+hv9Hx8NFD/YlJ + NNRO+JDM4ClJU1o6rf8+cvX60xlc31oftCGInvooEi8zGJt3Q1uDzzlhnEmouNiNFRvCGYyts6K6YsXe + Fa+ueTVkQ4jb0PD+IiY95u+r/451dNe5XanpqUMsMF5xnYVtmL2iDbnAb379JgapC60FxmvGiQy3bcKt + Cmxa4NiMWBwlEYhhKPBdx90FuxaIrnqMemi0Y0369+h/H3qBL1RfwOWodDa0AuP03HxyM3rRhXYTuPdh + 7+zts/VREsooME7H97e93/fQOlaHHVYCw1h8qVj+h5uZ6zL2Fxjt5TdetvZgJAcwSxLNSQDh6Awgx45C + AtABf3pts1U+dMNsSNCQRH+jkXODdDOiTds4rb2rXfoiUAUSnJckeCOAHHjTFIdLBEmAdrziNE/MSnS0 + /eTLL4QMTY/XWBDuweRGBx2hf8UA7aAj4GzAK/5kP2afnjpdZ64Jmq6t2F9KfGnoZzBQdqtseprr//zR + GQmanGXoW4zaQbhxBkMMjJNdYNgkgNsMJlo7WpfkLuFaIqH0aY6w+OvH+R939VhfjOZRP4kwPGYwLmtW + 7lsZvcnwX+y6jHpoYrdm8JMQGOmicJhA6EPrpwW2bUyc/OHbr8x8748xs19OfH/Cwnci1rwxI9OVmVFg + XEHg0pFd+BQYHEmevnEap8W05GnR9mjkgwTwCg4LyNmbZ7GdE3IUCTBMBN5yZgs2Jq3lsBAYC2lidiL6 + cBd482vTvnjrd39Z8K//8cGv/rD4hRcXv/CnRS/8afGv/7j4l/+5BJYJi95JyDQIjCWhurFautCF9iSw + izzsu+e4t710+7LCZe9vfX954fKd53bWtNTIGPVwdIThIPDRiqNui5AUxM34tAWGQ7WjGslpgaNTYv8z + ZN4v/++S345d9NuX/tl+yv/t94v/z18XRiU9zhIRoO7x68d1F7rQ3gX2ma120BGeucAdPR3BSYb/HPNP + 4MBudJAA3t+2f1f1nVwaRG14/X//ed5vxlgq/mbsQktXZ+vPfzN20a//uGjaF2/wwLCUsNyyXAaULnRi + WMdIjNkCko+nbMVBHyXO8lfA2AUvssiNDjqC94oBYly9f3XMJmtxRoOoJGhc3tyMEFiMYn9SF1n6fLxZ + dxPvQ+LsCb/788Jf/2mBcdb251Aay3XU+jewXx67eoyhAOlCz6QROYNbOluCNwTLvIRaJGj+zeAnLTCM + rZ2t/x0x71cvzn9hjB8C/3rM/BdennPl3nVjDrrQI1LgtKNpmBjPh8DXrjlCQvLGTU3/5R9m/+pP87SQ + Rv7C2AX/8t/vjZ24Liq6ICfnmjEHXeiRJzDeGvE9yBAInJGR0e4EdjIhmpMAwrGLAOT19fUkgNGhubll + 9uyDfI5CVFTeX6ek/u6lD/7lD++h/duLczGn2SD8v/7x/f/1+3d/O2bRmAlro6LzYmP34JDw8N319U0M + BRgTq6urI0HtSIDAstVhxdmTg3D+Bzu50UFHGEgOt2pvjV8zPi49Ljo1Gq9o0I9Ec220pdmESxvz2hhr + BjtP0MfPMOUMJsfZRAIIx+nGMw5ATUkA7UAC1Ne3TZqUw+9cx8QUyJevw6N3vhK08ffjVvy/V7/E69hJ + 60IitsbPcD13IT7eekIKSGTknhMn7rhiqS50YpjBJH5lK2PUDjqCOHtyEM7LInKjgxwO+KwYEsstz8V7 + X0xBmZcyazXXRvHE9H2qS3ROzhWbzSWbfMFevnKPBrH7cxF4xoy9H398kqEA6UIvlSNviV59YDUV0rKR + oA2vPXjZslPUDC0AgdFiY4sYCpAudKFHnsCzvp1FhZ4DgWfNKqFOTqkCEXjKFNc3wwDpQhd65AksUg2B + wEP7iQ4S7YD5B9nYILBwadCyP9fGV1/dwVCAdKETw1UJyeCz1RHE2ZOD8IHc6JAInnIgAWCMy3B98gSy + kegWb/oMDC6p3CxoT+NGx3vvHeRERAtsBgcF/exm8Jtfv8kp+Bws0V98cZo6oQUmMK6zGAqQLnShR57A + H+7+kAo9BwIXF/8QFVVIqQIQGOp++eVZhgKkC13okSew/ZidD8AYAoG9P8IBSpMAYkQGJADSdTHlrB0c + jvbJk3OgFhoEJoGQJJ4492CQ6dMLzp6964qlutCJYQ8m0UbNJR+drXE4+ihx9uQgHHuwcAkLiNGviiGC + 9Qn+ZOvTOZANr2gQlURzbRRP3QLcg/06H3H18NFHJxISrHkZwAyOiSnq7HT9Jz8gXejEmj08hIUEmSAf + ck/ZioOOIM74q55eJIBwSCLc6KAj+KwYjF29XVOSpmAKBjCDKS3501iiYbx/v43PcPZXYKztBw/eNuaA + M50EGHlLNF4X5ix0k40Ezb8l+ikIjNeMjIuxsdbbJOo3EIHj44vnzz/a12fdz2MoQLgu9IgU+EzVmbCU + sOdGYPxrwYKj0dGue9EDERi8tdVKw5iDLvSIFBhIzE4cAoHlRofc3LBuc5hudIiRZwC5fttudBBjR0f3 + nDkHoqPd73VQS81jY7E+F9XUuG5fSARA8tGJBXajw5itjuDzRodEABG7MVsdwdONDnGQCCevn5y2cRrk + dGvD60aHjuBwNGVmXgoNzddP64aiwrEsh4cXfPrpqeZm68PPPMqYg55JI3UGAx/nfMyviQQ+g5+mwLzc + ravr+Pzz0yEhu3HlhcsoiG2zFU2dunvChJz5849cv249rNBnyXShR7DA9Y31bpqhDXeBAZQDDlevNh44 + cGv79sqioqrz52t7e61fW6TD8y7w/ab7Z2+ePXT50LWaa9293QELjN2n2lEdkRYRuMD9f5QDRHMSQLj8 + 5gPg6Uc5SAAdQX5iov2fP7gBGLvAwMRHO4hRR5Af5dBG4c7fqHDl4/MnRHQE/TMXJIB2kAjQjHZHq8N+ + 1B6eHP63r/4WvCE4dGPohLUT/rLyL0tylly4Y/3oBxBAxS7fuRyREhGXEYfdFw3brRtBs6XZhEsb+/pY + 18/LAjgNhWhOAgjH2QqQQwkSQBxwDoqDjoCpRoIVggQwdoFRIQi5dpADdQSHw0GijcJ9ZqsddARx9uQg + EXBZBPv52+dDNobwWwhsmGpCpm6cumLviq6eLr8qhjWP5IHjwRvZb8RmWLerdFgSNMxg4dKe9kWWXqJJ + AGMXGKT4GB10hOGwRGM17v98bOGoNV7jMuPm75zf4LAepkpIBE8Vw9lAgn47uju+3PtlaEooP48nYdmM + S/SowBa0g44wcIGvPrgalhLGmnoRGA0af5L7CY8CJMJABCapvF85d/vciesm4urai8A426YlT4tYEDEq + 8GAF7unrsdltUmvvAqOFJYed/MH1KTPJYeACA3Cob6tPPpI8c8vMyE2Rk9ZPmrBuwt+/+jtesUdgq/4g + 74O9l/Y+fPQQ4vq40SEEEM4zgBxXBCSA0UFHQMlIoB8JYOwCe7D4aAcx6gioAok2CtfJ+MxWRxBnTw6M + UHShKDItElc0kBNNiBuXhqkGOwMac9Dj9V6xru6ujq6OlvaWpram2sba5rbmto42GCUUxB2dwYOdwe9u + fReyDXwGQ+CpyVOvPLgiEQB/ZzCJz2ytGTwqsHbQEQYicGtX67g14/wVGNsnHwkiOYwK7IJwHeEZCny9 + 9jq2PX8FTshKWLp7KSMw1BMUWN4HQ1QSFBcgFyMgHHEBcsQlAYwOOgLSJTGGBYRzmyE3OmgjzhsSo6dO + xq9sxdmTAzh/G4p7LVREE+LGpVkCb06YvW02IzCUxAeMObj160YAY7auH+Wg5vAWIhxVJgHEyIPJEZcE + MDqIEYDAJMawgNghMLIkNzroCBCYRBuF62R8ZqsjiLMnB0SouFeBdyMQUiarEM0pLTkFXpSzCBEkGiUh + H3jFfGY7ukRb0A46gjh7ckCE2pZavEvhTKV+ngQWIwVec2ANIzCUp4qN7sEWnu1VNB9T4ZfAePN67Jr1 + rXbJYVRgF4TrCM9WYFwPx6Zbk5L6DURgvE3q6bMqLDk8QYGzsrKoKLY9IZqTAJoL2traXMyDgzYiCRLo + RwIYu+CNDnKjg46AKpBoo+YCn9nqo7SzQDswQm1zbdD6oIHf6IhKi8o4nqEjAP3DEt4r5jNbiPuTGYzT + CDOntbUTDQT/1GeTcH2OGOfEz2oGA7lludH//C0wSCiTVbjMYLxBsqXZupw/iglIhCe7RONiu7i46sMP + jyUk7A0Kyhs3bifalCm5M2bsXbToaH7+D/x9e2NFRgUGurq7Piv8jF/Z9i5wlD2q8nYljwIkwhMUePr0 + f0yalGuzWZ92kw9Jac6fVl6/vvzePVdnOsSowACXyqRDSWGp1m+dU0s0LTDkj8+Mv+u461fFhkDgsWPn + UVH5dCOfp9HPWDRlSk5u7jWMBePhkAAUlwTAxkmiHcQINDa6fk9dGzs6OlxM2bGjyE5jdNARGhoaSLRR + uE5GZythtYOOIM6eHITz4xx8Qnd0mvWcRKzY2IDRoOv01OlTN0xdvW91a4e1oRorhsFKF3q8DoeDRPcr + DtpozNbag196ab6bliCak5BHRe1ZtuwkhiMhPAlMAugkjOkaOUomAhsdtFHOG315Ig7O8frIVhx02IEL + jIoLb+9ov91wO/Nk5ge5H8z+dvaqfatO/XCqqe1xv0NYMT1ejwK//PICWY2FaE4iPDa2eMmSY1hBuQiM + LtGAz2x1QZ72Eu2vwGjx8cXLlp1GSggxKjAw0gTGxXZ0dOGOHVcR4lkJ3N7VfvXB1cILhclHklcVrdp4 + eCPeq5TfKm/vbqeDHK4H/HMU2K89WDhaeHh+ZWXd07/RUdNU89W+ryaumzhto3UtE5sei+ua2IxYm90W + lhwG+0d5H1XVVvGDDW54Ejc6AC/ZupiCMQdPBfFeMZ/ZBrIHo/GrYwkJ+95+u8Sv83GQM/jho4ebT2zm + xwr1zb+YTdYbUL4b4eu0lGkr967s7rW+WKzPaGO22sHnnDBmbswWeJz5M5zBAQuMFh5ecPr0TcYCfKY7 + GIGbO5rnbJ8jN4y8CMyGOY3z4HbjbT3gUYFdZIACYxK/957hCSlDLvC9pnsQTEvoU2DyiLSIS3cvSTKj + AruIT4FF4wkTdnZ1uf7bGYs+CTpmxoAYAaRLghRJAO0gdmwzCELuaHPEZbh+B0nuDekbRiJw/7tIOAoa + 3228y1CoAgkg/SJVyVYnJs6eHCQCBBa7Ho5wXRCdgxwVWMV8Zuu6yKJg0E+I5iRuXFpoaN7p0/cYFB2T + IF1mDIgRQLok2mjkEBjZg/T29S7JWQK1IBVaf4JmfCy69kzMTuzo7kA0VMEZ3oLPbMXZk4NwCCzc6CCH + A55yIAF0BHE2hmWJCGO21kd2BrNEo9lsBdnZFVwQ0B8JQuP0IRcjEMASvb9if2RapMxLCOZG0Lws0WxY + APA+CtFQBWd4C9IXT3ZynZg4e3Lony1gHI4uiDEHTxV7xnswWkzMnk8/PcVwPtP1V+Cu3i4ssJiCIlVg + AoNPTZ7a0NYwKrCLDFzg2Ng9c+ceYTif6forcMH3BTHpMUMi8IzNM1btX/VzFDjgGx1scXGFs2aVoEuA + GyeATQIgFyOAJEhQERJAOwjnrYPYdOtRnPGmz0hoY+w/n9hp9JQWlBTU3NLM+IAxW51Y24Cf0cFsyY3D + 0REkLGB00BG8V8xnttZXVwY/g+fNeyIz+EHTg+AN1q8GQRs9F90I2kBmMF7DU8OPVhxlfED60qe8zzlh + zBzZit04nGc5gwe/B3/22RmG85muXwKfvXE2yh4FYYZKYKzSyQeSGR+QvnRFfJbMmPlIFhhX0Vu3uj6D + 4jNdvwTecnoLrn4tYYZIYLzO/WYu4wPSl66Iz5IZMx/WAsv7YGyxQoRDVBLa+xtDQnLLyh6gJ4DjBJAB + CSBGoKmpiUQbjbyjo2PdgXW854zdFK9sENuNoEHg/kYjT0xPZHxAZysJ62RwOpJ4chDOPZjc6CCHAxIW + MDroCOJsDGv0dCbrima9Dx47dh4VxeUSCbZVNDej5iDCx4/f3tbmeoAI9nkSyMMPOQBiBORpKdpo5Dhz + Vxav5ENGcA2FVzbj80eiU12fj9FG7Sn8NftrjA/4zFY/hMXoIByzR7jRQUcwPoSlvb3d2IU8tsYYFqSx + sfX06du5uZe3bTuP17Kyu01NrRIqMzNzUEs0yOLFJVwNAJw4JEOyRCcfTuYzwDD/3BZbTdAGuESjvZX5 + FuMD0pde03Riw3aJxjVyZWXDmjXnbLbCP/95e0jI7sjIwrCwvMjIPUFBea+8sg26bNx4vqqqebB7cGho + /vffV7u6HUC6fglccL4gJsNSbqgExuvSXdaXNgnpy1Lv+RG4oqLhnXdKgoN3JyT85GJIHvSKBjva5Mm5 + //M/CwIXGK+LFx/zK12/BK64W8Gfzh0qgXHJtuW461P+gPRlqfc8CIxOVq8+FxaW7yYEm5vAJBA38Bsd + oaG7b99uwjaAhIhBvm0HxI79w9HqmLTO+uIe9k68sgnXRrnRoZt2YJuSNOVK9RXGB4zZ6sRkaJ4cJAKI + 2PVwjF3oislR2kFHkIo5HG1z5x6OibE+zuwmBBuuitwsaBA3wBkcHV1YUnILZ9aTm8Hw+TDvw4Qs6xrY + bS5qgjbAGYxrcmO21vQc3jMYl2VvvLGfT813E4IEzeMMDkDgmJiiDRvKmcETFbjinrVKD4nAtnRb4YXC + 51FgxH733YNGIZ6IwFB35cqzfX0+fgXBmK6/Aj/68dHcHXOHRODYjNi+h9YPYjA+IH1Z6g1jgXG1PGOG + ddHkJgTagATu/x/+3IPdjLSHhxdkZ1/s7nbtFoCnHYUEECOAsZFoo5FjD2aQq/evhiWHQSE2iO1G0LAH + 9zdqz8i0yEOXDyGaMVsNbdR7MAlgzFbvwUYHHcGviuXnX46IKOgvBIk2QmAxit3ag8eOnU+1YRWiOQkm + Lno6deoeTivnCR3I+ejvDCbf9d0u3pTW81IImvcZjLm7tmQtQz1fM7in52FYWC7rD7VI0EQUbfQ4g+Pi + lmMFwJvl2FjXU9i1wHFx1qO68afs7IquLtfX/p3j9TtdIDCBcXav2r+KX870V2BcWM3fOb+n15X58yXw + tm1XIiPzKUTgAm/ZsgXBq6qaVq8unTXrEBbhkJA8NJB33jn45Zdnrl5ttHZD1bFzvH6nCwQmMIwIuP7g + +mh7tF8CY+4uyV3S2dPpPVvnaFwOw0rg+Hgfv1MzUIGd+T/+iB5mDEAuRkA4smFCANIlAYwOOgIuGUiM + YQHh2NVQMnIx5pblhmwI6X//sr/AINOSp+GcwIWVTsavbMXZk4NwCCzc6CCHA55yIAFoxLwKCrJ+555S + iaiaGwWG8ScCf/2Ef9pOR4DAJMawgNj5Zp9cO1Q3VGNSypOL2NwusoI3BL/9zdsVdytcx6h8dLbG4ejE + xNmTg85WuNFBR/BZMSaWnFyOrROyUTCISqK5NoqnbtZFFmYwFwT0QYJeAXIxAsJ5opEjXRJAHHg+kusI + AS/RJAB5VX3V50WfJ2QlhGwMGb92/F9X/nXc2nFTkqZgn/6k4JOy22XwkcN9ZqsddGLi7MlhgNkCuiAD + rNjbb1s/rK3nJQma9xmMJnbXEq3jAsNfYAB/RRc9fT3YYmvqa/Da3Yt3b660ATncmay3bLWDTuwZCtzX + 9zA62vrJ1p+1wCTAyPt+MK5AJk2y3iANgcB2ux1bI4AykTicIBcjIBw6kQB1dXUu5sFBR6itrSUxhgWE + NzY2ShCjgzbW1NSQGD0BCeVXtuLsyUE4yiXc6KAjDCSHujrH3/62DZpFR+M9qvX5i5iYAhLNtVE8dRsz + Zs7oDB6OM7izs3fcuF2YghDJbVKijS7RFoT7zFY76AjPUOChXKJHBdYOOsIzFPgZX2T5my4JgA2GxBgW + EM4bHeRGB230ft4gE+RD7le24uzJQTgEFm508LdioG+9dQAKBSAwjD8RODs7G3UBeBqSaE4CCEcGAHlb + WxsJYHTQETA2EmNYQDj/N4nc6KCNOG9I5BBAHHQyfmUrzp4chPN/k8iNDjrCAHPYsKEssBsdMIr9eb3R + AegII2+Jxuvlyw3O/wF6Fku0c7z+pUuMCgwMsGL4l88fxR8V2ILPbLWDjvBsBQa++eay9x/FH5DAo3uw + dtBhn+0eDLS3d4eG5kEtNNlWNddGCCxGsY/uwRa0g47wzGcwsGPHhago6/0S1OKkRIN+JNo4ukRbeO4E + xuK0YkXpoD50NyqwdtARhonAiP36649FRRsV2IJwn9lqBx1hmAiM15qa9piYwgA/+C4/L4ssSXDJAJCL + ERAO+UkAXDK42AA+BIqxkRjDAsLlY7OA0UEbUQUSoycgoTxla+xLnOWvgLELXmSRGx10hMAqVlvb+u67 + JXFx1gdm/fvY7OgM1g46gjh7chh4toOcwQDio5NPPz0VHl4wukRbEO4zW+2gIwxGYPg3NXU9eIAYViWH + RGC8wuXChToIPH06ZLbmqIjqJnB8/F6cCi++OG9UYI/6BSYw1toTJ+7GxRUHB+dNnpwTErJ75sySysoG + iTAYgYnu7p6LF+s/+ugE4k+alBsZie15b0yMtURD+IkT0Wne8uWnr11zQNxfZGRktDuBWEI0JwGEYxcB + yOvr60kAo4OOUFdXR2IMCwiHZigEudFBGyWsHAKIg07Gr2zF2ZODcJy45C0tbatWnQ4JyeFTLjCrSKZM + 2bVzZyWdA8vB2C/Ge+XKg9zcCrv9XHLyabzu2XPl+vUaCQVxrRnsPEEfP8OUM5gcZxMJIBynG884AH2Q + ANqBBNARUAgSbZS+ALHjsgXnLLnRQUfA2UCijcI9ZSthtYOOIM6eHIRjBpPb7RdsNuu+BJveLCMj92Bm + w8dnxfR4oSWJ7teojjFbawaPLtHaQUcQZ08ObtneudMSGvr46/duAuMVGuO89atiEJjE2K/PbEcFtqAd + dAR/Bd648TwufLwLfObM/VGBLTyPAkNdLarmFBhXtitXlj5tgQO70QGQYz8nAYwOOgKSIDGGBYR3qsd7 + Gh20EVUgMXrqZPzKVpw9OQhHucCDg3OhaLznp5qgLVx4xFMOJIDuwlgxozrGbK2HkY7OYO2gIxjnhHZw + yzYxcb+etZrLDF69+pxfFRtdoi0ME4HT0y9CQi8CR0TsOX++dlRgC8+jwLW1HdOmebuKjo0t7u21flyB + RwES4QkK/KS/PipHAUiXxBgWEDu3GXKjg45gDKu5hNLZGoejjxJnTw7CkS359u2VfKQGGwQWMn16QXm5 + 9dRWvyomzrpfcdBGHVaiWQ8jDWAG69MNcUkAo4OOIOejMSwgHCVDfuRGB22UhcHoiUyQD7mnbMVBRxBn + /NU4HOGoODncsrIuhodbGssMxroNdY8fv0vnIayYNkpYPd7RJdqCdtARdMmMDp6yvXmzecGCo0FBeePH + 7wwNzV++/Ex9fbtECExgY78+s7UETkxM3OxEenq6EM1JAOGZTpCnpKSQAEYHHSE5OZkkIyODBDB2Ybfb + xcfooCMYwwrXyfjMVkcQZ08OA89WR/CrYuJs7NdntomJif8f3MukU3DaesMAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAMAAABuMnOvAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFQEBA + f39/YI/CY4/DZJDEZpHFZ5PEaZPGbJXHbpbHcZjJcprJdJvLf5/JeKLRfaHQf6bSfqbTx2ZjyGZkyGdl + yGlny3Jw0Ht60n970H180X+FgYGBhISEjIyMnJycnZ2dgKPNjKXPjKbOjabPiabQo7XUor3dpLvbpMDf + q8PfuMTcpsPhp8fkr8vmr8znqczprcvors7ps8fhtcbgscnlts7ht87jtMzktM/pucjguMjhtdPsz4ON + 1YeF1YmD2pGF15ab1pad1pif3KKn26St46WW46ic4q2m4aio4q6s46+v5rGj6Las47Cw47Sz5LOy5ru7 + 6ru167207L6y4bXB5L/P7si878u/wsLC1tbWwM3jys/ixNjszd3rzt7rzOP01OLt1OLu1+Tv2+Lu1OX1 + 1eb02ubw3OXx3ejx5MPO6sPD6cTE68XF6cvN7czM7s7O6cnQ7tDL8NPT8NTU8t3U997S897d7Nrn+OHU + 5+fn5unu5ujv5+ru5uvv6Ojo6enp6erq6+vr6erv6uzt6uzu7Ozs7e3t7e3u7u7u7+/v4ufw4e3z7+Xz + 6uvw6e3x6u7x6O727u/w7O7y6vH37fDy7vHz7PH36fH46/X77/T59OPi9ebm9+fn8OTu8ubv8uvr8+3t + +Ovr+ezr+Ozs+e3t8efx9u/3+e/x/vTr/PTv8PDw8fHx8vLy8vLz8vP08fP38/T09fDw9PHx9PLy9PPz + 9PT09PT19vb29vb38vT59PX59fj79/n89/r9+vLy+/T0+fX1/PX1/vjy+Pj4+fn5+/v7+fv9+vz+/fn5 + /vv7/vz8/fz9/Pz+/f7+/v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5YFIZQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAABp5JREFUeF7tmod3 + 21QUxgtU7B2zS9l777333nvvXfYoo7EBh4hNadl74wElaZxAymxDaRzrb+Je8VX5bk8fOCSyXnv045zc + 7+lq/PosO34K0/wnShhEVYZQldZiBIUbzREEhRsjTQSFG0taCAo3OPMgFxS4kQvaRnuCP6AqPgp2dXUh + CV4KNroK47hee8486PQMFkYRFD6CMw86cQ8WUJXVUrCUMBtV4Vycg6Bwo7sbQTGNIoJSQFUKrlNx5oEI + NhJ6UZUQNaaCqnCjXkNQuFEbQFAKqEqhH0HhI8z1aJALCrlgLqiY69EgFxTaEZTfh0iKj4LmGwUd4dEM + LkQUPBQ0O6UjaO6iyQn2pSNo7iKe2gkL8r81pRnky/0PQflvOVMn2FfoQxImKZjKDPZPXLCMqvBOA+En + SFMpyJeQKaB3iUvQfVPQNVISdH3sWkGzFzbGWMFywmxUZQ6qUuIB52IRQSmgCjI3+MYeg61KoRtBcO9F + 1xBBrE6EyS2aeG00EtGqiY/gRZPMOZLwL4smJGHqBJegxhjBZQgKH9FhQbPspCPkVUVSfBS07x5sVdIR + lHttnInPYIiqpCLofsFcgn85b07OPHAKVug5mVNQXjCRBO0Iut89ExWUCyIJ7c0gX8ItOFXPB1f4lMdW + hc9U6KPrcaMDggWaHLegq5G+oLnlc0GBMw9yQYEbuaA9Uy64igmOeiqIJUGpJL9akQTztwPUGP47grNh + /gxhGqgx3ODMAxHE8qnxsfz+3TzBLMVcqzrzhIMb5tkMN6qoMdzgzAMS7JMZRBTYiQX7zEqzo4KyLqZH + dC5B86/ouCCq4hTUL6n4FmYfYnVakKScM2ieLHRYMHQI8sPFbAVRBUxaf7Va61+40EdB/fq/5Ra47fyd + QcBn8kSwzcdv3MgFVzggF1zhejTIBQVu5IK2sRoLDtSFHv0BONNABXsSulEVzj1FVIUb5RKCwo1SGUHh + xvIzbb+DMFN/AM7jgxmzRRCrE4EXTbyIae8ZNTf+c9F0pf7gnTiPD65anAsKKxdsXfdms/n2W9FPP/+4 + dLj5+rAse+/+IPolGv08Gn3/689av0efZit4+7vXN6/ZeMd9d9ln5yM3eXazW6PooS/ujU649IoTx745 + /uStHzj20a0+zFJw7PDozjv2Gt1z96eOOuaIo19Z/4Zo2dnRw49deNEZp4xFl3952uMXROd+lekM3tS6 + uXnwLRsdsMdv+x16yPcvHhRFs5r3t86/+L5LXo7O+vbBy8574q5WpoKLDruxuff+116904G73bbrS5u+ + E0W/njkrOv3Uc05qRff8cdx72z6yzUeZCgq8E2c/3sVCLjgJwZkzhO30B+A8PlhjJCvBGG5w5kEuKHAj + F7SNXHDVEBxKCFGVCqoyWEVQuNGoIyjcqDcQFG7UBhEUbvAluCGCAwk9qEovqlKvICica1UEQZZcSEK1 + hqDwqcI6gsINzjwQQayzBNeqLggCJIFXeGZVx43OLjvnB6EoJmCr4sm6eK6xcgpmN4ONeevOQxI8nEEr + xZn/VmGO8ETQ3pB8hC+CYbBm/L75B2xV/JlBOsRDwQb7+SmIGpML5oJKLpia4PPfIShtCNrP3fQF7fXa + ETTfsDogGAZrTR8HW4X2ZvBJVCUlwSBY+TcmEexN6EZVAlSlp4igcIOzGZR7EBQ+uuRovDAdIYZOJYJY + Pgm8qgto+WVWdQGqwtkMJr6qc53KLYiqpCT4ZzSGJLhOlaWg3HdIgutUmQqGwYYJG2BjDJ3KmxnknXwR + NEfkgnaQC9qDV3NB82ZNX3CYGyazhxE0X4xSF5RrIAm8k/VYhK2CjJCEgH67pSRoPLBRkdHShGAYWxWz + V/qCbMVvBXOJDAWjIbqE8yF6poKoSi4YC1aXUykiKAGqUikjKJzDXgSFG8HTCAqfKngDQeFGuYKgUEME + sTqJFy5IglkPTfj/3QrmIih8qoCXv9wwR5MICdbtJwi2xnRaMFyp4HxjxU8ZPJlBkXoNQeADOi3IsOCC + 5xCULAUXoCp2BlGVLAV5kJYgn8pDQbnL64iCj4JhsPZ6CX7O4KuIAh/hyz1o4IYvgs7ng8EzCIqHgvLa + 04ecj4JhMH2dBD9nkD7C+QhzPRp0+h40cMPsRINOC6b0h5xsBWsJZVSlBzWmF1XhRrWCoHCjUkVQuBGi + xnDDXI8GIrg4oYKqVFGVoRqCwo3BAQSFGwODCAo36kMICjc480AEsXwSeFXHq6yJr+rae7rFDc48EEGv + mTbtbxxCCW4GIaZ4AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAIAAADWjhTKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAANZtJREFUeF7tnYdT + HMme5/c/u4vdiIu7i7exd/fe2zfzpBmNHPIgCQkBAiG8hwa6oRua9t57b6BpgzcSTngrCe/lNXu/ooqi + yHYIIwnNfONLR1Z1dlZmfSqzsqqykn9JTU0VUsTn8wUCAbEQRRwOhwhFEZfLJULRFTeRuBFAbDabCEXR + 2UoEjwNEzoeptLSUjBBDSARI6l90Ot06Raurq2tra8RCFC0tLRGhKFpeXiZC0RU3kbgRQIuLi0Qois5W + IngcILKxsTo38+rV7Nz81HigrXNjY0MkEpERYgiJAEn9i9Pp/C+KPnz48PnzZ2Ihit68eUOEoujdu3e/ + //47sRBFcROJGwG0vb2NB6ampiYiaXBwkAhFV39/PxGiaGZmBk8Z9EU5iabDJILHsdlsXS16nbmlOie7 + SW9tHxje2dnRaDRkhBhCIgDcrw14c08LCwtEaHOT+O6gDrNHyN1Kp9NHIml4eJgIRdfQ0BARokgsFuMp + g74oJ9F0mETwOAB4Z2fF5wn2+DydLSG+RnmWAGdmZpoPKj8/n/juoA6zR8jdqlAo8ACiuGUBffr0iQhR + RN0tX5STaDpMIngcKuBgWxODyztLgGUyCa+kaGJqlMWSiBsZKmuTyWQivjuow+yRGIA313ZcvS+n1t9D + eGJ+fW713cL624h5+k4At3d1aY1G2G+7gFEdHbDD4QCipN6/f//x40diIYogFSIURW/fviVCYZLJZAN+ + z6v1HZ/H4/KYTW4bACa+2xW0jWW7gn4jHgBB55D4+qBgt+KBcMALL9d7ZlYdfQvB0dW2gZfNfS/dQytT + L9eez6w19b56/3mfdTTAeMqguOUFkTlBVFFRgReBWhyXy0V8vSf4udbv51utefn55eXllWGCzgREi5sT + JALAxQDDUUMKajAUmFiIIkiFCEURXoMjigpYr1NbbRhg4rtd2e32qeEOIddELynQqY2PS0o2tnZUKhXx + 9UHBfsEDOGBz+6wuOA2GAACe3HzfNrzQPbHS9mxG3fHK9WwhMPh6e3NH5pte/7DfSkUDjKcMilteEJkT + RFartd2j84V6M9KeOMyWykasvUX2+cdPn82hcaGryTc2FggGibWRFDcnSAQM8FdvomVry0ub2zvLS0sz + k6Ozi6tIEw2Ad3Y2HCq1OdQrkXJqawQb2ztqtZr4+qBgt+KBCE30+pvt3/9rZXnTPbg8MbvSM7Xu7Fsc + m13pmFgxh2bffopfg4nQ8ZpoALy2MO2zq5s7e4oaFBKpCQBTE996+7FY8fxyZaCoQfPzvZJPMXd+3Jwg + EWBDXxtwXl5e/a6gb4UHCgoKiO92hQN2arQaR6iquiIYtL5e3ToCYFxxywL6CoCDzRaD2ZPL05ucRirg + gem1a9XBJ8IeS8eco3s+qTbwaiXWts4AYFLIdkntAt6aGBlzmRQDoyN8FbZHzjTgzfWV2ZeLcqVscrjL + 6A3hgN9//Cxtmjhf4muwvgC0uItkGGnil5F0ZgAvr6zkFxW9efuWWKbIYDBwdwWXtngAdATAH1dev2ry + bi9vQfjTu3f4ys944POHtyvYelz7gH///OntBzx4UoCJAhwsjsbsfsTpTKxr07fOkHTBfOdwifI58ctI + Ogrgr9zJwiUzmRqNRrnevP32I3QxiLUHhWQsomC34oFwwG/HRrZW17anJ1aePZ+32Fbag5sTo7Na7XJP + z9rg8Nbk1II/tDn+Yqm9bX18ejEY2hwbWu3tmnW04T+HXYOnDIpbXhCZk2jCi/P58+8t/a9/KfWVqftt + XVizTLUhNHmTHoLTMP6TcMXNCRIB62RBkwhVltRJXSbBUUIsRBJfpx/Y3LySw/6psOkmPVgo79MEJp9N + rmzuvCd/JxAI5ubniYUogt2KB3DALx32ObMRDIE3Y8PLQ0MLLYHl5z1LTaYRgXRS61x7PrDyrG1aLZs1 + O5bam2da+lY6O2dVtZMy2bTNt9oXWOqexAHDrsFTBsUtL4jMSTTV1tYuraxXavp/K28Re8ftXXPhNrVO + 3q9vX1yLurm4OUEiANxv0ESvbb3/5ak8u4oldXTrQzON9hFolx6yOy5X+v+W502oBt7P6rWt6SUlAoMh + dmbIhjG8Br9/Of3S43nt79ycHl9tb523mF+39e5Mjrz2+V65HUsdPZujA0tD01sTk2t9oXmbdalvaGtq + aKmVaCFPqonGFWxtLW5oSCxuSON1mTtmkYpLGgCXqp47u18SPwtT3JwgEbAm+isDhvWAs1I7AIVBimcH + d81D14OmG7hVKG4eGzO0t0NzQvwykmIAxhW3LKBT7WThMjmdbfPzHKMVKTJi2CdQuWHnED8L0xkA3Dq0 + eIsRApDhgKk2tU5k0eponP07/hF1VgDXKEMZUBy+FikmYtgnUL9h/0Rr/r53wJtvPlytCqj8U3hhqGUL + t7x5vED2jPhlFMUAvL7c19vDW9na7y3jWlubJ0J7Om3Ak6+34OxjCE4gBQw3vk+SmG1LGxGuL0BHAQzn + YSghKehk4R3pGIIrOSIURdDJgqaVWKCIbhiE/pStcxYMhcED0QwRoKgR0yEFuxUPyOVyOKQQTYwH1lZG + pqZDoxOBjfXZ9bXRFy8cQ8Ne4us9wQFNhCiCThaeMihueUFkThC9//AxjdvFtg3HLS8YjwO7qKnvJfH7 + g4qbEyTCV+1k9U2sXqsOQuNMPVpjGCJAYwUXUcTvIwmpwf39ir4+IRgCsAiAR4ccKysD/kDJ+Iilt4vv + D5S1dFh2f7Ev2BFEiKKTqsFNz14lN7TjxaGWLqLxOAL3WI1hiPj9QR2lBn8dwDvvPgJd6EAhhYlhiJDK + 7YT2jUgikhDAiObmemem2l/OBUOtNTOT3s316VArs3fIT3y9p9MDDKekK7SALjSNF4dauojG48Bp+E5d + K5HEQX17wE1NTXD9yuVy4ROEP0gA1CzLi3xZX3hhYhgiwDWDqyfqNQMoNmBQ3LKATg9wg/UFXDKQxSGL + Fs1knBv00MomcfeNqm8P2GazDfT4ewaG5OzGyddrFgvWHg5Mr0Hfytp54MbNYQDDJTLHMYqnHFHfM+CJ + V1tQatteqb8IcIGsz9f/mkiIou8CsMFqNOkF+dl165vbAPjdh893altFnnGyGLgPA1gdmHoq6iGSjiRy + t6anp2siSa1WE6HoihintLQUTxl0BMCfPv/+iNMJRye1OGQ4msk4POdonXmYSIuiowA2m83Q6SW1tbUF + PTFiIYrW19eJUJigTe7vaq5uYPUEQ7qOcVgUuEYz+J3mtinE+sAYsgYxRDC1Tl2vDuzsvCFSD9Pq6ioe + gDxHFEQgQtG1vLxMhA4KTxkUo7ykyJzgsnfO3me1IsWhLkY0GccQmrzHansTVu64OUEiAFz0YQN+L5pY + iCIoPBEKk9VqtZlkKoWqkl4+NLvMFqkuVfqtHbPITVcwHK3IGsR4hMS61q03H4jUwwSHIxGKohhZJbW5 + uUmEoihGIrAHiylKSEiAlWtb7y5V+KFvFV6c2KbGuV0boeBxi4NEwB42nGwTrdfrpyjKKmvgOvebKarJ + 5iia8QiZgu6R+Q0i9TBF7NpQdZjWFY4SIhRFMRKBPfis3U2r5Ur4NJWjGe9U1pmGy9T91LKA45YXTI2T + J+0LDS3iWyF1lCb6ZAFPTk62t7dD/zkUCmXWqJPK9WSOER8ScKV2wNw+S6Qepu8BcGuLLausaGN9RW+3 + AGA4HBOgbxX2KPBLAUMHk20bITazp28PGFdnZ+f4/PrFCr+pPdaTE2QNYjyCwDVWa4rQ3cD1PQCemZlt + dlscWvOrtU0AnMrp5LvGqAXB/aWADa0zyQ0dxGb29F0AhlP445ycq5lVbNv+YJRwHxIwnMnSeV1E0mH6 + HgCvzL/QWj1ybpXd1waAofNMLQXpLwUMhtPwzrsDD9OOAhgubAAJqXfv3gFjYiGK4ExOhCKptbVVEww6 + +vvVTYPUG62IoTDIGsR4BEvHzBVa4H2UHAFgIhRFsbOK6ziJuFwuzq5qamrqWOwbSSnaQORyxS0vGImT + JeruGl0itrSruMVBIgDck6/BEzOvBE4P3+owt8U6ZpGjNdxkhCRmW8TbOqDTrsHQwV5bW3v58iV8guDC + g/giTHDpXGMYqtAOkPlHHLe8YCROg/UFXBATG9jVUWrwiQOGU2ZKtVFkwe6wx/DhAWeLe59NrhKpH9Rp + A4YrHztFMpmM+OKg4CL44ZOShOpgeN+K9BEAw+kJGnxiG7v69oCx+3O0gKkNe+Ib24cHTDcMaQLTxAYO + 6rQBy+VySUMtX8AsLqtZXN+CFo/44qAEWm1SVnaFyE1mPtxHAGzvnoeD5s27/Tup3xjwp8+/Q4cIWhVL + O/b8JLYPD1jSNBFtFMtXAKyXcBvpjHqOaHVzOxzw77//F7QuHLOtaWQkny4kMx/uIwAGPxH2DEytERv7 + 5oD9/Qv4s8+TBQzXWpAssY2D+gqAtQZ1I7vCalO/eLmGAF5Ye1ukeHahvOUxTZBLZxkCkW/p4D4aYKZl + WOQeJ7Z3NMDhvWj8bmUMRezLbe28u1YdVLVMWDtmzG1T8BnRmqbBlBzao9wq8lPlHUDi4IbS4gHoSF+u + 9L+L1JMGwEQoio7Zi4aT7uTY0Kvl1WeD2Gv2FosFX//m7XtZ0/gvpb58aZ+xdZqa22iOGwEcHkftn0zn + duIbBX3LXrTCN5kr6cWPuxg1mG8Mzs1O6632qZHeYM/g/Pw8R9uCxMFNPZzvstpml3aILVF02jW4qqqK + yWTm5OTAJ8hsNsPKrtHlm4wQ9O2VLfs5NIbiDLmiFieaw+PYu+axq8SPBJGj1OATAby08Q7ygb9BBY4N + eLS/wyTi2XvHXG7jIQHny/r8AwvExig6bcC4yF30cmWnUP7sYoWf+kIR7lMCDIZuzfO9i4hvAxg6GiXK + 5wzjEJmn2IDHh7rrKir7RybU9kBEwCmZBUXFxUVFxdhncTEssizDYu/+qYjUVwAMDV1xaenQyLiseeJc + STOcdJGRC7hPD3CtaQg2jWfm2wDun1q7SceGOpN5ig145FmoqLKwtLhCZXVHBMyTaswyvlijzEzPml3Z + hEVoDKHqENuj6CsA9odCDTpdEV95v75dG4xartMDDFfD0JfGM3O6gDc2NrKzsysqKsrLy+ET1Nra+vHT + 53v17RLvgQEbsQAbgtPT05AULghHBOzWKwxcZnNnj6pzGhbtXXN3mW3hQ62/AmBnU1P/xgbXbEMyifj0 + AIN330jDCn8UwPZDj4teWlrqCnmZ9EqNySPWYW+qw29tnbOp3E7qHVQw9KKRNaR1LS8ySljgc1fv4gGt + bxiJw5VobHaTXlRgsHjdQ6+xxc5ZKCR0pIms7AkAE6EogkwSoeiKnUi1uutefjVdZKLmMNzABlmDOG4E + cLQ4qZzOF7NrkJm4xUEiAKAvqMGrq6u9vb0vert8TR6t1gxpaQyWq1UBw8GXXMExajDpojoZsoY0VNlO + vy3QPy6VS7a2d2ARVsJhNLWAVrXTrsEj8xtXqgLGQ1S+U63BNYZBlX8K8nOUGvylgP0+v9frNdgMAPj8 + o7rwoQvguIDZCuflC5ck1sj3q7OLaxh1DeW0avgEwyKsLFE9d4cNoT1VwHD2gfMuzzl6GDanChi6INni + XsjS1wDcNzA02O0TGewA+C+3qyPeXo8LWFDPadGoGgpKXEqHw//C0REhPlLFIw6hPVXA0FvGH+5+c8DQ + gb1Bx17ywIsDpQYWpKg74biAi4qK8EkIcGVViZGs4I4DuHOWmZ6xPTLESLjuvXCh6W//13v5iif9qate + 4rS0OjqJBj81n65wEXdOwNBGhQ+hPT3Aa1vvL+0OnINNf3PA4EeNnbNLO3hxeDweUCMFi3ieQccCTAp+ + 0jmynMRsQzJBOjZgdyndcu3Gk+v3HPVSF1vuYkncJTWetCfe6ze95/7Z9Pe/epKSFdklBWmpkoZG6D/j + v4LATUbo88Ge9OkBrjEMle+dfb4HwDTdgD40gxfHarU6jfJadlVeSuHc8hYs4nkGRQCMTCe8srKyFnM6 + YajH9FrmtaoWsfuFPjAW0dqWEWQNaVOD3Pvbb1Y630TnW2qFiK21Qlt1oyunhHU5YdTf3GoyaH37W7nF + CL5aXCHysasTmcR3YWGBCO2ptX8GOo86P7FdDSUP0axuHkbWID5MIjHiCJzD2cJOvDgGg2Fj+VWoI/Ag + KaV/bg0W8WyDTmA6YYfHk0WrelguQg4xqqPVYKe1ren8ORedCxXXzpJg1TeKLXWiivTHtNxi6s8z+N0j + cweG0J5GDYYrzuSGDqF7f+Dc91CDoUNwrTq4tYXdkIcqO9gWmJ2fafKaXYOv49TgLwWsdjqbRkZqZTok + B7jNbZOGwKimeQg+wSZqsYOj3itX3UVVOMLYgMHOCpYnI2f/57tDaJFppI4DGC4T4ecgqMF4AF9vbseu + 7Knb/R4Ag5Mb2kdnliGHQHRpZQU6ucNDA/B5koDffvh0q0hMl8sZEjOyedz55XV6ivKKacRXnTOeB2me + tCySX1zA9jqR9+ZtMmUw3zWGvLFDUommGICh4EQud1VRUfHx48fVrfcX9/pWpL8TwOWafm3L6O+//w5Z + raOIOpDoWIAhaahDedK+GPlgi9Qei6qSXpOVmftsalEkJ2alcJcxvLcSD/CLC5gl8V5NcHTtj6wOH0J7 + TMCTw715ebm8RpZU7/D7/VB2KGD4wLnvBDDf3p+Yi9WfGGP/IgB2HHo6YdjGLUbI1hnrNRsAvLO90WyV + uboGRYFhAAwrXUI9dKycLLGzQUbaxpJQF8MNETw3bjm8z8nErZ2z0PfBZk7bEwAmQlEEBSZCYYKCQ/sW + ag06XQaTBwPcPbqYUB2wdaJvUsUoL2kAjKxBfJhEYseh8TXNY2PVbDZRgEhCygtlPOxMd5OvN38rb4E6 + BFuKDXiiM/hiaowt0LUMzWE12NrmPUd0rKgGfsgaxBjgh+lOmZWaPlybLW+8JfJ0iPnloMBEKEwY4O1V + rzNg1GssNisAvkX3izwRpij7TgBXCTXDb97UKQ0fPh52KjwM8GGa6HcfPiUy2xrtI3hbAfnAA+EGwK+X + lqBm9D/v2dzaFgml1I4V1Ydpot05xe4aDjX9p+Le51P7Q2iP2UTvbK2/XNmYmxqbfLkIgFMbI986jVFe + 0l+hida1DD/IKbtZaoBrdOR+ACmkvFgTfRjAtabhbPH+TaUY+Sio5haW0zOeFhSU1RSWVuX8+188aU8Q + crgPBbiizpOVT02/xjCoDe4PoT0O4J6eHvaucnJyKqrrfr31WB+KPNo3Rnml9u4cGg+cWdqAB5AIpI8P + GAwR4HrpLgurbAjiUCgEF8QqlQo+QX19fbAyKmC4Rg7uSai2/+87THIqAnwzZDiiGWKrtX16t2N1B8FG + +jCAXXVCSIGaMjKE9jiAScnlijJ1PyRL3RDVMcpbVi/f2lhp6+gd6G4feDEOexaJQPqkAMMnXCve3p00 + gYrYbDZPjw69mJj2ulxLa1v4tVNUwLBy4fXLzs7eoee9zwaGoSm3Up4HxM1HRiGDXVQNHSsXS4xgI30o + wGw5tPDURxGm9tkH7P137o4PeHZ2NiHpUUKVnzoiBXFswC02na+rW80XTr1cMplMSATSJwgYbO6YvUEP + KXyTJGOLxaJSSEJetUzr2drewUf4YoAjdrJg5fNWj9HlVQvFI5OzcH6i3pyKnQ+xpZ1Hq/AI+ZbKeiow + xIfpZMGnFzrS/v0RbrauucuVfnIC4uN0snAJDYbC+vqSxliTDMYCzJJbzMqSymqfw6E16b8aYCzcNpNQ + HTS1zeIFAcAV+Y/4EpFVI2qbWIUaDCuxTpY90nTCsNLn0VdVM8wqpUyvxwC3TZHdOdgMGQ43U+acCAWe + u536Gh5y5UM18EPWIMYjeJJTnSo3NX3oSM8sbOG5BcB4IJoAMBGKIp7B0L24WFIvpW4CcYzylrJko+1t + RSymUt6gtTkBMBKBdOydhjtuHCSCLjgFh7unF5t0GQAbpEK2qJ5RUzT0cgMAw8qoIzpg5eTzHqaQY7Zq + VCYzAP6CJjowWn7uHC39KbU6hvuQTbTnaaG7lk9NP1/WFxgkhtAev4l+RFM+pbH0fuICIaJjlBeaaLhk + IPU1azBudWDqYoW/dXgRABOZ2NV+Ex0RsMWGPc/f2Nzc2oKLne0vAuxmipwP06moIvqQgN1ltZ7sImr6 + TPOwtIkYRnpMwDOL23AmO84VDlfnv5OaD/7LX8/D561HeUgE0qcEGKzyT/1a1pJZyq6pqblz5w58gtxu + NxQwMuA37z78mlp7OSnz1sOnuK/fy7B17t8yjJWPzllvwjVHVSMVVUQfErCLwfcm3qNuQkEZQntMwHCx + QTcOncglbFY5G1mD+PQAg6G39Vt5y8D0GkITBQynZbFCcSOt8B4t8rME3DHy4TS0eK/diAsPfFjADTLo + jcNxQ24CurvYENrdDB8H8PuPnxOqgnBZeXzAdK7m5/OXoJuCrKf6VAGDJd7xCyWeG0n3XV4vUUIcMJyH + sQGWuxodHfUMD9dIZXxTGzlmM9ywGWQNaffTQldBBbChdpci+pCdLLAn4bq9eYC6lVuM0Lv32DTDABjP + eTTBiYYIhcndM/9E2A2pAWBq4uGOUV7cZrFYXscorZMg66mOmwg4bpzYEYrZOr7NJnE6iRKGD5t9/fq1 + qbPT0tOrdD9DDhCqYTPIGsKBEe+vv7qgR3qCNRj6WfdTnHofdUOPOJ3TC1jdPXINhuusBw0d+Ntjx6/B + Si7/dU9nLT/qnFHguImA48aJHaFe6e5aXBTuviGHC22iQd6m5nK2Gvkl4mibcTVIaX/9W+6D9OzkNPgE + FyQ/JoEhPjxgd1a+m3VgdF+J8rmnFxtCe2TA4682E+ta8dSOD5ina8n6xzkXrR5ZT3WMRJgyR05pLTir + qAY+0/MqkQikY+cELpxyKuoHh/bnmo4A+O27D47uOaG5LbOITjo1l2aP28nqmvPevN1YVNbZ5LA3BWxa + 1fzKuoiNPkQi/QWAS+me3FLqttj2Ee7uENojA64xDNXvvSF4Ip0sa73Me+GCI4TOuUo6RiI0tmKir0uq + NXc0O7tfTOn0RiQC6bg5aeo9MGlcVMBFdbKlmXGhRP6ir6v12ehhLpOc5hD0nxtpDAWb6Wtxco3BhRMC + 7KoVeO4mU7cFFwY5uwPBjwZ4Y+fD5cr9iX5PBjBP40l57KZzkfWkYwNu0mq0Hr9Cp3v5au4rAe73N8md + PpVaNjU1chjA7vwyd24pAJ4YGder6rMrmK7nUycDuF7qvXSJui1b19xNOjaE9miArR1z1NnJTwowHIhY + JW6NnFpswDOjkwa3g1lbobLZThgwMp3w+saWpW0yny6aGx0PtjorSp82KjUA2BDcnw1XHzYzriUw4rlw + wc4UsyvpDovc6LBxqxkD0wuiBi5wimhLrRBZg5gawfPbRUvTAHWLtxmh1Q1sgD+R7yhaD5t/d+fN26S6 + VpVvnExK5x8lwxEdXt4I5qggn67kVGd1I/rVrmMkUs6SdrZ7BHKFValwtbVr9QYkAum4OXF3TRLl3BUx + nfBninbevnN0zRbVSof62+obGxx6LRxTANjSHutetJOjxG4aN8houcU9FNWUVOCXOuG2MQ+M4Ak3NQI0 + 0U6tl7rF3SG061tbxE3paIIqToT29Gxi5X59OzUpQzDyP5ojHV7ecFu4Gsgn9nzz4iV7W4TRHTESKa0T + EftrV3XMeiQC6bg5aeqdIcq5K+xhQ7QmeoYiOBBiNdHQvbp1x01rgOZUW9UoKWHkJz4SFtZAQBX9gRJ2 + vIetpJoawZOZC1106kYrtAPWzjm8ib5x4wY+XTMulUqFlwUU3kSXa/qhg0ZN6sSaaDyrD9PctQLkW3CM + RPT+EZGlHZwKLaelXWKNPNslOG5ODncO7pqDDVXxDFTD0UGmgmzGaWv3Xr5CwgDXZhZ+Eb+IpkZwF1e7 + Cw9cPPBco0zzMA5YJuNXpuYY7UZafeP2zo5cLsfLAkIAQ/fqalUAefR7soBdDB7WY6DUB9yHSSTGK7W4 + jwv448ePwnrWg/spCteB/5CCGNmMu5DmzikhYdhYkjuX/1GamYQ1WXsrw/1lRwCD772fQt2oLjj9mN9N + ABY1ZDzIGZ5+5fPZt7ZjAdYEpsh/g0L6hAFDJU5+hLQ34NiJQP2hVTfcuHrDGIwwFTHp4wIeGhycbg+5 + 5FKBMYT8kuoDm2kdx+5eUWAwMvLdtsKQr1JfE7ULDf7SKo49w6C0ItCRTqgKbm5ib51Ihfzx2SmBxqx3 + tO1Er8EfPn2+XhMMf139xAG76FzvpcuO9gO3pmMnomt50W23BvXaQnqsd4KOApg6Edr62ppRyDcya41V + jdSbnIhhM2TYCdd/9x6QvSGwklEjET3kcpPEykcONnrD2coUCwqrwfx8Gh6ANUgc3MjNau/VBNvBm8aJ + da2zr1ch21KpRMKr9jgM5YyG7e0dqVSKFwcEvInQx49tw4spjR3UFHADYGQNYmp5o9nK01Jz676X4myQ + UiPESURqEWZnNSnlcA5Gv6I4bk6a+2aJ0u4qwkRo87NzmtJa7y+/uHhRb1hSjyPv3WR3FXv/4GXLxIa7 + LE6ioPEJ33xdok92Nh6oiMLC6paWlu7u7o721mCoFcK8fBo1AmmkBnuS7jvNQXK74Kfino7hV58+fbp3 + 7x4+aTMu/FUOQLu5ubmwsACfILhmyJH0hv93H/DJ12AwXok79luLGIk4jX7vuXOGoirlz/+kPjcLd9yc + HKKTtfPGxVG4ajje8+ddKifye9zkZpzObigGtWAGCY1nuaaWFGllJVpZsdB0W2i84+CIyAgAeH5+vp5F + G+jr4IhlED4s4MfZLo6SzAOYpu6tEVrgEPnwgfjH+1ThE9ORKqliJVD+cyLVpwIYOyKTXY0KMkK0RJzO + LqhO7lI6/MR57YbT0YVEoPrkAEPHtYIJjJ2mAPljTdNgdnY2PqkfrrK//cOTVUAWCUByrVdUytw9wJjF + hntQle1cPh4HAI8PdZfzJTtb674WbCK0QwJ2F9GgL01mBlzKFrMNBhPl3TqqLBbL9LMmpStQkFs4vbyZ + XMih6SIPjD0lwFglhn7DXo2MmIizqR9qiDu/HP+J41EmNIFIHKpPDHDpg8yS4uKSwsKSouKSktKku3fh + OhgA9/b2GjUSl0zaKNNCG1j+3/+bq34fg0KdKdbfB6hUwGCJ7iHPctXKx4Z5AOBnre5bibf9/uDwwuYX + AK5uhEtMamHoUqV/aqqCp4aLHyL3FAFgp0XOVynKGNzF9e30Uh450yLi0wIMlfjuAxdXhUfAE0nPKYP9 + SfrhTz9hT9D34tsLacj4JMQnBrjkfgbw02jkslqaweHD70UD4J7uVjqLYRYJyhv5EKH0n7+SmbMIWFzr + JY28OBwwWKZJ59gumgUsvIle31jf2NiAFA4PGC48sDHSlI50tUBXwGQnVpp/K29x975E/hGtxWKqK0zJ + otU6TIqWkUUmn9jR4T49wHBQ7lZi7EyMJ8IWqbdW53VmXea1lJH5VXEDhxrfTud5r98g0wz3UQBTe9Gg + 7c0tZ6O8+N7jlZnREqGEXZqnsHoAsLl5UOl57rfKbt65ZQz1Gp1WwFN8N83RINs1XFndlqsyNdJiMADG + A1TDtxzbb8LagvtXbz68fufiT+fhE8LycuZeIgcMvWhkjefqNVtwjDrbLhQYPgWuUTi/Jje0D8+swvkY + Lwicd7e3NhZX1nqfY29JNwhV1B9SDYCRNaSflDak5FY9zKHBJ7hGaEYi7JunRXKL25N4zyHQQQQ8q5CN + QLDZalPevnL/xdyKiM2lRoYiQ4ttO1hGqvFEYjh+L5qswR0+y4PMJwMjwya7EQA7b9/VOKGF7n39en5+ + aqitF9trEA0/9KCOCkw3yfoaXoNxK1VPgbFeWgE/IX8bzWgNhhbvzl3o1lEPWLLywWVxlX7wfKmvzjSM + t9h8Pr++vj4/P7+kkn43o6SgOuqDvBg1mCsQb60tTr98ZbC7obwxmoGINRjsrmrwXr8JZ+K9GqySsGkF + FRWDIwPqtjHkaRsUGbpm0Kmmpkz1UWpwjCZ6cmqyK+joGZnBAN99YL6V+DS7oJLOyisspWU9peUX1mZg + PSw7V8CxXVIr8kmQ0QCDoQvGsV3ksjKv/vSfRgbR84roCIDTslyCA68gIGxM7bMZ/O4L5S22zvkPu3Ms + Q+nqrS/olJlwwx0bsN/EUfiePQuZJhe3jgAY7L2d5BKb9gCrd3fshFbBW9/cjgD4aSHyQiXVJwYYmmh6 + ZRXpjEdpsG3vnbueJ3lwRskoZj79299zEpNz7qeCU1OuNPCTqBRjAAbDoUCjX1bLHlc/jTV8Ohywu6DS + XcqgliciG7kP+9/wScy2ganV0vKK89kqa6QJgEnHBCySMgs1oWGF0rB5pBoMxisxNl1J11x6cjq9tIzc + sVnJqdSYUGR3JcuT9gRJnPQJAO7t6WJlF1Wl5VA3TLhe6r12w5Jb+vf/9zN0jkZGX4z1d7uCXRBmVD48 + gDAmYDCDljg/Jaoovu1s3J0qK5IjAK5me1IzqeWJxgaud+vMw/94LKTL5CxN1Df+cMcG/KLT3SCU5tOY + S+tHrMFg9807lVnFNflVmp9+ctUJkW9JY0VmibE7JJHmDwQfF/Dy8rJFX/A04xfNgZtTFLPE7KSkiqzM + +dnp7JI8u9vjbPYeAXADI/3hvZ/rZJd3b3WhjDMTH2Q/zsxOz8Q+H2fCIvEVU4R1SinlicEGTBebepeX + BTYHsh5xjEQ4fNE2RUcGXPc4Z6jJnfbzzy4GD/mKavyYhosFp28QSR/3UQBDRwsfQwsaGhrqbqN3hqrp + dYlWTuRXx0SV1a1GfU+L8X5GlszmsDY3AWB6xUNqhxkAUxcjGosjKxIab0P329YopG6CV1vvsiqa/F3s + Wsar1S1YJL/yXrxoC46Rt16hwGQ43IbAWDaNReNhsxGHmylz5pfRST96UmBpR2dBzqnipxUwfr50Bz7B + tVJs+uSIRu5FU52ccDvjQUpZXl5eZmZhxtOylCwkAmn89rvnQapDZkXSxx27vGDoRRMsdxWhF83nVuVk + XYL93mi/oFI9tXPQ9oRfQMu6e29ubjbUHgo6bQqj/Qg1GEzGEevv8803yFtd2CZq69eW5nQyGa+qbmRx + ExbJr6DD4nT1kAds7BoMjnHIF9XJXk4PC+U6p0mpNGOTsFAHNVAd9zEtOEYN5jWy1XJ2iy/IbGCvbGwX + p+7PJYUYr8HuvHJ3KR1JH/dxm2jQm50tnbwMA6DIE5hvwlWNRlHg4Bx4j5ubVxkMBvv3BOHjAAZLdSk8 + 6xX8VhcYiC4svNJIS7Q6vWdokQoYzsHQIyXLc0zAm5ubHp1qbX3NH+qOBljrG/r14k/VnMjTrpKOCZjz + cn7YbQ91t7Vt7ezEBeyicz33HiDp4z5JwLiVyhye5RrXekkrLSVPlvVZJbTi+6Xsf9bSHuFWigrJn4C/ + FDCYvNUF6QNRr01uD3ZUMyqW1raogN15Ze4KJlme4wP2e3Wjgz3DM0tRAM/VcDgmbbZcmhv21QHHAMzF + AM9am1wtzV64RooPGDqzFy5QJwgjffKAcSvUT6CG8S3X9JJKe70k8deLbNNFuKJFopE+AmAwbAUaDKO4 + JuthmoAiWCR3AVxyeNKfkuU5JuCZ8WcMLr+r+xlUrHDA5o4eSXNxLuuvY4ONDY1R3wvFHQswu0HIY7Q/ + 6w71Th8KMJyJrt1w2juQTYBPCzBuuSada7tUUPlPRtXN/KLfkG+pPhpgMH6rSyfFnq5EvtXFFGOTOuyV + 55iA8SeJuGg0GgnY3NEl8ZU1ui6KmnLUAVl6SbbMfuAOWrhjAE57lEpsY1dZiQ+RCKRJwNgtnYPPRnEf + BTAynfDC65dqSbFKXBjRSnEBq/buQA+TTktCvqJaKSoAIysRK4T5yBrcClk2tNVyUU7mtSRNZQM50zBu + a63Q88sv+r1pd48zia/OP6JqGgQnP63EA/rAqMrXwnPmNbouAVpZk1jWJMPsNSG/DbeRrUCyStpQwzVU + c3NuPYRPsIkRYR5l3OQUy/aCSntWAbIJcNw5ie1tYwTIXUWYTjhGDcZdU36/vPhaTXkysp7qI9dg3GpF + Pl3+S9Kd/0MvTobLBvIAx+29flMutWYW0Z8UMdLzq/BP05e/T4Abam1KbhWca80d3eLmokbXZVFzrjog + 1wQ1pNX+OP9TBxyjBuPOuf2QmAA9uskajN3uODgRK+7TbaJJx+V3TMDg0oLbfm+Zy1pgZaN3Bjwpj+sy + ClYW5lR688bG4tjwDPTkNU1HvDNAq6u5fu3/1ijToNaKm/OgQaaixX18wLyCykf3/0HLOnBjMtz7gOE4 + vnzlCGNvzwxgMSenpvJWcclFjvWiUVRDFhvszi1hXk98NT8bMhs7eoJWG3bBdmTAAm6aw5yfVZ6gDkgR + rqSPD5iRlxFsLpdyM5H1iKmAPYn3wh8r/TiAwXA+hk+FOpNjvwAdbHLwnruynvXXv29sbFi03NmlBZ/n + 6IB1rbbCqnMKaUadko5Apfr4gBvzSjXyJ6Xll13sw44V9zzJdzMOTC8EPgpg9N2k7c3vBDAZQS0v4Juv + gy18tpMtd9ZLWP/2r2PDXTUs+uvV5Y5QFwBWewfI93Oohj2CrCGtb3U2uq7IfTyRS6wOqNUAMpr9NuS3 + 4QbAWN6iW8us4xtuaeRFyHqqsVuVe2FXORMuCJGtxCgO7ua+WQLkrrB3k+Bvd6Y0Qjvb30sNPhihWKp9 + 1Gi7AGEnW8b6y1/Gxsam9uTz+dRNKOD7adlPc/JJp+dWUL/Vt7qBrtLPgwqq8Cmo9TXchwRMVr6INjey + ofPIsV2ycwTIV6QB8P4iS+K9ctV+cPLqwwAmQO4qwstn308THR5BpcyBC3GJPtl87TK9TlojtFy9mwGf + YCtlBDJukVyrENNlGlVJXkbn1CpbtD/M29Dm47ivKvxcnN9hAJO/jebDAIYiSHUpYOQr0tQmGoxNeH/w + TZajNNFnCDAYmjihMZGn+clow/6hYYzZqQDwzta60W7qaWtd29khARvbAxx3gsLPJvl9TcDQFHGtV4wi + bBR0uBHA2DtOygND0398wLgV0mSO5VwZ+8n5X/9DYo38/7kAsNdonV1Zb3Z5dvYAm9pbd+k2UPl9XcAl + SlU233It4kgHBLA7t9RdXkvdyh8FsI6bpa29w2Il6lRPqhqKbV0H3vfFDYB5jAKTy9czMoUDNrW3A115 + Cwvh95UBg0WGJJUyG4kARgC7qhuhElO3chTAyLDZra0NrbwMeTiPGHY9sgZx3AjgYyUiyteXJFTQHw30 + MHNq/wknVFkL3dTWZe2cJh99Z+QUsxrYtXVM+AQ/LnjMcV+T+eqwDvNBA2BkDWq/jUw2mmM88McNgMn8 + q2UFXOslK5eDxMEf+O8b+lkXLtgowxAAMBmO6PjDZs9EDQbr83+TOEWFrAIAoPRzhU2ZbNcFQdNjXavF + 3r3f4cKf1Zs7+jjuG/IWBlI1cX/9GgyWadLFhrtIHLQG796XdXr2J6X7ozTRYH3RZU2TlMpGHVRKfGVc + 9y28D2XuwP7JRHohQ9Uc4npuy1pqyJiIvwlgMM98zSA58FZHOGBsgINwfwK9PxLgyttaY10kNliFFnjT + Gl0Xq+T3n2T8UlJ5QeqrCou2728FWKXM5VovU1+9BMCiopqc7JzSklLcOdnZ/LT9/+/3BwKsq3uoE+Xj + bO5m3k3NSyVdKajEqATkRczkrtZqtTyTRBXR3wowWKxPlqv3H3sDYGFh9Uh/R0Z2emu7TyHFRqwKfv2N + 3MofCTDniY6ZgrORSMQWnXh6alxlxa6I0grTcDACG7+07GZB5UN8MZq/IeDdy+LLFgE2QREYBwxQn4Vs + o4urHrMLwsL/+T8ce/8w4yiA0V705oZW9t33oqXFWmGevuw6sFEF1GIh98XEaB6N1RJq3tzeTi1IhZW4 + FS1KMhzNeCIxrPZHHS1LOtrLZ6QBMFIE3HJVhtB029EghTjQixYUVE2PDiq0TTs7azhgwd/+btf78K0A + YHKLEf3j9KK10mJ93q+KZuzJvEQq8dmsEqs90O7f2NomazBY2aIkw9H8TWswZvy9PYiD1+DhXj+DwZhZ + WpscmwTA/ISbbiYxM8sfqIkG6wsvKZx8ACDkMJ6k5jkM1hqeZJvSRIPPBGC1Ip9ru2TnCgAwJ7eitKCI + XkHDXVZQLE7P8WQSYzr/YIArbqkMtQCgjlk3SdGjgkckmzMBGCzVpdAbrtMzcsoehP0nwAbslTBHN/a2 + 0h8LsI6RrBEXVomrClgFpZxS0jwL9hAQ91kBrBAVCPjJtVW3GnPLkB+CsakNdged/bEAs+j3K6oScxlP + ER5Un5kazMtzWQufd9eVpOwPAiftuZ/iUrlgK0cBbDAYNilaWlyIMWwWd9whsXEjgI+fCF+QoZQVMSUF + 8mZ5NEu9UmRNuOPHaTIZguOxbWQrrXWiGDbUs5D8I87LupqVdZ5rTDCzuMhvHVkF9rJa2Iq2ZYS60XA7 + O8YJkLsCuGe5BrMeupw17MJLmuYIQyFxn5UajBuKLNEni4xJyMNEdxUbn2Hoj9VEqyRFvIYMXVUiXBBr + okA6c4DhU2i8LdOmHhie1yDD3grfm+gjhn8owGBo2eBTX3lbX3FTc5Dlw6yHWflZT/KewCf4cdFj6rdU + f2+ANfJiniVBpcw1MvjpCYm4M/7139KyK5UedKpcxD8mYK2sGADrabepjPlSfpfPMTA6xWBxVrd26vh1 + 5FeIvzfAYI28kGu9zKx+ND8/Pzc9Oz892jUwAmGm3A3bwv7NemUdaeoEQj8qYHCxvvyGvipR4ycYA+CX + o8/dPteznoBrcOFsAQarFHnFvL/OTI2UlNBsNpfT68YAKzDAPKlmfLBrcGSaz+OvbG7DIpmNCIDD7kWv + n4l70biROHAy1lUnqVqwe8s8Ke/1+IC7xd3T0eIdXqzj1VFvL1MNgJE1iNV+O3Wyscg+6r1oqpHiMGru + A1Sfx+X2eczNzRBmKdywLa5E/Wp6qMVlsLWETH3zsEhm4we6F71rSg3eNTAuScBugARUUINXXs2MTc+W + 1TA3ts9YE42bWZ0KUANNXpdBy1fqqDV4bWHa79K5Qu36nrk4NfiHAgyWFumLrujqUjKyH4spyiyI+lT4 + Owe8syesBkvssC0gurHyemhkjE6jL23Ea6J/NMBgYFx4Scd6pA6os6qy8IFzCDOqv1vAEm7urWt/Byfc + +l+Xk/574l/+o6agBrZVWM6AtpdUUcX+0No/BmAwtNXAuCE9vSRV4Tvwsm+4v1vAFBfzzddl7NsPzl0U + GENwJjaFxklT/2/xHwYwWFIkzjmflvZLHT8LAYb4LADGXukoYPzno+S/X7l14MVwmbNH5sCsb8H+1+YP + 3otGzGQ8MBtoGm0R0itGDICRNYi/VS8aMa30tt2U18hNM7b1ktstLCz0NTf7A4ESOgcWf/Re9EGLedkC + YUadINbjJvCZqMHgypIkHvt+Qfb/abSel7bQLJ3YeGmJhFOWXjY2u4BPs/hHaqJ3rVJWILTCfVYAg7H5 + yLhZuryfRbo7ja6LspYaiZCdnZLR1Df6hwWMDaGN7TMEGI+g4zwx5JxTW+uETU/EArar2WVp6wfAF367 + VFBYVFxczOVycZp/AsZ85gCDdezH+pzzWgdPIpVMT45ubm3XcGokYn5ZTk7v2DycenGafwLGfBYBg3X1 + afq8C1cTzqU8SQGfu/7vgvoKY2u/sqX7AGC0F30m3i7cc9w4KlUlfqMjhgEwsgb1Sb9dGM1fuk90zBR9 + 4UW1R4TnU8yhK6wha+szq9WK0/zBe9HgH7gG49bVPsDfw4N8QnOtVwrmlzf+bKIP+EwDBuvo9/QlCZpm + 2Z27dyqrKjkcjkKhwGn+CRjzWQcMxsYtld/U+JX5jHwC5K7+BIz5BwAMxsYtVSWm5j9YW1sjWP4JGPeP + ARgsKLycl31NyW0kWOKAw6cTVsUbFx1tJmDSymNMJ0w6bgRw/ETkZcSUwNEt8UiQNaiPN50wbn09E8lb + uI+5T+royX431ymTECyPNp0w+EQq34kkAqVC1iD+Q9VguTCvlp6i2+thgf5sojH/MIDBVn09AXJXfwLG + /Cdg1CfC5kQS+RMw4giAv//phGM4bhwAjM4NHGYAjKxBfRLTCX81wATIXZ2h6YQjO26ck6rBCM5wfz81 + mAC5KwxwamqqkCJOI/ve7X/evf1TDCfd/AeyBnHSrTgRwPETiRcBHDdOYuK5u1l3Y/tOxh1kDeKkJymP + 8mpi+2HC3bQrt2P4wdUrSN7Cffx9knL/MgFyV6mpqf8fjOc9WOmdjTcAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAIAAADWjhTKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAAFMhJREFUeF7tnflz + HMd1xynSImiClAhCIkXwwLU3dhd7YncB8AKIc4EFSBykJIqiSMk6kki2pehIdJAiddlRIsW2jrKiVOi4 + Kk4lkkpO7LKOH5LKb/mn8sj51hDdb/phdzJY7i7mU99idTf4+s30m37TPXtt2bFjx71Vs6V29u7dC+Na + gHEtuHC0Z88eGNdCR0cH7KuGTGBcC+3t7bCvhe3bt8Pe4siRI6NrGBsbQ4kxPDwMGwb1ixJjenoa9ion + T55EiXH06FEYMwRHU1NTsFc5fvw4dYiKyokTJ2DMEBydOnUK9irHjh0jX6iokAmMGYKjgYEB2DPGx8dR + Yhw4cAD2Fp4E+J577kGJYQowDS5KDCHAgiNvAyw48jbAgiMhwEKYnAP80IvvXnzzE1mPXv345OOvcB0I + Jnbu3InuGIVCIe5EKpVKJBKoqFA7jBk7d7ajxDAFmMbdRYCFMzIFmLyQL1RUhAALjoQAC/nPOcCPvPbB + g3/5NumRV35mFbjOvfBW/vQlrtDwpHAzGzp7Ze7VP3ilroFj6JchzGDTuAsBFs7I2xksOPIyRVsBPrl6 + uTS7WpxZObly6aEX33n4xXeokQp2gIfOXKaIWv+uDbCQZwoPXV+4+r1XOhg3hsRP0RZ6gCkl0m3y8esf + X3z1/RMXr1rjePzim+/909c3vvrjY6+9/9aNL59+7W/pr6QXf/7R5KXnn/u7z05ffp4KlvIzK6FQ6JCB + 4sNeBjhUmEO/jMXFRToRzuzs7MzMDCoq5XIZxgzhjCqVCuxVyAv5QkWFTGDMEBxRtGDPmJ+fR4mRTCZh + f+jQ/fffv6Wnp4cu8Auvf0gz9diFK9Y4Hrtw9Y1f/9snN/71s9//17989z9f/+Gb337/v198/99fff37 + p6598Nl/fnfl73/z8ef/WFh6nBQZne7s7NxmwNsZfCgxhn4ZdG50Ihy6XVmTmEN/gjFDOKOJiQnYq5AX + 6hAVFTKBMUNwRGsR2DNMx0BZ5ODBg7Dftm3r1q1Kil4b4B+/+/Fb//C7D2/8+y+/+NP7n/7zZ199+9v/ + +OPLb3/4Z9c++s233/3sF58/8co1P0WvpUFTtCnAT7/9ybVfff7ihzde+PlHz1z9gAoU8p9ceffCK+88 + 8tMrcz965fxfvGwHWFgKRsceK114zyvd1zOIfhn+KtpCCnBu9tHc4nPZhWezMxeshdVauVtF07jTBppD + F/vIyAgqKtQOY4bsyDpDDYqiadw33SqadP7l9+yIahICvHv3bnTHoFuj5ViDBhclBk0FGDO2t+3Y+oPt + jkokU6FIlCsciYVuSm8nRWNxrRNb29t+qLXYGogntX4skaNbvvR2EplondgSHAWCIYwIo/YU/eoHj7z5 + qazzVz+Z+vNrXAdj2fZ24/MHU4BNFzshBLgnP2/fj1teQ/NPY0QYNadoIp/PZzKZQqFA/zqSSqVgwxDy + jCnAwiH6AbYkBLiGFE2Ro02VDe3YUGLQrjFsgO4WKDFWVlZgryI4ImDMSI49rI1CC2vkzLMYDoYwejRF + MVjh8OHDh2/PYAvh1kjLH1wUDD9Fb4Q8TtEWwtwXAuyn6I2QNylaC7Aw7kKA67aK7uxOJsvPOipd+YkL + aZ1UI62HKqV1Uo0iQ5MYEUbNq2ibBk/RgiNvH3QIjrx90CE48vJBh02Dp2jBkbcPOnbt2oUSo1gsWtsK + jWw2m8vlUFEhExgzhAAHAgHYM0yXLNHcKVpwZAowpQoXM/hAdHTq+d81rAaL9b0Hu0jR7gJctxR9KDmu + LXkaSqlh55Ml9ABHIhG6Q9jMzMygxKAbe6cBukpQYtCODfYqFPiJiQlUVKgdxgzBEW0BYa9CgTc5omOA + MSOQn9XGtKGUO1bGOTBo+4tz6Oy8+VJVf38/Xcg29D9QYtBU2GngvvvuQ4kxNzcHexVyRNkCFRVqhzFD + cFQul2GvQqsKkyM6BhgzejJT2pg2lDKjMzgHFTrT3t5enMPOnTt27Gj9FO3uHtw6KVoLsL+KttgfLJx4 + +tOGVSJvnB4bssgSNhXezmDBkbczmPIbSgy6XApO0F6oVCqhoiKckeCI7qawZ5guWWLTraLdBVhwlEql + ok7EYrGBgQFUVAbNL8QJjvwHHQrepmjBUXLuucqVb2vS0LmrMGYIjoQA0/IQJYafom8jBFhwNDj3Y23J + s66GHnwTxgzBkRDgGp5FU8KhDYbNwsICSgzaIvcZSCaTKDGWlpZgr0L7Y5ScgDFDcHTmzBkYq9D+mLZq + qKjQMcCYITjKLD6vxW9dFR++DmOG4IiuPxwoY3FxESVGNpuFfV9fV1dXbSn6LgMdHR0oMeiygL0KpQrT + xKJ2GDMER0KqEFI0jBmCI3czGMYMwVE8HseBMkwpmoaOZjDs77rr5gz2U7QjDZ6i3S+y/ABbCI56suX8 + 6us1KTh6FsaMegfYX0VbCI5MQ0Re6GJCRYVMYMzYjKto4Y3vgiM6cjwFUCmVSsViERUVd2dkGlwKsOlK + IhMYM+o9gxshwMn80WNP/PLO6kDEeJE1d4AbIUWnSnf+QX93towTYAgBNqVoIcAbnqK1lwsnJiZQYtAJ + 3HoNyoF9+/ahxHDxcmF2ZFIb7vqrv1DBCTDoZo8DVRkbG6PpgYoKmcCYIQxdOp2GPWNychIlFRrSnp4e + 2FsvF0ajUQqqzezsLEoMOno6Gkd6e3tRYiwsLMBehfbHdJSoqAwdm9GGu/4Kj5zBCTDK5TIOVIWiSOkK + FRUygTFDGDpaOsCeYToGggIK+337bqYHP0U7qnVStCeLLG9fTRosnNDeY1Z/HUoaNzamwaXdnYtFVr1f + TXIXYG9X0cKbTAVHdHgpJ7LZbObWJ+c4uVwOxgzBkTCDXQR4M66iG/xBhxDg5k7R8XQxdPy8oyInHtFa + bMXGL8bGHq1VWie2JEdjdXOkd7KuetITGG5GA6Xo9NGGfidpI+tOvh5cfYr2A+xaQoA3PEUXCoXTa1hZ + WUGJMTq1oh23rypVOv8W1nWMkZERlBi0fMHQM1ZXV1Fi0FIA9qlUIBDwU3Q95KfoFtedTNHVz+Dk4OC2 + u3c4ave9e7UWW5FYvLc/xBUIR/sCeqMlatc6sSU4CkcNjkKRvkBYa7TUH4pondgSHAXDMa0fS/3BcH8w + ojVaCoYiGG7GZnzQ0eDv6PB2H9xAKbpuDzoS2eHMmZdr1UBiEPYq/oMOJcDCxBIC7OJZtGksCHcvNsTi + zgGmcXcxg4UzMg1ugz6L7u7upiOzobmPEoMCjHdjMnbv3o0SY2ZmBvYqNLgoMdKlU1rwqhHNYNir0JVk + xZhDw4SjZAhnRNGCvYo1g1FRIRMYMwRH8Xgc9gwhTF1dXbC/xZZ0Oj23hoWFBZQYs7OzQQN0KCgxlpeX + Ya9SqVRQYpTG5rTgVaPcUAn2KtYb3x2hY8BRMoQzor0m7FVufguZwReZwJghOKLrD/YMIUz5fB72weCh + Q4f8FO1M66RoT1bR3n4JS6o4Pv/6n2qVKcBW2kRFRQiwcEamAFspGhUVIcCCo5ZdRVOSgTGjra0NJYYQ + RdPEEgLc4KtoIUxNsIqmUMGYITgy7YP9FK0EOJPJREaXHRUeXe7JzTmqvUPtdA0uUrQQYCGhefugo2VT + dDKZ1BYv1Wh/cAjdMVykaCHAQkLbVO/ocJ+i6xZgdyl6p/kbLbxN0YIjU4DJi4sULTjyJkVrrwfTUWrB + q0aJ0XnaTzty7tw5dF0LMGbQHQQlxtmzZ2FcNUtLSzBmCI6El8xNkAmMGYIjmhuwrwW6yGCfTtNW2E/R + zvgpWpGfookGTdFagGkP2hcZdFRvOPnDe/c56gfbd6A7hinANLgoMYQA+6toC/eraMFS2Af7vwBOuAtw + vX8BXJhYQoDv70sPTD7pqPj0U/EpJ5nab0nrxJb0J8GR+U9aJ7bor1qLLW8d3ddr/I60DUnR7mZwcPSc + dlf2VaUCwysYREYDpWg/wK7lLsA1pOihoaGFNSwvL6PEqFQqCQOZmSe04/ZVpdLTlzGIjMnJSQw9wxSm + xcXFkZER2CcSfX19/gy+w/JTdItrw1O0J6vone3td9211VGx2EB/f4ArFAprLbcVCGid2Gpv36W12IpG + Y3o/txQMhgKBoNZoif6kdWJLcBQOR7R+LJEX6lBrtEQmWie2aOgwiIwGWkULv1Pu7YMOwZG3++BW+4l3 + G3cBdvGgo1AoRIplR0WL5QPRUUf1pMa1FlsDIxWtH0ux4floaU5rtETtWie2BEfUodYPNDRdKpVweipN + /6BDeKBqCnA6na688Y12Q2pqzbz0ZT6fx+mpCAGu97PouqVoP8AW7lK0+33w6uoqSgxhH0z9osQ4e/Ys + 7FXoGmy9AJt2rrRtxXAwhKET9sGmMK2/D/ZTtGv5KVrBD7DFhqfoO7WKLhaLoczxUOaEo/YeiTvqYDin + tdiKDY1rnViK5MbCWb3RUiR7UuvEluAomhvT+oHSx/xV9G1MW0ZC2AcLjvx3dFhsyAzes/f+tvY9jkpm + iuF4mmtgMB9hjZaoXevEVucDh7UWW4lMQevHUiyZiyQyWqOlaDKrdWJLcDSQymv9WIomMrFkVmu0RCZa + J7YER0f6I1o/thLpIa3Flp4SPAmw/yy6QVS58h1CYuNJivYD3CByCHAmk5lfw9LSEkqMcrkcNpCauqx5 + 8nVHRAGmGYuohMOHDx/2U3RLyU/RLa71A+xuBu/rS0dPXXZUuvxMavZpB5nab0nrxFZ88kdaiy2jo1nB + 0TNaJ7YER3KHrMWSG0fJ6SdZP5DpZAdnntq2bRuiYuFJgF086BB2csI+WHDkvy/aYmMedOzZrz3usTU4 + PB0bGq9Rp7ROqlGydkfxwoTWSTVKlKa0ftZVNG38FabmeNDh34NlCd9VWe8Z7Ad4IyQEeMNfbND2wQL+ + Pti1Sg9fx0jVAk02DH0tFAoF2Pv74LrJT9EtrjuZoj1ZRd+zv+9IetpRqfGHEidWa9RZrZNqlBp/kPWz + jpIn3TgaHDun9bOuQlnjz2w1xypayDP+PphooH2wuwC7eMuOuwALjkwBHhkZCYXDIScikSiMGXfffTdK + DBoHdK1Szze+1ztFC3nmjr+jI5fLlf/qa+2m+P/RQLqArlXosFv2HR2NnKLrFuAGTdHaPnhhYQElhrAP + pkNBibGysgJ7lUqlgpITMGYIjpaXl2GsQmPhbYDzwyfRNcN0UmfOnMFRMoQzoskGe4YQpnX2wX6KXleb + MUUL3+blbYp28UVoDZ6i6/1FaHVbRQupQgiwi1V0Pp8fLD+bXnzBUanK87Uqlkija5V6rqKFMG26VTSN + O3WIioqwDxYcUbRgr9L0KTqVye/qPOSo/d0RrcVWcuh4JFXiimdHo6zRErVrndja07kPx80wBZiiaBp3 + IcAt+12VQoAb4bcLD8aNITEFmAbdxQxu2a8yFFJ0kwZ4s6fo6t8XPTyxpA13/TUwehpbPIZpH7y4uGja + ntJuEsaMtbtJDdrUwl7F+nguKirCPlhwRNMU9gzTyRLr7IOFS8NP0RZ+it5A1S1Ft+yvrgjLs0SmGBw9 + 56joifNai63U9OXk5GNcqSlqv6Q1WhqcvKR1YqvjQB+Om+Gvoi3WCbBwaQj7YCHPePugQ3Dkp2gL9yla + CLCQZ7LZbMyJZDJJJ4CKCrXDmOHCUSKRiMfjqKjQn2DMEBxhOBhNn6KFAAdGVitvfLNJNJAawoiotHKK + prujthpqYXn7YsOGp2hKlTNroC0jSgy6m3YbSE48po1CCytbPI4RUSmXy3Nzc6io0BYZI8WgOwVKDLpi + YM+gDlFSmZ2dTafTsO/ufuCBB/RfAKe5jxKDZvBWA5tqBsfTBYyICk1fWsGgokIzGCPF2Lt3L0oM4RfA + qUOUGF1dXbDfuvXmL4D7KbpWNVmK9iTAB2JHCw9e2yQyvR5Ms6dlV9HCUpDu3CNOWPsxVFSoHcYMwRHt + g2GvQrOKhh4VFfoTjBmCI9MQtfIqeteuXSgxXDzoIGDMEBxNTk7CWMUKMCoqwoMOwRFFC/Yq7gIsOGqg + FC3kGRcBTuZGhx/9m1o1kPDyN/yFMzIFePOmaNirCIeYKo1r65pqFIs7B5iiaBp3IcDCGXk7gzc8Rff1 + 9dFh2dChoMSgK7TNQGdnJ0oM2h3CXoUOESVGZmRCC141iifTsFehbEaBREWFjgFHyRDOiO4FsFehS5Z8 + oaJCJjBmCI5SqRTsGRMTEygxaMbCvq3t5gdw6DKh5YkNbdVRYlCntMdyJBgMosQ4ffo07FUo8CgxCsfd + vC6Zzg3BXoX2/pRFUFGhP+EoGcIZzc/Pw17FetSAigqZwJghOKJlIOwZQpgSiQTsu7ro6vFTtDMNnqJN + x0A0wSp6sHBy5qUvapUpwDTodVtFm64kIcCbcRVdKBRgzBAcmTp0F2AXq2h3AW76VTTdSGixwMlmsyg5 + AWOGMBylUgnGKplMJp1Oo6JCxwBjRt32wU2fonPLfz3z0pdNp8OpSZwAw9sZ7C5Fu5/Bnge48NB1bTXU + FOrOlnECjCYLcCwWo12aDe0cUGLQUe430NvbixKjSQMcHlnCCTBoi4IRUaEtCi04UFEhExgzhKGjmw7s + GbTJRIlBAYX9/v0dHR36gw7h+YPwoIM6QonRpAHuG5rHCTBoEDEiKrRko4mFigqZwJghDB2tEmDPoMmG + EoNSMuytBx1+inZU66TojV5FD0w9efTxXzSdDkSM3w8rBJgmECoqQoCbYxUt7xqLTtD2ie4xqKhQO4wZ + wke16NKEvYrgiE4KxgwXHz5zN4PrvQ/2PEW7eNBBN3sYMwRHtMaBvQrNqtZ7kuU+wIN0Z6/8tGG197Dx + q8tMAaYomsZdCLCQOYUAN0GKTiaT2nKjoVS3Txe6eFRJXlzM4HqnaD/AFq2TorPZ7K3PDQNakmhj2lCK + Hz0dNWD6TPTCrZ+2RkVlcXERxozBwUGUGKYPgJMX8oWKCpnAmCE4omUj7BmmT5rTMdDiEfbRaHd3tz+D + nfFT9J2Rn6It3L8eTHuhoIFAIAAbxvbt21FiJBIJ2KuEw2GUGKFQCMaMtrY2lBj+KtpinQC72wcLecbb + fbDgyBRgGnc/Rd/GXYCFPOM/6CCEAG9sit6y5f8Af2XvE6UgCOAAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAIAAADWjhTKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAAGnhJREFUeF7tnYdb + GtnawPc/+p577+7eu3d3k6iJm2bXmGy7iZtqElM1JsaeGM1q1oYFBRXQ2I0d7L1r7IoVpSMKogKCut/B + OYsjOjobiREyv+c8ed6ZeRlezo8z5QThi2vXrlH3Iz4+HkbY4MkBxMXFwQgbEokEI2yMVVJycjKZTIYL + 2Bxm2YmJiRQKBS5ggLPsq1evfkGj0f7cj+XlZRhhgycHoFAoYITN4uIijLAxVklra2urq6twAZvDLFul + Um1sbMAFDHCWnZaWRgj+PASDKBab6OhoGGGDJwdgrF0ZKydmk2fPnslkMqRTdsXkBefn5yOrdgXsDkbY + 4MkBGGtXxsoBXQno7+//XAS/zhkITO9FWkUPH3QAX6oEu1tcXjXorflFFYz+/HNWIO+emNfuqGpBoTZY + Z9Dp4vq6/qAApA2Hv97QrCx0dS7OCOFmIGB1eVWxsjgypNXoH6iVdXcp+JLVealaKoXrdqDVyJZXNXAB + m89O8IWQWrvAaqQllrGVS8qyXtHIuIT5XiBVaQQLqhWVRiJXN7/nyZQalVojXdZ1YueQRCxamJhTiRfV + DT28hSXVslorkKmb+wRKjVYkVytXtauaNcWyWiJTSpe2+n2KTquzt0Fa4yVX7QJPzpEIG2qUAr5WqVmd + E64plSreuKSLva7RKEXiPzf+XBrqVCq0ovp6zfKyuLYKqyfmFromROxVsBetclUjX1ldXlZJlWrpklqu + 0SwqVAurmkWw8nMXzOXOT/Fk9QNCIFgwr0gqHspqnGkfEjA7eFU93Lqe2X6Orl9K6ybymmaLmsbjy9ms + Dm5Z63TTgHB0UpRazy1vm0woY1f0CYYnJayOmcKm6boBEfJcgB2CZ8apNFH7gKAog5NJ4bcNydqZgpZ2 + fkmZqLVJNjK0PK+c7+0ED1xo7uDX1Yr+EixVcNj8OqSNCeq1a6oZccesuG1a1DYj6e5ik5vYmd2cWqms + p5nNGONVjfCqutmJDWP5JiRYvrxa9V6AtPp+gVEEj9a1c2re86jlE+/aePXDwoaOqaxWweSMpLqbX97F + re+Z7ZhYAI/qGp4D76nW97Pt41Iwglk9vIExcfsQn9HIberl6lb2csvaZ5uGRR2Dog72HPJcgJ0jeJG3 + oFkUzJQ3zGYlc2vbZJ1Vop5+UXWNuL1F0tGhlKuUU4Pi9l5eVa0YJdiANc1c9zSrd6pwRtrFneeMzJbN + SN4PCnoneOVDM8Vj3PL+GdbobAlHOmxCggc5Mp/4ciprLK5oyNUnQ61Www3Y7D+C19Z0z6RWa9Sa9fX1 + DeXqmnZtY31jQ7u2rllbX1tfX9Wug4S19Q0gGCSANLAJ5ICTm0oDEjbASl2wtq7W6hY1GrB9q3oDwcgp + cW1Nu65SrWu162oVWNDtYvPfNRXykjbAcVu7uqpbiXkZBWoEGzXgkaCv1nXFanW1gAP9mpovaRzityAr + N5/QZASfuJUIvNj4Mu08aXgFMxgM4CY3Nxd5qZEFQ+A6C2ngUICs1LndDzw5APBcMNpE3Ngw9HsY0kai + I5GVBjm7YsSSQBoQPDenOwhhsbS0BCNswJsARtgAwTDCRgnevlotXEDRNynVC7b3osv5/L434ex4Emjt + fs/BERvmoaDT6YYjeFdAKoywwZMDMNaujJWDOAaCFxZ05xosgGAYYXOYI9jekybjTKc7O773edrl7ZVq + ZaHV7HLLsHWIbmhoCMEmMDAQRtjgyQEEBATACBt/f38YYWOskl68eBEcHBwUFATGDdIpu3IED9EyDifZ + 4litvU213flUyxNg0MM8FFuC9wZPWXhyAIfZU3hywCjHczlKCCYEE4I3IQTDCBtCsA5CMCGYEEwIJgQj + EIIJwYRgQvAmhGAYYWNkwUlJSZL9EAgEMMIGTw6Az+fDCBsejwcjbIxVklgsFolEcAGbwyxbKBTCaDtN + vdNowZy+PrTgXfdMJpO/SElJWdmP+fl5GGGDJwcglUphhM3c3ByMsDFWSUtLS2DkwQVsDrNsmUwGBjpc + QNHFFqIFi9ijaMG7vgoqlUoIJgQTgo+aYD/mvSjv0d4KQrB5CnYILCWVuHGG2gjB5in4t8i0yHdPiEO0 + 2Qp2Cnrn9DSVEGyegn96nReef9Pei7jIMlPBPrTgh+RXxFW0DvMTbOkeTyq74vIijxCsw/wEW92O/zGs + 4O/dB9NoNLiEjVwuhxE2eHIAoHoYYYMnx1glga5UKBRwAZvDLBvrDdfNFr5Iv/7z77lAsL0XXTI2tq9g + 3Vw0MYJNZQSPzgxEFV+zD6oiZrIgZia4foB8jxRITFVuYbqClxSKRbEYaYrN3S4vL/WMjVh7xBGCtzBd + wYL2tubgoAlK8khcbInbZTCgeydLMuszkYkOQjDEhAW3tVIsj9c52FbYnc+64LyokL1t9KjsaTcfwcuL + i/oGDk9wAwozEwxe4qJiGWnS+QWdYIvjdfY2FTbngOBxXntBm0/XqMBAsN+X//T/6l8BX39JPnHMxATX + 3/cYiY1mk2KYN67x2lrhBhRmJpjVyXnJaCMVjYRlvb8dXiJo3SZYMs/lCHv1c9GI4HmRiFtbza3RNV5t + za7XZUdXcJa9TZWjXb2zQ4qVBbe5CW5AAZ5upqpyKj9vuiBvPDtLPDgAN6AwIcElLRPW92lOL2psn5f8 + FpwlaG3RC6Zesq7tjwc5QPDx66RzPiVnvd8BweBIjjx2D46wYDubSttz4BWmWJ7AElzt7dUb8ftodGTh + VbfR7Cy4AYVpCbbySAOj89yz4m2Cbc/Fh55vH80EOd1s4Tc/v/r28hvQnJ5l4pkzMW3B5R53ys6fATmM + k5bmKph10Sal/FepTADz/kKBr2y8ghcWFmCEDZ4cAJ5OB725r2DwdPsKxlMSTsE4y4YRNlglbRecrT8H + sxzPZfn+AoqEeX+Bs2wg94u0tDS4tJ3+SXF9LxdpYxwhXIsNnlMCAE+ng97cVzB4un0F4ykJ9BSeuWic + ZcMIG6yS0IKvvshBBNc42zLinLJ+dNl5AYWz7NTUVMwRHEpvTGEOM6onn5AqKMXdcC02eF4egDhEw2g7 + ux6iC30c0xKcwFX0roIPeoh+QmKdfVoInvLkPToh+PAFJ1seT81xLbpq8xkJTi4bTK1gp1aMRef3dA5x + zFyw1fHixw7IfbCJCW667zEYFjoY9qrit8sLAsPrQwCW4J8D8wNoXUHpvQ5etNLmUTMWzOtuTU5zrnWC + Ex0mJphx2rrpyq/Nl39NsbKQ8rjI+sruWWbnDGiszhm+ULyrYKdnWTa+5aAkC/dk8xbcOpxOi3UEL80k + BdOsLGrsztfa21Atj+sF33xdksIaA+1H37fD4zOfs+BfA1NSmb9SHazMSrDV3RRb/wq7gCoL96TPWbDN + 80KPCPpobT6cyTo0wXOjo7y6WqRJ2WyYhMLsBfMbG2AP1NeDx8ANKLAEtw4J6nq5SJviiuDa7egFe1FD + qSy/ranKQxPcnRA/kEyeYtCag4PaI9/AJBQHF+wQWOYYzDyygpl3b0/SaZO0tOxLrlIeD25AgSX4XhSL + VjnGqJ68FZpf1jwK125nU3Dqg6SoyMLf7oYzPoHg1jfhBWeswVPmnj7V/oeRBS8tK+7GBMWUut0nR14O + CRueGD6CgreX/TcEo8vGElzWNubiR7odn+ASlKGf6DCOYKyPzaIFp5b17isY58dmQdoOwcscYe/rnGvX + oynOL0rvk55lNj5Idzizt2Bm2/i+gnF+bBZ0FlzAZkfZuwjGmoZEl81qGx/LyhxLoY6nUvtJsbyWFpDA + EfVlNz/xZzwBOeAi69rLXIP/8N8pGGfZQO4nHsGS2WlWT4RkYfakBxU5B1u6J6XXhEWHnI079h35xLGY + 7781sxFc8fB+h69Pf1BA7qUL3W/jZYtzOS2eiWUJp+6lIoKNPII/reDaVtK7dj/F0iL6Iqt3ZKQj5Y+W + Vy9bQ0PaQl/NseFh7TAFC+fkIRmdkQWDoHkmNIjFEmMJRsqucbahh9pTmD9N8DsUSzKD+2AzEZx03iKj + xl0q44P1BlfR47zW2v4E5CF6DlMwVyRz8KI9oXR5JrVb3aEIhSIjCi52Plv82IGc5NjPzEByTFgwqA2M + Bn3TC666ZEv55ZRwZhxJMxAMrNPqrskV2/Z5yIItbpFBPbb+lZa3jSmYGf0oJce1xsWWYW3J/qtsExbM + E8ueJtSkVIxTmGOufnkika6nqu3PZ8a5UEJsse6DwRpWT/jAdAWyFcEMBNNYJVTmL4V3bJGyzUEwV7zZ + U4FVdgFbPVX00D41x5VifWIPwYK5sTnZtn40dcEn7ySllBfQHznqyzYjweieOmVR4m5XdsNus6cwBQMq + 3v+xIN+a+jF1wX50r4b3jeiy9xAc/t//pFqdAHeJmaYmWEiLcmT+ZvdXT+0luLI3qn+KicQAkxZ8PTol + Iu8ys3UQj2DJ0GDxwwdMz0fljx+2hYaYkuCG3owkhnO1kw0ewWxuY1lXKBIDTFpwxLs7F32D9bdJewve + adSAIyrY2iM+reYaxcUK1VN7CZYrpG2j8EYCcAQFszpnyts5oDE7OHzh7v+RAMp2CCi6FPrO8vbWffBO + wd+5/QEcW91JOUKCG/pmM2rG3tZO0CtHCxuGhF2dYxnpk5kZ4xkMdl4ukqMX7BhU/lNwOIc7sb2n9hIM + 4ElGhdIJJD6Cgm+8LqGy2BTW2KXnuv/GHqXTJt9mgB4YSCLPjcM7QFe/jD8Kr18IKQZlYwlu7ufefJnp + Hpp/KzQ3jN5oTMHJyckLu+EZU64XnFTY2fR7mF5wS/jvSE5kVotPUkNIZv/NCGZgcmU/g171+OFgyIuG + B/dKHz1AciZnxUhPeVJfB6Q/5nK56J4STE4iaWjB/SNwJaBjNK+2LwmJHZ9m6gUXNwyV3bmt76nBjHQk + Bw24JYMRNuC+HBxa4QIKfdmIYJxlF/x4sfdlMOiBdEf7qbo6JMeLHP08+dpXF/y++flVceNw2R13fdlD + u5UtkUjAWxMuYIBVtgFALub3RT9LqNILTil93xkdqRfcHRON5MQXdJ32zAE54N9gStV4Xm6mte5zCMXn + Tlc88UJypAo16KlLoQWxpVfOPSaBwtE9tTIPfwAY3VPjHAGyErCwNJvX+gSJnX2y9YJZbeMVD+7pe2qq + YJdfbgPjAEbYYH1ftHRRV7ZeMOis7WXPI2kGZaP/E0zS3QUSNv7cyGjwGpwZHOXKQRPNyZj37oKtb62t + kiyOTb3bpWys74tGg/Nrrvf6QnDjCr4ckf6AHAF66u8KXt9YK+kKWtWugNgUBStX5SqNAmhG8kFJreGv + s9wu5/x2BTRBfR2yHo3pCbZ9HHErNgnpqb8rGKBdW9Vodb879wGC17XaNZUKaSBG1q9vbKhW15C2ogId + 9bEEg3dnfpv33OIkkgzA854zMcHzCvXzlPsPk/74YMEzc921A7Eg+ADBwynUgZjoscT4Nn+//sR4ZP3w + rNyf0pBQOhpTOPRL8Ltdf6fVKIL5C4NAMNCMJAOOqGBqSc+HC14SRBVfdQxmfrDgFbUss+ne+ob2AwR3 + RkW+O3em3sk+74x1dywse5Ajs3QnOwbX2Pmz7DB+iNcogmsGYsYFTUgmwhEVHJKRUBBy/cMEi2W8G+FB + +p76AMFgBOS1eslXBB8meKtslGD4p/J+uj+V/0iC+e1N4NIBPXwBR1Tw75nZycU/FrjoevNvCV5WSRuG + CtE9BQTHfP9t5Hf/jfr+v6Rj3+kFW95O/uFR1g+eOaDrDQQDJIsT2jX1RxIsn5mpf/xoJPLN8JvwElcX + 5OdLDi64IPPWhLAZSdNzRAWDc3BTM+ltrPPfFdzCTmP2pBkIHqfTxmipoI3T07QqFbIr56cMu4fJ9g+T + nbwZU1wRslKPQimpH0p09tma6MASTCrsD83qe50z4JXYlF0zhEewjMOhWFnUuzjWOjukWp5Afmn5oIId + rOg115GLfzRHV3BXXFT+pTNVP9viF6xaXWTU3+LOiQwEI4/dg8UdP0Ck1ixlNnnYedP2FQzKvhxWeS2q + 2cYrQ3dtiE8w+vuIjCKYEWDXPpaB5KA5uoLBRVa2yw8pBRezHK1xCl5Wzw9xK8Bt0vHrpDNP8k975YHj + 8IcJBhR1+F/wjdhX8NN4UHbRVtmfQnD1RVvqWQtRv+4+2IBPIJjBYICzzk684yv1gtPK+9oj/wA9lRfq + lBRj3xkTheSQ8jr1gkNSa9k52XrBxY/cm0dTQY5EtmLtTrJ2jwPNxjNdJpcjj92DpaUlGKEY4zf9FBip + F1zRMcm676EXPJGXi6R5x4GyoeDNst/oBXdGw7L7JqV6wfZe9IXpabRg0L8gR7ywvE2wTIYWrBCLkV2h + BU/OihDBWVHOcd5nhB3tSA4aIBhG2CiVShhhA+yCa0O4gA2dTv8bIxj0VK2zTSrZqSdZd1cK2GMEJwac + axxOQtLQfPBvxK2va+9Gx9j4HfURXHrZhlp8kXLWApnJMuBIH6JhT505VRB9E1wegxxMwRfOUsp/XlLN + IbtC88GC19Y11KqbzsG6ko6y4MwXDu/8HZH7YCQHjSkIPn0q4/dLxZ2B4A4PU7DDmdJUH7ij7XywYEBE + wUuPxJhPIlh3+37SAiTsLTjnvgvL5XydA5zoQHLQmIbgjug3pd0ve6ff7SqYdc0uNcK+whtOdBhwEMEe + seRnaS8OU7BLSPG9xKjnqY+4gvGkiku0DNf8QEfqyRO7Cm7uq6eU/lTupvvEpGkLBlfRKo1iRb0QnZdr + IDjj7EnaW9d0Txv9TJYBBxEM7oOdggocgisOQbBEvnjqLulN4c2wvHvXw4PnF+bTzlkWP7Av9HZIvnv6 + XfvzKVGrdk2NCLYPrDj3MIpSdZVyZ+tPqkxbMEhQrsrTam/cjQtHC056dCYj6ULx+a2pSgMOJjjbl/bU + PS7xowrWaDRcaW9W0/0rr4IuhBTZBVQYnIPBBVTXYFZOy6NJUesTin9wpnd4wZ1zDyN7xtr098HmIBjw + tqY+stDtbkKcgy89OCWrsjwkw/ZUjYutfiZrJwcUfCOK9CLryUcUfNaSNzeY3nCreaTMwj1x74usjY31 + K6HhntTQm7FJJ+8moCc6zEQwOAfbPGW4vip6keVFZv0vO+tG5tmTIOfjCXYILCSVXfnBI87ogmucbQr8 + HSn5rkr1klqzdJCJDrMSjJyDz3tnhqSVbV1FfzTBNr7lP4bln7xLNqJg0fRw8nmLjESXtIwLqZd/OOBt + knkK1p+DD0HwhZCSiAK3yg72HoIdg1nW99Pii+MLMx8xQuxrnW0Y/nbl6U/Z/HqVZrGyN/9muN+16NTL + EYzQrBspVf+jPjlX+ZNttb0R7oNNRvDToyoYPN3LrPstw7m7C06o/C0iJrLopovvm7jisPwcD/obxxoX + G1qUY3aBe8MwWaEU57aEBNDveKWEXXyVezcyjD/ek2x5HJ6DNy+ywH7MRzDOueiOzbloRLB+UpeUvzUX + /XL7XDTLyxPJMWDXeWYDwJsARttx/utz0U4+sfQ6jzKPW3rByFz0imoxmZkRVXz9Tnw8GMH6KXSk7C79 + XPQUnrnolW2CDeaiJXvNRSOCTXIuGumpTz6CwVV0aWtvZdyToms2tU42jFOWA7mUltHUdx2+fsks2+f5 + W2V/6H0wcQ7W8QkF6y6yqE+Tiy+m5rqmOZ6kFv1U2fdGviI4+H0wIfjICH5wr9jpbOl9B/ppy/GiXCSH + EIzG5AUb8T6YEEwINi/B3iTml84+X7kGfPNzaGpZLyHY3ATLlldFC0qkSaRyIDj/tDV4ebk/EILNQjAa + UBa49w36+svQb/4d8e1/euP2/8gOIdjEBOv+ikutQpr+r7gIwQaC6efPxh//PsniWOz335qYYBhthxD8 + 3eWIry74f30x8Lsrb4Dg91GRra9etr0KaQ8NWeJwkBw0n0Aw1lQlGlAWjLazx8dmDzJViZWjn6oEgo/I + x2ZL2jjFrZutjTM3L0NW7gFWT6I5pKlKNKY7gjuiIqO//5ZqeYJ84hh6BH/zSxjYCTiu2j0+0AhGg1U2 + mk8wgs1b8HRZSfXzZ3W+PrW+PrMsJpIzK1n2ia/wJdc8J1eHZbTJZ2YIwaYqGFm5B6CnFmdnCcG7l0XK + a/+HvedXLn7/vhQUTKlm5+Z4/eP/Ar7+V/C/v/oYH5vFI9gruvSfDt6bJQXjF4z+rXRC8BZTQkXjoAhp + feMCJZ8naWxAmnxoCCZt52MLHpqR6Utiz4iRlXsAekqlUEiaGmHlTY1I5+4UTLE4nv3DSXCxlmzx2QhG + gycH8LEFo8FTElZP7RScefFCmrNjmotT9sULKrkc5qEgBOswXcFwAzaEYB2EYBhhQwgmBBOCNzmg4O+v + Rp96kA6a5W3d13nCDdgQgnWYimD58uqvfoxf/TNAu/qqSCbb5arKgCMqOCkpSbIfAoEARtjgyQHw+XwY + YYOVg/622cL6wVLU17b2M+gwCQWeksRisUgkggvYHKRsNHhKEgqFMMIGZ9lkMhnz+6LR4PniZTw5AOkB + fqf1ML8v2oCDlI0GT0kymQwMdLiAAc6y9/pCcDSEYEIwIZgQvAkhGEbYEIIJwYTgTQjBhGBC8CaEYEIw + IZgQvAkhGEbYGFkwjUaDS9jI5XIYYYMnBwCqhxE2WDlowcy28X0F4ykJdKVCoYAL2BykbDR4SsJjDmfZ + urloYgQTh2hCMCGYEEwIRiAEwwgbQjAhmBC8CSGYEEwI3oQQTAgmBBOCNzGi4JK7t+OOfUexPA7+JQTv + imkL7qMk1/o9r/P3rfPz5TU3wSQUhGCd4EOei8aTBl4hjLaDFsxsG4drscE5Fw06Cy5gc5Cy0eDZD55J + ZpxlA7mmNIIdnjBO3Ey0vEM9djUGjGC4FhtiBJvYITo4pf5xVOnj6LLH0eWt/dNwLTaEYBMTjMZYJRGC + dRCCCcGEYELwJoRgGGFDCNZBCCYEE4IJwYRgBEKwCQs2oY/NojFWSaArTfRjs8AxXMBG97FZNze3hP2I + iYmBETZ4cgDR0dEwwgZPjrFKiouLI5FIcAGbwyw7NjY2Pj4eLmCAs2w3N7f/B9VB2SaISaQKAAAAAElF + TkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAIAAADWjhTKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAAEGtJREFUeF7tXWlQ + VFcWnl/6J6kYrcriLjqYVEqnTMVoKhOjM3EBwZIYtQIZHU0MGaMxI4oguEQFxNEkTmQXZImJScZdRBEw + ihsuiAMKGNGABqRRGmUXMHNf3/fuO/3u49ENPW3z+lR9RX197nfuPfd8aU33ySN/WOofGL19R3R8EkFU + 3I7I2ATKY6QgW43eniiS+KRt0dulYKdlslJFBrlEgCxRSDdxvk5ZJgSlYjhZREx8lLQJvyoTsmFUrDKo + KouOUwZBK1hQrSeykl3H7LKUQN6BTFz18w/4Q+qxnx80ttU0/U5gbGi7X9dC+cPGVkrYKiMEVQ8aFEGZ + ND2mhEBDVtP0mCl5mYmzAkQiy4REMZevk8lgkJfdq22uaRQ3AWeJq7ASg7FOEVSX1dQrgrAVKreQc+VW + sDrb6Qk7l5OZnSXKDqdnocE0qHVZNNicgJM0ZGgwyEWDFTIhUdkRlstkMNjtDM48eTY2IYkgLj6REsgZ + iY6NpyQWyL7+JsJouhoaLG7igAanZfzc2vZ7+3hMSUtrGwiKyMk5/+vdarIJGixu4rAGZ5RkJV5OSryc + TAAt7NDg42cukE2UBlfVNu8/fGx/WibBwbR0Sg6kiRFCDpgIwZ4Dh1mQIxkElDPZqZxL9AjVW6HB7Rmc + dVP4WdtUf+SX9ILS9F15KZm/XtqVn9Hc1nasKIMsUYPrmxpbW5rTfjlFOAExOOtUDtlEafCtivszvp4x + 99u5toVPvM/fAufRI1RvhQZrGFzX3BCavXHb+ciG2pv7CtL2F58+cu3YDUN+6IltqQU704qz04sOrj+1 + k7ynMwozOzZ4Xuq8JXlLbIuFZxd+GP4xPUL1VmhwewYfK8mct2/e4sOfHb91gli49UREyrmknOKje69m + pubvi/o57MvTsXGXEg9dzSXi40VZHRs8a/+s+Rfm2xZzTs6ZEzafHqF6KzS4PYPJO3h5+oqKh5Umg38v + NpQUG26evn5g/7WDYSe3Rpz4aufF73YXZf2Ud6C1pWFbTkpLhwZP2jlpeuZ028Iz1XP2Oh96hOqt0OD2 + DP4+/4fTZWfP3T4fdSGGvAR4/OhR/fac2AJDpXlcgJbBr8e8Pm7fONvizV1veq16jx6heis0uD2Daxof + GuruGeruE0ALO/y36HYNHv7l8BHJI2yLV+JecQ+YRo9QvRUa3J7BuTfvpefdTs+7QwAt7LzBzwc933dL + X9vixdAX//r5ZHqE6q3Q4PYMvnxLfOPm3bp/s8yQceV2bqkxq6Cyue3x+SLhD2dqcGNTa31905Er5R3/ + HdzDvUfPmT1tDK+ef/YZT49QvRUabInBjbV1J6+Wn7xedbaw8rbhQcrJG+cKbp+7bjhfXJF8+jZ5T9+4 + c7+5VdPg+3UtF68UXiq4TnA5XyS5+UUKQpCTm68IyqSgOJeTFZWU0SNUb4UGW2Iw+flD9i+pObfyiyuO + X7t7quD23hNFP5y5eSi3LPtaNTG4pKKGits1GL+qZKuwEscxuNRQS5B/vSL7Wvl32Tf2ZJekXyo9WWzI + zKuorn6482xpk/Y7GA1mq7CSJ2hwVn554R1j4Z2aQxdLqdMSyMek1kPnf71haDCPC0CDBdItDK5tbDHW + NVNACzv5b9FoMFuFlTxBg9tHpwyuqm0+kJZx8GgWQUlZBQ2qXkbDOTRYXgWtsNbgsxevBASv+ch34Ue+ + /zD9pGBcJPM/+lgRofzEWWF8pzSYfEya8ZUwTfLa7BWbnEKDqpfRcA4NlldBK6w1mMjIn6ald6tLK+4J + P00okzgjN0rLKSm9e18iwuqdew/JJioG02nS3ANzY79FgwVC8KQMpgQeAc7lZGZniTIVg+k06b0978Wg + wSZCoCuD6TRpYvLE6JRkGgSbyifxx8sEnKQhQ4NBrh0NptOk0ZGjo5KTaBBsKp/EHy8TcJKGDA0GuXY0 + mE6TXP/lGpWcSINgU/kk/niZgJM0ZGgwyLWjwXSa9Fzgc5GJO2gQbCqfxB8vE3CShgwNBrl2NLjHVGGa + 1MOtR0RCAg2CTeWT+ONlAk7SkKHBINdeBpMPXufzrl7MLyb4zWCkQbCpfBJ/vEzASRoyNBjk2stg/KqS + rcJK0GBzAk7SkKHBIBcNVsiERGVHWC6TwSAaLLxGg9kqrEQ/BlfVNh88mnko/ThBqgrJooRgX+pRKaiU + HUqXZZfyC+nOoDJWLhrMcu1lMPmY9O5X785JmWMTzNo2a83WULozqIyViwazXDsabMNnkxZkLlgXG053 + BpWxctFglmtHg234bNL7R95fE4PvYHHVUQy24bNJbv9xC45cR3cGlbFy0WCWa0eDbfhs0huJbwRsW013 + BpWxctFglmtHg234bNLL37y8bGsQ3RlUxspFg1muHQ224bNJL6x94fPNK+jOoDJWLhrMcu1osDBNmtXT + JugxrceiL/zozqAyVi4azHLtZfC9ukc5lwsuXCkkuJjHyFVKLlxhpPDMhTxK2CqQXZNIIf9IEigXDWa5 + 9jIYv6pkq7ASNNicgJM0ZGgwyEWDFTIhUdkRlstkMIgGC6/RYLYKK9GPweXVdUvXr1gWFmhCgERUsHSD + vyKiiq7JWAEi6UgmwlJZCLspgbC6NCRga1w0bQVsq34MJh+TvBO9fdN8nRPz98z/eMNC2grYVl0ZPDdt + 7uL/LnZO+J71/WTLItoK2FZdGTx99/QPznzgnJidMXu+yq9c1JfB45PGux9xd05M2jvpgw1/p62AbdWV + waMiRo39aaxzYnTy6JlrvGkrYFt1ZbBLuItrvKtzYljEsOlB/K9c1JfBvT7r1Xt1b+fEsyuedfvck7YC + tlU/BpdV1ri4DXOZJmCo6acqEeA5VBHshExWcjLIVWX8Ki+DQRUZgBj0GOazWNd/Bxsb2u7VNhsbHwv/ + z46GRxJpAaSNcnIZEDQjxoZWsg/lmrI2QdmODHJGmAwewdcJZG010hH8blUPG6vlTdiq2DjYVl0ZjF9V + KggBGmxOwEkaMjQY5KLBCpmQqOwIy2UyGESDhddoMFuFlejHYGmatJJguTBjUScEplGM+uqSVcsMD5vp + hnyVoFw0mOXay2DyObir06TDvhODJv52X+wIXyUoFw1muXY0uIvTpEVXFrltcUODRWLWdO4Wcq4dDe7i + NMnntM+4kHFosEjMms7dQs61o8FdnSalub8a/CoaLBKzpnO3kHPtaHBXp0k/jnX1c0WDRWLWdO4Wcq4d + DXYJdxkeP7zTcI137buwLxosErOmc7eQc+1ocFenSat6PzXzKTRYJGZN524h59rL4LLKmiFThg6ZJsDF + 9BMSM3i6UKKUeQ4d8vbQCqN4Vb5KUC4azHLtZbCRTpOEOU+bMKURSYuCEJDLKIJgVTybgK8SlIsGs1w7 + GoxfVSoIARpsTsBJGjI0GOSiwQqZkKjsCMtlMhhEg4XXaDBbhZXox+Dy6jq/DQHLNwYR+IetFMlGJSHw + C5FkKqsWymTwMsgZYTIIvk5zmbTKyZaFBlICgzwh8NuwQhFUl4UoZbAVrADVyzJoy5Tnhq1cGbKWemeR + weRzsDM/m9TtsODgAg8/6T8DtdDguUec99mkboeFlxZOWzudemepwc78bFK3g/cJ70krp1DvLDV4QtIE + 5YAI4aiYcmjKW8vept5ZarAzP5vU7TDm+zGjF4+h3llqcBenSQh7wjXWdYTvSOqdpQb3+qxXn9V9EN0C + vYN6D509jHpnkcFllcbBk10Ge1oAjyHKiCp0IPN0GeSw5Xm4vO75BvXOIoONlk+TjFrTJIloD50IRCUv + g5wRJoNH8HUCGYGo5GVVD0zPJpkHeUJwt7pWEVSVVRrruKBKnaqX5eu0vCfUO0sNxq8qFYQAv4s2J+Ak + DRkaDHLRYIVMSFR2hOUyGQyiwcJrNJitwkp0NU1atiHQf2OwCUHtk+BlIQFcUE0WqiGTuZoM8k7L5KCa + jN1UDqqRYD8LL6slk3nXL+u3ITAt6wS1zDqDyedgnCY5PohHWxNiqGVWG4zTJMcH8ejfSbHUMqsNxmmS + 48Nrj9fXO8Rfmmq1wThNcnxMSJ7wZUIktcxqg3Ga5PgYFTlqc3wEtcxqg4VpUsJwhCPDZZPLprhvqGVW + G4zTJMcH8Whj9FZqmXUGl1YaB00eMsjDAkwdrIyoQweyIQMtu6yFMhuUN2nItoR4apl1BhvhNKneFtMk + LRmBqORlkDPCZGZTGq5Og+o0iZPZfprEyVTrVL0sX6d2Tzr5TRbJxK8qFYQAv4s2J+AkDRkaDHLRYIVM + SFR2hOUyGQyiwcJrNJitwkr0Y3BFdd3ykJUrwlcJ2BgkkWAlCV+1PDRQGZRXCRF552WQS4TK/MNXLV27 + olz6LRFosBixxGDyOdh7h8NPkw77un3hVnKnitaMBosRCw3uFtMkzwhPNJgSqw3uFtOkCZsnoMGUWG2w + ME066u7QOOL+2vrX0GBKrDa4G0yTfhz7UuBLaDAlVhvsssnhp0nxw/st6YcGU2K1wd1imvT0+0+jwZRY + Z3BppXHgpEEDPQabwBOAqf9vGeQSobKpgweOG0T+WaQ1o8FixBKDjaZpUnVDG0FN/SORNLRQYpQIQaWx + nhK2CmTCYIRyg5ZMUFLOywRer0xhMpJImkJrRoPFiIUG41eVCkKABpsTcJKGDA0GuWiwQiYkKjvCcpkM + BtFg4TUazFZhJfoxuKK6fnmIOEQKkEY9gJhmOyYsDxWHTp2WmbhIeBnkjDAZhLaMHcHL/MPEmy5bvzK3 + oJh2AHRQbqt+DCafPYRp0mFhYuM8mBk5c29qOu0A6KDcVl0Z7ITPJnnv9nYig53w2SSPFA8nMrgbTJNs + jbei33Iig53w2aSRW0Y6kcHdYJpkawxeN9iJDHbCZ5Oe+eSZvalHaQdAB+W26sfg0krjgIkDB0wdZIIG + GdTfvesymavJIFeVKVfVZHJQhUiy/n8ZmJZ5knYAdFBuq34MNqpOk6Spjvo0ic18ZJk8TepIJk6TeJmJ + KwtgMpjLy8DQSa6Zl9FnkyhYv0AH5bbqymD8qlJBCNBgcwJO0pChwSAXDVbIhERlR1guk8EgGiy8RoPZ + KqxEPwZXVNf7hwYHbFpNEBi+ipIAnmxa7R8WpAzKRNQQdCCTlCoyUAAjQCbn8nXKMhBUkwW3u0n46uDQ + L2hPCPRjMPkc7ITTJB4LDi6YtGQy7QmBrgzG33RH8OnlT91Wu9OeEOjKYK/dXophixPCJ9tnfMAE2hMC + XRnshNMkHm6pbmP+OZb2hEBXBuNvuiMYs2vMyIV/oj0h0JXBTjhN4uEa5/rHD11pTwh0ZXCvJb36rOnj + 7Aju029Gf9oTAv0YXFpp7P/OgP7uHaMfF1GFI8u04DbglXdG0J4Q6MdgoxXTpDpK2CqQPeFpEpDJNWtP + k/jVmgbxGz0CXRmMX1UqCAEabE7ASRoyNBjkosEKmZCo7AjLZTIYRIOF12gwW4WVoMHmBJykIUODQS4a + rJAJicqOsFwmg0HnNXipf2D09h3R8UkEUXE7ImMTKI+Rgmw1enuiSOKTtkVvl4KdlslKFRnkEgGyRCHd + xPk6ZZkQlIrhZBEx8VHSJvyqTMiGUbHKoKosOk4ZBK1gQbWeyEp2HbPLUgJ5BzJx1c8/4H9ign3GgCGQ + ywAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAIAAADWjhTKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAAEVJJREFUeF7tnXlQ + HNedx8frRFtKpTZblcqmXNkcf+SPOMmaJLVJObVJbSprV1K5fJQ2UWwLeW1LtqTIcjaKLkuR7djhCAwW + IEDi1MUpTlk3IGQhgaUoNiALMCAkDSBguMUpIe1+u99BT/dr0pDhGPT7VFf719Pfbl73Z17zGD2wa+nS + pVG+uN1uXgnCw8N5NSmhoaG8sickJIRXAuuXs2YiIyN5JQgLC+OVwF8Za3twlOnAaWciIiL4hsB0FHBy + +dZbrcwEBwe7kpKS/s+X8fFxXgmGhoZ4Jbh79+6dO3f4hqC/v59XOv7KgNu3b/NKcPPmTV4J/JWxXv6t + W7dMByozgG/oWDM4iSkDrE1ycvkOMxkZGa6UlBTsMzI2NsYrAQTzygDayisBbhavBNbMwMAArwROMtYm + DQ4O8kowc5nR0VHTi8oM4Bs61gxeMWWANebk8p1koOPAgQOu5ORk2G5ubuYd++9+RJeXl7N3EPVgXglw + EmjgGwJrk/zcg9kjurS0VH5t3HRWSKwOlLBLiomJYZskmFcCnMSUAdYmkWANEswrgTKjEBz2XsLiPcvY + 8om0p89cL28d7He33phwfmf8/NAorznjDYMj2n9IsIF5KvgP7yW7ysr4UnKs+EpxdmvbzdHhmpFbzSOj + w3fG28fG+sbv9IyNem+Pe0dHUZ/v6djX3o1jSTDf0JkvgjGKRlNKSkowwMPtNgtuKq7t9b7S0LS3ve31 + K42vNV8/2dvzZkvHy41Nm5qubG9sKurqv3v39omObhyL82AdHR2NgoGvyisBhn+8EjjJ4L7wSgAxvBLM + XAZvfcA3dKaXwSu4yXxDYDoKWC9/2pn09HRtFA0rtj24qfhD/CQx3L+qtrFhZGhXa1vL6PDr19siW71n + e3v+MtD39rU2vHsgGMfipFijB+OEAF0TsFqCtxWvdBDAUXxDYMoAvAl4JYAYXglmLgMxpheVGcA3dKzX + haNwk/mGwHoq6+WbzgycZCDY0SP6g96u16+3jN0effN6y0dDgwPjt8/cHCntbCvqvVnY1lI6MIxvy02D + WNMjOhC+B2+vTHC9k8iXop0lV0rwotWBEhLMN3TmqeCekZ6G7obGnka2DN/WuiYJNh0YkILZIIvdcVZI + cLDpRWxaY2g91iSYMV8Es8+im5ub3fZERkbyalIiIiKwrqysxAkBu2ZWS3BDeaWDAJ4cfENgygDrR7jW + z5CdZKxfy+Fn0aaT+ysDrK84uXyHGe2zaNaDjVjfevSvSaYDA6kHk2BeCUiwBgnmlUD3S4KnlQHW1pNg + XgmUGRJ8DwiOj4/v86Wnp4dXgs7OTl4JenX4hqC9vZ1XOv7KgO7ubl4JOjo6eCVgzb7cWhtVEcWW0NNh + rHBXRB2vOyEzRuzOYwRf3dQAf2WA9RUnl+8wk5ycvNB6cFF90bPHj8W1tMS1trJlZ0vLfxcXP1+4VWaM + 0CNaI7AEL4qN+eLZs1+qrGTLFysq7k9JIcETBLpg144druLiiX8yOXXKlZxMgicgwbwSwIrpQBKsQYJ5 + JcBJTBlgbZJDebwSKDOa4NTUVNY4yejoKK8EEDw2NsY3dLBpegXgZvFKx18ZYG3S4OAgrwQsk/9hvlLw + /+RtkRkjducxMjIyYnpRmQF8Q0dmfnzgl0/mr3qycM0T+oICm9/c/ROWt57KyeU7zOzfv5968Iz34M++ + /VRofX1sa6tcXq6qui90GTuntUkOeyevBMoMPaJnQ/Di8CWuvLyJ9mApKnKFPMPOaW2SQ3m8EigzJJgE + 65Bg04EkWIMEs2KOBTscRfNK4HD066+MtUlTHkXnz+woGq+YXpTXZSd4eHgYe62ncnL5DjM0iqZHtA4J + Nh1IgjVIMCtIMAn2waE8XgmUGRJ8Dwh2+Dc62EVK2PXwDQFuFq90pp0ZsPwBCgwReSWwzmdmmfzL6lH0 + c/lbsNd6adbzWDM4s6kBU8rYCcbgHHtNRwHTLQLTzizAedHUgyXI0COaBOssMMGe/ha3PhMPS0hZKCsi + K6KKm0qxlwRrBLTgow1Hlx09EufxTEzMa239ZUnJ8rxXsZcEawS64EUxO75QXv6Figq2fP7cuY+lpi5M + wQkJCaiM9Pb2Yt3V25X815TEi4lYYitid1/czercS3ks1tfXxwpJR0cHrwTTy7S3t/NKwJpkpLOzk1cC + lsl6P0spODhno8zkVuW6dkSZMykpT2VtkBkjPT09pheVGcA3dGRmcZhaMMtbT+Xk8q23UZnBj0iKHsze + C13DXY9mRuy82ryztUUuG99//6Fdv0G381fvVGagnFcC69tzyj24wKcHKwXPkx7s5PJNtxEoM5M9oiH4 + vvB1D54+/bULF+Tyqdzcr8Wv0f3OoGAnrf87H9HzWbBDebwSKDN/Q7Ar/GXX4cM+LcvKmkPBpc1lP8t6 + nk1de6xgNSt+lPncG6fCZYYES5AJMMF5tXnfy8qK8XhiWlrYssPj+XpOzkuHtskMCZYgE3iCXdHRrpKS + ifZATFISCQbKjCbYbkbHjf4bSsFfjVs9JmB5Cb4v8krHXxnAmpRdk60UvLLgVZlxMi/6UO0hpeBlBzfL + jBGHMzrs5kXbCZ7jGR3UgyW4Wab+EUg9mATzDAnWFhKsQ4I1/JUBrPUkWOIwQ4INmXtnFM2Gte397UrB + X41fw2JWrEM7JyNk56PonEs5SsErCw2jaPsZHTJzqM5mFJ2rjaKt7cFR7EDJlDJ2guf4twupB0tws0z9 + I5B6MAnmGRKsLSRYhwRr+CsDWOtJsMRhhgQbMgtVsN286PaBvz2KZnkJhm280pl2xm5e9CSjaJlxMi/6 + nbp3lIIxipYZIzgzO7lkShk7wXM8L5p6sIS9BfmGTiD1YBLMMyRYW0iwDgnW8FcGsNaTYInDDAk2ZBaq + 4ISEBAy3jGAH1te815SCH9y5CqNcBstLOjs7eaXjJAOcZPr6+rBOfz9dKfj5vE3Yy5qd/UG2UvDygxtl + Jq86Tyn46eyJjBF8ddYAyZQydvOiWd50FLC7fCMOM2lpaVoP1jvkBHgvYN01ZNuD0ecYLC/BJfFKR5lB + O3ilgwDe6XxDYMoAdA6s8y7b9OCibTJTVGfTgwu2Yi+7tCMfHbHrwTJjBD/wsJNLrBmt/9pkJunB2Gs6 + CthdvhEnGeigR7QhQ9+DtYUE65BgDX9lAGs9CZY4zJBgQ2ahCrabF207o2Pu5kXn1Nh8Fu2vedH6jA6W + Ac8Wrl55dMPKYxtfOLphhV5gvSR7BRosMxK8YnpRbtoJnuq86MyagysOr0czsDx3+Hes+HX+2mP1x2XG + CM5DMzoMGUsP/lx0sLuhQf6SOJZXqqoWhwcjIDMSdk/5ho7M+KsHby+LXfnuu8b2RHs8X0pL23Vht8wY + 4T2YBPOMRfDHQpfcX1Bw/+nTcrmvoGBR2DJN71wI3nYq5r6kpPvLyiaaVFrqio0lwdMX7MrPn8hgmWvB + uFitqfI8uBUkmAST4AUteBZmdOyvznyrPOKts5FYtpf+iRdlId4Br8wYGZgfMzrsBOMLyYwEL7IGSGTG + TvBUZ3S8WrJDKTiuMl5mjOA8szSj4/GszW9UVxuHf+FXrnxm5x+bupqcnAeguVhTD55OD54FwY/uX784 + I+Ofy8vl8smTJ10RW0gw9irF8ErAMvNasAs/cRvPc+wYCWaNUYrhlYBlSLCWIcESEnxvCLYbRXcMdCgF + T2MU/ci+/1UKrm+vlxkj1lE0a5L9KHqrzBRcLlAKdjaK9vmb0naCMV6VGQleNI1jZcZOMBtFW09l90OE + 3Sg6fs5H0dSD6RHtAwnmlYBlSLCWIcESEkyCSfACELxr164hXzCKw9rT5VEKfjBu9aCA5SVer5dXOjLz + wz2/VQq+5LmEAAZ7LC8xnQewJmV8kKEU/ELeZpnJqc5RCl6eu0lmCi5hpK0Q/HTORuyV7bETjJPIzMmm + 4sMfHcZSVFuEhdXHGo5jl8zYzYuGAOxlTTJid/mbTriVgmPKY2XGCM6zZ88erQejDxnBOxFr76DXrgez + tzBgeUlfXx+vdGTmkX2/Uwpu6GxAAG89lpf09vbySoCfJbDO/TBXKfjFom3Yy5pdWFeo7sEFr8qM3bzo + 4LyJDLATjIDMPJz6oru+xn21Xi5/qv3g0+7lxoxdD2YBdmlGTLcRsMzW0mil4IT3dsmMEZwnPT1dE8y7 + tAA3HWt6RDt5RP9j2JL/KCt7tKpKLl8+ceIfQp8xZuh7cGALNmcKC0kwCSbBvrDWk+DpCJ7yvOj4Nfh+ + jgBbG8G4kVcClrH7LLquvU5mjFjPw5pkOy96Zv7SnZ3gkZERmVlkI9iYsROMDPayJhmxu/wtxbYzOmTG + CM4zS/OiqQfTI9oHEswrAcuQYC1DgiUkmAST4AUgeBbmRTuZ0ZFfW/Tnc262/PFUCCvCyiO9A17sxRAR + 63k4L9pOMBtFs4ydYDajgzX73avl1ssPLY+ouXFJZubvvGgnPfipvNfe8p07Hdnc/K8JobUdtdiL5mK9 + gHvwa2Wxm8+fN15+rMfzrfT05IspMhPYj+ifZ27+p8zMB86dk8un0frIbfeI4E0lOz6RlvbA2bPy8v/l + zBlXTMyCEuzat88nc/z4PSUYjTTLI8EkmATf84JTU1Mx3mOjWQbGY1g7/H8Xrjj0218cfPEXBaux/Dx/ + lVbkr/rG7seud1+Xmf/aa/NZ9I06mflp+kal4OqWatmkWf5/F9oJxuhXZuw+ix4eHpYZO8HGv9Gx4YRb + KXj3e7tlZkvx20rBcRVxMmPEP59F/+eeda9cuBDl8chlS13dx92br/VckxnqwQH8iP5+2joXftgyZjR5 + m0iwzJBgEkyC9daTYBJMgifgguPi4rp98Xq9WDe2NioFfyX2pS4BYt9NWq0UXHWlSmZ+kLpOKfhi40WZ + +dHe9UrBlR9VyibtPb9XKfjZnA0yk/6XdKXgZ7J+LzPZf81WCl6auV5mgJ3gzs5OmVlkzeiCjRm7edEd + HR3Yy2KvvBOqFBx9Olpm1h8JVwp2l0XJjJG2trbExETqwSJDj2htIcEkmASTYBJMgrGQYL8ITklJueU7 + N2NsKjM6vpe6Vim4qbNJZiaf0cG+3M/SNykF17TWYO+on2Z0sIxfZnSwS7MTLOdFI2Mn2DijY8PJKKXg + xPOJMjM3MzqoB8/3HkyCeYYEawsJJsEkmAST4FkUbPfbhQ5ndNiOojuaZOYRRzM6bEbRLTWySTSjQyk4 + rmImf7uQevB878EkmGdIsLaQYBJMgkkwCZ5FwbMwinY2L5pG0QrBcz8vmnrwfO/BJJhnSLC2kGASTIJJ + MAmeRcHx8fE9vnR1dWF9tf3qNxKXBGWtDjr48r9l/wZrbTmw8omMlXzebXc3Ysvz1gXtW8H2fj17jVZg + nfirek+9zLxQsF6RSVp6+fpl7GWZ1Yc2qzK/rr5ajb2sSYdqDgUlLw/KWYu9E03a89z2kyEyc+TDI0HJ + wZbM81uPvykzxy+fUGY2HXtDZsC/Jz0WlPESdj2Us/ahg1o4KGPVt5OeREBmvpP0OM8cXIsYy3wr8XFj + 5uHkJ4LSfTOZ2i9gsgBb//l0DC5E2yUvH8mU5RkXM2XGfSYuKE2R2X/hgMwYuXHjBnqvbQ82MjQ0xCuB + 7HlG8JbhlY6/MsD69sTPALwS+CtjvXz8yGE6UJkBfEPHmsFJTBlgbZKTy3eYmewRbYQEmw4kwRokmFcC + nMSUAdYmOZTHK4EyQ4JJsA4JNh0YSILtPos2AsG8EsjPkI3gZvFK4K+MtUmDg4O8EsxcxvjhM8PaZgSc + ZHAqviEwHQWcXL7DzGSfRRuhHmw6MJB6MAnmlWChCV66dGmUL263m1eC8PBwXk1KaGgor+wJCQnhlcD6 + 5ayZyMhIXgnCwsJ4JfBXxtoeHGU6cNqZiIgIviEwHQWcXL71ViszwcHB/w8QL/QBQawCzAAAAABJRU5E + rkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAIAAADWjhTKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAADzdJREFUeF7tXUtv + JFcVnnE/3O+u6ur3Y2z3+D3j9mBnkskkivKaSSIeIaAIsQGJP4BggUiygT0bgoKCWLAFiUV2LKIgiAQh + S34FSxYoSpZ8vve45vpU+1bfvlVut30/fbLOqT713XvPV4+udFK5cXBwUFPQbDbr9TolAt1ulyKBdrtN + kYDnediFEoFOp0ORAKuP6rMCS31AP2FT/VarZdSQWH1WYKkPaBqytbV1Y3t7+4aCQqFw8+ZNSgRQR5FA + pVKhSGBlZQW7UCJQrVYpEmD1UX1WYKkP6Cdsql8sFo0aEqvPCiz1AU1D+v2+M9gZ7Ax2BlMi4AymSODK + GtxYXf3z64/SoxwLiC7YGUyRvcFodLNUxHc+2BlyFDTwd9urSxvYhKL6+gVMNQDK4XDDxslwKteaTRkU + s1lUzqFPkcDSGzyZTHwF+JKNjlEigCKKBPAlniLfR/v0RI1aD0T1WQFLgyDALpQI9Ho9Noqec+hTJICH + kNkbAsTqswJLfUBTv7OzY3sGZzKZfD5PuYAsaBeL+LRTLG40A/wNecv3uqWSuoUVsLRXLt/yPHXLuNWE + shwLiB7R6oRRyQpY6i7RMeOd16BKLofmpkc5FhBdsKUBzuCYBWjGA6L6+gWY6gPOYIqcwYAzeAEGd/rD + b/3i41TZbHflcM7g1A1GuykSQH339j3VjDTYurUvh2Pzx0dXzeCF/5qk9l3lm7/8JCWygRjdr0kxR+gc + Z3B2tRSy3mi1N++rHU+DzfVDOVy+WCnX/HB0fHTVzuBLeA+uttdVM9JgORjI4WLn7wxO3mCKBEz1AUsD + nMExC3AGUyRw7QwedJqf/uyZ5eLKijNYgToeusPqd3pVbPzqD28vCzHbzMwGR9e7eINTfUzCgr/44PEX + HzwK+d9fv4qNX/728bIQs/3Pr15Sl8BWpKYoju0PK1juxyQsuFqpQC/kbre8dAZnV05aEhJ2qKm6QBTH + 9ocVXLV7cN8rogvLRfhLsxcwMuDaGRzV1y/AVB+wNIDpWxrgDI5ZgDNYrw84g+fXf+OPf0+DpC7gDL5Q + g9F9ZvCPP/l3slQNRpy6we6/TVL10XFGZo89mb77b5Mu+gzu7E38XSJSZo89oanqu0v0hRoMqPowIA2S + uoAzeJEGA5YGRPVZgTPYGazTB5zBVvqJG3x076l3fvC7BHl07z5JC6gTcAanbjAMYPqvPHgLG99/96NE + CKmXn3mTpAUwAWyU8YnB7jFJr2/zGHO8/wJ6PZXMp7nJZEM2/AYm4B6T0j2Dc9k8et30u9WSH/Kl4+9i + I/NpbkLqxaO3VP1ua4CNN26czNldotM1GIjqH2w+CwMS5MHmA5IWUCfgDF6AwazAUh/QNMQZ7Ay+fgZ/ + +JfvJU6SFmATcAab6aOb9gZTlARee3tvqsHhxtQNvnPnTkmB7/vlcpkSATwnUCQQBAFFApDDkwYlAnjq + oEiA1Uf1WYGN/teeW0Pj7ElyAqYNic6fiYeUBZb6gKZ+PB6fnME4gkLggMJBTYkAngIpEsCMKRLIZDLy + GAyBA4oiAVYf1WcFNvobuwEaR0fvvIACyQmgTUYNic5/6pTCUSz1AZzxFAmoBYPBwN2Dp1yiEydJC7AJ + pH6JdgYz/VqtijMqJC6fmQyqnmzxvLqasnqWZnOZUqlI0gJsAs7gizaY6VsaENVnBc5gZ7BOH7hcBrO3 + IaVEGkxA3yBn8Ml4mZs3WdfmBnSYvn4BpgfQ7XpNM1V8ZKq/9AbP8nNh4HloTVJk+pY/57H6w36fDcdo + qm/zcyEQ1WcFlvqApiEGPxeiNTKNPUL1Z1iokx7YEOoE8JHp/K/FJZoigdgFxBp8AaTBBPQNcgYnbHBU + X78AU33A0gBncMwCUjI4l8vX6h7Y6w9kQGmvr6Zgo9GQ+0rMqB/CGRyzgJQMBtirkDSU9RKz60tcNYN3 + d3ezCsrlci6Xo0TA932KBPCVjyKBfD6PXSgRwPdGigRYfVSfFYQp8wnAFvbOuiijBp8HlOXyq7HzR7+M + GhLbH1ZgqQ9oGj4ajW7s7e3hEAuBw4eiUwRBQJEAhqdIAAcg2wVXSIoEWH1UnxWEqbSKkdkZJavXs1gq + x84f/aLoFPqGxPaHFVjqA5r69fX1y3uJhgH4G+oPD15WvdFTCBBm1A9x1S7Ry3IPzuSmn9NTKfeVmFE/ + hDM4ZgEpGRxCrw9YGuAMjlmAM5giAWfwmQL2/qKkSOoCpvN3Bs9qcK2QRa+fGgeTUW0yrB4Mq/LvM1tt + BDJGwZcfvpEsoRnq4y+GC4cGD0d1TEnGcuOD7U6Ygth9uQ2eTCZ4MAjR6XTwtZsSgcFgQJFAr9ejSADF + 2IUSAVYQpq/fG6FZsWQvmrMnNP/58wchP3/voZp+9s6z/3r3zJbP33tOTbF782xD0DWKBM5br0Rsf9in + gJE+oKm3/R9jAUaXaDQrqs8K/vebR8kSmqQuYDp/7L7cZ7C7B+vn7+7BSRoMWOoDlgY4g2MW4AymSMAZ + HLOAOQxm7yzSEMXO4EttMExi9QA23lzJhKzUalPTuQ2WO4YwnT8rSN3gpX5HB3o9lfSxwHn6bBcjBv2h + FAFM588KLsu/dBci9gi98DO4+uTt64LYSB8LnKd/Uib+47BCoajuXq3W1LRYKp1MWOGM+hKLP4PdPViv + 7+7Bl85gSwOcwTELcAZTJHCNDGYv/0mcchTAGUxRUgZjiuhvLpuX9L0gjEGv3pCB9CCqr1/AjAeQOoGg + 0QxjMJzA1HQ1X6iUa+oWNn8oL7fBeEzCV/kQ+Nbu+z4lAr1ejyIBfCmnSADF9/YeoAuzEPVRfSYY1ccu + lAjgKYIiAVnPBkqWvt+QY0noGxI7f1aApxqKTmGkD2jqT87eRC7R6ALl2kt0YbXs1RrFQgVByMBva9JS + sYpd1C3NxpR6dQKWZxibP5SX+wx292D9/N09eFaDJaL6+gWY6gPOYIqcwYAzmI+3ub3B3hGUOGkkAWew + Xh+wMhjtZuMdPz/Gxj/94ycp8cIMlgNdfYP1vyahC1PJXEmQbKBUiQXiWUL/a5jlrz1RfVZgqQ+wCasF + 8b8moQvDtbYXFEM+fHRyif79x99PiRBXh2u0yp2+p24ZrLXUtH+rqabgaP3MhFlBmGIgLPC6X6IBNt7m + 3TZakyppJIH0LtESzuCY8UwNiOrrF+AM1usDzmAr/Wtn8J3NTfZKmyvP6/W/eH/+1ghr/uxHP7wmTMNg + aFJyAQab/kt3r443rpvBaZC6eQn/pbuH3Q7mx7pwhYnFrmYyuZWVkIHnqalXrWrS1Wy2UiqqW+rVKjSp + m5fwEr0XNOQxeH14ve7BsQvQjAdE9fULMNUHLA1g+pYGOINjFuAM1usDCzP45kqGvfwmDUYX7AymaA6D + ow3VNCi3Wkb95v2vDyevhNw4fn10+Kq6hRWwdHT4CLuoWzafflIw1WBspEhA36Crb7DRYxJ6Z0r2tT6q + r38M0P/aw8YKSR8L2OgDV/zXJAB1FImTY3z0uL//QsjB3RfX7r2ibhkfvyaD0eFj1LMjLqqvP0L1Z1h0 + PiA20scCNvrA9bpEA7ELCMfLikt02owu2NIAZ3DMAjTjAVF9/QJM9QFnMEXOYMAZnLrBvu/59VrIYb+r + poHvddstdctw0DuTnq0Hbw0HaoqCsvI/lzOdvzPY1mD2yqOUSIOZw7Qhsf1hBakbvPA3vqP77N10iXNu + g1ezKx//9P5Wp0pzFdA3JLY/rAB+XPE3vl+MwfMR7uLv0caZFekbEtsfVgA/KDqFkT6gqb8Ub3xXG5oe + aTDz+WPf5b5EL9zgpl8beIWQW4OGmo4apXHnTMH2IFBTVg/ujJpqioJGOUeDmc/f0gBncMwCTPUBSwOc + wZVSZ1AZrEnWRhuN8XaYgu3t/TPp1p6aBuPt6nBd3eIPbpG0AFuAM1ivDyRvMHsZkT1JOiE4gymSBu/v + 72MGwdYe8hl7jTLsIlEqlTAhSgTYt2iW4ksjlkSJQLIGQ61/55CkBfTziZ0/HkLYhJvNJkUCi9UH2Ldo + teDkW/TOzk4mk6mt3ZbdmZHYRQLPcFgDJQKwkCIBLI8iARTj+YwSAaZsT9wjSFqATYClsfPHUyxFp4Al + FAmY6rMCS31A0/DhcHjmEo3uwPZZLtGUJAGmxi5BpvdgqEUnTJGAqf7SX6Iv2z2YLcDUYMAZTJF7TAKc + wc5gZ/AlM5i9XmkOHh8++UebzmBbg7vtIXp6e3ggeXfzfhiDW6PJ3saRuuVg62k1ZfUg1N5/96O5id0f + HrwRqu2Pj1v+ABtpuktn8GQywffyEK24Vxl2z75JEE9d2IUSAVbA0qj+8d3n0b5kyTwzIpMKSdONa4hp + f9rttlHDWQpo6k/O3stwiUb7KLHWB6DGPDMidh/375DW6RmmznDJzmB3D46yVHgyhLsHXzqDLQ1g+s5g + Z7CZPitwBi/YYPaKp0RI0gLO4As1GN33G/X8ajYkttgYEJ0/BFX9uldZLTxJwWbLl0Emu4JivT4QY7D9 + G9/1jwGsPqrPCiz1Af2E9fpoaJT02Sls9AEmHku9PqCZz8nZ685gVR8NZfrYUq7mS5Un7PQDNW11fE1a + qRX8oKpugSBJC+gv0SjWzx+IOYOdwXp9tDhxkrSAuwcv2GD3LdoZbKbPCpzB0/XZm45SJeYgh5ZwBscY + jJb1yqWQt1tNTTqoVNZ9X92y2WrhL0Q+ffs7F0AM1FdGl0Orb87SG7B4gyeTSUMBvmQHQUCJAIooEsCX + cooEUNxutykRYAUshT4alAj/9u1vXgDZoJIjZcn69cb2Bw2h6BT6hrMU0NTv7Ows5gymREB/hJ6nD5G/ + vvmNCyAGYm+6s5w/K3D34HMNvjDaGOAMjlmAqT5gaQDTtzTAGRyzAGewXh+47Aaz1yLpmStC3hl8Bos3 + GMZQco7BmVwhZN0P1DRXKJWrdRmjsuR15zBYnYDp/JfeYNM3vrNX6XlxrwJEPfqrJ5UKaPTZXkaUCoDp + /FvX6lWGQOwROvUMXsnkJHE+ZrL5MAXxKZUKaPRRWQmGNc9Xd6/WPTUFPT9Q02rNU4cwnb+7RMcbTJFA + VB/dn52rFV+vD1ga4AyOWYCpwfoFmOoDzmCKnMGAM9gZ7Ax2BiuI1WcFqRv88OHDDQXwm6JT7O/vUySw + u7tLkcB4PGa77O3tUSTA6qP6rMBSH9BP2FR/Z2eHolNY6rMCS31AU390dPR/J2g2z7KdRYgAAAAASUVO + RK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAIAAADWjhTKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAARltJREFUeF7tvQmw + Zsd13zfvffu+72/f5r03OzBYiJ0gMAQ5AEFSNAlItpKQtrXEVSIlcQVFEgAlm3Jily2RAkFWuMiJFYm7 + 6JJJmqRAy05VrLIWKy4nVXHFVS5XXK6UncQ2NynMr/vft7/++t43mAFmsBTxrzt3zvnfvqdP9+ntLt99 + x17CS3gJL3JUKpXDw8Pd3d09i52dHS97ASBz6Pjx45JDcn9/P01K9aTgyYj3CHkvPy0JUOVGBCWLEguU + JZMHIZ8ppwUBVVUUQXyUWEjzqGJCPlM+isRmr9dzAS4UCs1ms2FRr9fb7Xan05EaAp5znGJB4m632+/3 + nW4B2Wq1SMweVKvVWgBU8krzAOPsQx4Zg6SPSNzLtDwej8nd6QlgsBwlFvA8zVuvF4wj4wakZE+qjJEF + VNxwSgLIcqU8GA4qlXK1FudI+rQRSk0xQ15y2g3VZ0TCcLoLcIRcLpfP550SAL5cLjslAY0jTS4tLWEB + cIqjAiwvL2faT9sBmCK9UxIUi8VMCxTVSYvItAwYupwUINNt3EiTlP0y3cjnCrVyczparZYzPMx0m+wo + plMCpHPMrE9OP6o2rlqAS6Vyph1IznJKAKqbE52SINOZUqmUWXi6VLo1YDMzkPC0dKcEyGw9mE37fJQb + 9J6oIIP27N0//lFtxXzJsQlI76QAZId9pyTALDlGxvE27QbktQ0wiRkdOSRrHjJCjUc8YCzFmuclUEgZ + CXkCk7ZADJgvsOB0C9LAMMBGiY/iAZYjt5GpQUjJnpQbIQnSbnC00+zffu5+oru1clguxZ6TXr1Q4Cgg + O+yHKZExS47sPa+UkRsiae4uHmI9VKdOScA58MTA6QkwnSbxwCRuNJQxqgcqJK5HPKC6OcvzEuS9VyVo + moks4CFzLZFwugVpsElbjhKjkjLNAx82pydGjnIjJIF3IySPLR9bnx4nwKptxyYgPWc5xVoDZIf9MDEy + ZskxNK6UkRsi5wFG8aBCCRh1rZr1EM85IY9MyjRJfiRWri6PAHLUKQE4Nxp8ACUnvVMSUN2ZFjKHaBg8 + cUoAeGrQKQGwnHZbAXBKgityY328rwCncdQQTU06JcHlD9GcPh+iOSEEx3DdKQGwQk05JQEp0yTVQWKC + no4NyKwscFQYSO+UBJQ800J68gMwNB2nLCIzRyyn3caNNEkZj3LDSQHWRq4HpzHvagHIjrp1SoB0jpn1 + yemZbhhwwlGBSbcpTGc2NCxcaYAzw5AZYEp+VM2+YAO8Oty7oh5Mds8ywEcusjiW6Td8uqYoZJqkOrDA + zHCUHc5ySgCNBE5JkNnaaFKZFq5oiCavazdEhwVZXlouFct7a2cIMCusQiE+JbMHk92zHKJdu9FNA/IQ + kFnUgZAEqKQcDAZRYhYIaZKUWBhNphyFQfVAhez3+xEPhsMh+5BHxk5kBJkcQWQBdTqdkt7pFrKA5XRi + +PF4HPEA39I5yg3JnsQHEockQMYNp3Q6zWbj5O71hDbc6FvhKaQPVYBKdlEZJUc5KmWa5Fx4E2CaQwT1 + YKcEUA92SgLaTppUe4fPtAOpZhiBfkZvc0qCTGdo2vQepwSgYGTtlAQwGhsikBc92CkB8C2dY6Yb6sFO + CYAbviDU8MbYzL6P/cSvP/6Tf4c9clTtpHdSALKjmE5JgFlyjGopsz5h6GkmwGlkjooAPj1oyA+nJCAD + 1chRdjjklADpoR5QGNI7JcGLaw5eG5nZ931v/uT73/Ip9gpwiMxIkN21moMz6xTAp2OJoTQJsMAh4PQA + VxRg2XFKghdjgInuB/7ip9k/DwFG4nJW4PqV/Bg0dDXsIZ5hPeSRGfHTpOYYyYSf+vVAVeKIB5xCjXte + AqNoZARZDkcWUJl4sOB0C0gYLKcTw+N8xIO020oMKdmTciMkATJuOKVSYRTfWT0VBZgZJjyF9JEF9ljG + fsTjBjx7zyOoPiV7EoZ1gwswugetUnWK4CgLWhM8MQ55ZAylSfLAAn4AmhLtywMVElMRDygPuXhegjwW + I8BjPG0Blaamzu0BCYPldGJ4PI94gOW025QLEsHzCHIjJAFy6EYun9uanYgCTJrwFNKHqmQsYz/iqVt4 + 9p5HoH4iNxDwlmbtAhwhc1QE8JTTKQkwlyY1BwuOCgDJWU4JgE/pAZZMgVMSUH0U0ikBKNLlD9Hw5OiU + AKogpyS4oiE6cmPdLrLCALsDCTIjgWWK6ZQA6RypnzSJtzRrp0TghMzAwF+VAGc6BDLDkLkgUP9wSgB6 + 5OUHGFyjAOOGkyyerzk406wBxzL9hk/XFIVMk1QHFkC6UsBR9rGTDk9mazuqB19RgOFfID04MxJYvmo9 + mPLTC6EE7EpVUT3gNdaHPOcypeZzCykpORZkVlXjgapDEQ+YzrHseQnemZDHDWKD4EmAzGQW+gYgYbAc + pgTiqYKIB5HbEjLdwAcShyRAZnVDDYhkvzk9iAIMqaMCboeqZCxTzIjHZ/iolvAtcgMBZt5uNjY2VldX + cReLqjv2HKb8ngTIAG8W+Hrtid95kzbHWJAAC7Rlpwfg9Ewey1q2hCA2pHdKAt2scUoCchyPx6R3egKY + fr/vlADklclnGs/0mZTAKQFGo5F3o1It762fjgKsQx7pV3YAtZc2js+4EdVSZkqSzVfRNAFSOCWBGoJT + Aqh1O4WxK7e0vtchutP1ZjQ6Zo6uIHNIATQ6JwUgL9I7JQEOZ1qgqJc/RAOq1UkBsJx2W53DKQmOGqJx + w0kWz/91MOWfRzsB56RrFpA44rvDKgEuVzLyyCw/fOYMSnWnw0Ne6ZqlkWVaoNmmGyVMZiDJi5bulACZ + YcusRAJwlBuLc7DuZH3i/W/5JPt0gEnvpABkRzGdkgCz5BjVUmZ9cvq83RwcHDBKq1MDejN7hi8g2QOV + 8Yex1PPtdmdrd0KAJ7NBmBiZ07mET1vI5AGW2XtegvViwQ3koUVkAXU2m+Gb0y2UBsvpxKRkbIx4gG/p + HEkML9mT+BCRABk3nEL9dNrrs22C+vp73vwj976FPTKTQHgK6SML7LEcldHzXpaAt5m+wbsAM6ZTANpF + CBoFTcMpAegNEd8bmWm4Uovvd9OI1NwiQNL2nRKA/kRHcUqCTCOMIrRupwSgbGkLMFh2SgB4Cu6UAOqX + TkmgXuKUBPiQ6Qb1G7qxu3GSoH7ksc//2uNfYI/sDiQgvZMC4AbFdEoCRiN49k63wLG0G5DzHsxh8nBK + AoqUHu4AiSO+M6gQ4FIlHkgpJEacEgA+PdyBzJmSvEjvlAQUMtPCC3MO3ts0tyo/8aGvfPKXv8oe2R1I + cM3n4JcCHALLabefXYBND/7vPvT3P/HLX2H/PASYNb2GaIoBJKgSPSmgUikhj9C3Q3S1bkYwkQCZ8oOQ + BOIxHvGAgRS3PC+BvCI3kAmYBiVHWaDSTLHgdAtIyq8h2lEW4jVEOyoBvkVuI6u6JXsSH1QQTwJkDdFS + qd79bXOZFAbYn0JrpD22WyYSSg90FMsUU8kEZMzCs/c8gupTckjO2w2zMXMyZYAFVCh7AkkBJAu2qs3N + gZBnpTyatQhws20CLxIgY0GtwVEWqPid5gGWcdTzEkgMwsTIuhCMLOA/zRQLTrcgDQyWo8TiqYKIB1iO + 3EOmyJCSPend8CSI3FjKLR3uno0CTBqdVWm0ap3eaG293GhhQnZ0iOywL0ZAxiw5sve8UkJKDsn54hyJ + GBN5moaHXHRKAHINeU4aTBoEuNZwr6d7YIF6cUqAo3gsU3KnJCAv0jslAd4TdackwH8WWZTN6QlgsOyU + AOTF0OWUAFhOu4cbaTLTDeaEVrO9vGRqBiwtLx3smLexwgD7mh6ePP+q33hKGx451kJNyikJ8Jkco1qi + ftJuwMwDjK2X5mAPLKfdxo00qb7iFAsypyq0+Qq5xBzcOX7q+I/+JNHt7J9xVAKyo5hOCZAueGZ9cvpV + W2S1+ybAxfJzF2DmEmZFpwR43gOcyy9tHXSpjetuWxnM3F0UBZjofvKvf5V9GGDQ2jkgwE4JQHZXJ8C4 + jpReZOE9iTwpoFIp4nWoUFwer5ohutkpF0qMS45nT64YkeohHtcjHjCR4KvnJZAX6UOSdjdttTba5jUD + kQKHwtWNAAmDZW9BEM/QHfEA3yK3kXEDUrInaesqiCdz+eXBpE5tbB30G23TEzikRdavPW6ug9mQSW1O + YeQvlSbnbiLAxVKR3mBIY8xYIzvapWQBGZ/JMaol1adkT8K4RRYB29zcnEwmUFgE+M2ewlMvkj1QGdnF + g2Zr/qRBW7PtTmGPBSY5qR5H8QDLOON5CeRF+pAcNBqfue9ebTWxFvjPUhELTrcgPQyWvQVBPHN2xAOa + e+SeEuOGZE/6lCHJjnpoteusNGDo5Me3TQ8ONw7QinqrG+fvvfiKv/wzBPiGV16cHT80JyTWsEyEvGWA + jBtkyt7zCDgGKdmTMG5UJuDYoqjIRB5IUA/2JDCpbYMQDzoDcxf6pns27rp/nz3yaGaGBSVWD5bqcRQP + sIwznpfge7BU9uBUr0t0UUy6BPDqwU63gFQPRnCUBSp5pXlAQyHHkJcRfJbsSeqRxBFJ/6EeKjVngb2g + p8KSxa/dfZHQhhs9VAkA2WEfwRo2QMZncoxqST1Ysic53fVgQMwV4BCcRqmcEoDEnm91TWtFoImwRx7O + jCAoNk4JoOHOKQEIsJwLQV6+PXkcdjoE2CkB6KkqfAgYLDslAHkpwBHwLe02bqRJqjWzINRDObXkTP/4 + bHbHfQT14mf+sdk++z+ZAC/PK5zsFOAQ+EyOUS1l1ienzwOMoWe2yGp2SgowowR75MHUCEJmbEBmZQGa + jpMCkJdvTx4H7XZmgJ/3RRYge+qhVI19Tv/4bHr7Kwnqq3/rH5ntM/8Y+djSvMLJjgbklADpHDPrk9MZ + pZ3CCit9o0NDuWQBGXCaeNAfNylMbjlnx8YC8spGN58zdjhK9QEEnS6gYpmuE/HAW5YqgcQgTJzLF84M + BwTYjA+OM8D/5/FGB6jWzHgWbbllUxssvrZXzUyMoNOJ/+pdr456MIOys/Wsb3TAzK+DkXSjgzoC6nkU + iaSSBWRAruJBd2hWjLRaOxrkkKdr7aVjxg5HsQAQdLqAin/ELOKByuN5CSQGyJ6nN53q9wiw7haIBPiv + Gx1OtyABDDNImBKgUoo0D/AtcluJISV7kppVQYRW16xITpyfnnvZ9tbhkEOqHM6gktfsU2EEUnI6QjrA + tAWZAmSHfQRlB5Api5q755USUrInYeYBxtAP4RwMTzN3SgB8S7uNG2mSlhcWhAtFaqDdY0HTyRdMFaty + wKy/RXT95siX5mBAXr49ebww5+BG29RGpV5oNszkFwa4Ve/vrJ6+7uD2zclhPudO0RwcBvhazcEvBTjE + swxwteG+nRAGWKjVF7J77gJMeDLvZHGaJwEyoFI4WXKnb2YdLGBr6Zi5/huvGEGJsQAQdLogHtcjHjBg + 4qvnJeBDZISIneja6+BFE2i6Dna6BSQMlhfTOp6CRzzQwBvyyBQZUrInaesqiNDqmog22uVWq00qH+Ak + uVmpsLeqCeTszniIphGZdGqjy4Xlggmw0gN4fCbHqJZUn5JDcj5EaxXNadQmoDDs8Y8CSBaQAdMt5iT3 + R+YmJT6YyW/JLLJm6x0W1UqMBYCg0wXxaiWOSuAtS5WAD5GR5Vz+9KBPgM344DgD/KcgFMzpFiSBof0t + pj2SB/gW5YiMY5CSPUm7UUGE7sAsOdu9WqfTJRXpVTk+Pe2PvVQivPryeJHFKpkE5WLh5Errpt3hLfvj + Sces5wUO4TM5svd2EFSfkkNyYRU9GAyIPHXkQc1iyCkBaPWe79lVNAb7/V6xUESerBFpZ4dKwYjkEKos + pwQgwHjmlATkRXqnWGA+XEV74L9W0U5PAKPVcgR4AuyUAPiWdhs30qSaglNyuU7f3Lhtdip2IDFVrAC7 + wySwA4xAJ53dYYbo+/7u75rN3snKF0zF1svFb73jJm03bnbCGlHkolrKrE+8vQqLLK2i6cdbuyuDURv5 + pTn4EnOweI/JTXcQ1AtPfNZsH/0cMr7qULuSJ7oXT/WX49I8ozkYV57ZZRKXBJRhNO3s7K+Np+Yx2Q/z + rUpdJtWabvJLB3jepSx2b7uboP7E//A7Zvu7fx+ZKVSHmEUJ8O27ca/T5BrVUmZ94u3CHDwajZQOcIw9 + /tFZJXug0i7EA93JYky2NZtHnl3GnSxIajbigbcsVQJugDDxC/ZOVm9oViQM1N1uj1S4bQNshnelxz32 + Uonk6fseJKjvfOp/Mdu3/jkyU5q1VKjYUfruw+ExW5kCPD6TI3tkT6o+JYfkfA7OXGSRglJJFpCBwiBZ + iyyWV2Z2cQFeWGRhBEGnC0fx4BKLLK+ChUVWYAT/+/2+Cu9BAhh8DlMC8QQ44gGVRY4hr8T4LNmTpASS + gV9k2aWADzBjuzuLepYA6IPpABft51tBuWQDfDBgBld6AE/wyJE9sifJyLvhyYUAk+KH8E7WNRqiy9V8 + vWYqIQnwHNEQfeLCA1GA/ePC3LIZou/Yu0pDNL3k8hdZrCapM8kv+hsdqXuBAN/SbuNGmoyaghZZ0eaO + WTCQOMni8N77owD7imVtZefgpAsGSFddZn3i7Tw7WuLlBJia65SKa+32JGn4L94AF1udcn/YW9vI1xcq + HTzjANdbpjbWdwdcU/RHrXQPft4CrDkYinRAAsNaOAcj4DLVqq2iRY2dg4kjY6Ofg1lkKT0lBN6CIB7j + EQ9wiKbmeQnpOZhWc3pgF1kWIgEyBVGle0BiE8s+JUKxXKE2tY3O3MgVdGgH30K3JaTdQGCEJ7FkoDm4 + 1WXy65CK9KjL5iaYOcUk6HYlAyJ56jLmYBYcSg/gKR05skf2pOpTsidh5p2W6GoVTV0AUrCnU+o0kRit + lcu3zmbU7C0rs7JNNpiYV94JsFlk2efBq1tmFU16jvryy4IgHkQ8IAyqRKkSsEBir4JoFS0S4L8WWSFI + Qmzo2f50CkKsOuvbVOj2xTe2pmu0CEgdBWQXFRzgWOQGAlUEJAMtOTv9Oqto7CnAS+YVUGOcBFpF27NL + NsCvjQLMUt1aKlQrZQL8isPhkq1MAZ6y4AZ7ZE/CeDdCch5glkhUDUMZAxGQoHSeBAx2Q9uJa0XDg+Re + 9JIdDey96NVndS+aIHleAj6Q3qsAN670XjTlX0xrRkIqtLt/GsFRCfAtchtZrV+yJ6loIBn4e9GMZ6RS + gL19Elg+KcWxYydfGS+yaLvW0lIhnyPAdx3vUatKD+ApC26wR/Yk3no3QvKZLLJG5TI1y0Wl1EvPwQZ2 + QqSowOoGmXMGKJQyljz4QHqnJLgqiywqtHNw1ikB8I2yOyUBbqRJKjEsyJXeyXrBLbIAQww1W014H+Bq + xSy7fICp015rsj7e25jujzqrNr6XCnBheWncLK4PW+MWQ+1ChDIDvGvfnHVKgMwAg1LZtHGnJDgqwFy4 + cvXp5ATPcYABAX7Z1vya0+OKA8xhovu0v03K53LdWu3s6io1ezCbMctDdgbm9nqnX1nZGOj3DePVFmbK + peqtZy/6FxgUYNkBWKa6ncKImstN2xXKo217UAsdwYfIjVa1eufONm5Me71yceHRQvphQ73SHHZWVsdb + OLBwaHmZCu2fvN6Xmv9KhfzusHp6tX1yxfyULqwOztXYGAKbYUHaPTNhJQ8b3BsdYa2KFxhHT84XWX+i + ADNdk75VK29MB1TFG162vTrqhVVH2MiRvdMtovoUYNyNDnI9ffr06uoqMzE9ABB59lQWhySDnh0Vw41D + k5U+ZXjwvzypDXllbdBomNfBS5XCHdc9QHSrNfcmuuxwFpaBt9xoNjfGvR+/c4ciPXzb9t6KscAxJcCH + p3VDhxAmkwml8irwjWxtvMNiE8Ydrdep0LUbb2vYr9QA8tyedn07u/f01Hzex6Znj1l8lmyTG4FFE5AM + ZmsDamC60h+Px6SiyKjVivnGp9JY3p1eq5RPv9IE+Kd+6+s//Zlv/uRvfg253enU6g3vg7aw6tiTI854 + Owg45t3wpHUt+ctnlzNEF5eXqM1/+IbXfesNr/uDh9+ILJ4yhJtI4abDC9SsUwLQvtJDSq2wTGGi8Rmo + BzglceOpN7zu9+zm3RAoW3qIxofZcBs7NGpHWVChmUM0bkzb8asUnH7Vh+j2bBUfwo25DR4HvvPEq7/z + 5MXvfuyiAqz0QrrqMutzPkQDSn6ZAf7max/43dc+8Pt/7vVhzbqv7FTjPK4owI2SWTdWzPXhAjID/M0H + 738KTx68/zIDvDraRbicABdypn7Xe/GEfTkB1ork8gMs9E6cM6ENgAP/6cP3fvsjF77zkQvPdYC/8eD9 + VG4U4FbP3IPNm1d9HbjgZl1978t+hMrlqr9cXHDxKgT4NReJLvsrCjADVRikqx5g3cmqt0uttnHjMgPc + 2T+VDvB//PA93/7wvd/58L3pAKfdePoAb2xsrKys6HrZQ5OZU+r1Xqtpatb24H9ix0bxs/UexdDWG5j0 + tVr15F78VwpYxzbq5jvMAMu0J8kek36bwgy7rQUngo9XC3KDduZ7cJhek5xTLCrVMrnvb5yt1c3tC+AO + VKtU68r5W5kLHWPRbZsp8OR6v7roB2ZDNwQmv7Agw4n5IFy0lctJjvX6aDRyUgI989cmplyp4cB/+tWF + HqyKa7a74/W92faJ7mBiCQccwxOnJMAxSBdgJL2yQ9gBLYI9drVuFFkrFqMAc4iDuLS22zl78/rOiUG5 + bJa72Dmz9zKq9Rf/6//+gz/9dxTgJd2ys8YZMKhoc3IC5G7d3LtpVkt0WE+y1xLRq1XrRhhgn558WVbQ + q6QKkOS+NTtczrnSCfDU6fD0Db7UQrVcwI2dUYOBw1E2a9ygQiR7ki5BQSSDYqlAza9smrt7G8e7s40m + 62pvhwTUM3uvsquOZ52DM6s33laZzETiTzrAXJhzqNEdv+YDX9PGGOntqD4le5KzCLwLMEp6iKbXk84p + jG/Lyz7A0RDNQM7CLc/oluDE1k1U6/vf8ukP/MVPK8DugAUeEAanJGiWzUsq1WCcF+S0U8wQbd04Yg6m + SFSQUxKQ+9p4zykBCHD38JxTEhTz5jndRm9hVAS4kR4GiXq6IEwRpuNW44EUMBo5yQNvl3N0QCMkMAFe + nIM16+Tyxdb0ONGtdiaWcMisT7ydZ3f5c3BmgEG9Vrffi3E43LzRBvhT+jRjFODMynoOFlkRCPDVnYM9 + CHCpErdUkDkHA7qHkyzSAXYHcCNXJMCF8sINkMz6xNt5ds8+wFz4hjV7wgaY7pvZg69dgOnBVxTg7kGq + B1/LAGf0YIuIv0SAc8WqCXBloUE8fYD7/X76nSyGdQIvGdTtXehwDvaHEGgfjFcIADund8wcHAZ4Oeee + PZAAjzGOIAYg95rmZlarXs4HZtnjA+mRpTo3ggD79OSrp0lShVw+R+7bsxPMWY6ywEszB5+5gfnKURaN + Sgk3dscNJjlHGcu5UhG3y5wlNwACaxkVJCSLJfP6cKO1UECAyhIhIgV4VT7HmJFMgBfnYBWJcyuNNgGu + tfrejiHtky7JnsSx+Rw8sdByxgPvOc0p5XKrVo0C7A5Y4KIaBKCGz+7dGgU4VzD3GQQs0+OdkmDYrlOY + brO24IR9OkZ6pyRuPPXg/f/wtQ98ywbYpS+Vc8uFdqtHLMJyFIoFct9dPVWyf+hE0D1YAjw6c54hAd0d + KJebddPO9mftYmCk1mi1eyPWro12n/bm2MVPOHjQDghwm0VjCrQ/Jy2CFa53ulAwLew7H7n3e09c+P4T + LsA+y3qrR4Cb3ZHTLagfPHFKAhybj8pYf7ZzsH0e55RkDg4D7A5YPJshurBk3Pjsffd+/lUXPmdvVYrP + 5ZdGK40T161t7HWJtUiB3KMhOl+tFzs9E+Cb7iq1e8vBU6zMObg+2Fg5dffq6VcMts8fWwrmC9tXnBLg + yufgeIj+l3/1zv/jr931r/7aXQqwO8AKLl8mwLnSwiO7px+iCfiLJcD4RNaP3nnHY3fd8fhdd3g39K0u + bWtbC0/Z0gEmtNHmDhwR4PbKAdWqbSn5bSC4dgH+9E/d8us/fStbGGBG/0Z7gA9cL+mmpvD0AWYY1EUx + QVKc2HOOalYkV8Q+wBqiw/QMCGFr0GVSOsBKrPlGqoDctO/yV0vzHCXgA+m9yhBG1n/83vf8yS88wubd + YF8smR9HMel6CwCZ3HWZJBUQ0dbmXn262t/cGd5wG+qSdZ4Epby5DN3omzq1BtwpzeEmNSvZ85rv0UNy + WR9hsTduRQLJCqSYEJosEdgh4MD3vvSOP/vtd/5/X36nArxs3jgw6+dwS05x9SnZmLMCzLzdbG9vr66u + EmbiBDRHkispJINeqxUF2B9CGA6HtBcEwNX/dft3RAEuVcySRImxzIAhVUCeDuydrJ65k+VJ9vhAeq/q + adI/fc+7/uiRd//Re96FrPTM1IORuZHEHtXD3cnaNHeyUDHCsoKItgcjHO73eqOD06iNpitpr93EjZNr + 5k6WNaB865Pt09Rpo2HKKB6w8qBjqOBiEJiXjRvDuIDsx+NxSHp4nl25WsWBb3/u5777hbd/74tvV4CZ + 6jsDc5fjLX/j9978N3/voce+jJyc4u5kSTbmrACDey7ArI/Ug0PQBMKxsZSb3+jwPdiDQoY9+OQRPVhg + bFAPDhH24BA0z3D8KeXzUYDdgWPHKjXzUlj6mQe5r4+PO8WCiBaq5g+a1KrV+pp5OYt+p0NhDw7RmuzY + TmM6h1DP51farWmr2SktlIUOZN24vBsdFurBHukAk2uhXMeBBx/7xmsf++ar3vl564wD9cNY4pQEkPPs + sudg80zayeCK5uATW1c8B5eWTcHiGTh9HWxnij9QgB95d+gGdUrNpj+ZSe7pOThXNq/CV7nAWN0yAU5w + 1I2O5mg7rFP8JGttF1Zmjk1g3YhbKphPiouIAm8C/PmfDwMMmSvVcOA1j379wUe/cd87Phc6k1mfl5qD + Qb0360x3OpPtUr2zZH92Xg7mYB9gJUbAVhiGgw0T4Pf8Fx9n8wH2ifFGPVhqzS6vwq1dd/VLAvVgpWSv + OTgKsI6yNKZm6ceoHvDkrh4sFRDRYrNdKJW5/Glt76NqDgYF24PXk1uV7oRjS63JLnWqqpDdqh1Lru/3 + 67ZyDWntuzk4+RCaB6oC6fQA6sEI/EPAgSjAzMGFyrwH+wCbU5IeLNmYs8LCHEx0w98mAdNY7Nad7bB4 + o5ZrpdI8wHaIVtUDTmQAIA8YkMstn9y1Af5LH2bzAc4XTHoS4DGTAgLqci4/bptZ59888dC/+9jD/+eT + DyNvmfsMBiRgdCG9TmRfr5jXOsMAswaDZynWbJuFdKPl7ooIRITct2aHLL5QMUIzJKLdzZ3ObHW8uTM9 + fwuqvctg5ohw2xial23lSG91n9qgZcoNs7cBPt7rLOfNMtBkZnksGTeYchJSQKWeI1JgslTlc5TLMLKO + hmgW65VGBwcI8IPJEC1T5M0VNBVqnAjcWLjRwbRMHkSe8VCgB5vorh4Wq2Z5zKGyLU8YYJ8egcaCUQTh + upO3Ua2/8r7PsPkALy2b9BylCtTipI5b5tL+T5981Xc/+qoffPzVyNtD8yMlJcBd0isl+4p9mhQGWDz7 + WsPULP0Y1YM+SO4bk32fjOZNRKv9YbnR7PQHXfs4lsV6IWceM/zrX3vo3z75o//2yR9DPr/ZcacsLben + pgczXRjFksxgJsCdtr4fajITnzOL+ar9EyUiBVRqPCIFuod49tQTWUcBJq9itRkFWKdwNIS1Z+xQw5ea + g5eWc5go1uaT/6XnYJqIdc7hhjN3Uq2f/OtfZfMB9lBDc8qxY4O6eUL37Q/fy/b9XzP3bjaCKZD6Ir1T + nukcvDZaeJpERHNlMwhXK2U/B+tN1e9/9L7vPnHfnz15H/JNm/OpsTlemIMFct/NmlatG1d5Ds7bOTga + ooHiGsGkj250RKvoXKGEiXJ9Toar6MxFFg3HKceO3XjJAJMuHyQeNszPNL7zkQvf/siF7z/xSuTN1CIW + yG+tojMDfIlV9Oo4XmTp+yaMB9XZugmw6ZG2Zm07+95HzKsUN23M4xEtsgRy32nFb7bSzq0bz24VvRhg + uk4uaxUNv1Kv4Ya2eQ+LVtF056gHL9vL6lIQYPXgpx68/1sP3v9PU5dJ0SpaAX7yF3/7Y7/05YUA53Kl + 3qA+mjanq8Wmy149OAyw78Gd1cOVk3etnHp5d+2UAny1VtH11a3KYNRd3eifuznswfjA9j07kNwYBLjS + WckM8GZj8UV/C9womN+mxHj2q2gX4MVV9E7TvOXilATzHkyo+/ZPZ2kwBAjFsjFXa48saXi9SvHZ11z8 + 3IP3f+VHTIDD9LRB7CAIJ/auU1z9Jr7cbFGb2nonzomc2JeikwCbmt0Z2T+xUCgcv/NHcUMb5YSr2rWe + C7C9DoaUD42Wuctfb7BamIMVH7lvsshKkgFyX7nngc3737h9/5s2H3gYFbJUNIusMMC37HY5odro7J25 + +cZ73ogPJ87f0ZusY2elXt+3t1zunk4POu1xzf1xBdY39YZZ6w3GjXKF1mhytI4YgV7k1RAMn+LZc1Fo + 3Ficg1k1VWotHAjnYBIL+jm83lSXQQTOcgMDcT44OJhOp6y76IiAq6Zm2zy16I7Xza2Aunme07bN5Fcf + ftOvPvzQx3/8LyDrOY/S0z6YhhGEVqPdanTIg8rttvqdVq9aq9Zq1FW3e9wsaqZ3XGhv7NUqLP9qGyNz + DysM8OFqz1gxD+Mqo80TJrol4zFc195QCwOMXXyoVmv6Ckx/MH9zivSlchEfjq+frlTLOGDMVuc/LfQb + dKtpHmeFAb7zcFyvVbfP3I4D4dao18k32qzpWqtlbmNpW98a4hqkd4ZLFa+GGI1G4tmXKhl3ssix3R2S + dRhgEgPyPT+b4kDTni6DCDSm+Z0slqlPP0TbsfGP3/uef/YLj/yrX3wc2R2wwGg4RAsKsFMCUKHFTpL3 + JYdoFnvtmbk+QcQa+ysaopeXcqWC8WF75VSpUC3kF273KLROOXqI7q6Zm5QX3//1i+/72gOPflPOkC/j + CTMOl73tkhnbrA1zETxda5y7ZXPvVL+Teu/nGg3Rh3YsiWqffjzPDhPZi6zGPAx+dfOHj7z7f3/80bBm + Ad03XGQJlwhwuT9yyqUXWUvLnSTAwhUtssg92twBiyjAXACR9X/+8L1s37WLLBfgdRNg+s2Dj379dR98 + Ss6Qb5sr52KR64FR1VyaWxsOTbO8iJs7OGqR9bQBxlb+6FuVJ+wHLcwVYQBmzHmA0/eiXyAB5mqtYx/V + SQVXGuBT27fUq61Bb9xtji4dYK7iyfo//K1X/Ie//Yr/91degXxUgKlI8r1EgAlYejwD1yrA3acLMBOw + 3ujAFuCqqWZfDWkPVsoJ2W6YiccF+LEPIOseE0BguKeVeAboe7rUaUiCUsG8K9NeWS+XiqjFUnl1YB7g + hHPw/qzDWa3+ZLh+uHn9fXgyWD3e6PRJzwQrN3yAzX0c84ZvudMz33Tq9BomGxYmxTy5n9y+gemf5ttu + dlHxSv6U7GuzbMVl0xAhWW2Q9TcffYDtqcceQL5ue1Qpl8a751WzPsCkJ99xs9loNmv1xnrHjJAYdZZL + JVYk1AZyCI7qjQ6nB9AbHZJzBdPcozkYWw37Lkc4B2MKUPxz4zEO1BIHAALRnU+7zKC6k+WRL5o3Byqt + gdOTm8BE94/e+55/+UHTg90BC8yxcnOKBWbJiTp1uoftOtXhGMloS0sjeycrDPDWwHw7FAeibWlpOX0v + 2ho1SO5Fm1tIAAfIfWfltDlUrdKcUCFR86XKqb/0cwowm02+xDUAWf/73/gZtv/nN9+KfOPeBL63cYas + wwAv27dKzL3ZcrlQKk1q5kpURgSWr1FtCOrZaegOl4CHZB0FmByLlYZzIwmwO2Fp6YT9EyXm2VAA1lXz + gYGAZy+yGsGNDjs2fvNtb/36237m99+98JwORHeyBAXYKQGo03J/6BQWWY30IssM0ThQ76/W2kO24e5N + qJBXtMgi9+3ZKQQ8YYU1d4aQj2fN9Z3h/qlyfyxOczDVyvanX3oH8k3HzevHR83B+oQaF0Yj26GtDYej + huL5mLmIpx2iIRcWWYtD9J69snBKgoVF1pEBDlbRTLBYCTd3wOJKV9GlXhDgI1bROLCcMx8MY2skL1Rc + nQAnKBfnEzbtn6wXArxnYt9dUw/+3Qcf/cbrPvgtuUG+BJgJmAvPYcW86GltOFzzACer6IYdz8LNGjBY + CDCXTVpk2c5t4rScy2OiVHdRF88F9MzOxD2m/QAk0BDtUwJkH2BHWaAS4MrA1J3UUTMcok2AtwauBxcI + GlWYW25P91BJn/G40BoB0eNCGHJPD9FAR1kVUnCv5u0QHQb45uNTDvTWT5H1xff+zsVH/t4D7/uK3CBf + M0SXSnTisX3RU07IFEOulpyoHqgKpNMD6I4EAntA1t/+fDxEF5Ih2vdgUu/b9fPrtrdev7N9cWMd2d8D + XhiiudAej8cMOWbSLsbv/lRq5g1Q5pt8sbhqL7n69ovCkAIyUzh+hGQubx50UKchCQr2hWRzq7Jgf6xe + KK70zB2GcA4+Pm0W8uZpR63ZsauV8mDd3O4gfctOeEmAzUyhz+MwXLa79kuCXfeqL+2C3A82ry+VzXOV + Zr2Nqj96wlH2uEfNerVWNT+OCgN8+8l1Dow3T5L1697+6df9/Kde/85fN26UTJcdMS01GtVafbVtRkj7 + ehaVZEyxmMI4Xhk/EohXdhFYZLnKL5WW8/bRy+d+Ngwwq6Z6M7XIKhbP2+XVZr+/PRoet/ez6jYKgDF1 + PiqTATG2c4p5LMrJG2fvObjzR7fsCrY9WrOnmKuCVTvcD2yAQ2AL/5xikcu7VbTTEyjAjclK0WbHbqVr + fk/3Z09c+NMnLvzgSRvgSZPBj6yr9ZZZEZZL/bVDVNI3qqa7hAG2Ths7rY75nkSzbV4BByyYFWBkAlyv + mV/745WOAmpTARZYMJN1GODbTpiCr+2eJeuf/KXP/sQvfuanPvQFZEJJvsO6ucNXqdZW7A8eZUSguWPc + KQHgnbQIAu8q39SbArzQg7FVbXTJ2gXYDtEkPqPvhVFBXMLYm7i0btlhcNLAYIA34RzMyY3hRne2p1cJ + m+MddyD1lR2PZzMHd6vmJvAfP373Hz1+95988B7kmf2BPVnnCmVGp+WlY/iACnl152CGBycdPQeP18yF + +I+96+N//l0f/7F3fFRukO/zOQcniyx9bcg8zAb2aRBX89bGJRdZOlljOXJjuGVFg2sR4EbFtNlP/+wD + n/rZB37951+D3G+6OfiFEOCivcMQbpDk+/wE+PFvvvbx333Vu8xAAnm5AUZilGBdwEKJPSdzTcWwILk9 + 2YXXoamdAhmOlVhAxkUsRqQCHJIAlQBXhxPx7CcdMwf/4Mvv/sGX3/WD33k38s7UvEpB1sVyjSGd+bgz + Mz+bJL3e6NBblX9oHzZ4O7WG/YJC3X0LB4bc99bOItD+GMXkDFACoBtwCOzJiKwV4O/bAN9yMLOHTJW1 + kgf+VCAk+XbtuoSBfmKfyHq7/E9vseICxCepFhDyCGTthugvuADDM0bjwMX3fPH+93zpwlvNUoC0J3vm + TxuwNjLzWMFcx7L0wAJgVJ63m8PDw83NTbJhkmi3TIPtdrj2HPW65j2g1ePXwYNOt7s/NQ8uNkYjVt0i + AfJ0OqWJhGSrbe4oUachCTot88RwsnO8q+w63b31KcX43hfeQZH+zNbsub21Ttu8oTIYz/q9Xr/XXds3 + t5NIPxkOcSAMMF7Bdzvd2cqIAE9XhiYb44CZdM8d3trtdlhCjkdT1GbL/J1VJQDQUtkP+n2yDgN87/nj + OkSStePXWwdcGVUJg+GwPxyqTmwqA/6fzWZWXID4JNUCQr7RMs/WogDDD4YjHHj5Qz9/90Nvv/31f8U6 + 07153ayce/Zp77hvFlnsMQVYVBERF+D0EN3sDHvjtXbPGG1Pru0cPLC/K3QB/m1TsxtDM7aQ9QthiBZa + zgFXRvJ9jofokn2r8pFP/+Ejn/rDt33YPdR65nNwb7IxXj8+mG4gd6bzF5p+OAPctO/MaltaNvbJ9zkO + cNleBz/yqT945JN/8LZf/YZq45kHmFplqc0e+Vovsq5WgItl8zpjIfhtxNUKcKU9Hu6cH+/d0J4d6NeF + qgTqdTmfHzwnAS5WTQ9+6698/a1/+x/89Ie+pNq43AAzZPv3olk8m5rNmU+pFnImwL2VfXO+ba0r9r2O + 3uLXnpG55GJWD0kGMwU4JEFuyQSY6+B8zrwSy9Ji2jdPk8IA7630SUbW5VqT60m2/qq5VqHNpd+Ltvbz + nU5z92CTAO8e35itjEvlAiUl9/2N61ikUdRapWECvGxKTr7ssQYvlaJxHWnc+KKpVrnBdbBLWSpX6816 + s8X/Sk++x/u91X5/pdc7PR6hmnQylTMfW8G4VA9U+IgUmGJV+Rw96r3ocsX8tj/cSH/aflaZtZ55n6Rs + roOrydvptN35dTCzcRTgfM585qmYPyLAtYUAcyIDwDMO8OySAabeywTYXoxmBhivWDkT2nAbr5o+cekA + 43AYYN3o+Pf/41v/r9946//9m29Dvv3kulKyx40qw4ANIyr5Hg4Hm8PhxmBw3WSCao9YU/YPsEW1AVCv + JMALd7J0U4gYNzrmxZ1Wf1osmu8pLAbYDCTZAWaAJQ8EDbOY4D+Mohlz4x14c2hpaWJvJNFbxQicQk3h + otMtIBVgpyeAJ8CVwRhJ6qht7mSFAd4aG8/IulCq5s2La09zL7pSNY/6P/H1/+qT33jzJ77xZuTVHTPj + kPvu6hnOovjh40IBh+Elw+pedLhtj+dP8agyqtgp9l70qFptVKs0uPWm+fStO2BLRHOPakNgKHbSIhQJ + yQhknb4XrUP5kunHxaoZe2H03WyaBu2JwCIzhdm0l3xciAn2FFjy8zgHa0UD6gOz3EPInINLdvb96Fff + 9ORXH3ryaw8hz7ZdD778ORh06qXVvrkov26zO2xVS3l34x5wZUmMnfJ8zMFC9BGWy52DCX86wEp4jQIc + vnQ3bJkA/+kX3/H9L779B182Ad5MAjzeODFa2R2t7Gyde8XTBvjJr77pY197iM0EeMsFeGt6wiQolZgQ + njbAAg7M2vGvW9MBfo5X0cJy3rxK5T+jdFkB5hBzMFfKUCBnbyENd2+a7t8y3L0Rubd6qENgxX6JW4us + EAwyWlYIzBDT/qYCvDbazekrc4wk7W65PyLA7b2T5d6wWDXf8B/34g/obow6+EHWu2fv2Dl1887Jm07f + +QZUEmumSQJsbnRA1hvmjWi678e+9jAb8vpej5CQ+7n92ztMWePVUW+GqjgJFJwqcEoC96W7cYPIhaCJ + UByn2MGwX61WqtVypTKzQ7Q7YMFci3GnBKAXOWkRmpsFFiU4EC2y3ARfKjfsSFbrTi2RP21vbhTtl+6q + 9uXOShIFznJzMPPQxsbGZDJhoIYt2adJ4dab7cIDEmzYQX/UaimxgEwTsdO8Ixv11vX7L6dCtbEg4FC1 + 2SS00QbfbTduOdx4xXU7F27Yv/f63VtObgw6rK0KZF2rt/CoUi4O7NMkLLdtCwsDjIV217yNHAZ4+9B8 + FYqs7zz/wPba8cO9s/ubZ1Cpdjlp/LGvGkr1aDfMm1kHKx1WLo6yiSldo2HuzSk9+Y5bzUazWW801u07 + b7A6gQT0FoxbbQ54ainKTiC95wtFs9aLAmxslcuNdn/19D0mIiv7Nm3lOvu4kJKY96Ht8qiZfBiJtjsf + ldHDIVrAUKES//BGr6c0U7/P101dp4QIhm0Wu0S0c3C2u3vYP35ycss9qO6YRa6wYBYHuA5mzWCvg82t + BkgtJeIhumJucYQB9kN0MgeX6YSoyB7MKekhOvmU4fzXbwKlo1M6RUO0XdoyOGa+spOesMAzHqJla7lQ + 1j35cvIiht6nbNFSWSbblzsLSRRo3/Ps0gFOv7IjXNEczEqSbJxCljXTg2EJGP+qU/urrwCUxEkWCvDl + 3OhI5uBLBPiyFlngMj9laKr1+ZiDqQRtUs+OzJ35O/f27trfv3tvFzl7kYUJBiunWKTfiwacOrPjQK8c + fxEisweTR9jqC3UT4FyZUcg8bW/o4xgBqO6wleBAvmh+Gktr0A/sIRd7sBmiIcupHryybaYfIrqzYv5w + DpaLBfM1FmQP8mLgdUoC14NTP2/UdapTbIAv8V40k19mDz4q8PMLVgsc+I+f/bn//Lmf42JJAfa2MKur + Nan6G440PUg1fd+D8Xae3Ww2e9r3oiEHdjWhrWX/RKfAIS6jqUQER1mSqAOR2Gn0BkR09dxN62dvYNt5 + +atQS/ZRl06hnH4iLxXNUqDe6sLUa9XhhnkxyqRZeC/aBJjJst0xL+tEczCrFSJ6Yvt8uWLGp1ajg5ov + uvei2eNweg5u2Tl4f9YpluY8adJz8LTVarZa9WZz065LYHWIakzPwTo0HA6j7AR4VT4HaTQ4EG7wssW5 + mKVf+qrWG9HVet38kQv7JDd7DkbRjQ56IaCBFEoVU6GtAU1lTuZy40plr9/faDbNc8sEnEhjob+SxlE2 + ve2oyS/56XzNNhGtdPo1AtLp9uyv0OD9WVSi7g8gYxMHoufB8HoevNCDl5YqNfO6XRjg6EYHNRLe6MAO + exzWzGLyTlAsmEXsRp+ePedJQ4egLJLZk2+0GbuJ59RsVBsAFT4iBUVCsknWKG8MW7jx2vMrU/sevz9E + /RA8X0v+eTCtXLeAGOE4BPB2PjBg4nKGaEA8aE26BxKC1k1+TkmQOUQv2y9+wNcXP28DCAOeOeWyhmg3 + B19iiI42YzcBeUVDNBPwyam50XHhRK9Rns+4IBqiuUzs23u/NwwGPTrTYoU8yyEa6M/L3m7/vCzREQkw + e/QQbZpd9hBN+Ofd2eKoRRYgcTqWl7fIapguW2CyMHxtZTMKcFgSgAPPcpE162+d3r7l5debPx1xuHnD + qa2XGbsBaFJOsqgVlx88M6Rm/8LLZuvdhXUWRQ7LIpD7ViPjb1cdFcjLXGQBimwCbP/yWVQtYTt7ho8L + BdOByvEaBLyIApxbzlfLzZtPmD/+Uqu0SoUF+zgcBThnq1VbxbxyP8dRAd5pXvMARzg6wKYHZweYIYJ1 + gepdoDa1DbfOcukdHiKWjAdOSYCLZOGUBDQF4BQmj1aHiBar5m94wrc2dlHzwa0lxnlvhDHKBBiBeqcK + RuYODvzinSwTYNLU66k7Wbs9veTEpHJmz3zyZ2nZXKDJuEApqAKnJDDfVC+V88X5n44A2CHxvCwWOEru + +13z53RDkJj5Ll0bQHNzGnqa5BRrgRAT4Ju36XVmreCBWbqBN37K3slidQBZKZopwz3wspU/H/nJmACr + kQrTg1s3z927ed2F7mxP38kSyJswEKHIIWyZWWCRJA/yFclUWml3iWjJvkbPirC1aQJsptjkLAVYKksK + Irr7stdvnb+4ff7Vp+77yzbAhXSAOb9mv5rwsX/w0Me//jAb8sZeb3nJFIfuf+747QQ4+qMc5KIA+9w9 + 6NbebQ+KDIkgnr0CfNAzdxnDxFQjAU73AdLAR2YFAhxWPgvCN9xg3lP7G286PJg1fUsxmdovfftaUoCP + 5QvLRMT6w7kcAng7DzDnRIssEI/CCVR4pySgptLjNh7gilOSRVauxHLP4HIWWdFGc85cZOlO1n/zmw/+ + t7/1WjbkafD9lDM75uvkTgmAw9EiSyA2odsCRY5IHCX33azRmJpN1waY1/giIr5k/wicttMrjXCqoH5w + z9fSWRvgGyfjm6fTWyfmkomllg7h7Xzkp0ul52DCk+klidP8tZiDBf8JB4GT0wHWh4Q/9Kk3/vKn38SG + rAf+AuuszACDaA4WqJrQbYEip0lyv0ZzMDAD0OK9WyFsZ9vBnQltPjB4O8+O8DBKECGKASRokPGkgEql + RDyyxrqIxIKam1Mb5oVZJgdchNedLHglAOF1MDBCLt+1L+vQeMRXivEDf/hqzczBv/XUez/zrV9gQ97c + HSs9J57dtXNwYlZAJS+1S0clYDT2bgvIFBlSsvZMLuS+124xF0SJ6S0Yd3oCeHpqmNKD9JEFQB0xw0U8 + ZjU/ijfM0tLZvrkaZow2TJKSZPN2Y14bHo8pAL0TcIw91U0sJXug4mXEIzPC0/8ikuoDIqmzur2TVW02 + sVyv1XrbB6ilormBoFNwKDSCUKlWR1vm57n2zSzDt+xb5mGAOdDumKdJX/onj3759x9jQz5+cpX2T/p8 + IXf9gfloVzH4wwzAGLd/Lcpn58FSwLstIFNkSMnas4wg95ODQbnkSIFq7Nsfnzk9AWnoRWFKD9L7ygdK + Q3Z0mzA9MmZxz9cSe6rv7Mi8FEZ+PjECyeajMkp0J4u9OXnxT7wjA8IT8ZxIbNLdGqeBSIbvkv1IVr5s + fv5GvJvqwXZe0SnpHpzLF7or5kFh0IPDO1l2iMYlu4r+7SDA2/a326Rnf3bXzsFLrnSCMX6FPRhesvZJ + D3av9diEBuRIH8jswdRSmNJDc7BTbEpAdgQyTI+MWeIX9mCKf9LeK2UN5hMjcPq8B3POC3QODj6jJGTO + weWKeScrDPDG7vwjLy/SOZjsCJJTAoRzsPD0n1F6KcAhXgrwiynAXP3eePhKAlwpZUTihyXAk8lkOp0S + OaoYSCBmTIqeFFCZMNI8ywQqKySRscDsLpJ9oz8kojX/5y92zSKLBYE/S8s3ryJUq7Xxtvn9NbL49ONC + +E7XfEDpS//zPMD7p9b1iGVv/RTR1Sab1raMZzwuBNSLd1tANgvDel2y35P7ydHA3LVZNHLUKzvhqzkh + 0o8RUcmOwIe8ZHzztcQe6MWd6DNKJJt3WsrpX3xX+2WvdJIFZKDChzwnEhuaW0giKzORLAGqHXcnC5LS + t+2drLy9waRTsMzqxqsIxKi/Zr6gkE++qr744rsJMAeaLfPb/jDAuwczFhwmfbXZaw+no7V2w/xZOQ9j + PPhlQwjFJuSRKR2kZO2L9vHcvr2TJVKgNqhPjDs9AWngw5Qe8L7ygbVnao9WFaZHxizu+Vpiv5zLnbQf + b5BqExqB07V2M1BbdkoC0pGrUwJwZponNulxW/k5BYNX+LgQXOaX7ipV8zw4HKI3gx8GAsYJJwUgL2rQ + KQEUG6ckUACcYoGj5L67+IdDBWo2PWGBo4bueSQCkB0dySkJMIt7oXGCcdvEXCb1bX92rD19nh1Keg6m + SJle0pbTPOOJkwIQ8rApaA4+VihyMtcQtdX4lR2ajpMC6C/mOgVX7cXJv3j/L/xvH3jf//qB9ynAeh78 + 1X/2S1/541/62p/8VeSNvfkiC2RaBjQpJwWg/aVbMEVOk+S+08wo+FWZg8kucw7GPSdZTOyQpu2mqflZ + vXhOd9lR+LW1tfF4jDnTBhIQM8rvlAB4k+YZANKk5i2noLbMGx3lSnWwf6rZ6zdHU6MGoCHjjFMsqvXW + xH5JsFI1bwjBNO2LKeEG2WrPP+KrbWtv6kvDiVh2SgB4mrVTAjAahW4LlC4i8YbcT9hpNQJzbVQQQa/N + pqG5OQLZESGnJMAs7nnj/DdptU5Pxqen08ORmcg9SOY6LdLe3l70vWhZ55BkD1RiGfHIuJ4msUBr8CQC + EY02HRKwzD40Mt4yE7A2SsUh6n69192fTI9PJseHo76132g2Jqv9ncMJod0+mKzvjPrDjl4WljUsh2aB + Ocve3ol4gM94HvJKDCnZ7W1TOz02n3oWKSCPUn+rH8Cz0AlTevjvRXugkh0RCnnJuOdl/lVYMSA0m+Zm + m1096Chtej7tXtEQTet4ZkO0B3EtdgdOCYBzTkrQXj1cO3uBrbN2MjzKfIh/TkmQL5o/WGS/jRcjbVmg + RpwU4IqG6K2GWTNG9jOHXEDMnLSIzPRkdzlDNAgv4YiOBE6fZwebDjDnpNdNgMRpngCno04eaW8AAQ5/ + fOaRGYblZVez4VFKHi15gB4ahj8AF3As0zLIDDCWL12JQsf+VOTW0ciE9xoEmOwyA5wuOPWTJjl9nh3h + uRZPk8hVSz5HWaASYPPz0UUeMLCwj4yQF3Yikgql8J5EyOWWu8MqAe6Na/nCwl1ZHMOyZwTxapeOSoDl + yG1k3ICUzF5rPW0KsE1oQAJ6i1MCwGt17fQApI94VLLDbMhLxj0vS6B+0iSnz9sNc/D6+jpBwgPAAfaM + 4ECyByoTScQjs0bDy4gkGe0mJAHzGAEebu4w0TkqAWsN9pERzKazY8oHnmw1WysbQ6Krbe/klNnfHbIW + 8Dm0AMQz+UU8wOd0jiSGlyySOZmkbAqwSECCyWTilADw1FJo1oP0EY+KD1RIyEuO3FDKNEn9QLoA08BJ + hEDkgQSaAM3Wk8AktcNamlcPjkj14JAEqOrBEQ+wTOvzvATfg0OeaULDl2eWlpe4/hpN+/Yvny0kVg/2 + jHAUD9SDQx5ZPViyJ+WGAiwSwFPF6kYhxPvTQ0Q8MiA7zEY8ZtVZPY+gHizZk5xOmBEMMEQLdUoCTpOh + CCRO8ywyZTeEYuOUAAQ4/KS/h8oTgTCoPYXwMYhAA077hmOZc+1RPJbTbuNGmpQbuB15Pq/ZRVwRT3Z+ + xRQiXXA1PqckgJzPwS/sRVbGUpyazWw61FTaDZhMyyAzwFhOu40baVJNIW38qEDOa3wRmenJjmI6JUC6 + 4JmNj9Pn2b3Yh2gBlWaKG063gIRRIB1lgUpeRw3Rqi+nJ0Yoi2RPyo2QBMhXa4hWD3as5TFLjlEt4W3k + BgKnz9sNaw2gdIBj7Ck8bVOygAw4Lc3TPvAmIrEAQhIU7B8e0/eiHZUgsiyB2GDEqxKYERgzYsuFgm4J + Od2CNDBYjhKjkhc1G/EAy5HbSgwv2ZNyIyQBbrDASVcRe9wLSQ94X/lAafAB+5ERykKOYVUjkDLtG8x8 + VKac+EQjDSErTgnAmWmeGsRFpyQgJ4w4JQFtjwBX+yNWQo5KgOW0ETntlAREnRp0SgDaWdoCDJadEoCx + gRp0SgAsp93GjTR5RW4ADTBpkN5JAcgO+05JgM/kyN7pFtRP2g1O18BgQIrnaA7mCrJpft/Q2jnM1+Kb + X3jppADkhR2nJMBhatApAWhnaTdgMi0DDd0RsBy7fck52CkBcMNJi3je5uDnLMDLpXLn4AwBnt5yT31t + 27EJXgpwCLK7agFmfNYcjMdymj2FJ5aeBMiA09I87UOV7ihLUq0YCclK3Twx1NZe3XBsAiyHRiSQF3a8 + KoGhlYkHwZMAmUt7LDjdAhKGGgxTgqN4gOXQbQm4AelVCTRrzdahEWS5EZIAVUO30wOQPrLAnuwoZsRj + lhxD4wjUT+QGAqfPh+jt7e21tTXcpYoBdtkTM1JIFpABrSHN61ZRRGIBhCRsrVohXbvZqNsfq4fAcmhE + AnlhxKsSqBGA4EmArFtCTreAhGEVE6YER/GAMIRuS8h0g5QgJAEyvSWqDYA6Ho8jUiB9ZIE92amMIgEy + ZskxNI5AysgNBBhOdwGmeVJUhjI6O9CoqH4jWUAGnEwLCnlOxFw6sTpfSALxtK+IB1hmYPG8BPIivVcl + qJNFFnBDy1GnW5AGhjJHicVTUxEPsBy5rcSQkj0pN0IS4AYtlfQhCVDhI1KA95UPSAPIji4Xpkemfsgx + qiXVp+SQpHQuwNhaXV1VQwASVlZWaFmeBMhgZ2dHd54d2+3Suk+cOEEnDknkmUVIAtTpdIrxiKe5YZkI + eV4CnVJGQn5jY4MhxzMC5Tl79iwWnG5BGhgsR4lRqda9vT2cd1QCqiJyG5nS4TNOeh5BbkgWCXDjzJkz + GHd6AjI6ffp0Ojtskp6znG6tAbLDfmgZGbO4x97zCHgbuYGAWdqHCzCgBWkvgSZAlrQLTwKT7tgxMqDl + Rvz+/j5dLSKxAEISoGoAiXjaHZYZBjwvQRMHcsjTwghbSALkc+fO4YbTLSBhKH+YEqCS19aW+Uqjoywo + OFUTuo0A6APUGkdDnqiTWLJIgEzAwoIAZECAQ1Kg4LTLkJdMdhQz4um7RJfhwfMIeEtthL4JqMeOHfv/ + Ae7AUtoKEbIJAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAMAAABuMnOvAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAA + AAABAQECAgIBAgICAgIDAQMEAwQGBQICBAMGBAUCBAQEBQUFBQQHBgYGBwcHAwUIBgUIBAYJBAoLBgkO + CAMDDAcDDAUFDQgDDQgEDgkFDwoGCAgICQkJCgoKCwsLCggNCwgODwsLDAwMDQ0NDg4ODw8PBwwRCA0T + CQ4TDgsRDwsSDhESDxITDhIXCxMbDhMYEQcHFAwGFw4GFAgIFgkJFwoJFgoKFA8LGgsLGw8PHQwMHg0N + Hw4OFhEMFRoMGRAIGBMPHRIIHhUNHxYPEBAQEREREhISExMTFRUTFBQUFRUVFhYWFxcXEhYcExcdFxId + FhQZFRgRERgaFBkeGRQQGhURHhMSHxQTGBgYGRkZGhoaGxsbHBwcHh4eHx8fDhciDR4jDh8kFB8iEh4s + GhUgHhcmHxgmHxknDiAkDyElECEmFCUqFCYrFykuGCovFiQ1HSczGiswGSo9GjM5IBYMLhwNIBUVJBMS + JxYWIRgRIhkSJBsTKBcWLhMSKRgYLBoZMxUVIBsnIRwmJB0rJB0sJR4tJx4xJCsWJi4WKDEXLDMdOicX + ISEhIiIiJCQkJSUlJiYmJycnJyAvKCgoKSkpKioqKysrLCwsLS0tLi4uLy8vIC09IC4+KSIwKSIxKyQz + OyMiMDAwMjIyMzMzNDQ0PT09Gy1CIC5ASx8eQUFBR3Ope1+bf2OhdIxDPIecPIqfQpivuk1KvU9MkrBU + 3IU+34c/54xCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApgXMrQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAABohJREFUeF7tXAd7 + G0UQlYgTAgSHDgZbBqxCb04gIDrIEi70lpheDAZCh4QSQu811CT0DorAIIP/Hvtm9+7W65F0pyva4Hvf + 56cZP+/c0+6efNJIyvy+W+AH0O6fQD+CvqdfUEgkdS83dW2oqZulfele/nPmo4zAYBZcAI2A+gbBeRDl + UqeQ1bWhpj5klNZ0ClndKz2dGkwNUt7CYFP8mnJrDa5WeZwGdxaq1eqU+KlWp0GbQLXvmsFRmCwIEFXG + wVOgiSJ4I8jUKWR1ORThhy1m8PiywLZyM5N5BtHW88EUEl2wFbwNRHl5e7l8tjYDUc5g2yUWBilvscQg + ynkDCRgUoDw1GKXB+kG2G7wnWYOfDQkUc+BxUBWUK4JrIMpJP60eEDS+AtJKa/UpZHXv0O9ldvQJ5FaC + K6A86IAcuACinHTcKT+oq1ugr2/YKK3Vp5DV+4pOeGv0J8mjwmCUS9zJYA4UxOA+Ky03CErSIOVPLbgh + q/fc4FH/uCGrx2nwi7xAtQCeAk2AClXwZD7/7gLhX3kTBbT6FNZA2qGJcGgZfqDPYBGk3UNxNy7FbSjQ + 5jDRcQbdvIv/JCBT55eQdGmQ1SmMZg+GMDgEstogZ8Aig6ssN3joXGiD/i8WtH/mpr7kYgD1CXPqtg0w + oM3Fwuc5gcoweAJUA41UwOMgyqVOIatrQz39oTk/GDMObdR7v5cnyRykHu/B9gZBdhrUYaVBqV8DsnSJ + 14IbkDoa/LRfIL8WXANVQIN58BiIcqlTyOr9VTc09QIN9XQcWWK/PSpog/7bM5+sERjpB4+BiqD+YXAF + RLnUKWR1baip50GG3iDskTftcO+a23q5Bylk9YMbTtjTk4RCVs/ablACoa0G3dK9Mjj/thMmZDAo5tWt + gzYGd40JTFbB06CNoNokeBOIcqlTyOhX/DHfNcamjEMTefmOGJd4f5omi/fgCtsNSj01SHkng+ubbmjq + URoMgRgN7kTTaVz2o1RPKxS0VlecrbDFS/gC2pr6PTT0FjMUzQz6MVi23WDHkyQ12IXB+iHWGlxVKp14 + Rql+eumqksCVoNL1bgjaN0qDwa9mHlOdrjbQxrNXK1KnMJmrmTuo/cXqPVhiAVM/wXaDvIHUIGdwgdWX + tUH9agakXW04lxSqidU1RJV4r2aOGNhw9IDAJS4dswF8A4jygRtBCyBTv3A1qoSYwQhPEq9nq+lJ70Fe + 5w2kBrs1OLe8DLbvuKtc6l5H3NVPVf2ijnjSGaqNpzBkx13l/Axq8NGSWzqeQn4G3TyiJb6LDLK6jXsw + NRjQYONA2w2eHKtB/mpGdXqiwDcoGPnVzMszAh9LeqMx89p9Wi5w/6tuSDTztRua+uvHomCIGey8xMc1 + 2i8xwBqIZol97UEJr4B1Bm2awWtXCLLZoNkDCoFoDDodd/wGiMggqrIdd60jTyGre7necX9TdafCo1PH + XekUsrqXB++4z18kqJd7UCvAG+ROIpsMsnqSBvE5JbsNnivIJoP09jztPXKqYZQMFh+6xdvzsgJDfeAi + CNajxN9HqoBHNucdesSlbMEJb4n9JGmeCQ6xxLGfxaDUYBiDnIEEDda/QpSQwW6gf4DJO0CUBhc/q/tV + 9bICA+O9Z2XJddyfqFNu7x4s2W5Q5anBaAwunOXkthp8enR09FnxM3rxZeDnQJSPPu+Gpn75AIaGMBig + 4y4bW4GBob3uuKuhaDWZepJL7BXYWw26lBrkDf4JYvV4Dd45O7v5gVmBx0EPgx7cDH4ERLnU/wKx+uzd + TkFJURrcVVXNqnBwv4VDfhUHfTcHhea3dPjSvXzpw8x1aBqZS2jTHjzFdoNagdQgKBmDJ7kfUFmi22Hw + 6hgN+nhjj6Or3lZQYGhsT5pUrmbQeUUnu3IQnAfJF3uMF3+k/m1DUC7sDMZ4kryChbdjD/IGJCw2SLrN + M9jJYOsPxOxVBgM8zHgPA6bOPoy8o/pOfqGN7/ZhxiV/M0gI2vuT9bQZjHmJ35rnllDqFNq8Bylc5gad + 74Zb1gZ9Pcy8qFpXIeCU0upTGM3VzND6dQI3uXTOeeCbQZSv2+KGpt78DbzlcKeUVl+W7jSDcZ8kzZfA + rE5hzw2G3oP/X4OH1S03+EtCBs2OO3W8tS+8+VK1knxB/L05nu2oS53CwB13+aRH3i8Del+uJZzxAvSk + iu2oS53CKDvu3ierTD3OJQ5gkMDqlhgkYnVLDHpVLTXoFUgNOqUz0/8BhkYgU0kdYv8AAAAASUVORK5C + YII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAIAAADWjhTKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC42/Ixj3wAAE2tJREFUeF7tndtv + Y9d1xjUSdeFNIinykEekJF5010iaGXvGk45jt46d2gaaFAlaGyhcpG0CFH3oW4ukfUmA/g29oH1Mb0Df + +1CkTQsEfe9f1I/cn8bf2VxnoG1dTFH7h/Owvj2jpbXXd/Y5WzwUtTCwODg4YCQMh8O9vT0KYX9/n1GW + 20symkAhhCZBMRRCUBLM5e6TmON5SRa2trYWplhfX2ckLC4urq2tUQiVSoVRFjPJ0tLSysoKhZCXZGNj + g5FQKBSWl5cphKAkKAPFUAhB01ldXUVbKISgJOjqo0ePKIS8JOZ4sVhk5BEN9giaTpDBqyvFQe+QQogG + +9xTgzctMH67Bh8fH+MLPJIkYSRUq9VGo0EhNJtNRlnMJGhTvV6nEPKStNttRgIMAxRCUJJarYZiKISg + 6WAuaAuFYCYZbR//5Pf/jkJAV6+eBJjjOFcYZVnodrs4fTwwc0YCTlWcJhQCsjDKAg8YCVh8OOsphKAk + WL6AQghKghWMYiiEoCSYCy4DFIKZZKvZh8EUArqK3lIIeZWY46VSiVGWeIn2CZpO0CU6nRhMIcR7sE80 + mJEQDfZ5KAbjR2/8mwdu44wEXOWxMaEQsEdglMVMUi6X0SkKIS9Jq9ViJGCG2JVQCEFJ3L6GQgiaDuaC + GVEIZpJ+9xAGu4NDE3D+obcUQl4l5rhpDVjY3t7GOeiBb8lIwLpBHRQCOsUoC74lIwErDycshRCUBIvP + LR2PoCQoA8VQCEFJ0EG0hUIwk3STIaz95sVvne19g0MT0FVcSyiEvErMcZxnZpJ4ifYJmk68B/tEgymE + aLBPNJiRkGvw2dkZ5u/R6XQYCbgJYaNBIbTbbUZZzCT1en1zc5NCyEuSpikjAbsMQCEEJUEZKIZCCJoO + kqAtFIKZZL//GAZTCOjq1ZMAcxwbSUZZ4gr2CZpOvET7RIMphGiwTzSYkRAN9nkoBsdNlkfQdB7EJqtW + X19cNE7AuII97usl+m///bPB0fidCR7RYI9osEE0eBpzPBrs81AMPj8/x/w98vZH5p0cBp+9vUshmFsb + JAnaqd3qJuv6STCXq+/UDnI2WejqjWyyzCRxBfvkJbmvKzga7JGXJBrsEw32eIPBuF9QCHmVmOPRYJ+H + YvD1X8nK22TFV7I83vBKVlBPzPFbfCUrrmAKwUySt4I/+Zf/vsUVHA32yEsSZPDwqLO45O+bosEG99Rg + 9KRY9iuMBhuY3qAdSblMIUSDDa6zycI03HHHmyxk+LePP6IQQpPc3iYLPWmnX07zrZP3/uIHf/+XP/gH + c5MFgz/5519+/PNfnH7+Qw5N+Po3WSurS2ulZUzm7lcwDKYQZnYFLy4urS4Xdzvj32zgkOBWcKFYXsze + d25mBd/TS/T9MtgR78EG0eBposE+d2kwuuGOWTH46dOnyO4B1xkJ2GHh9k4hYDJPXgwphG63y0hAkiRJ + KATsgxhlMZMAGMxICEqCMtxLSB7XTDLY644OeuhJt+f36mh0AYMpBGfwNHmVmOPYAzLKElewzzVXsMNc + wa7jDg5NiJdoH7TjPhq8tFRoN41uR4N97qnBwEwSDfaJBjMScg1+8uSJe/qmwHVGAorAJotCwGQuXgwo + hLwkrVaLQsDGgVGWvCQwmEIISoIysD+iEIKSuA0jhYCebPUSCsFM4gymEPZ2u4yymBWa1oC4gn1mZwX/ + z5+/U1w2koet4GiwRzTYJxpMIcyQwdf/KENMZni0SSGgrYyEwk18lKEzmEIISgKDUQyFEJQEc8FZQiGg + J6XKCoVgNtYZTCGMDV656uck5n6U4enpKb6rB+7YjATMEHVQCJjM47d2KIROp8NIqNVquPNTCNitMMpi + JnEGUwhBSVAGiqEQQpOgLRQCepJ0jGmajXUGUwgwOGlctUJsGBlliZdon7wk5nTiPdgnGsxImBWDUcSw + UacQ7qnB1U633Dbm/qANNtt6Hw1GBoWjE+bN4IuLi/oUaZoyElAE2kohYDLnz/sUAk4dRgKStFotCgFb + GEZZ8pKYlYQmQWcphKAk7lU5CgE9SbvGNM0kzmAKAQaniTFuVojtG6MsD3QFA2cwhTBvKzga7BEN9jEN + Xlxc6ncPKIRoMCNhtgw+wY2kXOLQBNPg8tq6+f6jPIMxmaOO8V72NxiMSjqlTCXmzEtr1eenH1AIeQaj + ksqq8ePT12Lwu/v15/2NcraeMIOfPn2KbYIHXGckuLa6g0MTMJnXB4cajW66A4MpBPeeLAoBk3l5ZDwd + 63aNQa1EizGfow13DsxKnMEUAio52DEevZmVYC7IQyGgFVd5XNg9PBk8/zVnMIcEVPK/P3n5qx+/fOcw + 81XmNLHzMpPczCX66El7rbS8VPjyXP4KK/g4NU7M61+iG+ttsxIkyVvBSdWo8DZWMApwB4rhkIBKZvce + HA2e802WM7hV22qsJxyaEA1mJNyuwaPRCFV64NrNSHBtpRAwmYOzDsUl9fUm2uoODk1AHaiPQsBkznfq + FAK+KSMhrxL8XM9I6DR7Xg0OZzCFgEp6m0aFZiWYy9raGoWAnrij06txaILZWGcwhYBKNipFCqHVNSzD + qcMoy0K/31+eAp1iJLi2Uggv3h+20nWKSzaqDbSVQsC3LJVKFAImc7a9QSGgI4yEvEqw3BkJSaNrVuIM + phBQyVbdqNCspFwuY0YUAqz93T9++r0/uuhs1zg0wWxs5+I5iqEQUEm1ZCT/zk//g5FQrVYZZbmBS7R5 + xYj34KtfonENQDEUAioxL9EwmJFwi/fgaDCFEGrw+K0XU0SDfaLBBru7u4UparUaI8G1lUJA0YyE9Uod + baUQ4C5KoRAwmce9DQoBNy1GQlAlrfqWWYkzmEJAJWnNqNCsxO0nKAQYXFk3kpiNxY3cTIJKKsXxG8c8 + YDAjASc3oywL+/v76LhH0/o7fa6tFAJ2H4yEzVoLbaUQ8v52ISbzpL9JIVy/krQ1fk2NQnAGUwioZKfl + Vwh38f+xkYGjHJqAuXgjDhhc3zT+uqI5HVylzCSopL5u/GFEGMxIwKnDKMtcXaLPnm+vFQsUl0xfoheX + VwrFsjOYQwIqmb5El+qd0fNPYQPq0ctpvAf73KrBaOtm239iMW3wwec/+vgf/xPuXt3gatI32xoN9pkF + gx07H37n/hrsDuoJuQZf/WOUXFsphLb1qT6dZPzyAoXgbmYUAibzfN/4pmnIxyihrf09P8lud2RWgiQw + mEJAJaOu/5GcW8PHaCiFgCS4+VEIqEQ/Ruk1ZmNxYzaToJJ20/igJ1Sy//ZH+299SD3hBj5GybWVQrin + K9gZTCGgkquv4H6ttlUxHmPf9gpmJMRLtM+NGDxOsrNNIUSDfe6vwXmVzK7BjxaXugdvUwi3bbA7Xgwy + jkaDKYQwg09OTuCQUttMkIJCcJOhEHB7ZyQkzRRtpRBgGPZZFAIm87PvP/6Tjw7P+gmHJmAHx0jIqwRt + 3RlmvhxspwOzEmcwheDOM3dwqFLp9E+CeoJKWm1jmuZ0Go1GtVqlEFBAq75BIeRVYiYZ//oorb5kebUc + dLaOs0xRLuauYPxoQSFgMjdyiW5OvXPvK6zgP/3W7h+86vbqX/4i1vpXWcHGhSpvBZs/a6GS4orx9j+z + klKphGIolOlLdGG1dAMGx3vw3V6iUUY0OEM02OfuDV5cWu70jymEaDAjIdfgg4MDXL6Vam0TKSgENxkK + AeOMJrSb49ew3MEhwbWVQsBkng6aFJfU2ztBlaCtvX6mGLCV7L6hEndwaAIq2UnGj3eU1s4RKnGHG0EB + rw83oqCSRnP8oMkDG1JGQq1WY5QFlTTWKxSC2ROU4RnhWNje3sYdXlkpjvdpFIJrK4WAzRujCeuVxqvz + T3/j2ffQVg4Jrq0UAiZzupXJA8q1dlAlaGsr9ZM0a503VDL87u81Hz/j0ARU0tkY73qUjfYAley9+qx3 + /i038qzV+nx/9FfvPM+rpFwdv0ztgTsOIwE24MJGIaCS8mqBQjB74gymEO76Eu3aSiFgMtOX6OJ6K6gS + tHVGLtEvPxgVrKvr/N+D39DWGzd4sHXy4y/+BmXcvcFmT0A0OMM1DV5aXCqtVbut4YM2ePpxYaPVQQoK + wU2GQgh6XOjaSiFgMvq4sNFMusPT/tmroEpg8N0/Lrx6T8BNPS5kJDiDKYQZXcH13jFqcAeHhLxKZuce + fC8v0a/Szp0Z7LjtTdZquUohPESDP93dwde7g0PC/TUYP5xQCPfO4Orycqu4hjK+usHVleWdSuW3B/1o + sMcsGIwC3GEbfMVNFr7426MhslALt7HJciS94XQlwLWVQgjdZNWtP22HSuZ2k1VpbuOL3cGhS/DF83cP + no8V7HAGUyhq8NLyGravzcHTh2DwSs5nVXoGFzfau299evjrX8yDwQ5zF/1gDd7o7KEGd3BIiAb73DuD + Hff4En1+fo47vLKZpEhBcQm++Nt7I2ShFrChYCSk7fEHJ1AIzmAKAZN5cZBSXNLeHk1XAlxbKQQYPNj3 + k/R7e2Yl2No0Jp8J7oFK9notiku6o7OgSsyegDT1ywPuwzspBFTSaRkVmpU4gymEuIJ9UMncbrIc0eBo + cIaHYHBxY/xWYgohGuxzTw0Gpjd3afBapfHdn/0CR5jBc/ZK1uuDQzf0Sha4/m9cgmu/koX/Nt5kUQnO + YAph3lZwM608Wny0IOvh6isYNbhjNlfwa8yeOIMplHiJfs33n7V/+M1eNNhnbgx2RIN9rmkwfP3GcPxD + fTTY42YMzttkuYND4ZuspDl+NzLFhJPP/vDjf/ovuIuDQxMwDXc87vsfQjA7jwvBbGyyxpg9cQZTCLkr + eGllbWn5y18DxBcHrWDgna2LhcLSWrH7/ifmJdpMElewuYLXaw1GgjOYQrmlSzTI60g02CPUYDN5NNgn + GpwhGnyXBu8lpaNO+WYMfvbsGf5BSdIe2kohPN7aem84oBDSNGWUpdvtMsoCgxkJZpJ098CsBLj5eMDg + 0aH/TYc7hzCYQkiSBLsbCgFtPdxpUwh500Elrw8OBfYEOzJGl/zyz17+30/fRSXdtlGhmdxsCAhYwYs5 + f142ruAfnRy/nbQ4NOGaK9hxMyv4gRjsDg5NeIPBm5Wr/u52XiXRYJ/bNrixnqyXMz9d5BkcOp05MRg8 + kEv0vBk8/aftNjebw6MnFAK+HtsBCgH3fEZZcOowEpzBFIKZJN3Zh8EUgmsrheA2WRSXDLbtP23XarXc + 27I8QqdjVhKUxG2yKAQYvJVctUJnMIVgrGBgnmhf1wp2B4cmuLZSCPO3gtdu4xINZsrgeu94vT3k0IQH + YnBeEnMcZfz8ww/++v13P9ruccgx+wZTCNFgRgLK+OJw/3yz0SpmPer1esjugToYCWhHsVikEKrVKqMs + G5M/b+DhDKYQzCSlyVvdKATXVgoBBjc7FYpLNjfGz7UohNXV1UKhQCGETsesJCgJuorFQyHkJTHH//U3 + P8SdnEIYfxgpvsAjSRJGAlzHfCgE7FYYZcHegZHgDKYQzCTNrfGbVSkE11YKAQbvDP3Kt9PxZ3RQCO5Z + IYUQOh2zkqAk2AoxypKXxBxHGYN2Ao+oL4mXaJ/Q6ZiVBCW5qUv0SZKMP/nMIxrsETqd2TH4eWf8+zLU + r4kGe4ROZ3YMfm8rxX0HNnHIEQ32CJ3OTBmMf/I/jvvi4mL8S2hZUuuX4LAXwOaLQuh0OoyymEmcwRSC + maS9Pf7dXArBtZVCgMHDqV9RxEmNk5hCyPvtwrzpmEnyKgnqCTZNKJJCyEtijqOMT/b3kMdLNf8rGIzf + ezbFXK5geASDOeSIBnuETmemDEaAVZuZVzTYI3Q6M2JwuVRanCQpl8sZm74Wg93BoQlmkmmDk2Lx8eUz + HA5N6A1qe6fNh2zw6z+rs7y8nPku048LAVxnJGAyQY8Lu13/yR1wBrc6aTNJODTBTJLu+o8Lf+f4EA11 + B4cmwFp3TD8uBGYl2NoEPS7Mm45XiSMvidnYvMeFeUnMcey8GGWZ6Uv0aqVuXqILhQLOUwohrmCDWTYY + mN5EgxkJ0WCfmzL43bRDIQQluV2DR6PR6hSom5GAFKiPQsAPXoyymEmcwRRCUBJsFAGFAIPTbSOPmQRt + KpVKFELodNAWCiEoCboKjymEvCTmOE5iM8nC7u4uFoQHfpZiJOCUR1MoBKRmlAV1MBIwQxhMIQQlwUwA + xQSk9eA/TDCTOGMohKBKcIqgLRRCUBKcrLggUQh5Scxx0xowV5fooCQ3conGKYK2UAhBSdDVeA/OEA1m + JESDfR6Kwf1+f3ypzmLeKmb5HuwISjJn9+BqtWomWdjb23P9UmADIwEdQWoKAUUzymImcQZTCHlJms0m + IwEdwalGIQQlQQbYQyEEJUFb0RYKIagnWNZBScxx0xoQL9E+QdOJ92CfaDAjYd4Mrnb8PyoP8pJEg6cx + x3MNnv4YJdCxPu2nNnmbC4XQDvnIINw/4DGFkJckTVNGgntOQiEEJUEZKIZCCJoOkqAtFEJQEnQ1KIk5 + 3mr5H0LluOsVjEWDpUMh5CUZlzhFXMGMhNwVfHJyMpji9PSUkTAajQ4PDymE4+NjRlnykhwcHFAIQUmw + 89/f36cQgpIgA/JQCEFJMBfMiEIISoKuDodDCiEviTl+dHRkJBkM/h8boFPhTFWi6AAAAABJRU5ErkJg + gg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vwAADr8BOAVTJAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAAADQRSURBVHhe7Z1n + WFTZuufn65xzZ+7MfW6aO3PD3Gfuc+/t00E7ne4+nU93e+w2kSXnJDmIJMmCERVElCAgIAgGggEk5yiK + EgREkJyxtbXPt//stcsqqqi3qF1FQWG3H36P3YLUXmv9WO+71l7hvzx58gSveY22eC3ga7TKawFfo1Ve + C/garfJawGUsLC5iaHwSPUMjaOntx/nKBlQUZ+FhwTF0nXVG53Fj3I7cgtvh3yCpKB8R9d08F+8/wv2u + Njy7ew3P7hThaXc55iZGMDw+i7n5RfKzXvMrF3Bubh6D/UOoLGlAbnoRfN2O4Jvwk3jT5wB+5x2FNzj+ + 0ysS3g5/Qo3pf5XDJ/E4dAtbJFzOjsafk3ZIKIkLhE5kJZzjGxBwrhUn0mswcOUyJu50YPbxY/KZfm38 + qgRc5Hq3x6MDqGq6jJiYcNjp+UP/qz3Q+dxJxBdO+J17BC+dNM5OuwQJeC0rXEbAzGPR2BleIcHfMwHV + u7ajWncnavR1cHt/EBamp9HRfw2DY5yU85Pkc/+S+VUI2N3fjoKyswiNN4Jj6IewC34Xlnu+XhJPivcc + 9ssJaLbHVJCA5ZlBMgIeO5IgI+Axx3CRgC9p2+uDiZkhJJcZI6XcFOmV1ii9HYve4TrMzE2QZfml8YsV + kPV20+Nj/H+n5ofy0kljG/ABdL90lBPwD6b75ATc7uqIatPfKBWwKcNXRkC36DwZAS+a2skI2J97AXcf + lvACLie90galHbHoetCGmak5ufL9UvjFCTjJ5VZNl/KRZGWBNGdHPOFEvNfbBMcQUc8njeF2MzkBv9L3 + kRPwK3dPQQL2pDlJ5HuRtAumkdcl8umHluC6obFEvhouDI/fbkdl5xlSQDEH98cidm8+irMa8XhwgvvF + osv9qvKLEHBxYQH97W3ICwxA9OefYv87b/FE/eFjTshhzM5NIzB2l5yApqa75ATc8r2HnICfePihyvS3 + SgWcSDWXCDhzxghGkSUSAc2DrqJSZ6dEwDrT3ZgdfYyL9T6keIwzhTYId0xHmN15ngN7snHhVAW6Owax + sPDLGFm/0gLOz87iblkZkm2sEfb+uxLxpGnMu8h/b3bRETkBLV3k88Bt37riDU9ZAT/0CMAts79UKuCT + ZH2JgA9PW0MnvFwioIfvOYl8jLZ9vhifHkRKmQkpH+N4QoBEPmnCHTKRHH0d99ofYp7r4ZfXy6vEKykg + E6+9uAjx+roI2fwOKZ6YVDtbPgx397XJhWFbf/k8cNcXznhz2Uh4k+d+FFv8zYoC6hc24zkXdsUCdp5y + ksjHiHI5JCPgwMVcdD4sJcXjuWWCKK8zpIBiPEIL4FNxF52jU1gk6ulV4JUSkIXarpoanDI0QMimt0nh + lsPC8MTQEObmZ8gwbLjNXEZAxruOITICvukVjkuW/7CigGYFtfgpWVci4K2T+2QETLPykMhXo7cL41zK + UNmZSMvHkXDRGWH2GaR4jBCuF9TPqMEPlxqhe7UZR5t6MDg1S9bbRuaVEfBRZycy3d0Q9sF7pGgr0ZCb + y/+MC8VH5QQ0IfLAT8z8ZQRk5Fr+44oC2l0pw4tkHYmAmbFLc4A6YWUoMjKVCCjJ/+q8SPkYRw9FkuKJ + cQ0r4OWTZjf3HAXdQ69UWN7wAs5MTuLG8VhEfPQhKZcQUmxt+J/V098Oh5APZASk8sAvDXzlBEyx/o8V + BfS4cg0/J+2UCHjiSLxEQJP9xSjX1ZUI2O7vh7Hph/zcHyVf0k1zROw5R4rHCHHMgm5mrZyAjO2XG+FX + 0cmF5VdjUnvjCsj9FrNwe2LndlIqVYj65CM+DM/PzyHouK6MgLb+H8rlgVt+kB8JH7T7aEUB/S9dkcjH + 8I7JkQjosC+HE2+HRMCBvFzcG7xFyseIT/MmxRPjElFIyidN+oUTeNaQwdXjAl2/G4QNKeDUxASuRIQr + HNmqDJcvVmek8z8791qsjIAMwx8sZATc9h0bCcsORPwcvltRwND8XIl8rCc0ibwhEXC/+wmJfHz+19aK + yruK87+DwbGkeIz9TlnQuVBHSifGJfcqfkrcip8T/4TnhQF4MjksV8cbhQ0nYHf/MHa7HYXvBx/TMqlJ + wm5D/uc/eHgHDvvflxFweR6480v5kbCL044VBTyQlykRcP6MAXZLzQGetA+WCCjO/3LrPEj5zhTYINxB + 8eBjT1QRKZ2YXfl16E22xM+nv5PwIlUPPw60yNX1RmBDCVhc0YaPdofhHZ0gfPX9HgRt3kTKpA7h3OBl + 5MEDLCzMY/8JfRkBqTxwk3OojIA2e4xWFPD4xRSJgI8SLWXmAK/utpQI2B7oj7GpAYX53/FTgaR4jGDn + bOzKWbn3yzgfIyOfRMLknXjWyELyxhqgbAgBZ2bnceDMVbxvEMLLJ8boKwNSJnWpSE7iPy/vRpyMgLb7 + 5PPAj80DZATUdbFdUcDknFMSAaXnAA1DbqBE30AiIMv/7j8qJ+Xj5/68Fc/9OR68RkonxiP3Ehd6/0QK + yMN97aeKk3gyNy3XBtpC6wKOjE3CM/q8jHhi3t0VANePviRlUod4Az2+B+h/dE8uDBssywO/NNgrke8N + ryh86+6Fmxb/ghLzf8E1y7c43ob3iQgYZefwJGeEY+7MNrzgBKyI85UIaB14CVU6ogGIOP+ruJtACpiQ + swdh9rR8wXuysTOnnhSPoZNfi/4kM1o8KX4qCt5QAxOtCtg3OAJdLkGn5BPzyXYvBLyrmcEIG9QMd3dj + kWuA0DgjGQFNTHdC9wtnGP3RA1Y/BMLB5DDs3M7C2zUNIXsyEbXnAv8uVgT77wtw32cg9TPegz33J8M1 + 5GNYhhjCNMQVLv4+yDPdgjK9bag1McTM6DAu1LqSAh6JOUDKx7A7eoMUT0xuRgQpnDTPc53wZHoMU9Oz + yLhajbl57YuoNQHZYON7xyOkdMvZ9p0VJ5CwNx/KKEs8zX/+ldLTvDROQZ/D088E+1xDEeaQzom2JJgy + ZAVcGYegd3HsuAW67vXAd58dYs5a4HTx0nvgpJtmiHBOI+ULcr2AHbmKez+fnIt4fnqF0MvxItsGT6ZG + +EUM+0/mYZNuMELjL3ESzsu1zXqiFQF7OPm2OgiTj7FJJxC2n31PCqUqcXo6/FrBoeGHCPM8zgmXRcol + BFUEZJy/Go3iS+WSMK/3lROc7O0QedISsad9SPkY1sdLSPEY+vnVeJRkTEon5kXyLn4UzPa7nMoqwWa9 + YFG9chIGn7iI6RntrTdcdwGZfEJ7Pmne3+kH3w8+IqUSSujvN+GI1R8xMT7EPwtb2kSJJRTVBHwPjbdv + 4kBAgkyuuSTjHtjvCMM+80QZ+QLcc7Ajr4GUb9ulBhSkBZPSiWHyPe2t4cube60e7+rtl6tb070JfC4u + 3U7rxboK2NU3hK1qyCfm663Oqk/NbHobUds/wsmIbUi9boG0Sht0D4kapLWmhxRLKKoI6Br5GR4NPYTV + zr2kgGJ0P3eG6Za98DGNQ6hdBqxOKu79Ai9krRx6E7fgWUsOX9ba1i58ahpJ1ivDwDMOI+NTMu21Hqyb + gLx8KoRdRez+Uo8WbRkh776NaIM/IDHJAGnlVpx41hJKO47zzzQ5PoMj3nmkXEJQRcCIBFPcu9PD93SU + eBS7t3Cj6cN5+CFfvgc0yq/AyFkjWjwGJ99PVfH8qL/9Xj8+M48i61MaNhsxO7e+OeG6CNj/aFStsEux + eVcA3H7/BSkdI2Tz24gx+hRnM42QVrEknTRZNc6YmRvnny1nFWFYFQEzrkThmlT+JxhuZL7LJBTbE5fm + ALdzofdG2j5avJf8VMH9knGjfRZalc00iNmkG8TnhPPrODpecwHZkH+3zymywOryBzY1s3nZ1MymtxC1 + 7SOcPqOvUDxpuoaq+Odrq1U/DAsX8D00dZQgat8pWjIhfLkHOzmRtmVXI/RC+oqh93muM57Mz2BsYhoW + /olkHSqCScheCrCB2vK2XAvWVEDWne89ks2NYunCroYd31pI5Av7aDPiorbjXJlsqF2Jko5Y/hn5MOyl + XhgWKqBb5Od8/me5w5eWSxW+90ZJiBleEOLx8uU48NMtbI7PNTKdrDtlsNHxuXP5cu25FqypgJcvFWAz + 9xtFFVIT2H26lQu3nyH5iikp2UrIhOEE9cKwUAEjT5vhXke37Cb4VaD3hRMS7UzxJG5ZL5i8Ez+OD/DT + LXGZN/nejKq3lWBTXgZfGyHsg/dxr7JSrk01zZoJ+ONQJ56d3YGEvTZ4Xy+QLOxqeM8gEL4n9sgNMFTh + /qMK/lnbantJwZQhVMC0y5G4drmClGk1eOy0xdDhbSL5knbgaU81X55zlyslc32q8O4uf5n51tgfvsf4 + o0cy7app1kbA6VE8z7bjK4aFivIII3y1ex9ZaHX4wsofMRccSalUoeT2Mf55p7gwfNjzIinZSggVsPnO + LUT6xZMSrRaLbx3QGqaLp/dL+bKw6ZZ39eXn+pTx0Q4f8r37eTcXLKzh2xLNC8iNvH4qOyobGjgGj22H + kZU3WXhV2OHhh9M3bEmhVCW9yhaTs6LFmuqMhoUI6BbF8r9BWG7XQP5HoMuF47gDqXy9s+mWLyyUT7cs + 58vvXeD3Pr3lgW3+unU6Qb6dNYTGBXzaU4Wfz3wvJyBjIX4rglyc1MoL2UDGNNgbKWU2pEzq0t5fyD93 + uxphWIiAkQlc/nenB/pfu5ACrZaDwWcwOzuHxxNT+KPjIbLuVmLHt5YI3LyZlE8M24/TXVcn19aaQKMC + /siNvl5kWpHySXMhyFylvJAl03YHPHFOwPSKqhS1RvLPPjUxg0MeqoVhIQKeuxS+Jvkfw808DFOT05ic + mYV1QgbecI/AO0bCwu/mXYEw+VKXE0zYIo94fT0szGn+nbHmBORGXj+Vx5LCUbTG6OE7471k5UjD5HM8 + 6EHKowlYGJ6aHeHLoGoYFiJgy90yROyNIwVaDQ6GQRjoG8LcwgKcky4srV3kJNxkLLuwdznsvbrjJ9+Q + oimCD8UvVxJpEo0J+OPgbfzMNsIQsili7MQPsLHzICuJweSzj147+cSIw/Dt+gekaIpQJiDL/4a4/M9i + uw8pkbqYbPVEb9cAf1BR9KUbEvkkEnpEKpTw020e8P7wD6RkymCb/Ie7u+TafjVoRsD5GX6xIyWZMp4l + bEG0pz3eJfJCmwhPUhhNU9QawZdjamJWpTCsTED2/vd+Z69G8z+jb934E12ZfMmlNXjTR3SKKyXh8nC8 + 5U/28m+QVCTdxVmjo2KNCPi0o4CTaYucXKpQFGqMTwwCJJWlv9cXqeW0MJomo8qOGw2LjszNPV1Jykah + TMCU/FCN5n9M5OtXRZPDhc0d/FHClHxi3nDjwrFhMD+5rP+1EYKVnKMjhIAvN6Gx4ZpM+6+G1Qs4Ny1o + 4CGE3iM7sdPMB985+iGpVLOjXWW09V3ly9PRIDwMKxOw9W65xvI/tl3g9NFM/h1tc08/Pgk+Skq3nDdd + I2D55U5SJlUI/P3bcLfYDPug9xASZ4D5ec2cQ7NqAZ81ppMyqcvY6W1IKl5f+RiFLSwML3KjylnBk9Ir + Ccjyv+HhRxqZ/2PyHQ1LxvzcPO4NDuPT/cdI2RTxrZkTgjep1/sFv/cWvPU3wT5gqWz2+99HTYsob14t + qxNwcpjfb0qJpA4vEregrNCYFGSt4cPwjGhS+mJiFSncclYSMPyUMbpY/vfV6vO/vQ4xmJudw+jUNPSP + JpOSKcN0G5tyoSUj2fQW9n7/Dhx96fIFn9DD3NyMvBMqsioBn9WeJUVSl/s5uqQc60Vb3xW+XHea+kjh + lrOSgKn5YSjOV2P93zL2mITg8fCoaK7vVAYplxDecg+D2+fCtrj6f/0O9rjS5RJjv/89VDZdlnNCVdQX + kM/9ZI+AWA0zKT/gfIX6Cws0QWFLOBbFYVjAEq2VBGzrrES470lSKqE4GAbiYd8jfnVLYNZVUixV+MBp + HwLfU/zWI/CTt+FmK8rzqDItJ/iELmZX2QuqLeDTjkJSJHVgofdmsQkpxXqSUWXPX5vAynfxjPIwrEhA + TeR/u79zR2NNOy9f/PUKhdMtqqKjby4nXtAHb8HLmBMvUL4sK8F6QbbRarkbqqCegAtz/D5TSiZ16M3W + IYXQBq0qhGFFAobF736Z/6m3/o/N9ZUUiZZWsavClE23qAILxR6ffsaLF/zuW/DduQmOfvJlEErsuT2r + Wj2tloBTg/dEx38RMqnKk7NbcaHMkpRBGxS2hPFheJoLw8o2LCkSkL3/LcorI+VSBhvxZiWLpoTq7vfi + nb3RpEir4XMbD+z9bhOcPeWfXVWcwz7C4HCPnCNCUUvAxNZeOOUWojgtANNndEixhNKWp0+KoC3OVztw + YVi0CDNPSRhWJKC6+R+TLzYiBQsLC7jdPyh4rk8ddPx3kM+uDjnFonWV6qCygBNz8zAoaJbs0DLIr8KR + rER0JtvimYq94mLSVmRqeeBBIR4N323uJ8UTQwnI9n8MPx5Ua/9HuG8c5mbn+aVVX4WdIMXRFO/5+ME2 + WPa4YnXxOPAVpqZF2xtURWUBb/WPSOSThu3Sd7pYyO/UZ73iCwGv5hovG5ICaBt+NLy4gOmpWZzwv0LK + x6AEZIcedd97AL0vVcv/nI33Y/TxONf7zsBqFdMtqrArYKfc86uCbeD7sHL7AsZGBii7LtrsryoqCxhZ + 10UKKI1efjUOZCfjToq9wl7xx7N/QuYq9nOsJeerHTExPciXt+h8AykfgxIw7XIECi/eIiVThL1+APp7 + BzG/sAiX5BxSlrXgXZ99XC8oe0ydUoLeg7XXpzAx0YH+dzaSMsQEqrdUSyUBx7nwYFTYQkpHsY3DkesV + c9MjMHlWV6ZXvJurRzb+RkH8brj37hCiXXIEC9jaWaHS+1/Db9zQUn+Hv2jm9I1KUpS1RC/gB7kyyMFJ + Z+P7MUwttsNgqxV/re3ycpj/4I2pCdUPvlRJwIqBUVI0IbADFCOyU9Ga4oSnid8jv5Sd00I3/kZAHIZn + Z+ZxMoAOw8sFZOe/DD9+COtdfnINRGHwR1fcLBBtkM+satTodItQPvZ1556dnni23fd7mNls5S/zYXtP + qDKIYV+vLW+Wc0YZKgmY2N5HyqUq7lfPk42+kcjkwjC7y42VuzizkRAwmxPQCHb7l67/CjlpgJ57fVz+ + 50w2kjS63PcUcKGa/fymnn685bv+8jHe8AqHWdDnS9IFvA8Lx+9gtMsYOsR1titxJjZbxhchCBaQLYDc + U9pBCqUqYSUHyUbfaLT3F/Bl7+J+8SJNDiB8uzPCvtJB6Cd/RMgHH8PC+Rh0wgugF5YJw7DjSCm8gvrL + N+DwtR10iQaS5hg/3bKIOwOP8FlILCnHevGtnwV/UPtufUPofu1APq8Q7A0CVL7FU7CAD7kR4Y7LTaRQ + qrDjch2SKla/p3c9KGgOx8LiPH/JTeTHv5d7hWXuFCc5C5rR2jOGrviT/HnQV3foIOw7cxgt70W4UBUT + dFqyk+3r8JOkFOvJ226h/CFIMs+pJt1cBKD8UYRgAcsUTL+oikPRBbKxNxJnS2zhddIV39j7o6blPr/h + 6pyD3YoCGh+sxvjkDFrcXSUn4jNu7NiFwG8t+eM0WAO5W4ZjemoGEzOzsEk4TwqhDbZ+7yEnkzqwGQDK + H0UIFjC1Y4AUSlXCbsaQjb4ROFdhA/9EF3xiurQ1ICBWdNFha2HBigJ6nWnCzMOHqNZdupRamtQfjOC+ + OxCDA8OYmZuH45lsUgRt8ZnJPlIoVUk8liXnzkoIEnCBy/88y+6QQqnC9sv1OFXuTja+tjlz0xY63r4S + 8cR8YxODyelZTI6M8HfOKRIw9WY3hm5cJ+Vj1JsZY3qA7WRbRGTeNVICbcIu5tFEGHazCCMdUoQgAWe5 + xNLmejsplSrsvnqTbHxtE19kjz/a0WfXbNYNRkVjJx+G052dFArY2s3lf6fiSPlqjfQxUlvL12Xp7TK8 + s1czS6s0zfZvXEmpVMF8mw+fYix3SBGCBOwZnyaFUhXX4jRSAG2ScN0OX9n4k/KJ8Ttyga+HtqJCUsDd + MdUY4/M/F1K+4TJRXjQ4dgep5WZwS3XFmz60BNrkm13epFRCseDks9PzR29Xv4w/KyFIwI6RSVIoVdlo + +R87Z2aLkx8pnTR/tI7BBPdbPTU6iqhPP5ET0PtsM5f/DaD65Y1IErj/78vM4OtwZPIBsmr2SO4FcU52 + wxuEBNrkD6b+pFjLMfmTJy9adGACjkelovpWE9qbOjHDpSrzKu4ZFiSgJgYgbLFCbJkfKYK2cDroTgq3 + HBaGyxvu8mE4w81FTsC0kh48Wp7/cfLdPx6LxYUFfs9xdo2LRD7G2Vsm2Botex+dtnnPfr+saFs9YaPj + hxCv4zgWnsy/tWnl6mFyYhpzxGHms5x8j8Ym+M1Ty7+mCEECJrX3k1Kpws7LNUiusCdF0AbHLjtgsx4t + HIXvYdEsf/u1YjkBW7pH0X36lIyAdyLCsMg1yNzCDG60H5KRT8zxYgts3hdOyrCefBhwGJ/tj4XdqQwc + Dk3CjauVaKnvwMT4FGaJS2yYaMPjk2jpHcDlhjYcuVrCTyl9FxWPTX4xsE8UPhJWKiB7SR5d301KpQoG + V26RImgL40DVzir82joa45PTmB4fw4GXYZgJaBhdhbGJWbRwPaNYvmZXZ8yNjWF+YRY32w+T8omxTpC/ + nX0tYOGeifYpJ5rt6Ux4peXjEidP5d1ujHE91vQsLRqbLGeiFTTdxsHLN2HH/Vs2ef7uvoMK96n86cAp + uZ+lCKUCznNhx6PsDnYXtvDsuqLe2xDbwjxSBG0QV2ivUu/HYEfeltZ18GE4y9NDIiCf/w0s5X9Nzg6Y + 5Y+1XUTNvRRSOmlOXjfH276yl2OvFiYH27zOeiXPc3l8L1XWcZ8PjVOEaIvzXO42MYzpvnY0NFbj4JWb + cDqbzS+Kfd//EH7nrdqo/ZuIOMH7RASF4Jn5BUzNcXB/PpiYQe3gGKofisjqHER4bRfCau8jlMP6ehsM + OVF5Clokr+820gjY7ZgbKZky9r4Mw/erKvkbmJiA6aU9GLp5g5evdrcBpnq6ue9h73hv8CNeSrrl6B/z + JRtSGUy03wcegfHxVP6ItvSKetxsu8vnYWwf8fJ25EWbHMHUgzaM1F9C38UI3D2ijxa/91Bv93eotfxL + eDhtIz9LFd7ghO0dFh15pwxBAqrC3MIiJjlZJ3jmcXd0il/G1fKom3uoOjT25PBnMzNucuTUefAn1otJ + r1zbYznYIZdb9yg/l5Dia6toLtxOYW56Goe/+ZoXsOk+l/8lJqDWUE8y3cIOPxcqH8Mv05FsSDGb/Q7y + 4ZMX7ewFZFQ24HrrHQyOjWN8Wn7ObXF+DgvT45xo7RhtLEBfTgg6Y3ej2ecd1Dv8L9Ra/De5y7fFRNt9 + TD6DqrDza5Y/F4XyHJDrSge6H6O/axjjI1OY58QSs5rteGJYnjQzP8HlG5OYmZvgKrUD3UPV6Bmu5Rvy + 1p04Lok/zMl6BNe5ZD671oVfKpVZ7cT/ye5+o0RTRFKpLX/CPiWYMlgYvllzm3/u/OAg2LjGY5Tlf+4u + eMQNTtjfj0718c9FiaaIE9fM+XnBTXtj8EHAIew+ngJHLgRmVNajqLkDD0fH+TxNut4YvGgzk5ju78BY + yzX05Ybh3klztPhuQoPj/0GN+V+Qkq3Eaes3SaFUpfXBgNzzUijPAbmwe8L/Mn9zY7TLBcTuvcRz3O8S + Ug/d4JesM65lN6Kj8YFIVo7BB6P81sYF7t+zn8H+ZPkT9RmqMLfAJcxz47ys03Nj6Btp5kXtGqrkw97N + 20dxrS2Gk/UgilqjeFHZTjcGO//lZIE9KZdQxKPh+1VVCAtP5ef/uuJO8GUbmx6Qm25ZTkqZCdcLW/A9 + P1v0yvLEzsFbXI/Whv6RMYxyA53lZV5cmMfi3DRmBrsw3l6CgatHcf+UDVr2bkaD8z+jxuy3pEzqkG35 + L6RQqpJf3ypXDgphAu4TCagqhzxyeXkZBb5H0BHkjwepKehNSUJfRjoGC65iqus+Ju/dw/SDB/zIkU1d + 8CxoQthFvmednuV+GThZx6YGUNtRgcScW4g7fwPOYedg7JvA36W20yUW7xuE4D39/fw1B4ru2WBheHSc + iwQzM2iobsHs8DAnxxzfk19pCpYRjYXh81UOKGgOxa2Ok/wvyIPHDfyRwOz75Z53kYsqXJ42M9SN8Y5y + DFw5jK4zTmgL+gMaXf6Vz9EoaTTJVYu/x5teqx8UnSwuly8fgXIBuVAby/V2lGCqcNHcF/Vckr4ixoZo + dXdFq5sL2n28cDcqnBf1QVoqBnKy+WR/ureXk7aL6w0eYmGWy3+YpGKI5xcKSyeYWL0PH+P+g0doutOL + i9cbcDa3DPFZJYhJKoB14Fn+WlN2F4f0v2VrBllPxgQsvxOP2/1FnGiN/AQ067Glv1cM+zwWIYb6x9Be + 14uG8yloC/4UTW7/hlpzxTnaWlNi9j/xltfq5yZjLt8gy70cpQKODk8i3CGTlEoVLpt70tKtgiYbS7R7 + e6LN0x23/f1w/+hh9GdnoT/zPB5eyscIN1qd7u8T9a6PH4t6VaKMq2V+YYaH+hqDifZ4cBwt1d24dakV + WSfLcGp/AWLcciT1k2TtQAqx3lSb/gZvaKAHDM0tIutiOUoFfNQ3KiOSuhSYuZISrSfNDnboj/bgb5N8 + XrAPz5rOc2TiWXMWnnaX48fxfv6utR/HH+LJrOo3iM9Mz+Hxowncax1ARUE7Mk/cQmJYEb9/hKoTaU5Z + e5NCaANNCBiSoyEBB3pGyApTlSKzPaQU602P+y6Z/cmKYFfdP7/ogud5HPlueFZxAs9aLvD8OCa77Hxx + YREF6XX8WTJU2YVwytqHlEEbvO4B15BuN2ECKoKJye7CY3XD1kmyxbrieop0yiLLLoTT1h6kDNpAEwJG + 5V+X8UgRSgVkuQtVYapyxdyDFGK9ueOgR4ollOeFAZK6qXo4ipI+0en6jMqi22TZhZBqbUXKsN5Umf4W + v9tIArLVEIe9LpKVpgp55j6kEOtNk5k+XiTQcilnC57eEx3IyBZpxDR0w6y4FYNToikVNmOQHH2dLL8y + 8iy/IoVYb4rN/1ojo2B2gY60R4pQKiCbBzyu5jygNBcs9pFCrDcNJgZYPKbe2YYvUnQk4Xd8bh6mnHzs + PTc7L4edZMr+nkUMdXLBEvN/IoVYb3It/5FfOUNJpQqnrovuYlaGIAHFb0JWQ6plBCmENhgJ3k4Kpozn + V/0k9cLCr3ilD0M6FDeW30e4vfCpq6O2MVzja+5txmpItf53LgSvvgesuCPsSq916wFPWx8iZdAG6uaB + z1pFWzTF4VdaQBaKH70MxQvzi/xcH1UPFBlWhqQM2oDlgKVm/wMXuZ7wuO1mBNp/DRennTBwscJ3bq74 + zN0Hmz33k9JJo7HFCOyoBTZpSlWcKhy1TSBl0AYNxgZYOKJiGE7azs8Rsjrhw2+RKPxK41V+l18/yb5n + ZGhSUCiOtEtGufnfkTJoBbPf0H//kkqzv+DShb/CNS5XTLf+Nxyw+wS+Dltg42yI7a6O+NrdEx95+ON2 + 30MZjxShVEBGUWYDWXmqEGV3jmt8QzkZtMV9F9WOFn6e58q/q2X1sTz8imHH0WXeXar4lqoupW+R0qxN + yYZ+NfkN/yalwvrvMD0mum1AGYIEZCtdqMpThQi7dJSbWJIyaAWuF5yJoW92p3jWksPXhbItCrpXm9H7 + 8pw8NkGdHVdO1gfjkG0s16P8FdGQWkRJDyiEJo//5Mov7N28IAFrb94lK1BVNspktJh2G338FCfglk8W + fsdEOQ0LvyZE+JWGnSLBFuay7x97PIVjvvlydRFhl4pii7fIBnzVYat3pP1ZCUECPnygmddx6ZahpAja + 5L6rrtJ5wed5bpLwy7YhUNJJw0Jxxp2lUNx1+yEiHZfekoTbpSHXagvZeNpl9b0foyfVQ1J2ZQgScJRL + qFfzmklMnM1xUgJt88BbZ0UJnzaLTkZQZYegHheKu8ZehuLFJyhIr+frIILLhbOttpENp3U0EH4ZfTmh + Mv6shCAB2Ug4LvCKnFBCCHfIQKRrCg6FHUF84l7UmdESaJsurid8Hk+E46QdksUHbI+LsZLwK41LaQe/ + kYv925mpWSTsy0Ch5btko/2SmLgjbBKaIUjAJ9xvcE5CBSmYHPYZiHBJ5YQ7ihOnA3D6kgOSSk0lK4VL + fTfOSHg57TZ6mImWHZiIRr+iUwBqBpWH3+UktD7ge07270earml1salyVt8D1jv8A+anxmT9WQFhAnKU + XmpVLJzzORwMOYYTCYE4neckI9xyLsXvJht/o8DmCB947pLME7K1gqz8TKIDamzQ181vQlPvywbh8sj7 + p+3JhvulwLZ4SnujDMECsl1xYunCndJwMDgWx+OCkXDReUXhlpNeYEw2/IaDE7Fzjz4WBu7y5Wfhl23M + pySj2JbXiF3JdTA8XAPPM80Ynxb1ovPjQ2jy+A+y8bTL+g9AGIIFnJqcQcLpgzh1wUUl4eS4ZYxyt40b + hqVpdd3Dbzhi5a/rHcWOrAZSNgmcdDvPN0A3gRPvUA0Mo6slnL3WzQ9G2M9iWyhr1dgyuaZoaADyuEq1 + k/IFC8gmFktuH6WlUpFLcRs7DIvpObN0+098wX2RTAdroH+8BrrxtRL04mphcIwTLmZJuOUYcV+r6ni5 + YIELxd1Je8gG1Aoakq/e7u8xNyJsP7AYFQR8gtv9haRQqnLuujFqN+hoWIKxISY7ReF3Zm4BzvGNpFiq + YHu8HiMTL9cOTo2i2ftNsiHXHQ0J2B7yhYwvQlBJQLbNMEWFIydW4nqIEd3wG4RWt6Xw2/FgnO/BKKlU + JTrnjmTt4MS9GtTZ/g3ZmOtFoc2/wSfoOM7t2YJKs/9Ofo9QBq4ckfFFCCoJyChoDiGFUpWsCxt7MCId + fln+RsmkDkzk0talF/XsgCCqMdeH3yDML0jybNYRV3Hc0wrXrf6R+N6VqbX475h52Ckpl1BUFrC9r4AU + SlVSOEp9NuhgZFn4dYpbffiVxvpYHYbGRKF4cW4G7fs/Jxt1rblu9c8wPlAm93zGB8qxf18I8uw3k/+O + oi3oExlPhKKygJMzw1wYXsUoWIrs7I3ZC/Lhd140bXKbC7/sEPLljbRaIrJuS0LxZE8T6m3/lmzYtSTK + 14d8NjFG0ZXYE3IOKS7fo9x85VU7D4tOyHgiFJUFZLCTqiihVGWj9oJrFX6lYaG4uFF0GSKDnQNDNexa + UWTz/2By4Bb5bBSWkUU46mWPYut/lftZ7O3H3Ijwk/GlUUvA7qEqUih1yMrhekFjWgStwMLv3Tt8OWdm + F+AY10A2iCawOFKLewOiExjYCVjtoV/KNe5aUG36WwQERJPPpAwWsv0DYpDj8CGqzERzmXePGcn4oQpq + CchOnGJHnVFCqUNx5MYZEcuHX9kJZU2zN7mFq0/RggV2RC7rTZYLo2ku2r+P3Vx4pZ5HKEbRVXAMy8JZ + Nx08bhBd7q0OagnIqOvKIGVSh7RiE9RY0UKsNz2JCZIyJl1fm/C7nMyyB5LPHCpLRY352u2QY7mcEycO + 9RzqsC+lVeUrWqVRW8DHE90aG4wwNsQiBS78TnSITkBdi9GvIsy5UHy3f4L/XHaC190jeqQ8muCwtxP5 + DOrAokNdp7CzoBWhtoAMds4zJZOqZGUaocxyJ+oM9Wgx1gnpd7/rEX6l2ZvcykvPPnt2+MGahOJ8u3fI + aRd12cv1fnPz6vd+jFUJODR+f1W9YOp1YxSE6aFKV3S/Ro3uTtQb6ZNyrAfdCUv3WyTfWJ/wK03GrV7J + 5w9XZGg0FN+y+FvYh+eQn6sO7Jez+s7SZnx1WZWAbIGCsotYFJGdwfV6FvJ369bo7yLlWA/YgZasXJp6 + 96sqLBS3947zz8BGxexke0omVWGj1UD/SPIz1UUTvR9jlQKyXvCeSr1g6g1jFIYs9XoUtQa6pCBrSZOd + NRampvgydfRNrGv4lcY1oQmTM6JR+OzjPtFp94RUqnDJ7kuYHCgnP08dWN3U3F1978dYtYCiXlDAxPSt + l70el+tR0smgswN1RuubD947fFBSpsu1A2TFrxcJhfclawdHG6/y71kpsYRQa/p/ucGVPnLtvWERWUJ+ + nqrsS23F/CpGvtJoQEDR6zl2wQwpHgfL9YqC9DixCNkUsc4SPq4QnerOKtY/tY2s+PWC9TAt3UvL+LvO + qrd2sNbsf3PyLdXhNSsH7Am9Qn6mUMwPL43YNYFGBGS09OZzspnIyZedZoRycwG9HgE/KJGSZK1osrXC + /ISoUvsfT8P4oHbCrzQuUqF4buwRmr1UWztYa/p3qDeRr79KUzP4B6STnymEo/mdkt5ZE2hMQHbvxcU6 + L4l4rNcrDFax1yOo0Vv7Qcm9g9GSclyt0274lYatwhbvqBttKRZ8T4gi+cTUmuzGUa9j/NsM6nMV4XCy + AWNT8pcdrgaNCcjoH2nhL2fJSTZEual6vR5Fjd7aTs8Ml5byz89Wp2g7/ErDQjG7i46vX+7ZulPcSOGk + USafNKnOwTCNEjYvyBZP1Gpo4CGNRgVkl6+05p0kJVotLBzXrYGE7K4RdkMTe/4BLvzu3gDhVxq7E/V4 + LF7GPzmCZp+3SfEYtab/xMmn2gxCgbUz7MKLyc+WJlxq+Zgm0aiAjLmRETQ52pESrZo1GJh0xhyQPPsV + LY9+FRF1oUPS+ON3ylFn89eEfP/OlUe9X9Ayc0t4B2WTn82wia3H0Ljol0DTaFxAxmhTI2q53oqUaLVw + EtYa6JAVqQ7DJS8PHecSa//UVrIBtA0LxdJrB/vzoqQ2Ev0F6kw/XPWStlpjI0T5JpCf3ShOA9aANRGQ + 0Zd5npeFlGjV7MAJ5wjcMLchK1MojdYWfI/NnpcPv1xlL2+AjQLbUTc4KroOTLyMv9b0b7mQu5Usm1oY + G+KMSxhMDlRIPje9tFcyEFoL1kzAxdlZtPl6E/KsnmQbX+wMr4BR6E0kOwaijqpMAXQeiJQ870YNv9Kw + PEw8ATzd14kmW3OyXKvlor0XrCJuIjCtTXLO4VqxZgIyZoeH0OzqTEqkLleNLWEYcpMXkLErvBx+vsko + MbciK3Mlhm6ILlMRhd+NM/pVBOuhrzX1SOp36Fox32tRZVstpc7ueDyu+AJGTbGmAjKmH/SizsSIlElV + bunpwyYgTyKfNIahJTjpEoUqExOyQpfTwD3T7NAj/hkfjsxobN/vWrH7YAX2pSUis9oL49Oiwy/Z2sHO + KM1ff8FmBsbb22Taca1YcwEZI3W1qOUKRkkllCqdnQj0iCflk8Yq+CrS7f1QwyXVVOWK6Qj0lzzflQ00 + +bwcful7fB5OFu9FWqU1z432w9yoWPyWZBQtLs5kGdWh0dIMY81NkrpZa9ZFQMbjqkrUGuqRcgnhlH0Q + H24p6ZbDvs8uMB/nHPxRbUxv/Ry8cknybCzXoRpf29ieKMDBS2E4V2EjkY+RXmWL9v5CyfOPNtRrJhRz + P2PgougulPVi3QRkM/kPMtLVGhlfNHWAfmgpKdtK7OKw5HrERKcQ3DKzkFR0g+lu/sZ19lzD47MbbPRb + xYsXnR+J1Ao7GfGkOV/tgOGJl7cRcXXbk3BKViZV4eTrO5/B/yyZdltj1k9ABi9hmkoSlugbwjLoCimY + KrAcce/eFGTZeaMlKEjyTGVtQ4QE6w/L8ZwTcnHkajAnni0p3XKuNodwo1TROdTz42NodXOh5VIGlw/3 + Za6/fIz1FZDxsies0dchhZOmUmcXfH2SSKHUhfWKV6uWRpIHc++QQqwHRhzmEeVwC7iG6MgznFSyoVYI + Tb0sZIrEGWtsUDkUs8FYf1amVuRjrL+ADK6wjysrlL4tiXUKJyVaDXpRlfyol3+OmTF0J3shMTYezgeL + YRK9NAG7Vuw+UAWr8DK4+xdjv2c+olxycGDPBUS7ZiPlujMp2Uqw/dlDE/ckddubkkyKRtFgZoyBnAta + k4+hHQFfwg9MFEiYZe4M3bBbpESrwSepWTKz/6yrDH9O2sHzImkXhhMtURPvh4TYU/A7nAfLmFJeStZT + UTIpg8lmwglvy+WvroHXEOB9GeFuF3nhKOJORZGSKeNKUxDmF0S/VAvT02j38SKFk4ZNtYw1NWpVPoZW + BWSwKZrl84Q3DHbDLLiQFGi15NcsnWHyvCRaIuByfk7aiZ+SdDgprXD/tBMaT3njYGIaDJLqYZBYD/3T + dTIYnOH+nvuafloD9LOboJfbBJ/wIlI0RRzyS0XashGvUCo6EyXlYnubGy1MSfEYzfa26zbPpwytC8iY + efhQ8sakUncX3PemkfKsFv2oKi78ipL2J7MT+DnDlJRPEfnZMdAtbBGM29GbpGgrcSbXlxRMGWxqpne4 + XlKnfefTSfluB+zD7GPNr+tTlw0hIGNudASdRw7hsPMBUh5N4H2WC78vl5M/7a4gJVuJszkJpGiKcDhd + Tkq2ErExx0nBhJBb74XZedHOvoWZGbR5ey7Jxw1O2Klf4q0HG4UNIyBjYX4e+dV9XP5URQq0WvKqpcNv + DCmZIlhIjsrPJkVThHlGDSnZSkS7ZyK11J4UTAgVnUtHy03evYsGcxMu37MSLTvTcr5HsaEEFMPOZHY/ + 3URKpC4G3IBgQBx+Z1j4NSNFWwmfSwWkaIowyamXjHJV4dTZMFIuIaRzo+Ke4TpJXQ7fvIGpLmHX52uD + DSkgg51OkMIfj6GZ3pCNfsWrip/2VJKCrcQLrgd0uXKTFE0RBleaEOGeS0q2EocDk9QejDAu1ntz9Sc6 + YWGjs2EFFNPWOwbPM6vvDfMl4XdxxdGvIp4m68H2agUp2kqE+OSRkq2IywUkXfYk5VIGG4ywE2zHp5dW + UG9kNryADHYGCTutgG3QoeRSButFl8LvuFrhdzbFGKYFtaRkK7E3vJCWTAnHDx8lBVuJnDoP3H/Ebqrc + eLmeIl4JAcVMTM8jvuAe2KHhlGiK8GXh9+XK3qc9VaRgyphMMYV+YTMp2Uq4HlN9KoYR45WBc7cUL0aQ + hvV6tffPYXpO+C2VG4VXSkAxbG/E8cudMD4oTETpyeefquJJwZQxnGpFCqYMdaZixCSk7ieFE8New7G1 + gcMT92Xq51XilRRQDLtrI+7qvRVFZOGXHbfB/5v5GfycbUsKpow76W6kYMowP19LyiWEI/sTycGIWLxH + 451YfIXCLcUrLaAYtnGbHShpT+SIvsktko08TwfbSbmEUJEZRAqmDOPcekS5qj4Vw+OSjeRCVynx7PkB + BjsS71UXT8wvQkAxs3MLqO8cQXROB38FAhPw7LWlObDnaoZfRmFWJCmYMvipGA/Vp2LEnIg9hAu1bqjq + PIvHk92/GPHE/KIElIYNWIoaHqJ7UHQPx5O5afycZUPKJYTsC0dJwYQQ4ptPyrUSB91zcSaiGGUFTa/M + nJ46/GIFXM6Pow/wc6Yl/pyiSwqmjJO5yaRcQtgrcFUML114MUrzWzHYN4qFl/eH/JL51QjIw/WCPw7d + xU91KXiR54Kf043x5+SdpHDSsPfAwfl5pFxCcI0tIYWLdsnBUZ98ZBwrRVNFFx71j2L+5Un5vxZ+XQJK + szDPL8l62teAnxrS8PxaKH4+b4E/pxmRUrpevkHKJQSHxHK+dzvilYezkddwIb4CzZVd6O4YxMzUnEYP + fHzV+PUKSMH1kOxNydO+RjzruoWfmrPxong/fioOwbGaFtiXdsDkWhuMFcC+5lvZidC6LoRxRDf2oKR/ + BNXdw1zvNoYpbrT+awirqvBaQBWYXVjEBBciR2fnSSa5ry38inszdXgt4Gu0ymsBX6NVXgv4Gi3yBP8f + Dl9zmFWDBX0AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vwAADr8BOAVTJAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAAADArSURBVHhe7Z1X + XJTLmq/P7dln5pzJZ8/MCb+5mTmz9+yVXGmv5FquYFgqqIjkDJJFQJAgOSpgICpJkhKVnHNOAipZkuSM + 2bn7n6+qpSUU2F8HunV58fxWULr763qo962qt6r+y6NHj/Ce98iL9wK+R668F/A9cuW9gO+RK+8F3Ia5 + yUkMd3XiflUlWnOy0ZiehqrYWJRGhCMvMADZoVG4VtBDiS3qRUbNIHIahlDd+RCtvZPoHZnF5Owi87Xf + I+C9gByz4+Pora9DVVws0p2dEH7iOLy/+hKen38Kt48+wLkP/8TkzLe/QMmzYkuUvSqg4lMF9YBquF5v + Q3jOfWTXD6FjYAqzC8vMz/Jb4zcp4MSDB7RHy3B1QfCB/fD8bBfObSPaVrxJwK1Q5jjuV4XTUc3IaxzG + eHUVJpsasTQzzfy87zK/CQGXl5Yw2NaGsogIhKupwoMIxxCKL+IKuJaksj40GuqhWvkQatVU0OHmguGc + 25gfHmY+y7vGOy3gyoqAvsZGuH/yEVMiSZBUQBKiG2s7UXNMmQq4ltrjR9Hu5IiRwnwsTowzn+9d4J0U + cHJ6FtllLdB1isKNvDoszM4i4IfdTIkkQVIB1bjccKS0ZJN8G6lVO477IUGY5gZEK8vvVu74zgi4vLyC + 5s5+uF3JwDea3vjwiAtF3/kq7QVve3syJZIESQV0iW/D/cuXmNKxqDmqhBYrc4yVlWJ5YYH5PbxtvPUC + Liwuoay+C1oOEfj4mKtQvFW+UPPAw8kZbpRbv+2IVhwkFZDmf0b6TNm25chhNJkYYbSwAMtzs8zv5W3h + rRVwbn6RhtkjVpfw0dH10m0k4XY1DcOBP/7AFElcJBGQ5H8NtV3M/I8PjUYGeFhRjpWlt3O+8a0TcInL + gUrqOnHYIoQpGwuSC5IwnO3jzRRJXCQR8IS/aPmfSHA9Ypu9Laba2/BoZYX5vSkqb42ARKD2e4MwcLnG + 9XibQ+12kDA8NjFNR8PSDMOSCEjzvyui53+iQHrTe8EXsDg5yfwOFZG3QkCSwzmFpOLT425MwUQhPqsK + i3NzOP/THqZM4iCJgImlXP5nYsgUSVLqdbXoQOVtGDErtIBkZFtQ1Y6fDQOYUvFB2zGS9qI5fr5MmcRB + XAFJ/ldfd5eOalkCSQUuLHdyI//FyQnmd6soKKyAo+PTsA1IYo5sxYGE4ZGHU+hvbobbxx8yheKLuAKq + +lVhuLSULY6UaTDQpct8rO9YEVBIASub7uFHA3+mSJIQl1lJw/CFX35mCsUXcQV05vK/binnf9tRo3IE + fXEx3Eh5ifl9yxOFEpCMcMOSiyXK9bZD80yEVMOwuAImlPShycyEKYvMICHZ0x1LMzPM715eKIyAE9Oz + sPJJYIojLUgYHh6bxEBrq1RGw+IKWF3fLfH8n7i0WFlgbqCf2QbyQCEE7B96CGXLi0xppE1MRgUW5+cR + tO8XplQbcfv0C7h/sw8ePx6H5wEjeB40h5eyDbxUzsJF0x5abmYUTTcbqLs744RHIFQ9QqHikQBlz8JN + 8pH6wKGycqYcOwLXE/ZGX2W2gzyQu4CtXQMyyfe2QsM+nIbhXH+/zbJ9+T0VzUv5NLw1/eFrmghf8xSO + G0zcra7AyPWTbfgUhud2Q9dNHZruDpyYYTgbU4174WFsOXaADvdzNBfsHq3iUp55ZpvsJHIVsKLxLg2L + LFFkBXm/wZEJPLjTDvdPP4P7D8rwOmoPH6MoTqqtZWPxZgE3cyMvBNY67jDdYwT/vVq4eVAFVQxRZEGr + 7Sksc4OwHk6+2HIt3G5yxcKSfHNCuQmYU96KXTIabLyJqNQyLC0sItQlkymWqIgjYEVtDo79YI4j35lS + jnLo/GACP07GzENHmeJIg0ZDfSyMjWF4shPxFbqILlOnZDU6YW5BfnOFchEwp6JVZiPd7dhj6Ajz89ZI + KHXjPscKStJbmWKJCl8BTd2/REl+pVC+jRAZLX80QMyvJ1ChfJgpkjjUaaph5v49TM0NIbHKWCjfKmn1 + tpieH9nUTjvBjguYV9m2o/LtOu4MVUc7+N88ibgKA8RX6iOx2gTTcyMYGZyEn8VNplyiwFdAvyh9RFxI + Ysq3EdIrhu5XR6mSZKsltarHMF5Xi/nFKaTX222Sb5UbtVaY5ARltZks2VEBSRXLTsn3+QlnaLudRmiu + MZVuI639WVheWkakRy5TLlHgK2Bq/kXY6HsxhdsKze9PIvyAmng9IjfiHbqVSQcbOS0eTPHWQnrCucWd + Dcc7JmBDey8+U5W9fLtUnKHpchoRhUZM8Va5xSXgK1wYLs1sY8olCvwE3IXqhvx1+R8fDPcYI+HX42zR + WHDy9UVf40b8y6joCmcKx4LkhAtLO1fkuiMCDgyPY4++bKdaSFGq0ml7BGeaMIXbSAKXC5GcaPTBJPwt + xQvDfAQ08/gzivMqmHKJCskRz/6shwKlN09id/l602qYpt6bTNG2I7/Vh+s1d6bkX+YCTs3MQeXUZaY0 + 0uLPGk5wumrB5Xhs2baipT+DC8MriPLKYwr2JvgI6Belh/DziUyx+KLBheWYX1WZ4hFa7U7TPSN3h0sQ + U67JlOxNVHSF0d6T1abSRKYCkrVdS+/rTGmkxVE7O0S+IdxuRVaTMw3D5bfbmYK9CT4CpuaH8M7/toP0 + hm57dTcNUppMDLE4Po6hyTvcL6QOUy7R0EBLXzqzXaWJTAUMTylhSiMNPlV1xunLVrx7vbWQMDwxO4ix + oSmxwrCoAhqf24WaxkKoiJn/bYfJHiPkHD5C5aPTLd33uWca4J7NkCEVP2LLtanIrLaVFjITsOGO7AYd + 3+meRcDNk0yp+NLcl8blSiu45lvAlGw7RBXQ3PNrFOWWMwWSBupcSL5xRB0TDfXcKHYSaXW2TKHEIaXG + AvPca7LaWBrIRMCJqVn8ahrElEdSDlicETvksshsdKRhuDKngynZdogqIMn/wgITmPJIg6PfmyEntYQO + HLKb3ZkiSUJ+m5/M8kGpC0jK6O0Ck5nySMpxB3tcKzVkiiQuCVVGGJ/tx/jINO8wLKqAKbkXYGvow5RH + Uo7uNkNsaBrNt91Tk3ExT5K8b2vIgI3V3pIidQHzq9qlVka/CpliMfA6zeUkgpUMadPUd5P7DV9BjH8h + U7StEEVAY9ddqG0qxPE9FkyBJCXwXBSWlpZxMbcMfzjtja9d3XEhW48pkSTEV+hhcu4Bs80lQaoCTk7P + Ya/xeaZE4kLk0+fkW11GkwUZDQ40DFfl8QvDoghoweV/xfllTHkkxeGkP+bnFnCjpgl/tPPBv3MCEj53 + 8kDAbX2mSJKQ1+pDvydW24uL1AQkNXY+kbeYEkmCrrutTOUjkDD8cKYH46P8wrAoAnqFayAqJIUpkCRY + aLphYnwK1Xd78LGDv1C+VT5xJBJKuyfUwL3hMmb7i4vUBGzp6udGve5MicRF7aydzMLuRhp7b9BfotiA + IqZsLEQRMCk7kMv/fJkSiYv2QTv0dT/A3aFRfOF8YZN8q/zZxV3qOWFyjRkWpbhUJxUBycCDnELFkkhc + 9pufQXTpzshHSG+wp+GlpqCTKRuLNwlI5v9qm4pw/EdLpkjioPaLNVoaOjEyNY2fvUOZ4q3lB09XhBeJ + txqyFVV3pVfSLxUBSWUz3+MytuM7vbOIKJDeVIsoXK8yxNh0NybGZuAnYhh+k4AWXt9INf9T+cECRdlV + mF1YhPqlWKZwLPb5nsXVUg2mTOIQV6ErtfpBiQUkx6OdsA1liiQOZIUjME06k8x8aehNoc8Uf76YKdxG + 3iSgZ5g6robcYMrEFzLdcj2SlFYtwzImlSnadmiHnmbKJC6kwmajC+IgsYAF1e10pMqSSRxOXbRiyrET + pNXbcc+0gtrCLqZwG3mTgEm3A3DaQDrzfxe9Y6l8gbeK8Afb1yNeUfmjrTecUk4yZRIHUtY/OTu4yQe+ + SCQg6f0OmQczRRKHI7b2Mh/xbgcJw6NTdzH5cFakMLydgIL8rxiqUsj/nC0uYIELu3HldZxI/OVbZRc3 + Mg7Ofb0fRFJKOy4xveCDRAJKM/cjJVXSXGITl/qeRPps8RfeHIa3E9DS+1up5H/WOh6YnppFcfs9fHjG + jykWH37xcZZaPkiKFSTtBcUWkKwcGLpeY8okDg4RFkwhdhpSlk5Gw/Ul95jSrWU7AUn+J+n8n8ERBwwN + jqKtfwifOQUyheILWS05FWfOFEocKu5GMP0QFbEF7Ogewi6Vc0yZ+HLI+oxcQ+96DDA82YHJ8TeH4e0E + JPN/p/TEr/9T33sKHa33MfBwAt+5hTBlEpddZz1wpUCbKRRfkqpNsLg8x3REFMQWkBwYyZKJL2TX2qXb + opXR7xS13fH0Ga8HlTDFW2UrASXN/8jPVRY3cuFtDkcvXGNKJClHLpzBNYZQ4tDxIG+TH6IiloCk3Opb + rddXIUiCupMtUwJ5klp/mobhxrL7TPFW2UpAK+/vUCRm/kdKq1LjczHPDfAMI5KY8kgDMir2TJe8aJWQ + 2eAodrmWWALmVrThI4ZMfPlM1Rnh+fIfeGzGAEMT7ZjiwrC/VSpTPsJWAoqd/+02pfuGSXWL280cmq+x + 5JEWe32dcK2ULRUfYso0MTZ9n+nKmxBLQBP3WKZQfCH7dtkCyJ+a+7H0WROCS5nyEbYSkOR/1jqebMm2 + wdP+CpUvsqhKrLk+vkizFyzvDN3kiSjwFnBodBJfSuFAIbJ/NzRXEXs/Aal1XBjmwkpTRTdTPgJLQLr/ + o6EAJ362Ykq2FTb63pifm8etxnb8h50vUxhZIK1e8EatJZZX+N9VwlvA1IJ6plB8UbG3Yza84mCABxNt + mJ6Y2zIMswQk83+lReV06YwlGgtjbiA2NjKOxp4BfOIYwBRFVvzR1gu+WZLXDsaUaWB06h7Tme3gLaCV + j+TbLMnSHTmrhd3wikP1vWj6zIkh7DDMEtDtynHEXEllisZCY58N7nb0omf0Ib5yDWJKImuOBdszpeLL + atrCB14Czswt4FttH6ZUfPjJ2BGSbKfcKVLrbGgYbq7socJ5myXB1SQeVpaxiDS2wBVLM5hcNkeo//cw + OncYVmc/R+ItP5zSEy3/U/3JCrXlLRifmcXBgAimHDvBx44eCC3UYkrFBzqJz3M0zEtAchulNJbezAKt + mQ2ueBhgcKIVUxOzsD2rDW01Tezfb01HpwXaf4ss8z/CMqsQo5E60HW5hfJjSuipzUdohj4cXA2gsdeG + KR7h2PdmyEopotMtemEJTDF2EqtYyVdHyKGXU3P8LtrmJSA5wZ4lFB9I+N3qxCqFguuhozM0kH8zkD77 + hdiT0Dn5Cw79aIE/2njjpt7/pQLaZWajK8wMNvaxqNM4gd6eMq4xNBCWaA13owRYG0ZCWcVlk4CRwcm0 + usUx6RZTiJ3mBw+XTUKJQ9vArU3ebAcvATXOhDOl4sM+8zO0cZmNriBcvaGOAM3v4LbrQ3rDJrnyv7wh + Hfp2X+PI96b4D2svhBp8SAU8l5GO4stOXIgOQIu1Beq7E2hDBLoHwcMoETphpfg1vR6nz/lDfc9JKp+v + UzidbgkvrNyR6RZR+MDeCyFSKN8v6bjIdGcrRBZwbn4B30hh9cPE/xSz0RWB6BJ9BNn8AvfPXl/vT65z + uFdRgcnpUXrC6bGfjPCp8Tl4GX9DBQxIS0BKiC/idU+hJzIMGQ1ncDVPD56m8Thrk4pDGQ3QTC/DXNQR + DPgdhreFO+Zm55FR3ypRaZUssIk3Y0rFh9XpK5ZDLEQW8G7fsFT2+yrq6DcszwgHzM7g5Febb1FKO+tI + v4OgODOoq6rgaw1HOJr8RAWMSI3ExfOhyDuhiaHaEu619HAp8iw8jBOhFVGGQ5kNqIk7hZcRv+BFohYe + TY9wvWT/jk+3iMIBv7NMqfhA9g+T01g3+rMVIguYX9nGFIoPX2o47dguNz6E3DLGNzpO9DN+cdgejrs+ + WydgwJ7vaRiubMykeeCPR+1gbXqICnj9xiU4ecajSksTvb3liC7VhK99OBxs03CQ6/3OJ0fhRcRevIxW + wuOxu+h9MIZvzRRPPsLHDp4Sb2Ai84FkGZPlEAuRBbwQm7tJKL4o2dgzBZAnZEC0W08g3yr79xrg3Jqb + lEgYvltehompEZg4/ID9B6yhY65OBUxOCYKjcwyaaf6XiIiMk/AwSYRmVDl004sxH6WMl1EH8KS3mm7c + V1q9kEfbnSmBPPmDrbdUJqUbegR7a0RBZAGN3WLWNZI4mPgpVv6XyIWL827GzD0tet8eXNcLpjmdpd/D + hRhTKB3gBhMWRlTApKRg+NtcoPkf2doZdN4b9vbpUMqoR0OsJV5G7sPT9kwscoMO43Ovv8M/H7KFymEN + pgjyxDLGgikVC3L4Jdkhd6vJBWWdl7kR8G0MjDfJJgRL4zYjl2hzpgjyoiPtGBcef0Gqixa+UHFe91k/ + VXKE3Wd/FgoY+OMeLC8uoqopC2onjmO/uTkV8GZ8AEJNXDBUXYS4EiN4WcVA41oFLiaH0dD7rCqUS8pX + 4Bh8U/jaew6Yw2HX57SX/VHHnCmCvDgWtHlVhIgWW6FNz48u5Ua5rf2Z6B2rZc75kaPuJh+KfvmNSAKS + EfBXGl7rGkgcIgqle7KVJNwu0sLzSC434wQkdAYcwX4Nh3Wfl4ji+ioUkzDcVVZKw7Ch+SEcMLJEhsWf + kBHti1z9k+jrq0Rogg3sHDNgmFaAxSglPCv0oiNCMn+6OoF/8Gdd7jVf31ds9/UX+NDGlSnDTkNG5d+7 + e1DRiu8E07MTe0ar6VnaG50gopGDPTsaB1CR3Y60yCpEeubC2zQZ50+nYX5OtMIEkQQkh4xLer3CZyec + FWYAcp3jQZKSUL5VZi//ipPGVus+t+oeVaEsqY4O9PsIDDuNAxoWSLX4COlXvFBja0/zP3+3i9CKKUdb + zEk8z7DGo8U5pBU24GNOvo+VnaG9W/l1bvnRn2B/+COcdNiF/Y7qm2SQJUS0j874QykwChbRN3Eprxy3 + m9rRPfKQ9tZr256KNjyFruZBVOZ2IP1qNRXNhxPN0ziJznVuxMskidZSrn2drRBJQHKhoKR7f/cYOSrM + BHRiiTEecwODjQISSEi+ZGfISSP43B9x4lh9uZtKQyall0gYbryFX9XMkWz1KdIC3NAdEYabZa6wdctA + ZNJFPE/Wx+O5cVQ136Pn5XyudAamX/0kFNnh5w9hdup1AYOu61f442kPpiySQEQjO+kOB0bC9GoKgnNK + kVnfhvsjY1jeJNoS5ofuYqIpB3U5tciMrqaHt/uYpcCTE4ol2lYQMfvvja17/a0QSUBSgk9+k8lVp+dj + cmF/PoUm1FoOEThoFoyvNb3ob/knx85tKephBRoBOxSEQjO9FHGJgRi+piGYJtkgYpGnGr47cZZ+9q8P + 2sD5k08Eo+GyMjoprWqshxsWHyPV1REPqgtx5ao3bGMzsHxdC48n+um86W4dX3xz0Br2n31JxXP65gNY + niTS7RLKZ+j8KXQt9mC3iTVTIlEgon1g74tf/SNoGf/528VIrW2hhxcR0VbWtCW5umF+pBuTLfkYzr2M + 7kgTtLl+gzq9v0at9l+gRvN3CDOwZ4rFh7riu+sc2gqRByEsyGlSpMsmhxORpSVyGTTpLXMrWpGYXYOI + G6XwCs+iJ+W7hl/G7WY3WjGRWC2YjCYbwTfKIWviKg2hfrsIv2Y2UshEsdONZFTE2WIl8tA6CQeCDuOo + jh2V8NDPOjR83jxjT5/dM8QTiRafIdnBFb291XAKSMC9eHM8GWzC8MMp7DUKxP69hpy4u+Dy+Qc4pfUx + jF1e9Xouu6BnvRsa6kdx7Edjujy3l5OcJddayLLdB/Z+2O8bBv3wBPhlFiK5uhEdg8NY5MRaGz6JaAuj + vZhqL8Zwfih6rlmg3W036vT/FrU6/50T7b9uSbyexiah+JKX3Cj8LNshmoDzk3gyUI8nI3fob/fjuQk8 + Wlli/91tIBt9SFK+zP0sOc+YJLfkFPZ7I+W4M5iDpr5UVN6NQmF7IHJaPOk1CjfrTiGhmhQvGEhF2Mhy + CxzKqhcKuBbVjEpcSwzC4DUtYa+4FLofp03NaUg2/novAn7YjaWFBVRUFyPC4jvkunqjrC4bydEBeHK3 + EDOz89A6E47je07AZdcHsD36EUzOCsTTP/0NNLUPQeUXg3WFCYTDP1rgDzZea0TzxV6fMGhfuQ7v9Hwk + VjbQ/cGkemZd+OT+fWGsD1Md5RgpikJv7Cnc8fwJ9Yb/8EbRtiJV5yemVHzIjK5Z1/ZbIZKAZBL1JW0Q + jsh9eHmN6ykIcap4kWaO5wWeeFZxCc/qovG0PQNPeirwZKiVzvw/nuZGUAvTzNd9E6uyklJvcq8tOcuZ + zDN1DRWhdSCLnmJA5p/y2nxp75rR6ICUWktOVCNuoMEJy7FRwIulZ3CQId9aSK9oczMDpXH23Gj2MM0L + Yxx18bWyPRw+/QKdxcWYmBzDJcsD6LoahZSUMCzXX6dHldh6x8Lw2304s/8jmNp9AgP7r6ClfwDH9+vh + 6O710pGqaXJ1g+kJFziaBcIjORvx5fVo7XuAOS7XXOIii/D74ERbHB/EdFcVRktj0Btvhzvev6De6Peo + 1f0rTpzfbRJJXG7rfMqUig9Jl0Q7yFIkAZ925QnDEi/INAeX7L+IVsakjwpaLc3Q6eGGntDLGIiPxVB6 + KsZKSzDZ3ISZe/cwN9BPL1lZnhfnJu/V3pU03DxmF8ZpiTiZRrgzmEunFKrvRyOpOQHWZZ0wK+6ATn4b + jt1upkIeympiyng8owoR3MCi75oOanxPQF1JHyn2gjCcfekslxOW4EFFPJeGLONS+A1YHvgeZiZfQtto + L1QPaePI7pNC0YxVnHDGxB9X/K8jI6kAHS3cM8/N0/RF+BzcMyxOPMDM/TqMlV9HX4IDOvx+Rb3xP3J5 + 2t9wgkhPtK0o0P5XplR8uOqT//qZtkE0AZtT2ILxYMzlEOrVjm9Lg8YJNOpooslQl0MPbbancNfPB71R + ERhMSsRw9i2MV1Vh+k47Znt7MD88hKWpKaxwvQXrc2/HMpe/LnI9zBzX+DOLyxiYmUfT6DRyeseQ1DWE + q+2D8G/ogX3FXZiVdOBkYRtcb+UgJeocfI2N6Wh4Neci/8xKvwWDo/uhcUwTRscd6Kn45ESrtOt5aGvs + wvTUDBa5HnL1/cnPjE3PoH1gCLcb2+nAISr4DBrM/g/N02q0ZC/aVpRq/xNTKj6EutwWPut2iCTgs4Y4 + plR8GHY8zJRObNRV0aCphiZ9HTQb6aPF1Bh3nBxwP/gC+mOj8SD1JkYLCzDZ2EAva54bGMDi2BiWZmaF + 4vBhifuZea6Xm+ZknV/Y0ENzf5adlo/mug5MTkzTk6zW/jkpue8aGkFeSyc9zd7s2g163ManZwPX1QOq + W3C9LEOInaZC62+YUvEhxCFz3XewFaIJWB/DlIoPg/ZKbJFkDScq/SfXuzZoa+D2SVect0nDpbNZiD9f + hKyYWhSltaAqtwOt1T3o6RjGyMAEvTdkZmoeiwuiDbbIVAc5SuP+8BgK2+4iNL8C1rFp+N7jEj5zOk9F + e9NG84OWJ5lC7DSVmn/FlIoP0hWwJpIpFR8GTstJwA2kaW8/x7U6u09m830tbiDILp0S7p6D5MtlyE1q + QH15+6Ze9E5+DrztTeBgdhDmZkegYqGPH6xt8NUpB3xsc46TTzDC3Y4DlqZMIXYaxRNQCj3ggN3bISAL + L/M4+DmEITjYA9ERpoj2DxKOUBfmBJUfC6MjKLDmcj+XGFw5pYEi3X+ijVmh9ZfI1/k7bmT5e8Tq/xt8 + jL6G9cmD0DVXxwErM3x96gw+O+WMP9l44LClySYZ5IHCCfi0KYkpFR+GziiGgLe0rJlf2Fq8zOLgaxeB + oAteCEuxwNUCHcQUqSMr8DhS9M0QdqtT8N1Mj6A0KQAz8+P0vx+WlaJUVx92Ljeg5VMIdwdX3DL8I6o1 + /xuzoau5ES2hROuvcEvnH5Gp+8/Mv7fTSEPAy06ibU4STcD2TKZUfBg5K+VBiJiUaujBc8OXRfZv+NhG + IijQG6GJ1nRPx9pypMQ0NZSYKKPwuBq0zuWgpUdwe+TTzlxciwlDbmUEF5KX6erD/fMBqNFQh5d9BE74 + VUHNrxLW564i3uwnVGj/NbPBhchx5LuWMq3fr/t+xOGKszQF7MpnSsWHhyJMw+wEVeqa8D0ZDR+bKFwI + 8KUlVFG57CrgmGJBr1elchiVR5Rw2i4WBiF1wvD7PMcZ7kmpuBgSTCfHyf8j85jNJ41Qxw1+Iq24ka1v + BVT9qqmMBl6ZCD5thELd/8VseEURMF/735lS8YEUMqx1aCtEEvBJTzlTKj5MeRxkCiEPEmPffIVVQroa + ik2VhTeRB5l6QcmzAkEZXfQ7eTwzRleCzDKL4eOYiKQKa0y/KtAcr6mmc5rkvW6a2EHPu4hKuIqmbwlc + HT2QbvQRqrRIAQDX8AoiHyFL589MqfiQfKV8nUNbIZqA/XVMqfgw73dgkwjyIt/9BFM6QkyJOjLPc73e + 8cNC+ZJ0LHHEowzKXhVouCfI957eK8bzaGXo3K6G25kMRCQ40cv8yNIhmRfsvhQifL9CXSOYud1aJyGB + 9IpWbtcQY74fVdrirdvKAmmsBd+Or9vkEQuRBHw8epeTaHPJEh8eBe9Dg/pmGeRBtf5xxHKDio3yJaYK + cr1V8QgFx9Wh6ZpLez+dC7VYXBKE3xd557AcowrN7Dqc8cpFkHsESMEEWfYjf05WaFosTIXvWamlBWen + +E0SCkSsRLrxJ0wZ5EGcnhZTKj4U3mxa59BWiCbgzCheXj3IFEtUXoT/woWlzTLIi6zLakLxSK+XFaCC + qmOvez1CFZf3WZ+5TuUjBKYJRr+kGug/445jIlYHJ7IbYRlSBD+rZMTkmSOpxhQTswP07001NwtDMYHk + hRdOh2wS8LRrKB0Ns2SQB1cMnJhS8YHcubfWoa0QScBHy0t4GaPMFIsPbfoq6ySQJzVcLxiXz+71Vgk0 + 8xPKR8JvZYegyvdJdxn+89phDMUZ4lhOM4wjK+jpWVdC/WjFTXaLBy2KIKG4Lypyw3urciNiF6j7CAYn + an4VNBdkiSAPqjX/AhcMA5lSiYqgInp0s0cMRBOQ40WyPlMqPvSdUt7QGPKl1IrL9Tb0eqsk6FhB2bNc + KKDW+Rph+H1e6EMF7I03xdGcFmgn1VIBA+zjEFcmqFls7k+nf3d5bg5tp6w2vfctQysYeuZzPaJiLL+t + UqH1d/AyimGKJSpkYxI52HOtP1shsoDPC72YUvFh/JxiTMWspfb4kU3y5atqQONcnlA+gu+NDvo9PJ6f + ouGXCNiYYE8FVE9tgM+rO0Wibp6hAiZWmwgP7p7u7KCFExvfu0SHe78tJqnlRY7Oh0yp+BBsnyHyGrrI + Aj6tk3w5biFAcUbCa6k5piSUr/KoMswdktbJp8xR3i4IKU96q6h8hLxkLyqgyq0meNqkUQGDva9QAQmk + opvUJpKfG0xMWP++Gj9xDa5Y8hES9Y4xpeJDuFvOOne2Q2QBn/TXMqXiw7PQvWhUoIHIWmqOcXngkcPw + sgxaJx9BLaAaC4uCotHnxf5CAVNuBFEBCW7cbz0R0P9UEmIKTIUS1nUn0J9bWVrCHQd7+l516t9zjf2X + mxpf/vwOFw3cmFLxQdRyfILIAj6eesCNhH9lisWH++ZHNjW+opChY4oja/K+VbxT7gi+h8VZLvyqCgWM + vhkmFJBMxRABCaGRnkIBE6qMhIf1kCLaet0vGQ2vGFRo/T28jaKZUvGhoUz0w8pFFpCUir+MV2VKxYcJ + N8XLA9dy09AG+q5Z6wQsahHcDv6kr0YoH8EvPUkooGXI69s1Ax1jEL9mE356wxnMLwqOq3iQFcA1tuJM + uawlU+drplB8IGVs5Nb5de5sg+gCcpDNRyyp+PAoRHEmpLeiRl0NYeYeMHLOoKsV86vhtyxIKN/La0qw + zcoRCmgcWS4U0NciBVczBFeQxZSbwC0lBGHZgiU8UrDQ7kZCMFsCeRKhf4opFR9IGdbSq+9LFHgJ+LQ1 + lSkVX+4YHWM2vKJRp6aKusBXR84uznHh98Q6AfVvVwoF1EoWTMWsEhRwCd6p/tALzhfM9/nXoKbrIX2t + ucEO1Bn+PVMCeVGh9bfwNYpgSsWH60HF65x5E7wEfDx2X7AtkyEVHxRxOmYrxooL6bPf6R5G0qUL6Aq3 + wESUDpavCZbhVgVUv9mAczYZcLC7BVPXQqj7Vq5b7SAYX27AxIxgv8hw3mWFKkDI0N3NFIov1fmirYCs + wktAsiLy4ro6Uyo+PL3MjYY12Q2uSDRqa2BpRpDPhOXcF4qk4VcBHf9SqAZy/x1YI4AbKZ9YI9tWXEgX + hGKSU3f47GPKsNOQuciLBu5MofhAJqDJPcvrnHkD/ATkeFZ5hSkVX/ptFGtVhMVdb0/6zGQFRD+kjikU + X074V6O0TTCnSM5oIft9WVLsJMXa/wIvozimVHwIc8vmctz1e2XeBG8BydknklbGEBYDDyj8YGQ0X1DZ + QiqgRendRMXgYj0eTi3Q1x4tieZCsXwnpKP1jZhC8aVAxAqYtfAWkByz8SL2GFMqvtwzO8pseEWgQUsd + S5OC0vuo/B6mSJLgc6MD5HAnEoq7zh9lirETkE3o0pj7I0e4DfUJaiX5wF9ADnLyJ0soviz4H0C9gvaC + ne7n6LOS8ntDrsdiSSQpeY2CCuqFhwNoOLlFmb6MideX/CQsQti5bHpK2lpPREEsAZ88aJbKaJjUCHaa + KGYvOJItOFqivX+K5m0sgSRFN6gOwxOCteKH1Sk7HopJ7+djdI0pFF/Kb4t+NcNaxBLw0fIiXiTpMqXi + CynVV7RckFSuLIwJBgoxhb1MeaSFW+Id0OPWOO5d1maKIht+h2v6JkyZ+ELmPckpEps8EQHxBOR42nKT + KZQ49FgpVi/Y4epEn5HkaKahjUxxpAUZ3GTVPqDvtzg5gkbzf2HIIn0Kdf5VKiNfQuLF0nVu8EFsAWmZ + fvTmg77F4fHFfWhSoHnBocwM+oxdg9MyC79rIaF4YExQwDnReOvVUblscaRBtdZf4pIUql4IpPq5+87m + U/RFRWwBCc+ksDa8ypiLYmxcJ3s45ocEX2hCSR9TGFngHN/2ar/xCj23mSWOtLipt58pkziQE/P5zv2t + RSIBHz+8j5dRkpdoEZ6H7UWHsfzXiEnN3urzWYY3MWWRBSQU36gQbGZamn6IJut/Y8ojKSXa/xveUhp4 + eBonorWmV/h9iYNEApLf1uf57kyhxGEleL/cl+gepKXSZ+senuHCbw1TFlmhfaEWPSOCpazJ1gKxz3je + iiqt/8GF3nNMmcSBnP8iztTLWiQUULq9IGHSXX6FCg0aapjr76PPlVzez5RE1pyJaRVufuqNsWaKJB6/ + w3UpnH6/FlGvYtgOiQUU9IIeTJnEgcwN9p6ST9V0u62N8Llsr7YwBdkJrnO5J/kMy7OTaLH7kCETf27r + fA5Po+tMkcQh1FW8ieeNSEFA0gt2S7UXfB66Vy4T1A9uJNPn6edGpKR+jyXHTqAZWENH4OSzTHdW0ktk + WFKJSoHO/5PKcpsQLvfrahLkq5IiFQEJz8qCmDKJy9PL+9BusHMb2cnk82xPD32W1MoBphg7yanIZmEl + dn+KKyeSeLWDpdr/jACjy2yRxCQ2sEiwjr2m/cVFagI+mpvEizjJ94ysZSVoP5q12cJImzYbK+GzOHJ5 + GEuKnSYyr5t+nuWFWbQ589/MVK71Dwgy9GNKJC5eJ5Mx2C2o7JYG0hOQgxzYKI1SrbUsnT+wIxKSfbvk + GYbG5+UafteiHlAjPAxztq8FdQZ/xxSNBZEv2MCXKZEk5CTUr2tzSZGqgKRimlxTyhJJEoiELTpscaQB + Db/dgt4mo/oBUwZ5YRbaiJl5wSkDD7ICObneHIrLtf5eJvJddMwS+cQDUZGugByPR7sE13gxRJKE5Qv7 + 0aLLFkhSWq3MaTEAyWvOxrYxRZAnF7Pu0s+2srSAOx4/MqVbpUz795x8PkyBJIHU+91rE6xZSxOpC0h4 + 2pzMSSPdUEx4FLJfJjvqBq7H0889OrmgMOF3LXRHXacg75ofvod6o//JlI8UGAQaXmQKJCl8Tjvgg0wE + JFW+z7PPMiWSlGdX9uKeufSmaMjkM7lJiXxuUpXCEkARML70ekfdSGHkhh11v0O2zi6pLbFthBSbLrxK + A6SNbATkeDw7jhfxJ5gSSQqZrB60V5ZKHSG5QJFsFichziVe8cLvWvxTO2ntILndvDNAicpHltcS9FTh + aRTPlEdS/CxuiFVqLyoyE5BAjrJ4GbWfKZE0mPX5lRucSDZX2B9zjX7WsakFOupkNbyioOZfjeJWQaEs + KeOvMP1Qqmu7GyGlVnzOeREHmQpIeEovOpR+PrjKk8t7cd9CvJBMSq9m7grWM3MahpiNrmgYhNQLy/jb + qu/TwQFLHokxfnXQuJQmnLdC5gKS0eWzkkCmPNKChORJj4PcKJlfb9hifpIem0bCr+v1dmaDKxwXauBc + 2EVv7yT31aVGVrIFkhBykeO6e4xlhOwFJCwt4HmmDVMeaUIGKORWTlFLuvquRtLPN84l9xrkdANWgysK + XPg9FlGHg+mNOJjViIxuwYlds9ML9ERSlkTiQopM52f538EsDjsjIMdjslQnhXOmRYEs4XVbHdleRPUT + mO4QHLub3zTMbnRFgBNP5WItDqc0rLvJXSW7GX3TglDc1TxIj0VjycQXMtk8xfN4DUnYMQEJjyf68CJB + gymNLFgJ3kcPRmeJ2GJqQm9aJ+GX7ExjNr6cOR5cA6Xr9evEW4tteRe99Z18t7fiaplC8eGCbTqGByY2 + tZss2VEBCY/He/Hi+s5JSHgcsg9DDkpo1eNyxFdTN71hV+jnmeRCjdb5WqYAcoHr8YTiZbDFW+UgR1KX + YP/KwtwivYSbJZYoUPn6d1Y+wo4LSBBIKPkpW3whgxWyD5kUvM50tNHPUtI6yhZhpyE5XigXapPXh9o3 + ceRWM+5NCEJm951hsULxBds0Tj7ZzfVth1wEJDwe7+EkVGOKImvIBDk5cJJcs+92Q47hl+R3ITVQjq3H + wTS2YKJgXtIhDMXkRneWZFsh6PnkIx9BbgISaE8opRMW+PCsyJe+/+TCEk3mD3EJ/pFrdTTZJ1IwZZEG + 5LUDBT2dUlw9DqXy6+2241r7IH0msmR2xeU2U7aNhLvnYHxEUHktL+QqIIEs2T3PPMUURTbspbd/kvcu + GRjf3Jhc3nWY60WUY+pxNKxWIGXAK3lYUjEQbmY/XwOVy7U4GlkHZSLcDekJt5HDWU1ofyg4TJNck0UK + R1nSrRJ/oWjHplq2Q+4CUpYWZD5ZvQqp2ibXLZD3PVdzn9mYTDgxiUBKiRzcAEEpnkECByfvwZucaG8Y + QMgC46I7mHs1eVyc3sIUj+zlzb5eh+VXO+/kjWIISFhZwdPG63gZdYApjrR4XuBB32+KC7/Hs1uYDfk2 + c7mlnz4fWcWIcM9dJx8pLKgvkXwrpTRRHAFfQW5kkt1cIRd+e6vp+5Q/mKDTGKxGfJshqyQNI1P0Gcm0 + Cjm3mchHjs+VZVWLuCicgJT5SdpTSbuI4UWcCh4tCPIkdz7h9y1Dr6ANM6921JFT67NiaqReSi8tFFNA + AgnJnTl4GXOEKZM4PM93o69Nwq9azrsXftcS2CDZmS07heIK+ApyRx2tro6UtDfkwm93GX3NqqF3M/yu + cogLw/4NPYKDLzd8n4qGwgtI4b7IJ72VkhUzxL4Ovz513cyGexfQ58Jv7bBgK+fbwNsh4CrLi3jaEM+F + 5aNsybbheY4zfY3pxXcz/B693YzQ1n7ML8u+hk+avF0CvuLx7EM8Kz3PIz/kwu9dwZVbdVzv8C6F30NZ + TXQ+s/9Vadbbxlsp4CqP5ybwrCoUL7jwyhbvFZyo5H4T8jMBXG7Easi3DZLnnS7vRNPoFF3T3vjdvC28 + 1QIK4eR6Wh/7qsJm82DlebYj/XtkakIjt5XZoG8LpMezq+ii4r0Ng4w38W4IuMrSPDdYqeLyPSe8jFYW + Cvi0I4f+eePI1FsbfknRhBc3eCLrvcsy3ii0k7xbAq7h8dw4nrbcwPN0S2H4DW7qYzauokJ6O8PCdlzv + HMLDefkXDsiCd1bAjSwsr9DGVPQekCylaeW1IqS5Dx3jM8I6v3eV34yAhImFJVQ8mKCTtKSRSQ/DkmCn + OXKriVayRLQN4A4n3WpFy2+B35SAayE9S+/UHLK6R+Fb3wOd/DY6lybrHpL0cKQKx6jwDi5yvVzZ4ASG + Zhfe6pGsJPxmBdwISexH5xZpD0SkJPmic9U96Be0QzWnBcc4OZW4nmq7XpPIS/5cmft7RLIT3M+dLL4D + t5r7uNLSj8L+h7g7MUsrsVmf4bfIewFFgJxCQAYBgzMLuDc5hzvcSLSNQcf4LO5zfz7M9WhEMrLlk/V6 + 73nNewHfI1feC/geufJewPfIkUf4/57e3ZAnALWYAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vwAADr8BOAVTJAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAAACTuSURBVHhe7Z33 + dxtHlu/3H3o7YXff29mdDTO7xxM8DpLlLFtOspwkS5YclXPOgUqUKCaJokgx5wTmCAaRBHMOYJaY5sf7 + 6lsQKDR0G0AD3UjinPM5tjkE0I36sG7VrVvV//D48WNaZZVAsSrgKgFlVcBVAsqqgKsElFUBXTA7M0Mz + U5M0OTZG1qEhGunpobGBfpqbm6MR6zQNjk3R0Ng0jYp/H52YodnZOfZ9VlFnVUDBaF8f9ZjN1FZWRvXp + aVQSdZuyzpym3EsXKffiRcq5cIGyz56l/IgrlH3+HE1PTlB2TR/dK+6ku0WdFJVrkdzOaaeYfIv8WVJp + NxXUD1Bj5xh1D07Q+OQM+9kvOi+cgDNTU1K2prw8Ko+Po/Tjxyjn/Hky3blDpdHRVBYTQ2WxsarkXrxA + 0xM2AVMrelySUt5DD8u76YGpi+7kCUGFpOmVvWTuHF0V8ikvhIATo6PUajIJyaIo5fAhKZs70dTIPneO + pqxWVjhPiSvskCEc1zZkKqHx5iaam7b994tG2AtYlXhf9lqyd2OE0kp+RIQIwZOUJnoyTi5PSBChe25O + jDFFKK/7fju1XrpAbSK8dz9IpJHqKpqdsLL3Eo6EvYDo+fSSD2AcCAFzat2HYDUwPsS1DZeXUcnrr0hM + b66lms1fU8vJE2S5FUm9qQ9ppKpSyDjx3D2FE2EjIGam/UNjlFXSoPj5xMiICJtnWZm8Ie/yJTkGzK3t + Z+VyR3JZt3wtrs1y8/qKgI5IGbd8Q60XzlH79avUl5VB00OD9Fjco+O9hQMhL+CYdZKqzBa6lVREF2Oy + 6XJcLo2NTyp+p/D6NVYmb8CEBWPAjCrvQnC0mCWPTdgmILXfbWUFXGHNK1T2/jtk3reH2q9FUF9GGk1Y + LGElYsgK2N0/TPezK+laQj5FPSyh2LRSSXSKiYoqWxS/245Qd+sWK5RWkJJBD8jJ5QkJxV00K8Z/M2Nj + ZHrjdV48BtO6NVS7fZvsEbvvJ8iJSziIGFICYuDe0TskJTt3J2tFOmfuCCEdXzc1Pi7HbpxQWim4elWO + ATO97AGRmsE1DZc9G/9pAdLWbt1Clsgb1BkTTZPdXYp7DTVCRsCe/hEp1gURZjnpHMHvTEwq0xpILnNC + aSX/ipiEiB4wr077GBA5weJGMZYT12O5wY//PMW09jWq//kHW2jOzBAzauWwI1QIegFHxiYoKbdaju04 + 2TgQkjOK6xXv02oqcTsbLhZhOv34cUrau4divt1C1z/aQJfeXEen/vwSnXjpf+nQv/+ODv7uX+UYMMeD + RLQzsQUd1D8yJa+n5tvNrFhaKX3rDWo6eliG5rHGxpALy0ErIGa1OaVmuhKfRzGpJlY0V0TczVO83/jA + gGI2XBoTI//77vc76Or69+nYH/9Ae377a9r9q//jFoT0NEYwd8QXdojx3xxNjwzLMR0nlLdUbvyE2i5f + pN6UhzQ9PKy492AmKAXsFOO8a/fyvRLPTsS9PBocHle8L8Jn8v59dG3DB3TkP39Pe379j6xg7oCAGMsh + nweQWkF45aRzBNLiOhzzf3qC8aF5727quBNF402hMUkJKgFnZmcprbCOLsbmsFJpAROVgopmxfvXpaXR + bi+lcwQCXnjYQm8cKqJ1h4rp3WMl9NHpUvrsbDl9c7mSdt+po1OJTXQzq40SSrpsa8JC0upWW8/UfuMa + K5BeyN4w4jL1ZaQHfSI7aAQcGhmXeTzHlIqv3E4qVnzG+NCgHMNxUmkBAp5NaqbX9he65PUDhbT2YBFt + OFVK312rpp4h20Sh+usvWXH0BGPD5hPHqSvhHk0P2iY+wUhQCFjf0kWnb2ewEvkC3nN4VLmuGr35a1Yq + LXgqoCOfni0TPbwY/wkZIAcnje6seZUadv4kQvJtsra1Kb6HYCHgAqYX1dHleM9nuFpJK6xVfF59ejor + lRa8EfDI3Ub5+VjfZWUxkOqvvqCO27dobib4SsACJuCcAOM0PUMuxxUht+PnYm344O/+HyuWp3gjoD0B + bbl1k5XESKq/3EQzo6OK7yFYCIiAKF1HmoQTRm8iHxRRz8CI4vPjtm1lxfIUrQJiHNgxYJsMoOKFk8Qo + yj98nya6lKslQ9YOxX8HEr8LiOKBs1GZrCxGEJ1qotwyW/iz05CZwYrlKVoFxAxZjv+Ghqj0nTdZUYwA + uUbUFzree8dgJVW136XOIeXPA4VfBcRM94yQL4YRxUhuiV7Q8TogkC9hWKuAR+6a5ef6c/yHnGB/brbi + vvtGGqnGcp8auzOprjOZ2gdKxc8Dmyv0m4ADQ2NyOS0mlZfESJBXHBgeU1zPvR9/YOXyBK0Cpvp7/Cdm + v51xMYr7HRZht8aSKOWzU9eRTG39JWI8HjgJ/SLgoOj5UDbly8qGL9xJKaHUAuVsuDE3h5XLE7QIiPFf + e59Vrkr4a/yHQlbHVZDxyQHR4yUp5HOUsLWvKGASGi6gdWJKFosGSj476AVRzmW/LpRUHf79v7GCuUOL + gB+eKpWfOz0sxn9vGz/+M+/fo0i3TM9MyHDLyWentuOBHBvaX+NPDBUQC+9ItaAH4qTwJ/gjcA7D93f+ + wgrmDi0C2sd/w5UVMjRy0uhFzbff0Kz1WeJ9bm6WGrrSyNyVwYrnCMJzz4hyO4M/MFRAhL2bDwpZIfwN + /gjynGbDzfn5Xq0NaxEQhQr4LKPHf5WffkxTAwOK+2vqyZECcsJxYILSP6qsJjcawwQ01bbKcR8nQyDA + 7Hvb0RhZ5mW/Rhy9ceS//oOVzBWeCvj6gSJq7R2X4zFUMXPi6AFSO2OofnH4/tv6izXJZ6fack9MWPxX + ZW2IgO1dA3Q9oYAVwZ9EJRfTj6fv0p83nqBfr91F//LW3ueS0g/27GYlc4WnAq4/YZIrPliFKH17HSuP + ryDXN1isTDN1D9d6JZ8d9IQYOzq+p1HoLuC4dVIWkXJC+Isb9wvo64NR9Pv1B+lXa3YqQJ2h4/W2FBVq + DsOeCng43uDxn3jP7oR7ivsZHGt1O+lwh7krXf7THzlCXQVEeEvIqpATD04Mo7kterxtx2Lod+/tf048 + O+9sv6QIw5gNH/vjf7OiqeGpgKgBxGdYIo0Z/6Hmz34fAOkWrHI4C+UNtR1J1DVUo3h/I9BVwEqzRfY+ + nBxGc/R6Cv33hiOsdI78dt1u6upTlqwn7t7FiqaGJwJi/NeJ9V8he92ObaxAvtB05BDNzc6u3MP07ARV + tsWxMnlLVfs9Gp2wJdGNQjcBR8cnNW0c0gsUG2z46Sr99o3drHAcl2JzFNfeWlKiKQx7IuDHZ8ps4z/x + u6Vv6lv/V7t9q2IX3OzcjG49nzN1oiecmbVtpDIC3QS8L0Ovf/N956Kz6I8fue/1nHlr20VFGMYut+P/ + 8wdWNg5PBFwZ/1WUsxJ5S9WmjTQ9opxI1XU+JHO3+1yfNzR0pVL7QJni8/REFwGxiUiPfRxa+OVsAv3T + uj2sYO5Ab2npVpapJ+7eycrG4YmA9vEfCkE5kbyhbP27ZG1XVjZDvIbOVFYevahoi6WJaaX0euGzgOhJ + roqZJSeJEWBJb9O+SJlW4eTyFGxed7yPttJSj8OwOwGxF8S+/6P+px9YmbSCMn5U0yiuud9EkYUfUHHz + VVYc/ciQa8mOn60XPgtY2WDxW8IZ1dMfivEeJ5RW1m09r7gPhGFPZ8PuBMTuOCxDYpyGk644obRgWvs6 + 9aalKq63b7SJbhV+SDfy36XIgvVU0HiJEUc/sF7cO9KouAY98ElALLK7OqNFT3Asx7s7LrMyecNv3thF + LZZexf0k7dvDCueMOwGfjf8qWKE0seZVuYzneJ0jE90UU7JJymfnZsH7lGc+x8qjF1Xt8XLC43gtvuKT + gFmmBikGJ4ye4DPW/xjBiuQLZ24j2frsftqFMJ5sVncn4EMd6/9aThxTpFsmpofpbtm3CvnsoCcsMjAc + Y3WlfcC0ci164LWAk1PTdNYPvR/GfB/vvM4K5CuvfnVGcU9ISnsyG3Yl4JqDRdQ3Yhv/1e34jpXKU+p+ + 2EGzU89SINOzk5RavY+Vz05kwQdU+ugWK5AeIBTPzul3nrXXAlY2tBu+ow1sPx7r84RDjd+I961/pFx4 + xyHmnHSOuBJw47lyuf8D+T/TG96f/1L99RfyDEH7dSH05ZrPsNI5c7voI6q2JLAC+QrSMt3DdYrvzBe8 + EtBfM98j11I0JZi94WRkuuLeLJWVbsOwKwEPxNpq6nzZ/1G+Yb3TTrY5mQq5kf/ec7KpEV/6jU8FCa6o + 7UjUbSzolYBN7b2GC3j9fgH9+/sHWGn05G9fnpaTKfu9zU5Pu50NuxLwgelp/u/ObVYud8jSqgZlYSjq + +m5qkM9OavVeViBfqe9MoZ5h5fF33uKVgEYXG2Dct3bLOVYYvcHasLnVJo2dtKNHWPHsqAm45kDRSv4P + 4zdOMFdgJ9tAnnIjPcKdPd2iFUhrVI4Qe0kcr9NbNAuIk+hP3UpnxdGLn07fZWUxilPOYViEzz2/+RUr + H1ATEOe/TM/Yxn+lWvN/a1+jrrhYxXUMWzspuuRzVi5PiS7eKHqsh6xEvlDZHifTQY7X6w2aBcShkUZu + MEJo/9d39rGiGMXLX5xSPGgQaY+TL/0vKx9QE/Bg3NPxX3UVL5kaa16l1ovnFTvZrFNDchzHSaWVtJr9 + rES+0tSTtXK93qJJQGT3jT5S490dl1hJjARhuMEpDGecOsnKB9QETH76AJqOKG3rv+Y9uxSP6kI1cnLV + TlYmb0B+sKIthpXIF1Cu5WvltCYBcVA4JgecOHpwJipDzHqNSbm449h15VJXZ02NahjmBET+D0/FxGtr + t33LisZRs3WzDNn2z0WOLav+OCuSLySUfyek0bdiBrNsLAnar90bNAmIM1Zw1gonj68grK/Z7J+JB8df + N50Uf83PVhwQDs+8/BePBfzkjG38h1IpT/d/VHz0AU32PCv4xOZw06NIViBfwVJdWesdViRfwAx95Tvz + Ak0C4qgzTh49wMQGiWFODn+AtWHn2XDW2TMeC3jo6frvSE01K5szZe+9TeMtTkcIi8mCllyfVu6XbxfS + 6NsLogrbl1MVPBZwaNRqyCmmdrBXgxPDnxy9lqK45+6GBjYpzQmoZfyHdAse0+r4WZaBMjlW48TRC/SC + KCjgRPIW7B3xJQx7LGBNU4dhS2/YRffPb3pXXKonf910ShmGBedee8WtgDj/xdJvO5GgVozpOOlWEDPe + nqRExWcMjLVSVNEnrDR6k2JAcrqlT7nTUAseC5icV83KowebD91hhfA33NpwzvlzbgXEIeTy/L/hYSpz + df6fkA9PNnJMt4xN9lOs6StWFiOIKvpYrudyInkLekHH70wLHglo5NovVlX+55OjrBCB4FCEMsPf29T0 + 3GzYWUBPx39Nhw8qd7LNWCmp8idWFCPJbzzPiuQtqJDxNh3jkYDWySnDCk9xZIZR1S7e8BcxG55xCMM4 + vuP8mtdcCujJ/o/6H3c47WSbpvTaQ6wgRmNLyfAyeQMmT0PjlpV704JHAnb0DBqWgA6W8GsHYRj7mx3v + P/fSRVUBMf5re3r+C06n4uSr+vxTxbM6EFFQOMrJ4Q9QM6jnRiacvvWor1DxnXmKRwLmlzcZlv9DNQon + QiDZd+mB4v77H7WIMPzsOXKOAn5w0iRXiJD/48Z/5R+8R1ZLu+L9cACQkekWTyhsuszK5C0Iw4736Cke + CZiSX8PK4ys4sw/LYJwEgeRPG48r1oZlGH79WRh2FHBl/Fctxn9ikuEoHw4Owr5g+/uAR30FMh3CSeFP + kit/YUXSCs6RQfFrdfs90bMrMwie4JGARu37QMEpJ0CgwZi0tLZV8R3kXrzACrhS/+ec/xMy9qWnKd4D + u8puFW5ghfA3sSVfskKpAdHQy5W3RlNlezw19WTLDeu9I2Y5k/f2ICO3AmK8YtSTjLYejWYFCAb2XFDm + 6vpEGN779HGudgGx/7el++n5f99tVcjXcStS8foRaxfdKd7IyhAI0AujsFQpWsaKaNWW+/KfSLG09hdT + 32gjjQvRvOnlXOFWwOnpGTlT5QTylWBY/VADqSE8vdP+PSAMn3vtVYWA7x83iQZ5LPduOD7/o/nEUUWu + D6cKYBmMEyFwvCfHgQifEM3cnU7NvbnUNVQrT9ky8jwYR9wKiBTM2TuZ8hAgHH+mZzV0MOX/nPn12p2U + X6FcYsqPuKIQ8FCcffxXtTL+a9j1s6K0amZ2klKq9zAC+A9URt8p/ozulm6RlTYoSsD2yqHxDr+JpoZb + ATHD6x0cpaa2HiqubpETEpz9fC+jXE4izkdnyZMRbiYWylQNTshCyRYelepu6S4Ylt9c8ctZ5eGP/a2t + tPeffrMiIB5WjZ/b8394KODM2LNnsmGRvqDxIiuFEUA0LOndK/uWMuoOC9Fuy/QIwv/UjPLh3bohIoB1 + bJL6u0ZoalL7RiWPJiHuwIwRoXp8YkoWLbRY+qhRCFtU1SKX8HBULoREyRVExdrv8Rup8shc5N2CKRHt + yH98cEixNozxMJLSEPBccott/Vf8rO777VTx8Qaa7FWetIAiUE4UX4FomMzcK9tKaTUHqFSI1tyT81Q0 + q+7jNDvWsSnqsQxRfZmFitPMVJ7bQrmJtZSTUEOFqQ3UWNXJvs4VugioFYytsLEdwqLItcpsoaTcainn + OTHexMlXn++NpPe/vyJrBP/w0RHZW0JUf8uabbKFWTsF165KAW/ntMvz//BYhPIP19Nog3KXGGaJvqdb + 3pMVMgidqTX7Za0gJguD4+1yk7pRoqEn6+0YJnNlJ+U+qKX4S4V0ansiHf4qnvZvjKZ9n0XTlX1pUkBH + zBXaH4IYEAG1gF4HwqInGh6zyqEA9qXEp5fJg9CRytl6NIY+23WD3hWTmpc+O07/9+29UlTU+HFSaQGH + nDtez8TwsHwQTP+obewE8Zx3snUN18rVBl4qHsgaa/pSioZVEkwKMPM0UrRZ8Z32d4/Inis/uY4SIorp + 3E9JdOjLOCFajBRNDfyes4CVBY/Yz3FF0AuoFcxKIe3E5LQ8rd9U80gOAzB5wno2xnXfHIyij36+Kjcj + YQMUZFXbAP+fHx4SvbXnYxusiaLihJMMQDSM07BnF7NQ20kDtU/HaN4XdrpEfCfD/ePUJEQrEqHy/tVi + urI3lQ5+EetWNDWOfBP/nIAlGY3857sg7AT0BvSu3WIogJpHhNzE7ErZux6KeEg/nop/7jBLNbCT7W7Z + FikaekCIhs1FBU2X5NbIzsEq+Tvca31FpoOmZ2lkUESJ6i4pQ+K1Erp+OFOETvc9mlbwfqVZTQoBc+7X + 0JzDCpIneCCgQX+VYUhjT5Z8RAJOlx+b7POpVF0VIRrGaKNDVnpU10OmzEbZo107lEHHttzTXTQ19n8e + I8J2vULAwpQG+UfAXrcKbgWcb8qg5buf09LDHbSYd4IWyiNpoS6B5ltyaL67hp4MW+jJeD89mRylxzOB + zSmFG9Mi9I8MjlObuVeK9uCGSQz+U+nktgS/ieaKrHvVCgExM57WW0AI9/crL6nwJxtX/0J/v/E6Ld95 + j5aj19Nywle0lLmPFksu00LlHVowP6R5Swk96W8UwnYIYQfo8bQthcF95osGeg2M0dqb+mRYe3i7jC7v + EaJ9d58OiJ5m39OZZ7CReqdCISBSMVNi7M3doxpuBVwsOOMknY9E/Jn+fu1vtBz5Bi3fWkfLsRtE7/oD + LeafpMXS67RQE0/zj0Tv2lVFTwaa6clIl613NWgm6E8wPhoeGCdLc79osGZKi66gq/vT6PjWBDqwKfA9 + mlaSbpYqBCx4WE8T49qioHsBc4/yIvkF0btGiN71+quS5ah3aenBt7SYfYgWi87TIoYD5hSaby+h+Z5a + ejLURk+sYsIwq98Bit4yNjIhRasqbKW0mAq6eTSLjm6+K2eeXGOGIg+umxQC5j2oo/HRZ1XfnuBewMz9 + jBhBSgSGA38VPezL9Peba2k5fiMtpe0UY9fjtuFAzV0xds2m+Y5Smu8z05OxXjFu1faFuaLz0QDdOZ0b + dqKp4SwgxoCTVr1DcCgJqBUMB2QP+wotx3xIS8nbxdh1vxh2nKaFits0j961TfkkSldgdnpxVwrbWOGI + s4BFqWaasOocgpeyDvCN94KwdP8b9ntRA73gwS/i2AYLN5IjlWNACDipt4CLucfZhnlRWKiOY78XV+Ql + 1bENFm48vFWmEBBjQP0nIUUX2IZ5IRAhGrNw7ntJax+gGZU0EtIqSAxzjRZOZMZXKQUUf3j6p2HKb/KN + 8wKAfCb3nUzMzNKbKTV0u1F5mJEjWOQ//HU823DhALcSUpxuptkZnZfiFmri2MZ5EVioima/k/K+UXr5 + QSW9llxFTcO2M2E4kFQO1iSyr2AlxpSpXAvGLFj3teCFhmS2ccIeGX75AstTVe1SQPBVrhh4ix6R+z2s + 20adymEbMNQ5uClWIR/ASgj7PbjArYDz7UV8A4U5y/e+YL+PydlZeju1ZkVAcL2eHyeC4f4xWSTANWIo + gwJVZwFRU8h9B65wKyCKDWS+jGmkcGZBjH2576NaCPU3B/nA6yIU1w+q77mozG8RIYtvyFDl8p6U5wSs + LlLupfYEtwKiaOCFE9BF+D1f06GQz86mnAayqoRi7JmJOZfHNmSoghUfR/kw3m1rVO6J8QT3As5O0/Lt + d/iGClNQfsZV6iD8vpdWywoIICf2iTi/DowMWenE1gS2MUORxOslCgFRAItCC+7eXeFeQNEQWA3gGipc + WSy7zn4XtYPPh19HMCvGDJl7LcBuMqQvuAYNJTADdk7BeFMJA9wLKFjMP8U2VFiC8DvM7+66WMuHX0c+ + yqyjUZU9JNirgo0/XKOGEse23KWynGaFgCjHx6yfu29XeCTgQmMa31hhyHL8Z2zt4aQYx32QXsdK58zR + irbnXm/HOjpJp3cksg0bKlza/fwEBEJy9+sOjwS0zYRR/cw3WjixaIpgvwPz0LjL8OvIK0mVlN81zL4P + aK7pCulQHHehQCFfaXazrObm7tUdHgn4eHqClm+9yTZYWIHwO8inEq7UdbKyqfF+ei0NuVgXRdk917jB + DsZ/2KzuKGBJupiA9Ht39IdnAgqWErfwjRZGLMdsELP+58dv0yL8fpJZz4rmij0m9Y3aUxPTcnM318jB + DGbyzuM/TEC07oaz47GAC1UxbKOFE4tFF9l7bx62ehx+HcFrUtoH2PcEKNk/sCm0KqdvHstSyAewY4+7 + P0/wWEDstwjrhDTC7wA/kL7Z0MUK5glvpdZQt4v0RPa9arahgxGs5qTHVjrJ10QdLTghlb8/d3gsoExI + R3/AN14YgHvjNjOh5u/z7AZWLk/5sahZtXYQe39xTAbX4MHG8W/vyQmHo4CoAfQ2/ALPBRQsFl9iGy8c + WCw8x95z2+iEnNVyYnkKQnHCI/VZYnf7oDwQiGv0YCLqlHL5DXibfrGjSUCchGDbjM43Ysgiwu98r/J4 + NTtRjT2sVFpBAatlTH0HHipJuEYPFrBvGdfoKB96w9b6Z4+b9QZNAmIL43JU+K0LY7+x2l7ir3PNrFDe + sC2/yXUZ/8F0tvGDAe44Nqx+4Ig37n48RZuAgoWy8CvRX8w7yd5r5/gk/c3H8OsIQnF0k3qP0dc1Epyh + WEw+kp02IIHSbN+elg40C4h1Urn5m2nIkCTiTzTfWcHea2xzLyuSL6x9WE0tI+pl/KgqYSUIIDijpsx5 + 8vGgjsaGvXtAoSOaBQRLyTv4xgxBliPXqZ7q9U2efuHXEZTxT6nsnUBIu3U8mxUhUNy/piy9AqYs33s/ + 4JWA820FbGOGIjj7hrvHDjFheCWpihVID7C0x30uwLIWjvfgZPA3x5B6cTqIsijNLHf9cdeuFa8EfDw7 + JY9h4xo01MCeF+4e77boH34deVXIjfJ+7rMBytuDoYyf6/0wTMCJrNx1a8U7AQVhUaJ143W/zH7V+Diz + nsZUkrho4LiLBawU/gJlY87rvlh2e+Rj6sURrwXEov1y9Id8w4YIS1kH2XvrErNf9FCcNHpzqkr9Qc84 + 6gwTAE4Oo0Hvi/MLHeUD2HqJwlruer3BewEFC42pbMOGCvOt+ex93X/Ux8piBBDd1KM+nsKzNwJxHC+W + B53lwwn7na3qxRXe4JOAqBxGCRPXuEGPi/C7Jb+RlcUoNmS4KuMXfxBX/VvGjyNFcOC4s4Aou+Ku0Rd8 + E1CAXiQUq6WXMvay99NtnZKbizhRjARl/Go76vAstlN+KuNH6L1/9fmJB4oOtJ5+6gk+Cyh3zaX8yDZy + MDP/SPl0IzvJbf2sIEaDlI/LMv7abtuB5Yw0eoL9HmU5SvmQhsGOPu66fMV3AQVyzwjOcWYaOihB+GWS + z+iBsF7LCeIPUMY/oFbGL0Kx0WX8OEIEOT5H+QB+NuPjmq8auggIFspu8I0dhCyl72LvoVeEXxyzwcnh + L1DGr5Zjw/nL539OZuXxFVRmOxebgoLkehrsVc9X+opuAj6eGqfluE/YBg825puz2HtIbR9gpfAnKH5w + X8avfyiOPZ//nHwot6orbWevQy/0E1DwpK9RPgOEa/SgAeF3+vlFdITf7YWBC7+OvJVSQz0uzlrGE4o4 + ibwlYn/acwlnIB+9ZVDotaOrgAAPmmEbPkhYSv2Jve5BMfZCpQonRCD4vrBZdVaM2kFMFjiZtII6P+eD + JqV8qQ002Gdc6LWju4DIDS6l/MQ2fjCA5Dl33Zkdg6wIgeRui3oZP55c7uuOOjyhCcllTj5fNhppQX8B + BXhaEaqMOQECCsLvJP9X/UtJCytBIFkjeuTWEfWau4KUelYsT8AGo/wkZYk9KE5vNCzlwmGIgECOB2+8 + xosQIJYefs9e68jUDL0RROHXkc15jaq1gziP+caRTFYwV6Dncz7dCiAUV+S16LrW6w7DBATzFpPtsVmM + DIEAz5XjrjO7c4ht/GDhlln9NP6BnlH59HJONA6cbIAlNWf5UPFcktno0xZLbzBUQIBnCwfFhnbRGz+x + 8k8rR+6Na/hgYU1ytTwcibt2UJbt2Wn8qKxh5RMzYDxiYXJCJQluIIYLiKU6237iwK4XLyVtY69vXPzF + r0sJzvDryBc5Daqn8eMIYHen8V/alSILSZ3lK8+xFRkEQj5gvIBAzIxtT1wKnIQL9YnstWH9lWvwYMRl + Gf8AX8aP4oLrhzOfO9HATm5irTydgXtPf+AfAYGU8Dwrh+Fcf8X2aFbmuo6Ut7GNHYygSqd2QD03h2cT + O5bxo3gh/mIhKx6AfFqfbKQ3/hMQQMLii0IK//aES/c3s9eDY9dwYgHX2MHKJ1n18lFh3P1g9hp91nYa + P9IsWXerWfHQGyL/58/Zrhr+FRBgTFhyxa8TE7UnXhb3jLCNHOycdlHGPzo8QVcPpMtDIzn5kOerLEDB + Q+DlA/4X8ClIiSA0csLoyrWX6cko/ySj45XPHrkVSqB2EH883D0BFCxwZVXI/TXXdItOgH9dIAiYgOBJ + Ty0t336bF0cnlhO+ZD8byd1QmP2qsT69loZdlPGX59nSK3b5MN7D0R/c7weSgAoInoz2yAfDcPLowUJl + FPu5pt7QDL+O7C9tdVHGPyXTKyWZTbY0izUwaRZ3BFxAybSVFvNOiHHhX1iJvCbiT7Jam/vMkyEafh3B + YUfplkH2/oClqV/W8+m1idwIgkNAyRzNP8rT9TT+5fiNzOfYwm+ozX7VwBHA/QFKIutBEAlo48n4AC2l + /MAKpZWF8kj2Myr6bQ+cDhd2lqCA4Pn7DAWCTkDJ3JycJftU0oXwO8Q/sehstYVtyFAFRwhjOwF3r8FO + cApoZ2pMPrnIm3SNWvjFI7ecHzgdymAmj3QSHpo9G4K9YHAL+BQcirmUtlPTwZiLpdfY96piHjgdiuBI + j2/zG+UZ1lkdg6rPKg52QkJAG3P0pL+JljJ2u68xxDM/VMKv2gOnQwX88XyaVU8XajplyT5O8efuM1QI + IQGfgdTKYvZh1c3wy3GfynGk8+tQzuTqgdPBDMRD8vmECLfRjb1UPziueuB5KBGSAtrBjHmx/CYtx34s + Jx12AbHWzP1+nWi0UAu/dvFOVVroRkM35XUNySIK7v5CkZAWcIW5WZrvqaXF3GO0HLlW9YmXl2q1PfEy + kGCD+sbsBll4cNvcQ+mWgbDo8ZwJDwEdETJyP0fy+cMMzx44HUiwOQp7gq/UdVF8cy+V9o6ImXtoTjA8 + IfwEVKFp2CobN9hCMK4H2y+x++1sdQddre+SR3O0h/jkwlNeGAFrBsZkKLsgZsG/FLfI3hANHwghcQDS + +2Iy9ENRM50T0iGVktTaT+V9o6rFpuHKCyMgwBiqfWxCNnZ8S++KkLtKHtGXOWZ6J7WW1gg59JIS74My + eiS+P8tqoJ+F+BAOk4lb4rMftvXTo5GJF046R14oAZ1B8rZ9dFImcuPEeCumqVf2Rhh/Id2B7Zo/FbXI + E/M/y6qXR+mi53IGvSlyc3gAzQ/i9/G64xXt8n0gWqS5W74/ZrAtYiiAjfBqZVQvGi+0gM5gKQu5wqHJ + aTIPWWWpU27nEKWJfyaKXhOCggfi3/H41XstfbIXxT+T2wZEjzYgx29Yl8WYE1UqkDwcZ696sSrgKgFl + VcBVAsqqgKsElH+gp//j/s9VVjGWx/T/AS9VebkLYiqlAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vwAADr8BOAVTJAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAAAB3BSURBVHhe7Z33 + V1xXfsDzazbZnPSTk7Kbk5zknOwm3uIt9tpZO7v2tpPsru21mlUsWQUJ9WLZFgIEkhCgDqhZBXWQAIEE + qog+AwwDDKJ3Zpje8H/wzfve0QzvDV9gyptXZvjhc1w05b65H936vd/7R1999RUssIBcLAgYAR6vG6x2 + E8NmnwSnyw4utwO8Xg/5+gVmZ0HACNC2P4KN6a8zkjPegJ1H3oU9Ob+B1FOL4OCZFXDq2na4eT8XqjXF + 0NWnBZvD/FLOqRmflegsCBgBTW2VsDbl+yGxbv+rsH7/D2BH1juQe2kD3Hl4Clo6n8CkZZz87ERjQcAI + CEfA2diQ+iMw9DaRn59ILAgYAWIIuOnAG+Bw2sjPTyQWBIwAMQQ8kL8MpqYWxoQLAs4BCuL1cni84OFw + u7l/cogh4LXyLPI7E40FATlQqtGBSTC0DIHm6Qt4cEMLN09Xw5Wcx3DhYCXk7y+HU5+XQe6OO3D801JR + BNToq8iyJBoJJyC2ZMP9Jmir74OKaxq4mPUQsrYUweFNt+BQCBzZWhS1gElpr7G1Q6p8iUZCCGg22qG9 + aQBKL9ZD7s67cDj5NilXKIghYGbB8oXx30viWsCJEQvrQrO3FZMyRYIYAl69d4gsbyIS1wI6bC7I2S6e + fIgYAjZy76fKm4jEtYBTU1/B9ZPPSJEiJVoB16f+kO0fU+VNROJ+DKir6yNFipRoBUw7vZgsZ6IS9wI6 + HW5Ru+FoBbx27zBZzkQl7gVEis/VkjJFQjQCYmBCW9dzsoyJSkIIiEswlEyREI2AyRlvgtk6QZYxUUkI + Ae1Wl2hLMdEImHrqQ7J8iUxCCIgUnRGnG45GwIX935nErYAujx1GLZ2B/+7QiNMNRyogjv86ehoEZVwg + zgT0Tnlg3PoC6rovwo36jXC9PgkcbjP7M5vFyYIJKKnCIVIBtxx8Cyw244wyJzpxIaDb64Te8Toobf4C + Cms+gSs1qwN0j1UHXne7oIaUKhwiFTDt9CJBmRfwoWoB3R4H6IcqoLhpFyfbGoF4fqr02YHXY7jV4WRa + rFCJVMAbFUcEZZcT79QUtA2OkH8mNaoUcGrKC12jTznxdpLS8blauw6cbgt7H86Gj+2+S4oVKpEI6Fv/ + q5nxHHKRV/Ucvr/3CJRq2sg/lxJVCTj11RQMmVrhXst+Ti66xaMwjDwKfEa03XAkAuL6n8NpFTyLXJQ3 + t8N/7joE/7EjE17ZcxguVzeSr5MK1QjocE3Cs848bowXunh+qtqmlz+6WodJsUIlEgEzCj5SRPxf/Ys+ + +A4nHcrn5z93HYTjFU9lK5/iBcTutm+iAW41bCHlCgXWDXt8LZDL6Ybje0pIuUIhEgGvl8s//nsxOgFv + 7j8mkM/Pt3cehIN3q9jYkHpvLFG0gLiWV20oiKjVC6ZjePoMxp1zdaRcoRCJgHLH/41bbPDLg3mkfH5Q + QtYSEu+PJYoVcNI+yJZVKJkiobINo1B8f8OxG450NhyugElpP5Z1/Gd3uWHxiYukdMG8svswFDW0kJ8T + KxQpYO94PVyvSyJFipTrdRsCs2E8ahlpNxyugAfyl8o2vvJwz7n7agkp22x899MseKzvIj8vFihKQJzl + 6gZKoLBWuJgsFh3D011hxdUmUrD5CFfAK6UZgmeUkuyyR6Rk8/E9TsKG7n7yM8VGMQJiyjPcQgtneSVc + 7utQBl9r1K0fgUMRdMPhCtiguy94Tqm4VqOBb3MzXEqwUPhJyjEYNMb+6IAiBMSttCcdJ0hpxAT3hu0u + 334sHkaPZFE6HAExAZFVhvMfzzq64bt7skixwmHJiUvg9njJ7xAL2QX0Trklkc9P+/B0i1RxVUNKNhfh + CJgqw/6vfnAEfvR5DilUuHyLI+feY/J7xEJWAVG+54YzpCixoqI1PfD9PR2jYc+GwxGwsDRT8LyxZnjS + Au9knCZlihRsSas7e8jvEwPZBMQJR03XWVKSWHKtbj1YnKOsDC6nJ+zZcKgCrkt5FVo6n0LZrcdw9tgN + aGnsAIfdOeN3EAuLwwnv554nJYqWN/YfY3JT3xstsgiI8mn7bpKCSEH70HQ3/OC6lhRtNkIVEPP/YRbU + z5Nz4b2fJsH7b22Ej369HbL3nwNtvR7cbvHySeM4Len8TVIesVhdcC0mOyWyCPhirBoKa9eSckjBvZbU + QFn6u8bDyhUTqoApJz8Ap8MFH/5sMxOQD8q4eXkaPCqvBbvNIfhtwgWlyLhTycZrlDhi8a2dB6EkBtEz + kgs4au5g3SAlhlTgOqPZ4YuHw73hk5+VkbJRhCrg1bKDrKULli+YT97fC3euVUXcIp59VMvkoKQRm7fS + ToDV6SLLESmSCojh8cWa3aQUUqMbLA2UK5xF6VAE9Mf/XS64Q0pHsXXVAdBpDYLfaz4etHbMiG6JNWlF + 4q5rSiYgRrU87ThJyiAH5S1pXLl8Y5qB7omQZ8OhCLg586dgMo/BpxuOkLLNxvtvb4Sj6RfANOE7xzIX + 2t5BFlRKSRJLcL+4tX+YLFMkSCYgRqNQIsgFnh2xOsdY2dwuD+TtKyeFCyYUAfef+gPYrHZY/O4WUrT5 + WPPeXtBppk/0BdM7boTXU46SgkjB4uMXweMVZ4FaEgGxouUe91G09t8NlDHU2XAoAl4vz4LmhnY22aAE + C4VF72yGW5cqwOMRjg0n7Q74XfZZUgypwNCt5wZx1gZjLiB2vQ/12aQAcoOzYX+kylCPMaTZ8HwC4vhP + Z6jmxn93SbHCAQUuyLkW+C2dnIyr8gpJKaRmEdcKirEsE3MBe8ZrucqOXYBBNFytXcu1zr4bi1DE/P0V + pHR85hMQr+6y2iZh28cZpFThsPL/dsFAn2+2jiFkn10vI2WQAzxXIsYOSUwFdLqtcLtxK1n5SqGlvzhQ + 3kdFLaR0fOYTMD1vCTeJmISlv9xGShUqi9/ZwpZxsFwYpXyqslqy5ZZQ+X3O+ajHgjEVUNt3i6x0JYFR + 1zhMwPIOstnw3N3wfAJeu5fFtt2iGf99+LNktkjt/x1v1TezcRclgZzgX4gq3eyTpVCImYA21wRLj0FV + upLAbtjyclEaU/qe/uIeKZ6fuQTE/V+8STOc9b9gPnh7E5t8+H/HGkMvCxClBFACn5y5HihrJMRMwIae + QrLClYi273ag3E/u6kjx/Mwl4Mb019j9b7jNRskVCsczLsIUN97DsnSNjMNrX+SSFa8U/osbC0YTuBoT + AW0uoyKXXWajRLuXBUhg2X2zYVo+ZC4B8fzHxLgp4vFf6vbjgS05k80OvzqUT1a60sDQf379h0NMBNQN + lpAVrVTw3LDJNsDK7vVMzdkNzyXgpbtpEY//tqxIB4vZd3um3eWC5aeukJWtRDAGMdLJiOgCerwubua7 + jaxoJdPM64aflbaR8iFzCVjfWg6X88Mf/338uz0wPODblXF5PJD85W2yopUKTkYqI5yMiC4gJg2iKljp + FDftDnTDeHFh1mZ6NjybgBtSfwhWuwm2r84kJZuN5b/ZAV3tvex7cWH3cOlDxS23hMKWi0UCD0JFVAFx + Mfe+LpOsYKVTWLsGxiy+87B4oSHekBmOgJj/edJkYet3lGgUi36+GWqfaAO/X+HzJkUut4TCT9NOsEPw + /mcJFVEFxD1fXNagKlgNNPVOLynM1g3PJuDlkvSQ4v/8fPD2Rii5+TDwfY/0XfDKbl/WKjWCrXZjBGeJ + RRWwdeAuWbFq4a7mU+45fN3w+LAZDhPdMC3gq6DRPwx5/e/9t5LgzNEbgX3ojuFReH2ffNEtYpFyqzzg + QqiIJiCecLur/ZSsWLWASZAmrN2+5+G64bMHHoQk4Mb018FkHoW9SdmkcMEc2HUqIN+gaRLe5rovqkLV + xs8zToV9jlg0Ac2O4Zil1JCSxp6rgWeqvqcPScB9J95jZztwC40Sjs+utYfA4fCFtftCq86RlalGMEAB + F8/9v18oiCag0gJOI6VE+1lgb9g4Zp0xG6YEvFKaCU21OlI4Pus+/AImxkzss51uN6w7e4OsSDWDKUH4 + XsyHaAJWtmWRFao2sBWfsPrCjLCb/PJw1ZwC+uP/Lp4uIqXzs+J/d0Ff91Dgc/dx4yWqAtUOZuPiezEf + ogjo8ljhRv0mskLVSEPPlcCz1VS0zyng5ow3wTg5Ap8mzX7+Y8kvtoK2oT3wmRefNqh2uWU+3s3MCzxn + KIgioNHaK0oWU6VwR7OHTarw2caHLYJuOFjAfSfe953/mGX9Dw8alRc9CfxWFS3tUWWtUjp4UAozsvqf + dz5EEbBr9AlZkWoFF6X93TDC74aDBcTzv5q6NnL/F//flTPT506aegbgVRlOskkJrgfWhHFeRBQB67sv + kRWpZjBXYeD5qgykgDj+a+l8Ro7/cK0vN+18ILSqZwyThB8nK03NoHCYwOh/0k+y3DT7bpZDx5Av904o + iCIgzhypSlQzRU07hN3wlqIZAiYfeAPMViNsWzXz/Mdnm3LA+TKLAHZJv+DGRlQFqgVM/YGivbYvF97L + OQ97r5fBucd1rFUfmbSAg5vV850IlagFxAsCxc7nrARwNjz+cm8YI6XPZ1bOEDD19Ifs/AdOMvjyJS9P + A8ukLzG5062ck2yhgut5mHEBz3zsLLzLRMPIbDyPjNE6/PqPlqgFtDkn4GrdOrIS1U49rxtueOjrhvkC + FpZlgrZeeP531W93w+DLk2x4mAhbCqqSlQCKhmPSD45eYNEspyufs5uU8E4Rqe4MiVpAvB5Vqccuo+Vm + w+ZAN4yL0ijftICvQpO+Ci7lFQfkW/ar7dDe8oK9Htf6jpY/UURoFS75YNeJLdrGC7fYCbt7nGhDJjMT + Teq7QfhELeCgqZmrrPgUEJ8L76bD50ShsBv2C5iU/hrYnVbYtCyVyfeHnyXDk/v1gd/ldn0La2EoIWIB + io6ivZFyDH5zuAA2fXmb/QWoaOkIjNGkatXCIWoBXR4bDBi1LPeypu8Gmz0+6TwJ5a1p7BrVW41buZYk + mZ0RweUNf8XOrGxlUtt1PvCsTU+6AgIeyF8G46NGWPqLbawLvnlxOhLkafuLmGWtwskAio2Hld7JOAWb + LtyGI2WPWETyINeiYaZUf6CDGohawPnASQoeUMdYQZOtn12j3ztRD/qhcnZy7rmhAB6150JZ8z7W5eH5 + DJ+sGNggv6i3GrZyFerbGzYb7ezWdRQQ7//w53/Jz74aqPTO4THRTrLxlzg2cV3n4ZKHLCUbfgcGMvB/ + 55DhnmXK4wLnSBcY62+DqWl6nVIOYi5guGBlO9yT7KquYbMe+o1NbKG7ub8IarrOweOO41Cpz2IHyrFl + xVbVl201VrKu4VoW3/VVuKZ3JfcxE7BBV8HOf6TuOAHul5HAY2ZrRMstKBq2ani4BwMUMu9Uwp1GHWh6 + B1mLxv99wmHK6wHHcCcnWQkMl2ZD14ml0JbyJjSu/itoWPGnUP/RH4Nu7w/I90qF4gQMD2x1pljiS6Ot + DwZMWm4G95Tdoq7pvQHPDHlQpT8CFboDnLCfs9YMW1jcNgwndOx519nAd+Kt690DrWBzmOHEwctgf5l4 + 3OZ0sYQ9lGB+cIyGUc+/PpQPK/MK2Q2V12u10Nw3xMZokU4GptwOcAy1w2TLfU60I9Bd8Am0ff4aNH78 + FwHRZgNf4w/ClQOVCxgq3EyPa1lxOOD1utmdcUxYo4aFkbUO3IXG3qssgSbepoStKwbX4hWxuMRU1IiL + 0jPXv7wvjyJiEOaWS0UC0XBPFG+oXHbyMhwo5rrs503sDg8ULdIjjF6Hhes6DWBuewgj93Kh59wGaN3z + PWhc89ecaF8nBZuPhpVfB7dJvIST4SKagK7RURi6fg1Gy0rB+OwpWNp04BgYANfEBHjM3HTf4eDGHuIu + YsYSXH5xex1MVmxhqdf4wYVavFUoveg+i4djYzSbI7JbhrixJIrmMg6ApeMZjJQfg56z66F11yug2fBP + nDB/BvXLv0bKFCm2F9Ozd6kRTUBLaws0LV0ETUs+9IH/zqFZthi0H6+A1qT10LZjK+j37ARDZjr0nS2A + keIiGK+qBFNdLdgMneAaG2Wiel0un6wiZeFUJJxoU24neKwTTLTRyjwmmu6zH4N287/6us7lf0IKIzaT + zdO5aKRGNAFN9XXT8kXC0g9B89ESJq129UrQbU2Gjn2fgeFAGnQfzYGBy5dgrKIcjM+rwazVgL2nG9xG + o2paVY/VyEQbf/Il13UmQXvGu6BN/peXoonbooWLsfYGWWYpEE3AiSfc7JASK4bwhW3bvsUn67Fc6Dt3 + BoZv3YDxh1Uw2djAhgP23h42HPA6Y3dbEeIyDflEe3YZ+i7vgM7s34N20z9HPEaTgvHq6QBcqRFNwLH7 + FaQkigGHA8uXgnbFMjYkwBbWkJEOvXmnuNb1IozcKYKJp0/YUMLW/QIcgwPc4NzIhgTU8/IZf3wBOrN+ + C03r/o6bVf45V6nytmjhEhcCjpaW0BWvNnDsyv2TjV1XLoeWtWugdeMGmOLGpdRzI7aeJmhc/Zdk5aqB + +GgBHyi8BYyCztR9bNLgf1ZqT3WwKJ2sXDUwEQ8CTjyVfgwoFSMlwu2qB9pRaDD4jlf6we0tfcp/kxWs + dEyNdwTPIiWiCWiqi3IWrFA0y5awyYv/OTE4df9VPSSd1oDFIZyB2/t1quyKrV11gueQEtEENDc3B8ZP + 8UTHvs8Fz2myuWHpkXpYdLgOcu4YuO5Y+DuM3D8p+7JKOODCtnPclx5ODkQT0N7TE5cCBne/FZoRJh+y + JKsenrUJU1FMedzQnvkLsrKVCG7F4YI4/xmkRDQBsZti63JEJaoVfB5cjvE/I3a/X1xpCwiIrD3ZBONm + 4QzZOdoNmvV/T1a40mje+u+CskuNaAJ6bTZoWf8JWZFqBbcN+c9otLpgeU6DQEAk42YHk5P/WtzxkGor + LRpwoZxfbqkRTcAprxfatm8lK1KtDBdN541GHrWOzZAPWZxVB/e5mTH/tRiLZ8h5n6x0JdF3aZug3FIj + moBIZ9p+siLViGbFMnAODQqeL6VQTwqIrMxtgCGjcNfEPTkK2k3fJCteEXCTpUlNmaDMUiOqgCPFt8nK + VCP6ndsFi88TFhcnWSMpnx8cH3peZkLwY6wvgoYVyuyKMTLaJeMMGBFVQHMLLsXQFao2MJiB/2yPdeOk + dMHcrhG2mihxd97HpABywyYgxK6OlIgqoMdqiYuZMD6Dc9iXy89PJjfRoIQLZgXXFfeN2QXvdVvGWegV + JYGc9JzdICinHIgqIMbm6XduIytVTWD3i5Mq/3NN2tzk7Hc2Pr2oA1dQNDQGfbJoZkIEWeDGf+a2yK/Y + EgtRBUR6T58kK1VNDF4Vbs4/b58gRZuLa0+n1w99TEHv+Y20DDKg2fhN8NrnPmogBaILiAGgVKWqBQzD + cgTNfrOLDaRkc/FRdgO0D1gEn+N1WqF193dJIaSm6/gSQdnkQnQBMeJYu/IjsnLVAA4h+N2v3eUNq/vl + s/VMM3s///exGmrZUUhKCsngZuWW9umsrXIiuoDIi+wssnLVAEZH85+ltsNIyhUq5x7MzBY6cGs/LYZE + 4Ak7DB8LLpccxETAiUcPycpVPEsXgc1gEDzLsZIuUqxQwcgZXZ9wrOV12VlGAkoOKRi6kykoj5zEREA8 + B6xdpb5uWLdlk2BdzOWZgo+Pzb34HArJ+VxX7BTGDtp6NNC4Cs+P0JLECs2GfwCPTRhMKycxERDpK8gj + K1nJ9J8/J3iGhi4TKVQknCh9MSNgAdNoSH2Aqe/SdkEZ5CZmAuJBc5xRUhWtSLjuF49v8p8BA04pmSJh + CdcV13caBZ+PcXj61LdJUWJB0yd/Ay5j0E6NzMRMQIwGwUwIZGUrEAwl42disHFd5toTTaRMkYKxgxjS + xf+dME0aHuekhBGXr8HgrVTBdyuBmAmIGKufqiZKGlOF8Muu7Z6ExYRE0ZJVNPNqe0zLEevYQUz34bFN + zvhuuYmpgLgm2LZtM1nhSgKHCla9XlD2k2UvSIGiBWMHq1rGBN+FE5/OI78lxREFTm45z/7ORUwFRDCX + i9Jbwdakddx4bPqei1h0v3w+4T57zCw8h+Ea72MzVFKgKOk88jtOcuGCuFKIuYBYsfpd28mKVwo4Y+eX + ubXXzFoqSh6xOHCjHbxBsYMT1YW+ZEWERJGiSfoGuCfly/83HzEXEDFrNNCk1Bkx1zpbO6ZvskQKKnpI + acQEBb/X5LtPJADXSnUdX0yKFAl44m2i5rrwOxSGJAIi3bnZtAAyg3lf+BmznG4vrDkeu+6Xz6pjjTBs + CgrjNw2DZuM3SKHCxRfvJ2/A6XxIJqBzZIRlpqIkkJPekycE5dT3W2Le/fLBMH63RyiJqamUBQxQUoWK + 7rMfcX+xQr82VS4kExDBQ96UBLLBdb/mZq2gjBeqeklRYgUu9cwM4/dCz5m1pFih0Lzl39ikRvCZCkVS + AXFC0pHyBS2DDLRsWMvSAfvLh1mvYjn7nQ0MWOga9l1uGCiL0wotO75NCjYXmg3/CPZ+3+1OakBSARHs + ilvWriaFkBrMpsovm36A634JQaRg5/nWGWH8GLMXThg/7qgoIcw+HCQXEMG1QSXsE5tqawTluvSoj5RD + KvD7+eVB+gv3kLIF07T2b8Gsq5rxfqUji4C48t9XkE9KIRXNa1YJFp/xkpjNZ5pJMaTio5wG6BgMCuN3 + WKB193dI6fzgPSHmlvuC96kFeQTkwLD3rkOZpBxS0J1zRFCe7hEby3ZFiSEl28+1gGNGGH/NrGH8OOGw + dtUKXq8mZBMQ8disoN+1gxQk1hirnwnKclnm7pfPmfs9M67tGrydygnHjx38GrTt+4niwqvCRVYBEZyU + tG5YR0oSK/DQlNc+fXgc1+G2nW0hZZCDZdysWPNCGLWMYfz6lDeZfLjD0VOAM3jhAXg1IruAiKO/D1rW + ryVliQUvjhwWfH/vqDK6Xz7rTmrAbJ8eoyKOwXaWYWH82RU2jub/mVpRhICIow8llCa/IM7C+d99o3qA + lEBu8EAUv5yIx668mL5oUIyACLaEGBpFSSMWzatXgts8XYlu7xRskXn2Oxu4JVjTPp0gPR5RlIAIpsTF + W4woecTAkHlA8H2YSEhp3S+f9ac0YLIKu+J4QnECInis05CRRgoUFUsXsatk+d91s3qQrHglcfh2J3k5 + TjygSAERvBqrN/+0qDsmuPjsnpzufqe4SlVq98sHW+hHwWH8cYJiBWR4vTBW+QC0q5aTQoWLIV14Kgy7 + X/+dH0oHYxRHJ+W7TiFWKFvAlzgG+qF9725SqnBAmfmfe7d+iKxspZJ6VR93XbEqBERw3xYTB+GVq5Rc + 84GtKGZw5X/m7i9byYpWMiX1yj3fEQmqEdAPXjzdmZYS9km7ztQUweItZrRXS/fLB1PFBacAVjOqExDB + QAZTXS3oNm8KWcSx8nuCzyhrGCYrWA3svaSbEcavVlQpoB+8zRzD/Nni9RzZ+bHb5i8+I3jjJVW5auH6 + s+AUwOpE1QL6QRHHH9wHTK9GCYjHAPjdL+ZnUWP3ywez8WMIGf93UCNxIaAf7JoxzMqQkS6YrIzcLRa8 + rqJp+sZLNbPrQuuM2EG1EVcC8sEFZ7y5qX3vHnCNTt/jhssYwTdeqhU8v3LxoTpOv81G3AoYICgnCna/ + y7LV3f3ywWdp6VFvhEz8CxjEA+0oWZFqZlO+FuxOdXbFCSUgpsjdFyfdbzD5Fd3kMyudhBIQb7zE2SNV + gWoHD9RbHMJE6GogoQSc7cJpNYORMkeKDWAKSv2rFhJKQLUvPgezuaAZ6g3GGdn31UTCCBhP3e/q401Q + XDuk+jVAJGEEfNYW2oXTSgYDEc7e74mrEP2EERCz01OVqgaw5T77oAfGFgJS1YnF7mbXp1KVq1RwlyPp + tBauPO5X7QQjFBJCQDzaSFWyEsFuFtcqn3JDhngJuZqLhBDwXGWvoo9eYuuM+QFxYoFbhWqe1YZLQgiI + LQmm38AYuj0XdWxMJVciSgQPnK862ggZNzrY1uCIyZlQ0vFJmEkIH7PNza7iuvy4D1IK9UzIWLaQeFEh + 5no5dKsT7tQNsav842EJRQwSUsBgMBUazjDxdnTsBvPKu1nr9PnlNkjO18LKow1zRtCgwHhsEs8YY6gX + ioY3pZc1DoOGEz04ydAC0ywIOAfYLWL8oMc7P3jrkZd7fXBevwXmZkHABWTkK/h/lpVQcZb35PwAAAAA + SUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vwAADr8BOAVTJAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAAAB1YSURBVHhe7Z33 + W1TX1sfff+h9403uzc0tuSVvck3exN5rNPYSa4wmVkTALioCUhQFpKkgiCC9987QGdoUmBkYRIo/rnev + PaIz4xqnnTlzzsAPn8fnQZhz9lnf2Wettdde+79evXoF88zjLeYFOI9XmRfgPF5lXoA2mNCrYWKwFV53 + lcHrliyYrH8Kk9WPYLLiAUwVhbynJNz0c/b/+HuvO4rgtbIOJob74dW4kfzsed4z5wU4oVPB654qJqIE + mMoOhJmEnfAmcjG8ufsDvAlbCG9C/+MC7O/C/49/xkz8TzD14jxMFYfBa0UuTAy1wSvjGHkvc5E5J8CJ + 4T42U2XDVM5lmHm4kYnke0JAHiTsWybwJTCdcQYmaxJgYmSQvM+5gu8LkL0G8VWKr8mZlJ/FF9zHYDPs + RH/ju3sdZzR3KGFsbO68un1WgBNaJZthEmEm9kfTrEMJwMvM3Ftl4Sd2KYfgz2vPwdfbLkJQRBoUV7fC + 8IjeYly+hm8JcEzPgoBimE4/BW8iFpFGlxLT6Sct7j+joBY+WXbyHQuWn4K/b/SHUzeToaqx0ydnRt8Q + 4OgIj0JnHqxnhnU1cBCfydoki3GcvpVsIUBz/rDiFCzedx1inhaBclBj8XdyRt4CNGiZEVNg5v4a0sCS + hrkFE+rud2MxGsfh31sCSfFZ85f1fnDmVgq0dw9YPg8ZIk8Bjun47IE+FGlcGTATu5mNZfzdmDD4+HTF + aVJwtvh8zVk4eikO6hU9MD7+/rPkhLwEyBx2TAxjbo0yqpyYyrpgMbb4jFJSZI7w2crTcDDwIXT0yC+l + IxsB4utqOuO0ZCNaZ5lsem4xvsNBsaS4nOEv6/zg6r0M0Moocpa+AI2jMFkRw5O3lCFlSfh3MKEbejdG + vWEM/rrhPCkqV8A0TmpOFfcrLZ6lBJG0ACc0PTD95DBtRBkzk7DLYpzVTZ085UKJyVXw8/b7x0g+Ypam + AJlD/br5BcxELScNKHem8oMtxns3MZcUkRD8c3MAPGWzoVSDFOkJcHQEprKDfMbXo3jdlm8x5m2nIkjx + CAXOhhgtD+sMFteVApISIJYwzSTtJY3mM9z9nn/JZseMAcPna86RwhGa5T8HQ3NHn8Uz9zaSEeBEX8Pb + lQzCaD7E9OODFuMurGolxeIp/saCnWd5NRb34E0kIcDXrTmyWLsVgqnSSIuxX7v3nBSKJ8FlveAHLyQR + JXtdgJNVcTwtQRnL91jIi1/Nx7/y0C1SJJ4G/UIscjCMerc41qsCnKyM9elg4wMil1pUQ/cNauCzVWdI + gYjBAsaus9FeLfnymgAnK9nMN5fEx5hO/93iGTwvrCOFITYbjoWCWvs+MBITrwiQv3bnmPgQLJA1fw5n + b6eQgvAG64/dAY1WZ3F/YiC6ACer4uek+HDMEwMt757D+Pgr+HbHZVIM3mLziXDR15FFFSAmYPluMcpA + Pg7WLJqXXym6+p0uvxIDTIqP6MVLWIsmwIn+JngTsZg0zlxgKivA4nkkZpaRApAC+y/EwKhI5f+iCJCv + cDzYQBpmrvC6OdPimeDSGGV8KYApmivRGXyXnvk9ewLPC3BUZ9oOSRhlzsDcDtylN/tMxoxG+HKTP2l8 + qYDJ6oTnpZa29AAeFyBWfpBGmUNgBbf5M6lp7hK8/MoT4BbRsro2i3sXGo8K8HV7wdyMeK2Yyr9h8Vyi + UvJJg0uRr7YGwoBKa3H/QuIxAWLLCTlvGhKOhbxhkfmz2X3uHmlsqbL3/H0weqie0DMCHDfC9LMThDHm + IBGL4JX+fVUylt//WaTyK6FYsPwk3HtSYGljgfCIADHjL6cN4p5kmgVg5s+msKqFNLLUwQ1PjW29FmMR + AsEFODEyAG98tJTeFazLr27EZJIGlgPrfrkjeGm/wAIcN5XTE4aYk4Qx/6+31uIZbToeRhpXDuCr+EGq + pT/rLoIKcEJZPx/1mhO1jDdMmn0+mmEdfLbSe+VXQvDPHwMEjYqFE6BxDKaT9tGGmKNgIGb+jF4U1ZNG + lRsnriVYjMsdBBMgtp+dn/0ssS6/8rvzhDSo3MBVEkymm4/NVYSbAceNMNmUwZvuUMaYc+Dy26Di3fPB + 8qul+2+QBpUjP52MECQgETgIYbBXMe9MGrOWNswcAcdv3v20t1/NZw7KmHLkD8tPQVldu6XtXcBtAY7Z + +hYw5xtTEDPRK0gD+TrW5VdJmeWkIeXM5hNhbs+CbgkQl2d+K2yBm9Wd0Gdj1z2etzGVd9109AFhKF8F + zwwxfw6HL7rf/UpqYEFFQeX7Km9XcEuAdYPDsOhJJXz/uAJWpFZBVH03qA30Nr8JTS9MZ/nPjYroiEUw + oX2/aoC9nf/3pyDSiHJnx+ko7t+a29oZXBYgzn7HC5q5+MxZ86waklr7YHiUrqjFIxOmn/0mv4gZD63B + g2cerIeZ+K3vwbNGIpea/v/t8uNM3BaLMeMSli/5f+Zgc8w2N1oFuyxA89mPYmNGDTzvGAQ9tfueiXei + twamUw68NRxhcG/DviB4xMNUziWYrH/CZ/BXhmHm2zJXA/f2vmOU93rBqu/XbXkwVRjyQfpFTuVXroC7 + +8zH6wwuCRBLtf1KFKTwrNmRVQ+FvSo6WMGWu+2FMPNoh0SEuJBHr1hEO6HqMAnM+p5d4HzoU/hi3Tm+ + EZwyoNz5x6YLLu+mc0mAvSMGWM58PkpwFD8wDuc1QfWAlvYXsAtqY7rpdUYKw9Mw4cVu4kc94BaCD+7P + TXDMuHwVm1YMa47cluRuOHeJeVpIjt0eLgnwXkMPKTR7LHpSAb8XtUCLeoTe8MKMj/uGxTx2YSZqGUxW + PrRYs/Uk6DuX1Ch4UQLm0ihjyhEcjyspGacFqGMRHfp3lMAcZenTSggsa4OeYRv7T/UafgwqLuZTohEE + 9srH9r/YBpi8Bw+DG5NeljTA8gPBpEHlxuerz0LfkPPtgJ0WYEW/hr9SKWE5C6Zubtd0wpCeOfLEtdCx + n8q9InzrtrDvYKo0yhRAENcVE9wE7s98RLlXySDhCbnkGD+G0wIMLG8jxeQOmLqJaeyxnbpRdcJ05jlh + cohMzJMNaeR1vEk2mw2x1IkyrFxYcyTE6b0jTgkQk8yr0qpJEQkBvtqfKPrBYKNxInZXmE79hc9gpLjs + wcSHZwVTny0FMJ/27U5p9YtxBjy5aVA9TI7NFk4JENMplHCEZvuLenjZNWTz2/S6qxxmkvY4l7oJ/45H + 2tTnSQkU4fe7r5IGljqYZsKO/NS4bOGUAK9WdpCC8QToZx7IaYRSpZq8F36UQ0sWX3UgBWfBQphEn4/6 + HAnS2TsEX22V59Kds8WqDgsQX4vr092Lfl3hhycVfMmvfsjG1I45xNrkj5Z/TT85IlhSWSzwsOo/sciS + MrKUwdnbmcZGDguwSTXCxUCJRAxw2e98qQLaNTYSxZhDLIv+IHUzE70SJrTSOprAUfAAG9wIRBlaquDa + cE+/ihwPhcMCTGrpI4UhNouZEK8xVwBXY6j7fIXlX4Uhb1M37NVb/Yj+PRmAuULs4UwZWqqgH5iWW02O + h8JhAZ4pbiUF4S0wmR1R1/2RHGKfaU+uBHJ97tDUruTRJWVsqXIx8hk5FgqHBIj+H+bqKCF4G0wLxTcr + beYQfQG5bWba8ls4OQ4KhwSIfheu41ICkAqYQ0xtG7CZQ5Qz/UNa+PtGafcTNAd7Xzt6/ohDAizoESf/ + JwTbXtRBYa+N1I2MCQhPJY0tFdD3w6Lbf/0YABt/DeWb8KlxWOOQAF2tfvEWd2qE2bMqJbCpuTcPtZkF + K3i+WOsHi/de5131/UKe8ILboqpWGNKM8JnPmaoYhwR4VmIByMfAAgeVjX0pcgYj4tWHxTnWC0X26crT + 8M22i/woscNBsfxsOVzl6Ogd5Me+4j4X8j5HR0Hd0wMDbY51VnVIgN5IQLvKpQr396q6wvhb33P2X09w + NymPFIwrYH4RhfYl8y0X7b3GN5oHstc8FpZWNnSAis1mesMoWUCMM9yIagj6FQpozsuD/MgIeHLuLISs + XgWB//gS/P70GVz//juHZkK7AsT6v9UeLEAQEly+w3IxahyewtZDHmcz1rjABwE2KHqcLmLFrZOYxlnI + AoNVbDY7fi0BbsVmwcvSRp4wxlJ6W6dmGkZGQMVms+7aWqhISoLMa1fh/p5dcPmbr+HC3/4CZ/7wCZxe + 8D9w+pP//oBLX3/F/576XHPsChATvkue2t58JCUwEra5Ud4FjDZyjN4CHXuquz6KbDYAwKWw3eeiISgi + DeIzSvmOPNwOYLDhlhjZK3N4cBAG2GzWkJUFeXfDIfn3E3Bz6RK4+NW/4NwfP4UzNkT2Mc7/+U+g7e8n + r2mOXQHyJTjC2FIEq6ypMbiK8e1me0++Vp0BZ1ssff+a+WbrjobAqeBkCH30km8O71IO8dmMmpHxZ3qt + FtS9vdBRUQ4lsbGQcekiRPy4Ga5++x/w/+sXLonsY+DnDXbYd4fsCrCiT0MaW4qkKIRd87V+hUpBiHi0 + qs0AwGCAkSHmm7W2Qm1GOuSGhULc4UNsNlvMZ7Ozny4QXGi2wOsoiu03s7QrwDyZ5ACxUKKZzdbUGHwN + 9K00fUpu4JLYh5AWcAHCNqznjr8fe/WJJTJ7lMXHk/dvjl0Bprb1kwaXGuinjgro/yHjLAqkfu5N8FV6 + ZeE3Hw0ApAL6k9QYzLErwNgmJWlwqbGBBSBGN3qUUIwzB536uSN46nU9qtdzv40yuNTIuRNCjsEcuwKM + rO8mDS419r5s8MjhephOoX7+MTzpK+L93F65nDS41MC0DTUGc3xGgEfzm8j790VCVq8kDS41Mi5fIu/f + HJ8R4KHcJlGOF5UCYRvWkQaXGulBgeT9m+MzAjyY2+gxATqypIQIvfJBwu4lZJU8ZsD0i0H0GMywK8D7 + jb2kwaXGrqx6r8+AYggQVy5uLltCGlxqZAVbnhJKYVeAyQpp7AWxx7LUKkGX4ZxFrCS1YXgYAv/5JWlw + qVEQGUGOwRy7AnzROUgaXGrgrjmlrY1KbjCuN/AludlluQ/+X+TVEZ1a9b4QgDC6lKhITiLHYI5dARb3 + qmWzFpzTPUSOQQjMk9LeXJLTGYyQX6uEstJ6KHyUCJlXr8C9ndsheMliU+GARISJqzGN2fbboNgVIG4I + p4wtRYKrO8kx+BLFTYOw9Hw+Z3VgIey8WQ5XU5rgUV4HlDUooTSnBPKio+HxmdN8ee7Kf772yqrJmQWf + QGeV/TYddgXYqdV/tBe0lNjvoWS0lIjMbIMlfvk2We5fAOsuFsHRiCoIS2+FtJJOqKzrhOK0TMgOCYHY + gwfg1oplEPDl3zy6Znzm0wWg6u4mx2COXQFiR6yVaY634/UmuGndE36gVMDq5AOhlaTwPsZSxuqAQth0 + pQT84uohJrsNciq7oLqyGQriE3nCOGrbVrjxw/fg9/kfBRFmIBO4Tm1/c5hdAeL66mqJ7gmmiKi3/62T + K70qPay4UECKzBXwNb6ezZY7gsvg2uNmSMxrh5IaNmMWlENORBR/jd9Zuxous9e4s6Vc175byJcNrcdg + jV0BIthgnDK2FMGu/M42SZQLcXmdpJCEBGfLFew1vpnNlofDqyA8QwFpRe1QVdMGpRnZkHkjGOIOHYDg + xYsg8B9/t+lfhm9cT47BGocEiNscKWNLCdw4j+3cMBL2RT9wjEXe+0IqSNGIwWzQs+1GKZx9WAcPc9oh + u7QNaioaoDAhGdICAyBiy48s6PkGzn/xOaScOkmOwxqHBCjlmkDsEYPn1eEREEKXY0kJXVcndPSo4PqT + Zh5kUCLxBsuYMDdeLoY9t8v5vaUUdEBReSv099rfD4I4JEA8FUlquUDc/3uxvM1muza9Tt5NicwZVamg + bPMGqNy1HXqfPmbGHYTY3A7Ycq2EFIW3wdd4YqFjzQEcEiBu9EaDU0IQm7UsILpb102ezolFA70dQ5AY + WgDXjqWAztYxEDKj4340FC1d9I6yTRugPSIc1F09kFmphJ9DK/hMRInBG+DruqXHsV7RDgkQwcV+ShBi + gLPvlsxaSG7tAw2x4I/7WhX1vXDvUhb47YyFc9sfctIfln/wu3LD0N8PpRvWWghwlpLVK6A5KAA0TY1Q + 0TIIv9+vFTRKdhV0EbQ6xwozHBZgWK34gQgGFj+zwCK7awhGieUv3B1WXdQGd848A78d74U3S+D+R6Ae + lPFGJaMRmi6cJ8VnwbLFUHf8GAwVF4GiR8NXRlYFFJLiEIO9LFhy9AhXhwVYrFSTIvEEmFA+WdTCuxxQ + Ea1BPwqF6fVw4/jjD0RnTcKdfIfr+aTGQG4OFxcpOgr2u5V7doIyLRWU7Nndy2qHDZeKSZF4kmAWjFDj + oXBYgIPM6J72A5exiPZyRTs/S466B83QCGQ+qoRLBxNJsVHgzFie496p3t5gpL0NStevoYXmAOVbNkFn + zD1Qs2j0SUkP7LpVTopFaDAAKWocJMdE4bAAkUO5jaRw3AW7r4azwKLfRskTBhYpEUXgvzuOFJk9gvYn + 8M+gPluKjA4NQeXunaSwnAX9RMXNG6BtbYW8ugE4HlXNAhbP+Ylrgxz3/xCnBJgoYKNyDCy2ssACPxMb + IFlfC1+bLbU9EHM1m/TvnOX2qTQY1ohzIqY7jKnVUHP0ECkmdyhevgQazpwCVXkZNHaqISihEVZ6IGA5 + crfKqYUApwSIlTHuNipC4R1gMykGFpSjOmoYg6rC2cCCFpOrhJ57BsNq4c8DFgrDQD9UH9hHCkgwmJ9Y + tX8P9D3PgL4+Ndx9ruCJZEpMroDLhdTYbOGUAFHZ+3IaSGHZAwOL08WtUNWvJb8hI0zcBSywuHo0mRSP + UKAI1cyXtL6+FMBIlhSNh8DkdlfsQ1D3KCGluBt2u+knYgqoT+3cW8YpASJPnVyWW5FWxZtG2lqxGFRq + 4HlcBQTse0QKxhNcOZLM84bU/XgD1Yhp1UDb1AQla1aSYvEk6Ce2Mj9Rw/zE/PoB+NVFPxGLFxxNv8zi + tABxBcKR4/qxVUZobReoiP4qeJPdigFIuFPgcmDhLnjd3Ke1YLTRaUoMRo16KGyJgHv5P0KPqo7/bCDn + JRSvWEoKxdPgdRvOnARVRfk7P9GZfGJCgfO9uZ0WIHK2hO4Zjf7d9hd1kNjaB3rCsMaxcWiu7oboiy/g + vNmKhddgPmb4+QxQNCid/ua6S4+qBpLKjkJk7jpOXPEe0OpN7eU6oiJIgYgG+on79kB/VibzE1UQmq7g + 5VmU6GbBSplBrfNLny4JECtPzM+Nw5J9TNHkdg+RWyMNulGoKlCwSDRV8MBCCHD57sG1l9DdNsijb+v7 + F5Kh4Q7Irr8K0Xkb34lvlscVJ9isqIPxsTFoPH+OFofIlG1aD13xcaDu7YPkom7YebOM5/qsBXgu1jSD + O4tLAsRlsV3Z9TxxjIEFVstQpVCY9ihIb+A+F2V4qYGzMkbfmLjWqoSLlo3GUegeqoEXdZfY63bTB8Iz + 52XDdRakjcOYRgNVe3eRovAG6Jua/EQFFDQMwC8R7/1ELD6oaHUtz+qSAJEaNgt2DevJiHawTwsZceU8 + AUwZWg4EsqAoMjATCtkXqL2pD1QDw6AbMTg0Q46PG2FYP8BEVw1FLZEQV7SHiWv9B2KjiGK/V9Vh2k+r + 6+zgMxAlCG9RvHIZ1J/+HVRVldDQroIL8Q1wMKySF8xaPwdHcFmA1qBhuhWD8CgkHy7siSeNKluY2+C/ + K44vAWKaCGf0rtYBPm6NrpcJJhEqGYUtdyGt6gzEF+9lM91mUmCOEJ23CToGSvnnD5UUc6NTYvAqzE/E + nCWuV+vcOJfFbQGOjRp5YIGzhSQCC5HAVRocf1t/ISkid3lYuONdeqYnKcG5ogQRqf/9BG+YZK4JZ3Bb + gMl3iwRZKpMbnhYgklh6GPRjWr67rPnyRVIAXoV9KYZKSj7QhDO4LcC2xj6LItC5ghgCRDJrL7IAbwyM + uhGoOSL8GrE74Jq1O7Mf4rYAsRo5KugFaSRfRiwBIiWt99m1xkGvVEL5ls2kGEQHZ7+iQgstuIIgQUhb + g3LOvYbFFCDmDFv78vj1NDU1fOmMFIWI1B476vbshwgiQD4LsiCEMpSv0lprWksWQ4DI/YKt0K81FdYq + n6Xy8ipKGGKA19bU1VpowFUEESDSpRiYM1EwzvadLaY0TLMymxSMJ0goOQC6URWfeRS3b5LiEIOmAP8P + 7O8qggkQeRxZTBrM1zAXYFPvC1IsniKt6iyMGQ38DBNMgVAC8SSl61aDzoGuV44iqAC1ah1cOphEGs2X + 8KYAkYJm0wlEWLpfsf0nUiieojs+zsLm7iKoAJGi54185YAynK/gbQFG5W2A+u50fv0RRatbm5ecofrg + foc6XjmD4ALEgCTiwnPScL6CtwWIROdvgm5VDb+HgbwcjwclxauWg7ZZ+MOABBcgMtCr4ZvCKeP5AlIQ + IBJbtBM0OiW/j67YB55brlsm/Kt3Fo8IECnNbmaGog0od3DlZ3abZ0PPc1IcYpFc/gsYxkZ4ZNzo70cL + yE3qfjvOPt8zleMeEyDy8EYOaUC5gwLs6za1n63rSiWFISZY4IolYMaREcF31WEjJFyBsbatUHhUgBgV + Y5cqyohyRmoCRMrbYvn96Lq7BKshRL8P94eY21RoPCpABBPUYu54EwMpChAj47Z+0xH5KBq3awhZUNPz + OMXClp7A4wJEynNbuONOGVOOSFGAyP38LTA43M7vqycl2fWghP1da/B1QdZ67SGKAJGM2ArSmHJEqgJE + EksPgX5Uw8XTcv0qLTA7NJw9DeNj4nSYFU2AuP82NjiXNKjcQAH295gEWCsxASLpNf6mGkK9Hmp/OUKK + zBZ1J46BUSde+xLRBIhg3xfcE0wZVU6gOzHb+LK6M5kUgbcpbo3m92fo6+Ot2iixWVNz+CCMOnC4jJCI + KkAEd5bd9c8gDSsXzAVYJVEBYlDS1JvF71FTX2e35QcXn0plYSsxEF2ACKZnQs8+I40rB+QgQOR+wRbo + 05i6lSrTn9kMSmqPHRF95pvFKwJEcNO6XGdCuQgQiS/ZDyOGIR6UtIWFfiDCuuO/8E3w1vYRC68JEMHX + sRz3k8hJgEhq1WnencFoMEDdb7+axMeE2Oh/jgcq1nYRE68KEDHox+DB9ZekoaWK3ASIFDSH8ZYfvP3v + ru1sNrzDe9BY20NsvC5ABI9byIir4IalDC5FsKEm3jt2RaAMLjWw5Udddxq/Z+7viZBkdgRJCHAWXDGR + S1sP/YgpUVvR/og0uBR5xPzBMaO0+mRLSoBIZ0s/XD9m//wPbyMvAa7ne0mGDY4fnyAWkhMgMqI1wKPb + eaThpYJcBIh7isvb4rj/Z/2cpYAkBYhgx9IK9koO+lmaLd7kIMDYot28RZz1s5USkhXgLEP9WtPyncSq + q6UsQFwFedlwA3QG8Vc2nEXyAkSw9yC2+L16VCLFrezLIFUBYjWM1Gc9c2QhwFnwEOrU+6Vej5SxA8Ts + gdilihhSCGKDtYBlbQ/BOG66L7kgKwHOouxUQfytXN61lBKIp5GSALHndHb9NVDrTM2S5IYsBTiLsnMI + 4m6KL0QpCBDb+GbVXeFd962fi5yQtQA5LFrGLZJ4LrBYTdG9KUDsPZ1Vd/mt8KSZWnEG+QvQDCzzyk6p + 5jvxPLknWXwBrof44n3sWvdBq+9n15W/8GbxKQHOgpXXTVXdgB37Lx1KEjyFI5YAcbbDrvu42w07YlmP + 0xfwSQGag+mShvJOHrTg8Qq4n4MSlTNgFI6nP+HnY+k7JR5XiSn4iZdP1XY99bnZjsLnBWgOzozoL758 + XAORAZlw8UCiS4I0F2Bh811SSI6CS2W4YvGC+XWtffmySB4LyZwSoDU4O/Z1qaC6qA3SYkr5WSeX2Ssb + l/8+Flm7KkAUW0zBNkgp/5X9XTh/tWL6BHewWd/bXGFOC9AWWAyBHb46mvu5OIsyGyHzUSWvWcQusJgM + xwN68HdLWu8xUW19Bx7LlVB6kPtuOQ3B3EdsVr6EXnU9qEe6TY2ErK43l5kX4DxeZV6A83iVeQHO40Ve + wf8D9K3wZLcbeP4AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vwAADr8BOAVTJAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAAAB6MSURBVHhe7Z33 + WxtntoDvP3TvJrvZdrfd+2xukk11TWJc4rg7LrFjJ3E2brjXuBtTbHoxBkyxwZjei+hdCESVQI0O+fHc + OZ8YWaADzIxG0ozQD++TJ7sxzMx5/Z2vnu8/JiYmIEAAXxEQMIBPCQgYwKcEBAzgUwICBvApAQED+JSA + gAIYHx8Hm9UKVpMJLCMjMDo0BKODg2A2mWF41MowmmxgsoyB1TZO/owANAEBnTAZDNDX1gqNua+gODIS + Mq9chid798CdNZ/CrY8/gmvv/hMu/+PvcO5Pf4Dg3/8OHt2MhA0XixhfXi6GrddLYPftcjhwvxJ+fFwL + N1OaIbFQC0UN/dDVb2Kijo+7/t7VzKoV0GaxcLK1QXVaKmRcugj3NqyDS3/7K5x+67/g1G/+UxD3roTD + Z8EFglhzrgC+4CTdf68C7qW3Qna1HnoGzeSzrSZWlYCYOlsKCyHtXDBcf+9dOP32b0ixhCJGQIrguHrQ + xsZAZ0Q4DNfWgM1oJJ/bn1k1Aj799wm48Jc/wykRLdxKuCtgYn4nVB/8BorXfALFaz+FsqAvoDH4NAwU + 5IPNMEy+h7/htwKOmizwsqgO0nKr2b+/vHmDlMgd3BFw7blCqKvrgpL1a+wCLqJs0+fQdPkiDFdVwrjN + 5vJ+/oJfCYgd/Po2HVwOTYe/b7sAv1n7M3y49zrYxsZAV1fndspdjDsCBl0tgd68PFK+BXAtY+XuHaB7 + lgyWgX7yvdWMXwiIguWU1MPm7x/Cb9efYuLx4L/Xt+rYoOPGB++TIknFHQHPxNRB2/27tHRLUPr5eugI + ewQWvZ78DmpE1QKaLVZIzq6ETw/8Am85SbeYK+EZ7L/PvvULKZJU3BEwgev/1Rw+SIq2Eihi+8P7YOnv + c/kmakOVAo6NjUPKqyp4b9dVUrjFfLiPS8M2Lg3X18uahqUKiFMytXXaJft/Qin9ciNo42NhzKze6RzV + CVimaYeg4w+WbfEW8/b6k9DA9Q3HrFYuDb9HyiQFqQLifKC+oICUSgqVO7dD/+tcmBhX3yqMagTUDxjg + 2NU4JhMl2UrgwAR/jpxpWKqAp6LruBT6gJRJMtxgpeHsaTDrul2+nZJRvICYbpNzKuHvW+2jWql8tO8G + WLk03NPQIFsalipgPNf/qz1ymBbJTTAt65KTYJwbmFHfU2koWkBt7yAcPB8Fb62T1uo5gy1nXUs3C8zN + f31ACiUWKQJi/6+mvtvt/t+ycK1h/cl/g6VP+YMURQqI83kviurcbvUWcyEkjf38V3fvkEKJRYqA2P/r + k7H/txzl2zbDQHGRy/dVEooTEKdWroZnSu7rLceHe+fTcGMjnPntW6RUYpAi4Gns/4XI3P9bhpJ1n4E2 + LkaxqymKElDXNwRf/fSIlEcO3uZSeU2Tlu3vu/XJR6RUYpAiYEKBFmqOHCJl8RhcSm66eB5soyPkd/cl + ihGwsb0H3t1xhRRHToLvp7Df9/rBfVIqMYgVEPt/mgau/7fOg/2/peAk1KU8c/nuvkYRAhZXt8Lftpwn + hZGbf+29ztJwrwxpWKyAm64UQ39hIS2Ih2m6dIHr3hjgdcNtGLUMknHwBT4XMDW3Cv745VlSFk+AI+rq + xi42aXtnzWekWEIRK6C3+388dT8cB6vJCNl11yA8bxM8Lf8ORszKGCH7VMCn2RXw2w0LNw94gzN37ako + LySEFEsoYgVk/b/DB0hJPAXupMFdNEUtYUw+noTSg2Aw9bjExNv4TEBcy/WFfMgHu6+xtWF9SzOcflt6 + GhYjIPb/6uq1bFRKieIJyjZvgtGOdqjvzoSIvKAFAiJxJfthaJTLBkR8vIVPBMwoqIV3Np4m5fAGmIYr + 6jrYs9zlBgSUXEIQI2DQVa7/V1REiuIJSjaug6HKCugcKIeI/C0u8vHEFu+DYZPOJUbewusC5pY1+lQ+ + njP37Gk4P/QRKZcQxAh4Mgr7fw9JWWSHG/HqszJgYKQdogq/JsVzJqH0kM8GJl4VsKVTL/vqhlT+b9dV + tpEVT8ZJXRsWI2BcfhfUHPJC/4+TryvyMYxYBiC+5AApHEVq5U9gtZnIuHkSrwk4aBiFj/beIGXwBZiG + S2ra2LPd37iBFGwlhAqI/b9qtv9vLS2NjOA5Eot1BJ5V/ECKthwvNJdgfNy7KyZeEdBitcHOk2GkCL7k + 1J1k9nwFYaGkYCshVECc/+srKSWFkZO6Ez+AzWKCl5rLpGBCyG+67xI/T+IVAYMfpJIC+Jp/7rjMtnsN + dnXBaQmT0kIF/OlJLXSEh5LSyEXV/j1gHR6CwuYQUizhBEFTTw4ZR0/gcQEzuRGvHNupPMFb636G/Iom + 9pwhm4NIyZZDqIAxr6Wf/xBCxfatYOrWQm1XCjndIhYcuAyOdLrE0hN4VMDOngH4q5eW2KTy0y9J7FkL + H0eQki2HEAHZ+Q9NF5RsWEfK4y54fthQp4FWfQFE5G8mhZJCcsVxsI55flDiMQHNFhs7JkkFXUn8z1cX + 2Wh4uKcHzvzubVK0pRAi4OarJVz/r4SUx11wU2vfqxzoGa6HyIKvSJHcIb/xHhdLz54z8ZiAj5LyyIAr + kVelDeyZQ7/aSoq2FEIEZP0/bpBDCeQOuKLSnRgPw6M6iC3eSwrkLtiidvaXu8RWTjwiYIeuH/7kxQ0G + 7vLDjQT23MWRT0jRlkKIgNj/qz64n5TIHVpv3QSTeRCSyo6Q8shFYulhj6Zi2QXEUeW+4CdkoJUK9lOt + NhsM63RwVkQaXklAtv6r6YTSjetJiaTScPokWM0jkFlzjpRGbsraoshYy4HsAmYWaBQ76l2O7JJ6tlM6 + dJvwNLySgFuulYC+WN75P6ymZTUMQ17jHVIWT4D9y8ER+9q53MgqIFaken+3sGoFSuP4tXj2DsVRkaRs + FCsJeOKxvPN/bLpF1w1VHYmcGO5Pt4gho+Ys9xdU/qOesgoYm15CBlcN/HfQOXYgariHS8PvCEvDKwnI + +n8H9pEyiaX0iw1gbKiHVn2+rNMtQsH5Re2gvdSdnMgm4LDRxKY0qOCqhexiLg2PjcGjLZtJ4RaznICO + /t/n7vf/cMSLpTd6hxvgScE2UhBvkFLxo+ytoGwCPojPJYOqJr6fT8Ml0dGkcItZTsCtXP+vV47137Wf + QndSAhhMvWzvHiWG9wiCzv4yl9i7gywCGkZM8A+Vt37IXzafA5OZS8M4Gn7nt6R0ziwn4A8RtdAZEUZL + JYLWWzfAbDVAUtlRQgjvk1Ipbysoi4BJL8vJgKoNXBvGSWlMwyFBm0jpnFlOwKjcDq7/5978H0632Gxm + r023CEPeVtBtAXGrFRaIpAKqRvjRcGlsLCmdM0sJ6Oj/cQMHSiwh1Hx7CGwjRnaMkhbBd6RXn+G+kTxL + dG4LWFDZrMp5v6XASemRUTNbG8bLaCjxeJYScOv1UuhxY/4P6/2Z9b1Q0R7HBdy70y1CwDMmcp0jcUtA + nLjde+YxGUi1gmkY603ju620RWspAfGWpM5waf0/PMk20trC9uT5YrpFKEUtoaQTYnFLwL5BA/zxC/Ws + +Qrluyux7P3K4uNI8XiWEtDe/xM//4cn2bCalXagEh7nbyUDrxRii/eAbczi4oRY3BIw+nkxGUC1gwen + DCP2NHzuj78n5UMoAbH/p5HQ/8OtVT3PU9mSV3TRLjLoSkOOndOSBRzjUhTWaqYCqHYwDeMlN1i+I3Tb + FlI+hBIQ9//pSsvZ/B0lGgn333aEhrByGWJOsvmazJpg0g0xSBYQt1wtvpPDn/j2Ugx7z/KEBFI+hBLw + WFg1OxZJirYEWDrNYjFCWtW/yUArlScFX7m9VUuygJGpRWTg/AW8aQkn2JdLw5SAj7PbRZ3/0Bw/CtZR + I+TMFw5SG3gUgPJDKJIF3HfWv0a/i8E0nFWoYe8atn2bIAGx/1ej6YKyLzeSsi2mctfX7LKZ0tYnZHDV + QG79TRc3xCBJQJx8/nNQMBk4f+LQhWj2vhVJSYIEDLpaDN2lFYL6f+VbNsFoexs06F7IcpLNV8QU7XZr + aU6SgEXVLayFoILmTziPhoP/8M6KArL+X9QTUjhnSjasgcHSEugaqIDHyxQOUgdB0DPEDdgIT4QgScDb + 0S/JgPkb+JcMq/XjO0fs/HpFASNetq98/wfXOvY+T2PnbtUy3bISeB55sSNCkSTgfpWd+XCHA+ft5yEq + k58uKyD2/6o02hX7f1gha9QywApEUsFUI1h5dbEjQpEkoLfqOSsBTMPGUTMYentd0rCzgF9eXrn/13g+ + mFWgSqv6mQykWokv+Yb0RAiiBezqHYS3/Xj+bzGYhjPya9m7R+zasaSA9v5fJCkeovn+GNjMJsipu04G + Uc1E5G2WXF9QtIBY64UKlD9z4Fwke/fq1JQlBQx/2Qa1x46S8lXt2QmWgQEobokgA6h+gqC9r9jFFSGI + FvBOTA4ZJH8Gd0pjGjb29y9Iw7yA2P+r0HSziwIXy1e+bQuYurqgrjtD1dMtdoLY6gduRHhedZJV4qrX + ZbGzKlKLW4oW8MTNRDJI/g4WVcf3j9q/z0VAvP9NR/T/cEPCcHUVax2UvLXKlSB4XLCVnUFJrTwBBU0P + oE77nIk2Yu4n5/3GbNLmAkULuOtUOBkgfwdXfvD9a9OfuwhI9f9wrq8vJxv0hmZBdZp9Ayda/hYmGlZU + zWu8BzVdz1ixI6O5D8bGrS7xt1psMDwwCp3NfVCa3QTPI8vg4ZkMiL2d5/LfCkG0gO/u9Px1WkoEV35w + Unp0aMiRhnkBsf+HgwyHgFxLqI2JZvdweKpwkDiCWAuMz4Jl13Cbf1VnEuiGalmLZhtzvfIfWzQUTdvW + D+W5zZAZUwEhwZlw41gynNsbC8G7Y+DsrjdcPpTo8jOEIEpArPuCFe7x0j8xV+b7C3j4Cr9DzOFDCwQs + w/6f0/6/lpvXwGwZhuTyY4QMngX7mbg8hr87p/4GVHYksKsaUDQrIdo4F1PDkAm62wegKr8VXiZUQfjF + l3D9u2Q4vy8Ozi4SbSnO7Y0D86hri7kSoltALDbepu1jy3HxmWVwP+4VXAnLgO+uxMG2E49g/eE78PH+ + G2w3ye84WfG8iL+cGdlzJoJ9g9r0dIeAGy8WLej/1Z/8CaxmI2TVXiAFkQsULapwByfacXhZd4WdH8G+ + JqZOu2iuh4ZGhs2g6xiAmuJ2yE6shshrOXDt6FO4sD9esGjLgRIv/p0rIVrAlRjnwFuIsMwFjhx7BwxQ + 09TF5tIinhXA7ehsVhwcz5JsOv4A1h2+zWo1/+GLM6xV9cQ9wXLxp03BYOTSsNloYFu0UMBjYTXQFR3F + 5Kvev5fVacZOOyWNFFA0HHni/W4odXlbDLT05rGD6pg6xwnRTCMW6OkYhPryLsh5WgNxd/LgOifaxW8S + ZBFtKfD3LX6WlRAnIDf6mdJWwKS+HiaHtTBpHma7hsn/ViCY1vH2Sl5YvEskv6IZ4rPKICTx9XzrGgs7 + fg6DL4/dh4/23WDTItiq+mJDLLb6+NxxR79lAoa9aGPV6bFwkFmnY514KdMt+GfwHAgeQMdzwKVtkWzL + ++BoFzt7QY08LWYb9HYNQWOlFnJTaiHxfgHcPPaMiba4j+YNKl63uDzjSogScHK0H3599CH8+vB9+DXk + A/g17BP4NfQjmIv8AuaSD8Lsy2CYyb8FM2XhMF2fClPtBTClq4LJgVb2ZyfGxPcRnMGr/HlhcUuYtncQ + Kuo7IDWXSyepRXA3NgdOcq0rrlVjdwBb1//dfsneb+VaVjm6ArtPhbNn0WRmMAFLND1QvnUzGDS1Aus0 + 2wcEuBacURMMxS3hbEtWv7F1XjTXv9CYUfp0w9BU3Q35z+sg+VER3D6RylJn8O5YUgZfgM+2+NlXQpyA + g+12+R6+JxLuz6C4SPgamEvYCbMZP8FM7hWYKboH09XxMNWSA1OdJTDVWweTBh1MWEfJZxADBhPProyN + jcEQ13fFS7Gx8kEi17qGJ+fDpdB01nfdfSoCgr5/AO/vvsZO+S3XumJXAXdKW0ZGIDs9D/Q1Guh7hdMt + jRBZuH2BbPaR5z5W2oxN2nZnsikO3MZOpU583gG9EZpruqEoqwGehRWzKY7z+5Ql2lJkxVa4vNNKiBJw + qqeWkMsDYOuKsmLrGr0ZZlOOcK3rWZjJuz7fuqbBVFseTHVXcn8pOuxdAeJ5xYItLEqA3YGungFudNsO + 6Xk1rOzc3Riudb2dDAcvREF5XfuCP2c067k+2lFIrz7NLnrBVY/uwWqw2PCKfLqLgiPPFo2OzaWlRpRA + 2IUX9hZtj/JFWwp8D+pdl0OcgFzASWF8ynzrGsL988kGmEvaZ29dcy7Ot65xMNWUBVMdhTClb4DJET3X + FfDedVQ4IGhv6IXy3BZ4/qQMnlzNYXNmahZtKZIeFpLfYDnECdhVSgigMh79yy5r+GcwF7cdZlO/g9ms + 0zDz+irMlEfY+67YHdCWs9Z1wmywC4uDAKJ/xoNzYLg6UJnXChnR5RB14xWb4vBH0ZYiIKDcoKjYHWAD + rS9h7ul+mE07zgZWzt8FB0ah57PIoKwmPC9gdwUdqNUEJ+OkaYh9j36zlRtQ2FtFnA65+E08GZjVQlKI + pwXkRqhkUFYROCDiv0dInRYeN7ypElWYUU8GZrWAo3b+WwhFlID2aRg6MKuF6Rr7ojuu+Gx/qYE1aVXQ + MIij3QmwWccg/NJLMjirAY+PgieNPfZOPBGYVcEjLv2O2tc7GznpPk6phI849r2qB5PNvlLR32OASwcT + yQD5O9lJ4qvoixOQ6/vYV0KI4KwCZp8d4r6Dvc8XXt/N5ON5qNE6vhNuX/LFUpivKXvV7PgGQhElIE5H + rOYWcLrKXjcQ0++Ol3ULBMRUXNNvZP8/joojr78ig+TPaErF36YkTkCOueggMjh+D9fyT470sW/QMjwK + n6S+kY9nZ3YdjM6n4qH+EbhyOIkMlL+CKzvOrghBtICz6T/QAfJzcA6Qn4iObOxxkY/nl+o3N43XFLWr + Yg1XDs7tiWX9X/7dhSJaQNxAQAXI35musB/NxPS7O6eelA/5NLUKyvX2QODaMu7FowLmb+A6NrWTZyVE + C4iBoALk13D9XrZDh3v/NoOJS79VpHw8X73QgNFqX2/GTQfXjjwlg+ZPPDidscAToYgWENdJySD5MXMJ + u+1rwdz7xzX3ktIt5kpFB2st8c/gTmF/T8W4GdbZE6GIFnByqNO+PkoEyl+ZKQtzvD/O+VHCLQYHKUU9 + b7aJPQ0pJAPnL+CObP5dxSBaQJwH+zViLRkovySES7/cXzp8906jmfXxKOEotmTVwrDFnopHuT/7y/cp + ZPD8AdxEu9ATYUgQkBsJZ5ygg+WHzMV/7Ui/SS16UrTlCC5tc6TillodGy1SAVQz7EimSdpxC0kCTpc/ + JoPlj8wUP3C89ze5DaRky4HLdS+63hxXTI8qJ4OoZh6ckTYAQSQJONVZTAbL7+D6upMDbeydu0fM8Fma + 8PTrzBcZNaA32W8VwpNsd39+TgZSraSEi9+EwCNJQDwwxE7EUUHzI+Ziv3Js33/WJj79OnOisAXGxu3f + r6ulz151gAimGpGyBMcjTUCO2fQfyaD5EzOFd9m7Yh/u29eNpFhCwVT8tFXv+H64c4QKptrACWhs1fn3 + EotkAfHsBBU0vwHTb18je9eeUQvbbECJJYZ1z6uhixsN48/EKlMPz2aQQVUTuOnC2QuxSBZw0qj3650x + eByUP0j/vL2PFEoKR/IawTq/ZKVrH4ALKt/Gj8dKnb0Qi2QBcWoCF+ip4PkDM/m/ON71u/wmUiapRDX2 + OH52XqqGDKwawH6sYci9AgLSBeTA/XFU8FQPpt8e+8y+3mRlqZMSSSqYzpvnA4fb+EPPvyADrHTcTb+I + WwLi/rhfQ/1vNIxHMCfmL2N+0TlASuQuB3IbwDJ/ok7frc4TdbUl0ke/PG4JiMtys5k/k0FUM3hInX/H + HwqbSYHkALf187+n+EUDGWSlguXesGgS//xScVNAnJT2s8PqIe+zqgj4boNmK6yXOf06g6m4nj9RxwUz + 4nI2GWwlkvakdIEHUnFbwAmbmY0YyWCqkLnHG9g74bvlaD2Tfp3B3TXm+ZYEK2NdOpBABlxJ4NzfQK/4 + 3c8U7gvI4U+bVGdzLjje62RJKymN3NyvfXOiDos8UkFXEvF38x3P6y6yCDhhHuZajvVkQNUFl3477OUl + cBvVxnTPpV9nMBVXz5+ow6LhUTdzycArAdzNg3WmF8TfDeQRkMMvWsHwNY7CmHncyJSSxVPgiboRqz0V + 4/UIVw4r83A7FjbHsy7OsXcH2QScMKm/FcQimPz7BJe1kaJ4khtVnY69gzjFobTD7ef3xoG2tf9NzGVA + PgE5piuiyMCqhakW+8SqkWuJcAsVJYknwd3WxfPb+LGVwXJnlAi+IkHiuY/lkFVALOY4F7WJDK7iCfvE + kX5RAr7ui7fBE3X8Nv4Rg5ndTETJ4G0uHUyAoT77lJGcyCsgBzs1h4UdqSArmNmsk453uFjeTsrhLS5w + v59PxXjWQgkn6vAGJf77yInsAuImhdm0Y2SQlcx0UxZ7fqxytSmzlhTDW+C54xztmwug8UJASgpvcevH + VEnXcAlBfgE5cBs7VhKlAq1IQj+GCYs9vZT1GnyWfp0J4v4S9M8f9LGYrexeEEoOT4MXE+L9JM7xlROP + CIjMlIbSwVYgeMqPf24ciVJC+IKTxa2OVNzRpPfJiTo8z8x/G0/gMQEnbBZ2ZQIVcKUx3ZDOnhnrPeNZ + XkoGX4AtMW6G5b/pi/hKUhJPgTdmGoel3YQuFM8JyMGqKIR/RgZdMXBdBXYVA/e8VX1GRaRfZzakV7Mj + Afh8uI3/3knvnKjD1hbvoHOOpyfwqIDIdGOGokfFeO0C/6z3artICXzN8YJmx4k6nAj2xom67ETPjHoX + 43EBkdnsc2TwlcC05hl7Rpz43fZCQwqgBBJbeh3fM8fDJ+qw0DpWeeV/nyfxioA4wpxL3E0K4FMefcg2 + UuAz1g+MwMdE1VOlsCatGjqN9v4YO1F3xjMn6rDfh9VdF8TPg3hHQA6ssK+0VZLZVKc7PzRaMvBK4tu8 + RrDxJ+o6BmTfxo97EbVt8q71roTXBEQm9Q2KGpQ43/nx9aKi40ol2vlEXZpGthvQscBQQ6X4G8/dxasC + IlOtuco4T4xFx/k7P4ZGFTf6XYq1i07UhV10/0QdjnjxagnnOHkLrwuI4H2/vr5vZDZ56Ts/lA5W6eK3 + 8eNN6rhRgBJLCLjSUZjZ4IiNt/GJgMhUw3OfSuh85wduBqUCrWQe1b2ZoyvNaZK0dxDTri/lQ3wmIDLt + Kwkx/eLF1dwzYDpTS/p1BkvFaQakX4yDm0tL3CyrIQc+FRCZbnrhdQnnnn7z5s6PBh0ZYDWwy+linME+ + vBhH2DZ+nMjGG9yd4+ArfC4gMtX62qt1p6cro9jvVWv6deZW9Ztt/FUFbSvuHcTbm7yxxCYURQiITPY1 + eecaMLzzw2ifymgbXvnOD6WD2/grBF6Mg0XSezrf7DNUAooREMFaM7PJB2lxZGIuaa+j6HhM09JXbqkJ + vLeYvxjHiBfjHHW9GCf0fBYYBt2rZOUJFCUgw2aG2ezzHtvAMFMWzn4Ppq29Au/8UANXK+mLcfCf6dHl + bM5wwXdWCMoTkDEOUzg4iVhHSiQZvPNj2D7bL/bOD6WD69iFuiHHN0wOLYKr3yZBXdmbyxOViEIFtIP3 + s82mHKFlksBc/A5H+sXdJVQg1YzzxTimEQsM6u3TNEpG0QIyOGFY1YXQj0mpxDBT8tDxc7E+HxVEtYMn + +hZ8P4WjfAHnmRzssN/QJLVv6HTnh9aNOz+UDFba4su9qQXVCGiH6xu2F8Bc3HZasmVwvvMjpU2+ouNK + AGsYRnMjen6rlppQmYDzcCPl6eo4mIv8nJSNgr/zAznk5p0fSgEHUWdLWx1XP6gRdQrIYx2FaU3yfIHM + ZVKzB+788CU44sW/RHxJNzWjbgF5sEVszORGuTuZbIsFnIvZ4rjzI03GOz+8DS9eYc8QjKkw3VL4h4A8 + XB9vqkcDMzkXWKldXkD+zg+cqD0q850f3gAHTMcKmljRJH8Rj8e/BHTGMgJTzdkwm/odOwqA/xveWLnW + g0XH5ebzjBq4VtkB7QaTY5XD3/BfAQkyO/rJQCsJvBTn+4Jm9qz8+q4/s6oExAHI4wYd60cpZSCCm2Gx + GOaJomZ41qqHAbNnqlAplVUlIA+mM1yyyursh+uVnbD/VQMT0hs7o3EgsTG9hvVFH9V1Q5ne4DjfsRpZ + lQIuBvfR4c7i6j4jJLboWb/rSF4TO6q5Nq1a9IF1FJkXbU9OPUupDzRaNgLHPYj8FV0BAgIuC9ZjwatV + h7jWEisnlHCj0OyuQXjW1udCKgcWlcTNoXjOBCve48qEnBXl/ZGAgAF8SkDAAD4lIGAAnxIQMIBPCQgY + wKcEBAzgQybg/wHM+JM9RA5vewAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vwAADr8BOAVTJAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAAADHxSURBVHhe7Z1X + Vxvbuqb7L/Yv6O7LHqPHOBfn7LNPWnvl5RUcAAcMJucclUAgQFmAyDnnnPG5fnu+UxSUSlPSFMjGNrp4 + B3ZVqVThqS/Nr6b+x8XFBXLK6bGUAzCnR1UOwJweVTkAFTo/P8fp6Sn29/exubmJpaUlzM7OSs3MzGB6 + ehpTU1MJ4nKup+bm5rCwsIC1tTXs7e3J/Z2dnSm/7ykrB6AQASFkhIbwEJzl5WUJHyEkPKrPpROBOzw8 + xNbWltwf90uI+T2Li4vY3t6WsKs++1T05AAkFLzxBIIgEIiNjY3Pbp0I3s7Ozi2QfAAI6lOzkk8CwOPj + Y2nNDAtHi/elWR4ez8HBwa2rp+s+OjpSbvst6ZsFkJaEFoXA0d19bTfz5OQEq6urMq4kjPcNA750fXMA + 0trR0jHeYvym2uZrEx8eIxH6Vs7J0DcDIK3d/Pw8VlZWvunAfn19XZ4n49Zv4Ty/agB5Axjb0TIwrlNt + 863KiBcJ5NcM4lcJIC+4Ed+xzKHa5qmI7pnXgQ/i1wjiVwcgLR0v+OeKhXhTmQAwKeB3Eny6P7p6qwgB + 13M7bs/PfS4o+CDSIrK0o1r/peqrAZA3k7EPb7BqfTZkZM5MYIySjVGUZkbKdXwA6P6Y7FhF8Lie23F7 + fo7HzP0QDu6LkBJO1fdnQwSQ38njUa3/0vRVAMg4h6WUbFsT3iTu2wCON253d/eTWS3ul4DyXIxMnSWW + bIcR/B7Cz31/Lgt8X33RADK+IRTZquEZAPDm0CqxtEFr9Jg3iZad7pv1Ph4Pjy9bx8MHjKDTYqvWfwn6 + YgGkq+KNycbNIMCEjjeZw3BfalGXIQBdKI8zm8VzWvkvNVv+4gDkTaBrykaSwZtJS/c1jiTwOhAaHj8f + RtU2mYhuntbwS7sOXxSAdBWEjxdftV5XzFLpumntVOu/NtEt83yY2DzEivGzhptXrX8MfTEA0lrRUqnW + 6YgXl+Ax2/ySY56HyIjpaBkf8pDyOmXDqmZDjw4gwSF4D6lf8bME79GK0ofbuDzYwOWROIcTcQxnn67M + QhFEni/LPfe1iAxxshVjP0SPCiBPnsnBfcFhkM4b8aldCq0NYydmzPwuI0EydGT7HUe9r3HkeoUT1wtc + 9L7ElVvIX4qrkWZczfThcmcRF6ciqcjiDSdED3nwCPKnKG9lokcFkCfPi6Bal0q8YIxlHhoTqUTYjGI0 + by6TAB4nQaOlZlzJG8/jNnTVX4DTkXacDLfhONKK/UAjdn312B6qxeZANTbdJdhx5AlAX+J6sBDXkTpc + LQayZinpknk97nMt+GBlI+6+rx4FQJ4sb+p9MjLGdwzIszWaYADHG2gUh+nSM7mZHz0FuJqwpdTleLeE + c2uwRkK54y4WlvMZrgIVwkL2Chf+sJiM14PX5T7ewHigHwPCzw6gAV+mJ8uLxCf9IYmKIX433SiBo5Wj + RXuIJdUBUCVazc2BKmx5KnFo/wuX3hJcLYVEHHn/JIrnxWuU6fkYEH7uMs1nBZA3/j5PGi9KNkZEjDIP + octWkZf62CfiPQVgmeg82ild9lZfCc4YQ451yORG9X3pxLCAD1emXoIQ3tcz3VefDUDj5DKFjwH2fT5n + llGQpnV4yH6S6WPfCyVU9xFd9WGoGRt95Th05eE6VH0v92xYtEwL+vwcH1L+Va3Ptj4bgAziM30iCQ4T + DdU6HTFh+BwF6WwCaBZd9NZgNY568nE92oqLo13l96fSfWp+fEj50KvWZVufBUBClGlxmBeNyYFqXTox + EKcL+lwjIR97/1QClC0xu94SseJJbx6upnszzp7Z4cP4WbUumWgsWCJTrcumPjmAhCjTzIxBdKaug2Ls + QreT6RNv1ZlwP1tHJxjfPkD3/CamdlI/PB97/1CCk20dhVuw1V+Oi4F3uNyaUx5LMjGUoRfKxLXSaGQj + 6UulTwogTyDTJ4/W8j4JguFu7xtAH56eIbS+h6qJFeRHFlA6toymmTV0zm2gdnJF7pfBPR8MPlS8MUYh + +qTrR1n3Owg2SWvFhOJirEvGcyqQHiLuc9dbhyNPEa7oli/0geLxZ2rVeF1pQVXrsqFPBiBvWKZxBG9q + plV9xisE7z4X6fjsHEOrO6gYX0FxdEkCZ1/YhG1+A81j86gNT6I6OI68oTF54/gw8YbQovMhoZuirp2/ + SugYs9FKGYVo1vw2PFWy7kc4CaUKqvvoJNKKXdtfODvJrJBPCPnQqNYlE8+dn1Ote6g+GYCZZlKEL9M4 + kdsT8kwztvXDE3QJyN6NLKJ1Zl1C1za5hPrhaQkd1T61LJdThWI71X4MfXQ9U0JiFi2jLLMIKHeEBWNR + WrWdrq6DlbjYjLX5Z/rw8eHJBEJeXz7kqnUP1ScBkG40E0vGTC1ZzDcTXcFYMBEAww1al6fSzM4h6qZW + pbWzCbA6Z1bRODorrVzL+IK0fAZ0ZtEdHwgXrdrnxfkZPvZkFgPellqEdSSMZ6Mdyu2SarRFJCM9t8fA + a8FrGHdcacT7k8n1o6VnfK1a9xBlHcBM4z66tGSdMIRvoHsMQ/ZxTERiJ8+nkS4hk8RmQ1i8GhHH1U6u + Csg2pXWrCU2gYWQG3XMxC5hK1eKzKwdJXNDp0YPKMIRxz98gYaRVTBs3ivXXAZGICPDNx8HrTkBU3mB5 + XV0NyPRe3SehTKesAsh4jOUP1TqVUl2AqeFlDNrGEPbMSBFEAkn4dOuJjPGYRJSNL9+CZ1g7FWjJ1Cxi + w5HNJFn5AwE0iwAaIKrWU9f+MlwmGSHhdaFLNhfbveIhK6hywCniWPO2hlIZAJUeOihgVVYBZFyhG6ym + SlIWpzfg6YrewkeF+qfRWTuEGeEOVZ+xivDliWyWANLVMq5jYqECLJ06uA8h1fdcHO/jY3+eEpb7iu6Z + sSKTmrh1kXpcLfjUx3EjwkFLyOtL+Eqa+9HiCqK0pR+BUbVxyOS+EfJsFqmzBiCtmW5MQTeRLElZW9yG + u20kAb7ejiCCfVPo7xjF6oJegdm1uIWakVnpalVgZaKyJOCzCfV64HU8KFmSkU1Lt0zXO1yvPAareF07 + e3wobnRL+Ay9r+9FdEZ9Hpkkjayz3qdOq1LWAMzE9SZ74na3D+Fqiijh419jWV/7KLbWUscivEBTs7Mo + HsnM3SZT4aj6qf+UAFIs3bCMc97/RrtLxjtMy9eH0kYnmhz+OAhfVzsxu5RozTO1bLzfusCmUlYA5BOh + G5xyO9VIxenJGdyt8ZaPssJniFZyd0t9Q5gRGlnh4v4RKidWlFBlogLhzo/EQ0NLz7iJ1p4P0tpsFIfO + F9JS0XXSbbImmDaZyEDX4VrsTftl/JvupvtMbrfZGZAQ8q8Vwr2DxGI/yzk8N+tylVjKecg4vaGsAKhb + I0qWpPCiMskI9sWD5u4MIeCejFtmVk/LMPZ37y4k90NXYnUPjN9Y91OBlUpMVpgtM3Ep8I5jZD42ja65 + EH26vYTLwUIJHWt9hJBZLWt+RhGarvTeQEbbcT3WLs+DXiOVq4xZvhh8hghfWZMrblmTWFbU4Fbuh/Gj + bpJ3nxqsVQ8GMJMqObdVDZVNRpZkqcUM14B9BEPO+EREJVrCo4Pj2wxQtf8TkZCURJeUkJnFOiDrgkxY + CB6L08Y6ZsLh9UQrf7m3hmvvezU8N4p1tdRIEU7CqtpOpWt/aVzzAR9inqf1mqvgM9Rg86K8uSduWWX7 + AOyD0bh9UNy/rkExrrlqna4eBCBvtu4B0GqoiqWM5Xqah+Og8rrG4LHFL0umkD2C3pYw5mdTH8fk9oGs + A5qBM8TyTF1kSkLXNRsbjrOKFtQp/lr3e7m9gGtfiRIelRjTGSMi6UZDrgMVuNxVj1jQUjEc4L8HI9Mo + TQKfodrOAVS3x2/zrq5HGQ+yLENLb12uEt2wrsVU6UEAZlKTUz1VZ6dncDbGJx10uT3tgbhlyRSyheH9 + LQ/u39+iv31ExpHW7zCrfTbeFXdMr0joUo2CGOLICUdRrPuUAPr1ATREl8xxY7ppuu6EbSyjHSqxhuoY + GEZZS2r4DFW09EpraF72qsKOw6NED6brXmmEMklArbo3gPxiXVOdbJw36p+Hvzc+xiN8qqTDqpBjGN5n + +eh/VYLA63L48stFHBkVLiT5RdsXgHIYjqMfdLOZFqQ5JGfdZwzA0kSAMhDjRsaKt0NyLLmEqsT+UwPQ + F5jAm6ruBKhS6UO9PS4pabT7Ud0xlLBvGhbdrJjJ2H2t4L0BJFQ6sR9BVZ0IM1ir9aPbpfs1L1Mp5ByF + 9/cC9L38gEBhTUyvy+AtqIDXMY6L8/jvMsszvYAPwcm0Fk8lVVPC5caUbAywQnUfMT5kwnLt+5C2DZ/w + sbhMiBjf6ULIsow1KXlb68LkfKJ1J1iqmNqqZPdYR/cCkKaZ71io1lmlctPnApD+jvgEg66XJRfzMqX6 + JuH74w3cL4rv4DNUICB8XSX2NRX3fZRxkfaFJa4TsSAbTVWQpRJrgewbNO83mwBS54EarIdtKR9uwmd1 + u4Sq0e6LW5ZMVW19qO8eilv2usYpG3HN38Nrpute6Q3vM0R3LwBZx9PpdiF4qiRleW4LfR2jcWA5W31x + /0+mwNsq9D1/D/+76kQAbyAcLKhCZGD21hLyWM0xDSH6EL1rt9IVk5joVnyJ53J9Qr44pIIpY4114DpS + L4+TD66qtkr4yls9cfBQdKslDY6Eml8yWbctb/PA7Z9I+D4mGTqejtvcpy54LwB1Yz+VCWfi4WgIx0E1 + 6BjVKrkEa2zo/y0fPgGhEj5D+SUYeFOL8eCizOhUQ4TB9d3bBlRddc6uo10kLizYMqPn+W1G3dj3lEjX + yayWcdx9G09lyYXTd9wcIx90c9G+T4QOKvgMqdxrMtFlMykxL3tVacfRcfz94v3Tvd/3SUYyBpCk8+lU + rTOL5pjv31qXz46vxdX8mHA4WrxxoCnlnsDQP36FJ69UDZ1VeSXoeVWNYd90wjEYqmF7lgI0s1gLZKZc + FRiTpZryyIwEkFaVFv5sKYyLUK0EjwCy85k9fuv9lTKxSFdqMXQdrMLlZuKx0goy23WbYr5UYrmlpiM5 + pGYRVvNQXVXHIGwDownHoFvtYOkm0+bYjAGkS9VJz2l1EmO/c9jrQnFgMfHw907ELVNJjgnX9cD/11vp + ZpXQmTQosuLBv97B/boB85Pqli/2CTKztULH7hmjO9raQVM+Hv/wXS1HcDXSpISKMjpbCGVCd4shut6x + zrj9mmXzRPC22h4HTyoxKbGOAaukspjPy7qFFYy/b5kkGSqjk0oZAUiAdM2x6kAWBAiDtjvrx+4WV5s/ + DrRkYnmG24cFiIH3tTEQFeBRgwUCPiH+2/+qGL2vG0Xcqc4q+U6I0ZZP8GjlCF+yLJldMeZg/WopEKvZ + qcAyiXU/ZrkJbVYsuYis19pgaoiWj26Xlo3JgxmWZGJsx3KLap1V1uSlpnMIzqHEERLedx3Dk6wpNpky + ApBjrKpGAqs4oK0a1O5tiR/d6OsKx6AyLVOJ8SGH5szLQu1e+J/lI/CmIg4+75vKRDf9sgi971qwsZLo + HggToaofmZHDcOnKMx+iS7LX0Pi8LoBmMV7kaAhjRXY3X+6pg3cDvls4hGvVda/cjtCq1plFWNmwYF72 + x4fOBIgYcugkGZk0NFAZAajbgqMKRjdX9xJarXQz36TbibiQRWj/i/cSNP/b6vjaoEn+l+/R+74d2xvx + WSwfqvDULEqji0rgrGJnjbk9/2reK12oCrRUokXc9ZTiKOqIOx5DzEjLWhJhY+KgW27RtYLWjhkO6w0N + J5bZdJMMTrKuWq6SNoAET6f2x+RDFS/4XJOySGzAo9tswO3SFaeD9S5hDfPgfl6khM8QQe0pbMfeTqyE + xODeGJ9m82r7XPriNJsSBlbuWtiv5geFG71H1kvXG6zElvAoVssSg0+dcBAU3XKLKtNViUBbrWB+VeKD + weO0VjVU0s0TKG0AOZSm4355U1XDbhwi49ttva3DcDVH4GjWyHyFdGNET5sPvueFCLxSW0BDfpGYuAo7 + MT+7GNe2dS5EV6yCziw5JiyyZ+Nz9wVQllyOY9/P1i4jdqLbVVk+swiMbrmFsKqWW0UAmWVzbLikqV/Z + pMAKiE4ywtKXtSUumbQB1B3v0zG/25u7cLYE4GwMY6BLbd1CQsXVQdgt74ao5OsZl/Fk2DONYGUH/H+8 + RiBZoVqo/+eXcBV14khkwebjWtjTa141Z8JXs/0ZAyhnSOU8gKbvpudosg2gLEWdzywmJHVdg8p1ZtEK + poK1rtuHNzUu/PmhA3aRbZ9YRnqs0slyMxlB0QZQx/3yi3Xas4yMikXppdlN9AiLyPgw0HuXkPQ4JvFz + 4QBeVkak7PZJhPoT4aOsVpItWv7fC2R8aIWPMSIL2b4/36KvwiUeqvgL7hCAsYFVBR7FRoa3kbnbQvRO + qB273trbaTnSFqHHOnE92hz3nZQc223uk7DouFcqE+tm3if/zTjvz5IuCeDGduzXmXSMh6q8ppJuHKgF + IJ9OHQBpelXDR2YlO9GD3SMMD83BVhtEf2dUuIIQ3lXx4o1K5VVF8Fd5GG2d8Y2rHEWhzMukRHYdKKqH + /883t/AxO2aWbPzf+8cbeGr7xINwF68ciVCBHTNm6JgZ88UmdkazRFMYnsHmXuwXMc+nenER7ZClFbZX + sTWfLVZGlmsF8NpbFDfaQfX6x29jvkzcK8dzdWI8Wko5/mvz4ffiTryt7cHIFCcKjY/TGAakG89leKXq + 67SK+9KJF7UAZGqt8+6oTvDJdD7lCZxfYCK6iv/K60N+sR/FtcO3EFIF1cN4XhFBQ9sYgv3TaWPEUOuA + cMkFGMwrwWB+YgHb+/sbeJsG4457WiQpHPdlcyrrgpS5UZUTGLGIzW05vzMTCitohI/FZ4JotFmxxepy + K96F8X1da8Khah5NJqt1s6rZGWs0+Pl1Pdp6wtjbTz7xE++zzkjG1FRis4dVjAF1yjFaAOpmPzoHphNL + +ibFTXaOwx5aRXlTFK9LAnhTRpczcgtiYd0Ifiryobw+DJ87df9g0D0BtwDN/0IkKRYAJYTPCuBv9d42 + LxDGquFZVIen4iyhocbpNYzevKieDECzZJvVUJX8t/k8HUNRVLSra3Wq5lGVaN0qW+Nfv6QYS+ZV2lHc + 2Ic5kVDotM/pejqd+I686CQsWgDqjH7oZkg6sUGhcLNd/kU4I2tSjvAa2gcWUVgZRsEHP4qqIxLC/NJB + FNWP4LfSMMrF/wdNMaRZRpNrsLE3VrxWNDMM/VaAkC2E05NYHLt/eISSJFkxY8S22djwHruW0wF4NdGN + S18p5udmbx8+wlfZnjqJ0I3xjHofXSwTipflNgyEpnAszsW4prpvsekkGayGqCodVuncay0AdZ4KDkSn + a9HixU+XpGztneBFfegWPqvswRXUdk8hr8iLl4WDt1axWID4p4gR39WOwNNzByIz5Lj3S1zRWOE6L7Fc + M/BLPjwCCiMOYutV/ZS6Y8bIhK8mHWkBlNNpHGxIy7ooYqNOdxgVbelHKXRcMd3v+zrhYt+2CAD9WNtM + 7kJ1gGAZLd19pLFRdRhZpQNzWgB50XQApGtNF8Dq1IfCM9uosI0o4TOroXccbf3z4ukfQb5wxe+rwhLE + koZR/CVixNciVuxxTibttAlWdopMWVjDG/jYX8gmV8/P+ZgK3J1vk3C3qubVwtHYZElpAWSjwqzndn98 + E41t9LqjGcmKzg12vxwye9/Qi0B0DlMacNECpnPDtJSEULXOEJnQccP0iOlCt7QAEph0B0TpuGmdWLLe + PYNO3537TaYahwlS4aJru6bwtjyEAhEvfqiLJS7PxL9flgfQ1a3utgl1h2RTg7+gDH0vbiyiALH/xzzM + D8cu8M7xqRz/TQBwZBEn4kZcE7JkAI533bzbETs3GfPdWL50yYMhc3sVt2f7fEEVZzwIYt/0crlOs4Au + XLRch7upk04da8qEJt3gRVoAecA8cNU6s3SspA6kzxsiIuZbjYPNqk7fAtoGZ5XrbIEVlAirWPAhgBeF + Humi84U1pHtuF7Fl0FpLFLFhP8szLF7fWENC2Pf9CyxGY+FCZGNPWkIzgJXjK1g9OMb1eGdSAGWXy3Gs + LOUQls8c87EVyjr8pVKz0KvSNjlCwZfJ55Zjrtx8zSidrNOAK26Z8Fq7wp0ujQxjuKMdfUXvUfW3f0H9 + 3/+GlTH1jFqUjnvl96ULudICyGbEdE8W1+s8EekgXd1exy9VbnSHFuCIrCgBo5r6hGtNA2l3YElkmMN4 + R6t4U855K/RMJCyNbWPw38zCwBixvzuCUIfvprvGqBNWw/NTHtZm+atDF6ieWAGneCN8rAvWjS9iYGYJ + e16+bF6fUITmdBqXa+PyvJIlHIzvko1mGAnFC5FQdPcFsbWdujzC8CedWzwV7ncsHMLicATBpka4CvLR + +v0/4Hj1AoMV5fA31CPU0gzHh2L4amsQFv9W7YdiyKVjmNIdU1oA6cfTAciglQekWmeIrjfdwXSFnHjZ + 3IwPrhYUORtR2tOO6n43Wn2jAjgCGYOuTiQSVuCsavFMwxZclv/u9i+jqn1c1hVZznknQPyjLIzKplHY + W0ydNrK7puK2u4aWcODXAmyvbktXzNkVjEbVhjHxkAg4L0dacD7aIYvQxgvnF6NtuB7hzTuHbSCK8hQJ + R3GdLe7/LJ88K+6QCYUxsSSTN50udLMRoGU72tvDrHcI3ppq2F88R/cfv6Px55/gKRHhRmODhE2lvsoK + eOvr0C9ANO/fLMbzOi+vPxhAHbdpzJeiWmeIaXu6zKmitwNF3V2oEdAZqu7vRVlPJ4ocDRLMst4uvO/s + RLM3AlsoeaxY3zOmXN7inpNlHJZz8ssC+FW46lKRuAz13tUSZXcNExSOJ7+twuDvb7G+uIb20Wk0TsXG + imkN2dLPH5BhmcWwfGyz2nflY3dbWEvhdlPBRzHGK29x40VZt5w+bSgyk/B2GpXKw9BAbAtAB5qa4Bfg + 9L59g+4//0DX78/gKS2Jg8tTLc5HWDfzMqsIHyF0FeQpv4+iQeFoh2qdWen4SQugTrajkwET0nQZ8Ku2 + WpS5HHEAWlXZ68IHWxfKe8UNc9RLMPnvWo8I1L3D6ArGYsNa52gCfGbRhb+vDeJNaUAmLr98ENZIxI5u + 500JR2TZbGRlR/VQfhncIjs+2N6LueKbOJDJiRXA62CFHO1osg2huCF+PhazmhwBOTUGi8WFNQLaw9TZ + KWMpXmO60Y3ZGUwPDMBfV4ueN6/RItyo7cVfcJeUSMBUUBkKCNfbU1aqXGeWU1hJ+8sXKb2fDhsPjgF1 + vkQnTkwH6fn5Gb6rfIcqd48SPEOlDpuE0Lq8uq8HlW47Pjib8aa7Cu+7m8Xyfum+CaXjxn2bZUDa5V1C + cc0w8oSL/q1IACmSFqdjUiYo/op29P/0XFjCSgz+UYiF9d3bti1O2XY93HgLH3+342rSKS0fYz6OUFhH + M5gFv6qw4b1IKBZWNqW1o5VQXRu60M35OUz298Et3GGLcJ+ErUdYOMLHOM4MTbC5SYJjXqaS7jbOvFcS + eOtxGdLxjulCuKwAqPMeQLptDo638GN1TQJYVn2wdwvYepXrDJXYbQLkXgllhduGElertJYlrjYZU7Z4 + R9DunUazZyoOSA79NTpn5NDfL2+8+LM0hIYGPwIs14gs2Z9XAu+LYvTOrsuREL6ofhCsi8EnXC97/Oye + kdtSC8smHKXg9Beck49uliMUBxZrt7e7ixVxo7YWFxC122WM1vHLz9KNut8XwiusWrbhUi03ywDwJEVR + OhtsZAVAnSG4dE/C5v4sfqpuVQJlFt2varlZqbYhvOUijnzbWYtiZ1Ms0RHLmr1h2MNLtzDSKrKE8/3L + Pvz23o/m9igCHxrh//UlBvNKUTy8ICcrirrLY67XXwa70xM3wsEGzx9eN6K8tR+Lq3cB+5mIn9YmJxFp + j5U9bM//Qr2wbK7XBTJhUAFBPQaAtMLm+2RWNrxjVgBM5+epdJAuboXxY1WnEhqzirvTb3MfSI2YklDy + 33TflS4POvzTaHDM4KWwhj8Kq1hTIhKFX17A9qoE5dFF9HUV4mq4Ac7GCglfXbdX1uwK63oxGJ7GgcgW + Aw47Rm3C+onYy/HqJVp//F7CZs5EPzdcquVmSQDz83CYogtKhw2GXp8cQJ1YIB2ks+uD+EdFenB0AMzG + Nsy+33e3odjRiEK7SI5EJl7ldiO/phffvXah/N/zUMpZGrrewl76XLrX3/Jq8DqvHL6WVvQVF0k32v7L + T2gXwbyM14QbVd1sirU31XJDgYZ62ArfytjPkLdGZLQiWzWrQ1itfgFPnD7wrcA3t2oR2THjSNYBrXLm + v5JqEsfd9uMPTwvA78q/HAAp6zYVzMCdNrzpasUPlWX47h/vUP2v/4R/+l//jH/9n/8bz//P/0XxP/0z + Kv/tP9Hww49o/lkA+NsvqP3P/5AlEbvIVFmPM8slrAxvfPOvv9yBIKxjj0UDZWXoFtD4hIs2FGlvw3hP + T5wGW1uwPDoap9WJCeytr91qPBwWf9dxsLUlMvvtOB3v70tNi88cp+l40bnvOQCTyLpNdV9MFb1uvOt2 + 4mWbU4QENvxc14U/mx14b4sIl+xHR2Mpgh9+wtjz/wdv3j/jF3HMzZV/h/Pf/gabiA1rGwZR1DWJPxtG + 8V/lYfytOIjvSn3IbwqhrDMi65MO3wy8I3OITi1gcWkF6xubGBsflwV9ZsO8YYbM10jnXmTrfmVrm68G + wPkN3yd3weU9brztdgm4evBzTRd+b+zEqzYXiu0hlLqG0DQYQt/oEsKzS1jcWMPcwhzOtldxPmLDafcr + HFf8HbtFf8dyya8YKvkDVd4AXrZE0FzXCu9kGaJdRZjJe4n5okKsdrRhLzqKk+MTrGwfiX3uiH1viJhy + BWWuObzumMazhnF8VzmKZ/VRvGoexbu2Ebyq8+F9awjlXcOoc4yg3hFGuzsCT3ACHl8Es3MCWhFPM7tk + Yd8YBOCwGG90tiDN1n3/LABmIwlZ3RnHD1XtSnDMUiUYtFylrl4U2npQ0OEWN7QDz1u6kdfehzedA2K5 + G5XuELqDM/BNTWJpcxkLi7HaG1/HjDuW0xNcrIzhbKgWR3XfY7/0X3DQ+AK71b9jp+JXzHWUw10hXKbf + j675TbyqDci5DgdHmjG61IGxJRvW+l1YEvHZsojTCONKazN2IxGcWjJKjjGfnp0L2A/hndiScDYNLqHG + vSDiTaHeeaEFVPbMo1xAS3Dfdk6Lc5rGB/ssKlwzqHROotIeRbWw0HX2WPZt9wzDExhDaHQSE1MzEhRe + f2ak7EgaFW6ZXSocTuMIFVu0rF1K2YL0s2TB6UosVLp60M7BEn6qbkyAq0rAVSYsV7GjV7jGXvzZSLgc + eNHaL+RCfodT3BhhJfwjwgqNYHlrWViuRfmbHmdJ5luh4rp697dwPj2EM1chTir/hoPqn3DQnIeDlgKs + lPyInbKfcOKuxJizGf1VBYhORGRbPlUjrBbnIuwRVis034ipVTdCc/XY2V/ETsCHpepKrIpYbU1kwQul + JViqrca234eTrdRtSoTz+PQcB0enmFs7wMDYpoSztn9RwDiPCgFlTd8CGgeW0OZdQWdgFfYQa5lrEuQG + T2y7wu4ZuR2vvRxJEaBRhI7tUux24r3hfZ6cnJSvVXDYb2RkRHa8EF6uJ7jc1rC4vHbcVgWvWQ8GUMfM + poOLSncgRyd7+M+KMhFv9eBZowu/CdBetNlR4vSh2TuEgfEwZtaWMD4zI2DdEZYj+XslbEtK+XLNmbgJ + 28vY6K3EScMPOKr8DxzW/yGgy5fQUftNr7At4NtuLcBRuB1D7fUINrzF1twwysZX5EwKbNnv750SAM5h + oHtcttxHFpoxvdaP4cVWzG14cSYs6u7oCBYry4Vbbhff2SNhXKqtwUJZCTbFA3YiHgY2DyiPNYn4Rtve + 4SnWd44xsbSH3pF1CR0tZoljDh+EavoW0epdRrsvsx+otorgsiGCsDFO5ZAqQaR75X014DUAZtcT4eXy + sbGxhwGYDTNLpW9GPUd0Jow1AcbpWeo3t3jyqnWG+D2JD444vqURnPWV4LTxRxxW/hfWyn68Be5WAsLt + Dz/gQIB3Fe3GkYj/OitLMd72HgezQdgWtuS7wwTw7cgiRrzzEkDK3Sqyzu1hRJe6JITjKw4ML7QKS7Yv + AdsjiFUVwiW3SBCpdYddwrhYWYF1u/i+5ez8Ji9d+8buMaZW9rG5l3qc+TGVFQtI05yu1TutVRLik5Wu + Y4ZPo04zpOw9PNjC5bRHutbjin/FQeX3cVZus/Yv7DXFXC21U/4L9ur+wuVwB64nndjwd8LZUIN5exm2 + xz2Ykj94vSbhMyzgWGBBuuDhQWEFu8bkDylOrLiEK+6VEFKh+Qas7911szA5Wa6vxUpz4y2IUj0idhQu + elF4gnW7DfuTExlbxq9NaQHUSTB0rBKzNLpq1TqzHtTYen6Ky805nIdasS8SiKPyv4m/wrW23EFn1r6A + cbXyGXarhCp/xUWwRYJ3NeHEbF+rhG+1twrb0T45r3TlxOotfFSV+P94aPEWwGFhBZmQnInwgPHg9Frf + LYSjix3y/2fnN6GD8Bj701NYqqtJBPEGxtW2ViyUlyae5zektADqxHc6b7tROnDpWDd+1+0xcYIf4Vov + PGWxBKL8O5G1vsR2/QvsNLxUgmdoT1jAtfff4dhTLcGjzsccCHU3oq+lDtueGmwOu+R3tcyuC9d7Bx+7 + Yfg7wpPhpTsAhTydMSu4f7RxGw8amlztkdaQ627PR+z7UJwPs+aV5iYJngEhSzk7oeDdtt+g0gLIQJNu + T7XOrE8Cl0pi3faqyLone3DW/rtIIP5dZK0/y6TBCthKxW8Jy6h9AirivJMeNhI4sDVYJ+FjvDfYVo+B + 1noc+RuwEbLJY5nYPkDTzHqc9WMJxru2i6mRZUQ8dwBStILMYld2orfxoFmRhSYsbUXE+cSf5+GCyDhF + PLjcKL6b7lhAeZ4ybv76lRZAxm4603LowKVTrmE8aby8fSvxGTZ5Xo9342OgHNdDxdgdrBYuNE+AdxfD + WbVR82dcjMdtmdketr/F1bj91uqdjXZhoa9Rgudtb8BpSFiiYIc8Vv66UvlELOs1ixZxcucAs2OrCPZO + xwE4KDJi/hQFARtfsQvLdxcPGooudWNs2SaShcTY+VDE3SstTVgX2bJ13bemtADqutd7w2URY0Vm1Xyb + jBOAX4+24L8H3uJjqOYWGGpzoBYX4VbslP4UB51ZhG+9OlZe2Sn7BfvCJV+N2eL2wwbS2b42uBurMNQm + 9jncik1/q2yZ4vFw0kqz6zXEdvz1Q3Ftptbhc07GAUi520bl9WCjbWShJQFAStYM5+uxfZC+ne1bVVoA + KR33qgMXi5daMysNteK/Pa9xzdnjJx1xwBg6CrfhbKRTgPWzEj4pAd5a8ffYFq74ciSW2Zp1Pu5AxNaE + QGej/Hvoq8X6kLCAN/BxZoRmi+s19EFkwPwZWE4vN2SfSABwyDaBlflYYsZmW8Z+KgipYQHo3MaQhNV8 + HZ6CtADUca+sjqfLhCmtCYymhOULViUAY9alcKHbQ/U4dnyQpRMrfLs1f8iyypm/ETvehoTPH4t4TxaX + RcIx5mrB1Wg7tsR2RjmJWW+FwvUaKhYAcjsmHJ6uaAKAVG/LyK1X4FCjKh40NLHilJaSBXnjOjwFaQHI + TDhdIsILrWMpWVdM56r3BczHrlcJ0FhFsCSIwsoZ4O2L7Jdx3mn/HcDHkXYp4/9bgS6ZbAS7mjDtbpW/ + 0bE9WHM7JwrHh2n5VK7XEOHktpx8ne5WBSBds/k3SlgfVMWDhlg7ZOZsbP8UpAUgx02zNTsCreTtGGwS + EdCVvmoBRtctNCoRvl1fI466i7AnEg6646OuQrEu0W1zu0vhcmf72+DraECgqxELHv4cvnDjA1Vxb+yN + pnC9lFOA2TAdK5jvbB7IH9xWAUjxF0GN/bIGGJ4X0Cvgo+iKU40CfYvSApBuSaeIrDMHHeNEmWQo1pm1 + tjiHq8GiBJCsklZwrDs2dGbKbK06H7NjsLkCYRHrEcA1X6cEfHdQwGfqUuEL6OU3Y73JxOnZPDcz5e/v + HsHZEFHCR9EKTo/ejcUeHm8jvJAIIeFjrGhs91SkBSClE7vRhekkGTqWklnopuudEiazaAVVMZ5Zx6N2 + Ee81iESjQWS7ldgNd8uSDieN3N25m0+Frpc/YEgLpwLPEGuCc3sxS3V4cCx/fkwFnyEjIza+Z213UrZu + GfDR7T7VTFgbQJ3YTTcOpBtONy5MLUe9+BioUEJl1kGwBReW8oqhrWAs3os6WySEu8EOHIjE5NBbjc2N + +JmiIpt78nVLFXRmsQSzdfOrkifHZ+isCijBM0QryIK1+bs4LMeREbrkg+P0P3/xrUobQJ3YjdIFVafJ + gXHnTs97AZK6FGOWMZph1txNvEf4+PdEWEJOp3Y4WIG1lXgg9k7Su15DHBNmlmx8tq3UqwTPLHfriEjk + 7q7L2fmpLEQfn6a/pt+ytAFk7KYTB+rW+tIOud1obdyH62B8EVoljmbQEvLfTDZGHM0IdTfJv/5OZssC + 4nEbTn1VCfDFXG96y2eodGwlrpO6vcynhM4sWsGZaPopcp+atAGkdNwrodLpIbwd8VCsM+tYbLfVI5KR + ieQJhqHDUCv2gu3wCms36mzGsL1ZJh3sbuHnz/zVWFlKHNUJrO+hVcP1GjJKMIY6KvxK6Kxitmz+SYic + MgSQWa5OOUanbkhpW8GZKK58ZUrozNoW8V5PXQVGHU1yZGPM1XwDnwPngWosLyQ+GNsilmNblQq0ZKq/ + KcEY6koTAxryu6ZyVtCijADkEJWOG+Z2OuPHdNfpGlApwrzmqb0ZmksEj5r3xOI9jmp4mipjBWa5zoHL + YDUWZycT9ks3WjuVPus1i/NFdy/EJw322tRZsFks2eSs4J0yApDSca+UrnXTSVqo3e0tHPexyBwP3qWw + cFHhboNdsSE1f2ejSD5asePjrFV2XAn4lmYmlN8RFK6XzQYq0JKJsWJ0Kz5xYLFZBZtKQfc0xoNPt/nA + qowBZIKRbp4/SqdLmtJNWqjliSCu/OW38DGrpdUbFYkG4eO/11lgJpgi4djvLcRiEvg2j06UbVbpxB8z + 3LP8vlyqkRCVXE0iFjRlxE9ZGQNI6TQnUNxO1wrqxIzc15qvHdejbTLeY/9eVIBH+NjHt8cCs4RTZLx0 + uzPjyheh6Ho5lOZUAJZOhJZdMOb99SUZC04mWsFRX/oy1FPQvQBk9qoDDK2gTsFZt8RDMQkaay+Cv6NO + gkexwMxuZsMyXodqsDKrho8aXN1B22xmrtcQE5azm5/0MsQ2fBVoqSTrgml+GvUp6F4A6kxKTtFi6Qy7 + UXTDaX9pU4iTSNa5xjDR8lq+KM6Siyww38D3MVSN1emRpGPSdL1Vk5llvWbxs9Z9sgNaBVkq0Qry10Gt + +3pquheAlG7yoNsnSKVKXPgSdl3/IrqCsZ9vaO2JYLTpDS7G7kZJPoZqsTYzmnTE5lTsu/oB8FFMQqz7 + VTWk6qhXWMGTmyG9p6p7A0iwdH6Ok9KNBZMVp/mCdalzDo6b2Us7Ayvyjf/V+Umce2P1wY/hWmzMjacc + LqTr7Zq/n+s11Ck+b92vqiVfR7lY8AEAUrrulWDpuGyKvYfWLPvw+ExO1MNfzWzzLUs3zLfOuG5dQHcx + 8B5bc9GU2fnq4bHMYFVQ6YqNCv61xJiWv/TOmRFUkKUTM+KnbAUfBCATDJ035ihatmRJgVVMSKzbbu+f + oMg2C0800QLNTE+ntMaMHdnBooIqE9F9rxwkxpah/pm4d4MzUahvRv617vOp6EEAUrolGWbNOh0wFN21 + KsakJTT/n+JDkO4H8fpXtmUTqQqqTFQUXUrIgCkCFLa8G5yJODpydPML7E9NDwZQdziNorXUjRt1SjN0 + uXwbT7XOEF+dtE6pcV9xLhjVdzCOCwsrqIJLR7SejAdV+/7W9WAAKZ13gg2p3GsyMdFJNkrCUhBn3FKt + M+v47BzNInZj4VkFVSYiyKrv4PwwdMMquHTFN+hOjp5eLJgVAHXfGaEyccUUIbS62EySGkOL+0eyjYrz + uajgSieOmnBCStW+p4aXb2O5+4oWNPAErWBWAKR0XkgyROul67Yp87hyJqMmVjF+84kslq5Up/XeLE5G + 5FpS1zM5PcdDAaT47shTiwWzBiBdsG5CQuk2NRhi/EhLeF/4rAqs78qstt40318qcTIifka1r/mJ9djI + hgKqTEQryJ5B1Xd8q8oagBSB0u1soehGadFU66yi62bdUTfW1BHLM7O7h6idWpU1Qr4LnKxBgaAab8JZ + tTi9kTBB0X1FK3jwBc9omm1lFUCK9T5dV0yYOPyWrrGB63W2e4iORLLC2a4II100kxaWbozZEbjsIEnz + wPKssI69U0qgMhHdeE/TsLSoqu/5FpV1AAlVJkkGM2Jm0ap1FPfH9Z8SPqs4Zsykhe+KNM6soXR8GX+F + k58T54fxOu43HkzRfTvqw4gMzuJw/+lYPyrrAFKZZqmpEgtaVF03/VhaX96Rs+Sr4Eomae2ah2UvITuk + n2pr1icBkGLWmq69yiy6bSu0/L+uO39McYIiT6d6hixDnEWVXTPsAyR0tHZHB09z9MOsTwYglan1Miwn + 3S6LzMZsVV+6tjf2JVQcjqNl8/dMYcg2jv72KFyNEVlkpotmsnL8BIvNqfRJATTiQf5VrVeJFo8/eJKq + repLE2t3tGxe54QspfDVy83VXTlxUSbn/hT1SQGk0iUZVtF167Tx5/Rt6JMDSOmO27LYrNs9ndO3oc8C + IJWucyVV40FO364+G4CUeUzXLJ22qpy+TX1WACmrm9V1zzl9m/rsAFIGhPdpq8rp29KjAEgRQtUbcDk9 + LT0agDnlROUAzOlRlQMwp0dVDsCcHlU5AHN6VOUAzOlRlQMwp0dVDsCcHlU5AHN6VOUAzOlRlQMwp0dV + DsCcHlU5AHN6VOUAzOlRlQMwp0dVDsCcHlU5AHN6VOUAzOlRlQMwp0dVDsCcHlU5AHN6RF3g/wONExfe + iWGCnwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vwAADr8BOAVTJAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAAACMfSURBVHhe7Z33 + exRHnsbvH7pb27fnTffseePdBq9JXoKzCTYGTLAJDuQMxkQjokkCEySBkEgSymGUcx7lHGYkG/D6x+/1 + 23KNenqqZ7qqa4Lk+eHzANO56q1vqurm37799luKEydaxAUYJ6rEBRgnqsQFqIDu7m5yu90+urq6qLe3 + lwYHB2lkZIQ8Hg+Nj49zj/2pExegApqamsjr9foYGxuj4eFhGhgY0IXY3t6u71NXV0cNDQ3U3NxMPT09 + ujAnJia45/ypEBegAiAo3u9WQHRDQ0PU2dlJLS0t1NjYqP8JwfL2n8nEBagAUQHygChhLWEpIcaOjg7d + QvL2nUnEBagAFQI0A1cOIeLciClnqhjjAlRAOARoBOJrbW3VrwM3PZPixrgAFRBuATIgPGTWSGRgFWdC + Zh0XoAIiJUAjo6Ojuotua2ub1kKMC1AB0RAgA7Ei3DPqj9PRNccFqIBoCpCBOBH3AdfM2x6rxAWogFgQ + IAMzLyjlTJeaYlyACoglATL6+vp01xzr5Zu4ABWAKTZMtzEwzQYLhEQBAohWkoDrQoQQI297LBAXoALg + 8iA0BtwgBAghQpCwkPX19b4pNwgikgkDSje4biwmKXEBKkDEBUME/f39umVi025YTRNuK8myZcxB87ZH + i7gAFeA0BsTKGZwDYIFCOOM2ZMkQPG9bNIgLUAFOBWgE4mNzwOFy1RA8Ctix4JLjAlSASgEagVDCNe3G + XHK0Z1HiAlRAuATIwAJXXAMJjUrBsCwZYuRtjwRxASog3AJkQIgQjEr3ifPgfDg3b3u4iQtQAZESIIPF + iVjAytsuA6wrXD5vWziJC1ABkRYgg9X3UHfkbRcFsWakyzRxASrALMD+YQ/VtA1Se+8oDY+GN76CC8Xy + faDCLaMMhBkc3rZwEBegAswCfFDaSa9sz6K5u7LpjYN5tPhwAW2/UknXslp1YQ6OqBcl3DLuQ0UsB3cc + zlqkkbgAFVBdXa1PtaFkgum2c3fLdQHymLUji14/kEfrz5ZScr6bez5ZYAEhHqdzvywxiUR2HBegAswW + 8FRaA1d8ZjZ9XeZ3nCow1QcB8bbZBSJExq3CrQcjLkAFmAW482oVV3Bmvk6r1GO3cFgauFCnhWZWJ+Rt + U0VcgAowC3DDuVKu4IzM251DnX2Ty7VwPLJZ1VNvzIo5iedwLJb787apIC5ABRgFOD4+QWtOlXBFZ2Tl + V8U0PjF1DoiFTb2x1TEjbmdulAF37CSzhUsP15rCuAAVYBTgmGeclh4p5IrOyNl7jX7nMAKx1GZmUv78 + eVR/5DB5FHQ+XL2TeiGOD8dsSVyACjAKEHW/BXtzuaJjzNYy4Tr3oN85/NCsYdW2LZQ762WdwjcWUXtK + Mk04LI04qfHBQuM5VSclcQEqwCjAgRGvXmrhCY+xRLOQHq91Rw5UlFPenFd8AmSUfriCBquruMfYBfGc + rCXDcSjz8LbJEhegAowCbOsZ0SxcNld4jIM3a/yONzKhZcQVG9cHiI+RN282uW/d0K0k73g7OKnx4TUD + ldN1cQEqwCjA8ub+oBZwlsbjCusVyf2lJZQ7+x9c8fnQtldt20xjPXIrm1l2LFuiUemK4wJUgFGAGeVd + XOEx5mvx4ZiX3/ETmiDK16/ji45D0btv0WBlJfdcoYD4UPrhbQuFytJMXIAKMAowJd/NFR5j88Vyv2ON + 9JcUc2M/K/IXzSd3cTH3XHZAVozEhLctFMiKndQXGXEBKsA4F3wiqYwrPEZSnkVtT3Np5Rs+5gqNR97c + WdSd8UhfkiUrIiAb08EF460+3jYRlAkQJh0dgAbhbZ/JGC3g4eRarvAAyi+t3fzO7i9x2bd+WgzYevmi + 71gUsJ1kp4gHZZISLIh1mpAoEyA6ASLEiMIDRXJNWbQxCnDTeWsLuPJEsR53AbSTMZCv+GQDX2wcavbu + CsiC0d6yIsR9yMaDWP3D+90uSgSI+hBiAvZvPBCCVKAiToh1jAJcfryIKz5w4eGUy0L8hc5Du3UXFti2 + fuUfr6NxizoeRGjsBxFgyWS+rIVpOicfQlIiQHQALy2HRYQ1RIwim/JPB5gAUVy2moZDbbC6NbCjvNoA + dX28lis2M0WL36axECKBO5b9RBvqgzL9hNCL97sdHAvQzqiDhUTAipiBJ9TpDhPg0KiX3jyYzxXgW1/k + a50b+Ox9xUWUF6rup1GgZbxDtbUBx/NAHC7zwhLiQBlXDAsoawUdC1Bk1KBhIMSZlqgwAfYMjNGru3O4 + AvwyKVA8E14Pla1dzRWcEcx+9GRnBRwfDBgFmcUHWIkjehyMimws6EiAGDHG+McuVVVV+kibKYkKawO8 + hMSbBcFvRXWBFqm3IN/WrEdr4pWAY+2ANhb1ONhfprwC4cq81ulIgIjtRJMMiI7VrZC1IVEJx4rgSMIE + WOce4goQ74CYX0TCypbSD1fyRWegYu9u6XlfFoPztgVDxqVCuDLu25EAZYJPjC7jqEQj4canc6LCBFhQ + 28sV4JbLFQHH9OblhrR+5Rs+ooG+PumkAsjGgzJ9C7GLWlxpAWKEiK6SRWxh9WkwWFKI01wfmw4wAd4t + ag8QH0jVfjfuj9ivdNUHXNExipcuJs+PwkG7wVvItguEITq4ZcorSDZF54ilBYjkQ7RBYOlCNQTiCAS0 + 0ylRwcBBGJGY2Rwgvn9qSUnvoH+Y0pubE9T6FSz8Jw3V+SctxkKzZ3yEvOP21/RhcIu6YvStTGIhmhNI + C1D05kQbAW4DHSuTyUUa9o3oL28EzoKsOeXSOtOw/8Q4la5exRUeyHt1DvVoAjWen4HB2dxWSymuz+hh + 5SGa+Na+AYAbF0360AeihgDZt0hMLyVAmQls0RsDsJgw6bC2sTyjwkb93uvVAQL8KqXCF+PCqgS1fsh4 + r1pnvN2DDXQ1byWdzVxI5zIXUbX7Hnc/HjIWDceIWjRRQyMlQNGbAqJBrTGeQEPgoSDiWExUWHuY34bD + 4oPmrsnShF6M1wTgsrJ+mvgajh2xyHgnqKEzmy5mv6OLj3Ex+11dlIH784FFEzUcMrMjImUcYQHKjAqZ + 1/p4Dw4LGouJCmuPN7/wnwV5/1iRFqtN3Wf340xL61fxyUZ9OT7blzEx4aWS5pt07vFrfuJj3Chcq8eE + 5uN4oM1ExAFg0dAXvG1WwNrb9XbCApSZa4T1EhEMHjpYTQlxIdwJhM3bHmkgQKxyRr3PKMAjKVOJBOp+ + JSuWc8XnWr6MvJyM0zs+ShnVR3V3yxMfo1QTqPlYK9B3ogVjUYMjohFhAdrJZM2Ijjq78SLKBBBitBMV + dFDfkIcW7Jt6HRPvfuRV9/j26X70kCu+vAWvUl9Ntd/5wIinn1JLt3MFZwaueGjU3vshMh5MJn7HAl3e + 72aEBWj3xAyIRLQQKhIvokEx2pCJRitRQYfibbi5O6fehsO7wezVy3Et+yxZ/l6A+PK1jLc3P0+PdY0Z + au9QC10vWMMVmxVZNV/5jg+FqEfCvYm6YbSJnWsICRCjQCTDAaKjLVi8OKaZ9iurP6TSlBTyGDoMAT7u + C42Ezox0ooJnrG/3n4bbnjj1shCWzgfEfnNeIffN6759YGXwHC09xXQpZzFXZME4//h16hu2JxJ4DFyP + t80K0SQScbqdso+QAOHbRZIJjABR9xtsdNZkZtCW5/6DNmvs+91L9Pj0aRrQGtKYsOBPCAIzLiKj3Am4 + XllTv098IK14soNh/VzLlviLDxnv8aN+Ge/ExDhlV1zWhPQGV2B2yK5N8J0vFKKGQXRgQ+RWs15GhASI + YquIm4PFZKUUuwQTLKzf5p/9ux87f/kiJW7aSJ2aCzYKDqMvUokKOvNxxdTrmHM0V4ylWdjW9fBBgPWr + 2vK532c2MKuRW3dWE1HwZCMUl3KWasmQvQRDJFMFaEeR5AV9YSdcExKgaCFTtGCNfa1GTb8m/u0v/jxA + gIxtP3+Bvl66hBry8vRVxuw4VPJx36KZnwgQ4I2cNp8A150u0X+f0Fyqa9liP/GVfPAeeQ2zC2PeIbpb + tpMrKBnKWpJ85w6GqBsOVZngYcdtCwkQgT7vdytE3S8e0MptFlxN5ArPDFz08XlztTgxmbyaANjxGAy4 + n3AkKjgvvnbFBJj4eLKjdOs3a8r6Fb6+kIabp9qkf8RNN4s+5gpJFpwP7pxdIxiiCaXo/hiYocIg2wKE + /xcVlOgNB7OwiWtWcwVniSbEg3/+E2UmnKThH7NwNAbe4eUVuZ1QW1tLe69OzoLM2ZlFhZUtNK4J3Zj5 + YlUzFqCyY9r7Kuhy7jKuiJyAZGRo1F4Nzo5AjIjuD28WqkRmW4A4EawIbxsPlgzwtvHA/lYZ9rgWq+z8 + 9S/5QrPBDi1OvLNrJ7mrqvR7QuxjnJ/lXVMEnHPblUpdgEsOF9DwyChVJl6ZEt/cWdR+O8W3f037A/o6 + 602ugFRQ3jp1rWBAIMi8edt4oL1E9odmQpXgbAsQ2W8oNRvBjeKGedt4IP6zutmmoqLJ7JcjLhG2vvAc + XVz+vh4nQtS4R1h10WlCMxDgByeKdQGeuFOvJxjGzLcOGa+23/iElwoaLtG5TP60mipSS7cF3CMPxMV2 + MlUG4mmR1TEId0LFmbYFCDGJxE+4UZEFjcEy7KLr12nXb36lRIRgy/M/o6OzX6GS5CQaHRzwJSqiE/UM + CHDhvlx98UFFc7/+MUkmvurtW6hV2z443EsPKg5yBaMSuOCk4k36NB7vXo3A64gklqgsiBgVnD9U4mJb + gKJxk6i5DtYQCKqHNPffWlZGmacS9Hhw/x9/Tzt/9QvHotz/h9/pceKgZglggWERRe4b1NU36gtP3z6U + T0P9Q1S89F1dfJj79WqiHhjppG/y1nIF44xF+jQcFiRk1Z6kuo7HVFWHb0/bNxQiiaVoWAVC5QG2BSh6 + YcRzIoIVTVgglP6OdmrMz6eHx4/R5VUraO9Lv6Vt//k8V2ihgIVN2rKZuhoadLchcv+uijr9q/e7rlVR + R+ptve5X+NbrNOpuo86BGrqa9wFHPOJgRcyF7Lf1sk1x0zVq76+kkTH/8EFl4sdDtBKiTICiNxrujNmq + xoR6YWV6Ot0//CV9/d5S3cLB5fJExwNx4qWVK6gqM5PKy8t1MYZKVB4XVulfPkjPbaKid9/WMt5Z1FdY + QI1duVqy8RZXTHaAO03MWUWPqg5Tdft96h7U4ssQJRbRdg+3oQilG9sCVCUQHiwr5W3jAUHYHhDavpiu + e3ThAqUd2E9nNYHAfYcSJVz7iVfnUeGN61RfUxO0ApCaVU7z9+ZQ/c0kvdzScfcOlTTfsFzDx2cRXc5Z + SndKtlJ+wwVdvGPeQX2hhciMRbhDJdE54agJUGR/NIBIVR4NLCJYnJ+90ANQoxvs7tKTkLv791HCawvp + wJ/+aClKzDunaRa1vKCAmwXeyiinj47nUeHbb1DdySOUUXWUIzAji/Q53+sFa7XE5IA+e9E73PJj7OZv + bZHIiUwnQrAiyaLdRQMMUQsban/bAhT1/cb98VKOx2M9itEAdhcwAtE5ZpRZQnWiZ2SE+rVzliQnU9K2 + rXRk7mza9/uXdJeMojaEiHrixXVryaW5Z2NJKvF+JZ3ceopcWz+i5MJNAYLDglJYt1tFGyiz8iRVtTyi + UU+/XpYx3gMPDB5YNd42AG/g9YzT2KiXRobGtIy7nbo7+qmve4h6uwbJ3dhDLfXdVO1qpYqCZsq/X0O5 + 6dWUmVxOD26UUmeH2BcNpqUAS6pb6G/vf0F/X37Ix+sbTvpYs+eSxkXa8MU12pVwmw5fvKfz1dVHdDEl + R+fy7VxKeuii5EcuuvWgiFIziii/rEGnqsFNDa1dOu6ufuof1MSkMTA0QoPDo9TU0kZdPX00Oubx4fWO + k1ezpMAc47E57NEhzQVqLsd166aeoByfN0dPVjAnfWzRQiq8m6ovCzt/u4werl9GVzKW6IKDdcMsx/2K + fborxnsbo55BzXJPaOcdplbtfiCY0REPjQyP6cLp6RigzrZ+aqrupPrydirNaaTizHpNLFWUfDGLHt4s + o+RzeXTjVA6d3XOPTu9Mp6OfptDRT1LoyKYUOrQ+ifatvk67V1yjne8n0valV2jbksv6n+zvZnYsu0Id + bV1CtT3RZDTU/mETIKan2N8hkp/N/ixsPD/3c3ph7mad5+d8PvW79vdfLthGv5i/Vf/zz0v2+5i35ijN + X3dc57X1X9GbGxN03v3sDC3bcoZW7LhAq/dc1gfE7lOTnLnxmBIupdOe3Qm0ecWn9N4fZtG2uQvp2KZt + 9NXpDXTi7Ba6euUifXP+Nt25lE+JRzPp8uEMXTBndqdTwvY0Ov75bTqw7jrth1g+uOYTB8QAzCIJJ7he + V0ePUL12WgrQVdVMzxmEMVN4TuOdZevp9tHVtPGTZG4nxzIQYGd7XIDTEljUM1/soe8T/koV59+nBbeK + ab/mEnkdHatAgO2aCxaZAZo2AjTuX1rTMqMECLfd8CiRfjj1V/rh5J+p/tJK+ntSMa1/oCUjO9O4nR2L + IFZsa+mYHkmIkzJMs7uHXpi3mduZ04kXtVjy4Pm75K1I9YkPDN/6iGbfLqGXk4vpSkUbXTj4gNvhsQbi + UHdru1AZRvWEhG0BOilAIiP9heayeJ06XUAWj2TqSU2aJr6/+MQHnt3ZSAtSS+lvmhWcowmxTMtorx57 + zO30WOLYp7fJ7RZ7zSJqhWgnykeZ48X501OAyLC3HLull3Se1N4PEB/4Pm0zfZJTpwsQvHOvgnqHxuj6 + yWxux8cKX21NDboKnYfqGTHbAhQNPs1TQn9avI/bwbHMH9/dSykPC/X7txKfLsD0LZRQ3uoTINhd2KgX + iJPO5nE7Pxa4dOiRkEWDUFXPiNkWoOhreebl2B9sv8Dt5FgECdPavVf00KETixHKkyzFB76/t51Sm7r9 + BPh3LR5MbujSi8+3L+RzBRBt7l1zCSWXcNVWq9Z5QLDKLKDo8m2k9sbpr4Pn07idHWv8z5u76daD4h/d + 0gQ9qbhFPyT8H1d4jGcP91BFz5CeCRtFOO9OCVV39VFLc4ve2VYzEtGiJKdeaE5d9LUMTJmGEqxtAaJY + KZKumxcYpGSUcDs8VkCst3TzWXJrgpm85wl6WqFZvgRry8eAAN1azPdKistPgGDpvXIa9k5O92UkldGO + 92JDhJNF6G6hIrTou8HQQKgV1LYFCPWLvD+ABjcmLmW1rTFbC/z1oh10MSVXnxdm9/u0MiWk5WM8e/wl + jWoiW5BaFiBA8IWrmSZ+PG/23UpNhIlcUUSSIxuT9QxYZKkXVhSJ7I855lCLQGwLEPGfaBHSGIB29Q7S + rxZu5wogmixYd4Jqm/yXgj3RLZ898YHh1F162yxJ5wvwH8kuymibeuEq/0EN7YyyCJGAiPan6P521hra + FiAQnQ1B5jwZS03+e86HR7giiAb/9c+tdOhCup/Vw+LVp6XfCIkPPMs+ph//ZUkzV4Bg3p1Sah2cKvi6 + shpo1/KrXHFEggJtEIjW9ET7345ghQQoOgJgfo0m+Mil+1wxRJrZqw5TVqHp/+6YGKenJYnC4gPPCs7q + 57he18kVH2NlRpXuqtk1q4paaM+Ka1yBhBNMwWEOWOR1VMyWiCwaBnZKNkICxA2IZMJw28bFlJhJiGYc + CKu3KyGFRsY8ejbnWwcH8bmuSIkPMAEWdQ4EZMJmjpf6Z531Fe20d9U3XKGEi3N77ullNaN3CgXaS7Tv + lVtAJCKiH5s03kRP/xD99+s7ueIIN39ZdoCyi/3/7w0MqFHtmZ4WX5QWH3hafEk/HzLhl7V4jyc8BuLB + LLe/5Wmu6aS9KyMnwqzUSmFvJjpjgjKcHQsrJECoWqRuBFAHMt748u1fcwUSLlBeWX/wKvVq4jfeF2Mk + 44Qj8QG4bpxrYMzrmxMOxmtpZdQ9MjX/inZ15VVFxBLC/TbXu0Nmp2ZEZ0CQgNiZYxYSIBANXFE3Mr7v + kZZdrrlhvlhU89Jbuyk1q8xXAvEDCUfRBU18/8sVlQhMgOMT39Li+xVc0ZlZn1VLXu0e2OwCBqm7qYcO + rL3BFY4qvjmRJWxEYM1ESnDAroUVFiBiOpFaEDDeDCb1f/vGLq5gVIE484MdF6inz2KhpRbzPSs8r0R8 + 4Gn51Ffqt+TVcwVnBrHimbLmgBeOutz9dGRTeFZXw/q1aIlSsJeceIjGi9jXrsUUFqB5hsMOeGDjA2Ce + lSccFSDGTEzNs26wcS89yzvl2O0aMQrwSk07V3A8ZqW49MTF7/408Ebb8c/vcEXkhNO70nVr68SA2AGz + K3ZnWIQFCERXxpjdcGFFo9/LQyqA1Xvrk1NUXF7jtwjCD4gv+5gyy8fAlB27BgrOPLFZseiufzzIGBoY + pYRtd7lCkgFTb5VFzUKLCQAqBSLzv0Bk4YqUAEVjCGCcloN1WvDRCa6QZMD7GWdvPva9e2xOfBjIVlWL + D2Dajl2jaWAkZCZs5tOcOi1+DLzf4cExOrVDzRL/c3vv655IZPEpEDU2QGTtqJQAZUaFeTXN9fRCrphE + mb3qCFU3+v9/vFarML7rb6V/Jb7NFZETjAIc1AYBlufzhGYF4sHEWn5Yg3eGz2iukycqu2Dar6lm8oNL + vGtYASsmegy8XagFCEakBAhE4wJzYXJ4ZEzPUnmisgPeAd575g6NWXxxwapy/91QF/3r+vtcIcnSm3NZ + txSgoamZFlvMCQcDS/kre/lJ0+iwh74+IP+eCTJfCMmuW2TAlYoUn4FowiItQHNiYQfz5PS5W1lccYUC + X1bIKwtdDkIsyB2NnmF69nC3MneM90SM59+YXcsVWShQwhn08EXS3dVDFw6JixC1xdbGDmGPBbHKhFqi + hklagOhc0WwYrtEYU+CzGSJL9X/+6hbafPQmDWnW03jeYMAlcO9TGzxPq+7QD+fncEUlwpNa//+396Rp + eb4I2/IbAuJBiAezCuPeCbp5Koe2L+WLLQBtv4KHtVJxHAauyNtyAMVt0ZkyaQECUbUD86d4r6UV2CpM + /+GdPfSooEqzuoHnDAWsrpXF/m6wk76/+5mjssyThky/c6Y393DFZQckMFjKj/PgfiEE44vjWOJ/51Kh + rdXV+DSIjJDM4ZJdZI5xJECMTMuShwXmBGFk1KO7VJ7oAKbSVu++TE2t7cKjywhED0vAzQK1jn7SlDMZ + G0oI0SxAxHKhFiUEY+6dEqrVzgEXyBMPRJh+tTioCA+uu0kd7m6hr44xkDCKihb9iviPty0YjgSIkSL6 + uiaAFTQ+YLarTk8qzOL7zWs76cb9Ip/lgisVLSMYwXnQSJbzoBPj9KQln75PXiskxCfNeX7nwRJ80VKM + mTdTXTQ4Zv2seJYHN0q47hjrDGtKW4UzWIA+lXHZMiUe4EiAQFYUxodEY2489I1PeHDJS7eco5Z2f4uH + /XAcE6QsiKfQOcHu+7v+NnpWcI6+v7E86Btx4Enr5KubDMw9v54mngmb2V8c3KUhHMlILvezhCg4Fzys + 0a2naNYLRIrIDFnRAscCRCfKjDRM1Rhdat/AsP4eLt7POJ+UzS3MAph6jDbeNhEgYpwHMVJwQWvbxgbp + ac09epZ9VLOO6+hfV9+lH87Nph9O/21SgG3FAcehuMwTlQj41Edac+hFAPjgpL7EX7OGePsORkHUhQLR + Gh5DxmUzHAsQYNTIWEEI19j5OSV1VNccugFwLZl4gwcSFIQRaHiIm7dPAPiyqVdrcI8W/3qGdddt3udI + SQtXVKLMTy2lFsNSfiuKH9fTzdM5+nOIxuUMmbILrJ9M8sFQIkDchIwVlLWeACNOtAwUDAgRbgT3A0vg + 1M2nNHZxBSXDKtNSfit6ug2rvAVBsoLn5m0LBo4TLVYbUSJAIBuEwg2LfJ/OCI6TcRnBwGDCPWHdIywC + riEjxsLOAa6YZDlqWspvBnGtyDseRmQHM9pKJgk1okyA6CQZEw4gXtvuzwRGrfEL+CphYoRVREPDQuJe + 0dHoNPPIxwDE78iyXQ3NegzHE5MMeOndvJSfgRhMdIUzA88om0BAtLL9xlAmQIC6oIw1QyPIiheg0xET + OnWbdsC9IoGC6HFNCJMBceJ3CBRz1FjvxxOTLIgH24f9RQ8PIOtBgOzgx2DDsbxtIigVIJAdTbAmTmI6 + NCJELBMGhAu8hskTkhPWZNaQZ3xCHwgQAAYf79p2cBL+mBNIWZQLUDaVB2gQkW+VmEGDoFOcnEMlB4ub + uCJyynFXoz7YIELede0gM5fPMJfQnKBcgMA83ysC4hmZbMwIXCDuIRIuORgiy/NF+IcWWxZwlvLbBd5G + tozlNFwyExYB4iad1IYwMp2k9gDH4x6cxEdOyW3v5wpIBW+ml1PvqPggZ66bt80OsjGjFWERIIAVgzXj + bbMDRqiKB8U9YMSqbDS71PUP08sc8agC36LhXdcKiM9J7AbXK1vqsSJsAgROqvJoJDSWCuGwc8GyOomb + RMGL6nMFl+fbAV9XOFHWSmNaMsK7Lg8mPtnnR0iF43nbnBBWAQJYH9kRh+OcZnpGIGa4ZScxqiiv3XW+ + KMHIkvsV3Fc5g8HEIys+NoBl+zEYYRcgHtpp0ArBOE1MjECIuCc0quxMh1225tt7UT0Ur94ppfNVbhoV + sHoAsTAGsZNnVBGTWxF2AQKIR2ZhpBEcr7q8gk5BTINpN8ScaGTVYjxb2cYVlF1m33bR/qJG6jAVoO3A + CvS8bXaRWWYvQkQECNDRTgWEhnAqZCvgphCzslkN/F1F/Hm/RW55PqbedhU26O8Z884bCrS3k8I+QPwu + W9O1S8QECFTU+HC8k3jGLmh8uC7M7AC4bPwbgwArTmBdzG4JIsbv2A4BwPpk1TQKLc/H17WOl2nXGpKL + e2HBcV3ZuWEGng2hD2+bSiIqQIBR6TSpYHFlpGt86Fz2Uj46GYKE+2ZgYOB3bIe1x/6dI2P6O788sTGw + /dPcOnrQ2qNPs/GubQe0K9rFqeXGQMKz8bapJuICBOgkFUEtLCpcsuq4TSUolZiX5+N9kbfvldM2LUFJ + 11z0sMW7wCLAMquwWBBvuDJeHlERIIAIVcRYGPWI2aI54xEK/D9ySx9UaslEE31T10GtmnsVqeEFA8+v + asYHoouk+EDUBIiHhJlXIUIAC6DC/YQDJ27VCoQhGMRIElQIBueLRGxtJmoCBGg4Ve4YoPEg6nBnbtGG + DTZVxXTmdiMtPhBVATJUF5qRwSJzRcITSXcSTvAciHfxXCrroRj8GLTRaqeYECAIR6EZFoJNvcWia7YD + rBIsOp5Ddl7dCpwvEqWWYMSMAAFcC+BtcwLEB8sBNyP71likgTgQniDBUuVqjWCwOy1UqyCmBAiQzYXL + JeCcKBDjA9roXHRyLLlouENYO9QU4RHCEZPheXGNcAx0GWJOgAAjHhYrHCOfAauIOiI6G9eCZYx0EI7r + IfZFQoH7gDBUJWQ8mCdwOhGgkpgUIMBIRXyCWQXedpUwywjLC5eHTlKdGAF0PESG8+M6CAnwfJEQPlxu + tDLdYMSsABloOJX1Qrswd4jgH0A0sFS4F7hvCBQxlBn8ju3YD/vjOHYObFOdSIQCgwv3E4mBLEPMCxCg + EdGZsFK87ZEE92IX3vGRBIMXAyCWKwDTQoAMxGkQYizFMLEIYmdY4FgYsKGYVgIEsCxwdXArsRbPRBu0 + B8IGiG+6tM20EyADbgVBNcQYC+4umuD5EePB3U437zBtBchAg8Mt/1SFiFIShBfLq4GCMe0FyEDWio6A + aw5n/TAWgHvFgENmPV2Fx5gxAmSgc+CaYRVVzy1HGzZLFOuZrQgzToAMuGMIEDMM0ai/qYIVr/EcmD6b + aWHGjBWgEVgLxEqxOgdsBPcF0WHQ4H4hvpkcUvwkBGgEYkTGiPhJ5euXTmADhN0T/j7T41jGT06AZtiy + J8RVAPEjVqKEy2UjWYLAcB12TcR1quedpws/eQHygAtElom4CxYJlglJDUQDsWIbRGoFtsOFsvlgHA9w + Phz/UxUbj7gABUB8BpBph4LtyztPnCniAowTVeICjBNV4gKME0W+pf8HNi1HsqI6WQkAAAAASUVORK5C + YII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTCtCgrA + AAAUzklEQVR4Xu2d6XtTV3rA+7Wk7UyXp326zjPtl062TmY6nWeeztZl2k4z05k+zwwEMGsYIDAQggmB + JA1g4wWMDXjF7FvAYCAshgSwDd4l74tsSZZlS5ZkydZi/oO3970TUdV5ZZ17dSWdc68+/D7FODp6fz7r + e97zW8+ePYMsWTJFVsAsGSUrYJaMkhUwS0bJCsjIfDAI4ZkZCLldEJx0PufZ/DxMeHxgc3ue4/YHIBAM + wbz036jfleX/yAr4OfORCIR9Ppi122G6uQkm6q+D9UQ19H+wF8xbNoP5rY3Q9eY66Fy1EjpWvvGckMcD + /1FQCa/sKnjO3+85BD/Yd1TmJ0XVsP3MNSi7+wguPemEDosNnN4ZmA2FyM9hNAwrYGRuDuYc4zD14D5Y + yo5Az47t0LV+DbQvXwrtb/ySGRTwX/PK4Wvv5DPx4s6D8OquQvjnA8dh+bEzUPWgGVpHrOANzELEgD2m + cQSUgotDqLupEUZKS+QeTalsFEoFpHhxZz58471iWFp2WhZy0DEJYalHJtuhM3QvYNjrhan7DTCYtw86 + Vq0gJUoGLQRcyEtSL/nvByuh8OYD6LY5YJ5ol17QpYDz0vzK0/IUhgoPyvM0ShytSIWAseCQjXPM6k+f + yIsdqr0ioysBcYXqqLsC5k0bSFlSQaoFjAXnjltPXYWnw2O66RV1IeCs1Qpj1ZXSClX7ITYR6RQwCg7R + Pz98Aj7p7IVgOEx+J6IgtIAonuVoKXTkLCflSAeZEDDKixKvF1bBHVM/hMJiLlqEFDAoDbWjleUpWVQo + JZMCRsF54s8OnYDmQYtwWzlCCRgJBmHiZj10vbmGlCET8CBglJdzC2BT7cdgmXST3x+PiCGg9FftHxyA + 3twdpASZhCcBo3xzzyE43tAIcyH+54fcCxgJBMB68kTKt1PUwqOACG5u40LFbHWQ3ysvcC2gf3BQPiKj + As8LvAoY5bXdRVDR0AThCJ9zQy4FnA+HwVF3NaOrW1Z4FxDB1XJO+Tmwuz3k951JuBMw5PXCUEEeGWwe + EUHAKN/58Ag87Bsmv/dMwZWA/qEh6N62hQw0r4gkIILpYkfvPuZmu4YbAX2mLuhcvZIMMs+IJmCUPZdu + cXGKknkBpb9Ed+PjjByjaYGoAiJ4ruyfC9JxSROZFVCSz3mzXojFRjxEFhBZcewseAKzdHzSQMYExBR4 + +/mz0LFiGRlYURBdQOS/DtXApHeGjFOqyYyAkny4uaxFRnKm0YOAyI8LquS7KmS8UkhGBBy/dEEX8iF6 + ERD5aXENePzpHY7TLqDz9i3hh91Y9CQgsqzsNMykcWGSVgHdzY3cnumqRW8CIr+quZy2RIa0Ceg1dQm9 + 2o2HHgVEdp6vh0gazo/TImDAYoHONTlkAEVHrwIiedfvpfzuScoFxGoDPW9vI4OnB/Qs4Cu5BfK9Eyqu + WpFSATGrBa9GUoHTC3oWEPmHvYdh2Oki46sFKRVw4vo1Mmh6Qu8CIpjYOhtMTS2blAnoHx4SMrlAKUYQ + EPMJ91+7R8Y5WVIiIKbR97yznQyY3jCCgMjfvVsIj1KQS5gSAW1nTpPB0iNGERDBil5aJy5oLuDMwIAu + 9/viYSQBkb2Xb5FxV4umAmJRoL7duWSg9IrRBMSM6qZBCxl/NWgq4OS9u2SQ9IzRBEQwfSukUf1CzQTE + DeeuN9eSQdIzRhQQV8VnHreRHihFMwGNtPCIxYgCIv/4P6WaZM1oIiAWCzLCnh+FUQVE8HYd5YMSNBFQ + zm4mgmMEjCzgd6VeEJ+joJxgJWkBg64p3Wa6sGBkAZGj95LrBZMW0Hr6JBkYo2B0AX+4/1hSb54kJSBW + oDdtWEcGxigYXUDkfFM76QcLSQk4ceM6GRQjgPdaEBTwR/kV8HLuQXl7ggqQ3nm9qFr1vqBqAfHtNNHq + uKhi+VK5l+/buxvGaqrkJ7y8He0QsIzINarlK6auaegfd0LjgAWutpqg+NansL7qIvxL3nG5aikVND2B + JYLxtSfKk0SoFtDXbdbN1covILXLvHmj/FYc1igM+/3kd5AIrL2CctY+bIH/PlwLr75bSAZQD2CZD+o7 + SIRqAYcPFdHBExlJPDzLnn7SBJFZbbM+8OVMzCx+98JN+VkuKogig5nTrhnlf6iqBMR5T9e61XQQBaVn + xzbwtLXKJUOoNmsJPumae75ePtingikiOP+92NxJtncxVAk4/fQJGUQRwRMcx9UrcgV+qq2pBJ9V+M/C + KjKgIpJz/BzZzsVQJeBwcSEZTNHArG3/0CDZxnSB56lYqw9fP6KCKhL4TrLS+jKKBcQnTzvXriIDKhJD + B/PkN4OpNqYbvHuLj1ljQXEqsKKAw3Bdq5lsYzwUC+gzmciACoO00BitOJ6WuZ5SPusdgm9Jk3kquKKw + ufYK2bZ4KBbQdkrsozfLsTJ5745qGw887h+B1wReJX/7/RJFCQrKBJyfh+6tm8nAisDg/o/ky/Jk2zji + WpsZXsoVc06Ic9l2i41sF4UiAYNTk8JeODJLfziYtU21Sym4pxeWRJ6T5pBRQqEQRDTsWfG1dCrAIlB5 + v5lsE4UiAT0d7WRweQcLoPt6esg2sYLC+SSBHQ4HWK1WGB0dBYvF8v8YGxsDu90ObrdblhJFpX4XC1ge + 7RdHTpIB5p1NJz4m20ShSED7+XNkgHnHWltDtocFFG9qaooULhHj4+MQCATI38tCt80hXwingswzOA9k + /eNTJKCIhYbwTBe3jqj2JMLj8agSbyETExOyyNT/IxFYEoMKMs+8uqsAbC62Z8EUCSjirTe8Kkq1ZTFw + Lud0OkmZ1ILD9qyK82Xc2MUNXirQPPOgh22Dn1nAkDSvEW0BYt6ySXFSAfZUOI+jJEoW7E1nVPTG+fX3 + ySDzTHlDI9mWhTALONPbQwaZZyau15FtiQfOW3DeRsmjFSih0p5wfNoLr+0Wa29w+5lrZFsWwizg9JNm + Msi8gkkGoelpsi3xmJycJKWJR39PF1SWFsHBg4Vw7c4jGCF+hgJXy7htQ30GCjyqW11xngw0r7AmJjAL + iL0JFWhewU1n3Din2kKBWyyULPFA+cqPFMD+/ft/w4E8uHG/mfxZCuxpqc8RjzumPvkVdCrYPPL9fUfJ + diyEWcCxqgoy0LyC91WodlDgogMXCZQoFAOSfBWx8n1OafV58ufjoWQ+6J4JwNcFSlbAqwgsT8IyCzhS + WkIGmktWLIVZO/txEG63UIJQDPSaoKK08AvyYQ9488ET8t/EAxc7rPtl+OT+zw6fIIPNI1jgnCVDmlnA + wQMf0cHmENOmDXKpOKodC0EBWHu/wV4zVJYVkfLVSXNA6t8kQsmCRKQ9QbyoNOCYJNsRC7OAIpXc7duz + m3n+h0dmlBgLGZR6Plq+fNXyIbjwoT4XBeYMUsHmFczsodoRC7OAIm1CD5cUk22gYBl+5TkfNezmJScf + YrPZmIdhvPoo0kLkZkfi83d2AdevIYPNI/ZzZ8g2UGByASVGlC+sdmMoPFwGFy9eTMjDp13k70ZwX5A1 + iwYvM4l0z7i+vZtsRyzMAor0pL7jCls2RqL5Hw675SW0fEooPnZy0T1CnAZQn28huBIW6e7IlRYT2Y5Y + mAXse28X9O7cIQSuzz4l27AQFBA3hSkpkOaG66RQSikqOwHDxO+Pwpoxg0WAflJcLZfCEIGG7gGyHbEw + C+j0zIFjWgwCQbYhDYe+xQTs7WqB4oJ8UiolFB+tXVRAP2vlBekPZs45DHMTQ0IQmUu8z8ks4MpDrbC0 + 8KkQ1D9lO2VI1AMiXS2P4kp4QFqEFBcXJ+AQXL/XSP7uKKxbMZHZGWjJWQItK39bCKYenSbbEQu7gIfF + EfByI/smNK5CKSliMckS5n1BwPyiEmiWJtrUv1FCkPFSfMgzAa2rfocMNo9MPTxFtiMWZgHXlbWRweaR + U/fHyDZQsOb9pUpCJatgHNZaV/0uGWwecTVdINsRC7OAG462k8HmkfyP+8k2UHi9XlIMingS5iUhIfbA + 1Oei8HTdIQPNK+4nl8l2xMIsYO5JMxlsHtklfdb5ebodC8G0KEqMeJhaHtMSFh6GpjYz+W8Ww+Vif4t3 + 4u4xMtC84utJvBvBLGCe1KtQweaRNUfaYC7EfkVSaQa0qZWWsLRGWTYMwjr/Q4aP55CB5hGcq86OJx6J + mAUsvTFEBptHlhU9hV4r+x1g3Aah5FgMWcLCWAkPwNm6u+TPxgNPYajPQzEfmgPTzpfJYPMIzlXD/sQJ + wcwCnrg3SgabV84/ZC8Zi9sxalLxfyMhbtEcgNqLN2BkhP45Clx8sJ6AIMGpMaEWIK1rviR9bg3zAT9p + myADzSs4Z2VJiIyCe3EoBSXLYgwO9EFvbx8MK5APwbvG1OeIh/PucTLQvGJ65yWyHQthFrB1cJoMNK8s + L24B65SyS+FKElOTQUkiKjIfCUH37m+SgeaV/oLXybYshFnAwfEZWEYEmmeq7ih/1xZ7JkoarcDkB6WX + 1P2WdqE2oJGRynVkWxbCLKB/NgwrDrWQgeaVtaVt4PEre8UHe6ZUSYjyKVn1Rhks+QUZZJ6ZuFNGtmUh + zAIim8s7yEDzzAUFi5FYtB6OccWrpjzHrL0P2tb+PhlkflkCHhNbRQpFAh6pF2crJsrqklZwuJWXxEBw + YZJslQRc2ExPTyua8z1nPgIDRT8lAsw3bdIKODjNlhCiSMC6J+NkkHln/6U+5pMRCrw+qXSbBodbPOVg + PeelcLfUCZX9EqVzy1fJ9lAoEhA3d0VbiCC4MX2nY4JskxLw2A6HZqx2hT0jShYFz3RxmEXpMMFUVY8X + Q9Btg47Nf0kGmHeGj60k20ShSECftBDJESgtKxZMJxtyqCvTFg+ULBbqZ9QwHw5Cf/6/kcEVgckHVWS7 + KBQJiOw+3U0GWAS2VnXBlDf9D9IoQpr3jZ19RwqkeEMv0rr69yAwlvguSBTFAl5tspPBFYVdp8xyT061 + LeNI8tnrDgg574vSufWvYT7C/v0qFnAIN6SlORUVXFFACV0+vnpCDJrt4w8k+V4gAysKluoNZPvioVjA + YDgC68vESU6Nx6+l4djiVPcMq9ZEggGw1GwUuueTkT6/p+s22cZ4KBYQqbprIYMqGrhHeN80KS0g6Ham + g1l7L/S8/x06oILRsenPmVKwYlElYM+YV/hhOApuKxVcGQC7S91mtVoic34Yry+AtnV/QAZTRIZKl5Ft + XQxVAs4GI7DhmHjHcouB59xnPh2T7z9TbdYKTCx1NV8E085XyCAKCw6/HbfINi+GKgGRUw/GyECKDt5/ + rrg9Iu8ZRiLa7e0FXVZw3isH046vSQETfK5H0Pnrv2G6iL4Q1QLapgJyzh0VRD3wRlELbKvugkuPbfKU + Y9ofUpTgGg54IGDtBmdDuXye27buD8nA6YWxszvI7yERqgXEYOw500MGT2/gfHf1kTbYXN4pnyuflnr/ + uma7XIEhGIrA5Ge10nyuEKwXdsNIxVr57kbH5r8SfkuFFUy/x5IhlCeJUC0g0tTnEvJsWEsw37Dr7b8l + A2MU+vJ+xFwQdCFJCYhXH7dUdpKBMQqGF1DF3l8sSQmI1Lc4yMAYBaMLaH73NUVHbwtJWkD/XBjeFKhs + h9YYW8Al4LxfSXrBStICIvUtYiaqaoGRBTTv+rqcQEE5wYomAuL58Kbj+tqYZsWwAkpzP1cj23Nci6GJ + gMjdTqchV8RGFbD7vW8l3fshmgmIL/nsrBWngpZWGFFAvKPsNTeQHihFMwER06hXPkGgAqVXjCgg3lOm + 4q8GTQXEZ0VLBLy6mQxGE7B9wx+rPvWg0FRAZMoXlCsSUMHSI4YSUFp4sFY8YEVzAZEHpkkyWHrESAL2 + fvg9+cYeFXO1pERATGPCOs1UwPSGUQRs3/AnTBVPlZISAZHpmRBsNMDeoCEEzHlBzvih4pwsKRMQ6Rzx + CFdRSylGEHCobJkme34UKRUQufjIqusNar0LiMdtkYCXjK0WpFxA3KDGSz9U8PSAngXEeV/AaibjqhUp + FxDBjBm9npLoVcDWNV8G91O2Z2+TIS0CIpPeOXirQn/Jq3oUEI/aJm6XknHUmrQJiIw6A7rbpNadgDlL + wHZpDxm/VJBWAZEeqw9W6mhlrDcBR2u3qL7foYa0C4i0DU3rRkL9CLhEfgosmfR6NWREQKSx1yVssctY + dCGgNOwOHV0uV22gYpVKMiYg0jHike/bUoEVBeEFlOSznNis+RkvKxkVEBmwzwhdZ0ZkAXG1a734XspO + OVjIuIAIVqbCMhhUgHlHVAGxmoHj1mHp+0/fgoOCCwERrFiKlUupIPOMiALiwzdTj8+QcUg33AiIzMyG + obhuUKizY9EE7Nz6VfAyvGSeLrgSEMGiR1ea7MJk0QgjoLTY6N33Qwi67eT3nim4EzCKedQLWwQ4uhNB + wLY1Xwbb5fczttJdDG4FRHBIxvfpeB6SeRcQC2L6+h6S3y8PcC0gggXEm/vdsInTlzp5FRAfjBk9uRUi + sz7ye+UF7gWMEghGoPz2CHdVWbkTUJrrYcUq30AT+T3yhjACInjvGGs3f3Cuh5sq/TwJ2PHWV8DxSQmX + c714CCVgFLx1h9VZ364xZVxEHgTEzGV8Xy484yK/L54RUsAowfA8fGaelE9RMiViJgVsW/9HMFr7Fndb + K0oQWsAoIUlE7BHxJc9016bJhIDtG/9MLoiOTz9Q34dI6ELAKLhi7h7zyqcpK9K0WEmXgK05L8iLC+e9 + 49JQ6ybbLyK6EjAWty8Idc3j8mWoVPaKKRVQWtFibzdSuR58fY/TmqmcLnQrYCz4qM7lRps8RGu9jaO5 + gFJPh+e1w+VrYLr9RtozlNONIQSMgts43kAIGjqdUHh1QH5B/Y0kFy9JCygJ1/6rP4Xeff8EtssfgH+k + LaP5eenGUAIuBLdzsIYNVvM6eX8U3j/XA1sru+ReklVMZgHx1SSJjk1/Ad17vy31cKvlPTv/WNfnqfD6 + G15ZMLSAFLiixov0NtcsNPe74GqzXX6aq/TGEHx0oRdyT5phe41JBvchfYEw9B/8sfz6pUzuq9Dz4Xdh + 6MgvYfT0NvkV9MkHVTAz2Awh76T8TKse53JqyQqYJaNkBcySUbICZskoWQGzZJBn8L+YWOTeTnNU4gAA + AABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACWCAYAAABZ7IOdAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vwAADr8BOAVTJAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAAACmpSURBVHhe7Z1X + dFzHtWDn9z2veTPz/uateTN/s9ZYY1sSbVljK9rPlmSJoiiJYEBizhnMJBiQSIIRJEEQIEDknHMOjRwb + OeecAUbo80ydAhrsbpzuvvf27QCSH3thSexQF3ejTp2qU3X/09OnT+Ed77AU7wR8h0V5J+A7LMo7AQUw + Oz0NM5OTMD0xAVNjYzA+MACTIyP834bHZ2BkYgbGJmdhYmoWJqfnVrz/Hbp5J+ASKNloXy901VRDXUY6 + VCclQWl4OGR5eUH6rZuQeecO5D3ygRxvb05RYCB/n1dCE0QWdEJEficE57RDYFY7BGS2QRT7f0mlPZBe + 2QulTUPQ3j8BQ0zWmdn5Fd/9NvN2Cjg/DxNDTIqKciiPiYZcHxTrAf+JYhWHhEBJWJheCgP8+WehdMll + PXpJLOmG+OJuLmpwdjuXtUA5AJ0DkzA/T7TvLeKtErC7thZqU1Mh/7Ef5Dx4AIrgYCgJDSUFM0TB48f8 + M7G3o6QzBPaOKCL2iHMstA+VFMNkVxf/49Bu95vMWyHgQEsLJLm5Qr6fLymTFMoiI/ln+6S2kIIJIbqQ + Ccc+Y7S2Bsp37YA65/NQ73oF+rMyYYK1eX5mRuM63kTeCgExcci+f48UyRjws33TW0m5DBHPwjKGYfyM + ztAQKPph7SLrv4fijT9D9fEj0HT7JvSz8ehYQ73G9bxJvHECzrEQVlbXBnNzmqEs56E3KZE2Bf7+kObp + CXHOFyDs6BHwc3SA+z//BHfWfgee//EXuPr5Z+D68R8h5PAh/rmBbExHCWaI6MJOGBid5p9Rc9LptYBa + lNhuhtqzp6DlwX0YLi+Duakpjeta7bwRAs4z6XoGRiA1vwbuhmSAd3g2pBfWarymRaHgCYa6bPjfKdeu + QvjxY+C9yQauffk5XPzgd+D8u98YJHDvbv65Bx6Uw0n/KjjFuBhcCx6RSrgd3wgPU5ohhCUoCaynw/Ge + toBRTMBZ9kcyy3rn4k0bSPnUUfy4DqoO7YfGG9ehPzsTpgcHNa5vtbKqBZyZnQNFVTP4ReeBb3QuhKYU + Q9gST+IKNF87OQmZXndZpvsQok6fgns/rocrH/2elEsIKgHXXcnXyQ8u+bDetQAcbxbDfibq5dBaeJDc + zOXDrBjfj+M/DLuUdDTfQ9l2R2jwcIOehHiY7u/TuM7VxqoUcGp6FoqYeJ7+KRCcWLQsnTq+TMqJqcUQ + pyLihJPgHs4QQgTUBUqJvSK+vzM0mJBMAEzaUgdbUF52hr7UFJ5Jq1/ramFVCTg5NQP55Y1wNzgDnsQX + kOKpCEwohNKaVo33VycnkTJJwRgBf2QC4hwgvl/f+E8QTMSyHVuh4Zo7DJeVssxZ84/O2lkVAs7OzUGF + sh38YvIgML6QFI7icUy+xudMjY2C658+JoUSizECbrtVsjz+K9myiRZLJDhGrDywFzoCn8BEe7vGdVsz + Vi9gU0cfPIzIhiDWo1GS6eN2UDpMz8xqfF7I4YOkUGIxRkB3lqjge8eUSpHjP8PgFI7y8kXoS0+F2fFx + jWu3RqxWwFmWYMRklvMEg5JLCMFJRZCUV63xubgS4vz+b0mpxGCMgKrxX1c4y8QJieSgYs9OaPN7xCe0 + 1a/f2rBKAdt7BuFGQCqEJitIscSi/tlYxeL+yZ9IqcQgVUAc/2FhAr7X6PGfAbA3bPS8CoMFbChipUt8 + ViUgTiKnFdbCHRY6KZGk4M3C9+j44oBfRejhQ6RUYpAqIE7J4CQ5H//ZbSbFkRUW4quPHYGuyHCrDMlW + IyBmuI9ZkhEQpz+7FUtQYhHPnNW/qy493egwLFVA94il8V+9/OM/fZTv2g7tAY9hqntx/dlasAoBO1jI + xYSBEkgqKJ6LdzzYHLsP+y4/0fg+OcKwVAETliaguyLCSVFMSYntJmi6dcOqwrFFBcRauNLaVrgVmEZK + JAWfyBzYfdEfPrFzhd+tP8/5/YaLMDyqOVEbxsISJZZQpAi43qUAmrrH+PtqTp0gJTEluOSHPa/678HS + WExAHO9lKOr4FAslkhhwCc4rJBPsTj3ksqnEUycsWTMZqc/ONioMSxHQ1lOxOP83zsZ/tmYY/6mh+Hk9 + DBUVavwO5uYtX+5lEQFxYjkyrRT8ZRjvPYzIgc0nvOHDn51J8VTsuLBYQKoCw7DHZ5+QcglBioAuYXX8 + PWPKOrOO//C7euJjNa5/dLIHipufQP+o5vjY3JhdQMwA/WPzda7hCgWTlX1XAuEPNpdI4bTBnrF3cFSj + LVGnTpJyCUGKgLGKxQTAlPN/K2Dy4Xyg+nVPzYxCaUsI1HenQ2V7NPSMLP5hWAKzCohhF6tUQpKkz+9h + uMXk4lN7N1I0feD3qrenMT9PchgWKyBWxjTi+I/9DmpPn6RlMQGNV91hnkUc1TXPzE1BeWs4l09FRVsU + dA/XLL/GnJhNQKzZw8zUmJ4P13a3sHD7/o8XSMEMsfWsr0absFLa/dM/k4IZQqyAW64X8aQLq1bkWv81 + RM2JYzA//bo4YX5+Fqo74ph0aRoCIpVMwq6hquXXmguzCYhjPqxQocQSwjW/ZPiz7evMVgofbbwEPf2L + +3lVxJw/RwpmCLECLo//6mrNMv6rYO2bHdUcctR3Z0BdV8oK+VRgOO41czg2i4C5pQ3wKCqXFMsQIckK + OOIRAmsMJBlCwR5YvW1NBQWSwrBYAWOLlsZ/EaYf/5XabYaJNs1StPaBEtb7xZPiqVPeFg5D4+arpjG5 + gI3tfbx+j5LLENhjbjh2D94nRJKKwxnNATmediAlDIsREMd/Td3jfPxXd/4MKY1c4PrvSFWlxjX2jzWt + GPfpo6ItAkYmzLNiYlIB+4fGwDMglZTLEFj79+3em6RExvDHTZehu39Yo51xFy+QkulDjIB2norF8d/0 + FBv/bSTFkQPFTz9AX1qKxrX1jzZBQaMPKZo+qtpjYWyyV+OzTIHJBMT9GljRQslliPthWfCXbVdJgeTg + SbzmhGyLogguigzDYgRUjf9GTTn+Y5/bEbR4XIiKsak+CFfsh+DCnaxXiyRF0wcmLDNzmoUccmMSAXnG + m1AEocm0YPq4F5rJkg0XUhy5sD35EObV2ovnwnh8/ikpmi7ECBinmv8z4fovrvGqT7fgXF90qRM8zt3M + CSrYBmWtoaRousCEpbEni/2uTLd2bBIBc8saDO7ZoMCeT30N11R8ZHMJuvqGNNqc6OZCiqYLoQLi+K+t + b3EdWul8npTHWGrPntaYbpmdm4bUardl+VQE5m+FkpYgUjZd1LDEpWdYc4urnMguYHffMN+bSwmmD6zb + +9QM8qnwi87VaHdbaYmoMCxUQKz/w/EfHrMhZP+vWCoP7oPZsdfTLfPzc5BXf3+FfCpQwrLWMFI2XVS2 + R/FwrvoOOZFVQFxmk5LxYh3gX0045qPYePw+Hyost312Fq795QtSNgqhAi6P/0Tv/zUMbsuc7Opcvoan + LFTiXJ5/7hZSPhVBBTv46yjZdIGvn5vX3F8jB7IKmKVQ8tUOSjJd4OvX7r9FSmJKfm9zETq1wnDKVY8V + ol1a8wHc+sfX8MhuCy/hSnJ3g4zbt6AyPo6/Jyi7HZ5ktcGDpGa4HFoHx30rwfa6goXeAi5gnGKp/k/m + 9d+SzTZ8U5N6+5t6c8E/z5aUTpswxT4WXhNI2ShqO5OhtV9zKVMOZBNwYGiML5VRkukC93zYn/YhBTEH + WEmjfg3t5eVcuIebNvJDKRtyc/hynfrg3hCY3GDJVe/wFGRU9sHg2OLYTHnJmRRJCjjdMsDapv69WFDw + JN+RlE0XUSVHQalnZUQbnEvE5Eb9e41FFgExlEWklojeRHTqZoSsk8xisdEKw8jE8LBJKoanerp5Flxz + yokLRIklCBbGu6IWj4ZTMTLZDaFFe0jJDJFa7UrKpgsMxerfbSyyCNjc0cfPZqEk0wUmKkJLqUzFmg0X + V2TD5mBmaAg6w0KhbJsDLZkeWu57afyBYI8UVXKMlEsI/nlbQNHkT8pGgVlx15DmSosxGC0glliJ3TSO + E8F/33mdlMJcYH0gVsfUty7u0bUEmBn3paVC1eGDpGzaKC9e0BgOYEVzSrULKZYYcI6wqiOWFI4CJ7Xl + SkiMFrC1a4BPoVCi6QL3bFBSmAOc6rnql8TbTV2PJZhnGXhPYjyU2m8hxUPwwEr1A4hwuiVbeYcUSgrR + pcdBSZRpUeDrWvs1izqkYpSAOH7CTUCUZLrA3W+69m2YElxdwSmiIa3NScaQlOsLN/z3wJ3AgxCc6A7J + eX5QWZ8DgyM9MD0jfglrZmQEmu/e4fs31OUr37ENpvv71V47z+fyKJGMIbf+HikcBY4FccJbvf1SMErA + mqYuUWVWeFTGN3tukIKYCizjOnE9HPq0yvHlwDv8JOy88OEKdjv/HpyufwWpBZrbQYUyWFgIpXaLvSH+ + nGhp1vh37IEMzfVJAUMxjvEo4bTBZbr2Ac2NXlIwSkCx0y4nb0SQkpiKr3d78lpEqu1yoEtAFSU1qeT7 + hDDV3c2P7hgq1px76xgsg4A8e1IgOUioOEcKR1HVHgPTs8adtiBZwPbuQV4yRYlGgceqfeYgfh+HFN7/ + 8TzsuRwAw2PGh9vpqVno7RyGakUb5MTVQNxjBQRcy4SHl1Lg4pmLpHjI3kt/hImpxT3AUtGefxwca2W9 + 1HZSHLnArLi4OYAUThs5xoKSBUzKrSJF08XRq6GkLHLzwU8XePk+bv2k2i0EXFKsKmyFiPv5cON4DHgc + iAT3/RErOHf0MikfcunexhVzjMYwPtXPVy8oaeQmquQIKRwFbmii2isUSQJOTc+Al4iCA9xC+fGmK6Qw + coLzerjl09inD83NzsGdU/GkdOroEzAw3oX8bKkUNj4iZTENW0AhsBes7Uw0qlpGkoDlde2iNhgdvxZG + CiMnmGxgm6j2SiExsISUTh3dAq6B0tp08nOlMjs3BRm11wlZTIOYXrChJ5NssxAkCSgm+cC9uF84upPS + yAWO+R6EZZFtlUpLbQ8LvbR4KnQJuO/yxzA+qbn7Tg7m5mYgW3mbFEZucCxY0hxICqcNZs6TM9KuV7SA + OJ3hFZpJykZx2Tve5Ou9Z29H8RUZqr1iwQnenpFayK3zgWtOQaR4KnQJeNFrg6zjP3WwJ0yuukxKIzdx + 5WdI4bTBZKRjsJxsryFEC5hX1iCq6GDt/tukNHLx81EvfrYg1VYxoHhtAyWQUHEBAlmmGViwDe7evEGK + p0KXgEEJruR3GCKlSglhhYZvJE59xJSeIKWRk4B8+6WN7LR46tR0JpBtNYRoASnJdIFLdB/8JM9+XoqP + N1+Bhjbjd24NTXRAWo3HsngqfKOPk+KpoAVcAxVK8cOB8tZOWHP6Grx33A18s4s09qxQDLM2BxZsJcWR + k8xaT1I4bXB9eHJGc7ehEEQJiCfOiznLz9RTL9qPYRALjqnK2sIhpGi3hngqnuTuZGE4kJQPoQTcf+VP + MDYhrsKmtX8QPnG+Bf/nmCuHS5hleH6tuS/PJCsi6oSy342yK5WUTh18TftAKdlOfYgSsKaxEwIEbjbC + MG3KrZWbnB4wgaTP9eGgGbNKSjx17t72JOVDKAGdvX4WNf4bHJuAbzy8l+VT8Rsnd4guMXRWy7zJM2MU + XPhuujSijfoRJWBUWqnG89j0gdsrP5B4iJAhcLK5ROspSGIYnuiEmLKTpHDa+MYeA3cd2TAlYHCCG/md + FJPTM+BwP2iFfCo+ZCG5jIVm6r0qRid7+RouJY9cpFW7E7KtBEu6xBYoiBJQTOEBVjtT8sjBfpdAsn1C + wOrhyJLDpGwU+sLwSgHX8GoY6nu1wZWa40GxpHjq/IfLPfYHo7+yprwtghRHLnAFhjpRSxtMRPDgS6qN + uhAsID74D/ftUrJR/HTEi5THWLBXrazvINtoiInpQb5ZmxJNH3dvXxck4K6zn0C90vDDpTHBuJuaC79m + Yz1KOm0O+UfpDetTs2MQUriLlEcOcKMTFh5Q0qmD48DWfnGLAYIFxOID3D5JyaYNVjzjUWiUQMbicNpH + 0hzb9OzE0hQLLZk+/OKOChLQ1v57+OmL/XDQ/hIkRefA5AT9cOlIRSVPNCjZKN5zcoMcZRP5WSpMUR+o + Dk6AU9JpgydwUe3ThWAB88obeT0fJZw2+KAZXJ2gBDKWmAxpE554QA8llxCe5O6Aa8dXTkprC7jhWwdY + /9neZRzWnoCkqGyYn3v9B1Pc1AYfnLpGiqaPr9zuw5TWc+/UGZ8aEL0rTgwJFedJ4bSp6Uzkc6pUGykE + C4i73ijZKM7diSLlMRY8tmNiUnwVbvtgKS9jouQSiteda3oF3HHmI/jxy90aAnI+3wsnd1+F7s4+aOod + gD9feD3dIoZfMwLzSsjrU2HKjDisaK+gkn3sAcXUCAoWEI+yoGSj2H7ejxTIWA66BpFt0wdOt4hJOnTB + w7BWNqwuoOOhL1bKp4bt+pPw18t3SbmE8tmlO2wcq/sPEJfDKHnkAItgsfJFXTYc82FlNJbn41RNXVcy + 3xyPY22qfRSCBMQxF06rULJR/HW7aeb/sBem2qePoqbHpFBieZLHwrBWNqwuII7/KPGQdV/sgzW7nEmp + xBKQq/t3gD1PcOEOUiBjwflALNHC+j+UDUXDM6XxNNWJaelbWwUJiGFP6KO08KiN/7dZ/to/rPUbHBFX + /o3zfXg2HiWUFLzueegU0OY7e1K+Hz7fB3/cfp6USQrrrj/SW3iRVnOVFEg4W3hvF6bYD/HlZyG/8SHU + diVB32gj34Ms9/kwggTs6hsG73BhWy9xg7pc5zmrg6el4jOEqfbpQq7eT4Vf/BEWhsNXCLjjzB/o8R/j + 0y2nSZGkgtlzRZvu43MxJNJiabOFT6/gHB9WveQ1POCFB70jSt6jmespSoIE7Owd4g+OxsdqYShGyXBS + GsEKZPXnfuAjs0yRAe+5FEC2TRc49gsp2kOKJJn87XD9xJMVAjoe/JKU78sNJ0iJjMUlRveS18BYy4r1 + Yaztw/XuuPLTkKO8w8dsGD7xdyTH1kpjEJyEILhXAgsSsCR/ZGyS94yFFU2QUVTHn/MblV4Knv4p/CBw + m2P34OtdnrxiBYX80MiqGPxcqk26aO7LpyUyknv33VYIaGu/boV8f193DN4j5JGDb9y9dc6F4jgwqfIi + ZNbdgIr2KF5iNjE9zETDHk38/KkQJkanoLNlAJpquqGyoAWaa4SvhogSUAz4C8Llphku7Cx09AxBcU0L + xGaWQ0BsAR9TnrkVxXs2PCFr3cE7fNccivrhTxdW9KLa5zobQkihgRT8EjAMawpos9ZOQ75vvj4E7x1x + IeWRAwzDXUP6KpBNI9rUxAx0tQ5CTXEbZERVQphXLngejQa3feHgsjsUcuJroDS7CRTphleDVJhMQLGg + sDi4xl4Wj3qrberivWp4Sgn4slDf1i38KA1c9QhlYxtKIKPJ3wbXTwYsC7jjLBv/fbFnWb61fzsIvz18 + hRRHTgxXykgHx9o9HUNQV9oOWTFVEPEgH26fjAPXvWFweWeITjIiK7mAeYnCNylZjYBy0j/WzGQxbuJZ + H/ceLIZhFNDx4Ov5v3Vf7ocP914khZET7AHdYo3f9IR/9AM9o1y03IQaiPQugPsXEsFlTxhc2UVLpg/c + M40CorS4n5r6Tm3eSAHrezJIceTCL+EwD8MooK3D4vzfD1/sg492XiCFkcr/dXLnJVlrr/nAkScxcC8t + D1IqldDSN6hzDKgNHwrNzMFw/zgoyzuhILkOoh4WgM+VFNajhTPRQkmZpBB8K5sLWJiihMlxYcnNGylg + SUswKY6ceJ725wLafG/Ll9v+bH+WlEgf7x27Ah8cdYa/HDoCDvs3w4k9X8GDHe/DrbhkyKhpgIaefv68 + Feoa9dHTNgQFTIIo1qM9ckkFj4MRsoqmi8fu6VzAorR6GOoTdiqEMAEnR+DZxAA8m2IDXzz1ScRisyXA + Oa3g3O0QlEfLIwf3H7rCucMufPz3uc1JUjAV7x1zgTVHz8Nnh4+D7X5bOL7nG/De/huIcvyfkGv3L1Bk + +8+gsP0nTrHdr2Cy07gHBmKCQAliarwvJi8L2NMubHVEkIAv827BLz5fwS9+38NC4EZYCNsKC5F74FXy + GXiZfwdelAfBi9o4eN6aD8/6lPBspAuejffD02n2V8DTf/pzTQXO1lec2A+FuzZCwb6NkOu0CTIuboGU + G3aQ6GUH8X72EBXuAOEJjhCWshVC0rdCUA4TiyUYHEI4bR4nHYJT2+7A39Y78UIBFO3XS6J9zkTbdMAB + jjHR7m1/H2Ic/wdk2/1XDdH0MVyRRF6XUEqzG0lBTM2d0/FcQEV6A9RX6K/kViFIwFcpF+CXh38XBoqK + Px/9A37x/xEWgrbAQog9LMQehpeZ7vBS4QMvKsPgRX0KPO8shWcDTUzYTtbDsr+YWfkeC1W5eweUbtpg + kJItG6DY3gYUW22gaIcN5B/YCNmnNkOauy0k37KFxAf2EPvEHiKjHZeFDc5iwrLe9ZyTG9js2wpH93wL + t3esgTiHf4Ms+38VLJouBgpCyGsSSlNND1yWkEQYy41jMVzAkqxGqC5qI9umjSABF2IOrBRNFpZk9fka + fvFdCwtPNiwSsZNJf571vKx3LXkML5SsRxAZ9oUKKIrNTFjbJWEdbcDniDNkbP13UiJjGCwKJ69JKJ3N + A6QgpubqoUguIIIJD9U2bYQJyIRYKY/5WAjewnpHcUtG1YcP0BLJhg0cco6BU+duGt3jaTNcJm2Tt4re + jmFSEFNz9eBrAXGymmqbNsIEDHUgxTAX+P1P58RVYdRfciakkY8Mhx1g41HEKASfQz+SIkllrKGAvCah + WExAtR6wslDYrsVVIqCj6BDc/ughKY5ceB9k4z8uYBHYu2VA2tb/RcoklmKH/wxzRh5saQ0CFqVqPsVJ + F8IEDN9OimEueA8osg6tJy6WFEcOSlj4PXIhallAxOmCFxTZ/YqUSgyVTr8lr0cMHU39FklCrh+J4vJh + EiJrFmy6JEQYC8G2oseAY3W1pDxykOWwHTay0KsuIOJ9mCUnhFRiaLzDxrvE9YihrqyDFMTUeB6Lfi2g + nEnIq6TTpBjmYiHgJ3g6I+6859nRUSh3sCUFMhafA1dWyIfYuWVC8vb/TYollMGiCPJ6xICrIJQgpubu + maV5wIwGaKsX9nhXYQJmupFimA2frxfnCYm26aPB9QopkHHYwLHzkaSAyGFnXyiw+xdSLkOU7f43mJ+h + 9xKLIT5AQQpianxdU7mAuBbc3SpsY5IgAXG1gxTDXPh8Bc/6hNeYqRjIyiQEMo4sh22wyb2AlE/FrWM7 + ScEM0fxgO3kdYsGKFkoQUxNwLYMLiOVYo0PCIpYgAXEymBTDjLyoFv+UxtnxcajY5kCKJBXfA5dJ6dTZ + 4p4D8Tt/Q0qmi5Kt/w0mexrJ6xDDxNgUz0YpQUxN6N3c5R5welLYEqwwAZWJpBTmBIcBVNsM0RkUSIok + DRtwOh9OSqfNvkvBLBT/F1I2iqb7jmT7xcJXQSyQASN4sDsKiGNQLAGj2qeNIAGfd1cyCZaWzSwETgVJ + qcLBR6OWO9oRMokn234bbHbPJ4Wj8DhxjJRNm7K9/w7TQ7p3uokBi0EpOUwNFrBmxVQvCphcx+4V3T5t + BAn4bLj9dZGBpXj0j8UKG6J9hsDH5VNCicV/nzMpmi42eRRA1O4/kNKpKLb/FQwqjM98ETyDxlLjP9wX + Upiq5AJidTXVPgphAk4O8VIsUgwz8qJK2o2an56G6kP7SanEcOJcKCmaPnZdiYI8+38l5VPY/jO0+Oxm + vYU8m4jwkWK4OYgSxNSoVkFKspr4Y82o9lEIEhDXYRcCbUgpzMmruKOsPdJu1mh1NZRt2UiKJYQce0fY + 4pZHSmaIK6fOEvL9E9RfXQvzIifY9ZESUkbKYQ5UxahYC9jVInwDmTABGaJqAk3Fo2/YcEDa4ZRIZ0gw + KZcQAveeI+USAq6ahOz9QkO+uit/g7lp+Z5djHswcIskJYc5CLuXxwXEDHh8VPhcpmABsYiUlMLM4Jwk + 1T4h4NMnm29cJwUzxKmzwaRcQtnmmghZjv8dFHa/gqa7dkYXHGiD4y9KDLPAEpD0iIql8V8tf9Ye1UYK + wQI+76lmAlg4EUECfoSnU9IfPj03OQmN7q6kZLrItXMAW7dcUiwxnD/nAZ2x7pKyeX1MTUzDTadYWg4z + gAkIhl4UEKdgqDbqQrCAi4nIWloKM/NS8ZBso1C4hB5upGwUwXvOkEKJZePVIsipkZbJ68NSUy8qvM4m + cPmKMxuhoVLcdJJgARHcjEQJYXYe/yB5SkbF/Mw0tHrfh1IBicmZM4GkUFLYcacU+kfkSzwGe0f5JnlK + DHMRfv/1+G9kUNy4VpSAL4t9aSEswKu0S2QbRTE/D/0Z6VCxYyspHpJnZw/2rtmkTFJxDVfqPeNPKLjp + /IlnJimFucD9xjlxixPQ+Ul1/GgVqq26ECXgs54ay09Iq/D5Gp63yfN84Kme7sWQvNlmhYChe06REhkD + huK0cuOfcWfRxGMJfKI8yoeU5zaT7dSHKAFxjy/W5pFCWICFwE3wbEL4ecR6Yb3JSEU5KM+e0hDx/Gl/ + UiJj2XqrBHqGpJdeYb0dnuFCSWFOgm4uHceRWs/Xoam26kOcgIyXOddJGSzFq5Rz8maVTMTR6io+XVPk + 6AiOrlmkQHJwMbhWdMhCBvvGePUxJYQ5wfXf7NjF8Is/hZ5Xo45oAZ+3FZAiWBLc7E611Vhux9ST4sjF + RkZKmbhQPDYyCffOJZBCmBvVSQi4/IYHU1LtNYRoAbE0Hk88oESwGI++gee4eZ1qr0SmZuZgJ8tYKXHk + YMt1BfiktsDYpPDNVmPDk/DAOYmUwRJE+xQuhV8lP+aNarMhxAvIeFl4nxbBkvh+C88bUsn2SqGseZj3 + UJQ8xrD5mgLOB9VCU7e4E//7Oofh7hnr6PkQt/2vJ58x+xVafqWNJAGfDTbzLJQUwZKghHWJrI3GT3F4 + JTaTAknFzrMYPCLrQdk5xsZK9HeSsNfi5O61w1GkCJYi0DNzKfw2Cj4FgUKSgMiruCO0BJbG5xvWQ98z + 6lQuFMQlTAkON4qN6gVRutMB1RBd2AW9w+IzXqwqzoissIpsVx08qheX3FBAPJZXaPUzhWQBnzem0wJY + Ca+STsGzcWFbA3UxMjEDxQ2DfKx2LrAGDj2sAMebJTyMqouG47ltt0vhgHcFf51/Rhvk1w3A4Ng0fzQr + 9dlC6O8eAXcW6igJLMljj8WDKLH3k5p8qJAsIJ8TDNpM3nxrYSHgZ3jenM3aa3xIRnD1YmJ6DkZZ4jAy + PrMM/vck+/+zEqZUDIE7zCgJLAX2frlLp+HnxNUY1fsh0gVkvKiJIW+8VcHGqq8ST8KzIenjFEuCN9jP + LY2UwRKotl7K0fshRgmIx2XgAZTkjbc2Hn0LL/Nu88MwyWuxMNN6ek8MxR4HLFtwgGAbVPs+MPMVU3iq + C+MEZOB+XfKGWyuP/gEvM93geVcFX/WgrsmczDDxopv7wDa1GrrGdd/Q4owGUgpzoqp6wbKrmuJ2sp1i + MVpAPLTc2seCNF/xo4PxTGvyusxA5cAY7M9Wwrdx5RynvAadUzS4ZBdw3XKVL7j0h38Eqt7P2LGfCuMF + ZDyvT+E3lL7RVozvt/IVMwhklvW6hT0jcDK/EdbGVyzLh3zHCGvUvTSHz/rARy5QgpgS3GmXGlbO5cPJ + Z2WZ9H052sgiIO6as9p5QT28ijnI2r8yDOPUib4xmVhQOgyvKNfuzDoumrp46qxPqISmEd1FnTjwl/IU + I2Pwv7qYeCz2fsIfwyUEeQRk4Gn3v/h+R95oawU3WlHXUjc0Do5pNeBS0gIpbQPQPT4NE7NzglcwUN7+ + yRko7h0Bf2U37M2qY70dLRwFhmVdfwBYcYJjMUoUU4CHTuJzP1C+7LhqwU9AEopsAiJWuUasC/bH8myM + nqj2re3SEAJD5abkKt57OSua4RH7d+zNwtXA97iVtsKR3Hou7/da4VUs+HlU2xDMPm+YoRwLV2BSQxdD + L0oo9NRTMcgqIO5Ww4E9ecOtjIWofazNdPjdnlFLSmFOfkiogGqWpGi3T0UDk8Gkj99iYV512hWWW2Hi + IaXezxDyCsh43l3Fpzqom25NvKigHwbTMDwB34kIl6ZkF+txMfRT7UQSAoppeWQAz5jByWZV6MVj36g2 + GIvsAiL46C7qplsNmP2O0CHucZ1m+LU096p0Z5z4SNS7p+NJgYwBK29UxQa4FIilYNT3y4FJBORZcYIT + ffOtgIXI3ayddDjZYQXhV511LBSX9+su9mzFvSEyHkiEj6HNWiqzxymXulL5plwoTCMgAwf4+NgtSgBL + 86I0gGxzoxWFX3W2pdfCuJ6JX5yjo2QSCxYaqOb7MPxi4iHmmA0pmExAhB9s+ehbUgKLgecM6ihMCKzv + JgWwBjzL23SWds1Mzxq9TwQTmli/Ii6fKvROCTxm1xhMKiDyvDGDF4mSMliAhbBt5Bow3tydmdYVftXB + qaCinpEV7VaBD6fBHoySyxBXWAhX7e9AcIfb+Ih8Ty7Vh8kFRF6UsaTESja0vyz2I9vYzH7hYiaLLYFd + ajUMs96Oaj8i5YwYHD9GP3otH36G0BPu5cAsAuKA/2XuTVIIs8J64mcD9En0QfU95E23Nq4Ut+gNxT5X + UkjRKFC+GN/XYRd7vqF+eY+NM4SZBGSwzPhl7g1aDDOx+Mw5OvziKgd1w60NXEdObdddQIEPKsRMlhJO + HTxSLdZPoSEfHnREfaYpMZ+AiIUlfFlEH+vWMorh17ilM3OyMbkKeid0r8kaOjMGn+ubFr54oCSCh0oO + 9Zm351NhXgERlDDvFhPCzGNCfNpSL13JEdawOsKvOqcLGnXXDs7O8QoWSj48TChnaU8HTrVgtjvUL26P + spyYX0Bkfo4/jt+ciQl/4qaOtd/VEn61iWrSvetvsHdMo3YQS7jwIHE8RAjlw+JSPM/PVEtsQrGMgAgb + i72oCAU8VoMSRm5eFniR7WhnN8DYyhVLgQUL2H7qupDy3CYuHk7PRD7Ih9KsxZC7KGEjzMyIewazKbCc + gEs8by0w/TNIWE+LRRLU90c09ZI3d7WA5V9Y8EpdG4bo8Ht5kBldxcVDMORiWZUpKlukYHEBESxmXQix + o+WRATxHUFf4Vd+TsVoJYWNY7WtTgQWkqoQDq5lNWVggBasQEMG9GXjWnynGhbgdk/rOzvEpvthP3dTV + xPrESj6RTl0j0qrs5eu65lrdEIPVCLgIGxfWJcAvj9eRIkkCw29XOfFdTyGmuY+8oauRA6wnn9JTOCB0 + O4G5sTIBF8HN4wuxh2ihRIJbRsnJZ3ZDDuas/vCrjr4yfmvFKgXkzM3wqmV8MA0lllBw4pv6/J6JaZ5F + UjdytWKojN8asV4Bl8DngeBJBtLK/HWH39iWNyf8qsAVkqtlrfy0BeqarRGrF3CReb6Kgft4xSQpC0Es + +yUOMMfwi9MX1E1cjeAy4sGcep4N61uis0ZWiYBLMJmet+bDQvR+JphhEV9mXyM/p+8NCb9YmGCfVgPX + ytqgon8M5qw00dDH6hJQBUsqnneWwav443p6RBZ+O0rI9ye1DpA3dDWB4fZcYRPP5CdNXDZvSlangMuw + 0NxTA68yXFaspiwEbuSFD9rvwclnp/wG8qauBjYkVcGFoia+Mb7Twuu4crDKBVRjehxe1MbBq9jDrFf8 + micu1OuGpmb4+SvUzbVmsMc7y3q8+JZ+vneZurbVyJsjoBrPhts51L+ltq+e8IvJBW4TxVCLw4bVlmAI + 4Y0UUBcYfrEXoW62tYCJBZ5Dc6qgEW5XtENGx6DeLZmrnbdKQDzmAnsT3GeL66f6jkkzJ1gOZptSDUdz + G+AWky6tfRBaRyd1Vrm8SbxdPeD8U76rLK9rGAKU3XyvLc4H4vG46xMrzCYkCreZCbc3SwkXFc18CS2p + bYBLJ8dzhFcTb5WA2mCPiJlkVucQBCp7eO+DPSQu7OMWSAyFOF+IYoqVE1+Potmwz7BLrYE9mXX8VNTr + ZW3gU9PFz4XGgyjHZmattlDAHLzVAmqDS1goZQeTMrdriJe8hzb08hWGO5Ud4FrSwsdmZwqa+FQOnul8 + KKcejrOfKNf5omZ+fqBHaSvvYXGqJK65n8/VoWxDU7P84Ekci1Lf/zbyTkABoDAYGlFQLHmaWvqJE8Ao + LP6cmpvjcuG/zbDXvpNMGO8EfIdFeSfgOyzKOwHfYUGewv8HAu+9LO1LNKEAAAAASUVORK5CYII= + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartTitleCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartTitleCollectionEditor.cs new file mode 100644 index 00000000..d5499185 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/ChartTitleCollectionEditor.cs @@ -0,0 +1,95 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class ChartTitleCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private ChartContainer _Container; + + #endregion + + public ChartTitleCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _Container = context.Instance as ChartContainer; + + return (base.EditValue(context, provider, value)); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + if (itemType == typeof(ChartTitle)) + { + ChartTitle title = (ChartTitle)base.CreateInstance(itemType); + + title.Name = _Container.Titles.GetUniqueName(); + + return (title); + } + + return (base.CreateInstance(itemType)); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + ChartTitle title = ChartItem as ChartTitle; + + if (title != null) + { + if (AddButton != null) + { + ChartControlDesigner ccd = GetDesigner(_Container.ChartControl); + + ccd.InCopyItem = true; + + try + { + AddButton.PerformClick(); + + ChartTitleCollection ctc = _Container.Titles; + ChartTitle clone = ctc[ctc.Count - 1]; + + string name = clone.Name; + title.CopyTo(clone); + clone.Name = name; + } + finally + { + ccd.InCopyItem = false; + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(ChartTitle); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/DataLabelCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/DataLabelCollectionEditor.cs new file mode 100644 index 00000000..c1a8a607 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/DataLabelCollectionEditor.cs @@ -0,0 +1,94 @@ +using System; +using System.ComponentModel; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class DataLabelCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private ChartSeries _ChartSeries; + + #endregion + + public DataLabelCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _ChartSeries = context.Instance as ChartSeries; + + return (base.EditValue(context, provider, value)); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + if (itemType == typeof(DataLabel)) + { + DataLabel label = (DataLabel)base.CreateInstance(itemType); + + label.Name = _ChartSeries.DataLabels.GetUniqueName(); + + return (label); + } + + return (base.CreateInstance(itemType)); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + DataLabel item = ChartItem as DataLabel; + + if (item != null) + { + if (AddButton != null) + { + ChartControlDesigner ccd = GetDesigner(_ChartSeries.ChartControl); + + ccd.InCopyItem = true; + + try + { + AddButton.PerformClick(); + + DataLabelCollection dlc = _ChartSeries.DataLabels; + DataLabel clone = dlc[dlc.Count - 1]; + + string name = clone.Name; + item.CopyTo(clone); + clone.Name = name; + } + finally + { + ccd.InCopyItem = false; + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(DataLabel); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/DevComponents.DotNetBar.Charts.Design.csproj b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/DevComponents.DotNetBar.Charts.Design.csproj new file mode 100644 index 00000000..9ec0a333 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/DevComponents.DotNetBar.Charts.Design.csproj @@ -0,0 +1,214 @@ + + + + + Debug + AnyCPU + {CBBE8B3E-A0DD-4CE7-9E42-AB7AB387E277} + Library + Properties + DevComponents.Charts.Design + DevComponents.Charts.Design + v2.0 + 512 + + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + + + ChartControlDesignTime.snk + + + + + + + + + + + LabeledTextBoxX.cs + Designer + + + LocationDropDown.cs + + + PivotPointDropDown.cs + + + RangeValueDropDown.cs + + + SeriesPointValueDropDown.cs + Designer + + + ChartStyleDialog.cs + Designer + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + SizeDropDown.cs + + + + + + + + + + + + UserControl + + + LocationDropDown.cs + + + + + + UserControl + + + PivotPointDropDown.cs + + + + + UserControl + + + RangeValueDropDown.cs + + + + + + + + Component + + + UserControl + + + LabeledTextBoxX.cs + + + UserControl + + + SeriesPointValueDropDown.cs + + + + + + + Form + + + ChartStyleDialog.cs + + + True + True + Resources.resx + + + UserControl + + + SizeDropDown.cs + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.5 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + + + {2af9ba7a-2d05-419e-9f49-0ccef791947e} + DevComponents.DotNetBar.Charts + + + {36546ce3-335c-4ab6-a2f3-40f8c818bc66} + DotNetBar + + + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/FlagsEnumEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/FlagsEnumEditor.cs new file mode 100644 index 00000000..0276eb53 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/FlagsEnumEditor.cs @@ -0,0 +1,210 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing.Design; +using System.Text; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.Charts.Design +{ + #region FlagsEnumUIEditor + + public class FlagsEnumUIEditor : UITypeEditor + { + private FlagsCheckedListBox _FlagCb; + + public FlagsEnumUIEditor() + { + _FlagCb = new FlagsCheckedListBox(); + } + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return (UITypeEditorEditStyle.DropDown); + } + + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + if (context != null && context.Instance != null && provider != null) + { + IWindowsFormsEditorService edSvc = + (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); + + if (edSvc != null) + { + Enum e = (Enum)Convert.ChangeType(value, context.PropertyDescriptor.PropertyType); + + _FlagCb.Value = e; + edSvc.DropDownControl(_FlagCb); + + return (_FlagCb.Value); + } + } + + return (base.EditValue(provider, value)); + } + } + + #endregion + + public class FlagsCheckedListBox : CheckedListBox + { + private Type _Type; + private Enum _Value; + private bool _UpdatingStates; + + public FlagsCheckedListBox() + { + CheckOnClick = true; + BorderStyle = BorderStyle.None; + } + + #region Public properties + + #region Value + + public Enum Value + { + get + { + return (_Value); + } + + set + { + _Value = value; + _Type = value.GetType(); + + InitializeCheckedListBox(); + } + } + + #endregion + + #endregion + + #region InitializeCheckedListBox + + private void InitializeCheckedListBox() + { + Items.Clear(); + + foreach (string name in Enum.GetNames(_Type)) + { + object o = Enum.Parse(_Type, name); + uint value = (uint)Convert.ChangeType(o, typeof(uint)); + + FlagsCheckedListBoxItem item = new FlagsCheckedListBoxItem(value, name); + + Items.Add(item); + } + + SetCheckedItems(); + } + + #region OnItemCheck + + protected override void OnItemCheck(ItemCheckEventArgs e) + { + base.OnItemCheck(e); + + if (_UpdatingStates == false) + { + FlagsCheckedListBoxItem item = Items[e.Index] as FlagsCheckedListBoxItem; + + uint sum; + + if (e.NewValue == CheckState.Checked && + (item.Value == 0 || item.Text.Equals("None"))) + { + sum = item.Value; + } + else + { + sum = CalculateCheckedSum(); + + if (e.NewValue == CheckState.Checked) + sum += item.Value; + else + sum -= item.Value; + } + + _Value = (Enum)(Enum.ToObject(_Type, sum)); + + SetCheckedItems(); + } + } + + #endregion + + #region SetCheckedItems + + private void SetCheckedItems() + { + _UpdatingStates = true; + + int value = (int)Convert.ChangeType(_Value, typeof(int)); + + for (int i = 0; i < Items.Count; i++) + { + FlagsCheckedListBoxItem item = Items[i] as FlagsCheckedListBoxItem; + + if (item.Value == 0) + SetItemChecked(i, value == 0); + + else if (item.Text.Equals("None")) + SetItemChecked(i, value == item.Value); + + else + SetItemChecked(i, ((item.Value & value) == item.Value)); + } + + _UpdatingStates = false; + } + + #endregion + + #endregion + + #region CalculateCheckedSum + + private uint CalculateCheckedSum() + { + uint sum = 0; + + for (int i = 0; i < Items.Count; i++) + { + FlagsCheckedListBoxItem item = Items[i] as FlagsCheckedListBoxItem; + + if (GetItemChecked(i)) + sum |= item.Value; + } + + return (sum); + } + + #endregion + } + + #region FlagsCheckedListBoxItem + + public class FlagsCheckedListBoxItem + { + public uint Value; + public string Text; + + public FlagsCheckedListBoxItem(uint value, string text) + { + Value = value; + Text = text; + } + + public override string ToString() + { + return (Text); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/IndicatorCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/IndicatorCollectionEditor.cs new file mode 100644 index 00000000..a767533d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/IndicatorCollectionEditor.cs @@ -0,0 +1,128 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Reflection; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class IndicatorCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private ChartSeries _ChartSeries; + + #endregion + + public IndicatorCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _ChartSeries = context.Instance as ChartSeries; + + return (base.EditValue(context, provider, value)); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + if (itemType == typeof(RegressionLine)) + { + RegressionLine regLine = (RegressionLine)base.CreateInstance(itemType); + + if (_ChartSeries != null) + regLine.Name = _ChartSeries.ChartIndicators.GetUniqueName("RegLine"); + + return (regLine); + } + + if (itemType == typeof(TrendLine)) + { + TrendLine trendLine = (TrendLine)base.CreateInstance(itemType); + + if (_ChartSeries != null) + trendLine.Name = _ChartSeries.ChartIndicators.GetUniqueName("TrendLine"); + + return (trendLine); + } + + return (base.CreateInstance(itemType)); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + ChartIndicator item = ChartItem as ChartIndicator; + + if (item != null) + { + if (AddButton != null) + { + ChartControlDesigner ccd = GetDesigner(_ChartSeries.ChartControl); + ChartIndicatorCollection cic = _ChartSeries.ChartIndicators; + + ccd.InCopyItem = true; + + if (item is RegressionLine) + _ItemTypes[0] = typeof(RegressionLine); + + try + { + AddButton.PerformClick(); + + ChartIndicator clone = (ChartIndicator)cic[cic.Count - 1]; + + string name = clone.Name; + item.CopyTo(clone); + clone.Name = name; + } + finally + { + if (item is RegressionLine) + _ItemTypes[0] = typeof(TrendLine); + + ccd.InCopyItem = false; + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(ChartIndicator); + } + + #endregion + + #region CreateNewItemTypes + + private Type[] _ItemTypes = new Type[] + { + typeof(TrendLine), + typeof(RegressionLine), + }; + + protected override Type[] CreateNewItemTypes() + { + return (_ItemTypes); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LabeledTextBoxX.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LabeledTextBoxX.Designer.cs new file mode 100644 index 00000000..b26117db --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LabeledTextBoxX.Designer.cs @@ -0,0 +1,92 @@ +namespace DevComponents.Charts.Design +{ + partial class LabeledTextBoxX + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lbIndex = new DevComponents.DotNetBar.LabelX(); + this.tbValue = new DevComponents.DotNetBar.Controls.TextBoxX(); + this.SuspendLayout(); + // + // lbIndex + // + // + // + // + this.lbIndex.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.lbIndex.ForeColor = System.Drawing.Color.DimGray; + this.lbIndex.Location = new System.Drawing.Point(3, 4); + this.lbIndex.Name = "lbIndex"; + this.lbIndex.Size = new System.Drawing.Size(8, 13); + this.lbIndex.Style = DevComponents.DotNetBar.eDotNetBarStyle.OfficeXP; + this.lbIndex.TabIndex = 1; + this.lbIndex.Text = "3"; + this.lbIndex.TextAlignment = System.Drawing.StringAlignment.Far; + // + // tbValue + // + this.tbValue.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + // + // + // + this.tbValue.Border.BorderBottom = DevComponents.DotNetBar.eStyleBorderType.Etched; + this.tbValue.Border.BorderColor = System.Drawing.SystemColors.ControlDark; + this.tbValue.Border.BorderColor2 = System.Drawing.SystemColors.ControlLight; + this.tbValue.Border.BorderLeft = DevComponents.DotNetBar.eStyleBorderType.Etched; + this.tbValue.Border.BorderRight = DevComponents.DotNetBar.eStyleBorderType.Etched; + this.tbValue.Border.BorderTop = DevComponents.DotNetBar.eStyleBorderType.Etched; + this.tbValue.Border.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.tbValue.Border.PaddingBottom = 2; + this.tbValue.Border.PaddingLeft = 3; + this.tbValue.Border.PaddingRight = 2; + this.tbValue.Border.PaddingTop = 2; + this.tbValue.Location = new System.Drawing.Point(17, 0); + this.tbValue.Name = "tbValue"; + this.tbValue.PreventEnterBeep = true; + this.tbValue.Size = new System.Drawing.Size(54, 18); + this.tbValue.TabIndex = 2; + this.tbValue.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.tbValue_PreviewKeyDown); + // + // LabeledTextBoxX + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.Controls.Add(this.tbValue); + this.Controls.Add(this.lbIndex); + this.Margin = new System.Windows.Forms.Padding(0); + this.Name = "LabeledTextBoxX"; + this.Size = new System.Drawing.Size(72, 19); + this.ResumeLayout(false); + + } + + #endregion + + internal DotNetBar.LabelX lbIndex; + internal DotNetBar.Controls.TextBoxX tbValue; + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LabeledTextBoxX.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LabeledTextBoxX.cs new file mode 100644 index 00000000..fa837f9a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LabeledTextBoxX.cs @@ -0,0 +1,34 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; + +namespace DevComponents.Charts.Design +{ + [ToolboxItem(false)] + public partial class LabeledTextBoxX : UserControl + { + #region EscapeKeyPressed + + public event EventHandler EscapeKeyPressed; + + #endregion + + public LabeledTextBoxX() + { + InitializeComponent(); + } + + #region tbValue_PreviewKeyDown + + private void tbValue_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + if (e.KeyCode == Keys.Escape) + { + if (EscapeKeyPressed != null) + EscapeKeyPressed(this, EventArgs.Empty); + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LabeledTextBoxX.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LabeledTextBoxX.resx new file mode 100644 index 00000000..7080a7d1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LabeledTextBoxX.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationDropDown.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationDropDown.Designer.cs new file mode 100644 index 00000000..8ca9ec3f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationDropDown.Designer.cs @@ -0,0 +1,48 @@ +namespace DevComponents.Charts.Design +{ + partial class LocationDropDown + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // PivotPointDropDown + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Name = "PivotPointDropDown"; + this.Size = new System.Drawing.Size(99, 110); + this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.PivotPointDropDown_PreviewKeyDown); + this.ResumeLayout(false); + + } + + #endregion + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationDropDown.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationDropDown.cs new file mode 100644 index 00000000..714f113a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationDropDown.cs @@ -0,0 +1,248 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.Charts.Design +{ + [ToolboxItem(false)] + public partial class LocationDropDown : UserControl + { + #region Constants + + private const int DotRadius = 4; + + #endregion + + #region Private variables + + private PointF _PivotPoint; + private Rectangle _DotBounds; + private Rectangle _FrameBounds; + + private Point _Center; + + private bool _InFrame; + private bool _InPivotDot; + private bool _PivotMoving; + + private bool _EscapePressed; + + private IWindowsFormsEditorService _EditorService; + private ITypeDescriptorContext _Context; + + #endregion + + public LocationDropDown(PointF value, + IWindowsFormsEditorService editorService, ITypeDescriptorContext context) + { + Initialize(); + + _EditorService = editorService; + _Context = context; + + PivotPoint = value; + } + + public LocationDropDown() + { + Initialize(); + } + + #region Initialize + + private void Initialize() + { + InitializeComponent(); + + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + } + + #endregion + + #region Public properties + + #region EditorService + + public IWindowsFormsEditorService EditorService + { + get { return (_EditorService); } + set { _EditorService = value; } + } + + #endregion + + #region EscapePressed + + public bool EscapePressed + { + get { return (_EscapePressed); } + set { _EscapePressed = value; } + } + + #endregion + + #region PivotPoint + + public PointF PivotPoint + { + get { return (_PivotPoint); } + + set + { + _PivotPoint = value; + + RecalcLayout(); + Invalidate(); + + _Context.OnComponentChanging(); + _Context.PropertyDescriptor.SetValue(_Context.Instance, value); + _Context.OnComponentChanged(); + } + } + + #endregion + + #endregion + + #region RecalcLayout + + private void RecalcLayout() + { + int n = Math.Min(Bounds.Width - 4, Bounds.Height - 4); + + _FrameBounds = new Rectangle(2, 2, n, n); + _FrameBounds.X = (Bounds.Width - n) / 2; + _FrameBounds.Y = (Bounds.Height - n) / 2; + + int x = _FrameBounds.X + (int)(_PivotPoint.X * _FrameBounds.Width); + int y = _FrameBounds.Y + (int)(_PivotPoint.Y * _FrameBounds.Height); + + _DotBounds = new Rectangle(x - DotRadius, y - DotRadius, + DotRadius * 2, DotRadius * 2); + + _Center = new Point(_FrameBounds.X + _FrameBounds.Width / 2, + _FrameBounds.Y + _FrameBounds.Height / 2); + } + + #endregion + + #region Paint support + + #region OnPaint + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + Graphics g = e.Graphics; + + g.SmoothingMode = SmoothingMode.AntiAlias; + + RecalcLayout(); + + g.DrawLine(Pens.Red, new Point(_FrameBounds.X, _Center.Y), + new Point(_FrameBounds.Right, _Center.Y)); + + g.DrawLine(Pens.Red, new Point(_Center.X, _FrameBounds.Y), + new Point(_Center.X, _FrameBounds.Bottom)); + + DrawPivotDot(g); + } + + #endregion + + #region DrawPivotDot + + private void DrawPivotDot(Graphics g) + { + g.FillEllipse(Brushes.SkyBlue, _DotBounds); + g.DrawEllipse(Pens.DimGray, _DotBounds); + } + + #endregion + + #endregion + + #region Mouse support + + #region OnMouseMove + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + + _InFrame = (_FrameBounds.Contains(e.Location) == true); + + if (_PivotMoving == true && _InFrame == true) + { + PivotPoint = new PointF( + (float)(e.X - _FrameBounds.X) / _FrameBounds.Width, + (float)(e.Y - _FrameBounds.Y) / _FrameBounds.Height); + } + + _InPivotDot = (_DotBounds.Contains(e.Location) == true); + + Cursor = (_InPivotDot == true) ? Cursors.Hand : Cursors.Default; + } + + #endregion + + #region OnMouseLeave + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + + _InFrame = false; + _InPivotDot = false; + } + + #endregion + + #region OnMouseDown + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + if (e.Button == MouseButtons.Left) + { + if (_InPivotDot == true) + _PivotMoving = true; + } + } + + #endregion + + #region OnMouseUp + + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + _PivotMoving = false; + + _InFrame = (_FrameBounds.Contains(e.Location) == true); + _InPivotDot = (_DotBounds.Contains(e.Location) == true); + } + + #endregion + + #endregion + + #region PivotPointDropDown_PreviewKeyDown + + private void PivotPointDropDown_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + if (e.KeyCode == Keys.Escape) + _EscapePressed = true; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationDropDown.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationDropDown.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationDropDown.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationEditor.cs new file mode 100644 index 00000000..72c1ce4e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/LocationEditor.cs @@ -0,0 +1,59 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms.Design; + +namespace DevComponents.Charts.Design +{ + public class LocationEditor : UITypeEditor + { + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return (UITypeEditorEditStyle.DropDown); + } + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (false); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + if (provider != null) + { + IWindowsFormsEditorService editorService = + provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (editorService != null) + { + LocationDropDown pv = new LocationDropDown((PointF)value, editorService, context); + + pv.EscapePressed = false; + + editorService.DropDownControl(pv); + + if (pv.EscapePressed == true) + context.PropertyDescriptor.SetValue(context.Instance, value); + else + return (pv.PivotPoint); + } + } + + return (base.EditValue(context, provider, value)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PieReferenceCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PieReferenceCollectionEditor.cs new file mode 100644 index 00000000..1b00ea62 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PieReferenceCollectionEditor.cs @@ -0,0 +1,112 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class PieReferenceCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private SliceVisualLayout _SliceLayout; + + #endregion + + public PieReferenceCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _SliceLayout = context.Instance as SliceVisualLayout; + + IComponentChangeService cs = BeforeEditValue(context); + + object retval = value; + + try + { + retval = base.EditValue(context, provider, value); + } + finally + { + AfterEditValue(context, cs); + } + + return (retval); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + if (itemType == typeof(PieReferenceLine)) + { + PieReferenceLine line = (PieReferenceLine)base.CreateInstance(itemType); + + line.Name = _SliceLayout.ReferenceLines.GetUniqueName(); + + return (line); + } + + return (base.CreateInstance(itemType)); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + PieReferenceLine item = ChartItem as PieReferenceLine; + + if (item != null) + { + if (AddButton != null) + { + ChartVisualElement cve = _SliceLayout.Parent as ChartVisualElement; + + ChartControlDesigner ccd = (cve != null) ? GetDesigner(cve.ChartControl) : null; + + if (ccd != null) + ccd.InCopyItem = true; + + try + { + AddButton.PerformClick(); + + PieReferenceLineCollection rlc = _SliceLayout.ReferenceLines; + PieReferenceLine clone = rlc[rlc.Count - 1]; + + string name = clone.Name; + item.CopyTo(clone); + clone.Name = name; + } + finally + { + if (ccd != null) + ccd.InCopyItem = false; + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(PieReferenceLine); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PieSeriesPointCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PieSeriesPointCollectionEditor.cs new file mode 100644 index 00000000..481a458b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PieSeriesPointCollectionEditor.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using DevComponents.DotNetBar; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class PieSeriesPointCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private PieSeries _PieSeries; + + #endregion + + public PieSeriesPointCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _PieSeries = context.Instance as PieSeries; + + if (_PieSeries == null) + { + PieSeriesPoint psp = context.Instance as PieSeriesPoint; + + if (psp != null) + _PieSeries = psp.ChartSeries; + } + + if (_PieSeries != null) + return (base.EditValue(context, provider, value)); + + return (value); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + return (base.CreateInstance(itemType)); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + PieSeriesPoint item = ChartItem as PieSeriesPoint; + + if (item != null) + { + if (AddButton != null) + { + ChartControlDesigner ccd = GetDesigner(_PieSeries.ChartControl); + + ccd.InCopyItem = true; + + try + { + AddButton.PerformClick(); + + PieSeriesPointCollection spc = item.Parent as PieSeriesPointCollection; + PieSeriesPoint clone = spc[spc.Count - 1]; + + item.CopyTo(clone); + } + finally + { + ccd.InCopyItem = false; + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(PieSeriesPoint); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointDropDown.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointDropDown.Designer.cs new file mode 100644 index 00000000..22904d4e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointDropDown.Designer.cs @@ -0,0 +1,48 @@ +namespace DevComponents.Charts.Design +{ + partial class PivotPointDropDown + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // PivotPointDropDown + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Name = "PivotPointDropDown"; + this.Size = new System.Drawing.Size(99, 110); + this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.PivotPointDropDown_PreviewKeyDown); + this.ResumeLayout(false); + + } + + #endregion + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointDropDown.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointDropDown.cs new file mode 100644 index 00000000..fee40cd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointDropDown.cs @@ -0,0 +1,332 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.Charts.Design +{ + [ToolboxItem(false)] + public partial class PivotPointDropDown : UserControl + { + #region Constants + + private const int DotRadius = 4; + private const int ScaleWidth = 3; + private const float BevelInside = .035f; + private const float BevelOutside = .05f; + private const float RoundRectangleArc = .125f; + + #endregion + + #region Private variables + + private PointF _PivotPoint; + private Rectangle _DotBounds; + private Rectangle _FrameBounds; + private Rectangle _ScaleBounds; + + private double _ScaleRadius; + private double _StartAngle; + private double _SweepAngle; + + private bool _InFrame; + private bool _InPivotDot; + private bool _PivotMoving; + + private bool _EscapePressed; + + private IWindowsFormsEditorService _EditorService; + private ITypeDescriptorContext _Context; + + #endregion + + public PivotPointDropDown(PointF value, + double scaleRadius, double startAngle, double sweepAngle, + IWindowsFormsEditorService editorService, ITypeDescriptorContext context) + { + _ScaleRadius = scaleRadius; + _StartAngle = startAngle; + _SweepAngle = sweepAngle; + + _ScaleRadius = Math.Max(_ScaleRadius, .07f); + + Initialize(); + + _EditorService = editorService; + _Context = context; + + PivotPoint = value; + } + + public PivotPointDropDown() + { + Initialize(); + } + + #region Initialize + + private void Initialize() + { + InitializeComponent(); + + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + } + + #endregion + + #region Public properties + + #region EditorService + + public IWindowsFormsEditorService EditorService + { + get { return (_EditorService); } + set { _EditorService = value; } + } + + #endregion + + #region EscapePressed + + public bool EscapePressed + { + get { return (_EscapePressed); } + set { _EscapePressed = value; } + } + + #endregion + + #region PivotPoint + + public PointF PivotPoint + { + get { return (_PivotPoint); } + + set + { + _PivotPoint = value; + + RecalcLayout(); + Invalidate(); + + _Context.OnComponentChanging(); + _Context.PropertyDescriptor.SetValue(_Context.Instance, value); + _Context.OnComponentChanged(); + } + } + + #endregion + + #endregion + + #region RecalcLayout + + private void RecalcLayout() + { + int n = Math.Min(Bounds.Width - 4, Bounds.Height - 4); + + _FrameBounds = new Rectangle(2, 2, n, n); + _FrameBounds.X = (Bounds.Width - n) / 2; + _FrameBounds.Y = (Bounds.Height - n) / 2; + + int radius = (int)(n * _ScaleRadius); + int n2 = n / 2; + + _ScaleBounds.Width = radius * 2; + _ScaleBounds.Height = radius * 2; + + int x = _FrameBounds.X + (int)(_PivotPoint.X * _FrameBounds.Width + n2); + int y = _FrameBounds.Y + (int)(_PivotPoint.Y * _FrameBounds.Height + n2); + + _ScaleBounds.X = x - radius; + _ScaleBounds.Y = y - radius; + + _DotBounds = new Rectangle(x - DotRadius, y - DotRadius, DotRadius * 2, DotRadius * 2); + } + + #endregion + + #region Paint support + + #region OnPaint + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + Graphics g = e.Graphics; + + g.SmoothingMode = SmoothingMode.AntiAlias; + + RecalcLayout(); + + DrawFrame(g); + DrawScale(g); + DrawPivotDot(g); + } + + #endregion + + #region DrawFrame + + private void DrawFrame(Graphics g) + { + DrawBlankFrame(g); + } + + #region DrawBlankFrame + + private void DrawBlankFrame(Graphics g) + { + using (Brush br = new SolidBrush(Color.LightGray)) + g.FillRectangle(br, _FrameBounds); + + g.DrawRectangle(Pens.DimGray, _FrameBounds); + } + + #endregion + + #endregion + + #region DrawScale + + private void DrawScale(Graphics g) + { + using (Brush br = new SolidBrush(Color.CornflowerBlue)) + { + using (Pen pen = new Pen(br, ScaleWidth)) + g.DrawArc(pen, _ScaleBounds, (float)_StartAngle, (float)_SweepAngle); + } + } + + #endregion + + #region DrawPivotDot + + private void DrawPivotDot(Graphics g) + { + g.FillEllipse(Brushes.SkyBlue, _DotBounds); + g.DrawEllipse(Pens.DimGray, _DotBounds); + } + + #endregion + + #endregion + + #region Mouse support + + #region OnMouseMove + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + + _InFrame = (_FrameBounds.Contains(e.Location) == true); + + if (_PivotMoving == true && _InFrame == true) + { + int n = Math.Min(Bounds.Width - 4, Bounds.Height - 4); + int n2 = n / 2; + + PivotPoint = new PointF( + (float)(e.X - _FrameBounds.X - n2) / _FrameBounds.Width, + (float)(e.Y - _FrameBounds.Y - n2) / _FrameBounds.Height); + } + + _InPivotDot = (_DotBounds.Contains(e.Location) == true); + + Cursor = (_InPivotDot == true) ? Cursors.Hand : Cursors.Default; + } + + #endregion + + #region OnMouseLeave + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + + _InFrame = false; + _InPivotDot = false; + } + + #endregion + + #region OnMouseDown + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + if (e.Button == MouseButtons.Left) + { + if (_InPivotDot == true) + _PivotMoving = true; + } + } + + #endregion + + #region OnMouseUp + + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + _PivotMoving = false; + + _InFrame = (_FrameBounds.Contains(e.Location) == true); + _InPivotDot = (_DotBounds.Contains(e.Location) == true); + } + + #endregion + + #endregion + + #region PivotPointDropDown_PreviewKeyDown + + private void PivotPointDropDown_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + PointF pt = PivotPoint; + + int n = Math.Min(Bounds.Width - 4, Bounds.Height - 4) / 2; + + switch (e.KeyCode) + { + case Keys.Escape: + _EscapePressed = true; + break; + + case Keys.Home: + PivotPoint = PointF.Empty; + break; + + case Keys.Left: + pt.X -= (float)(_ScaleRadius / 20); + PivotPoint = pt; + break; + + case Keys.Right: + pt.X += (float)(_ScaleRadius / 20); + PivotPoint = pt; + break; + + case Keys.Up: + pt.Y -= (float)(_ScaleRadius / 20); + PivotPoint = pt; + break; + + case Keys.Down: + pt.Y += (float)(_ScaleRadius / 20); + PivotPoint = pt; + break; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointDropDown.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointDropDown.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointDropDown.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointEditor.cs new file mode 100644 index 00000000..0990ea24 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PivotPointEditor.cs @@ -0,0 +1,77 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class PivotPointEditor : UITypeEditor + { + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return (UITypeEditorEditStyle.DropDown); + } + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (false); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + if (provider != null) + { + IWindowsFormsEditorService editorService = + provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (editorService != null) + { + PieChart pieChart = context.Instance as PieChart; + + if (pieChart != null) + { + double scale = pieChart.OuterRadius; + + if (scale >= 1) + { + int n = Math.Min(pieChart.ContentBounds.Width, pieChart.ContentBounds.Height); + scale = (n > 0) ? pieChart.ActualOuterRadius / n : 0; + } + + scale /= 2; + + PivotPointDropDown pv = new PivotPointDropDown((PointF) value, + scale, pieChart.SubSliceVisualLayout.StartAngle, + pieChart.SubSliceVisualLayout.SweepAngle, editorService, context); + + pv.EscapePressed = false; + + editorService.DropDownControl(pv); + + if (pv.EscapePressed == true) + context.PropertyDescriptor.SetValue(context.Instance, value); + else + return (pv.PivotPoint); + } + } + } + + return (base.EditValue(context, provider, value)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PointValueConverter.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PointValueConverter.cs new file mode 100644 index 00000000..e3df5ecb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/PointValueConverter.cs @@ -0,0 +1,117 @@ +using System; +using System.ComponentModel; +using System.Globalization; + +namespace DevComponents.Charts.Design +{ + /// + /// Represents PointValueConverter converter. + /// + public class PointValueConverter : TypeConverter + { + public PointValueConverter() + { + } + + #region CanConvertTo + + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + return true; + + return base.CanConvertFrom(context, sourceType); + } + + #endregion + + #region CanConvertTo + + public override bool CanConvertTo( + ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + return true; + + return base.CanConvertTo(context, destinationType); + } + + #endregion + + #region ConvertFrom + + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + return (GetConvertedValue((string)value)); + + return base.ConvertFrom(context, culture, value); + } + + #region GetConvertedValue + + private object GetConvertedValue(string text) + { + string s = text.Trim(); + + if (text.Length == 0) + return (null); + + if (s.StartsWith("\"") && s.EndsWith("\"")) + return (s.Substring(1, s.Length - 2)); + + int intResult; + + if (int.TryParse(text, out intResult) == true) + return (intResult); + + double dblResult; + + if (double.TryParse(text, out dblResult) == true) + return (dblResult); + + DateTime dtResult; + + if (DateTime.TryParse(text, out dtResult) == true) + return (dtResult); + + return (text); + } + + #endregion + + #endregion + + #region ConvertTo + + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (value != null) + { + if (destinationType == typeof(string)) + { + if (value == null) + return (""); + + if (value is string) + return ("\"" + value + "\""); + + if (value is int) + return (value.ToString()); + + if (value is DateTime) + return (value.ToString()); + + return (String.Format("{0:0.0###############}", value)); + } + } + + return (string.Empty); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/Properties/Resources.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/Properties/Resources.Designer.cs new file mode 100644 index 00000000..9702ca24 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34209 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DevComponents.Charts.Design.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DevComponents.Charts.Design.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Copy { + get { + object obj = ResourceManager.GetObject("Copy", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/Properties/Resources.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/Properties/Resources.resx new file mode 100644 index 00000000..11a4ac80 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\resources\copy.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueDropDown.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueDropDown.Designer.cs new file mode 100644 index 00000000..dcc1c86b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueDropDown.Designer.cs @@ -0,0 +1,105 @@ +namespace DevComponents.Charts.Design +{ + partial class RangeValueDropDown + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this._TrackBar = new System.Windows.Forms.TrackBar(); + this._LabelValue = new System.Windows.Forms.Label(); + this._LabelMin = new System.Windows.Forms.Label(); + this._LabelMax = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this._TrackBar)).BeginInit(); + this.SuspendLayout(); + // + // _TrackBar + // + this._TrackBar.AutoSize = false; + this._TrackBar.Dock = System.Windows.Forms.DockStyle.Fill; + this._TrackBar.Location = new System.Drawing.Point(0, 0); + this._TrackBar.Name = "_TrackBar"; + this._TrackBar.Size = new System.Drawing.Size(186, 40); + this._TrackBar.TabIndex = 0; + this._TrackBar.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this._TrackBar_PreviewKeyDown); + this._TrackBar.ValueChanged += new System.EventHandler(this.TrackBar_ValueChanged); + // + // _LabelValue + // + this._LabelValue.AutoEllipsis = true; + this._LabelValue.Location = new System.Drawing.Point(59, 21); + this._LabelValue.Name = "_LabelValue"; + this._LabelValue.Size = new System.Drawing.Size(69, 16); + this._LabelValue.TabIndex = 1; + this._LabelValue.Text = "Value"; + this._LabelValue.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // _LabelMin + // + this._LabelMin.AutoEllipsis = true; + this._LabelMin.ForeColor = System.Drawing.SystemColors.ControlDarkDark; + this._LabelMin.Location = new System.Drawing.Point(3, 21); + this._LabelMin.Name = "_LabelMin"; + this._LabelMin.Size = new System.Drawing.Size(50, 16); + this._LabelMin.TabIndex = 2; + this._LabelMin.Text = "Min"; + this._LabelMin.TextAlign = System.Drawing.ContentAlignment.BottomLeft; + // + // _LabelMax + // + this._LabelMax.AutoEllipsis = true; + this._LabelMax.ForeColor = System.Drawing.SystemColors.ControlDarkDark; + this._LabelMax.Location = new System.Drawing.Point(134, 21); + this._LabelMax.Name = "_LabelMax"; + this._LabelMax.Size = new System.Drawing.Size(52, 16); + this._LabelMax.TabIndex = 3; + this._LabelMax.Text = "Max"; + this._LabelMax.TextAlign = System.Drawing.ContentAlignment.BottomRight; + // + // RangeValueDropDown + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this._LabelMax); + this.Controls.Add(this._LabelMin); + this.Controls.Add(this._LabelValue); + this.Controls.Add(this._TrackBar); + this.Name = "RangeValueDropDown"; + this.Size = new System.Drawing.Size(186, 40); + ((System.ComponentModel.ISupportInitialize)(this._TrackBar)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TrackBar _TrackBar; + private System.Windows.Forms.Label _LabelValue; + private System.Windows.Forms.Label _LabelMin; + private System.Windows.Forms.Label _LabelMax; + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueDropDown.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueDropDown.cs new file mode 100644 index 00000000..965e0eb8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueDropDown.cs @@ -0,0 +1,160 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.Charts.Design +{ + [ToolboxItem(false)] + public partial class RangeValueDropDown : UserControl + { + #region Private variables + + private double _Value; + private bool _EscapePressed; + + private IWindowsFormsEditorService _EditorService; + private ITypeDescriptorContext _Context; + + #endregion + + public RangeValueDropDown(double value, double minimum, double maximum, + IWindowsFormsEditorService editorService, ITypeDescriptorContext context) + { + InitializeComponent(); + + _EditorService = editorService; + _Context = context; + + if (double.IsNaN(value) == true) + value = 0; + + if (value < minimum) + { + if ((minimum * 1000 > Int16.MinValue) && (minimum * 1000 < Int16.MaxValue)) + minimum = value; + } + + if (value > maximum) + { + if ((maximum * 1000 > Int16.MinValue) && (maximum * 1000 < Int16.MaxValue)) + maximum = value; + } + + _TrackBar.Minimum = (int)(minimum * 1000); + _TrackBar.Maximum = (int)(maximum * 1000); + + _TrackBar.SmallChange = _TrackBar.Maximum / 100; + _TrackBar.LargeChange = _TrackBar.Maximum / 10; + _TrackBar.TickFrequency = _TrackBar.LargeChange; + + _TrackBar.Value = (int)(value * 1000); + + _LabelMin.Text = String.Format("{0:f}", minimum); + _LabelMax.Text = String.Format("{0:f}", maximum); + + Value = value; + } + + public RangeValueDropDown() + { + InitializeComponent(); + } + + #region DefaultSize + + protected override Size DefaultSize + { + get { return new Size(186, 40); } + } + + #endregion + + #region Public properties + + #region EditorService + + public IWindowsFormsEditorService EditorService + { + get { return (_EditorService); } + set { _EditorService = value; } + } + + #endregion + + #region EscapePressed + + public bool EscapePressed + { + get { return (_EscapePressed); } + set { _EscapePressed = value; } + } + + #endregion + + #region Value + + public double Value + { + get { return (_Value); } + + set + { + _Value = value; + + _LabelValue.Text = String.Format("{0:f3}", value); + _LabelValue.Update(); + + object cvalue = Convert.ChangeType(value, _Context.PropertyDescriptor.PropertyType); + + _Context.OnComponentChanging(); + _Context.PropertyDescriptor.SetValue(_Context.Instance, cvalue); + _Context.OnComponentChanged(); + } + } + + #endregion + + #endregion + + #region OnResize + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + + int width = _TrackBar.Width; + + int dx = width / 3; + + _LabelMin.Width = dx; + _LabelMax.Width = dx; + _LabelValue.Width = dx; + + _LabelValue.Location = new Point((width - dx) / 2, _LabelValue.Location.Y); + _LabelMax.Location = new Point(width - dx, _LabelMax.Location.Y); + } + + #endregion + + #region _TrackBar_ValueChanged + + private void TrackBar_ValueChanged(object sender, EventArgs e) + { + Value = ((float)_TrackBar.Value) / 1000; + } + + #endregion + + #region _TrackBar_PreviewKeyDown + + private void _TrackBar_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + if (e.KeyCode == Keys.Escape) + _EscapePressed = true; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueDropDown.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueDropDown.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueDropDown.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueEditor.cs new file mode 100644 index 00000000..03be54b9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/RangeValueEditor.cs @@ -0,0 +1,225 @@ +using System; +using System.ComponentModel; +using System.Drawing.Design; +using System.Windows.Forms.Design; + +namespace DevComponents.Charts.Design +{ + public class RangeValueEditor : UITypeEditor + { + #region Private variables + + private const double MinValue = 0; + private const double MaxValue = 1; + + #endregion + + #region Public properties + + public virtual double Minimum + { + get { return (MinValue); } + } + + public virtual double Maximum + { + get { return (MaxValue); } + } + + #endregion + + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return (UITypeEditorEditStyle.DropDown); + } + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (false); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + if (provider != null) + { + IWindowsFormsEditorService editorService = + provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (editorService != null) + { + double dvalue = Convert.ToDouble(value); + + RangeValueDropDown rv = new + RangeValueDropDown(dvalue, Minimum, Maximum, editorService, context); + + rv.EscapePressed = false; + + editorService.DropDownControl(rv); + + if (rv.EscapePressed == true) + { + context.PropertyDescriptor.SetValue(context.Instance, value); + } + else + { + Type type = value.GetType(); + + value = Convert.ChangeType(rv.Value, type); + + return (value); + } + } + } + + return (base.EditValue(context, provider, value)); + } + + #endregion + } + + #region AngleRangeValueEditor + + public class AngleRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (360); } + } + } + + #endregion + + #region AngleOffsetRangeValueEditor + + public class AngleOffsetRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (360); } + } + + public override double Minimum + { + get { return (-360); } + } + } + + #endregion + + #region AngleMarginRangeValueEditor + + public class AngleMarginRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (10); } + } + } + + #endregion + + #region MarginRangeValueEditor + + public class MarginRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (50); } + } + } + + #endregion + + #region RadiusRangeValueEditor + + public class RadiusRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (1); } + } + } + + #endregion + + #region WidthRangeValueEditor + + public class WidthRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (.3); } + } + } + + #endregion + + #region OffsetRangeValueEditor + + public class OffsetRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (.3); } + } + + public override double Minimum + { + get { return (-.3); } + } + } + + #endregion + + #region OffsetRangeValueEditor + + public class OffsetPosRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (.9); } + } + + public override double Minimum + { + get { return (0); } + } + } + + #endregion + + #region WidthMaxRangeValueEditor + + public class WidthMaxRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (1); } + } + } + + #endregion + + #region HalfRadiusRangeValueEditor + + public class HalfRadiusRangeValueEditor : RangeValueEditor + { + public override double Maximum + { + get { return (.5); } + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/Resources/Copy.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/Resources/Copy.png new file mode 100644 index 00000000..195dc6d6 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/Resources/Copy.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointCollectionEditor.cs new file mode 100644 index 00000000..c22e5069 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointCollectionEditor.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using DevComponents.DotNetBar; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class SeriesPointCollectionEditor : BaseCollectionEditor + { + #region Private variables + + private ChartSeries _ChartSeries; + private SeriesPointCollection _SavedCollection; + + #endregion + + public SeriesPointCollectionEditor(Type type) + : base(type) + { + } + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _ChartSeries = context.Instance as ChartSeries; + + SeriesPointCollection spc = (SeriesPointCollection)value; + + _SavedCollection = new SeriesPointCollection(); + + foreach (SeriesPoint sp in spc) + _SavedCollection.Add(sp.Copy()); + + try + { + object evalue = base.EditValue(context, provider, value); + + if (EditCancelled == true) + return (_SavedCollection); + + return (evalue); + } + catch + { + return (_SavedCollection); + } + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + return (base.CreateInstance(itemType)); + } + + #endregion + + #region CopyButton_Click + + protected override void CopyButton_Click(object sender, EventArgs e) + { + SeriesPoint item = ChartItem as SeriesPoint; + + if (item != null) + { + if (AddButton != null) + { + ChartControlDesigner ccd = GetDesigner(_ChartSeries.ChartControl); + + ccd.InCopyItem = true; + + try + { + AddButton.PerformClick(); + + SeriesPointCollection spc = _ChartSeries.SeriesPoints; + SeriesPoint clone = spc[spc.Count - 1]; + + item.CopyTo(clone); + } + finally + { + ccd.InCopyItem = false; + } + } + } + } + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(SeriesPoint); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueDropDown.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueDropDown.Designer.cs new file mode 100644 index 00000000..07d8ba24 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueDropDown.Designer.cs @@ -0,0 +1,88 @@ +namespace DevComponents.Charts.Design +{ + partial class SeriesPointValueDropDown + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnCancel = new DevComponents.DotNetBar.ButtonX(); + this.btnOk = new DevComponents.DotNetBar.ButtonX(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.ColorTable = DevComponents.DotNetBar.eButtonColor.Blue; + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(48, 29); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(15, 15); + this.btnCancel.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnCancel.Symbol = ""; + this.btnCancel.SymbolColor = System.Drawing.Color.DarkRed; + this.btnCancel.SymbolSize = 10F; + this.btnCancel.TabIndex = 3; + this.btnCancel.TextAlignment = DevComponents.DotNetBar.eButtonTextAlignment.Left; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // btnOk + // + this.btnOk.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOk.ColorTable = DevComponents.DotNetBar.eButtonColor.Blue; + this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOk.Location = new System.Drawing.Point(26, 29); + this.btnOk.Name = "btnOk"; + this.btnOk.Size = new System.Drawing.Size(19, 15); + this.btnOk.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnOk.Symbol = ""; + this.btnOk.SymbolColor = System.Drawing.SystemColors.ControlText; + this.btnOk.SymbolSize = 10F; + this.btnOk.TabIndex = 2; + this.btnOk.TextAlignment = DevComponents.DotNetBar.eButtonTextAlignment.Left; + this.btnOk.Click += new System.EventHandler(this.btnOk_Click); + // + // SeriesPointValueDropDown + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.btnOk); + this.Controls.Add(this.btnCancel); + this.MinimumSize = new System.Drawing.Size(45, 45); + this.Name = "SeriesPointValueDropDown"; + this.Size = new System.Drawing.Size(65, 45); + this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.MyPreviewKeyDown); + this.ResumeLayout(false); + + } + + #endregion + + private DotNetBar.ButtonX btnCancel; + private DotNetBar.ButtonX btnOk; + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueDropDown.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueDropDown.cs new file mode 100644 index 00000000..2ba4f7cc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueDropDown.cs @@ -0,0 +1,330 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.Charts.Design +{ + [ToolboxItem(false)] + public partial class SeriesPointValueDropDown : UserControl + { + #region Private variables + + private object _Value; + private bool _EscapePressed; + + private IWindowsFormsEditorService _EditorService; + private ITypeDescriptorContext _Context; + + private LabeledTextBoxX[] _TextBoxes; + + #endregion + + public SeriesPointValueDropDown() + { + InitializeComponent(); + } + + public SeriesPointValueDropDown(object value, + IWindowsFormsEditorService editorService, ITypeDescriptorContext context) + { + if (value == null) + value = new object[0]; + + _Value = value; + + _EditorService = editorService; + _Context = context; + + BackColor = SystemColors.Control; + + InitializeComponent(); + + LayoutMultipleEntry(); + + Disposed += SeriesPointValueDropDown_Disposed; + } + + #region LayoutMultipleEntry + + private void LayoutMultipleEntry() + { + if (_Value is object[]) + { + object[] values = (object[])_Value; + + _TextBoxes = GetTextBoxArray(values); + + PositionBtns(); + } + } + + #region GetTextBoxArray + + private LabeledTextBoxX[] GetTextBoxArray(object[] values) + { + LabeledTextBoxX[] tba = new LabeledTextBoxX[Math.Max(values.Length + 1, 3)]; + + for (int i = 0; i < tba.Length; i++) + { + object value = (i < values.Length) ? values[i] : null; + + tba[i] = GetValueTextBox(value, i); + } + + return (tba); + } + + #endregion + + #endregion + + #region GetValueTextBox + + private LabeledTextBoxX GetValueTextBox(object value, int i) + { + LabeledTextBoxX ltb = new LabeledTextBoxX(); + + ltb.EscapeKeyPressed += ltb_EscapeKeyPressed; + + ltb.lbIndex.Text = i.ToString(); + ltb.tbValue.Tag = (value is string) ? "\"" + value + "\"" : value; + ltb.tbValue.Text = FormatToStringValue(value); + + ltb.Location = new Point(0, i * (ltb.Height + 2) + 2); + ltb.Width = Width + 6; + + ltb.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + + Controls.Add(ltb); + + return (ltb); + } + + #region FormatToStringValue + + private string FormatToStringValue(object value) + { + if (value == null) + return (""); + + if (value is string) + return ("\"" + value + "\""); + + if (value is int) + return (value.ToString()); + + if (value is DateTime) + return (value.ToString()); + + return (String.Format("{0:0.0###############}", value)); + } + + #endregion + + #region ltb_EscapeKeyPressed + + void ltb_EscapeKeyPressed(object sender, EventArgs e) + { + btnCancel.PerformClick(); + } + + #endregion + + #endregion + + #region PositionBtns + + private void PositionBtns() + { + int y = 2; + + foreach (LabeledTextBoxX ltb in _TextBoxes) + y += (ltb.Height + 2); + + Height = y + btnOk.Height; + + int x = Width - btnCancel.Width; + + btnCancel.Location = new Point(x - 3 , y); + btnOk.Location = new Point(x - 3 - btnOk.Width, y); + } + + #endregion + + #region Public properties + + #region Value + + public object Value + { + get + { + if (EscapePressed == true) + return (_Value); + + return (GetTextBoxValues()); + } + } + + #region GetTextBoxValues + + private object[] GetTextBoxValues() + { + object[] values = new object[_TextBoxes.Length]; + + int n = 0; + + for (int i = 0; i < _TextBoxes.Length; i++) + { + values[i] = GetTextBoxValue(i); + + if (values[i] != null) + n++; + } + + if (n > 0) + { + object[] rvalues = new object[n]; + + n = 0; + + for (int i = 0; i < values.Length; i++) + { + if (values[i] != null) + rvalues[n++] = values[i]; + } + + return (rvalues); + } + + return (null); + } + + #endregion + + #region GetTextBoxValue + + private object GetTextBoxValue(int n) + { + LabeledTextBoxX ltb = _TextBoxes[n]; + + if (string.IsNullOrEmpty(ltb.tbValue.Text) == true) + return (null); + + if (ltb.tbValue.Tag != null) + { + if (ltb.tbValue.Text.Equals(ltb.tbValue.Tag.ToString()) == true) + return (ltb.tbValue.Tag); + } + + return (GetConvertedValue(ltb.tbValue.Text)); + } + + #endregion + + #region GetConvertedValue + + private object GetConvertedValue(string text) + { + string s = text.Trim(); + + if (s.StartsWith("\"") && s.EndsWith("\"")) + return (s.Substring(1, s.Length - 2)); + + if (s.Contains(".") == false) + { + int iResult; + + if (int.TryParse(text, out iResult) == true) + return (iResult); + } + + double dblResult; + + if (double.TryParse(text, out dblResult) == true) + return (dblResult); + + DateTime dtResult; + + if (DateTime.TryParse(text, out dtResult) == true) + return (dtResult); + + return (text); + } + + #endregion + + #endregion + + #region EditorService + + public IWindowsFormsEditorService EditorService + { + get { return (_EditorService); } + set { _EditorService = value; } + } + + #endregion + + #region EscapePressed + + public bool EscapePressed + { + get { return (_EscapePressed); } + set { _EscapePressed = value; } + } + + #endregion + + #endregion + + #region MyPreviewKeyDown + + private void MyPreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + if (e.KeyCode == Keys.Escape) + _EscapePressed = true; + } + + #endregion + + #region btnOk_Click + + private void btnOk_Click(object sender, EventArgs e) + { + _EditorService.CloseDropDown(); + } + + #endregion + + #region btnCancel_Click + + private void btnCancel_Click(object sender, EventArgs e) + { + _EscapePressed = true; + + _EditorService.CloseDropDown(); + } + + #endregion + + #region SeriesPointValueDropDown_Disposed + + void SeriesPointValueDropDown_Disposed(object sender, EventArgs e) + { + for (int i = 0; i < _TextBoxes.Length; i++) + { + LabeledTextBoxX ltb = _TextBoxes[i]; + + ltb.EscapeKeyPressed -= ltb_EscapeKeyPressed; + ltb.Dispose(); + + _TextBoxes[i] = null; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueDropDown.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueDropDown.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueDropDown.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueEditor.cs new file mode 100644 index 00000000..f49387fb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SeriesPointValueEditor.cs @@ -0,0 +1,59 @@ +using System; +using System.ComponentModel; +using System.Drawing.Design; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.Charts; + +namespace DevComponents.Charts.Design +{ + public class SeriesPointValueEditor : UITypeEditor + { + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return (UITypeEditorEditStyle.DropDown); + } + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (false); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + IWindowsFormsEditorService editorService = + provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (editorService != null) + { + SeriesPointValueDropDown fs = new + SeriesPointValueDropDown(value, editorService, context); + + fs.EscapePressed = false; + + editorService.DropDownControl(fs); + + if (fs.EscapePressed == true) + return (value); + + context.PropertyDescriptor.SetValue(context.Instance, fs.Value); + + return (fs.Value); + } + + return (base.EditValue(context, provider, value)); + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeDropDown.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeDropDown.Designer.cs new file mode 100644 index 00000000..e4659acc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeDropDown.Designer.cs @@ -0,0 +1,48 @@ +namespace DevComponents.Charts.Design +{ + partial class SizeDropDown + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // PivotPointDropDown + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Name = "PivotPointDropDown"; + this.Size = new System.Drawing.Size(99, 110); + this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.PivotPointDropDown_PreviewKeyDown); + this.ResumeLayout(false); + + } + + #endregion + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeDropDown.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeDropDown.cs new file mode 100644 index 00000000..5f744368 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeDropDown.cs @@ -0,0 +1,242 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.Charts.Design +{ + [ToolboxItem(false)] + public partial class SizeDropDown : UserControl + { + #region Constants + + private const int DotRadius = 4; + + #endregion + + #region Private variables + + private SizeF _Size; + private Rectangle _DotBounds; + private Rectangle _FrameBounds; + private Rectangle _DotRect; + + private bool _InFrame; + private bool _InSizeDot; + private bool _PivotMoving; + + private bool _EscapePressed; + + private IWindowsFormsEditorService _EditorService; + private ITypeDescriptorContext _Context; + + #endregion + + public SizeDropDown(SizeF value, + IWindowsFormsEditorService editorService, ITypeDescriptorContext context) + { + Initialize(); + + _EditorService = editorService; + _Context = context; + + _Size = value; + } + + public SizeDropDown() + { + Initialize(); + } + + #region Initialize + + private void Initialize() + { + InitializeComponent(); + + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + } + + #endregion + + #region Public properties + + #region EditorService + + public IWindowsFormsEditorService EditorService + { + get { return (_EditorService); } + set { _EditorService = value; } + } + + #endregion + + #region EscapePressed + + public bool EscapePressed + { + get { return (_EscapePressed); } + set { _EscapePressed = value; } + } + + #endregion + + #region PivotPoint + + public SizeF Syze + { + get { return (_Size); } + + set + { + _Size = value; + + RecalcLayout(); + Invalidate(); + + _Context.OnComponentChanging(); + _Context.PropertyDescriptor.SetValue(_Context.Instance, value); + _Context.OnComponentChanged(); + } + } + + #endregion + + #endregion + + #region RecalcLayout + + private void RecalcLayout() + { + int n = Math.Min(Bounds.Width - 4, Bounds.Height - 4); + + _FrameBounds = new Rectangle(2, 2, n, n); + _FrameBounds.X = (Bounds.Width - n) / 2; + _FrameBounds.Y = (Bounds.Height - n) / 2; + + int x = _FrameBounds.X + (int)(_Size.Width * _FrameBounds.Width); + int y = _FrameBounds.Y + (int)(_Size.Height * _FrameBounds.Height); + + _DotBounds = new Rectangle(x - DotRadius, y - DotRadius, + DotRadius * 2, DotRadius * 2); + + _DotRect = new Rectangle(0, 0, x, y); + } + + #endregion + + #region Paint support + + #region OnPaint + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + Graphics g = e.Graphics; + + g.SmoothingMode = SmoothingMode.AntiAlias; + + RecalcLayout(); + + g.DrawRectangle(Pens.Red, _DotRect); + + DrawPivotDot(g); + } + + #endregion + + #region DrawPivotDot + + private void DrawPivotDot(Graphics g) + { + g.FillEllipse(Brushes.SkyBlue, _DotBounds); + g.DrawEllipse(Pens.DimGray, _DotBounds); + } + + #endregion + + #endregion + + #region Mouse support + + #region OnMouseMove + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + + _InFrame = (_FrameBounds.Contains(e.Location) == true); + + if (_PivotMoving == true && _InFrame == true) + { + Syze = new SizeF( + (float)(e.X - _FrameBounds.X) / _FrameBounds.Width, + (float)(e.Y - _FrameBounds.Y) / _FrameBounds.Height); + } + + _InSizeDot = (_DotBounds.Contains(e.Location) == true); + + Cursor = (_InSizeDot == true) ? Cursors.Hand : Cursors.Default; + } + + #endregion + + #region OnMouseLeave + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + + _InFrame = false; + _InSizeDot = false; + } + + #endregion + + #region OnMouseDown + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + if (e.Button == MouseButtons.Left) + { + if (_InSizeDot == true) + _PivotMoving = true; + } + } + + #endregion + + #region OnMouseUp + + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + _PivotMoving = false; + + _InFrame = (_FrameBounds.Contains(e.Location) == true); + _InSizeDot = (_DotBounds.Contains(e.Location) == true); + } + + #endregion + + #endregion + + #region PivotPointDropDown_PreviewKeyDown + + private void PivotPointDropDown_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + if (e.KeyCode == Keys.Escape) + _EscapePressed = true; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeDropDown.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeDropDown.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeDropDown.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeEditor.cs new file mode 100644 index 00000000..5d93fb54 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts.Design/SizeEditor.cs @@ -0,0 +1,59 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms.Design; + +namespace DevComponents.Charts.Design +{ + public class SizeEditor : UITypeEditor + { + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return (UITypeEditorEditStyle.DropDown); + } + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (false); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + if (provider != null) + { + IWindowsFormsEditorService editorService = + provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (editorService != null) + { + SizeDropDown pv = new SizeDropDown((SizeF)value, editorService, context); + + pv.EscapePressed = false; + + editorService.DropDownControl(pv); + + if (pv.EscapePressed == true) + context.PropertyDescriptor.SetValue(context.Instance, value); + else + return (pv.Syze); + } + } + + return (base.EditValue(context, provider, value)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.cs new file mode 100644 index 00000000..a28f961c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.cs @@ -0,0 +1,8248 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using DevComponents.Charts.TextMarkup; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents a Chart Control + /// + [ToolboxItem(true), ToolboxBitmap(typeof(ChartControl), "ChartControl.ico")] + [Designer("DevComponents.Charts.Design.ChartControlDesigner, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class ChartControl : Control, INotifyPropertyChanged, IMessageFilter + { + #region Events + + #region DataBindingStart + + /// + /// Occurs when the Chart is about to start a binding operation + /// + [Description("Occurs when the Chart is about to start a binding operation.")] + public event EventHandler DataBindingStart; + + #endregion + + #region ChartDataBindingComplete + + /// + /// Occurs when a Chart data binding operation is completed + /// + [Description("Occurs when a Chart data binding operation is completed.")] + public event EventHandler ChartDataBindingComplete; + + #endregion + + #region ChartMatrixResized + + /// + /// Occurs when a ChartMatrix has been resized. + /// + [Description("Occurs when a ChartMatrix has been resized.")] + public event EventHandler ChartMatrixResized; + + #endregion + + #region CompareElements + + /// + /// Occurs when the chart needs to compare 1 element with another + /// + [Description("Occurs when the chart needs to compare 1 element with another.")] + public event EventHandler CompareElements; + + #endregion + + #region EmptyTextMarkupLinkClick + + /// + /// Occurs when a ChartContainer's EmptyText MarkupLink has been clicked + /// + [Description("Occurs when a ChartContainer's EmptyText MarkupLink has been clicked.")] + public event EventHandler EmptyTextMarkupLinkClick; + + #endregion + + #region GetPieCenterLabel + + /// + /// Occurs when a Pie Center label is needed + /// + [Description("Occurs when a Pie Center label is needed.")] + public event EventHandler GetPieCenterLabel; + + #endregion + + #region GetCrosshairAxisLabel + + /// + /// Occurs when a Crosshair Axis label is needed + /// + [Description("Occurs when a Crosshair Axis label is needed.")] + public event EventHandler GetCrosshairAxisLabel; + + #endregion + + #region GetCrosshairLabelHeader + + /// + /// Occurs when a CrosshairLabel header is needed + /// + [Description("Occurs when a CrosshairLabel header is needed.")] + public event EventHandler GetCrosshairLabelHeader; + + #endregion + + #region GetCrosshairLabelItem + + /// + /// Occurs when a CrosshairLabel item (text) is needed + /// + [Description("Occurs when a CrosshairLabel item (text) is needed.")] + public event EventHandler GetCrosshairLabelItem; + + #endregion + + #region GetSliceLabel + + /// + /// Occurs when a Pie Slice label (text) is needed + /// + [Description("Occurs when a Pie Slice label (text) is needed.")] + public event EventHandler GetSliceLabel; + + #endregion + + #region GetTickmarkLabel + + /// + /// Occurs when a MajorTickmark label (text and color) is needed + /// + [Description("Occurs when a MajorTickmark label (text and color) is needed.")] + public event EventHandler GetTickmarkLabel; + + #endregion + + #region GetToolTip + + /// + /// Occurs when a Pie SeriesPoint ToolTip is needed + /// + [Description("Occurs when a Pie SeriesPoint ToolTip is needed.")] + public event EventHandler GetToolTip; + + #endregion + + #region GetElementStyle + + /// + /// Occurs when a ChartElement Style is needed. + /// + [Description("Occurs when a ChartElement Style is needed.")] + public event EventHandler GetElementStyle; + + #endregion + + #region GetPieSeriesPointStyle + + /// + /// Occurs when a PieSeriesPoint Style is needed. + /// + [Description("Occurs when a PieSeriesPoint Style is needed.")] + public event EventHandler GetPieSeriesPointStyle; + + #endregion + + #region LayoutBoundsInvalid + + /// + /// Occurs when layout bounds of the item is invalidated. + /// + public event EventHandler LayoutBoundsInvalid; + + #endregion + + #region LegendItemCheckedChanged + + /// + /// Occurs when a LegendItem checked state has changed + /// + [Description("Occurs when a LegendItem checked state has changed.")] + public event EventHandler LegendItemCheckedChanged; + + #endregion + + #region ChartMouseClick + + /// + /// Occurs when a single click has ocurred on a chart Pie element. + /// + [Description("Occurs when a single click has ocurred on a chart Pie element.")] + public event EventHandler ChartMouseClick; + + #endregion + + #region ChartMouseDoubleClick + + /// + /// Occurs when a double click has ocurred on a chart Pie element. + /// + [Description("Occurs when a double click has ocurred on a chart Pie element.")] + public event EventHandler ChartMouseDoubleClick; + + #endregion + + #region PieCenterMarkupLinkClick + + /// + /// Occurs after a pie center MarkupLink has been clicked. + /// + [Description("Occurs after a pie center MarkupLink has been clicked.")] + public event EventHandler PieCenterMarkupLinkClick; + + #endregion + + #region PieDetachChanged + + /// + /// Occurs after a pie element detach was performed by the user. + /// + [Description("Occurs after a pie element detach was performed by the user.")] + public event EventHandler PieDetachChanged; + + #endregion + + #region PieExplodeChanged + + /// + /// Occurs after a pie explode operation was performed by the user. + /// + [Description("Occurs after a pie explode operation was performed by the user.")] + public event EventHandler PieExplodeChanged; + + #endregion + + #region PieRingLevelChanged + + /// + /// Occurs after a ring level change, as initiated + /// by the user, has taken place. + /// + [Description("Occurs after a ring level change, as initiated by the user, has taken place.")] + public event EventHandler PieRingLevelChanged; + + #endregion + + #region PieRingLevelChanging + + /// + /// Occurs after a user has initiated a ring level change, but + /// before the actual change has taken place. + /// + [Description("Occurs after a user has initiated a ring level change, but before the actual change has taken place.")] + public event EventHandler PieRingLevelChanging; + + #endregion + + #region PieSelectionChanged + + /// + /// Occurs after a pie selection was performed by the user. + /// + [Description("Occurs after a pie selection was performed by the user.")] + public event EventHandler PieSelectionChanged; + + #endregion + + #region PointLabelUpdate + + /// + /// Occurs when a PointLabel update is needed. + /// + [Description("Occurs when a PointLabel update is needed.")] + public event EventHandler PointLabelUpdate; + + #endregion + + #region PostLoadLegendData + + /// + /// Occurs after a Legend's data has been loaded. + /// + [Description("Occurs after a Legend's data has been loaded.")] + public event EventHandler PostLoadLegendData; + + #endregion + + #region PostRenderContentBackground + + /// + /// Occurs after a chart content area has been rendered. + /// + [Description("Occurs after a chart content area has been rendered.")] + public event EventHandler PostRenderContentBackground; + + #endregion + + #region PostRenderFrameBackground + + /// + /// Occurs after a chart Frame area has been rendered. + /// + [Description("Occurs after a chart Frame area has been rendered.")] + public event EventHandler PostRenderFrameBackground; + + #endregion + + #region PostRenderPanelBackground + + /// + /// Occurs after a chart Panel area has been rendered. + /// + [Description("Occurs after a chart Panel area has been rendered.")] + public event EventHandler PostRenderPanelBackground; + + #endregion + + #region PostRenderPieCenterBackground + + /// + /// Occurs after the pie center background has been rendered. + /// + [Description("Occurs after the pie center background has been rendered.")] + public event EventHandler PostRenderPieCenterBackground; + + #endregion + + #region PostRenderPieCenterContent + + /// + /// Occurs after the pie center content has been rendered. + /// + [Description("Occurs after the pie center content has been rendered.")] + public event EventHandler PostRenderPieCenterContent; + + #endregion + + #region PostRenderPointConnector + + /// + /// Occurs after a PointConnector has been rendered + /// + [Description("Occurs after a PointConnector has been rendered.")] + public event EventHandler PostRenderPointConnector; + + #endregion + + #region PostRenderPointLabel + + /// + /// Occurs after a PointLabel has been rendered + /// + [Description("Occurs after a PointLabel has been rendered.")] + public event EventHandler PostRenderPointLabel; + + #endregion + + #region PostRenderRadialGrid + + /// + /// Occurs after a radial grid has been rendered + /// + [Description("Occurs after a radial grid has been rendered.")] + public event EventHandler PostRenderRadialGrid; + + #endregion + + #region PostRenderSeriesBar + + /// + /// Occurs after a series bar has been rendered. + /// + [Description("Occurs after a series bar has been rendered.")] + public event EventHandler PostRenderSeriesBar; + + #endregion + + #region PostRenderSeriesHiLoBar + + /// + /// Occurs after a series HiLo Bar segment has been rendered. + /// + [Description("Occurs after a series HiLo Bar segment has been rendered.")] + public event EventHandler PostRenderSeriesHiLoBar; + + #endregion + + #region PostRenderSeriesPoint + + /// + /// Occurs after a series point has been rendered + /// + [Description("Occurs after a series point has been rendered.")] + public event EventHandler PostRenderSeriesPoint; + + #endregion + + #region PostRenderSlice + + /// + /// Occurs after the pie slice area has been rendered. + /// + [Description("Occurs after the pie slice area has been rendered.")] + public event EventHandler PostRenderSlice; + + #endregion + + #region PreLoadLegendData + + /// + /// Occurs prior to a Legend's data being loaded. + /// + [Description("Occurs prior to a Legend's data being loaded.")] + public event EventHandler PreLoadLegendData; + + #endregion + + #region PreRenderContentBackground + + /// + /// Occurs prior to the chart Content area being rendered. + /// + [Description("Occurs prior to the chart Content area being rendered.")] + public event EventHandler PreRenderContentBackground; + + #endregion + + #region PreRenderFrameBackground + + /// + /// Occurs prior to the chart Frame area being rendered. + /// + [Description("Occurs prior to the chart Frame area being rendered.")] + public event EventHandler PreRenderFrameBackground; + + #endregion + + #region PreRenderPanelBackground + + /// + /// Occurs prior to the chart Panel area being rendered. + /// + [Description("Occurs prior to the chart Panel area being rendered.")] + public event EventHandler PreRenderPanelBackground; + + #endregion + + #region PreRenderPieCenterBackground + + /// + /// Occurs prior to the pie center background being rendered. + /// + [Description("Occurs prior to the pie center background being rendered.")] + public event EventHandler PreRenderPieCenterBackground; + + #endregion + + #region PreRenderPieCenterContent + + /// + /// Occurs prior to the pie center content being rendered. + /// + [Description("Occurs prior to the pie center content being rendered.")] + public event EventHandler PreRenderPieCenterContent; + + #endregion + + #region PreRenderPointConnector + + /// + /// Occurs prior to a PointConnector being rendered + /// + [Description("Occurs prior to a PointConnector being rendered.")] + public event EventHandler PreRenderPointConnector; + + #endregion + + #region PreRenderPointLabel + + /// + /// Occurs prior to a PointLabel being rendered + /// + [Description("Occurs prior to a PointLabel being rendered.")] + public event EventHandler PreRenderPointLabel; + + #endregion + + #region PreRenderRadialGrid + + /// + /// Occurs prior to a radial (circular) grid being rendered. + /// + [Description("Occurs prior to a radial (circular) grid being rendered.")] + public event EventHandler PreRenderRadialGrid; + + #endregion + + #region PreRenderSeriesBar + + /// + /// Occurs prior to a series bar being rendered. + /// + [Description("Occurs prior to a series bar being rendered.")] + public event EventHandler PreRenderSeriesBar; + + #endregion + + #region PreRenderSeriesHiLoBar + + /// + /// Occurs prior to a series HiLo Bar segment being rendered. + /// + [Description("Occurs prior to a series HiLo Bar segment being rendered.")] + public event EventHandler PreRenderSeriesHiLoBar; + + #endregion + + #region PreRenderSeriesPoint + + /// + /// Occurs prior to a series point being rendered + /// + [Description("Occurs prior to a series point being rendered.")] + public event EventHandler PreRenderSeriesPoint; + + #endregion + + #region PreRenderSlice + + /// + /// Occurs prior to the pie slice area being rendered. + /// + [Description("Occurs prior to the pie slice area being rendered.")] + public event EventHandler PreRenderSlice; + + #endregion + + #region ReferenceLineMarkupLinkClick + + /// + /// Occurs when a ReferenceLine MarkupLink has been clicked + /// + [Description("Occurs when a ReferenceLine MarkupLink has been clicked.")] + public event EventHandler ReferenceLineMarkupLinkClick; + + #endregion + + #region RenderCrosshairCallout + + /// + /// Occurs when a Crosshair Callout (enclosing "border") needs to be rendered + /// + [Description("Occurs when a Crosshair Callout (enclosing border) needs to be rendered.")] + public event EventHandler RenderCrosshairCallout; + + #endregion + + #region RenderCrosshairLabel + + /// + /// Occurs when a CrosshairLabel needs to be rendered + /// + [Description("Occurs when a CrosshairLabel needs to be rendered.")] + public event EventHandler RenderCrosshairLabel; + + #endregion + + #region RenderCrosshairLabelItem + + /// + /// Occurs when an individual CrosshairLabel item needs to be rendered + /// + [Description("Occurs when an individual CrosshairLabel item needs to be rendered.")] + public event EventHandler RenderCrosshairLabelItem; + + #endregion + + #region RenderPieRingOut + + /// + /// Occurs when the pie center 'ring-out' indicator needs to be rendered. + /// + [Description("Occurs when the pie center 'ring-out' indicator needs to be rendered.")] + public event EventHandler RenderPieRingOut; + + #endregion + + #region RenderSliceCenterLine + + /// + /// Occurs when a pie slice center line needs to be rendered. + /// + [Description("Occurs when a pie slice center line needs to be rendered.")] + public event EventHandler RenderSliceCenterLine; + + #endregion + + #region RenderSliceInnerLabel + + /// + /// Occurs when a slice inner label needs to be rendered. + /// + [Description("Occurs when a slice inner label needs to be rendered.")] + public event EventHandler RenderSliceInnerLabel; + + #endregion + + #region RenderSliceOuterLabel + + /// + /// Occurs when a slice outer label needs to be rendered. + /// + [Description("Occurs when a slice outer label needs to be rendered.")] + public event EventHandler RenderSliceOuterLabel; + + #endregion + + #region Scroll + + /// + /// Occurs when the Horizontal or Vertical scrollbar has been scrolled + /// + [Description("Occurs when the Horizontal or Vertical scrollbar has been scrolled.")] + public event EventHandler Scroll; + + #endregion + + #region ScrollMin + + /// + /// Occurs when the Horizontal or Vertical + /// scrollbar has been scrolled to the Minimum and released + /// + [Description("Occurs when the Horizontal or Vertical scrollbar has been scrolled to the Minimum and released.")] + public event EventHandler ScrollMin; + + #endregion + + #region ScrollMax + + /// + /// Occurs when the Horizontal or Vertical scrollbar has been scrolled to the Maximum and released + /// + [Description("Occurs when the Horizontal or Vertical scrollbar has been scrolled to the Maximum and released.")] + public event EventHandler ScrollMax; + + #endregion + + #region SelectionChanged + + /// + /// Occurs when a visual item's selected state has changed + /// + [Description("Occurs when a visual item's selected state has changed.")] + public event EventHandler SelectionChanged; + + #endregion + + #region SeriesDataBindingComplete + + /// + /// Occurs when a ChartSeries data binding operation is completed + /// + [Description("Occurs when a ChartSeries data binding operation is completed.")] + public event EventHandler SeriesDataBindingComplete; + + #endregion + + #region StyleManagerChanged + + /// + /// Occurs when the StyleManager style has changed + /// + [Description("Occurs when the StyleManager style has changed.")] + public event EventHandler StyleManagerChanged; + + #endregion + + #region TitleMarkupLinkClick + + /// + /// Occurs when a title MarkupLink has been clicked + /// + [Description("Occurs when a title MarkupLink has been clicked.")] + public event EventHandler TitleMarkupLinkClick; + + #endregion + + #endregion + + #region Dll imports + + private const int WmMouseWheel = 0x20a; + + [DllImport("user32.dll")] + private static extern IntPtr WindowFromPoint(Point pt); + + [DllImport("user32.dll")] + private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); + + #endregion + + #region Private variables + + private States _States; + + private ChartPanel _ChartPanel; + + private object _DataSource; + private string _DataMember; + private DataBinder _DataBinder; + + private DefaultVisualStyles _BaseVisualStyles; + private DefaultVisualStyles _DefaultVisualStyles; + + private ushort _BeginUpdateCount; + private ushort _GlobalUpdateCount; + private ushort _BoundsUpdateCount; + + private bool _InUpdateLayout; + private bool _LayoutValid; + private ChartVisualElement _LayoutBoundsItem; + + private Cursor _ChartCursor; + private Cursor _DefaultCursor = Cursors.Default; + private bool _SetChartCursor; + + private ChartVisualElement _CapturedItem; + private ChartVisualElement _MouseOverElement; + + private bool _PostInternalUpdate; + private int _SelectionUpdateCount; + private bool _InPostUpdate; + + private System.Windows.Forms.ToolTip _ToolTip; + private string _ToolTipText; + + #endregion + + /// + /// Initializes a new instance of the ChartControl class. + /// + public ChartControl() + { + SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | + ControlStyles.Opaque | ControlStyles.ResizeRedraw | + ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor, true); + + InitDefaultStates(); + + UpdateChartStyle(); + + if (DesignMode == false) + Application.AddMessageFilter(this); + + StyleManager.Register(this); + } + + #region DefaultSize + + protected override Size DefaultSize + { + get { return new Size(250, 250); } + } + + #endregion + + #region ScaleControl + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + Dpi.SetScaling(factor); + + base.ScaleControl(factor, specified); + } + + #endregion + + #region Scale + + /// + /// Scales the ChartControl based upon the + /// parent form AutoScaleDimensions. + /// + /// + public void Scale(Form form) + { + if (form != null) + { + SizeF factor = new SizeF( + form.AutoScaleDimensions.Width / 96F, + form.AutoScaleDimensions.Height / 96F); + + Scale(factor); + } + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + //SetState(States.AllowEdit, true); + } + + #endregion + + #region Public properties + + #region BaseVisualStyles + + /// + /// BaseVisualStyles - the ChartControl starting base styles + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DefaultVisualStyles BaseVisualStyles + { + get { return (_BaseVisualStyles); } + internal set { _BaseVisualStyles = value; } + } + + #endregion + + #region ChartCursor + + /// + /// Gets or sets the logical Chart cursor + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Cursor ChartCursor + { + get { return (_ChartCursor); } + + set + { + if (value == null || value == Cursors.Default) + _ChartCursor = _DefaultCursor; + else + _ChartCursor = value; + } + } + + #endregion + + #region ChartPanel + + /// + /// Gets or sets the base Chart Panel for the Chart (contains Chart Graphs and additional Chart Panels) + /// + [Category("Appearance")] + [Description("Indicates the base Chart Panel for the Chart (contains Chart Graphs and additional Chart Panels.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartPanel ChartPanel + { + get + { + if (_ChartPanel == null) + { + _ChartPanel = new ChartPanel("PrimaryPanel"); + + _ChartPanel.ChartControl = this; + _ChartPanel.PropertyChanged += ChartPanelPropertyChanged; + } + + return (_ChartPanel); + } + + set + { + if (_ChartPanel != null) + _ChartPanel.PropertyChanged -= ChartPanelPropertyChanged; + + _ChartPanel = value; + + if (value != null) + { + _ChartPanel.ChartControl = this; + _ChartPanel.PropertyChanged += ChartPanelPropertyChanged; + } + + OnPropertyChangedEx("ChartPanel", VisualChangeType.Layout); + + LayoutValid = false; + } + } + + #region ChartPanelPropertyChanged + + void ChartPanelPropertyChanged(object sender, PropertyChangedEventArgs e) + { + } + + #endregion + + #endregion + + #region DataMember + + /// + /// Gets or sets the name of the list or table + /// in the data source that the Chart is bound to. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the list or table in the data source that the Chart is bound to.")] + public string DataMember + { + get { return (_DataMember); } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataMember = value; + + OnPropertyChangedEx("DataMember", VisualChangeType.Layout); + } + } + + #endregion + + #region DataSource + + /// + /// Gets or sets the data source that the Chart is bound to + /// + [DefaultValue(null), AttributeProvider(typeof(IListSource)), Category("Data")] + [Description("Indicates the data source that the Chart is bound to.")] + public object DataSource + { + get { return (_DataSource); } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataSource = value; + + OnPropertyChangedEx("DataSource", VisualChangeType.Layout); + } + } + + #endregion + + #region DefaultVisualStyles + + /// + /// Gets or sets the Default Visual Styles for each Chart element + /// + [Browsable(true), Category("Style")] + [Description("Gets or sets the Default Visual Styles for the each Invalidate element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DefaultVisualStyles DefaultVisualStyles + { + get + { + if (_DefaultVisualStyles == null) + { + _DefaultVisualStyles = new DefaultVisualStyles(); + + DefaultVisualChangeHandler(null, _DefaultVisualStyles); + } + + return (_DefaultVisualStyles); + } + + set + { + if (_DefaultVisualStyles != value) + { + DefaultVisualStyles oldValue = _DefaultVisualStyles; + _DefaultVisualStyles = value; + + OnDefaultVisualStyleChanged(oldValue, value); + } + } + } + + #region OnDefaultVisualStyleChanged + + private void OnDefaultVisualStyleChanged( + DefaultVisualStyles oldValue, DefaultVisualStyles newValue) + { + DefaultVisualChangeHandler(oldValue, newValue); + + OnPropertyChanged("DefaultVisualStyles"); + } + + #endregion + + #region DefaultVisualChangeHandler + + private void DefaultVisualChangeHandler( + DefaultVisualStyles oldValue, DefaultVisualStyles newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= DefaultVisualStylesPropertyChanged; + + if (newValue != null) + newValue.PropertyChanged += DefaultVisualStylesPropertyChanged; + } + + #region DefaultVisualStylesPropertyChanged + + void DefaultVisualStylesPropertyChanged(object sender, PropertyChangedEventArgs e) + { + GlobalUpdateCount++; + + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + if (changeType == VisualChangeType.Layout) + ChartPanel.InvalidateLayout(); + else + ChartPanel.InvalidateRender(); + } + + #endregion + + #endregion + + #endregion + + #region IsUpdateSuspended + + /// + /// Gets whether Chart updating / rendering is suspended + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsUpdateSuspended + { + get { return (_BeginUpdateCount > 0); } + } + + #endregion + + #region SelectedItems + + /// + /// Gets a list of the currently selected chart items. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public List SelectedItems + { + get + { + List selectedItems = new List(_SelectedItems); + + return (selectedItems); + } + } + + #endregion + + #region ToolTip + + internal System.Windows.Forms.ToolTip ToolTip + { + get + { + if (_ToolTip == null) + _ToolTip = new System.Windows.Forms.ToolTip(); + + return (_ToolTip); + } + } + + #endregion + + #region ToolTipText + + internal string ToolTipText + { + get { return (_ToolTipText); } + + set + { + if (_ToolTipText != value) + { + _ToolTipText = value; + + ToolTip.SetToolTip(this, value); + + ToolTip.Active = + (string.IsNullOrEmpty(value) == false); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region BoundsUpdateCount + + internal ushort BoundsUpdateCount + { + get { return (_BoundsUpdateCount); } + set { _BoundsUpdateCount = value; } + } + + #endregion + + #region CapturedItem + + internal ChartVisualElement CapturedItem + { + get + { + if (Capture == false) + _CapturedItem = null; + + return (_CapturedItem); + } + + set { Capture = ((_CapturedItem = value) != null); } + } + + #endregion + + #region DataBinder + + internal DataBinder DataBinder + { + get { return (_DataBinder); } + set { _DataBinder = value; } + } + + #endregion + + #region DefaultCursor + + internal new Cursor DefaultCursor + { + get { return (_DefaultCursor); } + set { _DefaultCursor = value; } + } + + #endregion + + #region DesignerHosted + + internal bool DesignerHosted + { + get { return (DesignMode); } + } + + #endregion + + #region GlobalUpdateCount + + internal ushort GlobalUpdateCount + { + get { return (_GlobalUpdateCount); } + set { _GlobalUpdateCount = value; } + } + + #endregion + + #region InUpdateLayout + + internal bool InUpdateLayout + { + get { return (_InUpdateLayout); } + } + + #endregion + + #region IsPointLabelUpdateHooked + + internal bool IsPointLabelUpdateHooked + { + get { return (PointLabelUpdate != null); } + } + + #endregion + + #region IsScrollHooked + + internal bool IsScrollHooked + { + get { return (Scroll != null); } + } + + #endregion + + #region LayoutBoundsItem + + internal ChartVisualElement LayoutBoundsItem + { + get { return (_LayoutBoundsItem); } + + set + { + _LayoutBoundsItem = value; + + OnLayoutBoundsInvalid(EventArgs.Empty); + } + } + + #region OnLayoutBoundsInvalid + + /// + /// Raises LayoutBoundsInvalid event. + /// + /// Provides event arguments. + protected virtual void OnLayoutBoundsInvalid(EventArgs e) + { + if (LayoutBoundsInvalid != null) + LayoutBoundsInvalid(this, e); + } + + #endregion + + #endregion + + #region LayoutValid + + internal bool LayoutValid + { + get { return (_LayoutValid); } + set { _LayoutValid = value; } + } + + #endregion + + #region MouseOverElement + + internal ChartVisualElement MouseOverElement + { + get { return (_MouseOverElement); } + set { _MouseOverElement = value; } + } + + #endregion + + #region PostInternalUpdate + + internal bool PostInternalUpdate + { + get { return (_PostInternalUpdate); } + set { _PostInternalUpdate = value; } + } + + #endregion + + #region SelectionUpdateCount + + internal int SelectionUpdateCount + { + get { return (_SelectionUpdateCount); } + set { _SelectionUpdateCount = value; } + } + + #endregion + + #region SetChartCursor + + internal bool SetChartCursor + { + get { return (_SetChartCursor); } + set { _SetChartCursor = value; } + } + + #endregion + + #endregion + + #region Licensing + +#if !TRIAL + private string _LicenseKey = ""; + + [Browsable(false), DefaultValue("")] + public string LicenseKey + { + get { return _LicenseKey; } + + set + { + if (Licensing.ValidateLicenseKey(value) == false) + _LicenseKey = (!Licensing.CheckLicenseKey(value) ? "9dsjkhds7" : value); + } + } +#endif + #endregion + + #region OnEnabledChanged + + /// + /// OnEnabledChanged + /// + /// + protected override void OnEnabledChanged(EventArgs e) + { + base.OnEnabledChanged(e); + + Refresh(); + } + + #endregion + + #region StyleManager support + + #region StyleManagerStyleChanged + + /// + /// Called by StyleManager to notify control that style on + /// manager has changed and that control should refresh its + /// appearance if its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + UpdateChartStyle(); + } + + #endregion + + #region UpdateChartStyle + + private void UpdateChartStyle() + { + ChartControlStyle style = ChartControlStyle.Office2010Blue; + + switch (StyleManager.Style) + { + case eStyle.Office2007VistaGlass: + case eStyle.VisualStudio2010Blue: + case eStyle.Windows7Blue: + case eStyle.Office2007Blue: + case eStyle.Office2010Blue: + style = ChartControlStyle.Office2010Blue; + break; + + case eStyle.Office2007Black: + case eStyle.Office2010Black: + style = ChartControlStyle.Office2010Black; + break; + + case eStyle.Office2007Silver: + case eStyle.Office2010Silver: + style = ChartControlStyle.Office2010Silver; + break; + + case eStyle.Metro: + case eStyle.VisualStudio2012Dark: + case eStyle.VisualStudio2012Light: + style = ChartControlStyle.Metro; + break; + } + + _BaseVisualStyles = VisualStylesTable.GetStyle(style); + + if (IsHandleCreated == true) + { + Invalidate(true); + + if (StyleManagerChanged != null) + StyleManagerChanged(this, new EventArgs()); + } + } + + #endregion + + #endregion + + #region Paint processing + + #region OnPaint + + /// + /// Renders the control. + /// + /// Paint arguments. + protected override void OnPaint(PaintEventArgs e) + { + if (IsUpdateSuspended == false) + { + SmoothingMode sm = e.Graphics.SmoothingMode; + TextRenderingHint th = e.Graphics.TextRenderingHint; + + base.OnPaintBackground(e); + + if (LayoutValid == false || LayoutBoundsItem != null) + UpdateLayout(e.Graphics); + + ChartRenderInfo renderInfo = GetRenderInfo(e); + + PaintControl(renderInfo); + + e.Graphics.SmoothingMode = sm; + e.Graphics.TextRenderingHint = th; + + base.OnPaint(e); + } + } + + #endregion + + #region PaintControl + + private void PaintControl(ChartRenderInfo renderInfo) + { + if (ChartPanel.Visible == true) + ChartPanel.Render(renderInfo); + } + + #endregion + + #region PaintTo + + /// + /// Paints control to canvas. This method might be used for print output. + /// + /// Graphics object to paint control to. + public void PaintTo(Graphics g) + { + PaintTo(g, ClientRectangle); + } + + /// + /// Paints control to canvas. This method might be used for print output. + /// + /// Graphics object to paint control to. + /// Indicates clipping rectangle. + public void PaintTo(Graphics g, Rectangle clipRectangle) + { + SmoothingMode sm = g.SmoothingMode; + TextRenderingHint th = g.TextRenderingHint; + + if (LayoutValid == false || LayoutBoundsItem != null) + UpdateLayout(g); + + ChartRenderInfo renderInfo = GetRenderInfo(g, clipRectangle); + + PaintControl(renderInfo); + + g.SmoothingMode = sm; + g.TextRenderingHint = th; + } + + #endregion + + #endregion + + #region UpdateLayout + + /// + /// OnHandleCreated + /// + /// + protected override void OnHandleCreated(EventArgs e) + { + UpdateLayout(false); + + base.OnHandleCreated(e); + } + + /// + /// Performs Chart layout. + /// + public void UpdateLayout() + { + UpdateLayout(false); + } + + /// + /// Performs Chart layout. + /// + ///Whether to force operation even if layout is valid. + public void UpdateLayout(bool force) + { + if (force == true) + _LayoutValid = false; + + if (_LayoutValid == false || LayoutBoundsItem != null) + { + if (_InUpdateLayout == false) + { + using (Graphics g = CreateGraphics()) + UpdateLayout(g); + } + } + } + + internal ushort LayoutUpdateCount + { + get { return (_LayoutUpdateCount); } + } + + internal ushort _LayoutUpdateCount; + + private void UpdateLayout(Graphics g) + { + if (ChartPanel.Visible == true) + { + if (_InUpdateLayout == false) + { + _InUpdateLayout = true; + + _LayoutUpdateCount++; + + try + { + ChartLayoutInfo layoutInfo = GetLayoutInfo(g); + + if (_LayoutValid == false) + { + ChartPanel.Measure(layoutInfo); + + layoutInfo.ClientBounds.Width = Math.Max(0, layoutInfo.ClientBounds.Width); + layoutInfo.ClientBounds.Height = Math.Max(0, layoutInfo.ClientBounds.Height); + + _LayoutValid = true; + _LayoutBoundsItem = ChartPanel; + + PostInternalMouseMove(); + } + + if (LayoutBoundsItem != null) + { + layoutInfo = GetLayoutInfo(g); + layoutInfo.ScrollOffset = GetScrollOffset(); + + LayoutBoundsItem.Arrange(layoutInfo); + } + + LayoutBoundsItem = null; + } + finally + { + _InUpdateLayout = false; + + // If the user initiated an action during the paint event that + // resulted in a layout change, process it now, as our associated + // invalidation will be eaten by the Windows event system + + if (PostInternalUpdate == true) + { + PostInternalUpdate = false; + + if (_InPostUpdate == false) + { + _InPostUpdate = true; + + _LayoutValid = false; + + UpdateLayout(g); + + _InPostUpdate = false; + } + } + } + } + } + } + + #region GetScrollOffset + + private Point GetScrollOffset() + { + ChartContainer cc = LayoutBoundsItem.ParentChartContainer; + + if (cc != null) + { + Point pt = cc.ScrollOffset; + + if (LayoutBoundsItem is ChartLegend == false) + { + pt.X += cc.HScrollOffset; + pt.Y += cc.VScrollOffset; + } + + return (pt); + } + + return (Point.Empty); + } + + #endregion + + #region GetLayoutInfo + + private ChartLayoutInfo GetLayoutInfo(Graphics g) + { + ChartLayoutInfo layoutInfo = new ChartLayoutInfo(g, ClientRectangle); + + Rectangle r = ClientRectangle; + + layoutInfo.LayoutBounds = ClientRectangle; + + return (layoutInfo); + } + + #endregion + + #region GetRenderInfo + + private ChartRenderInfo GetRenderInfo(PaintEventArgs e) + { + ChartRenderInfo renderInfo = + new ChartRenderInfo(e.Graphics, Rectangle.Ceiling(e.ClipRectangle)); + + return (renderInfo); + } + + private ChartRenderInfo GetRenderInfo(Graphics g, Rectangle clipRectangle) + { + ChartRenderInfo renderInfo = + new ChartRenderInfo(g, Rectangle.Ceiling(clipRectangle)); + + return (renderInfo); + } + + #endregion + + #endregion + + #region DoEvent support + + #region ChartMatrixResizedEvent + + /// + /// Handles invocation of ChartMatrixResized events + /// + internal void DoChartMatrixResizedEvent(ChartPanel chartPanel) + { + if (ChartMatrixResized != null) + { + ChartMatrixResizedEventArgs ev = new + ChartMatrixResizedEventArgs(chartPanel); + + ChartMatrixResized(this, ev); + } + } + + #endregion + + #region ChartTitleMarkupLinkClickEvent + + /// + /// Handles invocation of ChartTitleMarkupLinkClick events + /// + internal void DoChartTitleMarkupLinkClickEvent(ChartNote title, HyperLink hyperLink) + { + if (TitleMarkupLinkClick != null) + { + ChartTitleMarkupLinkClickEventArgs ev = new + ChartTitleMarkupLinkClickEventArgs(title, hyperLink.Name, hyperLink.HRef); + + TitleMarkupLinkClick(this, ev); + } + } + + #endregion + + #region DataBindingStartEvent + + /// + /// Handles invocation of DataBindingStart events + /// + internal bool DoDataBindingStartEvent( + BaseChart chartBase, object source, ref bool autogen) + { + if (DataBindingStart != null) + { + ChartDataBindingStartEventArgs ev = new + ChartDataBindingStartEventArgs(chartBase, source, autogen); + + DataBindingStart(this, ev); + + autogen = ev.AutoGenerateSeries; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region ChartDataBindingCompleteEvent + + /// + /// Handles invocation of ChartDataBindingComplete events + /// + internal void DoChartDataBindingCompleteEvent(BaseChart chartBase, object source) + { + if (ChartDataBindingComplete != null) + { + ChartDataBindingCompleteEventArgs ev = new + ChartDataBindingCompleteEventArgs(chartBase, source); + + ChartDataBindingComplete(this, ev); + } + } + + #endregion + + #region ChartMouseClickEvent + + internal bool DoChartMouseClickEvent(BaseChart baseChart, PieSeriesPoint item, MouseEventArgs e) + { + if (ChartMouseClick != null) + { + ChartMouseClickEventArgs ev = new + ChartMouseClickEventArgs(baseChart, item, e); + + ChartMouseClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region ChartMouseDoubleClickEvent + + /// + /// Handles invocation of ChartMouseDoubleClick events + /// + internal bool DoChartMouseDoubleClickEvent(BaseChart baseChart, + ItemHitArea hitArea, ChartVisualElement hitElement, object hitItem, MouseEventArgs e) + { + if (ChartMouseDoubleClick != null) + { + ChartMouseDoubleClickEventArgs ev = new + ChartMouseDoubleClickEventArgs(baseChart, hitArea, hitElement, hitItem, e); + + ChartMouseDoubleClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region CompareElementsEvent + + /// + /// Handles invocation of CompareElementsEvent events + /// + internal bool DoCompareElementsEvent( + ChartVisualElement chartElement, object a, object b, ref int result) + { + if (CompareElements != null) + { + ChartCompareElementsEventArgs ev = new + ChartCompareElementsEventArgs(chartElement, a, b); + + CompareElements(this, ev); + + result = ev.Result; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region EmptyTextMarkupLinkClickEvent + + /// + /// Handles invocation of EmptyTextMarkupLinkClick events + /// + internal void DoEmptyTextMarkupLinkClickEvent(ChartContainer container, HyperLink hyperLink) + { + if (EmptyTextMarkupLinkClick != null) + { + ChartEmptyTextMarkupLinkClickEventArgs ev = new + ChartEmptyTextMarkupLinkClickEventArgs(container, hyperLink.Name, hyperLink.HRef); + + EmptyTextMarkupLinkClick(this, ev); + } + } + + #endregion + + #region GetPieCenterLabelEvent + + internal void DoGetPieCenterLabelEvent(PieChart pieChart, ref string text) + { + if (GetPieCenterLabel != null) + { + GetPieCenterLabelEventArgs ev = new + GetPieCenterLabelEventArgs(pieChart, text); + + GetPieCenterLabel(this, ev); + + text = ev.LabelText; + } + } + + #endregion + + #region GetCrosshairAxisLabelEvent + + internal void DoGetCrosshairAxisLabelEvent( + ChartAxis axis, object value, ref string labelText) + { + if (GetCrosshairAxisLabel != null) + { + GetCrosshairAxisLabelEventArgs ev = new + GetCrosshairAxisLabelEventArgs(axis, value, labelText); + + GetCrosshairAxisLabel(this, ev); + + labelText = ev.LabelText; + } + } + + #endregion + + #region GetCrosshairLabelHeaderEvent + + internal void DoGetCrosshairLabelHeaderEvent( + BaseChart chart, CrosshairPoint cp, List cps, ref string text) + { + if (GetCrosshairLabelHeader != null) + { + GetCrosshairLabelHeaderEventArgs ev = new + GetCrosshairLabelHeaderEventArgs(chart, cp, cps, text); + + GetCrosshairLabelHeader(this, ev); + + text = ev.Text; + } + } + + #endregion + + #region GetCrosshairLabelItemEvent + + internal void DoGetCrosshairLabelItemEvent( + BaseChart chart, CrosshairPoint cp, ref string text) + { + if (GetCrosshairLabelItem != null) + { + GetCrosshairLabelItemEventArgs ev = new + GetCrosshairLabelItemEventArgs(chart, cp, text); + + GetCrosshairLabelItem(this, ev); + + text = ev.Text; + } + } + + #endregion + + #region GetElementStyleEvent + + /// + /// Handles invocation of GetElementStyle events + /// + internal void DoGetElementStyleEvent( + ChartElement chartElement, StyleType styleType, ref BaseVisualStyle style) + { + if (GetElementStyle != null) + { + ChartGetElementStyleEventArgs ev = new + ChartGetElementStyleEventArgs(chartElement, styleType, style); + + GetElementStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetElementStyleEvent + + /// + /// Handles invocation of GetElementStyle events + /// + internal void DoGetPieSeriesPointStyleEvent( + PieSeriesPoint pieSeriesPoint, StyleType styleType, ref BaseVisualStyle style) + { + if (GetPieSeriesPointStyle != null) + { + ChartGetPieSeriesPointStyleEventArgs ev = new + ChartGetPieSeriesPointStyleEventArgs(pieSeriesPoint, styleType, style); + + GetPieSeriesPointStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetSliceLabelEvent + + internal bool DoGetSliceLabelEvent(PieChart pieChart, + PieSeries chartSeries, PieSeriesPoint psp, bool inner, ref string text) + { + if (GetSliceLabel != null) + { + GetSliceLabelEventArgs ev = new + GetSliceLabelEventArgs(pieChart, chartSeries, psp, inner, text); + + GetSliceLabel(this, ev); + + text = ev.Text; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region GetTickmarkLabelEvent + + internal void DoGetTickmarkLabelEvent( + ChartAxis axis, object value, ref string labelText, ref Color labelColor) + { + if (GetTickmarkLabel != null) + { + GetTickmarkLabelEventArgs ev = new + GetTickmarkLabelEventArgs(axis, value, labelText); + + GetTickmarkLabel(this, ev); + + labelText = ev.LabelText; + labelColor = ev.LabelColor; + } + } + + #endregion + + #region GetToolTipEvent + + /// + /// Handles invocation of GetToolTipEvent events + /// + internal bool DoGetToolTipEvent(BaseChart baseChart, + BaseSeries baseSeries, SeriesPoint sp, ref string toolTip) + { + if (GetToolTip != null) + { + GetToolTipEventArgs ev = new + GetToolTipEventArgs(baseChart, baseSeries, sp, toolTip); + + GetToolTip(this, ev); + + toolTip = ev.ToolTip; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region LegendItemCheckedChanged + + /// + /// Handles invocation of LegendItemCheckedChanged events + /// + internal void DoLegendItemCheckedChangedEvent( + ChartLegend legend, ChartLegendItem legendItem) + { + if (LegendItemCheckedChanged != null) + { + LegendItemCheckedChangedEventArgs ev = new + LegendItemCheckedChangedEventArgs(legend, legendItem); + + LegendItemCheckedChanged(this, ev); + } + } + + #endregion + + #region PointLabelUpdateEvent + + /// + /// Handles invocation of PointLabelUpdate events + /// + internal void DoPointLabelUpdateEvent( + BaseChart chart, ChartSeries chartSeries, List pointLabels) + { + if (PointLabelUpdate != null) + { + ChartPointLabelUpdateEventArgs ev = new + ChartPointLabelUpdateEventArgs(chart, chartSeries, pointLabels); + + PointLabelUpdate(this, ev); + } + } + + #endregion + + #region PieCenterMarkupLinkClick Event + + /// + /// Handles invocation of PieCenterMarkupLinkClick events + /// + internal void DoPieCenterMarkupLinkClickEvent( + PieChart pieChart, HyperLink hyperLink) + { + if (PieCenterMarkupLinkClick != null) + { + PieCenterMarkupLinkClickEventArgs ev = new PieCenterMarkupLinkClickEventArgs( + pieChart, hyperLink.Name, hyperLink.HRef); + + PieCenterMarkupLinkClick(this, ev); + } + } + + #endregion + + #region PieDetachChangedEvent + + internal void DoPieDetachChangedEvent( + PieChart pieChart, PieSeries pieSeries, PieSelectionMode psm) + { + if (PieDetachChanged != null) + { + PieDetachChangedEventArgs ev = new + PieDetachChangedEventArgs(pieChart, pieSeries, psm); + + PieDetachChanged(this, ev); + } + } + + #endregion + + #region PieExplodeChangedEvent + + internal void DoPieExplodeChangedEvent(PieChart pieChart, PieSeries pieSeries) + { + if (PieExplodeChanged != null) + { + PieExplodeChangedEventArgs ev = new + PieExplodeChangedEventArgs(pieChart, pieSeries); + + PieExplodeChanged(this, ev); + } + } + + #endregion + + #region PieRingLevelChanged + + internal void DoPieRingLevelChangedEvent( + PieChart pieChart, PieSeriesPointCollection spcOld, PieSeriesPointCollection spcNew) + { + if (PieRingLevelChanged != null) + { + PieRingLevelChangedEventArgs ev = new + PieRingLevelChangedEventArgs(pieChart, spcOld, spcNew); + + PieRingLevelChanged(this, ev); + } + } + + #endregion + + #region PieRingLevelChanging + + internal bool DoPieRingLevelChangingEvent( + PieChart pieChart, PieSeriesPointCollection spcOld, PieSeriesPointCollection spcNew) + { + if (PieRingLevelChanging != null) + { + PieRingLevelChangingEventArgs ev = new + PieRingLevelChangingEventArgs(pieChart, spcOld, spcNew); + + PieRingLevelChanging(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PieSelectionChangedEvent + + internal void DoPieSelectionChangedEvent( + PieChart pieChart, PieSeries pieSeries, PieSeriesPoint psp, PieSelectionMode psm) + { + if (PieSelectionChanged != null) + { + PieSelectionChangedEventArgs ev = new + PieSelectionChangedEventArgs(pieChart, pieSeries, psp, psm); + + PieSelectionChanged(this, ev); + } + } + + #endregion + + #region PostLoadLegendDataEvent + + internal void DoPostLoadLegendDataEvent(ChartLegend legend) + { + if (PostLoadLegendData != null) + { + PostLoadLegendDataEventArgs ev = new + PostLoadLegendDataEventArgs(legend); + + PostLoadLegendData(this, ev); + } + } + + #endregion + + #region PostRenderContentBackgroundEvent + + internal void DoPostRenderContentBackgroundEvent(Graphics g, BaseChart chart, Rectangle r) + { + if (PostRenderContentBackground != null) + { + PostRenderContentBackgroundEventArgs ev = new + PostRenderContentBackgroundEventArgs(g, chart, r); + + PostRenderContentBackground(this, ev); + } + } + + #endregion + + #region PostRenderFrameBackgroundEvent + + internal void DoPostRenderFrameBackgroundEvent(Graphics g, BaseChart chart, Rectangle r) + { + if (PostRenderFrameBackground != null) + { + PostRenderFrameBackgroundEventArgs ev = new + PostRenderFrameBackgroundEventArgs(g, chart, r); + + PostRenderFrameBackground(this, ev); + } + } + + #endregion + + #region PostRenderPanelBackgroundEvent + + internal void DoPostRenderPanelBackgroundEvent(Graphics g, ChartPanel panel, Rectangle r) + { + if (PostRenderPanelBackground != null) + { + PostRenderPanelBackgroundEventArgs ev = new + PostRenderPanelBackgroundEventArgs(g, panel, r); + + PostRenderPanelBackground(this, ev); + } + } + + #endregion + + #region PostRenderPieCenterBackgroundEvent + + internal void DoPostRenderPieCenterBackgroundEvent( + Graphics g, PieChart pieChart, Rectangle rc) + { + if (PostRenderPieCenterBackground != null) + { + PostRenderPieCenterBackgroundEventArgs ev = new + PostRenderPieCenterBackgroundEventArgs(g, pieChart, rc); + + PostRenderPieCenterBackground(this, ev); + } + } + + #endregion + + #region PostRenderPieCenterContentEvent + + internal void DoPostRenderPieCenterContentEvent( + Graphics g, PieChart pieChart, Rectangle rt, string centerlabel) + { + if (PostRenderPieCenterContent != null) + { + PostRenderPieCenterContentEventArgs ev = new + PostRenderPieCenterContentEventArgs(g, pieChart, rt, centerlabel); + + PostRenderPieCenterContent(this, ev); + } + } + + #endregion + + #region PostRenderPointConnectorEvent + + internal void DoPostRenderPointConnectorEvent(Graphics g, BaseChart chart, + ChartSeries series, PointLabel pointLabel, bool isCrosshairPt, Point dataPt, Point labelPt) + { + if (PostRenderPointConnector != null) + { + PostRenderPointConnectorEventArgs ev = new + PostRenderPointConnectorEventArgs(g, chart, series, pointLabel, isCrosshairPt, dataPt, labelPt); + + PostRenderPointConnector(this, ev); + } + } + + #endregion + + #region PostRenderPointLabelEvent + + internal void DoPostRenderPointLabelEvent(Graphics g, BaseChart chart, + ChartSeries series, PointLabel pointLabel, bool isCrosshairPt, Rectangle bounds) + { + if (PostRenderPointLabel != null) + { + PostRenderPointLabelEventArgs ev = new + PostRenderPointLabelEventArgs(g, chart, series, pointLabel, isCrosshairPt, bounds); + + PostRenderPointLabel(this, ev); + } + } + + #endregion + + #region PostRenderRadialGridEvent + + internal void DoPostRenderRadialGridEvent(Graphics g, + PieChart pieChart, double outerRadius, double innerRadius, double exp) + { + if (PostRenderRadialGrid != null) + { + PostRenderRadialGridEventArgs ev = new + PostRenderRadialGridEventArgs(g, pieChart, outerRadius, innerRadius, exp); + + PostRenderRadialGrid(this, ev); + } + } + + #endregion + + #region PostRenderSeriesBarEvent + + internal void DoPostRenderSeriesBarEvent(Graphics g, BaseChart chart, + ChartSeries chartSeries, SeriesPoint sp, Rectangle r, Rectangle r2, BarSegment segment) + { + if (PostRenderSeriesBar != null) + { + PostRenderSeriesBarEventArgs ev = new + PostRenderSeriesBarEventArgs(g, chart, chartSeries, sp, r, r2, segment); + + PostRenderSeriesBar(this, ev); + } + } + + #endregion + + #region PostRenderSeriesHiLoBarEvent + + internal void DoPostRenderSeriesHiLoBarEvent(Graphics g, ChartXy chartXy, + ChartSeries chartSeries, HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + if (PostRenderSeriesHiLoBar != null) + { + PostRenderSeriesHiLoBarEventArgs ev = new + PostRenderSeriesHiLoBarEventArgs(g, chartXy, chartSeries, rd, pt1, pt2, segment); + + PostRenderSeriesHiLoBar(this, ev); + } + } + + #endregion + + #region PostRenderSeriesPointEvent + + internal void DoPostRenderSeriesPointEvent(Graphics graphics, BaseChart chart, + ChartSeries chartSeries, SeriesPoint sp, Point pt, Size pointSize, Image marker) + { + if (PostRenderSeriesPoint != null) + { + PostRenderSeriesPointEventArgs ev = new + PostRenderSeriesPointEventArgs(graphics, chart, chartSeries, sp, pt, pointSize, marker); + + PostRenderSeriesPoint(this, ev); + } + } + + #endregion + + #region PostRenderSliceEvent + + internal void DoPostRenderSliceEvent(Graphics g, GraphicsPath path, + PieChart pieChart, PieSeries pieSeries, PieSeriesPoint psp, SliceRenderType rtype) + { + if (PostRenderSlice != null) + { + PostRenderSliceEventArgs ev = new + PostRenderSliceEventArgs(g, path, pieChart, pieSeries, psp, rtype); + + PostRenderSlice(this, ev); + } + } + + #endregion + + #region PreLoadLegendDataEvent + + internal bool DoPreLoadLegendDataEvent(ChartLegend legend) + { + if (PreLoadLegendData != null) + { + PreLoadLegendDataEventArgs ev = new + PreLoadLegendDataEventArgs(legend); + + PreLoadLegendData(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderContentBackgroundEvent + + internal bool DoPreRenderContentBackgroundEvent(Graphics g, BaseChart chart, Rectangle r) + { + if (PreRenderContentBackground != null) + { + PreRenderContentBackgroundEventArgs ev = new + PreRenderContentBackgroundEventArgs(g, chart, r); + + PreRenderContentBackground(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderFrameBackgroundEvent + + internal bool DoPreRenderFrameBackgroundEvent(Graphics g, BaseChart chart, Rectangle r) + { + if (PreRenderFrameBackground != null) + { + PreRenderFrameBackgroundEventArgs ev = new + PreRenderFrameBackgroundEventArgs(g, chart, r); + + PreRenderFrameBackground(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderPanelBackgroundEvent + + internal bool DoPreRenderPanelBackgroundEvent(Graphics g, ChartPanel panel, Rectangle r) + { + if (PreRenderPanelBackground != null) + { + PreRenderPanelBackgroundEventArgs ev = new + PreRenderPanelBackgroundEventArgs(g, panel, r); + + PreRenderPanelBackground(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderPieCenterBackgroundEvent + + internal bool DoPreRenderPieCenterBackgroundEvent( + Graphics g, PieChart pieChart, Rectangle rc) + { + if (PreRenderPieCenterBackground != null) + { + PreRenderPieCenterBackgroundEventArgs ev = new + PreRenderPieCenterBackgroundEventArgs(g, pieChart, rc); + + PreRenderPieCenterBackground(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderPieCenterContentEvent + + internal bool DoPreRenderPieCenterContentEvent( + Graphics g, PieChart pieChart, Rectangle rt, string centerlabel) + { + if (PreRenderPieCenterContent != null) + { + PreRenderPieCenterContentEventArgs ev = new + PreRenderPieCenterContentEventArgs(g, pieChart, rt, centerlabel); + + PreRenderPieCenterContent(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderPointConnectorEvent + + internal bool DoPreRenderPointConnectorEvent(Graphics g, BaseChart chart, + ChartSeries series, PointLabel pointLabel, bool isCrosshairPt, Point dataPt, Point labelPt) + { + if (PreRenderPointConnector != null) + { + PreRenderPointConnectorEventArgs ev = new + PreRenderPointConnectorEventArgs(g, chart, series, pointLabel, isCrosshairPt, dataPt, labelPt); + + PreRenderPointConnector(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderPointLabelEvent + + internal bool DoPreRenderPointLabelEvent(Graphics g, BaseChart chart, + ChartSeries series, PointLabel pointLabel, bool isCrosshairPt, Rectangle bounds) + { + if (PreRenderPointLabel != null) + { + PreRenderPointLabelEventArgs ev = new + PreRenderPointLabelEventArgs(g, chart, series, pointLabel, isCrosshairPt, bounds); + + PreRenderPointLabel(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderRadialGridEvent + + internal bool DoPreRenderRadialGridEvent(Graphics g, + PieChart pieChart, double outerRadius, double innerRadius, double exp) + { + if (PreRenderRadialGrid != null) + { + PreRenderRadialGridEventArgs ev = new + PreRenderRadialGridEventArgs(g, pieChart, outerRadius, innerRadius, exp); + + PreRenderRadialGrid(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderSeriesBarEvent + + internal bool DoPreRenderSeriesBarEvent(Graphics g, BaseChart chart, + ChartSeries chartSeries, SeriesPoint sp, Rectangle r, Rectangle r2, BarSegment segment) + { + if (PreRenderSeriesBar != null) + { + PreRenderSeriesBarEventArgs ev = new + PreRenderSeriesBarEventArgs(g, chart, chartSeries, sp, r, r2, segment); + + PreRenderSeriesBar(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderSeriesHiloBarEvent + + internal bool DoPreRenderSeriesHiloBarEvent(Graphics g, ChartXy chartXy, + ChartSeries chartSeries, HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + if (PreRenderSeriesHiLoBar != null) + { + PreRenderSeriesHiLoBarEventArgs ev = new + PreRenderSeriesHiLoBarEventArgs(g, chartXy, chartSeries, rd, pt1, pt2, segment); + + PreRenderSeriesHiLoBar(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreRenderSeriesPointEvent + + internal bool DoPreRenderSeriesPointEvent(Graphics graphics, BaseChart chart, + ChartSeries chartSeries, SeriesPoint sp, Point pt, Size pointSize, ref Image marker) + { + if (PreRenderSeriesPoint != null) + { + PreRenderSeriesPointEventArgs ev = new + PreRenderSeriesPointEventArgs(graphics, chart, chartSeries, sp, pt, pointSize, marker); + + PreRenderSeriesPoint(this, ev); + + marker = ev.Marker; + + return (ev.Cancel || marker == null); + } + + return (false); + } + + #endregion + + #region PreRenderSliceEvent + + internal bool DoPreRenderSliceEvent(Graphics g, GraphicsPath path, + PieChart pieChart, PieSeries pieSeries, PieSeriesPoint psp, SliceRenderType rtype) + { + if (PreRenderSlice != null) + { + PreRenderSliceEventArgs ev = new + PreRenderSliceEventArgs(g, path, pieChart, pieSeries, psp, rtype); + + PreRenderSlice(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region ReferenceLineMarkupLinkClickEvent + + /// + /// Handles invocation of ReferenceLineMarkupLinkClick events + /// + internal void DoReferenceLineMarkupLinkClickEvent(ReferenceLine line, HyperLink hyperLink) + { + if (ReferenceLineMarkupLinkClick != null) + { + ReferenceLineMarkupLinkClickEventArgs ev = new + ReferenceLineMarkupLinkClickEventArgs(line, hyperLink.Name, hyperLink.HRef); + + ReferenceLineMarkupLinkClick(this, ev); + } + } + + #endregion + + #region RenderCrosshairCalloutEvent + + /// + /// Handles invocation of RenderCrosshairCallout events + /// + internal bool DoRenderCrosshairCalloutEvent(Graphics graphics, + BaseChart chart, Rectangle bounds, Point pt, CrosshairVisualStyle cstyle) + { + if (RenderCrosshairCallout != null) + { + RenderCrosshairCalloutEventArgs ev = new + RenderCrosshairCalloutEventArgs(graphics, chart, bounds, pt, cstyle); + + RenderCrosshairCallout(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RenderCrosshairLabelEvent + + /// + /// Handles invocation of RenderCrosshairLabel events + /// + internal bool DoRenderCrosshairLabelEvent(Graphics graphics, + BaseChart chart, List cps, Rectangle bounds, Point pt) + { + if (RenderCrosshairLabel != null) + { + RenderCrosshairLabelEventArgs ev = new + RenderCrosshairLabelEventArgs(graphics, chart, cps, bounds, pt); + + RenderCrosshairLabel(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RenderCrosshairLabelItemEvent + + /// + /// Handles invocation of RenderCrosshairLabelItem events + /// + internal bool DoRenderCrosshairLabelItemEvent(Graphics graphics, + BaseChart chart, CrosshairPoint cp, Rectangle bounds, CrosshairVisualStyle cstyle) + { + if (RenderCrosshairLabelItem != null) + { + RenderCrosshairLabelItemEventArgs ev = new + RenderCrosshairLabelItemEventArgs(graphics, chart, cp, bounds, cstyle); + + RenderCrosshairLabelItem(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RenderPieRingOutEvent + + internal bool DoRenderPieRingOutEvent(Graphics g, PieChart pieChart, Rectangle r) + { + if (RenderPieRingOut != null) + { + RenderPieRingOutEventArgs ev = new + RenderPieRingOutEventArgs(g, pieChart, r); + + RenderPieRingOut(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RenderSliceCenterLineEvent + + internal bool DoRenderSliceCenterLineEvent(Graphics g, + PieChart pieChart, PieSeriesPoint psp, Point ptInner, Point ptOuter) + { + if (RenderSliceCenterLine != null) + { + RenderSliceCenterLineEventArgs ev = new + RenderSliceCenterLineEventArgs(g, pieChart, psp, ptInner, ptOuter); + + RenderSliceCenterLine(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RenderSliceInnerLabelEvent + + internal bool DoRenderSliceInnerLabelEvent(Graphics g, + PieChart pieChart, PieSeriesPoint psp, string text, ref bool displayed) + { + if (RenderSliceInnerLabel != null) + { + RenderSliceInnerLabelEventArgs ev = new + RenderSliceInnerLabelEventArgs(g, pieChart, psp, text, displayed); + + RenderSliceInnerLabel(this, ev); + + displayed = ev.Displayed; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RenderSliceOuterLabelEvent + + internal bool DoRenderSliceOuterLabelEvent( + Graphics g, PieChart pieChart, PieSeriesPoint psp, PieLabel pl) + { + if (RenderSliceOuterLabel != null) + { + RenderSliceOuterLabelEventArgs ev = new + RenderSliceOuterLabelEventArgs(g, pieChart, psp, pl); + + RenderSliceOuterLabel(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region ScrollEvent + + /// + /// Handles invocation of Scroll events + /// + internal void DoScrollEvent(ChartContainer chartContainer, + ScrollEventArgs args, ScrollBarLite sbar) + { + if (Scroll != null) + { + ChartScrollEventArgs ev = new + ChartScrollEventArgs(chartContainer, args); + + Scroll(this, ev); + } + + if (args.Type == ScrollEventType.EndScroll) + { + if (args.NewValue == 0) + DoScrollMaxEvent(chartContainer, args); + + else if (args.NewValue + sbar.LargeChange >= sbar.Maximum) + DoScrollMaxEvent(chartContainer, args); + } + } + + #endregion + + #region ScrollMinEvent + + /// + /// Handles invocation of ScrollMin events + /// + internal void DoScrollMinEvent(ChartContainer chartContainer, ScrollEventArgs args) + { + if (ScrollMin != null) + { + ChartScrollEventArgs ev = new + ChartScrollEventArgs(chartContainer, args); + + ScrollMin(this, ev); + } + } + + #endregion + + #region ScrollMaxEvent + + /// + /// Handles invocation of ScrollMax events + /// + internal void DoScrollMaxEvent(ChartContainer chartContainer, ScrollEventArgs args) + { + if (ScrollMax != null) + { + ChartScrollEventArgs ev = new + ChartScrollEventArgs(chartContainer, args); + + ScrollMax(this, ev); + } + } + + #endregion + + #region SelectionChanged + + /// + /// Handles invocation of SelectionChanged events + /// + internal void DoSelectionChangedEvent( + ChartVisualElement item, bool oldState, bool newState) + { + if (SelectionChanged != null) + { + SelectionChangedEventArgs ev = new + SelectionChangedEventArgs(item, oldState, newState, _SelectedItems.Count); + + SelectionChanged(this, ev); + } + } + + #endregion + + #region SeriesDataBindingCompleteEvent + + /// + /// Handles invocation of SeriesDataBindingComplete events + /// + internal void DoSeriesDataBindingCompleteEvent(BaseChart chartBase, BaseSeries series, object source) + { + if (SeriesDataBindingComplete != null) + { + SeriesDataBindingCompleteEventArgs ev = new + SeriesDataBindingCompleteEventArgs(chartBase, series, source); + + SeriesDataBindingComplete(this, ev); + } + } + + #endregion + + #endregion + + #region Mouse Support + + #region OnMouseLeave + + /// + /// OnMouseLeave + /// + /// + protected override void OnMouseLeave(EventArgs e) + { + _ChartPanel.InternalMouseLeave(e); + + if (_MouseOverElement != null) + { + _MouseOverElement.InternalMouseLeave(e); + + _MouseOverElement = null; + } + + base.OnMouseLeave(e); + } + + #endregion + + #region OnMouseMove + + /// + /// OnMouseMove + /// + /// + protected override void OnMouseMove(MouseEventArgs e) + { + if (CapturedItem != null) + { + CapturedItem.InternalMouseMove(e); + } + else + { + ChartVisualElement item = _ChartPanel.GetElementAt(e.Location); + + if (item != null) + item.InternalMouseMove(e); + else + _ChartPanel.InternalMouseMove(e); + } + + base.OnMouseMove(e); + + base.Cursor = _ChartCursor; + + if (_ChartPanel.IsDesignerHosted == true) + Cursor = Cursors.Arrow; + } + + #endregion + + #region OnMouseDown + + /// + /// OnMouseDown + /// + /// + protected override void OnMouseDown(MouseEventArgs e) + { + Focus(); + + ChartVisualElement item = _ChartPanel.GetElementAt(e.Location); + + if (item != null) + item.InternalMouseDown(e); + else + _ChartPanel.InternalMouseDown(e); + + base.OnMouseDown(e); + } + + #endregion + + #region OnMouseUp + + /// + /// OnMouseUp + /// + /// + protected override void OnMouseUp(MouseEventArgs e) + { + if (CapturedItem != null) + { + CapturedItem.InternalMouseUp(e); + } + else + { + ChartVisualElement item = _ChartPanel.GetElementAt(e.Location); + + if (item != null) + item.InternalMouseUp(e); + else + _ChartPanel.InternalMouseUp(e); + + } + + base.OnMouseUp(e); + } + + #endregion + + #region OnMouseClick + + /// + /// OnMouseClick + /// + /// + protected override void OnMouseClick(MouseEventArgs e) + { + if (_MouseOverElement == null) + { + ChartVisualElement item = _ChartPanel.GetElementAt(e.Location); + + if (item != null) + item.InternalMouseMove(e); + else + _ChartPanel.InternalMouseMove(e); + } + + if (_MouseOverElement != null) + _MouseOverElement.InternalMouseClick(e); + + base.OnMouseClick(e); + } + + #endregion + + #region OnMouseDoubleClick + + /// + /// OnMouseDoubleClick + /// + /// + protected override void OnMouseDoubleClick(MouseEventArgs e) + { + if (_MouseOverElement == null) + { + ChartVisualElement item = _ChartPanel.GetElementAt(e.Location); + + if (item != null) + item.InternalMouseMove(e); + else + _ChartPanel.InternalMouseMove(e); + } + + if (_MouseOverElement != null) + _MouseOverElement.InternalMouseDoubleClick(e); + + base.OnMouseDoubleClick(e); + } + + #endregion + + #endregion + + #region GetElementAt + + public ChartVisualElement GetElementAt(Point pt) + { + ChartVisualElement item = ChartPanel.GetElementAt(pt); + + return (item ?? ChartPanel); + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData(bool root) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (root == true) + sec.AddStartElement("ChartControl"); + + sec.AddValue("DataMember", DataMember, null); + //sec.AddValue("DataSource", DataSource, null); + + if (_DefaultVisualStyles != null && _DefaultVisualStyles.IsEmpty == false) + sec.AddElement(_DefaultVisualStyles.GetSerialData()); + + sec.AddElement(ChartPanel.GetSerialData("")); + + if (root == true) + sec.AddEndElement("ChartControl"); + + return (sec); + } + + #endregion + + #region PostInternalMouseMove + + internal void PostInternalMouseMove() + { + Point pt = PointToClient(Control.MousePosition); + + if (ClientRectangle.Contains(pt) == true) + Cursor.Position = Cursor.Position; + } + + #endregion + + #region Cursor + + /// + /// Cursor + /// + public override Cursor Cursor + { + get { return (base.Cursor); } + + set + { + base.Cursor = value; + + if (SetChartCursor == true) + ChartCursor = value; + else + DefaultCursor = value; + } + } + + #endregion + + #region OnResize + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + + if (ChartPanel != null) + ChartPanel.InternalOnResize(e); + } + + #endregion + + #region Selection Support + + private List _SelectedItems = new List(); + + public bool GetSelected(ChartContainer item) + { + if (item.ChartControl == null) + throw new Exception("Items must be a member of the ChartControl"); + + return (_SelectedItems.IndexOf(item) >= 0); + } + + public void SetSelected(ChartContainer item, bool select) + { + SetSelectedEx(item, select, true); + } + + #region SetSelectedEx + + internal void SetSelectedEx(ChartContainer item, bool select, bool sendEvent) + { + int index = _SelectedItems.IndexOf(item); + + if (select == false) + { + if (index >= 0) + { + _SelectedItems.RemoveAt(index); + + item.IsSelected = false; + + if (sendEvent == true) + OnSelectionChanged(item, true, false); + } + } + else + { + if (index < 0) + { + _SelectedItems.Add(item); + + item.IsSelected = true; + + if (sendEvent == true) + OnSelectionChanged(item, false, true); + } + } + } + + #region OnSelectionChanged + + private void OnSelectionChanged(ChartContainer item, bool oldState, bool newState) + { + DoSelectionChangedEvent(item, oldState, newState); + } + + #endregion + + #endregion + + #region ClearAllSelected + + /// + /// Clears all selected items + /// + public void ClearAllSelected() + { + for (int i=_SelectedItems.Count - 1; i>=0; i--) + SetSelectedEx(_SelectedItems[i], false, true); + } + + #endregion + + #endregion + + #region Update support + + /// + /// Calling the BeginUpdate routine informs the Chart Control + /// that an extended update phase has begun. The Chart Control + /// will suspend all layout calculations and display updates + /// until the corresponding EndUpdate routine is called. + /// + /// BeginUpdate / EndUpdate can be nested and must be + /// called in pairs every BeginUpdate must have a + /// matching EndUpdate call. + /// + public void BeginUpdate() + { + _BeginUpdateCount++; + } + + /// + /// Calling the EndUpdate routine informs the Chart Control + /// that an extended update phase has ended. + /// + /// BeginUpdate / EndUpdate can be nested and must be + /// called in pairs every EndUpdate must have a + /// matching BeginUpdate call. + /// + public void EndUpdate() + { + if (_BeginUpdateCount > 0) + { + if (--_BeginUpdateCount == 0) + ChartPanel.InvalidateLayout(); + } + } + + #endregion + + #region InvalidateRender + + /// + /// Invalidates render of the chart element. + /// + /// Element to invalidate rendering for. + internal void InvalidateRender(ChartVisualElement chartElement) + { + Rectangle bounds = chartElement.Bounds; + + if (bounds.IsEmpty == false) + Invalidate(bounds, true); + } + + internal void InvalidateRender(Rectangle bounds) + { + Invalidate(bounds, InvokeRequired == false); + } + + #endregion + + #region PreFilterMessage + + public bool PreFilterMessage(ref Message m) + { + if (IsDisposed == true) + return (false); + + if (DesignMode == true || Enabled == false) + return (false); + + if (ContainsFocus == true || m.Msg == WmMouseWheel) + { + if (m.Msg == WmMouseWheel) + { + Point pt = new Point(LoWord(m.LParam), HiWord(m.LParam)); + + IntPtr hWnd = WindowFromPoint(pt); + + if (hWnd != IntPtr.Zero) + { + Control ctl = Control.FromHandle(hWnd); + + if (ctl == this) + { + pt = PointToClient(pt); + + MouseEventArgs e = new + MouseEventArgs(MouseButtons.None, 0, pt.X, pt.Y, HiWord(m.WParam)); + + ChartVisualElement item = _ChartPanel.GetElementAt(pt); + + if (item != null) + item.InternalMouseWheel(e); + else + _ChartPanel.InternalMouseWheel(e); + + return (true); + } + } + } + } + + return (false); + } + + #region HiWord / LoWord + + private int LoWord(int n) + { + return (short)(n & 0xffff); + } + + private int HiWord(int n) + { + return (n >> 0x10); + } + + private int LoWord(IntPtr n) + { + return LoWord((int)((long)n)); + } + + private int HiWord(IntPtr n) + { + return HiWord((int)((long)n)); + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + OnPropertyChanged(s); + + if (changeType == VisualChangeType.Layout) + Invalidate(); + else + Invalidate(); + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler handler = PropertyChanged; + + if (handler != null) + handler(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + #endregion + + #region States + + [Flags] + private enum States : uint + { + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + + #endregion + } + + #region enum + + #region AutoScrollEnable + + [Flags] + internal enum AutoScrollEnable + { + None = 0, + Vertical = (1 << 0), + Horizontal = (1 << 1), + } + + #endregion + + #region SortDirection + + public enum SortDirection + { + None = 0, + Ascending = 1, + Descending = 2, + } + + #endregion + + #endregion + + #region EventArgs + + #region ChartCancelEventArgs + + /// + /// ChartCancelEventArgs + /// + public class ChartCancelEventArgs : ChartEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// ChartCancelEventArgs + /// + ///Associated Chart + public ChartCancelEventArgs(BaseChart chartBase) + : base(chartBase) + { + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the default operation. + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridCompareElementsEventArgs + + /// + /// GridCompareElementsEventArgs + /// + public class ChartCompareElementsEventArgs : CancelEventArgs + { + #region Private variables + + private ChartVisualElement _ChartElement; + + private object _ElementA; + private object _ElementB; + + private int _Result; + + #endregion + + /// + /// ChartCompareElementsEventArgs + /// + /// + /// + /// + public ChartCompareElementsEventArgs( + ChartVisualElement chartElement, object a, object b) + { + _ChartElement = chartElement; + + _ElementA = a; + _ElementB = b; + } + + #region Public properties + + /// + /// Gets the visual ChartElement associated with the sort. + /// + public ChartVisualElement ChartElement + { + get { return (_ChartElement); } + } + + /// + /// Gets the left-hand element of the comparison + /// + public object ElementA + { + get { return (_ElementA); } + } + + /// + /// Gets the right-hand element of the comparison + /// + public object ElementB + { + get { return (_ElementB); } + } + + /// + /// Gets or sets the result of the element compare. + /// -1 = ElementA is less than ElementB + /// 0 = ElementA is equal to ElementB + /// +1 = ElementA is greater than ElementB + /// + public int Result + { + get { return (_Result); } + set { _Result = value; } + } + + #endregion + } + + #endregion + + #region ChartEventArgs + + /// + /// ChartEventArgs + /// + public class ChartEventArgs : EventArgs + { + #region Private variables + + private BaseChart _Chart; + + #endregion + + /// + /// ChartControlEventArgs + /// + ///Associated ChartControl + public ChartEventArgs(BaseChart chart) + { + _Chart = chart; + } + + #region Public properties + + /// + /// Gets the associated Chart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + #endregion + } + + #endregion + + #region ChartDataBindingCompleteEventArgs + + /// + /// ChartDataBindingCompleteEventArgs + /// + public class ChartDataBindingCompleteEventArgs : ChartEventArgs + { + #region Private variables + + private object _Source; + + #endregion + + /// + /// ChartDataBindingCompleteEventArgs + /// + /// + public ChartDataBindingCompleteEventArgs(BaseChart chart, object source) + : base(chart) + { + _Source = source; + } + + #region Public properties + + /// + /// Gets the data source that was bound to. + /// + public object Source + { + get { return (_Source); } + } + + #endregion + } + + #endregion + + #region ChartDataBindingStartEventArgs + + /// + /// ChartDataBindingStartEventArgs + /// + public class ChartDataBindingStartEventArgs : ChartCancelEventArgs + { + #region Private variables + + private bool _AutoGenerateSeries; + private object _Source; + + #endregion + + /// + /// ChartDataBindingStartEventArgs + /// + ///Associated ChartControl + ///Associated ChartPanel + ///The data source being bound to + ///Whether to auto-generate panel series + public ChartDataBindingStartEventArgs( + BaseChart chartBase, object source, bool autoGenerateSeries) + : base(chartBase) + { + _Source = source; + _AutoGenerateSeries = autoGenerateSeries; + } + + #region Public properties + + /// + /// Gets or sets whether to auto-generate + /// the the panel series from the bound data. + /// + public bool AutoGenerateSeries + { + get { return (_AutoGenerateSeries); } + set { _AutoGenerateSeries = value; } + } + + /// + /// Gets the associated data source being bound to. + /// + public object Source + { + get { return (_Source); } + } + + #endregion + } + + #endregion + + #region ChartEmptyTextMarkupLinkClickEventArgs + + /// + /// ChartEmptyTextMarkupLinkClickEventArgs + /// + public class ChartEmptyTextMarkupLinkClickEventArgs : EventArgs + { + #region Private variables + + private string _HRef; + private string _Name; + + private ChartContainer _ChartContainer; + + #endregion + + /// + /// ChartEmptyTextMarkupLinkClickEventArgs + /// + /// + /// + /// + /// + public ChartEmptyTextMarkupLinkClickEventArgs( + ChartContainer chartContainer, string name, string href) + { + _HRef = href; + _Name = name; + + _ChartContainer = chartContainer; + } + + #region Public properties + + /// + /// Gets the associated HyperLink HRef + /// + public string HRef + { + get { return (_HRef); } + } + + /// + /// Gets the associated HyperLink Name + /// + public string Name + { + get { return (_Name); } + } + + /// + /// Gets the associated ChartContainer + /// + public ChartContainer ChartContainer + { + get { return (_ChartContainer); } + } + + #endregion + } + + #endregion + + #region ChartGetElementStyleEventArgs + + /// + /// ChartGetElementStyleEventArgs + /// + public class ChartGetElementStyleEventArgs : EventArgs + { + #region Private variables + + private ChartElement _ChartElement; + private StyleType _StyleType; + private BaseVisualStyle _Style; + + #endregion + + /// + /// ChartGetElementStyleEventArgs + /// + public ChartGetElementStyleEventArgs( + ChartElement chartElement, StyleType styleType, BaseVisualStyle style) + { + _ChartElement = chartElement; + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the ChartElement. + /// + public ChartElement ChartElement + { + get { return (_ChartElement); } + } + + /// + /// Gets the StyleType. + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets the Style. + /// + public BaseVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot be null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region ChartGetPieSeriesPointStyleEventArgs + + /// + /// ChartGetPieSeriesPointStyleEventArgs + /// + public class ChartGetPieSeriesPointStyleEventArgs : EventArgs + { + #region Private variables + + private PieSeriesPoint _PieSeriesPoint; + private StyleType _StyleType; + private BaseVisualStyle _Style; + + #endregion + + /// + /// ChartGetPieSeriesPointStyleEventArgs + /// + /// + /// + /// + public ChartGetPieSeriesPointStyleEventArgs( + PieSeriesPoint pieSeriesPoint, StyleType styleType, BaseVisualStyle style) + { + _PieSeriesPoint = pieSeriesPoint; + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the PieSeriesPoint. + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (_PieSeriesPoint); } + } + + /// + /// Gets the StyleType. + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets the Style. + /// + public BaseVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot be null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region ChartMatrixResizedEventArgs + + /// + /// ChartMatrixResizedEventArgs + /// + public class ChartMatrixResizedEventArgs : EventArgs + { + #region Private variables + + private ChartPanel _ChartPanel; + + #endregion + + /// + /// ChartMatrixResizedEventArgs + /// + /// + public ChartMatrixResizedEventArgs(ChartPanel chartPanel) + { + _ChartPanel = chartPanel; + } + + #region Public properties + + /// + /// Gets the associated ChartPanel + /// + public ChartPanel ChartPanel + { + get { return (_ChartPanel); } + } + + #endregion + } + + #endregion + + #region ChartMouseClickEventArgs + + /// + /// ChartMouseClickEventArgs + /// + public class ChartMouseClickEventArgs : CancelEventArgs + { + #region Private variables + + private BaseChart _BaseChart; + private object _HitItem; + private MouseEventArgs _MouseEventArgs; + + #endregion + + /// + /// ChartMouseClickEventArgs + /// + /// + /// + /// + public ChartMouseClickEventArgs(BaseChart baseChart, object item, MouseEventArgs e) + { + _BaseChart = baseChart; + _HitItem = item; + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart BaseChart + { + get { return (_BaseChart); } + } + + /// + /// Gets the associated hit item. + /// + public object HitItem + { + get { return (_HitItem); } + } + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + #endregion + } + + #endregion + + #region ChartMouseDoubleClickEventArgs + + /// + /// ChartMouseDoubleClickEventArgs + /// + public class ChartMouseDoubleClickEventArgs : CancelEventArgs + { + #region Private variables + + private BaseChart _BaseChart; + private ItemHitArea _HitArea; + private ChartVisualElement _HitElement; + private object _HitItem; + private MouseEventArgs _MouseEventArgs; + + #endregion + + /// + /// ChartMouseDoubleClickEventArgs + /// + /// + /// + /// + /// + public ChartMouseDoubleClickEventArgs(BaseChart baseChart, + ItemHitArea hitArea, ChartVisualElement hitElement, object hitItem, MouseEventArgs e) + { + _BaseChart = baseChart; + + _HitArea = hitArea; + _HitItem = hitItem; + _HitElement = hitElement; + + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart BaseChart + { + get { return (_BaseChart); } + } + + /// + /// Gets the associated hit area. + /// + public ItemHitArea HitArea + { + get { return (_HitArea); } + } + + /// + /// Gets the associated hit item. + /// + public object HitItem + { + get { return (_HitItem); } + } + + /// + /// Gets the associated hit Visual Chart Element. + /// + public ChartVisualElement HitElement + { + get { return (_HitElement); } + } + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + #endregion + } + + #endregion + + #region ChartPanelCancelEventArgs + + /// + /// ChartPanelCancelEventArgs + /// + public class ChartPanelCancelEventArgs : ChartPanelEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// ChartPanelCancelEventArgs + /// + ///Associated ChartControl + ///Associated ChartPanel + public ChartPanelCancelEventArgs(ChartPanel chartPanel) + : base(chartPanel) + { + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the default operation. + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region ChartPanelEventArgs + + /// + /// ChartPanelEventArgs + /// + public class ChartPanelEventArgs : EventArgs + { + #region Private variables + + private ChartPanel _ChartPanel; + + #endregion + + /// + /// ChartPanelEventArgs + /// + ///Associated ChartControl + ///Associated ChartPanel + public ChartPanelEventArgs(ChartPanel chartPanel) + { + _ChartPanel = chartPanel; + } + + #region Public properties + + /// + /// Gets the associated ChartPanel + /// + public ChartPanel ChartPanel + { + get { return (_ChartPanel); } + } + + #endregion + } + + #endregion + + #region ChartPointLabelUpdateEventArgs + + /// + /// ChartPointLabelUpdateEventArgs + /// + public class ChartPointLabelUpdateEventArgs : EventArgs + { + #region Private variables + + private BaseChart _Chart; + private ChartSeries _ChartSeries; + private List _PointLabels; + + #endregion + + /// + /// ChartPointLabelUpdateEventArgs + /// + public ChartPointLabelUpdateEventArgs( + BaseChart chart, ChartSeries chartSeries, List pointLabels) + { + _Chart = chart; + _ChartSeries = chartSeries; + _PointLabels = pointLabels; + } + + #region Public properties + + /// + /// Gets the associated BaseChart. + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries. + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated list of PointLabels. + /// + public List PointLabels + { + get { return (_PointLabels); } + } + + #endregion + } + + #endregion + + #region ChartScrollEventArgs + + /// + /// ChartScrollEventArgs + /// + public class ChartScrollEventArgs : EventArgs + { + #region Private variables + + private ChartContainer _ChartContainer; + private ScrollEventArgs _ScrollEventArgs; + + #endregion + + /// + /// ChartScrollEventArgs + /// + /// + /// + public ChartScrollEventArgs( + ChartContainer chartContainer, ScrollEventArgs scrollEventArgs) + { + _ChartContainer = chartContainer; + _ScrollEventArgs = scrollEventArgs; + } + + #region Public properties + + /// + /// Gets the ChartContainer that was scrolled + /// + public ChartContainer ChartContainer + { + get { return (_ChartContainer); } + } + + /// + /// Gets the scroll event args + /// + public ScrollEventArgs ScrollEventArgs + { + get { return (_ScrollEventArgs); } + } + + #endregion + } + + #endregion + + #region ChartScrollBarValueChangedEventArgs + + /// + /// ChartScrollBarValueChangedEventArgs + /// + public class ChartScrollBarValueChangedEventArgs : EventArgs + { + #region Private variables + + private ChartContainer _ChartContainer; + + private int _OldValue; + private int _NewValue; + + #endregion + + /// + /// ChartScrollBarValueChangedEventArgs + /// + /// + /// + /// + public ChartScrollBarValueChangedEventArgs( + ChartContainer chartContainer, int oldValue, int newValue) + { + _ChartContainer = chartContainer; + + _OldValue = oldValue; + _NewValue = newValue; + } + + #region Public properties + + /// + /// Gets the associated ChartContainer + /// + public ChartContainer ChartContainer + { + get { return (_ChartContainer); } + } + + /// + /// Gets the old scroll Value + /// + public int OldValue + { + get { return (_OldValue); } + } + + /// + /// Gets the new scroll Value + /// + public int NewValue + { + get { return (_NewValue); } + } + + #endregion + } + + #endregion + + #region ChartTitleMarkupLinkClickEventArgs + + /// + /// ChartTitleMarkupLinkClickEventArgs + /// + public class ChartTitleMarkupLinkClickEventArgs : EventArgs + { + #region Private variables + + private string _HRef; + private string _Name; + + private ChartNote _Title; + + #endregion + + /// + /// ChartTitleMarkupLinkClickEventArgs + /// + /// + /// + /// + /// + public ChartTitleMarkupLinkClickEventArgs( + ChartNote title, string name, string href) + { + _HRef = href; + _Name = name; + + _Title = title; + } + + #region Public properties + + /// + /// Gets the associated HyperLink HRef + /// + public string HRef + { + get { return (_HRef); } + } + + /// + /// Gets the associated HyperLink Name + /// + public string Name + { + get { return (_Name); } + } + + /// + /// Gets the associated Title + /// + public ChartNote Title + { + get { return (_Title); } + } + + #endregion + } + + #endregion + + #region GetCrosshairAxisLabelEventArgs + + /// + /// GetCrosshairAxisLabelEventArgs + /// + public class GetCrosshairAxisLabelEventArgs : EventArgs + { + #region Private variables + + private ChartAxis _ChartAxis; + private object _Value; + private string _LabelText; + + #endregion + + /// + /// GetCrosshairAxisLabelEventArgs + /// + /// ChartAxis + /// object + /// string List + public GetCrosshairAxisLabelEventArgs( + ChartAxis axis, object value, string labelText) + { + _ChartAxis = axis; + _Value = value; + _LabelText = labelText; + } + + #region Public properties + + /// + /// Gets the associated ChartAxis + /// + public ChartAxis ChartAxis + { + get { return (_ChartAxis); } + } + + /// + /// Gets the associated ChartXy + /// + public ChartXy ChartXy + { + get { return ((ChartXy)_ChartAxis.Parent); } + } + + /// + /// Gets the associated label Value + /// + public object Value + { + get { return (_Value); } + } + + /// + /// Gets or sets the label Text + /// + public string LabelText + { + get { return (_LabelText); } + set { _LabelText = value; } + } + + #endregion + } + + #endregion + + #region GetCrosshairLabelHeaderEventArgs + + /// + /// GetCrosshairLabelHeaderEventArgs + /// + public class GetCrosshairLabelHeaderEventArgs : EventArgs + { + #region Private variables + + private BaseChart _Chart; + private CrosshairPoint _CrosshairPoint; + private List _CrosshairPoints; + private string _Text; + + #endregion + + /// + /// GetCrosshairLabelHeaderEventArgs + /// + /// BaseChart + /// CrosshairPoint + /// CrosshairPoint List + /// Default header text + public GetCrosshairLabelHeaderEventArgs( + BaseChart chart, CrosshairPoint cp, List cps, string text) + { + _Chart = chart; + _CrosshairPoint = cp; + _CrosshairPoints = cps; + _Text = text; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated CrosshairPoint (for which + /// the header text is defined for) + /// + public CrosshairPoint CrosshairPoint + { + get { return (_CrosshairPoint); } + } + + /// + /// Gets the full list of CrosshairPoints + /// + public List CrosshairPoints + { + get { return (_CrosshairPoints); } + } + + /// + /// Gets or sets the CrosshairPoint header Text + /// + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + } + + #endregion + + #region GetCrosshairLabelItemEventArgs + + /// + /// GetCrosshairLabelItemEventArgs + /// + public class GetCrosshairLabelItemEventArgs : EventArgs + { + #region Private variables + + private BaseChart _Chart; + private CrosshairPoint _CrosshairPoint; + private string _Text; + + #endregion + + /// + /// GetCrosshairLabelItemEventArgs + /// + /// BaseChart + /// CrosshairPoint + /// Item text + public GetCrosshairLabelItemEventArgs( + BaseChart chart, CrosshairPoint cp, string text) + { + _Chart = chart; + _CrosshairPoint = cp; + _Text = text; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated CrosshairPoint + /// + public CrosshairPoint CrosshairPoint + { + get { return (_CrosshairPoint); } + } + + /// + /// Gets or sets the CrosshairPoint item Text + /// + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + } + + #endregion + + #region GetPieCenterLabelEventArgs + + /// + /// GetPieCenterLabelEventArgs + /// + public class GetPieCenterLabelEventArgs : EventArgs + { + #region Private variables + + private PieChart _PieChart; + private string _LabelText; + + #endregion + + /// + /// GetPieCenterLabelEventArgs + /// + /// + /// + public GetPieCenterLabelEventArgs(PieChart pieChart, string text) + { + _PieChart = pieChart; + _LabelText = text; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets or sets the Center Label Text + /// + public string LabelText + { + get { return (_LabelText); } + set { _LabelText = value; } + } + + #endregion + } + + #endregion + + #region GetSliceLabelEventArgs + + /// + /// GetSliceLabelEventArgs + /// + public class GetSliceLabelEventArgs : CancelEventArgs + { + #region Private variables + + private PieChart _Chart; + private PieSeries _ChartSeries; + private PieSeriesPoint _Psp; + private bool _InnerLabel; + private string _Text; + + #endregion + + /// + /// GetSliceLabelEventArgs + /// + /// + /// + /// + /// + /// + /// + public GetSliceLabelEventArgs(PieChart chart, + PieSeries chartSeries, PieSeriesPoint psp, bool inner, string text) + { + _Chart = chart; + _ChartSeries = chartSeries; + _Psp = psp; + _InnerLabel = inner; + _Text = text; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries + /// + public PieSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated PieSeriesPoint + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (_Psp); } + } + + /// + /// Gets whether the request is for the inner + /// or outer label of the slice. + /// + public bool InnerLabel + { + get { return (_InnerLabel); } + } + + /// + /// Gets or sets the label Text + /// + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + } + + #endregion + + #region GetTickmarkLabelEventArgs + + /// + /// GetTickmarkLabelEventArgs + /// + public class GetTickmarkLabelEventArgs : EventArgs + { + #region Private variables + + private ChartAxis _ChartAxis; + private object _Value; + private string _LabelText; + private Color _LabelColor = Color.Empty; + + #endregion + + /// + /// GetTickmarkLabelEventArgs + /// + /// ChartAxis + /// object + /// string List + public GetTickmarkLabelEventArgs( + ChartAxis axis, object value, string labelText) + { + _ChartAxis = axis; + _Value = value; + _LabelText = labelText; + } + + #region Public properties + + /// + /// Gets the associated ChartAxis + /// + public ChartAxis ChartAxis + { + get { return (_ChartAxis); } + } + + /// + /// Gets the associated ChartXy + /// + public ChartXy ChartXy + { + get { return ((ChartXy)_ChartAxis.Parent); } + } + + /// + /// Gets the associated label Value + /// + public object Value + { + get { return (_Value); } + } + + /// + /// Gets or sets the label Text + /// + public string LabelText + { + get { return (_LabelText); } + set { _LabelText = value; } + } + + /// + /// Gets or sets the label Color + /// + public Color LabelColor + { + get { return (_LabelColor); } + set { _LabelColor = value; } + } + + #endregion + } + + #endregion + + #region GetToolTipEventArgs + + /// + /// GetToolTipEventArgs + /// + public class GetToolTipEventArgs : CancelEventArgs + { + #region Private variables + + private BaseChart _BaseChart; + private BaseSeries _BaseSeries; + private SeriesPoint _SeriesPoint; + + private string _ToolTip; + + #endregion + + /// + /// GetToolTipEventArgs + /// + /// + /// + /// + /// + public GetToolTipEventArgs(BaseChart baseChart, + BaseSeries baseSeries, SeriesPoint sp, string toolTip) + { + _BaseChart = baseChart; + _BaseSeries = baseSeries; + _SeriesPoint = sp; + + _ToolTip = toolTip; + } + + #region Public properties + + /// + /// Gets the associated BaseChart. + /// + public BaseChart BaseChart + { + get { return (_BaseChart); } + } + + /// + /// Gets the associated BaseSeries. + /// + public BaseSeries BaseSeries + { + get { return (_BaseSeries); } + } + + /// + /// Gets the associated SeriesPoint. + /// + public SeriesPoint SeriesPoint + { + get { return (_SeriesPoint); } + } + + /// + /// Gets the associated PieChart. + /// + public PieChart PieChart + { + get { return (_BaseChart as PieChart); } + } + + /// + /// Gets the associated PieSeries. + /// + public PieSeries PieSeries + { + get { return (_BaseSeries as PieSeries); } + } + + /// + /// Gets the associated PieSeriesPoint. + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (_SeriesPoint as PieSeriesPoint); } + } + + /// + /// Gets or sets the associated ToolTip text + /// + public string ToolTip + { + get { return (_ToolTip); } + set { _ToolTip = value; } + } + + #endregion + } + + #endregion + + #region LegendItemCheckedChangedEventArgs + + /// + /// LegendItemCheckedChangedEventArgs + /// + public class LegendItemCheckedChangedEventArgs : EventArgs + { + #region Private variables + + private ChartLegend _Legend; + private ChartLegendItem _LegendItem; + + #endregion + + /// + /// LegendItemCheckedChangedEventArgs + /// + ///Associated legend + ///Associated legend item + public LegendItemCheckedChangedEventArgs( + ChartLegend legend, ChartLegendItem legendItem) + { + _Legend = legend; + _LegendItem = legendItem; + } + + #region Public properties + + /// + /// Gets the associated Legend. + /// + public ChartLegend Legend + { + get { return (_Legend); } + } + + /// + /// Gets the associated LegendItem. + /// + public ChartLegendItem LegendItem + { + get { return (_LegendItem); } + } + + #endregion + } + + #endregion + + #region PieCenterMarkupLinkClickEventArgs + + /// + /// PieCenterMarkupLinkClickEventArgs + /// + public class PieCenterMarkupLinkClickEventArgs : EventArgs + { + #region Private variables + + private PieChart _PieChart; + + private string _HRef; + private string _Name; + + #endregion + + /// + /// PieCenterMarkupLinkClickEventArgs + /// + /// + /// + /// + public PieCenterMarkupLinkClickEventArgs(PieChart pieChart, string name, string href) + { + _HRef = href; + _Name = name; + + _PieChart = pieChart; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated HyperLink HRef + /// + public string HRef + { + get { return (_HRef); } + } + + /// + /// Gets the associated HyperLink Name + /// + public string Name + { + get { return (_Name); } + } + + #endregion + } + + #endregion + + #region PieDetachChangedEventArgs + + /// + /// PieDetachChangedEventArgs + /// + public class PieDetachChangedEventArgs : EventArgs + { + #region Private variables + + private PieChart _PieChart; + private PieSeries _PieSeries; + private PieSelectionMode _PieSelectionMode; + + #endregion + + /// + /// PieDetachChangedEventArgs + /// + /// + /// + /// + public PieDetachChangedEventArgs( + PieChart pieChart, PieSeries pieSeries, PieSelectionMode psm) + { + _PieChart = pieChart; + _PieSeries = pieSeries; + + _PieSelectionMode = psm; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated PieSeries. + /// + public PieSeries PieSeries + { + get { return (_PieSeries); } + } + + /// + /// Gets the associated PieSelectionMode. + /// + public PieSelectionMode PieSelectionMode + { + get { return (_PieSelectionMode); } + } + + #endregion + } + + #endregion + + #region PieExplodeChangedEventArgs + + /// + /// PieExplodeChangedEventArgs + /// + public class PieExplodeChangedEventArgs : EventArgs + { + #region Private variables + + private PieChart _PieChart; + private PieSeries _PieSeries; + + #endregion + + /// + /// PieExplodeChangedEventArgs + /// + /// + /// + public PieExplodeChangedEventArgs(PieChart pieChart, PieSeries pieSeries) + { + _PieChart = pieChart; + _PieSeries = pieSeries; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated PieSeries. + /// + public PieSeries PieSeries + { + get { return (_PieSeries); } + } + + #endregion + } + + #endregion + + #region PieRingLevelChangingEventArgs + + /// + /// PieRingLevelChangedEventArgs + /// + public class PieRingLevelChangedEventArgs : EventArgs + { + #region Private variables + + private PieChart _PieChart; + private PieSeriesPointCollection _SpcOld; + private PieSeriesPointCollection _SpcNew; + + #endregion + + /// + /// PieRingLevelChanged + /// + /// + /// + /// + public PieRingLevelChangedEventArgs( + PieChart pieChart, PieSeriesPointCollection spcOld, PieSeriesPointCollection spcNew) + { + _PieChart = pieChart; + + _SpcOld = spcOld; + _SpcNew = spcNew; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the old, post-change PieSeriesPointCollection. + /// + public PieSeriesPointCollection SpcOld + { + get { return (_SpcOld); } + } + + /// + /// Gets the new, post-change PieSeriesPointCollection. + /// + public PieSeriesPointCollection SpcNew + { + get { return (_SpcNew); } + } + + #endregion + } + + #endregion + + #region PieRingLevelChangingEventArgs + + /// + /// PieRingLevelChanging + /// + public class PieRingLevelChangingEventArgs : CancelEventArgs + { + #region Private variables + + private PieChart _PieChart; + private PieSeriesPointCollection _SpcOld; + private PieSeriesPointCollection _SpcNew; + + #endregion + + /// + /// PieRingLevelChangingEventArgs + /// + /// + /// + /// + public PieRingLevelChangingEventArgs( + PieChart pieChart, PieSeriesPointCollection spcOld, PieSeriesPointCollection spcNew) + { + _PieChart = pieChart; + + _SpcOld = spcOld; + _SpcNew = spcNew; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the old, pre-change PieSeriesPointCollection. + /// + public PieSeriesPointCollection SpcOld + { + get { return (_SpcOld); } + } + + /// + /// Gets the new, pre-change PieSeriesPointCollection. + /// + public PieSeriesPointCollection SpcNew + { + get { return (_SpcNew); } + } + + #endregion + } + + #endregion + + #region PieSelectionChangedEventArgs + + /// + /// PieSelectionChangedEventArgs + /// + public class PieSelectionChangedEventArgs : EventArgs + { + #region Private variables + + private PieChart _PieChart; + private PieSeries _PieSeries; + private PieSeriesPoint _PieSeriesPoint; + private PieSelectionMode _PieSelectionMode; + + #endregion + + /// + /// PieSelectionChangedEventArgs + /// + /// + /// + /// + /// + public PieSelectionChangedEventArgs( + PieChart pieChart, PieSeries pieSeries, PieSeriesPoint psp, PieSelectionMode psm) + { + _PieChart = pieChart; + _PieSeries = pieSeries; + + _PieSeriesPoint = psp; + _PieSelectionMode = psm; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated PieSeries. + /// + public PieSeries PieSeries + { + get { return (_PieSeries); } + } + + /// + /// Gets the associated PieSeriesPoint (may not be + /// applicable for the associated PieSelectionMode). + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (_PieSeriesPoint); } + } + + /// + /// Gets the associated PieSelectionMode. + /// + public PieSelectionMode PieSelectionMode + { + get { return (_PieSelectionMode); } + } + + #endregion + } + + #endregion + + #region PostLoadLegendDataEventArgs + + /// + /// PostLoadLegendDataEventArgs + /// + public class PostLoadLegendDataEventArgs : EventArgs + { + #region Private variables + + private ChartLegend _Legend; + private ChartContainer _ChartContainer; + + #endregion + + public PostLoadLegendDataEventArgs(ChartLegend legend) + { + _Legend = legend; + _ChartContainer = legend.ParentChartContainer; + } + + #region Public properties + + /// + /// Gets the associated Legend + /// + public ChartLegend Legend + { + get { return (_Legend); } + } + + /// + /// Gets the Legend's parent ChartContainer + /// + public ChartContainer ChartContainer + { + get { return (_ChartContainer); } + } + + #endregion + } + + #endregion + + #region PostRenderContentBackgroundEventArgs + + /// + /// PostRenderContentBackgroundEventArgs + /// + public class PostRenderContentBackgroundEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _BaseChart; + private Rectangle _Bounds; + + #endregion + + /// + /// PostRenderContentBackgroundEventArgs + /// + /// Graphics + /// BaseChart + /// Bounds + public PostRenderContentBackgroundEventArgs(Graphics g, BaseChart baseChart, Rectangle bounds) + { + _Graphics = g; + _BaseChart = baseChart; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart BaseChart + { + get { return (_BaseChart); } + } + + /// + /// Gets the associated ChartXy + /// + public ChartXy ChartXy + { + get { return (_BaseChart as ChartXy); } + } + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_BaseChart as PieChart); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PostRenderFrameBackgroundEventArgs + + /// + /// PostRenderFrameBackgroundEventArgs + /// + public class PostRenderFrameBackgroundEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _BaseChart; + private Rectangle _Bounds; + + #endregion + + /// + /// PostRenderFrameBackgroundEventArgs + /// + /// Graphics + /// BaseChart + /// Bounds + public PostRenderFrameBackgroundEventArgs(Graphics g, BaseChart baseChart, Rectangle bounds) + { + _Graphics = g; + _BaseChart = baseChart; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart BaseChart + { + get { return (_BaseChart); } + } + + /// + /// Gets the associated ChartXy + /// + public ChartXy ChartXy + { + get { return (_BaseChart as ChartXy); } + } + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_BaseChart as PieChart); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PostRenderPanelBackgroundEventArgs + + /// + /// PostRenderPanelBackgroundEventArgs + /// + public class PostRenderPanelBackgroundEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private ChartPanel _ChartPanel; + private Rectangle _Bounds; + + #endregion + + /// + /// PostRenderPanelBackgroundEventArgs + /// + /// Graphics + /// BaseChart + /// Bounds + public PostRenderPanelBackgroundEventArgs(Graphics g, ChartPanel panel, Rectangle bounds) + { + _Graphics = g; + _ChartPanel = panel; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the associated ChartPanel + /// + public ChartPanel ChartPanel + { + get { return (_ChartPanel); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PostRenderSeriesBarEventArgs + + /// + /// PostRenderSeriesBarEventArgs + /// + public class PostRenderSeriesBarEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private ChartSeries _ChartSeries; + private SeriesPoint _SeriesPoint; + private Rectangle _Bounds; + private Rectangle _ExtendedBounds; + private BarSegment _BarSegment; + + #endregion + + /// + /// PostRenderSeriesBarEventArgs + /// + /// Graphics + /// BaseChart + /// Chart Series + /// SeriesPoint + public PostRenderSeriesBarEventArgs(Graphics graphics, BaseChart chart, + ChartSeries series, SeriesPoint sp, Rectangle r, Rectangle r2, BarSegment segment) + { + _Graphics = graphics; + _Chart = chart; + _ChartSeries = series; + _SeriesPoint = sp; + _Bounds = r; + _ExtendedBounds = r2; + _BarSegment = segment; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounds for the bar segment. + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the associated SeriesPoint + /// + public SeriesPoint SeriesPoint + { + get { return (_SeriesPoint); } + } + + /// + /// Gets the 'extended' rectangle for the bar (calculated based + /// upon the series maximum displayed bar bounds). + /// + public Rectangle ExtendedBounds + { + get { return (_ExtendedBounds); } + } + + /// + /// Gets the associated 'segment' of the bar being rendered. + /// + public BarSegment BarSegment + { + get { return (_BarSegment); } + } + + #endregion + } + + #endregion + + #region PostRenderSeriesHiLoBarEventArgs + + /// + /// PreRenderSeriesHiLoBarEventArgs + /// + public class PostRenderSeriesHiLoBarEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + + private BaseChart _Chart; + private ChartSeries _ChartSeries; + + private HiLoRenderData _RenderData; + private HiLoBarSegment _BarSegment; + + private Point _Pt1; + private Point _Pt2; + + #endregion + + /// + /// PostRenderSeriesHiLoBarEventArgs + /// + /// + /// + /// + /// + /// + /// + /// + public PostRenderSeriesHiLoBarEventArgs(Graphics g, BaseChart chart, + ChartSeries series, HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + _Graphics = g; + + _Chart = chart; + _ChartSeries = series; + + _RenderData = rd; + _BarSegment = segment; + + _Pt1 = pt1; + _Pt2 = pt2; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated HiLo RenderData. + /// + public HiLoRenderData RenderData + { + get { return (_RenderData); } + } + + /// + /// Gets the associated HiLo BarSegment. + /// + public HiLoBarSegment BarSegment + { + get { return (_BarSegment); } + } + + /// + /// Gets the initial segment Point. + /// + public Point Point1 + { + get { return (_Pt1); } + } + + /// + /// Gets the terminal segment Point. + /// + public Point Point2 + { + get { return (_Pt2); } + } + + #endregion + } + + #endregion + + #region PostRenderSliceEventArgs + + /// + /// PostRenderSliceEventArgs + /// + public class PostRenderSliceEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private GraphicsPath _GraphicsPath; + + private PieChart _PieChart; + private PieSeries _PieSeries; + private PieSeriesPoint _PieSeriesPoint; + + private SliceRenderType _SliceRenderType; + + #endregion + + /// + /// PostRenderSliceEventArgs + /// + /// + /// + /// + /// + /// + /// + public PostRenderSliceEventArgs(Graphics g, GraphicsPath path, + PieChart pieChart, PieSeries pieSeries, PieSeriesPoint psp, SliceRenderType rtype) + { + _Graphics = g; + _GraphicsPath = path; + + _PieChart = pieChart; + _PieSeries = pieSeries; + _PieSeriesPoint = psp; + + _SliceRenderType = rtype; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated PieSeries + /// + public PieSeries PieSeries + { + get { return (_PieSeries); } + } + + /// + /// Gets the associated PieSeriesPoint + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (PieSeriesPoint); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the GraphicsPath for the slice. + /// + public GraphicsPath GraphicsPath + { + get { return (_GraphicsPath); } + } + + /// + /// Gets the SliceRenderType - they 'type' of slice element being rendered. + /// + public SliceRenderType SliceRenderType + { + get { return (_SliceRenderType); } + } + + #endregion + } + + #endregion + + #region PostRenderPieCenterBackgroundEventArgs + + /// + /// PostRenderPieCenterBackgroundEventArgs + /// + public class PostRenderPieCenterBackgroundEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private PieChart _PieChart; + private Rectangle _CenterBounds; + + #endregion + + /// + /// PostRenderPieCenterBackgroundEventArgs + /// + /// + /// + /// + public PostRenderPieCenterBackgroundEventArgs( + Graphics g, PieChart pieChart, Rectangle rc) + { + _Graphics = g; + _PieChart = pieChart; + _CenterBounds = rc; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the Pie Center Bounds. + /// + public Rectangle CenterBounds + { + get { return (_CenterBounds); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region PostRenderPieCenterContentEventArgs + + /// + /// PostRenderPieCenterContentEventArgs + /// + public class PostRenderPieCenterContentEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private PieChart _PieChart; + private Rectangle _TextBounds; + private string _CenterLabel; + + #endregion + + /// + /// PostRenderPieCenterContentEventArgs + /// + /// + /// + /// + /// + public PostRenderPieCenterContentEventArgs( + Graphics g, PieChart pieChart, Rectangle rt, string centerlabel) + { + _Graphics = g; + _PieChart = pieChart; + _TextBounds = rt; + _CenterLabel = centerlabel; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the Pie Center Text Bounds. + /// + public Rectangle TextBounds + { + get { return (_TextBounds); } + } + + /// + /// Gets the center text label. + /// + public string CenterLabel + { + get { return (_CenterLabel); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region PostRenderPointConnectorEventArgs + + /// + /// PostRenderPointConnectorEventArgs + /// + public class PostRenderPointConnectorEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private ChartSeries _ChartSeries; + private PointLabel _PointLabel; + private bool _IsCrosshairPoint; + private Point _DataPoint; + private Point _LabelPoint; + + #endregion + + /// + /// PostRenderPointConnectorEventArgs + /// + /// Graphics + /// BaseChart + /// Chart Series + /// PointLabel + /// Is the point a crosshair point + /// Data Point + /// Label Point + public PostRenderPointConnectorEventArgs(Graphics graphics, BaseChart chart, + ChartSeries series, PointLabel pointLabel, bool isCrosshairPt, Point dataPt, Point labelPt) + { + _Graphics = graphics; + _Chart = chart; + _ChartSeries = series; + _PointLabel = pointLabel; + _IsCrosshairPoint = isCrosshairPt; + _DataPoint = dataPt; + _LabelPoint = labelPt; + } + + #region Public properties + + /// + /// Gets the associated BaseChart. + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries. + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object. + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated PointLabel. + /// + public PointLabel PointLabel + { + get { return (_PointLabel); } + } + + /// + /// Gets the whether the point is a Crosshair Point. + /// + public bool IsCrosshairPoint + { + get { return (_IsCrosshairPoint); } + } + + /// + /// Gets the data-side Connector Point. + /// + public Point DataPoint + { + get { return (_DataPoint); } + } + + /// + /// Gets the label-side Connector Point. + /// + public Point LabelPoint + { + get { return (_LabelPoint); } + } + + #endregion + } + + #endregion + + #region PostRenderPointLabelEventArgs + + /// + /// PostRenderPointLabelEventArgs + /// + public class PostRenderPointLabelEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private ChartSeries _ChartSeries; + private PointLabel _PointLabel; + private bool _IsCrosshairPoint; + private Rectangle _Bounds; + + #endregion + + /// + /// PostRenderPointLabelEventArgs + /// + /// Graphics + /// BaseChart + /// Chart Series + /// PointLabel + /// Is the point a crosshair point + /// Display Bounds + public PostRenderPointLabelEventArgs(Graphics graphics, BaseChart chart, + ChartSeries series, PointLabel pointLabel, bool isCrosshairPoint, Rectangle bounds) + { + _Graphics = graphics; + _Chart = chart; + _ChartSeries = series; + _PointLabel = pointLabel; + _IsCrosshairPoint = isCrosshairPoint; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the associated BaseChart. + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries. + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object. + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated PointLabel. + /// + public PointLabel PointLabel + { + get { return (_PointLabel); } + } + + /// + /// Gets the whether the point is a Crosshair Point. + /// + public bool IsCrosshairPoint + { + get { return (_IsCrosshairPoint); } + } + + /// + /// Gets the bounding display rectangle. + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PostRenderRadialGridEventArgs + + /// + /// PostRenderRadialGridEventArgs + /// + public class PostRenderRadialGridEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + + private PieChart _PieChart; + + private double _OuterRadius; + private double _InnerRadius; + private double _ExpDelta; + + #endregion + + /// + /// PostRenderRadialGridEventArgs + /// + /// + /// + /// + /// + /// + public PostRenderRadialGridEventArgs(Graphics graphics, + PieChart pieChart, double outerRadius, double innerRadius, double exp) + { + _Graphics = graphics; + + _PieChart = pieChart; + + _OuterRadius = outerRadius; + _InnerRadius = innerRadius; + _ExpDelta = exp; + } + + #region Public properties + + /// + /// Gets the associated PieChart. + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the inner, bounding radius for the grid. + /// + public double InnerRadius + { + get { return (_InnerRadius); } + } + + /// + /// Gets the outer, bounding radius for the grid. + /// + public double OuterRadius + { + get { return (_OuterRadius); } + } + + /// + /// Gets the expanded/exploded delta for the grid. This is + /// the adjustment needed if the pie has been expanded. If you + /// want to render an expanded grid, then this delta should be + /// added to both the inner and outer radius values. + /// + public double ExpDelta + { + get { return (_ExpDelta); } + } + + /// + /// Gets the associated Graphics object. + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region PostRenderSeriesPointEventArgs + + /// + /// PostRenderSeriesPointEventArgs + /// + public class PostRenderSeriesPointEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private ChartSeries _ChartSeries; + private Point _Point; + private SeriesPoint _SeriesPoint; + private Size _PointSize; + private Image _Marker; + + #endregion + + /// + /// PostRenderSeriesPointEventArgs + /// + /// Graphics + /// BaseChart + /// Chart Series + /// Marker Point (center) + /// SeriesPoint + /// Max marker point size + /// Marker Image + public PostRenderSeriesPointEventArgs(Graphics graphics, + BaseChart chart, ChartSeries series, SeriesPoint sp, Point pt, Size pointSize, Image marker) + { + _Graphics = graphics; + _Chart = chart; + _ChartSeries = series; + _Point = pt; + _SeriesPoint = sp; + _PointSize = pointSize; + _Marker = marker; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the center point for the marker + /// + public Point Point + { + get { return (_Point); } + } + + /// + /// Gets the associated SeriesPoint + /// + public SeriesPoint SeriesPoint + { + get { return (_SeriesPoint); } + } + + /// + /// Gets the max size for the point marker + /// + public Size PointSize + { + get { return (_PointSize); } + } + + /// + /// Gets the associated marker Image + /// + public Image Marker + { + get { return (_Marker); } + } + + #endregion + } + + #endregion + + #region PreLoadLegendDataEventArgs + + /// + /// PreLoadLegendDataEventArgs + /// + public class PreLoadLegendDataEventArgs : CancelEventArgs + { + #region Private variables + + private ChartLegend _Legend; + private ChartContainer _ChartContainer; + + #endregion + + public PreLoadLegendDataEventArgs(ChartLegend legend) + { + _Legend = legend; + _ChartContainer = legend.ParentChartContainer; + } + + #region Public properties + + /// + /// Gets the associated Legend + /// + public ChartLegend Legend + { + get { return (_Legend); } + } + + /// + /// Gets the Legend's parent ChartContainer + /// + public ChartContainer ChartContainer + { + get { return (_ChartContainer); } + } + + #endregion + } + + #endregion + + #region PreRenderContentBackgroundEventArgs + + /// + /// PreRenderContentBackgroundEventArgs + /// + public class PreRenderContentBackgroundEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _BaseChart; + private Rectangle _Bounds; + + #endregion + + /// + /// PreRenderContentBackgroundEventArgs + /// + /// + /// + /// + public PreRenderContentBackgroundEventArgs(Graphics g, BaseChart baseChart, Rectangle r) + { + _Graphics = g; + _BaseChart = baseChart; + _Bounds = r; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart BaseChart + { + get { return (_BaseChart); } + } + + /// + /// Gets the associated ChartXy + /// + public ChartXy ChartXy + { + get { return (_BaseChart as ChartXy); } + } + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_BaseChart as PieChart); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounds for the bar segment. + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PreRenderFrameBackgroundEventArgs + + /// + /// PreRenderFrameBackgroundEventArgs + /// + public class PreRenderFrameBackgroundEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _BaseChart; + private Rectangle _Bounds; + + #endregion + + /// + /// PreRenderFrameBackgroundEventArgs + /// + /// + /// + /// + public PreRenderFrameBackgroundEventArgs(Graphics g, BaseChart baseChart, Rectangle r) + { + _Graphics = g; + _BaseChart = baseChart; + _Bounds = r; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart BaseChart + { + get { return (_BaseChart); } + } + + /// + /// Gets the associated ChartXy + /// + public ChartXy ChartXy + { + get { return (_BaseChart as ChartXy); } + } + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_BaseChart as PieChart); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounds for the bar segment. + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PreRenderPanelBackgroundEventArgs + + /// + /// PreRenderPanelBackgroundEventArgs + /// + public class PreRenderPanelBackgroundEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private ChartPanel _ChartPanel; + private Rectangle _Bounds; + + #endregion + + /// + /// PreRenderPanelBackgroundEventArgs + /// + /// + /// + /// + public PreRenderPanelBackgroundEventArgs(Graphics g, ChartPanel panel, Rectangle r) + { + _Graphics = g; + _ChartPanel = panel; + _Bounds = r; + } + + #region Public properties + + /// + /// Gets the associated ChartPanel + /// + public ChartPanel ChartPanel + { + get { return (_ChartPanel); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounds for the bar segment. + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PreRenderPieCenterBackgroundEventArgs + + /// + /// PreRenderPieCenterBackgroundEventArgs + /// + public class PreRenderPieCenterBackgroundEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private PieChart _PieChart; + private Rectangle _CenterBounds; + + #endregion + + /// + /// PreRenderPieCenterBackgroundEventArgs + /// + /// + /// + /// + public PreRenderPieCenterBackgroundEventArgs( + Graphics g, PieChart pieChart, Rectangle rc) + { + _Graphics = g; + _PieChart = pieChart; + _CenterBounds = rc; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the Pie Center Bounds. + /// + public Rectangle CenterBounds + { + get { return (_CenterBounds); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region PreRenderPieCenterContentEventArgs + + /// + /// PreRenderPieCenterContentEventArgs + /// + public class PreRenderPieCenterContentEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private PieChart _PieChart; + private Rectangle _TextBounds; + private string _CenterLabel; + + #endregion + + /// + /// PreRenderPieCenterContentEventArgs + /// + /// + /// + /// + /// + public PreRenderPieCenterContentEventArgs( + Graphics g, PieChart pieChart, Rectangle rt, string centerlabel) + { + _Graphics = g; + _PieChart = pieChart; + _TextBounds = rt; + _CenterLabel = centerlabel; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the Pie Center Text Bounds. + /// + public Rectangle TextBounds + { + get { return (_TextBounds); } + } + + /// + /// Gets the center text label. + /// + public string CenterLabel + { + get { return (_CenterLabel); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region PreRenderPointConnectorEventArgs + + /// + /// PreRenderPointConnectorEventArgs + /// + public class PreRenderPointConnectorEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private ChartSeries _ChartSeries; + private PointLabel _PointLabel; + private bool _IsCrosshairPoint; + private Point _DataPoint; + private Point _LabelPoint; + + #endregion + + /// + /// PreRenderPointConnectorEventArgs + /// + /// Graphics + /// BaseChart + /// Chart Series + /// PointLabel + /// Is the point a crosshair point + /// Data Point + /// Label Point + public PreRenderPointConnectorEventArgs(Graphics graphics, BaseChart chart, + ChartSeries series, PointLabel pointLabel, bool isCrosshairPt, Point dataPt, Point labelPt) + { + _Graphics = graphics; + _Chart = chart; + _ChartSeries = series; + _PointLabel = pointLabel; + _IsCrosshairPoint = isCrosshairPt; + _DataPoint = dataPt; + _LabelPoint = labelPt; + } + + #region Public properties + + /// + /// Gets the associated BaseChart. + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries. + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object. + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated PointLabel. + /// + public PointLabel PointLabel + { + get { return (_PointLabel); } + } + + /// + /// Gets the whether the point is a Crosshair Point. + /// + public bool IsCrosshairPoint + { + get { return (_IsCrosshairPoint); } + } + + /// + /// Gets the data-side Connector Point. + /// + public Point DataPoint + { + get { return (_DataPoint); } + } + + /// + /// Gets the label-side Connector Point. + /// + public Point LabelPoint + { + get { return (_LabelPoint); } + } + + #endregion + } + + #endregion + + #region PreRenderPointLabelEventArgs + + /// + /// PreRenderPointLabelEventArgs + /// + public class PreRenderPointLabelEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private ChartSeries _ChartSeries; + private PointLabel _PointLabel; + private bool _IsCrosshairPoint; + private Rectangle _Bounds; + + #endregion + + /// + /// PreRenderPointLabelEventArgs + /// + /// Graphics + /// BaseChart + /// Chart Series + /// PointLabel + /// Is the point a crosshair point + /// Display Bounds + public PreRenderPointLabelEventArgs(Graphics graphics, BaseChart chart, + ChartSeries series, PointLabel pointLabel, bool isCrosshairPoint, Rectangle bounds) + { + _Graphics = graphics; + _Chart = chart; + _ChartSeries = series; + _PointLabel = pointLabel; + _IsCrosshairPoint = isCrosshairPoint; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the associated BaseChart. + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries. + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object. + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated PointLabel. + /// + public PointLabel PointLabel + { + get { return (_PointLabel); } + } + + /// + /// Gets the whether the point is a Crosshair Point. + /// + public bool IsCrosshairPoint + { + get { return (_IsCrosshairPoint); } + } + + /// + /// Gets the bounding display rectangle. + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PreRenderRadialGridEventArgs + + /// + /// PreRenderRadialGridEventArgs + /// + public class PreRenderRadialGridEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + + private PieChart _PieChart; + + private double _OuterRadius; + private double _InnerRadius; + private double _ExpDelta; + + #endregion + + /// + /// PreRenderRadialGridEventArgs + /// + /// + /// + /// + /// + /// + public PreRenderRadialGridEventArgs(Graphics graphics, + PieChart pieChart, double outerRadius, double innerRadius, double exp) + { + _Graphics = graphics; + + _PieChart = pieChart; + + _OuterRadius = outerRadius; + _InnerRadius = innerRadius; + _ExpDelta = exp; + } + + #region Public properties + + /// + /// Gets the associated PieChart. + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the inner, bounding radius for the grid. + /// + public double InnerRadius + { + get { return (_InnerRadius); } + } + + /// + /// Gets the outer, bounding radius for the grid. + /// + public double OuterRadius + { + get { return (_OuterRadius); } + } + + /// + /// Gets the expanded/exploded delta for the grid. This is + /// the adjustment needed if the pie has been expanded. If you + /// want to render an expanded grid, then this delta should be + /// added to both the inner and outer radius values. + /// + public double ExpDelta + { + get { return (_ExpDelta); } + } + + /// + /// Gets the associated Graphics object. + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region PreRenderSeriesBarEventArgs + + /// + /// PreRenderSeriesBarEventArgs + /// + public class PreRenderSeriesBarEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private ChartSeries _ChartSeries; + private SeriesPoint _SeriesPoint; + private Rectangle _Bounds; + private Rectangle _FillRangeBounds; + private BarSegment _BarSegment; + + #endregion + + /// + /// PreRenderSeriesBarEventArgs + /// + /// + /// + /// + /// + /// + /// + /// + public PreRenderSeriesBarEventArgs(Graphics graphics, BaseChart chart, + ChartSeries series, SeriesPoint sp, Rectangle r, Rectangle r2, BarSegment segment) + { + _Graphics = graphics; + _Chart = chart; + _ChartSeries = series; + _SeriesPoint = sp; + _Bounds = r; + _FillRangeBounds = r2; + _BarSegment = segment; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounds for the bar segment. + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the 'FillRange' bounds for the bar (See ChartXy.FillRange). + /// + public Rectangle FillRangeBounds + { + get { return (_FillRangeBounds); } + } + + /// + /// Gets the associated SeriesPoint + /// + public SeriesPoint SeriesPoint + { + get { return (_SeriesPoint); } + } + + /// + /// Gets the associated 'segment' of the bar being rendered. + /// + public BarSegment BarSegment + { + get { return (_BarSegment); } + } + + #endregion + } + + #endregion + + #region PreRenderSeriesHiLoBarEventArgs + + /// + /// PreRenderSeriesHiLoBarEventArgs + /// + public class PreRenderSeriesHiLoBarEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + + private BaseChart _Chart; + private ChartSeries _ChartSeries; + + private HiLoRenderData _RenderData; + private HiLoBarSegment _BarSegment; + + private Point _Pt1; + private Point _Pt2; + + #endregion + + /// + /// PreRenderSeriesHiLoBarEventArgs + /// + /// + /// + /// + /// + /// + /// + /// + public PreRenderSeriesHiLoBarEventArgs(Graphics g, BaseChart chart, + ChartSeries series, HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + _Graphics = g; + + _Chart = chart; + _ChartSeries = series; + + _RenderData = rd; + _BarSegment = segment; + + _Pt1 = pt1; + _Pt2 = pt2; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated HiLo RenderData. + /// + public HiLoRenderData RenderData + { + get { return (_RenderData); } + } + + /// + /// Gets the associated HiLo BarSegment. + /// + public HiLoBarSegment BarSegment + { + get { return (_BarSegment); } + } + + /// + /// Gets the initial segment Point. + /// + public Point Point1 + { + get { return (_Pt1); } + } + + /// + /// Gets the terminal segment Point. + /// + public Point Point2 + { + get { return (_Pt2); } + } + + /// + /// Gets the associated SeriesPoint + /// + public SeriesPoint SeriesPoint + { + get { return (_RenderData.Sp); } + } + + /// + /// Gets the associated SeriesPoint index + /// + public int SeriesPointIndex + { + get { return (_RenderData.Index); } + } + + #endregion + } + + #endregion + + #region PreRenderSeriesPointEventArgs + + /// + /// PreRenderSeriesPointEventArgs + /// + public class PreRenderSeriesPointEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private ChartSeries _ChartSeries; + private Point _Point; + private SeriesPoint _SeriesPoint; + private Size _PointSize; + private Image _Marker; + + #endregion + + /// + /// PreRenderSeriesPointEventArgs + /// + /// Graphics + /// BaseChart + /// Chart Series + /// Marker Point (center) + /// SeriesPoint + /// Max marker point size + /// Marker Image + public PreRenderSeriesPointEventArgs(Graphics graphics, + BaseChart chart, ChartSeries series, SeriesPoint sp, Point pt, Size pointSize, Image marker) + { + _Graphics = graphics; + _Chart = chart; + _ChartSeries = series; + _Point = pt; + _SeriesPoint = sp; + _PointSize = pointSize; + _Marker = marker; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated ChartSeries + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the center point for the marker + /// + public Point Point + { + get { return (_Point); } + } + + /// + /// Gets the associated SeriesPoint + /// + public SeriesPoint SeriesPoint + { + get { return (_SeriesPoint); } + } + + /// + /// Gets the max size for the point marker + /// + public Size PointSize + { + get { return (_PointSize); } + } + + /// + /// Gets or sets the associated marker Image + /// + public Image Marker + { + get { return (_Marker); } + set { _Marker = value; } + } + + #endregion + } + + #endregion + + #region PreRenderSliceEventArgs + + /// + /// PreRenderSliceEventArgs + /// + public class PreRenderSliceEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private GraphicsPath _GraphicsPath; + + private PieChart _PieChart; + private PieSeries _PieSeries; + private PieSeriesPoint _PieSeriesPoint; + + private SliceRenderType _SliceRenderType; + + #endregion + + /// + /// PreRenderSliceEventArgs + /// + /// + /// + /// + /// + /// + /// + public PreRenderSliceEventArgs(Graphics g, GraphicsPath path, + PieChart pieChart, PieSeries pieSeries, PieSeriesPoint psp, SliceRenderType rtype) + { + _Graphics = g; + _GraphicsPath = path; + + _PieChart = pieChart; + _PieSeries = pieSeries; + _PieSeriesPoint = psp; + + _SliceRenderType = rtype; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated PieSeries + /// + public PieSeries PieSeries + { + get { return (_PieSeries); } + } + + /// + /// Gets the associated PieSeriesPoint + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (PieSeriesPoint); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the GraphicsPath for the slice. + /// + public GraphicsPath GraphicsPath + { + get { return (_GraphicsPath); } + } + + /// + /// Gets the SliceRenderType - they 'type' of slice element being rendered. + /// + public SliceRenderType SliceRenderType + { + get { return (_SliceRenderType); } + } + + #endregion + } + + #endregion + + #region ReferenceLineMarkupLinkClickEventArgs + + /// + /// ReferenceLineMarkupLinkClickEventArgs + /// + public class ReferenceLineMarkupLinkClickEventArgs : EventArgs + { + #region Private variables + + private string _HRef; + private string _Name; + + private ReferenceLine _ReferenceLine; + + #endregion + + /// + /// ReferenceLineMarkupLinkClickEventArgs + /// + /// + /// + /// + public ReferenceLineMarkupLinkClickEventArgs( + ReferenceLine referenceLine, string name, string href) + { + _HRef = href; + _Name = name; + + _ReferenceLine = referenceLine; + } + + #region Public properties + + /// + /// Gets the associated HyperLink HRef + /// + public string HRef + { + get { return (_HRef); } + } + + /// + /// Gets the associated HyperLink Name + /// + public string Name + { + get { return (_Name); } + } + + /// + /// Gets the associated ReferenceLine + /// + public ReferenceLine ReferenceLine + { + get { return (_ReferenceLine); } + } + + #endregion + } + + #endregion + + #region RenderCrosshairCalloutEventArgs + + /// + /// RenderCrosshairCalloutEventArgs + /// + public class RenderCrosshairCalloutEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private Rectangle _Bounds; + private Point _Point; + private CrosshairVisualStyle _Style; + + #endregion + + /// + /// RenderCrosshairCalloutEventArgs + /// + /// Graphics + /// BaseChart + /// Callout bounds + /// Mouse point + /// Crosshair style + public RenderCrosshairCalloutEventArgs(Graphics graphics, + BaseChart chart, Rectangle bounds, Point pt, CrosshairVisualStyle style) + { + _Graphics = graphics; + _Chart = chart; + _Bounds = bounds; + _Point = pt; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the Crosshair style + /// + public CrosshairVisualStyle Style + { + get { return (_Style); } + } + + /// + /// Gets the bounding chart Rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the associated mouse position + /// + public Point Point + { + get { return (_Point); } + } + + #endregion + } + + #endregion + + #region RenderCrosshairLabelEventArgs + + /// + /// RenderCrosshairLabelEventArgs + /// + public class RenderCrosshairLabelEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private Rectangle _Bounds; + private List _CrosshairPoints; + private Point _Point; + + #endregion + + /// + /// RenderCrosshairLabelEventArgs + /// + /// Graphics + /// BaseChart + /// CrosshairPoint list + /// + /// Mouse Point + public RenderCrosshairLabelEventArgs(Graphics graphics, + BaseChart chart, List cps, Rectangle bounds, Point pt) + { + _Graphics = graphics; + _Chart = chart; + _CrosshairPoints = cps; + _Bounds = bounds; + _Point = pt; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the list of CrosshairPoints + /// + public List CrosshairPoints + { + get { return (_CrosshairPoints); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounding chart Rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the associated mouse position + /// + public Point Point + { + get { return (_Point); } + } + + #endregion + } + + #endregion + + #region RenderCrosshairLabelItemEventArgs + + /// + /// RenderCrosshairLabelItemEventArgs + /// + public class RenderCrosshairLabelItemEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private BaseChart _Chart; + private CrosshairPoint _CrosshairPoint; + private Rectangle _Bounds; + private CrosshairVisualStyle _Style; + + #endregion + + /// + /// RenderCrosshairLabelItemEventArgs + /// + /// Graphics + /// BaseChart + /// CrosshairPoint + /// Bounding rectangle + /// Style + public RenderCrosshairLabelItemEventArgs(Graphics graphics, + BaseChart chart, CrosshairPoint cp, Rectangle bounds, CrosshairVisualStyle style) + { + _Graphics = graphics; + _Chart = chart; + _CrosshairPoint = cp; + _Bounds = bounds; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated BaseChart + /// + public BaseChart Chart + { + get { return (_Chart); } + } + + /// + /// Gets the associated CrosshairPoint + /// + public CrosshairPoint CrosshairPoint + { + get { return (_CrosshairPoint); } + } + + /// + /// Gets the Crosshair style + /// + public CrosshairVisualStyle Style + { + get { return (_Style); } + } + + /// + /// Gets the bounding chart Rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region RenderPieRingOutEventArgs + + /// + /// RenderSliceCenterLineEventArgs + /// + public class RenderPieRingOutEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private PieChart _PieChart; + private Rectangle _RingOutBounds; + + #endregion + + /// + /// RenderPieRingOutEventArgs + /// + /// + /// + /// + public RenderPieRingOutEventArgs(Graphics graphics, PieChart pieChart, Rectangle r) + { + _Graphics = graphics; + + _PieChart = pieChart; + _RingOutBounds = r; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated Ring-Out indicator bounds. + /// + public Rectangle RingOutBounds + { + get { return (_RingOutBounds); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region RenderSliceCenterLineEventArgs + + /// + /// RenderSliceCenterLineEventArgs + /// + public class RenderSliceCenterLineEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private PieChart _PieChart; + private PieSeriesPoint _PieSeriesPoint; + private Point _PtInner; + private Point _PtOuter; + + #endregion + + /// + /// RenderSliceCenterLineEventArgs + /// + /// + /// + /// + /// + /// + public RenderSliceCenterLineEventArgs(Graphics graphics, + PieChart pieChart, PieSeriesPoint psp, Point ptInner, Point ptOuter) + { + _Graphics = graphics; + + _PieChart = pieChart; + _PieSeriesPoint = psp; + + _PtInner = ptInner; + _PtOuter = ptOuter; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated PieSeriesPoint + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (_PieSeriesPoint); } + } + + /// + /// Gets the inner Point for the CenterLine. + /// + public Point PtInner + { + get { return (_PtInner); } + } + + /// + /// Gets the outer Point for the CenterLine. + /// + public Point PtOuter + { + get { return (_PtOuter); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region RenderSliceInnerLabelEventArgs + + /// + /// RenderSliceInnerLabelEventArgs + /// + public class RenderSliceInnerLabelEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private PieChart _PieChart; + private PieSeriesPoint _PieSeriesPoint; + private string _Text; + private bool _Displayed; + + #endregion + + /// + /// RenderSliceInnerLabelEventArgs + /// + /// + /// + /// + /// + /// + public RenderSliceInnerLabelEventArgs(Graphics graphics, + PieChart pieChart, PieSeriesPoint psp, string text, bool displayed) + { + _Graphics = graphics; + + _PieChart = pieChart; + _PieSeriesPoint = psp; + + _Text = text; + _Displayed = displayed; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated PieSeriesPoint + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (_PieSeriesPoint); } + } + + /// + /// Gets the label text. + /// + public string Text + { + get { return (_Text); } + } + + /// + /// Gets or sets whether the label text was displayed. This value + /// will determine whether the lable will be displayed as an outer + /// label when SliceLabelDisplayMode is set to InnerXorOuter. + /// + public bool Displayed + { + get { return (_Displayed); } + set { _Displayed = value; } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region RenderSliceOuterLabelEventArgs + + /// + /// RenderSliceOuterLabelEventArgs + /// + public class RenderSliceOuterLabelEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private PieChart _PieChart; + private PieSeriesPoint _PieSeriesPoint; + private PieLabel _PieLabel; + + #endregion + + /// + /// RenderSliceOuterLabelEventArgs + /// + /// + /// + /// + /// + public RenderSliceOuterLabelEventArgs( + Graphics graphics, PieChart pieChart, PieSeriesPoint psp, PieLabel pl) + { + _Graphics = graphics; + _PieChart = pieChart; + _PieSeriesPoint = psp; + _PieLabel = pl; + } + + #region Public properties + + /// + /// Gets the associated PieChart + /// + public PieChart PieChart + { + get { return (_PieChart); } + } + + /// + /// Gets the associated PieSeriesPoint + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (_PieSeriesPoint); } + } + + /// + /// Gets the PieLabel defining the label. + /// + public PieLabel PieLabel + { + get { return (_PieLabel); } + } + + /// + /// Gets the associated Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region SelectionChangedEventArgs + + /// + /// SelectionChangedEventArgs + /// + public class SelectionChangedEventArgs : EventArgs + { + #region Private variables + + private ChartVisualElement _Item; + + private bool _OldState; + private bool _NewState; + + private int _SelectedCount; + + #endregion + + /// + /// SelectionChangedEventArgs + /// + ///Associated items changing selected state + ///Old selected state + ///New selected state + ///Resultant total selected item count + public SelectionChangedEventArgs( + ChartVisualElement item, bool oldState, bool newState, int selectedCount) + { + _Item = item; + + _OldState = oldState; + _NewState = newState; + + _SelectedCount = selectedCount; + } + + #region Public properties + + /// + /// Gets the associated item. + /// + public ChartVisualElement Item + { + get { return (_Item); } + } + + /// + /// Gets the old / previous selected state. + /// + public bool OldState + { + get { return (_OldState); } + } + + /// + /// Gets the new / current selected state. + /// + public bool NewState + { + get { return (_NewState); } + } + + /// + /// Gets the resultant selected item count. + /// + public int SelectedCount + { + get { return (_SelectedCount); } + } + + #endregion + } + + #endregion + + #region SeriesDataBindingCompleteEventArgs + + /// + /// SeriesDataBindingCompleteEventArgs + /// + public class SeriesDataBindingCompleteEventArgs : EventArgs + { + #region Private variables + + private BaseChart _BaseChart; + private BaseSeries _BaseSeries; + + private object _Source; + + #endregion + + /// + /// SeriesDataBindingCompleteEventArgs + /// + public SeriesDataBindingCompleteEventArgs(BaseChart chart, BaseSeries series, object source) + { + _BaseChart = chart; + _BaseSeries = series; + + _Source = source; + } + + #region Public properties + + /// + /// Gets the associated BaseChart that was bound. + /// + public BaseChart BaseChart + { + get { return (_BaseChart); } + } + + /// + /// Gets the associated Chart that was bound. + /// + public BaseChart Chart + { + get { return (_BaseChart); } + } + + /// + /// Gets the associated ChartXy that was bound. + /// + public ChartXy ChartXy + { + get { return (_BaseChart as ChartXy); } + } + + /// + /// Gets the associated PieChart that was bound. + /// + public PieChart PieChart + { + get { return (_BaseChart as PieChart); } + } + + /// + /// Gets the associated BaseSeries that was bound. + /// + public BaseSeries BaseSeries + { + get { return (_BaseSeries); } + } + + /// + /// Gets the associated ChartSeries that was bound. + /// + public ChartSeries ChartSeries + { + get { return (_BaseSeries as ChartSeries); } + } + + /// + /// Gets the associated PieSeries that was bound. + /// + public PieSeries PieSeries + { + get { return (_BaseSeries as PieSeries); } + } + + /// + /// Gets the data source that was bound to. + /// + public object Source + { + get { return (_Source); } + } + + #endregion + } + + #endregion + + #endregion + + #region Attributes + + /// + /// Attribute to control the visibility of individual fields + /// or properties in an IList data source to the ChartControl. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public class IsVisibleToChartControl : Attribute + { + private bool _Visible; + + /// + /// IsVisibleToChartControl + /// + /// + public IsVisibleToChartControl(bool visible) + { + _Visible = visible; + } + + /// + /// Visible + /// + public bool Visible + { + get { return (_Visible); } + set { _Visible = value; } + } + } + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.ico b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.ico new file mode 100644 index 00000000..9c379579 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.ico differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.png new file mode 100644 index 00000000..c2570cdd Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.snk b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.snk new file mode 100644 index 00000000..644c4bc8 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl.snk differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/Annotation.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/Annotation.cs new file mode 100644 index 00000000..c8859b09 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/Annotation.cs @@ -0,0 +1,226 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using DevComponents.DotNetBar.Charts.Style; +using DevComponents.Charts.TextMarkup; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of ChartAnnotations. + /// + [Editor("DevComponents.ChartControl.Design.AnnotationCollectionEditor, DevComponents.ChartControl.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartAnnotationCollection : CustomNamedCollection + { + } + + public class Annotation : ChartNote + { + #region Private variables + + private States _States; + + private float _ShapeRotation; + + private float _ConnectorRotation; + private float _ConnectorLength; + + private AnnotationVisualStyles _AnnotationVisualStyles; + + #endregion + + #region Public properties + + #region AnnotationVisualStyles + + /// + /// Gets or sets the visual styles for the Annotation. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Annotation.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public AnnotationVisualStyles AnnotationVisualStyles + { + get + { + if (_AnnotationVisualStyles == null) + { + _AnnotationVisualStyles = new AnnotationVisualStyles(); + + StyleVisualChangeHandler(null, _AnnotationVisualStyles); + } + + return (_AnnotationVisualStyles); + } + + set + { + if (_AnnotationVisualStyles != value) + { + AnnotationVisualStyles oldValue = _AnnotationVisualStyles; + + _AnnotationVisualStyles = value; + + OnStyleChanged("AnnotationVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ConnectorLength + + /// + /// Gets or Sets the length of the Annotation Connector. + /// + [Category("Appearance")] + [Description("Indicates the length of the Annotation Connector.")] + public float ConnectorLength + { + get { return (_ConnectorLength); } + + set + { + if (_ConnectorLength != value) + { + _ConnectorLength = value; + + OnPropertyChangedEx("ConnectorLength", VisualChangeType.Render); + } + } + } + + #endregion + + #region ConnectorRotation + + /// + /// Gets or Sets the rotation of the Annotation Connector. + /// + [Category("Appearance")] + [Description("Indicates the rotation of the Annotation Connector.")] + public float ConnectorRotation + { + get { return (_ConnectorRotation); } + + set + { + if (_ConnectorRotation != value) + { + _ConnectorRotation = value; + + OnPropertyChangedEx("ConnectorRotation", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShapeRotation + + /// + /// Gets or Sets the rotation of the Annotation Shape. + /// + [Category("Appearance")] + [Description("Indicates the rotation of the Annotation Shape.")] + public float ShapeRotation + { + get { return (_ShapeRotation); } + + set + { + if (_ShapeRotation != value) + { + _ShapeRotation = value; + + OnPropertyChangedEx("ShapeRotation", VisualChangeType.Render); + } + } + } + + #endregion + + #endregion + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + throw new NotImplementedException(); + } + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + throw new NotImplementedException(); + } + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + throw new NotImplementedException(); + } + + #region Annotation States + + [Flags] + private enum States : uint + { + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + } + + #region enums + + #region AnnotationShape + + public enum AnnotationShape + { + NotSet = 0, + + Ellipse, + Rectangular, + } + + #endregion + + #region ConnectorShape + + public enum ConnectorShape + { + NotSet = 0, + + None, + + Arrow, + Line, + Tail, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/BaseChart.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/BaseChart.cs new file mode 100644 index 00000000..3a240889 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/BaseChart.cs @@ -0,0 +1,1236 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Primitives; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents a base chart. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class BaseChart : ChartContainer + { + #region Static variables + + // DNB base color palettes + + static public Color[] PaletteLight = new Color[] { + ColorFactory.GetColor(136, 189, 230), ColorFactory.GetColor(251, 178, 88), + ColorFactory.GetColor(144, 205, 151), ColorFactory.GetColor(246, 170, 201), + ColorFactory.GetColor(191, 165, 84), ColorFactory.GetColor(188, 153, 199), + ColorFactory.GetColor(237, 221, 70), ColorFactory.GetColor(240, 126, 110), + ColorFactory.GetColor(140, 140, 140), }; + + static public Color[] PaletteMedium = new Color[] { + ColorFactory.GetColor(93, 165, 218), ColorFactory.GetColor(250, 164, 58), + ColorFactory.GetColor(96, 189, 104), ColorFactory.GetColor(241, 124, 176), + ColorFactory.GetColor(178, 145, 47), ColorFactory.GetColor(178, 118, 178), + ColorFactory.GetColor(222, 207, 63), ColorFactory.GetColor(241, 88, 84), + ColorFactory.GetColor(77, 77, 77), }; + + static public Color[] PaletteDark = new Color[] { + ColorFactory.GetColor(38, 93, 171), ColorFactory.GetColor(223, 92, 36), + ColorFactory.GetColor(5, 151, 72), ColorFactory.GetColor(229, 18, 111), + ColorFactory.GetColor(157, 114, 42), ColorFactory.GetColor(123, 58, 150), + ColorFactory.GetColor(199, 180, 46), ColorFactory.GetColor(203, 32, 39), + ColorFactory.GetColor(0, 0, 0), }; + + // Excel 2016 colors palettes + + static public Color[] PaletteColor1 = new Color[] { + ColorFactory.GetColor(79, 129, 189), // Medium Blue + ColorFactory.GetColor(192, 80, 77), // Red + ColorFactory.GetColor(155, 187, 89), // Green + ColorFactory.GetColor(128, 100, 162), // Purple + ColorFactory.GetColor(75, 172, 198), // Light Blue + ColorFactory.GetColor(247, 150, 70), }; // Orange + + static public Color[] PaletteColor2 = new Color[] { + ColorFactory.GetColor(79, 129, 180), // Medium Blue + ColorFactory.GetColor(155, 187, 89), // Green + ColorFactory.GetColor(75, 172, 198), // Light Blue + ColorFactory.GetColor(44, 76, 116), // Dark Blue + ColorFactory.GetColor(95, 117, 48), // Dark Green + ColorFactory.GetColor(39, 106, 124), }; // Dark Cyan + + static public Color[] PaletteColor3 = new Color[] { + ColorFactory.GetColor(192, 80, 77), // Red + ColorFactory.GetColor(128, 100, 162), // Purple + ColorFactory.GetColor(247, 150, 70), // Orange + ColorFactory.GetColor(119, 44, 42), // Dark Red + ColorFactory.GetColor(77, 59, 98), // Dark Purple + ColorFactory.GetColor(182, 87, 8), }; // Dark Orange + + static public Color[] PaletteColor4 = new Color[] { + ColorFactory.GetColor(247, 150, 70), // Orange + ColorFactory.GetColor(75, 172, 198), // Light Blue + ColorFactory.GetColor(128, 100, 162), // Purple + ColorFactory.GetColor(182, 87, 8), // Dark Orange + ColorFactory.GetColor(39, 106, 124), // Dark Cyan + ColorFactory.GetColor(77, 59, 98), }; // Dark Purple + + // Monochrome + + static public Color[] PaletteMonoBlue = new Color[] { + ColorFactory.GetColor(56, 93, 138), ColorFactory.GetColor(66, 109, 161), + ColorFactory.GetColor(75, 123, 180), ColorFactory.GetColor(115, 148, 197), + ColorFactory.GetColor(161, 180, 212), ColorFactory.GetColor(194, 205, 225), }; + + static public Color[] PaletteMonoRed = new Color[] { + ColorFactory.GetColor(140, 56, 54), ColorFactory.GetColor(164, 67, 64), + ColorFactory.GetColor(183, 76, 73), ColorFactory.GetColor(200, 161, 160), + ColorFactory.GetColor(214, 180, 212), ColorFactory.GetColor(226, 194, 194), }; + + static public Color[] PaletteMonoGreen = new Color[] { + ColorFactory.GetColor(113, 137, 63), ColorFactory.GetColor(132, 159, 75), + ColorFactory.GetColor(148, 178, 85), ColorFactory.GetColor(169, 195, 121), + ColorFactory.GetColor(192, 210, 164), ColorFactory.GetColor(213, 224, 196), }; + + static public Color[] PaletteMonoPurple = new Color[] { + ColorFactory.GetColor(92, 71, 118), ColorFactory.GetColor(108, 84, 138), + ColorFactory.GetColor(122, 95, 154), ColorFactory.GetColor(148, 128, 174), + ColorFactory.GetColor(179, 168, 196), ColorFactory.GetColor(205, 198, 215), }; + + static public Color[] PaletteMonoTeal = new Color[] { + ColorFactory.GetColor(53, 125, 145), ColorFactory.GetColor(63, 146, 169), + ColorFactory.GetColor(71, 164, 189), ColorFactory.GetColor(112, 183, 205), + ColorFactory.GetColor(160, 202, 217), ColorFactory.GetColor(193, 219, 229), }; + + static public Color[] PaletteMonoOrange = new Color[] { + ColorFactory.GetColor(182, 109, 49), ColorFactory.GetColor(211, 127, 58), + ColorFactory.GetColor(236, 143, 66), ColorFactory.GetColor(248, 165, 110), + ColorFactory.GetColor(249, 190, 158), ColorFactory.GetColor(251, 211, 193), }; + + static public Color[] PaletteMonoGray = new Color[] { + ColorFactory.GetColor(95, 95, 95), ColorFactory.GetColor(179, 179, 179), + ColorFactory.GetColor(137, 137, 137), ColorFactory.GetColor(33, 33, 33), + ColorFactory.GetColor(218, 218, 218), ColorFactory.GetColor(170, 170, 170), }; + + // Palette groups + + static public Color[][] PaletteGroups = new Color[][] { + PaletteColor1, PaletteColor2, PaletteColor3, PaletteColor4, + + PaletteMonoBlue, PaletteMonoRed, PaletteMonoGreen, + PaletteMonoPurple, PaletteMonoTeal, PaletteMonoOrange, PaletteMonoGray, + + PaletteLight, PaletteMedium, PaletteDark, }; + + #endregion + + #region Private variables + + private States _States; + + private object _DataSource; + private string _DataMember; + private DataBinder _DataBinder; + + private string _DataPropertyNameSeries; + private string _DataPropertyNameX; + private CustomCollection _DataPropertyNamesY; + + private ChartBaseSeriesCollection _BaseSeries; + + private object _BoundSource; + + private List _LegendData; + + private PaletteGroup _PaletteGroup = PaletteGroup.Color1; + private Color[] _CustomPalette; + + private int _SeriesPointCount; + private int _SeriesLayoutCount; + + private SeriesDisplayOrder _SeriesDisplayOrder = SeriesDisplayOrder.NotSet; + + #endregion + + public BaseChart() + { + InitDefaultStates(); + + VScrollBar.Inverted = true; + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.SeriesRangeChanged, true); + } + + #endregion + + #region Public properties + + #region AutoGenSeriesCollection + + /// + /// Gets or sets whether series definitions are automatically generated. + /// from the associated bound data. + /// + [DefaultValue(false), Category("Data")] + [Description("Indicates whether series definitions are automatically generated from the associated bound data.")] + public bool AutoGenSeriesCollection + { + get { return (TestState(States.AutoGenSeriesCollection)); } + + set + { + if (value != AutoGenSeriesCollection) + { + SetState(States.AutoGenSeriesCollection, value); + + OnPropertyChangedEx("AutoGenSeriesCollection", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BaseSeries + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartBaseSeriesCollection BaseSeries + { + get + { + if (_BaseSeries == null) + _BaseSeries = GetBaseSeries(); + + return (_BaseSeries); + } + + set { _BaseSeries = value; } + } + + #endregion + + #region GetBaseSeries + + internal virtual ChartBaseSeriesCollection GetBaseSeries() + { + throw new NotImplementedException(); + } + + #endregion + + #region CustomPalette + + /// + /// Gets or sets the custom palette for the chart. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the custom palette for the chart.")] + public virtual Color[] CustomPalette + { + get { return (_CustomPalette); } + + set + { + _CustomPalette = value; + + OnPropertyChangedEx("CustomPalette", VisualChangeType.Layout); + } + } + + #endregion + + #region DataMember + + /// + /// Gets or sets the name of the list or table + /// in the data source that the Chart is bound to. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the list or table in the data source that the Chart is bound to.")] + public string DataMember + { + get { return (_DataMember); } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataMember = value; + + NeedToUpdateBindings = true; + + OnPropertyChangedEx("DataMember", VisualChangeType.Layout); + } + } + + #endregion + + #region DataSource + + /// + /// Gets or sets the data source that the Chart is bound to + /// + [DefaultValue(null), AttributeProvider(typeof(IListSource)), Category("Data")] + [Description("Indicates the data source that the Chart is bound to.")] + public object DataSource + { + get { return (_DataSource); } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataSource = value; + + NeedToUpdateBindings = true; + + OnPropertyChangedEx("DataSource", VisualChangeType.Layout); + } + } + + #endregion + + #region DataPropertyNameSeries + + /// + /// Gets or sets the default name of the data field to which the Series Name is bound. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the default name of the data field to which the Series Name is bound.")] + public string DataPropertyNameSeries + { + get { return (_DataPropertyNameSeries); } + + set + { + if (value != _DataPropertyNameSeries) + { + _DataPropertyNameSeries = value; + + NeedToUpdateBindings = true; + + InvalidateLayout(); + + OnPropertyChangedEx("DataPropertyNameSeries", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DataPropertyNameX + + /// + /// Gets or sets the default name of the data field to which the X-Axis data is bound. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the default name of the data field to which the X-Axis data is bound.")] + public string DataPropertyNameX + { + get { return (_DataPropertyNameX); } + + set + { + if (value != _DataPropertyNameX) + { + _DataPropertyNameX = value; + + NeedToUpdateBindings = true; + + InvalidateLayout(); + + OnPropertyChangedEx("DataPropertyNameX", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DataPropertyNamesY + + /// + /// Gets or sets the default names of the data fields to which the Y-Axis data is bound. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the default names of the data fields to which the Y-Axis data is bound.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version= 2.0.0.0, Culture=neutral," + + "PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + public CustomCollection DataPropertyNamesY + { + get + { + if (_DataPropertyNamesY == null) + { + _DataPropertyNamesY = new CustomCollection(); + + _DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged; + } + + return (_DataPropertyNamesY); + } + + set + { + if (value != _DataPropertyNamesY) + { + if (_DataPropertyNamesY != null) + { + _DataPropertyNamesY.Clear(); + + _DataPropertyNamesY.CollectionChanged -= DataPropertyNamesY_CollectionChanged; + } + + _DataPropertyNamesY = value; + + if (_DataPropertyNamesY != null) + _DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged; + + OnPropertyChangedEx("DataPropertyNamesY", Style.VisualChangeType.Layout); + } + } + } + + void DataPropertyNamesY_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + NeedToUpdateBindings = true; + + InvalidateLayout(); + } + + #endregion + + #region EnableDiscreteBoundItems + + /// + /// Gets or sets whether discrete bound item suport is enabled. + /// This property permits each List bound item to be a separate object type. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool EnableDiscreteBoundItems + { + get { return (TestState(States.EnableDiscreteBoundItems)); } + + set + { + if (value != EnableDiscreteBoundItems) + { + SetState(States.EnableDiscreteBoundItems, value); + + OnPropertyChangedEx("EnableDiscreteBoundItems", VisualChangeType.Layout); + } + } + } + + #endregion + + #region PaletteGroup + + /// + /// Gets or sets the palette color group to use (Light/Medium/Dark/Color1/MonoBlue/etc). + /// + [DefaultValue(PaletteGroup.Color1), Category("Appearance")] + [Description("Indicates the palette color group to use (Light/Medium/Dark/Color1/MonoBlue/etc.).")] + public virtual PaletteGroup PaletteGroup + { + get { return (_PaletteGroup); } + + set + { + if (value != _PaletteGroup) + { + _PaletteGroup = value; + + OnPropertyChangedEx("PaletteGroup", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ReversePaletteColors + + /// + /// Gets or sets whether default palette colors are utilized in reverse order. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether default palette colors are utilized in reverse order.")] + public virtual bool ReversePaletteColors + { + get { return (TestState(States.ReversePaletteColors)); } + + set + { + if (value != ReversePaletteColors) + { + SetState(States.ReversePaletteColors, value); + + OnPropertyChangedEx("ReversePaletteColors", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SeriesDisplayOrder + + /// + /// Gets or sets the order in which the charts series are displayed. + /// + [DefaultValue(SeriesDisplayOrder.NotSet), Category("Display")] + [Description("Indicates the order in which the charts series are displayed.")] + public SeriesDisplayOrder SeriesDisplayOrder + { + get { return (_SeriesDisplayOrder); } + + set + { + if (value != _SeriesDisplayOrder) + { + _SeriesDisplayOrder = value; + + OnPropertyChangedEx("SeriesDisplayOrder", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SeriesRangeChanged + + /// + /// Signals to the chart that an underlying chart series data has changed. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool SeriesRangeChanged + { + get { return (TestState(States.SeriesRangeChanged)); } + set { SetState(States.SeriesRangeChanged, value); } + } + + #endregion + + #endregion + + #region Internal properties + + #region DataBinder + + internal DataBinder DataBinder + { + get + { + if (_DataBinder == null) + _DataBinder = new DataBinder(this); + + return (_DataBinder); + } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataBinder = value; + } + } + + #endregion + + #region LegendData + + internal List LegendData + { + get { return (_LegendData); } + set { _LegendData = value; } + } + + #endregion + + #region NeedToUpdateBindings + + internal bool NeedToUpdateBindings + { + get { return (TestState(States.NeedToUpdateBindings)); } + set { SetState(States.NeedToUpdateBindings, value); } + } + + #endregion + + #region SeriesLayoutCount + + internal int SeriesLayoutCount + { + get { return (_SeriesLayoutCount); } + set { _SeriesLayoutCount = value; } + } + + #endregion + + #region SeriesPointCount + + internal int SeriesPointCount + { + get { return (_SeriesPointCount); } + set { _SeriesPointCount = value; } + } + + #endregion + + #region VisibleSeriesCount + + internal int VisibleSeriesCount + { + get + { + int count = 0; + + ChartBaseSeriesCollection baseSeries = BaseSeries; + + foreach (BaseSeries series in baseSeries) + { + if (series.Visible == true) + count++; + } + + return (count); + } + } + + #endregion + + #region DisplayedSeriesCount + + internal int DisplayedSeriesCount + { + get + { + int count = 0; + + ChartBaseSeriesCollection baseSeries = BaseSeries; + + foreach (BaseSeries series in baseSeries) + { + if (series.Visible == true) + { + if (Legend.Visible == false || + (series.ShowCheckBoxInLegend == false || series.CheckedInLegend == true)) + { + count++; + } + } + } + + return (count); + } + } + + #endregion + + #endregion + + #region RenderFrameBackground + + protected virtual void RenderFrameBackground( + Graphics g, Rectangle bounds, ContainerVisualStyle cstyle) + { + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderFrameBackgroundEvent(g, this, bounds) == false) + { + cstyle.RenderBackground(g, bounds); + + chartControl.DoPostRenderFrameBackgroundEvent(g, this, bounds); + } + } + + #endregion + + #region UpdateDataBindings + + protected void UpdateDataBindings() + { + if (NeedToUpdateBindings == true) + { + NeedToUpdateBindings = false; + + DataBinder.Clear(); + + object boundSource = null; + + if (DataSource != null) + _BoundSource = DataBinder.DataConnect(DataSource, DataMember); + + if (boundSource != null) + ChartControl.DoChartDataBindingCompleteEvent(this, boundSource); + } + } + + #endregion + + #region FinalizeDataBindings + + protected void FinalizeDataBindings() + { + if (_BoundSource != null) + { + ChartControl.DoChartDataBindingCompleteEvent(this, _BoundSource); + + _BoundSource = null; + } + } + + #endregion + + #region DataCompare + + internal int DataCompare(object value1, object value2) + { + if (value1 == value2) + return (0); + + if (value1 == null) + return (-1); + + if (value2 == null) + return (1); + + if (value1.GetType() == value2.GetType()) + { + IComparable icompa = value1 as IComparable; + + if (icompa == null) + throw new Exception("Values must support IComparable"); + + return (icompa.CompareTo(value2)); + } + + double v1 = Convert.ToDouble(value1); + double v2 = Convert.ToDouble(value2); + + return (v1.CompareTo(v2)); + } + + #endregion + + #region GetAutoGenSeriesType + + internal virtual SeriesType GetAutoGenSeriesType() + { + throw new NotImplementedException(); + } + + #endregion + + #region GetAutoGenSeriesNameCount + + internal virtual int GetAutoGenSeriesNameCount() + { + throw new NotImplementedException(); + } + + #endregion + + #region GetNewSeries + + internal virtual BaseSeries GetNewSeries() + { + throw new NotImplementedException(); + } + + #endregion + + #region AddChartSeries + + internal virtual void AddChartSeries(BaseSeries series) + { + throw new NotImplementedException(); + } + + #endregion + + #region GetPaletteColor + + /// + /// Gets the series default Palette color. + /// + /// + public Color GetPaletteColor(int index) + { + return (GetPaletteColor(index, PaletteGroup)); + } + + /// + /// Gets the series default Palette color from the + /// specified PaletteGroup. + /// + /// + /// + /// + public Color GetPaletteColor(int index, PaletteGroup group) + { + if (group == PaletteGroup.NotSet) + group = PaletteGroup.Color1; + + Color[] palette = (group == PaletteGroup.Custom) + ? CustomPalette : PaletteGroups[(int)group]; + + return (GetPaletteColor(index, palette, ReversePaletteColors)); + } + + internal Color GetPaletteColor( + int index, Color[] palette, bool reversePaletteColors) + { + if (palette == null || palette.Length == 0) + palette = PaletteColor1; + + int n = index % palette.Length; + + if (reversePaletteColors == true) + n = (palette.Length - n - 1); + + index = index % (palette.Length * 3); + + Color color = palette[n]; + + if (color.IsEmpty == false) + { + n = index / palette.Length; + + if (n > 0) + { + int z = (int)(Math.Ceiling(n * .75d)); + + float fn = (float)(z) * .05f; + + if ((n % 2) == 0) + color = ControlPaint.Light(color, fn); + else + color = ControlPaint.Dark(color, fn); + } + } + + return (color); + } + + #endregion + + #region GetShadowBounds + + internal Rectangle GetShadowBounds(Rectangle bounds) + { + bounds.Width -= 3; + bounds.Height -= 3; + + return (bounds); + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + base.ApplyStyles(style); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + ChartBaseSeriesCollection baseSeries = BaseSeries; + + foreach (BaseSeries series in baseSeries) + series.InvalidateStyle(); + } + + #endregion + + #endregion + + #region ILegendData + + #region GetLegendData + + public override List GetLegendData() + { + LegendData = new List(); + + ChartBaseSeriesCollection baseSeries = BaseSeries; + + foreach (BaseSeries series in baseSeries) + { + if (series.Visible == true) + { + List items = series.GetLegendItems(); + + if (items != null && items.Count > 0) + _LegendData.AddRange(items); + } + } + + return (_LegendData); + } + + #endregion + + #endregion + + #region OnSeriesCheckStateChanged + + internal virtual void OnSeriesCheckStateChanged(string property) + { + } + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + BaseChart copy = new BaseChart(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + BaseChart c = copy as BaseChart; + + if (c != null) + { + base.CopyTo(c); + + c.AutoGenSeriesCollection = AutoGenSeriesCollection; + + if (_CustomPalette != null) + { + c.CustomPalette = new Color[CustomPalette.Length]; + + CustomPalette.CopyTo(c.CustomPalette, 0); + } + + c.DataMember = DataMember; + c.DataSource = DataSource; + c.DataPropertyNameSeries = DataPropertyNameSeries; + c.DataPropertyNameX = DataPropertyNameX; + c.DataPropertyNamesY = DataPropertyNamesY; + c.EnableDiscreteBoundItems = EnableDiscreteBoundItems; + + c.PaletteGroup = PaletteGroup; + c.ReversePaletteColors = ReversePaletteColors; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "BaseChart"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AutoGenSeriesCollection", AutoGenSeriesCollection, false); + + if (_CustomPalette != null && _CustomPalette.Length > 0) + { + sec.AddStartElement("CustomPalette count=\"" + _CustomPalette.Length + "\""); + + foreach (Color color in _CustomPalette) + sec.AddValue("PaletteColor", color); + + sec.AddEndElement("CustomPalette"); + } + + sec.AddDataValue("DataSource", DataSource, null); + sec.AddValue("DataMember", DataMember, null); + + sec.AddValue("DataPropertyNameSeries", DataPropertyNameSeries, null); + sec.AddValue("DataPropertyNameX", DataPropertyNameX, null); + + if (_DataPropertyNamesY != null && _DataPropertyNamesY.Count > 0) + { + sec.AddStartElement("DataPropertyNamesYs count=\"" + _DataPropertyNamesY.Count + "\""); + + foreach (string s in _DataPropertyNamesY) + sec.AddValue("DataPropertyNamesY", s); + + sec.AddEndElement("DataPropertyNamesYs"); + } + + sec.AddValue("EnableDiscreteBoundItems", EnableDiscreteBoundItems, false); + + sec.AddValue("PaletteGroup", PaletteGroup, PaletteGroup.Color1); + sec.AddValue("ReversePaletteColors", ReversePaletteColors, false); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AutoGenSeriesCollection": + AutoGenSeriesCollection = bool.Parse(se.StringValue); + break; + + case "DataMember": + DataMember = se.StringValue; + break; + + case "DataSource": + DataSource = se.DataValue; + break; + + case "DataPropertyNameSeries": + DataPropertyNameSeries = se.StringValue; + break; + + case "DataPropertyNameX": + DataPropertyNameX = se.StringValue; + break; + + case "DataPropertyNamesY": + DataPropertyNamesY.Add(se.StringValue); + break; + + case "EnableDiscreteBoundItems": + EnableDiscreteBoundItems = bool.Parse(se.StringValue); + break; + + case "PaletteColor": + CustomPalette[se.ValueIndex] = se.GetValueColor(); + break; + + case "PaletteGroup": + PaletteGroup = (PaletteGroup)se.GetValueEnum(typeof(PaletteGroup)); + break; + + case "ReversePaletteColors": + ReversePaletteColors = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartContainers": + sec.PutSerialData(this); + break; + + case "CustomPalette": + if (se.ArrayCount > 0) + { + CustomPalette = new Color[se.ArrayCount]; + + sec.PutSerialData(this); + } + break; + + case "DataPropertyNamesYs": + if (se.ArrayCount > 0) + { + DataPropertyNamesY = new CustomCollection(se.ArrayCount); + + sec.PutSerialData(this); + } + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + AutoGenSeriesCollection = (1U << 0), + EnableDiscreteBoundItems = (1U << 1), + ReversePaletteColors = (1U << 2), + + //------------ + + SeriesRangeChanged = (1U << 3), + NeedToUpdateBindings = (1U << 4), + IsSelected = (1U << 5), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + base.Dispose(); + } + + #endregion + } + + #region enums + + #region PaletteGroup + + public enum PaletteGroup + { + /// + /// NotSet. + /// + NotSet = -1, + + /// + /// Colorful 'Color1' toned pallete + /// + Color1, + + /// + /// Colorful 'Color2' toned pallete + /// + Color2, + + /// + /// Colorful 'Color3' toned pallete + /// + Color3, + + /// + /// Colorful 'Color4' toned pallete + /// + Color4, + + /// + /// Monochromatic 'Blue' toned pallete + /// + MonoBlue, + + /// + /// Monochromatic 'Red' toned pallete + /// + MonoRed, + + /// + /// Monochromatic 'Green' toned pallete + /// + MonoGreen, + + /// + /// Monochromatic 'Purple' toned pallete + /// + MonoPurple, + + /// + /// Monochromatic 'Teal' toned pallete + /// + MonoTeal, + + /// + /// Monochromatic 'Orange' toned pallete + /// + MonoOrange, + + /// + /// Monochromatic 'Gray' toned pallete + /// + MonoGray, + + /// + /// Colorful 'Light' toned pallete + /// + Light, + + /// + /// Colorful 'Medium' toned pallete + /// + Medium, + + /// + /// Colorful 'Dark' toned pallete + /// + Dark, + + /// + /// Custom pallete (CustomPalette property) + /// + Custom + } + + #endregion + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/BaseSeries.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/BaseSeries.cs new file mode 100644 index 00000000..5a7c6922 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/BaseSeries.cs @@ -0,0 +1,1226 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of BaseSeries. + /// + [Editor("DevComponents.Charts.Design.ChartSeriesCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartBaseSeriesCollection : CustomNamedCollection + { + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("Series")); + } + + #endregion + } + + public class BaseSeries : ChartVisualElement, ILegendItem + { + #region Private variables + + private States _States; + + private SeriesType _SeriesType; + + private int _SeriesId; + private object _SeriesKey; + + private object _DataSource; + private string _DataMember; + private DataBinder _DataBinder; + + private string _DataPropertyNameSeries; + private string _DataPropertyNameX; + private CustomCollection _DataPropertyNamesY; + + private Color _DefaultPaletteColor = Color.Empty; + + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + + private string _LegendText; + private ChartLegendItem _LegendItem; + + private bool _SeriesRangeChanged = true; + private Rectangle _RenderBounds; + + #endregion + + #region Constructors + + public BaseSeries() + : this(null, SeriesType.Point) + { + } + + public BaseSeries(SeriesType seriesType) + : this(null, seriesType) + { + } + + public BaseSeries(string name, SeriesType seriesType) + { + Name = name; + SeriesType = seriesType; + + InitDefaultStates(); + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.ShowInLegend, true); + SetState(States.ShowInParentLegend, true); + SetState(States.ShowCheckBoxInLegend, true); + SetState(States.ShowMarkerInLegend, true); + SetState(States.CheckedInLegend, true); + } + + #endregion + + #region Public properties + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the visual styles for the Legend item. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Legend item.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleVisualChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (_ChartLegendItemVisualStyles != value) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region DataMember + + /// + /// Gets or sets the name of the list or table + /// in the data source that the Series is bound to. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the list or table in the data source that the Series is bound to.")] + public string DataMember + { + get { return (_DataMember); } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataMember = value; + + NeedToUpdateBindings = true; + + OnPropertyChangedEx("DataMember", VisualChangeType.Layout); + } + } + + #endregion + + #region DataPropertyNameSeries + + /// + /// Gets or sets the name of the data field to which the Series Name is bound. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the data field to which the Series Name is bound.")] + public string DataPropertyNameSeries + { + get { return (_DataPropertyNameSeries); } + + set + { + if (value != _DataPropertyNameSeries) + { + _DataPropertyNameSeries = value; + + if (NeedToUpdateBindings == false) + { + NeedToUpdateBindings = true; + + InvalidateLayout(); + } + + OnPropertyChangedEx("DataPropertyNameSeries", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DataPropertyNameX + + /// + /// Gets or sets the name of the data field to which the X-Axis data is bound. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the data field to which the X-Axis data is bound.")] + public string DataPropertyNameX + { + get { return (_DataPropertyNameX); } + + set + { + if (value != _DataPropertyNameX) + { + _DataPropertyNameX = value; + + if (NeedToUpdateBindings == false) + { + NeedToUpdateBindings = true; + + InvalidateLayout(); + } + + OnPropertyChangedEx("DataPropertyNameX", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DataPropertyNamesY + + /// + /// Gets or sets the names of the data fields to which the Y-Axis data is bound. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the names of the data fields to which the Y-Axis data is bound.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CustomCollection DataPropertyNamesY + { + get + { + if (_DataPropertyNamesY == null) + { + _DataPropertyNamesY = new CustomCollection(); + + _DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged; + } + + return (_DataPropertyNamesY); + } + + set + { + if (value != _DataPropertyNamesY) + { + if (_DataPropertyNamesY != null) + { + _DataPropertyNamesY.Clear(); + + _DataPropertyNamesY.CollectionChanged -= DataPropertyNamesY_CollectionChanged; + } + + _DataPropertyNamesY = value; + + if (_DataPropertyNamesY != null) + _DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged; + + OnPropertyChangedEx("DataPropertyNamesY", Style.VisualChangeType.Layout); + } + } + } + + void DataPropertyNamesY_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (NeedToUpdateBindings == false) + { + NeedToUpdateBindings = true; + + InvalidateLayout(); + } + } + + #endregion + + #region DataSource + + /// + /// Gets or sets the data source that the Series is bound to. + /// + [DefaultValue(null), AttributeProvider(typeof(IListSource)), Category("Data")] + [Description("Indicates the data source that the Series is bound to.")] + public object DataSource + { + get { return (_DataSource); } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataSource = value; + + NeedToUpdateBindings = true; + + OnPropertyChangedEx("DataSource", VisualChangeType.Layout); + } + } + + #endregion + + #region DefaultPaletteColor + + /// + /// Gets the default palette color assigned to the series when it + /// is added to the chart. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the default palette color assigned to the series when it is added to the chart.")] + public Color DefaultPaletteColor + { + get { return (_DefaultPaletteColor); } + + internal set + { + if (value != _DefaultPaletteColor) + { + _DefaultPaletteColor = value; + + InvalidateStyle(); + } + } + } + + #endregion + + #region IsDisplayed + + /// + /// Gets whether the series is displayed (based upon Visibility and Legend state). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool IsDisplayed + { + get + { + BaseChart baseChart = Parent as BaseChart; + + ItemCheckAction ica = (baseChart != null) + ? baseChart.Legend.ItemCheckAction : ItemCheckAction.ShowItem; + + return ((Visible == true) && + (ica == ItemCheckAction.None || + (ShowCheckBoxInLegend == false || CheckedInLegend == true))); + } + } + + #endregion + + #region SeriesRangeChanged + + /// + /// Signals to the chart that the series data has changed. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool SeriesRangeChanged + { + get { return (_SeriesRangeChanged); } + + set + { + _SeriesRangeChanged = value; + + if (value == true) + { + BaseChart chart = Parent as BaseChart; + + if (chart != null) + { + chart.SeriesRangeChanged = true; + + chart.InvalidateLayout(); + } + } + } + } + + #endregion + + #region SeriesType + + /// + /// Gets or sets the Series Type. + /// + [DefaultValue(SeriesType.Point), Category("Appearance")] + [Description("Indicates the Series Type.")] + public virtual SeriesType SeriesType + { + get { return (_SeriesType); } + + set + { + if (value != _SeriesType) + { + _SeriesType = value; + + BaseChart chart = Parent as BaseChart; + + if (chart != null) + { + SeriesRangeChanged = true; + chart.SeriesRangeChanged = true; + } + + OnPropertyChangedEx("SeriesType", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region DataBinder + + internal DataBinder DataBinder + { + get + { + if (_DataBinder == null) + _DataBinder = new DataBinder(this); + + return (_DataBinder); + } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataBinder = value; + } + } + + #endregion + + #region NeedToUpdateBindings + + internal bool NeedToUpdateBindings + { + get { return (TestState(States.NeedToUpdateBindings)); } + set { SetState(States.NeedToUpdateBindings, value); } + } + + #endregion + + #region RenderBounds + + internal Rectangle RenderBounds + { + get { return (_RenderBounds); } + set { _RenderBounds = value; } + } + + #endregion + + #region SeriesId + + internal int SeriesId + { + get { return (_SeriesId); } + set { _SeriesId = value; } + } + + #endregion + + #region SeriesKey + + internal object SeriesKey + { + get { return (_SeriesKey); } + set { _SeriesKey = value; } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + UpdateDataBindings(); + } + + #region UpdateDataBindings + + internal void UpdateDataBindings() + { + if (NeedToUpdateBindings == true) + { + BaseChart chart = Parent as BaseChart; + + object dataSource = DataSource ?? chart.DataSource; + string dataMember = (string.IsNullOrEmpty(DataMember) == false) ? DataMember : chart.DataMember; + + if (dataSource != null) + { + ClearSeriesPoints(); + + DataBinder dataBinder = DataBinder; + + dataBinder.Clear(); + + dataBinder.DataConnect(dataSource, dataMember); + dataBinder.LoadSeriesData(this); + } + + NeedToUpdateBindings = false; + } + } + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + BoundsRelative = layoutInfo.LayoutBounds; + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + throw new NotImplementedException(); + } + + #endregion + + #region Render + + internal override void Render(ChartRenderInfo renderInfo) + { + if (Displayed == true) + { + Rectangle bounds = BoundsRelative; + + if (renderInfo.ClipRectangle.IntersectsWith(bounds)) + RenderOverride(renderInfo); + } + } + + #endregion + + #region RefreshSeries + + /// + /// Causes the series to refresh its display, as the underlying + /// series data (potentially) has changed in some way. + /// + public void RefreshSeries() + { + SeriesRangeChanged = true; + + InvalidateLayout(); + } + + #endregion + + #region AddSeriesPoint + + internal virtual void AddSeriesPoint(object valuex, object[] valuesY, object dataItem) + { + throw new NotImplementedException(); + } + + #endregion + + #region ClearSeriesPoints + + internal virtual void ClearSeriesPoints() + { + throw new NotImplementedException(); + } + + #endregion + + #region Style handling + + #region InvalidateStyle + + /// + ///Invalidate the cached Style definitions + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + if (LegendItem != null) + LegendItem.EffectiveStyles.InvalidateStyles(); + } + + #endregion + + #endregion + + #region ILegendItem + + #region CheckedInLegend + + /// + /// Gets or sets whether the series is checked in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the series is checked in the Legend.")] + public bool CheckedInLegend + { + get { return (TestState(States.CheckedInLegend)); } + + set + { + if (value != CheckedInLegend) + { + SetState(States.CheckedInLegend, value); + + if (LegendItem != null) + LegendItem.UpdateCheckState(); + + OnCheckStateChanged(); + } + } + } + + internal virtual void OnCheckStateChanged() + { + BaseChart chart = Parent as BaseChart; + + if (chart != null) + chart.OnSeriesCheckStateChanged("CheckedInLegend"); + + OnPropertyChangedEx("CheckedInLegend", VisualChangeType.Render); + } + + #endregion + + #region ShowCheckBoxInLegend + + /// + /// Gets or sets whether a checkbox for the series is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether a checkbox for the series is shown in the Legend.")] + public bool ShowCheckBoxInLegend + { + get { return (TestState(States.ShowCheckBoxInLegend)); } + + set + { + if (value != ShowCheckBoxInLegend) + { + SetState(States.ShowCheckBoxInLegend, value); + + OnPropertyChangedEx("ShowCheckBoxInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInLegend + + /// + /// Gets or sets whether the series is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the series is shown in the Legend.")] + public bool ShowInLegend + { + get { return (TestState(States.ShowInLegend)); } + + set + { + if (value != ShowInLegend) + { + SetState(States.ShowInLegend, value); + + OnPropertyChangedEx("ShowInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInParentLegend + + /// + /// Gets or sets whether the series is shown in parent Legend(s). + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the series is shown in parent Legend(s).")] + public bool ShowInParentLegend + { + get { return (TestState(States.ShowInParentLegend)); } + + set + { + if (value != ShowInParentLegend) + { + SetState(States.ShowInParentLegend, value); + + OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowMarkerInLegend + + /// + /// Gets or sets whether the series Marker is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the series Marker is shown in the Legend.")] + public bool ShowMarkerInLegend + { + get { return (TestState(States.ShowMarkerInLegend)); } + + set + { + if (value != ShowMarkerInLegend) + { + SetState(States.ShowMarkerInLegend, value); + + OnPropertyChangedEx("ShowMarkerInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LegendItem + + /// + /// Gets the item's parent LegendItem. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the item's parent LegendItem.")] + public ChartLegendItem LegendItem + { + get { return (_LegendItem); } + internal set { _LegendItem = value; } + } + + #endregion + + #region LegendText + + /// + /// Gets or sets the text to display in the legend. + /// + [DefaultValue(null), Category("Legend")] + [Description("Indicates the text to display in the legend.")] + public string LegendText + { + get { return (_LegendText); } + + set + { + if (value != _LegendText) + { + _LegendText = value; + + OnPropertyChangedEx("LegendText", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region GetLegendItem + + public virtual ChartLegendItem GetLegendItem() + { + LegendItem = null; + + if (ShowInLegend == true) + { + ChartContainer chart = Parent as ChartContainer; + + if (chart != null) + { + LegendItem = new ChartLegendItem(); + + if (CheckedInLegend == true) + _LegendItem.CheckState = CheckState.Checked; + + _LegendItem.Parent = chart.Legend; + + _LegendItem.Name = Name; + _LegendItem.ItemText = LegendText; + + if (string.IsNullOrEmpty(_LegendItem.Name) == true) + _LegendItem.Name = "(Series)"; + + _LegendItem.ChartItems.Add(this); + } + } + + return (_LegendItem); + } + + #endregion + + #region GetLegendItems + + public List GetLegendItems() + { + List list = new List(); + + ChartLegendItem item = GetLegendItem(); + + if (item != null) + list.Add(item); + + AddSubLegendItems(list); + + return (list); + } + + #region AddSubLegendItems + + internal virtual void AddSubLegendItems(List list) + { + throw new NotImplementedException(); + } + + #endregion + + #endregion + + #region GetLegendItemColor + + public Color GetLegendItemColor() + { + ChartXy chartXy = Parent as ChartXy; + + ChartLegendItemVisualStyle lstyle = ChartLegendItemVisualStyles[StyleType.Default]; + + if (lstyle.TextColor.IsEmpty == false) + return (lstyle.TextColor); + + Color color = GetLegendItemColorEx(); + + if (color.IsEmpty == true) + color = _DefaultPaletteColor; + + return (color); + } + + #region GetLegendItemColorEx + + internal virtual Color GetLegendItemColorEx() + { + throw new NotImplementedException(); + } + + #endregion + + #endregion + + #region RenderLegendItemMarker + + public void RenderLegendItemMarker(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + RenderLegendItemMarkerEx(g, litem, style); + + g.SmoothingMode = sm; + } + + #region RenderLegendItemMarkerEx + + internal virtual void RenderLegendItemMarkerEx( + Graphics g, ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + throw new NotImplementedException(); + } + + #endregion + + #region RenderDefaultMarker + + internal void RenderDefaultMarker(Graphics g, + Rectangle bounds, ChartSeriesVisualStyle sstyle) + { + bounds.Width++; + bounds.Height++; + + Background background = sstyle.MarkerVisualStyle.Background; + + if (background.IsEmpty == true) + { + g.FillRectangle(Brushes.DimGray, bounds); + } + else + { + using (Brush br = background.GetBrush(bounds)) + g.FillRectangle(br, bounds); + } + } + + #endregion + + #endregion + + #endregion + + #region InvalidateRender + + public override void InvalidateRender() + { + BaseChart chart = Parent as BaseChart; + + if (chart != null) + chart.InvalidateRender(); + } + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + BaseSeries copy = new BaseSeries(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + BaseSeries c = copy as BaseSeries; + + if (c != null) + { + base.CopyTo(c); + + c.ChartLegendItemVisualStyles = + (_ChartLegendItemVisualStyles != null) ? ChartLegendItemVisualStyles.Copy() : null; + + c.DataPropertyNameSeries = DataPropertyNameSeries; + c.DataPropertyNameX = DataPropertyNameX; + c.DataPropertyNamesY = DataPropertyNamesY; + + c.DataMember = DataMember; + c.DataSource = DataSource; + + c.DefaultPaletteColor = DefaultPaletteColor; + + c.SeriesType = SeriesType; + + c.CheckedInLegend = CheckedInLegend; + c.LegendText = LegendText; + c.ShowCheckBoxInLegend = ShowCheckBoxInLegend; + c.ShowInLegend = ShowInLegend; + c.ShowInParentLegend = ShowInParentLegend; + c.ShowMarkerInLegend = ShowMarkerInLegend; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "BaseSeries"; + + sec.AddStartElement(serialName); + } + + if (_ChartLegendItemVisualStyles != null) + sec.AddElement(_ChartLegendItemVisualStyles.GetSerialData("ChartLegendItemVisualStyles")); + + //sec.AddDataValue("DataSource", DataSource, null); + sec.AddValue("DataMember", DataMember, null); + + sec.AddValue("DataPropertyNameSeries", DataPropertyNameSeries, null); + sec.AddValue("DataPropertyNameX", DataPropertyNameX, null); + + if (_DataPropertyNamesY != null && _DataPropertyNamesY.Count > 0) + { + sec.AddStartElement("DataPropertyNamesYs count=\"" + _DataPropertyNamesY.Count + "\""); + + foreach (string s in _DataPropertyNamesY) + sec.AddValue("DataPropertyNamesY", s); + + sec.AddEndElement("DataPropertyNamesYs"); + } + + sec.AddValue("DefaultPaletteColor", DefaultPaletteColor, Color.Empty); + + sec.AddValue("SeriesType", SeriesType, SeriesType.Point); + + sec.AddValue("CheckedInLegend", CheckedInLegend, true); + sec.AddValue("LegendText", LegendText, null); + sec.AddValue("ShowCheckBoxInLegend", ShowCheckBoxInLegend, true); + sec.AddValue("ShowInLegend", ShowInLegend, true); + sec.AddValue("ShowInParentLegend", ShowInParentLegend, true); + sec.AddValue("ShowMarkerInLegend", ShowMarkerInLegend, true); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "DataMember": + DataMember = se.StringValue; + break; + + case "DataPropertyNameSeries": + DataPropertyNameSeries = se.StringValue; + break; + + case "DataPropertyNameX": + DataPropertyNameX = se.StringValue; + break; + + case "DataPropertyNamesY": + DataPropertyNamesY.Add(se.StringValue); + break; + + case "DataSource": + DataSource = se.DataValue; + break; + + case "DefaultPaletteColor": + DefaultPaletteColor = se.GetValueColor(); + break; + + case "SeriesType": + SeriesType = (SeriesType)se.GetValueEnum(typeof(SeriesType)); + break; + + case "CheckedInLegend": + CheckedInLegend = bool.Parse(se.StringValue); + break; + + case "LegendText": + LegendText = se.StringValue; + break; + + case "ShowCheckBoxInLegend": + ShowCheckBoxInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInLegend": + ShowInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInParentLegend": + ShowInParentLegend = bool.Parse(se.StringValue); + break; + + case "ShowMarkerInLegend": + ShowMarkerInLegend = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartLegendItemVisualStyles": + sec.PutSerialData(ChartLegendItemVisualStyles); + break; + + case "DataPropertyNamesYs": + if (se.ArrayCount > 0) + { + DataPropertyNamesY = new CustomCollection(se.ArrayCount); + + sec.PutSerialData(this); + } + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region Series States + + [Flags] + private enum States : uint + { + NeedToUpdateBindings = (1U << 0), + + CheckedInLegend = (1U << 1), + ShowInLegend = (1U << 2), + ShowInParentLegend = (1U << 3), + ShowCheckBoxInLegend = (1U << 4), + ShowMarkerInLegend = (1U << 5), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + ChartLegendItemVisualStyles = null; + + base.Dispose(); + } + + #endregion + } + + #region enums + + #region SeriesType + + /// + /// Defines available Series types + /// + public enum SeriesType + { + Bubble, + + HorizontalBar, + VerticalBar, + + Line, + Point, + + HorizontalDot, // Wilkinson dotplot + VerticalDot, + + HorizontalHiLoBar, // Box, Candle, HiLo + VerticalHiLoBar, + + Pie, + //Polar, + //Radar, + + //TreeMap, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartContainer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartContainer.cs new file mode 100644 index 00000000..9d7be7e6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartContainer.cs @@ -0,0 +1,2482 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.Charts.TextMarkup; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of ChartContainer objects. + /// + [Editor("DevComponents.Charts.Design.ChartContainerCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartContainerCollection : CustomNamedCollection + { + public ChartContainerCollection() + { + } + + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("ChartCont")); + } + + #endregion + } + + /// + /// ChartContainer + /// + public class ChartContainer : ChartVisualElement, ILegendData, IScrollable, IComparable + { + #region Private variables + + private States _States; + + private string _EmptyText; + private BodyElement _EmptyTextMarkup; + private ChartLegend _Legend; + + private ChartTitleCollection _Titles; + + private ScrollBarLite _VScrollBar; + private ScrollBarLite _HScrollBar; + + private int _VScrollBarWidth = 9; + private int _HScrollBarHeight = 9; + + private Rectangle _FrameBounds; // Margin + private Rectangle _ContentBounds; // Content - chart container(s) + private Rectangle _ContentBoundsEx; // Content - extended content bounds + + private int _FillWeight = 100; + private AutoSizeMode _AutoSizeMode = AutoSizeMode.NotSet; + private Size _MinContentSize = new Size(100, 100); + + private Timer _AutoScrollTimer; + private AutoScrollEnable _AutoScrollEnable; + private Rectangle _ScrollRect; + + private bool _Panning; + + private int _HPanOffset; + private int _VPanOffset; + + private ItemHitArea _HitArea; + private ItemHitArea _MouseDownHitArea; + + private ContainerVisualStyles _ContainerVisualStyles; + private EffectiveStyles _EffectiveContainerStyles; + + private int _MatrixDisplayOrder; + private Rectangle _MatrixDisplayBounds; + + private int _SelectionUpdateCount = -1; + + #endregion + + public ChartContainer() + { + InitDefaultStates(); + + SetupScrollBars(); + + _EffectiveContainerStyles = new EffectiveStyles(this); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.AutoGenSeriesCollection, true); + SetState(States.EnablePanning, true); + + SetState(States.HScrollBarVisible, true); + SetState(States.VScrollBarVisible, true); + } + + #endregion + + #region Public properties + + #region AutoSizeMode + + /// + /// Gets or sets the mode used to size the container (by FillWeight, etc). + /// + [DefaultValue(AutoSizeMode.NotSet), Category("Layout")] + [Description("Indicates the mode used to size the container (by FillWeight, etc).")] + public AutoSizeMode AutoSizeMode + { + get { return (_AutoSizeMode); } + + set + { + if (value != _AutoSizeMode) + { + _AutoSizeMode = value; + + OnPropertyChangedEx("AutoSizeMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ContainerVisualStyles + + /// + /// Gets or sets the visual styles for the container. + /// + [Category("Style")] + [Description("Indicates the visual styles for the container.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ContainerVisualStyles ContainerVisualStyles + { + get + { + if (_ContainerVisualStyles == null) + { + _ContainerVisualStyles = new ContainerVisualStyles(); + + StyleVisualChangeHandler(null, _ContainerVisualStyles); + } + + return (_ContainerVisualStyles); + } + + set + { + if (_ContainerVisualStyles != value) + { + ContainerVisualStyles oldValue = _ContainerVisualStyles; + + _ContainerVisualStyles = value; + + OnStyleChanged("ContainerVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ContentBounds + + /// + /// Gets the Content area bounding rectangle. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle ContentBounds + { + get { return (_ContentBounds); } + internal set { _ContentBounds = value; } + } + + #endregion + + #region EffectiveContainerStyle + + /// + /// Gets a reference to the container's effective (cached, composite) styles. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public EffectiveStyles EffectiveContainerStyles + { + get { return (_EffectiveContainerStyles); } + } + + #endregion + + #region EmptyText + + /// + /// Gets or sets the Text to display when the container is empty. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates the Text to display when the container is empty.")] + public string EmptyText + { + get { return (_EmptyText); } + + set + { + if (_EmptyText != value) + { + _EmptyText = value; + + EmptyTextMarkupChanged(); + + OnPropertyChangedEx("EmptyText", VisualChangeType.Render); + } + } + } + + #endregion + + #region EnableEmptyTextMarkup + + /// + /// Gets or sets whether EmptyText markup support is enabled. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether EmptyText markup support is enabled.")] + public bool EnableEmptyTextMarkup + { + get { return (TestState(States.EnableEmptyTextMarkup)); } + + set + { + if (EnableEmptyTextMarkup != value) + { + SetState(States.EnableEmptyTextMarkup, value); + + EmptyTextMarkupChanged(); + + OnPropertyChangedEx("EnableEmptyTextMarkup", VisualChangeType.Layout); + } + } + } + + #region Markup support + + private void EmptyTextMarkupChanged() + { + _EmptyTextMarkup = null; + + if (EnableEmptyTextMarkup == true) + { + if (MarkupParser.IsMarkup(_EmptyText) == true) + { + _EmptyTextMarkup = MarkupParser.Parse(_EmptyText); + + if (_EmptyTextMarkup != null) + _EmptyTextMarkup.HyperLinkClick += EmptyTextMarkupLinkClick; + } + } + } + + /// + /// Occurs when a text markup link is clicked + /// + protected virtual void EmptyTextMarkupLinkClick(object sender, EventArgs e) + { + HyperLink link = sender as HyperLink; + + ChartControl.DoEmptyTextMarkupLinkClickEvent(this, link); + } + + /// + /// Gets plain text without text-markup (if text-markup is used in EmptyText) + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public string EmptyTextPlainText + { + get { return (_EmptyTextMarkup != null ? _EmptyTextMarkup.PlainText : _EmptyText); } + } + + #endregion + + #endregion + + #region EnablePanning + + /// + /// Gets or sets whether the container can be panned with the mouse. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the container can be panned with the mouse.")] + public bool EnablePanning + { + get { return (TestState(States.EnablePanning)); } + + set + { + if (value != EnablePanning) + { + SetState(States.EnablePanning, value); + + OnPropertyChanged("EnablePanning"); + } + } + } + + #endregion + + #region EnableSelection + + /// + /// Gets or sets whether the CONTAINER can be "selected" with the mouse. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether the CONTAINER can be \"selected\" with the mouse.")] + public bool EnableSelection + { + get { return (TestState(States.EnableSelection)); } + + set + { + if (value != EnableSelection) + { + SetState(States.EnableSelection, value); + + OnPropertyChanged("EnableSelection"); + } + } + } + + #endregion + + #region FillWeight + + /// + /// Gets or sets a value which, when AutoSizeMode is Fill, + /// represents the width of the container relative to the widths + /// of other fill-mode containers (default value is 100). + /// + [DefaultValue(100), Category("Layout")] + [Description("Indicates a value which, when AutoSizeMode is Fill, represents the width of the containers relative to the widths of other fill-mode containers (default value is 100).")] + public int FillWeight + { + get { return (_FillWeight); } + + set + { + if (value != _FillWeight) + { + _FillWeight = value; + + OnPropertyChangedEx("FillWeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FrameBounds + + /// + /// Gets the Frame area bounding rectangle. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle FrameBounds + { + get { return (_FrameBounds); } + internal set { _FrameBounds = value; } + } + + #endregion + + #region HScrollBar + + /// + /// Gets a reference to the containers’s horizontal scrollbar + /// + [Category("ScrollBar")] + [Description("Indicates the container’s horizontal scrollbar.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarLite HScrollBar + { + get { return (_HScrollBar); } + internal set { _HScrollBar = value; } + } + + #endregion + + #region HScrollBarHeight + + /// + /// Gets or sets the horizontal scrollBar height. + /// + [DefaultValue(9), Category("ScrollBar")] + [Description("Indicates the horizontal scrollBar height")] + public int HScrollBarHeight + { + get { return (_HScrollBarHeight); } + + set + { + if (value != _HScrollBarHeight) + { + if (value > 0) + { + _HScrollBarHeight = value; + + OnPropertyChangedEx("HScrollBarHeight", VisualChangeType.Layout); + } + } + } + } + + #endregion + + #region HScrollOffset + + /// + /// Gets or sets the horizontal scrollbar offset. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int HScrollOffset + { + get + { + if (_HScrollBar != null && _HScrollBar.Visible == true) + return (_HScrollBar.Value); + + return (0); + } + + set { SetHScrollValue(value); } + } + + #endregion + + #region HScrollBarVisible + + /// + /// Gets or sets whether Horizontal Scrollbar is shown if needed (due to content of the control exceeding available width). + /// + [DefaultValue(true), Category("ScrollBar")] + [Description("Indicates whether Horizontal Scrollbar is shown if needed (due to content of the control exceeding available width).")] + public bool HScrollBarVisible + { + get { return (TestState(States.HScrollBarVisible)); } + + set + { + if (value != HScrollBarVisible) + { + SetState(States.HScrollBarVisible, value); + + InvalidateLayout(); + } + } + } + + #endregion + + #region IsSelected + + /// + /// Gets or sets whether the container is selected. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSelected + { + get + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + { + if (_SelectionUpdateCount == chartControl.SelectionUpdateCount) + return (TestState(States.IsSelected)); + + bool selected = chartControl.GetSelected(this); + + SetState(States.IsSelected, selected); + + _SelectionUpdateCount = chartControl.SelectionUpdateCount; + } + + return (TestState(States.IsSelected)); + } + + set + { + if (value != IsSelected) + { + SetState(States.IsSelected, value); + + ChartControl chartControl = ChartControl; + + if (chartControl != null) + { + chartControl.SetSelected(this, value); + + InvalidateRender(); + } + } + } + } + + #endregion + + #region Legend + + /// + /// Gets or Sets the element Legend. + /// + [Category("Legend")] + [Description("Indicates the element Legend.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegend Legend + { + get + { + if (_Legend == null) + Legend = new ChartLegend(); + + return (_Legend); + } + + set + { + if (value != _Legend) + { + if (_Legend != null) + { + _Legend.Parent = null; + _Legend.PropertyChanged -= LegendPropertyChanged; + } + + _Legend = value; + + if (_Legend != null) + { + _Legend.Parent = this; + _Legend.PropertyChanged += LegendPropertyChanged; + } + } + } + } + + void LegendPropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateLayout(); + } + + #endregion + + #region MatrixAlignEndColumn + + /// + /// Gets or sets whether the container's content ending X-offset is aligned + /// with other containers ending in the same ChartMatrix column. + /// + [DefaultValue(false), Category("Matrix")] + [Description("Indicates whether the container's content ending X-offset is aligned with other containers ending in the same ChartMatrix column.")] + public bool MatrixAlignEndColumn + { + get { return (TestState(States.MatrixAlignEndColumn)); } + + set + { + if (value != MatrixAlignEndColumn) + { + SetState(States.MatrixAlignEndColumn, value); + + OnPropertyChangedEx("MatrixAlignEndColumn", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MatrixAlignEndRow + + /// + /// Gets or sets whether the container's content ending Y-offset is aligned + /// with other containers ending in the same ChartMatrix row. + /// + [DefaultValue(false), Category("Matrix")] + [Description("Indicates whether the container's content ending Y-offset is aligned with other containers ending in the same ChartMatrix row.")] + public bool MatrixAlignEndRow + { + get { return (TestState(States.MatrixAlignEndRow)); } + + set + { + if (value != MatrixAlignEndRow) + { + SetState(States.MatrixAlignEndRow, value); + + OnPropertyChangedEx("MatrixAlignEndRow", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MatrixAlignStartColumn + + /// + /// Gets or sets whether the container's content starting X-offset is aligned + /// with other containers starting in the same ChartMatrix column. + /// + [DefaultValue(false), Category("Matrix")] + [Description("Indicates whether the container's content starting X-offset is aligned with other containers starting in the same ChartMatrix column.")] + public bool MatrixAlignStartColumn + { + get { return (TestState(States.MatrixAlignStartColumn)); } + + set + { + if (value != MatrixAlignStartColumn) + { + SetState(States.MatrixAlignStartColumn, value); + + OnPropertyChangedEx("MatrixAlignStartColumn", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MatrixAlignStartRow + + /// + /// Gets or sets whether the container's content starting Y-offset is aligned + /// with other containers starting in the same ChartMatrix row. + /// + [DefaultValue(false), Category("Matrix")] + [Description("Indicates whether the container's content starting Y-offset is aligned with other containers starting in the same ChartMatrix row.")] + public bool MatrixAlignStartRow + { + get { return (TestState(States.MatrixAlignStartRow)); } + + set + { + if (value != MatrixAlignStartRow) + { + SetState(States.MatrixAlignStartRow, value); + + OnPropertyChangedEx("MatrixAlignStartRow", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MatrixDisplayBounds + + /// + /// Gets or sets the containers matrix display bounds (in relative units of the matrix). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle MatrixDisplayBounds + { + get { return (_MatrixDisplayBounds); } + + set + { + if (value != _MatrixDisplayBounds) + { + _MatrixDisplayBounds = value; + + OnPropertyChangedEx("MatrixDisplayBounds", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MatrixDisplayOrder + + /// + /// Gets or sets the containers display order in the parent matrix layout + /// (higher values are placed on top of lower values). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int MatrixDisplayOrder + { + get { return (_MatrixDisplayOrder); } + + set + { + if (value != _MatrixDisplayOrder) + { + _MatrixDisplayOrder = value; + + OnPropertyChangedEx("MatrixDisplayOrder", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinContentSize + + /// + /// Gets or sets the minimum size of the content area of the chart. + /// + [Category("Layout")] + [Description("Indicates the minimum size of the content area of the chart.")] + public Size MinContentSize + { + get { return (_MinContentSize); } + + set + { + if (value != _MinContentSize) + { + _MinContentSize = value; + + OnPropertyChangedEx("MinContentSize", VisualChangeType.Layout); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeMinContentSize() + { + return (_MinContentSize.Width != 100 || _MinContentSize.Height != 100); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetMinContentSize() + { + MinContentSize = new Size(100, 100); + } + + #endregion + + #region ScrollBounds + + /// + /// Gets the Scrollable bounds. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual Rectangle ScrollBounds + { + get { return (_ContentBounds); } + } + + #endregion + + #region ScrollBoundsEx + + /// + /// Gets the extended Scrollable bounds. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual Rectangle ScrollBoundsEx + { + get { return (_ContentBoundsEx); } + } + + #endregion + + #region ScrollBoundsOffset + + /// + /// Gets the current scrollbar offset + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Point ScrollBoundsOffset + { + get { return (new Point(HScrollOffset, VScrollOffset)); } + } + + #endregion + + #region Titles + + /// + /// Gets or Sets a reference to the collection of Titles + /// + [Category("Appearance")] + [Description("Indicates the collection of Titles.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartTitleCollection Titles + { + get + { + if (_Titles == null) + { + _Titles = new ChartTitleCollection(); + + _Titles.CollectionChanged += TitlesCollectionChanged; + } + + return (_Titles); + } + + internal set + { + if (_Titles != null) + _Titles.CollectionChanged -= TitlesCollectionChanged; + + _Titles = value; + + if (_Titles != null) + _Titles.CollectionChanged += TitlesCollectionChanged; + } + } + + #region TitlesCollectionChanged + + void TitlesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (ChartTitle title in e.NewItems) + title.Parent = this; + break; + + case NotifyCollectionChangedAction.Replace: + foreach (ChartTitle title in e.OldItems) + title.Parent = null; + + foreach (ChartTitle title in e.NewItems) + title.Parent = this; + break; + + case NotifyCollectionChangedAction.Remove: + foreach (ChartTitle title in e.OldItems) + title.Parent = null; + break; + } + + InvalidateLayout(); + } + + #endregion + + #endregion + + #region VScrollBar + + /// + /// Gets a reference to the container’s vertical scrollbar + /// + [Category("ScrollBar")] + [Description("Indicates the container’s vertical scrollbar.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarLite VScrollBar + { + get { return (_VScrollBar); } + } + + #endregion + + #region VScrollBarWidth + + /// + /// Gets or sets the vertical scrollBar width. + /// + [DefaultValue(9), Category("ScrollBar")] + [Description("Indicates the vertical scrollBar width")] + public int VScrollBarWidth + { + get { return (_VScrollBarWidth); } + + set + { + if (value != _VScrollBarWidth) + { + if (value > 0) + { + _VScrollBarWidth = value; + + OnPropertyChangedEx("VScrollBarWidth", VisualChangeType.Layout); + } + } + } + } + + #endregion + + #region VScrollOffset + + /// + /// Gets the vertical scrollbar offset + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int VScrollOffset + { + get + { + if (_VScrollBar != null && _VScrollBar.Visible == true) + return (_VScrollBar.Value); + + return (0); + } + + set { SetVScrollValue(value); } + } + + #endregion + + #region VScrollBarVisible + + /// + /// Gets or sets whether Vertical Scrollbar is shown when needed (due to the content area exceeding available height). + /// + [DefaultValue(true), Category("ScrollBar")] + [Description("Indicates whether Vertical Scrollbar is shown when needed (due to the content area exceeding available height)")] + public bool VScrollBarVisible + { + get { return (TestState(States.VScrollBarVisible)); } + + set + { + if (value != VScrollBarVisible) + { + SetState(States.VScrollBarVisible, value); + + InvalidateLayout(); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region ContentBoundsEx + + internal Rectangle ContentBoundsEx + { + get { return (_ContentBoundsEx); } + set { _ContentBoundsEx = value; } + } + + #endregion + + #region EmptyTextMarkup + + internal BodyElement EmptyTextMarkup + { + get { return (_EmptyTextMarkup); } + set { _EmptyTextMarkup = value; } + } + + #endregion + + #region HitArea + + internal ItemHitArea HitArea + { + get { return (_HitArea); } + set { _HitArea = value; } + } + + #endregion + + #region IsSubPanel + + /// + /// Gets whether the ChartPanel is a subordinate / nested panel. + /// + internal bool IsSubPanel + { + get { return (Parent != null); } + } + + #endregion + + #region MatrixColumnAligned + + /// + /// Gets whether the ChartContainer column was MatrixAligned. + /// + internal bool MatrixColumnAligned + { + get { return (TestState(States.MatrixColumnAligned)); } + set { SetState(States.MatrixColumnAligned, value); } + } + + #endregion + + #region MatrixRowAligned + + /// + /// Gets whether the ChartContainer row was MatrixAligned. + /// + internal bool MatrixRowAligned + { + get { return (TestState(States.MatrixRowAligned)); } + set { SetState(States.MatrixRowAligned, value); } + } + + #endregion + + #region MouseDownHitArea + + internal ItemHitArea MouseDownHitArea + { + get { return (_MouseDownHitArea); } + set { _MouseDownHitArea = value; } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + if (Legend.Visible == true) + Legend.Measure(layoutInfo); + + foreach (ChartTitle title in Titles) + { + if (title.Visible == true) + title.Measure(layoutInfo); + } + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + if (Legend.Visible == true) + Legend.Arrange(layoutInfo); + + foreach (ChartTitle title in Titles) + { + if (title.Visible == true) + title.Arrange(layoutInfo); + } + + UpdateScrollBars(layoutInfo); + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + // Render Titles + + foreach (ChartTitle title in Titles) + { + if (title.Visible == true) + title.Render(renderInfo); + } + + // Render the Legend + + if (Legend.Visible == true) + Legend.Render(renderInfo); + } + + #endregion + + #region RenderTextMarkup + + internal void RenderTextMarkup(Graphics g, + Font font, Color textColor, Alignment alignment, Rectangle r) + { + if (textColor.IsEmpty) + textColor = Color.Black; + + MarkupDrawContext d = + new MarkupDrawContext(g, font, textColor, false); + + _EmptyTextMarkup.Arrange(new Rectangle(Point.Empty, r.Size), d); + + Size size = _EmptyTextMarkup.Bounds.Size; + + switch (alignment) + { + case Alignment.NotSet: + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + if (r.Height > size.Height) + r.Y += (r.Height - size.Height) / 2; + break; + + case Alignment.BottomLeft: + case Alignment.BottomCenter: + case Alignment.BottomRight: + if (r.Height > size.Height) + r.Y = r.Bottom - size.Height; + break; + } + + _EmptyTextMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + _EmptyTextMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #region RenderEmptyText + + protected void RenderEmptyText( + Graphics g, ContainerVisualStyle style, Rectangle bounds) + { + if (String.IsNullOrEmpty(EmptyText) == false) + { + if (EmptyTextMarkup != null) + { + RenderTextMarkup(g, style.Font, + style.TextColor, style.Alignment, bounds); + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + TextDrawing.DrawString(g, + EmptyText, style.Font, style.TextColor, bounds, tf); + } + } + } + + #endregion + + #region RenderScrollbars + + protected void RenderScrollbars(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + if (HScrollBar.Visible == true && VScrollBar.Visible == true) + { + ScrollBarVisualStyle style = VScrollBar.GetEffectiveStyle(); + + Rectangle r = HScrollBar.Bounds; + + r.X = VScrollBar.Bounds.X; + r.Width = VScrollBar.Width; + + using (Brush br = style.TrackBackground.GetBrush(r)) + g.FillRectangle(br, r); + + using (Pen pen = new Pen(style.BorderColor)) + g.DrawRectangle(pen, r); + } + + if (HScrollBar.Visible == true) + HScrollBar.Render(renderInfo); + + if (VScrollBar.Visible == true) + VScrollBar.Render(renderInfo); + } + + #endregion + + #region Mouse handling + + #region OnMouseEnter + + protected override bool OnMouseEnter(EventArgs e) + { + base.OnMouseEnter(e); + + InvalidateRender(); + + return (true); + } + + #endregion + + #region OnMouseLeave + + protected override bool OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + + InvalidateRender(); + + return (true); + } + + #endregion + + #region OnMouseMove + + protected override bool OnMouseMove(MouseEventArgs e) + { + _HitArea = GetHitArea(e.Location); + + if (IsMouseDown == true) + return (OnMouseDownMove(e)); + + if (_HitArea == ItemHitArea.InContent) + { + if (EmptyTextMarkup != null) + { + ChartControl.SetChartCursor = true; + EmptyTextMarkup.MouseMove(ChartControl, e); + ChartControl.SetChartCursor = false; + + if (EmptyTextMarkup.MouseOverElement != null) + { + if (EmptyTextMarkup.MouseOverElement is HyperLink) + return (true); + } + } + + if (EnablePanning == true && + (HScrollBar.Enabled == true || VScrollBar.Enabled == true)) + { + ChartCursor = OpenHandCursor; + + return (true); + } + } + + ChartCursor = Cursors.Default; + + return (false); + } + + #region OnMouseDownMove + + private bool OnMouseDownMove(MouseEventArgs e) + { + if (_Panning == true) + { + ChartCursor = ClosedHandCursor; + + if (HScrollBar.Enabled == true) + HScrollOffset = _HPanOffset + (MouseDownPoint.X - e.Location.X); + + if (VScrollBar.Enabled == true) + { + int n = (MouseDownPoint.Y - e.Location.Y); + + if (VScrollBar.Inverted == true) + VScrollOffset = _VPanOffset - n; + else + VScrollOffset = _VPanOffset + n; + } + } + + return (true); + } + + #endregion + + #endregion + + #region OnMouseDown + + protected override bool OnMouseDown(MouseEventArgs e) + { + ChartControl.Focus(); + + UpdateSelection(e); + + return (OnMouseDownEx(e)); + } + + protected override bool OnMouseDownEx(MouseEventArgs e) + { + base.OnMouseDown(e); + + MouseDownHitArea = _HitArea; + + if (EmptyTextMarkup != null) + { + if (EmptyTextMarkup.MouseOverElement != null) + { + EmptyTextMarkup.MouseDown(ChartControl, e); + + return (true); + } + } + + if (_HitArea == ItemHitArea.InContent) + { + if (EnablePanning == true && + (HScrollBar.Visible == true || VScrollBar.Visible == true)) + { + _HPanOffset = HScrollOffset; + _VPanOffset = VScrollOffset; + + _Panning = true; + + ChartCursor = ClosedHandCursor; + ChartControl.PostInternalMouseMove(); + + ChartControl.CapturedItem = this; + + return (true); + } + } + + return (false); + } + + #region UpdateSelection + + private void UpdateSelection(MouseEventArgs e) + { + ChartContainer parent = Parent as ChartContainer; + + if (parent != null && parent.EnableSelection == true) + { + if (IsSelected == false || + ((e.Button & MouseButtons.Left) == MouseButtons.Left)) + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + { + bool ctrlKey = ((Control.ModifierKeys & Keys.Control) == Keys.Control); + + if (ctrlKey == true) + { + chartControl.SetSelected(this, !IsSelected); + } + else + { + chartControl.ClearAllSelected(); + + chartControl.SetSelected(this, true); + } + } + } + } + } + + #endregion + + #endregion + + #region OnMouseUp + + protected override bool OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + if (EmptyTextMarkup != null) + { + if (EmptyTextMarkup.MouseOverElement != null) + EmptyTextMarkup.Click(ChartControl); + } + + if (_Panning == true) + { + _Panning = false; + + ChartControl.CapturedItem = null; + } + + return (true); + } + + #endregion + + #region OnMouseWheel + + protected override bool OnMouseWheel(MouseEventArgs e) + { + if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) + return (OnHorizontalMouseWheel(e)); + + return (OnVerticalMouseWheel(e)); + + } + + #region OnHorizontalMouseWheel + + private bool OnHorizontalMouseWheel(MouseEventArgs e) + { + if (HScrollBar.Enabled == true) + { + if ((e.Delta < 0 && HScrollBar.IsAtMaxumum == false) || + (e.Delta > 0 && HScrollBar.IsAtMinumum == false)) + { + SetHWheelValue(-e.Delta); + + return (true); + } + } + + return (false); + } + + #region SetHWheelValue + + private void SetHWheelValue(int delta) + { + int value = delta * SystemInformation.MouseWheelScrollLines / 120; + + value *= HScrollBar.SmallChange; + value += HScrollBar.Value; + + SetHScrollValue(value); + } + + #endregion + + #endregion + + #region OnVerticalMouseWheel + + private bool OnVerticalMouseWheel(MouseEventArgs e) + { + if (VScrollBar.Enabled == true) + { + if (VScrollBar.Inverted == true) + { + if ((e.Delta < 0 && VScrollBar.IsAtMinumum == false) || + (e.Delta > 0 && VScrollBar.IsAtMaxumum == false)) + { + SetVWheelValue(e.Delta); + + return (true); + } + } + else + { + if ((e.Delta < 0 && VScrollBar.IsAtMaxumum == false) || + (e.Delta > 0 && VScrollBar.IsAtMinumum == false)) + { + SetVWheelValue(-e.Delta); + + return (true); + } + } + } + + return (false); + } + + #region SetVWheelValue + + private void SetVWheelValue(int delta) + { + int value = delta * SystemInformation.MouseWheelScrollLines / 120; + + value *= VScrollBar.SmallChange; + value += VScrollBar.Value; + + SetVScrollValue(value); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region Scrollbar support + + #region SetupScrollBars + + private void SetupScrollBars() + { + _VScrollBar = new VScrollBarLite(); + _VScrollBar.Parent = this; + _VScrollBar.Width = Dpi.Width(VScrollBarWidth); + + _HScrollBar = new HScrollBarLite(); + _HScrollBar.Parent = this; + _HScrollBar.Height = Dpi.Height(HScrollBarHeight); + + _HScrollBar.Visible = false; + _VScrollBar.Visible = false; + } + + #endregion + + #region UpdateScrollBars + + private void UpdateScrollBars(ChartLayoutInfo layoutInfo) + { + Rectangle cbounds = ScrollBounds; + Rectangle cboundsEx = ScrollBoundsEx; + + EnableHScrollBar(cbounds, cboundsEx); + EnableVScrollBar(cbounds, cboundsEx); + + if (_HScrollBar.Enabled == true) + { + int widthEx = cboundsEx.Width; + + _HScrollBar.SmallChange = cbounds.Width / 20; + _HScrollBar.Maximum = Math.Max(0, widthEx); + _HScrollBar.LargeChange = Math.Min(cbounds.Width, _HScrollBar.Maximum); + + if (_HScrollBar.Value + _HScrollBar.LargeChange > _HScrollBar.Maximum) + _HScrollBar.Value = _HScrollBar.Maximum - _HScrollBar.LargeChange; + + _HScrollBar.Arrange(layoutInfo); + } + + if (_VScrollBar.Enabled == true) + { + int heightEx = cboundsEx.Height; + + _VScrollBar.SmallChange = cbounds.Height / 20; + _VScrollBar.Maximum = Math.Max(0, heightEx); + _VScrollBar.LargeChange = Math.Min(cbounds.Height, _VScrollBar.Maximum); + + if (_VScrollBar.Value + _VScrollBar.LargeChange > _VScrollBar.Maximum) + _VScrollBar.Value = _VScrollBar.Maximum - _VScrollBar.LargeChange; + + _VScrollBar.Arrange(layoutInfo); + } + } + + #region EnableHScrollBar + + private void EnableHScrollBar(Rectangle cbounds, Rectangle cboundsEx) + { + bool enable = (HScrollBarVisible == true) && + (cboundsEx.Width > cbounds.Width); + + if ((cbounds.Height < _HScrollBar.Height + 4) || cbounds.Width <= 0) + enable = false; + + if (enable == true) + { + _HScrollBar.Location = new + Point(cbounds.Left, cbounds.Bottom - _HScrollBar.Height - 1); + + int n = cbounds.Width - 1; + + if (_VScrollBar.Visible == true) + n -= _VScrollBar.Width; + + _HScrollBar.Width = n; + _HScrollBar.Height = Dpi.Height(HScrollBarHeight); + } + else + { + _HScrollBar.Value = 0; + } + + _HScrollBar.Enabled = enable; + _HScrollBar.Visible = enable; + } + + #endregion + + #region EnableVScrollBar + + private void EnableVScrollBar(Rectangle cbounds, Rectangle cboundsEx) + { + bool enable = (VScrollBarVisible == true) && + (cboundsEx.Height > cbounds.Height); + + if (cbounds.Height <= 0 || (cbounds.Width < _VScrollBar.Width + 4)) + enable = false; + + if (enable == true) + { + _VScrollBar.Location = new + Point(cbounds.Right - _VScrollBar.Width - 1, cbounds.Top); + + _VScrollBar.Height = cbounds.Height - 1; + + if (_HScrollBar.Visible == true) + _VScrollBar.Height -= _HScrollBar.Height; + + _VScrollBar.Width = Dpi.Width(VScrollBarWidth); + } + else + { + _VScrollBar.Value = 0; + } + + _VScrollBar.Enabled = enable; + _VScrollBar.Visible = enable; + } + + #endregion + + #endregion + + #region SetVScrollValue + + internal void SetVScrollValue(int value) + { + if (_VScrollBar.Visible == true) + { + int oldValue = _VScrollBar.Value; + + value = Math.Max(value, 0); + value = Math.Min(value, _VScrollBar.Maximum); + + _VScrollBar.Value = value; + } + } + + #endregion + + #region SetHScrollValue + + internal void SetHScrollValue(int value) + { + if (_HScrollBar.Visible == true) + { + int oldValue = _HScrollBar.Value; + + value = Math.Max(value, 0); + value = Math.Min(value, _HScrollBar.Maximum); + + _HScrollBar.Value = value; + } + } + + #endregion + + #region AutoScrolling support + + #region EnableAutoScrolling + + internal void EnableAutoScrolling( + AutoScrollEnable enable, Rectangle scrollRect) + { + if (ChartControl.Focused == true) + { + _AutoScrollEnable = enable; + + if ((_HScrollBar != null && _HScrollBar.Visible == true) || + (_VScrollBar != null && _VScrollBar.Visible == true)) + { + _ScrollRect = scrollRect; + + if (_AutoScrollTimer == null) + { + _AutoScrollTimer = new Timer(); + + _AutoScrollTimer.Interval = 10; + _AutoScrollTimer.Tick += AutoScrollTimerTick; + _AutoScrollTimer.Start(); + } + } + } + } + + #endregion + + #region DisableAutoScrolling + + internal void DisableAutoScrolling() + { + if (_AutoScrollTimer != null) + { + _AutoScrollTimer.Stop(); + _AutoScrollTimer.Tick -= AutoScrollTimerTick; + + _AutoScrollTimer = null; + } + } + + #endregion + + #region AutoScrollTimerTick + + private void AutoScrollTimerTick(object sender, EventArgs e) + { + Point pt = ChartControl.PointToClient(Cursor.Position); + Rectangle t = _ScrollRect; + + if ((_AutoScrollEnable & AutoScrollEnable.Horizontal) == AutoScrollEnable.Horizontal && + (_HScrollBar != null && _HScrollBar.Visible == true)) + { + int dx = (pt.X < t.X) + ? ScrollAmount(pt.X - t.X) + : (pt.X >= t.Right) ? ScrollAmount(pt.X - t.Right) : 0; + + SetHScrollValue(_HScrollBar.Value + dx); + } + + if ((_AutoScrollEnable & AutoScrollEnable.Vertical) == AutoScrollEnable.Vertical && + (_VScrollBar != null && _VScrollBar.Visible == true)) + { + int dy = (pt.Y < t.Top) + ? ScrollAmount(pt.Y - t.Top) + : (pt.Y >= t.Bottom) ? ScrollAmount(pt.Y - t.Bottom) : 0; + + SetVScrollValue(_VScrollBar.Value + dy); + } + } + + #endregion + + #region ScrollAmount + + private int ScrollAmount(int delta) + { + int n = Math.Abs(delta); + int amt = 1 << ((n / 16) + 1); + + return (delta < 0 ? -amt : amt); + } + + #endregion + + #endregion + + #endregion + + #region EnsureVisible + + /// + /// Ensures the container is visible on screen, and optionally + /// centered (if possible). + /// + /// + public virtual void EnsureVisible(bool center) + { + ChartContainer parent = Parent as ChartContainer; + + if (parent != null) + parent.EnsureVisible(this, center); + } + + /// + /// Ensures that the given container "item" is visible + /// on screen, and optionally centered (if possible). + /// + /// + public virtual void EnsureVisible(ChartContainer item, bool center) + { + Rectangle bounds = ContentBounds; + + bounds.X += HScrollOffset; + + if (VScrollBar.Inverted == true) + bounds.Y -= VScrollOffset; + else + bounds.Y += VScrollOffset; + + if (HScrollBar.Enabled == true) + bounds.Width -= VScrollBar.Width; + + if (VScrollBar.Enabled == true) + bounds.Height -= HScrollBar.Height; + + bounds.Width -= Dpi.Width4; + bounds.Height -= Dpi.Height4; + + Rectangle ibounds = item.FrameBounds; + + if (bounds.Contains(ibounds) == false) + { + if (HScrollBar.Enabled == true) + { + if (center == true) + { + int x = (bounds.X + bounds.Right) / 2 - (ibounds.Width / 2); + + SetHScrollValue(ibounds.X - x); + } + else + { + int x = ibounds.X; + + if (ibounds.Right > bounds.Right) + x -= (ibounds.Right - bounds.Right); + + if (x < bounds.X) + x = bounds.X; + + SetHScrollValue(HScrollOffset + (ibounds.X - x)); + } + } + + if (VScrollBar.Enabled == true) + { + if (center == true) + { + int y = (bounds.Y + bounds.Bottom) / 2; + y -= (ibounds.Height / 2); + + SetVScrollValue(ibounds.Y - y); + } + else + { + int y = ibounds.Y; + + if (ibounds.Bottom > bounds.Bottom) + y -= (ibounds.Bottom - bounds.Bottom); + + if (y < bounds.Y) + y = bounds.Y; + + SetVScrollValue(VScrollOffset + (ibounds.Y - y)); + } + } + } + + ChartContainer parent = Parent as ChartContainer; + + if (parent != null) + parent.EnsureVisible(this, center); + } + + #endregion + + #region GetDisplayBounds + + /// + /// Gets the "displayBounds" of the given rectangle (scroll + /// adjusted bounds). + /// + /// + /// + public Rectangle GetDisplayBounds(Rectangle bounds) + { + bounds.X -= HScrollOffset; + + if (VScrollBar.Inverted == true) + bounds.Y += VScrollOffset; + else + bounds.Y -= VScrollOffset; + + return (bounds); + } + + #endregion + + #region GetElementAt + + /// + /// Gets the element at the given Point. + /// + /// + /// + public override ChartVisualElement GetElementAt(Point pt) + { + if (InScrollBar(HScrollBar, pt)) + return (HScrollBar); + + if (InScrollBar(VScrollBar, pt)) + return (VScrollBar); + + foreach (ChartTitle title in Titles) + { + if (title.Visible == true) + { + if (title.Bounds.Contains(pt)) + return (title); + } + } + + if (Legend.Visible == true) + { + if (Legend.FrameBounds.Contains(pt)) + { + ChartVisualElement item = Legend.GetElementAt(pt); + + return (item ?? Legend); + } + } + + return (null); + } + + #region InScrollBar + + private bool InScrollBar(ScrollBarLite scrollBar, Point pt) + { + if (scrollBar != null && scrollBar.Visible == true) + { + if (scrollBar.Bounds.Contains(pt)) + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region GetHitArea + + /// + /// Gets the HitArea for the given Point. + /// + /// + /// + public override ItemHitArea GetHitArea(Point pt) + { + Rectangle contentBounds = GetScrollBounds(ContentBounds); + + if (contentBounds.Contains(pt)) + return (ItemHitArea.InContent); + + Rectangle frameBounds = GetScrollBounds(FrameBounds); + + if (frameBounds.Contains(pt)) + return (ItemHitArea.InFrame); + + return (ItemHitArea.None); + } + + #endregion + + #region GetTitleByName + + /// + /// Gets the defined Title with the given name. + /// + /// + /// ChartTitle or null + public ChartTitle GetTitleByName(string name) + { + return (Titles[name]); + } + + #endregion + + #region Style Support + + #region GetEffectiveContainerStyle + + internal ContainerVisualStyle GetEffectiveContainerStyle() + { + StyleState state = GetStyleState(); + + return (EffectiveContainerStyles[state]); + } + + #endregion + + #region GetStyleState + + private StyleState GetStyleState() + { + StyleState state = StyleState.Default; + + if (IsMouseOver == true) + state |= StyleState.MouseOver; + + if (IsSelected == true) + state |= StyleState.Selected; + + return (state); + } + + #endregion + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style, StyleType cs) + { + base.ApplyStyles(style); + + ContainerVisualStyle cstyle = style as ContainerVisualStyle; + + if (cstyle != null) + { + ApplyParentStyles(cstyle, Parent as ChartContainer, cs); + + cstyle.ApplyStyle(ContainerVisualStyles[cs]); + } + } + + #region ApplyParentStyles (ChartContainerVisualStyles) + + private void ApplyParentStyles( + ContainerVisualStyle cstyle, ChartContainer item, StyleType cs) + { + if (item != null) + { + ApplyParentStyles(cstyle, item.Parent as ChartContainer, cs); + + ChartPanel panel = item as ChartPanel; + + if (panel != null) + { + if (panel.DefaultVisualStyles.ContainerVisualStyles != null) + cstyle.ApplyStyle(panel.DefaultVisualStyles.ContainerVisualStyles[cs]); + } + } + else + { + ChartControl chartControl = ChartControl; + + if (chartControl.BaseVisualStyles.ContainerVisualStyles != null) + cstyle.ApplyStyle(chartControl.BaseVisualStyles.ContainerVisualStyles[cs]); + + if (chartControl.DefaultVisualStyles.ContainerVisualStyles != null) + cstyle.ApplyStyle(chartControl.DefaultVisualStyles.ContainerVisualStyles[cs]); + } + } + + #endregion + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults(BaseVisualStyle style, StyleType cs) + { + ContainerVisualStyle cstyle = style as ContainerVisualStyle; + + if (cstyle != null) + { + if (cstyle.BorderPattern == null) + cstyle.BorderPattern = new BorderPattern(LinePattern.Solid); + + if (cstyle.DropShadow.Enabled == Tbool.NotSet) + cstyle.DropShadow.Enabled = Tbool.False; + } + + base.ApplyDefaults(style, cs); + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Style + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + _EffectiveContainerStyles.InvalidateStyles(); + + if (_VScrollBar != null) + _VScrollBar.InvalidateStyle(); + + if (_HScrollBar != null) + _HScrollBar.InvalidateStyle(); + } + + #endregion + + #endregion + + #region ILegendData + + #region GetLegendItems + + public virtual List GetLegendData() + { + return (null); + } + + #endregion + + #endregion + + #region CompareTo + + public int CompareTo(object obj) + { + ChartContainer cobj = obj as ChartContainer; + + if (cobj != null) + { + if (this.Equals(cobj) == true) + return (0); + } + + return (-1); + } + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartContainer copy = new ChartContainer(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartContainer c = copy as ChartContainer; + + if (c != null) + { + base.CopyTo(c); + + c.AutoSizeMode = AutoSizeMode; + + c.ContainerVisualStyles = (_ContainerVisualStyles != null) ? ContainerVisualStyles.Copy() : null; + + c.EmptyText = EmptyText; + c.EnableEmptyTextMarkup = EnableEmptyTextMarkup; + c.EnablePanning = EnablePanning; + c.EnableSelection = EnableSelection; + c.FillWeight = FillWeight; + c.HScrollBarHeight = HScrollBarHeight; + c.HScrollBarVisible = HScrollBarVisible; + + c.Legend = (_Legend != null) ? (ChartLegend)Legend.Copy() : null; + + c.MatrixAlignEndColumn = MatrixAlignEndColumn; + c.MatrixAlignEndRow = MatrixAlignEndRow; + c.MatrixAlignStartColumn = MatrixAlignStartColumn; + c.MatrixAlignStartRow = MatrixAlignStartRow; + c.MatrixDisplayBounds = MatrixDisplayBounds; + c.MatrixDisplayOrder = MatrixDisplayOrder; + c.MinContentSize = MinContentSize; + + c.Titles.Clear(); + + foreach (ChartTitle title in Titles) + c.Titles.Add((ChartTitle)title.Copy()); + + c.VScrollBarWidth = VScrollBarWidth; + c.VScrollBarVisible = VScrollBarVisible; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartContainer"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AutoSizeMode", AutoSizeMode, AutoSizeMode.NotSet); + + if (_ContainerVisualStyles != null && _ContainerVisualStyles.IsEmpty == false) + sec.AddElement(_ContainerVisualStyles.GetSerialData("ContainerVisualStyles")); + + sec.AddValue("EmptyText", EmptyText, null); + sec.AddValue("EnableEmptyTextMarkup", EnableEmptyTextMarkup, false); + + sec.AddValue("EnablePanning", EnablePanning, true); + sec.AddValue("EnableSelection", EnableSelection, false); + + sec.AddValue("FillWeight", FillWeight, 100); + + sec.AddValue("HScrollBarHeight", HScrollBarHeight, 9); + sec.AddValue("HScrollBarVisible", HScrollBarVisible, true); + + if (_HScrollBar != null) + sec.AddElement(_HScrollBar.GetSerialData("HScrollBar")); + + if (_Legend != null) + sec.AddElement(_Legend.GetSerialData("Legend")); + + sec.AddValue("MatrixAlignEndColumn", MatrixAlignEndColumn, false); + sec.AddValue("MatrixAlignEndRow", MatrixAlignEndRow, false); + sec.AddValue("MatrixAlignStartColumn", MatrixAlignStartColumn, false); + sec.AddValue("MatrixAlignStartRow", MatrixAlignStartRow, false); + + ChartPanel panel = Parent as ChartPanel; + + if (panel == null || panel.AutoFillChartMatrix == false) + { + if (_MatrixDisplayBounds.IsEmpty == false) + sec.AddValue("MatrixDisplayBounds", MatrixDisplayBounds); + } + + sec.AddValue("MatrixDisplayOrder", MatrixDisplayOrder, 0); + sec.AddValue("MinContentSize", MinContentSize, new Size(100,100)); + + if (_Titles != null && _Titles.Count > 0) + { + sec.AddStartElement("Titles count=\"" + _Titles.Count + "\""); + + foreach (ChartTitle title in _Titles) + sec.AddElement(title.GetSerialData("")); + + sec.AddEndElement("Titles"); + } + + if (_VScrollBar != null) + sec.AddElement(_VScrollBar.GetSerialData("VScrollBar")); + + sec.AddValue("VScrollBarWidth", VScrollBarWidth, 9); + sec.AddValue("VScrollBarVisible", VScrollBarVisible, true); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement("ChartContainer"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AutoSizeMode": + AutoSizeMode = (AutoSizeMode)se.GetValueEnum(typeof(AutoSizeMode)); + break; + + case "EmptyText": + EmptyText = se.StringValue; + break; + + case "EnableEmptyTextMarkup": + EnableEmptyTextMarkup = bool.Parse(se.StringValue); + break; + + case "EnablePanning": + EnablePanning = bool.Parse(se.StringValue); + break; + + case "EnableSelection": + EnableSelection = bool.Parse(se.StringValue); + break; + + case "FillWeight": + FillWeight = int.Parse(se.StringValue); + break; + + case "HScrollBarHeight": + HScrollBarHeight = int.Parse(se.StringValue); + break; + + case "HScrollBarVisible": + HScrollBarVisible = bool.Parse(se.StringValue); + break; + + case "MatrixAlignEndColumn": + MatrixAlignEndColumn = bool.Parse(se.StringValue); + break; + + case "MatrixAlignEndRow": + MatrixAlignEndRow = bool.Parse(se.StringValue); + break; + + case "MatrixAlignStartColumn": + MatrixAlignStartColumn = bool.Parse(se.StringValue); + break; + + case "MatrixAlignStartRow": + MatrixAlignStartRow = bool.Parse(se.StringValue); + break; + + case "MatrixDisplayBounds": + ChartPanel panel = Parent as ChartPanel; + + if (panel == null || panel.AutoFillChartMatrix == false) + MatrixDisplayBounds = se.GetValueRect(); + break; + + case "MatrixDisplayOrder": + MatrixDisplayOrder = int.Parse(se.StringValue); + break; + + case "MinContentSize": + MinContentSize = se.GetValueSize(); + break; + + case "VScrollBarWidth": + VScrollBarWidth = int.Parse(se.StringValue); + break; + + case "VScrollBarVisible": + VScrollBarVisible = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartTitle": + string name = sec.GetItemValue("Name"); + + ChartTitle title = GetTitleByName(name); + + if (title != null) + Titles.Remove(title); + + title = new ChartTitle(name); + + sec.PutSerialData(title); + + Titles.Add(title); + break; + + case "ContainerVisualStyles": + sec.PutSerialData(ContainerVisualStyles); + break; + + case "HScrollBar": + sec.PutSerialData(HScrollBar); + break; + + case "Legend": + sec.PutSerialData(Legend); + break; + + case "Titles": + sec.PutSerialData(this); + break; + + case "VScrollBar": + sec.PutSerialData(VScrollBar); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + AutoGenSeriesCollection = (1U << 0), + + EnableEmptyTextMarkup = (1U << 1), + EnablePanning = (1U << 2), + + ShowPointsToolTips = (1U << 3), + ShowSeriesToolTips = (1U << 4), + + HScrollBarEnabled = (1U << 5), + VScrollBarEnabled = (1U << 6), + HScrollBarVisible = (1U << 7), + VScrollBarVisible = (1U << 8), + + LayoutBoundsValid = (1U << 9), + IsSelected = (1U << 10), + + MatrixAlignStartColumn = (1U << 11), + MatrixAlignEndColumn = (1U << 12), + MatrixAlignStartRow = (1U << 13), + MatrixAlignEndRow = (1U << 14), + + MatrixColumnAligned = (1U << 15), + MatrixRowAligned = (1U << 16), + + EnableSelection = (1U << 17), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + ContainerVisualStyles = null; + Titles = null; + + base.Dispose(); + } + + #endregion + } + + #region enums + + #region AutoSizeMode + + /// + /// Defines auto-sizing mode. + /// + public enum AutoSizeMode + { + /// + /// NotSet (None is default) + /// + NotSet = -1, + + /// + /// No Auto-sizing will take place. + /// + None, + + /// + /// Size will be determined by the fill weight. + /// + Fill, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartCrosshair.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartCrosshair.cs new file mode 100644 index 00000000..571f88ed --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartCrosshair.cs @@ -0,0 +1,895 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents a Crosshair element. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartCrosshair : ChartVisualElement + { + #region Private variables + + private States _States; + + private PointIntersectMode _PointIntersectMode = PointIntersectMode.Edge; + private int _PointIntersectMargin = 2; + + private AxisOrientation _AxisOrientation = AxisOrientation.X; + private CrosshairLabelMode _CrosshairLabelMode = CrosshairLabelMode.Common; + + private CrosshairVisualStyle _CrosshairVisualStyle; + private EffectiveStyle _EffectiveCrosshairStyle; + + private CrosshairValueVisualStyle _CrosshairLabelVisualStyle; + private EffectiveStyle _EffectiveCrosshairLabelStyle; + + #endregion + + public ChartCrosshair() + { + InitDefaultStates(); + + _EffectiveCrosshairStyle = new EffectiveStyle(this); + _EffectiveCrosshairLabelStyle = new EffectiveStyle(this); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.ShowCrosshairLabelMarkers, true); + SetState(States.ShowGroupHeader, true); + } + + #endregion + + #region Public properties + + #region AxisOrientation + + /// + /// Gets or sets the axis orientation driving the crosshair display. + /// + [DefaultValue(AxisOrientation.X), Category("Appearance")] + [Description("Indicates the axis orientation driving the crosshair display.")] + public AxisOrientation AxisOrientation + { + get { return (_AxisOrientation); } + + set + { + if (value != _AxisOrientation) + { + _AxisOrientation = value; + + OnPropertyChanged("AxisOrientation"); + } + } + } + + #endregion + + #region CrosshairLabelMode + + /// + /// Gets or sets the mode used to display the Crosshair label. + /// + [DefaultValue(CrosshairLabelMode.Common), Category("Behavior")] + [Description("Indicates the mode used to display the Crosshair label.")] + public CrosshairLabelMode CrosshairLabelMode + { + get { return (_CrosshairLabelMode); } + + set + { + if (value != _CrosshairLabelMode) + { + _CrosshairLabelMode = value; + + OnPropertyChangedEx("CrosshairLabelMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region PointIntersectMode + + /// + /// Gets or sets the the Crosshair point intersection mode. + /// + [DefaultValue(PointIntersectMode.Edge), Category("Behavior")] + [Description("Indicates the Crosshair point intersection mode.")] + public PointIntersectMode PointIntersectMode + { + get { return (_PointIntersectMode); } + + set + { + if (value != _PointIntersectMode) + { + _PointIntersectMode = value; + + OnPropertyChangedEx("PointIntersectMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region PointIntersectMargin + + /// + /// Gets or sets the the Crosshair point intersection margin. + /// + [DefaultValue(2), Category("Layout")] + [Description("Indicates the Crosshair point intersection margin.")] + public int PointIntersectMargin + { + get { return (_PointIntersectMargin); } + + set + { + if (value != _PointIntersectMargin) + { + _PointIntersectMargin = value; + + OnPropertyChangedEx("PointIntersectMargin", VisualChangeType.Render); + } + } + } + + #endregion + + #region CrosshairLabelVisualStyle + + /// + /// Gets or sets the default visual style to be used for Crosshair + /// values rendered on the X and Y axes. + /// + [Category("Style")] + [Description("Indicates visual style to be used for Crosshair values rendered on the X and Y axes")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CrosshairValueVisualStyle CrosshairLabelVisualStyle + { + get + { + if (_CrosshairLabelVisualStyle == null) + { + _CrosshairLabelVisualStyle = new CrosshairValueVisualStyle(); + + StyleVisualChangeHandler(null, _CrosshairLabelVisualStyle); + } + + return (_CrosshairLabelVisualStyle); + } + + set + { + if (_CrosshairLabelVisualStyle != value) + { + CrosshairValueVisualStyle oldValue = _CrosshairLabelVisualStyle; + _CrosshairLabelVisualStyle = value; + + OnVisualStyleChanged("CrosshairLabelVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region CrosshairVisualStyle + + /// + /// Gets or sets the visual style for the Crosshair. + /// + [Category("Style")] + [Description("Indicates the visual style for the Crosshair.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CrosshairVisualStyle CrosshairVisualStyle + { + get + { + if (_CrosshairVisualStyle == null) + { + _CrosshairVisualStyle = new CrosshairVisualStyle(); + + StyleVisualChangeHandler(null, _CrosshairVisualStyle); + } + + return (_CrosshairVisualStyle); + } + + set + { + if (_CrosshairVisualStyle != value) + { + CrosshairVisualStyle oldValue = _CrosshairVisualStyle; + + _CrosshairVisualStyle = value; + + OnVisualStyleChanged("CrosshairVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region EffectiveCrosshairLabelStyle + + /// + /// Gets a reference to the Crosshair label's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CrosshairValueVisualStyle EffectiveCrosshairLabelStyle + { + get { return (_EffectiveCrosshairLabelStyle.Style); } + } + + #endregion + + #region EffectiveCrosshairStyle + + /// + /// Gets a reference to the Crosshair's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CrosshairVisualStyle EffectiveCrosshairStyle + { + get { return (_EffectiveCrosshairStyle.Style); } + } + + #endregion + + #region HighlightPoints + + /// + /// Gets or sets whether series points are highlighted + /// when the Crosshair cursor intersects with them. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether series points are highlighted when the Crosshair cursor intersects with them.")] + public bool HighlightPoints + { + get { return (TestState(States.HighlightPoints)); } + + set + { + if (value != HighlightPoints) + { + SetState(States.HighlightPoints, value); + + OnPropertyChangedEx("HighlightPoints", VisualChangeType.Render); + } + } + } + + #endregion + + #region HighlightSinglePoint + + /// + /// Gets or sets whether only single series points are highlighted + /// when the Crosshair cursor intersects with them. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether only single series points are highlighted when the Crosshair cursor intersects with them.")] + public bool HighlightSinglePoint + { + get { return (TestState(States.HighlightSinglePoint)); } + + set + { + if (value != HighlightSinglePoint) + { + SetState(States.HighlightSinglePoint, value); + + OnPropertyChangedEx("HighlightSinglePoint", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowValueXLabels + + /// + /// Gets or sets whether ValueX Labels are shown. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether ValueX Labels are shown.")] + public bool ShowValueXLabels + { + get { return (TestState(States.ShowValueXLabels)); } + + set + { + if (value != ShowValueXLabels) + { + SetState(States.ShowValueXLabels, value); + + OnPropertyChangedEx("ShowValueXLabels", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowValueXLine + + /// + /// Gets or sets whether a ValueX line is shown. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether a ValueX line is shown.")] + public bool ShowValueXLine + { + get { return (TestState(States.ShowValueXLine)); } + + set + { + if (value != ShowValueXLine) + { + SetState(States.ShowValueXLine, value); + + OnPropertyChangedEx("ShowValueXLine", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowCrosshairLabelMarkers + + /// + /// Gets or sets whether Crosshair label markers are shown. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Crosshair label markers are shown.")] + public bool ShowCrosshairLabelMarkers + { + get { return (TestState(States.ShowCrosshairLabelMarkers)); } + + set + { + if (value != ShowCrosshairLabelMarkers) + { + SetState(States.ShowCrosshairLabelMarkers, value); + + OnPropertyChangedEx("ShowCrosshairLabelMarkers", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowCrosshairLabels + + /// + /// Gets or sets whether Crosshair labels are shown. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether Crosshair labels are shown.")] + public bool ShowCrosshairLabels + { + get { return (TestState(States.ShowCrosshairLabels)); } + + set + { + if (value != ShowCrosshairLabels) + { + SetState(States.ShowCrosshairLabels, value); + + OnPropertyChangedEx("ShowCrosshairLabels", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowGroupHeaders + + /// + /// Gets or sets whether Group Headers are shown for each series. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Group Headers are shown for each series.")] + public bool ShowGroupHeaders + { + get { return (TestState(States.ShowGroupHeader)); } + + set + { + if (value != ShowGroupHeaders) + { + SetState(States.ShowGroupHeader, value); + + OnPropertyChangedEx("ShowGroupHeaders", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowValueYLabels + + /// + /// Gets or sets whether a ValueY label is shown. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether a ValueY label is shown.")] + public bool ShowValueYLabels + { + get { return (TestState(States.ShowValueYLabels)); } + + set + { + if (value != ShowValueYLabels) + { + SetState(States.ShowValueYLabels, value); + + OnPropertyChangedEx("ShowValueYLabels", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowValueYLine + + /// + /// Gets or sets whether a ValueY line is shown. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether a ValueY line is shown.")] + public bool ShowValueYLine + { + get { return (TestState(States.ShowValueYLine)); } + + set + { + if (value != ShowValueYLine) + { + SetState(States.ShowValueYLine, value); + + OnPropertyChangedEx("ShowValueYLine", VisualChangeType.Render); + } + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + } + + #endregion + + #region Style support + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + base.ApplyStyles(style); + + CrosshairVisualStyle cstyle = style as CrosshairVisualStyle; + + if (cstyle != null) + { + ApplyParentStyles(cstyle, Parent as ChartContainer); + + cstyle.ApplyStyle(CrosshairVisualStyle); + + ApplyDefaultLineStyles(cstyle.ValueXLineStyle); + ApplyDefaultLineStyles(cstyle.ValueYLineStyle); + + if (cstyle.GroupHeaderFont == null) + cstyle.GroupHeaderFont = SystemFonts.CaptionFont; + + if (cstyle.GroupHeaderTextColor.IsEmpty) + cstyle.GroupHeaderTextColor = Color.Black; + + if (cstyle.Padding.IsEmpty == true) + cstyle.Padding = new Style.Padding(4); + + if (cstyle.BorderThickness <= 0) + cstyle.BorderThickness = 1; + + if (cstyle.BorderPattern == LinePattern.NotSet) + cstyle.BorderPattern = LinePattern.Solid; + + if (cstyle.BorderColor.IsEmpty == true) + cstyle.BorderColor = Color.Black; + + if (cstyle.Background.IsEmpty == true) + cstyle.Background = new Background(Color.White); + + if (cstyle.Font == null) + cstyle.Font = SystemFonts.DefaultFont; + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles( + CrosshairVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is ChartPanel) + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.CrosshairVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.CrosshairVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.CrosshairVisualStyle); + } + } + + #endregion + + #region ApplyDefaultLineStyles + + private void ApplyDefaultLineStyles(ChartLineVisualStyle style) + { + if (style.LineColor.IsEmpty == true) + style.LineColor = Color.Fuchsia; + + if (style.LinePattern == LinePattern.NotSet) + style.LinePattern = LinePattern.Solid; + + if (style.LineWidth < 0) + style.LineWidth = 1; + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Styles + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + _EffectiveCrosshairStyle.InvalidateStyle(); + } + + #endregion + + #endregion + + #endregion + + #region Crosshair States + + [Flags] + private enum States : uint + { + HighlightPoints = (1U << 0), + HighlightSinglePoint = (1U << 1), + + ShowValueXLabels = (1U << 2), + ShowValueXLine = (1U << 3), + + ShowCrosshairLabels = (1U << 4), + ShowGroupHeader = (1U << 5), + ShowCrosshairLabelMarkers = (1U << 6), + + ShowValueYLabels = (1U << 7), + ShowValueYLine = (1U << 8), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartCrosshair copy = new ChartCrosshair(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartCrosshair c = copy as ChartCrosshair; + + if (c != null) + { + base.CopyTo(c); + + c.AxisOrientation = AxisOrientation; + c.CrosshairLabelMode = CrosshairLabelMode; + c.PointIntersectMode = PointIntersectMode; + c.PointIntersectMargin = PointIntersectMargin; + + c.CrosshairLabelVisualStyle = (_CrosshairLabelVisualStyle != null) ? CrosshairLabelVisualStyle.Copy() : null; + c.CrosshairVisualStyle = (_CrosshairVisualStyle != null) ? CrosshairVisualStyle.Copy() : null; + + c.HighlightPoints = HighlightPoints; + c.HighlightSinglePoint = HighlightSinglePoint; + + c.ShowValueXLabels = ShowValueXLabels; + c.ShowValueXLine = ShowValueXLine; + c.ShowCrosshairLabels = ShowCrosshairLabels; + c.ShowGroupHeaders = ShowGroupHeaders; + c.ShowValueYLabels = ShowValueYLabels; + c.ShowValueYLine = ShowValueYLine; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartCrosshair"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AxisOrientation", AxisOrientation, AxisOrientation.X); + sec.AddValue("CrosshairLabelMode", CrosshairLabelMode, CrosshairLabelMode.Common); + sec.AddValue("PointIntersectMode", PointIntersectMode, PointIntersectMode.Edge); + sec.AddValue("PointIntersectMargin", PointIntersectMargin, 2); + + if (_CrosshairLabelVisualStyle != null && _CrosshairLabelVisualStyle.IsEmpty == false) + sec.AddElement(_CrosshairLabelVisualStyle.GetSerialData("CrosshairLabelVisualStyle")); + + if (_CrosshairVisualStyle != null && _CrosshairVisualStyle.IsEmpty == false) + sec.AddElement(_CrosshairVisualStyle.GetSerialData("CrosshairVisualStyle")); + + sec.AddValue("HighlightPoints", HighlightPoints, false); + sec.AddValue("HighlightSinglePoint", HighlightSinglePoint, false); + + sec.AddValue("ShowValueXLabels", ShowValueXLabels, false); + sec.AddValue("ShowValueXLine", ShowValueXLine, false); + sec.AddValue("ShowCrosshairLabels", ShowCrosshairLabels, false); + sec.AddValue("ShowGroupHeaders", ShowGroupHeaders, true); + sec.AddValue("ShowValueYLabels", ShowValueYLabels, false); + sec.AddValue("ShowValueYLine", ShowValueYLine, false); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AxisOrientation": + AxisOrientation = (AxisOrientation)se.GetValueEnum(typeof(AxisOrientation)); + break; + + case "CrosshairLabelMode": + CrosshairLabelMode = (CrosshairLabelMode)se.GetValueEnum(typeof(CrosshairLabelMode)); + break; + + case "PointIntersectMode": + PointIntersectMode = (PointIntersectMode)se.GetValueEnum(typeof(PointIntersectMode)); + break; + + case "PointIntersectMargin": + PointIntersectMargin = int.Parse(se.StringValue); + break; + + case "HighlightPoints": + HighlightPoints = bool.Parse(se.StringValue); + break; + + case "HighlightSinglePoint": + HighlightSinglePoint = bool.Parse(se.StringValue); + break; + + case "ShowValueXLabels": + ShowValueXLabels = bool.Parse(se.StringValue); + break; + + case "ShowValueXLine": + ShowValueXLine = bool.Parse(se.StringValue); + break; + + case "ShowCrosshairLabels": + ShowCrosshairLabels = bool.Parse(se.StringValue); + break; + + case "ShowGroupHeaders": + ShowGroupHeaders = bool.Parse(se.StringValue); + break; + + case "ShowValueYLabels": + ShowValueYLabels = bool.Parse(se.StringValue); + break; + + case "ShowValueYLine": + ShowValueYLine = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "CrosshairLabelVisualStyle": + sec.PutSerialData(CrosshairLabelVisualStyle); + break; + + case "CrosshairVisualStyle": + sec.PutSerialData(CrosshairVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + CrosshairLabelVisualStyle = null; + CrosshairVisualStyle = null; + + base.Dispose(); + } + + #endregion + } + + #region enums + + #region CrosshairLabelMode + + public enum CrosshairLabelMode + { + /// + /// A common Crosshair label is shown for all series + /// + Common, + + /// + /// A crosshair label is shown for the nearest series + /// + NearestSeries, + + /// + /// A crosshair label is shown for each series + /// + EachSeries, + } + + #endregion + + #region CrosshairLabelPosition + + public enum CrosshairLabelPosition + { + /// + /// Crosshair labels positioned relative to the Chart + /// + ChartRelative, + + /// + /// Crosshair labels positioned relative to the Mouse + /// + MouseRelative, + } + + #endregion + + #region PointIntersectMode + + public enum PointIntersectMode + { + /// + /// From center. + /// + Center, + + /// + /// From edge. + /// + Edge, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartElement.cs new file mode 100644 index 00000000..e33f8b85 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartElement.cs @@ -0,0 +1,1769 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.IO; +using System.Threading; +using System.Windows.Forms; +using System.Xml; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + [DesignTimeVisible(false)] + public abstract class ChartElement : INotifyPropertyChanged, INamed, IDisposable + { + #region Events + + /// + /// Occurs when parent of the item has changed. + /// + public event EventHandler ParentChanged; + + /// + /// Occurs when display/rendering of the item is invalidated. + /// + public event EventHandler RenderInvalid; + + /// + /// Occurs when layout of the item is invalidated. + /// + public event EventHandler LayoutInvalid; + + #endregion + + #region Private variables + + private string _Name = String.Empty; + + private ChartControl _ChartControl; + private ChartElement _Parent; + private object _Tag; + + #endregion + + #region Public properties + + #region ChartControl + + /// + /// Gets the parent ChartControl + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartControl ChartControl + { + get { return (GetChartControl()); } + internal set { _ChartControl = value; } + } + + #region GetChartControl + + private ChartControl GetChartControl() + { + if (_ChartControl != null) + return (_ChartControl); + + ChartElement parent = _Parent; + + while (parent != null) + { + if (parent.ChartControl != null) + return (parent.ChartControl); + + parent = parent.Parent; + } + + return (null); + } + + #endregion + + #endregion + + #region ChartPanel + + /// + /// Gets the parent ChartPanel + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartPanel ChartPanel + { + get { return (GetChartPanel()); } + } + + #region GetChartPanel + + private ChartPanel GetChartPanel() + { + ChartElement item = this; + + while (item != null) + { + if (item is ChartPanel) + return ((ChartPanel)item); + + item = item.Parent; + } + + return (null); + } + + #endregion + + #endregion + + #region Name + + /// + /// Gets or sets the Name of the item. + /// + [DefaultValue("")] + [Description("Indicates the Name of the item.")] + public virtual string Name + { + get { return (_Name); } + set { _Name = value; } + } + + #endregion + + #region Parent + + /// + /// Gets or sets the parent of the item. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual ChartElement Parent + { + get { return (_Parent); } + + internal set + { + if (_Parent != value) + { + ChartElement oldParent = _Parent; + _Parent = value; + + OnParentChanged(oldParent, value); + } + } + } + + #region OnParentChanged + + /// + /// Called after parent of the item has changed. + /// + /// Reference to old parent. + /// Reference to new parent. + protected virtual void OnParentChanged(ChartElement oldParent, ChartElement newParent) + { + if (oldParent != null) + oldParent.ParentChanged -= GrapdParentChanged; + + if (newParent != null) + newParent.ParentChanged += GrapdParentChanged; + + OnParentChanged(EventArgs.Empty); + } + + void GrapdParentChanged(object sender, EventArgs e) + { + ChartElement parent = sender as ChartElement; + + if (parent != null) + Parent = parent; + } + + /// + /// Raises ParentChanged event. + /// + /// Provides event arguments. + protected virtual void OnParentChanged(EventArgs e) + { + EventHandler handler = ParentChanged; + + if (handler != null) + handler(this, e); + } + + #endregion + + #endregion + + #region ParentChartContainer + + /// + /// Gets the parent ChartContainer + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartContainer ParentChartContainer + { + get { return (GetParentChartContainer()); } + } + + #region GetParentChartContainer + + private ChartContainer GetParentChartContainer() + { + ChartElement parent = _Parent; + + while (parent != null) + { + if (parent is ChartContainer) + return ((ChartContainer)parent); + + parent = parent.Parent; + } + + return (null); + } + + #endregion + + #endregion + + #region Tag + + /// + /// Gets or sets user-defined data associated with the object + /// + [DefaultValue(null)] + [Description("User-defined data associated with the object")] + [TypeConverter(typeof(StringConverter))] + public object Tag + { + get { return (_Tag); } + set { _Tag = value; } + } + + #endregion + + #endregion + + #region OnLayoutInvalid + + /// + /// Raises LayoutInvalid event. + /// + /// Provides event arguments. + protected virtual void OnLayoutInvalid(EventArgs e) + { + EventHandler handler = LayoutInvalid; + + if (handler != null) + handler(this, e); + } + + #endregion + + #region OnRenderInvalid + + /// + /// Raises RenderInvalid event. + /// + /// Provides event arguments. + protected virtual void OnRenderInvalid(EventArgs e) + { + EventHandler handler = RenderInvalid; + + if (handler != null) + handler(this, e); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + #endregion + + #region IDisposable + + public virtual void Dispose() + { + Parent = null; + } + + #endregion + } + + [ToolboxItem(false)] + public abstract class ChartVisualElement : ChartElement, IEffectiveStyle, IProcessSerialElement + { + #region Static variables + + static Point _mouseDownPoint; + + static Cursor _OpenHandCursor; + static Cursor _ClosedHandCursor; + + #endregion + + #region Private variables + + private Es _States; + + private Rectangle _BoundsRelative; + private Point _ScrollOffset; + + private ChartVisualElement _HitItem; + + #endregion + + #region Constructor + + /// + /// ChartVisualElement + /// + protected ChartVisualElement() + { + SetState(Es.Visible, true); + } + + #endregion + + #region Abstract methods + + /// + /// Performs the layout of the item + /// and sets the Size property to size that item will take. + /// + /// Layout information. + protected abstract void MeasureOverride(ChartLayoutInfo layoutInfo); + + /// + /// Performs the arrange pass layout of the item when + /// the final position and size of the item has been set. + /// + /// Layout information. + protected abstract void ArrangeOverride(ChartLayoutInfo layoutInfo); + + /// + /// Performs drawing of the item and its children. + /// + /// Holds contextual rendering information. + protected abstract void RenderOverride(ChartRenderInfo renderInfo); + + #endregion + + #region Public properties + + #region Bounds + + /// + /// Gets or sets the absolute (scroll adjusted) bounds of the item. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual Rectangle Bounds + { + get { return (GetScrollBounds(_BoundsRelative)); } + } + + #endregion + + #region BoundsRelative + + /// + /// Gets or sets the relative bounds of the item. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual Rectangle BoundsRelative + { + get { return (_BoundsRelative); } + internal set { _BoundsRelative = value; } + } + + #endregion + + #region IsMouseOver + + /// + /// Gets whether mouse is over the element. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool IsMouseOver + { + get { return (TestState(Es.MouseOver)); } + internal set { SetState(Es.MouseOver, value); } + } + + #endregion + + #region Size + + /// + /// Gets or sets the Size of the item. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Size Size + { + get { return (_BoundsRelative.Size); } + internal set { _BoundsRelative.Size = value; } + } + + #endregion + + #region Visible + + /// + /// Get or sets whether the item is visible + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the item is visible")] + public virtual bool Visible + { + get { return (TestState(Es.Visible)); } + + set + { + if (Visible != value) + { + SetState(Es.Visible, value); + + OnPropertyChangedEx("Visible", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region Capture + + internal virtual bool Capture + { + get { return (CapturedItem != null); } + + set + { + if (ChartControl != null) + CapturedItem = (value == true) ? this : null; + } + } + + #endregion + + #region CapturedItem + + internal ChartVisualElement CapturedItem + { + get + { + if (ChartControl != null) + return (ChartControl.CapturedItem); + + return (null); + } + + set + { + if (ChartControl != null) + ChartControl.CapturedItem = value; + } + } + + #endregion + + #region ChartCursor + + internal Cursor ChartCursor + { + get + { + ChartControl cc = ChartControl; + + if (cc != null) + return (cc.ChartCursor); + + return (Cursors.Default); + } + + set + { + ChartControl cc = ChartControl; + + if (cc != null) + cc.ChartCursor = value; + } + } + + #endregion + + #region ClosedHandCursor + + internal Cursor ClosedHandCursor + { + get + { + if (_ClosedHandCursor == null) + _ClosedHandCursor = new Cursor(GetType(), "ClosedHand.cur"); + + return (_ClosedHandCursor); + } + } + + #endregion + + #region HitItem + + internal ChartVisualElement HitItem + { + get { return (_HitItem); } + set { _HitItem = value; } + } + + #endregion + + #region Displayed + + /// + /// Gets whether element is actually displayed on screen + /// + internal bool Displayed + { + get { return (TestState(Es.Displayed)); } + set { SetState(Es.Displayed, value); } + } + + #endregion + + #region IsMouseDown + + /// + /// Gets whether mouse is down + /// + internal virtual bool IsMouseDown + { + get { return (Control.MouseButtons != MouseButtons.None); } + } + + #endregion + + #region MouseDownPoint + + /// + /// Gets the mouse down Point + /// + internal virtual Point MouseDownPoint + { + get { return (_mouseDownPoint); } + set { _mouseDownPoint = value; } + } + + #endregion + + #region MouseOverElement + + internal ChartVisualElement MouseOverElement + { + get { return (ChartControl.MouseOverElement); } + set { ChartControl.MouseOverElement = value; } + } + + #endregion + + #region OpenHandCursor + + internal Cursor OpenHandCursor + { + get + { + if (_OpenHandCursor == null) + _OpenHandCursor = new Cursor(GetType(), "OpenHand.cur"); + + return (_OpenHandCursor); + } + } + + #endregion + + #region ScrollOffset + + internal Point ScrollOffset + { + get { return (_ScrollOffset); } + set { _ScrollOffset = value; } + } + + #endregion + + #endregion + + #region Measure + + /// + /// This method is used by the items internally to invoke the measure pass to + /// get item size. Override MeasureOverride method to perform actual measuring. + /// + /// Holds contextual layout information. + internal void Measure(ChartLayoutInfo layoutInfo) + { + MeasureOverride(layoutInfo); + } + + #endregion + + #region Arrange + + /// + /// This method is used by the items internally to invoke the arrange pass after + /// location and size of the item has been set. Override ArrangeOverride method + /// to perform internal arranging. + /// + /// + /// + internal void Arrange(ChartLayoutInfo layoutInfo) + { + Displayed = true; + + _ScrollOffset = layoutInfo.ScrollOffset; + + ArrangeOverride(layoutInfo); + } + + #endregion + + #region Render + + private int _RenderCount; + + /// + /// This method is used by the items internally to invoke the rendering + /// for the item. Override RenderOverride method to perform actual rendering. + /// + /// Holds contextual rendering information. + internal virtual void Render(ChartRenderInfo renderInfo) + { + if (Displayed == true && renderInfo.ClipRectangle.IntersectsWith(Bounds)) + { + RenderOverride(renderInfo); + + //Graphics g = renderInfo.Graphics; + + //using (StringFormat sf = new StringFormat()) + //{ + // sf.LineAlignment = StringAlignment.Center; + // sf.Alignment = StringAlignment.Center; + + // _RenderCount++; + + // g.DrawString(_RenderCount.ToString(), SystemFonts.CaptionFont, Brushes.Red, Bounds, sf); + //} + } + } + + #endregion + + #region CancelCapture + + /// + /// Cancels any inprogress operations that may + /// have the mouse captured (resize, reorder). + /// + public virtual void CancelCapture() + { + if (CapturedItem == this) + Capture = false; + } + + #endregion + + #region InvalidateRecalc + + internal virtual void InvalidateRecalc() + { + InvalidateLayout(); + } + + #endregion + + #region InvalidateLayout + + /// + /// Invalidates the layout for the item. + /// + public virtual void InvalidateLayout() + { + ChartControl control = ChartControl; + + if (control != null) + { + control.LayoutValid = false; + + if (control.InUpdateLayout == true) + control.PostInternalUpdate = true; + else + control.Invalidate(); + } + + OnLayoutInvalid(EventArgs.Empty); + } + + #endregion + + #region InvalidateRender + + /// + /// Invalidates the display state of the item + /// + public virtual void InvalidateRender() + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + { + if (chartControl.InvokeRequired) + chartControl.BeginInvoke(new MethodInvoker(delegate { chartControl.InvalidateRender(this); })); + else + chartControl.InvalidateRender(this); + } + + OnRenderInvalid(EventArgs.Empty); + } + + /// + /// Invalidates the display state of the item + /// + public virtual void InvalidateRender(Rectangle bounds) + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + chartControl.InvalidateRender(bounds); + + OnRenderInvalid(EventArgs.Empty); + } + + #endregion + + #region InvalidateLayoutBounds + + /// + /// Invalidates the layout bounds + /// + public virtual void InvalidateLayoutBounds(ScrollBarLite sbar) + { + ChartControl.LayoutBoundsItem = this; + } + + #endregion + + #region GetElementAt + + /// + /// Gets the visual chart element at the given Point. + /// + /// + /// + public virtual ChartVisualElement GetElementAt(Point pt) + { + return (null); + } + + #endregion + + #region GetHitArea + + /// + /// Gets the element Hit Area for the given Point. + /// + /// + /// + public virtual ItemHitArea GetHitArea(Point pt) + { + return (ItemHitArea.None); + } + + #endregion + + #region Mouse Handling + + #region OnMouseEnter + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual bool InternalMouseEnter(EventArgs e) + { + IsMouseOver = true; + + return (OnMouseEnter(e)); + } + + /// + /// Called when the mouse enters the element. + /// + /// + protected virtual bool OnMouseEnter(EventArgs e) + { + return (true); + } + + #endregion + + #region OnMouseLeave + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual bool InternalMouseLeave(EventArgs e) + { + IsMouseOver = false; + + return (OnMouseLeave(e)); + } + + /// + /// Called when mouse leaves the element. + /// + /// + protected virtual bool OnMouseLeave(EventArgs e) + { + return (true); + } + + #endregion + + #region OnMouseHover + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual bool InternalMouseHover(EventArgs e) + { + return (OnMouseHover(e)); + } + + /// + /// Called when mouse hovers over the element. + /// + /// + protected virtual bool OnMouseHover(EventArgs e) + { + return (false); + } + + #endregion + + #region OnMouseDown + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual bool InternalMouseDown(MouseEventArgs e) + { + MouseDownPoint = e.Location; + + bool handled = OnMouseDown(e); + + if (handled == false) + { + ChartVisualElement parent = Parent as ChartVisualElement; + + while (parent != null) + { + parent.OnMouseMoveEx(e); + + if (parent.OnMouseDownEx(e) == true) + return (true); + + parent = parent.Parent as ChartVisualElement; + } + } + + return (false); + } + + /// + /// Called when mouse button is pressed over the element. + /// + /// + protected virtual bool OnMouseDown(MouseEventArgs e) + { + return (true); + } + + /// + /// Called when mouse button is pressed over the element. + /// + /// + protected virtual bool OnMouseDownEx(MouseEventArgs e) + { + return (true); + } + + #endregion + + #region OnMouseUp + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual bool InternalMouseUp(MouseEventArgs e) + { + Capture = false; + + return (OnMouseUp(e)); + } + + /// + /// Called when mouse button is released over the element. + /// + /// + protected virtual bool OnMouseUp(MouseEventArgs e) + { + return (true); + } + + #endregion + + #region OnMouseMove + + /// + /// Called by top-level control to pass message into the chart + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual bool InternalMouseMove(MouseEventArgs e) + { + ChartVisualElement mouseOverElement = MouseOverElement; + + if (this != mouseOverElement) + { + if (mouseOverElement != null) + mouseOverElement.InternalMouseLeave(e); + + MouseOverElement = this; + + InternalMouseEnter(e); + } + + bool handled = OnMouseMove(e); + + ChartVisualElement parent = Parent as ChartVisualElement; + + while (parent != null) + { + if (handled == false) + handled = parent.OnMouseMove(e); + else + parent.OnMouseMoveEx(e); + + parent = parent.Parent as ChartVisualElement; + } + + return (false); + } + + /// + /// Called when mouse is moved over the element. + /// + /// + protected virtual bool OnMouseMove(MouseEventArgs e) + { + return (false); + } + + /// + /// Called when mouse is moved over the element. + /// + /// + protected virtual void OnMouseMoveEx(MouseEventArgs e) + { + } + + #endregion + + #region OnMouseClick + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual bool InternalMouseClick(MouseEventArgs e) + { + return (OnMouseClick(e)); + } + /// + /// Called when mouse is clicked on the element. + /// + /// + protected virtual bool OnMouseClick(MouseEventArgs e) + { + return (true); + } + + #endregion + + #region OnMouseDoubleClick + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual bool InternalMouseDoubleClick(MouseEventArgs e) + { + return (OnMouseDoubleClick(e)); + } + + /// + /// Called when mouse is double clicked on the element. + /// + /// + protected virtual bool OnMouseDoubleClick(MouseEventArgs e) + { + return (false); + } + + #endregion + + #region OnMouseWheel + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual bool InternalMouseWheel(MouseEventArgs e) + { + bool handled = OnMouseWheel(e); + + if (handled == false) + { + ChartVisualElement parent = Parent as ChartVisualElement; + + while (parent != null) + { + if (parent.OnMouseWheel(e) == true) + return (true); + + parent = parent.Parent as ChartVisualElement; + } + } + + return (false); + } + + /// + /// Called when mousewheel is moved while over the element. + /// + /// + protected virtual bool OnMouseWheel(MouseEventArgs e) + { + return (false); + } + + #endregion + + #endregion + + #region Keyboard handling + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalKeyDown(Keys keyData) + { + OnKeyDown(keyData); + } + + /// + /// Called when mouse button is pressed over the element. + /// + /// + protected virtual void OnKeyDown(Keys keyData) + { + } + + #endregion + + #region OnResize + + internal virtual bool InternalOnResize(EventArgs e) + { + return (OnResize(e)); + } + + /// + /// Called when control is resized. + /// + /// + protected virtual bool OnResize(EventArgs e) + { + return (true); + } + + #endregion + + #region OnVisualStyleChanged + + protected virtual void OnVisualStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + StyleVisualChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #endregion + + #region StyleVisualChangeHandler + + protected virtual void StyleVisualChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) + { + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + if (changeType == VisualChangeType.Layout) + InvalidateLayout(); + else + InvalidateRender(); + + if (ChartControl != null) + ChartControl.GlobalUpdateCount++; + } + + #endregion + + #endregion + + #region ApplyStyles + + public virtual void ApplyStyles(BaseVisualStyle style, StyleType cs) + { + } + + public virtual void ApplyStyles(BaseVisualStyle style) + { + } + + #endregion + + #region ApplyDefaults + + public virtual void ApplyDefaults(BaseVisualStyle style, StyleType cs) + { + } + + #endregion + + #region ClearEffectiveStyles + + protected virtual void ClearEffectiveStyles() + { } + + #endregion + + #region GetElementStyle + + public virtual void GetElementStyle( + IEffectiveStyle chartElement, StyleType styleType, ref BaseVisualStyle style) + { + ChartControl.DoGetElementStyleEvent(this, styleType, ref style); + } + + #endregion + + #region GetAdjustedBounds + + internal Rectangle GetAdjustedBounds(Rectangle bounds, Thickness thickness) + { + if (thickness.IsEmpty == false) + { + if (bounds.Height > Dpi.Height(thickness.Vertical)) + { + bounds.Y += Dpi.Height(thickness.Top); + bounds.Height -= Dpi.Height(thickness.Vertical); + } + + if (bounds.Width > Dpi.Width(thickness.Horizontal)) + { + bounds.X += Dpi.Width(thickness.Left); + bounds.Width -= Dpi.Width(thickness.Horizontal); + } + } + + return (bounds); + } + + #endregion + + #region GetScrollBounds + + internal Rectangle GetScrollBounds(Rectangle bounds) + { + bounds.X -= _ScrollOffset.X; + bounds.Y -= _ScrollOffset.Y; + + return (bounds); + } + + #endregion + + #region Export + + /// + /// Exports the chart element to the specified file. The + /// specified file will be created and/or overwritten. + /// + /// + /// + public void Export(string fileName) + { + string dir = Path.GetDirectoryName(fileName); + + if (dir != null) + { + if (Directory.Exists(dir) == false) + Directory.CreateDirectory(dir); + + using (FileStream stream = new + FileStream(fileName, FileMode.Create, FileAccess.ReadWrite)) + { + Export(stream); + } + } + } + + /// + /// Exports the chart element to the specified stream. + /// + /// + /// + public void Export(Stream stream) + { + CultureInfo cinfo = Thread.CurrentThread.CurrentCulture; + Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); + + SerialElementCollection sec = new SerialElementCollection(); + + sec = GetSerialData(""); + + using (StreamWriterNC sw = new StreamWriterNC(stream)) + { + sw.WriteLine(""); + + ExportData(sw, sec); + } + + Thread.CurrentThread.CurrentCulture = cinfo; + } + + #region ExportData + + private void ExportData(StreamWriterNC sw, SerialElementCollection sec) + { + foreach (SerialElement se in sec) + { + switch (se.SerType) + { + case SerElementType.Start: + sw.WriteLine("<" + se.Name + ">"); + break; + + case SerElementType.ValueStart: + sw.Write("<" + se.Name + ">"); + break; + + case SerElementType.Value: + sw.Write(se.GetValueString()); + break; + + case SerElementType.DataValue: + sw.Write(se.GetDataValueString()); + break; + + case SerElementType.End: + case SerElementType.ValueEnd: + sw.WriteLine(""); + break; + + case SerElementType.Collection: + ExportData(sw, se.Sec); + break; + } + } + } + + #endregion + + #endregion + + #region Import + + /// + /// Imoprts the chart element from the given file path. + /// + /// + /// + public void Import(string fileName) + { + if (File.Exists(fileName) == true) + { + using (FileStream stream = new + FileStream(fileName, FileMode.Open, FileAccess.Read)) + { + Import(stream); + } + } + } + + /// + /// Imoprts the chart element from the given stream. + /// + /// + /// + public void Import(Stream stream) + { + CultureInfo cinfo = Thread.CurrentThread.CurrentCulture; + Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); + + SerialElementCollection sec; + + stream.Position = 0; + + using (XmlReader reader = XmlReader.Create(stream)) + sec = ImportData(reader, 0); + + if (sec.Count > 0) + PutSerialData(sec); + + Thread.CurrentThread.CurrentCulture = cinfo; + } + + #region ImportData + + internal virtual SerialElementCollection ImportData(XmlReader reader, int depth) + { + SerialElementCollection sec = new SerialElementCollection(); + + string name = ""; + + bool read = depth > 0; + + int arrayCount = 0; + + while (read || reader.Read()) + { + read = false; + + switch (reader.NodeType) + { + case XmlNodeType.Element: + if (reader.Depth == depth) + { + if (reader.IsStartElement()) + { + SerialElement se = sec.AddStartElement(reader.Name); + + se.ArrayCount = GetArrayCount(reader); + + arrayCount = se.ArrayCount; + } + } + else if (reader.Depth > depth) + { + SerialElementCollection sec2 = ImportData(reader, reader.Depth); + + SerialElement se = sec.AddElement(sec2); + + se.ArrayCount = arrayCount; + + se.Name = reader.Name; + sec.Name = reader.Name; + + sec.AddEndElement(reader.Name); + } + + name = reader.Name; + break; + + case XmlNodeType.Text: + sec.AddValue(name, reader.Value); + break; + + case XmlNodeType.EndElement: + if (reader.Depth < depth) + return (sec); + + sec.AddEndElement(reader.Name); + break; + } + } + + return (sec); + } + + #region GetArrayCount + + private int GetArrayCount(XmlReader reader) + { + if (reader.HasAttributes == true) + { + string count = reader.GetAttribute("count"); + + if (count != null) + return (int.Parse(count)); + } + + return (0); + } + + #endregion + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + OnPropertyChanged(s); + + switch (changeType) + { + case VisualChangeType.Layout: + InvalidateLayout(); + break; + + case VisualChangeType.Recalc: + InvalidateRecalc(); + break; + + default: + InvalidateRender(); + break; + } + } + + protected void OnStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + StyleVisualChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #endregion + + #region IsDesignerHosted + + internal bool IsDesignerHosted + { + get + { + if (ChartControl != null) + return (ChartControl.DesignerHosted); + + return (false); + } + } + + #endregion + + #region ElementStates + + [Flags] + private enum Es + { + LayoutBoundsValid = (1 << 0), + LayoutValid = (1 << 1), + + MouseOver = (1 << 2), + Displayed = (1 << 3), + Visible = (1 << 4), + + NeedsMeasured = (1 << 5), + } + + #region TestState + + private bool TestState(Es state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(Es state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public virtual ChartVisualElement Copy() + { + return (null); + } + + public virtual void CopyTo(ChartVisualElement copy) + { + copy.Name = Name; + copy.Size = Size; + copy.Tag = Tag; + + copy.Visible = Visible; + } + + #endregion + + #region GetSerialData + + internal virtual SerialElementCollection GetSerialData(string serialName) + { + if ((String.IsNullOrEmpty(Name) == false) || (Tag != null) || (Visible == false)) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartElement"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("Name", Name, String.Empty); + sec.AddValue("Tag", Tag, null); + sec.AddValue("Visible", Visible, true); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + return (null); + } + + #endregion + + #region PutSerialData + + internal void PutSerialData(SerialElementCollection sec) + { + sec.PutSerialData(this); + } + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + ProcessValue(se); + } + + internal virtual void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Name": + Name = se.StringValue; + break; + + case "Tag": + Tag = se.DataValue; + break; + + case "Visible": + Visible = bool.Parse(se.StringValue); + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + ProcessCollection(se); + } + + internal virtual void ProcessCollection(SerialElement se) + { + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + + #endregion + + #endregion + } + + #region ItemHitArea + + /// + /// Specifies the ItemHitArea hit areas + /// + public enum ItemHitArea + { + /// + /// None + /// + None, + + /// + /// Ancillary AxisX + /// + InAncillaryAxisX, + + /// + /// Primary AxisX + /// + InPrimaryAxisX, + + /// + /// Ancillary AxisY + /// + InAncillaryAxisY, + + /// + /// Primary AxisX + /// + InPrimaryAxisY, + + /// + /// ScrollBar ArrowIncrease + /// + ArrowIncrease, + + /// + /// ScrollBar ArrowDecrease + /// + ArrowDecrease, + + /// + /// ScrollBar TrackIncrease + /// + TrackIncrease, + + /// + /// ScrollBar ArrowDecrease + /// + TrackDecrease, + + /// + /// ScrollBar Thumb + /// + Thumb, + + /// + /// Content area + /// + InContent, + + /// + /// Frame area + /// + InFrame, + + /// + /// PieSeriesPoint + /// + InPieSeriesPoint, + + /// + /// Pie Center + /// + InPieCenter, + + /// + /// Pie Ring Out (Out a ring level) + /// + InPieRingOut, + + /// + /// In Markup area + /// + InMarkup, + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartIndicator.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartIndicator.cs new file mode 100644 index 00000000..9cf4a84e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartIndicator.cs @@ -0,0 +1,1480 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of ChartIndicators. + /// + [Editor("DevComponents.Charts.Design.IndicatorCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartIndicatorCollection : CustomNamedCollection + { + } + + #region RegressionLine + + /// + /// Represents a Regression Line (a least-squares calculated series line). + /// + public class RegressionLine : ChartIndicator, IEffectiveStyle + { + #region Private variables + + private RegressionLineVisualStyle _RegressionLineVisualStyle; + private EffectiveStyle _EffectiveStyle; + + #endregion + + #region Constructors + + public RegressionLine(string name) + : this() + { + Name = name; + } + + public RegressionLine() + { + InitDefaultStates(); + + _EffectiveStyle = new EffectiveStyle(this); + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + } + + #endregion + + #region Public properties + + #region EffectiveStyle + + /// + /// Gets a reference to the RegressionLine's effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public RegressionLineVisualStyle EffectiveStyle + { + get { return (_EffectiveStyle.Style); } + } + + #endregion + + #region IndicatorType + + /// + /// Gets the RegressionLine's IndicatorType + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override ChartIndicatorType IndicatorType + { + get { return (ChartIndicatorType.RegressionLine); } + } + + #endregion + + #region RegressionLineVisualStyle + + /// + /// Gets or sets the visual style for the RegressionLine Indicator. + /// + [Category("Style")] + [Description("Indicates the visual style for the RegressionLine Indicator.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public RegressionLineVisualStyle RegressionLineVisualStyle + { + get + { + if (_RegressionLineVisualStyle == null) + { + _RegressionLineVisualStyle = new RegressionLineVisualStyle(); + + StyleVisualChangeHandler(null, _RegressionLineVisualStyle); + } + + return (_RegressionLineVisualStyle); + } + + set + { + if (_RegressionLineVisualStyle != value) + { + RegressionLineVisualStyle oldValue = _RegressionLineVisualStyle; + + _RegressionLineVisualStyle = value; + + OnStyleChanged("RegressionLineVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #endregion + + #region Style support + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + RegressionLineVisualStyle rstyle = style as RegressionLineVisualStyle; + + if (rstyle != null) + { + ApplyParentStyles(rstyle, Parent as ChartContainer); + + rstyle.ApplyStyle(RegressionLineVisualStyle); + + if (rstyle.LineWidth < 0) + rstyle.LineWidth = 1; + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles( + RegressionLineVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + ChartPanel panel = item as ChartPanel; + + if (panel != null) + pstyle.ApplyStyle(panel.DefaultVisualStyles.RegressionLineVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.RegressionLineVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.RegressionLineVisualStyle); + } + } + + #endregion + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Style + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + if (LegendItem != null) + LegendItem.EffectiveStyles.InvalidateStyles(); + } + + #endregion + + #region StyleChanged + + protected override void StyleChanged(object sender, PropertyChangedEventArgs e) + { + base.StyleChanged(sender, e); + + if (sender is ChartLegendItemVisualStyles && LegendItem != null) + InvalidateRender(LegendItem.Bounds); + } + + #endregion + + #endregion + + #region ILegendItem + + #region GetLegendItemColorEx + + protected override Color GetLegendItemColorEx() + { + RegressionLineVisualStyle rstyle = EffectiveStyle; + + return (rstyle.LineColor); + } + + #endregion + + #region RenderLegendItemMarkerEx + + protected override void RenderLegendItemMarkerEx(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + RegressionLineVisualStyle rstyle = EffectiveStyle; + + if (rstyle.LinePattern != LinePattern.None) + { + Rectangle bounds = litem.MarkerBounds; + + int n = bounds.Height / 2; + + int lineWidth = Math.Min(rstyle.LineWidth, bounds.Height); + + using (Pen pen = new Pen(GetLegendItemColor(), lineWidth)) + { + if (rstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)rstyle.LinePattern; + + g.DrawLine(pen, + new Point(bounds.X, bounds.Y + n), + new Point(bounds.Right - 1, bounds.Y + n)); + } + } + } + + #endregion + + #region GetLegendItemTextEx + + protected override string GetLegendItemTextEx() + { + return ("(RegLine)"); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + RegressionLine copy = new RegressionLine(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + RegressionLine c = copy as RegressionLine; + + if (c != null) + { + base.CopyTo(c); + + c.RegressionLineVisualStyle = + (_RegressionLineVisualStyle != null) ? RegressionLineVisualStyle.Copy() : null; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "RegressionLine"; + + sec.AddStartElement(serialName); + } + + if (_RegressionLineVisualStyle != null && _RegressionLineVisualStyle.IsEmpty == false) + sec.AddElement(_RegressionLineVisualStyle.GetSerialData("RegressionLineVisualStyle")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "RegressionLineVisualStyle": + sec.PutSerialData(RegressionLineVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + RegressionLineVisualStyle = null; + + base.Dispose(); + } + + #endregion + } + + #endregion + + #region TrendLine + + /// + /// Represents a Trend Line (a line connecting any 2 defined SeriesPoints). + /// + public class TrendLine : ChartIndicator, IEffectiveStyle + { + #region Private variables + + private object _ValueX1; + private object _ValueX2; + + private TrendLineVisualStyle _TrendLineVisualStyle; + private EffectiveStyle _EffectiveStyle; + + #endregion + + #region Constructors + + /// + /// TrendLine + /// + public TrendLine() + { + InitDefaultStates(); + + _EffectiveStyle = new EffectiveStyle(this); + } + + #region Constructors + + /// + /// TrendLine + /// + /// Name + public TrendLine(string name) + : this() + { + Name = name; + } + + /// + /// TrendLine + /// + /// Name + /// Starting X-Axis value + /// Ending X-Axis value + public TrendLine(string name, object valuex1, object valuex2) + : this(name) + { + ValueX1 = valuex1; + ValueX2 = valuex2; + } + + #endregion + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + } + + #endregion + + #region Public properties + + #region EffectiveStyles + + /// + /// Gets a reference to the TrendLine's effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TrendLineVisualStyle EffectiveStyle + { + get { return (_EffectiveStyle.Style); } + } + + #endregion + + #region IndicatorType + + /// + /// Gets the TrendLine's IndicatorType + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override ChartIndicatorType IndicatorType + { + get { return (ChartIndicatorType.TrendLine); } + } + + #endregion + + #region TrendLineVisualStyle + + /// + /// Gets or sets the visual style for the TrendLine Indicator. + /// + [Category("Style")] + [Description("Indicates the visual style for the TrendLine Indicator.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TrendLineVisualStyle TrendLineVisualStyle + { + get + { + if (_TrendLineVisualStyle == null) + { + _TrendLineVisualStyle = new TrendLineVisualStyle(); + + StyleVisualChangeHandler(null, _TrendLineVisualStyle); + } + + return (_TrendLineVisualStyle); + } + + set + { + if (_TrendLineVisualStyle != value) + { + TrendLineVisualStyle oldValue = _TrendLineVisualStyle; + + _TrendLineVisualStyle = value; + + OnStyleChanged("TrendLineVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ValueX1 + + /// + /// Trendline starting X value + /// + [Category("Data")] + [Description("Indicates the Trendline starting X value.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter," + + "DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object ValueX1 + { + get { return (_ValueX1); } + set { _ValueX1 = value; } + } + + #endregion + + #region ValueX2 + + /// + /// Trendline ending X value + /// + [Category("Data")] + [Description("Indicates the Trendline ending X value.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter," + + "DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object ValueX2 + { + get { return (_ValueX2); } + set { _ValueX2 = value; } + } + + #endregion + + #endregion + + #region Style support + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + TrendLineVisualStyle tstyle = style as TrendLineVisualStyle; + + if (tstyle != null) + { + ApplyParentStyles(tstyle, Parent as ChartContainer); + + tstyle.ApplyStyle(TrendLineVisualStyle); + + if (tstyle.LineWidth < 0) + tstyle.LineWidth = 1; + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles( TrendLineVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is ChartPanel) + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.TrendLineVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.TrendLineVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.TrendLineVisualStyle); + } + } + + #endregion + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Style + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + if (LegendItem != null) + LegendItem.EffectiveStyles.InvalidateStyles(); + } + + #endregion + + #region StyleChanged + + protected override void StyleChanged(object sender, PropertyChangedEventArgs e) + { + base.StyleChanged(sender, e); + + if (sender is ChartLegendItemVisualStyles && LegendItem != null) + InvalidateRender(LegendItem.Bounds); + } + + #endregion + + #endregion + + #region ILegendItem + + #region GetLegendItemColorEx + + protected override Color GetLegendItemColorEx() + { + TrendLineVisualStyle tstyle = EffectiveStyle; + + return (tstyle.LineColor); + } + + #endregion + + #region RenderLegendItemMarkerEx + + protected override void RenderLegendItemMarkerEx(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + TrendLineVisualStyle tstyle = EffectiveStyle; + + if (tstyle.LinePattern != LinePattern.None) + { + Rectangle bounds = litem.MarkerBounds; + + int n = bounds.Height / 2; + + int lineWidth = Math.Min(tstyle.LineWidth, bounds.Height); + + using (Pen pen = new Pen(GetLegendItemColor(), lineWidth)) + { + if (tstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)tstyle.LinePattern; + + g.DrawLine(pen, + new Point(bounds.X, bounds.Y + n), + new Point(bounds.Right - 1, bounds.Y + n)); + } + } + } + + #endregion + + #region GetLegendItemTextEx + + protected override string GetLegendItemTextEx() + { + return ("(TrendLine)"); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + TrendLine copy = new TrendLine(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + TrendLine c = copy as TrendLine; + + if (c != null) + { + base.CopyTo(c); + + c.TrendLineVisualStyle = + (_TrendLineVisualStyle != null) ? TrendLineVisualStyle.Copy() : null; + + c.ValueX1 = ValueX1; + c.ValueX2 = ValueX2; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "TrendLine"; + + sec.AddStartElement(serialName); + } + + if (_TrendLineVisualStyle != null && _TrendLineVisualStyle.IsEmpty == false) + sec.AddElement(_TrendLineVisualStyle.GetSerialData("TrendLineVisualStyle")); + + sec.AddDataValue("ValueX1", ValueX1, null); + sec.AddDataValue("ValueX2", ValueX2, null); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "ValueX1": + ValueX1 = se.DataValue; + break; + + case "ValueX2": + ValueX2 = se.DataValue; + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "TrendLineVisualStyle": + sec.PutSerialData(TrendLineVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + TrendLineVisualStyle = null; + + base.Dispose(); + } + + #endregion + } + + #endregion + + public abstract class ChartIndicator : ChartVisualElement, ILegendItem + { + #region Private variables + + private States _States; + + private string _LegendText; + private ChartLegendItem _LegendItem; + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + + private int _ValueYIndex; + + #endregion + + public ChartIndicator() + { + InitDefaultStates(); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.CheckedInLegend, true); + SetState(States.ShowInLegend, true); + SetState(States.ShowInParentLegend, true); + SetState(States.ShowCheckBoxInLegend, true); + SetState(States.ShowMarkerInLegend, true); + } + + #endregion + + #region Public properties + + #region DisplayOnTop + + /// + /// Gets or sets whether Indicator is displayed on top of chart data. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether Indicator is displayed on top of chart data.")] + public bool DisplayOnTop + { + get { return (TestState(States.DisplayOnTop)); } + + set + { + if (value != DisplayOnTop) + { + SetState(States.DisplayOnTop, value); + + OnPropertyChangedEx("DisplayOnTop", VisualChangeType.Render); + } + } + } + + #endregion + + #region IndicatorType + + /// + /// Indicator type + /// + public virtual ChartIndicatorType IndicatorType + { + get { throw new NotImplementedException(); } + } + + #endregion + + #region Intercept + + /// + /// Gets the Indicator Line's Intercept (ie. the 'b' portion of 'y = mx + b'). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double Intercept + { + get + { + ChartSeries series = Parent as ChartSeries; + + if (series == null) + throw new Exception("Indicator Line not associated with a ChartSeries."); + + ChartXy chartXy = series.Parent as ChartXy; + + if (chartXy == null) + throw new Exception("Indicator Line not associated with a ChartXy."); + + SortedSeriesPoints ssp = series.GetSortedSeriesPoints(chartXy); + + ssp.SlopeIndex = ValueYIndex; + + return (ssp.Intercept); + } + } + + #endregion + + #region IsDisplayed + + /// + /// Gets whether the Indicator is displayed. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDisplayed + { + get + { + return ((Visible == true) && + (ShowCheckBoxInLegend == false || CheckedInLegend == true)); + } + } + + #endregion + + #region Slope + + /// + /// Gets the Indicator Line's Slope (ie. the 'm' portion of 'y = mx + b'). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double Slope + { + get + { + ChartSeries series = Parent as ChartSeries; + + if (series == null) + throw new Exception("Indicator Line not associated with a ChartSeries."); + + ChartXy chartXy = series.Parent as ChartXy; + + if (chartXy == null) + throw new Exception("Indicator Line not associated with a ChartXy."); + + SortedSeriesPoints ssp = series.GetSortedSeriesPoints(chartXy); + + ssp.SlopeIndex = ValueYIndex; + + return (ssp.Slope); + } + } + + #endregion + + #region ValueYIndex + + /// + /// Gets or sets the ValueY index to use for the slope/intercept. + /// + [DefaultValue(0), Category("Appearance")] + [Description("Indicates the ValueY index to use for the slope/intercept.")] + public int ValueYIndex + { + get { return (_ValueYIndex); } + + set + { + if (value != _ValueYIndex) + { + _ValueYIndex = value; + + OnPropertyChangedEx("ValueYIndex", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + } + + #endregion + + #region ILegendItem + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the visual styles for the Legend item. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Legend item.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleVisualChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (_ChartLegendItemVisualStyles != value) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CheckedInLegend + + /// + /// Gets or sets whether the Line is checked in the Legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the Line is checked in the Legend.")] + public bool CheckedInLegend + { + get { return (TestState(States.CheckedInLegend)); } + + set + { + if (value != CheckedInLegend) + { + SetState(States.CheckedInLegend, value); + + if (LegendItem != null) + LegendItem.UpdateCheckState(); + + OnPropertyChangedEx("CheckedInLegend", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowCheckBoxInLegend + + /// + /// Gets or sets whether a checkbox for the Line is shown in the Legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether a checkbox for the Line is shown in the Legend.")] + public bool ShowCheckBoxInLegend + { + get { return (TestState(States.ShowCheckBoxInLegend)); } + + set + { + if (value != ShowCheckBoxInLegend) + { + SetState(States.ShowCheckBoxInLegend, value); + + OnPropertyChangedEx("ShowCheckBoxInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInLegend + + /// + /// Gets or sets whether the Line is shown in the Legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether theLine is shown in the Legend.")] + public bool ShowInLegend + { + get { return (TestState(States.ShowInLegend)); } + + set + { + if (value != ShowInLegend) + { + SetState(States.ShowInLegend, value); + + OnPropertyChangedEx("ShowInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInParentLegend + + /// + /// Gets or sets whether the Line is shown in parent Legend(s). + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the Line is shown in parent Legend(s).")] + public bool ShowInParentLegend + { + get { return (TestState(States.ShowInParentLegend)); } + + set + { + if (value != ShowInParentLegend) + { + SetState(States.ShowInParentLegend, value); + + OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowMarkerInLegend + + /// + /// Gets or sets whether the Line Marker is shown in the Legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the Line Marker is shown in the Legend.")] + public bool ShowMarkerInLegend + { + get { return (TestState(States.ShowMarkerInLegend)); } + + set + { + if (value != ShowMarkerInLegend) + { + SetState(States.ShowMarkerInLegend, value); + + OnPropertyChangedEx("ShowMarkerInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LegendItem + + /// + /// Gets the item's parent LegendItem. + /// + [Description("Indicates the item's parent LegendItem.")] + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartLegendItem LegendItem + { + get { return (_LegendItem); } + + internal set + { + if (_LegendItem != null) + _LegendItem.Dispose(); + + _LegendItem = value; + } + } + + #endregion + + #region LegendText + + /// + /// Gets or sets the text to display in the legend. + /// + [DefaultValue(null), Category("DataLabel")] + [Description("Indicates the text to display in the legend.")] + public string LegendText + { + get { return (_LegendText); } + + set + { + if (value != _LegendText) + { + _LegendText = value; + + OnPropertyChangedEx("LegendText", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region GetLegendItem + + public ChartLegendItem GetLegendItem() + { + LegendItem = null; + + if (ShowInLegend == true) + { + LegendItem = new ChartLegendItem(); + + if (CheckedInLegend == true) + _LegendItem.CheckState = CheckState.Checked; + + _LegendItem.Name = Name; + _LegendItem.ItemText = LegendText; + + if (string.IsNullOrEmpty(Name) == true && + string.IsNullOrEmpty(_LegendItem.ItemText) == true) + { + _LegendItem.ItemText = GetLegendItemTextEx(); + } + + _LegendItem.ChartItems.Add(this); + } + + return (_LegendItem); + } + + protected virtual string GetLegendItemTextEx() + { + return ("(IndLine)"); + } + + #endregion + + #region GetLegendItems + + public List GetLegendItems() + { + List list = new List(1); + + list.Add(GetLegendItem()); + + return (list); + } + + #endregion + + #region GetLegendItemColor + + public Color GetLegendItemColor() + { + Color color = GetLegendItemColorEx(); + + if (color.IsEmpty == true) + { + ChartSeries series = Parent as ChartSeries; + + if (series != null) + color = series.DefaultPaletteColor; + } + + return (color); + } + + protected virtual Color GetLegendItemColorEx() + { + return (Color.Empty); + } + + #endregion + + #region RenderLegendItemMarker + + public void RenderLegendItemMarker(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + RenderLegendItemMarkerEx(g, litem, style); + } + + protected virtual void RenderLegendItemMarkerEx(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + } + + #endregion + + #endregion + + #region CopyTo + + public override void CopyTo(ChartVisualElement copy) + { + ChartIndicator c = copy as ChartIndicator; + + if (c != null) + { + base.CopyTo(c); + + c.ChartLegendItemVisualStyles = + (_ChartLegendItemVisualStyles != null) ? ChartLegendItemVisualStyles.Copy() : null; + + c.CheckedInLegend = CheckedInLegend; + c.LegendText = LegendText; + c.ShowCheckBoxInLegend = ShowCheckBoxInLegend; + c.ShowInLegend = ShowInLegend; + c.ShowInParentLegend = ShowInParentLegend; + c.ShowMarkerInLegend = ShowMarkerInLegend; + c.DisplayOnTop = DisplayOnTop; + c.ValueYIndex = _ValueYIndex; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartIndicator"; + + sec.AddStartElement(serialName); + } + + if (_ChartLegendItemVisualStyles != null) + sec.AddElement(_ChartLegendItemVisualStyles.GetSerialData("ChartLegendItemVisualStyles")); + + sec.AddValue("DisplayOnTop", DisplayOnTop, false); + + sec.AddValue("CheckedInLegend", CheckedInLegend, true); + sec.AddValue("LegendText", LegendText, null); + sec.AddValue("ShowCheckBoxInLegend", ShowCheckBoxInLegend, true); + sec.AddValue("ShowInLegend", ShowInLegend, true); + sec.AddValue("ShowInParentLegend", ShowInParentLegend, true); + sec.AddValue("ShowMarkerInLegend", ShowMarkerInLegend, true); + + sec.AddValue("ValueYIndex", _ValueYIndex, 0); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "CheckedInLegend": + CheckedInLegend = bool.Parse(se.StringValue); + break; + + case "DisplayOnTop": + DisplayOnTop = bool.Parse(se.StringValue); + break; + + case "LegendText": + LegendText = se.StringValue; + break; + + case "ShowCheckBoxInLegend": + ShowCheckBoxInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInLegend": + ShowInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInParentLegend": + ShowInParentLegend = bool.Parse(se.StringValue); + break; + + case "ShowMarkerInLegend": + ShowMarkerInLegend = bool.Parse(se.StringValue); + break; + + case "ValueYIndex": + ValueYIndex = int.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartLegendItemVisualStyles": + sec.PutSerialData(ChartLegendItemVisualStyles); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + CheckedInLegend = (1U << 1), + ShowCheckBoxInLegend = (1U << 2), + ShowInLegend = (1U << 3), + ShowInParentLegend = (1U << 4), + ShowMarkerInLegend = (1U << 5), + DisplayOnTop = (1U << 6), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + } + + #region enums + + #region ChartIndicatorType + + public enum ChartIndicatorType + { + TrendLine, + RegressionLine, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLable.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLable.cs new file mode 100644 index 00000000..9ef8acdd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLable.cs @@ -0,0 +1,261 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// ChartAxisLable + /// + public class ChartAxisLable : ChartVisualElement + { + #region Private variables + + private States _States; + + private string _Text; + private int _FixedHeight; + + #endregion + + #region Public properties + + #region FixedHeight + + /// + /// Gets or sets the fixed Text height of the label (0 to auto-size) + /// + [DefaultValue(0), Category("Layout")] + [Description("Indicates the fixed Text height of the label (0 to auto-size)")] + public int FixedHeight + { + get { return (_FixedHeight); } + + set + { + if (value != _FixedHeight) + { + _FixedHeight = value; + + OnPropertyChangedEx("FixedHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Text + + /// + /// Gets or sets the label Text. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the label Text.")] + public string Text + { + get { return (_Text); } + + set + { + _Text = value; + + OnPropertyChangedEx("Text", VisualChangeType.Layout); + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + throw new NotImplementedException(); + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + throw new NotImplementedException(); + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + throw new NotImplementedException(); + } + + #endregion + + #region Mouse handling + + #region OnMouseEnter + + protected override bool OnMouseEnter(EventArgs e) + { + return (true); + } + + #endregion + + #region OnMouseLeave + + protected override bool OnMouseLeave(EventArgs e) + { + return (true); + } + + #endregion + + #region OnMouseMove + + protected override bool OnMouseMove(MouseEventArgs e) + { + ChartCursor = Cursors.Default; + + return (false); + } + + #endregion + + #region OnMouseDown + + protected override bool OnMouseDown(MouseEventArgs e) + { + return (false); + } + + #endregion + + #region OnMouseUp + + protected override bool OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + return (true); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartAxisLable copy = new ChartAxisLable(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartAxisLable c = copy as ChartAxisLable; + + if (c != null) + { + base.CopyTo(c); + + c.FixedHeight = FixedHeight; + c.Text = Text; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "BaseChart"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("FixedHeight", FixedHeight, 0); + sec.AddValue("Text", Text, null); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "FixedHeight": + FixedHeight = int.Parse(se.StringValue); + break; + + case "Text": + Text = se.StringValue; + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + EnableTextMarkup = (1U << 0), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLayoutInfo.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLayoutInfo.cs new file mode 100644 index 00000000..b3339a1d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLayoutInfo.cs @@ -0,0 +1,30 @@ +using DevComponents.DotNetBar.Charts.Style; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Provides the layout information for chart layout pass + /// + public class ChartLayoutInfo + { + #region Public variables + + public Graphics Graphics; + + public Rectangle ClientBounds; + public Rectangle LayoutBounds; + + public Point ScrollOffset; + + public bool LayoutBoundsAdjusted; + + #endregion + + public ChartLayoutInfo(Graphics graphics, Rectangle clientBounds) + { + Graphics = graphics; + ClientBounds = clientBounds; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLegend.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLegend.cs new file mode 100644 index 00000000..3d7a2902 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLegend.cs @@ -0,0 +1,2793 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartLegend : ChartVisualElement, IScrollable + { + #region Private variables + + private States _States; + + private Alignment _Alignment = Alignment.NotSet; + private Placement _Placement = Placement.NotSet; + private Direction _Direction = Direction.NotSet; + + private ChartLegendVisualStyles _ChartLegendVisualStyles; + private EffectiveStyles _EffectiveStyles; + + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + private EffectiveStyles _EffectiveItemStyles; + + private Rectangle _FrameBounds; + private Rectangle _ContentBounds; + private Rectangle _ContentBoundsEx; + + private bool _LegendMeasured; + + private double _MaxHorizontalPct = 100d; + private double _MaxVerticalPct = 100d; + + private Size _CheckBoxSize = new Size(15, 15); + private Size _MarkerSize = new Size(15, 15); + private Size _MinContentSize = new Size(15, 15); + + private Tbool _ShowPieSeriesCheckBoxes = Tbool.NotSet; + private Tbool _ShowPieRingCheckBoxes = Tbool.NotSet; + private Tbool _ShowPieSeriesPointCheckBoxes = Tbool.NotSet; + + private int _ItemTextOffset = 2; + + private List _LegendItems; + + private ScrollBarLite _VScrollBar; + private int _VScrollBarWidth = 9; + + private bool _Panning; + private int _VPanOffset; + + private LegendArea _HitArea; + + private SortDirection _ItemSortDirection = SortDirection.None; + private ItemCheckAction _ItemCheckAction = ItemCheckAction.ShowItem; + + private PointMarker _PointMarker; + + private LegendTrackingMode _TrackingMode = LegendTrackingMode.NotSet; + + #endregion + + public ChartLegend() + { + InitDefaultStates(); + + _EffectiveStyles = new EffectiveStyles(this); + _EffectiveItemStyles = new EffectiveStyles(this); + + SetupScrollBars(); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.CombineLikeItems, true); + SetState(States.EnablePanning, true); + SetState(States.ShowItemText, true); + SetState(States.ShowMarkers, true); + SetState(States.ShowPieSeriesInLegend, true); + SetState(States.ShowPieSeriesPointsInLegend, true); + SetState(States.VScrollBarVisible, true); + } + + #endregion + + #region Public properties + + #region Alignment + + /// + /// Gets or sets the Alignment of the legend with respect to the chart. + /// + [DefaultValue(Alignment.NotSet), Category("Layout")] + [Description("Indicates the Alignment of the legend with respect to the chart.")] + public Alignment Alignment + { + get { return (_Alignment); } + + set + { + if (_Alignment != value) + { + _Alignment = value; + + OnPropertyChangedEx("Alignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AlignVerticalItems + + /// + /// Gets or sets whether vertical items are aligned in the legend + /// (used when multiple columns are presented). + /// + [DefaultValue(false), Category("Layout")] + [Description("Indicates whether vertical items are aligned in the legend (used when multiple columns are presented).")] + public bool AlignVerticalItems + { + get { return (TestState(States.AlignVerticalItems)); } + + set + { + if (value != AlignVerticalItems) + { + SetState(States.AlignVerticalItems, value); + + OnPropertyChangedEx("AlignVerticalItems", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the default visual styles for Legend items. + /// + [Category("Style")] + [Description("Indicates the default visual styles for Legend items.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleVisualChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (_ChartLegendItemVisualStyles != value) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ChartLegendVisualStyles + + /// + /// Gets or sets the visual styles for the Legend. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Legend.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendVisualStyles ChartLegendVisualStyles + { + get + { + if (_ChartLegendVisualStyles == null) + { + _ChartLegendVisualStyles = new ChartLegendVisualStyles(); + + StyleVisualChangeHandler(null, _ChartLegendVisualStyles); + } + + return (_ChartLegendVisualStyles); + } + + set + { + if (_ChartLegendVisualStyles != value) + { + ChartLegendVisualStyles oldValue = _ChartLegendVisualStyles; + + _ChartLegendVisualStyles = value; + + OnStyleChanged("ChartLegendVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CheckBoxSize + + /// + /// Gets or sets the default size of the item CheckBoxes. + /// + [Category("Appearance")] + [Description("Indicates the default size of the item CheckBoxes.")] + public Size CheckBoxSize + { + get { return (_CheckBoxSize); } + + set + { + if (value != _CheckBoxSize) + { + _CheckBoxSize = value; + + OnPropertyChangedEx("CheckBoxSize", VisualChangeType.Layout); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeCheckBoxSize() + { + return (_CheckBoxSize != new Size(15, 15)); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetCheckBoxSize() + { + CheckBoxSize = new Size(15, 15); + } + + #endregion + + #region CombineLikeItems + + /// + /// Gets or sets whether 'like' subordinate items + /// (items with same Names) are combined into a single item. + /// + [DefaultValue(true), Category("Layout")] + [Description("Indicates whether 'like' subordinate items (items with same Names) are combined into a single item.")] + public bool CombineLikeItems + { + get { return (TestState(States.CombineLikeItems)); } + + set + { + if (value != CombineLikeItems) + { + SetState(States.CombineLikeItems, value); + + OnPropertyChangedEx("CombineLikeItems", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Direction + + /// + /// Gets or sets the display direction of the items within the legend. + /// + [DefaultValue(Direction.NotSet), Category("Layout")] + [Description("Indicates the display direction of the items within the legend.")] + public Direction Direction + { + get { return (_Direction); } + + set + { + if (_Direction != value) + { + _Direction = value; + + OnPropertyChangedEx("Direction", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EffectiveItemStyles + + /// + /// Gets a reference to the legend's item Effective (cached, composite) styles. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public EffectiveStyles EffectiveItemStyles + { + get { return (_EffectiveItemStyles); } + } + + #endregion + + #region EffectiveStyles + + /// + /// Gets a reference to the legend's Effective (cached, composite) styles. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public EffectiveStyles EffectiveStyles + { + get { return (_EffectiveStyles); } + } + + #endregion + + #region EnablePanning + + /// + /// Gets or sets whether the legend can be panned with the mouse. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the legend can be panned with the mouse.")] + public bool EnablePanning + { + get { return (TestState(States.EnablePanning)); } + + set + { + if (value != EnablePanning) + { + SetState(States.EnablePanning, value); + + OnPropertyChanged("EnablePanning"); + } + } + } + + #endregion + + #region ItemCheckAction + + /// + /// Gets or sets the "action" taken when a LegendItem is checked. + /// + [DefaultValue(ItemCheckAction.ShowItem), Category("Behavior")] + [Description("Indicates the series sort direction (LegendItem Name).")] + public ItemCheckAction ItemCheckAction + { + get { return (_ItemCheckAction); } + + set + { + if (_ItemCheckAction != value) + { + _ItemCheckAction = value; + + OnPropertyChanged("ItemCheckAction"); + } + } + } + + #endregion + + #region ItemSortDirection + + /// + /// Gets or sets the item sort direction (LegendItem Text) + /// + [DefaultValue(SortDirection.None), Category("Appearance")] + [Description("Indicates the series sort direction (LegendItem Text).")] + public SortDirection ItemSortDirection + { + get { return (_ItemSortDirection); } + + set + { + if (_ItemSortDirection != value) + { + _ItemSortDirection = value; + + OnPropertyChanged("ItemSortDirection"); + } + } + } + + #endregion + + #region ItemTextOffset + + /// + /// Gets or sets the offset between the marker (or Checkbox) and the item text. + /// + [DefaultValue(2), Category("Layout")] + [Description("Indicates the offset between the marker (or Checkbox) and the item text.")] + public int ItemTextOffset + { + get { return (_ItemTextOffset); } + + set + { + if (value != _ItemTextOffset) + { + if ((uint)value > 1000) + throw new ArgumentOutOfRangeException("value", "Must be between 0 and 1000."); + + _ItemTextOffset = value; + + OnPropertyChangedEx("ItemTextOffset", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LegendItems + + /// + /// Gets the collection of LegendItems. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public List LegendItems + { + get + { + if (_LegendItems == null) + _LegendItems = new List(); + + return (_LegendItems); + } + + internal set { _LegendItems = value; } + } + + #endregion + + #region MarkerSize + + /// + /// Gets or sets the default size of the item marker. + /// + [Category("Appearance")] + [Description("Indicates the default size of the item marker.")] + public Size MarkerSize + { + get { return (_MarkerSize); } + + set + { + if (value != _MarkerSize) + { + _MarkerSize = value; + + OnPropertyChangedEx("MarkerSize", VisualChangeType.Layout); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeMarkerSize() + { + return (_MarkerSize != new Size(15, 15)); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetMarkerSize() + { + MarkerSize = new Size(15, 15); + } + + #endregion + + #region MaxHorizontalPct + + /// + /// Gets or sets the maximum horizontal size of the legend when autosizing. The value + /// is specified as a percentage of the displayed chart size. + /// + [DefaultValue(100d), Category("Layout")] + [Description("Indicates the maximum horizontal size of the legend when autosizing. The value is specified as a percentage of the displayed chart size.")] + public double MaxHorizontalPct + { + get { return (_MaxHorizontalPct); } + + set + { + if (value != _MaxHorizontalPct) + { + if ((uint)value > 100) + throw new ArgumentOutOfRangeException("value", "Must be between 0 and 100 percent."); + + _MaxHorizontalPct = value; + + OnPropertyChangedEx("MaxHorizontalPct", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxVerticalPct + + /// + /// Gets or sets the maximum vertical size of the legend when autosizing. The value + /// is specified as a percentage of the displayed chart size. + /// + [DefaultValue(100d), Category("Layout")] + [Description("Indicates the maximum vertical size of the legend when autosizing. The value is specified as a percentage of the displayed chart size.")] + public double MaxVerticalPct + { + get { return (_MaxVerticalPct); } + + set + { + if (value != _MaxVerticalPct) + { + if ((uint)value > 100) + throw new ArgumentOutOfRangeException("value", "Must be between 0 and 100 percent."); + + _MaxVerticalPct = value; + + OnPropertyChangedEx("MaxVerticalPct", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinContentSize + + /// + /// Gets or sets the minimum size of the content area of the legend. + /// + [Category("Layout")] + [Description("Indicates the minimum size of the content area of the legend.")] + public Size MinContentSize + { + get { return (_MinContentSize); } + + set + { + if (value != _MinContentSize) + { + _MinContentSize = value; + + OnPropertyChangedEx("MinContentSize", VisualChangeType.Layout); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeMinContentSize() + { + return (_MinContentSize.Width != 15 || _MinContentSize.Height != 15); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + private void ResetMinContentSize() + { + MinContentSize = new Size(15, 15); + } + + #endregion + + #region Placement + + /// + /// Gets or sets the placement of the legend with respect to the chart. + /// + [DefaultValue(Placement.NotSet), Category("Layout")] + [Description("Indicates the placement of the legend with respect to the chart.")] + public Placement Placement + { + get { return (_Placement); } + + set + { + if (_Placement != value) + { + _Placement = value; + + OnPropertyChangedEx("Placement", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ScrollBounds + + /// + /// Gets the Scrollable bounds of the legend. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual Rectangle ScrollBounds + { + get { return (_ContentBounds); } + } + + #endregion + + #region ScrollBoundsEx + + /// + /// Gets the Extended Scrollable bounds of the legend. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual Rectangle ScrollBoundsEx + { + get { return (_ContentBoundsEx); } + } + + #endregion + + #region ScrollBoundsOffset + + /// + /// Gets the current scrollbar offset + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Point ScrollBoundsOffset + { + get { return (new Point(0, VScrollOffset)); } + } + + #endregion + + #region ShowCheckBoxes + + /// + /// Gets or sets whether checkboxes are shown in the legend. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether checkboxes are shown in the legend.")] + public bool ShowCheckBoxes + { + get { return (TestState(States.ShowCheckBoxes)); } + + set + { + if (value != ShowCheckBoxes) + { + SetState(States.ShowCheckBoxes, value); + + OnPropertyChangedEx("ShowCheckBoxes", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowItemText + + /// + /// Gets or sets whether item text values are shown in the legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether item text values are shown in the legend.")] + public bool ShowItemText + { + get { return (TestState(States.ShowItemText)); } + + set + { + if (value != ShowItemText) + { + SetState(States.ShowItemText, value); + + OnPropertyChangedEx("ShowItemText", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowMarkers + + /// + /// Gets or sets whether markers are shown in the legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether markers are shown in the legend.")] + public bool ShowMarkers + { + get { return (TestState(States.ShowMarkers)); } + + set + { + if (value != ShowMarkers) + { + SetState(States.ShowMarkers, value); + + OnPropertyChangedEx("ShowMarkers", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowPieRingCheckBoxes + + /// + /// Gets or sets whether PieRing checkboxes are shown in the legend. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether PieRing checkboxes are shown in the legend.")] + public Tbool ShowPieRingCheckBoxes + { + get { return (_ShowPieRingCheckBoxes); } + + set + { + if (value != _ShowPieRingCheckBoxes) + { + _ShowPieRingCheckBoxes = value; + + OnPropertyChangedEx("ShowPieRingCheckBoxes", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowPieRingsInLegend + + /// + /// Gets or sets whether PieRings are shown in the Legend. + /// + [DefaultValue(false), Category("Legend")] + [Description("Indicates whether Pie Series are shown in the Legend.")] + public bool ShowPieRingsInLegend + { + get { return (TestState(States.ShowPieRingsInLegend)); } + + set + { + if (value != ShowPieRingsInLegend) + { + SetState(States.ShowPieRingsInLegend, value); + + OnPropertyChangedEx("ShowPieRingsInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowPieSeriesCheckBoxes + + /// + /// Gets or sets whether PieRing checkboxes are shown in the legend. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether PieRing checkboxes are shown in the legend.")] + public Tbool ShowPieSeriesCheckBoxes + { + get { return (_ShowPieSeriesCheckBoxes); } + + set + { + if (value != _ShowPieSeriesCheckBoxes) + { + _ShowPieSeriesCheckBoxes = value; + + OnPropertyChangedEx("ShowPieSeriesCheckBoxes", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowPieSeriesInLegend + + /// + /// Gets or sets whether Pie Series are shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether Pie Series are shown in the Legend.")] + public bool ShowPieSeriesInLegend + { + get { return (TestState(States.ShowPieSeriesInLegend)); } + + set + { + if (value != ShowPieSeriesInLegend) + { + SetState(States.ShowPieSeriesInLegend, value); + + OnPropertyChangedEx("ShowPieSeriesInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowPieSeriesPointCheckBoxes + + /// + /// Gets or sets whether PieSeriesPoint checkboxes are shown in the legend. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether PieSeriesPoint checkboxes are shown in the legend.")] + public Tbool ShowPieSeriesPointCheckBoxes + { + get { return (_ShowPieSeriesPointCheckBoxes); } + + set + { + if (value != _ShowPieSeriesPointCheckBoxes) + { + _ShowPieSeriesPointCheckBoxes = value; + + OnPropertyChangedEx("ShowPieSeriesPointCheckBoxes", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowPieSeriesPointsInLegend + + /// + /// Gets or sets whether Pie Series are shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether Pie Series are shown in the Legend.")] + public bool ShowPieSeriesPointsInLegend + { + get { return (TestState(States.ShowPieSeriesPointsInLegend)); } + + set + { + if (value != ShowPieSeriesPointsInLegend) + { + SetState(States.ShowPieSeriesPointsInLegend, value); + + OnPropertyChangedEx("ShowPieSeriesPointsInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TrackingMode + + /// + /// Gets or sets the tracking mode for highlighting either + /// or both chart and legend items when the user mouses over them. + /// LegendItems must have MouseOver style set accordingly. + /// This property is only honored for PieSeries elements. + /// + [DefaultValue(LegendTrackingMode.NotSet), Category("Behavior")] + [Description("Indicates the tracking mode for highlighting either or both chart and legend items when the user mouses over them. LegendItems must have MouseOver style set accordingly. This property is only honored for PieSeries elements.")] + public LegendTrackingMode TrackingMode + { + get { return (_TrackingMode); } + + set + { + if (value != _TrackingMode) + { + _TrackingMode = value; + + OnPropertyChanged("TrackingMode"); + } + } + } + + #endregion + + #region Visible + + /// + /// Get or sets whether the item is visible + /// + [Description("Indicates whether the item is visible")] + [DefaultValue(-1), Category("Appearance")] + new public bool Visible + { + get { return (base.Visible); } + set { base.Visible = value; } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeVisible() + { + return (true); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetVisible() + { + Visible = true; + } + + #endregion + + #region VScrollBar + + /// + /// Gets a reference to the Legend’s vertical scrollbar + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether markers are shown in the legend.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarLite VScrollBar + { + get { return (_VScrollBar); } + } + + #endregion + + #region VScrollBarWidth + + /// + /// Gets or sets the width of a vertical scrollBar. + /// + [DefaultValue(9)] + [Description("Indicates the width of a vertical scrollBar")] + public int VScrollBarWidth + { + get { return (_VScrollBarWidth); } + + set + { + if (value != _VScrollBarWidth) + { + _VScrollBarWidth = value; + + OnPropertyChangedEx("VScrollBarWidth", VisualChangeType.Layout); + } + } + } + + #endregion + + #region VScrollOffset + + /// + /// Gets or sets the vertical scrollbar offset + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int VScrollOffset + { + get + { + if (_VScrollBar != null && _VScrollBar.Visible == true) + return (_VScrollBar.Value); + + return (0); + } + + set { SetVScrollValue(value); } + } + + #endregion + + #region VScrollBarVisible + + /// + /// Gets or sets whether Vertical Scrollbar is shown (due to the content of the control exceeding available height). + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Vertical Scrollbar is shown (due to the content of the control exceeding available height).")] + public bool VScrollBarVisible + { + get { return (TestState(States.VScrollBarVisible)); } + + set + { + if (value != VScrollBarVisible) + { + SetState(States.VScrollBarVisible, value); + + InvalidateLayout(); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region ContentBounds + + internal Rectangle ContentBounds + { + get { return (_ContentBounds); } + set { _ContentBounds = value; } + } + + #endregion + + #region ContentBoundsEx + + internal Rectangle ContentBoundsEx + { + get { return (_ContentBoundsEx); } + set { _ContentBoundsEx = value; } + } + + #endregion + + #region FrameBounds + + internal Rectangle FrameBounds + { + get { return (_FrameBounds); } + set { _FrameBounds = value; } + } + + #endregion + + #region PointMarker + + internal PointMarker PointMarker + { + get + { + if (_PointMarker == null) + _PointMarker = new PointMarker(); + + return (_PointMarker); + } + + set { _PointMarker = value; } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + Graphics g = layoutInfo.Graphics; + ChartLegendVisualStyle style = _EffectiveStyles[StyleState.Default]; + + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreLoadLegendDataEvent(this) == false) + { + ChartContainer cc = ParentChartContainer; + + if (cc != null) + LegendItems = cc.GetLegendData(); + + chartControl.DoPostLoadLegendDataEvent(this); + } + + if (LegendItems.Count > 0) + { + OrderLegendItems(); + + Rectangle layoutBounds = GetLayoutBounds(layoutInfo, style); + + AdjustViewRects(layoutBounds, style); + + _ContentBoundsEx = _ContentBounds; + + Rectangle rrr = layoutInfo.LayoutBounds; + layoutInfo.LayoutBounds = layoutBounds; + + Size size = MeasureLegendData(layoutInfo, _ContentBounds, style); + + layoutInfo.LayoutBounds = rrr; + + _ContentBoundsEx.Size = size; + + Size minContentSize = Dpi.Size(MinContentSize); + + size.Width = Math.Max(size.Width, minContentSize.Width); + size.Height = Math.Max(size.Height, minContentSize.Height); + + size.Width += Dpi.Width(style.Padding.Horizontal + style.Margin.Horizontal + style.BorderThickness.Horizontal); + size.Height += Dpi.Height(style.Padding.Vertical + style.Margin.Vertical + style.BorderThickness.Vertical); + + size.Width = Math.Min(size.Width, layoutBounds.Width); + size.Height = Math.Min(size.Height, layoutBounds.Height); + + layoutBounds.Size = size; + Size = size; + + if (VScrollBarVisible == true) + { + if (ContentBoundsEx.Height > ContentBounds.Height) + layoutBounds.Width += Dpi.Width(_VScrollBarWidth) + 1; + } + + layoutBounds = AlignLegend(layoutInfo, layoutBounds, style); + + BoundsRelative = layoutBounds; + + AdjustViewRects(layoutBounds, style); + } + else + { + BoundsRelative = Rectangle.Empty; + } + + _LegendMeasured = true; + } + + #region PreLoadLegendData + + private bool PreLoadLegendData() + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + return (chartControl.DoPreLoadLegendDataEvent(this)); + + return (false); + } + + #endregion + + #region OrderLegendItems + + private void OrderLegendItems() + { + if (ItemSortDirection != SortDirection.None) + LegendItems.Sort(new LegendItemComparer(this)); + } + + #region RowComparer + + private class LegendItemComparer : IComparer + { + private ChartLegend _ChartLegend; + + public LegendItemComparer(ChartLegend chartLegend) + { + _ChartLegend = chartLegend; + } + + public int Compare(ChartLegendItem x, ChartLegendItem y) + { + int sval = 0; + + string sx = string.IsNullOrEmpty(x.ItemText) ? x.Name : x.ItemText; + string sy = string.IsNullOrEmpty(y.ItemText) ? y.Name : y.ItemText; + + if (sx == null || sy == null) + { + if (sx != sy) + sval = (sx == null ? 1 : -1); + } + else + { + sval = sx.CompareTo(sy); + } + + if (sval != 0) + { + return (_ChartLegend.ItemSortDirection == + SortDirection.Ascending) ? sval : -sval; + } + + return (0); + } + } + + #endregion + + #endregion + + #region AdjustViewRects + + private void AdjustViewRects(Rectangle layoutBounds, ChartLegendVisualStyle style) + { + _FrameBounds = GetAdjustedBounds(layoutBounds, style.Margin); + + _ContentBounds = GetAdjustedBounds(_FrameBounds, style.BorderThickness); + _ContentBounds = GetAdjustedBounds(_ContentBounds, style.Padding); + } + + #endregion + + #region GetLayoutBounds + + private Rectangle GetLayoutBounds( + ChartLayoutInfo layoutInfo, ChartLegendVisualStyle style) + { + Rectangle layoutBounds = layoutInfo.LayoutBounds; + + int width = layoutBounds.Width; + int height = layoutBounds.Height; + + int pwidth = (style.Padding.Horizontal + style.Margin.Horizontal + style.BorderThickness.Horizontal); + int pheight = (style.Padding.Vertical + style.Margin.Vertical + style.BorderThickness.Vertical); + + if (_MaxHorizontalPct >= 0 && _MaxHorizontalPct < 100) + width = (int)Math.Min(width, layoutBounds.Width * _MaxHorizontalPct / 100); + + width = Math.Max(width, _MinContentSize.Width + pwidth); + width = Math.Min(width, layoutBounds.Width); + + layoutBounds.Width = width; + + if (_MaxVerticalPct >= 0 && _MaxVerticalPct < 100) + height = (int)Math.Min(height, layoutBounds.Height * _MaxVerticalPct / 100); + + height = Math.Max(height, _MinContentSize.Height + pheight); + height = Math.Min(height, layoutBounds.Height); + + layoutBounds.Height = height; + + return (layoutBounds); + } + + #endregion + + #region MeasureLegendData + + private Size MeasureLegendData( + ChartLayoutInfo layoutInfo, Rectangle bounds, ChartLegendVisualStyle style) + { + Rectangle layoutBounds = layoutInfo.LayoutBounds; + + layoutInfo.LayoutBounds = bounds; + + Size size = Size.Empty; + + if (_LegendItems != null && _LegendItems.Count > 0) + { + switch (Direction) + { + case Direction.LeftToRight: + case Direction.RightToLeft: + size = MeasureHorizontalLegend(layoutInfo, style); + break; + + case Direction.TopToBottom: + case Direction.BottomToTop: + size = MeasureVerticalLegend(layoutInfo, style); + break; + + default: + switch (Alignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + size = MeasureHorizontalLegend(layoutInfo, style); + break; + + default: + size = MeasureVerticalLegend(layoutInfo, style); + break; + } + break; + } + } + + layoutInfo.LayoutBounds = layoutBounds; + + return (size); + } + + #region MeasureHorizontalLegend + + private Size MeasureHorizontalLegend( + ChartLayoutInfo layoutInfo, ChartLegendVisualStyle style) + { + if (AlignVerticalItems == true) + return (MeasureEquallySpacedItems(layoutInfo, style)); + + return (MeasureDefaultSpacedItems(layoutInfo, style)); + } + + #region MeasureEquallySpacedItems + + private Size MeasureEquallySpacedItems( + ChartLayoutInfo layoutInfo, ChartLegendVisualStyle style) + { + Size size = Size.Empty; + Rectangle bounds = layoutInfo.LayoutBounds; + + Size[] itemSizes = MeasureAllItems(layoutInfo); + int mcc = GetMaxColumnCount(layoutInfo, style, itemSizes); + + if (mcc > 0) + { + int[] widthArray = GetWidthArray(layoutInfo, itemSizes, mcc); + + while (mcc > 1) + { + int n = 0; + + for (int j = 0; j < widthArray.Length; j++) + n += widthArray[j]; + + n += ((widthArray.Length - 1) * Dpi.Width(style.HorizontalSpacing)); + + if (n <= layoutInfo.LayoutBounds.Width) + break; + + widthArray = GetWidthArray(layoutInfo, itemSizes, --mcc); + } + + if (mcc > 0) + { + int[] heightArray = GetHeightArray(layoutInfo, itemSizes, mcc); + + for (int i = 0; i < _LegendItems.Count; i++) + { + int x = i % mcc; + int y = i / mcc; + + ChartLegendItem li = _LegendItems[i]; + + li.Size = new Size(widthArray[x], heightArray[y]); + } + + for (int i = 0; i < widthArray.Length; i++) + size.Width += widthArray[i]; + + size.Width += ((mcc - 1) * Dpi.Width(style.HorizontalSpacing)); + + for (int i = 0; i < heightArray.Length; i++) + size.Height += heightArray[i]; + + size.Height += ((heightArray.Length - 1) * Dpi.Height(style.VerticalSpacing)); + } + } + + return (size); + } + + #region MeasureAllItems + + private Size[] MeasureAllItems(ChartLayoutInfo layoutInfo) + { + Size[] sizes = new Size[_LegendItems.Count]; + + for (int i = 0; i < _LegendItems.Count; i++) + { + ChartLegendItem li = _LegendItems[i]; + + li.Parent = this; + li.Measure(layoutInfo); + + sizes[i] = li.Size; + } + + return (sizes); + } + + #endregion + + #region GetMaxColumnCount + + private int GetMaxColumnCount( + ChartLayoutInfo layoutInfo, ChartLegendVisualStyle style, Size[] itemSizes) + { + int n = 0; + + for (int i = 0; i < itemSizes.Length; i++) + { + n += (itemSizes[i].Width + Dpi.Width(style.HorizontalSpacing)); + + if (n >= layoutInfo.LayoutBounds.Width) + return (i > 0 ? i : 1); + } + + return (itemSizes.Length); + } + + #endregion + + #region GetWidthArray + + private int[] GetWidthArray( + ChartLayoutInfo layoutInfo, Size[] itemSizes, int mcc) + { + int[] widthArray = new int[mcc]; + + for (int i = 0; i < _LegendItems.Count; i++) + { + int x = i % mcc; + + ChartLegendItem li = _LegendItems[i]; + + if (li.Size.Width > widthArray[x]) + widthArray[x] = li.Size.Width; + } + + return (widthArray); + } + + #endregion + + #region GetHeightArray + + private int[] GetHeightArray( + ChartLayoutInfo layoutInfo, Size[] itemSizes, int mcc) + { + int n = (int)Math.Ceiling((double)_LegendItems.Count / mcc); + int[] heightArray = new int[n]; + + for (int i = 0; i < _LegendItems.Count; i++) + { + int y = i / mcc; + + ChartLegendItem li = _LegendItems[i]; + + if (li.Size.Height > heightArray[y]) + heightArray[y] = li.Size.Height; + } + + return (heightArray); + } + + #endregion + + #endregion + + #region MeasureDefaultSpacedItems + + private Size MeasureDefaultSpacedItems( + ChartLayoutInfo layoutInfo, ChartLegendVisualStyle style) + { + Size size = Size.Empty; + Size rsize = Size.Empty; + + Rectangle bounds = layoutInfo.LayoutBounds; + + for (int i = 0; i < _LegendItems.Count; i++) + { + ChartLegendItem li = _LegendItems[i]; + + li.Parent = this; + li.Measure(layoutInfo); + + if (rsize.Width + li.Size.Width <= bounds.Width && li.TextWrapped == false) + { + rsize.Width += li.Size.Width; + layoutInfo.LayoutBounds.Width -= li.Size.Width; + + if (i + 1 < _LegendItems.Count) + { + int n = Dpi.Width(style.HorizontalSpacing); + + rsize.Width += n; + layoutInfo.LayoutBounds.Width -= n; + } + + if (li.Size.Height > rsize.Height) + rsize.Height = li.Size.Height; + } + else + { + if (rsize.IsEmpty == false || layoutInfo.LayoutBounds.Width == bounds.Width) + { + if (layoutInfo.LayoutBounds.Width != bounds.Width) + i--; + else + rsize = li.Size; + + if (size.Width < rsize.Width) + size.Width = rsize.Width; + + size.Height += (rsize.Height + Dpi.Height(style.VerticalSpacing)); + + layoutInfo.LayoutBounds = bounds; + layoutInfo.LayoutBounds.Height = bounds.Height - size.Height; + + rsize = Size.Empty; + } + } + } + + if (rsize.IsEmpty == false) + { + if (size.Width < rsize.Width) + size.Width = rsize.Width; + + size.Height += rsize.Height; + } + + return (size); + } + + #endregion + + #endregion + + #region MeasureVerticalLegend + + private Size MeasureVerticalLegend( + ChartLayoutInfo layoutInfo, ChartLegendVisualStyle style) + { + Size size = Size.Empty; + + Rectangle layoutBounds = layoutInfo.LayoutBounds; + Rectangle bounds = GetAdjustedBounds(layoutBounds, style.BorderThickness); + + layoutInfo.LayoutBounds = bounds; + + for (int i = 0; i < _LegendItems.Count; i++) + { + ChartLegendItem li = _LegendItems[i]; + + li.Parent = this; + li.Measure(layoutInfo); + + size.Height += li.Size.Height; + + if (li.Size.Width > size.Width) + size.Width = li.Size.Width; + } + + size.Height += (Dpi.Height(style.VerticalSpacing) * (_LegendItems.Count - 1)); + + return (size); + } + + #endregion + + #endregion + + #region AlignLegend + + private Rectangle AlignLegend( + ChartLayoutInfo layoutInfo, Rectangle bounds, ChartLegendVisualStyle style) + { + Rectangle layoutBounds = layoutInfo.LayoutBounds; + + bool inside = (Placement == Placement.Inside || Alignment == Alignment.MiddleCenter); + + if (inside == false) + { + switch (Alignment) + { + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + layoutBounds.X += bounds.Width; + layoutBounds.Width -= bounds.Width; + break; + + case Alignment.TopCenter: + layoutBounds.Y += bounds.Height; + layoutBounds.Height -= bounds.Height; + break; + + case Alignment.BottomCenter: + layoutBounds.Height -= bounds.Height; + break; + + case Alignment.NotSet: + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + layoutBounds.Width -= bounds.Width; + break; + } + } + + switch (Alignment) + { + case Alignment.MiddleLeft: + bounds.Y += (layoutBounds.Height - bounds.Height) / 2; + break; + + case Alignment.BottomLeft: + bounds.Y = layoutBounds.Bottom - bounds.Height; + break; + + case Alignment.TopCenter: + bounds.X += (layoutBounds.Width - bounds.Width) / 2; + break; + + case Alignment.MiddleCenter: + bounds.X += (layoutBounds.Width - bounds.Width) / 2; + bounds.Y += (layoutBounds.Height - bounds.Height) / 2; + break; + + case Alignment.BottomCenter: + bounds.X += (layoutBounds.Width - bounds.Width) / 2; + bounds.Y = layoutBounds.Bottom - (inside ? bounds.Height : 0); + break; + + case Alignment.TopRight: + bounds.X = layoutBounds.Right - (inside ? bounds.Width : 0); + break; + + case Alignment.MiddleRight: + bounds.X = layoutBounds.Right - (inside ? bounds.Width : 0); + bounds.Y += (layoutBounds.Height - bounds.Height) / 2; + break; + + case Alignment.NotSet: + case Alignment.BottomRight: + bounds.X = layoutBounds.Right - (inside ? bounds.Width : 0); + bounds.Y = layoutBounds.Bottom - bounds.Height; + break; + } + + layoutBounds.Width = Math.Max(0, layoutBounds.Width); + layoutBounds.Height = Math.Max(0, layoutBounds.Height); + + layoutInfo.LayoutBounds = layoutBounds; + + return (bounds); + } + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + ChartLegendVisualStyle style = _EffectiveStyles[StyleState.Default]; + + if (_LegendMeasured == true) + { + PostAlignLegend(style); + + _LegendMeasured = false; + } + + if (_LegendItems != null && _LegendItems.Count > 0) + { + Rectangle layoutBounds = layoutInfo.LayoutBounds; + + switch (Direction) + { + case Direction.LeftToRight: + case Direction.RightToLeft: + AlignHorizontalLegendItems(layoutInfo, style); + break; + + case Direction.TopToBottom: + case Direction.BottomToTop: + AlignVerticalLegendItems(layoutInfo, style); + break; + + default: + switch (Alignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + AlignHorizontalLegendItems(layoutInfo, style); + break; + + default: + AlignVerticalLegendItems(layoutInfo, style); + break; + } + break; + } + + layoutInfo.LayoutBounds = layoutBounds; + } + + UpdateScrollBars(layoutInfo); + } + + #region AlignHorizontalLegendItems + + private void AlignHorizontalLegendItems( + ChartLayoutInfo layoutInfo, ChartLegendVisualStyle style) + { + Rectangle bounds = _ContentBounds; + Rectangle layoutBounds = bounds; + + Rectangle scContentBounds = GetScrollBounds(_ContentBounds); + + int verticalSpacing = Dpi.Height(style.VerticalSpacing); + int horizontalSpacing = Dpi.Width(style.HorizontalSpacing); + + layoutInfo.ScrollOffset.Y += VScrollOffset; + + for (int i = 0; i < _LegendItems.Count; i++) + { + int index = (Direction == Direction.RightToLeft) ? (_LegendItems.Count - i - 1) : i; + + ChartLegendItem item = _LegendItems[index]; + + if (bounds.X + item.Size.Width > layoutBounds.Right) + { + if (bounds.X > layoutBounds.X) + { + bounds.X = layoutBounds.X; + bounds.Y += (bounds.Height + verticalSpacing); + } + } + + bounds.Width = item.Size.Width; + bounds.Height = item.Size.Height; + + layoutInfo.LayoutBounds = bounds; + + item.Arrange(layoutInfo); + + item.Displayed = item.Bounds.IntersectsWith(scContentBounds); + + bounds.X += (item.Size.Width + horizontalSpacing); + + item.UpdateCheckState(); + } + + layoutInfo.ScrollOffset.Y -= VScrollOffset; + } + + #endregion + + #region AlignVerticalLegendItems + + private void AlignVerticalLegendItems( + ChartLayoutInfo layoutInfo, ChartLegendVisualStyle style) + { + Rectangle bounds = _ContentBounds; + Rectangle scContentBounds = GetScrollBounds(ContentBounds); + + int verticalSpacing = Dpi.Height(style.VerticalSpacing); + + layoutInfo.ScrollOffset.Y += VScrollOffset; + + for (int i = 0; i < _LegendItems.Count; i++) + { + int index = (Direction == Direction.BottomToTop) ? (_LegendItems.Count - i - 1) : i; + + ChartLegendItem item = _LegendItems[index]; + + bounds.Height = item.Size.Height; + layoutInfo.LayoutBounds = bounds; + + item.Arrange(layoutInfo); + + item.Displayed = item.Bounds.IntersectsWith(scContentBounds); + + bounds.Y += (item.Size.Height + verticalSpacing); + + item.UpdateCheckState(); + } + + layoutInfo.ScrollOffset.Y -= VScrollOffset; + } + + #endregion + + #region PostAlignLegend + + private void PostAlignLegend(ChartLegendVisualStyle style) + { + if (Placement == Placement.Inside) + { + ChartContainer cc = Parent as ChartContainer; + + Rectangle r = BoundsRelative; + + if (cc.HScrollBar.Visible == true) + { + switch (Alignment) + { + case Alignment.NotSet: + case Alignment.BottomLeft: + case Alignment.BottomCenter: + case Alignment.BottomRight: + if (r.Bottom > cc.HScrollBar.BoundsRelative.Top) + r.Y -= (r.Bottom - cc.HScrollBar.BoundsRelative.Top); + break; + } + } + + if (cc.VScrollBar.Visible == true) + { + switch (Alignment) + { + case Alignment.NotSet: + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + if (r.Right > cc.VScrollBar.BoundsRelative.Left) + r.X -= (r.Right - cc.VScrollBar.BoundsRelative.Left); + break; + } + } + + if (BoundsRelative != r) + { + BoundsRelative = r; + + _FrameBounds = GetAdjustedBounds(BoundsRelative, style.Margin); + _ContentBounds = GetAdjustedBounds(_FrameBounds, style.BorderThickness); + _ContentBounds = GetAdjustedBounds(_ContentBounds, style.Padding); + } + } + } + + #endregion + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + Rectangle bounds = Bounds; + Rectangle scFrameBounds = GetScrollBounds(_FrameBounds); + Rectangle scContentBounds = GetScrollBounds(_ContentBounds); + + if (scContentBounds.Height > 2 & scContentBounds.Width > 2) + { + ChartLegendVisualStyle style = GetEffectiveStyle(); + + style.RenderBackground(g, scFrameBounds); + + if (style.ImageOverlay != ImageOverlay.Top) + style.RenderBackgroundFigure(g, scFrameBounds); + + style.RenderBorder(g, scFrameBounds); + + if (_LegendItems != null && _LegendItems.Count > 0) + { + Region clip = g.Clip; + g.SetClip(scContentBounds, CombineMode.Intersect); + + Point pt = scContentBounds.Location; + + for (int i = 0; i < _LegendItems.Count; i++) + { + ChartLegendItem li = _LegendItems[i]; + + if (li.Visible == true) + li.Render(renderInfo); + } + + if (VScrollBar.Visible == true) + VScrollBar.Render(renderInfo); + + if (style.ImageOverlay == ImageOverlay.Top) + style.RenderBackgroundFigure(g, scFrameBounds); + + g.Clip = clip; + + if (style.DropShadow.Enabled == Tbool.True) + style.DropShadow.RenderDropShadow(g, scFrameBounds, true, true); + } + } + } + + #endregion + + #region Mouse handling + + #region OnMouseEnter + + protected override bool OnMouseEnter(EventArgs e) + { + base.OnMouseEnter(e); + + return (true); + } + + #endregion + + #region OnMouseLeave + + protected override bool OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + + return (true); + } + + #endregion + + #region OnMouseMove + + protected override bool OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + + _HitArea = GetLegendAreaAt(e.Location); + + if (IsMouseDown == true) + return (OnMouseDownMove(e)); + + if (EnablePanning == true && VScrollBar.Enabled == true) + { + ChartCursor = OpenHandCursor; + + return (true); + } + + ChartCursor = Cursors.Default; + + return (false); + } + + #region OnMouseDownMove + + private bool OnMouseDownMove(MouseEventArgs e) + { + if (_Panning == true) + { + ChartCursor = ClosedHandCursor; + + if (VScrollBar.Enabled == true) + VScrollOffset = _VPanOffset + (MouseDownPoint.Y - e.Location.Y); + } + + return (true); + } + + #endregion + + #endregion + + #region OnMouseDown + + protected override bool OnMouseDown(MouseEventArgs e) + { + return (OnMouseDownEx(e)); + } + + protected override bool OnMouseDownEx(MouseEventArgs e) + { + if (EnablePanning == true && VScrollBar.Visible == true) + { + _VPanOffset = VScrollOffset; + + _Panning = true; + + ChartCursor = ClosedHandCursor; + ChartControl.PostInternalMouseMove(); + + ChartControl.CapturedItem = this; + + return (true); + } + + return (false); + } + + #endregion + + #region OnMouseUp + + protected override bool OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + if (_Panning == true) + { + _Panning = false; + + ChartControl.CapturedItem = null; + } + + return (true); + } + + #endregion + + #region OnMouseWheel + + protected override bool OnMouseWheel(MouseEventArgs e) + { + if (VScrollBar.Enabled == true) + { + if ((e.Delta < 0 && VScrollBar.IsAtMaxumum == false) || + (e.Delta > 0 && VScrollBar.IsAtMinumum == false)) + { + int value = -e.Delta * SystemInformation.MouseWheelScrollLines / 120; + + value *= VScrollBar.SmallChange; + value += VScrollBar.Value; + + SetVScrollValue(value); + + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region Scrollbar support + + #region SetupScrollBars + + private void SetupScrollBars() + { + _VScrollBar = new VScrollBarLite(); + + _VScrollBar.Parent = this; + _VScrollBar.Width = Dpi.Width(_VScrollBarWidth); + + _VScrollBar.Visible = false; + } + + #endregion + + #region UpdateScrollBars + + private void UpdateScrollBars(ChartLayoutInfo layoutInfo) + { + EnableVScrollBar(); + + if (_VScrollBar.Enabled == true) + { + _VScrollBar.SmallChange = ContentBounds.Height / 20; + _VScrollBar.Maximum = Math.Max(0, ContentBoundsEx.Height); + _VScrollBar.LargeChange = Math.Min(ContentBounds.Height, _VScrollBar.Maximum); + + if (_VScrollBar.Value + _VScrollBar.LargeChange > _VScrollBar.Maximum) + _VScrollBar.Value = _VScrollBar.Maximum - _VScrollBar.LargeChange; + + _VScrollBar.Arrange(layoutInfo); + } + } + + #region EnableVScrollBar + + private void EnableVScrollBar() + { + bool enable = (VScrollBarVisible == true) && + (ContentBounds.Height > 0 && ContentBoundsEx.Height > ContentBounds.Height); + + if (enable == true) + { + _VScrollBar.Height = ContentBounds.Height - 1; + _VScrollBar.Width = Dpi.Width(_VScrollBarWidth); + + _VScrollBar.Location = new + Point(ContentBounds.Right - _VScrollBar.Width - 1, ContentBounds.Top); + + } + else + { + _VScrollBar.Value = 0; + } + + _VScrollBar.Enabled = enable; + _VScrollBar.Visible = enable; + } + + #endregion + + #endregion + + #region SetVScrollValue + + internal void SetVScrollValue(int value) + { + if (_VScrollBar.Visible == true) + { + int oldValue = _VScrollBar.Value; + + value = Math.Max(value, 0); + value = Math.Min(value, _VScrollBar.Maximum); + + _VScrollBar.Value = value; + } + } + + #endregion + + #endregion + + #region GetElementAt + + /// + /// Gets the legend element at the given Point. + /// + /// + /// + public override ChartVisualElement GetElementAt(Point pt) + { + if (InScrollBar(VScrollBar, pt)) + return (VScrollBar); + + if (_LegendItems != null) + { + foreach (ChartLegendItem item in _LegendItems) + { + if (item != null && item.Visible == true && item.IsEnabled == true) + { + if (item.Bounds.Contains(pt)) + { + ChartVisualElement subItem = item.GetElementAt(pt); + + if (subItem != null) + return (subItem); + + return (item); + } + } + } + } + + return (null); + } + + #region InScrollBar + + private bool InScrollBar(ScrollBarLite scrollBar, Point pt) + { + if (scrollBar != null && scrollBar.Visible == true) + { + if (scrollBar.Bounds.Contains(pt)) + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region GetLegendAreaAt + + private LegendArea GetLegendAreaAt(Point pt) + { + if ((Bounds.Contains(pt) == false || Visible == false)) + return (LegendArea.None); + + ChartVisualElement item = GetElementAt(pt); + + if (item != null) + { + if (item is ScrollBarLite) + return (LegendArea.ScrollBar); + + return (LegendArea.LegendItem); + } + + return (LegendArea.WhiteSpace); + } + + #endregion + + #region InvalidateItem + + internal void InvalidateItem(ChartLegendItem item) + { + ChartLegendItem likeItem = FindLikeItem(item); + + if (likeItem != null && likeItem.Legend != item.Legend) + { + likeItem.UpdateCheckState(); + likeItem.InvalidateRender(); + } + } + + #endregion + + #region FindLikeItem + + private ChartLegendItem FindLikeItem(ChartLegendItem item) + { + if (_LegendItems != null) + { + string itemName = item.Name ?? item.ItemText; + + if (String.IsNullOrEmpty(itemName) == false) + { + foreach (ChartLegendItem likeItem in _LegendItems) + { + string likeName = likeItem.Name ?? likeItem.ItemText; + + if (String.IsNullOrEmpty(likeName) == false) + { + if (likeName.Equals(itemName) == true) + return (likeItem); + } + } + } + } + + return (null); + } + + #endregion + + #region GetLegendItem + + /// + /// Gets the LegendItem from the given chart item. + /// + /// + /// + public ChartLegendItem GetLegendItem(ILegendItem chartItem) + { + if (LegendItems != null) + { + foreach (ChartLegendItem litem in LegendItems) + { + foreach (ILegendItem citem in litem.ChartItems) + { + if (citem == chartItem) + return (litem); + } + } + } + + return (null); + } + + #endregion + + #region Style Support + + #region GetEffectiveStyle + + internal ChartLegendVisualStyle GetEffectiveStyle() + { + StyleState state = StyleState.Default; + + if (IsMouseOver == true) + { + state |= StyleState.MouseOver; + } + else + { + Point pt = Control.MousePosition; + + pt = ChartControl.PointToClient(pt); + + if (Bounds.Contains(pt)) + state |= StyleState.MouseOver; + } + + return (EffectiveStyles[state]); + } + + #endregion + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style, StyleType cs) + { + ChartLegendVisualStyle lstyle = style as ChartLegendVisualStyle; + + if (lstyle != null) + { + ApplyParentStyles(lstyle, cs, Parent as ChartContainer); + + lstyle.ApplyStyle(ChartLegendVisualStyles[cs]); + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles( + ChartLegendVisualStyle lstyle, StyleType cs, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(lstyle, cs, item.Parent as ChartContainer); + + if (item is ChartPanel) + lstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartLegendVisualStyles[cs]); + } + else + { + lstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartLegendVisualStyles[cs]); + lstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartLegendVisualStyles[cs]); + } + } + + #endregion + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults(BaseVisualStyle style, StyleType cs) + { + ChartLegendVisualStyle lstyle = style as ChartLegendVisualStyle; + + if (lstyle != null) + lstyle.ApplyDefaults(); + + base.ApplyDefaults(style, cs); + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Style + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + EffectiveStyles.InvalidateStyles(); + EffectiveItemStyles.InvalidateStyles(); + + if (_LegendItems != null) + { + for (int i = 0; i < _LegendItems.Count; i++) + _LegendItems[i].EffectiveStyles.InvalidateStyles(); + } + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartLegend copy = new ChartLegend(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartLegend c = copy as ChartLegend; + + if (c != null) + { + base.CopyTo(c); + + c.Alignment = Alignment; + c.AlignVerticalItems = AlignVerticalItems; + + c.ChartLegendItemVisualStyles = + (_ChartLegendItemVisualStyles != null) ? ChartLegendItemVisualStyles.Copy() : null; + + c.ChartLegendVisualStyles = + (_ChartLegendVisualStyles != null) ? ChartLegendVisualStyles.Copy() : null; + + c.CheckBoxSize = CheckBoxSize; + c.CombineLikeItems = CombineLikeItems; + c.Direction = Direction; + c.EnablePanning = EnablePanning; + + c.ItemCheckAction = ItemCheckAction; + c.ItemSortDirection = ItemSortDirection; + c.ItemTextOffset = ItemTextOffset; + + c.MarkerSize = MarkerSize; + + c.MaxHorizontalPct = MaxHorizontalPct; + c.MaxVerticalPct = MaxVerticalPct; + c.MinContentSize = MinContentSize; + + c.Placement = Placement; + + c.ShowCheckBoxes = ShowCheckBoxes; + c.ShowItemText = ShowItemText; + c.ShowMarkers = ShowMarkers; + + c.ShowPieRingCheckBoxes = ShowPieRingCheckBoxes; + c.ShowPieSeriesCheckBoxes = ShowPieSeriesCheckBoxes; + c.ShowPieSeriesPointCheckBoxes = ShowPieSeriesPointCheckBoxes; + + c.ShowPieRingsInLegend = ShowPieRingsInLegend; + c.ShowPieSeriesInLegend = ShowPieSeriesInLegend; + c.ShowPieSeriesPointsInLegend = ShowPieSeriesPointsInLegend; + + c.TrackingMode = TrackingMode; + + c.VScrollBarWidth = VScrollBarWidth; + c.VScrollBarVisible = VScrollBarVisible; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartLegend"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("Alignment", Alignment, Alignment.NotSet); + sec.AddValue("AlignVerticalItems", AlignVerticalItems, false); + + if (_ChartLegendItemVisualStyles != null && _ChartLegendItemVisualStyles.IsEmpty == false) + sec.AddElement(_ChartLegendItemVisualStyles.GetSerialData("ChartLegendItemVisualStyles")); + + if (_ChartLegendVisualStyles != null && _ChartLegendVisualStyles.IsEmpty == false) + sec.AddElement(_ChartLegendVisualStyles.GetSerialData("ChartLegendVisualStyles")); + + sec.AddValue("CheckBoxSize", CheckBoxSize, new Size(15, 15)); + sec.AddValue("CombineLikeItems", CombineLikeItems, true); + sec.AddValue("Direction", Direction, Direction.NotSet); + sec.AddValue("EnablePanning", EnablePanning, true); + + sec.AddValue("ItemCheckAction", ItemCheckAction, ItemCheckAction.ShowItem); + sec.AddValue("ItemSortDirection", ItemSortDirection, SortDirection.None); + sec.AddValue("ItemTextOffset", ItemTextOffset, 2); + + sec.AddValue("MarkerSize", MarkerSize, new Size(15, 15)); + sec.AddValue("MaxHorizontalPct", MaxHorizontalPct, 100d); + sec.AddValue("MaxVerticalPct", MaxVerticalPct, 100d); + sec.AddValue("MinContentSize", MinContentSize, new Size(15, 15)); + sec.AddValue("Placement", Placement, Placement.NotSet); + + sec.AddValue("ShowCheckBoxes", ShowCheckBoxes, false); + sec.AddValue("ShowItemText", ShowItemText, true); + sec.AddValue("ShowMarkers", ShowMarkers, true); + + sec.AddValue("ShowPieRingCheckBoxes", ShowPieRingCheckBoxes, Tbool.NotSet); + sec.AddValue("ShowPieSeriesCheckBoxes", ShowPieSeriesCheckBoxes, Tbool.NotSet); + sec.AddValue("ShowPieSeriesPointCheckBoxes", ShowPieSeriesPointCheckBoxes, Tbool.NotSet); + + sec.AddValue("ShowPieRingsInLegend", ShowPieRingsInLegend, false); + sec.AddValue("ShowPieSeriesInLegend", ShowPieSeriesInLegend, false); + sec.AddValue("ShowPieSeriesPointsInLegend", ShowPieSeriesPointsInLegend, true); + + sec.AddValue("TrackingMode", TrackingMode, LegendTrackingMode.NotSet); + + if (_VScrollBar != null) + sec.AddElement(_VScrollBar.GetSerialData("VScrollBar")); + + sec.AddValue("VScrollBarWidth", VScrollBarWidth, 9); + sec.AddValue("VScrollBarVisible", VScrollBarVisible, true); + + // Don't call base, due to 'Visible' default differences + // between ChartPanel and ChartXy elements. + + sec.AddValue("Name", Name, String.Empty); + sec.AddValue("Tag", Tag, null); + sec.AddValue("Visible", Visible, Parent is BaseChart); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Alignment": + Alignment = (Alignment)se.GetValueEnum(typeof(Alignment)); + break; + + case "AlignVerticalItems": + AlignVerticalItems = bool.Parse(se.StringValue); + break; + + case "CheckBoxSize": + CheckBoxSize = se.GetValueSize(); + break; + + case "CombineLikeItems": + CombineLikeItems = bool.Parse(se.StringValue); + break; + + case "Direction": + Direction = (Direction)se.GetValueEnum(typeof(Direction)); + break; + + case "EnablePanning": + EnablePanning = bool.Parse(se.StringValue); + break; + + case "ItemCheckAction": + ItemCheckAction = (ItemCheckAction)se.GetValueEnum(typeof(ItemCheckAction)); + break; + + case "ItemSortDirection": + ItemSortDirection = (SortDirection)se.GetValueEnum(typeof(SortDirection)); + break; + + case "ItemTextOffset": + ItemTextOffset = int.Parse(se.StringValue); + break; + + case "MarkerSize": + MarkerSize = se.GetValueSize(); + break; + + case "MaxHorizontalPct": + MaxHorizontalPct = double.Parse(se.StringValue); + break; + + case "MaxVerticalPct": + MaxVerticalPct = double.Parse(se.StringValue); + break; + + case "MinContentSize": + MinContentSize = se.GetValueSize(); + break; + + case "Placement": + Placement = (Placement)se.GetValueEnum(typeof(Placement)); + break; + + case "ShowCheckBoxes": + ShowCheckBoxes = bool.Parse(se.StringValue); + break; + + case "ShowItemText": + ShowItemText = bool.Parse(se.StringValue); + break; + + case "ShowMarkers": + ShowMarkers = bool.Parse(se.StringValue); + break; + + case "ShowPieRingCheckBoxes": + ShowPieRingCheckBoxes = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShowPieSeriesCheckBoxes": + ShowPieSeriesCheckBoxes = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShowPieSeriesPointCheckBoxes": + ShowPieSeriesPointCheckBoxes = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShowPieRingsInLegend": + ShowPieRingsInLegend = bool.Parse(se.StringValue); + break; + + case "ShowPieSeriesInLegend": + ShowPieSeriesInLegend = bool.Parse(se.StringValue); + break; + + case "ShowPieSeriesPointsInLegend": + ShowPieSeriesPointsInLegend = bool.Parse(se.StringValue); + break; + + case "TrackingMode": + TrackingMode = (LegendTrackingMode)se.GetValueEnum(typeof(LegendTrackingMode)); + break; + + case "VScrollBarWidth": + VScrollBarWidth = int.Parse(se.StringValue); + break; + + case "VScrollBarVisible": + VScrollBarVisible = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartLegendItemVisualStyles": + sec.PutSerialData(ChartLegendItemVisualStyles); + break; + + case "ChartLegendVisualStyles": + sec.PutSerialData(ChartLegendVisualStyles); + break; + + case "VScrollBar": + sec.PutSerialData(VScrollBar); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + AlignVerticalItems = (1U << 0), + + VScrollBarEnabled = (1U << 1), + VScrollBarVisible = (1U << 2), + + EnablePanning = (1U << 3), + + ShowCheckBoxes = (1U << 4), + + ShowPieSeriesInLegend = (1U << 5), + ShowPieRingsInLegend = (1U << 6), + ShowPieSeriesPointsInLegend = (1U << 7), + + ShowMarkers = (1U << 8), + ShowItemText = (1U << 9), + + CombineLikeItems = (1U << 10), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + ChartLegendItemVisualStyles = null; + ChartLegendVisualStyles = null; + LegendItems = null; + + base.Dispose(); + } + + #endregion + } + + #region enums + + #region Direction + + /// + /// Specifies how the legend items are presented. + /// + public enum Direction + { + NotSet = 0, + + LeftToRight, + RightToLeft, + TopToBottom, + BottomToTop, + } + + #endregion + + #region ItemCheckAction + + public enum ItemCheckAction + { + /// + /// No action is taken. + /// + None, + + /// + /// Item will be shown or hidden, depending + /// upon the check state of the item. + /// + ShowItem, + } + + #endregion + + #region LegendArea + + public enum LegendArea + { + None = 0, + + // In a legend item. + LegendItem, + + // In legend scrollbar. + ScrollBar, + + // In legend whitespace. + WhiteSpace, + } + + #endregion + + #region Placement + + /// + /// Specifies the placement of the element with respect + /// to the chart contents. + /// + public enum Placement + { + NotSet = 0, + + Inside, + Outside, + } + + #endregion + + #endregion + + #region Interfaces + + #region ILegendData + + internal interface ILegendData + { + ChartLegend Legend { get; } + List GetLegendData(); + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLegendItem.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLegendItem.cs new file mode 100644 index 00000000..8851b1ab --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartLegendItem.cs @@ -0,0 +1,1505 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents an item in the chart Legend. + /// + public class ChartLegendItem : ChartVisualElement + { + #region Private variables + + private States _States; + + private List _ChartItems; + private ChartLegendItem _LikeItem; + + private Tbool _ShowCheckBox = Tbool.NotSet; + private Tbool _ShowItemText = Tbool.NotSet; + private Tbool _ShowMarker = Tbool.NotSet; + private Tbool _ShowInParentLegend = Tbool.NotSet; + + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + private EffectiveStyles _EffectiveStyles; + + private Size _MarkerSize; + private Size _TextSize; + + private Rectangle _MarkerBounds; + + private string _ItemText; + private string _FormattedText; + + private LegendItemArea _HitArea; + private LegendItemArea _MouseDownHitArea; + + private CheckState _CheckState = CheckState.Unchecked; + private bool _InCheckStateUpdate; + + #endregion + + public ChartLegendItem() + { + InitDefaultStates(); + + _EffectiveStyles = new EffectiveStyles(this); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.IsEnabled, true); + } + + #endregion + + #region Public properties + + #region ChartItems + + /// + /// Gets or sets the referenced Chart items. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public List ChartItems + { + get + { + if (_ChartItems == null) + _ChartItems = new List(); + + return (_ChartItems); + } + + set + { + if (value != ChartItems) + { + _ChartItems = value; + + OnPropertyChangedEx("ChartItems", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the visual styles for the Legend item. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Legend item.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleVisualChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (_ChartLegendItemVisualStyles != value) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CheckState + + /// + /// Gets or sets whether the item's checkbox is checked. + /// + [DefaultValue(CheckState.Unchecked), Category("Appearance")] + [Description("Indicates whether the item's checkbox is checked.")] + public CheckState CheckState + { + get { return (_CheckState); } + + set + { + if (value != _CheckState) + { + _CheckState = value; + + UpdateChartItemsCheckState(); + + OnPropertyChangedEx("CheckState", VisualChangeType.Render); + } + } + } + + #endregion + + #region EffectiveStyles + + /// + /// Gets a reference to the item's Effective (cached, composite) styles. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public EffectiveStyles EffectiveStyles + { + get { return (_EffectiveStyles); } + } + + #endregion + + #region ItemText + + /// + /// Gets or sets the item Text. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the item Text.")] + public string ItemText + { + get { return (_ItemText); } + + set + { + if (value != _ItemText) + { + _ItemText = value; + + OnPropertyChangedEx("ItemText", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ItemTextBounds + + /// + /// Gets the Item's Text bounds + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle ItemTextBounds + { + get + { + Rectangle bounds = Bounds; + + int n = _MarkerSize.Width + Dpi.Width(Legend.ItemTextOffset); + + bounds.X += n; + bounds.Width -= n; + + return (bounds); + } + } + + #endregion + + #region Legend + + /// + /// Gets the associated ChartLegend + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartLegend Legend + { + get { return (Parent as ChartLegend); } + } + + #endregion + + #region MarkerBounds + + /// + /// Gets the Marker bounds + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle MarkerBounds + { + get { return (_MarkerBounds); } + } + + #endregion + + #region ShowCheckBox + + /// + /// Gets or sets whether the item CheckBox is shown in the Legend. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether the item CheckBox is shown in the Legend.")] + public Tbool ShowCheckBox + { + get { return (_ShowCheckBox); } + + set + { + if (value != _ShowCheckBox) + { + _ShowCheckBox = value; + + OnPropertyChangedEx("ShowCheckBox", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInParentLegend + + /// + /// Gets or sets whether the item is shown in parent Legend(s). + /// + [DefaultValue(Tbool.NotSet), Category("Layout")] + [Description("Indicates whether the item is shown in parent Legend(s).")] + public Tbool ShowInParentLegend + { + get { return (_ShowInParentLegend); } + + set + { + if (value != _ShowInParentLegend) + { + _ShowInParentLegend = value; + + OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowItemText + + /// + /// Gets or sets whether the item text is shown in the Legend. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether the item text is shown in the Legend.")] + public Tbool ShowItemText + { + get { return (_ShowItemText); } + + set + { + if (value != _ShowItemText) + { + _ShowItemText = value; + + OnPropertyChangedEx("ShowItemText", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowMarker + + /// + /// Gets or sets whether the item Marker is shown in the Legend. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether the item Marker is shown in the Legend.")] + public Tbool ShowMarker + { + get { return (_ShowMarker); } + + set + { + if (value != _ShowMarker) + { + _ShowMarker = value; + + OnPropertyChangedEx("ShowMarker", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region FormattedText + + internal string FormattedText + { + get { return (_FormattedText); } + set { _FormattedText = value; } + } + + #endregion + + #region IsEnabled + + internal bool IsEnabled + { + get { return (TestState(States.IsEnabled)); } + set { SetState(States.IsEnabled, value); } + } + + #endregion + + #region IsHitItem + + internal bool IsHitItem + { + get { return (TestState(States.IsHitItem)); } + set { SetState(States.IsHitItem, value); } + } + + #endregion + + #region IsLegendHitItem + + internal bool IsLegendHitItem + { + get { return (TestState(States.IsLegendHitItem)); } + set { SetState(States.IsLegendHitItem, value); } + } + + #endregion + + #region LikeItem + + internal ChartLegendItem LikeItem + { + get { return (_LikeItem ?? this); } + set { _LikeItem = value; } + } + + #endregion + + #region TextWrapped + + internal bool TextWrapped + { + get { return (TestState(States.TextWrapped)); } + set { SetState(States.TextWrapped, value); } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + BoundsRelative = layoutInfo.LayoutBounds; + + ChartLegend cl = Parent as ChartLegend; + + if (cl != null) + { + Size sizeNeeded = Size.Empty; + Rectangle layoutBounds = layoutInfo.LayoutBounds; + + ChartLegendItemVisualStyle style = EffectiveStyles[StyleType.Default]; + + if (cl.ShowMarkers == true || cl.ShowCheckBoxes == true) + { + Size size = MeasureMarker(layoutInfo, cl); + + sizeNeeded.Width += (size.Width + Dpi.Width2); + + if (cl.ShowItemText == true) + sizeNeeded.Width += Dpi.Width(cl.ItemTextOffset); + + sizeNeeded.Height = size.Height; + + layoutInfo.LayoutBounds.Width -= sizeNeeded.Width; + } + + _TextSize = Size.Empty; + + if (cl.ShowItemText == true) + { + Size size = MeasureItemText(layoutInfo, cl, style); + + sizeNeeded.Width += size.Width; + + if (size.Height > sizeNeeded.Height) + sizeNeeded.Height = size.Height; + } + + layoutInfo.LayoutBounds = layoutBounds; + + Size = sizeNeeded; + } + } + + #region MeasureMarker + + private Size MeasureMarker(ChartLayoutInfo layoutInfo, ChartLegend legend) + { + _MarkerSize = Size.Empty; + + if (legend.ShowCheckBoxes == true) + _MarkerSize = Dpi.Size(legend.CheckBoxSize); + + if (legend.ShowMarkers == true) + { + Size msize = Dpi.Size(legend.MarkerSize); + + _MarkerSize.Width = Math.Max(_MarkerSize.Width, msize.Width); + _MarkerSize.Height = Math.Max(_MarkerSize.Height, msize.Height); + } + + return (_MarkerSize); + } + + #endregion + + #region MeasureItemText + + private Size MeasureItemText( + ChartLayoutInfo layoutInfo, ChartLegend legend, ChartLegendItemVisualStyle style) + { + if (legend.ShowItemText == true && (ShowItemText != Tbool.False)) + { + Graphics g = layoutInfo.Graphics; + + string text = GetItemText(); + + if (string.IsNullOrEmpty(text) == false) + { + using (StringFormat sf = new StringFormat()) + { + style.GetStringFormatFlags(sf); + + Size size = layoutInfo.LayoutBounds.Size; + + _TextSize = g.MeasureString(text, style.Font, size, sf).ToSize(); + } + } + + _TextSize.Width++; + _TextSize.Height++; + + TextWrapped = false; + + if (style.MaxLineCount > 1) + { + if (_TextSize.Height > style.Font.Height + 2) + { + if (text.Contains("\n") == false) + TextWrapped = true; + } + + int lineHeight = style.Font.Height * style.MaxLineCount; + + if (_TextSize.Height > lineHeight) + _TextSize.Height = lineHeight; + } + } + + return (_TextSize); + } + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + BoundsRelative = layoutInfo.LayoutBounds; + + Rectangle bounds = Bounds; + _MarkerBounds = bounds; + + _MarkerBounds.X += Dpi.Width2; + + if (_MarkerSize.IsEmpty == false) + { + _MarkerBounds.Size = _MarkerSize; + + ChartLegend legend = Legend; + + if (legend != null) + { + if (bounds.Height > _MarkerBounds.Height) + _MarkerBounds.Y += (bounds.Height - _MarkerBounds.Height) / 2; + } + } + else + { + _MarkerBounds.Size = Size.Empty; + } + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + ChartLegend legend = Parent as ChartLegend; + + if (legend != null) + { + Graphics g = renderInfo.Graphics; + Rectangle bounds = Bounds; + + bool showCheckBoxes = (CanShowCheckBox(legend) == true); + + StyleState state = (IsMouseOver == true || IsHitItem == true) + ? StyleState.MouseOver : StyleState.Default; + + if (showCheckBoxes == true) + { + if (CheckState != CheckState.Unchecked) + state |= StyleState.Selected; + } + + ChartLegendItemVisualStyle istyle = EffectiveStyles[state]; + Color dcolor = GetLegendItemColor(legend, istyle); + + if (istyle.Background.IsEmpty == false) + { + using (Brush br = istyle.Background.GetBrush(bounds)) + g.FillRectangle(br, bounds); + } + + if (_MarkerSize.IsEmpty == false) + { + if (CanShowCheckBox(legend) == true) + RenderCheckBox(g, istyle, dcolor); + + else if (CanShowMarker(legend) == true) + RenderMarker(g, istyle); + + int n = _MarkerSize.Width; + + if (_TextSize.IsEmpty == false) + n += Dpi.Width(legend.ItemTextOffset); + + bounds.X += n; + bounds.Width -= n; + } + + if (_TextSize.IsEmpty == false) + RenderItemText(g, bounds, istyle, dcolor); + } + } + + #region RenderCheckBox + + private void RenderCheckBox(Graphics g, + ChartLegendItemVisualStyle istyle, Color dcolor) + { + if (_HitArea != LegendItemArea.CheckBox) + istyle = EffectiveStyles[StyleState.Default]; + + Rectangle r = _MarkerBounds; + r.Inflate(-1, -1); + + Background background = istyle.CheckBoxBackground; + + if (background.IsEmpty == false) + { + using (Brush br = background.GetBrush(r)) + g.FillRectangle(br, r); + } + + Color color = GetCheckBoxBorderColor(istyle, dcolor); + + using (Pen pen = new Pen(color, Dpi.Width1)) + g.DrawRectangle(pen, r); + + color = GetCheckBoxCheckColor(istyle, dcolor); + + Rectangle t = r; + t.Inflate(-Dpi.Width2, -Dpi.Width2); + + float fx = (float)t.Width / Dpi.Width9; + float fy = (float)t.Height / Dpi.Width9; + + switch (_CheckState) + { + case CheckState.Checked: + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + Point pt1 = new Point(t.X + (int)(fx), t.Y + (int)(fy * Dpi.Width4)); + Point pt2 = new Point(t.X + (int)(fx * Dpi.Width3), t.Bottom - Dpi.Width2); + Point pt3 = new Point(t.Right - Dpi.Width1, t.Y + (int)fy); + + using (Pen pen = new Pen(color, Dpi.Width2)) + g.DrawLines(pen, new Point[] { pt1, pt2, pt3 }); + + g.SmoothingMode = sm; + break; + + case CheckState.Indeterminate: + Rectangle z = t; + z.Inflate(-(int)fx, -(int)fy); + z.Width += Dpi.Width1; + z.Height += Dpi.Width1; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, z); + break; + } + } + + #region GetCheckBoxCheckColor + + private Color GetCheckBoxCheckColor( + ChartLegendItemVisualStyle istyle, Color dcolor) + { + Color color = istyle.CheckBoxCheckColor; + + if (color.IsEmpty == true) + color = dcolor; + + return (color); + } + + #endregion + + #region GetCheckBoxBorderColor + + private Color GetCheckBoxBorderColor( + ChartLegendItemVisualStyle istyle, Color dcolor) + { + Color color = istyle.CheckBoxBorderColor; + + if (color.IsEmpty == true) + color = dcolor; + + return (color); + } + + #endregion + + #endregion + + #region RenderMarker + + private void RenderMarker(Graphics g, ChartLegendItemVisualStyle istyle) + { + if (istyle.MarkerVisualStyle.IsEmpty == false) + { + Color color = GetLegendItemColor(Legend, istyle); + + istyle.MarkerVisualStyle.RenderMarker(g, Legend.PointMarker, MarkerBounds, color); + } + else + { + if (ChartItems.Count > 0) + { + ILegendItem item = ChartItems[0]; + + item.RenderLegendItemMarker(g, this, istyle); + } + } + } + + #endregion + + #region RenderItemText + + private void RenderItemText(Graphics g, + Rectangle bounds, ChartLegendItemVisualStyle istyle, Color dcolor) + { + bounds.Y++; + + string text = GetItemText(); + + using (StringFormat sf = new StringFormat()) + { + istyle.GetStringFormatFlags(sf); + + Color color = istyle.TextColor; + + if (color.IsEmpty == true) + color = dcolor; + + using (Brush br = new SolidBrush(color)) + g.DrawString(text, istyle.Font, br, bounds, sf); + } + } + + #endregion + + #region GetLegendItemColor + + private Color GetLegendItemColor(ChartLegend legend, ChartLegendItemVisualStyle istyle) + { + if (IsEnabled == true) + { + Color color = istyle.TextColor; + + if (color.IsEmpty == false) + return (color); + + if (ChartItems.Count > 0) + { + color = ChartItems[0].LegendItem.EffectiveStyles[StyleType.Default].TextColor; + + if (color.IsEmpty == true) + color = ChartItems[0].GetLegendItemColor(); + } + + if (color.IsEmpty == true) + color = Color.DimGray; + else + color = Color.FromArgb(255, color); + + return (color); + } + else + { + Color color = istyle.DisabledTextColor; + + if (color.IsEmpty == true) + color = Color.Silver; + + return (color); + } + } + + #endregion + + #endregion + + #region Mouse handling + + #region OnMouseEnter + + protected override bool OnMouseEnter(EventArgs e) + { + base.OnMouseEnter(e); + + InvalidateRender(); + InvalidateChartItems(true); + + return (true); + } + + #endregion + + #region OnMouseLeave + + protected override bool OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + + InvalidateRender(); + InvalidateChartItems(false); + + return (true); + } + + #endregion + + #region InvalidateChartItems + + private void InvalidateChartItems(bool isHitItem) + { + IsLegendHitItem = isHitItem; + + foreach (ILegendItem item in ChartItems) + { + ILegendItemEx itemEx = item as ILegendItemEx; + + if (itemEx != null) + { + if (itemEx.TrackLegendItem == true) + { + if (item is PieRing) + { + PieRing pieRing = (PieRing)item; + + foreach (PieSeriesPoint psp in pieRing.Psps) + { + psp.LegendItem.IsLegendHitItem = isHitItem; + psp.InvalidateRender(); + } + } + else + { + item.LegendItem.IsLegendHitItem = isHitItem; + itemEx.InvalidateRender(); + } + } + } + } + } + + #endregion + + #region OnMouseMove + + protected override bool OnMouseMove(MouseEventArgs e) + { + LegendItemArea area = GetItemAreaAt(e.Location); + + if (_HitArea != area) + InvalidateRender(); + + _HitArea = area; + + if (_HitArea == LegendItemArea.CheckBox) + { + ChartCursor = Cursors.Hand; + + return (true); + } + + return (false); + } + + #endregion + + #region OnMouseDown + + protected override bool OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + _MouseDownHitArea = _HitArea; + + if (_HitArea == LegendItemArea.CheckBox) + { + ChartControl.CapturedItem = this; + + return (true); + } + + return (false); + } + + #endregion + + #region OnMouseUp + + protected override bool OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + if (_HitArea == LegendItemArea.CheckBox && + _MouseDownHitArea == LegendItemArea.CheckBox) + { + switch (CheckState) + { + case CheckState.Checked: + CheckState = CheckState.Unchecked; + break; + + default: + CheckState = CheckState.Checked; + break; + } + + ChartControl.CapturedItem = null; + + InvalidateDisplay(); + } + + return (true); + } + + #region UpdateChartItemsCheckState + + private void UpdateChartItemsCheckState() + { + if (_InCheckStateUpdate == false) + { + _InCheckStateUpdate = true; + + if (CheckState != CheckState.Indeterminate) + { + foreach (ILegendItem item in ChartItems) + item.CheckedInLegend = (CheckState == CheckState.Checked); + } + + if (ChartControl != null) + ChartControl.DoLegendItemCheckedChangedEvent(Legend, this); + + _InCheckStateUpdate = false; + } + } + + #endregion + + #endregion + + #endregion + + #region GetItemText + + private string GetItemText() + { + string text = GetItemTextEx(); + + if (string.IsNullOrEmpty(text) == false) + { + if (ChartItems.Count > 0) + { + if (ChartItems[0] is ILegendItemEx) + { + ILegendItemEx itemEx = (ILegendItemEx)ChartItems[0]; + + text = itemEx.FormatItemText(text); + } + } + } + + return (text); + } + + #region GetItemTextEx + + private string GetItemTextEx() + { + if (String.IsNullOrEmpty(_ItemText) == false) + return (_ItemText); + + foreach (ILegendItem item in _ChartItems) + { + if (String.IsNullOrEmpty(item.LegendText) == false) + return (item.LegendText); + } + + if (_ChartItems.Count > 0) + { + if (String.IsNullOrEmpty(_ChartItems[0].Name) == false) + return (_ChartItems[0].Name); + } + + if (String.IsNullOrEmpty(Name) == false) + return (Name); + + return (""); + } + + #endregion + + #endregion + + #region GetItemAreaAt + + private LegendItemArea GetItemAreaAt(Point pt) + { + if (Bounds.Contains(pt) == true) + { + if (_MarkerBounds.Contains(pt)) + { + ChartLegend legend = Parent as ChartLegend; + + if (CanShowCheckBox(legend) == true) + return (LegendItemArea.CheckBox); + + return (LegendItemArea.Marker); + } + + if (pt.X > _MarkerBounds.Right) + return (LegendItemArea.ItemText); + } + + return (LegendItemArea.None); + } + + #endregion + + #region Style Support + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style, StyleType cs) + { + ChartLegendItemVisualStyle lstyle = style as ChartLegendItemVisualStyle; + + if (lstyle != null) + { + ApplyParentStyles(lstyle, cs, Parent as ChartVisualElement); + + lstyle.ApplyStyle(ChartLegendItemVisualStyles[cs]); + + if (ChartItems.Count > 0 && ChartItems[0] != null) + lstyle.ApplyStyle(ChartItems[0].ChartLegendItemVisualStyles[cs]); + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles( + ChartLegendItemVisualStyle lstyle, StyleType cs, ChartVisualElement item) + { + if (item != null) + { + ApplyParentStyles(lstyle, cs, item.Parent as ChartVisualElement); + + if (item is ChartLegend) + lstyle.ApplyStyle(((ChartLegend)item).ChartLegendItemVisualStyles[cs]); + + else if (item is ChartPanel) + lstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartLegendItemVisualStyles[cs]); + } + else + { + lstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartLegendItemVisualStyles[cs]); + lstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartLegendItemVisualStyles[cs]); + } + } + + #endregion + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults(BaseVisualStyle style, StyleType cs) + { + ChartLegendItemVisualStyle lstyle = style as ChartLegendItemVisualStyle; + + if (lstyle != null) + { + if (lstyle.MaxLineCount <= 0) + lstyle.MaxLineCount = 2; + + if (lstyle.Font == null) + lstyle.Font = SystemFonts.DefaultFont; + } + + base.ApplyDefaults(style, cs); + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Styles + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + EffectiveStyles.InvalidateStyles(); + } + + #endregion + + #endregion + + #region InvalidateDisplay + + private void InvalidateDisplay() + { + ChartContainer cc = ParentChartContainer; + + if (cc != null) + { + cc.InvalidateRender(GetScrollBounds(cc.ContentBounds)); + cc.InvalidateLayoutBounds(null); + } + + while (cc != null) + { + ILegendData ld = cc as ILegendData; + + if (ld != null) + { + ChartLegend legend = ld.Legend; + + if (legend != null) + { + if (CanShowInParentLegend(legend) == true) + legend.InvalidateItem(this); + } + } + + cc = cc.ParentChartContainer; + } + } + + #endregion + + #region UpdateCheckState + + internal void UpdateCheckState() + { + if (_InCheckStateUpdate == false) + { + _InCheckStateUpdate = true; + + if (ChartItems.Count > 0) + { + CheckState checkState = CheckState.Unchecked; + + for (int i = 0; i < ChartItems.Count; i++) + { + ILegendItem chartItem = ChartItems[i]; + + CheckState ics = chartItem.CheckedInLegend ? CheckState.Checked : CheckState.Unchecked; + + if (i == 0) + { + checkState = ics; + } + else + { + if (checkState != ics) + { + checkState = CheckState.Indeterminate; + break; + } + } + } + + if (CheckState != checkState) + { + CheckState = checkState; + + InvalidateDisplay(); + } + } + + _InCheckStateUpdate = false; + } + } + + #endregion + + #region CanShowCheckBox + + private bool CanShowCheckBox(ChartLegend legend) + { + if (legend.ShowCheckBoxes == true) + { + if (ShowCheckBox != Tbool.NotSet) + { + bool show = (ShowCheckBox == Tbool.False ? false : true); + + if (ChartItems.Count > 0) + ChartItems[0].ShowCheckBoxInLegend = show; + + return (show); + } + + if (ChartItems.Count > 0) + return (ChartItems[0].ShowCheckBoxInLegend); + + return (true); + } + + return (false); + } + + #endregion + + #region CanShowMarker + + private bool CanShowMarker(ChartLegend legend) + { + if (legend.ShowMarkers == true) + { + if (ShowMarker == Tbool.NotSet) + { + if (ChartItems.Count > 0) + return (ChartItems[0].ShowMarkerInLegend); + } + + return (ShowMarker == Tbool.False ? false : true); + } + + return (false); + } + + #endregion + + #region CanShowInParentLegend + + private bool CanShowInParentLegend(ChartLegend legend) + { + if (ChartItems.Count > 0) + { + if (ShowInParentLegend == Tbool.NotSet) + return (ChartItems[0].ShowInParentLegend); + + return (ShowInParentLegend == Tbool.False ? false : true); + } + + return (false); + } + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartLegendItem copy = new ChartLegendItem(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartLegendItem c = copy as ChartLegendItem; + + if (c != null) + { + base.CopyTo(c); + + c.ChartLegendItemVisualStyles = + (_ChartLegendItemVisualStyles != null) ? ChartLegendItemVisualStyles.Copy() : null; + + c.CheckState = CheckState; + c.ItemText = ItemText; + c.ShowCheckBox = ShowCheckBox; + c.ShowInParentLegend = ShowInParentLegend; + c.ShowItemText = ShowItemText; + c.ShowMarker = ShowMarker; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "BaseChart"; + + sec.AddStartElement(serialName); + } + + if (_ChartLegendItemVisualStyles != null) + sec.AddElement(_ChartLegendItemVisualStyles.GetSerialData("ChartLegendItemVisualStyles")); + + sec.AddValue("CheckState", CheckState, CheckState.Unchecked); + sec.AddValue("ItemText", ItemText, null); + sec.AddValue("ShowCheckBox", ShowCheckBox, Tbool.NotSet); + sec.AddValue("ShowInParentLegend", ShowInParentLegend, Tbool.NotSet); + sec.AddValue("ShowItemText", ShowItemText, Tbool.NotSet); + sec.AddValue("ShowMarker", ShowMarker, Tbool.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "CheckState": + CheckState = (CheckState)se.GetValueEnum(typeof(CheckState)); + break; + + case "ItemText": + ItemText = se.StringValue; + break; + + case "ShowCheckBox": + ShowCheckBox = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShowInParentLegend": + ShowInParentLegend = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShowItemText": + ShowItemText = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShowMarker": + ShowMarker = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartLegendItemVisualStyles": + sec.PutSerialData(ChartLegendItemVisualStyles); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + IsEnabled = (1U << 0), + + IsHitItem = (1 << 1), + IsLegendHitItem = (1 << 2), + + TextWrapped = (1U << 3), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + ChartLegendItemVisualStyles = null; + + base.Dispose(); + } + + #endregion + } + + #region enums + + #region LegendItemArea + + public enum LegendItemArea + { + None = 0, + + CheckBox, + ItemText, + Marker, + } + + #endregion + + #endregion + + #region Interfaces + + #region ILegendItem + + public interface ILegendItem + { + string Name { get; set; } + string LegendText { get; set; } + + ChartLegendItem LegendItem { get; } + ChartLegendItem GetLegendItem(); + List GetLegendItems(); + + Color GetLegendItemColor(); + + bool ShowInLegend { get; set; } + bool ShowInParentLegend { get; set; } + bool ShowCheckBoxInLegend { get; set; } + bool ShowMarkerInLegend { get; set; } + bool CheckedInLegend { get; set; } + + void RenderLegendItemMarker(Graphics g, ChartLegendItem item, ChartLegendItemVisualStyle style); + + ChartLegendItemVisualStyles ChartLegendItemVisualStyles { get; set; } + } + + #endregion + + #region ILegendItem + + internal interface ILegendItemEx + { + bool TrackLegendItem { get; } + + void InvalidateRender(); + string FormatItemText(string text); + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartMatrix.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartMatrix.cs new file mode 100644 index 00000000..13f85e6a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartMatrix.cs @@ -0,0 +1,1046 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts +{ + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartMatrix : IProcessSerialElement + { + #region Private variables + + private States _States; + + private int _Width; + private int _Height; + + private ChartContainer[,] _LocalArray; + private Rectangle[,] _BoundsArray; + + private Point _ScrollOffset; + + private MatrixRowColProperties[] _ColumnProperties; + private MatrixRowColProperties[] _RowProperties; + + private Size _DefaultCellSize = new Size(100, 100); + + private AutoSizeMode _AutoSizeMode = AutoSizeMode.NotSet; + private DividerLines _DividerLines = DividerLines.NotSet; + + private ChartContainer _Parent; + + #endregion + + #region Constructors + + public ChartMatrix() + : this(0, 0) + { + } + + public ChartMatrix(Size size) + : this(size.Width, size.Height) + { + } + + public ChartMatrix(int width, int height) + { + CreateMatrix(width, height); + } + + #endregion + + #region Public properties + + #region AutoSizeMode + + /// + /// Gets or sets the default mode used to size each matrix row/col (by FillWeight, etc). + /// + [DefaultValue(AutoSizeMode.NotSet), Category("Layout")] + [Description("Indicates the default mode used to size each matrix row/col (by FillWeight, etc).")] + public AutoSizeMode AutoSizeMode + { + get { return (_AutoSizeMode); } + + set + { + if (value != _AutoSizeMode) + { + _AutoSizeMode = value; + + OnPropertyChanged("AutoSizeMode"); + } + } + } + + #endregion + + #region ColumnProperties + + /// + /// Get a reference to the matrix column properties. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public MatrixRowColProperties[] ColumnProperties + { + get { return (_ColumnProperties); } + } + + #endregion + + #region DefaultCellSize + + /// + /// Gets or sets the default minimum size for each matrix cell. + /// + [ Category("Layout")] + [Description("Indicates the default minimum size for each matrix cell.")] + public Size DefaultCellSize + { + get { return (_DefaultCellSize); } + + set + { + if (value != _DefaultCellSize) + { + _DefaultCellSize = value; + + OnPropertyChanged("DefaultCellSize"); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeDefaultCellSize() + { + return (_DefaultCellSize != new Size(100, 100)); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetDefaultCellSize() + { + DefaultCellSize = new Size(100, 100); + } + + #endregion + + #region DividerLines + + /// + /// Gets or sets which Divider lines (horizontal and/or vertical) + /// are displayed between each Matrix cell. + /// + [DefaultValue(DividerLines.NotSet), Category("Appearance")] + [Description("Indicates which Divider lines (horizontal and/or vertical) are displayed between each Matrix cell.")] + public DividerLines DividerLines + { + get { return (_DividerLines); } + + set + { + if (_DividerLines != value) + { + _DividerLines = value; + + OnPropertyChanged("DividerLines"); + } + } + } + + #endregion + + #region Indexer [,] + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartContainer this[int x, int y] + { + get + { + ValidateXandY(x, y); + + return (_LocalArray[x, y]); + } + + internal set + { + ValidateXandY(x, y); + + if (value is IComparable == true) + { + if (((IComparable)value).CompareTo(_LocalArray[x, y]) == 0) + return; + } + + _LocalArray[x, y] = value; + + if (value != null) + value.Parent = Parent; + + OnPropertyChanged("Value"); + } + } + + #endregion + + #region Indexer [] + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartContainer this[int xy] + { + get + { + ValidateXY(xy); + + int y = xy / _Width; + int x = xy % _Width; + + return (this[x, y]); + } + + internal set + { + ValidateXY(xy); + + int y = xy / _Width; + int x = xy % _Width; + + this[x, y] = value; + + OnPropertyChanged("Value"); + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the matrix is empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + for (int i = 0; i < _Width; i++) + { + for (int j = 0; j < _Height; j++) + { + if (_LocalArray[i, j] != null) + return (false); + } + } + + return (true); + } + } + + #endregion + + #region Height + + /// + /// Gets or sets the matrix height. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Height + { + get { return (_Height); } + + set + { + if (value != _Height) + { + _Height = value; + + CreateMatrix(_Width, _Height); + + OnPropertyChanged("Height"); + } + } + } + + #endregion + + #region RowProperties + + /// + /// Get a reference to the matrix row properties. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public MatrixRowColProperties[] RowProperties + { + get { return (_RowProperties); } + } + + #endregion + + #region Size + + /// + /// Gets or sets the matrix size. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Size Size + { + get + { + int x = _Width; + int y = _Height; + + return (new Size(x, y)); + } + + set + { + if (value.Width != _Width || value.Height != _Height) + { + int x = value.Width; + int y = value.Height; + + CreateMatrix(x, y); + + OnPropertyChanged("Size"); + } + } + } + + #endregion + + #region Width + + /// + /// Gets or sets the matrix width. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Width + { + get { return (_Width); } + + set + { + if (value != _Width) + { + _Width = value; + + CreateMatrix(_Width, _Height); + + OnPropertyChanged("Width"); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region BoundsArray + + internal Rectangle[,] BoundsArray + { + get { return (_BoundsArray); } + } + + #endregion + + #region Parent + + internal ChartContainer Parent + { + get { return (_Parent); } + set { _Parent = value; } + } + + #endregion + + #region ScrollOffset + + internal Point ScrollOffset + { + get { return (_ScrollOffset); } + set { _ScrollOffset = value; } + } + + #endregion + + #endregion + + #region ValidateXandY + + protected void ValidateXandY(int x, int y) + { + if ((uint)x >= _Width) + throw new IndexOutOfRangeException("Invalid 'x' value."); + + if ((uint)y >= _Height) + throw new IndexOutOfRangeException("Invalid 'y' value."); + } + + #endregion + + #region ValidateXY + + protected void ValidateXY(int xy) + { + int xyMax = _Width * _Height; + + if (xy >= xyMax) + throw new IndexOutOfRangeException("Invalid 'xy' value."); + } + + #endregion + + #region CreateMatrix + + private void CreateMatrix(int width, int height) + { + if (width < 0) + throw new Exception("Width cannot be negative"); + + if (height < 0) + throw new Exception("Heigth cannot be negative"); + + _Width = width; + _Height = height; + + _LocalArray = new ChartContainer[width, height]; + _BoundsArray = new Rectangle[width, height]; + + CreateProperties(ref _RowProperties, height); + CreateProperties(ref _ColumnProperties, width); + } + + #endregion + + #region CreateProperties + + private void CreateProperties(ref MatrixRowColProperties[] properties, int length) + { + ReleaseProperties(ref properties); + + properties = new MatrixRowColProperties[length]; + + for (int i = 0; i < length; i++) + { + properties[i] = new MatrixRowColProperties(); + properties[i].PropertyChanged += Matrix_PropertyChanged; + } + } + + #endregion + + #region ReleaseProperties + + private void ReleaseProperties(ref MatrixRowColProperties[] properties) + { + if (properties != null) + { + for (int i = 0; i < properties.Length; i++) + { + properties[i].PropertyChanged -= Matrix_PropertyChanged; + properties[i] = null; + } + + properties = null; + } + } + + #endregion + + #region Clear + + public void Clear() + { + CreateMatrix(_Width, _Height); + } + + #endregion + + #region GetElementAt + + public ChartContainer GetElementAt(Point pt) + { + for (int i = 0; i < _Width; i++) + { + for (int j = 0; j < _Height; j++) + { + if (_LocalArray[i, j] != null) + { + Rectangle bounds = _BoundsArray[i, j]; + + bounds.X -= _ScrollOffset.X; + bounds.Y -= _ScrollOffset.Y; + + if (bounds.Contains(pt)) + return (_LocalArray[i, j]); + } + } + } + + return (null); + } + + #endregion + + #region GetMatrixCoordAt + + public bool GetMatrixCoordAt(Point pt, ref int column, ref int row) + { + for (int i = 0; i < _Width; i++) + { + for (int j = 0; j < _Height; j++) + { + Rectangle bounds = _BoundsArray[i, j]; + + bounds.X -= _ScrollOffset.X; + bounds.Y -= _ScrollOffset.Y; + + if (bounds.Contains(pt)) + { + column = i; + row = j; + + return (true); + } + } + } + + return (false); + } + + #endregion + + #region GetMatrixCoordOf + + public bool GetMatrixCoordOf(ChartContainer item, ref int row, ref int column) + { + if (item != null) + { + for (int i = 0; i < _Width; i++) + { + for (int j = 0; j < _Height; j++) + { + if (item.Equals(_LocalArray[i, j])) + { + column = i; + row = j; + + return (true); + } + } + } + } + + return (false); + } + + #endregion + + #region Matrix_PropertyChanged + + void Matrix_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + #endregion + + #region Copy/CopyTo + + public ChartMatrix Copy() + { + ChartMatrix copy = new ChartMatrix(); + + CopyTo(copy); + + return (copy); + } + + public void CopyTo(ChartMatrix c) + { + c.AutoSizeMode = AutoSizeMode; + c.DividerLines = DividerLines; + + c.Size = Size; + + if (ColumnProperties != null) + { + for (int i = 0; i < ColumnProperties.Length; i++) + ColumnProperties[i].CopyTo(c.ColumnProperties[i]); + } + + if (RowProperties != null) + { + for (int i = 0; i < RowProperties.Length; i++) + RowProperties[i].CopyTo(c.RowProperties[i]); + } + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData() + { + return (GetSerialData(true)); + } + + internal SerialElementCollection GetSerialData(bool root) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (root == true) + sec.AddStartElement("ChartMatrix"); + + sec.AddValue("AutoSizeMode", AutoSizeMode, AutoSizeMode.NotSet); + sec.AddValue("DividerLines", DividerLines, DividerLines.NotSet); + + ChartPanel panel = Parent as ChartPanel; + + if (panel != null) + { + if (panel.AutoSizeChartMatrix == false) + sec.AddValue("Size", Size, Size.Empty); + } + + if (AutoSizeMode == AutoSizeMode.None) + { + if (ColumnProperties != null && ColumnProperties.Length > 0) + { + sec.AddStartElement("ColumnProperties count=\"" + ColumnProperties.Length + "\""); + + foreach (MatrixRowColProperties rcp in ColumnProperties) + sec.AddElement(rcp.GetSerialData()); + + sec.AddEndElement("ColumnProperties"); + } + + if (RowProperties != null && RowProperties.Length > 0) + { + sec.AddStartElement("RowProperties count=\"" + RowProperties.Length + "\""); + + foreach (MatrixRowColProperties rcp in RowProperties) + sec.AddElement(rcp.GetSerialData()); + + sec.AddEndElement("RowProperties"); + } + } + + if (root == true) + sec.AddEndElement("ChartMatrix"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + ChartPanel panel = Parent as ChartPanel; + + switch (se.Name) + { + case "AutoSizeMode": + AutoSizeMode = (AutoSizeMode)se.GetValueEnum(typeof(AutoSizeMode)); + break; + + case "DividerLines": + DividerLines = (DividerLines)se.GetValueEnum(typeof(DividerLines)); + break; + + case "Size": + if (panel != null) + { + if (panel.AutoSizeChartMatrix == false) + Size = se.GetValueSize(); + } + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + private MatrixRowColProperties[] _RcProperties; + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ColumnProperties": + _RcProperties = ColumnProperties; + sec.PutSerialData(this); + break; + + case "RowProperties": + _RcProperties = RowProperties; + sec.PutSerialData(this); + break; + + case "MatrixRowColProperties": + sec.PutSerialData(_RcProperties[se.ValueIndex]); + break; + + default: + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public virtual void Dispose() + { + ReleaseProperties(ref _RowProperties); + ReleaseProperties(ref _ColumnProperties); + } + + #endregion + } + + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class MatrixRowColProperties : IProcessSerialElement, INotifyPropertyChanged + { + #region Private variables + + private int _FillWeight = 100; + private int _MinimumLength = 0; + private int _Length; + + private AutoSizeMode _AutoSizeMode = AutoSizeMode.NotSet; + private bool _AlignContentBounds = true; + + #endregion + + #region Public properties + + #region AlignContentBounds + + /// + /// Gets or sets whether the matrix row/col has its content bounds aligned. + /// + [DefaultValue(true), Category("Data")] + [Description("Indicates the matrix row/col has its content bounds aligned.")] + public bool AlignContentBounds + { + get { return (_AlignContentBounds); } + + set + { + if (value != _AlignContentBounds) + { + _AlignContentBounds = value; + + OnPropertyChanged("AlignContentBounds"); + } + } + } + + #endregion + + #region AutoSizeMode + + /// + /// Gets or sets the mode used to size the matrix row/col. + /// + [DefaultValue(AutoSizeMode.NotSet), Category("Data")] + [Description("Indicates the mode used to sice the matrix row/col.")] + public AutoSizeMode AutoSizeMode + { + get { return (_AutoSizeMode); } + + set + { + if (value != _AutoSizeMode) + { + _AutoSizeMode = value; + + OnPropertyChanged("AutoSizeMode"); + } + } + } + + #endregion + + #region FillWeight + + /// + /// Gets or sets a value which, when AutoSizeMode is Fill, + /// represents the width of the row/col relative to the widths + /// of other fill-mode row/col items (default value is 100). + /// + [DefaultValue(100), Category("Sizing")] + [Description("Indicates a value which, when AutoSizeMode is Fill, represents the width of the row/col relative to the widths of other fill-mode row/col items (default value is 100).")] + public int FillWeight + { + get { return (_FillWeight); } + + set + { + if (value != _FillWeight) + { + _FillWeight = value; + + OnPropertyChanged("FillWeight"); + } + } + } + + #endregion + + #region Length + + /// + /// Gets or sets a value which represents the length (in pixels) + /// that the row/col is to occupy. + /// + [DefaultValue(0), Category("Sizing")] + [Description("Indicates a value which represents the length (in pixels) that the row/col is to occupy.")] + public int Length + { + get { return (_Length); } + + set + { + if (value != _Length) + { + _Length = value; + + OnPropertyChanged("Length"); + } + } + } + + #endregion + + #region MinimumLength + + /// + /// Gets or sets a value which represents the minimum length (in pixels) + /// that the row/col can occupy. + /// + [DefaultValue(0), Category("Sizing")] + [Description("Indicates a value which represents the minimum length (in pixels) that the row/col can occupy.")] + public int MinimumLength + { + get { return (_MinimumLength); } + + set + { + if (value != _MinimumLength) + { + _MinimumLength = value; + + OnPropertyChanged("MinimumLength"); + } + } + } + + #endregion + + #endregion + + #region CopyTo + + public void CopyTo(MatrixRowColProperties c) + { + c.AlignContentBounds = AlignContentBounds; + c.AutoSizeMode = AutoSizeMode; + c.FillWeight = FillWeight; + c.Length = Length; + c.MinimumLength = MinimumLength; + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData() + { + return (GetSerialData(true)); + } + + internal SerialElementCollection GetSerialData(bool root) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (root == true) + sec.AddStartElement("MatrixRowColProperties"); + + sec.AddValue("AlignContentBounds", AlignContentBounds, true); + sec.AddValue("AutoSizeMode", AutoSizeMode, AutoSizeMode.NotSet); + sec.AddValue("FillWeight", FillWeight, 100); + sec.AddValue("Length", Length, 0); + sec.AddValue("MinimumLength", MinimumLength, 0); + + if (root == true) + sec.AddEndElement("MatrixRowColProperties"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AlignContentBounds": + AlignContentBounds = bool.Parse(se.StringValue); + break; + + case "AutoSizeMode": + AutoSizeMode = (AutoSizeMode)se.GetValueEnum(typeof(AutoSizeMode)); + break; + + case "FillWeight": + FillWeight = int.Parse(se.StringValue); + break; + + case "Length": + Length = int.Parse(se.StringValue); + break; + + case "MinimumLength": + MinimumLength = int.Parse(se.StringValue); + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartNote.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartNote.cs new file mode 100644 index 00000000..751c70c7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartNote.cs @@ -0,0 +1,362 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using DevComponents.Charts.TextMarkup; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// ChartNote. + /// + public class ChartNote : ChartVisualElement + { + #region Private variables + + private States _States; + + private string _Text; + private BodyElement _TextMarkup; + private int _FixedHeight; + + #endregion + + #region Public properties + + #region EnableTextMarkup + + /// + /// Gets or sets whether text-markup support is enabled + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled.")] + public bool EnableTextMarkup + { + get { return (TestState(States.EnableTextMarkup)); } + + set + { + if (EnableTextMarkup != value) + { + SetState(States.EnableTextMarkup, value); + + MarkupTextChanged(); + + OnPropertyChangedEx("EnableTextMarkup", VisualChangeType.Layout); + } + } + } + + #region MarkupTextChanged + + private void MarkupTextChanged() + { + if (_TextMarkup != null) + _TextMarkup.HyperLinkClick -= TextMarkupLinkClick; + + _TextMarkup = null; + + if (EnableTextMarkup == true) + { + if (MarkupParser.IsMarkup(_Text) == true) + { + _TextMarkup = MarkupParser.Parse(_Text); + + if (_TextMarkup != null) + _TextMarkup.HyperLinkClick += TextMarkupLinkClick; + } + } + } + + #endregion + + #region TextMarkupLinkClick + + /// + /// Occurs when a text markup link is clicked + /// + protected virtual void TextMarkupLinkClick(object sender, EventArgs e) + { + HyperLink link = sender as HyperLink; + + if (link != null) + ChartControl.DoChartTitleMarkupLinkClickEvent(this, link); + } + + #endregion + + #endregion + + #region PlainText + + /// + /// Gets text without text-markup (if text-markup is used in Text) + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public string PlainText + { + get { return (_TextMarkup != null ? _TextMarkup.PlainText : _Text); } + } + + #endregion + + #region FixedHeight + + /// + /// Gets or sets the fixed Text height (0 to auto-size) + /// + [DefaultValue(0), Category("Layout")] + [Description("Indicates the fixed Text height (0 to auto-size)")] + public int FixedHeight + { + get { return (_FixedHeight); } + + set + { + if (value != _FixedHeight) + { + _FixedHeight = value; + + OnPropertyChangedEx("FixedHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Text + + /// + /// Gets or sets the item Text. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the item Text.")] + [Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Text + { + get { return (_Text); } + + set + { + _Text = value; + + MarkupTextChanged(); + + OnPropertyChangedEx("Text", VisualChangeType.Layout); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region TextMarkup + + internal BodyElement TextMarkup + { + get { return (_TextMarkup); } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + throw new NotImplementedException(); + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + throw new NotImplementedException(); + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + throw new NotImplementedException(); + } + + #endregion + + #region Mouse handling + + #region OnMouseEnter + + protected override bool OnMouseEnter(EventArgs e) + { + return (true); + } + + #endregion + + #region OnMouseLeave + + protected override bool OnMouseLeave(EventArgs e) + { + return (true); + } + + #endregion + + #region OnMouseMove + + protected override bool OnMouseMove(MouseEventArgs e) + { + ChartCursor = Cursors.Default; + + return (false); + } + + #endregion + + #region OnMouseDown + + protected override bool OnMouseDown(MouseEventArgs e) + { + return (false); + } + + #endregion + + #region OnMouseUp + + protected override bool OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + return (true); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartNote copy = new ChartNote(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartNote c = copy as ChartNote; + + if (c != null) + { + base.CopyTo(c); + + c.EnableTextMarkup = EnableTextMarkup; + c.FixedHeight = FixedHeight; + c.Text = Text; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartNote"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("EnableTextMarkup", EnableTextMarkup, false); + sec.AddValue("FixedHeight", FixedHeight, 0); + sec.AddValue("Text", Text, null); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "EnableTextMarkup": + EnableTextMarkup = bool.Parse(se.StringValue); + break; + + case "FixedHeight": + FixedHeight = int.Parse(se.StringValue); + break; + + case "Text": + Text = se.StringValue; + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + EnableTextMarkup = (1U << 0), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartPanel.cs new file mode 100644 index 00000000..09337883 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartPanel.cs @@ -0,0 +1,2320 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// ChartPanel is a container object which holds + /// and defines ChartGraphs, which can be single or multiple. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartPanel : ChartContainer, IEffectiveStyle + { + #region Private variables + + private States _States; + + private ChartContainerCollection _ChartContainers; + private ContainerLayout _ContainerLayout = ContainerLayout.Auto; + + private ChartMatrix _ChartMatrix; + private List _MatrixList; + + private DefaultVisualStyles _DefaultVisualStyles; + + private ChartPanelVisualStyle _ChartPanelVisualStyle; + private EffectiveStyle _EffectivePanelStyle; + + private List _LegendData; + private LegendSource _LegendSource = (LegendSource.NestedCharts | LegendSource.NestedPanels); + + #endregion + + public ChartPanel(string name) + : this() + { + Name = name; + } + + public ChartPanel() + { + InitDefaultStates(); + + _EffectivePanelStyle = new EffectiveStyle(this); + + Legend.Visible = false; + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.AutoFillChartMatrix, true); + SetState(States.AutoSizeChartMatrix, true); + } + + #endregion + + #region Public properties + + #region AutoFillChartMatrix + + /// + /// Gets or sets whether the ChartMatrix is auto filled + /// from the ChartContainer collection. + /// + [DefaultValue(true), Category("Layout")] + [Description("Indicates whether the ChartMatrix is auto filled from the ChartContainer collection.")] + public bool AutoFillChartMatrix + { + get { return (TestState(States.AutoFillChartMatrix)); } + + set + { + if (value != AutoFillChartMatrix) + { + SetState(States.AutoFillChartMatrix, value); + + OnPropertyChangedEx("AutoFillChartMatrix", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AutoGenSeriesCollection + + /// + /// Gets or sets whether series definitions are auto generated from the set DataSource. + /// + [DefaultValue(false), Category("Data")] + [Description("Indicates whether series definitions are auto generated from the set DataSource.")] + public bool AutoGenSeriesCollection + { + get { return (TestState(States.AutoGenSeriesCollection)); } + + set + { + if (value != AutoGenSeriesCollection) + { + SetState(States.AutoGenSeriesCollection, value); + + OnPropertyChangedEx("AutoGenSeriesCollection", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AutoSizeChartMatrix + + /// + /// Gets or sets whether the ChartMatrix is auto sized + /// from the ChartContainer collection. + /// + [DefaultValue(true), Category("Layout")] + [Description("Indicates whether the ChartMatrix is auto sized from the ChartContainer collection.")] + public bool AutoSizeChartMatrix + { + get { return (TestState(States.AutoSizeChartMatrix)); } + + set + { + if (value != AutoSizeChartMatrix) + { + SetState(States.AutoSizeChartMatrix, value); + + OnPropertyChangedEx("AutoSizeChartMatrix", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ChartContainers + + /// + /// Gets a reference to the collection of Chart Containers (ChartPanels and Chart graphs). + /// + [Category("Layout")] + [Description("Indicates the reference to the collection of Chart Containers (ChartPanels and Chart graphs).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartContainerCollection ChartContainers + { + get + { + if (_ChartContainers == null) + { + _ChartContainers = new ChartContainerCollection(); + + _ChartContainers.CollectionChanged += ChartContainersCollectionChanged; + } + + return (_ChartContainers); + } + + internal set + { + if (_ChartContainers != null) + _ChartContainers.CollectionChanged -= ChartContainersCollectionChanged; + + _ChartContainers = value; + + if (_ChartContainers != null) + _ChartContainers.CollectionChanged += ChartContainersCollectionChanged; + } + } + + #region ChartContainersCollectionChanged + + void ChartContainersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + ChartControl chartControl = ChartControl; + + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (ChartContainer item in e.NewItems) + { + item.Parent = this; + + if (chartControl != null) + AddSelectedItems(chartControl, item); + } + break; + + case NotifyCollectionChangedAction.Replace: + foreach (ChartContainer item in e.OldItems) + { + if (chartControl != null) + RemoveSelectedItems(chartControl, item); + + item.Parent = null; + } + + foreach (ChartContainer item in e.NewItems) + { + item.Parent = this; + + if (chartControl != null) + AddSelectedItems(chartControl, item); + } + break; + + case NotifyCollectionChangedAction.Remove: + foreach (ChartContainer item in e.OldItems) + { + item.Parent = null; + + if (chartControl != null) + RemoveSelectedItems(chartControl, item); + } + break; + } + + InvalidateLayout(); + } + + #region AddSelectedItems + + private void AddSelectedItems(ChartControl chartControl, ChartContainer item) + { + BaseChart chart = item as BaseChart; + + if (chart != null) + { + if (chart.IsSelected == true) + chartControl.SetSelected(item, true); + } + else if (item is ChartPanel) + { + foreach (ChartContainer citem in ((ChartPanel)item).ChartContainers) + AddSelectedItems(chartControl, citem); + } + } + + #endregion + + #region RemoveSelectedItems + + private void RemoveSelectedItems(ChartControl chartControl, ChartContainer item) + { + BaseChart chart = item as BaseChart; + + if (chart != null) + { + if (chart.IsSelected == true) + chartControl.SetSelected(item, false); + } + else if (item is ChartPanel) + { + foreach (ChartContainer citem in ((ChartPanel)item).ChartContainers) + RemoveSelectedItems(chartControl, citem); + } + } + + #endregion + + #endregion + + #endregion + + #region ChartMatrix + + /// + /// Gets the Matrix used to display the defined Panels and Charts in a Matrix format. + /// + [Category("Layout")] + [Description("Indicates the Matrix used to display the defined Panels and Charts in a Matrix format.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartMatrix ChartMatrix + { + get + { + if (_ChartMatrix == null) + { + _ChartMatrix = new ChartMatrix(); + _ChartMatrix.Parent = this; + + _ChartMatrix.PropertyChanged += ChartMatrix_PropertyChanged; + } + + return (_ChartMatrix); + } + + internal set + { + if (_ChartMatrix != value) + { + if (_ChartMatrix != null) + { + _ChartMatrix.PropertyChanged -= ChartMatrix_PropertyChanged; + _ChartMatrix.Parent = null; + } + + _ChartMatrix = value; + + if (_ChartMatrix != null) + { + _ChartMatrix.Parent = this; + _ChartMatrix.PropertyChanged += ChartMatrix_PropertyChanged; + } + } + } + } + + #region ChartMatrix_PropertyChanged + + void ChartMatrix_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (ChartControl != null) + { + if (e.PropertyName.Equals("Size") || e.PropertyName.Equals("Height") || e.PropertyName.Equals("Width")) + ChartControl.DoChartMatrixResizedEvent(this); + + if (ChartControl.InUpdateLayout == false) + InvalidateLayout(); + } + } + + #endregion + + #endregion + + #region ChartPanelVisualStyle + + /// + /// Gets or sets the visual style for the Chart Panel. + /// + [Category("Style")] + [Description("Indicates the visual style for the Chart Panel.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartPanelVisualStyle ChartPanelVisualStyle + { + get + { + if (_ChartPanelVisualStyle == null) + { + _ChartPanelVisualStyle = new ChartPanelVisualStyle(); + + StyleVisualChangeHandler(null, _ChartPanelVisualStyle); + } + + return (_ChartPanelVisualStyle); + } + + set + { + if (_ChartPanelVisualStyle != value) + { + ChartPanelVisualStyle oldValue = _ChartPanelVisualStyle; + + _ChartPanelVisualStyle = value; + + OnStyleChanged("ChartPanelVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ContainerLayout + + /// + /// Gets or sets the layout (horizontal, vertical, matrix) for the defined Chart Containers. + /// + [DefaultValue(ContainerLayout.Auto), Category("Layout")] + [Description("Indicates the layout (horizontal, vertical, matrix) for the defined Chart Containers.")] + public ContainerLayout ContainerLayout + { + get { return (_ContainerLayout); } + + set + { + if (_ContainerLayout != value) + { + _ContainerLayout = value; + + OnPropertyChangedEx("ContainerLayout", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DefaultVisualStyles + + /// + /// Gets or sets the Default Visual Styles for each Chart element. + /// + [Browsable(true), Category("Style"), DefaultValue(null)] + [Description("Indicates the Default Visual Styles for each Chart element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DefaultVisualStyles DefaultVisualStyles + { + get + { + if (_DefaultVisualStyles == null) + { + _DefaultVisualStyles = new DefaultVisualStyles(); + + _DefaultVisualStyles.PropertyChanged += DefaultVisualStylesPropertyChanged; + } + + return (_DefaultVisualStyles); + } + + set + { + if (_DefaultVisualStyles != value) + { + if (_DefaultVisualStyles != null) + _DefaultVisualStyles.PropertyChanged -= DefaultVisualStylesPropertyChanged; + + _DefaultVisualStyles = value; + + if (_DefaultVisualStyles != null) + _DefaultVisualStyles.PropertyChanged += DefaultVisualStylesPropertyChanged; + } + } + } + + #region DefaultVisualStylesPropertyChanged + + private void DefaultVisualStylesPropertyChanged(object sender, PropertyChangedEventArgs e) + { + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + switch (changeType) + { + case VisualChangeType.Layout: + InvalidateRender(); + break; + + case VisualChangeType.Render: + InvalidateRender(); + break; + } + + //ChartControl cc = ChartControl; + + //if (cc != null) + // cc.UpdateStyleCount(); + } + + #endregion + + #endregion + + #region EffectivePanelStyle + + /// + /// Gets a reference to the panel's effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartPanelVisualStyle EffectivePanelStyle + { + get { return (_EffectivePanelStyle.Style); } + } + + #endregion + + #region LegendSource + + /// + /// Gets or sets the source for the items in the panel legend. + /// + [Category("Layout")] + [Description("Indicates the source for the items in the panel legend.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public LegendSource LegendSource + { + get { return (_LegendSource); } + + set + { + if (value != _LegendSource) + { + _LegendSource = value; + + OnPropertyChangedEx("LegendSource", VisualChangeType.Layout); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeLegendSource() + { + return (_LegendSource != (LegendSource.NestedCharts | LegendSource.NestedPanels)); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetLegendSource() + { + LegendSource = (LegendSource.NestedCharts | LegendSource.NestedPanels); + } + + #endregion + + #endregion + + #region Internal properties + + #region LegendData + + internal List LegendData + { + get { return (_LegendData); } + + set + { + if (_LegendData != null) + { + foreach (ChartLegendItem item in _LegendData) + item.Dispose(); + } + + _LegendData = value; + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + ChartPanelVisualStyle pstyle = EffectivePanelStyle; + ContainerVisualStyle cstyle = GetEffectiveContainerStyle(); + + if (cstyle.DropShadow.Enabled == Tbool.True) + { + layoutInfo.LayoutBounds.Height -= 3; + layoutInfo.LayoutBounds.Width -= 3; + } + + BoundsRelative = layoutInfo.LayoutBounds; + + FrameBounds = GetAdjustedBounds(BoundsRelative, cstyle.Margin); + ContentBounds = GetAdjustedBounds(FrameBounds, cstyle.BorderThickness); + ContentBounds = GetAdjustedBounds(ContentBounds, cstyle.Padding); + + layoutInfo.LayoutBounds = ContentBounds; + + base.MeasureOverride(layoutInfo); + + ContentBounds = layoutInfo.LayoutBounds; + ContentBoundsEx = ContentBounds; + + if (AutoFillChartMatrix == true) + AutoFillMatrix(layoutInfo); + else + FillMatrix(); + + Size size = MeasureMatrix(layoutInfo, pstyle); + + Size minContentSize = Dpi.Size(MinContentSize); + + if (size.Width < minContentSize.Width) + size.Width = minContentSize.Width; + + if (size.Height < minContentSize.Height) + size.Height = minContentSize.Height; + + Rectangle r = ContentBoundsEx; + + if (size.Width > r.Width) + r.Width = size.Width; + + if (size.Height > r.Height) + r.Height = size.Height; + + ContentBoundsEx = r; + + if ((ContentBoundsEx.Width > ContentBounds.Width && ContentBoundsEx.Height == ContentBounds.Height) || + (ContentBoundsEx.Height > ContentBounds.Height && ContentBoundsEx.Width == ContentBounds.Width)) + { + layoutInfo.LayoutBounds = ContentBounds; + + if (ContentBoundsEx.Width > ContentBounds.Width) + layoutInfo.LayoutBounds.Height -= (HScrollBar.Height + 1); + + if (ContentBoundsEx.Height > ContentBounds.Height) + layoutInfo.LayoutBounds.Width -= (VScrollBar.Width + 1); + + size = MeasureMatrix(layoutInfo, pstyle); + + if (size.IsEmpty == false) + { + if (size.Width < minContentSize.Width) + size.Width = minContentSize.Width; + + if (size.Height < minContentSize.Height) + size.Height = minContentSize.Height; + + r = ContentBoundsEx; + r.Size = size; + ContentBoundsEx = r; + } + } + else if (ContentBoundsEx.Width > ContentBounds.Width && + ContentBoundsEx.Height > ContentBounds.Height) + { + r.Width += (VScrollBar.Width + 1); + r.Height += (HScrollBar.Height + 1); + + ContentBoundsEx = r; + } + } + + #region FillMatrix + + private void FillMatrix() + { + Size size = Size.Empty; + + _MatrixList = new List(); + + foreach (ChartContainer cc in ChartContainers) + { + if (cc.Visible == true) + { + if (cc.MatrixDisplayBounds.Right > 0 && cc.MatrixDisplayBounds.Bottom > 0) + { + _MatrixList.Add(cc); + + if (cc.MatrixDisplayBounds.Right > size.Width) + size.Width = cc.MatrixDisplayBounds.Right; + + if (cc.MatrixDisplayBounds.Bottom > size.Height) + size.Height = cc.MatrixDisplayBounds.Bottom; + } + } + } + + if (AutoSizeChartMatrix == true) + { + ChartMatrix.Size = size; + } + else + { + if (size.Width > ChartMatrix.Size.Width || size.Height > ChartMatrix.Size.Height) + throw new Exception("ChartMatrix not large enough for assigned containers."); + } + + ChartMatrix.Clear(); + + _MatrixList.Sort(new MatrixComparer()); + + foreach (ChartContainer cc in _MatrixList) + { + Rectangle r = cc.MatrixDisplayBounds; + + for (int i = r.X; i < r.Right; i++) + { + for (int j = r.Y; j < r.Bottom; j++) + ChartMatrix[i, j] = cc; + } + } + } + + #endregion + + #region AutoFillMatrix + + private void AutoFillMatrix(ChartLayoutInfo layoutInfo) + { + _MatrixList = new List(); + + int count = VisibleContainerCount(); + + if (count > 0) + { + Size size = ChartMatrix.Size; + + ContainerLayout clayout = ContainerLayout; + + if (AutoSizeChartMatrix == true) + size = GetAutoMatrixSize(layoutInfo, count, ref clayout); + + ChartMatrix.Size = size; + + int n = -1; + + if (clayout == ContainerLayout.Horizontal) + { + for (int i = 0; i < size.Height; i++) + { + for (int j = 0; j < size.Width; j++) + { + ChartContainer container = GetNextVisibleContainer(ref n); + + if (container == null) + { + i = size.Height; + break; + } + + ChartMatrix[j, i] = container; + container.MatrixDisplayBounds = new Rectangle(j, i, 1, 1); + + _MatrixList.Add(container); + } + } + } + else + { + for (int i = 0; i < size.Width; i++) + { + for (int j = 0; j < size.Height; j++) + { + ChartContainer container = GetNextVisibleContainer(ref n); + + if (container == null) + { + i = size.Width; + break; + } + + ChartMatrix[i, j] = container; + container.MatrixDisplayBounds = new Rectangle(i, j, 1, 1); + + _MatrixList.Add(container); + } + } + } + } + } + + #region VisibleContainerCount + + private int VisibleContainerCount() + { + int count = 0; + + foreach (ChartContainer cc in ChartContainers) + { + if (cc.Visible == true) + count++; + } + + return (count); + } + + #endregion + + #region GetAutoMatrixSize + + private Size GetAutoMatrixSize( + ChartLayoutInfo layoutInfo, int count, ref ContainerLayout clayout) + { + if (count > 0) + { + if (ContainerLayout == ContainerLayout.Horizontal) + return (new Size(count, 1)); + + if (ContainerLayout == ContainerLayout.Vertical) + return (new Size(1, count)); + + double w = Math.Ceiling(Math.Sqrt((double)count)); + double h = (w * w == count) ? w : Math.Ceiling(count / w); + + if (w != h) + { + if ((layoutInfo.LayoutBounds.Width > layoutInfo.LayoutBounds.Height && w < h) || + (layoutInfo.LayoutBounds.Width < layoutInfo.LayoutBounds.Height && w > h)) + { + clayout = ContainerLayout.Vertical; + + return (new Size((int)h, (int)w)); + } + } + + clayout = ContainerLayout.Horizontal; + + return (new Size((int)w, (int)h)); + } + + return (Size.Empty); + } + + #endregion + + #region GetNextVisibleContainer + + private ChartContainer GetNextVisibleContainer(ref int n) + { + n++; + + while (n < ChartContainers.Count) + { + if (ChartContainers[n].Visible == true) + return (ChartContainers[n]); + + n++; + } + + return (null); + } + + #endregion + + #endregion + + #region MeasureMatrix + + private Size MeasureMatrix(ChartLayoutInfo layoutInfo, ChartPanelVisualStyle style) + { + int hLen = GetMatrixLayout(layoutInfo, ContainerLayout.Horizontal); + int vLen = GetMatrixLayout(layoutInfo, ContainerLayout.Vertical); + + Rectangle layoutBounds = layoutInfo.LayoutBounds; + Point ptLayout = layoutBounds.Location; + + for (int i = 0; i < ChartMatrix.Width; i++) + { + int width = ChartMatrix.ColumnProperties[i].Length; + + Point ptBounds = ptLayout; + + for (int j = 0; j < ChartMatrix.Height; j++) + { + int height = ChartMatrix.RowProperties[j].Length; + + ChartMatrix.BoundsArray[i, j] = new Rectangle(ptBounds, new Size(width, height)); + + ptBounds.Y += height; + } + + ptLayout.X += width; + } + + int dx = style.DividerLineX.LineWidth / 2; + int dy = style.DividerLineY.LineWidth / 2; + + foreach (ChartContainer cc in _MatrixList) + { + Rectangle r = GetMatrixBounds(cc, dx, dy); + + cc.BoundsRelative = r; + + layoutInfo.LayoutBounds = cc.BoundsRelative; + + cc.Measure(layoutInfo); + } + + AlignMatrix(layoutInfo); + + return (new Size(hLen, vLen)); + } + + #region GetMatrixBounds + + private Rectangle GetMatrixBounds(ChartContainer cc, int dx, int dy) + { + Rectangle r = Rectangle.Empty; + + Rectangle ccb = cc.MatrixDisplayBounds; + + for (int i = ccb.X; i < ccb.Right; i++) + { + for (int j = ccb.Y; j < ccb.Bottom; j++) + { + if (r.IsEmpty == true) + r = ChartMatrix.BoundsArray[i, j]; + else + r = Rectangle.Union(r, ChartMatrix.BoundsArray[i, j]); + } + } + + if (ccb.X != 0) + { + r.X += dy; + r.Width -= dy; + } + + if (ccb.Right != ChartMatrix.Width) + r.Width -= dy; + + if (ccb.Y != 0) + { + r.Y += dx; + r.Height -= dx; + } + + if (ccb.Bottom != ChartMatrix.Height) + r.Height -= dx; + + return (r); + } + + #endregion + + #region AlignMatrix + + private void AlignMatrix(ChartLayoutInfo layoutInfo) + { + for (int i = 0; i < ChartMatrix.Width; i++) + { + Vector v = GetMatrixColumnVector(i); + + UpdateMatrixColumnBounds(v, i); + } + + for (int i = 0; i < ChartMatrix.Height; i++) + { + Vector v = GetMatrixRowVector(i); + + UpdateMatrixRowBounds(v, i); + } + + foreach (ChartContainer cc in _MatrixList) + { + if (cc.MatrixColumnAligned == true || cc.MatrixRowAligned == true) + { + cc.MatrixColumnAligned = false; + cc.MatrixRowAligned = false; + + layoutInfo.LayoutBounds = cc.BoundsRelative; + + cc.Measure(layoutInfo); + } + } + } + + #region GetMatrixColumnVector + + private Vector GetMatrixColumnVector(int index) + { + Vector v = new Vector(); + + foreach (ChartContainer cc in _MatrixList) + { + Rectangle cb = cc.ContentBounds; + + if (cc.MatrixDisplayBounds.X == index) + { + if (cc.MatrixAlignStartColumn == true) + { + if (v.IsEmpty == true) + { + v.Start = cb.X; + v.End = cb.Right; + } + else + { + if (cb.X > v.Start) + { + int n = cb.X - v.Start; + v.Start += n; + v.End -= n; + } + } + } + } + + if (cc.MatrixDisplayBounds.Right - 1 == index) + { + if (cc.MatrixAlignEndColumn == true) + { + if (v.IsEmpty == true) + { + v.End = cb.Right; + } + else + { + if (cb.Right < v.End) + { + int n = v.End - cb.Right; + v.End -= n; + } + } + } + } + } + + return (v); + } + + #endregion + + #region UpdateMatrixColumnBounds + + private void UpdateMatrixColumnBounds(Vector v, int index) + { + foreach (ChartContainer cc in _MatrixList) + { + Rectangle cb = cc.ContentBounds; + Rectangle t = cc.BoundsRelative; + + if (cc.MatrixDisplayBounds.X == index) + { + if (cc.MatrixAlignStartColumn == true) + { + if (cb.X != v.Start) + { + t.X += (v.Start - cb.X); + t.Width -= (v.Start - cb.X); + + cc.MatrixColumnAligned = true; + } + } + } + + if (cc.MatrixDisplayBounds.Right - 1 == index) + { + if (cc.MatrixAlignEndColumn == true) + { + if (cb.Right != v.End) + { + t.Width -= (cb.Right - v.End); + + cc.MatrixColumnAligned = true; + } + } + } + + cc.BoundsRelative = t; + } + } + + #endregion + + #region GetMatrixRowVector + + private Vector GetMatrixRowVector(int index) + { + Vector v = new Vector(); + + foreach (ChartContainer cc in _MatrixList) + { + Rectangle cb = cc.ContentBounds; + + if (cc.MatrixDisplayBounds.Y == index) + { + if (cc.MatrixAlignStartRow == true) + { + if (v.IsEmpty == true) + { + v.Start = cb.Y; + v.End = cb.Bottom; + } + else + { + if (cb.Y > v.Start) + { + int n = (cb.Y - v.Start); + + v.Start += n; + v.End -= n; + } + } + } + } + + if (cc.MatrixDisplayBounds.Bottom - 1 == index) + { + if (cc.MatrixAlignEndRow == true) + { + if (v.IsEmpty == true) + { + v.Start = cb.Y; + v.End = cb.Bottom; + } + else + { + if (cb.Bottom < v.End) + v.End = cb.Bottom; + } + } + } + } + + return (v); + } + + #endregion + + #region UpdateMatrixRowBounds + + private void UpdateMatrixRowBounds(Vector v, int index) + { + foreach (ChartContainer cc in _MatrixList) + { + if (cc.MatrixDisplayBounds.Y == index) + { + Rectangle cb = cc.ContentBounds; + Rectangle t = cc.BoundsRelative; + + if (cc.MatrixAlignStartRow == true) + { + if (cb.Y != v.Start) + { + t.Y += (v.Start - cb.Y); + t.Height -= (v.Start - cb.Y); + + cc.MatrixRowAligned = true; + } + } + + if (cc.MatrixAlignEndRow == true) + { + if (cb.Bottom != v.End) + { + t.Height -= (cb.Bottom - v.End); + + cc.MatrixRowAligned = true; + } + } + + cc.BoundsRelative = t; + } + } + } + + #endregion + + #endregion + + #region RowComparer + + private class MatrixComparer : IComparer + { + public int Compare(ChartContainer x, ChartContainer y) + { + return (x.MatrixDisplayOrder - y.MatrixDisplayOrder); + } + } + + #endregion + + #region GetMatrixLayout + + private int GetMatrixLayout( + ChartLayoutInfo layoutInfo, ContainerLayout containerLayout) + { + int fillBase; + int noFillBase; + + CalculateMatrixFillData(layoutInfo, containerLayout, out fillBase, out noFillBase); + + int length = CalcMatrixContentSize(layoutInfo, containerLayout, fillBase, noFillBase); + + return (length); + } + + #region CalculateMatrixFillData + + private void CalculateMatrixFillData(ChartLayoutInfo layoutInfo, + ContainerLayout containerLayout, out int fillBase, out int noFillBase) + { + fillBase = 0; + noFillBase = 0; + + if (containerLayout == ContainerLayout.Horizontal) + { + for (int i = 0; i < ChartMatrix.Width; i++) + { + MatrixRowColProperties props = ChartMatrix.ColumnProperties[i]; + + if (props.AutoSizeMode == AutoSizeMode.NotSet) + { + if (ChartMatrix[i] != null && AutoSizeMode != AutoSizeMode.None) + fillBase += ChartMatrix[i].FillWeight; + else + noFillBase += props.Length; + } + else + { + if (props.AutoSizeMode != AutoSizeMode.None) + fillBase += props.FillWeight; + else + noFillBase += props.Length; + } + } + } + else + { + for (int i = 0; i < ChartMatrix.Height; i++) + { + MatrixRowColProperties props = ChartMatrix.RowProperties[i]; + + if (props.AutoSizeMode == AutoSizeMode.NotSet) + { + if (ChartMatrix[i] != null && AutoSizeMode != AutoSizeMode.None) + fillBase += ChartMatrix[i].FillWeight; + else + noFillBase += props.Length; + } + else + { + if (props.AutoSizeMode != AutoSizeMode.None) + fillBase += props.FillWeight; + else + noFillBase += props.Length; + } + } + } + } + + #endregion + + #region CalcMatrixContentSize + + private int CalcMatrixContentSize(ChartLayoutInfo layoutInfo, + ContainerLayout containerLayout, int fillBase, int noFillBase) + { + int length; + + if (containerLayout == ContainerLayout.Horizontal) + length = CalcHorizontalMatrixContentSize(layoutInfo, fillBase, noFillBase); + else + length = CalctVerticalMatrixContentSize(layoutInfo, fillBase, noFillBase); + + return (length); + } + + #region CalcHorizontalMatrixContentSize + + private int CalcHorizontalMatrixContentSize( + ChartLayoutInfo layoutInfo, int fillBase, int noFillBase) + { + int lenNeeded = 0; + int n = layoutInfo.LayoutBounds.Width - noFillBase; + + for (int i = 0; i < ChartMatrix.Width; i++) + { + MatrixRowColProperties props = ChartMatrix.ColumnProperties[i]; + + int length = 0; + AutoSizeMode autoSizeMode = props.AutoSizeMode; + + if (autoSizeMode == AutoSizeMode.NotSet) + autoSizeMode = AutoSizeMode; + + if (fillBase > 0) + { + int fillWeight = (ChartMatrix[i] != null && props.AutoSizeMode == AutoSizeMode.NotSet) + ? ChartMatrix[i].FillWeight : props.FillWeight; + + if (fillWeight != 0) + { + if (i == ChartMatrix.Width - 1) + length = layoutInfo.LayoutBounds.Width - lenNeeded; + else + length = (int)(n * (float)fillWeight / fillBase); + } + } + + int minLength = (props.MinimumLength > 0) + ? props.MinimumLength : ChartMatrix.DefaultCellSize.Width; + + length = Math.Max(length, minLength); + + props.Length = length; + + lenNeeded += length; + } + + return (lenNeeded); + } + + #endregion + + #region CalctVerticalMatrixContentSize + + private int CalctVerticalMatrixContentSize( + ChartLayoutInfo layoutInfo, int fillBase, int noFillBase) + { + int lengthNeeded = 0; + int n = layoutInfo.LayoutBounds.Height - noFillBase; + + for (int i = 0; i < ChartMatrix.Height; i++) + { + MatrixRowColProperties props = ChartMatrix.RowProperties[i]; + + int length = 0; + AutoSizeMode autoSizeMode = props.AutoSizeMode; + + if (autoSizeMode == AutoSizeMode.NotSet) + autoSizeMode = AutoSizeMode; + + if (fillBase > 0 && autoSizeMode != AutoSizeMode.None) + { + if (props.FillWeight != 0) + { + if (i == ChartMatrix.Height - 1) + length = layoutInfo.LayoutBounds.Height - lengthNeeded; + else + length = (int)(n * (float)props.FillWeight / fillBase); + } + } + + int minLength = (props.MinimumLength > 0) + ? props.MinimumLength : ChartMatrix.DefaultCellSize.Height; + + length = Math.Max(length, minLength); + + props.Length = length; + + lengthNeeded += length; + } + + return (lengthNeeded); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + base.ArrangeOverride(layoutInfo); + + layoutInfo.ScrollOffset.X += HScrollOffset; + layoutInfo.ScrollOffset.Y += VScrollOffset; + + Rectangle scContentBounds = GetScrollBounds(ContentBounds); + + _ChartMatrix.ScrollOffset = layoutInfo.ScrollOffset; + + foreach (ChartContainer cc in _MatrixList) + { + if (cc.Visible == true) + { + cc.Arrange(layoutInfo); + + cc.Displayed = cc.Bounds.IntersectsWith(scContentBounds); + } + } + + layoutInfo.ScrollOffset.X -= HScrollOffset; + layoutInfo.ScrollOffset.Y -= VScrollOffset; + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + ChartPanelVisualStyle pstyle = EffectivePanelStyle; + ContainerVisualStyle cstyle = GetEffectiveContainerStyle(); + + Rectangle scFrameBounds = GetScrollBounds(FrameBounds); + Rectangle scContentBounds = GetScrollBounds(ContentBounds); + Rectangle scDisplayBounds = GetDisplayBounds(scContentBounds); + + RenderPanelBackground(g, scFrameBounds, cstyle); + + cstyle.RenderBorder(g, scFrameBounds); + + Rectangle imageBounds = GetImageBounds(FrameBounds, cstyle); + + if (cstyle.ImageOverlay != ImageOverlay.Top) + cstyle.RenderBackgroundFigure(g, imageBounds); + + Region clip = g.Clip; + g.SetClip(scContentBounds, CombineMode.Intersect); + + if (ChartMatrix.Size.Width > 0 && ChartMatrix.Size.Height > 0) + RenderMatrix(renderInfo, pstyle); + + if (_MatrixList == null || _MatrixList.Count <= 0) + RenderEmptyText(g, cstyle, scDisplayBounds); + + if (cstyle.ImageOverlay == ImageOverlay.Top) + cstyle.RenderBackgroundFigure(g, imageBounds); + + RenderScrollbars(renderInfo); + + g.Clip = clip; + + if (cstyle.DropShadow.Enabled == Tbool.True) + cstyle.DropShadow.RenderDropShadow(g, scFrameBounds, true, true); + + base.RenderOverride(renderInfo); + } + + #region RenderPanelBackground + + private void RenderPanelBackground( + Graphics g, Rectangle bounds, ContainerVisualStyle cstyle) + { + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderPanelBackgroundEvent(g, this, bounds) == false) + { + cstyle.RenderBackground(g, bounds); + + chartControl.DoPostRenderPanelBackgroundEvent(g, this, bounds); + } + } + + #endregion + + #region GetImageBounds + + private Rectangle GetImageBounds(Rectangle bounds, ContainerVisualStyle style) + { + bounds = GetAdjustedBounds(bounds, style.BorderThickness); + + Rectangle scBounds = GetScrollBounds(bounds); + + if (HScrollBar.Visible == true) + scBounds.Height -= HScrollBar.Height; + + if (VScrollBar.Visible == true) + scBounds.Width -= VScrollBar.Width; + + return (scBounds); + } + + #endregion + + #region RenderMatrix + + private void RenderMatrix(ChartRenderInfo renderInfo, ChartPanelVisualStyle style) + { + Graphics g = renderInfo.Graphics; + + // Render divider lines + + switch (ChartMatrix.DividerLines) + { + case DividerLines.Horizontal: + RenderDividerLinesX(g, style.DividerLineX); + break; + + case DividerLines.Vertical: + RenderDividerLinesY(g, style.DividerLineY); + break; + + case DividerLines.BothXy: + RenderDividerLinesX(g, style.DividerLineX); + RenderDividerLinesY(g, style.DividerLineY); + break; + + case DividerLines.BothYx: + RenderDividerLinesY(g, style.DividerLineY); + RenderDividerLinesX(g, style.DividerLineX); + break; + } + + // Render each matrix item + + if (_MatrixList != null && _MatrixList.Count > 0) + { + foreach (ChartContainer cc in _MatrixList) + cc.Render(renderInfo); + } + } + + #region RenderDividerLinesX + + private void RenderDividerLinesX(Graphics g, DividerLineVisualStyle style) + { + if (style.LinePattern != LinePattern.None && style.LineWidth != 0) + { + LinePattern pattern = (style.LinePattern == LinePattern.NotSet) ? LinePattern.Solid : style.LinePattern; + int thickness = (style.LineWidth > 0) ? style.LineWidth : 1; + + int n = ChartMatrix.Width - 1; + int xoffset = _ChartMatrix.ScrollOffset.X; + int yoffset = _ChartMatrix.ScrollOffset.Y; + + for (int i = 1; i < ChartMatrix.Height; i++) + { + Point pt1 = ChartMatrix.BoundsArray[0, i].Location; + Point pt2 = ChartMatrix.BoundsArray[n, i].Location; + + pt1.X -= xoffset; + pt1.Y -= yoffset; + + pt2.X -= xoffset; + pt2.Y -= yoffset; + + pt2.X += ChartMatrix.BoundsArray[n, i].Width; + + using (Pen pen = new Pen(style.LineColor, Dpi.Width(style.LineWidth))) + { + pen.DashStyle = (DashStyle)pattern; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #region RenderDividerLinesY + + private void RenderDividerLinesY(Graphics g, DividerLineVisualStyle style) + { + if (style.LinePattern != LinePattern.None && style.LineWidth != 0) + { + LinePattern pattern = (style.LinePattern == LinePattern.NotSet) ? LinePattern.Solid : style.LinePattern; + int thickness = (style.LineWidth > 0) ? style.LineWidth : 1; + + int n = ChartMatrix.Height - 1; + int xoffset = _ChartMatrix.ScrollOffset.X; + int yoffset = _ChartMatrix.ScrollOffset.Y; + + for (int i = 1; i < ChartMatrix.Width; i++) + { + Point pt1 = ChartMatrix.BoundsArray[i, 0].Location; + Point pt2 = ChartMatrix.BoundsArray[i, n].Location; + + pt1.X -= xoffset; + pt1.Y -= yoffset; + + pt2.X -= xoffset; + pt2.Y -= yoffset; + + pt2.Y += ChartMatrix.BoundsArray[i, n].Height; + + using (Pen pen = new Pen(style.LineColor, Dpi.Height(thickness))) + { + pen.DashStyle = (DashStyle)pattern; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #endregion + + #endregion + + #region Mouse handling + + #region OnMouseMove + + protected override bool OnMouseMove(MouseEventArgs e) + { + if (base.OnMouseMove(e) == true) + return (true); + + return (false); + } + + #endregion + + #endregion + + #region OnResize + + protected override bool OnResize(EventArgs e) + { + InvalidateLayout(); + + foreach (ChartContainer cc in ChartContainers) + cc.InternalOnResize(e); + + return (base.OnResize(e)); + } + + #endregion + + #region GetElementAt + + /// + /// Gets the visua element at the given Point. + /// + /// + /// + public override ChartVisualElement GetElementAt(Point pt) + { + ChartVisualElement item = base.GetElementAt(pt); + + if (item == null) + { + if (ContentBounds.Contains(pt)) + { + if (ChartMatrix.IsEmpty == false) + { + item = ChartMatrix.GetElementAt(pt); + + if (item != null && item.Visible == true) + { + if (item.Bounds.Contains(pt)) + { + ChartVisualElement subItem = item.GetElementAt(pt); + + if (subItem != null) + return (subItem); + + return (item); + } + + return (null); + } + } + } + } + + return (item); + } + + #endregion + + #region GetMatrixCoordAt + + /// + /// Gets the matric coordinate (row/column) at the given Point. + /// + /// + /// + /// + /// true if valid coordinate is returned + public bool GetMatrixCoordAt(Point pt, ref int column, ref int row) + { + if (ContentBounds.Contains(pt)) + return (ChartMatrix.GetMatrixCoordAt(pt, ref column, ref row)); + + return (false); + } + + #endregion + + #region GetMatrixCoordOf + + /// + /// Gets the matric coordinate (row/column) of the given container. + /// + /// + /// + /// + /// true if valid coordinate returned. + public bool GetMatrixCoordOf(ChartContainer item, ref int row, ref int column) + { + return (ChartMatrix.GetMatrixCoordOf(item, ref row, ref column)); + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + ChartPanelVisualStyle pstyle = style as ChartPanelVisualStyle; + + if (pstyle != null) + { + ApplyParentStyles(pstyle, Parent as ChartContainer); + + pstyle.DividerLineX.ApplyStyle(DefaultVisualStyles.DividerLineVisualStyle); + pstyle.DividerLineY.ApplyStyle(DefaultVisualStyles.DividerLineVisualStyle); + + pstyle.ApplyStyle(DefaultVisualStyles.ChartPanelVisualStyle); + pstyle.ApplyStyle(ChartPanelVisualStyle); + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles(ChartPanelVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + ChartPanel panel = item as ChartPanel; + + if (panel != null) + { + pstyle.DividerLineX.ApplyStyle(panel.DefaultVisualStyles.DividerLineVisualStyle); + pstyle.DividerLineY.ApplyStyle(panel.DefaultVisualStyles.DividerLineVisualStyle); + + pstyle.ApplyStyle(panel.DefaultVisualStyles.ChartPanelVisualStyle); + } + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartPanelVisualStyle); + + pstyle.DividerLineX.ApplyStyle(ChartControl.DefaultVisualStyles.DividerLineVisualStyle); + pstyle.DividerLineY.ApplyStyle(ChartControl.DefaultVisualStyles.DividerLineVisualStyle); + + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartPanelVisualStyle); + } + } + + #endregion + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + _EffectivePanelStyle.InvalidateStyle(); + } + + #endregion + + #endregion + + #region ILegendData + + #region GetLegendData + + public override List GetLegendData() + { + LegendData = new List(); + + if (LegendSource != LegendSource.None) + { + ChartContainerCollection containers = ChartContainers; + + foreach (ChartContainer cc in containers) + { + if ((cc is ChartPanel) && ((LegendSource & LegendSource.NestedPanels) != 0) || + (cc is BaseChart) && ((LegendSource & LegendSource.NestedCharts) != 0)) + { + List data = cc.GetLegendData(); + + if (data != null && data.Count > 0) + AddLegendItems(data); + } + } + } + + return (_LegendData); + } + + #region AddLegendItems + + private void AddLegendItems(List items) + { + foreach (ChartLegendItem item in items) + { + ChartLegendItem likeItem = null; + + if (Legend.CombineLikeItems == true) + likeItem = FindLikeItems(item); + + if (likeItem == null) + { + likeItem = new ChartLegendItem(); + + likeItem.Parent = Legend; + + likeItem.Name = item.Name; + likeItem.ItemText = item.ItemText; + + _LegendData.Add(likeItem); + } + + likeItem.ChartItems.AddRange(item.ChartItems); + } + } + + #region FindLikeItems + + private ChartLegendItem FindLikeItems(ChartLegendItem item) + { + string itemName = item.Name ?? item.ItemText; + + if (String.IsNullOrEmpty(itemName) == false) + { + foreach (ChartLegendItem likeItem in _LegendData) + { + string likeName = likeItem.Name ?? likeItem.ItemText; + + if (String.IsNullOrEmpty(likeName) == false) + { + if (likeName.Equals(itemName) == true) + return (likeItem); + } + } + } + + return (null); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetContainerByName + + /// + /// Gets the ChartContainer object from the given name. + /// + /// + /// + public ChartContainer GetContainerByName(string name) + { + return (GetContainerByName(name, false)); + } + + /// + /// Gets the ChartContainer object from the given name, with + /// optional searching of nested panels/charts. + /// + /// + /// + /// + public ChartContainer GetContainerByName(string name, bool searchNested) + { + if (String.IsNullOrEmpty(name) == true) + return (null); + + if (_ChartContainers != null) + { + foreach (ChartContainer container in _ChartContainers) + { + if (name.Equals(container.Name) == true) + return (container); + + else if (searchNested == true) + { + ChartPanel panel = container as ChartPanel; + + if (panel != null) + { + ChartContainer item = panel.GetContainerByName(name, true); + + if (item != null) + return (item); + } + } + } + } + + return (null); + } + + #endregion + + #region GetChartByName + + /// + /// Gets the BaseChart from the given name. + /// + /// + /// + public BaseChart GetChartByName(string name) + { + return (GetChartByName(name, false)); + } + + /// + /// Gets the BaseChart from the given name, optionally searching + /// nested panels and charts. + /// + /// + /// + /// + public BaseChart GetChartByName(string name, bool searchNested) + { + if (String.IsNullOrEmpty(name) == true) + return (null); + + if (_ChartContainers != null) + { + foreach (ChartContainer container in _ChartContainers) + { + if (container is BaseChart) + { + if (name.Equals(container.Name) == true) + return ((BaseChart)container); + } + else if (searchNested == true) + { + ChartPanel panel = container as ChartPanel; + + if (panel != null) + { + BaseChart item = panel.GetChartByName(name, true); + + if (item != null) + return (item); + } + } + } + } + + return (null); + } + + #endregion + + #region GetPanelByName + + /// + /// Gets the ChartPanel from the given name. + /// + /// + /// + public ChartPanel GetPanelByName(string name) + { + return (GetPanelByName(name, false)); + } + + /// + /// Gets the ChartPanel from the given name, optionally + /// searching through nested panels. + /// + /// + /// + /// + public ChartPanel GetPanelByName(string name, bool searchNested) + { + if (String.IsNullOrEmpty(name) == true) + return (null); + + if (_ChartContainers != null) + { + foreach (ChartContainer container in _ChartContainers) + { + ChartPanel panel = container as ChartPanel; + + if (panel != null) + { + if (name.Equals(panel.Name) == true) + return (panel); + + if (searchNested == true) + { + ChartPanel item = panel.GetPanelByName(name, true); + + if (item != null) + return (item); + } + } + } + } + + return (null); + } + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartPanel copy = new ChartPanel(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartPanel c = copy as ChartPanel; + + if (c != null) + { + base.CopyTo(c); + + c.AutoFillChartMatrix = AutoFillChartMatrix; + c.AutoGenSeriesCollection = AutoGenSeriesCollection; + c.AutoSizeChartMatrix = AutoSizeChartMatrix; + + foreach (ChartContainer cc in ChartContainers) + c.ChartContainers.Add((ChartContainer)cc.Copy()); + + c.ChartMatrix = ChartMatrix.Copy(); + + c.ChartPanelVisualStyle = + (_ChartPanelVisualStyle != null) ? ChartPanelVisualStyle.Copy() : null; + + c.ContainerLayout = ContainerLayout; + + c.DefaultVisualStyles = + (_DefaultVisualStyles != null) ? DefaultVisualStyles.Copy() : null; + + c.LegendSource = LegendSource; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartPanel"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AutoFillChartMatrix", AutoFillChartMatrix, true); + sec.AddValue("AutoGenSeriesCollection", AutoGenSeriesCollection, false); + sec.AddValue("AutoSizeChartMatrix", AutoSizeChartMatrix, true); + + if (ChartContainers.Count > 0) + { + sec.AddStartElement("ChartContainers count=\"" + ChartContainers.Count + "\""); + + foreach (ChartContainer cc in ChartContainers) + sec.AddElement(cc.GetSerialData("")); + + sec.AddEndElement("ChartContainers"); + } + + if (_ChartMatrix != null && _ChartMatrix.IsEmpty == false) + { + if (AutoFillChartMatrix == false) + sec.AddElement(_ChartMatrix.GetSerialData()); + } + + if (_ChartPanelVisualStyle != null && _ChartPanelVisualStyle.IsEmpty == false) + sec.AddElement(_ChartPanelVisualStyle.GetSerialData("ChartPanelVisualStyle")); + + sec.AddValue("ContainerLayout", ContainerLayout, ContainerLayout.Auto); + + if (_DefaultVisualStyles != null && _DefaultVisualStyles.IsEmpty == false) + sec.AddElement(_DefaultVisualStyles.GetSerialData()); + + sec.AddValue("LegendSource", + LegendSource, (LegendSource.NestedCharts | LegendSource.NestedPanels)); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AutoFillChartMatrix": + AutoFillChartMatrix = bool.Parse(se.StringValue); + break; + + case "AutoGenSeriesCollection": + AutoGenSeriesCollection = bool.Parse(se.StringValue); + break; + + case "AutoSizeChartMatrix": + AutoSizeChartMatrix = bool.Parse(se.StringValue); + break; + + case "ContainerLayout": + ContainerLayout = (ContainerLayout)se.GetValueEnum(typeof(ContainerLayout)); + break; + + case "LegendSource": + LegendSource = (LegendSource)se.GetValueEnum(typeof(LegendSource)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartPanel": + case "ChartContainers": + sec.PutSerialData(this); + break; + + case "ChartXy": + string name = sec.GetItemValue("Name"); + + ChartXy chartXy = new ChartXy(name); + + sec.PutSerialData(chartXy); + + ChartContainers.Add(chartXy); + break; + + case "ChartMatrix": + sec.PutSerialData(ChartMatrix); + break; + + case "ChartPanelVisualStyle": + sec.PutSerialData(ChartPanelVisualStyle); + break; + + case "DefaultVisualStyles": + sec.PutSerialData(DefaultVisualStyles); + break; + + case "PieChart": + string pname = sec.GetItemValue("Name"); + + PieChart pieChart = new PieChart(pname); + + sec.PutSerialData(pieChart); + + ChartContainers.Add(pieChart); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + AutoFillChartMatrix = (1U << 0), + AutoGenSeriesCollection = (1U << 1), + AutoSizeChartMatrix = (1U << 2), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region Structs + + private struct Vector + { + public int Start; + public int End; + + public bool IsEmpty + { + get { return (Start == End); } + } + } + + #endregion + + #region IDisposable + + public override void Dispose() + { + ChartContainers = null; + ChartMatrix = null; + ChartPanelVisualStyle = null; + DefaultVisualStyles = null; + + base.Dispose(); + } + + #endregion + } + + #region enums + + #region ContainerLayout + + public enum ContainerLayout + { + Auto, + Horizontal, + Vertical, + HorizontalThenVertical, + VerticalThenHorizontal, + } + + #endregion + + #region DividerLines + + /// + /// Specifies which divider lines are displayed + /// + public enum DividerLines + { + /// + /// Not set + /// + NotSet, + + /// + /// No lines are displayed + /// + None, + + /// + /// Only horizontal divider lines are displayed + /// + Horizontal, + + /// + /// Only vertical divider lines are displayed + /// + Vertical, + + /// + /// Both horizontal and vertical divider lines are displayed, + /// horizontal first, then vertical. + /// + BothXy, + + /// + /// Both horizontal and vertical divider lines are displayed + /// vertical first, then horizontal. + /// + BothYx, + } + + #endregion + + #region LegendSource + + [Flags] + public enum LegendSource + { + None = 0, + + NestedCharts = (1 << 0), + NestedPanels = (1 << 1), + } + + #endregion + + #endregion + + #region BlankExpandableObjectConverter + + /// + /// BlankExpandableObjectConverter + /// + public class BlankExpandableObjectConverter : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + return (" "); + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartRenderInfo.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartRenderInfo.cs new file mode 100644 index 00000000..a4098a3c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartRenderInfo.cs @@ -0,0 +1,24 @@ +using DevComponents.DotNetBar.Charts.Style; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Provides the rendering information for chart render pass. + /// + public class ChartRenderInfo + { + #region Public properties + + public readonly Graphics Graphics; + public readonly Rectangle ClipRectangle; + + #endregion + + public ChartRenderInfo(Graphics graphics, Rectangle clipRectangle) + { + Graphics = graphics; + ClipRectangle = clipRectangle; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartSeries.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartSeries.cs new file mode 100644 index 00000000..b828b583 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartSeries.cs @@ -0,0 +1,10637 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of ChartSeries. + /// + [Editor("DevComponents.Charts.Design.ChartSeriesCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartSeriesCollection : CustomNamedCollection + { + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("Series")); + } + + #endregion + } + + public class ChartSeries : ChartVisualElement, ILegendItem + { + #region Constants + + private const int StockHigh = 0; + private const int StockLow = 1; + private const int StockClose = 2; + private const int StockOpen = 3; + private const int StockMedian = 4; + + #endregion + + #region Private variables + + private States _States; + + private SeriesType _SeriesType = SeriesType.Point; + private SeriesPointCollection _SeriesPoints; + + private PointData _PointData; + private PointData _EmptyPointData; + private PointData _StepPointData; + + private object _DataSource; + private string _DataMember; + private DataBinder _DataBinder; + + private string _DataPropertyNameSeries; + private string _DataPropertyNameX; + private CustomCollection _DataPropertyNamesY; + + private int _SeriesId; + private object _SeriesKey; + + private ChartAxis _AxisX; + private ChartAxis _AxisY; + + private int _BarOffset; + private int _BarWidth; + private double _BarWidthRatio; + + private Tbool _BarShadingEnabled = Tbool.NotSet; + private BarFillRange _BarFillRange = BarFillRange.NotSet; + private BarLabelPosition _BarLabelPosition = BarLabelPosition.NotSet; + + private Color[] _BarShadingColors; + + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + + private ChartSeriesVisualStyle _ChartSeriesVisualStyle; + private EffectiveStyle _EffectiveChartSeriesStyle; + + private DataLabelVisualStyle _DataLabelVisualStyle; + private EffectiveStyle _EffectiveDataLabelStyle; + + private Tbool _CrosshairEnabled = Tbool.NotSet; + private Tbool _CrosshairHighlightPoints = Tbool.NotSet; + private Tbool _CrosshairShowLabels = Tbool.NotSet; + + private ScaleType _ScaleTypeX = ScaleType.NotSet; + private ScaleType _ScaleTypeY = ScaleType.NotSet; + private ScaleType _ActualScaleTypeX = ScaleType.NotSet; + private ScaleType _ActualScaleTypeY = ScaleType.NotSet; + + private string _LegendText; + private ChartLegendItem _LegendItem; + + private object _MinValueX; + private object _MinValueY; + + private object _MaxValueX; + private object _MaxValueY; + + private object _AreaBaseValue; + + private bool _SeriesRangeChanged = true; + private SortedSeriesPoints _SortedSeriesPoints; + private object[] _EmptyValues; + + private List _QualitativeXValues; + private List _QualitativeYValues; + + private PointMarker _PointMarker; + private Image _PointMarkerImage; + private Image _PointMarkerEmptyImage; + private Image _PointMarkerHighlightImage; + private Point _PointOffset; + + private int _GroupId; + private object _PlotData; + private double _DotPlotIndexValue = 1.0d; + + private ChartIndicatorCollection _ChartIndicators; + private Point[] _ConvexHullPoints; + + private double _BubbleScaleFactor = 1.0d; + private double _BubbleMaxPercentage = .25d; + private int _BubbleMinSize = 4; + private BubbleSizeMode _BubbleSizeMode = BubbleSizeMode.NotSet; + + private BubbleIntensityMode _BubbleIntensityMode = BubbleIntensityMode.NotSet; + private ChartLineDisplayMode _ChartLineDisplayMode = ChartLineDisplayMode.NotSet; + private ChartLineAreaDisplayMode _ChartLineAreaDisplayMode = ChartLineAreaDisplayMode.NotSet; + private ConvexHullDisplayMode _ConvexHullDisplayMode = ConvexHullDisplayMode.NotSet; + private PointLabelDisplayMode _PointLabelDisplayMode = PointLabelDisplayMode.NotSet; + + private StepLines _StepLines = StepLines.NotSet; + private StepLineMode _StepLineMode = StepLineMode.NotSet; + private StepLineMode _LastStepLineMode = StepLineMode.NotSet; + + private Color _DefaultPaletteColor = Color.Empty; + + private DataLabelCollection _DataLabels; + private int _PointLabelSkip; + private int _PointLabelMinDistance; + + private HiLoBarType _HiLoBarType = HiLoBarType.Box; + private Rectangle _RenderBounds; + + #endregion + + #region Constructors + + public ChartSeries() + : this(null, SeriesType.Point) + { + } + + public ChartSeries(string name) + : this(name, SeriesType.Point) + { + } + + public ChartSeries(SeriesType seriesType) + : this(null, seriesType) + { + } + + public ChartSeries(string name, SeriesType seriesType) + { + Name = name; + SeriesType = seriesType; + + InitDefaultStates(); + + _EffectiveChartSeriesStyle = new EffectiveStyle(this); + _EffectiveDataLabelStyle = new EffectiveStyle(this); + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.ShowInLegend, true); + SetState(States.ShowInParentLegend, true); + SetState(States.ShowCheckBoxInLegend, true); + SetState(States.ShowMarkerInLegend, true); + SetState(States.CheckedInLegend, true); + SetState(States.DisplayLinePointsOnTop, true); + SetState(States.StackQualitativePoints, true); + SetState(States.ShowOriginValueLabels, true); + } + + #endregion + + #region Public properties + + #region ActualScaleTypeX + + /// + /// Gets the Actual X axis Scale Type (may be + /// different than XScaleType when XScaleType is 'Auto'). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ScaleType ActualScaleTypeX + { + get + { + if (IsRotated == false) + return (_ActualScaleTypeX); + + return (_ActualScaleTypeY); + } + + internal set { _ActualScaleTypeX = value; } + } + + #endregion + + #region ActualScaleTypeY + + /// + /// Gets the Actual Y axis Scale Type (may be + /// different than YScaleType when YScaleType is 'Auto'). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ScaleType ActualScaleTypeY + { + get + { + if (IsRotated == true) + return (_ActualScaleTypeX); + + return (_ActualScaleTypeY); + } + + internal set { _ActualScaleTypeY = value; } + } + + #endregion + + #region AreaBaseValue + + /// + /// Gets or sets the base, reference value for displaying Line/Spline/Step Areas. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the base, reference value for displaying Line/Spline/Step Areas.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter," + + "DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object AreaBaseValue + { + get { return (_AreaBaseValue); } + + set + { + if (value != _AreaBaseValue) + { + _AreaBaseValue = value; + + OnPropertyChangedEx("AreaBaseValue", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region AxisX + + /// + /// Gets a reference to the X-Axis associated with the series. + /// + [Category("Axis"), DefaultValue(null)] + [Description("Indicates the reference to the X-Axis associated with the series.")] + [TypeConverter(typeof(AxisTypeConverter))] + [Editor("DevComponents.Charts.Design.AxisListTypeEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartAxis AxisX + { + get { return (_AxisX); } + + set + { + if (value != _AxisX) + { + ChartXy chartXy = Parent as ChartXy; + + if (value != null) + { + if (value.IsPrimaryAxis == false) + { + if (chartXy != null) + { + if (chartXy.AncillaryAxesX.Contains(value) == false) + { + throw new Exception("Cannot set the series XAxis. The axis is not primary " + + "or a member of the chart's AncillaryAxesX collection."); + } + } + } + } + + if (_AxisX != null) + { + _AxisX.SeriesRangeChanged = true; + _AxisX.PropertyChanged -= AxisX_PropertyChanged; + } + else + { + if (chartXy != null) + chartXy.AxisX.SeriesRangeChanged = true; + } + + _AxisX = value; + + if (_AxisX != null) + { + _AxisX.SeriesRangeChanged = true; + _AxisX.PropertyChanged += AxisX_PropertyChanged; + } + else + { + if (chartXy != null) + chartXy.AxisX.SeriesRangeChanged = true; + } + + OnPropertyChangedEx("AxisX", VisualChangeType.Layout); + } + } + } + + void AxisX_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateLayout(); + } + + #endregion + + #region AxisY + + /// + /// Gets a reference to the Y-Axis associated with the series. + /// + [Category("Axis"), DefaultValue(null)] + [Description("Indicates the reference to the Y-Axis associated with the series.")] + [Editor("DevComponents.Charts.Design.AxisListTypeEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartAxis AxisY + { + get { return (_AxisY); } + + set + { + if (value != _AxisY) + { + ChartXy chartXy = Parent as ChartXy; + + if (value != null) + { + if (value.IsPrimaryAxis == false) + { + if (chartXy != null) + { + if (chartXy.AncillaryAxesY.Contains(value) == false) + { + throw new Exception("Cannot set the series YAxis. The axis is not primary " + + "or a member of the chart's AncillaryAxesY collection."); + } + } + } + } + + if (_AxisY != null) + { + _AxisY.SeriesRangeChanged = true; + _AxisY.PropertyChanged -= AxisY_PropertyChanged; + } + else + { + if (chartXy != null) + chartXy.AxisY.SeriesRangeChanged = true; + } + + _AxisY = value; + + if (_AxisY != null) + { + _AxisY.SeriesRangeChanged = true; + _AxisY.PropertyChanged += AxisY_PropertyChanged; + } + else + { + if (chartXy != null) + chartXy.AxisY.SeriesRangeChanged = true; + } + + OnPropertyChangedEx("AxisY", VisualChangeType.Layout); + } + } + } + + void AxisY_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateLayout(); + } + + #endregion + + #region BarFillRange + + /// + /// Gets or sets how series bars are filled (either according to + /// each individual bar range, or the entire series range). + /// + [DefaultValue(BarFillRange.NotSet), Category("Bar Display")] + [Description("Indicates how series bars are filled (either according to each individual bar range, or the entire series range).")] + public BarFillRange BarFillRange + { + get { return (_BarFillRange); } + + set + { + if (value != _BarFillRange) + { + _BarFillRange = value; + + OnPropertyChangedEx("BarFillRange", VisualChangeType.Render); + } + } + } + + #endregion + + #region BarLabelPosition + + /// + /// Gets or sets the position of bar series labels (default is Center). + /// + [DefaultValue(BarLabelPosition.NotSet), Category("Bar Display")] + [Description("Indicates the position of bar series labels (default is Center).")] + public BarLabelPosition BarLabelPosition + { + get { return (_BarLabelPosition); } + + set + { + if (value != _BarLabelPosition) + { + _BarLabelPosition = value; + + OnPropertyChangedEx("BarLabelPosition", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BarShadingEnabled + + /// + /// Gets or sets whether Bar shading is enabled for Horizontal and Vertical Bar series. + /// + [DefaultValue(Tbool.NotSet), Category("Bar Display")] + [Description("Indicates whether Bar shading is enabled for Horizontal and Vertical Bar series.")] + public Tbool BarShadingEnabled + { + get { return (_BarShadingEnabled); } + + set + { + if (value != _BarShadingEnabled) + { + _BarShadingEnabled = value; + + OnPropertyChangedEx("BarShadingEnabled", VisualChangeType.Render); + } + } + } + + #endregion + + #region BarWidthRatio + + /// + /// Gets or sets the ratio of bar width to bar spacing within + /// the same series (defaults to 2 - bar is twice as wide as spacing). + /// + [DefaultValue(0d), Category("Bar Display")] + [Description("Indicates the ratio of bar width to bar spacing within the same series (defaults to 2 - bar is twice as wide as spacing).")] + public double BarWidthRatio + { + get { return (_BarWidthRatio); } + + set + { + if (value != _BarWidthRatio) + { + if (value < 0) + throw new ArgumentException("Value must be > 0"); + + _BarWidthRatio = value; + + OnPropertyChangedEx("BarWidthRatio", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BubbleIntensityMode + + /// + /// Gets or sets the mode used to determine bubble intensities. + /// + [DefaultValue(BubbleIntensityMode.NotSet), Category("Display")] + [Description("Indicates the mode used to determine bubble intensities.")] + public BubbleIntensityMode BubbleIntensityMode + { + get { return (_BubbleIntensityMode); } + + set + { + if (value != _BubbleIntensityMode) + { + _BubbleIntensityMode = value; + + OnPropertyChangedEx("BubbleIntensityMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region BubbleMaxPercentage + + /// + /// Gets or sets the max percentage of the display + /// area used to calculate series bubble sizes (default is .25). + /// + [DefaultValue(0.25d), Category("Display")] + [Description("Indicates the max percentage of the display area used to calculate series bubble sizes (default is .25).")] + public double BubbleMaxPercentage + { + get { return (_BubbleMaxPercentage); } + + set + { + if (value != _BubbleMaxPercentage) + { + if (value <= 0 || value > 1) + throw new ArgumentException("Value must be between 0 and 1"); + + _BubbleMaxPercentage = value; + + OnPropertyChangedEx("BubbleMaxPercentage", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BubbleMinSize + + /// + /// Gets or sets the minimum series bubble size (in pixels) Default is 4. + /// + [DefaultValue(4), Category("Display")] + [Description("Indicates the minimum series bubble size (in pixels). Default is 4.")] + public int BubbleMinSize + { + get { return (_BubbleMinSize); } + + set + { + if (value != _BubbleMinSize) + { + if (value < 0) + throw new ArgumentException("Value must be > 0"); + + _BubbleMinSize = value; + + OnPropertyChangedEx("BubbleMinSize", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BubbleScaleFactor + + /// + /// Gets or sets the Scale Factor used to calculate series bubble sizes. + /// + [DefaultValue(1.0d), Category("Display")] + [Description("Indicates the Scale Factor used to calculate series bubble sizes.")] + public double BubbleScaleFactor + { + get { return (_BubbleScaleFactor); } + + set + { + if (value != _BubbleScaleFactor) + { + _BubbleScaleFactor = value; + + OnPropertyChangedEx("BubbleScaleFactor", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BubbleSizeMode + + /// + /// Gets or sets the mode used to calculate series bubble sizes. + /// + [DefaultValue(BubbleSizeMode.NotSet), Category("Display")] + [Description("Indicates the mode used to calculate series bubble sizes.")] + public BubbleSizeMode BubbleSizeMode + { + get { return (_BubbleSizeMode); } + + set + { + if (value != _BubbleSizeMode) + { + _BubbleSizeMode = value; + + OnPropertyChangedEx("BubbleSizeMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ChartIndicators + + /// + /// Gets a reference to the Chart Indicators collection. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Chart Indicators collection.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartIndicatorCollection ChartIndicators + { + get + { + if (_ChartIndicators == null) + { + _ChartIndicators = new ChartIndicatorCollection(); + + _ChartIndicators.CollectionChanged += ChartIndicators_CollectionChanged; + } + + return (_ChartIndicators); + } + + internal set + { + if (_ChartIndicators != null) + _ChartIndicators.CollectionChanged -= ChartIndicators_CollectionChanged; + + _ChartIndicators = value; + + if (_ChartIndicators != null) + _ChartIndicators.CollectionChanged += ChartIndicators_CollectionChanged; + } + } + + #region ChartIndicators_CollectionChanged + + void ChartIndicators_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + bool updateLayout = false; + + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (ChartIndicator ci in e.NewItems) + { + if (ci.ShowInLegend == true || ci.ShowInParentLegend == true) + updateLayout = true; + + ci.Parent = this; + } + break; + + case NotifyCollectionChangedAction.Replace: + foreach (ChartIndicator ci in e.OldItems) + { + if (ci.ShowInLegend == true || ci.ShowInParentLegend == true) + updateLayout = true; + + ci.Parent = null; + } + + foreach (ChartIndicator ci in e.NewItems) + { + if (ci.ShowInLegend == true || ci.ShowInParentLegend == true) + updateLayout = true; + + ci.Parent = this; + } + break; + + case NotifyCollectionChangedAction.Remove: + foreach (ChartIndicator ci in e.OldItems) + { + if (ci.ShowInLegend == true || ci.ShowInParentLegend == true) + updateLayout = true; + + ci.Parent = null; + } + break; + } + + if (updateLayout == true) + InvalidateLayout(); + else + InvalidateRender(); + } + + #endregion + + #endregion + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the visual styles for the Legend item. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Legend item.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleVisualChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (_ChartLegendItemVisualStyles != value) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ChartLineAreaDisplayMode + + /// + /// Gets or sets the Line 'Area' display mode. + /// + [DefaultValue(ChartLineAreaDisplayMode.NotSet), Category("Display")] + [Description("Indicates the Line ChartType display mode.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartLineAreaDisplayMode ChartLineAreaDisplayMode + { + get { return (_ChartLineAreaDisplayMode); } + + set + { + if (value != _ChartLineAreaDisplayMode) + { + _ChartLineAreaDisplayMode = value; + + OnPropertyChangedEx("ChartLineAreaDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ChartLineDisplayMode + + /// + /// Gets or sets the Line ChartType display mode. + /// + [DefaultValue(ChartLineDisplayMode.NotSet), Category("Display")] + [Description("Indicates the Line ChartType display mode.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartLineDisplayMode ChartLineDisplayMode + { + get { return (_ChartLineDisplayMode); } + + set + { + if (value != _ChartLineDisplayMode) + { + _ChartLineDisplayMode = value; + + _SortedSeriesPoints = null; + + OnPropertyChangedEx("ChartLineDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ChartSeriesVisualStyle + + /// + /// Gets or sets the visual style for the series. + /// + [Category("Style")] + [Description("Indicates the visual style for the series.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSeriesVisualStyle ChartSeriesVisualStyle + { + get + { + if (_ChartSeriesVisualStyle == null) + { + _ChartSeriesVisualStyle = new ChartSeriesVisualStyle(); + + StyleVisualChangeHandler(null, _ChartSeriesVisualStyle); + } + + return (_ChartSeriesVisualStyle); + } + + set + { + if (_ChartSeriesVisualStyle != value) + { + ChartSeriesVisualStyle oldValue = _ChartSeriesVisualStyle; + + _ChartSeriesVisualStyle = value; + + OnStyleChanged("ChartSeriesVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ConvexHullDisplayMode + + /// + /// Gets or sets the ConvexHull display mode. + /// + [DefaultValue(ConvexHullDisplayMode.NotSet), Category("Display")] + [Description("Indicates the ConvexHull display mode.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ConvexHullDisplayMode ConvexHullDisplayMode + { + get { return (_ConvexHullDisplayMode); } + + set + { + if (value != _ConvexHullDisplayMode) + { + _ConvexHullDisplayMode = value; + + OnPropertyChangedEx("ConvexHullDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region CrosshairEnabled + + /// + /// Gets or sets whether Crosshair support is enabled for the series. + /// + [DefaultValue(Tbool.NotSet), Category("Crosshair")] + [Description("Indicates whether Crosshair support is enabled for the series.")] + public Tbool CrosshairEnabled + { + get { return (_CrosshairEnabled); } + + set + { + if (value != _CrosshairEnabled) + { + _CrosshairEnabled = value; + + OnPropertyChanged("CrosshairEnabled"); + } + } + } + + #endregion + + #region CrosshairHighlightPoints + + /// + /// Gets or sets whether Crosshair Point highlighting is enabled for the series. + /// + [DefaultValue(Tbool.NotSet), Category("Crosshair")] + [Description("Indicates whether Crosshair Point highlighting is enabled for the series.")] + public Tbool CrosshairHighlightPoints + { + get { return (_CrosshairHighlightPoints); } + + set + { + if (value != _CrosshairHighlightPoints) + { + _CrosshairHighlightPoints = value; + + OnPropertyChanged("CrosshairHighlightPoints"); + } + } + } + + #endregion + + #region CrosshairShowLabels + + /// + /// Gets or sets whether Crosshair labels are shown for the series. + /// + [DefaultValue(Tbool.NotSet), Category("Crosshair")] + [Description("Indicates whether Crosshair labels are shown for the series.")] + public Tbool CrosshairShowLabels + { + get { return (_CrosshairShowLabels); } + + set + { + if (value != _CrosshairShowLabels) + { + _CrosshairShowLabels = value; + + OnPropertyChanged("CrosshairShowLabels"); + } + } + } + + #endregion + + #region DataLabels + + /// + /// Gets or sets the list of instance Data Labels. + /// + [DefaultValue(null), Category("DataLabel")] + [Description("Indicates the list of instance Data Labels.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DataLabelCollection DataLabels + { + get + { + if (_DataLabels == null) + { + _DataLabels = new DataLabelCollection(); + + _DataLabels.PropertyChanged += DataLabels_PropertyChanged; + _DataLabels.CollectionChanged += DataLabels_CollectionChanged; + } + + return (_DataLabels); + } + + internal set + { + if (_DataLabels != null) + { + _DataLabels.PropertyChanged -= DataLabels_PropertyChanged; + _DataLabels.CollectionChanged -= DataLabels_CollectionChanged; + } + + _DataLabels = value; + + if (_DataLabels != null) + { + _DataLabels.PropertyChanged += DataLabels_PropertyChanged; + _DataLabels.CollectionChanged += DataLabels_CollectionChanged; + } + } + } + + #region DataLabels_PropertyChanged + + void DataLabels_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateRender(); + } + + #endregion + + #region DataLabels_CollectionChanged + + private void DataLabels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (DataLabel dl in e.NewItems) + { + dl.Parent = this; + dl.PropertyChanged += DataLabel_PropertyChanged; + } + break; + + case NotifyCollectionChangedAction.Replace: + foreach (DataLabel dl in e.OldItems) + { + dl.Parent = null; + dl.PropertyChanged -= DataLabel_PropertyChanged; + } + + foreach (DataLabel dl in e.NewItems) + { + dl.Parent = this; + dl.PropertyChanged += DataLabel_PropertyChanged; + } + break; + + case NotifyCollectionChangedAction.Remove: + case NotifyCollectionChangedAction.Reset: + if (e.OldItems != null) + { + foreach (DataLabel dl in e.OldItems) + dl.PropertyChanged -= DataLabel_PropertyChanged; + } + break; + } + + InvalidateLayout(); + } + + private void DataLabel_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateLayout(); + } + + #endregion + + #endregion + + #region DataLabelVisualStyle + + /// + /// Gets or sets the visual style for the data labels. + /// + [Category("Style")] + [Description("Indicates the visual style for the data labels.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DataLabelVisualStyle DataLabelVisualStyle + { + get + { + if (_DataLabelVisualStyle == null) + { + _DataLabelVisualStyle = new DataLabelVisualStyle(); + + StyleVisualChangeHandler(null, _DataLabelVisualStyle); + } + + return (_DataLabelVisualStyle); + } + + set + { + if (_DataLabelVisualStyle != value) + { + DataLabelVisualStyle oldValue = _DataLabelVisualStyle; + + _DataLabelVisualStyle = value; + + OnStyleChanged("DataLabelVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region DataPropertyNameSeries + + /// + /// Gets or sets the name of the data field to which the Series Name is bound. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the data field to which the Series Name is bound.")] + public string DataPropertyNameSeries + { + get { return (_DataPropertyNameSeries); } + + set + { + if (value != _DataPropertyNameSeries) + { + _DataPropertyNameSeries = value; + + if (NeedToUpdateBindings == false) + { + NeedToUpdateBindings = true; + + InvalidateLayout(); + } + + OnPropertyChangedEx("DataPropertyNameSeries", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DataPropertyNameX + + /// + /// Gets or sets the name of the data field to which the X-Axis data is bound. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the data field to which the X-Axis data is bound.")] + public string DataPropertyNameX + { + get { return (_DataPropertyNameX); } + + set + { + if (value != _DataPropertyNameX) + { + _DataPropertyNameX = value; + + if (NeedToUpdateBindings == false) + { + NeedToUpdateBindings = true; + + InvalidateLayout(); + } + + OnPropertyChangedEx("DataPropertyNameX", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DataPropertyNamesY + + /// + /// Gets or sets the names of the data fields to which the Y-Axis data is bound. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the names of the data fields to which the Y-Axis data is bound.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CustomCollection DataPropertyNamesY + { + get + { + if (_DataPropertyNamesY == null) + { + _DataPropertyNamesY = new CustomCollection(); + + _DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged; + } + + return (_DataPropertyNamesY); + } + + set + { + if (value != _DataPropertyNamesY) + { + if (_DataPropertyNamesY != null) + { + _DataPropertyNamesY.Clear(); + + _DataPropertyNamesY.CollectionChanged -= DataPropertyNamesY_CollectionChanged; + } + + _DataPropertyNamesY = value; + + if (_DataPropertyNamesY != null) + _DataPropertyNamesY.CollectionChanged += DataPropertyNamesY_CollectionChanged; + + OnPropertyChangedEx("DataPropertyNamesY", Style.VisualChangeType.Layout); + } + } + } + + void DataPropertyNamesY_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (NeedToUpdateBindings == false) + { + NeedToUpdateBindings = true; + + InvalidateLayout(); + } + } + + #endregion + + #region DataMember + + /// + /// Gets or sets the name of the list or table + /// in the data source that the Series is bound to. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the list or table in the data source that the Series is bound to.")] + public string DataMember + { + get { return (_DataMember); } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataMember = value; + + NeedToUpdateBindings = true; + + OnPropertyChangedEx("DataMember", VisualChangeType.Layout); + } + } + + #endregion + + #region DataSource + + /// + /// Gets or sets the data source that the Series is bound to. + /// + [DefaultValue(null), AttributeProvider(typeof(IListSource)), Category("Data")] + [Description("Indicates the data source that the Series is bound to.")] + public object DataSource + { + get { return (_DataSource); } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataSource = value; + + NeedToUpdateBindings = true; + + OnPropertyChangedEx("DataSource", VisualChangeType.Layout); + } + } + + #endregion + + #region DefaultPaletteColor + + /// + /// Gets the default palette color assigned to the series when it + /// is added to the chart. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the default palette color assigned to the series when it is added to the chart.")] + public Color DefaultPaletteColor + { + get { return (_DefaultPaletteColor); } + + internal set + { + if (value != _DefaultPaletteColor) + { + _DefaultPaletteColor = value; + + InvalidateStyle(); + } + } + } + + #endregion + + #region DisplayLinePointsOnTop + + /// + /// Gets or sets whether series points are displayed on top of series line. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether series points are displayed on top of series line.")] + public bool DisplayLinePointsOnTop + { + get { return (TestState(States.DisplayLinePointsOnTop)); } + + set + { + if (value != DisplayLinePointsOnTop) + { + SetState(States.DisplayLinePointsOnTop, value); + + OnPropertyChangedEx("DisplayLinePointsOnTop", VisualChangeType.Render); + } + } + } + + #endregion + + #region DotPlotIndexValue + + /// + /// Gets or sets the value used to index between DotPlot points. Default is 1. + /// + [DefaultValue(1.0d), Category("Display")] + [Description("Indicates the value used to index between DotPlot points. Default is 1.")] + public double DotPlotIndexValue + { + get { return (_DotPlotIndexValue); } + + set + { + if (value != _DotPlotIndexValue) + { + if (value < 0) + throw new ArgumentException("Value must be > 0"); + + _DotPlotIndexValue = value; + + OnPropertyChangedEx("DotPlotIndexValue", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EffectiveDataLabelStyle + + /// + /// Gets a reference to the DataLabel effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DataLabelVisualStyle EffectiveDataLabelStyle + { + get { return (_EffectiveDataLabelStyle.Style); } + } + + #endregion + + #region EffectiveSeriesStyle + + /// + /// Gets a reference to the Series's effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates a reference to the Series's Effective (cached, composite) style.")] + public ChartSeriesVisualStyle EffectiveChartSeriesStyle + { + get { return (_EffectiveChartSeriesStyle.Style); } + } + + #endregion + + #region EmptyValues + + /// + /// Gets or sets the value(s) used to determine if + /// a series point is empty or missing. + /// + [Category("Empty")] + [Description("Indicates the value(s) used to determine if a series point is empty or missing.")] + [Editor("DevComponents.Charts.Design.SeriesPointValueEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public object[] EmptyValues + { + get { return (_EmptyValues); } + + set + { + if (value != _EmptyValues) + { + _EmptyValues = value; + + OnPropertyChangedEx("EmptyValue", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableEmptyValues + + /// + /// Gets or sets whether EmptyValues are processed in the series + /// + [DefaultValue(false), Category("Empty")] + [Description("Indicates whether EmptyValues are processed in the series.")] + public bool EnableEmptyValues + { + get { return (TestState(States.EnableEmptyValues)); } + + set + { + if (value != EnableEmptyValues) + { + SetState(States.EnableEmptyValues, value); + + _PointData = null; + _EmptyPointData = null; + _StepPointData = null; + + OnPropertyChangedEx("EnableEmptyValues", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupId + + /// + /// Gets or sets the logical grouping Id used to group qualitative series. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int GroupId + { + get { return (_GroupId); } + + set + { + if (value != _GroupId) + { + _GroupId = value; + + OnPropertyChangedEx("GroupId", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region HiLoBarType + + /// + /// Gets or sets the Series HiLoBar Type. + /// + [DefaultValue(HiLoBarType.Box), Category("Appearance")] + [Description("Indicates the Series HiLoBar Type.")] + public HiLoBarType HiLoBarType + { + get { return (_HiLoBarType); } + + set + { + if (value != _HiLoBarType) + { + _HiLoBarType = value; + + OnPropertyChangedEx("HiLoBarType", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsDisplayed + + /// + /// Gets whether the series is displayed (based upon Visibility and Legend state). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDisplayed + { + get + { + ChartXy chartXy = Parent as ChartXy; + + ItemCheckAction ica = (chartXy != null) + ? chartXy.Legend.ItemCheckAction : ItemCheckAction.ShowItem; + + return ((Visible == true) && + (ica == ItemCheckAction.None || + (ShowCheckBoxInLegend == false || CheckedInLegend == true))); + } + } + + #endregion + + #region MaxValueX + + /// + /// Gets the series Maximum X value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MaxValueX + { + get + { + UpdateSeriesRange(); + + if (IsRotated == true) + return (_MaxValueY); + + return (_MaxValueX); + } + } + + #endregion + + #region MaxValueY + + /// + /// Gets the series Maximum Y value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MaxValueY + { + get + { + UpdateSeriesRange(); + + if (IsRotated == true) + return (_MaxValueX); + + return (_MaxValueY); + } + } + + #endregion + + #region MinValueX + + /// + /// Gets the series minimum X value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MinValueX + { + get + { + UpdateSeriesRange(); + + if (IsRotated == true) + return (_MinValueY); + + return (_MinValueX); + } + } + + #endregion + + #region MinValueY + + /// + /// Gets the series minimum Y value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MinValueY + { + get + { + UpdateSeriesRange(); + + if (IsRotated == true) + return (_MinValueX); + + return (_MinValueY); + } + } + + #endregion + + #region PointLabelDisplayMode + + /// + /// Gets or sets the display mode for the chart PointLabels. + /// + [DefaultValue(PointLabelDisplayMode.NotSet), Category("DataLabel")] + [Description("Indicates the display mode for the chart PointLabels.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public PointLabelDisplayMode PointLabelDisplayMode + { + get { return (_PointLabelDisplayMode); } + + set + { + if (value != _PointLabelDisplayMode) + { + _PointLabelDisplayMode = value; + + InvalidatePointLabels(); + + OnPropertyChangedEx("PointLabelDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region PointLabelMinDistance + + /// + /// Gets or sets the minimum distance between label data points. + /// + [DefaultValue(0), Category("DataLabel")] + [Description("Indicates the minimum distance between label data points.")] + public int PointLabelMinDistance + { + get { return (_PointLabelMinDistance); } + + set + { + if (value != _PointLabelMinDistance) + { + if (value < 0) + throw new Exception("Minimum Distance must be >= 0"); + + _PointLabelMinDistance = value; + + InvalidatePointLabels(); + + OnPropertyChangedEx("PointLabelMinDistance", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region PointLabelSkip + + /// + /// Gets or sets the number of inter-label points to skip. + /// + [DefaultValue(0), Category("DataLabel")] + [Description("Indicates the number of inter-label points to skip.")] + public int PointLabelSkip + { + get { return (_PointLabelSkip); } + + set + { + if (value != _PointLabelSkip) + { + if (value < 0) + throw new Exception("Skip value must be >= 0"); + + _PointLabelSkip = value; + + InvalidatePointLabels(); + + OnPropertyChangedEx("PointLabelSkip", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region ScaleTypeX + + /// + /// Gets or sets the X axis Scale Type. + /// + [DefaultValue(ScaleType.NotSet), Category("Axis")] + [Description("Indicates the X axis Scale Type.")] + public ScaleType ScaleTypeX + { + get { return (_ScaleTypeX); } + + set + { + if (value != _ScaleTypeX) + { + if (ValidScaleTypeX(value) == false) + throw new Exception("Incompatible ScaleTypeX for defined series data."); + + _ScaleTypeX = value; + + InvalidatePoints(); + + OnPropertyChangedEx("ScaleTypeX", VisualChangeType.Layout); + } + } + } + + #region ValidScaleTypeX + + private bool ValidScaleTypeX(ScaleType scaleType) + { + if (scaleType == ScaleType.NotSet || scaleType == ScaleType.Auto) + return (true); + + if (SeriesPoints.Count > 0) + { + for (int i = 0; i < SeriesPoints.Count; i++) + { + SeriesPoint sp = SeriesPoints[i]; + + if (sp.ValueX != null) + { + Type dataType = sp.ValueX.GetType(); + ScaleType autoType = SeriesPoint.GetScaleType(dataType); + + if (scaleType == autoType) + return (true); + + if (scaleType == ScaleType.Qualitative) + return (true); + + return (false); + } + } + } + + return (true); + } + + #endregion + + #endregion + + #region ScaleTypeY + + /// + /// Gets or sets the Y axis Scale Type. + /// + [DefaultValue(ScaleType.NotSet), Category("Axis")] + [Description("Indicates the Y axis Scale Type.")] + public ScaleType ScaleTypeY + { + get { return (_ScaleTypeY); } + + set + { + if (value != _ScaleTypeY) + { + if (ValidScaleTypeY(value) == false) + throw new Exception("Incompatible ScaleTypeY for defined series data."); + + _ScaleTypeY = value; + + InvalidatePoints(); + + OnPropertyChangedEx("ScaleTypeY", VisualChangeType.Layout); + } + } + } + + #region ValidScaleTypeY + + private bool ValidScaleTypeY(ScaleType scaleType) + { + if (scaleType == ScaleType.NotSet || scaleType == ScaleType.Auto) + return (true); + + if (SeriesPoints.Count > 0) + { + for (int i = 0; i < SeriesPoints.Count; i++) + { + SeriesPoint sp = SeriesPoints[i]; + + if (sp.ValueY != null && sp.ValueY.Length > 0) + { + Type dataType = sp.ValueY[0].GetType(); + ScaleType autoType = SeriesPoint.GetScaleType(dataType); + + if (scaleType == autoType) + return (true); + + if (scaleType == ScaleType.Qualitative) + return (true); + + return (false); + } + } + } + + return (true); + } + + #endregion + + #endregion + + #region SeriesPoints + + /// + /// Gets the series point data collection + /// + [Category("Data")] + [Description("Indicates the series point data collection.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SeriesPointCollection SeriesPoints + { + get + { + if (_SeriesPoints == null) + { + _SeriesPoints = new SeriesPointCollection(); + + _SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged; + } + + return (_SeriesPoints); + } + + set + { + if (value != _SeriesPoints) + { + if (_SeriesPoints != null) + _SeriesPoints.CollectionChanged -= SeriesPoints_CollectionChanged; + + _SeriesPoints = value; + + if (_SeriesPoints != null) + _SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged; + } + } + } + + #region SeriesPoints_CollectionChanged + + void SeriesPoints_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + SeriesRangeChanged = true; + + InvalidateLayout(); + } + + #endregion + + #endregion + + #region SeriesType + + /// + /// Gets or sets the Series Type. + /// + [DefaultValue(SeriesType.Point), Category("Appearance")] + [Description("Indicates the Series Type.")] + public SeriesType SeriesType + { + get { return (_SeriesType); } + + set + { + if (value != _SeriesType) + { + _SeriesType = value; + + IsRotated = ( + SeriesType == SeriesType.HorizontalDot || + SeriesType == SeriesType.HorizontalBar || + SeriesType == SeriesType.HorizontalHiLoBar); + + BaseChart chart = Parent as BaseChart; + + if (chart != null) + { + SeriesRangeChanged = true; + chart.SeriesRangeChanged = true; + } + + OnPropertyChangedEx("SeriesType", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowHiLoBarMedianLines + + /// + /// Gets or sets whether defined HiLoBar Median lines are shown. + /// + [DefaultValue(false), Category("Empty")] + [Description("Indicates whether defined HiLoBar Median lines are shown.")] + public bool ShowHiLoBarMedianLines + { + get { return (TestState(States.ShowHiLoBarMedianLines)); } + + set + { + if (value != ShowHiLoBarMedianLines) + { + SetState(States.ShowHiLoBarMedianLines, value); + + OnPropertyChangedEx("ShowHiLoBarMedianLines", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowEmptyLines + + /// + /// Gets or sets whether EmptyLines are shown in the series. + /// + [DefaultValue(false), Category("Empty")] + [Description("Indicates whether EmptyLines are shown in the series.")] + public bool ShowEmptyLines + { + get { return (TestState(States.ShowEmptyLines)); } + + set + { + if (value != ShowEmptyLines) + { + SetState(States.ShowEmptyLines, value); + + InvalidatePoints(); + + OnPropertyChangedEx("ShowEmptyLines", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowEmptyPoints + + /// + /// Gets or sets whether EmptyPoints are shown in the series. + /// + [DefaultValue(false), Category("Empty")] + [Description("Indicates whether EmptyPoints are shown in the series.")] + public bool ShowEmptyPoints + { + get { return (TestState(States.ShowEmptyPoints)); } + + set + { + if (value != ShowEmptyPoints) + { + SetState(States.ShowEmptyPoints, value); + + InvalidatePoints(); + + OnPropertyChangedEx("ShowEmptyPoints", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowOriginValueLabels + + /// + /// Gets or sets whether labels are shown for 'Origin' data values. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether labels are shown for 'Origin' data values.")] + public bool ShowOriginValueLabels + { + get { return (TestState(States.ShowOriginValueLabels)); } + + set + { + if (value != ShowOriginValueLabels) + { + SetState(States.ShowOriginValueLabels, value); + + OnPropertyChangedEx("ShowOriginValueLabels", VisualChangeType.Layout); + } + } + } + + #endregion + + #region StackQualitativePoints + + /// + /// Gets or sets whether Qualitative points are + /// stacked or spread across the associated grouped column. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Qualitative points are stacked or spread across the associated grouped column.")] + public bool StackQualitativePoints + { + get { return (TestState(States.StackQualitativePoints)); } + + set + { + if (value != StackQualitativePoints) + { + SetState(States.StackQualitativePoints, value); + + OnPropertyChangedEx("StackQualitativePoints", VisualChangeType.Layout); + } + } + } + + #endregion + + #region StepLines + + /// + /// Gets or sets which 'Step lines' are displayed. + /// + [DefaultValue(StepLines.NotSet), Category("Display")] + [Description("Indicates which 'Step lines' are displayed.")] + public StepLines StepLines + { + get { return (_StepLines); } + + set + { + if (value != _StepLines) + { + _StepLines = value; + + OnPropertyChangedEx("StepLines", VisualChangeType.Render); + } + } + } + + #endregion + + #region StepLineMode + + /// + /// Gets or sets the mode used to render "Step Lines" in + /// the defined Line series. + /// + [DefaultValue(StepLineMode.NotSet), Category("Display")] + [Description("Indicates the mode used to render 'Step Lines' in the defined Line series.")] + public StepLineMode StepLineMode + { + get { return (_StepLineMode); } + + set + { + if (value != _StepLineMode) + { + _StepLineMode = value; + + OnPropertyChangedEx("StepLineMode", VisualChangeType.Render); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region BarOffset + + internal int BarOffset + { + get { return (_BarOffset); } + set { _BarOffset = value; } + } + + #endregion + + #region BarShadingColors + + internal Color[] BarShadingColors + { + get + { + if (_BarShadingColors == null) + { + // Top, Bottom, Left, Right + + _BarShadingColors = new Color[] { + Color.FromArgb(200, Color.White), + Color.FromArgb(100, Color.Black), + Color.FromArgb(100, Color.Black), + Color.FromArgb(100, Color.Black)}; + } + + return (_BarShadingColors); + } + } + + #endregion + + #region BarWidth + + internal int BarWidth + { + get { return (_BarWidth); } + set { _BarWidth = value; } + } + + #endregion + + #region DataBinder + + internal DataBinder DataBinder + { + get + { + if (_DataBinder == null) + _DataBinder = new DataBinder(this); + + return (_DataBinder); + } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataBinder = value; + } + } + + #endregion + + #region IsQualitativeXValues + + internal bool IsQualitativeXValues + { + get + { + UpdateSeriesRange(); + + return (QualitativeXValues.Count > 0); + } + } + + #endregion + + #region IsQualitativeYValues + + internal bool IsQualitativeYValues + { + get + { + UpdateSeriesRange(); + + return (QualitativeYValues.Count > 0); + } + } + + #endregion + + #region IsBarSeries + + internal bool IsBarSeries + { + get + { + return (_SeriesType == SeriesType.HorizontalBar || + _SeriesType == SeriesType.VerticalBar || + _SeriesType == SeriesType.HorizontalHiLoBar || + _SeriesType == SeriesType.VerticalHiLoBar); + } + } + + #endregion + + #region IsRotated + + internal bool IsRotated + { + get { return (TestState(States.IsRotated)); } + set { SetState(States.IsRotated, value); } + } + + #endregion + + #region IsSorted + + internal bool IsSorted + { + get { return (TestState(States.IsSorted)); } + set { SetState(States.IsSorted, value); } + } + + #endregion + + #region NeedToUpdateBindings + + internal bool NeedToUpdateBindings + { + get { return (TestState(States.NeedToUpdateBindings)); } + set { SetState(States.NeedToUpdateBindings, value); } + } + + #endregion + + #region PlotData + + internal object PlotData + { + get { return (_PlotData); } + set { _PlotData = value; } + } + + #endregion + + #region PointMarkerEmptyImage + + internal Image PointMarkerEmptyImage + { + get { return (_PointMarkerEmptyImage); } + set { _PointMarkerEmptyImage = value; } + } + + #endregion + + #region PointMarkerImage + + internal Image PointMarkerImage + { + get { return (_PointMarkerImage); } + set { _PointMarkerImage = value; } + } + + #endregion + + #region PointMarkerHighlightImage + + internal Image PointMarkerHighlightImage + { + get { return (_PointMarkerHighlightImage); } + set { _PointMarkerHighlightImage = value; } + } + + #endregion + + #region PointOffset + + internal Point PointOffset + { + get { return (_PointOffset); } + set { _PointOffset = value; } + } + + #endregion + + #region QualitativeXValues + + internal List QualitativeXValues + { + get + { + if (_QualitativeXValues == null) + _QualitativeXValues = new List(); + + return (_QualitativeXValues); + } + + set { _QualitativeXValues = value; } + } + + #endregion + + #region QualitativeYValues + + internal List QualitativeYValues + { + get + { + if (_QualitativeYValues == null) + _QualitativeYValues = new List(); + + return (_QualitativeYValues); + } + + set { _QualitativeYValues = value; } + } + + #endregion + + #region SeriesId + + internal int SeriesId + { + get { return (_SeriesId); } + set { _SeriesId = value; } + } + + #endregion + + #region SeriesKey + + internal object SeriesKey + { + get { return (_SeriesKey); } + set { _SeriesKey = value; } + } + + #endregion + + #region SeriesRangeChanged + + internal bool SeriesRangeChanged + { + get { return (_SeriesRangeChanged); } + + set + { + if (value != _SeriesRangeChanged) + { + _SeriesRangeChanged = value; + + if (value == true) + { + BaseChart chart = Parent as BaseChart; + + if (chart != null) + chart.SeriesRangeChanged = true; + + _SortedSeriesPoints = null; + } + } + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + UpdateDataBindings(); + UpdateMarkerImage(layoutInfo.Graphics); + } + + #region UpdateDataBindings + + internal void UpdateDataBindings() + { + if (NeedToUpdateBindings == true) + { + BaseChart chart = Parent as BaseChart; + + object dataSource = DataSource ?? chart.DataSource; + string dataMember = (string.IsNullOrEmpty(DataMember) == false) ? DataMember : chart.DataMember; + + if (dataSource != null) + { + SeriesPoints.Clear(); + + DataBinder dataBinder = DataBinder; + + dataBinder.Clear(); + + dataBinder.DataConnect(dataSource, dataMember); + dataBinder.LoadSeriesData(this); + } + + NeedToUpdateBindings = false; + } + } + + #endregion + + #region UpdateMarkerImage + + private void UpdateMarkerImage(Graphics g) + { + switch (SeriesType) + { + case SeriesType.Bubble: + case SeriesType.VerticalDot: + case SeriesType.Line: + case SeriesType.Point: + case SeriesType.HorizontalDot: + if (PointMarkerImage == null) + { + ChartXy chartXy = Parent as ChartXy; + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + PointMarkerImage = chartXy.GetPointMarker(g, sstyle.MarkerVisualStyle); + } + break; + } + } + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + BoundsRelative = layoutInfo.LayoutBounds; + + if (SeriesType == SeriesType.Bubble) + UpdateBubblePointOffset(); + } + + #region UpdateBubblePointOffset + + private void UpdateBubblePointOffset() + { + BubblePlotData bdata = _PlotData as BubblePlotData; + + if (bdata != null) + { + ChartXy chartXy = Parent as ChartXy; + + Rectangle bounds = chartXy.ContentBoundsEx; + + float minSize = Dpi.Width(BubbleMinSize); + float maxSize = (float)(Math.Min(bounds.Width, bounds.Height) * BubbleMaxPercentage); + + double minTotalSize; + double maxTotalSize; + chartXy.GetChartBubbleData(out minTotalSize, out maxTotalSize); + + BubbleSizeMode smode = GetBubbleSizeMode(chartXy); + + double range = maxSize - minSize; + + double sizeRange = (smode == BubbleSizeMode.Diameter) + ? maxTotalSize - minTotalSize : AMath.ToScalar((float)(maxTotalSize - minTotalSize)); + + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + int size = GetBubbleSize(sp, smode, minSize, maxSize, range, sizeRange); + + sp.PointSize = new Size(size, size); + } + } + } + } + + #region GetBubbleSize + + private int GetBubbleSize(SeriesPoint sp, + BubbleSizeMode smode, double minSize, double maxSize, double range, double sizeRange) + { + if (sp.ValueY == null || sp.ValueY.Length < 2 || sizeRange == 0) + return (int)minSize; + + double size = Math.Abs(GetDoubleValue(sp.ValueY[1])); + + double value = (smode == BubbleSizeMode.Diameter) + ? (size * range) / sizeRange + : (AMath.ToScalar((float)size) * range) / sizeRange; + + if (BubbleScaleFactor > 0) + value *= BubbleScaleFactor; + + value = Math.Max(minSize, value); + + return ((int)Math.Min(maxSize, value)); + } + + #endregion + + #endregion + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + if (SeriesPoints.Count > 0) + { + ChartXy chartXy = Parent as ChartXy; + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + ssp.SeriesLayoutCount = chartXy.SeriesLayoutCount; + + UpdateMarkerImage(g); + + int n = Dpi.Width1; + + _RenderBounds = chartXy.ContentBounds; + _RenderBounds.Location = chartXy.GetGlobalAdjustedPoint(_RenderBounds.Location); + + if (_RenderBounds.Width > 0 && _RenderBounds.Height > 0) + { + switch (SeriesType) + { + case SeriesType.Bubble: + RenderBubblePlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.HorizontalBar: + RenderHBarPlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.HorizontalDot: + RenderHDotPlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.HorizontalHiLoBar: + RenderHStockPlot(renderInfo, chartXy, ssp, sstyle); + break; + + case SeriesType.Point: + RenderPointPlot(g, chartXy, ssp, true, sstyle); + break; + + case SeriesType.Line: + RenderLinePlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.VerticalBar: + RenderVBarPlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.VerticalDot: + RenderVDotPlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.VerticalHiLoBar: + RenderVStockPlot(renderInfo, chartXy, ssp, sstyle); + break; + } + } + } + } + + #region GetSortedSeriesPoints + + internal SortedSeriesPoints GetSortedSeriesPoints(ChartXy chartXy) + { + if (_SortedSeriesPoints == null) + { + bool sort = (IsSorted == false && NeedSortedSeries(chartXy) == true); + + _SortedSeriesPoints = new SortedSeriesPoints(this, sort); + + if (SeriesType == SeriesType.VerticalDot || SeriesType == SeriesType.HorizontalDot) + CombineDuplicates(_SortedSeriesPoints); + } + + return (_SortedSeriesPoints); + } + + #region CombineDuplicates + + private void CombineDuplicates(SortedSeriesPoints ssp) + { + SeriesPoint spLast = null; + + List cList = new List(); + List iList = new List(); + + int dcount = 0; + int spLastIndex = 0; + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (spLast != null && spLast.ValueX.Equals(sp.ValueX) == false) + { + iList.Add(spLastIndex); + cList.Add(dcount); + + dcount = 0; + + spLast = sp; + spLastIndex = (ssp.IndexArray != null ? ssp.IndexArray[i] : i); + } + + dcount += GetDotCount(sp); + + if (spLast == null) + { + spLast = sp; + spLastIndex = (ssp.IndexArray != null ? ssp.IndexArray[i] : i); + } + } + + if (dcount > 0) + { + iList.Add(spLastIndex); + cList.Add(dcount); + } + + int[] indexArray = new int[iList.Count]; + int[] countArray = new int[iList.Count]; + + for (int i = 0; i < iList.Count; i++) + { + indexArray[i] = iList[i]; + countArray[i] = cList[i]; + } + + ssp.IndexArray = indexArray; + ssp.CountArray = countArray; + } + + #endregion + + #region NeedSortedSeries + + private bool NeedSortedSeries(ChartXy chartXy) + { + if (IsSorted == true || _ActualScaleTypeX == ScaleType.Qualitative) + return (false); + + if (SeriesType != SeriesType.Line) + return (true); + + ChartLineDisplayMode mode = GetLineDisplayMode(chartXy); + + return ((mode & ChartLineDisplayMode.DisplayUnsorted) != ChartLineDisplayMode.DisplayUnsorted); + } + + #endregion + + #endregion + + #region RenderBarPlot + + #region RenderHBarPlot + + private void RenderHBarPlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + g.RenderingOrigin = chartXy.GetLocalAdjustedPoint(Point.Empty); + + BarRenderData rd = new BarRenderData(chartXy, AxisX ?? chartXy.AxisX); + + rd.FillRange = GetBarFillRange(chartXy); + rd.BarShading = GetBarShading(chartXy); + + rd.SeriesStyle = sstyle; + + int index = 0; + bool isHistogram = false; + + if (chartXy.BarShowAsHistogram == Tbool.True) + { + ChartAxis axisY = AxisY ?? chartXy.AxisY; + AxisBar axisBar = axisY.AxisBars[(int)AxisBarType.Bar]; + + if (axisBar.BarCount == 1) + { + TickmarkLayout layout = axisY.TickmarkLayout; + + for (int i = 0; i < layout.Ticks.Length; i++) + { + if (layout.Ticks[i].LabelIndex >= 0) + { + index = i; + break; + } + } + + isHistogram = true; + } + } + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + rd.Spt = sp.Point[0]; + rd.Sp = sp; + + RenderHBar(g, rd, isHistogram, i + index); + } + } + } + + #region RenderHBar + + private void RenderHBar( + Graphics g, BarRenderData rd, bool isHistogram, int index) + { + ChartXy chartXy = rd.ChartXy; + SeriesPoint sp = rd.Sp; + + sp.PointSize = new Size(5, BarWidth); + + Point ptt = chartXy.GetDataPointEx(this, sp, 0); + + int y = (int)(ptt.Y + BarOffset - BarWidth / 2); + int height = BarWidth; + + if (isHistogram == true) + y = GetHistogramSizeY(chartXy, ptt, index, out height); + + int x1 = ptt.X; + int x2 = GetHBarStart(chartXy, sp); + int xOrigin = GetHBarOrigin(chartXy, rd.Axis, sp); + + if (x1 > x2) + { + int xtemp = x1; + x1 = x2; + x2 = xtemp; + } + + if (x2 <= xOrigin) + { + RenderLeftBar(g, rd, y, height, x1, x2, xOrigin); + } + else if (x1 >= xOrigin) + { + RenderRightBar(g, rd, y, height, x1, x2, xOrigin); + } + else + { + RenderLeftBar(g, rd, y, height, x1, xOrigin, xOrigin); + RenderRightBar(g, rd, y, height, xOrigin, x2, xOrigin); + } + } + + #region GetHistogramSizeY + + private int GetHistogramSizeY( + ChartXy chartXy, Point spt, int index, out int height) + { + ChartAxis axis = AxisY ?? chartXy.AxisY; + TickmarkLayout layout = axis.TickmarkLayout; + + if (index < layout.Ticks.Length) + height = layout.Ticks[index + 1].TickPoint.Y - spt.Y; + else + height = (int)layout.MajorInterval; + + int y = spt.Y - (int)(layout.MajorInterval / 2); + + return (y); + } + + #endregion + + #region GetHBarStart + + internal int GetHBarStart(ChartXy chartXy, SeriesPoint sp) + { + ChartAxis axis = AxisX ?? chartXy.AxisX; + + object value = ((sp.ValueY.Length > 1) + ? sp.ValueY[1] : chartXy.BarOrigin ?? null); + + if (value == null) + { + if (axis.ScaleType == ScaleType.Quantitative) + value = 0; + else + value = axis.ActualMinValue; + } + + return (chartXy.GetDataPointX(axis, value)); + } + + #endregion + + #region GetHBarOrigin + + private int GetHBarOrigin( + ChartXy chartXy, ChartAxis axis, SeriesPoint sp) + { + object value = ((sp.ValueY != null && sp.ValueY.Length > 2) + ? sp.ValueY[2] : (chartXy.BarOrigin ?? null)); + + if (value == null) + { + if (axis.ScaleType == ScaleType.Quantitative) + value = 0; + else + value = axis.ActualMinValue; + } + + return (chartXy.GetDataPointX(axis, value)); + } + + #endregion + + #region RenderRightBar + + private void RenderRightBar(Graphics g, + BarRenderData rd, int y, int height, int x1, int x2, int xOrigin) + { + Rectangle r = new Rectangle(x1, y, x2 - x1, Math.Max(1, height - 1)); + + if (r.IntersectsWith(_RenderBounds)) + { + Background bk = rd.SeriesStyle.BarVisualStyle.Background; + ChartLineVisualStyle lstyle = rd.SeriesStyle.BarVisualStyle.Border; + + // r is actual area, r2 is FillRange area + + Rectangle r2 = r; + + if (rd.FillRange == BarFillRange.BySeries) + { + r2.X = xOrigin; + r2.Width = rd.ChartXy.GetDataPointX(rd.Axis, MaxValueX) - r2.X; + } + + BarSegment segment = (x1 > xOrigin) ? BarSegment.Right : BarSegment.RightPartial; + + RenderFullHBar(g, rd, r, r2, bk, lstyle, segment); + } + } + + #endregion + + #region RenderLeftBar + + private void RenderLeftBar(Graphics g, + BarRenderData rd, int y, int height, int x1, int x2, int xOrigin) + { + Rectangle r = new Rectangle(x1, y, x2 - x1, Math.Max(1, height - 1)); + + if (r.IntersectsWith(_RenderBounds)) + { + ChartSeriesVisualStyle sstyle = rd.SeriesStyle; + + Background bk = sstyle.BarVisualStyle.AlternateBackground; + + if (bk.IsEmpty) + bk = sstyle.BarVisualStyle.Background; + + ChartLineVisualStyle lstyle = sstyle.BarVisualStyle.AlternateBorder; + + if (lstyle.IsEmpty) + lstyle = sstyle.BarVisualStyle.Border; + + Rectangle r2 = r; + + if (rd.FillRange == BarFillRange.BySeries) + { + int left = rd.ChartXy.GetDataPointX(rd.Axis, MinValueX); + + r2.X = left; + r2.Width = xOrigin - left; + } + + BarSegment segment = (x2 < xOrigin) ? BarSegment.Left : BarSegment.LeftPartial; + + RenderFullHBar(g, rd, r, r2, bk, lstyle, segment); + } + } + + #endregion + + #region RenderFullHBar + + private void RenderFullHBar(Graphics g, BarRenderData rd, + Rectangle r, Rectangle r2, Background bk, ChartLineVisualStyle lstyle, BarSegment segment) + { + if (r2.Width > 0 && r2.Height > 0) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment) == false) + { + using (Brush br = bk.GetBrush(r2)) + g.FillRectangle(br, r); + + int lw = 0; + + if (lstyle.LinePattern != LinePattern.None) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + lw = (int)pen.Width; + + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + g.DrawRectangle(pen, r); + } + + g.SmoothingMode = sm; + } + + if (rd.BarShading == true) + { + Rectangle t = r; + t.Inflate(-lw/2, -lw/2); + + t.Width++; + t.Height++; + + RenderHBarShading(g, t, r2, segment); + } + + chartControl.DoPostRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment); + } + } + } + + #region RenderHBarShading + + private void RenderHBarShading( + Graphics g, Rectangle r, Rectangle r2, BarSegment segment) + { + if (r.Width > 6) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + int n = (int)(r.Height *.15); + + Color[] colors = (Color[])BarShadingColors.Clone(); + + colors[2] = Color.FromArgb(Math.Max(0,colors[2].A - 30), colors[2]); + colors[3] = Color.FromArgb(Math.Max(0, colors[3].A - 30), colors[3]); + + Rectangle r3 = r; + + r3.Inflate(1, 1); + + using (LinearGradientBrush lbr = new LinearGradientBrush(r3, Color.Empty, Color.Empty, 90f)) + { + lbr.WrapMode = WrapMode.Tile; + + ColorBlend cb = new ColorBlend(4); + + cb.Colors = new Color[] { colors[0], Color.Transparent, Color.Transparent, colors[1] }; + cb.Positions = new float[] { 0f, .25f, .75f, 1f }; + + lbr.InterpolationColors = cb; + + r3.Inflate(-1, -1); + + g.FillRectangle(lbr, r3); + } + + switch (segment) + { + case BarSegment.LeftPartial: + FillLeft(g, r, n, colors); + break; + + case BarSegment.RightPartial: + FillRight(g, r, n, colors); + break; + + default: + FillLeft(g, r, n, colors); + FillRight(g, r, n, colors); + break; + } + + g.SmoothingMode = sm; + } + } + + #region FillLeft + + private void FillLeft(Graphics g, Rectangle r, int n, Color[] colors) + { + r.Width = n - 1; + r.Inflate(1, 0); + + using (LinearGradientBrush lbr = new LinearGradientBrush(r, colors[2], Color.Transparent, 0f)) + { + lbr.WrapMode = WrapMode.TileFlipX; + + r.X++; + + g.FillRectangle(lbr, r); + } + } + + #endregion + + #region FillRight + + private void FillRight(Graphics g, Rectangle r, int n, Color[] colors) + { + r.X = r.Right - n; + r.Width = n; + r.Inflate(1, 0); + + using (LinearGradientBrush lbr = new LinearGradientBrush(r, colors[2], Color.Transparent, 180f)) + { + r.X++; + r.Width--; + + g.FillRectangle(lbr, r); + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region RenderVBarPlot + + private void RenderVBarPlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + PointData pd = GatherSeriesPoints(chartXy, ssp, 0, ssp.Count, false); + + if (pd.Points.Count > 0) + { + g.RenderingOrigin = chartXy.GetLocalAdjustedPoint(Point.Empty); + + BarRenderData rd = new BarRenderData(chartXy, AxisY ?? chartXy.AxisY); + + rd.FillRange = GetBarFillRange(chartXy); + rd.BarShading = GetBarShading(chartXy); + + rd.SeriesStyle = sstyle; + + int index = 0; + bool isHistogram = false; + + if (chartXy.BarShowAsHistogram == Tbool.True) + { + ChartAxis axisX = AxisX ?? chartXy.AxisX; + AxisBar axisBar = axisX.AxisBars[(int)AxisBarType.Bar]; + + if (axisBar.BarCount == 1) + { + TickmarkLayout layout = axisX.TickmarkLayout; + + for (int i = 0; i < layout.Ticks.Length; i++) + { + if (layout.Ticks[i].LabelIndex >= 0) + { + index = i; + break; + } + } + + isHistogram = true; + } + } + + for (int i = 0; i < pd.Points.Count; i++) + { + Point[] pts = pd.Points[i]; + SeriesPoint[] spts = pd.SeriesPoints[i]; + + for (int j = 0; j < pts.Length; j++) + { + rd.Spt = pts[j]; + rd.Sp = spts[j]; + + RenderVBar(g, rd, isHistogram, j + index); + } + } + } + } + + #region RenderVBar + + private void RenderVBar( + Graphics g, BarRenderData rd, bool isHistogram, int index) + { + ChartXy chartXy = rd.ChartXy; + SeriesPoint sp = rd.Sp; + Point spt = rd.Spt; + + sp.PointSize = new Size(BarWidth, 5); + + int x = (int)(spt.X + BarOffset - BarWidth / 2); + int width = BarWidth; + + if (isHistogram == true) + x = GetHistogramSizeX(chartXy, spt, index, out width); + + int y1 = spt.Y; + int y2 = GetVBarStart(chartXy, sp); + int yOrigin = GetVBarOrigin(chartXy, rd.Axis, sp); + + if (y1 > y2) + { + int ytemp = y1; + y1 = y2; + y2 = ytemp; + } + + if (y2 <= yOrigin) + { + RenderAscendingBar(g, rd, x, width, y1, y2, yOrigin); + } + else if (y1 >= yOrigin) + { + RenderDescendingBar(g, rd, x, width, y1, y2, yOrigin); + } + else + { + RenderAscendingBar(g, rd, x, width, y1, yOrigin, yOrigin); + RenderDescendingBar(g, rd, x, width, yOrigin, y2, yOrigin); + } + } + + #region GetHistogramSizeX + + private int GetHistogramSizeX( + ChartXy chartXy, Point spt, int index, out int width) + { + ChartAxis axis = AxisX ?? chartXy.AxisX; + TickmarkLayout layout = axis.TickmarkLayout; + + if (index < layout.Ticks.Length) + width = layout.Ticks[index + 1].TickPoint.X - spt.X; + else + width = (int)layout.MajorInterval; + + int x = spt.X - (int)(layout.MajorInterval / 2); + + return (x); + } + + #endregion + + #region GetVBarStart + + internal int GetVBarStart(ChartXy chartXy, SeriesPoint sp) + { + ChartAxis axis = AxisY ?? chartXy.AxisY; + + object value = ((sp.ValueY != null && sp.ValueY.Length > 1) + ? sp.ValueY[1] : (chartXy.BarOrigin ?? null)); + + if (value == null) + { + if (axis.ScaleType == ScaleType.Quantitative) + value = 0; + else + value = axis.ActualMinValue; + } + + return (chartXy.GetDataPointY(axis, value)); + } + + #endregion + + #region GetVBarOrigin + + private int GetVBarOrigin( + ChartXy chartXy, ChartAxis axis, SeriesPoint sp) + { + object value = ((sp.ValueY != null && sp.ValueY.Length > 2) + ? sp.ValueY[2] : (chartXy.BarOrigin ?? null)); + + if (value == null) + { + if (axis.ScaleType == ScaleType.Quantitative) + value = 0; + else + value = axis.ActualMinValue; + } + + return (chartXy.GetDataPointY(axis, value)); + } + + #endregion + + #region RenderAscendingBar + + private void RenderAscendingBar(Graphics g, + BarRenderData rd, int x, int width, int y1, int y2, int yOrigin) + { + Rectangle r = new Rectangle(x, y1, Math.Max(1, width - 1), y2 - y1); + + if (r.IntersectsWith(_RenderBounds)) + { + Background bk = rd.SeriesStyle.BarVisualStyle.Background; + ChartLineVisualStyle lstyle = rd.SeriesStyle.BarVisualStyle.Border; + + Rectangle r2 = r; + + if (rd.FillRange == BarFillRange.BySeries) + { + int top = rd.ChartXy.GetDataPointY(rd.Axis, MaxValueY); + + r2.Y = top; + r2.Height = yOrigin - top; + } + + BarSegment segment = (y2 < yOrigin) ? BarSegment.Top : BarSegment.TopPartial; + + RenderFullVBar(g, rd, r, r2, bk, lstyle, segment); + } + } + + #endregion + + #region RenderDescendingBar + + private void RenderDescendingBar(Graphics g, + BarRenderData rd, int x, int width, int y1, int y2, int yOrigin) + { + Rectangle r = new Rectangle(x, y1, Math.Max(1, width - 1), y2 - y1); + + if (r.IntersectsWith(_RenderBounds)) + { + ChartSeriesVisualStyle sstyle = rd.SeriesStyle; + + Background bk = sstyle.BarVisualStyle.AlternateBackground; + + if (bk.IsEmpty) + bk = sstyle.BarVisualStyle.Background; + + ChartLineVisualStyle lstyle = sstyle.BarVisualStyle.AlternateBorder; + + if (lstyle.IsEmpty) + lstyle = sstyle.BarVisualStyle.Border; + + Rectangle r2 = r; + + if (GetBarFillRange(rd.ChartXy) == BarFillRange.BySeries) + { + r2.Y = yOrigin; + r2.Height = rd.ChartXy.GetDataPointY(rd.Axis, MinValueY) - r2.Y; + } + + BarSegment segment = (y1 > yOrigin) ? BarSegment.Bottom : BarSegment.BottomPartial; + + RenderFullVBar(g, rd, r, r2, bk, lstyle, segment); + } + } + + #endregion + + #region RenderFullVBar + + private void RenderFullVBar(Graphics g, BarRenderData rd, + Rectangle r, Rectangle r2, Background bk, ChartLineVisualStyle lstyle, BarSegment segment) + { + if (r2.Width > 0 && r2.Height > 0) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment) == false) + { + using (Brush br = bk.GetBrush(r2)) + g.FillRectangle(br, r); + + int lw = 0; + + if (lstyle.LinePattern != LinePattern.None) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + lw = (int)pen.Width; + + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + g.DrawRectangle(pen, r); + } + + g.SmoothingMode = sm; + } + + if (rd.BarShading == true) + { + Rectangle t = r; + t.Inflate(-lw/2, -lw/2); + + t.Width++; + t.Height++; + + RenderVBarShading(g, t, r2, segment); + } + + chartControl.DoPostRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment); + } + } + } + + #region RenderVBarShading + + private void RenderVBarShading( + Graphics g, Rectangle r, Rectangle r2, BarSegment segment) + { + int n = r.Width / 10 + 1; + + if (r.Width > 6 && r.Height > n) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + Color[] colors = (Color[])BarShadingColors.Clone(); + + Rectangle r3 = r; + + using (LinearGradientBrush lbr = new LinearGradientBrush(r3, Color.Empty, Color.Empty, 0f)) + { + lbr.WrapMode = WrapMode.TileFlipX; + + ColorBlend cb = new ColorBlend(4); + + cb.Colors = new Color[] { colors[2], Color.Transparent, Color.Transparent, colors[3] }; + cb.Positions = new float[] { 0f, .15f, .85f, 1f }; + + lbr.InterpolationColors = cb; + + g.FillRectangle(lbr, r3); + } + + switch (segment) + { + case BarSegment.TopPartial: + FillTop(g, r, n, colors); + break; + + case BarSegment.BottomPartial: + FillBottom(g, r, n, colors); + break; + + default: + FillTop(g, r, n, colors); + FillBottom(g, r, n, colors); + break; + } + + g.SmoothingMode = sm; + } + } + + #region FillTop + + private void FillTop(Graphics g, Rectangle r, int n, Color[] colors) + { + using (Pen pen = new Pen(colors[0])) + { + Point pt1 = new Point(r.X + 1, r.Y); + Point pt2 = new Point(r.Right - 2, r.Y); + + for (int i = 0; i < n; i++) + { + g.DrawLine(pen, pt1, pt2); + + pt1.X++; + pt2.X--; + + pt1.Y++; + pt2.Y++; + } + } + } + + #endregion + + #region FillBottom + + private void FillBottom(Graphics g, Rectangle r, int n, Color[] colors) + { + using (Pen pen = new Pen(colors[1])) + { + Point pt1 = new Point(r.X + 1, r.Bottom - 1); + Point pt2 = new Point(r.Right - 2, r.Bottom - 1); + + for (int i = 0; i < n; i++) + { + g.DrawLine(pen, pt1, pt2); + + pt1.X++; + pt2.X--; + + pt1.Y--; + pt2.Y--; + } + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetBarFillRange + + private BarFillRange GetBarFillRange(ChartXy chartXy) + { + BarFillRange fillRange = BarFillRange; + + if (fillRange == BarFillRange.NotSet) + fillRange = chartXy.BarFillRange; + + return ((fillRange != BarFillRange.NotSet) + ? fillRange : BarFillRange.ByBar); + } + + #endregion + + #region GetBarLabelPosition + + internal BarLabelPosition GetBarLabelPosition(ChartXy chartXy) + { + BarLabelPosition labelPos = BarLabelPosition; + + if (labelPos == BarLabelPosition.NotSet) + labelPos = chartXy.BarLabelPosition; + + return ((labelPos != BarLabelPosition.NotSet) + ? labelPos : BarLabelPosition.Center); + } + + #endregion + + #region GetBarShading + + private bool GetBarShading(ChartXy chartXy) + { + Tbool barShading = BarShadingEnabled; + + if (barShading == Tbool.NotSet) + barShading = chartXy.BarShadingEnabled; + + return (barShading == Tbool.True); + } + + #endregion + + #endregion + + #region RenderBubblePlot + + private void RenderBubblePlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + BubblePlotData bdata = _PlotData as BubblePlotData; + + if (bdata != null) + { + double minIntensity = 32; + double maxIntensity = 255; + + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + PointMarkerVisualStyle hstyle = GetHighlightStyle(chartXy, sstyle); + + if (DisplayLinePointsOnTop == true) + RenderConvexHull(g, chartXy, ssp, sstyle, pstyle); + + BubbleIntensityMode imode = GetBubbleIntensityMode(chartXy); + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + int size = sp.PointSize.Width; + + Point pt = chartXy.GetDataPointNa(this, sp, 0); + Rectangle r = new Rectangle(pt.X - size / 2, pt.Y - size / 2, size, size); + + if (r.IntersectsWith(_RenderBounds)) + { + Point ppt = chartXy.GetLocalAdjustedPoint(pt); + + bool isCrossPoint = chartXy.IsCrosshairSeriesPoint(this, ppt); + int intensity = GetIntensity(sp, imode, bdata, minIntensity, maxIntensity); + + PointMarkerVisualStyle style = (hstyle != null && isCrossPoint) ? hstyle : pstyle; + + Image image = style.GetPointMarkerImage(); + + if (image == null) + image = GetPointMarker(g, style, r.Size); + + if (image != null) + { + g.DrawImage(image, r); + } + else if (style.Type == PointMarkerType.Ellipse || style.Type == PointMarkerType.NotSet) + { + using (Brush br = style.Background.GetBrush(r, intensity)) + { + g.FillEllipse(br, r); + + if (style.BorderColor.IsEmpty == false && style.BorderWidth > 0) + { + using (Pen pen = new Pen(style.BorderColor, Dpi.Width(style.BorderWidth))) + g.DrawEllipse(pen, r); + } + } + } + } + } + } + + if (DisplayLinePointsOnTop == false) + RenderConvexHull(g, chartXy, ssp, sstyle, pstyle); + + if (hstyle != null) + hstyle.Dispose(); + } + } + + #region GetIntensity + + private int GetIntensity(SeriesPoint sp, + BubbleIntensityMode imode, BubblePlotData bdata, double minIntensity, double maxIntensity) + { + if (imode != BubbleIntensityMode.None && imode != BubbleIntensityMode.NotSet) + { + if (sp.ValueY.Length > 2) + { + double intensity = -1; + + if (sp.ValueY[2] is double) + intensity = (double)sp.ValueY[2]; + + else if (sp.ValueY[2] is int) + intensity = Convert.ToDouble(sp.ValueY[2]); + + if (imode == BubbleIntensityMode.Alpha) + return ((int)intensity); + + if (intensity >= 0) + { + double range = maxIntensity - minIntensity; + double intensityRange = bdata.MaxIntensity - bdata.MinIntensity; + + if (intensityRange <= 0) + return (-1); + + return (int)(((intensity - bdata.MinIntensity) * range) / intensityRange + minIntensity); + } + } + } + + return (-1); + } + + #endregion + + #region GetBubbleSizeMode + + private BubbleSizeMode GetBubbleSizeMode(ChartXy chartXy) + { + if (BubbleSizeMode != BubbleSizeMode.NotSet) + return (BubbleSizeMode); + + if (chartXy.BubbleSizeMode != BubbleSizeMode.NotSet) + return (chartXy.BubbleSizeMode); + + return (BubbleSizeMode.Area); + } + + #endregion + + #region GetBubbleIntensityMode + + private BubbleIntensityMode GetBubbleIntensityMode(ChartXy chartXy) + { + if (BubbleIntensityMode != BubbleIntensityMode.NotSet) + return (BubbleIntensityMode); + + if (chartXy.BubbleIntensityMode != BubbleIntensityMode.NotSet) + return (chartXy.BubbleIntensityMode); + + return (BubbleIntensityMode.None); + } + + #endregion + + #region GetPointMarker + + internal Image GetPointMarker(Graphics g, PointMarkerVisualStyle style, Size size) + { + if (style.Type == PointMarkerType.NotSet || + style.Type == PointMarkerType.None || style.Type == PointMarkerType.Ellipse) + { + return (null); + } + + if (_PointMarker == null) + _PointMarker = new PointMarker(); + + return (_PointMarker.GetMarkerBitmap(g, style.Type, style.PointCount, + size, style.Rotation, style.Background, style.BorderColor, style.BorderWidth)); + } + + #endregion + + #endregion + + #region RenderDotPlot + + #region RenderHDotPlot + + private void RenderHDotPlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + Image marker = PointMarkerImage; + + if (marker != null) + { + Size maxSize = chartXy.GetMaxDotPlotMarkerSize(); + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + object pointValueX = chartXy.GetDataPointValueX(this, sp); + + Point pt = chartXy.GetPointFromValue(this, 0, pointValueX); + + Point ppt = new Point(pt.X + maxSize.Width / 2, pt.Y); + + int dcount = ssp.CountArray[i]; + + for (int j = 0; j < dcount; j++) + { + RenderPointMarker(g, chartXy, sp, ppt, maxSize, marker); + + ppt.X += maxSize.Width; + } + } + } + } + } + + #endregion + + #region RenderVDotPlot + + private void RenderVDotPlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + Image marker = PointMarkerImage; + + if (marker != null) + { + Size maxSize = chartXy.GetMaxDotPlotMarkerSize(); + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + Point pt = chartXy.GetDataPointNa(this, sp, -1); + Point ppt = new Point(pt.X, pt.Y - maxSize.Height / 2); + + int dcount = ssp.CountArray[i]; + + for (int j = 0; j < dcount; j++) + { + RenderPointMarker(g, chartXy, sp, ppt, maxSize, marker); + + ppt.Y -= maxSize.Height; + } + } + } + } + } + + #endregion + + #region GetDotCount + + private int GetDotCount(SeriesPoint sp) + { + if (sp.ValueY != null && sp.ValueY.Length > 0) + { + int count = 0; + + foreach (object o in sp.ValueY) + { + if (o is int) + count += (int)o; + + else if (o is double) + count += (int)Convert.ChangeType(o, typeof(int)); + } + + return (count); + } + + return (1); + } + + #endregion + + #endregion + + #region RenderPointPlot + + private void RenderPointPlot(Graphics g, ChartXy chartXy, + SortedSeriesPoints ssp, bool showHull, ChartSeriesVisualStyle sstyle) + { + PointData pd = GatherSeriesPoints(chartXy, ssp, 0, ssp.Count, true); + + if (pd.Points.Count > 0) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + PointMarkerVisualStyle hstyle = GetHighlightStyle(chartXy, sstyle); + + if (showHull == true) + RenderConvexHull(g, chartXy, ssp, sstyle, pstyle); + + if (hstyle == null) + { + Image marker = chartXy.GetPointMarker(g, pstyle); + + if (marker != null) + { + for (int i=0; i 3) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddPolygon(_ConvexHullPoints); + + if ((mode & ConvexHullDisplayMode.DisplayBackground) == ConvexHullDisplayMode.DisplayBackground) + { + Rectangle r = Rectangle.Round(path.GetBounds()); + + Background bg = (sstyle.ConvexHullBackground.IsEmpty) + ? pstyle.Background : sstyle.ConvexHullBackground; + + using (Brush br = bg.GetBrush(r)) + g.FillPath(br, path); + } + + if ((mode & ConvexHullDisplayMode.DisplayBorder) == ConvexHullDisplayMode.DisplayBorder) + { + Color color; + int width; + LinePattern pattern; + + if (sstyle.ConvexHullLineStyle.IsEmpty == false) + { + color = sstyle.ConvexHullLineStyle.LineColor; + width = sstyle.ConvexHullLineStyle.LineWidth; + pattern = sstyle.ConvexHullLineStyle.LinePattern; + } + else + { + color = pstyle.BorderColor; + width = pstyle.BorderWidth; + pattern = LinePattern.Solid; + } + + if (pattern != LinePattern.None) + { + using (Pen pen = new Pen(color, Dpi.Width(width))) + { + if (pattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)pattern; + + g.DrawPath(pen, path); + } + } + } + } + } + } + } + + #region GetConvexHullDisplayMode + + private ConvexHullDisplayMode GetConvexHullDisplayMode(ChartXy chartXy) + { + if (ConvexHullDisplayMode != ConvexHullDisplayMode.NotSet) + return (ConvexHullDisplayMode); + + ConvexHullDisplayMode mode = chartXy.ConvexHullDisplayMode; + + if (mode != ConvexHullDisplayMode.NotSet) + return (mode); + + return (ConvexHullDisplayMode.None); + } + + #endregion + + #region CombineListPoints + + private Point[] CombineListPoints(List plist) + { + int n = 0; + + foreach (Point[] points in plist) + n += points.Length; + + Point[] fpoints = new Point[n]; + + n = 0; + + foreach (Point[] points in plist) + { + for (int i = 0; i < points.Length; i++) + fpoints[n++] = points[i]; + } + + return (fpoints); + } + + #endregion + + #endregion + + #region RenderEmptyPoints + + private void RenderEmptyPoints(Graphics g, + ChartXy chartXy, PointData pd, ChartSeriesVisualStyle sstyle) + { + PointData epd = _EmptyPointData; + + if (epd != null && epd.Points.Count > 0) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerEmptyVisualStyle; + + Image marker = GetEmptyMarkerImage(g, chartXy, pstyle); + + if (marker != null) + { + for (int i = 0; i < epd.Points.Count; i++) + { + Point[] epts = epd.Points[i]; + SeriesPoint[] septs = epd.SeriesPoints[i]; + + Point[] pts = GetEmptyPointRange(epts[0]); + + int run = pts[0].X - pts[1].X; + int rise = pts[0].Y - pts[1].Y; + + double slope = (run != 0) ? (double)rise / run : 0; + double b = pts[0].Y - (slope * pts[0].X); + + for (int j = 0; j < epts.Length; j++) + { + Point ept = epts[j]; + SeriesPoint sept = septs[j]; + + Point ppt = new Point(ept.X, (int)(slope * ept.X + b)); + + RenderPointMarker(g, chartXy, sept, ppt, Size.Empty, marker); + } + } + } + } + } + + #region GetEmptyPointRange + + private Point[] GetEmptyPointRange(Point pt) + { + Point[] pts = new Point[2]; + + pts[0] = Point.Empty; + pts[1] = Point.Empty; + + PointData pd = _PointData; + + for (int i = 0; i < pd.Points.Count; i++) + { + Point[] lps = pd.Points[i]; + + if (pt.X <= lps[0].X) + { + pts[1] = lps[0]; + + if (i == 0) + pts[0] = pts[1]; + + return (pts); + } + + pts[0] = lps[lps.Length - 1]; + } + + pts[1] = pts[0]; + + return (pts); + } + + #endregion + + #endregion + + #endregion + + #region RenderLinePlot + + private void RenderLinePlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + PointData pd = GatherSeriesPoints(chartXy, ssp, 0, ssp.Count, false); + + if (pd.Points.Count > 0) + { + ChartLineDisplayMode lineMode = GetLineDisplayMode(chartXy); + ChartLineAreaDisplayMode areaMode = GetAreaDisplayMode(chartXy); + + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + RenderConvexHull(g, chartXy, ssp, sstyle, pstyle); + + if (DisplayLinePointsOnTop == true) + RenderLinePlotLines(g, chartXy, pd, lineMode, areaMode, sstyle); + + if ((lineMode & ChartLineDisplayMode.DisplayPoints) == ChartLineDisplayMode.DisplayPoints) + { + RenderPointPlot(g, chartXy, ssp, false, sstyle); + } + else + { + if (ShowEmptyPoints == true) + RenderEmptyPoints(g, chartXy, pd, sstyle); + + RenderPointLabelPoints(g, chartXy, sstyle); + + if (HighLightPoints(chartXy) == true) + RenderHighlightPoints(g, chartXy, pd, sstyle); + } + + if (DisplayLinePointsOnTop == false) + RenderLinePlotLines(g, chartXy, pd, lineMode, areaMode, sstyle); + } + } + + #region RenderPointLabelPoints + + private void RenderPointLabelPoints(Graphics g, + ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + List pointLabels = chartXy.PointLabels; + + if (pointLabels != null && pointLabels.Count > 0) + { + foreach (PointLabelGroup lg in pointLabels) + { + if (lg.ChartSeries == this) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + Image marker = chartXy.GetPointMarker(g, pstyle); + + if (marker != null) + { + Size size = marker.Size; + + for (int i = 0; i < lg.PointLabels.Count; i++) + { + PointLabel pl = lg.PointLabels[i]; + + if (pl.Visible == true && pl.SeriesPoint.IsEmpty == false) + { + DataLabelVisualStyle dstyle = GetPointLabelVisualStyle(pl); + + if (dstyle.DrawPointMarker != Tbool.False) + { + SeriesPoint spt = pl.SeriesPoint; + + Point ppt = pl.Point; + Point ppc = new Point(ppt.X, ppt.Y); + + RenderPointMarker(g, chartXy, spt, ppc, Size.Empty, marker); + } + } + } + } + break; + } + } + } + } + + #endregion + + #region RenderLinePlotLines + + private void RenderLinePlotLines(Graphics g, ChartXy chartXy, PointData pd, + ChartLineDisplayMode lineMode, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + if ((lineMode & ChartLineDisplayMode.DisplayStepLine) == ChartLineDisplayMode.DisplayStepLine) + { + StepLineMode slm = GetStepLineMode(chartXy); + + if (slm != StepLineMode.None) + RenderStepLines(g, chartXy, pd, slm, areaMode, sstyle); + } + + if ((lineMode & ChartLineDisplayMode.DisplayLine) == ChartLineDisplayMode.DisplayLine) + RenderLines(g, chartXy, pd, lineMode, areaMode, sstyle); + + if ((lineMode & ChartLineDisplayMode.DisplaySpline) == ChartLineDisplayMode.DisplaySpline) + RenderSplines(g, chartXy, pd, lineMode, areaMode, sstyle); + + if (ShowEmptyLines == true) + { + if ((lineMode & (ChartLineDisplayMode.DisplayLine | ChartLineDisplayMode.DisplaySpline)) != 0) + RenderEmptyLines(g, chartXy, pd.Points, areaMode, sstyle); + } + } + + #region GetStepLineMode + + private StepLineMode GetStepLineMode(ChartXy chartXy) + { + StepLineMode mode = StepLineMode; + + if (mode == StepLineMode.NotSet) + mode = chartXy.StepLineMode; + + if (mode == StepLineMode.NotSet) + mode = StepLineMode.HorizontalThenVertical; + + return (mode); + } + + #endregion + + #region RenderLines + + private void RenderLines(Graphics g, ChartXy chartXy, + PointData pd, ChartLineDisplayMode lineMode, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + ChartLineVisualStyle lstyle = sstyle.LineStyle; + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if ((lineMode & ChartLineDisplayMode.DisplayClosed) == ChartLineDisplayMode.DisplayClosed) + { + foreach (Point[] points in pd.Points) + { + if (points.Length > 1) + g.DrawLines(pen, points); + } + + Point fp = pd.Points[0][0]; + Point[] lps = pd.Points[pd.Points.Count - 1]; + Point lp = lps[lps.Length - 1]; + + if (fp.Equals(lp) == false) + g.DrawLine(pen, lp, fp); + } + else + { + foreach (Point[] points in pd.Points) + { + if (points.Length > 1) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(points); + + if ((areaMode & ChartLineAreaDisplayMode.DisplayLine) == ChartLineAreaDisplayMode.DisplayLine) + RenderAreaBackground(g, chartXy, points, path, sstyle.LineAreaBackground); + + g.DrawPath(pen, path); + } + } + } + } + } + } + } + + #endregion + + #region RenderSplines + + private void RenderSplines(Graphics g, ChartXy chartXy, PointData pd, + ChartLineDisplayMode lineMode, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + ChartLineVisualStyle lstyle = sstyle.SplineStyle; + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if ((pd.Points.Count == 1) && + (lineMode & ChartLineDisplayMode.DisplayClosed) == ChartLineDisplayMode.DisplayClosed) + { + Point[] points = pd.Points[0]; + + if (points.Length > 1) + g.DrawClosedCurve(pen, points); + } + else + { + foreach (Point[] points in pd.Points) + { + if (points.Length > 1) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddCurve(points); + + if ((areaMode & ChartLineAreaDisplayMode.DisplaySpline) == ChartLineAreaDisplayMode.DisplaySpline) + RenderAreaBackground(g, chartXy, points, path, sstyle.SplineAreaBackground); + + g.DrawPath(pen, path); + } + } + } + } + } + } + } + + #endregion + + #region RenderStepLines + + private void RenderStepLines(Graphics g, ChartXy chartXy, PointData pd, + StepLineMode slm, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + StepLines sls = GetStepLines(chartXy); + + if (sls != StepLines.None) + { + PointData sd = GetStepPointData(chartXy, pd, slm); + + if (sd != null) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + + ChartCapLineVisualStyle lstyle = sstyle.StepLineStyle; + + if (sls == StepLines.Both) + { + RenderStepLinesEx1(g, sd, lstyle); + } + else + { + int n = ((sls == StepLines.Horizontal && (slm == StepLineMode.HorizontalThenVertical || slm == StepLineMode.MidPoint)) || + (sls == StepLines.Vertical && slm == StepLineMode.VerticalThenHorizontal)) ? 0 : 1; + + RenderStepLinesEx2(g, sd, n, lstyle); + + if (sstyle.StepLineAltStyle.IsEmpty == false) + RenderStepLinesEx2(g, sd, n ^ 1, sstyle.StepLineAltStyle); + } + + g.SmoothingMode = sm; + + if ((areaMode & ChartLineAreaDisplayMode.DisplayStepLine) == ChartLineAreaDisplayMode.DisplayStepLine) + { + foreach (Point[] points in sd.Points) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(points); + + RenderAreaBackground(g, chartXy, points, path, sstyle.StepLineAreaBackground); + } + } + } + } + } + } + + #region GetStepLines + + private StepLines GetStepLines(ChartXy chartXy) + { + StepLines mode = StepLines; + + if (mode == StepLines.NotSet) + mode = chartXy.StepLines; + + if (mode == StepLines.NotSet) + mode = StepLines.Both; + + return (mode); + } + + #endregion + + #region GetStepPointData + + private PointData GetStepPointData( + ChartXy chartXy, PointData pd, Charts.StepLineMode slm) + { + if (_LastStepLineMode != slm) + _StepPointData = null; + + if (_StepPointData == null) + { + PointData sd = new PointData(); + + sd.Points = new List(); + + foreach (Point[] points in pd.Points) + { + if (points.Length > 1) + sd.Points.Add(GetStepPoints(slm, points)); + } + + _StepPointData = sd; + + _LastStepLineMode = slm; + } + + return (_StepPointData); + } + + #region GetStepPoints + + private Point[] GetStepPoints(StepLineMode slm, Point[] pts) + { + if (slm == StepLineMode.HorizontalThenVertical || slm == StepLineMode.VerticalThenHorizontal) + { + Point[] points = new Point[pts.Length * 2 - 1]; + + if (slm == StepLineMode.HorizontalThenVertical) + { + for (int i = 0; i < pts.Length; i++) + { + int n = i * 2; + + points[n] = pts[i]; + + if (i + 1 < pts.Length) + points[n + 1] = new Point(pts[i + 1].X, pts[i].Y); + } + } + else + { + for (int i = 0; i < pts.Length; i++) + { + int n = i * 2; + + points[n] = pts[i]; + + if (i + 1 < pts.Length) + points[n + 1] = new Point(pts[i].X, pts[i + 1].Y); + } + } + + return (points); + } + else + { + Point[] points = new Point[pts.Length * 2]; + + points[0] = pts[0]; + + for (int i = 0; i < pts.Length - 1; i++) + { + int n0 = i * 2 + 1; + int n1 = n0 + 1; + + points[n0] = new Point((pts[i].X + pts[i + 1].X) / 2, pts[i].Y); + points[n1] = new Point(points[n0].X, pts[i + 1].Y); + } + + points[points.Length - 1] = pts[pts.Length - 1]; + + return (points); + } + } + + #endregion + + #endregion + + #region RenderStepLinesEx1 + + private void RenderStepLinesEx1(Graphics g, PointData sd, ChartCapLineVisualStyle lstyle) + { + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.StartCap != ChartLineCap.NotSet) + pen.StartCap = (LineCap)lstyle.StartCap; + + if (lstyle.EndCap != ChartLineCap.NotSet) + pen.EndCap = (LineCap)lstyle.EndCap; + + foreach (Point[] points in sd.Points) + { + if (points.Length > 1) + g.DrawLines(pen, points); + } + } + } + } + + #endregion + + #region RenderStepLinesEx2 + + private void RenderStepLinesEx2(Graphics g, + PointData sd, int n, ChartCapLineVisualStyle lstyle) + { + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.StartCap != ChartLineCap.NotSet) + pen.StartCap = (LineCap)lstyle.StartCap; + + if (lstyle.EndCap != ChartLineCap.NotSet) + pen.EndCap = (LineCap)lstyle.EndCap; + + foreach (Point[] points in sd.Points) + { + if (points.Length > 1) + { + for (int i = n; i < points.Length - 1; i += 2) + { + Point pt1 = points[i]; + Point pt2 = points[i + 1]; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + } + } + + #endregion + + #endregion + + #region RenderEmptyLines + + private void RenderEmptyLines(Graphics g, ChartXy chartXy, + List lpoints, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + if (lpoints.Count > 1) + { + ChartLineVisualStyle lstyle = sstyle.EmptyStyle; + + if (lstyle.LinePattern != LinePattern.None) + { + Point[] points = new Point[(lpoints.Count - 1) * 2]; + Point[][] epoints = new Point[lpoints.Count - 1][]; + + for (int i = 0; i < lpoints.Count - 1; i++) + { + Point[] pts1 = lpoints[i]; + Point[] pts2 = lpoints[i + 1]; + + epoints[i] = new Point[2]; + + epoints[i][0] = pts1[pts1.Length - 1]; + epoints[i][1] = pts2[0]; + } + + for (int i = 0; i < points.Length / 2; i++ ) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(epoints[i]); + + if ((areaMode & ChartLineAreaDisplayMode.DisplayEmptyLine) == ChartLineAreaDisplayMode.DisplayEmptyLine) + RenderAreaBackground(g, chartXy, epoints[i], path, sstyle.EmptyAreaBackground); + + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + g.DrawPath(pen, path); + } + } + } + } + } + } + + #endregion + + #region RenderAreaBackground + + private void RenderAreaBackground(Graphics g, + ChartXy chartXy, Point[] points, GraphicsPath path, Background background) + { + bool backEmpty = (background == null || background.IsEmpty == true); + + if (backEmpty == true) + background = new Background(Color.FromArgb(100, DefaultPaletteColor)); + + if (background != null && background.IsEmpty == false) + { + int y = chartXy.ContentBoundsEx.Bottom; + + if (AreaBaseValue != null) + { + ChartAxis axis = _AxisY ?? chartXy.AxisY; + + y = chartXy.GetDataPointY(axis, AreaBaseValue); + } + + using (GraphicsPath path2 = new GraphicsPath()) + { + path2.AddLine(new Point(points[0].X, y), points[0]); + path2.AddPath(path, true); + path2.AddLine(points[points.Length - 1], new Point(points[points.Length - 1].X, y)); + + path2.CloseFigure(); + + Rectangle r = Rectangle.Round(path2.GetBounds()); + + using (Brush br = background.GetBrush(r)) + g.FillPath(br, path2); + } + } + + if (backEmpty == true) + background.Dispose(); + } + + #endregion + + #endregion + + #region RenderHighlightPoints + + private void RenderHighlightPoints(Graphics g, + ChartXy chartXy, PointData pd, ChartSeriesVisualStyle sstyle) + { + PointMarkerVisualStyle hstyle = GetHighlightStyle(chartXy, sstyle); + + Image marker = GetHighlightImage(g, chartXy, hstyle); + + if (marker != null) + { + Size size = marker.Size; + + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + for (int i=0; i x1) + x1 = rd.Value[StockOpen]; + + if (rd.Value[StockOpen] < x2) + x2 = rd.Value[StockOpen]; + } + + if (rd.Value[StockClose] != int.MinValue) + { + if (rd.Value[StockClose] > x1) + x1 = rd.Value[StockClose]; + + if (rd.Value[StockClose] < x2) + x2 = rd.Value[StockClose]; + } + + int y = pt.Y + BarOffset - BarWidth / 2; + + return (new Rectangle(x2, y, x1 - x2, BarWidth)); + } + + #endregion + + #region RenderHStockBox + + private void RenderHStockBox(Graphics g, HiLoRenderData rd, int y) + { + int x1 = rd.Value[StockClose]; + int x2 = rd.Value[StockOpen]; + + if (rd.Value[StockOpen] != int.MinValue && rd.Value[StockClose] != int.MinValue) + { + if (rd.Value[StockOpen] < rd.Value[StockClose]) + { + x1 = rd.Value[StockOpen]; + x2 = rd.Value[StockClose]; + } + + if (rd.Value[StockLow] > x1) + rd.Value[StockLow] = x1; + + if (rd.Value[StockHigh] < x2) + rd.Value[StockHigh] = x2; + + rd.IsAlternate = (rd.Value[StockOpen] > rd.Value[StockClose]); + + RenderHStockBoxWhisker(g, rd, + rd.Value[StockLow], x1, y, HiLoBarSegment.LowWhisker); + + RenderHStockBoxWhisker(g, rd, + x2, rd.Value[StockHigh], y, HiLoBarSegment.HighWhisker); + + RenderHStockBoxOpenClose(g, rd, x1, x2, y); + } + else + { + int x = (x1 != int.MinValue) ? x1 : x2; + + if (x != int.MinValue) + { + if (x > rd.Value[StockHigh]) + rd.Value[StockHigh] = x; + + if (x < rd.Value[StockLow]) + rd.Value[StockLow] = x; + } + + if (x < rd.Value[StockHigh] && x > rd.Value[StockLow]) + { + RenderHStockBoxWhisker(g, rd, x, rd.Value[StockHigh], y, HiLoBarSegment.HighWhisker); + RenderHStockBoxWhisker(g, rd, rd.Value[StockLow], x, y, HiLoBarSegment.LowWhisker); + + RenderHStockBoxOpenClose(g, rd, x, x, y); + } + else + { + RenderHStockBoxWhisker(g, rd, + rd.Value[StockLow], rd.Value[StockHigh], y, HiLoBarSegment.CenterLine); + + if (x != int.MinValue) + RenderHStockBoxOpenClose(g, rd, x, x, y); + } + } + } + + #region RenderHStockBoxWhisker + + private void RenderHStockBoxWhisker(Graphics g, + HiLoRenderData rd, int x1, int x2, int y, HiLoBarSegment segment) + { + if (x2 > x1) + { + Point pt1 = new Point(x1, y); + Point pt2 = new Point(x2 + 1, y); + + RenderBoxWhisker(g, rd, pt1, pt2, segment); + } + } + + #endregion + + #region RenderHStockBoxOpenClose + + private void RenderHStockBoxOpenClose( + Graphics g, HiLoRenderData rd, int x1, int x2, int y) + { + if (x2 == x1) + { + x1--; + x2++; + } + + x2++; + + Point pt1 = new Point(x1, y - BarWidth / 2); + Point pt2 = new Point(x2, pt1.Y + BarWidth); + + int lw = RenderStockBox(g, rd, pt1, pt2); + + Rectangle r = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y); + + if (r.Width > 0 && r.Height > 0) + { + if (GetBarShading(rd.ChartXy) == true) + { + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading) == false) + { + RenderHBarShading(g, r, r, BarSegment.Left); + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading); + } + } + } + } + + #endregion + + #endregion + + #region RenderHStockBoxMedian + + private void RenderHStockBoxMedian( + Graphics g, HiLoRenderData rd, int y, int x1, int x2) + { + if (rd.Value.Length > StockMedian) + { + int x3 = rd.Value[StockMedian]; + + if (x3 > x1 && x3 < x2) + { + Point pt1 = new Point(x3, y); + Point pt2 = new Point(x3, y + BarWidth - 1); + + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, HiLoBarSegment.MedianLine); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.LineWidth > 1) + pt2.Y++; + + g.DrawLine(pen, pt1, pt2); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine); + } + } + } + } + + #endregion + + #region RenderHStockHiLo + + private void RenderHStockHiLo(Graphics g, HiLoRenderData rd, int y) + { + int x1, x2, x3, x4; + NormalizeHiLoValues(rd, out x1, out x2, out x3, out x4); + + ChartLineVisualStyle ostyle, cstyle; + NormalizeHiLoStyles(rd, out ostyle, out cstyle); + + if (rd.Value[StockOpen] != int.MinValue) + { + Point pt1 = new Point(x2, y - BarWidth / 2); + Point pt2 = new Point(pt1.X, pt1.Y + BarWidth / 2); + + RenderHiLoWhisker(g, rd, pt1, pt2, ostyle, HiLoBarSegment.OpenWhisker); + } + + if (rd.Value[StockClose] != int.MinValue) + { + Point pt1 = new Point(x3, y); + Point pt2 = new Point(pt1.X, pt1.Y + BarWidth / 2 + 1); + + RenderHiLoWhisker(g, rd, pt1, pt2, cstyle, HiLoBarSegment.CloseWhisker); + } + + if (rd.IsAlternate == false) + { + int x = x2; + x2 = x3; + x3 = x; + + ChartLineVisualStyle style = ostyle; + ostyle = cstyle; + cstyle = ostyle; + } + + if ((rd.IsAlternate == false && _RenderFullDefRange == true) || + (rd.IsAlternate == true && _RenderFullAltRange == true)) + { + RenderHiLoRange(g, rd, + new Point(x1, y), new Point(x4, y), HiLoBarSegment.FullRange); + } + else + { + // Open value either not specified or is + // set to High value. + + if (x1 == x2 && x3 != x4) + x2 = x3; + + if (x2 < x1) + { + int n = (ostyle != null) ? (ostyle.LineWidth + 1) / 2 : 1; + + RenderHiLoRange(g, rd, + new Point(x1, y), new Point(x2 + n, y), HiLoBarSegment.HighWhisker); + } + + if (x3 > x4) + { + int n = 1; + + // Low segment extends to the top. + + if (x3 == x1) + n = (cstyle.LineWidth + 1) / 2; + + // We have a Center segment. + + else if (x3 != x2) + n = -cstyle.LineWidth / 2; + + RenderHiLoRange(g, rd, + new Point(x3 + n, y), new Point(x4, y), HiLoBarSegment.LowWhisker); + } + + if (x2 > x3 || (x1 == x2 && x3 == x4)) + { + ChartLineVisualStyle y2Style = (x2 == rd.Value[StockOpen]) ? ostyle : cstyle; + ChartLineVisualStyle y3Style = (x3 == rd.Value[StockOpen]) ? ostyle : cstyle; + + if (y2Style != null) + x2 += ((y2Style.LineWidth + 1) / 2 ); + + if (y3Style != null) + x3 -= (y3Style.LineWidth / 2); + + RenderHiLoRange(g, rd, + new Point(x2, y), new Point(x3, y), HiLoBarSegment.CenterLine); + } + } + } + + #endregion + + #endregion + + #endregion + + #region RenderVStockPlot + + private void RenderVStockPlot(ChartRenderInfo renderInfo, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + HiLoRenderData rd = new HiLoRenderData(chartXy, AxisY ?? chartXy.AxisY); + + rd.SeriesStyle = sstyle; + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + if (sp.ValueY.Length > 0) + { + rd.Sp = sp; + rd.Spt = sp.Point[0]; + rd.Index = i; + + rd.IsAlternate = false; + + RenderVStock(renderInfo, rd); + } + } + } + } + + #region RenderVStock + + private void RenderVStock(ChartRenderInfo renderInfo, HiLoRenderData rd) + { + Graphics g = renderInfo.Graphics; + + rd.Value = GetVStockValues(rd.ChartXy, rd.Sp); + + if (rd.Value[StockHigh] != int.MinValue) + { + Point pt = rd.ChartXy.GetDataPointEx(this, rd.Sp, 0); + + Rectangle r = GetVBoundingRect(rd, pt); + + if (r.IntersectsWith(_RenderBounds) == true) + { + int x = pt.X + BarOffset; + + rd.Sp.PointSize = new Size(BarWidth/3, 5); + + switch (HiLoBarType) + { + case HiLoBarType.Box: + case HiLoBarType.Candle: + RenderVStockBox(g, rd, x); + break; + + default: + RenderVStockHiLo(g, rd, x); + break; + } + } + } + } + + #region GetVBoundingRect + + private Rectangle GetVBoundingRect(HiLoRenderData rd, Point pt) + { + int y1 = rd.Value[StockHigh]; + int y2 = rd.Value[StockLow]; + + if (rd.Value[StockOpen] != int.MinValue) + { + if (y1 > rd.Value[StockOpen]) + y1 = rd.Value[StockOpen]; + + if (y2 < rd.Value[StockOpen]) + y2 = rd.Value[StockOpen]; + } + + if (rd.Value[StockClose] != int.MinValue) + { + if (y1 > rd.Value[StockClose]) + y1 = rd.Value[StockClose]; + + if (y2 < rd.Value[StockClose]) + y2 = rd.Value[StockClose]; + } + + int x = pt.X + BarOffset - BarWidth / 2; + + return (new Rectangle(x, y1, BarWidth, y2 - y1)); + } + + #endregion + + #region RenderVStockBox + + private void RenderVStockBox(Graphics g, HiLoRenderData rd, int x) + { + int y1 = rd.Value[StockOpen]; + int y2 = rd.Value[StockClose]; + + if (rd.Value[StockOpen] != int.MinValue && rd.Value[StockClose] != int.MinValue) + { + if (rd.Value[StockOpen] > rd.Value[StockClose]) + { + y1 = rd.Value[StockClose]; + y2 = rd.Value[StockOpen]; + } + + if (rd.Value[StockHigh] > y1) + rd.Value[StockHigh] = y1; + + if (rd.Value[StockLow] < y2) + rd.Value[StockLow] = y2; + + rd.IsAlternate = (rd.Value[StockOpen] < rd.Value[StockClose]); + + RenderVStockBoxWhisker(g, rd, x, + rd.Value[StockHigh], y1, HiLoBarSegment.HighWhisker); + + RenderVStockBoxWhisker(g, rd, x, + y2, rd.Value[StockLow], HiLoBarSegment.LowWhisker); + + RenderVStockBoxOpenClose(g, rd, x, y1, y2); + } + else + { + int y = (y1 != int.MinValue) ? y1 : y2; + + if (y != int.MinValue) + { + if (y < rd.Value[StockHigh]) + rd.Value[StockHigh] = y; + + if (y > rd.Value[StockLow]) + rd.Value[StockLow] = y; + } + + if (y > rd.Value[StockHigh] && y < rd.Value[StockLow]) + { + RenderVStockBoxWhisker(g, rd, x, rd.Value[StockHigh], y, HiLoBarSegment.HighWhisker); + RenderVStockBoxWhisker(g, rd, x, y, rd.Value[StockLow], HiLoBarSegment.LowWhisker); + + RenderVStockBoxOpenClose(g, rd, x, y, y); + } + else + { + RenderVStockBoxWhisker(g, rd, x, + rd.Value[StockHigh], rd.Value[StockLow], HiLoBarSegment.CenterLine); + + if (y != int.MinValue) + RenderVStockBoxOpenClose(g, rd, x, y, y); + } + } + } + + #region RenderVStockBoxWhisker + + private void RenderVStockBoxWhisker(Graphics g, + HiLoRenderData rd, int x, int y1, int y2, HiLoBarSegment segment) + { + if (y2 > y1) + { + Point pt1 = new Point(x, y1); + Point pt2 = new Point(x, y2 + 1); + + RenderBoxWhisker(g, rd, pt1, pt2, segment); + } + } + + #endregion + + #region RenderVStockBoxOpenClose + + private void RenderVStockBoxOpenClose( + Graphics g, HiLoRenderData rd, int x, int y1, int y2) + { + if (y2 == y1) + { + y1--; + y2++; + } + + y2++; + + Point pt1 = new Point(x - BarWidth / 2, y1); + Point pt2 = new Point(pt1.X + BarWidth, y2); + + int lw = RenderStockBox(g, rd, pt1, pt2); + + Rectangle r = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y); + + if (r.Width > 0 && r.Height > 0) + { + if (GetBarShading(rd.ChartXy) == true) + { + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading) == false) + { + + RenderVBarShading(g, r, r, BarSegment.Top); + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading); + } + } + } + } + + #endregion + + #endregion + + #region RenderVStockBoxMedian + + private void RenderVStockBoxMedian( + Graphics g, HiLoRenderData rd, int x, int y1, int y2) + { + if (rd.Value.Length > StockMedian) + { + int y3 = rd.Value[StockMedian]; + + if (y3 > y1 && y3 < y2) + { + Point pt1 = new Point(x, y3); + Point pt2 = new Point(x + BarWidth - 1, y3); + + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, HiLoBarSegment.MedianLine); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, lstyle.LineWidth)) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.LineWidth > 1) + pt2.X++; + + g.DrawLine(pen, pt1, pt2); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine); + } + } + } + } + + #endregion + + #region RenderVStockHiLo + + private void RenderVStockHiLo(Graphics g, HiLoRenderData rd, int x) + { + int y1, y2, y3, y4; + NormalizeHiLoValues(rd, out y1, out y2, out y3, out y4); + + ChartLineVisualStyle ostyle, cstyle; + NormalizeHiLoStyles(rd, out ostyle, out cstyle); + + if (rd.Value[StockOpen] != int.MinValue) + { + Point pt1 = new Point(x - BarWidth / 2, y2); + Point pt2 = new Point(pt1.X + BarWidth / 2, pt1.Y); + + RenderHiLoWhisker(g, rd, pt1, pt2, ostyle, HiLoBarSegment.OpenWhisker); + } + + if (rd.Value[StockClose] != int.MinValue) + { + Point pt1 = new Point(x + 1, y3); + Point pt2 = new Point(pt1.X + BarWidth / 2, pt1.Y); + + RenderHiLoWhisker(g, rd, pt1, pt2, cstyle, HiLoBarSegment.CloseWhisker); + } + + NormalizeHiLoDir(rd, ref y2, ref y3, ref ostyle, ref cstyle); + + if ((rd.IsAlternate == false && _RenderFullDefRange == true) || + (rd.IsAlternate == true && _RenderFullAltRange == true)) + { + RenderHiLoRange(g, rd, + new Point(x, y1), new Point(x, y4), HiLoBarSegment.FullRange); + } + else + { + if (y1 == y2 && y3 != y4) + y2 = y3; + + // High segment + + if (y2 > y1) + { + int n = (ostyle != null) ? ostyle.LineWidth / 2 : 0; + + RenderHiLoRange(g, rd, + new Point(x, y1), new Point(x, y2 - n), HiLoBarSegment.HighWhisker); + } + + // Low segment + + if (y3 < y4) + { + int n = 0; + + if (y3 == y1) + n = -cstyle.LineWidth / 2; + + else if (y3 != y2) + n = (cstyle.LineWidth + 1) / 2; + + RenderHiLoRange(g, rd, + new Point(x, y3 + n), new Point(x, y4), HiLoBarSegment.LowWhisker); + } + + // Center segment. + + if (y2 < y3 || (y1 == y2 && y3 == y4)) + { + ChartLineVisualStyle y2Style = (y2 == rd.Value[StockOpen]) ? ostyle : cstyle; + ChartLineVisualStyle y3Style = (y3 == rd.Value[StockOpen]) ? ostyle : cstyle; + + if (y2Style != null) + y2 -= (y2Style.LineWidth / 2); + + if (y3Style != null) + y3 += ((y3Style.LineWidth + 1) / 2); + + RenderHiLoRange(g, rd, + new Point(x, y2), new Point(x, y3), HiLoBarSegment.CenterLine); + } + } + } + + #endregion + + #endregion + + #endregion + + #region GetHStockValues + + internal int[] GetHStockValues(ChartXy chartXy, SeriesPoint sp) + { + ChartAxis axis = AxisX ?? chartXy.AxisX; + + int[] values = new int[Math.Max(4, sp.ValueY.Length)]; + + for (int i = 0; i < sp.ValueY.Length; i++) + values[i] = chartXy.GetDataPointX(axis, sp.ValueY[i]); + + NormalizeStockValues(sp, values); + + return (values); + } + + #endregion + + #region GetVStockValues + + internal int[] GetVStockValues(ChartXy chartXy, SeriesPoint sp) + { + ChartAxis axis = AxisY ?? chartXy.AxisY; + + int[] values = new int[Math.Max(4, sp.ValueY.Length)]; + + for (int i = 0; i < sp.ValueY.Length; i++) + values[i] = chartXy.GetDataPointY(axis, sp.ValueY[i]); + + NormalizeStockValues(sp, values); + + return (values); + } + + #endregion + + #region NormalizeStockValues + + private void NormalizeStockValues(SeriesPoint sp, int[] values) + { + for (int i = sp.ValueY.Length; i < values.Length; i++) + values[i] = int.MinValue; + + if (values[StockLow] == int.MinValue) + values[StockLow] = values[StockHigh]; + + if ((IsRotated == true && values[StockLow] > values[StockHigh]) || + (IsRotated == false && values[StockLow] < values[StockHigh])) + { + int temp = values[StockLow]; + values[StockLow] = values[StockHigh]; + values[StockHigh] = temp; + } + } + + #endregion + + #region NormalizeHiLoValues + + private void NormalizeHiLoValues( + HiLoRenderData rd, out int v1, out int v2, out int v3, out int v4) + { + v1 = rd.Value[StockHigh]; + v4 = rd.Value[StockLow]; + + v2 = (rd.Value[StockOpen] != int.MinValue) ? rd.Value[StockOpen] : v1; + v3 = (rd.Value[StockClose] != int.MinValue) ? rd.Value[StockClose] : v4; + + if (v1 > v4) + { + if (v1 v3) + v4 = v3; + + rd.IsAlternate = (v2 > v3); + } + else + { + if (v1 > v2) + v1 = v2; + + if (v4 < v3) + v4 = v3; + + rd.IsAlternate = (v2 < v3); + } + } + + #endregion + + #region NormalizeHiLoDir + + private void NormalizeHiLoDir(HiLoRenderData rd, + ref int v1, ref int v2, ref ChartLineVisualStyle style1, ref ChartLineVisualStyle style2) + { + if (rd.IsAlternate == false) + { + int y = v1; + v1 = v2; + v2 = y; + + ChartLineVisualStyle style = style1; + style1 = style2; + style2 = style1; + } + } + + #endregion + + #region NormalizeHiLoStyles + + private void NormalizeHiLoStyles(HiLoRenderData rd, + out ChartLineVisualStyle ostyle, out ChartLineVisualStyle cstyle) + { + ostyle = (rd.Value[StockOpen] != int.MinValue) ? GetSegLineStyle(rd, HiLoBarSegment.OpenWhisker) : null; + cstyle = (rd.Value[StockClose] != int.MinValue) ? GetSegLineStyle(rd, HiLoBarSegment.CloseWhisker) : null; + + rd.EndDelta = GetHiLoEndDelta(ostyle, cstyle); + } + + #region GetHiLoEndDelta + + private int GetHiLoEndDelta( + ChartLineVisualStyle ostyle, ChartLineVisualStyle cstyle) + { + int delta = 0; + + if (ostyle != null) + { + if (ostyle.LineWidth > 1) + { + if (ostyle.LinePattern != LinePattern.None) + delta = (ostyle.LineWidth + 1) / 2; + } + } + + if (cstyle != null) + { + if (cstyle.LineWidth > 1) + { + if (cstyle.LinePattern != LinePattern.None) + delta = Math.Max(delta, (cstyle.LineWidth + 1) / 2); + } + } + + return (delta); + } + + #endregion + + #endregion + + #region RenderBoxWhisker + + private void RenderBoxWhisker(Graphics g, + HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (chartControl.DoPreRenderSeriesHiloBarEvent(g, chartXy, this, rd, pt1, pt2, segment) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, segment); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + Point pt3 = pt2; + + if (lstyle.LineWidth == 1) + { + if (pt1.X == pt2.X) + pt3.Y--; + else + pt3.X--; + } + + g.DrawLine(pen, pt1, pt3); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent(g, chartXy, this, rd, pt1, pt2, segment); + } + + if (rd.SeriesStyle.HiLoBarVisualStyle.ShowWhiskerCaps == Tbool.True) + RenderWhiskerCap(g, rd, pt1, pt2, segment); + + g.SmoothingMode = sm; + } + + #region RenderWhiskerCap + + private void RenderWhiskerCap(Graphics g, + HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + if (segment == HiLoBarSegment.HighWhisker || segment == HiLoBarSegment.LowWhisker) + { + HiLoBarSegment capSegment = (segment == HiLoBarSegment.HighWhisker) + ? HiLoBarSegment.HighWhiskerCap : HiLoBarSegment.LowWhiskerCap; + + GetWhiskerCapPoints(segment, ref pt1, ref pt2); + + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, capSegment) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, capSegment); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, lstyle.LineWidth)) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.LineWidth == 1) + { + if (pt1.X == pt2.X) + pt2.Y--; + else + pt2.X--; + } + + g.DrawLine(pen, pt1, pt2); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, capSegment); + } + } + } + + #region GetWhiskerCapPoints + + private void GetWhiskerCapPoints( + HiLoBarSegment segment, ref Point pt1, ref Point pt2) + { + int n = BarWidth / 3; + + switch (segment) + { + case HiLoBarSegment.HighWhisker: + if (pt1.X == pt2.X) + { + pt1.X -= n; + pt2.X += n + 1; + pt2.Y = pt1.Y; + } + else + { + pt1.Y -= n; + pt2.Y += n + 1; + pt1.X = pt2.X; + } + break; + + case HiLoBarSegment.LowWhisker: + if (pt1.X == pt2.X) + { + pt1.X -= n; + pt2.X += n + 1; + pt1.Y = pt2.Y; + } + else + { + pt1.Y -= n; + pt2.Y += n + 1; + pt2.X = pt1.X; + } + break; + } + } + + #endregion + + #endregion + + #endregion + + #region RenderStockBox + + private int RenderStockBox( + Graphics g, HiLoRenderData rd, Point pt1, Point pt2) + { + int lineWidth = 0; + + Rectangle r = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y); + + if (r.Width > 0 && r.Height > 0) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, chartXy, this, rd, pt1, pt2, HiLoBarSegment.Box) == false) + { + if (HiLoBarType == HiLoBarType.Box) + RenderStockBoxBackground(g, rd, r); + else + RenderStockCandleBackground(g, rd, r); + + ChartLineVisualStyle lstyle = rd.DefaultStyle.BoxBorder; + + if (CanUseAlternateSegmentStyle(rd) == true) + { + if (rd.IsAlternate == true && rd.AlternateStyle.BoxBorder.IsEmpty == false) + lstyle = rd.AlternateStyle.BoxBorder; + } + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + lineWidth = (int)pen.Width; + + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (pt1.X == pt2.X || pt1.Y == pt2.Y) + { + g.DrawLine(pen, pt1, pt2); + } + else + { + pen.Alignment = PenAlignment.Inset; + + if (lstyle.LineWidth == 1) + { + r.Width--; + r.Height--; + } + + if (r.Width > 0 && r.Height > 0) + g.DrawRectangle(pen, r); + } + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, chartXy, this, rd, pt1, pt2, HiLoBarSegment.Box); + } + + if (ShowHiLoBarMedianLines == true) + { + if (IsRotated == false) + RenderVStockBoxMedian(g, rd, r.X, r.Y, r.Bottom); + else + RenderHStockBoxMedian(g, rd, r.Y, r.X, r.Right); + } + + g.SmoothingMode = sm; + } + + return (lineWidth); + } + + #region RenderStockCandleBackground + + private void RenderStockCandleBackground( + Graphics g, HiLoRenderData rd, Rectangle r) + { + Background bk = + GetBoxBackground(rd, rd.AlternateStyle.BoxBackground, rd.DefaultStyle.BoxBackground); + + if (bk.IsEmpty == false) + { + using (Brush br = bk.GetBrush(r)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region RenderStockBoxBackground + + private void RenderStockBoxBackground( + Graphics g, HiLoRenderData rd, Rectangle r) + { + Background bkDef = rd.DefaultStyle.BoxBackground; + Background bkAlt = rd.AlternateStyle.BoxBackground; + + if (bkAlt.IsEmpty == true) + bkAlt = bkDef; + + if (rd.IsAlternate == true) + { + Background bkSave = bkDef; + bkDef = bkAlt; + bkAlt = bkSave; + } + + if ((ShowHiLoBarMedianLines == true) && (rd.Value.Length > StockMedian)) + { + if (bkAlt.IsEmpty == false) + { + if (IsRotated == false) + r = RenderVBox(g, rd.Value[StockMedian], bkAlt, r); + else + r = RenderHBox(g, rd.Value[StockMedian], bkAlt, r); + } + } + + if (r.Width > 0 && r.Height > 0) + { + if (bkDef.IsEmpty == false) + { + using (Brush br = bkDef.GetBrush(r)) + g.FillRectangle(br, r); + } + } + } + + #region RenderVBox + + private Rectangle RenderVBox(Graphics g, int y, Background bk, Rectangle r) + { + if ((y > r.Y && y < r.Bottom) && bk.IsEmpty == false) + { + int ry = r.Y; + + r.Height = r.Bottom - y; + r.Y = y; + + using (Brush br = bk.GetBrush(r)) + g.FillRectangle(br, r); + + r.Y = ry; + r.Height = y - ry; + } + + return (r); + } + + #endregion + + #region RenderHBox + + private Rectangle RenderHBox(Graphics g, int x, Background bk, Rectangle r) + { + if (x > r.X && x < r.Right) + { + int rw = r.Width; + + r.Width = x - r.X; + + using (Brush br = bk.GetBrush(r)) + g.FillRectangle(br, r); + + r.X = r.Right; + r.Width = rw - r.Width; + } + + return (r); + } + + #endregion + + #endregion + + #endregion + + #region RenderHiLoWhisker + + private ChartLineVisualStyle RenderHiLoWhisker(Graphics g, + HiLoRenderData rd, Point pt1, Point pt2, ChartLineVisualStyle style, HiLoBarSegment segment) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (chartControl.DoPreRenderSeriesHiloBarEvent(g, chartXy, this, rd, pt1, pt2, segment) == false) + { + if (style.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(style.LineColor, Dpi.Width(style.LineWidth))) + { + if (style.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)style.LinePattern; + + if (style.LineWidth == 1) + { + if (pt1.X == pt2.X) + pt2.Y--; + else + pt2.X--; + } + + g.DrawLine(pen, pt1, pt2); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent(g, chartXy, this, rd, pt1, pt2, segment); + } + + g.SmoothingMode = sm; + + return (style); + } + + #endregion + + #region RenderHiLoRange + + private void RenderHiLoRange( + Graphics g, HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + if (pt1.X == pt2.X) + { + if (segment == HiLoBarSegment.HighWhisker || segment == HiLoBarSegment.FullRange) + pt1.Y -= rd.EndDelta; + + if (segment == HiLoBarSegment.LowWhisker || segment == HiLoBarSegment.FullRange) + pt2.Y += rd.EndDelta; + } + else + { + if (segment == HiLoBarSegment.LowWhisker || segment == HiLoBarSegment.FullRange) + pt2.X -= rd.EndDelta; + + if (segment == HiLoBarSegment.HighWhisker || segment == HiLoBarSegment.FullRange) + pt1.X += rd.EndDelta; + } + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (chartControl.DoPreRenderSeriesHiloBarEvent(g, chartXy, this, rd, pt1, pt2, segment) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, segment); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + + g.DrawLine(pen, pt1, pt2); + } + } + } + + if (ShowHiLoBarMedianLines == true) + { + if (segment == HiLoBarSegment.CenterLine || segment == HiLoBarSegment.FullRange) + { + if (IsRotated == false) + RenderVStockBoxMedian(g, rd, pt1.X - BarWidth / 2, pt1.Y, pt2.Y); + else + RenderHStockBoxMedian(g, rd, pt1.Y - BarWidth / 2, pt2.X, pt1.X); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent(g, chartXy, this, rd, pt1, pt2, segment); + + g.SmoothingMode = sm; + } + + #endregion + + #region GetSegLineStyle + + private ChartLineVisualStyle GetSegLineStyle(HiLoRenderData rd, HiLoBarSegment segment) + { + ChartLineVisualStyle style = rd.DefaultStyle.Default; + + if (CanUseAlternateSegmentStyle(rd) == true) + { + if (rd.IsAlternate == true && rd.AlternateStyle.Default.IsEmpty == false) + style = rd.AlternateStyle.Default; + } + + switch (segment) + { + case HiLoBarSegment.FullRange: + break; + + case HiLoBarSegment.Box: + if (rd.IsAlternate == true && rd.AlternateStyle.BoxBorder.IsEmpty == false) + { + style = rd.AlternateStyle.BoxBorder; + } + else + { + if (rd.DefaultStyle.BoxBorder.IsEmpty == false) + style = rd.DefaultStyle.BoxBorder; + } + break; + + case HiLoBarSegment.MedianLine: + if (rd.IsAlternate == true && rd.AlternateStyle.MedianLine.IsEmpty == false) + { + style = rd.AlternateStyle.MedianLine; + } + else + { + if (rd.DefaultStyle.MedianLine.IsEmpty == false) + style = rd.DefaultStyle.MedianLine; + } + break; + + case HiLoBarSegment.HighWhiskerCap: + if (rd.IsAlternate == true && rd.AlternateStyle.HighWhiskerCap.IsEmpty == false) + { + style = rd.AlternateStyle.HighWhiskerCap; + } + else + { + if (rd.DefaultStyle.HighWhiskerCap.IsEmpty == false) + style = rd.DefaultStyle.HighWhiskerCap; + } + break; + + case HiLoBarSegment.LowWhiskerCap: + if (rd.IsAlternate == true && rd.AlternateStyle.LowWhiskerCap.IsEmpty == false) + { + style = rd.AlternateStyle.LowWhiskerCap; + } + else + { + if (rd.DefaultStyle.LowWhiskerCap.IsEmpty == false) + style = rd.DefaultStyle.LowWhiskerCap; + } + break; + + case HiLoBarSegment.HighWhisker: + if (rd.IsAlternate == true && rd.AlternateStyle.HighWhisker.IsEmpty == false) + { + style = rd.AlternateStyle.HighWhisker; + } + else + { + if (rd.DefaultStyle.HighWhisker.IsEmpty == false) + style = rd.DefaultStyle.HighWhisker; + } + break; + + case HiLoBarSegment.LowWhisker: + if (rd.IsAlternate == true && rd.AlternateStyle.LowWhisker.IsEmpty == false) + { + style = rd.AlternateStyle.LowWhisker; + } + else + { + if (rd.DefaultStyle.LowWhisker.IsEmpty == false) + style = rd.DefaultStyle.LowWhisker; + } + break; + + case HiLoBarSegment.OpenWhisker: + if (rd.IsAlternate == true && rd.AlternateStyle.OpenWhisker.IsEmpty == false) + { + style = rd.AlternateStyle.OpenWhisker; + } + else + { + if (rd.DefaultStyle.OpenWhisker.IsEmpty == false) + style = rd.DefaultStyle.OpenWhisker; + } + break; + + case HiLoBarSegment.CloseWhisker: + if (rd.IsAlternate == true && rd.AlternateStyle.CloseWhisker.IsEmpty == false) + { + style = rd.AlternateStyle.CloseWhisker; + } + else + { + if (rd.DefaultStyle.CloseWhisker.IsEmpty == false) + style = rd.DefaultStyle.CloseWhisker; + } + break; + + case HiLoBarSegment.CenterLine: + if (rd.IsAlternate == true && rd.AlternateStyle.CenterLine.IsEmpty == false) + { + style = rd.AlternateStyle.CenterLine; + } + else + { + if (rd.DefaultStyle.CenterLine.IsEmpty == false) + style = rd.DefaultStyle.CenterLine; + } + break; + } + + return (style); + } + + #region CanUseAlternateSegmentStyle + + private bool CanUseAlternateSegmentStyle(HiLoRenderData rd) + { + Tbool uas = rd.SeriesStyle.HiLoBarVisualStyle.UseAlternateSegmentStyle; + + if (uas == Tbool.NotSet) + return (HiLoBarType == HiLoBarType.Candle); + + return (uas == Tbool.True); + } + + #endregion + + #endregion + + #region GetBoxBackground + + private Background GetBoxBackground(HiLoRenderData rd, Background abk, Background sbk) + { + if (rd.IsAlternate == true && abk.IsEmpty == false) + return (abk); + + return (sbk); + } + + #endregion + + #endregion + + #region HighLightPoints + + private bool HighLightPoints(ChartXy chartXy) + { + if (chartXy.ChartCrosshair.Visible == false) + return (false); + + if (CrosshairHighlightPoints != Tbool.NotSet) + return (CrosshairHighlightPoints == Tbool.True); + + return (chartXy.ChartCrosshair.HighlightPoints); + } + + #endregion + + #region GetHighlightStyle + + private PointMarkerVisualStyle GetHighlightStyle( + ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + if (HighLightPoints(chartXy) == true) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + PointMarkerVisualStyle hstyle = pstyle.Copy(); + + if (sstyle.MarkerHighlightVisualStyle.IsEmpty == false) + { + hstyle.ApplyStyle(sstyle.MarkerHighlightVisualStyle); + } + else + { + Size size = hstyle.Size; + + size.Width += 4; + size.Height += 4; + + hstyle.Size = size; + } + + return (hstyle); + } + + return (null); + } + + #endregion + + #region GetPointMarkerImage + + private Image GetPointMarkerImage( + Graphics g, ChartXy chartXy, PointMarkerVisualStyle style) + { + Image image = PointMarkerImage; + + if (image == null) + { + image = chartXy.GetPointMarker(g, style); + + PointMarkerImage = image; + } + + return (image); + } + + #endregion + + #region GetHighlightImage + + private Image GetHighlightImage( + Graphics g, ChartXy chartXy, PointMarkerVisualStyle style) + { + Image image = PointMarkerHighlightImage; + + if (image == null) + { + image = chartXy.GetPointMarker(g, style); + + PointMarkerHighlightImage = image; + } + + return (image); + } + + #endregion + + #region GetEmptyMarkerImage + + private Image GetEmptyMarkerImage( + Graphics g, ChartXy chartXy, PointMarkerVisualStyle style) + { + Image image = PointMarkerEmptyImage; + + if (image == null) + { + image = chartXy.GetPointMarker(g, style); + + PointMarkerEmptyImage = image; + } + + return (image); + } + + #endregion + + #region GatherSeriesPoints + + private PointData GatherSeriesPoints( + ChartXy chartXy, SortedSeriesPoints ssp, int index, int count, bool allArgs) + { + if (_PointData == null) + _PointData = GatherSeriesPointsEx(chartXy, ssp, index, count, allArgs); + + return (_PointData); + } + + private PointData GatherSeriesPointsEx( + ChartXy chartXy, SortedSeriesPoints ssp, int index, int count, bool allArgs) + { + PointData pd = new PointData(); + + pd.Points = new List(); + pd.SeriesPoints = new List(); + + if (EnableEmptyValues == true) + { + PointData epd = new PointData(); + + epd.Points = new List(); + epd.SeriesPoints = new List(); + + int n = 0; + bool empty = false; + + for (int i = 0; i < count; i++) + { + if (ssp[index + i].IsEmpty != empty) + { + int cnt = i - n; + + if (cnt > 0) + GetPointList(chartXy, ssp, index + n, cnt, allArgs, empty ? epd : pd); + + empty = !empty; + + n = i; + } + } + + if (n < count) + GetPointList(chartXy, ssp, index + n, count - n, allArgs, empty ? epd : pd); + + _EmptyPointData = epd; + } + else + { + GetPointList(chartXy, ssp, index, count, allArgs, pd); + } + + return (pd); + } + + #endregion + + #region GetPointList + + private void GetPointList(ChartXy chartXy, + SortedSeriesPoints ssp, int index, int cnt, bool allArgs, PointData pd) + { + GetPointList(chartXy, ssp, index, cnt, 0, 0, allArgs, pd); + } + + private void GetPointList(ChartXy chartXy, SortedSeriesPoints ssp, + int index, int cnt, int skip, int minDistance, bool allArgs, PointData pd) + { + if (cnt > 0) + { + Stack stack = new Stack(); + + skip++; + + Point lpt = new Point(-5000, -5000); + + if (allArgs == false) + { + if (cnt > skip && skip > 1) + cnt = (cnt + skip - 1) / skip; + + for (int i = 0; i < cnt; i++) + { + int n = index + (i * skip); + + if (n >= ssp.Count) + break; + + SeriesPoint sp = ssp[n]; + + if (sp.Visible == true) + { + Point pt = chartXy.GetDataPointEx(this, sp, 0); + + if (minDistance <= 0 || DataPointDistanceOk(lpt, pt, minDistance) == true) + { + stack.Push(sp); + stack.Push(pt); + + lpt = pt; + } + } + } + } + else + { + int n = 0; + + for (int i = 0; i < cnt; i++) + n += ssp[index + i].ValueY.Length; + + n /= (n + skip - 1) / skip; + + int m = 0; + + for (int i = 0; i < cnt; i++) + { + SeriesPoint sp = ssp[index + i]; + + for (int j = 0; j < sp.ValueY.Length; j++) + { + if (m % skip == 0) + { + int w = m / skip; + + Point pt = chartXy.GetDataPointNa(this, sp, j); + + if (minDistance <= 0 || DataPointDistanceOk(lpt, pt, minDistance) == true) + { + stack.Push(sp); + stack.Push(pt); + + lpt = pt; + } + } + + m++; + } + } + } + + if (stack.Count > 0) + { + int n = stack.Count / 2; + + Point[] points = new Point[n]; + SeriesPoint[] seriesPoints = new SeriesPoint[n]; + + for (int i = n - 1; i >= 0; i--) + { + points[i] = (Point)stack.Pop(); + seriesPoints[i] = (SeriesPoint)stack.Pop(); + } + + pd.Points.Add(points); + pd.SeriesPoints.Add(seriesPoints); + } + } + } + + #region DataPointDistanceOk + + private bool DataPointDistanceOk(Point lpt, Point pt, int minDistance) + { + int dx = (lpt.X - pt.X); + int dy = (lpt.Y - pt.Y); + + int h = (int)AMath.Sqrt(dx * dx + dy * dy); + + return (h >= minDistance); + } + + #endregion + + #endregion + + #endregion + + #region Render + + internal override void Render(ChartRenderInfo renderInfo) + { + if (Displayed == true) + { + Rectangle bounds = BoundsRelative; + + if (renderInfo.ClipRectangle.IntersectsWith(bounds)) + RenderOverride(renderInfo); + } + } + + #endregion + + #region RenderIndicators + + internal void RenderIndicators(ChartRenderInfo renderInfo, bool onTop) + { + if (SeriesType != SeriesType.HorizontalDot || SeriesType != SeriesType.VerticalDot) + { + if (SeriesPoints.Count > 0) + { + Graphics g = renderInfo.Graphics; + + ChartXy chartXy = Parent as ChartXy; + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + + foreach (ChartIndicator indicator in ChartIndicators) + { + if (indicator.DisplayOnTop == onTop) + { + if (indicator.IsDisplayed == true) + { + ssp.SlopeIndex = indicator.ValueYIndex; + + switch (indicator.IndicatorType) + { + case ChartIndicatorType.RegressionLine: + RenderRegressionLine(g, chartXy, ssp, (RegressionLine)indicator); + break; + + case ChartIndicatorType.TrendLine: + RenderTrendLine(g, chartXy, ssp, (TrendLine)indicator); + break; + } + } + } + } + } + } + } + + #region RenderRegressionLine + + private void RenderRegressionLine(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, RegressionLine regline) + { + double m = regline.Slope; + double b = regline.Intercept; + + if (m.Equals(double.NaN) == false && b.Equals(double.NaN) == false) + { + ChartAxis axis = AxisX ?? chartXy.AxisX; + + double x1, x2; + + switch (ActualScaleTypeX) + { + case ScaleType.DateTime: + x1 = chartXy.GetDateTimePointValue(axis, axis.TickmarkLayout, (DateTime)MinValueX); + x2 = chartXy.GetDateTimePointValue(axis, axis.TickmarkLayout, (DateTime)MaxValueX); + break; + + default: + x1 = Convert.ToDouble(MinValueX); + x2 = Convert.ToDouble(MaxValueX); + break; + } + + Point pt1 = chartXy.GetPointFromValue(this, MinValueX, m * x1 + b); + Point pt2 = chartXy.GetPointFromValue(this, MaxValueX, m * x2 + b); + + if (SeriesType == SeriesType.VerticalBar || + SeriesType == SeriesType.VerticalHiLoBar) + { + pt1.X += BarOffset; + pt2.X += BarOffset; + } + else if (SeriesType == SeriesType.HorizontalBar || + SeriesType == SeriesType.HorizontalHiLoBar) + { + pt1.Y += BarOffset; + pt2.Y += BarOffset; + } + + RegressionLineVisualStyle rstyle = regline.RegressionLineVisualStyle; + + Color color = rstyle.LineColor; + + if (color.IsEmpty) + color = DefaultPaletteColor; + + using (Pen pen = new Pen(color, Dpi.Width(rstyle.LineWidth))) + { + if (rstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)rstyle.LinePattern; + + if (rstyle.StartCap != ChartLineCap.NotSet) + pen.StartCap = (LineCap)rstyle.StartCap; + + if (rstyle.EndCap != ChartLineCap.NotSet) + pen.EndCap = (LineCap)rstyle.EndCap; + + g.DrawLine(pen, pt1, pt2); + } + } + } + + #endregion + + #region RenderTrendLine + + private void RenderTrendLine(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, TrendLine trendLine) + { + SeriesPoint sp1 = ssp.GetSeriesPoint(trendLine.ValueX1); + SeriesPoint sp2 = ssp.GetSeriesPoint(trendLine.ValueX2); + + if (sp1 != null && sp2 != null) + { + Point pt1 = chartXy.GetDataPointEx(this, sp1, trendLine.ValueYIndex); + Point pt2 = chartXy.GetDataPointEx(this, sp2, trendLine.ValueYIndex); + + if (SeriesType == SeriesType.VerticalBar || + SeriesType == SeriesType.VerticalHiLoBar) + { + pt1.X += BarOffset; + pt2.X += BarOffset; + } + else if (SeriesType == SeriesType.HorizontalBar || + SeriesType == SeriesType.HorizontalHiLoBar) + { + pt1.Y += BarOffset; + pt2.Y += BarOffset; + } + + if (pt1.X >= chartXy.ContentBounds.X && pt2.X < chartXy.ContentBounds.Right) + { + TrendLineVisualStyle tstyle = trendLine.TrendLineVisualStyle; + + Color color = tstyle.LineColor; + + if (color.IsEmpty) + color = DefaultPaletteColor; + + using (Pen pen = new Pen(color, Dpi.Width(tstyle.LineWidth))) + { + if (tstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)tstyle.LinePattern; + + if (tstyle.StartCap != ChartLineCap.NotSet) + pen.StartCap = (LineCap)tstyle.StartCap; + + if (tstyle.EndCap != ChartLineCap.NotSet) + pen.EndCap = (LineCap)tstyle.EndCap; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #endregion + + #region InvalidatePoints + + internal void InvalidatePoints() + { + _PointData = null; + _EmptyPointData = null; + _ConvexHullPoints = null; + _StepPointData = null; + } + + #endregion + + #region InvalidatePointLabels + + internal void InvalidatePointLabels() + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + chartXy.InvalidatePointLabelsEx(); + } + + #endregion + + #region RefreshSeries + + /// + /// Causes the series to refresh its display, as the underlying + /// series data (potentially) has changed in some way. + /// + public void RefreshSeries() + { + SeriesRangeChanged = true; + + InvalidateLayout(); + } + + #endregion + + #region UpdateSeriesRange + + internal void UpdateSeriesRange() + { + if (SeriesRangeChanged == true) + { + if (Parent == null) + return; + + SeriesRangeChanged = false; + + IsSorted = true; + + QualitativeXValues.Clear(); + QualitativeYValues.Clear(); + + _MinValueX = null; + _MinValueY = null; + _MaxValueX = null; + _MaxValueY = null; + + if (SeriesPoints.Count > 0) + { + ChartXy chartXy = Parent as ChartXy; + + Type dataTypeX = null; + Type dataTypeY = null; + + if (ChartControl != null && ChartControl.DesignerHosted == true) + { + dataTypeX = GetDataTypeX(SeriesPoints); + dataTypeY = GetDataTypeY(SeriesPoints); + + ActualScaleTypeX = GetActualScaleType(dataTypeX, ScaleTypeX); + ActualScaleTypeY = GetActualScaleType(dataTypeY, ScaleTypeY); + + _PlotData = null; + } + + for (int i = 0; i < SeriesPoints.Count; i++) + { + SeriesPoint sp = SeriesPoints[i]; + + if (sp.Visible == true) + { + UpdateXValueRange(chartXy, sp, ref dataTypeX); + + switch (SeriesType) + { + case SeriesType.VerticalDot: + case SeriesType.HorizontalDot: + ActualScaleTypeY = ScaleType.Quantitative; + break; + + case SeriesType.Bubble: + UpdateYBubbleRange(chartXy, sp, ref dataTypeY); + break; + + default: + UpdateYValueRange(chartXy, sp, ref dataTypeY); + break; + } + } + } + + if (SeriesType == SeriesType.VerticalDot || + SeriesType == SeriesType.HorizontalDot) + { + UpdateStackedYValueRange(); + } + else + { + if (QualitativeXValues.Count > 0) + { + _MinValueX = 0; + _MaxValueX = QualitativeXValues.Count - 1; + } + + if (QualitativeYValues.Count > 0) + { + _MinValueY = 0; + _MaxValueY = QualitativeYValues.Count - 1; + } + } + } + } + } + + #region GetDataTypeX + + private Type GetDataTypeX(SeriesPointCollection spc) + { + Type dataType = null; + + for (int i = 0; i < spc.Count; i++) + { + SeriesPoint sp = spc[i]; + + if (sp.Visible == true) + { + if (sp.ValueX != null) + { + dataType = sp.ValueX.GetType(); + + if (dataType != typeof(int)) + break; + } + } + } + + return (dataType); + } + + #endregion + + #region GetDataTypeY + + private Type GetDataTypeY(SeriesPointCollection spc) + { + Type dataType = null; + + for (int i = 0; i < spc.Count; i++) + { + SeriesPoint sp = spc[i]; + + if (sp.Visible == true) + { + if (sp.ValueY != null && sp.ValueY.Length > 0) + { + for (int j = 0; j < sp.ValueY.Length; j++) + { + object valueY = sp.ValueY[j]; + + if (valueY != null) + { + dataType = valueY.GetType(); + + if (dataType != typeof(int)) + return (dataType); + } + } + } + } + } + + return (dataType); + } + + #endregion + + #region UpdateXValueRange + + private int _CmpLast; + + private void UpdateXValueRange(ChartXy chartXy, SeriesPoint sp, ref Type dataType) + { + object value = sp.ValueX; + + if (value != null) + { + if (dataType == null) + { + dataType = value.GetType(); + + ActualScaleTypeX = GetActualScaleType(dataType, ScaleTypeX); + } + else + { + if (value.GetType() != dataType) + { + if (ChartControl.DesignerHosted == true) + { + try + { + sp.ValueX = Convert.ChangeType(value, dataType); + } + catch + { + sp.ValueX = null; + } + + value = sp.ValueX; + } + else + { + throw new Exception("Cannot mix ValueX data types (" + + dataType + "," + value.GetType() + ")."); + } + } + } + + switch (_ActualScaleTypeX) + { + case ScaleType.Qualitative: + if (QualitativeXValues.Contains(value) == false) + QualitativeXValues.Add(value); + break; + + default: + if (_MinValueX == null) + { + _MinValueX = value; + _MaxValueX = value; + + _CmpLast = 0; + } + else + { + if (chartXy.DataCompare(value, _MaxValueX) >= 0) + { + _MaxValueX = value; + + if (_CmpLast == 0) + _CmpLast = 1; + + else if (_CmpLast < 0) + IsSorted = false; + } + else + { + if (chartXy.DataCompare(value, _MinValueX) <= 0) + _MinValueX = value; + + if (_CmpLast == 0) + _CmpLast = -1; + + else if (_CmpLast > 0) + IsSorted = false; + } + } + break; + } + } + } + + #endregion + + #region UpdateYBubbleRange + + private void UpdateYBubbleRange(ChartXy chartXy, SeriesPoint sp, ref Type dataType) + { + if (sp.ValueY == null || sp.ValueY.Length < 1) + throw new Exception("Invalid Bubble Chart 'Y' arguments."); + + if (_PlotData == null) + _PlotData = new BubblePlotData(); + + BubblePlotData bdata = (BubblePlotData)_PlotData; + + object value = sp.ValueY[0]; + + sp.IsEmptyValue = IsEmptyValue(value); + + if (sp.IsEmpty == false) + { + if (dataType == null) + { + bdata.Clear(); + + dataType = value.GetType(); + + ActualScaleTypeY = GetActualScaleType(dataType, ScaleTypeY); + } + else + { + if (value.GetType() != dataType) + { + if (ChartControl.DesignerHosted == true) + { + sp.ValueY[0] = Convert.ChangeType(value, dataType); + + value = sp.ValueY[0]; + } + else + { + throw new Exception("Cannot mix ValueY data types (" + + dataType + "," + value.GetType() + ")."); + } + } + } + + ProcessYValueRange(chartXy, value); + + if (sp.ValueY.Length > 1) + { + double bvalue = GetDoubleValue(sp.ValueY[1]); + + bvalue = Math.Abs(bvalue); + + if (bvalue < bdata.MinSize) + bdata.MinSize = bvalue; + + if (bvalue > bdata.MaxSize) + bdata.MaxSize = bvalue; + + bdata.TotalSize += bvalue; + + if (sp.ValueY.Length > 2) + { + double ivalue = GetDoubleValue(sp.ValueY[2]); + + if (ivalue < bdata.MinIntensity) + bdata.MinIntensity = ivalue; + + if (ivalue > bdata.MaxIntensity) + bdata.MaxIntensity = ivalue; + } + } + } + } + + #endregion + + #region UpdateYValueRange + + private void UpdateYValueRange(ChartXy chartXy, SeriesPoint sp, ref Type dataType) + { + if (sp.ValueY != null) + { + for (int j = 0; j < sp.ValueY.Length; j++) + { + object value = sp.ValueY[j]; + + sp.IsEmptyValue = IsEmptyValue(value); + + if (sp.IsEmpty == false) + { + if (dataType == null) + { + dataType = value.GetType(); + + ActualScaleTypeY = GetActualScaleType(dataType, ScaleTypeY); + } + else + { + if (value.GetType() != dataType) + { + if (ChartControl.DesignerHosted == true) + { + try + { + sp.ValueY[j] = Convert.ChangeType(value, dataType); + } + catch + { + sp.ValueY[j] = null; + } + + value = sp.ValueY[j]; + } + else + { + throw new Exception("Cannot mix ValueY data types (" + + dataType + "," + value.GetType() + ")."); + } + } + } + + ProcessYValueRange(chartXy, value); + } + } + } + else + { + sp.IsEmptyValue = true; + } + } + + #region IsEmptyValue + + private bool IsEmptyValue(object value) + { + if (value == null) + return (true); + + if (EmptyValues != null) + { + Type dataType = value.GetType(); + + for (int i = 0; i < EmptyValues.Length; i++) + { + if (EmptyValues[i] != null) + { + if (dataType == EmptyValues[i].GetType()) + { + if (value.Equals(EmptyValues[i]) == true) + return (true); + } + } + } + } + + return (false); + } + + #endregion + + #endregion + + #region UpdateStackedYValueRange + + private void UpdateStackedYValueRange() + { + if (QualitativeXValues.Count > 0 || QualitativeYValues.Count > 0) + throw new Exception("Dot plots can not contain Qualitative values."); + + Dictionary pd = new Dictionary(); + + for (int i = 0; i < SeriesPoints.Count; i++) + { + SeriesPoint sp = SeriesPoints[i]; + + if (sp.Visible == true) + { + object ox = sp.ValueX; + + double count = 0; + + if (sp.ValueY != null && sp.ValueY.Length > 0) + { + foreach (object oy in sp.ValueY) + { + sp.IsEmptyValue = IsEmptyValue(oy); + + if (sp.IsEmpty == false) + count += GetDoubleValue(oy); + } + } + else + { + if (sp.IsEmpty == false) + count++; + } + + if (sp.IsEmpty == false) + { + if (pd.ContainsKey(ox) == true) + pd[ox] += count; + else + pd.Add(ox, count); + } + } + } + + double maxValue = 0; + + foreach (KeyValuePair kvp in pd) + { + if (kvp.Value > maxValue) + maxValue = kvp.Value; + } + + _MinValueY = 0.0; + _MaxValueY = maxValue; + } + + #endregion + + #region ProcessYValueRange + + private void ProcessYValueRange(ChartXy chartXy, object value) + { + switch (_ActualScaleTypeY) + { + case ScaleType.Qualitative: + if (QualitativeYValues.Contains(value) == false) + QualitativeYValues.Add(value); + break; + + default: + if (_MinValueY == null) + { + _MinValueY = value; + _MaxValueY = value; + } + else + { + int cmpMax = chartXy.DataCompare(value, _MaxValueY); + + if (cmpMax >= 0) + { + _MaxValueY = value; + } + else + { + int cmpMin = chartXy.DataCompare(value, _MinValueY); + + if (cmpMin <= 0) + _MinValueY = value; + } + } + break; + } + } + + #endregion + + #region GetActualScaleType + + private ScaleType GetActualScaleType(Type dataType, ScaleType scaleType) + { + ScaleType autoType = SeriesPoint.GetScaleType(dataType); + + if (scaleType == ScaleType.NotSet || scaleType == ScaleType.Auto) + return (autoType); + + if (scaleType == autoType) + return (scaleType); + + if (scaleType == ScaleType.Qualitative) + return (scaleType); + + throw new Exception("Set ScaleType is incompatible with series data."); + } + + #endregion + + #endregion + + #region ResetSortedPoints + + internal void ResetSortedPoints() + { + if (IsSorted == false) + _SortedSeriesPoints = null; + } + + #endregion + + #region GetValueX + + internal object GetValueX(SeriesPoint sp) + { + if (IsRotated == false) + return (sp.ValueX); + + if (sp.ValueY != null && sp.ValueY.Length > 0) + return (sp.ValueY[0]); + + return (null); + } + + #endregion + + #region GetValueY + + internal object GetValueY(SeriesPoint sp, int index) + { + if (IsRotated == true) + return (sp.ValueX); + + if (sp.ValueY != null && sp.ValueY.Length > index) + return (sp.ValueY[index]); + + return (null); + } + + #endregion + + #region GetQualitativeValueX + + internal object GetQualitativeValueX(int index) + { + if (IsRotated == false) + { + if (QualitativeXValues != null && QualitativeXValues.Count > index) + return (QualitativeXValues[index]); + } + else + { + if (QualitativeYValues != null && QualitativeYValues.Count > index) + return (QualitativeYValues[index]); + } + + return (null); + } + + #endregion + + #region GetQualitativeValueY + + internal object GetQualitativeValueY(int index) + { + if (IsRotated == true) + { + if (QualitativeXValues != null && QualitativeXValues.Count > index) + return (QualitativeXValues[index]); + } + else + { + if (QualitativeYValues != null && QualitativeYValues.Count > index) + return (QualitativeYValues[index]); + } + + return (null); + } + + #endregion + + #region GetDoubleValue + + private double GetDoubleValue(object value) + { + if (value is double) + return (double)value; + + return (Convert.ToDouble(value)); + } + + #endregion + + #region GetBarWidthRatio + + internal double GetBarWidthRatio(ChartXy chartXy) + { + return (_BarWidthRatio > 0 ? _BarWidthRatio : + (chartXy.BarWidthRatio > 0 ? chartXy.BarWidthRatio : 1)); + } + + #endregion + + #region GetPointLabels + + internal List GetPointLabels(Graphics g) + { + ChartXy chartXy = Parent as ChartXy; + + PointLabelDisplayMode plmode = GetPointLabelDisplayType(chartXy); + + if (plmode != PointLabelDisplayMode.None) + { + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + ssp.SeriesLayoutCount = chartXy.SeriesLayoutCount; + + ChartAxis axisX = (IsRotated == true) ? AxisY ?? chartXy.AxisY : AxisX ?? chartXy.AxisX; + ChartAxis axisY = (IsRotated == true) ? AxisX ?? chartXy.AxisX : AxisY ?? chartXy.AxisY; + + if (ssp.Count > 0) + { + DataLabelVisualStyle dstyle = EffectiveDataLabelStyle; + + PointData pd = GetLabelPoints(chartXy, ssp, 0, ssp.Count, plmode); + + List plabels = new List(); + + if (pd.Points.Count > 0) + { + for (int i = 0; i < pd.Points.Count; i++) + { + Point[] pts = pd.Points[i]; + SeriesPoint[] spts = pd.SeriesPoints[i]; + + for (int j = 0; j < pts.Length; j++) + { + SeriesPoint sp = spts[j]; + Point pt = pts[j]; + + if (IsBarSeries == true && ShowOriginValueLabels == false) + { + if (IsBarOrigin(chartXy, sp) == true) + continue; + } + + string text = GetPointLabelText(sp, axisX, axisY, dstyle); + + PointLabel pl = new PointLabel(sp, pt, text); + + pl.LabelSize = MeasurePointLabel(g, pl); + + plabels.Add(pl); + } + } + } + + if ((plmode & PointLabelDisplayMode.DataLabels) == PointLabelDisplayMode.DataLabels) + GetDataLabels(g, plabels, chartXy, axisX, axisY, dstyle); + + return (plabels); + } + } + + return (null); + } + + #region GetPointLabelDisplayType + + private PointLabelDisplayMode GetPointLabelDisplayType(ChartXy chartXy) + { + PointLabelDisplayMode ptype = PointLabelDisplayMode; + + if (ptype != PointLabelDisplayMode.NotSet) + return (ptype); + + ptype = chartXy.PointLabelDisplayMode; + + return (ptype != PointLabelDisplayMode.NotSet ? ptype : PointLabelDisplayMode.None); + } + + #endregion + + #region GetLabelPoints + + /// + /// Gets the collection of series PointData for the given PointLabelDisplayType. + /// + /// + /// + public PointData GetLabelPoints(PointLabelDisplayMode displayType) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + { + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + + return (GetLabelPoints(chartXy, ssp, 0, ssp.Count, displayType)); + } + + return (null); + } + + private PointData GetLabelPoints(ChartXy chartXy, + SortedSeriesPoints ssp, int index, int count, PointLabelDisplayMode displayType) + { + PointData pd = new PointData(); + + pd.Points = new List(); + pd.SeriesPoints = new List(); + + if ((displayType & PointLabelDisplayMode.AllSeriesPoints) == PointLabelDisplayMode.AllSeriesPoints) + GetPointList(chartXy, ssp, index, count, _PointLabelSkip, _PointLabelMinDistance, false, pd); + + else if ((displayType & ~PointLabelDisplayMode.AllSeriesPoints) != 0) + { + List lmmsp = new List(); + + if ((displayType & PointLabelDisplayMode.MinValueX) == PointLabelDisplayMode.MinValueX) + { + int n; + + if (IsRotated == true) + { + if (QualitativeYValues.Count > 0) + n = (int)MinValueX; + else + n = ssp.SearchY(MinValueX); + } + else + { + if (QualitativeXValues.Count > 0) + n = (int)MinValueX; + else + n = (ssp.IsSorted == true) ? 0 : ssp.SearchX(MinValueX); + } + + if (n >= 0) + lmmsp.Add(ssp[n]); + } + + if ((displayType & PointLabelDisplayMode.MaxValueX) == PointLabelDisplayMode.MaxValueX) + { + int n; + + if (IsRotated == true) + { + if (QualitativeYValues.Count > 0) + n = (int)MaxValueX; + else + n = ssp.SearchY(MaxValueX); + } + else + { + if (QualitativeXValues.Count > 0) + n = (int)MaxValueX; + else + n = (ssp.IsSorted == true) ? ssp.Count - 1 : ssp.SearchX(MaxValueX); + } + + if (n >= 0 && lmmsp.Contains(ssp[n]) == false) + lmmsp.Add(ssp[n]); + } + + if ((displayType & PointLabelDisplayMode.MinValueY) == PointLabelDisplayMode.MinValueY) + { + int n; + + if (IsRotated == true) + { + if (QualitativeXValues.Count > 0) + n = (int)MinValueY; + else + n = (ssp.IsSorted == true) ? 0 : ssp.SearchX(MinValueY); + } + else + { + if (QualitativeYValues.Count > 0) + n = (int)MinValueY; + else + n = ssp.SearchY(MinValueY); + } + + if (n >= 0 && lmmsp.Contains(ssp[n]) == false) + lmmsp.Add(ssp[n]); + } + + if ((displayType & PointLabelDisplayMode.MaxValueY) == PointLabelDisplayMode.MaxValueY) + { + int n; + + if (IsRotated == true) + { + if (QualitativeXValues.Count > 0) + n = (int)MaxValueY; + else + n = ssp.SearchX(MaxValueY); + } + else + { + if (QualitativeYValues.Count > 0) + n = (int)MaxValueY; + else + n = ssp.SearchY(MaxValueY); + } + + if (n >= 0 && lmmsp.Contains(ssp[n]) == false) + lmmsp.Add(ssp[n]); + } + + if (lmmsp.Count > 0) + { + SeriesPoint[] mmsp = new SeriesPoint[lmmsp.Count]; + Point[] mmpt = new Point[lmmsp.Count]; + + for (int i = 0; i < lmmsp.Count; i++) + { + mmsp[i] = lmmsp[i]; + mmpt[i] = chartXy.GetDataPointNa(this, lmmsp[i], 0); + } + + pd.SeriesPoints.Add(mmsp); + pd.Points.Add(mmpt); + } + } + + return (pd); + } + + #endregion + + #region GetDataLabels + + private void GetDataLabels(Graphics g, List plabels, + ChartXy chartXy, ChartAxis axisX, ChartAxis axisY, DataLabelVisualStyle dstyle) + { + foreach (DataLabel dlabel in DataLabels) + { + DataLabelVisualStyle xstyle = dlabel.EffectiveDataLabelStyle; + + PointLabel pl = FindPointLabel(plabels, dlabel); + + if (pl != null) + { + if (string.IsNullOrEmpty(dlabel.Text) == false) + pl.Label = dlabel.Text; + + pl.DataLabelVisualStyle = xstyle; + pl.BarLabelPosition = dlabel.BarLabelPosition; + + pl.LabelSize = MeasurePointLabel(g, pl); + } + else + { + SeriesPoint sp = new SeriesPoint(dlabel.ValueX, dlabel.ValueY); + + string label = (string.IsNullOrEmpty(dlabel.Text) == false) ? dlabel.Text : + GetPointLabelText(sp, axisX, axisY, xstyle); + + Point pt = chartXy.GetDataPointNa(this, sp, 0); + + pl = new PointLabel(sp, pt, label); + + pl.IsDataLabel = true; + + pl.DataLabelVisualStyle = xstyle; + pl.BarLabelPosition = dlabel.BarLabelPosition; + + pl.LabelSize = MeasurePointLabel(g, pl); + + plabels.Add(pl); + } + } + } + + #region FindPointLabel + + private PointLabel FindPointLabel(List plabels, DataLabel dlabel) + { + for (int i = 0; i < plabels.Count; i++) + { + SeriesPoint sp = plabels[i].SeriesPoint; + + if ((sp.ValueX != null) && + (sp.ValueY != null && sp.ValueY.Length > 0) && + (sp.ValueX.Equals(dlabel.ValueX) && sp.ValueY[0].Equals(dlabel.ValueY))) + { + return (plabels[i]); + } + } + + return (null); + } + + #endregion + + #endregion + + #region IsBarOrigin + + internal bool IsBarOrigin(ChartXy chartXy, SeriesPoint sp) + { + object value = ((sp.ValueY != null && sp.ValueY.Length > 1) ? sp.ValueY[1] : (chartXy.BarOrigin ?? 0)); + + ChartAxis axis = AxisY ?? chartXy.AxisY; + + switch (axis.ScaleType) + { + case ScaleType.Quantitative: + double d1 = Convert.ToDouble(value); + double d2 = Convert.ToDouble(sp.ValueY[0]); + + return (d1.Equals(d2)); + + case ScaleType.Qualitative: + string s1 = axis.QualitativeValues[0] as string; + string s2 = sp.ValueY[0] as string; + + if (s1 != null) + return (s1.Equals(s2)); + break; + } + + return (false); + } + + #endregion + + #region GetPointLabelText + + private string GetPointLabelText(SeriesPoint sp, + ChartAxis axisX, ChartAxis axisY, DataLabelVisualStyle dstyle) + { + string pattern = dstyle.TextFormat; + + if (string.IsNullOrEmpty(pattern) == true) + return (GetDefaultPointLabelText(sp, axisX, axisY, dstyle)); + + pattern = pattern.Replace("\\n", "\n"); + pattern = pattern.Replace("\\r", "\r"); + + Regex regex = new Regex("{([^}]*)}"); + MatchCollection mc = regex.Matches(pattern); + + StringBuilder sb = new StringBuilder(); + + int index = 0; + + foreach (Match ma in mc) + { + if (ma.Index > index) + sb.Append(pattern.Substring(index, ma.Index - index)); + + sb.Append(ProcessFormatSpecifier(sp, axisX, axisY, ma.Value)); + + index = ma.Index + ma.Length; + } + + if (index < pattern.Length) + sb.Append(pattern.Substring(index)); + + return (sb.ToString()); + } + + #region ProcessFormatSpecifier + + private string ProcessFormatSpecifier( + SeriesPoint sp, ChartAxis axisX, ChartAxis axisY, string pattern) + { + string s = pattern.Substring(1, pattern.Length - 2); + + int n = s.IndexOf(':'); + + if ((uint)n > s.Length - 1) + n = s.Length; + + string placeHolder = s.Substring(0, n).Trim().ToUpper(); + string formatSpecifier = (n + 1 < s.Length) ? s.Substring(n + 1) : ""; + + try + { + switch (placeHolder) + { + case "X": + return (GetPointLabelText(sp.ValueX, axisX, formatSpecifier)); + + case "Y": + case "Y0": + if (sp.ValueY != null && sp.ValueY.Length > 0) + return (GetPointLabelText(sp.ValueY[0], axisY, formatSpecifier)); + + return (""); + + case "S": + if (string.IsNullOrEmpty(formatSpecifier) == false) + return (String.Format(formatSpecifier, Name)); + + return (Name); + + default: + if (placeHolder.StartsWith("Y") == true) + { + int index = int.Parse(placeHolder.Substring(1)); + + if (sp.ValueY != null && sp.ValueY.Length > index) + return (GetPointLabelText(sp.ValueY[index], axisY, formatSpecifier)); + } + + return (s); + } + } + catch + { + } + + return (s); + } + + #endregion + + #region GetDefaultPointLabelText + + private string GetDefaultPointLabelText(SeriesPoint sp, + ChartAxis axisX, ChartAxis axisY, DataLabelVisualStyle dstyle) + { + String text = string.Empty; + + if (IsBarSeries == true) + { + text = GetPointLabelText(sp.ValueY[0], axisY, string.Empty); + } + else + { + text = GetPointLabelText(sp.ValueX, axisX, string.Empty); + + if (sp.ValueY != null) + text += " : " + GetPointLabelText(sp.ValueY[0], axisY, string.Empty); + } + + return (text); + } + + #endregion + + #region GetPointLabelText + + private string GetPointLabelText( + object value, ChartAxis axis, string format) + { + switch (axis.ScaleType) + { + case ScaleType.DateTime: + if (string.IsNullOrEmpty(format) == false) + { + if (value is DateTime) + { + DateTime date = (DateTime)value; + + return (date.ToString(format)); + } + } + + return (GetDateTimeLabelText(axis, (DateTime)value)); + + case ScaleType.Qualitative: + if (string.IsNullOrEmpty(format) == false) + return (string.Format(format, value)); + + return (value.ToString()); + + default: + double d = Convert.ToDouble(value); + + if (string.IsNullOrEmpty(format) == false) + return (d.ToString(format)); + + return (d.ToString("F3")); + } + } + + #region GetDateTimeLabelText + + internal string GetDateTimeLabelText(ChartAxis axis, DateTime dt) + { + switch (axis.ActualDateTimeUnits) + { + case DateTimeUnits.Ticks: + return (dt.Ticks.ToString()); + + case DateTimeUnits.Milliseconds: + return (dt.Millisecond.ToString()); + + case DateTimeUnits.Seconds: + return (dt.Second.ToString()); + + case DateTimeUnits.Minutes: + return (dt.Minute.ToString()); + + case DateTimeUnits.Hours: + return (dt.ToShortTimeString()); + + case DateTimeUnits.Days: + return (dt.ToShortDateString()); + + case DateTimeUnits.Months: + return (dt.Year + " " + dt.Month); + + default: + return (dt.Year.ToString()); + } + } + + #endregion + + #endregion + + #endregion + + #region MeasurePointLabel + + internal Size MeasurePointLabel(Graphics g, PointLabel pl) + { + DataLabelVisualStyle dstyle = GetPointLabelVisualStyle(pl); + + int width = (dstyle.MaxTextWidth > 0) ? dstyle.MaxTextWidth : 0; + + using (StringFormat sf = new StringFormat()) + { + if (dstyle.MaxTextLineCount <= 1) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + Size size = g.MeasureString(pl.Label, dstyle.Font, width, sf).ToSize(); + size.Width++; + + if (dstyle.MaxTextLineCount > 1) + { + int lineHeight = (int)(Math.Ceiling(dstyle.Font.GetHeight())) * dstyle.MaxTextLineCount; + + if (size.Height > lineHeight) + size.Height = lineHeight; + } + + return (size); + } + } + + #region GetPointLabelVisualStyle + + internal DataLabelVisualStyle GetPointLabelVisualStyle(PointLabel pl) + { + DataLabelVisualStyle dstyle = EffectiveDataLabelStyle.Copy(); + + if (pl.DataLabelVisualStyle != null) + dstyle.ApplyStyle(pl.DataLabelVisualStyle); + else + dstyle = EffectiveDataLabelStyle; + + return (dstyle); + } + + #endregion + + #endregion + + #endregion + + #region GetRotateDegrees + + internal RotateDegrees GetRotateDegrees(DataLabelVisualStyle dstyle) + { + RotateDegrees degrees = dstyle.RotateDegrees; + + if (degrees == RotateDegrees.Auto || degrees == RotateDegrees.NotSet) + { + switch (SeriesType) + { + case SeriesType.HorizontalBar: + case SeriesType.HorizontalHiLoBar: + return (RotateDegrees.None); + + case SeriesType.VerticalBar: + case SeriesType.VerticalHiLoBar: + return (RotateDegrees.Rotate270); + + default: + return (RotateDegrees.None); + } + } + + return (dstyle.RotateDegrees); + } + + #endregion + + #region IsConvexHullPoint + + /// + /// Determines whether the given SeriesPoint is a ConvexHull point. + /// + /// + /// + public bool IsConvexHullPoint(SeriesPoint sp) + { + if (sp != null && _ConvexHullPoints != null) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + { + ConvexHullDisplayMode mode = GetConvexHullDisplayMode(chartXy); + + if (mode != ConvexHullDisplayMode.None) + { + foreach (Point ptc in _ConvexHullPoints) + { + if (ptc.Equals(sp.Point[0]) == true) + return (true); + } + } + } + } + + return (false); + } + + #endregion + + #region IsHighLightPoint + + /// + /// Determines if the given SeriesPoint is a HighLight Point (a + /// point highlighted by the Crosshair setup). + /// + /// + /// + public bool IsHighLightPoint(SeriesPoint sp) + { + if (sp != null) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + return (chartXy.IsCrosshairSeriesPoint(this, sp.Point[0])); + } + + return (false); + } + + #endregion + + #region Style handling + + #region ApplyStyles + + internal override void ApplyStyles(BaseVisualStyle style) + { + ChartSeriesVisualStyle sstyle = style as ChartSeriesVisualStyle; + + if (sstyle != null) + { + ApplyParentStyles(sstyle, Parent as ChartContainer); + + sstyle.ApplyStyle(ChartSeriesVisualStyle); + + ApplyDefaultLineStyles(sstyle.LineStyle); + ApplyDefaultLineStyles(sstyle.SplineStyle); + ApplyDefaultLineStyles(sstyle.StepLineStyle); + ApplyDefaultLineStyles(sstyle.EmptyStyle); + + ApplyDefaultMarkerStyles(sstyle.MarkerVisualStyle); + ApplyDefaultMarkerStyles(sstyle.MarkerEmptyVisualStyle); + + if (sstyle.EmptyAreaBackground.IsEmpty) + sstyle.EmptyAreaBackground = new Background(Color.FromArgb(100, Color.LightGray)); + + if (SeriesType == SeriesType.Bubble) + { + if (sstyle.MarkerVisualStyle.Background.IsEmpty) + sstyle.MarkerVisualStyle.Background = new Background(DefaultPaletteColor); + } + + ApplyDefaultBarStyles(sstyle.BarVisualStyle); + ApplyDefaultOhlcBarStyles(sstyle.HiLoBarVisualStyle); + } + else if (style is DataLabelVisualStyle) + { + DataLabelVisualStyle dstyle = (DataLabelVisualStyle)style; + + ApplyParentStyles(dstyle, Parent as ChartContainer); + + dstyle.ApplyStyle(_DataLabelVisualStyle); + + dstyle.ApplyDefaults(); + } + } + + #region ApplyParentStyles (ChartSeriesVisualStyle) + + private void ApplyParentStyles( + ChartSeriesVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is BaseChart) + pstyle.ApplyStyle(((BaseChart)item).ChartSeriesVisualStyle); + + if (item is ChartPanel) + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartSeriesVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartPanelVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartPanelVisualStyle); + } + } + + #endregion + + #region ApplyParentStyles (DataLabelVisualStyle) + + private void ApplyParentStyles( + DataLabelVisualStyle dstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(dstyle, item.Parent as ChartContainer); + + if (item is BaseChart) + dstyle.ApplyStyle(((BaseChart)item).DataLabelVisualStyle); + + if (item is ChartPanel) + dstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.DataLabelVisualStyle); + } + else + { + dstyle.ApplyStyle(ChartControl.BaseVisualStyles.DataLabelVisualStyle); + dstyle.ApplyStyle(ChartControl.DefaultVisualStyles.DataLabelVisualStyle); + } + } + + #endregion + + #region ApplyDefaultLineStyles + + private void ApplyDefaultLineStyles(ChartLineVisualStyle lstyle) + { + if (lstyle.LineColor.IsEmpty == true) + lstyle.LineColor = DefaultPaletteColor; + + lstyle.ApplyDefaults(); + } + + #endregion + + #region ApplyDefaultMarkerStyles + + private void ApplyDefaultMarkerStyles(PointMarkerVisualStyle pstyle) + { + if (pstyle.Background.IsEmpty && pstyle.BorderColor.IsEmpty) + pstyle.BorderColor = DefaultPaletteColor; + + pstyle.ApplyDefaults(); + } + + #endregion + + #region ApplyDefaultBarStyles + + private void ApplyDefaultBarStyles(ChartBarVisualStyle bstyle) + { + if (bstyle.Background.IsEmpty == true) + bstyle.Background = new Background(DefaultPaletteColor); + + ApplyDefaultLineStyles(bstyle.Border); + } + + #endregion + + #region ApplyDefaultOhlcBarStyles + + private void ApplyDefaultOhlcBarStyles(ChartHiLoBarVisualStyle bstyle) + { + HiLoBarSegmentStyle sstyle = bstyle.DefaultSegmentStyle; + + if (sstyle.Default.LineColor.IsEmpty == true) + sstyle.Default.LineColor = Color.Black; + + sstyle.Default.ApplyDefaults(); + + switch (HiLoBarType) + { + case HiLoBarType.Candle: + bool backSet = (sstyle.BoxBackground.IsEmpty == true); + + if (backSet == true) + sstyle.BoxBackground = new Background(DefaultPaletteColor); + + Background bk = sstyle.BoxBackground; + + sstyle = bstyle.AlternateSegmentStyle; + + if (sstyle.BoxBackground.IsEmpty == true) + { + if (backSet == true) + { + sstyle.BoxBackground = new Background(Color.Black, DefaultPaletteColor); + sstyle.BoxBackground.HatchFillType = HatchFillType.ForwardDiagonal; + } + else + { + if (bk.IsSolidBrush == true) + { + sstyle.BoxBackground = new Background(Color.Black, bk.Color1); + sstyle.BoxBackground.HatchFillType = HatchFillType.ForwardDiagonal; + } + else if (bk.Color1.IsEmpty == false && bk.Color2.IsEmpty == false) + { + sstyle.BoxBackground = new Background(bk.Color2, bk.Color1); + } + } + } + break; + + case Charts.HiLoBarType.Box: + if (sstyle.BoxBackground.IsEmpty == true) + sstyle.BoxBackground = new Background(DefaultPaletteColor); + break; + } + + sstyle = bstyle.DefaultSegmentStyle; + + _RenderFullDefRange = sstyle.CenterLine.IsEmpty && + sstyle.HighWhisker.IsEmpty && sstyle.LowWhisker.IsEmpty; + + sstyle = bstyle.AlternateSegmentStyle; + + _RenderFullAltRange = sstyle.CenterLine.IsEmpty && + sstyle.HighWhisker.IsEmpty && sstyle.LowWhisker.IsEmpty; + } + + private bool _RenderFullDefRange; + private bool _RenderFullAltRange; + + #endregion + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Style definition + /// + public void InvalidateStyle() + { + if (_EffectiveChartSeriesStyle.InvalidateStyle() == true) + InvalidateLayout(); + + _EffectiveDataLabelStyle.InvalidateStyle(); + + foreach (DataLabel dl in DataLabels) + dl.InvalidateStyle(); + + PointMarkerImage = null; + PointMarkerEmptyImage = null; + PointMarkerHighlightImage = null; + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + _EffectiveChartSeriesStyle.InvalidateStyle(); + _EffectiveDataLabelStyle.InvalidateStyle(); + + if (LegendItem != null) + LegendItem.EffectiveStyles.InvalidateStyles(); + + PointMarkerImage = null; + PointMarkerEmptyImage = null; + PointMarkerHighlightImage = null; + } + + #endregion + + #region StyleChanged + + protected override void StyleChanged(object sender, PropertyChangedEventArgs e) + { + base.StyleChanged(sender, e); + + if (sender is ChartLegendItemVisualStyles && LegendItem != null) + InvalidateRender(LegendItem.Bounds); + } + + #endregion + + #endregion + + #region InvalidateRender + + public override void InvalidateRender() + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + chartXy.InvalidateRender(); + } + + #endregion + + #region ILegendItem + + #region CheckedInLegend + + /// + /// Gets or sets whether the series is checked in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the series is checked in the Legend.")] + public bool CheckedInLegend + { + get { return (TestState(States.CheckedInLegend)); } + + set + { + if (value != CheckedInLegend) + { + SetState(States.CheckedInLegend, value); + + if (IsQualitativeXValues || IsQualitativeYValues) + InvalidateLayout(); + + if (PointLabelDisplayMode != PointLabelDisplayMode.None) + InvalidatePointLabels(); + + if (LegendItem != null) + LegendItem.UpdateCheckState(); + + OnPropertyChangedEx("CheckedInLegend", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowCheckBoxInLegend + + /// + /// Gets or sets whether a checkbox for the series is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether a checkbox for the series is shown in the Legend.")] + public bool ShowCheckBoxInLegend + { + get { return (TestState(States.ShowCheckBoxInLegend)); } + + set + { + if (value != ShowCheckBoxInLegend) + { + SetState(States.ShowCheckBoxInLegend, value); + + OnPropertyChangedEx("ShowCheckBoxInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInLegend + + /// + /// Gets or sets whether the series is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the series is shown in the Legend.")] + public bool ShowInLegend + { + get { return (TestState(States.ShowInLegend)); } + + set + { + if (value != ShowInLegend) + { + SetState(States.ShowInLegend, value); + + OnPropertyChangedEx("ShowInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInParentLegend + + /// + /// Gets or sets whether the series is shown in parent Legend(s). + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the series is shown in parent Legend(s).")] + public bool ShowInParentLegend + { + get { return (TestState(States.ShowInParentLegend)); } + + set + { + if (value != ShowInParentLegend) + { + SetState(States.ShowInParentLegend, value); + + OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowMarkerInLegend + + /// + /// Gets or sets whether the series Marker is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the series Marker is shown in the Legend.")] + public bool ShowMarkerInLegend + { + get { return (TestState(States.ShowMarkerInLegend)); } + + set + { + if (value != ShowMarkerInLegend) + { + SetState(States.ShowMarkerInLegend, value); + + OnPropertyChangedEx("ShowMarkerInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LegendItem + + /// + /// Gets the item's parent LegendItem. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the item's parent LegendItem.")] + public ChartLegendItem LegendItem + { + get { return (_LegendItem); } + + internal set + { + if (_LegendItem != null) + _LegendItem.Dispose(); + + _LegendItem = value; + } + } + + #endregion + + #region LegendText + + /// + /// Gets or sets the text to display in the legend. + /// + [DefaultValue(null), Category("Legend")] + [Description("Indicates the text to display in the legend.")] + public string LegendText + { + get { return (_LegendText); } + + set + { + if (value != _LegendText) + { + _LegendText = value; + + OnPropertyChangedEx("LegendText", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region GetLegendItem + + public ChartLegendItem GetLegendItem() + { + LegendItem = null; + + if (ShowInLegend == true) + { + ChartXy chartXy = Parent as ChartXy; + + LegendItem = new ChartLegendItem(); + + if (CheckedInLegend == true) + _LegendItem.CheckState = CheckState.Checked; + + _LegendItem.Parent = chartXy.Legend; + + _LegendItem.Name = Name; + _LegendItem.ItemText = LegendText; + + if (string.IsNullOrEmpty(_LegendItem.Name) == true) + _LegendItem.Name = "(Series)"; + + _LegendItem.ChartItems.Add(this); + } + + return (_LegendItem); + } + + #endregion + + #region GetLegendItems + + public List GetLegendItems() + { + List list = new List(); + + ChartLegendItem item = GetLegendItem(); + + if (item != null) + list.Add(item); + + foreach (ChartIndicator ci in ChartIndicators) + { + if (ci.Visible == true) + { + ChartLegendItem li = ci.GetLegendItem(); + + if (li != null) + list.Add(li); + } + } + + return (list); + } + + #endregion + + #region GetLegendItemColor + + public Color GetLegendItemColor() + { + ChartXy chartXy = Parent as ChartXy; + + ChartLegendItemVisualStyle lstyle = ChartLegendItemVisualStyles[StyleType.Default]; + + if (lstyle.TextColor.IsEmpty == false) + return (lstyle.TextColor); + + Color color = Color.Empty; + + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + if (sstyle.ItemColor.IsEmpty == false) + return (sstyle.ItemColor); + + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + switch (SeriesType) + { + case SeriesType.Bubble: + case SeriesType.Point: + case SeriesType.HorizontalDot: + case SeriesType.VerticalDot: + color = pstyle.Background.Color1; + break; + + case SeriesType.Line: + ChartLineDisplayMode mode = GetLineDisplayMode(chartXy); + + if ((mode & ChartLineDisplayMode.DisplayLine) == ChartLineDisplayMode.DisplayLine) + color = sstyle.LineStyle.LineColor; + + else if ((mode & ChartLineDisplayMode.DisplaySpline) == ChartLineDisplayMode.DisplaySpline) + color = sstyle.SplineStyle.LineColor; + + else if ((mode & ChartLineDisplayMode.DisplayStepLine) == ChartLineDisplayMode.DisplayStepLine) + color = sstyle.StepLineStyle.LineColor; + + if (color.IsEmpty == true) + color = pstyle.Background.Color1; + break; + + case SeriesType.HorizontalBar: + case SeriesType.VerticalBar: + ChartBarVisualStyle bstyle = sstyle.BarVisualStyle; + color = bstyle.Background.Color1; + break; + + case SeriesType.HorizontalHiLoBar: + case SeriesType.VerticalHiLoBar: + HiLoBarSegmentStyle hstyle = sstyle.HiLoBarVisualStyle.DefaultSegmentStyle; + + if (HiLoBarType == HiLoBarType.Line) + { + color = hstyle.Default.LineColor; + + if (color.IsEmpty == true) + color = hstyle.CenterLine.LineColor; + } + else + { + color = hstyle.BoxBackground.Color1; + } + break; + } + + if (color.IsEmpty == true) + color = _DefaultPaletteColor; + + return (color); + } + + #endregion + + #region RenderLegendItemMarker + + public void RenderLegendItemMarker(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + ChartXy chartXy = Parent as ChartXy; + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + Rectangle bounds = litem.MarkerBounds; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + switch (SeriesType) + { + case SeriesType.HorizontalHiLoBar: + case SeriesType.VerticalHiLoBar: + RenderHiLoBarMarker(g, bounds, chartXy, sstyle); + break; + + case SeriesType.VerticalBar: + case SeriesType.HorizontalBar: + RenderBarMarker(g, bounds, chartXy, sstyle); + break; + + case SeriesType.Bubble: + RenderBubbleMarker(g, bounds, chartXy, sstyle); + break;; + + case SeriesType.VerticalDot: + case SeriesType.HorizontalDot: + case SeriesType.Point: + RenderDotMarker(g, bounds, chartXy, sstyle); + break; + + case SeriesType.Line: + RenderLineMarker(g, bounds, chartXy, sstyle); + break; + + default: + RenderDefaultMarker(g, bounds, sstyle); + break; + } + + g.SmoothingMode = sm; + } + + #region RenderHiLoBarMarker + + private void RenderHiLoBarMarker(Graphics g, + Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + Rectangle r = bounds; + r.Inflate(-1, -1); + + if (r.Width > 0 && r.Height > 0) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + HiLoBarSegmentStyle hstyle = sstyle.HiLoBarVisualStyle.DefaultSegmentStyle; + + if (HiLoBarType == HiLoBarType.Line) + { + Color color = hstyle.Default.LineColor; + + if (color.IsEmpty == true) + color = hstyle.CenterLine.LineColor; + + if (color.IsEmpty == true) + color = _DefaultPaletteColor; + + if (color.IsEmpty == true) + color = Color.Black; + + if (IsRotated == true || r.Width > r.Height) + RenderHiLoHBarMarker(g, r, color); + else + RenderHiLoVBarMarker(g, r, color); + } + else + { + Background bk = hstyle.BoxBackground; + ChartLineVisualStyle lstyle = hstyle.BoxBorder; + + if (IsRotated == true || r.Width > r.Height) + RenderHBoxMarker(g, r, bk, hstyle, lstyle); + else + RenderVBoxMarker(g, r, bk, hstyle, lstyle); + } + + g.SmoothingMode = sm; + } + } + + #region RenderHBoxMarker + + private void RenderHBoxMarker(Graphics g, Rectangle r, + Background bk, HiLoBarSegmentStyle hstyle, ChartLineVisualStyle lstyle) + { + int n = r.Height / 4; + + Rectangle t = r; + t.Inflate(-n, -n); + + if (t.Height % 2 != 0) + { + t.Y--; + t.Height++; + } + + using (Brush br = bk.GetBrush(t)) + g.FillRectangle(br, t); + + Color lineColor = lstyle.LineColor; + + if (lineColor.IsEmpty == true) + lineColor = hstyle.Default.LineColor; + + if (lineColor.IsEmpty == true) + lineColor = Color.Black; + + using (Pen pen = new Pen(lineColor)) + { + Point pt1 = new Point(r.X, (r.Y + r.Bottom) / 2); + Point pt2 = new Point(t.X, pt1.Y); + + g.DrawLine(pen, pt1, pt2); + + pt1.X = t.Right; + pt2.X = r.Right; + + g.DrawLine(pen, pt1, pt2); + } + + using (Pen pen = new Pen(lineColor)) + g.DrawRectangle(pen, t); + } + + #endregion + + #region RenderVBoxMarker + + private void RenderVBoxMarker(Graphics g, Rectangle r, + Background bk, HiLoBarSegmentStyle hstyle, ChartLineVisualStyle lstyle) + { + int n = r.Width / 4; + + Rectangle t = r; + t.Inflate(-n, -n); + + if (t.Width % 2 != 0) + { + t.X--; + t.Width++; + } + + using (Brush br = bk.GetBrush(t)) + g.FillRectangle(br, t); + + Color lineColor = lstyle.LineColor; + + if (lineColor.IsEmpty == true) + lineColor = hstyle.Default.LineColor; + + if (lineColor.IsEmpty == true) + lineColor = Color.Black; + + using (Pen pen = new Pen(lineColor)) + { + Point pt1 = new Point((r.X + r.Right) / 2, r.Y); + Point pt2 = new Point(pt1.X, t.Y); + + g.DrawLine(pen, pt1, pt2); + + pt1.Y = t.Bottom; + pt2.Y = r.Bottom; + + g.DrawLine(pen, pt1, pt2); + } + + using (Pen pen = new Pen(lineColor)) + g.DrawRectangle(pen, t); + } + + #endregion + + #region RenderHiLoHBarMarker + + private void RenderHiLoHBarMarker(Graphics g, Rectangle r, Color color) + { + Point pt1 = new Point(r.X, (r.Y + r.Bottom) / 2); + Point pt2 = new Point(r.Right, pt1.Y); + + using (Pen pen = new Pen(color)) + { + g.DrawLine(pen, pt1, pt2); + + int n = (r.Bottom - r.Top) / 3; + + pt1.X = r.X + (r.Width / 4); + pt1.Y -= n; + + pt2.X = pt1.X; + + g.DrawLine(pen, pt1, pt2); + + pt1.X = r.X + (r.Width / 4) * 3; + pt1.Y += (2 * n); + pt2.X = pt1.X; + + g.DrawLine(pen, pt1, pt2); + } + } + + #endregion + + #region RenderHiLoVBarMarker + + private void RenderHiLoVBarMarker(Graphics g, Rectangle r, Color color) + { + Point pt1 = new Point((r.X + r.Right) / 2, r.Y); + Point pt2 = new Point(pt1.X, r.Bottom); + + using (Pen pen = new Pen(color)) + { + g.DrawLine(pen, pt1, pt2); + + int n = (r.Right - r.Left) / 3; + + pt1.X -= n; + pt1.Y = r.Y + (r.Height / 4); + pt2.Y = pt1.Y; + + g.DrawLine(pen, pt1, pt2); + + pt1.X += (2 * n); + pt1.Y = r.Y + (r.Height / 4) * 3; + pt2.Y = pt1.Y; + + g.DrawLine(pen, pt1, pt2); + } + } + + #endregion + + #endregion + + #region RenderBarMarker + + private void RenderBarMarker(Graphics g, Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + ChartLineVisualStyle cstyle = sstyle.BarVisualStyle.Border; + Background bk = sstyle.BarVisualStyle.Background; + + Rectangle r = bounds; + r.Inflate(-1, -1); + + using (Brush br = bk.GetBrush(r)) + { + g.FillRectangle(br, r); + + if (cstyle.LineColor.IsEmpty == false && cstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(cstyle.LineColor, cstyle.LineWidth)) + { + if (cstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)cstyle.LinePattern; + + g.DrawRectangle(pen, r); + } + } + } + } + + #endregion + + #region RenderBubbleMarker + + private void RenderBubbleMarker(Graphics g, + Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + Background bk = pstyle.Background; + + Rectangle r = bounds; + r.Inflate(-1, -1); + + using (Brush br = pstyle.Background.GetBrush(r)) + { + g.FillEllipse(br, r); + + if (pstyle.BorderColor.IsEmpty == false && pstyle.BorderWidth > 0) + { + using (Pen pen = new Pen(pstyle.BorderColor, pstyle.BorderWidth)) + g.DrawEllipse(pen, r); + } + } + } + + #endregion + + #region RenderDotMarker + + private void RenderDotMarker(Graphics g, + Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + Image marker = pstyle.GetPointMarkerImage(); + + if (marker != null) + { + g.DrawImage(marker, bounds); + } + else + { + marker = chartXy.GetPointMarker(g, pstyle.Type, pstyle.PointCount, + bounds.Size, pstyle.Rotation, pstyle.Background, + pstyle.BorderColor, pstyle.BorderWidth); + + if (marker != null) + { + // Make allowances for the fact that GetPointMarker() adjusts the + // size and pos of the image to allow for better anti-aliasing + + bounds.X--; + bounds.Y--; + + g.DrawImageUnscaled(marker, bounds); + } + else + { + RenderDefaultMarker(g, bounds, sstyle); + } + } + } + + #endregion + + #region RenderLineMarker + + private void RenderLineMarker(Graphics g, + Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + ChartLineDisplayMode mode = GetLineDisplayMode(chartXy); + + int n = bounds.Height / 2; + + using (Pen pen = new Pen(GetLegendItemColor())) + { + g.DrawLine(pen, + new Point(bounds.X, bounds.Y + n), + new Point(bounds.Right - 1, bounds.Y + n)); + } + + if ((mode & ChartLineDisplayMode.DisplayPoints) == ChartLineDisplayMode.DisplayPoints) + { + n = Math.Min(bounds.Height, bounds.Width); + n = (int)Math.Ceiling((double)n / 2); + + if (n % 2 == 0) + n++; + + Rectangle r = bounds; + + r.X += ((r.Width - n) / 2); + r.Y += ((r.Height - n) / 2); + + r.Width = n; + r.Height = n; + + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + Image marker2 = chartXy.GetPointMarker(g, pstyle.Type, pstyle.PointCount, + r.Size, 0, pstyle.Background, pstyle.BorderColor, pstyle.BorderWidth > 0 ? 1 : 0); + + if (marker2 != null) + { + // Make allowances for the fact that GetPointMarker() adjusts the + // size and pos of the image to allow for better anti-aliasing + + r.X--; + r.Y--; + + g.DrawImageUnscaled(marker2, r); + } + else + { + RenderDefaultMarker(g, bounds, sstyle); + } + } + } + + #endregion + + #region RenderDefaultMarker + + private void RenderDefaultMarker(Graphics g, + Rectangle bounds, ChartSeriesVisualStyle sstyle) + { + bounds.Width++; + bounds.Height++; + + Background background = sstyle.MarkerVisualStyle.Background; + + if (background.IsEmpty == true) + { + g.FillRectangle(Brushes.DimGray, bounds); + } + else + { + using (Brush br = background.GetBrush(bounds)) + g.FillRectangle(br, bounds); + } + } + + #endregion + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartSeries copy = new ChartSeries(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartSeries c = copy as ChartSeries; + + if (c != null) + { + base.CopyTo(c); + + c.AxisX = AxisX; + c.AxisY = AxisY; + + c.AreaBaseValue = AreaBaseValue; + + c.BarFillRange = BarFillRange; + c.BarLabelPosition = BarLabelPosition; + c.BarShadingEnabled = BarShadingEnabled; + c.BarWidthRatio = BarWidthRatio; + + c.BubbleIntensityMode = BubbleIntensityMode; + c.BubbleScaleFactor = BubbleScaleFactor; + c.BubbleSizeMode = BubbleSizeMode; + + foreach (ChartIndicator ci in ChartIndicators) + c.ChartIndicators.Add((ChartIndicator)ci.Copy()); + + c.ChartLegendItemVisualStyles = + (_ChartLegendItemVisualStyles != null) ? ChartLegendItemVisualStyles.Copy() : null; + + c.ChartLineAreaDisplayMode = ChartLineAreaDisplayMode; + c.ChartLineDisplayMode = ChartLineDisplayMode; + + c.ChartSeriesVisualStyle = + (_ChartSeriesVisualStyle != null) ? ChartSeriesVisualStyle.Copy() : null; + + c.ConvexHullDisplayMode = ConvexHullDisplayMode; + + c.CrosshairEnabled = CrosshairEnabled; + c.CrosshairHighlightPoints = CrosshairHighlightPoints; + c.CrosshairShowLabels = CrosshairShowLabels; + + foreach (DataLabel dl in DataLabels) + c.DataLabels.Add((DataLabel)dl.Copy()); + + c.DataLabelVisualStyle = + (_DataLabelVisualStyle != null) ? DataLabelVisualStyle.Copy() : null; + + c.DataPropertyNameSeries = DataPropertyNameSeries; + c.DataPropertyNameX = DataPropertyNameX; + c.DataPropertyNamesY = DataPropertyNamesY; + + c.DataMember = DataMember; + c.DataSource = DataSource; + + c.DefaultPaletteColor = DefaultPaletteColor; + c.DisplayLinePointsOnTop = DisplayLinePointsOnTop; + c.DotPlotIndexValue = DotPlotIndexValue; + c.EmptyValues = EmptyValues; + c.EnableEmptyValues = EnableEmptyValues; + c.GroupId = GroupId; + + c.PointLabelDisplayMode = PointLabelDisplayMode; + c.PointLabelMinDistance = PointLabelMinDistance; + c.PointLabelSkip = PointLabelSkip; + + c.ScaleTypeX = ScaleTypeX; + c.ScaleTypeY = ScaleTypeY; + + foreach (SeriesPoint sp in SeriesPoints) + c.SeriesPoints.Add(sp.Copy()); + + c.SeriesType = SeriesType; + + c.ShowEmptyLines = ShowEmptyLines; + c.ShowEmptyPoints = ShowEmptyPoints; + c.ShowHiLoBarMedianLines = ShowHiLoBarMedianLines; + c.ShowOriginValueLabels = ShowOriginValueLabels; + c.StackQualitativePoints = StackQualitativePoints; + + c.StepLines = StepLines; + c.StepLineMode = StepLineMode; + + c.CheckedInLegend = CheckedInLegend; + c.LegendText = LegendText; + c.ShowCheckBoxInLegend = ShowCheckBoxInLegend; + c.ShowInLegend = ShowInLegend; + c.ShowInParentLegend = ShowInParentLegend; + c.ShowMarkerInLegend = ShowMarkerInLegend; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartSeries"; + + sec.AddStartElement(serialName); + } + + if (AxisX != null && string.IsNullOrEmpty(AxisX.Name) == false) + sec.AddValue("AxisX", AxisX.Name); + + if (AxisY != null && string.IsNullOrEmpty(AxisY.Name) == false) + sec.AddValue("AxisY", AxisY.Name); + + sec.AddDataValue("AreaBaseValue", AreaBaseValue, null); + + sec.AddValue("BarFillRange", BarFillRange, BarFillRange.NotSet); + sec.AddValue("BarLabelPosition", BarLabelPosition, BarLabelPosition.NotSet); + sec.AddValue("BarShadingEnabled", BarShadingEnabled, Tbool.NotSet); + sec.AddValue("BarWidthRatio", BarWidthRatio, 0d); + + sec.AddValue("BubbleIntensityMode", BubbleIntensityMode, BubbleIntensityMode.NotSet); + sec.AddValue("BubbleScaleFactor", BubbleScaleFactor, 1.0d); + sec.AddValue("BubbleSizeMode", BubbleSizeMode, BubbleSizeMode.NotSet); + + if (_ChartIndicators != null && _ChartIndicators.Count > 0) + { + sec.AddStartElement("ChartIndicators count=\"" + _ChartIndicators.Count + "\""); + + foreach (ChartIndicator ci in _ChartIndicators) + sec.AddElement(ci.GetSerialData("")); + + sec.AddEndElement("ChartIndicators"); + } + + if (_ChartLegendItemVisualStyles != null) + sec.AddElement(_ChartLegendItemVisualStyles.GetSerialData("ChartLegendItemVisualStyles")); + + sec.AddValue("ChartLineAreaDisplayMode", ChartLineAreaDisplayMode, ChartLineAreaDisplayMode.NotSet); + sec.AddValue("ChartLineDisplayMode", ChartLineDisplayMode, ChartLineDisplayMode.NotSet); + + if (_ChartSeriesVisualStyle != null) + sec.AddElement(_ChartSeriesVisualStyle.GetSerialData("ChartSeriesVisualStyle")); + + sec.AddValue("ConvexHullDisplayMode", ConvexHullDisplayMode, ConvexHullDisplayMode.NotSet); + sec.AddValue("CrosshairEnabled", CrosshairEnabled, Tbool.NotSet); + sec.AddValue("CrosshairHighlightPoints", CrosshairHighlightPoints, Tbool.NotSet); + sec.AddValue("CrosshairShowLabels", CrosshairShowLabels, Tbool.NotSet); + + if (_DataLabels != null && _DataLabels.Count > 0) + { + sec.AddStartElement("DataLabels count=\"" + _DataLabels.Count + "\""); + + foreach (DataLabel dl in _DataLabels) + sec.AddElement(dl.GetSerialData("")); + + sec.AddEndElement("DataLabels"); + } + + if (_DataLabelVisualStyle != null) + sec.AddElement(_DataLabelVisualStyle.GetSerialData("DataLabelVisualStyle")); + + //sec.AddDataValue("DataSource", DataSource, null); + sec.AddValue("DataMember", DataMember, null); + + sec.AddValue("DataPropertyNameSeries", DataPropertyNameSeries, null); + sec.AddValue("DataPropertyNameX", DataPropertyNameX, null); + + if (_DataPropertyNamesY != null && _DataPropertyNamesY.Count > 0) + { + sec.AddStartElement("DataPropertyNamesYs count=\"" + _DataPropertyNamesY.Count + "\""); + + foreach (string s in _DataPropertyNamesY) + sec.AddValue("DataPropertyNamesY", s); + + sec.AddEndElement("DataPropertyNamesYs"); + } + + sec.AddValue("DefaultPaletteColor", DefaultPaletteColor, Color.Empty); + sec.AddValue("DisplayLinePointsOnTop", DisplayLinePointsOnTop, true); + sec.AddValue("DotPlotIndexValue", DotPlotIndexValue, 1.0d); + + if (_EmptyValues != null && _EmptyValues.Length > 0) + { + sec.AddStartElement("EmptyValues count=\"" + _EmptyValues.Length + "\""); + + foreach (object value in _EmptyValues) + sec.AddValue("EmptyValue", value); + + sec.AddEndElement("EmptyValues"); + } + + sec.AddValue("EnableEmptyValues", EnableEmptyValues, false); + sec.AddValue("GroupId", GroupId, 0); + sec.AddValue("HiLoBarType", HiLoBarType, HiLoBarType.Box); + sec.AddValue("PointLabelDisplayMode", PointLabelDisplayMode, PointLabelDisplayMode.NotSet); + sec.AddValue("PointLabelMinDistance", PointLabelMinDistance, 0); + sec.AddValue("PointLabelSkip", PointLabelSkip, 0); + sec.AddValue("ScaleTypeX", ScaleTypeX, ScaleType.NotSet); + sec.AddValue("ScaleTypeY", ScaleTypeY, ScaleType.NotSet); + + if (_SeriesPoints != null && _SeriesPoints.Count > 0) + { + sec.AddStartElement("SeriesPoints count=\"" + _SeriesPoints.Count + "\""); + + foreach (SeriesPoint sp in _SeriesPoints) + sec.AddElement(sp.GetSerialData()); + + sec.AddEndElement("SeriesPoints"); + } + + sec.AddValue("SeriesType", SeriesType, SeriesType.Point); + + sec.AddValue("ShowEmptyLines", ShowEmptyLines, false); + sec.AddValue("ShowEmptyPoints", ShowEmptyPoints, false); + sec.AddValue("ShowHiLoBarMedianLines", ShowHiLoBarMedianLines, false); + sec.AddValue("ShowOriginValueLabels", ShowOriginValueLabels, true); + + sec.AddValue("StackQualitativePoints", StackQualitativePoints, true); + + sec.AddValue("StepLines", StepLines, StepLines.NotSet); + sec.AddValue("StepLineMode", StepLineMode, StepLineMode.NotSet); + + sec.AddValue("CheckedInLegend", CheckedInLegend, true); + sec.AddValue("LegendText", LegendText, null); + sec.AddValue("ShowCheckBoxInLegend", ShowCheckBoxInLegend, true); + sec.AddValue("ShowInLegend", ShowInLegend, true); + sec.AddValue("ShowInParentLegend", ShowInParentLegend, true); + sec.AddValue("ShowMarkerInLegend", ShowMarkerInLegend, true); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + ChartXy chartXy = Parent as ChartXy; + + switch (se.Name) + { + case "AreaBaseValue": + AreaBaseValue = se.DataValue; + break; + + case "AxisX": + if (chartXy != null) + AxisX = GetAncillaryAxis(chartXy.AncillaryAxesX, se.GetValueString()); + break; + + case "AxisY": + if (chartXy != null) + AxisY = GetAncillaryAxis(chartXy.AncillaryAxesY, se.GetValueString()); + break; + + case "BarFillRange": + BarFillRange = (BarFillRange)se.GetValueEnum(typeof(BarFillRange)); + break; + + case "BarLabelPosition": + BarLabelPosition = (BarLabelPosition)se.GetValueEnum(typeof(BarLabelPosition)); + break; + + case "BarShadingEnabled": + BarShadingEnabled = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "BarWidthRatio": + BarWidthRatio = double.Parse(se.StringValue); + break; + + case "BubbleIntensityMode": + BubbleIntensityMode = (BubbleIntensityMode)se.GetValueEnum(typeof(BubbleIntensityMode)); + break; + + case "BubbleScaleFactor": + BubbleScaleFactor = double.Parse(se.StringValue); + break; + + case "BubbleSizeMode": + BubbleSizeMode = (BubbleSizeMode)se.GetValueEnum(typeof(BubbleSizeMode)); + break; + + case "ChartLineAreaDisplayMode": + ChartLineAreaDisplayMode = (ChartLineAreaDisplayMode)se.GetValueEnum(typeof(ChartLineAreaDisplayMode)); + break; + + case "ChartLineDisplayMode": + ChartLineDisplayMode = (ChartLineDisplayMode)se.GetValueEnum(typeof(ChartLineDisplayMode)); + break; + + case "CheckedInLegend": + CheckedInLegend = bool.Parse(se.StringValue); + break; + + case "ConvexHullDisplayMode": + ConvexHullDisplayMode = (ConvexHullDisplayMode)se.GetValueEnum(typeof(ConvexHullDisplayMode)); + break; + + case "CrosshairEnabled": + CrosshairEnabled = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "CrosshairHighlightPoints": + CrosshairHighlightPoints = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "CrosshairShowLabels": + CrosshairShowLabels = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "DataMember": + DataMember = se.StringValue; + break; + + case "DataPropertyNameSeries": + DataPropertyNameSeries = se.StringValue; + break; + + case "DataPropertyNameX": + DataPropertyNameX = se.StringValue; + break; + + case "DataPropertyNamesY": + DataPropertyNamesY.Add(se.StringValue); + break; + + case "DataSource": + DataSource = se.DataValue; + break; + + case "DefaultPaletteColor": + DefaultPaletteColor = se.GetValueColor(); + break; + + case "DisplayLinePointsOnTop": + DisplayLinePointsOnTop = bool.Parse(se.StringValue); + break; + + case "DotPlotIndexValue": + DotPlotIndexValue = double.Parse(se.StringValue); + break; + + case "EmptyValues": + EmptyValues[se.ValueIndex] = se.DataValue; + break; + + case "EnableEmptyValues": + EnableEmptyValues = bool.Parse(se.StringValue); + break; + + case "GroupId": + GroupId = int.Parse(se.StringValue); + break; + + case "HiLoBarType": + HiLoBarType = (HiLoBarType)se.GetValueEnum(typeof(HiLoBarType)); + break; + + case "LegendText": + LegendText = se.StringValue; + break; + + case "PointLabelDisplayMode": + PointLabelDisplayMode = (PointLabelDisplayMode)se.GetValueEnum(typeof(PointLabelDisplayMode)); + break; + + case "PointLabelMinDistance": + PointLabelMinDistance = int.Parse(se.StringValue); + break; + + case "PointLabelSkip": + PointLabelSkip = int.Parse(se.StringValue); + break; + + case "ScaleTypeX": + ScaleTypeX = (ScaleType)se.GetValueEnum(typeof(ScaleType)); + break; + + case "ScaleTypeY": + ScaleTypeY = (ScaleType)se.GetValueEnum(typeof(ScaleType)); + break; + + case "SeriesType": + SeriesType = (SeriesType)se.GetValueEnum(typeof(SeriesType)); + break; + + case "ShowCheckBoxInLegend": + ShowCheckBoxInLegend = bool.Parse(se.StringValue); + break; + + case "ShowEmptyLines": + ShowEmptyLines = bool.Parse(se.StringValue); + break; + + case "ShowEmptyPoints": + ShowEmptyPoints = bool.Parse(se.StringValue); + break; + + case "ShowHiLoBarMedianLines": + ShowHiLoBarMedianLines = bool.Parse(se.StringValue); + break; + + case "ShowInLegend": + ShowInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInParentLegend": + ShowInParentLegend = bool.Parse(se.StringValue); + break; + + case "ShowMarkerInLegend": + ShowMarkerInLegend = bool.Parse(se.StringValue); + break; + + case "ShowOriginValueLabels": + ShowOriginValueLabels = bool.Parse(se.StringValue); + break; + + case "StackQualitativePoints": + StackQualitativePoints = bool.Parse(se.StringValue); + break; + + case "StepLines": + StepLines = (StepLines)se.GetValueEnum(typeof(StepLines)); + break; + + case "StepLineMode": + StepLineMode = (StepLineMode)se.GetValueEnum(typeof(StepLineMode)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #region GetAncillaryAxis + + private ChartAxis GetAncillaryAxis(ChartAxesCollection axes, string name) + { + foreach (ChartAxis axis in axes) + { + if (name.Equals(axis.Name) == true) + return (axis); + } + + return (null); + } + + #endregion + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartIndicators": + sec.PutSerialData(this); + break; + + case "ChartLegendItemVisualStyles": + sec.PutSerialData(ChartLegendItemVisualStyles); + break; + + case "ChartSeriesVisualStyle": + sec.PutSerialData(ChartSeriesVisualStyle); + break; + + case "DataLabel": + sec.PutSerialData(DataLabels[se.ValueIndex]); + break; + + case "DataLabels": + sec.PutSerialData(this); + break; + + case "DataLabelVisualStyle": + sec.PutSerialData(DataLabelVisualStyle); + break; + + case "DataPropertyNamesYs": + if (se.ArrayCount > 0) + { + DataPropertyNamesY = new CustomCollection(se.ArrayCount); + + sec.PutSerialData(this); + } + break; + + case "EmptyValues": + if (se.ArrayCount > 0) + { + EmptyValues = new object[se.ArrayCount]; + + sec.PutSerialData(this); + } + break; + + case "RegressionLine": + string rname = se.Sec.GetItemValue("Name"); + + RegressionLine reg = ChartIndicators[rname] as RegressionLine; + + if (reg != null) + ChartIndicators.Remove(reg); + + reg = new RegressionLine(rname); + + if (reg != null) + { + sec.PutSerialData(reg); + + ChartIndicators.Add(reg); + } + break; + + case "SeriesPoints": + if (se.ArrayCount > 0) + { + SeriesPoints = new SeriesPointCollection(); + + sec.PutSerialData(this); + } + break; + + case "SeriesPoint": + SeriesPoint sp = new SeriesPoint(); + + sec.PutSerialData(sp); + + SeriesPoints.Add(sp); + break; + + case "TrendLine": + string tname = se.Sec.GetItemValue("Name"); + + TrendLine trend = ChartIndicators[tname] as TrendLine; + + if (trend != null) + ChartIndicators.Remove(trend); + + trend = new TrendLine(tname); + + if (trend != null) + { + sec.PutSerialData(trend); + + ChartIndicators.Add(trend); + } + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region Series States + + [Flags] + private enum States : uint + { + FilterIgnoreMatchCase = (1U << 0), + + CheckedInLegend = (1U << 1), + ShowInLegend = (1U << 2), + ShowInParentLegend = (1U << 3), + ShowCheckBoxInLegend = (1U << 4), + ShowMarkerInLegend = (1U << 5), + + IsSorted = (1U << 6), + IsRotated = (1U << 7), + + StackQualitativePoints = (1U << 8), + DisplayLinePointsOnTop = (1U << 9), + + EnableEmptyValues = (1U << 10), + ShowEmptyLines = (1U << 11), + ShowEmptyPoints = (1U << 12), + ShowOriginValueLabels = (1U << 13), + ShowHiLoBarMedianLines = (1U << 14), + + NeedToUpdateBindings = (1U << 15), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + AxisX = null; + AxisY = null; + ChartIndicators = null; + ChartLegendItemVisualStyles = null; + ChartSeriesVisualStyle = null; + DataLabels = null; + DataLabelVisualStyle = null; + SeriesPoints = null; + + base.Dispose(); + } + + #endregion + } + + #region SortedSeriesPoints + + public class SortedSeriesPoints + { + #region Private variables + + private ChartSeries _ChartSeries; + private SeriesPointCollection _Spc; + + private int[] _IndexArray; + private int[] _CountArray; + + private int _SeriesLayoutCount; + + private int _FirstDisplayIndex = -1; + private int _LastDisplayIndex = -1; + + private double _Slope = double.NaN; + private double _Intercept = double.NaN; + + private bool _SlopeCalculated; + private int _SlopeIndex; + + #endregion + + public SortedSeriesPoints(ChartSeries series, bool sortPoints) + { + _ChartSeries = series; + _Spc = series.SeriesPoints; + + if (sortPoints == true) + _IndexArray = CreateIndexArray(_Spc); + } + + #region Public properties + + #region Count + + public int Count + { + get + { + if (_IndexArray != null) + return (_IndexArray.Length); + + return (_Spc.Count); + } + } + + #endregion + + #region Indexer[int] + + public SeriesPoint this[int index] + { + get + { + if (_IndexArray != null) + index = _IndexArray[index]; + + return (_Spc[index]); + } + } + + #endregion + + #region IsSorted + + public bool IsSorted + { + get { return (_ChartSeries.IsSorted); } + } + + #endregion + + #region SeriesLayoutCount + + public int SeriesLayoutCount + { + get { return (_SeriesLayoutCount); } + + set + { + if (value != _SeriesLayoutCount) + { + _SeriesLayoutCount = value; + + _FirstDisplayIndex = -1; + _LastDisplayIndex = -1; + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region CountArray + + internal int[] CountArray + { + get { return (_CountArray); } + set { _CountArray = value; } + } + + #endregion + + #region IndexArray + + internal int[] IndexArray + { + get { return (_IndexArray); } + set { _IndexArray = value; } + } + + #endregion + + #region Intercept + + internal double Intercept + { + get + { + if (_SlopeCalculated == false) + CalcSeriesSlope(); + + return (_Intercept); + } + + set { _Intercept = value; } + } + + #endregion + + #region Slope + + internal double Slope + { + get + { + if (_SlopeCalculated == false) + CalcSeriesSlope(); + + return (_Slope); + } + + set { _Slope = value; } + } + + #endregion + + #region SlopeIndex + + internal int SlopeIndex + { + get { return (_SlopeIndex); } + + set + { + if (_SlopeIndex != value) + { + _SlopeIndex = value; + _SlopeCalculated = false; + } + } + } + + #endregion + + #endregion + + #region CreateIndexArray + + private int[] CreateIndexArray(SeriesPointCollection spc) + { + int[] indexArray = new int[_Spc.Count]; + object[] keyArray = new object[_Spc.Count]; + + for (int i = 0; i < _Spc.Count; i++) + { + indexArray[i] = i; + keyArray[i] = _Spc[i].ValueX; + } + + Array.Sort(keyArray, indexArray); + + return (indexArray); + } + + #endregion + + #region SearchX + + public int SearchX(object okey) + { + ChartXy chartXy = _ChartSeries.Parent as ChartXy; + + if (IsSorted == true) + { + int min = 0; + int max = Count - 1; + + while (min <= max) + { + int mid = (min + max) / 2; + + int cmp = chartXy.DataCompare(okey, this[mid].ValueX); + + if (cmp > 0) + min = mid + 1; + + else if (cmp < 0) + max = mid - 1; + + else + return (mid); + } + + return (-((min > 0) ? min - 1 : 0)); + } + else + { + for (int i = 0; i < Count; i++) + { + if (chartXy.DataCompare(okey, this[i].ValueX) == 0) + return (i); + } + + return (-1); + } + } + + #endregion + + #region SearchY + + public int SearchY(object okey) + { + ChartXy chartXy = _ChartSeries.Parent as ChartXy; + + for (int i = 0; i < _Spc.Count; i++) + { + if (_Spc[i].ValueY[0].Equals(okey)) + return (i); + } + + return (0); + } + + #endregion + + #region GetQualitativeXIndex + + internal int GetQualitativeXIndex(object okey) + { + int index; + + if (okey is string) + index = _ChartSeries.QualitativeXValues.IndexOf((string)okey); + else + index = Convert.ToInt32(okey); + + return (index); + } + + #endregion + + #region GetQualitativeYIndex + + internal int GetQualitativeYIndex(object okey) + { + int index; + + if (okey is string) + index = _ChartSeries.QualitativeYValues.IndexOf((string)okey); + else + index = Convert.ToInt32(okey); + + return (index); + } + + #endregion + + #region CalcSeriesSlope + + private void CalcSeriesSlope() + { + ChartXy chartXy = _ChartSeries.Parent as ChartXy; + + if (chartXy != null) + { + ChartAxis axisX = _ChartSeries.AxisX ?? chartXy.AxisX; + ChartAxis axisY = _ChartSeries.AxisY ?? chartXy.AxisY; + + if (_ChartSeries.ActualScaleTypeX != ScaleType.NotSet) + { + int n = Count; + + double sumX = 0; + double sumY = 0; + double sumXx = 0; + double sumXy = 0; + + int nn = 0; + + for (int i = 0; i < n; i++) + { + SeriesPoint sp = this[i]; + + if (sp.IsEmpty == false && (sp.ValueY.Length > _SlopeIndex)) + { + nn++; + + double x; + + switch (_ChartSeries.ActualScaleTypeX) + { + case ScaleType.DateTime: + x = chartXy.GetDateTimePointValue(axisX, + axisX.TickmarkLayout, (DateTime)sp.ValueX, (DateTime)_ChartSeries.MinValueX); + break; + + case ScaleType.Qualitative: + x = _ChartSeries.QualitativeXValues.IndexOf(sp.ValueX); + break; + + default: + x = Convert.ToDouble(sp.ValueX); + break; + } + + double y; + + switch (_ChartSeries.ActualScaleTypeY) + { + case ScaleType.DateTime: + y = chartXy.GetDateTimePointValue(axisY, axisY.TickmarkLayout, (DateTime)sp.ValueY[_SlopeIndex]); + break; + + case ScaleType.Qualitative: + y = _ChartSeries.QualitativeYValues.IndexOf(sp.ValueY[_SlopeIndex]); + break; + + default: + y = Convert.ToDouble(sp.ValueY[_SlopeIndex]); + break; + } + + sumX += x; + sumY += y; + + sumXx += (x * x); + sumXy += (x * y); + } + } + + double a = nn * sumXy; + double b = sumX * sumY; + double c = nn * sumXx; + double d = sumX * sumX; + + double m = (a - b) / (c - d); + double yi = (sumY - (m * sumX)) / nn; + + Slope = m; + Intercept = yi; + + _SlopeCalculated = true; + } + } + } + + #endregion + + #region GetSeriesPoint + + internal SeriesPoint GetSeriesPoint(object key) + { + if (Count > 0) + { + int index; + + if (this[0].IsQuantitativeXValue == true) + index = SearchX(key); + else + index = GetQualitativeXIndex(key) - 1; + + if (index < 0 && IsSorted == true) + index = -index; + + if ((uint)index < Count) + return (this[index]); + } + + return (null); + } + + #endregion + } + + #endregion + + #region PointData + + public class PointData + { + public List Points; + public List SeriesPoints; + } + + #endregion + + #region BubblePlotData + + internal class BubblePlotData + { + public double MinSize; + public double MaxSize; + + public double TotalSize; + + public double MinIntensity; + public double MaxIntensity; + + public void Clear() + { + MinSize = double.MaxValue; + MaxSize = double.MinValue; + + MinIntensity = double.MaxValue; + MaxIntensity = double.MinValue; + + TotalSize = 0; + } + } + + #endregion + + #region BarRenderData + + internal class BarRenderData + { + public ChartAxis Axis; + public ChartXy ChartXy; + + public BarFillRange FillRange; + public bool BarShading; + + public Point Spt; + public SeriesPoint Sp; + + public ChartSeriesVisualStyle SeriesStyle; + + public BarRenderData(ChartXy chartXy, ChartAxis axis) + { + ChartXy = chartXy; + Axis = axis; + } + } + + #endregion + + #region HiLoRenderData + + public class HiLoRenderData + { + #region Private variables + + private ChartAxis _Axis; + private ChartXy _ChartXy; + + private Point _Spt; + private SeriesPoint _Sp; + private int _Index; + + private ChartSeriesVisualStyle _SeriesStyle; + + private int[] _Value; + + private bool _IsAlternate; + private int _EndDelta; + + #endregion + + public HiLoRenderData(ChartXy chartXy, ChartAxis axis) + { + _ChartXy = chartXy; + _Axis = axis; + } + + #region Public properties + + #region AlternateStyle + + /// + /// Gets the alternate segment style used when Open/Close values are reversed. + /// + public HiLoBarSegmentStyle AlternateStyle + { + get { return (SeriesStyle.HiLoBarVisualStyle.AlternateSegmentStyle); } + } + + #endregion + + #region DefaultStyle + + /// + /// Gets the default segment style used when Open/Close values are not reversed. + /// + public HiLoBarSegmentStyle DefaultStyle + { + get { return (SeriesStyle.HiLoBarVisualStyle.DefaultSegmentStyle); } + } + + #endregion + + #region IsAlternate + + /// + /// Gets whether the segment is to be render as 'Alternate'. + /// + public bool IsAlternate + { + get { return (_IsAlternate); } + internal set { _IsAlternate = value; } + } + + #endregion + + #region SeriesStyle + + /// + /// Gets the associated series visual style. + /// + public ChartSeriesVisualStyle SeriesStyle + { + get { return (_SeriesStyle); } + internal set { _SeriesStyle = value; } + } + + #endregion + + #region Value + + /// + /// Gets an array of specified HiLo coordinate data values (x or y, + /// depending upon the bar orientation). The values are specified + /// in [High=0, Low=1, Close=2, Open=3, Median=4] order, followed + /// by any 'extra' user supplied bar values. + /// + public int[] Value + { + get { return (_Value); } + internal set { _Value = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region Axis + + internal ChartAxis Axis + { + get { return (_Axis); } + set { _Axis = value; } + } + + #endregion + + #region ChartXy + + internal ChartXy ChartXy + { + get { return (_ChartXy); } + set { _ChartXy = value; } + } + + #endregion + + #region EndDelta + + public int EndDelta + { + get { return (_EndDelta); } + set { _EndDelta = value; } + } + + #endregion + + #region Index + + internal int Index + { + get { return (_Index); } + set { _Index = value; } + } + + #endregion + + #region Sp + + internal SeriesPoint Sp + { + get { return (_Sp); } + set { _Sp = value; } + } + + #endregion + + #region Spt + + internal Point Spt + { + get { return (_Spt); } + set { _Spt = value; } + } + + #endregion + + #endregion + } + + #endregion + + #region AMath (approximate math) + + internal class AMath + { + public static double ToScalar(double x) + { + return (AMath.Sqrt((float)(x / Math.PI)) * 2); + } + + public static float Sqrt(float x) + { + if (x != 0) + { + FloatIntUnion u; + + u.tmp = 0; + u.f = x; + + u.tmp -= 1 << 23; // Subtract 2^m + u.tmp >>= 1; // Divide by 2 + u.tmp += 1 << 29; // Add ((b + 1) / 2) * 2^m + + return (u.f); + } + + return (0); + } + + [StructLayout(LayoutKind.Explicit)] + private struct FloatIntUnion + { + [FieldOffset(0)] + public float f; + + [FieldOffset(0)] + public int tmp; + } + } + + #endregion + + #region enums + + #region BarLabelPosition + + /// + /// Specifies the position for Bar series labels. + /// + public enum BarLabelPosition + { + /// + /// Not set (default is Center). + /// + NotSet = -1, + + /// + /// Labels will be positioned in the center of the bar. + /// + Center, + + /// + /// Labels will be positioned outside the bar, relative to its origin. + /// + Near, + + /// + /// Labels will be positioned inside the bar, relative to its origin. + /// + NearInside, + + /// + /// Labels will be positioned outside the bar, opposite to its origin. + /// + Far, + + /// + /// Labels will be positioned inside the bar, opposite to its origin. + /// + FarInside, + } + + #endregion + + #region BarSegment + + public enum BarSegment + { + /// + /// Top portion of Vertical bar (full area). + /// + Top, + + /// + /// Partial Top area of Vertical bar. + /// + TopPartial, + + /// + /// Bottom portion of Vertical bar (full area). + /// + Bottom, + + /// + /// Partial Bottom area of Vertical bar. + /// + BottomPartial, + + /// + /// Left portion of Horizontal bar (full area). + /// + Left, + + /// + /// Partial Left area of Horizontal bar. + /// + LeftPartial, + + /// + /// Right portion of Horizontal bar (full area). + /// + Right, + + /// + /// Partial Right area of Horizontal bar. + /// + RightPartial, + } + + #endregion + + #region SeriesType + + /// + /// Defines available Series types + /// + public enum SeriesType + { + Bubble, + + HorizontalBar, + VerticalBar, + + Line, + Point, + + HorizontalDot, // Wilkinson dotplot + VerticalDot, + + HorizontalHiLoBar, // Box, Candle, HiLo + VerticalHiLoBar, + + //Bullet, + + //Pie, + //Polar, + //Radar, + + //TreeMap, + } + + #endregion + + #region ConvexHullDisplayMode + + /// + /// Specifies the ConvexHull display mode + /// + [Flags] + public enum ConvexHullDisplayMode + { + /// + /// Not set (default is None). + /// + NotSet = 0, + + /// + /// No Convex Hull processing will take place. + /// + None = (1 << 0), + + /// + /// Convex Hull border will be displayed. + /// + DisplayBorder = (1 << 1), + + /// + /// Convex Hull background area will be displayed. + /// + DisplayBackground = (1 << 2), + } + + #endregion + + #region PointLabelDisplayMode + + /// + /// Specifies which PointLabels are to be displayed + /// + [Flags] + public enum PointLabelDisplayMode + { + /// + /// Not set (default is None). + /// + NotSet, + + /// + /// No labels will be displayed. + /// + None = (1 << 0), + + /// + /// All series points will display a label. + /// + AllSeriesPoints = (1 << 1), + + /// + /// User defined DataLabels will be displayed. + /// + DataLabels = (1 << 2), + + /// + /// Minimum 'X' Value label will be displayed. + /// + MinValueX = (1 << 3), + + /// + /// Minimum 'Y' Value label will be displayed. + /// + MinValueY = (1 << 4), + + /// + /// Maximum 'X' Value label will be displayed. + /// + MaxValueX = (1 << 5), + + /// + /// Maximum 'Y' Value label will be displayed. + /// + MaxValueY = (1 << 6), + + } + + #endregion + + #region StepLineMode + + /// + /// Specifies the mode used to render "Step Lines" in + /// a given Line series. + /// + public enum StepLineMode + { + /// + /// Not set (default is HorizontalThenVertical). + /// + NotSet = -1, + + /// + /// No Step Lines will be rendered. + /// + None, + + /// + /// Step lines will be displayed between consecutive + /// series points, by first displaying the horizontal step + /// line, followed by the connecting vertical step line. + /// + HorizontalThenVertical, + + /// + /// Step lines will be displayed between consecutive + /// series points, by first displaying the vertical step + /// line, followed by the connecting horizontal step line. + /// + VerticalThenHorizontal, + + /// + /// Step lines will be displayed between consecutive + /// series points, by first displaying the midPoint horizontal + /// step line, followed by the connecting vertical step line. + /// + MidPoint, + } + + #endregion + + #region StepLines + + /// + /// Specifies the mode used to render "Stepped Lines" in + /// a given Line series. + /// + public enum StepLines + { + /// + /// Not set (default is StepHv). + /// + NotSet = -1, + + /// + /// No step lines will be displayed. + /// + None, + + /// + /// Horizontal step lines will be displayed. + /// + Horizontal, + + /// + /// Vertical step lines will be displayed. + /// + Vertical, + + /// + /// Both horizontal and vertical step lines will be displayed. + /// + Both, + } + + #endregion + + #region ScaleType + + /// + /// Specifies the scale type for the series points + /// + public enum ScaleType + { + /// + /// ScaleType is NotSet (default is 'Auto'). + /// + NotSet, + + /// + /// ScaleType is Automatic. Scale type will be determined + /// by the underlying, assigned data. + /// + Auto, + + /// + /// DateTime data scale. Points will be treated as + /// DateTime values and will be shown as such on the axis. + /// + DateTime, + + /// + /// Numerical data scale. Points will be treated as + /// numerical values and will be shown on the axis as numbers. + /// + Quantitative, + + /// + /// Qualitative data scale. Points will be treated as + /// qualitative values and will be shown on the axis as text. + /// + Qualitative, + + } + + #endregion + + #region HiLoBarType + + /// + /// Specifies the HiloBar series display type. + /// + public enum HiLoBarType + { + /// + /// Box Plot display. Display is identical to 'Candle' except: + /// 1. Median separated segments are separately rendered using both + /// default and alternate box backgrounds. + /// 2. UseAlternateSegmentStyle defaults to false. + /// + Box, + + /// + /// Candle Plot display. Display is identical to 'Box' except: + /// 1. Mmedian separated segments are both rendered using either + /// the default or alternate box background. + /// 2. UseAlternateSegmentStyle defaults to true. + /// + Candle, + + /// + /// Line plot display. + /// + Line, + } + + #endregion + + #region HiLoBarSegment + + public enum HiLoBarSegment + { + /// + /// Box (Box plot). + /// + Box, + + /// + /// High whisker (Box, Candle, Line). + /// + HighWhisker, + + /// + /// High whisker cap (Box, Candle, Line). + /// + HighWhiskerCap, + + /// + /// Low whisker (Box, Candle, Line). + /// + LowWhisker, + + /// + /// Low whisker cap (Box, Candle, Line). + /// + LowWhiskerCap, + + /// + /// Open whisker (Line plot). + /// + OpenWhisker, + + /// + /// Close whisker (Line Plot). + /// + CloseWhisker, + + /// + /// Center line (Line plot). + /// + CenterLine, + + /// + /// Full range (Line plot). + /// + FullRange, + + /// + /// Median line (Box, Candle, Line). + /// + MedianLine, + + /// + /// Bar shading (Box, Candle). + /// + BarShading, + } + + #endregion + + #endregion + + #region AxisTypeConverter + + /// + /// AxisTypeConverter + /// + public class AxisTypeConverter : TypeConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + ChartAxis axis = value as ChartAxis; + + if (axis != null) + { + if (string.IsNullOrEmpty(axis.Name) == false) + return (axis.Name); + + return ("No Axis Name"); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartTitle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartTitle.cs new file mode 100644 index 00000000..be80b45f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/ChartTitle.cs @@ -0,0 +1,1206 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using DevComponents.Charts.TextMarkup; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of ChartTitles. + /// + [Editor("DevComponents.Charts.Design.ChartTitleCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartTitleCollection : CustomNamedCollection + { + public ChartTitleCollection() + { + } + + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("Title")); + } + + #endregion + } + + /// + /// ChartTitle + /// + public class ChartTitle : ChartNote + { + #region Private variables + + private States _States; + private XyAlignment _XyAlignment = XyAlignment.NotSet; + private RotateDegrees _RotateDegrees = RotateDegrees.NotSet; + + private ChartTitleVisualStyle _ChartTitleVisualStyle; + private EffectiveStyle _EffectiveTitleStyle; + + private Rectangle _FrameBounds; + private Rectangle _ContentBounds; + private int _TextHeight; + + #endregion + + #region Constructors + + /// + /// Creates a new ChartTitle + /// + public ChartTitle() + : this(null, null) + { + } + + /// + /// Creates a new ChartTitle + /// + /// Title name + public ChartTitle(string name) + : this(name, null) + { + } + + /// + /// Creates a new ChartTitle + /// + /// Title Name + /// Title Text + public ChartTitle(string name, string text) + { + InitDefaultStates(); + + Name = name; + Text = text; + + _EffectiveTitleStyle = new EffectiveStyle(this); + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + } + + #endregion + + #region Public properties + + #region ChartTitleVisualStyle + + /// + /// Gets or sets the visual style for the Title. + /// + [Category("Style")] + [Description("Indicates the visual style for the Title.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartTitleVisualStyle ChartTitleVisualStyle + { + get + { + if (_ChartTitleVisualStyle == null) + { + _ChartTitleVisualStyle = new ChartTitleVisualStyle(); + + StyleVisualChangeHandler(null, _ChartTitleVisualStyle); + } + + return (_ChartTitleVisualStyle); + } + + set + { + if (_ChartTitleVisualStyle != value) + { + ChartTitleVisualStyle oldValue = _ChartTitleVisualStyle; + + _ChartTitleVisualStyle = value; + + OnStyleChanged("ChartTitleVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region EffectiveTitleStyle + + /// + /// Gets a reference to the title's effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartTitleVisualStyle EffectiveTitleStyle + { + get { return (_EffectiveTitleStyle.Style); } + } + + #endregion + + #region RotateDegrees + + /// + /// Gets or sets the title's display rotation. + /// + [DefaultValue(RotateDegrees.NotSet), Category("Layout")] + [Description("Indicates the title's display rotation.")] + public RotateDegrees RotateDegrees + { + get { return (_RotateDegrees); } + + set + { + if (value != _RotateDegrees) + { + _RotateDegrees = value; + + OnPropertyChangedEx("RotateDegrees", VisualChangeType.Layout); + } + } + } + + #endregion + + #region XyAlignment + + /// + /// Gets or sets the X/Y Alignment for the title. + /// + [DefaultValue(XyAlignment.NotSet), Category("Layout")] + [Description("Indicates the X/Y Alignment for the title.")] + public XyAlignment XyAlignment + { + get { return (_XyAlignment); } + + set + { + if (value != _XyAlignment) + { + _XyAlignment = value; + + OnPropertyChangedEx("XyAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + Graphics g = layoutInfo.Graphics; + ChartTitleVisualStyle style = EffectiveTitleStyle; + + Size size = Size.Empty; + Rectangle layoutBounds = layoutInfo.LayoutBounds; + + RotateDegrees rotDegrees = GetRotateDegrees(style); + + if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270) + layoutBounds.Size = new Size(layoutBounds.Height, layoutBounds.Width); + + Thickness brdThickness = style.BorderThickness; + Size ncSize = GetNonContentSize(style, brdThickness); + + layoutBounds.Width -= ncSize.Width; + layoutBounds.Height -= ncSize.Height; + + Alignment imageAlignment = style.ImageAlignment; + Size imageSize = style.GetFigureSize(g); + + if (layoutBounds.Width > 0 && layoutBounds.Height > 0) + { + if (imageSize.IsEmpty == false) + { + if (style.IsOverlayImage == true) + imageAlignment = Alignment.MiddleCenter; + + else if (imageAlignment == Alignment.NotSet) + imageAlignment = Alignment.MiddleLeft; + + switch (imageAlignment) + { + case Alignment.TopLeft: + case Alignment.TopRight: + case Alignment.BottomLeft: + case Alignment.BottomRight: + case Alignment.MiddleLeft: + case Alignment.MiddleRight: + if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270) + layoutBounds.Height -= imageSize.Width; + else + layoutBounds.Width -= imageSize.Width; + break; + + case Alignment.TopCenter: + case Alignment.BottomCenter: + layoutBounds.Height -= imageSize.Height; + break; + } + + if (layoutBounds.Size.Width > 0 && layoutBounds.Size.Height > 0) + size = MeasureText(g, style, layoutBounds.Size); + + switch (imageAlignment) + { + case Alignment.TopLeft: + case Alignment.TopRight: + case Alignment.MiddleLeft: + case Alignment.MiddleRight: + case Alignment.BottomLeft: + case Alignment.BottomRight: + size.Width += imageSize.Width; + size.Height = Math.Max(imageSize.Height, size.Height); + break; + + case Alignment.TopCenter: + case Alignment.BottomCenter: + size.Height += imageSize.Height; + size.Width = Math.Max(imageSize.Width, size.Width); + break; + + case Alignment.MiddleCenter: + size.Height = Math.Max(imageSize.Height, size.Height); + size.Width = Math.Max(imageSize.Width, size.Width); + break; + } + } + else + { + size = MeasureText(g, style, layoutBounds.Size); + } + + size.Width += ncSize.Width; + size.Height += ncSize.Height; + } + + if (FixedHeight > 0) + size.Height = Dpi.Height(FixedHeight); + + Rectangle bounds = layoutBounds; + + if (style.Stretch == Tbool.True) + { + switch (XyAlignment) + { + case XyAlignment.Left: + case XyAlignment.Right: + if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270) + size.Width = layoutInfo.LayoutBounds.Height; + break; + + default: + if (rotDegrees != RotateDegrees.Rotate90 && rotDegrees != RotateDegrees.Rotate270) + size.Width = layoutInfo.LayoutBounds.Width; + break; + } + } + + Rectangle rb = bounds; + + if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270) + bounds.Size = new Size(size.Height, size.Width); + else + bounds.Size = size; + + if (bounds.Width > layoutInfo.LayoutBounds.Width) + bounds.Width = layoutInfo.LayoutBounds.Width; + + if (bounds.Height > layoutInfo.LayoutBounds.Height) + bounds.Height = layoutInfo.LayoutBounds.Height; + + Size = bounds.Size; + + bounds = AlignTitle(layoutInfo, bounds, style); + + _FrameBounds = GetAdjustedBoundsRot(bounds, style.Margin); + + if (style.DropShadow.Enabled == Tbool.True) + { + _FrameBounds.Width -= 3; + _FrameBounds.Height -= 3; + } + + _ContentBounds = _FrameBounds; + + if (brdThickness.IsEmpty == false) + { + _ContentBounds.X += brdThickness.Left; + _ContentBounds.Width -= brdThickness.Horizontal; + + _ContentBounds.Y += brdThickness.Top; + _ContentBounds.Height -= brdThickness.Vertical; + } + + if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270) + _ContentBounds = GetAdjustedBoundsRot(_ContentBounds, style.Padding); + else + _ContentBounds = GetAdjustedBounds(_ContentBounds, style.Padding); + + if (imageSize.IsEmpty == false) + { + if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270) + AdjustVerticalContent(rotDegrees, imageAlignment, imageSize); + else + AdjustHorizontalContent(imageAlignment, imageSize); + } + + BoundsRelative = bounds; + } + + #region GetAdjustedBoundsRot + + internal Rectangle GetAdjustedBoundsRot(Rectangle bounds, Thickness thickness) + { + if (thickness.IsEmpty == false) + { + if (bounds.Width > Dpi.Height(thickness.Vertical)) + { + bounds.X += Dpi.Height(thickness.Top); + bounds.Width -= Dpi.Height(thickness.Vertical); + } + + if (bounds.Height > Dpi.Width(thickness.Horizontal)) + { + bounds.Y += Dpi.Width(thickness.Left); + bounds.Height -= Dpi.Width(thickness.Horizontal); + } + } + + return (bounds); + } + + #endregion + + #region GetNonContentSize + + private Size GetNonContentSize(ChartTitleVisualStyle style, Thickness brdThickness) + { + Size size = Size.Empty; + + size.Width = Dpi.Width(style.Margin.Horizontal + brdThickness.Horizontal + style.Padding.Horizontal); + size.Height = Dpi.Height(style.Margin.Vertical + brdThickness.Vertical + style.Padding.Vertical); + + if (style.DropShadow.Enabled == Tbool.True) + { + size.Width += 3; + size.Height += 3; + } + + return (size); + } + + #endregion + + #region AdjustVerticalContent + + private void AdjustVerticalContent( + RotateDegrees rotDegrees, Alignment imageAlignment, Size imageSize) + { + switch (imageAlignment) + { + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + if (rotDegrees == RotateDegrees.Rotate90) + _ContentBounds.Y += imageSize.Width; + + else if (rotDegrees == RotateDegrees.Rotate270) + _ContentBounds.Y += imageSize.Width; + else + _ContentBounds.X += imageSize.Height; + + _ContentBounds.Height -= imageSize.Width; + break; + + case Alignment.TopCenter: + if (rotDegrees == RotateDegrees.Rotate90) + _ContentBounds.X += imageSize.Height; + + else if (rotDegrees == RotateDegrees.Rotate270) + _ContentBounds.X += imageSize.Height; + else + _ContentBounds.Y += imageSize.Width; + + _ContentBounds.Width -= imageSize.Height; + break; + + case Alignment.BottomCenter: + _ContentBounds.Width -= imageSize.Height; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + _ContentBounds.Height -= imageSize.Width; + break; + } + } + + #endregion + + #region AdjustHorizontalContent + + private void AdjustHorizontalContent( + Alignment imageAlignment, Size imageSize) + { + switch (imageAlignment) + { + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + _ContentBounds.X += imageSize.Width; + _ContentBounds.Width -= imageSize.Width; + break; + + case Alignment.TopCenter: + _ContentBounds.Y += imageSize.Height; + _ContentBounds.Height -= imageSize.Height; + break; + + case Alignment.BottomCenter: + _ContentBounds.Height -= imageSize.Height; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + _ContentBounds.Width -= imageSize.Width; + break; + } + } + + #endregion + + #region MeasureText + + private Size MeasureText(Graphics g, ChartTitleVisualStyle style, Size vsize) + { + Size size = Size.Empty; + + string s = Text; + + if (string.IsNullOrEmpty(s) == false) + { + if (TextMarkup != null) + { + size = GetMarkupTextSize(g, + TextMarkup, style, (vsize.Width > 0 ? vsize.Width : 10000)); + } + else + { + using (StringFormat sf = new StringFormat()) + { + style.GetStringFormatFlags(sf); + + if (style.MaxLineCount <= 1) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + size = g.MeasureString(Text, style.Font, vsize, sf).ToSize(); + } + } + + size.Width++; + size.Height++; + + if (style.MaxLineCount > 1) + { + int lineHeight = (int)(Math.Ceiling(style.Font.GetHeight())) * style.MaxLineCount; + + if (size.Height > lineHeight) + size.Height = lineHeight; + } + } + + _TextHeight = size.Height; + + return (size); + } + + #region GetMarkupTextSize + + private Size GetMarkupTextSize(Graphics g, + BodyElement textMarkup, ChartTitleVisualStyle style, int width) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + textMarkup.InvalidateElementsSize(); + textMarkup.Measure(new Size(width, 0), d); + + return (textMarkup.Bounds.Size); + } + + #endregion + + #endregion + + #region AlignTitle + + private Rectangle AlignTitle( + ChartLayoutInfo layoutInfo, Rectangle bounds, ChartTitleVisualStyle style) + { + Rectangle layoutBounds = layoutInfo.LayoutBounds; + + switch (XyAlignment) + { + case XyAlignment.Left: + layoutInfo.LayoutBounds.X += Size.Width; + layoutInfo.LayoutBounds.Width -= Size.Width; + break; + + case XyAlignment.Bottom: + bounds.Y = layoutBounds.Bottom - Size.Height; + layoutInfo.LayoutBounds.Height -= Size.Height; + break; + + case XyAlignment.Right: + bounds.X = layoutBounds.Right - Size.Width; + layoutInfo.LayoutBounds.Width -= Size.Width; + break; + + default: + layoutInfo.LayoutBounds.Y += Size.Height; + layoutInfo.LayoutBounds.Height -= Size.Height; + break; + } + + if (XyAlignment == XyAlignment.Left || XyAlignment == XyAlignment.Right) + { + if (bounds.Height < layoutBounds.Height) + { + switch (style.Alignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + bounds.Y += (layoutBounds.Height - bounds.Height) / 2; + break; + + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + bounds.Y = layoutBounds.Bottom - bounds.Height; + break; + } + } + } + else + { + if (bounds.Width < layoutBounds.Width) + { + switch (style.Alignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + bounds.X += (layoutBounds.Width - bounds.Width) / 2; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + bounds.X = layoutBounds.Right - bounds.Width; + break; + } + } + } + + return (bounds); + } + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + Rectangle scFrameBounds = GetScrollBounds(_FrameBounds); + Rectangle scContentBounds = GetScrollBounds(_ContentBounds); + + if (scFrameBounds.Height > 0 && scFrameBounds.Width > 0) + { + ChartTitleVisualStyle tstyle = EffectiveTitleStyle; + + Rectangle rfb = scFrameBounds; + Rectangle rcb = scContentBounds; + + RotateDegrees rotDegrees = GetRotateDegrees(tstyle); + + if (rotDegrees != RotateDegrees.None) + { + TransformBounds(g, scFrameBounds, rotDegrees); + + rfb = TranslateFrameBounds(scFrameBounds, rotDegrees); + rcb = TranslateContentBounds(scFrameBounds, scContentBounds, rotDegrees); + } + + RenderBackground(g, rfb, tstyle); + RenderTextAndFigure(g, rfb, rcb, rotDegrees, tstyle); + + if (rotDegrees != RotateDegrees.None) + g.ResetTransform(); + + tstyle.RenderBorder(g, scFrameBounds); + + if (tstyle.DropShadow.Enabled == Tbool.True) + tstyle.DropShadow.RenderDropShadow(g, scFrameBounds, true, true); + } + } + + #region TransformBounds + + private void TransformBounds(Graphics g, Rectangle rfb, RotateDegrees rotDegrees) + { + switch (rotDegrees) + { + case RotateDegrees.Rotate90: + g.TranslateTransform(rfb.Right, rfb.Y); + g.RotateTransform(90); + break; + + case RotateDegrees.Rotate180: + g.TranslateTransform(rfb.Right, rfb.Bottom); + g.RotateTransform(-180); + break; + + case RotateDegrees.Rotate270: + g.TranslateTransform(rfb.X, rfb.Bottom); + g.RotateTransform(-90); + break; + } + } + + #endregion + + #region TranslateFrameBounds + + private Rectangle TranslateFrameBounds(Rectangle rfb, RotateDegrees rotDegrees) + { + Rectangle tfb = new Rectangle(0, 0, rfb.Width, rfb.Height); + + switch (rotDegrees) + { + case RotateDegrees.Rotate90: + case RotateDegrees.Rotate270: + tfb.Width = rfb.Height; + tfb.Height = rfb.Width; + break; + } + + return (tfb); + } + + #endregion + + #region TranslateContentBounds + + private Rectangle TranslateContentBounds(Rectangle rfb, Rectangle rcb, RotateDegrees rotDegrees) + { + Rectangle tcb = new Rectangle(rcb.X - rfb.X, rcb.Y - rfb.Y, rcb.Width, rcb.Height); + + switch (rotDegrees) + { + case RotateDegrees.Rotate90: + int X = tcb.X; + tcb.X = tcb.Y; + tcb.Y = X; + + tcb.Width = rcb.Height; + tcb.Height = rcb.Width; + break; + + case RotateDegrees.Rotate270: + int X1 = tcb.X; + tcb.X = tcb.Y; + tcb.Y = X1; + + tcb.Width = rcb.Height; + tcb.Height = rcb.Width; + break; + } + + return (tcb); + } + + #endregion + + #region CalcImageBounds + + private Rectangle CalcImageBounds( + Rectangle rfb, RotateDegrees rotDegrees, ChartTitleVisualStyle style) + { + if (style.BorderThickness.IsEmpty == false) + { + switch (rotDegrees) + { + case RotateDegrees.Rotate90: + rfb.X += Dpi.Height(style.BorderThickness.Top); + rfb.Width -= Dpi.Height(style.BorderThickness.Vertical); + + rfb.Y += Dpi.Width(style.BorderThickness.Right); + rfb.Height -= Dpi.Width(style.BorderThickness.Horizontal); + break; + + case RotateDegrees.Rotate270: + rfb.X += Dpi.Height(style.BorderThickness.Bottom); + rfb.Width -= Dpi.Height(style.BorderThickness.Vertical); + + rfb.Y += Dpi.Width(style.BorderThickness.Left); + rfb.Height -= Dpi.Width(style.BorderThickness.Horizontal); + break; + + case RotateDegrees.Rotate180: + rfb.X += Dpi.Width(style.BorderThickness.Right); + rfb.Width -= Dpi.Width(style.BorderThickness.Horizontal); + + rfb.Y += Dpi.Height(style.BorderThickness.Bottom); + rfb.Height -= Dpi.Height(style.BorderThickness.Vertical); + break; + + default: + rfb.X += Dpi.Width(style.BorderThickness.Left); + rfb.Width -= Dpi.Width(style.BorderThickness.Horizontal); + + rfb.Y += Dpi.Height(style.BorderThickness.Top); + rfb.Height -= Dpi.Height(style.BorderThickness.Vertical); + break; + } + } + + return (rfb); + } + + #endregion + + #region RenderBackground + + private void RenderBackground( + Graphics g, Rectangle r, ChartTitleVisualStyle style) + { + if (r.Width > 2 && r.Height > 2) + { + using (Brush br = style.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region RenderTextAndFigure + + private void RenderTextAndFigure(Graphics g, Rectangle rfb, + Rectangle rcb, RotateDegrees rotDegrees, ChartTitleVisualStyle tstyle) + { + Rectangle rib = Rectangle.Empty; + + object figure = tstyle.GetFigure(); + + if (figure != null) + { + rib = CalcImageBounds(rfb, rotDegrees, tstyle); + + if (tstyle.ImageOverlay != ImageOverlay.Top) + RenderFigure(g, figure, rib, tstyle); + } + + RenderText(g, rcb, tstyle); + + if (figure != null) + { + if (tstyle.ImageOverlay == ImageOverlay.Top) + RenderFigure(g, figure, rib, tstyle); + } + } + + #region RenderFigure + + private void RenderFigure(Graphics g, + object figure, Rectangle r, ChartTitleVisualStyle tstyle) + { + Rectangle t = tstyle.GetFigureBounds(g, r); + + t.Intersect(r); + + if (t.Width > 0 && t.Height > 0) + { + SymbolDef sd = figure as SymbolDef; + + if (sd != null && sd.IsValidSymbol == true) + { + using (Brush br = new SolidBrush(sd.SymbolColor)) + g.DrawString(sd.SymbolRealized, sd.SymbolFont, br, t); + } + else + { + Image image = figure as Image; + + if (image != null) + g.DrawImage(image, t); + } + } + } + + #endregion + + #region RenderText + + private void RenderText( + Graphics g, Rectangle r, ChartTitleVisualStyle style) + { + if (r.Width > 0 && r.Height > 0) + { + string s = Text; + + if (string.IsNullOrEmpty(s) == false) + { + if (TextMarkup != null) + { + RenderTextMarkup(g, r, style); + } + else + { + using (SolidBrush br = new SolidBrush(style.TextColor)) + { + using (StringFormat sf = new StringFormat()) + { + style.GetStringFormatFlags(sf); + + if (style.MaxLineCount <= 1) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + if (r.Height > _TextHeight) + { + if (sf.LineAlignment == StringAlignment.Center) + { + r.Y += (r.Height - _TextHeight) / 2; + r.Height = _TextHeight; + } + } + + g.DrawString(Text, style.Font, br, r, sf); + } + } + } + } + } + } + + #region RenderTextMarkup + + private void RenderTextMarkup( + Graphics g, Rectangle r, ChartTitleVisualStyle style) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + TextMarkup.Arrange(r, d); + + Size size = TextMarkup.Bounds.Size; + + switch (style.Alignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + if (r.Height > size.Height) + r.Y += (r.Height - size.Height) / 2; + break; + + default: + if (r.Height > size.Height) + r.Y = r.Bottom - size.Height; + break; + } + + TextMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + TextMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetRotateDegrees + + private RotateDegrees GetRotateDegrees(ChartTitleVisualStyle style) + { + switch (RotateDegrees) + { + case RotateDegrees.Auto: + case RotateDegrees.NotSet: + + switch (XyAlignment) + { + case XyAlignment.Left: + return (RotateDegrees.Rotate270); + + case XyAlignment.Right: + return (RotateDegrees.Rotate90); + + default: + return (RotateDegrees.None); + } + } + + return (RotateDegrees); + } + + #endregion + + #region Style Support + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + ChartTitleVisualStyle tstyle = style as ChartTitleVisualStyle; + + if (tstyle != null) + { + ApplyParentStyles(tstyle, Parent as ChartContainer); + + tstyle.ApplyStyle(ChartTitleVisualStyle); + + tstyle.ApplyDefaults(); + } + } + + #endregion + + #region ApplyParentStyles + + private void ApplyParentStyles(ChartTitleVisualStyle tstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(tstyle, item.Parent as ChartContainer); + + if (item is ChartPanel) + tstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartTitleVisualStyle); + } + else + { + tstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartTitleVisualStyle); + tstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartTitleVisualStyle); + } + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Styles + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + _EffectiveTitleStyle.InvalidateStyle(); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartTitle copy = new ChartTitle(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartTitle c = copy as ChartTitle; + + if (c != null) + { + base.CopyTo(c); + + c.ChartTitleVisualStyle = + (_ChartTitleVisualStyle != null) ? ChartTitleVisualStyle.Copy() : null; + + c.RotateDegrees = RotateDegrees; + c.XyAlignment = XyAlignment; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartTitle"; + + sec.AddStartElement(serialName); + } + + if (_ChartTitleVisualStyle != null && _ChartTitleVisualStyle.IsEmpty == false) + sec.AddElement(_ChartTitleVisualStyle.GetSerialData("ChartTitleVisualStyle")); + + sec.AddValue("RotateDegrees", RotateDegrees, RotateDegrees.NotSet); + sec.AddValue("XyAlignment", XyAlignment, XyAlignment.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "RotateDegrees": + RotateDegrees = (RotateDegrees)se.GetValueEnum(typeof(RotateDegrees)); + break; + + case "XyAlignment": + XyAlignment = (XyAlignment)se.GetValueEnum(typeof(XyAlignment)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartTitleVisualStyle": + sec.PutSerialData(ChartTitleVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + ChartTitleVisualStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/DataBinder.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/DataBinder.cs new file mode 100644 index 00000000..b95a0f94 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/DataBinder.cs @@ -0,0 +1,1126 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// DataBinding helper class + /// + public class DataBinder : IDisposable + { + #region Private variables + + private readonly ChartControl _ChartControl; + private readonly BaseChart _Chart; + private readonly BaseSeries _Series; + + private CurrencyManager _CurrencyManager; + private PropertyDescriptorCollection _Pdc; + private DataView _DataView; + + private BindingSource _BindingSource; + private BindingSource _BaseBindingSource; + private object _BaseDataSource; + private string _BaseDataMember; + + private bool _NotificationAutogen; + private bool _NotificationInProgress; + + private int _SeriesCount; + + #endregion + + /// + /// DataBinding + /// + /// + internal DataBinder(BaseChart chart) + { + _Chart = chart; + _ChartControl = chart.ChartControl; + } + + internal DataBinder(BaseSeries series) + { + _Series = series; + + _Chart = series.Parent as BaseChart; + _ChartControl = _Chart.ChartControl; + } + + #region Internal properties + + #region BaseDataMember + + internal string BaseDataMember + { + get { return (_BaseDataMember); } + set { _BaseDataMember = value; } + } + + #endregion + + #region BaseDataSource + + internal object BaseDataSource + { + get { return (_BaseDataSource); } + set { _BaseDataSource = value; } + } + + #endregion + + #region CurrencyManager + + internal CurrencyManager CurrencyManager + { + get { return (_CurrencyManager); } + + set + { + if (_CurrencyManager != value) + { + if (_CurrencyManager != null) + _CurrencyManager.ListChanged -= CurrencyManagerListChanged; + + _CurrencyManager = value; + _BaseBindingSource = null; + + if (_CurrencyManager != null) + { + _Pdc = CurrencyManager.GetItemProperties(); + _BaseBindingSource = _BaseDataSource as BindingSource; + + _CurrencyManager.ListChanged += CurrencyManagerListChanged; + } + else + { + _Pdc = null; + } + } + } + } + + #endregion + + #region DataView + + internal DataView DataView + { + get { return (_DataView); } + set { _DataView = value; } + } + + #endregion + + #region GetValue + + internal object GetValue(int index, string name) + { + if (CurrencyManager != null && _Pdc != null) + { + if ((uint)index < CurrencyManager.List.Count) + { + object dataItem = CurrencyManager.List[index]; + + PropertyDescriptorCollection pdc = GetPdc(dataItem); + PropertyDescriptor pd = FindPropertyDescriptor(pdc, name); + + if (pd != null) + return (pd.GetValue(dataItem)); + } + } + + return (null); + } + + #endregion + + #region Pdc + + internal PropertyDescriptorCollection Pdc + { + get { return (_Pdc); } + set { _Pdc = value; } + } + + #endregion + + #region RowCount + + internal int RowCount + { + get + { + if (CurrencyManager != null) + return (CurrencyManager.Count); + + return (0); + } + } + + #endregion + + #endregion + + #region Clear + + internal void Clear() + { + CurrencyManager = null; + } + + #endregion + + #region DataConnect + + internal object DataConnect(object dataSource, string dataMember) + { + _BaseDataSource = dataSource; + _BaseDataMember = dataMember; + + if (_BaseDataSource != null) + { + _BindingSource = _BaseDataSource as BindingSource; + + if (_BindingSource != null) + { + BindingSource bs = _BindingSource.DataSource as BindingSource; + + if (bs != null) + { + if (string.IsNullOrEmpty(_BindingSource.DataMember) == false) + _BaseDataMember = _BindingSource.DataMember; + else + _BindingSource = null; + + while (bs.DataSource is BindingSource) + bs = (BindingSource)bs.DataSource; + + DataSet dss = bs.DataSource as DataSet; + + if (dss != null) + { + DataRelation dsr = dss.Relations[_BaseDataMember]; + + if (dsr != null) + { + _BaseDataSource = dss; + _BaseDataMember = dsr.ChildTable.TableName; + } + } + } + else + { + _BaseDataSource = _BindingSource.DataSource; + _BaseDataMember = _BindingSource.DataMember; + } + } + + DataView = null; + + if (_BaseDataSource is DataSet) + return (AddDataSetTable((DataSet)_BaseDataSource, _BaseDataMember)); + + if (_BaseDataSource is DataTable) + return (AddDataTable((DataTable)_BaseDataSource)); + + if (_BaseDataSource is IListSource) + return (AddList(((IListSource)_BaseDataSource).GetList())); + + return (AddList(_BaseDataSource)); + } + + return (null); + } + + #endregion + + #region AddList + + internal object AddList(object source) + { + bool autogen = _Chart.AutoGenSeriesCollection; + + if (_ChartControl.DoDataBindingStartEvent(_Chart, source, ref autogen) == false) + return (AddList(source, autogen)); + + return (null); + } + + internal object AddList(object source, bool autogen) + { + if (_Series == null) + { + if (SetDataConnection(source, autogen) == true) + ProcessAddList(source, autogen); + } + else + { + SetDataConnection(source, false); + } + + return (source); + } + + #region ProcessAddList + + private void ProcessAddList(object source, bool autogen) + { + if (_Pdc != null) + { + if (autogen == true && _ChartControl.DesignerHosted == false) + AutoGenerateListSeries(source); + + foreach (ChartSeries series in _Chart.BaseSeries) + series.NeedToUpdateBindings = true; + } + } + + #region AutoGenerateListSeries + + private void AutoGenerateListSeries(object source) + { + string nameSeries = _Chart.DataPropertyNameSeries; + + string nameX = GetListNameX(nameSeries); + CustomCollection namesY = GetListNamesY(nameSeries, nameX); + + if (string.IsNullOrEmpty(nameSeries) == true) + AutoGenListSeriesSingle(nameX, namesY); + else + AutoGenListSeriesMultiple(source, nameSeries, nameX, namesY); + } + + #region AutoGenListSeriesSingle + + private void AutoGenListSeriesSingle( + string nameX, CustomCollection namesY) + { + BaseSeries series = _Chart.GetNewSeries(); + + series.DataPropertyNameX = nameX; + series.DataPropertyNamesY = namesY; + + SetAutoSeriesId(series); + + _Chart.AddChartSeries(series); + } + + #endregion + + #region AutoGenListSeriesMultiple + + private void AutoGenListSeriesMultiple(object source, + string nameSeries, string nameX, CustomCollection namesY) + { + PropertyDescriptor pdSeries = FindListPd(nameSeries); + + if (pdSeries == null) + throw new Exception("List series name not found (" + nameSeries + ")"); + + object lastSeriesKey = null; + + IList list = source as IList; + + if (list != null) + { + for (int i = 0; i < list.Count; i++) + { + object o = list[i]; + + if (o != null) + { + object seriesKey = pdSeries.GetValue(o); + + if ((lastSeriesKey != null) && (seriesKey != lastSeriesKey)) + AddAutoGenSeries(lastSeriesKey, nameSeries, nameX, namesY); + + lastSeriesKey = seriesKey; + } + } + + if (lastSeriesKey != null) + AddAutoGenSeries(lastSeriesKey, nameSeries, nameX, namesY); + } + } + + #endregion + + #region GetListNameX + + private string GetListNameX(string nameSeries) + { + string nameX = _Chart.DataPropertyNameX; + + if (string.IsNullOrEmpty(nameX) == false) + { + if (FindListPd(nameX) == null) + throw new Exception("Cannot find List Property (" + nameX + ")"); + + return (nameX); + } + + bool emptyNameSeries = string.IsNullOrEmpty(nameSeries); + + foreach (PropertyDescriptor pd in _Pdc) + { + if (IsAccessibleItem(pd) == true) + { + if (emptyNameSeries == true || emptyNameSeries.Equals(pd.Name) == false) + return (pd.Name); + } + } + + throw new Exception("Cannot determine auto-assigned DataPropertyNameX."); + } + + #endregion + + #region GetListNamesY + + private CustomCollection + GetListNamesY(string nameSeries, string nameX) + { + CustomCollection namesY = _Chart.DataPropertyNamesY; + + if (namesY == null) + namesY = new CustomCollection(); + + if (namesY.Count == 0) + { + int countY = _Chart.GetAutoGenSeriesNameCount(); + + foreach (PropertyDescriptor pd in _Pdc) + { + if (IsAccessibleItem(pd) == true) + { + if ((nameSeries == null || nameSeries.Equals(pd.Name) == false) + && nameX.Equals(pd.Name) == false) + { + namesY.Add(pd.Name); + + if (--countY == 0) + return (namesY); + } + } + } + + throw new Exception("Cannot determine auto-assigned DataPropertyNamesY."); + } + + return (namesY); + } + + #endregion + + #region FindListPd + + private PropertyDescriptor FindListPd(string nameX) + { + foreach (PropertyDescriptor pd in _Pdc) + { + if (IsAccessibleItem(pd) == true) + { + if (pd.Name.Equals(nameX) == true) + return (pd); + } + } + + return (null); + } + + #endregion + + #region IsAccessibleItem + + private bool IsAccessibleItem(PropertyDescriptor pd) + { + if (pd.PropertyType.IsInterface == false) + { + if (IsNestedList(pd.PropertyType.Name) == false && IsVisibleItem(pd) == true) + return (true); + } + + return (false); + } + + #region IsNestedList + + private bool IsNestedList(string name) + { + return (name.Equals("List`1") || name.Equals("BindingList`1")); + } + + #endregion + + #region IsVisibleItem + + private bool IsVisibleItem(PropertyDescriptor pd) + { + foreach (Attribute attr in pd.Attributes) + { + IsVisibleToChartControl dattr = attr as IsVisibleToChartControl; + + if (dattr != null) + return (dattr.Visible); + } + + return (true); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region AddDataSetTable + + internal object AddDataSetTable(DataSet dataSet, string dataMember) + { + if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0) + dataMember = dataSet.Tables[0].TableName; + + if (string.IsNullOrEmpty(dataMember) == false) + return (AddDataTable(dataSet.Tables[dataMember])); + + return (null); + } + + #endregion + + #region AddDataTable + + internal object AddDataTable(DataTable dt) + { + if (_Series == null) + { + bool autogen = _Chart.AutoGenSeriesCollection; + + if (_ChartControl.DoDataBindingStartEvent(_Chart, dt, ref autogen) == false) + { + if (SetDataConnection(dt, autogen) == true) + { + if (CurrencyManager != null) + ProcessAddDataTable(dt, autogen); + } + } + } + else + { + SetDataConnection(dt, false); + } + + return (dt); + } + + #region ProcessAddDataTable + + private void ProcessAddDataTable(DataTable dt, bool autogen) + { + if (autogen == true && _ChartControl.DesignerHosted == false) + AutoGenerateDataTableSeries(dt); + + dt.DefaultView.RowFilter = ""; + + DataView = dt.DefaultView; + + ChartBaseSeriesCollection baseSeries = _Chart.BaseSeries; + + foreach (BaseSeries series in baseSeries) + series.NeedToUpdateBindings = true; + } + + #region AutoGenerateDataTableSeries + + private void AutoGenerateDataTableSeries(DataTable dt) + { + string nameSeries = _Chart.DataPropertyNameSeries; + + string nameX = GetDataTableNameX(dt, nameSeries); + CustomCollection namesY = GetDataTableNamesY(dt, nameSeries, nameX); + + if (string.IsNullOrEmpty(nameSeries) == true) + AutoGenDataTableSeriesSingle(dt, nameX, namesY); + else + AutoGenDataTableSeriesMultiple(dt, nameSeries, nameX, namesY); + } + + #region AutoGenDataTableSeriesSingle + + private void AutoGenDataTableSeriesSingle( + DataTable dt, string nameX, CustomCollection namesY) + { + BaseSeries series = _Chart.GetNewSeries(); + + series.DataPropertyNameX = nameX; + series.DataPropertyNamesY = namesY; + + SetAutoSeriesId(series); + + _Chart.AddChartSeries(series); + } + + #endregion + + #region AutoGenDataTableSeriesMultiple + + private void AutoGenDataTableSeriesMultiple(DataTable dt, + string nameSeries, string nameX, CustomCollection namesY) + { + DataColumn dtSeries = FindDataColumn(dt, nameSeries); + + if (dtSeries == null) + throw new Exception("DataTable series name not found (" + nameSeries + ")"); + + object lastSeriesKey = null; + + for (int i = 0; i < CurrencyManager.Count; i++) + { + DataRowView view = CurrencyManager.List[i] as DataRowView; + + if (view != null) + { + object seriesKey = view.Row.ItemArray[dtSeries.Ordinal]; + + if ((lastSeriesKey != null) && (seriesKey != lastSeriesKey)) + AddAutoGenSeries(lastSeriesKey, nameSeries, nameX, namesY); + + lastSeriesKey = seriesKey; + } + } + + if (lastSeriesKey != null) + AddAutoGenSeries(lastSeriesKey, nameSeries, nameX, namesY); + } + + #region AddAutoGenSeries + + private void AddAutoGenSeries(object seriesKey, + string nameSeries, string nameX, CustomCollection namesY) + { + string name = seriesKey.ToString(); + + if (FindChartSeries(name) == null) + { + BaseSeries series = _Chart.GetNewSeries(); + + series.SeriesId = ++_SeriesCount; + series.Name = name; + + series.SeriesKey = seriesKey; + + series.DataPropertyNameSeries = nameSeries; + series.DataPropertyNameX = nameX; + series.DataPropertyNamesY = namesY; + + _Chart.AddChartSeries(series); + } + } + + #endregion + + #endregion + + #region GetDataTableNameX + + private string GetDataTableNameX(DataTable dt, string nameSeries) + { + string nameX = _Chart.DataPropertyNameX; + + if (string.IsNullOrEmpty(nameX) == false) + { + if (FindDataColumn(dt, nameX) == null) + throw new Exception("Cannot find DataColumn (" + nameX + ")"); + + return (nameX); + } + + bool emptyNameSeries = string.IsNullOrEmpty(nameSeries); + + foreach (DataColumn dtColumn in dt.Columns) + { + if ((dtColumn.ColumnMapping & MappingType.Hidden) != MappingType.Hidden) + { + if (emptyNameSeries == true || emptyNameSeries.Equals(dtColumn.ColumnName) == false) + return (dtColumn.ColumnName); + } + } + + throw new Exception("Cannot determine auto-assigned DataPropertyNameX."); + } + + #endregion + + #region GetDataTableNamesY + + private CustomCollection + GetDataTableNamesY(DataTable dt, string nameSeries, string nameX) + { + CustomCollection namesY = _Chart.DataPropertyNamesY; + + if (namesY == null) + namesY = new CustomCollection(); + + if (namesY.Count == 0) + { + int countY = _Chart.GetAutoGenSeriesNameCount(); + + foreach (DataColumn dtColumn in dt.Columns) + { + if ((dtColumn.ColumnMapping & MappingType.Hidden) != MappingType.Hidden) + { + if ((nameSeries == null || nameSeries.Equals(dtColumn.ColumnName) == false) + && nameX.Equals(dtColumn.ColumnName) == false) + { + namesY.Add(dtColumn.ColumnName); + + if (--countY == 0) + return (namesY); + } + } + } + + throw new Exception("Cannot determine auto-assigned DataPropertyNamesY."); + } + + return (namesY); + } + + #endregion + + #endregion + + #region FindDataColumn + + private DataColumn FindDataColumn(DataTable dt, string name) + { + if (string.IsNullOrEmpty(name) == false) + { + foreach (DataColumn dtColumn in dt.Columns) + { + if ((dtColumn.ColumnMapping & MappingType.Hidden) != MappingType.Hidden) + { + if (dtColumn.ColumnName.Equals(name) == true) + return (dtColumn); + } + } + } + + return (null); + } + + #endregion + + #endregion + + #endregion + + #region SetAutoSeriesId + + private void SetAutoSeriesId(BaseSeries series) + { + series.SeriesId = ++_SeriesCount; + + series.Name = GetUniqueSeriesName(series); + } + + #region GetUniqueSeriesName + + private string GetUniqueSeriesName(BaseSeries series) + { + string name = "Series" + series.SeriesId; + + while (FindChartSeries(name) != null) + name += "*"; + + return (name); + } + + #endregion + + #endregion + + #region SetDataConnection + + private bool SetDataConnection(object dataSource, bool autogen) + { + ClearDataNotification(dataSource); + + if (_BindingSource != null || _ChartControl.BindingContext != null) + SetDataNotification(dataSource, autogen); + + return (_NotificationInProgress == false); + } + + #endregion + + #region SetDataNotification + + private void SetDataNotification(object dataSource, bool autogen) + { + ISupportInitializeNotification notification = + dataSource as ISupportInitializeNotification; + + if (notification == null || notification.IsInitialized == true) + { + CurrencyManager = (_BindingSource != null) + ? _BindingSource.CurrencyManager + : _ChartControl.BindingContext[DataView ?? dataSource] as CurrencyManager; + } + else + { + CurrencyManager = null; + + if (_NotificationInProgress == false) + { + _NotificationInProgress = true; + _NotificationAutogen = autogen; + + notification.Initialized += DataSourceInitialized; + } + } + } + + #endregion + + #region ClearDataNotification + + private void ClearDataNotification(object dataSource) + { + ISupportInitializeNotification notification = + dataSource as ISupportInitializeNotification; + + if (notification != null && _NotificationInProgress == true) + { + notification.Initialized -= DataSourceInitialized; + + _NotificationInProgress = false; + _NotificationAutogen = false; + } + } + + #endregion + + #region DataSourceInitialized + + private void DataSourceInitialized(object sender, EventArgs e) + { + ISupportInitializeNotification dataSource = + _Chart.DataSource as ISupportInitializeNotification; + + if (dataSource != null) + { + _NotificationInProgress = false; + + dataSource.Initialized -= DataSourceInitialized; + + CurrencyManager = + _ChartControl.BindingContext[dataSource] as CurrencyManager; + + if (dataSource is DataTable) + ProcessAddDataTable((DataTable)dataSource, _NotificationAutogen); + else + ProcessAddList(dataSource, _NotificationAutogen); + } + } + + #endregion + + #region GetPdc + + private PropertyDescriptorCollection GetPdc(object dataItem) + { + if (_Chart.EnableDiscreteBoundItems == false) + return (_Pdc); + + if (dataItem != null) + return (TypeDescriptor.GetProperties(dataItem.GetType())); + + return (null); + } + + #endregion + + #region FindPropertyDescriptor + + private PropertyDescriptor FindPropertyDescriptor( + PropertyDescriptorCollection pdc, string name) + { + if (pdc != null) + { + foreach (PropertyDescriptor pd in pdc) + { + if (pd.Name.Equals(name) == true) + return (pd); + } + } + + return (null); + } + + #endregion + + #region FindChartSeries + + private BaseSeries FindChartSeries(string name) + { + ChartBaseSeriesCollection baseSeries = _Chart.BaseSeries; + + foreach (BaseSeries series in baseSeries) + { + if (name.Equals(series.Name) == true) + return (series); + } + + return (null); + } + + #endregion + + #region LoadSeriesData + + internal void LoadSeriesData(BaseSeries series) + { + if (_BaseDataSource is DataSet) + LoadDataSetTable((DataSet)_BaseDataSource, _BaseDataMember, series); + + else if (_BaseDataSource is DataTable) + LoadDataTableSeriesData((DataTable)_BaseDataSource, series); + + else + LoadListSeriesData(series); + } + + #region LoadDataSetTable + + internal void LoadDataSetTable(DataSet dataSet, string dataMember, BaseSeries series) + { + if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0) + dataMember = dataSet.Tables[0].TableName; + + if (string.IsNullOrEmpty(dataMember) == false) + LoadDataTableSeriesData(dataSet.Tables[dataMember], series); + } + + #endregion + + #region LoadDataTableSeriesData + + private void LoadDataTableSeriesData(DataTable dt, BaseSeries series) + { + DataColumn dtSeries = FindDataColumn(dt, series.DataPropertyNameSeries); + DataColumn dtNameX = FindDataColumn(dt, series.DataPropertyNameX); + + if (dtNameX == null) + throw new Exception("DataPropertyNameX (" + series.DataPropertyNameX + ") not present in DataTable."); + + DataColumn[] dtNamesY = + new DataColumn[series.DataPropertyNamesY.Count]; + + for (int i = 0; i < series.DataPropertyNamesY.Count; i++) + { + string name = series.DataPropertyNamesY[i]; + + dtNamesY[i] = FindDataColumn(dt, name); + + if (dtNamesY[i] == null) + throw new Exception("DataPropertyNameY (" + name + ") not present in DataTable."); + } + + if (dtSeries == null) + LoadDataTableSeriesDataSingle(series, dt, dtNameX, dtNamesY); + else + LoadDataTableSeriesDataMultiple(series, dt, dtSeries, dtNameX, dtNamesY); + + _ChartControl.DoSeriesDataBindingCompleteEvent(_Chart, series, dt); + } + + #region LoadDataTableSeriesDataSingle + + private void LoadDataTableSeriesDataSingle( + BaseSeries series, DataTable dt, DataColumn dtNameX, DataColumn[] dtNamesY) + { + for (int i = 0; i < CurrencyManager.Count; i++) + { + DataRowView view = CurrencyManager.List[i] as DataRowView; + + if (view != null) + AddDataTableSeriesData(series, dt, dtNameX, dtNamesY, view); + } + } + + #endregion + + #region LoadDataTableSeriesDataMultiple + + private void LoadDataTableSeriesDataMultiple(BaseSeries series, + DataTable dt, DataColumn dtSeries, DataColumn dtNameX, DataColumn[] dtNamesY) + { + for (int i = 0; i < CurrencyManager.Count; i++) + { + DataRowView view = CurrencyManager.List[i] as DataRowView; + + if (view != null) + { + object seriesKey = view.Row.ItemArray[dtSeries.Ordinal]; + + if (seriesKey == series.SeriesKey || seriesKey.Equals(series.SeriesKey)) + AddDataTableSeriesData(series, dt, dtNameX, dtNamesY, view); + } + } + } + + #endregion + + #region AddDataTableSeriesData + + private void AddDataTableSeriesData(BaseSeries series, + DataTable dt, DataColumn dtNameX, DataColumn[] dtNamesY, DataRowView view) + { + object valueX = view.Row.ItemArray[dtNameX.Ordinal]; + + object[] valuesY = new object[dtNamesY.Length]; + + for (int i = 0; i < dtNamesY.Length; i++) + { + DataColumn dtcol = dtNamesY[i]; + + valuesY[i] = view.Row.ItemArray[dtcol.Ordinal]; + } + + series.AddSeriesPoint(valueX, valuesY, view); + } + + #endregion + + #endregion + + #region LoadListSeriesData + + private void LoadListSeriesData(BaseSeries series) + { + object source = _BaseDataSource; + + PropertyDescriptor pdSeries = FindListPd(series.DataPropertyNameSeries); + PropertyDescriptor pdNameX = FindListPd(series.DataPropertyNameX); + + if (pdNameX == null) + throw new Exception("DataPropertyNameX (" + series.DataPropertyNameX + ") not present."); + + PropertyDescriptor[] pdNamesY = + new PropertyDescriptor[series.DataPropertyNamesY.Count]; + + for (int i = 0; i < series.DataPropertyNamesY.Count; i++) + { + string name = series.DataPropertyNamesY[i]; + + pdNamesY[i] = FindListPd(name); + + if (pdNamesY[i] == null) + throw new Exception("DataPropertyNameY (" + name + ") not present."); + } + + if (pdSeries == null) + LoadListSeriesDataSingle(series, source, pdNameX, pdNamesY); + else + LoadListSeriesDataMultiple(series, source, pdSeries, pdNameX, pdNamesY); + + _ChartControl.DoSeriesDataBindingCompleteEvent(_Chart, series, source); + } + + #region LoadListSeriesDataSingle + + private void LoadListSeriesDataSingle( + BaseSeries series, object source, PropertyDescriptor pdNameX, PropertyDescriptor[] pdNamesY) + { + IList list = source as IList; + + if (list != null) + { + for (int i = 0; i < list.Count; i++) + { + object o = list[i]; + + AddListSeriesData(series, o, pdNameX, pdNamesY); + } + } + } + + #endregion + + #region LoadListSeriesDataMultiple + + private void LoadListSeriesDataMultiple(BaseSeries series, + object source, PropertyDescriptor pdSeries, PropertyDescriptor pgNameX, PropertyDescriptor[] pdNamesY) + { + IList list = source as IList; + + if (list != null) + { + for (int i = 0; i < list.Count; i++) + { + object o = list[i]; + + object seriesKey = pdSeries.GetValue(o); + + if (seriesKey == series.SeriesKey || seriesKey.Equals(series.SeriesKey)) + AddListSeriesData(series, o, pgNameX, pdNamesY); + } + } + } + + #endregion + + #region AddListSeriesData + + private void AddListSeriesData(BaseSeries series, + object o, PropertyDescriptor pdNameX, PropertyDescriptor[] pdNamesY) + { + object valueX = pdNameX.GetValue(o); + + object[] valuesY = new object[pdNamesY.Length]; + + for (int i = 0; i < pdNamesY.Length; i++) + valuesY[i] = pdNamesY[i].GetValue(o); + + series.AddSeriesPoint(valueX, valuesY, o); + } + + #endregion + + #endregion + + #endregion + + #region CurrencyManagerListChanged + + void CurrencyManagerListChanged(object sender, ListChangedEventArgs e) + { + if (_CurrencyManager != null) + _Chart.InvalidateLayout(); + } + + #endregion + + #region Dispose + + /// + /// Data Binder Dispose + /// + public void Dispose() + { + CurrencyManager = null; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/DataLabel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/DataLabel.cs new file mode 100644 index 00000000..7940c159 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/DataLabel.cs @@ -0,0 +1,408 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing.Design; +using DevComponents.DotNetBar.Charts; +using DevComponents.DotNetBar.Charts.Style; + +/// +/// Represents the collection of DataLabels. +/// +[Editor("DevComponents.Charts.Design.DataLabelCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] +public class DataLabelCollection : CustomNamedCollection +{ + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("DataLabel")); + } + + #endregion +} + +namespace DevComponents.DotNetBar.Charts +{ + public class DataLabel : ChartVisualElement, IEffectiveStyle + { + #region Private variables + + private string _Text; + + private DataLabelVisualStyle _DataLabelVisualStyle; + private EffectiveStyle _EffectiveDataLabelStyle; + + private object _ValueX; + private object _ValueY; + + private BarLabelPosition _BarLabelPosition = BarLabelPosition.NotSet; + + #endregion + + #region Constructors + + /// + /// DataLabel + /// + /// Associated SeriesPoint + /// Label text + public DataLabel(SeriesPoint sp, string text) + : this(sp) + { + _Text = text; + } + + /// + /// DataLabel + /// + /// Associated SeriesPoint + public DataLabel(SeriesPoint sp) + : this() + { + if (sp.ValueX == null) + throw new Exception("DataLabel Value X must be defined."); + + if (sp.ValueY == null || sp.ValueY.Length == 0) + throw new Exception("DataLabel Value Y must be defined."); + + ValueX = sp.ValueX; + ValueY = sp.ValueY[0]; + } + + /// + /// DataLabel + /// + public DataLabel() + { + _EffectiveDataLabelStyle = new EffectiveStyle(this); + } + + #endregion + + #region Public properties + + #region BarLabelPosition + + /// + /// Gets or sets the position of bar series labels. + /// + [DefaultValue(BarLabelPosition.NotSet), Category("Bar Display")] + [Description("Indicates the position of bar series labels.")] + public BarLabelPosition BarLabelPosition + { + get { return (_BarLabelPosition); } + set { _BarLabelPosition = value; } + } + + #endregion + + #region DataLabelVisualStyle + + /// + /// Gets or sets the visual style for the data label. + /// + [Category("Style")] + [Description("Indicates the visual style for the data label.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DataLabelVisualStyle DataLabelVisualStyle + { + get + { + if (_DataLabelVisualStyle == null) + { + _DataLabelVisualStyle = new DataLabelVisualStyle(); + + StyleVisualChangeHandler(null, _DataLabelVisualStyle); + } + + return (_DataLabelVisualStyle); + } + + set + { + if (_DataLabelVisualStyle != value) + { + DataLabelVisualStyle oldValue = _DataLabelVisualStyle; + + _DataLabelVisualStyle = value; + + OnVisualStyleChanged("DataLabelVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region EffectiveDataLabelStyle + + /// + /// Gets a reference to the DataLabel effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates a reference to the DataLabel effective (cached, composite) style.")] + public DataLabelVisualStyle EffectiveDataLabelStyle + { + get { return (_EffectiveDataLabelStyle.Style); } + } + + #endregion + + #region ValueX + + /// + /// Gets or sets the X-Axis Value. + /// + [Category("Data")] + [Description("Indicates the X-Axis Value.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object ValueX + { + get { return (_ValueX); } + set { _ValueX = value; } + } + + #endregion + + #region ValueY + + /// + /// Gets or sets the Y-Axis Value. + /// + [Category("Data")] + [Description("Indicates the Y-Axis Value.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object ValueY + { + get { return (_ValueY); } + set { _ValueY = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the DataLabel text. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the DataLabel text.")] + public string Text + { + get { return (_Text); } + + set + { + _Text = value; + + OnPropertyChangedEx("Text", VisualChangeType.Layout); + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + DataLabelVisualStyle dstyle = style as DataLabelVisualStyle; + + if (dstyle != null) + { + ChartSeries series = Parent as ChartSeries; + + dstyle.ApplyStyle(series.EffectiveDataLabelStyle); + dstyle.ApplyStyle(DataLabelVisualStyle); + } + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Style definition + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + if (_EffectiveDataLabelStyle.InvalidateStyle() == true) + InvalidateLayout(); + + ChartXy chartXy = ParentChartContainer as ChartXy; + + if (chartXy != null) + chartXy.InvalidatePointLabels(); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + DataLabel copy = new DataLabel(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + DataLabel c = copy as DataLabel; + + if (c != null) + { + base.CopyTo(c); + + c.DataLabelVisualStyle = + (_DataLabelVisualStyle != null) ? DataLabelVisualStyle.Copy() : null; + + c.ValueX = ValueX; + c.ValueY = ValueY; + + c.Text = (Text != null) ? (string)Text.Clone() : null; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "DataLabel"; + + sec.AddStartElement(serialName); + } + + if (_DataLabelVisualStyle != null && _DataLabelVisualStyle.IsEmpty == false) + sec.AddElement(_DataLabelVisualStyle.GetSerialData("DataLabelVisualStyle")); + + sec.AddDataValue("ValueX", ValueX, null); + sec.AddDataValue("ValueY", ValueY, null); + + sec.AddValue("Text", Text, null); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "ValueX": + ValueX = se.DataValue; + break; + + case "ValueY": + ValueY = se.DataValue; + break; + + case "Text": + Text = se.StringValue; + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "DataLabelVisualStyle": + sec.PutSerialData(DataLabelVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + DataLabelVisualStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/IOwnerLocalize.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/IOwnerLocalize.cs new file mode 100644 index 00000000..5f282702 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/IOwnerLocalize.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieChart.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieChart.cs new file mode 100644 index 00000000..2716fb9b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieChart.cs @@ -0,0 +1,6396 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.Charts.TextMarkup; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + public class PieChart : BaseChart, ISeriesPointContainer + { + #region Private variables + + private ChartPieSeriesCollection _PieSeries; + + private Point _CenterPoint; + private PointF _CenterPos = PointF.Empty; + + private double _InnerRadius; + private double _InnerRadiusEx = double.NaN; + + private double _OuterRadius = .8d; + private double _OuterRadiusEx = double.NaN; + + private double _MaxPieOuterExtent; + + private double _GridInnerRadius; + private double _GridInnerRadiusEx = double.NaN; + + private double _GridOuterRadius = 1d; + private double _GridOuterRadiusEx = double.NaN; + + private int _MinOuterRadius = 80; + + private PieRadiusScale _PieRadiusScale = PieRadiusScale.Percentage; + + private double _InnerMargin = .02d; + private double _InnerMarginEx = double.NaN; + + private double _OuterMargin = 0d; + private double _SeriesMargin = .02d; + + private double _ExplodedOffset = .05d; + private double _ExplodedMargin = .1d; + + private double _DetachedOffset = .1d; + private int _MaxDetachedOffset = 100; + + private double _ExplodedOffsetEx = double.NaN; + private int _MaxExplodedOffset = 100; + + private int _MaxRingOutRadius = 48; + private int _MinRingOutRadius = 9; + + private string _CenterLabel; + private CenterLabelVisibility _CenterLabelVisibility = CenterLabelVisibility.Always; + private BodyElement _CenterLabelMarkup; + + private SymbolDef _ScaleSymDef = new SymbolDef(); + private float _SymFontScale = -1; + + private PieChartVisualStyle _ChartVisualStyle; + private EffectiveStyle _EffectiveChartStyle; + private EffectiveStyles _EffectivePieCenterStyles; + + private SliceLabelOverlapMode _SliceLabelOverlapMode = SliceLabelOverlapMode.NotSet; + + private int _RingWeightTotal; + + private PieSeriesPoint _LastHitPsp; + private PieSeriesPoint _HitPsp; + private ItemHitArea _LastHitArea; + + private Tbool _CenterFirstSlice = Tbool.NotSet; + private Tbool _ShowAllRings = Tbool.NotSet; + private Tbool _ShowOtherSlice = Tbool.NotSet; + + private MouseClickSliceAction _MouseClickSliceAction = MouseClickSliceAction.NotSet; + private MouseDoubleClickSliceAction _MouseDoubleClickSliceAction = MouseDoubleClickSliceAction.NotSet; + + private PieSelectionMode _PieSelectionMode = PieSelectionMode.NotSet; + private PieRingOutDisplayMode _PieRingOutDisplayMode = PieRingOutDisplayMode.OnMouseOver; + + private WhitespaceClickBehavior _WhitespaceClickBehavior = WhitespaceClickBehavior.ClearSelection; + + private PspDragType _PspDragType; + private Tbool _EnableDragDetach = Tbool.NotSet; + + private double _GridInterval = 10d; + private double _GridMinValue = 0d; + private double _GridMaxValue = 100d; + + private List _PieLabels; + private Rectangle _RenderBounds; + + private SliceVisualLayout _SubSliceVisualLayout; + + private uint _GlobalSelectionCount; + + private States _States; + + #endregion + + public PieChart(string name) + : this() + { + Name = name; + } + + public PieChart() + { + InitDefaultStates(); + + _EffectiveChartStyle = new EffectiveStyle(this); + _EffectivePieCenterStyles = new EffectiveStyles(this); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.MultiSelect, true); + } + + #endregion + + #region Public properties + + #region ActualInnerRadius + + /// + /// Gets the actual, calculated inner radius of the pie. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double ActualInnerRadius + { + get { return (InnerRadiusEx); } + } + + #endregion + + #region ActualOuterRadius + + /// + /// Gets the actual, calculated outer radius of the pie. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double ActualOuterRadius + { + get { return (OuterRadiusEx); } + } + + #endregion + + #region CenterFirstSlice + + /// + /// Gets or sets whether the first pie slice is centered + /// on the starting angle or starts on the starting angle. Default is false. + /// + [DefaultValue(Tbool.NotSet), Category("Display")] + [Description("Indicates whether the first pie slice is centered on the starting angle or starts on the starting angle. Default is false.")] + public Tbool CenterFirstSlice + { + get { return (_CenterFirstSlice); } + + set + { + if (value != _CenterFirstSlice) + { + _CenterFirstSlice = value; + + OnPropertyChangedEx("CenterFirstSlice", VisualChangeType.Layout); + } + } + } + + #endregion + + #region CenterLabel + + /// + /// Gets or sets the text to use for the center hole label. + /// + [DefaultValue(null), Category("Label")] + [Description("Indicates the text to use for the center hole label.")] + [Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string CenterLabel + { + get { return (_CenterLabel); } + + set + { + if (value != _CenterLabel) + { + _CenterLabel = value; + + MarkupCenterLabelChanged(); + + OnPropertyChangedEx("CenterLabel", VisualChangeType.Render); + } + } + } + + #endregion + + #region CenterLabelVisibility + + /// + /// Gets or sets the mode used to determine if/when to display the center label. + /// + [DefaultValue(CenterLabelVisibility.Always), Category("Label")] + [Description("Indicates the mode used to determine if/when to display the center label.")] + public CenterLabelVisibility CenterLabelVisibility + { + get { return (_CenterLabelVisibility); } + + set + { + if (value != _CenterLabelVisibility) + { + _CenterLabelVisibility = value; + + OnPropertyChangedEx("CenterLabelVisibility", VisualChangeType.Render); + } + } + } + + #endregion + + #region CenterPoint + + /// + /// Gets the calculated center Point for the pie. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Point CenterPoint + { + get { return (_CenterPoint); } + internal set { _CenterPoint = value; } + } + + #endregion + + #region CenterPos + + /// + /// Gets or sets the offset from the default center x,y location of the chart. If + /// the values are between -1 and 1, then the offsets are taken as a percentage + /// of the width/height, otherwise they are taken as absolute pixel offsets. + /// + [Description("Indicates the offset from the default center x,y location of the chart. If the values are between -1 and 1, then the offsets are taken as a percentage of the width/height, otherwise they are taken as absolute pixel offsets.")] + [Editor("DevComponents.Charts.Design.PivotPointEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + [TypeConverter(typeof(PointFConverter))] + [Category("Offset")] + public PointF CenterPos + { + get { return (_CenterPos); } + + set + { + if (value != _CenterPos) + { + _CenterPos = value; + + OnPropertyChangedEx("CenterPos", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeCenterPos() + { + return (_CenterPos.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetCenterPos() + { + CenterPos = PointF.Empty; + } + + #endregion + + #region ChartSeries + + /// + /// Gets a reference to the collection of PieSeries + /// + [Category("Data")] + [Description("Indicates the collection of Chart Series.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartPieSeriesCollection ChartSeries + { + get + { + if (_PieSeries == null) + { + _PieSeries = new ChartPieSeriesCollection(); + + _PieSeries.CollectionChanged += ChartSeriesCollectionChanged; + } + + return (_PieSeries); + } + + internal set + { + BaseSeries = null; + + if (_PieSeries != null) + _PieSeries.CollectionChanged -= ChartSeriesCollectionChanged; + + _PieSeries = value; + + if (_PieSeries != null) + _PieSeries.CollectionChanged += ChartSeriesCollectionChanged; + } + } + + #region ChartSeriesCollectionChanged + + void ChartSeriesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + BaseSeries = null; + InvalidateValueCache(); + + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (PieSeries item in e.NewItems) + item.Parent = this; + break; + + case NotifyCollectionChangedAction.Replace: + foreach (PieSeries item in e.OldItems) + item.Parent = null; + + foreach (PieSeries item in e.NewItems) + item.Parent = this; + break; + + case NotifyCollectionChangedAction.Remove: + foreach (PieSeries item in e.OldItems) + item.Parent = null; + break; + } + + SeriesRangeChanged = true; + + InvalidateLayout(); + } + + #endregion + + #endregion + + #region ChartVisualStyles + + /// + /// Gets or sets the visual style for the Chart. + /// + [Category("Style")] + [Description("Indicates the visual style for the Chart.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieChartVisualStyle ChartVisualStyle + { + get + { + if (_ChartVisualStyle == null) + { + _ChartVisualStyle = new PieChartVisualStyle(); + + StyleVisualChangeHandler(null, _ChartVisualStyle); + } + + return (_ChartVisualStyle); + } + + set + { + if (_ChartVisualStyle != value) + { + PieChartVisualStyle oldValue = _ChartVisualStyle; + + _ChartVisualStyle = value; + + OnStyleChanged("ChartVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CustomPalette + + /// + /// Gets or sets the custom palette for the chart. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the custom palette for the chart.")] + public override Color[] CustomPalette + { + get { return (base.CustomPalette); } + + set + { + base.CustomPalette = value; + + UpdatePaletteNeeded = true; + } + } + + #endregion + + #region DetachedOffset + + /// + /// Gets or sets the default offset distance of a slice from the pie center, as measured + /// by a percentage of the pie radius (if less than 1), or absolute pixel amount (if greater than 1). Default is .1. + /// + /// A value of 0 will restore the slice to its original position in the pie (which + /// may still be offset, if the pie is "exploded"). + /// + [DefaultValue(.1d), Category("Offset")] + [Description("Indicates the default offset distance of a slice from the pie center, as measured by a percentage of the pie radius (if <= 1), or absolute pixel amount (if > 1). Default is .1.")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double DetachedOffset + { + get { return (_DetachedOffset); } + + set + { + if (value != _DetachedOffset) + { + _DetachedOffset = value; + + OnPropertyChangedEx("DetachedOffset", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EffectiveChartStyle + + /// + /// Gets a reference to the Chart's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public PieChartVisualStyle EffectiveChartStyle + { + get { return (_EffectiveChartStyle.Style); } + } + + #endregion + + #region EffectivePieCenterStyles + + /// + /// Gets a reference to the Chart's Effective (cached, composite) Pie Center styles. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public EffectiveStyles EffectivePieCenterStyle + { + get { return (_EffectivePieCenterStyles); } + } + + #endregion + + #region EnableCenterLabelMarkup + + /// + /// Gets or sets whether text-markup support is enabled for the Center Label. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for the Center Label.")] + public bool EnableCenterLabelMarkup + { + get { return (TestState(States.EnableCenterLabelMarkup)); } + + set + { + if (EnableCenterLabelMarkup != value) + { + SetState(States.EnableCenterLabelMarkup, value); + + MarkupCenterLabelChanged(); + + OnPropertyChangedEx("EnableCenterLabelMarkup", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableDragDetach + + /// + /// Gets or sets whether the user can, by default, detach + /// slices of the pie by Click and drag. + /// + [DefaultValue(Tbool.NotSet), Category("Behavior")] + [Description("Indicates whether the user can, by default, detach slices of the pie by Click and drag.")] + public Tbool EnableDragDetach + { + get { return (_EnableDragDetach); } + + set + { + if (value != _EnableDragDetach) + { + _EnableDragDetach = value; + + OnPropertyChangedEx("EnableDragDetach", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableShiftDragExplode + + /// + /// Gets or sets whether the user can explode the pie by + /// ShiftClick and drag. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether the user can explode the pie by ShiftClick and drag.")] + public bool EnableShiftDragExplode + { + get { return (TestState(States.EnableShiftDragExplode)); } + + set + { + if (value != EnableShiftDragExplode) + { + SetState(States.EnableShiftDragExplode, value); + + OnPropertyChanged("EnableShiftDragExplode"); + } + } + } + + #endregion + + #region ExplodedMargin + + /// + /// Gets or sets the exploded between each series when the pie + /// is Exploded. The Margin is is measured as a percentage of the pie radius (if <= 1) + /// or the absolute pixel amount (if > 1). Default is .1. + /// + [DefaultValue(.1d), Category("Margin")] + [Description("Indicates the exploded between each series when the pie is Exploded. The Margin is is measured as a percentage of the pie radius (if <= 1) or the absolute pixel amount (if > 1). Default is .1.")] + public double ExplodedMargin + { + get { return (_ExplodedMargin); } + + set + { + if (value != _ExplodedMargin) + { + _ExplodedMargin = value; + + OnPropertyChangedEx("ExplodedMargin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ExplodedOffset + + /// + /// Gets or sets the offset of each slice from the pie center when the pie + /// is Exploded. The offset is is measured as a percentage of the pie radius (if less than 1) + /// or the absolute pixel amount (if greater than 1). Default is .1. + /// + /// Clicking a Detached slice will restore it to its original position in the pie, which + /// may still be offset by this amount, if the pie is 'exploded'. + /// + [DefaultValue(.05d), Category("Offset")] + [Description("Indicates the offset of each slice from the pie center when the pie is Exploded. The offset is is measured as a percentage of the pie radius (if <= 1) or the absolute pixel amount (if > 1). Default is .1.")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double ExplodedOffset + { + get { return (_ExplodedOffset); } + + set + { + if (value != _ExplodedOffset) + { + _ExplodedOffset = value; + _ExplodedOffsetEx = double.NaN; + + OnPropertyChangedEx("ExplodedOffset", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GridInnerRadius + + /// + /// Gets or sets the Inner radius of the pie grid, relative to the pie area. Can be a + /// percentage (if value is between 0 and 1) or pixel amount (if value > 1). + /// Defaults to 0. + /// + [DefaultValue(0d), Category("Radius")] + [Description("Indicates the Inner radius of the pie grid, relative to the pie area. Can be a percentage (if value is between 0 and 1) or pixel amount (if value > 1). Defaults to 0")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double GridInnerRadius + { + get { return (_GridInnerRadius); } + + set + { + if (value != _GridInnerRadius) + { + _GridInnerRadius = value; + + InvalidateValueCache(); + + OnPropertyChangedEx("GridInnerRadius", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GridOuterRadius + + /// + /// Gets or sets the outer radius of the pie grid, relative to the pie area. Can be a + /// percentage (if value is between 0 and 1) or pixel amount (if value > 1). + /// Defaults to 1 (ie 100 %). + /// + [DefaultValue(1d), Category("Radius")] + [Description("Indicates the outer radius of the pie grid, relative to the pie area. Can be a percentage (if value is between 0 and 1) or pixel amount (if value > 1). Defaults to 1")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double GridOuterRadius + { + get { return (_GridOuterRadius); } + + set + { + if (value != _GridOuterRadius) + { + _GridOuterRadius = value; + + InvalidateValueCache(); + + OnPropertyChangedEx("GridOuterRadius", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GridInterval + + /// + /// Gets or sets the radial grid interval (interval division between grid lines). + /// + [DefaultValue(10d), Category("Grid")] + [Description("Indicates the radial grid interval (interval division between grid lines).")] + public double GridInterval + { + get { return (_GridInterval); } + + set + { + if (value != _GridInterval) + { + _GridInterval = value; + + OnPropertyChangedEx("GridInterval", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GridMaxValue + + /// + /// Gets or sets the radial grid maximum value. + /// + [DefaultValue(100d), Category("Grid")] + [Description("Indicates the radial grid maximum value.")] + public double GridMaxValue + { + get { return (_GridMaxValue); } + + set + { + if (value != _GridMaxValue) + { + _GridMaxValue = value; + + OnPropertyChangedEx("GridMaxValue", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GridMinValue + + /// + /// Gets or sets the radial grid minimum value. + /// + [DefaultValue(0d), Category("Grid")] + [Description("Indicates the radial grid minimum value.")] + public double GridMinValue + { + get { return (_GridMinValue); } + + set + { + if (value != _GridMinValue) + { + _GridMinValue = value; + + OnPropertyChangedEx("GridMinValue", VisualChangeType.Layout); + } + } + } + + #endregion + + #region InnerMargin + + /// + /// Gets or sets the inner pixel margin between the inner + /// most ring and the pie center. Default is .02d. + /// + [Description("Indicates the inner pixel margin between the inner most ring and the pie center. Default is .02d.")] + [DefaultValue(.02d), Category("Margin")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double InnerMargin + { + get { return (_InnerMargin); } + + set + { + if (value != _InnerMargin) + { + _InnerMargin = value; + + InvalidateValueCache(); + + OnPropertyChangedEx("InnerMargin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region InnerRadius + + /// + /// Gets or sets the size of the inner radius for the pie, relative to the plot + /// area. Can be a percentage (if value is between 0 and 1) or pixel amount (if value > 1). + /// A value > 0 will create an inner "hole" or donut chart. + /// + [DefaultValue(0d), Category("Radius")] + [Description("Indicates the size of the inner radius for the pie, relative to the plot area. Can be a percentage (if value is between 0 and 1) or pixel amount (if value > 1). A value > 0 will create an inner 'hole' or donut chart.")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double InnerRadius + { + get { return (_InnerRadius); } + + set + { + if (value != _InnerRadius) + { + _InnerRadius = value; + + InvalidateValueCache(); + + OnPropertyChangedEx("InnerRadius", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsExploded + + /// + /// Gets or sets whether all slices of the pie have been pulled out, or + /// exploded, from the center of the pie. This attribute can be used to + /// create added emphasis or to highlight the entire pie. Default is false. + /// + [DefaultValue(false), Category("Display")] + [Description("Indicates whether all slices of the pie have been pulled out, or exploded, from the center of the pie. This attribute can be used to create added emphasis or to highlight the entire pie. Default is false.")] + public bool IsExploded + { + get { return (TestState(States.Exploded)); } + + set + { + if (value != IsExploded) + { + SetState(States.Exploded, value); + + _ExplodedOffsetEx = double.NaN; + + OnPropertyChangedEx("IsExploded", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxDetachedOffset + + /// + /// Gets or sets the maximum Detached Offset value (in pixels) that + /// a pie slice can be detached. Default is 100. + /// + [DefaultValue(100), Category("Offset")] + [Description("Indicates the maximum DetachedOffset value (in pixels) that a pie slice can be detached. Default is 100.")] + public int MaxDetachedOffset + { + get { return (_MaxDetachedOffset); } + + set + { + if (value != _MaxDetachedOffset) + { + _MaxDetachedOffset = value; + + OnPropertyChangedEx("MaxDetachedOffset", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxExplodedOffset + + /// + /// Gets or sets the maximum ExplodedOffset value (in pixels) that + /// the pie may be exploded. Default is 100. + /// + [DefaultValue(100), Category("Offset")] + [Description("Indicates the maximum ExplodedOffset value (in pixels) that the pie may be exploded. Default is 100.")] + public int MaxExplodedOffset + { + get { return (_MaxExplodedOffset); } + + set + { + if (value != _MaxExplodedOffset) + { + _MaxExplodedOffset = value; + + OnPropertyChangedEx("MaxExplodedOffset", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxRingOutRadius + + /// + /// Gets or sets the maximum radius of the Center + /// RingOut image (in pixels). Default is 48. + /// + [DefaultValue(48), Category("Radius")] + [Description("Indicates the maximum radius of the Center RingOut image (in pixels). Default is 48.")] + public int MaxRingOutRadius + { + get { return (_MaxRingOutRadius); } + + set + { + if (value != _MaxRingOutRadius) + { + _MaxRingOutRadius = value; + + OnPropertyChanged("MaxRingOutRadius"); + } + } + } + + #endregion + + #region MinOuterRadius + + /// + /// Gets or sets the minimum outer radius of the chart, in pixels. Defaults to 80. + /// + [DefaultValue(80), Category("Radius")] + [Description("Indicates the minimum outer radius of the chart, in pixels. Defaults to 80.")] + public int MinOuterRadius + { + get { return (_MinOuterRadius); } + + set + { + if (value != _MinOuterRadius) + { + _MinOuterRadius = value; + + _OuterRadiusEx = double.NaN; + _ExplodedOffsetEx = double.NaN; + + OnPropertyChangedEx("MinOuterRadius", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinRingOutRadius + + /// + /// Gets or sets the minimum radius of the Center + /// RingOut image (in pixels). Default is 9. + /// + [DefaultValue(9), Category("Radius")] + [Description("Indicates the maximum radius of the Center RingOut image (in pixels). Default is 9.")] + public int MinRingOutRadius + { + get { return (_MinRingOutRadius); } + + set + { + if (value != _MinRingOutRadius) + { + _MinRingOutRadius = value; + + OnPropertyChanged("MinRingOutRadius"); + } + } + } + + #endregion + + #region MouseClickAction + + /// + /// Gets or sets the default action used when the user clicks on a pie slice. Default is 'None'. + /// + [DefaultValue(MouseClickSliceAction.NotSet), Category("Behavior")] + [Description("Indicates the default action used when the user clicks on a pie slice. Default is 'None'.")] + public MouseClickSliceAction MouseClickSliceAction + { + get { return (_MouseClickSliceAction); } + + set + { + if (value != _MouseClickSliceAction) + { + _MouseClickSliceAction = value; + + OnPropertyChanged("MouseClickSliceAction"); + } + } + } + + #endregion + + #region MouseDoubleClickSliceAction + + /// + /// Gets or sets the default action used when + /// the user double-clicks on a pie slice. Default is 'None'. + /// + [DefaultValue(MouseDoubleClickSliceAction.NotSet), Category("Behavior")] + [Description("Indicates the default action used when the user double-clicks on a pie slice. Default is 'None'.")] + public MouseDoubleClickSliceAction MouseDoubleClickSliceAction + { + get { return (_MouseDoubleClickSliceAction); } + + set + { + if (value != _MouseDoubleClickSliceAction) + { + _MouseDoubleClickSliceAction = value; + + OnPropertyChanged("MouseDoubleClickSliceAction"); + } + } + } + + #endregion + + #region MultiSelect + + /// + /// Gets or sets whether multiple items can be selected by the user. Default is true. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether multiple items can be selected by the user. Default is true.")] + public bool MultiSelect + { + get { return (TestState(States.MultiSelect)); } + + set + { + if (value != MultiSelect) + { + SetState(States.MultiSelect, value); + + OnPropertyChanged("MultiSelect"); + } + } + } + + #endregion + + #region OuterMargin + + /// + /// Gets or sets the outer pixel margin for the chart. + /// + [Description("Indicates the outer pixel margin for the chart.")] + [DefaultValue(0d), Category("Margin")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double OuterMargin + { + get { return (_OuterMargin); } + + set + { + if (value != _OuterMargin) + { + _OuterMargin = value; + + _OuterRadiusEx = double.NaN; + _ExplodedOffsetEx = double.NaN; + + OnPropertyChangedEx("OuterMargin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region OuterRadius + + /// + /// Gets or sets the outer radius of the pie, relative to the plot area. Can be a + /// percentage (if value is between 0 and 1) or pixel amount (if value > 1). + /// Defaults to .8 (ie 80 %). + /// + [DefaultValue(.8d), Category("Radius")] + [Description("Indicates the outer radius of the pie, relative to the plot area. Can be a percentage (if value is between 0 and 1) or pixel amount (if value > 1). Defaults to .8")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public virtual double OuterRadius + { + get { return (_OuterRadius); } + + set + { + if (value != _OuterRadius) + { + _OuterRadius = value; + + InvalidateValueCache(); + + OnPropertyChangedEx("OuterRadius", VisualChangeType.Layout); + } + } + } + + #endregion + + #region PaletteGroup + + /// + /// Gets or sets the palette color group to use (Light/Medium/Dark/Color1/MonoBlue/etc). + /// + [DefaultValue(PaletteGroup.Color1), Category("Appearance")] + [Description("Indicates the palette color group to use (Light/Medium/Dark/Color1/MonoBlue/etc.).")] + public override PaletteGroup PaletteGroup + { + get { return (base.PaletteGroup); } + + set + { + if (value != PaletteGroup) + { + base.PaletteGroup = value; + + UpdatePaletteNeeded = true; + } + } + } + + #endregion + + #region PieRadiusScale + + /// + /// Gets or sets how the PieRadius values (InnerRadius, OuterRadius, + /// GridInnerRadius, and GridOuterRadius) are interpreted (as absolute + /// pixel values or as relative percentages). + /// + [DefaultValue(PieRadiusScale.Percentage), Category("Radius")] + [Description("Indicates how the PieRadius values (InnerRadius, OuterRadius, GridInnerRadius, and GridOuterRadius) are interpreted (as absolute pixel values or as relative percentages).")] + public PieRadiusScale PieRadiusScale + { + get { return (_PieRadiusScale); } + + set + { + if (value != _PieRadiusScale) + { + _PieRadiusScale = value; + + OnPropertyChangedEx("PieRadiusScale", VisualChangeType.Recalc); + } + } + } + + #endregion + + #region PieRingOutDisplayMode + + /// + /// Gets or sets the display mode for the RingOut indicator (used + /// to move out a ring level when ShowAllRings is false and the + /// ActiveSeriesPointCollection has been set to an inner ring). + /// + [DefaultValue(PieRingOutDisplayMode.OnMouseOver), Category("Behavior")] + [Description("Indicates the display mode for the RingOut indicator (used to move out a ring level when ShowAllRings is false and the ActiveSeriesPointCollection has been set to an inner ring).")] + public PieRingOutDisplayMode PieRingOutDisplayMode + { + get { return (_PieRingOutDisplayMode); } + + set + { + if (value != _PieRingOutDisplayMode) + { + _PieRingOutDisplayMode = value; + + OnPropertyChangedEx("PieRingOutDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region PieSelectionMode + + /// + /// Gets or sets the default mode used to perform pie selections. Default is 'Slice'. + /// + [DefaultValue(PieSelectionMode.NotSet), Category("Behavior")] + [Description("Indicates the default mode used to perform pie selections. Default is 'Slice'.")] + public PieSelectionMode PieSelectionMode + { + get { return (_PieSelectionMode); } + + set + { + if (value != _PieSelectionMode) + { + _PieSelectionMode = value; + + OnPropertyChanged("PieSelectionMode"); + } + } + } + + #endregion + + #region ReversePaletteColors + + /// + /// Gets or sets whether default palette colors are utilized in reverse order. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether default palette colors are utilized in reverse order.")] + public override bool ReversePaletteColors + { + get { return (base.ReversePaletteColors); } + + set + { + if (value != ReversePaletteColors) + { + base.ReversePaletteColors = value; + + UpdatePaletteNeeded = true; + } + } + } + + #endregion + + #region ReverseRingOrder + + /// + /// Gets or sets whether rings of the pie are presented in reverse order. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether rings of the pie are presented in reverse order.")] + public bool ReverseRingOrder + { + get { return (TestState(States.ReverseRingOrder)); } + + set + { + if (value != ReverseRingOrder) + { + SetState(States.ReverseRingOrder, value); + + OnPropertyChangedEx("ReverseRingOrder", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SeriesMargin + + /// + /// Gets or sets the margin between multiple series in + /// the chart, relative to the plot area. Can be a percentage (if + /// value is between 0 and 1) or pixel amount (if value > 1). + /// Defaults to .02 + /// + [Description("Indicates the margin between multiple series in the chart, relative to the plot area. Can be a percentage (if value is between 0 and 1) or pixel amount (if value > 1). Defaults to .02")] + [DefaultValue(.02d), Category("Margin")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double SeriesMargin + { + get { return (_SeriesMargin); } + + set + { + if (value != _SeriesMargin) + { + _SeriesMargin = value; + + OnPropertyChangedEx("SeriesMargin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SeriesOverlayEnabled + + /// + /// Gets or sets whether chart series are, by default, + /// overlayed on top of each other. Default is false. + /// + [DefaultValue(false), Category("Display")] + [Description("Indicates whether chart series are, by default, overlayed on top of each other. Default is false.")] + public bool SeriesOverlayEnabled + { + get { return (TestState(States.SeriesOverlayEnabled)); } + + set + { + if (value != SeriesOverlayEnabled) + { + SetState(States.SeriesOverlayEnabled, value); + + OnPropertyChangedEx("SeriesOverlayEnabled", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowAllRings + + /// + /// Gets or sets whether all series rings are shown when rendering the chart. + /// If false, only one ring at a time is shown, with the ability to 'drill' up + /// or down, to display adjacent rings. Defaults to true'. + /// + [DefaultValue(Tbool.NotSet), Category("Display")] + [Description("Indicates whether all series rings are shown when rendering the chart. If false, only one ring at a time is shown, with the ability to 'drill' up or down, to display adjacent rings. Defaults to true.")] + public Tbool ShowAllRings + { + get { return (_ShowAllRings); } + + set + { + if (value != _ShowAllRings) + { + _ShowAllRings = value; + + OnPropertyChangedEx("ShowAllRings", VisualChangeType.Layout); + } + } + } + + #region ShowAllRingsEx + + internal bool ShowAllRingsEx + { + get { return (ShowAllRings != Tbool.False); } + } + + #endregion + + #endregion + + #region ShowFullGrid + + /// + /// Gets or sets whether the radial pie grid is displayed over the entire + /// pie (0 - 360 degrees) or only over the sweep angle. Default is false. + /// + [DefaultValue(false), Category("Grid")] + [Description("Indicates whether the radial pie grid is displayed over the entire pie (0 - 360 degrees) or only over the sweep angle. Default is false.")] + public bool ShowFullGrid + { + get { return (TestState(States.ShowFullGrid)); } + + set + { + if (value != ShowFullGrid) + { + SetState(States.ShowFullGrid, value); + + OnPropertyChangedEx("ShowFullGrid", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowGridOnTop + + /// + /// Gets or sets whether the radial grid is displayed + /// on top of the pie (ShowPieGrid must also be true). Default is false. + /// + [DefaultValue(false), Category("Grid")] + [Description("Indicates whether the radial grid is displayed on top of the pie (ShowPieGrid must also be true). Default is false.")] + public bool ShowGridOnTop + { + get { return (TestState(States.ShowGridOnTop)); } + + set + { + if (value != ShowGridOnTop) + { + SetState(States.ShowGridOnTop, value); + + OnPropertyChangedEx("ShowGridOnTop", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowOtherSlice + + /// + /// Gets or sets whether to consolidate 'excluded' pie slices + /// (due to MaxSlices or MinPercent settings) into a single slice + /// that represents 'Other' data values. Default is false. + /// + [DefaultValue(Tbool.NotSet), Category("Display")] + [Description("Indicates whether to consolidate 'excluded' pie slices (due to MaxSlices or MinPercent settings) into a single slice that represents 'Other' data values. Default is false.")] + public Tbool ShowOtherSlice + { + get { return (_ShowOtherSlice); } + + set + { + if (value != _ShowOtherSlice) + { + _ShowOtherSlice = value; + + SeriesRangeChanged = true; + + OnPropertyChangedEx("ShowOtherSlice", VisualChangeType.Recalc); + } + } + } + + #endregion + + #region ShowPieGrid + + /// + /// Gets or sets whether a radial grid is displayed for the chart. Defaults to false. + /// + [DefaultValue(false), Category("Grid")] + [Description("Indicates whether a radial grid is displayed for the chart. Defaults to false.")] + public bool ShowPieGrid + { + get { return (TestState(States.ShowPieGrid)); } + + set + { + if (value != ShowPieGrid) + { + SetState(States.ShowPieGrid, value); + + OnPropertyChangedEx("ShowPieGrid", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowSliceLabelsOnEntry + + /// + /// Gets or sets whether all enabled slice labels will be shown + /// when the mouse enters the chart area. Default is false. + /// + [DefaultValue(false), Category("Label")] + [Description("Indicates whether all enabled slice labels will be shown when the mouse enters the chart area. Default is false.")] + public bool ShowSliceLabelsOnEntry + { + get { return (TestState(States.ShowSliceLabelsOnEntry)); } + + set + { + if (value != ShowSliceLabelsOnEntry) + { + SetState(States.ShowSliceLabelsOnEntry, value); + + OnPropertyChangedEx("ShowSliceLabelsOnEntry", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowToolTips + + /// + /// Gets or sets whether tooltips are shown. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether tooltips are shown.")] + public bool ShowToolTips + { + get { return (TestState(States.ShowToolTips)); } + + set + { + if (value != ShowToolTips) + { + SetState(States.ShowToolTips, value); + + OnPropertyChanged("ShowToolTips"); + } + } + } + + #endregion + + #region SliceLabelOverlapMode + + /// + /// Gets or sets the mode for resolving overlapping outer slice labels. + /// Outer slice labels are only displayed for the outer-most chart series ring. + /// This setting only applies to individual series (ie. Overlapped series are + /// treated as distinct elements). Default is HideOverlapping. + /// + [DefaultValue(SliceLabelOverlapMode.NotSet), Category("Label")] + [Description("Indicates the mode for resolving overlapping outer slice labels. Outer slice labels are only displayed for the outer-most chart series ring. This setting only applies to individual series (ie. Overlapped series are treated as distinct elements). Default is HideOverlapping.")] + public SliceLabelOverlapMode SliceLabelOverlapMode + { + get { return (_SliceLabelOverlapMode); } + + set + { + if (value != _SliceLabelOverlapMode) + { + _SliceLabelOverlapMode = value; + + OnPropertyChangedEx("SliceLabelOverlapMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SubSliceVisualLayout + + /// + /// Gets or sets the default layout of chart SeriesPoints that are + /// subordinate to the chart. + /// + [Category("Layout")] + [Description("Indicates the default layout of chart SeriesPoints.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SliceVisualLayout SubSliceVisualLayout + { + get + { + if (_SubSliceVisualLayout == null) + SubSliceVisualLayout = new SliceVisualLayout(this); + + return (_SubSliceVisualLayout); + } + set + { + if (value != _SubSliceVisualLayout) + { + if (_SubSliceVisualLayout != null) + _SubSliceVisualLayout.PropertyChanged -= SliceVisualLayout_PropertyChanged; + + _SubSliceVisualLayout = value; + + if (_SubSliceVisualLayout != null) + _SubSliceVisualLayout.PropertyChanged += SliceVisualLayout_PropertyChanged; + + OnPropertyChangedEx("SubSliceVisualLayout", VisualChangeType.Recalc); + } + } + } + + #region SliceVisualLayout_PropertyChanged + + void SliceVisualLayout_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (ChartControl != null) + ChartControl.GlobalUpdateCount++; + + VisualPropertyChangedEventArgs vce = e as VisualPropertyChangedEventArgs; + + if (vce != null) + { + switch (vce.ChangeType) + { + case VisualChangeType.Recalc: + foreach (BaseSeries series in BaseSeries) + series.InvalidateRecalc(); + break; + + case VisualChangeType.Layout: + InvalidateLayout(); + break; + + default: + InvalidateRender(); + break; + } + } + + if (e is VisualPropertyChangedEventArgs) + OnPropertyChangedEx(e.PropertyName, ((VisualPropertyChangedEventArgs)e).ChangeType); + } + + #endregion + + #endregion + + #region UseAlternateGridBackground + + /// + /// Gets or sets whether the chart utilizes the alternate background color + /// when ShowPieGrid is enabled. + /// + [DefaultValue(false), Category("Grid")] + [Description("Indicates whether the chart utilizes the alternate background color when ShowPieGrid is enabled.")] + public bool UseAlternateGridBackground + { + get { return (TestState(States.UseAlternateGridBackground)); } + + set + { + if (value != UseAlternateGridBackground) + { + SetState(States.UseAlternateGridBackground, value); + + OnPropertyChangedEx("UseAlternateGridBackground", VisualChangeType.Render); + } + } + } + + #endregion + + #region WhitespaceClickBehavior + + /// + /// Gets or sets the behavior when the user + /// clicks the mouse in the chart whitespace. + /// + [DefaultValue(WhitespaceClickBehavior.ClearSelection), Category("Behavior")] + [Description("Indicates the behavior when the user clicks the mouse in the chart whitespace.")] + public WhitespaceClickBehavior WhitespaceClickBehavior + { + get { return (_WhitespaceClickBehavior); } + + set + { + if (value != _WhitespaceClickBehavior) + { + _WhitespaceClickBehavior = value; + + OnPropertyChanged("WhitespaceClickBehavior"); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region ExplodedOffsetEx + + internal double ExplodedOffsetEx + { + get + { + if (double.IsNaN(_ExplodedOffsetEx) == true) + _ExplodedOffsetEx = GetExplodedOffset(); + + return (_ExplodedOffsetEx); + } + } + + #region GetExplodedOffset + + internal double GetExplodedOffset() + { + if (IsExploded == true) + { + if (ExplodedOffset > 0) + { + if (ExplodedOffset >= 1) + return (ExplodedOffset); + + return (OuterRadiusEx * ExplodedOffset); + } + } + + return (0); + } + + #endregion + + #endregion + + #region GlobalSelectionCount + + internal uint GlobalSelectionCount + { + get { return (_GlobalSelectionCount); } + set { _GlobalSelectionCount = value; } + } + + #endregion + + #region GridInnerRadiusEx + + internal double GridInnerRadiusEx + { + get + { + if (double.IsNaN(_GridInnerRadiusEx) == true) + { + _GridInnerRadiusEx = GridInnerRadius; + + if (_GridInnerRadiusEx > 0) + { + if (PieRadiusScale == PieRadiusScale.Percentage || _GridInnerRadiusEx <= 1) + _GridInnerRadiusEx *= OuterRadiusEx; + } + + _GridInnerRadiusEx += InnerRadiusEx; + } + + return (_GridInnerRadiusEx); + } + } + + #endregion + + #region GridOuterRadiusEx + + internal double GridOuterRadiusEx + { + get + { + if (double.IsNaN(_GridOuterRadiusEx) == true) + { + _GridOuterRadiusEx = GridOuterRadius; + + if (_GridOuterRadiusEx > 0) + { + if (PieRadiusScale == PieRadiusScale.Percentage || _GridOuterRadiusEx <= 1) + _GridOuterRadiusEx *= OuterRadiusEx; + } + } + + return (_GridOuterRadiusEx); + } + } + + #endregion + + #region HitPsp + + internal PieSeriesPoint HitPsp + { + get { return (_HitPsp); } + set { _HitPsp = value; } + } + + #endregion + + #region InnerMarginEx + + internal double InnerMarginEx + { + get + { + if (double.IsNaN(_InnerMarginEx) == true) + _InnerMarginEx = GetInnerMargin(); + + return (_InnerMarginEx); + } + } + + #region GetInnerMargin + + private double GetInnerMargin() + { + if (InnerMargin <= 0) + return (0); + + if (PieRadiusScale == PieRadiusScale.Percentage || InnerMargin <= 1) + return (InnerMargin * OuterRadiusEx); + + return (InnerMargin); + } + + #endregion + + #endregion + + #region InnerRadiusEx + + internal double InnerRadiusEx + { + get + { + if (double.IsNaN(_InnerRadiusEx) == true) + _InnerRadiusEx = GetInnerRadius(); + + return (_InnerRadiusEx); + } + } + + #region GetInnerRadius + + private double GetInnerRadius() + { + if (InnerRadius > 0) + { + if (PieRadiusScale == PieRadiusScale.Percentage || InnerRadius <= 1) + return (InnerRadius * OuterRadiusEx); + + return (InnerRadius); + } + + return (0); + } + + #endregion + + #endregion + + #region IsDragging + + internal bool IsDragging + { + get { return (TestState(States.Dragging)); } + set { SetState(States.Dragging, value); } + } + + #endregion + + #region MaxPieOuterExtent + + internal double MaxPieOuterExtent + { + get { return (_MaxPieOuterExtent); } + set { _MaxPieOuterExtent = value; } + } + + #endregion + + #region OuterRadiusEx + + internal double OuterRadiusEx + { + get + { + if (double.IsNaN(_OuterRadiusEx) == true) + { + _OuterRadiusEx = OuterRadiusExx; + + if (OuterMargin > 0) + { + if (OuterMargin >= 1) + _OuterRadiusEx -= OuterMargin; + else + _OuterRadiusEx -= (_OuterRadiusEx * OuterMargin); + } + + _OuterRadiusEx = Math.Max(0, _OuterRadiusEx); + } + + return (_OuterRadiusEx); + } + } + + #endregion + + #region OuterRadiusExx + + internal double OuterRadiusExx + { + get + { + double radius = OuterRadius; + + if (radius > 0) + { + if (PieRadiusScale == PieRadiusScale.Percentage || radius <= 1) + radius *= (Math.Min(ContentBoundsEx.Width, ContentBoundsEx.Height) / 2); + } + + return (Math.Max(MinOuterRadius, radius)); + } + } + + #endregion + + #region PspDragType + + internal PspDragType PspDragType + { + get { return (_PspDragType); } + set { _PspDragType = value; } + } + + #endregion + + #region RingOutRadius + + internal int RingOutRadius + { + get + { + PieSeries series = GetInnerSeries(); + + if (series != null) + { + double radius = InnerRadiusEx; + + if (InnerMarginEx > 0) + radius -= InnerMarginEx; + + if (ShowAllRingsEx == true) + { + if (ExplodedOffsetEx > 0) + { + radius += ExplodedOffsetEx; + radius -= GetExplodedMargin(series); + } + } + + radius = Math.Min(radius, Dpi.Width(MaxRingOutRadius)); + + return (int)(Math.Max(0, radius)); + } + + return (0); + } + } + + #endregion + + #region RingWeightTotal + + internal int RingWeightTotal + { + get { return (_RingWeightTotal); } + set { _RingWeightTotal = value; } + } + + #endregion + + #region UpdatePaletteNeeded + + internal bool UpdatePaletteNeeded + { + get { return (TestState(States.UpdatePaletteNeeded)); } + set { SetState(States.UpdatePaletteNeeded, value); } + } + + #endregion + + #endregion + + #region OnResize + + protected override bool OnResize(EventArgs e) + { + InvalidateValueCache(); + + return (base.OnResize(e)); + } + + #region InvalidateValueCache + + private void InvalidateValueCache() + { + _InnerRadiusEx = double.NaN; + _OuterRadiusEx = double.NaN; + + _GridInnerRadiusEx = double.NaN; + _GridOuterRadiusEx = double.NaN; + + _ExplodedOffsetEx = double.NaN; + + _InnerMarginEx = double.NaN; + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + ContainerVisualStyle cStyle = GetEffectiveContainerStyle(); + PieChartVisualStyle pieStyle = EffectiveChartStyle; + + BoundsRelative = layoutInfo.LayoutBounds; + + UpdateDataBindings(); + + _PieLabels = null; + + Rectangle oldFrameBounds = FrameBounds; + + FrameBounds = GetAdjustedBounds(BoundsRelative, cStyle.Margin); + FrameBounds = GetAdjustedBounds(FrameBounds, cStyle.Padding); + FrameBounds = GetAdjustedBounds(FrameBounds, pieStyle.Margin); + + if (FrameBounds != oldFrameBounds) + SeriesPointCount++; + + ContentBounds = GetAdjustedBounds(FrameBounds, cStyle.BorderThickness); + ContentBounds = GetAdjustedBounds(ContentBounds, pieStyle.BorderThickness); + ContentBounds = GetAdjustedBounds(ContentBounds, pieStyle.Padding); + + layoutInfo.LayoutBounds = ContentBounds; + + foreach (ChartTitle title in Titles) + { + if (title.Visible == true) + title.Measure(layoutInfo); + } + + if (pieStyle.DropShadow.Enabled == Tbool.True) + layoutInfo.LayoutBounds = GetShadowBounds(layoutInfo.LayoutBounds); + + MeasureSeries(layoutInfo); + + if (Legend.Visible == true) + Legend.Measure(layoutInfo); + + Rectangle oldContentBoundsEx = ContentBoundsEx; + + ContentBounds = layoutInfo.LayoutBounds; + ContentBoundsEx = ContentBounds; + + Rectangle r = ContentBounds; + + r.Size = new Size( + Math.Max(r.Size.Width, Dpi.Width(MinContentSize.Width)), + Math.Max(r.Size.Height, Dpi.Height(MinContentSize.Height))); + + // Since our vertical scrollbar is reversed, we + // need to adjust the extended content area accordingly + + if (r.Height > ContentBounds.Height) + r.Y -= (r.Height - ContentBounds.Height); + + ContentBoundsEx = r; + + FinalizeDataBindings(); + + InvalidateValueCache(); + } + + #region MeasureSeries + + private void MeasureSeries(ChartLayoutInfo layoutInfo) + { + PieSeries[] aseries = new PieSeries[ChartSeries.Count]; + + ChartSeries.CopyTo(aseries, 0); + + foreach (PieSeries series in aseries) + { + if (series.IsDisplayed == true) + series.Measure(layoutInfo); + } + + if (SeriesRangeChanged == true) + { + SeriesRangeChanged = false; + UpdatePaletteNeeded = true; + + RingWeightTotal = 0; + MaxPieOuterExtent = 0; + + for (int i = 0; i < aseries.Length; i++) + { + PieSeries series = aseries[i]; + + if (series.IsDisplayed == true) + RingWeightTotal += series.RingWeight; + + MeasurePieSlices(series, series.SeriesPoints); + + if (series.PieOuterExtent > MaxPieOuterExtent) + MaxPieOuterExtent = series.PieOuterExtent; + } + + if (SeriesOverlayEnabled == true) + UpdateSeriesOverlayValues(aseries); + } + + if (UpdatePaletteNeeded == true) + { + UpdatePaletteNeeded = false; + + int colorIndex = 0; + + for (int i = 0; i < aseries.Length; i++) + UpdateSeriesPalette(aseries[i], ref colorIndex); + } + } + + #region MeasurePieSlices + + private void MeasurePieSlices(PieSeries series, PieSeriesPointCollection spc) + { + if (spc != null && spc.Count > 0) + { + int ringLevel = 0; + + series.PieRings.Clear(); + + CalculatePieTotals(series, spc, ringLevel); + CalculateRingTotal(series); + CalculateSliceValues(spc); + + GatherPieSlices(series, spc); + } + } + + #region GetMaxSlices + + private int GetMaxSlices(PieSeriesPointCollection spc) + { + int maxSlices = spc.Parent.SubSliceVisualLayout.MaxSlices; + + if (maxSlices < 0) + maxSlices = SubSliceVisualLayout.MaxSlices; + + return ((maxSlices >= 0) ? maxSlices : 100); + } + + #endregion + + #region GetMinPercent + + private double GetMinPercent(PieSeriesPointCollection spc) + { + double minPercent = spc.Parent.SubSliceVisualLayout.MinPercent; + + if (double.IsNaN(minPercent) || minPercent < 0) + minPercent = SubSliceVisualLayout.MinPercent; + + if (double.IsNaN(minPercent) == true || minPercent < 0) + minPercent = .04d; + + return (minPercent); + } + + #endregion + + #region CalculatePieTotals + + private void CalculatePieTotals( + PieSeries series, PieSeriesPointCollection spc, int ringLevel) + { + if (spc.Count > 0) + { + spc.PieTotal = 0; + spc.PieTotalExtent = 0; + + spc.PieMinExtent = double.MaxValue; + spc.PieMaxExtent = 0; + + spc.PieRing = GetPieRingAtLevel(series, ringLevel); + + int ringWeight = spc.PieRing.RingWeight; + int maxSlices = GetMaxSlices(spc); + + int sliceCount = 0; + + bool showOtherSlices = series.ShowOtherSliceEx(this); + + foreach (PieSeriesPoint psp in spc) + { + if (psp != null && psp.Visible == true) + { + if (psp.ValueY.Length > 0) + { + sliceCount++; + + double d = Convert.ToDouble(psp.ValueY[0]); + spc.PieTotal += d; + + psp.PieRing = spc.PieRing; + + if (psp.ValueY.Length > 1) + { + d = Convert.ToDouble(psp.ValueY[1]); + + spc.PieTotalExtent += d; + + if (d > spc.PieMaxExtent) + spc.PieMaxExtent = d; + + if (d < spc.PieMinExtent) + spc.PieMinExtent = d; + + psp.HasExtent = true; + } + + if (psp.RingWeightEx >= 0) + { + if (psp.RingWeightEx > ringWeight) + ringWeight = psp.RingWeightEx; + } + + spc.PieRing.Psps.Add(psp); + + if (psp.SeriesPoints != null) + CalculatePieTotals(series, psp.SeriesPoints, ringLevel + 1); + } + } + + spc.PieOuterExtent = Math.Max(psp.MinExtentEx, spc.PieMaxExtent); + + if (spc.PieOuterExtent > series.PieOuterExtent) + series.PieOuterExtent = spc.PieOuterExtent; + + if (showOtherSlices == false && sliceCount >= maxSlices) + break; + } + + spc.PieRing.RingWeight = (ringWeight < 0) ? 100 : ringWeight; + + int visCount = spc.VisibleCount; + + spc.PieAverage = ((visCount > 0) ? (spc.PieTotal / visCount) : 0); + spc.PieAverageExtent = ((visCount > 0) ? (spc.PieTotalExtent / visCount) : 0); + } + } + + #region GetPieRingAtLevel + + private PieRing GetPieRingAtLevel(PieSeries series, int ringLevel) + { + foreach (PieRing ring in series.PieRings) + { + if (ring.RingLevel == ringLevel) + return (ring); + } + + PieRing pieRing = new PieRing(ringLevel); + pieRing.ChartSeries = series; + + series.PieRings.Add(pieRing); + + return (pieRing); + } + + #endregion + + #endregion + + #region CalculateRingTotal + + private void CalculateRingTotal(PieSeries series) + { + int ringTotal = 0; + + foreach (PieRing ring in series.PieRings) + ringTotal += ring.RingWeight; + + series.RingWeightTotal = ringTotal; + } + + #endregion + + #region CalculateSliceValues + + private void CalculateSliceValues(PieSeriesPointCollection spc) + { + if (spc != null) + { + foreach (PieSeriesPoint psp in spc) + { + if (psp != null && psp.Visible == true) + { + psp.SliceValue = 0; + psp.SliceExtent = 1; + + if (psp.ValueY.Length > 0) + { + double d = Convert.ToDouble(psp.ValueY[0]); + + psp.SliceValue = (spc.PieTotal > 0) ? (d / spc.PieTotal) : 0; + + if (spc.PieOuterExtent > 0 && psp.ValueY.Length > 1) + { + d = Convert.ToDouble(psp.ValueY[1]); + + psp.SliceExtent = d / spc.PieOuterExtent; + } + + CalculateSliceValues(psp.SeriesPoints); + } + } + } + } + } + + #endregion + + #region GatherPieSlices + + private void GatherPieSlices(PieSeries series, PieSeriesPointCollection spc) + { + int maxSlices = GetMaxSlices(spc); + double minPercent = GetMinPercent(spc); + + PieSeriesPointCollection pieSlices = GetNewListSpc(spc); + PieSeriesPointCollection otherSlices = null; + + if (series.ShowOtherSliceEx(this) == true) + { + otherSlices = GetNewListSpc(spc); + otherSlices.IsOther = true; + } + + for (int i = 0; i < spc.Count; i++) + { + AddPieSeriesPoint(series, spc, + maxSlices, minPercent, i, pieSlices, otherSlices); + + if (otherSlices == null && pieSlices.Count >= maxSlices) + break; + } + + if (otherSlices != null && otherSlices.Count > 0) + { + double value = 0; + double extent = 0; + + foreach (PieSeriesPoint psp in otherSlices) + { + if (psp.ValueY.Length > 0) + value += Convert.ToDouble(psp.ValueY[0]); + + if (psp.ValueY.Length > 1) + { + double d = Convert.ToDouble(psp.ValueY[1]); + + if (d > extent) + extent = value; + } + } + + PieSeriesPoint opsp = spc.OtherSlicePsp; + + opsp.ValueX = "Other"; + opsp.ValueY[0] = value; + opsp.ValueY[1] = extent; + + opsp.IsOther = true; + opsp.PieRing = spc.PieRing; + + opsp.SliceValue = (spc.PieTotal > 0) ? (value / spc.PieTotal) : 0; + opsp.SliceExtent = (spc.PieOuterExtent > 0) ? (extent / spc.PieOuterExtent) : 1; + + pieSlices.Add(opsp); + + spc.PieRing.Psps.Add(opsp); + } + + spc.PieSlices = pieSlices; + spc.OtherSlices = otherSlices; + } + + #region GetNewListSpc + + private PieSeriesPointCollection GetNewListSpc(PieSeriesPointCollection spc) + { + PieSeriesPointCollection spcNew = new PieSeriesPointCollection(); + + spcNew.PieAverage = spc.PieAverage; + spcNew.PieTotal = spc.PieTotal; + + spcNew.PieAverageExtent = spc.PieAverageExtent; + spcNew.PieMaxExtent = spc.PieMaxExtent; + spcNew.PieMinExtent = spc.PieMinExtent; + spcNew.PieOuterExtent = spc.PieOuterExtent; + spcNew.PieTotalExtent = spc.PieTotalExtent; + + spcNew.PieRing = spc.PieRing; + spcNew.Parent = spc.Parent; + + return (spcNew); + } + + #endregion + + #region AddPieSeriesPoint + + private void AddPieSeriesPoint(PieSeries series, + PieSeriesPointCollection spc, int maxSlices, double minPercent, + int index, PieSeriesPointCollection pieSlices, PieSeriesPointCollection otherSlices) + { + PieSeriesPoint psp = spc[index] as PieSeriesPoint; + + if (psp != null && psp.Visible == true) + { + psp.IsInOtherEx = ((otherSlices != null) && + (psp.IsInOther || (pieSlices.Count >= maxSlices || psp.SliceValue < minPercent))); + + if (psp.IsInOtherEx == true) + { + psp.OrdinalValue = otherSlices.Count; + otherSlices.Add(psp); + } + else + { + psp.OrdinalValue = pieSlices.Count; + pieSlices.Add(psp); + } + + GatherPieSlices(series, psp.SeriesPoints); + } + } + + #endregion + + #endregion + + #endregion + + #region UpdateSeriesOverlayValues + + private void UpdateSeriesOverlayValues(PieSeries[] aseries) + { + for (int i = 0; i < aseries.Length; i++) + { + PieSeries series = aseries[i]; + + if (series.IsDisplayed == true) + UpdatePspOverlayValues(series, series.SeriesPoints.PieSlices); + } + } + + #region UpdatePspOverlayValues + + private void UpdatePspOverlayValues(PieSeries series, PieSeriesPointCollection spc) + { + if (spc != null && spc.Count > 0) + { + if (spc.PieOuterExtent != MaxPieOuterExtent) + { + spc.PieOuterExtent = MaxPieOuterExtent; + + CalculateSliceValues(spc); + } + } + } + + #endregion + + #endregion + + #region UpdateSeriesPalette + + private void UpdateSeriesPalette(PieSeries series, ref int colorIndex) + { + if (series.UpdatePalette(this) == false) + { + foreach (PieRing pieRing in series.PieRings) + { + foreach (PieSeriesPoint psp in pieRing.Psps) + psp.DefaultPaletteColor = GetPaletteColor(colorIndex++); + } + } + } + + #endregion + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + int vmax = VScrollBar.LargeChange; + + base.ArrangeOverride(layoutInfo); + + if (VScrollBar.LargeChange != vmax) + SeriesPointCount++; + + CalcPieCenter(layoutInfo); + + if (RingWeightTotal > 0) + ArrangeSeries(layoutInfo); + + SeriesLayoutCount++; + } + + #region CalcPieCenter + + private void CalcPieCenter(ChartLayoutInfo layoutInfo) + { + Rectangle bounds = ContentBoundsEx; + Point centerPos = Point.Empty; + + centerPos.X = bounds.X + bounds.Width / 2; + centerPos.Y = bounds.Y + bounds.Height / 2; + + if (CenterPos.X >= -1 && CenterPos.X <= 1) + { + if (CenterPos.X != 0.0) + centerPos.X += (int)(bounds.Width * CenterPos.X); + } + else + { + centerPos.X += (int)CenterPos.X; + } + + if (CenterPos.Y >= -1 && CenterPos.Y <= 1) + { + if (CenterPos.Y != 0.0) + centerPos.Y += (int)(bounds.Height * CenterPos.Y); + } + else + { + centerPos.Y += (int)CenterPos.Y; + } + + CenterPoint = centerPos; + } + + #endregion + + #region ArrangeSeries + + private void ArrangeSeries(ChartLayoutInfo layoutInfo) + { + if (ChartSeries.Count > 0) + { + List pieSeries = GetVisibleSeries(); + + if (pieSeries.Count > 0) + { + UpdatePieRingList(); + + PieChartVisualStyle pStyle = EffectiveChartStyle; + + int innerRadius = (int)(ReverseRingOrder ? OuterRadiusEx : InnerRadiusEx); + int outerRadius = (int)(ReverseRingOrder ? InnerRadiusEx : OuterRadiusEx); + + double ringWidth = Math.Max(0, (OuterRadiusEx - InnerRadiusEx)); + + double width = ringWidth; + int seriesMargin = GetSeriesMargin(); + + if (SeriesOverlayEnabled == false) + { + if (pieSeries.Count > 1) + width -= (pieSeries.Count - 1) * seriesMargin; + } + + bool revOrder = (SeriesDisplayOrder == SeriesDisplayOrder.Reverse) ^ (ReverseRingOrder == true); + + if (revOrder == true) + { + for (int i = pieSeries.Count - 1; i >= 0; i--) + ArrangeSeriesEx(layoutInfo, pieSeries[i], pStyle, ref outerRadius, width, seriesMargin); + } + else + { + for (int i = 0; i < pieSeries.Count; i++) + ArrangeSeriesEx(layoutInfo, pieSeries[i], pStyle, ref outerRadius, width, seriesMargin); + } + + AdjustSeriesWidths(pieSeries, seriesMargin); + } + } + } + + #region AdjustSeriesWidths + + private void AdjustSeriesWidths(List pieSeries, int seriesMargin) + { + int pieWidth = (int)(OuterRadiusEx - InnerRadiusEx); + + if (SeriesOverlayEnabled == false) + pieWidth -= ((pieSeries.Count - 1) * seriesMargin); + + int seriesWidth = 0; + + foreach (PieSeries series in pieSeries) + { + seriesWidth += series.RingWeightEx; + + if (SeriesOverlayEnabled == true) + break; + } + + if (seriesWidth < pieWidth) + { + int n = 0; + int count = pieWidth - seriesWidth; + + for (int i = 0; i < pieSeries.Count; i++) + { + PieSeries series = pieSeries[i]; + + if (i < count) + series.RingWeightEx++; + + AdjustRingWidths(series, n); + + if (i < count) + n++; + } + } + } + + #region AdjustRingWidths + + private void AdjustRingWidths(PieSeries series, int offset) + { + int seriesWidth = series.RingWeightEx; + + int ringWidth = 0; + + foreach (PieRing pieRing in series.PieRings) + ringWidth += (pieRing.OuterRadius - pieRing.InnerRadius); + + int n = 0; + int count = seriesWidth - ringWidth; + + if (ReverseRingOrder == true) + { + for (int i = series.PieRings.Count - 1; i >= 0; i--) + { + PieRing pieRing = series.PieRings[i]; + + pieRing.InnerRadius += offset; + pieRing.OuterRadius += offset; + + if (n < count) + { + pieRing.InnerRadius += n; + pieRing.OuterRadius += (n + 1); + + n++; + } + + AdjustPspWidths(pieRing); + } + } + else + { + for (int i = 0; i < series.PieRings.Count; i++) + { + PieRing pieRing = series.PieRings[i]; + + pieRing.OuterRadius -= offset; + pieRing.InnerRadius -= offset; + + if (n < count) + { + pieRing.OuterRadius -= n; + pieRing.InnerRadius -= (n + 1); + + n++; + } + + AdjustPspWidths(pieRing); + } + } + } + + #region AdjustPspWidths + + private void AdjustPspWidths(PieRing pieRing) + { + int ringWidth = (pieRing.OuterRadius - pieRing.InnerRadius); + + foreach (PieSeriesPoint psp in pieRing.Psps) + { + psp.OuterRadius = pieRing.OuterRadius; + psp.InnerRadius = pieRing.InnerRadius; + } + } + + #endregion + + #endregion + + #endregion + + #region GetVisibleSeries + + private List GetVisibleSeries() + { + List pieSeries = new List(); + + foreach (PieSeries series in ChartSeries) + { + if (series.IsDisplayed == true) + pieSeries.Add(series); + } + + return (pieSeries); + } + + #endregion + + #region UpdatePieRingList + + private void UpdatePieRingList() + { + PieRing innerRing = null; + PieRing outerRing = null; + + if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse) + { + for (int i = ChartSeries.Count - 1; i >= 0; i--) + UpdatePieRingListEx(ChartSeries[i], ref innerRing, ref outerRing); + } + else + { + for (int i = 0; i < ChartSeries.Count; i++) + UpdatePieRingListEx(ChartSeries[i], ref innerRing, ref outerRing); + } + + if (innerRing != null) + { + innerRing.IsInnerRing = true; + innerRing.ChartSeries.IsInnerRingSeries = true; + } + + if (outerRing != null) + { + outerRing.IsOuterRing = true; + outerRing.ChartSeries.IsOuterRingSeries = true; + } + } + + #region UpdatePieRingListEx + + private void UpdatePieRingListEx( + PieSeries series, ref PieRing innerRing, ref PieRing outerRing) + { + if (series.IsDisplayed == true) + { + if (series.PieRings.Count > 0) + { + if (ReverseRingOrder == true) + { + if (outerRing == null) + outerRing = series.PieRings[series.PieRings.Count - 1]; + + innerRing = series.PieRings[0]; + } + else + { + if (outerRing == null) + outerRing = series.PieRings[0]; + + innerRing = series.PieRings[series.PieRings.Count - 1]; + } + + series.IsInnerRingSeries = false; + series.IsOuterRingSeries = false; + + for (int j = 0; j < series.PieRings.Count; j++) + { + PieRing pieRing = series.PieRings[j]; + + pieRing.IsOuterRing = false; + pieRing.IsInnerRing = false; + } + } + } + } + + #endregion + + #endregion + + #region GetSeriesMargin + + private int GetSeriesMargin() + { + //if (SeriesMargin <= 0) + // return (0); + + if (Math.Abs(SeriesMargin) >= 1) + return ((int)SeriesMargin); + + return (int)(SeriesMargin * (OuterRadiusEx - InnerRadiusEx)); + } + + #endregion + + #region ArrangeSeriesEx + + private void ArrangeSeriesEx(ChartLayoutInfo layoutInfo, PieSeries series, + PieChartVisualStyle pStyle, ref int outerRadius, double dwidth, int seriesMargin) + { + if (series.IsDisplayed == true) + { + series.Arrange(layoutInfo); + + int width = (SeriesOverlayEnabled == false) + ? (int)(dwidth * ((double)series.RingWeight / RingWeightTotal)) + : (int)(dwidth); + + ArrangePieSlices(series, outerRadius, width); + + series.RingWeightEx = width; + + if (SeriesOverlayEnabled == false) + { + if (ReverseRingOrder == true) + { + if (series.IsOuterRingSeries == false) + width += seriesMargin; + + outerRadius += width; + } + else + { + if (series.IsInnerRingSeries == false) + width += seriesMargin; + + outerRadius -= width; + } + } + } + } + + #region ArrangePieSlices + + private void ArrangePieSlices(PieSeries series, int outerRadius, int width) + { + series.IsOffset = false; + + PieSeriesPointCollection spc = series.GetActiveSeriesPointCollection(); + + if (spc != null) + { + if (spc.PieSlices != null) + spc = spc.PieSlices; + + if (spc != null && spc.Count > 0) + { + int sweepDir = GetSweepDirEx(series); + double sweepAngle = GetSweepAngle(series); + + CalculateSweepAngles(spc, spc.PieTotal, sweepAngle, sweepDir); + + double startAngle = GetStartAngle(series); + bool centerFirstSlice = GetCenterFirstSlice(series); + + ArrangePieSlicesEx(series, spc, + outerRadius, width, startAngle, centerFirstSlice); + } + } + } + + #region GetCenterFirstSlice + + private bool GetCenterFirstSlice(PieSeries series) + { + Tbool centerSlice = series.CenterFirstSlice; + + if (centerSlice == Tbool.NotSet) + centerSlice = CenterFirstSlice; + + return (centerSlice == Tbool.True); + } + + #endregion + + #region GetSweepDirEx + + internal int GetSweepDirEx(PieSeries series) + { + SweepDirection sweepDir = series.SubSliceVisualLayout.SweepDirection; + + if (sweepDir == SweepDirection.NotSet) + sweepDir = SubSliceVisualLayout.SweepDirection; + + return (sweepDir == SweepDirection.CounterClockwise) ? -1 : 1; + } + + #endregion + + #region GetSweepAngle + + private double GetSweepAngle(PieSeries series) + { + double sweepAngle = series.SubSliceVisualLayout.SweepAngle; + + if (double.IsNaN(sweepAngle) == false) + return (sweepAngle); + + sweepAngle = SubSliceVisualLayout.SweepAngle; + + return (double.IsNaN(sweepAngle) == false ? sweepAngle : 360d); + } + + #endregion + + #region GetStartAngle + + private double GetStartAngle(PieSeries series) + { + double startAngle = series.SubSliceVisualLayout.StartAngle; + + if (double.IsNaN(startAngle) == false) + return (startAngle); + + startAngle = SubSliceVisualLayout.StartAngle; + + return (double.IsNaN(startAngle) == false ? startAngle : 270d); + } + + #endregion + + #region CalculateSweepAngles + + private void CalculateSweepAngles + (PieSeriesPointCollection spc, double pieTotal, double degrees, int sweepDir) + { + if (spc != null && spc.Count > 0) + { + if (pieTotal > 0) + { + foreach (PieSeriesPoint psp in spc) + { + psp.SweepAngleEx = 0; + psp.AngleMarginExx = 0; + + if (double.IsNaN(psp.SweepAngle) == false) + psp.SweepAngleEx = psp.SweepAngle; + else + psp.SweepAngleEx = psp.SliceValue * degrees; + + if (psp.AngleMarginEx > 0) + { + psp.AngleMarginExx = psp.AngleMarginEx; + + if (psp.SweepAngleEx < (psp.AngleMarginEx * 2)) + psp.AngleMarginExx = psp.SweepAngleEx / 2 - 1; + + if (psp.AngleMarginExx > 0) + psp.SweepAngleEx -= (psp.AngleMarginExx * 2); + } + + CalculateSweepAngles( + psp.SeriesPoints.PieSlices, psp.SeriesPoints.PieTotal, psp.SweepAngleEx, sweepDir); + + psp.SweepAngleEx *= sweepDir; + } + } + } + } + + #endregion + + #region ArrangePieSlicesEx + + private void ArrangePieSlicesEx(PieSeries series, + PieSeriesPointCollection spc, int outerRadius, int width, double sliceAngle, bool centerSlice) + { + if (spc.PieSlices != null) + spc = spc.PieSlices; + + if (spc != null && spc.Count > 0) + { + if (series.ShowAllRingsEx(this) == true) + { + ArrangeAllPieRings(series, + spc, outerRadius, width, sliceAngle, centerSlice); + } + else + { + ArrangeSinglePieRing(series, + spc, outerRadius, width, sliceAngle, centerSlice); + } + } + } + + #region ArrangeAllPieRings + + private void ArrangeAllPieRings(PieSeries series, + PieSeriesPointCollection spc, int outerRadius, int width, double startAngle, bool centerSlice) + { + if (series.RingWeightTotal != 0) + { + if (spc.PieRing != null) + { + int awidth = (int)(width * + (double)spc.PieRing.RingWeight / series.RingWeightTotal); + + int innerRadius = outerRadius - ((ReverseRingOrder == true) ? -awidth : awidth); + + spc.PieRing.OuterRadius = (ReverseRingOrder == true) ? innerRadius : outerRadius; + spc.PieRing.InnerRadius = (ReverseRingOrder == true) ? outerRadius : innerRadius; + + int sdir = GetSweepDirEx(series); + + for (int i = 0; i < spc.Count; i++) + { + PieSeriesPoint psp = spc[i] as PieSeriesPoint; + + if (psp != null) + { + psp.StartAngleEx = (startAngle + 360000) % 360; + startAngle += psp.SweepAngleEx; + + if (double.IsNaN(psp.StartAngle) == false) + psp.StartAngleEx = psp.StartAngle; + + if (centerSlice == true) + { + centerSlice = false; + + startAngle -= (psp.SweepAngleEx / 2); + psp.StartAngleEx -= (int)((psp.SweepAngleEx + psp.AngleMarginExx * sdir) / 2); + } + + if (psp.AngleMarginExx > 0) + { + double n = psp.AngleMarginExx * sdir; + + startAngle += (n * 2); + psp.StartAngleEx += n; + } + + psp.OuterRadius = spc.PieRing.OuterRadius; + psp.InnerRadius = spc.PieRing.InnerRadius; + + int extentRadius = (int)psp.ExtentRadius; + + if (extentRadius > spc.PieRing.ExtentRadius) + spc.PieRing.ExtentRadius = extentRadius; + + PieSeriesPoint pspParent = spc.Parent as PieSeriesPoint; + + if (pspParent == null) + { + psp.SliceCenter = GetSliceCenter(series, spc, psp); + } + else + { + psp.SliceCenter = pspParent.SliceCenter; + psp.IsOffset = pspParent.IsOffset; + + double offset = GetDetachedOffset(psp); + + if (offset > 0) + { + double centerAngle = psp.CenterAngle; + double radians = MathHelper.ToRadians(centerAngle); + + Point pt = psp.SliceCenter; + + pt.X += (int)(Math.Cos(radians) * offset); + pt.Y += (int)(Math.Sin(radians) * offset); + + psp.SliceCenter = pt; + + psp.IsOffset = psp.SliceCenter.Equals(CenterPoint); + } + } + + ArrangePieSlicesEx(series, + psp.SeriesPoints, innerRadius, width, psp.StartAngleEx, false); + + psp.PathBounds = Rectangle.Empty; + } + } + } + } + } + + #endregion + + #region ArrangeSinglePieRing + + private int ArrangeSinglePieRing(PieSeries series, + PieSeriesPointCollection spc, int outerRadius, int width, double startAngle, bool centerSlice) + { + int innerRadius = outerRadius - ((ReverseRingOrder == true) ? -width : width); + + bool isInnerRing = false; + bool isOuterRing = false; + + GetRingBorderState(series, spc, ref isOuterRing, ref isInnerRing); + + spc.PieRing.OuterRadius = (ReverseRingOrder == true) ? innerRadius : outerRadius; + spc.PieRing.InnerRadius = (ReverseRingOrder == true) ? outerRadius : innerRadius; + + int vcount = spc.VisibleCount; + + int sdir = GetSweepDirEx(series); + + for (int i = 0; i < spc.Count; i++) + { + PieSeriesPoint psp = spc[i] as PieSeriesPoint; + + if (psp != null) + { + psp.StartAngleEx = (startAngle + 360000) % 360; + startAngle += psp.SweepAngleEx; + + if (double.IsNaN(psp.StartAngle) == false) + psp.StartAngleEx = psp.StartAngle; + + if (centerSlice == true) + { + centerSlice = false; + + startAngle -= (psp.SweepAngleEx / 2); + psp.StartAngleEx -= (int)((psp.SweepAngleEx + psp.AngleMarginExx * sdir) / 2); + } + + if (psp.AngleMarginExx > 0) + { + double n = psp.AngleMarginExx * sdir; + + startAngle += (n * 2); + psp.StartAngleEx += n; + } + + psp.OuterRadius = spc.PieRing.OuterRadius; + psp.InnerRadius = spc.PieRing.InnerRadius; + + psp.SliceCenter = GetSliceCenter(series, spc, psp); + + spc.PieRing.OuterRadius = psp.OuterRadius; + spc.PieRing.InnerRadius = psp.InnerRadius; + + int extentRadius = (int)psp.ExtentRadius; + + if (extentRadius > spc.PieRing.ExtentRadius) + spc.PieRing.ExtentRadius = extentRadius; + + psp.PathBounds = Rectangle.Empty; + } + } + + return (Math.Abs(outerRadius - innerRadius)); + } + + #endregion + + #region AdjustForAngleMargin + + private void AdjustForAngleMargin(PieSeries series, PieSeriesPoint psp) + { + double angleMargin = psp.AngleMarginExx; + + if (angleMargin != 0) + { + if (angleMargin != 0) + { + angleMargin *= GetSweepDirEx(series); + + psp.StartAngleEx += (angleMargin); + psp.SweepAngleEx -= (angleMargin * 2); + } + } + } + + #endregion + + #region GetRingBorderState + + private void GetRingBorderState(PieSeries series, + PieSeriesPointCollection spc, ref bool isOuterRing, ref bool isInnerRing) + { + if (series.IsInnerRingSeries == true) + { + if (series.ShowAllRingsEx(this) == true) + isInnerRing = spc.PieRing.IsInnerRing; + else + isInnerRing = true; + } + + if (series.IsOuterRingSeries == true) + { + if (series.ShowAllRingsEx(this) == true) + isOuterRing = spc.PieRing.IsOuterRing; + else + isOuterRing = true; + } + } + + #endregion + + #region GetSliceCenter + + private Point GetSliceCenter(PieSeries series, + PieSeriesPointCollection spc, PieSeriesPoint psp) + { + Point sliceCenter = CenterPoint; + + if (IsExploded == false && psp.IsDetached == false) + return (sliceCenter); + + double offset = GetPspOffset(series, psp); + + psp.IsOffset = false; + + if (offset > 0) + { + if (spc.Count > 1) + { + double centerAngle = psp.StartAngleEx + psp.SweepAngleEx / 2; + double radians = MathHelper.ToRadians(centerAngle); + + sliceCenter.X += (int)(Math.Cos(radians) * offset); + sliceCenter.Y += (int)(Math.Sin(radians) * offset); + + psp.IsOffset = true; + series.IsOffset = true; + } + else + { + psp.InnerRadius += (int)offset; + psp.OuterRadius += (int)offset; + } + } + + return (sliceCenter); + } + + #region GetPspOffset + + internal double GetPspOffset(PieSeries series, PieSeriesPoint psp) + { + double offset = ExplodedOffsetEx + GetDetachedOffset(psp); + + if (series.IsOuterRingSeries == false && IsExploded == true) + { + double expMargin = GetExplodedMargin(series); + + offset -= expMargin; + } + + return (offset); + } + + #region GetExplodedMargin + + internal double GetExplodedMargin(PieSeries series) + { + double margin = 0; + + if (IsExploded == true) + { + for (int i = 0; i < ChartSeries.Count; i++) + { + PieSeries aseries = ChartSeries[i]; + + if (series.IsDisplayed == true) + { + if (aseries.IsOuterRingSeries == false) + { + if (aseries.IsDisplayed == true) + margin += GetExplodedMarginEx(aseries); + } + + if (series == aseries) + break; + } + } + } + + return (margin); + } + + #region GetExplodedMarginEx + + internal double GetExplodedMarginEx(PieSeries series) + { + if (IsExploded == true) + { + double margin = (double.IsNaN(series.ExplodedMargin) == false) + ? series.ExplodedMargin : ExplodedMargin; + + if (margin > 0) + { + if (margin >= 1) + return (margin); + + return (OuterRadiusEx * margin); + } + } + + return (0); + } + + #endregion + + #endregion + + #region GetDetachedOffset + + internal double GetDetachedOffset(PieSeriesPoint psp) + { + if (psp != null && psp.IsDetached == true) + { + double detachedOffset = double.IsNaN(psp.DetachedOffset) == false + ? psp.DetachedOffset : DetachedOffset; + + if (double.IsNaN(detachedOffset) == false) + { + if (Math.Abs(detachedOffset) >= 1) + return (detachedOffset); + + return (OuterRadiusEx * detachedOffset); + } + } + + return (0); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + PieChartVisualStyle pStyle = EffectiveChartStyle; + ContainerVisualStyle cStyle = GetEffectiveContainerStyle(); + + Rectangle scFrameBounds = GetScrollBounds(FrameBounds); + Rectangle scContentBounds = GetScrollBounds(ContentBounds); + + _RenderBounds = ContentBounds; + _RenderBounds.Location = GetGlobalAdjustedPoint(_RenderBounds.Location); + + Rectangle scFigureBounds = GetFigureBounds(scFrameBounds, cStyle); + + RenderFrameBackground(g, scFrameBounds, cStyle); + + cStyle.RenderBackgroundFigure(g, scFigureBounds); + cStyle.RenderBorder(g, scFrameBounds); + + Region clip = g.Clip; + g.SetClip(scContentBounds, CombineMode.Intersect); + + Rectangle imageBounds = GetXyImageBounds(pStyle); + + if (pStyle.ImageOverlay != ImageOverlay.Top && pStyle.ImageOverlay != ImageOverlay.Middle) + pStyle.RenderBackgroundFigure(g, scContentBounds, imageBounds); + + Point cpt = Point.Empty; + Rectangle cbounds = Rectangle.Empty; + + if (pStyle.ImageOverlay == ImageOverlay.Middle) + pStyle.RenderBackgroundFigure(g, scContentBounds, imageBounds); + + if (InnerRadiusEx < OuterRadiusEx) + { + Point pt = GetLocalAdjustedPoint(Point.Empty); + + if (pt.IsEmpty == false) + g.TranslateTransform(pt.X, pt.Y); + + RenderContentBackground(renderInfo, scContentBounds, pStyle); + + if (ShowGridOnTop == false) + RenderChartGrid(renderInfo, pStyle); + + RenderChartContent(renderInfo, pStyle); + + if (ShowGridOnTop == true) + RenderChartGrid(renderInfo, pStyle); + + RenderChartOuterLabels(renderInfo, pStyle); + + if (pt.IsEmpty == false) + g.ResetTransform(); + } + + g.Clip = clip; + + pStyle.RenderBorder(g, scContentBounds); + + if (pStyle.ImageOverlay == ImageOverlay.Top) + pStyle.RenderBackgroundFigure(g, scContentBounds, imageBounds); + + RenderScrollbars(renderInfo); + + if (pStyle.DropShadow.Enabled == Tbool.True) + pStyle.DropShadow.RenderDropShadow(g, scContentBounds, true, true); + + if (cStyle.DropShadow.Enabled == Tbool.True) + cStyle.DropShadow.RenderDropShadow(g, scFrameBounds, true, true); + + g.SmoothingMode = sm; + + base.RenderOverride(renderInfo); + } + + #region RenderChartOuterLabels + + private void RenderChartOuterLabels( + ChartRenderInfo renderInfo, PieChartVisualStyle pstyle) + { + Graphics g = renderInfo.Graphics; + + List pieLabels = GetPieLabels(g); + + if (pieLabels != null) + { + ChartControl chartControl = ChartControl; + + using (StringFormat sf = new StringFormat()) + { + foreach (PieLabel pl in pieLabels) + { + if (pl.Bounds.Height > 0 && pl.Bounds.Width > 0) + { + PieSeriesPoint psp = pl.PieSeriesPoint; + + if (psp.ChartSeries.IsLabelDisplayed(this, psp) == true) + { + SliceOuterLabelVisualStyle lstyle = + psp.GetEffectiveSliceStyle(this, psp.ChartSeries).SliceOuterLabelStyle; + + if (chartControl.DoRenderSliceOuterLabelEvent(g, this, psp, pl) == false) + { + RenderOuterLabelBackground(g, pl, lstyle); + RenderOuterLabelContent(g, pl, sf, lstyle); + RenderOuterLabelBorder(g, pl, lstyle); + RenderOuterLabelConnector(g, pl, lstyle); + } + } + } + } + } + } + } + + #region GetPieLabels + + private List GetPieLabels(Graphics g) + { + if (_PieLabels == null) + { + if (SeriesOverlayEnabled == false) + { + PieSeries series = GetOuterSeries(); + + _PieLabels = GetPieLabelsEx(g, series); + } + else + { + _PieLabels = new List(); + + foreach (PieSeries series in ChartSeries) + { + if (series.IsDisplayed == true) + { + List pieLabels = GetPieLabelsEx(g, series); + + if (pieLabels != null) + _PieLabels.AddRange(pieLabels); + } + } + } + } + + return (_PieLabels); + } + + #region GetPieLabelsEx + + private List GetPieLabelsEx(Graphics g, PieSeries series) + { + if (series != null && series.Visible == true) + { + List pieLabels = series.GetPieLabels(g, this); + + if (pieLabels != null) + { + ContainerVisualStyle cstyle = GetEffectiveContainerStyle(); + Rectangle r = GetAdjustedBounds(ContentBoundsEx, cstyle.BorderThickness); + + RadialAlign ralign = new RadialAlign(pieLabels); + + ralign.Iterate(g, this, r); + } + + return (pieLabels); + } + + return (null); + } + + #endregion + + #region GetOuterSeries + + private PieSeries GetOuterSeries() + { + if (ChartSeries.Count > 0) + { + if (ChartSeries.Count > 0) + { + foreach (PieSeries series in ChartSeries) + { + if (series.IsDisplayed == true && series.IsOuterRingSeries == true) + return (series); + } + } + } + + return (null); + } + + #endregion + + #region GetInnerSeries + + private PieSeries GetInnerSeries() + { + if (ChartSeries.Count > 0) + { + foreach (PieSeries series in ChartSeries) + { + if (series.IsDisplayed == true && series.IsInnerRingSeries == true) + return (series); + } + } + + return (null); + } + + #endregion + + #endregion + + #region RenderOuterLabelBackground + + private void RenderOuterLabelBackground( + Graphics g, PieLabel pl, SliceOuterLabelVisualStyle lstyle) + { + if (lstyle.Background.IsEmpty == false) + { + using (Brush br = lstyle.Background.GetBrush(pl.Bounds)) + g.FillRectangle(br, pl.Bounds); + } + } + + #endregion + + #region RenderOuterLabelContent + + private void RenderOuterLabelContent(Graphics g, + PieLabel pl, StringFormat sf, SliceOuterLabelVisualStyle lstyle) + { + lstyle.GetStringFormatFlags(sf, false); + + Rectangle r = GetAdjustedBounds(pl.Bounds, lstyle.Padding); + + using (Brush br = new SolidBrush(lstyle.TextColor)) + g.DrawString(pl.Label, lstyle.Font, br, r, sf); + } + + #endregion + + #region RenderOuterLabelBorder + + private void RenderOuterLabelBorder( + Graphics g, PieLabel pl, SliceOuterLabelVisualStyle lstyle) + { + if (lstyle.Border.IsDisplayable == true) + { + using (Pen pen = new Pen(lstyle.Border.LineColor, Dpi.Width(lstyle.Border.LineWidth))) + { + if (lstyle.Border.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.Border.LinePattern; + + g.DrawRectangle(pen, pl.Bounds); + } + } + } + + #endregion + + #region RenderOuterLabelConnector + + private void RenderOuterLabelConnector( + Graphics g, PieLabel pl, SliceOuterLabelVisualStyle lstyle) + { + if (lstyle.DrawConnector == Tbool.True) + { + if (lstyle.ConnectorColor.IsEmpty == false && lstyle.ConnectorThickness > 0 && + lstyle.ConnectorPattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.ConnectorColor, Dpi.Width(lstyle.ConnectorThickness))) + { + if (lstyle.ConnectorPattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.ConnectorPattern; + + g.DrawLines(pen, + new Point[] { pl.PtBoxEdge, pl.PtBoxBend, pl.PtSliceEdge }); + } + } + } + } + + #endregion + + #endregion + + #region RenderChartGrid + + private void RenderChartGrid(ChartRenderInfo renderInfo, PieChartVisualStyle pstyle) + { + if (ShowPieGrid == true) + { + double startAngle = SubSliceVisualLayout.StartAngle; + double sweepAngle = SubSliceVisualLayout.SweepAngle; + + if (double.IsNaN(startAngle) == true) + startAngle = 270; + + if (double.IsNaN(sweepAngle) == true) + sweepAngle = 360; + + if (sweepAngle > 0) + { + ChartControl chartControl = ChartControl; + + if (GridMinValue != GridMaxValue && GridInterval != 0) + { + int dv = (int)Math.Ceiling((GridMaxValue - GridMinValue) / GridInterval); + + if (dv > 0) + { + Graphics g = renderInfo.Graphics; + + double exp = GetExplodedOffset(); + + int outerRadius = (int)(GridOuterRadiusEx + exp); + int innerRadius = (int)(GridInnerRadiusEx + exp); + + if (chartControl.DoPreRenderRadialGridEvent(g, this, OuterRadiusExx, InnerRadiusEx, exp) == false) + { + int sdir = (SubSliceVisualLayout.SweepDirection == SweepDirection.CounterClockwise) ? -1 : 1; + double delta = (double)(outerRadius - innerRadius) / dv; + + PieGridLineVisualStyle gstyle = pstyle.GridLineVisualStyle; + + using (Pen pen = new Pen(gstyle.LineColor, Dpi.Width(gstyle.LineWidth))) + { + if (gstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)gstyle.LinePattern; + + if (UseAlternateGridBackground == false) + { + RenderChartGridLine(g, pen, + innerRadius, startAngle, sweepAngle, sdir, dv, delta); + } + else + { + RenderChartGridLinePath(g, pen, + innerRadius, startAngle, sweepAngle, sdir, dv, delta, pstyle); + } + + if (ShowFullGrid == false && sweepAngle < 360) + { + RenderGridRay(g, pen, innerRadius, outerRadius, startAngle); + RenderGridRay(g, pen, innerRadius, outerRadius, startAngle + sweepAngle * sdir); + } + } + + chartControl.DoPostRenderRadialGridEvent(g, this, OuterRadiusExx, InnerRadiusEx, exp); + } + } + } + } + } + } + + #region RenderChartGridLine + + private void RenderChartGridLine(Graphics g, Pen pen, int innerRadius, + double startAngle, double sweepAngle, int sdir, int dv, double delta) + { + Rectangle r = new Rectangle(); + + for (int i = 0; i <= dv; i++) + { + int n = (int)(innerRadius + delta * i); + + if (n > 0) + { + r.Location = CenterPoint; + r.Size = Size.Empty; + r.Inflate(n, n); + + if (ShowFullGrid == true || sweepAngle >= 360) + g.DrawEllipse(pen, r); + else + g.DrawArc(pen, r, (float)startAngle, (float)sweepAngle * sdir); + } + } + } + + #endregion + + #region RenderChartGridLinePath + + private void RenderChartGridLinePath(Graphics g, Pen pen, int innerRadius, + double startAngle, double sweepAngle, int sdir, int dv, double delta, PieChartVisualStyle pstyle) + { + Rectangle r = new Rectangle(); + + using (GraphicsPath path = new GraphicsPath()) + { + r.Location = CenterPoint; + r.Inflate((int)OuterRadiusEx, (int)OuterRadiusEx); + + using (Brush br = pstyle.AlternateGridBackground.GetBrush(r)) + { + for (int i = 0; i <= dv; i++) + { + int n = (int)(innerRadius + delta * i); + + if (n > 0) + { + r.Location = CenterPoint; + r.Size = Size.Empty; + r.Inflate(n, n); + + if (ShowFullGrid == true || sweepAngle >= 360) + { + path.AddEllipse(r); + } + else + { + if (i % 2 == 0) + path.AddArc(r, (float)startAngle, (float)sweepAngle * sdir); + else + path.AddArc(r, (float)(startAngle + sweepAngle * sdir), -(float)sweepAngle * sdir); + } + + if (i % 2 == 1) + { + g.FillPath(br, path); + g.DrawPath(pen, path); + + path.Reset(); + } + } + } + + if (path.PointCount > 0) + g.DrawPath(pen, path); + } + } + } + + #endregion + + #region RenderGridRay + + private void RenderGridRay(Graphics g, + Pen pen, int innerRadius, int outerRadius, double angle) + { + double radians = MathHelper.ToRadians(angle); + + int x = CenterPoint.X + (int)(Math.Cos(radians) * innerRadius); + int y = CenterPoint.Y + (int)(Math.Sin(radians) * innerRadius); + + Point pt1 = new Point(x, y); + + x = CenterPoint.X + (int)(Math.Cos(radians) * outerRadius); + y = CenterPoint.Y + (int)(Math.Sin(radians) * outerRadius); + + Point pt2 = new Point(x, y); + + g.DrawLine(pen, pt1, pt2); + } + + #endregion + + #endregion + + #region RenderContentBackground + + private void RenderContentBackground( + ChartRenderInfo renderInfo, Rectangle bounds, PieChartVisualStyle pstyle) + { + Graphics g = renderInfo.Graphics; + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderContentBackgroundEvent(g, this, bounds) == false) + { + pstyle.RenderBackground(g, bounds); + + Rectangle r = new Rectangle(); + + r.Location = CenterPoint; + r.Inflate((int)InnerRadiusEx, (int)InnerRadiusEx); + + if (r.IntersectsWith(_RenderBounds) == true) + { + RenderPieCenter(g, pstyle); + + if ((PieRingOutDisplayMode == PieRingOutDisplayMode.OnMouseOver && HitArea == ItemHitArea.InPieRingOut) || + (PieRingOutDisplayMode == PieRingOutDisplayMode.Always && PresentRingOut() == true)) + { + RenderPieRingOut(g, pstyle); + } + } + + chartControl.DoPostRenderContentBackgroundEvent(g, this, bounds); + } + } + + #region RenderPieCenter + + private void RenderPieCenter(Graphics g, PieChartVisualStyle pstyle) + { + if ((CenterLabelVisibility == CenterLabelVisibility.Always) || + (CenterLabelVisibility == CenterLabelVisibility.MouseOver && HitArea == ItemHitArea.InPieCenter)) + { + int margin = (int)InnerMarginEx; + + Rectangle rc = new Rectangle(); + rc.Location = CenterPoint; + rc.Inflate((int)InnerRadiusEx - margin, (int)InnerRadiusEx - margin); + + if (rc.Width > 0) + { + double hwidth = (double)rc.Width / 2; + + int d = (int)Math.Sqrt((hwidth * hwidth) / 2); + + Rectangle rt = new Rectangle(); + rt.Location = CenterPoint; + rt.Inflate(d, d); + + RenderPieCenterEx(g, pstyle, rc, rt); + } + } + } + + #region RenderPieCenterEx + + private void RenderPieCenterEx(Graphics g, + PieChartVisualStyle pstyle, Rectangle rc, Rectangle rt) + { + PieCenterVisualStyle cstyle = GetEffectivePieCenterStyle(); + ChartLineVisualStyle border = cstyle.Border; + + RenderPieCenterBackground(g, cstyle, rc, rt); + + Rectangle rcSav = rc; + + if (border.IsDisplayable == true) + { + int n = cstyle.Border.LineWidth / 2 + 1; + + rc.Inflate(-n, -n); + rc.Width++; + + rt.Inflate(-n, -n); + rc.Height++; + } + + rc.Location = GetAdjustedPoint(rc.Location, cstyle.ImagePadding); + rt.Location = GetAdjustedPoint(rt.Location, cstyle.ImagePadding); + + if (cstyle.ImageOverlay != ImageOverlay.Top) + RenderCenterFigure(g, rcSav, rc, rt, cstyle); + + RenderPieCenterContent(g, cstyle, rc, rt); + + if (cstyle.ImageOverlay == ImageOverlay.Top) + RenderCenterFigure(g, rcSav, rc, rt, cstyle); + + if (border.IsDisplayable == true) + { + using (Pen pen = new Pen(border.LineColor, Dpi.Width(border.LineWidth))) + { + if (border.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)border.LinePattern; + + g.DrawEllipse(pen, rcSav); + } + } + } + + #region GetAdjustedPoint + + private Point GetAdjustedPoint(Point pt, Thickness thickness) + { + if (thickness.IsEmpty == false) + { + pt.X += Dpi.Width(thickness.Left - thickness.Right); + pt.Y += Dpi.Height(thickness.Top - thickness.Bottom); + } + + return (pt); + } + + #endregion + + #region RenderPieCenterBackground + + private void RenderPieCenterBackground( + Graphics g, PieCenterVisualStyle cstyle, Rectangle rc, Rectangle rt) + { + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderPieCenterBackgroundEvent(g, this, rc) == false) + { + if (cstyle.Background.IsEmpty == false) + { + using (Brush br = cstyle.Background.GetBrush(rc)) + g.FillEllipse(br, rc); + } + + chartControl.DoPostRenderPieCenterBackgroundEvent(g, this, rc); + } + } + + #endregion + + #region RenderPieCenterContent + + private void RenderPieCenterContent( + Graphics g, PieCenterVisualStyle style, Rectangle rc, Rectangle rt) + { + ChartControl chartControl = ChartControl; + + Rectangle r = (style.TextInscribed == Tbool.False) ? rc : rt; + + r = GetAdjustedBounds(r, style.Padding); + + if (r.Width > 0 && r.Height > 0) + { + string centerlabel = CenterLabel; + + if (chartControl.DoPreRenderPieCenterContentEvent(g, this, r, centerlabel) == false) + { + if (string.IsNullOrEmpty(centerlabel) == false) + { + if (_CenterLabelMarkup != null) + { + RenderTextMarkup(g, _CenterLabelMarkup, style, r); + } + else + { + using (StringFormat sf = new StringFormat()) + { + style.GetStringFormatFlags(sf); + + using (Brush br = new SolidBrush(style.TextColor)) + g.DrawString(centerlabel, style.Font, br, r, sf); + } + } + } + + chartControl.DoPostRenderPieCenterContentEvent(g, this, r, centerlabel); + } + } + } + + #region RenderTextMarkup + + private void RenderTextMarkup(Graphics g, + BodyElement textMarkup, PieCenterVisualStyle style, Rectangle r) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + textMarkup.Measure(r.Size, d); + textMarkup.Arrange(r, d); + + Size size = textMarkup.Bounds.Size; + + switch (style.Alignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + if (r.Height > size.Height) + r.Y += (r.Height - size.Height) / 2; + break; + + default: + if (r.Height > size.Height) + r.Y = r.Bottom - size.Height; + break; + } + + textMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + textMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #endregion + + #region RenderCenterFigure + + private void RenderCenterFigure(Graphics g, + Rectangle rcSav, Rectangle rc, Rectangle rt, PieCenterVisualStyle cstyle) + { + object figure = cstyle.GetFigure(); + + if (figure != null) + { + int radius = rc.Width / 2; + Size fsize = cstyle.GetFigureSize(g); + + Rectangle r = rc; + + if (cstyle.ImageSizeMode == ImageSizeMode.Normal) + { + if (double.IsNaN(cstyle.ImageScale) == false) + { + if (cstyle.ImageScale != 1) + { + double d = (double)fsize.Height / fsize.Width; + + fsize.Width = (int)(rt.Width * cstyle.ImageScale); + fsize.Height = (int)(fsize.Width * d); + + cstyle.FigureSizeEx = fsize; + } + } + } + + if (cstyle.ImageInscribed == Tbool.True) + r = GetFigureAlignment(radius, fsize, cstyle, rc, rt); + + if (r.Width > 0 && r.Height > 0) + { + Region clip = g.Clip; + + using (GraphicsPath path = new GraphicsPath()) + { + rc.Inflate(1, 1); + path.AddEllipse(rcSav); + + g.SetClip(path, CombineMode.Intersect); + + cstyle.RenderBackgroundFigure(g, r); + + g.Clip = clip; + } + } + } + } + + #region GetFigureAlignment + + private Rectangle GetFigureAlignment(int radius, + Size fsize, PieCenterVisualStyle cstyle, Rectangle rc, Rectangle rt) + { + Rectangle r = rc; + + Alignment align = cstyle.ImageAlignment; + + if (cstyle.ImageSizeMode == ImageSizeMode.Tile) + return (rc); + + if (cstyle.ImageSizeMode == ImageSizeMode.Stretch) + return (rt); + + if (cstyle.ImageSizeMode == ImageSizeMode.Zoom) + { + double ratio = (double)fsize.Height / fsize.Width; + + int dx = (int)Math.Sqrt((radius * radius) / (1 + ratio * ratio)); + int dy = (int)(dx * ratio); + + r.X += ((r.Width / 2) - dx); + r.Width = dx * 2; + + r.Y += ((r.Height / 2) - dy); + r.Height = dy * 2; + + return (r); + } + + if ((cstyle.ImageSizeMode == ImageSizeMode.Normal) && + (align == Alignment.TopCenter || align == Alignment.BottomCenter || + align == Alignment.MiddleLeft || align == Alignment.MiddleRight)) + { + int height = fsize.Height / 2; + int width = fsize.Width / 2; + + switch (align) + { + case Alignment.TopCenter: + if (radius > width) + { + int cy = (radius * radius) - (width * width); + int dy = radius - (int)Math.Sqrt(cy); + + r.Y += dy; + } + + if (r.Y > rt.Y) + r.Y = rt.Y; + + r = GetAdjustedBounds(r, cstyle.ImagePadding); + break; + + case Alignment.BottomCenter: + if (radius > width) + { + int cy = (radius * radius) - (width * width); + int dy = radius - (int)Math.Sqrt(cy); + + r.Y -= dy; + + if (r.Bottom < rt.Bottom) + r.Y = (rt.Bottom - r.Height); + + r = GetAdjustedBounds(r, cstyle.ImagePadding); + } + break; + + case Alignment.MiddleLeft: + if (radius > height) + { + int cx = (radius * radius) - (height * height); + int dx = radius - (int)Math.Sqrt(cx); + + r.X += dx; + } + + if (r.X > rt.X) + r.X = rt.X; + + r = GetAdjustedBounds(r, cstyle.ImagePadding); + break; + + case Alignment.MiddleRight: + if (radius > height) + { + int cx = (radius * radius) - (height * height); + int dx = radius - (int)Math.Sqrt(cx); + + r.X -= dx; + } + + if (r.Right < rt.Right) + r.X = (rt.Right - r.Width); + + r = GetAdjustedBounds(r, cstyle.ImagePadding); + break; + } + + return (r); + } + + switch (align) + { + case Alignment.TopLeft: + r.X = rt.X; + r.Y = rt.Y; + break; + + case Alignment.TopRight: + r.X = rt.Right - fsize.Width; + r.Y = rt.Y; + break; + + case Alignment.TopCenter: + r.X = (r.X + r.Width / 2) - fsize.Width / 2; + r.Y = rt.Y; + break; + + case Alignment.BottomLeft: + r.X = rt.X; + r.Y = (rt.Bottom - fsize.Height); + break; + + case Alignment.BottomRight: + r.X = rt.Right - fsize.Width; + r.Y = (rt.Bottom - fsize.Height); + break; + + case Alignment.BottomCenter: + r.X = (r.X + r.Width / 2) - fsize.Width / 2; + r.Y = (rt.Bottom - fsize.Height); + break; + + default: + r.X = (r.X + r.Width / 2) - fsize.Width / 2; + r.Y = (r.Y + r.Height / 2) - fsize.Height / 2; + break; + } + + r.Size = fsize; + + return (r); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region RenderPieRingOut + + private void RenderPieRingOut(Graphics g, PieChartVisualStyle pstyle) + { + float n = RingOutRadius; + + if (n > MinRingOutRadius) + { + Rectangle r = new Rectangle(); + + r.Location = CenterPoint; + r.Inflate((int)n, (int)n); + + if (ChartControl.DoRenderPieRingOutEvent(g, this, r) == false) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + using (Brush br = new SolidBrush(Color.FromArgb(30, Color.Black))) + g.FillEllipse(br, r); + + if (_SymFontScale < 0) + { + _ScaleSymDef.SymbolSet = eSymbolSet.Awesome; + _ScaleSymDef.Symbol = "\uf060"; + _ScaleSymDef.SymbolSize = n; + + _SymFontScale = n / (_ScaleSymDef.SymbolFont.Height * .8f); + } + + _ScaleSymDef.SymbolSize = n * _SymFontScale; + + using (StringFormat sf = new StringFormat()) + { + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Center; + + r.Y++; + using (Brush br = new SolidBrush(Color.FromArgb(130, Color.Black))) + g.DrawString(_ScaleSymDef.SymbolRealized, _ScaleSymDef.SymbolFont, br, r, sf); + } + + g.SmoothingMode = sm; + } + } + } + + #endregion + + #endregion + + #region GetXyImageBounds + + private Rectangle GetXyImageBounds(PieChartVisualStyle pieStyle) + { + Rectangle scBbounds = GetScrollBounds(ScrollBounds); + + scBbounds = GetAdjustedBounds(scBbounds, pieStyle.BorderThickness); + + if (pieStyle.EnableImageScroll != Tbool.False) + { + scBbounds = GetScrollBounds(ScrollBoundsEx); + scBbounds = GetDisplayBounds(scBbounds); + } + + if (HScrollBar.Visible == true) + scBbounds.Height -= HScrollBar.Height; + + if (VScrollBar.Visible == true) + scBbounds.Width -= VScrollBar.Width; + + return (scBbounds); + } + + #endregion + + #region GetFigureBounds + + private Rectangle GetFigureBounds(Rectangle bounds, ContainerVisualStyle cStyle) + { + bounds = GetAdjustedBounds(bounds, cStyle.BorderThickness); + + Rectangle scBounds = GetScrollBounds(bounds); + + return (scBounds); + } + + #endregion + + #region RenderChartContent + + protected virtual void RenderChartContent( + ChartRenderInfo renderInfo, PieChartVisualStyle pieStyle) + { + Graphics g = renderInfo.Graphics; + + if (ChartSeries.Count > 0) + { + if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse) + { + for (int i = ChartSeries.Count - 1; i >= 0; i--) + RenderSeries(renderInfo, ChartSeries[i]); + } + else + { + for (int i = 0; i < ChartSeries.Count; i++) + RenderSeries(renderInfo, ChartSeries[i]); + } + } + else + { + Rectangle scContentBounds = GetScrollBounds(ContentBounds); + Rectangle scDisplayBounds = GetDisplayBounds(scContentBounds); + + RenderEmptyText(g, pieStyle, scDisplayBounds); + } + } + + #region RenderSeries + + private void RenderSeries(ChartRenderInfo renderInfo, PieSeries series) + { + if (Visible == true) + { + if (Legend.ItemCheckAction != ItemCheckAction.ShowItem || series.IsDisplayed == true) + series.Render(renderInfo); + } + } + + #endregion + + #endregion + + #endregion + + #region Markup support + + private void MarkupCenterLabelChanged() + { + if (_CenterLabelMarkup != null) + _CenterLabelMarkup.HyperLinkClick -= CenterLabelMarkupLinkClick; + + _CenterLabelMarkup = null; + + if (EnableCenterLabelMarkup == true) + { + if (MarkupParser.IsMarkup(_CenterLabel) == true) + { + _CenterLabelMarkup = MarkupParser.Parse(_CenterLabel); + + if (_CenterLabelMarkup != null) + _CenterLabelMarkup.HyperLinkClick += CenterLabelMarkupLinkClick; + } + } + else + { + if (_CenterLabelMarkup != null) + _CenterLabelMarkup.HyperLinkClick -= CenterLabelMarkupLinkClick; + } + } + + protected virtual void CenterLabelMarkupLinkClick(object sender, EventArgs e) + { + HyperLink link = sender as HyperLink; + + ChartControl.DoPieCenterMarkupLinkClickEvent(this, link); + + InvalidatePieCenter(); + } + + /// + /// Gets plain CenterLabel text without text-markup (if text-markup is used in Text) + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public string PlainCenterlabelText + { + get { return (_CenterLabelMarkup != null ? _CenterLabelMarkup.PlainText : _CenterLabel); } + } + + #endregion + + #region Mouse Support + + #region OnMouseDown + + protected override bool OnMouseDown(MouseEventArgs e) + { + MouseDownHitArea = HitArea; + + PieSeriesPoint psp = _HitPsp; + + if (psp != null) + { + PieSeries series = psp.PieRing.ChartSeries; + + if (series != null) + { + Capture = true; + + return (series.ProcessMouseDown(e, this, psp)); + } + } + else if (HitArea != ItemHitArea.InPieRingOut) + { + uint selCount = GlobalSelectionCount; + + if (WhitespaceClickBehavior == WhitespaceClickBehavior.ClearSelection) + { + SetSelected(false); + + if (GlobalSelectionCount != selCount) + ChartControl.DoPieSelectionChangedEvent(this, null, null, PieSelectionMode.None); + } + } + + return (base.OnMouseDown(e)); + } + + #endregion + + #region OnMouseUp + + protected override bool OnMouseUp(MouseEventArgs e) + { + switch (MouseDownHitArea) + { + case ItemHitArea.InMarkup: + if (MouseDownHitArea == ItemHitArea.InMarkup) + { + if (e.Button == MouseButtons.Left) + DoMarkupClick(_CenterLabelMarkup); + } + break; + + case ItemHitArea.InPieSeriesPoint: + if (_HitPsp != null) + _HitPsp.ChartSeries.ProcessMouseUp(e, this); + break; + + case ItemHitArea.InPieRingOut: + ProcessRingOutClick(); + break; + } + + Capture = false; + + return (base.OnMouseUp(e)); + } + + #region DoMarkupClick + + private bool DoMarkupClick(BodyElement bodyElement) + { + if (bodyElement != null) + { + if (bodyElement.MouseOverElement != null) + { + bodyElement.Click(ChartControl); + + ChartControl.Cursor = Cursors.Default; + + return (true); + } + } + + return (false); + } + + #endregion + + #region ProcessRingOutClick + + private void ProcessRingOutClick() + { + List spcs = GetSelectedSpcs(); + + if (spcs != null) + { + ChartControl chartControl = ChartControl; + + foreach (PieSeriesPointCollection spc1 in spcs) + { + PieSeriesPoint psp = spc1.Parent as PieSeriesPoint; + + if (psp != null) + { + PieSeriesPointCollection spc2 = psp.Parent as PieSeriesPointCollection; + + if (chartControl.DoPieRingLevelChangingEvent(this, spc1, spc2) == false) + { + psp.ChartSeries.SetActiveSeriesPointCollection(spc2); + + chartControl.DoPieRingLevelChangedEvent(this, spc1, spc2); + } + } + } + } + } + + #region GetSelectedSpss + + private List GetSelectedSpcs() + { + List list = new List(); + + PieSeriesPointCollection dspc = null; + + foreach (PieSeries series in ChartSeries) + { + if (series.IsDisplayed == true) + { + if (series.ShowAllRingsEx(this) == false) + { + PieSeriesPointCollection spc = series.GetActiveSeriesPointCollection(); + + if (SpcHasSelection(spc) == true) + list.Add(spc); + + dspc = spc; + } + } + } + + if (list.Count == 0 && dspc != null) + list.Add(dspc); + + return (list); + } + + #region SpcHasSelection + + private bool SpcHasSelection(PieSeriesPointCollection spc) + { + if (spc.PieRing != null && spc.PieRing.Psps != null) + { + foreach (PieSeriesPoint psp in spc.PieRing.Psps) + { + if (psp.IsSelected == true) + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region OnMouseMove + + protected override bool OnMouseMove(MouseEventArgs e) + { + if (Capture == false) + { + HitArea = GetHitItem(e.Location, out _HitPsp); + + ChartControl.ChartCursor = Cursors.Default; + + if (HitArea == ItemHitArea.InPieCenter) + { + if (_CenterLabelMarkup != null) + { + _CenterLabelMarkup.MouseMove(ChartControl, e); + + if (_CenterLabelMarkup.MouseOverElement != null) + { + ChartControl.ChartCursor = Cursors.Hand; + + HitArea = ItemHitArea.InMarkup; + } + } + } + + if (_HitPsp != _LastHitPsp) + { + if (_LastHitPsp != null) + _LastHitPsp.ChartSeries.ProcessMouseLeave(EventArgs.Empty, this); + + if (_HitPsp != null) + _HitPsp.ChartSeries.ProcessMouseEnter(EventArgs.Empty, this); + + InvalidatePsp(_LastHitPsp); + InvalidatePsp(_HitPsp); + + _LastHitPsp = _HitPsp; + } + + if (HitArea != _LastHitArea) + { + if (HitArea == ItemHitArea.InPieCenter || _LastHitArea == ItemHitArea.InPieCenter) + InvalidatePieCenter(); + + else if (HitArea == ItemHitArea.InPieRingOut || _LastHitArea == ItemHitArea.InPieRingOut) + InvalidateRingOut(); + } + + _LastHitArea = HitArea; + } + + if (_HitPsp != null) + _HitPsp.ChartSeries.ProcessMouseMove(e, this); + + if (HitArea == ItemHitArea.None || HitArea == ItemHitArea.InContent) + return (base.OnMouseMove(e)); + + return (true); + } + + #region GetHitArea + + /// + /// Gets the hit area in the chart from the given point. + /// + /// + /// ItemHitArea + public override ItemHitArea GetHitArea(Point pt) + { + PieSeriesPoint psp; + + return (GetHitItem(pt, out psp)); + } + + #endregion + + #region GetHitItem + + /// + /// Gets the hit item in the chart from the given point. + /// + /// + /// + /// + public ItemHitArea GetHitItem(Point pt, out PieSeriesPoint psp) + { + Rectangle contentBounds = GetScrollBounds(ContentBounds); + + if (contentBounds.Contains(pt)) + { + psp = GetPspFromPoint(pt); + + if (psp != null) + return (ItemHitArea.InPieSeriesPoint); + + Point centerPoint = GetLocalAdjustedPoint(CenterPoint); + + Point rpt = pt; + int radius = MathHelper.GetPointRadius(ref rpt, centerPoint); + + if (radius <= RingOutRadius) + { + if (PresentRingOut() == true) + return (ItemHitArea.InPieRingOut); + } + + if (radius <= InnerRadiusEx - InnerMarginEx) + return (ItemHitArea.InPieCenter); + + return (ItemHitArea.InContent); + } + + psp = null; + + Rectangle frameBounds = GetScrollBounds(FrameBounds); + + if (frameBounds.Contains(pt)) + return (ItemHitArea.InFrame); + + return (ItemHitArea.None); + } + + #endregion + + #region GetPspFromPoint + + /// + /// Gets the psp at the given Point. Note that the order of + /// displayed/overlapping series is taken into account. + /// + /// + /// PieSeriesPoint or null. + public PieSeriesPoint GetPspFromPoint(Point pt) + { + if (_RenderBounds.Contains(GetGlobalAdjustedPoint(pt)) == true) + { + Point centerPoint = GetLocalAdjustedPoint(CenterPoint); + + int radius, angle; + Point cpt = MathHelper.GetOffsetPoint(pt, centerPoint, out radius, out angle); + + if (SeriesDisplayOrder == SeriesDisplayOrder.Forward) + { + for (int i = ChartSeries.Count - 1; i >= 0; i--) + { + PieSeriesPoint psp = + GetPspFromPoint(ChartSeries[i], pt, cpt, radius, angle); + + if (psp != null) + return (psp); + } + } + else + { + for (int i = 0; i < ChartSeries.Count; i++) + { + PieSeriesPoint psp = + GetPspFromPoint(ChartSeries[i], pt, cpt, radius, angle); + + if (psp != null) + return (psp); + } + } + } + + return (null); + } + + #region GetPspFromPoint (series) + + private PieSeriesPoint GetPspFromPoint( + PieSeries series, Point pt, Point cpt, int radius, int angle) + { + if (series.IsDisplayed == true) + { + if (series.ShowAllRingsEx(this) == false) + { + PieSeriesPointCollection spc = series.GetActiveSeriesPointCollection(); + + if (spc != null) + { + if (spc.PieSlices != null) + spc = spc.PieSlices; + + if (spc != null) + { + foreach (PieSeriesPoint psp in spc) + { + if (GetPspFromPointEx(series, psp, pt, radius, angle) == true) + return (psp); + } + } + } + } + else + { + foreach (PieRing pieRing in series.PieRings) + { + PieSeriesPoint psp = GetPspFromPoint(series, pieRing, pt, cpt, radius, angle); + + if (psp != null) + return (psp); + } + } + } + + return (null); + } + + #region GetPspFromPoint (pieRing) + + private PieSeriesPoint GetPspFromPoint(PieSeries series, + PieRing pieRing, Point pt, Point cpt, int cradius, int cangle) + { + if (series.IsOffset == false) + { + int innerRadius = pieRing.InnerRadius; + + if (cradius < pieRing.InnerRadius || cradius > pieRing.OuterRadius) + return (null); + } + + foreach (PieSeriesPoint psp in pieRing.Psps) + { + if (psp.IsInOtherEx == false) + { + if (GetPspFromPointEx(series, psp, pt, cradius, cangle) == true) + return (psp); + } + } + + return (null); + } + + #endregion + + #region GetPspFromPointEx + + private bool GetPspFromPointEx(PieSeries series, + PieSeriesPoint psp, Point pt, int cradius, int cangle) + { + if (psp.IsDisplayed == true) + { + int width = psp.OuterRadius - psp.InnerRadius; + + if (width > 0) + { + PieSeriesPointCollection spc = psp.Parent as PieSeriesPointCollection; + + if (spc != null) + { + int outerRadius = (psp.ShowSliceWhiteSpaceEx == true) + ? psp.OuterRadius : (int)(psp.InnerRadius + psp.SliceExtent * width); + + int innerRadius = psp.InnerRadius; + + if (outerRadius - innerRadius > 0) + { + if (psp.IsOffset == false) + { + if (cradius >= innerRadius && cradius <= outerRadius) + { + int startAngle, endAngle; + NormalizePspAngles(psp, out startAngle, out endAngle); + + if (IsAngleBetween(cangle, startAngle, endAngle) == true) + return (true); + } + } + else + { + Point scpt = GetLocalAdjustedPoint(psp.SliceCenter); + + Point ppt = pt; + int pradius = MathHelper.GetPointRadius(ref ppt, scpt); + + if (pradius >= innerRadius && pradius <= outerRadius) + { + int startAngle, endAngle; + NormalizePspAngles(psp, out startAngle, out endAngle); + + int angle = MathHelper.GetPointAngle(ppt); + + if (IsAngleBetween(angle, startAngle, endAngle) == true) + return (true); + } + } + } + } + } + } + + return (false); + } + + #region NormalizePspAngles + + private void NormalizePspAngles(PieSeriesPoint psp, out int startAngle, out int endAngle) + { + startAngle = (int)psp.StartAngleEx; + endAngle = (int)(psp.StartAngleEx + psp.SweepAngleEx); + + if (startAngle > endAngle) + { + int temp = startAngle; + startAngle = endAngle; + endAngle = temp; + } + } + + #endregion + + #region IsAngleBetween + + private bool IsAngleBetween(int angle, int start, int end) + { + if (end - start >= 360) + return (true); + + start = (3600000 + start) % 360; + end = (3600000 + end) % 360; + + if (start <= end) + return (start <= angle && angle <= end); + + return (start <= angle || angle <= end); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region InvalidatePsp + + private void InvalidatePsp(PieSeriesPoint psp) + { + if (psp != null) + { + PieSeries series = psp.ChartSeries; + + PieSelectionMode psm = series.GetPieSelectionMode(this); + + switch (psm) + { + case PieSelectionMode.Pie: + if (_LastHitPsp == null || _HitPsp == null) + InvalidateRender(); + break; + + case PieSelectionMode.Ring: + psp.PieRing.InvalidateRender(this); + break; + + case PieSelectionMode.Series: + foreach (PieRing pieRing in series.PieRings) + pieRing.InvalidateRender(this); + break; + + case PieSelectionMode.Slice: + PieSeriesPoint pspHit = psp; + + if (series.ShowAllRingsEx(this) == true) + { + psp = psp.RootPsp; + + InvalidateSlice(psp.SeriesPoints); + } + + InvalidateRender(psp.PathBounds); + InvalidatePieLabel(psp); + + InvalidateLegendItem(pspHit); + break; + + case PieSelectionMode.Point: + InvalidateRender(psp.PathBounds); + InvalidatePieLabel(psp); + InvalidateLegendItem(psp); + break; + } + } + } + + #region InvalidateSlice + + private void InvalidateSlice(PieSeriesPointCollection spc) + { + if (spc != null) + { + foreach (PieSeriesPoint psp in spc) + { + InvalidateRender(psp.PathBounds); + InvalidatePieLabel(psp); + InvalidateLegendItem(psp); + + InvalidateSlice(psp.SeriesPoints); + } + } + } + + #endregion + + #region InvalidateLegendItem + + private void InvalidateLegendItem(PieSeriesPoint psp) + { + if (Legend.TrackingMode == LegendTrackingMode.ChartAndLegend || + Legend.TrackingMode == LegendTrackingMode.Chart) + { + if (psp.LegendItem != null) + { + psp.LegendItem.LikeItem.IsHitItem = (psp == HitPsp); + psp.LegendItem.LikeItem.InvalidateRender(); + } + } + } + + #endregion + + #region InvalidatePieLabel + + private void InvalidatePieLabel(PieSeriesPoint psp) + { + if (psp.PieLabel != null) + { + if (psp.PieLabel.Bounds.IsEmpty == false) + { + InvalidateRender(psp.PieLabel.Bounds); + + if (psp.PieLabel.ConnectorBounds.IsEmpty == false) + InvalidateRender(psp.PieLabel.ConnectorBounds); + } + } + } + + #endregion + + #endregion + + #region InvalidatePieCenter + + /// + /// Invalidates the Pie Center area (causing a repaint). + /// + public void InvalidatePieCenter() + { + int n = (int)InnerRadiusEx; + + if (n > 0) + { + Rectangle r = new Rectangle(); + + r.Location = GetLocalAdjustedPoint(CenterPoint); + r.Inflate(n, n); + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(r); + + using (Region rgn = new Region(path)) + ChartControl.Invalidate(rgn); + } + } + } + + #endregion + + #region InvalidateRingOut + + /// + /// Invalidates the 'Ring Out' area (causing a repaint). + /// + public void InvalidateRingOut() + { + int n = RingOutRadius; + + if (n > MinRingOutRadius) + { + Rectangle r = new Rectangle(); + + r.Location = GetLocalAdjustedPoint(CenterPoint); + r.Inflate(n, n); + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(r); + + using (Region rgn = new Region(path)) + ChartControl.Invalidate(rgn); + } + } + } + + #endregion + + #endregion + + #region OnMouseEnter + + protected override bool OnMouseEnter(EventArgs e) + { + if (ShowSliceLabelsOnEntry == true) + InvalidateRender(); + + return (base.OnMouseEnter(e)); + } + + #endregion + + #region OnMouseLeave + + protected override bool OnMouseLeave(EventArgs e) + { + _HitPsp = null; + + if (_LastHitArea == ItemHitArea.InPieSeriesPoint) + { + if (_LastHitPsp != null) + { + InvalidateRender(_LastHitPsp.PathBounds); + InvalidateLegendItem(_LastHitPsp); + + if (_LastHitPsp != null) + _LastHitPsp.ChartSeries.ProcessMouseLeave(e, this); + + _LastHitPsp = null; + + IsDragging = false; + } + } + else if (_LastHitArea == ItemHitArea.InPieRingOut) + { + InvalidatePieCenter(); + } + + HitArea = ItemHitArea.None; + _LastHitArea = ItemHitArea.None; + + if (ShowSliceLabelsOnEntry == true) + InvalidateRender(); + + return (base.OnMouseLeave(e)); + } + + #endregion + + #region OnMouseDoubleClick + + protected override bool OnMouseDoubleClick(MouseEventArgs e) + { + ChartControl chartControl = ChartControl; + PieSeriesPoint psp = _HitPsp; + + ItemHitArea hitArea = HitArea; + ChartVisualElement hitElement = this; + object hitItem = psp; + + if (hitArea == ItemHitArea.InPieSeriesPoint && psp != null) + hitElement = psp.ChartSeries; + + if (chartControl.DoChartMouseDoubleClickEvent(this, hitArea, hitElement, hitItem, e) == false) + { + if (hitArea == ItemHitArea.InPieSeriesPoint && psp != null) + return (psp.ChartSeries.ProcessMouseDoubleClick(e, this, psp)); + } + + return (base.OnMouseDoubleClick(e)); + } + + #endregion + + #endregion + + #region PresentRingOut + + private bool PresentRingOut() + { + if (PieRingOutDisplayMode == PieRingOutDisplayMode.Never) + return (false); + + int inCount = 0; + int ringCount = 0; + + foreach (PieSeries series in ChartSeries) + { + if (series.IsDisplayed == true) + { + if (series.ShowAllRingsEx(this) == false) + { + PieSeriesPointCollection spc = series.GetActiveSeriesPointCollection(); + + if (spc != null) + { + if (spc.Parent is PieSeries == false) + { + if (SpcHasSelection(spc) == true) + return (true); + + inCount++; + } + + ringCount++; + } + } + } + } + + return (inCount == 1 && ringCount == 1); + } + + #endregion + + #region CancelCapture + + /// + /// Cancels any inprogress operations that may have the mouse captured. + /// + public override void CancelCapture() + { + IsDragging = false; + PspDragType = PspDragType.None; + + base.CancelCapture(); + } + + #endregion + + #region SetSelected + + /// + /// Set (or clears) all selected elements in the chart. + /// + /// + public void SetSelected(bool select) + { + foreach (PieSeries series in ChartSeries) + { + if (series.IsDisplayed == true) + series.SetSelected(select); + } + } + + /// + /// Set (or clears) all selected elements in the given series. + /// + /// + /// + public void SetSelected(PieSeries series, bool select) + { + if (series != null) + series.SetSelected(select); + } + + /// + /// Set (or clears) the given series point. + /// + /// + /// + public void SetSelected(PieSeriesPoint psp, bool select) + { + if (psp != null) + psp.IsSelected = select; + } + + #endregion + + #region GetVisibleSelectionCount + + /// + /// Gets a count of the visible, selected pie series points. + /// + /// + public int GetVisibleSelectionCount() + { + int count = 0; + + foreach (PieSeries series in ChartSeries) + { + if (series.IsDisplayed == true) + count += series.GetVisibleSelectionCount(); + } + + return (count); + } + + #endregion + + #region GetVisibleSelectedPoints + + /// + /// Gets a list of the currently Visible selected points. + /// + /// + public List GetVisibleSelectedPoints() + { + List list = new List(); + + foreach (PieSeries series in ChartSeries) + { + List slist = series.GetVisibleSelectedPoints(); + + if (slist != null && slist.Count > 0) + list.AddRange(slist); + } + + return (list); + } + + #endregion + + #region GetSelectionCount + + /// + /// Gets a count of the selected pie series points. + /// + /// + public int GetSelectionCount() + { + int count = 0; + + foreach (PieSeries series in ChartSeries) + { + if (series.IsDisplayed == true) + count += series.GetSelectionCount(); + } + + return (count); + } + + #endregion + + #region GetSelectedPoints + + /// + /// Gets a list of the currently selected points. + /// + /// + public List GetSelectedPoints() + { + List list = new List(); + + foreach (PieSeries series in ChartSeries) + { + List slist = series.GetSelectedPoints(); + + if (slist != null && slist.Count > 0) + list.AddRange(slist); + } + + return (list); + } + + #endregion + + #region GetLocalAdjustedPoint + + /// + /// Gets the local, scroll adjusted point. + /// + /// + /// + public Point GetLocalAdjustedPoint(Point pt) + { + pt.X -= ScrollOffset.X; + pt.X += (HScrollBar.Inverted == true ? HScrollOffset : -HScrollOffset); + + pt.Y -= ScrollOffset.Y; + pt.Y += (VScrollBar.Inverted == true ? VScrollOffset : -VScrollOffset); + + return (pt); + } + + #endregion + + #region GetGlobalAdjustedPoint + + internal Point GetGlobalAdjustedPoint(Point pt) + { + pt.X -= (HScrollBar.Inverted == true ? HScrollOffset : -HScrollOffset); + pt.Y -= (VScrollBar.Inverted == true ? VScrollOffset : -VScrollOffset); + + return (pt); + } + + #endregion + + #region GetRayEndPoint + + /// + /// Gets the end Point for a ray, of the given angle (in degrees), + /// starting at the pie center and ending at the outer radius. + /// + /// + /// + public Point GetRayEndPoint(double angle) + { + return (GetRayEndPoint(angle, OuterRadiusEx)); + } + + /// + /// Gets the end Point for a ray, of the given angle (in degrees), + /// starting at the pie center and ending at the specified radius. + /// + /// + /// + /// + public Point GetRayEndPoint(double angle, double radius) + { + Point pt = CenterPoint; + + double radians = MathHelper.ToRadians(angle); + + pt.X += (int)(Math.Cos(radians) * radius); + pt.Y += (int)(Math.Sin(radians) * radius); + + return (pt); + } + + #endregion + + #region OnSeriesCheckStateChanged + + internal override void OnSeriesCheckStateChanged(string property) + { + SeriesRangeChanged = true; + + InvalidateLayout(); + + base.OnSeriesCheckStateChanged(property); + } + + #endregion + + #region GetBaseSeries + + internal override ChartBaseSeriesCollection GetBaseSeries() + { + ChartBaseSeriesCollection baseSeries = new ChartBaseSeriesCollection(); + + foreach (BaseSeries series in ChartSeries) + baseSeries.Add(series); + + return (baseSeries); + } + + #endregion + + #region GetSeriesByName + + /// + /// Gets the chart series with the given Name. + /// + /// + /// PieSeries or null. + public PieSeries GetSeriesByName(string name) + { + if (String.IsNullOrEmpty(name) == true) + return (null); + + foreach (PieSeries series in ChartSeries) + { + if (name.Equals(series.Name) == true) + return (series); + } + + return (null); + } + + #endregion + + #region GetAutoGenSeriesType + + internal override SeriesType GetAutoGenSeriesType() + { + return (SeriesType.Pie); + } + + #endregion + + #region GetAutoGenSeriesNameCount + + internal override int GetAutoGenSeriesNameCount() + { + return (1); + } + + #endregion + + #region GetNewSeries + + internal override BaseSeries GetNewSeries() + { + return (new PieSeries()); + } + + #endregion + + #region AddChartSeries + + internal override void AddChartSeries(BaseSeries series) + { + ChartSeries.Add((PieSeries)series); + } + + #endregion + + #region Style handling + + #region GetEffectivePieCenterStyle + + internal PieCenterVisualStyle GetEffectivePieCenterStyle() + { + StyleState state = GetPieCenterStyleState(); + + return (EffectivePieCenterStyle[state]); + } + + #region GetPieCenterStyleState + + private StyleState GetPieCenterStyleState() + { + StyleState state = StyleState.Default; + + if (HitArea == ItemHitArea.InPieCenter || HitArea == ItemHitArea.InPieRingOut) + state |= StyleState.MouseOver; + + return (state); + } + + #endregion + + #endregion + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + base.ApplyStyles(style); + + PieChartVisualStyle pstyle = style as PieChartVisualStyle; + + if (pstyle != null) + { + ApplyParentStyles(pstyle, Parent as ChartContainer); + + pstyle.ApplyStyle(_ChartVisualStyle); + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles(PieChartVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + ChartPanel panel = item as ChartPanel; + + if (panel != null) + pstyle.ApplyStyle(panel.DefaultVisualStyles.PieChartVisualStyle); + } + else + { + ChartControl chartControl = ChartControl; + + pstyle.ApplyStyle(chartControl.BaseVisualStyles.PieChartVisualStyle); + pstyle.ApplyStyle(chartControl.DefaultVisualStyles.PieChartVisualStyle); + } + } + + #endregion + + #endregion + + #region ApplyStyles (StyleType) + + public override void ApplyStyles(BaseVisualStyle style, StyleType cs) + { + base.ApplyStyles(style, cs); + + PieCenterVisualStyle cstyle = style as PieCenterVisualStyle; + + if (cstyle != null) + { + ApplyParentStyles(cstyle, Parent as ChartContainer, cs); + + if (ChartVisualStyle.PieCenterVisualStyles != null) + cstyle.ApplyStyle(ChartVisualStyle.PieCenterVisualStyles[cs]); + } + } + + #region ApplyParentStyles (PieCenterVisualStyle) + + private void ApplyParentStyles( + PieCenterVisualStyle cstyle, ChartContainer item, StyleType cs) + { + if (item != null) + { + ApplyParentStyles(cstyle, item.Parent as ChartContainer, cs); + + ChartPanel panel = item as ChartPanel; + + if (panel != null) + { + if (panel.DefaultVisualStyles.PieChartVisualStyle.PieCenterVisualStyles != null) + cstyle.ApplyStyle(panel.DefaultVisualStyles.PieChartVisualStyle.PieCenterVisualStyles[cs]); + } + } + else + { + ChartControl chartControl = ChartControl; + + if (chartControl.BaseVisualStyles.PieChartVisualStyle.PieCenterVisualStyles != null) + cstyle.ApplyStyle(ChartControl.BaseVisualStyles.PieChartVisualStyle.PieCenterVisualStyles[cs]); + + if (chartControl.DefaultVisualStyles.PieChartVisualStyle.PieCenterVisualStyles != null) + cstyle.ApplyStyle(ChartControl.DefaultVisualStyles.PieChartVisualStyle.PieCenterVisualStyles[cs]); + } + } + + #endregion + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults(BaseVisualStyle style, StyleType cs) + { + PieCenterVisualStyle ctyle = style as PieCenterVisualStyle; + + if (ctyle != null) + { + ctyle.ApplyDefaults(); + } + else if (style is PieChartVisualStyle) + { + PieChartVisualStyle pstyle = (PieChartVisualStyle)style; + + pstyle.ApplyDefaults(); + } + + base.ApplyDefaults(style, cs); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + _EffectiveChartStyle = null; + + base.ClearEffectiveStyles(); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + PieChart copy = new PieChart(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + PieChart c = copy as PieChart; + + if (c != null) + { + base.CopyTo(c); + + c.CenterFirstSlice = CenterFirstSlice; + c.CenterLabel = CenterLabel; + c.CenterLabelVisibility = CenterLabelVisibility; + c.CenterPos = CenterPos; + + foreach (PieSeries series in ChartSeries) + c.ChartSeries.Add((PieSeries)series.Copy()); + + c.ChartVisualStyle = (_ChartVisualStyle != null) ? ChartVisualStyle.Copy() : null; + + c.DetachedOffset = DetachedOffset; + + c.EnableDragDetach = EnableDragDetach; + + c.EnableShiftDragExplode = EnableShiftDragExplode; + c.ExplodedMargin = ExplodedMargin; + c.ExplodedOffset = ExplodedOffset; + + c.GridInnerRadius = GridInnerRadius; + c.GridInterval = GridInterval; + c.GridMaxValue = GridMaxValue; + c.GridMinValue = GridMinValue; + c.GridOuterRadius = GridOuterRadius; + + c.InnerMargin = InnerMargin; + c.InnerRadius = InnerRadius; + + c.IsExploded = IsExploded; + + c.MaxDetachedOffset = MaxDetachedOffset; + c.MaxExplodedOffset = MaxExplodedOffset; + c.MaxRingOutRadius = MaxRingOutRadius; + c.MinOuterRadius = MinOuterRadius; + c.MinRingOutRadius = MinRingOutRadius; + + c.MouseClickSliceAction = MouseClickSliceAction; + c.MouseDoubleClickSliceAction = MouseDoubleClickSliceAction; + + c.MultiSelect = MultiSelect; + c.OuterMargin = OuterMargin; + c.OuterRadius = OuterRadius; + + c.PieRingOutDisplayMode = PieRingOutDisplayMode; + c.PieSelectionMode = PieSelectionMode; + + c.ReverseRingOrder = ReverseRingOrder; + c.SeriesMargin = SeriesMargin; + c.SeriesOverlayEnabled = SeriesOverlayEnabled; + + c.ShowFullGrid = ShowFullGrid; + c.ShowGridOnTop = ShowGridOnTop; + c.ShowAllRings = ShowAllRings; + c.ShowOtherSlice = ShowOtherSlice; + c.ShowPieGrid = ShowPieGrid; + c.ShowSliceLabelsOnEntry = ShowSliceLabelsOnEntry; + + c.SliceLabelOverlapMode = _SliceLabelOverlapMode; + + c.SubSliceVisualLayout = (_SubSliceVisualLayout != null) ? SubSliceVisualLayout.Copy() : null; + + c.UseAlternateGridBackground = UseAlternateGridBackground; + c.WhitespaceClickBehavior = WhitespaceClickBehavior; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "PieChart"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("CenterFirstSlice", CenterFirstSlice, Tbool.NotSet); + sec.AddValue("CenterLabel", CenterLabel, null); + sec.AddDataValue("CenterLabelVisibility", CenterLabelVisibility, CenterLabelVisibility.Always); + sec.AddValue("CenterPos", CenterPos, PointF.Empty); + + if (ChartSeries.Count > 0) + { + sec.AddStartElement("ChartSeries count=\"" + ChartSeries.Count + "\""); + + foreach (PieSeries series in ChartSeries) + sec.AddElement(series.GetSerialData("ChartSeries")); + + sec.AddEndElement("ChartSeries"); + } + + if (_ChartVisualStyle != null && _ChartVisualStyle.IsEmpty == false) + sec.AddElement(_ChartVisualStyle.GetSerialData("ChartVisualStyle")); + + sec.AddValue("EnableDragDetach", EnableDragDetach, Tbool.NotSet); + sec.AddValue("EnableShiftDragExplode", EnableShiftDragExplode, true); + + sec.AddValue("ExplodedMargin", ExplodedMargin, .1d); + sec.AddValue("ExplodedOffset", ExplodedOffset, .05d); + + sec.AddValue("GridInnerRadius", GridInnerRadius, 0d); + sec.AddValue("GridInterval", GridInterval, 10d); + sec.AddValue("GridMaxValue", GridMaxValue, 100d); + sec.AddValue("GridMinValue", GridMinValue, 0d); + sec.AddValue("GridOuterRadius", GridOuterRadius, 1d); + + sec.AddValue("InnerMargin", InnerMargin, 3d); + sec.AddValue("InnerRadius", InnerRadius, 0d); + + sec.AddValue("IsExploded", IsExploded, false); + + sec.AddValue("MaxDetachedOffset", MaxDetachedOffset, 100); + sec.AddValue("MaxExplodedOffset", MaxExplodedOffset, 100); + sec.AddValue("MaxRingOutRadius", MaxRingOutRadius, 48); + sec.AddValue("MinOuterRadius", MinOuterRadius, 80); + sec.AddValue("MinRingOutRadius", MinRingOutRadius, 9); + + sec.AddValue("MouseClickSliceAction", MouseClickSliceAction, MouseClickSliceAction.NotSet); + sec.AddValue("MouseDoubleClickSliceAction", MouseDoubleClickSliceAction, MouseDoubleClickSliceAction.NotSet); + + sec.AddValue("MultiSelect", MultiSelect, true); + sec.AddValue("OuterMargin", OuterMargin, 0d); + sec.AddValue("PieRingOutDisplayMode", PieRingOutDisplayMode, PieRingOutDisplayMode.OnMouseOver); + sec.AddValue("PieSelectionMode", PieSelectionMode, PieSelectionMode.NotSet); + sec.AddValue("ReverseRingOrder", ReverseRingOrder, false); + + sec.AddValue("SeriesMargin", SeriesMargin, 0d); + sec.AddValue("SeriesOverlayEnabled", SeriesOverlayEnabled, false); + + sec.AddValue("ShowFullGrid", ShowFullGrid, false); + sec.AddValue("ShowGridOnTop", ShowGridOnTop, false); + sec.AddValue("ShowAllRings", ShowAllRings, Tbool.NotSet); + sec.AddValue("ShowOtherSlice", ShowOtherSlice, Tbool.NotSet); + sec.AddValue("ShowPieGrid", ShowPieGrid, false); + sec.AddValue("ShowSliceLabelsOnEntry", ShowSliceLabelsOnEntry, false); + sec.AddValue("ShowToolTips", ShowToolTips, false); + sec.AddValue("SliceLabelOverlapMode", SliceLabelOverlapMode, SliceLabelOverlapMode.NotSet); + + if (_SubSliceVisualLayout != null) + sec.AddElement(_SubSliceVisualLayout.GetSerialData(true)); + + sec.AddValue("UseAlternateBackground", UseAlternateGridBackground, false); + sec.AddValue("WhitespaceClickBehavior", WhitespaceClickBehavior, WhitespaceClickBehavior.ClearSelection); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "CenterFirstSlice": + CenterFirstSlice = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "CenterLabel": + CenterLabel = se.StringValue; + break; + + case "CenterLabelVisibility": + CenterLabelVisibility = (CenterLabelVisibility)se.GetValueEnum(typeof(CenterLabelVisibility)); + break; + + case "CenterPos": + CenterPos = se.GetValuePointF(); + break; + + case "EnableDragDetach": + EnableDragDetach = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "EnableShiftDragExplode": + EnableShiftDragExplode = bool.Parse(se.StringValue); + break; + + case "ExplodedMargin": + ExplodedMargin = double.Parse(se.StringValue); + break; + + case "ExplodedOffset": + ExplodedOffset = double.Parse(se.StringValue); + break; + + case "GridInnerRadius": + GridInnerRadius = double.Parse(se.StringValue); + break; + + case "GridInterval": + GridInterval = double.Parse(se.StringValue); + break; + + case "GridMaxValue": + GridMaxValue = double.Parse(se.StringValue); + break; + + case "GridMinValue": + GridMinValue = double.Parse(se.StringValue); + break; + + case "GridOuterRadius": + GridOuterRadius = double.Parse(se.StringValue); + break; + + case "InnerMargin": + InnerMargin = double.Parse(se.StringValue); + break; + + case "InnerRadius": + InnerRadius = double.Parse(se.StringValue); + break; + + case "IsExploded": + IsExploded = bool.Parse(se.StringValue); + break; + + case "MaxDetachedOffset": + MaxDetachedOffset = int.Parse(se.StringValue); + break; + + case "MaxExplodedOffset": + MaxExplodedOffset = int.Parse(se.StringValue); + break; + + case "MaxRingOutRadius": + MaxRingOutRadius = int.Parse(se.StringValue); + break; + + case "MinOuterRadius": + MinOuterRadius = int.Parse(se.StringValue); + break; + + case "MinRingOutRadius": + MinRingOutRadius = int.Parse(se.StringValue); + break; + + case "MouseClickSliceAction": + MouseClickSliceAction = (MouseClickSliceAction)se.GetValueEnum(typeof(MouseClickSliceAction)); + break; + + case "MouseDoubleClickSliceAction": + MouseDoubleClickSliceAction = (MouseDoubleClickSliceAction)se.GetValueEnum(typeof(MouseDoubleClickSliceAction)); + break; + + case "MultiSelect": + MultiSelect = bool.Parse(se.StringValue); + break; + + case "OuterMargin": + OuterMargin = double.Parse(se.StringValue); + break; + + case "PieRingOutDisplayMode": + PieRingOutDisplayMode = (PieRingOutDisplayMode)se.GetValueEnum(typeof(PieRingOutDisplayMode)); + break; + + case "PieSelectionMode": + PieSelectionMode = (PieSelectionMode)se.GetValueEnum(typeof(PieSelectionMode)); + break; + + case "ReverseRingOrder": + ReverseRingOrder = bool.Parse(se.StringValue); + break; + + case "SeriesMargin": + SeriesMargin = double.Parse(se.StringValue); + break; + + case "SeriesOverlayEnabled": + SeriesOverlayEnabled = bool.Parse(se.StringValue); + break; + + case "ShowFullGrid": + ShowFullGrid = bool.Parse(se.StringValue); + break; + + case "ShowGridOnTop": + ShowGridOnTop = bool.Parse(se.StringValue); + break; + + case "ShowAllRings": + ShowAllRings = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShowOtherSlice": + ShowOtherSlice = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShowPieGrid": + ShowPieGrid = bool.Parse(se.StringValue); + break; + + case "ShowSliceLabelsOnEntry": + ShowSliceLabelsOnEntry = bool.Parse(se.StringValue); + break; + + case "ShowToolTips": + ShowToolTips = bool.Parse(se.StringValue); + break; + + case "SliceLabelOverlapMode": + SliceLabelOverlapMode = (SliceLabelOverlapMode)se.GetValueEnum(typeof(SliceLabelOverlapMode)); + break; + + case "UseAlternateBackground": + UseAlternateGridBackground = bool.Parse(se.StringValue); + break; + + case "WhitespaceClickBehavior": + WhitespaceClickBehavior = (WhitespaceClickBehavior)se.GetValueEnum(typeof(WhitespaceClickBehavior)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartSeries": + if (se.ArrayCount > 0) + { + sec.PutSerialData(this); + } + else + { + string name = sec.GetItemValue("Name"); + + PieSeries series = new PieSeries(name); + + ChartSeries.Add(series); + + sec.PutSerialData(series); + } + break; + + case "ChartVisualStyle": + sec.PutSerialData(ChartVisualStyle); + break; + + case "SliceVisualLayout": + sec.PutSerialData(SubSliceVisualLayout); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + Exploded = (1U << 0), + ReverseRingOrder = (1U << 1), + + MultiSelect = (1U << 2), + + Dragging = (1U << 3), + EnableShiftDragExplode = (1U << 4), + EnableCenterLabelMarkup = (1U << 5), + + ShowPieGrid = (1U << 6), + ShowGridOnTop = (1U << 7), + ShowFullGrid = (1U << 8), + ShowSliceLabelsOnEntry = (1U << 9), + ShowToolTips = (1U << 10), + + UseAlternateGridBackground = (1U << 11), + SeriesOverlayEnabled = (1U << 12), + + ShowPieRingsInLegend = (1U << 13), + ShowPieSeriesPointsInLegend = (1U << 14), + + UpdatePaletteNeeded = (1U << 15), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + } + + #region enums + + #region LegendTrackingMode + + /// + /// Defines the mode used to track mouse over interaction + /// between PieChart elements and associated Legend elements. + /// + public enum LegendTrackingMode + { + /// + /// NotSet + /// + NotSet, + + /// + /// No tracking. + /// + None, + + /// + /// Hit Chart elements are tracked in the Legend. + /// + Chart, + + /// + /// Hit Legend elements are tracked in the Chart. + /// + Legend, + + /// + /// Both hit Legend elements and Chart elements are tracked. + /// + ChartAndLegend, + } + + #endregion + + #region MouseClickSliceAction + + /// + /// Defines the action taken when a user + /// clicks with the mouse in a pie slice.. + /// + public enum MouseClickSliceAction + { + /// + /// NotSet + /// + NotSet, + + /// + /// No action taken. + /// + None, + + /// + /// Element select. + /// + Select, + + /// + /// Element detach toggle. + /// + Detach, + + /// + /// Pie Exploded. + /// + Explode, + } + + #endregion + + #region MouseDoubleClickSliceAction + + /// + /// Defines the action taken when a user + /// double-clicks with the mouse in a pie slice. + /// + public enum MouseDoubleClickSliceAction + { + /// + /// NotSet + /// + NotSet, + + /// + /// No action taken. + /// + None, + + /// + /// Change Active Ring (used when ShowAllRings is set to false). + /// + ChangeActiveRing, + + /// + /// Element detach toggle. + /// + Detach, + + /// + /// Pie Exploded. + /// + Explode, + } + + #endregion + + #region OtherSliceMethod + + /// + /// Defines the method used when determining + /// which slices are to be included in the 'Other' slice. + /// + public enum OtherSliceMethod + { + /// + /// Uses the percentage that is set by the OtherMinPercent property. + /// + MinPercent, + + /// + /// Uses the count that is set by the OtherMaxSlices property. + /// + MaxSlices, + } + + #endregion + + #region PieRadiusScale + + /// + /// Defines how the PieRadius values (InnerRadius, + /// OuterRadius, GridInnerRadius, and GridOuterRadius) values are interpreted). + /// + public enum PieRadiusScale + { + /// + /// Values are always taken as percentages of the content area. + /// + Percentage, + + /// + /// Values > 1 are taken as pixel values. + /// + Pixel, + } + + #endregion + + #region PieSelectionMode + + /// + /// Defines the selection mode used when the user + /// clicks on a pie element. + /// + public enum PieSelectionMode + { + /// + /// NotSet + /// + NotSet, + + /// + /// No selection. + /// + None, + + /// + /// Pie selection. + /// + Pie, + + /// + /// Series selection. + /// + Series, + + /// + /// Slice selection (includes nested PieSeriesPoints). + /// + Slice, + + /// + /// Ring level selection. + /// + Ring, + + /// + /// Individual PieSeriesPoint selection. + /// + Point, + } + + #endregion + + #region PspDragType + + /// + /// Defines the drag type. + /// + internal enum PspDragType + { + None, + + Explode, + Detach, + } + + #endregion + + #region PieRingOutDisplayMode + + /// + /// Defines when the 'RingOut' indicator is displayed. + /// + public enum PieRingOutDisplayMode + { + /// + /// Always displayed (when appropriate). + /// + Always, + + /// + /// Never displayed (user can go up a level by shift dbl-click). + /// + Never, + + /// + /// Indicator shown when mouse is over ring area in center of Pie. (default) + /// + OnMouseOver, + } + + #endregion + + #region SliceLabelOverlapMode + + /// + /// Specifies how overlapping outer slice Labels are resolved + /// + public enum SliceLabelOverlapMode + { + /// + /// Not set (default is None). + /// + NotSet = -1, + + /// + /// Overlapping labels will be shown. + /// + ShowOverlapping, + + /// + /// Overlapping labels will be hidden. + /// + HideOverlapping, + } + + #endregion + + #region SweepDirection + + /// + /// Defines the sweep direction. + /// + public enum SweepDirection + { + /// + /// NotSet + /// + NotSet, + + /// + /// Clockwise. + /// + Clockwise, + + /// + /// CounterClockwise. + /// + CounterClockwise, + } + + #endregion + + #region WhitespaceClickBehavior + + /// + /// Specifies the resultant behavior + /// of clicking in the chart whitespace area. + /// + public enum WhitespaceClickBehavior + { + /// + /// No effect + /// + None, + + /// + /// Current selection is cleared + /// + ClearSelection, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieLabel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieLabel.cs new file mode 100644 index 00000000..f94514a2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieLabel.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents a PieLabel (label associated with a pie data slice in the chart). + /// + public class PieLabel : IDisposable + { + #region Private data + + private PieSeriesPoint _PieSeriesPoint; + + private float _Angle; + private Rectangle _Bounds; + private Rectangle _ConnectorBounds; + + private Point _PtBoxEdge; + private Point _PtBoxBend; + private Point _PtSliceEdge; + + private double _Radius; + private double _OuterRadius; + + private string _Label; + private Size _LabelSize; + + private SliceOuterLabelVisualStyle _SliceLabelVisualStyle; + + private States _States; + + #endregion + + public PieLabel(PieSeriesPoint sp, string label) + { + _PieSeriesPoint = sp; + _Label = label; + + InitDefaultStates(); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + } + + #endregion + + #region Public properties + + #region Angle + + /// + /// Gets the angle used to display the point label + /// associated with the data point. + /// + public float Angle + { + get { return (_Angle); } + internal set { _Angle = value; } + } + + #endregion + + #region Bounds + + /// + /// Gets the label text bounds. + /// + public Rectangle Bounds + { + get { return (_Bounds); } + internal set { _Bounds = value; } + } + + #endregion + + #region IsLeftlabel + + /// + /// Gets whether the label is a left positioned + /// label (with respect to the chart slice). + /// + public bool IsLeftlabel + { + get { return (!TestState(States.RightLabel)); } + internal set { SetState(States.RightLabel, !value); } + } + + #endregion + + #region IsRightlabel + + /// + /// Gets whether the label is a right positioned + /// label (with respect to the chart slice). + /// + public bool IsRightlabel + { + get { return (TestState(States.RightLabel)); } + internal set { SetState(States.RightLabel, value); } + } + + #endregion + + #region Label + + /// + /// Gets or sets the label text + /// + public string Label + { + get { return (_Label); } + internal set { _Label = value; } + } + + #endregion + + #region LabelSize + + /// + /// Gets the label size. + /// + public Size LabelSize + { + get { return (_LabelSize); } + internal set { _LabelSize = value; } + } + + #endregion + + #region PieSeriesPoint + + /// + /// Gets the associated PieSeriesPoint. + /// + public PieSeriesPoint PieSeriesPoint + { + get { return (_PieSeriesPoint); } + internal set { _PieSeriesPoint = value; } + } + + #endregion + + #region PtBoxBend + + /// + /// Gets the middle connector point located + /// at the 'bend' of the connector. + /// + public Point PtBoxBend + { + get { return (_PtBoxBend); } + internal set { _PtBoxBend = value; } + } + + #endregion + + #region PtBoxEdge + + /// + /// Gets the connector point located and the + /// 'edge' of the label text bounding box. + /// + public Point PtBoxEdge + { + get { return (_PtBoxEdge); } + internal set { _PtBoxEdge = value; } + } + + #endregion + + #region PtSliceEdge + + /// + /// Gets the initial connector point, located at + /// the edge of the pie slice. + /// + public Point PtSliceEdge + { + get { return (_PtSliceEdge); } + internal set { _PtSliceEdge = value; } + } + + #endregion + + #region SliceLabelVisualStyle + + /// + /// Gets the current slice label VisualStyle for the label. + /// + public SliceOuterLabelVisualStyle LabelStyle + { + get { return (_SliceLabelVisualStyle); } + internal set { _SliceLabelVisualStyle = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region ConnectorBounds + + internal Rectangle ConnectorBounds + { + get { return (_ConnectorBounds); } + set { _ConnectorBounds = value; } + } + + #endregion + + #region OuterRadius + + internal double OuterRadius + { + get { return (_OuterRadius); } + set { _OuterRadius = value; } + } + + #endregion + + #region Radius + + internal double Radius + { + get { return (_Radius); } + set { _Radius = value; } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + RightLabel = (1U << 0), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public void Dispose() + { + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieReferenceLine.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieReferenceLine.cs new file mode 100644 index 00000000..b16a4670 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieReferenceLine.cs @@ -0,0 +1,404 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.Charts.TextMarkup; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of PieReferenceLines. + /// + [Editor("DevComponents.Charts.Design.PieReferenceCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class PieReferenceLineCollection : CustomNamedCollection + { + #region GetUniqueName + + /// + /// Gets a unique (unused) reference line Name. + /// + /// + public string GetUniqueName() + { + return (GetUniqueName("PieRefLine")); + } + + #endregion + } + + /// + /// Represents a reference line (a radial line on the chart + /// that can be used to signify, or reference, a specific chart value). + /// + public class PieReferenceLine : ChartVisualElement + { + #region Private variables + + private double _Value; + + private PieReferenceLineVisualStyle _ReferenceLineVisualStyle; + private EffectiveStyle _EffectiveStyle; + + #endregion + + #region Constructors + + /// + /// PieReferenceLine + /// + public PieReferenceLine() + { + _EffectiveStyle = new EffectiveStyle(this); + } + + /// + /// PieReferenceLine + /// + /// + public PieReferenceLine(string name) + : this() + { + Name = name; + } + + /// + /// PieReferenceLine + /// + /// + /// + public PieReferenceLine(string name, double value) + : this(name) + { + Value = value; + } + + #endregion + + #region Public properties + + #region EffectiveStyle + + /// + /// Gets a reference to the ReferenceLine's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public PieReferenceLineVisualStyle EffectiveStyle + { + get { return (_EffectiveStyle.Style); } + } + + #endregion + + #region ReferenceLineVisualStyle + + /// + /// Gets or sets the visual style for the Reference Line. + /// + [Category("Style")] + [Description("Indicates the visual style for the ReferenceLine.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieReferenceLineVisualStyle ReferenceLineVisualStyle + { + get + { + if (_ReferenceLineVisualStyle == null) + { + _ReferenceLineVisualStyle = new PieReferenceLineVisualStyle(); + + StyleVisualChangeHandler(null, _ReferenceLineVisualStyle); + } + + return (_ReferenceLineVisualStyle); + } + + set + { + if (_ReferenceLineVisualStyle != value) + { + PieReferenceLineVisualStyle oldValue = _ReferenceLineVisualStyle; + + _ReferenceLineVisualStyle = value; + + OnVisualStyleChanged("ReferenceLineVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region Value + + /// + /// Gets or sets the associated radial grid value of the reference line. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the associated radial grid value of the reference line.")] + //[TypeConverter("DevComponents.Charts.Design.PointValueConverter," + + // "DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public double Value + { + get { return (_Value); } + + set + { + if (value != _Value) + { + _Value = value; + + OnPropertyChangedEx("Value", VisualChangeType.Render); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + } + + #region RenderLine + + internal void RenderLine(ChartRenderInfo renderInfo) + { + } + + #endregion + + #endregion + + #region InvalidateRender + + public override void InvalidateRender() + { + ChartVisualElement cve = Parent as ChartVisualElement; + + if (cve != null) + cve.InvalidateRender(); + else + base.InvalidateRender(); + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + ChartLineVisualStyle rstyle = style as ChartLineVisualStyle; + + if (rstyle != null) + { + ApplyParentStyles(rstyle, Parent as ChartContainer); + + rstyle.ApplyStyle(ReferenceLineVisualStyle); + + if (rstyle.LineColor.IsEmpty == true) + rstyle.LineColor = Color.Red; + + if (rstyle.LineWidth < 0) + rstyle.LineWidth = 1; + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles(ChartLineVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + ChartPanel chartPanel = item as ChartPanel; + + if (chartPanel != null) + { + pstyle.ApplyStyle(chartPanel.DefaultVisualStyles.PieChartVisualStyle.ReferenceLineVisualStyle); + } + else if (item is PieChart) + { + PieChart pieChart = (PieChart)item; + + pstyle.ApplyStyle(pieChart.ChartVisualStyle.ReferenceLineVisualStyle); + } + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ReferenceLineVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ReferenceLineVisualStyle); + } + } + + #endregion + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Style definition + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + if (_EffectiveStyle.InvalidateStyle() == true) + InvalidateLayout(); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + PieReferenceLine copy = new PieReferenceLine(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + PieReferenceLine c = copy as PieReferenceLine; + + if (c != null) + { + base.CopyTo(c); + + c.Value = Value; + + c.ReferenceLineVisualStyle = + (_ReferenceLineVisualStyle != null) ? ReferenceLineVisualStyle.Copy() : null; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "PieReferenceLine"; + + sec.AddStartElement(serialName); + } + + if (_ReferenceLineVisualStyle != null && _ReferenceLineVisualStyle.IsEmpty == false) + sec.AddElement(_ReferenceLineVisualStyle.GetSerialData("ReferenceLineVisualStyle")); + + sec.AddValue("Value", Value, null); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Value": + Value = double.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ReferenceLineVisualStyle": + sec.PutSerialData(ReferenceLineVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + ReferenceLineVisualStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieRing.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieRing.cs new file mode 100644 index 00000000..da75f15e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieRing.cs @@ -0,0 +1,918 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + public class PieRing : ILegendItem, ILegendItemEx, INotifyPropertyChanged + { + #region Private variables + + private int _RingLevel; + private int _RingWeight = -1; + + private int _InnerRadius; + private int _OuterRadius; + private int _ExtentRadius; + + private PieSeries _ChartSeries; + private List _Psps; + + private ChartLegendItem _LegendItem; + private string _LegendText; + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + + private string _Name; + + private States _States; + + #endregion + + public PieRing() + { + InitDefaultStates(); + } + + public PieRing(int ringLevel) + : this() + { + RingLevel = ringLevel; + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.AllowDetach, true); + SetState(States.AllowSelect, true); + + SetState(States.CheckedInLegend, true); + SetState(States.ShowInLegend, true); + SetState(States.ShowInParentLegend, true); + SetState(States.ShowMarkerInLegend, true); + + SetState(States.Visible, true); + } + + #endregion + + #region Public properties + + #region AllowDetach + + /// + /// Gets or sets whether the element can be 'detached' from + /// the center of the pie by the user. Defaults to true. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the element can be 'detached' from the center of the pie by the user. Defaults to true.")] + public bool AllowDetach + { + get { return (TestState(States.AllowDetach)); } + + set + { + if (value != AllowDetach) + { + SetState(States.AllowDetach, value); + + OnPropertyChanged("AllowDetach"); + } + } + } + + #endregion + + #region AllowSelect + + /// + /// Gets or sets whether the ring can be selected by clicking on it. Defaults to true. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the ring can be selected by clicking on it. Defaults to true.")] + public bool AllowSelect + { + get { return (TestState(States.AllowSelect)); } + + set + { + if (value != AllowSelect) + { + SetState(States.AllowSelect, value); + + OnPropertyChanged("AllowSelect"); + } + } + } + + #endregion + + #region IsDisplayed + + /// + /// Gets whether the ring is displayed (based upon Visibility and Legend state). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDisplayed + { + get + { + if (ChartSeries != null) + { + PieChart pieChart = ChartSeries.Parent as PieChart; + + if (pieChart != null) + { + ItemCheckAction ica = (pieChart != null) + ? pieChart.Legend.ItemCheckAction : ItemCheckAction.ShowItem; + + return ((Visible == true) && + (ica == ItemCheckAction.None || + (ShowCheckBoxInLegend == false || CheckedInLegend == true))); + } + } + + return (false); + } + } + + #endregion + + #region Name + + /// + /// Gets or sets the user assigned Name of the item. + /// + [DefaultValue("")] + [Description("Indicates the Name of the item.")] + public virtual string Name + { + get { return (_Name); } + set { _Name = value; } + } + + #endregion + + #region RingWeight + + /// + /// Gets or sets the 'relative' thickness of the series ring, as + /// compared to the relative thickness of other series + /// rings. + /// + [DefaultValue(-1), Category("Display")] + [Description("Indicates the 'relative' thickness of the series ring, as compared to the relative thickness of other series rings.")] + public int RingWeight + { + get { return (_RingWeight); } + + set + { + if (value != _RingWeight) + { + _RingWeight = value; + + OnPropertyChangedEx("RingWeight", Style.VisualChangeType.Recalc); + } + } + } + + #endregion + + #region Visible + + /// + /// Get or sets whether the item is visible + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the item is visible")] + public virtual bool Visible + { + get { return (TestState(States.Visible)); } + + set + { + if (Visible != value) + { + SetState(States.Visible, value); + + OnPropertyChangedEx("Visible", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region ChartSeries + + internal PieSeries ChartSeries + { + get { return (_ChartSeries); } + set { _ChartSeries = value; } + } + + #endregion + + #region ExtentRadius + + internal int ExtentRadius + { + get { return (_ExtentRadius); } + set { _ExtentRadius = value; } + } + + #endregion + + #region InnerRadius + + internal int InnerRadius + { + get { return (_InnerRadius); } + set { _InnerRadius = value; } + } + + #endregion + + #region IsEnabled + + internal bool IsEnabled + { + get { return (IsRingEnabled()); } + } + + #region IsRingEnabled + + private bool IsRingEnabled() + { + if (ChartSeries != null) + { + int index = ChartSeries.PieRings.IndexOf(this); + + if (index >= 0) + { + for (int i = index - 1; i >= 0; i--) + { + PieRing pieRing = ChartSeries.PieRings[i]; + + if (pieRing.IsDisplayed == false) + return (false); + } + } + + return (ChartSeries.IsDisplayed); + } + + return (false); + } + + #endregion + + #endregion + + #region IsInitialRing + + internal bool IsInnerRing + { + get { return (TestState(States.InnerRing)); } + set { SetState(States.InnerRing, value); } + } + + #endregion + + #region IsOuterRing + + internal bool IsOuterRing + { + get { return (TestState(States.OuterRing)); } + set { SetState(States.OuterRing, value); } + } + + #endregion + + #region OuterRadius + + internal int OuterRadius + { + get { return (_OuterRadius); } + set { _OuterRadius = value; } + } + + #endregion + + #region Psps + + internal List Psps + { + get + { + if (_Psps == null) + _Psps = new List(); + + return (_Psps); + } + } + + #endregion + + #region RingLevel + + internal int RingLevel + { + get { return (_RingLevel); } + set { _RingLevel = value; } + } + + #endregion + + #endregion + + #region GetSelectionCount + + /// + /// Gets a count of the visible selected pie series points. + /// + /// + public int GetSelectionCount() + { + int count = 0; + + foreach (PieSeriesPoint psp in Psps) + { + if (psp.Visible == true) + { + if (psp.IsSelected == true) + count++; + } + } + + return (count); + } + + #endregion + + #region InvalidateRender + + internal void InvalidateRender(PieChart pieChart) + { + foreach (PieSeriesPoint psp in Psps) + pieChart.InvalidateRender(psp.PathBounds); + } + + #endregion + + #region ILegendItem + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the visual styles for the Legend item. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Legend item.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (_ChartLegendItemVisualStyles != value) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CheckedInLegend + + /// + /// Gets or sets whether the item is checked in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the item is checked in the Legend.")] + public bool CheckedInLegend + { + get { return (TestState(States.CheckedInLegend)); } + + set + { + if (value != CheckedInLegend) + { + SetState(States.CheckedInLegend, value); + + ChartSeries.InvalidateLayout(); + + if (LegendItem != null) + LegendItem.UpdateCheckState(); + + foreach (PieSeriesPoint psp in Psps) + { + if (psp.LegendItem != null) + psp.LegendItem.IsEnabled = psp.IsEnabled; + } + + OnPropertyChangedEx("CheckedInLegend", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowCheckBoxInLegend + + /// + /// Gets or sets whether a checkbox for the item is shown in the Legend. + /// + [DefaultValue(false), Category("Legend")] + [Description("Indicates whether a checkbox for the item is shown in the Legend.")] + public bool ShowCheckBoxInLegend + { + get { return (TestState(States.ShowCheckBoxInLegend)); } + + set + { + if (value != ShowCheckBoxInLegend) + { + SetState(States.ShowCheckBoxInLegend, value); + + OnPropertyChangedEx("ShowCheckBoxInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInLegend + + /// + /// Gets or sets whether the item is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the item is shown in the Legend.")] + public bool ShowInLegend + { + get { return (TestState(States.ShowInLegend)); } + + set + { + if (value != ShowInLegend) + { + SetState(States.ShowInLegend, value); + + OnPropertyChangedEx("ShowInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInParentLegend + + /// + /// Gets or sets whether the item Line is shown in parent Legend(s). + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the item Line is shown in parent Legend(s).")] + public bool ShowInParentLegend + { + get { return (TestState(States.ShowInParentLegend)); } + + set + { + if (value != ShowInParentLegend) + { + SetState(States.ShowInParentLegend, value); + + OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowMarkerInLegend + + /// + /// Gets or sets whether the item Marker is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the item Marker is shown in the Legend.")] + public bool ShowMarkerInLegend + { + get { return (TestState(States.ShowMarkerInLegend)); } + + set + { + if (value != ShowMarkerInLegend) + { + SetState(States.ShowMarkerInLegend, value); + + OnPropertyChangedEx("ShowMarkerInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LegendItem + + /// + /// Gets the item's parent LegendItem. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the item's parent LegendItem.")] + public ChartLegendItem LegendItem + { + get { return (_LegendItem); } + internal set { _LegendItem = value; } + } + + #endregion + + #region LegendText + + /// + /// Gets or sets the text to display in the legend. + /// + [DefaultValue(null), Category("Legend")] + [Description("Indicates the text to display in the legend.")] + [NotifyParentProperty(true)] + public string LegendText + { + get { return (_LegendText); } + + set + { + if (value != _LegendText) + { + _LegendText = value; + + OnPropertyChangedEx("LegendText", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region GetLegendItem + + /// + /// Creates the LegendItem for the item. + /// + /// + public ChartLegendItem GetLegendItem() + { + _LegendItem = null; + + if (ShowInLegend == true) + { + _LegendItem = new ChartLegendItem(); + + if (CheckedInLegend == true) + _LegendItem.CheckState = CheckState.Checked; + + _LegendItem.Name = Name; + _LegendItem.ItemText = LegendText; + + if (string.IsNullOrEmpty(_LegendItem.Name) == true) + _LegendItem.Name = "(PieRing " + (RingLevel + 1) + ")"; + + _LegendItem.IsEnabled = IsEnabled; + + _LegendItem.ChartItems.Add(this); + } + + return (_LegendItem); + } + + #endregion + + #region GetLegendItems + + /// + /// Creates a list of legend items associated with + /// the item. + /// + /// + public List GetLegendItems() + { + List list = new List(); + + for (int i = 0; i < Psps.Count; i++) + { + PieSeriesPoint psp = Psps[i]; + + if (psp.IsDisplayable == true) + { + List items = psp.GetLegendItems(); + + if (items != null && items.Count > 0) + list.AddRange(items); + } + } + + return (list); + } + + #endregion + + #region GetLegendItemColor + + /// + /// Gets the default color associated with the legend item. + /// + /// + public Color GetLegendItemColor() + { + if (Psps.Count > 0) + return (Psps[0].GetLegendItemColor()); + + return (ChartSeries.GetLegendItemColor()); + } + + #endregion + + #region RenderLegendItemMarker + + /// + /// Renders the Legend item Marker. + /// + /// + /// + /// + public void RenderLegendItemMarker(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + Rectangle bounds = litem.MarkerBounds; + bounds.Inflate(-1, -1); + + bounds.Width--; + bounds.Height--; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + if (IsEnabled == true) + { + Color color = GetLegendItemColor(); + + using (Pen pen = new Pen(color, 2)) + g.DrawEllipse(pen, bounds); + } + else + { + Color color = style.DisabledMarkerBackground.Color1; + + if (color.IsEmpty == true) + color = style.DisabledTextColor; + + if (color.IsEmpty == true) + color = Color.LightGray; + + using (Pen pen = new Pen(color, 2)) + g.DrawEllipse(pen, bounds); + } + + g.SmoothingMode = sm; + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + AllowSelect = (1U << 0), + AllowDetach = (1U << 1), + + InnerRing = (1U << 2), + OuterRing = (1U << 3), + + CheckedInLegend = (1U << 4), + ShowInLegend = (1U << 5), + ShowInParentLegend = (1U << 6), + ShowCheckBoxInLegend = (1U << 7), + ShowMarkerInLegend = (1U << 8), + + Visible = (1U << 9), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + #region OnPropertyChanged + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (PropertyChanged != null) + PropertyChanged(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType)); + } + + #endregion + + #region NotifyVisualParent + + internal void NotifyVisualParent(object sender, VisualChangeType vct) + { + object parent = sender; + + PieSeries series = ChartSeries; + + if (series != null) + { + if (vct == VisualChangeType.Layout) + series.InvalidateLayout(); + else + series.InvalidateRender(); + } + } + + #endregion + + #endregion + + #region OnStyleChanged + + protected virtual void OnStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + StyleChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #endregion + + #region StyleChangeHandler + + protected void StyleChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected void StyleChanged(object sender, PropertyChangedEventArgs e) + { + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + PieSeries series = ChartSeries; + + if (series != null) + { + if (series.ChartControl != null) + series.ChartControl.GlobalUpdateCount++; + + if (changeType == VisualChangeType.Layout) + series.InvalidateLayout(); + else + series.InvalidateRender(); + } + } + + #endregion + + #endregion + + #region InvalidateRender + + public void InvalidateRender() + { + PieSeries series = ChartSeries; + + if (series != null) + series.InvalidateRender(); + } + + #endregion + + #region TrackLegendItem + + /// + /// Gets whether legend item tracking is enabled. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TrackLegendItem + { + get + { + if (ChartSeries != null) + return (ChartSeries.TrackLegendItem); + + return (false); + } + } + + #endregion + + #region FormatItemText + + /// + /// Formats the provided item text. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string FormatItemText(string text) + { + return (text); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieSeries.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieSeries.cs new file mode 100644 index 00000000..5390cedc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/PieSeries.cs @@ -0,0 +1,6323 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of PieSeries. + /// + [Editor("DevComponents.Charts.Design.ChartSeriesCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartPieSeriesCollection : CustomNamedCollection + { + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("Series")); + } + + #endregion + } + + [TypeConverter(typeof(PieSeriesConverter))] + public class PieSeries : BaseSeries, ISeriesPointContainer, ILegendItemEx + { + #region Private variables + + private States _States; + + private PieSeriesPointCollection _SeriesPoints; + + private double _ExplodedMargin = double.NaN; + + private Point _PieCenter; + private List _PieRings; + + private int _RingWeightTotal; + + private Tbool _CenterFirstSlice = Tbool.NotSet; + + private Tbool _ShowAllRings = Tbool.NotSet; + private Tbool _ShowOtherSlice = Tbool.NotSet; + + private PieSeriesPointCollection _ActiveSeriesPointSet; + + private MouseClickSliceAction _MouseClickSliceAction = MouseClickSliceAction.NotSet; + private MouseDoubleClickSliceAction _MouseDoubleClickSliceAction = MouseDoubleClickSliceAction.NotSet; + + private PieSelectionMode _PieSelectionMode = PieSelectionMode.NotSet; + + private PieSeriesPoint _MouseDownPsp; + private int _MouseDownRadius; + private int _MouseDownOffset; + + private Tbool _EnableDragDetach = Tbool.NotSet; + + private SymbolDef _ScaleSymDef = new SymbolDef(); + private float _SymFontScale = -1; + + private SliceVisualLayout _SliceVisualLayout; + + private int _RingWeight = 100; + private int _RingWeightEx; + + private PaletteGroup _PaletteGroup = PaletteGroup.NotSet; + private Color[] _CustomPalette; + + private double _PieOuterExtent; + + #endregion + + #region Constructors + + public PieSeries() + : this(null) + { + } + + public PieSeries(string name) + { + Name = name; + SeriesType = SeriesType.Pie; + + InitDefaultStates(); + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.ShowInnerRingsEx, true); + } + + #endregion + + #region Public properties + + #region CenterFirstSlice + + /// + /// Gets or sets whether the first pie slice is centered + /// on the starting angle or starts on the starting angle. Default is false. + /// + [DefaultValue(Tbool.NotSet), Category("Display")] + [Description("Indicates whether the first pie slice is centered on the starting angle or starts on the starting angle. Default is false.")] + public Tbool CenterFirstSlice + { + get { return (_CenterFirstSlice); } + + set + { + if (value != _CenterFirstSlice) + { + _CenterFirstSlice = value; + + OnPropertyChangedEx("CenterFirstSlice", VisualChangeType.Layout); + } + } + } + + #endregion + + #region CustomPalette + + /// + /// Gets or sets the custom palette for the series. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the custom palette for the series.")] + public Color[] CustomPalette + { + get { return (_CustomPalette); } + + set + { + _CustomPalette = value; + + OnPropertyChangedEx("CustomPalette", VisualChangeType.Layout); + } + } + + #endregion + + #region EnableDragDetach + + /// + /// Gets or sets whether the user can detach associated series elements by Click and drag. + /// Note that MouseClickSelect must not be set to None or NotSet. + /// + [DefaultValue(Tbool.NotSet), Category("Behavior")] + [Description("Indicates whether the user can detach associated series elements by Click and drag. Note that MouseClickSelect must not be set to None or NotSet.")] + public Tbool EnableDragDetach + { + get { return (_EnableDragDetach); } + + set + { + if (value != _EnableDragDetach) + { + _EnableDragDetach = value; + + OnPropertyChangedEx("EnableDragDetach", VisualChangeType.Layout); + } + } + } + + #region GetEnableDragDetach + + internal bool GetEnableDragDetach(PieChart pieChart) + { + Tbool enable = EnableDragDetach; + + if (enable == Tbool.NotSet) + enable = pieChart.EnableDragDetach; + + return (enable == Tbool.True); + } + + #endregion + + #endregion + + #region ExplodedMargin + + /// + /// Gets or sets the exploded Margin for the series when the pie + /// is Exploded. The Margin is is measured as a percentage of the pie + /// radius (if less than 1) or the absolute pixel amount (if greater than 1). + /// + [DefaultValue(double.NaN), Category("Layout")] + [Description("Indicates the exploded Margin for the series when the pie is Exploded. The Margin is is measured as a percentage of the pie radius (if <= 1) or the absolute pixel amount (if > 1).")] + public double ExplodedMargin + { + get { return (_ExplodedMargin); } + + set + { + if (value != _ExplodedMargin) + { + _ExplodedMargin = value; + + OnPropertyChangedEx("ExplodedMargin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MouseClickSliceAction + + /// + /// Gets or sets the action used when the user clicks on a pie slice. + /// + [DefaultValue(MouseClickSliceAction.NotSet), Category("Behavior")] + [Description("Indicates the action used when the user clicks on a pie slice.")] + public MouseClickSliceAction MouseClickSliceAction + { + get { return (_MouseClickSliceAction); } + + set + { + if (value != _MouseClickSliceAction) + { + _MouseClickSliceAction = value; + + OnPropertyChanged("MouseClickSliceAction"); + } + } + } + + #region GetMouseClickSliceAction + + private MouseClickSliceAction GetMouseClickSliceAction(PieChart pieChart) + { + MouseClickSliceAction mca = + (MouseClickSliceAction != MouseClickSliceAction.NotSet) + ? MouseClickSliceAction : pieChart.MouseClickSliceAction; + + return ((mca != MouseClickSliceAction.NotSet) ? mca : MouseClickSliceAction.None); + } + + #endregion + + #endregion + + #region MouseDoubleClickSliceAction + + /// + /// Gets or sets the action used when the user double-clicks on a pie slice. + /// + [DefaultValue(MouseDoubleClickSliceAction.NotSet), Category("Behavior")] + [Description("Indicates the action used when the user clicks on a pie slice.")] + public MouseDoubleClickSliceAction MouseDoubleClickSliceAction + { + get { return (_MouseDoubleClickSliceAction); } + + set + { + if (value != _MouseDoubleClickSliceAction) + { + _MouseDoubleClickSliceAction = value; + + OnPropertyChanged("MouseDoubleClickSliceAction"); + } + } + } + + #region GetMouseDoubleClickSliceAction + + private MouseDoubleClickSliceAction GetMouseDoubleClickSliceAction(PieChart pieChart) + { + MouseDoubleClickSliceAction mca = + (MouseDoubleClickSliceAction != MouseDoubleClickSliceAction.NotSet) + ? MouseDoubleClickSliceAction : pieChart.MouseDoubleClickSliceAction; + + return ((mca != MouseDoubleClickSliceAction.NotSet) ? mca : MouseDoubleClickSliceAction.None); + } + + #endregion + + #endregion + + #region PaletteGroup + + /// + /// Gets or sets the palette color group to use (Light/Medium/Dark/Color1/MonoBlue/etc). + /// + [DefaultValue(PaletteGroup.NotSet), Category("Appearance")] + [Description("Indicates the palette color group to use (Light/Medium/Dark/Color1/MonoBlue/etc.).")] + public PaletteGroup PaletteGroup + { + get { return (_PaletteGroup); } + + set + { + if (value != _PaletteGroup) + { + _PaletteGroup = value; + + OnPropertyChangedEx("PaletteGroup", VisualChangeType.Recalc); + } + } + } + + #endregion + + #region PieSelectionMode + + /// + /// Gets or sets the mode used to perfoem pie selections. + /// + [DefaultValue(PieSelectionMode.NotSet), Category("Behavior")] + [Description("Indicates the mode used to perform pie selections.")] + public PieSelectionMode PieSelectionMode + { + get { return (_PieSelectionMode); } + + set + { + if (value != _PieSelectionMode) + { + _PieSelectionMode = value; + + OnPropertyChanged("PieSelectionMode"); + } + } + } + + #region GetPieSelectionMode + + internal PieSelectionMode GetPieSelectionMode(PieChart pieChart) + { + PieSelectionMode psm = PieSelectionMode; + + if (psm == PieSelectionMode.NotSet) + psm = pieChart.PieSelectionMode; + + return ((psm != PieSelectionMode.NotSet) ? psm : PieSelectionMode.Slice); + } + + #endregion + + #endregion + + #region ReversePaletteColors + + /// + /// Gets or sets whether default palette colors are utilized in reverse order. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether default palette colors are utilized in reverse order.")] + public virtual bool ReversePaletteColors + { + get { return (TestState(States.ReversePaletteColors)); } + + set + { + if (value != ReversePaletteColors) + { + SetState(States.ReversePaletteColors, value); + + OnPropertyChangedEx("ReversePaletteColors", VisualChangeType.Layout); + } + } + } + + #endregion + + #region RingWeight + + /// + /// Gets or sets the 'relative' total combined thickness of all series rings, as + /// compared to the relative thickness of other series combined rings. + /// rings. + /// + [DefaultValue(100), Category("Layout")] + [Description("Indicates the 'relative' total combined thickness of all series rings, as compared to the relative thickness of other series combined rings.. Default is 100.")] + public int RingWeight + { + get { return (_RingWeight); } + + set + { + if (value != _RingWeight) + { + _RingWeight = value; + + OnPropertyChangedEx("RingWeight", Style.VisualChangeType.Recalc); + } + } + } + + #endregion + + #region SeriesPoints + + /// + /// Gets or sets the series point data collection. + /// + [Category("Data")] + [Description("Indicates the series point data collection.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieSeriesPointCollection SeriesPoints + { + get + { + if (_SeriesPoints == null) + { + _SeriesPoints = new PieSeriesPointCollection(); + + _SeriesPoints.Parent = this; + + _SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged; + } + + return (_SeriesPoints); + } + + set + { + if (value != _SeriesPoints) + { + if (_SeriesPoints != null) + { + _SeriesPoints.Parent = null; + + _SeriesPoints.CollectionChanged -= SeriesPoints_CollectionChanged; + } + + _SeriesPoints = value; + + if (_SeriesPoints != null) + { + _SeriesPoints.Parent = this; + + _SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged; + } + } + } + } + + #region SeriesPoints_CollectionChanged + + void SeriesPoints_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + SeriesRangeChanged = true; + + SetPointNotify(e.OldItems, false); + SetPointNotify(e.NewItems, true); + + InvalidateLayout(); + } + + #region SetPointNotify + + private void SetPointNotify(IList list, bool notify) + { + if (list != null) + { + for (int i = 0; i < list.Count; i++) + { + PieSeriesPoint psp = list[i] as PieSeriesPoint; + + if (psp != null) + { + if (notify == true) + { + psp.Parent = SeriesPoints; + psp.PropertyChanged += Sp_PropertyChanged; + } + else + { + psp.Parent = null; + psp.PropertyChanged -= Sp_PropertyChanged; + } + } + } + } + } + + #endregion + + #region Sp_PropertyChanged + + void Sp_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + VisualPropertyChangedEventArgs vce = e as VisualPropertyChangedEventArgs; + + if (vce != null) + { + if (vce.ChangeType == VisualChangeType.Recalc) + { + InvalidateRecalc(); + } + else if (vce.ChangeType == VisualChangeType.Layout) + { + InvalidateLayout(); + } + else + { + PieSeriesPoint psp = sender as PieSeriesPoint; + + if (psp != null) + { + InvalidateRender(psp.Bounds); + InvalidateRender(psp.PathBounds); + } + else + { + InvalidateRender(); + } + } + + if (ChartControl != null) + ChartControl.GlobalUpdateCount++; + } + } + + #endregion + + #endregion + + #endregion + + #region ShowAllRings + + /// + /// Gets or sets whether all series rings are shown when rendering the chart. + /// If false, only one ring at a time is shown, with the ability to 'drill' up + /// or down, to display adjacent rings. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether all series Rings are shown when rendering the chart. If false, only one ring at a time is shown, with the ability to 'drill' up or down, to display adjacent rings.")] + public Tbool ShowAllRings + { + get { return (_ShowAllRings); } + + set + { + if (value != _ShowAllRings) + { + _ShowAllRings = value; + + OnPropertyChangedEx("ShowAllRings", VisualChangeType.Layout); + } + } + } + + #region ShowAllRingsEx + + internal bool ShowAllRingsEx(PieChart pieChart) + { + if (ShowAllRings != Tbool.NotSet) + return (ShowAllRings != Tbool.False); + + return (pieChart.ShowAllRings != Tbool.False); + } + + #endregion + + #endregion + + #region ShowOtherSlice + + /// + /// Gets or sets whether to consolidate smaller pie slices into a single slice that + /// represents 'other' data values, or whether to display those smaller slices + /// as separate pie slices. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether to consolidate smaller pie slices into a single slice that represents 'other' data values, or whether to display those smaller slices as separate pie slices.")] + public Tbool ShowOtherSlice + { + get { return (_ShowOtherSlice); } + + set + { + if (value != _ShowOtherSlice) + { + _ShowOtherSlice = value; + + OnPropertyChangedEx("ShowOtherSlice", VisualChangeType.Layout); + } + } + } + + #region ShowOtherSliceEx + + internal bool ShowOtherSliceEx(PieChart pieChart) + { + if (ShowOtherSlice != Tbool.NotSet) + return (ShowOtherSlice == Tbool.True); + + return (pieChart.ShowOtherSlice == Tbool.True); + } + + #endregion + + #endregion + + #region SubSliceVisualLayout + + /// + /// Gets or sets the default layout of the subordinate or nested series slices. + /// + [Category("Layout")] + [Description("Indicates the default layout of the subordinate or nested series slices.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SliceVisualLayout SubSliceVisualLayout + { + get + { + if (_SliceVisualLayout == null) + SubSliceVisualLayout = new SliceVisualLayout(this); + + return (_SliceVisualLayout); + } + + set + { + if (value != _SliceVisualLayout) + { + if (_SliceVisualLayout != null) + _SliceVisualLayout.PropertyChanged -= SliceVisualLayout_PropertyChanged; + + _SliceVisualLayout = value; + + if (_SliceVisualLayout != null) + _SliceVisualLayout.PropertyChanged += SliceVisualLayout_PropertyChanged; + + OnPropertyChangedEx("SliceVisualLayout", VisualChangeType.Recalc); + } + } + } + + #region SliceVisualLayout_PropertyChanged + + void SliceVisualLayout_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + VisualPropertyChangedEventArgs vce = e as VisualPropertyChangedEventArgs; + + if (vce != null) + { + OnPropertyChangedEx(vce.PropertyName, vce.ChangeType); + + if (ChartControl != null) + ChartControl.GlobalUpdateCount++; + } + } + + #endregion + + #endregion + + #region Visible + + /// + /// Gets or sets whether the series is visible or not. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the series is visible or not.")] + public override bool Visible + { + get { return (base.Visible); } + + set + { + if (Visible != value) + { + base.Visible = value; + + SeriesRangeChanged = true; + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region ActiveSeriesPointCollection + + internal PieSeriesPointCollection ActiveSeriesPointCollection + { + get { return (_ActiveSeriesPointSet); } + set { _ActiveSeriesPointSet = value; } + } + + #endregion + + #region IsInnerRingSeries + + internal bool IsInnerRingSeries + { + get { return (TestState(States.IsInnerRingSeries)); } + set { SetState(States.IsInnerRingSeries, value); } + } + + #endregion + + #region IsOffset + + internal bool IsOffset + { + get { return (TestState(States.IsOffset)); } + set { SetState(States.IsOffset, value); } + } + + #endregion + + #region IsOuterRingSeries + + internal bool IsOuterRingSeries + { + get { return (TestState(States.IsOuterRingSeries)); } + set { SetState(States.IsOuterRingSeries, value); } + } + + #endregion + + #region PieCenter + + internal Point PieCenter + { + get { return (_PieCenter); } + set { _PieCenter = value; } + } + + #endregion + + #region PieOuterExtent + + internal double PieOuterExtent + { + get { return (_PieOuterExtent); } + set { _PieOuterExtent = value; } + } + + #endregion + + #region PieRings + + internal List PieRings + { + get + { + if (_PieRings == null) + _PieRings = new List(); + + return (_PieRings); + } + } + + #endregion + + #region RingWeightTotal + + internal int RingWeightTotal + { + get { return (_RingWeightTotal); } + set { _RingWeightTotal = value; } + } + + #endregion + + #region RingWeightEx + + internal int RingWeightEx + { + get { return (_RingWeightEx); } + set { _RingWeightEx = value; } + } + + #endregion + + #region SymFontScale + + internal float SymFontScale + { + get { return (_SymFontScale); } + set { _SymFontScale = value; } + } + + #endregion + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + if (SeriesPoints.Count > 0) + { + PieChart pieChart = Parent as PieChart; + + Point pt = pieChart.GetGlobalAdjustedPoint(pieChart.ContentBounds.Location); + RenderBounds = new Rectangle(pt, pieChart.ContentBounds.Size); + + if (RenderBounds.Width > 0 && RenderBounds.Height > 0) + RenderPieSeries(renderInfo); + } + } + + #region RenderPieSeries + + private void RenderPieSeries(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + PieChart pieChart = Parent as PieChart; + + PieSeriesPointCollection spc = GetActiveSeriesPointCollection(); + + RenderPieSeriesEx(g, renderInfo.ClipRectangle, pieChart, spc); + } + + #region RenderPieSeriesEx + + private void RenderPieSeriesEx(Graphics g, + Rectangle clip, PieChart pieChart, PieSeriesPointCollection spc) + { + if (spc != null) + spc = spc.PieSlices; + + if (spc != null) + { + foreach (PieSeriesPoint psp in spc) + { + if (psp.PieRing != null) + { + if (psp.PieRing.IsDisplayed == true) + RenderSlice(g, clip, pieChart, spc, psp); + } + } + } + } + + #region RenderSlice + + private void RenderSlice(Graphics g, Rectangle clip, + PieChart pieChart, PieSeriesPointCollection spc, PieSeriesPoint psp) + { + if (PspNeedsDisplayed(pieChart, psp, clip) == true) + { + Region rgn = null; + + int outerRadius = (int)psp.OuterRadius; + int innerRadius = (int)psp.InnerRadius; + + ChartSliceVisualStyle sstyle = psp.GetEffectiveSliceStyle(pieChart, this); + + if (psp.IsEmpty == false) + RenderReferenceLines(g, pieChart, spc, psp, false); + + RenderSliceEx(g, ref rgn, pieChart, + spc, psp, outerRadius, innerRadius, sstyle); + + if (psp.IsEmpty == false) + { + if (psp.IsOther == true) + { + if (ShowAllRingsEx(pieChart) == true) + { + List pieRings = psp.PieRing.ChartSeries.PieRings; + + outerRadius = innerRadius; + innerRadius = pieRings[pieRings.Count - 1].InnerRadius; + + RenderSliceOtherSpace(g, ref rgn, + pieChart, psp, outerRadius, innerRadius, sstyle); + } + } + } + + psp.PathBounds = (rgn != null) + ? Rectangle.Ceiling(rgn.GetBounds(g)) : Rectangle.Empty; + + if (psp.IsEmpty == false) + { + if (sstyle.ImageOverlay == ImageOverlay.Bottom) + RenderSliceFigure(g, rgn, pieChart, psp, sstyle); + + if ((sstyle.ImageOverlay == ImageOverlay.Middle) || + (sstyle.ImageOverlay == ImageOverlay.NotSet)) + { + RenderSliceFigure(g, rgn, pieChart, psp, sstyle); + } + + RenderSliceLabel(g, pieChart, psp, sstyle); + + if (sstyle.ImageOverlay == ImageOverlay.Top) + RenderSliceFigure(g, rgn, pieChart, psp, sstyle); + + RenderReferenceLines(g, pieChart, spc, psp, true); + } + + //using (StringFormat sf = new StringFormat()) + //{ + // sf.Alignment = StringAlignment.Center; + // sf.LineAlignment = StringAlignment.Center; + + // g.DrawString(psp.RenderCount.ToString(), + // SystemFonts.DefaultFont, Brushes.Black, psp.PathBounds, sf); + //} + + //psp.RenderCount++; + } + + if (ShowAllRingsEx(pieChart) == true) + { + if (psp.SeriesPoints != null) + RenderPieSeriesEx(g, clip, pieChart, psp.SeriesPoints); + } + } + + #region PspNeedsDisplayed + + private bool PspNeedsDisplayed(PieChart pieChart, PieSeriesPoint psp, Rectangle clip) + { + if (psp.IsDisplayedEx == true) + { + if (psp.SweepAngleEx != 0) + { + Rectangle r = psp.Bounds; + + if (r.Width > 0 && r.Height > 0) + { + if (psp.InnerRadius < psp.OuterRadius) + { + if (psp.PathBounds.IsEmpty == true || clip.IntersectsWith(psp.PathBounds) == true) + return (true); + } + } + } + } + + return (false); + } + + #endregion + + #region RenderSliceEx + + private void RenderSliceEx(Graphics g, ref Region rgn, + PieChart pieChart, PieSeriesPointCollection spc, PieSeriesPoint psp, + int outerRadius, int innerRadius, ChartSliceVisualStyle sstyle) + { + int width = outerRadius - innerRadius; + int extentWidth = (int)(psp.SliceExtent * width); + + bool renderShading = (sstyle.EnableShading == Tbool.True); + + SliceRenderType renderType = SliceRenderType.FullSlice; + + if (psp.HasExtent == true) + { + int extentRadius = innerRadius + extentWidth; + + if (extentWidth < width) + { + renderType = SliceRenderType.ExtentSlice; + + if (psp.ShowSliceWhiteSpaceEx == true) + { + RenderSliceWhiteSpace(g, ref rgn, pieChart, + psp, outerRadius, extentRadius, renderShading, sstyle); + + renderShading = false; + } + } + + outerRadius = extentRadius; + } + + RenderSliceExtent(g, ref rgn, pieChart, + psp, outerRadius, innerRadius, renderShading, renderType, sstyle); + } + + #region RenderSliceWhiteSpace + + private void RenderSliceWhiteSpace(Graphics g, ref Region rgn, + PieChart pieChart, PieSeriesPoint psp, int outerRadius, + int innerRadius, bool renderShading, ChartSliceVisualStyle sstyle) + { + Background background = sstyle.WhiteSpaceBackground; + ChartLineVisualStyle border = sstyle.WhiteSpaceBorder; + + GraphicsState gs = g.Save(); + + g.TranslateTransform((float)psp.SliceCenter.X, (float)psp.SliceCenter.Y); + g.RotateTransform((float)(psp.CenterAngle) % 360); + + Rectangle r = new Rectangle(); + + r.X = r.Y = -outerRadius; + r.Width = r.Height = (outerRadius * 2); + + float angle = (float)GetSweepAngle(psp); + + // Try to blend the edges of the slice better. + + //if (background.IsDisplayable == true && border.IsDisplayable == false) + // angle += .1f; + + ChartControl chartControl = ChartControl; + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddArc(r, -angle / 2, angle); + + if (psp.SliceExtent == 0) + { + path.AddLine(Point.Empty, Point.Empty); + path.CloseFigure(); + + if (chartControl.DoPreRenderSliceEvent( + g, path, pieChart, this, psp, SliceRenderType.ExtentWhitespace) == false) + { + Rectangle pb = Rectangle.Truncate(path.GetBounds()); + + if (psp.IsEmpty == false) + { + if (background.IsDisplayable == true) + { + using (Brush br = background.GetBrush(pb)) + g.FillPath(br, path); + } + } + + if (border.IsDisplayable == true) + { + using (Pen pen = new Pen(border.LineColor, Dpi.Width(border.LineWidth))) + { + if (border.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)border.LinePattern; + + g.DrawPath(pen, path); + } + } + + chartControl.DoPostRenderSliceEvent( + g, path, pieChart, this, psp, SliceRenderType.ExtentWhitespace); + } + + if (psp.IsEmpty == false) + { + if (renderShading == true) + RenderShading(g, psp, path); + } + + path.Transform(g.Transform); + + if (rgn == null) + rgn = new Region(path); + } + else + { + int pcount = path.PointCount; + + Rectangle t = new Rectangle(); + t.X = t.Y = (-innerRadius); + t.Width = t.Height = (innerRadius * 2); + + path.AddArc(t, angle / 2, -angle); + + PointF ppt1 = path.PathPoints[pcount]; + PointF ppt2 = path.GetLastPoint(); + + path.CloseFigure(); + + if (chartControl.DoPreRenderSliceEvent( + g, path, pieChart, this, psp, SliceRenderType.ExtentWhitespace) == false) + { + if (psp.IsEmpty == false) + { + if (background.IsDisplayable == true) + { + t = Rectangle.Ceiling(path.GetBounds()); + + Rectangle t2 = t; + t2.Width = outerRadius - (int)psp.InnerRadius; + t2.X = -t2.Width; + + using (Brush br = background.GetBrush(t2)) + g.FillPath(br, path); + } + + if (renderShading == true) + RenderShading(g, psp, path); + } + + path.Transform(g.Transform); + + if (rgn == null) + rgn = new Region(path); + + if (border.IsDisplayable == true) + { + path.Reset(); + + using (Pen pen = new Pen(border.LineColor, Dpi.Width(border.LineWidth))) + { + if (border.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)border.LinePattern; + + path.AddLine(ppt2, ppt2); + path.AddArc(r, -angle / 2, angle); + path.AddLine(ppt1, ppt1); + + g.DrawPath(pen, path); + } + } + + chartControl.DoPostRenderSliceEvent( + g, path, pieChart, this, psp, SliceRenderType.ExtentWhitespace); + } + } + } + + g.Restore(gs); + } + + #endregion + + #region RenderSliceExtent + + private void RenderSliceExtent(Graphics g, ref Region rgn, + PieChart pieChart, PieSeriesPoint psp, int outerRadius, int innerRadius, + bool renderShading, SliceRenderType renderType, ChartSliceVisualStyle sstyle) + { + if (outerRadius - innerRadius > 0) + { + GraphicsState gs = g.Save(); + + g.TranslateTransform((float)psp.SliceCenter.X, (float)psp.SliceCenter.Y); + g.RotateTransform((float)(psp.CenterAngle) % 360); + + Rectangle r = new Rectangle(); + + r.X = r.Y = -outerRadius; + r.Width = r.Height = (outerRadius * 2); + + float angle = (float)GetSweepAngle(psp); + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddArc(r, -angle / 2, angle); + + if (psp.InnerRadius == 0) + { + path.AddLine(Point.Empty, Point.Empty); + } + else + { + Rectangle t = new Rectangle(); + t.X = t.Y = -innerRadius; + t.Width = t.Height = innerRadius * 2; + + path.AddArc(t, angle / 2, -angle); + } + + path.CloseFigure(); + + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSliceEvent(g, path, pieChart, this, psp, renderType) == false) + { + if (psp.IsEmpty == false) + { + if (sstyle.Background.IsDisplayable == true) + { + r = Rectangle.Ceiling(path.GetBounds()); + + if (psp.HasExtent == true) + { + switch (sstyle.ExtentFillRange) + { + case ExtentFillRange.ByRing: + r.Width = psp.PieRing.ExtentRadius - innerRadius; + break; + + case ExtentFillRange.BySlice: + PieSeriesPointCollection spc = psp.Parent as PieSeriesPointCollection; + + if (spc != null) + { + double sliceExtent = spc.PieMaxExtent / spc.PieOuterExtent; + + int width = (int)(psp.OuterRadius - psp.InnerRadius); + int extentWidth = (int)(sliceExtent * width); + + r.Width = extentWidth; + } + break; + } + } + + using (Brush br = sstyle.Background.GetBrush(r)) + g.FillPath(br, path); + } + } + + if (sstyle.Border.IsDisplayable == true) + { + using (Pen pen = new Pen( + sstyle.Border.LineColor, Dpi.Width(sstyle.Border.LineWidth))) + { + if (sstyle.Border.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)sstyle.Border.LinePattern; + + g.DrawPath(pen, path); + } + } + + chartControl.DoPostRenderSliceEvent(g, path, pieChart, this, psp, renderType); + } + + if (psp.IsEmpty == false) + { + if (renderShading == true) + RenderShading(g, psp, path); + } + + path.Transform(g.Transform); + + if (rgn == null) + rgn = new Region(path); + else + rgn.Union(path); + + g.Restore(gs); + } + } + } + + #region GetSweepAngle + + private double GetSweepAngle(PieSeriesPoint psp) + { + double sweepAngle = psp.SweepAngleEx; + + if (sweepAngle > 360) + sweepAngle %= 360; + + return (sweepAngle); + } + + #endregion + + #endregion + + #endregion + + #region RenderSliceOtherSpace + + private void RenderSliceOtherSpace(Graphics g, + ref Region rgn, PieChart pieChart, PieSeriesPoint psp, + int outerRadius, int innerRadius, ChartSliceVisualStyle sstyle) + { + if (outerRadius - innerRadius > 0) + { + GraphicsState gs = g.Save(); + + g.TranslateTransform((float)psp.SliceCenter.X, (float)psp.SliceCenter.Y); + g.RotateTransform((float)(psp.CenterAngle) % 360); + + Rectangle r = new Rectangle(); + + r.X = r.Y = -outerRadius; + r.Width = r.Height = (outerRadius * 2); + + float angle = (float)GetSweepAngle(psp); + + Background background = sstyle.WhiteSpaceBackground; + ChartLineVisualStyle border = sstyle.WhiteSpaceBorder; + + ChartControl chartControl = ChartControl; + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddArc(r, -angle / 2, angle); + + if (innerRadius == 0) + { + path.AddLine(Point.Empty, Point.Empty); + path.CloseFigure(); + + if (chartControl.DoPreRenderSliceEvent( + g, path, pieChart, this, psp, SliceRenderType.OtherWhitespace) == false) + { + Rectangle pb = Rectangle.Truncate(path.GetBounds()); + + if (background.IsEmpty == false) + { + using (Brush br = background.GetBrush(pb)) + g.FillPath(br, path); + } + + if (border.IsDisplayable == true) + { + using (Pen pen = new Pen(border.LineColor, Dpi.Width(border.LineWidth))) + { + if (border.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)border.LinePattern; + + g.DrawPath(pen, path); + } + } + + chartControl.DoPostRenderSliceEvent( + g, path, pieChart, this, psp, SliceRenderType.OtherWhitespace); + } + + path.Transform(g.Transform); + + if (rgn == null) + rgn = new Region(path); + else + rgn.Union(path); + } + else + { + int pcount = path.PointCount; + + Rectangle t = new Rectangle(); + + t.X = t.Y = -innerRadius; + t.Width = t.Height = (innerRadius * 2); + + PointF ppt1 = path.PathPoints[0]; + PointF ppt2 = path.GetLastPoint(); + + path.AddArc(t, angle / 2, -angle); + path.CloseFigure(); + + if (chartControl.DoPreRenderSliceEvent( + g, path, pieChart, this, psp, SliceRenderType.OtherWhitespace) == false) + { + Rectangle pb = Rectangle.Ceiling(path.GetBounds()); + + if (background.IsEmpty == false) + { + using (Brush br = background.GetBrush(pb)) + g.FillPath(br, path); + } + + path.Transform(g.Transform); + + if (rgn == null) + rgn = new Region(path); + else + rgn.Union(path); + + if (border.IsDisplayable == true) + { + using (Pen pen = new Pen(border.LineColor, Dpi.Width(border.LineWidth))) + { + if (border.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)border.LinePattern; + + path.Reset(); + + path.AddLine(ppt1, ppt1); + path.AddArc(t, -angle / 2, angle); + path.AddLine(ppt2, ppt2); + + g.DrawPath(pen, path); + } + } + + chartControl.DoPostRenderSliceEvent( + g, path, pieChart, this, psp, SliceRenderType.OtherWhitespace); + } + else + { + path.Transform(g.Transform); + + if (rgn == null) + rgn = new Region(path); + else + rgn.Union(path); + } + } + } + + g.Restore(gs); + } + } + + #endregion + + #region RenderShading + + private void RenderShading(Graphics g, PieSeriesPoint psp, GraphicsPath path) + { + PieChart pieChart = Parent as PieChart; + + int radius = (int)((psp.HasExtent == true) ? psp.ExtentRadius : psp.OuterRadius); + + Rectangle r = new Rectangle(); + r.Inflate(radius, radius); + + Region clip = g.Clip; + g.SetClip(path, CombineMode.Intersect); + + using (GraphicsPath path2 = new GraphicsPath()) + { + path2.AddEllipse(r); + + PathGradientBrush pbr = new PathGradientBrush(path2); + + ColorBlend cb = new ColorBlend(3); + + Color[] colors = new Color[3]; + + colors[0] = Color.FromArgb(100, Color.Black); + colors[1] = Color.Transparent; + colors[2] = Color.Transparent; + + cb.Colors = colors; + + float[] cp = new float[3]; + + cp[0] = 0f; + cp[1] = .07f; + cp[2] = 1f; + + cb.Positions = cp; + + pbr.InterpolationColors = cb; + + g.FillEllipse(pbr, r); + } + + g.Clip = clip; + } + + #endregion + + #region RenderReferenceLines + + private void RenderReferenceLines(Graphics g, PieChart pieChart, + PieSeriesPointCollection spc, PieSeriesPoint psp, bool onTop) + { + if (spc.PieOuterExtent > 0) + { + ISeriesPointContainer ispc = spc.Parent; + + if (ispc != null) + { + if (psp.ReferenceLineDisplayOnTopEx == onTop) + { + PieRefLineDisplayMode mode = psp.ReferenceLineDisplayModeEx; + + if ((mode != PieRefLineDisplayMode.NotSet) && + ((mode & PieRefLineDisplayMode.None) != PieRefLineDisplayMode.None)) + { + ChartSliceVisualStyle sstyle = psp.GetEffectiveSliceStyle(pieChart, this); + + int width = psp.OuterRadius - psp.InnerRadius; + + float start = (float)psp.StartAngleEx; + float sweep = (float)psp.SweepAngleEx; + + if ((mode & PieRefLineDisplayMode.ExtentAverage) == PieRefLineDisplayMode.ExtentAverage) + { + int avg = (int)((spc.PieAverageExtent / spc.PieOuterExtent) * width); + + RenderReferenceLine(g, psp, start, sweep, + avg + psp.InnerRadius, sstyle.ExtentAverageRefLineStyle); + } + + if ((mode & PieRefLineDisplayMode.ExtentMinimum) == PieRefLineDisplayMode.ExtentMinimum) + { + int min = (int)((spc.PieMinExtent / spc.PieOuterExtent) * width); + + RenderReferenceLine(g, psp, start, sweep, + min + psp.InnerRadius, sstyle.ExtentMinRefLineStyle); + } + + if ((mode & PieRefLineDisplayMode.ExtentMaximum) == PieRefLineDisplayMode.ExtentMaximum) + { + int max = (int)((spc.PieMaxExtent / spc.PieOuterExtent) * width); + + RenderReferenceLine(g, psp, start, sweep, + max + psp.InnerRadius, sstyle.ExtentMaxRefLineStyle); + } + + if ((mode & PieRefLineDisplayMode.ExtentOuterRadius) == PieRefLineDisplayMode.ExtentOuterRadius) + { + RenderReferenceLine(g, psp, start, sweep, + psp.OuterRadius, sstyle.ExtentOuterRefLineStyle); + } + + if ((mode & PieRefLineDisplayMode.UserDefined) == PieRefLineDisplayMode.UserDefined) + { + List lines = psp.ReferenceLinesEx; + + if (lines.Count > 0) + { + foreach (PieReferenceLine line in lines) + { + if (line.Visible == true) + { + double radius = (line.Value / spc.PieOuterExtent) * width; + + RenderReferenceLine(g, psp, start, sweep, + radius + psp.InnerRadius, line.EffectiveStyle); + } + } + } + } + } + } + } + } + } + + #region RenderReferenceLine + + private void RenderReferenceLine(Graphics g, PieSeriesPoint psp, + float start, float sweep, double radius, PieReferenceLineVisualStyle rstyle) + { + if (radius > 0) + { + if (rstyle.IsDisplayable == true) + { + Rectangle r = new Rectangle(); + r.Location = psp.SliceCenter; + + r.Inflate((int)radius, (int)radius); + + using (Pen pen = new Pen(rstyle.LineColor, rstyle.LineWidth)) + { + if (rstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)rstyle.LinePattern; + + g.DrawArc(pen, r, start, sweep); + } + } + } + } + + #endregion + + #endregion + + #region RenderSliceFigure + + private void RenderSliceFigure(Graphics g, Region rgn, + PieChart pieChart, PieSeriesPoint psp, ChartSliceVisualStyle sstyle) + { + object figure = sstyle.GetFigure(); + + if (figure != null) + { + double radius = GetFigureRadius(psp, sstyle); + double centerAngle = psp.CenterAngle; + + double angle = GetImageAngle(psp, centerAngle, sstyle); + + Point pt = psp.GetRayEndPoint(angle, radius); + Size srcSize = sstyle.GetFigureSizeEx(g); + + srcSize.Height = Dpi.DescaleHeight(srcSize.Height); + srcSize.Width = Dpi.DescaleWidth(srcSize.Width); + + Rectangle srcRect = new Rectangle(pt, Size.Empty); + Rectangle destRect = srcRect; + + double scaleFactor = GetImageSideFactor(psp, radius, srcSize); + + Size destSize = srcRect.Size; + + if (scaleFactor != 1) + { + double dh = (double)srcSize.Width / srcSize.Height; + destSize = new Size((int)(dh * scaleFactor * 2), (int)scaleFactor * 2); + } + + srcRect.Inflate(srcSize.Width / 2, srcSize.Height / 2); + destRect.Inflate(destSize.Width / 2, destSize.Height / 2); + + bool scaleImage = (double.IsNaN(sstyle.ImageScale) == false); + + Region clip = null; + + if (scaleImage == false) + { + if (sstyle.ImageCropMode == SliceImageCropMode.ClipImage) + { + clip = g.Clip; + + g.SetClip(rgn, CombineMode.Intersect); + } + else if (sstyle.ImageCropMode == SliceImageCropMode.HideImage) + { + if (destRect.Contains(srcRect) == false) + return; + } + + destRect = srcRect; + } + + psp.PathBounds = Rectangle.Union(psp.PathBounds, destRect); + + GraphicsState gState = null; + + if (sstyle.ImageAutoRotate == Tbool.True || sstyle.ImageRotation != 0) + { + gState = g.Save(); + + destRect.X = -(destRect.Width / 2); + destRect.Y = -(destRect.Height / 2); + + g.TranslateTransform(pt.X, pt.Y); + + if (sstyle.ImageAutoRotate == Tbool.True) + g.RotateTransform((float)angle); + + if (sstyle.ImageRotation != 0) + g.RotateTransform((float)sstyle.ImageRotation); + } + + if (scaleImage == true) + { + if (sstyle.ImageScale != 1) + { + int width = (int)(destRect.Width * sstyle.ImageScale); + int height = (int)(destRect.Height * sstyle.ImageScale); + + destRect.X += (destRect.Width / 2); + destRect.Y += (destRect.Height / 2); + destRect.Size = Size.Empty; + + destRect.Inflate(width / 2, height / 2); + } + } + + if (sstyle.IsSymbolFigure == true) + RenderSliceSymbol(g, pieChart, (SymbolDef)figure, destRect, sstyle); + else + RenderSliceImage(g, (Image)figure, srcRect, destRect); + + if (sstyle.ImageAutoRotate == Tbool.True || sstyle.ImageRotation != 0) + g.Restore(gState); + + if (clip != null) + g.Clip = clip; + } + } + + #region GetImageAngle + + private double GetImageAngle( + PieSeriesPoint psp, double centerAngle, ChartSliceVisualStyle sstyle) + { + double offset = sstyle.ImageAngleOffset; + + if (offset == 0) + return (centerAngle); + + if ((uint)offset < 1) + return (centerAngle + offset * psp.SweepAngleEx); + + return (centerAngle + offset); + } + + #endregion + + #region GetImageSideFactor + + /// + /// Calculates the max 'a' side of the image. + /// + /// + /// + /// + /// + private double GetImageSideFactor( + PieSeriesPoint psp, double radius, Size size) + { + double maxRadius = GetMaxImageRadius(psp, radius); + + double scaleFactor = (double)(size.Width * size.Width) / (size.Height * size.Height); + double side = Math.Sqrt((maxRadius * maxRadius) / (scaleFactor + 1)); + + return (side); + } + + #region GetMaxImageRadius + + /// + /// Gets the max radius of a circle image at the given ray radius. + /// + /// + /// + /// + private double GetMaxImageRadius(PieSeriesPoint psp, double radius) + { + double angle = psp.SweepAngleEx / 2; + + if (angle >= 90) + return (radius); + + double radians = MathHelper.ToRadians(angle); + + double maxRad = radius * Math.Sin(radians); + + //double dr = (int)(radius * radius); + + //double maxRad = 2 * dr - 2 * (dr * Math.Cos(radians)); + //maxRad = Math.Sqrt(maxRad); + + return (maxRad); + } + + #endregion + + #endregion + + #region GetFigureRadius + + private double GetFigureRadius(PieSeriesPoint psp, ChartSliceVisualStyle sstyle) + { + double radius = psp.OuterRadius - psp.InnerRadius; + double extentRadius = psp.InnerRadius + radius * psp.SliceExtent; + + double innerRadius = GetAnchorRadius(psp, extentRadius, sstyle.ImageInnerRadiusAnchor); + double outerRadius = GetAnchorRadius(psp, extentRadius, sstyle.ImageOuterRadiusAnchor); + + double delta = outerRadius - innerRadius; + + if (delta == 0) + delta = radius; + + if (Math.Abs(sstyle.ImageRadiusOffset) <= 1) + return (innerRadius + delta * sstyle.ImageRadiusOffset); + else + return (innerRadius + sstyle.ImageRadiusOffset * (delta > 0 ? 1 : -1)); + } + + #region GetAnchorRadius + + private double GetAnchorRadius( + PieSeriesPoint psp, double extentRadius, SliceImageRadiusAnchor anchor) + { + switch (anchor) + { + case SliceImageRadiusAnchor.ExtentRadius: + return (extentRadius); + + case SliceImageRadiusAnchor.InnerRadius: + return (psp.InnerRadius); + + case SliceImageRadiusAnchor.OuterRadius: + return (psp.OuterRadius); + } + + return (psp.InnerRadius); + } + + #endregion + + #endregion + + #region RenderSliceSymbol + + private void RenderSliceSymbol(Graphics g, + PieChart pieChart, SymbolDef symDef, Rectangle destRect, ChartSliceVisualStyle sstyle) + { + TextRenderingHint hint = g.TextRenderingHint; + g.TextRenderingHint = TextRenderingHint.AntiAlias; + + if (double.IsNaN(sstyle.ImageScale) == true) + { + using (StringFormat sf = new StringFormat()) + { + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Center; + + using (Brush br = new SolidBrush(symDef.SymbolColor)) + g.DrawString(symDef.SymbolRealized, symDef.SymbolFont, br, destRect, sf); + } + } + else + { + float n = Math.Max(destRect.Width, destRect.Height); + + destRect.Y += Dpi.Width4; + + if (_SymFontScale <= 0) + { + _ScaleSymDef.SymbolSize = n; + _ScaleSymDef.SymbolSet = symDef.SymbolSet; + + _SymFontScale = n / _ScaleSymDef.SymbolFont.Height * .8f; + } + + float fn = _SymFontScale * n; + + _ScaleSymDef.SymbolSize = fn; + _ScaleSymDef.SymbolSet = symDef.SymbolSet; + + using (StringFormat sf = new StringFormat()) + { + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Center; + + using (Brush br = new SolidBrush(symDef.SymbolColor)) + g.DrawString(symDef.SymbolRealized, _ScaleSymDef.SymbolFont, br, destRect, sf); + } + } + + g.TextRenderingHint = hint; + } + + #endregion + + #region RenderSliceImage + + private void RenderSliceImage(Graphics g, Image image, Rectangle srcRect, Rectangle destRect) + { + g.DrawImage(image, destRect, + new Rectangle(Point.Empty, srcRect.Size), GraphicsUnit.Pixel); + } + + #endregion + + #endregion + + #region RenderSliceLabel + + internal void RenderSliceLabel(Graphics g, + PieChart pieChart, PieSeriesPoint psp, ChartSliceVisualStyle sstyle) + { + if (IsInnerSliceLabelVisible(pieChart, psp) == true) + { + SliceInnerLabelVisualStyle lstyle = sstyle.SliceInnerLabelStyle; + + psp.InnerLabelDisplayed = false; + + string text = GetSliceLabel(pieChart, psp, true, psp.InnerSliceLabelEx); + + ChartControl chartControl = ChartControl; + + bool displayed = true; + + if (chartControl.DoRenderSliceInnerLabelEvent(g, pieChart, psp, text, ref displayed) == false) + { + if (string.IsNullOrEmpty(text) == false) + { + double maxRadius = psp.OuterRadius; + + if (lstyle.OuterRadiusOffsetBase == OuterRadiusOffsetBase.ExtentRadius) + maxRadius = psp.InnerRadius + (psp.OuterRadius - psp.InnerRadius) * psp.SliceExtent; + + SliceLabelOrientation orientation = psp.InnerLabelOrientationEx; + + switch (orientation) + { + case SliceLabelOrientation.Adaptive: + psp.InnerLabelDisplayed = + RenderAdaptiveLabel(g, pieChart, psp, maxRadius, text, lstyle); + break; + + case SliceLabelOrientation.Custom: + psp.InnerLabelDisplayed = + RenderCustomLabel(g, pieChart, psp, maxRadius, text, lstyle); + break; + + case SliceLabelOrientation.Parallel: + psp.InnerLabelDisplayed = + RenderParallelLabel(g, pieChart, psp, maxRadius, text, lstyle); + break; + + case SliceLabelOrientation.Perpendicular: + psp.InnerLabelDisplayed = + RenderPerpendicularLabel(g, pieChart, psp, maxRadius, text, lstyle); + break; + + default: + psp.InnerLabelDisplayed = + RenderHorizontalLabel(g, pieChart, psp, maxRadius, text, lstyle); + break; + } + } + } + } + else + { + psp.LastPathBounds = Rectangle.Empty; + } + } + + #region IsInnerSliceLabelVisible + + private bool IsInnerSliceLabelVisible(PieChart pieChart, PieSeriesPoint psp) + { + switch (psp.SliceLabelDisplayModeEx) + { + case SliceLabelDisplayMode.NotSet: + + case SliceLabelDisplayMode.Inner: + case SliceLabelDisplayMode.InnerAndOuter: + case SliceLabelDisplayMode.InnerXorOuter: + return (IsLabelDisplayed(pieChart, psp)); + } + + return (false); + } + + #region IsLabelDisplayed + + internal bool IsLabelDisplayed(PieChart pieChart, PieSeriesPoint psp) + { + SliceLabelVisibility labVis = psp.SliceLabelVisibilityEx; + + if ((labVis == SliceLabelVisibility.NotSet) || + (labVis & SliceLabelVisibility.Always) == SliceLabelVisibility.Always) + return (true); + + if ((labVis & SliceLabelVisibility.Never) == SliceLabelVisibility.Never) + return (false); + + if (pieChart.ShowSliceLabelsOnEntry == true && pieChart.IsMouseOver == true) + return (true); + + if ((labVis & SliceLabelVisibility.SliceMouseOver) == SliceLabelVisibility.SliceMouseOver) + { + if (psp == pieChart.HitPsp) + return (true); + } + + if (((labVis & SliceLabelVisibility.SelectionModeMouseOver) == SliceLabelVisibility.SelectionModeMouseOver) || + ((labVis & SliceLabelVisibility.SliceMouseOver) == SliceLabelVisibility.SliceMouseOver)) + { + if (IsHighLightedPsp(pieChart, psp) == true) + return (true); + } + + if ((labVis & SliceLabelVisibility.SliceSelect) == SliceLabelVisibility.SliceSelect) + { + if (psp.IsSelected == true) + return (true); + } + + if ((labVis & SliceLabelVisibility.SliceDetach) == SliceLabelVisibility.SliceDetach) + { + if (psp.IsDetached == true) + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region RenderAdaptiveLabel + + internal bool RenderAdaptiveLabel(Graphics g, PieChart pieChart, + PieSeriesPoint psp, double maxRadius, string text, SliceInnerLabelVisualStyle lstyle) + { + double innerOffset = GetLableInnerOffset(psp, maxRadius, lstyle); + double outerOffset = GetLableOuterOffset(psp, maxRadius, lstyle); + + if (outerOffset - innerOffset > 0) + { + double centerAngle = psp.CenterAngle % 360; + + float fontAngle = 0; + + if (lstyle.AutoOrientLabel != Tbool.False) + { + if (centerAngle < 180) + fontAngle += 180; + } + + float c = (float)(Math.PI * outerOffset * 2); + + if (c > 0) + { + RectangleF[] cBounds = GetAdaptiveCharBounds(g, psp, text, lstyle); + + if (centerAngle < 180) + { + return (PaintAdaptiveFlipText(g, pieChart, psp, + outerOffset, innerOffset, fontAngle, text, cBounds, lstyle)); + } + + return (PaintAdaptiveText(g, pieChart, psp, + outerOffset, innerOffset, fontAngle, text, cBounds, lstyle)); + } + } + + return (false); + } + + #region GetAdaptiveCharBounds + + private RectangleF[] GetAdaptiveCharBounds(Graphics g, + PieSeriesPoint psp, string text, SliceInnerLabelVisualStyle lstyle) + { + RectangleF[] charBounds = psp.CharBounds; + + if (charBounds == null || charBounds.Length < text.Length) + { + charBounds = new RectangleF[text.Length]; + + int n = (int)Math.Ceiling((double)text.Length / 32); + + using (StringFormat sf = new StringFormat()) + { + sf.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.MeasureTrailingSpaces; + + for (int i = 0; i < text.Length; i += 32) + { + int len = 32; + + if (i + len > text.Length) + len = text.Length - i; + + MeasureAdaptiveText(g, sf, text, i, len, charBounds, lstyle); + } + } + + psp.CharBounds = charBounds; + } + + return (charBounds); + } + + #region MeasureAdaptiveText + + private void MeasureAdaptiveText(Graphics g, StringFormat sf, + string text, int index, int len, RectangleF[] charBounds, SliceInnerLabelVisualStyle lstyle) + { + CharacterRange[] crs = new CharacterRange[len]; + + string s = text.Substring(index, len); + + for (int j = 0; j < len; j++) + crs[j] = new CharacterRange(j, 1); + + sf.SetMeasurableCharacterRanges(crs); + + Rectangle r = new Rectangle(0, 0, 5000, 5000); + Region[] rgns = g.MeasureCharacterRanges(s, lstyle.Font, r, sf); + + for (int i = 0; i < len; i++) + charBounds[index + i] = rgns[i].GetBounds(g); + + if (index > 0) + { + float dx = charBounds[index - 1].X + charBounds[index - 1].Width - charBounds[index].X; + + for (int i = 0; i < len; i++) + charBounds[index + i].X += dx; + } + } + + #endregion + + #endregion + + #region PaintAdaptiveText + + private bool PaintAdaptiveText(Graphics g, PieChart pieChart, + PieSeriesPoint psp, double outerOffset, double innerOffset, + float fontAngle, string text, RectangleF[] cBounds, SliceInnerLabelVisualStyle lstyle) + { + bool clipped; + List wpsLines = + GetAdaptiveLines(psp, outerOffset, innerOffset, text, cBounds, out clipped, lstyle); + + if (wpsLines != null && wpsLines.Count > 0) + { + psp.InnerLabelClipped = clipped; + + if (clipped == true) + { + if (psp.SliceLabelCropModeEx == SliceLabelCropMode.Hide) + return (false); + } + + double startAngle; + double endAngle; + NormalizeSliceAngles(psp, out startAngle, out endAngle); + + double startRadians = MathHelper.ToRadians((float)(startAngle + lstyle.AngleMargin)); + double endRadians = MathHelper.ToRadians((float)(endAngle - lstyle.AngleMargin)); + + if (startRadians < endRadians) + { + TextRenderingHint renderingHint = g.TextRenderingHint; + g.TextRenderingHint = TextRenderingHint.AntiAlias; + + float height = cBounds[0].Height; + float halfHeight = height / 2; + + using (Brush br = new SolidBrush(lstyle.TextColor)) + { + foreach (WordPosLine wpsLine in wpsLines) + { + double offset = wpsLine.Offset; + + if (wpsLine.Wps.Count > 0) + { + double dx = GetAlignmentOffset(wpsLine, cBounds, lstyle); + double xRadians = startRadians + (dx / offset); + + foreach (WordPos wp in wpsLine.Wps) + { + for (int j = 0; j < wp.Text.Length; j++) + { + RectangleF tf = cBounds[wp.Index + j]; + + float cRadians = (float)(tf.Width / offset); + + if (xRadians + cRadians > (float)endRadians + .5) + break; + + xRadians += (cRadians / 2); + + float z = (float)(offset - halfHeight); + float y = (float)(psp.SliceCenter.Y + z * Math.Sin(xRadians)); + float x = (float)(psp.SliceCenter.X + z * Math.Cos(xRadians)); + + int n = (int)Math.Max(tf.Width, tf.Height); + + GraphicsState gState = g.Save(); + + g.TranslateTransform(x, y); + g.RotateTransform(90 + (float)MathHelper.ToDegrees((float)xRadians)); + + g.DrawString(wp.Text[j].ToString(), lstyle.Font, br, -tf.Width/2, -tf.Height / 2); + + g.Restore(gState); + + xRadians += (cRadians / 2); + } + + if (wp.Index + wp.Length < cBounds.Length) + xRadians += cBounds[wp.Index + wp.Length].Width / offset; + } + } + } + } + + if ((outerOffset > psp.OuterRadius) || + (wpsLines[wpsLines.Count - 1].Offset < psp.InnerRadius)) + { + Rectangle t = GetBoundingArcRect( + psp, startAngle, endAngle, outerOffset + height); + + psp.PathBounds = Rectangle.Union(psp.PathBounds, t); + + if (psp.PathBounds.Equals(psp.LastPathBounds) == false) + { + psp.LastPathBounds = psp.PathBounds; + + InvalidateRender(psp.PathBounds); + } + } + + g.TextRenderingHint = renderingHint; + + return (true); + } + } + + return (false); + } + + #region GetBoundingArcRect + + private Rectangle GetBoundingArcRect( + PieSeriesPoint psp, double startAngle, double endAngle, double outerOffset) + { + Rectangle r = new Rectangle(psp.SliceCenter, Size.Empty); + + double n = startAngle; + + n += 89; + n = (int)(n / 90) * 90; + + while (n <= endAngle) + { + UpdateAngleBounds(psp, n, outerOffset, ref r); + + n += 90; + } + + if (startAngle % 90 != 0) + UpdateAngleBounds(psp, startAngle, outerOffset, ref r); + + if (endAngle % 90 != 0) + UpdateAngleBounds(psp, endAngle, outerOffset, ref r); + + return (r); + } + + #region UpdateAngleBounds + + private void UpdateAngleBounds(PieSeriesPoint psp, + double angle, double outerOffset, ref Rectangle r) + { + Point pts = psp.GetRayEndPoint(angle, outerOffset); + + if (pts.X < r.X) + { + r.Width += (r.X - pts.X); + r.X = pts.X; + } + else if (pts.X > r.Right) + { + r.Width += (pts.X - r.Right); + } + + if (pts.Y < r.Y) + { + r.Height += (r.Y - pts.Y); + r.Y = pts.Y; + } + else if (pts.Y > r.Bottom) + { + r.Height += (pts.Y - r.Bottom); + } + } + + #endregion + + #endregion + + #region GetAdaptiveLines + + private List GetAdaptiveLines( + PieSeriesPoint psp, double outerOffset, double innerOffset, + string text, RectangleF[] cBounds, out bool clipped, SliceInnerLabelVisualStyle lstyle) + { + if (psp.WordPosLines == null) + { + psp.WordPosLines = + GetAdaptiveLinesEx(psp, outerOffset, innerOffset, text, cBounds, out clipped, lstyle); + + psp.InnerLabelClipped = clipped; + } + + clipped = psp.InnerLabelClipped; + + return (psp.WordPosLines); + } + + #region GetAdaptiveLinesEx + + private List GetAdaptiveLinesEx( + PieSeriesPoint psp, double outerOffset, double innerOffset, string text, + RectangleF[] cBounds, out bool clipped, SliceInnerLabelVisualStyle lstyle) + { + float height = cBounds[0].Height; + int maxLineCount = (int)((outerOffset - innerOffset) / height); + + SliceLabelCropMode cropMode = psp.SliceLabelCropModeEx; + + if (cropMode != SliceLabelCropMode.Hide) + maxLineCount = 1000; + + if (lstyle.MaxLineCount >= 0) + { + if (maxLineCount > lstyle.MaxLineCount) + maxLineCount = lstyle.MaxLineCount; + } + + List wpsLines = null; + + if (maxLineCount > 0) + { + List wps = GetWordWidths(text, cBounds); + + double offset = outerOffset; + + bool middle = false; + + switch (lstyle.Alignment) + { + case SliceLabelAlignment.MiddleLeft: + case SliceLabelAlignment.MiddleRight: + case SliceLabelAlignment.MiddleCenter: + offset = (outerOffset + innerOffset) / 2; + middle = true; + break; + + case SliceLabelAlignment.InnerLeft: + case SliceLabelAlignment.InnerRight: + case SliceLabelAlignment.InnerCenter: + + clipped = false; + + while (offset > innerOffset) + { + List ilines = FitAdaptiveLines(psp, + offset, -height, cBounds, maxLineCount, wps, out clipped, lstyle); + + if (ilines != null) + { + if (wpsLines == null || clipped == false) + wpsLines = ilines; + + if (clipped == true) + break; + + wps = GetWordWidths(text, cBounds); + + offset -= height; + } + else + { + break; + } + } + + return (wpsLines); + + default: + List lines = FitAdaptiveLines(psp, + offset, -height, cBounds, maxLineCount, wps, out clipped, lstyle); + + return (lines); + } + + for (int i = 0; i < maxLineCount; i++) + { + List lines = FitAdaptiveLines(psp, + offset, -height, cBounds, (i + 1), wps, out clipped, lstyle); + + if (lines != null) + { + if (clipped == false) + return (lines); + + wpsLines = lines; + + wps = GetWordWidths(text, cBounds); + + if ((middle == false) || (i % 2 == 0)) + offset += height; + } + else + { + break; + } + } + } + + clipped = false; + + return (wpsLines); + } + + #region FitAdaptiveLines + + private List FitAdaptiveLines( + PieSeriesPoint psp, double offset, float height, RectangleF[] cBounds, + int count, List wps, out bool clipped, SliceInnerLabelVisualStyle lstyle) + { + List wpsLines = new List(); + + int wordIndex = 0; + + while (wpsLines.Count < count) + { + int lineWordCount = 0; + + double arcWidth = GetArcWidth(psp, offset - cBounds[0].Height / 4, lstyle); + + if (arcWidth <= 0) + break; + + WordPosLine wpsLine = new WordPosLine(); + + wpsLine.Offset = offset; + wpsLine.ArcWidth = arcWidth; + + while (wordIndex < wps.Count) + { + WordPos wp = wps[wordIndex]; + + double wordLength = GetWordLength(wp, cBounds, lineWordCount); + + if (wp.Text.Equals("\n") == true) + { + if (wpsLine.Wps.Count == 0) + wpsLine.Wps.Add(wp); + + wordIndex++; + break; + } + + if (wpsLine.ArcWidth - (wpsLine.LineWidth + wordLength) < 0) + { + if (lineWordCount == 0 || wpsLines.Count + 1 == count) + { + wpsLine = FitNonBrokenLine(psp, offset, + count - wpsLines.Count, wpsLines, wpsLine, wp, cBounds, height, out clipped, lstyle); + + if (clipped == true || wpsLine == null) + { + if (wpsLine != null && wpsLine.Wps.Count > 0) + wpsLines.Add(wpsLine); + + return (wpsLines); + } + + offset = wpsLine.Offset; + } + else + { + break; + } + } + else + { + wpsLine.LineWidth += wordLength; + + wpsLine.Wps.Add(wp); + } + + wordIndex++; + lineWordCount++; + } + + if (wpsLine.Wps.Count > 0) + { + offset = wpsLine.Offset; + + wpsLines.Add(wpsLine); + } + + if (wordIndex >= wps.Count) + break; + + offset += height; + } + + clipped = (wordIndex < wps.Count); + + return (wpsLines); + } + + #region FitNonBrokenLine + + private WordPosLine FitNonBrokenLine(PieSeriesPoint psp, + double offset, int maxCount, List wpsLines, WordPosLine wpsLine, + WordPos wp, RectangleF[] cBounds, float height, out bool clipped, SliceInnerLabelVisualStyle lstyle) + { + double length; + int count = GetNonBrokenCount(wpsLine, wp, cBounds, out length); + + clipped = true; + + if (length == 0) + return (wpsLine); + + int rindex = wp.Index; + + while (count > 0) + { + WordPos wp2 = new WordPos(); + + wp2.Index = wp.Index; + wp2.Length = count; + wp2.Text = wp.Text.Substring((wp.Index - rindex), count); + + wpsLine.Wps.Add(wp2); + + wp.Index += count; + wp.Length -= count; + + if (--maxCount <= 0) + break; + + if (wp.Length <= 0) + break; + + wpsLines.Add(wpsLine); + + offset += height; + + wpsLine = new WordPosLine(); + wpsLine.Offset = offset; + + wpsLine.ArcWidth = GetArcWidth(psp, offset - cBounds[0].Height / 4, lstyle); + + count = GetNonBrokenCount(wpsLine, wp, cBounds, out length); + } + + clipped = (wp.Length > 0); + + return (wpsLine); + } + + #region GetNonBrokenCount + + private int GetNonBrokenCount( + WordPosLine wpsLine, WordPos wp, RectangleF[] cBounds, out double length) + { + length = 0; + + if (wpsLine.Wps.Count > 0 && wp.Index > 0) + { + double width = cBounds[wp.Index - 1].Width; + + if (wpsLine.ArcWidth - (wpsLine.LineWidth + width) < 0) + return (0); + + wpsLine.LineWidth += width; + length += width; + } + + for (int i = 0; i < wp.Length; i++) + { + double width = cBounds[wp.Index + i].Width; + + if (wpsLine.ArcWidth - (wpsLine.LineWidth + width) < 0) + return (i); + + wpsLine.LineWidth += width; + length += width; + } + + return (wp.Length); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region PaintAdaptiveFlipText + + private bool PaintAdaptiveFlipText(Graphics g, PieChart pieChart, + PieSeriesPoint psp, double outerOffset, double innerOffset, float fontAngle, + string text, RectangleF[] cBounds, SliceInnerLabelVisualStyle lstyle) + { + bool clipped; + List wpsLines = + GetAdaptiveFlipLines(psp, outerOffset, innerOffset, text, cBounds, out clipped, lstyle); + + if (wpsLines != null && wpsLines.Count > 0) + { + if (clipped == true) + { + if (psp.SliceLabelCropModeEx == SliceLabelCropMode.Hide) + return (false); + } + + double startAngle; + double endAngle; + NormalizeSliceAngles(psp, out startAngle, out endAngle); + + double endRadians = MathHelper.ToRadians(startAngle + lstyle.AngleMargin); + double startRadians = MathHelper.ToRadians(endAngle - lstyle.AngleMargin); + + float height = cBounds[0].Height; + float halfHeight = height / 2; + + TextRenderingHint renderingHint = g.TextRenderingHint; + g.TextRenderingHint = TextRenderingHint.AntiAlias; + + using (Brush br = new SolidBrush(lstyle.TextColor)) + { + foreach (WordPosLine wpsLine in wpsLines) + { + double offset = wpsLine.Offset; + + if (wpsLine.Wps.Count > 0) + { + double dx = GetAlignmentOffset(wpsLine, cBounds, lstyle); + double xRadians = startRadians - dx / offset; + + foreach (WordPos wp in wpsLine.Wps) + { + for (int j = 0; j < wp.Text.Length; j++) + { + if (xRadians < (float)endRadians) + break; + + RectangleF tf = cBounds[wp.Index + j]; + + float cRadians = (float)(tf.Width / offset); + + xRadians -= (cRadians / 2); + + float z = (float)(offset - halfHeight); + float y = (float)((float)psp.SliceCenter.Y + z * Math.Sin(xRadians)); + float x = (float)((float)psp.SliceCenter.X + z * Math.Cos(xRadians)); + + GraphicsState gState = g.Save(); + + g.TranslateTransform(x, y); + g.RotateTransform(-90 + (float)MathHelper.ToDegrees(xRadians)); + + g.DrawString(wp.Text[j].ToString(), lstyle.Font, br, -tf.Width / 2, -tf.Height / 2); + + g.Restore(gState); + + xRadians -= (cRadians / 2); + } + + if (wp.Index + wp.Length < cBounds.Length) + xRadians -= cBounds[wp.Index + wp.Length].Width / offset; + } + } + } + } + + if ((outerOffset > psp.OuterRadius) || + (wpsLines.Count > 0 && wpsLines[0].Offset < psp.InnerRadius)) + { + Rectangle t = GetBoundingArcRect( + psp, startAngle, endAngle, outerOffset + height); + + psp.PathBounds = Rectangle.Union(psp.PathBounds, t); + + if (psp.PathBounds.Equals(psp.LastPathBounds) == false) + { + psp.LastPathBounds = psp.PathBounds; + + InvalidateRender(psp.PathBounds); + } + } + + g.TextRenderingHint = renderingHint; + + return (true); + } + + return (false); + } + + #region GetAdaptiveFlipLines + + private List GetAdaptiveFlipLines( + PieSeriesPoint psp, double outerOffset, double innerOffset, + string text, RectangleF[] cBounds, out bool clipped, SliceInnerLabelVisualStyle lstyle) + { + if (psp.WordPosLines == null) + { + psp.WordPosLines = + GetAdaptiveFlipLinesEx(psp, outerOffset, innerOffset, text, cBounds, out clipped, lstyle); + + psp.InnerLabelClipped = clipped; + } + + clipped = psp.InnerLabelClipped; + + return (psp.WordPosLines); + } + + #region GetAdaptiveFlipLinesEx + + private List GetAdaptiveFlipLinesEx( + PieSeriesPoint psp, double outerOffset, double innerOffset, + string text, RectangleF[] cBounds, out bool clipped, SliceInnerLabelVisualStyle lstyle) + { + float height = cBounds[0].Height; + int maxLineCount = (int)Math.Abs((outerOffset - innerOffset) / height); + + SliceLabelCropMode cropMode = psp.SliceLabelCropModeEx; + + if (cropMode == SliceLabelCropMode.NoAction) + maxLineCount = 1000; + + if (lstyle.MaxLineCount >= 0) + { + if (maxLineCount > lstyle.MaxLineCount) + maxLineCount = lstyle.MaxLineCount; + } + + List wpsLines = null; + + clipped = false; + + if (maxLineCount > 0) + { + List wps = GetWordWidths(text, cBounds); + + double offset = outerOffset; + + bool middle = false; + + switch (lstyle.Alignment) + { + case SliceLabelAlignment.MiddleLeft: + case SliceLabelAlignment.MiddleRight: + case SliceLabelAlignment.MiddleCenter: + offset = (outerOffset + innerOffset) / 2; + height = -height; + middle = true; + break; + + case SliceLabelAlignment.InnerLeft: + case SliceLabelAlignment.InnerRight: + case SliceLabelAlignment.InnerCenter: + + clipped = false; + + offset = innerOffset; + + while (offset < outerOffset) + { + List ilines = FitAdaptiveLines(psp, + offset, height, cBounds, maxLineCount, wps, out clipped, lstyle); + + if (ilines != null && ilines.Count > 0) + return (ilines); + + wps = GetWordWidths(text, cBounds); + + offset += height; + } + + return (wpsLines); + + default: + height = -height; + break; + } + + for (int i = 0; i < maxLineCount; i++) + { + List lines = FitAdaptiveLines(psp, + offset, Math.Abs(height), cBounds, i + 1, wps, out clipped, lstyle); + + if (lines != null) + { + if (clipped == false) + return (lines); + + wpsLines = lines; + + wps = GetWordWidths(text, cBounds); + + if ((middle == false) || (i % 2 == 0)) + offset += height; + } + else + { + break; + } + } + } + + return (wpsLines); + } + + #endregion + + #endregion + + #endregion + + #region NormalizeSliceAngles + + private void NormalizeSliceAngles( + PieSeriesPoint psp, out double startAngle, out double endAngle) + { + startAngle = psp.StartAngleEx; + endAngle = psp.StartAngleEx + psp.SweepAngleEx; + + if (startAngle > endAngle) + { + double temp = startAngle; + startAngle = endAngle; + endAngle = temp; + } + } + + #endregion + + #region GetArcWidth + + private double GetArcWidth( + PieSeriesPoint psp, double offset, SliceInnerLabelVisualStyle lstyle) + { + double margin = lstyle.AngleMargin * 2; + double sweep = Math.Abs(psp.SweepAngleEx); + + double width = offset * MathHelper.ToRadians(sweep - margin); + + return (width); + } + + #endregion + + #region GetWordLength + + private double GetWordLength( + WordPos wp, RectangleF[] cBounds, int lineWordCount) + { + double length = 0; + + if (lineWordCount > 0) + length += cBounds[wp.Index - 1].Width; + + for (int i = 0; i < wp.Length; i++) + length += cBounds[wp.Index + i].Width; + + return (length); + } + + #endregion + + #region GetWordWidths + + private List GetWordWidths(string text, RectangleF[] cBounds) + { + List wps = new List(); + + int index = 0; + + while (index < text.Length) + { + int length = GetNextWord(text, ref index); + + if (length > 0) + { + WordPos wp = new WordPos(); + + wp.Index = index; + wp.Length = length; + wp.Text = text.Substring(index, length); + + wps.Add(wp); + + index += length; + } + } + + return (wps); + } + + #region GetNextWord + + private int GetNextWord(string text, ref int index) + { + while (index < text.Length) + { + if (text[index] == '\n') + return (1); + + if (Char.IsWhiteSpace(text[index]) == false) + break; + + index++; + } + + int eindex = index; + + while (eindex < text.Length) + { + if (Char.IsWhiteSpace(text[eindex]) == true) + break; + + eindex++; + } + + return (eindex - index); + } + + #endregion + + #endregion + + #region GetAlignmentOffset + + private double GetAlignmentOffset( + WordPosLine wpsLine, RectangleF[] tbounds, SliceInnerLabelVisualStyle lstyle) + { + switch (lstyle.Alignment) + { + case SliceLabelAlignment.OuterRight: + case SliceLabelAlignment.MiddleRight: + case SliceLabelAlignment.InnerRight: + return (wpsLine.ArcWidth - wpsLine.LineWidth); + + case SliceLabelAlignment.OuterCenter: + case SliceLabelAlignment.MiddleCenter: + case SliceLabelAlignment.InnerCenter: + return ((wpsLine.ArcWidth - wpsLine.LineWidth) / 2); + + default: + return (0); + } + } + + #endregion + + #endregion + + #region RenderCustomLabel + + internal bool RenderCustomLabel(Graphics g, PieChart pieChart, + PieSeriesPoint psp, double maxRadius, string text,SliceInnerLabelVisualStyle lstyle) + { + double angle = GetCustomLabelAngle(psp, lstyle); + double offset = GetCustomLableOffset(psp, maxRadius, lstyle); + + Rectangle r = GetCustomLabelRect(psp, maxRadius, angle, offset, lstyle); + + angle += lstyle.CustomFontAngle; + + if (lstyle.AutoRotate != Tbool.True) + angle -= (psp.CenterAngle - 90); + + angle = (angle + 360000) % 360; + + double fontAngle = 0; + + if (lstyle.AutoOrientLabel != Tbool.False) + { + if (angle < 180) + fontAngle += 180; + } + + r = GetSliceLabelBounds(g, pieChart, psp, text, r, lstyle); + + if (r.Width > 0 && r.Height > 0) + { + GraphicsState gState = g.Save(); + + TextRenderingHint renderingHint = g.TextRenderingHint; + g.TextRenderingHint = TextRenderingHint.AntiAlias; + + using (StringFormat sf = new StringFormat()) + { + lstyle.GetStringFormatFlags(sf, angle < 180); + + g.TranslateTransform(r.X, r.Y); + g.RotateTransform((float)(angle + fontAngle + 90)); + + r.X = -(int)(r.Width / 2); + r.Y = -(int)(r.Height / 2); + + if (lstyle.Background.IsEmpty == false) + { + using (Brush br = lstyle.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + + using (Brush br = new SolidBrush(lstyle.TextColor)) + g.DrawString(text, lstyle.Font, br, r, sf); + + if (ChartControl.DesignerHosted == true) + { + using (Pen pen = new Pen(Color.Plum)) + { + pen.DashStyle = DashStyle.Dash; + + g.DrawRectangle(pen, r); + } + } + } + + g.Restore(gState); + + return (true); + } + + return (false); + } + + #region GetCustomLabelRect + + private Rectangle GetCustomLabelRect(PieSeriesPoint psp, + double maxRadius, double angle, double offset, SliceInnerLabelVisualStyle lstyle) + { + Rectangle r = new Rectangle(); + + r.Location = psp.GetRayEndPoint(angle, offset); + + r.Width = (int)GetCustomLabelWidth(psp, offset, lstyle); + r.Height = (int)GetCustomLabelHeight(psp, maxRadius, offset, lstyle); + + return (r); + } + + #endregion + + #region GetCustomLabelHeight + + private double GetCustomLabelHeight(PieSeriesPoint psp, + double maxRadius, double offset, SliceInnerLabelVisualStyle lstyle) + { + double height = maxRadius - psp.InnerRadius; + + if (double.IsNaN(lstyle.CustomHeight) == false) + { + if (Math.Abs(lstyle.CustomHeight) < 1) + return (lstyle.CustomHeight * height); + + return (lstyle.CustomHeight); + } + + return (height * .5); + } + + #endregion + + #region GetCustomLabelWidth + + private double GetCustomLabelWidth( + PieSeriesPoint psp, double offset, SliceInnerLabelVisualStyle lstyle) + { + double width = GetArcWidth(psp, offset, lstyle); + + if (double.IsNaN(lstyle.CustomWidth) == false) + { + if (Math.Abs(lstyle.CustomWidth) < 1) + return (lstyle.CustomWidth * width); + + return (lstyle.CustomWidth); + } + + return (width * .8); + } + + #endregion + + #region GetCustomLableOffset + + private double GetCustomLableOffset( + PieSeriesPoint psp, double maxRadius, SliceInnerLabelVisualStyle lstyle) + { + double offset = lstyle.CustomRadiusOffset; + + if (double.IsNaN(offset) == false) + { + if (Math.Abs(offset) < 1) + offset = (maxRadius - psp.InnerRadius) * offset; + + return (psp.InnerRadius + offset); + } + + return (psp.InnerRadius + (maxRadius - psp.InnerRadius) * .7); + } + + #endregion + + #region GetCustomLabelAngle + + private double GetCustomLabelAngle(PieSeriesPoint psp, SliceInnerLabelVisualStyle lstyle) + { + double angle = (psp.StartAngleEx + psp.SweepAngleEx / 2) % 360; + + if (double.IsNaN(lstyle.CustomAngleOffset) == false) + { + double offset = lstyle.CustomAngleOffset; + + if (Math.Abs(offset) < 1) + angle += (psp.SweepAngleEx * offset); + else + angle += offset; + } + + return (angle); + } + + #endregion + + #endregion + + #region RenderParallelLabel + + internal bool RenderParallelLabel(Graphics g, PieChart pieChart, + PieSeriesPoint psp, double maxRadius, string text, SliceInnerLabelVisualStyle lstyle) + { + double centerAngle = psp.CenterAngle % 360; + + double innerOffset = GetLableInnerOffset(psp, maxRadius, lstyle); + double outerOffset = GetLableOuterOffset(psp, maxRadius, lstyle); + + float fontAngle = 0; + + if (lstyle.AutoOrientLabel != Tbool.False) + { + if (centerAngle >= 90 && centerAngle < 270) + fontAngle += 180; + } + + Point lpt = psp.GetRayEndPoint( + centerAngle, (innerOffset + outerOffset) / 2); + + Rectangle r = new Rectangle(); + + r.Location = lpt; + r.Width = (int)(outerOffset - innerOffset); + r.Height = (int)GetArcWidth(psp, innerOffset, lstyle); + + r = GetSliceLabelBounds(g, pieChart, psp, text, r, lstyle); + + if (r.Width > 0 && r.Height > 0) + { + GraphicsState gState = g.Save(); + + TextRenderingHint renderingHint = g.TextRenderingHint; + g.TextRenderingHint = TextRenderingHint.AntiAlias; + + using (StringFormat sf = new StringFormat()) + { + GetStringFormatFlags(lstyle, sf, fontAngle != 0); + + r.X = -(int)(r.Width / 2); + r.Y = -(int)(r.Height / 2); + + g.TranslateTransform(lpt.X, lpt.Y); + g.RotateTransform((float)centerAngle + fontAngle); + + if (lstyle.Background.IsEmpty == false) + { + using (Brush br = lstyle.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + + using (Brush br = new SolidBrush(lstyle.TextColor)) + g.DrawString(text, lstyle.Font, br, r, sf); + } + + g.Restore(gState); + + return (true); + } + + return (false); + } + + #region GetStringFormatFlags + + private void GetStringFormatFlags( + SliceInnerLabelVisualStyle lstyle, StringFormat sf, bool flip) + { + if (lstyle.AllowWrap == Tbool.False || lstyle.MaxLineCount == 1) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + sf.Trimming = StringTrimming.EllipsisCharacter; + + switch (lstyle.Alignment) + { + case SliceLabelAlignment.OuterLeft: + sf.Alignment = (flip ? StringAlignment.Near : StringAlignment.Far); // Outer/inner + sf.LineAlignment = (flip ? StringAlignment.Far : StringAlignment.Near); // Left/right + break; + + case SliceLabelAlignment.InnerLeft: + sf.Alignment = (flip ? StringAlignment.Far : StringAlignment.Near); + sf.LineAlignment = (flip ? StringAlignment.Far : StringAlignment.Near); + break; + + case SliceLabelAlignment.MiddleLeft: + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = (flip ? StringAlignment.Far : StringAlignment.Near); + break; + + case SliceLabelAlignment.OuterRight: + sf.Alignment = (flip ? StringAlignment.Near : StringAlignment.Far); + sf.LineAlignment = (flip ? StringAlignment.Near : StringAlignment.Far); + break; + + case SliceLabelAlignment.InnerRight: + sf.Alignment = (flip ? StringAlignment.Far : StringAlignment.Near); + sf.LineAlignment = (flip ? StringAlignment.Near : StringAlignment.Far); + break; + + case SliceLabelAlignment.MiddleRight: + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = (flip ? StringAlignment.Near : StringAlignment.Far); + break; + + case SliceLabelAlignment.OuterCenter: + sf.Alignment = (flip ? StringAlignment.Near : StringAlignment.Far); + sf.LineAlignment = StringAlignment.Center; + break; + + case SliceLabelAlignment.InnerCenter: + sf.Alignment = (flip ? StringAlignment.Far : StringAlignment.Near); + sf.LineAlignment = StringAlignment.Center; + break; + + case SliceLabelAlignment.NotSet: + case SliceLabelAlignment.MiddleCenter: + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + break; + } + } + + #endregion + + #endregion + + #region RenderPerpendicularLabel + + internal bool RenderPerpendicularLabel(Graphics g, PieChart pieChart, + PieSeriesPoint psp, double maxRadius, string text, SliceInnerLabelVisualStyle lstyle) + { + double innerOffset = GetLableInnerOffset(psp, maxRadius, lstyle); + double outerOffset = GetLableOuterOffset(psp, maxRadius, lstyle); + + if (outerOffset - innerOffset > 0) + { + double centerAngle = psp.CenterAngle % 360; + + Point lpt = psp.GetRayEndPoint(centerAngle, outerOffset); + + float fontAngle = 0; + + if (lstyle.AutoOrientLabel != Tbool.False) + { + if (centerAngle < 180) + fontAngle += 180; + } + + Rectangle r = GetInscribedRectP(psp, maxRadius, + centerAngle, outerOffset, innerOffset, lpt, lstyle); + + r = GetSliceLabelBounds(g, pieChart, psp, text, r, lstyle); + + if (r.Width > 0 && r.Height > 0) + { + GraphicsState gState = g.Save(); + + TextRenderingHint renderingHint = g.TextRenderingHint; + g.TextRenderingHint = TextRenderingHint.AntiAlias; + + g.TranslateTransform(lpt.X, lpt.Y); + g.RotateTransform((float)((centerAngle + fontAngle + 90) % 360)); + + if (lstyle.Background.IsEmpty == false) + { + using (Brush br = lstyle.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + + using (StringFormat sf = new StringFormat()) + { + lstyle.GetStringFormatFlags(sf, (centerAngle < 180)); + + using (Brush br = new SolidBrush(lstyle.TextColor)) + g.DrawString(text, lstyle.Font, br, r, sf); + } + + g.Restore(gState); + + return (true); + } + } + + return (false); + } + + #region GetInscribedRectP + + private Rectangle GetInscribedRectP(PieSeriesPoint psp, double maxRadius, + double centerAngle, double outerOffset, double innerOffset, Point lpt, SliceInnerLabelVisualStyle lstyle) + { + if (psp.InscribedRectValid == false) + { + double sweepAngle = psp.SweepAngleEx / 2 - lstyle.AngleMargin; + + double b = (innerOffset * Math.Tan(MathHelper.ToRadians(sweepAngle))); + double h = (outerOffset - innerOffset); + + double maxb = Math.Sqrt(maxRadius * maxRadius - outerOffset * outerOffset); + + if (b > maxb) + b = maxb; + + h = (h / lstyle.Font.Height) * lstyle.Font.Height; + + Rectangle r = new Rectangle(); + + r.Location = new Point((int)-b, (centerAngle < 180) ? (int)-h : 0); + + r.Width = (int)(b * 2); + r.Height = (int)h; + + psp.InscribedRect = r; + } + + return (psp.InscribedRect); + } + + #endregion + + #endregion + + #region RenderHorizontalLabel + + internal bool RenderHorizontalLabel(Graphics g, PieChart pieChart, + PieSeriesPoint psp, double maxRadius, string text, SliceInnerLabelVisualStyle lstyle) + { + double innerOffset = GetLableInnerOffset(psp, maxRadius, lstyle); + + Rectangle r = GetInscribedRectH(g, + psp, psp.CenterAngle % 360, maxRadius, innerOffset, lstyle); + + r = GetSliceLabelBounds(g, pieChart, psp, text, r, lstyle); + + if (r.Width > 0 && r.Height > 0) + { + if (lstyle.Background.IsDisplayable == true) + { + using (Brush br = lstyle.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + + using (StringFormat sf = new StringFormat()) + { + lstyle.GetStringFormatFlags(sf, false); + + using (Brush br = new SolidBrush(lstyle.TextColor)) + g.DrawString(text, lstyle.Font, br, r, sf); + } + + if (ChartControl.DesignerHosted == true) + { + using (Pen pen = new Pen(Color.Plum)) + { + pen.DashStyle = DashStyle.Dash; + + g.DrawRectangle(pen, r); + } + } + + return (true); + } + + return (false); + } + + #region GetInscribedRectH + + private Rectangle GetInscribedRectH(Graphics g, PieSeriesPoint psp, + double centerAngle, double outerOffset, double innerOffset, SliceInnerLabelVisualStyle lstyle) + { + if (psp.InscribedRectValid == false) + { + double startAngle = psp.StartAngleEx % 360; + double endAngle = startAngle + psp.SweepAngleEx; + + if (psp.SweepAngleEx > 180) + { + startAngle = centerAngle - 88; + endAngle = centerAngle + 88; + } + + Rectangle r; + + if (centerAngle > 270) + { + r = GetInscribedRectQuad4(g, psp, + startAngle, endAngle, centerAngle, outerOffset, innerOffset, lstyle); + } + else if (centerAngle > 180) + { + r = GetInscribedRectQuad3(g, psp, + startAngle, endAngle, centerAngle, outerOffset, innerOffset, lstyle); + } + else if (centerAngle > 90) + { + r = GetInscribedRectQuad2(g, psp, + startAngle, endAngle, centerAngle, outerOffset, innerOffset, lstyle); + } + else + { + r = GetInscribedRectQuad1(g, psp, + startAngle, endAngle, centerAngle, outerOffset, innerOffset, lstyle); + } + + r.Inflate(-2, -2); + + psp.InscribedRect = r; + } + + return (psp.InscribedRect); + } + + #region GetInscribedRectQuad1 + + private Rectangle GetInscribedRectQuad1(Graphics g, + PieSeriesPoint psp, double startAngle, double endAngle, + double centerAngle, double outerOffset, double innerOffset, SliceInnerLabelVisualStyle lstyle) + { + Point ptCenter = psp.SliceCenter; + + centerAngle = NormalizeCenterAngleQuad1(centerAngle, startAngle, endAngle); + + Point ptcInner = psp.GetRayEndPoint(centerAngle, innerOffset); + Point ptcOuter = psp.GetRayEndPoint(centerAngle, outerOffset); + + Point ptLeftRay = psp.GetRayEndPoint(startAngle, outerOffset); + Point ptRightRay = psp.GetRayEndPoint(endAngle, outerOffset); + + Point ptPie1, ptPie2; + int count = FindCircleIntersect(ptCenter, outerOffset, ptcOuter, + new Point(ptcOuter.X + 1, ptcOuter.Y), out ptPie1, out ptPie2, true); + + if (count != 2) + return (Rectangle.Empty); + + Point ptLeftLower = new Point(ptPie1.X, ptcOuter.Y); + + Point pt1; + if (FindLineIntersect(ptcOuter, ptLeftLower, ptCenter, ptRightRay, out pt1) == true) + { + if ((uint)(ptcOuter.X - pt1.X) < ptcOuter.X - ptLeftLower.X) + ptLeftLower.X = pt1.X; + } + + Point ptPie3, ptPie4; + count = FindCircleIntersect(ptCenter, outerOffset, ptcOuter, + new Point(ptcOuter.X, ptcOuter.Y + 10), out ptPie3, out ptPie4, false); + + if (count != 2) + return (Rectangle.Empty); + + Point ptRightUpper = new Point(ptcOuter.X, ptPie3.Y); + + if (FindLineIntersect(ptcOuter, new Point(ptcOuter.X, ptcOuter.Y + 10), + ptCenter, ptLeftRay, out pt1) == true) + { + if ((uint)(ptcOuter.Y - pt1.Y) < (ptcOuter.Y - ptRightUpper.Y)) + ptRightUpper.Y = pt1.Y; + } + + if (centerAngle < 40) + { + Point ray = psp.GetRayEndPoint(0, innerOffset); + + if (Math.Abs(ray.X - ptcOuter.X) < Math.Abs(ptLeftLower.X - ptcOuter.X)) + ptLeftLower.X = ray.X; + } + else if (centerAngle > 50) + { + Point ray = psp.GetRayEndPoint(90, innerOffset); + + if (Math.Abs(ray.Y - ptcOuter.Y) < Math.Abs(ptRightUpper.Y - ptcOuter.Y)) + ptRightUpper.Y = ray.Y; + } + else + { + if (ptLeftLower.X < ptcInner.X) + { + if (FindLineIntersect(ptCenter, ptLeftRay, ptcInner, + new Point(ptcInner.X, ptcInner.Y + 10), out pt1) == true) + { + if (Math.Abs(pt1.X - ptcOuter.X) < Math.Abs(ptLeftLower.X - ptcOuter.X)) + ptLeftLower.X = pt1.X; + } + } + + if (ptRightUpper.Y <= ptcInner.Y) + { + if (FindLineIntersect(ptCenter, ptRightRay, + ptcInner, new Point(ptcInner.X + 10, ptcInner.Y), out pt1) == true) + { + if (Math.Abs(pt1.Y - ptcOuter.Y) < Math.Abs(ptRightUpper.Y - ptcOuter.Y)) + ptRightUpper.Y = pt1.Y; + } + } + } + + if (psp.SweepAngleEx < 180) + { + if (FindLineIntersect(ptCenter, ptRightRay, ptRightUpper, + new Point(ptRightUpper.X + 10, ptRightUpper.Y), out pt1) == true) + { + if (Math.Abs(pt1.X - ptcOuter.X) < Math.Abs(ptLeftLower.X - ptcOuter.X)) + ptLeftLower.X = pt1.X; + } + + if (FindLineIntersect(ptCenter, ptLeftRay, ptLeftLower, + new Point(ptLeftLower.X, ptLeftLower.Y + 10), out pt1) == true) + { + if (Math.Abs(pt1.Y - ptcOuter.Y) < Math.Abs(ptRightUpper.Y - ptcOuter.Y)) + ptRightUpper.Y = pt1.Y; + } + } + + Rectangle r = new Rectangle(); + + r.Location = new Point(ptLeftLower.X, ptRightUpper.Y); + r.Width = ptcOuter.X - ptLeftLower.X; + r.Height = ptcOuter.Y - ptRightUpper.Y; + + return (r); + } + + #region NormalizeCenterAngleQuad1 + + private double NormalizeCenterAngleQuad1( + double centerAngle, double startAngle, double endAngle) + { + if (centerAngle > 70) + { + centerAngle -= (centerAngle - 70) / 2; + + if (centerAngle - 2 < 0) + centerAngle += 360; + + if (centerAngle - 2 <= startAngle) + centerAngle = (startAngle + 2) % 360; + } + else if (centerAngle < 20) + { + centerAngle += (20 - centerAngle) / 2; + + if (centerAngle + 2 >= endAngle) + centerAngle = endAngle - 2; + } + + return (centerAngle); + } + + #endregion + + #endregion + + #region GetInscribedRectQuad2 + + private Rectangle GetInscribedRectQuad2(Graphics g, + PieSeriesPoint psp, double startAngle, double endAngle, + double centerAngle, double outerOffset, double innerOffset, SliceInnerLabelVisualStyle lstyle) + { + Point ptCenter = psp.SliceCenter; + + centerAngle = NormalizeCenterAngleQuad2(centerAngle, startAngle, endAngle); + + Point ptcInner = psp.GetRayEndPoint(centerAngle, innerOffset); + Point ptcOuter = psp.GetRayEndPoint(centerAngle, outerOffset); + + Point ptLeftRay = psp.GetRayEndPoint(startAngle, outerOffset); + Point ptRightRay = psp.GetRayEndPoint(endAngle, outerOffset); + + Point ptPie1, ptPie2; + int count = FindCircleIntersect(ptCenter, outerOffset, ptcOuter, + new Point(ptcOuter.X + 1, ptcOuter.Y), out ptPie1, out ptPie2, true); + + if (count != 2) + return (Rectangle.Empty); + + Point ptRightLower = new Point(ptPie2.X, ptcOuter.Y); + + Point pt1; + if (FindLineIntersect(ptcOuter, ptRightLower, ptCenter, ptLeftRay, out pt1) == true) + { + if ((uint)(pt1.X - ptcOuter.X) < (ptRightLower.X - ptcOuter.X)) + ptRightLower.X = pt1.X; + } + + Point ptPie3, ptPie4; + count = FindCircleIntersect(ptCenter, outerOffset, ptcOuter, + new Point(ptcOuter.X, ptcOuter.Y + 10), out ptPie3, out ptPie4, false); + + if (count != 2) + return (Rectangle.Empty); + + Point ptLeftUpper = new Point(ptcOuter.X, ptPie3.Y); + + if (FindLineIntersect(ptcOuter, new Point(ptcOuter.X, ptcOuter.Y + 10), + ptCenter, ptRightRay, out pt1) == true) + { + if ((uint)(ptcOuter.Y - pt1.Y) < (ptcOuter.Y - ptLeftUpper.Y)) + ptLeftUpper.Y = pt1.Y; + } + + if (centerAngle < 130) + { + Point ray = psp.GetRayEndPoint(90, innerOffset); + + if (Math.Abs(ray.Y - ptcOuter.Y) < Math.Abs(ptLeftUpper.Y - ptcOuter.Y)) + ptLeftUpper.Y = ray.Y; + } + else if (centerAngle > 140) + { + Point ray = psp.GetRayEndPoint(180, innerOffset); + + if (Math.Abs(ray.X - ptcOuter.X) < Math.Abs(ptRightLower.X - ptcOuter.X)) + ptRightLower.X = ray.X; + } + else + { + if (ptRightLower.X > ptcInner.X) + { + if (FindLineIntersect(ptCenter, ptLeftRay, ptcInner, + new Point(ptcInner.X, ptcInner.Y + 10), out pt1) == true) + { + if (Math.Abs(pt1.X - ptcOuter.X) < Math.Abs(ptRightLower.X - ptcOuter.X)) + ptRightLower.X = pt1.X; + } + } + + if (ptLeftUpper.Y <= ptcInner.Y) + { + if (FindLineIntersect(ptCenter, ptRightRay, + ptcInner, new Point(ptcInner.X + 10, ptcInner.Y), out pt1) == true) + { + if (Math.Abs(pt1.Y - ptcOuter.Y) < Math.Abs(ptLeftUpper.Y - ptcOuter.Y)) + ptLeftUpper.Y = pt1.Y; + } + } + } + + if (psp.SweepAngleEx < 180) + { + if (FindLineIntersect(ptCenter, ptRightRay, ptRightLower, + new Point(ptRightLower.X, ptRightLower.Y + 10), out pt1) == true) + { + if (Math.Abs(pt1.Y - ptcOuter.Y) < Math.Abs(ptLeftUpper.Y - ptcOuter.Y)) + ptLeftUpper.Y = pt1.Y; + } + + if (FindLineIntersect(ptCenter, ptLeftRay, ptLeftUpper, + new Point(ptLeftUpper.X + 10, ptLeftUpper.Y), out pt1) == true) + { + if (Math.Abs(pt1.X - ptcOuter.X) < Math.Abs(ptRightLower.X - ptcOuter.X)) + ptRightLower.X = pt1.X; + } + } + + Rectangle r = new Rectangle(); + + r.Location = ptLeftUpper; + r.Width = ptRightLower.X - ptcOuter.X; + r.Height = ptcOuter.Y - ptLeftUpper.Y; + + return (r); + } + + #region NormalizeCenterAngleQuad2 + + private double NormalizeCenterAngleQuad2( + double centerAngle, double startAngle, double endAngle) + { + if (centerAngle > 160) + { + centerAngle -= (centerAngle - 160) / 2; + + if (centerAngle - 2 <= startAngle) + centerAngle = startAngle + 2; + } + else if (centerAngle < 110) + { + centerAngle += (110 - centerAngle) / 2; + + if (centerAngle + 2 >= endAngle) + centerAngle = endAngle - 2; + } + + return (centerAngle); + } + + #endregion + + #endregion + + #region GetInscribedRectQuad3 + + private Rectangle GetInscribedRectQuad3(Graphics g, + PieSeriesPoint psp, double startAngle, double endAngle, + double centerAngle, double outerOffset, double innerOffset, SliceInnerLabelVisualStyle lstyle) + { + Point ptCenter = psp.SliceCenter; + + centerAngle = NormalizeCenterAngleQuad3(centerAngle, startAngle, endAngle); + + Point ptcInner = psp.GetRayEndPoint(centerAngle, innerOffset); + Point ptcOuter = psp.GetRayEndPoint(centerAngle, outerOffset); + + Point ptLeftRay = psp.GetRayEndPoint(startAngle, outerOffset); + Point ptRightRay = psp.GetRayEndPoint(endAngle, outerOffset); + + Point ptPie1, ptPie2; + + int count = FindCircleIntersect(ptCenter, outerOffset, ptcOuter, + new Point(ptcOuter.X + 1, ptcOuter.Y), out ptPie1, out ptPie2, true); + + if (count != 2) + return (Rectangle.Empty); + + Point ptRightUpper = new Point(ptPie2.X, ptcOuter.Y); + + Point pt1; + if (FindLineIntersect(ptcOuter, ptRightUpper, ptCenter, ptRightRay, out pt1) == true) + { + if (pt1.X - ptcOuter.X > 0) + { + if ((uint)(pt1.X - ptcOuter.X) < (ptRightUpper.X - ptcOuter.X)) + ptRightUpper.X = pt1.X; + } + } + + Point ptPie3, ptPie4; + + count = FindCircleIntersect(ptCenter, outerOffset, ptcOuter, + new Point(ptcOuter.X, ptcOuter.Y + 10), out ptPie3, out ptPie4, false); + + if (count != 2) + return (Rectangle.Empty); + + Point ptLeftLower = new Point(ptcOuter.X, ptPie4.Y); + + if (FindLineIntersect(ptcOuter, new Point(ptcOuter.X, ptcOuter.Y + 10), + ptCenter, ptLeftRay, out pt1) == true) + { + if (pt1.Y - ptcOuter.Y > 0) + { + if ((uint)(pt1.Y - ptcOuter.Y) < (ptLeftLower.Y - ptcOuter.Y)) + ptLeftLower.Y = pt1.Y; + } + } + + if (centerAngle < 220) + { + Point ray = psp.GetRayEndPoint(180, innerOffset); + + if (Math.Abs(ray.X - ptcOuter.X) < Math.Abs(ptRightUpper.X - ptcOuter.X)) + ptRightUpper.X = ray.X; + } + else if (centerAngle > 230) + { + Point ray = psp.GetRayEndPoint(270, innerOffset); + + if (Math.Abs(ray.Y - ptcOuter.Y) < Math.Abs(ptLeftLower.Y - ptcOuter.Y)) + ptLeftLower.Y = ray.Y; + } + else + { + if (ptLeftLower.Y >= ptcInner.Y) + { + if (FindLineIntersect(ptCenter, ptLeftRay, ptcInner, + new Point(ptcInner.X + 10, ptcInner.Y), out pt1) == true) + { + if (Math.Abs(pt1.Y - ptcOuter.Y) < Math.Abs(ptLeftLower.Y - ptcOuter.Y)) + ptLeftLower.Y = pt1.Y; + } + } + + if (ptRightUpper.X > ptcInner.X) + { + if (FindLineIntersect(ptCenter, ptRightRay, + ptcInner, new Point(ptcInner.X, ptcInner.Y + 10), out pt1) == true) + { + if (Math.Abs(pt1.X - ptcOuter.X) < Math.Abs(ptRightUpper.X - ptcOuter.X)) + ptRightUpper.X = pt1.X; + } + } + } + + if (psp.SweepAngleEx < 180) + { + if (FindLineIntersect(ptCenter, ptRightRay, ptLeftLower, + new Point(ptLeftLower.X + 10, ptLeftLower.Y), out pt1) == true) + { + if (Math.Abs(pt1.X - ptcOuter.X) < Math.Abs(ptRightUpper.X - ptcOuter.X)) + ptRightUpper.X = pt1.X; + } + + if (FindLineIntersect(ptCenter, ptLeftRay, + ptRightUpper, new Point(ptRightUpper.X, ptRightUpper.Y + 10), out pt1) == true) + { + if (Math.Abs(pt1.Y - ptcOuter.Y) < Math.Abs(ptLeftLower.Y - ptcOuter.Y)) + ptLeftLower.Y = pt1.Y; + } + } + + Rectangle r = new Rectangle(); + + r.Location = ptcOuter; + r.Width = ptRightUpper.X - ptcOuter.X; + r.Height = ptLeftLower.Y - ptcOuter.Y; + + return (r); + } + + #region NormalizeCenterAngleQuad3 + + private double NormalizeCenterAngleQuad3( + double centerAngle, double startAngle, double endAngle) + { + if (centerAngle > 250) + { + centerAngle -= (centerAngle - 250) / 2; + + if (centerAngle - startAngle < 2) + centerAngle = startAngle + 2; + } + else if (centerAngle < 200) + { + centerAngle += (200 - centerAngle) / 2; + + if (centerAngle + 2 >= endAngle) + centerAngle = endAngle - 2; + } + + return (centerAngle); + } + + #endregion + + #endregion + + #region GetInscribedRectQuad4 + + private Rectangle GetInscribedRectQuad4(Graphics g, + PieSeriesPoint psp, double startAngle, double endAngle, + double centerAngle, double outerOffset, double innerOffset, SliceInnerLabelVisualStyle lstyle) + { + Point ptCenter = psp.SliceCenter; + + centerAngle = NormalizeCenterAngleQuad4(centerAngle, startAngle, endAngle); + + Point ptcInner = psp.GetRayEndPoint(centerAngle, innerOffset); + Point ptcOuter = psp.GetRayEndPoint(centerAngle, outerOffset); + + Point ptLeftRay = psp.GetRayEndPoint(startAngle, outerOffset); + Point ptRightRay = psp.GetRayEndPoint(endAngle, outerOffset); + + Point ptPie1, ptPie2; + int count = FindCircleIntersect(ptCenter, outerOffset, ptcOuter, + new Point(ptcOuter.X + 1, ptcOuter.Y), out ptPie1, out ptPie2, true); + + if (count != 2) + return (Rectangle.Empty); + + Point ptLeftUpper = new + Point((ptcOuter.Y < ptCenter.Y) ? ptPie1.X : ptPie2.X, ptcOuter.Y); + + Point pt1; + if (FindLineIntersect(ptcOuter, ptLeftUpper, ptCenter, ptLeftRay, out pt1) == true) + { + if (ptcOuter.X - pt1.X > 0) + { + if ((uint)(ptcOuter.X - pt1.X) < ptcOuter.X - ptLeftUpper.X) + ptLeftUpper.X = pt1.X; + } + } + + Point ptPie3, ptPie4; + count = FindCircleIntersect(ptCenter, outerOffset, ptcOuter, + new Point(ptcOuter.X, ptcOuter.Y + 10), out ptPie3, out ptPie4, false); + + if (count != 2) + return (Rectangle.Empty); + + Point ptRightLower = new Point(ptcOuter.X, + (ptcOuter.X < ptCenter.X) ? ptPie3.Y : ptPie4.Y); + + if (FindLineIntersect(ptcOuter, new Point(ptcOuter.X, ptcOuter.Y + 10), + ptCenter, ptRightRay, out pt1) == true) + { + if (pt1.Y - ptcOuter.Y > 0) + { + if ((uint)(pt1.Y - ptcOuter.Y) < (ptRightLower.Y - ptcOuter.Y)) + ptRightLower.Y = pt1.Y; + } + } + + if (centerAngle < 310) + { + Point ray = psp.GetRayEndPoint(270, innerOffset); + + if (Math.Abs(ray.Y - ptcOuter.Y) < Math.Abs(ptRightLower.Y - ptcOuter.Y)) + ptRightLower.Y = ray.Y; + } + else if (centerAngle > 320) + { + Point ray = psp.GetRayEndPoint(0, innerOffset); + + if (Math.Abs(ray.X - ptcOuter.X) < Math.Abs(ptLeftUpper.X - ptcOuter.X)) + ptLeftUpper.X = ray.X; + } + else + { + if (ptLeftUpper.X <= ptcInner.X) + { + if (FindLineIntersect(ptCenter, ptLeftRay, ptcInner, + new Point(ptcInner.X, ptcInner.Y + 10), out pt1) == true) + { + if (Math.Abs(pt1.X - ptcOuter.X) < Math.Abs(ptLeftUpper.X - ptcOuter.X)) + ptLeftUpper.X = pt1.X; + } + } + + if (ptRightLower.Y >= ptcInner.Y) + { + if (FindLineIntersect(ptCenter, ptRightRay, + ptcInner, new Point(ptcInner.X + 10, ptcInner.Y), out pt1) == true) + { + if (Math.Abs(pt1.Y - ptcOuter.Y) < Math.Abs(ptRightLower.Y - ptcOuter.Y)) + ptRightLower.Y = pt1.Y; + } + } + } + + if (psp.SweepAngleEx < 180) + { + if (FindLineIntersect(ptCenter, ptRightRay, ptLeftUpper, + new Point(ptLeftUpper.X, ptLeftUpper.Y + 10), out pt1) == true) + { + if (Math.Abs(pt1.Y - ptcOuter.Y) < Math.Abs(ptRightLower.Y - ptcOuter.Y)) + ptRightLower.Y = pt1.Y; + } + + if (FindLineIntersect(ptCenter, ptLeftRay, + ptRightLower, new Point(ptRightLower.X + 10, ptRightLower.Y), out pt1) == true) + { + if (Math.Abs(pt1.X - ptcOuter.X) < Math.Abs(ptLeftUpper.X - ptcOuter.X)) + ptLeftUpper.X = pt1.X; + } + } + + Rectangle r = new Rectangle(); + + r.Location = ptLeftUpper; + r.Width = ptRightLower.X - ptLeftUpper.X; + r.Height = ptRightLower.Y - ptLeftUpper.Y; + + return (r); + } + + #region NormalizeCenterAngleQuad4 + + private double NormalizeCenterAngleQuad4( + double centerAngle, double startAngle, double endAngle) + { + if (centerAngle > 340) + { + centerAngle -= (centerAngle - 340) / 2; + + if (centerAngle - 2 <= startAngle) + centerAngle = startAngle + 2; + } + else if (centerAngle < 290) + { + centerAngle += (290 - centerAngle) / 2; + + if (centerAngle + 2 >= endAngle) + centerAngle = endAngle - 2; + } + + return (centerAngle); + } + + #endregion + + #endregion + + #region FindLineIntersect + + private bool FindLineIntersect( + Point ps1, Point pe1, Point ps2, Point pe2, out Point ptOut) + { + float A1 = pe1.Y - ps1.Y; + float B1 = ps1.X - pe1.X; + float C1 = A1 * ps1.X + B1 * ps1.Y; + + float A2 = pe2.Y - ps2.Y; + float B2 = ps2.X - pe2.X; + float C2 = A2 * ps2.X + B2 * ps2.Y; + + float delta = A1 * B2 - A2 * B1; + + if (delta == 0) + { + ptOut = Point.Empty; + + return (false); + } + + ptOut = new Point( + (int)((B2 * C1 - B1 * C2) / delta), + (int)((A1 * C2 - A2 * C1) / delta)); + + return (true); + } + + #endregion + + #region FindCircleIntersect + + private int FindCircleIntersect(Point ptc, double radius, + Point pt1, Point pt2, out Point ptOut1, out Point ptOut2, bool normx) + { + int dx = pt2.X - pt1.X; + int dy = pt2.Y - pt1.Y; + + int a = dx * dx + dy * dy; + int b = 2 * (dx * (pt1.X - ptc.X) + dy * (pt1.Y - ptc.Y)); + + double c = (pt1.X - ptc.X) * (pt1.X - ptc.X) + + (pt1.Y - ptc.Y) * (pt1.Y - ptc.Y) - radius * radius; + + double det = b * b - 4 * a * c; + + if ((a <= 0.0000001) || (det < 0)) + { + ptOut1 = Point.Empty; + ptOut2 = Point.Empty; + + return (0); + } + else if (det == 0) + { + double t1 = -b / (2 * a); + + ptOut1 = new Point((int)(pt1.X + t1 * dx), (int)(pt1.Y + t1 * dy)); + ptOut2 = Point.Empty; + + return (1); + } + else + { + double t2 = (float)((-b + Math.Sqrt(det)) / (2 * a)); + double t3 = (float)((-b - Math.Sqrt(det)) / (2 * a)); + + ptOut1 = new Point((int)(pt1.X + t2 * dx), (int)(pt1.Y + t2 * dy)); + ptOut2 = new Point((int)(pt1.X + t3 * dx), (int)(pt1.Y + t3 * dy)); + + if ((normx == true && ptOut1.X > ptOut2.X) || + (normx == false && ptOut1.Y > ptOut2.Y)) + { + Point ptTemp = ptOut1; + + ptOut1 = ptOut2; + ptOut2 = ptTemp; + } + + return (2); + } + } + + #endregion + + #endregion + + #endregion + + #region GetLableInnerOffset + + internal double GetLableInnerOffset + (PieSeriesPoint psp, double maxRadius, SliceInnerLabelVisualStyle lstyle) + { + double offset; + + if (Math.Abs(lstyle.InnerRadiusOffset) >= 1) + offset = lstyle.InnerRadiusOffset; + else + offset = (maxRadius - psp.InnerRadius) * lstyle.InnerRadiusOffset; + + offset += psp.InnerRadius; + + if (lstyle.MaxLineCount >= 0) + { + double outerOffset = psp.InnerRadius; + + if (lstyle.OuterRadiusOffset > -1 && lstyle.OuterRadiusOffset < 1) + outerOffset += (lstyle.OuterRadiusOffset * maxRadius); + else + outerOffset += lstyle.OuterRadiusOffset; + + double fh = lstyle.Font.GetHeight() * lstyle.MaxLineCount; + + fh = outerOffset - fh; + + if (fh > offset) + offset = fh; + } + + return (offset); + } + + #endregion + + #region GetLableOuterOffset + + internal double GetLableOuterOffset( + PieSeriesPoint psp, double maxRadius, SliceInnerLabelVisualStyle lstyle) + { + double offset; + + if (Math.Abs(lstyle.OuterRadiusOffset) >= 1) + offset = lstyle.OuterRadiusOffset; + else + offset = (maxRadius * lstyle.OuterRadiusOffset); + + return (maxRadius + offset); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetSliceLabel + + internal string GetSliceLabel( + PieChart pieChart, PieSeriesPoint psp, bool inner, string label) + { + if (string.IsNullOrEmpty(label) == false) + { + string text = (string)label.Clone(); + + if (ChartControl.DoGetSliceLabelEvent(pieChart, this, psp, inner, ref text) == false) + text = psp.GetLabelText(text); + + return (text); + } + + return (null); + } + + #endregion + + #region GetSliceLabelBounds + + private Rectangle GetSliceLabelBounds(Graphics g, PieChart pieChart, + PieSeriesPoint psp, string text, Rectangle r, SliceInnerLabelVisualStyle lstyle) + { + if (r.Width > 0 && r.Height > 0) + { + SizeF sz = g.MeasureString(text, lstyle.Font, r.Width); + Size size = sz.ToSize(); + + psp.InnerLabelClipped = (size.Width > r.Width || size.Height > r.Height); + + if (psp.InnerLabelClipped == true) + { + SliceLabelCropMode cropMode = psp.SliceLabelCropModeEx; + + if (cropMode == SliceLabelCropMode.Hide) + return (Rectangle.Empty); + + else if (cropMode == SliceLabelCropMode.Clip) + { + int height = GetTruncatedHeight(r.Height, lstyle); + + if (height > 0) + r.Height = height; + } + else + { + r.Height = size.Height; + } + } + } + + return (r); + } + + #region GetTruncatedHeight + + private int GetTruncatedHeight(int height, SliceInnerLabelVisualStyle lstyle) + { + int n = (int)(height / lstyle.Font.Height); + + if (lstyle.MaxLineCount > 0) + { + if (n > lstyle.MaxLineCount) + n = lstyle.MaxLineCount; + } + + return (lstyle.Font.Height * n); + } + + #endregion + + #endregion + + #endregion + + #region IsHighLightedPsp + + internal bool IsHighLightedPsp(PieChart pieChart, PieSeriesPoint psp) + { + if (pieChart.Legend.TrackingMode == LegendTrackingMode.ChartAndLegend) + { + if (LegendItem != null && LegendItem.IsLegendHitItem == true) + return (true); + + if (psp.LegendItem != null && psp.LegendItem.IsLegendHitItem == true) + return (true); + } + + PieSeriesPoint hitPsp = pieChart.HitPsp; + + if (hitPsp != null) + { + PieSelectionMode psm = GetPieSelectionMode(pieChart); + + switch (psm) + { + case PieSelectionMode.Pie: + return (true); + + case PieSelectionMode.Ring: + return (psp.PieRing == hitPsp.PieRing); + + case PieSelectionMode.Series: + return (psp.ChartSeries == hitPsp.ChartSeries); + + case PieSelectionMode.Slice: + if (ShowAllRingsEx(pieChart) == true) + return (psp.RootPsp == hitPsp.RootPsp); + else + return (psp == hitPsp); + + case PieSelectionMode.Point: + return (psp == hitPsp); + } + } + + return (false); + } + + #endregion + + #endregion + + #region Render + + internal override void Render(ChartRenderInfo renderInfo) + { + if (Displayed == true) + { + Rectangle bounds = BoundsRelative; + + if (renderInfo.ClipRectangle.IntersectsWith(bounds)) + RenderOverride(renderInfo); + } + } + + #endregion + + #region UpdatePalette + + internal bool UpdatePalette(PieChart pieChart) + { + if (PaletteGroup == PaletteGroup.NotSet) + return (false); + + Color[] palette = (PaletteGroup == PaletteGroup.Custom) + ? (CustomPalette.Length > 0 ? CustomPalette : pieChart.CustomPalette) + : BaseChart.PaletteGroups[(int)PaletteGroup]; + + if (palette == null || palette.Length == 0) + palette = BaseChart.PaletteColor1; + + int colorIndex = 0; + + DefaultPaletteColor = + pieChart.GetPaletteColor(colorIndex++, palette, ReversePaletteColors); + + if (PieRings != null) + { + foreach (PieRing pieRing in PieRings) + { + foreach (PieSeriesPoint psp in pieRing.Psps) + { + psp.DefaultPaletteColor = + pieChart.GetPaletteColor(colorIndex++, palette, ReversePaletteColors); + } + } + } + + return (true); + } + + #endregion + + #region AddSeriesPoint + + internal override void AddSeriesPoint(object valueX, object[] valuesY, object dataItem) + { + PieSeriesPoint sp = new PieSeriesPoint(valueX, valuesY); + + sp.DataItem = dataItem; + + SeriesPoints.Add(sp); + } + + #endregion + + #region ClearSeriesPoints + + internal override void ClearSeriesPoints() + { + SeriesPoints.Clear(); + } + + #endregion + + #region GetActiveSeriesPointCollection + + /// + /// Gets the current 'active' SeriesPointCollection (useful when + /// 'ShowInnerRings' is set to false). + /// + /// + public PieSeriesPointCollection GetActiveSeriesPointCollection() + { + PieChart pieChart = Parent as PieChart; + + if (pieChart != null) + { + return ((ShowAllRingsEx(pieChart) == true) + ? SeriesPoints : (ActiveSeriesPointCollection ?? SeriesPoints)); + } + + return (null); + } + + #endregion + + #region SetActiveSeriesPointCollection + + /// + /// Sets the current 'active' SeriesPointCollection (useful when + /// 'ShowInnerRings' is set to false). + /// + /// + public void SetActiveSeriesPointCollection(PieSeriesPointCollection spc) + { + if (spc == null || ValidSeriesPointSet(SeriesPoints, spc) == true) + ActiveSeriesPointCollection = spc; + else + throw new Exception("Not a valid PieSeriesPointSet for the series."); + + InvalidateLayout(); + } + + #region ValidSeriesPointSet + + private bool ValidSeriesPointSet(PieSeriesPointCollection spc, PieSeriesPointCollection aspc) + { + if (aspc == spc) + return (true); + + if (spc.PieSlices != null) + { + foreach (PieSeriesPoint psp in spc.PieSlices) + { + if (psp.SeriesPoints == aspc) + return (true); + + if (ValidSeriesPointSet(psp.SeriesPoints, aspc) == true) + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region GetPieSeriesPointCollection + + /// + /// Gets the SeriesPointCollection containing the given PieSeriesPoint + /// + /// + /// + public PieSeriesPointCollection GetPieSeriesPointCollection(PieSeriesPoint psp) + { + return (psp.Parent as PieSeriesPointCollection); + } + + #endregion + + #region GetPieLabels + + internal List GetPieLabels(Graphics g, PieChart pieChart) + { + List pieLabels = new List(); + + if (ShowAllRingsEx(pieChart) == true) + { + PieRing pieRing = GetOuterRing(pieChart); + + if (pieRing != null) + { + foreach (PieSeriesPoint psp in pieRing.Psps) + { + SetPieLabel(g, pieChart, psp); + + if (psp.PieLabel != null) + pieLabels.Add(psp.PieLabel); + } + } + } + else + { + PieSeriesPointCollection spc = GetActiveSeriesPointCollection(); + + if (spc != null) + { + foreach (PieSeriesPoint psp in spc) + { + SetPieLabel(g, pieChart, psp); + + if (psp.PieLabel != null) + pieLabels.Add(psp.PieLabel); + } + } + } + + return (pieLabels); + } + + #region SetPieLabel + + private void SetPieLabel( + Graphics g, PieChart pieChart, PieSeriesPoint psp) + { + psp.PieLabel = null; + + if (psp.IsDisplayed == true && psp.SweepAngleEx != 0 && + psp.IsInOtherEx == false && psp.IsEmpty == false) + { + ChartSliceVisualStyle sstyle = psp.GetEffectiveSliceStyle(pieChart, this); + + if (IsOuterSliceLabelVisible(pieChart, psp) == true) + { + SliceOuterLabelVisualStyle lstyle = sstyle.SliceOuterLabelStyle; + SliceLabelDisplayMode displayMode = psp.SliceLabelDisplayModeEx; + + if (displayMode == SliceLabelDisplayMode.Outer || + displayMode == SliceLabelDisplayMode.InnerAndOuter || + displayMode == SliceLabelDisplayMode.NotSet) + { + string outerlabel = psp.OuterSliceLabelEx; + + if (string.IsNullOrEmpty(outerlabel) == false) + SetPieLabelEx(g, pieChart, psp, outerlabel, lstyle); + } + else + { + if (psp.InnerLabelDisplayed == false) + { + string outerlabel = psp.OuterSliceLabelEx; + + if (string.IsNullOrEmpty(outerlabel) == false) + { + SetPieLabelEx(g, pieChart, psp, outerlabel, lstyle); + } + else + { + string innerlabel = psp.InnerSliceLabelEx; + + if (string.IsNullOrEmpty(innerlabel) == false) + SetPieLabelEx(g, pieChart, psp, innerlabel, lstyle); + } + } + } + } + } + } + + #endregion + + #region GetOuterRing + + private PieRing GetOuterRing(PieChart pieChart) + { + if (ShowAllRingsEx(pieChart) == false) + { + PieSeriesPointCollection spc = (ActiveSeriesPointCollection ?? SeriesPoints); + + return (spc.PieRing); + } + + if (PieRings.Count > 0) + { + foreach (PieRing pieRing in PieRings) + { + if (pieRing.IsOuterRing == true) + return (pieRing); + } + + return (PieRings[0]); + } + + return (null); + } + + #endregion + + #region IsOuterSliceLabelVisible + + private bool IsOuterSliceLabelVisible(PieChart pieChart, PieSeriesPoint psp) + { + if (psp.SliceLabelVisibilityEx == SliceLabelVisibility.Never) + return (false); + + switch (psp.SliceLabelDisplayModeEx) + { + case SliceLabelDisplayMode.Outer: + case SliceLabelDisplayMode.InnerAndOuter: + case SliceLabelDisplayMode.InnerXorOuter: + return (true); + } + + return (false); + } + + #endregion + + #region SetPieLabelEx + + private void SetPieLabelEx(Graphics g, PieChart pieChart, + PieSeriesPoint psp, string text, SliceOuterLabelVisualStyle lstyle) + { + string s = GetSliceLabel(pieChart, psp, false, text); + + if (String.IsNullOrEmpty(s) == false) + { + PieLabel pl = new PieLabel(psp, s); + + pl.LabelSize = MeasurePieLabel(g, pieChart, psp, pl, 0, lstyle); + + psp.PieLabel = pl; + } + } + + #region MeasurePieLabel + + internal Size MeasurePieLabel(Graphics g, PieChart pieChart, + PieSeriesPoint psp, PieLabel pl, int cwidth, SliceOuterLabelVisualStyle lstyle) + { + float fheight = lstyle.Font.GetHeight(); + + int maxWidth = GetMaxPieTextWidth(g, pieChart, lstyle); + int maxHeight = GetMaxPieTextHeight(g, pieChart, fheight, lstyle); + + int minWidth = GetMinPieTextWidth(g, pieChart, lstyle); + int minHeight = GetMinPieTextHeight(g, pieChart, fheight, lstyle); + + using (StringFormat sf = new StringFormat()) + { + lstyle.GetStringFormatFlags(sf, false); + + if (cwidth != 0) + cwidth -= Dpi.Width(lstyle.Padding.Horizontal); + + Size size = g.MeasureString(pl.Label, + lstyle.Font, cwidth != 0 ? cwidth : maxWidth, sf).ToSize(); + + size.Width += Dpi.Width1; + + size = AdjustForPadding(pieChart, psp, size); + + size.Height = MathHelper.Clamp(size.Height, minHeight, maxHeight); + size.Width = MathHelper.Clamp(size.Width, minWidth, maxWidth); + + if (lstyle.MaxLineCount > 1) + { + int lineHeight = (int)(Math.Ceiling(fheight)) * lstyle.MaxLineCount; + + if (size.Height > lineHeight) + size.Height = lineHeight; + } + + return (size); + } + } + + #region GetMaxPieTextWidth + + private int GetMaxPieTextWidth( + Graphics g, PieChart pieChart, SliceOuterLabelVisualStyle lstyle) + { + double maxWidth = lstyle.MaxLabelWidth; + + if (double.IsNaN(maxWidth) == false) + { + if (Math.Abs(maxWidth) >= 1) + return ((int)maxWidth); + } + else + { + maxWidth = .5; + } + + return ((int)(pieChart.ContentBoundsEx.Width * maxWidth)); + } + + #endregion + + #region GetMaxPieTextHeight + + private int GetMaxPieTextHeight( + Graphics g, PieChart pieChart, float fheight, SliceOuterLabelVisualStyle lstyle) + { + double maxHeight = lstyle.MaxLabelHeight; + + if (double.IsNaN(maxHeight) == false) + { + if (Math.Abs(maxHeight) >= 1) + return ((int)maxHeight); + } + else + { + maxHeight = .5; + } + + double height = pieChart.ContentBoundsEx.Height * maxHeight; + + int n = (int)(height / fheight); + + return ((int)(fheight * n)); + } + + #endregion + + #region GetMinPieTextWidth + + private int GetMinPieTextWidth( + Graphics g, PieChart pieChart, SliceOuterLabelVisualStyle lstyle) + { + double minWidth = lstyle.MinLabelWidth; + + if (double.IsNaN(minWidth) == false) + { + if (Math.Abs(minWidth) >= 1) + return ((int)minWidth); + + return ((int)(pieChart.ContentBoundsEx.Width * minWidth)); + } + + return (0); + } + + #endregion + + #region GetMinPieTextHeight + + private int GetMinPieTextHeight( + Graphics g, PieChart pieChart, float fheight, SliceOuterLabelVisualStyle lstyle) + { + double minHeight = lstyle.MinLabelHeight; + + if (double.IsNaN(minHeight) == false) + { + if (Math.Abs(minHeight) >= 1) + return ((int)minHeight); + + double height = pieChart.ContentBoundsEx.Height * minHeight; + + int n = (int)(height / fheight); + + return ((int)(fheight * n)); + } + + return ((int)fheight); + } + + #endregion + + #region AdjustForPadding + + private Size AdjustForPadding(PieChart pieChart, PieSeriesPoint psp, Size size) + { + SliceOuterLabelVisualStyle sstyle = + psp.GetEffectiveSliceStyle(pieChart, psp.ChartSeries).SliceOuterLabelStyle; + + size.Width += Dpi.Width(sstyle.Padding.Horizontal); + size.Height += Dpi.Width(sstyle.Padding.Vertical); + + return (size); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetOtherPieSeriesPoint + + /// + /// Gets the 'Other' PieSeriesPoint + /// + /// + public PieSeriesPoint GetOtherPieSeriesPoint() + { + return (SeriesPoints.OtherSlicePsp); + } + + #endregion + + #region Mouse support + + #region ProcessMouseEnter + + internal void ProcessMouseEnter(EventArgs e, PieChart pieChart) + { + SetToolTip(pieChart.ShowToolTips ? GetToolTipText(pieChart) : string.Empty); + } + + #region SetToolTip + + private static string _toolTipText; + + private void SetToolTip(string toolTipText) + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + { + if (chartControl.ToolTipText != _toolTipText) + chartControl.ToolTip.Hide(chartControl); + + chartControl.ToolTipText = toolTipText; + } + } + + #endregion + + #region GetToolTipText + + private string GetToolTipText(PieChart pieChart) + { + PieSeriesPoint psp = pieChart.HitPsp; + + if (psp == null || "".Equals(psp.ToolTipText)) + return (string.Empty); + + if (_toolTipText == null) + { + ChartControl chartControl = ChartControl; + + string s = ""; + + if (chartControl.DoGetToolTipEvent(pieChart, this, psp, ref s) == false) + s = psp.ToolTipTextEx; + + _toolTipText = psp.FormatItemText(s); + } + + return (_toolTipText); + } + + #endregion + + #endregion + + #region ProcessMouseLeave + + internal void ProcessMouseLeave(EventArgs e, PieChart pieChart) + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + chartControl.ToolTipText = ""; + + _toolTipText = null; + } + + #endregion + + #region ProcessMouseDown + + internal bool ProcessMouseDown( + MouseEventArgs e, PieChart pieChart, PieSeriesPoint psp) + { + pieChart.IsDragging = false; + pieChart.PspDragType = PspDragType.None; + + if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left) + { + _MouseDownPsp = psp; + + Point cpt = pieChart.GetLocalAdjustedPoint(pieChart.CenterPoint); + + Point rpt = e.Location; + _MouseDownRadius = MathHelper.GetPointRadius(ref rpt, cpt); + + if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) + { + _MouseDownOffset = (int)pieChart.ExplodedOffsetEx; + } + else + { + PieSeriesPoint rootPsp = (ShowAllRingsEx(pieChart) == true) + ? psp.RootPsp : psp; + + _MouseDownOffset = (double.IsNaN(rootPsp.DetachedOffset) == false) + ? (int)rootPsp.DetachedOffset : 0; + } + + MouseClickSliceAction mca = GetMouseClickSliceAction(pieChart); + + switch (mca) + { + case MouseClickSliceAction.Explode: + case MouseClickSliceAction.Detach: + InitPspDrag(pieChart, psp); + break; + + case MouseClickSliceAction.Select: + ProcessSliceSelect(e, pieChart, psp); + break; + } + + return (true); + } + + return (false); + } + + #region InitPspDrag + + private bool InitPspDrag(PieChart pieChart, PieSeriesPoint psp) + { + if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) + { + if (pieChart.EnableShiftDragExplode == true) + { + pieChart.PspDragType = PspDragType.Explode; + + return (true); + } + } + else + { + if (GetEnableDragDetach(pieChart) == true) + { + pieChart.PspDragType = PspDragType.Detach; + + return (psp.IsSelected); + } + } + + return (false); + } + + #endregion + + #region ProcessSliceSelect + + private void ProcessSliceSelect( + MouseEventArgs e, PieChart pieChart, PieSeriesPoint psp) + { + bool select = true; + + if ((pieChart.MultiSelect == true) && + (Control.ModifierKeys & Keys.Control) == Keys.Control) + { + select = !psp.IsSelected; + } + else + { + if (InitPspDrag(pieChart, psp) == true) + return; + + int selCount = pieChart.GetSelectionCount(); + + if (selCount != 1 || psp.IsSelected == false) + pieChart.SetSelected(false); + } + + ProcessSliceSelectEx(pieChart, psp, select); + } + + #region ProcessSliceSelectEx + + private void ProcessSliceSelectEx( + PieChart pieChart, PieSeriesPoint psp, bool select) + { + PieSelectionMode psm = GetPieSelectionMode(pieChart); + + switch (psm) + { + case PieSelectionMode.Pie: + pieChart.SetSelected(select); + break; + + case PieSelectionMode.Series: + SelectPspSeries(SeriesPoints, true, select); + break; + + case PieSelectionMode.Ring: + SelectPspRing(psp, select); + break; + + case PieSelectionMode.Slice: + SelectPspSlice(pieChart, psp, select); + break; + + case PieSelectionMode.Point: + psp.IsSelected = select; + break; + } + + ChartControl.DoPieSelectionChangedEvent(pieChart, this, psp, psm); + } + + #region SelectPspSeries + + private void SelectPspSeries( + PieSeriesPointCollection spc, bool showInner, bool select) + { + if (spc != null) + { + foreach (PieSeriesPoint psp in spc) + { + if (psp.AllowSelect == true) + { + psp.IsSelected = select; + + if (showInner == true) + SelectPspSeries(psp.SeriesPoints, true, select); + } + } + } + } + + #endregion + + #region SelectPspRing + + private void SelectPspRing(PieSeriesPoint psp, bool select) + { + if (psp.PieRing != null) + { + if (psp.PieRing.AllowSelect == true) + { + foreach (PieSeriesPoint rpsp in psp.PieRing.Psps) + { + if (rpsp.AllowSelect == true) + rpsp.IsSelected = select; + } + } + } + } + + #endregion + + #region SelectPspSlice + + private void SelectPspSlice( + PieChart pieChart, PieSeriesPoint psp, bool select) + { + PieSeriesPoint rootPsp = (ShowAllRingsEx(pieChart) == true) + ? psp.RootPsp : psp; + + if (rootPsp != null) + { + if (rootPsp.AllowSelect == true) + { + rootPsp.IsSelected = select; + + SelectPspSliceEx(rootPsp.SeriesPoints, select); + } + } + } + + #region SelectPspSliceEx + + private void SelectPspSliceEx(PieSeriesPointCollection spc, bool select) + { + if (spc != null) + { + foreach (PieSeriesPoint psp in spc) + { + if (psp.AllowSelect == true) + { + psp.IsSelected = select; + + SelectPspSliceEx(psp.SeriesPoints, select); + } + } + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region ProcessMouseMove + + internal void ProcessMouseMove(MouseEventArgs e, PieChart pieChart) + { + if (IsMouseDown == true && _MouseDownPsp != null) + ProcessMouseDownMove(e, pieChart); + } + + #region ProcessMouseDownMove + + private bool ProcessMouseDownMove(MouseEventArgs e, PieChart pieChart) + { + Point pt = e.Location; + + if (pieChart.IsDragging == false) + { + if (Math.Abs(MouseDownPoint.X - pt.X) > 3 || + Math.Abs(MouseDownPoint.Y - pt.Y) > 3) + { + pieChart.IsDragging = true; + } + } + else + { + int deltaOffset = GetDeltaOffset(pieChart, pt); + + MouseClickSliceAction mca = GetMouseClickSliceAction(pieChart); + + switch (pieChart.PspDragType) + { + case PspDragType.Detach: + if (GetEnableDragDetach(pieChart) == true) + DetachSelectedPsps(pieChart, mca, deltaOffset); + break; + + case PspDragType.Explode: + if (pieChart.EnableShiftDragExplode == true) + ExplodePie(pieChart, deltaOffset); + break; + } + } + + return (true); + } + + #region GetDeltaOffset + + private int GetDeltaOffset(PieChart pieChart, Point pt) + { + PieSeriesPoint psp = pieChart.HitPsp; + + if (psp != null) + { + Point cpt = pieChart.GetLocalAdjustedPoint(pieChart.CenterPoint); + + Point rpt = pt; + double radius = MathHelper.GetPointRadius(ref rpt, cpt); + + if (ShowAllRingsEx(pieChart) == true) + { + double pspAngle = MathHelper.GetPointAngle(rpt); + + double angle = psp.CenterAngle - pspAngle; + double delta = Math.Cos(MathHelper.ToRadians(angle)) * radius; + + return ((int)delta); + } + + return ((int)radius); + } + + return (0); + } + + #endregion + + #region DetachSelectedPsps + + private void DetachSelectedPsps( + PieChart pieChart, MouseClickSliceAction mca, int deltaOffset) + { + int offset = Math.Max(0, deltaOffset - _MouseDownRadius + _MouseDownOffset); + offset = Math.Min(offset, pieChart.MaxDetachedOffset); + + PieSeriesPoint pspRoot = + ShowAllRingsEx(pieChart) ? _MouseDownPsp.RootPsp : _MouseDownPsp; + + PieSelectionMode psm = GetPieSelectionMode(pieChart); + + bool detachChange = false; + + switch (psm) + { + case PieSelectionMode.Pie: + foreach (PieSeries series in pieChart.ChartSeries) + { + if (series.IsDisplayed == true) + { + foreach (PieSeriesPoint psp in series.SeriesPoints) + detachChange |= DetachPsp(psp, offset); + } + } + break; + + case PieSelectionMode.Series: + case PieSelectionMode.Ring: + if (pspRoot.PieRing.AllowDetach == true) + { + foreach (PieSeriesPoint psp in pspRoot.PieRing.Psps) + detachChange |= DetachPsp(psp, offset); + } + break; + + case PieSelectionMode.Slice: + case PieSelectionMode.Point: + if (mca == MouseClickSliceAction.Select) + { + if (pspRoot.PieRing.AllowDetach == true) + { + foreach (PieSeriesPoint psp in pspRoot.PieRing.Psps) + { + if (psp.IsSelected == true) + detachChange |= DetachPsp(psp, offset); + } + } + } + else + { + detachChange |= DetachPsp(pspRoot, offset); + } + break; + } + + ChartControl.DoPieDetachChangedEvent(pieChart, this, psm); + } + + #region DetachPsp + + private void DetachPsp(PieSeriesPoint psp) + { + DetachPsp(psp, psp.DetachedOffset); + } + + private bool DetachPsp(PieSeriesPoint psp, double offset) + { + if (psp.AllowDetach == true) + { + if (psp.DetachedOffset != offset || psp.IsDetached != (offset > 0)) + { + psp.DetachedOffset = offset; + psp.IsDetached = (offset > 0); + + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region ExplodePie + + private void ExplodePie(PieChart pieChart, int deltaOffset) + { + int offset = Math.Max(0, deltaOffset - _MouseDownRadius + _MouseDownOffset); + + offset = Math.Min(offset, pieChart.MaxExplodedOffset); + + if (pieChart.ExplodedOffset != offset || pieChart.IsExploded != (offset > 0)) + { + pieChart.IsExploded = (offset > 0); + pieChart.ExplodedOffset = offset; + + ChartControl.DoPieExplodeChangedEvent(pieChart, this); + } + } + + #endregion + + #endregion + + #endregion + + #region ProcessMouseUp + + internal void ProcessMouseUp(MouseEventArgs e, PieChart pieChart) + { + if (pieChart.IsDragging == false) + { + PieSeriesPoint psp = pieChart.HitPsp; + + if (psp != null && psp == _MouseDownPsp) + { + ChartControl chartControl = ChartControl; + + if (chartControl.DoChartMouseClickEvent(pieChart, psp, e) == false) + { + MouseClickSliceAction mca = GetMouseClickSliceAction(pieChart); + + switch (mca) + { + case MouseClickSliceAction.Explode: + pieChart.IsExploded = !pieChart.IsExploded; + break; + + case MouseClickSliceAction.Detach: + DetachPsp(ShowAllRingsEx(pieChart) ? psp.RootPsp : psp); + break; + + case MouseClickSliceAction.Select: + if ((Control.ModifierKeys & Keys.Control) == Keys.None) + { + int selCount = pieChart.GetSelectionCount(); + + if (selCount != 1 || psp.IsSelected == false) + pieChart.SetSelected(false); + + ProcessSliceSelectEx(pieChart, psp, true); + } + break; + } + } + } + } + } + + + #endregion + + #region ProcessMouseDoubleClick + + internal bool ProcessMouseDoubleClick( + MouseEventArgs e, PieChart pieChart, PieSeriesPoint psp) + { + if (e.Button == MouseButtons.Left) + { + MouseDoubleClickSliceAction mdca = GetMouseDoubleClickSliceAction(pieChart); + + switch (mdca) + { + case MouseDoubleClickSliceAction.Detach: + psp.IsDetached = !psp.IsDetached; + break; + + case MouseDoubleClickSliceAction.Explode: + pieChart.IsExploded = !pieChart.IsExploded; + break; + + case MouseDoubleClickSliceAction.ChangeActiveRing: + Keys keys = Control.ModifierKeys; + + if ((keys & Keys.Shift) == Keys.Shift) + ProcessPieDrillUp(pieChart, psp); + + else if ((keys & Keys.Control) == Keys.None) + ProcessPieDrillDown(pieChart, psp); + break; + } + + return (true); + } + + return (false); + } + + #region ProcessPieDrillUp + + private void ProcessPieDrillUp(PieChart pieChart, PieSeriesPoint psp) + { + PieSeriesPointCollection spc1 = psp.Parent as PieSeriesPointCollection; + + if (spc1 != null) + { + PieSeriesPoint psp2 = spc1.Parent as PieSeriesPoint; + + if (psp2 != null) + { + PieSeriesPointCollection spc2 = GetPieSeriesPointCollection(psp2); + + if (spc2 != null) + { + ChartControl chartControl = ChartControl; + + if (chartControl.DoPieRingLevelChangingEvent(pieChart, spc1, spc2) == false) + { + SetActiveSeriesPointCollection(spc2); + + chartControl.DoPieRingLevelChangedEvent(pieChart, spc1, spc2); + } + } + } + } + } + + #endregion + + #region ProcessPieDrillDown + + private void ProcessPieDrillDown(PieChart pieChart, PieSeriesPoint psp) + { + if (psp.ChartSeries.ShowAllRingsEx(pieChart) == false) + { + PieSeriesPointCollection spc1 = psp.Parent as PieSeriesPointCollection; + + if (psp.SeriesPoints.Count > 0) + { + ChartControl chartControl = ChartControl; + PieSeriesPointCollection spc2 = psp.SeriesPoints; + + if (chartControl.DoPieRingLevelChangingEvent(pieChart, spc1, spc2) == false) + { + SetActiveSeriesPointCollection(psp.SeriesPoints); + + chartControl.DoPieRingLevelChangedEvent(pieChart, spc1, spc2); + } + } + } + } + + #endregion + + #endregion + + #endregion + + #region SetSelected + + /// + /// Selects or clears all series PieSeriesPoints. + /// + /// + public void SetSelected(bool select) + { + PieSeriesPointCollection spc = SeriesPoints; + + spc.SetSelected(select); + + if (spc.OtherSlicePsp != null) + spc.OtherSlicePsp.IsSelected = select; + } + + #endregion + + #region GetVisibleSelectionCount + + /// + /// Gets the count of the currently Visible selected pie series points. + /// + /// + public int GetVisibleSelectionCount() + { + int count = GetVisibleSelectionCountEx(SeriesPoints); + + return (count); + } + + #region GetVisibleSelectionCountEx + + private int GetVisibleSelectionCountEx(PieSeriesPointCollection spc) + { + int count = 0; + + if (spc != null && spc.Count > 0) + { + foreach (PieSeriesPoint psp in spc) + { + if (psp.IsSelected == true && psp.Visible == true) + count++; + + count += GetVisibleSelectionCountEx(psp.SeriesPoints); + } + + if (spc.OtherSlicePsp != null) + { + if (spc.OtherSlicePsp.IsSelected == true && spc.OtherSlicePsp.Visible == true) + count++; + } + } + + return (count); + } + + #endregion + + #endregion + + #region GetVisibleSelectedPoints + + /// + /// Gets a list of the currently Visible selected pie series points. + /// + /// + public List GetVisibleSelectedPoints() + { + List list = new List(); + + GetVisibleSelectedPointsEx(list, SeriesPoints); + + return (list); + } + + #region GetVisibleSelectedPointsEx + + private void GetVisibleSelectedPointsEx( + List list, PieSeriesPointCollection spc) + { + if (spc != null && spc.Count > 0) + { + foreach (PieSeriesPoint psp in spc) + { + if (psp.IsSelected == true && psp.Visible == true) + list.Add(psp); + + GetVisibleSelectedPointsEx(list, psp.SeriesPoints); + } + + if (spc.OtherSlicePsp != null) + { + if (spc.OtherSlicePsp.IsSelected == true && spc.OtherSlicePsp.Visible == true) + list.Add(spc.OtherSlicePsp); + } + } + } + + #endregion + + #endregion + + #region GetSelectionCount + + /// + /// Gets a count of the selected pie series points. + /// + /// + public int GetSelectionCount() + { + int count = GetSelectionCountEx(SeriesPoints); + + return (count); + } + + #region GetSelectionCountEx + + private int GetSelectionCountEx(PieSeriesPointCollection spc) + { + int count = 0; + + if (spc != null && spc.Count > 0) + { + foreach (PieSeriesPoint psp in spc) + { + if (psp.IsSelected == true) + count++; + + count += GetSelectionCountEx(psp.SeriesPoints); + } + + if (spc.OtherSlicePsp != null) + { + if (spc.OtherSlicePsp.IsSelected == true ) + count++; + } + } + + return (count); + } + + #endregion + + #endregion + + #region GetSelectedPoints + + /// + /// Gets a list of the currently selected pie series points. + /// + /// + public List GetSelectedPoints() + { + List list = new List(); + + GetSelectedPointsEx(list, SeriesPoints); + + return (list); + } + + #region GetSelectedPointsEx + + private void GetSelectedPointsEx( + List list, PieSeriesPointCollection spc) + { + if (spc != null && spc.Count > 0) + { + foreach (PieSeriesPoint psp in spc) + { + if (psp.IsSelected == true) + list.Add(psp); + + GetSelectedPointsEx(list, psp.SeriesPoints); + } + + if (spc.OtherSlicePsp != null) + { + if (spc.OtherSlicePsp.IsSelected == true) + list.Add(spc.OtherSlicePsp); + } + } + } + + #endregion + + #endregion + + #region Style handling + + #region StyleChanged + + protected override void StyleChanged(object sender, PropertyChangedEventArgs e) + { + base.StyleChanged(sender, e); + + if (sender is ChartLegendItemVisualStyles && LegendItem != null) + InvalidateRender(LegendItem.Bounds); + } + + #endregion + + #endregion + + #region InvalidateRender + + public override void InvalidateRender() + { + BaseChart chart = Parent as BaseChart; + + if (chart != null) + chart.InvalidateRender(); + } + + #endregion + + #region InvalidateRecalc + + internal override void InvalidateRecalc() + { + SeriesRangeChanged = true; + + base.InvalidateRecalc(); + } + + #endregion + + #region ILegendItem + + #region GetLegendItem + + public override ChartLegendItem GetLegendItem() + { + LegendItem = null; + + if (ShowInLegend == true) + { + PieChart pieChart = Parent as PieChart; + + if (pieChart != null) + { + if (pieChart.VisibleSeriesCount > 1) + { + if (pieChart.Legend.ShowPieSeriesInLegend == true) + { + LegendItem = base.GetLegendItem(); + + LegendItem.ShowCheckBox = pieChart.Legend.ShowPieSeriesCheckBoxes; + } + } + } + } + + return (LegendItem); + } + + #endregion + + #region AddSubLegendItems + + internal override void AddSubLegendItems(List list) + { + PieChart pieChart = Parent as PieChart; + + if (pieChart != null) + { + if (ShowInLegend == true) + { + ChartLegend legend = pieChart.Legend; + + if (ShowAllRingsEx(pieChart) == true) + { + if (PieRings != null && PieRings.Count > 0) + { + bool addRings = + ((PieRings.Count > 1) && + (pieChart.Legend.ShowPieRingsInLegend == true)); + + foreach (PieRing pieRing in PieRings) + { + if (addRings == true) + { + ChartLegendItem litem = pieRing.GetLegendItem(); + + if (litem != null) + { + litem.ShowCheckBox = legend.ShowPieRingCheckBoxes; + list.Add(litem); + } + } + + if (legend.ShowPieSeriesPointsInLegend == true) + AddSubLegendItemsEx(legend, list, pieRing.GetLegendItems()); + } + } + } + else + { + PieSeriesPointCollection spc = GetActiveSeriesPointCollection(); + + if (spc != null) + { + if (spc.PieSlices != null) + spc = spc.PieSlices; + + if (spc != null) + { + foreach (PieSeriesPoint psp in spc) + { + if (psp.IsDisplayable == true) + AddSubLegendItemsEx(legend, list, psp.GetLegendItems()); + } + } + } + } + } + } + } + + #region AddSubLegendItemsEx + + private void AddSubLegendItemsEx(ChartLegend legend, + List list, List items) + { + if (items != null && items.Count > 0) + { + foreach (ChartLegendItem item in items) + { + item.ShowCheckBox = legend.ShowPieSeriesPointCheckBoxes; + + if (legend.CombineLikeItems == true) + { + ChartLegendItem likeItem = FindLikeItems(list, item); + + if (likeItem == null) + { + item.ChartControl = ChartControl; + + likeItem = new ChartLegendItem(); + + likeItem.Parent = legend; + likeItem.ChartControl = ChartControl; + + likeItem.Name = item.Name; + likeItem.ItemText = item.ItemText; + likeItem.IsEnabled = item.IsEnabled; + + list.Add(likeItem); + } + + item.LikeItem = likeItem; + + likeItem.ChartItems.AddRange(item.ChartItems); + } + else + { + list.Add(item); + } + } + } + } + + #region FindLikeItems + + private ChartLegendItem FindLikeItems(List list, ChartLegendItem item) + { + string itemName = item.Name ?? item.ItemText; + + if (String.IsNullOrEmpty(itemName) == false) + { + foreach (ChartLegendItem likeItem in list) + { + string likeName = likeItem.Name ?? likeItem.ItemText; + + if (String.IsNullOrEmpty(likeName) == false) + { + if (likeName.Equals(itemName) == true) + return (likeItem); + } + } + } + + return (null); + } + + #endregion + + #endregion + + #endregion + + #region GetLegendItemColorEx + + internal override Color GetLegendItemColorEx() + { + return (Color.Empty); + } + + #endregion + + #region RenderLegendItemMarkerEx + + internal override void RenderLegendItemMarkerEx( + Graphics g, ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + Rectangle bounds = litem.MarkerBounds; + + bounds.Width--; + bounds.Height--; + + Color color = GetLegendItemColor(); + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(bounds); + + using (Brush br = new SolidBrush(color)) + g.FillPath(br, path); + } + } + + #endregion + + #region TrackLegendItem + + /// + /// Gets whether legend item tracking is enabled. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TrackLegendItem + { + get + { + PieChart pieChart = Parent as PieChart; + + if (pieChart != null) + { + return (pieChart.Legend.TrackingMode == LegendTrackingMode.ChartAndLegend || + pieChart.Legend.TrackingMode == LegendTrackingMode.Legend); + } + + return (false); + } + } + + #endregion + + #region FormatItemText + + /// + /// Formats the provided item text. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string FormatItemText(string text) + { + return (text); + } + + #endregion + + #region OnCheckStateChanged + + internal override void OnCheckStateChanged() + { + if (LegendItem != null) + LegendItem.UpdateCheckState(); + + foreach (PieRing pieRing in PieRings) + { + if (pieRing.LegendItem != null) + { + pieRing.LegendItem.IsEnabled = pieRing.IsEnabled; + } + else + { + foreach (PieSeriesPoint psp in pieRing.Psps) + { + if (psp.LegendItem != null) + psp.LegendItem.IsEnabled = psp.IsEnabled; + } + } + } + + base.OnCheckStateChanged(); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartSeries copy = new ChartSeries(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + PieSeries c = copy as PieSeries; + + if (c != null) + { + base.CopyTo(c); + + c.CenterFirstSlice = CenterFirstSlice; + + if (_CustomPalette != null) + { + c.CustomPalette = new Color[CustomPalette.Length]; + + CustomPalette.CopyTo(c.CustomPalette, 0); + } + + c.EnableDragDetach = EnableDragDetach; + c.ExplodedMargin = ExplodedMargin; + + c.MouseClickSliceAction = MouseClickSliceAction; + c.MouseDoubleClickSliceAction = MouseDoubleClickSliceAction; + + c.PaletteGroup = PaletteGroup; + c.PieSelectionMode = PieSelectionMode; + c.ReversePaletteColors = ReversePaletteColors; + c.RingWeight = RingWeight; + + c.SubSliceVisualLayout = (_SliceVisualLayout != null) ? _SliceVisualLayout.Copy() : null; + + foreach (PieSeriesPoint psp in SeriesPoints) + c.SeriesPoints.Add(psp.Copy()); + + c.ShowAllRings = ShowAllRings; + c.ShowOtherSlice = ShowOtherSlice; + + c.SubSliceVisualLayout = (_SliceVisualLayout != null) ? SubSliceVisualLayout.Copy() : null; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "PieSeries"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("CenterFirstSlice", CenterFirstSlice, Tbool.NotSet); + + if (_CustomPalette != null && _CustomPalette.Length > 0) + { + sec.AddStartElement("CustomPalette count=\"" + _CustomPalette.Length + "\""); + + foreach (Color color in _CustomPalette) + sec.AddValue("PaletteColor", color); + + sec.AddEndElement("CustomPalette"); + } + + sec.AddValue("EnableDragDetach", EnableDragDetach, Tbool.NotSet); + sec.AddValue("ExplodedMargin", ExplodedMargin, double.NaN); + + sec.AddValue("MouseClickSliceAction", MouseClickSliceAction, MouseClickSliceAction.NotSet); + sec.AddValue("MouseDoubleClickSliceAction", MouseDoubleClickSliceAction, MouseDoubleClickSliceAction.NotSet); + + sec.AddValue("PaletteGroup", PaletteGroup, PaletteGroup.NotSet); + sec.AddValue("PieSelectionMode", PieSelectionMode, PieSelectionMode.NotSet); + sec.AddValue("ReversePaletteColors", ReversePaletteColors, false); + sec.AddValue("RingWeight", RingWeight, 100); + + if (_SeriesPoints != null) + { + PieSeriesPointCollection spc = _SeriesPoints; + + if (spc.Count > 0) + { + sec.AddStartElement("SeriesPoints count=\"" + spc.Count + "\""); + + foreach (PieSeriesPoint psp in spc) + sec.AddElement(psp.GetSerialData()); + + sec.AddEndElement("SeriesPoints"); + } + } + + sec.AddValue("ShowAllRings", ShowAllRings, Tbool.NotSet); + sec.AddValue("ShowOtherSlice", ShowOtherSlice, Tbool.NotSet); + + if (_SliceVisualLayout != null) + sec.AddElement(_SliceVisualLayout.GetSerialData(true)); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + ChartXy chartXy = Parent as ChartXy; + + switch (se.Name) + { + case "CenterFirstSlice": + CenterFirstSlice = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "EnableDragDetach": + EnableDragDetach = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ExplodedMargin": + ExplodedMargin = double.Parse(se.StringValue); + break; + + case "MouseClickSliceAction": + MouseClickSliceAction = (MouseClickSliceAction)se.GetValueEnum(typeof(MouseClickSliceAction)); + break; + + case "MouseDoubleClickSliceAction": + MouseDoubleClickSliceAction = (MouseDoubleClickSliceAction)se.GetValueEnum(typeof(MouseDoubleClickSliceAction)); + break; + + case "PaletteColor": + CustomPalette[se.ValueIndex] = se.GetValueColor(); + break; + + case "PaletteGroup": + PaletteGroup = (PaletteGroup)se.GetValueEnum(typeof(PaletteGroup)); + break; + + case "PieSelectionMode": + PieSelectionMode = (PieSelectionMode)se.GetValueEnum(typeof(PieSelectionMode)); + break; + + case "ReversePaletteColors": + ReversePaletteColors = bool.Parse(se.StringValue); + break; + + case "RingWeight": + RingWeight = int.Parse(se.StringValue); + break; + + case "ShowAllRings": + ShowAllRings = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShowOtherSlice": + ShowOtherSlice = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "CustomPalette": + if (se.ArrayCount > 0) + { + CustomPalette = new Color[se.ArrayCount]; + + sec.PutSerialData(this); + } + break; + + case "SeriesPoint": + PieSeriesPoint psp = new PieSeriesPoint(); + + sec.PutSerialData(psp); + + SeriesPoints.Add(psp); + break; + + case "SeriesPoints": + if (se.ArrayCount > 0) + { + SeriesPoints = new PieSeriesPointCollection(); + + sec.PutSerialData(this); + } + break; + + case "SliceVisualLayout": + sec.PutSerialData(SubSliceVisualLayout); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region Series States + + [Flags] + private enum States : uint + { + FilterIgnoreMatchCase = (1U << 0), + + IsSorted = (1U << 1), + IsRotated = (1U << 2), + + StackQualitativePoints = (1U << 3), + DisplayLinePointsOnTop = (1U << 4), + + EnableEmptyValues = (1U << 5), + ShowEmptyLines = (1U << 6), + ShowEmptyPoints = (1U << 7), + ShowOriginValueLabels = (1U << 8), + ShowHiLoBarMedianLines = (1U << 9), + + NeedToUpdateBindings = (1U << 10), + + IsInnerRingSeries = (1U << 11), + IsOuterRingSeries = (1U << 12), + + IsOffset = (1U << 13), + IsDetached = (1U << 14), + + ShowInnerRingsEx = (1U << 15), + ReversePaletteColors = (1U << 16), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + Visible = false; + + SeriesPoints = null; + SubSliceVisualLayout = null; + + base.Dispose(); + } + + #endregion + } + + #region WordPos + + internal class WordPos + { + public string Text; + + public int Index; + public int Length; + } + + #endregion + + #region WordPosLine + + internal class WordPosLine + { + public double ArcWidth; + public double LineWidth; + public double Offset; + + public List Wps = new List(); + } + + #endregion + + #region enums + + #region SliceRenderType + + public enum SliceRenderType + { + /// + /// Full slice. + /// + FullSlice, + + /// + /// Extent slice (partial slice). + /// + ExtentSlice, + + /// + /// Extentwhitespace. + /// + ExtentWhitespace, + + /// + /// 'Other' slice whitespace. + /// + OtherWhitespace, + } + + #endregion + + #region ExtentFillRange + + public enum ExtentFillRange + { + /// + /// Not set (default is ByPoint) + /// + NotSet = 0, + + /// + /// Extents are filled according to each individual + /// PieSeriesPoint extent value. + /// + ByPoint, + + /// + /// Extents are filled according to the slice + /// maximum extent value. + /// + BySlice, + + /// + /// Extents are filled according to the associated + /// PieRing maximum extent value. + /// + ByRing, + } + + #endregion + + #region SliceImageCropMode + + public enum SliceImageCropMode + { + NotSet = -1, + + NoAction, + ClipImage, + HideImage, + } + + #endregion + + #region SliceImageRadiusAnchor + + /// + /// Defines the anchor for the slice image (ie. the image's bounding edge). + /// + public enum SliceImageRadiusAnchor + { + /// + /// NotSet + /// + NotSet = -1, + + /// + /// The pie InnerRadius will be the anchor. + /// + InnerRadius, + + /// + /// The pie ExtentRadius will be the anchor. The 'ExtentRadius' denotes + /// how far the slice extends out from the slice center - which may not + /// be as far as the OuterRadius (specified by the ValuesY[1] value). + /// + ExtentRadius, + + /// + /// The pie OuterRadius will be the anchor. + /// + OuterRadius, + } + + #endregion + + #region PieRefLineDisplayMode + + [Flags] + /// + /// Defines the type of ReferenceLine to display. + /// + public enum PieRefLineDisplayMode + { + /// + /// NotSet + /// + NotSet = 0, + + /// + /// No Reference lines + /// + None = (1 << 0), + + /// + /// Extent Average Line. + /// + ExtentAverage = (1 << 3), + + /// + /// Extent Minimum Line. + /// + ExtentMaximum = (1 << 2), + + /// + /// Extent Minimum Line. + /// + ExtentMinimum = (1 << 1), + + /// + /// Outer Extent Line. + /// + ExtentOuterRadius = (1 << 4), + + /// + /// All User defined Lines. + /// + UserDefined = (1 << 5), + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/RadialAlign.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/RadialAlign.cs new file mode 100644 index 00000000..27083fda --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/RadialChart/RadialAlign.cs @@ -0,0 +1,614 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + class RadialAlign + { + #region Private variables + + private List _PieLabels; + + #endregion + + public RadialAlign(List pieLabels) + { + _PieLabels = pieLabels; + + foreach (PieLabel pl in _PieLabels) + pl.Bounds = Rectangle.Empty; + } + + #region Iterate + + public bool Iterate(Graphics g, PieChart pieChart, Rectangle bounds) + { + if (_PieLabels.Count > 0) + { + PositionLabels(pieChart, bounds); + + List[] plist = SortLabels(); + + for (int i = 0; i < plist.Length; i++) + { + List pls = plist[i]; + + if (pls.Count > 0) + { + if (IsAnyOverlap(pieChart, pls) == true) + { + AdjustDownwards(pieChart, pls, bounds); + + if (IsAnyOverlap(pieChart, pls) == true) + AdjustUpwards(pieChart, pls, bounds); + } + + AdjustLabelSizes(g, pieChart, pls, bounds); + + if (IsAnyOverlap(pieChart, pls) == true) + { + AdjustDownwards(pieChart, pls, bounds); + + if (IsAnyOverlap(pieChart, pls) == true) + AdjustUpwards(pieChart, pls, bounds); + } + + if (pieChart.SliceLabelOverlapMode != SliceLabelOverlapMode.ShowOverlapping) + { + if (IsAnyOverlap(pieChart, pls) == true) + HideOverLapping(pls, bounds); + } + + UpdateBoxPoints(pieChart, pls); + } + } + } + + return (true); + } + + #region PositionLabels + + private void PositionLabels(PieChart pieChart, Rectangle bounds) + { + foreach (PieLabel pl in _PieLabels) + { + PieSeriesPoint psp = pl.PieSeriesPoint; + PieSeriesPointCollection spc = psp.Parent as PieSeriesPointCollection; + + if (spc != null) + { + bool showWhiteSpace = psp.ShowSliceWhiteSpaceEx; + + int width = psp.OuterRadius - psp.InnerRadius; + + int outerRadius = (psp.ShowSliceWhiteSpaceEx == true) + ? psp.OuterRadius : (int)(psp.InnerRadius + psp.SliceExtent * width); + + pl.LabelStyle = psp.GetEffectiveSliceStyle(pieChart, psp.ChartSeries).SliceOuterLabelStyle; + + pl.OuterRadius = outerRadius; + pl.Radius = outerRadius + pl.LabelStyle.ConnectorLength; + + UpdateBoundingRect(pieChart, psp, pl, psp.CenterAngle); + } + } + + AdjustForChartBounds(pieChart, _PieLabels); + } + + #region UpdateBoundingRect + + private void UpdateBoundingRect(PieChart pieChart, PieSeriesPoint psp, PieLabel pl, double angle) + { + pl.PtSliceEdge = psp.GetRayEndPoint(angle, pl.OuterRadius); + + Point pt = psp.GetRayEndPoint(angle, pl.Radius); + + Rectangle r = new Rectangle(pt, pl.LabelSize); + r.Y -= (r.Size.Height / 2); + + angle = (angle + 360000) % 360; + + int n = (pl.LabelStyle.DrawConnector == Tbool.True) + ? Dpi.Width(pl.LabelStyle.ConnectorTickLength) : 0; + + r.X += ((angle >= 270 || angle <= 90) ? n : -(r.Size.Width + n)); + + pl.Bounds = r; + + AdjustForPieIntersect(pl); + } + + #region AdjustForPieIntersect + + private void AdjustForPieIntersect(PieLabel pl) + { + PieSeriesPoint psp = pl.PieSeriesPoint; + + Point pto = GetClosestOffset(psp.SliceCenter, pl.Bounds); + + Point ptr = psp.SliceCenter; + ptr.X += pto.X; + ptr.Y += pto.Y; + + if (Intersects(psp, ptr, pl) == true) + { + Rectangle r = pl.Bounds; + + double ihyp = Math.Sqrt(pto.X * pto.X + pto.Y * pto.Y); + double ohyp = (psp.OuterRadius + pl.LabelStyle.LabelMargin) - ihyp; + + double scale = ohyp / ihyp; + + int dx = (int)(pto.X * scale); + int dy = (int)(pto.Y * scale); + + r.X += dx; + r.Y += dy; + + pl.Bounds = r; + } + } + + #region GetClosestOffset + + private Point GetClosestOffset(Point ptc, Rectangle r) + { + Point pt = new Point(); + + int dx1 = r.X - ptc.X; + int dx2 = r.Right - ptc.X; + + int dy1 = r.Y - ptc.Y; + int dy2 = r.Bottom - ptc.Y; + + pt.X = Math.Abs(dx1) < Math.Abs(dx2) ? dx1 : dx2; + pt.Y = Math.Abs(dy1) < Math.Abs(dy2) ? dy1 : dy2; + + return (pt); + } + + #endregion + + #region Intersects + + private bool Intersects( + PieSeriesPoint psp, Point ptr, PieLabel pl) + { + int radius = psp.OuterRadius + pl.LabelStyle.LabelMargin; + + int dx = psp.SliceCenter.X - ptr.X; + int dy = psp.SliceCenter.Y - ptr.Y; + + float dsq = (dx * dx) + (dy * dy); + + return (dsq < (radius * radius)); + } + + #endregion + + #endregion + + #endregion + + #region AdjustForChartBounds + + private void AdjustForChartBounds(PieChart pieChart, List pls) + { + Rectangle r = pieChart.ContentBoundsEx; + + for (int i = 0; i < pls.Count; i++) + { + PieLabel pl = pls[i]; + + if (pl.Bounds.IsEmpty == false) + { + int margin = Dpi.Width(pl.LabelStyle.LabelMargin); + + if (pl.Bounds.Bottom + margin > r.Bottom) + { + Rectangle t = pl.Bounds; + t.Y = (r.Bottom - t.Height - margin); + pl.Bounds = t; + } + } + } + } + + #endregion + + #endregion + + #region SortLabels + + private List[] SortLabels() + { + List[] plist = new List[2]; + + plist[0] = new List(); + plist[1] = new List(); + + foreach (PieLabel pl in _PieLabels) + { + double angle = pl.PieSeriesPoint.CenterAngle % 360; + + pl.IsRightlabel = (angle >= 270 || angle <= 90); + + if (pl.IsRightlabel == true) + plist[1].Add(pl); + else + plist[0].Add(pl); + } + + plist[0].Sort(new PieLabelYComparer()); + plist[1].Sort(new PieLabelYComparer()); + + return (plist); + } + + #region PieLabelYComparer + + private class PieLabelYComparer : IComparer + { + public int Compare(PieLabel pl1, PieLabel pl2) + { + return (pl1.PtSliceEdge.Y - pl2.PtSliceEdge.Y); + } + } + + #endregion + + #endregion + + #region IsAnyOverlap + + private bool IsAnyOverlap(PieChart pieChart, List pls) + { + if (pls.Count <= 0) + return (false); + + PieSeriesPoint psp = pls[0].PieSeriesPoint; + + if (psp.SliceLabelVisibilityEx == SliceLabelVisibility.SliceMouseOver) + return (false); + + int maxy = 0; + + for (int i = 0; i < pls.Count; i++) + { + PieLabel pl = pls[i]; + + if (pl.Bounds.IsEmpty == false) + { + if (maxy > pl.Bounds.Y) + return (IsAnyOverlapEx(pieChart, pls)); + + int margin = Dpi.Width(pl.LabelStyle.LabelMargin); + + if (pl.Bounds.Bottom + margin > maxy) + maxy = pl.Bounds.Bottom + margin; + } + } + + return (false); + } + + #region IsAnyOverlapEx + + private bool IsAnyOverlapEx(PieChart pieChart, List pls) + { + for (int i = 0; i < pls.Count; i++) + { + PieLabel pl = pls[i]; + + if (pl.Bounds.IsEmpty == false) + { + int margin = pl.LabelStyle.LabelMargin; + + Rectangle r = pl.Bounds; + r.Inflate(margin, margin); + + for (int j = i + 1; j < pls.Count; j++) + { + PieLabel pl2 = pls[j]; + + if (r.IntersectsWith(pl2.Bounds) == true) + return (true); + } + } + } + + return (false); + } + + #endregion + + #endregion + + #region HideOverLapping + + private void HideOverLapping(List pls, Rectangle bounds) + { + for (int i = 0; i < pls.Count; i++) + { + PieLabel pl = pls[i]; + + if (pl.Bounds.IsEmpty == false) + { + for (int j = i + 1; j < pls.Count; j++) + { + PieLabel pl2 = pls[j]; + + if (pl.Bounds.IntersectsWith(pl2.Bounds) == true) + pl2.Bounds = Rectangle.Empty; + } + } + } + } + + #endregion + + #region AdjustUpwards + + private void AdjustUpwards(PieChart pieChart, List pls, Rectangle bounds) + { + for (int i = pls.Count - 1; i > 0; i--) + { + PieLabel pl0 = pls[i]; + PieLabel pl1 = pls[i - 1]; + + int margin = Dpi.Width(pl0.LabelStyle.LabelMargin); + + Rectangle t = pl0.Bounds; + t.Inflate(margin, margin); + + if (pl1.Bounds.Bottom > t.Y) + { + if ((pl1.Bounds.X < t.Right) && (t.X < pl1.Bounds.Right)) + { + Rectangle r = pl1.Bounds; + + r.Y = Math.Max(bounds.Y + margin, pl0.Bounds.Y - pl1.Bounds.Height - margin); + + pl1.Bounds = r; + + AdjustForPieIntersect(pl1); + } + } + } + } + + #endregion + + #region AdjustDownwards + + private void AdjustDownwards(PieChart pieChart, List pls, Rectangle bounds) + { + for (int i = 0; i < pls.Count - 1; i++) + { + PieLabel pl0 = pls[i]; + PieLabel pl1 = pls[i + 1]; + + int margin = Dpi.Width(pl0.LabelStyle.LabelMargin) + 4; + + Rectangle t = pl0.Bounds; + t.Inflate(margin, margin); + + if (pl1.Bounds.Bottom < t.Bottom) + { + if ((pl1.Bounds.X < t.Right) && (t.X < pl1.Bounds.Right)) + { + Rectangle r = pl1.Bounds; + + r.Y = Math.Min(bounds.Bottom - r.Height - margin, t.Bottom); + + pl1.Bounds = r; + + AdjustForPieIntersect(pl1); + } + } + } + } + + #endregion + + #region AdjustSpread + + private void AdjustSpread(List pls, Rectangle bounds) + { + int height = 0; + + for (int i = 0; i < pls.Count; i++) + height += pls[i].Bounds.Height; + + int margin = bounds.Height - height; + + if (pls.Count > 1) + margin /= (pls.Count - 1); + + int y = bounds.Y; + + for (int i = 0; i < pls.Count; i++) + { + PieLabel pl = pls[i]; + + Rectangle r = pl.Bounds; + + r.Y = y; + pl.Bounds = r; + + y = (pl.Bounds.Bottom + margin); + + AdjustForPieIntersect(pl); + } + } + + #endregion + + #region AdjustLabelSizes + + private void AdjustLabelSizes(Graphics g, + PieChart pieChart, List pls, Rectangle bounds) + { + Rectangle r = pieChart.ContentBoundsEx; + + foreach (PieLabel pl in pls) + { + PieSeriesPoint psp = pl.PieSeriesPoint; + + ChartSliceVisualStyle sstyle = + psp.GetEffectiveSliceStyle(pieChart, psp.ChartSeries); + + Rectangle t = GetChartBounds(pieChart, pl); + + if (pl.LabelSize.Width != t.Width) + { + PieSeries series = psp.ChartSeries; + + Size size = series.MeasurePieLabel(g, + pieChart, psp, pl, t.Width, sstyle.SliceOuterLabelStyle); + + if (size != pl.Bounds.Size) + { + if (t.X != pl.Bounds.X && size.Width < t.Size.Width) + t.X += (t.Size.Width - size.Width); + + if (size.Height > t.Size.Height) + t.Y -= (size.Height - t.Size.Height) / 2; + + t.Size = size; + } + + pl.Bounds = t; + + AdjustForPieIntersect(pl); + } + } + } + + #region GetChartBounds + + private Rectangle GetChartBounds(PieChart pieChart, PieLabel pl) + { + Rectangle r = pl.Bounds; + + r.Inflate(4, 4); + + if (r.X < pieChart.ContentBoundsEx.X) + { + r.Width -= (pieChart.ContentBoundsEx.X - r.X); + r.X = pieChart.ContentBoundsEx.X; + + if (r.Width <= 0) + return (Rectangle.Empty); + } + + if (r.Right >= pieChart.ContentBoundsEx.Right) + { + r.Width -= (r.Right - pieChart.ContentBoundsEx.Right + 1); + + if (r.Width <= 0) + return (Rectangle.Empty); + } + + if (r.Y < pieChart.ContentBoundsEx.Y) + { + r.Height -= (pieChart.ContentBoundsEx.Y - r.Y); + r.Y = pieChart.ContentBoundsEx.Y; + + if (r.Height <= 0) + return (Rectangle.Empty); + } + + if (r.Bottom >= pieChart.ContentBoundsEx.Bottom) + { + int n = (r.Bottom - pieChart.ContentBoundsEx.Bottom + 1); + + r.Y -= n; + r.Width++; + + if (r.Height <= 0) + return (Rectangle.Empty); + } + + r.Inflate(-4, -4); + + return (r); + } + + #endregion + + #endregion + + #region UpdateBoxPoints + + private void UpdateBoxPoints(PieChart pieChart, List pls) + { + foreach (PieLabel pl in pls) + { + Rectangle t = new Rectangle(); + + Rectangle r = pl.Bounds; + + if (r.IsEmpty == false) + { + if (pl.LabelStyle.DrawConnector == Tbool.True) + { + int tick = pl.LabelStyle.ConnectorTickLength; + + if (pl.IsLeftlabel == true) + { + pl.PtBoxEdge = new Point(r.Right, r.Y + r.Height / 2); + pl.PtBoxBend = new Point(pl.PtBoxEdge.X + tick, pl.PtBoxEdge.Y); + } + else + { + pl.PtBoxEdge = new Point(r.X, r.Y + r.Height / 2); + pl.PtBoxBend = new Point(pl.PtBoxEdge.X - tick, pl.PtBoxEdge.Y); + } + + Point ptMin = new Point(); + Point ptMax = new Point(); + + if (pl.PtBoxEdge.X < pl.PtSliceEdge.X) + { + ptMin.X = pl.PtBoxEdge.X; + ptMax.X = pl.PtSliceEdge.X; + } + else + { + ptMin.X = pl.PtSliceEdge.X; + ptMax.X = pl.PtBoxEdge.X; + } + + if (pl.PtBoxEdge.Y < pl.PtSliceEdge.Y) + { + ptMin.Y = pl.PtBoxEdge.Y; + ptMax.Y = pl.PtSliceEdge.Y; + } + else + { + ptMin.Y = pl.PtSliceEdge.Y; + ptMax.Y = pl.PtBoxEdge.Y; + } + + t.Location = ptMin; + t.Width = ptMax.X - ptMin.X + 1; + t.Height = ptMax.Y - ptMin.Y + 1; + } + } + + pl.Bounds = r; + pl.ConnectorBounds = t; + } + } + + #endregion + + #endregion + } +} + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/SeriesPoints.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/SeriesPoints.cs new file mode 100644 index 00000000..133da031 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/SeriesPoints.cs @@ -0,0 +1,5681 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + [Editor("DevComponents.Charts.Design.PieSeriesPointCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class PieSeriesPointCollection : CustomNamedCollection + { + #region Private variables + + private ISeriesPointContainer _Parent; + + private PieSeriesPointCollection _PieSlices; + private PieSeriesPointCollection _OtherSlices; + + private PieSeriesPoint _OtherSlicePsp; + + private double _PieTotal; + + private double _PieMinExtent; + private double _PieMaxExtent; + private double _PieOuterExtent; + private double _PieTotalExtent; + + private double _PieAverage; + private double _PieAverageExtent; + + private PieRing _PieRing; + + private States _States; + + #endregion + + #region Public properties + + #region IsOther + + /// + /// Gets whether the PieSeriesPoint is the 'Other' slice collection. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsOther + { + get { return (TestState(States.Other)); } + internal set { SetState(States.Other, value); } + } + + #endregion + + #region OtherSlicePsp + + /// + /// Gets the 'Other' slice PieSeriesPoint. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public PieSeriesPoint OtherSlicePsp + { + get + { + if (_OtherSlicePsp == null) + _OtherSlicePsp = new PieSeriesPoint("Other", null, null); + + return (_OtherSlicePsp); + } + } + + #endregion + + #region OtherSlices + + /// + /// Gets the 'Other' slice collection of SeriesPoints. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public PieSeriesPointCollection OtherSlices + { + get { return (_OtherSlices); } + internal set { _OtherSlices = value; } + } + + #endregion + + #region Parent + + /// + /// Gets the parent of this item. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ISeriesPointContainer Parent + { + get { return (_Parent); } + internal set { _Parent = value; } + } + + #endregion + + #region PieAverage + + /// + /// Gets the average pie point 'value' (Y[0]) for the collection. + /// + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double PieAverage + { + get { return (_PieAverage); } + internal set { _PieAverage = value; } + } + + #endregion + + #region PieAverageExtent + + /// + /// Gets the average extent for the collection. + /// + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double PieAverageExtent + { + get { return (_PieAverageExtent); } + internal set { _PieAverageExtent = value; } + } + + #endregion + + #region PieSlices + + /// + /// Gets the collection of displayed Pie slices. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public PieSeriesPointCollection PieSlices + { + get { return (_PieSlices); } + + internal set + { + if (_PieSlices != null) + SetOtherHandler(false); + + _PieSlices = value; + + if (_PieSlices != null) + SetOtherHandler(true); + } + } + + #region SetOtherHandler + + private void SetOtherHandler(bool notify) + { + PieSeriesPointCollection spc = _PieSlices; + + foreach (PieSeriesPoint psp in spc) + { + if (psp.IsOther == true) + { + SetPointNotify(psp, notify); + + break; + } + } + } + + #region SetPointNotify + + private void SetPointNotify(PieSeriesPoint psp, bool notify) + { + if (notify == true) + { + psp.Parent = this; + psp.PropertyChanged += Sp_PropertyChanged; + } + else + { + psp.Parent = null; + psp.PropertyChanged -= Sp_PropertyChanged; + } + } + + #endregion + + #region Sp_PropertyChanged + + void Sp_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + VisualPropertyChangedEventArgs vce = e as VisualPropertyChangedEventArgs; + + if (vce != null) + { + PieSeriesPoint psp = sender as PieSeriesPoint; + + if (psp != null) + psp.NotifyVisualParent(psp, vce.ChangeType); + } + } + + #endregion + + #endregion + + #endregion + + #region PieTotal + + /// + /// Gets the sum total of the pie collection 'values' (Y[0]). + /// + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double PieTotal + { + get { return (_PieTotal); } + internal set { _PieTotal = value; } + } + + #endregion + + #region PieTotalExtent + + /// + /// Gets the sum total of the collection 'extents' (Y[1]). + /// + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double PieTotalExtent + { + get { return (_PieTotalExtent); } + internal set { _PieTotalExtent = value; } + } + + #endregion + + #region VisibleCount + + /// + /// Gets count of visible points in the collection. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int VisibleCount + { + get + { + int vcount = 0; + + foreach (PieSeriesPoint psp in Items) + { + if (psp.Visible == true) + vcount++; + } + + return (vcount); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region PieMaxExtent + + internal double PieMaxExtent + { + get { return (_PieMaxExtent); } + set { _PieMaxExtent = value; } + } + + #endregion + + #region PieMinExtent + + internal double PieMinExtent + { + get { return (_PieMinExtent); } + set { _PieMinExtent = value; } + } + + #endregion + + #region PieOuterExtent + + internal double PieOuterExtent + { + get { return (_PieOuterExtent); } + set { _PieOuterExtent = value; } + } + + #endregion + + #region PieRing + + internal PieRing PieRing + { + get { return (_PieRing); } + set { _PieRing = value; } + } + + #endregion + + #endregion + + #region ClearItems + + protected override void ClearItems() + { + if (Parent is PieSeriesPoint) + { + for (int i = Items.Count - 1; i >= 0; i--) + RemoveItem(i); + } + else + { + CheckReentrancy(); + + Items.Clear(); + + OnPropertyChanged(CountString); + OnPropertyChanged(ItemString); + + OnCollectionReset(); + } + } + + #endregion + + #region SetSelected + + internal void SetSelected(bool select) + { + foreach (PieSeriesPoint psp in Items) + { + if (psp != null) + { + psp.IsSelected = select; + + if (psp.SeriesPoints.PieSlices != null) + psp.SeriesPoints.PieSlices.SetSelected(select); + } + } + } + + #endregion + + #region States + + [Flags] + private enum States : uint + { + Other = (1 << 0), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + } + + #region SliceVisualLayout + + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class SliceVisualLayout : INotifyPropertyChanged, IProcessSerialElement, IDisposable + { + #region Private variables + + private ChartVisualElement _Parent; + + private double _AngleMargin = double.NaN; + + private int _RingWeight = -1; + + private int _MaxSlices = -1; + private int _MinExtent = -1; + private double _MinPercent = double.NaN; + + private SliceLabelOrientation _InnerLabelOrientation = SliceLabelOrientation.NotSet; + private SliceLabelCropMode _SliceLabelCropMode = SliceLabelCropMode.NotSet; + private SliceLabelVisibility _SliceLabelVisibility = SliceLabelVisibility.NotSet; + private SliceLabelDisplayMode _SliceLabelDisplayMode = SliceLabelDisplayMode.NotSet; + + private ChartSliceVisualStyles _SliceVisualStyles; + private ChartSliceVisualStyles _OtherSliceVisualStyles; + + private Tbool _ShowSliceWhiteSpace = Tbool.NotSet; + + private string _InnerSliceLabel; + private string _OuterSliceLabel; + + private double _StartAngle = double.NaN; + private double _SweepAngle = double.NaN; + private SweepDirection _SweepDirection = SweepDirection.NotSet; + + private string _ToolTipText; + + private PieRefLineDisplayMode _RefLineDisplayMode = PieRefLineDisplayMode.NotSet; + private Tbool _ReferenceLineDisplayOnTop = Tbool.NotSet; + + internal PieReferenceLineCollection _ReferenceLines; + + #endregion + + public SliceVisualLayout(ChartVisualElement parent) + { + _Parent = parent; + } + + #region Public properties + + #region AngleMargin + + /// + /// Gets or sets the margin used to offset the angle at + /// which the slice sides are rendered. This can be used to + /// create a more 'wedge' shaped slice. + /// + [Description("Indicates the margin used to offset the angle at which the slice sides are rendered. This can be used to create a more 'wedge' shaped slice.")] + [DefaultValue(double.NaN)] + [Editor("DevComponents.Charts.Design.AngleMarginRangeValueEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double AngleMargin + { + get { return (_AngleMargin); } + + set + { + if (value != _AngleMargin) + { + _AngleMargin = value; + + OnPropertyChangedEx("AngleMargin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region InnerLabelOrientation + + /// + /// Gets or sets the inner label orientation with respect to the slice. + /// + [Category("Behavior"), DefaultValue(SliceLabelOrientation.NotSet)] + [Description("Indicates the inner label orientation with respect to the slice.")] + public SliceLabelOrientation InnerLabelOrientation + { + get { return (_InnerLabelOrientation); } + + set + { + if (value != _InnerLabelOrientation) + { + _InnerLabelOrientation = value; + + OnPropertyChangedEx("InnerLabelOrientation", VisualChangeType.Layout); + } + } + } + + #endregion + + #region InnerSliceLabel + + /// + /// Gets or sets the inner slice label for the pie slice. The label can be + /// straight text, or be comprised of text and formatting specifiers. The label + /// should be specified as (note that brackets denote optional elements): + /// "[text]{keyword[:format]}[text][{...}]". + /// + /// Here are the formatting specifiers that can be used with both inner and + /// outer labels: + /// + /// "AVG" "A" - Average (angular values). + /// "PCT" "P" - Percent of pie (angular values) - (.025 yields "2.5 %"). + /// "TOT" "T" - Total of all values (angluar values). + /// "VAL" "V" - Value percent of pie (angular value) - (.025 yields ".025"). + /// + /// "AVGX" "AX" - Average (extent/radial values). + /// "PCTX" "PX" - Percent of pie (extent values) - (.025 yields "2.5 %"). + /// "TOTX" "TX" - Total of all values (extent values). + /// "VALX" "VX" - Value percent of pie (extent value) - (.025 yields ".025"). + /// + /// "S" "SNAME" - Series name. + /// "X" - ValueX. + /// "Y", "Y0", "Yn" - ValueY values (where 'n' is index value). + /// + /// Example use: + /// + /// "{S}\\n{X:yyyy} ({Y:##,##0} - {P:Y1})" + /// "Individual cost {Y:C} and average cost {AVG:C} of goods." + /// + /// + [DefaultValue(null), Category("Label")] + [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))] + [Description("Indicates the inner slice label for the pie slices (format specifiers {Keyword[:Format]} - " + + "S, X, Y, Y0-Yn, N, [A|AVG][X], [A|PCT][X], [A|TOT][X], [A|VAL][X]. e.g. \"{x:f2},{avg:##.##},{totx:c}\"")] + public string InnerSliceLabel + { + get { return (_InnerSliceLabel); } + + set + { + if (String.Equals(value, _InnerSliceLabel) == false) + { + _InnerSliceLabel = value; + + OnPropertyChangedEx("InnerSliceLabel", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxSlices + + /// + /// Gets or sets the maximum number of slices to represent in the pie. Any remaining values + /// are consolidated into the 'Other' slice, if shown, or are not displayed at all. + /// + /// The slices are counted in the order in which they are displayed. This order is + /// affected by the ReverseSlices property. + /// + [DefaultValue(-1), Category("Display")] + [Description("Indicates the maximum number of slices to represent in the pie. Any remaining values are consolidated into the 'Other' slice, if shown, or are not displayed at all.")] + public int MaxSlices + { + get { return (_MaxSlices); } + + set + { + if (value != _MaxSlices) + { + _MaxSlices = value; + + OnPropertyChangedEx("MaxSlices", VisualChangeType.Recalc); + } + } + } + + #endregion + + #region MinExtent + + /// + /// Gets or sets the minimum extent for the collection. + /// + [DefaultValue(-1), Category("Display")] + [Description("Indicates the minimum extent for the collection.")] + public int MinExtent + { + get { return (_MinExtent); } + + set + { + if (value != _MinExtent) + { + _MinExtent = value; + + OnPropertyChangedEx("MinExtent", Style.VisualChangeType.Recalc); + } + } + } + + #endregion + + #region MinPercent + + /// + /// Gets or sets the minimum percent-of-total represented in individual slices. + /// Values less than the MinPercent are either accumulated into the 'Other' slice, if shown, + /// or left in the main pie display. + /// Range is 0–1. + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the minimum percent-of-total represented in individual slices. Values less than the MinPercent are accumulated into the 'Other' slice. Range is 0–1.")] + public double MinPercent + { + get { return (_MinPercent); } + + set + { + if (value != _MinPercent) + { + _MinPercent = value; + + OnPropertyChangedEx("MinPercent", VisualChangeType.Recalc); + } + } + } + + #endregion + + #region OtherSliceVisualStyles + + /// + /// Gets or sets the default visual style for the series 'Other' slice. + /// + [Category("Style")] + [Description("Indicates the default visual style for the series 'Other' slice.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSliceVisualStyles OtherSliceVisualStyles + { + get + { + if (_OtherSliceVisualStyles == null) + { + _OtherSliceVisualStyles = new ChartSliceVisualStyles(); + + StyleChangeHandler(null, _OtherSliceVisualStyles); + } + + return (_OtherSliceVisualStyles); + } + + set + { + if (_OtherSliceVisualStyles != value) + { + ChartSliceVisualStyles oldValue = _OtherSliceVisualStyles; + + _OtherSliceVisualStyles = value; + + OnStyleChanged("OtherSliceVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region OuterSliceLabel + + /// + /// Gets or sets the outer slice label for the pie slice. See InnerSliceLabel for + /// further notes on Format Specifiers. + /// + [DefaultValue(null), Category("Label")] + [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))] + [Description("Indicates the inner slice label for the pie slices. See InnerSliceLabel for further notes on Format Specifiers.")] + public string OuterSliceLabel + { + get { return (_OuterSliceLabel); } + + set + { + if (String.Equals(value, _OuterSliceLabel) == false) + { + _OuterSliceLabel = value; + + OnPropertyChangedEx("OuterSliceLabel", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Parent + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartVisualElement Parent + { + get { return (_Parent); } + + internal set + { + _Parent = value; + + UpdateRelations(); + } + } + + #region UpdateRelations + + private void UpdateRelations() + { + foreach (PieReferenceLine line in ReferenceLines) + line.Parent = _Parent; + } + + #endregion + + #endregion + + #region ReferenceLineDisplayMode + + /// + /// Gets or sets the type of pie reference lines to display. + /// + [Category("Appearance"), DefaultValue(PieRefLineDisplayMode.NotSet)] + [Description("Indicates the type of pie reference lines to display.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public PieRefLineDisplayMode ReferenceLineDisplayMode + { + get { return (_RefLineDisplayMode); } + + set + { + if (value != _RefLineDisplayMode) + { + _RefLineDisplayMode = value; + + OnPropertyChangedEx("ReferenceLineDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ReferenceLineDisplayOnTop + + /// + /// Gets or sets whether references lines are displayed on top of chart data. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether the reference lines are displayed on top of chart data.")] + public Tbool ReferenceLineDisplayOnTop + { + get { return (_ReferenceLineDisplayOnTop); } + + set + { + if (value != _ReferenceLineDisplayOnTop) + { + _ReferenceLineDisplayOnTop = value; + + OnPropertyChangedEx("ReferenceLineDisplayOnTop", VisualChangeType.Render); + } + } + } + + #endregion + + #region ReferenceLines + + /// + /// Gets a reference to the collection of user defined Reference Lines. + /// + [Category("Appearance")] + [Description("Indicates the collection of user defined Reference Lines.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieReferenceLineCollection ReferenceLines + { + get + { + if (_ReferenceLines == null) + { + _ReferenceLines = new PieReferenceLineCollection(); + + _ReferenceLines.CollectionChanged += ReferenceLineCollectionChanged; + } + + return (_ReferenceLines); + } + + internal set + { + if (_ReferenceLines != null) + _ReferenceLines.CollectionChanged -= ReferenceLineCollectionChanged; + + _ReferenceLines = value; + + if (_ReferenceLines != null) + _ReferenceLines.CollectionChanged += ReferenceLineCollectionChanged; + } + } + + #region ReferenceLineCollectionChanged + + void ReferenceLineCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (ChartElement item in e.NewItems) + { + item.Parent = Parent; + item.PropertyChanged += Item_PropertyChanged; + } + break; + + case NotifyCollectionChangedAction.Replace: + foreach (ChartElement item in e.OldItems) + { + item.Parent = null; + item.PropertyChanged -= Item_PropertyChanged; + } + + foreach (ChartElement item in e.NewItems) + { + item.Parent = Parent; + item.PropertyChanged += Item_PropertyChanged; + } + break; + + case NotifyCollectionChangedAction.Remove: + foreach (ChartElement item in e.OldItems) + { + item.Parent = null; + item.PropertyChanged -= Item_PropertyChanged; + } + break; + } + + OnPropertyChangedEx("ReferenceLines", VisualChangeType.Render); + } + + void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #endregion + + #region RingWeight + + /// + /// Gets or sets the 'relative' thickness of the associated pie ring, as + /// compared to the relative thickness of other series rings + /// rings. + /// + [DefaultValue(-1), Category("Layout")] + [Description("Indicates the 'relative' thickness of the associated pie ring, as compared to the relative thickness of other series rings. Default is 100.")] + public int RingWeight + { + get { return (_RingWeight); } + + set + { + if (value != _RingWeight) + { + _RingWeight = value; + + OnPropertyChangedEx("RingWeight", Style.VisualChangeType.Recalc); + } + } + } + + #endregion + + #region ShowSliceWhiteSpace + + /// + /// Gets or sets whether to display, by default, the full + /// slice (includes potential area beyond slice extent). Default is false. + /// + [DefaultValue(Tbool.NotSet), Category("Display")] + [Description("Indicates whether to display, by default the full slice (includes potential area beyond slice extent). Default is false.")] + public Tbool ShowSliceWhiteSpace + { + get { return (_ShowSliceWhiteSpace); } + + set + { + if (value != _ShowSliceWhiteSpace) + { + _ShowSliceWhiteSpace = value; + + OnPropertyChangedEx("ShowSliceWhiteSpace", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SliceLabelCropMode + + /// + /// Gets or sets the label display mode (ie. the action taken + /// when a label needs be clipped for full display). Default is Clip. + /// + [DefaultValue(SliceLabelCropMode.NotSet), Category("Label")] + [Description("Indicates the label display mode (ie. the action taken when a label needs clipped for full display). Default is Clip.")] + public SliceLabelCropMode SliceLabelCropMode + { + get { return (_SliceLabelCropMode); } + + set + { + if (value != _SliceLabelCropMode) + { + _SliceLabelCropMode = value; + + OnPropertyChangedEx("SliceLabelCropMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SliceLabelVisibility + + /// + /// Gets or sets when the slice labels are visibly displayed. + /// + [DefaultValue(SliceLabelVisibility.NotSet), Category("Label")] + [Description("Indicates when the slice labels are visibly displayed.")] + public SliceLabelVisibility SliceLabelVisibility + { + get { return (_SliceLabelVisibility); } + + set + { + if (value != _SliceLabelVisibility) + { + _SliceLabelVisibility = value; + + OnPropertyChangedEx("SliceLabelVisibility", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SliceLabelDisplayMode + + /// + /// Gets or sets the label display mode, which determines + /// which slice labels (inner/outer) are displayed. Default is InnerAndOuter. + /// + [DefaultValue(SliceLabelDisplayMode.NotSet), Category("Label")] + [Description("Indicates the label display mode, which determines which slice labels (inner/outer) are displayed. Default is InnerAndOuter.")] + public SliceLabelDisplayMode SliceLabelDisplayMode + { + get { return (_SliceLabelDisplayMode); } + + set + { + if (value != _SliceLabelDisplayMode) + { + _SliceLabelDisplayMode = value; + + OnPropertyChangedEx("SliceLabelDisplayMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SliceVisualStyles + + /// + /// Gets or sets the visual styles for the slice. + /// + [Category("Style")] + [Description("Indicates the visual styles for the slice.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSliceVisualStyles SliceVisualStyles + { + get + { + if (_SliceVisualStyles == null) + { + _SliceVisualStyles = new ChartSliceVisualStyles(); + + StyleChangeHandler(null, _SliceVisualStyles); + } + + return (_SliceVisualStyles); + } + + set + { + if (_SliceVisualStyles != value) + { + ChartSliceVisualStyles oldValue = _SliceVisualStyles; + + _SliceVisualStyles = value; + + OnStyleChanged("SliceVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region StartAngle + + /// + /// Gets or sets the start angle of the pie in degrees where 0 is right and 270 is top. + /// Defaults to 270. + /// + [DefaultValue(double.NaN), Category("Layout")] + [Description("Indicates the start angle of the pie in degrees where 0 is right and 270 is top. Defaults to 270.")] + [Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double StartAngle + { + get { return (_StartAngle); } + + set + { + if (value != _StartAngle) + { + _StartAngle = value; + + OnPropertyChangedEx("StartAngle", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SweepAngle + + /// + /// Gets or sets the sweep angle (distance from StartAngle to the + /// ending angle) of the pie in positive degrees (use SweepDirection + /// to change rotational direction). + /// + [DefaultValue(double.NaN), Category("Layout")] + [Description("Indicates the sweep angle (distance from StartAngle to the ending angle) of the pie in positive degrees (use SweepDirection to change rotational direction).")] + [Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double SweepAngle + { + get { return (_SweepAngle); } + + set + { + if (value != _SweepAngle) + { + if (value < 0) + throw new Exception("SweepAngle cannot be negative (See SweepDirection)."); + + _SweepAngle = value; + + OnPropertyChangedEx("SweepAngle", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SweepDirection + + /// + /// Gets or sets the direction to display the pie slices - in either a clockwise + /// or counterclockwise direction. + /// + [DefaultValue(SweepDirection.NotSet), Category("Layout")] + [Description("Indicates the direction to display the pie slices - in either a clockwise or counterclockwise direction).")] + public SweepDirection SweepDirection + { + get { return (_SweepDirection); } + + set + { + if (value != _SweepDirection) + { + _SweepDirection = value; + + OnPropertyChangedEx("SweepDirection", VisualChangeType.Recalc); + } + } + } + + #endregion + + #region ToolTipText + + /// + /// Gets or sets the text to use for the point ToolTip. + /// + [DefaultValue(null), Category("Label")] + [Description("Indicates the text to use for the point ToolTip.")] + [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))] + public string ToolTipText + { + get { return (_ToolTipText); } + + set + { + if (value != _ToolTipText) + { + _ToolTipText = value; + + OnPropertyChanged("ToolTipText"); + } + } + } + + #endregion + + #endregion + + #region GetReferenceLineByName + + /// + /// Gets the ReferenceLine from the given name. + /// + /// + /// + public PieReferenceLine GetReferenceLineByName(string name) + { + if (String.IsNullOrEmpty(name) == true) + return (null); + + if (_ReferenceLines != null) + { + foreach (PieReferenceLine line in _ReferenceLines) + { + if (name.Equals(line.Name) == true) + return (line); + } + } + + return (null); + } + + #endregion + + #region Style support + + #region OnStyleChanged + + protected virtual void OnStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + StyleChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #endregion + + #region StyleChangeHandler + + protected void StyleChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected void StyleChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + #region OnPropertyChanged + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (PropertyChanged != null) + PropertyChanged(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType)); + } + + #endregion + + #endregion + + #endregion + + #region Copy/CopyTo + + /// + /// Creates a copy of the SeriesPointsLayout + /// + /// + public SliceVisualLayout Copy() + { + SliceVisualLayout copy = new SliceVisualLayout(null); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the item data to the given SeriesPointsLayout. + /// + /// + public void CopyTo(SliceVisualLayout c) + { + c.AngleMargin = AngleMargin; + + c.MaxSlices = MaxSlices; + c.MinExtent = MinExtent; + c.MinPercent = MinPercent; + + c.InnerLabelOrientation = _InnerLabelOrientation; + c.InnerSliceLabel = _InnerSliceLabel; + + c.OtherSliceVisualStyles = (_OtherSliceVisualStyles != null) ? _OtherSliceVisualStyles.Copy() : null; + + c.OuterSliceLabel = OuterSliceLabel; + + foreach (PieReferenceLine line in ReferenceLines) + c.ReferenceLines.Add((PieReferenceLine)line.Copy()); + + c.ReferenceLineDisplayMode = _RefLineDisplayMode; + c.ReferenceLineDisplayOnTop = _ReferenceLineDisplayOnTop; + + c.RingWeight = RingWeight; + + c.ShowSliceWhiteSpace = _ShowSliceWhiteSpace; + c.SliceLabelCropMode = _SliceLabelCropMode; + c.SliceLabelDisplayMode = _SliceLabelDisplayMode; + c.SliceLabelVisibility = _SliceLabelVisibility; + + c.SliceVisualStyles = (_SliceVisualStyles != null) ? _SliceVisualStyles.Copy() : null; + + c.StartAngle = _StartAngle; + c.SweepAngle = _SweepAngle; + c.SweepDirection = _SweepDirection; + } + + #endregion + + #region GetSerialData + + internal virtual SerialElementCollection GetSerialData() + { + return (GetSerialData(true)); + } + + internal virtual SerialElementCollection GetSerialData(bool root) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (root == true) + sec.AddStartElement("SliceVisualLayout"); + + sec.AddValue("AngleMargin", AngleMargin, double.NaN); + + sec.AddValue("MaxSlices", MaxSlices, -1); + sec.AddValue("MinExtent", MinExtent, -1); + sec.AddValue("MinPercent", MinPercent, double.NaN); + + sec.AddValue("InnerLabelOrientation", InnerLabelOrientation, SliceLabelOrientation.NotSet); + + sec.AddValue("InnerSliceLabel", InnerSliceLabel, null); + + if (_OtherSliceVisualStyles != null && _OtherSliceVisualStyles.IsEmpty == false) + sec.AddElement(_OtherSliceVisualStyles.GetSerialData("OtherSliceVisualStyles")); + + sec.AddValue("OuterSliceLabel", OuterSliceLabel, null); + + if (_ReferenceLines != null && _ReferenceLines.Count > 0) + { + sec.AddStartElement("ReferenceLines count=\"" + _ReferenceLines.Count + "\""); + + foreach (PieReferenceLine rline in _ReferenceLines) + sec.AddElement(rline.GetSerialData("")); + + sec.AddEndElement("ReferenceLines"); + } + + sec.AddValue("ReferenceLineDisplayMode", ReferenceLineDisplayMode, PieRefLineDisplayMode.NotSet); + sec.AddValue("ReferenceLineDisplayOnTop", ReferenceLineDisplayOnTop, Tbool.NotSet); + + sec.AddValue("RingWeight", RingWeight, -1); + + sec.AddValue("ShowSliceWhiteSpace", ShowSliceWhiteSpace, Tbool.NotSet); + sec.AddValue("SliceLabelCropMode", SliceLabelCropMode, SliceLabelCropMode.NotSet); + sec.AddValue("SliceLabelDisplayMode", SliceLabelDisplayMode, SliceLabelDisplayMode.NotSet); + sec.AddValue("SliceLabelVisibility", SliceLabelVisibility, SliceLabelVisibility.NotSet); + + if (_SliceVisualStyles != null && _SliceVisualStyles.IsEmpty == false) + sec.AddElement(_SliceVisualStyles.GetSerialData("SliceVisualStyles")); + + sec.AddValue("StartAngle", StartAngle, double.NaN); + sec.AddValue("SweepAngle", SweepAngle, double.NaN); + sec.AddValue("SweepDirection", SweepDirection, SweepDirection.NotSet); + + if (root == true) + sec.AddEndElement("SliceVisualLayout"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AngleMargin": + AngleMargin = double.Parse(se.StringValue); + break; + + case "InnerLabelOrientation": + InnerLabelOrientation = (SliceLabelOrientation)se.GetValueEnum(typeof(SliceLabelOrientation)); + break; + + case "InnerSliceLabel": + InnerSliceLabel = se.StringValue; + break; + + case "MaxSlices": + MaxSlices = int.Parse(se.StringValue); + break; + + case "MinExtent": + MinExtent = int.Parse(se.StringValue); + break; + + case "MinPercent": + MinPercent = double.Parse(se.StringValue); + break; + + case "OuterSliceLabel": + OuterSliceLabel = se.StringValue; + break; + + case "ReferenceLineDisplayMode": + ReferenceLineDisplayMode = (PieRefLineDisplayMode)se.GetValueEnum(typeof(PieRefLineDisplayMode)); + break; + + case "ReferenceLineDisplayOnTop": + ReferenceLineDisplayOnTop = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "RingWeight": + RingWeight = int.Parse(se.StringValue); + break; + + case "ShowSliceWhiteSpace": + ShowSliceWhiteSpace = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "SliceLabelCropMode": + SliceLabelCropMode = (SliceLabelCropMode)se.GetValueEnum(typeof(SliceLabelCropMode)); + break; + + case "SliceLabelDisplayMode": + SliceLabelDisplayMode = (SliceLabelDisplayMode)se.GetValueEnum(typeof(SliceLabelDisplayMode)); + break; + + case "SliceLabelVisibility": + SliceLabelVisibility = (SliceLabelVisibility)se.GetValueEnum(typeof(SliceLabelVisibility)); + break; + + case "StartAngle": + StartAngle = double.Parse(se.StringValue); + break; + + case "SweepAngle": + SweepAngle = double.Parse(se.StringValue); + break; + + case "SweepDirection": + SweepDirection = (SweepDirection)se.GetValueEnum(typeof(SweepDirection)); + break; + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "OtherSliceVisualStyles": + sec.PutSerialData(OtherSliceVisualStyles); + break; + + case "ReferenceLine": + PieReferenceLine line = GetReferenceLineByName(se.Name); + + if (line != null) + sec.PutSerialData(line); + break; + + case "ReferenceLines": + sec.PutSerialData(this); + break; + + case "SliceVisualStyles": + sec.PutSerialData(SliceVisualStyles); + break; + } + } + + #endregion + + #endregion + + #region IDispose + + public virtual void Dispose() + { + ReferenceLines = null; + OtherSliceVisualStyles = null; + SliceVisualStyles = null; + + Parent = null; + } + + #endregion + } + + #region ISeriesPointContainer + + public interface ISeriesPointContainer + { + SliceVisualLayout SubSliceVisualLayout { get; set; } + } + + #endregion + + #endregion + + #region PieSeriesPoint + + [DesignTimeVisible(false), ToolboxItem(false)] + public class PieSeriesPoint : SeriesPoint, + IEffectiveStyle, INotifyPropertyChanged, ILegendItem, ILegendItemEx, ISeriesPointContainer, INamed + { + #region Private variables + + private object _Parent; + + private int _OrdinalValue; + + private ChartControl _ChartControl; + private int _LocalUpdateCount; + + private string _InnerSliceLabel; + private string _OuterSliceLabel; + + private double _DetachedOffset = double.NaN; + + private double _StartAngle = double.NaN; + private double _SweepAngle = double.NaN; + + private double _AngleMarginExx; + + private double _StartAngleEx; + private double _SweepAngleEx; + + private Point _SliceCenter; + private double _SliceExtent; + private double _SliceValue; + + private int _InnerRadius; + private int _OuterRadius; + + private Rectangle _PathBounds; + private Rectangle _LastPathBounds; + + private PieRing _PieRing; + + private PieSeriesPoint _RootPsp; + + private ChartSliceVisualStyles _SliceVisualStyles; + private EffectiveStyles _EffectiveSliceStyles; + private ChartSliceVisualStyle _LastEffectiveStyle; + + private Color _DefaultPaletteColor = Color.Empty; + + private ushort _LayoutUpdateCount; + private Rectangle _InscribedRect; + private List _WordPosLines; + private RectangleF[] _CharBounds; + + private PieLabel _PieLabel; + + private ChartLegendItem _LegendItem; + private string _LegendText; + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + + private string _Name; + private string _ToolTipText; + + private PieSeriesPointCollection _SeriesPoints; + private SliceVisualLayout _SliceVisualLayout; + + private States _States; + + // ---- Cached items + + private double _AngleMarginEx; + + private SliceLabelCropMode _SliceLabelCropModeEx; + private SliceLabelDisplayMode _SliceLabelDisplayModeEx; + private SliceLabelOrientation _InnerLabelOrientationEx; + private SliceLabelVisibility _SliceLabelVisibilityEx; + + private string _InnerSliceLabelEx; + private string _OuterSliceLabelEx; + + private int _MaxSlicesEx; + private int _MinExtentEx; + private double _MinPercentEx; + + private int _RingWeightEx; + + private PieRefLineDisplayMode _ReferenceLineDisplayModeEx; + private List _ReferenceLinesEx; + + private string _ToolTipTextEx; + + #endregion + + #region Constructors + + public PieSeriesPoint() + : this(0, 0) + { + } + + /// + /// PieSeriesPoint + /// + /// + /// + public PieSeriesPoint(object xValue, object yValue) + : base(xValue, yValue) + { + InitDefaultStates(); + + _EffectiveSliceStyles = new EffectiveStyles(this); + } + + /// + /// PieSeriesPoint + /// + /// + /// + public PieSeriesPoint(object xValue, object[] yValue) + : base(xValue, yValue) + { + InitDefaultStates(); + + _EffectiveSliceStyles = new EffectiveStyles(this); + } + + /// + /// PieSeriesPoint + /// + /// + /// angular value + /// yValue2=radial + public PieSeriesPoint(object xValue, object yValue1, object yValue2) + : base(xValue, yValue1, yValue2) + { + InitDefaultStates(); + + _EffectiveSliceStyles = new EffectiveStyles(this); + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.AllowDetach, true); + SetState(States.AllowSelect, true); + + SetState(States.CheckedInLegend, true); + SetState(States.ShowInLegend, true); + SetState(States.ShowInParentLegend, true); + SetState(States.ShowMarkerInLegend, true); + } + + #endregion + + #region Public properties + + #region ActualStartAngle + + /// + /// Gets the actual, calculated starting angle for the slice. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double ActualStartAngle + { + get { return (StartAngleEx); } + } + + #endregion + + #region ActualSweepAngle + + /// + /// Gets the actual, calculated sweep angle for the slice. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double ActualSweepAngle + { + get { return (SweepAngleEx); } + } + + #endregion + + #region AllowDetach + + /// + /// Gets or sets whether the element can be 'detached' from + /// the center of the pie by the user. Defaults to true. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the element can be 'detached' from the center of the pie by the user. Defaults to true.")] + public bool AllowDetach + { + get { return (TestState(States.AllowDetach)); } + + set + { + if (value != AllowDetach) + { + SetState(States.AllowDetach, value); + + OnPropertyChanged("AllowDetach"); + } + } + } + + #endregion + + #region AllowSelect + + /// + /// Gets or sets whether the element can be selected by clicking on it. Defaults to true. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the element can be selected by clicking on it. Defaults to true.")] + public bool AllowSelect + { + get { return (TestState(States.AllowSelect)); } + + set + { + if (value != AllowSelect) + { + SetState(States.AllowSelect, value); + + OnPropertyChanged("AllowSliceSelect"); + } + } + } + + #endregion + + #region CenterAngle + + /// + /// Gets the Center Angle for the slice. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double CenterAngle + { + get { return ((StartAngleEx + SweepAngleEx / 2) + 360000) % 360; } + } + + #endregion + + #region ChartSeries + + /// + /// Gets the associated ChartSeries. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public PieSeries ChartSeries + { + get { return (_PieRing != null ? _PieRing.ChartSeries : null); } + } + + #endregion + + #region DefaultPaletteColor + + /// + /// Gets the default palette color assigned to the point when it + /// is arranged in the pie. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the default palette color assigned to the point when it is arranged in the pie.")] + public Color DefaultPaletteColor + { + get { return (_DefaultPaletteColor); } + + internal set + { + if (value != _DefaultPaletteColor) + { + _DefaultPaletteColor = value; + + ClearEffectiveStyles(); + + OnPropertyChangedEx("DetachedOffset", VisualChangeType.Render); + } + } + } + + #endregion + + #region DetachedOffset + + /// + /// Gets or sets the offset distance of the slice from the pie center, as measured + /// by a percentage of the pie radius (if between 0 and 1), or absolute pixel amount (if >= 1). + /// + [DefaultValue(double.NaN), Category("Appearance")] + [Description("Indicates the offset distance of the slice from the pie center, as measured by a percentage of the pie radius (if between 0 and 1), or absolute pixel amount (if >= 1).")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double DetachedOffset + { + get { return (_DetachedOffset); } + + set + { + if (value != _DetachedOffset) + { + _DetachedOffset = value; + + OnPropertyChangedEx("DetachedOffset", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EffectiveSliceStyles + + /// + /// Gets a reference to the Effective (cached, composite) Slice styles. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public EffectiveStyles EffectiveSliceStyles + { + get { return (_EffectiveSliceStyles); } + } + + #endregion + + #region ExtentRadius + + /// + /// Gets the actual, calculated extent radius of the slice (the + /// radius between the inner and outer radius - ValuesY[1]). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double ExtentRadius + { + get + { + int width = OuterRadius - InnerRadius; + int extendWidth = (int)(SliceExtent * width); + + return (InnerRadius + extendWidth); + } + } + + #endregion + + #region InnerRadius + + /// + /// Gets the actual, inner radius of the slice. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int InnerRadius + { + get { return (_InnerRadius); } + internal set { _InnerRadius = value; } + } + + #endregion + + #region InnerSliceLabel + + /// + /// Gets or sets the inner slice label for the pie slice. The label can be + /// straight text, or be comprised of text and formatting specifiers. The label + /// should be specified as "Some text {Keyword:Format} more text [{...:...}]". + /// + /// Here are the formatting specifiers that can be used with both inner and + /// outer labels: + /// + /// "AVG" "A" - Average (angular values). + /// "PCT" "P" - Percent of pie (angular values) - (.025 yields "2.5 %"). + /// "TOT" "T" - Total of all values (angluar values). + /// "VAL" "V" - Value percent of pie (angular value) - (.025 yields ".025"). + /// + /// "AVGX" "AX" - Average (extent/radial values). + /// "PCTX" "PX" - Percent of pie (extent values) - (.025 yields "2.5 %"). + /// "TOTX" "TX" - Total of all values (extent values). + /// "VALX" "VX" - Value percent of pie (extent value) - (.025 yields ".025"). + /// + /// "S" "SNAME" - Series name. + /// "X" - ValueX. + /// "Y", "Y0", "Yn" - ValueY values (where 'n' is index value). + /// + /// Examples: + /// + /// "{S}\\n{X:yyyy} ({Y:##,##0} - {P:Y1})" + /// "Individual cost {Y:C} and average cost {AVG:C} of goods." + /// + /// + [DefaultValue(null), Category("Label")] + [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))] + [Description("Indicates the inner slice label for the pie slices (format specifiers {Keyword[:Format]} - " + + "S, X, Y, Y0-Yn, N, [A|AVG][X], [A|PCT][X], [A|TOT][X], [A|VAL][X]. e.g. \"{x:f2},{avg:##.##},{totx:c}\"")] + public string InnerSliceLabel + { + get { return (_InnerSliceLabel); } + + set + { + if (String.Equals(value, _InnerSliceLabel) == false) + { + _InnerSliceLabel = value; + + OnPropertyChangedEx("InnerSliceLabel", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsDetached + + /// + /// Gets or sets whether the slice is 'detached' from the center of the pie. This can be + /// used to create emphasis or to highlight a slice of the pie. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the slice is 'detached' from the center of the pie.")] + public bool IsDetached + { + get { return (TestState(States.Detached)); } + + set + { + if (value != IsDetached) + { + SetState(States.Detached, value); + + OnPropertyChangedEx("IsDetached", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsDisplayed + + /// + /// Gets whether the series point is displayed + /// based upon its Visibility and Legend state. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDisplayed + { + get { return (Visible == true && IsDisplayedEx == true); } + } + + #endregion + + #region IsEmptyPoint + + /// + /// Gets or sets whether the point is an 'Empty' (or missing) Point. + /// + [DefaultValue(false), Category("Data")] + [Description("Indicates whether the point is an 'Empty' (or missing) Point.")] + public override bool IsEmptyPoint + { + get { return (base.IsEmptyPoint); } + + set + { + if (value != base.IsEmptyPoint) + { + base.IsEmptyPoint = value; + + OnPropertyChangedEx("IsEmptyPoint", VisualChangeType.Recalc); + } + } + } + + #endregion + + #region IsInOther + + /// + /// Gets whether the slice is in the 'Other' slice. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the slice is in the 'Other' slice.")] + public bool IsInOther + { + get { return (TestState(States.IsInOther)); } + + set + { + if (value != IsInOther) + { + SetState(States.IsInOther, value); + + OnPropertyChangedEx("IsInOther", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsOther + + /// + /// Gets whether the slice is the 'Other' slice. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates whether the slice is the 'Other' slice.")] + public bool IsOther + { + get { return (TestState(States.IsOther)); } + internal set { SetState(States.IsOther, value); } + } + + #endregion + + #region IsSelected + + /// + /// Gets or sets whether the slice is selected. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates whether the slice is selected.")] + public bool IsSelected + { + get { return (TestState(States.Selected)); } + + set + { + if (value != IsSelected) + { + SetState(States.Selected, value); + + OnPropertyChangedEx("IsSelected", VisualChangeType.Render); + + PieSeries series = ChartSeries; + + if (series != null) + { + PieChart pieChart = series.Parent as PieChart; + + if (pieChart != null) + pieChart.GlobalSelectionCount++; + } + } + } + } + + #endregion + + #region Name + + /// + /// Gets or sets the Name of the item. + /// + [DefaultValue(null)] + [Description("Indicates the Name of the item.")] + public virtual string Name + { + get { return (_Name); } + set { _Name = value; } + } + + #endregion + + #region OrdinalValue + + /// + /// Gets the ordial value for the point (the ordinal value when added + /// to the PieSeriesPoint Collection + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int OrdinalValue + { + get { return (_OrdinalValue); } + internal set { _OrdinalValue = value; } + } + + #endregion + + #region OuterRadius + + /// + /// Gets the actual, outer radius of the slice. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int OuterRadius + { + get { return (_OuterRadius); } + internal set { _OuterRadius = value; } + } + + #endregion + + #region OuterSliceLabel + + /// + /// Gets or sets the outer slice label for the pie slice. See InnerSliceLabel for + /// further notes on Format Specifiers. + /// + [DefaultValue(null), Category("Label")] + [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))] + [Description("Indicates the inner slice label for the pie slices. See InnerSliceLabel for further notes on Format Specifiers.")] + public string OuterSliceLabel + { + get { return (_OuterSliceLabel); } + + set + { + if (String.Equals(value, _OuterSliceLabel) == false) + { + _OuterSliceLabel = value; + + OnPropertyChangedEx("OuterSliceLabel", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Parent + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the item Parent.")] + public object Parent + { + get { return (_Parent); } + + internal set + { + _Parent = value; + + _RootPsp = null; + + if (value != null) + { + PieSeriesPointCollection psp = value as PieSeriesPointCollection; + + if (psp != null) + SubSliceVisualLayout.Parent = psp.Parent as ChartVisualElement; + } + } + } + + #endregion + + #region PieRing + + /// + /// Gets the items associated PieRing (if applicable). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public PieRing PieRing + { + get { return (_PieRing); } + internal set { _PieRing = value; } + } + + #endregion + + #region SeriesPoints + + /// + /// Gets the nested series point data collection. + /// + [Category("Data")] + [Description("Indicates the nested series point data collection.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieSeriesPointCollection SeriesPoints + { + get + { + if (_SeriesPoints == null) + SeriesPoints = new PieSeriesPointCollection(); + + return (_SeriesPoints); + } + + set + { + if (value != _SeriesPoints) + { + if (_SeriesPoints != null) + { + _SeriesPoints.Parent = null; + + _SeriesPoints.CollectionChanged -= SeriesPoints_CollectionChanged; + } + + _SeriesPoints = value; + + if (_SeriesPoints != null) + { + _SeriesPoints.Parent = this; + + _SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged; + } + + OnPropertyChangedEx("SeriesPoints", VisualChangeType.Layout); + } + } + } + + #region SeriesPoints_CollectionChanged + + void SeriesPoints_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + SetSpcNotify(e.OldItems, false); + SetSpcNotify(e.NewItems, true); + + OnPropertyChangedEx("SeriesPoints", Style.VisualChangeType.Layout); + } + + #region SetPointNotify + + private void SetSpcNotify(IList list, bool notify) + { + if (list != null) + { + foreach (PieSeriesPoint psp in list) + { + if (psp != null) + { + if (notify == true) + { + psp.Parent = SeriesPoints; + psp.PropertyChanged += Spc_PropertyChanged; + } + else + { + psp.Parent = null; + psp.PropertyChanged -= Spc_PropertyChanged; + } + } + } + } + } + + #endregion + + #region Spc_PropertyChanged + + void Spc_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e is VisualPropertyChangedEventArgs) + OnPropertyChanged(e); + } + + #endregion + + #endregion + + #endregion + + #region SliceCenter + + /// + /// Gets the slice center origin point. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Point SliceCenter + { + get { return (_SliceCenter); } + internal set { _SliceCenter = value; } + } + + #endregion + + #region SliceExtent + + /// + /// Gets the calculated slice extent value (the relative + /// percent-of-total ValuesY[1] value for the slice). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double SliceExtent + { + get { return (_SliceExtent); } + internal set { _SliceExtent = value; } + } + + #endregion + + #region SliceValue + + /// + /// Gets the calculated slice value (the relative + /// percent-of-total ValuesY[0] value for the slice). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public double SliceValue + { + get { return (_SliceValue); } + internal set { _SliceValue = value; } + } + + #endregion + + #region SliceVisualStyles + + /// + /// Gets or sets the visual styles for the slice. + /// + [Category("Style")] + [Description("Indicates the visual styles for the slice.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSliceVisualStyles SliceVisualStyles + { + get + { + if (_SliceVisualStyles == null) + { + _SliceVisualStyles = new ChartSliceVisualStyles(); + + StyleChangeHandler(null, _SliceVisualStyles); + } + + return (_SliceVisualStyles); + } + + set + { + if (_SliceVisualStyles != value) + { + ChartSliceVisualStyles oldValue = _SliceVisualStyles; + + _SliceVisualStyles = value; + + OnStyleChanged("SliceVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region StartAngle + + /// + /// Gets or sets the starting angle of the slice. For subsequent slices, + /// the default is the ending angle of the previous slice. Specify a value + /// for the StartAngle if you want the next slice to start at an angle that + /// is different from the previous ending angle. + /// + [DefaultValue(double.NaN), Category("Layout")] + [Description("Indicates the starting angle of the slice. For subsequent slices, the default is the ending angle of the previous slice. Specify a value for the StartAngle if you want the next slice to start at an angle that is different from the previous ending angle.")] + [Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double StartAngle + { + get { return (_StartAngle); } + + set + { + if (value != _StartAngle) + { + _StartAngle = value; + + OnPropertyChangedEx("StartAngle", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region SubSliceVisualLayout + + /// + /// Gets or sets the layout of the subordinate (or nested) slices. + /// + [Category("Layout")] + [Description("Indicates the layout of the subordinate (or nested) slices.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SliceVisualLayout SubSliceVisualLayout + { + get + { + if (_SliceVisualLayout == null) + SubSliceVisualLayout = new SliceVisualLayout(null); + + return (_SliceVisualLayout); + } + set + { + if (value != _SliceVisualLayout) + { + if (_SliceVisualLayout != null) + _SliceVisualLayout.PropertyChanged -= SliceVisualLayout_PropertyChanged; + + _SliceVisualLayout = value; + + if (_SliceVisualLayout != null) + { + _SliceVisualLayout.SliceVisualStyles.Default.Tag = "PSP_Def"; + _SliceVisualLayout.SliceVisualStyles.MouseOver.Tag = "PSP_Mov"; + _SliceVisualLayout.SliceVisualStyles.Selected.Tag = "PSP_Sel"; + _SliceVisualLayout.SliceVisualStyles.SelectedMouseOver.Tag = "PSP_Smo"; + + _SliceVisualLayout.PropertyChanged += SliceVisualLayout_PropertyChanged; + } + + OnPropertyChangedEx("SubSliceVisualLayout", VisualChangeType.Recalc); + } + } + } + + #region SliceVisualLayout_PropertyChanged + + void SliceVisualLayout_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e is VisualPropertyChangedEventArgs) + OnPropertyChanged(e); + } + + #endregion + + #endregion + + #region SweepAngle + + /// + /// Gets or sets the sweep angle of the slice (angle size, in degrees). + /// + [DefaultValue(double.NaN), Category("Layout")] + [Description("Indicates the sweep angle of the slice (angle size, in degrees).")] + [Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double SweepAngle + { + get { return (_SweepAngle); } + + set + { + if (value != _SweepAngle) + { + if (value < 0) + throw new Exception("SweepAngle cannot be negative."); + + _SweepAngle = value; + + OnPropertyChangedEx("SweepAngle", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region ToolTipText + + /// + /// Gets or sets the text to use for the point ToolTip. + /// + [DefaultValue(null), Category("Label")] + [Description("Indicates the text to use for the point ToolTip.")] + [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))] + public string ToolTipText + { + get { return (_ToolTipText); } + + set + { + if (value != _ToolTipText) + { + _ToolTipText = value; + + OnPropertyChanged("ToolTipText"); + } + } + } + + #endregion + + #region Visible + + /// + /// Gets or sets whether the point is Visible. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the point is Visible.")] + public override bool Visible + { + get { return (base.Visible); } + + set + { + if (value != base.Visible) + { + base.Visible = value; + + OnPropertyChangedEx("Visible", VisualChangeType.Recalc); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region AngleMarginExx + + internal double AngleMarginExx + { + get { return (_AngleMarginExx); } + set { _AngleMarginExx = value; } + } + + #endregion + + #region AngleMarginEx + + internal double AngleMarginEx + { + get { UpdatePropertyCache(); return (_AngleMarginEx); } + set { _AngleMarginEx = value; } + } + + #endregion + + #region Bounds + + internal Rectangle Bounds + { + get + { + Rectangle r = new Rectangle(); + r.Location = _SliceCenter; + r.Inflate(OuterRadius, OuterRadius); + + return (r); + } + } + + #endregion + + #region CharBounds + + internal RectangleF[] CharBounds + { + get + { + VerifyLayoutUpdateCount(); + + return (_CharBounds); + } + + set { _CharBounds = value; } + } + + #endregion + + #region HasExtent + + internal bool HasExtent + { + get { return (TestState(States.HasExtent)); } + set { SetState(States.HasExtent, value); } + } + + #endregion + + #region InnerLabelClipped + + internal bool InnerLabelClipped + { + get { return (TestState(States.InnerLabelClipped)); } + set { SetState(States.InnerLabelClipped, value); } + } + + #endregion + + #region InnerLabelDisplayed + + internal bool InnerLabelDisplayed + { + get { return (TestState(States.InnerLabelDisplayed)); } + set { SetState(States.InnerLabelDisplayed, value); } + } + + #endregion + + #region InnerLabelOrientationEx + + internal SliceLabelOrientation InnerLabelOrientationEx + { + get { UpdatePropertyCache(); return (_InnerLabelOrientationEx); } + set { _InnerLabelOrientationEx = value; } + } + + #endregion + + #region InnerSliceLabelEx + + internal string InnerSliceLabelEx + { + get { UpdatePropertyCache(); return (_InnerSliceLabelEx); } + set { _InnerSliceLabelEx = value; } + } + + #endregion + + #region InscribedRect + + internal Rectangle InscribedRect + { + get + { + VerifyLayoutUpdateCount(); + + return (_InscribedRect); + } + + set + { + _InscribedRect = value; + + InscribedRectValid = true; + } + } + + #endregion + + #region InscribedRectValid + + internal bool InscribedRectValid + { + get + { + VerifyLayoutUpdateCount(); + + return (TestState(States.InscribedRectValid)); + } + + set + { + SetState(States.InscribedRectValid, value); + + if (value == false) + _InscribedRect = Rectangle.Empty; + } + } + + #endregion + + #region IsDisplayable + + internal bool IsDisplayable + { + get + { + if (Visible == false || IsEmpty == true) + return (false); + + if (IsInOtherEx == false) + { + object item = Parent; + + while (item != null) + { + if (item is PieSeriesPointCollection) + { + if (((PieSeriesPointCollection)item).IsOther == true) + { + IsInOtherEx = true; + break; + } + + item = ((PieSeriesPointCollection)item).Parent; + } + else if (item is PieSeriesPoint) + { + if (((PieSeriesPoint)item).IsInOtherEx == true) + { + IsInOtherEx = true; + break; + } + + item = ((PieSeriesPoint)item).Parent; + } + else + { + break; + } + } + } + + return (IsInOtherEx == false); + } + } + + #endregion + + #region IsDisplayedEx + + internal bool IsDisplayedEx + { + get + { + if (Visible == true) + { + if (ChartSeries != null) + { + PieChart pieChart = ChartSeries.Parent as PieChart; + + if (pieChart != null) + { + ItemCheckAction ica = (pieChart != null) + ? pieChart.Legend.ItemCheckAction : ItemCheckAction.ShowItem; + + return ((ica == ItemCheckAction.None || + (ShowCheckBoxInLegend == false || CheckedInLegend == true))); + } + } + } + + return (false); + } + } + + #endregion + + #region IsInOtherEx + + internal bool IsInOtherEx + { + get { return (TestState(States.IsInOtherEx)); } + set { SetState(States.IsInOtherEx, value); } + } + + #endregion + + #region IsOffset + + internal bool IsOffset + { + get { return (TestState(States.IsOffset)); } + set { SetState(States.IsOffset, value); } + } + + #endregion + + #region IsEnabled + + internal bool IsEnabled + { + get + { + PieRing pieRing = PieRing; + + if (pieRing != null) + { + if (pieRing.IsEnabled == true) + return (pieRing.IsDisplayed); + } + + return (false); + } + } + + #endregion + + #region LastPathBounds + + internal Rectangle LastPathBounds + { + get { return (_LastPathBounds); } + set { _LastPathBounds = value; } + } + + #endregion + + #region MaxSlicesEx + + internal int MaxSlicesEx + { + get { UpdatePropertyCache(); return (_MaxSlicesEx); } + set { _MaxSlicesEx = value; } + } + + #endregion + + #region MinExtentEx + + internal int MinExtentEx + { + get { UpdatePropertyCache(); return (_MinExtentEx); } + set { _MinExtentEx = value; } + } + + #endregion + + #region MinPercentEx + + internal double MinPercentEx + { + get { UpdatePropertyCache(); return (_MinPercentEx); } + set { _MinPercentEx = value; } + } + + #endregion + + #region OuterSliceLabelEx + + internal string OuterSliceLabelEx + { + get { UpdatePropertyCache(); return (_OuterSliceLabelEx); } + set { _OuterSliceLabelEx = value; } + } + + #endregion + + #region PathBounds + + internal Rectangle PathBounds + { + get { return (_PathBounds); } + set { _PathBounds = value; } + } + + #endregion + + #region PieLabel + + internal PieLabel PieLabel + { + get { return (_PieLabel); } + set { _PieLabel = value; } + } + + #endregion + + #region ReferenceLineDisplayModeEx + + internal PieRefLineDisplayMode ReferenceLineDisplayModeEx + { + get { UpdatePropertyCache(); return (_ReferenceLineDisplayModeEx); } + set { _ReferenceLineDisplayModeEx = value; } + } + + #endregion + + #region ReferenceLineDisplayOnTopEx + + internal bool ReferenceLineDisplayOnTopEx + { + get + { + UpdatePropertyCache(); + + return (TestState(States.ReferenceLineDisplayOnTop)); + } + + set { SetState(States.ReferenceLineDisplayOnTop, value); } + } + + #endregion + + #region ReferenceLinesEx + + internal List ReferenceLinesEx + { + get { UpdatePropertyCache(); return (_ReferenceLinesEx); } + set { _ReferenceLinesEx = value; } + } + + #endregion + + #region RenderCount + + private int _RenderCount; + + internal int RenderCount + { + get { return (_RenderCount); } + set { _RenderCount = value; } + } + + #endregion + + #region RingWeightEx + + internal int RingWeightEx + { + get { UpdatePropertyCache(); return (_RingWeightEx); } + set { _RingWeightEx = value; } + } + + #endregion + + #region RootPsp + + internal PieSeriesPoint RootPsp + { + get + { + if (_RootPsp == null) + _RootPsp = GetRootPsp(); + + return (_RootPsp); + } + } + + #region GetRootPsp + + private PieSeriesPoint GetRootPsp() + { + if (PieRing.RingLevel > 0) + { + PieSeriesPointCollection spc = Parent as PieSeriesPointCollection; + + if (spc != null) + { + PieSeriesPoint psp = spc.Parent as PieSeriesPoint; + + if (psp != null) + return (psp.RootPsp); + } + } + + return (this); + } + + #endregion + + #endregion + + #region ShowSliceWhiteSpaceEx + + internal bool ShowSliceWhiteSpaceEx + { + get + { + UpdatePropertyCache(); + + return (TestState(States.ShowSliceWhiteSpaceEx)); + } + + set { SetState(States.ShowSliceWhiteSpaceEx, value); } + } + + #endregion + + #region SliceLabelCropModeEx + + internal SliceLabelCropMode SliceLabelCropModeEx + { + get { UpdatePropertyCache(); return (_SliceLabelCropModeEx); } + set { _SliceLabelCropModeEx = value; } + } + + #endregion + + #region SliceLabelDisplayModeEx + + internal SliceLabelDisplayMode SliceLabelDisplayModeEx + { + get { UpdatePropertyCache(); return (_SliceLabelDisplayModeEx); } + set { _SliceLabelDisplayModeEx = value; } + } + + #endregion + + #region SliceLabelVisibilityEx + + internal SliceLabelVisibility SliceLabelVisibilityEx + { + get { UpdatePropertyCache(); return (_SliceLabelVisibilityEx); } + set { _SliceLabelVisibilityEx = value; } + } + + #endregion + + #region StartAngleEx + + internal double StartAngleEx + { + get { return (_StartAngleEx); } + set { _StartAngleEx = value; } + } + + #endregion + + #region SweepAngleEx + + internal double SweepAngleEx + { + get { return (_SweepAngleEx); } + set { _SweepAngleEx = value; } + } + + #endregion + + #region ToolTipTextEx + + internal string ToolTipTextEx + { + get { UpdatePropertyCache(); return (_ToolTipTextEx); } + set { _ToolTipTextEx = value; } + } + + #endregion + + #region WordPosLines + + internal List WordPosLines + { + get + { + VerifyLayoutUpdateCount(); + + return (_WordPosLines); + } + + set { _WordPosLines = value; } + } + + #endregion + + #endregion + + #region VerifyLayoutUpdateCount + + private void VerifyLayoutUpdateCount() + { + PieSeries series = ChartSeries; + + if (series != null) + { + ChartControl chartControl = series.ChartControl; + + if (chartControl != null) + { + if (_LayoutUpdateCount != chartControl.LayoutUpdateCount) + { + _WordPosLines = null; + + InscribedRectValid = false; + + _LayoutUpdateCount = chartControl.LayoutUpdateCount; + } + } + } + } + + #endregion + + #region UpdatePropertyCache + + private void UpdatePropertyCache() + { + if (ChartControl != null) + { + if (_LocalUpdateCount != ChartControl.GlobalUpdateCount) + { + PieSeriesPointCollection spc = Parent as PieSeriesPointCollection; + + if (spc != null) + { + PieSeries pieSeries = this.ChartSeries; + PieChart pieChart = pieSeries.Parent as PieChart; + + _AngleMarginEx = GetAngleMarginEx(pieChart, pieSeries, spc.Parent); + _InnerLabelOrientationEx = GetSliceLabelOrientationEx(pieChart, pieSeries, spc.Parent); + _InnerSliceLabelEx = GetInnerSliceLabelEx(pieChart, pieSeries, spc.Parent); + _MaxSlicesEx = GetMaxSlicesEx(pieChart, pieSeries, spc.Parent); + _MinExtentEx = GetMinExtentEx(pieChart, pieSeries, spc.Parent); + _MinPercentEx = GetMinPercentEx(pieChart, pieSeries, spc.Parent); + _OuterSliceLabelEx = GetOuterSliceLabelEx(pieChart, pieSeries, spc.Parent); + _ReferenceLineDisplayModeEx = GetReferenceLineDisplayModeEx(pieChart, pieSeries, spc.Parent); + _ReferenceLinesEx = GetReferenceLinesEx(pieChart, pieSeries, spc.Parent); + _RingWeightEx = GetRingWeightEx(pieChart, pieSeries, spc.Parent); + + SetState(States.ReferenceLineDisplayOnTop, GetReferenceLineDisplayOnTopEx(pieChart, pieSeries, spc.Parent)); + SetState(States.ShowSliceWhiteSpaceEx, GetShowSliceWhiteSpaceEx(pieChart, pieSeries, spc.Parent)); + + _SliceLabelCropModeEx = GetSliceLabelCropModeEx(pieChart, pieSeries, spc.Parent); + _SliceLabelDisplayModeEx = GetSliceLabelDisplayModeEx(pieChart, pieSeries, spc.Parent); + _SliceLabelVisibilityEx = GetSliceLabelVisibilityEx(pieChart, pieSeries, spc.Parent); + + _ToolTipTextEx = GetToolTipTextEx(pieChart, pieSeries, spc.Parent); + } + + _LocalUpdateCount = ChartControl.GlobalUpdateCount; + } + } + } + + #region GetAngleMarginEx + + private double GetAngleMarginEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (double.IsNaN(psp.SubSliceVisualLayout.AngleMargin) == false) + return (psp.SubSliceVisualLayout.AngleMargin); + + psp = GetParentPsp(psp); + } + + if (double.IsNaN(pieSeries.SubSliceVisualLayout.AngleMargin) == false) + return (pieSeries.SubSliceVisualLayout.AngleMargin); + + if (double.IsNaN(pieChart.SubSliceVisualLayout.AngleMargin) == false) + return (pieChart.SubSliceVisualLayout.AngleMargin); + + return (0); + } + + #endregion + + #region GetInnerSliceLabelEx + + private string GetInnerSliceLabelEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + CharBounds = null; + + if (InnerSliceLabel != null) + return (InnerSliceLabel); + + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.InnerSliceLabel != null) + return (psp.SubSliceVisualLayout.InnerSliceLabel); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.InnerSliceLabel != null) + return (pieSeries.SubSliceVisualLayout.InnerSliceLabel); + + if (pieChart.SubSliceVisualLayout.InnerSliceLabel != null) + return (pieChart.SubSliceVisualLayout.InnerSliceLabel); + + return ("{X}"); + } + + #endregion + + #region GetMaxSlicesEx + + private int GetMaxSlicesEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.MaxSlices >= 0) + return (psp.SubSliceVisualLayout.MaxSlices); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.MaxSlices >= 0) + return (pieSeries.SubSliceVisualLayout.MaxSlices); + + if (pieChart.SubSliceVisualLayout.MaxSlices >= 0) + return (pieChart.SubSliceVisualLayout.MaxSlices); + + return (100); + } + + #endregion + + #region GetMinExtentEx + + private int GetMinExtentEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.MinExtent >= 0) + return (psp.SubSliceVisualLayout.MinExtent); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.MinExtent >= 0) + return (pieSeries.SubSliceVisualLayout.MinExtent); + + if (pieChart.SubSliceVisualLayout.MinExtent >= 0) + return (pieChart.SubSliceVisualLayout.MinExtent); + + return (0); + } + + #endregion + + #region GetMinPercentEx + + private double GetMinPercentEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (double.IsNaN(psp.SubSliceVisualLayout.MinPercent) == false) + return (psp.SubSliceVisualLayout.MinPercent); + + psp = GetParentPsp(psp); + } + + if (double.IsNaN(pieSeries.SubSliceVisualLayout.MinPercent) == false) + return (pieSeries.SubSliceVisualLayout.MinPercent); + + if (double.IsNaN(pieChart.SubSliceVisualLayout.MinPercent) == false) + return (pieChart.SubSliceVisualLayout.MinPercent); + + return (.04d); + } + + #endregion + + #region GetOuterSliceLabelEx + + private string GetOuterSliceLabelEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + if (OuterSliceLabel != null) + return (OuterSliceLabel); + + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.OuterSliceLabel != null) + return (psp.SubSliceVisualLayout.OuterSliceLabel); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.OuterSliceLabel != null) + return (pieSeries.SubSliceVisualLayout.OuterSliceLabel); + + if (pieChart.SubSliceVisualLayout.OuterSliceLabel != null) + return (pieChart.SubSliceVisualLayout.OuterSliceLabel); + + return ("{X}"); + } + + #endregion + + #region GetReferenceLineDisplayModeEx + + private PieRefLineDisplayMode GetReferenceLineDisplayModeEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.ReferenceLineDisplayMode != PieRefLineDisplayMode.NotSet) + return (psp.SubSliceVisualLayout.ReferenceLineDisplayMode); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.ReferenceLineDisplayMode != PieRefLineDisplayMode.NotSet) + return (pieSeries.SubSliceVisualLayout.ReferenceLineDisplayMode); + + if (pieChart.SubSliceVisualLayout.ReferenceLineDisplayMode != PieRefLineDisplayMode.NotSet) + return (pieChart.SubSliceVisualLayout.ReferenceLineDisplayMode); + + return (PieRefLineDisplayMode.None); + } + + #endregion + + #region GetReferenceLineDisplayOnTopEx + + private bool GetReferenceLineDisplayOnTopEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.ReferenceLineDisplayOnTop != Tbool.NotSet) + return (psp.SubSliceVisualLayout.ReferenceLineDisplayOnTop == Tbool.True); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.ReferenceLineDisplayOnTop != Tbool.NotSet) + return (pieSeries.SubSliceVisualLayout.ReferenceLineDisplayOnTop == Tbool.True); + + return (pieChart.SubSliceVisualLayout.ReferenceLineDisplayOnTop != Tbool.False); + } + + #endregion + + #region GetReferenceLinesEx + + private List GetReferenceLinesEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + List lines = new List(); + + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout._ReferenceLines != null) + AddReferenceLines(lines, psp.SubSliceVisualLayout.ReferenceLines); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout._ReferenceLines != null) + AddReferenceLines(lines, pieSeries.SubSliceVisualLayout.ReferenceLines); + + if (pieChart.SubSliceVisualLayout._ReferenceLines != null) + AddReferenceLines(lines, pieChart.SubSliceVisualLayout.ReferenceLines); + + return (lines); + } + + #region AddReferenceLines + + private void AddReferenceLines( + List lines, PieReferenceLineCollection rlc) + { + foreach (PieReferenceLine line in rlc) + lines.Add(line); + } + + #endregion + + #endregion + + #region GetRingWeightEx + + private int GetRingWeightEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.RingWeight >= 0) + return (psp.SubSliceVisualLayout.RingWeight); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.RingWeight >= 0) + return (pieSeries.SubSliceVisualLayout.RingWeight); + + if (pieChart.SubSliceVisualLayout.RingWeight >= 0) + return (pieChart.SubSliceVisualLayout.RingWeight); + + return (100); + } + + #endregion + + #region GetShowSliceWhiteSpaceEx + + private bool GetShowSliceWhiteSpaceEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.ShowSliceWhiteSpace != Tbool.NotSet) + return (psp.SubSliceVisualLayout.ShowSliceWhiteSpace == Tbool.True); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.ShowSliceWhiteSpace != Tbool.NotSet) + return (pieSeries.SubSliceVisualLayout.ShowSliceWhiteSpace == Tbool.True); + + return (pieChart.SubSliceVisualLayout.ShowSliceWhiteSpace == Tbool.True); + } + + #endregion + + #region GetSliceLabelCropModeEx + + private SliceLabelCropMode GetSliceLabelCropModeEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.SliceLabelCropMode != SliceLabelCropMode.NotSet) + return (psp.SubSliceVisualLayout.SliceLabelCropMode); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.SliceLabelCropMode != SliceLabelCropMode.NotSet) + return (pieSeries.SubSliceVisualLayout.SliceLabelCropMode); + + if (pieChart.SubSliceVisualLayout.SliceLabelCropMode != SliceLabelCropMode.NotSet) + return (pieChart.SubSliceVisualLayout.SliceLabelCropMode); + + return (SliceLabelCropMode.Clip); + } + + #endregion + + #region GetSliceLabelDisplayModeEx + + private SliceLabelDisplayMode GetSliceLabelDisplayModeEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.SliceLabelDisplayMode != SliceLabelDisplayMode.NotSet) + return (psp.SubSliceVisualLayout.SliceLabelDisplayMode); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.SliceLabelDisplayMode != SliceLabelDisplayMode.NotSet) + return (pieSeries.SubSliceVisualLayout.SliceLabelDisplayMode); + + if (pieChart.SubSliceVisualLayout.SliceLabelDisplayMode != SliceLabelDisplayMode.NotSet) + return (pieChart.SubSliceVisualLayout.SliceLabelDisplayMode); + + return (SliceLabelDisplayMode.InnerAndOuter); + } + + #endregion + + #region GetSliceLabelOrientationEx + + private SliceLabelOrientation GetSliceLabelOrientationEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.InnerLabelOrientation != SliceLabelOrientation.NotSet) + return (psp.SubSliceVisualLayout.InnerLabelOrientation); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.InnerLabelOrientation != SliceLabelOrientation.NotSet) + return (pieSeries.SubSliceVisualLayout.InnerLabelOrientation); + + if (pieChart.SubSliceVisualLayout.InnerLabelOrientation != SliceLabelOrientation.NotSet) + return (pieChart.SubSliceVisualLayout.InnerLabelOrientation); + + return (SliceLabelOrientation.Adaptive); + } + + #endregion + + #region GetSliceLabelVisibilityEx + + private SliceLabelVisibility GetSliceLabelVisibilityEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.SliceLabelVisibility != SliceLabelVisibility.NotSet) + return (psp.SubSliceVisualLayout.SliceLabelVisibility); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.SliceLabelVisibility != SliceLabelVisibility.NotSet) + return (pieSeries.SubSliceVisualLayout.SliceLabelVisibility); + + if (pieChart.SubSliceVisualLayout.SliceLabelVisibility != SliceLabelVisibility.NotSet) + return (pieChart.SubSliceVisualLayout.SliceLabelVisibility); + + return (SliceLabelVisibility.NotSet); + } + + #endregion + + #region GetToolTipTextEx + + private string GetToolTipTextEx( + PieChart pieChart, PieSeries pieSeries, object item) + { + PieSeriesPoint psp = item as PieSeriesPoint; + + while (psp != null) + { + if (psp.SubSliceVisualLayout.ToolTipText != null) + return (psp.SubSliceVisualLayout.ToolTipText); + + psp = GetParentPsp(psp); + } + + if (pieSeries.SubSliceVisualLayout.ToolTipText != null) + return (pieSeries.SubSliceVisualLayout.ToolTipText); + + if (pieChart.SubSliceVisualLayout.ToolTipText != null) + return (pieChart.SubSliceVisualLayout.ToolTipText); + + return ("{x}"); + } + + #endregion + + #region GetParentPsp + + private PieSeriesPoint GetParentPsp(PieSeriesPoint psp) + { + PieSeriesPointCollection spc = psp.Parent as PieSeriesPointCollection; + + return (spc != null) ? spc.Parent as PieSeriesPoint : null; + } + + #endregion + + #endregion + + #region GetRayEndPoint + + internal Point GetRayEndPoint(double angle, double radius) + { + Point pt = SliceCenter; + + double radians = MathHelper.ToRadians(angle); + + pt.X += (int)(Math.Cos(radians) * radius); + pt.Y += (int)(Math.Sin(radians) * radius); + + return (pt); + } + + #endregion + + #region GetLabelText + + internal string GetLabelText(string pattern) + { + pattern = pattern.Replace("\\n", "\n"); + pattern = pattern.Replace("\\r", "\r"); + + Regex regex = new Regex("{([^}]*)}"); + MatchCollection mc = regex.Matches(pattern); + + StringBuilder sb = new StringBuilder(); + + int index = 0; + + foreach (Match ma in mc) + { + if (ma.Index > index) + sb.Append(pattern.Substring(index, ma.Index - index)); + + sb.Append(ProcessSliceLabelFmt(ma.Value)); + + index = ma.Index + ma.Length; + } + + if (index < pattern.Length) + sb.Append(pattern.Substring(index)); + + return (sb.ToString()); + } + + #region ProcessSliceLabelFmt + + /// "AVG" "A" - Average (angular values). + /// "PCT" "P" - Percent of pie (angular values) - (.025 yields "2.5 %"). + /// "TOT" "T" - Total of all values (angluar values). + /// "VAL" "V" - Value percent of pie (angular value) - (.025 yields ".025"). + /// + /// "AVGX" "AX" - Average (extent/radial values). + /// "PCTX" "PX" - Percent of pie (extent values) - (.025 yields "2.5 %"). + /// "TOTX" "TX" - Total of all values (extent values). + /// "VALX" "VX" - Value percent of pie (extent value) - (.025 yields ".025"). + /// + /// "S" "SNAME" - Series name. + /// "X" - ValueX. + /// "Y", "Y0", "Yn" - ValueY values (where 'n' is index value). + /// + /// Use: {format[:specifier]} + + private string ProcessSliceLabelFmt(string pattern) + { + string s = pattern.Substring(1, pattern.Length - 2); + + int n = s.IndexOf(':'); + + if ((uint)n > s.Length - 1) + n = s.Length; + + string placeHolder = s.Substring(0, n).Trim().ToUpper(); + string formatSpecifier = (n + 1 < s.Length) ? s.Substring(n + 1) : ""; + + try + { + PieSeriesPointCollection spc = Parent as PieSeriesPointCollection; + + switch (placeHolder) + { + case "A": + case "AVG": + if (spc != null) + return (GetSliceLabelText(spc.PieAverage, formatSpecifier)); + break; + + case "AX": + case "AVGX": + if (spc != null) + return (GetSliceLabelText(spc.PieAverageExtent, formatSpecifier)); + break; + + case "N": + case "NAME": + if (string.IsNullOrEmpty(formatSpecifier) == false) + return (String.Format(formatSpecifier, Name)); + + return (Name); + + case "P": + case "PCT": + if (string.IsNullOrEmpty(formatSpecifier) == false) + return (SliceValue.ToString(formatSpecifier)); + + return (GetSliceLabelText(SliceValue, "P")); + + case "PX": + case "PCTX": + if (string.IsNullOrEmpty(formatSpecifier) == false) + return (SliceExtent.ToString(formatSpecifier)); + + return (GetSliceLabelText(SliceExtent, "P")); + + case "S": + case "SNAME": + string sname = ChartSeries != null ? ChartSeries.Name : ""; + + if (string.IsNullOrEmpty(formatSpecifier) == false) + return (String.Format(formatSpecifier, sname)); + + return (sname); + + case "T": + case "TOTA": + if (spc != null) + return (GetSliceLabelText(spc.PieTotal, formatSpecifier)); + break; + + case "TX": + case "TOTX": + if (spc != null) + return (GetSliceLabelText(spc.PieTotalExtent, formatSpecifier)); + break; + + case "V": + case "VAL": + return (GetSliceLabelText(SliceValue, formatSpecifier)); + + case "VX": + case "VALX": + return (GetSliceLabelText(SliceExtent, formatSpecifier)); + + case "X": + return (GetSliceLabelText(ValueX, formatSpecifier)); + + case "Y": + case "Y0": + if (ValueY != null && ValueY.Length > 0) + return (GetSliceLabelText(ValueY[0], formatSpecifier)); + + return (""); + + default: + if (placeHolder.StartsWith("Y") == true) + { + int index = int.Parse(placeHolder.Substring(1)); + + if (ValueY != null && ValueY.Length > index) + return (GetSliceLabelText(ValueY[index], formatSpecifier)); + } + + return (s); + } + } + catch + { + } + + return (s); + } + + #region GetSliceLabelText + + private string GetSliceLabelText(object value, string format) + { + if (value is string) + { + if (string.IsNullOrEmpty(format) == true) + return ((string)value); + + return (String.Format(format, value)); + } + else + { + double d = Convert.ToDouble(value); + + if (string.IsNullOrEmpty(format) == false) + return (d.ToString(format)); + + return (d.ToString("F3")); + } + } + + #endregion + + #endregion + + #endregion + + #region Style handling + + #region GetEffectiveSliceStyle + + public ChartSliceVisualStyle + GetEffectiveSliceStyle(PieChart pieChart, PieSeries series) + { + StyleState state = StyleState.Default; + + if (series.IsHighLightedPsp(pieChart, this) == true) + state |= StyleState.MouseOver; + + if (IsSelected == true) + state |= StyleState.Selected; + + ChartSliceVisualStyle estyle = EffectiveSliceStyles[state]; + + if (_WordPosLines != null) + { + if (_LastEffectiveStyle != null) + { + if (EqualFonts(estyle.SliceInnerLabelStyle.Font, + _LastEffectiveStyle.SliceInnerLabelStyle.Font) == false) + { + _CharBounds = null; + _WordPosLines = null; + } + } + + _LastEffectiveStyle = estyle; + } + + return (estyle); + } + + #region EqualFonts + + private bool EqualFonts(Font font1, Font font2) + { + if (font1 == null || font2 == null) + return (false); + + return (font1.Name == font2.Name && + font1.SizeInPoints == font2.SizeInPoints && + font1.Style == font2.Style); + } + + #endregion + + #endregion + + #region ApplyStyles + + public void ApplyStyles(BaseVisualStyle style) + { + } + + public void ApplyStyles(BaseVisualStyle style, StyleType cs) + { + ChartSliceVisualStyle sstyle = style as ChartSliceVisualStyle; + + if (sstyle != null) + { + PieSeriesPointCollection spc = Parent as PieSeriesPointCollection; + PieSeries series = ChartSeries; + + if (IsOther == true) + { + ApplyOtherParentStyles(sstyle, cs, series.Parent as ChartContainer); + + sstyle.ApplyStyle(series.SubSliceVisualLayout.OtherSliceVisualStyles[cs]); + + ApplyOtherParentPspStyle(sstyle, cs, this); + } + else + { + ApplyParentStyles(sstyle, cs, series.Parent as ChartContainer); + + sstyle.ApplyStyle(series.SubSliceVisualLayout.SliceVisualStyles[cs]); + + ApplyParentPspStyle(sstyle, cs, this); + } + + sstyle.ApplyStyle(SliceVisualStyles[cs]); + } + } + + #region ApplyOtherParentStyles + + private void ApplyOtherParentStyles( + ChartSliceVisualStyle sstyle, StyleType cs, ChartContainer item) + { + if (item != null) + { + ApplyOtherParentStyles(sstyle, cs, item.Parent as ChartContainer); + + ChartPanel panel = item as ChartPanel; + + if (panel != null) + { + sstyle.ApplyStyle(panel.DefaultVisualStyles.OtherSliceVisualStyles[cs]); + } + else + { + PieChart pieChart = item as PieChart; + + if (pieChart != null) + sstyle.ApplyStyle(pieChart.SubSliceVisualLayout.OtherSliceVisualStyles[cs]); + } + } + else + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + { + sstyle.ApplyStyle(chartControl.BaseVisualStyles.OtherSliceVisualStyles[cs]); + sstyle.ApplyStyle(chartControl.DefaultVisualStyles.OtherSliceVisualStyles[cs]); + } + } + } + + #endregion + + #region ApplyOtherParentPspStyle + + private void ApplyOtherParentPspStyle( + ChartSliceVisualStyle sstyle, StyleType cs, PieSeriesPoint psp) + { + psp = GetParentPsp(psp); + + if (psp != null) + { + ApplyOtherParentPspStyle(sstyle, cs, psp); + + sstyle.ApplyStyle(psp.SubSliceVisualLayout.OtherSliceVisualStyles[cs]); + } + } + + #endregion + + #region ApplyParentStyles + + private void ApplyParentStyles( + ChartSliceVisualStyle sstyle, StyleType cs, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(sstyle, cs, item.Parent as ChartContainer); + + if (item is PieChart) + sstyle.ApplyStyle(((PieChart)item).SubSliceVisualLayout.SliceVisualStyles[cs]); + + if (item is ChartPanel) + sstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.SliceVisualStyles[cs]); + } + else + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + { + sstyle.ApplyStyle(ChartControl.BaseVisualStyles.SliceVisualStyles[cs]); + sstyle.ApplyStyle(ChartControl.DefaultVisualStyles.SliceVisualStyles[cs]); + } + } + } + + #endregion + + #region ApplyParentPspStyle + + private void ApplyParentPspStyle( + ChartSliceVisualStyle sstyle, StyleType cs, PieSeriesPoint psp) + { + psp = GetParentPsp(psp); + + if (psp != null) + { + ApplyParentPspStyle(sstyle, cs, psp); + + sstyle.ApplyStyle(psp.SubSliceVisualLayout.SliceVisualStyles[cs]); + } + } + + #endregion + + #endregion + + #region ApplyDefaults + + public void ApplyDefaults(BaseVisualStyle style, StyleType styleType) + { + ChartSliceVisualStyle sstyle = style as ChartSliceVisualStyle; + + if (sstyle != null) + { + HatchFillType hatch = HatchFillType.LightUpwardDiagonal; + + switch (styleType) + { + case StyleType.Default: + if (sstyle.Background.IsEmpty == true) + sstyle.Background = new Background(DefaultPaletteColor); + + if (sstyle.WhiteSpaceBackground.IsEmpty == true) + sstyle.WhiteSpaceBackground = new Background(Color.FromArgb(100, DefaultPaletteColor)); + + if (sstyle.WhiteSpaceBorder.LinePattern == LinePattern.NotSet) + sstyle.WhiteSpaceBorder.LinePattern = LinePattern.Solid; + + break; + + case StyleType.MouseOver: + if (sstyle.Background.IsEmpty == true) + sstyle.Background = new Background(ControlPaint.Light(DefaultPaletteColor)); + + if (sstyle.WhiteSpaceBackground.IsEmpty == true) + sstyle.WhiteSpaceBackground = new Background(Color.FromArgb(50, DefaultPaletteColor)); + + if (sstyle.WhiteSpaceBorder.LinePattern == LinePattern.NotSet) + sstyle.WhiteSpaceBorder.LinePattern = LinePattern.Solid; + + break; + + case StyleType.Selected: + if (sstyle.Background.IsEmpty == true) + { + sstyle.Background = new Background(Color.White, DefaultPaletteColor); + sstyle.Background.HatchFillType = hatch; + } + + if (sstyle.Border.LineWidth < 0) + sstyle.Border.LineWidth = 2; + + if (sstyle.WhiteSpaceBackground.IsEmpty == true) + { + sstyle.WhiteSpaceBackground = new Background(Color.White, Color.FromArgb(100, DefaultPaletteColor)); + sstyle.WhiteSpaceBackground.HatchFillType = hatch; + } + + if (sstyle.WhiteSpaceBorder.LineWidth < 0) + sstyle.WhiteSpaceBorder.LineWidth = 2; + + break; + + case StyleType.SelectedMouseOver: + if (sstyle.Background.IsEmpty == true) + { + sstyle.Background = new Background(Color.White, ControlPaint.Light(DefaultPaletteColor)); + sstyle.Background.HatchFillType = hatch; + } + + if (sstyle.Border.LineWidth < 0) + sstyle.Border.LineWidth = 2; + + if (sstyle.WhiteSpaceBackground.IsEmpty == true) + { + sstyle.WhiteSpaceBackground = new Background(Color.White, Color.FromArgb(50, DefaultPaletteColor)); + sstyle.WhiteSpaceBackground.HatchFillType = hatch; + } + + if (sstyle.WhiteSpaceBorder.LineWidth < 0) + sstyle.WhiteSpaceBorder.LineWidth = 2; + + break; + } + + if (sstyle.Border.LineColor.IsEmpty == true) + sstyle.Border.LineColor = DefaultPaletteColor; + + if (sstyle.WhiteSpaceBorder.LineColor.IsEmpty == true) + sstyle.WhiteSpaceBorder.LineColor = DefaultPaletteColor; + + if (sstyle.ExtentAverageRefLineStyle.LineColor.IsEmpty == true) + sstyle.ExtentAverageRefLineStyle.LineColor = Color.DimGray; + + if (sstyle.ExtentMinRefLineStyle.LineColor.IsEmpty == true) + sstyle.ExtentMinRefLineStyle.LineColor = Color.DimGray; + + if (sstyle.ExtentMaxRefLineStyle.LineColor.IsEmpty == true) + sstyle.ExtentMaxRefLineStyle.LineColor = Color.DimGray; + + if (sstyle.ExtentOuterRefLineStyle.LineColor.IsEmpty == true) + sstyle.ExtentOuterRefLineStyle.LineColor = Color.DimGray; + + if (sstyle.SliceOuterLabelStyle.TextColor.IsEmpty == true) + sstyle.SliceOuterLabelStyle.TextColor = DefaultPaletteColor; + + sstyle.ApplyDefaults(); + } + } + + #endregion + + #region GetElementStyle + + public virtual void GetElementStyle( + IEffectiveStyle chartElement, StyleType styleType, ref BaseVisualStyle style) + { + ChartControl chartControl = ChartControl; + + if (chartControl != null) + chartControl.DoGetPieSeriesPointStyleEvent(this, styleType, ref style); + } + + #endregion + + #region ChartControl + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartControl ChartControl + { + get + { + if (_ChartControl == null) + { + if (ChartSeries != null) + _ChartControl = ChartSeries.ChartControl; + } + + return (_ChartControl); + } + } + + #endregion + + #region ClearEffectiveStyles + + protected void ClearEffectiveStyles() + { + _EffectiveSliceStyles.InvalidateStyles(); + } + + #endregion + + #region OnStyleChanged + + protected virtual void OnStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + StyleChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #endregion + + #region StyleChangeHandler + + protected void StyleChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected void StyleChanged(object sender, PropertyChangedEventArgs e) + { + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + PieSeries series = ChartSeries; + + if (series != null) + { + if (series.ChartControl != null) + series.ChartControl.GlobalUpdateCount++; + + if (changeType == VisualChangeType.Layout) + series.InvalidateLayout(); + else + series.InvalidateRender(); + } + } + + #endregion + + #endregion + + #endregion + + #region ILegendItem + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the visual styles for the Legend item. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Legend item.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (_ChartLegendItemVisualStyles != value) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CheckedInLegend + + /// + /// Gets or sets whether the item is checked in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the item is checked in the Legend.")] + public bool CheckedInLegend + { + get { return (TestState(States.CheckedInLegend)); } + + set + { + if (value != CheckedInLegend) + { + SetState(States.CheckedInLegend, value); + + if (LegendItem != null) + LegendItem.UpdateCheckState(); + + OnPropertyChangedEx("CheckedInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowCheckBoxInLegend + + /// + /// Gets or sets whether a checkbox for the item is shown in the Legend. + /// + [DefaultValue(false), Category("Legend")] + [Description("Indicates whether a checkbox for the item is shown in the Legend.")] + public bool ShowCheckBoxInLegend + { + get { return (TestState(States.ShowCheckBoxInLegend)); } + + set + { + if (value != ShowCheckBoxInLegend) + { + SetState(States.ShowCheckBoxInLegend, value); + + OnPropertyChangedEx("ShowCheckBoxInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInLegend + + /// + /// Gets or sets whether the item is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the item is shown in the Legend.")] + public bool ShowInLegend + { + get { return (TestState(States.ShowInLegend)); } + + set + { + if (value != ShowInLegend) + { + SetState(States.ShowInLegend, value); + + OnPropertyChangedEx("ShowInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInParentLegend + + /// + /// Gets or sets whether the item Line is shown in parent Legend(s). + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the item Line is shown in parent Legend(s).")] + public bool ShowInParentLegend + { + get { return (TestState(States.ShowInParentLegend)); } + + set + { + if (value != ShowInParentLegend) + { + SetState(States.ShowInParentLegend, value); + + OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowMarkerInLegend + + /// + /// Gets or sets whether the item Marker is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the item Marker is shown in the Legend.")] + public bool ShowMarkerInLegend + { + get { return (TestState(States.ShowMarkerInLegend)); } + + set + { + if (value != ShowMarkerInLegend) + { + SetState(States.ShowMarkerInLegend, value); + + OnPropertyChangedEx("ShowMarkerInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LegendItem + + /// + /// Gets the item's parent LegendItem. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the item's parent LegendItem.")] + public ChartLegendItem LegendItem + { + get + { + if (_LegendItem == null) + { + _LegendItem = new ChartLegendItem(); + + _LegendItem.Name = (ValueX != null ? ValueX.ToString() : ""); + + if (string.IsNullOrEmpty(_LegendItem.Name) == true) + _LegendItem.Name = "(Psp)"; + + _LegendItem.ChartItems.Add(this); + } + + return (_LegendItem); + } + + internal set { _LegendItem = value; } + } + + #endregion + + #region LegendText + + /// + /// Gets or sets the text to display in the legend. + /// + [DefaultValue(null), Category("Legend")] + [Description("Indicates the text to display in the legend.")] + [NotifyParentProperty(true)] + public string LegendText + { + get { return (_LegendText); } + + set + { + if (value != _LegendText) + { + _LegendText = value; + + OnPropertyChangedEx("LegendText", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region GetLegendItem + + /// + /// Creates the LegendItem for the item. + /// + /// + public ChartLegendItem GetLegendItem() + { + ChartLegendItem item = LegendItem; + + if (ShowInLegend == true) + { + item.CheckState = (CheckedInLegend == true) + ? CheckState.Checked : CheckState.Unchecked; + + item.ItemText = LegendText; + item.IsEnabled = IsEnabled; + + } + + return (item); + } + + #endregion + + #region GetLegendItems + + /// + /// Creates a list of legend items associated with + /// the item. + /// + /// + public List GetLegendItems() + { + List list = null; + + ChartLegendItem litem = GetLegendItem(); + + if (litem != null) + { + list = new List(1); + + list.Add(litem); + } + + return (list); + } + + #endregion + + #region GetLegendItemColor + + /// + /// Gets the default color associated with the legend item. + /// + /// + public Color GetLegendItemColor() + { + ChartSliceVisualStyle sstyle = EffectiveSliceStyles[StyleState.Default]; + + Color color = sstyle.Background.Color1; + + if (color.IsEmpty == false) + return (color); + + return (Color.DimGray); + } + + #endregion + + #region RenderLegendItemMarker + + /// + /// Renders the Legend item Marker. + /// + /// + /// + /// + public void RenderLegendItemMarker(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + ChartSliceVisualStyle sstyle = EffectiveSliceStyles[StyleState.Default]; + + Rectangle r = litem.MarkerBounds; + r.Inflate(-1, -1); + + g.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = new GraphicsPath()) + { + Point pt = new Point(r.Right - 2, r.Bottom - 2); + + r.Height += (r.Height - 4); + r.Width += (r.Width - 4); + + path.AddArc(r, 180, 90); + path.AddLine(pt, pt); + + path.CloseFigure(); + + if (IsEnabled == true) + { + if (sstyle.Background.IsEmpty == true) + { + g.FillPath(Brushes.LightPink, path); + } + else + { + using (Brush br = sstyle.Background.GetBrush(r)) + g.FillPath(br, path); + + if (sstyle.Background.Color1.IsEmpty == false) + { + using (Pen pen = new Pen(sstyle.Background.Color1)) + g.DrawPath(pen, path); + } + } + } + else + { + Background back = style.DisabledMarkerBackground; + + if (back.IsEmpty == true) + { + using (Brush br = new SolidBrush(Color.LightGray)) + g.FillPath(br, path); + } + else + { + using (Brush br = back.GetBrush(r)) + g.FillPath(br, path); + + if (back.Color1.IsEmpty == false) + { + using (Pen pen = new Pen(sstyle.Background.Color1)) + g.DrawPath(pen, path); + } + } + } + } + } + + #endregion + + #region TrackLegendItem + + /// + /// Gets whether legend item tracking is enabled. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TrackLegendItem + { + get + { + if (ChartSeries != null) + return (ChartSeries.TrackLegendItem); + + return (false); + } + } + + #endregion + + #region FormatItemText + + /// + /// Formats the provided item text. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string FormatItemText(string text) + { + return (GetLabelText(text)); + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + AllowDetach = (1U << 0), + AllowSelect = (1U << 1), + + Detached = (1U << 2), + Selected = (1U << 3), + + IsOther = (1U << 4), + IsInOther = (1U << 5), + IsInOtherEx = (1U << 6), + + InnerLabelClipped = (1U << 7), + InnerLabelDisplayed = (1U << 8), + + IsOffset = (1U << 9), + InscribedRectValid = (1 << 10), + + CheckedInLegend = (1U << 11), + ShowInLegend = (1U << 12), + ShowInParentLegend = (1U << 13), + ShowCheckBoxInLegend = (1U << 14), + ShowMarkerInLegend = (1U << 15), + + ReferenceLineDisplayOnTop = (1U << 16), + ShowSliceWhiteSpaceEx = (1U << 17), + + HasExtent = (1U << 18), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region Copy/CopyTo + + /// + /// Creates a copy of the PieSeriesPoint + /// + /// + public new PieSeriesPoint Copy() + { + PieSeriesPoint copy = new PieSeriesPoint(ValueX, 0); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the item data to the given PieSeriesPoint. + /// + /// + public void CopyTo(PieSeriesPoint c) + { + base.CopyTo(c); + + c.AllowDetach = AllowDetach; + c.AllowSelect = AllowSelect; + + c.DetachedOffset = DetachedOffset; + c.InnerSliceLabel = InnerSliceLabel; + c.IsDetached = IsDetached; + c.IsInOther = IsInOther; + c.IsSelected = IsSelected; + c.Name = Name; + c.OuterSliceLabel = OuterSliceLabel; + + if (_SeriesPoints != null) + { + PieSeriesPointCollection spc = SeriesPoints; + + if (spc.Count > 0) + { + foreach (PieSeriesPoint psp in spc) + { + PieSeriesPoint pspCopy = psp.Copy(); + + c.SeriesPoints.Add(pspCopy); + } + } + } + + c.SubSliceVisualLayout = (_SliceVisualLayout != null) ? _SliceVisualLayout.Copy() : null; + c.SliceVisualStyles = (_SliceVisualStyles != null) ? _SliceVisualStyles.Copy() : null; + + c.StartAngle = StartAngle; + c.SweepAngle = SweepAngle; + + c.CheckedInLegend = CheckedInLegend; + c.LegendText = LegendText; + c.ShowCheckBoxInLegend = ShowCheckBoxInLegend; + c.ShowInLegend = ShowInLegend; + c.ShowInParentLegend = ShowInParentLegend; + c.ShowMarkerInLegend = ShowMarkerInLegend; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(bool root) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (root == true) + sec.AddStartElement("SeriesPoint"); + + sec.AddValue("AllowDetach", AllowDetach, true); + sec.AddValue("AllowSelect", AllowSelect, true); + sec.AddValue("DetachedOffset", DetachedOffset, double.NaN); + sec.AddValue("InnerSliceLabel", InnerSliceLabel, null); + sec.AddValue("IsDetached", IsDetached, false); + sec.AddValue("IsInOther", IsInOther, false); + sec.AddValue("IsSelected", IsSelected, false); + sec.AddValue("Name", Name, null); + sec.AddValue("OuterSliceLabel", OuterSliceLabel, null); + + sec.AddValue("StartAngle", StartAngle, double.NaN); + sec.AddValue("SweepAngle", SweepAngle, double.NaN); + + if (_SeriesPoints != null) + { + PieSeriesPointCollection spc = SeriesPoints; + + if (spc.Count > 0) + { + sec.AddStartElement("SeriesPoints count=\"" + spc.Count + "\""); + + foreach (PieSeriesPoint psp in spc) + sec.AddElement(psp.GetSerialData()); + + sec.AddEndElement("SeriesPoints"); + } + } + + if (_SliceVisualLayout != null) + sec.AddElement(_SliceVisualLayout.GetSerialData()); + + if (_SliceVisualStyles != null && _SliceVisualStyles.IsEmpty == false) + sec.AddElement(_SliceVisualStyles.GetSerialData("SliceVisualStyles")); + + sec.AddValue("CheckedInLegend", CheckedInLegend, true); + sec.AddValue("LegendText", LegendText, null); + sec.AddValue("ShowCheckBoxInLegend", ShowCheckBoxInLegend, true); + sec.AddValue("ShowInLegend", ShowInLegend, true); + sec.AddValue("ShowInParentLegend", ShowInParentLegend, true); + sec.AddValue("ShowMarkerInLegend", ShowMarkerInLegend, true); + + sec.AddElement(base.GetSerialData(false)); + + if (root == true) + sec.AddEndElement("SeriesPoint"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AllowDetach": + AllowDetach = bool.Parse(se.StringValue); + break; + + case "AllowSelect": + AllowSelect = bool.Parse(se.StringValue); + break; + + case "DetachedOffset": + DetachedOffset = double.Parse(se.StringValue); + break; + + case "InnerSliceLabel": + InnerSliceLabel = se.StringValue; + break; + + case "IsDetached": + IsDetached = bool.Parse(se.StringValue); + break; + + case "IsInOther": + IsInOther = bool.Parse(se.StringValue); + break; + + case "IsSelected": + IsSelected = bool.Parse(se.StringValue); + break; + + case "Name": + Name = se.StringValue; + break; + + case "OuterSliceLabel": + OuterSliceLabel = se.StringValue; + break; + + case "StartAngle": + StartAngle = double.Parse(se.StringValue); + break; + + case "SweepAngle": + SweepAngle = double.Parse(se.StringValue); + break; + + case "CheckedInLegend": + CheckedInLegend = bool.Parse(se.StringValue); + break; + + case "LegendText": + LegendText = se.StringValue; + break; + + case "ShowCheckBoxInLegend": + ShowCheckBoxInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInLegend": + ShowInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInParentLegend": + ShowInParentLegend = bool.Parse(se.StringValue); + break; + + case "ShowMarkerInLegend": + ShowMarkerInLegend = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "SeriesPoints": + if (se.ArrayCount > 0) + { + SeriesPoints = new PieSeriesPointCollection(); + + sec.PutSerialData(this); + } + break; + + case "SeriesPoint": + PieSeriesPoint sp = new PieSeriesPoint(); + + sec.PutSerialData(sp); + + SeriesPoints.Add(sp); + break; + + case "SliceVisualLayout": + sec.PutSerialData(SubSliceVisualLayout); + break; + + case "SliceVisualStyles": + se.Sec.PutSerialData(SliceVisualStyles); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + #region OnPropertyChanged + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (PropertyChanged != null) + PropertyChanged(this, e); + + VisualPropertyChangedEventArgs vce = e as VisualPropertyChangedEventArgs; + + if (vce != null) + NotifyVisualParent(this, vce.ChangeType); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType)); + } + + #endregion + + #region NotifyVisualParent + + internal void NotifyVisualParent(object sender, VisualChangeType vct) + { + ChartVisualElement cve = GetParentCve(sender); + + if (cve != null) + { + if (vct == VisualChangeType.Recalc) + { + cve.InvalidateRecalc(); + cve.InvalidateLayout(); + } + else if (vct == VisualChangeType.Layout) + { + cve.InvalidateLayout(); + } + else + { + PieSeriesPoint psp = (PieSeriesPoint)sender; + + cve.InvalidateRender(psp.PathBounds); + + if (psp.PieLabel != null) + { + if (psp.PieLabel.Bounds.IsEmpty == false) + { + cve.InvalidateRender(psp.PieLabel.Bounds); + + if (psp.PieLabel.ConnectorBounds.IsEmpty == false) + cve.InvalidateRender(psp.PieLabel.ConnectorBounds); + } + } + } + } + } + + #region GetParentCve + + private ChartVisualElement GetParentCve(object sender) + { + object parent = sender; + + while (parent != null) + { + if (parent is ChartVisualElement) + break; + + if (parent is PieSeriesPoint) + parent = ((PieSeriesPoint)parent).Parent; + + else if (parent is PieSeriesPointCollection) + parent = ((PieSeriesPointCollection)parent).Parent; + + else + parent = null; + } + + return ((ChartVisualElement)parent); + } + + #endregion + + #endregion + + #endregion + + #region InvalidateRender + + public void InvalidateRender() + { + ChartVisualElement cve = GetParentCve(Parent); + + if (cve != null) + { + cve.InvalidateRender(PathBounds); + + if (PieLabel != null) + { + if (PieLabel.Bounds.IsEmpty == false) + { + cve.InvalidateRender(PieLabel.Bounds); + + if (PieLabel.ConnectorBounds.IsEmpty == false) + cve.InvalidateRender(PieLabel.ConnectorBounds); + } + } + } + } + + #endregion + + #region IDispose + + public override void Dispose() + { + SubSliceVisualLayout = null; + SliceVisualStyles = null; + + base.Dispose(); + } + + #endregion + } + + #endregion + + [Editor("DevComponents.Charts.Design.SeriesPointCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class SeriesPointCollection : CustomCollection + { + } + + #region SeriesPoint + + [DesignTimeVisible(false), ToolboxItem(false)] + public class SeriesPoint : IProcessSerialElement, IDisposable + { + #region Private variables + + private object _ValueX; + private object[] _ValueY; + + private Point[] _Point; + private int _SeriesValidationCount; + + private Size _PointSize; + + private States _States; + + private object _DataItem; + private object _Tag; + + #endregion + + #region Constructors + + public SeriesPoint() + : this(0, 0) + { + } + + public SeriesPoint(object xValue) + { + _Point = new Point[1]; + + ValueX = xValue; + + InitDefaultStates(); + } + + public SeriesPoint(object xValue, object yValue) + { + _ValueY = new object[1]; + _Point = new Point[1]; + + ValueX = xValue; + + _ValueY[0] = yValue; + + InitDefaultStates(); + } + + public SeriesPoint(object xValue, object yValue, object size) + { + _ValueY = new object[2]; + _Point = new Point[1]; + + ValueX = xValue; + + _ValueY[0] = yValue; + _ValueY[1] = size; + + InitDefaultStates(); + } + + public SeriesPoint(object xValue, object yValue, object size, object intensity) + { + _ValueY = new object[3]; + _Point = new Point[1]; + + ValueX = xValue; + + _ValueY[0] = yValue; + _ValueY[1] = size; + _ValueY[2] = intensity; + + InitDefaultStates(); + } + + public SeriesPoint(object xValue, object[] yValue) + { + _ValueY = new object[yValue.Length]; + _Point = new Point[yValue.Length]; + + ValueX = xValue; + + for (int i = 0; i < yValue.Length; i++) + { + _ValueY[i] = yValue[i]; + + if (i > 0) + { + if (IsQuantitativeYValue != IsQuantitativeValue(yValue[i])) + throw new ArgumentException("Cannot have mixed qualitative/quantitative yValues"); + } + } + + InitDefaultStates(); + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.Visible, true); + } + + #endregion + + #region Public properties + + #region DataItem + + /// + /// Gets the object to which the Point is bound. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object DataItem + { + get { return (_DataItem); } + internal set { _DataItem = value; } + } + + #endregion + + #region IsEmpty + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get { return (IsEmptyPoint || IsEmptyValue); } + } + + #endregion + + #region IsEmptyPoint + + /// + /// Gets or sets whether the point is an 'Empty' (or missing) Point. + /// + [DefaultValue(false)] + public virtual bool IsEmptyPoint + { + get { return (TestState(States.IsEmptyPoint)); } + set { SetState(States.IsEmptyPoint, value); } + } + + #endregion + + #region IsEmptyValue + + /// + /// Gets whether the point is an 'Empty' value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmptyValue + { + get { return (TestState(States.IsEmptyValue)); } + internal set { SetState(States.IsEmptyValue, value); } + } + + #endregion + + #region IsQualitativeXValue + + /// + /// Gets whether the X Value is a Qualitative value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsQualitativeXValue + { + get { return (TestState(States.IsQualitativeXValue)); } + internal set { SetState(States.IsQualitativeXValue, value); } + } + + #endregion + + #region IsQualitativeYValue + + /// + /// Gets whether the Y Values are a Qualitative values. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsQualitativeYValue + { + get { return (IsQuantitativeYValue == false); } + } + + #endregion + + #region IsQuantitativeXValue + + /// + /// Gets whether the X Value is a Quantitative value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsQuantitativeXValue + { + get { return (!IsQualitativeXValue); } + internal set { IsQualitativeXValue = !value; } + } + + #endregion + + #region IsQuantitativeYValue + + /// + /// Gets whether the Y Values are Quantitative values. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsQuantitativeYValue + { + get + { + if (_ValueY != null && _ValueY.Length > 0) + return (IsQuantitativeValue(_ValueY[0])); + + return (true); + } + } + + #endregion + + #region Tag + + /// + /// Gets or sets user-defined data associated with the point + /// + [DefaultValue(null)] + [Description("Indicates the user-defined data associated with the point.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object Tag + { + get { return (_Tag); } + set { _Tag = value; } + } + + #endregion + + #region ValueX + + /// + /// Gets or sets the X-Axis Value. + /// + [Category("Data")] + [Description("Indicates the X-Axis Value.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object ValueX + { + get { return (_ValueX); } + + set + { + _ValueX = value; + + IsQuantitativeXValue = IsQuantitativeValue(value); + } + } + + #endregion + + #region ValueY + + /// + /// Gets or sets the Y-Axis Values. + /// + [Category("Data")] + [Description("Indicates the Y-Axis Values.")] + [Editor("DevComponents.Charts.Design.SeriesPointValueEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public object[] ValueY + { + get { return (_ValueY); } + set { _ValueY = value; } + } + + #endregion + + #region Visible + + /// + /// Gets or sets whether the point is Visible. + /// + [DefaultValue(true)] + public virtual bool Visible + { + get { return (TestState(States.Visible)); } + set { SetState(States.Visible, value); } + } + + #endregion + + #endregion + + #region Internal properties + + #region Point + + internal Point[] Point + { + get { return (_Point); } + set { _Point = value; } + } + + #endregion + + #region PointSize + + internal Size PointSize + { + get { return (_PointSize); } + set { _PointSize = value; } + } + + #endregion + + #region SeriesValidationCount + + internal int SeriesValidationCount + { + get { return (_SeriesValidationCount); } + set { _SeriesValidationCount = value; } + } + + #endregion + + #endregion + + #region InvalidatePoints + + internal void InvalidatePoints() + { + if (_Point != null) + _Point = new Point[_Point.Length]; + } + + #endregion + + #region IsQuantitativeValue + + private bool IsQuantitativeValue(object value) + { + if (value is string || value is bool || value is char) + return (false); + + return (true); + } + + #endregion + + #region IsQualitativeValue + + private bool IsQualitativeValue(object value) + { + return (IsQuantitativeValue(value) == false); + } + + #endregion + + #region GetScaleType + + public static ScaleType GetScaleType(Type dataType) + { + if (dataType == typeof(DateTime)) + return (ScaleType.DateTime); + + if (dataType == typeof(string) || dataType == typeof(bool) || dataType == typeof(char)) + return (ScaleType.Qualitative); + + return (ScaleType.Quantitative); + } + + #endregion + + #region Copy/CopyTo + + /// + /// Creates a copy of the SeriesPoint + /// + /// + public SeriesPoint Copy() + { + SeriesPoint copy = new SeriesPoint(ValueX); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the item data to the given SeriesPoint. + /// + /// + public void CopyTo(SeriesPoint sp) + { + sp.IsEmptyPoint = IsEmptyPoint; + sp.Tag = Tag; + + sp.ValueX = ValueX; + + if (ValueY != null) + { + sp.ValueY = new object[ValueY.Length]; + sp.Point = new Point[ValueY.Length]; + + for (int i = 0; i < ValueY.Length; i++) + sp.ValueY[i] = ValueY[i]; + } + } + + #endregion + + #region GetSerialData + + internal virtual SerialElementCollection GetSerialData() + { + return (GetSerialData(true)); + } + + internal virtual SerialElementCollection GetSerialData(bool root) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (root == true) + sec.AddStartElement("SeriesPoint"); + + sec.AddDataValue("Tag", Tag, null); + sec.AddDataValue("ValueX", ValueX); + + if (ValueY != null) + { + if (ValueY.Length == 1) + { + sec.AddDataValue("ValueY0", ValueY[0]); + } + else + { + sec.AddStartElement("ValueYs count=\"" + ValueY.Length + "\""); + + for (int i = 0; i < ValueY.Length; i++) + sec.AddDataValue("ValueY", ValueY[i]); + + sec.AddEndElement("ValueYs"); + } + } + + if (root == true) + sec.AddEndElement("SeriesPoint"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + ProcessValue(se); + } + + internal virtual void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Tag": + Tag = se.DataValue; + break; + + case "ValueX": + ValueX = se.DataValue; + break; + + case "ValueY": + ValueY[se.ValueIndex] = se.DataValue; + break; + + case "ValueY0": + ValueY = new object[1]; + ValueY[0] = se.DataValue; + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + ProcessCollection(se); + } + + internal virtual void ProcessCollection(SerialElement se) + { + switch (se.Name) + { + case "ValueYs": + if (se.ArrayCount > 0) + { + ValueY = new object[se.ArrayCount]; + + se.Sec.PutSerialData(this); + } + break; + + default: + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + IsQualitativeXValue = (1U << 0), + IsQualitativeYValue = (1U << 1), + + IsEmptyPoint = (1U << 2), + IsEmptyValue = (1U << 3), + + Visible = (1U << 4), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region ToString + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.Append("SeriesPoint ("); + sb.Append(FormatToStringValue(ValueX)); + sb.Append(","); + + if (ValueY != null && ValueY.Length > 0) + { + if (ValueY.Length > 1) + sb.Append("["); + + foreach (object value in ValueY) + { + sb.Append(FormatToStringValue(value)); + sb.Append(","); + } + + sb.Length--; + + if (ValueY.Length > 1) + sb.Append("]"); + } + + sb.Append(")"); + + return (sb.ToString()); + } + + #region FormatToStringValue + + private string FormatToStringValue(object value) + { + if (value == null) + return (""); + + if (value is string) + return ("\"" + value + "\""); + + if (value is int) + return (value.ToString()); + + if (value is DateTime) + return (value.ToString()); + + return (String.Format("{0:0.0###############}", value)); + } + + #endregion + + #endregion + + #region IDispose + + public virtual void Dispose() + { + } + + #endregion +} + + #region PointValueConvertor + + /// + /// PointValueConvertor + /// + public class PointValueConvertor : BlankExpandableObjectConverter + { + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + if (value == null) + return (""); + + if (value is string) + return ("\"" + value + "\""); + + if (value is int) + return (value.ToString()); + + if (value is DateTime) + return (value.ToString()); + + return (String.Format("{0:0.0}", value)); + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/TextDrawing.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/TextDrawing.cs new file mode 100644 index 00000000..9a6561e6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/TextDrawing.cs @@ -0,0 +1,250 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Drawing.Text; + +namespace DevComponents.DotNetBar.Charts +{ + internal class TextDrawing + { + #region Public / internal variables + + public static bool UseTextRenderer = true; + public static bool TextDrawingEnabled = true; + + internal static bool UseGenericDefault = false; + + #endregion + + #region DrawString + + public static void DrawString(Graphics g, + string text, Font font, Color color, int x, int y, eTextFormat format) + { + DrawString(g, text, font, color, new Rectangle(x, y, 0, 0), format); + } + + public static void DrawString(Graphics g, + string text, Font font, Color color, Rectangle bounds, eTextFormat format) + { + if (UseTextRenderer && (format & eTextFormat.Vertical) == 0) + TextRenderer.DrawText(g, text, font, bounds, color, GetTextFormatFlags(format)); + else + DrawStringLegacy(g, text, font, color, bounds, format); + } + + #endregion + + #region DrawStringLegacy + + public static void DrawStringLegacy(Graphics g, + string text, Font font, Color color, Rectangle bounds, eTextFormat format) + { + if (color.IsEmpty == false && TextDrawingEnabled == true) + { + using (SolidBrush brush = new SolidBrush(color)) + { + using (StringFormat sf = GetStringFormat(format)) + g.DrawString(text, font, brush, bounds, sf); + } + } + } + + #endregion + + #region MeasureString + + public static Size MeasureString(Graphics g, + string text, Font font) + { + return MeasureString(g, text, font, Size.Empty, eTextFormat.Default); + } + + public static Size MeasureString(Graphics g, + string text, Font font, int proposedWidth, eTextFormat format) + { + return MeasureString(g, text, font, new Size(proposedWidth, 0), format); + } + + public static Size MeasureString(Graphics g, + string text, Font font, int proposedWidth) + { + return MeasureString(g, text, font, new Size(proposedWidth, 0), eTextFormat.Default); + } + + public static Size MeasureString(Graphics g, + string text, Font font, Size proposedSize, eTextFormat format) + { + if (UseTextRenderer && (format & eTextFormat.Vertical) == 0) + { + format = format & ~(format & eTextFormat.VerticalCenter); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.Bottom); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.HorizontalCenter); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.Right); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.EndEllipsis); // Bug in .NET Framework 2.0 + + return (Size.Ceiling(TextRenderer.MeasureText(g, text, font, proposedSize, GetTextFormatFlags(format)))); + } + + using (StringFormat sf = GetStringFormat(format)) + return Size.Ceiling(g.MeasureString(text, font, proposedSize, sf)); + } + + #endregion + + #region MeasureStringLegacy + + public static Size MeasureStringLegacy(Graphics g, + string text, Font font, Size proposedSize, eTextFormat format) + { + using (StringFormat sf = GetStringFormat(format)) + return (g.MeasureString(text, font, proposedSize, sf).ToSize()); + } + + #endregion + + #region TranslateHorizontal + + public static eTextFormat TranslateHorizontal(StringAlignment align) + { + if (align == StringAlignment.Center) + return (eTextFormat.HorizontalCenter); + + if (align == StringAlignment.Far) + return (eTextFormat.Right); + + return (eTextFormat.Default); + } + + #endregion + + #region TranslateVertical + + public static eTextFormat TranslateVertical(StringAlignment align) + { + if (align == StringAlignment.Center) + return (eTextFormat.VerticalCenter); + + if (align == StringAlignment.Far) + return (eTextFormat.Bottom); + + return (eTextFormat.Default); + } + + #endregion + + #region GetTextFormatFlags + + private static TextFormatFlags GetTextFormatFlags(eTextFormat format) + { + format |= eTextFormat.PreserveGraphicsTranslateTransform | + eTextFormat.PreserveGraphicsClipping; + + if ((format & eTextFormat.SingleLine) == eTextFormat.SingleLine && + (format & eTextFormat.WordBreak) == eTextFormat.WordBreak) + { + format = format & ~(format & eTextFormat.SingleLine); + } + + return (TextFormatFlags)format; + } + + #endregion + + #region GetStringFormat + + public static StringFormat GetStringFormat(eTextFormat format) + { + StringFormat sf = new StringFormat(UseGenericDefault + ? StringFormat.GenericDefault : StringFormat.GenericTypographic); + + if (format == eTextFormat.Default) + return sf; + + if ((format & eTextFormat.HorizontalCenter) == eTextFormat.HorizontalCenter) + sf.Alignment = StringAlignment.Center; + + else if ((format & eTextFormat.Right) == eTextFormat.Right) + sf.Alignment = StringAlignment.Far; + + if ((format & eTextFormat.VerticalCenter) == eTextFormat.VerticalCenter) + sf.LineAlignment = StringAlignment.Center; + + else if ((format & eTextFormat.Bottom) == eTextFormat.Bottom) + sf.LineAlignment = StringAlignment.Far; + + if ((format & eTextFormat.EndEllipsis) == eTextFormat.EndEllipsis) + sf.Trimming = StringTrimming.EllipsisCharacter; + else + sf.Trimming = StringTrimming.Character; + + if ((format & eTextFormat.HidePrefix) == eTextFormat.HidePrefix) + sf.HotkeyPrefix = HotkeyPrefix.Hide; + else if ((format & eTextFormat.NoPrefix) == eTextFormat.NoPrefix) + sf.HotkeyPrefix = HotkeyPrefix.None; + else + sf.HotkeyPrefix = HotkeyPrefix.Show; + + if ((format & eTextFormat.WordBreak) == eTextFormat.WordBreak) + sf.FormatFlags = sf.FormatFlags & ~(sf.FormatFlags & StringFormatFlags.NoWrap); + else + sf.FormatFlags |= StringFormatFlags.NoWrap; + + if ((format & eTextFormat.LeftAndRightPadding) == eTextFormat.LeftAndRightPadding) + sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces; + + if ((format & eTextFormat.RightToLeft) == eTextFormat.RightToLeft) + sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + + if ((format & eTextFormat.Vertical) == eTextFormat.Vertical) + sf.FormatFlags |= StringFormatFlags.DirectionVertical; + + if ((format & eTextFormat.NoClipping) == eTextFormat.NoClipping) + sf.FormatFlags |= StringFormatFlags.NoClip; + + return (sf); + } + + #endregion + } + + #region enums + + #region eTextFormat + [Flags] + internal enum eTextFormat + { + Bottom = 8, + Default = 0, + EndEllipsis = 0x8000, + ExpandTabs = 0x40, + ExternalLeading = 0x200, + GlyphOverhangPadding = 0, + HidePrefix = 0x100000, + HorizontalCenter = 1, + Internal = 0x1000, + Left = 0, + LeftAndRightPadding = 0x20000000, + ModifyString = 0x10000, + NoClipping = 0x100, + NoFullWidthCharacterBreak = 0x80000, + NoPadding = 0x10000000, + NoPrefix = 0x800, + PathEllipsis = 0x4000, + PrefixOnly = 0x200000, + PreserveGraphicsClipping = 0x1000000, + PreserveGraphicsTranslateTransform = 0x2000000, + Right = 2, + RightToLeft = 0x20000, + SingleLine = 0x20, + TextBoxControl = 0x2000, + Top = 0, + VerticalCenter = 4, + WordBreak = 0x10, + WordEllipsis = 0x40000, + Vertical = 0x40000000 + } + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/TreeMap/TreeMap.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/TreeMap/TreeMap.cs new file mode 100644 index 00000000..a5aba092 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/TreeMap/TreeMap.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Charts +{ + public class TreeMap : BaseChart + { + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/AxisStripe.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/AxisStripe.cs new file mode 100644 index 00000000..97989857 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/AxisStripe.cs @@ -0,0 +1,814 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of Axis Stripes. + /// + [Editor("DevComponents.Charts.Design.AxisStripeCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class AxisStripeCollection : CustomNamedCollection + { + public AxisStripeCollection() + { + } + + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("Stripe")); + } + + #endregion + } + + /// + /// Element describing a color stripe on the chart. Each AxisStripe + /// is associated with a primary or Ancillary Axis. + /// + public class AxisStripe : ChartVisualElement, ILegendItem + { + #region Private variables + + private States _States; + + private object _MinValue; + private object _MaxValue; + private AxisStripeVisualStyle _AxisStripeVisualStyle; + + private string _LegendText; + private ChartLegendItem _LegendItem; + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + + #endregion + + #region Constructors + + /// + /// Create a new AxisStripe. + /// + /// + /// + /// + public AxisStripe(string name, object minValue, object maxValue) + : this() + { + Name = name; + + MinValue = minValue; + MaxValue = maxValue; + } + + /// + /// Create a new AxisStripe. + /// + /// + public AxisStripe(string name) + : this() + { + Name = name; + } + + /// + /// Create a new AxisStripe. + /// + public AxisStripe() + { + InitDefaultStates(); + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.CheckedInLegend, true); + SetState(States.ShowInLegend, true); + SetState(States.ShowInParentLegend, true); + SetState(States.ShowCheckBoxInLegend, true); + SetState(States.ShowMarkerInLegend, true); + } + + #endregion + + #region Public properties + + #region AxisStripeVisualStyle + + /// + /// Gets or sets the visual style for the AxisStripe. + /// + [Category("Style")] + [Description("Indicates the visual style for the AxisStripe.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public AxisStripeVisualStyle AxisStripeVisualStyle + { + get + { + if (_AxisStripeVisualStyle == null) + { + _AxisStripeVisualStyle = new AxisStripeVisualStyle(); + + StyleVisualChangeHandler(null, _AxisStripeVisualStyle); + } + + return (_AxisStripeVisualStyle); + } + + set + { + if (_AxisStripeVisualStyle != value) + { + AxisStripeVisualStyle oldValue = _AxisStripeVisualStyle; + + _AxisStripeVisualStyle = value; + + OnVisualStyleChanged("AxisStripeVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region IsDisplayed + + /// + /// Gets whether the Stripe is displayed (must be Visible + /// and appropriately 'checked' if presented in the Legend). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDisplayed + { + get + { + return ((Visible == true) && + (ShowCheckBoxInLegend == false || CheckedInLegend == true)); + } + } + + #endregion + + #region MaxValue + + /// + /// Gets or sets the maximum axis stripe value. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the maximum axis stripe value.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object MaxValue + { + get { return (_MaxValue); } + + set + { + if (value != _MaxValue) + { + _MaxValue = value; + + OnPropertyChangedEx("MaxValue", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinValue + + /// + /// Gets or sets the minimum axis stripe value. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the minimum axis stripe value.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object MinValue + { + get { return (_MinValue); } + + set + { + if (value != _MinValue) + { + _MinValue = value; + + OnPropertyChangedEx("MinValue", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + } + + #endregion + + #region Style support + + #region InvalidateStyle + + /// + ///Invalidate the cached Styles + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + if (LegendItem != null) + LegendItem.EffectiveStyles.InvalidateStyles(); + } + + #endregion + + #region StyleChanged + + protected override void StyleChanged(object sender, PropertyChangedEventArgs e) + { + base.StyleChanged(sender, e); + + if (sender is ChartLegendItemVisualStyles && LegendItem != null) + InvalidateRender(LegendItem.Bounds); + } + + #endregion + + #endregion + + #region ILegendItem + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the visual styles for the Legend item. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Legend item.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleVisualChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (_ChartLegendItemVisualStyles != value) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CheckedInLegend + + /// + /// Gets or sets whether the ReferenceLine is checked in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the ReferenceLine is checked in the Legend.")] + public bool CheckedInLegend + { + get { return (TestState(States.CheckedInLegend)); } + + set + { + if (value != CheckedInLegend) + { + SetState(States.CheckedInLegend, value); + + if (LegendItem != null) + LegendItem.UpdateCheckState(); + + OnPropertyChangedEx("CheckedInLegend", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowCheckBoxInLegend + + /// + /// Gets or sets whether a checkbox for the ReferenceLine is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether a checkbox for the ReferenceLine is shown in the Legend.")] + public bool ShowCheckBoxInLegend + { + get { return (TestState(States.ShowCheckBoxInLegend)); } + + set + { + if (value != ShowCheckBoxInLegend) + { + SetState(States.ShowCheckBoxInLegend, value); + + OnPropertyChangedEx("ShowCheckBoxInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInLegend + + /// + /// Gets or sets whether the ReferenceLine is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the ReferenceLine is shown in the Legend.")] + public bool ShowInLegend + { + get { return (TestState(States.ShowInLegend)); } + + set + { + if (value != ShowInLegend) + { + SetState(States.ShowInLegend, value); + + OnPropertyChangedEx("ShowInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInParentLegend + + /// + /// Gets or sets whether the Reference Line is shown in parent Legend(s). + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the Reference Line is shown in parent Legend(s).")] + public bool ShowInParentLegend + { + get { return (TestState(States.ShowInParentLegend)); } + + set + { + if (value != ShowInParentLegend) + { + SetState(States.ShowInParentLegend, value); + + OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowMarkerInLegend + + /// + /// Gets or sets whether the ReferenceLine Marker is shown in the Legend. + /// + [DefaultValue(true), Category("Legend")] + [Description("Indicates whether the ReferenceLine Marker is shown in the Legend.")] + public bool ShowMarkerInLegend + { + get { return (TestState(States.ShowMarkerInLegend)); } + + set + { + if (value != ShowMarkerInLegend) + { + SetState(States.ShowMarkerInLegend, value); + + OnPropertyChangedEx("ShowMarkerInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LegendItem + + /// + /// Gets the item's parent LegendItem. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates the item's parent LegendItem.")] + public ChartLegendItem LegendItem + { + get { return (_LegendItem); } + internal set { _LegendItem = value; } + } + + #endregion + + #region LegendText + + /// + /// Gets or sets the text to display in the legend. + /// + [DefaultValue(null), Category("Legend")] + [Description("Indicates the text to display in the legend.")] + [NotifyParentProperty(true)] + public string LegendText + { + get { return (_LegendText); } + + set + { + if (value != _LegendText) + { + _LegendText = value; + + OnPropertyChangedEx("LegendText", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region GetLegendItem + + /// + /// Creates the LegendItem for the AxisStripe. + /// + /// + public ChartLegendItem GetLegendItem() + { + _LegendItem = null; + + if (ShowInLegend == true) + { + _LegendItem = new ChartLegendItem(); + + if (CheckedInLegend == true) + _LegendItem.CheckState = CheckState.Checked; + + _LegendItem.Name = Name; + _LegendItem.ItemText = LegendText; + + if (string.IsNullOrEmpty(_LegendItem.Name) == true) + _LegendItem.Name = "(RefLine)"; + + _LegendItem.ChartItems.Add(this); + } + + return (_LegendItem); + } + + #endregion + + #region GetLegendItems + + /// + /// Creates a list of legend items associated with + /// the AxisStripe. + /// + /// + public List GetLegendItems() + { + List list = null; + + ChartLegendItem item = GetLegendItem(); + + if (item != null) + { + list = new List(1); + + list.Add(item); + } + + return (list); + } + + #endregion + + #region GetLegendItemColor + + /// + /// Gets the default color associated with the + /// AxisStripe legend item. + /// + /// + public Color GetLegendItemColor() + { + AxisStripeVisualStyle astyle = AxisStripeVisualStyle; + + Color color = astyle.Background.Color1; + + if (color.IsEmpty == false) + return (color); + + return (Color.DimGray); + } + + #endregion + + #region RenderLegendItemMarker + + /// + /// Renders the Legend item Marker. + /// + /// + /// + /// + public void RenderLegendItemMarker(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + AxisStripeVisualStyle astyle = AxisStripeVisualStyle; + + Rectangle bounds = litem.MarkerBounds; + + if (astyle.Background.IsEmpty == true) + { + g.FillRectangle(Brushes.LightPink, bounds); + } + else + { + using (Brush br = astyle.Background.GetBrush(bounds)) + g.FillRectangle(br, bounds); + } + } + + #endregion + + #endregion + + #region Copy/CopyTo + + /// + /// Creates a copy of the element. + /// + /// + public override ChartVisualElement Copy() + { + AxisStripe copy = new AxisStripe(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the current element properties and styles + /// to the provided "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + AxisStripe c = copy as AxisStripe; + + if (c != null) + { + base.CopyTo(c); + + c.AxisStripeVisualStyle = (_AxisStripeVisualStyle != null) ? _AxisStripeVisualStyle.Copy() : null; + c.ChartLegendItemVisualStyles = (_ChartLegendItemVisualStyles != null) ? ChartLegendItemVisualStyles.Copy() : null; + + c.MaxValue = MaxValue; + c.MinValue = MinValue; + + c.CheckedInLegend = CheckedInLegend; + c.ShowCheckBoxInLegend = ShowCheckBoxInLegend; + c.ShowInLegend = ShowInLegend; + c.ShowInParentLegend = ShowInParentLegend; + c.LegendText = LegendText; + c.ShowMarkerInLegend = ShowMarkerInLegend; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartAxis"; + + sec.AddStartElement(serialName); + } + + if (_AxisStripeVisualStyle != null && _AxisStripeVisualStyle.IsEmpty == false) + sec.AddElement(_AxisStripeVisualStyle.GetSerialData("AxisStripeVisualStyle")); + + if (_ChartLegendItemVisualStyles != null) + sec.AddElement(_ChartLegendItemVisualStyles.GetSerialData("ChartLegendItemVisualStyles")); + + sec.AddDataValue("MaxValue", MaxValue, null); + sec.AddDataValue("MinValue", MinValue, null); + + sec.AddValue("CheckedInLegend", CheckedInLegend, true); + sec.AddValue("LegendText", LegendText, null); + sec.AddValue("ShowCheckBoxInLegend", ShowCheckBoxInLegend, true); + sec.AddValue("ShowInLegend", ShowInLegend, true); + sec.AddValue("ShowInParentLegend", ShowInParentLegend, true); + sec.AddValue("ShowMarkerInLegend", ShowMarkerInLegend, true); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "CheckedInLegend": + CheckedInLegend = bool.Parse(se.StringValue); + break; + + case "LegendText": + LegendText = se.StringValue; + break; + + case "MaxValue": + MaxValue = se.DataValue; + break; + + case "MinValue": + MinValue = se.DataValue; + break; + + case "ShowCheckBoxInLegend": + ShowCheckBoxInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInLegend": + ShowInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInParentLegend": + ShowInParentLegend = bool.Parse(se.StringValue); + break; + + case "ShowMarkerInLegend": + ShowMarkerInLegend = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "AxisStripeVisualStyle": + sec.PutSerialData(AxisStripeVisualStyle); + break; + + case "ChartLegendItemVisualStyles": + sec.PutSerialData(ChartLegendItemVisualStyles); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #region GetAncillaryAxis + + private ChartAxis GetAncillaryAxis(ChartAxesCollection axes, string name) + { + foreach (ChartAxis axis in axes) + { + if (name.Equals(axis.Name) == true) + return (axis); + } + + return (null); + } + + #endregion + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + CheckedInLegend = (1U << 1), + ShowCheckBoxInLegend = (1U << 2), + ShowInLegend = (1U << 3), + ShowInParentLegend = (1U << 4), + ShowMarkerInLegend = (1U << 5), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + AxisStripeVisualStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartAxes.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartAxes.cs new file mode 100644 index 00000000..61cced46 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartAxes.cs @@ -0,0 +1,5491 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of Chart AxesX. + /// + [Editor("DevComponents.Charts.Design.ChartAxesCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartAxesXCollection : ChartAxesCollection + { + public ChartAxesXCollection() + : base(AxisOrientation.X) + { + } + + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("AncAxisX")); + } + + #endregion + } + + /// + /// Represents the collection of Chart AxesY. + /// + [Editor("DevComponents.Charts.Design.ChartAxesCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartAxesYCollection : ChartAxesCollection + { + public ChartAxesYCollection() + : base(AxisOrientation.Y) + { + } + + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("AncAxisY")); + } + + #endregion + } + + /// + /// Represents the collection of Chart Axes. + /// + public class ChartAxesCollection : CustomNamedCollection + { + #region Private variables + + private AxisOrientation _AxisOrientation; + + #endregion + + public ChartAxesCollection(AxisOrientation axisOrientation) + { + _AxisOrientation = axisOrientation; + } + + #region Public properties + + #region AxisOrientation + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AxisOrientation AxisOrientation + { + get { return (_AxisOrientation); } + } + + #endregion + + #endregion + + #region InsertItem + + protected override void InsertItem(int index, ChartAxis item) + { + if (item.IsPrimaryAxis == true) + throw new Exception("Primary Axes cannot be added as Ancillary Axes."); + + base.InsertItem(index, item); + } + + #endregion + } + + #region ChartAxisX + + /// + /// Represents an X-Axis element. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartAxisX : ChartAxis + { + #region Constructors + + public ChartAxisX() + : base(AxisOrientation.X) + { + } + + public ChartAxisX(string name) + : base(AxisOrientation.X) + { + Name = name; + } + + public ChartAxisX(string name, object minValue, object maxValue) + : base(AxisOrientation.X) + { + Name = name; + + MinValue = minValue; + MaxValue = MaxValue; + } + + #endregion + + #region Public properties + + #region MajorGridLines + + /// + /// Gets the axis MajorGridLines element. + /// + [Description("Indicates the MajorGridLines element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public override ChartMajorGridLines MajorGridLines + { + get + { + if (_MajorGridLines == null) + { + _MajorGridLines = new ChartMajorGridLinesX(); + _MajorGridLines.Parent = this; + } + + return (_MajorGridLines); + } + } + + #endregion + + #region MajorTickmarks + + /// + /// Gets the axis MajorTickmarks element. + /// + [Description("Indicates the MajorTickmarks element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public override MajorTickmarks MajorTickmarks + { + get + { + if (_MajorTickmarks == null) + { + _MajorTickmarks = new MajorTickmarksX(); + _MajorTickmarks.Parent = this; + } + + return (_MajorTickmarks); + } + } + + #endregion + + #region MinorGridLines + + /// + /// Gets the axis MinorGridLines element. + /// + [Description("Indicates the MinorGridLines element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public override ChartMinorGridLines MinorGridLines + { + get + { + if (_MinorGridLines == null) + { + _MinorGridLines = new ChartMinorGridLinesX(); + _MinorGridLines.Parent = this; + } + + return (_MinorGridLines); + } + } + + #endregion + + #region MinorTickmarks + + /// + /// Gets the axis MinorTickmarks element. + /// + [Description("Indicates the MinorTickmarks element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public override MinorTickmarks MinorTickmarks + { + get + { + if (_MinorTickmarks == null) + { + _MinorTickmarks = new MinorTickmarksX(); + _MinorTickmarks.Parent = this; + } + + return (_MinorTickmarks); + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + ChartXy chartXy = Parent as ChartXy; + + ChartAxisVisualStyle astyle = EffectiveAxisStyle; + AxisAlignment axisAlignment = GetAxisAlignment(); + + Rectangle bounds = layoutInfo.LayoutBounds; + + if (Visible == true) + { + MeasureTitle(layoutInfo, axisAlignment); + + int width = Math.Max(layoutInfo.LayoutBounds.Width, Dpi.Width(chartXy.MinContentSize.Width)); + + int tickmarkLen = MeasureTickmarks(layoutInfo, width); + + bounds.Height = GetMeasuredHeight(); + + layoutInfo.LayoutBounds.Height -= tickmarkLen; + + if (axisAlignment == AxisAlignment.Far) + { + layoutInfo.LayoutBounds.Y += tickmarkLen; + } + else + { + bounds.Y = layoutInfo.LayoutBounds.Bottom; + + if (EdgeAxis == true) + { + bounds.Y--; + + if (chartXy.DropShadowDisplayed == true) + layoutInfo.LayoutBounds.Height += 3; + } + } + } + else + { + int width = Math.Max(layoutInfo.LayoutBounds.Width, Dpi.Width(chartXy.MinContentSize.Width)); + + MeasureTickmarks(layoutInfo, width); + + bounds.Height = 0; + } + + CalcAxisBounds(layoutInfo, axisAlignment, bounds); + + BoundsRelative = bounds; + + base.MeasureOverride(layoutInfo); + } + + #region MeasureTitle + + protected void MeasureTitle( + ChartLayoutInfo layoutInfo, AxisAlignment axisAlignment) + { + if (Title.Visible == true) + { + Title.XyAlignment = (axisAlignment == AxisAlignment.Near) + ? XyAlignment.Bottom : XyAlignment.Top; + + Title.Measure(layoutInfo); + } + } + + #endregion + + #region MeasureTickmarks + + protected virtual int MeasureTickmarks(ChartLayoutInfo layoutInfo, int width) + { + CalcMajorSpacing(layoutInfo, width); + + MajorTickmarks.TickmarkLayout = TickmarkLayout; + MinorTickmarks.TickmarkLayout = TickmarkLayout; + + MajorTickmarks.Measure(layoutInfo); + MinorTickmarks.Measure(layoutInfo); + + return (Math.Max(MajorTickmarks.Size.Height, + MinorTickmarks.Size.Height)); + } + + #endregion + + #region GetMeasuredHeight + + private int GetMeasuredHeight() + { + int height = Math.Max(MajorTickmarks.Size.Height, + MinorTickmarks.Size.Height); + + if (Title.Visible == true) + height += Title.Size.Height; + + return (height); + } + + #endregion + + #region CalcAxisBounds + + private void CalcAxisBounds(ChartLayoutInfo layoutInfo, + AxisAlignment axisAlignment, Rectangle bounds) + { + ChartXy chartXy = Parent as ChartXy; + + int labelHeight = 0; + int tmInnerLength = 0; + int tmOuterLength = 0; + + if (TickmarkLayout.MajorCount > 0) + { + labelHeight = MajorTickmarks.GetTotalLabelHeight(); + + tmOuterLength = Dpi.Width(GetMaxTickMarkLength(false)); + tmInnerLength = Dpi.Width(GetMaxTickMarkLength(true)); + + if (axisAlignment == AxisAlignment.Near) + { + if (EdgeAxis == true) + { + if (chartXy.HScrollBar.Visible == true) + tmInnerLength += (chartXy.HScrollBar.Height + 1); + + bounds.Y -= tmInnerLength; + } + } + else + { + if (Title.Visible == true) + bounds.Y += Title.Size.Height; + } + + bounds.Height = (labelHeight + tmOuterLength + tmInnerLength + 1); + + AxisBounds = bounds; + + Rectangle r = bounds; + r.Height = 1; + + if (axisAlignment == AxisAlignment.Near) + { + r.Y += tmInnerLength; + + if (EdgeAxis == false) + r.Y += 1; + } + else + { + r.Y = bounds.Bottom - tmInnerLength - 1; + } + + AxisLineBounds = r; + } + } + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + ChartXy chartXy = Parent as ChartXy; + + // Let the axis bounds extend into the chart's frame + // area as much as possible for better label display. + + Rectangle r = AxisBounds; + r.Width = chartXy.ContentBounds.Width; + + int n1 = r.X - chartXy.FrameBounds.X; + int n2 = chartXy.FrameBounds.Right - r.Right; + + r.X = chartXy.FrameBounds.X; + r.Width += (n1 + n2); + + AxisBounds = r; + + r = AxisLineBounds; + r.Width = chartXy.ContentBounds.Width; + AxisLineBounds = r; + + base.ArrangeOverride(layoutInfo); + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + if (Visible == true) + { + base.RenderOverride(renderInfo); + + Graphics g = renderInfo.Graphics; + ChartAxisVisualStyle astyle = EffectiveAxisStyle; + + if (TickmarkLayout.MajorCount > 0) + { + Rectangle axisBounds = GetScrollBounds(AxisBounds); + + Region clip = g.Clip; + g.SetClip(axisBounds, CombineMode.Intersect); + + MajorTickmarks.Render(renderInfo); + MinorTickmarks.Render(renderInfo); + + RenderAxisLine(g, astyle); + + g.Clip = clip; + } + } + } + + #region RenderAxisLine + + private void RenderAxisLine(Graphics g, ChartAxisVisualStyle astyle) + { + if (astyle.AxisColor.IsEmpty == false && + astyle.AxisColor.Equals(Color.Transparent) == false) + { + Rectangle alBounds = GetScrollBounds(AxisLineBounds); + + using (Pen pen = new Pen(astyle.AxisColor, Dpi.Height1)) + g.DrawLine(pen, alBounds.X, alBounds.Y, alBounds.Right - 1, alBounds.Y); + } + } + + #endregion + + #endregion + + #region RenderCrosshairLabel (Point) + + internal override void RenderCrosshairLabel(Graphics g, Point pt) + { + TickmarkLayout layout = TickmarkLayout; + + if (layout != null && layout.Ticks != null && layout.Ticks.Length > 0) + { + TickmarkTick tick = layout.Ticks[0]; + CrosshairValueVisualStyle lstyle = EffectiveCrosshairLabelStyle; + + string text = GetCrosshairLabel(pt, layout, tick, lstyle); + + if (string.IsNullOrEmpty(text) == false) + { + Rectangle r = GetCrosshairBounds(g, text, pt, lstyle); + + lstyle.RenderBackground(g, r); + lstyle.RenderBorder(g, r); + + if (lstyle.DropShadow.Enabled == Tbool.True) + lstyle.DropShadow.RenderDropShadow(g, r, true, true); + + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + using (Brush br = new SolidBrush(lstyle.TextColor)) + g.DrawString(text, lstyle.Font, br, r, sf); + } + } + } + } + + #region GetCrosshairLabel + + private string GetCrosshairLabel(Point pt, + TickmarkLayout layout, TickmarkTick tick, CrosshairValueVisualStyle lstyle) + { + object value = null; + + switch (ScaleType) + { + case ScaleType.DateTime: + value = GetValueFromPoint(layout, pt); + break; + + case ScaleType.Qualitative: + pt = GetChartPoint(pt); + + int n = (int)Math.Floor((pt.X - (layout.NearMargin + layout.MarginOffset - + layout.MajorInterval / 2 + tick.TickPoint.X)) / (layout.MajorInterval * layout.MajorSpacing)); + + n += tick.Index; + + if ((uint)n < QualitativeValues.Count) + value = QualitativeValues[n]; + break; + + case ScaleType.Quantitative: + double dvalue = Convert.ToDouble(GetValueFromPoint(layout, pt)); + + if (DotPlotAxis == true && Math.Floor(layout.MajorSpacing) == layout.MajorSpacing) + dvalue = Math.Floor(dvalue + .5); + + value = dvalue; + break; + } + + return (GetCrosshairLabel(value, lstyle)); + } + + #endregion + + #region GetCrosshairBounds + + private Rectangle GetCrosshairBounds(Graphics g, + string text, Point pt, CrosshairValueVisualStyle lstyle) + { + Rectangle bounds = GetScrollBounds(MajorTickmarks.LabelBounds); + Rectangle r = bounds; + + SizeF sizef = g.MeasureString(text, lstyle.Font); + + r.Width = (int)(sizef.Width + 2); + r.Height = (int)(sizef.Height + 2); + + r.X = pt.X - (int)(sizef.Width / 2); + r.Y--; + + AxisAlignment axisalignment = GetAxisAlignment(); + + if (lstyle.Margin.IsEmpty == false) + { + if (axisalignment == AxisAlignment.Near) + r.Y += lstyle.Margin.Top; + else + r.Y -= lstyle.Margin.Bottom; + } + + if (axisalignment == AxisAlignment.Near) + r.Y += (lstyle.BorderThickness.Vertical); + else + r.Y -= (lstyle.BorderThickness.Vertical); + + r.Height += lstyle.BorderThickness.Vertical; + + if (lstyle.Padding.IsEmpty == false) + { + if (axisalignment == AxisAlignment.Far) + r.Y -= lstyle.Padding.Vertical; + + r.Height += lstyle.Padding.Vertical; + + r.X -= lstyle.Padding.Left; + r.Width += lstyle.Padding.Horizontal; + } + + if (r.Bottom > bounds.Bottom) + r.Y -= (r.Bottom - bounds.Bottom); + + if (r.Right > bounds.Right) + r.X -= (r.Right - bounds.Right); + + return (r); + } + + #endregion + + #endregion + + #region RenderCrosshairLabel (CrosshairPoint) + + internal override void RenderCrosshairLabel(Graphics g, CrosshairPoint cp) + { + CrosshairValueVisualStyle lstyle = EffectiveCrosshairLabelStyle; + + string text = (cp.ChartSeries.IsRotated == false) + ? GetCrosshairLabel(cp.SeriesPoint.ValueX, lstyle) + : GetCrosshairLabel(cp.SeriesPoint.ValueY[cp.ValueIndex], lstyle); + + if (string.IsNullOrEmpty(text) == false) + { + Rectangle r = GetCrosshairBounds(g, text, cp.Point, lstyle); + + lstyle.RenderBackground(g, r); + lstyle.RenderBorder(g, r); + + if (lstyle.DropShadow.Enabled == Tbool.True) + lstyle.DropShadow.RenderDropShadow(g, r, true, true); + + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + using (Brush br = new SolidBrush(lstyle.TextColor)) + g.DrawString(text, lstyle.Font, br, r, sf); + } + } + } + + #endregion + + #region RenderBackground + + internal override void RenderBackground(ChartRenderInfo renderInfo, Rectangle scContentBounds) + { + if (UseAlternateBackground == true) + { + if (TickmarkLayout.Ticks != null) + { + Graphics g = renderInfo.Graphics; + ChartXy chartXy = Parent as ChartXy; + + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + if (ScaleType == ScaleType.Qualitative) + pt.X -= (int)(TickmarkLayout.MajorInterval / 2); + + ChartAxisVisualStyle astyle = EffectiveAxisStyle; + + if (astyle.AlternateBackground.IsSolidBrush == true) + { + using (Brush br = astyle.AlternateBackground.GetBrush(Rectangle.Empty)) + { + RenderAltBackground(g, + scContentBounds, pt, TickmarkLayout, astyle, br); + } + } + else + { + RenderAltBackground(g, + scContentBounds, pt, TickmarkLayout, astyle, null); + } + } + } + } + + #region RenderAltBackground + + private void RenderAltBackground(Graphics g, Rectangle scContentBounds, + Point pt, TickmarkLayout TickmarkLayout, ChartAxisVisualStyle astyle, Brush br) + { + foreach (TickmarkTick tmi in TickmarkLayout.Ticks) + { + double value = GetTickmarkAltValue(tmi); + int n = (int)(Math.Ceiling(value / TickmarkLayout.MajorSpacing)); + + if (n % 2 == 0) + { + Rectangle r = scContentBounds; + r.X = tmi.TickPoint.X + pt.X; + r.Width = (int)TickmarkLayout.MajorInterval + 1; + + if (br == null) + { + using (Brush br2 = astyle.AlternateBackground.GetBrush(r)) + g.FillRectangle(br2, r); + } + else + { + g.FillRectangle(br, r); + } + } + } + } + + #endregion + + #endregion + + #region RenderStripes + + internal override void RenderStripes(ChartRenderInfo renderInfo, Rectangle scContentBounds) + { + if (AxisStripes.Count > 0) + { + Graphics g = renderInfo.Graphics; + ChartXy chartXy = Parent as ChartXy; + + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + foreach (AxisStripe stripe in AxisStripes) + { + if (stripe.IsDisplayed == true) + { + if (stripe.MinValue != stripe.MaxValue) + { + int x1 = chartXy.GetDataPointX(this, stripe.MinValue); + int x2 = chartXy.GetDataPointX(this, stripe.MaxValue); + + Rectangle r = scContentBounds; + r.X = (x1 + pt.X); + r.Width = (x2 - x1); + + RenderStripe(g, r, stripe); + } + } + } + } + } + + #endregion + + #region UpdateRangeValues + + internal override void UpdateRangeValues(ChartXy chartXy) + { + bool seriesSeen = false; + + foreach (ChartSeries series in chartXy.ChartSeries) + { + if (series.AxisX == this) + { + if (series.SeriesPoints.Count > 0) + UpdateRangeValuesEx(chartXy, series, ref seriesSeen); + } + } + + if (seriesSeen == false) + { + foreach (ChartSeries series in chartXy.ChartSeries) + { + if (series.AxisX == null) + { + if (series.SeriesPoints.Count > 0) + UpdateRangeValuesEx(chartXy, series, ref seriesSeen); + } + } + } + } + + #region UpdateRangeValuesEx + + private void UpdateRangeValuesEx(ChartXy chartXy, ChartSeries series, ref bool seriesSeen) + { + if (ActualMinValue == null) + { + ActualMinValue = series.MinValueX; + ActualMaxValue = series.MaxValueX; + } + else + { + if (chartXy.DataCompare(series.MinValueX, ActualMinValue) < 0) + ActualMinValue = series.MinValueX; + + if (chartXy.DataCompare(series.MaxValueX, ActualMaxValue) > 0) + ActualMaxValue = series.MaxValueX; + } + + if (seriesSeen == false) + { + seriesSeen = true; + + ScaleType = series.ActualScaleTypeX; + } + else + { + if (series.ActualScaleTypeX != ScaleType) + { + string s = "XAxis cannot contain series with differing ScaleTypes"; + + if (String.IsNullOrEmpty(Name) == false) + s += " (" + Name + ")"; + + throw new Exception(s); + } + } + + if (ScaleType == ScaleType.Qualitative) + { + if (series.IsRotated == true) + { + foreach (object o in series.QualitativeYValues) + { + if (QualitativeValues.Contains(o) == false) + QualitativeValues.Add(o); + } + } + else + { + foreach (object o in series.QualitativeXValues) + { + if (QualitativeValues.Contains(o) == false) + QualitativeValues.Add(o); + } + } + + if (QualitativeValues.Count - 1 > (int)ActualMaxValue) + ActualMaxValue = QualitativeValues.Count - 1; + } + } + + #endregion + + #endregion + + #region GetValueFromPoint + + internal override object GetValueFromPoint(TickmarkLayout layout, Point pt) + { + if (layout.Ticks != null) + { + pt = GetChartPoint(pt); + + TickmarkTick lastTick = null; + + foreach (TickmarkTick tick in layout.Ticks) + { + if (tick.TickPoint.X == pt.X) + return (tick.Value); + + if (tick.TickPoint.X > pt.X) + { + if (lastTick != null) + { + double d = ((double)tick.TickPoint.X - lastTick.TickPoint.X) / (layout.MinorCount + 1); + + for (int i = 1; i <= layout.MinorCount; i++) + { + int x = (int)(lastTick.TickPoint.X + (d * i)); + + if (x >= pt.X) + break; + } + } + break; + } + + lastTick = tick; + } + + int dx = pt.X - Bounds.X; + + switch (ScaleType) + { + case ScaleType.Qualitative: + return (layout.MajorSpacing * ((dx + layout.MarginOffset) / + layout.MajorInterval) + (int)layout.BaseValue); + + case ScaleType.DateTime: + return (GetDateTimePointValue(layout, dx)); + + default: + return (layout.MajorSpacing * ((dx + layout.MarginOffset) / + layout.MajorInterval) + Convert.ToDouble(layout.BaseValue)); + } + } + + return (null); + } + + #endregion + + #region GetPointFromValue + + /// + /// Gets the chart Point from the given axis data value. + /// + /// + /// + public override Point GetPointFromValue(object value) + { + return (new Point(GetDisplayValue(value), 0)); + } + + #endregion + + #region GetDisplayValue + + internal override int GetDisplayValue(object axisValue) + { + ChartXy chartXy = Parent as ChartXy; + + return (chartXy.GetDataPointX(this, axisValue)); + } + + #endregion + + #region EnsureVisible + + /// + /// Ensures the given data value is visible and + /// optionally centered on screen. + /// + /// + public override void EnsureVisible(object value, bool center) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + { + if (chartXy.ChartControl != null) + { + if (chartXy.ChartControl.LayoutValid == false) + chartXy.ChartControl.UpdateLayout(); + + Rectangle cbounds = chartXy.ContentBounds; + + int x = GetDisplayValue(value); + + if (center == true) + { + int n = (x - cbounds.Width / 2) - cbounds.X; + + chartXy.HScrollOffset = n; + } + else + { + int n = cbounds.X + chartXy.HScrollOffset + 20; + + if (x < n) + { + chartXy.HScrollOffset += (x - n); + } + else + { + n = cbounds.Right + chartXy.HScrollOffset - 20; + + if (x > n) + chartXy.HScrollOffset += (x - n); + } + } + } + } + } + + #endregion + + #region Copy/CopyTo + + /// + /// Creates a copy of the axis. + /// + /// + public override ChartVisualElement Copy() + { + ChartAxisX copy = new ChartAxisX(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the current axis properties to the + /// given "copy" axis. + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + ChartAxisX c = copy as ChartAxisX; + + if (c != null) + { + base.CopyTo(c); + + MajorGridLines.CopyTo(c.MajorGridLines); + MinorGridLines.CopyTo(c.MinorGridLines); + + MajorTickmarks.CopyTo(c.MajorTickmarks); + MinorTickmarks.CopyTo(c.MinorTickmarks); + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartAxisX"; + + sec.AddStartElement(serialName); + } + + sec.AddElement(MajorGridLines.GetSerialData("MajorGridLines")); + sec.AddElement(MinorGridLines.GetSerialData("MinorGridLines")); + sec.AddElement(MajorTickmarks.GetSerialData("MajorTickmarks")); + sec.AddElement(MinorTickmarks.GetSerialData("MinorTickmarks")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "MajorGridLines": + sec.PutSerialData(MajorGridLines); + break; + + case "MinorGridLines": + sec.PutSerialData(MinorGridLines); + break; + + case "MajorTickmarks": + sec.PutSerialData(MajorTickmarks); + break; + + case "MinorTickmarks": + sec.PutSerialData(MinorTickmarks); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + } + + #endregion + + #region ChartAxisY + + /// + /// Represents a Y-Axis element. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartAxisY : ChartAxis + { + #region Constructors + + public ChartAxisY() + : base(AxisOrientation.Y) + { + } + + public ChartAxisY(string name) + : base(AxisOrientation.Y) + { + Name = name; + } + + public ChartAxisY(string name, object minValue, object maxValue) + : base(AxisOrientation.Y) + { + Name = name; + + MinValue = minValue; + MaxValue = MaxValue; + } + + #endregion + + #region Public properties + + #region MajorGridLines + + /// + /// Gets the axis MajorGridLines element. + /// + [Description("Indicates the MajorGridLines element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public override ChartMajorGridLines MajorGridLines + { + get + { + if (_MajorGridLines == null) + { + _MajorGridLines = new ChartMajorGridLinesY(); + _MajorGridLines.Parent = this; + } + + return (_MajorGridLines); + } + } + + #endregion + + #region MajorTickmarks + + /// + /// Gets the axis MajorTickmarks element. + /// + [Description("Indicates the MajorTickmarks element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public override MajorTickmarks MajorTickmarks + { + get + { + if (_MajorTickmarks == null) + { + _MajorTickmarks = new MajorTickmarksY(); + _MajorTickmarks.Parent = this; + } + + return (_MajorTickmarks); + } + } + + #endregion + + #region MinorGridLines + + /// + /// Gets the axis MinorGridLines element. + /// + [Description("Indicates the MinorGridLines element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public override ChartMinorGridLines MinorGridLines + { + get + { + if (_MinorGridLines == null) + { + _MinorGridLines = new ChartMinorGridLinesY(); + _MinorGridLines.Parent = this; + } + + return (_MinorGridLines); + } + } + + #endregion + + #region MinorTickmarks + + /// + /// Gets the axis MinorTickmarks element. + /// + [Description("Indicates the MinorTickmarks element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public override MinorTickmarks MinorTickmarks + { + get + { + if (_MinorTickmarks == null) + { + _MinorTickmarks = new MinorTickmarksY(); + _MinorTickmarks.Parent = this; + } + + return (_MinorTickmarks); + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + ChartXy chartXy = Parent as ChartXy; + + ChartAxisVisualStyle astyle = EffectiveAxisStyle; + AxisAlignment axisAlignment = GetAxisAlignment(); + + Rectangle bounds = layoutInfo.LayoutBounds; + + if (Visible == true) + { + MeasureTitle(layoutInfo, axisAlignment); + + int height = Math.Max(layoutInfo.LayoutBounds.Height, Dpi.Height((chartXy.MinContentSize.Height))); + int tickmarkLen = MeasureTickmarks(layoutInfo, height); + + bounds.Width = GetMeasuredWidth(); + + layoutInfo.LayoutBounds.Width -= tickmarkLen; + + if (axisAlignment == AxisAlignment.Far) + { + layoutInfo.LayoutBounds.X += tickmarkLen; + } + else + { + bounds.X = layoutInfo.LayoutBounds.Right; + + if (EdgeAxis == true) + { + bounds.X -= 1; + + if (chartXy.DropShadowDisplayed == true) + layoutInfo.LayoutBounds.Width += 3; + } + } + } + else + { + int height = Math.Max(layoutInfo.LayoutBounds.Height, Dpi.Height(chartXy.MinContentSize.Height)); + int tickmarkLen = MeasureTickmarks(layoutInfo, height); + + bounds.Width = 0; + } + + CalcAxisBounds(layoutInfo, axisAlignment, bounds); + + BoundsRelative = bounds; + + base.MeasureOverride(layoutInfo); + } + + #region MeasureTitle + + protected void MeasureTitle( + ChartLayoutInfo layoutInfo, AxisAlignment axisAlignment) + { + if (Title.Visible == true) + { + Title.XyAlignment = (axisAlignment == AxisAlignment.Near) + ? XyAlignment.Right : XyAlignment.Left; + + Title.Measure(layoutInfo); + } + } + + #endregion + + #region MeasureTickmarks + + protected virtual int MeasureTickmarks(ChartLayoutInfo layoutInfo, int height) + { + CalcMajorSpacing(layoutInfo, height); + + MajorTickmarks.TickmarkLayout = TickmarkLayout; + MinorTickmarks.TickmarkLayout = TickmarkLayout; + + MajorTickmarks.Measure(layoutInfo); + MinorTickmarks.Measure(layoutInfo); + + return (Math.Max(MajorTickmarks.Size.Width, + MinorTickmarks.Size.Width)); + } + + #endregion + + #region GetMeasuredWidth + + private int GetMeasuredWidth() + { + int width = Math.Max(MajorTickmarks.Size.Width, + MinorTickmarks.Size.Width); + + if (Title.Visible == true) + width += Title.Size.Width; + + return (width); + } + + #endregion + + #region CalcAxisBounds + + private void CalcAxisBounds(ChartLayoutInfo layoutInfo, + AxisAlignment axisAlignment, Rectangle bounds) + { + int labelWidth = 0; + int tmInnerLength = 0; + int tmOuterLength = 0; + + if (TickmarkLayout.MajorCount > 0) + { + labelWidth = MajorTickmarks.GetTotalLabelWidth(); + + tmOuterLength = Dpi.Width(GetMaxTickMarkLength(false)); + tmInnerLength = Dpi.Width(GetMaxTickMarkLength(true)); + + if (axisAlignment == AxisAlignment.Near) + { + if (EdgeAxis == true) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy.VScrollBar.Visible == true) + tmInnerLength += (chartXy.VScrollBar.Width + 1); + + bounds.X -= tmInnerLength; + } + } + else + { + if (Title.Visible == true) + bounds.X += Title.Size.Width; + } + + bounds.Width = (labelWidth + tmOuterLength + tmInnerLength + 1); + + AxisBounds = bounds; + + Rectangle r = bounds; + r.Width = 1; + + if (axisAlignment == AxisAlignment.Near) + { + r.X += tmInnerLength; + + if (EdgeAxis == false) + r.X += 1; + } + else + { + r.X = bounds.Right - tmInnerLength - 1; + } + + AxisLineBounds = r; + } + } + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + ChartXy chartXy = Parent as ChartXy; + + // Let the axis bounds extend into the chart's frame + // area as much as possible for better label display. + + Rectangle r = AxisBounds; + r.Height = chartXy.ContentBounds.Height; + + int n1 = r.Y - chartXy.FrameBounds.Y; + int n2 = chartXy.FrameBounds.Bottom - r.Bottom; + + r.Y = chartXy.FrameBounds.Y; + r.Height += (n1 + n2); + + AxisBounds = r; + + r = AxisLineBounds; + r.Height = chartXy.ContentBounds.Height; + AxisLineBounds = r; + + base.ArrangeOverride(layoutInfo); + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + base.RenderOverride(renderInfo); + + Graphics g = renderInfo.Graphics; + ChartAxisVisualStyle astyle = EffectiveAxisStyle; + + if (TickmarkLayout.MajorCount > 0) + { + Rectangle axisBounds = GetScrollBounds(AxisBounds); + + Region clip = g.Clip; + g.SetClip(axisBounds, CombineMode.Intersect); + + MajorTickmarks.Render(renderInfo); + MinorTickmarks.Render(renderInfo); + + RenderAxisLine(g, astyle); + + g.Clip = clip; + } + } + + #region RenderAxisLine + + private void RenderAxisLine(Graphics g, ChartAxisVisualStyle astyle) + { + if (astyle.AxisColor.IsEmpty == false && + astyle.AxisColor.Equals(Color.Transparent) == false) + { + Rectangle alBounds = GetScrollBounds(AxisLineBounds); + + using (Pen pen = new Pen(astyle.AxisColor, Dpi.Width1)) + g.DrawLine(pen, alBounds.X, alBounds.Y, alBounds.X, alBounds.Bottom - 1); + } + } + + #endregion + + #endregion + + #region RenderCrosshairLabel (Point) + + internal override void RenderCrosshairLabel(Graphics g, Point pt) + { + TickmarkLayout layout = TickmarkLayout; + + if (layout != null && layout.Ticks != null && layout.Ticks.Length > 0) + { + TickmarkTick tick = layout.Ticks[0]; + CrosshairValueVisualStyle lstyle = EffectiveCrosshairLabelStyle; + + string text = GetCrosshairLabel(pt, layout, tick, lstyle); + + if (string.IsNullOrEmpty(text) == false) + { + Rectangle r = GetCrosshairBounds(g, text, pt, lstyle); + + lstyle.RenderBackground(g, r); + lstyle.RenderBorder(g, r); + + if (lstyle.DropShadow.Enabled == Tbool.True) + lstyle.DropShadow.RenderDropShadow(g, r, true, true); + + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + using (Brush br = new SolidBrush(lstyle.TextColor)) + g.DrawString(text, lstyle.Font, br, r, sf); + } + } + } + } + + #region GetCrosshairLabel + + private string GetCrosshairLabel(Point pt, + TickmarkLayout layout, TickmarkTick tick, CrosshairValueVisualStyle lstyle) + { + object value = null; + + switch (ScaleType) + { + case ScaleType.DateTime: + value = GetValueFromPoint(layout, pt); + break; + + case ScaleType.Qualitative: + pt = GetChartPoint(pt); + + int n = (int)Math.Floor(((tick.TickPoint.Y - layout.NearMargin - layout.MarginOffset + + layout.MajorInterval / 2) - pt.Y) / (layout.MajorInterval * layout.MajorSpacing)); + + n += tick.Index; + + if ((uint)n < QualitativeValues.Count) + value = QualitativeValues[n]; + break; + + case ScaleType.Quantitative: + double dvalue = (Double)GetValueFromPoint(layout, pt); + + if (DotPlotAxis == true && Math.Floor(layout.MajorSpacing) == layout.MajorSpacing) + dvalue = Math.Floor(dvalue + .5); + + value = dvalue; + break; + } + + return (GetCrosshairLabel(value, lstyle)); + } + + #endregion + + #region GetCrosshairBounds + + private Rectangle GetCrosshairBounds(Graphics g, + string text, Point pt, CrosshairValueVisualStyle lstyle) + { + ChartXy chartXy = (ChartXy)Parent; + + AxisAlignment axisalignment = GetAxisAlignment(); + Rectangle r = GetScrollBounds(MajorTickmarks.LabelBounds); + ChartXyVisualStyle cstyle = chartXy.EffectiveChartStyle; + + if (axisalignment == AxisAlignment.Far) + { + r.X -= cstyle.Padding.Left; + r.Width += cstyle.Padding.Left; + } + else + { + r.Width += cstyle.Padding.Right; + } + + SizeF sizef = g.MeasureString(text, lstyle.Font); + + int width = (int) sizef.Width + 2; + + if (Visible == true) + width = Math.Min(r.Width, width); + + if (axisalignment == AxisAlignment.Far) + r.X = Math.Max(r.X, r.Right - width); + + r.Width = width; + + r.Y = pt.Y - (int)(sizef.Height / 2) - 2 - lstyle.BorderThickness.Top; + r.Height = (int)sizef.Height; + + if (lstyle.Margin.IsEmpty == false) + { + if (axisalignment == AxisAlignment.Near) + r.Y += lstyle.Margin.Top; + else + r.Y -= lstyle.Margin.Bottom; + } + + if (axisalignment == AxisAlignment.Near) + r.X += (lstyle.BorderThickness.Horizontal); + else + r.X -= (lstyle.BorderThickness.Horizontal); + + r.Width += lstyle.BorderThickness.Horizontal; + r.Height += lstyle.BorderThickness.Vertical; + + if (lstyle.Padding.IsEmpty == false) + { + if (axisalignment == AxisAlignment.Far) + r.Y -= lstyle.Padding.Vertical; + + r.Height += lstyle.Padding.Vertical; + + r.X -= lstyle.Padding.Left; + r.Width += lstyle.Padding.Horizontal; + } + + return (r); + } + + #endregion + + #endregion + + #region RenderCrosshairLabel (CrosshairPoint) + + internal override void RenderCrosshairLabel(Graphics g, CrosshairPoint cp) + { + if ((DotPlotAxis == true) || + (cp.SeriesPoint.ValueY == null || cp.SeriesPoint.ValueY.Length == 0)) + { + RenderCrosshairLabel(g, cp.Point); + } + else + { + CrosshairValueVisualStyle lstyle = EffectiveCrosshairLabelStyle; + + string text = (cp.ChartSeries.IsRotated == true) + ? GetCrosshairLabel(cp.SeriesPoint.ValueX, lstyle) + : GetCrosshairLabel(cp.SeriesPoint.ValueY[cp.ValueIndex], lstyle); + + if (string.IsNullOrEmpty(text) == false) + { + Rectangle r = GetCrosshairBounds(g, text, cp.Point, lstyle); + + lstyle.RenderBackground(g, r); + lstyle.RenderBorder(g, r); + + if (lstyle.DropShadow.Enabled == Tbool.True) + lstyle.DropShadow.RenderDropShadow(g, r, true, true); + + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + using (Brush br = new SolidBrush(lstyle.TextColor)) + g.DrawString(text, lstyle.Font, br, r, sf); + } + } + } + } + + #endregion + + #region RenderBackground + + internal override void RenderBackground(ChartRenderInfo renderInfo, Rectangle scContentBounds) + { + if (UseAlternateBackground == true) + { + if (TickmarkLayout.Ticks != null) + { + Graphics g = renderInfo.Graphics; + ChartXy chartXy = Parent as ChartXy; + + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + if (ScaleType == ScaleType.Qualitative) + pt.Y -= (int)(TickmarkLayout.MajorInterval / 2); + + ChartAxisVisualStyle astyle = EffectiveAxisStyle; + + if (astyle.AlternateBackground.IsSolidBrush == true) + { + using (Brush br = astyle.AlternateBackground.GetBrush(Rectangle.Empty)) + { + RenderAltBackground(g, + scContentBounds, pt, TickmarkLayout, astyle, br); + } + } + else + { + RenderAltBackground(g, + scContentBounds, pt, TickmarkLayout, astyle, null); + } + } + } + } + + #region RenderAltBackground + + private void RenderAltBackground(Graphics g, Rectangle scContentBounds, + Point pt, TickmarkLayout TickmarkLayout, ChartAxisVisualStyle astyle, Brush br) + { + foreach (TickmarkTick tmi in TickmarkLayout.Ticks) + { + double value = GetTickmarkAltValue(tmi); + int n = (int)(Math.Ceiling(value / TickmarkLayout.MajorSpacing)); + + if (n % 2 == 0) + { + Rectangle r = scContentBounds; + r.Y = tmi.TickPoint.Y + pt.Y; + r.Height = (int)TickmarkLayout.MajorInterval + 1; + + if (br == null) + { + using (Brush br2 = astyle.AlternateBackground.GetBrush(r)) + g.FillRectangle(br2, r); + } + else + { + g.FillRectangle(br, r); + } + } + } + } + + #endregion + + #endregion + + #region RenderStripes + + internal override void RenderStripes(ChartRenderInfo renderInfo, Rectangle scContentBounds) + { + if (AxisStripes.Count > 0) + { + Graphics g = renderInfo.Graphics; + ChartXy chartXy = Parent as ChartXy; + + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + foreach (AxisStripe stripe in AxisStripes) + { + if (stripe.IsDisplayed == true) + { + int y2 = chartXy.GetDataPointY(this, stripe.MinValue); + int y1 = chartXy.GetDataPointY(this, stripe.MaxValue); + + Rectangle r = scContentBounds; + r.Y = (y1 + pt.Y); + r.Height = (y2 - y1) + 1; + + RenderStripe(g, r, stripe); + } + } + } + } + + #endregion + + #region UpdateRangeValues + + internal override void UpdateRangeValues(ChartXy chartXy) + { + bool seriesSeen = false; + + foreach (ChartSeries series in chartXy.ChartSeries) + { + if (series.AxisY == this) + { + if (series.SeriesPoints.Count > 0) + UpdateRangeValuesEx(chartXy, series, ref seriesSeen); + } + } + + if (seriesSeen == false) + { + foreach (ChartSeries series in chartXy.ChartSeries) + { + if (series.AxisY == null) + { + if (series.SeriesPoints.Count > 0) + UpdateRangeValuesEx(chartXy, series, ref seriesSeen); + } + } + } + } + + #region UpdateRangeValuesEx + + private void UpdateRangeValuesEx(ChartXy chartXy, ChartSeries series, ref bool seriesSeen) + { + if (ActualMinValue == null) + { + ActualMinValue = series.MinValueY; + ActualMaxValue = series.MaxValueY; + } + else + { + if (chartXy.DataCompare(series.MinValueY, ActualMinValue) < 0) + ActualMinValue = series.MinValueY; + + if (chartXy.DataCompare(series.MaxValueY, ActualMaxValue) > 0) + ActualMaxValue = series.MaxValueY; + } + + if (seriesSeen == false) + { + seriesSeen = true; + + ScaleType = series.ActualScaleTypeY; + } + else + { + if (series.ActualScaleTypeY != ScaleType) + { + string s = "YAxis cannot contain series with differing ScaleTypes"; + + if (String.IsNullOrEmpty(Name) == false) + s += " (" + Name + ")"; + + throw new Exception(s); + } + } + + if (ScaleType == ScaleType.Qualitative) + { + if (series.IsRotated == true) + { + foreach (object o in series.QualitativeXValues) + { + if (QualitativeValues.Contains(o) == false) + QualitativeValues.Add(o); + } + } + else + { + foreach (object o in series.QualitativeYValues) + { + if (QualitativeValues.Contains(o) == false) + QualitativeValues.Add(o); + } + } + + if (QualitativeValues.Count - 1 > (int)ActualMaxValue) + ActualMaxValue = QualitativeValues.Count - 1; + } + } + + #endregion + + #endregion + + #region GetValueFromPoint + + internal override object GetValueFromPoint(TickmarkLayout layout, Point pt) + { + pt = GetChartPoint(pt); + + TickmarkTick lastTick = null; + + foreach (TickmarkTick tick in layout.Ticks) + { + if (tick.TickPoint.Y == pt.Y) + return (Convert.ToDouble(tick.Value)); + + if (tick.TickPoint.Y < pt.Y) + { + if (lastTick != null) + { + double d = ((double)lastTick.TickPoint.Y - tick.TickPoint.Y) / (layout.MinorCount + 1); + + for (int i = 1; i <= layout.MinorCount; i++) + { + int y = (int)(lastTick.TickPoint.Y - (d * i)); + + if (y == pt.Y) + return (Convert.ToDouble(lastTick.Value) + (layout.MajorSpacing / (layout.MinorCount + 1) * i)); + + if (y < pt.Y) + break; + } + } + break; + } + + lastTick = tick; + } + + int dy = Bounds.Bottom - pt.Y; + + switch (ScaleType) + { + case ScaleType.Qualitative: + return (layout.MajorSpacing * ((dy + layout.MarginOffset) / + layout.MajorInterval) + (int)layout.BaseValue); + + case ScaleType.DateTime: + return (GetDateTimePointValue(layout, dy)); + + default: + return (layout.MajorSpacing * ((dy + layout.MarginOffset) / + layout.MajorInterval) + Convert.ToDouble(layout.BaseValue)); + } + } + + #endregion + + #region GetPointFromValue + + /// + /// Gets the chart Point from the given axis data value. + /// + /// + /// + public override Point GetPointFromValue(object value) + { + return (new Point(0, GetDisplayValue(value))); + } + + #endregion + + #region GetDisplayValue + + internal override int GetDisplayValue(object axisValue) + { + ChartXy chartXy = Parent as ChartXy; + + return (chartXy.GetDataPointY(this, axisValue)); + } + + #endregion + + #region EnsureVisible + + /// + /// Ensures the given data value is visible and + /// optionally centered on screen. + /// + /// + public override void EnsureVisible(object value, bool center) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + { + if (chartXy.ChartControl != null) + { + if (chartXy.ChartControl.LayoutValid == false) + chartXy.ChartControl.UpdateLayout(); + + Rectangle cbounds = chartXy.ContentBounds; + + int y = GetDisplayValue(value); + + if (center == true) + { + int n = cbounds.Y - (y - cbounds.Height / 2); + + chartXy.VScrollOffset = n; + } + else + { + int n = cbounds.Y - chartXy.VScrollOffset + 20; + + if (y < n) + { + chartXy.VScrollOffset += (n - y); + } + else + { + n = cbounds.Bottom - chartXy.VScrollOffset - 20; + + if (y > n) + chartXy.VScrollOffset -= (y - n); + } + } + } + } + } + + #endregion + + #region Copy/CopyTo + + /// + /// Creates a copy of the axis. + /// + /// + public override ChartVisualElement Copy() + { + ChartAxisY copy = new ChartAxisY(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies each axis property to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + ChartAxisY c = copy as ChartAxisY; + + if (c != null) + { + base.CopyTo(c); + + MajorGridLines.CopyTo(c.MajorGridLines); + MinorGridLines.CopyTo(c.MinorGridLines); + + MajorTickmarks.CopyTo(c.MajorTickmarks); + MinorTickmarks.CopyTo(c.MinorTickmarks); + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartAxisY"; + + sec.AddStartElement(serialName); + } + + sec.AddElement(MajorGridLines.GetSerialData("MajorGridLines")); + sec.AddElement(MinorGridLines.GetSerialData("MinorGridLines")); + sec.AddElement(MajorTickmarks.GetSerialData("MajorTickmarks")); + sec.AddElement(MinorTickmarks.GetSerialData("MinorTickmarks")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "MajorGridLines": + sec.PutSerialData(MajorGridLines); + break; + + case "MinorGridLines": + sec.PutSerialData(MinorGridLines); + break; + + case "MajorTickmarks": + sec.PutSerialData(MajorTickmarks); + break; + + case "MinorTickmarks": + sec.PutSerialData(MinorTickmarks); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + } + + #endregion + + #region ChartAxis + + [TypeConverter(typeof(BlankExpandableObjectConverter))] + abstract public class ChartAxis : ChartVisualElement + { + #region Private variables + + private States _States; + + private AxisOrientation _AxisOrientation = AxisOrientation.X; + private AxisAlignment _AxisAlignment = AxisAlignment.NotSet; + private SortDirection _QualitativeSortDirection = SortDirection.None; + + private int _AxisMargins = -1; + private int _AxisNearMargin = -1; + private int _AxisFarMargin = -1; + + private AxisStripeCollection _AxisStripes; + + private object _MinValue = null; + private object _MaxValue = null; + + private object _ActualMinValue; + private object _ActualMaxValue; + + private double _GridSpacing; + private double _GridInterval; + private int _MinGridInterval = 10; + + private AxisTitle _Title; + private ReferenceLineCollection _ReferenceLines; + + private TickmarkLayout _TickmarkLayout; + private TickmarkLayout _LastTickmarkLayout; + + private Rectangle _AxisBounds; + private Rectangle _AxisLineBounds; + + private ChartAxisVisualStyle _ChartAxisVisualStyle; + private EffectiveStyle _EffectiveAxisStyle; + + private CrosshairValueVisualStyle _CrosshairLabelVisualStyle; + private EffectiveStyle _EffectiveCrosshairLabelStyle; + + private List _QualitativeValues; + private DateTimeUnits _DateTimeUnits = DateTimeUnits.Days; + private DateTimeUnits _DateTimeUnitsLimit = DateTimeUnits.Years; + private DateTimeUnits _ActualDateTimeUnits = DateTimeUnits.Days; + + private ScaleType _ScaleType; + + private AxisBar[] _AxisBars; + + #endregion + + #region Protected variables + + protected MajorTickmarks _MajorTickmarks; + protected MinorTickmarks _MinorTickmarks; + + protected ChartMajorGridLines _MajorGridLines; + protected ChartMinorGridLines _MinorGridLines; + + #endregion + + public ChartAxis(AxisOrientation orientation) + { + InitDefaultStates(); + + _AxisOrientation = orientation; + + _EffectiveAxisStyle = new EffectiveStyle(this); + _EffectiveCrosshairLabelStyle = new EffectiveStyle(this); + + _AxisBars = new AxisBar[(int)AxisBarType.MaxBarCount]; + + for (int i = 0; i < _AxisBars.Length; i++) + _AxisBars[i] = new AxisBar(); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.AutoCalcBarMargins, true); + SetState(States.SeriesRangeChanged, true); + SetState(States.UseAutoMinGridInterval, true); + } + + #endregion + + #region Public properties + + #region ActualDateTimeUnits + + /// + /// Gets the actual axis display units for DateTime data (as determined by + /// either the DateTimeUnits property or actual inspection of the associated data). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTimeUnits ActualDateTimeUnits + { + get { return (_ActualDateTimeUnits); } + internal set { _ActualDateTimeUnits = value; } + } + + #endregion + + #region ActualMaxValue + + /// + /// Gets the actual, axis max data value (as determined by + /// either the MaxValue property or actual inspection of the associated data). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object ActualMaxValue + { + get { return (_ActualMaxValue); } + internal set { _ActualMaxValue = value; } + } + + #endregion + + #region ActualMinValue + + /// + /// Gets the actual, axis min data value (as determined by + /// either the MinValue property or actual inspection of the associated data). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object ActualMinValue + { + get { return (_ActualMinValue); } + internal set { _ActualMinValue = value; } + } + + #endregion + + #region AutoCalcBarMargins + + /// + /// Gets or sets whether axis Bar Margins are calculated and used. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether axis Bar Margins are calculated and used.")] + public bool AutoCalcBarMargins + { + get { return (TestState(States.AutoCalcBarMargins)); } + + set + { + if (value != AutoCalcBarMargins) + { + SetState(States.AutoCalcBarMargins, value); + + OnPropertyChangedEx("AutoCalcBarMargins", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AxisAlignment + + /// + /// Gets or sets the axis alignment. + /// + [DefaultValue(AxisAlignment.NotSet), Category("Layout")] + [Description("Indicates the axis alignment.")] + public AxisAlignment AxisAlignment + { + get { return (_AxisAlignment); } + + set + { + if (value != _AxisAlignment) + { + _AxisAlignment = value; + + OnPropertyChangedEx("AxisAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AxisFarMargin + + /// + /// Gets or sets the far/ending margin for the axis. When set ( >= 0 ), the + /// value overrides the general AxisMargins setting. + /// + [DefaultValue(-1), Category("Layout")] + [Description("Indicates the far/ending margin for the axis. When set ( >= 0 ), the value overrides the general AxisMargins setting.")] + public int AxisFarMargin + { + get { return (_AxisFarMargin); } + + set + { + if (value != _AxisFarMargin) + { + _AxisFarMargin = value; + + OnPropertyChangedEx("AxisFarMargin", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region AxisMargins + + /// + /// Gets or sets the near/beginning and far/ending pixel margins for the axis + /// (ignored when set to < 0). + /// + [DefaultValue(-1), Category("Layout")] + [Description("Indicates the near/beginning and far/ending margins for the axis (ignored when set to < 0).")] + public int AxisMargins + { + get { return (_AxisMargins); } + + set + { + if (value != _AxisMargins) + { + _AxisMargins = value; + + OnPropertyChangedEx("AxisMargins", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region AxisNearMargin + + /// + /// Gets or sets the near/beginning margin for the axis. When set ( >= 0 ), the + /// value overrides the general AxisMargins setting. + /// + [DefaultValue(-1), Category("Layout")] + [Description("Indicates the near/beginning margin for the axis. When set ( >= 0 ), the value overrides the general AxisMargins setting.")] + public int AxisNearMargin + { + get { return (_AxisNearMargin); } + + set + { + if (value != _AxisNearMargin) + { + _AxisNearMargin = value; + + OnPropertyChangedEx("AxisNearMargin", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region AxisOrientation + + /// + /// Gets the axis orientation (X/Y). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AxisOrientation AxisOrientation + { + get { return (_AxisOrientation); } + } + + #endregion + + #region AxisStripes + + /// + /// Gets a reference to the collection of AxisStripes associated with the axis. + /// + [Category("Appearance")] + [Description("Indicates the collection of AxisStripes associated with the axis.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public AxisStripeCollection AxisStripes + { + get + { + if (_AxisStripes == null) + { + _AxisStripes = new AxisStripeCollection(); + + _AxisStripes.CollectionChanged += AxisStripeCollectionChanged; + } + + return (_AxisStripes); + } + + internal set + { + if (_AxisStripes != null) + _AxisStripes.CollectionChanged -= AxisStripeCollectionChanged; + + _AxisStripes = value; + + if (_AxisStripes != null) + _AxisStripes.CollectionChanged += AxisStripeCollectionChanged; + } + } + + #region AxisStripeCollectionChanged + + void AxisStripeCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (ChartElement item in e.NewItems) + item.Parent = this; + break; + + case NotifyCollectionChangedAction.Replace: + foreach (ChartElement item in e.OldItems) + item.Parent = null; + + foreach (ChartElement item in e.NewItems) + item.Parent = this; + break; + + case NotifyCollectionChangedAction.Remove: + foreach (ChartElement item in e.OldItems) + item.Parent = null; + break; + } + + InvalidateLayout(); + } + + #endregion + + #endregion + + #region ChartAxisVisualStyle + + /// + /// Gets or sets the visual style for the Axis. + /// + [Category("Style")] + [Description("Indicates the visual style for the Axis.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartAxisVisualStyle ChartAxisVisualStyle + { + get + { + if (_ChartAxisVisualStyle == null) + { + _ChartAxisVisualStyle = new ChartAxisVisualStyle(); + + StyleVisualChangeHandler(null, _ChartAxisVisualStyle); + } + + return (_ChartAxisVisualStyle); + } + + set + { + if (_ChartAxisVisualStyle != value) + { + ChartAxisVisualStyle oldValue = _ChartAxisVisualStyle; + + _ChartAxisVisualStyle = value; + + OnStyleChanged("ChartAxisVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CrosshairLabelVisualStyle + + /// + /// Gets or sets the visual style to be used for Crosshair elements associated with the axis. + /// + [Category("Style")] + [Description("Indicates the visual style to be used for Crosshair elements associated with the axis.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CrosshairValueVisualStyle CrosshairLabelVisualStyle + { + get + { + if (_CrosshairLabelVisualStyle == null) + { + _CrosshairLabelVisualStyle = new CrosshairValueVisualStyle(); + + StyleVisualChangeHandler(null, _CrosshairLabelVisualStyle); + } + + return (_CrosshairLabelVisualStyle); + } + + set + { + if (_CrosshairLabelVisualStyle != value) + { + CrosshairValueVisualStyle oldValue = _CrosshairLabelVisualStyle; + _CrosshairLabelVisualStyle = value; + + OnStyleChanged("CrosshairLabelVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region DateTimeUnits + + /// + /// Gets or sets the axis display units for DateTime data. + /// + [DefaultValue(DateTimeUnits.Days), Category("Data")] + [Description("Indicates the axis display units for DateTime data.")] + public DateTimeUnits DateTimeUnits + { + get { return (_DateTimeUnits); } + + set + { + if (value != _DateTimeUnits) + { + _DateTimeUnits = value; + + OnPropertyChangedEx("DateTimeUnits", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DateTimeUnitsLimit + + /// + /// Gets or sets the limiting axis display units for DateTime data (the + /// max DateTime units the chart will, if needed, promote the display to). + /// + [DefaultValue(DateTimeUnits.Years), Category("Data")] + [Description("Indicates the limiting axis display units for DateTime data (the max DateTime units the chart will, if needed, promote the display to).")] + public DateTimeUnits DateTimeUnitsLimit + { + get { return (_DateTimeUnitsLimit); } + + set + { + if (value != _DateTimeUnitsLimit) + { + _DateTimeUnitsLimit = value; + + OnPropertyChangedEx("DateTimeUnitsLimit", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EffectiveAxisStyle + + /// + /// Gets a reference to the Axis' Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartAxisVisualStyle EffectiveAxisStyle + { + get { return (_EffectiveAxisStyle.Style); } + } + + #endregion + + #region EffectiveCrosshairLabelStyle + + /// + /// Gets a reference to the CrosshairLabel's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CrosshairValueVisualStyle EffectiveCrosshairLabelStyle + { + get { return (_EffectiveCrosshairLabelStyle.Style); } + } + + #endregion + + #region GridInterval + + /// + /// Gets or sets the grid interval (the distance between MajorTickmarks, in pixels) + /// + [Description("Indicates the grid interval (the distance between MajorTickmarks, in pixels).")] + [DefaultValue(0.0d), Category("Layout")] + public double GridInterval + { + get { return (_GridInterval); } + + set + { + if (value != _GridInterval) + { + _GridInterval = value; + + OnPropertyChangedEx("GridInterval", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GridSpacing + + /// + /// Gets or sets the numerical spacing between MajorTickmarks (such as 1, 10, 100, ...). + /// + [Description("Indicates the numerical spacing between MajorTickmarks (such as 1, 10, 100, ...).")] + [DefaultValue(0.0d), Category("Layout")] + public double GridSpacing + { + get { return (_GridSpacing); } + + set + { + if (value != _GridSpacing) + { + _GridSpacing = value; + + OnPropertyChangedEx("GridSpacing", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsPrimaryAxis + + /// + /// Gets whether the axis is the Primary axis. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPrimaryAxis + { + get { return (TestState(States.PrimaryAxis)); } + internal set { SetState(States.PrimaryAxis, value); } + } + + #endregion + + #region MajorGridLines + + /// + /// Gets the axis MajorGridLines element. + /// + [Description("Indicates the MajorGridLines element."), Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public virtual ChartMajorGridLines MajorGridLines + { + get { return (_MajorGridLines); } + } + + #endregion + + #region MajorTickmarks + + /// + /// Gets the axis MajorTickmarks element. + /// + [Description("Indicates the MajorTickmarks element."), Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public virtual MajorTickmarks MajorTickmarks + { + get { return (_MajorTickmarks); } + } + + #endregion + + #region MaxValue + + /// + /// Gets or sets the maximum axis data value. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the maximum axis data value.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter," + + "DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object MaxValue + { + get { return (_MaxValue); } + + set + { + if (value != _MaxValue) + { + _MaxValue = value; + + OnPropertyChangedEx("MaxValue", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinorGridLines + + /// + /// Gets the axis MinorGridLines element. + /// + [Description("Indicates the MinorGridLines element."), Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public virtual ChartMinorGridLines MinorGridLines + { + get { return (_MinorGridLines); } + } + + #endregion + + #region MinGridInterval + + /// + /// Gets or sets the minimum grid interval size. This is the distance (in pixels) + /// between tickmark layout items. + /// + [DefaultValue(10), Category("Layout")] + [Description("Indicates the minimum grid interval size. This is the distance (in pixels) between tickmark layout items.")] + public int MinGridInterval + { + get { return (_MinGridInterval); } + + set + { + if (value != _MinGridInterval) + { + _MinGridInterval = value; + + OnPropertyChangedEx("MinGridInterval", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinorTickmarks + + /// + /// Gets the axis MinorTickmarks element. + /// + [Description("Indicates the MinorTickmarks element."), Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public virtual MinorTickmarks MinorTickmarks + { + get { return (_MinorTickmarks); } + } + + #endregion + + #region MinValue + + /// + /// Gets or sets the minimum axis data value. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the minimum axis data value.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter," + + "DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object MinValue + { + get { return (_MinValue); } + + set + { + if (value != _MinValue) + { + _MinValue = value; + + OnPropertyChangedEx("MinValue", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region QualitativeSortDirection + + /// + /// Gets or sets the sort direction for Qualitative axis values. + /// + [DefaultValue(SortDirection.None), Category("Data")] + [Description("Indicates the sort direction for Qualitative axis values.")] + public SortDirection QualitativeSortDirection + { + get { return (_QualitativeSortDirection); } + + set + { + if (value != _QualitativeSortDirection) + { + _QualitativeSortDirection = value; + + RefreshRangeValues(); + + OnPropertyChangedEx("QualitativeSortDirection", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ReferenceLines + + /// + /// Gets a reference to the collection of axis Reference Lines + /// + [Category("Appearance")] + [Description("Indicates the collection of axis Reference Lines.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ReferenceLineCollection ReferenceLines + { + get + { + if (_ReferenceLines == null) + { + _ReferenceLines = new ReferenceLineCollection(); + + _ReferenceLines.CollectionChanged += ReferenceLineCollectionChanged; + } + + return (_ReferenceLines); + } + + internal set + { + if (_ReferenceLines != null) + _ReferenceLines.CollectionChanged -= ReferenceLineCollectionChanged; + + _ReferenceLines = value; + + if (_ReferenceLines != null) + _ReferenceLines.CollectionChanged += ReferenceLineCollectionChanged; + } + } + + #region ReferenceLineCollectionChanged + + void ReferenceLineCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (ChartElement item in e.NewItems) + item.Parent = this; + break; + + case NotifyCollectionChangedAction.Replace: + foreach (ChartElement item in e.OldItems) + item.Parent = null; + + foreach (ChartElement item in e.NewItems) + item.Parent = this; + break; + + case NotifyCollectionChangedAction.Remove: + foreach (ChartElement item in e.OldItems) + item.Parent = null; + break; + } + + InvalidateRender(); + } + + #endregion + + #endregion + + #region Title + + /// + /// Gets or sets the Axis Title. + /// + [Category("Layout")] + [Description("Indicates the Axis Title.")] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public AxisTitle Title + { + get + { + if (_Title == null) + { + _Title = new AxisTitle(); + _Title.Parent = this; + } + + return (_Title); + } + + set + { + if (value != _Title) + { + _Title = value; + _Title.Parent = (value != null) ? this : null; + + OnPropertyChangedEx("Title", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region UseAlternateBackground + + /// + /// Gets or sets whether the axis utilizes the alternate background color. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the axis utilizes the alternate background color.")] + public bool UseAlternateBackground + { + get { return (TestState(States.UseAlternateBackground)); } + + set + { + if (value != UseAlternateBackground) + { + SetState(States.UseAlternateBackground, value); + + OnPropertyChangedEx("UseAlternateBackground", VisualChangeType.Render); + } + } + } + + #endregion + + #region UseAutoMinGridInterval + + /// + /// Gets or sets whether the auto-calculated minimum grid interval + /// will be used in determining the axis major tickmark interval. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the auto-calculated minimum grid interval will be used in determining the axis major tickmark interval.")] + public bool UseAutoMinGridInterval + { + get { return (TestState(States.UseAutoMinGridInterval)); } + + set + { + if (value != UseAutoMinGridInterval) + { + SetState(States.UseAutoMinGridInterval, value); + + OnPropertyChangedEx("UseAutoMinGridInterval", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region AxisBars + + internal AxisBar[] AxisBars + { + get { return (_AxisBars); } + } + + #endregion + + #region AxisBounds + + internal Rectangle AxisBounds + { + get { return (_AxisBounds); } + set { _AxisBounds = value; } + } + + #endregion + + #region AxisLineBounds + + internal Rectangle AxisLineBounds + { + get { return (_AxisLineBounds); } + set { _AxisLineBounds = value; } + } + + #endregion + + #region DotPlotAxis + + internal bool DotPlotAxis + { + get { return (TestState(States.DotPlotAxis)); } + set { SetState(States.DotPlotAxis, value); } + } + + #endregion + + #region EdgeAxis + + internal bool EdgeAxis + { + get { return (TestState(States.EdgeAxis)); } + set { SetState(States.EdgeAxis, value); } + } + + #endregion + + #region LastTickmarkLayout + + internal TickmarkLayout LastTickmarkLayout + { + get { return (_LastTickmarkLayout); } + set { _LastTickmarkLayout = value; } + } + + #endregion + + #region QualitativeValues + + internal List QualitativeValues + { + get + { + if (_QualitativeValues == null) + _QualitativeValues = new List(); + + return (_QualitativeValues); + } + + set { _QualitativeValues = value; } + } + + #endregion + + #region ScaleType + + internal ScaleType ScaleType + { + get { return (_ScaleType); } + set { _ScaleType = value; } + } + + #endregion + + #region SeriesRangeChanged + + internal bool SeriesRangeChanged + { + get { return (TestState(States.SeriesRangeChanged)); } + set { SetState(States.SeriesRangeChanged, value); } + } + + #endregion + + #region TickmarkLayout + + internal TickmarkLayout TickmarkLayout + { + get { return(_TickmarkLayout); } + set { _TickmarkLayout = value; } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + MeasureReferenceLines(layoutInfo); + } + + protected void MeasureReferenceLines(ChartLayoutInfo layoutInfo) + { + Rectangle layoutBounds = layoutInfo.LayoutBounds; + + foreach (ReferenceLine line in ReferenceLines) + { + layoutInfo.LayoutBounds = BoundsRelative; + + line.Measure(layoutInfo); + } + + layoutInfo.LayoutBounds = layoutBounds; + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + if (Title.Visible == true) + Title.Arrange(layoutInfo); + + MajorTickmarks.Arrange(layoutInfo); + MinorTickmarks.Arrange(layoutInfo); + + MajorGridLines.TickmarkLayout = TickmarkLayout; + MinorGridLines.TickmarkLayout = TickmarkLayout; + + MajorGridLines.Arrange(layoutInfo); + MinorGridLines.Arrange(layoutInfo); + + ArrangeReferenceLines(layoutInfo); + } + + #region ArrangeReferenceLines + + private void ArrangeReferenceLines(ChartLayoutInfo layoutInfo) + { + Rectangle layoutBounds = layoutInfo.LayoutBounds; + + foreach (ReferenceLine line in ReferenceLines) + { + layoutInfo.LayoutBounds = BoundsRelative; + + line.Arrange(layoutInfo); + } + + layoutInfo.LayoutBounds = layoutBounds; + } + + #endregion + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + ChartAxisVisualStyle astyle = EffectiveAxisStyle; + + if (Title.Visible == true) + Title.Render(renderInfo); + } + + #endregion + + #region Render + + internal override void Render(ChartRenderInfo renderInfo) + { + if (Displayed == true) + { + Rectangle bounds = GetScrollBounds(AxisBounds); + + if (renderInfo.ClipRectangle.IntersectsWith(bounds)) + RenderOverride(renderInfo); + } + } + + #endregion + + #region RenderCrosshairLabel + + internal virtual void RenderCrosshairLabel(Graphics g, Point pt) + { + } + + internal virtual void RenderCrosshairLabel(Graphics g, CrosshairPoint cp) + { + } + + #region GetCrosshairLabel + + internal string GetCrosshairLabel(object value, CrosshairValueVisualStyle lstyle) + { + string label = ""; + + if (value != null) + { + TickmarkLabelVisualStyle tstyle = MajorTickmarks.EffectiveLabelStyle; + + try + { + switch (ScaleType) + { + case ScaleType.DateTime: + DateTime dtvalue = (DateTime)value; + + if (string.IsNullOrEmpty(lstyle.TextFormat) == false) + label = dtvalue.ToString(lstyle.TextFormat); + + else if (string.IsNullOrEmpty(tstyle.TextFormat) == false) + label = dtvalue.ToString(tstyle.TextFormat); + else + label = GetDateTimeLabel(dtvalue); + break; + + case ScaleType.Qualitative: + if (string.IsNullOrEmpty(lstyle.TextFormat) == false) + label = string.Format(lstyle.TextFormat, value); + + else if (string.IsNullOrEmpty(tstyle.TextFormat) == false) + label = string.Format(tstyle.TextFormat, value); + else + label = value.ToString(); + break; + + default: + double d = Convert.ToDouble(value); + + if (string.IsNullOrEmpty(lstyle.TextFormat) == false) + label = d.ToString(lstyle.TextFormat); + + else if (string.IsNullOrEmpty(tstyle.TextFormat) == false) + label = d.ToString(tstyle.TextFormat); + + else if (value is int) + label = ((int)value).ToString(); + + else + label = d.ToString("F6"); + + break; + } + } + catch + { + } + } + + ChartControl chartControl = ChartControl; + + if (chartControl != null) + chartControl.DoGetCrosshairAxisLabelEvent(this, value, ref label); + + return (label); + } + + #endregion + + #endregion + + #region RenderBackground + + internal virtual void RenderBackground( + ChartRenderInfo renderInfo, Rectangle scContentBounds) + { + } + + #endregion + + #region RenderStripes + + internal virtual void RenderStripes( + ChartRenderInfo renderInfo, Rectangle scContentBounds) + { + } + + #endregion + + #region RenderStripe + + protected void RenderStripe( + Graphics g, Rectangle bounds, AxisStripe stripe) + { + if (bounds.Width > 0 && bounds.Height > 0) + { + AxisStripeVisualStyle astyle = stripe.AxisStripeVisualStyle; + + if (astyle.Background.IsEmpty == true) + { + g.FillRectangle(Brushes.LightPink, bounds); + } + else + { + using (Brush br = astyle.Background.GetBrush(bounds)) + g.FillRectangle(br, bounds); + } + } + } + + #endregion + + #region CalcMajorSpacing + + protected void CalcMajorSpacing(ChartLayoutInfo layoutInfo, int width) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy.DropShadowDisplayed == true) + width -= 3; + + if (AxisOrientation == AxisOrientation.X) + { + if (chartXy.VScrollBar.Visible == true) + width -= chartXy.VScrollBar.Width; + } + else + { + if (chartXy.HScrollBar.Visible == true) + width -= chartXy.HScrollBar.Height; + } + + TickmarkLayout layout = new TickmarkLayout(); + + layout.MinValue = GetMinValue(); + layout.MaxValue = GetMaxValue(); + + if (layout.MinValue != null && layout.MaxValue != null) + { + ScaleType scaleType = ScaleType; + + if (ScaleType == ScaleType.NotSet) + ScaleType = SeriesPoint.GetScaleType(layout.MinValue.GetType()); + + layout.MinorCount = MinorTickmarks.TickmarkCount; + + if (ScaleType != ScaleType.NotSet) + { + switch (ScaleType) + { + case ScaleType.DateTime: + CalcMajorDateTimeSpacing(chartXy, layout, width); + break; + + case ScaleType.Qualitative: + CalcMajorQualitativeSpacing(layout, width); + break; + + default: + CalcMajorQuantitativeSpacing(chartXy, layout, width); + break; + } + } + + if (AxisOrientation == AxisOrientation.Y) + { + if (chartXy.HScrollBar.Visible == true) + layout.MarginOffset -= chartXy.HScrollBarHeight; + } + } + + TickmarkLayout = layout; + } + + #region CalcMajorDateTimeSpacing + + private void CalcMajorDateTimeSpacing( + ChartXy chartXy, TickmarkLayout layout, int width) + { + DateTime dtMinValue = (DateTime)layout.MinValue; + DateTime dtMaxValue = (DateTime)layout.MaxValue; + + DateTime odtMinValue = dtMinValue; + + if (width > 0 && dtMinValue < dtMaxValue) + { + DateTime ominValue = dtMinValue; + + width = SetLayoutMargin(layout, width) - 2; + + CalcDateTimeSpacing(chartXy, layout, dtMinValue, dtMaxValue, width); + + if (AutoCalcBarMargins == true) + { + ChartSeries barSeries = GetBarSeries(chartXy); + + if (barSeries != null) + { + if ((barSeries.IsRotated == false && AxisOrientation == AxisOrientation.X) || + (barSeries.IsRotated == true && AxisOrientation == AxisOrientation.Y)) + { + int n = (int)(width / layout.MajorCount / 2 / layout.MajorSpacing); + + layout.NearMargin += n; + layout.FarMargin += n; + + width -= (n * 2); + + layout.MajorInterval = (double)width / layout.MajorCount; + } + } + } + else + { + layout.MajorInterval = (double)width / layout.MajorCount; + } + + if (UseAutoMinGridInterval == true) + { + if (layout.MajorInterval <= 3) + layout.MajorInterval = 3; + } + + dtMinValue = AdjustDateTimeBase(layout, dtMinValue); + + UpdateDateTimeMargins(layout, ref dtMinValue, ref dtMaxValue); + + double offset = GetDateTimeRange(ActualDateTimeUnits, dtMinValue, ominValue); + + int moff = (int)((layout.MajorInterval * offset) / layout.MajorSpacing - layout.NearMargin - 1); + + layout.MarginOffset = moff; + + layout.MinValue = dtMinValue; + layout.MaxValue = dtMaxValue; + } + } + + #region AdjustDateTimeBase + + private DateTime AdjustDateTimeBase(TickmarkLayout layout, DateTime dtValue) + { + switch (ActualDateTimeUnits) + { + case DateTimeUnits.Milliseconds: + dtValue = dtValue.AddMilliseconds(-dtValue.Millisecond % layout.GridSpacing); + break; + + case DateTimeUnits.Seconds: + dtValue = new DateTime(dtValue.Year, dtValue.Month, dtValue.Day, dtValue.Hour, dtValue.Minute, dtValue.Second); + dtValue = dtValue.AddSeconds(-dtValue.Second % layout.GridSpacing); + break; + + case DateTimeUnits.Minutes: + dtValue = new DateTime(dtValue.Year, dtValue.Month, dtValue.Day, dtValue.Hour, dtValue.Minute, 0); + dtValue = dtValue.AddMinutes(-dtValue.Minute % layout.GridSpacing); + break; + + case DateTimeUnits.Hours: + dtValue = new DateTime(dtValue.Year, dtValue.Month, dtValue.Day, dtValue.Hour, 0, 0); + dtValue = dtValue.AddHours(-dtValue.Hour % layout.GridSpacing); + break; + + case DateTimeUnits.Days: + dtValue = new DateTime(dtValue.Year, dtValue.Month, dtValue.Day); + dtValue = dtValue.AddDays(-dtValue.Day % layout.GridSpacing); + break; + + case DateTimeUnits.Months: + dtValue = new DateTime(dtValue.Year, dtValue.Month, 1); + dtValue = dtValue.AddMonths(-(int)(dtValue.Month % layout.GridSpacing)); + break; + + case DateTimeUnits.Years: + dtValue = new DateTime(dtValue.Year, 1, 1); + dtValue = dtValue.AddYears(-(int)(dtValue.Year % layout.GridSpacing)); + break; + + default: + dtValue = dtValue.AddTicks(-(long)(dtValue.Millisecond % layout.GridSpacing)); + break; + } + + return (dtValue); + } + + #endregion + + #region CalcDateTimeSpacing + + private void CalcDateTimeSpacing(ChartXy chartXy, + TickmarkLayout layout, DateTime dtMinValue, DateTime dtMaxValue, int width) + { + DateTimeUnits adtu = DateTimeUnits; + + double range = GetDateTimeRange(adtu, dtMinValue, dtMaxValue); + + if (GridSpacing <= 0) + { + layout.GridSpacing = 1; + layout.MajorSpacing = layout.GridSpacing; + } + else + { + layout.GridSpacing = GridSpacing; + layout.MajorSpacing = layout.GridSpacing; + } + + CalcDateTimeInterval(layout, range, width); + + double minorInterval = layout.MajorInterval / (MinorTickmarks.TickmarkCount + 1); + + if (minorInterval > 0) + { + ChartSeries barSeries = GetBarSeries(chartXy); + + while (minorInterval < MinGridInterval) + { + if ((barSeries == null) && (int)adtu < (int)DateTimeUnitsLimit) + { + adtu = GetNextDateTimeUnit(adtu, dtMinValue, dtMaxValue); + range = GetDateTimeRange(adtu, dtMinValue, dtMaxValue); + + CalcDateTimeInterval(layout, range, width); + + minorInterval = layout.MajorInterval / (MinorTickmarks.TickmarkCount + 1); + } + else + { + if (GridSpacing > 0) + break; + + minorInterval *= 2; + layout.MajorSpacing *= 2; + } + } + + ActualDateTimeUnits = adtu; + + CalcDateTimeInterval(layout, range, width); + } + } + + #region CalcDateTimeInterval + + private void CalcDateTimeInterval(TickmarkLayout layout, double range, int width) + { + double d = range / layout.MajorSpacing; + + layout.MajorCount = (int)Math.Ceiling(d); + layout.MajorInterval = (double)width / d; + + if (layout.MajorCount <= 0) + layout.MajorCount = 1; + } + + #endregion + + #region GetNextDateTimeUnit + + private DateTimeUnits GetNextDateTimeUnit( + DateTimeUnits adtu, DateTime dtMinValue, DateTime dtMaxValue) + { + switch (adtu) + { + case DateTimeUnits.Ticks: + return (DateTimeUnits.Milliseconds); + + case DateTimeUnits.Milliseconds: + return (DateTimeUnits.Seconds); + + case DateTimeUnits.Seconds: + return (DateTimeUnits.Minutes); + + case DateTimeUnits.Minutes: + return (DateTimeUnits.Hours); + + case DateTimeUnits.Hours: + return (DateTimeUnits.Days); + + case DateTimeUnits.Days: + return (DateTimeUnits.Months); + + default: + return (DateTimeUnits.Years); + } + } + + #endregion + + #endregion + + #region AddDateTimeOffset + + private DateTime AddDateTimeOffset(DateTime dtValue, int offset) + { + switch (ActualDateTimeUnits) + { + case DateTimeUnits.Milliseconds: + dtValue = dtValue.AddMilliseconds(offset); + break; + + case DateTimeUnits.Seconds: + dtValue = dtValue.AddSeconds(offset); + break; + + case DateTimeUnits.Minutes: + dtValue = dtValue.AddMinutes(offset); + break; + + case DateTimeUnits.Hours: + dtValue = dtValue.AddHours(offset); + break; + + case DateTimeUnits.Days: + dtValue = dtValue.AddDays(offset); + break; + + case DateTimeUnits.Months: + dtValue = dtValue.AddMonths(offset); + break; + + case DateTimeUnits.Years: + dtValue = dtValue.AddYears(offset); + break; + + default: + dtValue = dtValue.AddTicks(offset); + break; + } + + return (dtValue); + } + + #endregion + + #region UpdateDateTimeMargins + + private void UpdateDateTimeMargins( + TickmarkLayout layout, ref DateTime dtMinValue, ref DateTime dtMaxValue) + { + if (layout.NearMargin > 0) + { + int marginCount = (int)Math.Ceiling(layout.NearMargin / layout.MajorInterval); + + layout.MajorCount += marginCount; + + dtMinValue = AddDateTimeOffset(dtMinValue, -(int)(marginCount * 1)); //layout.MajorSpacing)); + } + + if (layout.FarMargin > 0) + { + int marginCount = (int)Math.Ceiling(layout.FarMargin / layout.MajorInterval); + + layout.MajorCount += marginCount; + + dtMaxValue = AddDateTimeOffset(dtMaxValue, (int)(marginCount * 1)); //layout.MajorSpacing)); + } + } + + #endregion + + #region GetDateTimeRange + + private double GetDateTimeRange( + DateTimeUnits dtu, DateTime dtMinValue, DateTime dtMaxValue) + { + TimeSpan ts = dtMaxValue - dtMinValue; + + switch (dtu) + { + case DateTimeUnits.Milliseconds: + return (ts.TotalMilliseconds); + + case DateTimeUnits.Seconds: + return (ts.TotalSeconds); + + case DateTimeUnits.Minutes: + return (ts.TotalMinutes); + + case DateTimeUnits.Hours: + return (ts.TotalHours); + + case DateTimeUnits.Days: + return (ts.TotalDays); + + case DateTimeUnits.Months: + return (CalcDateTimeMonths(dtMinValue, dtMaxValue)); + + case DateTimeUnits.Years: + return (CalcDateTimeYears(dtMinValue, dtMaxValue)); + + default: + return (dtMaxValue.Ticks - dtMinValue.Ticks); + } + } + + #region CalcDateTimeYears + + internal double CalcDateTimeYears(DateTime dtMinValue, DateTime dtMaxValue) + { + int years = dtMaxValue.Year - dtMinValue.Year; + + DateTime last = dtMinValue.AddYears(years); + + if (last > dtMaxValue) + { + last = last.AddYears(-1); + years--; + } + + DateTime next = last.AddYears(1); + + double yearDays = (next - last).Days; + double days = (dtMaxValue - last).Days; + + return ((double)years + (days / yearDays)); + } + + #endregion + + #region CalcDateTimeMonths + + internal double CalcDateTimeMonths(DateTime dtMinValue, DateTime dtMaxValue) + { + // Rough estimation... + + TimeSpan ts = dtMaxValue - dtMinValue; + + return ((double)ts.Days / 30); + } + + #endregion + + #endregion + + #endregion + + #region CalcMajorQuantitativeSpacing + + private void CalcMajorQuantitativeSpacing( + ChartXy chartXy, TickmarkLayout layout, int width) + { + Type otype = layout.MinValue.GetType(); + + double dminValue = Convert.ToDouble(layout.MinValue); + double dmaxValue = Convert.ToDouble(layout.MaxValue); + + if (AutoCalcBarMargins == true) + { + ChartSeries barSeries = GetFullBarSeries(chartXy); + + if (barSeries != null) + { + if (barSeries.IsRotated == true && AxisOrientation == AxisOrientation.X || + barSeries.IsRotated == false && AxisOrientation == AxisOrientation.Y) + { + double origin = Convert.ToDouble((chartXy.BarOrigin ?? 0)); + + dminValue = Math.Min(origin, dminValue); + } + } + } + + double ominValue = dminValue; + + if (dminValue == dmaxValue) + dmaxValue++; + + if (width > 0 && dminValue <= dmaxValue) + { + width = SetLayoutMargin(layout, width); + + double range = Math.Abs(dmaxValue - dminValue); + + CalcQuantitativeSpacing(chartXy, layout, range, width); + + if (UseAutoMinGridInterval == true) + { + if (layout.MajorInterval < 3) + layout.MajorInterval = 3; + } + + UpdateQuantitativeMargins(layout, otype, ref dminValue, ref dmaxValue); + + // Make sure zero is included on the axis + + int n = dminValue < 0 ? -1 : 1; + + if (dminValue < 0) + dminValue -= ((dminValue % layout.MajorSpacing) + layout.MajorSpacing); + + else if (dminValue > 0) + dminValue -= (dminValue % layout.MajorSpacing); + + int moff = 0; + + double delta = Math.Floor(Math.Abs(dminValue) / layout.MajorSpacing); + double value = (int)delta * layout.MajorSpacing * n; + double offset = Math.Abs(value - ominValue); + + moff = (int)((layout.MajorInterval * offset) / layout.MajorSpacing - layout.NearMargin); + + layout.MarginOffset = moff; + + layout.MinValue = Convert.ChangeType(dminValue, otype); + layout.MaxValue = Convert.ChangeType(dmaxValue, otype); + } + } + + #region CalcQuantitativeSpacing + + void CalcQuantitativeSpacing( + ChartXy chartXy, TickmarkLayout layout, double range, int width) + { + if (GridSpacing <= 0) + { + // User has not specified a spacing, so calculate it for them based + // upon powers of 10 (10, 100, 1000, etc) + // + // MajorSpacing is set to a multiple of the GridSpacing (based upon + // the calculated minor tickmark interval) + + layout.GridSpacing = Math.Pow(10, Math.Floor(Math.Log10(range / 10))); + + if (layout.GridSpacing < 1) + layout.GridSpacing = 1; + + if (layout.MinValue is int) + layout.GridSpacing = Math.Ceiling(layout.GridSpacing); + + layout.MajorSpacing = layout.GridSpacing; + + layout.MajorCount = (int)Math.Ceiling(range / layout.MajorSpacing); + layout.MajorInterval = (double)width / layout.MajorCount; + } + else + { + layout.GridSpacing = GridSpacing; + layout.MajorSpacing = layout.GridSpacing; + + layout.MajorCount = (int)Math.Ceiling(range / layout.MajorSpacing); + layout.MajorInterval = (double)width / layout.MajorCount; + } + + double gridInterval = GridInterval; + double pxp = (range < 1) ? width : ((double)width / range); + + ChartSeries dpSeries = GetChartDotPlotSeries(chartXy); + + if (dpSeries != null) + { + // Calculate the default dot plot spacing + + gridInterval = CalcDotPlotSpacing( + chartXy, layout, range, ref width, dpSeries); + + double count = range / layout.MajorSpacing; + + layout.MajorCount = (int)Math.Ceiling(count); + + pxp = (double)width / range; + + DotPlotAxis = true; + } + else + { + ChartSeries barSeries = GetBarSeries(chartXy); + + if (barSeries != null) + { + if ((barSeries.IsRotated == false && AxisOrientation == AxisOrientation.X) || + (barSeries.IsRotated == true && AxisOrientation == AxisOrientation.Y)) + { + int n = (int)(pxp / 2) + 1; + + layout.NearMargin += n; + layout.FarMargin += n; + + width -= (n * 2); + + layout.MajorInterval = (double)width / layout.MajorCount; + + pxp = (double)width / (range); + } + } + + double minorInterval = layout.MajorInterval / (MinorTickmarks.TickmarkCount + 1); + + if (minorInterval > 0) + { + while (minorInterval < MinGridInterval) + { + minorInterval *= 2; + layout.MajorSpacing *= 2; + } + } + + gridInterval = layout.MajorInterval; + + double dminValue = Convert.ToDouble(layout.MinValue); + double dmaxValue = Convert.ToDouble(layout.MaxValue); + + double maxp = (int)(dmaxValue / layout.MajorSpacing) * layout.MajorSpacing; + + if (maxp < dmaxValue) + maxp += layout.MajorSpacing; + + double minp = (int)(dminValue / layout.MajorSpacing) * layout.MajorSpacing; + + if (minp > dminValue) + minp -= layout.MajorSpacing; + + layout.MajorCount = (int)Math.Ceiling((maxp - minp) / layout.MajorSpacing); + + layout.MinValue = minp; + layout.MaxValue = maxp; + + DotPlotAxis = false; + } + + if (GridInterval > 0) + { + layout.MajorInterval = GridInterval; + } + else + { + if (AxisCanExpand(dpSeries) == true) + gridInterval = Math.Max(gridInterval, pxp * layout.MajorSpacing); + + layout.MajorInterval = Math.Max(gridInterval, 1); + } + } + + #region GetChartDotPlotSeries + + private ChartSeries GetChartDotPlotSeries(ChartXy chartXy) + { + foreach (ChartSeries series in chartXy.ChartSeries) + { + if ((series.SeriesType == SeriesType.VerticalDot) || + (series.SeriesType == SeriesType.HorizontalDot)) + { + return (series); + } + } + + return (null); + } + + #endregion + + #region CalcDotPlotSpacing + + private double CalcDotPlotSpacing(ChartXy chartXy, + TickmarkLayout layout, double range, ref int width, ChartSeries dpSeries) + { + // If we previously added a default margin, back it back out + // since we are going to adjust the margin based upon the orientation + // and size of the marker + + if (AxisMargins < 0) + { + width += ((layout.NearMargin * 2) - Dpi.Width10); + layout.NearMargin = Dpi.Width5; + } + + Size dotSize = chartXy.GetMaxDotPlotMarkerSize(); + DotPlotType dotTypes = chartXy.GetDotPlotTypes(); + + return (AxisOrientation == AxisOrientation.X) + ? CalcXDotPlotSpacing(chartXy, layout, range, ref width, dpSeries, dotTypes, dotSize) + : CalcYDotPlotSpacing(chartXy, layout, range, ref width, dpSeries, dotTypes, dotSize); + } + + #region CalcXDotPlotSpacing + + private double CalcXDotPlotSpacing(ChartXy chartXy, TickmarkLayout layout, + double range, ref int width, ChartSeries dpSeries, DotPlotType dotTypes, Size dotSize) + { + if ((dotTypes & DotPlotType.Vertical) == DotPlotType.Vertical) + { + int n = dotSize.Width / 2; + + layout.NearMargin += n; + width -= (n * 2); + } + + layout.MajorSpacing = (GridSpacing <= 0) ? 1 : GridSpacing; + + double gridInterval = Math.Max(layout.MajorSpacing, 1) * dotSize.Width; + + if (MinGridInterval > 0) + { + while (gridInterval < Dpi.Width(MinGridInterval)) + { + gridInterval *= 2; + layout.MajorSpacing *= 2; + } + } + + Size size = chartXy.MinQualitativeSize; + + double count = range; + + if ((dotTypes & DotPlotType.Vertical) == DotPlotType.Vertical) + count = range / dpSeries.DotPlotIndexValue; + + size.Width = (int)(dotSize.Width * count + layout.NearMargin * 2); + + if (chartXy.VScrollBar.Enabled == true) + size.Width += chartXy.VScrollBar.Width; + + chartXy.MinQualitativeSize = size; + + return (gridInterval); + } + + #endregion + + #region CalcYDotPlotSpacing + + private double CalcYDotPlotSpacing(ChartXy chartXy, TickmarkLayout layout, + double range, ref int width, ChartSeries dpSeries, DotPlotType dotTypes, Size dotSize) + { + if ((dotTypes & DotPlotType.Horizontal) == DotPlotType.Horizontal) + { + int n = dotSize.Height / 2; + + layout.NearMargin += n; + width -= (n * 2); + } + + layout.MajorSpacing = (GridSpacing <= 0) ? 1 : GridSpacing; + + double gridInterval = layout.MajorSpacing * dotSize.Height; + + if (MinGridInterval > 0) + { + while (gridInterval < MinGridInterval) + { + gridInterval *= 2; + layout.MajorSpacing *= 2; + } + } + + Size size = chartXy.MinQualitativeSize; + + double count = range; + + if ((dotTypes & DotPlotType.Horizontal) == DotPlotType.Horizontal) + count = range / dpSeries.DotPlotIndexValue; + + size.Height = (int)(dotSize.Height * count + layout.NearMargin * 2); + + if (chartXy.HScrollBar.Enabled == true) + size.Height += chartXy.HScrollBar.Height; + + chartXy.MinQualitativeSize = size; + + return (gridInterval); + } + + #endregion + + #endregion + + #region AxisCanExpand + + private bool AxisCanExpand(ChartSeries dpSeries) + { + return ((dpSeries == null) || + (AxisOrientation == AxisOrientation.X && dpSeries.SeriesType == SeriesType.VerticalDot) || + (AxisOrientation == AxisOrientation.Y && dpSeries.SeriesType == SeriesType.HorizontalDot)); + } + + #endregion + + #endregion + + #region UpdateQuantitativeMargins + + private void UpdateQuantitativeMargins( + TickmarkLayout layout, Type otype, ref double dminValue, ref double dmaxValue) + { + if (layout.NearMargin > 0) + { + int marginCount = (int)Math.Ceiling(layout.NearMargin / layout.MajorInterval); + + layout.MajorCount += marginCount; + + if (otype == typeof(Int32)) + { + if (dminValue - (marginCount * layout.MajorSpacing) > Int32.MinValue) + dminValue -= (marginCount * layout.MajorSpacing); + } + else + { + dminValue -= (marginCount * layout.MajorSpacing); + } + } + + if (layout.FarMargin > 0) + { + int marginCount = (int)Math.Ceiling(layout.FarMargin / layout.MajorInterval); + + layout.MajorCount += marginCount; + + if (otype == typeof(Int32)) + { + if (dmaxValue + (marginCount * layout.MajorSpacing) < Int32.MaxValue) + dmaxValue += (marginCount * layout.MajorSpacing); + } + else + { + dmaxValue += (marginCount * layout.MajorSpacing); + } + } + } + + #endregion + + #endregion + + #region CalcMajorQualitativeSpacing + + private void CalcMajorQualitativeSpacing(TickmarkLayout layout, int width) + { + int iminValue = (int)layout.MinValue; + int imaxValue = (int)layout.MaxValue; + + int ominValue = iminValue; + + if (width > 0 && iminValue <= imaxValue) + { + width = SetLayoutMargin(layout, width); + + double range = Math.Abs(imaxValue - iminValue) + 1; + + CalcQualitativeSpacing(layout, range, width); + + if (UseAutoMinGridInterval == true) + { + if (layout.MajorInterval <= 3) + layout.MajorInterval = 3; + } + + UpdateQualitativeMargins(layout, ref iminValue, ref imaxValue); + + // Make sure zero is included on the axis + + iminValue -= (int)(iminValue % layout.MajorSpacing); + + int moff = 0; + + int n = iminValue < 0 ? -1 : 1; + + double delta = Math.Floor(Math.Abs(iminValue) / layout.GridSpacing); + double value = (int)delta * layout.GridSpacing * n; + double offset = Math.Abs(value - ominValue); + + moff = (int)((layout.MajorInterval * offset) / layout.MajorSpacing - layout.NearMargin); + + layout.MarginOffset = moff; + + layout.MinValue = iminValue; + layout.MaxValue = imaxValue; + } + } + + #region CalcQualitativeSpacing + + private void CalcQualitativeSpacing( + TickmarkLayout layout, double range, int width) + { + ChartXy chartXy = Parent as ChartXy; + + layout.GridSpacing = 1; + layout.MajorSpacing = layout.GridSpacing; + + layout.MajorCount = (int)range; + layout.MajorInterval = (double)width / layout.MajorCount; + + if (layout.MinorCount > 0) + { + double minorInterval = layout.MajorInterval / (layout.MinorCount + 1); + + if (minorInterval > 0) + { + while (minorInterval < MinGridInterval) + { + minorInterval *= 2; + layout.MinorCount /= 2; + } + } + } + + List groupIds = GetSeriesGroupIds(chartXy); + + int colWidth = int.MinValue; + + foreach (int groupId in groupIds) + { + int n = chartXy.GetQualitativeColumnWidth(this, groupId); + + if (n > colWidth) + colWidth = n; + } + + if (UseAutoMinGridInterval == false) + { + if (colWidth > layout.MajorInterval) + colWidth = (int)layout.MajorInterval; + } + + if (colWidth < MinGridInterval) + colWidth = MinGridInterval; + + int minWidth = colWidth * (layout.MajorCount); + + if (AxisOrientation == AxisOrientation.X) + { + if (chartXy.MinQualitativeSize.Width != minWidth) + { + Size size = chartXy.MinQualitativeSize; + size.Width = minWidth + layout.NearMargin; + chartXy.MinQualitativeSize = size; + + // Force a layout change when the next + // layout invalidation arrives + + LastTickmarkLayout = null; + } + } + else + { + if (chartXy.MinQualitativeSize.Height != minWidth) + { + Size size = chartXy.MinQualitativeSize; + size.Height = minWidth + layout.NearMargin; + chartXy.MinQualitativeSize = size; + + LastTickmarkLayout = null; + } + } + + width += layout.NearMargin; + minWidth = Math.Max(width, minWidth) - layout.NearMargin; + + layout.MajorInterval = (double)minWidth / layout.MajorCount; + + if (layout.MajorInterval < MinGridInterval) + { + layout.MajorInterval = MinGridInterval; + + minWidth = (int)(layout.MajorInterval * (layout.MajorCount - 0)); + } + + layout.MajorInterval = (double)minWidth / (layout.MajorCount - 0); + + foreach (int groupId in groupIds) + { + chartXy.AdjustQualitativeOffsets(this, + groupId, colWidth, (int)(layout.MajorInterval)); + } + + layout.NearMargin += (int)(layout.MajorInterval / 2); + } + + #region GetSeriesGroupIds + + private List GetSeriesGroupIds(ChartXy chartXy) + { + List groupIds = new List(); + + foreach (ChartSeries series in chartXy.ChartSeries) + { + if (groupIds.Contains(series.GroupId) == false) + groupIds.Add(series.GroupId); + } + + return (groupIds); + } + + #endregion + + #endregion + + #region UpdateQualitativeMargins + + private void UpdateQualitativeMargins( + TickmarkLayout layout, ref int iminValue, ref int imaxValue) + { + if (layout.NearMargin > 0) + { + int marginCount = (int)Math.Ceiling(layout.NearMargin / layout.MajorInterval); + + layout.MajorCount += marginCount; + + iminValue -= (int)(marginCount * layout.MajorSpacing); + } + + if (layout.FarMargin > 0) + { + int marginCount = (int)Math.Ceiling(layout.FarMargin / layout.MajorInterval); + + layout.MajorCount += marginCount; + + imaxValue += (int)(marginCount * layout.MajorSpacing); + } + } + + #endregion + + #endregion + + #region SetLayoutMargin + + private int SetLayoutMargin(TickmarkLayout layout, int width) + { + layout.NearMargin = (AxisNearMargin >= 0) ? AxisNearMargin : AxisMargins >= 0 ? AxisMargins : 20; + layout.FarMargin = (AxisFarMargin >= 0) ? AxisFarMargin : AxisMargins >= 0 ? AxisMargins : 20; + + layout.NearMargin = Dpi.Width(layout.NearMargin); + layout.FarMargin = Dpi.Width(layout.FarMargin); + + layout.NearMargin = Math.Min(layout.NearMargin, width / 3); + layout.FarMargin = Math.Min(layout.FarMargin, width / 3); + + if (layout.NearMargin > 0) + width -= (layout.NearMargin + 1); + + if (layout.FarMargin > 0) + width -= (layout.FarMargin + 1); + + return (width); + } + + #endregion + + #region GetBarSeries + + private ChartSeries GetBarSeries(ChartXy chartXy) + { + foreach (ChartSeries series in chartXy.ChartSeries) + { + if (series.Visible == true) + { + if (series.IsBarSeries == true) + return (series); + } + } + + return (null); + } + + #endregion + + #region GetFullBarSeries + + private ChartSeries GetFullBarSeries(ChartXy chartXy) + { + foreach (ChartSeries series in chartXy.ChartSeries) + { + if (series.Visible == true) + { + if (series.SeriesType == SeriesType.HorizontalBar || + series.SeriesType == SeriesType.VerticalBar) + { + if (AxisOrientation == AxisOrientation.X) + { + if (series.AxisX == this || (series.AxisX == null && chartXy.AxisX == this)) + return (series); + } + else + { + if (series.AxisY == this || (series.AxisY == null && chartXy.AxisY == this)) + return (series); + } + } + } + } + + return (null); + } + + #endregion + + #endregion + + #region GetMaxTickMarkLength + + protected int GetMaxTickMarkLength(bool inner) + { + int majorLength = MajorTickmarks.GetMaxTickmarkLength(this, inner); + int minorLength = MinorTickmarks.GetMaxTickmarkLength(this, inner); + + int maxlen = Math.Max(majorLength, minorLength); + + return (maxlen); + } + + #endregion + + #region GetAxisAlignment + + internal AxisAlignment GetAxisAlignment() + { + if (AxisAlignment == AxisAlignment.NotSet) + return (IsPrimaryAxis ? AxisAlignment.Near : AxisAlignment.Far); + + return (AxisAlignment); + } + + #endregion + + #region GetMinValue + + internal object GetMinValue() + { + UpdateRangeValues(); + + if (MinValue != null) + { + if (ScaleType != ScaleType.NotSet) + { + if (SeriesPoint.GetScaleType(MinValue.GetType()) != ScaleType) + { + if (IsDesignerHosted == false) + throw new Exception("MinValue ScaleType must match Axis ScaleType"); + + return (ActualMinValue); + } + } + + return (MinValue); + } + + return (ActualMinValue); + } + + #endregion + + #region GetMaxValue + + internal object GetMaxValue() + { + UpdateRangeValues(); + + if (MaxValue != null) + { + if (ScaleType != ScaleType.NotSet) + { + if (SeriesPoint.GetScaleType(MaxValue.GetType()) != ScaleType) + { + if (IsDesignerHosted == false) + throw new Exception("MaxValue ScaleType must match Axis ScaleType"); + + return (ActualMaxValue); + } + } + + return (MaxValue); + } + + return (ActualMaxValue); + } + + #endregion + + #region UpdateRangeValues + + internal void UpdateRangeValues() + { + if (SeriesRangeChanged == true) + { + SeriesRangeChanged = false; + + ActualMinValue = null; + ActualMaxValue = null; + + QualitativeValues.Clear(); + + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + { + if (chartXy.ChartSeries.Count > 0) + { + UpdateRangeValues(chartXy); + + if (QualitativeValues.Count > 1) + { + if (QualitativeSortDirection != SortDirection.None) + { + QualitativeValues.Sort(new + ObjComparer(this, QualitativeSortDirection == SortDirection.Ascending)); + } + } + } + } + } + } + + internal virtual void UpdateRangeValues(ChartXy chartXy) + { + } + + #region ObjComparer + + private class ObjComparer : IComparer + { + private ChartVisualElement _ChartElement; + private ChartControl _ChartControl; + + private bool _Ascending; + + public ObjComparer(ChartVisualElement chartElement, bool ascending) + { + _ChartElement = chartElement; + _ChartControl = chartElement.ChartControl; + + _Ascending = ascending; + } + + public int Compare(object v1, object v2) + { + int sval = 0; + + if (_ChartControl.DoCompareElementsEvent(_ChartElement, v1, v2, ref sval) == true) + return (sval); + + if (v1 is IComparable) + { + sval = ((IComparable)v1).CompareTo(v2); + + if (sval != 0) + return (_Ascending == true) ? sval : -sval; + } + + return (sval); + } + } + + #endregion + + #endregion + + #region ValidateAxis + + internal bool ValidateAxis() + { + bool altered = false; + + if (LastTickmarkLayout == null || TickmarkLayout == null) + altered = true; + + else if ((TickmarkLayout.MinValue != LastTickmarkLayout.MinValue) || + (TickmarkLayout.MaxValue != LastTickmarkLayout.MaxValue) || + (TickmarkLayout.MajorInterval != LastTickmarkLayout.MajorInterval) || + (TickmarkLayout.MajorSpacing != LastTickmarkLayout.MajorSpacing) || + (TickmarkLayout.MarginOffset != LastTickmarkLayout.MarginOffset)) + { + altered = true; + } + + LastTickmarkLayout = TickmarkLayout; + + return (altered); + } + + #endregion + + #region GetChartPoint + + protected Point GetChartPoint(Point pt) + { + ChartXy chartXy = Parent as ChartXy; + + pt.X += ScrollOffset.X; + pt.X -= (chartXy.HScrollBar.Inverted == true ? chartXy.HScrollOffset : -chartXy.HScrollOffset); + + pt.Y += ScrollOffset.Y; + pt.Y -= (chartXy.VScrollBar.Inverted == true ? chartXy.VScrollOffset : -chartXy.VScrollOffset); + + return (pt); + } + + #endregion + + #region GetDisplayValue + + virtual internal int GetDisplayValue(object axisValue) + { + return (0); + } + + #endregion + + #region GetDateTime + + internal DateTime GetDateTime(DateTime dt, double delta) + { + switch (ActualDateTimeUnits) + { + case DateTimeUnits.Milliseconds: + return (dt.AddMilliseconds(delta)); + + case DateTimeUnits.Seconds: + return (dt.AddSeconds(delta)); + + case DateTimeUnits.Minutes: + return (dt.AddMinutes(delta)); + + case DateTimeUnits.Hours: + return (dt.AddHours(delta)); + + case DateTimeUnits.Days: + return (dt.AddDays(delta)); + + case DateTimeUnits.Months: + dt = dt.AddMonths((int)delta); + dt = dt.AddDays((delta - (int)delta) * 31); + + return (dt); + + case DateTimeUnits.Years: + return (dt.AddYears((int)delta)); + + default: + return (dt.AddTicks((long)delta)); + } + } + + #endregion + + #region GetDateTimeValue + + internal long GetDateTimeValue(DateTime dtValue) + { + switch (ActualDateTimeUnits) + { + case DateTimeUnits.Milliseconds: + return (dtValue.Millisecond); + + case DateTimeUnits.Seconds: + return (dtValue.Second); + + case DateTimeUnits.Minutes: + return (dtValue.Minute); + + case DateTimeUnits.Hours: + return (dtValue.Hour); + + case DateTimeUnits.Days: + return (dtValue.Day); + + case DateTimeUnits.Months: + return (dtValue.Month); + + case DateTimeUnits.Years: + return (dtValue.Year); + + default: + return (dtValue.Ticks); + } + } + + #endregion + + #region GetDateTimePointValue + + internal DateTime GetDateTimePointValue(TickmarkLayout layout, int dz) + { + double delta = (double)(layout.MajorSpacing * ((dz + layout.MarginOffset) / layout.MajorInterval)); + + return (GetDateTime((DateTime)layout.BaseValue, delta)); + } + + #endregion + + #region GetDateTimeLabel + + internal string GetDateTimeLabel(DateTime dt) + { + switch (ActualDateTimeUnits) + { + case DateTimeUnits.Ticks: + return (dt.Ticks.ToString()); + + case DateTimeUnits.Milliseconds: + return (dt.Millisecond.ToString()); + + case DateTimeUnits.Seconds: + return (dt.Second.ToString()); + + case DateTimeUnits.Minutes: + return (dt.Minute.ToString()); + + case DateTimeUnits.Hours: + return (dt.ToShortTimeString()); + + case DateTimeUnits.Days: + return (dt.ToShortDateString()); + + case DateTimeUnits.Months: + return (dt.Month + "/" + dt.Year); + + default: + return (dt.Year.ToString()); + } + } + + #endregion + + #region GetTickmarkAltValue + + internal double GetTickmarkAltValue(TickmarkTick tick) + { + switch (ScaleType) + { + case ScaleType.DateTime: + DateTime dt = AddDateTimeOffset((DateTime)tick.Value, (int)(TickmarkLayout.MajorSpacing / 2)); + + return (GetDateTimeValue(dt)); + + case ScaleType.Qualitative: + return ((int)tick.Value + TickmarkLayout.MajorSpacing / 2); + + default: + return (Convert.ToDouble(tick.Value) + TickmarkLayout.MajorSpacing / 2); + } + } + + #endregion + + #region GetLegendData + + internal void GetLegendData(List legendData) + { + foreach (ReferenceLine line in ReferenceLines) + { + if (line.Visible == true) + { + List items = line.GetLegendItems(); + + if (items != null && items.Count > 0) + legendData.AddRange(items); + } + } + + foreach (AxisStripe stripe in AxisStripes) + { + if (stripe.Visible == true) + { + List items = stripe.GetLegendItems(); + + if (items != null && items.Count > 0) + legendData.AddRange(items); + } + } + } + + #endregion + + #region GetPointFromValue + + /// + /// Gets the chart Point from the given data value. + /// + /// + /// + public virtual Point GetPointFromValue(object value) + { + return (Point.Empty); + } + + #endregion + + #region GetValueFromPoint + + /// + /// Gets the "Data" value from the given Chart Point. + /// + /// + /// + public object GetValueFromPoint(Point pt) + { + TickmarkLayout layout = TickmarkLayout; + + return (GetValueFromPoint(layout, pt)); + } + + internal virtual object GetValueFromPoint(TickmarkLayout layout, Point pt) + { + return (null); + } + + #endregion + + #region GetReferenceLineByName + + /// + /// Gets the ReferenceLine from the given name. + /// + /// + /// + public ReferenceLine GetReferenceLineByName(string name) + { + if (String.IsNullOrEmpty(name) == true) + return (null); + + if (_ReferenceLines != null) + { + foreach (ReferenceLine line in _ReferenceLines) + { + if (name.Equals(line.Name) == true) + return (line); + } + } + + return (null); + } + + #endregion + + #region GetStripeByName + + /// + /// Gets the AxisStripe from the given name. + /// + /// + /// + public AxisStripe GetStripeByName(string name) + { + if (String.IsNullOrEmpty(name) == true) + return (null); + + if (_AxisStripes != null) + { + foreach (AxisStripe stripe in _AxisStripes) + { + if (name.Equals(stripe.Name) == true) + return (stripe); + } + } + + return (null); + } + + #endregion + + #region EnsureVisible + + /// + /// Ensures the given data value is visible on screen. + /// + /// + public void EnsureVisible(object value) + { + EnsureVisible(value, false); + } + + /// + /// Ensures the given data value is visible and + /// optionally centered on screen. + /// + /// + public virtual void EnsureVisible(object value, bool center) + { + } + + #endregion + + #region Style Support + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + ChartAxisVisualStyle astyle = style as ChartAxisVisualStyle; + + if (astyle != null) + { + ApplyParentStyles(astyle, Parent as ChartContainer); + + astyle.ApplyStyle(ChartAxisVisualStyle); + astyle.ApplyDefaults(); + } + else if (style is CrosshairValueVisualStyle) + { + CrosshairValueVisualStyle cstyle = (CrosshairValueVisualStyle)style; + + ApplyParentStyles(cstyle, Parent as ChartContainer); + + cstyle.ApplyStyle(CrosshairLabelVisualStyle); + cstyle.ApplyDefaults(); + } + } + + #region ApplyParentStyles (ChartAxisVisualStyle) + + private void ApplyParentStyles( + ChartAxisVisualStyle astyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(astyle, item.Parent as ChartContainer); + + ChartPanel cp = item as ChartPanel; + + if (cp != null) + { + if (_AxisOrientation == AxisOrientation.X) + astyle.ApplyStyle(cp.DefaultVisualStyles.ChartXAxisVisualStyle); + else + astyle.ApplyStyle(cp.DefaultVisualStyles.ChartYAxisVisualStyle); + } + } + else + { + if (_AxisOrientation == AxisOrientation.X) + { + astyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartXAxisVisualStyle); + astyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartXAxisVisualStyle); + } + else + { + astyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartYAxisVisualStyle); + astyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartYAxisVisualStyle); + } + } + } + + #endregion + + #region ApplyParentStyles (CrosshairLabelVisualStyle) + + private void ApplyParentStyles( + CrosshairValueVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is ChartPanel) + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.CrosshairLabelVisualStyle); + + else if (item is ChartXy) + pstyle.ApplyStyle(((ChartXy)item).ChartCrosshair.CrosshairLabelVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.CrosshairLabelVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.CrosshairLabelVisualStyle); + } + } + + #endregion + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Styles + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + _EffectiveAxisStyle.InvalidateStyle(); + } + + #endregion + + #endregion + + #region InvalidateRender + + /// + /// Invalidate the axis for rendering purposes. + /// + public override void InvalidateRender() + { + base.InvalidateRender(); + + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + chartXy.InvalidateRender(); + } + + #endregion + + #region RefreshRangeValues + + /// + /// Causes an invalidation and refresh of the range values for the axis. + /// + public void RefreshRangeValues() + { + SeriesRangeChanged = true; + + InvalidateLayout(); + } + + #endregion + + #region Copy/CopyTo + + /// + /// Copies the axis elements to the given "copy" + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + ChartAxis c = copy as ChartAxis; + + if (c != null) + { + base.CopyTo(c); + + c.AxisAlignment = AxisAlignment; + + c.AxisFarMargin = AxisFarMargin; + c.AxisMargins = AxisMargins; + c.AxisNearMargin = AxisNearMargin; + + foreach (AxisStripe stripe in AxisStripes) + c.AxisStripes.Add((AxisStripe)stripe.Copy()); + + c.ChartAxisVisualStyle = (_ChartAxisVisualStyle != null) ? ChartAxisVisualStyle.Copy() : null; + c.CrosshairLabelVisualStyle = (_CrosshairLabelVisualStyle != null) ? CrosshairLabelVisualStyle.Copy() : null; + + c.DateTimeUnits = DateTimeUnits; + c.GridInterval = GridInterval; + c.GridSpacing = GridSpacing; + + c.MinGridInterval = MinGridInterval; + + c.MaxValue = MaxValue; + c.MinValue = MinValue; + + foreach (ReferenceLine line in ReferenceLines) + c.ReferenceLines.Add((ReferenceLine)line.Copy()); + + Title.CopyTo(c.Title); + + c.UseAlternateBackground = UseAlternateBackground; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartAxis"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AxisAlignment", AxisAlignment, AxisAlignment.NotSet); + + sec.AddValue("AxisFarMargin", AxisFarMargin, -1); + sec.AddValue("AxisMargins", AxisMargins, -1); + sec.AddValue("AxisNearMargin", AxisNearMargin, -1); + + if (_AxisStripes != null && _AxisStripes.Count > 0) + { + sec.AddStartElement("AxisStripes count=\"" + _AxisStripes.Count + "\""); + + foreach (AxisStripe stripe in _AxisStripes) + sec.AddElement(stripe.GetSerialData("")); + + sec.AddEndElement("AxisStripes"); + } + + if (_ChartAxisVisualStyle != null && _ChartAxisVisualStyle.IsEmpty == false) + sec.AddElement(_ChartAxisVisualStyle.GetSerialData("ChartAxisVisualStyle")); + + if (_CrosshairLabelVisualStyle != null && _CrosshairLabelVisualStyle.IsEmpty == false) + sec.AddElement(_CrosshairLabelVisualStyle.GetSerialData("CrosshairLabelVisualStyle")); + + sec.AddValue("DateTimeUnits", DateTimeUnits, DateTimeUnits.Days); + + sec.AddValue("GridInterval", GridInterval, 0.0d); + sec.AddValue("GridSpacing", GridSpacing, 0.0d); + sec.AddValue("MinGridInterval", MinGridInterval, 10); + + sec.AddDataValue("MaxValue", MaxValue, null); + sec.AddDataValue("MinValue", MinValue, null); + + sec.AddValue("QualitativeSortDirection", QualitativeSortDirection, SortDirection.None); + + if (_ReferenceLines != null && _ReferenceLines.Count > 0) + { + sec.AddStartElement("ReferenceLines count=\"" + _ReferenceLines.Count + "\""); + + foreach (ReferenceLine rline in _ReferenceLines) + sec.AddElement(rline.GetSerialData("")); + + sec.AddEndElement("ReferenceLines"); + } + + if (_Title != null) + sec.AddElement(_Title.GetSerialData("Title")); + + sec.AddValue("UseAlternateBackground", UseAlternateBackground, false); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AxisAlignment": + AxisAlignment = (AxisAlignment)se.GetValueEnum(typeof(AxisAlignment)); + break; + + case "AxisFarMargin": + AxisFarMargin = int.Parse(se.StringValue); + break; + + case "AxisMargins": + AxisMargins = int.Parse(se.StringValue); + break; + + case "AxisNearMargin": + AxisNearMargin = int.Parse(se.StringValue); + break; + + case "DateTimeUnits": + DateTimeUnits = (DateTimeUnits)se.GetValueEnum(typeof(DateTimeUnits)); + break; + + case "GridInterval": + GridInterval = double.Parse(se.StringValue); + break; + + case "GridSpacing": + GridSpacing = double.Parse(se.StringValue); + break; + + case "MinGridInterval": + MinGridInterval = int.Parse(se.StringValue); + break; + + case "MaxValue": + MaxValue = se.DataValue; + break; + + case "MinValue": + MinValue = se.DataValue; + break; + + case "QualitativeSortDirection": + QualitativeSortDirection = (SortDirection)se.GetValueEnum(typeof(SortDirection)); + break; + + case "UseAlternateBackground": + UseAlternateBackground = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "AxisStripes": + case "ReferenceLines": + sec.PutSerialData(this); + break; + + case "AxisStripe": + AxisStripe stripe = GetStripeByName(se.Name); + + if (stripe != null) + sec.PutSerialData(stripe); + break; + + case "ChartAxisVisualStyle": + sec.PutSerialData(ChartAxisVisualStyle); + break; + + case "CrosshairLabelVisualStyle": + sec.PutSerialData(CrosshairLabelVisualStyle); + break; + + case "ReferenceLine": + ReferenceLine line = GetReferenceLineByName(se.Name); + + if (line != null) + sec.PutSerialData(line); + break; + + case "Title": + sec.PutSerialData(Title); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + AutoCalcBarMargins = (1U << 0), + + DotPlotAxis = (1U << 1), + EdgeAxis = (1U << 2), + PrimaryAxis = (1U << 3), + + SeriesRangeChanged = (1U << 4), + + UseAlternateBackground = (1U << 5), + UseAutoMinGridInterval = (1U << 6), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region ToString + + public override string ToString() + { + if (String.IsNullOrEmpty(Name) == false) + return (Name); + + return (base.ToString()); + } + + #endregion + + #region IDisposable + + public override void Dispose() + { + AxisStripes = null; + ChartAxisVisualStyle = null; + CrosshairLabelVisualStyle = null; + ReferenceLines = null; + Title = null; + + base.Dispose(); + } + + #endregion + } + + #endregion + + #region TickmarkLayout + + internal class TickmarkLayout + { + public object MinValue; + public object MaxValue; + + public object BaseValue; + + public int NearMargin; + public int FarMargin; + public int MarginOffset; + + public int MajorCount; + public int MinorCount; + + public double GridSpacing; + public double MajorSpacing; + public double MajorInterval; + + public int TickmarkStart; + public int TickmarkEnd; + + public TickmarkTick[] Ticks; + } + + #endregion + + #region TickmarkTick + + internal class TickmarkTick + { + public int Index; + public object Value; + public Point TickPoint; + + public string Label; + public Size LabelSize; + public Point LabelPoint; + public int LabelIndex; + public Color LabelColor; + + public SizeF TextSize; + + public bool LabelVisible; + } + + #endregion + + #region AxisBar + + internal class AxisBar + { + public int BarCount; + public int BarOffset; + public int BarTotalWidth; + + public double BarTotal; + + public void Reset() + { + BarCount = 0; + BarTotal = 0; + BarTotalWidth = 0; + + BarOffset = int.MinValue; + } + } + + #endregion + + public class AxisTitle : ChartTitle + { + #region XyAlignment + + [Browsable(false)] + [Bindable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [EditorBrowsable(EditorBrowsableState.Never)] + public new XyAlignment XyAlignment + { + get { return (base.XyAlignment); } + set { base.XyAlignment = value; } + } + + #endregion + } + + [Obsolete] + public class AsixTitle : AxisTitle + { + } + + #region Enums + + #region AxisAlignment + + public enum AxisAlignment + { + /// + /// Default is determined by the Axis (X/Y). + /// + NotSet = -1, + + /// + /// Axis is displayed at the right or bottom side of the chart. + /// + Near, + + /// + /// Axis is displayed at the left or top side of the chart. + /// + Far, + } + + #endregion + + #region AxisBarType + + internal enum AxisBarType + { + Bar, + HiLoBar, + + MaxBarCount + } + + #endregion + + #region AxisOrientation + + /// + /// AxisOrientation. + /// + public enum AxisOrientation + { + /// + /// X Axis + /// + X, + + /// + /// Y Axis + /// + Y, + } + + #endregion + + #region DateTimeUnits + + /// + /// DateTimeUnits + /// + public enum DateTimeUnits + { + Ticks, + Milliseconds, + Seconds, + Minutes, + Hours, + Days, + Months, + Years, + } + + #endregion + + #region MarginLayout + + public enum MarginLayout + { + /// + /// No Margins will be displayed. + /// + None, + + /// + /// Margin is displayed at the right or bottom side of the axis. + /// + Near, + + /// + /// Margin is displayed at the left or top side of the axis. + /// + Far, + + /// + /// Both Near and Far margins are displayed. + /// + Both, + } + + #endregion + + #region OriginOffsetMode + + /// + /// Mode for setting the axis origin, or offset from its + /// normal position. + /// + public enum OriginOffsetMode + { + /// + /// No offset + /// + None, + + /// + /// Origin is shifted by an absolute amount (OriginOffset) + /// + Absolute, + + /// + /// Origin is shifted relative to the major scale amounts. + /// + Relative, + + /// + /// Origin is shifted a percentage of the total axis length. + /// + Percent, + } + + #endregion + + #region OverlapLabelMode + + public enum OverlapLabelMode + { + /// + /// Default is to Hide overlapping labels. + /// + NotSet = 0, + + /// + /// Overlapping labels will be staggered. + /// + Stagger, + + /// + /// Overlapping labels may be hidden. + /// + Hide, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartGridLines.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartGridLines.cs new file mode 100644 index 00000000..bf0815de --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartGridLines.cs @@ -0,0 +1,800 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + #region ChartMajorGridLines + + #region ChartMajorGridLinesX + + /// + /// Represents a chart's MajorGridLines for the X-Axis. + /// + public class ChartMajorGridLinesX : ChartMajorGridLines + { + public ChartMajorGridLinesX() + : base(AxisOrientation.X) + { + } + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + if (Visible == true) + { + TickmarkTick[] ticks = TickmarkLayout.Ticks; + + if (ticks != null) + { + Graphics g = renderInfo.Graphics; + + ChartAxis axis = Parent as ChartAxis; + ChartXy chartXy = axis.Parent as ChartXy; + + PieGridLineVisualStyle gstyle = EffectiveStyle; + Rectangle scContentBounds = GetScrollBounds(chartXy.ContentBounds); + + if (gstyle.LinePattern != LinePattern.None && + gstyle.LinePattern != LinePattern.NotSet && gstyle.LineWidth > 0) + { + using (Pen pen = new Pen(gstyle.LineColor, Dpi.Width(gstyle.LineWidth))) + { + pen.DashStyle = (DashStyle)gstyle.LinePattern; + + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + foreach (TickmarkTick tmi in ticks) + { + Point pt1 = tmi.TickPoint; + pt1.X += pt.X; + pt1.Y = scContentBounds.Y; + + Point pt2 = pt1; + pt2.Y = scContentBounds.Bottom; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + } + } + + #endregion + + #region Copy/CopyTo + + /// + /// Create a copy of the MajorGridLine. + /// + /// + public override ChartVisualElement Copy() + { + ChartMajorGridLinesX copy = new ChartMajorGridLinesX(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the MajorGridLine to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + ChartMajorGridLinesX c = copy as ChartMajorGridLinesX; + + if (c != null) + base.CopyTo(c); + } + + #endregion + } + + #endregion + + #region ChartMajorGridLinesY + + /// + /// Represents a chart's MajorGridLines for the Y-Axis. + /// + public class ChartMajorGridLinesY : ChartMajorGridLines + { + public ChartMajorGridLinesY() + : base(AxisOrientation.Y) + { + } + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + if (Visible == true) + { + TickmarkTick[] ticks = TickmarkLayout.Ticks; + + if (ticks != null) + { + Graphics g = renderInfo.Graphics; + + ChartAxis axis = Parent as ChartAxis; + ChartXy chartXy = axis.Parent as ChartXy; + + PieGridLineVisualStyle gstyle = EffectiveStyle; + Rectangle scContentBounds = GetScrollBounds(chartXy.ContentBounds); + + if (gstyle.LinePattern != LinePattern.None && + gstyle.LinePattern != LinePattern.NotSet && gstyle.LineWidth > 0) + { + using (Pen pen = new Pen(gstyle.LineColor, Dpi.Height(gstyle.LineWidth))) + { + pen.DashStyle = (DashStyle)gstyle.LinePattern; + + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + foreach (TickmarkTick tmi in ticks) + { + Point pt1 = tmi.TickPoint; + pt1.X = scContentBounds.X; + pt1.Y += pt.Y; + + Point pt2 = pt1; + pt2.X = scContentBounds.Right; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + } + } + + #endregion + + #region Copy/CopyTo + + /// + /// Create a copy of the MajorGridLine. + /// + /// + public override ChartVisualElement Copy() + { + ChartMajorGridLinesY copy = new ChartMajorGridLinesY(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the MajorGridLine to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + ChartMajorGridLinesY c = copy as ChartMajorGridLinesY; + + if (c != null) + base.CopyTo(c); + } + + #endregion + } + + #endregion + + #region ChartMajorGridLines + + /// + /// Represents a chart's MajorGridLines. + /// + public class ChartMajorGridLines : ChartGridLines + { + public ChartMajorGridLines(AxisOrientation orientation) + : base(orientation) + { + } + } + + #endregion + + #endregion + + #region ChartMinorGridLines + + #region ChartMinorGridLinesX + + public class ChartMinorGridLinesX : ChartMinorGridLines + { + public ChartMinorGridLinesX() + : base(AxisOrientation.X) + { + } + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + if (Visible == true) + { + TickmarkTick[] ticks = TickmarkLayout.Ticks; + + if (ticks != null && ticks.Length > 1) + { + Graphics g = renderInfo.Graphics; + + ChartAxis axis = Parent as ChartAxis; + ChartXy chartXy = axis.Parent as ChartXy; + + PieGridLineVisualStyle gstyle = EffectiveStyle; + Rectangle scContentBounds = GetScrollBounds(chartXy.ContentBounds); + + if (gstyle.LinePattern != LinePattern.None && + gstyle.LinePattern != LinePattern.NotSet && gstyle.LineWidth > 0) + { + using (Pen pen = new Pen(gstyle.LineColor, Dpi.Width(gstyle.LineWidth))) + { + pen.DashStyle = (DashStyle)gstyle.LinePattern; + + int minorTickCount = axis.MinorTickmarks.TickmarkCount; + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + for (int i = 0; i < ticks.Length - 1; i++) + { + TickmarkTick tick = ticks[i]; + + Point pt1 = tick.TickPoint; + pt1.Y = scContentBounds.Y; + + Point pt2 = pt1; + pt2.Y = scContentBounds.Bottom; + + double dx = (double)(ticks[i + 1].TickPoint.X - tick.TickPoint.X) / (minorTickCount + 1); + double ddx = dx; + + for (int j = 0; j < minorTickCount; j++) + { + pt1.X = pt.X + (int)(tick.TickPoint.X + ddx); + pt2.X = pt1.X; + + ddx += dx; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + } + } + } + + #endregion + + #region Copy/CopyTo + + /// + /// Create a copy of the MinorGridLine. + /// + /// + public override ChartVisualElement Copy() + { + ChartMinorGridLinesX copy = new ChartMinorGridLinesX(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the MinorGridLine to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + ChartMinorGridLinesX c = copy as ChartMinorGridLinesX; + + if (c != null) + base.CopyTo(c); + } + + #endregion + } + + #endregion + + #region ChartMinorGridLinesY + + public class ChartMinorGridLinesY : ChartMinorGridLines + { + public ChartMinorGridLinesY() + : base(AxisOrientation.Y) + { + } + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + if (Visible == true) + { + TickmarkTick[] ticks = TickmarkLayout.Ticks; + + if (ticks != null) + { + Graphics g = renderInfo.Graphics; + + ChartAxis axis = Parent as ChartAxis; + ChartXy chartXy = axis.Parent as ChartXy; + + PieGridLineVisualStyle gstyle = EffectiveStyle; + Rectangle scContentBounds = GetScrollBounds(chartXy.ContentBounds); + + if (gstyle.LinePattern != LinePattern.None && + gstyle.LinePattern != LinePattern.NotSet && gstyle.LineWidth > 0) + { + using (Pen pen = new Pen(gstyle.LineColor, Dpi.Height(gstyle.LineWidth))) + { + pen.DashStyle = (DashStyle)gstyle.LinePattern; + + int minorTickCount = axis.MinorTickmarks.TickmarkCount; + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + for (int i = 0; i < ticks.Length - 1; i++) + { + TickmarkTick tick = ticks[i]; + + Point pt1 = tick.TickPoint; + pt1.X = scContentBounds.X; + + Point pt2 = pt1; + pt2.X = scContentBounds.Right; + + double dy = (double)(ticks[i + 1].TickPoint.Y - tick.TickPoint.Y) / (minorTickCount + 1); + double ddy = dy; + + for (int j = 0; j < axis.MinorTickmarks.TickmarkCount; j++) + { + pt1.Y = pt.Y + (int)(tick.TickPoint.Y + ddy); + pt2.Y = pt1.Y; + + ddy += dy; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + } + } + } + + #endregion + + #region Copy/CopyTo + + /// + /// Create a copy of the MinorGridLine. + /// + /// + public override ChartVisualElement Copy() + { + ChartMinorGridLinesY copy = new ChartMinorGridLinesY(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the MinorGridLine to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + ChartMinorGridLinesY c = copy as ChartMinorGridLinesY; + + if (c != null) + base.CopyTo(c); + } + + #endregion + } + + #endregion + + #region ChartMinorGridLines + + public class ChartMinorGridLines : ChartGridLines + { + public ChartMinorGridLines(AxisOrientation orientation) + : base(orientation) + { + } + } + + #endregion + + #endregion + + #region ChartGridLines + + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public abstract class ChartGridLines : ChartVisualElement + { + #region Private variables + + private States _States; + + private AxisOrientation _AxisOrientation; + private TickmarkLayout _TickmarkLayout; + + private PieGridLineVisualStyle _GridLinesVisualStyle; + private EffectiveStyle _EffectiveStyle; + + #endregion + + public ChartGridLines(AxisOrientation orientation) + { + _AxisOrientation = orientation; + + InitDefaultStates(); + + _EffectiveStyle = new EffectiveStyle(this); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + } + + #endregion + + #region Public properties + + #region DisplayOnTop + + /// + /// Gets or sets whether grid lines are displayed on top of chart data. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether grid lines are displayed on top of chart data.")] + public bool DisplayOnTop + { + get { return (TestState(States.DisplayOnTop)); } + + set + { + if (value != DisplayOnTop) + { + SetState(States.DisplayOnTop, value); + + OnPropertyChangedEx("DisplayOnTop", VisualChangeType.Render); + } + } + } + + #endregion + + #region EffectiveStyles + + /// + /// Gets a reference to the GridLine's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public PieGridLineVisualStyle EffectiveStyle + { + get { return (_EffectiveStyle.Style); } + } + + #endregion + + #region GridLinesVisualStyle + + /// + /// Gets or sets the visual style for the GridLines. + /// + [Category("Style")] + [Description("Indicates the visual style for the GridLines.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieGridLineVisualStyle GridLinesVisualStyle + { + get + { + if (_GridLinesVisualStyle == null) + { + _GridLinesVisualStyle = new PieGridLineVisualStyle(); + + StyleVisualChangeHandler(null, _GridLinesVisualStyle); + } + + return (_GridLinesVisualStyle); + } + + set + { + if (_GridLinesVisualStyle != value) + { + PieGridLineVisualStyle oldValue = _GridLinesVisualStyle; + + _GridLinesVisualStyle = value; + + OnVisualStyleChanged("GridLinesVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region TickmarkLayout + + internal TickmarkLayout TickmarkLayout + { + get { return (_TickmarkLayout); } + set { _TickmarkLayout = value; } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + BoundsRelative = layoutInfo.LayoutBounds; + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + } + + #endregion + + #region Render + + internal override void Render(ChartRenderInfo renderInfo) + { + if (Displayed == true) + { + Rectangle bounds = BoundsRelative; + + if (renderInfo.ClipRectangle.IntersectsWith(bounds)) + RenderOverride(renderInfo); + } + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + PieGridLineVisualStyle sstyle = style as PieGridLineVisualStyle; + + if (sstyle != null) + { + ApplyParentStyles(sstyle, Parent as ChartContainer); + + sstyle.ApplyStyle(GridLinesVisualStyle); + + if (sstyle.LineColor.IsEmpty == true) + { + if (this is ChartMajorGridLines) + sstyle.LineColor = Color.DimGray; + else + sstyle.LineColor = Color.LightGray; + } + + if (sstyle.LinePattern == LinePattern.NotSet) + sstyle.LinePattern = LinePattern.Solid; + + if (sstyle.LineWidth < 0) + sstyle.LineWidth = 1; + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles(PieGridLineVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is ChartPanel) + { + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.GridLineVisualStyle); + } + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.GridLineVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.GridLineVisualStyle); + } + } + + #endregion + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + if (_EffectiveStyle.InvalidateStyle() == true) + InvalidateLayout(); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + /// + /// Copies the chart element to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + ChartGridLines c = copy as ChartGridLines; + + if (c != null) + { + base.CopyTo(c); + + c.DisplayOnTop = DisplayOnTop; + + c.GridLinesVisualStyle = (_GridLinesVisualStyle != null) ? GridLinesVisualStyle.Copy() : null; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartGridLines"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("DisplayOnTop", DisplayOnTop, false); + + if (_GridLinesVisualStyle != null && _GridLinesVisualStyle.IsEmpty == false) + sec.AddElement(_GridLinesVisualStyle.GetSerialData("GridLinesVisualStyle")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "DisplayOnTop": + DisplayOnTop = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "GridLinesVisualStyle": + sec.PutSerialData(GridLinesVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + DisplayOnTop = (1U << 0), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + GridLinesVisualStyle = null; + + base.Dispose(); + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartSeries.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartSeries.cs new file mode 100644 index 00000000..4bb43172 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartSeries.cs @@ -0,0 +1,9905 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of ChartSeries. + /// + [Editor("DevComponents.Charts.Design.ChartSeriesCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ChartSeriesCollection : CustomNamedCollection + { + #region GetUniqueName + + public string GetUniqueName() + { + return (GetUniqueName("Series")); + } + + #endregion + } + + public class ChartSeries : BaseSeries + { + #region Constants + + private const int StockHigh = 0; + private const int StockLow = 1; + private const int StockClose = 2; + private const int StockOpen = 3; + private const int StockMedian = 4; + + #endregion + + #region Private variables + + private States _States; + + private SeriesPointCollection _SeriesPoints; + + private PointData _PointData; + private PointData _EmptyPointData; + private PointData _StepPointData; + + private ChartAxis _AxisX; + private ChartAxis _AxisY; + + private int _BarOffset; + private int _BarWidth; + private double _BarWidthRatio; + + private Tbool _BarShadingEnabled = Tbool.NotSet; + private BarFillRange _BarFillRange = BarFillRange.NotSet; + private BarLabelPosition _BarLabelPosition = BarLabelPosition.NotSet; + + private Color[] _BarShadingColors; + + private ChartSeriesVisualStyle _ChartSeriesVisualStyle; + private EffectiveStyle _EffectiveChartSeriesStyle; + + private DataLabelVisualStyle _DataLabelVisualStyle; + private EffectiveStyle _EffectiveDataLabelStyle; + + private Tbool _CrosshairEnabled = Tbool.NotSet; + private Tbool _CrosshairHighlightPoints = Tbool.NotSet; + private Tbool _CrosshairHighlightSinglePoint = Tbool.NotSet; + private Tbool _CrosshairShowLabels = Tbool.NotSet; + + private ScaleType _ScaleTypeX = ScaleType.NotSet; + private ScaleType _ScaleTypeY = ScaleType.NotSet; + private ScaleType _ActualScaleTypeX = ScaleType.NotSet; + private ScaleType _ActualScaleTypeY = ScaleType.NotSet; + + private object _MinValueX; + private object _MinValueY; + + private object _MaxValueX; + private object _MaxValueY; + + private object _AreaBaseValue; + + private SortedSeriesPoints _SortedSeriesPoints; + private object[] _EmptyValues; + + private List _QualitativeXValues; + private List _QualitativeYValues; + + private PointMarker _PointMarker; + private Image _PointMarkerImage; + private Image _PointMarkerEmptyImage; + private Image _PointMarkerHighlightImage; + private Point _PointOffset; + + private int _GroupId; + private object _PlotData; + private double _DotPlotIndexValue = 1.0d; + + private ChartIndicatorCollection _ChartIndicators; + private Point[] _ConvexHullPoints; + + private double _BubbleScaleFactor = 1.0d; + private double _BubbleMaxPercentage = .25d; + private int _BubbleMinSize = 4; + + private BubbleSizeMode _BubbleSizeMode = BubbleSizeMode.NotSet; + private BubbleIntensityMode _BubbleIntensityMode = BubbleIntensityMode.NotSet; + private ChartLineDisplayMode _ChartLineDisplayMode = ChartLineDisplayMode.NotSet; + private ChartLineAreaDisplayMode _ChartLineAreaDisplayMode = ChartLineAreaDisplayMode.NotSet; + private ConvexHullDisplayMode _ConvexHullDisplayMode = ConvexHullDisplayMode.NotSet; + private PointLabelDisplayMode _PointLabelDisplayMode = PointLabelDisplayMode.NotSet; + + private StepLines _StepLines = StepLines.NotSet; + private StepLineMode _StepLineMode = StepLineMode.NotSet; + private StepLineMode _LastStepLineMode = StepLineMode.NotSet; + + private DataLabelCollection _DataLabels; + private int _PointLabelSkip; + private int _PointLabelMinDistance; + + private HiLoBarType _HiLoBarType = HiLoBarType.Box; + + #endregion + + #region Constructors + + public ChartSeries() + : this(null, SeriesType.Point) + { + } + + public ChartSeries(string name) + : this(name, SeriesType.Point) + { + } + + public ChartSeries(SeriesType seriesType) + : this(null, seriesType) + { + } + + public ChartSeries(string name, SeriesType seriesType) + { + Name = name; + SeriesType = seriesType; + + InitDefaultStates(); + + _EffectiveChartSeriesStyle = new EffectiveStyle(this); + _EffectiveDataLabelStyle = new EffectiveStyle(this); + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.ShowInLegend, true); + SetState(States.ShowInParentLegend, true); + SetState(States.ShowCheckBoxInLegend, true); + SetState(States.ShowMarkerInLegend, true); + SetState(States.CheckedInLegend, true); + SetState(States.DisplayLinePointsOnTop, true); + SetState(States.StackQualitativePoints, true); + SetState(States.ShowOriginValueLabels, true); + SetState(States.ShowInnerRingsEx, true); + } + + #endregion + + #region Public properties + + #region ActualScaleTypeX + + /// + /// Gets the Actual X axis Scale Type (may be + /// different than XScaleType when XScaleType is 'Auto'). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ScaleType ActualScaleTypeX + { + get + { + if (IsRotated == false) + return (_ActualScaleTypeX); + + return (_ActualScaleTypeY); + } + + internal set { _ActualScaleTypeX = value; } + } + + #endregion + + #region ActualScaleTypeY + + /// + /// Gets the Actual Y axis Scale Type (may be + /// different than YScaleType when YScaleType is 'Auto'). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ScaleType ActualScaleTypeY + { + get + { + if (IsRotated == true) + return (_ActualScaleTypeX); + + return (_ActualScaleTypeY); + } + + internal set { _ActualScaleTypeY = value; } + } + + #endregion + + #region AreaBaseValue + + /// + /// Gets or sets the base, reference value for displaying Line/Spline/Step Areas. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the base, reference value for displaying Line/Spline/Step Areas.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter," + + "DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object AreaBaseValue + { + get { return (_AreaBaseValue); } + + set + { + if (value != _AreaBaseValue) + { + _AreaBaseValue = value; + + OnPropertyChangedEx("AreaBaseValue", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region AxisX + + /// + /// Gets a reference to the X-Axis associated with the series. + /// + [Category("Axis"), DefaultValue(null)] + [Description("Indicates the reference to the X-Axis associated with the series.")] + [TypeConverter(typeof(AxisTypeConverter))] + [Editor("DevComponents.Charts.Design.AxisListTypeEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartAxis AxisX + { + get { return (_AxisX); } + + set + { + if (value != _AxisX) + { + ChartXy chartXy = Parent as ChartXy; + + if (value != null) + { + if (value.IsPrimaryAxis == false) + { + if (chartXy != null) + { + if (chartXy.AncillaryAxesX.Contains(value) == false) + { + throw new Exception("Cannot set the series XAxis. The axis is not primary " + + "or a member of the chart's AncillaryAxesX collection."); + } + } + } + } + + if (_AxisX != null) + { + _AxisX.SeriesRangeChanged = true; + _AxisX.PropertyChanged -= AxisX_PropertyChanged; + } + else + { + if (chartXy != null) + chartXy.AxisX.SeriesRangeChanged = true; + } + + _AxisX = value; + + if (_AxisX != null) + { + _AxisX.SeriesRangeChanged = true; + _AxisX.PropertyChanged += AxisX_PropertyChanged; + } + else + { + if (chartXy != null) + chartXy.AxisX.SeriesRangeChanged = true; + } + + OnPropertyChangedEx("AxisX", VisualChangeType.Layout); + } + } + } + + void AxisX_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateLayout(); + } + + #endregion + + #region AxisY + + /// + /// Gets a reference to the Y-Axis associated with the series. + /// + [Category("Axis"), DefaultValue(null)] + [Description("Indicates the reference to the Y-Axis associated with the series.")] + [Editor("DevComponents.Charts.Design.AxisListTypeEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartAxis AxisY + { + get { return (_AxisY); } + + set + { + if (value != _AxisY) + { + ChartXy chartXy = Parent as ChartXy; + + if (value != null) + { + if (value.IsPrimaryAxis == false) + { + if (chartXy != null) + { + if (chartXy.AncillaryAxesY.Contains(value) == false) + { + throw new Exception("Cannot set the series YAxis. The axis is not primary " + + "or a member of the chart's AncillaryAxesY collection."); + } + } + } + } + + if (_AxisY != null) + { + _AxisY.SeriesRangeChanged = true; + _AxisY.PropertyChanged -= AxisY_PropertyChanged; + } + else + { + if (chartXy != null) + chartXy.AxisY.SeriesRangeChanged = true; + } + + _AxisY = value; + + if (_AxisY != null) + { + _AxisY.SeriesRangeChanged = true; + _AxisY.PropertyChanged += AxisY_PropertyChanged; + } + else + { + if (chartXy != null) + chartXy.AxisY.SeriesRangeChanged = true; + } + + OnPropertyChangedEx("AxisY", VisualChangeType.Layout); + } + } + } + + void AxisY_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateLayout(); + } + + #endregion + + #region BarFillRange + + /// + /// Gets or sets how series bars are filled (either according to + /// each individual bar range, or the entire series range). + /// + [DefaultValue(BarFillRange.NotSet), Category("Bar Display")] + [Description("Indicates how series bars are filled (either according to each individual bar range, or the entire series range).")] + public BarFillRange BarFillRange + { + get { return (_BarFillRange); } + + set + { + if (value != _BarFillRange) + { + _BarFillRange = value; + + OnPropertyChangedEx("BarFillRange", VisualChangeType.Render); + } + } + } + + #endregion + + #region BarLabelPosition + + /// + /// Gets or sets the position of bar series labels (default is Center). + /// + [DefaultValue(BarLabelPosition.NotSet), Category("Bar Display")] + [Description("Indicates the position of bar series labels (default is Center).")] + public BarLabelPosition BarLabelPosition + { + get { return (_BarLabelPosition); } + + set + { + if (value != _BarLabelPosition) + { + _BarLabelPosition = value; + + OnPropertyChangedEx("BarLabelPosition", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BarShadingEnabled + + /// + /// Gets or sets whether Bar shading is enabled for Horizontal and Vertical Bar series. + /// + [DefaultValue(Tbool.NotSet), Category("Bar Display")] + [Description("Indicates whether Bar shading is enabled for Horizontal and Vertical Bar series.")] + public Tbool BarShadingEnabled + { + get { return (_BarShadingEnabled); } + + set + { + if (value != _BarShadingEnabled) + { + _BarShadingEnabled = value; + + OnPropertyChangedEx("BarShadingEnabled", VisualChangeType.Render); + } + } + } + + #endregion + + #region BarWidthRatio + + /// + /// Gets or sets the ratio of bar width to bar spacing within + /// the same series (defaults to 2 - bar is twice as wide as spacing). + /// + [DefaultValue(0d), Category("Bar Display")] + [Description("Indicates the ratio of bar width to bar spacing within the same series (defaults to 2 - bar is twice as wide as spacing).")] + public double BarWidthRatio + { + get { return (_BarWidthRatio); } + + set + { + if (value != _BarWidthRatio) + { + if (value < 0) + throw new ArgumentException("Value must be > 0"); + + _BarWidthRatio = value; + + OnPropertyChangedEx("BarWidthRatio", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BubbleIntensityMode + + /// + /// Gets or sets the mode used to determine bubble intensities. + /// + [DefaultValue(BubbleIntensityMode.NotSet), Category("Display")] + [Description("Indicates the mode used to determine bubble intensities.")] + public BubbleIntensityMode BubbleIntensityMode + { + get { return (_BubbleIntensityMode); } + + set + { + if (value != _BubbleIntensityMode) + { + _BubbleIntensityMode = value; + + OnPropertyChangedEx("BubbleIntensityMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region BubbleMaxPercentage + + /// + /// Gets or sets the max percentage of the display + /// area used to calculate series bubble sizes (default is .25). + /// + [DefaultValue(0.25d), Category("Display")] + [Description("Indicates the max percentage of the display area used to calculate series bubble sizes (default is .25).")] + public double BubbleMaxPercentage + { + get { return (_BubbleMaxPercentage); } + + set + { + if (value != _BubbleMaxPercentage) + { + if (value <= 0 || value > 1) + throw new ArgumentException("Value must be between 0 and 1"); + + _BubbleMaxPercentage = value; + + OnPropertyChangedEx("BubbleMaxPercentage", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BubbleMinSize + + /// + /// Gets or sets the minimum series bubble size (in pixels) Default is 4. + /// + [DefaultValue(4), Category("Display")] + [Description("Indicates the minimum series bubble size (in pixels). Default is 4.")] + public int BubbleMinSize + { + get { return (_BubbleMinSize); } + + set + { + if (value != _BubbleMinSize) + { + if (value < 0) + throw new ArgumentException("Value must be > 0"); + + _BubbleMinSize = value; + + OnPropertyChangedEx("BubbleMinSize", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BubbleScaleFactor + + /// + /// Gets or sets the Scale Factor used to calculate series bubble sizes. + /// + [DefaultValue(1.0d), Category("Display")] + [Description("Indicates the Scale Factor used to calculate series bubble sizes.")] + public double BubbleScaleFactor + { + get { return (_BubbleScaleFactor); } + + set + { + if (value != _BubbleScaleFactor) + { + _BubbleScaleFactor = value; + + OnPropertyChangedEx("BubbleScaleFactor", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BubbleSizeMode + + /// + /// Gets or sets the mode used to calculate series bubble sizes. + /// + [DefaultValue(BubbleSizeMode.NotSet), Category("Display")] + [Description("Indicates the mode used to calculate series bubble sizes.")] + public BubbleSizeMode BubbleSizeMode + { + get { return (_BubbleSizeMode); } + + set + { + if (value != _BubbleSizeMode) + { + _BubbleSizeMode = value; + + OnPropertyChangedEx("BubbleSizeMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ChartIndicators + + /// + /// Gets a reference to the Chart Indicators collection. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Chart Indicators collection.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartIndicatorCollection ChartIndicators + { + get + { + if (_ChartIndicators == null) + { + _ChartIndicators = new ChartIndicatorCollection(); + + _ChartIndicators.CollectionChanged += ChartIndicators_CollectionChanged; + } + + return (_ChartIndicators); + } + + internal set + { + if (_ChartIndicators != null) + _ChartIndicators.CollectionChanged -= ChartIndicators_CollectionChanged; + + _ChartIndicators = value; + + if (_ChartIndicators != null) + _ChartIndicators.CollectionChanged += ChartIndicators_CollectionChanged; + } + } + + #region ChartIndicators_CollectionChanged + + void ChartIndicators_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + bool updateLayout = false; + + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (ChartIndicator ci in e.NewItems) + { + if (ci.ShowInLegend == true || ci.ShowInParentLegend == true) + updateLayout = true; + + ci.Parent = this; + } + break; + + case NotifyCollectionChangedAction.Replace: + foreach (ChartIndicator ci in e.OldItems) + { + if (ci.ShowInLegend == true || ci.ShowInParentLegend == true) + updateLayout = true; + + ci.Parent = null; + } + + foreach (ChartIndicator ci in e.NewItems) + { + if (ci.ShowInLegend == true || ci.ShowInParentLegend == true) + updateLayout = true; + + ci.Parent = this; + } + break; + + case NotifyCollectionChangedAction.Remove: + foreach (ChartIndicator ci in e.OldItems) + { + if (ci.ShowInLegend == true || ci.ShowInParentLegend == true) + updateLayout = true; + + ci.Parent = null; + } + break; + } + + if (updateLayout == true) + InvalidateLayout(); + else + InvalidateRender(); + } + + #endregion + + #endregion + + #region ChartLineAreaDisplayMode + + /// + /// Gets or sets the Line 'Area' display mode. + /// + [DefaultValue(ChartLineAreaDisplayMode.NotSet), Category("Display")] + [Description("Indicates the Line ChartType display mode.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartLineAreaDisplayMode ChartLineAreaDisplayMode + { + get { return (_ChartLineAreaDisplayMode); } + + set + { + if (value != _ChartLineAreaDisplayMode) + { + _ChartLineAreaDisplayMode = value; + + OnPropertyChangedEx("ChartLineAreaDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ChartLineDisplayMode + + /// + /// Gets or sets the Line ChartType display mode. + /// + [DefaultValue(ChartLineDisplayMode.NotSet), Category("Display")] + [Description("Indicates the Line ChartType display mode.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartLineDisplayMode ChartLineDisplayMode + { + get { return (_ChartLineDisplayMode); } + + set + { + if (value != _ChartLineDisplayMode) + { + _ChartLineDisplayMode = value; + + _SortedSeriesPoints = null; + + OnPropertyChangedEx("ChartLineDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ChartSeriesVisualStyle + + /// + /// Gets or sets the visual style for the series. + /// + [Category("Style")] + [Description("Indicates the visual style for the series.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSeriesVisualStyle ChartSeriesVisualStyle + { + get + { + if (_ChartSeriesVisualStyle == null) + { + _ChartSeriesVisualStyle = new ChartSeriesVisualStyle(); + + StyleVisualChangeHandler(null, _ChartSeriesVisualStyle); + } + + return (_ChartSeriesVisualStyle); + } + + set + { + if (_ChartSeriesVisualStyle != value) + { + ChartSeriesVisualStyle oldValue = _ChartSeriesVisualStyle; + + _ChartSeriesVisualStyle = value; + + OnStyleChanged("ChartSeriesVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ConvexHullDisplayMode + + /// + /// Gets or sets the ConvexHull display mode. + /// + [DefaultValue(ConvexHullDisplayMode.NotSet), Category("Display")] + [Description("Indicates the ConvexHull display mode.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ConvexHullDisplayMode ConvexHullDisplayMode + { + get { return (_ConvexHullDisplayMode); } + + set + { + if (value != _ConvexHullDisplayMode) + { + _ConvexHullDisplayMode = value; + + OnPropertyChangedEx("ConvexHullDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region CrosshairEnabled + + /// + /// Gets or sets whether Crosshair support is enabled for the series. + /// + [DefaultValue(Tbool.NotSet), Category("Crosshair")] + [Description("Indicates whether Crosshair support is enabled for the series.")] + public Tbool CrosshairEnabled + { + get { return (_CrosshairEnabled); } + + set + { + if (value != _CrosshairEnabled) + { + _CrosshairEnabled = value; + + OnPropertyChanged("CrosshairEnabled"); + } + } + } + + #endregion + + #region CrosshairHighlightPoints + + /// + /// Gets or sets whether Crosshair Point highlighting is enabled for the series. + /// + [DefaultValue(Tbool.NotSet), Category("Crosshair")] + [Description("Indicates whether Crosshair Point highlighting is enabled for the series.")] + public Tbool CrosshairHighlightPoints + { + get { return (_CrosshairHighlightPoints); } + + set + { + if (value != _CrosshairHighlightPoints) + { + _CrosshairHighlightPoints = value; + + OnPropertyChanged("CrosshairHighlightPoints"); + } + } + } + + #endregion + + #region CrosshairHighlightSinglePoint + + /// + /// Gets or sets whether Crosshair Point highlighting will + /// only highlight a single point for the series. + /// + [DefaultValue(Tbool.NotSet), Category("Crosshair")] + [Description("Indicates whether Crosshair Point highlighting will only highlight a single point for the series.")] + public Tbool CrosshairHighlightSinglePoint + { + get { return (_CrosshairHighlightSinglePoint); } + + set + { + if (value != _CrosshairHighlightSinglePoint) + { + _CrosshairHighlightSinglePoint = value; + + OnPropertyChanged("CrosshairHighlightSinglePoint"); + } + } + } + + #endregion + + #region CrosshairShowLabels + + /// + /// Gets or sets whether Crosshair labels are shown for the series. + /// + [DefaultValue(Tbool.NotSet), Category("Crosshair")] + [Description("Indicates whether Crosshair labels are shown for the series.")] + public Tbool CrosshairShowLabels + { + get { return (_CrosshairShowLabels); } + + set + { + if (value != _CrosshairShowLabels) + { + _CrosshairShowLabels = value; + + OnPropertyChanged("CrosshairShowLabels"); + } + } + } + + #endregion + + #region DataLabels + + /// + /// Gets or sets the list of instance Data Labels. + /// + [DefaultValue(null), Category("DataLabel")] + [Description("Indicates the list of instance Data Labels.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DataLabelCollection DataLabels + { + get + { + if (_DataLabels == null) + { + _DataLabels = new DataLabelCollection(); + + _DataLabels.PropertyChanged += DataLabels_PropertyChanged; + _DataLabels.CollectionChanged += DataLabels_CollectionChanged; + } + + return (_DataLabels); + } + + internal set + { + if (_DataLabels != null) + { + _DataLabels.PropertyChanged -= DataLabels_PropertyChanged; + _DataLabels.CollectionChanged -= DataLabels_CollectionChanged; + } + + _DataLabels = value; + + if (_DataLabels != null) + { + _DataLabels.PropertyChanged += DataLabels_PropertyChanged; + _DataLabels.CollectionChanged += DataLabels_CollectionChanged; + } + } + } + + #region DataLabels_PropertyChanged + + void DataLabels_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateRender(); + } + + #endregion + + #region DataLabels_CollectionChanged + + private void DataLabels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (DataLabel dl in e.NewItems) + { + dl.Parent = this; + dl.PropertyChanged += DataLabel_PropertyChanged; + } + break; + + case NotifyCollectionChangedAction.Replace: + foreach (DataLabel dl in e.OldItems) + { + dl.Parent = null; + dl.PropertyChanged -= DataLabel_PropertyChanged; + } + + foreach (DataLabel dl in e.NewItems) + { + dl.Parent = this; + dl.PropertyChanged += DataLabel_PropertyChanged; + } + break; + + case NotifyCollectionChangedAction.Remove: + case NotifyCollectionChangedAction.Reset: + if (e.OldItems != null) + { + foreach (DataLabel dl in e.OldItems) + dl.PropertyChanged -= DataLabel_PropertyChanged; + } + break; + } + + InvalidateLayout(); + } + + private void DataLabel_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateLayout(); + } + + #endregion + + #endregion + + #region DataLabelVisualStyle + + /// + /// Gets or sets the visual style for the data labels. + /// + [Category("Style")] + [Description("Indicates the visual style for the data labels.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DataLabelVisualStyle DataLabelVisualStyle + { + get + { + if (_DataLabelVisualStyle == null) + { + _DataLabelVisualStyle = new DataLabelVisualStyle(); + + StyleVisualChangeHandler(null, _DataLabelVisualStyle); + } + + return (_DataLabelVisualStyle); + } + + set + { + if (_DataLabelVisualStyle != value) + { + DataLabelVisualStyle oldValue = _DataLabelVisualStyle; + + _DataLabelVisualStyle = value; + + OnStyleChanged("DataLabelVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region DisplayLinePointsOnTop + + /// + /// Gets or sets whether series points are displayed on top of series line. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether series points are displayed on top of series line.")] + public bool DisplayLinePointsOnTop + { + get { return (TestState(States.DisplayLinePointsOnTop)); } + + set + { + if (value != DisplayLinePointsOnTop) + { + SetState(States.DisplayLinePointsOnTop, value); + + OnPropertyChangedEx("DisplayLinePointsOnTop", VisualChangeType.Render); + } + } + } + + #endregion + + #region DotPlotIndexValue + + /// + /// Gets or sets the value used to index between DotPlot points. Default is 1. + /// + [DefaultValue(1.0d), Category("Display")] + [Description("Indicates the value used to index between DotPlot points. Default is 1.")] + public double DotPlotIndexValue + { + get { return (_DotPlotIndexValue); } + + set + { + if (value != _DotPlotIndexValue) + { + if (value < 0) + throw new ArgumentException("Value must be > 0"); + + _DotPlotIndexValue = value; + + OnPropertyChangedEx("DotPlotIndexValue", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EffectiveDataLabelStyle + + /// + /// Gets a reference to the DataLabel effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DataLabelVisualStyle EffectiveDataLabelStyle + { + get { return (_EffectiveDataLabelStyle.Style); } + } + + #endregion + + #region EffectiveSeriesStyle + + /// + /// Gets a reference to the Series's effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates a reference to the Series's Effective (cached, composite) style.")] + public ChartSeriesVisualStyle EffectiveChartSeriesStyle + { + get { return (_EffectiveChartSeriesStyle.Style); } + } + + #endregion + + #region EmptyValues + + /// + /// Gets or sets the value(s) used to determine if + /// a series point is empty or missing. + /// + [Category("Empty")] + [Description("Indicates the value(s) used to determine if a series point is empty or missing.")] + [Editor("DevComponents.Charts.Design.SeriesPointValueEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public object[] EmptyValues + { + get { return (_EmptyValues); } + + set + { + if (value != _EmptyValues) + { + _EmptyValues = value; + + OnPropertyChangedEx("EmptyValue", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableEmptyValues + + /// + /// Gets or sets whether EmptyValues are processed in the series + /// + [DefaultValue(false), Category("Empty")] + [Description("Indicates whether EmptyValues are processed in the series.")] + public bool EnableEmptyValues + { + get { return (TestState(States.EnableEmptyValues)); } + + set + { + if (value != EnableEmptyValues) + { + SetState(States.EnableEmptyValues, value); + + _PointData = null; + _EmptyPointData = null; + _StepPointData = null; + + OnPropertyChangedEx("EnableEmptyValues", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupId + + /// + /// Gets or sets the logical Id used to group qualitative series. + /// + [DefaultValue(0), Category("Display")] + [Description("Indicates the logical Id used to group qualitative series).")] + public int GroupId + { + get { return (_GroupId); } + + set + { + if (value != _GroupId) + { + _GroupId = value; + + OnPropertyChangedEx("GroupId", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region HiLoBarType + + /// + /// Gets or sets the Series HiLoBar Type. + /// + [DefaultValue(HiLoBarType.Box), Category("Appearance")] + [Description("Indicates the Series HiLoBar Type.")] + public HiLoBarType HiLoBarType + { + get { return (_HiLoBarType); } + + set + { + if (value != _HiLoBarType) + { + _HiLoBarType = value; + + OnPropertyChangedEx("HiLoBarType", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxValueX + + /// + /// Gets the series Maximum X value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MaxValueX + { + get + { + UpdateSeriesRange(); + + if (IsRotated == true) + return (_MaxValueY); + + return (_MaxValueX); + } + } + + #endregion + + #region MaxValueY + + /// + /// Gets the series Maximum Y value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MaxValueY + { + get + { + UpdateSeriesRange(); + + if (IsRotated == true) + return (_MaxValueX); + + return (_MaxValueY); + } + } + + #endregion + + #region MinValueX + + /// + /// Gets the series minimum X value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MinValueX + { + get + { + UpdateSeriesRange(); + + if (IsRotated == true) + return (_MinValueY); + + return (_MinValueX); + } + } + + #endregion + + #region MinValueY + + /// + /// Gets the series minimum Y value. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MinValueY + { + get + { + UpdateSeriesRange(); + + if (IsRotated == true) + return (_MinValueX); + + return (_MinValueY); + } + } + + #endregion + + #region PointLabelDisplayMode + + /// + /// Gets or sets the display mode for the chart PointLabels. + /// + [DefaultValue(PointLabelDisplayMode.NotSet), Category("DataLabel")] + [Description("Indicates the display mode for the chart PointLabels.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public PointLabelDisplayMode PointLabelDisplayMode + { + get { return (_PointLabelDisplayMode); } + + set + { + if (value != _PointLabelDisplayMode) + { + _PointLabelDisplayMode = value; + + InvalidatePointLabels(); + + OnPropertyChangedEx("PointLabelDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region PointLabelMinDistance + + /// + /// Gets or sets the minimum distance between label data points. + /// + [DefaultValue(0), Category("DataLabel")] + [Description("Indicates the minimum distance between label data points.")] + public int PointLabelMinDistance + { + get { return (_PointLabelMinDistance); } + + set + { + if (value != _PointLabelMinDistance) + { + if (value < 0) + throw new Exception("Minimum Distance must be >= 0"); + + _PointLabelMinDistance = value; + + InvalidatePointLabels(); + + OnPropertyChangedEx("PointLabelMinDistance", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region PointLabelSkip + + /// + /// Gets or sets the number of inter-label points to skip. + /// + [DefaultValue(0), Category("DataLabel")] + [Description("Indicates the number of inter-label points to skip.")] + public int PointLabelSkip + { + get { return (_PointLabelSkip); } + + set + { + if (value != _PointLabelSkip) + { + if (value < 0) + throw new Exception("Skip value must be >= 0"); + + _PointLabelSkip = value; + + InvalidatePointLabels(); + + OnPropertyChangedEx("PointLabelSkip", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region ScaleTypeX + + /// + /// Gets or sets the X axis Scale Type. + /// + [DefaultValue(ScaleType.NotSet), Category("Axis")] + [Description("Indicates the X axis Scale Type.")] + public ScaleType ScaleTypeX + { + get { return (_ScaleTypeX); } + + set + { + if (value != _ScaleTypeX) + { + if (ValidScaleTypeX(value) == false) + throw new Exception("Incompatible ScaleTypeX for defined series data."); + + _ScaleTypeX = value; + + InvalidatePoints(); + + OnPropertyChangedEx("ScaleTypeX", VisualChangeType.Layout); + } + } + } + + #region ValidScaleTypeX + + private bool ValidScaleTypeX(ScaleType scaleType) + { + if (scaleType == ScaleType.NotSet || scaleType == ScaleType.Auto) + return (true); + + if (SeriesPoints.Count > 0) + { + for (int i = 0; i < SeriesPoints.Count; i++) + { + SeriesPoint sp = SeriesPoints[i]; + + if (sp.ValueX != null) + { + Type dataType = sp.ValueX.GetType(); + ScaleType autoType = SeriesPoint.GetScaleType(dataType); + + if (scaleType == autoType) + return (true); + + if (scaleType == ScaleType.Qualitative) + return (true); + + return (false); + } + } + } + + return (true); + } + + #endregion + + #endregion + + #region ScaleTypeY + + /// + /// Gets or sets the Y axis Scale Type. + /// + [DefaultValue(ScaleType.NotSet), Category("Axis")] + [Description("Indicates the Y axis Scale Type.")] + public ScaleType ScaleTypeY + { + get { return (_ScaleTypeY); } + + set + { + if (value != _ScaleTypeY) + { + if (ValidScaleTypeY(value) == false) + throw new Exception("Incompatible ScaleTypeY for defined series data."); + + _ScaleTypeY = value; + + InvalidatePoints(); + + OnPropertyChangedEx("ScaleTypeY", VisualChangeType.Layout); + } + } + } + + #region ValidScaleTypeY + + private bool ValidScaleTypeY(ScaleType scaleType) + { + if (scaleType == ScaleType.NotSet || scaleType == ScaleType.Auto) + return (true); + + if (SeriesPoints.Count > 0) + { + for (int i = 0; i < SeriesPoints.Count; i++) + { + SeriesPoint sp = SeriesPoints[i]; + + if (sp.ValueY != null && sp.ValueY.Length > 0) + { + Type dataType = sp.ValueY[0].GetType(); + ScaleType autoType = SeriesPoint.GetScaleType(dataType); + + if (scaleType == autoType) + return (true); + + if (scaleType == ScaleType.Qualitative) + return (true); + + return (false); + } + } + } + + return (true); + } + + #endregion + + #endregion + + #region SeriesPoints + + /// + /// Gets the series point data collection + /// + [Category("Data")] + [Description("Indicates the series point data collection.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SeriesPointCollection SeriesPoints + { + get + { + if (_SeriesPoints == null) + { + _SeriesPoints = new SeriesPointCollection(); + + _SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged; + } + + return (_SeriesPoints); + } + + set + { + if (value != _SeriesPoints) + { + if (_SeriesPoints != null) + _SeriesPoints.CollectionChanged -= SeriesPoints_CollectionChanged; + + _SeriesPoints = value; + + if (_SeriesPoints != null) + _SeriesPoints.CollectionChanged += SeriesPoints_CollectionChanged; + } + } + } + + #region SeriesPoints_CollectionChanged + + void SeriesPoints_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + SeriesRangeChanged = true; + + InvalidateLayout(); + } + + #endregion + + #endregion + + #region SeriesType + + /// + /// Gets or sets the Series Type. + /// + [DefaultValue(SeriesType.Point), Category("Appearance")] + [Description("Indicates the Series Type.")] + public override SeriesType SeriesType + { + get { return (base.SeriesType); } + + set + { + if (value != base.SeriesType) + { + base.SeriesType = value; + + IsRotated = ( + value == SeriesType.HorizontalDot || + value == SeriesType.HorizontalBar || + value == SeriesType.HorizontalHiLoBar); + } + } + } + + #endregion + + #region ShowHiLoBarMedianLines + + /// + /// Gets or sets whether defined HiLoBar Median lines are shown. + /// + [DefaultValue(false), Category("Empty")] + [Description("Indicates whether defined HiLoBar Median lines are shown.")] + public bool ShowHiLoBarMedianLines + { + get { return (TestState(States.ShowHiLoBarMedianLines)); } + + set + { + if (value != ShowHiLoBarMedianLines) + { + SetState(States.ShowHiLoBarMedianLines, value); + + OnPropertyChangedEx("ShowHiLoBarMedianLines", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowEmptyLines + + /// + /// Gets or sets whether EmptyLines are shown in the series. + /// + [DefaultValue(false), Category("Empty")] + [Description("Indicates whether EmptyLines are shown in the series.")] + public bool ShowEmptyLines + { + get { return (TestState(States.ShowEmptyLines)); } + + set + { + if (value != ShowEmptyLines) + { + SetState(States.ShowEmptyLines, value); + + InvalidatePoints(); + + OnPropertyChangedEx("ShowEmptyLines", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowEmptyPoints + + /// + /// Gets or sets whether EmptyPoints are shown in the series. + /// + [DefaultValue(false), Category("Empty")] + [Description("Indicates whether EmptyPoints are shown in the series.")] + public bool ShowEmptyPoints + { + get { return (TestState(States.ShowEmptyPoints)); } + + set + { + if (value != ShowEmptyPoints) + { + SetState(States.ShowEmptyPoints, value); + + InvalidatePoints(); + + OnPropertyChangedEx("ShowEmptyPoints", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowOriginValueLabels + + /// + /// Gets or sets whether labels are shown for 'Origin' data values. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether labels are shown for 'Origin' data values.")] + public bool ShowOriginValueLabels + { + get { return (TestState(States.ShowOriginValueLabels)); } + + set + { + if (value != ShowOriginValueLabels) + { + SetState(States.ShowOriginValueLabels, value); + + OnPropertyChangedEx("ShowOriginValueLabels", VisualChangeType.Layout); + } + } + } + + #endregion + + #region StackQualitativePoints + + /// + /// Gets or sets whether Qualitative points are + /// stacked or spread across the associated grouped column. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Qualitative points are stacked or spread across the associated grouped column.")] + public bool StackQualitativePoints + { + get { return (TestState(States.StackQualitativePoints)); } + + set + { + if (value != StackQualitativePoints) + { + SetState(States.StackQualitativePoints, value); + + OnPropertyChangedEx("StackQualitativePoints", VisualChangeType.Layout); + } + } + } + + #endregion + + #region StepLines + + /// + /// Gets or sets which 'Step lines' are displayed. + /// + [DefaultValue(StepLines.NotSet), Category("Display")] + [Description("Indicates which 'Step lines' are displayed.")] + public StepLines StepLines + { + get { return (_StepLines); } + + set + { + if (value != _StepLines) + { + _StepLines = value; + + OnPropertyChangedEx("StepLines", VisualChangeType.Render); + } + } + } + + #endregion + + #region StepLineMode + + /// + /// Gets or sets the mode used to render "Step Lines" in + /// the defined Line series. + /// + [DefaultValue(StepLineMode.NotSet), Category("Display")] + [Description("Indicates the mode used to render 'Step Lines' in the defined Line series.")] + public StepLineMode StepLineMode + { + get { return (_StepLineMode); } + + set + { + if (value != _StepLineMode) + { + _StepLineMode = value; + + OnPropertyChangedEx("StepLineMode", VisualChangeType.Render); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region BarOffset + + internal int BarOffset + { + get { return (_BarOffset); } + set { _BarOffset = value; } + } + + #endregion + + #region BarShadingColors + + internal Color[] BarShadingColors + { + get + { + if (_BarShadingColors == null) + { + // Top, Bottom, Left, Right + + _BarShadingColors = new Color[] { + Color.FromArgb(200, Color.White), + Color.FromArgb(100, Color.Black), + Color.FromArgb(100, Color.Black), + Color.FromArgb(100, Color.Black)}; + } + + return (_BarShadingColors); + } + } + + #endregion + + #region BarWidth + + internal int BarWidth + { + get { return (_BarWidth); } + set { _BarWidth = value; } + } + + #endregion + + #region IsQualitativeXValues + + internal bool IsQualitativeXValues + { + get + { + UpdateSeriesRange(); + + return (QualitativeXValues.Count > 0); + } + } + + #endregion + + #region IsQualitativeYValues + + internal bool IsQualitativeYValues + { + get + { + UpdateSeriesRange(); + + return (QualitativeYValues.Count > 0); + } + } + + #endregion + + #region IsBarSeries + + internal bool IsBarSeries + { + get + { + return (SeriesType == SeriesType.HorizontalBar || + SeriesType == SeriesType.VerticalBar || + SeriesType == SeriesType.HorizontalHiLoBar || + SeriesType == SeriesType.VerticalHiLoBar); + } + } + + #endregion + + #region IsRotated + + internal bool IsRotated + { + get { return (TestState(States.IsRotated)); } + set { SetState(States.IsRotated, value); } + } + + #endregion + + #region IsSorted + + internal bool IsSorted + { + get { return (TestState(States.IsSorted)); } + set { SetState(States.IsSorted, value); } + } + + #endregion + + #region PlotData + + internal object PlotData + { + get { return (_PlotData); } + set { _PlotData = value; } + } + + #endregion + + #region PointMarkerEmptyImage + + internal Image PointMarkerEmptyImage + { + get { return (_PointMarkerEmptyImage); } + set { _PointMarkerEmptyImage = value; } + } + + #endregion + + #region PointMarkerImage + + internal Image PointMarkerImage + { + get { return (_PointMarkerImage); } + set { _PointMarkerImage = value; } + } + + #endregion + + #region PointMarkerHighlightImage + + internal Image PointMarkerHighlightImage + { + get { return (_PointMarkerHighlightImage); } + set { _PointMarkerHighlightImage = value; } + } + + #endregion + + #region PointOffset + + internal Point PointOffset + { + get { return (_PointOffset); } + set { _PointOffset = value; } + } + + #endregion + + #region QualitativeXValues + + internal List QualitativeXValues + { + get + { + if (_QualitativeXValues == null) + _QualitativeXValues = new List(); + + return (_QualitativeXValues); + } + + set { _QualitativeXValues = value; } + } + + #endregion + + #region QualitativeYValues + + internal List QualitativeYValues + { + get + { + if (_QualitativeYValues == null) + _QualitativeYValues = new List(); + + return (_QualitativeYValues); + } + + set { _QualitativeYValues = value; } + } + + #endregion + + #region SeriesRangeChanged + + public override bool SeriesRangeChanged + { + get { return (base.SeriesRangeChanged); } + + set + { + if (value != base.SeriesRangeChanged) + { + base.SeriesRangeChanged = value; + + if (value == true) + _SortedSeriesPoints = null; + } + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + UpdateDataBindings(); + + UpdateMarkerImage(layoutInfo.Graphics); + } + + #region UpdateMarkerImage + + private void UpdateMarkerImage(Graphics g) + { + switch (SeriesType) + { + case SeriesType.Bubble: + case SeriesType.VerticalDot: + case SeriesType.Line: + case SeriesType.Point: + case SeriesType.HorizontalDot: + if (PointMarkerImage == null) + { + ChartXy chartXy = Parent as ChartXy; + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + PointMarkerImage = chartXy.GetPointMarker(g, sstyle.MarkerVisualStyle); + } + break; + } + } + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + BoundsRelative = layoutInfo.LayoutBounds; + + if (SeriesType == SeriesType.Bubble) + UpdateBubblePointOffset(); + } + + #region UpdateBubblePointOffset + + private void UpdateBubblePointOffset() + { + BubblePlotData bdata = _PlotData as BubblePlotData; + + if (bdata != null) + { + ChartXy chartXy = Parent as ChartXy; + + Rectangle bounds = chartXy.ContentBoundsEx; + + float minSize = Dpi.Width(BubbleMinSize); + float maxSize = (float)(Math.Min(bounds.Width, bounds.Height) * BubbleMaxPercentage); + + double minTotalSize; + double maxTotalSize; + chartXy.GetChartBubbleData(out minTotalSize, out maxTotalSize); + + BubbleSizeMode smode = GetBubbleSizeMode(chartXy); + + double range = maxSize - minSize; + + double sizeRange = (smode == BubbleSizeMode.Diameter) + ? maxTotalSize - minTotalSize : MathHelper.ToScalar((float)(maxTotalSize - minTotalSize)); + + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + int size = GetBubbleSize(sp, smode, minSize, maxSize, range, sizeRange); + + sp.PointSize = new Size(size, size); + } + } + } + } + + #region GetBubbleSize + + private int GetBubbleSize(SeriesPoint sp, + BubbleSizeMode smode, double minSize, double maxSize, double range, double sizeRange) + { + if (sp.ValueY == null || sp.ValueY.Length < 2 || sizeRange == 0) + return (int)minSize; + + double size = Math.Abs(GetDoubleValue(sp.ValueY[1])); + + double value = (smode == BubbleSizeMode.Diameter) + ? (size * range) / sizeRange + : (MathHelper.ToScalar((float)size) * range) / sizeRange; + + if (BubbleScaleFactor > 0) + value *= BubbleScaleFactor; + + value = Math.Max(minSize, value); + + return ((int)Math.Min(maxSize, value)); + } + + #endregion + + #endregion + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + if (SeriesPoints.Count > 0) + { + Graphics g = renderInfo.Graphics; + + if (SeriesPoints.Count > 0) + { + ChartXy chartXy = Parent as ChartXy; + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + ssp.SeriesLayoutCount = chartXy.SeriesLayoutCount; + + UpdateMarkerImage(g); + + int n = Dpi.Width1; + + Point pt = chartXy.GetGlobalAdjustedPoint(chartXy.ContentBounds.Location); + RenderBounds = new Rectangle(pt, chartXy.ContentBounds.Size); + + if (RenderBounds.Width > 0 && RenderBounds.Height > 0) + { + switch (SeriesType) + { + case SeriesType.Bubble: + RenderBubblePlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.HorizontalBar: + RenderHBarPlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.HorizontalDot: + RenderHDotPlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.HorizontalHiLoBar: + RenderHStockPlot(renderInfo, chartXy, ssp, sstyle); + break; + + case SeriesType.Point: + RenderPointPlot(g, chartXy, ssp, true, sstyle); + break; + + case SeriesType.Line: + RenderLinePlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.VerticalBar: + RenderVBarPlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.VerticalDot: + RenderVDotPlot(g, chartXy, ssp, sstyle); + break; + + case SeriesType.VerticalHiLoBar: + RenderVStockPlot(renderInfo, chartXy, ssp, sstyle); + break; + } + } + } + } + } + + #region GetSortedSeriesPoints + + internal SortedSeriesPoints GetSortedSeriesPoints(ChartXy chartXy) + { + if (_SortedSeriesPoints == null) + { + bool sort = (IsSorted == false && NeedSortedSeries(chartXy) == true); + + _SortedSeriesPoints = new SortedSeriesPoints(this, sort); + + if (SeriesType == SeriesType.VerticalDot || SeriesType == SeriesType.HorizontalDot) + CombineDuplicates(_SortedSeriesPoints); + } + + return (_SortedSeriesPoints); + } + + #region CombineDuplicates + + private void CombineDuplicates(SortedSeriesPoints ssp) + { + SeriesPoint spLast = null; + + List cList = new List(); + List iList = new List(); + + int dcount = 0; + int spLastIndex = 0; + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (spLast != null && spLast.ValueX.Equals(sp.ValueX) == false) + { + iList.Add(spLastIndex); + cList.Add(dcount); + + dcount = 0; + + spLast = sp; + spLastIndex = (ssp.IndexArray != null ? ssp.IndexArray[i] : i); + } + + dcount += GetDotCount(sp); + + if (spLast == null) + { + spLast = sp; + spLastIndex = (ssp.IndexArray != null ? ssp.IndexArray[i] : i); + } + } + + if (dcount > 0) + { + iList.Add(spLastIndex); + cList.Add(dcount); + } + + int[] indexArray = new int[iList.Count]; + int[] countArray = new int[iList.Count]; + + for (int i = 0; i < iList.Count; i++) + { + indexArray[i] = iList[i]; + countArray[i] = cList[i]; + } + + ssp.IndexArray = indexArray; + ssp.CountArray = countArray; + } + + #endregion + + #region NeedSortedSeries + + private bool NeedSortedSeries(ChartXy chartXy) + { + if (IsSorted == true || _ActualScaleTypeX == ScaleType.Qualitative) + return (false); + + if (SeriesType != SeriesType.Line) + return (true); + + ChartLineDisplayMode mode = GetLineDisplayMode(chartXy); + + return ((mode & ChartLineDisplayMode.DisplayUnsorted) != ChartLineDisplayMode.DisplayUnsorted); + } + + #endregion + + #endregion + + #region RenderBarPlot + + #region RenderHBarPlot + + private void RenderHBarPlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + g.RenderingOrigin = chartXy.GetLocalAdjustedPoint(Point.Empty); + + BarRenderData rd = new BarRenderData(chartXy, AxisX ?? chartXy.AxisX); + + rd.FillRange = GetBarFillRange(chartXy); + rd.BarShading = GetBarShading(chartXy); + + rd.SeriesStyle = sstyle; + + int index = 0; + bool isHistogram = false; + + if (chartXy.BarShowAsHistogram == Tbool.True) + { + ChartAxis axisY = AxisY ?? chartXy.AxisY; + AxisBar axisBar = axisY.AxisBars[(int)AxisBarType.Bar]; + + if (axisBar.BarCount == 1) + { + TickmarkLayout layout = axisY.TickmarkLayout; + + for (int i = 0; i < layout.Ticks.Length; i++) + { + if (layout.Ticks[i].LabelIndex >= 0) + { + index = i; + break; + } + } + + isHistogram = true; + } + } + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + rd.Spt = sp.Point[0]; + rd.Sp = sp; + + RenderHBar(g, rd, isHistogram, i + index); + } + } + } + + #region RenderHBar + + private void RenderHBar( + Graphics g, BarRenderData rd, bool isHistogram, int index) + { + ChartXy chartXy = rd.ChartXy; + SeriesPoint sp = rd.Sp; + + sp.PointSize = new Size(5, BarWidth); + + Point ptt = chartXy.GetDataPointEx(this, sp, 0); + + int y = (int)(ptt.Y + BarOffset - BarWidth / 2); + int height = BarWidth; + + if (isHistogram == true) + y = GetHistogramSizeY(chartXy, ptt, index, out height); + + int x1 = ptt.X; + int x2 = GetHBarStart(chartXy, sp); + int xOrigin = GetHBarOrigin(chartXy, rd.Axis, sp); + + if (x1 > x2) + { + int xtemp = x1; + x1 = x2; + x2 = xtemp; + } + + if (x2 <= xOrigin) + { + RenderLeftBar(g, rd, y, height, x1, x2, xOrigin); + } + else if (x1 >= xOrigin) + { + RenderRightBar(g, rd, y, height, x1, x2, xOrigin); + } + else + { + RenderLeftBar(g, rd, y, height, x1, xOrigin, xOrigin); + RenderRightBar(g, rd, y, height, xOrigin, x2, xOrigin); + } + } + + #region GetHistogramSizeY + + private int GetHistogramSizeY( + ChartXy chartXy, Point spt, int index, out int height) + { + ChartAxis axis = AxisY ?? chartXy.AxisY; + TickmarkLayout layout = axis.TickmarkLayout; + + if (index < layout.Ticks.Length) + height = layout.Ticks[index + 1].TickPoint.Y - spt.Y; + else + height = (int)layout.MajorInterval; + + int y = spt.Y - (int)(layout.MajorInterval / 2); + + return (y); + } + + #endregion + + #region GetHBarStart + + internal int GetHBarStart(ChartXy chartXy, SeriesPoint sp) + { + ChartAxis axis = AxisX ?? chartXy.AxisX; + + object value = ((sp.ValueY.Length > 1) + ? sp.ValueY[1] : chartXy.BarOrigin ?? null); + + if (value == null) + { + if (axis.ScaleType == ScaleType.Quantitative) + value = 0; + else + value = axis.ActualMinValue; + } + + return (chartXy.GetDataPointX(axis, value)); + } + + #endregion + + #region GetHBarOrigin + + private int GetHBarOrigin( + ChartXy chartXy, ChartAxis axis, SeriesPoint sp) + { + object value = ((sp.ValueY != null && sp.ValueY.Length > 2) + ? sp.ValueY[2] : (chartXy.BarOrigin ?? null)); + + if (value == null) + { + if (axis.ScaleType == ScaleType.Quantitative) + value = 0; + else + value = axis.ActualMinValue; + } + + return (chartXy.GetDataPointX(axis, value)); + } + + #endregion + + #region RenderRightBar + + private void RenderRightBar(Graphics g, + BarRenderData rd, int y, int height, int x1, int x2, int xOrigin) + { + Rectangle r = new Rectangle(x1, y, x2 - x1, Math.Max(1, height - 1)); + + if (r.IntersectsWith(RenderBounds)) + { + Background bk = rd.SeriesStyle.BarVisualStyle.Background; + ChartLineVisualStyle lstyle = rd.SeriesStyle.BarVisualStyle.Border; + + // r is actual area, r2 is FillRange area + + Rectangle r2 = r; + + if (rd.FillRange == BarFillRange.BySeries) + { + r2.X = xOrigin; + r2.Width = rd.ChartXy.GetDataPointX(rd.Axis, MaxValueX) - r2.X; + } + + BarSegment segment = (x1 > xOrigin) ? BarSegment.Right : BarSegment.RightPartial; + + RenderFullHBar(g, rd, r, r2, bk, lstyle, segment); + } + } + + #endregion + + #region RenderLeftBar + + private void RenderLeftBar(Graphics g, + BarRenderData rd, int y, int height, int x1, int x2, int xOrigin) + { + Rectangle r = new Rectangle(x1, y, x2 - x1, Math.Max(1, height - 1)); + + if (r.IntersectsWith(RenderBounds)) + { + ChartSeriesVisualStyle sstyle = rd.SeriesStyle; + + Background bk = sstyle.BarVisualStyle.AlternateBackground; + + if (bk.IsEmpty) + bk = sstyle.BarVisualStyle.Background; + + ChartLineVisualStyle lstyle = sstyle.BarVisualStyle.AlternateBorder; + + if (lstyle.IsEmpty) + lstyle = sstyle.BarVisualStyle.Border; + + Rectangle r2 = r; + + if (rd.FillRange == BarFillRange.BySeries) + { + int left = rd.ChartXy.GetDataPointX(rd.Axis, MinValueX); + + r2.X = left; + r2.Width = xOrigin - left; + } + + BarSegment segment = (x2 < xOrigin) ? BarSegment.Left : BarSegment.LeftPartial; + + RenderFullHBar(g, rd, r, r2, bk, lstyle, segment); + } + } + + #endregion + + #region RenderFullHBar + + private void RenderFullHBar(Graphics g, BarRenderData rd, + Rectangle r, Rectangle r2, Background bk, ChartLineVisualStyle lstyle, BarSegment segment) + { + if (r2.Width > 0 && r2.Height > 0) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment) == false) + { + using (Brush br = bk.GetBrush(r2)) + g.FillRectangle(br, r); + + int lw = 0; + + if (lstyle.LinePattern != LinePattern.None) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + lw = (int)pen.Width; + + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + g.DrawRectangle(pen, r); + } + + g.SmoothingMode = sm; + } + + if (rd.BarShading == true) + { + Rectangle t = r; + t.Inflate(-lw / 2, -lw / 2); + + t.Width++; + t.Height++; + + RenderHBarShading(g, t, r2, segment); + } + + chartControl.DoPostRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment); + } + } + } + + #region RenderHBarShading + + private void RenderHBarShading( + Graphics g, Rectangle r, Rectangle r2, BarSegment segment) + { + if (r.Width > 6) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + int n = (int)(r.Height * .15); + + Color[] colors = (Color[])BarShadingColors.Clone(); + + colors[2] = Color.FromArgb(Math.Max(0, colors[2].A - 30), colors[2]); + colors[3] = Color.FromArgb(Math.Max(0, colors[3].A - 30), colors[3]); + + Rectangle r3 = r; + + r3.Inflate(1, 1); + + using (LinearGradientBrush lbr = new LinearGradientBrush(r3, Color.Empty, Color.Empty, 90f)) + { + lbr.WrapMode = WrapMode.Tile; + + ColorBlend cb = new ColorBlend(4); + + cb.Colors = new Color[] { colors[0], Color.Transparent, Color.Transparent, colors[1] }; + cb.Positions = new float[] { 0f, .25f, .75f, 1f }; + + lbr.InterpolationColors = cb; + + r3.Inflate(-1, -1); + + g.FillRectangle(lbr, r3); + } + + switch (segment) + { + case BarSegment.LeftPartial: + FillLeft(g, r, n, colors); + break; + + case BarSegment.RightPartial: + FillRight(g, r, n, colors); + break; + + default: + FillLeft(g, r, n, colors); + FillRight(g, r, n, colors); + break; + } + + g.SmoothingMode = sm; + } + } + + #region FillLeft + + private void FillLeft(Graphics g, Rectangle r, int n, Color[] colors) + { + r.Width = n - 1; + r.Inflate(1, 0); + + using (LinearGradientBrush lbr = new LinearGradientBrush(r, colors[2], Color.Transparent, 0f)) + { + lbr.WrapMode = WrapMode.TileFlipX; + + r.X++; + + g.FillRectangle(lbr, r); + } + } + + #endregion + + #region FillRight + + private void FillRight(Graphics g, Rectangle r, int n, Color[] colors) + { + r.X = r.Right - n; + r.Width = n; + r.Inflate(1, 0); + + using (LinearGradientBrush lbr = new LinearGradientBrush(r, colors[2], Color.Transparent, 180f)) + { + r.X++; + r.Width--; + + g.FillRectangle(lbr, r); + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region RenderVBarPlot + + private void RenderVBarPlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + PointData pd = GatherSeriesPoints(chartXy, ssp, 0, ssp.Count, false); + + if (pd.Points.Count > 0) + { + g.RenderingOrigin = chartXy.GetLocalAdjustedPoint(Point.Empty); + + BarRenderData rd = new BarRenderData(chartXy, AxisY ?? chartXy.AxisY); + + rd.FillRange = GetBarFillRange(chartXy); + rd.BarShading = GetBarShading(chartXy); + + rd.SeriesStyle = sstyle; + + int index = 0; + bool isHistogram = false; + + if (chartXy.BarShowAsHistogram == Tbool.True) + { + ChartAxis axisX = AxisX ?? chartXy.AxisX; + AxisBar axisBar = axisX.AxisBars[(int)AxisBarType.Bar]; + + if (axisBar.BarCount == 1) + { + TickmarkLayout layout = axisX.TickmarkLayout; + + for (int i = 0; i < layout.Ticks.Length; i++) + { + if (layout.Ticks[i].LabelIndex >= 0) + { + index = i; + break; + } + } + + isHistogram = true; + } + } + + for (int i = 0; i < pd.Points.Count; i++) + { + Point[] pts = pd.Points[i]; + SeriesPoint[] spts = pd.SeriesPoints[i]; + + for (int j = 0; j < pts.Length; j++) + { + rd.Spt = pts[j]; + rd.Sp = spts[j]; + + RenderVBar(g, rd, isHistogram, j + index); + } + } + } + } + + #region RenderVBar + + private void RenderVBar( + Graphics g, BarRenderData rd, bool isHistogram, int index) + { + ChartXy chartXy = rd.ChartXy; + SeriesPoint sp = rd.Sp; + Point spt = rd.Spt; + + sp.PointSize = new Size(BarWidth, 5); + + int x = (int)(spt.X + BarOffset - BarWidth / 2); + int width = BarWidth; + + if (isHistogram == true) + x = GetHistogramSizeX(chartXy, spt, index, out width); + + int y1 = spt.Y; + int y2 = GetVBarStart(chartXy, sp); + int yOrigin = GetVBarOrigin(chartXy, rd.Axis, sp); + + if (y1 > y2) + { + int ytemp = y1; + y1 = y2; + y2 = ytemp; + } + + if (y2 <= yOrigin) + { + RenderAscendingBar(g, rd, x, width, y1, y2, yOrigin); + } + else if (y1 >= yOrigin) + { + RenderDescendingBar(g, rd, x, width, y1, y2, yOrigin); + } + else + { + RenderAscendingBar(g, rd, x, width, y1, yOrigin, yOrigin); + RenderDescendingBar(g, rd, x, width, yOrigin, y2, yOrigin); + } + } + + #region GetHistogramSizeX + + private int GetHistogramSizeX( + ChartXy chartXy, Point spt, int index, out int width) + { + ChartAxis axis = AxisX ?? chartXy.AxisX; + TickmarkLayout layout = axis.TickmarkLayout; + + if (index < layout.Ticks.Length) + width = layout.Ticks[index + 1].TickPoint.X - spt.X; + else + width = (int)layout.MajorInterval; + + int x = spt.X - (int)(layout.MajorInterval / 2); + + return (x); + } + + #endregion + + #region GetVBarStart + + internal int GetVBarStart(ChartXy chartXy, SeriesPoint sp) + { + ChartAxis axis = AxisY ?? chartXy.AxisY; + + object value = ((sp.ValueY != null && sp.ValueY.Length > 1) + ? sp.ValueY[1] : (chartXy.BarOrigin ?? null)); + + if (value == null) + { + if (axis.ScaleType == ScaleType.Quantitative) + value = 0; + else + value = axis.ActualMinValue; + } + + return (chartXy.GetDataPointY(axis, value)); + } + + #endregion + + #region GetVBarOrigin + + private int GetVBarOrigin( + ChartXy chartXy, ChartAxis axis, SeriesPoint sp) + { + object value = ((sp.ValueY != null && sp.ValueY.Length > 2) + ? sp.ValueY[2] : (chartXy.BarOrigin ?? null)); + + if (value == null) + { + if (axis.ScaleType == ScaleType.Quantitative) + value = 0; + else + value = axis.ActualMinValue; + } + + return (chartXy.GetDataPointY(axis, value)); + } + + #endregion + + #region RenderAscendingBar + + private void RenderAscendingBar(Graphics g, + BarRenderData rd, int x, int width, int y1, int y2, int yOrigin) + { + Rectangle r = new Rectangle(x, y1, Math.Max(1, width - 1), y2 - y1); + + if (r.IntersectsWith(RenderBounds)) + { + Background bk = rd.SeriesStyle.BarVisualStyle.Background; + ChartLineVisualStyle lstyle = rd.SeriesStyle.BarVisualStyle.Border; + + Rectangle r2 = r; + + if (rd.FillRange == BarFillRange.BySeries) + { + int top = rd.ChartXy.GetDataPointY(rd.Axis, MaxValueY); + + r2.Y = top; + r2.Height = yOrigin - top; + } + + BarSegment segment = (y2 < yOrigin) ? BarSegment.Top : BarSegment.TopPartial; + + RenderFullVBar(g, rd, r, r2, bk, lstyle, segment); + } + } + + #endregion + + #region RenderDescendingBar + + private void RenderDescendingBar(Graphics g, + BarRenderData rd, int x, int width, int y1, int y2, int yOrigin) + { + Rectangle r = new Rectangle(x, y1, Math.Max(1, width - 1), y2 - y1); + + if (r.IntersectsWith(RenderBounds)) + { + ChartSeriesVisualStyle sstyle = rd.SeriesStyle; + + Background bk = sstyle.BarVisualStyle.AlternateBackground; + + if (bk.IsEmpty) + bk = sstyle.BarVisualStyle.Background; + + ChartLineVisualStyle lstyle = sstyle.BarVisualStyle.AlternateBorder; + + if (lstyle.IsEmpty) + lstyle = sstyle.BarVisualStyle.Border; + + Rectangle r2 = r; + + if (GetBarFillRange(rd.ChartXy) == BarFillRange.BySeries) + { + r2.Y = yOrigin; + r2.Height = rd.ChartXy.GetDataPointY(rd.Axis, MinValueY) - r2.Y; + } + + BarSegment segment = (y1 > yOrigin) ? BarSegment.Bottom : BarSegment.BottomPartial; + + RenderFullVBar(g, rd, r, r2, bk, lstyle, segment); + } + } + + #endregion + + #region RenderFullVBar + + private void RenderFullVBar(Graphics g, BarRenderData rd, + Rectangle r, Rectangle r2, Background bk, ChartLineVisualStyle lstyle, BarSegment segment) + { + if (r2.Width > 0 && r2.Height > 0) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment) == false) + { + using (Brush br = bk.GetBrush(r2)) + g.FillRectangle(br, r); + + int lw = 0; + + if (lstyle.LinePattern != LinePattern.None) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + lw = (int)pen.Width; + + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + g.DrawRectangle(pen, r); + } + + g.SmoothingMode = sm; + } + + if (rd.BarShading == true) + { + Rectangle t = r; + t.Inflate(-lw / 2, -lw / 2); + + t.Width++; + t.Height++; + + RenderVBarShading(g, t, r2, segment); + } + + chartControl.DoPostRenderSeriesBarEvent(g, chartXy, this, rd.Sp, r, r2, segment); + } + } + } + + #region RenderVBarShading + + private void RenderVBarShading( + Graphics g, Rectangle r, Rectangle r2, BarSegment segment) + { + int n = r.Width / 10 + 1; + + if (r.Width > 6 && r.Height > n) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + Color[] colors = (Color[])BarShadingColors.Clone(); + + Rectangle r3 = r; + + using (LinearGradientBrush lbr = new LinearGradientBrush(r3, Color.Empty, Color.Empty, 0f)) + { + lbr.WrapMode = WrapMode.TileFlipX; + + ColorBlend cb = new ColorBlend(4); + + cb.Colors = new Color[] { colors[2], Color.Transparent, Color.Transparent, colors[3] }; + cb.Positions = new float[] { 0f, .15f, .85f, 1f }; + + lbr.InterpolationColors = cb; + + g.FillRectangle(lbr, r3); + } + + switch (segment) + { + case BarSegment.TopPartial: + FillTop(g, r, n, colors); + break; + + case BarSegment.BottomPartial: + FillBottom(g, r, n, colors); + break; + + default: + FillTop(g, r, n, colors); + FillBottom(g, r, n, colors); + break; + } + + g.SmoothingMode = sm; + } + } + + #region FillTop + + private void FillTop(Graphics g, Rectangle r, int n, Color[] colors) + { + using (Pen pen = new Pen(colors[0])) + { + Point pt1 = new Point(r.X + 1, r.Y); + Point pt2 = new Point(r.Right - 2, r.Y); + + for (int i = 0; i < n; i++) + { + g.DrawLine(pen, pt1, pt2); + + pt1.X++; + pt2.X--; + + pt1.Y++; + pt2.Y++; + } + } + } + + #endregion + + #region FillBottom + + private void FillBottom(Graphics g, Rectangle r, int n, Color[] colors) + { + using (Pen pen = new Pen(colors[1])) + { + Point pt1 = new Point(r.X + 1, r.Bottom - 1); + Point pt2 = new Point(r.Right - 2, r.Bottom - 1); + + for (int i = 0; i < n; i++) + { + g.DrawLine(pen, pt1, pt2); + + pt1.X++; + pt2.X--; + + pt1.Y--; + pt2.Y--; + } + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetBarFillRange + + private BarFillRange GetBarFillRange(ChartXy chartXy) + { + BarFillRange fillRange = BarFillRange; + + if (fillRange == BarFillRange.NotSet) + fillRange = chartXy.BarFillRange; + + return ((fillRange != BarFillRange.NotSet) + ? fillRange : BarFillRange.ByBar); + } + + #endregion + + #region GetBarLabelPosition + + internal BarLabelPosition GetBarLabelPosition(ChartXy chartXy) + { + BarLabelPosition labelPos = BarLabelPosition; + + if (labelPos == BarLabelPosition.NotSet) + labelPos = chartXy.BarLabelPosition; + + return ((labelPos != BarLabelPosition.NotSet) + ? labelPos : BarLabelPosition.Center); + } + + #endregion + + #region GetBarShading + + private bool GetBarShading(ChartXy chartXy) + { + Tbool barShading = BarShadingEnabled; + + if (barShading == Tbool.NotSet) + barShading = chartXy.BarShadingEnabled; + + return (barShading == Tbool.True); + } + + #endregion + + #endregion + + #region RenderBubblePlot + + private void RenderBubblePlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + BubblePlotData bdata = _PlotData as BubblePlotData; + + if (bdata != null) + { + double minIntensity = 32; + double maxIntensity = 255; + + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + PointMarkerVisualStyle hstyle = GetHighlightStyle(chartXy, sstyle); + + if (DisplayLinePointsOnTop == true) + RenderConvexHull(g, chartXy, ssp, sstyle, pstyle); + + BubbleIntensityMode imode = GetBubbleIntensityMode(chartXy); + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + int size = sp.PointSize.Width; + + Point pt = chartXy.GetDataPointNa(this, sp, 0); + Rectangle r = new Rectangle(pt.X - size / 2, pt.Y - size / 2, size, size); + + if (r.IntersectsWith(RenderBounds)) + { + Point ppt = chartXy.GetLocalAdjustedPoint(pt); + + bool isCrossPoint = chartXy.IsCrosshairSeriesPoint(this, ppt); + int intensity = GetIntensity(sp, imode, bdata, minIntensity, maxIntensity); + + PointMarkerVisualStyle style = (hstyle != null && isCrossPoint) ? hstyle : pstyle; + + Image image = style.GetPointMarkerImage(); + + if (image == null) + image = GetPointMarker(g, style, r.Size); + + if (image != null) + { + g.DrawImage(image, r); + } + else if (style.Type == PointMarkerType.Ellipse || style.Type == PointMarkerType.NotSet) + { + using (Brush br = style.Background.GetBrush(r, intensity)) + { + g.FillEllipse(br, r); + + if (style.BorderColor.IsEmpty == false && style.BorderWidth > 0) + { + using (Pen pen = new Pen(style.BorderColor, Dpi.Width(style.BorderWidth))) + g.DrawEllipse(pen, r); + } + } + } + } + } + } + + if (DisplayLinePointsOnTop == false) + RenderConvexHull(g, chartXy, ssp, sstyle, pstyle); + + if (hstyle != null) + hstyle.Dispose(); + } + } + + #region GetIntensity + + private int GetIntensity(SeriesPoint sp, + BubbleIntensityMode imode, BubblePlotData bdata, double minIntensity, double maxIntensity) + { + if (imode != BubbleIntensityMode.None && imode != BubbleIntensityMode.NotSet) + { + if (sp.ValueY.Length > 2) + { + double intensity = -1; + + if (sp.ValueY[2] is double) + intensity = (double)sp.ValueY[2]; + + else if (sp.ValueY[2] is int) + intensity = Convert.ToDouble(sp.ValueY[2]); + + if (imode == BubbleIntensityMode.Alpha) + return ((int)intensity); + + if (intensity >= 0) + { + double range = maxIntensity - minIntensity; + double intensityRange = bdata.MaxIntensity - bdata.MinIntensity; + + if (intensityRange <= 0) + return (-1); + + return (int)(((intensity - bdata.MinIntensity) * range) / intensityRange + minIntensity); + } + } + } + + return (-1); + } + + #endregion + + #region GetBubbleSizeMode + + private BubbleSizeMode GetBubbleSizeMode(ChartXy chartXy) + { + if (BubbleSizeMode != BubbleSizeMode.NotSet) + return (BubbleSizeMode); + + if (chartXy.BubbleSizeMode != BubbleSizeMode.NotSet) + return (chartXy.BubbleSizeMode); + + return (BubbleSizeMode.Area); + } + + #endregion + + #region GetBubbleIntensityMode + + private BubbleIntensityMode GetBubbleIntensityMode(ChartXy chartXy) + { + if (BubbleIntensityMode != BubbleIntensityMode.NotSet) + return (BubbleIntensityMode); + + if (chartXy.BubbleIntensityMode != BubbleIntensityMode.NotSet) + return (chartXy.BubbleIntensityMode); + + return (BubbleIntensityMode.None); + } + + #endregion + + #region GetPointMarker + + internal Image GetPointMarker(Graphics g, PointMarkerVisualStyle style, Size size) + { + if (style.Type == PointMarkerType.NotSet || + style.Type == PointMarkerType.None || style.Type == PointMarkerType.Ellipse) + { + return (null); + } + + if (_PointMarker == null) + _PointMarker = new PointMarker(); + + return (_PointMarker.GetMarkerBitmap(g, style.Type, style.PointCount, + size, style.Rotation, style.Background, style.BorderColor, style.BorderWidth)); + } + + #endregion + + #endregion + + #region RenderDotPlot + + #region RenderHDotPlot + + private void RenderHDotPlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + Image marker = PointMarkerImage; + + if (marker != null) + { + Size maxSize = chartXy.GetMaxDotPlotMarkerSize(); + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + object pointValueX = chartXy.GetDataPointValueX(this, sp); + + Point pt = chartXy.GetPointFromValue(this, 0, pointValueX); + + Point ppt = new Point(pt.X + maxSize.Width / 2, pt.Y); + + int dcount = ssp.CountArray[i]; + + for (int j = 0; j < dcount; j++) + { + RenderPointMarker(g, chartXy, sp, ppt, maxSize, marker); + + ppt.X += maxSize.Width; + } + } + } + } + } + + #endregion + + #region RenderVDotPlot + + private void RenderVDotPlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + Image marker = PointMarkerImage; + + if (marker != null) + { + Size maxSize = chartXy.GetMaxDotPlotMarkerSize(); + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + Point pt = chartXy.GetDataPointNa(this, sp, -1); + Point ppt = new Point(pt.X, pt.Y - maxSize.Height / 2); + + int dcount = ssp.CountArray[i]; + + for (int j = 0; j < dcount; j++) + { + RenderPointMarker(g, chartXy, sp, ppt, maxSize, marker); + + ppt.Y -= maxSize.Height; + } + } + } + } + } + + #endregion + + #region GetDotCount + + private int GetDotCount(SeriesPoint sp) + { + if (sp.ValueY != null && sp.ValueY.Length > 0) + { + int count = 0; + + foreach (object o in sp.ValueY) + { + if (o is int) + count += (int)o; + + else if (o is double) + count += (int)Convert.ChangeType(o, typeof(int)); + } + + return (count); + } + + return (1); + } + + #endregion + + #endregion + + #region RenderPointPlot + + private void RenderPointPlot(Graphics g, ChartXy chartXy, + SortedSeriesPoints ssp, bool showHull, ChartSeriesVisualStyle sstyle) + { + PointData pd = GatherSeriesPoints(chartXy, ssp, 0, ssp.Count, true); + + if (pd.Points.Count > 0) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + PointMarkerVisualStyle hstyle = GetHighlightStyle(chartXy, sstyle); + + if (showHull == true) + RenderConvexHull(g, chartXy, ssp, sstyle, pstyle); + + if (hstyle == null) + { + Image marker = chartXy.GetPointMarker(g, pstyle); + + if (marker != null) + { + for (int i = 0; i < pd.Points.Count; i++) + { + Point[] pts = pd.Points[i]; + SeriesPoint[] spts = pd.SeriesPoints[i]; + + for (int j = 0; j < pts.Length; j++) + RenderPointMarker(g, chartXy, spts[j], pts[j], Size.Empty, marker); + } + } + } + else + { + bool highlightSinglePoint = HighLightSinglePoint(chartXy); + + Image highlightMarker = GetHighlightImage(g, chartXy, hstyle); + + for (int i = 0; i < pd.Points.Count; i++) + { + Point[] pts = pd.Points[i]; + SeriesPoint[] spts = pd.SeriesPoints[i]; + + for (int j = 0; j < pts.Length; j++) + { + Point ppt = pts[j]; + Point ppt2 = chartXy.GetLocalAdjustedPoint(ppt); + + Image marker = PointMarkerImage; + + if (highlightMarker != null) + { + if (chartXy.IsCrosshairSeriesPoint(this, ppt2) == true) + { + marker = highlightMarker; + + if (highlightSinglePoint == true) + highlightMarker = null; + } + } + + RenderPointMarker(g, chartXy, spts[j], ppt, Size.Empty, marker); + } + } + } + + if (ShowEmptyPoints == true) + RenderEmptyPoints(g, chartXy, pd, sstyle); + } + } + + #region RenderPointMarker + + private void RenderPointMarker(Graphics g, + ChartXy chartXy, SeriesPoint sp, Point pt, Size maxSize, Image marker) + { + if (marker != null) + { + ChartControl control = ChartControl; + + Image ptMarker = marker; + + Size markerSize = marker.Size; + Size size = maxSize.IsEmpty ? markerSize : maxSize; + + sp.PointSize = size; + + Point ptc = new Point( + pt.X - markerSize.Width / 2, + pt.Y - markerSize.Height / 2); + + Rectangle r = new Rectangle(ptc, markerSize); + + if (r.IntersectsWith(RenderBounds)) + { + if (control.DoPreRenderSeriesPointEvent(g, + chartXy, this, sp, pt, size, ref ptMarker) == false) + { + if (ptMarker != null) + { + g.DrawImageUnscaled(ptMarker, ptc); + + control.DoPostRenderSeriesPointEvent(g, + chartXy, this, sp, pt, ptMarker.Size, ptMarker); + } + } + } + } + } + + #endregion + + #region RenderConvexHull + + private void RenderConvexHull(Graphics g, ChartXy chartXy, + SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle, PointMarkerVisualStyle pstyle) + { + ConvexHullDisplayMode mode = GetConvexHullDisplayMode(chartXy); + + if (mode != ConvexHullDisplayMode.None) + { + if (_ConvexHullPoints == null) + { + PointData pd = GatherSeriesPointsEx(chartXy, ssp, 0, ssp.Count, true); + + _ConvexHullPoints = ConvexHull.GetConvexHull( + (pd.Points.Count == 1) ? pd.Points[0] : CombineListPoints(pd.Points)); + } + + if (_ConvexHullPoints.Length > 3) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddPolygon(_ConvexHullPoints); + + if ((mode & ConvexHullDisplayMode.DisplayBackground) == ConvexHullDisplayMode.DisplayBackground) + { + Rectangle r = Rectangle.Round(path.GetBounds()); + + Background bg = (sstyle.ConvexHullBackground.IsEmpty) + ? pstyle.Background : sstyle.ConvexHullBackground; + + using (Brush br = bg.GetBrush(r)) + g.FillPath(br, path); + } + + if ((mode & ConvexHullDisplayMode.DisplayBorder) == ConvexHullDisplayMode.DisplayBorder) + { + Color color; + int width; + LinePattern pattern; + + if (sstyle.ConvexHullLineStyle.IsEmpty == false) + { + color = sstyle.ConvexHullLineStyle.LineColor; + width = sstyle.ConvexHullLineStyle.LineWidth; + pattern = sstyle.ConvexHullLineStyle.LinePattern; + } + else + { + color = pstyle.BorderColor; + width = pstyle.BorderWidth; + pattern = LinePattern.Solid; + } + + if (pattern != LinePattern.None) + { + using (Pen pen = new Pen(color, Dpi.Width(width))) + { + if (pattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)pattern; + + g.DrawPath(pen, path); + } + } + } + } + } + } + } + + #region GetConvexHullDisplayMode + + private ConvexHullDisplayMode GetConvexHullDisplayMode(ChartXy chartXy) + { + if (ConvexHullDisplayMode != ConvexHullDisplayMode.NotSet) + return (ConvexHullDisplayMode); + + ConvexHullDisplayMode mode = chartXy.ConvexHullDisplayMode; + + if (mode != ConvexHullDisplayMode.NotSet) + return (mode); + + return (ConvexHullDisplayMode.None); + } + + #endregion + + #region CombineListPoints + + private Point[] CombineListPoints(List plist) + { + int n = 0; + + foreach (Point[] points in plist) + n += points.Length; + + Point[] fpoints = new Point[n]; + + n = 0; + + foreach (Point[] points in plist) + { + for (int i = 0; i < points.Length; i++) + fpoints[n++] = points[i]; + } + + return (fpoints); + } + + #endregion + + #endregion + + #region RenderEmptyPoints + + private void RenderEmptyPoints(Graphics g, + ChartXy chartXy, PointData pd, ChartSeriesVisualStyle sstyle) + { + PointData epd = _EmptyPointData; + + if (epd != null && epd.Points.Count > 0) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerEmptyVisualStyle; + + Image marker = GetEmptyMarkerImage(g, chartXy, pstyle); + + if (marker != null) + { + for (int i = 0; i < epd.Points.Count; i++) + { + Point[] epts = epd.Points[i]; + SeriesPoint[] septs = epd.SeriesPoints[i]; + + Point[] pts = GetEmptyPointRange(epts[0]); + + int run = pts[0].X - pts[1].X; + int rise = pts[0].Y - pts[1].Y; + + double slope = (run != 0) ? (double)rise / run : 0; + double b = pts[0].Y - (slope * pts[0].X); + + for (int j = 0; j < epts.Length; j++) + { + Point ept = epts[j]; + SeriesPoint sept = septs[j]; + + Point ppt = new Point(ept.X, (int)(slope * ept.X + b)); + + RenderPointMarker(g, chartXy, sept, ppt, Size.Empty, marker); + } + } + } + } + } + + #region GetEmptyPointRange + + private Point[] GetEmptyPointRange(Point pt) + { + Point[] pts = new Point[2]; + + pts[0] = Point.Empty; + pts[1] = Point.Empty; + + PointData pd = _PointData; + + for (int i = 0; i < pd.Points.Count; i++) + { + Point[] lps = pd.Points[i]; + + if (pt.X <= lps[0].X) + { + pts[1] = lps[0]; + + if (i == 0) + pts[0] = pts[1]; + + return (pts); + } + + pts[0] = lps[lps.Length - 1]; + } + + pts[1] = pts[0]; + + return (pts); + } + + #endregion + + #endregion + + #endregion + + #region RenderLinePlot + + private void RenderLinePlot(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + PointData pd = GatherSeriesPoints(chartXy, ssp, 0, ssp.Count, false); + + if (pd.Points.Count > 0) + { + ChartLineDisplayMode lineMode = GetLineDisplayMode(chartXy); + ChartLineAreaDisplayMode areaMode = GetAreaDisplayMode(chartXy); + + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + RenderConvexHull(g, chartXy, ssp, sstyle, pstyle); + + if (DisplayLinePointsOnTop == true) + RenderLinePlotLines(g, chartXy, pd, lineMode, areaMode, sstyle); + + if ((lineMode & ChartLineDisplayMode.DisplayPoints) == ChartLineDisplayMode.DisplayPoints) + { + RenderPointPlot(g, chartXy, ssp, false, sstyle); + } + else + { + if (ShowEmptyPoints == true) + RenderEmptyPoints(g, chartXy, pd, sstyle); + + RenderPointLabelPoints(g, chartXy, sstyle); + + if (HighLightPoints(chartXy) == true) + RenderHighlightPoints(g, chartXy, pd, sstyle); + } + + if (DisplayLinePointsOnTop == false) + RenderLinePlotLines(g, chartXy, pd, lineMode, areaMode, sstyle); + } + } + + #region RenderPointLabelPoints + + private void RenderPointLabelPoints(Graphics g, + ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + List pointLabels = chartXy.PointLabels; + + if (pointLabels != null && pointLabels.Count > 0) + { + foreach (PointLabelGroup lg in pointLabels) + { + if (lg.ChartSeries == this) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + Image marker = chartXy.GetPointMarker(g, pstyle); + + if (marker != null) + { + Size size = marker.Size; + + for (int i = 0; i < lg.PointLabels.Count; i++) + { + PointLabel pl = lg.PointLabels[i]; + + if (pl.Visible == true && pl.SeriesPoint.IsEmpty == false) + { + DataLabelVisualStyle dstyle = GetPointLabelVisualStyle(pl); + + if (dstyle.DrawPointMarker != Tbool.False) + { + SeriesPoint spt = pl.SeriesPoint; + + Point ppt = pl.Point; + Point ppc = new Point(ppt.X, ppt.Y); + + RenderPointMarker(g, chartXy, spt, ppc, Size.Empty, marker); + } + } + } + } + break; + } + } + } + } + + #endregion + + #region RenderLinePlotLines + + private void RenderLinePlotLines(Graphics g, ChartXy chartXy, PointData pd, + ChartLineDisplayMode lineMode, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + if ((lineMode & ChartLineDisplayMode.DisplayStepLine) == ChartLineDisplayMode.DisplayStepLine) + { + StepLineMode slm = GetStepLineMode(chartXy); + + if (slm != StepLineMode.None) + RenderStepLines(g, chartXy, pd, slm, areaMode, sstyle); + } + + if ((lineMode & ChartLineDisplayMode.DisplayLine) == ChartLineDisplayMode.DisplayLine) + RenderLines(g, chartXy, pd, lineMode, areaMode, sstyle); + + if ((lineMode & ChartLineDisplayMode.DisplaySpline) == ChartLineDisplayMode.DisplaySpline) + RenderSplines(g, chartXy, pd, lineMode, areaMode, sstyle); + + if (ShowEmptyLines == true) + { + if ((lineMode & (ChartLineDisplayMode.DisplayLine | ChartLineDisplayMode.DisplaySpline)) != 0) + RenderEmptyLines(g, chartXy, pd.Points, areaMode, sstyle); + } + } + + #region GetStepLineMode + + private StepLineMode GetStepLineMode(ChartXy chartXy) + { + StepLineMode mode = StepLineMode; + + if (mode == StepLineMode.NotSet) + mode = chartXy.StepLineMode; + + if (mode == StepLineMode.NotSet) + mode = StepLineMode.HorizontalThenVertical; + + return (mode); + } + + #endregion + + #region RenderLines + + private void RenderLines(Graphics g, ChartXy chartXy, + PointData pd, ChartLineDisplayMode lineMode, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + ChartLineVisualStyle lstyle = sstyle.LineStyle; + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if ((lineMode & ChartLineDisplayMode.DisplayClosed) == ChartLineDisplayMode.DisplayClosed) + { + foreach (Point[] points in pd.Points) + { + if (points.Length > 1) + g.DrawLines(pen, points); + } + + Point fp = pd.Points[0][0]; + Point[] lps = pd.Points[pd.Points.Count - 1]; + Point lp = lps[lps.Length - 1]; + + if (fp.Equals(lp) == false) + g.DrawLine(pen, lp, fp); + } + else + { + foreach (Point[] points in pd.Points) + { + if (points.Length > 1) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(points); + + if ((areaMode & ChartLineAreaDisplayMode.DisplayLine) == ChartLineAreaDisplayMode.DisplayLine) + RenderAreaBackground(g, chartXy, points, path, sstyle.LineAreaBackground); + + g.DrawPath(pen, path); + } + } + } + } + } + } + } + + #endregion + + #region RenderSplines + + private void RenderSplines(Graphics g, ChartXy chartXy, PointData pd, + ChartLineDisplayMode lineMode, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + ChartLineVisualStyle lstyle = sstyle.SplineStyle; + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if ((pd.Points.Count == 1) && + (lineMode & ChartLineDisplayMode.DisplayClosed) == ChartLineDisplayMode.DisplayClosed) + { + Point[] points = pd.Points[0]; + + if (points.Length > 1) + g.DrawClosedCurve(pen, points); + } + else + { + foreach (Point[] points in pd.Points) + { + if (points.Length > 1) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddCurve(points); + + if ((areaMode & ChartLineAreaDisplayMode.DisplaySpline) == ChartLineAreaDisplayMode.DisplaySpline) + RenderAreaBackground(g, chartXy, points, path, sstyle.SplineAreaBackground); + + g.DrawPath(pen, path); + } + } + } + } + } + } + } + + #endregion + + #region RenderStepLines + + private void RenderStepLines(Graphics g, ChartXy chartXy, PointData pd, + StepLineMode slm, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + StepLines sls = GetStepLines(chartXy); + + if (sls != StepLines.None) + { + PointData sd = GetStepPointData(chartXy, pd, slm); + + if (sd != null) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + + ChartCapLineVisualStyle lstyle = sstyle.StepLineStyle; + + if (sls == StepLines.Both) + { + RenderStepLinesEx1(g, sd, lstyle); + } + else + { + int n = ((sls == StepLines.Horizontal && (slm == StepLineMode.HorizontalThenVertical || slm == StepLineMode.MidPoint)) || + (sls == StepLines.Vertical && slm == StepLineMode.VerticalThenHorizontal)) ? 0 : 1; + + RenderStepLinesEx2(g, sd, n, lstyle); + + if (sstyle.StepLineAltStyle.IsEmpty == false) + RenderStepLinesEx2(g, sd, n ^ 1, sstyle.StepLineAltStyle); + } + + g.SmoothingMode = sm; + + if ((areaMode & ChartLineAreaDisplayMode.DisplayStepLine) == ChartLineAreaDisplayMode.DisplayStepLine) + { + foreach (Point[] points in sd.Points) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(points); + + RenderAreaBackground(g, chartXy, points, path, sstyle.StepLineAreaBackground); + } + } + } + } + } + } + + #region GetStepLines + + private StepLines GetStepLines(ChartXy chartXy) + { + StepLines mode = StepLines; + + if (mode == StepLines.NotSet) + mode = chartXy.StepLines; + + if (mode == StepLines.NotSet) + mode = StepLines.Both; + + return (mode); + } + + #endregion + + #region GetStepPointData + + private PointData GetStepPointData( + ChartXy chartXy, PointData pd, Charts.StepLineMode slm) + { + if (_LastStepLineMode != slm) + _StepPointData = null; + + if (_StepPointData == null) + { + PointData sd = new PointData(); + + sd.Points = new List(); + + foreach (Point[] points in pd.Points) + { + if (points.Length > 1) + sd.Points.Add(GetStepPoints(slm, points)); + } + + _StepPointData = sd; + + _LastStepLineMode = slm; + } + + return (_StepPointData); + } + + #region GetStepPoints + + private Point[] GetStepPoints(StepLineMode slm, Point[] pts) + { + if (slm == StepLineMode.HorizontalThenVertical || slm == StepLineMode.VerticalThenHorizontal) + { + Point[] points = new Point[pts.Length * 2 - 1]; + + if (slm == StepLineMode.HorizontalThenVertical) + { + for (int i = 0; i < pts.Length; i++) + { + int n = i * 2; + + points[n] = pts[i]; + + if (i + 1 < pts.Length) + points[n + 1] = new Point(pts[i + 1].X, pts[i].Y); + } + } + else + { + for (int i = 0; i < pts.Length; i++) + { + int n = i * 2; + + points[n] = pts[i]; + + if (i + 1 < pts.Length) + points[n + 1] = new Point(pts[i].X, pts[i + 1].Y); + } + } + + return (points); + } + else + { + Point[] points = new Point[pts.Length * 2]; + + points[0] = pts[0]; + + for (int i = 0; i < pts.Length - 1; i++) + { + int n0 = i * 2 + 1; + int n1 = n0 + 1; + + points[n0] = new Point((pts[i].X + pts[i + 1].X) / 2, pts[i].Y); + points[n1] = new Point(points[n0].X, pts[i + 1].Y); + } + + points[points.Length - 1] = pts[pts.Length - 1]; + + return (points); + } + } + + #endregion + + #endregion + + #region RenderStepLinesEx1 + + private void RenderStepLinesEx1(Graphics g, PointData sd, ChartCapLineVisualStyle lstyle) + { + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.StartCap != ChartLineCap.NotSet) + pen.StartCap = (LineCap)lstyle.StartCap; + + if (lstyle.EndCap != ChartLineCap.NotSet) + pen.EndCap = (LineCap)lstyle.EndCap; + + foreach (Point[] points in sd.Points) + { + if (points.Length > 1) + g.DrawLines(pen, points); + } + } + } + } + + #endregion + + #region RenderStepLinesEx2 + + private void RenderStepLinesEx2(Graphics g, + PointData sd, int n, ChartCapLineVisualStyle lstyle) + { + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.StartCap != ChartLineCap.NotSet) + pen.StartCap = (LineCap)lstyle.StartCap; + + if (lstyle.EndCap != ChartLineCap.NotSet) + pen.EndCap = (LineCap)lstyle.EndCap; + + foreach (Point[] points in sd.Points) + { + if (points.Length > 1) + { + for (int i = n; i < points.Length - 1; i += 2) + { + Point pt1 = points[i]; + Point pt2 = points[i + 1]; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + } + } + + #endregion + + #endregion + + #region RenderEmptyLines + + private void RenderEmptyLines(Graphics g, ChartXy chartXy, + List lpoints, ChartLineAreaDisplayMode areaMode, ChartSeriesVisualStyle sstyle) + { + if (lpoints.Count > 1) + { + ChartLineVisualStyle lstyle = sstyle.EmptyStyle; + + if (lstyle.LinePattern != LinePattern.None) + { + Point[] points = new Point[(lpoints.Count - 1) * 2]; + Point[][] epoints = new Point[lpoints.Count - 1][]; + + for (int i = 0; i < lpoints.Count - 1; i++) + { + Point[] pts1 = lpoints[i]; + Point[] pts2 = lpoints[i + 1]; + + epoints[i] = new Point[2]; + + epoints[i][0] = pts1[pts1.Length - 1]; + epoints[i][1] = pts2[0]; + } + + for (int i = 0; i < points.Length / 2; i++) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(epoints[i]); + + if ((areaMode & ChartLineAreaDisplayMode.DisplayEmptyLine) == ChartLineAreaDisplayMode.DisplayEmptyLine) + RenderAreaBackground(g, chartXy, epoints[i], path, sstyle.EmptyAreaBackground); + + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + g.DrawPath(pen, path); + } + } + } + } + } + } + + #endregion + + #region RenderAreaBackground + + private void RenderAreaBackground(Graphics g, + ChartXy chartXy, Point[] points, GraphicsPath path, Background background) + { + bool backEmpty = (background == null || background.IsEmpty == true); + + if (backEmpty == true) + background = new Background(Color.FromArgb(100, DefaultPaletteColor)); + + if (background != null && background.IsEmpty == false) + { + int y = chartXy.ContentBoundsEx.Bottom; + + if (AreaBaseValue != null) + { + ChartAxis axis = _AxisY ?? chartXy.AxisY; + + y = chartXy.GetDataPointY(axis, AreaBaseValue); + } + + using (GraphicsPath path2 = new GraphicsPath()) + { + path2.AddLine(new Point(points[0].X, y), points[0]); + path2.AddPath(path, true); + path2.AddLine(points[points.Length - 1], new Point(points[points.Length - 1].X, y)); + + path2.CloseFigure(); + + Rectangle r = Rectangle.Round(path2.GetBounds()); + + using (Brush br = background.GetBrush(r)) + g.FillPath(br, path2); + } + } + + if (backEmpty == true) + background.Dispose(); + } + + #endregion + + #endregion + + #region RenderHighlightPoints + + private void RenderHighlightPoints(Graphics g, + ChartXy chartXy, PointData pd, ChartSeriesVisualStyle sstyle) + { + PointMarkerVisualStyle hstyle = GetHighlightStyle(chartXy, sstyle); + + Image marker = GetHighlightImage(g, chartXy, hstyle); + + if (marker != null) + { + Size size = marker.Size; + + Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); + + for (int i = 0; i < pd.Points.Count; i++) + { + Point[] pts = pd.Points[i]; + SeriesPoint[] spts = pd.SeriesPoints[i]; + + for (int j = 0; j < pts.Length; j++) + { + Point ppt = pts[j]; + Point ppc = new Point(ppt.X, ppt.Y); + Point lppc = new Point(ppt.X + pt.X, ppt.Y + pt.Y); + + if (chartXy.IsCrosshairSeriesPoint(this, lppc) == true) + { + RenderPointMarker(g, chartXy, spts[j], ppc, Size.Empty, marker); + + if (HighLightSinglePoint(chartXy) == true) + break; + } + } + } + } + } + + #endregion + + #region GetLineDisplayMode + + private ChartLineDisplayMode GetLineDisplayMode(ChartXy chartXy) + { + ChartLineDisplayMode mode = ChartLineDisplayMode; + + if (mode == ChartLineDisplayMode.NotSet) + mode = chartXy.ChartLineDisplayMode; + + if (mode == ChartLineDisplayMode.NotSet) + mode = ChartLineDisplayMode.DisplayLine; + + return (mode); + } + + #endregion + + #region GetAreaDisplayMode + + private ChartLineAreaDisplayMode GetAreaDisplayMode(ChartXy chartXy) + { + ChartLineAreaDisplayMode mode = ChartLineAreaDisplayMode; + + if (mode == ChartLineAreaDisplayMode.NotSet) + mode = chartXy.ChartLineAreaDisplayMode; + + if (mode == ChartLineAreaDisplayMode.NotSet) + mode = ChartLineAreaDisplayMode.None; + + return (mode); + } + + #endregion + + #endregion + + #region RenderStockPlot + + #region RenderHStockPlot + + private void RenderHStockPlot(ChartRenderInfo renderInfo, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + HiLoRenderData rd = new HiLoRenderData(chartXy, AxisX ?? chartXy.AxisX); + + rd.SeriesStyle = sstyle; + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + rd.Sp = sp; + rd.Spt = sp.Point[0]; + rd.Index = i; + + RenderHStock(renderInfo, rd); + } + } + } + + #region RenderHStock + + private void RenderHStock(ChartRenderInfo renderInfo, HiLoRenderData rd) + { + Graphics g = renderInfo.Graphics; + + rd.Value = GetHStockValues(rd.ChartXy, rd.Sp); + + if (rd.Value[StockHigh] != int.MinValue) + { + Point pt = rd.ChartXy.GetDataPointEx(this, rd.Sp, 0); + + Rectangle r = GetHBoundingRect(rd, pt); + + if (r.IntersectsWith(RenderBounds) == true) + { + int y = pt.Y + BarOffset; + + rd.Sp.PointSize = new Size(5, BarWidth / 3); + + switch (HiLoBarType) + { + case HiLoBarType.Box: + case HiLoBarType.Candle: + RenderHStockBox(g, rd, y); + break; + + default: + RenderHStockHiLo(g, rd, y); + break; + } + } + } + } + + #region GetHBoundingRect + + private Rectangle GetHBoundingRect(HiLoRenderData rd, Point pt) + { + int x1 = rd.Value[StockHigh]; + int x2 = rd.Value[StockLow]; + + if (rd.Value[StockOpen] != int.MinValue) + { + if (rd.Value[StockOpen] > x1) + x1 = rd.Value[StockOpen]; + + if (rd.Value[StockOpen] < x2) + x2 = rd.Value[StockOpen]; + } + + if (rd.Value[StockClose] != int.MinValue) + { + if (rd.Value[StockClose] > x1) + x1 = rd.Value[StockClose]; + + if (rd.Value[StockClose] < x2) + x2 = rd.Value[StockClose]; + } + + int y = pt.Y + BarOffset - BarWidth / 2; + + return (new Rectangle(x2, y, x1 - x2, BarWidth)); + } + + #endregion + + #region RenderHStockBox + + private void RenderHStockBox(Graphics g, HiLoRenderData rd, int y) + { + int x1 = rd.Value[StockClose]; + int x2 = rd.Value[StockOpen]; + + if (rd.Value[StockOpen] != int.MinValue && rd.Value[StockClose] != int.MinValue) + { + if (rd.Value[StockOpen] < rd.Value[StockClose]) + { + x1 = rd.Value[StockOpen]; + x2 = rd.Value[StockClose]; + } + + if (rd.Value[StockLow] > x1) + rd.Value[StockLow] = x1; + + if (rd.Value[StockHigh] < x2) + rd.Value[StockHigh] = x2; + + rd.IsAlternate = (rd.Value[StockOpen] > rd.Value[StockClose]); + + RenderHStockBoxWhisker(g, rd, + rd.Value[StockLow], x1, y, HiLoBarSegment.LowWhisker); + + RenderHStockBoxWhisker(g, rd, + x2, rd.Value[StockHigh], y, HiLoBarSegment.HighWhisker); + + RenderHStockBoxOpenClose(g, rd, x1, x2, y); + } + else + { + int x = (x1 != int.MinValue) ? x1 : x2; + + if (x != int.MinValue) + { + if (x > rd.Value[StockHigh]) + rd.Value[StockHigh] = x; + + if (x < rd.Value[StockLow]) + rd.Value[StockLow] = x; + } + + if (x < rd.Value[StockHigh] && x > rd.Value[StockLow]) + { + RenderHStockBoxWhisker(g, rd, x, rd.Value[StockHigh], y, HiLoBarSegment.HighWhisker); + RenderHStockBoxWhisker(g, rd, rd.Value[StockLow], x, y, HiLoBarSegment.LowWhisker); + + RenderHStockBoxOpenClose(g, rd, x, x, y); + } + else + { + RenderHStockBoxWhisker(g, rd, + rd.Value[StockLow], rd.Value[StockHigh], y, HiLoBarSegment.CenterLine); + + if (x != int.MinValue) + RenderHStockBoxOpenClose(g, rd, x, x, y); + } + } + } + + #region RenderHStockBoxWhisker + + private void RenderHStockBoxWhisker(Graphics g, + HiLoRenderData rd, int x1, int x2, int y, HiLoBarSegment segment) + { + if (x2 > x1) + { + Point pt1 = new Point(x1, y); + Point pt2 = new Point(x2 + 1, y); + + RenderBoxWhisker(g, rd, pt1, pt2, segment); + } + } + + #endregion + + #region RenderHStockBoxOpenClose + + private void RenderHStockBoxOpenClose( + Graphics g, HiLoRenderData rd, int x1, int x2, int y) + { + if (x2 == x1) + { + x1--; + x2++; + } + + x2++; + + Point pt1 = new Point(x1, y - BarWidth / 2); + Point pt2 = new Point(x2, pt1.Y + BarWidth); + + int lw = RenderStockBox(g, rd, pt1, pt2); + + Rectangle r = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y); + + if (r.Width > 0 && r.Height > 0) + { + if (GetBarShading(rd.ChartXy) == true) + { + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading) == false) + { + RenderHBarShading(g, r, r, BarSegment.Left); + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading); + } + } + } + } + + #endregion + + #endregion + + #region RenderHStockBoxMedian + + private void RenderHStockBoxMedian( + Graphics g, HiLoRenderData rd, int y, int x1, int x2) + { + if (rd.Value.Length > StockMedian) + { + int x3 = rd.Value[StockMedian]; + + if (x3 > x1 && x3 < x2) + { + Point pt1 = new Point(x3, y); + Point pt2 = new Point(x3, y + BarWidth - 1); + + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, HiLoBarSegment.MedianLine); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.LineWidth > 1) + pt2.Y++; + + g.DrawLine(pen, pt1, pt2); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine); + } + } + } + } + + #endregion + + #region RenderHStockHiLo + + private void RenderHStockHiLo(Graphics g, HiLoRenderData rd, int y) + { + int x1, x2, x3, x4; + NormalizeHiLoValues(rd, out x1, out x2, out x3, out x4); + + ChartLineVisualStyle ostyle, cstyle; + NormalizeHiLoStyles(rd, out ostyle, out cstyle); + + if (rd.Value[StockOpen] != int.MinValue) + { + Point pt1 = new Point(x2, y - BarWidth / 2); + Point pt2 = new Point(pt1.X, pt1.Y + BarWidth / 2); + + RenderHiLoWhisker(g, rd, pt1, pt2, ostyle, HiLoBarSegment.OpenWhisker); + } + + if (rd.Value[StockClose] != int.MinValue) + { + Point pt1 = new Point(x3, y); + Point pt2 = new Point(pt1.X, pt1.Y + BarWidth / 2 + 1); + + RenderHiLoWhisker(g, rd, pt1, pt2, cstyle, HiLoBarSegment.CloseWhisker); + } + + if (rd.IsAlternate == false) + { + int x = x2; + x2 = x3; + x3 = x; + + ChartLineVisualStyle style = ostyle; + ostyle = cstyle; + cstyle = ostyle; + } + + if ((rd.IsAlternate == false && _RenderFullDefRange == true) || + (rd.IsAlternate == true && _RenderFullAltRange == true)) + { + RenderHiLoRange(g, rd, + new Point(x1, y), new Point(x4, y), HiLoBarSegment.FullRange); + } + else + { + // Open value either not specified or is + // set to High value. + + if (x1 == x2 && x3 != x4) + x2 = x3; + + if (x2 < x1) + { + int n = (ostyle != null) ? (ostyle.LineWidth + 1) / 2 : 1; + + RenderHiLoRange(g, rd, + new Point(x1, y), new Point(x2 + n, y), HiLoBarSegment.HighWhisker); + } + + if (x3 > x4) + { + int n = 1; + + // Low segment extends to the top. + + if (x3 == x1) + n = (cstyle.LineWidth + 1) / 2; + + // We have a Center segment. + + else if (x3 != x2) + n = -cstyle.LineWidth / 2; + + RenderHiLoRange(g, rd, + new Point(x3 + n, y), new Point(x4, y), HiLoBarSegment.LowWhisker); + } + + if (x2 > x3 || (x1 == x2 && x3 == x4)) + { + ChartLineVisualStyle y2Style = (x2 == rd.Value[StockOpen]) ? ostyle : cstyle; + ChartLineVisualStyle y3Style = (x3 == rd.Value[StockOpen]) ? ostyle : cstyle; + + if (y2Style != null) + x2 += ((y2Style.LineWidth + 1) / 2); + + if (y3Style != null) + x3 -= (y3Style.LineWidth / 2); + + RenderHiLoRange(g, rd, + new Point(x2, y), new Point(x3, y), HiLoBarSegment.CenterLine); + } + } + } + + #endregion + + #endregion + + #endregion + + #region RenderVStockPlot + + private void RenderVStockPlot(ChartRenderInfo renderInfo, + ChartXy chartXy, SortedSeriesPoints ssp, ChartSeriesVisualStyle sstyle) + { + HiLoRenderData rd = new HiLoRenderData(chartXy, AxisY ?? chartXy.AxisY); + + rd.SeriesStyle = sstyle; + + for (int i = 0; i < ssp.Count; i++) + { + SeriesPoint sp = ssp[i]; + + if (sp.Visible == true) + { + if (sp.ValueY.Length > 0) + { + rd.Sp = sp; + rd.Spt = sp.Point[0]; + rd.Index = i; + + rd.IsAlternate = false; + + RenderVStock(renderInfo, rd); + } + } + } + } + + #region RenderVStock + + private void RenderVStock(ChartRenderInfo renderInfo, HiLoRenderData rd) + { + Graphics g = renderInfo.Graphics; + + rd.Value = GetVStockValues(rd.ChartXy, rd.Sp); + + if (rd.Value[StockHigh] != int.MinValue) + { + Point pt = rd.ChartXy.GetDataPointEx(this, rd.Sp, 0); + + Rectangle r = GetVBoundingRect(rd, pt); + + if (r.IntersectsWith(RenderBounds) == true) + { + int x = pt.X + BarOffset; + + rd.Sp.PointSize = new Size(BarWidth / 3, 5); + + switch (HiLoBarType) + { + case HiLoBarType.Box: + case HiLoBarType.Candle: + RenderVStockBox(g, rd, x); + break; + + default: + RenderVStockHiLo(g, rd, x); + break; + } + } + } + } + + #region GetVBoundingRect + + private Rectangle GetVBoundingRect(HiLoRenderData rd, Point pt) + { + int y1 = rd.Value[StockHigh]; + int y2 = rd.Value[StockLow]; + + if (rd.Value[StockOpen] != int.MinValue) + { + if (y1 > rd.Value[StockOpen]) + y1 = rd.Value[StockOpen]; + + if (y2 < rd.Value[StockOpen]) + y2 = rd.Value[StockOpen]; + } + + if (rd.Value[StockClose] != int.MinValue) + { + if (y1 > rd.Value[StockClose]) + y1 = rd.Value[StockClose]; + + if (y2 < rd.Value[StockClose]) + y2 = rd.Value[StockClose]; + } + + int x = pt.X + BarOffset - BarWidth / 2; + + return (new Rectangle(x, y1, BarWidth, y2 - y1)); + } + + #endregion + + #region RenderVStockBox + + private void RenderVStockBox(Graphics g, HiLoRenderData rd, int x) + { + int y1 = rd.Value[StockOpen]; + int y2 = rd.Value[StockClose]; + + if (rd.Value[StockOpen] != int.MinValue && rd.Value[StockClose] != int.MinValue) + { + if (rd.Value[StockOpen] > rd.Value[StockClose]) + { + y1 = rd.Value[StockClose]; + y2 = rd.Value[StockOpen]; + } + + if (rd.Value[StockHigh] > y1) + rd.Value[StockHigh] = y1; + + if (rd.Value[StockLow] < y2) + rd.Value[StockLow] = y2; + + rd.IsAlternate = (rd.Value[StockOpen] < rd.Value[StockClose]); + + RenderVStockBoxWhisker(g, rd, x, + rd.Value[StockHigh], y1, HiLoBarSegment.HighWhisker); + + RenderVStockBoxWhisker(g, rd, x, + y2, rd.Value[StockLow], HiLoBarSegment.LowWhisker); + + RenderVStockBoxOpenClose(g, rd, x, y1, y2); + } + else + { + int y = (y1 != int.MinValue) ? y1 : y2; + + if (y != int.MinValue) + { + if (y < rd.Value[StockHigh]) + rd.Value[StockHigh] = y; + + if (y > rd.Value[StockLow]) + rd.Value[StockLow] = y; + } + + if (y > rd.Value[StockHigh] && y < rd.Value[StockLow]) + { + RenderVStockBoxWhisker(g, rd, x, rd.Value[StockHigh], y, HiLoBarSegment.HighWhisker); + RenderVStockBoxWhisker(g, rd, x, y, rd.Value[StockLow], HiLoBarSegment.LowWhisker); + + RenderVStockBoxOpenClose(g, rd, x, y, y); + } + else + { + RenderVStockBoxWhisker(g, rd, x, + rd.Value[StockHigh], rd.Value[StockLow], HiLoBarSegment.CenterLine); + + if (y != int.MinValue) + RenderVStockBoxOpenClose(g, rd, x, y, y); + } + } + } + + #region RenderVStockBoxWhisker + + private void RenderVStockBoxWhisker(Graphics g, + HiLoRenderData rd, int x, int y1, int y2, HiLoBarSegment segment) + { + if (y2 > y1) + { + Point pt1 = new Point(x, y1); + Point pt2 = new Point(x, y2 + 1); + + RenderBoxWhisker(g, rd, pt1, pt2, segment); + } + } + + #endregion + + #region RenderVStockBoxOpenClose + + private void RenderVStockBoxOpenClose( + Graphics g, HiLoRenderData rd, int x, int y1, int y2) + { + if (y2 == y1) + { + y1--; + y2++; + } + + y2++; + + Point pt1 = new Point(x - BarWidth / 2, y1); + Point pt2 = new Point(pt1.X + BarWidth, y2); + + int lw = RenderStockBox(g, rd, pt1, pt2); + + Rectangle r = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y); + + if (r.Width > 0 && r.Height > 0) + { + if (GetBarShading(rd.ChartXy) == true) + { + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading) == false) + { + + RenderVBarShading(g, r, r, BarSegment.Top); + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.BarShading); + } + } + } + } + + #endregion + + #endregion + + #region RenderVStockBoxMedian + + private void RenderVStockBoxMedian( + Graphics g, HiLoRenderData rd, int x, int y1, int y2) + { + if (rd.Value.Length > StockMedian) + { + int y3 = rd.Value[StockMedian]; + + if (y3 > y1 && y3 < y2) + { + Point pt1 = new Point(x, y3); + Point pt2 = new Point(x + BarWidth - 1, y3); + + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, HiLoBarSegment.MedianLine); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, lstyle.LineWidth)) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.LineWidth > 1) + pt2.X++; + + g.DrawLine(pen, pt1, pt2); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, HiLoBarSegment.MedianLine); + } + } + } + } + + #endregion + + #region RenderVStockHiLo + + private void RenderVStockHiLo(Graphics g, HiLoRenderData rd, int x) + { + int y1, y2, y3, y4; + NormalizeHiLoValues(rd, out y1, out y2, out y3, out y4); + + ChartLineVisualStyle ostyle, cstyle; + NormalizeHiLoStyles(rd, out ostyle, out cstyle); + + if (rd.Value[StockOpen] != int.MinValue) + { + Point pt1 = new Point(x - BarWidth / 2, y2); + Point pt2 = new Point(pt1.X + BarWidth / 2, pt1.Y); + + RenderHiLoWhisker(g, rd, pt1, pt2, ostyle, HiLoBarSegment.OpenWhisker); + } + + if (rd.Value[StockClose] != int.MinValue) + { + Point pt1 = new Point(x + 1, y3); + Point pt2 = new Point(pt1.X + BarWidth / 2, pt1.Y); + + RenderHiLoWhisker(g, rd, pt1, pt2, cstyle, HiLoBarSegment.CloseWhisker); + } + + NormalizeHiLoDir(rd, ref y2, ref y3, ref ostyle, ref cstyle); + + if ((rd.IsAlternate == false && _RenderFullDefRange == true) || + (rd.IsAlternate == true && _RenderFullAltRange == true)) + { + RenderHiLoRange(g, rd, + new Point(x, y1), new Point(x, y4), HiLoBarSegment.FullRange); + } + else + { + if (y1 == y2 && y3 != y4) + y2 = y3; + + // High segment + + if (y2 > y1) + { + int n = (ostyle != null) ? ostyle.LineWidth / 2 : 0; + + RenderHiLoRange(g, rd, + new Point(x, y1), new Point(x, y2 - n), HiLoBarSegment.HighWhisker); + } + + // Low segment + + if (y3 < y4) + { + int n = 0; + + if (y3 == y1) + n = -cstyle.LineWidth / 2; + + else if (y3 != y2) + n = (cstyle.LineWidth + 1) / 2; + + RenderHiLoRange(g, rd, + new Point(x, y3 + n), new Point(x, y4), HiLoBarSegment.LowWhisker); + } + + // Center segment. + + if (y2 < y3 || (y1 == y2 && y3 == y4)) + { + ChartLineVisualStyle y2Style = (y2 == rd.Value[StockOpen]) ? ostyle : cstyle; + ChartLineVisualStyle y3Style = (y3 == rd.Value[StockOpen]) ? ostyle : cstyle; + + if (y2Style != null) + y2 -= (y2Style.LineWidth / 2); + + if (y3Style != null) + y3 += ((y3Style.LineWidth + 1) / 2); + + RenderHiLoRange(g, rd, + new Point(x, y2), new Point(x, y3), HiLoBarSegment.CenterLine); + } + } + } + + #endregion + + #endregion + + #endregion + + #region GetHStockValues + + internal int[] GetHStockValues(ChartXy chartXy, SeriesPoint sp) + { + ChartAxis axis = AxisX ?? chartXy.AxisX; + + int[] values = new int[Math.Max(4, sp.ValueY.Length)]; + + for (int i = 0; i < sp.ValueY.Length; i++) + values[i] = chartXy.GetDataPointX(axis, sp.ValueY[i]); + + NormalizeStockValues(sp, values); + + return (values); + } + + #endregion + + #region GetVStockValues + + internal int[] GetVStockValues(ChartXy chartXy, SeriesPoint sp) + { + ChartAxis axis = AxisY ?? chartXy.AxisY; + + int[] values = new int[Math.Max(4, sp.ValueY.Length)]; + + for (int i = 0; i < sp.ValueY.Length; i++) + values[i] = chartXy.GetDataPointY(axis, sp.ValueY[i]); + + NormalizeStockValues(sp, values); + + return (values); + } + + #endregion + + #region NormalizeStockValues + + private void NormalizeStockValues(SeriesPoint sp, int[] values) + { + for (int i = sp.ValueY.Length; i < values.Length; i++) + values[i] = int.MinValue; + + if (values[StockLow] == int.MinValue) + values[StockLow] = values[StockHigh]; + + if ((IsRotated == true && values[StockLow] > values[StockHigh]) || + (IsRotated == false && values[StockLow] < values[StockHigh])) + { + int temp = values[StockLow]; + values[StockLow] = values[StockHigh]; + values[StockHigh] = temp; + } + } + + #endregion + + #region NormalizeHiLoValues + + private void NormalizeHiLoValues( + HiLoRenderData rd, out int v1, out int v2, out int v3, out int v4) + { + v1 = rd.Value[StockHigh]; + v4 = rd.Value[StockLow]; + + v2 = (rd.Value[StockOpen] != int.MinValue) ? rd.Value[StockOpen] : v1; + v3 = (rd.Value[StockClose] != int.MinValue) ? rd.Value[StockClose] : v4; + + if (v1 > v4) + { + if (v1 < v2) + v1 = v2; + + if (v4 > v3) + v4 = v3; + + rd.IsAlternate = (v2 > v3); + } + else + { + if (v1 > v2) + v1 = v2; + + if (v4 < v3) + v4 = v3; + + rd.IsAlternate = (v2 < v3); + } + } + + #endregion + + #region NormalizeHiLoDir + + private void NormalizeHiLoDir(HiLoRenderData rd, + ref int v1, ref int v2, ref ChartLineVisualStyle style1, ref ChartLineVisualStyle style2) + { + if (rd.IsAlternate == false) + { + int y = v1; + v1 = v2; + v2 = y; + + ChartLineVisualStyle style = style1; + style1 = style2; + style2 = style1; + } + } + + #endregion + + #region NormalizeHiLoStyles + + private void NormalizeHiLoStyles(HiLoRenderData rd, + out ChartLineVisualStyle ostyle, out ChartLineVisualStyle cstyle) + { + ostyle = (rd.Value[StockOpen] != int.MinValue) ? GetSegLineStyle(rd, HiLoBarSegment.OpenWhisker) : null; + cstyle = (rd.Value[StockClose] != int.MinValue) ? GetSegLineStyle(rd, HiLoBarSegment.CloseWhisker) : null; + + rd.EndDelta = GetHiLoEndDelta(ostyle, cstyle); + } + + #region GetHiLoEndDelta + + private int GetHiLoEndDelta( + ChartLineVisualStyle ostyle, ChartLineVisualStyle cstyle) + { + int delta = 0; + + if (ostyle != null) + { + if (ostyle.LineWidth > 1) + { + if (ostyle.LinePattern != LinePattern.None) + delta = (ostyle.LineWidth + 1) / 2; + } + } + + if (cstyle != null) + { + if (cstyle.LineWidth > 1) + { + if (cstyle.LinePattern != LinePattern.None) + delta = Math.Max(delta, (cstyle.LineWidth + 1) / 2); + } + } + + return (delta); + } + + #endregion + + #endregion + + #region RenderBoxWhisker + + private void RenderBoxWhisker(Graphics g, + HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (chartControl.DoPreRenderSeriesHiloBarEvent(g, chartXy, this, rd, pt1, pt2, segment) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, segment); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + Point pt3 = pt2; + + if (lstyle.LineWidth == 1) + { + if (pt1.X == pt2.X) + pt3.Y--; + else + pt3.X--; + } + + g.DrawLine(pen, pt1, pt3); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent(g, chartXy, this, rd, pt1, pt2, segment); + } + + if (rd.SeriesStyle.HiLoBarVisualStyle.ShowWhiskerCaps == Tbool.True) + RenderWhiskerCap(g, rd, pt1, pt2, segment); + + g.SmoothingMode = sm; + } + + #region RenderWhiskerCap + + private void RenderWhiskerCap(Graphics g, + HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + if (segment == HiLoBarSegment.HighWhisker || segment == HiLoBarSegment.LowWhisker) + { + HiLoBarSegment capSegment = (segment == HiLoBarSegment.HighWhisker) + ? HiLoBarSegment.HighWhiskerCap : HiLoBarSegment.LowWhiskerCap; + + GetWhiskerCapPoints(segment, ref pt1, ref pt2); + + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, capSegment) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, capSegment); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, lstyle.LineWidth)) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (lstyle.LineWidth == 1) + { + if (pt1.X == pt2.X) + pt2.Y--; + else + pt2.X--; + } + + g.DrawLine(pen, pt1, pt2); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, rd.ChartXy, this, rd, pt1, pt2, capSegment); + } + } + } + + #region GetWhiskerCapPoints + + private void GetWhiskerCapPoints( + HiLoBarSegment segment, ref Point pt1, ref Point pt2) + { + int n = BarWidth / 3; + + switch (segment) + { + case HiLoBarSegment.HighWhisker: + if (pt1.X == pt2.X) + { + pt1.X -= n; + pt2.X += n + 1; + pt2.Y = pt1.Y; + } + else + { + pt1.Y -= n; + pt2.Y += n + 1; + pt1.X = pt2.X; + } + break; + + case HiLoBarSegment.LowWhisker: + if (pt1.X == pt2.X) + { + pt1.X -= n; + pt2.X += n + 1; + pt1.Y = pt2.Y; + } + else + { + pt1.Y -= n; + pt2.Y += n + 1; + pt2.X = pt1.X; + } + break; + } + } + + #endregion + + #endregion + + #endregion + + #region RenderStockBox + + private int RenderStockBox( + Graphics g, HiLoRenderData rd, Point pt1, Point pt2) + { + int lineWidth = 0; + + Rectangle r = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y); + + if (r.Width > 0 && r.Height > 0) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (chartControl.DoPreRenderSeriesHiloBarEvent( + g, chartXy, this, rd, pt1, pt2, HiLoBarSegment.Box) == false) + { + if (HiLoBarType == HiLoBarType.Box) + RenderStockBoxBackground(g, rd, r); + else + RenderStockCandleBackground(g, rd, r); + + ChartLineVisualStyle lstyle = rd.DefaultStyle.BoxBorder; + + if (CanUseAlternateSegmentStyle(rd) == true) + { + if (rd.IsAlternate == true && rd.AlternateStyle.BoxBorder.IsEmpty == false) + lstyle = rd.AlternateStyle.BoxBorder; + } + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + lineWidth = (int)pen.Width; + + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + if (pt1.X == pt2.X || pt1.Y == pt2.Y) + { + g.DrawLine(pen, pt1, pt2); + } + else + { + pen.Alignment = PenAlignment.Inset; + + if (lstyle.LineWidth == 1) + { + r.Width--; + r.Height--; + } + + if (r.Width > 0 && r.Height > 0) + g.DrawRectangle(pen, r); + } + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent( + g, chartXy, this, rd, pt1, pt2, HiLoBarSegment.Box); + } + + if (ShowHiLoBarMedianLines == true) + { + if (IsRotated == false) + RenderVStockBoxMedian(g, rd, r.X, r.Y, r.Bottom); + else + RenderHStockBoxMedian(g, rd, r.Y, r.X, r.Right); + } + + g.SmoothingMode = sm; + } + + return (lineWidth); + } + + #region RenderStockCandleBackground + + private void RenderStockCandleBackground( + Graphics g, HiLoRenderData rd, Rectangle r) + { + Background bk = + GetBoxBackground(rd, rd.AlternateStyle.BoxBackground, rd.DefaultStyle.BoxBackground); + + if (bk.IsEmpty == false) + { + using (Brush br = bk.GetBrush(r)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region RenderStockBoxBackground + + private void RenderStockBoxBackground( + Graphics g, HiLoRenderData rd, Rectangle r) + { + Background bkDef = rd.DefaultStyle.BoxBackground; + Background bkAlt = rd.AlternateStyle.BoxBackground; + + if (bkAlt.IsEmpty == true) + bkAlt = bkDef; + + if (rd.IsAlternate == true) + { + Background bkSave = bkDef; + bkDef = bkAlt; + bkAlt = bkSave; + } + + if ((ShowHiLoBarMedianLines == true) && (rd.Value.Length > StockMedian)) + { + if (bkAlt.IsEmpty == false) + { + if (IsRotated == false) + r = RenderVBox(g, rd.Value[StockMedian], bkAlt, r); + else + r = RenderHBox(g, rd.Value[StockMedian], bkAlt, r); + } + } + + if (r.Width > 0 && r.Height > 0) + { + if (bkDef.IsEmpty == false) + { + using (Brush br = bkDef.GetBrush(r)) + g.FillRectangle(br, r); + } + } + } + + #region RenderVBox + + private Rectangle RenderVBox(Graphics g, int y, Background bk, Rectangle r) + { + if ((y > r.Y && y < r.Bottom) && bk.IsEmpty == false) + { + int ry = r.Y; + + r.Height = r.Bottom - y; + r.Y = y; + + using (Brush br = bk.GetBrush(r)) + g.FillRectangle(br, r); + + r.Y = ry; + r.Height = y - ry; + } + + return (r); + } + + #endregion + + #region RenderHBox + + private Rectangle RenderHBox(Graphics g, int x, Background bk, Rectangle r) + { + if (x > r.X && x < r.Right) + { + int rw = r.Width; + + r.Width = x - r.X; + + using (Brush br = bk.GetBrush(r)) + g.FillRectangle(br, r); + + r.X = r.Right; + r.Width = rw - r.Width; + } + + return (r); + } + + #endregion + + #endregion + + #endregion + + #region RenderHiLoWhisker + + private ChartLineVisualStyle RenderHiLoWhisker(Graphics g, + HiLoRenderData rd, Point pt1, Point pt2, ChartLineVisualStyle style, HiLoBarSegment segment) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (chartControl.DoPreRenderSeriesHiloBarEvent(g, chartXy, this, rd, pt1, pt2, segment) == false) + { + if (style.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(style.LineColor, Dpi.Width(style.LineWidth))) + { + if (style.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)style.LinePattern; + + if (style.LineWidth == 1) + { + if (pt1.X == pt2.X) + pt2.Y--; + else + pt2.X--; + } + + g.DrawLine(pen, pt1, pt2); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent(g, chartXy, this, rd, pt1, pt2, segment); + } + + g.SmoothingMode = sm; + + return (style); + } + + #endregion + + #region RenderHiLoRange + + private void RenderHiLoRange( + Graphics g, HiLoRenderData rd, Point pt1, Point pt2, HiLoBarSegment segment) + { + ChartXy chartXy = rd.ChartXy; + ChartControl chartControl = ChartControl; + + if (pt1.X == pt2.X) + { + if (segment == HiLoBarSegment.HighWhisker || segment == HiLoBarSegment.FullRange) + pt1.Y -= rd.EndDelta; + + if (segment == HiLoBarSegment.LowWhisker || segment == HiLoBarSegment.FullRange) + pt2.Y += rd.EndDelta; + } + else + { + if (segment == HiLoBarSegment.LowWhisker || segment == HiLoBarSegment.FullRange) + pt2.X -= rd.EndDelta; + + if (segment == HiLoBarSegment.HighWhisker || segment == HiLoBarSegment.FullRange) + pt1.X += rd.EndDelta; + } + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (chartControl.DoPreRenderSeriesHiloBarEvent(g, chartXy, this, rd, pt1, pt2, segment) == false) + { + ChartLineVisualStyle lstyle = GetSegLineStyle(rd, segment); + + if (lstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + if (lstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + + g.DrawLine(pen, pt1, pt2); + } + } + } + + if (ShowHiLoBarMedianLines == true) + { + if (segment == HiLoBarSegment.CenterLine || segment == HiLoBarSegment.FullRange) + { + if (IsRotated == false) + RenderVStockBoxMedian(g, rd, pt1.X - BarWidth / 2, pt1.Y, pt2.Y); + else + RenderHStockBoxMedian(g, rd, pt1.Y - BarWidth / 2, pt2.X, pt1.X); + } + } + + chartControl.DoPostRenderSeriesHiLoBarEvent(g, chartXy, this, rd, pt1, pt2, segment); + + g.SmoothingMode = sm; + } + + #endregion + + #region GetSegLineStyle + + private ChartLineVisualStyle GetSegLineStyle(HiLoRenderData rd, HiLoBarSegment segment) + { + ChartLineVisualStyle style = rd.DefaultStyle.Default; + + if (CanUseAlternateSegmentStyle(rd) == true) + { + if (rd.IsAlternate == true && rd.AlternateStyle.Default.IsEmpty == false) + style = rd.AlternateStyle.Default; + } + + switch (segment) + { + case HiLoBarSegment.FullRange: + break; + + case HiLoBarSegment.Box: + if (rd.IsAlternate == true && rd.AlternateStyle.BoxBorder.IsEmpty == false) + { + style = rd.AlternateStyle.BoxBorder; + } + else + { + if (rd.DefaultStyle.BoxBorder.IsEmpty == false) + style = rd.DefaultStyle.BoxBorder; + } + break; + + case HiLoBarSegment.MedianLine: + if (rd.IsAlternate == true && rd.AlternateStyle.MedianLine.IsEmpty == false) + { + style = rd.AlternateStyle.MedianLine; + } + else + { + if (rd.DefaultStyle.MedianLine.IsEmpty == false) + style = rd.DefaultStyle.MedianLine; + } + break; + + case HiLoBarSegment.HighWhiskerCap: + if (rd.IsAlternate == true && rd.AlternateStyle.HighWhiskerCap.IsEmpty == false) + { + style = rd.AlternateStyle.HighWhiskerCap; + } + else + { + if (rd.DefaultStyle.HighWhiskerCap.IsEmpty == false) + style = rd.DefaultStyle.HighWhiskerCap; + } + break; + + case HiLoBarSegment.LowWhiskerCap: + if (rd.IsAlternate == true && rd.AlternateStyle.LowWhiskerCap.IsEmpty == false) + { + style = rd.AlternateStyle.LowWhiskerCap; + } + else + { + if (rd.DefaultStyle.LowWhiskerCap.IsEmpty == false) + style = rd.DefaultStyle.LowWhiskerCap; + } + break; + + case HiLoBarSegment.HighWhisker: + if (rd.IsAlternate == true && rd.AlternateStyle.HighWhisker.IsEmpty == false) + { + style = rd.AlternateStyle.HighWhisker; + } + else + { + if (rd.DefaultStyle.HighWhisker.IsEmpty == false) + style = rd.DefaultStyle.HighWhisker; + } + break; + + case HiLoBarSegment.LowWhisker: + if (rd.IsAlternate == true && rd.AlternateStyle.LowWhisker.IsEmpty == false) + { + style = rd.AlternateStyle.LowWhisker; + } + else + { + if (rd.DefaultStyle.LowWhisker.IsEmpty == false) + style = rd.DefaultStyle.LowWhisker; + } + break; + + case HiLoBarSegment.OpenWhisker: + if (rd.IsAlternate == true && rd.AlternateStyle.OpenWhisker.IsEmpty == false) + { + style = rd.AlternateStyle.OpenWhisker; + } + else + { + if (rd.DefaultStyle.OpenWhisker.IsEmpty == false) + style = rd.DefaultStyle.OpenWhisker; + } + break; + + case HiLoBarSegment.CloseWhisker: + if (rd.IsAlternate == true && rd.AlternateStyle.CloseWhisker.IsEmpty == false) + { + style = rd.AlternateStyle.CloseWhisker; + } + else + { + if (rd.DefaultStyle.CloseWhisker.IsEmpty == false) + style = rd.DefaultStyle.CloseWhisker; + } + break; + + case HiLoBarSegment.CenterLine: + if (rd.IsAlternate == true && rd.AlternateStyle.CenterLine.IsEmpty == false) + { + style = rd.AlternateStyle.CenterLine; + } + else + { + if (rd.DefaultStyle.CenterLine.IsEmpty == false) + style = rd.DefaultStyle.CenterLine; + } + break; + } + + return (style); + } + + #region CanUseAlternateSegmentStyle + + private bool CanUseAlternateSegmentStyle(HiLoRenderData rd) + { + Tbool uas = rd.SeriesStyle.HiLoBarVisualStyle.UseAlternateSegmentStyle; + + if (uas == Tbool.NotSet) + return (HiLoBarType == HiLoBarType.Candle); + + return (uas == Tbool.True); + } + + #endregion + + #endregion + + #region GetBoxBackground + + private Background GetBoxBackground(HiLoRenderData rd, Background abk, Background sbk) + { + if (rd.IsAlternate == true && abk.IsEmpty == false) + return (abk); + + return (sbk); + } + + #endregion + + #endregion + + #region HighLightPoints + + private bool HighLightPoints(ChartXy chartXy) + { + if (chartXy.ChartCrosshair.Visible == false) + return (false); + + if (CrosshairHighlightPoints != Tbool.NotSet) + return (CrosshairHighlightPoints == Tbool.True); + + return (chartXy.ChartCrosshair.HighlightPoints); + } + + #endregion + + #region HighLightSinglePoint + + private bool HighLightSinglePoint(ChartXy chartXy) + { + if (chartXy.ChartCrosshair.Visible == false) + return (false); + + if (CrosshairHighlightSinglePoint != Tbool.NotSet) + return (CrosshairHighlightSinglePoint == Tbool.True); + + return (chartXy.ChartCrosshair.HighlightSinglePoint); + } + + #endregion + + #region GetHighlightStyle + + private PointMarkerVisualStyle GetHighlightStyle( + ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + if (HighLightPoints(chartXy) == true) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + PointMarkerVisualStyle hstyle = pstyle.Copy(); + + if (sstyle.MarkerHighlightVisualStyle.IsEmpty == false) + { + hstyle.ApplyStyle(sstyle.MarkerHighlightVisualStyle); + } + else + { + Size size = hstyle.Size; + + size.Width += 4; + size.Height += 4; + + hstyle.Size = size; + } + + return (hstyle); + } + + return (null); + } + + #endregion + + #region GetPointMarkerImage + + private Image GetPointMarkerImage( + Graphics g, ChartXy chartXy, PointMarkerVisualStyle style) + { + Image image = PointMarkerImage; + + if (image == null) + { + image = chartXy.GetPointMarker(g, style); + + PointMarkerImage = image; + } + + return (image); + } + + #endregion + + #region GetHighlightImage + + private Image GetHighlightImage( + Graphics g, ChartXy chartXy, PointMarkerVisualStyle style) + { + Image image = PointMarkerHighlightImage; + + if (image == null) + { + image = chartXy.GetPointMarker(g, style); + + PointMarkerHighlightImage = image; + } + + return (image); + } + + #endregion + + #region GetEmptyMarkerImage + + private Image GetEmptyMarkerImage( + Graphics g, ChartXy chartXy, PointMarkerVisualStyle style) + { + Image image = PointMarkerEmptyImage; + + if (image == null) + { + image = chartXy.GetPointMarker(g, style); + + PointMarkerEmptyImage = image; + } + + return (image); + } + + #endregion + + #region GatherSeriesPoints + + private PointData GatherSeriesPoints( + ChartXy chartXy, SortedSeriesPoints ssp, int index, int count, bool allArgs) + { + if (_PointData == null) + _PointData = GatherSeriesPointsEx(chartXy, ssp, index, count, allArgs); + + return (_PointData); + } + + private PointData GatherSeriesPointsEx( + ChartXy chartXy, SortedSeriesPoints ssp, int index, int count, bool allArgs) + { + PointData pd = new PointData(); + + pd.Points = new List(); + pd.SeriesPoints = new List(); + + if (EnableEmptyValues == true) + { + PointData epd = new PointData(); + + epd.Points = new List(); + epd.SeriesPoints = new List(); + + int n = 0; + bool empty = false; + + for (int i = 0; i < count; i++) + { + if (ssp[index + i].IsEmpty != empty) + { + int cnt = i - n; + + if (cnt > 0) + GetPointList(chartXy, ssp, index + n, cnt, allArgs, empty ? epd : pd); + + empty = !empty; + + n = i; + } + } + + if (n < count) + GetPointList(chartXy, ssp, index + n, count - n, allArgs, empty ? epd : pd); + + _EmptyPointData = epd; + } + else + { + GetPointList(chartXy, ssp, index, count, allArgs, pd); + } + + return (pd); + } + + #endregion + + #region GetPointList + + private void GetPointList(ChartXy chartXy, + SortedSeriesPoints ssp, int index, int cnt, bool allArgs, PointData pd) + { + GetPointList(chartXy, ssp, index, cnt, 0, 0, allArgs, pd); + } + + private void GetPointList(ChartXy chartXy, SortedSeriesPoints ssp, + int index, int cnt, int skip, int minDistance, bool allArgs, PointData pd) + { + if (cnt > 0) + { + Stack stack = new Stack(); + + skip++; + + Point lpt = new Point(-5000, -5000); + + if (allArgs == false) + { + if (cnt > skip && skip > 1) + cnt = (cnt + skip - 1) / skip; + + for (int i = 0; i < cnt; i++) + { + int n = index + (i * skip); + + if (n >= ssp.Count) + break; + + SeriesPoint sp = ssp[n]; + + if (sp.Visible == true) + { + Point pt = chartXy.GetDataPointEx(this, sp, 0); + + if (minDistance <= 0 || DataPointDistanceOk(lpt, pt, minDistance) == true) + { + stack.Push(sp); + stack.Push(pt); + + lpt = pt; + } + } + } + } + else + { + int n = 0; + + for (int i = 0; i < cnt; i++) + n += ssp[index + i].ValueY.Length; + + n /= (n + skip - 1) / skip; + + int m = 0; + + for (int i = 0; i < cnt; i++) + { + SeriesPoint sp = ssp[index + i]; + + for (int j = 0; j < sp.ValueY.Length; j++) + { + if (m % skip == 0) + { + int w = m / skip; + + Point pt = chartXy.GetDataPointNa(this, sp, j); + + if (minDistance <= 0 || DataPointDistanceOk(lpt, pt, minDistance) == true) + { + stack.Push(sp); + stack.Push(pt); + + lpt = pt; + } + } + + m++; + } + } + } + + if (stack.Count > 0) + { + int n = stack.Count / 2; + + Point[] points = new Point[n]; + SeriesPoint[] seriesPoints = new SeriesPoint[n]; + + for (int i = n - 1; i >= 0; i--) + { + points[i] = (Point)stack.Pop(); + seriesPoints[i] = (SeriesPoint)stack.Pop(); + } + + pd.Points.Add(points); + pd.SeriesPoints.Add(seriesPoints); + } + } + } + + #region DataPointDistanceOk + + private bool DataPointDistanceOk(Point lpt, Point pt, int minDistance) + { + int dx = (lpt.X - pt.X); + int dy = (lpt.Y - pt.Y); + + int h = (int)MathHelper.Sqrt(dx * dx + dy * dy); + + return (h >= minDistance); + } + + #endregion + + #endregion + + #endregion + + #region Render + + internal override void Render(ChartRenderInfo renderInfo) + { + if (Displayed == true) + { + Rectangle bounds = BoundsRelative; + + if (renderInfo.ClipRectangle.IntersectsWith(bounds)) + RenderOverride(renderInfo); + } + } + + #endregion + + #region RenderIndicators + + internal void RenderIndicators(ChartRenderInfo renderInfo, bool onTop) + { + if (SeriesType != SeriesType.HorizontalDot || SeriesType != SeriesType.VerticalDot) + { + if (SeriesPoints.Count > 0) + { + Graphics g = renderInfo.Graphics; + + ChartXy chartXy = Parent as ChartXy; + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + + foreach (ChartIndicator indicator in ChartIndicators) + { + if (indicator.DisplayOnTop == onTop) + { + if (indicator.IsDisplayed == true) + { + ssp.SlopeIndex = indicator.ValueYIndex; + + switch (indicator.IndicatorType) + { + case ChartIndicatorType.RegressionLine: + RenderRegressionLine(g, chartXy, ssp, (RegressionLine)indicator); + break; + + case ChartIndicatorType.TrendLine: + RenderTrendLine(g, chartXy, ssp, (TrendLine)indicator); + break; + } + } + } + } + } + } + } + + #region RenderRegressionLine + + private void RenderRegressionLine(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, RegressionLine regline) + { + double m = regline.Slope; + double b = regline.Intercept; + + if (m.Equals(double.NaN) == false && b.Equals(double.NaN) == false) + { + ChartAxis axis = AxisX ?? chartXy.AxisX; + + double x1, x2; + + switch (ActualScaleTypeX) + { + case ScaleType.DateTime: + x1 = chartXy.GetDateTimePointValue(axis, axis.TickmarkLayout, (DateTime)MinValueX); + x2 = chartXy.GetDateTimePointValue(axis, axis.TickmarkLayout, (DateTime)MaxValueX); + break; + + default: + x1 = Convert.ToDouble(MinValueX); + x2 = Convert.ToDouble(MaxValueX); + break; + } + + Point pt1 = chartXy.GetPointFromValue(this, MinValueX, m * x1 + b); + Point pt2 = chartXy.GetPointFromValue(this, MaxValueX, m * x2 + b); + + if (SeriesType == SeriesType.VerticalBar || + SeriesType == SeriesType.VerticalHiLoBar) + { + pt1.X += BarOffset; + pt2.X += BarOffset; + } + else if (SeriesType == SeriesType.HorizontalBar || + SeriesType == SeriesType.HorizontalHiLoBar) + { + pt1.Y += BarOffset; + pt2.Y += BarOffset; + } + + RegressionLineVisualStyle rstyle = regline.RegressionLineVisualStyle; + + Color color = rstyle.LineColor; + + if (color.IsEmpty) + color = DefaultPaletteColor; + + using (Pen pen = new Pen(color, Dpi.Width(rstyle.LineWidth))) + { + if (rstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)rstyle.LinePattern; + + if (rstyle.StartCap != ChartLineCap.NotSet) + pen.StartCap = (LineCap)rstyle.StartCap; + + if (rstyle.EndCap != ChartLineCap.NotSet) + pen.EndCap = (LineCap)rstyle.EndCap; + + g.DrawLine(pen, pt1, pt2); + } + } + } + + #endregion + + #region RenderTrendLine + + private void RenderTrendLine(Graphics g, + ChartXy chartXy, SortedSeriesPoints ssp, TrendLine trendLine) + { + SeriesPoint sp1 = ssp.GetSeriesPoint(trendLine.ValueX1); + SeriesPoint sp2 = ssp.GetSeriesPoint(trendLine.ValueX2); + + if (sp1 != null && sp2 != null) + { + Point pt1 = chartXy.GetDataPointEx(this, sp1, trendLine.ValueYIndex); + Point pt2 = chartXy.GetDataPointEx(this, sp2, trendLine.ValueYIndex); + + if (SeriesType == SeriesType.VerticalBar || + SeriesType == SeriesType.VerticalHiLoBar) + { + pt1.X += BarOffset; + pt2.X += BarOffset; + } + else if (SeriesType == SeriesType.HorizontalBar || + SeriesType == SeriesType.HorizontalHiLoBar) + { + pt1.Y += BarOffset; + pt2.Y += BarOffset; + } + + if (pt1.X >= chartXy.ContentBounds.X && pt2.X < chartXy.ContentBounds.Right) + { + TrendLineVisualStyle tstyle = trendLine.TrendLineVisualStyle; + + Color color = tstyle.LineColor; + + if (color.IsEmpty) + color = DefaultPaletteColor; + + using (Pen pen = new Pen(color, Dpi.Width(tstyle.LineWidth))) + { + if (tstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)tstyle.LinePattern; + + if (tstyle.StartCap != ChartLineCap.NotSet) + pen.StartCap = (LineCap)tstyle.StartCap; + + if (tstyle.EndCap != ChartLineCap.NotSet) + pen.EndCap = (LineCap)tstyle.EndCap; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #endregion + + #region InvalidatePoints + + internal void InvalidatePoints() + { + _PointData = null; + _EmptyPointData = null; + _ConvexHullPoints = null; + _StepPointData = null; + } + + #endregion + + #region InvalidatePointLabels + + internal void InvalidatePointLabels() + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + chartXy.InvalidatePointLabelsEx(); + } + + #endregion + + #region UpdateSeriesRange + + internal void UpdateSeriesRange() + { + if (SeriesRangeChanged == true) + { + if (Parent == null) + return; + + SeriesRangeChanged = false; + + IsSorted = true; + + QualitativeXValues.Clear(); + QualitativeYValues.Clear(); + + _MinValueX = null; + _MinValueY = null; + _MaxValueX = null; + _MaxValueY = null; + + if (SeriesPoints.Count > 0) + { + BaseChart chart = Parent as BaseChart; + + Type dataTypeX = null; + Type dataTypeY = null; + + if (ChartControl != null && ChartControl.DesignerHosted == true) + { + dataTypeX = GetDataTypeX(SeriesPoints); + dataTypeY = GetDataTypeY(SeriesPoints); + + ActualScaleTypeX = GetActualScaleType(dataTypeX, ScaleTypeX); + ActualScaleTypeY = GetActualScaleType(dataTypeY, ScaleTypeY); + + _PlotData = null; + } + + for (int i = 0; i < SeriesPoints.Count; i++) + { + SeriesPoint sp = SeriesPoints[i]; + + if (sp.Visible == true) + { + UpdateXValueRange(chart, sp, ref dataTypeX); + + switch (SeriesType) + { + case SeriesType.VerticalDot: + case SeriesType.HorizontalDot: + ActualScaleTypeY = ScaleType.Quantitative; + break; + + case SeriesType.Bubble: + UpdateYBubbleRange(chart, sp, ref dataTypeY); + break; + + default: + UpdateYValueRange(chart, sp, ref dataTypeY); + break; + } + } + } + + if (SeriesType == SeriesType.VerticalDot || + SeriesType == SeriesType.HorizontalDot) + { + UpdateStackedYValueRange(); + } + else + { + if (QualitativeXValues.Count > 0) + { + _MinValueX = 0; + _MaxValueX = QualitativeXValues.Count - 1; + } + + if (QualitativeYValues.Count > 0) + { + _MinValueY = 0; + _MaxValueY = QualitativeYValues.Count - 1; + } + } + } + } + } + + #region GetDataTypeX + + private Type GetDataTypeX(SeriesPointCollection spc) + { + Type dataType = null; + + for (int i = 0; i < spc.Count; i++) + { + SeriesPoint sp = spc[i]; + + if (sp.Visible == true) + { + if (sp.ValueX != null) + { + dataType = sp.ValueX.GetType(); + + if (dataType != typeof(int)) + break; + } + } + } + + return (dataType); + } + + #endregion + + #region GetDataTypeY + + private Type GetDataTypeY(SeriesPointCollection spc) + { + Type dataType = null; + + for (int i = 0; i < spc.Count; i++) + { + SeriesPoint sp = spc[i]; + + if (sp.Visible == true) + { + if (sp.ValueY != null && sp.ValueY.Length > 0) + { + for (int j = 0; j < sp.ValueY.Length; j++) + { + object valueY = sp.ValueY[j]; + + if (valueY != null) + { + dataType = valueY.GetType(); + + if (dataType != typeof(int)) + return (dataType); + } + } + } + } + } + + return (dataType); + } + + #endregion + + #region UpdateXValueRange + + private int _CmpLast; + + private void UpdateXValueRange(BaseChart chart, SeriesPoint sp, ref Type dataType) + { + object value = sp.ValueX; + + if (value != null) + { + if (dataType == null) + { + dataType = value.GetType(); + + ActualScaleTypeX = GetActualScaleType(dataType, ScaleTypeX); + } + else + { + if (value.GetType() != dataType) + { + if (ChartControl.DesignerHosted == true) + { + try + { + sp.ValueX = Convert.ChangeType(value, dataType); + } + catch + { + sp.ValueX = null; + } + + value = sp.ValueX; + } + else + { + throw new Exception("Cannot mix ValueX data types (" + + dataType + "," + value.GetType() + ")."); + } + } + } + + switch (_ActualScaleTypeX) + { + case ScaleType.Qualitative: + if (QualitativeXValues.Contains(value) == false) + QualitativeXValues.Add(value); + break; + + default: + if (_MinValueX == null) + { + _MinValueX = value; + _MaxValueX = value; + + _CmpLast = 0; + } + else + { + if (chart.DataCompare(value, _MaxValueX) >= 0) + { + _MaxValueX = value; + + if (_CmpLast == 0) + _CmpLast = 1; + + else if (_CmpLast < 0) + IsSorted = false; + } + else + { + if (chart.DataCompare(value, _MinValueX) <= 0) + _MinValueX = value; + + if (_CmpLast == 0) + _CmpLast = -1; + + else if (_CmpLast > 0) + IsSorted = false; + } + } + break; + } + } + } + + #endregion + + #region UpdateYBubbleRange + + private void UpdateYBubbleRange(BaseChart chart, SeriesPoint sp, ref Type dataType) + { + if (sp.ValueY == null || sp.ValueY.Length < 1) + throw new Exception("Invalid Bubble Chart 'Y' arguments."); + + if (_PlotData == null) + _PlotData = new BubblePlotData(); + + BubblePlotData bdata = (BubblePlotData)_PlotData; + + object value = sp.ValueY[0]; + + sp.IsEmptyValue = IsEmptyValue(value); + + if (sp.IsEmpty == false) + { + if (dataType == null) + { + bdata.Clear(); + + dataType = value.GetType(); + + ActualScaleTypeY = GetActualScaleType(dataType, ScaleTypeY); + } + else + { + if (value.GetType() != dataType) + { + if (ChartControl.DesignerHosted == true) + { + sp.ValueY[0] = Convert.ChangeType(value, dataType); + + value = sp.ValueY[0]; + } + else + { + throw new Exception("Cannot mix ValueY data types (" + + dataType + "," + value.GetType() + ")."); + } + } + } + + ProcessYValueRange(chart, value); + + if (sp.ValueY.Length > 1) + { + double bvalue = GetDoubleValue(sp.ValueY[1]); + + bvalue = Math.Abs(bvalue); + + if (bvalue < bdata.MinSize) + bdata.MinSize = bvalue; + + if (bvalue > bdata.MaxSize) + bdata.MaxSize = bvalue; + + bdata.TotalSize += bvalue; + + if (sp.ValueY.Length > 2) + { + double ivalue = GetDoubleValue(sp.ValueY[2]); + + if (ivalue < bdata.MinIntensity) + bdata.MinIntensity = ivalue; + + if (ivalue > bdata.MaxIntensity) + bdata.MaxIntensity = ivalue; + } + } + } + } + + #endregion + + #region UpdateYValueRange + + private void UpdateYValueRange(BaseChart chart, SeriesPoint sp, ref Type dataType) + { + if (sp.ValueY != null) + { + for (int j = 0; j < sp.ValueY.Length; j++) + { + object value = sp.ValueY[j]; + + sp.IsEmptyValue = IsEmptyValue(value); + + if (sp.IsEmpty == false) + { + if (dataType == null) + { + dataType = value.GetType(); + + ActualScaleTypeY = GetActualScaleType(dataType, ScaleTypeY); + } + else + { + if (value.GetType() != dataType) + { + if (ChartControl.DesignerHosted == true) + { + try + { + sp.ValueY[j] = Convert.ChangeType(value, dataType); + } + catch + { + sp.ValueY[j] = null; + } + + value = sp.ValueY[j]; + } + else + { + throw new Exception("Cannot mix ValueY data types (" + + dataType + "," + value.GetType() + ")."); + } + } + } + + ProcessYValueRange(chart, value); + } + } + } + else + { + sp.IsEmptyValue = true; + } + } + + #region IsEmptyValue + + private bool IsEmptyValue(object value) + { + if (value == null) + return (true); + + if (EmptyValues != null) + { + Type dataType = value.GetType(); + + for (int i = 0; i < EmptyValues.Length; i++) + { + if (EmptyValues[i] != null) + { + if (dataType == EmptyValues[i].GetType()) + { + if (value.Equals(EmptyValues[i]) == true) + return (true); + } + } + } + } + + return (false); + } + + #endregion + + #endregion + + #region UpdateStackedYValueRange + + private void UpdateStackedYValueRange() + { + if (QualitativeXValues.Count > 0 || QualitativeYValues.Count > 0) + throw new Exception("Dot plots can not contain Qualitative values."); + + Dictionary pd = new Dictionary(); + + for (int i = 0; i < SeriesPoints.Count; i++) + { + SeriesPoint sp = SeriesPoints[i]; + + if (sp.Visible == true) + { + object ox = sp.ValueX; + + double count = 0; + + if (sp.ValueY != null && sp.ValueY.Length > 0) + { + foreach (object oy in sp.ValueY) + { + sp.IsEmptyValue = IsEmptyValue(oy); + + if (sp.IsEmpty == false) + count += GetDoubleValue(oy); + } + } + else + { + if (sp.IsEmpty == false) + count++; + } + + if (sp.IsEmpty == false) + { + if (pd.ContainsKey(ox) == true) + pd[ox] += count; + else + pd.Add(ox, count); + } + } + } + + double maxValue = 0; + + foreach (KeyValuePair kvp in pd) + { + if (kvp.Value > maxValue) + maxValue = kvp.Value; + } + + _MinValueY = 0.0; + _MaxValueY = maxValue; + } + + #endregion + + #region ProcessYValueRange + + private void ProcessYValueRange(BaseChart chart, object value) + { + switch (_ActualScaleTypeY) + { + case ScaleType.Qualitative: + if (QualitativeYValues.Contains(value) == false) + QualitativeYValues.Add(value); + break; + + default: + if (_MinValueY == null) + { + _MinValueY = value; + _MaxValueY = value; + } + else + { + int cmpMax = chart.DataCompare(value, _MaxValueY); + + if (cmpMax >= 0) + { + _MaxValueY = value; + } + else + { + int cmpMin = chart.DataCompare(value, _MinValueY); + + if (cmpMin <= 0) + _MinValueY = value; + } + } + break; + } + } + + #endregion + + #region GetActualScaleType + + private ScaleType GetActualScaleType(Type dataType, ScaleType scaleType) + { + ScaleType autoType = SeriesPoint.GetScaleType(dataType); + + if (scaleType == ScaleType.NotSet || scaleType == ScaleType.Auto) + return (autoType); + + if (scaleType == autoType) + return (scaleType); + + if (scaleType == ScaleType.Qualitative) + return (scaleType); + + throw new Exception("Set ScaleType is incompatible with series data."); + } + + #endregion + + #endregion + + #region ResetSortedPoints + + internal void ResetSortedPoints() + { + if (IsSorted == false) + _SortedSeriesPoints = null; + } + + #endregion + + #region GetValueX + + internal object GetValueX(SeriesPoint sp) + { + if (IsRotated == false) + return (sp.ValueX); + + if (sp.ValueY != null && sp.ValueY.Length > 0) + return (sp.ValueY[0]); + + return (null); + } + + #endregion + + #region GetValueY + + internal object GetValueY(SeriesPoint sp, int index) + { + if (IsRotated == true) + return (sp.ValueX); + + if (sp.ValueY != null && sp.ValueY.Length > index) + return (sp.ValueY[index]); + + return (null); + } + + #endregion + + #region GetQualitativeValueX + + internal object GetQualitativeValueX(int index) + { + if (IsRotated == false) + { + if (QualitativeXValues != null && QualitativeXValues.Count > index) + return (QualitativeXValues[index]); + } + else + { + if (QualitativeYValues != null && QualitativeYValues.Count > index) + return (QualitativeYValues[index]); + } + + return (null); + } + + #endregion + + #region GetQualitativeValueY + + internal object GetQualitativeValueY(int index) + { + if (IsRotated == true) + { + if (QualitativeXValues != null && QualitativeXValues.Count > index) + return (QualitativeXValues[index]); + } + else + { + if (QualitativeYValues != null && QualitativeYValues.Count > index) + return (QualitativeYValues[index]); + } + + return (null); + } + + #endregion + + #region GetDoubleValue + + private double GetDoubleValue(object value) + { + if (value is double) + return (double)value; + + return (Convert.ToDouble(value)); + } + + #endregion + + #region AddSeriesPoint + + internal override void AddSeriesPoint(object valueX, object[] valuesY, object dataItem) + { + SeriesPoint sp = new SeriesPoint(valueX, valuesY); + + sp.DataItem = dataItem; + + SeriesPoints.Add(sp); + } + + #endregion + + #region ClearSeriesPoints + + internal override void ClearSeriesPoints() + { + SeriesPoints.Clear(); + } + + #endregion + + #region GetBarWidthRatio + + internal double GetBarWidthRatio(ChartXy chartXy) + { + return (_BarWidthRatio > 0 ? _BarWidthRatio : + (chartXy.BarWidthRatio > 0 ? chartXy.BarWidthRatio : 1)); + } + + #endregion + + #region GetPointLabels + + internal List GetPointLabels(Graphics g) + { + ChartXy chartXy = Parent as ChartXy; + + PointLabelDisplayMode plmode = GetPointLabelDisplayType(chartXy); + + if (plmode != PointLabelDisplayMode.None) + { + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + ssp.SeriesLayoutCount = chartXy.SeriesLayoutCount; + + ChartAxis axisX = (IsRotated == true) ? AxisY ?? chartXy.AxisY : AxisX ?? chartXy.AxisX; + ChartAxis axisY = (IsRotated == true) ? AxisX ?? chartXy.AxisX : AxisY ?? chartXy.AxisY; + + if (ssp.Count > 0) + { + DataLabelVisualStyle dstyle = EffectiveDataLabelStyle; + + PointData pd = GetLabelPoints(chartXy, ssp, 0, ssp.Count, plmode); + + List plabels = new List(); + + if (pd.Points.Count > 0) + { + for (int i = 0; i < pd.Points.Count; i++) + { + Point[] pts = pd.Points[i]; + SeriesPoint[] spts = pd.SeriesPoints[i]; + + for (int j = 0; j < pts.Length; j++) + { + SeriesPoint sp = spts[j]; + Point pt = pts[j]; + + if (IsBarSeries == true && ShowOriginValueLabels == false) + { + if (IsBarOrigin(chartXy, sp) == true) + continue; + } + + string text = GetPointLabelText(sp, axisX, axisY, dstyle); + + PointLabel pl = new PointLabel(sp, pt, text); + + pl.LabelSize = MeasurePointLabel(g, pl); + + plabels.Add(pl); + } + } + } + + if ((plmode & PointLabelDisplayMode.DataLabels) == PointLabelDisplayMode.DataLabels) + GetDataLabels(g, plabels, chartXy, axisX, axisY, dstyle); + + return (plabels); + } + } + + return (null); + } + + #region GetPointLabelDisplayType + + private PointLabelDisplayMode GetPointLabelDisplayType(ChartXy chartXy) + { + PointLabelDisplayMode ptype = PointLabelDisplayMode; + + if (ptype != PointLabelDisplayMode.NotSet) + return (ptype); + + ptype = chartXy.PointLabelDisplayMode; + + return (ptype != PointLabelDisplayMode.NotSet ? ptype : PointLabelDisplayMode.None); + } + + #endregion + + #region GetLabelPoints + + /// + /// Gets the collection of series PointData for the given PointLabelDisplayType. + /// + /// + /// + public PointData GetLabelPoints(PointLabelDisplayMode displayType) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + { + SortedSeriesPoints ssp = GetSortedSeriesPoints(chartXy); + + return (GetLabelPoints(chartXy, ssp, 0, ssp.Count, displayType)); + } + + return (null); + } + + private PointData GetLabelPoints(ChartXy chartXy, + SortedSeriesPoints ssp, int index, int count, PointLabelDisplayMode displayType) + { + PointData pd = new PointData(); + + pd.Points = new List(); + pd.SeriesPoints = new List(); + + if ((displayType & PointLabelDisplayMode.AllSeriesPoints) == PointLabelDisplayMode.AllSeriesPoints) + GetPointList(chartXy, ssp, index, count, _PointLabelSkip, _PointLabelMinDistance, false, pd); + + else if ((displayType & ~PointLabelDisplayMode.AllSeriesPoints) != 0) + { + List lmmsp = new List(); + + if ((displayType & PointLabelDisplayMode.MinValueX) == PointLabelDisplayMode.MinValueX) + { + int n; + + if (IsRotated == true) + { + if (QualitativeYValues.Count > 0) + n = (int)MinValueX; + else + n = ssp.SearchY(MinValueX); + } + else + { + if (QualitativeXValues.Count > 0) + n = (int)MinValueX; + else + n = (ssp.IsSorted == true) ? 0 : ssp.SearchX(MinValueX); + } + + if (n >= 0) + lmmsp.Add(ssp[n]); + } + + if ((displayType & PointLabelDisplayMode.MaxValueX) == PointLabelDisplayMode.MaxValueX) + { + int n; + + if (IsRotated == true) + { + if (QualitativeYValues.Count > 0) + n = (int)MaxValueX; + else + n = ssp.SearchY(MaxValueX); + } + else + { + if (QualitativeXValues.Count > 0) + n = (int)MaxValueX; + else + n = (ssp.IsSorted == true) ? ssp.Count - 1 : ssp.SearchX(MaxValueX); + } + + if (n >= 0 && lmmsp.Contains(ssp[n]) == false) + lmmsp.Add(ssp[n]); + } + + if ((displayType & PointLabelDisplayMode.MinValueY) == PointLabelDisplayMode.MinValueY) + { + int n; + + if (IsRotated == true) + { + if (QualitativeXValues.Count > 0) + n = (int)MinValueY; + else + n = (ssp.IsSorted == true) ? 0 : ssp.SearchX(MinValueY); + } + else + { + if (QualitativeYValues.Count > 0) + n = (int)MinValueY; + else + n = ssp.SearchY(MinValueY); + } + + if (n >= 0 && lmmsp.Contains(ssp[n]) == false) + lmmsp.Add(ssp[n]); + } + + if ((displayType & PointLabelDisplayMode.MaxValueY) == PointLabelDisplayMode.MaxValueY) + { + int n; + + if (IsRotated == true) + { + if (QualitativeXValues.Count > 0) + n = (int)MaxValueY; + else + n = ssp.SearchX(MaxValueY); + } + else + { + if (QualitativeYValues.Count > 0) + n = (int)MaxValueY; + else + n = ssp.SearchY(MaxValueY); + } + + if (n >= 0 && lmmsp.Contains(ssp[n]) == false) + lmmsp.Add(ssp[n]); + } + + if (lmmsp.Count > 0) + { + SeriesPoint[] mmsp = new SeriesPoint[lmmsp.Count]; + Point[] mmpt = new Point[lmmsp.Count]; + + for (int i = 0; i < lmmsp.Count; i++) + { + mmsp[i] = lmmsp[i]; + mmpt[i] = chartXy.GetDataPointNa(this, lmmsp[i], 0); + } + + pd.SeriesPoints.Add(mmsp); + pd.Points.Add(mmpt); + } + } + + return (pd); + } + + #endregion + + #region GetDataLabels + + private void GetDataLabels(Graphics g, List plabels, + ChartXy chartXy, ChartAxis axisX, ChartAxis axisY, DataLabelVisualStyle dstyle) + { + foreach (DataLabel dlabel in DataLabels) + { + DataLabelVisualStyle xstyle = dlabel.EffectiveDataLabelStyle; + + PointLabel pl = FindPointLabel(plabels, dlabel); + + if (pl != null) + { + if (string.IsNullOrEmpty(dlabel.Text) == false) + pl.Label = dlabel.Text; + + pl.DataLabelVisualStyle = xstyle; + pl.BarLabelPosition = dlabel.BarLabelPosition; + + pl.LabelSize = MeasurePointLabel(g, pl); + } + else + { + SeriesPoint sp = new SeriesPoint(dlabel.ValueX, dlabel.ValueY); + + string label = (string.IsNullOrEmpty(dlabel.Text) == false) ? dlabel.Text : + GetPointLabelText(sp, axisX, axisY, xstyle); + + Point pt = chartXy.GetDataPointNa(this, sp, 0); + + pl = new PointLabel(sp, pt, label); + + pl.IsDataLabel = true; + + pl.DataLabelVisualStyle = xstyle; + pl.BarLabelPosition = dlabel.BarLabelPosition; + + pl.LabelSize = MeasurePointLabel(g, pl); + + plabels.Add(pl); + } + } + } + + #region FindPointLabel + + private PointLabel FindPointLabel(List plabels, DataLabel dlabel) + { + for (int i = 0; i < plabels.Count; i++) + { + SeriesPoint sp = plabels[i].SeriesPoint; + + if ((sp.ValueX != null) && + (sp.ValueY != null && sp.ValueY.Length > 0) && + (sp.ValueX.Equals(dlabel.ValueX) && sp.ValueY[0].Equals(dlabel.ValueY))) + { + return (plabels[i]); + } + } + + return (null); + } + + #endregion + + #endregion + + #region IsBarOrigin + + internal bool IsBarOrigin(ChartXy chartXy, SeriesPoint sp) + { + object value = ((sp.ValueY != null && sp.ValueY.Length > 1) ? sp.ValueY[1] : (chartXy.BarOrigin ?? 0)); + + ChartAxis axis = AxisY ?? chartXy.AxisY; + + switch (axis.ScaleType) + { + case ScaleType.Quantitative: + double d1 = Convert.ToDouble(value); + double d2 = Convert.ToDouble(sp.ValueY[0]); + + return (d1.Equals(d2)); + + case ScaleType.Qualitative: + string s1 = axis.QualitativeValues[0] as string; + string s2 = sp.ValueY[0] as string; + + if (s1 != null) + return (s1.Equals(s2)); + break; + } + + return (false); + } + + #endregion + + #region GetPointLabelText + + private string GetPointLabelText(SeriesPoint sp, + ChartAxis axisX, ChartAxis axisY, DataLabelVisualStyle dstyle) + { + string pattern = dstyle.TextFormat; + + if (string.IsNullOrEmpty(pattern) == true) + return (GetDefaultPointLabelText(sp, axisX, axisY, dstyle)); + + pattern = pattern.Replace("\\n", "\n"); + pattern = pattern.Replace("\\r", "\r"); + + Regex regex = new Regex("{([^}]*)}"); + MatchCollection mc = regex.Matches(pattern); + + StringBuilder sb = new StringBuilder(); + + int index = 0; + + foreach (Match ma in mc) + { + if (ma.Index > index) + sb.Append(pattern.Substring(index, ma.Index - index)); + + sb.Append(ProcessFormatSpecifier(sp, axisX, axisY, ma.Value)); + + index = ma.Index + ma.Length; + } + + if (index < pattern.Length) + sb.Append(pattern.Substring(index)); + + return (sb.ToString()); + } + + #region ProcessFormatSpecifier + + private string ProcessFormatSpecifier( + SeriesPoint sp, ChartAxis axisX, ChartAxis axisY, string pattern) + { + string s = pattern.Substring(1, pattern.Length - 2); + + int n = s.IndexOf(':'); + + if ((uint)n > s.Length - 1) + n = s.Length; + + string placeHolder = s.Substring(0, n).Trim().ToUpper(); + string formatSpecifier = (n + 1 < s.Length) ? s.Substring(n + 1) : ""; + + try + { + switch (placeHolder) + { + case "X": + return (GetPointLabelText(sp.ValueX, axisX, formatSpecifier)); + + case "Y": + case "Y0": + if (sp.ValueY != null && sp.ValueY.Length > 0) + return (GetPointLabelText(sp.ValueY[0], axisY, formatSpecifier)); + + return (""); + + case "S": + case "SNAME": + if (string.IsNullOrEmpty(formatSpecifier) == false) + return (String.Format(formatSpecifier, Name)); + + return (Name); + + default: + if (placeHolder.StartsWith("Y") == true) + { + int index = int.Parse(placeHolder.Substring(1)); + + if (sp.ValueY != null && sp.ValueY.Length > index) + return (GetPointLabelText(sp.ValueY[index], axisY, formatSpecifier)); + } + + return (s); + } + } + catch + { + } + + return (s); + } + + #endregion + + #region GetDefaultPointLabelText + + private string GetDefaultPointLabelText(SeriesPoint sp, + ChartAxis axisX, ChartAxis axisY, DataLabelVisualStyle dstyle) + { + String text = string.Empty; + + if (IsBarSeries == true) + { + text = GetPointLabelText(sp.ValueY[0], axisY, string.Empty); + } + else + { + text = GetPointLabelText(sp.ValueX, axisX, string.Empty); + + if (sp.ValueY != null) + text += " : " + GetPointLabelText(sp.ValueY[0], axisY, string.Empty); + } + + return (text); + } + + #endregion + + #region GetPointLabelText + + private string GetPointLabelText( + object value, ChartAxis axis, string format) + { + switch (axis.ScaleType) + { + case ScaleType.DateTime: + if (string.IsNullOrEmpty(format) == false) + { + if (value is DateTime) + { + DateTime date = (DateTime)value; + + return (date.ToString(format)); + } + } + + return (GetDateTimeLabelText(axis, (DateTime)value)); + + case ScaleType.Qualitative: + if (string.IsNullOrEmpty(format) == false) + return (string.Format(format, value)); + + return (value.ToString()); + + default: + double d = Convert.ToDouble(value); + + if (string.IsNullOrEmpty(format) == false) + return (d.ToString(format)); + + return (d.ToString("F3")); + } + } + + #region GetDateTimeLabelText + + internal string GetDateTimeLabelText(ChartAxis axis, DateTime dt) + { + switch (axis.ActualDateTimeUnits) + { + case DateTimeUnits.Ticks: + return (dt.Ticks.ToString()); + + case DateTimeUnits.Milliseconds: + return (dt.Millisecond.ToString()); + + case DateTimeUnits.Seconds: + return (dt.Second.ToString()); + + case DateTimeUnits.Minutes: + return (dt.Minute.ToString()); + + case DateTimeUnits.Hours: + return (dt.ToShortTimeString()); + + case DateTimeUnits.Days: + return (dt.ToShortDateString()); + + case DateTimeUnits.Months: + return (dt.Year + " " + dt.Month); + + default: + return (dt.Year.ToString()); + } + } + + #endregion + + #endregion + + #endregion + + #region MeasurePointLabel + + internal Size MeasurePointLabel(Graphics g, PointLabel pl) + { + DataLabelVisualStyle dstyle = GetPointLabelVisualStyle(pl); + + int width = (dstyle.MaxTextWidth > 0) ? dstyle.MaxTextWidth : 0; + + using (StringFormat sf = new StringFormat()) + { + if (dstyle.MaxTextLineCount <= 1) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + Size size = g.MeasureString(pl.Label, dstyle.Font, width, sf).ToSize(); + size.Width++; + + if (dstyle.MaxTextLineCount > 1) + { + int lineHeight = (int)(Math.Ceiling(dstyle.Font.GetHeight())) * dstyle.MaxTextLineCount; + + if (size.Height > lineHeight) + size.Height = lineHeight; + } + + return (size); + } + } + + #region GetPointLabelVisualStyle + + internal DataLabelVisualStyle GetPointLabelVisualStyle(PointLabel pl) + { + DataLabelVisualStyle dstyle = EffectiveDataLabelStyle.Copy(); + + if (pl.DataLabelVisualStyle != null) + dstyle.ApplyStyle(pl.DataLabelVisualStyle); + else + dstyle = EffectiveDataLabelStyle; + + return (dstyle); + } + + #endregion + + #endregion + + #endregion + + #region GetRotateDegrees + + internal RotateDegrees GetRotateDegrees(DataLabelVisualStyle dstyle) + { + RotateDegrees degrees = dstyle.RotateDegrees; + + if (degrees == RotateDegrees.Auto || degrees == RotateDegrees.NotSet) + { + switch (SeriesType) + { + case SeriesType.HorizontalBar: + case SeriesType.HorizontalHiLoBar: + return (RotateDegrees.None); + + case SeriesType.VerticalBar: + case SeriesType.VerticalHiLoBar: + return (RotateDegrees.Rotate270); + + default: + return (RotateDegrees.None); + } + } + + return (dstyle.RotateDegrees); + } + + #endregion + + #region IsConvexHullPoint + + /// + /// Determines whether the given SeriesPoint is a ConvexHull point. + /// + /// + /// + public bool IsConvexHullPoint(SeriesPoint sp) + { + if (sp != null && _ConvexHullPoints != null) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + { + ConvexHullDisplayMode mode = GetConvexHullDisplayMode(chartXy); + + if (mode != ConvexHullDisplayMode.None) + { + foreach (Point ptc in _ConvexHullPoints) + { + if (ptc.Equals(sp.Point[0]) == true) + return (true); + } + } + } + } + + return (false); + } + + #endregion + + #region IsHighLightPoint + + /// + /// Determines if the given SeriesPoint is a HighLight Point (a + /// point highlighted by the Crosshair setup). + /// + /// + /// + public bool IsHighLightPoint(SeriesPoint sp) + { + if (sp != null) + { + ChartXy chartXy = Parent as ChartXy; + + if (chartXy != null) + return (chartXy.IsCrosshairSeriesPoint(this, sp.Point[0])); + } + + return (false); + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + ChartSeriesVisualStyle sstyle = style as ChartSeriesVisualStyle; + + if (sstyle != null) + { + ApplyParentStyles(sstyle, Parent as ChartContainer); + + sstyle.ApplyStyle(ChartSeriesVisualStyle); + + ApplyDefaultLineStyles(sstyle.LineStyle); + ApplyDefaultLineStyles(sstyle.SplineStyle); + ApplyDefaultLineStyles(sstyle.StepLineStyle); + ApplyDefaultLineStyles(sstyle.EmptyStyle); + + ApplyDefaultMarkerStyles(sstyle.MarkerVisualStyle); + ApplyDefaultMarkerStyles(sstyle.MarkerEmptyVisualStyle); + + if (sstyle.EmptyAreaBackground.IsEmpty) + sstyle.EmptyAreaBackground = new Background(Color.FromArgb(100, Color.LightGray)); + + if (SeriesType == SeriesType.Bubble) + { + if (sstyle.MarkerVisualStyle.Background.IsEmpty) + sstyle.MarkerVisualStyle.Background = new Background(DefaultPaletteColor); + } + + ApplyDefaultBarStyles(sstyle.BarVisualStyle); + ApplyDefaultOhlcBarStyles(sstyle.HiLoBarVisualStyle); + } + else if (style is DataLabelVisualStyle) + { + DataLabelVisualStyle dstyle = (DataLabelVisualStyle)style; + + ApplyParentStyles(dstyle, Parent as ChartContainer); + + dstyle.ApplyStyle(_DataLabelVisualStyle); + + dstyle.ApplyDefaults(); + } + } + + #region ApplyParentStyles (ChartSeriesVisualStyle) + + private void ApplyParentStyles(ChartSeriesVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is ChartXy) + pstyle.ApplyStyle(((ChartXy)item).ChartSeriesVisualStyle); + + if (item is ChartPanel) + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartSeriesVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartSeriesVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartSeriesVisualStyle); + } + } + + #endregion + + #region ApplyParentStyles (DataLabelVisualStyle) + + private void ApplyParentStyles(DataLabelVisualStyle dstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(dstyle, item.Parent as ChartContainer); + + if (item is BaseChart) + dstyle.ApplyStyle(((ChartXy)item).DataLabelVisualStyle); + + if (item is ChartPanel) + dstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.DataLabelVisualStyle); + } + else + { + dstyle.ApplyStyle(ChartControl.BaseVisualStyles.DataLabelVisualStyle); + dstyle.ApplyStyle(ChartControl.DefaultVisualStyles.DataLabelVisualStyle); + } + } + + #endregion + + #region ApplyDefaultLineStyles + + private void ApplyDefaultLineStyles(ChartLineVisualStyle lstyle) + { + if (lstyle.LineColor.IsEmpty == true) + lstyle.LineColor = DefaultPaletteColor; + + lstyle.ApplyDefaults(); + } + + #endregion + + #region ApplyDefaultMarkerStyles + + private void ApplyDefaultMarkerStyles(PointMarkerVisualStyle pstyle) + { + if (pstyle.Background.IsEmpty && pstyle.BorderColor.IsEmpty) + pstyle.BorderColor = DefaultPaletteColor; + + pstyle.ApplyDefaults(); + } + + #endregion + + #region ApplyDefaultBarStyles + + private void ApplyDefaultBarStyles(ChartBarVisualStyle bstyle) + { + if (bstyle.Background.IsEmpty == true) + bstyle.Background = new Background(DefaultPaletteColor); + + ApplyDefaultLineStyles(bstyle.Border); + } + + #endregion + + #region ApplyDefaultOhlcBarStyles + + private void ApplyDefaultOhlcBarStyles(ChartHiLoBarVisualStyle bstyle) + { + HiLoBarSegmentStyle sstyle = bstyle.DefaultSegmentStyle; + + if (sstyle.Default.LineColor.IsEmpty == true) + sstyle.Default.LineColor = Color.Black; + + sstyle.Default.ApplyDefaults(); + + switch (HiLoBarType) + { + case HiLoBarType.Candle: + bool backSet = (sstyle.BoxBackground.IsEmpty == true); + + if (backSet == true) + sstyle.BoxBackground = new Background(DefaultPaletteColor); + + Background bk = sstyle.BoxBackground; + + sstyle = bstyle.AlternateSegmentStyle; + + if (sstyle.BoxBackground.IsEmpty == true) + { + if (backSet == true) + { + sstyle.BoxBackground = new Background(Color.Black, DefaultPaletteColor); + sstyle.BoxBackground.HatchFillType = HatchFillType.ForwardDiagonal; + } + else + { + if (bk.IsSolidBrush == true) + { + sstyle.BoxBackground = new Background(Color.Black, bk.Color1); + sstyle.BoxBackground.HatchFillType = HatchFillType.ForwardDiagonal; + } + else if (bk.Color1.IsEmpty == false && bk.Color2.IsEmpty == false) + { + sstyle.BoxBackground = new Background(bk.Color2, bk.Color1); + } + } + } + break; + + case Charts.HiLoBarType.Box: + if (sstyle.BoxBackground.IsEmpty == true) + sstyle.BoxBackground = new Background(DefaultPaletteColor); + break; + } + + sstyle = bstyle.DefaultSegmentStyle; + + _RenderFullDefRange = sstyle.CenterLine.IsEmpty && + sstyle.HighWhisker.IsEmpty && sstyle.LowWhisker.IsEmpty; + + sstyle = bstyle.AlternateSegmentStyle; + + _RenderFullAltRange = sstyle.CenterLine.IsEmpty && + sstyle.HighWhisker.IsEmpty && sstyle.LowWhisker.IsEmpty; + } + + private bool _RenderFullDefRange; + private bool _RenderFullAltRange; + + #endregion + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + if (_EffectiveChartSeriesStyle.InvalidateStyle() == true) + InvalidateLayout(); + + if (_EffectiveDataLabelStyle.InvalidateStyle() == true) + InvalidateLayout(); + + foreach (DataLabel dl in DataLabels) + dl.InvalidateStyle(); + + if (LegendItem != null) + LegendItem.EffectiveStyles.InvalidateStyles(); + + PointMarkerImage = null; + PointMarkerEmptyImage = null; + PointMarkerHighlightImage = null; + } + + #endregion + + #region StyleChanged + + protected override void StyleChanged(object sender, PropertyChangedEventArgs e) + { + base.StyleChanged(sender, e); + + if (sender is ChartLegendItemVisualStyles && LegendItem != null) + InvalidateRender(LegendItem.Bounds); + } + + #endregion + + #endregion + + #region ILegendItem + + #region OnCheckStateChanged + + internal override void OnCheckStateChanged() + { + if (IsQualitativeXValues || IsQualitativeYValues) + InvalidateLayout(); + + if (PointLabelDisplayMode != PointLabelDisplayMode.None) + InvalidatePointLabels(); + + base.OnCheckStateChanged(); + } + + #endregion + + #region AddSubLegendItems + + internal override void AddSubLegendItems(List list) + { + foreach (ChartIndicator ci in ChartIndicators) + { + if (ci.Visible == true) + { + ChartLegendItem li = ci.GetLegendItem(); + + if (li != null) + list.Add(li); + } + } + } + + #endregion + + #region GetLegendItemColorEx + + internal override Color GetLegendItemColorEx() + { + ChartXy chartXy = Parent as ChartXy; + + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + if (sstyle.ItemColor.IsEmpty == false) + return (sstyle.ItemColor); + + switch (SeriesType) + { + case SeriesType.Bubble: + case SeriesType.Point: + case SeriesType.HorizontalDot: + case SeriesType.VerticalDot: + return (pstyle.Background.Color1); + + case SeriesType.Line: + ChartLineDisplayMode mode = GetLineDisplayMode(chartXy); + + if ((mode & ChartLineDisplayMode.DisplayLine) == ChartLineDisplayMode.DisplayLine) + { + if (sstyle.LineStyle.LineColor.IsEmpty == false) + return (sstyle.LineStyle.LineColor); + } + + if ((mode & ChartLineDisplayMode.DisplaySpline) == ChartLineDisplayMode.DisplaySpline) + { + if (sstyle.SplineStyle.LineColor.IsEmpty == false) + return (sstyle.SplineStyle.LineColor); + } + + if ((mode & ChartLineDisplayMode.DisplayStepLine) == ChartLineDisplayMode.DisplayStepLine) + { + if (sstyle.StepLineStyle.LineColor.IsEmpty == false) + return (sstyle.StepLineStyle.LineColor); + } + + return (pstyle.Background.Color1); + + case SeriesType.HorizontalBar: + case SeriesType.VerticalBar: + return (sstyle.BarVisualStyle.Background.Color1); + + case SeriesType.HorizontalHiLoBar: + case SeriesType.VerticalHiLoBar: + HiLoBarSegmentStyle hstyle = sstyle.HiLoBarVisualStyle.DefaultSegmentStyle; + + if (HiLoBarType == HiLoBarType.Line) + { + if (hstyle.Default.LineColor.IsEmpty == false) + return (hstyle.Default.LineColor); + + return (hstyle.CenterLine.LineColor); + } + + return (hstyle.BoxBackground.Color1); + } + + return (Color.Empty); + } + + #endregion + + #region RenderLegendItemMarkerEx + + internal override void RenderLegendItemMarkerEx( + Graphics g, ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + ChartXy chartXy = Parent as ChartXy; + ChartSeriesVisualStyle sstyle = EffectiveChartSeriesStyle; + + Rectangle bounds = litem.MarkerBounds; + + switch (SeriesType) + { + case SeriesType.HorizontalHiLoBar: + case SeriesType.VerticalHiLoBar: + RenderHiLoBarMarker(g, bounds, chartXy, sstyle); + break; + + case SeriesType.VerticalBar: + case SeriesType.HorizontalBar: + RenderBarMarker(g, bounds, chartXy, sstyle); + break; + + case SeriesType.Bubble: + RenderBubbleMarker(g, bounds, chartXy, sstyle); + break; ; + + case SeriesType.VerticalDot: + case SeriesType.HorizontalDot: + case SeriesType.Point: + RenderDotMarker(g, bounds, chartXy, sstyle); + break; + + case SeriesType.Line: + RenderLineMarker(g, bounds, chartXy, sstyle); + break; + + default: + RenderDefaultMarker(g, bounds, sstyle); + break; + } + } + + #region RenderHiLoBarMarker + + private void RenderHiLoBarMarker(Graphics g, + Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + Rectangle r = bounds; + r.Inflate(-1, -1); + + if (r.Width > 0 && r.Height > 0) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + HiLoBarSegmentStyle hstyle = sstyle.HiLoBarVisualStyle.DefaultSegmentStyle; + + if (HiLoBarType == HiLoBarType.Line) + { + Color color = hstyle.Default.LineColor; + + if (color.IsEmpty == true) + color = hstyle.CenterLine.LineColor; + + if (color.IsEmpty == true) + color = DefaultPaletteColor; + + if (color.IsEmpty == true) + color = Color.Black; + + if (IsRotated == true || r.Width > r.Height) + RenderHiLoHBarMarker(g, r, color); + else + RenderHiLoVBarMarker(g, r, color); + } + else + { + Background bk = hstyle.BoxBackground; + ChartLineVisualStyle lstyle = hstyle.BoxBorder; + + if (IsRotated == true || r.Width > r.Height) + RenderHBoxMarker(g, r, bk, hstyle, lstyle); + else + RenderVBoxMarker(g, r, bk, hstyle, lstyle); + } + + g.SmoothingMode = sm; + } + } + + #region RenderHBoxMarker + + private void RenderHBoxMarker(Graphics g, Rectangle r, + Background bk, HiLoBarSegmentStyle hstyle, ChartLineVisualStyle lstyle) + { + int n = r.Height / 4; + + Rectangle t = r; + t.Inflate(-n, -n); + + if (t.Height % 2 != 0) + { + t.Y--; + t.Height++; + } + + using (Brush br = bk.GetBrush(t)) + g.FillRectangle(br, t); + + Color lineColor = lstyle.LineColor; + + if (lineColor.IsEmpty == true) + lineColor = hstyle.Default.LineColor; + + if (lineColor.IsEmpty == true) + lineColor = Color.Black; + + using (Pen pen = new Pen(lineColor)) + { + Point pt1 = new Point(r.X, (r.Y + r.Bottom) / 2); + Point pt2 = new Point(t.X, pt1.Y); + + g.DrawLine(pen, pt1, pt2); + + pt1.X = t.Right; + pt2.X = r.Right; + + g.DrawLine(pen, pt1, pt2); + } + + using (Pen pen = new Pen(lineColor)) + g.DrawRectangle(pen, t); + } + + #endregion + + #region RenderVBoxMarker + + private void RenderVBoxMarker(Graphics g, Rectangle r, + Background bk, HiLoBarSegmentStyle hstyle, ChartLineVisualStyle lstyle) + { + int n = r.Width / 4; + + Rectangle t = r; + t.Inflate(-n, -n); + + if (t.Width % 2 != 0) + { + t.X--; + t.Width++; + } + + using (Brush br = bk.GetBrush(t)) + g.FillRectangle(br, t); + + Color lineColor = lstyle.LineColor; + + if (lineColor.IsEmpty == true) + lineColor = hstyle.Default.LineColor; + + if (lineColor.IsEmpty == true) + lineColor = Color.Black; + + using (Pen pen = new Pen(lineColor)) + { + Point pt1 = new Point((r.X + r.Right) / 2, r.Y); + Point pt2 = new Point(pt1.X, t.Y); + + g.DrawLine(pen, pt1, pt2); + + pt1.Y = t.Bottom; + pt2.Y = r.Bottom; + + g.DrawLine(pen, pt1, pt2); + } + + using (Pen pen = new Pen(lineColor)) + g.DrawRectangle(pen, t); + } + + #endregion + + #region RenderHiLoHBarMarker + + private void RenderHiLoHBarMarker(Graphics g, Rectangle r, Color color) + { + Point pt1 = new Point(r.X, (r.Y + r.Bottom) / 2); + Point pt2 = new Point(r.Right, pt1.Y); + + using (Pen pen = new Pen(color)) + { + g.DrawLine(pen, pt1, pt2); + + int n = (r.Bottom - r.Top) / 3; + + pt1.X = r.X + (r.Width / 4); + pt1.Y -= n; + + pt2.X = pt1.X; + + g.DrawLine(pen, pt1, pt2); + + pt1.X = r.X + (r.Width / 4) * 3; + pt1.Y += (2 * n); + pt2.X = pt1.X; + + g.DrawLine(pen, pt1, pt2); + } + } + + #endregion + + #region RenderHiLoVBarMarker + + private void RenderHiLoVBarMarker(Graphics g, Rectangle r, Color color) + { + Point pt1 = new Point((r.X + r.Right) / 2, r.Y); + Point pt2 = new Point(pt1.X, r.Bottom); + + using (Pen pen = new Pen(color)) + { + g.DrawLine(pen, pt1, pt2); + + int n = (r.Right - r.Left) / 3; + + pt1.X -= n; + pt1.Y = r.Y + (r.Height / 4); + pt2.Y = pt1.Y; + + g.DrawLine(pen, pt1, pt2); + + pt1.X += (2 * n); + pt1.Y = r.Y + (r.Height / 4) * 3; + pt2.Y = pt1.Y; + + g.DrawLine(pen, pt1, pt2); + } + } + + #endregion + + #endregion + + #region RenderBarMarker + + private void RenderBarMarker(Graphics g, Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + ChartLineVisualStyle cstyle = sstyle.BarVisualStyle.Border; + Background bk = sstyle.BarVisualStyle.Background; + + Rectangle r = bounds; + r.Inflate(-1, -1); + + using (Brush br = bk.GetBrush(r)) + { + g.FillRectangle(br, r); + + if (cstyle.LineColor.IsEmpty == false && cstyle.LinePattern != LinePattern.None) + { + using (Pen pen = new Pen(cstyle.LineColor, cstyle.LineWidth)) + { + if (cstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)cstyle.LinePattern; + + g.DrawRectangle(pen, r); + } + } + } + } + + #endregion + + #region RenderBubbleMarker + + private void RenderBubbleMarker(Graphics g, + Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + Background bk = pstyle.Background; + + Rectangle r = bounds; + r.Inflate(-1, -1); + + using (Brush br = pstyle.Background.GetBrush(r)) + { + g.FillEllipse(br, r); + + if (pstyle.BorderColor.IsEmpty == false && pstyle.BorderWidth > 0) + { + using (Pen pen = new Pen(pstyle.BorderColor, pstyle.BorderWidth)) + g.DrawEllipse(pen, r); + } + } + } + + #endregion + + #region RenderDotMarker + + private void RenderDotMarker(Graphics g, + Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + Image marker = pstyle.GetPointMarkerImage(); + + if (marker != null) + { + g.DrawImage(marker, bounds); + } + else + { + marker = chartXy.GetPointMarker(g, pstyle.Type, pstyle.PointCount, + bounds.Size, pstyle.Rotation, pstyle.Background, + pstyle.BorderColor, pstyle.BorderWidth); + + if (marker != null) + { + // Make allowances for the fact that GetPointMarker() adjusts the + // size and pos of the image to allow for better anti-aliasing + + bounds.X--; + bounds.Y--; + + g.DrawImageUnscaled(marker, bounds); + } + else + { + RenderDefaultMarker(g, bounds, sstyle); + } + } + } + + #endregion + + #region RenderLineMarker + + private void RenderLineMarker(Graphics g, + Rectangle bounds, ChartXy chartXy, ChartSeriesVisualStyle sstyle) + { + ChartLineDisplayMode mode = GetLineDisplayMode(chartXy); + + int n = bounds.Height / 2; + + using (Pen pen = new Pen(GetLegendItemColor())) + { + g.DrawLine(pen, + new Point(bounds.X, bounds.Y + n), + new Point(bounds.Right - 1, bounds.Y + n)); + } + + if ((mode & ChartLineDisplayMode.DisplayPoints) == ChartLineDisplayMode.DisplayPoints) + { + n = Math.Min(bounds.Height, bounds.Width); + n = (int)Math.Ceiling((double)n / 2); + + if (n % 2 == 0) + n++; + + Rectangle r = bounds; + + r.X += ((r.Width - n) / 2); + r.Y += ((r.Height - n) / 2); + + r.Width = n; + r.Height = n; + + PointMarkerVisualStyle pstyle = sstyle.MarkerVisualStyle; + + Image marker2 = chartXy.GetPointMarker(g, pstyle.Type, pstyle.PointCount, + r.Size, 0, pstyle.Background, pstyle.BorderColor, pstyle.BorderWidth > 0 ? 1 : 0); + + if (marker2 != null) + { + // Make allowances for the fact that GetPointMarker() adjusts the + // size and pos of the image to allow for better anti-aliasing + + r.X--; + r.Y--; + + g.DrawImageUnscaled(marker2, r); + } + else + { + RenderDefaultMarker(g, bounds, sstyle); + } + } + } + + #endregion + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartSeries copy = new ChartSeries(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartSeries c = copy as ChartSeries; + + if (c != null) + { + base.CopyTo(c); + + c.AreaBaseValue = AreaBaseValue; + + c.AxisX = AxisX; + c.AxisY = AxisY; + + c.BarFillRange = BarFillRange; + c.BarLabelPosition = BarLabelPosition; + c.BarShadingEnabled = BarShadingEnabled; + c.BarWidthRatio = BarWidthRatio; + + c.BubbleIntensityMode = BubbleIntensityMode; + c.BubbleMaxPercentage = BubbleMaxPercentage; + c.BubbleMinSize = BubbleMinSize; + c.BubbleScaleFactor = BubbleScaleFactor; + c.BubbleSizeMode = BubbleSizeMode; + + foreach (ChartIndicator ci in ChartIndicators) + c.ChartIndicators.Add((ChartIndicator)ci.Copy()); + + c.ChartLineAreaDisplayMode = ChartLineAreaDisplayMode; + c.ChartLineDisplayMode = ChartLineDisplayMode; + + c.ChartSeriesVisualStyle = + (_ChartSeriesVisualStyle != null) ? _ChartSeriesVisualStyle.Copy() : null; + + c.ConvexHullDisplayMode = ConvexHullDisplayMode; + + c.CrosshairEnabled = CrosshairEnabled; + c.CrosshairHighlightPoints = CrosshairHighlightPoints; + c.CrosshairShowLabels = CrosshairShowLabels; + + foreach (DataLabel dl in DataLabels) + c.DataLabels.Add((DataLabel)dl.Copy()); + + c.DataLabelVisualStyle = + (_DataLabelVisualStyle != null) ? _DataLabelVisualStyle.Copy() : null; + + c.DisplayLinePointsOnTop = DisplayLinePointsOnTop; + c.DotPlotIndexValue = DotPlotIndexValue; + + c.EmptyValues = EmptyValues; + c.EnableEmptyValues = EnableEmptyValues; + + c.GroupId = GroupId; + c.HiLoBarType = HiLoBarType; + c.CrosshairHighlightSinglePoint = CrosshairHighlightSinglePoint; + + c.PointLabelDisplayMode = PointLabelDisplayMode; + c.PointLabelMinDistance = PointLabelMinDistance; + c.PointLabelSkip = PointLabelSkip; + + c.ScaleTypeX = ScaleTypeX; + c.ScaleTypeY = ScaleTypeY; + + foreach (SeriesPoint sp in SeriesPoints) + c.SeriesPoints.Add(sp.Copy()); + + c.SeriesType = SeriesType; + + c.ShowEmptyLines = ShowEmptyLines; + c.ShowEmptyPoints = ShowEmptyPoints; + c.ShowHiLoBarMedianLines = ShowHiLoBarMedianLines; + c.ShowOriginValueLabels = ShowOriginValueLabels; + c.StackQualitativePoints = StackQualitativePoints; + + c.StepLines = StepLines; + c.StepLineMode = StepLineMode; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartSeries"; + + sec.AddStartElement(serialName); + } + + sec.AddDataValue("AreaBaseValue", AreaBaseValue, null); + + if (AxisX != null && string.IsNullOrEmpty(AxisX.Name) == false) + sec.AddValue("AxisX", AxisX.Name); + + if (AxisY != null && string.IsNullOrEmpty(AxisY.Name) == false) + sec.AddValue("AxisY", AxisY.Name); + + sec.AddValue("BarFillRange", BarFillRange, BarFillRange.NotSet); + sec.AddValue("BarLabelPosition", BarLabelPosition, BarLabelPosition.NotSet); + sec.AddValue("BarShadingEnabled", BarShadingEnabled, Tbool.NotSet); + sec.AddValue("BarWidthRatio", BarWidthRatio, 0d); + + sec.AddValue("BubbleIntensityMode", BubbleIntensityMode, BubbleIntensityMode.NotSet); + sec.AddValue("BubbleMaxPercentage", BubbleMaxPercentage, 0.25d); + sec.AddValue("BubbleMinSize", BubbleMinSize, 4); + sec.AddValue("BubbleScaleFactor", BubbleScaleFactor, 1.0d); + sec.AddValue("BubbleSizeMode", BubbleSizeMode, BubbleSizeMode.NotSet); + + if (_ChartIndicators != null && _ChartIndicators.Count > 0) + { + sec.AddStartElement("ChartIndicators count=\"" + _ChartIndicators.Count + "\""); + + foreach (ChartIndicator ci in _ChartIndicators) + sec.AddElement(ci.GetSerialData("")); + + sec.AddEndElement("ChartIndicators"); + } + + sec.AddValue("ChartLineAreaDisplayMode", ChartLineAreaDisplayMode, ChartLineAreaDisplayMode.NotSet); + sec.AddValue("ChartLineDisplayMode", ChartLineDisplayMode, ChartLineDisplayMode.NotSet); + + if (_ChartSeriesVisualStyle != null) + sec.AddElement(_ChartSeriesVisualStyle.GetSerialData("ChartSeriesVisualStyle")); + + sec.AddValue("ConvexHullDisplayMode", ConvexHullDisplayMode, ConvexHullDisplayMode.NotSet); + + sec.AddValue("CrosshairEnabled", CrosshairEnabled, Tbool.NotSet); + sec.AddValue("CrosshairHighlightPoints", CrosshairHighlightPoints, Tbool.NotSet); + sec.AddValue("CrosshairHighlightSinglePoint", CrosshairHighlightSinglePoint, Tbool.NotSet); + sec.AddValue("CrosshairShowLabels", CrosshairShowLabels, Tbool.NotSet); + + if (_DataLabels != null && _DataLabels.Count > 0) + { + sec.AddStartElement("DataLabels count=\"" + _DataLabels.Count + "\""); + + foreach (DataLabel dl in _DataLabels) + sec.AddElement(dl.GetSerialData("")); + + sec.AddEndElement("DataLabels"); + } + + if (_DataLabelVisualStyle != null) + sec.AddElement(_DataLabelVisualStyle.GetSerialData("DataLabelVisualStyle")); + + sec.AddValue("DisplayLinePointsOnTop", DisplayLinePointsOnTop, true); + sec.AddValue("DotPlotIndexValue", DotPlotIndexValue, 1.0d); + + if (_EmptyValues != null && _EmptyValues.Length > 0) + { + sec.AddStartElement("EmptyValues count=\"" + _EmptyValues.Length + "\""); + + foreach (object value in _EmptyValues) + sec.AddValue("EmptyValue", value); + + sec.AddEndElement("EmptyValues"); + } + + sec.AddValue("EnableEmptyValues", EnableEmptyValues, false); + + sec.AddValue("GroupId", GroupId, 0); + sec.AddValue("HiLoBarType", HiLoBarType, HiLoBarType.Box); + + sec.AddValue("PointLabelDisplayMode", PointLabelDisplayMode, PointLabelDisplayMode.NotSet); + sec.AddValue("PointLabelMinDistance", PointLabelMinDistance, 0); + sec.AddValue("PointLabelSkip", PointLabelSkip, 0); + + sec.AddValue("ScaleTypeX", ScaleTypeX, ScaleType.NotSet); + sec.AddValue("ScaleTypeY", ScaleTypeY, ScaleType.NotSet); + + if (_SeriesPoints != null && _SeriesPoints.Count > 0) + { + sec.AddStartElement("SeriesPoints count=\"" + _SeriesPoints.Count + "\""); + + foreach (SeriesPoint sp in _SeriesPoints) + sec.AddElement(sp.GetSerialData()); + + sec.AddEndElement("SeriesPoints"); + } + + sec.AddValue("SeriesType", SeriesType, SeriesType.Point); + + sec.AddValue("ShowEmptyLines", ShowEmptyLines, false); + sec.AddValue("ShowEmptyPoints", ShowEmptyPoints, false); + sec.AddValue("ShowHiLoBarMedianLines", ShowHiLoBarMedianLines, false); + sec.AddValue("ShowOriginValueLabels", ShowOriginValueLabels, true); + + sec.AddValue("StackQualitativePoints", StackQualitativePoints, true); + + sec.AddValue("StepLines", StepLines, StepLines.NotSet); + sec.AddValue("StepLineMode", StepLineMode, StepLineMode.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + ChartXy chartXy = Parent as ChartXy; + + switch (se.Name) + { + case "AreaBaseValue": + AreaBaseValue = se.DataValue; + break; + + case "AxisX": + if (chartXy != null) + AxisX = GetAncillaryAxis(chartXy.AncillaryAxesX, se.GetValueString()); + break; + + case "AxisY": + if (chartXy != null) + AxisY = GetAncillaryAxis(chartXy.AncillaryAxesY, se.GetValueString()); + break; + + case "BarFillRange": + BarFillRange = (BarFillRange)se.GetValueEnum(typeof(BarFillRange)); + break; + + case "BarLabelPosition": + BarLabelPosition = (BarLabelPosition)se.GetValueEnum(typeof(BarLabelPosition)); + break; + + case "BarShadingEnabled": + BarShadingEnabled = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "BarWidthRatio": + BarWidthRatio = double.Parse(se.StringValue); + break; + + case "BubbleIntensityMode": + BubbleIntensityMode = (BubbleIntensityMode)se.GetValueEnum(typeof(BubbleIntensityMode)); + break; + + case "BubbleMaxPercentage": + BubbleMaxPercentage = double.Parse(se.StringValue); + break; + + case "BubbleMinSize": + BubbleMinSize = int.Parse(se.StringValue); + break; + + case "BubbleScaleFactor": + BubbleScaleFactor = double.Parse(se.StringValue); + break; + + case "BubbleSizeMode": + BubbleSizeMode = (BubbleSizeMode)se.GetValueEnum(typeof(BubbleSizeMode)); + break; + + case "ChartLineAreaDisplayMode": + ChartLineAreaDisplayMode = (ChartLineAreaDisplayMode)se.GetValueEnum(typeof(ChartLineAreaDisplayMode)); + break; + + case "ChartLineDisplayMode": + ChartLineDisplayMode = (ChartLineDisplayMode)se.GetValueEnum(typeof(ChartLineDisplayMode)); + break; + + case "ConvexHullDisplayMode": + ConvexHullDisplayMode = (ConvexHullDisplayMode)se.GetValueEnum(typeof(ConvexHullDisplayMode)); + break; + + case "CrosshairEnabled": + CrosshairEnabled = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "CrosshairHighlightPoints": + CrosshairHighlightPoints = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "CrosshairHighlightSinglePoint": + CrosshairHighlightSinglePoint = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "CrosshairShowLabels": + CrosshairShowLabels = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "DisplayLinePointsOnTop": + DisplayLinePointsOnTop = bool.Parse(se.StringValue); + break; + + case "DotPlotIndexValue": + DotPlotIndexValue = double.Parse(se.StringValue); + break; + + case "EmptyValues": + EmptyValues[se.ValueIndex] = se.DataValue; + break; + + case "EnableEmptyValues": + EnableEmptyValues = bool.Parse(se.StringValue); + break; + + case "GroupId": + GroupId = int.Parse(se.StringValue); + break; + + case "HiLoBarType": + HiLoBarType = (HiLoBarType)se.GetValueEnum(typeof(HiLoBarType)); + break; + + case "PointLabelDisplayMode": + PointLabelDisplayMode = (PointLabelDisplayMode)se.GetValueEnum(typeof(PointLabelDisplayMode)); + break; + + case "PointLabelMinDistance": + PointLabelMinDistance = int.Parse(se.StringValue); + break; + + case "PointLabelSkip": + PointLabelSkip = int.Parse(se.StringValue); + break; + + case "ScaleTypeX": + ScaleTypeX = (ScaleType)se.GetValueEnum(typeof(ScaleType)); + break; + + case "ScaleTypeY": + ScaleTypeY = (ScaleType)se.GetValueEnum(typeof(ScaleType)); + break; + + case "SeriesType": + SeriesType = (SeriesType)se.GetValueEnum(typeof(SeriesType)); + break; + + case "ShowEmptyLines": + ShowEmptyLines = bool.Parse(se.StringValue); + break; + + case "ShowEmptyPoints": + ShowEmptyPoints = bool.Parse(se.StringValue); + break; + + case "ShowHiLoBarMedianLines": + ShowHiLoBarMedianLines = bool.Parse(se.StringValue); + break; + + case "ShowOriginValueLabels": + ShowOriginValueLabels = bool.Parse(se.StringValue); + break; + + case "StackQualitativePoints": + StackQualitativePoints = bool.Parse(se.StringValue); + break; + + case "StepLines": + StepLines = (StepLines)se.GetValueEnum(typeof(StepLines)); + break; + + case "StepLineMode": + StepLineMode = (StepLineMode)se.GetValueEnum(typeof(StepLineMode)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #region GetAncillaryAxis + + private ChartAxis GetAncillaryAxis(ChartAxesCollection axes, string name) + { + foreach (ChartAxis axis in axes) + { + if (name.Equals(axis.Name) == true) + return (axis); + } + + return (null); + } + + #endregion + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartIndicators": + sec.PutSerialData(this); + break; + + case "ChartSeriesVisualStyle": + sec.PutSerialData(ChartSeriesVisualStyle); + break; + + case "DataLabel": + sec.PutSerialData(DataLabels[se.ValueIndex]); + break; + + case "DataLabels": + sec.PutSerialData(this); + break; + + case "DataLabelVisualStyle": + sec.PutSerialData(DataLabelVisualStyle); + break; + + case "EmptyValues": + if (se.ArrayCount > 0) + { + EmptyValues = new object[se.ArrayCount]; + + sec.PutSerialData(this); + } + break; + + case "RegressionLine": + string rname = se.Sec.GetItemValue("Name"); + + RegressionLine reg = ChartIndicators[rname] as RegressionLine; + + if (reg != null) + ChartIndicators.Remove(reg); + + reg = new RegressionLine(rname); + + if (reg != null) + { + sec.PutSerialData(reg); + + ChartIndicators.Add(reg); + } + break; + + case "SeriesPoints": + if (se.ArrayCount > 0) + { + SeriesPoints = new SeriesPointCollection(); + + sec.PutSerialData(this); + } + break; + + case "SeriesPoint": + SeriesPoint sp = new SeriesPoint(); + + sec.PutSerialData(sp); + + SeriesPoints.Add(sp); + break; + + case "TrendLine": + string tname = se.Sec.GetItemValue("Name"); + + TrendLine trend = ChartIndicators[tname] as TrendLine; + + if (trend != null) + ChartIndicators.Remove(trend); + + trend = new TrendLine(tname); + + if (trend != null) + { + sec.PutSerialData(trend); + + ChartIndicators.Add(trend); + } + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region Series States + + [Flags] + private enum States : uint + { + FilterIgnoreMatchCase = (1U << 0), + + CheckedInLegend = (1U << 1), + ShowInLegend = (1U << 2), + ShowInParentLegend = (1U << 3), + ShowCheckBoxInLegend = (1U << 4), + ShowMarkerInLegend = (1U << 5), + + IsSorted = (1U << 6), + IsRotated = (1U << 7), + + StackQualitativePoints = (1U << 8), + DisplayLinePointsOnTop = (1U << 9), + + EnableEmptyValues = (1U << 10), + ShowEmptyLines = (1U << 11), + ShowEmptyPoints = (1U << 12), + ShowOriginValueLabels = (1U << 13), + ShowHiLoBarMedianLines = (1U << 14), + + NeedToUpdateBindings = (1U << 15), + + IsInnerRingSeries = (1U << 16), + IsOuterRingSeries = (1U << 17), + + IsOffset = (1U << 18), + IsDetached = (1U << 19), + + ShowInnerRingsEx = (1U << 20), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + AxisX = null; + AxisY = null; + ChartIndicators = null; + ChartLegendItemVisualStyles = null; + ChartSeriesVisualStyle = null; + DataLabels = null; + DataLabelVisualStyle = null; + SeriesPoints = null; + + base.Dispose(); + } + + #endregion + } + + #region SortedSeriesPoints + + public class SortedSeriesPoints + { + #region Private variables + + private ChartSeries _ChartSeries; + private SeriesPointCollection _Spc; + + private int[] _IndexArray; + private int[] _CountArray; + + private int _SeriesLayoutCount; + + private double _Slope = double.NaN; + private double _Intercept = double.NaN; + + private bool _SlopeCalculated; + private int _SlopeIndex; + + #endregion + + public SortedSeriesPoints(ChartSeries series, bool sortPoints) + { + _ChartSeries = series; + _Spc = series.SeriesPoints; + + if (sortPoints == true) + _IndexArray = CreateIndexArray(_Spc); + } + + #region Public properties + + #region Count + + public int Count + { + get + { + if (_IndexArray != null) + return (_IndexArray.Length); + + return (_Spc.Count); + } + } + + #endregion + + #region Indexer[int] + + public SeriesPoint this[int index] + { + get + { + if (_IndexArray != null) + index = _IndexArray[index]; + + return (_Spc[index]); + } + } + + #endregion + + #region IsSorted + + public bool IsSorted + { + get { return (_ChartSeries.IsSorted); } + } + + #endregion + + #region SeriesLayoutCount + + public int SeriesLayoutCount + { + get { return (_SeriesLayoutCount); } + + set + { + if (value != _SeriesLayoutCount) + _SeriesLayoutCount = value; + } + } + + #endregion + + #endregion + + #region Internal properties + + #region CountArray + + internal int[] CountArray + { + get { return (_CountArray); } + set { _CountArray = value; } + } + + #endregion + + #region IndexArray + + internal int[] IndexArray + { + get { return (_IndexArray); } + set { _IndexArray = value; } + } + + #endregion + + #region Intercept + + internal double Intercept + { + get + { + if (_SlopeCalculated == false) + CalcSeriesSlope(); + + return (_Intercept); + } + + set { _Intercept = value; } + } + + #endregion + + #region Slope + + internal double Slope + { + get + { + if (_SlopeCalculated == false) + CalcSeriesSlope(); + + return (_Slope); + } + + set { _Slope = value; } + } + + #endregion + + #region SlopeIndex + + internal int SlopeIndex + { + get { return (_SlopeIndex); } + + set + { + if (_SlopeIndex != value) + { + _SlopeIndex = value; + _SlopeCalculated = false; + } + } + } + + #endregion + + #endregion + + #region CreateIndexArray + + private int[] CreateIndexArray(SeriesPointCollection spc) + { + int[] indexArray = new int[_Spc.Count]; + object[] keyArray = new object[_Spc.Count]; + + for (int i = 0; i < _Spc.Count; i++) + { + indexArray[i] = i; + keyArray[i] = _Spc[i].ValueX; + } + + Array.Sort(keyArray, indexArray); + + return (indexArray); + } + + #endregion + + #region SearchX + + public int SearchX(object okey) + { + ChartXy chartXy = _ChartSeries.Parent as ChartXy; + + if (IsSorted == true) + { + int min = 0; + int max = Count - 1; + + while (min <= max) + { + int mid = (min + max) / 2; + + int cmp = chartXy.DataCompare(okey, this[mid].ValueX); + + if (cmp > 0) + min = mid + 1; + + else if (cmp < 0) + max = mid - 1; + + else + return (mid); + } + + return (-((min > 0) ? min - 1 : 0)); + } + else + { + for (int i = 0; i < Count; i++) + { + if (chartXy.DataCompare(okey, this[i].ValueX) == 0) + return (i); + } + + return (-1); + } + } + + #endregion + + #region SearchY + + public int SearchY(object okey) + { + ChartXy chartXy = _ChartSeries.Parent as ChartXy; + + for (int i = 0; i < _Spc.Count; i++) + { + if (_Spc[i].ValueY[0].Equals(okey)) + return (i); + } + + return (0); + } + + #endregion + + #region GetQualitativeXIndex + + internal int GetQualitativeXIndex(object okey) + { + int index; + + if (okey is string) + index = _ChartSeries.QualitativeXValues.IndexOf((string)okey); + else + index = Convert.ToInt32(okey); + + return (index); + } + + #endregion + + #region GetQualitativeYIndex + + internal int GetQualitativeYIndex(object okey) + { + int index; + + if (okey is string) + index = _ChartSeries.QualitativeYValues.IndexOf((string)okey); + else + index = Convert.ToInt32(okey); + + return (index); + } + + #endregion + + #region CalcSeriesSlope + + private void CalcSeriesSlope() + { + ChartXy chartXy = _ChartSeries.Parent as ChartXy; + + if (chartXy != null) + { + ChartAxis axisX = _ChartSeries.AxisX ?? chartXy.AxisX; + ChartAxis axisY = _ChartSeries.AxisY ?? chartXy.AxisY; + + if (_ChartSeries.ActualScaleTypeX != ScaleType.NotSet) + { + int n = Count; + + double sumX = 0; + double sumY = 0; + double sumXx = 0; + double sumXy = 0; + + int nn = 0; + + for (int i = 0; i < n; i++) + { + SeriesPoint sp = this[i]; + + if (sp.IsEmpty == false && (sp.ValueY.Length > _SlopeIndex)) + { + nn++; + + double x; + + switch (_ChartSeries.ActualScaleTypeX) + { + case ScaleType.DateTime: + x = chartXy.GetDateTimePointValue(axisX, + axisX.TickmarkLayout, (DateTime)sp.ValueX, (DateTime)_ChartSeries.MinValueX); + break; + + case ScaleType.Qualitative: + x = _ChartSeries.QualitativeXValues.IndexOf(sp.ValueX); + break; + + default: + x = Convert.ToDouble(sp.ValueX); + break; + } + + double y; + + switch (_ChartSeries.ActualScaleTypeY) + { + case ScaleType.DateTime: + y = chartXy.GetDateTimePointValue(axisY, axisY.TickmarkLayout, (DateTime)sp.ValueY[_SlopeIndex]); + break; + + case ScaleType.Qualitative: + y = _ChartSeries.QualitativeYValues.IndexOf(sp.ValueY[_SlopeIndex]); + break; + + default: + y = Convert.ToDouble(sp.ValueY[_SlopeIndex]); + break; + } + + sumX += x; + sumY += y; + + sumXx += (x * x); + sumXy += (x * y); + } + } + + double a = nn * sumXy; + double b = sumX * sumY; + double c = nn * sumXx; + double d = sumX * sumX; + + double m = (a - b) / (c - d); + double yi = (sumY - (m * sumX)) / nn; + + Slope = m; + Intercept = yi; + + _SlopeCalculated = true; + } + } + } + + #endregion + + #region GetSeriesPoint + + internal SeriesPoint GetSeriesPoint(object key) + { + if (Count > 0) + { + int index; + + if (this[0].IsQuantitativeXValue == true) + index = SearchX(key); + else + index = GetQualitativeXIndex(key) - 1; + + if (index < 0 && IsSorted == true) + index = -index; + + if ((uint)index < Count) + return (this[index]); + } + + return (null); + } + + #endregion + } + + #endregion + + #region PointData + + public class PointData + { + public List Points; + public List SeriesPoints; + } + + #endregion + + #region BubblePlotData + + internal class BubblePlotData + { + public double MinSize; + public double MaxSize; + + public double TotalSize; + + public double MinIntensity; + public double MaxIntensity; + + public void Clear() + { + MinSize = double.MaxValue; + MaxSize = double.MinValue; + + MinIntensity = double.MaxValue; + MaxIntensity = double.MinValue; + + TotalSize = 0; + } + } + + #endregion + + #region BarRenderData + + internal class BarRenderData + { + public ChartAxis Axis; + public ChartXy ChartXy; + + public BarFillRange FillRange; + public bool BarShading; + + public Point Spt; + public SeriesPoint Sp; + + public ChartSeriesVisualStyle SeriesStyle; + + public BarRenderData(ChartXy chartXy, ChartAxis axis) + { + ChartXy = chartXy; + Axis = axis; + } + } + + #endregion + + #region HiLoRenderData + + public class HiLoRenderData + { + #region Private variables + + private ChartAxis _Axis; + private ChartXy _ChartXy; + + private Point _Spt; + private SeriesPoint _Sp; + private int _Index; + + private ChartSeriesVisualStyle _SeriesStyle; + + private int[] _Value; + + private bool _IsAlternate; + private int _EndDelta; + + #endregion + + public HiLoRenderData(ChartXy chartXy, ChartAxis axis) + { + _ChartXy = chartXy; + _Axis = axis; + } + + #region Public properties + + #region AlternateStyle + + /// + /// Gets the alternate segment style used when Open/Close values are reversed. + /// + public HiLoBarSegmentStyle AlternateStyle + { + get { return (SeriesStyle.HiLoBarVisualStyle.AlternateSegmentStyle); } + } + + #endregion + + #region DefaultStyle + + /// + /// Gets the default segment style used when Open/Close values are not reversed. + /// + public HiLoBarSegmentStyle DefaultStyle + { + get { return (SeriesStyle.HiLoBarVisualStyle.DefaultSegmentStyle); } + } + + #endregion + + #region IsAlternate + + /// + /// Gets whether the segment is to be render as 'Alternate'. + /// + public bool IsAlternate + { + get { return (_IsAlternate); } + internal set { _IsAlternate = value; } + } + + #endregion + + #region SeriesStyle + + /// + /// Gets the associated series visual style. + /// + public ChartSeriesVisualStyle SeriesStyle + { + get { return (_SeriesStyle); } + internal set { _SeriesStyle = value; } + } + + #endregion + + #region Value + + /// + /// Gets an array of specified HiLo coordinate data values (x or y, + /// depending upon the bar orientation). The values are specified + /// in [High=0, Low=1, Close=2, Open=3, Median=4] order, followed + /// by any 'extra' user supplied bar values. + /// + public int[] Value + { + get { return (_Value); } + internal set { _Value = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region Axis + + internal ChartAxis Axis + { + get { return (_Axis); } + set { _Axis = value; } + } + + #endregion + + #region ChartXy + + internal ChartXy ChartXy + { + get { return (_ChartXy); } + set { _ChartXy = value; } + } + + #endregion + + #region EndDelta + + public int EndDelta + { + get { return (_EndDelta); } + set { _EndDelta = value; } + } + + #endregion + + #region Index + + internal int Index + { + get { return (_Index); } + set { _Index = value; } + } + + #endregion + + #region Sp + + internal SeriesPoint Sp + { + get { return (_Sp); } + set { _Sp = value; } + } + + #endregion + + #region Spt + + internal Point Spt + { + get { return (_Spt); } + set { _Spt = value; } + } + + #endregion + + #endregion + } + + #endregion + + #region enums + + #region BarLabelPosition + + /// + /// Specifies the position for Bar series labels. + /// + public enum BarLabelPosition + { + /// + /// Not set (default is Center). + /// + NotSet = -1, + + /// + /// Labels will be positioned in the center of the bar. + /// + Center, + + /// + /// Labels will be positioned outside the bar, relative to its origin. + /// + Near, + + /// + /// Labels will be positioned inside the bar, relative to its origin. + /// + NearInside, + + /// + /// Labels will be positioned outside the bar, opposite to its origin. + /// + Far, + + /// + /// Labels will be positioned inside the bar, opposite to its origin. + /// + FarInside, + } + + #endregion + + #region BarSegment + + public enum BarSegment + { + /// + /// Top portion of Vertical bar (full area). + /// + Top, + + /// + /// Partial Top area of Vertical bar. + /// + TopPartial, + + /// + /// Bottom portion of Vertical bar (full area). + /// + Bottom, + + /// + /// Partial Bottom area of Vertical bar. + /// + BottomPartial, + + /// + /// Left portion of Horizontal bar (full area). + /// + Left, + + /// + /// Partial Left area of Horizontal bar. + /// + LeftPartial, + + /// + /// Right portion of Horizontal bar (full area). + /// + Right, + + /// + /// Partial Right area of Horizontal bar. + /// + RightPartial, + } + + #endregion + + #region ConvexHullDisplayMode + + /// + /// Specifies the ConvexHull display mode + /// + [Flags] + public enum ConvexHullDisplayMode + { + /// + /// Not set (default is None). + /// + NotSet = 0, + + /// + /// No Convex Hull processing will take place. + /// + None = (1 << 0), + + /// + /// Convex Hull border will be displayed. + /// + DisplayBorder = (1 << 1), + + /// + /// Convex Hull background area will be displayed. + /// + DisplayBackground = (1 << 2), + } + + #endregion + + #region PointLabelDisplayMode + + /// + /// Specifies which PointLabels are to be displayed + /// + [Flags] + public enum PointLabelDisplayMode + { + /// + /// Not set (default is None). + /// + NotSet, + + /// + /// No labels will be displayed. + /// + None = (1 << 0), + + /// + /// All series points will display a label. + /// + AllSeriesPoints = (1 << 1), + + /// + /// User defined DataLabels will be displayed. + /// + DataLabels = (1 << 2), + + /// + /// Minimum 'X' Value label will be displayed. + /// + MinValueX = (1 << 3), + + /// + /// Minimum 'Y' Value label will be displayed. + /// + MinValueY = (1 << 4), + + /// + /// Maximum 'X' Value label will be displayed. + /// + MaxValueX = (1 << 5), + + /// + /// Maximum 'Y' Value label will be displayed. + /// + MaxValueY = (1 << 6), + } + + #endregion + + #region StepLineMode + + /// + /// Specifies the mode used to render "Step Lines" in + /// a given Line series. + /// + public enum StepLineMode + { + /// + /// Not set (default is HorizontalThenVertical). + /// + NotSet = -1, + + /// + /// No Step Lines will be rendered. + /// + None, + + /// + /// Step lines will be displayed between consecutive + /// series points, by first displaying the horizontal step + /// line, followed by the connecting vertical step line. + /// + HorizontalThenVertical, + + /// + /// Step lines will be displayed between consecutive + /// series points, by first displaying the vertical step + /// line, followed by the connecting horizontal step line. + /// + VerticalThenHorizontal, + + /// + /// Step lines will be displayed between consecutive + /// series points, by first displaying the midPoint horizontal + /// step line, followed by the connecting vertical step line. + /// + MidPoint, + } + + #endregion + + #region StepLines + + /// + /// Specifies the mode used to render "Stepped Lines" in + /// a given Line series. + /// + public enum StepLines + { + /// + /// Not set (default is StepHv). + /// + NotSet = -1, + + /// + /// No step lines will be displayed. + /// + None, + + /// + /// Horizontal step lines will be displayed. + /// + Horizontal, + + /// + /// Vertical step lines will be displayed. + /// + Vertical, + + /// + /// Both horizontal and vertical step lines will be displayed. + /// + Both, + } + + #endregion + + #region ScaleType + + /// + /// Specifies the scale type for the series points + /// + public enum ScaleType + { + /// + /// ScaleType is NotSet (default is 'Auto'). + /// + NotSet, + + /// + /// ScaleType is Automatic. Scale type will be determined + /// by the underlying, assigned data. + /// + Auto, + + /// + /// DateTime data scale. Points will be treated as + /// DateTime values and will be shown as such on the axis. + /// + DateTime, + + /// + /// Numerical data scale. Points will be treated as + /// numerical values and will be shown on the axis as numbers. + /// + Quantitative, + + /// + /// Qualitative data scale. Points will be treated as + /// qualitative values and will be shown on the axis as text. + /// + Qualitative, + + } + + #endregion + + #region HiLoBarType + + /// + /// Specifies the HiloBar series display type. + /// + public enum HiLoBarType + { + /// + /// Box Plot display. Display is identical to 'Candle' except: + /// 1. Median separated segments are separately rendered using both + /// default and alternate box backgrounds. + /// 2. UseAlternateSegmentStyle defaults to false. + /// + Box, + + /// + /// Candle Plot display. Display is identical to 'Box' except: + /// 1. Mmedian separated segments are both rendered using either + /// the default or alternate box background. + /// 2. UseAlternateSegmentStyle defaults to true. + /// + Candle, + + /// + /// Line plot display. + /// + Line, + } + + #endregion + + #region HiLoBarSegment + + public enum HiLoBarSegment + { + /// + /// Box (Box plot). + /// + Box, + + /// + /// High whisker (Box, Candle, Line). + /// + HighWhisker, + + /// + /// High whisker cap (Box, Candle, Line). + /// + HighWhiskerCap, + + /// + /// Low whisker (Box, Candle, Line). + /// + LowWhisker, + + /// + /// Low whisker cap (Box, Candle, Line). + /// + LowWhiskerCap, + + /// + /// Open whisker (Line plot). + /// + OpenWhisker, + + /// + /// Close whisker (Line Plot). + /// + CloseWhisker, + + /// + /// Center line (Line plot). + /// + CenterLine, + + /// + /// Full range (Line plot). + /// + FullRange, + + /// + /// Median line (Box, Candle, Line). + /// + MedianLine, + + /// + /// Bar shading (Box, Candle). + /// + BarShading, + } + + #endregion + + #endregion + + #region AxisTypeConverter + + /// + /// AxisTypeConverter + /// + public class AxisTypeConverter : TypeConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + ChartAxis axis = value as ChartAxis; + + if (axis != null) + { + if (string.IsNullOrEmpty(axis.Name) == false) + return (axis.Name); + + return ("No Axis Name"); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartTickmarks.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartTickmarks.cs new file mode 100644 index 00000000..41e7c6ee --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartTickmarks.cs @@ -0,0 +1,2740 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + #region MajorTickmarks + + #region MajorTickmarksX + + /// + /// Represents a chart MajorTickmark on the X-Axis. + /// + public class MajorTickmarksX : MajorTickmarks + { + public MajorTickmarksX() + : base(AxisOrientation.X) + { + } + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + ChartAxis chartAxis = Parent as ChartAxis; + ChartTickmarkVisualStyle tstyle = EffectiveStyle; + + Rectangle bounds = Rectangle.Empty; + + MeasureTickmarks(layoutInfo, chartAxis); + + if (TickmarkLayout.MajorCount > 0) + { + bounds = MeasureTickmarkLabels(layoutInfo, chartAxis); + + float angle = GetLabelAngle(); + + if (angle == 0) + CullOverlappingLabels(); + } + + BoundsRelative = bounds; + } + + #region MeasureTickmarks + + private void MeasureTickmarks(ChartLayoutInfo layoutInfo, ChartAxis chartAxis) + { + TickmarkLayout layout = TickmarkLayout; + + if (layout.MajorCount > 0) + { + Graphics g = layoutInfo.Graphics; + Rectangle bounds = layoutInfo.LayoutBounds; + + layout.TickmarkStart = GetStartIndex(); + layout.TickmarkEnd = layout.TickmarkStart + (int)Math.Ceiling((bounds.Width + layout.MarginOffset) / layout.MajorInterval) + 3; + + UpdateTickmarkTicks(g, chartAxis, bounds, layout); + + ArrangeTickmarks(); + } + } + + #endregion + + #region MeasureTickmarkLabels + + private Rectangle MeasureTickmarkLabels( + ChartLayoutInfo layoutInfo, ChartAxis chartAxis) + { + ChartTickmarkVisualStyle tstyle = EffectiveStyle; + + int labelHeight = GetTotalLabelHeight(); + int tickmarkHeight = Dpi.Height(GetMaxTickmarkLength(chartAxis, false)); + + if (tickmarkHeight == 0) + tickmarkHeight = Dpi.Height4; + + Rectangle bounds = layoutInfo.LayoutBounds; + bounds.Height = (labelHeight + tickmarkHeight); + + ChartXy chartXy = chartAxis.Parent as ChartXy; + + if (chartXy.DropShadowDisplayed == true) + bounds.Width -= 3; + + Rectangle r = bounds; + + if (chartAxis.GetAxisAlignment() == AxisAlignment.Far) + { + LabelBounds = new Rectangle(r.X, r.Y, r.Width, labelHeight); + + r.Y += labelHeight; + r.Height -= labelHeight; + + TickmarkBounds = r; + } + else + { + r.Y = layoutInfo.LayoutBounds.Bottom - labelHeight; + bounds.Y = r.Y; + + LabelBounds = new Rectangle(r.X, r.Y, r.Width, labelHeight); + + r.Y -= tickmarkHeight; + r.Height = tickmarkHeight; + + TickmarkBounds = r; + } + + if (chartAxis.EdgeAxis == false) + bounds.Height += Dpi.Height(GetMaxTickmarkLength(chartAxis, true)) + 2; + + return (bounds); + } + + #endregion + + #endregion + + #region ArrangeTickmarks + + protected override void ArrangeTickmarks() + { + TickmarkLayout layout = TickmarkLayout; + + if (layout.Ticks != null) + { + ChartAxis chartAxis = Parent as ChartAxis; + + Rectangle tmBounds = TickmarkBounds; + Rectangle lbounds = LabelBounds; + + AxisAlignment axisAlignment = chartAxis.GetAxisAlignment(); + + Point tickPoint = new Point(0, + (axisAlignment == AxisAlignment.Near) ? tmBounds.Y : tmBounds.Bottom + 1); + + float angle = GetLabelAngle(); + + for (int i = layout.TickmarkStart; i < layout.TickmarkEnd; i++) + { + TickmarkTick tick = layout.Ticks[i - layout.TickmarkStart]; + + tickPoint.X = (int)(tmBounds.Location.X + (i * layout.MajorInterval) - layout.MarginOffset); + tick.TickPoint = tickPoint; + + if (tick.Label != null) + { + tick.LabelPoint = tickPoint; + tick.LabelPoint.Y = lbounds.Y; + + int height = LabelBounds.Height; + + if (LabelsAreStaggered == true) + { + double value = GetTickmarkValue(chartAxis, tick); + int n = (int)(Math.Ceiling(value / TickmarkLayout.MajorSpacing)); + + if ((tick.Index % 2) != (axisAlignment == AxisAlignment.Far ? 0 : 1)) + { + height -= MaxLabelSize[0].Height; + tick.LabelPoint.Y += MaxLabelSize[0].Height; + } + else + { + height -= MaxLabelSize[1].Height; + } + } + + if (axisAlignment == AxisAlignment.Far) + tick.LabelPoint.Y += (height - tick.LabelSize.Height); + + if (angle == 0) + tick.LabelPoint.X -= (tick.LabelSize.Width / 2); + } + } + } + } + + #region CullOverlappingLabels + + private void CullOverlappingLabels() + { + TickmarkLayout layout = TickmarkLayout; + + for (int i = layout.TickmarkStart; i < layout.TickmarkEnd; i++) + { + TickmarkTick tick = layout.Ticks[i - layout.TickmarkStart]; + + if (tick.LabelVisible == true) + { + for (int j = i + 1; j < layout.TickmarkEnd; j++) + { + TickmarkTick tick2 = layout.Ticks[j - layout.TickmarkStart]; + + if (tick2.LabelVisible == true) + { + if (tick2.LabelPoint.X < tick.LabelPoint.X + tick.LabelSize.Width - 1) + { + if ((LabelsAreStaggered == false) || + (tick.LabelIndex % 2 == tick2.LabelIndex % 2)) + { + tick2.LabelVisible = false; + } + } + } + } + } + } + } + + #endregion + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + base.RenderOverride(renderInfo); + + Graphics g = renderInfo.Graphics; + + ChartAxis chartAxis = Parent as ChartAxis; + ChartTickmarkVisualStyle tstyle = EffectiveStyle; + + if (CanRenderTickmarks(tstyle) == true) + RenderTickmarks(g, tstyle, chartAxis); + + if (TickmarkLayout.MajorCount > 0) + RenderTickmarkLabels(g, chartAxis); + } + + #region RenderTickmarks + + private void RenderTickmarks(Graphics g, + ChartTickmarkVisualStyle tstyle, ChartAxis chartAxis) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + using (Pen pen = new Pen(tstyle.TickmarkColor, Dpi.Width(tstyle.TickmarkThickness))) + { + int tlen = Dpi.Width(tstyle.TickmarkLength - ((tstyle.TickmarkThickness > 1) ? 0 : 1)); + + AxisAlignment axisAlignment = chartAxis.GetAxisAlignment(); + + Point pt = GetLocalAdjustedPoint(Point.Empty); + + if ((tstyle.TickmarkAlignment == LineAlignment.Center) || + (axisAlignment == AxisAlignment.Far && tstyle.TickmarkAlignment == LineAlignment.Near) || + (axisAlignment == AxisAlignment.Near && tstyle.TickmarkAlignment == LineAlignment.Far)) + { + // Bottom + + RenderMarks(g, pen, chartAxis, pt, 0, tlen, axisAlignment == AxisAlignment.Far); + } + + if ((tstyle.TickmarkAlignment == LineAlignment.Center) || + (axisAlignment == AxisAlignment.Far && tstyle.TickmarkAlignment == LineAlignment.Far) || + (axisAlignment == AxisAlignment.Near && tstyle.TickmarkAlignment == LineAlignment.Near)) + { + // Top + + ChartXy chartXy = chartAxis.Parent as ChartXy; + + if (axisAlignment == AxisAlignment.Near) + { + int n = 1; + + if (chartAxis.EdgeAxis == true) + n = chartXy.GetScBorderThickness(XyAlignment.Bottom) + 1; + + RenderMarks(g, pen, chartAxis, pt, -(n + tlen), tlen, true); + } + else + { + int n = 1; + + RenderMarks(g, pen, chartAxis, pt, -(n + tlen), tlen, false); + } + } + } + + g.SmoothingMode = sm; + } + + #region RenderMarks + + private void RenderMarks(Graphics g, + Pen pen, ChartAxis chartAxis, Point pt, int voff, int len, bool skipFirst) + { + foreach (TickmarkTick tmi in TickmarkLayout.Ticks) + { + Point pt1 = tmi.TickPoint; + pt1.X += pt.X; + pt1.Y += (pt.Y + voff); + + if (pt1.X >= chartAxis.AxisLineBounds.X - ScrollOffset.X && + pt1.X < chartAxis.AxisLineBounds.Right - ScrollOffset.X) + { + if (tmi.Index > 0 || skipFirst == false) + { + Point pt2 = pt1; + pt2.Y += len; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #endregion + + #region RenderTickmarkLabels + + private void RenderTickmarkLabels(Graphics g, ChartAxis chartAxis) + { + if (LabelBounds.IsEmpty == false) + { + TickmarkLabelVisualStyle lstyle = EffectiveLabelStyle; + + Point pt = GetLocalAdjustedPoint(Point.Empty); + float angle = GetLabelAngle(); + + using (SolidBrush br = new SolidBrush(lstyle.TextColor)) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.HighQuality; + + ChartXy chartXy = chartAxis.Parent as ChartXy; + Rectangle alb = chartXy.GetScrollBounds(chartAxis.AxisLineBounds); + + foreach (TickmarkTick tmi in TickmarkLayout.Ticks) + { + if (tmi.LabelVisible == true) + { + if ((tmi.TickPoint.X + pt.X >= alb.X) && + (tmi.TickPoint.X + pt.X < alb.Right)) + { + if (tmi.LabelColor.IsEmpty == true) + { + RenderLabel(g, tmi, pt, angle, br, lstyle.Font); + } + else + { + using (SolidBrush br2 = new SolidBrush(tmi.LabelColor)) + RenderLabel(g, tmi, pt, angle, br2, lstyle.Font); + } + } + } + } + + g.SmoothingMode = sm; + } + } + } + + #region RenderLabel + + private void RenderLabel(Graphics g, + TickmarkTick tmi, Point pt, float angle, Brush br, Font font) + { + Rectangle r = new Rectangle(tmi.LabelPoint, tmi.LabelSize); + r.X += pt.X; + r.Y += pt.Y; + + if (angle == 0) + { + g.DrawString(tmi.Label, font, br, r); + } + else + { + Point pt1 = Point.Empty; + + if (angle > 0) + { + if (angle > 90) + { + angle = angle - 180; + + pt1.X = -(int)tmi.TextSize.Width; + } + + pt1.Y = -(int)((Math.Abs(angle) / 90f) * (font.Height / 2)); + + g.TranslateTransform(r.X, r.Y); + } + else + { + if (angle < -90) + { + angle = angle + 180; + + pt1.X = -(int)tmi.TextSize.Width + 4; + } + + pt1.Y = -(int)(tmi.TextSize.Height - + (Math.Abs(angle) / 90f) * (tmi.TextSize.Height / 2)); + + g.TranslateTransform(r.X, LabelBounds.Bottom - 1); + } + + g.RotateTransform(angle); + + g.DrawString(tmi.Label, font, br, pt1); + + g.ResetTransform(); + } + } + + #endregion + + #endregion + + #endregion + + #region GetStartIndex + + internal override int GetStartIndex() + { + ChartAxis chartAxis = Parent as ChartAxis; + ChartXy chartXy = chartAxis.Parent as ChartXy; + + return (GetStartIndexEx(chartXy.HScrollBar)); + } + + #endregion + + #region Copy/CopyTo + + /// + /// Create a copy of the chart element. + /// + /// + public override ChartVisualElement Copy() + { + MajorTickmarksX copy = new MajorTickmarksX(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the chart element to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + MajorTickmarksX c = copy as MajorTickmarksX; + + if (c != null) + base.CopyTo(c); + } + + #endregion + } + + #endregion + + #region MajorTickmarksY + + /// + /// Represents a chart MajorTickmark on the Y-Axis. + /// + public class MajorTickmarksY : MajorTickmarks + { + public MajorTickmarksY() + : base(AxisOrientation.Y) + { + } + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + ChartAxis chartAxis = Parent as ChartAxis; + ChartTickmarkVisualStyle tstyle = EffectiveStyle; + + Rectangle bounds = Rectangle.Empty; + + MeasureTickmarks(layoutInfo, chartAxis); + + if (TickmarkLayout.MajorCount > 0) + bounds = MeasureTickmarkLabels(layoutInfo, chartAxis); + + BoundsRelative = bounds; + } + + #region MeasureTickmarks + + private void MeasureTickmarks(ChartLayoutInfo layoutInfo, ChartAxis chartAxis) + { + TickmarkLayout layout = TickmarkLayout; + + if (layout.MajorCount > 0) + { + Graphics g = layoutInfo.Graphics; + Rectangle bounds = layoutInfo.LayoutBounds; + + layout.TickmarkStart = GetStartIndex(); + layout.TickmarkEnd = layout.TickmarkStart + (int)((Math.Ceiling(bounds.Height / layout.MajorInterval))) + 3; + + UpdateTickmarkTicks(g, chartAxis, bounds, layout); + + ArrangeTickmarks(); + } + } + + #endregion + + #region MeasureTickmarkLabels + + private Rectangle MeasureTickmarkLabels(ChartLayoutInfo layoutInfo, ChartAxis chartAxis) + { + Rectangle bounds = layoutInfo.LayoutBounds; + + int labelWidth = GetTotalLabelWidth(); + int tickmarkWidth = Dpi.Width(GetMaxTickmarkLength(chartAxis, false)); + + bounds.Width = (labelWidth + tickmarkWidth); + + ChartXy chartXy = chartAxis.Parent as ChartXy; + + if (chartXy.DropShadowDisplayed == true) + bounds.Height -= 3; + + Rectangle r = bounds; + + AxisAlignment axisAlignment = chartAxis.GetAxisAlignment(); + + if (axisAlignment == AxisAlignment.Far) + { + LabelBounds = new Rectangle(r.X, r.Y, labelWidth, r.Height); + + r.X += labelWidth; + r.Width -= labelWidth; + + TickmarkBounds = r; + } + else + { + r.X = layoutInfo.LayoutBounds.Right - labelWidth; + bounds.X = r.X; + + LabelBounds = new Rectangle(r.X, r.Y, labelWidth, r.Height); + + r.X -= tickmarkWidth; + r.Width = tickmarkWidth; + + TickmarkBounds = r; + } + + if (chartAxis.EdgeAxis == false) + bounds.Width += Dpi.Width(GetMaxTickmarkLength(chartAxis, true)) + 2; + + return (bounds); + } + + #endregion + + #endregion + + #region ArrangeTickmarks + + protected override void ArrangeTickmarks() + { + ChartAxis chartAxis = Parent as ChartAxis; + + Rectangle tmBounds = TickmarkBounds; + Rectangle lbounds = LabelBounds; + TickmarkLayout layout = TickmarkLayout; + + AxisAlignment axisAlignment = chartAxis.GetAxisAlignment(); + Point tickPoint = new Point((axisAlignment == AxisAlignment.Near) ? tmBounds.X : tmBounds.Right + 1, 0); + + float angle = GetLabelAngle(); + + for (int i = layout.TickmarkStart; i < layout.TickmarkEnd; i++) + { + TickmarkTick tick = layout.Ticks[i - layout.TickmarkStart]; + + tickPoint.Y = (int)(tmBounds.Bottom - 1 - (i * layout.MajorInterval) + layout.MarginOffset); + + tick.TickPoint = tickPoint; + + tick.LabelPoint = tickPoint; + tick.LabelPoint.X = lbounds.X; + + int width = LabelBounds.Width; + + if (LabelsAreStaggered == true) + { + double value = GetTickmarkValue(chartAxis, tick); + int n = (int)(Math.Ceiling(value / TickmarkLayout.MajorSpacing)); + + if ((n % 2) != (axisAlignment == AxisAlignment.Near ? 0 : 1)) + { + width -= MaxLabelSize[0].Width; + tick.LabelPoint.X += MaxLabelSize[0].Width; + } + else + { + width -= MaxLabelSize[1].Width; + } + } + + if (axisAlignment == AxisAlignment.Far) + tick.LabelPoint.X += (width - tick.LabelSize.Width); + + if ((angle + 90) % 180 == 0) + tick.LabelPoint.Y -= (tick.LabelSize.Height / 2); + } + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + base.RenderOverride(renderInfo); + + Graphics g = renderInfo.Graphics; + + ChartAxis chartAxis = Parent as ChartAxis; + ChartTickmarkVisualStyle tstyle = EffectiveStyle; + + if (CanRenderTickmarks(tstyle) == true) + RenderTickmarks(g, tstyle, chartAxis); + + if (TickmarkLayout.MajorCount > 0) + RenderTickmarkLabels(g, chartAxis); + } + + #region RenderTickmarks + + private void RenderTickmarks(Graphics g, + ChartTickmarkVisualStyle tstyle, ChartAxis chartAxis) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + using (Pen pen = new Pen(tstyle.TickmarkColor, Dpi.Height(tstyle.TickmarkThickness))) + { + int tlen = Dpi.Height(tstyle.TickmarkLength) - ((tstyle.TickmarkThickness > 1) ? 0 : 1); + + Point pt = GetLocalAdjustedPoint(Point.Empty); + + AxisAlignment axisAlignment = chartAxis.GetAxisAlignment(); + + if (tstyle.TickmarkAlignment == LineAlignment.Center || + (axisAlignment == AxisAlignment.Far && tstyle.TickmarkAlignment == LineAlignment.Near) || + (axisAlignment == AxisAlignment.Near && tstyle.TickmarkAlignment == LineAlignment.Far)) + { + // Right + + RenderMarks(g, pen, chartAxis, pt, 0, tlen, axisAlignment == AxisAlignment.Far); + } + + if (tstyle.TickmarkAlignment == LineAlignment.Center || + (axisAlignment == AxisAlignment.Far && tstyle.TickmarkAlignment == LineAlignment.Far) || + (axisAlignment == AxisAlignment.Near && tstyle.TickmarkAlignment == LineAlignment.Near)) + { + // Left + + ChartXy chartXy = chartAxis.Parent as ChartXy; + + if (axisAlignment == AxisAlignment.Near) + { + int n = 1; + + if (chartAxis.EdgeAxis == true) + n = chartXy.GetScBorderThickness(XyAlignment.Right) + 1; + + RenderMarks(g, pen, chartAxis, pt, -(n + tlen), tlen, true); + } + else + { + int n = 2; + + RenderMarks(g, pen, chartAxis, pt, -(n + tlen), tlen, false); + } + } + } + + g.SmoothingMode = sm; + } + + #region RenderMarks + + private void RenderMarks(Graphics g, + Pen pen, ChartAxis chartAxis, Point pt, int hoff, int len, bool skipFirst) + { + foreach (TickmarkTick tmi in TickmarkLayout.Ticks) + { + Point pt1 = tmi.TickPoint; + pt1.X += (pt.X + hoff); + pt1.Y += pt.Y; + + if (pt1.Y >= chartAxis.AxisLineBounds.Y - ScrollOffset.Y && + pt1.Y < chartAxis.AxisLineBounds.Bottom - ScrollOffset.Y) + { + if (tmi.Index > 0 || skipFirst == false) + { + Point pt2 = pt1; + pt2.X += len; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #endregion + + #region RenderTickmarkLabels + + private void RenderTickmarkLabels(Graphics g, ChartAxis chartAxis) + { + if (LabelBounds.IsEmpty == false) + { + TickmarkLabelVisualStyle lstyle = EffectiveLabelStyle; + + Point pt = GetLocalAdjustedPoint(Point.Empty); + AxisAlignment axisAlignment = chartAxis.GetAxisAlignment(); + + float angle = GetLabelAngle(); + + using (SolidBrush br = new SolidBrush(lstyle.TextColor)) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.HighQuality; + + Rectangle bounds = chartAxis.Bounds; + + foreach (TickmarkTick tmi in TickmarkLayout.Ticks) + { + if (tmi.LabelVisible == true) + { + if (tmi.TickPoint.Y + pt.Y < bounds.Y) + break; + + if (tmi.TickPoint.Y + pt.Y > bounds.Bottom) + continue; + + if (tmi.LabelColor.IsEmpty == true) + { + RenderLabel(g, tmi, pt, axisAlignment, angle, br, lstyle.Font); + } + else + { + using (SolidBrush br2 = new SolidBrush(tmi.LabelColor)) + RenderLabel(g, tmi, pt, axisAlignment, angle, br2, lstyle.Font); + } + } + } + + g.SmoothingMode = sm; + } + } + } + + #region RenderLabel + + private void RenderLabel(Graphics g, TickmarkTick tmi, + Point pt, AxisAlignment axisAlignment, float angle, Brush br, Font font) + { + Rectangle r = new Rectangle(tmi.LabelPoint, tmi.LabelSize); + r.X += pt.X; + r.Y += pt.Y; + + int n = (int)(tmi.TextSize.Height / 2); + + if (angle == 0) + { + r.Y -= n; + g.DrawString(tmi.Label, font, br, r); + } + else + { + Point pt1 = Point.Empty; + + if (angle > 0) + { + if (angle > 90) + { + angle = angle - 180; + + pt1.Y -= (int)(((90 + angle) / 90f) * (font.Height / 2)); + } + else + { + pt1.Y -= (n + (int)((Math.Abs(angle) / 90f) * (font.Height / 2))); + } + + g.TranslateTransform(r.X, r.Y); + } + else + { + if (angle < -90) + { + angle = angle + 180; + + pt1.Y -= ((int)((Math.Abs(90 - angle) / 90f) * (tmi.TextSize.Height / 2))); + } + else + { + pt1.Y -= (n + (int)((Math.Abs(angle) / 90f) * (font.Height / 2))); + } + + pt1.X = -(int)tmi.TextSize.Width; + + g.TranslateTransform(r.Right, r.Y); + } + + g.RotateTransform(angle); + + g.DrawString(tmi.Label, font, br, pt1); + + g.ResetTransform(); + } + } + + #endregion + + #endregion + + #endregion + + #region GetStartIndex + + internal override int GetStartIndex() + { + ChartAxis chartAxis = Parent as ChartAxis; + ChartXy chartXy = chartAxis.Parent as ChartXy; + + return (GetStartIndexEx(chartXy.VScrollBar)); + } + + #endregion + + #region Copy/CopyTo + + /// + /// Creates a copy of the chart element. + /// + /// + public override ChartVisualElement Copy() + { + MajorTickmarksY copy = new MajorTickmarksY(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the chart element to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + MajorTickmarksY c = copy as MajorTickmarksY; + + if (c != null) + base.CopyTo(c); + } + + #endregion + } + + #endregion + + #region MajorTickmarks + + /// + /// Represents a chart MajorTickmark. + /// + public class MajorTickmarks : ChartTickmarks + { + #region Private variables + + private MajorStates _MajorStates; + + private float _LabelAngle; + private int _MinLabelGap = 4; + private int _LabelSkip; + + private Rectangle _LabelBounds; + private Size[] _MaxLabelSize; + + private TickmarkLabelVisualStyle _LabelVisualStyle; + private EffectiveStyle _EffectiveLabelStyle; + + #endregion + + public MajorTickmarks(AxisOrientation orientation) + : base(orientation) + { + InitDefaultStates(); + + _EffectiveLabelStyle = new EffectiveStyle(this); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(MajorStates.AutoLayout, true); + SetState(MajorStates.ShowLabels, true); + SetState(MajorStates.StaggerLabels, true); + } + + #endregion + + #region Public properties + + #region AutoTickmarkLayout + + /// + /// Gets or sets whether Major Tickmark layout is automatic. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Major Tickmark layout is automatic.")] + public bool AutoTickmarkLayout + { + get { return (TestState(MajorStates.AutoLayout)); } + + set + { + if (value != AutoTickmarkLayout) + { + SetState(MajorStates.AutoLayout, value); + + OnPropertyChangedEx("AutoTickmarkLayout", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EffectiveLabelStyles + + /// + /// Gets a reference to the Tickmark Label's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TickmarkLabelVisualStyle EffectiveLabelStyle + { + get { return (_EffectiveLabelStyle.Style); } + } + + #endregion + + #region LabelAngle + + /// + /// Gets or sets the angle at which the Tickmark labels are displayed. + /// + [DefaultValue(0f), Category("Layout")] + [Description("Indicates the angle at which the Tickmark labels are displayed.")] + [Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public float LabelAngle + { + get { return (_LabelAngle); } + + set + { + if (value != _LabelAngle) + { + _LabelAngle = value; + + OnPropertyChangedEx("LabelAngle", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LabelSkip + + /// + /// Gets or sets the number of inter-labels to skip. + /// + [DefaultValue(0), Category("Layout")] + [Description("Indicates the number of inter-labels to skip.")] + public int LabelSkip + { + get { return (_LabelSkip); } + + set + { + if (value != _LabelSkip) + { + _LabelSkip = value; + + OnPropertyChangedEx("LabelSkip", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LabelVisualStyle + + /// + /// Gets or sets the visual style for the Tickmark Labels. + /// + [Category("Style")] + [Description("Indicates the visual style for the Tickmark Labels.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TickmarkLabelVisualStyle LabelVisualStyle + { + get + { + if (_LabelVisualStyle == null) + { + _LabelVisualStyle = new TickmarkLabelVisualStyle(); + + StyleVisualChangeHandler(null, _LabelVisualStyle); + } + + return (_LabelVisualStyle); + } + + set + { + if (_LabelVisualStyle != value) + { + TickmarkLabelVisualStyle oldValue = _LabelVisualStyle; + + _LabelVisualStyle = value; + + OnStyleChanged("LabelVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region MinLabelGap + + /// + /// Gets or sets the minimum gap between tickmark labels. + /// + [DefaultValue(4), Category("Layout")] + [Description("Indicates the minimum gap between tickmark labels.")] + public int MinLabelGap + { + get { return (_MinLabelGap); } + + set + { + if (value != _MinLabelGap) + { + _MinLabelGap = value; + + OnPropertyChangedEx("MinLabelGap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowLabels + + /// + /// Gets or sets whether Tickmark labels are shown. + /// + [DefaultValue(true), Category("Layout")] + [Description("Indicates whether Tickmark labels are shown.")] + public bool ShowLabels + { + get { return (TestState(MajorStates.ShowLabels)); } + + set + { + if (value != ShowLabels) + { + SetState(MajorStates.ShowLabels, value); + + OnPropertyChangedEx("ShowLabels", VisualChangeType.Layout); + } + } + } + + #endregion + + #region StaggerLabels + + /// + /// Gets or sets whether overlapping labels are staggered. + /// + [DefaultValue(true), Category("Layout")] + [Description("Indicates whether overlapping labels are staggered.")] + public bool StaggerLabels + { + get { return (TestState(MajorStates.StaggerLabels)); } + + set + { + if (value != StaggerLabels) + { + SetState(MajorStates.StaggerLabels, value); + + OnPropertyChangedEx("StaggerLabels", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region LabelBounds + + internal Rectangle LabelBounds + { + get { return (_LabelBounds); } + set { _LabelBounds = value; } + } + + #endregion + + #region LabelsAreStaggered + + internal bool LabelsAreStaggered + { + get { return (TestState(MajorStates.LabelsAreStaggered)); } + set { SetState(MajorStates.LabelsAreStaggered, value); } + } + + #endregion + + #region MaxLabelSize + + internal Size[] MaxLabelSize + { + get { return (_MaxLabelSize); } + set { _MaxLabelSize = value; } + } + + #endregion + + #endregion + + #region UpdateTickmarkTicks + + internal void UpdateTickmarkTicks(Graphics g, + ChartAxis chartAxis, Rectangle bounds, TickmarkLayout layout) + { + TickmarkTick[] ticks = new TickmarkTick[layout.TickmarkEnd - layout.TickmarkStart]; + + CalculateBaseValue(chartAxis, layout); + + if (ShowLabels == true) + { + TickmarkLabelVisualStyle lbstyle = EffectiveLabelStyle; + + using (StringFormat sf = new StringFormat()) + { + lbstyle.GetStringFormatFlags(sf); + + if (lbstyle.MaxLineCount <= 1) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + int maxLabelWidth = lbstyle.MaxWidth < 0 ? 0 : lbstyle.MaxWidth; + + float angle = GetLabelAngle(); + + int skip = (LabelSkip > 0 ? LabelSkip + 1 : 0); + + for (int i = layout.TickmarkStart; i < layout.TickmarkEnd; i++) + { + TickmarkTick tmi = new TickmarkTick(); + + tmi.Index = i; + + SetTickValue(chartAxis, layout, lbstyle, tmi); + + if ((tmi.Label != null) && (skip <= 0 || (tmi.LabelIndex) % skip == 0)) + { + lbstyle.GetStringFormatFlags(sf); + + tmi.TextSize = g.MeasureString(tmi.Label, lbstyle.Font, maxLabelWidth, sf); + + if (tmi.TextSize.IsEmpty == false) + { + tmi.TextSize.Width++; + tmi.TextSize.Height++; + } + + if (lbstyle.MaxLineCount > 1) + { + int lineHeight = (int)(Math.Ceiling(lbstyle.Font.GetHeight())) * lbstyle.MaxLineCount; + + if (tmi.TextSize.Height > lineHeight) + tmi.TextSize.Height = lineHeight; + } + + if (angle != 0) + { + double radians = MathHelper.ToRadians(angle); + + tmi.LabelSize.Width = (int)(Math.Abs(tmi.TextSize.Width * Math.Cos(radians)) + Math.Abs(tmi.TextSize.Height * Math.Sin(radians))); + tmi.LabelSize.Height = (int)(Math.Abs(tmi.TextSize.Width * Math.Sin(radians)) + Math.Abs(tmi.TextSize.Height * Math.Cos(radians))); + } + else + { + tmi.LabelSize = tmi.TextSize.ToSize(); + } + + tmi.LabelVisible = true; + } + else + { + tmi.LabelVisible = false; + } + + ticks[i - layout.TickmarkStart] = tmi; + } + } + } + else + { + for (int i = layout.TickmarkStart; i < layout.TickmarkEnd; i++) + { + TickmarkTick tmi = new TickmarkTick(); + + tmi.Index = i; + + SetTickValue(chartAxis, layout, null, tmi); + + ticks[i - layout.TickmarkStart] = tmi; + } + } + + layout.Ticks = ticks; + } + + #region CalculateBaseValue + + private void CalculateBaseValue(ChartAxis axis, TickmarkLayout layout) + { + switch (axis.ScaleType) + { + case ScaleType.Qualitative: + int iminValue = (int)layout.MinValue; + int ivalue = (int)Math.Floor(iminValue / layout.GridSpacing); + + layout.BaseValue = (int)(ivalue * layout.GridSpacing); + break; + + case ScaleType.DateTime: + layout.BaseValue = layout.MinValue; + break; + + default: + Type otype = layout.MinValue.GetType(); + + double dminValue = Convert.ToDouble(layout.MinValue); + double n = dminValue < 0 ? -1 : 1; + double dvalue = Math.Floor(Math.Abs(dminValue) / layout.MajorSpacing); + + layout.BaseValue = Convert.ChangeType((int)dvalue * layout.MajorSpacing * n, otype); + break; + } + } + + #endregion + + #region SetTickValue + + private void SetTickValue(ChartAxis chartAxis, + TickmarkLayout layout, TickmarkLabelVisualStyle lbstyle, TickmarkTick tmi) + { + tmi.LabelIndex = -1; + + switch (chartAxis.ScaleType) + { + case ScaleType.Qualitative: + tmi.Value = (int)layout.BaseValue + tmi.Index; + + if (ShowLabels == true) + { + int i = (int)tmi.Value; + + if ((uint)i < chartAxis.QualitativeValues.Count) + { + object value = chartAxis.QualitativeValues[i]; + + if (string.IsNullOrEmpty(lbstyle.TextFormat) == false) + tmi.Label = string.Format(lbstyle.TextFormat, value); + else + tmi.Label = value.ToString(); + + tmi.LabelIndex = i; + } + } + break; + + case ScaleType.DateTime: + tmi.Value = chartAxis.GetDateTime((DateTime)layout.BaseValue, tmi.Index * layout.MajorSpacing); + + if (ShowLabels == true) + { + DateTime dt = (DateTime)tmi.Value; + + if (string.IsNullOrEmpty(lbstyle.TextFormat) == false) + tmi.Label = dt.ToString(lbstyle.TextFormat); + else + tmi.Label = chartAxis.GetDateTimeLabel(dt); + + tmi.LabelIndex = tmi.Index; + } + break; + + default: + Type otype = layout.BaseValue.GetType(); + double dbase = Convert.ToDouble(layout.BaseValue); + + tmi.Value = dbase + (tmi.Index * layout.MajorSpacing); + + if (ShowLabels == true) + { + if (string.IsNullOrEmpty(lbstyle.TextFormat) == false) + tmi.Label = String.Format("{0:" + lbstyle.TextFormat + "}", tmi.Value); + else + tmi.Label = tmi.Value.ToString(); + + tmi.LabelIndex = tmi.Index; + } + break; + } + + if (ShowLabels == true && tmi.LabelIndex >= 0) + { + ChartControl chartControl = ChartControl; + + chartControl.DoGetTickmarkLabelEvent(chartAxis, tmi.Value, ref tmi.Label, ref tmi.LabelColor); + } + } + + #endregion + + #endregion + + #region GetTickmarkValue + + internal double GetTickmarkValue(ChartAxis chartAxis, TickmarkTick tick) + { + switch (chartAxis.ScaleType) + { + case ScaleType.DateTime: + return (chartAxis.GetDateTimeValue((DateTime)tick.Value)); + + case ScaleType.Qualitative: + return ((int)tick.Value + TickmarkLayout.MajorSpacing / 2); + + default: + return (Convert.ToDouble(tick.Value) + TickmarkLayout.MajorSpacing / 2); + } + } + + #endregion + + #region GetLabelAngle + + protected virtual float GetLabelAngle() + { + float angle = LabelAngle % 180; + + ChartAxis chartAxis = Parent as ChartAxis; + AxisAlignment axisAlignment = chartAxis.GetAxisAlignment(); + + if (axisAlignment == AxisAlignment.Near) + { + if (angle < -90) + angle += 180; + } + else + { + if (angle > 0) + angle -= 180; + } + + return (angle); + } + + #endregion + + #region GetStartIndex + + internal virtual int GetStartIndex() + { + return (0); + } + + internal int GetStartIndexEx(ScrollBarLite srollBar) + { + int offset = srollBar.Value; + + if (offset <= 0) + return (0); + + int range = TickmarkLayout.MajorCount - 1; + int smax = srollBar.Maximum; + + double dx = (((double)(offset * range)) / smax); + + return (int)(dx); + } + + #endregion + + #region ArrangeTickmarks + + protected virtual void ArrangeTickmarks() + { + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + ChartAxis axis = Parent as ChartAxis; + ChartXy chartXy = axis.Parent as ChartXy; + + if (TickmarkLayout.TickmarkStart != GetStartIndex()) + { + Rectangle bounds = layoutInfo.LayoutBounds; + layoutInfo.LayoutBounds = chartXy.BoundsRelative; + + chartXy.Measure(layoutInfo); + chartXy.Arrange(layoutInfo); + + layoutInfo.LayoutBounds = bounds; + + if (layoutInfo.LayoutBoundsAdjusted == true) + { + layoutInfo.LayoutBoundsAdjusted = false; + + chartXy.InvalidateRender(); + } + } + + ArrangeTickmarks(); + } + + #endregion + + #region GetTotalLabelHeight + + internal int GetTotalLabelHeight() + { + return (GetTotalLabelSize().Height); + } + + #endregion + + #region GetTotalLabelWidth + + internal int GetTotalLabelWidth() + { + return (GetTotalLabelSize().Width); + } + + #endregion + + #region GetTotalLabelSize + + internal Size GetTotalLabelSize() + { + _MaxLabelSize = new Size[2]; + _MaxLabelSize[0] = Size.Empty; + _MaxLabelSize[1] = Size.Empty; + + TickmarkTick lastTmi = null; + + LabelsAreStaggered = false; + + float angle = GetLabelAngle(); + + int minLabelGap = Dpi.Width(MinLabelGap); + + foreach (TickmarkTick tmi in TickmarkLayout.Ticks) + { + if (tmi.LabelVisible == true && tmi.LabelPoint.IsEmpty == false && tmi.LabelIndex >= 0) + { + int n = tmi.Index % 2; + + if (tmi.LabelSize.Height > _MaxLabelSize[n].Height) + _MaxLabelSize[n].Height = tmi.LabelSize.Height; + + if (tmi.LabelSize.Width > _MaxLabelSize[n].Width) + _MaxLabelSize[n].Width = tmi.LabelSize.Width; + + if (StaggerLabels == true && LabelsAreStaggered == false) + { + if (lastTmi != null) + { + if (AxisOrientation == AxisOrientation.X) + { + if (angle % 180 == 0) + { + if (lastTmi.LabelPoint.X + + lastTmi.LabelSize.Width + minLabelGap > tmi.LabelPoint.X) + { + LabelsAreStaggered = true; + } + } + } + else + { + if ((angle + 90) % 180 == 0) + { + if (tmi.LabelPoint.Y + + tmi.LabelSize.Height + minLabelGap > lastTmi.LabelPoint.Y) + { + LabelsAreStaggered = true; + } + } + } + } + + lastTmi = tmi; + } + } + } + + Size maxSize = Size.Empty; + + if (LabelsAreStaggered == true) + { + if (AxisOrientation == AxisOrientation.X) + maxSize.Height = _MaxLabelSize[0].Height + _MaxLabelSize[1].Height; + else + maxSize.Width = _MaxLabelSize[0].Width + _MaxLabelSize[1].Width; + } + else + { + maxSize.Height = Math.Max(_MaxLabelSize[0].Height, _MaxLabelSize[1].Height); + maxSize.Width = Math.Max(_MaxLabelSize[0].Width, _MaxLabelSize[1].Width); + } + + return (maxSize); + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + base.ApplyStyles(style); + + TickmarkLabelVisualStyle lstyle = style as TickmarkLabelVisualStyle; + + if (lstyle != null) + { + ApplyParentStyles(lstyle, Parent as ChartContainer); + + lstyle.ApplyStyle(LabelVisualStyle); + + if (lstyle.Font == null) + lstyle.Font = SystemFonts.DefaultFont; + + if (lstyle.TextColor.IsEmpty) + lstyle.TextColor = Color.Black; + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles( + TickmarkLabelVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.TickmarkLabelVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.TickmarkLabelVisualStyle); + } + } + + #endregion + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + base.ClearEffectiveStyles(); + + _EffectiveLabelStyle.InvalidateStyle(); + } + + #endregion + + #endregion + + #region Copy/CopyTo + + /// + /// Copies the chart element to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + MajorTickmarks c = copy as MajorTickmarks; + + if (c != null) + { + base.CopyTo(c); + + c.AutoTickmarkLayout = AutoTickmarkLayout; + c.LabelAngle = LabelAngle; + + c.LabelVisualStyle = (_LabelVisualStyle != null) ? LabelVisualStyle.Copy() : null; + + c.MinLabelGap = MinLabelGap; + c.ShowLabels = ShowLabels; + c.StaggerLabels = StaggerLabels; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "MajorTickmarks"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AutoTickmarkLayout", AutoTickmarkLayout, true); + sec.AddValue("LabelAngle", LabelAngle, 0f); + sec.AddValue("LabelSkip", LabelSkip, 0); + + if (_LabelVisualStyle != null && _LabelVisualStyle.IsEmpty == false) + sec.AddElement(_LabelVisualStyle.GetSerialData("LabelVisualStyle")); + + sec.AddValue("MinLabelGap", MinLabelGap, 4); + sec.AddValue("ShowLabels", ShowLabels, true); + sec.AddValue("StaggerLabels", StaggerLabels, true); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AutoTickmarkLayout": + AutoTickmarkLayout = bool.Parse(se.StringValue); + break; + + case "LabelAngle": + LabelAngle = float.Parse(se.StringValue); + break; + + case "LabelSkip": + LabelSkip = int.Parse(se.StringValue); + break; + + case "MinLabelGap": + MinLabelGap = int.Parse(se.StringValue); + break; + + case "ShowLabels": + ShowLabels = bool.Parse(se.StringValue); + break; + + case "StaggerLabels": + StaggerLabels = bool.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "LabelVisualStyle": + sec.PutSerialData(LabelVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region MajorStates + + [Flags] + protected enum MajorStates : uint + { + AutoLayout = (1U << 0), + ShowLabels = (1U << 1), + StaggerLabels = (1U << 2), + + //-------- + + LabelsAreStaggered = (1U << 3), + } + + #region TestState + + protected bool TestState(MajorStates state) + { + return ((_MajorStates & state) == state); + } + + #endregion + + #region SetState + + protected void SetState(MajorStates state, bool value) + { + if (value == true) + _MajorStates |= state; + else + _MajorStates &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + LabelVisualStyle = null; + + base.Dispose(); + } + + #endregion + } + + #endregion + + #endregion + + #region MinorTickmarks + + #region MinorTickmarksX + + /// + /// Represents a Minor tickmark on the X-Axis. + /// + public class MinorTickmarksX : MinorTickmarks + { + public MinorTickmarksX() + : base(AxisOrientation.X) + { + } + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + ChartAxis chartAxis = Parent as ChartAxis; + Rectangle bounds = Rectangle.Empty; + + if (TickmarkCount > 0) + { + bounds = layoutInfo.LayoutBounds; + bounds.Height = Dpi.Height(GetMaxTickmarkLength(chartAxis, false)); + } + + BoundsRelative = bounds; + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + TickmarkTick[] ticks = TickmarkLayout.Ticks; + + if (ticks.Length > 1) + { + ChartAxis chartAxis = Parent as ChartAxis; + ChartTickmarkVisualStyle tstyle = EffectiveStyle; + + if (CanRenderTickmarks(tstyle) == true) + { + Graphics g = renderInfo.Graphics; + Point pt = GetLocalAdjustedPoint(Point.Empty); + + AxisAlignment axisAlignment = chartAxis.GetAxisAlignment(); + + using (Pen pen = new Pen(tstyle.TickmarkColor, Dpi.Width(tstyle.TickmarkThickness))) + { + int tlen = Dpi.Width(tstyle.TickmarkLength); + + if ((tstyle.TickmarkAlignment == LineAlignment.Center) || + (axisAlignment == AxisAlignment.Far && tstyle.TickmarkAlignment == LineAlignment.Near) || + (axisAlignment == AxisAlignment.Near && tstyle.TickmarkAlignment == LineAlignment.Far)) + { + // Bottom + + RenderMarks(g, pen, chartAxis, pt, ticks, 0, tlen - 1); + } + + if ((tstyle.TickmarkAlignment == LineAlignment.Center) || + (axisAlignment == AxisAlignment.Far && tstyle.TickmarkAlignment == LineAlignment.Far) || + (axisAlignment == AxisAlignment.Near && tstyle.TickmarkAlignment == LineAlignment.Near)) + { + // Top + + ChartXy chartXy = chartAxis.Parent as ChartXy; + + if (axisAlignment == AxisAlignment.Near) + { + int n = 1; + + if (chartAxis.EdgeAxis == true) + n = chartXy.GetScBorderThickness(XyAlignment.Bottom); + + RenderMarks(g, pen, chartAxis, pt, ticks, -(n + tlen), tlen - 1); + } + else + { + int n = 0; + + RenderMarks(g, pen, chartAxis, pt, ticks, -(n + tlen), tlen - 1); + } + } + } + } + } + } + + #region CanRenderTickmarks + + protected override bool CanRenderTickmarks(ChartTickmarkVisualStyle tstyle) + { + if (TickmarkCount <= 0) + return (false); + + return (base.CanRenderTickmarks(tstyle)); + } + + #endregion + + #region RenderMarks + + private void RenderMarks(Graphics g, + Pen pen, ChartAxis chartAxis, Point pt, TickmarkTick[] ticks, int voff, int len) + { + ChartAxis axis = Parent as ChartAxis; + + int minorTickCount = TickmarkLayout.MinorCount; + + for (int i = 0; i < ticks.Length - 1; i++) + { + TickmarkTick tick = ticks[i]; + + Point pt1 = tick.TickPoint; + pt1.Y += (pt.Y + voff); + + Point pt2 = pt1; + pt2.Y += len; + + double dx = (double)(ticks[i + 1].TickPoint.X - tick.TickPoint.X) / (minorTickCount + 1); + double ddx = dx; + + for (int j = 0; j < minorTickCount; j++) + { + pt1.X = pt.X + (int)(tick.TickPoint.X + ddx); + pt2.X = pt1.X; + + ddx += dx; + + if (pt1.X >= chartAxis.AxisLineBounds.X - ScrollOffset.X && + pt1.X < chartAxis.AxisLineBounds.Right - ScrollOffset.X) + { + if (pt1.Equals(pt2) == true) + pt1.Y--; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #endregion + + #region Copy/CopyTo + + /// + /// Creates a copy of the chart element. + /// + /// + public override ChartVisualElement Copy() + { + MinorTickmarksX copy = new MinorTickmarksX(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the chart element to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + MinorTickmarksX c = copy as MinorTickmarksX; + + if (c != null) + { + base.CopyTo(c); + } + } + + #endregion + } + + #endregion + + #region MinorTickmarksY + + /// + /// Represents a Minor tickmark on the Y-Axis. + /// + public class MinorTickmarksY : MinorTickmarks + { + public MinorTickmarksY() + : base(AxisOrientation.Y) + { + } + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + ChartAxis chartAxis = Parent as ChartAxis; + + Rectangle bounds = Rectangle.Empty; + + if (TickmarkCount > 0) + { + bounds = layoutInfo.LayoutBounds; + bounds.Width = Dpi.Width(GetMaxTickmarkLength(chartAxis, false)); + + if (chartAxis.AxisAlignment == AxisAlignment.Near) + bounds.X = layoutInfo.LayoutBounds.Right - bounds.Width; + } + + BoundsRelative = bounds; + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + TickmarkTick[] ticks = TickmarkLayout.Ticks; + + if (ticks.Length > 1) + { + ChartAxis chartAxis = Parent as ChartAxis; + ChartTickmarkVisualStyle tstyle = EffectiveStyle; + + if (CanRenderTickmarks(tstyle) == true) + { + Graphics g = renderInfo.Graphics; + + AxisAlignment axisAlignment = chartAxis.GetAxisAlignment(); + + using (Pen pen = new Pen(tstyle.TickmarkColor, Dpi.Height(tstyle.TickmarkThickness))) + { + int tlen = Dpi.Height(tstyle.TickmarkLength); + + if (tstyle.TickmarkAlignment == LineAlignment.Center || + (axisAlignment == AxisAlignment.Far && tstyle.TickmarkAlignment == LineAlignment.Near) || + (axisAlignment == AxisAlignment.Near && tstyle.TickmarkAlignment == LineAlignment.Far)) + { + // Right + + RenderMarks(g, pen, chartAxis, ticks, 0, tlen - 1); + } + + if (tstyle.TickmarkAlignment == LineAlignment.Center || + (axisAlignment == AxisAlignment.Far && tstyle.TickmarkAlignment == LineAlignment.Far) || + (axisAlignment == AxisAlignment.Near && tstyle.TickmarkAlignment == LineAlignment.Near)) + { + // Left + + ChartXy chartXy = chartAxis.Parent as ChartXy; + + if (axisAlignment == AxisAlignment.Near) + { + int n = 1; + + if (chartAxis.EdgeAxis == true) + n = chartXy.GetScBorderThickness(XyAlignment.Right); + + RenderMarks(g, pen, chartAxis, ticks, -(n + tlen), tlen - 1); + } + else + { + int n = 1; + + RenderMarks(g, pen, chartAxis, ticks, -(n + tlen), tlen); + } + } + } + } + } + } + + #region CanRenderTickmarks + + protected override bool CanRenderTickmarks(ChartTickmarkVisualStyle tstyle) + { + if (TickmarkCount <= 0) + return (false); + + return (base.CanRenderTickmarks(tstyle)); + } + + #endregion + + #region RenderMarks + + private void RenderMarks(Graphics g, + Pen pen, ChartAxis chartAxis, TickmarkTick[] ticks, int hoff, int len) + { + ChartAxis axis = Parent as ChartAxis; + + int minorTickCount = TickmarkLayout.MinorCount; + + Point pt = GetLocalAdjustedPoint(Point.Empty); + + for (int i = 0; i < ticks.Length - 1; i++) + { + TickmarkTick tick = ticks[i]; + + Point pt1 = tick.TickPoint; + pt1.X += (pt.X + hoff); + + Point pt2 = pt1; + pt2.X += len; + + double dy = (double)(ticks[i + 1].TickPoint.Y - tick.TickPoint.Y) / (minorTickCount + 1); + double ddy = dy; + + for (int j = 0; j < minorTickCount; j++) + { + pt1.Y = pt.Y + (int)(tick.TickPoint.Y + ddy); + pt2.Y = pt1.Y; + + ddy += dy; + + if (pt1.Y >= chartAxis.AxisLineBounds.Y - ScrollOffset.Y && + pt1.Y < chartAxis.AxisLineBounds.Bottom - ScrollOffset.Y) + { + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #endregion + + #region Copy/CopyTo + + /// + /// Creates a copy of the chart element. + /// + /// + public override ChartVisualElement Copy() + { + MinorTickmarksY copy = new MinorTickmarksY(); + + CopyTo(copy); + + return (copy); + } + + /// + /// Copies the chart element to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + MinorTickmarksY c = copy as MinorTickmarksY; + + if (c != null) + { + base.CopyTo(c); + } + } + + #endregion + } + + #endregion + + #region MinorTickmarks + + /// + /// Represents a Minor tickmark. + /// + public class MinorTickmarks : ChartTickmarks + { + #region Private variables + + private int _TickmarkCount = 3; + + #endregion + + public MinorTickmarks(AxisOrientation orientation) + : base(orientation) + { + } + + #region Public properties + + #region TickmarkCount + + /// + /// Gets or sets the number of Tickmarks presented between Majortickmarks. + /// + [DefaultValue(3), Category("Layout")] + [Description("Indicates the number of Tickmarks presented between Majortickmarks.")] + public int TickmarkCount + { + get { return (_TickmarkCount); } + + set + { + if (value != _TickmarkCount) + { + _TickmarkCount = value; + + OnPropertyChangedEx("TickmarkCount", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region CopyTo + + /// + /// Copies the chart element to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + MinorTickmarks c = copy as MinorTickmarks; + + if (c != null) + { + base.CopyTo(c); + + c.TickmarkCount = TickmarkCount; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "MinorTickmarks"; + + sec.AddStartElement(serialName); + } + + sec.AddElement(base.GetSerialData(null)); + + sec.AddValue("TickmarkCount", TickmarkCount, 3); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "TickmarkCount": + TickmarkCount = int.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + } + + #endregion + + #endregion + + #region ChartTickmarks + + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public abstract class ChartTickmarks : ChartVisualElement + { + #region Private variables + + private States _States; + + private AxisOrientation _AxisOrientation; + + private Rectangle _TickmarkBounds; + private TickmarkLayout _TickmarkLayout; + + private ChartTickmarkVisualStyle _ChartTickmarkVisualStyle; + private EffectiveStyle _EffectiveStyle; + + #endregion + + public ChartTickmarks(AxisOrientation orientation) + { + _AxisOrientation = orientation; + + InitDefaultStates(); + + _EffectiveStyle = new EffectiveStyle(this); + + Visible = true; + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + } + + #endregion + + #region Public properties + + #region AxisOrientation + + /// + /// Gets the axis orientation (X/Y). + /// + [Browsable(false)] + [Description("Indicates the axis orientation (X/Y).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AxisOrientation AxisOrientation + { + get { return (_AxisOrientation); } + } + + #endregion + + #region EffectiveStyle + + /// + /// Gets a reference to the Tickmark's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates a reference to the Tickmark's Effective (cached, composite) style.")] + public ChartTickmarkVisualStyle EffectiveStyle + { + get { return (_EffectiveStyle.Style); } + } + + #endregion + + #region ChartTickmarkVisualStyle + + /// + /// Gets or sets the visual styles for the Tickmarks. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Tickmarks.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartTickmarkVisualStyle ChartTickmarkVisualStyle + { + get + { + if (_ChartTickmarkVisualStyle == null) + { + _ChartTickmarkVisualStyle = new ChartTickmarkVisualStyle(); + + StyleVisualChangeHandler(null, _ChartTickmarkVisualStyle); + } + + return (_ChartTickmarkVisualStyle); + } + + set + { + if (_ChartTickmarkVisualStyle != value) + { + ChartTickmarkVisualStyle oldValue = _ChartTickmarkVisualStyle; + + _ChartTickmarkVisualStyle = value; + + OnVisualStyleChanged("ChartTickmarkVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region TickmarkBounds + + internal Rectangle TickmarkBounds + { + get { return (_TickmarkBounds); } + set { _TickmarkBounds = value; } + } + + #endregion + + #region TickmarkLayout + + internal TickmarkLayout TickmarkLayout + { + get { return (_TickmarkLayout); } + set { _TickmarkLayout = value; } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + } + + #endregion + + #region CanRenderTickmarks + + protected virtual bool CanRenderTickmarks(ChartTickmarkVisualStyle tstyle) + { + if (Visible == false || tstyle.TickmarkThickness <= 0 || tstyle.TickmarkColor.IsEmpty == true) + return (false); + + return (true); + } + + #endregion + + #region Render + + internal override void Render(ChartRenderInfo renderInfo) + { + if (Displayed == true) + RenderOverride(renderInfo); + } + + #endregion + + #region GetMaxTickmarkLength + + internal int GetMaxTickmarkLength(ChartAxis chartAxis, bool inner) + { + int length = (inner == false) ? 4 : 0; + + if (Visible == true) + { + ChartTickmarkVisualStyle tstyle = EffectiveStyle; + + if (chartAxis.EdgeAxis == false) + { + length = tstyle.TickmarkLength; + } + else + { + switch (tstyle.TickmarkAlignment) + { + case LineAlignment.Near: + if (inner == true) + length = tstyle.TickmarkLength; + break; + + case LineAlignment.Center: + length = tstyle.TickmarkLength; + break; + + default: + if (inner == false) + length = tstyle.TickmarkLength; + break; + } + } + } + + return (length); + } + + #endregion + + #region GetLocalAdjustedBounds + + internal Rectangle GetLocalAdjustedBounds(Rectangle bounds) + { + bounds.Location = GetLocalAdjustedPoint(bounds.Location); + + return (bounds); + } + + #endregion + + #region GetLocalAdjustedPoint + + internal Point GetLocalAdjustedPoint(Point pt) + { + ChartAxis axis = Parent as ChartAxis; + ChartXy chartXy = axis.Parent as ChartXy; + + if (chartXy != null) + { + pt.X -= ScrollOffset.X; + pt.Y -= ScrollOffset.Y; + + if (_AxisOrientation == AxisOrientation.X) + { + pt.X -= chartXy.HScrollOffset; + } + else + { + if (chartXy.VScrollBar.Inverted == true) + pt.Y += chartXy.VScrollOffset; + else + pt.Y -= chartXy.VScrollOffset; + } + } + + return (pt); + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + ChartTickmarkVisualStyle tstyle = style as ChartTickmarkVisualStyle; + + if (tstyle != null) + { + ApplyParentStyles(tstyle, Parent as ChartContainer); + + tstyle.ApplyStyle(ChartTickmarkVisualStyle); + + if (tstyle.TickmarkColor.IsEmpty == true) + tstyle.TickmarkColor = Color.Gray; + + if (tstyle.TickmarkThickness < 0) + tstyle.TickmarkThickness = 1; + + if (tstyle.TickmarkLength < 0) + { + if (this is MajorTickmarks) + tstyle.TickmarkLength = 5; + else + tstyle.TickmarkLength = 2; + } + + if (tstyle.TickmarkAlignment == LineAlignment.NotSet) + tstyle.TickmarkAlignment = LineAlignment.Far; + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles( + ChartTickmarkVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is ChartPanel) + { + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartTickmarkVisualStyle); + } + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartTickmarkVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartTickmarkVisualStyle); + } + } + + #endregion + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Style definition + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + if (_EffectiveStyle.InvalidateStyle() == true) + InvalidateLayout(); + } + + #endregion + + #endregion + + #region CopyTo + + /// + /// Copies the chart element to the given "copy". + /// + /// + public override void CopyTo(ChartVisualElement copy) + { + ChartTickmarks c = copy as ChartTickmarks; + + if (c != null) + { + base.CopyTo(c); + + c.ChartTickmarkVisualStyle = + (_ChartTickmarkVisualStyle != null) ? ChartTickmarkVisualStyle.Copy() : null; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartTickmarks"; + + sec.AddStartElement(serialName); + } + + if (_ChartTickmarkVisualStyle != null && _ChartTickmarkVisualStyle.IsEmpty == false) + sec.AddElement(_ChartTickmarkVisualStyle.GetSerialData("ChartTickmarkVisualStyle")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ChartTickmarkVisualStyle": + sec.PutSerialData(ChartTickmarkVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + protected enum States : uint + { + } + + #region TestState + + protected bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + protected void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartXy.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartXy.cs new file mode 100644 index 00000000..81d79d68 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ChartXy.cs @@ -0,0 +1,6452 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents an X/Y oriented chart. + /// pi + public class ChartXy : BaseChart + { + #region Private variables + + private States _States; + + private ChartAxisX _AxisX; + private ChartAxisY _AxisY; + + private ChartAxesXCollection _AncillaryAxesX; + private ChartAxesYCollection _AncillaryAxesY; + + private ChartSeriesCollection _ChartSeries; + + private SeriesType _AutoGenSeriesChartType = SeriesType.Point; + + private int _BarSpacing; + private double _BarSpacingRatio = 0.2d; + private double _BarWidthRatio; + private object _BarOrigin; + private Tbool _BarShadingEnabled = Tbool.NotSet; + private Tbool _BarShowAsHistogram = Tbool.NotSet; + + private BarFillRange _BarFillRange = BarFillRange.NotSet; + private BarLabelPosition _BarLabelPosition = BarLabelPosition.NotSet; + + private DataLabelOverlapMode _DataLabelOverlapMode = DataLabelOverlapMode.NotSet; + + private DataLabelVisualStyle _DataLabelVisualStyle; + private EffectiveStyle _EffectiveDataLabelStyle; + + private ChartXyVisualStyle _ChartVisualStyle; + private EffectiveStyle _EffectiveChartStyle; + + private ChartSeriesVisualStyle _ChartSeriesVisualStyle; + private EffectiveStyle _EffectiveChartSeriesStyle; + + private ChartCrosshair _ChartCrosshair; + private List _CrosshairSeriesPoints; + private CrosshairPoint _NearestCrosshairPoint; + private bool _CanShowCrosshairLabel; + + private object _MinValueX; + private object _MaxValueX; + + private object _MinValueY; + private object _MaxValueY; + + private Size _MinQualitativeSize; + + private PointMarker _PointMarker; + + private ChartLineDisplayMode _ChartLineDisplayMode = ChartLineDisplayMode.NotSet; + private ChartLineAreaDisplayMode _ChartLineAreaDisplayMode = ChartLineAreaDisplayMode.NotSet; + + private BubbleSizeMode _BubbleSizeMode = BubbleSizeMode.NotSet; + private BubbleIntensityMode _BubbleIntensityMode = BubbleIntensityMode.NotSet; + private ConvexHullDisplayMode _ConvexHullDisplayMode = ConvexHullDisplayMode.NotSet; + private PointLabelDisplayMode _PointLabelDisplayType = PointLabelDisplayMode.NotSet; + + private StepLines _StepLines = StepLines.NotSet; + private StepLineMode _StepLineMode = StepLineMode.NotSet; + + private List _PointLabels; + + #endregion + + public ChartXy(string name) + : this() + { + Name = name; + } + + public ChartXy() + { + InitDefaultStates(); + + _EffectiveChartStyle = new EffectiveStyle(this); + _EffectiveChartSeriesStyle = new EffectiveStyle(this); + + _EffectiveDataLabelStyle = new EffectiveStyle(this); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + } + + #endregion + + #region Public properties + + #region AncillaryAxesX + + /// + /// Gets a reference to the collection of Ancillary X Axes (Axes that + /// can be presented in addition to the default X Axis) + /// + [Category("Axis")] + [Description("Indicates the collection of Ancillary X Axes (Axes that can be presented in addition to the default X Axis.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartAxesXCollection AncillaryAxesX + { + get + { + if (_AncillaryAxesX == null) + { + _AncillaryAxesX = new ChartAxesXCollection(); + _AncillaryAxesX.CollectionChanged += AncillaryAxesCollectionChanged; + } + + return (_AncillaryAxesX); + } + + internal set + { + if (_AncillaryAxesX != null) + _AncillaryAxesX.CollectionChanged -= AncillaryAxesCollectionChanged; + + _AncillaryAxesX = value; + + if (_AncillaryAxesX != null) + _AncillaryAxesX.CollectionChanged += AncillaryAxesCollectionChanged; + } + } + + #region AncillaryAxesCollectionChanged + + private void AncillaryAxesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + ChartAxesCollection cac = sender as ChartAxesCollection; + + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + AddAxisItems(e, cac.AxisOrientation); + break; + + case NotifyCollectionChangedAction.Replace: + RemoveAxisItems(e); + AddAxisItems(e, cac.AxisOrientation); + break; + + case NotifyCollectionChangedAction.Remove: + RemoveAxisItems(e); + break; + } + + InvalidateLayout(); + } + + #region AddAxisItems + + private void AddAxisItems( + NotifyCollectionChangedEventArgs e, AxisOrientation axisOrientation) + { + foreach (ChartAxis axis in e.NewItems) + { + if (axis.AxisOrientation != axisOrientation) + { + if (axisOrientation == AxisOrientation.X) + throw new Exception("Cannot add Y-Axis element to X-Axis collection."); + else + throw new Exception("Cannot add X-Axis element to Y-Axis collection."); + } + + axis.Parent = this; + } + } + + #endregion + + #region RemoveAxisItems + + private void RemoveAxisItems(NotifyCollectionChangedEventArgs e) + { + foreach (ChartAxis axis in e.OldItems) + axis.Parent = null; + } + + #endregion + + #endregion + + #endregion + + #region AncillaryAxesY + + /// + /// Gets a reference to the collection of Ancillary Y Axes (Axes that + /// can be presented in addition to the default Y Axis) + /// + [Category("Axis")] + [Description("Indicates the collection of Ancillary Y Axes (Axes that can be presented in addition to the default Y Axis.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartAxesYCollection AncillaryAxesY + { + get + { + if (_AncillaryAxesY == null) + { + _AncillaryAxesY = new ChartAxesYCollection(); + _AncillaryAxesY.CollectionChanged += AncillaryAxesCollectionChanged; + } + + return (_AncillaryAxesY); + } + + internal set + { + if (_AncillaryAxesY != null) + _AncillaryAxesY.CollectionChanged -= AncillaryAxesCollectionChanged; + + _AncillaryAxesY = value; + + if (_AncillaryAxesY != null) + _AncillaryAxesY.CollectionChanged += AncillaryAxesCollectionChanged; + } + } + + #endregion + + #region AutoGenSeriesType + + /// + /// Gets or sets the default SeriesType assigned to auto-generated Series. + /// + [DefaultValue(SeriesType.Point), Category("Behavior")] + [Description("Indicates the default SeriesType assigned to auto-generated Series.")] + public SeriesType AutoGenSeriesType + { + get { return (_AutoGenSeriesChartType); } + + set + { + if (value != _AutoGenSeriesChartType) + { + _AutoGenSeriesChartType = value; + + OnPropertyChanged("AutoGenSeriesType"); + } + } + } + + #endregion + + #region AxisX + + /// + /// Gets a reference to the default, primary X Axis. + /// + [Category("Axis")] + [Description("Indicates the reference to the default, primary X Axis.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartAxisX AxisX + { + get + { + if (_AxisX == null) + { + _AxisX = new ChartAxisX(); + + _AxisX.Parent = this; + _AxisX.IsPrimaryAxis = true; + } + + return (_AxisX); + } + + internal set + { + if (_AxisX != null) + _AxisX.Parent = null; + + _AxisX = value; + + if (_AxisX != null) + { + _AxisX.Parent = this; + _AxisX.IsPrimaryAxis = true; + } + } + } + + #endregion + + #region AxisY + + /// + /// Gets a reference to the default, primary Y Axis. + /// + [Category("Axis")] + [Description("Indicates the reference to the default, primary Y Axis.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartAxisY AxisY + { + get + { + if (_AxisY == null) + { + _AxisY = new ChartAxisY(); + + _AxisY.Parent = this; + _AxisY.IsPrimaryAxis = true; + } + + return (_AxisY); + } + + internal set + { + if (_AxisY != null) + _AxisY.Parent = null; + + _AxisY = value; + + if (_AxisY != null) + { + _AxisY.Parent = this; + _AxisY.IsPrimaryAxis = true; + } + } + } + + #endregion + + #region BarFillRange + + /// + /// Gets or sets how series bars are filled by default (either according to + /// each individual bar range, or the entire series range). + /// + [DefaultValue(BarFillRange.NotSet), Category("Bar Display")] + [Description("Indicates how series bars are filled by default(either according to each individual bar range, or the entire series range).")] + public BarFillRange BarFillRange + { + get { return (_BarFillRange); } + + set + { + if (value != _BarFillRange) + { + _BarFillRange = value; + + OnPropertyChangedEx("BarFillRange", VisualChangeType.Render); + } + } + } + + #endregion + + #region BarLabelPosition + + /// + /// Gets or sets the default position of bar series labels (default is Center). + /// + [DefaultValue(BarLabelPosition.NotSet), Category("Bar Display")] + [Description("Indicates the default position of bar series labels (default is Center).")] + public BarLabelPosition BarLabelPosition + { + get { return (_BarLabelPosition); } + + set + { + if (value != _BarLabelPosition) + { + _BarLabelPosition = value; + + OnPropertyChangedEx("BarLabelPosition", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BarOrigin + + /// + /// Gets or sets the bar 'origin'. This value is used as the base, or + /// starting Value, from which each bar originates. + /// + [DefaultValue(null), Category("Bar Display")] + [Description("Indicates the bar 'origin'. This value is used as the base, or starting Value, from which each bar originates.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter, DevComponents.Charts.Design," + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object BarOrigin + { + get { return (_BarOrigin); } + + set + { + if (value != _BarOrigin) + { + _BarOrigin = value; + + OnPropertyChangedEx("BarOrigin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BarOverlayEnabled + + /// + /// Gets or sets whether the intra-bar (or bar grouping) overlay + /// is enabled (bars within a group are positoned overlayed on top of each other). + /// + [DefaultValue(false), Category("Bar Display")] + [Description("Indicates whether the intra-bar (or bar grouping) overlay is enabled (bars within a group are positoned overlayed on top of each other).")] + public bool BarOverlayEnabled + { + get { return (TestState(States.BarOverlayEnabled)); } + + set + { + if (value != BarOverlayEnabled) + { + SetState(States.BarOverlayEnabled, value); + + OnPropertyChangedEx("BarOverlayEnabled", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BarShadingEnabled + + /// + /// Gets or sets whether Bar shading is enabled by + /// default for Horizontal and Vertical Bar series. + /// + [DefaultValue(Tbool.NotSet), Category("Bar Display")] + [Description("Indicates whether Bar shading is enabled by default for Horizontal and Vertical Bar series.")] + public Tbool BarShadingEnabled + { + get { return (_BarShadingEnabled); } + + set + { + if (value != _BarShadingEnabled) + { + _BarShadingEnabled = value; + + OnPropertyChangedEx("BarShadingEnabled", VisualChangeType.Render); + } + } + } + + #endregion + + #region BarShowAsHistogram + + /// + /// Gets or sets whether the bars will be shown as a Histogram. + /// Note that this will only be honored for single series bar displays. + /// + [DefaultValue(Tbool.NotSet), Category("Bar Display")] + [Description("Indicates whether the bars will be shown as a Histogram. Note that this will only be honored for single series bar displays.")] + public Tbool BarShowAsHistogram + { + get { return (_BarShowAsHistogram); } + + set + { + if (value != _BarShowAsHistogram) + { + _BarShowAsHistogram = value; + + OnPropertyChangedEx("BarShowAsHistogram", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BarSpacing + + /// + /// Gets or sets the intra-bar spacing (or spacing between bars + /// within the same group). Value is taken as a fixed pixel size. + /// Setting BarSpacing to 0 (zero) will disable the use of this + /// property, and will enable the use of the set BarSpacingRatio value. + /// + [DefaultValue(0), Category("Bar Display")] + [Description("Indicates the intra-bar spacing (or spacing between bars within the same group). Value is taken as a fixed pixel size. Setting BarSpacing to 0 (zero) will disable the use of this property, and will enable the use of the set BarSpacingRatio value.")] + public int BarSpacing + { + get { return (_BarSpacing); } + + set + { + if (value != _BarSpacing) + { + _BarSpacing = value; + + OnPropertyChangedEx("BarSpacing", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BarSpacingRatio + + /// + /// Gets or sets the intra-bar spacing ratio (bar spacing between + /// multiple series bars associated with the same value. Default is .2). + /// + [DefaultValue(0.2d), Category("Bar Display")] + [Description("Indicates the intra-bar spacing ratio (bar spacing between multiple series bars associated with the same value. Default is .2).")] + public double BarSpacingRatio + { + get { return (_BarSpacingRatio); } + + set + { + if (value != _BarSpacingRatio) + { + if (value < 0) + throw new ArgumentException("Value must be >= 0"); + + _BarSpacingRatio = value; + + OnPropertyChangedEx("BarSpacingRatio", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BarWidthRatio + + /// + /// Gets or sets the default ratio of bar width to bar + /// group spacing (defaults to 1 - bar width matches spacing). + /// + [DefaultValue(0d), Category("Bar Display")] + [Description("Indicates the default ratio of bar width to bar group spacing (defaults to 1 - bar width matches spacing).")] + public double BarWidthRatio + { + get { return (_BarWidthRatio); } + + set + { + if (value != _BarWidthRatio) + { + if (value < 0) + throw new ArgumentException("Value must be >= 0"); + + _BarWidthRatio = value; + + OnPropertyChangedEx("BarWidthRatio", VisualChangeType.Layout); + } + } + } + + #endregion + + #region BubbleIntensityMode + + /// + /// Gets or sets the default mode used to determine series bubble intensities. + /// + [DefaultValue(BubbleIntensityMode.NotSet), Category("Display")] + [Description("Indicates the default mode used to determine series bubble intensities.")] + public BubbleIntensityMode BubbleIntensityMode + { + get { return (_BubbleIntensityMode); } + + set + { + if (value != _BubbleIntensityMode) + { + _BubbleIntensityMode = value; + + OnPropertyChangedEx("BubbleIntensityMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region BubbleSizeMode + + /// + /// Gets or sets the default mode used to calculate series bubble sizes. + /// + [DefaultValue(BubbleSizeMode.NotSet), Category("Display")] + [Description("Indicates the default mode used to calculate series bubble sizes.")] + public BubbleSizeMode BubbleSizeMode + { + get { return (_BubbleSizeMode); } + + set + { + if (value != _BubbleSizeMode) + { + _BubbleSizeMode = value; + + OnPropertyChangedEx("BubbleSizeMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ChartLineAreaDisplayMode + + /// + /// Gets or sets the default Line 'Area' display mode. + /// + [DefaultValue(ChartLineAreaDisplayMode.NotSet), Category("Display")] + [Description("Indicates the default Line 'Area' display mode.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartLineAreaDisplayMode ChartLineAreaDisplayMode + { + get { return (_ChartLineAreaDisplayMode); } + + set + { + if (value != _ChartLineAreaDisplayMode) + { + _ChartLineAreaDisplayMode = value; + + OnPropertyChangedEx("ChartLineAreaDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ChartLineDisplayMode + + /// + /// Gets or sets the default display mode for SeriesType.Line series. + /// + [DefaultValue(ChartLineDisplayMode.NotSet), Category("Display")] + [Description("Indicates the default display mode for SeriesType.Line series.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ChartLineDisplayMode ChartLineDisplayMode + { + get { return (_ChartLineDisplayMode); } + + set + { + if (value != _ChartLineDisplayMode) + { + if ((_ChartLineDisplayMode & ChartLineDisplayMode.DisplayUnsorted) != + (value & ChartLineDisplayMode.DisplayUnsorted)) + { + foreach (ChartSeries series in ChartSeries) + series.ResetSortedPoints(); + } + + _ChartLineDisplayMode = value; + + OnPropertyChangedEx("ChartLineDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ChartSeries + + /// + /// Gets a reference to the collection of Chart Series + /// + [Category("Data")] + [Description("Indicates the collection of Chart Series.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSeriesCollection ChartSeries + { + get + { + if (_ChartSeries == null) + { + _ChartSeries = new ChartSeriesCollection(); + + _ChartSeries.CollectionChanged += ChartSeriesCollectionChanged; + } + + return (_ChartSeries); + } + + internal set + { + BaseSeries = null; + + if (_ChartSeries != null) + _ChartSeries.CollectionChanged -= ChartSeriesCollectionChanged; + + _ChartSeries = value; + + if (_ChartSeries != null) + _ChartSeries.CollectionChanged += ChartSeriesCollectionChanged; + } + } + + #region ChartSeriesCollectionChanged + + void ChartSeriesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + BaseSeries = null; + + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (ChartSeries item in e.NewItems) + item.Parent = this; + break; + + case NotifyCollectionChangedAction.Replace: + foreach (ChartSeries item in e.OldItems) + item.Parent = null; + + foreach (ChartSeries item in e.NewItems) + item.Parent = this; + break; + + case NotifyCollectionChangedAction.Remove: + foreach (ChartSeries item in e.OldItems) + item.Parent = null; + break; + } + + ValidateSeriesCollection(); + + InvalidateLayout(); + } + + #endregion + + #region ValidateSeriesCollection + + private void ValidateSeriesCollection() + { + SeriesRangeChanged = true; + + foreach (ChartSeries series in ChartSeries) + { + ChartAxis axis = series.AxisX; + + if (axis != null && axis.IsPrimaryAxis == false) + { + if (AncillaryAxesX.Contains(axis) == false) + { + throw new Exception("Cannot set the series YAxis. The axis is not primary " + + "or a member of the chart's AncillaryAxesY collection."); + } + } + + axis = series.AxisY; + + if (axis != null && axis.IsPrimaryAxis == false) + { + if (AncillaryAxesY.Contains(axis) == false) + { + throw new Exception("Cannot set the series YAxis. The axis is not primary " + + "or a member of the chart's AncillaryAxesY collection."); + } + } + } + } + + #endregion + + #endregion + + #region ChartSeriesVisualStyle + + /// + /// Gets or sets the default visual style for each chart series. + /// + [Category("Style")] + [Description("Indicates the default visual style for each chart series.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSeriesVisualStyle ChartSeriesVisualStyle + { + get + { + if (_ChartSeriesVisualStyle == null) + { + _ChartSeriesVisualStyle = new ChartSeriesVisualStyle(); + + StyleVisualChangeHandler(null, _ChartSeriesVisualStyle); + } + + return (_ChartSeriesVisualStyle); + } + + set + { + if (_ChartSeriesVisualStyle != value) + { + ChartSeriesVisualStyle oldValue = _ChartSeriesVisualStyle; + + _ChartSeriesVisualStyle = value; + + OnStyleChanged("ChartSeriesVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ChartVisualStyle + + /// + /// Gets or sets the visual style for the Chart. + /// + [Category("Style")] + [Description("Indicates the visual style for the Chart.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartXyVisualStyle ChartVisualStyle + { + get + { + if (_ChartVisualStyle == null) + { + _ChartVisualStyle = new ChartXyVisualStyle(); + + StyleVisualChangeHandler(null, _ChartVisualStyle); + } + + return (_ChartVisualStyle); + } + + set + { + if (_ChartVisualStyle != value) + { + ChartXyVisualStyle oldValue = _ChartVisualStyle; + + _ChartVisualStyle = value; + + OnStyleChanged("ChartVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ChartCrosshair + + /// + /// Gets a reference to the Crosshair element for the chart. + /// + [Category("Appearance")] + [Description("Indicates a reference to the Crosshair element for the chart.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartCrosshair ChartCrosshair + { + get + { + if (_ChartCrosshair == null) + { + _ChartCrosshair = new ChartCrosshair(); + + _ChartCrosshair.Parent = this; + _ChartCrosshair.PropertyChanged += ChartCrosshair_PropertyChanged; + } + + return (_ChartCrosshair); + } + + internal set + { + if (_ChartCrosshair != null) + { + _ChartCrosshair.Parent = null; + _ChartCrosshair.PropertyChanged -= ChartCrosshair_PropertyChanged; + } + + _ChartCrosshair = value; + + if (_ChartCrosshair != null) + { + _ChartCrosshair.Parent = this; + _ChartCrosshair.PropertyChanged += ChartCrosshair_PropertyChanged; + } + } + } + + #region ChartCrosshair_PropertyChanged + + void ChartCrosshair_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + InvalidateRender(); + } + + #endregion + + #endregion + + #region ConvexHullDisplayMode + + /// + /// Gets or sets the default ConvexHull display mode. + /// + [DefaultValue(ConvexHullDisplayMode.NotSet), Category("Display")] + [Description("Indicates the default ConvexHull display mode.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public ConvexHullDisplayMode ConvexHullDisplayMode + { + get { return (_ConvexHullDisplayMode); } + + set + { + if (value != _ConvexHullDisplayMode) + { + _ConvexHullDisplayMode = value; + + OnPropertyChangedEx("ConvexHullDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region DataLabelOverlapMode + + /// + /// Gets or sets the mode for resolving overlapping series data labels. + /// + [DefaultValue(DataLabelOverlapMode.NotSet), Category("Display")] + [Description("Indicates the mode for resolving overlapping series data labels.")] + public DataLabelOverlapMode DataLabelOverlapMode + { + get { return (_DataLabelOverlapMode); } + + set + { + if (value != _DataLabelOverlapMode) + { + _DataLabelOverlapMode = value; + + OnPropertyChangedEx("DataLabelOverlapMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DataLabelVisualStyle + + /// + /// Gets or sets the default visual style for the chart DataLabel's. + /// + [Category("Style")] + [Description("Indicates the default visual style for the chart DataLabel's.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DataLabelVisualStyle DataLabelVisualStyle + { + get + { + if (_DataLabelVisualStyle == null) + { + _DataLabelVisualStyle = new DataLabelVisualStyle(); + + StyleVisualChangeHandler(null, _DataLabelVisualStyle); + } + + return (_DataLabelVisualStyle); + } + + set + { + if (_DataLabelVisualStyle != value) + { + DataLabelVisualStyle oldValue = _DataLabelVisualStyle; + + _DataLabelVisualStyle = value; + + OnStyleChanged("DataLabelVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region EffectiveChartSeriesStyle + + /// + /// Gets a reference to the ChartSeries effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartSeriesVisualStyle EffectiveChartSeriesStyle + { + get { return (_EffectiveChartSeriesStyle.Style); } + } + + #endregion + + #region EffectiveChartStyle + + /// + /// Gets a reference to the Chart's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartXyVisualStyle EffectiveChartStyle + { + get { return (_EffectiveChartStyle.Style); } + } + + #endregion + + #region EffectiveDataLabelStyle + + /// + /// Gets a reference to the DataLabel Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Indicates a reference to the DataLabel Effective (cached, composite) style.")] + public DataLabelVisualStyle EffectiveDataLabelStyle + { + get { return (_EffectiveDataLabelStyle.Style); } + } + + #endregion + + #region MaxValueX + + /// + /// Gets the calculated maximum X value (composite value of all associated series). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MaxValueX + { + get + { + UpdateRangeValues(); + + return (_MaxValueX); + } + } + + #endregion + + #region MaxValueY + + /// + /// Gets the calculated maximum Y value (composite value of all associated series). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MaxValueY + { + get + { + UpdateRangeValues(); + + return (_MaxValueY); + } + } + + #endregion + + #region MinValueX + + /// + /// Gets the calculated minimum X value (composite value of all associated series). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MinValueX + { + get + { + UpdateRangeValues(); + + return (_MinValueX); + } + } + + #endregion + + #region MinValueY + + /// + /// Gets the calculated minimum Y value (composite value of all associated series). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object MinValueY + { + get + { + UpdateRangeValues(); + + return (_MinValueY); + } + } + + #endregion + + #region NearestCrosshairPoint + + /// + /// Gets the last calculated CrosshairPoint nearest to the mouse cursor. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CrosshairPoint NearestCrosshairPoint + { + get { return (_NearestCrosshairPoint); } + } + + #endregion + + #region PointLabelDisplayMode + + /// + /// Gets or sets the default display mode for the chart PointLabels. + /// + [DefaultValue(PointLabelDisplayMode.NotSet), Category("Display")] + [Description("Indicates the default display mode for the chart PointLabels.")] + [Editor("DevComponents.Charts.Design.FlagsEnumUIEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public PointLabelDisplayMode PointLabelDisplayMode + { + get { return (_PointLabelDisplayType); } + + set + { + if (value != _PointLabelDisplayType) + { + _PointLabelDisplayType = value; + + InvalidatePointLabels(); + + OnPropertyChangedEx("PointLabelDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ScrollBounds + + /// + /// Gets the Scrollable bounds of the chart. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle ScrollBounds + { + get + { + ChartXyVisualStyle xyStyle = EffectiveChartStyle; + + Rectangle cbounds = ContentBounds; + + cbounds.X += xyStyle.BorderThickness.Left; + cbounds.Width -= xyStyle.BorderThickness.Horizontal; + + cbounds.Y += xyStyle.BorderThickness.Top; + cbounds.Height -= xyStyle.BorderThickness.Vertical; + + return (cbounds); + } + } + + #endregion + + #region ScrollBoundsEx + + /// + /// Gets the Scrollable, extended bounds of the chart. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle ScrollBoundsEx + { + get + { + ChartXyVisualStyle xyStyle = EffectiveChartStyle; + + Rectangle cbounds = ContentBoundsEx; + + cbounds.X += xyStyle.BorderThickness.Left; + cbounds.Width -= xyStyle.BorderThickness.Horizontal; + + cbounds.Y += xyStyle.BorderThickness.Top; + cbounds.Height -= xyStyle.BorderThickness.Vertical; + + return (cbounds); + } + } + + #endregion + + #region StepLines + + /// + /// Gets or sets which 'Step lines' are displayed by default. + /// + [DefaultValue(StepLines.NotSet), Category("Display")] + [Description("Indicates which 'Step lines' are displayed by default.")] + public StepLines StepLines + { + get { return (_StepLines); } + + set + { + if (value != _StepLines) + { + _StepLines = value; + + OnPropertyChangedEx("StepLines", VisualChangeType.Render); + } + } + } + + #endregion + + #region StepLineMode + + /// + /// Gets or sets the default mode (or order of rendered Step Lines) + /// used to display "Step Lines" in the defined Line series. + /// + [DefaultValue(StepLineMode.NotSet), Category("Display")] + [Description("Indicates the default mode (or order of rendered Step Lines) used to display 'Step Lines' in the defined Line series.")] + public StepLineMode StepLineMode + { + get { return (_StepLineMode); } + + set + { + if (value != _StepLineMode) + { + _StepLineMode = value; + + OnPropertyChangedEx("StepLineMode", VisualChangeType.Render); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region CrosshairSeriesPoints + + internal List CrosshairSeriesPoints + { + get { return (_CrosshairSeriesPoints); } + set { _CrosshairSeriesPoints = value; } + } + + #endregion + + #region DisplayCrosshair + + internal bool DisplayCrosshair + { + get { return (TestState(States.DisplayCrosshair)); } + set { SetState(States.DisplayCrosshair, value); } + } + + #endregion + + #region DropShadowDisplayed + + internal bool DropShadowDisplayed + { + get { return (TestState(States.DropShadowDisplayed)); } + set { SetState(States.DropShadowDisplayed, value); } + } + + #endregion + + #region MinQualitativeSize + + internal Size MinQualitativeSize + { + get { return (_MinQualitativeSize); } + set { _MinQualitativeSize = value; } + } + + #endregion + + #region PointLabels + + internal List PointLabels + { + get { return (_PointLabels); } + set { _PointLabels = value; } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + ContainerVisualStyle cstyle = GetEffectiveContainerStyle(); + ChartXyVisualStyle xystyle = EffectiveChartStyle; + + BoundsRelative = layoutInfo.LayoutBounds; + + MinQualitativeSize = Size.Empty; + + UpdateDataBindings(); + UpdateRangeValues(); + + Rectangle oldFrameBounds = FrameBounds; + + FrameBounds = GetAdjustedBounds(BoundsRelative, cstyle.Margin); + FrameBounds = GetAdjustedBounds(FrameBounds, cstyle.Padding); + FrameBounds = GetAdjustedBounds(FrameBounds, xystyle.Margin); + + if (FrameBounds != oldFrameBounds) + SeriesPointCount++; + + ContentBounds = GetAdjustedBounds(FrameBounds, cstyle.BorderThickness); + ContentBounds = GetAdjustedBounds(ContentBounds, xystyle.BorderThickness); + ContentBounds = GetAdjustedBounds(ContentBounds, xystyle.Padding); + + layoutInfo.LayoutBounds = ContentBounds; + + foreach (ChartTitle title in Titles) + { + if (title.Visible == true) + title.Measure(layoutInfo); + } + + if (Legend.Visible == true && Legend.Placement != Placement.Inside) + Legend.Measure(layoutInfo); + + DropShadowDisplayed = (xystyle.DropShadow.Enabled == Tbool.True); + + MeasureSeries(layoutInfo); + MeasureXyAxes(layoutInfo); + + if (DropShadowDisplayed == true) + layoutInfo.LayoutBounds = GetShadowBounds(layoutInfo.LayoutBounds); + + if (Legend.Visible == true && Legend.Placement == Placement.Inside) + { + Rectangle t = layoutInfo.LayoutBounds; + + if (VScrollBar.Visible == true) + { + t.Width -= (VScrollBar.Width - 1); + layoutInfo.LayoutBounds = t; + } + + if (HScrollBar.Visible == true) + { + t.Height -= (HScrollBar.Height - 1); + layoutInfo.LayoutBounds = t; + } + + Legend.Measure(layoutInfo); + + if (VScrollBar.Visible == true) + { + t.Width += VScrollBar.Width; + layoutInfo.LayoutBounds = t; + } + + if (HScrollBar.Visible == true) + { + t.Height += HScrollBar.Height; + layoutInfo.LayoutBounds = t; + } + } + + Rectangle oldContentBoundsEx = ContentBoundsEx; + + ContentBounds = layoutInfo.LayoutBounds; + ContentBoundsEx = ContentBounds; + + Rectangle r = ContentBounds; + + r.Size = new Size( + Math.Max(r.Size.Width, Dpi.Width(MinContentSize.Width)), + Math.Max(r.Size.Height, Dpi.Height(MinContentSize.Height))); + + if (MinQualitativeSize.Width > r.Width) + r.Width = MinQualitativeSize.Width; + + if (MinQualitativeSize.Height > r.Height) + r.Height = MinQualitativeSize.Height; + + // Since our vertical scrollbar is reversed, we + // need to adjust the extended content area accordingly + + if (r.Height > ContentBounds.Height) + r.Y -= (r.Height - ContentBounds.Height); + + ContentBoundsEx = r; + + if (ContentBoundsEx.Equals(oldContentBoundsEx) == false) + _PointLabels = null; + + FinalizeDataBindings(); + } + + #region MeasureSeries + + private void MeasureSeries(ChartLayoutInfo layoutInfo) + { + ChartSeries[] aseries = new ChartSeries[ChartSeries.Count]; + + ChartSeries.CopyTo(aseries, 0); + + foreach (ChartSeries series in aseries) + { + if (series.Visible == true) + series.Measure(layoutInfo); + } + } + + #endregion + + #region MeasureXyAxes + + private void MeasureXyAxes(ChartLayoutInfo layoutInfo) + { + Rectangle obounds = layoutInfo.LayoutBounds; + + SetEdgeAxes(AncillaryAxesX, AxisX); + SetEdgeAxes(AncillaryAxesY, AxisY); + + MeasureAxes(layoutInfo, AncillaryAxesX, AxisX); + + Rectangle nbounds = layoutInfo.LayoutBounds; + + MeasureAxes(layoutInfo, AncillaryAxesY, AxisY); + + for (int i = 0; i < 10; i++) + { + if (layoutInfo.LayoutBounds.Width == nbounds.Width) + break; + + nbounds = layoutInfo.LayoutBounds; + + layoutInfo.LayoutBoundsAdjusted = true; + layoutInfo.LayoutBounds.Y = obounds.Y; + layoutInfo.LayoutBounds.Height = obounds.Height; + + MeasureAxes(layoutInfo, AncillaryAxesX, AxisX); + + if (layoutInfo.LayoutBounds.Height == nbounds.Height) + break; + + layoutInfo.LayoutBounds.X = obounds.X; + layoutInfo.LayoutBounds.Width = obounds.Width; + + MeasureAxes(layoutInfo, AncillaryAxesY, AxisY); + } + + ValidateAxes(); + } + + #region MeasureAxes + + private void MeasureAxes( + ChartLayoutInfo layoutInfo, ChartAxesCollection axes, ChartAxis axis) + { + for (int i = axes.Count - 1; i >= 0; i--) + { + ChartAxis ca = axes[i]; + + if (ca != null) + ca.Measure(layoutInfo); + } + + axis.Measure(layoutInfo); + } + + #endregion + + #region ValidateAxes + + private void ValidateAxes() + { + if (ValidateAxes(AncillaryAxesX, AxisX) | + ValidateAxes(AncillaryAxesY, AxisY)) + { + InvalidateSeriesPoints(); + } + } + + #region ValidateAxes + + private bool ValidateAxes(ChartAxesCollection axes, ChartAxis axis) + { + int visCount = 0; + bool altered = false; + + for (int i = axes.Count - 1; i >= 0; i--) + { + ChartAxis ca = axes[i]; + + if (ca.Visible == true) + { + visCount++; + altered |= ca.ValidateAxis(); + } + } + + if (axis.Visible == true) + { + visCount++; + altered |= axis.ValidateAxis(); + } + + return (altered || (visCount == 0)); + } + + #endregion + + #endregion + + #region SetEdgeAxes + + private void SetEdgeAxes(ChartAxesCollection axes, ChartAxis axis) + { + ChartAxis farEdgeAxis = null; + ChartAxis nearEdgeAxis = null; + + for (int i = axes.Count - 1; i >= 0; i--) + { + ChartAxis ca = axes[i]; + + if (ca.Visible == true) + { + AxisAlignment axisAlignment = ca.GetAxisAlignment(); + + ca.EdgeAxis = false; + + if (axisAlignment == AxisAlignment.Near) + nearEdgeAxis = ca; + + else if (axisAlignment == AxisAlignment.Far) + farEdgeAxis = ca; + } + } + + if (axis.Visible == true) + { + AxisAlignment axisAlignment = axis.GetAxisAlignment(); + + if (axisAlignment == AxisAlignment.Near) + nearEdgeAxis = axis; + + else if (axisAlignment == AxisAlignment.Far) + farEdgeAxis = axis; + } + + if (nearEdgeAxis != null) + nearEdgeAxis.EdgeAxis = true; + + if (farEdgeAxis != null) + farEdgeAxis.EdgeAxis = true; + } + + #endregion + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + int vmax = VScrollBar.LargeChange; + + UpdatePaletteColor(); + + base.ArrangeOverride(layoutInfo); + + if (VScrollBar.LargeChange != vmax) + SeriesPointCount++; + + ArrangeAxes(layoutInfo, AncillaryAxesX, AxisX); + ArrangeAxes(layoutInfo, AncillaryAxesY, AxisY); + + ArrangeSeries(layoutInfo); + + SeriesLayoutCount++; + } + + #region UpdatePaletteColor + + private void UpdatePaletteColor() + { + ChartBaseSeriesCollection baseSeries = BaseSeries; + + for (int i = 0; i < baseSeries.Count; i++) + { + BaseSeries series = baseSeries[i]; + + series.DefaultPaletteColor = GetPaletteColor(i); + } + } + + #endregion + + #region ArrangeAxes + + private void ArrangeAxes( + ChartLayoutInfo layoutInfo, ChartAxesCollection axes, ChartAxis axis) + { + foreach (ChartAxis ca in axes) + { + if (ca.Visible == true) + ca.Arrange(layoutInfo); + } + + axis.Arrange(layoutInfo); + } + + #endregion + + #region ArrangeSeries + + private void ArrangeSeries(ChartLayoutInfo layoutInfo) + { + if (ChartSeries.Count > 0) + { + for (int i = 0; i < ChartSeries.Count; i++) + { + ChartSeries series = ChartSeries[i]; + + series.Arrange(layoutInfo); + + if (series.IsBarSeries == true) + { + ChartAxis axis = (series.IsRotated == false) + ? (series.AxisX ?? AxisX) : (series.AxisY ?? AxisY); + + for (int j = 0; j < axis.AxisBars.Length; j++) + axis.AxisBars[j].Reset(); + } + } + + for (int i = ChartSeries.Count - 1; i >= 0; i--) + SetBarTotals(i); + + for (int i = ChartSeries.Count - 1; i >= 0; i--) + SetBarWidth(i); + + if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse) + { + for (int i = ChartSeries.Count - 1; i >= 0; i--) + ArrangeBarSeries(i); + } + else + { + for (int i = 0; i < ChartSeries.Count; i++) + ArrangeBarSeries(i); + } + } + } + + #region SetBarTotals + + private void SetBarTotals(int i) + { + ChartSeries series = ChartSeries[i]; + + if (series.IsDisplayed == true) + { + ChartAxis axis = (series.IsRotated == false) + ? series.AxisX ?? AxisX : series.AxisY ?? AxisY; + + switch (series.SeriesType) + { + case SeriesType.HorizontalBar: + case SeriesType.VerticalBar: + axis.AxisBars[(int)AxisBarType.Bar].BarCount++; + axis.AxisBars[(int)AxisBarType.Bar].BarTotal += series.GetBarWidthRatio(this); + break; + + case SeriesType.HorizontalHiLoBar: + case SeriesType.VerticalHiLoBar: + axis.AxisBars[(int)AxisBarType.HiLoBar].BarCount++; + axis.AxisBars[(int)AxisBarType.HiLoBar].BarTotal += series.GetBarWidthRatio(this); + break; + } + } + } + + #endregion + + #region SetBarWidth + + private void SetBarWidth(int i) + { + ChartSeries series = ChartSeries[i]; + + if (series.IsDisplayed == true) + { + switch (series.SeriesType) + { + case SeriesType.HorizontalBar: + case SeriesType.VerticalBar: + SetBarWidthEx(series, (int)AxisBarType.Bar); + break; + + case SeriesType.HorizontalHiLoBar: + case SeriesType.VerticalHiLoBar: + SetBarWidthEx(series, (int)AxisBarType.HiLoBar); + break; + } + } + } + + #region SetBarWidthEx + + private void SetBarWidthEx(ChartSeries series, int barType) + { + ChartAxis axis = (series.IsRotated == false) + ? series.AxisX ?? AxisX : series.AxisY ?? AxisY; + + AxisBar axisBar = axis.AxisBars[barType]; + + double interval = axis.MajorTickmarks.TickmarkLayout.MajorInterval; + + double dwidth = interval / axis.MajorTickmarks.TickmarkLayout.MajorSpacing; + double ratio = series.GetBarWidthRatio(this); + + if (BarOverlayEnabled == true || axisBar.BarCount == 1) + { + int width = (int)(dwidth * (ratio / (ratio + 1))); + + if (ratio > 100) + { + ratio = (ratio - 1) / 100; + width = (int)(dwidth * ratio); + } + + width = (width < 0) ? 0 : ((width - 1) | 1); + + series.BarWidth = (int)(width / axis.MajorTickmarks.TickmarkLayout.GridSpacing); + + axisBar.BarTotalWidth += series.BarWidth; + } + else + { + int spacing = BarSpacing; + + if (BarSpacing == 0) + { + double abt = (axisBar.BarTotal + 1) + (axisBar.BarCount - 1) * BarSpacingRatio; + double sr = BarSpacingRatio / abt; + + spacing = (int)(Math.Ceiling(dwidth * sr)); + } + + dwidth -= ((axisBar.BarCount - 1) * spacing); + + int width = (int)(dwidth * (ratio / (axisBar.BarTotal + 1))); + + if (ratio > 100) + { + ratio = (ratio - 1) / 100; + width = (int)(dwidth * ratio); + } + + width = (int)(width / axis.MajorTickmarks.TickmarkLayout.GridSpacing); + width = (width < 0) ? 0 : ((width - 1) | 1); + + series.BarWidth = width; + + axisBar.BarTotalWidth += (series.BarWidth + spacing); + } + } + + #endregion + + #endregion + + #region ArrangeBarSeries + + private void ArrangeBarSeries(int i) + { + ChartSeries series = ChartSeries[i]; + + if (series.IsDisplayed == true) + { + switch (series.SeriesType) + { + case SeriesType.HorizontalBar: + case SeriesType.VerticalBar: + ArrangeBarSeriesEx(series, (int)AxisBarType.Bar); + break; + + case SeriesType.HorizontalHiLoBar: + case SeriesType.VerticalHiLoBar: + ArrangeBarSeriesEx(series, (int)AxisBarType.HiLoBar); + break; + } + } + } + + #region ArrangeBarSeriesEx + + private void ArrangeBarSeriesEx(ChartSeries series, int barType) + { + ChartAxis axis = (series.IsRotated == false) + ? (series.AxisX ?? AxisX) : (series.AxisY ?? AxisY); + + AxisBar axisBar = axis.AxisBars[barType]; + + if (BarOverlayEnabled == true || axisBar.BarCount == 1) + { + series.BarOffset = 0; + + axisBar.BarOffset = series.BarWidth; + } + else + { + int spacing = BarSpacing; + + if (BarSpacing == 0) + { + double dwidth = axis.MajorTickmarks.TickmarkLayout.MajorInterval; + double abt = (axisBar.BarTotal + 1) + (axisBar.BarCount - 1) * BarSpacingRatio; + + spacing = (int)(Math.Ceiling(dwidth * BarSpacingRatio / abt)); + } + + if (axisBar.BarOffset == int.MinValue) + axisBar.BarOffset = (int)((-axisBar.BarTotalWidth + spacing) / 2); + + series.BarOffset = axisBar.BarOffset + series.BarWidth / 2; + + axisBar.BarOffset += (series.BarWidth + spacing); + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region RenderOverride + + private bool _LastDisplayCrosshair; + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + ChartXyVisualStyle xystyle = EffectiveChartStyle; + ContainerVisualStyle cstyle = GetEffectiveContainerStyle(); + + Rectangle scFrameBounds = GetScrollBounds(FrameBounds); + Rectangle scContentBounds = GetScrollBounds(ContentBounds); + + Rectangle scFigureBounds = GetFigureBounds(scFrameBounds, cstyle); + + RenderFrameBackground(g, scFrameBounds, cstyle); + + cstyle.RenderBackgroundFigure(g, scFigureBounds); + cstyle.RenderBorder(g, scFrameBounds); + + Region clip = g.Clip; + g.SetClip(scContentBounds, CombineMode.Intersect); + + RenderContentBackground(renderInfo, scContentBounds, xystyle); + + Rectangle imageBounds = GetXyImageBounds(xystyle); + + if (xystyle.ImageOverlay != ImageOverlay.Top && xystyle.ImageOverlay != ImageOverlay.Middle) + xystyle.RenderBackgroundFigure(g, scContentBounds, imageBounds); + + Point cpt = Point.Empty; + Rectangle cbounds = Rectangle.Empty; + + _NearestCrosshairPoint = null; + + if (DisplayCrosshair == true) + { + cpt = ChartControl.PointToClient(Control.MousePosition); + cbounds = GetCrosshairBounds(cstyle); + + _CrosshairSeriesPoints = GetCrosshairPoints(cbounds, cpt); + } + + UpdatePointLabels(g); + + RenderGrid(renderInfo, false); + RenderReferences(renderInfo, false); + + if (xystyle.ImageOverlay == ImageOverlay.Middle) + xystyle.RenderBackgroundFigure(g, scContentBounds, imageBounds); + + RenderChartContent(renderInfo, xystyle); + + RenderGrid(renderInfo, true); + RenderReferences(renderInfo, true); + + RenderPointLabels(g); + + g.Clip = clip; + + xystyle.RenderBorder(g, scContentBounds); + + if (xystyle.ImageOverlay == ImageOverlay.Top) + xystyle.RenderBackgroundFigure(g, scContentBounds, imageBounds); + + RenderAxes(renderInfo, AncillaryAxesX, AxisX); + RenderAxes(renderInfo, AncillaryAxesY, AxisY); + + RenderScrollbars(renderInfo); + + if (DropShadowDisplayed == true) + xystyle.DropShadow.RenderDropShadow(g, scContentBounds, true, true); + + if (cstyle.DropShadow.Enabled == Tbool.True) + cstyle.DropShadow.RenderDropShadow(g, scFrameBounds, true, true); + + if (DisplayCrosshair == true) + { + CrosshairVisualStyle chstyle = ChartCrosshair.EffectiveCrosshairStyle; + + RenderCrosshairLines(g, cbounds, cpt, chstyle); + base.RenderOverride(renderInfo); + + if (_CanShowCrosshairLabel == true) + RenderCrosshairLabels(g, cbounds, cpt, chstyle); + + _LastDisplayCrosshair = DisplayCrosshair; + } + else + { + if (_CanShowCrosshairLabel == true) + { + if (DisplayCrosshair != _LastDisplayCrosshair) + RenderCrosshairLabels(g, cbounds, cpt, ChartCrosshair.EffectiveCrosshairStyle); + } + + base.RenderOverride(renderInfo); + } + } + + #region RenderContentBackground + + private void RenderContentBackground( + ChartRenderInfo renderInfo, Rectangle bounds, ChartXyVisualStyle xyStyle) + { + Graphics g = renderInfo.Graphics; + ChartControl chartControl = ChartControl; + + if (chartControl.DoPreRenderContentBackgroundEvent(g, this, bounds) == false) + { + xyStyle.RenderBackground(g, bounds); + + RenderAxesBackground(renderInfo, bounds, AncillaryAxesX, AxisX); + RenderAxesBackground(renderInfo, bounds, AncillaryAxesY, AxisY); + + chartControl.DoPostRenderContentBackgroundEvent(g, this, bounds); + } + } + + #region RenderAxesBackground + + private void RenderAxesBackground(ChartRenderInfo renderInfo, + Rectangle scContentBounds, ChartAxesCollection axes, ChartAxis axis) + { + foreach (ChartAxis ca in axes) + { + if (ca.Visible == true) + ca.RenderBackground(renderInfo, scContentBounds); + } + + axis.RenderBackground(renderInfo, scContentBounds); + + foreach (ChartAxis ca in axes) + { + if (ca.Visible == true) + ca.RenderStripes(renderInfo, scContentBounds); + } + + axis.RenderStripes(renderInfo, scContentBounds); + } + + #endregion + + #endregion + + #region RenderChartContent + + protected virtual void RenderChartContent( + ChartRenderInfo renderInfo, ChartXyVisualStyle xyStyle) + { + Graphics g = renderInfo.Graphics; + + if (ChartSeries.Count > 0) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + Point pt = GetLocalAdjustedPoint(Point.Empty); + + if (pt.IsEmpty == false) + g.TranslateTransform(pt.X, pt.Y); + + // Indicators on bottom + + if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse) + { + for (int i = ChartSeries.Count - 1; i >= 0; i--) + RenderIndicators(renderInfo, ChartSeries[i], false); + } + else + { + foreach (ChartSeries series in ChartSeries) + RenderIndicators(renderInfo, series, false); + } + + // Series data + + if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse) + { + for (int i = ChartSeries.Count - 1; i >= 0; i--) + RenderSeries(renderInfo, ChartSeries[i]); + } + else + { + foreach (ChartSeries series in ChartSeries) + RenderSeries(renderInfo, series); + } + + // Indicators on top + + if (SeriesDisplayOrder == SeriesDisplayOrder.Reverse) + { + for (int i = ChartSeries.Count - 1; i >= 0; i--) + RenderIndicators(renderInfo, ChartSeries[i], true); + } + else + { + foreach (ChartSeries series in ChartSeries) + RenderIndicators(renderInfo, series, true); + } + + if (pt.IsEmpty == false) + g.ResetTransform(); + + g.SmoothingMode = sm; + } + else + { + Rectangle scContentBounds = GetScrollBounds(ContentBounds); + Rectangle scDisplayBounds = GetDisplayBounds(scContentBounds); + + RenderEmptyText(g, xyStyle, scDisplayBounds); + } + } + + #region RenderIndicators + + private void RenderIndicators( + ChartRenderInfo renderInfo, ChartSeries series, bool onTop) + { + if (Visible == true) + { + if (Legend.ItemCheckAction != ItemCheckAction.ShowItem || series.IsDisplayed == true) + series.RenderIndicators(renderInfo, onTop); + } + } + + #endregion + + #region RenderSeries + + private void RenderSeries(ChartRenderInfo renderInfo, ChartSeries series) + { + if (Visible == true) + { + if (Legend.ItemCheckAction != ItemCheckAction.ShowItem || series.IsDisplayed == true) + series.Render(renderInfo); + } + } + + #endregion + + #endregion + + #region GetFigureBounds + + private Rectangle GetFigureBounds(Rectangle bounds, ContainerVisualStyle cStyle) + { + bounds = GetAdjustedBounds(bounds, cStyle.BorderThickness); + + Rectangle scBounds = GetScrollBounds(bounds); + + return (scBounds); + } + + #endregion + + #region GetXyImageBounds + + private Rectangle GetXyImageBounds(ChartXyVisualStyle xyStyle) + { + Rectangle scBbounds = GetScrollBounds(ScrollBounds); + + scBbounds = GetAdjustedBounds(scBbounds, xyStyle.BorderThickness); + + if (xyStyle.EnableImageScroll != Tbool.False) + { + scBbounds = GetScrollBounds(ScrollBoundsEx); + scBbounds = GetDisplayBounds(scBbounds); + } + + if (HScrollBar.Visible == true) + scBbounds.Height -= HScrollBar.Height; + + if (VScrollBar.Visible == true) + scBbounds.Width -= VScrollBar.Width; + + return (scBbounds); + } + + #endregion + + #region RenderGrid + + private void RenderGrid(ChartRenderInfo renderInfo, bool displayOnTop) + { + Rectangle scContentBounds = GetScrollBounds(ContentBounds); + + if (scContentBounds.Width > 0 && scContentBounds.Height > 0) + { + RenderGridLines(renderInfo, displayOnTop, AncillaryAxesX, AxisX); + RenderGridLines(renderInfo, displayOnTop, AncillaryAxesY, AxisY); + } + } + + #region RenderGridLines + + private void RenderGridLines(ChartRenderInfo renderInfo, + bool displayOnTop, ChartAxesCollection axes, ChartAxis axis) + { + foreach (ChartAxis ca in axes) + { + if (ca.Visible == true) + { + if (ca.MajorGridLines.DisplayOnTop == displayOnTop) + ca.MajorGridLines.Render(renderInfo); + + if (ca.MinorGridLines.DisplayOnTop == displayOnTop) + ca.MinorGridLines.Render(renderInfo); + } + } + + if (axis.MajorGridLines.DisplayOnTop == displayOnTop) + axis.MajorGridLines.Render(renderInfo); + + if (axis.MinorGridLines.DisplayOnTop == displayOnTop) + axis.MinorGridLines.Render(renderInfo); + } + + #endregion + + #endregion + + #region RenderReferences + + private void RenderReferences(ChartRenderInfo renderInfo, bool displayOnTop) + { + Rectangle scContentBounds = GetScrollBounds(ContentBounds); + + if (scContentBounds.Width > 0 && scContentBounds.Height > 0) + { + RenderReferenceLines(renderInfo, displayOnTop, AncillaryAxesX, AxisX); + RenderReferenceLines(renderInfo, displayOnTop, AncillaryAxesY, AxisY); + } + } + + #region RenderReferenceLines + + private void RenderReferenceLines(ChartRenderInfo renderInfo, + bool displayOnTop, ChartAxesCollection axes, ChartAxis axis) + { + foreach (ChartAxis ca in axes) + { + foreach (ReferenceLine line in ca.ReferenceLines) + RenderReferenceLine(renderInfo, line, displayOnTop); + } + + if (axis.Visible == true) + { + foreach (ReferenceLine line in axis.ReferenceLines) + RenderReferenceLine(renderInfo, line, displayOnTop); + } + } + + #region RenderReferenceLine + + private void RenderReferenceLine( + ChartRenderInfo renderInfo, ReferenceLine line, bool displayOnTop) + { + if (line.Visible == true) + { + if (line.ShowCheckBoxInLegend == false || line.CheckedInLegend == true) + { + if (line.DisplayLineOnTop == displayOnTop) + line.RenderLine(renderInfo); + + if (line.DisplayTextOnTop == displayOnTop) + line.RenderLineText(renderInfo); + } + } + } + + #endregion + + #endregion + + #endregion + + #region RenderPointLabels + + private void RenderPointLabels(Graphics g) + { + Point pt = GetLocalAdjustedPoint(Point.Empty); + + List pointLabels = UpdatePointLabels(g); + + if (pointLabels.Count > 0) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + RenderPointConnector(g, pt, pointLabels); + RenderPointLabel(g, pt, pointLabels); + + g.SmoothingMode = sm; + } + } + + #region UpdatePointLabels + + private List UpdatePointLabels(Graphics g) + { + if (_PointLabels == null) + { + List labelGroups = new List(); + + foreach (ChartSeries series in ChartSeries) + { + if (series.IsDisplayed == true) + { + List list = series.GetPointLabels(g); + + if (list != null) + { + PointLabelGroup plg = new PointLabelGroup(series, list); + + labelGroups.Add(plg); + } + } + } + + UpdatePointLabelsEx(g, labelGroups); + + FlockAlign falign = new FlockAlign(labelGroups); + + ContainerVisualStyle cstyle = GetEffectiveContainerStyle(); + + Rectangle r = GetAdjustedBounds(ContentBoundsEx, cstyle.BorderThickness); + + falign.Iterate(r, DataLabelOverlapMode); + + _PointLabels = labelGroups; + } + + return (_PointLabels); + } + + #region UpdatePointLabelsEx + + private void UpdatePointLabelsEx(Graphics g, List labelGroups) + { + ChartControl control = ChartControl; + + if (control.IsPointLabelUpdateHooked == true) + { + for (int i = 0; i < labelGroups.Count; i++) + { + PointLabelGroup lg = labelGroups[i]; + List lps = lg.PointLabels; + + control.DoPointLabelUpdateEvent(this, lg.ChartSeries, lps); + + for (int j = 0; j < lps.Count; j++) + { + PointLabel pl = lps[j]; + + if (pl.IsFixedSize == false && pl.NeedsMeasured == true) + pl.LabelSize = lg.ChartSeries.MeasurePointLabel(g, pl); + } + } + } + } + + #endregion + + #endregion + + #region RenderPointConnector + + private void RenderPointConnector( + Graphics g, Point pt, List labelGroups) + { + ChartControl chartControl = ChartControl; + + foreach (PointLabelGroup lg in labelGroups) + { + ChartSeries series = lg.ChartSeries; + + foreach (PointLabel pl in lg.PointLabels) + { + if (pl.Visible == true && + pl.SeriesPoint.IsEmpty == false && pl.EdgePoint.IsEmpty == false) + { + DataLabelVisualStyle dstyle = series.GetPointLabelVisualStyle(pl); + ConnectorLineVisualStyle cstyle = dstyle.ConnectorLineStyle; + + if (dstyle.DrawConnector == Tbool.True && cstyle.LinePattern != LinePattern.None) + { + if (pl.Bounds.IsEmpty == false) + { + Rectangle r = pl.Bounds; + r.Offset(pt); + + Point pt1 = pl.Point; + pt1.Offset(pt); + + Point pt2 = pl.EdgePoint; + pt2.Offset(pt); + + bool isChpt = IsCrosshairSeriesPoint(null, pt1); + + if (cstyle.Origin == ConnectorOrigin.Edge) + { + int offset = Math.Max( + pl.SeriesPoint.PointSize.Width, + pl.SeriesPoint.PointSize.Height) / 2 + 1; + + double radians = MathHelper.ToRadians(pl.Angle); + + int x = (int)(Math.Cos(radians) * offset); + int y = (int)(Math.Sin(radians) * offset); + + pt1.X += (int)(Math.Cos(radians) * offset); + pt1.Y += (int)(Math.Sin(radians) * offset); + } + + if (r.Contains(pt1) == false) + { + if (chartControl.DoPreRenderPointConnectorEvent(g, this, series, pl, isChpt, pt1, pt2) == false) + { + using (Pen pen = new Pen(cstyle.LineColor, Dpi.Width(cstyle.LineWidth))) + { + if (cstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)cstyle.LinePattern; + + g.DrawLine(pen, pt1, pt2); + } + + chartControl.DoPostRenderPointConnectorEvent(g, this, series, pl, isChpt, pt1, pt2); + } + } + } + } + } + } + } + } + + #endregion + + #region RenderPointLabel + + private void RenderPointLabel( + Graphics g, Point pt, List labelGroups) + { + ChartControl chartControl = ChartControl; + + foreach (PointLabelGroup lg in labelGroups) + { + ChartSeries series = lg.ChartSeries; + + foreach (PointLabel pl in lg.PointLabels) + { + if (pl.Visible == true && pl.SeriesPoint.IsEmpty == false) + { + Rectangle r = pl.Bounds; + + if (r.IsEmpty == false) + { + DataLabelVisualStyle dstyle = series.GetPointLabelVisualStyle(pl); + + Point pt1 = r.Location; + pt1.Offset(pt); + r.Location = pt1; + + Point pt2 = pl.Point; + pt2.Offset(pt); + + bool isChpt = IsCrosshairSeriesPoint(null, pt2); + + if (chartControl.DoPreRenderPointLabelEvent(g, this, series, pl, isChpt, r) == false) + { + using (StringFormat sf = new StringFormat()) + { + dstyle.GetStringFormatFlags(sf); + + Color textColor = dstyle.TextColor; + Color borderColor = dstyle.BorderColor; + Background background = dstyle.Background; + LinePattern borderPattern = dstyle.BorderPattern; + + if (isChpt == true) + { + if (dstyle.HighlightTextColor.IsEmpty == false) + textColor = dstyle.HighlightTextColor; + + if (dstyle.HighlightBorderColor.IsEmpty == false) + borderColor = dstyle.HighlightBorderColor; + + if (dstyle.HighlightBackground.IsEmpty == false) + background = dstyle.HighlightBackground; + + if (dstyle.HighlightBorderPattern != LinePattern.NotSet) + borderPattern = dstyle.HighlightBorderPattern; + } + + RenderPointLabelEx(g, lg, pl, r, textColor, + background, borderColor, dstyle.BorderThickness, borderPattern, dstyle, sf); + } + + chartControl.DoPostRenderPointLabelEvent(g, this, series, pl, isChpt, r); + } + } + } + } + } + } + + #region RenderPointLabelEx + + private void RenderPointLabelEx(Graphics g, PointLabelGroup lg, PointLabel pl, + Rectangle r, Color tcolor, Background background, Color bcolor, + int thickness, LinePattern pattern, DataLabelVisualStyle dstyle, StringFormat sf) + { + if (background.IsEmpty == false) + { + using (Brush hbr = background.GetBrush(r)) + g.FillRectangle(hbr, r); + } + + g.SmoothingMode = SmoothingMode.None; + + using (Pen hBorderPen = GetBorderPen(bcolor, thickness, pattern)) + { + if (hBorderPen != null) + g.DrawRectangle(hBorderPen, r); + } + + if (dstyle.DropShadow.Enabled == Tbool.True) + dstyle.DropShadow.RenderDropShadow(g, r, true, true); + + RotateDegrees rotateDegrees = lg.ChartSeries.GetRotateDegrees(dstyle); + float angle = GetRotateAngle(rotateDegrees); + + r.Size = pl.LabelSize; + + Point ptc = new Point( + r.X + pl.Bounds.Width / 2, + r.Y + pl.Bounds.Height / 2); + + if (angle != 0) + { + g.TranslateTransform(ptc.X, ptc.Y); + g.RotateTransform(angle); + + r.X = -((r.Width + dstyle.Padding.Horizontal) / 2); + r.Y = -((r.Height + dstyle.Padding.Vertical) / 2); + + if (angle == 90) + r.Y--; + + else if (angle == 270) + r.X--; + + r.X += dstyle.Padding.Left; + r.Y += dstyle.Padding.Top; + } + else + { + if (dstyle.HasBorder == true) + { + r.X += dstyle.BorderThickness; + r.Y += dstyle.BorderThickness; + } + + r.X += dstyle.Padding.Left; + r.Y += dstyle.Padding.Top; + } + + using (Brush htbr = new SolidBrush(tcolor)) + g.DrawString(pl.Label, dstyle.Font, htbr, r, sf); + + if (angle != 0) + g.ResetTransform(); + } + + #region GetRotateAngle + + private float GetRotateAngle(RotateDegrees rotateDegrees) + { + switch (rotateDegrees) + { + case RotateDegrees.Rotate90: + return (90); + + case RotateDegrees.Rotate180: + return (180); + + case RotateDegrees.Rotate270: + return (270); + + default: + return (0); + } + } + + #endregion + + #region GetBorderPen + + private Pen GetBorderPen(Color color, int thickness, LinePattern pattern) + { + Pen pen = null; + + if (pattern != LinePattern.None && pattern != LinePattern.NotSet && + color.IsEmpty == false && thickness > 0) + { + pen = new Pen(color, Dpi.Width(thickness)); + + pen.Alignment = PenAlignment.Inset; + + if (pattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)pattern; + } + + return (pen); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region RenderAxes + + private void RenderAxes(ChartRenderInfo renderInfo, + ChartAxesCollection axes, ChartAxis axis) + { + foreach (ChartAxis ca in axes) + { + if (ca.Visible == true) + ca.Render(renderInfo); + } + + if (axis.Visible == true) + axis.Render(renderInfo); + } + + #endregion + + #region RenderCrosshair + + #region GetCrosshairBounds + + private Rectangle GetCrosshairBounds(ContainerVisualStyle cstyle) + { + ChartCrosshair crosshair = ChartCrosshair; + + Rectangle bounds = GetScrollBounds(ContentBounds); + + if (cstyle.BorderThickness.IsEmpty == false) + { + bounds.X += Dpi.Width(cstyle.BorderThickness.Left); + bounds.Width -= Dpi.Width(cstyle.BorderThickness.Horizontal); + + bounds.Y += Dpi.Height(cstyle.BorderThickness.Top); + bounds.Height -= Dpi.Height(cstyle.BorderThickness.Vertical); + } + + if (HScrollBar.Visible == true) + bounds.Height -= (HScrollBar.Height + 1); + + if (VScrollBar.Visible == true) + bounds.Width -= (VScrollBar.Width + 1); + + return (bounds); + } + + #endregion + + #region GetCrosshairPoints + + private List GetCrosshairPoints(Rectangle bounds, Point pt) + { + List cps; + + if (ChartCrosshair.AxisOrientation == AxisOrientation.X) + cps = GetCrosshairPointsX(pt, bounds); + else + cps = GetCrosshairPointsY(pt, bounds); + + _NearestCrosshairPoint = null; + + if (cps != null && cps.Count > 0) + { + if (ChartCrosshair.CrosshairLabelMode == CrosshairLabelMode.NearestSeries) + _NearestCrosshairPoint = GetNearestPoint(cps, pt, ChartCrosshair.AxisOrientation); + } + + return (cps); + } + + #endregion + + #region RenderCrosshair + + internal void RenderCrosshairLines(Graphics g, + Rectangle bounds, Point pt, CrosshairVisualStyle cstyle) + { + if (ChartCrosshair.AxisOrientation == AxisOrientation.X) + RenderCrosshairX(g, bounds, pt, cstyle); + else + RenderCrosshairY(g, bounds, pt, cstyle); + } + + #region RenderCrosshairX + + private void RenderCrosshairX(Graphics g, + Rectangle bounds, Point pt, CrosshairVisualStyle cstyle) + { + ChartCrosshair crosshair = ChartCrosshair; + + List cps = _CrosshairSeriesPoints; + + if (crosshair.ShowValueXLine == true) + RenderCrosshairLineX(g, pt, bounds, cstyle); + + if (crosshair.ShowValueXLabels == true) + RenderCrosshairLabelX(g, pt); + + if (crosshair.ShowValueYLine == true || crosshair.ShowValueYLabels == true) + { + if (crosshair.CrosshairLabelMode == CrosshairLabelMode.NearestSeries) + { + CrosshairPoint mcp = _NearestCrosshairPoint; + + if (mcp != null) + { + if (crosshair.ShowValueYLine == true) + RenderCrosshairLineY(g, mcp.Point, bounds, cstyle); + + if (crosshair.ShowValueYLabels == true) + RenderCrosshairLabelY(g, mcp); + } + } + else + { + foreach (CrosshairPoint cp in cps) + { + if (crosshair.ShowValueYLine == true) + RenderCrosshairLineY(g, cp.Point, bounds, cstyle); + + if (crosshair.ShowValueYLabels == true) + RenderCrosshairLabelY(g, cp); + } + } + } + } + + #region GetCrosshairPointsX + + private List GetCrosshairPointsX(Point pt, Rectangle bounds) + { + List cps = new List(); + + for (int i = 0; i < ChartSeries.Count; i++) + { + ChartSeries series = ChartSeries[i]; + + if (series.IsDisplayed == true && series.CrosshairEnabled != Tbool.False) + { + if (series.SeriesPoints.Count > 0) + { + SortedSeriesPoints ssp = series.GetSortedSeriesPoints(this); + + ChartAxis axis = (series.IsRotated == true) + ? series.AxisY ?? AxisY : series.AxisX ?? AxisX; + + TickmarkLayout layout = axis.TickmarkLayout; + + if (layout.Ticks != null && layout.Ticks.Length > 0) + { + Size msize = GetCrosshairMarkerSize(series); + + for (int j = 0; j < ssp.Count; j++) + SetCrosshairPointX(cps, series, ssp, j, msize, pt, bounds); + } + } + } + } + + return (cps); + } + + #region SetCrosshairPointX + + private void SetCrosshairPointX(List cps, ChartSeries series, + SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds) + { + SeriesPoint sp = ssp[index]; + + if (sp.IsEmpty == false) + { + int vindex = 0; + bool descending = false; + + Point spt = Point.Empty; + Point lpt = GetLocalAdjustedPoint(spt); + + switch (series.SeriesType) + { + case SeriesType.VerticalDot: + spt = GetDataPointEx(series, sp, -1); + spt.Offset(lpt); + + spt.Y -= (msize.Height * ssp.CountArray[index]); + spt.Y += (msize.Height / 2); + break; + + case SeriesType.HorizontalDot: + object x1 = GetDataPointValueX(series, sp); + + spt = GetPointFromValue(series, 0, x1); + spt.Offset(lpt); + + spt.X += (msize.Width * ssp.CountArray[index]); + spt.X -= (msize.Width / 2); + break; + + case SeriesType.VerticalBar: + spt = GetDataPointEx(series, sp, 0); + spt.Offset(lpt); + + spt.X += series.BarOffset; + + int yStart = series.GetVBarStart(this, sp) + lpt.Y; + + descending = (spt.Y > yStart); + + if (sp.ValueY.Length > 1) + { + AddCrosshairPointX(cps, series, + ssp, index, sp, 0, spt, msize, pt, bounds, descending); + + spt.Y = yStart; + + vindex = 1; + descending = !descending; + } + break; + + case SeriesType.HorizontalBar: + spt = GetDataPointEx(series, sp, 0); + spt.Offset(lpt); + + spt.Y += series.BarOffset; + + int xStart = series.GetHBarStart(this, sp) + lpt.X; + + descending = (spt.X < xStart); + + if (sp.ValueY.Length > 1) + { + AddCrosshairPointX(cps, series, + ssp, index, sp, 0, spt, msize, pt, bounds, descending); + + spt.X = xStart; + + vindex = 1; + descending = !descending; + } + break; + + case SeriesType.VerticalHiLoBar: + SetCrosshairPointVHiLoX(cps, series, ssp, index, msize, pt, bounds); + return; + + case SeriesType.HorizontalHiLoBar: + SetCrosshairPointHHiLoX(cps, series, ssp, index, msize, pt, bounds); + return; + + case SeriesType.Point: + for (int i = 0; i < sp.ValueY.Length; i++) + { + spt = GetDataPointEx(series, sp, i); + spt.Offset(lpt); + + AddCrosshairPointX(cps, series, + ssp, index, sp, i, spt, msize, pt, bounds, descending); + } + return; + + default: + spt = GetDataPoint(series, sp, 0); + break; + } + + AddCrosshairPointX(cps, series, + ssp, index, sp, vindex, spt, msize, pt, bounds, descending); + } + } + + #region SetCrosshairPointVHiLoX + + private void SetCrosshairPointVHiLoX(List cps, + ChartSeries series, SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds) + { + Point spt = Point.Empty; + Point lpt = GetLocalAdjustedPoint(spt); + + SeriesPoint sp = ssp[index]; + + spt = GetDataPointEx(series, sp, 0); + spt.X += (series.BarOffset + lpt.X); + + int[] values = GetVStockValues(series, sp); + + int v0, v1, v2, v3; + NormalizeStockValues(values, out v0, out v1, out v2, out v3); + + if (values[v2] != int.MinValue) + { + spt.Y = values[v2] + lpt.Y; + + AddCrosshairPointX(cps, series, + ssp, index, sp, v2, spt, msize, pt, bounds, false); + } + + if (values[v3] != int.MinValue) + { + spt.Y = values[v3] + lpt.Y; + + AddCrosshairPointX(cps, series, + ssp, index, sp, v3, spt, msize, pt, bounds, true); + } + + if (values[v2] == int.MinValue || values[v0] < values[v2]) + { + spt.Y = values[v0] + lpt.Y; + + AddCrosshairPointX(cps, series, + ssp, index, sp, v0, spt, msize, pt, bounds, false); + } + + if (values[v3] == int.MinValue || values[v1] > values[v3]) + { + spt.Y = values[v1] + lpt.Y; + + AddCrosshairPointX(cps, series, + ssp, index, sp, v1, spt, msize, pt, bounds, true); + } + } + + #region GetVStockValues + + private int[] GetVStockValues(ChartSeries series, SeriesPoint sp) + { + ChartAxis axis = series.AxisY ?? AxisY; + + int[] values = new int[4]; + + for (int i = 0; i < values.Length; i++) + { + if (i < sp.ValueY.Length) + values[i] = GetDataPointY(axis, sp.ValueY[i]); + else + values[i] = int.MinValue; + } + + return (values); + } + + #endregion + + #endregion + + #region SetCrosshairPointHHiLoX + + private void SetCrosshairPointHHiLoX(List cps, + ChartSeries series, SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds) + { + Point spt = Point.Empty; + Point lpt = GetLocalAdjustedPoint(spt); + + SeriesPoint sp = ssp[index]; + + spt = GetDataPointEx(series, sp, 0); + spt.Y += (series.BarOffset + lpt.Y); + + int[] values = GetHStockValues(series, sp); + + int v0, v1, v2, v3; + NormalizeStockValues(values, out v0, out v1, out v2, out v3); + + if (values[v2] != int.MinValue) + { + spt.X = values[v2] + lpt.X; + + AddCrosshairPointX(cps, series, + ssp, index, sp, v2, spt, msize, pt, bounds, true); + } + + if (values[v3] != int.MinValue) + { + spt.X = values[v3] + lpt.X; + + AddCrosshairPointX(cps, series, + ssp, index, sp, v3, spt, msize, pt, bounds, false); + } + + if (values[v2] == int.MinValue || values[v0] < values[v2]) + { + spt.X = values[v0] + lpt.X; + + AddCrosshairPointX(cps, series, + ssp, index, sp, v0, spt, msize, pt, bounds, true); + } + + if (values[v3] == int.MinValue || values[v1] > values[v3]) + { + spt.X = values[v1] + lpt.X; + + AddCrosshairPointX(cps, series, + ssp, index, sp, v1, spt, msize, pt, bounds, false); + } + } + + #region GetHStockValues + + private int[] GetHStockValues(ChartSeries series, SeriesPoint sp) + { + ChartAxis axis = series.AxisX ?? AxisX; + + int[] values = new int[4]; + + for (int i = 0; i < values.Length; i++) + { + if (i < sp.ValueY.Length) + values[i] = GetDataPointX(axis, sp.ValueY[i]); + else + values[i] = int.MinValue; + } + + return (values); + } + + #endregion + + #endregion + + #region NormalizeStockValues + + private void NormalizeStockValues(int[] values, + out int v0, out int v1, out int v2, out int v3) + { + v0 = 0; + v1 = 1; + v2 = 2; + v3 = 3; + + if (values[1] < values[0]) + { + v0 = 1; + v1 = 0; + } + + if (values[v3] != int.MinValue && values[v3] < values[v2]) + { + v2 = 3; + v3 = 2; + } + + if (values[v2] != int.MinValue) + { + if (values[v2] < values[v0]) + v0 = v2; + + if (values[v2] > values[v1]) + v1 = v2; + } + + if (values[v3] != int.MinValue) + { + if (values[v3] > values[v1]) + v1 = v3; + + if (values[v3] < values[v0]) + v0 = v3; + } + } + + #endregion + + #region AddCrosshairPointX + + private void AddCrosshairPointX(List cps, ChartSeries series, + SortedSeriesPoints ssp, int index, SeriesPoint sp, int vindex, Point spt, + Size msize, Point pt, Rectangle bounds, bool descending) + { + if (spt != Point.Empty && bounds.Contains(spt)) + { + int dx = ChartCrosshair.PointIntersectMargin; + + if (ChartCrosshair.PointIntersectMode == PointIntersectMode.Edge) + { + if (sp.PointSize.Width > 0) + dx += (sp.PointSize.Width / 2); + else + dx += (msize.Height / 2); + } + + if (spt.X >= pt.X - dx && spt.X <= pt.X + dx) + cps.Add(new CrosshairPoint(series, ssp, index, sp, vindex, spt, descending)); + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region RenderCrosshairY + + private void RenderCrosshairY(Graphics g, + Rectangle bounds, Point pt, CrosshairVisualStyle cstyle) + { + ChartCrosshair crosshair = ChartCrosshair; + + List cps = _CrosshairSeriesPoints; + + if (crosshair.ShowValueYLine == true) + RenderCrosshairLineY(g, pt, bounds, cstyle); + + if (crosshair.ShowValueYLabels == true) + RenderCrosshairLabelY(g, pt); + + if (crosshair.ShowValueXLine == true || crosshair.ShowValueXLabels == true) + { + if (crosshair.CrosshairLabelMode == CrosshairLabelMode.NearestSeries) + { + CrosshairPoint mcp = _NearestCrosshairPoint; + + if (mcp != null) + { + if (crosshair.ShowValueXLine == true) + RenderCrosshairLineX(g, mcp.Point, bounds, cstyle); + + if (crosshair.ShowValueXLabels == true) + RenderCrosshairLabelX(g, mcp); + } + } + else + { + foreach (CrosshairPoint cp in cps) + { + if (crosshair.ShowValueXLine == true) + RenderCrosshairLineX(g, cp.Point, bounds, cstyle); + + if (crosshair.ShowValueXLabels == true) + RenderCrosshairLabelX(g, cp); + } + } + } + } + + #region GetCrosshairPointsY + + private List GetCrosshairPointsY(Point pt, Rectangle bounds) + { + List cps = new List(); + + for (int i = 0; i < ChartSeries.Count; i++) + { + ChartSeries series = ChartSeries[i]; + + if (series.IsDisplayed == true && series.CrosshairEnabled != Tbool.False) + { + if (series.SeriesPoints.Count > 0) + { + SortedSeriesPoints ssp = series.GetSortedSeriesPoints(this); + + ChartAxis axis = series.AxisX ?? AxisX; + TickmarkLayout layout = axis.TickmarkLayout; + + if (layout.Ticks != null && layout.Ticks.Length > 0) + { + Size msize = GetCrosshairMarkerSize(series); + + for (int j = 0; j < ssp.Count; j++) + SetCrosshairPointY(cps, series, ssp, j, msize, pt, bounds); + } + } + } + } + + return (cps); + } + + #region SetCrosshairPointY + + private void SetCrosshairPointY(List cps, ChartSeries series, + SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds) + { + SeriesPoint sp = ssp[index]; + + if (sp.IsEmpty == false) + { + int vindex = 0; + bool descending = false; + + Point spt = Point.Empty; + Point lpt = GetLocalAdjustedPoint(spt); + + switch (series.SeriesType) + { + case SeriesType.VerticalDot: + spt = GetDataPointEx(series, sp, -1); + spt.Offset(lpt); + + spt.Y -= (msize.Height * ssp.CountArray[index] - msize.Height / 2); + break; + + case SeriesType.HorizontalDot: + object x1 = GetDataPointValueX(series, sp); + + spt = GetPointFromValue(series, 0, x1); + spt.Offset(lpt); + + spt.X += (msize.Width * ssp.CountArray[index] - msize.Width / 2); + break; + + case SeriesType.VerticalBar: + spt = GetDataPointEx(series, sp, 0); + spt.Offset(lpt); + + spt.X += series.BarOffset; + + int yStart = series.GetVBarStart(this, sp) + lpt.Y; + + descending = (spt.Y > yStart); + + if (sp.ValueY.Length > 1) + { + AddCrosshairPointY(cps, series, + ssp, index, sp, 0, spt, msize, pt, bounds, descending); + + spt.Y = yStart; + + vindex = 1; + descending = !descending; + } + break; + + case SeriesType.HorizontalBar: + spt = GetDataPointEx(series, sp, 0); + spt.Offset(lpt); + + spt.Y += series.BarOffset; + + int xStart = series.GetHBarStart(this, sp) + lpt.X; + + descending = (spt.X < xStart); + + if (sp.ValueY.Length > 1) + { + AddCrosshairPointX(cps, series, + ssp, index, sp, 0, spt, msize, pt, bounds, descending); + + spt.X = xStart; + + vindex = 1; + descending = !descending; + } + break; + + case SeriesType.VerticalHiLoBar: + SetCrosshairPointVHiLoY(cps, series, ssp, index, msize, pt, bounds); + return; + + case SeriesType.HorizontalHiLoBar: + SetCrosshairPointHHiLoY(cps, series, ssp, index, msize, pt, bounds); + return; + + case SeriesType.Point: + for (int i = 0; i < sp.ValueY.Length; i++) + { + spt = GetDataPointEx(series, sp, i); + spt.Offset(lpt); + + AddCrosshairPointY(cps, series, + ssp, index, sp, i, spt, msize, pt, bounds, descending); + } + return; + + default: + spt = GetDataPoint(series, sp, 0); + break; + } + + AddCrosshairPointY(cps, series, + ssp, index, sp, vindex, spt, msize, pt, bounds, descending); + } + } + + #region SetCrosshairPointVHiLoY + + private void SetCrosshairPointVHiLoY(List cps, + ChartSeries series, SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds) + { + Point spt = Point.Empty; + Point lpt = GetLocalAdjustedPoint(spt); + + SeriesPoint sp = ssp[index]; + + spt = GetDataPointEx(series, sp, 0); + spt.X += (series.BarOffset + lpt.X); + + int[] values = GetVStockValues(series, sp); + + int v0, v1, v2, v3; + NormalizeStockValues(values, out v0, out v1, out v2, out v3); + + if (values[v2] != int.MinValue) + { + spt.Y = values[v2] + lpt.Y; + + AddCrosshairPointY(cps, series, + ssp, index, sp, v2, spt, msize, pt, bounds, false); + } + + if (values[v3] != int.MinValue) + { + spt.Y = values[v3] + lpt.Y; + + AddCrosshairPointY(cps, series, + ssp, index, sp, v3, spt, msize, pt, bounds, true); + } + + if (values[v2] == int.MinValue || values[v0] < values[v2]) + { + spt.Y = values[v0] + lpt.Y; + + AddCrosshairPointY(cps, series, + ssp, index, sp, v0, spt, msize, pt, bounds, false); + } + + if (values[v3] == int.MinValue || values[v1] > values[v3]) + { + spt.Y = values[v1] + lpt.Y; + + AddCrosshairPointY(cps, series, + ssp, index, sp, v1, spt, msize, pt, bounds, true); + } + } + + #endregion + + #region SetCrosshairPointHHiLoY + + private void SetCrosshairPointHHiLoY(List cps, + ChartSeries series, SortedSeriesPoints ssp, int index, Size msize, Point pt, Rectangle bounds) + { + Point spt = Point.Empty; + Point lpt = GetLocalAdjustedPoint(spt); + + SeriesPoint sp = ssp[index]; + + spt = GetDataPointEx(series, sp, 0); + spt.Y += (series.BarOffset + lpt.Y); + + int[] values = GetHStockValues(series, sp); + + int v0, v1, v2, v3; + NormalizeStockValues(values, out v0, out v1, out v2, out v3); + + if (values[v2] != int.MinValue) + { + spt.X = values[v2] + lpt.X; + + AddCrosshairPointY(cps, series, + ssp, index, sp, v2, spt, msize, pt, bounds, true); + } + + if (values[v3] != int.MinValue) + { + spt.X = values[v3] + lpt.X; + + AddCrosshairPointY(cps, series, + ssp, index, sp, v3, spt, msize, pt, bounds, false); + } + + if (values[v2] == int.MinValue || values[v0] < values[v2]) + { + spt.X = values[v0] + lpt.X; + + AddCrosshairPointY(cps, series, + ssp, index, sp, v0, spt, msize, pt, bounds, true); + } + + if (values[v3] == int.MinValue || values[v1] > values[v3]) + { + spt.X = values[v1] + lpt.X; + + AddCrosshairPointY(cps, series, + ssp, index, sp, v1, spt, msize, pt, bounds, false); + } + } + + #endregion + + #region AddCrosshairPointY + + private void AddCrosshairPointY(List cps, ChartSeries series, + SortedSeriesPoints ssp, int index, SeriesPoint sp, int vindex, Point spt, + Size msize, Point pt, Rectangle bounds, bool descending) + { + if (spt != Point.Empty && bounds.Contains(spt)) + { + int dy = ChartCrosshair.PointIntersectMargin; + + if (ChartCrosshair.PointIntersectMode == PointIntersectMode.Edge) + { + if (sp.PointSize.Height > 0) + dy += (sp.PointSize.Height / 2); + else + dy += (msize.Height / 2); + } + + if (spt.Y >= pt.Y - dy && spt.Y <= pt.Y + dy) + cps.Add(new CrosshairPoint(series, ssp, index, sp, vindex, spt, descending)); + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetCrosshairMarkerSize + + private Size GetCrosshairMarkerSize(ChartSeries series) + { + Size msize = Size.Empty; + + if (series.SeriesType == SeriesType.VerticalDot || + series.SeriesType == SeriesType.HorizontalDot) + { + msize = GetMaxDotPlotMarkerSize(); + } + else if (series.IsBarSeries == true) + { + msize = new Size(series.BarWidth, Dpi.Height5); + } + else + { + Image marker = series.PointMarkerImage; + + if (marker != null) + msize = marker.Size; + } + + return (msize); + } + + #endregion + + #region RenderCrosshairLineX + + private void RenderCrosshairLineX(Graphics g, + Point pt, Rectangle bounds, CrosshairVisualStyle cstyle) + { + Point pt1 = new Point(pt.X, bounds.Y); + Point pt2 = new Point(pt.X, bounds.Bottom - 1); + + ChartLineVisualStyle lstyle = cstyle.ValueXLineStyle; + + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Width(lstyle.LineWidth))) + { + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + g.DrawLine(pen, pt1, pt2); + } + } + + #endregion + + #region RenderCrosshairLineY + + private void RenderCrosshairLineY(Graphics g, + Point pt, Rectangle bounds, CrosshairVisualStyle cstyle) + { + Point pt1 = new Point(bounds.X, pt.Y); + Point pt2 = new Point(bounds.Right - 1, pt.Y); + + ChartLineVisualStyle lstyle = cstyle.ValueYLineStyle; + + using (Pen pen = new Pen(lstyle.LineColor, Dpi.Height(lstyle.LineWidth))) + { + pen.DashStyle = (DashStyle)lstyle.LinePattern; + + g.DrawLine(pen, pt1, pt2); + } + } + + #endregion + + #region RenderCrosshairLabelX + + private void RenderCrosshairLabelX(Graphics g, Point pt) + { + RenderAxesCrosshairLabelXy(g, pt, AncillaryAxesX, AxisX); + } + + private void RenderCrosshairLabelX(Graphics g, CrosshairPoint cp) + { + ChartAxis axis = cp.ChartSeries.AxisX ?? AxisX; + + if (axis != null) + axis.RenderCrosshairLabel(g, cp); + } + + #endregion + + #region RenderCrosshairLabelY + + private void RenderCrosshairLabelY(Graphics g, Point pt) + { + RenderAxesCrosshairLabelXy(g, pt, AncillaryAxesY, AxisY); + } + + private void RenderCrosshairLabelY(Graphics g, CrosshairPoint cp) + { + ChartAxis axis = cp.ChartSeries.AxisY ?? AxisY; + + if (axis != null) + axis.RenderCrosshairLabel(g, cp); + } + + #endregion + + #region RenderAxesCrosshairLabelXy + + private void RenderAxesCrosshairLabelXy(Graphics g, + Point pt, ChartAxesCollection axes, ChartAxis axis) + { + foreach (ChartAxis ca in axes) + { + if (ca.Visible == true) + ca.RenderCrosshairLabel(g, pt); + } + + if (axis.Visible == true) + axis.RenderCrosshairLabel(g, pt); + } + + #endregion + + #region GetNearestPoint + + private CrosshairPoint GetNearestPoint( + List cps, Point pt, AxisOrientation orientation) + { + CrosshairPoint minPoint = null; + + int minValue = int.MaxValue; + int minValue2 = int.MaxValue; + + bool comp = (orientation == AxisOrientation.Y); + + foreach (CrosshairPoint cp in cps) + { + Point cpt = cp.Point; + + int dv = Math.Abs((comp == false) ? (cpt.Y - pt.Y) : (cpt.X - pt.X)); + int dv2 = Math.Abs((comp == true) ? (cpt.Y - pt.Y) : (cpt.X - pt.X)); + + if (dv < minValue) + { + minValue = dv; + minValue2 = dv2; + + minPoint = cp; + } + else if (dv == minValue) + { + if (dv2 < minValue2) + { + minValue2 = dv2; + minPoint = cp; + } + } + } + + return (minPoint); + } + + #endregion + + #region GetFirstValue + + private object GetFirstValue(TickmarkLayout layout) + { + for (int i = 0; i < layout.Ticks.Length; i++) + { + TickmarkTick tick = layout.Ticks[i]; + + if (tick.LabelIndex >= 0) + return (tick.Value); + } + + return (null); + } + + #endregion + + #region GetLastValue + + private object GetLastValue(TickmarkLayout layout) + { + for (int i = layout.Ticks.Length - 1; i >= 0; i--) + { + TickmarkTick tick = layout.Ticks[i]; + + if (tick.LabelIndex >= 0) + return (tick.Value); + } + + return (null); + } + + #endregion + + #endregion + + #endregion + + #region RenderCrosshairLabels + + #region RenderCrosshairLabels + + private void RenderCrosshairLabels(Graphics g, + Rectangle bounds, Point pt, CrosshairVisualStyle cstyle) + { + if (ChartCrosshair.ShowCrosshairLabels == true) + { + if (ChartControl.DoRenderCrosshairLabelEvent(g, this, _CrosshairSeriesPoints, bounds, pt) == false) + { + if (_CrosshairSeriesPoints != null && _CrosshairSeriesPoints.Count > 0) + { + switch (ChartCrosshair.CrosshairLabelMode) + { + case CrosshairLabelMode.Common: + RenderCrosshairLabelCommon(g, bounds, pt, cstyle); + break; + + case CrosshairLabelMode.EachSeries: + RenderCrosshairLabelEach(g, bounds, pt, cstyle); + break; + + case CrosshairLabelMode.NearestSeries: + if (_NearestCrosshairPoint != null) + RenderCrosshairLabel(g, bounds, cstyle, _NearestCrosshairPoint); + break; + } + } + } + } + } + + #region RenderCrosshairLabelCommon + + private void RenderCrosshairLabelCommon(Graphics g, + Rectangle bounds, Point pt, CrosshairVisualStyle cstyle) + { + Hashtable gps = GetCrosshairLabelGroups(_CrosshairSeriesPoints); + + MeasureCrosshairLabelGroups(g, gps, bounds, cstyle); + + int markerWidth; + Rectangle cbounds = GetCrosshairCommonBounds(gps, bounds, pt, cstyle, out markerWidth); + + cbounds = GetAdjustedBounds(cbounds, cstyle.Margin); + + if (ChartControl.DoRenderCrosshairCalloutEvent(g, this, cbounds, pt, cstyle) == false) + DrawRoundRectangle(g, cbounds, cstyle); + + cbounds = GetAdjustedBounds(cbounds, cstyle.Padding); + + RenderCrosshairLabelGroups(g, gps, cbounds, cstyle); + } + + #region GetCrosshairLabelGroups + + private Hashtable GetCrosshairLabelGroups(List cps) + { + Hashtable gps = new Hashtable(); + + foreach (CrosshairPoint cp in cps) + { + ChartAxis axis; + + if (ChartCrosshair.AxisOrientation == AxisOrientation.X) + axis = cp.ChartSeries.AxisX ?? AxisX; + else + axis = cp.ChartSeries.AxisY ?? AxisY; + + CrosshairGroup group = gps[axis] as CrosshairGroup; + + if (group == null) + { + group = new CrosshairGroup(); + + group.Cps = new List(); + group.Text = GetCrosshairHeader(cp, cps); + + gps[axis] = group; + } + + group.Cps.Add(cp); + } + + return (gps); + } + + #endregion + + #region MeasureCrosshairLabelGroups + + private void MeasureCrosshairLabelGroups(Graphics g, + Hashtable gps, Rectangle bounds, CrosshairVisualStyle cstyle) + { + bool groupHeader = ChartCrosshair.ShowGroupHeaders; + + foreach (DictionaryEntry pair in gps) + { + CrosshairGroup group = (CrosshairGroup)pair.Value; + + if (groupHeader == true) + MeasureCrosshairGroupHeader(g, group, bounds, cstyle); + + MeasureCrosshairCommonLabels(g, group, bounds, cstyle, groupHeader ? null : group.Text); + } + } + + #region MeasureCrosshairGroupHeader + + private void MeasureCrosshairGroupHeader(Graphics g, + CrosshairGroup group, Rectangle bounds, CrosshairVisualStyle cstyle) + { + if (string.IsNullOrEmpty(group.Text) == false) + { + SizeF sizef = g.MeasureString(group.Text, cstyle.GroupHeaderFont, bounds.Width); + + group.TextSize = new Size((int)sizef.Width + 1, (int)sizef.Height + 1); + } + } + + #endregion + + #region MeasureCrosshairCommonLabels + + private void MeasureCrosshairCommonLabels(Graphics g, + CrosshairGroup group, Rectangle bounds, CrosshairVisualStyle cstyle, string header) + { + group.LabelSize = Size.Empty; + group.MarkerWidth = 0; + + foreach (CrosshairPoint cp in group.Cps) + { + Size markerSize = Size.Empty; + + Image marker = cp.ChartSeries.PointMarkerImage; + + if (marker != null) + { + markerSize = marker.Size; + + if (marker.Width > group.MarkerWidth) + group.MarkerWidth = marker.Width; + } + + MeasureCrosshairLabel(g, bounds, cp, cstyle, header, false); + + if (cp.TextSize.IsEmpty == false) + { + group.LabelSize.Height += Math.Max(markerSize.Height, cp.TextSize.Height); + + if (markerSize.Width + cp.TextSize.Width > group.LabelSize.Width) + group.LabelSize.Width = markerSize.Width + cp.TextSize.Width; + } + } + } + + #endregion + + #endregion + + #region GetCrosshairCommonBounds + + private Rectangle GetCrosshairCommonBounds(Hashtable gps, + Rectangle bounds, Point pt, CrosshairVisualStyle cstyle, out int markerWidth) + { + markerWidth = 0; + + Size totalSize = Size.Empty; + + foreach (DictionaryEntry pair in gps) + { + CrosshairGroup group = (CrosshairGroup)pair.Value; + + totalSize.Width = Math.Max(totalSize.Width, group.TextSize.Width); + totalSize.Height += (group.TextSize.Height + Dpi.Width4); + + foreach (CrosshairPoint cp in group.Cps) + { + Size markerSize = Size.Empty; + + Image marker = cp.ChartSeries.PointMarkerImage; + + if (marker != null) + markerSize = Dpi.Size(marker.Size); + + markerWidth = Math.Max(markerWidth, markerSize.Width); + + totalSize.Width = Math.Max(totalSize.Width, cp.TextSize.Width); + totalSize.Height += (Math.Max(markerSize.Height, cp.TextSize.Height) + Dpi.Width4); + } + } + + totalSize.Width += markerWidth; + + totalSize.Width += (cstyle.Margin.Horizontal + cstyle.Padding.Horizontal + Dpi.Width4); + totalSize.Height += (cstyle.Margin.Horizontal + cstyle.Padding.Horizontal - Dpi.Width4); + + return (GetCrosshairLabelBounds(bounds, pt, totalSize)); + } + + #region GetCrosshairLabelBounds + + private Rectangle GetCrosshairLabelBounds( + Rectangle bounds, Point pt, Size size) + { + Rectangle r; + + int left = pt.X - bounds.X - Dpi.Width10; + int right = bounds.Right - pt.X - Dpi.Width10; + + if ((right >= size.Width) || (right > left)) + { + r = new Rectangle(pt.X + 10, pt.Y - size.Height, + size.Width, size.Height); + } + else + { + r = new Rectangle(pt.X - (size.Width + Dpi.Width10), + pt.Y - size.Height, size.Width, size.Height); + } + + r.Y -= Dpi.Height10; + + if (r.Y < ContentBounds.Y + Dpi.Height2) + r.Y = ContentBounds.Y + Dpi.Height2; + + return (r); + } + + #endregion + + #endregion + + #region RenderCrosshairLabelGroups + + private void RenderCrosshairLabelGroups(Graphics g, + Hashtable gps, Rectangle bounds, CrosshairVisualStyle cstyle) + { + using (Brush br = new SolidBrush(cstyle.GroupHeaderTextColor)) + { + foreach (DictionaryEntry pair in gps) + { + CrosshairGroup group = (CrosshairGroup)pair.Value; + + Rectangle r = bounds; + r.Height = group.TextSize.Height; + + if (string.IsNullOrEmpty(group.Text) == false) + { + g.DrawString(group.Text, cstyle.GroupHeaderFont, br, r); + + bounds.Y += (group.TextSize.Height + Dpi.Height4); + bounds.Height -= (group.TextSize.Height + Dpi.Height4); + } + + foreach (CrosshairPoint cp in group.Cps) + { + if (cp.TextSize.IsEmpty == false) + { + RenderCrosshairLabelItem(g, bounds, cp, cstyle); + + bounds.Y += (cp.TextSize.Height + Dpi.Height4); + bounds.Height -= (cp.TextSize.Height + Dpi.Height4); + } + } + } + } + } + + #endregion + + #endregion + + #region RenderCrosshairLabelEach + + private void RenderCrosshairLabelEach(Graphics g, + Rectangle bounds, Point pt, CrosshairVisualStyle cstyle) + { + List cps = _CrosshairSeriesPoints; + + foreach (CrosshairPoint cp in cps) + RenderCrosshairLabel(g, bounds, cstyle, cp); + } + + #endregion + + #region RenderCrosshairLabel + + private void RenderCrosshairLabel(Graphics g, + Rectangle bounds, CrosshairVisualStyle cstyle, CrosshairPoint cp) + { + string arg = GetCrosshairArgument(cp); + + MeasureCrosshairLabel(g, bounds, cp, cstyle, arg, true); + + if (cp.TextSize.IsEmpty == false) + { + Size markerSize = Size.Empty; + + if (ChartCrosshair.ShowCrosshairLabelMarkers == true) + { + Image marker = cp.ChartSeries.PointMarkerImage; + + if (marker != null) + markerSize = marker.Size; + } + + Size totalSize = new Size((markerSize.Width + cp.TextSize.Width), + Math.Max(markerSize.Height, cp.TextSize.Height) + Dpi.Height4); + + totalSize.Width += Dpi.Width(cstyle.Padding.Horizontal + 4); + totalSize.Height += Dpi.Height(cstyle.Padding.Vertical - 4); + + Point pt = cp.Point; + + if (ChartCrosshair.PointIntersectMode == PointIntersectMode.Edge) + { + if (cp.ChartSeries.SeriesType == SeriesType.VerticalDot) + pt.Y -= (cp.SeriesPoint.PointSize.Height / 2); + + else if (cp.ChartSeries.SeriesType == SeriesType.HorizontalDot) + pt.X += (cp.SeriesPoint.PointSize.Width / 2); + } + + Rectangle cbounds = GetCrosshairPointBounds(bounds, cp, pt, totalSize); + + DrawCrosshairCallout(g, cbounds, pt, cstyle); + + cbounds = GetAdjustedBounds(cbounds, cstyle.Padding); + + RenderCrosshairLabelItem(g, cbounds, cp, cstyle); + } + } + + #region GetCrosshairPointBounds + + private Rectangle GetCrosshairPointBounds( + Rectangle bounds, CrosshairPoint cp, Point pt, Size size) + { + Rectangle r; + + int n = size.Width / 5; + + int left = pt.X - bounds.X + n; + int right = bounds.Right - pt.X + n; + + if ((right >= size.Width) || (right > left)) + { + r = new Rectangle(pt.X - n, pt.Y - size.Height, + size.Width, size.Height); + } + else + { + r = new Rectangle(pt.X - (size.Width - n), + pt.Y - size.Height, size.Width, size.Height); + } + + r.Y -= Dpi.Height20; + + if (cp.ChartSeries.SeriesType == SeriesType.VerticalBar || + cp.ChartSeries.SeriesType == SeriesType.VerticalHiLoBar) + { + if (cp.IsDescending == true) + { + if (pt.Y + 20 + r.Height < Bounds.Bottom) + r.Y = pt.Y + Dpi.Height20; + } + } + else + { + if (r.Y < Bounds.Y + 2) + r.Y = pt.Y + Dpi.Height20; + } + + if (cp.ChartSeries.SeriesType == SeriesType.HorizontalBar || + cp.ChartSeries.SeriesType == SeriesType.HorizontalHiLoBar) + { + if (cp.IsDescending == true) + r.X = pt.X - (size.Width - n); + } + + if (r.Right > Bounds.Right - Dpi.Width2) + r.X = Bounds.Right - r.Width - Dpi.Width2; + + if (r.Left < Bounds.X + Dpi.Width2) + r.X = Bounds.X + Dpi.Width2; + + return (r); + } + + #endregion + + #endregion + + #endregion + + #region GetCrosshairHeader + + private string GetCrosshairHeader(CrosshairPoint cp, List cps) + { + string text = GetCrosshairArgument(cp); + + ChartControl.DoGetCrosshairLabelHeaderEvent(this, cp, cps, ref text); + + return (text); + } + + #endregion + + #region GetCrosshairArgument + + private string GetCrosshairArgument(CrosshairPoint cp) + { + AxisOrientation ao = ChartCrosshair.AxisOrientation; + + if (cp.ChartSeries.IsRotated == true) + { + ao = (ChartCrosshair.AxisOrientation == AxisOrientation.X) + ? AxisOrientation.Y : AxisOrientation.X; + } + + if (ao == AxisOrientation.X) + return (GetValueXText(cp.ChartSeries, cp.ValueX)); + + return (GetValueYText(cp.ChartSeries, cp.ValueY)); + } + + #endregion + + #region GetValueXText + + private string GetValueXText(ChartSeries series, object value) + { + ChartAxis axis = (series.IsRotated) + ? series.AxisY ?? AxisY : series.AxisX ?? AxisX; + + return (axis.GetCrosshairLabel( + value, axis.EffectiveCrosshairLabelStyle)); + } + + #endregion + + #region GetValueYText + + private string GetValueYText(ChartSeries series, object value) + { + ChartAxis axis = (series.IsRotated) + ? series.AxisX ?? AxisX : series.AxisY ?? AxisY; + + return (axis.GetCrosshairLabel( + value, axis.EffectiveCrosshairLabelStyle)); + } + + #endregion + + #region MeasureCrosshairLabel + + private void MeasureCrosshairLabel(Graphics g, + Rectangle bounds, CrosshairPoint cp, CrosshairVisualStyle cstyle, string arg, bool multiLine) + { + cp.Text = GetCrosshairItemText(cp, arg, multiLine); + + if (string.IsNullOrEmpty(cp.Text) == false) + { + SizeF sizef = g.MeasureString(cp.Text, cstyle.Font, bounds.Width); + + cp.TextSize = new Size((int)sizef.Width + 1, (int)sizef.Height + 1); + } + else + { + cp.TextSize = Size.Empty; + } + } + + #region GetCrosshairItemText + + private string GetCrosshairItemText(CrosshairPoint cp, string arg, bool multiLine) + { + string text = cp.ChartSeries.LegendText ?? cp.ChartSeries.Name ?? ""; + + if (String.IsNullOrEmpty(text) == false) + text += " "; + + if (arg != null) + { + if (multiLine == true && text.Length > 0) + text += "\n"; + + text += (arg + " : "); + } + + text += GetItemText(cp); + + ChartControl.DoGetCrosshairLabelItemEvent(this, cp, ref text); + + return (text); + } + + #region GetItemText + + private string GetItemText(CrosshairPoint cp) + { + AxisOrientation ao = ChartCrosshair.AxisOrientation; + + if (cp.ChartSeries.IsRotated == true) + { + ao = (ChartCrosshair.AxisOrientation == AxisOrientation.X) + ? AxisOrientation.Y : AxisOrientation.X; + } + + string text = (ao == AxisOrientation.X) + ? GetValueYText(cp.ChartSeries, cp.ValueY) + : GetValueXText(cp.ChartSeries, cp.ValueX); + + switch (cp.ChartSeries.SeriesType) + { + case SeriesType.HorizontalBar: + case SeriesType.VerticalBar: + return (GetBarText(cp, text)); + + case SeriesType.HorizontalHiLoBar: + case SeriesType.VerticalHiLoBar: + return (GetHiLoBarText(cp, text)); + + default: + return (text); + } + } + + #endregion + + #region GetBarText + + private string GetBarText(CrosshairPoint cp, string s1) + { + if (cp.ChartSeries.IsRotated == (ChartCrosshair.AxisOrientation == AxisOrientation.Y)) + { + if (cp.SeriesPoint.ValueY.Length > 1) + { + object v1 = cp.ValueY; + + ChartAxis axis = (cp.ChartSeries.IsRotated) + ? cp.ChartSeries.AxisX ?? AxisX : cp.ChartSeries.AxisY ?? AxisY; + + CrosshairValueVisualStyle lstyle = axis.EffectiveCrosshairLabelStyle; + + object v2 = cp.SeriesPoint.ValueY[1]; + + if (v2 != null) + { + string s2 = axis.GetCrosshairLabel(v2, lstyle); + + int y1 = GetDataPointX(axis, v1); + int y2 = GetDataPointX(axis, v2); + + if (y1 < y2) + return (s1 + " — " + s2); + + return (s2 + " — " + s1); + } + } + } + + return (s1); + } + + #endregion + + #region GetHiLoVBarText + + private string GetHiLoBarText(CrosshairPoint cp, string s1) + { + if (cp.ChartSeries.IsRotated == (ChartCrosshair.AxisOrientation == AxisOrientation.Y)) + { + if (cp.SeriesPoint.ValueY.Length > 1) + { + ChartAxis axis = (cp.ChartSeries.IsRotated) + ? cp.ChartSeries.AxisX ?? AxisX : cp.ChartSeries.AxisY ?? AxisY; + + CrosshairValueVisualStyle lstyle = axis.EffectiveCrosshairLabelStyle; + + s1 = axis.GetCrosshairLabel(cp.ValueY, lstyle); + } + } + + s1 = s1 + " (" + "HLCO"[cp.ValueIndex] + ")"; + + return (s1); + } + + #endregion + + #endregion + + #endregion + + #region RenderCrosshairLabelItem + + private void RenderCrosshairLabelItem(Graphics g, + Rectangle bounds, CrosshairPoint cp, CrosshairVisualStyle cstyle) + { + if (ChartControl.DoRenderCrosshairLabelItemEvent(g, this, cp, bounds, cstyle) == false) + { + Rectangle r = RenderCrosshairLabelMarker(g, bounds, cp); + + Color color = cstyle.TextColor; + + if (color.IsEmpty == true) + { + color = cp.ChartSeries.GetLegendItemColor(); + + color = Color.FromArgb(255, color); + } + + using (Brush lbr = new SolidBrush(color)) + g.DrawString(cp.Text, cstyle.Font, lbr, r); + } + } + + #region RenderCrosshairLabelMarker + + private Rectangle RenderCrosshairLabelMarker( + Graphics g, Rectangle r, CrosshairPoint cp) + { + if (ChartCrosshair.ShowCrosshairLabelMarkers == true) + { + Image image = cp.ChartSeries.PointMarkerImage; + + if (image != null) + { + Rectangle t = r; + + Size isize = image.Size; + + if (cp.TextSize.Height > isize.Height) + t.Y += (cp.TextSize.Height - isize.Height) / 2; + + g.DrawImageUnscaled(image, t); + + r.X += (isize.Width + Dpi.Width4); + r.Width -= (isize.Width + Dpi.Width4); + } + } + + return (r); + } + + #endregion + + #endregion + + #region DrawRoundRectangle + + private void DrawRoundRectangle(Graphics g, + Rectangle t, CrosshairVisualStyle cstyle) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = new GraphicsPath()) + { + int dia = Dpi.Width14; + Rectangle r = t; + + r.Width = dia; + r.Height = dia; + path.AddArc(r, 180, 90); + + r.X += (t.Width - dia); + path.AddArc(r, 270, 90); + + r.Y += (t.Height - dia); + path.AddArc(r, 0, 90); + + r.X = t.X; + path.AddArc(r, 90, 90); + + path.CloseFigure(); + + using (Brush br = cstyle.Background.GetBrush(r)) + g.FillPath(br, path); + + using (Pen pen = new Pen(cstyle.BorderColor, cstyle.BorderThickness)) + { + pen.DashStyle = (DashStyle)cstyle.BorderPattern; + + g.DrawPath(pen, path); + } + } + + g.SmoothingMode = sm; + } + + #endregion + + #region DrawCrosshairCallout + + private void DrawCrosshairCallout(Graphics g, + Rectangle t, Point pt, CrosshairVisualStyle cstyle) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = new GraphicsPath()) + { + AddCalloutToPath(path, t, pt); + + Rectangle rp = Rectangle.Round(path.GetBounds()); + + if (pt.Y > t.Y) + rp.Y -= Dpi.Height10; + + rp.Height += Dpi.Height10; + + using (Brush br = cstyle.Background.GetBrush(rp)) + g.FillPath(br, path); + + using (Pen pen = new Pen(cstyle.BorderColor, cstyle.BorderThickness)) + { + pen.DashStyle = (DashStyle)cstyle.BorderPattern; + + g.DrawPath(pen, path); + } + } + + g.SmoothingMode = sm; + } + + #region AddCalloutToPath + + private void AddCalloutToPath(GraphicsPath path, Rectangle t, Point pt) + { + int dia = Dpi.Width10; + Rectangle r = t; + + int n = Dpi.Width20; + + r.Width = dia; + r.Height = dia; + + if (pt.Y > t.Y) + { + if (pt.X < (t.X + t.Width / 2)) + { + path.AddLine(new Point(pt.X + n, pt.Y - Dpi.Width20), pt); + path.AddLine(pt, new Point(pt.X + Dpi.Width5, pt.Y - Dpi.Width20)); + } + else + { + path.AddLine(new Point(pt.X - Dpi.Width5, pt.Y - Dpi.Width20), pt); + path.AddLine(pt, new Point(pt.X - n, pt.Y - Dpi.Width20)); + } + + + r.Y += (t.Height - dia); + path.AddArc(r, 90, 90); + + r.Y = t.Y; + path.AddArc(r, 180, 90); + + r.X += (t.Width - dia); + path.AddArc(r, 270, 90); + + r.Y += (t.Height - dia); + path.AddArc(r, 0, 90); + } + else + { + if (pt.X < (t.X + t.Width / 2)) + { + path.AddLine(new Point(pt.X + Dpi.Width5, pt.Y + Dpi.Width20), pt); + path.AddLine(pt, new Point(pt.X + n, pt.Y + Dpi.Width20)); + } + else + { + path.AddLine(new Point(pt.X - n, pt.Y + Dpi.Width20), pt); + path.AddLine(pt, new Point(pt.X - Dpi.Width5, pt.Y + Dpi.Width20)); + } + + r.X += (t.Width - dia); + path.AddArc(r, 270, 90); + + r.Y += (t.Height - dia); + path.AddArc(r, 0, 90); + + r.X = t.X; + path.AddArc(r, 90, 90); + + r.Y = t.Y; + path.AddArc(r, 180, 90); + } + + path.CloseFigure(); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region Mouse Support + + #region OnMouseMove + + protected override bool OnMouseMove(MouseEventArgs e) + { + OnMouseMoveEx(e); + + if (Legend.Visible == false || + Legend.ContentBounds.Contains(e.Location) == false) + { + _CanShowCrosshairLabel = true; + } + + return (base.OnMouseMove(e)); + } + + #endregion + + #region OnMouseMoveEx + + protected override void OnMouseMoveEx(MouseEventArgs e) + { + ChartCrosshair crosshair = ChartCrosshair; + + bool displayCrosshair = DisplayCrosshair; + + _CanShowCrosshairLabel = false; + + if (crosshair.Visible == false || + (crosshair.ShowCrosshairLabels == false && + crosshair.ShowValueXLine == false && crosshair.ShowValueYLine == false && + crosshair.ShowValueXLabels == false && crosshair.ShowValueYLabels == false)) + { + DisplayCrosshair = false; + } + else + { + Rectangle bounds = GetScrollBounds(ContentBounds); + + if (VScrollBar.Enabled == true) + bounds.Width -= (VScrollBar.Width + 1); + + if (HScrollBar.Enabled == true) + bounds.Height -= (HScrollBar.Height + 1); + + DisplayCrosshair = bounds.Contains(e.Location); + } + + if (DisplayCrosshair == true || displayCrosshair != DisplayCrosshair) + { + if (DisplayCrosshair == false) + _CrosshairSeriesPoints = null; + + InvalidateRender(); + } + } + + #endregion + + #region OnMouseLeave + + protected override bool OnMouseLeave(EventArgs e) + { + if (DisplayCrosshair == true) + { + DisplayCrosshair = false; + + _CrosshairSeriesPoints = null; + + InvalidateRender(); + } + + return (base.OnMouseLeave(e)); + } + + #endregion + + #endregion + + #region GetLocalAdjustedPoint + + /// + /// Gets the local, scroll adjusted point. + /// + /// + /// + public Point GetLocalAdjustedPoint(Point pt) + { + pt.X -= ScrollOffset.X; + pt.X += (HScrollBar.Inverted == true ? HScrollOffset : -HScrollOffset); + + pt.Y -= ScrollOffset.Y; + pt.Y += (VScrollBar.Inverted == true ? VScrollOffset : -VScrollOffset); + + return (pt); + } + + #endregion + + #region GetGlobalAdjustedPoint + + internal Point GetGlobalAdjustedPoint(Point pt) + { + pt.X -= (HScrollBar.Inverted == true ? HScrollOffset : -HScrollOffset); + pt.Y -= (VScrollBar.Inverted == true ? VScrollOffset : -VScrollOffset); + + return (pt); + } + + #endregion + + #region GetScBorderThickness + + internal int GetScBorderThickness(XyAlignment side) + { + ChartXyVisualStyle xyStyle = EffectiveChartStyle; + + int n = 0; + + switch (side) + { + case XyAlignment.Top: + n = (xyStyle.BorderThickness.Top); + break; + + case XyAlignment.Left: + n = (xyStyle.BorderThickness.Left); + break; + + case XyAlignment.Bottom: + n = (xyStyle.BorderThickness.Bottom + + ((HScrollBar.Visible == true) ? HScrollBar.Height + 1 : 0)); + break; + + case XyAlignment.Right: + n = (xyStyle.BorderThickness.Right + + ((VScrollBar.Visible == true) ? VScrollBar.Width + 1 : 0)); + break; + } + + return (Dpi.Width(n)); + } + + #endregion + + #region GetPointMarker + + internal Image GetPointMarker(Graphics g, PointMarkerVisualStyle style) + { + Image marker = null; + + marker = style.GetPointMarkerImage(); + + return (marker ?? GetPointMarkerEx(g, style)); + } + + internal Image GetPointMarkerEx(Graphics g, PointMarkerVisualStyle style) + { + return (GetPointMarker(g, style.Type, + style.PointCount, Dpi.Size(style.Size), style.Rotation, + style.Background, style.BorderColor, style.BorderWidth)); + } + + internal Image GetPointMarker(Graphics g, PointMarkerType markerType, int markerPoints, + Size size, int markerRotation, Background background, Color borderColor, int borderWidth) + { + if (_PointMarker == null) + _PointMarker = new PointMarker(); + + if (markerType == PointMarkerType.None || markerType == PointMarkerType.NotSet) + markerType = PointMarkerType.Rectangle; + + return (_PointMarker.GetMarkerBitmap(g, markerType, + markerPoints, size, markerRotation, background, borderColor, borderWidth)); + } + + #endregion + + #region IsCrosshairSeriesPoint + + /// + /// Gets whether the given Point is a Crosshair displayed point. + /// + /// + /// + /// + public bool IsCrosshairSeriesPoint(ChartSeries series, Point pt) + { + if (_CrosshairSeriesPoints != null) + { + Rectangle r = new Rectangle(pt, Size.Empty); + r.Inflate(2, 2); + + foreach (CrosshairPoint chp in _CrosshairSeriesPoints) + { + if (r.Contains(chp.Point) && (series == null || chp.ChartSeries == series)) + { + if (chp == _NearestCrosshairPoint) + return (true); + + if (ChartCrosshair.CrosshairLabelMode != CrosshairLabelMode.NearestSeries) + return (true); + } + } + } + + return (false); + } + + #endregion + + #region UpdateRangeValues + + private void UpdateRangeValues() + { + if (SeriesRangeChanged == true) + { + SeriesRangeChanged = false; + + InvalidatePointLabelsEx(); + + _MinValueX = null; + _MaxValueX = null; + _MinValueY = null; + _MaxValueY = null; + + foreach (ChartSeries series in ChartSeries) + { + if (_MinValueX == null) + { + _MinValueX = series.MinValueX; + _MaxValueX = series.MaxValueX; + _MinValueY = series.MinValueY; + _MaxValueY = series.MaxValueY; + } + else + { + if (series.MinValueX != null) + { + if (DataCompare(series.MinValueX, _MinValueX) < 0) + _MinValueX = series.MinValueX; + + else if (DataCompare(series.MaxValueX, _MaxValueX) > 0) + _MaxValueX = series.MaxValueX; + + if (DataCompare(series.MinValueY, _MinValueY) < 0) + _MinValueY = series.MinValueY; + + else if (DataCompare(series.MaxValueY, _MaxValueY) > 0) + _MaxValueY = series.MaxValueY; + } + } + + ChartAxis axis = series.AxisX ?? AxisX; + + if (axis != null) + axis.SeriesRangeChanged = true; + + axis = series.AxisY ?? AxisY; + + if (axis != null) + axis.SeriesRangeChanged = true; + } + } + } + + #endregion + + #region GetPointFromValue + + /// + /// Gets the chart Point, given the provided SeriesPoint. + /// + /// + /// + /// + /// + public Point GetPointFromValue(ChartSeries series, SeriesPoint sp) + { + Point pt = GetDataPointNa(series, sp, 0); + + return (GetLocalAdjustedPoint(pt)); + } + + /// + /// Gets the chart Point, given the X and Y data point values. + /// + /// + /// + /// + /// + public Point GetPointFromValue(ChartSeries series, object pointValueX, object pointValueY) + { + Point pt = Point.Empty; + + ChartAxis axisX = series.AxisX ?? AxisX; + ChartAxis axisY = series.AxisY ?? AxisY; + + pt.X = GetDataPointX(axisX, pointValueX) + series.PointOffset.X; + pt.Y = GetDataPointY(axisY, pointValueY); + + return (pt); + } + + #endregion + + #region GetDataPoint + + internal Point GetDataPoint(ChartSeries series, SeriesPoint sp, int dy) + { + Point pt = GetDataPointNa(series, sp, dy); + + return (GetLocalAdjustedPoint(pt)); + } + + internal Point GetDataPointNa(ChartSeries series, SeriesPoint sp, int dy) + { + if (sp.SeriesValidationCount != SeriesPointCount) + { + sp.InvalidatePoints(); + + sp.SeriesValidationCount = SeriesPointCount; + } + + int n = (dy < 0) ? 0 : dy; + + if (sp.Point.Length > n) + { + if (sp.Point[n].IsEmpty == true) + { + sp.Point[n] = GetDataPointEx(series, sp, dy); + + if (sp.Point[n].IsEmpty == true) + return (Point.Empty); + } + + return (sp.Point[n]); + } + + return (Point.Empty); + } + + internal Point GetDataPointEx(ChartSeries series, SeriesPoint sp, int dy) + { + object pointValueX = sp.ValueX; + object pointValueY = 0; + + if (dy >= 0) + { + if (sp.ValueY != null && sp.ValueY.Length > dy) + pointValueY = sp.ValueY[dy]; + } + + if (series.IsRotated == true) + return (GetPointFromValue(series, pointValueY, pointValueX)); + + return (GetPointFromValue(series, pointValueX, pointValueY)); + } + + #region GetDataPointX + + internal int GetDataPointX(ChartAxis axis, object pointValueX) + { + TickmarkLayout layoutX = axis.TickmarkLayout; + + if (layoutX.Ticks != null) + { + Rectangle tmBoundsX = axis.MajorTickmarks.TickmarkBounds; + + int minOffset; + int majOffset = GetDataOffsetX(axis, layoutX, pointValueX, out minOffset); + + return ((tmBoundsX.X + majOffset - layoutX.MarginOffset) + minOffset); + } + else + { + Rectangle r = ScrollBounds; + + return (int)(r.Left); + } + } + + #region GetDataOffsetX + + private int GetDataOffsetX(ChartAxis axis, + TickmarkLayout layout, object pointValue, out int minOffset) + { + double ptValue; + + switch (axis.ScaleType) + { + case ScaleType.Qualitative: + ptValue = axis.QualitativeValues.IndexOf(pointValue) - Convert.ToInt32(layout.BaseValue); + break; + + case ScaleType.DateTime: + ptValue = GetDateTimePointValue(axis, layout, (DateTime)pointValue); + break; + + default: + try + { + ptValue = Convert.ToDouble(pointValue) - Convert.ToDouble(layout.BaseValue); + } + catch + { + minOffset = 0; + + return (0); + } + break; + } + + int n = (int)(ptValue / layout.MajorSpacing); + int p1 = (int)(n * layout.MajorInterval); + int p2 = (int)((n + 1) * layout.MajorInterval); + + double minorValue = (ptValue - (n * layout.MajorSpacing)); + minOffset = (int)(((p2 - p1) * minorValue) / layout.MajorSpacing); + + return (p1); + } + + #endregion + + #endregion + + #region GetDataPointY + + internal int GetDataPointY(ChartAxis axis, object pointValueY) + { + TickmarkLayout layoutY = axis.TickmarkLayout; + + if (layoutY.Ticks != null) + { + Rectangle tmBoundsY = axis.MajorTickmarks.TickmarkBounds; + + int minOffset; + int majOffset = GetDataOffsetY(axis, layoutY, pointValueY, out minOffset); + + return (((tmBoundsY.Bottom - 1) - majOffset + layoutY.MarginOffset) - minOffset); + } + else + { + Rectangle r = ScrollBounds; + + if (HScrollBar.Enabled == true) + r.Height -= HScrollBar.Height; + + return (int)(r.Bottom - 1); + } + } + + #region GetDataOffsetY + + private int GetDataOffsetY(ChartAxis axis, + TickmarkLayout layout, object pointValue, out int minOffset) + { + double ptValue; + + switch (axis.ScaleType) + { + case ScaleType.Qualitative: + ptValue = axis.QualitativeValues.IndexOf(pointValue) - Convert.ToInt32(layout.BaseValue); + break; + + case ScaleType.DateTime: + ptValue = GetDateTimePointValue(axis, layout, (DateTime)pointValue); + break; + + default: + try + { + ptValue = Convert.ToDouble(pointValue) - Convert.ToDouble(layout.BaseValue); + } + catch + { + minOffset = 0; + + return (0); + } + break; + } + + int n = (int)(ptValue / layout.MajorSpacing); + int p1 = (int)Math.Ceiling(n * layout.MajorInterval); + int p2 = (int)Math.Ceiling((n + 1) * layout.MajorInterval); + + double minorValue = (ptValue - (n * layout.MajorSpacing)); + minOffset = (int)Math.Ceiling(((p2 - p1) * minorValue) / layout.MajorSpacing); + + return (p1); + } + + #endregion + + #endregion + + #region GetDateTimePointValue + + internal double GetDateTimePointValue( + ChartAxis axis, TickmarkLayout layout, DateTime dt) + { + return (GetDateTimePointValue(axis, layout, dt, (DateTime)layout.BaseValue)); + } + + internal double GetDateTimePointValue( + ChartAxis axis, TickmarkLayout layout, DateTime dt, DateTime baseValue) + { + TimeSpan ts = dt - baseValue; + + DateTimeUnits adtu = axis.ActualDateTimeUnits; + + switch (adtu) + { + case DateTimeUnits.Ticks: + return (ts.Ticks); + + case DateTimeUnits.Milliseconds: + return (ts.TotalMilliseconds); + + case DateTimeUnits.Seconds: + return (ts.TotalSeconds); + + case DateTimeUnits.Minutes: + return (ts.TotalMinutes); + + case DateTimeUnits.Hours: + return (ts.TotalHours); + + case DateTimeUnits.Days: + return (ts.TotalDays); + + case DateTimeUnits.Months: + return (axis.CalcDateTimeMonths(baseValue, dt)); + + default: + return (axis.CalcDateTimeYears(baseValue, dt)); + } + } + + #endregion + + #endregion + + #region GetDataPointValueX + + internal object GetDataPointValueX(ChartSeries series, SeriesPoint sp) + { + ChartAxis axisX = series.AxisX ?? AxisX; + + switch (axisX.ScaleType) + { + case ScaleType.Qualitative: + return (axisX.QualitativeValues.IndexOf(sp.ValueX)); + + default: + return (sp.ValueX); + } + } + + #endregion + + #region GetDataPointValueY + + internal double GetDataPointValueY(ChartSeries series, SeriesPoint sp, int dy) + { + if (dy >= 0) + { + if (sp.IsQuantitativeYValue == true) + { + if (sp.ValueY != null && sp.ValueY.Length > dy) + return (Convert.ToDouble(sp.ValueY[dy])); + + return (1); + } + + ChartAxis axisY = series.AxisY ?? AxisY; + + return (axisY.QualitativeValues.IndexOf(sp.ValueY[dy])); + } + + return (0); + } + + #endregion + + #region GetQualitativeColumnWidth + + internal int GetQualitativeColumnWidth(ChartAxis axis, int groupId) + { + ChartXyVisualStyle cstyle = EffectiveChartStyle; + + List slist = GetQualitativeSeriesList(axis, groupId); + + int width = 0; + int swidth = 0; + + int count = 0; + + foreach (ChartSeries series in slist) + { + Size size; + + if (series.PointMarkerImage != null) + size = series.PointMarkerImage.Size; + else + size = series.EffectiveChartSeriesStyle.MarkerVisualStyle.Size; + + if (series.StackQualitativePoints == false) + { + count++; + width += size.Width; + } + else + { + swidth = Math.Max(swidth, size.Width); + } + } + + width += swidth; + + if (count > 1) + width += ((count - 1) * cstyle.IntraSeriesGap); + + int offset = -width / 2; + + if (swidth > 0) + { + Point pt = new Point(offset + swidth / 2, 0); + + foreach (ChartSeries series in slist) + { + if (series.StackQualitativePoints == true) + series.PointOffset = pt; + } + + offset += (swidth + cstyle.IntraSeriesGap); + } + + foreach (ChartSeries series in slist) + { + if (series.StackQualitativePoints == false) + { + Size size; + + if (series.PointMarkerImage != null) + size = series.PointMarkerImage.Size; + else + size = series.EffectiveChartSeriesStyle.MarkerVisualStyle.Size; + + series.PointOffset = new Point(offset + size.Width / 2 + 1, 0); + + offset += (size.Width + cstyle.IntraSeriesGap); + } + } + + width += (cstyle.InterSeriesGap * 2); + + return (width); + } + + #endregion + + #region AdjustQualitativeOffsets + + internal void AdjustQualitativeOffsets(ChartAxis axis, int groupId, int colWidth, int interval) + { + ChartXyVisualStyle cstyle = EffectiveChartStyle; + + if (cstyle.AutoExpandIntraSeriesGap == Tbool.True) + { + List slist = GetQualitativeSeriesList(axis, groupId); + + interval -= cstyle.InterSeriesGap; + + int count = 0; + + foreach (ChartSeries series in slist) + { + if (series.StackQualitativePoints == false) + count++; + } + + if (count > 1) + { + if (interval > colWidth) + { + int offset = (interval - colWidth); + int dv = offset / count; + + offset = offset / 2 - dv / 2; + + foreach (ChartSeries series in slist) + { + Point pt = series.PointOffset; + + if (axis.AxisOrientation == AxisOrientation.X) + pt.X -= offset; + else + pt.Y -= offset; + + series.PointOffset = pt; + + if (series.StackQualitativePoints == false) + offset -= dv; + } + } + } + } + } + + #endregion + + #region GetQualitativeSeriesList + + private List GetQualitativeSeriesList(ChartAxis axis, int groupId) + { + List slist = new List(); + + if (axis.ScaleType == ScaleType.Qualitative) + { + foreach (ChartSeries series in ChartSeries) + { + if (series.Visible == true && series.GroupId == groupId) + { + if (Legend.Visible == false || + (series.ShowCheckBoxInLegend == false || series.CheckedInLegend == true)) + { + if (axis.AxisOrientation == AxisOrientation.X) + { + if (series.AxisX == axis || (series.AxisX == null && axis.IsPrimaryAxis)) + slist.Add(series); + } + else + { + if (series.AxisY == axis || (series.AxisY == null && axis.IsPrimaryAxis)) + slist.Add(series); + } + } + } + } + } + + return (slist); + } + + #endregion + + #region GetChartBubbleData + + internal int GetChartBubbleData(out double min, out double max) + { + int count = 0; + + min = double.MaxValue; + max = double.MinValue; + + foreach (ChartSeries series in ChartSeries) + { + if (series.Visible == true) + { + BubblePlotData bpd = series.PlotData as BubblePlotData; + + if (bpd != null) + { + int n = series.SeriesPoints.Count; + count += n; + + double size = bpd.MinSize; + + if (size < min) + min = size; + + size = bpd.MaxSize; + + if (size > max) + max = size; + } + } + } + + return (count); + + } + + #endregion + + #region GetMaxDotPlotMarkerSize + + internal Size GetMaxDotPlotMarkerSize() + { + Size size = Size.Empty; + + foreach (ChartSeries series in ChartSeries) + { + if (series.Visible == true) + { + Image marker = series.PointMarkerImage; + + if (marker != null) + { + if (marker.Size.Width > size.Width) + size.Width = marker.Size.Width; + + if (marker.Size.Height > size.Height) + size.Height = marker.Size.Height; + } + } + } + + return (size); + } + + #endregion + + #region GetDotPlotTypes + + internal DotPlotType GetDotPlotTypes() + { + DotPlotType types = DotPlotType.None; + + foreach (ChartSeries series in ChartSeries) + { + if (series.Visible == true) + { + if (series.SeriesType == SeriesType.VerticalDot) + types |= DotPlotType.Vertical; + + else if (series.SeriesType == SeriesType.HorizontalDot) + types |= DotPlotType.Horizontal; + } + } + + return (types); + } + + #endregion + + #region GetBaseSeries + + internal override ChartBaseSeriesCollection GetBaseSeries() + { + ChartBaseSeriesCollection baseSeries = new ChartBaseSeriesCollection(); + + foreach (BaseSeries series in ChartSeries) + baseSeries.Add(series); + + return (baseSeries); + } + + #endregion + + #region GetSeriesByName + + /// + /// Gets the chart series with the given Name. + /// + /// + /// ChartSeries or null. + public ChartSeries GetSeriesByName(string name) + { + if (String.IsNullOrEmpty(name) == true) + return (null); + + foreach (ChartSeries series in ChartSeries) + { + if (name.Equals(series.Name) == true) + return (series); + } + + return (null); + } + + #endregion + + #region GetAutoGenSeriesType + + internal override SeriesType GetAutoGenSeriesType() + { + return (AutoGenSeriesType); + } + + #endregion + + #region GetAutoGenSeriesNameCount + + internal override int GetAutoGenSeriesNameCount() + { + return (AutoGenSeriesType == SeriesType.Bubble ? 2 : 1); + } + + #endregion + + #region GetNewSeries + + internal override BaseSeries GetNewSeries() + { + return (new ChartSeries(AutoGenSeriesType)); + } + + #endregion + + #region AddChartSeries + + internal override void AddChartSeries(BaseSeries series) + { + ChartSeries.Add((ChartSeries)series); + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + base.ApplyStyles(style); + + ChartXyVisualStyle xyStyle = style as ChartXyVisualStyle; + + if (xyStyle != null) + { + ApplyParentStyles(xyStyle, Parent as ChartContainer); + + xyStyle.ApplyStyle(ChartVisualStyle); + + xyStyle.ApplyDefaults(); + } + else if (style is ChartSeriesVisualStyle) + { + ChartSeriesVisualStyle sstyle = (ChartSeriesVisualStyle)style; + + ApplyParentStyles(sstyle, Parent as ChartContainer); + + sstyle.ApplyStyle(_ChartSeriesVisualStyle); + + sstyle.ApplyDefaults(); + } + else if (style is DataLabelVisualStyle) + { + DataLabelVisualStyle dstyle = style as DataLabelVisualStyle; + + if (dstyle != null) + { + ApplyParentStyles(dstyle, Parent as ChartContainer); + + dstyle.ApplyStyle(_DataLabelVisualStyle); + + dstyle.ApplyDefaults(); + } + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles(ChartXyVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is ChartPanel) + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartXyVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartXyVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartXyVisualStyle); + } + } + + #endregion + + #region ApplyParentStyles (ChartSeriesVisualStyle) + + private void ApplyParentStyles(ChartSeriesVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is ChartPanel) + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartSeriesVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartSeriesVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartSeriesVisualStyle); + } + } + + #endregion + + #region ApplyParentStyles (DataLabelVisualStyle) + + private void ApplyParentStyles(DataLabelVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + if (item is ChartPanel) + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.DataLabelVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.DataLabelVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.DataLabelVisualStyle); + } + } + + #endregion + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + _EffectiveChartStyle.InvalidateStyle(); + _EffectiveChartSeriesStyle.InvalidateStyle(); + + if (_EffectiveDataLabelStyle.InvalidateStyle() == true) + InvalidateLayout(); + + base.ClearEffectiveStyles(); + } + + #endregion + + #endregion + + #region InvalidateLayoutBounds + + public override void InvalidateLayoutBounds(ScrollBarLite sbar) + { + base.InvalidateLayoutBounds(sbar); + + if (sbar != null) + { + Rectangle contentBounds = GetScrollBounds(ContentBounds); + InvalidateRender(contentBounds); + + if (sbar.Orientation == Orientation.Horizontal) + InvalidateAxes(AncillaryAxesX, AxisX); + else + InvalidateAxes(AncillaryAxesY, AxisY); + } + } + + #region InvalidateAxes + + private void InvalidateAxes(ChartAxesCollection axes, ChartAxis axis) + { + foreach (ChartAxis ca in axes) + { + if (ca.Visible == true) + { + Rectangle bounds = ca.GetScrollBounds(ca.AxisBounds); + + ca.InvalidateRender(bounds); + } + } + + if (axis.Visible == true) + { + Rectangle bounds = axis.GetScrollBounds(axis.AxisBounds); + + axis.InvalidateRender(bounds); + } + } + + #endregion + + #endregion + + #region InvalidateSeriesPoints + + private void InvalidateSeriesPoints() + { + SeriesPointCount++; + + foreach (ChartSeries series in ChartSeries) + series.InvalidatePoints(); + + InvalidatePointLabelsEx(); + } + + #endregion + + #region InvalidatePointLabels + + /// + /// Invalidate the cached PointLabels + /// + public void InvalidatePointLabels() + { + InvalidatePointLabelsEx(); + InvalidateRender(); + } + + internal void InvalidatePointLabelsEx() + { + _PointLabels = null; + } + + #endregion + + #region GetLegendData + + /// + /// Gets the list of chart legend data. + /// + /// + public override List GetLegendData() + { + base.GetLegendData(); + + GetAxesLegendData(AncillaryAxesX, AxisX); + GetAxesLegendData(AncillaryAxesY, AxisY); + + return (LegendData); + } + + #endregion + + #region GetAxesLegendData + + private void GetAxesLegendData(ChartAxesCollection axes, ChartAxis axis) + { + for (int i = axes.Count - 1; i >= 0; i--) + { + ChartAxis ca = axes[i]; + + if (ca.Visible == true) + ca.GetLegendData(LegendData); + } + + if (axis.Visible == true) + axis.GetLegendData(LegendData); + } + + #endregion + + #region GetHitArea + + /// + /// Gets the hit area for the chart. + /// + /// + /// ItemHitArea + public override ItemHitArea GetHitArea(Point pt) + { + if (AxisX.Bounds.Contains(pt)) + return (ItemHitArea.InPrimaryAxisX); + + if (AxisY.Bounds.Contains(pt)) + return (ItemHitArea.InPrimaryAxisY); + + foreach (ChartAxis axis in AncillaryAxesX) + { + if (axis.Bounds.Contains(pt)) + return (ItemHitArea.InAncillaryAxisX); + } + + foreach (ChartAxis axis in AncillaryAxesY) + { + if (axis.Bounds.Contains(pt)) + return (ItemHitArea.InAncillaryAxisY); + } + + return (base.GetHitArea(pt)); + } + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ChartXy copy = new ChartXy(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ChartXy c = copy as ChartXy; + + if (c != null) + { + base.CopyTo(c); + + foreach (ChartAxisX axis in AncillaryAxesX) + c.AncillaryAxesX.Add((ChartAxisX)axis.Copy()); + + foreach (ChartAxisY axis in AncillaryAxesY) + c.AncillaryAxesY.Add((ChartAxisY)axis.Copy()); + + c.AutoGenSeriesType = AutoGenSeriesType; + + AxisX.CopyTo(c.AxisX); + AxisY.CopyTo(c.AxisY); + + c.BarFillRange = BarFillRange; + c.BarLabelPosition = BarLabelPosition; + c.BarOrigin = BarOrigin; + c.BarOverlayEnabled = BarOverlayEnabled; + c.BarShadingEnabled = BarShadingEnabled; + c.BarSpacing = BarSpacing; + c.BarSpacingRatio = BarSpacingRatio; + c.BarWidthRatio = BarWidthRatio; + + c.BubbleIntensityMode = BubbleIntensityMode; + c.BubbleSizeMode = BubbleSizeMode; + + c.ChartLineAreaDisplayMode = ChartLineAreaDisplayMode; + c.ChartLineDisplayMode = ChartLineDisplayMode; + + foreach (ChartSeries series in ChartSeries) + c.ChartSeries.Add((ChartSeries)series.Copy()); + + c.ChartSeriesVisualStyle = + (_ChartSeriesVisualStyle != null) ? _ChartSeriesVisualStyle.Copy() : null; + + c.ChartVisualStyle = (_ChartVisualStyle != null) ? ChartVisualStyle.Copy() : null; + + c.ConvexHullDisplayMode = ConvexHullDisplayMode; + + ChartCrosshair.CopyTo(c.ChartCrosshair); + + c.DataLabelOverlapMode = DataLabelOverlapMode; + + c.DataLabelVisualStyle = + (_DataLabelVisualStyle != null) ? _DataLabelVisualStyle.Copy() : null; + + c.PointLabelDisplayMode = PointLabelDisplayMode; + c.SeriesDisplayOrder = SeriesDisplayOrder; + + c.StepLines = StepLines; + c.StepLineMode = StepLineMode; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartXy"; + + sec.AddStartElement(serialName); + } + + if (_AncillaryAxesX != null && _AncillaryAxesX.Count > 0) + { + sec.AddStartElement("AncillaryAxesX count=\"" + _AncillaryAxesX.Count + "\""); + + foreach (ChartAxisX axis in _AncillaryAxesX) + sec.AddElement(axis.GetSerialData("ChartAxisX")); + + sec.AddEndElement("AncillaryAxesX"); + } + + if (_AncillaryAxesY != null && _AncillaryAxesY.Count > 0) + { + sec.AddStartElement("AncillaryAxesY count=\"" + _AncillaryAxesY.Count + "\""); + + foreach (ChartAxisY axis in _AncillaryAxesY) + sec.AddElement(axis.GetSerialData("ChartAxisY")); + + sec.AddEndElement("AncillaryAxesY"); + } + + sec.AddValue("AutoGenSeriesType", AutoGenSeriesType, SeriesType.Point); + + if (AxisX != null) + sec.AddElement(AxisX.GetSerialData("AxisX")); + + if (AxisY != null) + sec.AddElement(AxisY.GetSerialData("AxisY")); + + sec.AddValue("BarFillRange", BarFillRange, BarFillRange.NotSet); + sec.AddValue("BarLabelPosition", BarLabelPosition, BarLabelPosition.NotSet); + + sec.AddDataValue("BarOrigin", BarOrigin, null); + + sec.AddValue("BarOverlayEnabled", BarOverlayEnabled, false); + sec.AddValue("BarShadingEnabled", BarShadingEnabled, Tbool.NotSet); + sec.AddValue("BarShowAsHistogram", BarShowAsHistogram, Tbool.NotSet); + sec.AddValue("BarSpacing", BarSpacing, 0); + sec.AddValue("BarSpacingRatio", BarSpacingRatio, 0.2d); + sec.AddValue("BarWidthRatio", BarWidthRatio, 0d); + + sec.AddValue("BubbleIntensityMode", BubbleIntensityMode, BubbleIntensityMode.NotSet); + sec.AddValue("BubbleSizeMode", BubbleSizeMode, BubbleSizeMode.NotSet); + + sec.AddValue("ChartLineAreaDisplayMode", ChartLineAreaDisplayMode, ChartLineAreaDisplayMode.NotSet); + sec.AddValue("ChartLineDisplayMode", ChartLineDisplayMode, ChartLineDisplayMode.NotSet); + + if (ChartSeries.Count > 0) + { + sec.AddStartElement("ChartSeries count=\"" + ChartSeries.Count + "\""); + + foreach (ChartSeries series in ChartSeries) + sec.AddElement(series.GetSerialData("ChartSeries")); + + sec.AddEndElement("ChartSeries"); + } + + if (_ChartSeriesVisualStyle != null && _ChartSeriesVisualStyle.IsEmpty == false) + sec.AddElement(_ChartSeriesVisualStyle.GetSerialData("ChartSeriesVisualStyle")); + + if (_ChartVisualStyle != null && _ChartVisualStyle.IsEmpty == false) + sec.AddElement(_ChartVisualStyle.GetSerialData("ChartVisualStyle")); + + sec.AddValue("ConvexHullDisplayMode", ConvexHullDisplayMode, ConvexHullDisplayMode.NotSet); + + sec.AddElement(ChartCrosshair.GetSerialData("ChartCrosshair")); + + sec.AddValue("DataLabelOverlapMode", DataLabelOverlapMode, DataLabelOverlapMode.NotSet); + + if (_DataLabelVisualStyle != null && _DataLabelVisualStyle.IsEmpty == false) + sec.AddElement(_DataLabelVisualStyle.GetSerialData("DataLabelVisualStyle")); + + sec.AddValue("PointLabelDisplayMode", PointLabelDisplayMode, PointLabelDisplayMode.NotSet); + sec.AddValue("SeriesDisplayOrder", SeriesDisplayOrder, SeriesDisplayOrder.NotSet); + sec.AddValue("StepLines", StepLines, StepLines.NotSet); + sec.AddValue("StepLineMode", StepLineMode, StepLineMode.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AutoGenSeriesType": + AutoGenSeriesType = (SeriesType)se.GetValueEnum(typeof(SeriesType)); + break; + + case "BarFillRange": + BarFillRange = (BarFillRange)se.GetValueEnum(typeof(BarFillRange)); + break; + + case "BarLabelPosition": + BarLabelPosition = (BarLabelPosition)se.GetValueEnum(typeof(BarLabelPosition)); + break; + + case "BarOrigin": + BarOrigin = se.DataValue; + break; + + case "BarOverlayEnabled": + BarOverlayEnabled = bool.Parse(se.StringValue); + break; + + case "BarShadingEnabled": + BarShadingEnabled = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "BarShowAsHistogram": + BarShowAsHistogram = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "BarSpacing": + BarSpacing = int.Parse(se.StringValue); + break; + + case "BarSpacingRatio": + BarSpacingRatio = double.Parse(se.StringValue); + break; + + case "BarWidthRatio": + BarWidthRatio = double.Parse(se.StringValue); + break; + + case "BubbleIntensityMode": + BubbleIntensityMode = (BubbleIntensityMode)se.GetValueEnum(typeof(BubbleIntensityMode)); + break; + + case "BubbleSizeMode": + BubbleSizeMode = (BubbleSizeMode)se.GetValueEnum(typeof(BubbleSizeMode)); + break; + + case "ChartLineAreaDisplayMode": + ChartLineAreaDisplayMode = (ChartLineAreaDisplayMode)se.GetValueEnum(typeof(ChartLineAreaDisplayMode)); + break; + + case "ChartLineDisplayMode": + ChartLineDisplayMode = (ChartLineDisplayMode)se.GetValueEnum(typeof(ChartLineDisplayMode)); + break; + + case "ConvexHullDisplayMode": + ConvexHullDisplayMode = (ConvexHullDisplayMode)se.GetValueEnum(typeof(ConvexHullDisplayMode)); + break; + + case "DataLabelOverlapMode": + DataLabelOverlapMode = (DataLabelOverlapMode)se.GetValueEnum(typeof(DataLabelOverlapMode)); + break; + + case "PointLabelDisplayMode": + PointLabelDisplayMode = (PointLabelDisplayMode)se.GetValueEnum(typeof(PointLabelDisplayMode)); + break; + + case "SeriesDisplayOrder": + SeriesDisplayOrder = (SeriesDisplayOrder)se.GetValueEnum(typeof(SeriesDisplayOrder)); + break; + + case "StepLines": + StepLines = (StepLines)se.GetValueEnum(typeof(StepLines)); + break; + + case "StepLineMode": + StepLineMode = (StepLineMode)se.GetValueEnum(typeof(StepLineMode)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "AncillaryAxesX": + case "AncillaryAxesY": + sec.PutSerialData(this); + break; + + case "AxisX": + sec.PutSerialData(AxisX); + break; + + case "AxisY": + sec.PutSerialData(AxisY); + break; + + case "ChartAxisX": + string nameX = sec.GetItemValue("Name"); + + ChartAxis axisX = AncillaryAxesX[nameX]; + + if (axisX != null) + AncillaryAxesX.Remove(axisX); + + axisX = new ChartAxisX(nameX); + + sec.PutSerialData(axisX); + + AncillaryAxesX.Add(axisX); + break; + + case "ChartAxisY": + string nameY = sec.GetItemValue("Name"); + + ChartAxis axisY = AncillaryAxesY[nameY]; + + if (axisY != null) + AncillaryAxesY.Remove(axisY); + + axisY = new ChartAxisY(nameY); + + sec.PutSerialData(axisY); + + AncillaryAxesY.Add(axisY); + break; + + case "ChartSeries": + if (se.ArrayCount > 0) + { + sec.PutSerialData(this); + } + else + { + string name = sec.GetItemValue("Name"); + + ChartSeries series = new ChartSeries(name); + + ChartSeries.Add(series); + + sec.PutSerialData(series); + } + break; + + case "ChartSeriesVisualStyle": + sec.PutSerialData(ChartSeriesVisualStyle); + break; + + case "ChartVisualStyle": + sec.PutSerialData(ChartVisualStyle); + break; + + case "ChartCrosshair": + sec.PutSerialData(ChartCrosshair); + break; + + case "DataLabelVisualStyle": + sec.PutSerialData(DataLabelVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + BarOverlayEnabled = (1U << 0), + + DisplayCrosshair = (1U << 1), + DropShadowDisplayed = (1U << 2), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + AncillaryAxesX = null; + AncillaryAxesY = null; + + AxisX = null; + AxisY = null; + + ChartSeriesVisualStyle = null; + ChartVisualStyle = null; + ChartCrosshair = null; + DataLabelVisualStyle = null; + + base.Dispose(); + } + + #endregion + } + + #region CrosshairPoint + + /// + /// Defines a Crosshair Point + /// + public class CrosshairPoint + { + #region Public variables + + private ChartSeries _ChartSeries; + private SeriesPoint _SeriesPoint; + + private int _PointIndex; + private int _ValueIndex; + private SortedSeriesPoints _SortedSeriesPoints; + + private Point _Point; + + private string _Text; + private Size _TextSize; + + private bool _IsDescending; + + #endregion + + public CrosshairPoint(ChartSeries chartSeries, SortedSeriesPoints ssp, + int pointIndex, SeriesPoint seriesPoint, int valueIndex, Point point, bool isDescending) + { + _ChartSeries = chartSeries; + _IsDescending = isDescending; + _SortedSeriesPoints = ssp; + _PointIndex = pointIndex; + _SeriesPoint = seriesPoint; + _ValueIndex = valueIndex; + + _Point = point; + } + + #region Public properties + + #region ChartSeries + + /// + /// Gets the associated chart series. + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + internal set { _ChartSeries = value; } + } + + #endregion + + #region SeriesPoint + + /// + /// Gets the associated SeriesPoint. + /// + public SeriesPoint SeriesPoint + { + get { return (_SeriesPoint); } + internal set { _SeriesPoint = value; } + } + + #endregion + + #region ValueX + + /// + /// Gets the X-Value + /// + public object ValueX + { + get { return (SeriesPoint.ValueX); } + } + + #endregion + + #region ValueY + + /// + /// Gets the associated ValueY. + /// + public object ValueY + { + get + { + if (ChartSeries.SeriesType == SeriesType.VerticalDot || + ChartSeries.SeriesType == SeriesType.HorizontalDot) + { + return (SortedSeriesPoints.CountArray[PointIndex]); + } + + if (SeriesPoint.ValueY != null && (uint)_ValueIndex < SeriesPoint.ValueY.Length) + return (SeriesPoint.ValueY[_ValueIndex]); + + return (string.Empty); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region IsDescending + + internal bool IsDescending + { + get { return (_IsDescending); } + set { _IsDescending = value; } + } + + #endregion + + #region Point + + internal Point Point + { + get { return (_Point); } + set { _Point = value; } + } + + #endregion + + #region PointIndex + + internal int PointIndex + { + get { return (_PointIndex); } + set { _PointIndex = value; } + } + + #endregion + + #region SortedSeriesPoints + + internal SortedSeriesPoints SortedSeriesPoints + { + get { return (_SortedSeriesPoints); } + set { _SortedSeriesPoints = value; } + } + + #endregion + + #region Text + + internal string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + + #region TextSize + + internal Size TextSize + { + get { return (_TextSize); } + set { _TextSize = value; } + } + + #endregion + + #region ValueIndex + + internal int ValueIndex + { + get { return (_ValueIndex); } + set { _ValueIndex = value; } + } + + #endregion + + #endregion + } + + #endregion + + #region CrosshairGroup + + internal class CrosshairGroup + { + public string Text; + public Size TextSize; + + public Size LabelSize; + public int MarkerWidth; + + public List Cps; + } + + #endregion + + #region enums + + #region BarFillRange + + public enum BarFillRange + { + /// + /// Not set (default is ByBar) + /// + NotSet = 0, + + /// + /// Bars are filled according to each individual + /// bar's defined range. + /// + ByBar, + + /// + /// Bars are filled according to the associated series + /// minimum and maximum values. + /// + BySeries, + } + + #endregion + + #region BubbleIntensityMode + + public enum BubbleIntensityMode + { + /// + /// Not set (default is None) + /// + NotSet = 0, + + /// + /// Bubble intensity not used. + /// + None, + + /// + /// Bubble intensity is expressed as an alpha value (0 - 255). + /// + Alpha, + + /// + /// Bubble intensity is expressed as a data value (as is the size of the bubble). + /// + Value, + } + + #endregion + + #region BubbleSizeMode + + public enum BubbleSizeMode + { + /// + /// Not set (default is Area) + /// + NotSet = 0, + + /// + /// Bubble size is proportional to the bubble area. + /// + Area, + + /// + /// Bubble size is proportional to the bubble diameter. + /// + Diameter, + } + + #endregion + + #region ChartLineDisplayMode + + [Flags] + public enum ChartLineDisplayMode + { + /// + /// Not set + /// + NotSet = 0, + + /// + /// Display defined points on line + /// + DisplayPoints = (1 << 0), + + /// + /// Display a straight line through defined series points + /// + DisplayLine = (1 << 1), + + /// + /// Display a spline through defined series points + /// + DisplaySpline = (1 << 2), + + /// + /// Display a Step Line through defined series points + /// + DisplayStepLine = (1 << 3), + + /// + /// Points are displayed unsorted + /// + DisplayUnsorted = (1 << 4), + + /// + /// Start and end Points are connected. + /// + DisplayClosed = (1 << 5), + } + + #endregion + + #region ChartLineAreaDisplayMode + + [Flags] + public enum ChartLineAreaDisplayMode + { + /// + /// Not set + /// + NotSet = 0, + + /// + /// Not set + /// + None = (1 << 0), + + /// + /// Display background area under series Line. + /// + DisplayLine = (1 << 1), + + /// + /// Display background area under series Spline. + /// + DisplaySpline = (1 << 2), + + /// + /// Display background area under series StepLine. + /// + DisplayStepLine = (1 << 3), + + /// + /// Display background area under series EmptyLines. + /// + DisplayEmptyLine = (1 << 4), + } + + #endregion + + #region DotPlotType + + [Flags] + internal enum DotPlotType + { + None = 0, + Horizontal = (1 << 0), + Vertical = (1 << 1), + } + + #endregion + + #region DataLabelOverlapMode + + /// + /// Specifies how overlapping Series Data Labels are resolved + /// + public enum DataLabelOverlapMode + { + /// + /// Not set (default is None). + /// + NotSet = -1, + + /// + /// Overlapping labels will be shown. + /// + ShowOverlapping, + + /// + /// Overlapping labels will be hidden. + /// + HideOverlapping, + + /// + /// Overlapping labels will be rotated around point (when applicable). + /// + RotateAroundPoint, + } + + #endregion + + #region SeriesDisplayOrder + + public enum SeriesDisplayOrder + { + /// + /// Not set (default is Forward). + /// + NotSet, + + /// + /// Series are displayed in the normal collection order. + /// + Forward, + + /// + /// Series are displayed in the reverse collection order. + /// + Reverse, + } + + #endregion + + #region XyAlignment + + public enum XyAlignment + { + NotSet = -1, + + Top, + Left, + Bottom, + Right, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/FlockAlign.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/FlockAlign.cs new file mode 100644 index 00000000..d8893244 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/FlockAlign.cs @@ -0,0 +1,922 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + class FlockAlign + { + #region Constants + + private const long RemovePenalty = 1; + private const int MovesPerIteration = 500; + + #endregion + + #region Private variables + + private List _LabelGroups; + + #endregion + + public FlockAlign(List labelGroups) + { + _LabelGroups = labelGroups; + + foreach (PointLabelGroup lg in _LabelGroups) + { + foreach (PointLabel pl in lg.PointLabels) + pl.Bounds = Rectangle.Empty; + } + } + + #region Iterate + + public bool Iterate(Rectangle bounds, DataLabelOverlapMode ovlMode) + { + if (ovlMode == DataLabelOverlapMode.NotSet) + ovlMode = DataLabelOverlapMode.RotateAroundPoint; + + for (int i = 0; i < _LabelGroups.Count; i++) + { + PointLabelGroup lg = _LabelGroups[i]; + List lps = lg.PointLabels; + ChartSeries series = lg.ChartSeries; + + Point lp = Point.Empty; + + for (int j = 0; j < lps.Count; j++) + { + PointLabel pl = lps[j]; + + if (pl.Visible == true ) + { + DataLabelVisualStyle dstyle = pl.DataLabelVisualStyle ?? series.EffectiveDataLabelStyle; + + if (series.IsBarSeries == true) + { + if (series.IsRotated == true) + IterateHBar(series, pl, bounds, ovlMode, dstyle); + else + IterateVBar(series, pl, bounds, ovlMode, dstyle); + } + else + { + IteratePoint(series, pl, bounds, lp, ovlMode, dstyle); + } + } + + lp = pl.Point; + } + } + + return (true); + } + + #region IterateHBar + + private void IterateHBar(ChartSeries series, PointLabel pl, + Rectangle bounds, DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle) + { + ChartXy chartXy = series.Parent as ChartXy; + + int start = (pl.IsDataLabel == true) + ? pl.Point.X - 1 : series.GetHBarStart(chartXy, pl.SeriesPoint); + + int end = pl.Point.X; + + BarLabelPosition labelPos = pl.BarLabelPosition; + + if (labelPos == BarLabelPosition.NotSet) + labelPos = series.GetBarLabelPosition(chartXy); + + switch (labelPos) + { + case BarLabelPosition.Near: + SetHBarLabelNear(series, pl, bounds, ovlMode, dstyle, start, end, false); + break; + + case BarLabelPosition.NearInside: + SetHBarLabelNear(series, pl, bounds, ovlMode, dstyle, start, end, true); + break; + + case BarLabelPosition.Far: + SetHBarLabelFar(series, pl, bounds, ovlMode, dstyle, start, end, false); + break; + + case BarLabelPosition.FarInside: + SetHBarLabelFar(series, pl, bounds, ovlMode, dstyle, start, end, true); + break; + + default: + SetHBarLabelCenter(series, pl, bounds, ovlMode, dstyle, start, end); + break; + } + } + + #region SetHBarLabelNear + + private void SetHBarLabelNear(ChartSeries series, PointLabel pl, Rectangle bounds, + DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle, int start, int end, bool inside) + { + ConnectorLineVisualStyle cstyle = dstyle.ConnectorLineStyle; + + Point pt = new Point(start, pl.Point.Y + series.BarOffset); + + Size size = GetBoundsSize(series, pl, dstyle); + Rectangle t = Rectangle.Empty; + + int minLength = Dpi.Width(cstyle.MinLength); + + for (int i = 0; i < 2; i++) + { + int clen = (inside == false && minLength > 0) ? minLength + Dpi.Width2 : Dpi.Width4; + + int step = cstyle.LengthStep; + int offset = (size.Width / 2 + clen); + + if (inside ? end < start : end > start) + { + step *= -1; + offset *= -1; + } + + Point ptc = pt; + ptc.X += offset; + + t = GetCenteredRectangle(series, ptc, size); + + while (step < 0 ? t.X > bounds.X : t.Right < bounds.Right) + { + if (SetHBarLabelPos(pl, ovlMode, bounds, ptc, t, start, end) == true) + return; + + if (ovlMode != DataLabelOverlapMode.RotateAroundPoint) + break; + + t.X += step; + + if (cstyle.MaxLength > 0) + { + if (Math.Abs(t.X - ptc.X) > cstyle.MaxLength) + break; + } + } + + inside = !inside; + } + + SetHBarDefaultLabelPos(series, ref pl, pt, t, ovlMode, start, end); + } + + #endregion + + #region SetHBarLabelFar + + private void SetHBarLabelFar(ChartSeries series, PointLabel pl, Rectangle bounds, + DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle, int start, int end, bool inside) + { + ConnectorLineVisualStyle cstyle = dstyle.ConnectorLineStyle; + + Point pt = new Point(end, pl.Point.Y + series.BarOffset); + Size size = GetBoundsSize(series, pl, dstyle); + + Rectangle t = Rectangle.Empty; + + int minLength = Dpi.Width(cstyle.MinLength); + + for (int i = 0; i < 2; i++) + { + int clen = (inside == false && minLength >= 0) ? minLength + Dpi.Width2 : Dpi.Width4; + + int step = cstyle.LengthStep; + int offset = (size.Width / 2 + clen); + + if (inside ? end > start : end < start) + { + step *= -1; + offset *= -1; + } + + Point ptc = pt; + ptc.X += offset; + + t = GetCenteredRectangle(series, ptc, size); + + while (step < 0 ? t.X > bounds.X : t.Right < bounds.Right) + { + if (SetHBarLabelPos(pl, ovlMode, bounds, ptc, t, start, end) == true) + return; + + if (ovlMode != DataLabelOverlapMode.RotateAroundPoint) + break; + + t.X += step; + + if (cstyle.MaxLength > 0) + { + if (Math.Abs(t.X - ptc.X) > cstyle.MaxLength) + break; + } + } + + inside = !inside; + } + + SetHBarDefaultLabelPos(series, ref pl, pt, t, ovlMode, start, end); + } + + #endregion + + #region SetHBarLabelCenter + + private void SetHBarLabelCenter(ChartSeries series, PointLabel pl, + Rectangle bounds, DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle, + int start, int end) + { + Point pt = new Point((end + start) / 2, pl.Point.Y + series.BarOffset); + + int pass = 0; + int step = 2; + int startx = pt.X; + + Size size = GetBoundsSize(series, pl, dstyle); + + Rectangle t = GetCenteredRectangle(series, pt, size); + + int len = (end + start) / 2; + + while (pass <= len) + { + if (SetHBarLabelPos(pl, ovlMode, bounds, pt, t, start, end) == true) + return; + + if (ovlMode != DataLabelOverlapMode.RotateAroundPoint) + break; + + int pval = pass / 2 + 1; + + if (pass % 2 > 0) + pval = -pval; + + t.X = (startx + (pval * step)); + + pass++; + } + + SetHBarDefaultLabelPos(series, ref pl, pt, t, ovlMode, start, end); + } + + #endregion + + #region SetHBarLabelPos + + private bool SetHBarLabelPos(PointLabel pl, + DataLabelOverlapMode ovlMode, Rectangle bounds, Point pt, Rectangle t, int start, int end) + { + if (IsFreeArea(t, bounds, ovlMode, false, true) == true) + { + pl.Bounds = t; + + SetHBarEdgePoint(pl, pt, t, start, end); + + return (true); + } + + if (ovlMode == DataLabelOverlapMode.HideOverlapping) + return (true); + + return (false); + } + + #endregion + + #region SetHBarDefaultLabelPos + + private void SetHBarDefaultLabelPos(ChartSeries series, ref PointLabel pl, + Point pt, Rectangle t, DataLabelOverlapMode ovlMode, int start, int end) + { + if (ovlMode == DataLabelOverlapMode.RotateAroundPoint) + { + if (t.X < start) + t.X = start + Dpi.Width4; + else + t.X = end - (t.Width + Dpi.Width4); + + ChartXy chartXy = series.Parent as ChartXy; + + Rectangle bounds = chartXy.ContentBoundsEx; + + if (t.Right > bounds.Right) + t.X -= (t.Right - bounds.Right + Dpi.Width4); + + if (t.X < bounds.X) + t.X = bounds.X + Dpi.Width4; + + pl.Bounds = t; + + SetHBarEdgePoint(pl, pt, t, start, end); + } + else + { + pl.Bounds = Rectangle.Empty; + pl.EdgePoint = Point.Empty; + } + } + + #endregion + + #region SetHBarEdgePoint + + private void SetHBarEdgePoint(PointLabel pl, Point pt, Rectangle t, int start, int end) + { + if (t.X > start && t.X > end) + { + pt.X = Math.Max(start, end); + pl.EdgePoint = new Point(t.X, pt.Y); + } + else if (t.X < start && t.X < end) + { + pt.X = Math.Min(start, end); + pl.EdgePoint = new Point(t.Right, pt.Y); + } + else + { + pl.EdgePoint = Point.Empty; + } + + pl.Point = pt; + } + + #endregion + + #endregion + + #region IterateVBar + + private void IterateVBar(ChartSeries series, PointLabel pl, + Rectangle bounds, DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle) + { + ChartXy chartXy = series.Parent as ChartXy; + + int start = series.GetVBarStart(chartXy, pl.SeriesPoint); + int end = pl.Point.Y; + + BarLabelPosition labelPos = series.GetBarLabelPosition(chartXy); + + switch (labelPos) + { + case BarLabelPosition.Near: + SetVBarLabelNear(series, pl, bounds, ovlMode, dstyle, start, end, false); + break; + + case BarLabelPosition.NearInside: + SetVBarLabelNear(series, pl, bounds, ovlMode, dstyle, start, end, true); + break; + + case BarLabelPosition.Far: + SetVBarLabelFar(series, pl, bounds, ovlMode, dstyle, start, end, false); + break; + + case BarLabelPosition.FarInside: + SetVBarLabelFar(series, pl, bounds, ovlMode, dstyle, start, end, true); + break; + + default: + SetVBarLabelCenter(series, pl, bounds, ovlMode, dstyle, start, end); + break; + } + } + + #region SetVBarLabelNear + + private void SetVBarLabelNear(ChartSeries series, PointLabel pl, Rectangle bounds, + DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle, int start, int end, bool inside) + { + ConnectorLineVisualStyle cstyle = dstyle.ConnectorLineStyle; + + Point pt = new Point(pl.Point.X + series.BarOffset, start); + Size size = GetBoundsSize(series, pl, dstyle); + + int minLength = Dpi.Width(cstyle.MinLength); + + int clen = (inside == false && minLength >= 0) ? minLength + Dpi.Width2 : Dpi.Width4; + + int step = cstyle.LengthStep; + int offset = (size.Height / 2 + clen); + + Rectangle t = Rectangle.Empty; + + for (int i = 0; i < 2; i++) + { + if (inside ? end < start : end > start) + { + step *= -1; + offset *= -1; + } + + Point ptc = pt; + ptc.Y += offset; + + t = GetCenteredRectangle(series, ptc, size); + + while (t.Y < bounds.Bottom) + { + if (SetVBarLabelPos(pl, ovlMode, bounds, ptc, t, start, end) == true) + return; + + if (ovlMode != DataLabelOverlapMode.RotateAroundPoint) + break; + + t.Y += step; + + if (cstyle.MaxLength > 0) + { + if (Math.Abs(t.Y - ptc.Y) > cstyle.MaxLength) + break; + } + } + + inside = !inside; + } + + SetVBarDefaultLabelPos(series, ref pl, pt, t, ovlMode, start, end); + } + + #endregion + + #region SetVBarLabelFar + + private void SetVBarLabelFar(ChartSeries series, PointLabel pl, Rectangle bounds, + DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle, int start, int end, bool inside) + { + ConnectorLineVisualStyle cstyle = dstyle.ConnectorLineStyle; + + Point pt = new Point(pl.Point.X + series.BarOffset, end); + Size size = GetBoundsSize(series, pl, dstyle); + + int minLength = Dpi.Width(cstyle.MinLength); + + Rectangle t = Rectangle.Empty; + + for (int i = 0; i < 2; i++) + { + int clen = (inside == false && minLength >= 0) ? minLength + Dpi.Width2 : Dpi.Width4; + + int step = cstyle.LengthStep; + int offset = (size.Height / 2 + clen); + + if (inside ? end > start : end < start) + { + step *= -1; + offset *= -1; + } + + Point ptc = pt; + ptc.Y += offset; + + t = GetCenteredRectangle(series, ptc, size); + + while (step < 0 ? t.Y > bounds.Y : t.Y < bounds.Bottom) + { + if (SetVBarLabelPos(pl, ovlMode, bounds, ptc, t, start, end) == true) + return; + + if (ovlMode != DataLabelOverlapMode.RotateAroundPoint) + break; + + t.Y += step; + + if (cstyle.MaxLength > 0) + { + if (Math.Abs(t.Y - ptc.Y) > cstyle.MaxLength) + break; + } + } + + inside = !inside; + } + + SetVBarDefaultLabelPos(series, ref pl, pt, t, ovlMode, start, end); + } + + #endregion + + #region SetVBarLabelCenter + + private void SetVBarLabelCenter(ChartSeries series, PointLabel pl, + Rectangle bounds, DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle, + int origin, int end) + { + Point pt = new Point(pl.Point.X + series.BarOffset, (end + origin) / 2); + + int pass = 0; + int step = 2; + int starty = pt.Y; + + Size size = GetBoundsSize(series, pl, dstyle); + + Rectangle t = GetCenteredRectangle(series, pt, size); + + int len = (end + origin) / 2; + + while (pass <= len) + { + if (SetVBarLabelPos(pl, ovlMode, bounds, pt, t, origin, end) == true) + return; + + if (ovlMode != DataLabelOverlapMode.RotateAroundPoint) + break; + + int pval = pass / 2 + 1; + + if (pass % 2 > 0) + pval = -pval; + + t.Y = (starty + (pval * step)); + + pass++; + } + + SetVBarDefaultLabelPos(series, ref pl, pt, t, ovlMode, origin, end); + } + + #endregion + + #region SetVBarLabelPos + + private bool SetVBarLabelPos(PointLabel pl, + DataLabelOverlapMode ovlMode, Rectangle bounds, Point pt, Rectangle t, int start, int end) + { + if (IsFreeArea(t, bounds, ovlMode, false, true) == true) + { + pl.Bounds = t; + + SetVBarEdgePoint(pl, pt, t, start, end); + + return (true); + } + + if (ovlMode == DataLabelOverlapMode.HideOverlapping) + return (true); + + return (false); + } + + #endregion + + #region SetVBarDefaultLabelPos + + private void SetVBarDefaultLabelPos(ChartSeries series, ref PointLabel pl, + Point pt, Rectangle t, DataLabelOverlapMode ovlMode, int start, int end) + { + if (ovlMode == DataLabelOverlapMode.RotateAroundPoint) + { + if (t.Y > start) + t.Y = start - (t.Height + Dpi.Height4); + else + t.Y = end + Dpi.Height4; + + ChartXy chartXy = series.Parent as ChartXy; + + Rectangle bounds = chartXy.ContentBoundsEx; + + if (t.Y > bounds.Bottom) + t.Y -= (t.Bottom - bounds.Bottom + Dpi.Height4); + + if (t.Y < bounds.Y) + t.Y = bounds.Y + Dpi.Height4; + + pl.Bounds = t; + + SetVBarEdgePoint(pl, pt, t, start, end); + } + else + { + pl.Bounds = Rectangle.Empty; + pl.EdgePoint = Point.Empty; + } + } + + #endregion + + #region SetVBarEdgePoint + + private void SetVBarEdgePoint(PointLabel pl, Point pt, Rectangle t, int start, int end) + { + if (t.Y > start && t.Y > end) + { + pt.Y = Math.Max(start, end); + pl.EdgePoint = new Point(pt.X, t.Y); + } + else if (t.Y < start && t.Y < end) + { + pt.Y = Math.Min(start, end); + pl.EdgePoint = new Point(pt.X, t.Bottom); + } + else + { + pl.EdgePoint = Point.Empty; + } + + pl.Point = pt; + } + + #endregion + + #endregion + + #region IteratePoint + + private void IteratePoint(ChartSeries series, PointLabel pl, + Rectangle bounds, Point lp, DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle) + { + if ((dstyle.CenterLabel != Tbool.True) || + SetLabelCenter(series, pl, bounds, ovlMode, dstyle) == false) + { + ConnectorLineVisualStyle cstyle = dstyle.ConnectorLineStyle; + + int step; + int startAngle = GetStartAngle(lp, pl, cstyle, out step); + + int offset = 0; + + if (cstyle.Origin == ConnectorOrigin.Edge) + { + offset = Math.Max( + pl.SeriesPoint.PointSize.Width, + pl.SeriesPoint.PointSize.Height) / 2; + } + + SetLabel(series, pl, startAngle, step, + cstyle.MinLength + offset, cstyle.MaxLength + offset, ovlMode, bounds, dstyle); + } + } + + #endregion + + #region GetBoundsSize + + private Size GetBoundsSize( + ChartSeries series, PointLabel pl, DataLabelVisualStyle dstyle) + { + RotateDegrees rotate = series.GetRotateDegrees(dstyle); + + Size size = (rotate == RotateDegrees.Rotate90 || rotate == RotateDegrees.Rotate270) + ? new Size(pl.LabelSize.Height, pl.LabelSize.Width) : pl.LabelSize; + + if (dstyle.HasBorder == true) + { + size.Width += (dstyle.BorderThickness << 1); + size.Height += (dstyle.BorderThickness << 1); + } + + size.Width += dstyle.Padding.Horizontal; + size.Height += dstyle.Padding.Vertical; + + return (size); + } + + #endregion + + #region SetLabelCenter + + private bool SetLabelCenter(ChartSeries series, PointLabel pl, + Rectangle bounds, DataLabelOverlapMode ovlMode, DataLabelVisualStyle dstyle) + { + Rectangle t = GetCenteredRectangle(series, pl.Point, pl.LabelSize); + + if (IsFreeArea(t, bounds, ovlMode, true, true) == true) + { + pl.Bounds = t; + pl.EdgePoint = new Point(t.Right, t.Bottom); + + return (true); + } + + if (ovlMode == DataLabelOverlapMode.HideOverlapping) + return (true); + + return (false); + } + + #endregion + + #region SetLabel + + private bool SetLabel(ChartSeries series, PointLabel pl, int startAngle, int step, + int radius, int maxRadius, DataLabelOverlapMode ovlMode, Rectangle bounds, DataLabelVisualStyle dstyle) + { + int angle = startAngle; + int pass = 0; + + radius = Dpi.Width(radius); + maxRadius = Dpi.Width(maxRadius); + + while (radius <= maxRadius) + { + Point calcPoint; + Rectangle r = GetAreaRectangle(series, pl, angle, radius, out calcPoint, dstyle); + + if (IsFreeArea(r, bounds, ovlMode, true, true) == true) + { + pl.Angle = angle; + pl.Bounds = r; + pl.EdgePoint = calcPoint; + + return (true); + } + + if (ovlMode != DataLabelOverlapMode.RotateAroundPoint) + break; + + int pval = pass / 2 + 1; + + if (pass % 2 > 0) + pval = -pval; + + angle = (startAngle + (pval * step)) % 360; + + pass++; + + if (pass * step >= 360) + { + radius += Dpi.Width15; + pass = 0; + } + } + + pl.Bounds = Rectangle.Empty; + pl.EdgePoint = Point.Empty; + + return (false); + } + + #endregion + + #region GetStartAngle + + private int GetStartAngle(Point lp, + PointLabel pl, ConnectorLineVisualStyle cstyle, out int step) + { + step = cstyle.AngleStep; + + if (cstyle.DefaultAngle >= 0) + return (cstyle.DefaultAngle); + + Point pt = pl.Point; + + int rise = lp.Y - pt.Y; + int run = lp.X - pt.X; + + double slope = (run == 0) ? 0 : (double)rise / run; + + return ((slope < 1) ? 270 : (slope > 0) ? 315 : 225); + } + + #endregion + + #region GetCenteredRectangle + + private Rectangle GetCenteredRectangle( + ChartSeries series, Point pt, Size labelSize) + { + Rectangle r = new Rectangle(pt, labelSize); + + r.X -= (r.Width / 2); + r.Y -= (r.Height / 2); + + return (r); + } + + #endregion + + #region GetAreaRectangle + + private Rectangle GetAreaRectangle(ChartSeries series, PointLabel pl, + int angle, int radius, out Point calcPoint, DataLabelVisualStyle dstyle) + { + Rectangle r = new Rectangle(pl.Point, pl.LabelSize); + + RotateDegrees rotate = series.GetRotateDegrees(dstyle); + + if (rotate == RotateDegrees.Rotate90 || rotate == RotateDegrees.Rotate270) + { + r.Width = pl.LabelSize.Height; + r.Height = pl.LabelSize.Width; + } + + if (dstyle.HasBorder == true) + { + int n = Dpi.Width(dstyle.BorderThickness) << 1; + + r.Width += n; + r.Height += n; + } + + r.Width += Dpi.Width(dstyle.Padding.Horizontal); + r.Height += Dpi.Height(dstyle.Padding.Vertical); + + r.X += (int)(radius * Math.Cos(MathHelper.ToRadians(angle))); + r.Y += (int)(radius * Math.Sin(MathHelper.ToRadians(angle))); + + calcPoint = r.Location; + + return (OffsetAreaRectangle(r, angle, ref calcPoint, dstyle)); + } + + #region OffsetAreaRectangle + + private Rectangle OffsetAreaRectangle(Rectangle r, + int angle, ref Point calcPoint, DataLabelVisualStyle dstyle) + { + if (angle == 0) + { + r.Y -= (r.Height / 2); + } + else if (angle == 90) + { + r.X -= (r.Width / 2); + } + else if (angle == 180) + { + r.X -= r.Width; + r.Y -= (r.Height / 2); + } + else if (angle == 270) + { + r.X -= (r.Width / 2); + r.Y -= r.Height; + } + else if (angle < 90) + { + } + else if (angle < 180) + { + r.X -= r.Width; + } + else if (angle < 270) + { + r.X -= r.Width; + r.Y -= r.Height; + } + else + { + r.Y -= r.Height; + } + + return (r); + } + + #endregion + + #endregion + + #region IsFreeArea + + private bool IsFreeArea( + Rectangle r, Rectangle bounds, DataLabelOverlapMode ovlMode, bool xos, bool yos) + { + if (xos == true) + { + if (r.X < bounds.X || r.Right > bounds.Right) + return (false); + } + + if (yos == true) + { + if (r.Y < bounds.Y || r.Bottom > bounds.Bottom) + return (false); + } + + if (ovlMode == DataLabelOverlapMode.ShowOverlapping) + return (true); + + r.Inflate(3, 3); + + for (int i = 0; i < _LabelGroups.Count; i++) + { + List lps = _LabelGroups[i].PointLabels; + + for (int j = 0; j < lps.Count; j++) + { + PointLabel pl = lps[j]; + + if (pl.Bounds.IsEmpty == false) + { + if (pl.Bounds.IntersectsWith(r) == true) + return (false); + } + } + } + + return (true); + } + + #endregion + + #endregion + } +} + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/PointLabel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/PointLabel.cs new file mode 100644 index 00000000..36fa40f4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/PointLabel.cs @@ -0,0 +1,351 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents a PointLabel group. + /// + public class PointLabelGroup + { + #region Private data + + private ChartSeries _ChartSeries; + private List _PointLabels; + + #endregion + + public PointLabelGroup(ChartSeries chartSeries, List pointLabels) + { + _ChartSeries = chartSeries; + _PointLabels = pointLabels; + } + + #region Public properties + + #region ChartSeries + + /// + /// Gets or sets the associated chart series. + /// + public ChartSeries ChartSeries + { + get { return (_ChartSeries); } + set { _ChartSeries = value; } + } + + #endregion + + #region PointLabels + + /// + /// Gets or sets the associated list of PointLabels. + /// + public List PointLabels + { + get { return (_PointLabels); } + set { _PointLabels = value; } + } + + #endregion + + #endregion + } + + /// + /// Represents a PointLabel (label associated with a data point in the chart). + /// + public class PointLabel : IDisposable + { + #region Private data + + private SeriesPoint _SeriesPoint; + + private float _Angle; + private Rectangle _Bounds; + private Point _EdgePoint; + private Point _Point; + + private string _Label; + private Size _LabelSize; + + private BarLabelPosition _BarLabelPosition = BarLabelPosition.NotSet; + + private DataLabelVisualStyle _DataLabelVisualStyle; + + private States _States; + + #endregion + + public PointLabel(SeriesPoint sp, Point pt, string label) + { + _SeriesPoint = sp; + _Point = pt; + _Label = label; + + InitDefaultStates(); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.Visible, true); + SetState(States.NeedsMeasured, true); + } + + #endregion + + #region Public properties + + #region Angle + + /// + /// Gets the angle used to display the point label + /// associated with the data point. + /// + public float Angle + { + get { return (_Angle); } + internal set { _Angle = value; } + } + + #endregion + + #region BarLabelPosition + + /// + /// Gets or sets the position of bar series labels. + /// + [Description("Indicates the position of bar series labels.")] + public BarLabelPosition BarLabelPosition + { + get { return (_BarLabelPosition); } + set { _BarLabelPosition = value; } + } + + #endregion + + #region DataLabelVisualStyle + + /// + /// Gets or sets the visual style for the data label. + /// + public DataLabelVisualStyle DataLabelVisualStyle + { + get { return (_DataLabelVisualStyle); } + + set + { + if (value != _DataLabelVisualStyle) + { + DataLabelVisualStyle oldValue = _DataLabelVisualStyle; + + _DataLabelVisualStyle = value; + + StyleVisualChangeHandler(oldValue, value); + } + } + } + + #endregion + + #region FixedSize + + /// + /// Gets or set whether the LabelSize is a fixed size. + /// + public bool IsFixedSize + { + get { return (TestState(States.IsFixedSize)); } + set { SetState(States.IsFixedSize, value); } + } + + #endregion + + #region Label + + /// + /// Gets or sets the label text + /// + public string Label + { + get { return (_Label); } + + set + { + NeedsMeasured = true; + + _Label = value; + } + } + + #endregion + + #region LabelSize + + /// + /// Gets or sets the label size. + /// + public Size LabelSize + { + get { return (_LabelSize); } + + set + { + _LabelSize = value; + + NeedsMeasured = false; + } + } + + #endregion + + #region SeriesPoint + + /// + /// Gets the associated SeriesPoint. + /// + public SeriesPoint SeriesPoint + { + get { return (_SeriesPoint); } + internal set { _SeriesPoint = value; } + } + + #endregion + + #region Visible + + /// + /// Gets or sets whether the label is visible. + /// + public bool Visible + { + get { return (TestState(States.Visible)); } + set { SetState(States.Visible, value); } + } + + #endregion + + #endregion + + #region Internal properties + + #region Bounds + + internal Rectangle Bounds + { + get { return (_Bounds); } + set { _Bounds = value; } + } + + #endregion + + #region EdgePoint + + internal Point EdgePoint + { + get { return (_EdgePoint); } + set { _EdgePoint = value; } + } + + #endregion + + #region IsDataLabel + + internal bool IsDataLabel + { + get { return (TestState(States.IsDataLabel)); } + set { SetState(States.IsDataLabel, value); } + } + + #endregion + + #region NeedsMeasured + + internal bool NeedsMeasured + { + get { return (TestState(States.NeedsMeasured)); } + set { SetState(States.NeedsMeasured, value); } + } + + #endregion + + #region Point + + internal Point Point + { + get { return (_Point); } + set { _Point = value; } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + IsFixedSize = (1U << 0), + NeedsMeasured = (1U << 1), + Visible = (1U << 2), + IsDataLabel = (1U << 3), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region StyleVisualChangeHandler + + private void StyleVisualChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + private void StyleChanged(object sender, PropertyChangedEventArgs e) + { + NeedsMeasured = true; + } + + #endregion + + #region IDisposable + + public void Dispose() + { + DataLabelVisualStyle = null; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/PointMarker.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/PointMarker.cs new file mode 100644 index 00000000..0decf0d3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/PointMarker.cs @@ -0,0 +1,565 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + internal class PointMarker : IDisposable + { + #region Private variables + + private List _Bitmaps = new List(); + + #endregion + + #region GetMarkerBitmap + + public Bitmap GetMarkerBitmap(Graphics g, PointMarkerType markerType, int markerPoints, + Size size, int markerRotation, Background background, Color borderColor, int borderWidth) + { + if (markerType == PointMarkerType.None || markerType == PointMarkerType.NotSet) + return (null); + + if (markerType == PointMarkerType.Cross || + background == null || background.IsEmpty) + { + if (borderColor.IsEmpty) + borderColor = Color.Black; + } + + // Add margin to permit better antialiasing of image + + size.Width++; + size.Height++; + + Bitmap bitmap = null; + + bitmap = FindBitmap(markerType, markerPoints, + size, markerRotation, background, borderColor, borderWidth); + + if (bitmap == null) + { + size.Width = Math.Max(size.Width, 3); + size.Height = Math.Max(size.Height, 3); + + Rectangle r = new Rectangle(Point.Empty, size); + + using (GraphicsPath path = + GetMarkerPath(markerType, markerPoints, markerRotation, r, borderWidth)) + { + if (path != null) + { + bitmap = new Bitmap(size.Width, size.Height, g); + + using (Graphics gBmp = Graphics.FromImage(bitmap)) + { + gBmp.SmoothingMode = SmoothingMode.AntiAlias; + + FillMarkerPath(gBmp, path, r, markerType, background, borderColor, borderWidth); + + if (markerRotation != 0 && markerRotation != -1) + { + Bitmap bitmap2 = RotatePic(bitmap, markerRotation); + + bitmap.Dispose(); + + bitmap = bitmap2; + } + + _Bitmaps.Add(new BitmapEntry(markerType, size, markerPoints, + markerRotation, background, borderColor, borderWidth, bitmap)); + } + } + } + } + + return (bitmap); + } + + #endregion + + #region FindBitmap + + public Bitmap FindBitmap(PointMarkerType markerType, int markerPoints, + Size size, int markerRotation, Background background, Color borderColor, int borderWidth) + { + foreach (BitmapEntry entry in _Bitmaps) + { + if (entry.MarkerType == markerType && + entry.MarkerPoints == markerPoints && + entry.MarkerRotation == markerRotation && + entry.MarkerSize.Equals(size) && + entry.BorderWidth == borderWidth && + entry.BorderColor.Equals(borderColor) && + entry.Background.IsEqualTo(background)) + { + return (entry.Bitmap); + } + } + + return (null); + } + + #endregion + + #region GetMarkerPath + + internal GraphicsPath GetMarkerPath( PointMarkerType markerType, + int markerPoints, int markerRotation, Rectangle r, int borderWidth) + { + r.Inflate(-borderWidth, -borderWidth); + + if (r.Width > 0 && r.Height > 0) + { + switch (markerType) + { + case PointMarkerType.Ellipse: + return (GetCirclePath(r)); + + case PointMarkerType.Cross: + return (GetCrossPath(r, markerPoints)); + + case PointMarkerType.Diamond: + return (GetDiamondPath(r)); + + case PointMarkerType.Rectangle: + return (GetRectanglePath(r)); + + case PointMarkerType.Star: + return (GetStarPath(r, markerPoints)); + + case PointMarkerType.Triangle: + return (GetTrianglePath(r)); + + default: + return (GetPolygonPath(r, markerPoints)); + } + } + + return (null); + } + + #region GetCirclePath + + private GraphicsPath GetCirclePath(Rectangle r) + { + GraphicsPath path = new GraphicsPath(); + + path.AddEllipse(r); + + return (path); + } + + #endregion + + #region GetCrossPath + + private GraphicsPath GetCrossPath(Rectangle r, int points) + { + GraphicsPath path = new GraphicsPath(); + + PointF[] pts = new PointF[2 * points]; + + double rx1 = r.Width / 2; + double ry1 = r.Height / 2; + + if (rx1 < 2) + rx1 = 2; + + if (ry1 < 2) + ry1 = 2; + + double cx = r.X + rx1; + double cy = r.Y + ry1; + + double theta = MathHelper.ToRadians(270); + double dtheta = Math.PI / points; + + for (int i = 0; i < 2 * points; i += 2) + { + pts[i] = new PointF( + (float)(cx + rx1 * Math.Cos(theta)), + (float)(cy + ry1 * Math.Sin(theta))); + + pts[i + 1] = new PointF((float)cx, (float)cy); + + theta += (dtheta * 2); + } + + path.AddPolygon(pts); + + path.CloseAllFigures(); + + return (path); + } + + #endregion + + #region GetDiamondPath + + private GraphicsPath GetDiamondPath(Rectangle r) + { + GraphicsPath path = new GraphicsPath(); + + int dx = r.Width / 2; + int dy = r.Height / 2; + + int mx = r.X + dx; + int my = r.Y + dy; + + Point[] pts = + { + new Point(mx, my - dy), + new Point(mx + dx, my), + new Point(mx, my + dy), + new Point(mx - dx, my), + }; + + path.AddPolygon(pts); + + path.CloseAllFigures(); + + return (path); + } + + #endregion + + #region GetPolygonPath + + private GraphicsPath GetPolygonPath(Rectangle r, int sides) + { + if (sides <= 4) + return (GetRectanglePath(r)); + + GraphicsPath path = new GraphicsPath(); + + int radius = Math.Min(r.Width, r.Height); + + float dx = (float)radius / 2; + float radians = (float)MathHelper.ToRadians(270); + float delta = (float)MathHelper.ToRadians((float)360 / sides); + + Point[] pts = new Point[sides]; + + for (int i = 0; i < sides; i++) + { + pts[i] = new Point( + (int)(dx * Math.Cos(radians) + dx + r.X), + (int)(dx * Math.Sin(radians) + dx + r.Y)); + + radians += delta; + } + + path.AddPolygon(pts); + + path.CloseAllFigures(); + + if (r.Width != r.Height) + { + PointF[] dp = + { + new PointF(0, 0), + new PointF(r.Width, 0), + new PointF(0, r.Height), + }; + + path.Warp(dp, new RectangleF(0, 0, radius, radius)); + } + + return (path); + } + + #endregion + + #region GetRectanglePath + + private GraphicsPath GetRectanglePath(Rectangle r) + { + GraphicsPath path = new GraphicsPath(); + + path.AddRectangle(r); + + return (path); + } + + #endregion + + #region GetStarPath + + private GraphicsPath GetStarPath(Rectangle r, int points) + { + if (points < 2) + points = 2; + + GraphicsPath path = new GraphicsPath(); + + PointF[] pts = new PointF[2 * points]; + + double rx1 = r.Width / 2; + double ry1 = r.Height / 2; + + if (rx1 < 2) + rx1 = 2; + + if (ry1 < 2) + ry1 = 2; + + double rx2 = rx1 / 2; + double ry2 = ry1 / 2; + + double cx = r.X + rx1; + double cy = r.Y + ry1; + + double theta = MathHelper.ToRadians(270); + double dtheta = Math.PI / points; + + for (int i = 0; i < 2 * points; i += 2) + { + pts[i] = new PointF( + (float)(cx + rx1 * Math.Cos(theta)), + (float)(cy + ry1 * Math.Sin(theta))); + + theta += dtheta; + + pts[i + 1] = new PointF( + (float)(cx + rx2 * Math.Cos(theta)), + (float)(cy + ry2 * Math.Sin(theta))); + + theta += dtheta; + } + + path.AddPolygon(pts); + + path.CloseAllFigures(); + + return (path); + } + + #endregion + + #region GetTrianglePath + + private GraphicsPath GetTrianglePath(Rectangle r) + { + // Equal height and width will not be adjusted to make + // an equalaterial triangle - thus rotation will skew image. + + GraphicsPath path = new GraphicsPath(); + + int dx = r.Width / 2; + int dy = r.Height / 2; + + Point[] pts = { + new Point(r.X + dx, r.Y), + new Point(r.X , r.Y + dy * 2), + new Point(r.X + dx * 2, r.Y + dy * 2), + }; + + path.AddPolygon(pts); + + path.CloseAllFigures(); + + return (path); + } + + #endregion + + #endregion + + #region FillMarkerPath + + internal void FillMarkerPath(Graphics g, GraphicsPath path, Rectangle r, + PointMarkerType markerType, Background background, Color borderColor, int borderWidth) + { + if (markerType != PointMarkerType.Cross) + { + BackFillType fillType = GetMarkerFillType(markerType, background); + + using (Brush br = background.GetBrush(r, -1, fillType)) + g.FillPath(br, path); + } + + if (borderColor.IsEmpty == false && borderWidth > 0) + { + using (Pen pen = new Pen(borderColor, borderWidth)) + g.DrawPath(pen, path); + } + } + + #region GetMarkerFillType + + private BackFillType GetMarkerFillType(PointMarkerType markerType, Background background) + { + if (background.Color2.IsEmpty == true) + return (BackFillType.None); + + if (background.BackFillType == BackFillType.Auto) + { + switch (markerType) + { + case PointMarkerType.Ellipse: + case PointMarkerType.Star: + return (BackFillType.Center); + + default: + return (BackFillType.VerticalCenter); + } + } + + return (background.BackFillType); + } + + #endregion + + #endregion + + #region RotatePic + + private Bitmap RotatePic(Bitmap obmp, float angle) + { + float rad = (float)MathHelper.ToRadians(angle); + + double fW = Math.Abs((Math.Cos(rad) * obmp.Width)) + Math.Abs((Math.Sin(rad) * obmp.Height)); + double fH = Math.Abs((Math.Sin(rad) * obmp.Width)) + Math.Abs((Math.Cos(rad) * obmp.Height)); + + Bitmap nbmp = new Bitmap((int)Math.Ceiling(fW), (int)Math.Ceiling(fH)); + + using (Graphics g = Graphics.FromImage(nbmp)) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + + float hw = nbmp.Width / 2f; + float hh = nbmp.Height / 2f; + + Matrix m = g.Transform; + + m.RotateAt(angle, new PointF(hw, hh), MatrixOrder.Append); + + g.Transform = m; + + g.DrawImage(obmp, new PointF((float)((nbmp.Width - obmp.Width) / 2), (float)((nbmp.Height - obmp.Height) / 2))); + } + + return nbmp; + } + + #endregion + + #region Clear + + public void Clear() + { + foreach (BitmapEntry entry in _Bitmaps) + { + entry.Background.Dispose(); + entry.Bitmap.Dispose(); + } + + _Bitmaps.Clear(); + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + Clear(); + } + + #endregion + + #region BitmapEntry + + private class BitmapEntry + { + public PointMarkerType MarkerType; + public Size MarkerSize; + public int MarkerPoints; + public int MarkerRotation; + + public Background Background; + public Color BorderColor; + public int BorderWidth; + + public Bitmap Bitmap; + + public BitmapEntry(PointMarkerType markerType, Size markerSize, int markerPoints, + int markerRotation, Background background, Color borderColor, int borderWidth, Bitmap bitmap) + { + MarkerType = markerType; + MarkerSize = markerSize; + MarkerPoints = markerPoints; + MarkerRotation = markerRotation; + + Background = background.Copy(); + BorderColor = borderColor; + BorderWidth = borderWidth; + + Bitmap = bitmap; + } + } + + #endregion + } + + #region enums + + #region PointMarkerType + + public enum PointMarkerType + { + /// + /// Type not set. + /// + NotSet = -1, + + /// + /// No Marker + /// + None, + + /// + /// Cross + /// + Cross, + + /// + /// Diamond + /// + Diamond, + + /// + /// Ellipse + /// + Ellipse, + + /// + /// Polygon (Pentagon, Hexagon, etc) + /// + Polygon, + + /// + /// Rectangle + /// + Rectangle, + + /// + /// Star + /// + Star, + + /// + /// Triangle + /// + Triangle, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ReferenceLine.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ReferenceLine.cs new file mode 100644 index 00000000..c803421b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartControl/XyChart/ReferenceLine.cs @@ -0,0 +1,1599 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.Charts.TextMarkup; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents the collection of ReferenceLines. + /// + [Editor("DevComponents.Charts.Design.AxisReferenceCollectionEditor, DevComponents.Charts.Design, " + + "Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public class ReferenceLineCollection : CustomNamedCollection + { + #region GetUniqueName + + /// + /// Gets a unique (unused) reference line Name. + /// + /// + public string GetUniqueName() + { + return (GetUniqueName("RefLine")); + } + + #endregion + } + + /// + /// Represents a reference line (a vertical or horizontal line on the chart + /// that can be used to signify, or reference, a specific axis/chart value). + /// + public class ReferenceLine : ChartVisualElement, ILegendItem + { + #region Private variables + + private States _States; + + private object _AxisValue; + + private string _Text; + private Size _TextSize; + private BodyElement _TextMarkup; + + private Rectangle _LineBounds; + private int _MaxLineCount = 3; + + private ReferenceLineVisualStyle _ReferenceLineVisualStyle; + private EffectiveStyle _EffectiveStyle; + + private string _LegendText; + private ChartLegendItem _LegendItem; + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + + #endregion + + #region Constructors + + /// + /// ReferenceLine + /// + public ReferenceLine() + { + InitDefaultStates(); + + _EffectiveStyle = new EffectiveStyle(this); + } + + /// + /// ReferenceLine + /// + /// + public ReferenceLine(string name) + : this() + { + Name = name; + } + + /// + /// ReferenceLine + /// + /// + /// + public ReferenceLine(string name, object axisValue) + : this(name) + { + AxisValue = axisValue; + } + + /// + /// ReferenceLine + /// + /// + /// + public ReferenceLine(string name, object axisValue, string text) + : this(name, axisValue) + { + Text = text; + } + + #endregion + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.CheckedInLegend, true); + SetState(States.ShowInLegend, true); + SetState(States.ShowInParentLegend, true); + SetState(States.ShowCheckBoxInLegend, true); + SetState(States.ShowMarkerInLegend, true); + SetState(States.DisplayTextOnTop, true); + } + + #endregion + + #region Public properties + + #region AxisValue + + /// + /// Gets or sets the associated axis value of the reference line. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the associated axis value of the reference line.")] + [TypeConverter("DevComponents.Charts.Design.PointValueConverter," + + "DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public object AxisValue + { + get { return (_AxisValue); } + + set + { + if (value != _AxisValue) + { + _AxisValue = value; + + if (_LegendItem != null) + { + if (string.IsNullOrEmpty(Name) && string.IsNullOrEmpty(LegendText)) + { + ChartAxis axis = Parent as ChartAxis; + + _LegendItem.ItemText = axis.AxisOrientation + "-Axis: " + AxisValue; + } + } + + OnPropertyChangedEx("AxisValue", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DisplayLineOnTop + + /// + /// Gets or sets whether the reference line is displayed on top of chart data. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the reference line is displayed on top of chart data.")] + public bool DisplayLineOnTop + { + get { return (TestState(States.DisplayLineOnTop)); } + + set + { + if (value != DisplayLineOnTop) + { + SetState(States.DisplayLineOnTop, value); + + OnPropertyChangedEx("DisplayLineOnTop", VisualChangeType.Render); + } + } + } + + #endregion + + #region DisplayTextOnTop + + /// + /// Gets or sets whether the reference text is displayed on top of chart data. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the reference text is displayed on top of chart data.")] + public bool DisplayTextOnTop + { + get { return (TestState(States.DisplayTextOnTop)); } + + set + { + if (value != DisplayTextOnTop) + { + SetState(States.DisplayTextOnTop, value); + + OnPropertyChangedEx("DisplayTextOnTop", VisualChangeType.Render); + } + } + } + + #endregion + + #region EffectiveStyle + + /// + /// Gets a reference to the ReferenceLine's Effective (cached, composite) style. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ReferenceLineVisualStyle EffectiveStyle + { + get { return (_EffectiveStyle.Style); } + } + + #endregion + + #region EnableTextMarkup + + /// + /// Gets or sets whether text-markup support is enabled for the reference line text + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for the reference line text.")] + public bool EnableTextMarkup + { + get { return (TestState(States.EnableTextMarkup)); } + + set + { + if (EnableTextMarkup != value) + { + SetState(States.EnableTextMarkup, value); + + MarkupTextChanged(); + + OnPropertyChangedEx("EnableTextMarkup", VisualChangeType.Layout); + } + } + } + + #region MarkupTextChanged + + private void MarkupTextChanged() + { + if (_TextMarkup != null) + _TextMarkup.HyperLinkClick -= TextMarkupLinkClick; + + _TextMarkup = null; + + if (EnableTextMarkup == true) + { + if (MarkupParser.IsMarkup(_Text) == true) + { + _TextMarkup = MarkupParser.Parse(_Text); + + if (_TextMarkup != null) + _TextMarkup.HyperLinkClick += TextMarkupLinkClick; + } + } + } + + #endregion + + #region TextMarkupLinkClick + + /// + /// Occurs when a text markup link is clicked + /// + protected virtual void TextMarkupLinkClick(object sender, EventArgs e) + { + HyperLink link = sender as HyperLink; + + if (link != null) + ChartControl.DoReferenceLineMarkupLinkClickEvent(this, link); + } + + #endregion + + #endregion + + #region InvertVerticalText + + /// + /// Gets or sets whether vertical reference text is inverted. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether vertical reference text is inverted.")] + public bool InvertVerticalText + { + get { return (TestState(States.InvertVerticalText)); } + + set + { + if (value != InvertVerticalText) + { + SetState(States.InvertVerticalText, value); + + OnPropertyChangedEx("InvertVerticalText", VisualChangeType.Render); + } + } + } + + #endregion + + #region MaxLineCount + + /// + /// Gets or sets the maximum number of Text lines. + /// + [DefaultValue(3), Category("Layout")] + [Description("Indicates the maximum number of Text lines.")] + public int MaxLineCount + { + get { return (_MaxLineCount); } + + set + { + if (value != _MaxLineCount) + { + _MaxLineCount = value; + + OnPropertyChangedEx("MaxLineCount", VisualChangeType.Layout); + } + } + } + + #endregion + + #region PlainText + + /// + /// Gets text without text-markup (if text-markup is used in Text) + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string PlainText + { + get { return (_TextMarkup != null ? _TextMarkup.PlainText : _Text); } + } + + #endregion + + #region ReferenceLineVisualStyle + + /// + /// Gets or sets the visual style for the ReferenceLine. + /// + [Category("Style")] + [Description("Indicates the visual style for the ReferenceLine.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ReferenceLineVisualStyle ReferenceLineVisualStyle + { + get + { + if (_ReferenceLineVisualStyle == null) + { + _ReferenceLineVisualStyle = new ReferenceLineVisualStyle(); + + StyleVisualChangeHandler(null, _ReferenceLineVisualStyle); + } + + return (_ReferenceLineVisualStyle); + } + + set + { + if (_ReferenceLineVisualStyle != value) + { + ReferenceLineVisualStyle oldValue = _ReferenceLineVisualStyle; + + _ReferenceLineVisualStyle = value; + + OnVisualStyleChanged("ReferenceLineVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region Text + + /// + /// Gets or sets the ReferenceLine Text. + /// + [DefaultValue(null), Category("Layout")] + [Description("Indicates the ReferenceLine Text.")] + public string Text + { + get { return (_Text); } + + set + { + if (value != _Text) + { + _Text = value; + + MarkupTextChanged(); + + OnPropertyChangedEx("Text", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region LineBounds + + internal Rectangle LineBounds + { + get + { + if (_LineBounds.IsEmpty == true) + _LineBounds = GetLineBounds(); + + return (_LineBounds); + } + + set { _LineBounds = value; } + } + + #endregion + + #region TextMarkup + + internal BodyElement TextMarkup + { + get { return (_TextMarkup); } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + _TextSize = Size.Empty; + } + + #region MeasureText + + private Size MeasureText(Graphics g, + ReferenceLineVisualStyle style, Size vsize) + { + Size size = Size.Empty; + + string s = Text; + + if (string.IsNullOrEmpty(s) == false) + { + if (TextMarkup != null) + { + size = GetMarkupTextSize(g, + TextMarkup, style, (vsize.Width > 0 ? vsize.Width : 10000)); + } + else + { + using (StringFormat sf = new StringFormat()) + { + style.GetStringFormatFlags(sf); + + if (MaxLineCount <= 1) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + size = g.MeasureString(Text, style.Font, vsize, sf).ToSize(); + } + } + + size.Width++; + size.Height++; + + if (MaxLineCount > 1) + { + int lineHeight = (int)(Math.Ceiling(style.Font.GetHeight())) * MaxLineCount; + + if (size.Height > lineHeight) + size.Height = lineHeight; + } + } + + return (size); + } + + #region GetMarkupTextSize + + private Size GetMarkupTextSize(Graphics g, + BodyElement textMarkup, ReferenceLineVisualStyle style, int width) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + textMarkup.InvalidateElementsSize(); + textMarkup.Measure(new Size(width, 0), d); + + return (textMarkup.Bounds.Size); + } + + #endregion + + #endregion + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + LineBounds = Rectangle.Empty; + + ChartAxis axis = Parent as ChartAxis; + + if (axis != null) + { + ChartXy chartXy = axis.Parent as ChartXy; + + if (chartXy != null) + { + Rectangle bounds = chartXy.ContentBounds; + + if (chartXy.HScrollBar.Enabled == true) + bounds.Height -= (chartXy.HScrollBar.Height); + + if (chartXy.VScrollBar.Enabled == true) + bounds.Width -= (chartXy.VScrollBar.Width); + + BoundsRelative = GetLineBoundsEx(); + } + } + } + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + } + + #region RenderLine + + internal void RenderLine(ChartRenderInfo renderInfo) + { + ChartAxis axis = Parent as ChartAxis; + + if (axis != null) + { + Graphics g = renderInfo.Graphics; + ChartXy chartXy = axis.Parent as ChartXy; + + Rectangle contentBounds = chartXy.ContentBounds; + + ReferenceLineVisualStyle rstyle = EffectiveStyle; + + if (axis.AxisOrientation == AxisOrientation.X) + RenderLineX(g, contentBounds, rstyle); + else + RenderLineY(g, contentBounds, rstyle); + } + } + + #region RenderLineX + + private void RenderLineX(Graphics g, + Rectangle contentBounds, ReferenceLineVisualStyle rstyle) + { + if (rstyle.LinePattern != LinePattern.None) + { + Rectangle lbounds = LineBounds; + + if (lbounds.X > contentBounds.X && lbounds.X < contentBounds.Right) + { + Point pt1 = lbounds.Location; + Point pt2 = new Point(pt1.X, lbounds.Bottom); + + using (Pen pen = new Pen(rstyle.LineColor, Dpi.Width(rstyle.LineWidth))) + { + if (rstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)rstyle.LinePattern; + + g.DrawLine(pen, pt2, pt1); + } + } + } + } + + #endregion + + #region RenderLineY + + private void RenderLineY(Graphics g, + Rectangle contentBounds, ReferenceLineVisualStyle rstyle) + { + if (rstyle.LinePattern != LinePattern.None) + { + Rectangle lbounds = LineBounds; + + if (lbounds.Y > contentBounds.Y && lbounds.Y < contentBounds.Bottom) + { + Point pt1 = lbounds.Location; + Point pt2 = new Point(lbounds.Right, pt1.Y); + + using (Pen pen = new Pen(rstyle.LineColor, Dpi.Height(rstyle.LineWidth))) + { + if (rstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)rstyle.LinePattern; + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #endregion + + #region RenderLineText + + internal void RenderLineText(ChartRenderInfo renderInfo) + { + ChartAxis axis = Parent as ChartAxis; + + if (axis != null) + { + Graphics g = renderInfo.Graphics; + ChartXy chartXy = axis.Parent as ChartXy; + + Rectangle bounds = chartXy.ContentBounds; + + if (chartXy.HScrollBar.Enabled == true) + bounds.Height -= (chartXy.HScrollBar.Height + 1); + + if (chartXy.VScrollBar.Enabled == true) + bounds.Width -= (chartXy.VScrollBar.Width + 1); + + ReferenceLineVisualStyle rstyle = EffectiveStyle; + + if (axis.AxisOrientation == AxisOrientation.X) + RenderTextX(g, bounds, rstyle); + else + RenderTextY(g, bounds, rstyle); + } + } + + #region RenderTextX + + private void RenderTextX(Graphics g, + Rectangle bounds, ReferenceLineVisualStyle rstyle) + { + Rectangle lbounds = LineBounds; + + if (lbounds.X > bounds.X && lbounds.X < bounds.Right) + { + if (_TextSize == Size.Empty) + { + Rectangle r = bounds; + + int n = r.Width; + r.Width = r.Height; + r.Height = n; + + if (rstyle.AllowWrap == Tbool.False) + r.Size = Size.Empty; + + _TextSize = MeasureText(g, rstyle, r.Size); + } + + int dy = (lbounds.Y + lbounds.Bottom) / 2; + Point pt = new Point(lbounds.X, dy); + + int rotDegrees = (InvertVerticalText == true) ? 90 : -90; + + g.TranslateTransform(pt.X, pt.Y); + g.RotateTransform(rotDegrees); + + Rectangle tbounds = new Rectangle( + -bounds.Height / 2, -rstyle.LineWidth / 2, bounds.Height, rstyle.LineWidth); + + switch (rstyle.TextAlignment) + { + case Alignment.TopLeft: + case Alignment.TopCenter: + case Alignment.TopRight: + tbounds.Y -= (_TextSize.Height + rstyle.TextPadding.Bottom); + break; + + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + tbounds.Y -= (_TextSize.Height - tbounds.Height) / 2 + (rstyle.TextPadding.Vertical / 2 - rstyle.TextPadding.Top); + break; + + case Alignment.BottomLeft: + case Alignment.BottomCenter: + case Alignment.BottomRight: + tbounds.Y += (rstyle.LineWidth + rstyle.TextPadding.Top); + break; + } + + switch (rstyle.TextAlignment) + { + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + tbounds.X = (tbounds.Right - _TextSize.Width); + tbounds.Width = _TextSize.Width; + break; + } + + tbounds.X += +rstyle.TextPadding.Left; + tbounds.Width -= rstyle.TextPadding.Horizontal; + tbounds.Height = _TextSize.Height; + + RenderText(g, tbounds, rstyle); + + g.ResetTransform(); + } + } + + #endregion + + #region RenderTextY + + private void RenderTextY(Graphics g, + Rectangle bounds, ReferenceLineVisualStyle rstyle) + { + Rectangle lbounds = LineBounds; + + if (lbounds.Y > bounds.Y && lbounds.Y < bounds.Bottom) + { + if (_TextSize == Size.Empty) + { + Rectangle r = bounds; + + if (rstyle.AllowWrap == Tbool.False) + r.Size = Size.Empty; + + _TextSize = MeasureText(g, rstyle, r.Size); + } + + Point pt1 = lbounds.Location; + Point pt2 = new Point(lbounds.Right, pt1.Y); + + Rectangle tbounds = new Rectangle(pt1.X, pt1.Y, pt2.X - pt1.X, 0); + + switch (rstyle.TextAlignment) + { + case Alignment.TopLeft: + case Alignment.TopCenter: + case Alignment.TopRight: + tbounds.Y -= ((rstyle.LineWidth / 2) + rstyle.TextPadding.Bottom + _TextSize.Height); + break; + + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + tbounds.Y -= ((_TextSize.Height + rstyle.TextPadding.Vertical) / 2 - rstyle.TextPadding.Top); + break; + + case Alignment.BottomLeft: + case Alignment.BottomCenter: + case Alignment.BottomRight: + tbounds.Y += ((rstyle.LineWidth / 2) + rstyle.TextPadding.Top); + break; + } + + switch (rstyle.TextAlignment) + { + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + tbounds.X = (tbounds.Right - _TextSize.Width - rstyle.TextPadding.Horizontal); + tbounds.Width = _TextSize.Width + rstyle.TextPadding.Horizontal; + break; + } + + tbounds.X += rstyle.TextPadding.Left; + tbounds.Width -= rstyle.TextPadding.Horizontal; + + tbounds.Height += _TextSize.Height; + + RenderText(g, tbounds, rstyle); + } + } + + #endregion + + #region RenderText + + private void RenderText( + Graphics g, Rectangle r, ReferenceLineVisualStyle style) + { + if (r.Width > 0 && r.Height > 0) + { + string s = Text; + + if (string.IsNullOrEmpty(s) == false) + { + if (TextMarkup != null) + { + RenderTextMarkup(g, r, style); + } + else + { + using (SolidBrush br = new SolidBrush(style.TextColor)) + { + using (StringFormat sf = new StringFormat()) + { + style.GetStringFormatFlags(sf); + + g.DrawString(Text, style.Font, br, r, sf); + } + } + } + } + } + } + + #region RenderTextMarkup + + private void RenderTextMarkup( + Graphics g, Rectangle r, ReferenceLineVisualStyle style) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + TextMarkup.Arrange(r, d); + + Size size = TextMarkup.Bounds.Size; + + TextMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + TextMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetLineBounds + + private Rectangle GetLineBounds() + { + ChartAxis axis = Parent as ChartAxis; + + if (axis != null) + { + ChartXy chartXy = axis.Parent as ChartXy; + + if (chartXy != null) + { + Rectangle bounds = chartXy.ContentBounds; + + if (chartXy.HScrollBar.Enabled == true) + bounds.Height -= (chartXy.HScrollBar.Height); + + if (chartXy.VScrollBar.Enabled == true) + bounds.Width -= (chartXy.VScrollBar.Width); + + Point pt; + + if (axis.AxisOrientation == AxisOrientation.X) + { + pt = new Point(axis.GetDisplayValue(AxisValue), bounds.Y); + pt = chartXy.GetLocalAdjustedPoint(pt); + pt.Y = bounds.Y; + } + else + { + pt = new Point(bounds.X, axis.GetDisplayValue(AxisValue)); + pt = chartXy.GetLocalAdjustedPoint(pt); + pt.X = bounds.X; + } + + return (new Rectangle(pt, bounds.Size)); + } + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetLineBoundsEx + + private Rectangle GetLineBoundsEx() + { + ChartAxis axis = Parent as ChartAxis; + + if (axis != null) + { + ChartXy chartXy = axis.Parent as ChartXy; + + if (chartXy != null) + { + Rectangle bounds = chartXy.ContentBounds; + + if (chartXy.HScrollBar.Enabled == true) + bounds.Height -= (chartXy.HScrollBar.Height); + + if (chartXy.VScrollBar.Enabled == true) + bounds.Width -= (chartXy.VScrollBar.Width); + + Point pt; + + if (axis.AxisOrientation == AxisOrientation.X) + pt = new Point(axis.GetDisplayValue(AxisValue), bounds.Y); + else + pt = new Point(bounds.X, axis.GetDisplayValue(AxisValue)); + + return (new Rectangle(pt, bounds.Size)); + } + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetDoubleValue + + private double GetDoubleValue(object value) + { + if (value is double) + return (double)value; + + return (Convert.ToDouble(value)); + } + + #endregion + + #region EnsureVisible + + /// + /// Ensures that the reference line is visible on screen. + /// + public void EnsureVisible() + { + EnsureVisible(false); + } + + /// + /// Ensures that the reference line is visible on screen, and + /// optionally centered (if possible). + /// + /// + public void EnsureVisible(bool center) + { + ChartAxis axis = Parent as ChartAxis; + + if (axis != null) + axis.EnsureVisible(AxisValue, center); + } + + #endregion + + #region Style handling + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style) + { + ReferenceLineVisualStyle rstyle = style as ReferenceLineVisualStyle; + + if (rstyle != null) + { + ApplyParentStyles(rstyle, Parent as ChartContainer); + + rstyle.ApplyStyle(ReferenceLineVisualStyle); + + if (rstyle.LineColor.IsEmpty == true) + rstyle.LineColor = Color.Red; + + if (rstyle.LineWidth < 0) + rstyle.LineWidth = 1; + + if (rstyle.Font == null) + rstyle.Font = SystemFonts.DefaultFont; + + if (rstyle.TextColor.IsEmpty == true) + rstyle.TextColor = Color.Black; + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles( + ReferenceLineVisualStyle pstyle, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, item.Parent as ChartContainer); + + ChartPanel cp = item as ChartPanel; + + if (cp != null) + pstyle.ApplyStyle(cp.DefaultVisualStyles.ReferenceLineVisualStyle); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.ReferenceLineVisualStyle); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ReferenceLineVisualStyle); + } + } + + #endregion + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Style definition + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + if (_EffectiveStyle.InvalidateStyle() == true) + InvalidateLayout(); + + if (LegendItem != null) + LegendItem.EffectiveStyles.InvalidateStyles(); + } + + #endregion + + #region StyleChanged + + protected override void StyleChanged(object sender, PropertyChangedEventArgs e) + { + base.StyleChanged(sender, e); + + if (sender is ChartLegendItemVisualStyles && LegendItem != null) + InvalidateRender(LegendItem.Bounds); + } + + #endregion + + #endregion + + #region ILegendItem + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the visual styles for the Legend item. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Legend item.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleVisualChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (_ChartLegendItemVisualStyles != value) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendItemVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CheckedInLegend + + /// + /// Gets or sets whether the ReferenceLine is checked in the Legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the ReferenceLine is checked in the Legend.")] + public bool CheckedInLegend + { + get { return (TestState(States.CheckedInLegend)); } + + set + { + if (value != CheckedInLegend) + { + SetState(States.CheckedInLegend, value); + + if (LegendItem != null) + LegendItem.UpdateCheckState(); + + OnPropertyChangedEx("CheckedInLegend", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowCheckBoxInLegend + + /// + /// Gets or sets whether a checkbox for the ReferenceLine is shown in the Legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether a checkbox for the ReferenceLine is shown in the Legend.")] + public bool ShowCheckBoxInLegend + { + get { return (TestState(States.ShowCheckBoxInLegend)); } + + set + { + if (value != ShowCheckBoxInLegend) + { + SetState(States.ShowCheckBoxInLegend, value); + + OnPropertyChangedEx("ShowCheckBoxInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInLegend + + /// + /// Gets or sets whether the ReferenceLine is shown in the Legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the ReferenceLine is shown in the Legend.")] + public bool ShowInLegend + { + get { return (TestState(States.ShowInLegend)); } + + set + { + if (value != ShowInLegend) + { + SetState(States.ShowInLegend, value); + + OnPropertyChangedEx("ShowInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInParentLegend + + /// + /// Gets or sets whether the Reference Line is shown in parent Legend(s). + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the Reference Line is shown in parent Legend(s).")] + public bool ShowInParentLegend + { + get { return (TestState(States.ShowInParentLegend)); } + + set + { + if (value != ShowInParentLegend) + { + SetState(States.ShowInParentLegend, value); + + OnPropertyChangedEx("ShowInParentLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowMarkerInLegend + + /// + /// Gets or sets whether the ReferenceLine Marker is shown in the Legend. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the ReferenceLine Marker is shown in the Legend.")] + public bool ShowMarkerInLegend + { + get { return (TestState(States.ShowMarkerInLegend)); } + + set + { + if (value != ShowMarkerInLegend) + { + SetState(States.ShowMarkerInLegend, value); + + OnPropertyChangedEx("ShowMarkerInLegend", VisualChangeType.Layout); + } + } + } + + #endregion + + #region LegendItem + + /// + /// Gets the item's parent LegendItem. + /// + [Description("Indicates the item's parent LegendItem.")] + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ChartLegendItem LegendItem + { + get { return (_LegendItem); } + internal set { _LegendItem = value; } + } + + #endregion + + #region LegendText + + /// + /// Gets or sets the text to display in the legend. + /// + [DefaultValue(null), Category("DataLabel")] + [Description("Indicates the text to display in the legend.")] + public string LegendText + { + get { return (_LegendText); } + + set + { + if (value != _LegendText) + { + _LegendText = value; + + OnPropertyChangedEx("LegendText", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region GetLegendItem + + public ChartLegendItem GetLegendItem() + { + _LegendItem = null; + + if (ShowInLegend == true) + { + _LegendItem = new ChartLegendItem(); + + if (CheckedInLegend == true) + _LegendItem.CheckState = CheckState.Checked; + + _LegendItem.Name = Name; + _LegendItem.ItemText = LegendText; + + if (string.IsNullOrEmpty(_LegendItem.Name) == true) + _LegendItem.Name = "(RefLine)"; + + _LegendItem.ChartItems.Add(this); + } + + return (_LegendItem); + } + + #endregion + + #region GetLegendItems + + public List GetLegendItems() + { + List list = null; + + ChartLegendItem item = GetLegendItem(); + + if (item != null) + { + list = new List(1); + + list.Add(item); + } + + return (list); + } + + #endregion + + #region GetLegendItemColor + + public Color GetLegendItemColor() + { + ReferenceLineVisualStyle rstyle = EffectiveStyle; + + return (rstyle.LineColor); + } + + #endregion + + #region RenderLegendItemMarker + + public void RenderLegendItemMarker(Graphics g, + ChartLegendItem litem, ChartLegendItemVisualStyle style) + { + ReferenceLineVisualStyle rstyle = EffectiveStyle; + + if (rstyle.LinePattern != LinePattern.None) + { + Rectangle bounds = litem.MarkerBounds; + + int n = bounds.Height / 2; + + int lineWidth = Math.Min(rstyle.LineWidth, bounds.Height); + + using (Pen pen = new Pen(GetLegendItemColor(), lineWidth)) + { + if (rstyle.LinePattern != LinePattern.NotSet) + pen.DashStyle = (DashStyle)rstyle.LinePattern; + + g.DrawLine(pen, + new Point(bounds.X, bounds.Y + n), + new Point(bounds.Right - 1, bounds.Y + n)); + } + } + } + + #endregion + + #endregion + + #region Copy/CopyTo + + public override ChartVisualElement Copy() + { + ReferenceLine copy = new ReferenceLine(); + + CopyTo(copy); + + return (copy); + } + + public override void CopyTo(ChartVisualElement copy) + { + ReferenceLine c = copy as ReferenceLine; + + if (c != null) + { + base.CopyTo(c); + + c.AxisValue = AxisValue; + c.DisplayLineOnTop = DisplayLineOnTop; + c.DisplayTextOnTop = DisplayTextOnTop; + c.EnableTextMarkup = EnableTextMarkup; + c.InvertVerticalText = InvertVerticalText; + c.MaxLineCount = MaxLineCount; + + c.ReferenceLineVisualStyle = + (_ReferenceLineVisualStyle != null) ? ReferenceLineVisualStyle.Copy() : null; + + c.Text = Text; + + c.CheckedInLegend = CheckedInLegend; + c.LegendText = LegendText; + c.ShowCheckBoxInLegend = ShowCheckBoxInLegend; + c.ShowInLegend = ShowInLegend; + c.ShowInParentLegend = ShowInParentLegend; + c.ShowMarkerInLegend = ShowMarkerInLegend; + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ReferenceLine"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AxisValue", AxisValue, null); + sec.AddValue("DisplayLineOnTop", DisplayLineOnTop, false); + sec.AddValue("DisplayTextOnTop", DisplayTextOnTop, true); + sec.AddValue("EnableTextMarkup", EnableTextMarkup, false); + sec.AddValue("InvertVerticalText", InvertVerticalText, false); + sec.AddValue("MaxLineCount", MaxLineCount, 3); + + if (_ReferenceLineVisualStyle != null && _ReferenceLineVisualStyle.IsEmpty == false) + sec.AddElement(_ReferenceLineVisualStyle.GetSerialData("ReferenceLineVisualStyle")); + + sec.AddValue("Text", Text, null); + + sec.AddValue("CheckedInLegend", CheckedInLegend, true); + sec.AddValue("LegendText", LegendText, null); + sec.AddValue("ShowCheckBoxInLegend", ShowCheckBoxInLegend, true); + sec.AddValue("ShowInLegend", ShowInLegend, true); + sec.AddValue("ShowInParentLegend", ShowInParentLegend, true); + sec.AddValue("ShowMarkerInLegend", ShowMarkerInLegend, true); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AxisValue": + AxisValue = se.DataValue; + break; + + case "CheckedInLegend": + CheckedInLegend = bool.Parse(se.StringValue); + break; + + case "DisplayLineOnTop": + DisplayLineOnTop = bool.Parse(se.StringValue); + break; + + case "DisplayTextOnTop": + DisplayTextOnTop = bool.Parse(se.StringValue); + break; + + case "EnableTextMarkup": + EnableTextMarkup = bool.Parse(se.StringValue); + break; + + case "InvertVerticalText": + InvertVerticalText = bool.Parse(se.StringValue); + break; + + case "LegendText": + LegendText = se.StringValue; + break; + + case "MaxLineCount": + MaxLineCount = int.Parse(se.StringValue); + break; + + case "ShowCheckBoxInLegend": + ShowCheckBoxInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInLegend": + ShowInLegend = bool.Parse(se.StringValue); + break; + + case "ShowInParentLegend": + ShowInParentLegend = bool.Parse(se.StringValue); + break; + + case "ShowMarkerInLegend": + ShowMarkerInLegend = bool.Parse(se.StringValue); + break; + + case "Text": + Text = se.StringValue; + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ReferenceLineVisualStyle": + sec.PutSerialData(ReferenceLineVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region States + + [Flags] + private enum States : uint + { + CheckedInLegend = (1U << 1), + ShowCheckBoxInLegend = (1U << 2), + ShowInLegend = (1U << 3), + ShowInParentLegend = (1U << 4), + ShowMarkerInLegend = (1U << 5), + + DisplayLineOnTop = (1U << 6), + DisplayTextOnTop = (1U << 7), + + EnableTextMarkup = (1U << 8), + InvertVerticalText = (1U << 9) + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + ChartLegendItemVisualStyles = null; + ReferenceLineVisualStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartEventArgs.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartEventArgs.cs new file mode 100644 index 00000000..5f282702 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartEventArgs.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartPrint.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartPrint.cs new file mode 100644 index 00000000..d54a95bd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ChartPrint.cs @@ -0,0 +1,225 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Printing; + +namespace DevComponents.DotNetBar.Charts +{ + [ToolboxItem(false)] + public class ChartPrint : PrintDocument + { + #region Private variables + + private ChartControl _ChartControl; + private Image _ChartImage; + + private Rectangle _PrintBounds; + + private int _Columns; + private int _Rows; + + private int _CurCell; + + private FitToPageScale _FitToPageScale = FitToPageScale.Normal; + + #endregion + + #region Constructors + + /// + /// ChartPrint + /// + public ChartPrint() + : base() + { + } + + /// + /// ChartPrint + /// + /// ChartControl + public ChartPrint(ChartControl chartControl) + : base() + { + _ChartControl = chartControl; + } + + /// + /// ChartPrint + /// + /// ChartControl + /// FitToPageScale + public ChartPrint(ChartControl chartControl, FitToPageScale fitToPageScale) + : base() + { + _ChartControl = chartControl; + _FitToPageScale = fitToPageScale; + } + + #endregion + + #region Public properties + + #region FitToPageScale + + /// + /// Gets or sets how the chart is scaled + /// to fit the page when printing. + /// + public FitToPageScale FitToPageScale + { + get { return (_FitToPageScale); } + set { _FitToPageScale = value; } + } + + #endregion + + #endregion + + #region OnBeginPrint + + protected override void OnBeginPrint(PrintEventArgs e) + { + base.OnBeginPrint(e); + + if (_ChartControl == null) + throw new Exception("ChartControl has not been set."); + + Size size = _ChartControl.ClientSize; + + _PrintBounds = DefaultPageSettings.Bounds; + + Margins margins = DefaultPageSettings.Margins; + + _PrintBounds.X += margins.Left; + _PrintBounds.Width -= (margins.Left + margins.Right); + + _PrintBounds.Y += margins.Top; + _PrintBounds.Height -= (margins.Top + margins.Bottom); + + _Columns = (int)Math.Ceiling((double)size.Width / _PrintBounds.Width); + _Rows = (int)Math.Ceiling((double)size.Height / _PrintBounds.Height); + + _CurCell = 0; + + _ChartImage = new Bitmap(size.Width, size.Height); + + using (Graphics g = Graphics.FromImage(_ChartImage)) + _ChartControl.PaintTo(g); + } + + #endregion + + #region OnPrintPage + + protected override void OnPrintPage(PrintPageEventArgs e) + { + base.OnPrintPage(e); + + switch (FitToPageScale) + { + case Charts.FitToPageScale.Stretch: + PrintStretchPage(e); + break; + + case Charts.FitToPageScale.Zoom: + PrintZoomPage(e); + break; + + default: + PrintNormalPage(e); + break; + } + } + + #region PrintNormalPage + + private void PrintNormalPage(PrintPageEventArgs e) + { + Graphics g = e.Graphics; + + int curRow = _CurCell / _Columns; + int curColumn = _CurCell % _Columns; + + int x = curColumn * _PrintBounds.Width; + int y = curRow * _PrintBounds.Height; + + Rectangle rs = new Rectangle(x, y, _ChartImage.Width - x, _ChartImage.Height - y); + Rectangle rd = new Rectangle(_PrintBounds.X, _PrintBounds.Y, _ChartImage.Width - x, _ChartImage.Height - y); + + Region saveClip = g.Clip; + + g.SetClip(_PrintBounds); + g.DrawImage(_ChartImage, rd, rs, GraphicsUnit.Pixel); + g.Clip = saveClip; + + _CurCell++; + + e.HasMorePages = (_CurCell < _Columns * _Rows); + } + + #endregion + + #region PrintStretchPage + + private void PrintStretchPage(PrintPageEventArgs e) + { + Rectangle rs = new Rectangle(0, 0, _ChartImage.Width, _ChartImage.Height); + + e.Graphics.DrawImage(_ChartImage, _PrintBounds, rs, GraphicsUnit.Pixel); + + e.HasMorePages = false; + } + + #endregion + + #region PrintZoomPage + + private void PrintZoomPage(PrintPageEventArgs e) + { + Rectangle rd = _PrintBounds; + + SizeF size = new SizeF(_ChartImage.Width / _ChartImage.HorizontalResolution, + _ChartImage.Height / _ChartImage.VerticalResolution); + + float scale = Math.Min(rd.Width / size.Width, rd.Height / size.Height); + + size.Width *= scale; + size.Height *= scale; + + e.Graphics.DrawImage(_ChartImage, rd.X, rd.Y, size.Width, size.Height); + + e.HasMorePages = false; + } + + #endregion + + #endregion + + #region OnEndPrint + + protected override void OnEndPrint(PrintEventArgs e) + { + base.OnEndPrint(e); + + if (_ChartImage != null) + _ChartImage.Dispose(); + + _ChartImage = null; + } + + #endregion + } + + #region FitToPageScale + + public enum FitToPageScale + { + Normal, + + Stretch, + Zoom, + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ClosedHand.cur b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ClosedHand.cur new file mode 100644 index 00000000..13d7056e Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ClosedHand.cur differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/BlockLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/BlockLayoutManager.cs new file mode 100644 index 00000000..c088927e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/BlockLayoutManager.cs @@ -0,0 +1,38 @@ +using System.Collections; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + /// + /// Represents block layout manager responsible for sizing the content blocks. + /// + public abstract class BlockLayoutManager + { + private Graphics _Graphics; + + /// + /// Resizes the content block and sets it's Bounds property to reflect new size. + /// + /// Content block to resize. + /// Content size available for the block in the given line. + public abstract void Layout(IBlock block, Size availableSize); + + /// + /// Performs layout finalization + /// + /// + /// + /// + /// + public abstract Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines); + + /// + /// Gets or sets the graphics object used by layout manager. + /// + public Graphics Graphics + { + get {return _Graphics;} + set {_Graphics = value;} + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/Enums.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/Enums.cs new file mode 100644 index 00000000..89fc4d26 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/Enums.cs @@ -0,0 +1,55 @@ +namespace DevComponents.Charts.TextMarkup +{ + /// + /// Specifies orientation of content. + /// + public enum eContentOrientation + { + /// + /// Indicates Horizontal orientation of the content. + /// + Horizontal, + /// + /// Indicates Vertical orientation of the content. + /// + Vertical + } + + /// + /// Specifies content horizontal alignment. + /// + public enum eContentAlignment + { + /// + /// Content is left aligned.UI + /// + Left, + /// + /// Content is right aligned. + /// + Right, + /// + /// Content is centered. + /// + Center + } + + /// + /// Specifies content vertical alignment. + /// + public enum eContentVerticalAlignment + { + /// + /// Content is top aligned. + /// + Top, + /// + /// Content is bottom aligned. + /// + Bottom, + /// + /// Content is in the middle. + /// + Middle + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/IBlock.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/IBlock.cs new file mode 100644 index 00000000..d41189bd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/IBlock.cs @@ -0,0 +1,20 @@ +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + /// + /// Represents a content block interface. + /// + public interface IBlock + { + /// + /// Gets or sets the bounds of the content block. + /// + Rectangle Bounds {get;set;} + + /// + /// Gets or sets whether content block is visible. + /// + bool Visible {get;set;} + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/IBlockExtended.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/IBlockExtended.cs new file mode 100644 index 00000000..1acfbcf9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/IBlockExtended.cs @@ -0,0 +1,23 @@ +namespace DevComponents.Charts.TextMarkup +{ + /// + /// Represents a extended content block interface for advanced layout information. + /// + public interface IBlockExtended : IBlock + { + /// + /// Gets whether element is block level element. + /// + bool IsBlockElement { get;} + + /// + /// Gets whether new line is required after the element. + /// + bool IsNewLineAfterElement { get;} + + /// + /// Gets whether element can be on new line. + /// + bool CanStartNewLine { get; } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/IContentLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/IContentLayoutManager.cs new file mode 100644 index 00000000..2bb576d7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/IContentLayoutManager.cs @@ -0,0 +1,19 @@ +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + /// + /// Represents interface for block layout. + /// + public interface IContentLayout + { + /// + /// Performs layout of the content block. + /// + /// Container bounds to layout content blocks in. + /// Content blocks to layout. + /// Block layout manager that resizes the content blocks. + /// The bounds of the content blocks within the container bounds. + Rectangle Layout(Rectangle containerBounds, IBlock[] contentBlocks, BlockLayoutManager blockLayout); + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/SerialContentLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/SerialContentLayoutManager.cs new file mode 100644 index 00000000..7f45ee39 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ContentManager/SerialContentLayoutManager.cs @@ -0,0 +1,709 @@ +using System; +using System.Collections; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + /// + /// Represents the serial content layout manager that arranges content blocks in series next to each other. + /// + public class SerialContentLayoutManager:IContentLayout + { + #region Events + + /// + /// Occurs when X, Y position of next block is calcualted. + /// + public event LayoutManagerPositionEventHandler NextPosition; + + /// + /// Occurs before new block is layed out. + /// + public event LayoutManagerLayoutEventHandler BeforeNewBlockLayout; + + #endregion + + #region Private Variables + + private int _BlockSpacing; + private bool _FitContainerOversize; + private bool _FitContainer; + private bool _VerticalFitContainerWidth; + private bool _HorizontalFitContainerHeight; + private bool _EvenHeight; + private bool _MultiLine; + private bool _RightToLeft; + private bool _OversizeDistribute; + + private eContentAlignment _ContentAlignment = eContentAlignment.Left; + private eContentOrientation _ContentOrientation = eContentOrientation.Horizontal; + private eContentVerticalAlignment _ContentVerticalAlignment = eContentVerticalAlignment.Middle; + private eContentVerticalAlignment _BlockLineAlignment = eContentVerticalAlignment.Middle; + + #endregion + + #region IContentLayout Members + + /// + /// Performs layout of the content block. + /// + /// Container bounds to layout content blocks in. + /// Content blocks to layout. + /// Block layout manager that resizes the content blocks. + /// The bounds of the content blocks within the container bounds. + 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; + bool canStartOnNewLine; + + if (block is IBlockExtended) + { + IBlockExtended ex = block as IBlockExtended; + + isBlockElement = ex.IsBlockElement; + isNewLineTriggger = ex.IsNewLineAfterElement; + canStartOnNewLine = ex.CanStartNewLine; + } + else + canStartOnNewLine = true; + + if (!isBlockElement) + { + if (_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 (_MultiLine && currentLine.Blocks.Count > 0) + { + if (_ContentOrientation == eContentOrientation.Horizontal && + position.X + block.Bounds.Width > containerBounds.Right && canStartOnNewLine || isBlockElement || + switchToNewLine) + { + position.X = containerBounds.X; + position.Y += (currentLine.LineSize.Height + _BlockSpacing); + + currentLine = new BlockLineInfo(); + + currentLine.Line = lines.Count; + + lines.Add(currentLine); + } + else if (_ContentOrientation == eContentOrientation.Vertical && + position.Y + block.Bounds.Height > containerBounds.Bottom && canStartOnNewLine || isBlockElement || + switchToNewLine) + { + position.Y = containerBounds.Y; + position.X += (currentLine.LineSize.Width + _BlockSpacing); + + currentLine = new BlockLineInfo(); + + currentLine.Line = lines.Count; + + lines.Add(currentLine); + } + } + + if (_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 (_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); + + if (block.Visible) + currentLine.VisibleItemsCount++; + + 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 (_RightToLeft) + blocksBounds = MirrorContent(containerBounds, blocksBounds, contentBlocks); + + blocksBounds = blockLayout.FinalizeLayout(containerBounds, blocksBounds, lines); + + return blocksBounds; + } + + #endregion + + #region Internals + + private struct SizeExtended + { + public int Width; + public int Height; + public float WidthReduction; + public float HeightReduction; + public bool UseAbsoluteWidth; + } + + 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 (_ContentAlignment == eContentAlignment.Left && _ContentVerticalAlignment == eContentVerticalAlignment.Top && + !_FitContainer && !_FitContainerOversize && !_EvenHeight && _BlockLineAlignment == eContentVerticalAlignment.Top) + return blocksBounds; + + Point[] offset=new Point[lines.Count]; + SizeExtended[] sizeOffset = new SizeExtended[lines.Count]; + foreach(BlockLineInfo lineInfo in lines) + { + if (_ContentOrientation == eContentOrientation.Horizontal) + { + if (_FitContainer && containerBounds.Width > lineInfo.LineSize.Width || + _FitContainerOversize && lineInfo.LineSize.Width > containerBounds.Width) + { + if (_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width * .75) + { + sizeOffset[lineInfo.Line].Width = (int)Math.Floor((float)(containerBounds.Width - lineInfo.VisibleItemsCount * _BlockSpacing) / (float)lineInfo.VisibleItemsCount); + sizeOffset[lineInfo.Line].UseAbsoluteWidth = true; + } + else + sizeOffset[lineInfo.Line].Width = ((containerBounds.Width - lineInfo.VisibleItemsCount * _BlockSpacing) - lineInfo.LineSize.Width) / lineInfo.VisibleItemsCount; + sizeOffset[lineInfo.Line].WidthReduction = (float)(containerBounds.Width - lineInfo.VisibleItemsCount * _BlockSpacing) / (float)lineInfo.LineSize.Width; + blocksBounds.Width = containerBounds.Width; + } + + if (_HorizontalFitContainerHeight && containerBounds.Height > blocksBounds.Height) + sizeOffset[lineInfo.Line].Height = (containerBounds.Height - lineInfo.LineSize.Height) / lines.Count; + } + else + { + if (_FitContainer && containerBounds.Height > lineInfo.LineSize.Height || + _FitContainerOversize && lineInfo.LineSize.Height > containerBounds.Height) + { + if (_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width*.75) + { + sizeOffset[lineInfo.Line].Height = (int) + Math.Floor((float) (containerBounds.Height - lineInfo.VisibleItemsCount*_BlockSpacing)/ + (float) lineInfo.VisibleItemsCount); + + sizeOffset[lineInfo.Line].UseAbsoluteWidth = true; + } + else + sizeOffset[lineInfo.Line].Height = ((containerBounds.Height - + lineInfo.VisibleItemsCount*_BlockSpacing) - + lineInfo.LineSize.Height)/lineInfo.VisibleItemsCount; + sizeOffset[lineInfo.Line].HeightReduction = + (float) (containerBounds.Height - lineInfo.VisibleItemsCount*_BlockSpacing)/ + (float) lineInfo.LineSize.Height; + blocksBounds.Height = containerBounds.Height; + } + + if (_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width) + sizeOffset[lineInfo.Line].Width = (containerBounds.Width - lineInfo.LineSize.Width)/lines.Count; + } + + + if (_ContentOrientation == eContentOrientation.Horizontal && !_FitContainer) + { + if (containerBounds.Width > blocksBounds.Width && _FitContainerOversize || !_FitContainerOversize) + { + switch (_ContentAlignment) + { + case eContentAlignment.Right: + if (containerBounds.Width > lineInfo.LineSize.Width) + offset[lineInfo.Line].X = containerBounds.Width - lineInfo.LineSize.Width; + break; + + case eContentAlignment.Center: + if (containerBounds.Width > lineInfo.LineSize.Width) + offset[lineInfo.Line].X = (containerBounds.Width - lineInfo.LineSize.Width)/2; + break; + } + } + } + + if (_ContentOrientation == eContentOrientation.Vertical && !_FitContainer) + { + if (containerBounds.Height > blocksBounds.Height && _FitContainerOversize || !_FitContainerOversize) + { + switch (_ContentVerticalAlignment) + { + case eContentVerticalAlignment.Bottom: + if (containerBounds.Height > lineInfo.LineSize.Height) + offset[lineInfo.Line].Y = containerBounds.Height - lineInfo.LineSize.Height; + break; + + case eContentVerticalAlignment.Middle: + if (containerBounds.Height > lineInfo.LineSize.Height) + offset[lineInfo.Line].Y = (containerBounds.Height - lineInfo.LineSize.Height)/2; + break; + } + } + } + } + + if (_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width && _ContentOrientation==eContentOrientation.Vertical) + blocksBounds.Width = containerBounds.Width; + + else if(_HorizontalFitContainerHeight && containerBounds.Height>blocksBounds.Height && _ContentOrientation==eContentOrientation.Horizontal) + blocksBounds.Height = containerBounds.Height; + + if(_ContentOrientation==eContentOrientation.Horizontal) + { + foreach(BlockLineInfo lineInfo in lines) + { + foreach (IBlock block in lineInfo.Blocks) + { + if (!block.Visible) + continue; + + Rectangle r = block.Bounds; + + if (_EvenHeight && lineInfo.LineSize.Height > 0) + r.Height = lineInfo.LineSize.Height; + + r.Offset(offset[lineInfo.Line]); + + if (_ContentVerticalAlignment == eContentVerticalAlignment.Middle) + { + // Takes care of offset rounding error when both content is vertically centered and blocks in line are centered + + if (_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 (_BlockLineAlignment == eContentVerticalAlignment.Bottom) + r.Offset(0, lineInfo.LineSize.Height - r.Height); + } + else if (_ContentVerticalAlignment == eContentVerticalAlignment.Bottom) + r.Offset(0, containerBounds.Height - blocksBounds.Height); + + // To avoid rounding offset errors when dividing this is split see upper part + + if (_ContentVerticalAlignment != eContentVerticalAlignment.Middle) + { + // Line alignment of the block + + if (_BlockLineAlignment == eContentVerticalAlignment.Middle) + r.Offset(0, (lineInfo.LineSize.Height - r.Height)/2); + + else if (_BlockLineAlignment == eContentVerticalAlignment.Bottom) + r.Offset(0, lineInfo.LineSize.Height - r.Height); + } + + if (sizeOffset[lineInfo.Line].Width != 0) + { + if (_OversizeDistribute) + { + int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth + ? sizeOffset[lineInfo.Line].Width + : (int) Math.Floor(r.Width*sizeOffset[lineInfo.Line].WidthReduction); + + offset[lineInfo.Line].X += nw - r.Width; + + r.Width = nw; + } + else + { + 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 (!_OversizeDistribute && 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(_EvenHeight && lineInfo.LineSize.Width>0) + r.Width=lineInfo.LineSize.Width; + + r.Offset(offset[lineInfo.Line]); + + if(_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(_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) + { + if (_OversizeDistribute) + { + int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth + ? sizeOffset[lineInfo.Line].Height : (int)Math.Floor(r.Height * sizeOffset[lineInfo.Line].HeightReduction); + + offset[lineInfo.Line].Y += nw - r.Height; + r.Height = nw; + } + else + { + 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 (!_OversizeDistribute && 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(_ContentOrientation==eContentOrientation.Horizontal) + position.X+=block.Bounds.Width+_BlockSpacing; + else + position.Y+=block.Bounds.Height+_BlockSpacing; + + return position; + } + + internal class BlockLineInfo + { + public ArrayList Blocks=new ArrayList(); + public Size LineSize = Size.Empty; + public int Line; + public int VisibleItemsCount; + } + + private Rectangle MirrorContent(Rectangle containerBounds, Rectangle blockBounds, IBlock[] contentBlocks) + { + 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 + /// + /// Gets or sets the spacing in pixels between content blocks. Default value is 0. + /// + public virtual int BlockSpacing + { + get {return _BlockSpacing;} + set {_BlockSpacing=value;} + } + + /// + /// 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. + /// + public virtual bool FitContainerOversize + { + get {return _FitContainerOversize;} + set {_FitContainerOversize=value;} + } + + /// + /// 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. + /// + public virtual bool FitContainer + { + get {return _FitContainer;} + set {_FitContainer=value;} + } + + /// + /// 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. + /// + public virtual bool VerticalFitContainerWidth + { + get { return _VerticalFitContainerWidth; } + set { _VerticalFitContainerWidth = value; } + } + + /// + /// Gets or sets whether content blocks are resized (Height) to fit container bounds if they + /// occupy less space than the actual container height. Applies to the Horizontal orientation only. Default value is false. + /// + public virtual bool HorizontalFitContainerHeight + { + get { return _HorizontalFitContainerHeight; } + set { _HorizontalFitContainerHeight = value; } + } + + /// + /// Gets or sets the content orientation. Default value is Horizontal. + /// + public virtual eContentOrientation ContentOrientation + { + get {return _ContentOrientation;} + set {_ContentOrientation=value;} + } + + /// + /// Gets or sets the content vertical alignment. Default value is Middle. + /// + public virtual eContentVerticalAlignment ContentVerticalAlignment + { + get {return _ContentVerticalAlignment;} + set {_ContentVerticalAlignment=value;} + } + + /// + /// Gets or sets the block line vertical alignment. Default value is Middle. + /// + public virtual eContentVerticalAlignment BlockLineAlignment + { + get { return _BlockLineAlignment; } + set { _BlockLineAlignment = value; } + } + + /// + /// Gets or sets the content horizontal alignment. Default value is Left. + /// + public virtual eContentAlignment ContentAlignment + { + get {return _ContentAlignment;} + set {_ContentAlignment=value;} + } + + /// + /// Gets or sets whether all content blocks are resized so they have same height which is height of the tallest content block. Default value is false. + /// + public virtual bool EvenHeight + { + get {return _EvenHeight;} + set {_EvenHeight=value;} + } + + /// + /// Gets or sets whether oversized blocks are resized based on the percentage reduction instead of based on equal pixel distribution. Default value is false. + /// + public virtual bool OversizeDistribute + { + get { return _OversizeDistribute; } + set { _OversizeDistribute = value; } + } + + /// + /// Gets or sets whether content is wrapped into new line if it exceeds the width of the container. + /// + public bool MultiLine + { + get {return _MultiLine;} + set {_MultiLine=value;} + } + + /// + /// Gets or sets whether layout is right-to-left. + /// + public bool RightToLeft + { + get { return _RightToLeft; } + set { _RightToLeft = value; } + } + + #endregion + } + + /// + /// Represents event arguments for SerialContentLayoutManager.NextPosition event. + /// + public class LayoutManagerPositionEventArgs : EventArgs + { + /// + /// Gets or sets the block that is layed out. + /// + public IBlock Block; + + /// + /// Gets or sets the current block position. + /// + public Point CurrentPosition = Point.Empty; + + /// + /// Gets or sets the calculated next block position. + /// + public Point NextPosition = Point.Empty; + + /// + /// Cancels default position calculation. + /// + public bool Cancel; + } + + /// + /// Represents event arguments for the SerialContentLayoutManager layout events. + /// + public class LayoutManagerLayoutEventArgs : EventArgs + { + /// + /// Gets or sets the reference block object. + /// + public IBlock Block; + + /// + /// Gets or sets the position block will assume. + /// + public Point CurrentPosition = Point.Empty; + + /// + /// Cancel the layout of the block, applies only to BeforeXXX layout event. + /// + public bool CancelLayout; + + /// + /// Gets or sets the visibility index of the block. + /// + public int BlockVisibleIndex; + + /// + /// Creates new instance of the class and initializes it with default values. + /// + public LayoutManagerLayoutEventArgs(IBlock block, Point currentPosition, int visibleIndex) + { + this.Block = block; + this.CurrentPosition = currentPosition; + this.BlockVisibleIndex = visibleIndex; + } + } + + /// + /// Delegate for SerialContentLayoutManager.NextPosition event. + /// + public delegate void LayoutManagerPositionEventHandler(object sender, LayoutManagerPositionEventArgs e); + + /// + /// Delegate for the SerialContentLayoutManager layout events. + /// + public delegate void LayoutManagerLayoutEventHandler(object sender, LayoutManagerLayoutEventArgs e); + + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ConvexHull.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ConvexHull.cs new file mode 100644 index 00000000..5a1fd060 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ConvexHull.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Charts +{ + // Monotone Chain Convex Hull. + // It takes O(NlogN) in sorting & O(N) in actual convex hull calc for N points. + + public static class ConvexHull + { + #region GetConvexHull + + public static Point[] GetConvexHull(Point[] points) + { + int n = points.Length; + + Array.Sort(points, 0, n, new PointComparer()); + + Point[] ans = new Point[2 * n]; + + int k = 0; + int start = 0; + + // Bottom hull + + Point lpt = Point.Empty; + + for (int i = 0; i < n; i++) + { + Point p = points[i]; + + if (PtCompare(p, lpt) == 0) + continue; + + lpt = p; + + while (k - start >= 2) + { + Point sp1 = PtSub(p, ans[k - 1]); + Point sp2 = PtSub(p, ans[k - 2]); + + if (PtCross(sp1, sp2) <= 0) + break; + + k--; + } + + ans[k++] = p; + } + + k--; + + // Top hull + + start = k; + lpt = Point.Empty; + + for (int i = n - 1; i >= 0; i--) + { + Point p = points[i]; + + if (PtCompare(p, lpt) == 0) + continue; + + lpt = p; + + while (k - start >= 2) + { + Point sp1 = PtSub(p, ans[k - 1]); + Point sp2 = PtSub(p, ans[k - 2]); + + if (PtCross(sp1, sp2) <= 0) + break; + + k--; + } + + ans[k++] = p; + } + + k--; + + Point[] hullPoints = new Point[k + 1]; + Array.Copy(ans, hullPoints, k); + + hullPoints[k] = hullPoints[0]; + + return (hullPoints); + } + + #endregion + + #region PointComparer + + private class PointComparer : IComparer + { + public int Compare(Point pt1, Point pt2) + { + return (ConvexHull.PtCompare(pt1, pt2)); + } + } + + #endregion + + #region PtCompare + + private static int PtCompare(Point pt1, Point pt2) + { + if (pt1.X == pt2.X) + return (pt1.Y - pt2.Y); + + return (pt1.X - pt2.X); + } + + #endregion + + #region PtCross + + private static int PtCross(Point pt1, Point pt2) + { + return (pt1.X * pt2.Y - pt1.Y * pt2.X); + } + + #endregion + + #region PtSub + + private static Point PtSub(Point pt1, Point pt2) + { + return (new Point(pt1.X - pt2.X, pt1.Y - pt2.Y)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/DevComponents.DotNetBar.Charts.csproj b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/DevComponents.DotNetBar.Charts.csproj new file mode 100644 index 00000000..19274fa4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/DevComponents.DotNetBar.Charts.csproj @@ -0,0 +1,268 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {2AF9BA7A-2D05-419E-9F49-0CCEF791947E} + Library + Properties + DevComponents.DotNetBar.Charts + DevComponents.DotNetBar.Charts + v2.0 + 512 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;CHARTCONTROL + prompt + 4 + x86 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\DevComponents.DotNetBar.Charts.XML + AllRules.ruleset + + + true + + + ChartControl.snk + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + Component + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {36546ce3-335c-4ab6-a2f3-40f8c818bc66} + DotNetBar + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/MathHelper.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/MathHelper.cs new file mode 100644 index 00000000..da7bc96a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/MathHelper.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Text; + +namespace DevComponents.DotNetBar.Charts +{ + internal static class MathHelper + { + #region ToDegrees + + public static double ToDegrees(double radians) + { + return (radians * 180 / Math.PI); + } + + #endregion + + #region ToRadians + + public static double ToRadians(double degrees) + { + return (degrees * Math.PI / 180); + } + + #endregion + + #region GetPointAngle + + public static int GetPointAngle(Point pt) + { + double theta = Math.Atan2(pt.X, -pt.Y); + int angle = (int)(MathHelper.ToDegrees(theta) + 270) % 360; + + return (angle); + } + + #endregion + + #region GetPointRadius + + public static int GetPointRadius(ref Point pt, Point cpt) + { + pt.X -= cpt.X; + pt.Y -= cpt.Y; + + return ((int)Math.Sqrt(pt.X * pt.X + pt.Y * pt.Y)); + } + + #endregion + + #region GetOffsetPoint + + public static Point GetOffsetPoint( + Point pt, Point cpt, out int radius, out int angle) + { + radius = MathHelper.GetPointRadius(ref pt, cpt); + angle = MathHelper.GetPointAngle(pt); + + return (pt); + } + + #endregion + + #region Clamp + + public static T Clamp(T value, T min, T max) + where T : IComparable + { + T result = value; + + if (result.CompareTo(max) > 0) + result = max; + + if (result.CompareTo(min) < 0) + result = min; + + return (result); + } + + #endregion + + #region ToScalar + + public static double ToScalar(double x) + { + return (MathHelper.Sqrt((float)(x / Math.PI)) * 2); + } + + #endregion + + #region Sqrt + + [StructLayout(LayoutKind.Explicit)] + private struct FloatIntUnion + { + [FieldOffset(0)] + public float f; + + [FieldOffset(0)] + public int tmp; + } + + public static float Sqrt(float x) + { + if (x != 0) + { + FloatIntUnion u; + + u.tmp = 0; + u.f = x; + + u.tmp -= 1 << 23; // Subtract 2^m + u.tmp >>= 1; // Divide by 2 + u.tmp += 1 << 29; // Add ((b + 1) / 2) * 2^m + + return (u.f); + } + + return (0); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/PieSeriesConverter.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/PieSeriesConverter.cs new file mode 100644 index 00000000..629ddb48 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/PieSeriesConverter.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +namespace DevComponents.DotNetBar.Charts +{ + public class PieSeriesConverter : ExpandableObjectConverter + { + public override PropertyDescriptorCollection + GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) + { + PropertyDescriptorCollection pdc = base.GetProperties(context, value, attributes); + + PropertyDescriptor[] newProps = new PropertyDescriptor[pdc.Count - 1]; + + int n = 0; + + for (int i = 0; i < pdc.Count; i++) + { + if (pdc[i].Name.Equals("SeriesType") == false) + newProps[n++] = pdc[i]; + } + + return new PropertyDescriptorCollection(newProps); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/PointFConverter.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/PointFConverter.cs new file mode 100644 index 00000000..f20555cd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/PointFConverter.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +namespace DevComponents.DotNetBar.Charts +{ + public class PointFConverter : ExpandableObjectConverter + { + #region CanConvertTo + + public override bool CanConvertTo( + ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + return (true); + + return (base.CanConvertTo(context, destinationType)); + } + + #endregion + + #region ConvertTo + + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + PointF pf = (PointF)value; + + return (String.Format("{0:f}, {1:f}", pf.X, pf.Y)); + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + + #endregion + + #region CanConvertFrom + + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + return (true); + + return (base.CanConvertFrom(context, sourceType)); + } + + #endregion + + #region ConvertFrom + + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + string[] values = ((string)value).Split(','); + + if (values.Length != 2) + throw new ArgumentException("Invalid value to convert."); + + try + { + float x = float.Parse(values[0]); + float y = float.Parse(values[1]); + + PointF pf = new PointF(x, y); + + return (pf); + } + catch + { + throw new ArgumentException("Invalid value to convert."); + } + } + + return base.ConvertFrom(context, culture, value); + } + + #endregion + + #region GetCreateInstanceSupported + + public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region CreateInstance + + public override object CreateInstance( + ITypeDescriptorContext context, IDictionary propertyValues) + { + if (propertyValues != null) + return (new PointF((float)propertyValues["X"], (float)propertyValues["Y"])); + + return (null); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/TextHelpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/TextHelpers.cs new file mode 100644 index 00000000..287766e4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/TextHelpers.cs @@ -0,0 +1,55 @@ +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Provides helpers when working with text. + /// + internal static class TextHelper + { + private static int _textMarkupCultureSpecific = 3; + + /// + /// Get or sets the text-markup padding for text + /// measurement when running on Japanese version of Windows. + /// + public static int TextMarkupCultureSpecificPadding + { + get { return _textMarkupCultureSpecific; } + set { _textMarkupCultureSpecific = value; } + } + + /// + /// MeasureText always adds about 1/2 em width of white space on the right, + /// even when NoPadding is specified. It returns zero for an empty string. + /// To get the precise string width, measure the width of a string containing a + /// single period and subtract that from the width of our original string plus a period. + /// + public static Size MeasureText(Graphics g, + string s, Font font, Size csize, eTextFormat tf) + { + return (TextDrawing.MeasureString(g, s, font, csize, tf)); + + if (font.Italic == true) + return (TextDrawing.MeasureString(g, s, font, csize, tf)); + + Size sz1 = TextDrawing.MeasureString(g, ".", font, csize, tf); + Size sz2 = TextDrawing.MeasureString(g, s + ".", font, csize, tf); + + return (new Size(sz2.Width - sz1.Width, sz2.Height)); + } + + public static Size MeasureText(Graphics g, string s, Font font) + { + return (TextDrawing.MeasureString(g, s, font)); + + if (font.Italic == true) + return (TextDrawing.MeasureString(g, s, font)); + + Size sz1 = TextDrawing.MeasureString(g, ".", font); + Size sz2 = TextDrawing.MeasureString(g, s + ".", font); + + return (new Size(sz2.Width - sz1.Width, sz2.Height)); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/XmlHelpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/XmlHelpers.cs new file mode 100644 index 00000000..e8cfe83e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Helpers/XmlHelpers.cs @@ -0,0 +1,1059 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using System.Security; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + #region XmlSerializableFont + + static public class XmlSerializableFont + { + static public string ConvertToString(Font font) + { + if (font != null) + { + TypeConverter converter = + TypeDescriptor.GetConverter(typeof(Font)); + + return (converter.ConvertToString(font)); + } + + return (null); + } + + static public Font ConvertFromString(string fontString) + { + TypeConverter converter = + TypeDescriptor.GetConverter(typeof(Font)); + + Font font = (Font)converter.ConvertFromString(fontString); + + return (font); + } + } + + #endregion + + #region XmlSerializableImageList + + static public class XmlSerializableImageList + { + static public string ConvertToString(ImageList list) + { + TypeConverter converter = + TypeDescriptor.GetConverter(typeof(ImageList)); + + return (converter.ConvertToString(list)); + } + + static public ImageList ConvertFromString(string listString) + { + TypeConverter converter = + TypeDescriptor.GetConverter(typeof(ImageList)); + + ImageList list = (ImageList)converter.ConvertFromString(listString); + + return (list); + } + } + + #endregion + + #region SerialElementCollection + + public delegate void Pv(SerialElement se); + public delegate void Pc(SerialElement se); + + public class SerialElementCollection : CustomCollection + { + #region Private variables + + private int _ReadIndex = -1; + + private SerialElement _ReadSe; + private string _Name; + + private int _ValueIndex; + + #endregion + + #region Internal properties + + #region Eof + + internal bool Eof + { + get { return (_ReadIndex >= Count); } + } + + #endregion + + #region Name + + internal string Name + { + get { return (_Name); } + set { _Name = value; } + } + + #endregion + + #region ReadIndex + + internal int ReadIndex + { + get { return (_ReadIndex); } + set { _ReadIndex = value; } + } + + #endregion + + #region ReadSe + + internal SerialElement ReadSe + { + get { return (_ReadSe); } + } + + #endregion + + #endregion + + #region AddStartElement + + /// + /// Adds a 'Start' element to the collection. + /// + /// + /// + public SerialElement AddStartElement(string name) + { + SerialElement se = new SerialElement(SerElementType.Start, name); + + Items.Add(se); + + return (se); + } + + #endregion + + #region AddEndElement + + /// + /// Adds an 'End' element to the collection. + /// + /// + /// + public SerialElement AddEndElement(string name) + { + SerialElement se = new SerialElement(SerElementType.End, name); + + Items.Add(se); + + return (se); + } + + #endregion + + #region AddValue + + /// + /// Adds the given object element to the collection. + /// + /// + /// + public SerialElement AddValue(object value) + { + SerialElement se = new SerialElement(null, value); + + Items.Add(se); + + return (se); + } + + /// + /// Adds the given value to the collection (surrounded + /// by a 'Start' and 'End' element pair). + /// + /// + /// + public void AddValue(string name, object value) + { + Items.Add(new SerialElement(SerElementType.ValueStart, name)); + Items.Add(new SerialElement(name, value)); + Items.Add(new SerialElement(SerElementType.ValueEnd, name)); + } + + /// + /// Adds the given value to the collection (surrounded + /// by a 'Start' and 'End' element pair) - but only if the + /// value is not equal to the given defaultValue. + /// + /// + /// + /// + public void AddValue(string name, object value, object defaultValue) + { + if ((defaultValue == null && value != null) || + (defaultValue != null && defaultValue.Equals(value) == false)) + { + AddValue(name, value); + } + } + + /// + /// Adds the given value Image to the collection (surrounded + /// by a 'Start' and 'End' element pair). + /// + /// + /// + public void AddValue(string name, Image image) + { + if (image != null) + AddValue(name, ImageToString(image)); + } + + #endregion + + #region ImageToString + + private String ImageToString(Image image) + { + BinaryFormatter bf = new BinaryFormatter(); + MemoryStream ms = new MemoryStream(); + + bf.Serialize(ms, image); + + return (Convert.ToBase64String(ms.ToArray())); + } + + #endregion + + #region AddDataValue + + /// + /// Adds the given 'Data' value to the collection (surrounded + /// by a 'Start' and 'End' element pair). + /// + /// + /// + public void AddDataValue(string name, object value) + { + Items.Add(new SerialElement(SerElementType.ValueStart, name)); + Items.Add(new SerialElement(SerElementType.DataValue, name, value)); + Items.Add(new SerialElement(SerElementType.ValueEnd, name)); + } + + /// + /// Adds the given 'Data' value to the collection (surrounded + /// by a 'Start' and 'End' element pair) - but only if the + /// value is not equal to the given defaultValue. + /// + /// + /// + /// + public void AddDataValue(string name, object value, object defaultValue) + { + if ((defaultValue == null && value != null) || + (defaultValue != null && defaultValue.Equals(value) == false)) + { + AddDataValue(name, value); + } + } + + #endregion + + #region AddElement + + /// + /// Adds the given SerialElementCollection to the + /// collection, if the given collection is non-empty. + /// + /// + /// + public SerialElement AddElement(SerialElementCollection sec) + { + if (sec != null && sec.Count > 0) + { + int count = sec.Count; + + if (sec[count - 1].SerType == SerElementType.End) + count--; + + if (sec[0].SerType == SerElementType.Start) + count--; + + if (count > 0) + { + SerialElement se = new SerialElement(sec); + + Items.Add(se); + + return (se); + } + } + + return (null); + } + + /// + /// Adds the given style to the collection, if + /// it is not Empty. + /// + /// + /// + public SerialElement AddElement(BaseVisualStyle style) + { + if (style != null && style.IsEmpty == false) + return (AddElement(style.GetSerialData(""))); + + return (null); + } + + #endregion + + #region PutSerialData + + internal void PutSerialData(IProcessSerialElement ipse) + { + while (Read()) + { + SerialElement se = ReadSe; + + switch (se.SerType) + { + case SerElementType.Start: + case SerElementType.ValueStart: + string name = se.Name; + + PutSerialData(ipse); + + if (se.Name.Equals(name) == false) + throw new Exception("Expecting " + name + " End"); + + break; + + case SerElementType.Value: + se.ValueIndex = _ValueIndex++; + + ipse.ProcessValue(se); + break; + + case SerElementType.Collection: + int valueIndex = _ValueIndex; + _ValueIndex = 0; + + ipse.ProcessCollection(se); + + _ValueIndex = valueIndex; + break; + + case SerElementType.End: + case SerElementType.ValueEnd: + return; + } + } + } + + #region SkipSerialData + + private void SkipSerialData() + { + while (Read()) + { + SerialElement se = ReadSe; + + switch (se.SerType) + { + case SerElementType.Start: + case SerElementType.ValueStart: + string name = se.Name; + + SkipSerialData(); + + if (se.Name.Equals(name) == false) + throw new Exception("Expecting " + name + " End"); + + break; + + case SerElementType.End: + case SerElementType.ValueEnd: + return; + } + } + } + + #endregion + + #endregion + + #region Read + + internal bool Read() + { + _ReadIndex++; + + _ReadSe = (_ReadIndex < Count) ? Items[_ReadIndex] : null; + + return (_ReadSe != null); + } + + #endregion + + #region Rewind + + internal void Rewind() + { + _ReadIndex = -1; + } + + #endregion + + #region GetItemValue + + internal string GetItemValue(string text) + { + foreach (SerialElement se in this) + { + if (se.SerType == SerElementType.Value) + { + if (se.Name.Equals(text)) + return (se.StringValue); + } + } + + return (null); + } + + #endregion + } + + #endregion + + #region SerialElement + + public class SerialElement + { + #region Private variables + + private SerElementType _SerType; + + private string _Name; + private object _Value; + + private SerialElementCollection _Sec; + + private int _ArrayCount; + private int _ValueIndex; + + #endregion + + #region Constructors + + public SerialElement(SerElementType type, string name) + { + _SerType = type; + _Name = name; + } + + public SerialElement(string name, object value) + { + _SerType = SerElementType.Value; + + _Name = name; + _Value = value; + } + + public SerialElement(SerElementType type, string name, object value) + { + _SerType = type; + + _Name = name; + _Value = value; + } + + public SerialElement(SerialElementCollection sec) + { + _SerType = SerElementType.Collection; + + _Sec = sec; + } + + #endregion + + #region Public properties + + /// + /// Element name + /// + public string Name + { + get { return (_Name); } + set { _Name = value; } + } + + /// + /// Element type. + /// + public SerElementType SerType + { + get { return (_SerType); } + set { _SerType = value; } + } + + /// + /// Element value + /// + public object Value + { + get { return (_Value); } + set { _Value = value; } + } + + /// + /// Element sub-collection. + /// + public SerialElementCollection Sec + { + get { return (_Sec); } + set { _Sec = value; } + } + + #endregion + + #region Internal properties + + #region ArrayCount + + internal int ArrayCount + { + get { return (_ArrayCount); } + set { _ArrayCount = value; } + } + + #endregion + + #region ColorValue + + internal Color ColorValue + { + get { return (GetValueColor()); } + } + + #endregion + + #region DataValue + + internal object DataValue + { + get + { + if (Value is string) + { + string s = (string)Value; + + if (s.StartsWith("\"") && s.EndsWith("\"")) + return (s.Substring(1, s.Length - 2)); + + if (s.StartsWith("#") && s.EndsWith("#")) + return (DateTime.Parse(s.Substring(1, s.Length - 2))); + + if (s.StartsWith("{") && s.EndsWith("}")) + return (ColorTranslator.FromHtml(s.Substring(1, s.Length - 2))); + + if (s.StartsWith("[") && s.EndsWith("]")) + { + s = s.Substring(1, s.Length - 2); + + string[] t = s.Split(','); + + TypeCode tc = TypeCode.Double; + + if (t.Length > 1) + tc = (TypeCode)int.Parse(t[1]); + + return (GetNumericValue(t[0], tc)); + } + + if (s.Equals("xsi:nil=\"true\"")) + return (null); + + return (s); + } + + return (null); + } + } + + #endregion + + #region StringValue + + internal string StringValue + { + get + { + if (Value is string) + { + string s = (string)Value; + + if (s.StartsWith("\"") && s.EndsWith("\"")) + return (s.Substring(1, s.Length - 2)); + + return (s); + } + + return (""); + } + } + + #endregion + + #region ValueIndex + + internal int ValueIndex + { + get { return (_ValueIndex); } + set { _ValueIndex = value; } + } + + #endregion + + #endregion + + #region GetValueColor + + internal Color GetValueColor() + { + string s = StringValue; + + if (string.IsNullOrEmpty(s) == false) + { + if (s.IndexOf('=') >= 0) + { + string pattern = @"A=(?\d+)\s*,\s*R=(?\d+)\s*,\s*G=(?\d+)\s*,\s*B=(?\d+)"; + + Match match = Regex.Match(s, pattern); + + if (match.Success == true) + { + Color color = Color.FromArgb( + int.Parse(match.Groups["A"].Value), + int.Parse(match.Groups["R"].Value), + int.Parse(match.Groups["G"].Value), + int.Parse(match.Groups["B"].Value)); + + return (color); + } + } + else + { + return (Color)Color.FromName(s); + } + } + + return (Color.Empty); + } + + #endregion + + #region GetValueString + + internal string GetValueString() + { + string s = GetValueStringEx(); + + string encodedXml = SecurityElement.Escape(s); + + return (encodedXml); + } + + internal string GetValueStringEx() + { + object value = Value; + + if (value == null) + return ("xsi:nil=\"true\""); + + if (value is string) + return ((string)value); + + if (value is DateTime) + return (((DateTime)value).ToString("o")); + + if (value is Color) + { + Color color = (Color)value; + + string s = color.ToString(); + + int start = s.IndexOf('[') + 1; + int end = s.IndexOf(']'); + + s = s.Substring(start, end - start); + + return (s); + } + + return (value.ToString()); + } + + #endregion + + #region GetDataValueString + + internal string GetDataValueString() + { + object value = Value; + + if (value == null) + return ("xsi:nil=\"true\""); + + if (value is string) + return ("\"" + value + "\""); + + if (value is DateTime) + return ("#" + ((DateTime)value).ToString("o") + "#"); + + if (value is Color) + return ("{" + ColorTranslator.ToHtml((Color)value) + "}"); + + if (Value is Enum == false) + { + TypeCode typeCode; + + if (IsNumericValue(out typeCode)) + { + string s = value.ToString(); + + return ("[" + s + "," + (int)typeCode + "]"); + } + } + + return (value.ToString()); + } + + #endregion + + #region GetValueEnum + + internal object GetValueEnum(Type type) + { + return (Enum.Parse(type, StringValue)); + } + + #endregion + + #region GetValuePoint + + internal Point GetValuePoint() + { + string svalue = StringValue; + + if (string.IsNullOrEmpty(svalue) == false) + { + string pattern = @"(?X=\d+)\s,\s(?Y=\d+)"; + + Match match = Regex.Match(svalue, pattern); + + if (match.Success == true) + { + Point pt = new Point( + int.Parse(match.Groups["x"].Value), + int.Parse(match.Groups["y"].Value)); + + return (pt); + } + } + + return (Point.Empty); + } + + #endregion + + #region GetValuePointF + + internal PointF GetValuePointF() + { + string svalue = StringValue; + + if (string.IsNullOrEmpty(svalue) == false) + { + string pattern = @"(?X=\d+)\s,\s(?Y=\d+)"; + + Match match = Regex.Match(svalue, pattern); + + if (match.Success == true) + { + PointF ptf = new PointF( + float.Parse(match.Groups["x"].Value), + float.Parse(match.Groups["y"].Value)); + + return (ptf); + } + } + + return (PointF.Empty); + } + + #endregion + + #region GetValueSize + + internal Size GetValueSize() + { + string svalue = StringValue; + + if (string.IsNullOrEmpty(svalue) == false) + { + string pattern = @"Width=(?\d+)\s*,\s*Height=(?\d+)"; + + Match match = Regex.Match(svalue, pattern); + + if (match.Success == true) + { + Size size = new Size( + int.Parse(match.Groups["width"].Value), + int.Parse(match.Groups["height"].Value)); + + return (size); + } + } + + return (Size.Empty); + } + + #endregion + + #region GetValueRect + + internal Rectangle GetValueRect() + { + string svalue = StringValue; + + if (string.IsNullOrEmpty(svalue) == false) + { + string pattern = @"(?X=\d+)\s,\s(?Y=\d+)\s,\s(?Width=\d+)\s,\s(?Height=\d+)"; + + Match match = Regex.Match(svalue, pattern); + + if (match.Success == true) + { + Rectangle rect = new Rectangle( + int.Parse(match.Groups["x"].Value), + int.Parse(match.Groups["y"].Value), + int.Parse(match.Groups["width"].Value), + int.Parse(match.Groups["height"].Value)); + + return (rect); + } + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetValueImage + + internal Image GetValueImage() + { + string svalue = StringValue; + + if (string.IsNullOrEmpty(svalue) == false) + return (StringToImage(svalue)); + + return (null); + } + + #region StringToImage + + private Image StringToImage(String data) + { + MemoryStream ms = new MemoryStream(Convert.FromBase64String(data)); + BinaryFormatter bf = new BinaryFormatter(); + + Image image = (Image)bf.Deserialize(ms); + + return (image); + } + + #endregion + + #endregion + + #region IsNumericValue + + private bool IsNumericValue(out TypeCode typeCode) + { + typeCode = Type.GetTypeCode(Value.GetType()); + + switch (typeCode) + { + case TypeCode.Byte: + case TypeCode.Decimal: + case TypeCode.Double: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.SByte: + case TypeCode.Single: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + return (true); + } + + return (false); + } + + #endregion + + #region GetNumericValue + + private object GetNumericValue(string s, TypeCode typeCode) + { + switch (typeCode) + { + case TypeCode.Byte: + return (Byte.Parse(s)); + + case TypeCode.Decimal: + return (Decimal.Parse(s)); + + case TypeCode.Double: + return (Double.Parse(s)); + + case TypeCode.Int16: + return (Int16.Parse(s)); + + case TypeCode.Int32: + return (Int32.Parse(s)); + + case TypeCode.Int64: + return (Int64.Parse(s)); + + case TypeCode.SByte: + return (SByte.Parse(s)); + + case TypeCode.Single: + return (Single.Parse(s)); + + case TypeCode.UInt16: + return (UInt16.Parse(s)); + + case TypeCode.UInt32: + return (UInt32.Parse(s)); + + case TypeCode.UInt64: + return (UInt64.Parse(s)); + } + + return (false); + } + + #endregion + } + + #endregion + + #region Interfaces + + internal interface IProcessSerialElement + { + void ProcessValue(SerialElement se); + void ProcessCollection(SerialElement se); + } + + #endregion + + #region SerElementType enum + + public enum SerElementType + { + Start, + End, + + ValueStart, + ValueEnd, + + Value, + DataValue, + + Collection, + } + + #endregion + + #region StreamWriterNC + + public class StreamWriterNC : IDisposable + { + #region Private variables + + private Stream _Stream; + + #endregion + + public StreamWriterNC(Stream stream) + { + _Stream = stream; + + stream.Position = 0; + } + + #region Public properties + + public Stream Stream + { + get { return (_Stream); } + internal set { _Stream = value; } + } + + #endregion + + #region Write + + public void Write(string s) + { + byte[] bytes = new byte[s.Length * sizeof(char)]; + + Buffer.BlockCopy(s.ToCharArray(), 0, bytes, 0, bytes.Length); + + _Stream.Write(bytes, 0, bytes.Length); + } + + #endregion + + #region WriteLine + + public void WriteLine(string s) + { + Write(s + "\n"); + } + + public void WriteLine() + { + Write("\n"); + } + + #endregion + + #region Dispose + + public void Dispose() + { + _Stream.Flush(); + } + + #endregion + } + + #endregion +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Licensing.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Licensing.cs new file mode 100644 index 00000000..1a2499bf --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Licensing.cs @@ -0,0 +1,147 @@ +using System; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts +{ + internal class Licensing + { +#if !TRIAL + internal static bool KeyValidated; + internal static int KeyValidated2; + + internal static bool ValidateLicenseKey(string key) + { + 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 (false); + } + + internal static bool CheckLicenseKey(string key) + { + // {F962CEC7-CD8F-4911-A9E9-CAB39962FC1F}, 114 + string[] parts = key.Split('-'); + int test = 0; + + for (int i = parts.Length - 1; i >= 0; i--) + { + if (parts[i] == "CD8F") + test += 12; + else if (parts[i] == "CAB39962FC1F") + test += 2; + else if (parts[i] == "A9E9") + test += 3; + else if (parts[i] == "4911") + test += 7; + else if (parts[i] == "F962CEC7") + 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; + + 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\\{542FD3B2-2F65-4290-AB4F-EBFF0444C54C}\\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 + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/OpenHand.cur b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/OpenHand.cur new file mode 100644 index 00000000..d04e8481 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/OpenHand.cur differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/ColorFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/ColorFactory.cs new file mode 100644 index 00000000..dd518c68 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/ColorFactory.cs @@ -0,0 +1,74 @@ +using System; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Primitives +{ + public class ColorFactory + { + /// + /// Converts hex string to Color type. + /// + /// Hexadecimal color representation. + /// Reference to Color object. + public static Color GetColor(string rgbHex) + { + if (string.IsNullOrEmpty(rgbHex) == false) + { + if (rgbHex.Length == 8) + { + return (Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0, 2), 16), + Convert.ToInt32(rgbHex.Substring(2, 2), 16), + Convert.ToInt32(rgbHex.Substring(4, 2), 16), + Convert.ToInt32(rgbHex.Substring(6, 2), 16))); + } + + return (Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0, 2), 16), + Convert.ToInt32(rgbHex.Substring(2, 2), 16), + Convert.ToInt32(rgbHex.Substring(4, 2), 16))); + } + + return Color.Empty; + } + + /// + /// Converts int value to Color type. + /// + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int rgb) + { + return ((rgb == -1) ? Color.Empty : + Color.FromArgb((rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF)); + } + + /// + /// Converts int values to Color type. + /// + /// + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int alpha, int rgb) + { + return ((rgb == -1) ? Color.Empty : + Color.FromArgb(alpha, (rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF)); + } + + /// + /// Converts int values to Color type. + /// + /// Reference to Color object. + public static Color GetColor(int red, int green, int blue) + { + return (ColorFactory.GetColor(255, red, green, blue)); + } + + /// + /// Converts int values to Color type. + /// + /// Reference to Color object. + public static Color GetColor(int alpha, int red, int green, int blue) + { + return (Color.FromArgb(alpha, red, green, blue)); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/Converters.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/Converters.cs new file mode 100644 index 00000000..186d028c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/Converters.cs @@ -0,0 +1,33 @@ +using System; +using System.ComponentModel; +using System.Globalization; + +namespace DevComponents.DotNetBar.Charts.Primitives +{ + #region BlankExpandableObjectConverter + + /// + /// BlankExpandableObjectConverter + /// + public class BlankExpandableObjectConverter : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + return (" "); + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/CustomCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/CustomCollection.cs new file mode 100644 index 00000000..8e982234 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/CustomCollection.cs @@ -0,0 +1,1377 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.InteropServices; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Represents custom collection with INotifyPropertyChanged and INotifyCollectionChanged interface support. + /// + /// + [Serializable, DebuggerDisplay("Count = {Count}"), ComVisible(false)] + public class CustomCollection : IList, IList, INotifyPropertyChanged, INotifyCollectionChanged + { + #region Events + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + #endregion + + #region Private variables + + private SimpleMonitor _Monitor; + private object _SyncRoot; + private readonly IList _Items; + + #endregion + + #region Constructors + + /// + /// Creates new instance of object. + /// + public CustomCollection() + { + _Monitor = new SimpleMonitor(); + _Items = new List(); + } + + /// + /// Creates new instance of object. + /// + public CustomCollection(int capacity) + { + _Monitor = new SimpleMonitor(); + _Items = new List(capacity); + } + + /// + /// Creates new instance of object. + /// + /// List to initialize collection with. + public CustomCollection(IList list) + { + if (list == null) + throw new ArgumentNullException("list"); + + _Monitor = new SimpleMonitor(); + _Items = list; + } + + #endregion + + #region Add + + /// + /// Add item to collection. + /// + /// Item to add. + public void Add(T item) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + InsertItem(_Items.Count, item); + } + + #endregion + + #region AddRange + + /// + /// Add range of items to collection. + /// + /// + public void AddRange(IEnumerable collection) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + CheckReentrancy(); + + int index = _Items.Count; + + foreach (T item in collection) + _Items.Insert(index++, item); + + OnPropertyChanged(CountString); + + List list = new List(collection); + + NotifyCollectionChangedEventArgs e = new + NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, list); + + OnCollectionChanged(e); + } + + #endregion + + #region Clear + + /// + /// Remove all items from collection. + /// + public void Clear() + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + ClearItems(); + } + + /// + /// Remove all items from collection. + /// + protected virtual void ClearItems() + { + CheckReentrancy(); + + _Items.Clear(); + + OnPropertyChanged(CountString); + OnPropertyChanged(ItemString); + + OnCollectionReset(); + } + + #endregion + + #region Contains + + /// + /// Checks whether collection contains item. + /// + /// Item to look for. + /// true if item is in collection. + public bool Contains(T item) + { + OnCollectionReadAccess(); + + return (_Items.Contains(item)); + } + + #endregion + + #region CopyTo + + /// + /// Copy collection to array. + /// + /// Array to copy to. + /// Index to copy from. + public void CopyTo(T[] array, int index) + { + OnCollectionReadAccess(); + + _Items.CopyTo(array, index); + } + + #endregion + + #region Count + + /// + /// Returns number of items in collection. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Count + { + get + { + OnCollectionReadAccess(); + + return (_Items.Count); + } + } + + #endregion + + #region CountString + + protected string CountString + { + get { return ("Count"); } + } + + #endregion + + #region GetEnumerator + + /// + /// Gets enumerator for collection. + /// + /// Enumerator. + public IEnumerator GetEnumerator() + { + OnCollectionReadAccess(); + + return (_Items.GetEnumerator()); + } + + #endregion + + #region Indexer[int] + + /// + /// Returns item at index. + /// + /// Index of item. + /// Item at index. + public T this[int index] + { + get + { + OnCollectionReadAccess(); + + return (_Items[index]); + } + + set + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + if ((index < 0) || (index >= _Items.Count)) + throw new ArgumentOutOfRangeException(); + + SetItem(index, value); + } + } + + #endregion + + #region IndexOf + + /// + /// Returns index of an item. + /// + /// Reference to item. + /// Index of item. + public int IndexOf(T item) + { + OnCollectionReadAccess(); + + return (_Items.IndexOf(item)); + } + + #endregion + + #region Insert + + /// + /// Insert item at specified location. + /// + /// Index to insert item in. + /// Item to insert. + public void Insert(int index, T item) + { + if ((index < 0) || (index > _Items.Count)) + throw new ArgumentOutOfRangeException("index"); + + InsertItem(index, item); + } + + #endregion + + #region InsertItem + + /// + /// Inserts item. + /// + /// Index to insert item at. + /// Reference to item. + protected virtual void InsertItem(int index, T item) + { + CheckReentrancy(); + + _Items.Insert(index, item); + + OnPropertyChanged(CountString); + OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index); + } + + #endregion + + #region IsCompatibleObject + + private static bool IsCompatibleObject(object value) + { + return (value is T) || (value == null && !typeof (T).IsValueType); + } + + #endregion + + #region ItemString + + protected string ItemString + { + get { return ("Item[]"); } + } + + #endregion + + #region Remove + + /// + /// Removes item from collection. + /// + /// Item to remove. + /// true if item was removed. + public bool Remove(T item) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + int index = _Items.IndexOf(item); + + if (index < 0) + return (false); + + RemoveItem(index); + + return (true); + } + + #endregion + + #region RemoveAt + + /// + /// Remove item at specified location. + /// + /// Index of item to remove. + public void RemoveAt(int index) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + if ((index < 0) || (index >= _Items.Count)) + throw new ArgumentOutOfRangeException(); + + RemoveItem(index); + } + + #endregion + + #region RemoveItem + + /// + /// Remove item at specified location. + /// + /// Index of item to remove. + protected virtual void RemoveItem(int index) + { + CheckReentrancy(); + + object item = _Items[index]; + _Items.RemoveAt(index); + + OnPropertyChanged(CountString); + OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, index); + } + + #endregion + + #region RemoveRange + + /// + /// Removes a range of items from the collection. + /// + /// + public void RemoveRange(int index, int count) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + CheckReentrancy(); + + List list = new List(count); + + for (int i = index + count - 1; i >= index; i--) + { + if ((uint)i < _Items.Count) + { + list.Add(_Items[i]); + + _Items.RemoveAt(i); + } + } + + OnPropertyChanged(CountString); + + NotifyCollectionChangedEventArgs e = new + NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, list); + + OnCollectionChanged(e); + } + + #endregion + + #region SetItem + + /// + /// Set item on location. + /// + /// Index + /// Item to assign. + protected virtual void SetItem(int index, T item) + { + CheckReentrancy(); + + T oldItem = _Items[index]; + _Items[index] = item; + + OnPropertyChanged(CountString); + OnPropertyChanged(ItemString); + + OnCollectionChanged(NotifyCollectionChangedAction.Replace, oldItem, item, index); + } + + #endregion + + #region IList support + + #region Add + + int IList.Add(object value) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + VerifyValueType(value); + + Add((T)value); + + return (Count - 1); + } + + #endregion + + #region Contains + + bool IList.Contains(object value) + { + return (IsCompatibleObject(value) && Contains((T)value)); + } + + #endregion + + #region GetItemsDirect + + /// + /// Returns items directly without checks. + /// + /// List of items. + protected IList GetItemsDirect() + { + return (_Items); + } + + #endregion + + #region Indexer[int] + + object IList.this[int index] + { + get + { + OnCollectionReadAccess(); + return (_Items[index]); + } + set + { + VerifyValueType(value); + this[index] = (T)value; + } + } + + #region IndexOf + + int IList.IndexOf(object value) + { + OnCollectionReadAccess(); + + return (IsCompatibleObject(value) ? IndexOf((T) value) : -1); + } + + #endregion + + #region Insert + + void IList.Insert(int index, object value) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + VerifyValueType(value); + + Insert(index, (T)value); + } + + #endregion + + #region IsFixedSize + + bool IList.IsFixedSize + { + get + { + IList items = _Items as IList; + + return ((items != null) && items.IsFixedSize); + } + } + + #endregion + + #region IsReadOnly + + bool IList.IsReadOnly + { + get { return (_Items.IsReadOnly); } + } + + #endregion + + #region Items + + /// + /// Returns the IList interface for items in collection. + /// + protected IList Items + { + get + { + OnCollectionReadAccess(); + + return (_Items); + } + } + + #endregion + + #region Remove + + void IList.Remove(object value) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + if (IsCompatibleObject(value)) + Remove((T)value); + } + + #endregion + + #endregion + + #region VerifyValueType + + private static void VerifyValueType(object value) + { + if (!IsCompatibleObject(value)) + throw new ArgumentException("value is of wrong type"); + } + + #endregion + + #endregion + + #region IEnumerable.GetEnumerator + + IEnumerator IEnumerable.GetEnumerator() + { + OnCollectionReadAccess(); + + return (_Items.GetEnumerator()); + } + + #endregion + + #region ICollection support + + #region CopyTo + + void ICollection.CopyTo(Array array, int index) + { + CheckReentrancy(); + OnCollectionReadAccess(); + + if (array == null) + throw new ArgumentNullException("array"); + + if (array.Rank != 1) + throw new ArgumentException("Argument array.Rank multi-dimensional not supported"); + + if (array.GetLowerBound(0) != 0) + throw new ArgumentException("Argument array non zero lower bound not supported"); + + if (index < 0) + throw new ArgumentOutOfRangeException("index", "index must be non-negative number"); + + if ((array.Length - index) < Count) + throw new ArgumentException("array too small"); + + T[] localArray = array as T[]; + + if (localArray != null) + { + _Items.CopyTo(localArray, index); + } + else + { + Type elementType = array.GetType().GetElementType(); + Type c = typeof(T); + + if (elementType == null || + (!elementType.IsAssignableFrom(c) && !c.IsAssignableFrom(elementType))) + { + throw new ArgumentException("Argument array of invalid type"); + } + + object[] objArray = array as object[]; + + if (objArray == null) + throw new ArgumentException("Argument array invalid type"); + + int count = _Items.Count; + + try + { + for (int i = 0; i < count; i++) + objArray[index++] = _Items[i]; + } + catch (ArrayTypeMismatchException) + { + throw new ArgumentException("Argument array invalid type"); + } + } + } + + #endregion + + #region IsSynchronized + + bool ICollection.IsSynchronized + { + get { return false; } + } + + #endregion + + #region IsReadOnly + + bool ICollection.IsReadOnly + { + get { return (_Items.IsReadOnly); } + } + + #endregion + + #region SyncRoot + + object ICollection.SyncRoot + { + get + { + if (_SyncRoot == null) + { + ICollection items = _Items as ICollection; + + if (items != null) + _SyncRoot = items.SyncRoot; + else + System.Threading.Interlocked.CompareExchange(ref _SyncRoot, new object(), null); + } + + return (_SyncRoot); + } + } + + #endregion + + #endregion + + #region OnCollectionReadAccess + + /// + /// Occurs when collection is read. + /// + protected virtual void OnCollectionReadAccess() + { + } + + #endregion + + #region OnPropertyChanged + + /// + /// Occurs when collection property has changed. + /// + /// Event arguments. + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType)); + } + + protected void OnStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + StyleVisualChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #region StyleVisualChangeHandler + + protected virtual void StyleVisualChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) + { + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + OnPropertyChangedEx(e.PropertyName, changeType); + } + + #endregion + + #endregion + + #endregion + + #region BlockReentrancy + + /// + /// Blocks the collection reentrancy. + /// + /// IDisposable to end reentrancy + protected IDisposable BlockReentrancy() + { + _Monitor.Enter(); + + return (_Monitor); + } + + #endregion + + #region CheckReentrancy + + /// + /// Checks whether call creates reentrancy. + /// + protected void CheckReentrancy() + { + if ((_Monitor.Busy && (CollectionChanged != null)) && + (CollectionChanged.GetInvocationList().Length > 1)) + { + throw new InvalidOperationException("CustomCollectionReentrancyNotAllowed"); + } + } + + #endregion + + #region SimpleMonitor + + [Serializable] + private class SimpleMonitor : IDisposable + { + // Fields + private int _BusyCount; + + // Methods + public void Dispose() + { + _BusyCount--; + } + + public void Enter() + { + _BusyCount++; + } + + // Properties + public bool Busy + { + get { return (_BusyCount > 0); } + } + } + #endregion + + #region INotifyCollectionChanged Members + + /// + /// Occurs when collection has changed. + /// + public event NotifyCollectionChangedEventHandler CollectionChanged; + + protected void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index) + { + OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index)); + } + + protected void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem, object newItem, int index) + { + OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index)); + } + + protected void OnCollectionReset() + { + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + } + + /// + /// Called when collection has changed. + /// + /// Event arguments. + protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + { + if (CollectionChanged != null) + { + using (BlockReentrancy()) + { + CollectionChanged(this, e); + } + } + } + + #endregion + } + + #region INotifyCollectionChanged + /// + /// Represents collection changed notification interface. + /// + public interface INotifyCollectionChanged + { + /// + /// Occurs when collection changed. + /// + event NotifyCollectionChangedEventHandler CollectionChanged; + } + /// + /// Defines change actions. + /// + public enum NotifyCollectionChangedAction + { + /// + /// Items were added. + /// + Add, + /// + /// Items were removed. + /// + Remove, + /// + /// Items were replaced. + /// + Replace, + /// + /// Items were moved. + /// + Move, + /// + /// Collection was reset. + /// + Reset + } + /// + /// Defines delegate for collection notification events. + /// + /// Event sender. + /// Event arguments. + public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e); + /// + /// Defines collection change notification event arguments. + /// + public class NotifyCollectionChangedEventArgs : EventArgs + { + #region Private Vars + + private NotifyCollectionChangedAction _Action; + private IList _NewItems; + private int _NewStartingIndex; + private IList _OldItems; + private int _OldStartingIndex; + + #endregion + + /// + /// Create new instance of object. + /// + /// Action + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Reset) + { + throw new ArgumentException("WrongActionForCtor"); + } + InitializeAdd(action, null, -1); + } + + /// + /// Creates new instance of object. + /// + /// Specifies action. + /// List of changed items. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItems != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + InitializeAdd(action, null, -1); + } + else + { + if (changedItems == null) + { + throw new ArgumentNullException("changedItems"); + } + InitializeAddOrRemove(action, changedItems, -1); + } + + } + /// + /// Creates new instance of object. + /// + /// Specifies action. + /// Item that was changed. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItem != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + InitializeAdd(action, null, -1); + } + else + { + InitializeAddOrRemove(action, new object[] { changedItem }, -1); + } + } + + /// + /// Creates new instance of object. + /// + /// Action. + /// New items in collection. + /// Old items in collection. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (newItems == null) + { + throw new ArgumentNullException("newItems"); + } + if (oldItems == null) + { + throw new ArgumentNullException("oldItems"); + } + InitializeMoveOrReplace(action, newItems, oldItems, -1, -1); + } + + /// + /// Creates new instance of object. + /// + /// Action. + /// List of changed items. + /// Starting index of change. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int startingIndex) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItems != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + if (startingIndex != -1) + { + throw new ArgumentException("ResetActionRequiresIndexMinus1"); + } + InitializeAdd(action, null, -1); + } + else + { + if (changedItems == null) + { + throw new ArgumentNullException("changedItems"); + } + if (startingIndex < -1) + { + throw new ArgumentException("IndexCannotBeNegative"); + } + InitializeAddOrRemove(action, changedItems, startingIndex); + } + } + + /// + /// Creates new instance of object. + /// + /// Action + /// Changed item + /// Index of change + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItem != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + if (index != -1) + { + throw new ArgumentException("ResetActionRequiresIndexMinus1"); + } + InitializeAdd(action, null, -1); + } + else + { + InitializeAddOrRemove(action, new object[] { changedItem }, index); + } + } + + /// + /// Creates new instance of object. + /// + /// Action + /// New item + /// Old item + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, -1, -1); + } + + /// + /// Creates new instance of object. + /// + /// Action + /// New items. + /// Removed items. + /// Starting index of change. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (newItems == null) + { + throw new ArgumentNullException("newItems"); + } + if (oldItems == null) + { + throw new ArgumentNullException("oldItems"); + } + InitializeMoveOrReplace(action, newItems, oldItems, startingIndex, startingIndex); + } + + /// + /// Creates new instance of object. + /// + /// Action + /// Changed items + /// New index + /// Old index + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Move) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (index < 0) + { + throw new ArgumentException("IndexCannotBeNegative"); + } + InitializeMoveOrReplace(action, changedItems, changedItems, index, oldIndex); + } + + /// + /// Creates new instance of object. + /// + /// Action + /// Changed item + /// New index + /// Old index + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Move) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (index < 0) + { + throw new ArgumentException("IndexCannotBeNegative"); + } + object[] newItems = new object[] { changedItem }; + InitializeMoveOrReplace(action, newItems, newItems, index, oldIndex); + } + + /// + /// Creates new instance of object. + /// + /// Action. + /// New item + /// Old item + /// New index + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem, int index) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, index, index); + } + + private void InitializeAdd(NotifyCollectionChangedAction action, IList newItems, int newStartingIndex) + { + _Action = action; + _NewItems = (newItems == null) ? null : ArrayList.ReadOnly(newItems); + _NewStartingIndex = newStartingIndex; + } + + private void InitializeAddOrRemove(NotifyCollectionChangedAction action, IList changedItems, int startingIndex) + { + if (action == NotifyCollectionChangedAction.Add) + { + InitializeAdd(action, changedItems, startingIndex); + } + else if (action == NotifyCollectionChangedAction.Remove) + { + InitializeRemove(action, changedItems, startingIndex); + } + } + + private void InitializeMoveOrReplace(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex, int oldStartingIndex) + { + InitializeAdd(action, newItems, startingIndex); + InitializeRemove(action, oldItems, oldStartingIndex); + } + + private void InitializeRemove(NotifyCollectionChangedAction action, IList oldItems, int oldStartingIndex) + { + _Action = action; + _OldItems = (oldItems == null) ? null : ArrayList.ReadOnly(oldItems); + _OldStartingIndex = oldStartingIndex; + } + + /// + /// Gets the type of the collection change action. + /// + public NotifyCollectionChangedAction Action + { + get + { + return _Action; + } + } + /// + /// Gets list of newly added items. + /// + public IList NewItems + { + get + { + return _NewItems; + } + } + /// + /// Gets new starting index. + /// + public int NewStartingIndex + { + get + { + return _NewStartingIndex; + } + } + /// + /// Gets list of removed items. + /// + public IList OldItems + { + get + { + return _OldItems; + } + } + /// + /// Old starting index. + /// + public int OldStartingIndex + { + get + { + return _OldStartingIndex; + } + } + } + #endregion + + public class CustomNamedCollection : CustomCollection where T : class, INamed + { + #region Indexer[name] + + /// + /// Returns item at index. + /// + /// Name of item. + /// Item or null. + public T this[string name] + { + get + { + if (string.IsNullOrEmpty(name) == false) + { + OnCollectionReadAccess(); + + foreach (T item in Items) + { + if (name.Equals(item.Name) == true) + return (item); + } + } + + return (null); + } + + set + { + if (Items.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); + + T item = this[name]; + + if (item == null) + throw new ArgumentOutOfRangeException(); + + int index = Items.IndexOf(item); + + if ((uint)index >= Items.Count) + throw new ArgumentOutOfRangeException(); + + SetItem(index, value); + } + } + + #endregion + + #region GetUniqueName + + public string GetUniqueName(string rootText) + { + for (int i = 1; i < 500; i++) + { + string s = rootText + i; + + if (this[s] == null) + return (s); + } + + return (rootText); + } + + #endregion + } + + #region INamed + + public interface INamed + { + string Name { get; set; } + } + + #endregion + +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/SymbolDef.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/SymbolDef.cs new file mode 100644 index 00000000..957a5be5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Primitives/SymbolDef.cs @@ -0,0 +1,549 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Globalization; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + [TypeConverter(typeof(SymbolDefConvertor))] + [Editor(typeof(SymbolDefEditor), typeof(UITypeEditor))] + public class SymbolDef : INotifyPropertyChanged, IDisposable, IProcessSerialElement + { + #region Private variables + + private string _Symbol = ""; + private string _SymbolRealized; + + private float _SymbolSize = -1f; + private Color _SymbolColor = Color.Empty; + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + + private Font _SymbolFont; + private Size _RealSymbolSize; + + #endregion + + #region Public properties + + #region Symbol + + /// + /// Indicates the displayed Symbol. Symbol setting takes precedence over Image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("displayed Symbol. Symbol setting takes precedence over Image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return (_Symbol); } + + set + { + if (value == null) + value = ""; + + if (value != _Symbol) + { + _Symbol = value; + _SymbolRealized = null; + + OnPropertyChangedEx("Symbol"); + } + } + } + + #endregion + + #region SymbolColor + + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return (_SymbolColor); } + + set + { + if (_SymbolColor != value) + { + _SymbolColor = value; + + OnPropertyChangedEx("SymbolColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeSymbolColor() + { + return (_SymbolColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetSymbolColor() + { + SymbolColor = Color.Empty; + } + + #endregion + + #region SymbolRealized + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get + { + if (_SymbolRealized == null) + { + if (_Symbol != null) + _SymbolRealized = Symbols.GetSymbol(_Symbol); + } + + return (_SymbolRealized); + } + } + + #endregion + + #region SymbolSet + + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return (_SymbolSet); } + + set + { + if (_SymbolSet != value) + { + _SymbolSet = value; + + _SymbolRealized = null; + _SymbolFont = null; + _RealSymbolSize = Size.Empty; + + OnPropertyChangedEx("SymbolSet"); + } + } + } + + #endregion + + #region SymbolSize + + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(-1f), Category("Appearance")] + [Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return (_SymbolSize); } + + set + { + if (value != _SymbolSize) + { + _SymbolSize = value; + _SymbolFont = null; + _RealSymbolSize = Size.Empty; + + OnPropertyChangedEx("SymbolSize"); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether SymbolDef is Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + return ((string.IsNullOrEmpty(_Symbol) == true) && + (_SymbolColor.IsEmpty == true) && + (_SymbolSize == -1f)); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region SymbolFont + + internal Font SymbolFont + { + get + { + if (_SymbolFont == null) + _SymbolFont = Symbols.GetFont(SymbolSize, SymbolSet); + + return (_SymbolFont); + } + + set + { + _SymbolFont = value; + } + } + + #endregion + + #region IsValidSymbol + + internal bool IsValidSymbol + { + get { return (string.IsNullOrEmpty(SymbolRealized) == false); } + } + + #endregion + + #endregion + + #region GetSymbolSize + + internal Size GetSymbolSize(Graphics g) + { + if (_RealSymbolSize == Size.Empty) + { + Font font = SymbolFont; + + Size size = g.MeasureString(SymbolRealized, font).ToSize(); + + size.Width++; + size.Height++; + + _RealSymbolSize = size; + } + + return (_RealSymbolSize); + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the SymbolDef. + /// + /// Copy of the SymbolDef. + public SymbolDef Copy() + { + SymbolDef style = new SymbolDef(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(SymbolDef style) + { + style.Symbol = _Symbol; + + style.SymbolColor = _SymbolColor; + style.SymbolSet = _SymbolSet; + style.SymbolSize = _SymbolSize; + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData(string serialName) + { + if (IsEmpty == false) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "SymbolDef"; + + sec.AddStartElement(serialName); + } + + if (IsValidSymbol == true) + sec.AddValue("Symbol", Symbol); + + sec.AddValue("SymbolColor", SymbolColor, Color.Empty); + sec.AddValue("SymbolSet", SymbolSet, eSymbolSet.Awesome); + sec.AddValue("SymbolSize", SymbolSize, -1f); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + return (null); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Symbol": + Symbol = se.GetValueString(); + break; + + case "SymbolColor": + SymbolColor = se.GetValueColor(); + break; + + case "SymbolSet": + SymbolSet = (eSymbolSet)se.GetValueEnum(typeof(eSymbolSet)); + break; + + case "SymbolSize": + SymbolSize = float.Parse(se.StringValue); + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + switch (se.Name) + { + default: + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(VisualPropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChangedEx(string s) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + { + VisualPropertyChangedEventArgs e = + new VisualPropertyChangedEventArgs(s); + + eh(this, e); + } + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + { + VisualPropertyChangedEventArgs e = + new VisualPropertyChangedEventArgs(s, changeType); + + eh(this, e); + } + } + + #endregion + + #region UpdateChangeHandler + + private void UpdateChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// StyleChanged + /// + /// + /// + protected virtual void StyleChanged( + object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged((VisualPropertyChangedEventArgs)e); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + SymbolFont = null; + } + + #endregion + } + + #region SymbolDefConvertor + + /// + /// SymbolDefConvertor + /// + public class SymbolDefConvertor : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + SymbolDef sd = value as SymbolDef; + + if (sd != null) + return (sd.SymbolSet.ToString()); + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + + #region SymbolDefEditor + + /// + /// SymbolDefEditor + /// + public class SymbolDefEditor : UITypeEditor + { + #region GetPaintValueSupported + + /// + /// GetPaintValueSupported + /// + /// + /// + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region PaintValue + + /// + /// PaintValue + /// + /// + public override void PaintValue(PaintValueEventArgs e) + { + SymbolDef sd = e.Value as SymbolDef; + + if (sd != null) + { + Font font = Symbols.GetFont(10, sd.SymbolSet); + + Color color = sd.SymbolColor; + + if (sd.SymbolColor.IsEmpty || sd.SymbolColor == Color.White) + color = Color.Brown; + + using (Brush br = new SolidBrush(color)) + { + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + e.Graphics.DrawString(sd.SymbolRealized, font, br, e.Bounds, sf); + } + } + } + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Properties/Resources.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Properties/Resources.Designer.cs new file mode 100644 index 00000000..335f1f14 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34209 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DevComponents.DotNetBar.Charts.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DevComponents.DotNetBar.Charts.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Properties/Resources.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Properties/Resources.resx new file mode 100644 index 00000000..04e2214f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Properties/Resources.resx @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ScrollBarLite/ScrollBarLite.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ScrollBarLite/ScrollBarLite.cs new file mode 100644 index 00000000..5b8e63cd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/ScrollBarLite/ScrollBarLite.cs @@ -0,0 +1,1548 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + [ToolboxItem(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class HScrollBarLite : ScrollBarLite + { + public HScrollBarLite() + { + Orientation = Orientation.Horizontal; + } + } + + [ToolboxItem(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class VScrollBarLite : ScrollBarLite + { + public VScrollBarLite() + { + Orientation = Orientation.Vertical; + } + } + + [ToolboxItem(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ScrollBarLite : ChartVisualElement + { + #region Events + + #region Scroll + + /// + /// Occurs when the Horizontal or Vertical scrollbar has been scrolled + /// + [Description("Occurs when the Horizontal or Vertical scrollbar has been scrolled.")] + public event EventHandler Scroll; + + #endregion + + #region ValueChanged + + /// + /// Occurs when the Value property is changed. + /// + public event EventHandler ValueChanged; + + #endregion + + #endregion + + #region Private Variables + + private Orientation _Orientation = Orientation.Horizontal; + + private int _LargeChange = 10; + private int _Maximum = 100; + private int _Minimum; + private int _SmallChange = 1; + private int _Value; + + private bool _Enabled = true; + + private Rectangle _ArrowIncreaseBounds; + private Rectangle _ArrowDecreaseBounds; + private Rectangle _ThumbBounds; + + private Size _MinArrowSize = new Size(5, 7); + private Size _MaxArrowSize = new Size(50, 50); + private Size _MinThumbSize = new Size(10, 12); + + private ScrollBarVisualStyles _ScrollBarVisualStyles; + private EffectiveStyles _EffectiveStyles; + + private ItemHitArea _HitArea; + private ItemHitArea _LastHitArea; + private ItemHitArea _MouseDownHitArea; + private int _ThumbOffset; + + private Timer _ClickTimer; + private int _ClickCount; + private bool _RaiseEndScroll; + + private bool _Inverted; + + #endregion + + #region Constructor + + public ScrollBarLite() + { + Size = new Size(10, 10); + + _EffectiveStyles = new EffectiveStyles(this); + } + + #endregion + + #region Public properties + + #region Enabled + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool Enabled + { + get { return (_Enabled); } + + internal set + { + if (value != _Enabled) + { + _Enabled = value; + + InvalidateRender(); + } + } + } + + #endregion + + #region Orientation + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Orientation Orientation + { + get { return (_Orientation); } + + internal set + { + if (value != _Orientation) + { + _Orientation = value; + + InvalidateLayout(); + } + } + } + + #endregion + + #region ScrollBarVisualStyles + + /// + /// Gets or sets the visual styles for the ScrollBar. + /// + [Category("Style")] + [Description("Indicates the visual styles for the ScrollBar.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarVisualStyles ScrollBarVisualStyles + { + get + { + if (_ScrollBarVisualStyles == null) + { + _ScrollBarVisualStyles = new ScrollBarVisualStyles(); + + StyleVisualChangeHandler(null, _ScrollBarVisualStyles); + } + + return (_ScrollBarVisualStyles); + } + + set + { + if (_ScrollBarVisualStyles != value) + { + ScrollBarVisualStyles oldValue = _ScrollBarVisualStyles; + + _ScrollBarVisualStyles = value; + + OnStyleChanged("ScrollBarVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region Value + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Value + { + get { return (_Value); } + + set + { + if (value < Minimum) + throw new ArgumentOutOfRangeException("Value must be >= to Minimum property value."); + + if (value > Maximum) + throw new ArgumentOutOfRangeException("Value must be <= to Maximum property value."); + + value = NormalizeValue(value); + + if (value != _Value) + { + int oldValue = _Value; + _Value = value; + + OnValueChanged(oldValue, value); + + InvalidateLayoutBounds(this); + } + } + } + + #region OnValueChanged + + private void OnValueChanged(int oldValue, int newValue) + { + if (ValueChanged != null) + { + ValueChangedEventArgs args + = new ValueChangedEventArgs(oldValue, newValue); + + ValueChanged(this, args); + } + } + + #endregion + + #endregion + + #region Visible + + /// + /// Get or sets whether the item is visible + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool Visible + { + get { return (base.Visible); } + set { base.Visible = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region Height + + internal int Height + { + get { return (BoundsRelative.Height); } + + set + { + if (value != BoundsRelative.Height) + { + Rectangle r = BoundsRelative; + + _ThumbOffset -= (value - r.Height); + + r.Height = value; + + BoundsRelative = r; + } + } + } + + #endregion + + #region Inverted + + internal bool Inverted + { + get { return (_Inverted); } + set { _Inverted = value; } + } + + #endregion + + #region IsAtMaxumum + + internal bool IsAtMaxumum + { + get { return (_Value + _LargeChange >= _Maximum); } + } + + #endregion + + #region IsAtMinumum + + internal bool IsAtMinumum + { + get { return (_Value == _Minimum); } + } + + #endregion + + #region IsVertical + + internal bool IsVertical + { + get { return (Orientation == Orientation.Vertical); } + } + + #endregion + + #region LargeChange + + internal int LargeChange + { + get { return (_LargeChange); } + + set + { + if (value != _LargeChange) + { + if (value < 0) + throw new ArgumentOutOfRangeException(); + + _LargeChange = value; + + InvalidateRender(); + } + } + } + + #endregion + + #region Location + + internal Point Location + { + get { return (BoundsRelative.Location); } + + set + { + Rectangle r = BoundsRelative; + r.Location = value; + + BoundsRelative = r; + } + } + + #endregion + + #region Maximum + + internal int Maximum + { + get { return (_Maximum); } + + set + { + if (value != _Maximum) + { + _Maximum = value; + + InvalidateRender(); + } + } + } + + #endregion + + #region Minimum + + internal int Minimum + { + get { return (_Minimum); } + + set + { + if (value != _Minimum) + { + _Minimum = value; + + InvalidateRender(); + } + } + } + + #endregion + + #region SmallChange + + internal int SmallChange + { + get { return (_SmallChange); } + + set + { + if (value != _SmallChange) + { + if (value < 0) + throw new ArgumentOutOfRangeException(); + + _SmallChange = value; + + InvalidateRender(); + } + } + } + + #endregion + + #region Width + + internal int Width + { + get { return (BoundsRelative.Width); } + + set + { + if (value != BoundsRelative.Width) + { + Rectangle r = BoundsRelative; + + _ThumbOffset -= (value - r.Width); + + r.Width = value; + + BoundsRelative = r; + } + } + } + + #endregion + + #endregion + + #region MeasureOverride + + protected override void MeasureOverride(ChartLayoutInfo layoutInfo) + { + } + + #endregion + + #region ArrangeOverride + + protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) + { + UpdateBarBounds(); + } + + #region UpdateBarBounds + + private void UpdateBarBounds() + { + Rectangle bounds = Bounds; + + _ThumbBounds = Rectangle.Empty; + + if (Orientation == Orientation.Horizontal) + { + int arrowWidth = Height; + arrowWidth = Math.Max(arrowWidth, _MinArrowSize.Width); + arrowWidth = Math.Min(arrowWidth, _MaxArrowSize.Width); + + _ArrowDecreaseBounds = bounds; + _ArrowDecreaseBounds.Width = arrowWidth; + + _ArrowIncreaseBounds = bounds; + _ArrowIncreaseBounds.X = _ArrowIncreaseBounds.Right - arrowWidth; + _ArrowIncreaseBounds.Width = arrowWidth; + + if (bounds.Width > (_ArrowDecreaseBounds.Width + + _ArrowIncreaseBounds.Width + _MinThumbSize.Width)) + { + int tv = Maximum - Minimum; + int width = Width - (2 * arrowWidth); + int x = (width * Value) / tv; + + _ThumbBounds = bounds; + _ThumbBounds.X += (x + arrowWidth); + _ThumbBounds.Width = GetThumbSize(); + _ThumbBounds.Y += 1; + _ThumbBounds.Height -= 2; + } + } + else + { + int arrowHeight = Width; + arrowHeight = Math.Max(arrowHeight, _MinArrowSize.Height); + arrowHeight = Math.Min(arrowHeight, _MaxArrowSize.Height); + + _ArrowDecreaseBounds = bounds; + _ArrowDecreaseBounds.Height = arrowHeight; + + _ArrowIncreaseBounds = bounds; + _ArrowIncreaseBounds.Y = bounds.Bottom - arrowHeight; + _ArrowIncreaseBounds.Height = arrowHeight; + + if (bounds.Height > (_ArrowDecreaseBounds.Height + + _ArrowIncreaseBounds.Height + _MinThumbSize.Height)) + { + int tv = Maximum - Minimum; + int height = Height - (2 * arrowHeight); + int y = (height * Value) / tv; + + _ThumbBounds = bounds; + _ThumbBounds.Height = GetThumbSize(); + + if (Inverted == true) + _ThumbBounds.Y = (bounds.Bottom - _ThumbBounds.Height) - (y + arrowHeight); + else + _ThumbBounds.Y += (y + arrowHeight); + + _ThumbBounds.X += 1; + _ThumbBounds.Width -= 2; + } + } + } + + #region GetThumbSize + + private int GetThumbSize() + { + int size = GetAvailableTrackArea(); + + int i = (int)(size * ((float)LargeChange / (float)(Maximum - Minimum))) + 1; + + if (Orientation == Orientation.Horizontal) + i = Math.Max(_MinThumbSize.Width, i); + else + i = Math.Max(_MinThumbSize.Height, i); + + i = Math.Min(i, size); + + return i; + } + + #endregion + + #region GetAvailableTrackArea + + private int GetAvailableTrackArea() + { + Rectangle r = BoundsRelative; + + int size; + + if (Orientation == Orientation.Horizontal) + size = r.Width - (_ArrowDecreaseBounds.Width + _ArrowIncreaseBounds.Width); + else + size = r.Height - (_ArrowDecreaseBounds.Height + _ArrowIncreaseBounds.Height); + + return Math.Max(size, 8); + } + + #endregion + + #endregion + + #endregion + + #region RenderOverride + + protected override void RenderOverride(ChartRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + if (CanDrawScrollBar()) + { + Rectangle bounds = Bounds; + + RenderBackground(g, bounds); + + RenderArrowDecrease(g, bounds); + RenderArrowIncrease(g, bounds); + + RenderThumb(g, bounds); + + RenderBorder(g, bounds); + } + } + + #region CanDrawScrollBar + + private bool CanDrawScrollBar() + { + Rectangle bounds = Bounds; + + if (Orientation == Orientation.Horizontal) + { + if (bounds.Height < _MinArrowSize.Height) + return (false); + + int widthNeeded = (_ArrowIncreaseBounds.Width + _ArrowDecreaseBounds.Width); + + return (bounds.Width >= widthNeeded); + } + else + { + if (bounds.Width < _MinArrowSize.Width) + return (false); + + int heightNeeded = (_ArrowIncreaseBounds.Height + _ArrowDecreaseBounds.Height); + + return (bounds.Height >= heightNeeded); + } + } + + #endregion + + #region RenderBackground + + private void RenderBackground(Graphics g, Rectangle bounds) + { + ScrollBarVisualStyle style = GetEffectiveStyle(); + + bool noAlpha = (style.NoAlphaOnMouseOver == Tbool.True) ? IsMouseOver : false; + + using (Brush br = style.TrackBackground.GetBrush(bounds, noAlpha)) + g.FillRectangle(br, bounds); + } + + #endregion + + #region RenderArrowDecrease + + private void RenderArrowDecrease(Graphics g, Rectangle bounds) + { + ScrollBarVisualStyle style = GetAreaStyle(Inverted == true ? ItemHitArea.ArrowIncrease : ItemHitArea.ArrowDecrease); + Rectangle r = _ArrowDecreaseBounds; + + bool noAlpha = (style.NoAlphaOnMouseOver == Tbool.True) ? IsMouseOver : false; + + using (Brush br = style.ArrowBackground.GetBrush(r, noAlpha)) + g.FillRectangle(br, r); + + if (style.ArrowColor.IsEmpty == false) + { + Color color = style.GetColor(style.ArrowColor, noAlpha); + + using (Pen pen = new Pen(color)) + { + int n = Math.Min(r.Width, r.Height) / 4 + 1; + + if (Orientation == Orientation.Horizontal) + { + int x = r.X + (n * 5 / 4); + int y = r.Y + (r.Height / 2); + + for (int i = 0; i < n; i++) + { + g.DrawLine(pen, x + i, y - i, x + i + 1, y - i); + g.DrawLine(pen, x + i, y + i, x + i + 1, y + i); + } + } + else + { + int x = r.X + (r.Width / 2); + int y = r.Y + (n * 5 / 4); + + for (int i = 0; i < n; i++) + { + g.DrawLine(pen, x - i, y + i, x - i, y + i + 1); + g.DrawLine(pen, x + i, y + i, x + i, y + i + 1); + } + } + } + } + + if (style.ArrowBorderColor.IsEmpty == false) + { + Color color = style.GetColor(style.ArrowBorderColor, noAlpha); + + using (Pen pen = new Pen(color)) + g.DrawRectangle(pen, r); + } + } + + #endregion + + #region RenderArrowIncrease + + private void RenderArrowIncrease(Graphics g, Rectangle bounds) + { + ScrollBarVisualStyle style = GetAreaStyle(Inverted == true ? ItemHitArea.ArrowDecrease : ItemHitArea.ArrowIncrease); + Rectangle r = _ArrowIncreaseBounds; + + bool noAlpha = (style.NoAlphaOnMouseOver == Tbool.True) ? IsMouseOver : false; + + using (Brush br = style.ArrowBackground.GetBrush(r, noAlpha)) + g.FillRectangle(br, r); + + if (style.ArrowColor.IsEmpty == false) + { + Color color = style.GetColor(style.ArrowColor, noAlpha); + + using (Pen pen = new Pen(color)) + { + int n = Math.Min(r.Width, r.Height) / 4 + 1; + + if (Orientation == Orientation.Horizontal) + { + int x = r.Right - (n * 5 / 4); + int y = r.Y + (r.Height / 2); + + for (int i = 0; i < n; i++) + { + g.DrawLine(pen, x - i, y - i, x - i - 1, y - i); + g.DrawLine(pen, x - i, y + i, x - i - 1, y + i); + } + } + else + { + int x = r.X + (r.Width / 2); + int y = r.Bottom - (n * 5 / 4); + + for (int i = 0; i < n; i++) + { + g.DrawLine(pen, x - i, y - i, x - i, y - i - 1); + g.DrawLine(pen, x + i, y - i, x + i, y - i - 1); + } + } + } + } + + if (style.ArrowBorderColor.IsEmpty == false) + { + Color color = style.GetColor(style.ArrowBorderColor, noAlpha); + + using (Pen pen = new Pen(color)) + g.DrawRectangle(pen, r); + } + } + + #endregion + + #region RenderThumb + + private void RenderThumb(Graphics g, Rectangle bounds) + { + if (_ThumbBounds.IsEmpty == false) + { + ScrollBarVisualStyle style = GetAreaStyle(ItemHitArea.Thumb); + + bool noAlpha = (style.NoAlphaOnMouseOver == Tbool.True) ? IsMouseOver : false; + + using (Brush br = style.ThumbBackground.GetBrush(_ThumbBounds, noAlpha)) + g.FillRectangle(br, _ThumbBounds); + + if (style.ThumbColor.IsEmpty == false) + { + Color color = style.GetColor(style.ThumbColor, noAlpha); + + if (Orientation == Orientation.Horizontal) + RenderHThumbHashMarks(g, bounds, color); + else + RenderVThumbHashMarks(g, bounds, color); + } + + if (style.ThumbBorderColor.IsEmpty == false) + { + Color color = style.GetColor(style.ThumbBorderColor, noAlpha); + + using (Pen pen = new Pen(color)) + g.DrawRectangle(pen, _ThumbBounds); + } + } + } + + #region RenderHThumbHashMarks + + private void RenderHThumbHashMarks( + Graphics g, Rectangle bounds, Color color) + { + Rectangle r = _ThumbBounds; + + if (_ThumbBounds.Width > 20) + { + int n = r.Height / 6 + 1; + int m = r.Height / 10 + 1; + + r.X += (r.Width / 2 - 1 - m); + r.Y += n; + + r.Width = m * 2 + 3; + r.Height -= (n * 2); + + Point pt1 = new Point(r.X, r.Y); + Point pt2 = new Point(r.X, r.Bottom); + + using (Pen pen = new Pen(color)) + { + for (int i = 0; i < 3; i++) + { + g.DrawLine(pen, pt1, pt2); + + pt1.X += (m + 1); + pt2.X += (m + 1); + } + } + } + } + + #endregion + + #region RenderVThumbHashMarks + + private void RenderVThumbHashMarks( + Graphics g, Rectangle bounds, Color color) + { + Rectangle r = _ThumbBounds; + + if (_ThumbBounds.Height > 20) + { + int n = r.Width / 6 + 1; + int m = r.Width / 10 + 1; + + r.Y += (r.Height / 2 - 1 - m); + r.X += n; + + r.Height = m * 2 + 3; + r.Width -= (n * 2); + + Point pt1 = new Point(r.Left, r.Y); + Point pt2 = new Point(r.Right, r.Y); + + using (Pen pen = new Pen(color)) + { + for (int i = 0; i < 3; i++) + { + g.DrawLine(pen, pt1, pt2); + + pt1.Y += (m + 1); + pt2.Y += (m + 1); + } + } + } + } + + #endregion + + #endregion + + #region RenderBorder + + private void RenderBorder(Graphics g, Rectangle bounds) + { + ScrollBarVisualStyle style = GetEffectiveStyle(); + + if (style.BorderColor.IsEmpty == false) + { + bool noAlpha = (style.NoAlphaOnMouseOver == Tbool.True) ? IsMouseOver : false; + + Color color = style.GetColor(style.BorderColor, noAlpha); + + using (Pen pen = new Pen(color)) + g.DrawRectangle(pen, bounds); + } + } + + #endregion + + #region GetAreaStyle + + private ScrollBarVisualStyle GetAreaStyle(ItemHitArea scrollBarArea) + { + StyleState state = StyleState.Default; + + if (_HitArea == scrollBarArea) + state |= StyleState.MouseOver; + + if (_MouseDownHitArea == scrollBarArea) + state |= StyleState.Selected; + + return (GetEffectiveStyle(state)); + } + + #endregion + + #endregion + + #region Mouse handling + + #region OnMouseEnter + + protected override bool OnMouseEnter(EventArgs e) + { + ChartCursor = Cursors.Default; + + InvalidateRender(); + + return (true); + } + + #endregion + + #region OnMouseLeave + + protected override bool OnMouseLeave(EventArgs e) + { + _HitArea = ItemHitArea.None; + + InvalidateRender(); + + return (true); + } + + #endregion + + #region OnMouseMove + + /// + /// InternalMouseMove + /// + /// + protected override bool OnMouseMove(MouseEventArgs e) + { + _HitArea = GetHitArea(e.Location); + + if (_HitArea != _LastHitArea) + { + _LastHitArea = _HitArea; + + InvalidateRender(); + } + + if (IsMouseDown == false) + _MouseDownHitArea = ItemHitArea.None; + + if (_MouseDownHitArea == ItemHitArea.Thumb) + ProcessThumbMove(e); + + ChartCursor = Cursors.Default; + + return (true); + } + + #region ProcessThumbMove + + private void ProcessThumbMove(MouseEventArgs e) + { + int track; + int tc; + int tv = Maximum - Minimum - _LargeChange; + + if (Orientation == Orientation.Horizontal) + { + track = e.Location.X - _ThumbOffset; + track -= _ArrowDecreaseBounds.Right; + + tc = Width - (_ArrowDecreaseBounds.Width + _ArrowIncreaseBounds.Width + _ThumbBounds.Width); + } + else + { + track = e.Location.Y - _ThumbOffset; + track -= _ArrowDecreaseBounds.Bottom; + + tc = Height - (_ArrowDecreaseBounds.Height + _ArrowIncreaseBounds.Height + _ThumbBounds.Height); + } + + if (tc > 0) + { + int value = (tv * track) / tc; + + if (Inverted == true) + value = tv - value; + + SetScrollValue(value, ScrollEventType.ThumbPosition); + } + } + + #endregion + + #endregion + + #region OnMouseDown + + protected override bool OnMouseDown(MouseEventArgs e) + { + _MouseDownHitArea = _HitArea; + + if (_HitArea != ItemHitArea.None) + { + ChartControl.CapturedItem = this; + + switch (_HitArea) + { + case ItemHitArea.Thumb: + if (Orientation == Orientation.Horizontal) + _ThumbOffset = MouseDownPoint.X - _ThumbBounds.X; + else + _ThumbOffset = MouseDownPoint.Y - _ThumbBounds.Y; + break; + + case ItemHitArea.TrackDecrease: + SetScrollValue(Value - _LargeChange, ScrollEventType.LargeDecrement); + break; + + case ItemHitArea.TrackIncrease: + SetScrollValue(Value + _LargeChange, ScrollEventType.LargeIncrement); + break; + + case ItemHitArea.ArrowDecrease: + SetScrollValue(Value - _SmallChange, ScrollEventType.SmallDecrement); + break; + + case ItemHitArea.ArrowIncrease: + SetScrollValue(Value + _SmallChange, ScrollEventType.SmallIncrement); + break; + } + + if (_HitArea != ItemHitArea.Thumb) + SetupClickTimer(); + } + + InvalidateRender(); + + return (true); + } + + #endregion + + #region OnMouseUp + + protected override bool OnMouseUp(MouseEventArgs e) + { + ChartControl.CapturedItem = null; + + if (_MouseDownHitArea != ItemHitArea.None) + { + if (_RaiseEndScroll == true) + { + OnScroll(ScrollEventType.EndScroll, Value, Value); + + _RaiseEndScroll = false; + } + } + + DisposeTimer(); + + _MouseDownHitArea = ItemHitArea.None; + + InvalidateRender(); + + return (true); + } + + #endregion + + #endregion + + #region NormalizeValue + + private int NormalizeValue(int value) + { + value = Math.Max(Minimum, value); + + if (value + _LargeChange > _Maximum) + value = _Maximum - _LargeChange; + + return (value); + } + + #endregion + + #region Timer support + + #region SetupClickTimer + + private void SetupClickTimer() + { + if (_ClickTimer == null) + { + _ClickCount = 0; + + _ClickTimer = new Timer(); + _ClickTimer.Interval = 100; + _ClickTimer.Tick += new EventHandler(ClickTimerTick); + + _ClickTimer.Enabled = true; + } + } + + #endregion + + #region DisposeTimer + + private void DisposeTimer() + { + Timer clickTimer = _ClickTimer; + + if (clickTimer != null) + { + _ClickTimer = null; + + clickTimer.Enabled = false; + clickTimer.Tick -= new EventHandler(ClickTimerTick); + + clickTimer.Dispose(); + } + } + + #endregion + + #region ClickTimerTick + + private void ClickTimerTick(object sender, EventArgs e) + { + if (IsMouseDown == true) + { + if (_MouseDownHitArea == ItemHitArea.TrackDecrease || _MouseDownHitArea == ItemHitArea.TrackIncrease) + { + Point pt = ChartControl.PointToClient(Control.MousePosition); + + if (_ThumbBounds.Contains(pt)) + { + DisposeTimer(); + } + else + { + if (_MouseDownHitArea == ItemHitArea.TrackDecrease) + SetScrollValue(Value - _LargeChange, ScrollEventType.LargeDecrement); + else + SetScrollValue(Value + _LargeChange, ScrollEventType.LargeIncrement); + } + } + else + { + if (_HitArea == ItemHitArea.ArrowDecrease) + SetScrollValue(Value - _SmallChange, ScrollEventType.SmallDecrement); + + else if (_HitArea == ItemHitArea.ArrowIncrease) + SetScrollValue(Value + _SmallChange, ScrollEventType.SmallIncrement); + + else + { + _ClickCount = 0; + _ClickTimer.Interval = 100; + } + } + + Timer clickTimer = _ClickTimer; + + if (clickTimer != null) + { + _ClickCount++; + + if (_ClickCount > 4 && clickTimer.Interval > 20) + clickTimer.Interval -= 10; + } + } + } + + #endregion + + #endregion + + #region SetScrollValue + + private void SetScrollValue(int value, ScrollEventType type) + { + value = NormalizeValue(value); + int oldValue = _Value; + + Value = value; + + OnScroll(type, _Value, oldValue); + + _RaiseEndScroll = true; + } + + #endregion + + #region OnScroll + + private void OnScroll(ScrollEventType type, int oldValue, int newValue) + { + ScrollEventArgs args = null; + + if (Scroll != null) + { + ScrollOrientation so = (Orientation == Orientation.Horizontal) + ? ScrollOrientation.HorizontalScroll : ScrollOrientation.VerticalScroll; + + args = new ScrollEventArgs(type, oldValue, newValue, so); + + Scroll(this, args); + } + + if (ChartControl.IsScrollHooked == true) + { + if (args == null) + { + ScrollOrientation so = (Orientation == Orientation.Horizontal) + ? ScrollOrientation.HorizontalScroll : ScrollOrientation.VerticalScroll; + + args = new ScrollEventArgs(type, oldValue, newValue, so); + } + + ChartControl.DoScrollEvent((ChartContainer)Parent, args, this); + } + } + + #endregion + + #region GetBarAreaAt + + public override ItemHitArea GetHitArea(Point pt) + { + if ((Bounds.Contains(pt) == false) || + (Visible == false || Enabled == false)) + { + return (ItemHitArea.None); + } + + if (_ArrowDecreaseBounds.Contains(pt)) + return (Inverted ? ItemHitArea.ArrowIncrease : ItemHitArea.ArrowDecrease); + + if (_ArrowIncreaseBounds.Contains(pt)) + return (Inverted ? ItemHitArea.ArrowDecrease : ItemHitArea.ArrowIncrease); + + if (_ThumbBounds.Contains(pt)) + return (ItemHitArea.Thumb); + + if (Orientation == Orientation.Horizontal) + { + if (pt.X < _ThumbBounds.Left) + { + if (Inverted == false) + return (ItemHitArea.TrackDecrease); + } + } + else + { + if (pt.Y < _ThumbBounds.Top) + { + if (Inverted == false) + return (ItemHitArea.TrackDecrease); + } + } + + return (ItemHitArea.TrackIncrease); + } + + #endregion + + #region Style handling + + #region GetEffectiveStyle + + /// + /// Gets the EffectiveStyle for the ScrollBar. The effective + /// style is a composite, cached style definition. + /// + /// + /// + public ScrollBarVisualStyle GetEffectiveStyle(StyleState state) + { + return (_EffectiveStyles[state]); + } + + /// + /// Gets the EffectiveStyle for the ScrollBar. The effective + /// style is a composite, cached style definition. + /// + /// + public ScrollBarVisualStyle GetEffectiveStyle() + { + StyleState state = GetStyleState(); + + return (_EffectiveStyles[state]); + } + + #region GetStyleState + + private StyleState GetStyleState() + { + StyleState state = StyleState.Default; + + Point pt = ChartControl.PointToClient(Control.MousePosition); + + if (Bounds.Contains(pt)) + state |= StyleState.MouseOver; + + if (_MouseDownHitArea != ItemHitArea.None) + state |= StyleState.Selected; + + return (state); + } + + #endregion + + #endregion + + #region ApplyStyles + + public override void ApplyStyles(BaseVisualStyle style, StyleType cs) + { + ScrollBarVisualStyle pstyle = style as ScrollBarVisualStyle; + + if (pstyle != null) + { + ApplyParentStyles(pstyle, cs, Parent as ChartContainer); + + pstyle.ApplyStyle(ScrollBarVisualStyles[cs]); + } + } + + #region ApplyParentStyles + + private void ApplyParentStyles( + ScrollBarVisualStyle pstyle, StyleType cs, ChartContainer item) + { + if (item != null) + { + ApplyParentStyles(pstyle, cs, item.Parent as ChartContainer); + + if (item is ChartXy) + { + if (Orientation == Orientation.Horizontal) + pstyle.ApplyStyle(((ChartXy)item).ChartVisualStyle.HScrollBarVisualStyles[cs]); + else + pstyle.ApplyStyle(((ChartXy)item).ChartVisualStyle.VScrollBarVisualStyles[cs]); + } + else if (item is ChartPanel) + { + if (Orientation == Orientation.Horizontal) + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.HScrollBarVisualStyles[cs]); + else + pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.VScrollBarVisualStyles[cs]); + } + } + else + { + if (Orientation == Orientation.Horizontal) + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.HScrollBarVisualStyles[cs]); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.HScrollBarVisualStyles[cs]); + } + else + { + pstyle.ApplyStyle(ChartControl.BaseVisualStyles.VScrollBarVisualStyles[cs]); + pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.VScrollBarVisualStyles[cs]); + } + } + } + + #endregion + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults(BaseVisualStyle style, StyleType cs) + { + ScrollBarVisualStyle pstyle = style as ScrollBarVisualStyle; + + if (pstyle != null) + pstyle.ApplyDefaults(); + + base.ApplyDefaults(style, cs); + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidate the cached Styles + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + #endregion + + #region ClearEffectiveStyles + + protected override void ClearEffectiveStyles() + { + _EffectiveStyles.InvalidateStyles(); + + base.ClearEffectiveStyles(); + } + + #endregion + + #endregion + + #region InvalidateLayoutBounds + + /// + /// Invalidates the layout bounds for the item container + /// + public override void InvalidateLayoutBounds(ScrollBarLite sbar) + { + ChartVisualElement parent = Parent as ChartVisualElement; + + if (parent is IScrollable) + { + IScrollable isc = (IScrollable)parent; + + isc.InvalidateLayoutBounds(sbar); + + Rectangle scrollBounds = GetScrollBounds(isc.ScrollBounds); + + parent.InvalidateRender(scrollBounds); + } + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartXy"; + + sec.AddStartElement(serialName); + } + + if (_ScrollBarVisualStyles != null && _ScrollBarVisualStyles.IsEmpty == false) + sec.AddElement(_ScrollBarVisualStyles.GetSerialData("ScrollBarVisualStyles")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ScrollBarVisualStyles": + sec.PutSerialData(ScrollBarVisualStyles); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + ScrollBarVisualStyles = null; + + base.Dispose(); + } + + #endregion + } + + #region EventArgs + + #region ValueChangedEventArgs + + /// + /// ValueChangedEventArgs + /// + public class ValueChangedEventArgs : EventArgs + { + #region Private variables + + private int _OldValue; + private int _NewValue; + + #endregion + + /// + /// ValueChangedEventArgs + /// + /// + /// + public ValueChangedEventArgs(int oldValue, int newValue) + { + _OldValue = oldValue; + _NewValue = newValue; + } + + #region Public properties + + /// + /// Gets the old scroll Value + /// + public int OldValue + { + get { return (_OldValue); } + } + + /// + /// Gets the new scroll Value + /// + public int NewValue + { + get { return (_NewValue); } + } + + #endregion + } + + #endregion + + #endregion + + #region Interfaces + + #region IScrollable + + internal interface IScrollable + { + Rectangle ScrollBounds { get; } + Rectangle ScrollBoundsEx { get; } + + Point ScrollBoundsOffset { get; } + + void InvalidateLayoutBounds(ScrollBarLite sbar); + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/AnnotationVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/AnnotationVisualStyle.cs new file mode 100644 index 00000000..a66da6a0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/AnnotationVisualStyle.cs @@ -0,0 +1,206 @@ +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// AnnotationVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class AnnotationVisualStyles : VisualStyles + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public AnnotationVisualStyles Copy() + { + AnnotationVisualStyles styles = new AnnotationVisualStyles(); + + for (int i = 0; i < Styles.Length; i++) + { + AnnotationVisualStyle vstyle = Styles[i]; + + if (vstyle != null) + styles.Styles[i] = vstyle.Copy(); + } + + return (styles); + } + + #endregion + } + + /// + /// Represents the visual style of a Legend element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class AnnotationVisualStyle : ContainerVisualStyle + { + #region Private variables + + private AnnotationShape _AnnotationShape = AnnotationShape.Ellipse; + private ConnectorShape _ConnectorShape = ConnectorShape.NotSet; + + private Alignment _TextAlignment = Alignment.NotSet; + + #endregion + + #region Public properties + + #region AnnotationShape + + /// + /// Gets or sets the shape of the annotation container. + /// + [DefaultValue(AnnotationShape.NotSet), Category("Appearance")] + [Description("Indicates the shape of the annotation container.")] + public AnnotationShape AnnotationShape + { + get { return (_AnnotationShape); } + + set + { + if (_AnnotationShape != value) + { + _AnnotationShape = value; + + OnPropertyChangedEx("AnnotationShape", VisualChangeType.Render); + } + } + } + + #endregion + + #region ConnectorShape + + /// + /// Gets or sets the shape of the annotation connector. + /// + [DefaultValue(ConnectorShape.NotSet), Category("Appearance")] + [Description("Indicates the shape of the annotation connector.")] + public ConnectorShape ConnectorShape + { + get { return (_ConnectorShape); } + + set + { + if (_ConnectorShape != value) + { + _ConnectorShape = value; + + OnPropertyChangedEx("ConnectorShape", VisualChangeType.Render); + } + } + } + + #endregion + + #region TextAlignment + + /// + /// Gets or sets the alignment of the content within the cell + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the content within the cell.")] + public Alignment TextAlignment + { + get { return (_TextAlignment); } + + set + { + if (_TextAlignment != value) + { + _TextAlignment = value; + + OnPropertyChangedEx("TextAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_AnnotationShape == AnnotationShape.NotSet) && + (_ConnectorShape == ConnectorShape.NotSet) && + (_TextAlignment == Alignment.NotSet) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(AnnotationVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.AnnotationShape != AnnotationShape.NotSet) + _AnnotationShape = style.AnnotationShape; + + if (style.ConnectorShape != ConnectorShape.NotSet) + _ConnectorShape = style.ConnectorShape; + + if (style.TextAlignment != Alignment.NotSet) + _TextAlignment = style.TextAlignment; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new AnnotationVisualStyle Copy() + { + AnnotationVisualStyle style = new AnnotationVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(AnnotationVisualStyle style) + { + base.CopyTo(style); + + style.AnnotationShape = _AnnotationShape; + style.ConnectorShape = _ConnectorShape; + style.TextAlignment = _TextAlignment; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/AxisStripeVisualStyle .cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/AxisStripeVisualStyle .cs new file mode 100644 index 00000000..13fb24b4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/AxisStripeVisualStyle .cs @@ -0,0 +1,213 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents a AxisStripeVisualStyle. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class AxisStripeVisualStyle : BaseVisualStyle + { + #region Private variables + + private Background _Background; + + #endregion + + #region Public properties + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Background == null || _Background.IsEmpty == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(AxisStripeVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new AxisStripeVisualStyle Copy() + { + AxisStripeVisualStyle style = new AxisStripeVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(AxisStripeVisualStyle style) + { + base.CopyTo(style); + + style.Background = (_Background != null) ? _Background.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "AxisStripeVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "Background": + sec.PutSerialData(Background); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BackColorBlend.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BackColorBlend.cs new file mode 100644 index 00000000..1925bb04 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BackColorBlend.cs @@ -0,0 +1,290 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// BackColorBlend + /// + [TypeConverter(typeof(BackColorBlendConvertor))] + public class BackColorBlend : INotifyPropertyChanged, IProcessSerialElement + { + #region Private variables + + private Color[] _Colors; // Color values + private float[] _Positions; // Gradient color positions + + #endregion + + #region Public properties + + #region Colors + + /// + /// Gets or sets the ColorBlend Color array + /// + [Browsable(true), DefaultValue(null)] + [Description("Indicates the ColorBlend Color array")] + [TypeConverter(typeof(ArrayConverter))] + public Color[] Colors + { + get { return (_Colors); } + + set + { + if (value != null && value.Length == 0) + value = null; + + _Colors = value; + + OnPropertyChangedEx("Colors"); + } + } + + #endregion + + #region Positions + + /// + /// Gets or sets the ColorBlend Color Positions + /// + [Browsable(true), DefaultValue(null)] + [Description("Indicates the ColorBlend Color Positions")] + [TypeConverter(typeof(ArrayConverter))] + public float[] Positions + { + get { return (_Positions); } + + set + { + if (value != null && value.Length == 0) + value = null; + + _Positions = value; + + OnPropertyChangedEx("Positions"); + } + } + + #endregion + + #region IsEmpty + + /// + /// IsEmpty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get { return (_Colors == null || _Colors.Length == 1 && _Colors[0].IsEmpty); } + } + + #endregion + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the BackColorBlend. + /// + /// Copy of the BackColorBlend. + public BackColorBlend Copy() + { + BackColorBlend copy = new BackColorBlend(); + + if (_Colors != null) + { + copy.Colors = new Color[_Colors.Length]; + + _Colors.CopyTo(copy.Colors, 0); + } + + if (_Positions != null) + { + copy.Positions = new float[_Positions.Length]; + + _Positions.CopyTo(copy.Positions, 0); + } + + return (copy); + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData() + { + SerialElementCollection sec = new SerialElementCollection(); + + sec.AddStartElement("BackColorBlend"); + + if (_Colors != null && _Colors.Length > 0) + { + sec.AddStartElement("Colors count=\"" + _Colors.Length + "\""); + + foreach (Color color in _Colors) + sec.AddValue("Color", color); + + sec.AddEndElement("Colors"); + } + + if (_Positions != null && _Positions.Length > 0) + { + sec.AddStartElement("Positions count=\"" + _Positions.Length + "\""); + + foreach (float pos in _Positions) + sec.AddDataValue("Position", pos); + + sec.AddEndElement("Positions"); + } + + sec.AddEndElement("BackColorBlend"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Color": + _Colors[se.ValueIndex] = se.ColorValue; + break; + + case "Position": + _Positions[se.ValueIndex] = (float)se.DataValue; + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + int count = se.ArrayCount; + + if (count > 0) + { + switch (se.Name) + { + case "Colors": + _Colors = new Color[count]; + break; + + case "Positions": + _Positions = new float[count]; + break; + + default: + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + + se.Sec.PutSerialData(this); + } + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChangedEx(string s) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + { + VisualPropertyChangedEventArgs e = + new VisualPropertyChangedEventArgs(s); + + eh(this, e); + } + } + + #endregion + } + + #region BackColorBlendConvertor + + /// + /// BackColorBlendConvertor + /// + public class BackColorBlendConvertor : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + BackColorBlend cb = value as BackColorBlend; + + if (cb != null) + { + ColorConverter cvt = new ColorConverter(); + + if (cb.Colors != null) + { + if (cb.Colors[0] != Color.Empty) + return (cvt.ConvertToString(cb.Colors[0])); + + if (cb.Colors.Length > 1 && cb.Colors[1] != Color.Empty) + return (cvt.ConvertToString(cb.Colors[1])); + } + } + + return (String.Empty); + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/Background.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/Background.cs new file mode 100644 index 00000000..6ed7a85f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/Background.cs @@ -0,0 +1,1399 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using DevComponents.DotNetBar.Charts.Primitives; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents background of visual style. + /// + [TypeConverter(typeof(BackgroundConvertor))] + [Editor(typeof(BackgroundEditor), typeof(UITypeEditor))] + public class Background : INotifyPropertyChanged, IDisposable, IProcessSerialElement + { + #region Static data + + /// + /// Empty + /// + /// + /// Returns Empty instance of Background. + /// + public static Background Empty + { + get { return (new Background()); } + } + + #endregion + + #region Private variables + + private Color _Color1 = Color.Empty; + private Color _Color2 = Color.Empty; + + private int _GradientAngle = 90; + private double _RadialCenter = 0.0d; + + private BackFillType _BackFillType = BackFillType.Angle; + private HatchFillType _HatchFillType = HatchFillType.NotSet; + + private BackColorBlend _BackColorBlend; + + #endregion + + #region Constructors + + /// + /// Creates new instance of the object. + /// + public Background() { } + + /// + /// Creates new instance of the object. + /// + /// Start color. + public Background(Color color1) + { + _Color1 = color1; + } + + /// + /// Creates new instance of the object. + /// + /// Start color. + /// End color. + public Background(Color color1, Color color2) + { + _Color1 = color1; + _Color2 = color2; + } + + /// + /// Creates new instance of the object. + /// + /// Start color in hexadecimal representation like FFFFFF. + /// End color in hexadecimal representation like FFFFFF. + public Background(string color1, string color2) + { + _Color1 = ColorFactory.GetColor(color1); + _Color2 = ColorFactory.GetColor(color2); + } + + /// + /// Creates new instance of the object. + /// + /// Start color in 32-bit RGB representation. + /// End color in 32-bit RGB representation. + public Background(int color1, int color2) + { + _Color1 = ColorFactory.GetColor(color1); + _Color2 = ColorFactory.GetColor(color2); + } + + /// + /// Creates new instance of the object. + /// + /// Start color in 32-bit RGB representation. + /// End color in 32-bit RGB representation. + /// Gradient angle. + public Background(int color1, int color2, int gradientAngle) + { + _Color1 = ColorFactory.GetColor(color1); + _Color2 = ColorFactory.GetColor(color2); + + GradientAngle = gradientAngle; + } + + /// + /// Creates new instance of the object. + /// + /// Start color. + /// End color. + /// Gradient angle. + public Background(Color color1, Color color2, int gradientAngle) + { + _Color1 = color1; + _Color2 = color2; + + GradientAngle = gradientAngle; + } + + /// + /// Creates new instance of the object. + /// + /// Start color. + /// End color. + /// Gradient angle. + public Background(Color color1, Color color2, BackFillType fillType) + { + _Color1 = color1; + _Color2 = color2; + + _BackFillType = fillType; + } + + #endregion + + #region Public properties + + #region BackColorBlend + + /// + /// Gets or sets the BackColorBlend. + /// + [Description("Indicates the BackColorBlend.")] + public BackColorBlend BackColorBlend + { + get + { + if (_BackColorBlend == null) + { + _BackColorBlend = new BackColorBlend(); + + UpdateChangeHandler(null, _BackColorBlend); + } + + return (_BackColorBlend); + } + + set + { + if (_BackColorBlend != value) + { + UpdateChangeHandler(_BackColorBlend, value); + + _BackColorBlend = value; + + OnPropertyChangedEx("BackColorBlend"); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeBackColorBlend() + { + return (_BackColorBlend != null && _BackColorBlend.IsEmpty == false); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetBackColorBlend() + { + BackColorBlend = null; + } + + #endregion + + #region BackFillType + + /// + /// Gets or sets the Gradient BackFillType + /// + [DefaultValue(BackFillType.Angle)] + [Description("Indicates the Gradient BackFillType.")] + public BackFillType BackFillType + { + get { return (_BackFillType); } + + set + { + if (_BackFillType != value) + { + _BackFillType = value; + + OnPropertyChangedEx("BackFillType"); + } + } + } + + #endregion + + #region Color1 + + /// + /// Gets or sets the start color. + /// + [Description("Indicates the Starting Gradient Color.")] + public Color Color1 + { + get { return (_Color1); } + + set + { + if (_Color1 != value) + { + _Color1 = value; + + OnPropertyChangedEx("Color1"); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeColor1() + { + return (_Color1.IsEmpty == false); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetColor1() + { + Color1 = Color.Empty; + } + + #endregion + + #region Color2 + + /// + /// Gets or sets the Ending Gradient Color + /// + [Description("Indicates the Ending Gradient Color")] + public Color Color2 + { + get { return (_Color2); } + + set + { + if (_Color2 != value) + { + _Color2 = value; + + OnPropertyChangedEx("Color2"); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeColor2() + { + return (_Color2.IsEmpty == false); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetColor2() + { + Color2 = Color.Empty; + } + + #endregion + + #region GradientAngle + + /// + /// Gets or sets the gradient angle (default is 90) + /// + [DefaultValue(90)] + [Description("Indicates the Gradient Angle default is 90)")] + public int GradientAngle + { + get { return (_GradientAngle); } + + set + { + if (_GradientAngle != value) + { + _GradientAngle = value; + + OnPropertyChangedEx("GradientAngle"); + } + } + } + + #endregion + + #region HatchFillType + + /// + /// Gets or sets the Gradient BackFillType + /// + [DefaultValue(HatchFillType.NotSet)] + [Description("Indicates the Hatch FillType.")] + public HatchFillType HatchFillType + { + get { return (_HatchFillType); } + + set + { + if (_HatchFillType != value) + { + _HatchFillType = value; + + OnPropertyChangedEx("HatchFillType"); + } + } + } + + #endregion + + #region RadialCenter + + /// + /// Gets or sets the Radial Gradient Center expressed as a percentage of the radius (from 0 to 1) + /// + [DefaultValue(0.0d)] + [Description("Indicates the Radial Gradient Center expressed as a percentage of the radius (om 0 to 1)")] + public double RadialCenter + { + get { return (_RadialCenter); } + + set + { + if (_RadialCenter != value) + { + if (value < 0 || value > 1) + throw new Exception("RadialCenter must be a value between 0 and 1"); + + _RadialCenter = value; + + OnPropertyChangedEx("RadialCenter"); + } + } + } + + #endregion + + #region IsSolidBrush + + /// + /// Gets whether the backcolor brush is a SolidBrush + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSolidBrush + { + get + { + if (_BackColorBlend != null && _BackColorBlend.IsEmpty == false) + { + if (_BackColorBlend.Colors.Length == 1) + return (true); + } + + if (_Color2.IsEmpty == true) + return (true); + + return (false); + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether Background is empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + return ((_BackColorBlend == null || _BackColorBlend.IsEmpty) && + (_BackFillType == BackFillType.Angle) && + (_Color1.IsEmpty == true) && + (_Color2.IsEmpty == true) && + (_GradientAngle == 90) && + (_HatchFillType == HatchFillType.NotSet) && + (_RadialCenter == .0)); + } + } + + #endregion + + #region IsEqualTo + + /// + /// Determines if the Background is equal to the given one + /// + /// Background to compare + /// true if equal + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEqualTo(Background background) + { + return (_Color1 == background.Color1 && + _Color2 == background.Color2 && + (_BackColorBlend == null || _BackColorBlend.Equals(background._BackColorBlend)) && + _GradientAngle == background.GradientAngle && + _RadialCenter == background.RadialCenter && + _BackFillType == background.BackFillType); + } + + #endregion + + #endregion + + #region Internal properties + + internal bool IsDisplayable + { + get + { + if (_BackFillType == BackFillType.None) + return (false); + + if ((_BackColorBlend == null || _BackColorBlend.IsEmpty) && + (_Color1.IsEmpty == true) && + (_Color2.IsEmpty == true)) + { + return (false); + } + + return (true); + } + } + + #endregion + + #region GetBrush + + /// + /// GetBrush + /// + /// + /// + public Brush GetBrush(Rectangle r) + { + if (_HatchFillType != HatchFillType.NotSet) + return (GetHatchBrush(r)); + + return (GetBrush(r, -1, _BackFillType)); + } + + public Brush GetBrush(Rectangle r, bool noAlpha) + { + return (GetBrush(r, noAlpha ? 255 : -1)); + } + + /// + /// Get the background brush + /// + /// Brush rectangle + /// 0-255 to override default + /// Brush + public Brush GetBrush(Rectangle r, int alpha) + { + return (GetBrush(r, alpha, _BackFillType)); + } + + /// + /// Get the background brush + /// + /// Brush rectangle + /// 0-255 to override default + /// BackFillType + /// Brush + public Brush GetBrush(Rectangle r, int alpha, BackFillType fillType) + { + if (_BackColorBlend != null && _BackColorBlend.IsEmpty == false) + { + if (_BackColorBlend.Colors.Length == 1) + return (new SolidBrush(GetColor(_BackColorBlend.Colors[0], alpha))); + + Brush br = GetLinearBrush(r, alpha, fillType); + + if (br is LinearGradientBrush) + { + ColorBlend cb = GetColorBlend(alpha); + + if (cb != null) + ((LinearGradientBrush)br).InterpolationColors = cb; + } + + return (br); + } + + if (_Color2.IsEmpty == true) + return (new SolidBrush(GetColor(_Color1, alpha))); + + return (GetLinearBrush(r, alpha, fillType)); + } + + private Brush GetHatchBrush(Rectangle r) + { + HatchBrush brush = new HatchBrush((HatchStyle)_HatchFillType, Color1, Color2); + + return (brush); + } + + #region GetLinearBrush + + private Brush GetLinearBrush( + Rectangle r, int alpha, BackFillType fillType) + { + LinearGradientBrush lbr = null; + + if (r.Width > 0 && r.Height > 0) + { + Color color1 = GetColor(_Color1, alpha); + Color color2 = GetColor(_Color2, alpha); + + switch (fillType) + { + case BackFillType.HorizontalCenter: + r.Width /= 2; + r.Width = Math.Max(1, r.Width); + + lbr = new LinearGradientBrush(r, color1, color2, 0f); + break; + + case BackFillType.VerticalCenter: + r.Height /= 2; + r.Height = Math.Max(1, r.Height); + + lbr = new LinearGradientBrush(r, color1, color2, 90f); + break; + + case BackFillType.ForwardDiagonal: + lbr = new LinearGradientBrush(r, color1, color2, LinearGradientMode.ForwardDiagonal); + break; + + case BackFillType.BackwardDiagonal: + lbr = new LinearGradientBrush(r, color1, color2, LinearGradientMode.BackwardDiagonal); + break; + + case BackFillType.ForwardDiagonalCenter: + r.Width /= 2; + r.Height /= 2; + lbr = new LinearGradientBrush(r, color1, color2, LinearGradientMode.ForwardDiagonal); + break; + + case BackFillType.BackwardDiagonalCenter: + r.Width /= 2; + r.Height /= 2; + r.X += r.Width; + + lbr = new LinearGradientBrush(r, color1, color2, LinearGradientMode.BackwardDiagonal); + break; + + case BackFillType.Center: + using (GraphicsPath path = new GraphicsPath()) + { + path.AddRectangle(r); + + PathGradientBrush pbr = new PathGradientBrush(path); + + pbr.CenterColor = color1; + pbr.SurroundColors = new Color[] { color2 }; + + ColorBlend cb = GetColorBlend(alpha); + + if (cb != null) + pbr.InterpolationColors = cb; + + return (pbr); + } + + case BackFillType.Radial: + int n = (int) Math.Sqrt(r.Width*r.Width + r.Height*r.Height) + 4; + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(r.X - (n - r.Width)/2, r.Y - (n - r.Height)/2, n, n); + + PathGradientBrush pbr = new PathGradientBrush(path); + + pbr.CenterColor = color1; + + if (_RadialCenter != .0) + pbr.CenterPoint = GetRadialCenterPoint(r, n); + + pbr.SurroundColors = new Color[] { color2 }; + + ColorBlend cb = GetColorBlend(alpha); + + if (cb != null) + pbr.InterpolationColors = cb; + + return (pbr); + } + + default: + lbr = new LinearGradientBrush(r, color1, color2, _GradientAngle); + break; + } + + if (lbr != null) + lbr.WrapMode = WrapMode.TileFlipXY; + } + + return (lbr); + } + + #region GetRadialCenterPoint + + private PointF GetRadialCenterPoint(Rectangle r, int n) + { + double w2 = (double)r.Width / 2; + double h2 = (double)r.Height / 2; + + double z = ((double)n / 2) * _RadialCenter; + double radians = MathHelper.ToRadians(_GradientAngle); + + double dx = z * Math.Cos(radians); + double dy = z * Math.Sin(radians); + + PointF pf = new PointF((float)(r.X + (w2 + dx)), (float)(r.Y + (h2 + dy))); + + return (pf); + } + + #endregion + + #endregion + + #region GetColorBlend + + private ColorBlend GetColorBlend(int alpha) + { + if (_BackColorBlend != null && + _BackColorBlend.Colors != null && _BackColorBlend.Colors.Length > 0) + { + ColorBlend cb = new ColorBlend(_BackColorBlend.Colors.Length); + + Color[] colors = _BackColorBlend.Colors; + + if ((uint) alpha < 256) + { + for (int i = 0; i < colors.Length; i++) + colors[i] = GetColor(colors[i], alpha); + } + + cb.Colors = colors; + cb.Positions = GetPositions(); + + return (cb); + } + + return (null); + } + + #endregion + + #region GetPositions + + private float[] GetPositions() + { + float[] cp = _BackColorBlend.Positions; + + if (cp == null || cp.Length != _BackColorBlend.Colors.Length) + { + cp = new float[_BackColorBlend.Colors.Length]; + + float f = 1f / _BackColorBlend.Colors.Length; + + for (int i = 0; i < cp.Length; i++) + cp[i] = i * f; + + cp[_BackColorBlend.Colors.Length - 1] = 1; + } + + return (cp); + } + + #endregion + + #region GetColor + + private Color GetColor(Color color, int alpha) + { + if ((uint)alpha > 255) + return (color); + + return (Color.FromArgb(alpha, color)); + } + + #endregion + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the background. + /// + /// Copy of the background. + public Background Copy() + { + Background style = new Background(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(Background style) + { + style.Color1 = _Color1; + style.Color2 = _Color2; + + style.RadialCenter = _RadialCenter; + style.GradientAngle = _GradientAngle; + style.BackFillType = _BackFillType; + style.HatchFillType = _HatchFillType; + + style.BackColorBlend = (_BackColorBlend != null) ? _BackColorBlend.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "Background"; + + sec.AddStartElement(serialName); + } + + if (_BackColorBlend != null && _BackColorBlend.IsEmpty == false) + sec.AddElement(BackColorBlend.GetSerialData()); + + sec.AddValue("BackFillType", BackFillType, BackFillType.Angle); + + sec.AddValue("Color1", Color1, Color.Empty); + sec.AddValue("Color2", Color2, Color.Empty); + + sec.AddValue("GradientAngle", GradientAngle, 90); + sec.AddValue("HatchFillType", HatchFillType, HatchFillType.NotSet); + sec.AddValue("RadialCenter", RadialCenter, 0.0d); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "BackFillType": + BackFillType = (BackFillType)se.GetValueEnum(typeof(BackFillType)); + break; + + case "Color1": + Color1 = se.GetValueColor(); + break; + + case "Color2": + Color2 = se.GetValueColor();; + break; + + case "GradientAngle": + GradientAngle = int.Parse(se.StringValue); + break; + + case "HatchFillType": + HatchFillType = (HatchFillType)se.GetValueEnum(typeof(HatchFillType)); + break; + + case "RadialCenter": + RadialCenter = double.Parse(se.StringValue); + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + switch (se.Name) + { + case "BackColorBlend": + se.Sec.PutSerialData(BackColorBlend); + break; + + default: + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(VisualPropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChangedEx(string s) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + { + VisualPropertyChangedEventArgs e = + new VisualPropertyChangedEventArgs(s); + + eh(this, e); + } + } + + #endregion + + #region UpdateChangeHandler + + private void UpdateChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// StyleChanged + /// + /// + /// + protected virtual void StyleChanged( + object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged((VisualPropertyChangedEventArgs)e); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + BackColorBlend = null; + } + + #endregion + } + + #region enums + + #region BackFillType + + /// + /// BackFillType + /// + public enum BackFillType + { + /// + /// No fill + /// + None, + + /// + /// Auto + /// + Auto, + + /// + /// Angle + /// + Angle, + + /// + /// Center + /// + Center, + + /// + /// HorizontalCenter + /// + HorizontalCenter, + + /// + /// VerticalCenter + /// + VerticalCenter, + + /// + /// ForwardDiagonal + /// + ForwardDiagonal, + + /// + /// BackwardDiagonal + /// + BackwardDiagonal, + + /// + /// ForwardDiagonalCenter + /// + ForwardDiagonalCenter, + + /// + /// BackwardDiagonalCenter + /// + BackwardDiagonalCenter, + + /// + /// Radial + /// + Radial, + } + + #endregion + + #region HatchFillType + + public enum HatchFillType + { + NotSet = -1, + + /// + /// A pattern of horizontal lines. + /// + Horizontal = HatchStyle.Horizontal, + + /// + /// A pattern of vertical lines. + /// + Vertical = HatchStyle.Vertical, + + /// + /// A pattern of lines on a diagonal from upper left to lower right.. + /// + ForwardDiagonal = HatchStyle.ForwardDiagonal, + + /// + /// A pattern of lines on a diagonal from upper right to lower left. + /// + BackwardDiagonal = HatchStyle.BackwardDiagonal, + + /// + /// Specifies horizontal and vertical lines that cross. + /// + Cross = HatchStyle.Cross, + + /// + /// A pattern of crisscross diagonal lines. + /// + DiagonalCross = HatchStyle.DiagonalCross, + + /// + /// Specifies a 5-percent hatch. The ratio of foreground color to background + /// color is 5:100. + /// + Percent05 = HatchStyle.Percent05, + + /// + /// Specifies a 10-percent hatch. The ratio of foreground color to background + /// color is 10:100. + /// + Percent10 = HatchStyle.Percent10, + + /// + /// Specifies a 20-percent hatch. The ratio of foreground color to background + /// color is 20:100. + /// + Percent20 = HatchStyle.Percent20, + + /// + /// Specifies a 25-percent hatch. The ratio of foreground color to background + /// color is 25:100. + /// + Percent25 = HatchStyle.Percent25, + + /// + /// Specifies a 30-percent hatch. The ratio of foreground color to background + /// color is 30:100. + /// + Percent30 = HatchStyle.Percent30, + + /// + /// Specifies a 40-percent hatch. The ratio of foreground color to background + /// color is 40:100. + /// / + Percent40 = HatchStyle.Percent40, + + /// + /// Specifies a 50-percent hatch. The ratio of foreground color to background + /// color is 50:100. + /// + Percent50 = HatchStyle.Percent50, + + /// + /// Specifies a 60-percent hatch. The ratio of foreground color to background + /// color is 60:100. + /// + Percent60 = HatchStyle.Percent60, + + /// + /// Specifies a 70-percent hatch. The ratio of foreground color to background + /// color is 70:100. + /// / + Percent70 = HatchStyle.Percent70, + + /// + /// Specifies a 75-percent hatch. The ratio of foreground color to background + /// color is 75:100. + /// + Percent75 = HatchStyle.Percent75, + + /// + /// Specifies a 80-percent hatch. The ratio of foreground color to background + /// color is 80:100. + /// + Percent80 = HatchStyle.Percent80, + + /// + /// Specifies a 90-percent hatch. The ratio of foreground color to background + /// color is 90:100. + /// + Percent90 = HatchStyle.Percent90, + + /// + /// Specifies diagonal lines that slant to the right from top points to bottom + /// points and are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.ForwardDiagonal, + /// but are not antialiased. + /// + LightDownwardDiagonal = HatchStyle.LightDownwardDiagonal, + + /// + /// Specifies diagonal lines that slant to the left from top points to bottom + /// points and are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.BackwardDiagonal, + /// but they are not antialiased. + /// + LightUpwardDiagonal = HatchStyle.LightUpwardDiagonal, + + /// + /// Specifies diagonal lines that slant to the right from top points to bottom + /// points, are spaced 50 percent closer together than, and are twice the width + /// of System.Drawing.Drawing2D.HatchStyle.ForwardDiagonal. This hatch pattern + /// is not antialiased. + /// + DarkDownwardDiagonal = HatchStyle.DarkDownwardDiagonal, + + /// + /// Specifies diagonal lines that slant to the left from top points to bottom + /// points, are spaced 50 percent closer together than System.Drawing.Drawing2D.HatchStyle.BackwardDiagonal, + /// and are twice its width, but the lines are not antialiased. + /// + DarkUpwardDiagonal = HatchStyle.DarkUpwardDiagonal, + + /// + /// Specifies diagonal lines that slant to the right from top points to bottom + /// points, have the same spacing as hatch style System.Drawing.Drawing2D.HatchStyle.ForwardDiagonal, + /// and are triple its width, but are not antialiased. + /// + WideDownwardDiagonal = HatchStyle.WideDownwardDiagonal, + + /// + /// Specifies diagonal lines that slant to the left from top points to bottom + /// points, have the same spacing as hatch style System.Drawing.Drawing2D.HatchStyle.BackwardDiagonal, + /// and are triple its width, but are not antialiased. + /// + WideUpwardDiagonal = HatchStyle.WideUpwardDiagonal, + + /// + /// Specifies vertical lines that are spaced 50 percent closer together than + /// System.Drawing.Drawing2D.HatchStyle.Vertical. + /// + LightVertical = HatchStyle.LightVertical, + + /// + /// Specifies horizontal lines that are spaced 50 percent closer together than + /// System.Drawing.Drawing2D.HatchStyle.Horizontal. + /// + LightHorizontal = HatchStyle.LightHorizontal, + + /// + /// Specifies vertical lines that are spaced 75 percent closer together than + /// hatch style System.Drawing.Drawing2D.HatchStyle.Vertical (or 25 percent closer + /// together than System.Drawing.Drawing2D.HatchStyle.LightVertical). + /// + NarrowVertical = HatchStyle.NarrowVertical, + + /// + /// Specifies horizontal lines that are spaced 75 percent closer together than + /// hatch style System.Drawing.Drawing2D.HatchStyle.Horizontal (or 25 percent + /// closer together than System.Drawing.Drawing2D.HatchStyle.LightHorizontal). + /// + NarrowHorizontal = HatchStyle.NarrowHorizontal, + + /// + /// Specifies vertical lines that are spaced 50 percent closer together than + /// System.Drawing.Drawing2D.HatchStyle.Vertical and are twice its width. + /// + DarkVertical = HatchStyle.DarkVertical, + + /// + /// Specifies horizontal lines that are spaced 50 percent closer together than + /// System.Drawing.Drawing2D.HatchStyle.Horizontal and are twice the width of + /// System.Drawing.Drawing2D.HatchStyle.Horizontal. + /// + DarkHorizontal = HatchStyle.DarkHorizontal, + + /// + /// Specifies dashed diagonal lines, that slant to the right from top points + /// to bottom points. + /// + DashedDownwardDiagonal = HatchStyle.DashedDownwardDiagonal, + + /// + /// Specifies dashed diagonal lines, that slant to the left from top points to + /// bottom points. + /// + DashedUpwardDiagonal = HatchStyle.DashedUpwardDiagonal, + + /// + /// Specifies dashed horizontal lines. + /// + DashedHorizontal = HatchStyle.DashedHorizontal, + + /// + /// Specifies dashed vertical lines. + /// + DashedVertical = HatchStyle.DashedVertical, + + /// + /// Specifies a hatch that has the appearance of confetti. + /// + SmallConfetti = HatchStyle.SmallConfetti, + + /// + /// Specifies a hatch that has the appearance of confetti, and is composed of + /// larger pieces than System.Drawing.Drawing2D.HatchStyle.SmallConfetti. + /// + LargeConfetti = HatchStyle.LargeConfetti, + + /// + /// Specifies horizontal lines that are composed of zigzags. + /// + ZigZag = HatchStyle.ZigZag, + + /// + /// Specifies horizontal lines that are composed of tildes. + /// + Wave = HatchStyle.Wave, + + /// + /// Specifies a hatch that has the appearance of layered bricks that slant to + /// the left from top points to bottom points. + /// + DiagonalBrick = HatchStyle.DiagonalBrick, + + /// + /// Specifies a hatch that has the appearance of horizontally layered bricks. + /// + HorizontalBrick = HatchStyle.HorizontalBrick, + + /// + /// Specifies a hatch that has the appearance of a woven material. + /// + Weave = HatchStyle.Weave, + + /// + /// Specifies a hatch that has the appearance of a plaid material. + /// + Plaid = HatchStyle.Plaid, + + /// + /// Specifies a hatch that has the appearance of divots. + /// + Divot = HatchStyle.Divot, + + /// + /// Specifies horizontal and vertical lines, each of which is composed of dots, + /// that cross. + /// + DottedGrid = HatchStyle.DottedGrid, + + /// + /// Specifies forward diagonal and backward diagonal lines, each of which is + /// composed of dots, that cross. + /// + DottedDiamond = HatchStyle.DottedDiamond, + + /// + /// Specifies a hatch that has the appearance of diagonally layered shingles + /// that slant to the right from top points to bottom points. + /// + Shingle = HatchStyle.Shingle, + + /// + /// Specifies a hatch that has the appearance of a trellis. + /// + Trellis = HatchStyle.Trellis, + + /// + /// Specifies a hatch that has the appearance of spheres laid adjacent to one + /// another. + /// + Sphere = HatchStyle.Sphere, + + /// + /// Specifies horizontal and vertical lines that cross and are spaced 50 percent + /// closer together than hatch style System.Drawing.Drawing2D.HatchStyle.Cross. + /// + SmallGrid = HatchStyle.SmallGrid, + + /// + /// Specifies a hatch that has the appearance of a checkerboard. + /// + SmallCheckerBoard = HatchStyle.SmallCheckerBoard, + + /// + /// Specifies a hatch that has the appearance of a checkerboard with squares + /// that are twice the size of System.Drawing.Drawing2D.HatchStyle.SmallCheckerBoard. + /// + LargeCheckerBoard = HatchStyle.LargeCheckerBoard, + + /// + /// Specifies forward diagonal and backward diagonal lines that cross but are + /// not antialiased. + /// + OutlinedDiamond = HatchStyle.OutlinedDiamond, + + /// + /// Specifies a hatch that has the appearance of a checkerboard placed diagonally. + /// + SolidDiamond = HatchStyle.SolidDiamond, + } + + #endregion + + #endregion + + #region BackgroundConvertor + + /// + /// BackgroundConvertor + /// + public class BackgroundConvertor : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + Background gc = value as Background; + + if (gc != null) + { + if (gc.BackColorBlend != null && gc.BackColorBlend.IsEmpty == false) + return ("Blended"); + + ColorConverter cvt = new ColorConverter(); + + string s = gc.Color1.IsEmpty ? " " : cvt.ConvertToString(gc.Color1); + + if (gc.Color2 != Color.Empty) + s += ", " + cvt.ConvertToString(gc.Color2); + + return (s); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + + #region BackgroundEditor + + /// + /// BackgroundEditor + /// + public class BackgroundEditor : UITypeEditor + { + #region GetPaintValueSupported + + /// + /// GetPaintValueSupported + /// + /// + /// + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region PaintValue + + /// + /// PaintValue + /// + /// + public override void PaintValue(PaintValueEventArgs e) + { + Background b = e.Value as Background; + + if (b != null) + { + using (Brush br = b.GetBrush(e.Bounds)) + e.Graphics.FillRectangle(br, e.Bounds); + } + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BaseVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BaseVisualStyle.cs new file mode 100644 index 00000000..4d7af36f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BaseVisualStyle.cs @@ -0,0 +1,622 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the base visual style. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + public class BaseVisualStyle : INotifyPropertyChanged, IDisposable, IProcessSerialElement + { + #region Static data + + static private List _StyleList; + private static StyleUpdateMode _StyleUpdateMode = StyleUpdateMode.Full; + + #endregion + + #region Private variables + + private StyleType _StyleType; + private BaseVisualStyle _Parent; + + private ushort _StyleUpdateCount; + + private string _Class = ""; + private object _Tag; + + #endregion + + #region Public properties + + #region Class + + /// + /// Gets or sets the class style belongs to. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Class + { + get { return (_Class); } + + set + { + if (_Class != value) + { + _Class = value; + + OnPropertyChangedEx("Class", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public virtual bool IsEmpty + { + get { return (_Tag == null); } + } + + #endregion + + #region Tag + + /// + /// Gets or sets the user defined reference Tag. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("User defined reference Tag.")] + public object Tag + { + get { return (_Tag); } + set { _Tag = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region StyleType + + internal StyleType StyleType + { + get { return (_StyleType); } + set { _StyleType = value; } + } + + #endregion + + #region StyleUpdateCount + + internal ushort StyleUpdateCount + { + get { return (_StyleUpdateCount); } + set { _StyleUpdateCount = value; } + } + + #endregion + + #region StyleUpdateMode + + internal StyleUpdateMode StyleUpdateMode + { + get { return (_StyleUpdateMode); } + set { _StyleUpdateMode = value; } + } + + #endregion + + #region Parent + + internal BaseVisualStyle Parent + { + get { return (_Parent); } + set { _Parent = value; } + } + + #endregion + + #region StyleList + + internal List StyleList + { + get { return (_StyleList); } + set { _StyleList = value; } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(BaseVisualStyle style) + { + if (StyleList != null) + StyleList.Add(style ?? this); + } + + #endregion + + #region GetApplyStyleTypes + + internal StyleType[] GetApplyStyleTypes(StyleType e) + { + StyleType[] css = null; + + switch (e) + { + case StyleType.Default: + css = new StyleType[] { StyleType.Default}; + break; + + case StyleType.MouseOver: + css = new StyleType[] { StyleType.Default, e }; + break; + + case StyleType.Selected: + css = new StyleType[] { StyleType.Default, e }; + break; + + case StyleType.SelectedMouseOver: + css = new StyleType[] { StyleType.Default, StyleType.Selected, e }; + break; + } + + return (css); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public BaseVisualStyle Copy() + { + BaseVisualStyle style = new BaseVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(BaseVisualStyle copy) + { + copy.Class = _Class; + copy.Tag = _Tag; + } + + #endregion + + #region GetSerialData + + internal virtual SerialElementCollection GetSerialData(string serialName) + { + if ((String.IsNullOrEmpty(Class) == false) || (Tag != null)) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "BaseVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("Class", Class, ""); + sec.AddValue("Tag", Tag, null); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + return (null); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + ProcessValue(se); + } + + internal virtual void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Name": + Class = se.StringValue; + break; + + case "Tag": + Tag = se.DataValue; + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + ProcessCollection(se); + } + + internal virtual void ProcessCollection(SerialElement se) + { + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + + #endregion + + #endregion + + #region ApplyDefaults + + public virtual void ApplyDefaults() + { + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if ((StyleUpdateMode & StyleUpdateMode.UpdateCount) == StyleUpdateMode.UpdateCount) + StyleUpdateCount++; + + if ((StyleUpdateMode & StyleUpdateMode.Notify) == StyleUpdateMode.Notify) + { + if (PropertyChanged != null) + PropertyChanged(this, e); + } + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if ((StyleUpdateMode & StyleUpdateMode.UpdateCount) == StyleUpdateMode.UpdateCount) + StyleUpdateCount++; + + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s)); + } + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + if ((StyleUpdateMode & StyleUpdateMode.UpdateCount) == StyleUpdateMode.UpdateCount) + StyleUpdateCount++; + + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType)); + } + + #endregion + + #region UpdateChangeHandler + + /// + /// UpdateChangeHandler + /// + /// + /// + protected void UpdateChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= ValuePropertyChanged; + + if (newValue != null) + newValue.PropertyChanged += ValuePropertyChanged; + } + + void ValuePropertyChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #region OnStyleChanged + + protected void OnStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + UpdateChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public virtual void Dispose() + { + } + + #endregion + } + + #region enums + + #region StyleState + + /// + /// StyleState + /// + [Flags] + public enum StyleState + { + /// + /// Default + /// + Default = 0, + + /// + /// MouseOver + /// + MouseOver = (1 << 0), + + /// + /// Selected + /// + Selected = (1 << 1), + } + + #endregion + + #region StyleType + + /// + /// StyleType + /// + public enum StyleType + { + /// + /// CellStyle is Not Set + /// + NotSet = -1, + + /// + /// Default + /// + Default = 0, + + /// + /// MouseOver + /// + MouseOver, + + /// + /// Selected + /// + Selected, + + /// + /// SelectedMouseOver + /// + SelectedMouseOver, + } + + #endregion + + #region StyleUpdateMode + + [Flags] + internal enum StyleUpdateMode + { + None = 0, + + Notify = (1 << 0), + UpdateCount = (1 << 1), + + Full = (UpdateCount | Notify), + } + + #endregion + + #region Tbool + + /// + /// TBool - Three state boolean + /// + public enum Tbool + { + /// + /// NotSet + /// + NotSet, + + /// + /// True + /// + True, + + /// + /// False + /// + False + } + + #endregion + + #region VisualChangeType + + /// + /// Defines visual property change type. + /// + public enum VisualChangeType + { + /// + /// Visual style has changed so Recalc is needed + /// + Recalc, + + /// + /// Visual style has changed so layout is impacted, but not recalc + /// + Layout, + + /// + /// Visual style has changed so visuals are impacted, but not layout + /// + Render + } + + #endregion + + #endregion + + #region VisualPropertyChangedEventArgs + + /// + /// Represents visual property changed event arguments. + /// + public class VisualPropertyChangedEventArgs : PropertyChangedEventArgs + { + #region Public data + + /// + /// Gets the change type. + /// + public readonly VisualChangeType ChangeType; + + #endregion + + /// + /// Initializes a new instance of the VisualPropertyChangedEventArgs class. + /// + public VisualPropertyChangedEventArgs(string propertyName) + : base(propertyName) + { + ChangeType = VisualChangeType.Layout; + } + + /// + /// Initializes a new instance of the VisualPropertyChangedEventArgs class. + /// + public VisualPropertyChangedEventArgs(string propertyName, VisualChangeType changeType) + : base(propertyName) + { + ChangeType = changeType; + } + } + + #endregion + + #region VisualStylesConverter + + /// + /// VisualStylesConverter + /// + public class VisualStylesConverter : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + return (" "); + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + + #region DefaultStyleConvertor + + public class DefaultStyleConvertor : ExpandableObjectConverter + { + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + BaseVisualStyle bvs = value as BaseVisualStyle; + + if (bvs != null) + { + ColorConverter cvt = new ColorConverter(); + + return ((bvs.IsEmpty == true) ? " " : "(Set)"); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BorderColor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BorderColor.cs new file mode 100644 index 00000000..fe4d7618 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BorderColor.cs @@ -0,0 +1,670 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Globalization; +using System.Drawing.Design; +using System.Collections; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents style border color. + /// + [TypeConverter(typeof(BorderColorConverter))] + public class BorderColor : IProcessSerialElement, INotifyPropertyChanged + { + #region Static data + + /// + /// Empty + /// + /// + /// Returns Empty instance of BorderColor. + /// + public static BorderColor Empty + { + get { return (new BorderColor()); } + } + + #endregion + + #region Private variables + + private Color _Top = Color.Empty; + private Color _Left = Color.Empty; + private Color _Bottom = Color.Empty; + private Color _Right = Color.Empty; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the BorderColor object. + /// + /// + /// + /// + /// + public BorderColor(Color left, Color top, Color right, Color bottom) + { + _Top = top; + _Bottom = bottom; + _Left = left; + _Right = right; + } + + /// + /// Initializes a new instance of the BorderColor object. + /// + public BorderColor(Color all) + : this(all, all, all, all) + { + } + + /// + /// Initializes a new instance of the BorderColor object. + /// + public BorderColor() + { + } + + #endregion + + #region Public properties + + #region All + + /// + /// Gets or sets the color of all borders. + /// + //[Browsable(false)] + //[EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color All + { + set { _Top = _Left = _Bottom = _Right = value; } + } + + #endregion + + #region Bottom + + /// + /// Gets or sets the color of the bottom border + /// + [Category("Appearance")] + [Description("Indicates the color of the bottom border")] + public Color Bottom + { + get { return (_Bottom); } + + set + { + if (_Bottom != value) + { + _Bottom = value; + + OnVisualPropertyChanged("Bottom"); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBottom() + { + return (_Bottom.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBottom() + { + Bottom = Color.Empty; + } + + #endregion + + #region Left + + /// + /// Gets or sets the color of the left border + /// + [Category("Appearance")] + [Description("Indicates the color of the left border")] + public Color Left + { + get { return (_Left); } + + set + { + if (_Left != value) + { + _Left = value; + + OnVisualPropertyChanged("Left"); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLeft() + { + return (_Left.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetLeft() + { + Left = Color.Empty; + } + + #endregion + + #region Right + + /// + /// Gets or sets the color of the right border + /// + [Category("Appearance")] + [Description("Indicates the color of the right border")] + public Color Right + { + get { return (_Right); } + + set + { + if (_Right != value) + { + _Right = value; + + OnVisualPropertyChanged("Right"); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeRight() + { + return (_Right.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetRight() + { + Right = Color.Empty; + } + + #endregion + + #region Top + + /// + /// Gets or sets the color of the top border + /// + [Category("Appearance")] + [Description("Indicates the color of the top border")] + public Color Top + { + get { return (_Top); } + + set + { + if (_Top != value) + { + _Top = value; + + OnVisualPropertyChanged("Top"); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTop() + { + return (_Top.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTop() + { + Top = Color.Empty; + } + + #endregion + + #endregion + + #region Internal properties + + #region IsEmpty + + internal bool IsEmpty + { + get + { + return (_Left.IsEmpty && _Top.IsEmpty && + _Right.IsEmpty && _Bottom.IsEmpty); + } + } + + #endregion + + #region IsUniform + + internal bool IsUniform + { + get + { + return (_Left == _Top && + _Left == _Right && _Left == _Bottom); + } + } + + #endregion + + #endregion + + #region Operators + + #region '==' operator + + /// + /// Compares two instances. + /// + /// Instance 1 + /// Instance 2 + /// true if same + public static bool operator ==(BorderColor t1, BorderColor t2) + { + // If both are null, or both are same instance, return true. + + if (ReferenceEquals(t1, t2)) + return (true); + + // If one is null, but not both, return false. + + if (((object)t1 == null) || ((object)t2 == null)) + return (false); + + return (t1._Left == t2._Left && t1._Right == t2._Right && + t1._Top == t2._Top && t1._Bottom == t2._Bottom); + } + + #endregion + + #region "!=" operator + + /// + /// Compares two instances. + /// + /// Instance 1 + /// Instance 2 + /// true if different. + public static bool operator !=(BorderColor t1, BorderColor t2) + { + return ((t1 == t2) == false); + } + + #endregion + + #endregion + + #region GetHashCode + + /// + /// Returns hash-code for object. + /// + /// Hash-code value. + public override int GetHashCode() + { + return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^ + _Right.GetHashCode()) ^ _Bottom.GetHashCode()); + } + + #endregion + + #region Equals + + /// + /// Compares object to this instance. + /// + /// Object to compare. + /// true if same. + public override bool Equals(object obj) + { + if (obj is BorderColor) + return ((BorderColor) obj == this); + + return (false); + } + + /// + /// Compares object to this instance. + /// + /// Border color + /// true if same + public bool Equals(BorderColor borderColor) + { + return (this == borderColor); + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the BorderColor. + /// + /// Copy of the BorderColor. + public BorderColor Copy() + { + BorderColor copy = new BorderColor(_Left, _Top, _Right, _Bottom); + + return (copy); + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "BorderColor"; + + sec.AddStartElement(serialName); + } + + if (IsUniform == true) + { + sec.AddValue("All", Left, Color.Empty); + } + else + { + sec.AddValue("Left", Left, Color.Empty); + sec.AddValue("Top", Top, Color.Empty); + sec.AddValue("Right", Right, Color.Empty); + sec.AddValue("Bottom", Bottom, Color.Empty); + } + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "All": + All = (Color)se.ColorValue; + break; + + case "Left": + Left = (Color)se.ColorValue; + break; + + case "Top": + Top = (Color)se.ColorValue; + break; + + case "Right": + Right = (Color)se.ColorValue; + break; + + case "Bottom": + Bottom = (Color)se.ColorValue; + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnVisualPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s)); + } + + #endregion + } + + #region BorderColorConverter + + /// + /// BorderColorConverter + /// + public class BorderColorConverter : ExpandableObjectConverter + { + #region CanConvertTo + + /// + /// CanConvertTo + /// + /// + /// + /// + public override bool CanConvertTo( + ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + return (true); + + return (base.CanConvertTo(context, destinationType)); + } + + #endregion + + #region ConvertTo + + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + BorderColor bc = value as BorderColor; + + if (bc != null) + { + if (bc.IsUniform == true) + return (bc.Left.ToString()); + + return (String.Format("{0}, {1}, {2}, {3}", + bc.Bottom, bc.Left, bc.Right, bc.Top)); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + + #endregion + + #region CanConvertFrom + + /// + /// CanConvertFrom + /// + /// + /// + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + return (true); + + return (base.CanConvertFrom(context, sourceType)); + } + + #endregion + + #region ConvertFrom + + /// + /// ConvertFrom + /// + /// + /// + /// + /// + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + string[] values = ((string)value).Split(','); + + if (values.Length != 1 && values.Length != 4) + throw new ArgumentException("Invalid value to convert."); + + ColorConverter cvt = new ColorConverter(); + + try + { + Color[] c = new Color[values.Length]; + + for (int i = 0; i < values.Length; i++) + c[i] = (Color)cvt.ConvertFrom(values[i]); + + BorderColor bc = (values.Length == 1) + ? new BorderColor(c[0]) + : new BorderColor(c[1], c[3], c[2], c[0]); + + return (bc); + } + catch (Exception) + { + throw new ArgumentException("Invalid value to convert."); + } + } + + return base.ConvertFrom(context, culture, value); + } + + #endregion + + #region GetCreateInstanceSupported + + /// + /// GetCreateInstanceSupported + /// + /// + /// + public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region CreateInstance + + /// + /// CreateInstance + /// + /// + /// + /// + public override object CreateInstance( + ITypeDescriptorContext context, IDictionary propertyValues) + { + return (new BorderColor((Color)propertyValues["Left"], (Color)propertyValues["Top"], + (Color)propertyValues["Right"], (Color)propertyValues["Bottom"])); + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BorderPattern.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BorderPattern.cs new file mode 100644 index 00000000..f26cfbb5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/BorderPattern.cs @@ -0,0 +1,524 @@ +using System; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using DevComponents.DotNetBar.Charts.Primitives; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Defines Thickness class. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class BorderPattern : IEquatable, IProcessSerialElement, INotifyPropertyChanged + { + #region Static data + + /// + /// Returns Empty instance of BorderPattern. + /// + public static BorderPattern Empty + { + get { return (new BorderPattern()); } + } + + #endregion + + #region Private variables + + private LinePattern _Bottom = LinePattern.NotSet; + private LinePattern _Left = LinePattern.NotSet; + private LinePattern _Right = LinePattern.NotSet; + private LinePattern _Top = LinePattern.NotSet; + + #endregion + + #region Constructors + + /// + /// Creates new instance of the object. + /// + /// Left BorderPatternStyle. + /// Top BorderPatternStyle. + /// Right BorderPatternStyle. + /// Bottom BorderPatternStyle. + public BorderPattern(LinePattern left, + LinePattern top, LinePattern right, LinePattern bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + + PropertyChanged = null; + } + + /// + /// Creates new instance of the object. + /// + /// Specifies uniform Thickness. + public BorderPattern(LinePattern all) + : this(all, all, all, all) + { + } + + /// + /// Creates new instance of the object. + /// + public BorderPattern() + { + } + + #endregion + + #region Public properties + + #region All + + /// + /// Gets or sets the thickness of all sides. + /// + //[Browsable(false)] + //[EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public LinePattern All + { + set { _Top = _Left = _Bottom = _Right = value; } + } + + #endregion + + #region Bottom + + /// + /// Gets or sets the bottom Border Pattern + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the bottom Border Pattern")] + public LinePattern Bottom + { + get { return (_Bottom); } + + set + { + if (_Bottom != value) + { + _Bottom = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Bottom")); + } + } + } + + #endregion + + #region Left + + /// + /// Gets or sets the left Border Pattern + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the left Border Pattern")] + public LinePattern Left + { + get { return (_Left); } + + set + { + if (_Left != value) + { + _Left = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Left")); + } + } + } + + #endregion + + #region Right + + /// + /// Gets or sets the Right Border Pattern + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Right Border Pattern")] + public LinePattern Right + { + get { return (_Right); } + + set + { + if (_Right != value) + { + _Right = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Right")); + } + } + } + + #endregion + + #region Top + + /// + /// Gets or sets the Top Border Pattern + /// + [Browsable(true), DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Top Border Pattern")] + public LinePattern Top + { + get { return (_Top); } + + set + { + if (_Top != value) + { + _Top = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Top")); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the item is empty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + return (_Left == LinePattern.NotSet && + _Right == LinePattern.NotSet && + _Top == LinePattern.NotSet && + _Bottom == LinePattern.NotSet); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region IsUniform + + internal bool IsUniform + { + get + { + return (_Left == _Top && + _Left == _Right && _Left == _Bottom); + } + } + + #endregion + + #endregion + + #region Equals + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to. + /// true if equal otherwise false. + public override bool Equals(object obj) + { + if (obj is BorderPattern) + return (this == (BorderPattern)obj); + + return (false); + } + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to + /// true if equal otherwise false + public bool Equals(BorderPattern borderPattern) + { + return (this == borderPattern); + } + + #endregion + + #region GetHashCode + + /// + /// Returns hash-code. + /// + /// hash-code + public override int GetHashCode() + { + return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^ + _Right.GetHashCode()) ^ _Bottom.GetHashCode()); + } + + #endregion + + #region Operators + + #region "==" operator + + /// + /// Implements == operator. + /// + /// Object 1 + /// Object 2 + /// true if equals + public static bool operator ==(BorderPattern t1, BorderPattern t2) + { + if (ReferenceEquals(t1, t2)) + return (true); + + if (((object)t1 == null) || ((object)t2 == null)) + return (false); + + return (t1._Left == t2._Left && t1._Right == t2._Right && + t1._Top == t2._Top && t1._Bottom == t2._Bottom); + } + + #endregion + + #region "!=" operator + + /// + /// Implements != operator + /// + /// Object 1 + /// Object 2 + /// true if different + public static bool operator !=(BorderPattern t1, BorderPattern t2) + { + return ((t1 == t2) == false); + } + + #endregion + + #endregion + + #region ApplyPattern + + /// + /// Applies the pattern to instance of this pattern. + /// + /// Pattern to apply. + public void ApplyPattern(BorderPattern pattern) + { + if (pattern != null) + { + if (pattern.Top != LinePattern.NotSet) + _Top = pattern.Top; + + if (pattern.Left != LinePattern.NotSet) + _Left = pattern.Left; + + if (pattern.Bottom != LinePattern.NotSet) + _Bottom = pattern.Bottom; + + if (pattern.Right != LinePattern.NotSet) + _Right = pattern.Right; + } + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the BorderPattern. + /// + /// Copy of the BorderPattern. + public BorderPattern Copy() + { + BorderPattern copy = new BorderPattern(_Left, _Top, _Right, _Bottom); + + return (copy); + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "BorderPattern"; + + sec.AddStartElement(serialName); + } + + if (IsUniform == true) + { + sec.AddValue("All", Left, LinePattern.NotSet); + } + else + { + sec.AddValue("Left", Left, LinePattern.NotSet); + sec.AddValue("Top", Top, LinePattern.NotSet); + sec.AddValue("Right", Right, LinePattern.NotSet); + sec.AddValue("Bottom", Bottom, LinePattern.NotSet); + } + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "All": + All = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "Left": + Left = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "Top": + Top = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "Right": + Right = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "Bottom": + Bottom = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + void OnPropertyChanged(VisualPropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + #endregion + } + + #region enums + + #region LinePattern + + /// + /// LinePattern + /// + public enum LinePattern + { + /// + /// None + /// + None = -2, + + /// + /// NotSet + /// + NotSet = -1, + + /// + /// Solid + /// + Solid = DashStyle.Solid, + + /// + /// Dash + /// + Dash = DashStyle.Dash, + + /// + /// Dot + /// + Dot = DashStyle.Dot, + + /// + /// DashDot + /// + DashDot = DashStyle.DashDot, + + /// + /// DashDotDot + /// + DashDotDot = DashStyle.DashDotDot, + } + + #endregion + + #region ChartLineCap + + /// + /// ChartLineCap + /// + public enum ChartLineCap + { + /// + /// NotSet + /// + NotSet = -1, + + Flat = 0, + Square = 1, + Round = 2, + Triangle = 3, + NoAnchor = 16, + SquareAnchor = 17, + RoundAnchor = 18, + DiamondAnchor = 19, + ArrowAnchor = 20, + } + + #endregion + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartAxisVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartAxisVisualStyle.cs new file mode 100644 index 00000000..63b53088 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartAxisVisualStyle.cs @@ -0,0 +1,325 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// ChartAxisVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartAxisVisualStyles : VisualStyles + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public ChartAxisVisualStyles Copy() + { + ChartAxisVisualStyles styles = new ChartAxisVisualStyles(); + + for (int i = 0; i < Styles.Length; i++) + { + ChartAxisVisualStyle vstyle = Styles[i]; + + if (vstyle != null) + styles.Styles[i] = vstyle.Copy(); + } + + return (styles); + } + + #endregion + } + + /// + /// Represents the visual style of a ChartAxis element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartAxisVisualStyle : BaseVisualStyle + { + #region Private variables + + private Color _AxisColor = Color.Empty; + private Background _AlternateBackground; + + #endregion + + #region Public properties + + #region AlternateBackground + + /// + /// Gets or sets the alternate, or interlaced, background. + /// + [Description("Indicates the alternate, or interlaced, background")] + public Background AlternateBackground + { + get + { + if (_AlternateBackground == null) + { + _AlternateBackground = Background.Empty; + + UpdateChangeHandler(null, _AlternateBackground); + } + + return (_AlternateBackground); + } + + set + { + if (_AlternateBackground != value) + { + UpdateChangeHandler(_AlternateBackground, value); + + _AlternateBackground = value; + + OnPropertyChangedEx("AlternateBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeAlternateBackground() + { + return (_AlternateBackground != null && _AlternateBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetAlternateBackground() + { + AlternateBackground = null; + } + + #endregion + + #region AxisColor + + /// + /// Gets or sets the Axis line Color. + /// + [Category("Appearance")] + [Description("Indicates the Axis line Color.")] + public Color AxisColor + { + get { return (_AxisColor); } + + set + { + if (value != _AxisColor) + { + _AxisColor = value; + + OnPropertyChangedEx("AxisColor", Style.VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeAxisColor() + { + return (_AxisColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetAxisColor() + { + _AxisColor = Color.Empty; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_AlternateBackground == null || _AlternateBackground.IsEmpty) && + (_AxisColor.IsEmpty == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartAxisVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._AlternateBackground != null && style.AlternateBackground.IsEmpty == false) + AlternateBackground = style.AlternateBackground.Copy(); + + if (style.AxisColor.IsEmpty == false) + AxisColor = style.AxisColor; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (AxisColor.IsEmpty == true) + AxisColor = Color.Black; + + if (AlternateBackground.IsEmpty == true) + AlternateBackground = new Background(Color.Ivory); + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartAxisVisualStyle Copy() + { + ChartAxisVisualStyle style = new ChartAxisVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartAxisVisualStyle style) + { + base.CopyTo(style); + + style.AlternateBackground = + (_AlternateBackground != null) ? _AlternateBackground.Copy() : null; + + style.AxisColor = _AxisColor; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartAxisVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_AlternateBackground != null && _AlternateBackground.IsEmpty == false) + sec.AddElement(_AlternateBackground.GetSerialData("AlternateBackground")); + + sec.AddValue("AxisColor", AxisColor, Color.Empty); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AxisColor": + AxisColor = se.GetValueColor(); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "AlternateBackground": + sec.PutSerialData(AlternateBackground); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + AlternateBackground = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartBarVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartBarVisualStyle.cs new file mode 100644 index 00000000..687648e9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartBarVisualStyle.cs @@ -0,0 +1,388 @@ +using System.ComponentModel; +using System.Drawing.Design; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a Bar Series + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartBarVisualStyle : BaseVisualStyle + { + #region Private variables + + private ChartLineVisualStyle _Border; + private ChartLineVisualStyle _AlternateBorder; + + private Background _Background; + private Background _AlternateBackground; + + #endregion + + #region Public properties + + #region AlternateBackground + + /// + /// Gets or sets the background for the bar, when it + /// extends to the alternate side of the bar origin. + /// + [Description("Indicates the background for the bar, when it extends to the alternate side of the bar origin.")] + public Background AlternateBackground + { + get + { + if (_AlternateBackground == null) + { + _AlternateBackground = Background.Empty; + + UpdateChangeHandler(null, _AlternateBackground); + } + + return (_AlternateBackground); + } + + set + { + if (_AlternateBackground != value) + { + UpdateChangeHandler(_AlternateBackground, value); + + _AlternateBackground = value; + + OnPropertyChangedEx("AlternateBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeAlternateBackground() + { + return (_AlternateBackground != null && _AlternateBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetAlternateBackground() + { + AlternateBackground = null; + } + + #endregion + + #region AlternateBorder + + /// + /// Gets or sets the border style for the bar, when it + /// extends to the alternate side of the bar origin. + /// + [Category("Style")] + [Description("Indicates the border style for the bar, when it extends to the alternate side of the bar origin.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle AlternateBorder + { + get + { + if (_AlternateBorder == null) + { + _AlternateBorder = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _AlternateBorder); + } + + return (_AlternateBorder); + } + + set + { + if (_AlternateBorder != value) + { + ChartLineVisualStyle oldValue = _AlternateBorder; + + _AlternateBorder = value; + + OnStyleChanged("AlternateBorder", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region Background + + /// + /// Gets or sets the background for the bar. + /// + [Description("Indicates the background for the bar.")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region Border + + /// + /// Gets or sets the border style for the bar. + /// + [Category("Style")] + [Description("Indicates the border style for the bar.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle Border + { + get + { + if (_Border == null) + { + _Border = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _Border); + } + + return (_Border); + } + + set + { + if (_Border != value) + { + ChartLineVisualStyle oldValue = _Border; + + _Border = value; + + OnStyleChanged("Border", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_AlternateBackground == null || _AlternateBackground.IsEmpty == true) && + (_AlternateBorder == null || _AlternateBorder.IsEmpty) && + (_Background == null || _Background.IsEmpty) && + (_Border == null || _Border.IsEmpty) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartBarVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._AlternateBackground != null && style._AlternateBackground.IsEmpty == false) + AlternateBackground = style._AlternateBackground.Copy(); + + if (style._AlternateBorder != null && style._AlternateBorder.IsEmpty == false) + AlternateBorder.ApplyStyle(style._AlternateBorder); + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style._Border != null && style._Border.IsEmpty == false) + Border.ApplyStyle(style._Border); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartBarVisualStyle Copy() + { + ChartBarVisualStyle style = new ChartBarVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartBarVisualStyle style) + { + base.CopyTo(style); + + style.AlternateBackground = (_AlternateBackground != null) ? _AlternateBackground.Copy() : null; + style.AlternateBorder = (_AlternateBorder != null) ? _AlternateBorder.Copy() : null; + style.Background = (_Background != null) ? _Background.Copy() : null; + style.Border = (_Border != null) ? _Border.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartBarVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_AlternateBackground != null && _AlternateBackground.IsEmpty == false) + sec.AddElement(_AlternateBackground.GetSerialData("AlternateBackground")); + + if (_AlternateBorder != null && _AlternateBorder.IsEmpty == false) + sec.AddElement(_AlternateBorder.GetSerialData("AlternateBorder")); + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + if (_Border != null && _Border.IsEmpty == false) + sec.AddElement(_Border.GetSerialData("Border")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "AlternateBackground": + sec.PutSerialData(AlternateBackground); + break; + + case "AlternateBorder": + sec.PutSerialData(AlternateBorder); + break; + + case "Background": + sec.PutSerialData(Background); + break; + + case "Border": + sec.PutSerialData(Border); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + AlternateBackground = null; + Background = null; + Border = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartHiLoBarVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartHiLoBarVisualStyle.cs new file mode 100644 index 00000000..8d4f2743 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartHiLoBarVisualStyle.cs @@ -0,0 +1,330 @@ +using System; +using System.ComponentModel; +using System.Drawing.Design; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of an Hilo Bar Series (OHLC) + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartHiLoBarVisualStyle : BaseVisualStyle + { + #region Private variables + + private HiLoBarSegmentStyle _DefaultSegmentStyle; + private HiLoBarSegmentStyle _AlternateSegmentStyle; + + private Tbool _ShowWhiskerCaps = Tbool.NotSet; + private Tbool _UseAlternateSegmentStyle = Tbool.NotSet; + + #endregion + + #region Public properties + + #region AlternateSegmentStyle + + /// + /// Gets or sets the Alternate Style for the Ohlc bar. + /// + [Description("Indicates the Alternate Style for the Ohlc bar.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public HiLoBarSegmentStyle AlternateSegmentStyle + { + get + { + if (_AlternateSegmentStyle == null) + { + _AlternateSegmentStyle = HiLoBarSegmentStyle.Empty; + + UpdateChangeHandler(null, _AlternateSegmentStyle); + } + + return (_AlternateSegmentStyle); + } + + set + { + if (_AlternateSegmentStyle != value) + { + UpdateChangeHandler(_AlternateSegmentStyle, value); + + _AlternateSegmentStyle = value; + + OnPropertyChangedEx("AlternateSegmentStyle", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DefaultSegmentStyle + + /// + /// Gets or sets the Default Style for the Ohlc bar. + /// + [Description("Indicates the Default Style for the Ohlc bar.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public HiLoBarSegmentStyle DefaultSegmentStyle + { + get + { + if (_DefaultSegmentStyle == null) + { + _DefaultSegmentStyle = HiLoBarSegmentStyle.Empty; + + UpdateChangeHandler(null, _DefaultSegmentStyle); + } + + return (_DefaultSegmentStyle); + } + + set + { + if (_DefaultSegmentStyle != value) + { + UpdateChangeHandler(_DefaultSegmentStyle, value); + + _DefaultSegmentStyle = value; + + OnPropertyChangedEx("DefaultSegmentStyle", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowWhiskerCaps + + /// + /// Gets or sets whether Box/Candle whisker caps are displayed. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether Box/Candle whisker caps are displayed.")] + public Tbool ShowWhiskerCaps + { + get { return (_ShowWhiskerCaps); } + + set + { + if (value != _ShowWhiskerCaps) + { + _ShowWhiskerCaps = value; + + OnPropertyChangedEx("ShowWhiskerCaps", VisualChangeType.Render); + } + } + } + + #endregion + + #region UseAlternateSegmentStyle + + /// + /// Gets or sets whether Box/Candle whisker caps are displayed. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether Box/Candle whisker caps are displayed.")] + public Tbool UseAlternateSegmentStyle + { + get { return (_UseAlternateSegmentStyle); } + + set + { + if (value != _UseAlternateSegmentStyle) + { + _UseAlternateSegmentStyle = value; + + OnPropertyChangedEx("UseAlternateSegmentStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_AlternateSegmentStyle == null || _AlternateSegmentStyle.IsEmpty == true) && + (_DefaultSegmentStyle == null || _DefaultSegmentStyle.IsEmpty) && + (_ShowWhiskerCaps == Tbool.NotSet)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartHiLoBarVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._AlternateSegmentStyle != null && style._AlternateSegmentStyle.IsEmpty == false) + AlternateSegmentStyle.ApplyStyle(style._AlternateSegmentStyle); + + if (style._DefaultSegmentStyle != null && style._DefaultSegmentStyle.IsEmpty == false) + DefaultSegmentStyle.ApplyStyle(style._DefaultSegmentStyle); + + if (style.ShowWhiskerCaps != Tbool.NotSet) + ShowWhiskerCaps = style.ShowWhiskerCaps; + + if (style.UseAlternateSegmentStyle != Tbool.NotSet) + UseAlternateSegmentStyle = style.UseAlternateSegmentStyle; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartHiLoBarVisualStyle Copy() + { + ChartHiLoBarVisualStyle style = new ChartHiLoBarVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartHiLoBarVisualStyle style) + { + base.CopyTo(style); + + style.AlternateSegmentStyle = (_AlternateSegmentStyle != null) ? _AlternateSegmentStyle.Copy() : null; + style.DefaultSegmentStyle = (_DefaultSegmentStyle != null) ? _DefaultSegmentStyle.Copy() : null; + + style.ShowWhiskerCaps = _ShowWhiskerCaps; + style.UseAlternateSegmentStyle = _UseAlternateSegmentStyle; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartHiLoBarVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_DefaultSegmentStyle != null && _DefaultSegmentStyle.IsEmpty == false) + sec.AddElement(_DefaultSegmentStyle.GetSerialData("DefaultSegmentStyle")); + + if (_AlternateSegmentStyle != null && _AlternateSegmentStyle.IsEmpty == false) + sec.AddElement(_AlternateSegmentStyle.GetSerialData("AlternateSegmentStyle")); + + sec.AddValue("ShowWhiskerCaps", ShowWhiskerCaps, Tbool.NotSet); + sec.AddValue("UseAlternateSegmentStyle", UseAlternateSegmentStyle, Tbool.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "ShowWhiskerCaps": + ShowWhiskerCaps = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "UseAlternateSegmentStyle": + UseAlternateSegmentStyle = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "DefaultSegmentStyle": + sec.PutSerialData(DefaultSegmentStyle); + break; + + case "AlternateSegmentStyle": + sec.PutSerialData(AlternateSegmentStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + AlternateSegmentStyle = null; + DefaultSegmentStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartLegendItemVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartLegendItemVisualStyle.cs new file mode 100644 index 00000000..47fb86cf --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartLegendItemVisualStyle.cs @@ -0,0 +1,847 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// ChartLegendVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartLegendItemVisualStyles : VisualStyles + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public ChartLegendItemVisualStyles Copy() + { + ChartLegendItemVisualStyles styles = new ChartLegendItemVisualStyles(); + + for (int i = 0; i < Styles.Length; i++) + { + ChartLegendItemVisualStyle vstyle = Styles[i]; + + if (vstyle != null) + styles.Styles[i] = vstyle.Copy(); + } + + return (styles); + } + + #endregion + } + + /// + /// Represents the visual style of a Legend item element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartLegendItemVisualStyle : BaseVisualStyle + { + #region Private variables + + private Background _Background; + private Color _TextColor = Color.Empty; + private Font _Font; + + private Tbool _AllowWrap = Tbool.NotSet; + private Alignment _Alignment = Alignment.NotSet; + private int _MaxLineCount; + + private Background _CheckBoxBackground; + private Color _CheckBoxBorderColor = Color.Empty; + private Color _CheckBoxCheckColor = Color.Empty; + + private PointMarkerVisualStyle _MarkerVisualStyle; + + private Background _DisabledMarkerBackground; + private Color _DisabledTextColor = Color.Empty; + + #endregion + + #region Public properties + + #region Alignment + + /// + /// Gets or sets the alignment of the text + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the text.")] + public Alignment Alignment + { + get { return (_Alignment); } + + set + { + if (_Alignment != value) + { + _Alignment = value; + + OnPropertyChangedEx("Alignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region CheckBoxBackground + + /// + /// Gets or sets the CheckBox background. + /// + [Description("Indicates the CheckBox background")] + public Background CheckBoxBackground + { + get + { + if (_CheckBoxBackground == null) + { + _CheckBoxBackground = Background.Empty; + + UpdateChangeHandler(null, _CheckBoxBackground); + } + + return (_CheckBoxBackground); + } + + set + { + if (_CheckBoxBackground != value) + { + UpdateChangeHandler(_CheckBoxBackground, value); + + _CheckBoxBackground = value; + + OnPropertyChangedEx("CheckBoxBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeCheckBoxBackground() + { + return (_CheckBoxBackground != null && _CheckBoxBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetCheckBoxBackground() + { + CheckBoxBackground = null; + } + + #endregion + + #region CheckBoxBorderColor + + /// + /// Gets or sets the CheckBox border color. + /// + [Description("Indicates the CheckBox border color")] + public Color CheckBoxBorderColor + { + get { return (_CheckBoxBorderColor); } + + set + { + if (_CheckBoxBorderColor != value) + { + _CheckBoxBorderColor = value; + + OnPropertyChangedEx("CheckBoxBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeCheckBoxBorderColor() + { + return (_CheckBoxBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetCheckBoxBorderColor() + { + CheckBoxBorderColor = Color.Empty; + } + + #endregion + + #region CheckBoxCheckColor + + /// + /// Gets or sets the CheckBox check color. + /// + [Description("Indicates the CheckBox check color")] + public Color CheckBoxCheckColor + { + get { return (_CheckBoxCheckColor); } + + set + { + if (_CheckBoxCheckColor != value) + { + _CheckBoxCheckColor = value; + + OnPropertyChangedEx("CheckBoxCheckColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeCheckBoxCheckColor() + { + return (_CheckBoxCheckColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetCheckBoxCheckColor() + { + CheckBoxCheckColor = Color.Empty; + } + + #endregion + + #region DisabledMarkerBackground + + /// + /// Gets or sets the Disabled Marker Background style. + /// + [Description("Indicates the Disabled Marker Background style")] + public Background DisabledMarkerBackground + { + get + { + if (_DisabledMarkerBackground == null) + { + _DisabledMarkerBackground = Background.Empty; + + UpdateChangeHandler(null, _DisabledMarkerBackground); + } + + return (_DisabledMarkerBackground); + } + + set + { + if (_DisabledMarkerBackground != value) + { + UpdateChangeHandler(_DisabledMarkerBackground, value); + + _DisabledMarkerBackground = value; + + OnPropertyChangedEx("DisabledMarkerBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeDisabledMarkerBackground() + { + return (_DisabledMarkerBackground != null && _DisabledMarkerBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetDisabledMarkerBackground() + { + DisabledMarkerBackground = null; + } + + #endregion + + #region DisabledTextColor + + /// + /// Gets or sets the Disabled TextColor + /// + [Category("Appearance")] + [Description("Indicates whether the items in the Legend are equally spaced.")] + public Color DisabledTextColor + { + get { return (_DisabledTextColor); } + + set + { + if (value != _DisabledTextColor) + { + _DisabledTextColor = value; + + OnPropertyChangedEx("DisabledTextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeDisabledTextColor() + { + return (_DisabledTextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetDisabledTextColor() + { + DisabledTextColor = Color.Empty; + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font + /// + [DefaultValue(null)] + [Description("Indicates the style Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MarkerVisualStyle + + /// + /// Gets or sets the visual styles for the Legend Marker. + /// + [Category("Style")] + [Description("Indicates the visual styles for the PointMarker.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PointMarkerVisualStyle MarkerVisualStyle + { + get + { + if (_MarkerVisualStyle == null) + { + _MarkerVisualStyle = new PointMarkerVisualStyle(); + + UpdateChangeHandler(null, _MarkerVisualStyle); + } + + return (_MarkerVisualStyle); + } + + set + { + if (_MarkerVisualStyle != value) + { + PointMarkerVisualStyle oldValue = _MarkerVisualStyle; + + _MarkerVisualStyle = value; + + OnStyleChanged("MarkerVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region MaxLineCount + + /// + /// Gets or sets the maximum number of lines for the item text. + /// + [Category("Appearance")] + [Description("Indicates the maximum number of lines for the item text.")] + [DefaultValue(0)] + public int MaxLineCount + { + get { return (_MaxLineCount); } + + set + { + if (value != _MaxLineCount) + { + _MaxLineCount = value; + + OnPropertyChangedEx("MaxLineCount", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color. + /// + [Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + TextColor = Color.Empty; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Alignment == Alignment.NotSet) && + (_AllowWrap == Tbool.NotSet) && + (_Background == null || _Background.IsEmpty == true) && + (_CheckBoxBackground == null || _CheckBoxBackground.IsEmpty == true) && + (_CheckBoxBorderColor.IsEmpty == true) && + (_CheckBoxCheckColor.IsEmpty == true) && + (_DisabledMarkerBackground == null || _DisabledMarkerBackground.IsEmpty == true) && + (_DisabledTextColor.IsEmpty == true) && + (_Font == null) && + (_MarkerVisualStyle == null || _MarkerVisualStyle.IsEmpty) && + (_MaxLineCount == 0) && + (_TextColor.IsEmpty == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region GetStringFormatFlags + + internal void GetStringFormatFlags(StringFormat sf) + { + if (_AllowWrap == Tbool.False || _MaxLineCount <= 1) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + sf.Trimming = StringTrimming.EllipsisCharacter; + + switch (Alignment) + { + case Alignment.TopCenter: + sf.LineAlignment = StringAlignment.Near; + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.TopRight: + sf.LineAlignment = StringAlignment.Near; + sf.Alignment = StringAlignment.Far; + break; + + case Alignment.NotSet: + case Alignment.MiddleLeft: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Near; + break; + + case Alignment.MiddleCenter: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.MiddleRight: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Far; + break; + + case Alignment.BottomLeft: + sf.LineAlignment = StringAlignment.Far; + sf.Alignment = StringAlignment.Near; + break; + + case Alignment.BottomCenter: + sf.LineAlignment = StringAlignment.Far; + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.BottomRight: + sf.LineAlignment = StringAlignment.Far; + sf.Alignment = StringAlignment.Far; + break; + } + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartLegendItemVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.Alignment != Alignment.NotSet) + Alignment = style.Alignment; + + if (style.AllowWrap != Tbool.NotSet) + AllowWrap = style.AllowWrap; + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style._CheckBoxBackground != null && style._CheckBoxBackground.IsEmpty == false) + CheckBoxBackground = style._CheckBoxBackground.Copy(); + + if (style._CheckBoxBorderColor.IsEmpty == false) + CheckBoxBorderColor = style._CheckBoxBorderColor; + + if (style._CheckBoxCheckColor.IsEmpty == false) + CheckBoxCheckColor = style._CheckBoxCheckColor; + + if (style._DisabledMarkerBackground != null && style._DisabledMarkerBackground.IsEmpty == false) + DisabledMarkerBackground = style.DisabledMarkerBackground.Copy(); + + if (style.DisabledTextColor.IsEmpty == false) + DisabledTextColor = style.DisabledTextColor; + + if (style.Font != null) + Font = style.Font; + + if (style._MarkerVisualStyle != null && style.MarkerVisualStyle.IsEmpty == false) + MarkerVisualStyle.ApplyStyle(style.MarkerVisualStyle); + + if (style.MaxLineCount != 0) + MaxLineCount = style.MaxLineCount; + + if (style._TextColor.IsEmpty == false) + TextColor = style._TextColor; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartLegendItemVisualStyle Copy() + { + ChartLegendItemVisualStyle style = new ChartLegendItemVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartLegendItemVisualStyle style) + { + base.CopyTo(style); + + style.Alignment = _Alignment; + style.AllowWrap = _AllowWrap; + + style.Background = (_Background != null) ? _Background.Copy() : null; + + style.CheckBoxBackground = (_CheckBoxBackground != null) ? _CheckBoxBackground.Copy() : null; + style.CheckBoxBorderColor = _CheckBoxBorderColor; + style.CheckBoxCheckColor = _CheckBoxCheckColor; + + style.DisabledMarkerBackground = (_DisabledMarkerBackground != null ? _DisabledMarkerBackground.Copy() : null); + style.DisabledTextColor = _DisabledTextColor; + + style.Font = (_Font != null) ? (Font)_Font.Clone() : null; + style.MarkerVisualStyle = (_MarkerVisualStyle != null) ? _MarkerVisualStyle.Copy() : null; + + style.MaxLineCount = _MaxLineCount; + style.TextColor = _TextColor; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartLegendItemVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("Alignment", _Alignment, Alignment.NotSet); + sec.AddValue("AllowWrap", _AllowWrap, Tbool.NotSet); + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + if (_CheckBoxBackground != null && _CheckBoxBackground.IsEmpty == false) + sec.AddElement(_CheckBoxBackground.GetSerialData("CheckBoxBackground")); + + sec.AddValue("CheckBoxBorderColor", _CheckBoxBorderColor, Color.Empty); + sec.AddValue("CheckBoxCheckColor", _CheckBoxCheckColor, Color.Empty); + + if (_Font != null) + sec.AddValue("Font", XmlSerializableFont.ConvertToString(Font)); + + if (_MarkerVisualStyle != null && _MarkerVisualStyle.IsEmpty == false) + sec.AddElement(_MarkerVisualStyle.GetSerialData("MarkerVisualStyle")); + + sec.AddValue("MaxLineCount", _MaxLineCount, 0); + sec.AddValue("TextColor", _TextColor, Color.Empty); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Alignment": + Alignment = (Alignment)se.GetValueEnum(typeof(Alignment)); + break; + + case "AllowWrap": + AllowWrap = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "CheckBoxBorderColor": + CheckBoxBorderColor = se.GetValueColor(); + break; + + case "CheckBoxCheckColor": + CheckBoxCheckColor = se.GetValueColor(); + break; + + case "Font": + Font = XmlSerializableFont.ConvertFromString(se.StringValue); + break; + + case "MaxLineCount": + MaxLineCount = int.Parse(se.StringValue); + break; + + case "TextColor": + TextColor = se.GetValueColor(); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "Background": + sec.PutSerialData(Background); + break; + + case "CheckBoxBackground": + sec.PutSerialData(CheckBoxBackground); + break; + + case "MarkerVisualStyle": + sec.PutSerialData(MarkerVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + Background = null; + CheckBoxBackground = null; + MarkerVisualStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartLegendVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartLegendVisualStyle.cs new file mode 100644 index 00000000..8299026d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartLegendVisualStyle.cs @@ -0,0 +1,351 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// ChartLegendVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartLegendVisualStyles : VisualStyles + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public ChartLegendVisualStyles Copy() + { + ChartLegendVisualStyles styles = new ChartLegendVisualStyles(); + + for (int i = 0; i < Styles.Length; i++) + { + ChartLegendVisualStyle vstyle = Styles[i]; + + if (vstyle != null) + styles.Styles[i] = vstyle.Copy(); + } + + return (styles); + } + + #endregion + } + + /// + /// Represents the visual style of a Legend element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartLegendVisualStyle : ContainerVisualStyle + { + #region Private variables + + private Tbool _EquallySpacedItems = Tbool.NotSet; + + private int _HorizontalSpacing = -1; + private int _VerticalSpacing = -1; + + #endregion + + #region Public properties + + #region EquallySpacedItems + + /// + /// Gets or sets whether the items in the Legend are equally spaced. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether the items in the Legend are equally spaced.")] + public Tbool EquallySpacedItems + { + get { return (_EquallySpacedItems); } + + set + { + if (value != _EquallySpacedItems) + { + _EquallySpacedItems = value; + + OnPropertyChangedEx("EquallySpacedItems", VisualChangeType.Layout); + } + } + } + + #endregion + + #region HorizontalSpacing + + /// + /// Gets or sets the horizontal spacing of the legend items. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the horizontal spacing of the legend items.")] + public int HorizontalSpacing + { + get { return (_HorizontalSpacing); } + + set + { + if (value != _HorizontalSpacing) + { + _HorizontalSpacing = value; + + OnPropertyChangedEx("HorizontalSpacing", VisualChangeType.Layout); + } + } + } + + #endregion + + #region VerticalSpacing + + /// + /// Gets or sets the vertical spacing of the legend items. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the vertical spacing of the legend items.")] + public int VerticalSpacing + { + get { return (_VerticalSpacing); } + + set + { + if (value != _VerticalSpacing) + { + _VerticalSpacing = value; + + OnPropertyChangedEx("VerticalSpacing", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_EquallySpacedItems == Tbool.NotSet) && + (_HorizontalSpacing == -1) && + (_VerticalSpacing == -1) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region Hidden properties + + #region Alignment + + /// + /// Gets or sets the alignment of the text + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Alignment Alignment + { + get { return (base.Alignment); } + set { base.Alignment = value; } + } + + #endregion + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Tbool AllowWrap + { + get { return (base.AllowWrap); } + set { base.AllowWrap = value; } + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Font Font + { + get { return (base.Font); } + set { base.Font = value; } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Color TextColor + { + get { return (base.TextColor); } + set { base.TextColor = value; } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartLegendVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.EquallySpacedItems != Tbool.NotSet) + EquallySpacedItems = style.EquallySpacedItems; + + if (style.HorizontalSpacing != -1) + HorizontalSpacing = style.HorizontalSpacing; + + if (style.VerticalSpacing != -1) + VerticalSpacing = style.VerticalSpacing; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + base.ApplyDefaults(); + + if (VerticalSpacing < 0) + VerticalSpacing = 2; + + if (HorizontalSpacing < 0) + HorizontalSpacing = 2; + + if (BorderPattern == null) + BorderPattern = new BorderPattern(LinePattern.Solid); + + if (DropShadow.Enabled == Tbool.NotSet) + DropShadow.Enabled = Tbool.False; + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartLegendVisualStyle Copy() + { + ChartLegendVisualStyle style = new ChartLegendVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartLegendVisualStyle style) + { + base.CopyTo(style); + + style.HorizontalSpacing = _HorizontalSpacing; + style.EquallySpacedItems = _EquallySpacedItems; + + style.VerticalSpacing = _VerticalSpacing; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartLegendVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("HorizontalSpacing", HorizontalSpacing, -1); + sec.AddValue("EquallySpacedItems", EquallySpacedItems, Tbool.NotSet); + sec.AddValue("VerticalSpacing", VerticalSpacing, -1); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "HorizontalSpacing": + HorizontalSpacing = int.Parse(se.StringValue); + break; + + case "EquallySpacedItems": + EquallySpacedItems = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "VerticalSpacing": + VerticalSpacing = int.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartLineVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartLineVisualStyle.cs new file mode 100644 index 00000000..aefe5a58 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartLineVisualStyle.cs @@ -0,0 +1,517 @@ +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a Chart Line + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartLineVisualStyle : BaseVisualStyle + { + #region Private variables + + private Color _LineColor = Color.Empty; + private LinePattern _LinePattern = LinePattern.NotSet; + private int _LineWidth = -1; + + #endregion + + #region Public properties + + #region LineColor + + /// + /// Gets or sets the Line color. + /// + [Description("Indicates the Line color.")] + public Color LineColor + { + get { return (_LineColor); } + + set + { + if (_LineColor != value) + { + _LineColor = value; + + OnPropertyChangedEx("LineColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeLineColor() + { + return (_LineColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetLineColor() + { + LineColor = Color.Empty; + } + + #endregion + + #region LinePattern + + /// + /// Gets or sets the LinePattern. + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the LinePattern.")] + public LinePattern LinePattern + { + get { return (_LinePattern); } + + set + { + if (_LinePattern != value) + { + _LinePattern = value; + + OnPropertyChangedEx("LinePattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region LineWidth + + /// + /// Gets or sets the line width. + /// + [DefaultValue(-1)] + [Description("Indicates the line width")] + public int LineWidth + { + get { return (_LineWidth); } + + set + { + if (_LineWidth != value) + { + _LineWidth = value; + + OnPropertyChangedEx("LineWidth", VisualChangeType.Render); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_LineColor.IsEmpty) && + (_LinePattern == LinePattern.NotSet) && + (_LineWidth < 0) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region Internal properties + + internal bool IsDisplayable + { + get + { + return (LineColor.IsEmpty == false && + LinePattern != LinePattern.None && + LineWidth > 0); + } + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartLineVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.LineColor.IsEmpty == false) + LineColor = style.LineColor; + + if (style.LinePattern != LinePattern.NotSet) + LinePattern = style.LinePattern; + + if (style.LineWidth >= 0) + LineWidth = style.LineWidth; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (LinePattern == LinePattern.NotSet) + LinePattern = LinePattern.Solid; + + if (LineWidth < 0) + LineWidth = 1; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartLineVisualStyle Copy() + { + ChartLineVisualStyle style = new ChartLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartLineVisualStyle style) + { + base.CopyTo(style); + + style.LineColor = _LineColor; + style.LinePattern = _LinePattern; + style.LineWidth = _LineWidth; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartLineVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("LineColor", LineColor, Color.Empty); + sec.AddValue("LinePattern", LinePattern, LinePattern.NotSet); + sec.AddValue("LineWidth", LineWidth, -1); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "LineColor": + LineColor = se.GetValueColor(); + break; + + case "LinePattern": + LinePattern = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "LineWidth": + LineWidth = int.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + base.Dispose(); + } + + #endregion + } + + /// + /// Represents the visual style of a Chart CapLine + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartCapLineVisualStyle : ChartLineVisualStyle + { + #region Private variables + + private ChartLineCap _EndCap = ChartLineCap.NotSet; + private ChartLineCap _StartCap = ChartLineCap.NotSet; + + #endregion + + #region Public properties + + #region EndCap + + /// + /// Gets or sets the line EndCap. + /// + [DefaultValue(ChartLineCap.NotSet)] + [Description("Indicates the line End Cap.")] + public ChartLineCap EndCap + { + get { return (_EndCap); } + + set + { + if (_EndCap != value) + { + _EndCap = value; + + OnPropertyChangedEx("EndCap", VisualChangeType.Render); + } + } + } + + #endregion + + #region StartCap + + /// + /// Gets or sets the line StartCap. + /// + [DefaultValue(ChartLineCap.NotSet)] + [Description("Indicates the line Start Cap.")] + public ChartLineCap StartCap + { + get { return (_StartCap); } + + set + { + if (_StartCap != value) + { + _StartCap = value; + + OnPropertyChangedEx("StartCap", VisualChangeType.Render); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_EndCap == ChartLineCap.NotSet) && + (_StartCap == ChartLineCap.NotSet) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartCapLineVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.EndCap != ChartLineCap.NotSet) + _EndCap = style.EndCap; + + if (style.StartCap != ChartLineCap.NotSet) + _StartCap = style.StartCap; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (EndCap == ChartLineCap.NotSet) + EndCap = ChartLineCap.NoAnchor; + + if (StartCap == ChartLineCap.NotSet) + StartCap = ChartLineCap.NoAnchor; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartCapLineVisualStyle Copy() + { + ChartCapLineVisualStyle style = new ChartCapLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartCapLineVisualStyle style) + { + base.CopyTo(style); + + style.EndCap = _EndCap; + style.StartCap = _StartCap; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartCapLineVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("EndCap", EndCap, ChartLineCap.NotSet); + sec.AddValue("StartCap", StartCap, ChartLineCap.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "EndCap": + EndCap = (ChartLineCap)se.GetValueEnum(typeof(ChartLineCap)); + break; + + case "StartCap": + StartCap = (ChartLineCap)se.GetValueEnum(typeof(ChartLineCap)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartPanelVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartPanelVisualStyle.cs new file mode 100644 index 00000000..9065c817 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartPanelVisualStyle.cs @@ -0,0 +1,357 @@ +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a ChartPanel + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartPanelVisualStyle : BaseVisualStyle + { + #region Private variables + + private DividerLineVisualStyle _DividerLineX; + private DividerLineVisualStyle _DividerLineY; + + private ScrollBarVisualStyles _HScrollBarVisualStyles; + private ScrollBarVisualStyles _VScrollBarVisualStyles; + + #endregion + + #region Public properties + + #region DividerLineX + + /// + /// Gets or sets the visual style of the horizontal DividerLine (when ChartMatrix.DividerLines is enabled). + /// + [Description("Indicates the visual style of the horizontal DividerLine (when ChartMatrix.DividerLines is enabled).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DividerLineVisualStyle DividerLineX + { + get + { + if (_DividerLineX == null) + { + _DividerLineX = new DividerLineVisualStyle(); + + UpdateChangeHandler(null, _DividerLineX); + } + + return (_DividerLineX); + } + + set + { + if (_DividerLineX != value) + { + UpdateChangeHandler(_DividerLineX, value); + + _DividerLineX = value; + + OnPropertyChangedEx("DividerLineX", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DividerLineY + + /// + /// Gets or sets the visual style of the vertical DividerLine (when ChartMatrix.DividerLines is enabled). + /// + [Description("Indicates the visual style of the vertical DividerLine. (when ChartMatrix.DividerLines is enabled)")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DividerLineVisualStyle DividerLineY + { + get + { + if (_DividerLineY == null) + { + _DividerLineY = new DividerLineVisualStyle(); + + UpdateChangeHandler(null, _DividerLineY); + } + + return (_DividerLineY); + } + + set + { + if (_DividerLineY != value) + { + UpdateChangeHandler(_DividerLineY, value); + + _DividerLineY = value; + + OnPropertyChangedEx("DividerLineY", VisualChangeType.Layout); + } + } + } + + #endregion + + #region HScrollBarVisualStyles + + /// + /// Gets or sets the visual styles to be used for Horizontal ScrollBar elements + /// + [Category("Style")] + [Description("Indicates visual styles to be used for Horizontal ScrollBar elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarVisualStyles HScrollBarVisualStyles + { + get + { + if (_HScrollBarVisualStyles == null) + { + _HScrollBarVisualStyles = new ScrollBarVisualStyles(); + + UpdateChangeHandler(null, _HScrollBarVisualStyles); + } + + return (_HScrollBarVisualStyles); + } + + set + { + if (_HScrollBarVisualStyles != value) + { + ScrollBarVisualStyles oldValue = _HScrollBarVisualStyles; + _HScrollBarVisualStyles = value; + + OnStyleChanged("HScrollBarVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region VScrollBarVisualStyles + + /// + /// Gets or sets the visual styles to be used for Vertical ScrollBar elements + /// + [Category("Style")] + [Description("Indicates visual styles to be used for Vertical ScrollBar elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarVisualStyles VScrollBarVisualStyles + { + get + { + if (_VScrollBarVisualStyles == null) + { + _VScrollBarVisualStyles = new ScrollBarVisualStyles(); + + UpdateChangeHandler(null, _VScrollBarVisualStyles); + } + + return (_VScrollBarVisualStyles); + } + + set + { + if (_VScrollBarVisualStyles != value) + { + ScrollBarVisualStyles oldValue = _VScrollBarVisualStyles; + _VScrollBarVisualStyles = value; + + OnStyleChanged("VScrollBarVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_DividerLineX == null || _DividerLineX.IsEmpty == true) && + (_DividerLineY == null || _DividerLineY.IsEmpty == true) && + (_HScrollBarVisualStyles == null) && + (_VScrollBarVisualStyles == null) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartPanelVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.DividerLineX != null) + DividerLineX.ApplyStyle(style.DividerLineX); + + if (style.DividerLineY != null) + DividerLineY.ApplyStyle(style.DividerLineY); + + if (style.HScrollBarVisualStyles != null) + { + for (int i = 0; i < style.HScrollBarVisualStyles.Styles.Length; i++) + { + if (style.HScrollBarVisualStyles.Styles[i] != null) + HScrollBarVisualStyles.GetStyle(i).ApplyStyle(style.HScrollBarVisualStyles.Styles[i]); + } + } + + if (style.VScrollBarVisualStyles != null) + { + for (int i = 0; i < style.VScrollBarVisualStyles.Styles.Length; i++) + { + if (style.VScrollBarVisualStyles.Styles[i] != null) + VScrollBarVisualStyles.GetStyle(i).ApplyStyle(style.VScrollBarVisualStyles.Styles[i]); + } + } + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartPanelVisualStyle Copy() + { + ChartPanelVisualStyle style = new ChartPanelVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartPanelVisualStyle style) + { + base.CopyTo(style); + + style.DividerLineX = (_DividerLineX != null) ? _DividerLineX.Copy() : null; + style.DividerLineY = (_DividerLineY != null) ? _DividerLineY.Copy() : null; + + style.HScrollBarVisualStyles = (_HScrollBarVisualStyles != null) ? _HScrollBarVisualStyles.Copy() : null; + style.VScrollBarVisualStyles = (_VScrollBarVisualStyles != null) ? _VScrollBarVisualStyles.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartPanelVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_DividerLineX != null && _DividerLineX.IsEmpty == false) + sec.AddElement(_DividerLineX.GetSerialData("DividerLineX")); + + if (_DividerLineY != null && _DividerLineY.IsEmpty == false) + sec.AddElement(_DividerLineY.GetSerialData("DividerLineY")); + + if (_HScrollBarVisualStyles != null && _HScrollBarVisualStyles.IsEmpty == false) + sec.AddElement(_HScrollBarVisualStyles.GetSerialData("HScrollBarVisualStyles")); + + if (_VScrollBarVisualStyles != null && _VScrollBarVisualStyles.IsEmpty == false) + sec.AddElement(_VScrollBarVisualStyles.GetSerialData("VScrollBarVisualStyles")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "DividerLineX": + sec.PutSerialData(DividerLineX); + break; + + case "DividerLineY": + sec.PutSerialData(DividerLineY); + break; + + case "HScrollBarVisualStyles": + sec.PutSerialData(HScrollBarVisualStyles); + break; + + case "VScrollBarVisualStyles": + sec.PutSerialData(VScrollBarVisualStyles); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + DividerLineX = null; + DividerLineY = null; + HScrollBarVisualStyles = null; + VScrollBarVisualStyles = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartSeriesVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartSeriesVisualStyle.cs new file mode 100644 index 00000000..97e7ffff --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartSeriesVisualStyle.cs @@ -0,0 +1,1208 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a ChartSeries + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartSeriesVisualStyle : BaseVisualStyle + { + #region Private variables + + private ChartLineVisualStyle _LineStyle; + private ChartLineVisualStyle _SplineStyle; + private ChartCapLineVisualStyle _StepLineStyle; + private ChartBarVisualStyle _BarVisualStyle; + private ChartHiLoBarVisualStyle _HiLoBarVisualStyle; + + private Background _EmptyAreaBackground; + private Background _LineAreaBackground; + private Background _SplineAreaBackground; + private Background _StepLineAreaBackground; + + private ChartCapLineVisualStyle _StepLineAltStyle; + private ChartLineVisualStyle _EmptyStyle; + + private PointMarkerVisualStyle _MarkerVisualStyle; + private PointMarkerVisualStyle _MarkerHighlightVisualStyle; + private PointMarkerVisualStyle _MarkerEmptyVisualStyle; + + private ChartLineVisualStyle _ConvexHullLineStyle; + private Background _ConvexHullBackground; + + private ChartSliceVisualStyle _SliceVisualStyle; + + private Color _ItemColor = Color.Empty; + + #endregion + + #region Public properties + + #region BarVisualStyle + + /// + /// Gets or sets the visual style for series Bars. + /// + [Category("Style")] + [Description("Indicates the visual style for series Bars.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartBarVisualStyle BarVisualStyle + { + get + { + if (_BarVisualStyle == null) + { + _BarVisualStyle = new ChartBarVisualStyle(); + + UpdateChangeHandler(null, _BarVisualStyle); + } + + return (_BarVisualStyle); + } + + set + { + if (_BarVisualStyle != value) + { + ChartBarVisualStyle oldValue = _BarVisualStyle; + + _BarVisualStyle = value; + + OnStyleChanged("BarVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ConvexHullBackground + + /// + /// Gets or sets the ConvexHull background. + /// + [Description("Indicates the the ConvexHull background.")] + public Background ConvexHullBackground + { + get + { + if (_ConvexHullBackground == null) + { + _ConvexHullBackground = Background.Empty; + + UpdateChangeHandler(null, _ConvexHullBackground); + } + + return (_ConvexHullBackground); + } + + set + { + if (_ConvexHullBackground != value) + { + UpdateChangeHandler(_ConvexHullBackground, value); + + _ConvexHullBackground = value; + + OnPropertyChangedEx("ConvexHullBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeConvexHullBackground() + { + return (_ConvexHullBackground != null && _ConvexHullBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetConvexHullBackground() + { + ConvexHullBackground = null; + } + + #endregion + + #region ConvexHullLineStyle + + /// + /// Gets or sets the visual style for the ConvexHull Lines. + /// + [Category("Style")] + [Description("Indicates the visual style for the ConvexHull Lines.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle ConvexHullLineStyle + { + get + { + if (_ConvexHullLineStyle == null) + { + _ConvexHullLineStyle = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _ConvexHullLineStyle); + } + + return (_ConvexHullLineStyle); + } + + set + { + if (_ConvexHullLineStyle != value) + { + ChartLineVisualStyle oldValue = _ConvexHullLineStyle; + + _ConvexHullLineStyle = value; + + OnStyleChanged("ConvexHullLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region EmptyAreaBackground + + /// + /// Gets or sets the Empty Area Background. + /// + [Description("Indicates the Empty Area Background.")] + public Background EmptyAreaBackground + { + get + { + if (_EmptyAreaBackground == null) + { + _EmptyAreaBackground = Background.Empty; + + UpdateChangeHandler(null, _EmptyAreaBackground); + } + + return (_EmptyAreaBackground); + } + + set + { + if (_EmptyAreaBackground != value) + { + UpdateChangeHandler(_EmptyAreaBackground, value); + + _EmptyAreaBackground = value; + + OnPropertyChangedEx("EmptyAreaBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeEmptyAreaBackground() + { + return (_EmptyAreaBackground != null && _EmptyAreaBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetEmptyAreaBackground() + { + _EmptyAreaBackground = null; + } + + #endregion + + #region EmptyStyle + + /// + /// Gets or sets the visual styles for series EmptyValue Lines. + /// + [Category("Style")] + [Description("Indicates the visual styles for series EmptyValue Lines.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle EmptyStyle + { + get + { + if (_EmptyStyle == null) + { + _EmptyStyle = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _EmptyStyle); + } + + return (_EmptyStyle); + } + + set + { + if (_EmptyStyle != value) + { + ChartLineVisualStyle oldValue = _EmptyStyle; + + _EmptyStyle = value; + + OnStyleChanged("EmptyLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region HiLoBarVisualStyle + + /// + /// Gets or sets the visual style for series Hilo Bars. + /// + [Category("Style")] + [Description("Indicates the visual style for series Hilo Bars.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartHiLoBarVisualStyle HiLoBarVisualStyle + { + get + { + if (_HiLoBarVisualStyle == null) + { + _HiLoBarVisualStyle = new ChartHiLoBarVisualStyle(); + + UpdateChangeHandler(null, _HiLoBarVisualStyle); + } + + return (_HiLoBarVisualStyle); + } + + set + { + if (_HiLoBarVisualStyle != value) + { + ChartHiLoBarVisualStyle oldValue = _HiLoBarVisualStyle; + + _HiLoBarVisualStyle = value; + + OnStyleChanged("HiloBarVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ItemColor + + /// + /// Gets or sets the default color to use for the item. + /// + [Description("Indicates the default color to use for the item")] + public Color ItemColor + { + get { return (_ItemColor); } + + set + { + if (_ItemColor != value) + { + _ItemColor = value; + + OnPropertyChangedEx("ItemColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeItemColor() + { + return (_ItemColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetItemColor() + { + _ItemColor = Color.Empty; + } + + #endregion + + #region LineAreaBackground + + /// + /// Gets or sets the Line Area Background (area under the series 'Line'). + /// + [Description("Indicates the Line Area Background (area under the series 'Line').")] + public Background LineAreaBackground + { + get + { + if (_LineAreaBackground == null) + { + _LineAreaBackground = Background.Empty; + + UpdateChangeHandler(null, _LineAreaBackground); + } + + return (_LineAreaBackground); + } + + set + { + if (_LineAreaBackground != value) + { + UpdateChangeHandler(_LineAreaBackground, value); + + _LineAreaBackground = value; + + OnPropertyChangedEx("LineAreaBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeLineAreaBackground() + { + return (_LineAreaBackground != null && _LineAreaBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetLineAreaBackground() + { + LineAreaBackground = null; + } + + #endregion + + #region LineStyle + + /// + /// Gets or sets the visual styles for series Lines. + /// + [Category("Style")] + [Description("Indicates the visual styles for series Lines.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle LineStyle + { + get + { + if (_LineStyle == null) + { + _LineStyle = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _LineStyle); + } + + return (_LineStyle); + } + + set + { + if (_LineStyle != value) + { + ChartLineVisualStyle oldValue = _LineStyle; + + _LineStyle = value; + + OnStyleChanged("LineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region MarkerEmptyVisualStyle + + /// + /// Gets or sets the visual styles for the Empty PointMarker. + /// + [Category("Style")] + [Description("Indicates the visual styles for the Empty PointMarker.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PointMarkerVisualStyle MarkerEmptyVisualStyle + { + get + { + if (_MarkerEmptyVisualStyle == null) + { + _MarkerEmptyVisualStyle = new PointMarkerVisualStyle(); + + UpdateChangeHandler(null, _MarkerEmptyVisualStyle); + } + + return (_MarkerEmptyVisualStyle); + } + + set + { + if (_MarkerEmptyVisualStyle != value) + { + PointMarkerVisualStyle oldValue = _MarkerEmptyVisualStyle; + + _MarkerEmptyVisualStyle = value; + + OnStyleChanged("MarkerEmptyVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region MarkerHighlightVisualStyle + + /// + /// Gets or sets the visual styles for the PointMarker Highlight. + /// + [Category("Style")] + [Description("Indicates the visual styles for the PointMarker Highlight.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PointMarkerVisualStyle MarkerHighlightVisualStyle + { + get + { + if (_MarkerHighlightVisualStyle == null) + { + _MarkerHighlightVisualStyle = new PointMarkerVisualStyle(); + + UpdateChangeHandler(null, _MarkerHighlightVisualStyle); + } + + return (_MarkerHighlightVisualStyle); + } + + set + { + if (_MarkerHighlightVisualStyle != value) + { + PointMarkerVisualStyle oldValue = _MarkerHighlightVisualStyle; + + _MarkerHighlightVisualStyle = value; + + OnStyleChanged("MarkerHighlightVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region MarkerVisualStyle + + /// + /// Gets or sets the visual styles for the PointMarker. + /// + [Category("Style")] + [Description("Indicates the visual styles for the PointMarker.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PointMarkerVisualStyle MarkerVisualStyle + { + get + { + if (_MarkerVisualStyle == null) + { + _MarkerVisualStyle = new PointMarkerVisualStyle(); + + UpdateChangeHandler(null, _MarkerVisualStyle); + } + + return (_MarkerVisualStyle); + } + + set + { + if (_MarkerVisualStyle != value) + { + PointMarkerVisualStyle oldValue = _MarkerVisualStyle; + + _MarkerVisualStyle = value; + + OnStyleChanged("MarkerVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region SliceVisualStyle + + /// + /// Gets or sets the default visual style for series Pie Slices. + /// + [Category("Style")] + [Description("Indicates the default visual style for series Pie Slices.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSliceVisualStyle SliceVisualStyle + { + get + { + if (_SliceVisualStyle == null) + { + _SliceVisualStyle = new ChartSliceVisualStyle(); + + UpdateChangeHandler(null, _SliceVisualStyle); + } + + return (_SliceVisualStyle); + } + + set + { + if (_SliceVisualStyle != value) + { + ChartSliceVisualStyle oldValue = _SliceVisualStyle; + + _SliceVisualStyle = value; + + OnStyleChanged("SliceVisualStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region SplineAreaBackground + + /// + /// Gets or sets the Spline Area Background (area under the series 'Spline'). + /// + [Description("Indicates the Spline Area Background (area under the series 'Spline').")] + public Background SplineAreaBackground + { + get + { + if (_SplineAreaBackground == null) + { + _SplineAreaBackground = Background.Empty; + + UpdateChangeHandler(null, _SplineAreaBackground); + } + + return (_SplineAreaBackground); + } + + set + { + if (_SplineAreaBackground != value) + { + UpdateChangeHandler(_SplineAreaBackground, value); + + _SplineAreaBackground = value; + + OnPropertyChangedEx("SplineAreaBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeSplineAreaBackground() + { + return (_SplineAreaBackground != null && _SplineAreaBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetSplineAreaBackground() + { + SplineAreaBackground = null; + } + + #endregion + + #region SplineStyle + + /// + /// Gets or sets the visual styles for series Splines. + /// + [Category("Style")] + [Description("Indicates the visual styles for series Splines.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle SplineStyle + { + get + { + if (_SplineStyle == null) + { + _SplineStyle = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _SplineStyle); + } + + return (_SplineStyle); + } + + set + { + if (_SplineStyle != value) + { + ChartLineVisualStyle oldValue = _SplineStyle; + + _SplineStyle = value; + + OnStyleChanged("SplineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region StepLineAreaBackground + + /// + /// Gets or sets the StepLine Area Background (area under the series 'StepLines'). + /// + [Description("Indicates the StepLine Area Background (area under the series 'StepLines').")] + public Background StepLineAreaBackground + { + get + { + if (_StepLineAreaBackground == null) + { + _StepLineAreaBackground = Background.Empty; + + UpdateChangeHandler(null, _StepLineAreaBackground); + } + + return (_StepLineAreaBackground); + } + + set + { + if (_StepLineAreaBackground != value) + { + UpdateChangeHandler(_StepLineAreaBackground, value); + + _StepLineAreaBackground = value; + + OnPropertyChangedEx("StepLineAreaBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeStepLineAreaBackground() + { + return (_StepLineAreaBackground != null && _StepLineAreaBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetStepLineAreaBackground() + { + StepLineAreaBackground = null; + } + + #endregion + + #region StepLineStyle + + /// + /// Gets or sets the visual styles for series Step Lines. + /// + [Category("Style")] + [Description("Indicates the visual styles for series Step Lines.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartCapLineVisualStyle StepLineStyle + { + get + { + if (_StepLineStyle == null) + { + _StepLineStyle = new ChartCapLineVisualStyle(); + + UpdateChangeHandler(null, _StepLineStyle); + } + + return (_StepLineStyle); + } + + set + { + if (_StepLineStyle != value) + { + ChartCapLineVisualStyle oldValue = _StepLineStyle; + + _StepLineStyle = value; + + OnStyleChanged("StepLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region StepLineAltStyle + + /// + /// Gets or sets the visual styles for 'Alternate' series Step Lines. + /// + [Category("Style")] + [Description("Indicates the visual styles for 'Alternate' series Step Lines.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartCapLineVisualStyle StepLineAltStyle + { + get + { + if (_StepLineAltStyle == null) + { + _StepLineAltStyle = new ChartCapLineVisualStyle(); + + UpdateChangeHandler(null, _StepLineAltStyle); + } + + return (_StepLineAltStyle); + } + + set + { + if (_StepLineAltStyle != value) + { + ChartCapLineVisualStyle oldValue = _StepLineAltStyle; + + _StepLineAltStyle = value; + + OnStyleChanged("StepLineAltStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_BarVisualStyle == null || _BarVisualStyle.IsEmpty) && + (_ConvexHullBackground == null || _ConvexHullBackground.IsEmpty == true) && + (_ConvexHullLineStyle == null || _ConvexHullLineStyle.IsEmpty) && + (_EmptyAreaBackground == null || _EmptyAreaBackground.IsEmpty == true) && + (_EmptyStyle == null || _EmptyStyle.IsEmpty) && + (_HiLoBarVisualStyle == null || _HiLoBarVisualStyle.IsEmpty) && + (_ItemColor.IsEmpty) && + (_LineAreaBackground == null || _LineAreaBackground.IsEmpty == true) && + (_LineStyle == null || _LineStyle.IsEmpty) && + (_MarkerVisualStyle == null || _MarkerVisualStyle.IsEmpty) && + (_MarkerHighlightVisualStyle == null || _MarkerHighlightVisualStyle.IsEmpty) && + (_SliceVisualStyle == null || _SliceVisualStyle.IsEmpty) && + (_SplineAreaBackground == null || _SplineAreaBackground.IsEmpty == true) && + (_SplineStyle == null || _SplineStyle.IsEmpty) && + (_StepLineAreaBackground == null || _StepLineAreaBackground.IsEmpty == true) && + (_StepLineStyle == null || _StepLineStyle.IsEmpty) && + (_StepLineAltStyle == null || _StepLineAltStyle.IsEmpty) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartSeriesVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._BarVisualStyle != null && style._BarVisualStyle.IsEmpty == false) + BarVisualStyle.ApplyStyle(style.BarVisualStyle); + + if (style._ConvexHullBackground != null && style._ConvexHullBackground.IsEmpty == false) + ConvexHullBackground = style._ConvexHullBackground.Copy(); + + if (style._ConvexHullLineStyle != null && style.ConvexHullLineStyle.IsEmpty == false) + ConvexHullLineStyle.ApplyStyle(style.ConvexHullLineStyle); + + if (style._EmptyAreaBackground != null && style._EmptyAreaBackground.IsEmpty == false) + EmptyAreaBackground = style._EmptyAreaBackground.Copy(); + + if (style._EmptyStyle != null && style.EmptyStyle.IsEmpty == false) + EmptyStyle.ApplyStyle(style.EmptyStyle); + + if (style._HiLoBarVisualStyle != null && style._HiLoBarVisualStyle.IsEmpty == false) + HiLoBarVisualStyle.ApplyStyle(style.HiLoBarVisualStyle); + + if (style.ItemColor.IsEmpty == false) + ItemColor = style.ItemColor; + + if (style._LineAreaBackground != null && style._LineAreaBackground.IsEmpty == false) + LineAreaBackground = style._LineAreaBackground.Copy(); + + if (style._LineStyle != null && style.LineStyle.IsEmpty == false) + LineStyle.ApplyStyle(style.LineStyle); + + if (style._MarkerEmptyVisualStyle != null && style.MarkerEmptyVisualStyle.IsEmpty == false) + MarkerEmptyVisualStyle.ApplyStyle(style.MarkerEmptyVisualStyle); + + if (style._MarkerHighlightVisualStyle != null && style.MarkerHighlightVisualStyle.IsEmpty == false) + MarkerHighlightVisualStyle.ApplyStyle(style.MarkerHighlightVisualStyle); + + if (style._MarkerVisualStyle != null && style.MarkerVisualStyle.IsEmpty == false) + MarkerVisualStyle.ApplyStyle(style.MarkerVisualStyle); + + if (style._HiLoBarVisualStyle != null && style._HiLoBarVisualStyle.IsEmpty == false) + HiLoBarVisualStyle.ApplyStyle(style.HiLoBarVisualStyle); + + if (style._SliceVisualStyle != null && style._SliceVisualStyle.IsEmpty == false) + SliceVisualStyle.ApplyStyle(style.SliceVisualStyle); + + if (style._SplineAreaBackground != null && style._SplineAreaBackground.IsEmpty == false) + SplineAreaBackground = style._SplineAreaBackground.Copy(); + + if (style._SplineStyle != null && style.SplineStyle.IsEmpty == false) + SplineStyle.ApplyStyle(style.SplineStyle); + + if (style._StepLineAreaBackground != null && style._StepLineAreaBackground.IsEmpty == false) + StepLineAreaBackground = style._StepLineAreaBackground.Copy(); + + if (style._StepLineStyle != null && style.StepLineStyle.IsEmpty == false) + StepLineStyle.ApplyStyle(style.StepLineStyle); + + if (style._StepLineAltStyle != null && style.StepLineAltStyle.IsEmpty == false) + StepLineAltStyle.ApplyStyle(style.StepLineAltStyle); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartSeriesVisualStyle Copy() + { + ChartSeriesVisualStyle style = new ChartSeriesVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartSeriesVisualStyle style) + { + base.CopyTo(style); + + style.BarVisualStyle = (_BarVisualStyle != null) ? _BarVisualStyle.Copy() : null; + + style.ConvexHullBackground = (_ConvexHullBackground != null) ? _ConvexHullBackground.Copy() : null; + style.ConvexHullLineStyle = (_ConvexHullLineStyle != null) ? _ConvexHullLineStyle.Copy() : null; + + style.EmptyAreaBackground = (_EmptyAreaBackground != null) ? _EmptyAreaBackground.Copy() : null; + style.EmptyStyle = (_EmptyStyle != null) ? _EmptyStyle.Copy() : null; + + style.HiLoBarVisualStyle = (_HiLoBarVisualStyle != null) ? _HiLoBarVisualStyle.Copy() : null; + style.ItemColor = ItemColor; + + style.LineAreaBackground = (_LineAreaBackground != null) ? _LineAreaBackground.Copy() : null; + style.LineStyle = (_LineStyle != null) ? _LineStyle.Copy() : null; + + style.MarkerEmptyVisualStyle = (_MarkerEmptyVisualStyle != null) ? _MarkerEmptyVisualStyle.Copy() : null; + style.MarkerHighlightVisualStyle = (_MarkerHighlightVisualStyle != null) ? _MarkerHighlightVisualStyle.Copy() : null; + style.MarkerVisualStyle = (_MarkerVisualStyle != null) ? _MarkerVisualStyle.Copy() : null; + + style.SliceVisualStyle = (_SliceVisualStyle != null) ? _SliceVisualStyle.Copy() : null; + + style.SplineAreaBackground = (_SplineAreaBackground != null) ? _SplineAreaBackground.Copy() : null; + style.SplineStyle = (_SplineStyle != null) ? _SplineStyle.Copy() : null; + + style.StepLineAltStyle = (_StepLineAltStyle != null) ? _StepLineAltStyle.Copy() : null; + style.StepLineAreaBackground = (_StepLineAreaBackground != null) ? _StepLineAreaBackground.Copy() : null; + style.StepLineStyle = (_StepLineStyle != null) ? _StepLineStyle.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartSeriesVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_BarVisualStyle != null && _BarVisualStyle.IsEmpty == false) + sec.AddElement(_BarVisualStyle.GetSerialData("BarVisualStyle")); + + if (_ConvexHullBackground != null && _ConvexHullBackground.IsEmpty == false) + sec.AddElement(_ConvexHullBackground.GetSerialData("ConvexHullBackground")); + + if (_ConvexHullLineStyle != null && _ConvexHullLineStyle.IsEmpty == false) + sec.AddElement(_ConvexHullLineStyle.GetSerialData("ConvexHullLineStyle")); + + if (_EmptyAreaBackground != null && _EmptyAreaBackground.IsEmpty == false) + sec.AddElement(_EmptyAreaBackground.GetSerialData("EmptyAreaBackground")); + + if (_EmptyStyle != null && _EmptyStyle.IsEmpty == false) + sec.AddElement(_EmptyStyle.GetSerialData("EmptyStyle")); + + sec.AddValue("ItemColor", ItemColor, Color.Empty); + + if (_HiLoBarVisualStyle != null && _HiLoBarVisualStyle.IsEmpty == false) + sec.AddElement(_HiLoBarVisualStyle.GetSerialData("HiLoBarVisualStyle")); + + if (_LineAreaBackground != null && _LineAreaBackground.IsEmpty == false) + sec.AddElement(_LineAreaBackground.GetSerialData("LineAreaBackground")); + + if (_LineStyle != null && _LineStyle.IsEmpty == false) + sec.AddElement(_LineStyle.GetSerialData("LineStyle")); + + if (_MarkerEmptyVisualStyle != null && _MarkerEmptyVisualStyle.IsEmpty == false) + sec.AddElement(_MarkerEmptyVisualStyle.GetSerialData("MarkerEmptyVisualStyle")); + + if (_MarkerHighlightVisualStyle != null && _MarkerHighlightVisualStyle.IsEmpty == false) + sec.AddElement(_MarkerHighlightVisualStyle.GetSerialData("MarkerHighlightVisualStyle")); + + if (_MarkerVisualStyle != null && _MarkerVisualStyle.IsEmpty == false) + sec.AddElement(_MarkerVisualStyle.GetSerialData("MarkerVisualStyle")); + + if (_SplineAreaBackground != null && _SplineAreaBackground.IsEmpty == false) + sec.AddElement(_SplineAreaBackground.GetSerialData("SplineAreaBackground")); + + if (_SplineStyle != null && _SplineStyle.IsEmpty == false) + sec.AddElement(_SplineStyle.GetSerialData("SplineStyle")); + + if (_StepLineAreaBackground != null && _StepLineAreaBackground.IsEmpty == false) + sec.AddElement(_StepLineAreaBackground.GetSerialData("StepLineAreaBackground")); + + if (_StepLineStyle != null && _StepLineStyle.IsEmpty == false) + sec.AddElement(_StepLineStyle.GetSerialData("StepLineStyle")); + + if (_StepLineAltStyle != null && _StepLineAltStyle.IsEmpty == false) + sec.AddElement(_StepLineAltStyle.GetSerialData("StepLineAltStyle")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "ItemColor": + ItemColor = se.GetValueColor(); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "BarVisualStyle": + sec.PutSerialData(BarVisualStyle); + break; + + case "ConvexHullBackground": + sec.PutSerialData(ConvexHullBackground); + break; + + case "ConvexHullLineStyle": + sec.PutSerialData(ConvexHullLineStyle); + break; + + case "EmptyAreaBackground": + sec.PutSerialData(EmptyAreaBackground); + break; + + case "EmptyStyle": + sec.PutSerialData(EmptyStyle); + break; + + case "HiLoBarVisualStyle": + sec.PutSerialData(HiLoBarVisualStyle); + break; + + case "LineAreaBackground": + sec.PutSerialData(LineAreaBackground); + break; + + case "LineStyle": + sec.PutSerialData(LineStyle); + break; + + case "MarkerEmptyVisualStyle": + sec.PutSerialData(MarkerEmptyVisualStyle); + break; + + case "MarkerHighlightVisualStyle": + sec.PutSerialData(MarkerHighlightVisualStyle); + break; + + case "MarkerVisualStyle": + sec.PutSerialData(MarkerVisualStyle); + break; + + case "SplineAreaBackground": + sec.PutSerialData(SplineAreaBackground); + break; + + case "SplineStyle": + sec.PutSerialData(SplineStyle); + break; + + case "StepLineAreaBackground": + sec.PutSerialData(StepLineAreaBackground); + break; + + case "StepLineStyle": + sec.PutSerialData(StepLineStyle); + break; + + case "StepLineAltStyle": + sec.PutSerialData(StepLineAltStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + BarVisualStyle = null; + ConvexHullBackground = null; + ConvexHullLineStyle = null; + EmptyAreaBackground = null; + EmptyStyle = null; + HiLoBarVisualStyle = null; + LineAreaBackground = null; + LineStyle = null; + MarkerEmptyVisualStyle = null; + MarkerHighlightVisualStyle = null; + MarkerVisualStyle = null; + SliceVisualStyle = null; + SplineAreaBackground = null; + SplineStyle = null; + StepLineAreaBackground = null; + StepLineStyle = null; + StepLineAreaBackground = null; + StepLineStyle = null; + StepLineAltStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartSliceVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartSliceVisualStyle.cs new file mode 100644 index 00000000..4b10b22d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartSliceVisualStyle.cs @@ -0,0 +1,1824 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// ChartSliceVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartSliceVisualStyles : VisualStyles + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public ChartSliceVisualStyles Copy() + { + ChartSliceVisualStyles styles = new ChartSliceVisualStyles(); + + for (int i = 0; i < Styles.Length; i++) + { + ChartSliceVisualStyle vstyle = Styles[i]; + + if (vstyle != null) + styles.Styles[i] = vstyle.Copy(); + } + + return (styles); + } + + #endregion + } + + /// + /// Represents the visual style of a series Slice. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartSliceVisualStyle : BaseVisualStyle + { + #region Private variables + + private SymbolDef _SymbolDef; + + private SliceInnerLabelVisualStyle _SliceInnerLabelStyle; + private SliceOuterLabelVisualStyle _SliceOuterLabelStyle; + + private PieReferenceLineVisualStyle _ExtentMaxRefLineStyle; + private PieReferenceLineVisualStyle _ExtentMinRefLineStyle; + private PieReferenceLineVisualStyle _ExtentAverageRefLineStyle; + private PieReferenceLineVisualStyle _ExtentOuterRefLineStyle; + + private Background _Background; + private ChartLineVisualStyle _Border; + + private Background _WhiteSpaceBackground; + private ChartLineVisualStyle _WhiteSpaceBorder; + + private Image _Image; + private int _ImageIndex = -1; + private ImageList _ImageList; + + private double _ImageRotation = double.NaN; + private Tbool _ImageAutoRotate = Tbool.NotSet; + + private double _ImageRadiusOffset = double.NaN; + private double _ImageAngleOffset = double.NaN; + + private double _ImageScale = double.NaN; + private ImageOverlay _ImageOverlay = ImageOverlay.NotSet; + + private Padding _ImagePadding; + + private SliceImageCropMode _ImageCropMode = SliceImageCropMode.NotSet; + private SliceImageRadiusAnchor _ImageInnerRadiusAnchor = SliceImageRadiusAnchor.NotSet; + private SliceImageRadiusAnchor _ImageOuterRadiusAnchor = SliceImageRadiusAnchor.NotSet; + + private Tbool _EnableShading = Tbool.NotSet; + + private ExtentFillRange _ExtentFillRange = ExtentFillRange.NotSet; + + #endregion + + #region Public properties + + #region Background + + /// + /// Gets or sets the background style for the slice. + /// + [Description("Indicates the background style for the slice")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region ExtentFillRange + + /// + /// Gets or sets the range area used to fill the slice extent + /// background. + /// + [DefaultValue(ExtentFillRange.NotSet), Category("Behavior")] + [Description("Indicatesthe range area used to fill the slice extent background.")] + public ExtentFillRange ExtentFillRange + { + get { return (_ExtentFillRange); } + + set + { + if (value != _ExtentFillRange) + { + _ExtentFillRange = value; + + OnPropertyChangedEx("ExtentFillRange", VisualChangeType.Render); + } + } + } + + #endregion + + #region Border + + /// + /// Gets or sets the visual style for the slice border. + /// + [Category("Style")] + [Description("Indicates the visual styles for the slice border.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle Border + { + get + { + if (_Border == null) + { + _Border = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _Border); + } + + return (_Border); + } + + set + { + if (_Border != value) + { + ChartLineVisualStyle oldValue = _Border; + + _Border = value; + + OnStyleChanged("Border", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region EnableShading + + /// + /// Gets or sets whether shading is applie to the pie slice. + /// + [DefaultValue(Tbool.NotSet), Category("Behavior")] + [Description("Indicates whether shading is applie to the pie slice.")] + public Tbool EnableShading + { + get { return (_EnableShading); } + + set + { + if (value != _EnableShading) + { + _EnableShading = value; + + OnPropertyChangedEx("EnableShading", VisualChangeType.Render); + } + } + } + + #endregion + + #region Image + + /// + /// Gets or sets the slice Image. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the slice image.")] + public Image Image + { + get { return (_Image); } + + set + { + if (_Image != value) + { + _Image = value; + + OnPropertyChangedEx("Image", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageAngleOffset + + /// + /// Gets or sets the display angle offset for the slice image. By default, the image is + /// centered in the pie slice (mid sweepAngle), but can be offset either + /// toward the end angle (positive offset) or toward the start angle + /// (negative offset). The offset can either be a percentage (if value is + /// between 0 and 1) or pixel amount (if value > 1). + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the display angle offset for the slice image. By default, the image is centered in the pie slice (mid sweepAngle), but can be offset either toward the end angle (positive offset) or toward the start angle (negative offset). The offset can either be a percentage (if value is between 0 and 1) or pixel amount (if value > 1).")] + [Editor("DevComponents.Charts.Design.AngleOffsetRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double ImageAngleOffset + { + get { return (_ImageAngleOffset); } + + set + { + if (value != _ImageAngleOffset) + { + _ImageAngleOffset = value; + + OnPropertyChangedEx("ImageAngleOffset", VisualChangeType.Render); + } + } + } + + #endregion + + #region ImageAutoRotate + + /// + /// Gets or sets whether the Image (or Symbol) is auto + /// rotated to match the angle of the slice. + /// + [DefaultValue(Tbool.NotSet), Category("Display")] + [Description("Indicates whether the Image (or Symbol) is auto rotated to match the angle of the slice.")] + public Tbool ImageAutoRotate + { + get { return (_ImageAutoRotate); } + + set + { + if (value != _ImageAutoRotate) + { + _ImageAutoRotate = value; + + OnPropertyChangedEx("ImageAutoRotate", VisualChangeType.Render); + } + } + } + + #endregion + + #region ImageCropMode + + /// + /// Gets or sets how the slice image will be displayed when + /// the image needs to be cropped due to 'angular' size constraints + /// (ie. will not fully fit within the slice angular bounds). + /// Default is ClipImage. + /// + [DefaultValue(SliceImageCropMode.NotSet), Category("Display")] + [Description("Indicates how the slice image will be displayed when the image needs to be cropped due to 'angular' size constraints (ie. will not fully fit within the slice angular bounds). Default is ClipImage.")] + public SliceImageCropMode ImageCropMode + { + get { return (_ImageCropMode); } + + set + { + if (value != _ImageCropMode) + { + _ImageCropMode = value; + + OnPropertyChangedEx("ImageCropMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ImageIndex + + /// + /// Gets or sets the slice image index (used with the ImageList property). + /// + [DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the slice image index (used with the ImageList property)")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int ImageIndex + { + get { return (_ImageIndex); } + + set + { + if (_ImageIndex != value) + { + _ImageIndex = value; + + OnPropertyChangedEx("ImageIndex", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageInnerRadiusAnchor + + /// + /// Gets or sets the inner radius anchor for the slice image (ie. + /// the inner limiting radius - used with the ImageRadiusOffset property). + /// + [DefaultValue(SliceImageRadiusAnchor.NotSet), Category("Display")] + [Description("Indicates the inner radius anchor for the slice image (ie. the inner limiting radius - used with the ImageRadiusOffset property).")] + public SliceImageRadiusAnchor ImageInnerRadiusAnchor + { + get { return (_ImageInnerRadiusAnchor); } + + set + { + if (value != _ImageInnerRadiusAnchor) + { + _ImageInnerRadiusAnchor = value; + + OnPropertyChangedEx("ImageInnerRadiusAnchor", VisualChangeType.Render); + } + } + } + + #endregion + + #region ImageList + + /// + /// Gets or sets the slice ImageList. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates the slice ImageList.")] + public ImageList ImageList + { + get { return (_ImageList); } + + set + { + if (_ImageList != value) + { + _ImageList = value; + + OnPropertyChangedEx("ImageList", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageOuterRadiusAnchor + + /// + /// Gets or sets the Outer radius anchor for the slice image (ie. + /// the Outer limiting radius - used with the ImageRadiusOffset percentage). + /// + [DefaultValue(SliceImageRadiusAnchor.NotSet), Category("Display")] + [Description("Indicates the Outer radius anchor for the slice image (ie. the Outer limiting radius - used with the ImageRadiusOffset percentage).")] + public SliceImageRadiusAnchor ImageOuterRadiusAnchor + { + get { return (_ImageOuterRadiusAnchor); } + + set + { + if (value != _ImageOuterRadiusAnchor) + { + _ImageOuterRadiusAnchor = value; + + OnPropertyChangedEx("ImageOuterRadiusAnchor", VisualChangeType.Render); + } + } + } + + #endregion + + #region ImageOverlay + + /// + /// Gets or sets how to overlay the image with respect to the slice text. + /// + [DefaultValue(ImageOverlay.NotSet), Category("Appearance")] + [Description("Indicates how to overlay the image with respect to the slice text..")] + public ImageOverlay ImageOverlay + { + get { return (_ImageOverlay); } + + set + { + if (_ImageOverlay != value) + { + _ImageOverlay = value; + + OnPropertyChangedEx("ImageOverlay", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImagePadding + + /// + /// Gets or sets the spacing between content and edges of the Image + /// + [Description("Indicates the spacing between content and edges of the Image")] + public Padding ImagePadding + { + get + { + if (_ImagePadding == null) + { + _ImagePadding = Padding.Empty; + + UpdateChangeHandler(null, _ImagePadding); + } + + return (_ImagePadding); + } + + set + { + if (_ImagePadding != value) + { + UpdateChangeHandler(_ImagePadding, value); + + _ImagePadding = value; + + OnPropertyChangedEx("ImagePadding", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeImagePadding() + { + return (_ImagePadding != null && _ImagePadding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetImagePadding() + { + ImagePadding = null; + } + + #endregion + + #region ImageRadiusOffset + + /// + /// Gets or sets the display radius for the slice image. The image can be offset + /// toward the outer radius (positive offset) or toward the inner radius + /// (negative offset). The offset can either be a percentage (if value is + /// between 0 and 1) or pixel amount (if value > 1). + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the display radius for the slice image. The image can be offset toward the outer radius (positive offset) or toward the inner radius (negative offset). The offset can either be a percentage (if value is between 0 and 1) or pixel amount (if value > 1).")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double ImageRadiusOffset + { + get { return (_ImageRadiusOffset); } + + set + { + if (value != _ImageRadiusOffset) + { + _ImageRadiusOffset = value; + + OnPropertyChangedEx("ImageRadiusOffset", VisualChangeType.Render); + } + } + } + + #endregion + + #region ImageRotation + + /// + /// Gets or sets the amount to rotate the image, specified in degrees. + /// + [Description("Indicates the amount to rotate the image, specified in degrees.")] + [DefaultValue(double.NaN)] + [Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double ImageRotation + { + get { return (_ImageRotation); } + + set + { + if (value != _ImageRotation) + { + _ImageRotation = value; + + OnPropertyChangedEx("ImageRotation", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageScale + + /// + /// Gets or sets the 'scale' factor for the image/symbol. This property informs the + /// chart to scale the image (or symbol) based upon the available space at its offset + /// position in the slice - the image is moved in or out of the slice, the image will + /// grow of shrink accordingly. + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the 'scale' factor for the image/symbol. This property informs the chart to scale the image (or symbol) based upon the available space at its offset position in the slice - the image is moved in or out of the slice, the image will grow of shrink accordingly.")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double ImageScale + { + get { return (_ImageScale); } + + set + { + if (value != _ImageScale) + { + if (value < 0) + throw new Exception("ImageScale can not be negative."); + + _ImageScale = value; + + OnPropertyChangedEx("ImageScale", VisualChangeType.Render); + } + } + } + + #endregion + + #region ExtentAverageRefLineStyle + + /// + /// Gets or sets the visual style for the slice Extent Average + /// ReferenceLine style (see SliceVisualLayout.ReferenceLineDisplayMode). + /// + [Category("Style")] + [Description("Indicates the visual style for the slice Extent Average ReferenceLine style (see SliceVisualLayout.ReferenceLineDisplayMode).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieReferenceLineVisualStyle ExtentAverageRefLineStyle + { + get + { + if (_ExtentAverageRefLineStyle == null) + { + _ExtentAverageRefLineStyle = new PieReferenceLineVisualStyle(); + + UpdateChangeHandler(null, _ExtentAverageRefLineStyle); + } + + return (_ExtentAverageRefLineStyle); + } + + set + { + if (_ExtentAverageRefLineStyle != value) + { + PieReferenceLineVisualStyle oldValue = _ExtentAverageRefLineStyle; + + _ExtentAverageRefLineStyle = value; + + OnStyleChanged("ExtentAverageRefLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ExtentMaxRefLineStyle + + /// + /// Gets or sets the visual style for the slice Extent Maximum + /// ReferenceLine style (see SliceVisualLayout.ReferenceLineDisplayMode). + /// + [Category("Style")] + [Description("Indicates the visual style for the slice Extent Maximum ReferenceLine style (see SliceVisualLayout.ReferenceLineDisplayMode).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieReferenceLineVisualStyle ExtentMaxRefLineStyle + { + get + { + if (_ExtentMaxRefLineStyle == null) + { + _ExtentMaxRefLineStyle = new PieReferenceLineVisualStyle(); + + UpdateChangeHandler(null, _ExtentMaxRefLineStyle); + } + + return (_ExtentMaxRefLineStyle); + } + + set + { + if (_ExtentMaxRefLineStyle != value) + { + PieReferenceLineVisualStyle oldValue = _ExtentMaxRefLineStyle; + + _ExtentMaxRefLineStyle = value; + + OnStyleChanged("ExtentMaxRefLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ExtentMinRefLineStyle + + /// + /// Gets or sets the visual style for the slice Extent Minimum + /// ReferenceLine style (see SliceVisualLayout.ReferenceLineDisplayMode). + /// + [Category("Style")] + [Description("Indicates the visual style for the slice Extent Minimum ReferenceLine style (see SliceVisualLayout.ReferenceLineDisplayMode).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieReferenceLineVisualStyle ExtentMinRefLineStyle + { + get + { + if (_ExtentMinRefLineStyle == null) + { + _ExtentMinRefLineStyle = new PieReferenceLineVisualStyle(); + + UpdateChangeHandler(null, _ExtentMinRefLineStyle); + } + + return (_ExtentMinRefLineStyle); + } + + set + { + if (_ExtentMinRefLineStyle != value) + { + PieReferenceLineVisualStyle oldValue = _ExtentMinRefLineStyle; + + _ExtentMinRefLineStyle = value; + + OnStyleChanged("ExtentMinRefLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ExtentOuterRefLineStyle + + /// + /// Gets or sets the visual style for the slice Extent Outer + /// ReferenceLine style (see SliceVisualLayout.ReferenceLineDisplayMode). + /// + [Category("Style")] + [Description("Indicates the visual style for the slice Extent Outer ReferenceLine style (see SliceVisualLayout.ReferenceLineDisplayMode).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieReferenceLineVisualStyle ExtentOuterRefLineStyle + { + get + { + if (_ExtentOuterRefLineStyle == null) + { + _ExtentOuterRefLineStyle = new PieReferenceLineVisualStyle(); + + UpdateChangeHandler(null, _ExtentOuterRefLineStyle); + } + + return (_ExtentOuterRefLineStyle); + } + + set + { + if (_ExtentOuterRefLineStyle != value) + { + PieReferenceLineVisualStyle oldValue = _ExtentOuterRefLineStyle; + + _ExtentOuterRefLineStyle = value; + + OnStyleChanged("ExtentOuterRefLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region SliceInnerLabelStyle + + /// + /// Gets or sets the visual style for the inner slice Label. + /// + [Category("Style")] + [Description("Indicates the visual style for the inner slice Label.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SliceInnerLabelVisualStyle SliceInnerLabelStyle + { + get + { + if (_SliceInnerLabelStyle == null) + { + _SliceInnerLabelStyle = new SliceInnerLabelVisualStyle(); + + UpdateChangeHandler(null, _SliceInnerLabelStyle); + } + + return (_SliceInnerLabelStyle); + } + + set + { + if (value != _SliceInnerLabelStyle) + { + SliceInnerLabelVisualStyle oldValue = _SliceInnerLabelStyle; + + _SliceInnerLabelStyle = value; + + OnStyleChanged("SliceInnerLabelStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region SliceOuterLabelStyle + + /// + /// Gets or sets the visual style for the outer slice Label. + /// + [Category("Style")] + [Description("Indicates the visual style for the outer slice Label.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SliceOuterLabelVisualStyle SliceOuterLabelStyle + { + get + { + if (_SliceOuterLabelStyle == null) + { + _SliceOuterLabelStyle = new SliceOuterLabelVisualStyle(); + + UpdateChangeHandler(null, _SliceOuterLabelStyle); + } + + return (_SliceOuterLabelStyle); + } + + set + { + if (value != _SliceOuterLabelStyle) + { + SliceOuterLabelVisualStyle oldValue = _SliceOuterLabelStyle; + + _SliceOuterLabelStyle = value; + + OnStyleChanged("SliceOuterLabelStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region SymbolDef + + /// + /// Gets or sets the element Symbol Definition. Note that Symbol definition + /// takes precedence over Image definition. Also note that the supporting Image + /// properties (such as ImageCrpoMode, ImageRadiusOffset, etc) apply to a set + /// Symbol as well as to a set Image. + /// + [DefaultValue(null), Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Description("Indicates the element Symbol Definition. Note that Symbol definition takes precedence over Image definition. Also note that the supporting Image properties (such as ImageCrpoMode, ImageRadiusOffset, etc) apply to a set Symbol as well as to a set Image")] + public SymbolDef SymbolDef + { + get + { + if (_SymbolDef == null) + { + _SymbolDef = new SymbolDef(); + + UpdateChangeHandler(null, _SymbolDef); + } + + return (_SymbolDef); + } + + set + { + if (_SymbolDef != value) + { + UpdateChangeHandler(_SymbolDef, value); + + _SymbolDef = value; + + OnPropertyChangedEx("SymbolDef", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeSymbolDef() + { + return (_SymbolDef != null && _SymbolDef.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetSymbolDef() + { + SymbolDef = null; + } + + #endregion + + #region WhiteSpaceBackground + + /// + /// Gets or sets the WhiteSpace Background (area beyond the slice extent area). + /// + [Description("Indicates the WhiteSpace Background (area beyond the slice extent area).")] + public Background WhiteSpaceBackground + { + get + { + if (_WhiteSpaceBackground == null) + { + _WhiteSpaceBackground = Background.Empty; + + UpdateChangeHandler(null, _WhiteSpaceBackground); + } + + return (_WhiteSpaceBackground); + } + + set + { + if (_WhiteSpaceBackground != value) + { + UpdateChangeHandler(_WhiteSpaceBackground, value); + + _WhiteSpaceBackground = value; + + OnPropertyChangedEx("WhiteSpaceBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeWhiteSpaceBackground() + { + return (_WhiteSpaceBackground != null && + _WhiteSpaceBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetWhiteSpaceBackground() + { + WhiteSpaceBackground = null; + } + + #endregion + + #region WhiteSpaceBorder + + /// + /// Gets or sets the visual style for the slice WhiteSpace Border. + /// + [Category("Style")] + [Description("Indicates the visual styles for the slice WhiteSpace Border.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle WhiteSpaceBorder + { + get + { + if (_WhiteSpaceBorder == null) + { + _WhiteSpaceBorder = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _WhiteSpaceBorder); + } + + return (_WhiteSpaceBorder); + } + + set + { + if (_WhiteSpaceBorder != value) + { + ChartLineVisualStyle oldValue = _WhiteSpaceBorder; + + _WhiteSpaceBorder = value; + + OnStyleChanged("WhiteSpaceBorder", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Background == null || _Background.IsEmpty == true) && + (_Border == null || _Border.IsEmpty == true) && + (_EnableShading == Tbool.NotSet) && + (_ExtentAverageRefLineStyle == null || _ExtentAverageRefLineStyle.IsEmpty) && + (_ExtentMaxRefLineStyle == null || _ExtentMaxRefLineStyle.IsEmpty) && + (_ExtentMinRefLineStyle == null || _ExtentMinRefLineStyle.IsEmpty) && + (_ExtentOuterRefLineStyle == null || _ExtentOuterRefLineStyle.IsEmpty) && + (_Image == null) && + (double.IsNaN(_ImageAngleOffset) == true) && + (_ImageAutoRotate == Tbool.NotSet) && + (_ImageCropMode == SliceImageCropMode.NotSet) && + (_ImageIndex == -1) && + (_ImageInnerRadiusAnchor == SliceImageRadiusAnchor.NotSet) && + (_ImageList == null) && + (_ImageOuterRadiusAnchor == SliceImageRadiusAnchor.NotSet) && + (_ImageOverlay == ImageOverlay.NotSet) && + (_ImagePadding == null || _ImagePadding.IsEmpty == true) && + (double.IsNaN(_ImageRadiusOffset) == true) && + (double.IsNaN(_ImageRotation) == true) && + (double.IsNaN(_ImageScale) == true) && + (_SliceInnerLabelStyle == null || _SliceInnerLabelStyle.IsEmpty) && + (_SliceOuterLabelStyle == null || _SliceOuterLabelStyle.IsEmpty) && + (_SymbolDef == null || _SymbolDef.IsEmpty == true) && + (_WhiteSpaceBackground == null || _WhiteSpaceBackground.IsEmpty == true) && + (_WhiteSpaceBorder == null || _WhiteSpaceBorder.IsEmpty == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region IsSymbolFigure + + internal bool IsSymbolFigure + { + get { return (_SymbolDef != null && _SymbolDef.IsValidSymbol == true); } + } + + #endregion + + #region IsValidFigure + + internal bool IsValidFigure + { + get + { + if (IsSymbolFigure == true) + return (true); + + return (GetImage() != null); + } + } + + #endregion + + #endregion + + #region GetFigure + + internal object GetFigure() + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false && _SymbolDef.SymbolSize > 0) + return (_SymbolDef); + + return (GetImage()); + } + + #region GetImage + + internal Image GetImage() + { + if (_Image != null) + return (_Image); + + if (_ImageIndex >= 0) + { + ImageList imageList = ImageList; + + if (imageList != null && _ImageIndex < imageList.Images.Count) + return (imageList.Images[_ImageIndex]); + } + + return (null); + } + + #endregion + + #region GetSymbol + + internal string GetSymbol() + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + return (_SymbolDef.SymbolRealized); + + return (null); + } + + #endregion + + #endregion + + #region GetFigureSize + + internal Size GetFigureSize(Graphics g) + { + Size size = Size.Empty; + + if (IsSymbolFigure == true) + size = _SymbolDef.GetSymbolSize(g); + + else + { + Image image = GetImage(); + + if (image != null) + size = Dpi.Size(image.Size); + } + + if (size.IsEmpty == false) + { + size.Width += Dpi.Width(ImagePadding.Horizontal); + size.Height += Dpi.Height(ImagePadding.Vertical); + } + + return (size); + } + + #endregion + + #region GetFigureSizeEx + + internal Size GetFigureSizeEx(Graphics g) + { + Size size = Size.Empty; + + if (IsSymbolFigure == true) + size = _SymbolDef.GetSymbolSize(g); + + else + { + Image image = GetImage(); + + if (image != null) + size = Dpi.Size(image.Size); + } + + return (size); + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartSliceVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style._Border != null && style._Border.IsEmpty == false) + Border.ApplyStyle(style._Border); + + if (style._EnableShading != Tbool.NotSet) + EnableShading = style._EnableShading; + + if (style._ExtentAverageRefLineStyle != null && style._ExtentAverageRefLineStyle.IsEmpty == false) + ExtentAverageRefLineStyle.ApplyStyle(style._ExtentAverageRefLineStyle); + + if (style._ExtentFillRange != ExtentFillRange.NotSet) + ExtentFillRange = style._ExtentFillRange; + + if (style._ExtentMaxRefLineStyle != null && style._ExtentMaxRefLineStyle.IsEmpty == false) + ExtentMaxRefLineStyle.ApplyStyle(style._ExtentMaxRefLineStyle); + + if (style._ExtentMinRefLineStyle != null && style._ExtentMinRefLineStyle.IsEmpty == false) + ExtentMinRefLineStyle.ApplyStyle(style._ExtentMinRefLineStyle); + + if (style._ExtentOuterRefLineStyle != null && style._ExtentOuterRefLineStyle.IsEmpty == false) + ExtentOuterRefLineStyle.ApplyStyle(style._ExtentOuterRefLineStyle); + + if (style.Image != null) + Image = style.Image; + + if (double.IsNaN(style.ImageAngleOffset) == false) + ImageAngleOffset = style.ImageAngleOffset; + + if (style._ImageAutoRotate != Tbool.NotSet) + ImageAutoRotate = style._ImageAutoRotate; + + if (style._ImageCropMode != SliceImageCropMode.NotSet) + ImageCropMode = style._ImageCropMode; + + if (style._ImageIndex >= 0) + ImageIndex = style._ImageIndex; + + if (style._ImageInnerRadiusAnchor != SliceImageRadiusAnchor.NotSet) + ImageInnerRadiusAnchor = style._ImageInnerRadiusAnchor; + + if (style._ImageList != null) + ImageList = style._ImageList; + + if (style._ImageOuterRadiusAnchor != SliceImageRadiusAnchor.NotSet) + ImageOuterRadiusAnchor = style._ImageOuterRadiusAnchor; + + if (style._ImageOverlay != ImageOverlay.NotSet) + ImageOverlay = style._ImageOverlay; + + if (style._ImagePadding != null && style._ImagePadding.IsEmpty == false) + ImagePadding = style._ImagePadding.Copy(); + + if (double.IsNaN(style.ImageRadiusOffset) == false) + ImageRadiusOffset = style._ImageRadiusOffset; + + if (double.IsNaN(style.ImageRotation) == false) + ImageRotation = style.ImageRotation; + + if (double.IsNaN(style._ImageScale) == false) + ImageScale = style._ImageScale; + + if (style._SliceInnerLabelStyle != null && style._SliceInnerLabelStyle.IsEmpty == false) + SliceInnerLabelStyle.ApplyStyle(style._SliceInnerLabelStyle); + + if (style._SliceOuterLabelStyle != null && style._SliceOuterLabelStyle.IsEmpty == false) + SliceOuterLabelStyle.ApplyStyle(style._SliceOuterLabelStyle); + + if (style._SymbolDef != null && style._SymbolDef.IsEmpty == false) + SymbolDef = style._SymbolDef.Copy(); + + if (style._WhiteSpaceBackground != null && style._WhiteSpaceBackground.IsEmpty == false) + WhiteSpaceBackground = style._WhiteSpaceBackground.Copy(); + + if (style._WhiteSpaceBorder != null && style._WhiteSpaceBorder.IsEmpty == false) + WhiteSpaceBorder = style._WhiteSpaceBorder.Copy(); + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (_Border != null) + Border.ApplyDefaults(); + + ExtentAverageRefLineStyle.ApplyDefaults(); + ExtentMaxRefLineStyle.ApplyDefaults(); + ExtentMinRefLineStyle.ApplyDefaults(); + ExtentOuterRefLineStyle.ApplyDefaults(); + + if (_EnableShading == Tbool.NotSet) + EnableShading = Tbool.False; + + if (double.IsNaN(_ImageAngleOffset) == true) + ImageAngleOffset = 0; + + if (_ImageAutoRotate == Tbool.NotSet) + ImageAutoRotate = Tbool.False; + + if (ImageCropMode == SliceImageCropMode.NotSet) + ImageCropMode = SliceImageCropMode.ClipImage; + + if (ImageInnerRadiusAnchor == SliceImageRadiusAnchor.NotSet) + ImageInnerRadiusAnchor = SliceImageRadiusAnchor.InnerRadius; + + if (ImageOuterRadiusAnchor == SliceImageRadiusAnchor.NotSet) + ImageOuterRadiusAnchor = SliceImageRadiusAnchor.ExtentRadius; + + if (ImageOverlay == Style.ImageOverlay.NotSet) + ImageOverlay = Style.ImageOverlay.Top; + + if (double.IsNaN(ImageRadiusOffset) == true) + ImageRadiusOffset = .3; + + if (double.IsNaN(_ImageRotation) == true) + ImageRotation = 0; + + SliceInnerLabelStyle.ApplyDefaults(); + SliceOuterLabelStyle.ApplyDefaults(); + + if (_SymbolDef != null && _SymbolDef.IsValidSymbol == true) + { + if (_SymbolDef.SymbolSize == 0) + { + if (_SliceInnerLabelStyle != null) + { + if (_SliceInnerLabelStyle.Font != null) + _SymbolDef.SymbolSize = _SliceInnerLabelStyle.Font.SizeInPoints; + } + } + + if (_SymbolDef.SymbolColor.IsEmpty == true) + { + if (_SliceInnerLabelStyle != null && _SliceInnerLabelStyle.TextColor.IsEmpty == false) + _SymbolDef.SymbolColor = _SliceInnerLabelStyle.TextColor; + else + _SymbolDef.SymbolColor = Color.Black; + } + } + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartSliceVisualStyle Copy() + { + ChartSliceVisualStyle style = new ChartSliceVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartSliceVisualStyle style) + { + base.CopyTo(style); + + style.Background = (_Background != null) ? _Background.Copy() : null; + style.Border = (_Border != null) ? _Border.Copy() : null; + + style.EnableShading = EnableShading; + style.ExtentFillRange = _ExtentFillRange; + + style.ExtentAverageRefLineStyle = (_ExtentMinRefLineStyle != null) ? _ExtentMinRefLineStyle.Copy() : null; + style.ExtentMinRefLineStyle = (_ExtentMinRefLineStyle != null) ? _ExtentMinRefLineStyle.Copy() : null; + style.ExtentMaxRefLineStyle = (_ExtentMaxRefLineStyle != null) ? _ExtentMaxRefLineStyle.Copy() : null; + style.ExtentOuterRefLineStyle = (_ExtentOuterRefLineStyle != null) ? _ExtentOuterRefLineStyle.Copy() : null; + + style.Image = _Image; + style.ImageAngleOffset = _ImageAngleOffset; + style.ImageAutoRotate = _ImageAutoRotate; + style.ImageCropMode =_ImageCropMode; + style.ImageIndex = _ImageIndex; + style.ImageInnerRadiusAnchor = _ImageInnerRadiusAnchor; + style.ImageList = _ImageList; + style.ImageOuterRadiusAnchor = _ImageOuterRadiusAnchor; + style.ImageOverlay = _ImageOverlay; + style.ImagePadding = (_ImagePadding != null) ? _ImagePadding.Copy() : null; + style.ImageRadiusOffset = _ImageRadiusOffset; + style.ImageRotation = _ImageRotation; + style.ImageScale = _ImageScale; + + style.SliceInnerLabelStyle = (_SliceInnerLabelStyle != null) ? SliceInnerLabelStyle.Copy() : null; + style.SliceOuterLabelStyle = (_SliceOuterLabelStyle != null) ? SliceOuterLabelStyle.Copy() : null; + + style.SymbolDef = (_SymbolDef != null) ? _SymbolDef.Copy() : null; + + style.WhiteSpaceBackground = (_WhiteSpaceBackground != null) ? _WhiteSpaceBackground.Copy() : null; + style.WhiteSpaceBorder = (_WhiteSpaceBorder != null) ? _WhiteSpaceBorder.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartSliceVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + if (_Border != null && _Border.IsEmpty == false) + sec.AddElement(_Border.GetSerialData("Border")); + + sec.AddValue("EnableShading", EnableShading, Tbool.NotSet); + + if (_ExtentAverageRefLineStyle != null && _ExtentAverageRefLineStyle.IsEmpty == false) + sec.AddElement(_ExtentAverageRefLineStyle.GetSerialData("ExtentAverageRefLineStyle")); + + sec.AddValue("ExtentFillRange", ExtentFillRange, ExtentFillRange.NotSet); + + if (_ExtentMaxRefLineStyle != null && _ExtentMaxRefLineStyle.IsEmpty == false) + sec.AddElement(_ExtentMaxRefLineStyle.GetSerialData("ExtentMaxRefLineStyle")); + + if (_ExtentMinRefLineStyle != null && _ExtentMinRefLineStyle.IsEmpty == false) + sec.AddElement(_ExtentMinRefLineStyle.GetSerialData("ExtentMinRefLineStyle")); + + if (_ExtentOuterRefLineStyle != null && _ExtentOuterRefLineStyle.IsEmpty == false) + sec.AddElement(_ExtentOuterRefLineStyle.GetSerialData("ExtentOuterRefLineStyle")); + + sec.AddValue("Image", Image); + sec.AddValue("ImageAngleOffset", ImageAngleOffset, double.NaN); + sec.AddValue("ImageAutoRotate", ImageAutoRotate, Tbool.NotSet); + sec.AddValue("ImageCropMode", ImageCropMode, SliceImageCropMode.NotSet); + sec.AddValue("ImageIndex", _ImageIndex, -1); + sec.AddValue("ImageInnerRadiusAnchor", ImageInnerRadiusAnchor, SliceImageRadiusAnchor.NotSet); + + if (_ImageList != null) + sec.AddValue("ImageList", XmlSerializableImageList.ConvertToString(ImageList)); + + sec.AddValue("ImageOuterRadiusAnchor", ImageOuterRadiusAnchor, SliceImageRadiusAnchor.NotSet); + sec.AddValue("ImageOverlay", ImageOverlay, ImageOverlay.NotSet); + + if (_ImagePadding != null && _ImagePadding.IsEmpty == false) + sec.AddElement(_ImagePadding.GetSerialData("ImagePadding")); + + sec.AddValue("ImageRadiusOffset", ImageRadiusOffset, double.NaN); + sec.AddValue("ImageRotation", ImageRotation, double.NaN); + sec.AddValue("ImageScale", ImageScale, double.NaN); + + if (_SliceInnerLabelStyle != null && _SliceInnerLabelStyle.IsEmpty == false) + sec.AddElement(_SliceInnerLabelStyle.GetSerialData("SliceInnerLabelStyle")); + + if (_SliceOuterLabelStyle != null && _SliceOuterLabelStyle.IsEmpty == false) + sec.AddElement(_SliceOuterLabelStyle.GetSerialData("SliceOuterLabelStyle")); + + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + sec.AddElement(_SymbolDef.GetSerialData("SymbolDef")); + + if (_WhiteSpaceBackground != null && _WhiteSpaceBackground.IsEmpty == false) + sec.AddElement(_WhiteSpaceBackground.GetSerialData("WhiteSpaceBackground")); + + if (_WhiteSpaceBorder != null && _WhiteSpaceBorder.IsEmpty == false) + sec.AddElement(_WhiteSpaceBorder.GetSerialData("WhiteSpaceBorder")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Image": + Image = se.GetValueImage(); + break; + + case "EnableShading": + EnableShading = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ExtentFillRange": + ExtentFillRange = (ExtentFillRange)se.GetValueEnum(typeof(ExtentFillRange)); + break; + + case "ImageAngleOffset": + ImageAngleOffset = double.Parse(se.StringValue); + break; + + case "ImageAutoRotate": + ImageAutoRotate = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ImageCropMode": + ImageCropMode = (SliceImageCropMode)se.GetValueEnum(typeof(SliceImageCropMode)); + break; + + case "ImageIndex": + ImageIndex = int.Parse(se.StringValue); + break; + + case "ImageInnerRadiusAnchor": + ImageInnerRadiusAnchor = (SliceImageRadiusAnchor)se.GetValueEnum(typeof(SliceImageRadiusAnchor)); + break; + + case "ImageList": + ImageList = XmlSerializableImageList.ConvertFromString(se.StringValue); + break; + + case "ImageOuterRadiusAnchor": + ImageOuterRadiusAnchor = (SliceImageRadiusAnchor)se.GetValueEnum(typeof(SliceImageRadiusAnchor)); + break; + + case "ImageOverlay": + ImageOverlay = (ImageOverlay)se.GetValueEnum(typeof(ImageOverlay)); + break; + + case "ImageRadiusOffset": + ImageRadiusOffset = double.Parse(se.StringValue); + break; + + case "ImageRotation": + ImageRotation = double.Parse(se.StringValue); + break; + + case "ImageScale": + ImageScale = double.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "Background": + sec.PutSerialData(Background); + break; + + case "Border": + sec.PutSerialData(Border); + break; + + case "ExtentAverageRefLineStyle": + sec.PutSerialData(ExtentAverageRefLineStyle); + break; + + case "ExtentMaxRefLineStyle": + sec.PutSerialData(ExtentMaxRefLineStyle); + break; + + case "ExtentMinRefLineStyle": + sec.PutSerialData(ExtentMinRefLineStyle); + break; + + case "ExtentOuterRefLineStyle": + sec.PutSerialData(ExtentOuterRefLineStyle); + break; + + case "ImagePadding": + sec.PutSerialData(ImagePadding); + break; + + case "SliceInnerLabelStyle": + sec.PutSerialData(SliceInnerLabelStyle); + break; + + case "SliceOuterLabelStyle": + sec.PutSerialData(SliceOuterLabelStyle); + break; + + case "SymbolDef": + sec.PutSerialData(SymbolDef); + break; + + case "WhiteSpaceBackground": + sec.PutSerialData(WhiteSpaceBackground); + break; + + case "WhiteSpaceBorder": + sec.PutSerialData(WhiteSpaceBorder); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + Border = null; + + ExtentMaxRefLineStyle = null; + ExtentMinRefLineStyle = null; + ExtentAverageRefLineStyle = null; + ExtentOuterRefLineStyle = null; + + ImagePadding = null; + + SliceInnerLabelStyle = null; + SliceOuterLabelStyle = null; + + SymbolDef = null; + + WhiteSpaceBackground = null; + WhiteSpaceBorder = null; + + base.Dispose(); + } + + #endregion + } + + #region CenterLabelVisibility + + /// + /// Defines the visibility of the CenterLabel + /// + public enum CenterLabelVisibility + { + /// + /// Always shown. + /// + Always, + + /// + /// Never showm. + /// + Never, + + /// + /// Only shown on MouseOver. + /// + MouseOver, + } + + #endregion + + #region SliceLabelCropMode + + /// + /// Defines the label crop/clip mode. + /// + public enum SliceLabelCropMode + { + /// + /// NotSet + /// + NotSet = -1, + + /// + /// No clipping or hiding performed. + /// + NoAction, + + /// + /// Labels that do not fully fit will be clipped. + /// + Clip, + + /// + /// Labels that do not fully fit will be hidden. + /// + Hide, + } + + #endregion + + #region SliceLabelDisplayMode + + /// + /// Defines the slice label display mode. + /// + public enum SliceLabelDisplayMode + { + /// + /// NotSet + /// + NotSet = -1, + + /// + /// No labels displayed. + /// + None, + + /// + /// Inner labels only displayed (those inside the pie slice). + /// + Inner, + + /// + /// Outer labels only displayed (those outside the pie slice). + /// + Outer, + + /// + /// Both inner and outer labels displayed. + /// + InnerAndOuter, + + /// + /// Either the inner or the outer label will be displayed, but not + /// both (outer label will be displayed only when the inner label + /// cannot be displayed). + /// + InnerXorOuter, + } + + #endregion + + #region SliceLabelOrientation + + /// + /// Defines the slice inner label orientation. + /// + public enum SliceLabelOrientation + { + /// + /// NotSet + /// + NotSet = -1, + + /// + /// The text is perpendicular to the center line of the + /// slice, and is 'adapted' to fit the outer arc of the slice. + /// + Adaptive, + + /// + /// The label layout is gotten from the set 'Custom' layout + /// properties for the slice (include location, size, orientation, etc). + /// This option give the most control over the presentation of the label. + /// + Custom, + + /// + /// Labels are presented horizontally, within the bounds of the slice. + /// + Horizontal, + + /// + /// Labels are presented parallel to the slice center line, within + /// the bounds of the slice. + /// + Parallel, + + /// + /// Labels are presented perpendicular to the slice center line, within + /// the bounds of the slice. + /// + Perpendicular, + } + + #endregion + + #region SliceLabelVisibility + + /// + /// Defines the visibility of the slice labels. These values + /// can be combined to define a more targeted visibility. + /// + [Flags] + public enum SliceLabelVisibility + { + /// + /// NotSet + /// + NotSet = 0, + + /// + /// Labels are always visible. + /// + Always = (1 << 0), + + /// + /// Labels are never visible. + /// + Never = (1 << 1), + + /// + /// Labels will be shown according to the SelectionMode + /// setting in effect (ie. Ring, Slice, Pie, etc). + /// + SelectionModeMouseOver = (1 << 2), + + /// + /// Labels are shown for Detached slices. + /// + SliceDetach = (1 << 3), + + /// + /// Labels are shown on MouseOver. + /// + SliceMouseOver = (1 << 4), + + /// + /// Labels are shown for selected slices. + /// + SliceSelect = (1 << 5), + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartTickmarkVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartTickmarkVisualStyle.cs new file mode 100644 index 00000000..59394e89 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartTickmarkVisualStyle.cs @@ -0,0 +1,300 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a Chart Ticmark element. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartTickmarkVisualStyle : BaseVisualStyle + { + #region Private variables + + private int _TickmarkLength = -1; + private int _TickmarkThickness = -1; + private Color _TickmarkColor = Color.Empty; + + private LineAlignment _TickmarkAlignment = LineAlignment.NotSet; + + #endregion + + #region Public properties + + #region TickmarkAlignment + + /// + /// Gets or sets the Tickmark alignment. + /// + [DefaultValue(LineAlignment.NotSet), Category("Appearance")] + [Description("Indicates the Tickmark alignment.")] + public LineAlignment TickmarkAlignment + { + get { return (_TickmarkAlignment); } + + set + { + if (value != _TickmarkAlignment) + { + _TickmarkAlignment = value; + + OnPropertyChangedEx("TickMarkAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TickmarkColor + + /// + /// Gets or sets the Tickmark Color. + /// + [Category("Appearance")] + [Description("Indicates the Tickmark Color.")] + public Color TickmarkColor + { + get { return (_TickmarkColor); } + + set + { + if (value != _TickmarkColor) + { + _TickmarkColor = value; + + OnPropertyChangedEx("TickmarkColor", Style.VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTickmarkColor() + { + return (_TickmarkColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTickmarkColor() + { + TickmarkColor = Color.Empty; + } + + #endregion + + #region TickmarkLength + + /// + /// Gets or sets the Tickmark length. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the Tickmark length.")] + public int TickmarkLength + { + get { return (_TickmarkLength); } + + set + { + if (value != _TickmarkLength) + { + _TickmarkLength = value; + + OnPropertyChangedEx("TickmarkLength", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TickmarkThickness + + /// + /// Gets or sets the Tickmark Thickness. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the Tickmark Thickness.")] + public int TickmarkThickness + { + get { return (_TickmarkThickness); } + + set + { + if (value != _TickmarkThickness) + { + _TickmarkThickness = value; + + OnPropertyChangedEx("TickmarkThickness", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_TickmarkAlignment == LineAlignment.NotSet) && + (_TickmarkColor.IsEmpty == true) && + (_TickmarkLength < 0) && + (_TickmarkThickness < 0) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartTickmarkVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.TickmarkAlignment != LineAlignment.NotSet) + TickmarkAlignment = style.TickmarkAlignment; + + if (style.TickmarkColor.IsEmpty == false) + TickmarkColor = style.TickmarkColor; + + if (style.TickmarkLength >= 0) + TickmarkLength = style.TickmarkLength; + + if (style.TickmarkThickness >= 0) + TickmarkThickness = style.TickmarkThickness; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartTickmarkVisualStyle Copy() + { + ChartTickmarkVisualStyle style = new ChartTickmarkVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartTickmarkVisualStyle style) + { + base.CopyTo(style); + + style.TickmarkAlignment = _TickmarkAlignment; + style.TickmarkColor = _TickmarkColor; + style.TickmarkLength = _TickmarkLength; + style.TickmarkThickness = _TickmarkThickness; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartTickmarkVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("TickmarkAlignment", TickmarkAlignment, LineAlignment.NotSet); + sec.AddValue("TickmarkColor", TickmarkColor, Color.Empty); + sec.AddValue("TickmarkLength", TickmarkLength, -1); + sec.AddValue("TickmarkThickness", TickmarkThickness, -1); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "TickmarkAlignment": + TickmarkAlignment = (LineAlignment)se.GetValueEnum(typeof(LineAlignment)); + break; + + case "TickmarkColor": + TickmarkColor = se.GetValueColor(); + break; + + case "TickmarkLength": + TickmarkLength = int.Parse(se.StringValue); + break; + + case "TickmarkThickness": + TickmarkThickness = int.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartTitleVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartTitleVisualStyle.cs new file mode 100644 index 00000000..068b87d5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartTitleVisualStyle.cs @@ -0,0 +1,268 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of an element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ChartTitleVisualStyle : ContainerVisualStyle + { + #region Private variables + + private int _MaxLineCount = -1; + private Tbool _Stretch = Tbool.NotSet; + + #endregion + + #region Public properties + + #region MaxLineCount + + /// + /// Gets or sets the maximum number of Text lines. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the maximum number of Text lines.")] + public int MaxLineCount + { + get { return (_MaxLineCount); } + + set + { + if (value != _MaxLineCount) + { + _MaxLineCount = value; + + OnPropertyChangedEx("MaxLineCount", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Stretch + + /// + /// Gets or sets whether text is 'stretched' to consume entire XyAlignment area. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text is 'stretched' to consume entire XyAlignment area.")] + public Tbool Stretch + { + get { return (_Stretch); } + + set + { + if (_Stretch != value) + { + _Stretch = value; + + OnPropertyChangedEx("Stretch", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_MaxLineCount < 0) && + (_Stretch == Tbool.NotSet) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartTitleVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.MaxLineCount > 0) + _MaxLineCount = style.MaxLineCount; + + if (style.Stretch != Tbool.NotSet) + _Stretch = style.Stretch; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + base.ApplyDefaults(); + + if (TextColor.IsEmpty) + TextColor = Color.Black; + + if (MaxLineCount < 0) + MaxLineCount = 3; + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartTitleVisualStyle Copy() + { + ChartTitleVisualStyle style = new ChartTitleVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartTitleVisualStyle style) + { + base.CopyTo(style); + + style.MaxLineCount = _MaxLineCount; + style.Stretch = _Stretch; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartTitleVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("MaxLineCount", MaxLineCount, -1); + sec.AddValue("Stretch", Stretch, Tbool.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "MaxLineCount": + MaxLineCount = int.Parse(se.StringValue); + break; + + case "Stretch": + Stretch = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + base.Dispose(); + } + + #endregion + } + + #region RotateDegrees + + /// + /// Specifies the degrees to rotate the element. + /// + public enum RotateDegrees + { + /// + /// Not set + /// + NotSet = -1, + + /// + /// None + /// + None, + + /// + /// Rotate as needed + /// + Auto, + + /// + /// Rotate 90 degrees + /// + Rotate90, + + /// + /// Rotate 180 degrees + /// + Rotate180, + + /// + /// Rotate 270 degrees + /// + Rotate270, + } + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartXyVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartXyVisualStyle.cs new file mode 100644 index 00000000..c9faa6e2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ChartXyVisualStyle.cs @@ -0,0 +1,398 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of an XY Chart element. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ChartXyVisualStyle : ContainerVisualStyle + { + #region Private variables + + private ScrollBarVisualStyles _HScrollBarVisualStyles; + private ScrollBarVisualStyles _VScrollBarVisualStyles; + + private int _InterSeriesGap = -1; + private int _IntraSeriesGap = -1; + + private Tbool _AutoExpandIntraSeriesGap = Tbool.NotSet; + + #endregion + + #region Public properties + + #region AutoExpandIntraSeriesGap + + /// + /// Gets or sets whether to auto adjust the IntraSeriesGap when space permits. + /// + [Description("Indicates whether to auto adjust the IntraSeriesGap when space permits.")] + [DefaultValue(Tbool.NotSet)] + public Tbool AutoExpandIntraSeriesGap + { + get { return (_AutoExpandIntraSeriesGap); } + + set + { + if (value != _AutoExpandIntraSeriesGap) + { + _AutoExpandIntraSeriesGap = value; + + OnPropertyChangedEx("AutoExpandIntraSeriesGap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region HScrollBarVisualStyles + + /// + /// Gets or sets the visual styles to be used for Horizontal ScrollBar elements + /// + [Category("Style")] + [Description("Indicates visual styles to be used for Horizontal ScrollBar elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarVisualStyles HScrollBarVisualStyles + { + get + { + if (_HScrollBarVisualStyles == null) + { + _HScrollBarVisualStyles = new ScrollBarVisualStyles(); + + UpdateChangeHandler(null, _HScrollBarVisualStyles); + } + + return (_HScrollBarVisualStyles); + } + + set + { + if (_HScrollBarVisualStyles != value) + { + ScrollBarVisualStyles oldValue = _HScrollBarVisualStyles; + _HScrollBarVisualStyles = value; + + OnStyleChanged("HScrollBarVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region InterSeriesGap + + /// + /// Gets or sets the pixel gap between grouped, qualitative series. + /// + [Description("Indicates the pixel gap between grouped, qualitative series.")] + [DefaultValue(-1)] + public int InterSeriesGap + { + get { return (_InterSeriesGap); } + + set + { + if (value != _InterSeriesGap) + { + _InterSeriesGap = value; + + OnPropertyChangedEx("InterSeriesGap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IntraSeriesGap + + /// + /// Gets or sets the pixel gap between each series in a set of grouped, qualitative series. + /// + [Description("Indicates the pixel gap between each series in a set of grouped, qualitative series.")] + [DefaultValue(-1)] + public int IntraSeriesGap + { + get { return (_IntraSeriesGap); } + + set + { + if (value != _IntraSeriesGap) + { + _IntraSeriesGap = value; + + OnPropertyChangedEx("IntraSeriesGap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region VScrollBarVisualStyles + + /// + /// Gets or sets the visual styles to be used for Vertical ScrollBar elements + /// + [Category("Style")] + [Description("Indicates visual styles to be used for Vertical ScrollBar elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarVisualStyles VScrollBarVisualStyles + { + get + { + if (_VScrollBarVisualStyles == null) + { + _VScrollBarVisualStyles = new ScrollBarVisualStyles(); + + UpdateChangeHandler(null, _VScrollBarVisualStyles); + } + + return (_VScrollBarVisualStyles); + } + + set + { + if (_VScrollBarVisualStyles != value) + { + ScrollBarVisualStyles oldValue = _VScrollBarVisualStyles; + _VScrollBarVisualStyles = value; + + OnStyleChanged("VScrollBarVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_InterSeriesGap < 0) && + (_IntraSeriesGap < 0) && + (_VScrollBarVisualStyles == null) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ChartXyVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.AutoExpandIntraSeriesGap != Tbool.NotSet) + _AutoExpandIntraSeriesGap = style.AutoExpandIntraSeriesGap; + + if (style.InterSeriesGap >= 0) + _InterSeriesGap = style.InterSeriesGap; + + if (style.IntraSeriesGap >= 0) + _IntraSeriesGap = style.IntraSeriesGap; + + if (style.HScrollBarVisualStyles != null) + { + for (int i = 0; i < style.HScrollBarVisualStyles.Styles.Length; i++) + { + if (style.HScrollBarVisualStyles.Styles[i] != null) + HScrollBarVisualStyles.GetStyle(i).ApplyStyle(style.HScrollBarVisualStyles.Styles[i]); + } + } + + if (style.VScrollBarVisualStyles != null) + { + for (int i = 0; i < style.VScrollBarVisualStyles.Styles.Length; i++) + { + if (style.VScrollBarVisualStyles.Styles[i] != null) + VScrollBarVisualStyles.GetStyle(i).ApplyStyle(style.VScrollBarVisualStyles.Styles[i]); + } + } + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (BorderPattern == null) + BorderPattern = new BorderPattern(LinePattern.Solid); + + if (InterSeriesGap < 0) + InterSeriesGap = 2; + + if (IntraSeriesGap < 0) + IntraSeriesGap = 2; + + if (AutoExpandIntraSeriesGap == Tbool.NotSet) + AutoExpandIntraSeriesGap = Tbool.True; + + if (DropShadow.Enabled == Tbool.NotSet) + DropShadow.Enabled = Tbool.False; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ChartXyVisualStyle Copy() + { + ChartXyVisualStyle style = new ChartXyVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ChartXyVisualStyle style) + { + base.CopyTo(style); + + style.AutoExpandIntraSeriesGap = _AutoExpandIntraSeriesGap; + style.InterSeriesGap = _InterSeriesGap; + style.IntraSeriesGap = _IntraSeriesGap; + + style.HScrollBarVisualStyles = (_HScrollBarVisualStyles != null) ? _HScrollBarVisualStyles.Copy() : null; + style.VScrollBarVisualStyles = (_VScrollBarVisualStyles != null) ? _VScrollBarVisualStyles.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartXyVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AutoExpandIntraSeriesGap", AutoExpandIntraSeriesGap, Tbool.NotSet); + sec.AddValue("InterSeriesGap", InterSeriesGap, -1); + sec.AddValue("IntraSeriesGap", IntraSeriesGap, -1); + + if (_HScrollBarVisualStyles != null && _HScrollBarVisualStyles.IsEmpty == false) + sec.AddElement(_HScrollBarVisualStyles.GetSerialData("HScrollBarVisualStyles")); + + if (_VScrollBarVisualStyles != null && _VScrollBarVisualStyles.IsEmpty == false) + sec.AddElement(_VScrollBarVisualStyles.GetSerialData("VScrollBarVisualStyles")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AutoExpandIntraSeriesGap": + AutoExpandIntraSeriesGap = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "InterSeriesGap": + InterSeriesGap = int.Parse(se.StringValue); + break; + + case "IntraSeriesGap": + IntraSeriesGap = int.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "HScrollBarVisualStyles": + sec.PutSerialData(HScrollBarVisualStyles); + break; + + case "VScrollBarVisualStyles": + sec.PutSerialData(HScrollBarVisualStyles); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + HScrollBarVisualStyles = null; + VScrollBarVisualStyles = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ConnectorLineVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ConnectorLineVisualStyle.cs new file mode 100644 index 00000000..5394c66a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ConnectorLineVisualStyle.cs @@ -0,0 +1,407 @@ +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a Chart Line + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(DefaultStyleConvertor))] + public class ConnectorLineVisualStyle : ChartLineVisualStyle + { + #region Private variables + + private int _MaxLength = -1; + private int _MinLength = -1; + private int _LengthStep = -1; + + private int _DefaultAngle = -1; + private int _AngleStep = -1; + + private ConnectorOrigin _Origin = ConnectorOrigin.NotSet; + + #endregion + + #region Public properties + + #region AngleStep + + /// + /// Gets or sets the angle step value when rotating conflicting labels. + /// + [DefaultValue(-1), Category("DataLabel")] + [Description("Indicates the angle step value when rotating conflicting labels.")] + public int AngleStep + { + get { return (_AngleStep); } + + set + { + if (value != _AngleStep) + { + _AngleStep = value; + + OnPropertyChangedEx("AngleStep", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region DefaultAngle + + /// + /// Gets or sets the default line angle (-1 denotes 'auto'). + /// + [DefaultValue(-1), Category("DataLabel")] + [Description("Indicates the default line angle (-1 denotes 'auto').")] + public int DefaultAngle + { + get { return (_DefaultAngle); } + + set + { + if (value != _DefaultAngle) + { + _DefaultAngle = value; + + OnPropertyChangedEx("DefaultAngle", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region LengthStep + + /// + /// Gets or sets the angle step value when rotating conflicting labels. + /// + [DefaultValue(-1), Category("DataLabel")] + [Description("Indicates the angle step value when rotating conflicting labels.")] + public int LengthStep + { + get { return (_LengthStep); } + + set + { + if (value != _LengthStep) + { + _LengthStep = value; + + OnPropertyChangedEx("LengthStep", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxLength + + /// + /// Gets or sets the maximum connector line length. + /// + [DefaultValue(-1), Category("DataLabel")] + [Description("Indicates the maximum connector line length.")] + public int MaxLength + { + get { return (_MaxLength); } + + set + { + if (value != _MaxLength) + { + _MaxLength = value; + + OnPropertyChangedEx("MaxLength", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinLength + + /// + /// Gets or sets the minimum connector line length. + /// + [DefaultValue(-1), Category("DataLabel")] + [Description("Indicates the minimum connector line length.")] + public int MinLength + { + get { return (_MinLength); } + + set + { + if (value != _MinLength) + { + _MinLength = value; + + OnPropertyChangedEx("MinLength", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region Origin + + /// + /// Gets or sets the line connector origin. + /// + [DefaultValue(ConnectorOrigin.NotSet)] + [Description("Indicates the line connector origin")] + public ConnectorOrigin Origin + { + get { return (_Origin); } + + set + { + if (value != _Origin) + { + _Origin = value; + + OnPropertyChangedEx("Origin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_AngleStep < 0) && + (_DefaultAngle < 0) && + (_Origin == ConnectorOrigin.NotSet) && + (_LengthStep < 0) && + (_MaxLength < 0) && + (_MinLength < 0) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ConnectorLineVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.AngleStep >= 0) + _AngleStep = style.AngleStep; + + if (style.DefaultAngle >= 0) + _DefaultAngle = style.DefaultAngle; + + if (style.LengthStep >= 0) + _LengthStep = style.LengthStep; + + if (style.MaxLength >= 0) + _MaxLength = style.MaxLength; + + if (style.MinLength >= 0) + _MinLength = style.MinLength; + + if (style.Origin != ConnectorOrigin.NotSet) + _Origin = style.Origin; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (MinLength > MaxLength) + MaxLength = MinLength; + + if (MinLength < 0) + MinLength = 10; + + if (MaxLength < 0) + MaxLength = 200; + + if (MaxLength <= MinLength) + MaxLength = MinLength + 200; + + if (AngleStep < 0) + AngleStep = 15; + + if (LengthStep < 0) + LengthStep = 10; + + if (LinePattern == LinePattern.NotSet) + LinePattern = LinePattern.Solid; + + if (LineColor.IsEmpty == true) + LineColor = Color.Black; + + if (LineWidth < 0) + LineWidth = 1; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ConnectorLineVisualStyle Copy() + { + ConnectorLineVisualStyle style = new ConnectorLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ConnectorLineVisualStyle style) + { + base.CopyTo(style); + + style.AngleStep = _AngleStep; + style.DefaultAngle = _DefaultAngle; + + style.LengthStep = _LengthStep; + style.MaxLength = _MaxLength; + style.MinLength = _MinLength; + + style.Origin = _Origin; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ConnectorLineVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AngleStep", AngleStep, -1); + sec.AddValue("DefaultAngle", DefaultAngle, -1); + + sec.AddValue("LengthStep", LengthStep, -1); + sec.AddValue("MaxLength", MaxLength, -1); + sec.AddValue("MinLength", MinLength, -1); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AngleStep": + AngleStep = int.Parse(se.StringValue); + break; + + case "DefaultAngle": + DefaultAngle = int.Parse(se.StringValue); + break; + + case "LengthStep": + LengthStep = int.Parse(se.StringValue); + break; + + case "MaxLength": + MaxLength = int.Parse(se.StringValue); + break; + + case "MinLength": + MinLength = int.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + base.Dispose(); + } + + #endregion + } + + #region Enums + + #region ConnectorOrigin + + public enum ConnectorOrigin + { + NotSet = -1, + + Center, + + Edge, + } + + #endregion + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ContainerVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ContainerVisualStyle.cs new file mode 100644 index 00000000..bd45f0d5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ContainerVisualStyle.cs @@ -0,0 +1,1402 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// ContainerVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ContainerVisualStyles : VisualStyles + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public ContainerVisualStyles Copy() + { + ContainerVisualStyles styles = new ContainerVisualStyles(); + + for (int i = 0; i < Styles.Length; i++) + { + ContainerVisualStyle vstyle = Styles[i]; + + if (vstyle != null) + styles.Styles[i] = vstyle.Copy(); + } + + return (styles); + } + + #endregion + } + + /// + /// Represents the visual style of a container item. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class ContainerVisualStyle : VisualStyle + { + #region Private variables + + private Tbool _AllowWrap = Tbool.NotSet; + private Alignment _Alignment = Alignment.NotSet; + + private Image _Image; + private int _ImageIndex = -1; + private ImageList _ImageList; + + private Padding _ImagePadding; + + private Alignment _ImageAlignment = Alignment.NotSet; + private ImageOverlay _ImageOverlay = ImageOverlay.NotSet; + private ImageSizeMode _ImageSizeMode = ImageSizeMode.NotSet; + + private Tbool _EnableImageScroll = Tbool.NotSet; + + private DropShadowVisualStyle _DropShadow; + + private SymbolDef _SymbolDef; + + #endregion + + #region Public properties + + #region Alignment + + /// + /// Gets or sets the alignment of the text + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the text.")] + public Alignment Alignment + { + get { return (_Alignment); } + + set + { + if (_Alignment != value) + { + _Alignment = value; + + OnPropertyChangedEx("Alignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DropShadow + + /// + /// Gets or sets the visual style for the DropShadow. + /// + [Category("Style")] + [Description("Indicates the visual style for the DropShadow.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DropShadowVisualStyle DropShadow + { + get + { + if (_DropShadow == null) + { + _DropShadow = new DropShadowVisualStyle(); + + UpdateChangeHandler(null, _DropShadow); + } + + return (_DropShadow); + } + + set + { + if (_DropShadow != value) + { + DropShadowVisualStyle oldValue = _DropShadow; + + _DropShadow = value; + + OnStyleChanged("DropShadow", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region EnableImageScroll + + /// + /// Gets or sets whether the image scrolls or is fixed with the container content. + /// + [DefaultValue(Tbool.NotSet)] + [Category("Appearance"), Description("Indicates whether the image scrolls or is fixed with the container content.")] + public Tbool EnableImageScroll + { + get { return (_EnableImageScroll); } + + set + { + if (value != _EnableImageScroll) + { + _EnableImageScroll = value; + + OnPropertyChangedEx("EnableImageScroll", VisualChangeType.Render); + } + } + } + + #endregion + + #region Image + + /// + /// Gets or sets the element Image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the element image")] + public Image Image + { + get { return (_Image); } + + set + { + if (_Image != value) + { + _Image = value; + + OnPropertyChangedEx("Image", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageAlignment + + /// + /// Gets or sets the alignment of the Image + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the Image.")] + public Alignment ImageAlignment + { + get { return (_ImageAlignment); } + + set + { + if (_ImageAlignment != value) + { + _ImageAlignment = value; + + OnPropertyChangedEx("ImageAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageIndex + + /// + /// Gets or sets the image index + /// + [DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the image index")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int ImageIndex + { + get { return (_ImageIndex); } + + set + { + if (_ImageIndex != value) + { + _ImageIndex = value; + + OnPropertyChangedEx("ImageIndex", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageList + + /// + /// Gets or sets the ImageList. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates the ImageList.")] + public ImageList ImageList + { + get { return (_ImageList); } + + set + { + if (_ImageList != value) + { + _ImageList = value; + + OnPropertyChangedEx("ImageList", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageOverlay + + /// + /// Gets or sets how to overlay the cell image with respect to cell content + /// + [DefaultValue(ImageOverlay.NotSet), Category("Appearance")] + [Description("Indicates how to overlay the cell image with respect to cell content.")] + public ImageOverlay ImageOverlay + { + get { return (_ImageOverlay); } + + set + { + if (_ImageOverlay != value) + { + _ImageOverlay = value; + + OnPropertyChangedEx("ImageOverlay", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImagePadding + + /// + /// Gets or sets the spacing between content and edges of the Image + /// + [Description("Indicates the spacing between content and edges of the Image")] + public Padding ImagePadding + { + get + { + if (_ImagePadding == null) + { + _ImagePadding = Padding.Empty; + + UpdateChangeHandler(null, _ImagePadding); + } + + return (_ImagePadding); + } + + set + { + if (_ImagePadding != value) + { + UpdateChangeHandler(_ImagePadding, value); + + _ImagePadding = value; + + OnPropertyChangedEx("ImagePadding", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeImagePadding() + { + return (_ImagePadding != null && _ImagePadding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetImagePadding() + { + ImagePadding = null; + } + + #endregion + + #region ImageSizeMode + + /// + /// Gets or sets the 'mode' used to display the image. + /// + [DefaultValue(ImageSizeMode.NotSet), Category("Appearance")] + [Description("Indicates the 'mode' used to display the image.")] + public ImageSizeMode ImageSizeMode + { + get { return (_ImageSizeMode); } + + set + { + if (value!= _ImageSizeMode) + { + _ImageSizeMode = value; + + OnPropertyChangedEx("ImageSizeMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region SymbolDef + + /// + /// Gets or sets the element Symbol Definition. Note that Symbol definition + /// takes precedence over Image definition. Also note that the supporting Image + /// properties (such as ImageAlignment, ImageOverlay, etc) apply to a set + /// Symbol as well as to a set Image. + /// + [DefaultValue(null), Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Description("Indicates the element Symbol Definition. Note that Symbol definition takes precedence over Image definition. Also note that the supporting Image properties (such as ImageAlignment, ImageOverlay, etc) apply to a set Symbol as well as to a set Image.")] + public SymbolDef SymbolDef + { + get + { + if (_SymbolDef == null) + { + _SymbolDef = new SymbolDef(); + + UpdateChangeHandler(null, _SymbolDef); + } + + return (_SymbolDef); + } + + set + { + if (_SymbolDef != value) + { + UpdateChangeHandler(_SymbolDef, value); + + _SymbolDef = value; + + OnPropertyChangedEx("SymbolDef", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeSymbolDef() + { + return (_SymbolDef != null && _SymbolDef.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetSymbolDef() + { + SymbolDef = null; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Alignment == Alignment.NotSet) && + (_AllowWrap == Tbool.NotSet) && + (_DropShadow == null || _DropShadow.IsEmpty) && + (_Image == null) && + (_ImageAlignment == Alignment.NotSet) && + (_ImageIndex == -1) && + (_ImageList == null) && + (_ImageOverlay == ImageOverlay.NotSet) && + (_ImagePadding == null || _ImagePadding.IsEmpty == true) && + (_ImageSizeMode == Style.ImageSizeMode.NotSet) && + (_SymbolDef == null || _SymbolDef.IsEmpty == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region IsOverlayImage + + internal bool IsOverlayImage + { + get + { + return (_ImageOverlay == ImageOverlay.Top || + _ImageOverlay == ImageOverlay.Middle || + _ImageOverlay == ImageOverlay.Bottom); + } + } + + #endregion + + #region IsValidFigure + + internal bool IsValidFigure + { + get + { + if (IsSymbolFigure == true) + return (true); + + return (GetImage() != null); + } + } + + #endregion + + #region IsSymbolFigure + + internal bool IsSymbolFigure + { + get { return (_SymbolDef != null && _SymbolDef.IsValidSymbol == true); } + } + + #endregion + + #endregion + + #region GetFigure + + internal object GetFigure() + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + return (_SymbolDef); + + return (GetImage()); + } + + #region GetImage + + internal Image GetImage() + { + if (_Image != null) + return (_Image); + + if (_ImageIndex >= 0) + { + ImageList imageList = ImageList; + + if (imageList != null && _ImageIndex < imageList.Images.Count) + return (imageList.Images[_ImageIndex]); + } + + return (null); + } + + #endregion + + #region GetSymbol + + internal string GetSymbol() + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + return (_SymbolDef.SymbolRealized); + + return (null); + } + + #endregion + + #endregion + + #region GetFigureSize + + internal Size GetFigureSize(Graphics g) + { + Size size = Size.Empty; + + if (IsSymbolFigure == true) + size = _SymbolDef.GetSymbolSize(g); + + else + { + Image image = GetImage(); + + if (image != null) + size = Dpi.Size(image.Size); + } + + if (size.IsEmpty == false) + { + size.Width += Dpi.Width(ImagePadding.Horizontal); + size.Height += Dpi.Height(ImagePadding.Vertical); + } + + return (size); + } + + #endregion + + #region GetFigureBounds + + internal Rectangle GetFigureBounds(Graphics g, Rectangle r) + { + if (IsSymbolFigure == true) + return (GetSymbolBounds(g, r)); + + return (GetImageBounds(g, r)); + } + + #region GetImageBounds + + internal Rectangle GetImageBounds(Graphics g, Rectangle r) + { + Image image = GetImage(); + + return (GetImageBounds(g, r, image)); + } + + private Rectangle GetImageBounds(Graphics g, Rectangle r, Image image) + { + if (image != null) + return (GetSizeBounds(r, Dpi.Size(image.Size))); + + return (Rectangle.Empty); + } + + #endregion + + #region GetSymbolBounds + + internal Rectangle GetSymbolBounds(Graphics g, Rectangle r) + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + { + Size size = _SymbolDef.GetSymbolSize(g); + + return (GetSizeBounds(r, size)); + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetSizeBounds + + internal Rectangle GetSizeBounds(Rectangle r, Size size) + { + switch (ImageAlignment) + { + case Alignment.NotSet: + case Alignment.MiddleLeft: + r.Y += (r.Height - size.Height) / 2; + + r.X += Dpi.Width(ImagePadding.Left); + r.Y += Dpi.Height(ImagePadding.Top - ImagePadding.Bottom); + break; + + case Alignment.TopLeft: + r.X += Dpi.Width(ImagePadding.Left); + r.Y += Dpi.Height(ImagePadding.Top); + break; + + case Alignment.BottomLeft: + r.Y = r.Bottom - size.Height; + + r.X += Dpi.Width(ImagePadding.Left); + r.Y -= Dpi.Height(ImagePadding.Bottom); + break; + + case Alignment.TopCenter: + r.X += (r.Width - size.Width) / 2; + + r.X += Dpi.Width(ImagePadding.Left - ImagePadding.Right); + r.Y += Dpi.Height(ImagePadding.Top); + break; + + case Alignment.MiddleCenter: + r.X += (r.Width - size.Width) / 2; + r.Y += (r.Height - size.Height) / 2; + + r.X += Dpi.Width(ImagePadding.Left - ImagePadding.Right); + r.Y += Dpi.Height(ImagePadding.Top - ImagePadding.Bottom); + break; + + case Alignment.BottomCenter: + r.X += (r.Width - size.Width) / 2; + r.Y = r.Bottom - size.Height; + + r.X += Dpi.Width(ImagePadding.Left - ImagePadding.Right); + r.Y -= Dpi.Height(ImagePadding.Bottom); + break; + + case Alignment.TopRight: + r.X = r.Right - size.Width; + + r.X -= Dpi.Width(ImagePadding.Right); + r.Y += Dpi.Height(ImagePadding.Top); + break; + + case Alignment.MiddleRight: + r.X = r.Right - size.Width; + r.Y += (r.Height - size.Height) / 2; + + r.X -= Dpi.Width(ImagePadding.Right); + r.Y += Dpi.Height(ImagePadding.Top - ImagePadding.Bottom); + break; + + case Alignment.BottomRight: + r.X = r.Right - size.Width; + r.Y = r.Bottom - size.Height; + + r.X -= Dpi.Width(ImagePadding.Right); + r.Y -= Dpi.Height(ImagePadding.Bottom); + break; + } + + r.Size = size; + + return (r); + } + + #endregion + + #endregion + + #region RenderBackgroundFigure + + internal void RenderBackgroundFigure(Graphics g, Rectangle bounds) + { + RenderBackgroundFigure(g, bounds, bounds); + } + + internal void RenderBackgroundFigure(Graphics g, Rectangle bounds, Rectangle clipBounds) + { + if (IsSymbolFigure == true) + { + RenderBackgroundSymbol(g, bounds, clipBounds); + } + else + { + Image image = GetImage(); + + if (image != null) + RenderBackgroundImage(g, bounds, clipBounds); + } + } + + #region RenderBackgroundImage + + internal void RenderBackgroundImage(Graphics g, Rectangle bounds, Rectangle clipBounds) + { + Image image = GetImage(); + + if (image != null) + { + Region clip = g.Clip; + + if (ImageSizeMode == ImageSizeMode.NotSet || + ImageSizeMode == ImageSizeMode.Normal) + { + Rectangle dbounds = GetImageBounds(g, clipBounds, image); + + g.SetClip(Rectangle.Intersect(bounds, dbounds)); + + g.DrawImage(image, dbounds, + new Rectangle(Point.Empty, image.Size), GraphicsUnit.Pixel); + } + else + { + Rectangle r = GetAdjustedBounds(clipBounds, ImagePadding); + + g.SetClip(r, CombineMode.Intersect); + + switch (ImageSizeMode) + { + case ImageSizeMode.Stretch: + g.DrawImage(image, r); + break; + + case ImageSizeMode.Tile: + RenderImageTiled(g, image, r); + break; + + case ImageSizeMode.Zoom: + RenderImageZoomed(g, image, r); + break; + } + } + + g.Clip = clip; + } + } + + #region GetAdjustedBounds + + private Rectangle GetAdjustedBounds(Rectangle bounds, Thickness padding) + { + if (padding.IsEmpty == false) + { + if (bounds.Height > padding.Vertical) + { + bounds.Y += padding.Top; + bounds.Height -= padding.Vertical; + } + + if (bounds.Width > padding.Horizontal) + { + bounds.X += padding.Left; + bounds.Width -= padding.Horizontal; + } + } + + return (bounds); + } + + #endregion + + #region RenderImageTiled + + private void RenderImageTiled(Graphics g, Image image, Rectangle bounds) + { + Rectangle sr = new Rectangle(Point.Empty, image.Size); + Rectangle dr = new Rectangle(bounds.Location, image.Size); + + while (dr.Top < bounds.Bottom) + { + while (dr.Left < bounds.Right) + { + g.DrawImage(image, dr, sr, GraphicsUnit.Pixel); + + dr.X += image.Size.Width; + } + + dr.X = bounds.X; + dr.Y += image.Size.Height; + } + } + + #endregion + + #region RenderImageZoomed + + private void RenderImageZoomed( + Graphics g, Image image, Rectangle r) + { + SizeF size = new SizeF(image.Width / image.HorizontalResolution, + image.Height / image.VerticalResolution); + + float scale = Math.Min(r.Width / size.Width, r.Height / size.Height); + + size.Width *= scale; + size.Height *= scale; + + Point pt = r.Location; + + if (Math.Abs(r.Width - size.Width) > 2) + { + switch (ImageAlignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + pt.X += (int)((r.Width - size.Width) / 2); + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + pt.X = (int)(r.Right - size.Width); + break; + } + } + else + { + switch (ImageAlignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + pt.Y += (int)((r.Height - size.Height) / 2); + break; + + case Alignment.BottomLeft: + case Alignment.BottomCenter: + case Alignment.BottomRight: + pt.Y = (int)(r.Bottom - size.Height); + break; + } + } + + g.DrawImage(image, + pt.X, pt.Y, size.Width, size.Height); + } + + #endregion + + #endregion + + #region RenderBackgroundSymbol + + internal void RenderBackgroundSymbol(Graphics g, Rectangle bounds, Rectangle clipBounds) + { + string symbol = GetSymbol(); + + if (symbol != null) + { + Region clip = g.Clip; + + if (ImageSizeMode != ImageSizeMode.Tile) + { + Rectangle dbounds = GetSymbolBounds(g, clipBounds); + + g.SetClip(Rectangle.Intersect(bounds, dbounds)); + + using (Brush br = new SolidBrush(_SymbolDef.SymbolColor)) + g.DrawString(symbol, _SymbolDef.SymbolFont, br, dbounds); + } + else + { + Rectangle r = GetAdjustedBounds(clipBounds, ImagePadding); + + g.SetClip(r, CombineMode.Intersect); + + RenderSymbolTiled(g, symbol, r); + } + + g.Clip = clip; + } + } + + #region RenderSymbolTiled + + private void RenderSymbolTiled(Graphics g, string symbol, Rectangle bounds) + { + Font font = _SymbolDef.SymbolFont; + Color color = _SymbolDef.SymbolColor; + + Size size = _SymbolDef.GetSymbolSize(g); + Rectangle dr = new Rectangle(bounds.Location, size); + + while (dr.Top < bounds.Bottom) + { + while (dr.Left < bounds.Right) + { + TextDrawing.DrawString(g, symbol, font, color, dr, eTextFormat.Default); + + dr.X += size.Width; + } + + dr.X = bounds.X; + dr.Y += size.Height; + } + } + + #endregion + + #endregion + + #endregion + + #region GetStringFormatFlags + + internal void GetStringFormatFlags(StringFormat sf) + { + if (AllowWrap == Tbool.False) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + switch (Alignment) + { + case Alignment.TopCenter: + sf.LineAlignment = StringAlignment.Near; + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.TopRight: + sf.LineAlignment = StringAlignment.Near; + sf.Alignment = StringAlignment.Far; + break; + + case Alignment.MiddleLeft: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Near; + break; + + case Alignment.MiddleCenter: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.MiddleRight: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Far; + break; + + case Alignment.BottomLeft: + sf.LineAlignment = StringAlignment.Far; + sf.Alignment = StringAlignment.Near; + break; + + case Alignment.BottomCenter: + sf.LineAlignment = StringAlignment.Far; + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.BottomRight: + sf.LineAlignment = StringAlignment.Far; + sf.Alignment = StringAlignment.Far; + break; + } + } + + #endregion + + #region GetTextFormatFlags + + internal eTextFormat GetTextFormatFlags() + { + eTextFormat tf = eTextFormat.WordEllipsis | + eTextFormat.NoPadding | eTextFormat.NoPrefix; + + if (AllowWrap == Tbool.True) + tf |= eTextFormat.WordBreak; + + switch (Alignment) + { + case Alignment.TopCenter: + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.TopRight: + tf |= eTextFormat.Right; + break; + + case Alignment.MiddleLeft: + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.NotSet: + case Alignment.MiddleCenter: + tf |= eTextFormat.HorizontalCenter; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleRight: + tf |= eTextFormat.Right; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.BottomLeft: + tf |= eTextFormat.Bottom; + break; + + case Alignment.BottomCenter: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.BottomRight: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.Right; + break; + } + + return (tf); + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ContainerVisualStyle style) + { + base.ApplyStyle(style); + + if (style != null) + { + if (style.Alignment != Alignment.NotSet) + Alignment = style.Alignment; + + if (style.AllowWrap != Tbool.NotSet) + AllowWrap = style.AllowWrap; + + if (style._DropShadow != null && style.DropShadow.IsEmpty == false) + DropShadow.ApplyStyle(style.DropShadow); + + if (style.EnableImageScroll != Tbool.NotSet) + EnableImageScroll = style.EnableImageScroll; + + if (style.ImageIndex >= 0) + { + Image = null; + ImageIndex = style.ImageIndex; + } + + if (style.Image != null) + { + Image = style.Image; + ImageIndex = -1; + } + + if (style.ImageAlignment != Alignment.NotSet) + ImageAlignment = style.ImageAlignment; + + if (style.ImageList != null) + ImageList = style.ImageList; + + if (style._ImagePadding != null && style._ImagePadding.IsEmpty == false) + ImagePadding = style._ImagePadding.Copy(); + + if (style.ImageOverlay != ImageOverlay.NotSet) + ImageOverlay = style.ImageOverlay; + + if (style.ImageSizeMode != ImageSizeMode.NotSet) + ImageSizeMode = style.ImageSizeMode; + + if (style._SymbolDef != null && style._SymbolDef.IsEmpty == false) + SymbolDef = style._SymbolDef.Copy(); + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + base.ApplyDefaults(); + + if (_SymbolDef != null && _SymbolDef.IsValidSymbol == true) + { + if (_SymbolDef.SymbolSize == 0) + { + if (Font != null) + _SymbolDef.SymbolSize = Font.SizeInPoints; + } + + if (_SymbolDef.SymbolColor.IsEmpty == true) + { + _SymbolDef.SymbolColor = + (TextColor.IsEmpty == false) ? TextColor : Color.Black; + } + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ContainerVisualStyle Copy() + { + ContainerVisualStyle style = new ContainerVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ContainerVisualStyle style) + { + base.CopyTo(style); + + style.Alignment = _Alignment; + style.AllowWrap = _AllowWrap; + style.DropShadow = (_DropShadow != null) ? DropShadow.Copy() : null; + style.EnableImageScroll = _EnableImageScroll; + + style.Image = _Image; + style.ImageAlignment = _ImageAlignment; + style.ImageIndex = _ImageIndex; + style.ImageList = _ImageList; + style.ImageOverlay = _ImageOverlay; + style.ImagePadding = (_ImagePadding != null) ? _ImagePadding.Copy() : null; + style.ImageSizeMode = _ImageSizeMode; + + style.SymbolDef = (_SymbolDef != null) ? _SymbolDef.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ContainerVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("Alignment", Alignment, Alignment.NotSet); + sec.AddValue("AllowWrap", AllowWrap, Tbool.NotSet); + + if (_DropShadow != null && _DropShadow.IsEmpty == false) + sec.AddElement(_DropShadow.GetSerialData("DropShadow")); + + sec.AddValue("EnableImageScroll", EnableImageScroll, Tbool.NotSet); + sec.AddValue("Image", Image); + sec.AddValue("ImageAlignment", ImageAlignment, Alignment.NotSet); + sec.AddValue("ImageIndex", ImageIndex, -1); + + if (_ImageList != null) + sec.AddValue("ImageList", XmlSerializableImageList.ConvertToString(ImageList)); + + sec.AddValue("ImageOverlay", ImageOverlay, ImageOverlay.NotSet); + + if (_ImagePadding != null && _ImagePadding.IsEmpty == false) + sec.AddElement(_ImagePadding.GetSerialData("ImagePadding")); + + sec.AddValue("ImageSizeMode", ImageSizeMode, ImageSizeMode.NotSet); + + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + sec.AddElement(_SymbolDef.GetSerialData("SymbolDef")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement("ContainerVisualStyle"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Alignment": + Alignment = (Alignment)se.GetValueEnum(typeof(Alignment)); + break; + + case "AllowWrap": + AllowWrap = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "EnableImageScroll": + EnableImageScroll = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "Image": + Image = se.GetValueImage(); + break; + + case "ImageAlignment": + ImageAlignment = (Alignment)se.GetValueEnum(typeof(Alignment)); + break; + + case "ImageIndex": + ImageIndex = int.Parse(se.StringValue); + break; + + case "ImageList": + ImageList = XmlSerializableImageList.ConvertFromString(se.StringValue); + break; + + case "ImageOverlay": + ImageOverlay = (ImageOverlay)se.GetValueEnum(typeof(ImageOverlay)); + break; + + case "ImageSizeMode": + ImageSizeMode = (ImageSizeMode)se.GetValueEnum(typeof(ImageSizeMode)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "DropShadow": + sec.PutSerialData(DropShadow); + break; + + case "ImagePadding": + sec.PutSerialData(ImagePadding); + break; + + case "SymbolDef": + sec.PutSerialData(SymbolDef); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + DropShadow = null; + ImagePadding = null; + SymbolDef = null; + + base.Dispose(); + } + + #endregion + } + + #region ImageOverlay + + /// + /// How to Overlay the Image with + /// respect to the content + /// + public enum ImageOverlay + { + /// + /// Not set + /// + NotSet = -1, + + /// + /// None - Overlaying of the image will be avioded (when possible) + /// + None, + + /// + /// Top + /// + Top, + + /// + /// Middle + /// + Middle, + + /// + /// Bottom + /// + Bottom, + } + + #endregion + + #region ImageSizeMode + + /// + /// ImageSizeMode + /// + public enum ImageSizeMode + { + /// + /// Not set + /// + NotSet = -1, + + /// + /// The image is placed according to the specified + /// Alignment, and is clipped if needed to fit. + /// + Normal, + + /// + /// The image is stretched or shrunk to fit. + /// + Stretch, + + /// + /// The image is tiled to fill the area. + /// + Tile, + + /// + /// The size of the image is increased or decreased to fit the + /// area, maintaining the image size ratio. + /// + Zoom, + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/CrosshairValuelVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/CrosshairValuelVisualStyle.cs new file mode 100644 index 00000000..0e4eb0c6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/CrosshairValuelVisualStyle.cs @@ -0,0 +1,269 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of an element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class CrosshairValueVisualStyle : VisualStyle + { + #region Private variables + + private string _TextFormat; + private DropShadowVisualStyle _DropShadow; + + #endregion + + #region Public properties + + #region DropShadow + + /// + /// Gets or sets the visual style for the DropShadow. + /// + [Category("Style")] + [Description("Indicates the visual style for the DropShadow.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DropShadowVisualStyle DropShadow + { + get + { + if (_DropShadow == null) + { + _DropShadow = new DropShadowVisualStyle(); + + UpdateChangeHandler(null, _DropShadow); + } + + return (_DropShadow); + } + + set + { + if (_DropShadow != value) + { + DropShadowVisualStyle oldValue = _DropShadow; + + _DropShadow = value; + + OnStyleChanged("DropShadow", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region TextFormat + + /// + /// Gets or sets the Text Format specifier + /// + [DefaultValue(null)] + [Description("Indicates the Text Format specifier")] + public string TextFormat + { + get { return (_TextFormat); } + + set + { + if (_TextFormat != value) + { + _TextFormat = value; + + OnPropertyChangedEx("TextFormat", VisualChangeType.Render); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_DropShadow == null || _DropShadow.IsEmpty) && + (string.IsNullOrEmpty(_TextFormat) == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(CrosshairValueVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._DropShadow != null && style.DropShadow.IsEmpty == false) + DropShadow.ApplyStyle(style.DropShadow); + + if (string.IsNullOrEmpty(style.TextFormat) == false) + _TextFormat = style.TextFormat; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (Background.IsEmpty == true) + Background = new Background(ControlPaint.LightLight(Color.Fuchsia)); + + if (BorderColor.IsEmpty == true) + BorderColor = new BorderColor(Color.Black); + + if (BorderPattern.IsEmpty == true) + BorderPattern = new BorderPattern(LinePattern.Solid); + + if (BorderThickness.IsEmpty == true) + BorderThickness = new Thickness(1); + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new CrosshairValueVisualStyle Copy() + { + CrosshairValueVisualStyle style = new CrosshairValueVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(CrosshairValueVisualStyle style) + { + base.CopyTo(style); + + style.DropShadow = (_DropShadow != null) ? DropShadow.Copy() : null; + style.TextFormat = _TextFormat; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "CrosshairValueVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_DropShadow != null && _DropShadow.IsEmpty == false) + sec.AddElement(_DropShadow.GetSerialData("DropShadow")); + + sec.AddValue("TextFormat", TextFormat, null); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "TextFormat": + TextFormat = se.StringValue; + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "DropShadow": + sec.PutSerialData(DropShadow); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + DropShadow = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/CrosshairVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/CrosshairVisualStyle.cs new file mode 100644 index 00000000..9cd4fbe4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/CrosshairVisualStyle.cs @@ -0,0 +1,778 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of an element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class CrosshairVisualStyle : BaseVisualStyle + { + #region Private variables + + private Background _Background; + private Color _BorderColor = Color.Empty; + private LinePattern _BorderPattern = LinePattern.NotSet; + private int _BorderThickness; + + private Color _TextColor = Color.Empty; + + private ChartLineVisualStyle _ValueXLineStyle; + private ChartLineVisualStyle _ValueYLineStyle; + + private Font _GroupHeaderFont; + private Color _GroupHeaderTextColor = Color.Empty; + + private Font _Font; + private Padding _Margin; + private Padding _Padding; + + #endregion + + #region Public properties + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region BorderColor + + /// + /// Gets or sets the style border color. + /// + [Description("Indicates the style Border Color")] + public Color BorderColor + { + get { return (_BorderColor); } + + set + { + if (_BorderColor != value) + { + _BorderColor = value; + + OnPropertyChangedEx("BorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderColor() + { + return (_BorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderColor() + { + BorderColor = Color.Empty; + } + + #endregion + + #region BorderPattern + + /// + /// Gets or sets the style border pattern (Solid, Dash, ...) + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the style border pattern (Solid, Dash, ...)")] + public LinePattern BorderPattern + { + get { return (_BorderPattern); } + + set + { + if (_BorderPattern != value) + { + _BorderPattern = value; + + OnPropertyChangedEx("BorderPattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region BorderThickness + + /// + /// Gets or sets the style border thickness. + /// + [DefaultValue(0)] + [Description("Indicates the style border thickness")] + public int BorderThickness + { + get { return (_BorderThickness); } + + set + { + if (_BorderThickness != value) + { + _BorderThickness = value; + + OnPropertyChangedEx("BorderThickness", VisualChangeType.Render); + } + } + } + + #endregion + + #region GroupHeaderFont + + /// + /// Gets or sets the GroupHeader Font + /// + [DefaultValue(null)] + [Description("Indicates the GroupHeader Font")] + public Font GroupHeaderFont + { + get { return (_GroupHeaderFont); } + + set + { + if (_GroupHeaderFont != value) + { + _GroupHeaderFont = value; + + OnPropertyChangedEx("GroupHeaderFont", VisualChangeType.Render); + } + } + } + + #endregion + + #region GroupHeaderTextColor + + /// + /// Gets or sets the Color of the GroupHeaderText. + /// + [Category("Appearance")] + [Description("Indicates the Color of the GroupHeaderText.")] + public Color GroupHeaderTextColor + { + get { return (_GroupHeaderTextColor); } + + set + { + if (_GroupHeaderTextColor != value) + { + _GroupHeaderTextColor = value; + + OnPropertyChangedEx("GroupHeaderTextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeGroupHeaderTextColor() + { + return (_GroupHeaderTextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetGroupHeaderTextColor() + { + GroupHeaderTextColor = Color.Empty; + } + + #endregion + + #region Font + + /// + /// Gets or sets the Font + /// + [DefaultValue(null)] + [Description("Indicates the Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Render); + } + } + } + + #endregion + + #region Margin + + /// + /// Gets or sets the spacing between the border and outside content. + /// + [Description("Indicates the spacing between the border and outside content")] + public Padding Margin + { + get + { + if (_Margin == null) + { + _Margin = Padding.Empty; + + UpdateChangeHandler(null, _Margin); + } + + return (_Margin); + } + + set + { + if (_Margin != value) + { + UpdateChangeHandler(_Margin, value); + + _Margin = value; + + OnPropertyChangedEx("Margin", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeMargin() + { + return (_Margin != null && _Margin.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetMargin() + { + Margin = null; + } + + #endregion + + #region Padding + + /// + /// Gets or sets spacing between the content and edges of the element. + /// + [Description("Indicates the spacing between the content and edges of the element")] + public Padding Padding + { + get + { + if (_Padding == null) + { + _Padding = Padding.Empty; + + UpdateChangeHandler(null, _Padding); + } + + return (_Padding); + } + + set + { + if (_Padding != value) + { + UpdateChangeHandler(_Padding, value); + + _Padding = value; + + OnPropertyChangedEx("Padding", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializePadding() + { + return (_Padding != null && _Padding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetPadding() + { + Padding = null; + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color + /// + [Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + TextColor = Color.Empty; + } + + #endregion + + #region ValueXLineStyle + + /// + /// Gets or sets the visual style for the X Value Line. + /// + [Category("Style")] + [Description("Indicates the visual style for the X Value Line.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle ValueXLineStyle + { + get + { + if (_ValueXLineStyle == null) + { + _ValueXLineStyle = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _ValueXLineStyle); + } + + return (_ValueXLineStyle); + } + + set + { + if (_ValueXLineStyle != value) + { + ChartLineVisualStyle oldValue = _ValueXLineStyle; + + _ValueXLineStyle = value; + + OnStyleChanged("ValueXLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ValueYLineStyle + + /// + /// Gets or sets the visual style for the Y Value Line. + /// + [Category("Style")] + [Description("Indicates the visual style for the Y Value Line.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle ValueYLineStyle + { + get + { + if (_ValueYLineStyle == null) + { + _ValueYLineStyle = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _ValueYLineStyle); + } + + return (_ValueYLineStyle); + } + + set + { + if (_ValueYLineStyle != value) + { + ChartLineVisualStyle oldValue = _ValueYLineStyle; + + _ValueYLineStyle = value; + + OnStyleChanged("ValueYLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Background == null || _Background.IsEmpty == true) && + (_BorderColor.IsEmpty == true) && + (_BorderPattern == LinePattern.NotSet) && + (_BorderThickness <= 0) && + (_GroupHeaderFont == null) && + (_Font == null) && + (_GroupHeaderTextColor.IsEmpty == true) && + (_Margin == null || _Margin.IsEmpty == true) && + (_Padding == null || _Padding.IsEmpty == true) && + (_TextColor.IsEmpty == true) && + (_ValueXLineStyle == null || _ValueXLineStyle.IsEmpty) && + (_ValueYLineStyle == null || _ValueYLineStyle.IsEmpty) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(CrosshairVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style._BorderColor.IsEmpty == false) + BorderColor = style._BorderColor; + + if (style._BorderPattern != LinePattern.NotSet) + BorderPattern = style._BorderPattern; + + if (style._BorderThickness > 0) + BorderThickness = style._BorderThickness; + + if (style.GroupHeaderFont != null) + GroupHeaderFont = style.GroupHeaderFont; + + if (style._Font != null) + Font = style.Font; + + if (style.GroupHeaderTextColor.IsEmpty == false) + GroupHeaderTextColor = style.GroupHeaderTextColor; + + if (style._Margin != null && style._Margin.IsEmpty == false) + Margin = style.Margin.Copy(); + + if (style._Padding != null && style._Padding.IsEmpty == false) + Padding = style.Padding.Copy(); + + if (style._TextColor.IsEmpty == false) + TextColor = style._TextColor; + + if (style._ValueXLineStyle != null && style.ValueXLineStyle.IsEmpty == false) + ValueXLineStyle.ApplyStyle(style.ValueXLineStyle); + + if (style._ValueYLineStyle != null && style.ValueYLineStyle.IsEmpty == false) + ValueYLineStyle.ApplyStyle(style.ValueYLineStyle); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new CrosshairVisualStyle Copy() + { + CrosshairVisualStyle style = new CrosshairVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(CrosshairVisualStyle style) + { + base.CopyTo(style); + + style.Background = (_Background != null) ? _Background.Copy() : null; + + style.BorderColor = _BorderColor; + style.BorderPattern = _BorderPattern; + style.BorderThickness = _BorderThickness; + + style.GroupHeaderFont = (_GroupHeaderFont != null) ? (Font)_GroupHeaderFont.Clone() : null; + style.GroupHeaderTextColor = _GroupHeaderTextColor; + + style.Font = (_Font != null) ? (Font)_Font.Clone() : null; + style.Margin = (_Margin != null) ? _Margin.Copy() : null; + style.Padding = (_Padding != null) ? _Padding.Copy() : null; + + style.TextColor = _TextColor; + + style.ValueXLineStyle = (_ValueXLineStyle != null) ? _ValueXLineStyle.Copy() : null; + style.ValueYLineStyle = (_ValueYLineStyle != null) ? _ValueYLineStyle.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "CrosshairVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + sec.AddValue("BorderColor", BorderColor, Color.Empty); + sec.AddValue("BorderPattern", BorderPattern, LinePattern.NotSet); + sec.AddValue("BorderThickness", BorderThickness, 0); + + if (_GroupHeaderFont != null) + sec.AddValue("GroupHeaderFont", XmlSerializableFont.ConvertToString(GroupHeaderFont)); + + sec.AddValue("GroupHeaderTextColor", GroupHeaderTextColor, Color.Empty); + + if (_Font != null) + sec.AddValue("Font", XmlSerializableFont.ConvertToString(Font)); + + if (_Margin != null && _Margin.IsEmpty == false) + sec.AddElement(_Margin.GetSerialData("Margin")); + + if (_Padding != null && _Padding.IsEmpty == false) + sec.AddElement(_Padding.GetSerialData("Padding")); + + sec.AddValue("TextColor", TextColor, Color.Empty); + + if (_ValueXLineStyle != null && _ValueXLineStyle.IsEmpty == false) + sec.AddElement(_ValueXLineStyle.GetSerialData("ValueXLineStyle")); + + if (_ValueYLineStyle != null && _ValueYLineStyle.IsEmpty == false) + sec.AddElement(_ValueYLineStyle.GetSerialData("ValueYLineStyle")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "BorderColor": + BorderColor = se.GetValueColor(); + break; + + case "BorderPattern": + BorderPattern = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "BorderThickness": + BorderThickness = int.Parse(se.StringValue); + break; + + case "GroupHeaderFont": + GroupHeaderFont = XmlSerializableFont.ConvertFromString(se.StringValue); + break; + + case "GroupHeaderTextColor": + GroupHeaderTextColor = se.GetValueColor(); + break; + + case "Font": + Font = XmlSerializableFont.ConvertFromString(se.StringValue); + break; + + case "TextColor": + TextColor = se.GetValueColor(); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "Background": + sec.PutSerialData(Background); + break; + + case "Margin": + sec.PutSerialData(Margin); + break; + + case "Padding": + sec.PutSerialData(Padding); + break; + + case "ValueXLineStyle": + sec.PutSerialData(ValueXLineStyle); + break; + + case "ValueYLineStyle": + sec.PutSerialData(ValueYLineStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Margin = null; + Padding = null; + ValueXLineStyle = null; + ValueYLineStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DataLabelVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DataLabelVisualStyle.cs new file mode 100644 index 00000000..43c997a3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DataLabelVisualStyle.cs @@ -0,0 +1,1221 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents a SeriesLabelVisualStyle. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class DataLabelVisualStyle : BaseVisualStyle + { + #region Private variables + + private ConnectorLineVisualStyle _ConnectorLineStyle; + + private Tbool _CenterLabel = Tbool.NotSet; + private Tbool _DrawConnector = Tbool.NotSet; + private Tbool _DrawPointMarker = Tbool.NotSet; + + private RotateDegrees _RotateDegrees = RotateDegrees.NotSet; + + private Background _Background; + private Color _BorderColor = Color.Empty; + private LinePattern _BorderPattern = LinePattern.NotSet; + private int _BorderThickness = -1; + private Padding _Padding; + + private Font _Font; + private Color _TextColor = Color.Empty; + private LineAlignment _TextAlignment = LineAlignment.NotSet; + + private Background _HighlightBackground; + private Color _HighlightBorderColor = Color.Empty; + private LinePattern _HighlightBorderPattern = LinePattern.NotSet; + private Color _HighlightTextColor = Color.Empty; + + private int _MaxTextLineCount = -1; + private int _MaxTextWidth = -1; + + private string _TextFormat; + private DropShadowVisualStyle _DropShadow; + + #endregion + + #region Public properties + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region BorderColor + + /// + /// Gets or sets the style border color. + /// + [Description("Indicates the style Border Color")] + public Color BorderColor + { + get { return (_BorderColor); } + + set + { + if (value != _BorderColor) + { + _BorderColor = value; + + OnPropertyChangedEx("BorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderColor() + { + return (_BorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderColor() + { + _BorderColor = Color.Empty; + } + + #endregion + + #region BorderPattern + + /// + /// Gets or sets the style border pattern (Solid, Dash, ...) + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the style border pattern (Solid, Dash, ...)")] + public LinePattern BorderPattern + { + get { return (_BorderPattern); } + + set + { + if (value != _BorderPattern) + { + _BorderPattern = value; + + OnPropertyChangedEx("BorderPattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region BorderThickness + + /// + /// Gets or sets the style border thickness. + /// + [Description("Indicates the style border thickness")] + [DefaultValue(-1)] + public int BorderThickness + { + get { return (_BorderThickness); } + + set + { + if (value != _BorderThickness) + { + _BorderThickness = value; + + OnPropertyChangedEx("BorderThickness", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DropShadow + + /// + /// Gets or sets the visual style for the DropShadow. + /// + [Category("Style")] + [Description("Indicates the visual style for the DropShadow.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DropShadowVisualStyle DropShadow + { + get + { + if (_DropShadow == null) + { + _DropShadow = new DropShadowVisualStyle(); + + UpdateChangeHandler(null, _DropShadow); + } + + return (_DropShadow); + } + + set + { + if (_DropShadow != value) + { + DropShadowVisualStyle oldValue = _DropShadow; + + _DropShadow = value; + + OnStyleChanged("DropShadow", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font + /// + [DefaultValue(null)] + [Description("Indicates the style Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color + /// + [Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + _TextColor = Color.Empty; + } + + #endregion + + #region CenterLabel + + /// + /// Gets or sets whether the label is centered on top of the data point. + /// + [DefaultValue(Tbool.NotSet), Category("DataLabel")] + [Description("Indicates whether the label is centered on top of the data point.")] + public Tbool CenterLabel + { + get { return (_CenterLabel); } + + set + { + if (value != _CenterLabel) + { + _CenterLabel = value; + + OnPropertyChangedEx("CenterLabel", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region ConnectorStyle + + /// + /// Gets or sets the visual style for the line Connector. + /// + [Category("Style")] + [Description("Indicates the visual style for the line Connector.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [NotifyParentProperty(true)] + public ConnectorLineVisualStyle ConnectorLineStyle + { + get + { + if (_ConnectorLineStyle == null) + { + _ConnectorLineStyle = new ConnectorLineVisualStyle(); + + UpdateChangeHandler(null, _ConnectorLineStyle); + } + + return (_ConnectorLineStyle); + } + + set + { + if (_ConnectorLineStyle != value) + { + ConnectorLineVisualStyle oldValue = _ConnectorLineStyle; + + _ConnectorLineStyle = value; + + OnStyleChanged("ConnectorLineStyle", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region DrawConnector + + /// + /// Gets or sets whether a connecting line is drawn to the data point. + /// + [DefaultValue(Tbool.NotSet), Category("DataLabel")] + [Description("Indicates whether a connecting line is drawn to the data point.")] + public Tbool DrawConnector + { + get { return (_DrawConnector); } + + set + { + if (value != _DrawConnector) + { + _DrawConnector = value; + + OnPropertyChangedEx("DrawConnector", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region DrawPointMarker + + /// + /// Gets or sets whether the associated Point Marker is drawn for the data point. + /// + [DefaultValue(Tbool.NotSet), Category("DataLabel")] + [Description("Indicates whether the associated Point Marker is drawn for the data point.")] + public Tbool DrawPointMarker + { + get { return (_DrawPointMarker); } + + set + { + if (value != _DrawPointMarker) + { + _DrawPointMarker = value; + + OnPropertyChangedEx("DrawPointMarker", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region HighlightBackground + + /// + /// Gets or sets the Highlight style background. + /// + [Description("Indicates the Highlight style background")] + public Background HighlightBackground + { + get + { + if (_HighlightBackground == null) + { + _HighlightBackground = Background.Empty; + + UpdateChangeHandler(null, _HighlightBackground); + } + + return (_HighlightBackground); + } + + set + { + if (_HighlightBackground != value) + { + UpdateChangeHandler(_HighlightBackground, value); + + _HighlightBackground = value; + + OnPropertyChangedEx("HighlightBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeHighlightBackground() + { + return (_HighlightBackground != null && _HighlightBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetHighlightBackground() + { + HighlightBackground = null; + } + + #endregion + + #region HighlightBorderColor + + /// + /// Gets or sets the Highlight style border color. + /// + [Description("Indicates the Highlight style Border Color")] + public Color HighlightBorderColor + { + get { return (_HighlightBorderColor); } + + set + { + if (value != _HighlightBorderColor) + { + _HighlightBorderColor = value; + + OnPropertyChangedEx("HighlightBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeHighlightBorderColor() + { + return (_HighlightBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetHighlightBorderColor() + { + _HighlightBorderColor = Color.Empty; + } + + #endregion + + #region HighlightBorderPattern + + /// + /// Gets or sets the Highlight style border pattern (Solid, Dash, ...) + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Highlight style border pattern (Solid, Dash, ...)")] + public LinePattern HighlightBorderPattern + { + get { return (_HighlightBorderPattern); } + + set + { + if (value != _HighlightBorderPattern) + { + _HighlightBorderPattern = value; + + OnPropertyChangedEx("HighlightBorderPattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region HighlightTextColor + + /// + /// Gets or sets the Highlight Text color + /// + [Description("Indicates the Highlight Text color")] + public Color HighlightTextColor + { + get { return (_HighlightTextColor); } + + set + { + if (value != _HighlightTextColor) + { + _HighlightTextColor = value; + + OnPropertyChangedEx("HighlightTextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeHighlightTextColor() + { + return (_HighlightTextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetHighlightTextColor() + { + _HighlightTextColor = Color.Empty; + } + + #endregion + + #region MaxTextLineCount + + /// + /// Gets or sets the maximum number of Label Text lines. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the maximum number of Label Text lines.")] + public int MaxTextLineCount + { + get { return (_MaxTextLineCount); } + + set + { + if (value != _MaxTextLineCount) + { + _MaxTextLineCount = value; + + OnPropertyChangedEx("MaxTextLineCount", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxTextWidth + + /// + /// Gets or sets the maximum width of the label text. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the maximum width of the label text.")] + public int MaxTextWidth + { + get { return (_MaxTextWidth); } + + set + { + if (value != _MaxTextWidth) + { + _MaxTextWidth = value; + + OnPropertyChangedEx("MaxTextWidth", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Padding + + /// + /// Gets or sets spacing between the content and edges of the element. + /// + [Description("Indicates the spacing between the content and edges of the element")] + public Padding Padding + { + get + { + if (_Padding == null) + { + _Padding = Padding.Empty; + + UpdateChangeHandler(null, _Padding); + } + + return (_Padding); + } + + set + { + if (_Padding != value) + { + UpdateChangeHandler(_Padding, value); + + _Padding = value; + + OnPropertyChangedEx("Padding", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializePadding() + { + return (_Padding != null && _Padding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetPadding() + { + Padding = null; + } + + #endregion + + #region RotateDegrees + + /// + /// Gets or sets the label display rotation. + /// + [DefaultValue(RotateDegrees.NotSet), Category("Appearance")] + [Description("Indicates the label display rotation.")] + public RotateDegrees RotateDegrees + { + get { return (_RotateDegrees); } + + set + { + if (value != _RotateDegrees) + { + _RotateDegrees = value; + + OnPropertyChangedEx("RotateDegrees", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TextAlignment + + /// + /// Gets or sets the alignment of the text + /// + [DefaultValue(LineAlignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the text.")] + public LineAlignment TextAlignment + { + get { return (_TextAlignment); } + + set + { + if (value != _TextAlignment) + { + _TextAlignment = value; + + OnPropertyChangedEx("TextAlignment", VisualChangeType.Render); + } + } + } + + #endregion + + #region TextFormat + + // "{S}\\n{X:yyyy} ({Y:##,##0})" + // "{Y:C}" + // "X", "Y", "Y0", "Yn" + // "S" (name) + + /// + /// Gets or sets the Text Format specifier + /// + [DefaultValue(null)] + [Description("Indicates the Text Format specifier")] + public string TextFormat + { + get { return (_TextFormat); } + + set + { + if (_TextFormat != value) + { + _TextFormat = value; + + OnPropertyChangedEx("TextFormat", VisualChangeType.Render); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Background == null || _Background.IsEmpty == true) && + (_BorderColor.IsEmpty == true) && + (_BorderPattern == LinePattern.NotSet) && + (_BorderThickness < 0) && + (_CenterLabel == Tbool.NotSet) && + (_ConnectorLineStyle != null && _ConnectorLineStyle.IsEmpty == true) && + (_DrawConnector == Tbool.NotSet) && + (_DrawPointMarker == Tbool.NotSet) && + (_DropShadow == null || _DropShadow.IsEmpty) && + (_HighlightBackground == null || _HighlightBackground.IsEmpty == true) && + (_HighlightBorderColor.IsEmpty == true) && + (_HighlightBorderPattern == LinePattern.NotSet) && + (_HighlightTextColor.IsEmpty == true) && + (_MaxTextLineCount == -1) && + (_MaxTextWidth == -1) && + (_Padding == null || _Padding.IsEmpty == true) && + (_RotateDegrees == RotateDegrees.NotSet) && + (_TextAlignment == LineAlignment.NotSet) && + (_TextColor.IsEmpty == true) && + (string.IsNullOrEmpty(_TextFormat) == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region HasBorder + + internal bool HasBorder + { + get { return (BorderPattern != LinePattern.None && + BorderColor.IsEmpty == false && BorderThickness > 0); } + } + + #endregion + + #region HasHighlightBorder + + internal bool HasHighlightBorder + { + get + { + return (HighlightBorderPattern != LinePattern.None && + HighlightBorderColor.IsEmpty == false && BorderThickness > 0); + } + } + + #endregion + + #endregion + + #region GetStringFormatFlags + + internal void GetStringFormatFlags(StringFormat sf) + { + sf.LineAlignment = StringAlignment.Center; + + switch (TextAlignment) + { + case LineAlignment.Far: + sf.Alignment = StringAlignment.Far; + break; + + case LineAlignment.Center: + sf.Alignment = StringAlignment.Center; + break; + + default: + sf.Alignment = StringAlignment.Near; + break; + } + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(DataLabelVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style.Background.Copy(); + + if (style.BorderColor.IsEmpty == false) + BorderColor = style.BorderColor; + + if (style._BorderPattern != LinePattern.NotSet) + BorderPattern = style.BorderPattern; + + if (style.BorderThickness >= 0) + BorderThickness = style.BorderThickness; + + if (style.ConnectorLineStyle.IsEmpty == false) + ConnectorLineStyle.ApplyStyle(style.ConnectorLineStyle); + + if (style.CenterLabel != Tbool.NotSet) + CenterLabel = style.CenterLabel; + + if (style.DrawConnector != Tbool.NotSet) + DrawConnector = style.DrawConnector; + + if (style.DrawPointMarker != Tbool.NotSet) + DrawPointMarker = style.DrawPointMarker; + + if (style._DropShadow != null && style.DropShadow.IsEmpty == false) + DropShadow.ApplyStyle(style.DropShadow); + + if (style.Font != null) + Font = (Font)style.Font.Clone(); + + if (style._HighlightBackground != null && style._HighlightBackground.IsEmpty == false) + HighlightBackground = style.HighlightBackground.Copy(); + + if (style.HighlightBorderColor.IsEmpty == false) + HighlightBorderColor = style.HighlightBorderColor; + + if (style.HighlightBorderPattern != LinePattern.NotSet) + HighlightBorderPattern = style.HighlightBorderPattern; + + if (style.HighlightTextColor.IsEmpty == false) + HighlightTextColor = style.HighlightTextColor; + + if (style.MaxTextLineCount >= 0) + MaxTextLineCount = style.MaxTextLineCount; + + if (style.MaxTextWidth >= 0) + MaxTextWidth = style.MaxTextWidth; + + if (style._Padding != null && style._Padding.IsEmpty == false) + Padding = style.Padding.Copy(); + + if (style.RotateDegrees != RotateDegrees.NotSet) + RotateDegrees = style.RotateDegrees; + + if (style.TextAlignment != LineAlignment.NotSet) + TextAlignment = style.TextAlignment; + + if (style.TextColor.IsEmpty == false) + TextColor = style.TextColor; + + if (string.IsNullOrEmpty(style.TextFormat) == false) + TextFormat = style.TextFormat; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (Font == null) + Font = SystemFonts.DefaultFont; + + if (TextColor.IsEmpty == true) + TextColor = Color.Black; + + if (BorderColor.IsEmpty == true) + BorderColor = Color.Black; + + if (BorderPattern == LinePattern.NotSet) + BorderPattern = LinePattern.Solid; + + if (BorderThickness < 0) + BorderThickness = 1; + + if (Background.IsEmpty) + Background = new Background(Color.WhiteSmoke); + + if (DrawConnector == Tbool.NotSet) + DrawConnector = Tbool.True; + + if (DrawPointMarker == Tbool.NotSet) + DrawPointMarker = Tbool.True; + + if (HighlightBackground.IsEmpty) + HighlightBackground = new Background(Color.Yellow); + + if (HighlightTextColor.IsEmpty == true) + HighlightTextColor = Color.Black; + + if (HighlightBorderColor.IsEmpty == true) + HighlightBorderColor = Color.Black; + + if (HighlightBorderPattern == LinePattern.NotSet) + HighlightBorderPattern = LinePattern.Solid; + + ConnectorLineStyle.ApplyDefaults(); + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new DataLabelVisualStyle Copy() + { + DataLabelVisualStyle style = new DataLabelVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(DataLabelVisualStyle style) + { + base.CopyTo(style); + + style.Background = (_Background == null) ? null : _Background.Copy(); + style.BorderColor = _BorderColor; + style.BorderPattern = _BorderPattern; + style.BorderThickness = _BorderThickness; + + style.ConnectorLineStyle = (_ConnectorLineStyle == null) ? null : _ConnectorLineStyle.Copy(); + + style.CenterLabel = _CenterLabel; + style.DrawConnector = _DrawConnector; + style.DrawPointMarker = _DrawPointMarker; + + style.DropShadow = (_DropShadow != null) ? DropShadow.Copy() : null; + style.Font = (_Font == null) ? null : (Font)_Font.Clone(); + + style.HighlightBackground = (_HighlightBackground == null) ? null : _HighlightBackground.Copy(); + style.HighlightBorderColor = _HighlightBorderColor; + style.HighlightBorderPattern = _HighlightBorderPattern; + style.HighlightTextColor = _HighlightTextColor; + + style.MaxTextLineCount = _MaxTextLineCount; + style.MaxTextWidth = _MaxTextWidth; + style.Padding = (_Padding == null) ? null : _Padding.Copy(); + style.RotateDegrees = _RotateDegrees; + + style.TextAlignment = _TextAlignment; + style.TextColor = _TextColor; + style.TextFormat = _TextFormat; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "DataLabelVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + sec.AddValue("BorderColor", BorderColor, Color.Empty); + sec.AddValue("BorderPattern", BorderPattern, LinePattern.NotSet); + sec.AddValue("BorderThickness", BorderThickness, -1); + + if (_ConnectorLineStyle != null && _ConnectorLineStyle.IsEmpty == false) + sec.AddElement(_ConnectorLineStyle.GetSerialData("ConnectorLineStyle")); + + sec.AddValue("CenterLabel", CenterLabel, Tbool.NotSet); + sec.AddValue("DrawConnector", DrawConnector, Tbool.NotSet); + sec.AddValue("DrawPointMarker", DrawPointMarker, Tbool.NotSet); + + if (_DropShadow != null && _DropShadow.IsEmpty == false) + sec.AddElement(_DropShadow.GetSerialData("DropShadow")); + + if (_Font != null) + sec.AddValue("Font", XmlSerializableFont.ConvertToString(Font)); + + if (_HighlightBackground != null && _HighlightBackground.IsEmpty == false) + sec.AddElement(_HighlightBackground.GetSerialData("HighlightBackground")); + + sec.AddValue("HighlightBorderColor", HighlightBorderColor, Color.Empty); + sec.AddValue("HighlightBorderPattern", HighlightBorderPattern, LinePattern.NotSet); + sec.AddValue("HighlightTextColor", HighlightTextColor, Color.Empty); + + sec.AddValue("MaxTextLineCount", MaxTextLineCount, -1); + sec.AddValue("MaxTextWidth", MaxTextWidth, -1); + + if (_Padding != null && _Padding.IsEmpty == false) + sec.AddElement(_Padding.GetSerialData("Padding")); + + sec.AddValue("RotateDegrees", RotateDegrees, RotateDegrees.NotSet); + sec.AddValue("TextAlignment", TextAlignment, LineAlignment.NotSet); + + sec.AddValue("TextColor", TextColor, Color.Empty); + sec.AddValue("TextFormat", TextFormat, null); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "BorderColor": + BorderColor = se.GetValueColor(); + break; + + case "BorderPattern": + BorderPattern = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "BorderThickness": + BorderThickness = int.Parse(se.StringValue); + break; + + case "CenterLabel": + CenterLabel = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "DrawConnector": + DrawConnector = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "DrawPointMarker": + DrawPointMarker = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "Font": + Font = XmlSerializableFont.ConvertFromString(se.StringValue); + break; + + case "HighlightBorderColor": + HighlightBorderColor = se.GetValueColor(); + break; + + case "HighlightBorderPattern": + HighlightBorderPattern = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "HighlightTextColor": + HighlightTextColor = se.GetValueColor(); + break; + + case "MaxTextLineCount": + MaxTextLineCount = int.Parse(se.StringValue); + break; + + case "MaxTextWidth": + MaxTextWidth = int.Parse(se.StringValue); + break; + + case "RotateDegrees": + RotateDegrees = (RotateDegrees)se.GetValueEnum(typeof(RotateDegrees)); + break; + + case "TextAlignment": + TextAlignment = (LineAlignment)se.GetValueEnum(typeof(LineAlignment)); + break; + + case "TextColor": + TextColor = se.GetValueColor(); + break; + + case "TextFormat": + TextFormat = se.StringValue; + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "Background": + sec.PutSerialData(Background); + break; + + case "ConnectorLineStyle": + sec.PutSerialData(ConnectorLineStyle); + break; + + case "DropShadow": + sec.PutSerialData(DropShadow); + break; + + case "HighlightBackground": + sec.PutSerialData(HighlightBackground); + break; + + case "Padding": + sec.PutSerialData(Padding); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + DropShadow = null; + ConnectorLineStyle = null; + HighlightBackground = null; + Padding = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DefaultVisualStyles.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DefaultVisualStyles.cs new file mode 100644 index 00000000..2e35a998 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DefaultVisualStyles.cs @@ -0,0 +1,1347 @@ +using System; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Defines set of default visual styles that are defined on the container control. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class DefaultVisualStyles : IProcessSerialElement, INotifyPropertyChanged, IDisposable + { + #region Private variables + + // Multi state style definitions + + private ContainerVisualStyles _ContainerVisualStyles; + + private ChartLegendVisualStyles _ChartLegendVisualStyles; + private ChartLegendItemVisualStyles _ChartLegendItemVisualStyles; + + private ChartSliceVisualStyles _SliceVisualStyles; + private ChartSliceVisualStyles _OtherSliceVisualStyles; + + private ScrollBarVisualStyles _HScrollBarVisualStyles; + private ScrollBarVisualStyles _VScrollBarVisualStyles; + + // Single state style definitions + + private ChartAxisVisualStyle _ChartXAxisVisualStyle; + private ChartAxisVisualStyle _ChartYAxisVisualStyle; + + private ChartPanelVisualStyle _ChartPanelVisualStyle; + private ChartSeriesVisualStyle _ChartSeriesVisualStyle; + private ChartTickmarkVisualStyle _ChartTickmarkVisualStyle; + private ChartTitleVisualStyle _ChartTitleVisualStyle; + private ChartXyVisualStyle _ChartXyVisualStyle; + private DataLabelVisualStyle _DataLabelVisualStyle; + + private CrosshairValueVisualStyle _CrosshairLabelVisualStyle; + private CrosshairVisualStyle _CrosshairVisualStyle; + + private DividerLineVisualStyle _DividerLineVisualStyle; + private PieGridLineVisualStyle _GridLineVisualStyle; + private PieChartVisualStyle _PieChartVisualStyle; + + private ReferenceLineVisualStyle _ReferenceLineVisualStyle; + private RegressionLineVisualStyle _RegressionLineVisualStyle; + private TrendLineVisualStyle _TrendLineVisualStyle; + + private TickmarkLabelVisualStyle _TickmarkLabelVisualStyle; + + #endregion + + #region Public properties + + #region ChartLegendItemVisualStyles + + /// + /// Gets or sets the visual styles to be used for ChartLegendItem elements + /// + [Category("Style")] + [Description("Indicates visual styles to be used for ChartLegendI tem elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendItemVisualStyles ChartLegendItemVisualStyles + { + get + { + if (_ChartLegendItemVisualStyles == null) + { + _ChartLegendItemVisualStyles = new ChartLegendItemVisualStyles(); + + StyleChangeHandler(null, _ChartLegendItemVisualStyles); + } + + return (_ChartLegendItemVisualStyles); + } + + set + { + if (value != _ChartLegendItemVisualStyles) + { + ChartLegendItemVisualStyles oldValue = _ChartLegendItemVisualStyles; + _ChartLegendItemVisualStyles = value; + + OnStyleChanged("ChartLegendVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region ChartLegendVisualStyles + + /// + /// Gets or sets the visual styles to be used for ChartLegend elements + /// + [Category("Style")] + [Description("Indicates visual styles to be used for ChartLegend elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLegendVisualStyles ChartLegendVisualStyles + { + get + { + if (_ChartLegendVisualStyles == null) + { + _ChartLegendVisualStyles = new ChartLegendVisualStyles(); + + StyleChangeHandler(null, _ChartLegendVisualStyles); + } + + return (_ChartLegendVisualStyles); + } + + set + { + if (value != _ChartLegendVisualStyles) + { + ChartLegendVisualStyles oldValue = _ChartLegendVisualStyles; + _ChartLegendVisualStyles = value; + + OnStyleChanged("ChartLegendVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region ChartPanelVisualStyle + + /// + /// Gets or sets the visual style to be used for ChartPanel elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for ChartPanel elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartPanelVisualStyle ChartPanelVisualStyle + { + get + { + if (_ChartPanelVisualStyle == null) + { + _ChartPanelVisualStyle = new ChartPanelVisualStyle(); + + StyleChangeHandler(null, _ChartPanelVisualStyle); + } + + return (_ChartPanelVisualStyle); + } + + set + { + if (_ChartPanelVisualStyle != value) + { + ChartPanelVisualStyle oldValue = _ChartPanelVisualStyle; + _ChartPanelVisualStyle = value; + + OnStyleChanged("ChartPanelVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region ChartSeriesVisualStyle + + /// + /// Gets or sets the visual style to be used for ChartSeries elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for ChartSeries elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSeriesVisualStyle ChartSeriesVisualStyle + { + get + { + if (_ChartSeriesVisualStyle == null) + { + _ChartSeriesVisualStyle = new ChartSeriesVisualStyle(); + + StyleChangeHandler(null, _ChartSeriesVisualStyle); + } + + return (_ChartSeriesVisualStyle); + } + + set + { + if (value != _ChartSeriesVisualStyle) + { + ChartSeriesVisualStyle oldValue = _ChartSeriesVisualStyle; + _ChartSeriesVisualStyle = value; + + OnStyleChanged("ChartSeriesVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region ChartTickmarkVisualStyle + + /// + /// Gets or sets the visual style to be used for chart Tickmark elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for chart Tickmark elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartTickmarkVisualStyle ChartTickmarkVisualStyle + { + get + { + if (_ChartTickmarkVisualStyle == null) + { + _ChartTickmarkVisualStyle = new ChartTickmarkVisualStyle(); + + StyleChangeHandler(null, _ChartTickmarkVisualStyle); + } + + return (_ChartTickmarkVisualStyle); + } + + set + { + if (_ChartTickmarkVisualStyle != value) + { + ChartTickmarkVisualStyle oldValue = _ChartTickmarkVisualStyle; + _ChartTickmarkVisualStyle = value; + + OnStyleChanged("ChartTickmarkVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region ChartTitleVisualStyle + + /// + /// Gets or sets the visual style to be used for ChartTitle elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for ChartTitle elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartTitleVisualStyle ChartTitleVisualStyle + { + get + { + if (_ChartTitleVisualStyle == null) + { + _ChartTitleVisualStyle = new ChartTitleVisualStyle(); + + StyleChangeHandler(null, _ChartTitleVisualStyle); + } + + return (_ChartTitleVisualStyle); + } + + set + { + if (_ChartTitleVisualStyle != value) + { + ChartTitleVisualStyle oldValue = _ChartTitleVisualStyle; + _ChartTitleVisualStyle = value; + + OnStyleChanged("ChartTitleVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region ChartXAxisVisualStyle + + /// + /// Gets or sets the visual style to be used for X Axis elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for X Axis elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartAxisVisualStyle ChartXAxisVisualStyle + { + get + { + if (_ChartXAxisVisualStyle == null) + { + _ChartXAxisVisualStyle = new ChartAxisVisualStyle(); + + StyleChangeHandler(null, _ChartXAxisVisualStyle); + } + + return (_ChartXAxisVisualStyle); + } + + set + { + if (_ChartXAxisVisualStyle != value) + { + ChartAxisVisualStyle oldValue = _ChartXAxisVisualStyle; + _ChartXAxisVisualStyle = value; + + OnStyleChanged("ChartXAxisVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region ChartXyVisualStyle + + /// + /// Gets or sets the visual style to be used for XyChart elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for XyChart elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartXyVisualStyle ChartXyVisualStyle + { + get + { + if (_ChartXyVisualStyle == null) + { + _ChartXyVisualStyle = new ChartXyVisualStyle(); + + StyleChangeHandler(null, _ChartXyVisualStyle); + } + + return (_ChartXyVisualStyle); + } + + set + { + if (_ChartXyVisualStyle != value) + { + ChartXyVisualStyle oldValue = _ChartXyVisualStyle; + _ChartXyVisualStyle = value; + + OnStyleChanged("ChartXyVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region ChartYAxisVisualStyle + + /// + /// Gets or sets the visual style to be used for Y Axis elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for Y Axis elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartAxisVisualStyle ChartYAxisVisualStyle + { + get + { + if (_ChartYAxisVisualStyle == null) + { + _ChartYAxisVisualStyle = new ChartAxisVisualStyle(); + + StyleChangeHandler(null, _ChartYAxisVisualStyle); + } + + return (_ChartYAxisVisualStyle); + } + + set + { + if (_ChartYAxisVisualStyle != value) + { + ChartAxisVisualStyle oldValue = _ChartYAxisVisualStyle; + _ChartYAxisVisualStyle = value; + + OnStyleChanged("ChartYAxisVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region ContainerVisualStyles + + /// + /// Gets or sets the visual stylse to be used for Chart Container elements + /// + [Category("Style")] + [Description("Indicates visual styles to be used for XyChart elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ContainerVisualStyles ContainerVisualStyles + { + get + { + if (_ContainerVisualStyles == null) + { + _ContainerVisualStyles = new ContainerVisualStyles(); + + StyleChangeHandler(null, _ContainerVisualStyles); + } + + return (_ContainerVisualStyles); + } + + set + { + if (_ContainerVisualStyles != value) + { + ContainerVisualStyles oldValue = _ContainerVisualStyles; + _ContainerVisualStyles = value; + + OnStyleChanged("ContainerVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region CrosshairLabelVisualStyle + + /// + /// Gets or sets the visual style to be used for Crosshair label elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for Crosshair label elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CrosshairValueVisualStyle CrosshairLabelVisualStyle + { + get + { + if (_CrosshairLabelVisualStyle == null) + { + _CrosshairLabelVisualStyle = new CrosshairValueVisualStyle(); + + StyleChangeHandler(null, _CrosshairLabelVisualStyle); + } + + return (_CrosshairLabelVisualStyle); + } + + set + { + if (_CrosshairLabelVisualStyle != value) + { + CrosshairValueVisualStyle oldValue = _CrosshairLabelVisualStyle; + _CrosshairLabelVisualStyle = value; + + OnStyleChanged("CrosshairLabelVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region CrosshairVisualStyle + + /// + /// Gets or sets the visual style to be used for Crosshair elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for Crosshair elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CrosshairVisualStyle CrosshairVisualStyle + { + get + { + if (_CrosshairVisualStyle == null) + { + _CrosshairVisualStyle = new CrosshairVisualStyle(); + + StyleChangeHandler(null, _CrosshairVisualStyle); + } + + return (_CrosshairVisualStyle); + } + + set + { + if (_CrosshairVisualStyle != value) + { + CrosshairVisualStyle oldValue = _CrosshairVisualStyle; + _CrosshairVisualStyle = value; + + OnStyleChanged("CrosshairVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region DataLabelVisualStyle + + /// + /// Gets or sets the visual style to be used for DataLabel elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for DataLabel elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DataLabelVisualStyle DataLabelVisualStyle + { + get + { + if (_DataLabelVisualStyle == null) + { + _DataLabelVisualStyle = new DataLabelVisualStyle(); + + StyleChangeHandler(null, _DataLabelVisualStyle); + } + + return (_DataLabelVisualStyle); + } + + set + { + if (value != _DataLabelVisualStyle) + { + DataLabelVisualStyle oldValue = _DataLabelVisualStyle; + _DataLabelVisualStyle = value; + + OnStyleChanged("DataLabelVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region DividerLineVisualStyle + + /// + /// Gets or sets the visual style to be used for DividerLine elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for DividerLine elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DividerLineVisualStyle DividerLineVisualStyle + { + get + { + if (_DividerLineVisualStyle == null) + { + _DividerLineVisualStyle = new DividerLineVisualStyle(); + + StyleChangeHandler(null, _DividerLineVisualStyle); + } + + return (_DividerLineVisualStyle); + } + + set + { + if (_DividerLineVisualStyle != value) + { + DividerLineVisualStyle oldValue = _DividerLineVisualStyle; + _DividerLineVisualStyle = value; + + OnStyleChanged("DividerLineVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region GridLineVisualStyle + + /// + /// Gets or sets the visual style to be used for GridLine elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for GridLine elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieGridLineVisualStyle GridLineVisualStyle + { + get + { + if (_GridLineVisualStyle == null) + { + _GridLineVisualStyle = new PieGridLineVisualStyle(); + + StyleChangeHandler(null, _GridLineVisualStyle); + } + + return (_GridLineVisualStyle); + } + + set + { + if (_GridLineVisualStyle != value) + { + PieGridLineVisualStyle oldValue = _GridLineVisualStyle; + _GridLineVisualStyle = value; + + OnStyleChanged("GridLinesVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region HScrollBarVisualStyles + + /// + /// Gets or sets the visual styles to be used for Horizontal ScrollBar elements + /// + [Category("Style")] + [Description("Indicates visual styles to be used for Horizontal ScrollBar elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarVisualStyles HScrollBarVisualStyles + { + get + { + if (_HScrollBarVisualStyles == null) + { + _HScrollBarVisualStyles = new ScrollBarVisualStyles(); + + StyleChangeHandler(null, _HScrollBarVisualStyles); + } + + return (_HScrollBarVisualStyles); + } + + set + { + if (_HScrollBarVisualStyles != value) + { + ScrollBarVisualStyles oldValue = _HScrollBarVisualStyles; + _HScrollBarVisualStyles = value; + + OnStyleChanged("HScrollBarVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region OtherSliceVisualStyles + + /// + /// Gets or sets the default visual style for the series 'Other' slice. + /// + [Category("Style")] + [Description("Indicates the default visual style for the series 'Other' slice.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSliceVisualStyles OtherSliceVisualStyles + { + get + { + if (_OtherSliceVisualStyles == null) + { + _OtherSliceVisualStyles = new ChartSliceVisualStyles(); + + StyleChangeHandler(null, _OtherSliceVisualStyles); + } + + return (_OtherSliceVisualStyles); + } + + set + { + if (_OtherSliceVisualStyles != value) + { + ChartSliceVisualStyles oldValue = _OtherSliceVisualStyles; + + _OtherSliceVisualStyles = value; + + OnStyleChanged("OtherSliceVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region PieChartVisualStyles + + /// + /// Gets or sets the visual style to be used for PieChart elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for PieChart elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieChartVisualStyle PieChartVisualStyle + { + get + { + if (_PieChartVisualStyle == null) + { + _PieChartVisualStyle = new PieChartVisualStyle(); + + StyleChangeHandler(null, _PieChartVisualStyle); + } + + return (_PieChartVisualStyle); + } + + set + { + if (_PieChartVisualStyle != value) + { + PieChartVisualStyle oldValue = _PieChartVisualStyle; + _PieChartVisualStyle = value; + + OnStyleChanged("PieChartVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region ReferenceLineVisualStyle + + /// + /// Gets or sets the visual style to be used for ReferenceLine elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for ReferenceLine elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ReferenceLineVisualStyle ReferenceLineVisualStyle + { + get + { + if (_ReferenceLineVisualStyle == null) + { + _ReferenceLineVisualStyle = new ReferenceLineVisualStyle(); + + StyleChangeHandler(null, _ReferenceLineVisualStyle); + } + + return (_ReferenceLineVisualStyle); + } + + set + { + if (_ReferenceLineVisualStyle != value) + { + ReferenceLineVisualStyle oldValue = _ReferenceLineVisualStyle; + _ReferenceLineVisualStyle = value; + + OnStyleChanged("ReferenceLineVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region RegressionLineVisualStyle + + /// + /// Gets or sets the visual style to be used for RegressionIndicator elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for RegressionIndicator elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public RegressionLineVisualStyle RegressionLineVisualStyle + { + get + { + if (_RegressionLineVisualStyle == null) + { + _RegressionLineVisualStyle = new RegressionLineVisualStyle(); + + StyleChangeHandler(null, _RegressionLineVisualStyle); + } + + return (_RegressionLineVisualStyle); + } + + set + { + if (_RegressionLineVisualStyle != value) + { + RegressionLineVisualStyle oldValue = _RegressionLineVisualStyle; + _RegressionLineVisualStyle = value; + + OnStyleChanged("RegressionLineVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region SliceVisualStyles + + /// + /// Gets or sets the visual style to be used for Pie Slice elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for Pie Slice elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartSliceVisualStyles SliceVisualStyles + { + get + { + if (_SliceVisualStyles == null) + { + _SliceVisualStyles = new ChartSliceVisualStyles(); + + StyleChangeHandler(null, _SliceVisualStyles); + } + + return (_SliceVisualStyles); + } + + set + { + if (value != _SliceVisualStyles) + { + ChartSliceVisualStyles oldValue = _SliceVisualStyles; + _SliceVisualStyles = value; + + OnStyleChanged("SliceVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region TickmarkLabelVisualStyle + + /// + /// Gets or sets the visual styles to be used for Axis Lable + /// + [Category("Style")] + [Description("Indicates visual styles to be used for Axis Lable ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TickmarkLabelVisualStyle TickmarkLabelVisualStyle + { + get + { + if (_TickmarkLabelVisualStyle == null) + { + _TickmarkLabelVisualStyle = new TickmarkLabelVisualStyle(); + + StyleChangeHandler(null, _TickmarkLabelVisualStyle); + } + + return (_TickmarkLabelVisualStyle); + } + + set + { + if (_TickmarkLabelVisualStyle != value) + { + TickmarkLabelVisualStyle oldValue = _TickmarkLabelVisualStyle; + _TickmarkLabelVisualStyle = value; + + OnStyleChanged("TickmarkLabelVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region TrendLineVisualStyle + + /// + /// Gets or sets the visual style to be used for TrendLine elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for TrendLine elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TrendLineVisualStyle TrendLineVisualStyle + { + get + { + if (_TrendLineVisualStyle == null) + { + _TrendLineVisualStyle = new TrendLineVisualStyle(); + + StyleChangeHandler(null, _TrendLineVisualStyle); + } + + return (_TrendLineVisualStyle); + } + + set + { + if (_TrendLineVisualStyle != value) + { + TrendLineVisualStyle oldValue = _TrendLineVisualStyle; + _TrendLineVisualStyle = value; + + OnStyleChanged("TrendLineVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region VScrollBarVisualStyles + + /// + /// Gets or sets the visual styles to be used for Vertical ScrollBar elements + /// + [Category("Style")] + [Description("Indicates visual styles to be used for Vertical ScrollBar elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ScrollBarVisualStyles VScrollBarVisualStyles + { + get + { + if (_VScrollBarVisualStyles == null) + { + _VScrollBarVisualStyles = new ScrollBarVisualStyles(); + + StyleChangeHandler(null, _VScrollBarVisualStyles); + } + + return (_VScrollBarVisualStyles); + } + + set + { + if (_VScrollBarVisualStyles != value) + { + ScrollBarVisualStyles oldValue = _VScrollBarVisualStyles; + _VScrollBarVisualStyles = value; + + OnStyleChanged("VScrollBarVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style collection is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style collection is logically Empty.")] + public bool IsEmpty + { + get + { + if (_ChartLegendItemVisualStyles != null && _ChartLegendItemVisualStyles.IsEmpty == false) + return (false); + + if (_ChartLegendVisualStyles != null && _ChartLegendVisualStyles.IsEmpty == false) + return (false); + + if (_ChartPanelVisualStyle != null && _ChartPanelVisualStyle.IsEmpty == false) + return (false); + + if (_HScrollBarVisualStyles != null && _HScrollBarVisualStyles.IsEmpty == false) + return (false); + + if (_VScrollBarVisualStyles != null && _VScrollBarVisualStyles.IsEmpty == false) + return (false); + + if (_ChartSeriesVisualStyle != null && _ChartSeriesVisualStyle.IsEmpty == false) + return (false); + + if (_ChartTickmarkVisualStyle != null && _ChartTickmarkVisualStyle.IsEmpty == false) + return (false); + + if (_ChartTitleVisualStyle != null && _ChartTitleVisualStyle.IsEmpty == false) + return (false); + + if (_ChartXAxisVisualStyle != null && _ChartXAxisVisualStyle.IsEmpty == false) + return (false); + + if (_ChartXyVisualStyle != null && _ChartXyVisualStyle.IsEmpty == false) + return (false); + + if (_ChartYAxisVisualStyle != null && _ChartYAxisVisualStyle.IsEmpty == false) + return (false); + + if (_ContainerVisualStyles != null && _ContainerVisualStyles.IsEmpty == false) + return (false); + + if (_CrosshairLabelVisualStyle != null && _CrosshairLabelVisualStyle.IsEmpty == false) + return (false); + + if (_CrosshairVisualStyle != null && _CrosshairVisualStyle.IsEmpty == false) + return (false); + + if (_DataLabelVisualStyle != null && _DataLabelVisualStyle.IsEmpty == false) + return (false); + + if (_DividerLineVisualStyle != null && _DividerLineVisualStyle.IsEmpty == false) + return (false); + + if (_GridLineVisualStyle != null && _GridLineVisualStyle.IsEmpty == false) + return (false); + + if (_ReferenceLineVisualStyle != null && _ReferenceLineVisualStyle.IsEmpty == false) + return (false); + + if (_TickmarkLabelVisualStyle != null && _TickmarkLabelVisualStyle.IsEmpty == false) + return (false); + + if (_TrendLineVisualStyle != null && _TrendLineVisualStyle.IsEmpty == false) + return (false); + + return (true); + } + } + + #endregion + + #endregion + + #region OnStyleChanged + + private void OnStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + StyleChangeHandler(oldValue, newValue); + + OnPropertyChanged(new VisualPropertyChangedEventArgs(property)); + } + + #endregion + + #region StyleChangeHandler + + private void StyleChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #region Copy/CopyTo + + public DefaultVisualStyles Copy() + { + DefaultVisualStyles copy = new DefaultVisualStyles(); + + CopyTo(copy); + + return (copy); + } + + public void CopyTo(DefaultVisualStyles c) + { + for (int i = 0; i < ChartLegendItemVisualStyles.Styles.Length; i++) + { + if (ChartLegendItemVisualStyles.Styles[i] != null) + c.ChartLegendItemVisualStyles.Styles[i] = ChartLegendItemVisualStyles.Styles[i].Copy(); + } + + for (int i = 0; i < ChartLegendVisualStyles.Styles.Length; i++) + { + if (ChartLegendVisualStyles.Styles[i] != null) + c.ChartLegendVisualStyles.Styles[i] = ChartLegendVisualStyles.Styles[i].Copy(); + } + + ChartPanelVisualStyle.CopyTo(c.ChartPanelVisualStyle); + ChartSeriesVisualStyle.CopyTo(c.ChartSeriesVisualStyle); + ChartTickmarkVisualStyle.CopyTo(c.ChartTickmarkVisualStyle); + ChartTitleVisualStyle.CopyTo(c.ChartTitleVisualStyle); + ChartXAxisVisualStyle.CopyTo(c.ChartXAxisVisualStyle); + ChartXyVisualStyle.CopyTo(c.ChartXyVisualStyle); + ChartYAxisVisualStyle.CopyTo(c.ChartYAxisVisualStyle); + + for (int i = 0; i < ContainerVisualStyles.Styles.Length; i++) + { + if (ContainerVisualStyles.Styles[i] != null) + c.ContainerVisualStyles.Styles[i] = ContainerVisualStyles.Styles[i].Copy(); + } + + CrosshairLabelVisualStyle.CopyTo(c.CrosshairLabelVisualStyle); + CrosshairVisualStyle.CopyTo(c.CrosshairVisualStyle); + DataLabelVisualStyle.CopyTo(c.DataLabelVisualStyle); + DividerLineVisualStyle.CopyTo(c.DividerLineVisualStyle); + GridLineVisualStyle.CopyTo(c.GridLineVisualStyle); + + for (int i = 0; i < HScrollBarVisualStyles.Styles.Length; i++) + { + if (HScrollBarVisualStyles.Styles[i] != null) + c.HScrollBarVisualStyles.Styles[i] = HScrollBarVisualStyles.Styles[i].Copy(); + } + + for (int i = 0; i < OtherSliceVisualStyles.Styles.Length; i++) + { + if (OtherSliceVisualStyles.Styles[i] != null) + c.OtherSliceVisualStyles.Styles[i] = OtherSliceVisualStyles.Styles[i].Copy(); + } + + PieChartVisualStyle.CopyTo(c.PieChartVisualStyle); + ReferenceLineVisualStyle.CopyTo(c.ReferenceLineVisualStyle); + RegressionLineVisualStyle.CopyTo(c.RegressionLineVisualStyle); + + for (int i = 0; i < SliceVisualStyles.Styles.Length; i++) + { + if (SliceVisualStyles.Styles[i] != null) + c.SliceVisualStyles.Styles[i] = SliceVisualStyles.Styles[i].Copy(); + } + + TickmarkLabelVisualStyle.CopyTo(c.TickmarkLabelVisualStyle); + TrendLineVisualStyle.CopyTo(c.TrendLineVisualStyle); + + for (int i = 0; i < VScrollBarVisualStyles.Styles.Length; i++) + { + if (VScrollBarVisualStyles.Styles[i] != null) + c.VScrollBarVisualStyles.Styles[i] = VScrollBarVisualStyles.Styles[i].Copy(); + } + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData() + { + return (GetSerialData(true)); + } + + internal SerialElementCollection GetSerialData(bool root) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (root == true) + sec.AddStartElement("DefaultVisualStyles"); + + if (_ChartLegendItemVisualStyles != null && _ChartLegendItemVisualStyles.IsEmpty == false) + sec.AddElement(_ChartLegendItemVisualStyles.GetSerialData("ChartLegendItemVisualStyles")); + + if (_ChartLegendVisualStyles != null && _ChartLegendVisualStyles.IsEmpty == false) + sec.AddElement(_ChartLegendVisualStyles.GetSerialData("ChartLegendVisualStyles")); + + sec.AddElement(_ChartPanelVisualStyle); + sec.AddElement(_ChartSeriesVisualStyle); + sec.AddElement(_ChartTickmarkVisualStyle); + sec.AddElement(_ChartTitleVisualStyle); + sec.AddElement(_ChartXAxisVisualStyle); + sec.AddElement(_ChartXyVisualStyle); + sec.AddElement(_ChartYAxisVisualStyle); + + if (_ContainerVisualStyles != null && _ContainerVisualStyles.IsEmpty == false) + sec.AddElement(_ContainerVisualStyles.GetSerialData("ContainerVisualStyles")); + + sec.AddElement(_CrosshairLabelVisualStyle); + sec.AddElement(_CrosshairVisualStyle); + sec.AddElement(_DataLabelVisualStyle); + sec.AddElement(_DividerLineVisualStyle); + sec.AddElement(_GridLineVisualStyle); + + if (_HScrollBarVisualStyles != null && _HScrollBarVisualStyles.IsEmpty == false) + sec.AddElement(_HScrollBarVisualStyles.GetSerialData("HScrollBarVisualStyles")); + + if (_OtherSliceVisualStyles != null && _OtherSliceVisualStyles.IsEmpty == false) + sec.AddElement(_OtherSliceVisualStyles.GetSerialData("OtherSliceVisualStyles")); + + sec.AddElement(_PieChartVisualStyle); + sec.AddElement(_ReferenceLineVisualStyle); + sec.AddElement(_RegressionLineVisualStyle); + + if (_SliceVisualStyles != null && _SliceVisualStyles.IsEmpty == false) + sec.AddElement(_SliceVisualStyles.GetSerialData("SliceVisualStyles")); + + sec.AddElement(_TickmarkLabelVisualStyle); + sec.AddElement(_TrendLineVisualStyle); + + if (_VScrollBarVisualStyles != null && _VScrollBarVisualStyles.IsEmpty == false) + sec.AddElement(_VScrollBarVisualStyles.GetSerialData("VScrollBarVisualStyles")); + + if (root == true) + sec.AddEndElement("DefaultVisualStyles"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + switch (se.Name) + { + case "ChartLegendItemVisualStyles": + se.Sec.PutSerialData(ChartLegendItemVisualStyles); + break; + + case "ChartLegendVisualStyles": + se.Sec.PutSerialData(ChartLegendVisualStyles); + break; + + case "ChartPanelVisualStyle": + se.Sec.PutSerialData(ChartPanelVisualStyle); + break; + + case "ChartSeriesVisualStyle": + se.Sec.PutSerialData(ChartSeriesVisualStyle); + break; + + case "ChartTickmarkVisualStyle": + se.Sec.PutSerialData(ChartTickmarkVisualStyle); + break; + + case "ChartTitleVisualStyle": + se.Sec.PutSerialData(ChartTitleVisualStyle); + break; + + case "ChartXAxisVisualStyle": + se.Sec.PutSerialData(ChartXAxisVisualStyle); + break; + + case "ChartXyVisualStyle": + se.Sec.PutSerialData(ChartXyVisualStyle); + break; + + case "ChartYAxisVisualStyle": + se.Sec.PutSerialData(ChartYAxisVisualStyle); + break; + + case "ContainerVisualStyles": + se.Sec.PutSerialData(ContainerVisualStyles); + break; + + case "CrosshairLabelVisualStyle": + se.Sec.PutSerialData(CrosshairLabelVisualStyle); + break; + + case "CrosshairVisualStyle": + se.Sec.PutSerialData(CrosshairVisualStyle); + break; + + case "DataLabelVisualStyle": + se.Sec.PutSerialData(DataLabelVisualStyle); + break; + + case "DividerLineVisualStyle": + se.Sec.PutSerialData(DividerLineVisualStyle); + break; + + case "GridLineVisualStyle": + se.Sec.PutSerialData(GridLineVisualStyle); + break; + + case "HScrollBarVisualStyles": + se.Sec.PutSerialData(HScrollBarVisualStyles); + break; + + case "OtherSliceVisualStyles": + se.Sec.PutSerialData(OtherSliceVisualStyles); + break; + + case "PieChartVisualStyle": + se.Sec.PutSerialData(PieChartVisualStyle); + break; + + case "ReferenceLineVisualStyle": + se.Sec.PutSerialData(ReferenceLineVisualStyle); + break; + + case "RegressionLineVisualStyle": + se.Sec.PutSerialData(RegressionLineVisualStyle); + break; + + case "SliceVisualStyles": + se.Sec.PutSerialData(SliceVisualStyles); + break; + + case "TickmarkLableVisualStyle": + se.Sec.PutSerialData(TickmarkLabelVisualStyle); + break; + + case "TrendLineVisualStyle": + se.Sec.PutSerialData(TrendLineVisualStyle); + break; + + case "VScrollBarVisualStyles": + se.Sec.PutSerialData(VScrollBarVisualStyles); + break; + + default: + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + ChartPanelVisualStyle = null; + ChartTitleVisualStyle = null; + + ChartXAxisVisualStyle = null; + ChartYAxisVisualStyle = null; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DividerLineVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DividerLineVisualStyle.cs new file mode 100644 index 00000000..f737c9dc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DividerLineVisualStyle.cs @@ -0,0 +1,56 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a Legend element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class DividerLineVisualStyle : ChartLineVisualStyle + { + #region ApplyStyle + + /// + /// Applies the style to the instance of this style. + /// + /// Style to apply. + public void ApplyStyle(DividerLineVisualStyle style) + { + if (style != null) + base.ApplyStyle(style); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new DividerLineVisualStyle Copy() + { + DividerLineVisualStyle style = new DividerLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(DividerLineVisualStyle style) + { + base.CopyTo(style); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DropShadowVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DropShadowVisualStyle.cs new file mode 100644 index 00000000..161c8362 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/DropShadowVisualStyle.cs @@ -0,0 +1,309 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Globalization; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a DropShadow + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(DropShadowStyleConvertor))] + public class DropShadowVisualStyle : BaseVisualStyle + { + #region Private variables + + private Tbool _Enabled = Tbool.NotSet; + private Color _ShadowColor = Color.Empty; + + #endregion + + #region Public properties + + #region ShadowColor + + /// + /// Gets or sets the DropShadow color + /// + [Description("Indicates the DropShadow color")] + public Color ShadowColor + { + get { return (_ShadowColor); } + + set + { + if (value != _ShadowColor) + { + _ShadowColor = value; + + OnPropertyChangedEx("ShadowColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeShadowColor() + { + return (_ShadowColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetShadowColor() + { + _ShadowColor = Color.Empty; + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether drop shadow is displayed. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether drop shadow is displayed.")] + public Tbool Enabled + { + get { return (_Enabled); } + + set + { + if (value != _Enabled) + { + _Enabled = value; + + OnPropertyChangedEx("Enabled", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_ShadowColor.IsEmpty == true) && + (_Enabled == Tbool.NotSet) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region RenderDropShadow + + internal virtual void RenderDropShadow( + Graphics g, Rectangle r, bool drawBot, bool drawRight) + { + Color color = (_ShadowColor.IsEmpty == false) ? _ShadowColor : Color.Black; + + Point[] pts = new Point[] + { + new Point(r.X + 3, r.Bottom), + new Point(r.Right, r.Bottom), + new Point(r.Right, r.Y + 3) + }; + + using (Pen pen1 = new Pen(Color.FromArgb(100, color))) + g.DrawLines(pen1, pts); + + IncShadowPts(pts); + + using (Pen pen2 = new Pen(Color.FromArgb(64, color))) + g.DrawLines(pen2, pts); + + IncShadowPts(pts); + + using (Pen pen3 = new Pen(Color.FromArgb(32, color))) + g.DrawLines(pen3, pts); + + IncShadowPts(pts); + } + + #region IncShadowPts + + private void IncShadowPts(Point[] pts) + { + pts[0].X++; + pts[0].Y++; + + pts[1].X++; + pts[1].Y++; + + pts[2].X++; + pts[2].Y++; + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(DropShadowVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.ShadowColor.IsEmpty == false) + ShadowColor = style.ShadowColor; + + if (style.Enabled != Tbool.NotSet) + Enabled = style.Enabled; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new DropShadowVisualStyle Copy() + { + DropShadowVisualStyle style = new DropShadowVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(DropShadowVisualStyle style) + { + base.CopyTo(style); + + style.Enabled = _Enabled; + style.ShadowColor = _ShadowColor; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "DropShadowVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("Enabled", Enabled, Tbool.NotSet); + sec.AddValue("ShadowColor", ShadowColor, Color.Empty); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Enabled": + Enabled = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ShadowColor": + ShadowColor = se.GetValueColor(); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + base.Dispose(); + } + + #endregion + } + + #region DropShadowStyleConvertor + + public class DropShadowStyleConvertor : ExpandableObjectConverter + { + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + DropShadowVisualStyle dsc = value as DropShadowVisualStyle; + + if (dsc != null) + { + ColorConverter cvt = new ColorConverter(); + + if (dsc.Enabled == Tbool.NotSet) + return (" "); + + return ((dsc.Enabled == Tbool.True) ? "Enabled" : "Disabled"); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/EffectiveStyles.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/EffectiveStyles.cs new file mode 100644 index 00000000..b73190fe --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/EffectiveStyles.cs @@ -0,0 +1,338 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using DevComponents.DotNetBar.Charts.Style; + +namespace DevComponents.DotNetBar.Charts +{ + /// + /// Provides helpers when working with EffectiveStyles. + /// + public class EffectiveStyles where T : BaseVisualStyle, new() + { + #region Private variables + + private IEffectiveStyle _ChartElement; + private VisualStyles _Styles = new VisualStyles(); + + private ushort[] _StyleUpdateCount; + private ushort[] _GlobalStyleUpdateCount; + + private List[] _StyleList; + + #endregion + + public EffectiveStyles(IEffectiveStyle chartElement) + { + _ChartElement = chartElement; + + int len = Enum.GetValues(typeof(StyleType)).Length - 1; + + _StyleUpdateCount = new ushort[len]; + _GlobalStyleUpdateCount = new ushort[len]; + + _StyleList = new List[len]; + + for (int i = 0; i < len; i++) + { + _StyleUpdateCount[i] = ushort.MaxValue; + _GlobalStyleUpdateCount[i] = ushort.MaxValue; + } + } + + #region Public properties + + #region StyleType Indexer + + public T this[StyleType type] + { + get { return (GetEffectiveStyle(type)); } + } + + #endregion + + #region StyleState Indexer + + public T this[StyleState state] + { + get { return (GetEffectiveStyle(state)); } + } + + #endregion + + #endregion + + #region GetEffectiveStyle + + internal T GetEffectiveStyle(StyleType type) + { + return (GetStyle(type)); + } + + internal T GetEffectiveStyle(StyleState state) + { + if (_ChartElement.ChartControl.DesignerHosted == true) + state &= ~(StyleState.MouseOver | StyleState.Selected); + + switch (state) + { + case StyleState.MouseOver: + return (GetStyle(StyleType.MouseOver)); + + case StyleState.Selected: + return (GetStyle(StyleType.Selected)); + + case StyleState.Selected | StyleState.MouseOver: + return (GetStyle(StyleType.SelectedMouseOver)); + + default: + return (GetStyle(StyleType.Default)); + } + } + + #endregion + + #region GetStyle + + internal T GetStyle(StyleType e) + { + VisualStyles cvs = _Styles; + + if (cvs == null) + cvs = new VisualStyles(); + + int styleIndex = cvs.StyleIndex(e); + + ushort styleUpdateCount = _StyleUpdateCount[styleIndex]; + ushort globalUpdateCount = _ChartElement.ChartControl.GlobalUpdateCount; + + T style = cvs.Style(e); + + if (_GlobalStyleUpdateCount[styleIndex] != globalUpdateCount) + { + if (style != null) + styleUpdateCount = GetStyleUpdateCount(styleIndex); + } + + if (style == null || _StyleUpdateCount[styleIndex] != styleUpdateCount) + { + style = new T(); + + if (_StyleList[styleIndex] == null) + _StyleList[styleIndex] = new List(); + + _StyleList[styleIndex].Clear(); + + style.StyleType = e; + style.StyleList = _StyleList[styleIndex]; + style.StyleUpdateMode = StyleUpdateMode.UpdateCount; + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + foreach (StyleType cs in css) + _ChartElement.ApplyStyles(style, cs); + } + + style.StyleUpdateMode = StyleUpdateMode.None; + + _ChartElement.ApplyDefaults(style, e); + + style.StyleUpdateMode = (StyleUpdateMode.UpdateCount | StyleUpdateMode.Notify); + + BaseVisualStyle vstyle = (BaseVisualStyle)style; + _ChartElement.GetElementStyle(_ChartElement, e, ref vstyle); + + _StyleUpdateCount[styleIndex] = GetStyleUpdateCount(styleIndex); + + style.StyleList = null; + + cvs[e] = style; + + _Styles = cvs; + } + + _GlobalStyleUpdateCount[styleIndex] = globalUpdateCount; + + return (cvs[e]); + } + + #region GetStyleUpdateCount + + private ushort GetStyleUpdateCount(int styleIndex) + { + ushort styleCount = 0; + + List slist = _StyleList[styleIndex]; + + if (slist != null) + { + foreach (BaseVisualStyle style in slist) + styleCount += style.StyleUpdateCount; + } + + return (styleCount); + } + + #endregion + + #endregion + + #region InvalidateStyle + + public bool InvalidateStyle(StyleType type) + { + if (_Styles != null) + { + if (_Styles[type] != null) + { + _Styles[type].Dispose(); + _Styles[type] = null; + + return (true); + } + } + + return (false); + } + + #endregion + + #region InvalidateStyles + + public void InvalidateStyles() + { + if (_Styles != null) + { + _Styles.Dispose(); + _Styles = null; + } + } + + #endregion + } + + /// + /// Provides helpers when working with EffectiveStyle. + /// + public class EffectiveStyle where T : BaseVisualStyle, new() + { + #region Private variables + + private IEffectiveStyle _ChartElement; + private T _Style; + + private ushort _StyleUpdateCount = ushort.MaxValue; + private ushort _GlobalStyleUpdateCount = ushort.MaxValue; + + private List _StyleList = new List(); + + #endregion + + public EffectiveStyle(IEffectiveStyle chartElement) + { + _ChartElement = chartElement; + } + + #region Style + + internal T Style + { + get + { + ushort styleUpdateCount = _StyleUpdateCount; + ushort globalUpdateCount = _ChartElement.ChartControl.GlobalUpdateCount; + + if (_GlobalStyleUpdateCount != globalUpdateCount) + { + if (_Style != null) + styleUpdateCount = GetStyleUpdateCount(); + } + + if (_Style == null || _StyleUpdateCount != styleUpdateCount) + { + T style = new T(); + + _StyleList.Clear(); + + style.StyleList = _StyleList; + style.StyleType = StyleType.Default; + + _ChartElement.ApplyStyles(style); + _ChartElement.ApplyDefaults(style, StyleType.Default); + + BaseVisualStyle vstyle = (BaseVisualStyle)style; + _ChartElement.GetElementStyle(_ChartElement, StyleType.Default, ref vstyle); + + _StyleUpdateCount = GetStyleUpdateCount(); + + style.StyleList = null; + + _Style = style; + } + + _GlobalStyleUpdateCount = globalUpdateCount; + + return (_Style); + } + } + + #region GetStyleUpdateCount + + private ushort GetStyleUpdateCount() + { + ushort styleCount = 0; + + List slist = _StyleList; + + if (slist != null) + { + foreach (BaseVisualStyle style in slist) + styleCount += style.StyleUpdateCount; + } + + return (styleCount); + } + + #endregion + + #endregion + + #region InvalidateStyle + + public bool InvalidateStyle() + { + if (_Style != null) + { + _Style.Dispose(); + _Style = null; + + return (true); + } + + return (false); + } + + #endregion + } + + #region IEffectiveStyle + + public interface IEffectiveStyle + { + void ApplyStyles(BaseVisualStyle style); + void ApplyStyles(BaseVisualStyle style, StyleType styleType); + + void ApplyDefaults(BaseVisualStyle style, StyleType styleType); + + void GetElementStyle(IEffectiveStyle chartElement, StyleType styleType, ref BaseVisualStyle style); + + ChartControl ChartControl + { + get; + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/GridLineVisualStyle .cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/GridLineVisualStyle .cs new file mode 100644 index 00000000..3ac91f8f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/GridLineVisualStyle .cs @@ -0,0 +1,44 @@ +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents a GridLineVisualStyle. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class GridLineVisualStyle : ChartLineVisualStyle + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new GridLineVisualStyle Copy() + { + GridLineVisualStyle style = new GridLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(GridLineVisualStyle style) + { + base.CopyTo(style); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/HiLoBarSegmentStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/HiLoBarSegmentStyle.cs new file mode 100644 index 00000000..3f4b54a6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/HiLoBarSegmentStyle.cs @@ -0,0 +1,763 @@ +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents HiLoBarSegment visual style. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(VisualStylesConverter))] + public class HiLoBarSegmentStyle : BaseVisualStyle + { + #region Static data + + /// + /// Returns Empty instance of HiLoBarSegmentStyle. + /// + public static HiLoBarSegmentStyle Empty + { + get { return (new HiLoBarSegmentStyle()); } + } + + #endregion + + #region Private variables + + private ChartLineVisualStyle _Default; + + private ChartLineVisualStyle _OpenWhisker; + private ChartLineVisualStyle _CloseWhisker; + + private ChartLineVisualStyle _CenterLine; + private ChartLineVisualStyle _MedianLine; + + private ChartLineVisualStyle _HighWhisker; + private ChartLineVisualStyle _LowWhisker; + + private ChartLineVisualStyle _HighWhiskerCap; + private ChartLineVisualStyle _LowWhiskerCap; + + private Background _BoxBackground; + private ChartLineVisualStyle _BoxBorder; + + #endregion + + #region Public properties + + #region BoxBackground + + /// + /// Gets or sets the visual style for the Box Background (Box, Candle only). + /// + [Description("Indicates the the visual style for Box Background (Box, Candle only).")] + public Background BoxBackground + { + get + { + if (_BoxBackground == null) + { + _BoxBackground = Background.Empty; + + UpdateChangeHandler(null, _BoxBackground); + } + + return (_BoxBackground); + } + + set + { + if (_BoxBackground != value) + { + Background oldValue = _BoxBackground; + + _BoxBackground = value; + + OnStyleChanged("BoxBackground", oldValue, value); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBoxBackground() + { + return (_BoxBackground != null && _BoxBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBoxBackground() + { + BoxBackground = null; + } + + #endregion + + #region BoxBorder + + /// + /// Gets or sets the visual style for the Box Border (Box, Candle only). + /// + [Category("Style")] + [Description("Indicates the visual style for the Box Border (Box, Candle only).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle BoxBorder + { + get + { + if (_BoxBorder == null) + { + _BoxBorder = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _BoxBorder); + } + + return (_BoxBorder); + } + + set + { + if (_BoxBorder != value) + { + ChartLineVisualStyle oldValue = _BoxBorder; + + _BoxBorder = value; + + OnStyleChanged("BoxBorder", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CenterLine + + /// + /// Gets or sets the visual style for the Center Line segment. This is the + /// style used for the center Hilo segment and the Box/Candle segment when + /// no Open or Close values are specified. + /// + [Category("Style")] + [Description("Indicates the visual style for the Center Line segment. This is the style used for the center Hilo segment and the Box/Candle segment when no Open or Close values are specified.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle CenterLine + { + get + { + if (_CenterLine == null) + { + _CenterLine = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _CenterLine); + } + + return (_CenterLine); + } + + set + { + if (_CenterLine != value) + { + ChartLineVisualStyle oldValue = _CenterLine; + + _CenterLine = value; + + OnStyleChanged("CenterLine", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region CloseWhisker + + /// + /// Gets or sets the visual style for the Close Whisker (Hilo only). + /// + [Category("Style")] + [Description("Indicates the visual style for the Close Whisker (Hilo only).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle CloseWhisker + { + get + { + if (_CloseWhisker == null) + { + _CloseWhisker = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _CloseWhisker); + } + + return (_CloseWhisker); + } + + set + { + if (_CloseWhisker != value) + { + ChartLineVisualStyle oldValue = _CloseWhisker; + + _CloseWhisker = value; + + OnStyleChanged("CloseWhisker", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region Default + + /// + /// Gets or sets the visual style used as the Default when + /// a segment style is not specified (ie BoxBorder, HighWhisker, etc). + /// + [Category("Style")] + [Description("Indicates the visual style used as the Default when a segment style is not specified (ie BoxBorder, HighWhisker, etc).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle Default + { + get + { + if (_Default == null) + { + _Default = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _Default); + } + + return (_Default); + } + + set + { + if (_Default != value) + { + ChartLineVisualStyle oldValue = _Default; + + _Default = value; + + OnStyleChanged("Default", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region HighWhisker + + /// + /// Gets or sets the visual style for the High Whisker. + /// + [Category("Style")] + [Description("Indicates the visual style for the High Whisker.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle HighWhisker + { + get + { + if (_HighWhisker == null) + { + _HighWhisker = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _HighWhisker); + } + + return (_HighWhisker); + } + + set + { + if (_HighWhisker != value) + { + ChartLineVisualStyle oldValue = _HighWhisker; + + _HighWhisker = value; + + OnStyleChanged("HighWhisker", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region HighWhiskerCap + + /// + /// Gets or sets the visual style for the High Whisker Cap. + /// + [Category("Style")] + [Description("Indicates the visual style for the High Whisker Cap.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle HighWhiskerCap + { + get + { + if (_HighWhiskerCap == null) + { + _HighWhiskerCap = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _HighWhiskerCap); + } + + return (_HighWhiskerCap); + } + + set + { + if (_HighWhiskerCap != value) + { + ChartLineVisualStyle oldValue = _HighWhiskerCap; + + _HighWhiskerCap = value; + + OnStyleChanged("HighWhiskerCap", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region LowWhisker + + /// + /// Gets or sets the visual style for the Low Whisker. + /// + [Category("Style")] + [Description("Indicates the visual style for the Low Whisker.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle LowWhisker + { + get + { + if (_LowWhisker == null) + { + _LowWhisker = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _LowWhisker); + } + + return (_LowWhisker); + } + + set + { + if (_LowWhisker != value) + { + ChartLineVisualStyle oldValue = _LowWhisker; + + _LowWhisker = value; + + OnStyleChanged("LowWhisker", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region LowWhiskerCap + + /// + /// Gets or sets the visual style for the Low Whisker Cap. + /// + [Category("Style")] + [Description("Indicates the visual style for the Low Whisker Cap.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle LowWhiskerCap + { + get + { + if (_LowWhiskerCap == null) + { + _LowWhiskerCap = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _LowWhiskerCap); + } + + return (_LowWhiskerCap); + } + + set + { + if (_LowWhiskerCap != value) + { + ChartLineVisualStyle oldValue = _LowWhiskerCap; + + _LowWhiskerCap = value; + + OnStyleChanged("LowWhiskerCap", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region MedianLine + + /// + /// Gets or sets the visual style for the Median Line. + /// + [Category("Style")] + [Description("Indicates the visual style for the Median Line.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle MedianLine + { + get + { + if (_MedianLine == null) + { + _MedianLine = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _MedianLine); + } + + return (_MedianLine); + } + + set + { + if (_MedianLine != value) + { + ChartLineVisualStyle oldValue = _MedianLine; + + _MedianLine = value; + + OnStyleChanged("MedianLine", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region OpenWhisker + + /// + /// Gets or sets the visual style for the Open Whisker (Hilo only). + /// + [Category("Style")] + [Description("Indicates the visual style for the Open Whisker (Hilo only).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle OpenWhisker + { + get + { + if (_OpenWhisker == null) + { + _OpenWhisker = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _OpenWhisker); + } + + return (_OpenWhisker); + } + + set + { + if (_OpenWhisker != value) + { + ChartLineVisualStyle oldValue = _OpenWhisker; + + _OpenWhisker = value; + + OnStyleChanged("OpenWhisker", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether both colors assigned are empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool IsEmpty + { + get + { + return ((_BoxBackground == null || _BoxBackground.IsEmpty) && + (_BoxBorder == null || _BoxBorder.IsEmpty) && + (_CenterLine == null || _CenterLine.IsEmpty) && + (_CloseWhisker == null || _CloseWhisker.IsEmpty) && + (_Default == null || _Default.IsEmpty) && + (_HighWhisker == null || _HighWhisker.IsEmpty) && + (_HighWhiskerCap == null || _HighWhiskerCap.IsEmpty) && + (_LowWhisker == null || _LowWhisker.IsEmpty) && + (_LowWhiskerCap == null || _LowWhiskerCap.IsEmpty) && + (_OpenWhisker == null || _OpenWhisker.IsEmpty) && + (_MedianLine == null || _MedianLine.IsEmpty) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(HiLoBarSegmentStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._BoxBackground != null && style._BoxBackground.IsEmpty == false) + BoxBackground = style._BoxBackground.Copy(); + + if (style._BoxBorder != null && style._BoxBorder.IsEmpty == false) + BoxBorder.ApplyStyle(style._BoxBorder); + + if (style._CenterLine != null && style._CenterLine.IsEmpty == false) + CenterLine.ApplyStyle(style._CenterLine); + + if (style._CloseWhisker != null && style._CloseWhisker.IsEmpty == false) + CloseWhisker.ApplyStyle(style._CloseWhisker); + + if (style._Default != null && style._Default.IsEmpty == false) + Default.ApplyStyle(style._Default); + + if (style._HighWhisker != null && style._HighWhisker.IsEmpty == false) + HighWhisker.ApplyStyle(style._HighWhisker); + + if (style._HighWhiskerCap != null && style._HighWhiskerCap.IsEmpty == false) + HighWhiskerCap.ApplyStyle(style._HighWhiskerCap); + + if (style._LowWhisker != null && style._LowWhisker.IsEmpty == false) + LowWhisker.ApplyStyle(style._LowWhisker); + + if (style._LowWhiskerCap != null && style._LowWhiskerCap.IsEmpty == false) + LowWhiskerCap.ApplyStyle(style._LowWhiskerCap); + + if (style._MedianLine != null && style._MedianLine.IsEmpty == false) + MedianLine.ApplyStyle(style._MedianLine); + + if (style._OpenWhisker != null && style._OpenWhisker.IsEmpty == false) + OpenWhisker.ApplyStyle(style._OpenWhisker); + } + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the OhlcBarSegmentStyle. + /// + /// Copy of the OhlcBarSegmentStyle. + public new HiLoBarSegmentStyle Copy() + { + HiLoBarSegmentStyle style = new HiLoBarSegmentStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(HiLoBarSegmentStyle style) + { + style.BoxBackground = (_BoxBackground != null) ? _BoxBackground.Copy() : null; + style.BoxBorder = (_BoxBorder != null) ? _BoxBorder.Copy() : null; + style.CenterLine = (_CenterLine != null) ? _CenterLine.Copy() : null; + style.CloseWhisker = (_CloseWhisker != null) ? _CloseWhisker.Copy() : null; + style.Default = (_Default != null) ? _Default.Copy() : null; + style.HighWhisker = (_HighWhisker != null) ? _HighWhisker.Copy() : null; + style.HighWhiskerCap = (_HighWhiskerCap != null) ? _HighWhiskerCap.Copy() : null; + style.LowWhisker = (_LowWhisker != null) ? _LowWhisker.Copy() : null; + style.LowWhiskerCap = (_LowWhiskerCap != null) ? _LowWhiskerCap.Copy() : null; + style.MedianLine = (_MedianLine != null) ? _MedianLine.Copy() : null; + style.OpenWhisker = (_OpenWhisker != null) ? _OpenWhisker.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "HiLoBarSegmentStyle"; + + sec.AddStartElement(serialName); + } + + if (_BoxBackground != null && _BoxBackground.IsEmpty == false) + sec.AddElement(_BoxBackground.GetSerialData("BoxBackground")); + + if (_BoxBorder != null && _BoxBorder.IsEmpty == false) + sec.AddElement(_BoxBorder.GetSerialData("BoxBorder")); + + if (_CenterLine != null && _CenterLine.IsEmpty == false) + sec.AddElement(_CenterLine.GetSerialData("CenterLine")); + + if (_CloseWhisker != null && _CloseWhisker.IsEmpty == false) + sec.AddElement(_CloseWhisker.GetSerialData("CloseWhisker")); + + if (_Default != null && _Default.IsEmpty == false) + sec.AddElement(_Default.GetSerialData("Default")); + + if (_HighWhisker != null && _HighWhisker.IsEmpty == false) + sec.AddElement(_HighWhisker.GetSerialData("HighWhisker")); + + if (_HighWhiskerCap != null && _HighWhiskerCap.IsEmpty == false) + sec.AddElement(_HighWhiskerCap.GetSerialData("HighWhiskerCap")); + + if (_LowWhisker != null && _LowWhisker.IsEmpty == false) + sec.AddElement(_LowWhisker.GetSerialData("LowWhisker")); + + if (_LowWhiskerCap != null && _LowWhiskerCap.IsEmpty == false) + sec.AddElement(_LowWhiskerCap.GetSerialData("LowWhiskerCap")); + + if (_MedianLine != null && _MedianLine.IsEmpty == false) + sec.AddElement(_MedianLine.GetSerialData("MedianLine")); + + if (_OpenWhisker != null && _OpenWhisker.IsEmpty == false) + sec.AddElement(_OpenWhisker.GetSerialData("OpenWhisker")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "BoxBackground": + sec.PutSerialData(BoxBackground); + break; + + case "BoxBorder": + sec.PutSerialData(BoxBorder); + break; + + case "CenterLine": + sec.PutSerialData(CenterLine); + break; + + case "CloseWhisker": + sec.PutSerialData(CloseWhisker); + break; + + case "Default": + sec.PutSerialData(Default); + break; + + case "HighWhisker": + sec.PutSerialData(HighWhisker); + break; + + case "HighWhiskerCap": + sec.PutSerialData(HighWhiskerCap); + break; + + case "LowWhisker": + sec.PutSerialData(LowWhisker); + break; + + case "LowWhiskerCap": + sec.PutSerialData(LowWhiskerCap); + break; + + case "MedianLine": + sec.PutSerialData(MedianLine); + break; + + case "OpenWhisker": + sec.PutSerialData(OpenWhisker); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + BoxBorder = null; + CenterLine = null; + CloseWhisker = null; + Default = null; + HighWhisker = null; + HighWhiskerCap = null; + LowWhisker = null; + LowWhiskerCap = null; + MedianLine = null; + OpenWhisker = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/Padding.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/Padding.cs new file mode 100644 index 00000000..f81c0093 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/Padding.cs @@ -0,0 +1,292 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Globalization; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Padding + /// + [TypeConverter(typeof(PaddingTypeConverter))] + public class Padding : Thickness + { + #region Static data + + /// + /// Returns Empty instance of Thickness. + /// + public new static Padding Empty + { + get { return (new Padding()); } + } + + #endregion + + #region Constructors + + /// + /// Creates new instance of the class and initializes it. + /// + /// Left padding + /// Right padding + /// Top padding + /// Bottom padding + public Padding(int left, int top, int right, int bottom) + : base(left, top, right, bottom) + { + } + + /// + /// Initializes a new instance of the Padding class. + /// + /// Uniform padding. + public Padding(int all) + : base(all) + { + } + + /// + /// Initializes a new instance of the Padding class. + /// + public Padding() + { + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the Padding. + /// + /// Copy of the Padding. + public new Padding Copy() + { + Padding copy = new Padding(Left, Top, Right, Bottom); + + return (copy); + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string name) + { + SerialElementCollection sec = new SerialElementCollection(); + + sec.AddStartElement(name); + + if (IsUniform == true) + { + sec.AddValue("All", Left, 0); + } + else + { + sec.AddValue("Left", Left, 0); + sec.AddValue("Top", Top, 0); + sec.AddValue("Right", Right, 0); + sec.AddValue("Bottom", Bottom, 0); + } + + sec.AddEndElement(name); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "All": + All = int.Parse(se.StringValue); + break; + + case "Left": + Left = int.Parse(se.StringValue); + break; + + case "Top": + Top = int.Parse(se.StringValue); + break; + + case "Right": + Right = int.Parse(se.StringValue); + break; + + case "Bottom": + Bottom = int.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + } + + #region PaddingTypeConverter + + /// + /// PaddingTypeConverter + /// + public class PaddingTypeConverter : ExpandableObjectConverter + { + #region CanConvertTo + + /// + /// CanConvertTo + /// + /// + /// + /// + public override bool CanConvertTo( + ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + return (true); + + return (base.CanConvertTo(context, destinationType)); + } + + #endregion + + #region ConvertTo + + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + Padding p = value as Padding; + + if (p != null) + { + if (p.IsUniform == true) + return (p.Left.ToString()); + + return (String.Format("{0:d}, {1:d}, {2:d}, {3:d}", + p.Bottom, p.Left, p.Right, p.Top)); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + + #endregion + + #region CanConvertFrom + + /// + /// CanConvertFrom + /// + /// + /// + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + return (true); + + return (base.CanConvertFrom(context, sourceType)); + } + + #endregion + + #region ConvertFrom + + /// + /// ConvertFrom + /// + /// + /// + /// + /// + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + string[] values = ((string)value).Split(','); + + if (values.Length != 1 && values.Length != 4) + throw new ArgumentException("Invalid value to convert."); + + try + { + int[] v = new int[values.Length]; + + for (int i = 0; i < values.Length; i++) + v[i] = int.Parse(values[i]); + + Padding p = (values.Length == 1) + ? new Padding(v[0]) + : new Padding(v[1], v[3], v[2], v[0]); + + return (p); + } + catch (Exception) + { + throw new ArgumentException("Invalid value to convert."); + } + } + + return base.ConvertFrom(context, culture, value); + } + + #endregion + + #region GetCreateInstanceSupported + + /// + /// GetCreateInstanceSupported + /// + /// + /// + public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region CreateInstance + + /// + /// CreateInstance + /// + /// + /// + /// + public override object CreateInstance( + ITypeDescriptorContext context, IDictionary propertyValues) + { + return (new Padding((int)propertyValues["Left"], (int)propertyValues["Top"], + (int)propertyValues["Right"], (int)propertyValues["Bottom"])); + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieCenterVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieCenterVisualStyle.cs new file mode 100644 index 00000000..c7a1a098 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieCenterVisualStyle.cs @@ -0,0 +1,1861 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// PieCenterVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class PieCenterVisualStyles : VisualStyles + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public PieCenterVisualStyles Copy() + { + PieCenterVisualStyles styles = new PieCenterVisualStyles(); + + for (int i = 0; i < Styles.Length; i++) + { + PieCenterVisualStyle vstyle = Styles[i]; + + if (vstyle != null) + styles.Styles[i] = vstyle.Copy(); + } + + return (styles); + } + + #endregion + } + + /// + /// Represents the visual style of a Pie Center. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class PieCenterVisualStyle : BaseVisualStyle + { + #region Private variables + + private Tbool _AllowWrap = Tbool.NotSet; + private Alignment _Alignment = Alignment.NotSet; + + private Background _Background; + private ChartLineVisualStyle _Border; + private Padding _Padding; + + private Color _TextColor = Color.Empty; + private Font _Font; + + private Image _Image; + private int _ImageIndex = -1; + private ImageList _ImageList; + + private Padding _ImagePadding; + + private Alignment _ImageAlignment = Alignment.NotSet; + private ImageOverlay _ImageOverlay = ImageOverlay.NotSet; + private ImageSizeMode _ImageSizeMode = ImageSizeMode.NotSet; + + private double _ImageScale = double.NaN; + + private Size _FigureSizeEx; + + private Tbool _ImageInscribed = Tbool.NotSet; + private Tbool _TextInscribed = Tbool.NotSet; + + private SymbolDef _SymbolDef; + private SymbolDef _ScaleSymDef; + + private float _SymFontScale = -1; + + #endregion + + #region Public properties + + #region Alignment + + /// + /// Gets or sets the alignment of the text. + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the text.")] + public Alignment Alignment + { + get { return (_Alignment); } + + set + { + if (_Alignment != value) + { + _Alignment = value; + + OnPropertyChangedEx("Alignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Background + + /// + /// Gets or sets the background style. + /// + [Description("Indicates the background style")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region Border + + /// + /// Gets or sets the pie center border. + /// + [Category("Style")] + [Description("Indicates the pie center border.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle Border + { + get + { + if (_Border == null) + { + _Border = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _Border); + } + + return (_Border); + } + + set + { + if (_Border != value) + { + ChartLineVisualStyle oldValue = _Border; + + _Border = value; + + OnStyleChanged("Border", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font. + /// + [DefaultValue(null)] + [Description("Indicates the style Font.")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Image + + /// + /// Gets or sets the element Image. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the element image.")] + public Image Image + { + get { return (_Image); } + + set + { + if (_Image != value) + { + _Image = value; + + OnPropertyChangedEx("Image", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageAlignment + + /// + /// Gets or sets the alignment of the Image. + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the Image.")] + public Alignment ImageAlignment + { + get { return (_ImageAlignment); } + + set + { + if (_ImageAlignment != value) + { + _ImageAlignment = value; + + OnPropertyChangedEx("ImageAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageIndex + + /// + /// Gets or sets the image index. + /// + [DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the image index.")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int ImageIndex + { + get { return (_ImageIndex); } + + set + { + if (_ImageIndex != value) + { + _ImageIndex = value; + + OnPropertyChangedEx("ImageIndex", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageInscribed + + /// + /// Gets or sets whether the image is inscribed in the + /// PieCenter area (true = inscribed, false = circumscribed). + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether the image is inscribed in the PieCenter area (true = inscribed, false = circumscribed).")] + public Tbool ImageInscribed + { + get { return (_ImageInscribed); } + + set + { + if (_ImageInscribed != value) + { + _ImageInscribed = value; + + OnPropertyChangedEx("ImageInscribed", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageList + + /// + /// Gets or sets the ImageList. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates the ImageList.")] + public ImageList ImageList + { + get { return (_ImageList); } + + set + { + if (_ImageList != value) + { + _ImageList = value; + + OnPropertyChangedEx("ImageList", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageOverlay + + /// + /// Gets or sets how to overlay the image with respect to the center content. + /// + [DefaultValue(ImageOverlay.NotSet), Category("Appearance")] + [Description("Indicates how to overlay the image with respect to the center content.")] + public ImageOverlay ImageOverlay + { + get { return (_ImageOverlay); } + + set + { + if (_ImageOverlay != value) + { + _ImageOverlay = value; + + OnPropertyChangedEx("ImageOverlay", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImagePadding + + /// + /// Gets or sets the spacing between content and edges of the Image. + /// + [Description("Indicates the spacing between content and edges of the Image.")] + public Padding ImagePadding + { + get + { + if (_ImagePadding == null) + { + _ImagePadding = Padding.Empty; + + UpdateChangeHandler(null, _ImagePadding); + } + + return (_ImagePadding); + } + + set + { + if (_ImagePadding != value) + { + UpdateChangeHandler(_ImagePadding, value); + + _ImagePadding = value; + + OnPropertyChangedEx("ImagePadding", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeImagePadding() + { + return (_ImagePadding != null && _ImagePadding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetImagePadding() + { + ImagePadding = null; + } + + #endregion + + #region ImageScale + + /// + /// Gets or sets the 'scale' factor for the image/symbol. This property informs the + /// chart to scale the image (or symbol) based upon the available space at its offset + /// position in the slice - the image is moved in or out of the slice, the image will + /// grow of shrink accordingly. + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the 'scale' factor for the image/symbol. This property informs the chart to scale the image (or symbol) based upon the available space at its offset position in the slice - the image is moved in or out of the slice, the image will grow of shrink accordingly.")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double ImageScale + { + get { return (_ImageScale); } + + set + { + if (value != _ImageScale) + { + if (value < 0) + throw new Exception("ImageScale can not be negative."); + + _ImageScale = value; + + OnPropertyChangedEx("ImageScale", VisualChangeType.Render); + } + } + } + + #endregion + + #region ImageSizeMode + + /// + /// Gets or sets the 'mode' used to display the image. + /// + [DefaultValue(ImageSizeMode.NotSet), Category("Appearance")] + [Description("Indicates the 'mode' used to display the image.")] + public ImageSizeMode ImageSizeMode + { + get { return (_ImageSizeMode); } + + set + { + if (value!= _ImageSizeMode) + { + _ImageSizeMode = value; + + OnPropertyChangedEx("ImageSizeMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region Padding + + /// + /// Gets or sets the spacing between content and edges of the Image. + /// + [Description("Indicates the spacing between content and edges of the Image.")] + public Padding Padding + { + get + { + if (_Padding == null) + { + _Padding = Padding.Empty; + + UpdateChangeHandler(null, _Padding); + } + + return (_Padding); + } + + set + { + if (_Padding != value) + { + UpdateChangeHandler(_Padding, value); + + _Padding = value; + + OnPropertyChangedEx("Padding", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializePadding() + { + return (_Padding != null && _Padding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetPadding() + { + Padding = null; + } + + #endregion + + #region SymbolDef + + /// + /// Gets or sets the element Symbol Definition. Note that Symbol definition + /// takes precedence over Image definition. Also note that the supporting Image + /// properties (such as ImageAlignment, ImageOverlay, etc) apply to a set + /// Symbol as well as to a set Image. + /// + [DefaultValue(null), Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Description("Indicates the element Symbol Definition. Note that Symbol definition takes precedence over Image definition. Also note that the supporting Image properties (such as ImageAlignment, ImageOverlay, etc) apply to a set Symbol as well as to a set Image.")] + public SymbolDef SymbolDef + { + get + { + if (_SymbolDef == null) + { + _SymbolDef = new SymbolDef(); + + UpdateChangeHandler(null, _SymbolDef); + } + + return (_SymbolDef); + } + + set + { + if (_SymbolDef != value) + { + UpdateChangeHandler(_SymbolDef, value); + + _SymbolDef = value; + + OnPropertyChangedEx("SymbolDef", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeSymbolDef() + { + return (_SymbolDef != null && _SymbolDef.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetSymbolDef() + { + SymbolDef = null; + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color. + /// + [Description("Indicates the Text color.")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + TextColor = Color.Empty; + } + + #endregion + + #region TextInscribed + + /// + /// Gets or sets whether the Text is inscribed in the + /// PieCenter area (true = inscribed, false = circumscribed). + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether the Text is inscribed in the PieCenter area (true = inscribed, false = circumscribed).")] + public Tbool TextInscribed + { + get { return (_TextInscribed); } + + set + { + if (_TextInscribed != value) + { + _TextInscribed = value; + + OnPropertyChangedEx("TextInscribed", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Alignment == Alignment.NotSet) && + (_AllowWrap == Tbool.NotSet) && + (_Background == null || _Background.IsEmpty == true) && + (_Border == null || _Border.IsEmpty == true) && + (_Font == null) && + (_Image == null) && + (_ImageAlignment == Alignment.NotSet) && + (_ImageIndex == -1) && + (_ImageInscribed == Tbool.NotSet) && + (_ImageList == null) && + (_ImageOverlay == ImageOverlay.NotSet) && + (_ImagePadding == null || _ImagePadding.IsEmpty == true) && + (double.IsNaN(_ImageScale) == true) && + (_ImageSizeMode == Style.ImageSizeMode.NotSet) && + (_Padding == null || _Padding.IsEmpty == true) && + (_SymbolDef == null || _SymbolDef.IsEmpty == true) && + (_TextColor.IsEmpty == true) && + (_TextInscribed == Tbool.NotSet) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region IsOverlayImage + + internal bool IsOverlayImage + { + get + { + return (_ImageOverlay == ImageOverlay.Top || + _ImageOverlay == ImageOverlay.Middle || + _ImageOverlay == ImageOverlay.Bottom); + } + } + + #endregion + + #region IsValidFigure + + internal bool IsValidFigure + { + get + { + if (IsSymbolFigure == true) + return (true); + + return (GetImage() != null); + } + } + + #endregion + + #region IsSymbolFigure + + internal bool IsSymbolFigure + { + get { return (_SymbolDef != null && _SymbolDef.IsValidSymbol == true); } + } + + #endregion + + #region FigureSizeEx + + internal Size FigureSizeEx + { + get { return (_FigureSizeEx); } + set { _FigureSizeEx = value; } + } + + #endregion + + #endregion + + #region GetFigure + + internal object GetFigure() + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + return (_SymbolDef); + + return (GetImage()); + } + + #region GetImage + + internal Image GetImage() + { + if (_Image != null) + return (_Image); + + if (_ImageIndex >= 0) + { + ImageList imageList = ImageList; + + if (imageList != null && _ImageIndex < imageList.Images.Count) + return (imageList.Images[_ImageIndex]); + } + + return (null); + } + + #endregion + + #region GetSymbol + + internal string GetSymbol() + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + return (_SymbolDef.SymbolRealized); + + return (null); + } + + #endregion + + #endregion + + #region GetFigureSize + + internal Size GetFigureSize(Graphics g) + { + Size size = Size.Empty; + + if (IsSymbolFigure == true) + size = _SymbolDef.GetSymbolSize(g); + + else + { + Image image = GetImage(); + + if (image != null) + size = Dpi.Size(image.Size); + } + + return (size); + } + + #endregion + + #region GetFigureBounds + + internal Rectangle GetFigureBounds(Graphics g, Rectangle r) + { + if (IsSymbolFigure == true) + return (GetSymbolBounds(g, r)); + + return (GetImageBounds(g, r)); + } + + #region GetImageBounds + + internal Rectangle GetImageBounds(Graphics g, Rectangle r) + { + Image image = GetImage(); + + return (GetImageBounds(g, r, image)); + } + + private Rectangle GetImageBounds(Graphics g, Rectangle r, Image image) + { + if (image != null) + { + Size size = Dpi.Size(image.Size); + + if (double.IsNaN(ImageScale) == false) + { + if (ImageScale != 1) + size = FigureSizeEx; + } + + return (GetSizeBounds(r, size, ImageAlignment)); + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetSymbolBounds + + internal Rectangle GetSymbolBounds(Graphics g, Rectangle r) + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + { + Size size = _SymbolDef.GetSymbolSize(g); + + if (double.IsNaN(ImageScale) == false) + { + if (ImageScale != 1) + size = FigureSizeEx; + } + + return (GetSizeBounds(r, size, ImageAlignment)); + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetSizeBounds + + internal Rectangle GetSizeBounds(Rectangle r, + Size size, Padding padding, Alignment alignment) + { + switch (alignment) + { + case Alignment.NotSet: + case Alignment.MiddleLeft: + r.Y += (r.Height - size.Height) / 2; + + r.X += Dpi.Width(padding.Left); + r.Y += Dpi.Height(padding.Top - padding.Bottom); + break; + + case Alignment.TopLeft: + r.X += Dpi.Width(padding.Left); + r.Y += Dpi.Height(padding.Top); + break; + + case Alignment.BottomLeft: + r.Y = r.Bottom - size.Height; + + r.X += Dpi.Width(padding.Left); + r.Y -= Dpi.Height(padding.Bottom); + break; + + case Alignment.TopCenter: + r.X += (r.Width - size.Width) / 2; + + r.X += Dpi.Width(padding.Left - padding.Right); + r.Y += Dpi.Height(padding.Top); + break; + + case Alignment.MiddleCenter: + r.X += (r.Width - size.Width) / 2; + r.Y += (r.Height - size.Height) / 2; + + r.X += Dpi.Width(padding.Left - padding.Right); + r.Y += Dpi.Height(padding.Top - padding.Bottom); + break; + + case Alignment.BottomCenter: + r.X += (r.Width - size.Width) / 2; + r.Y = r.Bottom - size.Height; + + r.X += Dpi.Width(padding.Left - padding.Right); + r.Y -= Dpi.Height(padding.Bottom); + break; + + case Alignment.TopRight: + r.X = r.Right - size.Width; + + r.X -= Dpi.Width(padding.Right); + r.Y += Dpi.Height(padding.Top); + break; + + case Alignment.MiddleRight: + r.X = r.Right - size.Width; + r.Y += (r.Height - size.Height) / 2; + + r.X -= Dpi.Width(padding.Right); + r.Y += Dpi.Height(padding.Top - padding.Bottom); + break; + + case Alignment.BottomRight: + r.X = r.Right - size.Width; + r.Y = r.Bottom - size.Height; + + r.X -= Dpi.Width(padding.Right); + r.Y -= Dpi.Height(padding.Bottom); + break; + } + + r.Size = size; + + return (r); + } + + #endregion + + #region GetSizeBounds + + internal Rectangle GetSizeBounds(Rectangle r, Size size, Alignment alignment) + { + switch (alignment) + { + case Alignment.NotSet: + case Alignment.MiddleLeft: + r.Y += (r.Height - size.Height) / 2; + break; + + case Alignment.BottomLeft: + r.Y = r.Bottom - size.Height; + break; + + case Alignment.TopCenter: + r.X += (r.Width - size.Width) / 2; + break; + + case Alignment.MiddleCenter: + r.X += (r.Width - size.Width) / 2; + r.Y += (r.Height - size.Height) / 2; + break; + + case Alignment.BottomCenter: + r.X += (r.Width - size.Width) / 2; + r.Y = r.Bottom - size.Height; + break; + + case Alignment.TopRight: + r.X = r.Right - size.Width; + break; + + case Alignment.MiddleRight: + r.X = r.Right - size.Width; + r.Y += (r.Height - size.Height) / 2; + break; + + case Alignment.BottomRight: + r.X = r.Right - size.Width; + r.Y = r.Bottom - size.Height; + break; + } + + r.Size = size; + + return (r); + } + + #endregion + + #endregion + + #region GetTextBounds + + internal Rectangle GetTextBounds(Rectangle r, Size size) + { + return (GetSizeBounds(r, size, ImagePadding, Alignment)); + } + + #endregion + + #region RenderBackgroundFigure + + internal void RenderBackgroundFigure(Graphics g, Rectangle bounds) + { + RenderBackgroundFigure(g, bounds, bounds); + } + + internal void RenderBackgroundFigure(Graphics g, Rectangle bounds, Rectangle clipBounds) + { + if (IsSymbolFigure == true) + RenderBackgroundSymbol(g, bounds, clipBounds); + else + RenderBackgroundImage(g, bounds, clipBounds); + } + + #region RenderBackgroundImage + + internal void RenderBackgroundImage(Graphics g, Rectangle bounds, Rectangle clipBounds) + { + Image image = GetImage(); + + if (image != null) + { + Region clip = g.Clip; + + if (ImageSizeMode == ImageSizeMode.NotSet || + ImageSizeMode == ImageSizeMode.Normal) + { + Rectangle dbounds = GetImageBounds(g, clipBounds, image); + + g.SetClip(Rectangle.Intersect(bounds, dbounds), CombineMode.Intersect); + + g.DrawImage(image, dbounds, + new Rectangle(Point.Empty, image.Size), GraphicsUnit.Pixel); + } + else + { + Rectangle r = GetAdjustedBounds(clipBounds, ImagePadding); + + g.SetClip(r, CombineMode.Intersect); + + switch (ImageSizeMode) + { + case ImageSizeMode.Stretch: + g.PixelOffsetMode = PixelOffsetMode.Half; + g.DrawImage(image, r); + g.PixelOffsetMode = PixelOffsetMode.Default; + break; + + case ImageSizeMode.Tile: + RenderImageTiled(g, image, r); + break; + + case ImageSizeMode.Zoom: + RenderImageZoomed(g, image, r); + break; + } + } + + g.Clip = clip; + } + } + + #region GetAdjustedBounds + + private Rectangle GetAdjustedBounds(Rectangle bounds, Thickness padding) + { + if (padding.IsEmpty == false) + { + if (bounds.Height > padding.Vertical) + { + bounds.Y += padding.Top; + bounds.Height -= padding.Vertical; + } + + if (bounds.Width > padding.Horizontal) + { + bounds.X += padding.Left; + bounds.Width -= padding.Horizontal; + } + } + + return (bounds); + } + + #endregion + + #region RenderImageTiled + + private void RenderImageTiled(Graphics g, Image image, Rectangle bounds) + { + Size size = image.Size; + + Rectangle sr = new Rectangle(Point.Empty, size); + Rectangle dr = new Rectangle(bounds.Location, size); + + Rectangle r = new Rectangle(); + r.X = bounds.X + bounds.Width / 2; + r.Y = bounds.Y + bounds.Height / 2; + + int dx = ((bounds.Width / 2) / size.Width + 2) * size.Width; + int dy = ((bounds.Height / 2) / size.Height + 2) * size.Height; + + dr.X = r.X - dx + size.Width / 2; + dr.Y = r.Y - dy + size.Height / 2; + + int x = dr.X; + + while (dr.Top < bounds.Bottom) + { + while (dr.Left < bounds.Right) + { + g.DrawImage(image, dr, sr, GraphicsUnit.Pixel); + + dr.X += image.Size.Width; + } + + dr.X = x; + dr.Y += image.Size.Height; + } + } + + #endregion + + #region RenderImageZoomed + + private void RenderImageZoomed( + Graphics g, Image image, Rectangle r) + { + SizeF size = new SizeF(image.Width / image.HorizontalResolution, + image.Height / image.VerticalResolution); + + float scale = Math.Min(r.Width / size.Width, r.Height / size.Height); + + size.Width *= scale; + size.Height *= scale; + + Point pt = r.Location; + + if (Math.Abs(r.Width - size.Width) > 2) + { + switch (ImageAlignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + pt.X += (int)((r.Width - size.Width) / 2); + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + pt.X = (int)(r.Right - size.Width); + break; + } + } + else + { + switch (ImageAlignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + pt.Y += (int)((r.Height - size.Height) / 2); + break; + + case Alignment.BottomLeft: + case Alignment.BottomCenter: + case Alignment.BottomRight: + pt.Y = (int)(r.Bottom - size.Height); + break; + } + } + + g.PixelOffsetMode = PixelOffsetMode.Half; + + g.DrawImage(image, + pt.X, pt.Y, size.Width, size.Height); + + g.PixelOffsetMode = PixelOffsetMode.Default; + } + + #endregion + + #endregion + + #region RenderBackgroundSymbol + + internal void RenderBackgroundSymbol(Graphics g, Rectangle bounds, Rectangle clipBounds) + { + string symbol = GetSymbol(); + + if (symbol != null) + { + Region clip = g.Clip; + + TextRenderingHint hint = g.TextRenderingHint; + g.TextRenderingHint = TextRenderingHint.AntiAlias; + + bounds.X += (ImagePadding.Left - ImagePadding.Right); + bounds.Y += (ImagePadding.Top - ImagePadding.Bottom); + + if (ImageSizeMode == Style.ImageSizeMode.Stretch || + ImageSizeMode == Style.ImageSizeMode.Zoom) + { + if (_ScaleSymDef == null) + _ScaleSymDef = new SymbolDef(); + + float n = Math.Max(bounds.Width, bounds.Height); + + if (_SymFontScale < 0) + { + _ScaleSymDef.SymbolSize = n; + _ScaleSymDef.SymbolSet = _SymbolDef.SymbolSet; + + _SymFontScale = n / _ScaleSymDef.SymbolFont.Height * .8f; + } + + _ScaleSymDef.SymbolSize = n * _SymFontScale; + _ScaleSymDef.SymbolSet = _SymbolDef.SymbolSet; + + Rectangle t = bounds; + + if (t.Height > _ScaleSymDef.SymbolFont.Height) + { + t.Height = _ScaleSymDef.SymbolFont.Height; + t.Y += (bounds.Height - _ScaleSymDef.SymbolFont.Height) / 2; + } + + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Center; + + using (Brush br = new SolidBrush(_SymbolDef.SymbolColor)) + g.DrawString(_SymbolDef.SymbolRealized, _ScaleSymDef.SymbolFont, br, t, sf); + } + } + else if (ImageSizeMode == ImageSizeMode.Tile) + { + Rectangle r = GetAdjustedBounds(clipBounds, ImagePadding); + + g.SetClip(r, CombineMode.Intersect); + + RenderSymbolTiled(g, symbol, r); + } + else + { + Rectangle dbounds = GetSymbolBounds(g, clipBounds); + + float n = Math.Max(bounds.Width, bounds.Height); + + if (double.IsNaN(ImageScale) == false) + { + if (ImageScale != 1) + n = (int)(n * ImageScale); + } + + n = dbounds.Width; + + if (_ScaleSymDef == null) + _ScaleSymDef = new SymbolDef(); + + if (_SymFontScale < 0) + { + _ScaleSymDef.SymbolSize = n; + _ScaleSymDef.SymbolSet = _SymbolDef.SymbolSet; + + _SymFontScale = n / _ScaleSymDef.SymbolFont.Height * .8f; + } + + _ScaleSymDef.SymbolSize = n * _SymFontScale; + _ScaleSymDef.SymbolSet = _SymbolDef.SymbolSet; + + Rectangle t = dbounds; + + if (t.Height > _ScaleSymDef.SymbolFont.Height) + { + t.Height = _ScaleSymDef.SymbolFont.Height; + t.Y += (dbounds.Height - _ScaleSymDef.SymbolFont.Height) / 2; + } + + g.SetClip(Rectangle.Intersect(bounds, t), CombineMode.Intersect); + + using (Brush br = new SolidBrush(_SymbolDef.SymbolColor)) + g.DrawString(symbol, _ScaleSymDef.SymbolFont, br, t); + } + + g.TextRenderingHint = hint; + + g.Clip = clip; + } + } + + #region RenderSymbolTiled + + private void RenderSymbolTiled(Graphics g, string symbol, Rectangle bounds) + { + Font font = _SymbolDef.SymbolFont; + Color color = _SymbolDef.SymbolColor; + + Size size = _SymbolDef.GetSymbolSize(g); + Rectangle dr = new Rectangle(bounds.Location, size); + + Rectangle r = new Rectangle(); + r.X = bounds.X + bounds.Width / 2; + r.Y = bounds.Y + bounds.Height / 2; + + int dx = ((bounds.Width / 2) / size.Width + 2) * size.Width; + int dy = ((bounds.Height / 2) / size.Height + 2) * size.Height; + + dr.X = r.X - dx + size.Width / 2; + dr.Y = r.Y - dy + size.Height / 2; + + int x = dr.X; + + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + while (dr.Top < bounds.Bottom) + { + using (Brush br = new SolidBrush(_SymbolDef.SymbolColor)) + { + while (dr.Left < bounds.Right) + { + g.DrawString(symbol, font, br, dr, sf); + + dr.X += size.Width; + } + } + + dr.X = x; + dr.Y += size.Height; + } + } + } + + #endregion + + #endregion + + #endregion + + #region GetStringFormatFlags + + internal void GetStringFormatFlags(StringFormat sf) + { + if (AllowWrap == Tbool.False) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + switch (Alignment) + { + case Alignment.TopCenter: + sf.LineAlignment = StringAlignment.Near; + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.TopRight: + sf.LineAlignment = StringAlignment.Near; + sf.Alignment = StringAlignment.Far; + break; + + case Alignment.MiddleLeft: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Near; + break; + + case Alignment.MiddleCenter: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.MiddleRight: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Far; + break; + + case Alignment.BottomLeft: + sf.LineAlignment = StringAlignment.Far; + sf.Alignment = StringAlignment.Near; + break; + + case Alignment.BottomCenter: + sf.LineAlignment = StringAlignment.Far; + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.BottomRight: + sf.LineAlignment = StringAlignment.Far; + sf.Alignment = StringAlignment.Far; + break; + } + } + + #endregion + + #region GetTextFormatFlags + + internal eTextFormat GetTextFormatFlags() + { + eTextFormat tf = eTextFormat.WordEllipsis | + eTextFormat.NoPadding | eTextFormat.NoPrefix; + + if (AllowWrap == Tbool.True) + tf |= eTextFormat.WordBreak; + + switch (Alignment) + { + case Alignment.TopCenter: + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.TopRight: + tf |= eTextFormat.Right; + break; + + case Alignment.MiddleLeft: + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.NotSet: + case Alignment.MiddleCenter: + tf |= eTextFormat.HorizontalCenter; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleRight: + tf |= eTextFormat.Right; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.BottomLeft: + tf |= eTextFormat.Bottom; + break; + + case Alignment.BottomCenter: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.BottomRight: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.Right; + break; + } + + return (tf); + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(PieCenterVisualStyle style) + { + base.ApplyStyle(style); + + if (style != null) + { + if (style.Alignment != Alignment.NotSet) + Alignment = style.Alignment; + + if (style.AllowWrap != Tbool.NotSet) + AllowWrap = style.AllowWrap; + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style._Border != null && style._Border.IsEmpty == false) + Border = style._Border.Copy(); + + if (style.Font != null) + Font = style.Font; + + if (style.Image != null) + { + Image = style.Image; + ImageIndex = -1; + } + + if (style.ImageAlignment != Alignment.NotSet) + ImageAlignment = style.ImageAlignment; + + if (style.ImageIndex >= 0) + { + Image = null; + ImageIndex = style.ImageIndex; + } + + if (style.ImageInscribed != Tbool.NotSet) + ImageInscribed = style.ImageInscribed; + + if (style.ImageList != null) + ImageList = style.ImageList; + + if (style._ImageOverlay != ImageOverlay.NotSet) + ImageOverlay = style.ImageOverlay; + + if (style._ImagePadding != null && style._ImagePadding.IsEmpty == false) + ImagePadding = style._ImagePadding.Copy(); + + if (double.IsNaN(style._ImageScale) == false) + ImageScale = style._ImageScale; + + if (style._ImageSizeMode != ImageSizeMode.NotSet) + ImageSizeMode = style.ImageSizeMode; + + if (style._Padding != null && style._Padding.IsEmpty == false) + Padding = style._Padding.Copy(); + + if (style._SymbolDef != null && style._SymbolDef.IsEmpty == false) + SymbolDef = style._SymbolDef.Copy(); + + if (style._TextColor.IsEmpty == false) + TextColor = style._TextColor; + + if (style._TextInscribed != Tbool.NotSet) + TextInscribed = style.TextInscribed; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (_Alignment == Alignment.NotSet) + Alignment = Alignment.MiddleCenter; + + if (_Border != null) + Border.ApplyDefaults(); + + if (_Font == null) + Font = SystemFonts.DefaultFont; + + if (_ImageAlignment == Alignment.NotSet) + ImageAlignment = Alignment.MiddleLeft; + + if (_ImageInscribed == Tbool.NotSet) + ImageInscribed = Tbool.True; + + if (_ImageSizeMode == ImageSizeMode.NotSet) + ImageSizeMode = ImageSizeMode.Normal; + + if (_SymbolDef != null && _SymbolDef.IsValidSymbol == true) + { + if (_SymbolDef.SymbolSize == 0) + { + if (Font != null) + SymbolDef.SymbolSize = Font.SizeInPoints; + } + + if (_SymbolDef.SymbolColor.IsEmpty == true) + { + SymbolDef.SymbolColor = + (TextColor.IsEmpty == false) ? TextColor : Color.Black; + } + } + + if (_TextColor.IsEmpty == true) + TextColor = Color.Black; + + if (_TextInscribed == Tbool.NotSet) + TextInscribed = Tbool.True; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new PieCenterVisualStyle Copy() + { + PieCenterVisualStyle style = new PieCenterVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(PieCenterVisualStyle style) + { + base.CopyTo(style); + + style.Alignment = _Alignment; + style.AllowWrap = _AllowWrap; + + style.Background = (_Background == null) ? null : _Background.Copy(); + style.Border = (_Border != null) ? _Border.Copy() : null; + + style.Font = (_Font == null) ? null : (Font)_Font.Clone(); + + style.Image = _Image; + style.ImageAlignment = _ImageAlignment; + style.ImageIndex = _ImageIndex; + style.ImageInscribed = _ImageInscribed; + style.ImageList = _ImageList; + style.ImageOverlay = _ImageOverlay; + style.ImagePadding = (_ImagePadding != null) ? _ImagePadding.Copy() : null; + style.ImageScale = _ImageScale; + style.ImageSizeMode = _ImageSizeMode; + + style.Padding = (_Padding != null) ? _Padding.Copy() : null; + style.SymbolDef = (_SymbolDef != null) ? _SymbolDef.Copy() : null; + + style.TextColor = _TextColor; + style.TextInscribed = _TextInscribed; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "PieCenterVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("Alignment", Alignment, Alignment.NotSet); + sec.AddValue("AllowWrap", AllowWrap, Tbool.NotSet); + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + if (_Border != null && _Border.IsEmpty == false) + sec.AddElement(_Border.GetSerialData("Border")); + + if (_Font != null) + sec.AddValue("Font", XmlSerializableFont.ConvertToString(Font)); + + sec.AddValue("Image", Image); + sec.AddValue("ImageAlignment", ImageAlignment, Alignment.NotSet); + sec.AddValue("ImageIndex", ImageIndex, -1); + sec.AddValue("ImageInscribed", ImageInscribed, Tbool.NotSet); + + if (_ImageList != null) + sec.AddValue("ImageList", XmlSerializableImageList.ConvertToString(ImageList)); + + sec.AddValue("ImageOverlay", ImageOverlay, ImageOverlay.NotSet); + + if (_ImagePadding != null && _ImagePadding.IsEmpty == false) + sec.AddElement(_ImagePadding.GetSerialData("ImagePadding")); + + sec.AddValue("ImageScale", ImageScale, double.NaN); + sec.AddValue("ImageSizeMode", ImageSizeMode, ImageSizeMode.NotSet); + + if (_Padding != null && _Padding.IsEmpty == false) + sec.AddElement(_Padding.GetSerialData("Padding")); + + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + sec.AddElement(_SymbolDef.GetSerialData("SymbolDef")); + + sec.AddValue("TextColor", TextColor, Color.Empty); + sec.AddValue("TextInscribed", TextInscribed, Tbool.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement("ContainerVisualStyle"); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "Alignment": + Alignment = (Alignment)se.GetValueEnum(typeof(Alignment)); + break; + + case "AllowWrap": + AllowWrap = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "Font": + Font = XmlSerializableFont.ConvertFromString(se.StringValue); + break; + + case "Image": + Image = se.GetValueImage(); + break; + + case "ImageAlignment": + ImageAlignment = (Alignment)se.GetValueEnum(typeof(Alignment)); + break; + + case "ImageIndex": + ImageIndex = int.Parse(se.StringValue); + break; + + case "ImageInscribed": + ImageInscribed = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ImageList": + ImageList = XmlSerializableImageList.ConvertFromString(se.StringValue); + break; + + case "ImageOverlay": + ImageOverlay = (ImageOverlay)se.GetValueEnum(typeof(ImageOverlay)); + break; + + case "ImageScale": + ImageScale = double.Parse(se.StringValue); + break; + + case "ImageSizeMode": + ImageSizeMode = (ImageSizeMode)se.GetValueEnum(typeof(ImageSizeMode)); + break; + + case "TextColor": + TextColor = se.GetValueColor(); + break; + + case "TextInscribed": + TextInscribed = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "Background": + sec.PutSerialData(Background); + break; + + case "Border": + sec.PutSerialData(Border); + break; + + case "ImagePadding": + sec.PutSerialData(ImagePadding); + break; + + case "Padding": + sec.PutSerialData(Padding); + break; + + case "SymbolDef": + sec.PutSerialData(SymbolDef); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + Border = null; + + ImagePadding = null; + Padding = null; + + SymbolDef = null; + _ScaleSymDef = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieChartVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieChartVisualStyle.cs new file mode 100644 index 00000000..a7734604 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieChartVisualStyle.cs @@ -0,0 +1,491 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// PieChartVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class PieChartVisualStyles : VisualStyles + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public PieChartVisualStyles Copy() + { + PieChartVisualStyles styles = new PieChartVisualStyles(); + + for (int i = 0; i < Styles.Length; i++) + { + PieChartVisualStyle vstyle = Styles[i]; + + if (vstyle != null) + styles.Styles[i] = vstyle.Copy(); + } + + return (styles); + } + + #endregion + } + + /// + /// Represents the visual style of a Pie Chart element. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class PieChartVisualStyle : ContainerVisualStyle + { + #region Private variables + + private Background _AlternateGridBackground; + + private PieGridLineVisualStyle _GridLineVisualStyle; + private PieReferenceLineVisualStyle _ReferenceLineVisualStyle; + private PieCenterVisualStyles _PieCenterVisualStyles; + + #endregion + + #region Public properties + + #region AlternateGridBackground + + /// + /// Gets or sets the alternate, or interlaced, pie background (used + /// when ShowPieGrid is enabled). + /// + [Description("Indicates the alternate, or interlaced, pie background (used when ShowPieGrid is enabled)")] + public Background AlternateGridBackground + { + get + { + if (_AlternateGridBackground == null) + { + _AlternateGridBackground = Background.Empty; + + UpdateChangeHandler(null, _AlternateGridBackground); + } + + return (_AlternateGridBackground); + } + + set + { + if (_AlternateGridBackground != value) + { + UpdateChangeHandler(_AlternateGridBackground, value); + + _AlternateGridBackground = value; + + OnPropertyChangedEx("AlternateGridBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeAlternateGridBackground() + { + return (_AlternateGridBackground != null && _AlternateGridBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetAlternateGridBackground() + { + AlternateGridBackground = null; + } + + #endregion + + #region GridLineVisualStyle + + /// + /// Gets or sets the visual style to be used for GridLine elements. + /// + [Category("Style")] + [Description("Indicates visual style to be used for GridLine elements.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieGridLineVisualStyle GridLineVisualStyle + { + get + { + if (_GridLineVisualStyle == null) + { + _GridLineVisualStyle = new PieGridLineVisualStyle(); + + UpdateChangeHandler(null, _GridLineVisualStyle); + } + + return (_GridLineVisualStyle); + } + + set + { + if (_GridLineVisualStyle != value) + { + PieGridLineVisualStyle oldValue = _GridLineVisualStyle; + _GridLineVisualStyle = value; + + OnStyleChanged("GridLinesVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region PieCenterVisualStyles + + /// + /// Gets or sets the visual styles to be used for Pie Center elements. + /// + [Category("Style")] + [Description("Indicates visual styles to be used for Pie Center elements.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieCenterVisualStyles PieCenterVisualStyles + { + get + { + if (_PieCenterVisualStyles == null) + { + _PieCenterVisualStyles = new PieCenterVisualStyles(); + + UpdateChangeHandler(null, _PieCenterVisualStyles); + UpdatePropertyHandler(null, _PieCenterVisualStyles); + } + + return (_PieCenterVisualStyles); + } + + set + { + if (value != _PieCenterVisualStyles) + { + PieCenterVisualStyles oldValue = _PieCenterVisualStyles; + _PieCenterVisualStyles = value; + + OnStyleChanged("PieCenterVisualStyles", oldValue, value); + + UpdatePropertyHandler(oldValue, value); + } + } + } + + #region UpdatePropertyHandler + + protected void UpdatePropertyHandler( + PieCenterVisualStyles oldValue, PieCenterVisualStyles newValue) + { + if (oldValue != null) + { + for (int i = 0; i < oldValue.Count; i++) + { + BaseVisualStyle style = oldValue[(StyleType)i]; + + style.PropertyChanged -= style_PropertyChanged; + } + } + + if (newValue != null) + { + for (int i = 0; i < newValue.Count; i++) + { + BaseVisualStyle style = newValue[(StyleType)i]; + + style.PropertyChanged += style_PropertyChanged; + } + } + } + + #region style_PropertyChanged + + void style_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + BaseVisualStyle style = sender as BaseVisualStyle; + + if (style != null) + { + style.StyleUpdateCount++; + + BaseVisualStyle parent = style.Parent; + + while (parent != null) + { + parent.StyleUpdateCount++; + + parent = parent.Parent; + } + } + } + + #endregion + + #endregion + + #endregion + + #region ReferenceLineVisualStyle + + /// + /// Gets or sets the visual style to be used for ReferenceLine elements + /// + [Category("Style")] + [Description("Indicates visual style to be used for ReferenceLine elements ")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public PieReferenceLineVisualStyle ReferenceLineVisualStyle + { + get + { + if (_ReferenceLineVisualStyle == null) + { + _ReferenceLineVisualStyle = new PieReferenceLineVisualStyle(); + + UpdateChangeHandler(null, _ReferenceLineVisualStyle); + } + + return (_ReferenceLineVisualStyle); + } + + set + { + if (_ReferenceLineVisualStyle != value) + { + PieReferenceLineVisualStyle oldValue = _ReferenceLineVisualStyle; + _ReferenceLineVisualStyle = value; + + OnStyleChanged("ReferenceLineVisualStyle", oldValue, value); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_AlternateGridBackground == null || _AlternateGridBackground.IsEmpty) && + (_GridLineVisualStyle == null || _GridLineVisualStyle.IsEmpty) && + (_PieCenterVisualStyles == null || _PieCenterVisualStyles.IsEmpty) && + (_ReferenceLineVisualStyle == null || _ReferenceLineVisualStyle.IsEmpty) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(PieChartVisualStyle style) + { + base.ApplyStyle(style); + + if (style != null) + { + if (style._AlternateGridBackground != null && style.AlternateGridBackground.IsEmpty == false) + AlternateGridBackground = style.AlternateGridBackground.Copy(); + + if (style._GridLineVisualStyle != null && style._GridLineVisualStyle.IsEmpty == false) + GridLineVisualStyle.ApplyStyle(style.GridLineVisualStyle); + + if (style._PieCenterVisualStyles != null) + { + for (int i = 0; i < style._PieCenterVisualStyles.Styles.Length; i++) + { + if (style._PieCenterVisualStyles.Styles[i] != null) + PieCenterVisualStyles.GetStyle(i).ApplyStyle(style._PieCenterVisualStyles.Styles[i]); + } + } + + if (style._ReferenceLineVisualStyle != null && style._ReferenceLineVisualStyle.IsEmpty == false) + ReferenceLineVisualStyle.ApplyStyle(style._ReferenceLineVisualStyle); + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (Alignment == Alignment.NotSet) + Alignment = Alignment.MiddleCenter; + + if (_AlternateGridBackground == null) + AlternateGridBackground = new Background(Color.AliceBlue); + + GridLineVisualStyle.ApplyDefaults(); + + if (_GridLineVisualStyle.LineColor.IsEmpty == true) + GridLineVisualStyle.LineColor = Color.LightGray; + + ReferenceLineVisualStyle.ApplyDefaults(); + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new PieChartVisualStyle Copy() + { + PieChartVisualStyle style = new PieChartVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(PieChartVisualStyle style) + { + base.CopyTo(style); + + style.AlternateGridBackground = (_AlternateGridBackground != null) ? _AlternateGridBackground.Copy() : null; + + style.GridLineVisualStyle = (_GridLineVisualStyle != null) ? _GridLineVisualStyle.Copy() : null; + style.ReferenceLineVisualStyle = (_ReferenceLineVisualStyle != null) ? _ReferenceLineVisualStyle.Copy() : null; + + style.PieCenterVisualStyles = (_PieCenterVisualStyles != null) ? _PieCenterVisualStyles.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "PieChartVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_AlternateGridBackground != null && _AlternateGridBackground.IsEmpty == false) + sec.AddElement(_AlternateGridBackground.GetSerialData("AlternateBackground")); + + if (_GridLineVisualStyle != null && _GridLineVisualStyle.IsEmpty == false) + sec.AddElement(_GridLineVisualStyle.GetSerialData("GridLineVisualStyle")); + + if (_PieCenterVisualStyles != null && _PieCenterVisualStyles.IsEmpty == false) + sec.AddElement(_PieCenterVisualStyles.GetSerialData("PieCenterVisualStyles")); + + if (_ReferenceLineVisualStyle != null && _ReferenceLineVisualStyle.IsEmpty == false) + sec.AddElement(_ReferenceLineVisualStyle.GetSerialData("ReferenceLineVisualStyle")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "AlternateBackground": + sec.PutSerialData(AlternateGridBackground); + break; + + case "GridLineVisualStyle": + sec.PutSerialData(GridLineVisualStyle); + break; + + case "PieCenterVisualStyles": + sec.PutSerialData(PieCenterVisualStyles); + break; + + case "ReferenceLineVisualStyle": + sec.PutSerialData(ReferenceLineVisualStyle); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + AlternateGridBackground = null; + + GridLineVisualStyle = null; + PieCenterVisualStyles = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieGridLineVisualStyle .cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieGridLineVisualStyle .cs new file mode 100644 index 00000000..b37912f8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieGridLineVisualStyle .cs @@ -0,0 +1,44 @@ +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents a PieGridLineVisualStyle. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class PieGridLineVisualStyle : ChartLineVisualStyle + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new PieGridLineVisualStyle Copy() + { + PieGridLineVisualStyle style = new PieGridLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(PieGridLineVisualStyle style) + { + base.CopyTo(style); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieReferenceLineVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieReferenceLineVisualStyle.cs new file mode 100644 index 00000000..80434f20 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PieReferenceLineVisualStyle.cs @@ -0,0 +1,53 @@ +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents a PieReferenceLineVisualStyle. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class PieReferenceLineVisualStyle : ChartLineVisualStyle + { + #region ApplyDefaults + + public override void ApplyDefaults() + { + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new PieReferenceLineVisualStyle Copy() + { + PieReferenceLineVisualStyle style = new PieReferenceLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(PieReferenceLineVisualStyle style) + { + base.CopyTo(style); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PointMarkerVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PointMarkerVisualStyle.cs new file mode 100644 index 00000000..a75e6a96 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/PointMarkerVisualStyle.cs @@ -0,0 +1,765 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a PointMarker + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(VisualStylesConverter))] + public class PointMarkerVisualStyle : BaseVisualStyle + { + #region Private variables + + private PointMarkerType _Type = PointMarkerType.NotSet; + + private Background _Background; + private Color _BorderColor = Color.Empty; + private Size _Size = Size.Empty; + + private int _BorderWidth = -1; + private int _PointCount; + private int _Rotation = -1; + + private Image _Image; + private int _ImageIndex = -1; + private ImageList _ImageList; + + private Image _MarkerImage; + + #endregion + + #region Public properties + + #region Background + + /// + /// Gets or sets the Marker background for series points. + /// + [Description("Indicates the Marker background for series points")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region BorderColor + + /// + /// Gets or sets the Marker border color for series points. + /// + [Description("Indicates the point Marker Border Color for series points")] + public Color BorderColor + { + get { return (_BorderColor); } + + set + { + if (_BorderColor != value) + { + _BorderColor = value; + + OnPropertyChangedEx("BorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderColor() + { + return (_BorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderColor() + { + BorderColor = Color.Empty; + } + + #endregion + + #region BorderWidth + + /// + /// Gets or sets the Marker border width for series points. + /// + [DefaultValue(-1)] + [Description("Indicates the point Marker Border width for series points")] + public int BorderWidth + { + get { return (_BorderWidth); } + + set + { + if (_BorderWidth != value) + { + _BorderWidth = value; + + OnPropertyChangedEx("BorderWidth", VisualChangeType.Render); + } + } + } + + #endregion + + #region Image + + /// + /// Gets or sets the PointMarker Image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the PointMarker image")] + public Image Image + { + get { return (_Image); } + + set + { + if (_Image != value) + { + _Image = value; + + FreeMarkerImage(); + + OnPropertyChangedEx("Image", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageIndex + + /// + /// Gets or sets the PointMarker image index + /// + [DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the image index")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int ImageIndex + { + get { return (_ImageIndex); } + + set + { + if (_ImageIndex != value) + { + _ImageIndex = value; + + FreeMarkerImage(); + + OnPropertyChangedEx("ImageIndex", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageList + + /// + /// Gets or sets the ImageList. + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates the ImageList.")] + public ImageList ImageList + { + get { return (_ImageList); } + + set + { + if (_ImageList != value) + { + _ImageList = value; + + FreeMarkerImage(); + + OnPropertyChangedEx("ImageList", VisualChangeType.Layout); + } + } + } + + #endregion + + #region PointCount + + /// + /// Gets or sets the number of points for series markers (3 = triangle, 4 square, etc). + /// + [DefaultValue(0)] + [Description("Indicates the number of points for series markers (3 = triangle, 4 square, etc).")] + public int PointCount + { + get { return (_PointCount); } + + set + { + if (_PointCount != value) + { + if (value < 0) + throw new Exception("PointMarkerPoints must be >= 0"); + + _PointCount = value; + + OnPropertyChangedEx("PointCount", VisualChangeType.Render); + } + } + } + + #endregion + + #region Rotation + + /// + /// Gets or sets the Marker rotation angle for series points. + /// + [Description("Indicates the Marker rotation angle for series points.")] + [DefaultValue(-1)] + public int Rotation + { + get { return (_Rotation); } + + set + { + if (_Rotation != value) + { + _Rotation = value; + + OnPropertyChangedEx("Rotation", VisualChangeType.Render); + } + } + } + + #endregion + + #region Size + + /// + /// Gets or sets the Marker size for series points + /// + [Description("Indicates the Marker size for series points.")] + public Size Size + { + get { return (_Size); } + + set + { + if (_Size != value) + { + _Size = value; + + OnPropertyChangedEx("Size", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeSize() + { + return (Size.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetSize() + { + Size = Size.Empty; + } + + #endregion + + #region Type + + /// + /// Gets or sets the Marker type. + /// + [Description("Indicates the Marker type.")] + [DefaultValue(PointMarkerType.NotSet)] + public PointMarkerType Type + { + get { return (_Type); } + + set + { + if (_Type != value) + { + _Type = value; + + OnPropertyChangedEx("Type", VisualChangeType.Render); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Background == null || _Background.IsEmpty == true) && + (_BorderColor == null || _BorderColor.IsEmpty == true) && + (_BorderWidth == -1) && + (_Image == null) && + (_ImageIndex == -1) && + (_ImageList == null) && + (_PointCount <= 0) && + (_Rotation == -1) && + (_Size.IsEmpty == true) && + (_Type == PointMarkerType.NotSet) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region GetPointMarkerImage + + internal Image GetPointMarkerImage() + { + if (_MarkerImage != null) + return (_MarkerImage); + + _MarkerImage = GetPointMarkerImageEx(); + + if (_MarkerImage != null) + { + if (Dpi.UseFactor == true) + { + Size size = _MarkerImage.Size; + + size.Width *= Dpi.Width1; + size.Height *= Dpi.Width1; + + _MarkerImage = new Bitmap(_MarkerImage, size); + } + } + + return (_MarkerImage); + } + + #region GetPointMarkerImageEx + + private Image GetPointMarkerImageEx() + { + if (_Image != null) + return (_Image); + + if (_ImageIndex >= 0) + { + ImageList imageList = ImageList; + + if (imageList != null && _ImageIndex < imageList.Images.Count) + return (imageList.Images[_ImageIndex]); + } + + return (null); + } + + #endregion + + #endregion + + #region FreeMarkerImage + + private void FreeMarkerImage() + { + if (_MarkerImage != null) + { + _MarkerImage.Dispose(); + + _MarkerImage = null; + } + } + + #endregion + + #region RenderMarker + + internal void RenderMarker( + Graphics g, PointMarker pointMarker, Rectangle bounds, Color color) + { + Image marker = GetPointMarkerImage(); + + if (marker != null) + { + g.DrawImage(marker, bounds); + } + else + { + if (Type != PointMarkerType.NotSet && Type != PointMarkerType.None) + { + if (Background.IsEmpty == true) + { + using (Background back = new Background(color)) + { + marker = pointMarker.GetMarkerBitmap(g, Type, PointCount, + bounds.Size, Rotation, back, BorderColor, BorderWidth); + } + } + else + { + marker = pointMarker.GetMarkerBitmap(g, Type, PointCount, + bounds.Size, Rotation, Background, BorderColor, BorderWidth); + } + } + + if (marker != null) + { + // Make allowances for the fact that GetPointMarker() adjusts the + // size and pos of the image to allow for better anti-aliasing + + bounds.X--; + bounds.Y--; + + g.DrawImageUnscaled(marker, bounds); + } + else + { + RenderDefaultMarker(g, bounds, color); + } + } + } + + #region RenderDefaultMarker + + private void RenderDefaultMarker(Graphics g, Rectangle bounds, Color color) + { + bounds.Width++; + bounds.Height++; + + Background background = Background; + + if (background.IsEmpty == true) + { + if (color.IsEmpty == true) + color = Color.DimGray; + + using (Brush br = new SolidBrush(color)) + g.FillRectangle(br, bounds); + } + else + { + using (Brush br = background.GetBrush(bounds)) + g.FillRectangle(br, bounds); + } + + if (BorderColor.IsEmpty == false && BorderWidth > 0) + { + using (Pen pen = new Pen(BorderColor, BorderWidth)) + { + pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset; + + g.DrawRectangle(pen, bounds); + } + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(PointMarkerVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style.BorderColor.IsEmpty == false) + BorderColor = style.BorderColor; + + if (style.BorderWidth >= 0) + BorderWidth = style.BorderWidth; + + if (style.Image != null) + Image = style.Image; + + if (style.ImageIndex >= 0) + ImageIndex = style.ImageIndex; + + if (style._ImageList != null) + ImageList = style._ImageList; + + if (style.PointCount > 0) + PointCount = style.PointCount; + + if (style.Rotation != -1) + Rotation = style.Rotation; + + if (style.Size.IsEmpty == false) + Size = style.Size; + + if (style.Type != PointMarkerType.NotSet) + Type = style.Type; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (PointCount <= 0) + PointCount = 5; + + if (Size.IsEmpty) + Size = new Size(5, 5); + + if (BorderWidth == -1) + BorderWidth = 1; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new PointMarkerVisualStyle Copy() + { + PointMarkerVisualStyle style = new PointMarkerVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(PointMarkerVisualStyle style) + { + base.CopyTo(style); + + style.Background = (_Background != null) ? _Background.Copy() : null; + + style.BorderColor = _BorderColor; + style.BorderWidth = _BorderWidth; + + style.Image = _Image; + style.ImageIndex = _ImageIndex; + style.ImageList = _ImageList; + + style.PointCount = _PointCount; + style.Rotation = _Rotation; + style.Size = _Size; + style.Type = _Type; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "PointMarkerVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + sec.AddValue("BorderColor", _BorderColor, Color.Empty); + sec.AddValue("BorderWidth", _BorderWidth, -1); + + sec.AddValue("Image", Image); + sec.AddValue("ImageIndex", _ImageIndex, -1); + + if (_ImageList != null) + sec.AddValue("ImageList", XmlSerializableImageList.ConvertToString(ImageList)); + + sec.AddValue("PointCount", _PointCount, 0); + sec.AddValue("Rotation", _Rotation, -1); + sec.AddValue("Size", _Size, Size.Empty); + sec.AddValue("Type", _Type, PointMarkerType.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "BorderColor": + BorderColor = se.GetValueColor(); + break; + + case "BorderWidth": + BorderWidth = int.Parse(se.StringValue); + break; + + case "Image": + Image = se.GetValueImage(); + break; + + case "ImageIndex": + ImageIndex = int.Parse(se.StringValue); + break; + + case "ImageList": + ImageList = XmlSerializableImageList.ConvertFromString(se.StringValue); + break; + + case "PointCount": + PointCount = int.Parse(se.StringValue); + break; + + case "Rotation": + Rotation = int.Parse(se.StringValue); + break; + + case "Size": + Size = se.GetValueSize(); + break; + + case "Type": + Type = (PointMarkerType)se.GetValueEnum(typeof(PointMarkerType)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "Background": + sec.PutSerialData(Background); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ReferenceLineVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ReferenceLineVisualStyle.cs new file mode 100644 index 00000000..2d162549 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ReferenceLineVisualStyle.cs @@ -0,0 +1,460 @@ +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents a ReferenceLineVisualStyle. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ReferenceLineVisualStyle : ChartLineVisualStyle + { + #region Private variables + + private Alignment _TextAlignment = Alignment.NotSet; + private Tbool _AllowWrap = Tbool.NotSet; + private Color _TextColor = Color.Empty; + private Padding _TextPadding; + private Font _Font; + + #endregion + + #region Public properties + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Render); + } + } + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font + /// + [DefaultValue(null)] + [Description("Indicates the style Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TextAlignment + + /// + /// Gets or sets the Text alignment. + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the Text alignment.")] + public Alignment TextAlignment + { + get { return (_TextAlignment); } + + set + { + if (value != _TextAlignment) + { + _TextAlignment = value; + + OnPropertyChangedEx("TextAlignment", VisualChangeType.Render); + } + } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Reference Line Text Color. + /// + [Category("Appearance")] + [Description("Indicates the Reference Line Text Color.")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (value != _TextColor) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", Style.VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + _TextColor = Color.Empty; + } + + #endregion + + #region TextPadding + + /// + /// Gets or sets spacing between the content and edges of the Text. + /// + [Description("Indicates the spacing between the content and edges of the Text")] + public Padding TextPadding + { + get + { + if (_TextPadding == null) + { + _TextPadding = Padding.Empty; + + UpdateChangeHandler(null, _TextPadding); + } + + return (_TextPadding); + } + + set + { + if (_TextPadding != value) + { + UpdateChangeHandler(_TextPadding, value); + + _TextPadding = value; + + OnPropertyChangedEx("TextPadding", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextPadding() + { + return (_TextPadding != null && _TextPadding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextPadding() + { + TextPadding = null; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_AllowWrap == Tbool.NotSet) && + (_Font == null) && + (_TextAlignment == Alignment.NotSet) && + (_TextColor.IsEmpty == true) && + (_TextPadding == null || _TextPadding.IsEmpty == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region GetStringFormatFlags + + internal void GetStringFormatFlags(StringFormat sf) + { + if (AllowWrap == Tbool.False) + { + sf.FormatFlags |= StringFormatFlags.NoWrap; + sf.Trimming = StringTrimming.None; + } + + switch (TextAlignment) + { + case Alignment.TopLeft: + sf.Alignment = StringAlignment.Near; + break; + + case Alignment.TopCenter: + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.TopRight: + sf.Alignment = StringAlignment.Far; + break; + + case Alignment.MiddleLeft: + sf.Alignment = StringAlignment.Near; + break; + + case Alignment.MiddleCenter: + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.MiddleRight: + sf.Alignment = StringAlignment.Far; + break; + + case Alignment.BottomLeft: + sf.Alignment = StringAlignment.Near; + break; + + case Alignment.BottomCenter: + sf.Alignment = StringAlignment.Center; + break; + + case Alignment.BottomRight: + sf.Alignment = StringAlignment.Far; + break; + } + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ReferenceLineVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.AllowWrap != Tbool.NotSet) + _AllowWrap = style.AllowWrap; + + if (style.Font != null) + _Font = (Font)style.Font.Clone(); + + if (style.TextAlignment != Alignment.NotSet) + _TextAlignment = style.TextAlignment; + + if (style.TextColor.IsEmpty == false) + _TextColor = style.TextColor; + + if (style._TextPadding != null && style._TextPadding.IsEmpty == false) + TextPadding = style.TextPadding.Copy(); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ReferenceLineVisualStyle Copy() + { + ReferenceLineVisualStyle style = new ReferenceLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ReferenceLineVisualStyle style) + { + base.CopyTo(style); + + style.AllowWrap = _AllowWrap; + + style.Font = (_Font != null) ? (Font)_Font.Clone() : null; + + style.TextAlignment = _TextAlignment; + style.TextColor = _TextColor; + + style.TextPadding = (_TextPadding != null) ? _TextPadding.Copy() : null; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ReferenceLineVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AllowWrap", AllowWrap, Tbool.NotSet); + + if (_Font != null) + sec.AddValue("Font", XmlSerializableFont.ConvertToString(Font)); + + sec.AddValue("TextAlignment", TextAlignment, Alignment.NotSet); + sec.AddValue("TextColor", TextColor, Color.Empty); + + if (_TextPadding != null && _TextPadding.IsEmpty == false) + sec.AddElement(_TextPadding.GetSerialData("TextPadding")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AllowWrap": + AllowWrap = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "Font": + Font = XmlSerializableFont.ConvertFromString(se.StringValue); + break; + + case "TextAlignment": + TextAlignment = (Alignment)se.GetValueEnum(typeof(Alignment)); + break; + + case "TextColor": + TextColor = se.GetValueColor(); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "TextPadding": + sec.PutSerialData(TextPadding); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + TextPadding = null; + + base.Dispose(); + } + + #endregion + } + + #region enums + + #region NearAlignment + + public enum NearAlignment + { + NotSet = -1, + + Near, + + Far, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/RegressionLineVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/RegressionLineVisualStyle.cs new file mode 100644 index 00000000..28f90b83 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/RegressionLineVisualStyle.cs @@ -0,0 +1,42 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a Legend element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class RegressionLineVisualStyle : ChartCapLineVisualStyle + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new RegressionLineVisualStyle Copy() + { + RegressionLineVisualStyle style = new RegressionLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(RegressionLineVisualStyle style) + { + base.CopyTo(style); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ScrollBarVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ScrollBarVisualStyle.cs new file mode 100644 index 00000000..1692ffc6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/ScrollBarVisualStyle.cs @@ -0,0 +1,739 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// ScrollBarVisualStyle + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ScrollBarVisualStyles : VisualStyles + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public ScrollBarVisualStyles Copy() + { + ScrollBarVisualStyles styles = new ScrollBarVisualStyles(); + + for (int i = 0; i < Styles.Length; i++) + { + ScrollBarVisualStyle vstyle = Styles[i]; + + if (vstyle != null) + styles.Styles[i] = vstyle.Copy(); + } + + return (styles); + } + + #endregion + } + + /// + /// Represents the visual style of a ScrollBar element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ScrollBarVisualStyle : BaseVisualStyle + { + #region Private variables + + private Color _ArrowColor; + private Color _ArrowBorderColor; + private Background _ArrowBackground; + + private Color _ThumbColor; + private Color _ThumbBorderColor; + private Background _ThumbBackground; + + private Color _BorderColor; + private Background _TrackBackground; + + private Tbool _NoAlphaOnMouseOver = Tbool.NotSet; + + #endregion + + #region Public properties + + #region ArrowBackground + + /// + /// Gets or sets the Background of the Increase/Decrease Arrow elements of the ScrollBar. + /// + [Description("Indicates the Background of the Increase/Decrease Arrow elements of the ScrollBar")] + public Background ArrowBackground + { + get + { + if (_ArrowBackground == null) + { + _ArrowBackground = Background.Empty; + + UpdateChangeHandler(null, _ArrowBackground); + } + + return (_ArrowBackground); + } + + set + { + if (value != _ArrowBackground) + { + UpdateChangeHandler(_ArrowBackground, value); + + _ArrowBackground = value; + + OnPropertyChangedEx("ArrowBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeArrowBackground() + { + return (_ArrowBackground != null && _ArrowBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetArrowBackground() + { + ArrowBackground = null; + } + + #endregion + + #region ArrowBorderColor + + /// + /// Gets or sets the Arrow Increase/Decrease border color. + /// + [Description("Indicates the Arrow Increase/Decrease border color")] + public Color ArrowBorderColor + { + get { return (_ArrowBorderColor); } + + set + { + if (value != _ArrowBorderColor) + { + _ArrowBorderColor = value; + + OnPropertyChangedEx("ArrowBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeArrowBorderColor() + { + return (_ArrowBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetArrowBorderColor() + { + ArrowBorderColor = Color.Empty; + } + + #endregion + + #region ArrowColor + + /// + /// Gets or sets the Color of the Increase/Decrease Arrow elements of the scrollBar. + /// + [Description("Indicates the Color of the Increase/Decrease Arrow elements of the scrollBar")] + public Color ArrowColor + { + get { return (_ArrowColor); } + + set + { + if (value != _ArrowColor) + { + _ArrowColor = value; + + OnPropertyChangedEx("ArrowColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeArrowColor() + { + return (_ArrowColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetArrowColor() + { + ArrowColor = Color.Empty; + } + + #endregion + + #region BorderColor + + /// + /// Gets or sets the border color of the scrollBar. + /// + [Description("Indicates the Border Color of the scrollBar")] + public Color BorderColor + { + get { return (_BorderColor); } + + set + { + if (value != _BorderColor) + { + _BorderColor = value; + + OnPropertyChangedEx("BorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderColor() + { + return (_BorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderColor() + { + BorderColor = Color.Empty; + } + + #endregion + + #region NoAlphaOnMouseOver + + /// + /// Gets or sets whether color alpha values are ignored when the mouse is over the scrollbar. + /// + [DefaultValue(Tbool.NotSet)] + [Description("Indicates whether color alpha values are ignored when the mouse is over the scrollbar.")] + public Tbool NoAlphaOnMouseOver + { + get { return (_NoAlphaOnMouseOver); } + + set + { + if (value != _NoAlphaOnMouseOver) + { + _NoAlphaOnMouseOver = value; + + OnPropertyChangedEx("NoAlphaOnMouseOver", VisualChangeType.Render); + } + } + } + + #endregion + + #region ThumbBackground + + /// + /// Gets or sets the Background of the Thumb element of the ScrollBar. + /// + [Description("Indicates the Background of the Thumb element of the ScrollBar")] + public Background ThumbBackground + { + get + { + if (_ThumbBackground == null) + { + _ThumbBackground = Background.Empty; + + UpdateChangeHandler(null, _ThumbBackground); + } + + return (_ThumbBackground); + } + + set + { + if (value != _ThumbBackground) + { + UpdateChangeHandler(_ThumbBackground, value); + + _ThumbBackground = value; + + OnPropertyChangedEx("ThumbBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeThumbBackground() + { + return (_ThumbBackground != null && _ThumbBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetThumbBackground() + { + ThumbBackground = null; + } + + #endregion + + #region ThumbBorderColor + + /// + /// Gets or sets the Thumb border color. + /// + [Description("Indicates the Thumb border color")] + public Color ThumbBorderColor + { + get { return (_ThumbBorderColor); } + + set + { + if (value != _ThumbBorderColor) + { + _ThumbBorderColor = value; + + OnPropertyChangedEx("ThumbBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeThumbBorderColor() + { + return (_ThumbBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetThumbBorderColor() + { + ThumbBorderColor = Color.Empty; + } + + #endregion + + #region ThumbColor + + /// + /// Gets or sets the Color of the Thumb content element (hash marks) of the scrollBar. + /// + [Description("Indicates the Color of the Thumb content element (hash marks) of the scrollBar")] + public Color ThumbColor + { + get { return (_ThumbColor); } + + set + { + if (value != _ThumbColor) + { + _ThumbColor = value; + + OnPropertyChangedEx("ThumbColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeThumbColor() + { + return (_ThumbColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetThumbColor() + { + ThumbColor = Color.Empty; + } + + #endregion + + #region TrackBackground + + /// + /// Gets or sets the Background of the Increase/Decrease Track elements of the ScrollBar. + /// + [Description("Indicates the Background of the Increase/Decrease Track elements of the ScrollBar")] + public Background TrackBackground + { + get + { + if (_TrackBackground == null) + { + _TrackBackground = Background.Empty; + + UpdateChangeHandler(null, _TrackBackground); + } + + return (_TrackBackground); + } + + set + { + if (_TrackBackground != value) + { + UpdateChangeHandler(_TrackBackground, value); + + _TrackBackground = value; + + OnPropertyChangedEx("TrackBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTrackBackground() + { + return (_TrackBackground != null && _TrackBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTrackBackground() + { + TrackBackground = null; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_ArrowBackground == null || _ArrowBackground.IsEmpty) && + (_ArrowBorderColor.IsEmpty) && + (_ArrowColor.IsEmpty) && + (_BorderColor.IsEmpty) && + (_NoAlphaOnMouseOver == Tbool.NotSet) && + (_ThumbBackground == null || _ThumbBackground.IsEmpty) && + (_ThumbBorderColor.IsEmpty) && + (_ThumbColor.IsEmpty) && + (_TrackBackground == null || _TrackBackground.IsEmpty) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region GetColor + + internal Color GetColor(Color color, bool noAlpha) + { + if (noAlpha == false) + return (color); + + uint argb = (uint)color.ToArgb() | 0xff000000; + + return (Color.FromArgb((int)argb)); + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ScrollBarVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.ArrowBackground.IsEmpty == false) + ArrowBackground = style.ArrowBackground.Copy(); + + if (style.ArrowBorderColor.IsEmpty == false) + ArrowBorderColor = style.ArrowBorderColor; + + if (style.ArrowColor.IsEmpty == false) + ArrowColor = style.ArrowColor; + + if (style.BorderColor.IsEmpty == false) + BorderColor = style.BorderColor; + + if (style.NoAlphaOnMouseOver != Tbool.NotSet) + NoAlphaOnMouseOver = style.NoAlphaOnMouseOver; + + if (style.ThumbBackground.IsEmpty == false) + ThumbBackground = style.ThumbBackground.Copy(); + + if (style.ThumbBorderColor.IsEmpty == false) + ThumbBorderColor = style.ThumbBorderColor; + + if (style.ThumbColor.IsEmpty == false) + ThumbColor = style.ThumbColor; + + if (style.TrackBackground.IsEmpty == false) + TrackBackground = style.TrackBackground.Copy(); + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (ArrowBackground.IsEmpty) + ArrowBackground = new Background(Color.Gainsboro); + + if (ThumbBackground.IsEmpty) + ThumbBackground = new Background(Color.White, Color.Gainsboro); + + if (TrackBackground.IsEmpty) + TrackBackground = new Background(Color.Gainsboro); + + if (BorderColor.IsEmpty) + BorderColor = Color.Gray; + + if (ThumbBorderColor.IsEmpty) + ThumbBorderColor = Color.Gray; + + if (ArrowColor.IsEmpty) + ArrowColor = Color.DimGray; + + if (ThumbColor.IsEmpty) + ThumbColor = Color.Black; + + if (ArrowBorderColor.IsEmpty) + ArrowBorderColor = Color.Gray; + + if (NoAlphaOnMouseOver == Tbool.NotSet) + NoAlphaOnMouseOver = Tbool.False; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ScrollBarVisualStyle Copy() + { + ScrollBarVisualStyle style = new ScrollBarVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ScrollBarVisualStyle style) + { + base.CopyTo(style); + + style.ArrowBackground = (_ArrowBackground != null ? _ArrowBackground.Copy() : null); + + style.ArrowBorderColor = _ArrowBorderColor; + style.ArrowColor = _ArrowColor; + style.BorderColor = _BorderColor; + style.NoAlphaOnMouseOver = _NoAlphaOnMouseOver; + + style.ThumbBackground = (_ThumbBackground != null ? _ThumbBackground.Copy() : null); + + style.ThumbBorderColor = _ThumbBorderColor; + style.ThumbColor = _ThumbColor; + + style.TrackBackground = (_TrackBackground != null ? _TrackBackground.Copy() : null); + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ScrollBarVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_ArrowBackground != null && _ArrowBackground.IsEmpty == false) + sec.AddElement(_ArrowBackground.GetSerialData("ArrowBackground")); + + sec.AddValue("ArrowBorderColor", ArrowBorderColor, Color.Empty); + sec.AddValue("ArrowColor", ArrowColor, Color.Empty); + sec.AddValue("BorderColor", BorderColor, Color.Empty); + sec.AddValue("NoAlphaOnMouseOver", NoAlphaOnMouseOver, Tbool.NotSet); + + if (_ThumbBackground != null && _ThumbBackground.IsEmpty == false) + sec.AddElement(_ThumbBackground.GetSerialData("ThumbBackground")); + + sec.AddValue("ThumbBorderColor", ThumbBorderColor, Color.Empty); + sec.AddValue("ThumbColor", ThumbColor, Color.Empty); + + if (_TrackBackground != null && _TrackBackground.IsEmpty == false) + sec.AddElement(_TrackBackground.GetSerialData("TrackBackground")); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "ArrowBorderColor": + ArrowBorderColor = se.GetValueColor(); + break; + + case "ArrowColor": + ArrowColor = se.GetValueColor(); + break; + + case "BorderColor": + BorderColor = se.GetValueColor(); + break; + + case "NoAlphaOnMouseOver": + NoAlphaOnMouseOver = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "ThumbBorderColor": + ThumbBorderColor = se.GetValueColor(); + break; + + case "ThumbColor": + ThumbColor = se.GetValueColor(); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "ArrowBackground": + sec.PutSerialData(ArrowBackground); + break; + + case "ThumbBackground": + sec.PutSerialData(ThumbBackground); + break; + + case "TrackBackground": + sec.PutSerialData(TrackBackground); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + public override void Dispose() + { + ArrowBackground = null; + ThumbBackground = null; + TrackBackground = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/SeriesLabelVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/SeriesLabelVisualStyle.cs new file mode 100644 index 00000000..0cdb01d5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/SeriesLabelVisualStyle.cs @@ -0,0 +1,602 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents a SeriesLabelVisualStyle. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class SeriesLabelVisualStyle : ContainerVisualStyle + { + #region Private variables + + private Color _ConnectorColor = Color.Empty; + private LinePattern _ConnectorPattern = LinePattern.NotSet; + + private int _ConnectorLength = -1; + private int _ConnectorThickness = -1; + + private Tbool _DrawConnector = Tbool.NotSet; + private Tbool _ShowBaseValueLabels = Tbool.NotSet; + + private Size _MaximumSize = Size.Empty; + private Size _MinimumSize = Size.Empty; + + private Point _Offset; + + private float _Rotation = float.NaN; + + private string _TextFormat; + + #endregion + + #region Public properties + + #region ConnectorColor + + /// + /// Gets or sets the style border color. + /// + [Description("Indicates the style Border Color")] + public Color ConnectorColor + { + get { return (_ConnectorColor); } + + set + { + if (value != _ConnectorColor) + { + _ConnectorColor = value; + + OnPropertyChangedEx("ConnectorColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeConnectorColor() + { + return (_ConnectorColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetConnectorColor() + { + _ConnectorColor = Color.Empty; + } + + #endregion + + #region ConnectorLength + + /// + /// Gets or sets the length of the line connecting the slice + /// and the slice label. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the length of the line connecting the slice and the slice label.")] + public int ConnectorLength + { + get { return (_ConnectorLength); } + + set + { + if (value != _ConnectorLength) + { + if (value < 0) + throw new InvalidPropertyValueException("value cannot be negative."); + + _ConnectorLength = value; + + OnPropertyChangedEx("ConnectorLength", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ConnectorPattern + + /// + /// Gets or sets the style border pattern (Solid, Dash, ...) + /// + [Description("Indicates the style border pattern (Solid, Dash, ...)")] + [DefaultValue(LinePattern.NotSet)] + public LinePattern ConnectorPattern + { + get { return (_ConnectorPattern); } + + set + { + if (value != _ConnectorPattern) + { + _ConnectorPattern = value; + + OnPropertyChangedEx("ConnectorPattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region ConnectorThickness + + /// + /// Gets or sets the style border thickness. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the style border thickness")] + public int ConnectorThickness + { + get { return (_ConnectorThickness); } + + set + { + if (value != _ConnectorThickness) + { + _ConnectorThickness = value; + + OnPropertyChangedEx("ConnectorThickness", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DrawConnector + + /// + /// Gets or sets whether a connecting line is drawn to the data point. + /// + [DefaultValue(Tbool.NotSet), Category("DataLabel")] + [Description("Indicates whether a connecting line is drawn to the data point.")] + public Tbool DrawConnector + { + get { return (_DrawConnector); } + + set + { + if (value != _DrawConnector) + { + _DrawConnector = value; + + OnPropertyChangedEx("DrawConnector", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region MaximumSize + + /// + /// Gets or sets the maximum size of the label. + /// + [Category("Appearance")] + [Description("Indicates the maximum size of the label.")] + public Size MaximumSize + { + get { return (_MaximumSize); } + + set + { + if (value != _MaximumSize) + { + _MaximumSize = value; + + OnPropertyChangedEx("MaximumSize", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeCMaximumSize() + { + return (_MaximumSize.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetMaximumSize() + { + MaximumSize = Size.Empty; + } + + #endregion + + #region MinimumSize + + /// + /// Gets or sets the minimum size of the label. + /// + [Category("Appearance")] + [Description("Indicates the minimum size of the label.")] + public Size MinimumSize + { + get { return (_MinimumSize); } + + set + { + if (value != _MinimumSize) + { + _MinimumSize = value; + + OnPropertyChangedEx("MinimumSize", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeMinimumSize() + { + return (_MinimumSize.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetMinimumSize() + { + MinimumSize = Size.Empty; + } + + #endregion + + #region Offset + + /// + /// Gets or sets the offset of the label relative to the data point. + /// + [Category("Appearance")] + [Description("Indicates the offset of the label relative to the data point.")] + public Point Offset + { + get { return (_Offset); } + + set + { + if (value != _Offset) + { + _Offset = value; + + OnPropertyChangedEx("Offset", Style.VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeOffset() + { + return (_Offset.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetOffset() + { + Offset = Point.Empty; + } + + #endregion + + #region Rotation + + /// + /// Gets or sets the amount to rotate the label body. + /// + [DefaultValue(float.NaN), Category("Appearance")] + [Description("Indicates the amount to rotate the label body.")] + public float Rotation + { + get { return (_Rotation); } + + set + { + if (value != _Rotation) + { + _Rotation = value; + + OnPropertyChangedEx("Rotation", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowBaseValueLabels + + /// + /// Gets or sets whether Labels are shown for Base Values. + /// + [DefaultValue(Tbool.NotSet), Category("DataLabel")] + [Description("Indicates whether Labels are shown for Base Values.")] + public Tbool ShowBaseValueLabels + { + get { return (_ShowBaseValueLabels); } + + set + { + if (value != _ShowBaseValueLabels) + { + _ShowBaseValueLabels = value; + + OnPropertyChangedEx("ShowBaseValueLabels", Style.VisualChangeType.Render); + } + } + } + + #endregion + + #region TextFormat + + /// + /// Gets or sets the format specifier for the label text. + /// + [Category("Appearance")] + [Description("Indicates the format specifier for the label text.")] + public string TextFormat + { + get { return (_TextFormat); } + + set + { + if (value != _TextFormat) + { + _TextFormat = value; + + OnPropertyChangedEx("TextFormat", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_ConnectorColor == Color.Empty) && + (_ConnectorLength == -1) && + (_ConnectorPattern == LinePattern.NotSet) && + (_ConnectorThickness == -1) && + (_DrawConnector == Tbool.NotSet) && + (_MaximumSize == Size.Empty) && + (_MinimumSize == Size.Empty) && + (_Offset == Point.Empty) && + (_Rotation == float.NaN) && + (_ShowBaseValueLabels == Tbool.NotSet) && + (String.IsNullOrEmpty(_TextFormat)) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(SeriesLabelVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.ConnectorColor != Color.Empty) + _ConnectorColor = style.ConnectorColor; + + if (style.ConnectorLength != -1) + _ConnectorLength = style.ConnectorLength; + + if (style.ConnectorPattern != LinePattern.NotSet) + _ConnectorPattern = style.ConnectorPattern; + + if (style.ConnectorThickness != -1) + _ConnectorThickness = style.ConnectorThickness; + + if (style.DrawConnector != Tbool.NotSet) + _DrawConnector = style.DrawConnector; + + if (style.MaximumSize != Size.Empty) + _MaximumSize = style.MaximumSize; + + if (style.MinimumSize != Size.Empty) + _MinimumSize = style.MinimumSize; + + if (style.Offset != Point.Empty) + _Offset = style.Offset; + + if (style.Rotation == float.NaN) + _Rotation = style.Rotation; + + if (style.ShowBaseValueLabels == Tbool.NotSet) + _ShowBaseValueLabels = style.ShowBaseValueLabels; + + if (String.IsNullOrEmpty(style.TextFormat) == false) + _TextFormat = style.TextFormat; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new SeriesLabelVisualStyle Copy() + { + SeriesLabelVisualStyle style = new SeriesLabelVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(SeriesLabelVisualStyle style) + { + base.CopyTo(style); + + style.ConnectorColor = _ConnectorColor; + style.ConnectorLength = _ConnectorLength; + style.ConnectorPattern = _ConnectorPattern; + style.ConnectorThickness = _ConnectorThickness; + style.DrawConnector = _DrawConnector; + style.MaximumSize = _MaximumSize; + style.MinimumSize = _MinimumSize; + style.Offset = _Offset; + style.Rotation = _Rotation; + style.ShowBaseValueLabels = _ShowBaseValueLabels; + style.TextFormat = _TextFormat; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "SeriesLabelVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("ConnectorColor", ConnectorColor, Color.Empty); + sec.AddValue("ConnectorLength", ConnectorLength, -1); + sec.AddValue("ConnectorPattern", ConnectorPattern, LinePattern.NotSet); + sec.AddValue("ConnectorThickness", ConnectorThickness, -1); + sec.AddValue("DrawConnector", DrawConnector, Tbool.NotSet); + + sec.AddValue("MaximumSize", MaximumSize, Size.Empty); + sec.AddValue("MinimumSize", MinimumSize, Size.Empty); + + sec.AddValue("Offset", Offset, Point.Empty); + sec.AddValue("Rotation", Rotation, float.NaN); + + sec.AddValue("ShowBaseValueLabels", ShowBaseValueLabels, Tbool.NotSet); + sec.AddValue("TextFormat", TextFormat, null); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "ConnectorColor": + ConnectorColor = se.GetValueColor(); + break; + + case "ConnectorLength": + ConnectorLength = int.Parse(se.StringValue); + break; + + case "ConnectorPattern": + ConnectorPattern = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "ConnectorThickness": + ConnectorThickness = int.Parse(se.StringValue); + break; + + case "DrawConnector": + DrawConnector = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "MaximumSize": + MaximumSize = se.GetValueSize(); + break; + + case "MinimumSize": + MinimumSize = se.GetValueSize(); + break; + + case "Offset": + Offset = se.GetValuePoint(); + break; + + case "Rotation": + Rotation = float.Parse(se.StringValue); + break; + + case "ShowBaseValueLabels": + ShowBaseValueLabels = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "TextFormat": + TextFormat = se.StringValue; + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/SliceCenterLineVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/SliceCenterLineVisualStyle.cs new file mode 100644 index 00000000..6d7f3ef7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/SliceCenterLineVisualStyle.cs @@ -0,0 +1,226 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a Legend element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class SliceCenterLineVisualStyle : ChartLineVisualStyle + { + #region Private variables + + private int _InnerExtent; + private int _OuterExtent; + + #endregion + + #region Public properties + + #region InnerExtent + + /// + /// Gets or sets the distance (in pixels) to which the center line + /// is extended prior to the slice inner radius. + /// + [Description("Indicates the distance (in pixels) to which the center line is extended prior to the slice inner radius.")] + [DefaultValue(0)] + public int InnerExtent + { + get { return (_InnerExtent); } + + set + { + if (_InnerExtent != value) + { + _InnerExtent = value; + + OnPropertyChangedEx("InnerExtent", VisualChangeType.Render); + } + } + } + + #endregion + + #region OuterExtent + + /// + /// Gets or sets the distance (in pixels) to which the center line + /// is extended past to the slice Outer radius. + /// + [Description("Indicates the distance (in pixels) to which the center line is extended past the slice Outer radius.")] + [DefaultValue(0)] + public int OuterExtent + { + get { return (_OuterExtent); } + + set + { + if (_OuterExtent != value) + { + _OuterExtent = value; + + OnPropertyChangedEx("OuterExtent", VisualChangeType.Render); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_InnerExtent == 0) && + (_OuterExtent == 0) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to the instance of this style. + /// + /// Style to apply. + public void ApplyStyle(SliceCenterLineVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.InnerExtent != 0) + InnerExtent = style.InnerExtent; + + if (style.OuterExtent != 0) + OuterExtent = style.OuterExtent; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new SliceCenterLineVisualStyle Copy() + { + SliceCenterLineVisualStyle style = new SliceCenterLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(SliceCenterLineVisualStyle style) + { + base.CopyTo(style); + + style.InnerExtent = _InnerExtent; + style.OuterExtent = _OuterExtent; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "SliceCenterLineVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("InnerExtent", InnerExtent, 0); + sec.AddValue("OuterExtent", OuterExtent, 0); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "InnerExtent": + InnerExtent = int.Parse(se.StringValue); + break; + + case "OuterExtent": + OuterExtent = int.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/SliceLabelVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/SliceLabelVisualStyle.cs new file mode 100644 index 00000000..1dd6147a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/SliceLabelVisualStyle.cs @@ -0,0 +1,1954 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a series Slice. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class SliceLabelVisualStyle : BaseVisualStyle + { + #region Private variables + + private Tbool _AllowWrap = Tbool.NotSet; + private SliceLabelAlignment _Alignment = SliceLabelAlignment.NotSet; + + private Background _Background; + private Color _TextColor = Color.Empty; + private Font _Font; + + private int _MaxLineCount = -1; + + #endregion + + #region Public properties + + #region Alignment + + /// + /// Gets or sets the alignment of the label. + /// + [DefaultValue(SliceLabelAlignment.NotSet), Category("Layout")] + [Description("Indicates the alignment of the label.")] + public SliceLabelAlignment Alignment + { + get { return (_Alignment); } + + set + { + if (value != _Alignment) + { + _Alignment = value; + + OnPropertyChangedEx("Alignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (value != _AllowWrap) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font + /// + [DefaultValue(null)] + [Description("Indicates the style Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxLineCount + + /// + /// Gets or sets the maximum number of lines for label text. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the maximum number of lines for label text.")] + public int MaxLineCount + { + get { return (_MaxLineCount); } + + set + { + if (value != _MaxLineCount) + { + _MaxLineCount = value; + + OnPropertyChangedEx("MaxLineCount", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color. + /// + [Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + TextColor = Color.Empty; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Alignment == SliceLabelAlignment.NotSet) && + (_AllowWrap == Tbool.NotSet) && + (_Background == null || _Background.IsEmpty == true) && + (_Font == null) && + (_MaxLineCount < 0) && + (_TextColor.IsEmpty == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region GetStringFormatFlags + + internal void GetStringFormatFlags(StringFormat sf, bool flip) + { + if (_AllowWrap == Tbool.False || _MaxLineCount == 1) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + sf.Trimming = StringTrimming.EllipsisCharacter; + + switch (Alignment) + { + case SliceLabelAlignment.OuterLeft: + sf.LineAlignment = (flip ? StringAlignment.Far : StringAlignment.Near); + break; + + case SliceLabelAlignment.NotSet: + case SliceLabelAlignment.OuterCenter: + sf.LineAlignment = (flip ? StringAlignment.Far : StringAlignment.Near); + sf.Alignment = StringAlignment.Center; + break; + + case SliceLabelAlignment.OuterRight: + sf.LineAlignment = (flip ? StringAlignment.Far : StringAlignment.Near); + sf.Alignment = StringAlignment.Far; + break; + + case SliceLabelAlignment.MiddleLeft: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Near; + break; + + case SliceLabelAlignment.MiddleCenter: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Center; + break; + + case SliceLabelAlignment.MiddleRight: + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Far; + break; + + case SliceLabelAlignment.InnerLeft: + sf.LineAlignment = (flip ? StringAlignment.Near : StringAlignment.Far); + sf.Alignment = StringAlignment.Near; + break; + + case SliceLabelAlignment.InnerCenter: + sf.LineAlignment = (flip ? StringAlignment.Near : StringAlignment.Far); + sf.Alignment = StringAlignment.Center; + break; + + case SliceLabelAlignment.InnerRight: + sf.LineAlignment = (flip ? StringAlignment.Near : StringAlignment.Far); + sf.Alignment = StringAlignment.Far; + break; + } + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(SliceLabelVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.Alignment != SliceLabelAlignment.NotSet) + Alignment = style._Alignment; + + if (style.AllowWrap != Tbool.NotSet) + AllowWrap = style._AllowWrap; + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style.Font != null) + Font = style.Font; + + if (style.MaxLineCount >= 0) + MaxLineCount = style._MaxLineCount; + + if (style._TextColor.IsEmpty == false) + TextColor = style._TextColor; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (_Alignment == SliceLabelAlignment.NotSet) + _Alignment = SliceLabelAlignment.OuterCenter; + + if (_AllowWrap == Tbool.NotSet) + _AllowWrap = Tbool.True; + + if (_Font == null) + _Font = SystemFonts.DefaultFont; + + if (_TextColor.IsEmpty == true) + _TextColor = Color.Black; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new SliceLabelVisualStyle Copy() + { + SliceLabelVisualStyle style = new SliceLabelVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(SliceLabelVisualStyle style) + { + base.CopyTo(style); + + style.Alignment = _Alignment; + style.AllowWrap = _AllowWrap; + + style.Background = (_Background != null) ? _Background.Copy() : null; + style.Font = (_Font != null) ? (Font)_Font.Clone() : null; + + style.MaxLineCount = _MaxLineCount; + + style.TextColor = _TextColor; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "SliceLabelVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("Alignment", _Alignment, SliceLabelAlignment.NotSet); + sec.AddValue("AllowWrap", _AllowWrap, Tbool.NotSet); + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + if (_Font != null) + sec.AddValue("Font", XmlSerializableFont.ConvertToString(Font)); + + sec.AddValue("MaxLineCount", _MaxLineCount, 0); + sec.AddValue("TextColor", _TextColor, Color.Empty); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AllowWrap": + AllowWrap = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "Alignment": + Alignment = (SliceLabelAlignment)se.GetValueEnum(typeof(SliceLabelAlignment)); + break; + + case "Font": + Font = XmlSerializableFont.ConvertFromString(se.StringValue); + break; + + case "MaxLineCount": + MaxLineCount = int.Parse(se.StringValue); + break; + + case "TextColor": + TextColor = se.GetValueColor(); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "Background": + sec.PutSerialData(Background); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + + base.Dispose(); + } + + #endregion + } + + /// + /// Represents the visual style of a series Slice. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class SliceInnerLabelVisualStyle : SliceLabelVisualStyle + { + #region Private variables + + private Tbool _AutoRotate = Tbool.NotSet; + private Tbool _AutoOrientLabel = Tbool.NotSet; + + private double _AngleMargin = double.NaN; + private double _OuterRadiusOffset = double.NaN; + private double _InnerRadiusOffset = double.NaN; + + private double _CustomAngleOffset = double.NaN; + private double _CustomRadiusOffset = double.NaN; + private double _CustomFontAngle = double.NaN; + + private double _CustomWidth = double.NaN; + private double _CustomHeight = double.NaN; + + private OuterRadiusOffsetBase _OuterRadiusOffsetBase = OuterRadiusOffsetBase.NotSet; + + #endregion + + #region Public properties + + #region AngleMargin + + /// + /// Gets or sets the margin (in degrees) to inset the label from + /// both the start and ending slice angles. + /// + [DefaultValue(double.NaN), Category("Appearance")] + [Description("Indicates the margin (in degrees) to inset the label from both the start and ending slice angles.")] + [Editor("DevComponents.Charts.Design.AngleMarginRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double AngleMargin + { + get { return (_AngleMargin); } + + set + { + if (value != _AngleMargin) + { + _AngleMargin = value; + + OnPropertyChangedEx("AngleMargin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AutoOrientLabel + + /// + /// Gets or sets whether the label will be auto oriented away from being upside down. + /// + [DefaultValue(Tbool.NotSet), Category("Behavior")] + [Description("Indicates whether the label will be auto oriented away from being upside down.")] + public Tbool AutoOrientLabel + { + get { return (_AutoOrientLabel); } + + set + { + if (_AutoOrientLabel != value) + { + _AutoOrientLabel = value; + + OnPropertyChangedEx("AutoOrientLabel", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AutoRotate + + /// + /// Gets or sets whether the label is auto rotated to match + /// the angle of the slice (only valid for 'Custom' orientation mode). + /// + [DefaultValue(Tbool.NotSet), Category("Display")] + [Description("Indicates whether the label is auto rotated to match the angle of the slice (only valid for 'Custom' orientation mode).")] + public Tbool AutoRotate + { + get { return (_AutoRotate); } + + set + { + if (value != _AutoRotate) + { + _AutoRotate = value; + + OnPropertyChangedEx("AutoRotate", VisualChangeType.Render); + } + } + } + + #endregion + + #region CustomAngleOffset + + /// + /// Gets or sets the display angle offset for the label when + /// the label orientation is set to 'Custom'. The label can be + /// offset toward the end angle (positive offset) or toward + /// the start angle (negative offset). The offset is either a + /// percentage (if value is between 0 and 1) or pixel amount (if value > 1). + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the display angle offset for the label when the label orientation is set to 'Custom'. The label can be offset toward the end angle (positive offset) or toward the start angle (negative offset). The offset is either a percentage (if value is between 0 and 1) or pixel amount (if value > 1).")] + [Editor("DevComponents.Charts.Design.AngleOffsetRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double CustomAngleOffset + { + get { return (_CustomAngleOffset); } + + set + { + if (value != _CustomAngleOffset) + { + _CustomAngleOffset = value; + + OnPropertyChangedEx("CustomAngleOffset", VisualChangeType.Render); + } + } + } + + #endregion + + #region CustomFontAngle + + /// + /// Gets or sets the custom font angle when the label orientation + /// is set to 'Custom'. The FontAngle is the additional number of + /// degrees the label will be rotated. + /// + [DefaultValue(double.NaN), Category("Appearance")] + [Description("Indicates the custom font angle when the label orientation is set to 'Custom'. The FontAngle is the additional number of degrees the label will be rotated.")] + [Editor("DevComponents.Charts.Design.AngleRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double CustomFontAngle + { + get { return (_CustomFontAngle); } + + set + { + if (value != _CustomFontAngle) + { + _CustomFontAngle = value; + + OnPropertyChangedEx("CustomFontAngle", VisualChangeType.Layout); + } + } + } + + #endregion + + #region CustomHeight + + /// + /// Gets or sets the height of the bounding rectangle for the label when + /// the label orientation is set to 'Custom'. The height can be a percentage + /// of the slice height (if the value is between 0 and 1), or an absolute + /// pixel amount (if the value is > 1). + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the height of the bounding rectangle for the label when the label orientation is set to 'Custom'. The height can be a percentage of the slice height (if the value is between 0 and 1), or an absolute pixel amount (if the value is > 1).")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double CustomHeight + { + get { return (_CustomHeight); } + + set + { + if (value != _CustomHeight) + { + _CustomHeight = value; + + OnPropertyChangedEx("CustomHeight", VisualChangeType.Render); + } + } + } + + #endregion + + #region CustomRadiusOffset + + /// + /// Gets or sets the display radius offset for the label when the label orientation + /// is set to 'Custom. The label can be offset toward the outer radius + /// (positive offset) or toward the inner radius (negative offset). The + /// offset can either be a percentage (if value is between 0 and 1) or pixel + /// amount (if value > 1). + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the display radius offset for the label when the label orientation is set to 'Custom. The label can be offset toward the outer radius (positive offset) or toward the inner radius (negative offset). The offset can either be a percentage (if value is between 0 and 1) or pixel amount (if value > 1)..")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double CustomRadiusOffset + { + get { return (_CustomRadiusOffset); } + + set + { + if (value != _CustomRadiusOffset) + { + _CustomRadiusOffset = value; + + OnPropertyChangedEx("CustomRadiusOffset", VisualChangeType.Render); + } + } + } + + #endregion + + #region CustomWidth + + /// + /// Gets or sets the custom width for the bounding rectangle of the + /// label when the label orientation is set to 'Custom'. The width can + /// be a percentage of the slice width at the set RadiusOffset + /// (if the value is between 0 and 1), or an absolute pixel amount (if the + /// value is > 1). + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the custom width for the bounding rectangle of the label when the label orientation is set to 'Custom'. The width can be a percentage of the slice width at the set RadiusOffset (if the value is between 0 and 1), or an absolute pixel amount (if the value is > 1).")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double CustomWidth + { + get { return (_CustomWidth); } + + set + { + if (value != _CustomWidth) + { + _CustomWidth = value; + + OnPropertyChangedEx("CustomWidth", VisualChangeType.Render); + } + } + } + + #endregion + + #region InnerRadiusOffset + + /// + /// Gets or sets the offset of the inner edge of the rectangular label area from the + /// outer slice radius, as measured by a percentage of the slice radius + /// (if less than 1), or absolute pixel amount (if greater than 1). + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the offset of the inner edge of the rectangular label area from the outer slice radius, as measured by a percentage of the slice radius (if less than 1), or absolute pixel amount (if greater than 1).")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double InnerRadiusOffset + { + get { return (_InnerRadiusOffset); } + + set + { + if (value != _InnerRadiusOffset) + { + _InnerRadiusOffset = value; + + OnPropertyChangedEx("InnerRadiusOffset", VisualChangeType.Layout); + } + } + } + + #endregion + + #region OuterRadiusOffset + + /// + /// Gets or sets the offset of the outer edge of the rectangular label area from the + /// outer slice radius, as measured by a percentage of the slice radius + /// (if less than 1), or absolute pixel amount (if greater than 1). + /// + [DefaultValue(double.NaN), Category("Display")] + [Description("Indicates the offset of the outer edge of the rectangular label area from the outer slice radius, as measured by a percentage of the slice radius (if less than 1), or absolute pixel amount (if greater than 1).")] + [Editor("DevComponents.Charts.Design.RadiusRangeValueEditor, DevComponents.Charts.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public double OuterRadiusOffset + { + get { return (_OuterRadiusOffset); } + + set + { + if (value != _OuterRadiusOffset) + { + _OuterRadiusOffset = value; + + OnPropertyChangedEx("OuterRadiusOffset", VisualChangeType.Layout); + } + } + } + + #endregion + + #region OuterRadiusOffsetBase + + /// + /// Gets or sets whether the label's OuterRadiusOffset is relative + /// to the slice OuterRadius or the slice ExtentRadius. + /// + [Category("Behavior"), DefaultValue(OuterRadiusOffsetBase.NotSet)] + [Description("Indicates whether the label's OuterRadiusOffset is relative to the slice OuterRadius or the slice ExtentRadius.")] + public OuterRadiusOffsetBase OuterRadiusOffsetBase + { + get { return (_OuterRadiusOffsetBase); } + + set + { + if (_OuterRadiusOffsetBase != value) + { + _OuterRadiusOffsetBase = value; + + OnPropertyChangedEx("OuterRadiusOffsetBase", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((double.IsNaN(_AngleMargin) == true) && + (_AutoOrientLabel == Tbool.NotSet) && + (_AutoRotate == Tbool.NotSet) && + (double.IsNaN(_CustomAngleOffset) == true) && + (double.IsNaN(_CustomHeight) == true) && + (double.IsNaN(_CustomRadiusOffset) == true) && + (double.IsNaN(_CustomWidth) == true) && + (double.IsNaN(_CustomFontAngle) == true) && + (double.IsNaN(_InnerRadiusOffset) == true) && + (double.IsNaN(_OuterRadiusOffset) == true) && + (_OuterRadiusOffsetBase == OuterRadiusOffsetBase.NotSet) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(SliceInnerLabelVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (double.IsNaN(style._AngleMargin) == false) + AngleMargin = style._AngleMargin; + + if (style.AutoOrientLabel != Tbool.NotSet) + AutoOrientLabel = style._AutoOrientLabel; + + if (style._AutoRotate != Tbool.NotSet) + AutoRotate = style._AutoRotate; + + if (double.IsNaN(style._CustomAngleOffset) == false) + CustomAngleOffset = style._CustomAngleOffset; + + if (double.IsNaN(style._CustomHeight) == false) + CustomHeight = style._CustomHeight; + + if (double.IsNaN(style._CustomRadiusOffset) == false) + CustomRadiusOffset = style._CustomRadiusOffset; + + if (double.IsNaN(style._CustomWidth) == false) + CustomWidth = style._CustomWidth; + + if (double.IsNaN(style._CustomFontAngle) == false) + CustomFontAngle = style._CustomFontAngle; + + if (double.IsNaN(style._InnerRadiusOffset) == false) + InnerRadiusOffset = style._InnerRadiusOffset; + + if (double.IsNaN(style._OuterRadiusOffset) == false) + OuterRadiusOffset = style._OuterRadiusOffset; + + if (style.OuterRadiusOffsetBase != OuterRadiusOffsetBase.NotSet) + OuterRadiusOffsetBase = style._OuterRadiusOffsetBase; + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (_AutoRotate == Tbool.NotSet) + _AutoRotate = Tbool.False; + + if (double.IsNaN(_CustomFontAngle) == true) + _CustomFontAngle = 0; + + if (double.IsNaN(_AngleMargin) == true) + _AngleMargin = 1; + + if (_AutoOrientLabel == Tbool.NotSet) + _AutoOrientLabel = Tbool.True; + + if (double.IsNaN(_InnerRadiusOffset) == true) + _InnerRadiusOffset = .1; + + if (double.IsNaN(_OuterRadiusOffset) == true) + _OuterRadiusOffset = -.05; + + if (_OuterRadiusOffsetBase == OuterRadiusOffsetBase.NotSet) + _OuterRadiusOffsetBase = OuterRadiusOffsetBase.ExtentRadius; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new SliceInnerLabelVisualStyle Copy() + { + SliceInnerLabelVisualStyle style = new SliceInnerLabelVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(SliceInnerLabelVisualStyle style) + { + base.CopyTo(style); + + style.AngleMargin = _AngleMargin; + style.AutoOrientLabel = _AutoOrientLabel; + style.AutoRotate = _AutoRotate; + + style.CustomAngleOffset = _CustomAngleOffset; + style.CustomHeight = _CustomHeight; + style.CustomRadiusOffset = _CustomRadiusOffset; + style.CustomWidth = _CustomWidth; + + style.CustomFontAngle = _CustomFontAngle; + + style.InnerRadiusOffset = _InnerRadiusOffset; + style.OuterRadiusOffset = _OuterRadiusOffset; + style.OuterRadiusOffsetBase = _OuterRadiusOffsetBase; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "SliceInnerLabelVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AngleMargin", AngleMargin, double.NaN); + sec.AddValue("AutoOrientLabel", AutoOrientLabel, Tbool.NotSet); + sec.AddValue("AutoRotate", AutoRotate, Tbool.NotSet); + + sec.AddValue("CustomAngleOffset", CustomAngleOffset, double.NaN); + sec.AddValue("CustomHeight", CustomHeight, double.NaN); + sec.AddValue("CustomRadiusOffset", CustomRadiusOffset, double.NaN); + sec.AddValue("CustomWidth", CustomWidth, double.NaN); + + sec.AddValue("CustomFontAngle", CustomFontAngle, double.NaN); + + sec.AddValue("InnerRadiusOffset", InnerRadiusOffset, double.NaN); + sec.AddValue("OuterRadiusOffset", OuterRadiusOffset, double.NaN); + sec.AddValue("OuterRadiusOffsetBase", OuterRadiusOffsetBase, OuterRadiusOffsetBase.NotSet); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AngleMargin": + AngleMargin = double.Parse(se.StringValue); + break; + + case "AutoOrientLabel": + AutoOrientLabel = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "AutoRotate": + AutoRotate = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "CustomAngleOffset": + CustomAngleOffset = double.Parse(se.StringValue); + break; + + case "CustomFontAngle": + CustomFontAngle = double.Parse(se.StringValue); + break; + + case "CustomHeight": + CustomHeight = double.Parse(se.StringValue); + break; + + case "CustomRadiusOffset": + CustomRadiusOffset = double.Parse(se.StringValue); + break; + + case "CustomWidth": + CustomWidth = double.Parse(se.StringValue); + break; + + case "InnerRadiusOffset": + InnerRadiusOffset = double.Parse(se.StringValue); + break; + + case "OuterRadiusOffset": + OuterRadiusOffset = double.Parse(se.StringValue); + break; + + case "OuterRadiusOffsetBase": + OuterRadiusOffsetBase = (OuterRadiusOffsetBase)se.GetValueEnum(typeof(OuterRadiusOffsetBase)); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + base.Dispose(); + } + + #endregion + } + + /// + /// Represents the visual style of a series Slice. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class SliceOuterLabelVisualStyle : SliceLabelVisualStyle + { + #region Private variables + + private double _MaxLabelHeight = double.NaN; + private double _MaxLabelWidth = double.NaN; + private double _MinLabelHeight = double.NaN; + private double _MinLabelWidth = double.NaN; + + private int _LabelMargin = -1; + + private Tbool _DrawConnector = Tbool.NotSet; + + private Color _ConnectorColor = Color.Empty; + private LinePattern _ConnectorPattern = LinePattern.NotSet; + + private int _ConnectorLength = -1; + private int _ConnectorTickLength = -1; + private int _ConnectorThickness = -1; + + private ChartLineVisualStyle _Border; + private Padding _Padding; + + #endregion + + #region Public properties + + #region Border + + /// + /// Gets or sets the visual style for the label border. + /// + [Category("Style")] + [Description("Indicates the visual styles for the label border.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ChartLineVisualStyle Border + { + get + { + if (_Border == null) + { + _Border = new ChartLineVisualStyle(); + + UpdateChangeHandler(null, _Border); + } + + return (_Border); + } + + set + { + if (_Border != value) + { + ChartLineVisualStyle oldValue = _Border; + + _Border = value; + + OnStyleChanged("Border", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ConnectorColor + + /// + /// Gets or sets the style connector color. + /// + [Description("Indicates the style connector color"), Category("Appearance")] + public Color ConnectorColor + { + get { return (_ConnectorColor); } + + set + { + if (value != _ConnectorColor) + { + _ConnectorColor = value; + + OnPropertyChangedEx("ConnectorColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeConnectorColor() + { + return (_ConnectorColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetConnectorColor() + { + _ConnectorColor = Color.Empty; + } + + #endregion + + #region ConnectorLength + + /// + /// Gets or sets the length of the line connecting the slice + /// and the slice label. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the length of the line connecting the slice and the slice label.")] + public int ConnectorLength + { + get { return (_ConnectorLength); } + + set + { + if (value != _ConnectorLength) + { + if (value < 0) + throw new InvalidPropertyValueException("value cannot be negative."); + + _ConnectorLength = value; + + OnPropertyChangedEx("ConnectorLength", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ConnectorPattern + + /// + /// Gets or sets the style border pattern (Solid, Dash, ...) + /// + [Description("Indicates the style border pattern (Solid, Dash, ...)")] + [DefaultValue(LinePattern.NotSet), Category("Appearance")] + public LinePattern ConnectorPattern + { + get { return (_ConnectorPattern); } + + set + { + if (value != _ConnectorPattern) + { + _ConnectorPattern = value; + + OnPropertyChangedEx("ConnectorPattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region ConnectorThickness + + /// + /// Gets or sets the style connector thickness. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the style connector thickness.")] + public int ConnectorThickness + { + get { return (_ConnectorThickness); } + + set + { + if (value != _ConnectorThickness) + { + _ConnectorThickness = value; + + OnPropertyChangedEx("ConnectorThickness", VisualChangeType.Render); + } + } + } + + #endregion + + #region ConnectorTickLength + + /// + /// Gets or sets the length of the 'tick' line connecting the + /// label text with the main connector line associated with the pie slice. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the length of the length of the 'tick' line connecting the label text with the main connector line associated with the pie slice.")] + public int ConnectorTickLength + { + get { return (_ConnectorTickLength); } + + set + { + if (value != _ConnectorTickLength) + { + if (value < 0) + throw new InvalidPropertyValueException("value cannot be negative."); + + _ConnectorTickLength = value; + + OnPropertyChangedEx("ConnectorTickLength", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DrawConnector + + /// + /// Gets or sets whether a connecting line is drawn from the slice + /// to the outer slice label. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether a connecting line is drawn from the slice to the outer slice label.")] + public Tbool DrawConnector + { + get { return (_DrawConnector); } + + set + { + if (value != _DrawConnector) + { + _DrawConnector = value; + + OnPropertyChangedEx("DrawConnector", Style.VisualChangeType.Layout); + } + } + } + + #endregion + + #region LabelMargin + + /// + /// Gets or sets the pixel margin between the outer label + /// and the chart outer radius, as well as between the label and + /// any adjacent slice labels. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the pixel margin between the outer label and the chart outer radius, as well as between the label and any adjacent slice labels.")] + public int LabelMargin + { + get { return (_LabelMargin); } + + set + { + if (value != _LabelMargin) + { + _LabelMargin = value; + + OnPropertyChangedEx("LabelMargin", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxLabelHeight + + /// + /// Gets or sets the maximum vertical size of the label, as + /// measured by a percentage of the chart height (if less than 1), + /// or absolute pixel amount (if greater than 1). + /// + [DefaultValue(double.NaN), Category("Appearance")] + [Description("Indicates the maximum vertical size of the label, as measured by a percentage of the chart height (if less than 1), or absolute pixel amount (if greater than 1).")] + public double MaxLabelHeight + { + get { return (_MaxLabelHeight); } + + set + { + if (value != _MaxLabelHeight) + { + if (value < 0) + throw new ArgumentOutOfRangeException("value", "Must be greater than zero."); + + _MaxLabelHeight = value; + + OnPropertyChangedEx("MaxLabelHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxLabelWidth + + /// + /// Gets or sets the maximum horizontal size of the label, as + /// measured by a percentage of the chart width (if less than 1), + /// or absolute pixel amount (if greater than 1). + /// + [DefaultValue(double.NaN), Category("Appearance")] + [Description("Indicates the maximum horizontal size of the label, as measured by a percentage of the chart width (if less than 1), or absolute pixel amount (if greater than 1).")] + public double MaxLabelWidth + { + get { return (_MaxLabelWidth); } + + set + { + if (value != _MaxLabelWidth) + { + if (value < 0) + throw new ArgumentOutOfRangeException("value", "Must be greater than zero."); + + _MaxLabelWidth = value; + + OnPropertyChangedEx("MaxLabelWidth", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinLabelHeight + + /// + /// Gets or sets the Minimum vertical size of the label, as + /// measured by a percentage of the chart height (if less than 1), + /// or absolute pixel amount (if greater than 1). + /// + [DefaultValue(double.NaN), Category("Appearance")] + [Description("Indicates the Minimum vertical size of the label, as measured by a percentage of the chart height (if less than 1), or absolute pixel amount (if greater than 1).")] + public double MinLabelHeight + { + get { return (_MinLabelHeight); } + + set + { + if (value != _MinLabelHeight) + { + if (value < 0) + throw new ArgumentOutOfRangeException("value", "Must be greater than zero."); + + _MinLabelHeight = value; + + OnPropertyChangedEx("MinLabelHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinLabelWidth + + /// + /// Gets or sets the minimum horizontal size of the label, as + /// measured by a percentage of the chart width (if less than 1), + /// or absolute pixel amount (if greater than 1). + /// + [DefaultValue(double.NaN), Category("Appearance")] + [Description("Indicates the minimum horizontal size of the label, as measured by a percentage of the chart width (if less than 1), or absolute pixel amount (if greater than 1).")] + public double MinLabelWidth + { + get { return (_MinLabelWidth); } + + set + { + if (value != _MinLabelWidth) + { + if (value < 0) + throw new ArgumentOutOfRangeException("value", "Must be greater than zero."); + + _MinLabelWidth = value; + + OnPropertyChangedEx("MinLabelWidth", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Padding + + /// + /// Gets or sets spacing between the content and edges of the element. + /// + [Description("Indicates the spacing between the content and edges of the element")] + public Padding Padding + { + get + { + if (_Padding == null) + { + _Padding = Padding.Empty; + + UpdateChangeHandler(null, _Padding); + } + + return (_Padding); + } + + set + { + if (_Padding != value) + { + UpdateChangeHandler(_Padding, value); + + _Padding = value; + + OnPropertyChangedEx("Padding", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializePadding() + { + return (_Padding != null && _Padding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetPadding() + { + Padding = null; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Border == null || _Border.IsEmpty == true) && + (_ConnectorColor == Color.Empty) && + (_ConnectorLength == -1) && + (_ConnectorPattern == LinePattern.NotSet) && + (_ConnectorThickness == -1) && + (_ConnectorTickLength == -1) && + (_DrawConnector == Tbool.NotSet) && + (_LabelMargin == -1) && + (_Padding == null || _Padding.IsEmpty == true) && + (double.IsNaN(_MaxLabelHeight) == true) && + (double.IsNaN(_MaxLabelWidth) == true) && + (double.IsNaN(_MinLabelHeight) == true) && + (double.IsNaN(_MinLabelWidth) == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(SliceOuterLabelVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._Border != null && style._Border.IsEmpty == false) + Border = style._Border.Copy(); + + if (style.ConnectorColor != Color.Empty) + _ConnectorColor = style.ConnectorColor; + + if (style.ConnectorLength != -1) + _ConnectorLength = style.ConnectorLength; + + if (style.ConnectorPattern != LinePattern.NotSet) + _ConnectorPattern = style.ConnectorPattern; + + if (style.ConnectorThickness != -1) + _ConnectorThickness = style.ConnectorThickness; + + if (style.ConnectorTickLength != -1) + _ConnectorTickLength = style.ConnectorTickLength; + + if (style.DrawConnector != Tbool.NotSet) + _DrawConnector = style.DrawConnector; + + if (style.LabelMargin != -1) + _LabelMargin = style.LabelMargin; + + if (double.IsNaN(style._MaxLabelHeight) == false) + _MaxLabelHeight = style._MaxLabelHeight; + + if (double.IsNaN(style._MaxLabelWidth) == false) + _MaxLabelWidth = style._MaxLabelWidth; + + if (double.IsNaN(style._MinLabelHeight) == false) + _MinLabelHeight = style._MinLabelHeight; + + if (double.IsNaN(style._MinLabelWidth) == false) + _MinLabelWidth = style._MinLabelWidth; + + if (style._Padding != null && style._Padding.IsEmpty == false) + Padding = style._Padding.Copy(); + } + } + + #endregion + + #region ApplyDefaults + + public override void ApplyDefaults() + { + if (_ConnectorColor == Color.Empty) + _ConnectorColor = Color.Gray; + + if (_ConnectorLength == -1) + _ConnectorLength = 15; + + if (_ConnectorPattern == LinePattern.NotSet) + _ConnectorPattern = LinePattern.Solid; + + if (_ConnectorThickness == -1) + _ConnectorThickness = 1; + + if (_ConnectorTickLength == -1) + _ConnectorTickLength = 10; + + if (_DrawConnector == Tbool.NotSet) + _DrawConnector = Tbool.True; + + if (double.IsNaN(_MaxLabelHeight) == true) + _MaxLabelHeight = .25; + + if (double.IsNaN(_MaxLabelWidth) == true) + _MaxLabelWidth = .25; + + if (_LabelMargin == -1) + _LabelMargin = 10; + + base.ApplyDefaults(); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new SliceOuterLabelVisualStyle Copy() + { + SliceOuterLabelVisualStyle style = new SliceOuterLabelVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(SliceOuterLabelVisualStyle style) + { + base.CopyTo(style); + + style.Border = (_Border != null) ? _Border.Copy() : null; + + style.ConnectorColor = _ConnectorColor; + style.ConnectorLength = _ConnectorLength; + style.ConnectorPattern = _ConnectorPattern; + style.ConnectorThickness = _ConnectorThickness; + style.ConnectorTickLength = _ConnectorTickLength; + style.DrawConnector = _DrawConnector; + + style.LabelMargin = _LabelMargin; + style.Padding = (_Padding == null) ? null : _Padding.Copy(); + + style.MaxLabelHeight = _MaxLabelHeight; + style.MaxLabelWidth = _MaxLabelWidth; + style.MinLabelHeight = _MinLabelHeight; + style.MinLabelWidth = _MinLabelWidth; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "ChartSliceVisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_Border != null && _Border.IsEmpty == false) + sec.AddElement(_Border.GetSerialData("Border")); + + sec.AddValue("ConnectorColor", ConnectorColor, Color.Empty); + sec.AddValue("ConnectorLength", ConnectorLength, -1); + sec.AddValue("ConnectorPattern", ConnectorPattern, LinePattern.NotSet); + sec.AddValue("ConnectorThickness", ConnectorThickness, -1); + sec.AddValue("ConnectorTickLength", ConnectorTickLength, -1); + + sec.AddValue("DrawConnector", DrawConnector, Tbool.NotSet); + sec.AddValue("LabelMargin", LabelMargin, -1); + + if (_Padding != null && _Padding.IsEmpty == false) + sec.AddElement(_Padding.GetSerialData("Padding")); + + sec.AddValue("MaxLabelHeight", MaxLabelHeight, double.NaN); + sec.AddValue("MaxLabelWidth", MaxLabelWidth, double.NaN); + sec.AddValue("MinLabelHeight", MinLabelHeight, double.NaN); + sec.AddValue("MinLabelWidth", MinLabelWidth, double.NaN); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "ConnectorColor": + ConnectorColor = se.GetValueColor(); + break; + + case "ConnectorLength": + ConnectorLength = int.Parse(se.StringValue); + break; + + case "ConnectorPattern": + ConnectorPattern = (LinePattern)se.GetValueEnum(typeof(LinePattern)); + break; + + case "ConnectorThickness": + ConnectorThickness = int.Parse(se.StringValue); + break; + + case "ConnectorTickLength": + ConnectorTickLength = int.Parse(se.StringValue); + break; + + case "DrawConnector": + DrawConnector = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "MaxLabelHeight": + MaxLabelHeight = double.Parse(se.StringValue); + break; + + case "MaxLabelWidth": + MaxLabelWidth = double.Parse(se.StringValue); + break; + + case "MinLabelHeight": + MinLabelHeight = double.Parse(se.StringValue); + break; + + case "MinLabelWidth": + MinLabelWidth = double.Parse(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + SerialElementCollection sec = se.Sec; + + switch (se.Name) + { + case "Border": + sec.PutSerialData(Border); + break; + + case "Padding": + se.Sec.PutSerialData(Padding); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Border = null; + Padding = null; + + base.Dispose(); + } + + #endregion + } + + #region OuterRadiusOffsetBase + + /// + /// Defines what the label's OuterRadiusOffset is relative + /// to (slice OuterRadius or slice ExtentRadius). + /// + public enum OuterRadiusOffsetBase + { + /// + /// NotSet + /// + NotSet = -1, + + /// + /// OuterRadius + /// + OuterRadius, + + /// + /// ExtentRadius (default) + /// + ExtentRadius, + } + +#endregion + + #region SliceLabelAlignment + + /// + /// SliceLabelAlignment + /// + public enum SliceLabelAlignment + { + /// + /// NotSet + /// + NotSet = -1, + + /// + /// OuterLeft + /// + OuterLeft, + + /// + /// OuterCenter + /// + OuterCenter, + + /// + /// OuterRight + /// + OuterRight, + + /// + /// MiddleLeft + /// + MiddleLeft, + + /// + /// MiddleCenter + /// + MiddleCenter, + + /// + /// MiddleRight + /// + MiddleRight, + + /// + /// InnerLeft + /// + InnerLeft, + + /// + /// InnerCenter + /// + InnerCenter, + + /// + /// InnerRight + /// + InnerRight, + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/Thickness.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/Thickness.cs new file mode 100644 index 00000000..99d984ba --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/Thickness.cs @@ -0,0 +1,619 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Defines Thickness class. + /// + [TypeConverter(typeof(ThicknessTypeConverter))] + public class Thickness : IEquatable, IProcessSerialElement, INotifyPropertyChanged + { + #region Static data + + /// + /// Returns Empty instance of Thickness. + /// + public static Thickness Empty + { + get { return (new Thickness(0)); } + } + + #endregion + + #region Private variables + + private int _Bottom; + private int _Left; + private int _Right; + private int _Top; + + #endregion + + #region Constructors + + /// + /// Creates new instance of the object. + /// + /// Left thickness in pixels. + /// Top thickness in pixels. + /// Right thickness in pixels. + /// Bottom thickness in pixels. + public Thickness(int left, int top, int right, int bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + } + + /// + /// Creates new instance of the object. + /// + /// Specifies uniform Thickness. + public Thickness(int all) + : this(all, all, all, all) + { + } + + /// + /// Creates new instance of the object. + /// + public Thickness() + { + } + + #endregion + + #region Public properties + + #region All + + /// + /// Gets or sets the thickness of all sides + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int All + { + set { _Top = _Left = _Bottom = _Right = value; } + } + + #endregion + + #region Bottom + + /// + /// Gets or sets the Bottom thickness in pixels. + /// + [DefaultValue(0)] + [Description("Indicates the Bottom thickness in pixels.")] + public int Bottom + { + get { return (_Bottom); } + + set + { + if (_Bottom != value) + { + _Bottom = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Bottom")); + } + } + } + + #endregion + + #region Horizontal + + /// + /// Gets horizontal thickness (Left + Right) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Horizontal + { + get { return (_Left + _Right); } + } + + #endregion + + #region Left + + /// + /// Gets or sets the left thickness in pixels + /// + [DefaultValue(0)] + [Description("Indicates the left thickness in pixels")] + public int Left + { + get { return (_Left); } + + set + { + if (_Left != value) + { + _Left = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Left")); + } + } + } + + #endregion + + #region Right + + /// + /// Gets or sets the Right thickness in pixels + /// + [DefaultValue(0)] + [Description("Indicates the Right thickness in pixels")] + public int Right + { + get { return (_Right); } + + set + { + if (_Right != value) + { + _Right = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Right")); + } + } + } + + #endregion + + #region Top + + /// + /// Gets or sets the Top thickness in pixels + /// + [DefaultValue(0)] + [Description("Indicates the Top thickness in pixels")] + public int Top + { + get { return (_Top); } + + set + { + if (_Top != value) + { + _Top = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Top")); + } + } + } + + #endregion + + #region Vertical + + /// + /// Gets vertical thickness (Top + Bottom) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Vertical + { + get { return (_Top + _Bottom); } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the item is empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + return (_Left == 0 && _Right == 0 && + _Top == 0 && _Bottom == 0); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region IsUniform + + internal bool IsUniform + { + get + { + return (_Left == _Top && + _Left == _Right && _Left == _Bottom); + } + } + + #endregion + + #region IsZero + + internal bool IsZero + { + get + { + return (_Left == 0 && _Top == 0 && + _Right == 0 && _Bottom == 0); + } + } + + #endregion + + #region Size + + internal Size Size + { + get { return (new Size(_Left + _Right, _Top + _Bottom)); } + } + + #endregion + + #endregion + + #region Equals + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to. + /// true if equal otherwise false. + public override bool Equals(object obj) + { + if (obj is Thickness) + return (this == (Thickness)obj); + + return (false); + } + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to + /// true if equal otherwise false + public bool Equals(Thickness thickness) + { + return (this == thickness); + } + + #endregion + + #region GetHashCode + + /// + /// Returns hash-code. + /// + /// hash-code + public override int GetHashCode() + { + return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^ + _Right.GetHashCode()) ^ _Bottom.GetHashCode()); + } + + #endregion + + #region Operators + + #region "==" operator + + /// + /// Implements == operator. + /// + /// Object 1 + /// Object 2 + /// true if equals + public static bool operator ==(Thickness t1, Thickness t2) + { + if (ReferenceEquals(t1, t2)) + return (true); + + if (((object)t1 == null) || ((object)t2 == null)) + return (false); + + return (t1._Left == t2._Left && t1._Right == t2._Right && + t1._Top == t2._Top && t1._Bottom == t2._Bottom); + } + + #endregion + + #region "!=" operator + + /// + /// Implements != operator + /// + /// Object 1 + /// Object 2 + /// true if different + public static bool operator !=(Thickness t1, Thickness t2) + { + return ((t1 == t2) == false); + } + + #endregion + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the Thickness. + /// + /// Copy of the Thickness. + public Thickness Copy() + { + Thickness copy = new Thickness(_Left, _Top, _Right, _Bottom); + + return (copy); + } + + #endregion + + #region GetSerialData + + internal virtual SerialElementCollection GetSerialData(string name) + { + SerialElementCollection sec = new SerialElementCollection(); + + sec.AddStartElement(name); + + if (IsUniform == true) + { + sec.AddValue("All", Left, 0); + } + else + { + sec.AddValue("Left", Left, 0); + sec.AddValue("Top", Top, 0); + sec.AddValue("Right", Right, 0); + sec.AddValue("Bottom", Bottom, 0); + } + + sec.AddEndElement(name); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + ProcessValue(se); + } + + internal virtual void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "All": + All = int.Parse(se.StringValue); + break; + + case "Left": + Left = int.Parse(se.StringValue); + break; + + case "Top": + Top = int.Parse(se.StringValue); + break; + + case "Right": + Right = int.Parse(se.StringValue); + break; + + case "Bottom": + Bottom = int.Parse(se.StringValue); + break; + + default: + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + void OnPropertyChanged(VisualPropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + #endregion + } + + #region ThicknessTypeConverter + + /// + /// ThicknessTypeConverter + /// + public class ThicknessTypeConverter : ExpandableObjectConverter + { + #region CanConvertTo + + /// + /// CanConvertTo + /// + /// + /// + /// + public override bool CanConvertTo( + ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + return (true); + + return (base.CanConvertTo(context, destinationType)); + } + + #endregion + + #region ConvertTo + + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + Thickness t = value as Thickness; + + if (t != null) + { + if (t.IsUniform == true) + return (t.Left.ToString()); + + return (String.Format("{0:d}, {1:d}, {2:d}, {3:d}", + t.Bottom, t.Left, t.Right, t.Top)); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + + #endregion + + #region CanConvertFrom + + /// + /// CanConvertFrom + /// + /// + /// + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + return (true); + + return (base.CanConvertFrom(context, sourceType)); + } + + #endregion + + #region ConvertFrom + + /// + /// ConvertFrom + /// + /// + /// + /// + /// + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + string[] values = ((string)value).Split(','); + + if (values.Length != 1 && values.Length != 4) + throw new ArgumentException("Invalid value to convert."); + + try + { + int[] v = new int[values.Length]; + + for (int i = 0; i < values.Length; i++) + v[i] = int.Parse(values[i]); + + Thickness t = (values.Length == 1) + ? new Thickness(v[0]) + : new Thickness(v[1], v[3], v[2], v[0]); + + return (t); + } + catch (Exception) + { + throw new ArgumentException("Invalid value to convert."); + } + } + + return base.ConvertFrom(context, culture, value); + } + + #endregion + + #region GetCreateInstanceSupported + + /// + /// GetCreateInstanceSupported + /// + /// + /// + public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region CreateInstance + + /// + /// CreateInstance + /// + /// + /// + /// + public override object CreateInstance( + ITypeDescriptorContext context, IDictionary propertyValues) + { + return (new Thickness((int)propertyValues["Left"], (int)propertyValues["Top"], + (int)propertyValues["Right"], (int)propertyValues["Bottom"])); + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/TickmarkLableVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/TickmarkLableVisualStyle.cs new file mode 100644 index 00000000..764d3156 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/TickmarkLableVisualStyle.cs @@ -0,0 +1,444 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a Tickmark Label element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class TickmarkLabelVisualStyle : BaseVisualStyle + { + #region Private variables + + private Font _Font; + + private Tbool _AllowWrap = Tbool.NotSet; + + private Color _TextColor = Color.Empty; + private Alignment _TextAlignment = Alignment.NotSet; + private string _TextFormat; + + private int _MaxLineCount = -1; + private int _MaxWidth = -1; + + #endregion + + #region Public properties + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font + /// + [DefaultValue(null)] + [Description("Indicates the style Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxLineCount + + /// + /// Gets or sets the maximum number of Label Text lines. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the maximum number of Label Text lines.")] + public int MaxLineCount + { + get { return (_MaxLineCount); } + + set + { + if (value != _MaxLineCount) + { + _MaxLineCount = value; + + OnPropertyChangedEx("MaxLineCount", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MaxWidth + + /// + /// Gets or sets the maximum width of the lable. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the maximum width of the lable.")] + public int MaxWidth + { + get { return (_MaxWidth); } + + set + { + if (value != _MaxWidth) + { + _MaxWidth = value; + + OnPropertyChangedEx("MaxWidth", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TextAlignment + + /// + /// Gets or sets the alignment of the axis Text + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the axis Text.")] + public Alignment TextAlignment + { + get { return (_TextAlignment); } + + set + { + if (_TextAlignment != value) + { + _TextAlignment = value; + + OnPropertyChangedEx("TextAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color + /// + [Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + TextColor = Color.Empty; + } + + #endregion + + #region TextFormat + + /// + /// Gets or sets the Text Format specifier + /// + [DefaultValue(null)] + [Description("Indicates the Text Format specifier")] + public string TextFormat + { + get { return (_TextFormat); } + + set + { + if (_TextFormat != value) + { + _TextFormat = value; + + OnPropertyChangedEx("TextFormat", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_AllowWrap == Tbool.NotSet) && + (_Font == null) && + (_MaxLineCount < 0) && + (_MaxWidth < 0) && + (_TextAlignment == Alignment.NotSet) && + (_TextColor.IsEmpty == true) && + (string.IsNullOrEmpty(_TextFormat) == true) && + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region GetTextFormatFlags + + internal eTextFormat GetTextFormatFlags() + { + eTextFormat tf = eTextFormat.WordEllipsis | + eTextFormat.NoPadding | eTextFormat.NoPrefix; + + if (AllowWrap == Tbool.True) + tf |= eTextFormat.WordBreak; + + tf |= eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter; + + return (tf); + } + + #endregion + + #region GetStringFormatFlags + + internal void GetStringFormatFlags(StringFormat sf) + { + if (AllowWrap == Tbool.False) + sf.FormatFlags |= StringFormatFlags.NoWrap; + + sf.LineAlignment = StringAlignment.Center; + sf.Alignment = StringAlignment.Center; + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(TickmarkLabelVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.AllowWrap != Tbool.NotSet) + AllowWrap = style.AllowWrap; + + if (style.Font != null) + Font = style.Font; + + if (style.MaxLineCount > 0) + MaxLineCount = style.MaxLineCount; + + if (style.MaxWidth > 0) + MaxWidth = style.MaxWidth; + + if (style.TextAlignment != Alignment.NotSet) + TextAlignment = style.TextAlignment; + + if (style.TextColor.IsEmpty == false) + TextColor = style.TextColor; + + if (string.IsNullOrEmpty(style.TextFormat) == false) + TextFormat = style.TextFormat; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new TickmarkLabelVisualStyle Copy() + { + TickmarkLabelVisualStyle style = new TickmarkLabelVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(TickmarkLabelVisualStyle style) + { + base.CopyTo(style); + + style.AllowWrap = _AllowWrap; + + style.Font = (_Font != null) ? (Font)_Font.Clone() : null; + + style.MaxLineCount = _MaxLineCount; + style.MaxWidth = _MaxWidth; + + style.TextAlignment = _TextAlignment; + style.TextColor = _TextColor; + style.TextFormat = _TextFormat; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "TickmarkLabelVisualStyle"; + + sec.AddStartElement(serialName); + } + + sec.AddValue("AllowWrap", AllowWrap, Tbool.NotSet); + + if (_Font != null) + sec.AddValue("Font", XmlSerializableFont.ConvertToString(Font)); + + sec.AddValue("MaxLineCount", MaxLineCount, -1); + sec.AddValue("MaxWidth", MaxWidth, -1); + + sec.AddValue("TextAlignment", TextAlignment, Alignment.NotSet); + sec.AddValue("TextColor", TextColor, Color.Empty); + sec.AddValue("TextFormat", TextFormat, null); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "AllowWrap": + AllowWrap = (Tbool)se.GetValueEnum(typeof(Tbool)); + break; + + case "Font": + Font = XmlSerializableFont.ConvertFromString(se.StringValue); + break; + + case "MaxLineCount": + MaxLineCount = int.Parse(se.StringValue); + break; + + case "MaxWidth": + MaxWidth = int.Parse(se.StringValue); + break; + + case "TextAlignment": + TextAlignment = (Alignment)se.GetValueEnum(typeof(Alignment)); + break; + + case "TextColor": + TextColor = se.GetValueColor(); + break; + + case "TextFormat": + TextFormat = se.StringValue; + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/TrendLineVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/TrendLineVisualStyle.cs new file mode 100644 index 00000000..b413a813 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/TrendLineVisualStyle.cs @@ -0,0 +1,42 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style of a TrendLine Indicator element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class TrendLineVisualStyle : ChartCapLineVisualStyle + { + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new TrendLineVisualStyle Copy() + { + TrendLineVisualStyle style = new TrendLineVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(TrendLineVisualStyle style) + { + base.CopyTo(style); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/VisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/VisualStyle.cs new file mode 100644 index 00000000..97207aa1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/VisualStyle.cs @@ -0,0 +1,986 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents the visual style. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(ExpandableObjectConverter))] + public class VisualStyle : BaseVisualStyle + { + #region Private variables + + private Background _Background; + private BorderColor _BorderColor; + private BorderPattern _BorderPattern; + private Thickness _BorderThickness; + + private Color _TextColor = Color.Empty; + + private Padding _Margin; + private Padding _Padding; + + private Font _Font; + + #endregion + + #region Public properties + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region BorderColor + + /// + /// Gets or sets the style border color. + /// + [Description("Indicates the style Border Color")] + public BorderColor BorderColor + { + get + { + if (_BorderColor == null) + { + _BorderColor = BorderColor.Empty; + + UpdateChangeHandler(null, _BorderColor); + } + + return (_BorderColor); + } + + set + { + if (_BorderColor != value) + { + UpdateChangeHandler(_BorderColor, value); + + _BorderColor = value; + + OnPropertyChangedEx("BorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderColor() + { + return (_BorderColor != null && _BorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderColor() + { + BorderColor = null; + } + + #endregion + + #region BorderPattern + + /// + /// Gets or sets the style border pattern (Solid, Dash, ...) + /// + [Description("Indicates the style border pattern (Solid, Dash, ...)")] + public BorderPattern BorderPattern + { + get + { + if (_BorderPattern == null) + { + _BorderPattern = BorderPattern.Empty; + + UpdateChangeHandler(null, _BorderPattern); + } + + return (_BorderPattern); + } + + set + { + if (_BorderPattern != value) + { + UpdateChangeHandler(_BorderPattern, value); + + _BorderPattern = value; + + OnPropertyChangedEx("BorderPattern", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderPattern() + { + return (_BorderPattern != null && _BorderPattern.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderPattern() + { + BorderPattern = null; + } + + #endregion + + #region BorderThickness + + /// + /// Gets or sets the style border thickness. + /// + [Description("Indicates the style border thickness")] + public Thickness BorderThickness + { + get + { + if (_BorderThickness == null) + { + _BorderThickness = Thickness.Empty; + + UpdateChangeHandler(null, _BorderThickness); + } + + return (_BorderThickness); + } + + set + { + if (_BorderThickness != value) + { + UpdateChangeHandler(_BorderThickness, value); + + _BorderThickness = value; + + OnPropertyChangedEx("BorderThickness", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderThickness() + { + return (_BorderThickness != null && _BorderThickness.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderThickness() + { + BorderThickness = null; + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font + /// + [DefaultValue(null)] + [Description("Indicates the style Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Margin + + /// + /// Gets or sets the spacing between the border and outside content. + /// + [Description("Indicates the spacing between the border and outside content")] + public Padding Margin + { + get + { + if (_Margin == null) + { + _Margin = Padding.Empty; + + UpdateChangeHandler(null, _Margin); + } + + return (_Margin); + } + + set + { + if (_Margin != value) + { + UpdateChangeHandler(_Margin, value); + + _Margin = value; + + OnPropertyChangedEx("Margin", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeMargin() + { + return (_Margin != null && _Margin.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetMargin() + { + Margin = null; + } + + #endregion + + #region Padding + + /// + /// Gets or sets spacing between the content and edges of the element. + /// + [Description("Indicates the spacing between the content and edges of the element")] + public Padding Padding + { + get + { + if (_Padding == null) + { + _Padding = Padding.Empty; + + UpdateChangeHandler(null, _Padding); + } + + return (_Padding); + } + + set + { + if (_Padding != value) + { + UpdateChangeHandler(_Padding, value); + + _Padding = value; + + OnPropertyChangedEx("Padding", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializePadding() + { + return (_Padding != null && _Padding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetPadding() + { + Padding = null; + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color + /// + [Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + TextColor = Color.Empty; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Background == null || _Background.IsEmpty == true) && + (_BorderColor == null || _BorderColor.IsEmpty == true) && + (_BorderPattern == null || _BorderPattern.IsEmpty == true) && + (_BorderThickness == null || _BorderThickness.IsEmpty == true) && + (_Margin == null || _Margin.IsEmpty == true) && + (_Padding == null || _Padding.IsEmpty == true) && + (_Font == null) && + (_TextColor.IsEmpty == true) && + (base.IsEmpty == true)); } + } + + #endregion + + #endregion + + #region RenderBackground + + internal void RenderBackground(Graphics g, Rectangle bounds) + { + if (bounds.Width > 1 && bounds.Height > 1) + { + using (Brush br = Background.GetBrush(bounds)) + { + if (br != null) + g.FillRectangle(br, bounds); + } + } + } + + #endregion + + #region RenderBorder + + internal void RenderBorder(Graphics g, Rectangle r) + { + RenderBorderEx(g, r, BorderPattern, BorderThickness, BorderColor); + } + + internal void RenderBorderEx(Graphics g, Rectangle r, + BorderPattern borderPattern, Thickness borderThickness, BorderColor borderColor) + { + if (r.Width > 2 && r.Height > 2) + { + if (borderPattern == null || borderThickness == null || borderColor == null) + return; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (borderColor.IsUniform == true && + borderThickness.IsUniform == true && borderPattern.IsUniform == true) + { + RenderUniformBorder(g, r, borderPattern, borderThickness, borderColor); + } + else + { + RenderVariableBorder(g, r, borderPattern, borderThickness, borderColor); + } + + g.SmoothingMode = sm; + } + } + + #region RenderUniformBorder + + private void RenderUniformBorder(Graphics g, Rectangle r, + BorderPattern borderPattern, Thickness borderThickness, BorderColor borderColor) + { + if (borderPattern.Top != LinePattern.None && + (borderThickness.Top > 0 && borderColor.Top.IsEmpty == false)) + { + using (Pen pen = new + Pen(borderColor.Top, Dpi.Width(borderThickness.Top))) + { + LinePattern pattern = (borderPattern.Top == LinePattern.NotSet) + ? LinePattern.Solid : borderPattern.Top; + + if (borderThickness.Top > 1) + { + pen.Alignment = PenAlignment.Inset; + } + else + { + r.Width--; + r.Height--; + } + + pen.DashStyle = (DashStyle)pattern; + + g.DrawRectangle(pen, r); + } + } + } + + #endregion + + #region RenderVariableBorder + + private void RenderVariableBorder(Graphics g, Rectangle r, + BorderPattern borderPattern, Thickness borderThickness, BorderColor borderColor) + { + Pen[] pens = GetBorderPens(borderPattern, borderThickness, borderColor); + + if (pens[(int)BorderSide.Left] != null) + { + int n = (int)Math.Floor((double)borderThickness.Left / 2); + int left = r.Left + n; + + g.DrawLine(pens[(int)BorderSide.Left], left, r.Top, left, r.Bottom - 1); + } + + if (pens[(int)BorderSide.Right] != null) + { + int n = (int)Math.Ceiling((double)borderThickness.Right / 2); + int right = r.Right - n; + + g.DrawLine(pens[(int)BorderSide.Right], right, r.Top, right, r.Bottom); + } + + if (pens[(int)BorderSide.Top] != null) + { + int n = (int)Math.Floor((double)borderThickness.Top / 2); + int top = r.Top + n; + + g.DrawLine(pens[(int)BorderSide.Top], r.X, top, r.Right - 1, top); + } + + if (pens[(int)BorderSide.Bottom] != null) + { + int n = (int)Math.Ceiling((double)borderThickness.Bottom / 2); + int bottom = r.Bottom - n; + + g.DrawLine(pens[(int)BorderSide.Bottom], r.X, bottom, r.Right, bottom); + } + + foreach (Pen pen in pens) + { + if (pen != null) + pen.Dispose(); + } + } + + #region GetBorderPens + + internal Pen[] GetBorderPens( + BorderPattern borderPattern, Thickness borderThickness, BorderColor borderColor) + { + Pen[] pens = new Pen[4]; + + pens[(int)BorderSide.Top] = GetBorderPen(pens, + borderColor.Top, borderThickness.Top, borderPattern.Top); + + pens[(int)BorderSide.Left] = GetBorderPen(pens, + borderColor.Left, borderThickness.Left, borderPattern.Left); + + pens[(int)BorderSide.Bottom] = GetBorderPen(pens, + borderColor.Bottom, borderThickness.Bottom, borderPattern.Bottom); + + pens[(int)BorderSide.Right] = GetBorderPen(pens, + borderColor.Right, borderThickness.Right, borderPattern.Right); + + return (pens); + } + + #region GetBorderPen + + private Pen GetBorderPen(IEnumerable pens, + Color color, int width, LinePattern pattern) + { + if (color.IsEmpty == true || + pattern == LinePattern.None || width <= 0) + { + return (null); + } + + width = Dpi.Width(width); + + foreach (Pen pen in pens) + { + if (pen != null) + { + if (pen.Color == color && pen.Width == width && + pen.DashStyle == (DashStyle)pattern) + { + return (pen); + } + } + } + + Pen npen = new Pen(color, width); + + if (pattern == LinePattern.NotSet) + pattern = LinePattern.Solid; + + npen.DashStyle = (DashStyle)pattern; + + return (npen); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetBorderSize + + internal Size GetBorderSize(bool inclPadding) + { + Size size = Size.Empty; + + size.Width += (BorderThickness.Horizontal + Margin.Horizontal); + size.Height += (BorderThickness.Vertical + Margin.Vertical); + + if (inclPadding == true) + { + size.Width += Padding.Horizontal; + size.Height += Padding.Vertical; + } + + return (size); + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(VisualStyle style) + { + base.ApplyStyle(style); + + if (style != null) + { + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style._BorderColor != null && style._BorderColor.IsEmpty == false) + BorderColor = style._BorderColor.Copy(); + + if (style._BorderPattern != null && style._BorderPattern.IsEmpty == false) + BorderPattern.ApplyPattern(style._BorderPattern); + + if (style._BorderThickness != null && style._BorderThickness.IsZero == false) + BorderThickness = style._BorderThickness.Copy(); + + if (style.Font != null) + Font = style.Font; + + if (style._Margin != null && style._Margin.IsEmpty == false) + Margin = style.Margin.Copy(); + + if (style._Padding != null && style._Padding.IsEmpty == false) + Padding = style.Padding.Copy(); + + if (style._TextColor.IsEmpty == false) + TextColor = style._TextColor; + } + } + + #endregion + + #region ApplyDefaults + + private Background _DefaultBackground = new Background(Color.Transparent); + + public override void ApplyDefaults() + { + base.ApplyDefaults(); + + if (_TextColor.IsEmpty == true) + TextColor = Color.Black; + + if (Font == null) + Font = SystemFonts.DefaultFont; + + if (Background == null) + Background = _DefaultBackground; + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new VisualStyle Copy() + { + VisualStyle style = new VisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(VisualStyle style) + { + base.CopyTo(style); + + style.Background = (_Background == null) ? null : _Background.Copy(); + style.BorderColor = (_BorderColor == null) ? null : _BorderColor.Copy(); + style.BorderPattern = (_BorderPattern == null) ? null : _BorderPattern.Copy(); + style.BorderThickness = (_BorderThickness == null) ? null : _BorderThickness.Copy(); + style.Font = (_Font == null) ? null : (Font)_Font.Clone(); + style.Margin = (_Margin == null) ? null : _Margin.Copy(); + style.Padding = (_Padding == null) ? null : _Padding.Copy(); + style.TextColor = _TextColor; + } + + #endregion + + #region GetSerialData + + internal override SerialElementCollection GetSerialData(string serialName) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + serialName = "VisualStyle"; + + sec.AddStartElement(serialName); + } + + if (_Background != null && _Background.IsEmpty == false) + sec.AddElement(_Background.GetSerialData("Background")); + + if (_BorderColor != null && _BorderColor.IsEmpty == false) + sec.AddElement(_BorderColor.GetSerialData("BorderColor")); + + if (_BorderPattern != null && _BorderPattern.IsEmpty == false) + sec.AddElement(_BorderPattern.GetSerialData("BorderPattern")); + + if (_BorderThickness != null && _BorderThickness.IsEmpty == false) + sec.AddElement(_BorderThickness.GetSerialData("BorderThickness")); + + if (_Font != null) + sec.AddValue("Font", XmlSerializableFont.ConvertToString(_Font)); + + if (_Margin != null && _Margin.IsEmpty == false) + sec.AddElement(_Margin.GetSerialData("Margin")); + + if (_Padding != null && _Padding.IsEmpty == false) + sec.AddElement(_Padding.GetSerialData("Padding")); + + sec.AddValue("TextColor", TextColor, Color.Empty); + + sec.AddElement(base.GetSerialData(null)); + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + internal override void ProcessValue(SerialElement se) + { + switch (se.Name) + { + case "TextColor": + TextColor = se.GetValueColor(); + break; + + case "Font": + Font = XmlSerializableFont.ConvertFromString(se.StringValue); + break; + + default: + base.ProcessValue(se); + break; + } + } + + #endregion + + #region ProcessCollection + + internal override void ProcessCollection(SerialElement se) + { + switch (se.Name) + { + case "Background": + se.Sec.PutSerialData(Background); + break; + + case "BorderColor": + se.Sec.PutSerialData(BorderColor); + break; + + case "BorderPattern": + se.Sec.PutSerialData(BorderPattern); + break; + + case "BorderThickness": + se.Sec.PutSerialData(BorderThickness); + break; + + case "Margin": + se.Sec.PutSerialData(Margin); + break; + + case "Padding": + se.Sec.PutSerialData(Padding); + break; + + default: + base.ProcessCollection(se); + break; + } + } + + #endregion + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + BorderColor = null; + BorderPattern = null; + BorderThickness = null; + Margin = null; + Padding = null; + + base.Dispose(); + } + + #endregion + } + + #region Alignment + + /// + /// Alignment of the content + /// + public enum Alignment + { + /// + /// + NotSet = -1, + + /// + /// TopLeft + /// + TopLeft, + + /// + /// TopCenter + /// + TopCenter, + + /// + /// TopRight + /// + TopRight, + + /// + /// MiddleLeft + /// + MiddleLeft, + + /// + /// MiddleCenter + /// + MiddleCenter, + + /// + /// MiddleRight + /// + MiddleRight, + + /// + /// BottomLeft + /// + BottomLeft, + + /// + /// BottomCenter + /// + BottomCenter, + + /// + /// BottomRight + /// + BottomRight, + } + + #endregion + + #region LineAlignment + + /// + /// LineAlignment of the content + /// + public enum LineAlignment + { + /// + /// Not Set + /// + NotSet = -1, + + /// + /// Near + /// + Near, + + /// + /// Center + /// + Center, + + /// + /// Far + /// + Far, + } + + #endregion + + #region BorderSide + + internal enum BorderSide + { + Top, + Left, + Bottom, + Right + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/VisualStyles.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/VisualStyles.cs new file mode 100644 index 00000000..aec72703 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/Style/VisualStyles.cs @@ -0,0 +1,429 @@ +using System; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// VisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class VisualStyles : IDisposable, INotifyPropertyChanged, IProcessSerialElement + where T : BaseVisualStyle, new() + { + #region Private variables + + private T[] _Styles; + + #endregion + + /// + /// Constructor + /// + public VisualStyles() + { + _Styles = new T[Enum.GetValues(typeof(StyleType)).Length - 1]; + } + + #region Public properties + + #region Indexer + + /// + /// Gets or sets the visual style + /// assigned to the element. Default value is null. + /// + [DefaultValue(null), Category("Style")] + [Description("Indicates visual style assigned to the element")] + public T this[StyleType e] + { + get + { + int n = StyleIndex(e); + + return (GetStyle(n)); + } + + set + { + int n = StyleIndex(e); + + SetStyle(n, value); + } + } + + #endregion + + #region Default + + /// + /// The normal, default style + /// + [Description("Style to use for normal, default items")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T Default + { + get { return (GetStyle((int) StyleType.Default)); } + set { SetStyle((int) StyleType.Default, value); } + } + + #endregion + + #region MouseOver + + /// + /// MouseOver + /// + [Description("Style to use when the Mouse is over an item")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T MouseOver + { + get { return (GetStyle((int)StyleType.MouseOver)); } + set { SetStyle((int)StyleType.MouseOver, value); } + } + + #endregion + + #region Selected + + /// + /// Selected + /// + [Description("Style to use when the item is selected")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T Selected + { + get { return (GetStyle((int)StyleType.Selected)); } + set { SetStyle((int)StyleType.Selected, value); } + } + + #endregion + + #region SelectedMouseOver + + /// + /// MouseOver + /// + [Description("Style to use when the item is selected and the Mouse is over it")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T SelectedMouseOver + { + get { return (GetStyle((int)StyleType.SelectedMouseOver)); } + set { SetStyle((int)StyleType.SelectedMouseOver, value); } + } + + #endregion + + #region Styles + + /// + /// Styles array + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public T[] Styles + { + get { return (_Styles); } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style collection is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style collection is logically Empty.")] + public bool IsEmpty + { + get + { + for (int i = 0; i < Styles.Length; i++) + { + T vstyle = Styles[i]; + + if (vstyle != null && vstyle.IsEmpty == false) + return (false); + } + + return (true); + } + } + + #endregion + + #endregion + + #region Count + + internal int Count + { + get { return (_Styles.Length); } + } + + #endregion + + #region GetStyle + + internal T GetStyle(int n) + { + if (_Styles[n] == null) + { + _Styles[n] = new T(); + + OnStyleChangeHandler(null, _Styles[n]); + } + + return (_Styles[n]); + } + + #endregion + + #region SetStyle + + internal void SetStyle(int n, T value) + { + if (_Styles[n] != value) + { + T oldValue = _Styles[n]; + + _Styles[n] = value; + + OnStyleChanged(Enum.GetName(typeof(StyleType), n), oldValue, value); + } + } + + #endregion + + #region GetSerialData + + internal SerialElementCollection GetSerialData(string serialName) + { + if (IsEmpty == false) + { + SerialElementCollection sec = new SerialElementCollection(); + + if (serialName != null) + { + if (serialName.Equals("") == true) + { + serialName = this.ToString(); + + serialName = serialName.Substring(serialName.LastIndexOf('.') + 1); + } + + sec.AddStartElement(serialName); + } + + string[] enums = Enum.GetNames(typeof(StyleType)); + + for (int i = 0; i < Styles.Length; i++) + { + T vstyle = Styles[i]; + + if (vstyle != null && vstyle.IsEmpty == false) + { + sec.AddStartElement(enums[i]); + sec.AddElement(vstyle.GetSerialData(null)); + sec.AddEndElement(enums[i]); + } + } + + if (serialName != null) + sec.AddEndElement(serialName); + + return (sec); + } + + return (null); + } + + #endregion + + #region PutSerialData + + #region ProcessValue + + void IProcessSerialElement.ProcessValue(SerialElement se) + { + throw new Exception("Unknown Serial Value (" + se.Name + ")"); + } + + #endregion + + #region ProcessCollection + + void IProcessSerialElement.ProcessCollection(SerialElement se) + { + switch (se.Name) + { + case "Default": + se.Sec.PutSerialData(Default); + break; + + case "MouseOver": + se.Sec.PutSerialData(MouseOver); + break; + + case "Selected": + se.Sec.PutSerialData(Selected); + break; + + case "SelectedMouseOver": + se.Sec.PutSerialData(SelectedMouseOver); + break; + + default: + throw new Exception("Unknown Serial Collection (" + se.Name + ")"); + } + } + + #endregion + + #endregion + + #region OnStyleChanged + + private void OnStyleChanged( + string property, T oldValue, T newValue) + { + OnStyleChangeHandler(oldValue, newValue); + + OnPropertyChanged(new VisualPropertyChangedEventArgs(property)); + } + + #endregion + + #region StyleIndex + + internal int StyleIndex(Enum e) + { + int n = ((IConvertible)e).ToInt32(null); + + if (n < 0 || n > _Styles.Length) + throw new Exception("Invalid Style indexer"); + + return (n); + } + + #endregion + + #region IsValid + + internal T Style(Enum e) + { + int n = ((IConvertible) e).ToInt32(null); + + if (n < 0 || n > _Styles.Length) + throw new Exception("Invalid Style indexer"); + + return (_Styles[n]); + } + + #endregion + + #region GetStyleType + + internal StyleType GetStyleType(StyleState state) + { + switch (state) + { + case StyleState.MouseOver: + return (StyleType.MouseOver); + + case StyleState.Selected: + return (StyleType.Selected); + + case StyleState.Selected | StyleState.MouseOver: + return (StyleType.SelectedMouseOver); + + default: + return (StyleType.Default); + } + } + + #endregion + + #region Style support routines + + #region StyleVisualChangeHandler + + private void OnStyleChangeHandler(T oldValue, T newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + for (int i = 0; i < _Styles.Length; i++) + { + T style = _Styles[i]; + + if (style != null) + { + SetStyle(i, null); + + style.Dispose(); + } + } + + _Styles = null; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/BodyElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/BodyElement.cs new file mode 100644 index 00000000..1636411d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/BodyElement.cs @@ -0,0 +1,89 @@ +using System; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.Charts.TextMarkup +{ + internal class BodyElement : ContainerElement + { + #region Private Variables + private MarkupElementCollection m_ActiveElements=null; + private IActiveMarkupElement m_MouseOverElement = null; + internal bool HasExpandElement = false; + internal string PlainText = ""; + #endregion + + #region Events + public event EventHandler HyperLinkClick; + #endregion + + #region Internal Implementation + public BodyElement() + { + m_ActiveElements = new MarkupElementCollection(null); + } + + public MarkupElementCollection ActiveElements + { + get { return m_ActiveElements; } + } + + public void MouseLeave(Control parent) + { + if (m_MouseOverElement != null) + m_MouseOverElement.MouseLeave(parent); + m_MouseOverElement = null; + } + + public void MouseMove(Control parent, MouseEventArgs e) + { + if (m_MouseOverElement != null && m_MouseOverElement.HitTest(e.X, e.Y)) + return; + if (m_MouseOverElement != null) + m_MouseOverElement.MouseLeave(parent); + + m_MouseOverElement = null; + + foreach(IActiveMarkupElement el in m_ActiveElements) + { + if (el.HitTest(e.X, e.Y)) + { + m_MouseOverElement = el; + m_MouseOverElement.MouseEnter(parent); + } + } + } + + public void MouseDown(Control parent, MouseEventArgs e) + { + if (m_MouseOverElement != null) + m_MouseOverElement.MouseDown(parent, e); + } + + public void MouseUp(Control parent, MouseEventArgs e) + { + if (m_MouseOverElement != null) + m_MouseOverElement.MouseUp(parent, e); + } + + public void Click(Control parent) + { + if (m_MouseOverElement != null) + { + m_MouseOverElement.Click(parent); + if (m_MouseOverElement is HyperLink) + { + if (HyperLinkClick != null) + HyperLinkClick(m_MouseOverElement, new EventArgs()); + } + } + } + + internal IActiveMarkupElement MouseOverElement + { + get { return (m_MouseOverElement); } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/ContainerElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/ContainerElement.cs new file mode 100644 index 00000000..2a055218 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/ContainerElement.cs @@ -0,0 +1,104 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.Charts.TextMarkup +{ + internal class ContainerElement : MarkupElement + { + #region Private Variables + private SerialContentLayoutManager m_Layout = null; + private MarkupLayoutManager m_MarkupLayout = null; + #endregion + + #region Internal Implementation + public override void Measure(Size availableSize, MarkupDrawContext d) + { + ArrangeInternal(new Rectangle(Point.Empty, availableSize), d); + } + + protected virtual SerialContentLayoutManager GetLayoutManager(bool mutliLine) + { + if (m_Layout == null) + { + m_Layout = new SerialContentLayoutManager(); + m_Layout.MultiLine = mutliLine; + m_Layout.ContentVerticalAlignment = eContentVerticalAlignment.Top; + m_Layout.BlockLineAlignment = eContentVerticalAlignment.Top; + m_Layout.BlockSpacing = 0; + } + + m_Layout.EvenHeight = true; + return m_Layout; + } + + private MarkupLayoutManager GetMarkupLayout() + { + if (m_MarkupLayout == null) + { + m_MarkupLayout = new MarkupLayoutManager(); + } + return m_MarkupLayout; + } + + public override void Render(MarkupDrawContext d) + { + Point offset = this.GetContainerOffset(); + d.Offset.Offset(offset.X, offset.Y); + + try + { + foreach (MarkupElement e in this.Elements) + { + e.Render(d); + } + } + finally + { + d.Offset.Offset(-offset.X, -offset.Y); + } + } + + protected virtual Point GetContainerOffset() + { + return this.Bounds.Location; + } + + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) + { + this.Bounds = finalRect; + ArrangeInternal(finalRect, d); + } + + protected virtual void ArrangeInternal(Rectangle bounds, MarkupDrawContext d) + { + SerialContentLayoutManager layout = GetLayoutManager(d.AllowMultiLine); + layout.RightToLeft = d.RightToLeft; + MarkupLayoutManager markupLayout = GetMarkupLayout(); + markupLayout.MarkupDrawContext = d; + try + { + MarkupElement[] blocks = new MarkupElement[this.Elements.Count]; + this.Elements.CopyTo(blocks); + + Rectangle r = layout.Layout(new Rectangle(Point.Empty, bounds.Size), blocks, markupLayout); + this.Bounds = new Rectangle(bounds.Location, r.Size); + } + finally + { + markupLayout.MarkupDrawContext = null; + } + } + + /// + /// Returns whether markup element is an block element that always consumes a whole line in layout. + /// + public override bool IsBlockElement + { + get { return true; } + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Div.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Div.cs new file mode 100644 index 00000000..b8659bdf --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Div.cs @@ -0,0 +1,161 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; +using DevComponents.DotNetBar; + +namespace DevComponents.Charts.TextMarkup +{ + internal class Div : ContainerElement + { + #region Private Variables + private eParagraphAlignment m_Align = eParagraphAlignment.Left; + private eParagraphVerticalAlignment m_VAlign = eParagraphVerticalAlignment.Top; + private int m_Width = 0; + private Padding m_Padding = new Padding(0, 0, 0, 0); + #endregion + + #region Internal Implementation + public eParagraphAlignment Align + { + get { return m_Align; } + set { m_Align = value; } + } + + protected override SerialContentLayoutManager GetLayoutManager(bool multiLine) + { + SerialContentLayoutManager sm = base.GetLayoutManager(multiLine); + if (m_Align == eParagraphAlignment.Left) + sm.ContentAlignment = eContentAlignment.Left; + else if (m_Align == eParagraphAlignment.Right) + sm.ContentAlignment = eContentAlignment.Right; + else if (m_Align == eParagraphAlignment.Center) + sm.ContentAlignment = eContentAlignment.Center; + + if (m_VAlign != eParagraphVerticalAlignment.Top) + { + sm.EvenHeight = false; + sm.BlockLineAlignment = (m_VAlign == eParagraphVerticalAlignment.Bottom ? eContentVerticalAlignment.Bottom : eContentVerticalAlignment.Middle); + } + + return sm; + } + + protected override Point GetContainerOffset() + { + if (m_Padding.Left == 0 && m_Padding.Top == 0) + return base.GetContainerOffset(); + + Point p = base.GetContainerOffset(); + p.X += m_Padding.Left; + p.Y += m_Padding.Top; + return p; + } + + protected override void ArrangeInternal(Rectangle bounds, MarkupDrawContext d) + { + Rectangle r = bounds; + if (m_Width > 0) + r.Width = m_Width; + if (m_Padding.IsEmpty) + { + base.ArrangeInternal(r, d); + if (m_Width > 0) + this.Bounds = new Rectangle(this.Bounds.X, this.Bounds.Y, m_Width, this.Bounds.Height + m_Padding.Bottom); + } + else + { + r.X += m_Padding.Left; + r.Y += m_Padding.Top; + base.ArrangeInternal(r, d); + + r = new Rectangle(bounds.X, bounds.Y, this.Bounds.Width + m_Padding.Horizontal, this.Bounds.Height + m_Padding.Vertical); + if (m_Width > 0) + r.Width = m_Width; + + this.Bounds = r; + } + } + + public override void ReadAttributes(XmlTextReader reader) + { + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "align") + { + string s = reader.Value.ToLower(); + if (s == "left") + m_Align = eParagraphAlignment.Left; + else if (s == "right") + m_Align = eParagraphAlignment.Right; + else if (s == "center") + m_Align = eParagraphAlignment.Center; + } + else if (reader.Name.ToLower() == "valign") + { + string s = reader.Value.ToLower(); + if (s == "top") + m_VAlign = eParagraphVerticalAlignment.Top; + else if (s == "middle") + m_VAlign = eParagraphVerticalAlignment.Middle; + else if (s == "bottom") + m_VAlign = eParagraphVerticalAlignment.Bottom; + } + else if (reader.Name.ToLower() == "width") + { + try + { + m_Width = Int32.Parse(reader.Value); + } + catch + { + m_Width = 0; + } + } + else if (reader.Name.ToLower() == "padding") + { + try + { + string[] values = reader.Value.Split(','); + if (values.Length > 0) + m_Padding.Left = Int32.Parse(values[0]); + if (values.Length > 1) + m_Padding.Right = Int32.Parse(values[1]); + if (values.Length > 2) + m_Padding.Top = Int32.Parse(values[2]); + if (values.Length > 3) + m_Padding.Bottom = Int32.Parse(values[3]); + } + catch + { + m_Padding = new Padding(0,0,0,0); + } + } + } + } + #endregion + } + + #region eParagraphAlignment + /// + /// Indicates paragraph content alignment + /// + internal enum eParagraphAlignment + { + Left, + Right, + Center + } + + /// + /// Indicates paragraph content alignment + /// + internal enum eParagraphVerticalAlignment + { + Top, + Middle, + Bottom + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/EndMarkupElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/EndMarkupElement.cs new file mode 100644 index 00000000..68758c14 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/EndMarkupElement.cs @@ -0,0 +1,42 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + internal class EndMarkupElement : MarkupElement + { + #region Internap Implementation + private MarkupElement m_StartElement = null; + + public EndMarkupElement(MarkupElement startElement) + { + m_StartElement = startElement; + } + + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + m_StartElement.MeasureEnd(availableSize, d); + this.Bounds = Rectangle.Empty; + } + + public override void Render(MarkupDrawContext d) + { + m_StartElement.RenderEnd(d); + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) + { + this.Bounds = Rectangle.Empty; + } + + /// + /// Gets reference to markup start element. + /// + public MarkupElement StartElement + { + get { return m_StartElement; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/ExpandElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/ExpandElement.cs new file mode 100644 index 00000000..6e60b3e9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/ExpandElement.cs @@ -0,0 +1,193 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Xml; + +namespace DevComponents.Charts.TextMarkup +{ + internal class ExpandElement : MarkupElement + { + #region Internal Implementation + private Size m_DefaultSize = new Size(5, 4); + private eExpandDirection m_Direction = eExpandDirection.Default; + + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + this.Bounds = new Rectangle(Point.Empty, m_DefaultSize); + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Graphics g = d.Graphics; + Color color = d.CurrentForeColor; + //Color shadeColor = Color.FromArgb(96, Color.White); + + eExpandDirection direction = eExpandDirection.Bottom; + if (m_Direction != eExpandDirection.Default) + direction = m_Direction; + + #if DOTNETBAR + if(d.ContextObject is ButtonItem) + { + if (m_Direction == eExpandDirection.Default) + { + ButtonItem item = d.ContextObject as ButtonItem; + if (item.IsOnMenu) + { + direction = eExpandDirection.Right; + if (item.PopupSide == ePopupSide.Default && d.RightToLeft || item.PopupSide == ePopupSide.Left) + direction = eExpandDirection.Left; + } + else if (item.PopupSide == ePopupSide.Default) + direction = eExpandDirection.Bottom; + else if (item.PopupSide == ePopupSide.Left) + direction = eExpandDirection.Left; + else if (item.PopupSide == ePopupSide.Right) + direction = eExpandDirection.Right; + else if (item.PopupSide == ePopupSide.Bottom) + direction = eExpandDirection.Bottom; + else if (item.PopupSide == ePopupSide.Top) + direction = eExpandDirection.Top; + } + } + #endif + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + Rectangle shadeRect = r; + if (direction == eExpandDirection.Bottom || direction == eExpandDirection.PopupDropDown) + shadeRect.Offset(0, 1); + else if (direction == eExpandDirection.Top) + shadeRect.Offset(0, -1); + else if (direction == eExpandDirection.Left) + shadeRect.Offset(1, 0); + else if (direction == eExpandDirection.Right) + shadeRect.Offset(-1, 0); + Point[] p = GetExpandPolygon(shadeRect, direction); + //using (SolidBrush brush = new SolidBrush(shadeColor)) + // g.FillPolygon(brush, p); + + p = GetExpandPolygon(r, direction); + using(SolidBrush brush = new SolidBrush(color)) + g.FillPolygon(brush, p); + + if (direction == eExpandDirection.PopupDropDown) + { + using (Pen pen = new Pen(color, 1)) + g.DrawLine(pen, r.X, r.Y - 2, r.Right - 1, r.Y - 2); + //using (Pen pen = new Pen(shadeColor, 1)) + // g.DrawLine(pen, r.X, r.Y - 1, r.Right - 1, r.Y - 1); + } + + g.SmoothingMode = sm; + + this.RenderBounds = r; + } + + private Point[] GetExpandPolygon(Rectangle r, eExpandDirection direction) + { + Point[] p = new Point[3]; + switch (direction) + { + case eExpandDirection.Right: + { + p[0].X = r.Left + 1; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 - 1; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X + 3; + p[2].Y = p[0].Y + 3; + break; + } + case eExpandDirection.Left: + { + p[0].X = r.Left + 3; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 - 1; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X - 3; + p[2].Y = p[0].Y + 3; + break; + } + case eExpandDirection.Top: + { + p[0].X = r.Left - 1; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 + m_DefaultSize.Height; + p[1].X = p[0].X + 6; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 3; + p[2].Y = p[0].Y - 4; + break; + } + case eExpandDirection.Bottom: + case eExpandDirection.PopupDropDown: + { + p[0].X = r.Left; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 + 1; + p[1].X = p[0].X + 5; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 2; + p[2].Y = p[0].Y + 3; + break; + } + } + return p; + } + + public override void ReadAttributes(XmlTextReader reader) + { + m_Direction = eExpandDirection.Default; + + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "direction") + { + string s = reader.Value.ToLower(); + if (s == "left") + m_Direction = eExpandDirection.Left; + else if (s == "right") + m_Direction = eExpandDirection.Right; + else if (s == "top") + m_Direction = eExpandDirection.Top; + else if (s == "bottom") + m_Direction = eExpandDirection.Bottom; + else if (s == "popup") + m_Direction = eExpandDirection.PopupDropDown; + break; + } + } + } + + private enum eExpandDirection + { + Left, + Right, + Top, + Bottom, + Default, + PopupDropDown + } + + /// + /// Returns whether layout manager can start new line with this element. + /// + public override bool CanStartNewLine + { + get { return false; } + } + #endregion + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/FontChangeElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/FontChangeElement.cs new file mode 100644 index 00000000..f77c3711 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/FontChangeElement.cs @@ -0,0 +1,49 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + internal class FontChangeElement : MarkupElement + { + #region Private Variables + protected Font m_OldFont = null; + #endregion + + #region Internal Implementation + + public override void Measure(Size availableSize, MarkupDrawContext d) + { + this.Bounds = Rectangle.Empty; + SetFont(d); + } + + public override void Render(MarkupDrawContext d) + { + SetFont(d); + } + + protected virtual void SetFont(MarkupDrawContext d) + { + + } + + public override void RenderEnd(MarkupDrawContext d) + { + if(m_OldFont!=null) + d.CurrentFont = m_OldFont; + m_OldFont = null; + base.RenderEnd(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + if (m_OldFont != null) + d.CurrentFont = m_OldFont; + m_OldFont = null; + base.MeasureEnd(availableSize, d); + } + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) { } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/FontElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/FontElement.cs new file mode 100644 index 00000000..3fb893f3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/FontElement.cs @@ -0,0 +1,180 @@ +using DevComponents.DotNetBar.Charts; +using System; +using System.Drawing; +using System.Xml; +using DevComponents.DotNetBar.Charts.Primitives; + +namespace DevComponents.Charts.TextMarkup +{ + internal class FontElement : FontChangeElement + { + #region Private Variables + + private Color _MForeColor = Color.Empty; + private Color _MOldForeColor = Color.Empty; + private int _MSize; + private bool _MRelativeSize; + private string _MFace = ""; + private string _MSystemColorName = ""; + + #endregion + + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + try + { + if (_MFace != "" || _MSize != 0 && _MRelativeSize || _MSize>4 && !_MRelativeSize) + { + if (_MFace != "") + d.CurrentFont = new Font(_MFace, ((_MRelativeSize || _MSize == 0)?font.SizeInPoints + _MSize:_MSize), font.Style); + else + d.CurrentFont = new Font(font.FontFamily, ((_MRelativeSize || _MSize == 0)? font.SizeInPoints + _MSize : _MSize), font.Style); + } + else + font = null; + } + catch + { + font = null; + } + + if (font != null) + m_OldFont = font; + + if (!d.IgnoreFormattingColors) + { + if (!_MForeColor.IsEmpty) + { + _MOldForeColor = d.CurrentForeColor; + d.CurrentForeColor = _MForeColor; + } + else if (_MSystemColorName != "") + { +#if DOTNETBAR + if (Rendering.GlobalManager.Renderer is Rendering.Office2007Renderer) + { + m_OldForeColor = d.CurrentForeColor; + d.CurrentForeColor = ((Rendering.Office2007Renderer)Rendering.GlobalManager.Renderer).ColorTable.Form.Active.CaptionTextExtra; + } +#endif + } + } + } + + public override void RenderEnd(MarkupDrawContext d) + { + RestoreForeColor(d); + + base.RenderEnd(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + RestoreForeColor(d); + base.MeasureEnd(availableSize, d); + } + + protected virtual void RestoreForeColor(MarkupDrawContext d) + { + if (!_MOldForeColor.IsEmpty) + d.CurrentForeColor = _MOldForeColor; + _MOldForeColor = Color.Empty; + } + + public Color ForeColor + { + get { return _MForeColor; } + set { _MForeColor = value; } + } + + public int Size + { + get { return _MSize; } + set { _MSize = value; } + } + + public string Face + { + get { return _MFace; } + set { _MFace = value; } + } + + private Color GetColorFromName(string name) + { + string s = name.ToLower(); + _MSystemColorName = ""; + if (s == "syscaptiontextextra") + { + _MSystemColorName = s; + return Color.Empty; + } + + return Color.FromName(name); + } + + public override void ReadAttributes(XmlTextReader reader) + { + _MRelativeSize = false; + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "color") + { + try + { + string s = reader.Value; + if (s.StartsWith("#")) + { + if (s.Length == 7) + _MForeColor = ColorFactory.GetColor(s.Substring(1)); + } + else + { + _MForeColor = GetColorFromName(s); + } + } + catch + { + _MForeColor = Color.Empty; + } + } + else if (reader.Name.ToLower() == "size") + { + string s = reader.Value; + if (s.StartsWith("+")) + { + try + { + _MSize = Int32.Parse(s.Substring(1)); + _MRelativeSize = true; + } + catch + { + _MSize = 0; + } + } + else + { + if (s.StartsWith("-")) + _MRelativeSize = true; + try + { + _MSize = Int32.Parse(s); + } + catch + { + _MSize = 0; + } + } + } + else if (reader.Name.ToLower() == "face") + { + _MFace = reader.Value; + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Heading.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Heading.cs new file mode 100644 index 00000000..44c23494 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Heading.cs @@ -0,0 +1,89 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + internal class Heading: ContainerElement + { + #region Private Variables + private int m_Level = 1; + private Font m_OldFont = null; + #endregion + + #region Internal Implementation + public Heading() { } + public Heading(int level) + { + m_Level = level; + } + + public override void Measure(Size availableSize, MarkupDrawContext d) + { + SetFont(d); + base.Measure(availableSize, d); + if (m_OldFont != null) + d.CurrentFont = m_OldFont; + } + + public override void Render(MarkupDrawContext d) + { + SetFont(d); + base.Render(d); + if (m_OldFont != null) + d.CurrentFont = m_OldFont; + } + + protected virtual void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + try + { + float size = d.CurrentFont.SizeInPoints; + if (m_Level == 1) + { + size += 12; + } + else if (m_Level == 2) + { + size += 8; + } + else if (m_Level == 3) + { + size += 6; + } + else if (m_Level == 4) + { + size += 4; + } + else if (m_Level == 5) + { + size += 2; + } + else if (m_Level == 6) + { + size += 1; + } + + d.CurrentFont = new Font(d.CurrentFont.FontFamily, size, FontStyle.Bold); + } + catch + { + font = null; + } + + if (font != null) + m_OldFont = font; + } + + /// + /// Gets or sets heading level. Values from 1 to 6 are valid. Default is 1. + /// + public int Level + { + get { return m_Level; } + set { m_Level = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/HyperLink.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/HyperLink.cs new file mode 100644 index 00000000..3400ebfd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/HyperLink.cs @@ -0,0 +1,215 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; +using System.Windows.Forms; +using System.Drawing.Drawing2D; + +namespace DevComponents.Charts.TextMarkup +{ + internal class HyperLink : MarkupElement, IActiveMarkupElement + { + #region Private Variables + private Color m_ForeColor = Color.Empty; + private Color m_OldForeColor = Color.Empty; + private string m_HRef = ""; + private string m_Name = ""; + private Cursor m_OldCursor = null; + private bool m_IsMouseOver = false; + private bool m_Visited = false; + #endregion + + #region Internal Implementation + public override void Measure(Size availableSize, MarkupDrawContext d) + { + this.Bounds = Rectangle.Empty; + SetForeColor(d); + } + + public override void Render(MarkupDrawContext d) + { + d.HyperLink = true; + d.HyperlinkStyle = GetHyperlinkStyle(); + if (!d.HyperlinkStyle.BackColor.IsEmpty) + { + using (GraphicsPath gp = new GraphicsPath()) + { + MarkupElementCollection col = this.Parent.Elements; + int start = col.IndexOf(this) + 1; + for (int i = start; i < col.Count; i++) + { + MarkupElement elem = col[i]; + if (!elem.Visible) continue; + if (elem is EndMarkupElement && ((EndMarkupElement)elem).StartElement == this) + break; + gp.AddRectangle(elem.RenderBounds); + } + + using (SolidBrush brush = new SolidBrush(d.HyperlinkStyle.BackColor)) + d.Graphics.FillPath(brush, gp); + } + } + SetForeColor(d); + } + + private HyperlinkStyle GetHyperlinkStyle() + { + if (m_IsMouseOver && MarkupSettings.MouseOverHyperlink.IsChanged) + return MarkupSettings.MouseOverHyperlink; + else if (m_Visited && MarkupSettings.VisitedHyperlink.IsChanged) + return MarkupSettings.VisitedHyperlink; + + return MarkupSettings.NormalHyperlink; + } + + protected virtual void SetForeColor(MarkupDrawContext d) + { + Color c = Color.Empty; + HyperlinkStyle style = GetHyperlinkStyle(); + if (style != null && !style.TextColor.IsEmpty) + c = style.TextColor; + + if (!m_ForeColor.IsEmpty) + c = m_ForeColor; + if (!c.IsEmpty) + { + m_OldForeColor = d.CurrentForeColor; + d.CurrentForeColor = c; + } + } + + public override void RenderEnd(MarkupDrawContext d) + { + RestoreForeColor(d); + d.HyperLink = false; + d.HyperlinkStyle = null; + base.RenderEnd(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + RestoreForeColor(d); + base.MeasureEnd(availableSize, d); + } + + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) { } + + protected virtual void RestoreForeColor(MarkupDrawContext d) + { + if (!m_OldForeColor.IsEmpty) + d.CurrentForeColor = m_OldForeColor; + m_OldForeColor = Color.Empty; + } + + public Color ForeColor + { + get { return m_ForeColor; } + set { m_ForeColor = value; } + } + + public string HRef + { + get { return m_HRef; } + set { m_HRef = value; } + } + + public string Name + { + get { return m_Name; } + set { m_Name = value; } + } + + public override void ReadAttributes(XmlTextReader reader) + { + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "href") + { + m_HRef = reader.Value; + } + else if (reader.Name.ToLower() == "name") + { + m_Name = reader.Value; + } + } + } + + /// + /// Returns whether hyper-link contains specified coordinates. + /// + /// + /// + /// + public bool HitTest(int x, int y) + { + if (this.Parent == null) + return false; + + MarkupElementCollection col = this.Parent.Elements; + int start = col.IndexOf(this)+1; + for (int i = start; i < col.Count; i++) + { + MarkupElement el = col[i]; + if (el is EndMarkupElement && ((EndMarkupElement)el).StartElement == this) + break; + + if (col[i].RenderBounds.Contains(x, y)) + return true; + + } + + return false; + } + + public void MouseEnter(Control parent) + { + m_OldCursor = parent.Cursor; + parent.Cursor = Cursors.Hand; + m_IsMouseOver = true; + if (MarkupSettings.MouseOverHyperlink.IsChanged) + { + InvalidateElements(parent); + } + } + + public void MouseLeave(Control parent) + { + if (m_OldCursor != null && parent!=null) + parent.Cursor = m_OldCursor; + m_OldCursor = null; + m_IsMouseOver = false; + if (MarkupSettings.MouseOverHyperlink.IsChanged) + { + InvalidateElements(parent); + } + } + + public void MouseDown(Control parent, MouseEventArgs e) { } + public void MouseUp(Control parent, MouseEventArgs e) { } + public void Click(Control parent) + { + m_Visited = true; + if (MarkupSettings.VisitedHyperlink.IsChanged) + { + InvalidateElements(parent); + } + } + + private void InvalidateElements(Control parent) + { + if (this.Parent == null) return; + MarkupElementCollection col = this.Parent.Elements; + int start = col.IndexOf(this) + 1; + for (int i = start; i < col.Count; i++) + { + MarkupElement elem = col[i]; + if (!elem.Visible) continue; + if (elem is EndMarkupElement && ((EndMarkupElement)elem).StartElement == this) + break; + parent.Invalidate(elem.RenderBounds); + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/IActiveMarkupElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/IActiveMarkupElement.cs new file mode 100644 index 00000000..86405a41 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/IActiveMarkupElement.cs @@ -0,0 +1,16 @@ +using System; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.Charts.TextMarkup +{ + internal interface IActiveMarkupElement + { + bool HitTest(int x, int y); + void MouseEnter(Control parent); + void MouseLeave(Control parent); + void MouseDown(Control parent, MouseEventArgs e); + void MouseUp(Control parent, MouseEventArgs e); + void Click(Control parent); + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/ImageElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/ImageElement.cs new file mode 100644 index 00000000..ee064019 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/ImageElement.cs @@ -0,0 +1,180 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; +using System.Reflection; + +namespace DevComponents.Charts.TextMarkup +{ + internal class ImageElement : MarkupElement + { + #region Private Variables + private Size m_ImageSize = Size.Empty; + private string m_ImageSource = ""; + private Image m_Image = null; + #endregion + + #region Internal Implementation + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + if (!m_ImageSize.IsEmpty) + this.Bounds = new Rectangle(Point.Empty, m_ImageSize); + else if (m_ImageSource.Length == 0) + this.Bounds = Rectangle.Empty; + else + { + Image img = this.GetImage(); + if (img != null) + this.Bounds = new Rectangle(Point.Empty, img.Size); + else + this.Bounds = new Rectangle(Point.Empty, new Size(16,16)); + } + } + + public override bool IsBlockElement + { + get + { + return false; + } + } + + private Image GetImage() + { + if (m_Image != null) return m_Image; + Assembly a = null; + + // Load from format: ClassLibrary1/ClassLibrary1.MyImage.png or ClassLibrary1/global::ClassLibrary1.Resources.MyImage + if (m_ImageSource.IndexOf('/') >= 0) + { + string[] parts = m_ImageSource.Split('/'); + a = Assembly.Load(parts[0]); + string ResourceName = parts[1]; + if (a != null) + { + m_Image = LoadImageGlobalResource(parts[1], a); + if (m_Image == null) + m_Image = LoadImageResource(parts[1], a); + + if (m_Image != null) return m_Image; + } + } + + // Probe Executing Assembly + a = Assembly.GetExecutingAssembly(); + m_Image = LoadImageGlobalResource(m_ImageSource, a); + if(m_Image==null) + m_Image = LoadImageResource(m_ImageSource, a); + + // Probe Entry Assembly + if (m_Image == null) + { + a = Assembly.GetEntryAssembly(); + m_Image = LoadImageGlobalResource(m_ImageSource, a); + if (m_Image == null) + m_Image = LoadImageResource(m_ImageSource, a); + } + + return m_Image; + } + + private Image LoadImageGlobalResource(string imageSource, Assembly a) + { + Image img = null; +#if FRAMEWORK20 + if (imageSource.StartsWith("global::")) + { + string name = imageSource.Substring(8); + if (name.Length > 0) + { + try + { + int i = name.LastIndexOf('.'); + string resName = name.Substring(0, i); + name = name.Substring(i + 1); + System.Resources.ResourceManager r = new System.Resources.ResourceManager(resName, a); + object obj = r.GetObject(name); + img = (Bitmap)obj; + } + catch + { + img = null; + } + } + } +#endif + return img; + } + + private Image LoadImageResource(string imageSource, Assembly a) + { + Image img = null; + try + { + img = new Bitmap(a.GetManifestResourceStream(imageSource)); + } + catch { } + + return img; + } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Image img = this.GetImage(); + if (img != null) + { + Rectangle imageRect = r; + imageRect.Size = img.Size; + d.Graphics.DrawImage(img, imageRect); + } + else + { + using (SolidBrush brush = new SolidBrush(Color.White)) + { + d.Graphics.FillRectangle(brush, r); + } + using (Pen pen = new Pen(Color.DarkGray, 1)) + { + d.Graphics.DrawRectangle(pen, r); + d.Graphics.DrawLine(pen, r.X, r.Y, r.Right, r.Bottom); + d.Graphics.DrawLine(pen, r.Right, r.Y, r.X, r.Bottom); + } + } + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + public override void ReadAttributes(XmlTextReader reader) + { + m_ImageSize = Size.Empty; + m_ImageSource = ""; + m_Image = null; + + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "width") + { + string s = reader.Value; + m_ImageSize.Width = int.Parse(s); + } + else if (reader.Name.ToLower() == "height") + { + string s = reader.Value; + m_ImageSize.Height = int.Parse(s); + } + else if (reader.Name.ToLower() == "src") + { + m_ImageSource = reader.Value; + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Italic.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Italic.cs new file mode 100644 index 00000000..bf5af5ad --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Italic.cs @@ -0,0 +1,27 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + internal class Italic : FontChangeElement + { + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + FontStyle style=font.Style | FontStyle.Italic; + + if (!font.Italic && d.CurrentFont.FontFamily.IsStyleAvailable(style)) + d.CurrentFont = new Font(font, style); + else + font = null; + + if (font != null) + m_OldFont = font; + + base.SetFont(d); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupDrawContext.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupDrawContext.cs new file mode 100644 index 00000000..ff3e0ef5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupDrawContext.cs @@ -0,0 +1,50 @@ +using System; +using System.Drawing; +using System.Text; + +namespace DevComponents.Charts.TextMarkup +{ + internal class MarkupDrawContext + { + public Graphics Graphics = null; + public Font CurrentFont = null; + public Color CurrentForeColor = SystemColors.ControlText; + public bool RightToLeft = false; + public Point Offset = Point.Empty; + public bool HyperLink = false; + public HyperlinkStyle HyperlinkStyle = null; + public bool Underline = false; + public Rectangle ClipRectangle = Rectangle.Empty; + public bool HotKeyPrefixVisible = false; + public object ContextObject = null; + public bool AllowMultiLine = true; + public bool IgnoreFormattingColors = false; + public bool StrikeOut; + + public MarkupDrawContext(Graphics g, Font currentFont, Color currentForeColor, bool rightToLeft) : this(g, currentFont, currentForeColor, rightToLeft, Rectangle.Empty, false) + { + } + + public MarkupDrawContext(Graphics g, Font currentFont, Color currentForeColor, bool rightToLeft, Rectangle clipRectangle, bool hotKeyPrefixVisible) + { + this.Graphics = g; + this.CurrentFont = currentFont; + this.CurrentForeColor = currentForeColor; + this.RightToLeft = rightToLeft; + this.ClipRectangle = clipRectangle; + this.HotKeyPrefixVisible = hotKeyPrefixVisible; + } + + public MarkupDrawContext(Graphics g, Font currentFont, Color currentForeColor, bool rightToLeft, Rectangle clipRectangle, bool hotKeyPrefixVisible, object contextObject) + { + this.Graphics = g; + this.CurrentFont = currentFont; + this.CurrentForeColor = currentForeColor; + this.RightToLeft = rightToLeft; + this.ClipRectangle = clipRectangle; + this.HotKeyPrefixVisible = hotKeyPrefixVisible; + this.ContextObject = contextObject; + } + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupElement.cs new file mode 100644 index 00000000..ce2f4dfc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupElement.cs @@ -0,0 +1,191 @@ +using DevComponents.UI.ContentManager; +using System; +using System.Drawing; +using System.Text; +using System.Xml; + +namespace DevComponents.Charts.TextMarkup +{ + internal abstract class MarkupElement : IBlockExtended + { + #region Private Variables + private MarkupElementCollection m_Elements = null; + private MarkupElement m_Parent = null; + private Rectangle m_Bounds = Rectangle.Empty; + private bool m_Visible = true; + private bool m_SizeValid = false; + private Rectangle m_RenderBounds = Rectangle.Empty; + #endregion + + #region Internal Implementation + public MarkupElement() + { + m_Elements = new MarkupElementCollection(this); + } + + /// + /// Returns whether markup element is an block element that always consumes a whole line in layout. + /// + public virtual bool IsBlockElement + { + get { return false; } + } + + /// + /// Returns whether layout manager switches to new line after processing this element. + /// + public virtual bool IsNewLineAfterElement + { + get { return false; } + } + + /// + /// Returns whether layout manager can start new line with this element. + /// + public virtual bool CanStartNewLine + { + get { return true; } + } + + /// + /// Gets the collection of child elements if any for this markup element. + /// + public virtual MarkupElementCollection Elements + { + get + { + if (m_Elements == null) + m_Elements = new MarkupElementCollection(this); + return m_Elements; + } + } + + internal void InvalidateElementsSize() + { + this.IsSizeValid = false; + if (m_Elements==null || m_Elements.Count == 0) + return; + foreach (MarkupElement e in m_Elements) + { + e.InvalidateElementsSize(); + e.IsSizeValid = false; + } + } + + /// + /// Gets or sets whether element size is valid. When size is not valid element Measure method will be called to validate size. + /// + public virtual bool IsSizeValid + { + get { return m_SizeValid; } + set { m_SizeValid = value; } + } + + /// + /// Gets element parent or null if parent is not set. + /// + public virtual MarkupElement Parent + { + get { return m_Parent; } + } + + internal void SetParent(MarkupElement parent) + { + m_Parent = parent; + } + + /// + /// Gets or sets actual rendering bounds. + /// + public Rectangle Bounds + { + get { return m_Bounds; } + set { m_Bounds = value; } + } + + /// + /// Gets or sets whether markup element is visible. + /// + public bool Visible + { + get { return m_Visible; } + set { m_Visible = value; } + } + + /// + /// Measures the element given available size. + /// + /// Size available to element + /// Reference to graphics object + public abstract void Measure(Size availableSize, MarkupDrawContext d); + + /// + /// Measures the end tag of an element. Most implementations do not need to do anything but implementations like the ones + /// that change color should return state back at this time. + /// + /// + /// + public virtual void MeasureEnd(Size availableSize, MarkupDrawContext d) { } + + /// + /// Renders element. + /// + /// Provides markup drawing context information. + public abstract void Render(MarkupDrawContext d); + + /// + /// Renders element tag end. Most implementations do not need to do anything but mplementations like the ones + /// that change color should return state back at this time. + /// + /// Provides markup drawing context information. + public virtual void RenderEnd(MarkupDrawContext d) { } + + /// + /// Provides final rectangle to element and lets it arrange it's content given new constraint. + /// + /// Final rectangle. + /// + protected abstract void ArrangeCore(Rectangle finalRect, MarkupDrawContext d); + + /// + /// Arranges the element given the final size. Layout is two step process with Measure followed by Arrange. + /// + /// + /// + public void Arrange(Rectangle finalSize, MarkupDrawContext d) + { + this.ArrangeCore(finalSize, d); + } + + public virtual void ReadAttributes(XmlTextReader reader) { } + + /// + /// Gets or sets actual rendered bounds for a give markup element if applicable. + /// + public Rectangle RenderBounds + { + get { return m_RenderBounds; } + set { m_RenderBounds = value; } + } + #endregion + + + public bool IsBlockContainer + { + get { throw new NotImplementedException(); } + } + + + public DotNetBar.Padding Margin + { + get + { + throw new NotImplementedException(); + } + set + { + throw new NotImplementedException(); + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupElementCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupElementCollection.cs new file mode 100644 index 00000000..919e2941 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupElementCollection.cs @@ -0,0 +1,133 @@ +using System; +using System.Text; +using System.Collections; + +namespace DevComponents.Charts.TextMarkup +{ + internal class MarkupElementCollection : CollectionBase + { + #region Private Variables + private MarkupElement m_Parent = null; + #endregion + + #region Internal Implementation + /// Creates new instance of the class. + public MarkupElementCollection(MarkupElement parent) + { + m_Parent = parent; + } + + /// + /// Gets or sets the collection parent element. + /// + public MarkupElement Parent + { + get { return m_Parent; } + set { m_Parent = value; } + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(MarkupElement MarkupElement) + { + return List.Add(MarkupElement); + } + /// + /// Returns reference to the object in collection based on it's index. + /// + public MarkupElement this[int index] + { + get {return (MarkupElement)(List[index]);} + set {List[index] = value;} + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, MarkupElement value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(MarkupElement value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(MarkupElement value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + public void Remove(MarkupElement value) + { + List.Remove(value); + } + + protected override void OnRemoveComplete(int index,object value) + { + base.OnRemoveComplete(index,value); + MarkupElement me=value as MarkupElement; + if (m_Parent != null) + { + me.SetParent(null); + m_Parent.IsSizeValid = false; + } + } + protected override void OnInsertComplete(int index,object value) + { + base.OnInsertComplete(index,value); + MarkupElement me=value as MarkupElement; + if (m_Parent != null) + { + me.SetParent(m_Parent); + m_Parent.IsSizeValid = false; + } + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(MarkupElement[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the MarkupElement array. + /// + /// Array to copy to. + internal void CopyTo(MarkupElement[] array) + { + List.CopyTo(array,0); + } + + protected override void OnClear() + { + base.OnClear(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupLayoutManager.cs new file mode 100644 index 00000000..7c8f578d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupLayoutManager.cs @@ -0,0 +1,32 @@ +using System.Collections; +using System.Drawing; +using System.Text; + +namespace DevComponents.Charts.TextMarkup +{ + internal class MarkupLayoutManager : BlockLayoutManager + { + private MarkupDrawContext m_MarkupDrawContext = null; + + public MarkupDrawContext MarkupDrawContext + { + get { return m_MarkupDrawContext; } + set { m_MarkupDrawContext = value; } + } + + public override void Layout(IBlock block, Size availableSize) + { + if (block is MarkupElement) + { + MarkupElement m = block as MarkupElement; + if(!m.IsSizeValid) + m.Measure(availableSize, m_MarkupDrawContext); + } + } + + public override Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines) + { + return (blocksBounds); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupParser.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupParser.cs new file mode 100644 index 00000000..17543ed1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupParser.cs @@ -0,0 +1,250 @@ +using System; +using System.Text; +using System.IO; +using System.Xml; +using System.Collections; +using System.Text.RegularExpressions; + +namespace DevComponents.Charts.TextMarkup +{ + internal class MarkupParser + { + #region Private Variables + private static string TextElementName = "text"; + private static string BodyTag = "body"; + #endregion + + #region Internal Implementation + public static BodyElement Parse(string text) + { + StringBuilder plainText = new StringBuilder(text.Length); + BodyElement root = new BodyElement(); + root.HasExpandElement = false; + MarkupElement currentParent = root; + Stack openTags = new Stack(); + openTags.Push(root); + // Input text is not wrapped into the container tag so we wrap it here + text = text.Replace(" ", "{ent_nbsp}"); + text = text.Replace("&zwsp;", "{ent_zwsp}"); + text = text.Replace("<", "{ent_lt}"); + text = text.Replace(">", "{ent_gt}"); + text = text.Replace("&", "{ent_amp}"); + text = text.Replace("|", "{ent_l}"); + text = text.Replace("&", "|"); + text = text.Replace("{ent_nbsp}", " "); + text = text.Replace("{ent_zwsp}", "&zwsp;"); + text = text.Replace("{ent_lt}", "<"); + text = text.Replace("{ent_gt}", ">"); + StringReader sr = new StringReader("<"+BodyTag+">" + text + ""); +#if !DEBUG + try +#endif + { + XmlTextReader reader = new XmlTextReader(sr); + //reader.EntityHandling = EntityHandling.ExpandCharEntities; + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element) + { + if (reader.Name == BodyTag) + continue; + MarkupElement el = CreateMarkupElement(reader.Name); + if (el == null) + { + reader.Skip(); + continue; + } + else if (el is ExpandElement) + root.HasExpandElement = true; + + if (el is IActiveMarkupElement) + root.ActiveElements.Add(el); + + // Parse any attributes here + if (reader.AttributeCount > 0) + { + el.ReadAttributes(reader); + reader.MoveToElement(); + } + + currentParent.Elements.Add(el); + + if (el is ContainerElement) + currentParent = el; + + if (!reader.IsEmptyElement) + openTags.Push(el); + } + else if (reader.NodeType == XmlNodeType.Text) + { + if (reader.Value.Length == 1) + { + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + if (reader.Value == " ") + { + el.TrailingSpace = true; + plainText.Append(' '); + } + else + { + el.Text = reader.Value; + el.Text = el.Text.Replace("|", "&"); + el.Text = el.Text.Replace("{ent_l}", "|"); + el.Text = el.Text.Replace("{ent_amp}", "&&"); + plainText.Append(el.Text+" "); + } + currentParent.Elements.Add(el); + } + else + { + string s = reader.Value; + if (s.StartsWith("\r\n")) + s = s.TrimStart(new char[] { '\r', '\n' }); + s = s.Replace("\r\n", " "); + string[] words = s.Split(' '); + bool space = false; + if (currentParent.Elements.Count > 0 && currentParent.Elements[currentParent.Elements.Count - 1] is NewLine) + space = true; + for (int i = 0; i < words.Length; i++) + { + if (words[i].Length == 0) + { + if (space) + continue; + space = true; + } + else + space = false; + + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + el.Text = words[i].Replace("|","&"); + el.Text = el.Text.Replace("{ent_l}", "|"); + el.Text = el.Text.Replace("{ent_amp}", "&&"); + plainText.Append(el.Text + " "); + if (i < words.Length - 1) + { + el.TrailingSpace = true; + space = true; + } + + currentParent.Elements.Add(el); + } + } + } + else if (reader.NodeType == XmlNodeType.Whitespace) + { + if (reader.Value.IndexOf(' ') >= 0) + { + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + el.TrailingSpace = true; + currentParent.Elements.Add(el); + } + } + else if (reader.NodeType == XmlNodeType.EntityReference) + { + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + if (reader.Name == "nbsp") + { + el.TrailingSpace = true; + } + else if (reader.Name == "zwsp") + { + el.TrailingSpace = false; + } + else + el.Text = reader.Name; + el.EnablePrefixHandling = false; + currentParent.Elements.Add(el); + } + else if (reader.NodeType == XmlNodeType.EndElement) + { + MarkupElement el = openTags.Pop() as MarkupElement; + if (el != currentParent) + { + currentParent.Elements.Add(new EndMarkupElement(el)); + } + else + { + if (currentParent != root) + currentParent = currentParent.Parent; + } + } + } + } +#if !DEBUG + catch + { + return null; + } +#endif + root.PlainText = plainText.ToString(); + return root; + } + + public static MarkupElement CreateMarkupElement(string elementName) + { + if (elementName == "b" || elementName == "strong") + return new Strong(); + else if (elementName == "i" || elementName == "em") + return new Italic(); + else if (elementName == "u") + return new Underline(); + else if (elementName == "br") + return new NewLine(); + else if (elementName == "expand") + return new ExpandElement(); + else if (elementName == "a") + return new HyperLink(); + else if (elementName == "p") + return new Paragraph(); + else if (elementName == "div") + return new Div(); + else if (elementName == "span") + return new Span(); + else if (elementName == "img") + return new ImageElement(); + else if (elementName == "h1") + return new Heading(); + else if (elementName == "h2") + return new Heading(2); + else if (elementName == "h3") + return new Heading(3); + else if (elementName == "h4") + return new Heading(4); + else if (elementName == "h5") + return new Heading(5); + else if (elementName == "h6") + return new Heading(6); + else if (elementName == "font") + return new FontElement(); + else if (elementName == "s" || elementName == "strike") + return new Strike(); + else if (elementName == TextElementName) + return new TextElement(); + + return null; + } + + /// + /// Tests whether input text could be markup text. + /// + /// Text to test. + /// true if text could be markup, otherwise false + public static bool IsMarkup(string text) + { + if (string.IsNullOrEmpty(text) || + (text.IndexOf("") < 0)) + { + return false; + } + + return true; + } + + internal static string RemoveExpand(string text) + { + return Regex.Replace(text, "", "", RegexOptions.IgnoreCase); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupSettings.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupSettings.cs new file mode 100644 index 00000000..5254bef2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/MarkupSettings.cs @@ -0,0 +1,150 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + /// + /// Holds text-markup related settings. + /// + public static class MarkupSettings + { + private static HyperlinkStyle _NormalHyperlink = new HyperlinkStyle(Color.Blue, eHyperlinkUnderlineStyle.SolidLine); + /// + /// Gets the style of the hyperlink in its default state. + /// + public static HyperlinkStyle NormalHyperlink + { + get { return _NormalHyperlink; } + } + + private static HyperlinkStyle _MouseOverHyperlink = new HyperlinkStyle(); + /// + /// Gets the style of the hyperlink when mouse is over the link. + /// + public static HyperlinkStyle MouseOverHyperlink + { + get { return _MouseOverHyperlink; } + } + + private static HyperlinkStyle _VisitedHyperlink = new HyperlinkStyle(); + /// + /// Gets the style of the visited hyperlink. + /// + public static HyperlinkStyle VisitedHyperlink + { + get { return _VisitedHyperlink; } + } + } + + /// + /// Defines the text-markup hyperlink appearance style. + /// + public class HyperlinkStyle + { + /// + /// Initializes a new instance of the HyperlinkStyle class. + /// + public HyperlinkStyle() + { + } + + /// + /// Initializes a new instance of the HyperlinkStyle class. + /// + /// + /// + public HyperlinkStyle(Color textColor, eHyperlinkUnderlineStyle underlineStyle) + { + _TextColor = textColor; + _UnderlineStyle = underlineStyle; + } + + /// + /// Initializes a new instance of the HyperlinkStyle class. + /// + /// + /// + /// + public HyperlinkStyle(Color textColor, Color backColor, eHyperlinkUnderlineStyle underlineStyle) + { + _TextColor = textColor; + _BackColor = backColor; + _UnderlineStyle = underlineStyle; + } + private Color _TextColor = Color.Empty; + /// + /// Gets or sets hyperlink text color. + /// + public Color TextColor + { + get { return _TextColor; } + set + { + if (_TextColor != value) + { + _TextColor = value; + } + } + } + + private Color _BackColor = Color.Empty; + /// + /// Gets or sets hyperlink back color. + /// + public Color BackColor + { + get { return _BackColor; } + set + { + if (_BackColor != value) + { + _BackColor = value; + } + } + } + + private eHyperlinkUnderlineStyle _UnderlineStyle = eHyperlinkUnderlineStyle.None; + /// + /// Gets or sets the underline style for the hyperlink. + /// + public eHyperlinkUnderlineStyle UnderlineStyle + { + get { return _UnderlineStyle; } + set + { + if (_UnderlineStyle != value) + { + _UnderlineStyle = value; + } + } + } + + /// + /// Gets whether style has been changed from its default state. + /// + public bool IsChanged + { + get { return !_TextColor.IsEmpty || !_BackColor.IsEmpty || _UnderlineStyle != eHyperlinkUnderlineStyle.None; } + } + } + + /// + /// Defines hyperlink styles. + /// + public enum eHyperlinkUnderlineStyle + { + /// + /// Hyper links are not marked. + /// + None, + /// + /// Hyper links are underlined using solid line. + /// + SolidLine, + /// + /// Hyper links are underlined using dashed line. + /// + DashedLine + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/NewLine.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/NewLine.cs new file mode 100644 index 00000000..e1ec3e91 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/NewLine.cs @@ -0,0 +1,39 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + internal class NewLine : MarkupElement + { + #region Internal Implementation + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + // Causes layout manager to switch to the new line + this.Bounds = new Rectangle(0, 0, 0, d.CurrentFont.Height); + } + + /// + /// Gets or sets whether element size is valid. When size is not valid element Measure method will be called to validate size. + /// + public override bool IsSizeValid + { + get { return false; } + set { } + } + + public override void Render(MarkupDrawContext d) {} + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + /// + /// Returns whether layout manager switches to new line after processing this element. + /// + public override bool IsNewLineAfterElement + { + get { return true; } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Paragraph.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Paragraph.cs new file mode 100644 index 00000000..af8b16d3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Paragraph.cs @@ -0,0 +1,20 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; + +namespace DevComponents.Charts.TextMarkup +{ + internal class Paragraph : Div + { + #region Internal Implementation + protected override void ArrangeInternal(Rectangle bounds, MarkupDrawContext d) + { + base.ArrangeInternal(bounds, d); + this.Bounds = new Rectangle(this.Bounds.X, this.Bounds.Y, this.Bounds.Width , this.Bounds.Height + d.CurrentFont.Height); + } + #endregion + } + + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Span.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Span.cs new file mode 100644 index 00000000..98e6266d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Span.cs @@ -0,0 +1,16 @@ +using System; +using System.Text; + +namespace DevComponents.Charts.TextMarkup +{ + internal class Span : Div + { + /// + /// Returns whether markup element is an block element that always consumes a whole line in layout. + /// + public override bool IsBlockElement + { + get { return false; } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Strike.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Strike.cs new file mode 100644 index 00000000..0e2af6af --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Strike.cs @@ -0,0 +1,28 @@ +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + internal class Strike : MarkupElement + { + public override void Measure(Size availableSize, MarkupDrawContext d) + { + Bounds = Rectangle.Empty; + } + + public override void Render(MarkupDrawContext d) + { + d.StrikeOut = true; + } + + public override void RenderEnd(MarkupDrawContext d) + { + d.StrikeOut = false; + + base.RenderEnd(d); + } + + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) + { + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Strong.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Strong.cs new file mode 100644 index 00000000..902e8d83 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Strong.cs @@ -0,0 +1,27 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + internal class Strong : FontChangeElement + { + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + FontStyle style = d.CurrentFont.Style | FontStyle.Bold; + + if (!font.Bold && font.FontFamily.IsStyleAvailable(style)) + d.CurrentFont = new Font(d.CurrentFont, style); + else + font = null; + + if (font != null) + m_OldFont = font; + + base.SetFont(d); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/TextElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/TextElement.cs new file mode 100644 index 00000000..18469c8a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/TextElement.cs @@ -0,0 +1,223 @@ +using DevComponents.DotNetBar.Charts; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.Charts.TextMarkup +{ + internal class TextElement : MarkupElement + { + private static bool PadText; + static TextElement() + { + string lc = System.Windows.Forms.Application.CurrentCulture.TwoLetterISOLanguageName; + if (lc == "ja") + PadText = true; + } + #region Private Variables + private string m_Text = ""; + private bool m_TrailingSpace; + private bool m_EnablePrefixHandling = true; + #endregion + + #region Internal Implementation + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { +#if (FRAMEWORK20) + if (BarUtilities.UseTextRenderer) + { + eTextFormat format = eTextFormat.Default | eTextFormat.NoPadding; + if (!d.HotKeyPrefixVisible || m_EnablePrefixHandling) + format |= eTextFormat.HidePrefix; + Size size = Size.Empty; + if (m_TrailingSpace) + { + if (d.CurrentFont.Italic) + { + size = Size.Ceiling(TextDrawing.MeasureString(d.Graphics, m_Text, d.CurrentFont, 0, format)); + size.Width += (int)(d.Graphics.MeasureString("||", d.CurrentFont).Width / 4); + } + else + size = Size.Ceiling(TextDrawing.MeasureString(d.Graphics, m_Text + (BarFunctions.IsVista && m_Text.Length > 0 ? "|" : "||"), d.CurrentFont, 0, format)); + } + else + size = Size.Ceiling(TextDrawing.MeasureString(d.Graphics, m_Text, d.CurrentFont, 0, format)); + if (PadText) + { + size.Width += BarUtilities.TextMarkupCultureSpecificPadding; + size.Height += BarUtilities.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + else +#endif + { + using (StringFormat format = new StringFormat(StringFormat.GenericTypographic)) + { + format.FormatFlags = StringFormatFlags.NoWrap; + if (d.HotKeyPrefixVisible || !m_EnablePrefixHandling) + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; + else + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide; + + if (m_TrailingSpace) + { + if (d.CurrentFont.Italic) + { + Size size = Size.Ceiling(d.Graphics.MeasureString(m_Text, d.CurrentFont, 0, format)); + size.Width += (int)(d.Graphics.MeasureString("|", d.CurrentFont).Width / 4); + if (PadText) + { + size.Width += TextHelper.TextMarkupCultureSpecificPadding; + size.Height += TextHelper.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + else + { + Size size = Size.Ceiling(d.Graphics.MeasureString(m_Text + "|", d.CurrentFont, 0, format)); + if (PadText) + { + size.Width += TextHelper.TextMarkupCultureSpecificPadding; + size.Height += TextHelper.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + } + else + { + Size size = Size.Ceiling(d.Graphics.MeasureString(m_Text, d.CurrentFont, 0, format)); + if (PadText) + { + size.Width += TextHelper.TextMarkupCultureSpecificPadding; + size.Height += TextHelper.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + } + } + IsSizeValid = true; + } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Graphics g = d.Graphics; + #if (FRAMEWORK20) + if (BarUtilities.UseTextRenderer) + { + eTextFormat format = eTextFormat.Default | eTextFormat.NoClipping | eTextFormat.NoPadding; + if (d.RightToLeft) format |= eTextFormat.RightToLeft; + if (!d.HotKeyPrefixVisible) + format |= eTextFormat.HidePrefix; + + if (!d.ClipRectangle.IsEmpty && r.Right > d.ClipRectangle.Right) + { + format|= eTextFormat.EndEllipsis; + r.Width -= (r.Right - d.ClipRectangle.Right); + } + TextDrawing.DrawString(g, m_Text, d.CurrentFont, d.CurrentForeColor, r, format); + + } + else + #endif + { + using (StringFormat format = new StringFormat(StringFormat.GenericTypographic)) + { + format.FormatFlags |= StringFormatFlags.NoWrap; + + if (d.RightToLeft) + format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + + if (d.HotKeyPrefixVisible) + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; + else + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide; + + if (!d.ClipRectangle.IsEmpty && r.Right > d.ClipRectangle.Right) + { + format.Trimming = StringTrimming.EllipsisCharacter; + r.Width -= (r.Right - d.ClipRectangle.Right); + } + + // LineLimit causes problems with rotated text + + format.FormatFlags &= ~StringFormatFlags.LineLimit; + + using (SolidBrush brush = new SolidBrush(d.CurrentForeColor)) + g.DrawString(m_Text, d.CurrentFont, brush, r, format); + } + } + + if (d.StrikeOut == true) + { + // StrikeOut + + float descent = d.CurrentFont.FontFamily.GetCellDescent(d.CurrentFont.Style) * + d.CurrentFont.Size / d.CurrentFont.FontFamily.GetEmHeight(d.CurrentFont.Style) + 1; + + using (Pen pen = new Pen(d.CurrentForeColor, 1)) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + + float y = r.Top + (r.Height + descent) / 2; + + g.DrawLine(pen, r.X, y, r.Right - 1, y); + g.SmoothingMode = sm; + } + } + + if ((d.HyperLink && (d.HyperlinkStyle == null || d.HyperlinkStyle.UnderlineStyle != eHyperlinkUnderlineStyle.None)) || d.Underline) + { + // Underline Hyperlink + float descent = d.CurrentFont.FontFamily.GetCellDescent(d.CurrentFont.Style) * d.CurrentFont.Size / d.CurrentFont.FontFamily.GetEmHeight(d.CurrentFont.Style); + using (Pen pen = new Pen(d.CurrentForeColor, 1)) + { + if (d.HyperLink && d.HyperlinkStyle != null && d.HyperlinkStyle.UnderlineStyle == eHyperlinkUnderlineStyle.DashedLine) + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; + descent -= 1; + System.Drawing.Drawing2D.SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + g.DrawLine(pen, r.X, r.Bottom - descent, r.Right - 1, r.Bottom - descent); + g.SmoothingMode = sm; + } + } + + this.RenderBounds = r; + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) {} + + public string Text + { + get { return m_Text; } + set + { + m_Text = value; + this.IsSizeValid = false; + } + } + + public bool TrailingSpace + { + get { return m_TrailingSpace; } + set + { + m_TrailingSpace = value; + this.IsSizeValid = false; + } + } + + public bool EnablePrefixHandling + { + get { return m_EnablePrefixHandling; } + set { m_EnablePrefixHandling = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Underline.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Underline.cs new file mode 100644 index 00000000..23e86052 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/TextMarkup/Underline.cs @@ -0,0 +1,40 @@ +using System; +using System.Text; +using System.Drawing; + +namespace DevComponents.Charts.TextMarkup +{ + internal class Underline : FontChangeElement + { + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + d.Underline = true; + //Font font = d.CurrentFont; + //FontStyle style = d.CurrentFont.Style | FontStyle.Underline; + + //if (!font.Underline && font.FontFamily.IsStyleAvailable(style)) + // d.CurrentFont = new Font(font, style); + //else + // font = null; + + //if (font != null) + // m_OldFont = font; + + base.SetFont(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + d.Underline = false; + base.MeasureEnd(availableSize, d); + } + + public override void RenderEnd(MarkupDrawContext d) + { + d.Underline = false; + base.RenderEnd(d); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/MetroStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/MetroStyleFactory.cs new file mode 100644 index 00000000..2dfd8081 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/MetroStyleFactory.cs @@ -0,0 +1,49 @@ +using System.Drawing; +using DevComponents.DotNetBar.Metro.ColorTables; +using DevComponents.DotNetBar.Metro.Rendering; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Create the Metro Visual Style for ChartControl. + /// + public class MetroStyleFactory : VisualStyleFactory + { + private MetroPartColors _MetroPartColors; + + /// + /// Initializes a new instance of the MetroStyleFactory class. + /// + public MetroStyleFactory() + { + _MetroPartColors = MetroRender.GetColorTable().MetroPartColors; + } + + /// + /// Initializes a new instance of the MetroStyleFactory class. + /// + /// Metro Part Colors to Initialize Style with. + public MetroStyleFactory(MetroPartColors metroPartColors) + { + _MetroPartColors = metroPartColors; + + if (metroPartColors == null) + _MetroPartColors = MetroRender.GetColorTable().MetroPartColors; + } + + /// + /// Create the DefaultVisualStyle for ChartControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class.s + public override DefaultVisualStyles CreateStyle(ColorFactory factory) + { + DefaultVisualStyles visualStyle = new DefaultVisualStyles(); + + // TODO: Add int code + + return (visualStyle); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/Office2010BlackStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/Office2010BlackStyleFactory.cs new file mode 100644 index 00000000..ae962116 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/Office2010BlackStyleFactory.cs @@ -0,0 +1,23 @@ +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Office2010BlackStyleFactory + /// + public class Office2010BlackStyleFactory : VisualStyleFactory + { + /// + /// Create the DefaultVisualStyle for the ChartControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class.s + public override DefaultVisualStyles CreateStyle(ColorFactory factory) + { + DefaultVisualStyles visualStyle = new DefaultVisualStyles(); + + return (visualStyle); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/Office2010BlueStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/Office2010BlueStyleFactory.cs new file mode 100644 index 00000000..69cdee91 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/Office2010BlueStyleFactory.cs @@ -0,0 +1,23 @@ +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Create the Office 2010 Blue Visual Style for the ChartControl. + /// + public class Office2010BlueStyleFactory : VisualStyleFactory + { + /// + /// Create the DefaultVisualStyle for the ChartControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class.s + public override DefaultVisualStyles CreateStyle(ColorFactory factory) + { + DefaultVisualStyles visualStyle = new DefaultVisualStyles(); + + return (visualStyle); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/Office2010SilverStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/Office2010SilverStyleFactory.cs new file mode 100644 index 00000000..4d0cbda5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/Office2010SilverStyleFactory.cs @@ -0,0 +1,23 @@ +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Create the Office 2010 Silver Visual Style for the ChartControl. + /// + public class Office2010SilverStyleFactory : VisualStyleFactory + { + /// + /// Create the DefaultVisualStyle for the ChartControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class.s + public override DefaultVisualStyles CreateStyle(ColorFactory factory) + { + DefaultVisualStyles visualStyle = new DefaultVisualStyles(); + + return (visualStyle); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/VisualStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/VisualStyleFactory.cs new file mode 100644 index 00000000..61869cf1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/VisualStyleFactory.cs @@ -0,0 +1,52 @@ +using System; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// Represents base class that each visual style factory for the ChartControl inherits from. + /// + public abstract class VisualStyleFactory + { + /// + /// Create the DefaultVisualStyle for the ChartControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class. + public abstract DefaultVisualStyles CreateStyle(Rendering.ColorFactory factory); + + /// + /// Create the DefaultVisualStyle for the ChartControl with empty color factory. + /// + /// New instance of DefaultVisualStyles class. + public virtual DefaultVisualStyles CreateStyle() + { + if (StyleManager.ColorTint.IsEmpty) + return CreateStyle(Rendering.ColorFactory.Empty); + + return CreateStyle(new Rendering.ColorBlendFactory(StyleManager.ColorTint)); + } + + /// + /// Returns the style factory for specified visual style. + /// + /// Style to create factory for. + /// An instance of VisualStyleFactory. + public static VisualStyleFactory GetStyleFactory(ChartControlStyle style) + { + if (style == ChartControlStyle.Office2010Blue) + return new Office2010BlueStyleFactory(); + + if (style == ChartControlStyle.Office2010Silver) + return new Office2010SilverStyleFactory(); + + if (style == ChartControlStyle.Office2010Black) + return new Office2010BlackStyleFactory(); + + if (style == ChartControlStyle.Metro) + return new MetroStyleFactory(); + + throw new ArgumentException(string.Format( + "Specified style '{0}' factory has not been implemented.", style)); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/VisualStylesTable.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/VisualStylesTable.cs new file mode 100644 index 00000000..cc83f564 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Charts/VisualStyles/VisualStylesTable.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; + +namespace DevComponents.DotNetBar.Charts.Style +{ + /// + /// VisualStylesTable + /// + public static class VisualStylesTable + { + private static Dictionary + _DefaultStyles = new Dictionary(); + + /// + /// Gets the DefaultVisualStyles for specified Chart style. + /// + /// ChartControl Style to return. + /// An instance of DefaultVisualStyle. + public static DefaultVisualStyles GetStyle(ChartControlStyle style) + { + DefaultVisualStyles visualStyle; + bool cacheStyle = true; + + if (style == ChartControlStyle.Metro || !StyleManager.ColorTint.IsEmpty) + cacheStyle = false; + + if (cacheStyle == false || !_DefaultStyles.TryGetValue(style, out visualStyle)) + { + VisualStyleFactory factory = VisualStyleFactory.GetStyleFactory(style); + + visualStyle = factory.CreateStyle(); + + if (cacheStyle) // Do not cache Metro style + _DefaultStyles.Add(style, visualStyle); + } + + return visualStyle; + } + + /// + /// Replaces an system style with the specified visual style. + /// + /// ChartControlStyle to replace. + /// DefaultVisualStyles to replace the system style with. + public static void SetStyleFactory(ChartControlStyle style, DefaultVisualStyles visualStyle) + { + _DefaultStyles[style] = visualStyle; + } + } + + /// + /// Defines available pre-defined ChartControl visual styles. + /// + public enum ChartControlStyle + { + /// + /// Office 2010 Blue style. + /// + Office2010Blue, + + /// + /// Office 2010 Silver style. + /// + Office2010Silver, + + /// + /// Office 2010 Black style. + /// + Office2010Black, + + /// + /// Metro Style. + /// + Metro + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/DevComponents.DotNetBar.Keyboard.csproj b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/DevComponents.DotNetBar.Keyboard.csproj new file mode 100644 index 00000000..692131a8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/DevComponents.DotNetBar.Keyboard.csproj @@ -0,0 +1,115 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {57C1D8BE-55D4-4403-BC65-FC59D8148504} + Library + Properties + DevComponents.DotNetBar.Keyboard + DevComponents.DotNetBar.Keyboard + v2.0 + + + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\DevComponents.DotNetBar.Keyboard.XML + + + bin\Release\ + TRACE + true + pdbonly + AnyCPU + bin\Release\DevComponents.DotNetBar.Keyboard.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + bin\Release\DevComponents.DotNetBar.Keyboard.XML + + + bin\Release\ + TRACE;TRIAL + true + pdbonly + AnyCPU + bin\Release\DevComponents.DotNetBar.Keyboard.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + bin\Release\DevComponents.DotNetBar.Keyboard.XML + + + true + + + dotnetbar.snk + + + + + + + + + + + + + Form + + + + + Component + + + + + Component + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Dpi.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Dpi.cs new file mode 100644 index 00000000..87d6940b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Dpi.cs @@ -0,0 +1,230 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.Keyboard +{ + /// + /// Provides High DPI support for DotNetBar controls. + /// + public static class Dpi + { + private static SizeF _Factor = new SizeF(1f, 1f); + private static bool _UseFactor = false; + + static Dpi() + { + Debug.WriteLine("Static constructor"); + } + + 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 (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); + Width22 = Dpi.Width(22); + Width24 = Dpi.Width(24); + Width25 = Dpi.Width(25); + 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 Width22 = 22; + public static int Width24 = 24; + public static int Width25 = 25; + 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 + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Keyboard.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Keyboard.cs new file mode 100644 index 00000000..5ddfe14b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Keyboard.cs @@ -0,0 +1,778 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Collections.ObjectModel; + +namespace DevComponents.DotNetBar.Keyboard +{ + // A Keyboard is defined by one or more KeyboardLayout objects. + // A KeyboardLayout is a layout of certain Key objects. + // A Key object represents all the data that a virtual key needs (caption, actual key-information to send + // to the attached control, hint, bounds, style, etc). + + // Because in this version of the VirtualKeyboard control the user cannot design new layouts for the keyboard, + // we will not publicly expose the model classes of the keyboard. + + /// + /// Holds information about a single virtual keyboard Key. + /// + public class Key + { + private string _Caption; + + /// + /// Gets the caption on the key. + /// + public string Caption + { + get { return _Caption; } + } + + + private string _Info; + + /// + /// Gets the actual key-information that is sent to the attached control. The format of this information + /// must confirm to the description for the SendKeys.Send function. For more details, see: + /// http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx + /// + public string Info + { + get { return _Info; } + } + + + private Rectangle _Bounds; + + /// + /// Gets the bounds of the key. + /// + public Rectangle Bounds + { + get { return _Bounds; } + internal set { _Bounds = value; } + } + + + private KeyStyle _Style; + + /// + /// Gets a value representing the way the key looks on the virtual keyboard. A key might look normal, + /// lighter, darker or with a pressed effect. + /// + public KeyStyle Style + { + get { return _Style; } + } + + + private int _ChangeToLayout; + + /// + /// Gets the index of the layout to change to, if this key is pressed. A positive value represents a new layout. + /// KeyboardLayout.NoChange and KeyboardLayout.PreviousLayout constants can also be used with special meaning. + /// + /// + /// If this is a positive integer ( >= 0 ), it represents the index of the layout to switch to when this key + /// is pressed. In this case, the keyboard does not send any key information to the attached control (the Info + /// field is ignored), only changes the layout. + /// + /// If this is KeyboardLayout.NoChange the keyboard will send the info to the attached control. + /// + /// If this is KeyboardLayout.PreviousLayout the keyboard will switch to the previous set layout. The keyboard + /// maintains internally a stack of all used layouts. If no more layouts in the stakc, the keyboard switches to + /// the layout with index 0. + /// + public int ChangeToLayout + { + get { return _ChangeToLayout; } + } + + + private int _ChangeToLayoutEx; + + /// + /// Gets the index of the layout to change to, when this key is double clicked. A positive value represents a new layout. + /// KeyboardLayout.NoChange and KeyboardLayout.PreviousLayout constants can also be used with special meaning. + /// + /// + /// If this is a positive integer ( >= 0 ), it represents the index of the layout to switch to when this key + /// is pressed. In this case, the keyboard does not send any key information to the attached control (the Info + /// field is ignored), only changes the layout. + /// + /// If this is KeyboardLayout.NoChange the keyboard will send the info to the attached control. + /// + /// If this is KeyboardLayout.PreviousLayout the keyboard will switch to the previous set layout. The keyboard + /// maintains internally a stack of all used layouts. If no more layouts in the stakc, the keyboard switches to + /// the layout with index 0. + /// + public int ChangeToLayoutEx + { + get { return _ChangeToLayoutEx; } + } + + + private string _Hint; + + /// + /// Gets the text that will be displayed in the upper part of the keyboard, as a hint for what the key does, + /// usually in combination with a modifier key (e.g. Underline, Undo, etc). + /// + public string Hint + { + get { return _Hint; } + } + + + /// + /// Creates a new Key object. + /// + /// The text displayed on the key. + /// The information that will be sent to the attached control. + /// The text in the upper part of the key, that provides a hint for the user about what the key does. + /// The way the key looks. + /// The index of the layout to switch to. + public Key(string caption, string info = null, string hint = "", KeyStyle style = KeyStyle.Normal, int changeToLayout = KeyboardLayout.NoChange, int changeToLayoutEx = KeyboardLayout.NoChange) + { + _Caption = caption; + _Info = info != null ? info : caption; + _Style = style; + _Hint = hint; + _ChangeToLayout = changeToLayout; + _ChangeToLayoutEx = changeToLayoutEx; + } + + /// + /// Returns a string that represents the current Key. + /// + /// A string that represents the current Key. + public override string ToString() + { + return Caption; + } + } + + + /// + /// Specifies the way a key looks, specifically what color it uses from the ColorTable. + /// + public enum KeyStyle + { + /// + /// Key should be drawn as a normal key colors. + /// + Normal, + + /// + /// Key should be drawn with lighter colors. + /// + Light, + + /// + /// Key should be drawn with darker colors. + /// + Dark, + + /// + /// Key should be drawn with the pressed color. + /// + Pressed, + + /// + /// Key should be drawn with the toggled color. + /// + Toggled + } + + + /// + /// Represents a layout for a virtual keyboard. + /// + /// The Keys have coordinates in the KeyboardLayout specified in logical layout units. By default for this version + /// of the control, a normal key is 10 logical units (LUs) width and 10 LUs height. A space between two keys is 1 LU. + /// When rendering, we assume the whole Layout is stretched over the Keyboard control, so we need to change from + /// LUs (ranging from 0 to layout.LogicalWidth) to pixels (ranging from 0 to control.Width). + /// This allows the layout to be resized to almost any sizes. + public class KeyboardLayout + { + /// + /// Indicates that a key should switch the Keyboard to the previous layout. + /// + public const int PreviousLayout = -2; + + /// + /// Indicates that a key does not switch to any layout. + /// + public const int NoChange = -1; + + private KeysCollection _Keys = new KeysCollection(); + + /// + /// Gets the collection of the Keys in this KeyboardLayout. + /// + public KeysCollection Keys + { + get { return _Keys; } + } + + /// + /// Gets the logical width of this KeyboardLayout. + /// + public virtual int LogicalWidth + { + get + { + int w = 0; + foreach (Key key in Keys) + { + if (key.Bounds.Right > w) + w = key.Bounds.Right; + } + + return w; + } + } + + /// + /// Gets the logical height of this KeyboardLayout. + /// + public virtual int LogicalHeight + { + get + { + int h = 0; + foreach (Key key in Keys) + { + if (key.Bounds.Bottom > h) + h = key.Bounds.Bottom; + } + + return h; + } + } + + /// + /// Tests if a certain point hits a key on the virtual keyboard. + /// + /// The x-coordinate of the hit point (in logical units of this KeyboardLayout) + /// The y-coordinate of the hit point (in logical units of this KeyboardLayout) + /// Returns the key that was hit, or null if the point didn't hit any keys. + public Key KeyHitTest(int x, int y) + { + foreach (Key key in Keys) + { + if (key.Bounds.Contains(x, y)) + return key; + } + + return null; + } + } + + + /// + /// Represents a layout for a virtual keyboard in which keys are defined in a linear way. This class + /// allows creation of layouts in which keys can be ordered from left to right and from top to bottom. + /// + /// + /// With the linear layout, the keys are allowed to have any width. The height, however, must be the same. + /// This layout is build by adding to it spaces, keys and new lines. + /// A key represents a virtual key AND a space after it. + /// A space represents a placeholder between two keys and it is used when there is need for a larger space + /// between two certain keys + /// A new line represents the fact that a new line of keys should be defined. + /// + /// + /// The default virtual keyboard of the VirtualKeyboard control is defined in the following way: + /// + /// AddKey("q"); + /// AddKey("w"); + /// AddKey("e"); + /// // ... + /// AddKey("p"); + /// AddKey("Backspace"); + /// + /// AddLine(); // Starts a new row of keys. + /// AddSpace(4); // Creates a larger space at the beginning of the second row. + /// + /// AddKey("a"); + /// AddKey("s"); + /// // ... + /// + /// + public class LinearKeyboardLayout : KeyboardLayout + { + private int _LastXOffset = 0; + private int _LastYOffset = 0; + + /// + /// The logical size of the space between two keys. + /// + public const int SpaceSize = 1; + + /// + /// The logical size of a key. + /// + public const int NormalKeySize = 10; + + /// + /// Adds a space to this LinearKeyboardLayout. + /// + /// The size of the space, in logical units. + public void AddSpace(int width = SpaceSize) + { + width = Dpi.Width(width); + _LastXOffset += width; + } + + + /// + /// Starts a new row of keys in this LinearKeyboardLayout. + /// + public void AddLine() + { + _LastXOffset = 0; + _LastYOffset += Dpi.Width(NormalKeySize + SpaceSize); + } + + + /// + /// Adds a new key to this LinearKeayboardLayout. + /// + /// The text displayed on the key. + /// The information that will be sent to the attached control. + /// The text in the upper part of the key, that provides a hint for the user about what the key does. + /// The width of the key, in logical units. + /// The height of the key, in logical units. + /// The way the key looks. + /// The index of the layout to switch to. + /// The index of the layout to switch to, when key is double clicked. + public void AddKey(string caption, string info = null, string hint = "", int width = NormalKeySize, int height = NormalKeySize, KeyStyle style = KeyStyle.Normal, int layout = KeyboardLayout.NoChange, int layoutEx = KeyboardLayout.NoChange) + { + Key key = new Key(caption, info, hint, style, layout, layoutEx); + width = Dpi.Width(width); + height = Dpi.Height(height); + key.Bounds = new Rectangle(_LastXOffset, _LastYOffset, width, height); + + _LastXOffset += width; + AddSpace(); + + Keys.Add(key); + } + } + + + /// + /// Represents a Virtual Keyboard. + /// + /// Each Keyboard has a collection of KeyboardLayout objects. The Keyboard also maintains the current Layout among all its layouts. + public class Keyboard + { + private KeyboardLayoutsCollection _Layouts = new KeyboardLayoutsCollection(); + + /// + /// Gets the collection of the keyboard layouts in this Keyboard. + /// + public KeyboardLayoutsCollection Layouts + { + get { return _Layouts; } + } + + private int _CurrentLayoutIndex; + + /// + /// Gets or sets the current layout index of this Keyboard. + /// + public int CurrentLayoutIndex + { + get { return _CurrentLayoutIndex; } + set + { + _LayoutStack.Push(_CurrentLayoutIndex); + _CurrentLayoutIndex = value; + } + } + + + /// + /// Gets the current layout of this Keyboard. + /// + public KeyboardLayout CurrentLayout + { + get { return _Layouts[_CurrentLayoutIndex]; } + } + + + private Stack _LayoutStack = new Stack(); + + /// + /// Switches the Keyboard to the previous layout. + /// + public void ChangeToPreviousLayout() + { + if (_LayoutStack.Count > 0) + _CurrentLayoutIndex = _LayoutStack.Pop(); + else + _CurrentLayoutIndex = 0; + } + + /// + /// Switches the Keyboard to the first layout and resets the layout stack. + /// + public void ResetLayoutStack() + { + _LayoutStack.Clear(); + _CurrentLayoutIndex = 0; + } + + + /// + /// Creates the default Keyboard populated with common layouts and functionality. + /// + /// A new Keyboard instance representing a default keyboard. + public static Keyboard CreateDefaultKeyboard() + { + Keyboard keyboard = new Keyboard(); + + LinearKeyboardLayout kc; // Actually there are 4 layout objects, but for code simplicity this variable is reused for creating each of them. + + #region Normal style configuration (no modifier keys pressed) + + kc = new LinearKeyboardLayout(); + keyboard._Layouts.Add(kc); + + kc.AddKey("q"); + kc.AddKey("w"); + kc.AddKey("e"); + kc.AddKey("r"); + kc.AddKey("t"); + kc.AddKey("y"); + kc.AddKey("u"); + kc.AddKey("i"); + kc.AddKey("o"); + kc.AddKey("p"); + kc.AddKey("Backspace", info: "{BACKSPACE}", width: 21); + + kc.AddLine(); + kc.AddSpace(4); + + kc.AddKey("a"); + kc.AddKey("s"); + kc.AddKey("d"); + kc.AddKey("f"); + kc.AddKey("g"); + kc.AddKey("h"); + kc.AddKey("j"); + kc.AddKey("k"); + kc.AddKey("l"); + kc.AddKey("'"); + kc.AddKey("Enter", info: "{ENTER}", width: 17); + + kc.AddLine(); + + kc.AddKey("Shift", info: "", style: KeyStyle.Dark, layout: 1); + kc.AddKey("z"); + kc.AddKey("x"); + kc.AddKey("c"); + kc.AddKey("v"); + kc.AddKey("b"); + kc.AddKey("n"); + kc.AddKey("m"); + kc.AddKey(","); + kc.AddKey("."); + kc.AddKey("?"); + kc.AddKey("Shift", info: "", style: KeyStyle.Dark, layout: 1); + + kc.AddLine(); + + kc.AddKey("Ctrl", info: "", style: KeyStyle.Dark, layout: 2); + kc.AddKey("&123", info: "", style: KeyStyle.Dark, layout: 3); + kc.AddKey(":-)", info: ":-{)}", style: KeyStyle.Dark); + //kc.AddKey("Alt", info: "%", style: KeyStyle.Dark); + kc.AddKey(" ", width: 76); + kc.AddKey("<", info: "{LEFT}", style: KeyStyle.Dark); + kc.AddKey(">", info: "{RIGHT}", style: KeyStyle.Dark); + + #endregion + + #region Shift modifier pressed + + kc = new LinearKeyboardLayout(); + keyboard._Layouts.Add(kc); + + kc.AddKey("Q", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("W", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("E", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("R", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("T", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("Y", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("U", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("I", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("O", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("P", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("Backspace", info: "{BACKSPACE}", width: 21); + + kc.AddLine(); + kc.AddSpace(4); + + kc.AddKey("A", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("S", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("D", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("F", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("G", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("H", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("J", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("K", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("L", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("\"", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("Enter", info: "{ENTER}", width: 17); + + kc.AddLine(); + + kc.AddKey("Shift", info: "", style: KeyStyle.Pressed, layout: 0, layoutEx: 4); + kc.AddKey("Z", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("X", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("C", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("V", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("B", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("N", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("M", layout: KeyboardLayout.PreviousLayout); + kc.AddKey(";", layout: KeyboardLayout.PreviousLayout); + kc.AddKey(":", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("!", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("Shift", info: "", style: KeyStyle.Pressed, layout: 0, layoutEx: 4); + + kc.AddLine(); + + kc.AddKey("Ctrl", info: "", style: KeyStyle.Dark, layout: 2); + kc.AddKey("&123", info: "", style: KeyStyle.Dark, layout: 3); + kc.AddKey(":-)", info: ":-{)}", style: KeyStyle.Dark, layout: KeyboardLayout.PreviousLayout); + kc.AddKey(" ", width: 76, layout: KeyboardLayout.PreviousLayout); + kc.AddKey("<", info: "+{LEFT}", style: KeyStyle.Dark, layout: KeyboardLayout.PreviousLayout); + kc.AddKey(">", info: "+{RIGHT}", style: KeyStyle.Dark, layout: KeyboardLayout.PreviousLayout); + + #endregion + + #region Ctrl modifier pressed + + kc = new LinearKeyboardLayout(); + keyboard._Layouts.Add(kc); + + kc.AddKey("q", info: "^q", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("w", info: "^w", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("e", info: "^e", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("r", info: "^r", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("t", info: "^t", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("y", info: "^y", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("u", info: "^u", hint: "Underline", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("i", info: "^i", hint: "Italic", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("o", info: "^o", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("p", info: "^p", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("Backspace", info: "^{BACKSPACE}", width: 21, layout: KeyboardLayout.PreviousLayout); + + kc.AddLine(); + kc.AddSpace(4); + + kc.AddKey("a", info: "^a", hint: "Select all", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("s", info: "^s", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("d", info: "^d", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("f", info: "^f", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("g", info: "^g", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("h", info: "^h", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("j", info: "^j", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("k", info: "^k", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("l", info: "^l", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("'", info: "^'", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("Enter", info: "^{ENTER}", width: 17, layout: KeyboardLayout.PreviousLayout); + + kc.AddLine(); + + kc.AddKey("Shift", info: "", layout: 1); + kc.AddKey("z", info: "^z", hint: "Undo", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("x", info: "^x", hint: "Cut", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("c", info: "^c", hint: "Copy", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("v", info: "^v", hint: "Paste", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("b", info: "^b", hint: "Bold", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("n", info: "^n", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("m", info: "^m", layout: KeyboardLayout.PreviousLayout); + kc.AddKey(",", info: "^,", layout: KeyboardLayout.PreviousLayout); + kc.AddKey(".", info: "^.", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("?", info: "^?", layout: KeyboardLayout.PreviousLayout); + kc.AddKey("Shift", info: "", layout: 1); + + kc.AddLine(); + + kc.AddKey("Ctrl", info: "", style: KeyStyle.Pressed, layout: KeyboardLayout.PreviousLayout); + kc.AddKey("&123", info: "", style: KeyStyle.Dark, layout: 3); + kc.AddKey(":-)", info: "^:-{)}", style: KeyStyle.Dark, layout: KeyboardLayout.PreviousLayout); + kc.AddKey(" ", info: "^ ", width: 76, layout: KeyboardLayout.PreviousLayout); + kc.AddKey("<", info: "^{LEFT}", style: KeyStyle.Dark, layout: KeyboardLayout.PreviousLayout); + kc.AddKey(">", info: "^{RIGHT}", style: KeyStyle.Dark, layout: KeyboardLayout.PreviousLayout); + + #endregion + + #region Symbols and numbers (&123) modifier pressed + + kc = new LinearKeyboardLayout(); + keyboard._Layouts.Add(kc); + + kc.AddKey("!"); + kc.AddKey("@"); + kc.AddKey("#"); + kc.AddKey("$"); + kc.AddKey("½"); + kc.AddKey("-"); + kc.AddKey("+", info: "{+}"); + + kc.AddSpace(5); + + kc.AddKey("1", style: KeyStyle.Light); + kc.AddKey("2", style: KeyStyle.Light); + kc.AddKey("3", style: KeyStyle.Light); + + kc.AddSpace(5); + + kc.AddKey("Bcks", info: "{BACKSPACE}", style: KeyStyle.Dark); + + kc.AddLine(); + + // second line + kc.AddKey(";"); + kc.AddKey(":"); + kc.AddKey("\""); + kc.AddKey("%", info: "{%}"); + kc.AddKey("&"); + kc.AddKey("/"); + kc.AddKey("*"); + + kc.AddSpace(5); + + kc.AddKey("4", style: KeyStyle.Light); + kc.AddKey("5", style: KeyStyle.Light); + kc.AddKey("6", style: KeyStyle.Light); + + kc.AddSpace(5); + + kc.AddKey("Enter", info: "{ENTER}", style: KeyStyle.Dark); + + kc.AddLine(); + + // third line + kc.AddKey("(", info: "{(}"); + kc.AddKey(")", info: "{)}"); + kc.AddKey("[", info: "{[}"); + kc.AddKey("]", info: "{]}"); + kc.AddKey("_"); + kc.AddKey("\\"); + kc.AddKey("="); + + kc.AddSpace(5); + + kc.AddKey("7", style: KeyStyle.Light); + kc.AddKey("8", style: KeyStyle.Light); + kc.AddKey("9", style: KeyStyle.Light); + + kc.AddSpace(5); + + kc.AddKey("Tab", info: "{TAB}", style: KeyStyle.Dark); + + kc.AddLine(); + + // forth line + kc.AddKey("...", style: KeyStyle.Dark, layout: KeyboardLayout.PreviousLayout); + kc.AddKey("&123", info: "", style: KeyStyle.Pressed, layout: KeyboardLayout.PreviousLayout); + kc.AddKey(":-)", info: ":-{)}", style: KeyStyle.Dark); + kc.AddKey("<", info: "{LEFT}", style: KeyStyle.Dark); + kc.AddKey(">", info: "{RIGHT}", style: KeyStyle.Dark); + kc.AddKey("Space", info: "^ ", width: 21); + + kc.AddSpace(5); + + kc.AddKey("0", style:KeyStyle.Light, width: 21); + kc.AddKey(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, style: KeyStyle.Dark); + + kc.AddSpace(5); + + kc.AddLine(); + + #endregion + + #region Shift modifier toggled + + kc = new LinearKeyboardLayout(); + keyboard._Layouts.Add(kc); + + kc.AddKey("Q"); + kc.AddKey("W"); + kc.AddKey("E"); + kc.AddKey("R"); + kc.AddKey("T"); + kc.AddKey("Y"); + kc.AddKey("U"); + kc.AddKey("I"); + kc.AddKey("O"); + kc.AddKey("P"); + kc.AddKey("Backspace", info: "{BACKSPACE}", width: 21); + + kc.AddLine(); + kc.AddSpace(4); + + kc.AddKey("A"); + kc.AddKey("S"); + kc.AddKey("D"); + kc.AddKey("F"); + kc.AddKey("G"); + kc.AddKey("H"); + kc.AddKey("J"); + kc.AddKey("K"); + kc.AddKey("L"); + kc.AddKey("'"); + kc.AddKey("Enter", info: "{ENTER}", width: 17); + + kc.AddLine(); + + kc.AddKey("Shift", info: "", style: KeyStyle.Toggled, layout: 0); + kc.AddKey("Z"); + kc.AddKey("X"); + kc.AddKey("C"); + kc.AddKey("V"); + kc.AddKey("B"); + kc.AddKey("N"); + kc.AddKey("M"); + kc.AddKey(","); + kc.AddKey("."); + kc.AddKey("?"); + kc.AddKey("Shift", info: "", style: KeyStyle.Toggled, layout: 0); + + kc.AddLine(); + + kc.AddKey("Ctrl", info: "", style: KeyStyle.Dark, layout: 2); + kc.AddKey("&123", info: "", style: KeyStyle.Dark, layout: 3); + kc.AddKey(":-)", info: ":-{)}", style: KeyStyle.Dark); + kc.AddKey(" ", width: 76); + kc.AddKey("<", info: "+{LEFT}", style: KeyStyle.Dark); + kc.AddKey(">", info: "+{RIGHT}", style: KeyStyle.Dark); + + #endregion + + return keyboard; + } + } + + /// + /// Contains a collection of Key objects. + /// + public class KeysCollection : Collection + { + + } + + /// + /// Contains a collection of KeyboardLayout objects. + /// + public class KeyboardLayoutsCollection : Collection + { + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/KeyboardControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/KeyboardControl.cs new file mode 100644 index 00000000..efa021ce --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/KeyboardControl.cs @@ -0,0 +1,874 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Collections; +using System.Runtime.InteropServices; +using DevComponents.DotNetBar.Touch; + + +namespace DevComponents.DotNetBar.Keyboard +{ + /// + /// Represents virtual keyboard control. + /// + [ToolboxItem(true)] + public class KeyboardControl : Control + { + private TouchHandler _TouchHandler = null; + /// + /// Creates a new VirtualKeyboard control. + /// + public KeyboardControl() + { + _ColorTable = _DefaultColorTable; + + // Do not allow the control to receive focus. + SetStyle(ControlStyles.Selectable, false); + + // Do not call OnPaintBackground(). + SetStyle(ControlStyles.Opaque, true); + + // Enable double buffering. OptimizedDoubleBuffer and AllPaintingInWmPaint are set by the DoubleBuffered property below. + //SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + //SetStyle(ControlStyles.AllPaintingInWmPaint, true); + + DoubleBuffered = true; + + ResizeRedraw = true; + + _RepeatTimer = new Timer(); + _RepeatTimer.Tick += new EventHandler(RepeatTimer_Tick); + } + + // The model for the Keyboard. This object contains all the information about the keys + // and the possible layouts of the keyboard. + private Keyboard _Keyboard = null; //Keyboard.CreateDefaultKeyboard(); + + /// + /// Gets or sets the Keyboard object that describes the VirtualKeyboard. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Keyboard Keyboard + { + get + { + if(_Keyboard==null) + _Keyboard = Keyboard.CreateDefaultKeyboard(); + return _Keyboard; + } + set { _Keyboard = value; } + } + + /// + /// Default width for the keyboard in pixels. + /// + public static int DefaultWidth + { + get { return 740; } + } + + /// + /// Default height for the keyboard in pixels. + /// + public static int DefaultHeight { + get { return 250; } + } + + protected override Size DefaultSize + { + get + { + return Dpi.Size(new Size(DefaultWidth, DefaultHeight)); + } + } + + + private VirtualKeyboardColorTable _DefaultColorTable = new VirtualKeyboardColorTable(); + + private VirtualKeyboardColorTable _ColorTable; + /// + /// Gets or set the ColorTable used to draw the keyboard. + /// + public VirtualKeyboardColorTable ColorTable + { + get { return _ColorTable; } + set + { + _ColorTable = value; + Invalidate(); // Ok to invalidate entire control, to render everything with the new colors. + } + } + + + private Renderer _Renderer = new FlatStyleRenderer(); + /// + /// Gets or sets the Renderer used to render the keyboard. + /// + public Renderer Renderer + { + get { return _Renderer; } + set + { + if (value == null) + value = new FlatStyleRenderer(); + _Renderer = value; + Invalidate(); // Ok to invalidate entire control, to redraw everything with the new renderer. + } + } + + // Through this method, the keys generated by the Virtual Keyboard are sent to the target control. + // In this version, the current target control is always the control with input focus and the keyboard + // is only visible when the control (to which the keyboard was previously attached) has input focus. + // Therefore, SendKeys.Send offers all the logic needed for this version of the keyboard. + // + // For future versions, we might consider using the Win32 API SendInput function for greater flexibility. + private void SendKeysToTarget(string info) + { + KeyboardKeyCancelEventArgs cancelArgs = new KeyboardKeyCancelEventArgs(info); + OnSendingKey(cancelArgs); + if (cancelArgs.Cancel) return; + SendKeys.Send(info); + OnKeySent(new KeyboardKeyEventArgs(info)); + } + + + #region Send repeating key if mouse is hold down + + private Timer _RepeatTimer; // Used to send repeated keys to the target control. + private Key _PressedKey; // Used to keep the keys that is repeatedly sent to the target control. + + private void RepeatTimer_Tick(object sender, EventArgs e) + { + if (_PressedKey != null) + { + if (_RepeatTimer.Interval == KeyboardDelay) + _RepeatTimer.Interval = KeyboardSpeed; + SendKeysToTarget(_PressedKey.Info); + } + } + + + private void CancelRepeatKey() + { + _PressedKey = null; + _RepeatTimer.Stop(); + } + + + private void StartRepeatKey(Key key) + { + _PressedKey = key; + _RepeatTimer.Start(); + _RepeatTimer.Interval = KeyboardDelay; + } + + + private static int KeyboardDelay + { + get + { + // SystemInformation.KeyboardDelay is between 0 (2.5 repetitions per second) and 31 (about 30 per second) + // but these values arre hardware dependendant, so the fomula below is a fast and accurate enough not to feel + // any difference between this and a real keyboard at the same values. + return 1000 / (SystemInformation.KeyboardDelay + 1); + } + } + + + private static int KeyboardSpeed + { + get + { + // See KeyboardDelay for details. + return 1000 / (SystemInformation.KeyboardSpeed + 1); + } + } + + #endregion + + private bool _IsTopBarVisible = true; + /// + /// Gets or sets a value indicating if the top bar of the keyboard is visible. + /// + [DefaultValue(true)] + [Description("Indicates if the top bar of the keyboard is visible.")] + [Category("Appearance")] + public bool IsTopBarVisible + { + get { return _IsTopBarVisible; } + set + { + _IsTopBarVisible = value; + this.Invalidate(); + } + } + + private int _CaptionHeight = 20; + /// + /// Indicates the height of the keyboard caption which hosts the close button. + /// + [DefaultValue(20), Category("Appearance"), Description("Indicates the height of the keyboard caption which hosts the close button.")] + public int CaptionHeight + { + get { return _CaptionHeight; } + set + { + if (value != _CaptionHeight) + { + int oldValue = _CaptionHeight; + _CaptionHeight = value; + this.Invalidate(); + } + } + } + + //private const int TopBarHeight = 20; + + private int TopBarVisibleHeight + { + get { return IsTopBarVisible ? ActualCaptionHeight + Border : 0; } + } + + public int Border { + get { return Dpi.Width10; } + } + + private readonly Key HideKeyboardKey = new Key("Hide", info: null); + + private int ActualCaptionHeight + { + get { return Dpi.Height(_CaptionHeight); } + } + private Rectangle TopBarRectangle + { + get { return new Rectangle(Border, Border, Width - 2 * Border, ActualCaptionHeight); } + } + + private Rectangle CloseButtonRectangle + { + get { return new Rectangle(Width - ActualCaptionHeight - Border, Border, ActualCaptionHeight, ActualCaptionHeight); } + } + + private Rectangle KeysRectangle + { + get + { + Rectangle rect = new Rectangle(Border, Border, Width - 2 * Border, Height - 2 * Border); + if (IsTopBarVisible) + { + rect.Y += ActualCaptionHeight + Border; + rect.Height -= ActualCaptionHeight + Border; + } + return rect; + } + } + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + Dpi.SetScaling(factor); + base.ScaleControl(factor, specified); + } + + protected override void OnPaint(PaintEventArgs e) + { + KeyboardLayout currentLayout = Keyboard.CurrentLayout; + + if (currentLayout.LogicalWidth <= 0 || currentLayout.LogicalHeight <= 0) + return; + + Rectangle rectKeys = KeysRectangle; + + float sfx = (float)rectKeys.Width / currentLayout.LogicalWidth; + float sfy = (float)rectKeys.Height / currentLayout.LogicalHeight; + + Renderer.ColorTable = ColorTable; + + Renderer.BeginFrame(new BeginFrameRendererEventArgs(e.Graphics, e.ClipRectangle, rectKeys, Font, currentLayout)); + + Renderer.DrawBackground(new BackgroundRendererEventArgs(e.Graphics, e.ClipRectangle, new Rectangle(0, 0, Width, Height))); + + if (IsTopBarVisible) + { + Renderer.DrawTopBar(new TopBarRendererEventArgs(e.Graphics, e.ClipRectangle, TopBarRectangle, Text, Font)); + Renderer.DrawCloseButton(new CloseButtonRendererEventArgs(e.Graphics, _PressedKey == HideKeyboardKey, e.ClipRectangle, CloseButtonRectangle)); + } + + foreach (Key key in currentLayout.Keys) + { + Rectangle rectKey = new Rectangle((int)(key.Bounds.X * sfx), (int)(key.Bounds.Y * sfy), + (int)(key.Bounds.Width * sfx), (int)(key.Bounds.Height * sfy)); + + rectKey.Offset(rectKeys.Left, rectKeys.Top); + + Renderer.DrawKey(new KeyRendererEventArgs(e.Graphics, key, key == _PressedKey, e.ClipRectangle, rectKey)); + } + + Renderer.EndFrame(); + +#if TRIAL + using (Font font = new System.Drawing.Font(this.Font.FontFamily, 7, FontStyle.Regular)) + { + using (SolidBrush brush = new SolidBrush(Color.FromArgb(24, Color.White))) + e.Graphics.DrawString("DotNetBar Trial Version", font, brush, (this.ClientRectangle.Width - 80) / 2, this.ClientRectangle.Height - 32); + } +#endif + } + + private void PerformMoveAction(Point location) + { + if (IsTopBarVisible && CloseButtonRectangle.Contains(location)) + { + Cursor = Cursors.Hand; + } + else + { + KeyboardLayout currentLayout = Keyboard.CurrentLayout; + Rectangle rectKeys = KeysRectangle; + + float fx = (float)rectKeys.Width / currentLayout.LogicalWidth; + float fy = (float)rectKeys.Height / currentLayout.LogicalHeight; + + if (_PressedKey == HideKeyboardKey) + { + if (_PressedKey != null) + { + Invalidate(GetKeyPhysicalBounds(_PressedKey, fx, fy)); + } + _PressedKey = null; + Invalidate(CloseButtonRectangle); + this.Update(); + } + + Key key = null; + + if (KeysRectangle.Contains(location)) + key = currentLayout.KeyHitTest((int)((location.X - rectKeys.Left) / fx), (int)((location.Y - rectKeys.Top) / fy)); + + // If the mouse is over a key, change the cursor to the Hand cursor, to provide + // a visual feedback for the user to know that it can interact with this key. + Key pressedKey = _PressedKey; + if (key == null) + { + Cursor = Cursors.Arrow; + CancelRepeatKey(); + + if (pressedKey != null) + { + Invalidate(GetKeyPhysicalBounds(pressedKey, fx, fy)); // Only invalidate area under the currently pressed key. + this.Update(); + } + } + else if (key != pressedKey) + { + Cursor = Cursors.Hand; + CancelRepeatKey(); + if (pressedKey != null) + { + Invalidate(GetKeyPhysicalBounds(pressedKey, fx, fy)); // Only invalidate area under the currently pressed key. + this.Update(); + } + } + else + { + Cursor = Cursors.Hand; + } + } + } + protected override void OnMouseMove(MouseEventArgs e) + { + if (ProcessMouseAction) + { + PerformMoveAction(e.Location); + _LastTouchAction = null; + } + base.OnMouseMove(e); + } + + + protected override void OnMouseLeave(EventArgs e) + { + KeyboardLayout currentLayout = Keyboard.CurrentLayout; + Rectangle rectKeys = KeysRectangle; + + float fx = (float)rectKeys.Width / currentLayout.LogicalWidth; + float fy = (float)rectKeys.Height / currentLayout.LogicalHeight; + + if (_PressedKey != HideKeyboardKey) + Invalidate(CloseButtonRectangle); + else if (_PressedKey != null) + { + Invalidate(GetKeyPhysicalBounds(_PressedKey, fx, fy)); // Only invalidate area under the currently pressed key. + this.Update(); + } + + CancelRepeatKey(); + } + + private bool _TouchEnabled = true; + /// + /// Indicates whether touch support is enabled when provided by hardware. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether touch support is enabled when provided by hardware.")] + public bool TouchEnabled + { + get { return _TouchEnabled; } + set + { + if (value != _TouchEnabled) + { + bool oldValue = _TouchEnabled; + _TouchEnabled = value; + OnTouchEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when TouchEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTouchEnabledChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TouchEnabled")); + } + + protected override void OnHandleCreated(EventArgs e) + { + if (TouchHandler.IsTouchEnabled) + { + _TouchHandler = new TouchHandler(this, eTouchHandlerType.Touch); + _TouchHandler.TouchDown += new EventHandler(TouchHandlerTouchDown); + _TouchHandler.TouchUp += new EventHandler(TouchHandlerTouchUp); + // Don't need touch move action for keyboard handling + //_TouchHandler.TouchMove += new EventHandler(TouchHandlerTouchMove); + } + base.OnHandleCreated(e); + } + + private DateTime? _LastTouchAction = null; + //void TouchHandlerTouchMove(object sender, TouchEventArgs e) + //{ + // PerformMoveAction(e.Location); + // _LastTouchAction = DateTime.Now; + //} + void TouchHandlerTouchUp(object sender, TouchEventArgs e) + { + if (_TouchEnabled) + { + // Process keybaord hiding through the MouseUp event instead of touch event since if closed using touch the mouse up will occur on control + // which is under keyboard after keyboard is hidden which is not desired + if (IsTopBarVisible && CloseButtonRectangle.Contains(e.Location)) + { + _LastTouchAction = null; + return; + } + PerformUpAction(e.Location); + _LastTouchAction = DateTime.Now; + } + } + void TouchHandlerTouchDown(object sender, TouchEventArgs e) + { + if (_TouchEnabled) + { + PerformDownAction(e.Location); + _LastTouchAction = DateTime.Now; + } + } + + /// + /// Returns the Key at given location. Location expected is in control coordinates. + /// + /// Location is control coordinates. + /// Key if there is a key at given location or null/nothing if no key exists at given location. + public Key HitTest(Point location) + { + KeyboardLayout currentLayout = Keyboard.CurrentLayout; + Rectangle rectKeys = KeysRectangle; + + float fx = (float)rectKeys.Width / currentLayout.LogicalWidth; + float fy = (float)rectKeys.Height / currentLayout.LogicalHeight; + + Key key = null; + if (KeysRectangle.Contains(location)) + key = currentLayout.KeyHitTest((int)((location.X - rectKeys.Left) / fx), (int)((location.Y - rectKeys.Top) / fy)); + + return key; + } + + private void PerformDownAction(Point location) + { + if (_PressedKey != null) // This can happen because multi-touch can send multiple down messages + { + PerformUpAction(location); + } + + if (IsTopBarVisible && CloseButtonRectangle.Contains(location)) + { + _PressedKey = HideKeyboardKey; + Invalidate(CloseButtonRectangle); + } + else + { + KeyboardLayout currentLayout = Keyboard.CurrentLayout; + Rectangle rectKeys = KeysRectangle; + + float fx = (float)rectKeys.Width / currentLayout.LogicalWidth; + float fy = (float)rectKeys.Height / currentLayout.LogicalHeight; + + Key key = HitTest(location); + + if (key != null) + { + TimeSpan ts = DateTime.Now.Subtract(_LastMouseUpEvent); + if (_LastKeyUp != null && key.Caption == _LastKeyUp.Caption && ts < TimeSpan.FromMilliseconds(SystemInformation.DoubleClickTime) && key.ChangeToLayoutEx >= 0) + { + Keyboard.CurrentLayoutIndex = key.ChangeToLayoutEx; + _LastMouseUpEvent = DateTime.MinValue; + Invalidate(); + } + else + { + _PressedKey = key; + + if (_PressedKey.Info != null && _PressedKey.Info != "") + { + StartRepeatKey(key); + SendKeysToTarget(key.Info); + } + } + Invalidate(GetKeyPhysicalBounds(key, fx, fy)); // Only invalidate area under the currently pressed key. + } + } + this.Update(); + } + + private int TouchMouseInputFilterDelay = 2000; + private bool ProcessMouseAction + { + get + { + return _LastTouchAction == null || + (_LastTouchAction != null && DateTime.Now.Subtract(_LastTouchAction.Value).TotalMilliseconds > TouchMouseInputFilterDelay); + } + } + protected override void OnMouseDown(MouseEventArgs e) + { + if (ProcessMouseAction) + { + PerformDownAction(e.Location); + _LastTouchAction = null; + } + base.OnMouseDown(e); + } + + private DateTime _LastMouseUpEvent = DateTime.MinValue; + private Key _LastKeyUp = null; + + private void PerformUpAction(Point location) + { + if (IsTopBarVisible && CloseButtonRectangle.Contains(location)) + { + if (_PressedKey == HideKeyboardKey) + { + HideKeyboard(); + _PressedKey = null; + } + CancelRepeatKey(); + } + else + { + Key pressedKey = _PressedKey; + CancelRepeatKey(); + if (pressedKey != null) + { + KeyboardLayout currentLayout = Keyboard.CurrentLayout; + Rectangle rectKeys = KeysRectangle; + + float fx = (float)rectKeys.Width / currentLayout.LogicalWidth; + float fy = (float)rectKeys.Height / currentLayout.LogicalHeight; + + _LastMouseUpEvent = DateTime.Now; + _LastKeyUp = pressedKey; + + if (pressedKey.ChangeToLayout >= 0) + { + Keyboard.CurrentLayoutIndex = pressedKey.ChangeToLayout; + Invalidate(); // Ok to invalidate entire control because we need to draw a whole new layout. + } + else if (pressedKey.ChangeToLayout == KeyboardLayout.PreviousLayout) + { + Keyboard.ChangeToPreviousLayout(); + Invalidate(); // Ok to invalidate entire control because we need to draw a whole new layout. + } + else + { + Invalidate(GetKeyPhysicalBounds(pressedKey, fx, fy)); // Only invalidate area under the currently pressed key. + } + } + } + this.Update(); + } + protected override void OnMouseUp(MouseEventArgs e) + { + if (ProcessMouseAction) + { + PerformUpAction(e.Location); + base.OnMouseUp(e); + } + _LastTouchAction = null; + } + + private Rectangle GetKeyPhysicalBounds(Key key, float scaleFactorX, float scaleFactorY) + { + Rectangle r = key.Bounds; + + r.X = (int)(r.X * scaleFactorX) + Border; + r.Y = (int)(r.Y * scaleFactorY) + Border + TopBarVisibleHeight; + r.Width = (int)(r.Width * scaleFactorX); + r.Height = (int)(r.Height * scaleFactorY); + + return r; + } + + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_DefaultColorTable != null) + _DefaultColorTable.Dispose(); + if (_RepeatTimer != null) + _RepeatTimer.Dispose(); + } + + base.Dispose(disposing); + } + + + /// + /// Attaches the Keyboard to the specified control. The keyboard will automatically appear when the control receives input focus. + /// + /// The control to which the Keyboard will be attached. + public void AttachTo(Control control) + { + control.GotFocus += new EventHandler(control_GotFocus); + control.LostFocus += new EventHandler(control_LostFocus); + } + + + /// + /// Detaches the Keyboard from the specified control. + /// + /// The control from which the Keyboard will be detached. + public void DetachFrom(Control control) + { + control.GotFocus -= new EventHandler(control_GotFocus); + control.LostFocus -= new EventHandler(control_LostFocus); + } + + public void UnlockCapsLock() + { + if (Control.IsKeyLocked(Keys.CapsLock)) + { + OSVERSIONINFO info=new OSVERSIONINFO(); + info.dwOSVersionInfoSize= System.Runtime.InteropServices.Marshal.SizeOf(typeof(OSVERSIONINFO)); + GetVersionEx(ref info); + byte[] keys= new byte[255]; + if(info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) // Win95/98 + { + keys[VK_CAPITAL] = 1; + SetKeyboardState(keys); + } + else if (info.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + // Simulate Key Press + keybd_event(VK_CAPITAL, 0X45, KEYEVENTF_EXTENDEDKEY | 0, 0); + // Simulate Key Release + keybd_event(VK_CAPITAL, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); + } + } + } + + void control_GotFocus(object sender, EventArgs e) + { + Show(); + } + + + void control_LostFocus(object sender, EventArgs e) + { + HideKeyboard(); + } + + private void HideKeyboard() + { + CancelEventArgs ce = new CancelEventArgs(); + OnKeyboardClosing(ce); + if (ce.Cancel) return; + + this.Hide(); + + OnKeyboardClosed(EventArgs.Empty); + } + + /// + /// Occurs before the keyboard is closed and allows canceling of keyboard closing. + /// + [Description("Occurs before the keyboard is closed and allows canceling of keyboard closing.")] + public event CancelEventHandler KeyboardClosing; + /// + /// Raises KeyboardClosing event. + /// + /// Provides event arguments. + protected virtual void OnKeyboardClosing(CancelEventArgs e) + { + CancelEventHandler handler = KeyboardClosing; + if (handler != null) + handler(this, e); + } + + /// + /// Occurs after keyboard is closed. + /// + [Description("Occurs after keyboard is closed.")] + public event EventHandler KeyboardClosed; + /// + /// Raises KeyboardClosed event. + /// + /// Provides event arguments. + protected virtual void OnKeyboardClosed(EventArgs e) + { + EventHandler handler = KeyboardClosed; + if (handler != null) + handler(this, e); + } + /// + /// Occurs before the key pressed on keyboard is sent to target control and allows cancellation of the message + /// + [Description("Occurs before the key pressed on keyboard is sent to target control and allows cancellation of the message.")] + public event KeyCancelEventHandler SendingKey; + /// + /// Raises SendingKey event. + /// + /// Provides event arguments. + protected virtual void OnSendingKey(KeyboardKeyCancelEventArgs e) + { + KeyCancelEventHandler handler = SendingKey; + if (handler != null) + handler(this, e); + } + /// + /// Occurs after the key is sent to target control. + /// + [Description("Occurs after the key is sent to target control.")] + public event KeyEventHandler KeySent; + /// + /// Raises KeySent event. + /// + /// Provides event arguments. + protected virtual void OnKeySent(KeyboardKeyEventArgs e) + { + KeyEventHandler handler = KeySent; + if (handler != null) + handler(this, e); + } + + protected override void OnTextChanged(EventArgs e) + { + this.Invalidate(); + base.OnTextChanged(e); + } + + #region Windows API + // Declare Type for API call: + [StructLayout(LayoutKind.Sequential)] + internal struct OSVERSIONINFO + { + public int dwOSVersionInfoSize; + public int dwMajorVersion; + public int dwMinorVersion; + public int dwBuildNumber; + public int dwPlatformId; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public string szCSDVersion; + } + // Constant declarations: + const int VK_CAPITAL = 0x14; + const int KEYEVENTF_EXTENDEDKEY = 1; + const int KEYEVENTF_KEYUP = 2; + const int VER_PLATFORM_WIN32_NT = 2; + const int VER_PLATFORM_WIN32_WINDOWS = 1; + + + // API declarations: + [DllImport("kernel32.Dll")] + private static extern short GetVersionEx(ref OSVERSIONINFO o); + + [DllImport("user32.dll")] + static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo); + + [DllImport("user32.dll")] + static extern bool SetKeyboardState(byte[] lpKeyState); + #endregion + } + + /// + /// Defines delegate for key-related events. + /// + /// + /// + public delegate void KeyEventHandler(object sender, KeyboardKeyEventArgs e); + /// + /// Provides data for key related events. + /// + public class KeyboardKeyEventArgs : EventArgs + { + /// + /// Gets the key being pressed. The format of this information + /// must confirm to the description for the SendKeys.Send function. For more details, see: + /// http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx + /// + public readonly string Key; + /// + /// Initializes a new instance of the KeyboardKeyEventArgs class. + /// + /// + public KeyboardKeyEventArgs(string key) + { + Key = key; + } + } + + /// + /// Defines delegate for key-related events. + /// + /// + /// + public delegate void KeyCancelEventHandler(object sender, KeyboardKeyCancelEventArgs e); + /// + /// Provides data for key related events. + /// + public class KeyboardKeyCancelEventArgs : CancelEventArgs + { + /// + /// Gets the key being pressed. The format of this information + /// must confirm to the description for the SendKeys.Send function. For more details, see: + /// http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx + /// + public readonly string Key; + /// + /// Initializes a new instance of the KeyCancelEventArgs class. + /// + /// + public KeyboardKeyCancelEventArgs(string key) + { + Key = key; + } + } + + + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/KeyboardControl.ico b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/KeyboardControl.ico new file mode 100644 index 00000000..e82c50f9 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/KeyboardControl.ico differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/PopupVirtualKeyboard.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/PopupVirtualKeyboard.cs new file mode 100644 index 00000000..2edbc112 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/PopupVirtualKeyboard.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Keyboard +{ + internal class PopupVirtualKeyboard : Form + { + /// + /// Creates a new floating virtual keyboard. + /// + public PopupVirtualKeyboard() + { + StartPosition = FormStartPosition.Manual; + + // Make sure the popup window does not appear in the taskbar. + ShowInTaskbar = false; + + MinimizeBox = false; + MaximizeBox = false; + //ControlBox = false; + } + + + #region Window activation handling + + // We need to prevent the keyboard window from activating, otherwise will still focus from our target control. + // Also to achieve this effect, there must be no focusable control in the popup window. + + private const int WM_MOUSEACTIVATE = 0x0021; + private const int MA_NOACTIVATE = 0x0003; + private const int WS_EX_NOACTIVATE = 0x08000000; + + // Override CreateParams to specify that this Form should not be activated. + protected override CreateParams CreateParams + { + get + { + CreateParams createParams = base.CreateParams; + createParams.ExStyle = createParams.ExStyle & WS_EX_NOACTIVATE; + return createParams; + } + } + + + protected override void WndProc(ref Message m) + { + // This prevents the window from being activated with the mouse, + // but allows the window to be resized (with the mouse). + if (m.Msg == WM_MOUSEACTIVATE) + { + m.Result = (IntPtr)MA_NOACTIVATE; + } + else + { + base.WndProc(ref m); + } + } + + + protected override void OnActivated(EventArgs e) + { + Owner.Activate(); + } + + #endregion + + + protected override void OnClosing(CancelEventArgs e) + { + // Cancel the Closing event as this will Dispose the form. + e.Cancel = true; + Hide(); + } + + + protected override void OnVisibleChanged(EventArgs e) + { + base.OnVisibleChanged(e); + + if (Visible && CurrentControl != _LastControl && CurrentControl != null) + { + _LastControl = CurrentControl; + } + } + + + internal Control CurrentControl { get; set; } + private Control _LastControl; + /* + public void MoveNearControl(Control control) + { + // We want to show the keyboard near the target control, horizontally centered, + // under the control or above it and without overlapping it, if possible. + + // First try to position the Keyboard under the target control. + Point location = control.PointToScreen(Point.Empty); + location.Offset(control.Width / 2 - Width / 2, control.Height); + Location = location; + + // And make sure it is in the screen containing the control. + EnsureInScreen(control); + + // Now check if this position does not overlap the control. + if (!OverlapsControl(control)) + return; + + // Now we try to position the Keyboard above the control. + location = control.PointToScreen(Point.Empty); + location.Offset(control.Width / 2 - Width / 2, -Height); + Location = location; + + // And again make sure this location is in the screen with the control. + EnsureInScreen(control); + + // And check if it does not overlap the control. + if (!OverlapsControl(control)) + return; + + // If both below and above the control was not a good position, then this means the + // target control is quite large, so show the Keyboard inside it. + location = control.PointToScreen(Point.Empty); + location.Offset(control.Width / 2 - Width / 2, control.Height / 2 - Height / 2); + + // And again, make sure the Keybboard is not clipped by the screen. + EnsureInScreen(control); + } + + /// + /// Returns true if the Keyboard overlaps the specified control. + /// + /// The control for which to check if it is overlapped by the Keyboard. + /// + private bool OverlapsControl(Control control) + { + Rectangle rect = new Rectangle(control.PointToScreen(Point.Empty), control.Size); + return rect.IntersectsWith(Bounds); + } + + /// + /// Checks if the Keyboard is in the screen containing the specified control, and if + /// the Keyboard is not fully visible, adjusts it's location accordingly. + /// + /// The control from which the screen is checked. If null, the primary screen is used. + private void EnsureInScreen(Control control) + { + Screen screen = Screen.PrimaryScreen; + + if(control != null) + screen = Screen.FromControl(control); + + Rectangle rect = screen.WorkingArea; + + if (Location.X < rect.Left) + Location = new Point(rect.Left, Location.Y); + + if (Location.Y < rect.Top) + Location = new Point(Location.X, rect.Top); + + if (Bounds.Right > rect.Right) + Location = new Point(rect.Right - Width, Location.Y); + + if (Bounds.Bottom > rect.Bottom) + Location = new Point(Location.X, rect.Bottom - Height); + } + */ + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Renderer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Renderer.cs new file mode 100644 index 00000000..0db151dd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Renderer.cs @@ -0,0 +1,546 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Diagnostics; +using System.Windows.Forms; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Keyboard +{ + /// + /// Represents a renderer for a VirtualKeyboard. + /// + public abstract class Renderer + { + private VirtualKeyboardColorTable _ColorTable; + /// + /// Gets or sets the ColorTable used by this renderer to render the virtual keyboard. + /// + public VirtualKeyboardColorTable ColorTable + { + get { return _ColorTable; } + set { _ColorTable = value; } + } + + /// + /// Draws the top bar of the VirtualKeyboard. + /// + /// + public abstract void DrawTopBar(TopBarRendererEventArgs args); + + + public abstract void DrawCloseButton(CloseButtonRendererEventArgs args); + + /// + /// Draws the background of the VirtualKeyboard. + /// + /// Provides context information. + public abstract void DrawBackground(BackgroundRendererEventArgs args); + + /// + /// Draws a key of the VirtualKeyboard. + /// + /// Provides context information. + public abstract void DrawKey(KeyRendererEventArgs args); + + /// + /// Called when the control starts rendering a new frame. + /// + /// Provides context information. + public virtual void BeginFrame(BeginFrameRendererEventArgs args) { } + + /// + /// Called after the control finished rendering the frame. + /// + public virtual void EndFrame() { } + } + + + /// + /// Represents a VirtualKeyboard renderer with a flat style. + /// + public class FlatStyleRenderer : Renderer + { + // The ratio between the key size and the font that displays the letters on the keys. + private const float _KeyFontSizeRatio = 4; + + // The ratio between the key size and the font that displays the hints (e.g. Underline, Italic) on the keys. + private const float _HintFontSizeRatio = 7; + + private StringFormat _CenteredTextStringFormat; + private StringFormat _TopCenteredTextStringFormat; + private float _ScaleFactorX; + private float _ScaleFactorY; + private Font _KeyFont; + private Font _HintFont; + private Rectangle _KeysBounds; + + private static VirtualKeyboardColorTable _DefaultColorTable = new VirtualKeyboardColorTable(); + + + /// + /// Gets or sets whether anti-alias smoothing is used while painting. Default value is true. + /// + public bool ForceAntiAlias { get; set; } + + + /// + /// Starts rendering a new frame with the black style. This gives the renderer a chance to cash some resources. + /// + public override void BeginFrame(BeginFrameRendererEventArgs args) + { + _CenteredTextStringFormat = new StringFormat(); + _CenteredTextStringFormat.Alignment = StringAlignment.Center; + _CenteredTextStringFormat.LineAlignment = StringAlignment.Center; + + _TopCenteredTextStringFormat = new StringFormat(); + _TopCenteredTextStringFormat.Alignment = StringAlignment.Center; + _TopCenteredTextStringFormat.LineAlignment = StringAlignment.Near; + + // With this fx and fy we convert between logical units and pixels. + _ScaleFactorX = (float)args.Bounds.Width / args.Layout.LogicalWidth; + _ScaleFactorY = (float)args.Bounds.Height / args.Layout.LogicalHeight; + + _KeysBounds = args.Bounds; + + float min = Math.Min(_ScaleFactorX, _ScaleFactorY); + + float keyFontSize = min * LinearKeyboardLayout.NormalKeySize / _KeyFontSizeRatio; + float hintFontSize = min * LinearKeyboardLayout.NormalKeySize / _HintFontSizeRatio; + + if (keyFontSize < 1) + keyFontSize = 1; + if (hintFontSize < 1) + hintFontSize = 1; + + _KeyFont = new Font(args.Font.FontFamily, keyFontSize); + _HintFont = new Font(args.Font.FontFamily, hintFontSize); + + if (ForceAntiAlias) + args.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; + } + + + /// + /// Ends rendering a new frame with the black style. This gives the renderer a chance to free resources used during the frame. + /// + public override void EndFrame() + { + if (_CenteredTextStringFormat != null) + _CenteredTextStringFormat.Dispose(); + + if (_TopCenteredTextStringFormat != null) + _TopCenteredTextStringFormat.Dispose(); + + if (_KeyFont != null) + _KeyFont.Dispose(); + + if (_HintFont != null) + _HintFont.Dispose(); + } + + + /// + /// Creates a new renderer for the black style. + /// + public FlatStyleRenderer() + { + ColorTable = _DefaultColorTable; + } + + + /// + /// Draws the background of a VirtualKeyboard. + /// + /// Provides context information. + public override void DrawBackground(BackgroundRendererEventArgs args) + { + if (ColorTable != null) + args.Graphics.FillRectangle(ColorTable.BackgroundBrush, args.ClipRectangle); + } + + + internal static void DrawBackspaceSign(Graphics g, Rectangle rect, Brush background, Brush foreground) + { + SmoothingMode osm = g.SmoothingMode; // old smoothing mode, to restore it at the end. + g.SmoothingMode = SmoothingMode.AntiAlias; + + int unit = Math.Min(rect.Width, rect.Height); + + Point[] points = new Point[] + { + new Point(-2 * unit, 0), + new Point(-1 * unit, -1 * unit), + new Point(2 * unit, -1 * unit), + new Point(2 * unit, 1 * unit), + new Point(-1 * unit, 1 * unit), + new Point(-2 * unit, 0) + }; + + g.TranslateTransform(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); + g.ScaleTransform(0.125f, 0.125f); + + g.FillPolygon(foreground, points); + + g.ScaleTransform(8, 8); + + + g.ScaleTransform(0.125f, 0.125f); + g.TranslateTransform(unit / 2, 0); + + using (Pen p = new Pen(background, unit * 8 / 20)) + { + g.DrawLine(p, -unit / 2, -unit / 2, unit / 2, unit / 2); + g.DrawLine(p, -unit / 2, unit / 2, unit / 2, -unit / 2); + } + + g.TranslateTransform(-unit / 2, 0); + g.ScaleTransform(8, 8); + + g.TranslateTransform(-(rect.Left + rect.Width / 2), -(rect.Top + rect.Height / 2)); + g.SmoothingMode = osm; + } + + + internal static void DrawSmileySign(Graphics g, Rectangle rect, Brush background, Brush foreground) + { + SmoothingMode osm = g.SmoothingMode; // old smoothing mode, to restore it at the end. + g.SmoothingMode = SmoothingMode.AntiAlias; + + int unit = Math.Min(rect.Width, rect.Height) * 2 / 5; + float u = unit / 20f; + + PointF[] points = new PointF[] + { + new PointF(-5, 0), + new PointF(-7, 1), + new PointF(-6, 5), + new PointF(-2, 8), + new PointF(2, 8), + new PointF(6, 5), + new PointF(7, 1), + new PointF(5, 0), + new PointF(0, 2) + }; + + for (int i = 0; i < points.Length; i++) + { + points[i].X *= u; + points[i].Y *= u; + } + + g.TranslateTransform(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); + + g.FillEllipse(foreground, new Rectangle(-unit / 2, -unit / 2, unit, unit)); + + g.FillClosedCurve(background, points, System.Drawing.Drawing2D.FillMode.Winding, 0.5f); + + g.FillEllipse(background, new Rectangle((int)(-7 * u), (int)(-7 * u), (int)(5 * u), (int)(5 * u))); + g.FillEllipse(background, new Rectangle((int)(2 * u), (int)(-7 * u), (int)(5 * u), (int)(5 * u))); + + g.TranslateTransform(-(rect.Left + rect.Width / 2), -(rect.Top + rect.Height / 2)); + + g.SmoothingMode = osm; + } + + + internal static void DrawUpArrow(Graphics g, Rectangle rect, Brush background, Brush foreground) + { + SmoothingMode osm = g.SmoothingMode; // old smoothing mode, to restore it at the end. + g.SmoothingMode = SmoothingMode.AntiAlias; + + int unit = Math.Min(rect.Width, rect.Height) / 2 / 4; + + g.TranslateTransform(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); + + using (Pen p = new Pen(foreground, unit / 2f)) + { + g.DrawLine(p, 0, -unit * 1.5f, 0, unit * 1.5f); + g.DrawLine(p, 0, -unit * 1.5f, -unit, 0); + g.DrawLine(p, 0, -unit * 1.5f, unit, 0); + } + + g.TranslateTransform(-(rect.Left + rect.Width / 2), -(rect.Top + rect.Height / 2)); + + g.SmoothingMode = osm; + } + + + + /// + /// Draws the key of a VirtualKeyboard. + /// + /// Provides context information. + public override void DrawKey(KeyRendererEventArgs args) + { + Key key = args.Key; + + if (ColorTable != null) + { + Rectangle rect = args.Bounds; + + if (args.ClipRectangle.IntersectsWith(rect)) + { + Brush keyBrush = ColorTable.KeysBrush; + if (key.Style == KeyStyle.Dark) + keyBrush = ColorTable.DarkKeysBrush; + else if (key.Style == KeyStyle.Light) + keyBrush = ColorTable.LightKeysBrush; + else if (key.Style == KeyStyle.Pressed) + keyBrush = ColorTable.PressedKeysBrush; + else if (key.Style == KeyStyle.Toggled) + keyBrush = ColorTable.KeysBrush; + + if (args.IsDown) + keyBrush = ColorTable.DownKeysBrush; + + Brush textBrush = ColorTable.TextBrush; + if (key.Style == KeyStyle.Toggled) + textBrush = ColorTable.ToggleTextBrush; + if (args.IsDown) + textBrush = ColorTable.DownTextBrush; + + args.Graphics.FillRectangle(keyBrush, rect); + + + if (key.Info == "{BACKSPACE}") + { + DrawBackspaceSign(args.Graphics, rect, keyBrush, textBrush); + } + else if (key.Caption == ":-)") + { + DrawSmileySign(args.Graphics, rect, keyBrush, textBrush); + } + else if (key.Caption == "Shift") + { + DrawUpArrow(args.Graphics, rect, keyBrush, textBrush); + } + else + { + args.Graphics.DrawString(key.Caption, _KeyFont, textBrush, rect, _CenteredTextStringFormat); + + if (key.Hint != null) + { + args.Graphics.DrawString(key.Hint, _HintFont, textBrush, rect, _TopCenteredTextStringFormat); + } + } + } + } + } + + + public override void DrawCloseButton(CloseButtonRendererEventArgs args) + { + Rectangle rect = args.Bounds; + rect.Inflate(-4, -4); + if (args.IsDown) + { + args.Graphics.FillRectangle(ColorTable.DownKeysBrush, args.Bounds); + using (Pen p = new Pen(ColorTable.DownTextBrush, 4)) + { + args.Graphics.DrawLine(p, rect.Left, rect.Top, rect.Right, rect.Bottom); + args.Graphics.DrawLine(p, rect.Left, rect.Bottom, rect.Right, rect.Top); + } + } + else + { + //args.Graphics.FillRectangle(ColorTable.KeysBrush, args.Bounds); + using (Pen p = new Pen(ColorTable.TextBrush, 4)) + { + args.Graphics.DrawLine(p, rect.Left, rect.Top, rect.Right, rect.Bottom); + args.Graphics.DrawLine(p, rect.Left, rect.Bottom, rect.Right, rect.Top); + } + } + + } + + + public override void DrawTopBar(TopBarRendererEventArgs args) + { + args.Graphics.DrawString(args.Text, args.Font, ColorTable.TopBarTextBrush, args.Bounds); + } + } + + + /// + /// Provides data for Key rendering. + /// + public class KeyRendererEventArgs : EventArgs + { + /// + /// Gets a reference to the Key instance being rendered. + /// + public Key Key { get; private set; } + + public Rectangle Bounds { get; private set; } + + /// + /// Gets a reference to the Graphics object to be used for rendering. + /// + public Graphics Graphics { get; private set; } + + /// + /// Gets a value indicating if this key is currently down. + /// + public bool IsDown { get; private set; } + + /// + /// Gets the rectangle in which to paint. + /// + public Rectangle ClipRectangle { get; private set; } + + /// + /// Creates a new instance and initializes it with provided values. + /// + /// The Graphics object to be used for rendering. + /// The Key instance being rendered. + /// Indicates if the key is currently hold down. + /// The rectangle in which to paint. + public KeyRendererEventArgs(Graphics graphics, Key key, bool isDown, Rectangle clipRectangle, Rectangle bounds) + { + Key = key; + Graphics = graphics; + IsDown = isDown; + ClipRectangle = clipRectangle; + Bounds = bounds; + } + } + + + /// + /// Provides data for rendering the background of a VirtualKeyboard. + /// + public class BackgroundRendererEventArgs : EventArgs + { + public Rectangle Bounds { get; private set; } + + /// + /// Gets a reference to the Graphics object to be used for rendering. + /// + public Graphics Graphics { get; private set; } + + /// + /// Gets the rectangle in which to paint. + /// + public Rectangle ClipRectangle { get; private set; } + + /// + /// Creates a new instance and initializes it with provided values. + /// + /// The Graphics object to be used for rendering. + /// The area where the background should be drawn. + public BackgroundRendererEventArgs(Graphics graphics, Rectangle clipRectangle, Rectangle bounds) + { + Graphics = graphics; + ClipRectangle = clipRectangle; + Bounds = bounds; + } + } + + + public class BeginFrameRendererEventArgs : EventArgs + { + /// + /// Gets a reference to the Graphics object to be used for rendering. + /// + public Graphics Graphics { get; private set; } + + /// + /// Gets the rectangle in which to paint. + /// + public Rectangle ClipRectangle { get; private set; } + + /// + /// Gets the size of the background area in which to render the keyboard. + /// + //public Size Size { get; private set; } + public Rectangle Bounds { get; private set; } + + /// + /// Gets the font on the control. + /// + public Font Font { get; private set; } + + /// + /// Gets the current KeyboardLayout which will be rendered in this frame. + /// + public KeyboardLayout Layout { get; private set; } + + /// + /// Creates a new instance and initializes it with provided values. + /// + /// The size of the background area. + /// The font of the control. + /// The current KeyboardLayout that will be rendered in this frame. + public BeginFrameRendererEventArgs(Graphics graphics, Rectangle clipRectangle, Rectangle bounds, Font font, KeyboardLayout layout) + { + Graphics = graphics; + ClipRectangle = clipRectangle; + Bounds = bounds; + Font = font; + Layout = layout; + } + } + + + public class TopBarRendererEventArgs : EventArgs + { + public string Text { get; private set; } + + public Rectangle Bounds { get; private set; } + + /// + /// Gets a reference to the Graphics object to be used for rendering. + /// + public Graphics Graphics { get; private set; } + + /// + /// Gets the rectangle in which to paint. + /// + public Rectangle ClipRectangle { get; private set; } + + /// + /// Gets the font on the control. + /// + public Font Font { get; private set; } + + public TopBarRendererEventArgs(Graphics graphics, Rectangle clipRectangle, Rectangle bounds, string text, Font font) + { + Graphics = graphics; + ClipRectangle = clipRectangle; + Bounds = bounds; + Text = text; + Font = font; + } + } + + + public class CloseButtonRendererEventArgs : EventArgs + { + public Rectangle Bounds { get; private set; } + + /// + /// Gets a reference to the Key instance being rendered. + /// + public Graphics Graphics { get; private set; } + + /// + /// Gets the area where background should be drawn. + /// + public Rectangle ClipRectangle { get; private set; } + + /// + /// Gets a value indicating if this key is currently down. + /// + public bool IsDown { get; private set; } + + public CloseButtonRendererEventArgs(Graphics graphics, bool isDown, Rectangle clipRectangle, Rectangle bounds) + { + Graphics = graphics; + ClipRectangle = clipRectangle; + Bounds = bounds; + IsDown = isDown; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Touch/TouchHandler.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Touch/TouchHandler.cs new file mode 100644 index 00000000..f33878f5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Touch/TouchHandler.cs @@ -0,0 +1,916 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Data; + +namespace DevComponents.DotNetBar.Touch +{ + internal class TouchHandler + { + #region Events + public event EventHandler PanBegin; + /// + /// Raises PanBegin event. + /// + /// Provides event arguments. + protected virtual void OnPanBegin(GestureEventArgs e) + { + EventHandler handler = PanBegin; + if (handler != null) + handler(this, e); + } + public event EventHandler PanEnd; + /// + /// Raises PanBegin event. + /// + /// Provides event arguments. + protected virtual void OnPanEnd(GestureEventArgs e) + { + EventHandler handler = PanEnd; + if (handler != null) + handler(this, e); + } + public event EventHandler Pan; + /// + /// Raises PanBegin event. + /// + /// Provides event arguments. + protected virtual void OnPan(GestureEventArgs e) + { + EventHandler handler = Pan; + if (handler != null) + handler(this, e); + } + + public event EventHandler Begin; + /// + /// Raises Begin event. + /// + /// Provides event arguments. + protected virtual void OnBegin(GestureEventArgs e) + { + EventHandler handler = Begin; + if (handler != null) + handler(this, e); + } + + public event EventHandler End; + /// + /// Raises End event. + /// + /// Provides event arguments. + protected virtual void OnEnd(GestureEventArgs e) + { + EventHandler handler = End; + if (handler != null) + handler(this, e); + } + + public event EventHandler PressAndTap; + /// + /// Raises PressAndTap event. + /// + /// Provides event arguments. + protected virtual void OnPressAndTap(GestureEventArgs e) + { + EventHandler handler = PressAndTap; + if (handler != null) + handler(this, e); + } + + public event EventHandler RotateBegin; + /// + /// Raises RotateBegin event. + /// + /// Provides event arguments. + protected virtual void OnRotateBegin(GestureEventArgs e) + { + EventHandler handler = RotateBegin; + if (handler != null) + handler(this, e); + } + + public event EventHandler Rotate; + /// + /// Raises Rotate event. + /// + /// Provides event arguments. + protected virtual void OnRotate(GestureEventArgs e) + { + EventHandler handler = Rotate; + if (handler != null) + handler(this, e); + } + + public event EventHandler RotateEnd; + /// + /// Raises RotateEnd event. + /// + /// Provides event arguments. + protected virtual void OnRotateEnd(GestureEventArgs e) + { + EventHandler handler = RotateEnd; + if (handler != null) + handler(this, e); + } + + public event EventHandler TwoFingerTap; + /// + /// Raises TwoFingerTap event. + /// + /// Provides event arguments. + protected virtual void OnTwoFingerTap(GestureEventArgs e) + { + EventHandler handler = TwoFingerTap; + if (handler != null) + handler(this, e); + } + + public event EventHandler ZoomBegin; + /// + /// Raises ZoomBegin event. + /// + /// Provides event arguments. + protected virtual void OnZoomBegin(GestureEventArgs e) + { + EventHandler handler = ZoomBegin; + if (handler != null) + handler(this, e); + } + + public event EventHandler Zoom; + /// + /// Raises Zoom event. + /// + /// Provides event arguments. + protected virtual void OnZoom(GestureEventArgs e) + { + EventHandler handler = Zoom; + if (handler != null) + handler(this, e); + } + + public event EventHandler ZoomEnd; + /// + /// Raises ZoomEnd event. + /// + /// Provides event arguments. + protected virtual void OnZoomEnd(GestureEventArgs e) + { + EventHandler handler = ZoomEnd; + if (handler != null) + handler(this, e); + } + + // Touch events + public event EventHandler TouchDown; + /// + /// Raises TouchDown event. + /// + /// Provides event arguments. + protected virtual void OnTouchDown(TouchEventArgs e) + { + EventHandler handler = TouchDown; + if (handler != null) + handler(this, e); + } + + public event EventHandler TouchUp; + /// + /// Raises TouchDown event. + /// + /// Provides event arguments. + protected virtual void OnTouchUp(TouchEventArgs e) + { + EventHandler handler = TouchUp; + if (handler != null) + handler(this, e); + } + + public event EventHandler TouchMove; + /// + /// Raises TouchDown event. + /// + /// Provides event arguments. + protected virtual void OnTouchMove(TouchEventArgs e) + { + EventHandler handler = TouchMove; + if (handler != null) + handler(this, e); + } + #endregion + + #region Constructor + private Control _ParentControl = null; + private eTouchHandlerType _HandlerType = eTouchHandlerType.Gesture; + /// + /// Initializes a new instance of the TouchHandler class. + /// + /// + public TouchHandler(Control parentControl) : this(parentControl, eTouchHandlerType.Gesture) { } + + /// + /// Initializes a new instance of the TouchHandler class. + /// + /// + public TouchHandler(Control parentControl, eTouchHandlerType handlerType) + { + _ParentControl = parentControl; + _HandlerType = handlerType; + if (IsTouchEnabled) + { + if (_ParentControl.IsHandleCreated) + Initialize(); + else + _ParentControl.HandleCreated += new EventHandler(ParentControlHandleCreated); + } + } + #endregion + + #region Implementation + void ParentControlHandleCreated(object sender, EventArgs e) + { + Initialize(); + } + + private IntPtr _originalWindowProcId; + private WinApi.WindowProcDelegate _windowProcDelegate; + /// + /// Initializes handler + /// + private void Initialize() + { + if (!RegisterTouchWindow()) + { + throw new NotSupportedException("Cannot register window"); + } + + _windowProcDelegate = WindowProc; + + _originalWindowProcId = IntPtr.Size == 4 ? + WinApi.SubclassWindow(_ParentControl.Handle, WinApi.GWLP_WNDPROC, _windowProcDelegate) : + WinApi.SubclassWindow64(_ParentControl.Handle, WinApi.GWLP_WNDPROC, _windowProcDelegate); + + //take the desktop DPI + using (Graphics graphics = Graphics.FromHwnd(_ParentControl.Handle)) + { + DpiX = graphics.DpiX; + DpiY = graphics.DpiY; + } + } + + + public Control ParentControl + { + get { return _ParentControl; } + } + + /// + /// The Windows message handler. + /// + private uint WindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam) + { + if(msg == WinApi.WM_TOUCH && (_HandlerType & eTouchHandlerType.Touch)== eTouchHandlerType.Touch) + { + foreach (TouchEventArgs arg in DecodeMessage(hWnd, msg, wParam, lParam, DpiX, DpiY)) + { + + if (arg.IsTouchDown) + OnTouchDown(arg); + + if (arg.IsTouchMove) + OnTouchMove(arg); + + if (arg.IsTouchUp) + OnTouchUp(arg); + } + return 1; + } + + // Handle only gesture message + if (msg != WinApi.WM_GESTURE) + { + return WinApi.CallWindowProc(_originalWindowProcId, hWnd, msg, wParam, lParam); + } + + WinApi.GESTUREINFO gestureInfo = new WinApi.GESTUREINFO(); + gestureInfo.cbSize = (uint)Marshal.SizeOf(typeof(WinApi.GESTUREINFO)); + + bool result = WinApi.GetGestureInfo(lParam, ref gestureInfo); + + if (!result) + throw new Exception("Cannot retrieve gesture information"); + + //Decode the gesture info and get the message event argument + GestureEventArgs eventArgs = new GestureEventArgs(this, ref gestureInfo); + try + { + //Fire the event using the event map + uint gestureId = GetGestureEventId(gestureInfo.dwID, gestureInfo.dwFlags); + if (gestureId == GestureEventId.Begin) + OnBegin(eventArgs); + else if (gestureId == GestureEventId.End) + OnEnd(eventArgs); + else if (gestureId == GestureEventId.Pan) + OnPan(eventArgs); + else if (gestureId == GestureEventId.PanBegin) + OnPanBegin(eventArgs); + else if (gestureId == GestureEventId.PanEnd) + OnPanEnd(eventArgs); + else if (gestureId == GestureEventId.PressAndTap) + OnPressAndTap(eventArgs); + else if (gestureId == GestureEventId.Rotate) + OnRotate(eventArgs); + else if (gestureId == GestureEventId.RotateBegin) + OnRotateBegin(eventArgs); + else if (gestureId == GestureEventId.RotateEnd) + OnRotateEnd(eventArgs); + else if (gestureId == GestureEventId.TwoFingerTap) + OnTwoFingerTap(eventArgs); + else if (gestureId == GestureEventId.Zoom) + OnZoom(eventArgs); + else if (gestureId == GestureEventId.ZoomBegin) + OnZoomBegin(eventArgs); + else if (gestureId == GestureEventId.ZoomEnd) + OnZoomEnd(eventArgs); + } + catch (ArgumentOutOfRangeException) //In case future releases will introduce new event values + { + } + + //Keep the last message for relative calculations + LastEventArgs = eventArgs; + + //Keep the first message for relative calculations + if (eventArgs.IsBegin) + LastBeginEventArgs = eventArgs; + + WinApi.CloseGestureInfoHandle(lParam); + + return 1; + } + + /// + /// Decode the message and create a collection of event arguments + /// + private IEnumerable DecodeMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, float dpiX, float dpiY) + { + // More than one touch input can be associated with a touch message + int inputCount = WinApi.LoWord(wParam.ToInt32()); // Number of touch inputs, actual per-contact messages + + WinApi.TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures + inputs = new WinApi.TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages + try + { + // Unpack message parameters into the array of TOUCHINPUT structures, each representing a message for one single contact. + if (!WinApi.GetTouchInputInfo(lParam, inputCount, inputs, Marshal.SizeOf(inputs[0]))) + { + // Touch info failed. + throw new Exception("Error calling GetTouchInputInfo API"); + } + + // For each contact, dispatch the message to the appropriate message handler. + // For WM_TOUCHDOWN you can get down & move notifications and for WM_TOUCHUP you can get up & move notifications + // WM_TOUCHMOVE will only contain move notifications and up & down notifications will never come in the same message + for (int i = 0; i < inputCount; i++) + { + TouchEventArgs touchEventArgs = new TouchEventArgs(this, dpiX, dpiY, ref inputs[i]); + yield return touchEventArgs; + } + } + finally + { + WinApi.CloseTouchInputHandle(lParam); + } + } + + private GestureEventArgs _LastBeginEventArgs; + /// + /// The event arguments that started the current gesture + /// + internal GestureEventArgs LastBeginEventArgs + { + get { return _LastBeginEventArgs; } + set { _LastBeginEventArgs = value; } + } + /// + /// The last event in the current gesture event sequence + /// + private GestureEventArgs _LastEventArgs; + internal GestureEventArgs LastEventArgs + { + get { return _LastEventArgs; } + set { _LastEventArgs = value; } + } + + + private static class GestureEventId + { + public static readonly uint Begin = GetGestureEventId(WinApi.GID_BEGIN, 0); + public static readonly uint End = GetGestureEventId(WinApi.GID_END, 0); + public static readonly uint PanBegin = GetGestureEventId(WinApi.GID_PAN, WinApi.GF_BEGIN); + public static readonly uint Pan = GetGestureEventId(WinApi.GID_PAN, 0); + public static readonly uint PanEnd = GetGestureEventId(WinApi.GID_PAN, WinApi.GF_END); + public static readonly uint PressAndTap = GetGestureEventId(WinApi.GID_PRESSANDTAP, 0); + public static readonly uint RotateBegin = GetGestureEventId(WinApi.GID_ROTATE, WinApi.GF_BEGIN); + public static readonly uint Rotate = GetGestureEventId(WinApi.GID_ROTATE, 0); + public static readonly uint RotateEnd = GetGestureEventId(WinApi.GID_ROTATE, WinApi.GF_END); + public static readonly uint TwoFingerTap = GetGestureEventId(WinApi.GID_TWOFINGERTAP, 0); + public static readonly uint ZoomBegin = GetGestureEventId(WinApi.GID_ZOOM, WinApi.GF_BEGIN); + public static readonly uint Zoom = GetGestureEventId(WinApi.GID_ZOOM, 0); + public static readonly uint ZoomEnd = GetGestureEventId(WinApi.GID_ZOOM, WinApi.GF_END); + } + private static uint GetGestureEventId(uint dwID, uint dwFlags) + { + return (dwID << 3) + (dwID == WinApi.GID_TWOFINGERTAP || dwID == WinApi.GID_PRESSANDTAP + || dwID == WinApi.GID_BEGIN || dwID == WinApi.GID_END ? + 0 : dwFlags & 5); + } + + /// + /// Register for touch event + /// + /// true if succeeded + private bool RegisterTouchWindow() + { + bool result = false; + if ((_HandlerType & eTouchHandlerType.Gesture) == eTouchHandlerType.Gesture) + { + WinApi.GESTURECONFIG[] gestureConfig = new WinApi.GESTURECONFIG[] { new WinApi.GESTURECONFIG(0, WinApi.GC_ALLGESTURES, 0) }; + result = WinApi.SetGestureConfig(_ParentControl.Handle, 0, 1, gestureConfig, (uint)Marshal.SizeOf(typeof(WinApi.GESTURECONFIG))); + } + + if ((_HandlerType & eTouchHandlerType.Touch) == eTouchHandlerType.Touch) + { + result |= WinApi.RegisterTouchWindow(_ParentControl.Handle, _DisablePalmRejection ? WinApi.TouchWindowFlag.WantPalm : 0); + } + return result; + } + + private bool _DisablePalmRejection; + /// + /// Gets or sets whether palm rejection is enabled. + /// + public bool DisablePalmRejection + { + get + { + return _DisablePalmRejection; + } + set + { + if (_DisablePalmRejection == value) + return; + + _DisablePalmRejection = value; + + if (_ParentControl.IsHandleCreated) + { + WinApi.UnregisterTouchWindow(_ParentControl.Handle); + RegisterTouchWindow(); + } + } + } + + private float _DpiX; + public float DpiX + { + get { return _DpiX; } + set { _DpiX = value; } + } + + private float _DpiY; + public float DpiY + { + get { return _DpiY; } + set { _DpiY = value; } + } + + /// + /// Check if Multi-touch support device is ready + /// + public static bool IsTouchEnabled + { + get + { + return (WinApi.GetDigitizerStatus() & (WinApi.DigitizerStatus.StackReady | WinApi.DigitizerStatus.MultiInput)) != 0; + } + } + #endregion + } + [Flags] + internal enum eTouchHandlerType : short + { + Gesture = 1, + Touch = 2 + } + + internal class GestureEventArgs : EventArgs + { + private readonly uint _Flags; + + /// + /// Create new gesture event instance and decode the gesture info structure + /// + /// The gesture handler + /// The gesture information + internal GestureEventArgs(TouchHandler handler, ref WinApi.GESTUREINFO gestureInfo) + { + _Flags = gestureInfo.dwFlags; + GestureId = gestureInfo.dwID; + GestureArguments = gestureInfo.ullArguments; + + //Get the last event from the handler + LastEvent = handler.LastEventArgs; + + //Get the last begin event from the handler + LastBeginEvent = handler.LastBeginEventArgs; + + ParseGesture(handler.ParentControl, ref gestureInfo); + + //new gesture, clear last and first event fields + if (IsBegin) + { + LastBeginEvent = null; + LastEvent = null; + } + } + + //Decode the gesture + private void ParseGesture(Control parentControl, ref WinApi.GESTUREINFO gestureInfo) + { + Location = parentControl.PointToClient(new Point(gestureInfo.ptsLocation.x, gestureInfo.ptsLocation.y)); + + Center = Location; + + switch (GestureId) + { + case WinApi.GID_ROTATE: + ushort lastArguments = (ushort)(IsBegin ? 0 : LastEvent.GestureArguments); + + RotateAngle = WinApi.GID_ROTATE_ANGLE_FROM_ARGUMENT((ushort)(gestureInfo.ullArguments - lastArguments)); + break; + + + case WinApi.GID_ZOOM: + Point first = IsBegin ? Location : LastBeginEvent.Location; + Center = new Point((Location.X + first.X) / 2, (Location.Y + first.Y) / 2); + ZoomFactor = IsBegin ? 1 : (double)gestureInfo.ullArguments / LastEvent.GestureArguments; + //DistanceBetweenFingers = WinApi.LoDWord(gestureInfo.ullArguments); + break; + + case WinApi.GID_PAN: + PanTranslation = IsBegin ? new Size(0, 0) : + new Size(Location.X - LastEvent.Location.X, Location.Y - LastEvent.Location.Y); + int panVelocity = WinApi.HiDWord((long)(gestureInfo.ullArguments)); + PanVelocity = new Size(WinApi.LoWord(panVelocity), WinApi.HiWord(panVelocity)); + //DistanceBetweenFingers = WinApi.LoDWord(gestureInfo.ullArguments); + break; + } + + + } + + private uint _GestureId; + public uint GestureId + { + get { return _GestureId; } + private set { _GestureId = value; } + } + + private ulong _GestureArguments; + public ulong GestureArguments + { + get { return _GestureArguments; } + private set { _GestureArguments = value; } + } + + private Point _Location; + /// + /// The client location of gesture. + /// + public Point Location + { + get { return _Location; } + private set { _Location = value; } + } + + /// + /// Is this the first event of a gesture. + /// + public bool IsBegin + { + get + { + return (_Flags & WinApi.GF_BEGIN) != 0; + } + } + + /// + /// It this last event of a gesture. + /// + public bool IsEnd + { + get + { + return (_Flags & WinApi.GF_END) != 0; + } + } + + /// + /// Has gesture triggered inertia. + /// + public bool IsInertia + { + get + { + return (_Flags & WinApi.GF_INERTIA) != 0; + } + } + + /// + /// Gesture relative rotation angle for Rotate event. + /// + private double _RotateAngle; + public double RotateAngle + { + get { return _RotateAngle; } + private set { _RotateAngle = value; } + } + + /// + /// Indicates calculated gesture center. + /// + private Point _Center; + public Point Center + { + get { return _Center; } + private set { _Center = value; } + } + + /// + /// Gesture zoom factor for Zoom event. + /// + private double _ZoomFactor; + public double ZoomFactor + { + get { return _ZoomFactor; } + private set { _ZoomFactor = value; } + } + + /// + /// Gesture relative panning translation for Pan event. + /// + private Size _PanTranslation; + public Size PanTranslation + { + get { return _PanTranslation; } + set { _PanTranslation = value; } + } + + /// + /// Gesture velocity vector of the pan gesture for custom inertia implementations. + /// + private Size _PanVelocity; + public Size PanVelocity + { + get { return _PanVelocity; } + private set { _PanVelocity = value; } + } + + private GestureEventArgs _LastBeginEvent; + /// + /// The first touch arguments in this gesture event sequence. + /// + public GestureEventArgs LastBeginEvent + { + get { return _LastBeginEvent; } + internal set { _LastBeginEvent = value; } + } + + /// + /// The last touch arguments in this gesture event sequence. + /// + private GestureEventArgs _LastEvent; + public GestureEventArgs LastEvent + { + get { return _LastEvent; } + internal set { _LastEvent = value; } + } + } + + /// + /// EventArgs passed to Touch handlers + /// + internal class TouchEventArgs : EventArgs + { + private readonly TouchHandler _ParentHandler; + private readonly float _dpiXFactor; + private readonly float _dpiYFactor; + + /// + /// Create new touch event argument instance + /// + /// The target control + /// one of the inner touch input in the message + internal TouchEventArgs(TouchHandler parentHandler, float dpiX, float dpiY, ref WinApi.TOUCHINPUT touchInput) + { + _ParentHandler = parentHandler; + _dpiXFactor = 96F / dpiX; + _dpiYFactor = 96F / dpiY; + DecodeTouch(ref touchInput); + } + + private bool CheckFlag(int value) + { + return (Flags & value) != 0; + } + + + + // Decodes and handles WM_TOUCH* messages. + private void DecodeTouch(ref WinApi.TOUCHINPUT touchInput) + { + // TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels. + // Also convert screen to client coordinates. + if ((touchInput.dwMask & WinApi.TOUCHINPUTMASKF_CONTACTAREA) != 0) + ContactSize = new Size(AdjustDpiX(touchInput.cyContact / 100), AdjustDpiY(touchInput.cyContact / 100)); + + Id = touchInput.dwID; + + Point p = _ParentHandler.ParentControl.PointToClient(new Point(touchInput.x / 100, touchInput.y / 100)); + Location = p; // new Point(AdjustDpiX(p.X), AdjustDpiY(p.Y)); + + Time = touchInput.dwTime; + TimeSpan ellapse = TimeSpan.FromMilliseconds(Environment.TickCount - touchInput.dwTime); + AbsoluteTime = DateTime.Now - ellapse; + + Mask = touchInput.dwMask; + Flags = touchInput.dwFlags; + } + + + private int AdjustDpiX(int value) + { + return (int)(value * _dpiXFactor); + } + + private int AdjustDpiY(int value) + { + return (int)(value * _dpiYFactor); + } + + /// + /// Touch client coordinate in pixels + /// + private Point _Location; + public Point Location + { + get { return _Location; } + private set + { + _Location = value; + } + } + + /// + /// A touch point identifier that distinguishes a particular touch input + /// + private int _Id; + public int Id + { + get { return _Id; } + private set + { + _Id = value; + } + } + + /// + /// A set of bit flags that specify various aspects of touch point + /// press, release, and motion. + /// + private int _Flags; + public int Flags + { + get { return _Flags; } + private set + { + _Flags = value; + } + } + + /// + /// mask which fields in the structure are valid + /// + private int _Mask; + public int Mask + { + get { return _Mask; } + private set + { + _Mask = value; + } + } + + /// + /// touch event time + /// + private DateTime _AbsoluteTime; + public DateTime AbsoluteTime + { + get { return _AbsoluteTime; } + private set { _AbsoluteTime = value; } + } + + /// + /// touch event time from system up + /// + private int _Time; + public int Time + { + get { return _Time; } + private set + { + _Time = value; + } + } + /// + /// the size of the contact area in pixels + /// + private Size? _ContactSize; + public Size? ContactSize + { + get { return _ContactSize; } + private set { _ContactSize = value; } + } + + /// + /// Is Primary Contact (The first touch sequence) + /// + public bool IsPrimaryContact + { + get { return (Flags & WinApi.TOUCHEVENTF_PRIMARY) != 0; } + } + + /// + /// Specifies that movement occurred + /// + public bool IsTouchMove + { + get { return CheckFlag(WinApi.TOUCHEVENTF_MOVE); } + } + + /// + /// Specifies that the corresponding touch point was established through a new contact + /// + public bool IsTouchDown + { + get { return CheckFlag(WinApi.TOUCHEVENTF_DOWN); } + } + + /// + /// Specifies that a touch point was removed + /// + public bool IsTouchUp + { + get { return CheckFlag(WinApi.TOUCHEVENTF_UP); } + } + + /// + /// Specifies that a touch point is in range + /// + public bool IsTouchInRange + { + get { return CheckFlag(WinApi.TOUCHEVENTF_INRANGE); } + } + + /// + /// specifies that this input was not coalesced. + /// + public bool IsTouchNoCoalesce + { + get { return CheckFlag(WinApi.TOUCHEVENTF_NOCOALESCE); } + } + + /// + /// Specifies that the touch point is associated with a pen contact + /// + public bool IsTouchPen + { + get { return CheckFlag(WinApi.TOUCHEVENTF_PEN); } + } + + /// + /// The touch event came from the user's palm + /// + /// Set to true + public bool IsTouchPalm + { + get { return CheckFlag(WinApi.TOUCHEVENTF_PALM); } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Touch/WinApi.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Touch/WinApi.cs new file mode 100644 index 00000000..6f29679d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/Touch/WinApi.cs @@ -0,0 +1,290 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar.Touch +{ + internal class WinApi + { + #region Functions + [DllImport("user32")] + public static extern bool SetGestureConfig( + IntPtr hwnd, // window for which configuration is specified + uint dwReserved, // reserved, must be 0 + uint cIDs, // count of GESTURECONFIG structures + GESTURECONFIG[] pGestureConfig, // array of GESTURECONFIG structures, dwIDs will be processed in the + // order specified and repeated occurances will overwrite previous ones + uint cbSize); // sizeof(GESTURECONFIG) + + [DllImport("user32")] + public static extern bool RegisterTouchWindow(System.IntPtr hWnd, TouchWindowFlag flags); + + [DllImport("user32")] + public static extern bool UnregisterTouchWindow(System.IntPtr hWnd); + + [DllImport("user32")] + public static extern bool IsTouchWindow(System.IntPtr hWnd, out uint ulFlags); + + [DllImport("user32")] + public static extern bool GetTouchInputInfo(System.IntPtr hTouchInput, int cInputs, [In, Out] TOUCHINPUT[] pInputs, int cbSize); + + [DllImport("user32")] + public static extern void CloseTouchInputHandle(System.IntPtr lParam); + + [DllImport("user32")] + public static extern bool SetProp(IntPtr hWnd, string lpString, IntPtr hData); + + //Touch + [DllImport("user32", EntryPoint = "GetSystemMetrics")] + public static extern int GetDigitizerCapabilities(DigitizerIndex index); + [DllImport("user32")] + public static extern bool GetGestureInfo(IntPtr hGestureInfo, ref GESTUREINFO pGestureInfo); + [DllImport("user32")] + public static extern bool CloseGestureInfoHandle(IntPtr hGestureInfo); + [DllImport("user32", EntryPoint = "SetWindowLongPtr")] + public static extern IntPtr SubclassWindow64(IntPtr hWnd, int nIndex, WindowProcDelegate dwNewLong); + + [DllImport("user32", EntryPoint = "SetWindowLong")] + public static extern IntPtr SubclassWindow(IntPtr hWnd, int nIndex, WindowProcDelegate dwNewLong); + + + [DllImport("user32")] + public static extern uint CallWindowProc(IntPtr prevWndFunc, IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam); + + public delegate uint WindowProcDelegate(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam); + + /// + /// Get the current Digitizer Status + /// + public static DigitizerStatus GetDigitizerStatus() + { + return (DigitizerStatus)GetDigitizerCapabilities(DigitizerIndex.SM_DIGITIZER); + } + #endregion + + #region Structures & Constants + [StructLayout(LayoutKind.Sequential)] + public struct GESTURECONFIG + { + public uint dwID; // gesture ID + public uint dwWant; // settings related to gesture ID that are to be turned on + public uint dwBlock; // settings related to gesture ID that are to be turned off + /// + /// Initializes a new instance of the GESTURECONFIG structure. + /// + /// + /// + /// + public GESTURECONFIG(uint dwID, uint dwWant, uint dwBlock) + { + this.dwID = dwID; + this.dwWant = dwWant; + this.dwBlock = dwBlock; + } + } + /// + /// Specifies available digitizer capabilities + /// + [Flags] + public enum DigitizerStatus : byte + { + IntegratedTouch = 0x01, + ExternalTouch = 0x02, + IntegratedPan = 0x04, + ExternalPan = 0x08, + MultiInput = 0x40, + StackReady = 0x80 + } + public enum DigitizerIndex + { + SM_DIGITIZER = 94, + SM_MAXIMUMTOUCHES = 95 + } + public const int GWLP_WNDPROC = -4; + // Gesture argument helpers + // - Angle should be a double in the range of -2pi to +2pi + // - Argument should be an unsigned 16-bit value + // + public static ushort GID_ROTATE_ANGLE_TO_ARGUMENT(ushort arg) { return ((ushort)(((arg + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0)); } + public static double GID_ROTATE_ANGLE_FROM_ARGUMENT(ushort arg) { return ((((double)arg / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265); } + + //Gesture flags - GESTUREINFO.dwFlags + public const uint GF_BEGIN = 0x00000001; + public const uint GF_INERTIA = 0x00000002; + public const uint GF_END = 0x00000004; + + //Gesture IDs + public const uint GID_BEGIN = 1; + public const uint GID_END = 2; + public const uint GID_ZOOM = 3; + public const uint GID_PAN = 4; + public const uint GID_ROTATE = 5; + public const uint GID_TWOFINGERTAP = 6; + public const uint GID_PRESSANDTAP = 7; + + public const uint GC_ALLGESTURES = 0x00000001; + + public const uint WM_GESTURE = 0x0119; + + public const uint WM_GESTURENOTIFY = 0x011A; + + // Touch event window message constants [winuser.h] + public const int WM_TOUCH = 0x0240; + + // Touch input mask values (TOUCHINPUT.dwMask) [winuser.h] + public const int TOUCHINPUTMASKF_TIMEFROMSYSTEM = 0x0001; // the dwTime field contains a system generated value + public const int TOUCHINPUTMASKF_EXTRAINFO = 0x0002; // the dwExtraInfo field is valid + public const int TOUCHINPUTMASKF_CONTACTAREA = 0x0004; // the cxContact and cyContact fields are valid + + // Touch event flags ((TOUCHINPUT.dwFlags) [winuser.h] + public const int TOUCHEVENTF_MOVE = 0x0001; + public const int TOUCHEVENTF_DOWN = 0x0002; + public const int TOUCHEVENTF_UP = 0x0004; + public const int TOUCHEVENTF_INRANGE = 0x0008; + public const int TOUCHEVENTF_PRIMARY = 0x0010; + public const int TOUCHEVENTF_NOCOALESCE = 0x0020; + public const int TOUCHEVENTF_PEN = 0x0040; + public const int TOUCHEVENTF_PALM = 0x0080; + + public enum TouchWindowFlag : uint + { + FineTouch = 0x1, + WantPalm = 0x2 + } + /// + /// Gesture Info Interop Structure + /// + [StructLayout(LayoutKind.Sequential)] + public struct GESTUREINFO + { + public uint cbSize; // size, in bytes, of this structure (including variable length Args field) + public uint dwFlags; // see GF_* flags + public uint dwID; // gesture ID, see GID_* defines + public IntPtr hwndTarget; // handle to window targeted by this gesture + public POINTS ptsLocation; // current location of this gesture + public uint dwInstanceID; // internally used + public uint dwSequenceID; // internally used + public ulong ullArguments; // arguments for gestures whose arguments fit in 8 BYTES + public uint cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture + } + /// + /// A Simple POINTS Interop structure + /// + [StructLayout(LayoutKind.Sequential)] + public struct POINTS + { + public short x; + public short y; + } + + /// + /// A Simple POINT Interop structure + /// + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public int x; + public int y; + } + /// + /// Touch API defined structures [winuser.h] + /// + [StructLayout(LayoutKind.Sequential)] + public struct TOUCHINPUT + { + public int x; + public int y; + public System.IntPtr hSource; + public int dwID; + public int dwFlags; + public int dwMask; + public int dwTime; + public System.IntPtr dwExtraInfo; + public int cxContact; + public int cyContact; + } + + // Extracts lower 16-bit word from an 32-bit int. + // in: + // number int + // returns: + // lower word + public static ushort LoWord(uint number) + { + return (ushort)(number & 0xffff); + } + + // Extracts higher 16-bit word from an 32-bit int. + // in: + // number uint + // returns: + // lower word + public static ushort HiWord(uint number) + { + return (ushort)((number >> 16) & 0xffff); + } + + // Extracts lower 32-bit word from an 64-bit int. + // in: + // number ulong + // returns: + // lower word + public static uint LoDWord(ulong number) + { + return (uint)(number & 0xffffffff); + } + + // Extracts higher 32-bit word from an 64-bit int. + // in: + // number ulong + // returns: + // lower word + public static uint HiDWord(ulong number) + { + return (uint)((number >> 32) & 0xffffffff); + } + + + // Extracts lower 16-bit word from an 32-bit int. + // in: + // number int + // returns: + // lower word + public static short LoWord(int number) + { + return (short)number; + } + + // Extracts higher 16-bit word from an 32-bit int. + // in: + // number int + // returns: + // lower word + public static short HiWord(int number) + { + return (short)(number >> 16); + } + + // Extracts lower 32-bit word from an 64-bit int. + // in: + // number long + // returns: + // lower word + public static int LoDWord(long number) + { + return (int)(number); + } + + // Extracts higher 32-bit word from an 64-bit int. + // in: + // number long + // returns: + // lower word + public static int HiDWord(long number) + { + return (int)((number >> 32)); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/TouchKeyboard.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/TouchKeyboard.cs new file mode 100644 index 00000000..2d085f5b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/TouchKeyboard.cs @@ -0,0 +1,801 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Windows.Forms; +using System.Drawing; + +namespace DevComponents.DotNetBar.Keyboard +{ + [ToolboxItem(true), ProvideProperty("ShowTouchKeyboard", typeof(Control))] + public class TouchKeyboard : Component, IExtenderProvider + { + private List _Targets = new List(); + private Control _CurrentTarget; + private PopupVirtualKeyboard _PopupKeyboard; + private KeyboardControl _VirtualKeyboard; + + + public TouchKeyboard() + { + _PopupKeyboard = new PopupVirtualKeyboard(); + _VirtualKeyboard = new KeyboardControl(); + + //_PopupKeyboard.Size = Dpi.Size(new Size(KeyboardControl.DefaultWidth, KeyboardControl.DefaultHeight)); + + // Track floating keyboard location and size changed. The user can change this at runtime with the mouse. + //_PopupKeyboard.SizeChanged += new EventHandler(PopupKeyboard_SizeChanged); + _PopupKeyboard.ResizeEnd += PopupKeyboard_ResizeEnd; + _PopupKeyboard.LocationChanged += new EventHandler(PopupKeyboard_LocationChanged); + + // Track changes when the keyboard is inline. + _VirtualKeyboard.SizeChanged += new EventHandler(VirtualKeyboard_SizeChanged); + _VirtualKeyboard.LocationChanged += new EventHandler(VirtualKeyboard_LocationChanged); + _VirtualKeyboard.DockChanged += new EventHandler(VirtualKeyboard_DockChanged); + _VirtualKeyboard.SendingKey += new KeyCancelEventHandler(VirtualKeyboardSendingKey); + _VirtualKeyboard.KeySent += new KeyEventHandler(VirtualKeyboardKeySent); + } + + #region Handle Changed events. + /// + /// Occurs before the key pressed on keyboard is sent to target control and allows cancellation of the message + /// + [Description("Occurs before the key pressed on keyboard is sent to target control and allows cancellation of the message.")] + public event KeyCancelEventHandler SendingKey; + /// + /// Raises SendingKey event. + /// + /// Provides event arguments. + protected virtual void OnSendingKey(KeyboardKeyCancelEventArgs e) + { + KeyCancelEventHandler handler = SendingKey; + if (handler != null) + handler(this, e); + } + /// + /// Occurs after the key is sent to target control. + /// + [Description("Occurs after the key is sent to target control.")] + public event KeyEventHandler KeySent; + /// + /// Raises KeySent event. + /// + /// Provides event arguments. + protected virtual void OnKeySent(KeyboardKeyEventArgs e) + { + KeyEventHandler handler = KeySent; + if (handler != null) + handler(this, e); + } + + private void VirtualKeyboardKeySent(object sender, KeyboardKeyEventArgs e) + { + OnKeySent(e); + } + + private void VirtualKeyboardSendingKey(object sender, KeyboardKeyCancelEventArgs e) + { + OnSendingKey(e); + } + + void PopupKeyboard_ResizeEnd(object sender, EventArgs e) + { + _FloatingSize = _PopupKeyboard.Size; + OnFloatingSizeChanged(); + } + + //void PopupKeyboard_SizeChanged(object sender, EventArgs e) + //{ + // _FloatingSize = _PopupKeyboard.Size; + // OnFloatingSizeChanged(); + //} + + void PopupKeyboard_LocationChanged(object sender, EventArgs e) + { + OnFloatingLocationChanged(); + } + + void VirtualKeyboard_LocationChanged(object sender, EventArgs e) + { + if (_VirtualKeyboard.FindForm() != _PopupKeyboard) + { + OnLocationChanged(); + } + } + + void VirtualKeyboard_SizeChanged(object sender, EventArgs e) + { + if (_VirtualKeyboard.FindForm() != _PopupKeyboard) + { + _Size = _VirtualKeyboard.Size; + OnSizeChanged(); + } + + } + + void VirtualKeyboard_DockChanged(object sender, EventArgs e) + { + if (_VirtualKeyboard.FindForm() != _PopupKeyboard) + { + OnDockChanged(); + } + } + + #endregion + + /// + /// Gets the reference to internal keyboard control that is used to provide Keyboard visual. + /// + [Browsable(false)] + public KeyboardControl KeyboardControl + { + get + { + return _VirtualKeyboard; + } + } + + /// + /// Attaches the Keyboard to the specified control. The keyboard will automatically appear when the control receives input focus. + /// + /// The control to which the Keyboard will be attached. + private void AttachTo(Control control) + { + control.GotFocus += new EventHandler(control_GotFocus); + control.LostFocus += new EventHandler(control_LostFocus); + + _Targets.Add(control); + } + + + /// + /// Detaches the Keyboard from the specified control. + /// + /// The control from which the Keyboard will be detached. + private void DetachFrom(Control control) + { + if (_Targets.Contains(control)) + { + control.GotFocus -= new EventHandler(control_GotFocus); + control.LostFocus -= new EventHandler(control_LostFocus); + + _Targets.Remove(control); + } + } + + /// + /// Occurs before keyboard is shown and allows canceling of opening. + /// + [Description("Occurs before keyboard is shown and allows canceling of opening.")] + public event CancelKeyboardEventHandler KeyboardOpening; + /// + /// Raises KeyboardOpening event. + /// + /// Provides event arguments. + protected virtual void OnKeyboardOpening(CancelKeyboardEventArgs e) + { + CancelKeyboardEventHandler handler = KeyboardOpening; + if (handler != null) + handler(this, e); + } + /// + /// Occurs after keyboard is shown. + /// + [Description("Occurs after keyboard is shown.")] + public event EventHandler KeyboardOpened; + /// + /// Raises KeyboardOpened event. + /// + /// Provides event arguments. + protected virtual void OnKeyboardOpened(EventArgs e) + { + EventHandler handler = KeyboardOpened; + if (handler != null) + handler(this, e); + } + + private bool _ShowingFloatingKeyboard = false; + public void ShowKeyboard(Control control, TouchKeyboardStyle style) + { + CancelKeyboardEventArgs ce = new CancelKeyboardEventArgs(control, style); + OnKeyboardOpening(ce); + if (ce.Cancel) return; + + _CurrentTarget = ce.TargetControl; + style = ce.Style; + + _PopupKeyboard.CurrentControl = _CurrentTarget; + + _VirtualKeyboard.UnlockCapsLock(); + + if (_CurrentTarget != null) + { + if (style == TouchKeyboardStyle.Floating) + { + try + { + if (_FloatingSize.IsEmpty) + _PopupKeyboard.Size = Dpi.Size(new Size(KeyboardControl.DefaultWidth, KeyboardControl.DefaultHeight)); + else + _PopupKeyboard.Size = _FloatingSize; + + _ShowingFloatingKeyboard = true; + _PopupKeyboard.Owner = _CurrentTarget.FindForm(); + _PopupKeyboard.Controls.Add(_VirtualKeyboard); + _VirtualKeyboard.Dock = DockStyle.Fill; + _VirtualKeyboard.Visible = true; + _PopupKeyboard.Show(); + + // When floating, don't show the top bar. The information on the top bar are on the window's title bar. + _VirtualKeyboard.IsTopBarVisible = false; + } + finally + { + _ShowingFloatingKeyboard = false; + } + } + else if (style == TouchKeyboardStyle.Inline) + { + Form owner = _CurrentTarget.FindForm(); + if (_Size.IsEmpty) + _VirtualKeyboard.Size = Dpi.Size(new Size(KeyboardControl.DefaultWidth, KeyboardControl.DefaultHeight)); + else + _VirtualKeyboard.Size = _Size; + _VirtualKeyboard.Dock = Dock; + owner.Controls.Add(_VirtualKeyboard); + _VirtualKeyboard.BringToFront(); + _VirtualKeyboard.Visible = true; + + // When inline, show the top bar. + _VirtualKeyboard.IsTopBarVisible = true; + } + } + + OnKeyboardOpened(EventArgs.Empty); + } + + /// + /// Gets keyboard target control. + /// + [Browsable(false)] + public Control CurrentKeyboardTarget + { + get { return _CurrentTarget; } + } + + /// + /// Occurs before the keyboard is closed and allows canceling of keyboard closing. + /// + [Description("Occurs before the keyboard is closed and allows canceling of keyboard closing.")] + public event CancelEventHandler KeyboardClosing; + /// + /// Raises KeyboardClosing event. + /// + /// Provides event arguments. + protected virtual void OnKeyboardClosing(CancelEventArgs e) + { + CancelEventHandler handler = KeyboardClosing; + if (handler != null) + handler(this, e); + } + + /// + /// Occurs after keyboard is closed. + /// + [Description("Occurs after keyboard is closed.")] + public event EventHandler KeyboardClosed; + /// + /// Raises KeyboardClosed event. + /// + /// Provides event arguments. + protected virtual void OnKeyboardClosed(EventArgs e) + { + EventHandler handler = KeyboardClosed; + if (handler != null) + handler(this, e); + } + + /// + /// Hides the keyboard. + /// + public void HideKeyboard() + { + CancelEventArgs ce = new CancelEventArgs(); + OnKeyboardClosing(ce); + if (ce.Cancel) return; + + _PopupKeyboard.Hide(); + Form form = _VirtualKeyboard.FindForm(); + if (form != null && !(form is PopupVirtualKeyboard)) + { + form.Controls.Remove(_VirtualKeyboard); + } + + OnKeyboardClosed(EventArgs.Empty); + } + + /// + /// Gets reference to the form which hosts popup keyboard. + /// + public Form FloatingKeyboardForm + { + get { return _PopupKeyboard; } + } + + + void control_GotFocus(object sender, EventArgs e) + { + Control control = sender as Control; + + if (control != null) + { + TouchKeyboardStyle style = TouchKeyboardStyle.No; + TouchKeyboardStyle formStyle = GetShowTouchKeyboard(control.FindForm()); + + // If the form specifies a mode to show the keyboard, then use that mode. If we want for the control to have the last + // word about how to show the keyboard, the following two if instructions should be inverted. + + if (_ExtendedControls.ContainsKey(control)) + style = _ExtendedControls[control]; + + if (formStyle != TouchKeyboardStyle.No) + style = formStyle; + + if (style != TouchKeyboardStyle.No) + { + ShowKeyboard(control, style); + } + } + } + + private bool IsPopupKeyboardActivated + { + get + { + if (_PopupKeyboard == null) return false; + return Form.ActiveForm == _PopupKeyboard; + } + } + + void control_LostFocus(object sender, EventArgs e) + { + if (!_ShowingFloatingKeyboard && !IsPopupKeyboardActivated) + { + _CurrentTarget = null; + HideKeyboard(); + } + } + + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_VirtualKeyboard != null) + _VirtualKeyboard.Dispose(); + if (_PopupKeyboard != null) + _PopupKeyboard.Dispose(); + } + + base.Dispose(disposing); + } + + + bool IExtenderProvider.CanExtend(object extendee) + { + if (extendee is Control && !(extendee is KeyboardControl)) + return true; + else + return false; + } + + + Dictionary _ExtendedControls = new Dictionary(); + + + /// + /// Retursn the way the keyboard will be shown when controls receive focus. + /// + /// The control for which to retrieve the value. + /// A TouchKeyboardStyle value defining the way the keyboard appears. + [Description("Shows an on screen touch keyboard when the control is focused.")] + [Category("Touch Keyboard")] + [DefaultValue(TouchKeyboardStyle.No)] + public TouchKeyboardStyle GetShowTouchKeyboard(Control extendee) + { + if (extendee == null) + return TouchKeyboardStyle.No; + + if (_ExtendedControls.ContainsKey(extendee)) + return _ExtendedControls[extendee]; + else + return TouchKeyboardStyle.No; + } + + /// + /// Sets the way the keyboard will be shown when controls receive focus. If the control is a Form, + /// all controls on the Form will support this way of displaying the touch keyboard. + /// + /// The control for which this value is specified. + /// A TouchKeyboardStyle value defining the way the keyboard appears. + public void SetShowTouchKeyboard(Control extendee, TouchKeyboardStyle value) + { + if (extendee is Form) + { + if (value != TouchKeyboardStyle.No) + { + foreach (Control c in extendee.Controls) + { + AttachTo(c); + } + + // If other controls are added to the form, attach to those controls also. + extendee.ControlAdded += new ControlEventHandler(form_ControlAdded); + + // If controls are removed from the form, dettach from them, we don't want to keep a reference to them. + extendee.ControlRemoved += new ControlEventHandler(form_ControlRemoved); + } + } + + if (!_ExtendedControls.ContainsKey(extendee)) + _ExtendedControls.Add(extendee, value); + else + _ExtendedControls[extendee] = value; + + if (value == TouchKeyboardStyle.No) + DetachFrom(extendee); + else + AttachTo(extendee); + } + + + void form_ControlAdded(object sender, ControlEventArgs e) + { + if (sender is KeyboardControl) + return; + + AttachTo(e.Control); + } + + + void form_ControlRemoved(object sender, ControlEventArgs e) + { + if (sender is KeyboardControl) + return; + + DetachFrom(e.Control); + } + + + /// + /// Gets or set the ColorTable used to draw the keyboard. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public VirtualKeyboardColorTable ColorTable + { + get { return _VirtualKeyboard.ColorTable; } + set { _VirtualKeyboard.ColorTable = value; } + } + + + /// + /// Gets or set the Renderer used to draw the keyboard. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Renderer Renderer + { + get { return _VirtualKeyboard.Renderer; } + set { _VirtualKeyboard.Renderer = value; } + } + + + private Size _Size = Size.Empty; //new Size(KeyboardControl.DefaultWidth, KeyboardControl.DefaultHeight); + /// + /// Gets or sets the size of the keyboard, when shown inline. + /// + [Category("Inline Layout")] + [Description("Gets or sets the size of the keyboard, when the keyboard is shown inline.")] + [Browsable(true)] + public Size Size + { + get { return _Size; } + set + { + if (_Size != value) + { + _Size = value; + OnSizeChanged(); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSize() + { + return !_Size.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSize() + { + Size = Size.Empty; + } + private void OnSizeChanged() + { + Size newSize = Size; + if (newSize.IsEmpty) + newSize = Dpi.Size(new Size(KeyboardControl.DefaultWidth, KeyboardControl.DefaultHeight)); + + _VirtualKeyboard.Size = newSize; + + if (SizeChanged != null) + SizeChanged(this, EventArgs.Empty); + } + + + /// + /// Gets or sets the coordinates of the upper-left corner of the keyboard when shown inline, relative to the form. + /// + [Category("Inline Layout")] + [Description("The coordinates of the upper-left corner of the keyboard, when the keyboard is shown inline, relative to the form.")] + [Browsable(true)] + public Point Location + { + get { return _VirtualKeyboard.Location; } + set + { + if (_VirtualKeyboard.Location != value) + { + _VirtualKeyboard.Location = value; + OnLocationChanged(); + } + } + } + + private void OnLocationChanged() + { + if (LocationChanged != null) + LocationChanged(this, EventArgs.Empty); + } + + + private DockStyle _Dock = DockStyle.Bottom; + /// + /// Defines which borders of the keyboard are bound to the container. + /// + [Category("Inline Layout")] + [Description("Defines which border of the keyboard are bound to the form, when the keyboard is shown inline. Default value is DockStyle.Bottom.")] + [DefaultValue(DockStyle.Bottom)] + [Browsable(true)] + public DockStyle Dock + { + get { return _Dock; } + set + { + if (_Dock != value) + { + _Dock = value; + OnDockChanged(); + } + } + } + + private void OnDockChanged() + { + // When keybaord style is Floating, dock is always fill (to fill to popup window). + if (_PopupKeyboard.Controls.Contains(_VirtualKeyboard)) + _VirtualKeyboard.Dock = DockStyle.Fill; + else + _VirtualKeyboard.Dock = _Dock; + + if (DockChanged != null) + DockChanged(this, EventArgs.Empty); + } + + + /// + /// Gets or sets the coordinates of the upper-left corner of the keyboard when shown floating, relative to the screen. + /// + [Category("Floating Layout")] + [Description("The coordinates of the upper-left corner of the keyboard, when the keyboard is shown floating, relative to the screen.")] + [Browsable(true)] + public Point FloatingLocation + { + get { return _PopupKeyboard.Location; } + set + { + if (_PopupKeyboard.Location != value) + { + _PopupKeyboard.Location = value; + OnFloatingLocationChanged(); + } + } + } + + private void OnFloatingLocationChanged() + { + if (FloatingLocationChanged != null) + FloatingLocationChanged(this, EventArgs.Empty); + } + + /// + /// Indicates whether touch support is enabled when provided by hardware. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether touch support is enabled when provided by hardware.")] + public bool TouchEnabled + { + get { return _VirtualKeyboard.TouchEnabled; } + set + { + _VirtualKeyboard.TouchEnabled = value; + } + } + + private Size _FloatingSize = System.Drawing.Size.Empty; + /// + /// Gets or sets the size of the keyboard, when shown floating. + /// + [Category("Floating Layout")] + [Description("Gets or sets the size of the keyboard, when the keyboard is shown floating.")] + [Browsable(true)] + public Size FloatingSize + { + get { return _FloatingSize; } + set + { + if (_FloatingSize != value) + { + _FloatingSize = value; + OnFloatingSizeChanged(); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeFloatingSize() + { + return !_FloatingSize.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetFloatingSize() + { + FloatingSize = Size.Empty; + } + private void OnFloatingSizeChanged() + { + Size newSize = FloatingSize; + if (newSize.IsEmpty) + newSize = Dpi.Size(new Size(KeyboardControl.DefaultWidth, KeyboardControl.DefaultHeight)); + + _PopupKeyboard.Size = newSize; + + if (FloatingSizeChanged != null) + FloatingSizeChanged(this, EventArgs.Empty); + } + + /// + /// Gets or sets a text associated with this control. + /// + [Category("Appearance")] + [Description("The text associated with this control.")] + [Browsable(true)] + public string Text + { + get { return _VirtualKeyboard.Text; } + set + { + _VirtualKeyboard.Text = value; + _PopupKeyboard.Text = value; + OnTextChanged(); + } + } + + /// + /// Raises the TextChanged event. + /// + [EditorBrowsable(EditorBrowsableState.Advanced)] + protected void OnTextChanged() + { + if (TextChanged != null) + TextChanged(this, EventArgs.Empty); + } + + /// + /// Occurs when the Text property has changed. + /// + [Category("PropertyChanged")] + [Description("Event raised when the Text property has changed.")] + public event EventHandler TextChanged; + + /// + /// Occurs when the Size property has changed. + /// + [Category("Inline Layout")] + [Description("Event raised when the Size property has changed.")] + public event EventHandler SizeChanged; + + /// + /// Occurs when the Location property has changed. + /// + [Category("Inline Layout")] + [Description("Event raised when the Location property has changed.")] + public event EventHandler LocationChanged; + + /// + /// Occurs when the Dock property has changed. + /// + [Category("Inline Layout")] + [Description("Event raised when the Dock property has changed.")] + public event EventHandler DockChanged; + + /// + /// Occurs when the FloatingSize property has changed. + /// + [Category("Floating Layout")] + [Description("Event raised when the FloatingSize property has changed.")] + public event EventHandler FloatingSizeChanged; + + /// + /// Occurs when the FloatingLocation property has changed. + /// + [Category("Floating Layout")] + [Description("Event raised when the FloatingLocation property has changed.")] + public event EventHandler FloatingLocationChanged; + } + + + /// + /// Defines the way the touch keyboard will appear when attached to controls. + /// + public enum TouchKeyboardStyle + { + /// + /// Touch keyboard will not be visible. + /// + No, + + /// + /// Touch keyboard will appear inline in the form. + /// + Inline, + + /// + /// Touch keyboard will appear floating on the screen. + /// + Floating + } + + /// + /// Defines delegate for keyboard events. + /// + public delegate void CancelKeyboardEventHandler(object sender, CancelKeyboardEventArgs e); + /// + /// Defines event arguments for keyboard based events. + /// + public class CancelKeyboardEventArgs : CancelEventArgs + { + /// + /// Initializes a new instance of the CancelKeyboardEventArgs class. + /// + /// + /// + public CancelKeyboardEventArgs(Control targetControl, TouchKeyboardStyle style) + { + TargetControl = targetControl; + Style = style; + } + /// + /// Gets or sets the keyboard target control. + /// + public Control TargetControl; + + /// + /// Gets or sets the keyboard style. + /// + public TouchKeyboardStyle Style; + } + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/TouchKeyboard.ico b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/TouchKeyboard.ico new file mode 100644 index 00000000..4f72c9f9 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/TouchKeyboard.ico differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/VirtualKeyboardColors.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/VirtualKeyboardColors.cs new file mode 100644 index 00000000..06ca41a5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Keyboard/VirtualKeyboardColors.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.Keyboard +{ + /// + /// Defines the VirtualKeyboard colors. + /// + /// + /// This class maintains internally a Brush for each Color. These Brush objects are disposed internally when not needed anymore. + /// A Brush of a certain color is obtained by setting the same Color property to that color. + /// Maintaining the brushes here helps to have less GDI handles created / destroyed on each drawing of the keyboard. + /// + public sealed class VirtualKeyboardColorTable : IDisposable + { + /// + /// Creates a new color table for the VirtualKeyoard. + /// + public VirtualKeyboardColorTable() + { + _BackgroundBrush = new SolidBrush(BackgroundColor); + _KeysBrush = new SolidBrush(KeysColor); + _LightKeysBrush = new SolidBrush(LightKeysColor); + _DarkKeysBrush = new SolidBrush(DarkKeysColor); + _PressedKeysBrush = new SolidBrush(PressedKeysColor); + _TextBrush = new SolidBrush(TextColor); + _DownKeysBrush = new SolidBrush(DownKeysColor); + _DownTextBrush = new SolidBrush(DownTextColor); + _TopBarTextBrush = new SolidBrush(TopBarTextColor); + _ToggleTextBrush = new SolidBrush(ToggleTextColor); + } + + private static void ReCreateBrush(ref Brush brush, Color color) + { + if (brush != null) + brush.Dispose(); + + brush = new SolidBrush(color); + } + + + private Color _BackgroundColor = Color.Black; + /// + /// Gets or sets the color used to draw the background of the keyboard. + /// + public Color BackgroundColor + { + get { return _BackgroundColor; } + set { _BackgroundColor = value; ReCreateBrush(ref _BackgroundBrush, _BackgroundColor); } + } + + private Brush _BackgroundBrush; + /// + /// Gets a brush used for drawing the background of the keyboard. + /// + public Brush BackgroundBrush + { + get { return _BackgroundBrush; } + } + + + private Color _KeysColor = Color.FromArgb(0x30, 0x2f, 0x37); + /// + /// Gets or sets the color used for drawing normal keys. + /// + public Color KeysColor + { + get { return _KeysColor; } + set { _KeysColor = value; ReCreateBrush(ref _KeysBrush, _KeysColor); } + } + + private Brush _KeysBrush; + /// + /// Gets a brush used for drawing normal keys. + /// + public Brush KeysBrush + { + get { return _KeysBrush; } + } + + + private Color _LightKeysColor = Color.FromArgb(0x45, 0x44, 0x4c); + /// + /// Gets or sets the color used for drawing light keys. + /// + public Color LightKeysColor + { + get { return _LightKeysColor; } + set { _LightKeysColor = value; ReCreateBrush(ref _LightKeysBrush, _LightKeysColor); } + } + + private Brush _LightKeysBrush; + /// + /// Gets a brush used for drawing light keys. + /// + public Brush LightKeysBrush + { + get { return _LightKeysBrush; } + } + + + private Color _DarkKeysColor = Color.FromArgb(0x1d, 0x1c, 0x21); + /// + /// Gets or sets the color used for drawing dark keys. + /// + public Color DarkKeysColor + { + get { return _DarkKeysColor; } + set { _DarkKeysColor = value; ReCreateBrush(ref _DarkKeysBrush, _DarkKeysColor); } + } + + private Brush _DarkKeysBrush; + /// + /// Gets a brush used for drawing dark keys. + /// + public Brush DarkKeysBrush + { + get { return _DarkKeysBrush; } + } + + + private Color _PressedKeysColor = Color.FromArgb(0x10, 0xa1, 0x51); + /// + /// Gets or sets a brush used for drawing pressed keys. + /// + public Color PressedKeysColor + { + get { return _PressedKeysColor; } + set { _PressedKeysColor = value; ReCreateBrush(ref _PressedKeysBrush, _PressedKeysColor); } + } + + private Brush _PressedKeysBrush; + /// + /// Gets a brush used for drawing pressed keys. + /// + public Brush PressedKeysBrush + { + get { return _PressedKeysBrush; } + } + + + private Color _DownKeysColor = Color.White; + /// + /// Gets or sets a brush used for drawing pressed key when the key is down. + /// + public Color DownKeysColor + { + get { return _DownKeysColor; } + set { _DownKeysColor = value; ReCreateBrush(ref _DownKeysBrush, _DownKeysColor); } + } + + private Brush _DownKeysBrush; + /// + /// Gets a brush used for drawing pressed key when the key is down. + /// + public Brush DownKeysBrush + { + get { return _DownKeysBrush; } + } + + + private Color _TextColor = Color.White; + /// + /// Gets or sets a color used for drawing the text on the keys. + /// + public Color TextColor + { + get { return _TextColor; } + set { _TextColor = value; ReCreateBrush(ref _TextBrush, _TextColor); } + } + + private Brush _TextBrush; + /// + /// Gets a brush used for drawing the text on the keys. + /// + public Brush TextBrush + { + get { return _TextBrush; } + } + + + private Color _DownTextColor = Color.FromArgb(0x20, 0x20, 0x20); + /// + /// Gets or sets a color used for drawing the text on a key when the key is down. + /// + public Color DownTextColor + { + get { return _DownTextColor; } + set { _DownTextColor = value; ReCreateBrush(ref _DownTextBrush, _DownTextColor); } + } + + private Brush _DownTextBrush; + /// + /// Gets a brush used for drawing the text on a key when the key is down. + /// + public Brush DownTextBrush + { + get { return _DownTextBrush; } + } + + + private Color _TopBarTextColor = Color.White; + /// + /// Gets or sets a color used for drawing the text on the top bar. + /// + public Color TopBarTextColor + { + get { return _TopBarTextColor; } + set { _TopBarTextColor = value; ReCreateBrush(ref _TopBarTextBrush, _TopBarTextColor); } + } + + private Brush _TopBarTextBrush; + /// + /// Gets a brush used for drawing the text on the top bar. + /// + public Brush TopBarTextBrush + { + get { return _TopBarTextBrush; } + } + + + private Color _ToggleTextColor = Color.Green; + /// + /// Gets or sets a color used for drawing the text on a key when the key is in its toggled state. + /// + public Color ToggleTextColor + { + get { return _ToggleTextColor; } + set { _ToggleTextColor = value; ReCreateBrush(ref _ToggleTextBrush, _ToggleTextColor); } + } + + private Brush _ToggleTextBrush; + /// + /// Gets a brush used for drawing the text on a key when the key is in its toggled state. + /// + public Brush ToggleTextBrush + { + get { return _ToggleTextBrush; } + } + + + public void Dispose() + { + if (_BackgroundBrush != null) + _BackgroundBrush.Dispose(); + + if (_KeysBrush != null) + _KeysBrush.Dispose(); + + if (_LightKeysBrush != null) + _LightKeysBrush.Dispose(); + + if (_DarkKeysBrush != null) + _DarkKeysBrush.Dispose(); + + if (_PressedKeysBrush != null) + _PressedKeysBrush.Dispose(); + + if (_TextBrush != null) + _TextBrush.Dispose(); + + if (_DownTextBrush != null) + _DownTextBrush.Dispose(); + + if (_DownKeysBrush != null) + _DownKeysBrush.Dispose(); + + if (_TopBarTextBrush != null) + _TopBarTextBrush.Dispose(); + + if (_ToggleTextBrush != null) + _ToggleTextBrush.Dispose(); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/ColorHelpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/ColorHelpers.cs new file mode 100644 index 00000000..62f98599 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/ColorHelpers.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout.Design +{ + internal static class ColorHelpers + { + /// + /// Converts hex string to Color type. + /// + /// Hexadecimal color representation. + /// Reference to Color object. + public static Color GetColor(string rgbHex) + { + if (string.IsNullOrEmpty(rgbHex)) + return Color.Empty; + if (rgbHex.Length == 8) + return Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0, 2), 16), + Convert.ToInt32(rgbHex.Substring(2, 2), 16), + Convert.ToInt32(rgbHex.Substring(4, 2), 16), + Convert.ToInt32(rgbHex.Substring(6, 2), 16)); + + return Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0, 2), 16), + Convert.ToInt32(rgbHex.Substring(2, 2), 16), + Convert.ToInt32(rgbHex.Substring(4, 2), 16)); + } + + /// + /// Converts hex string to Color type. + /// + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int rgb) + { + if (rgb == -1) return Color.Empty; + return Color.FromArgb((rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF); + } + + /// + /// Converts hex string to Color type. + /// + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int alpha, int rgb) + { + if (rgb == -1) return Color.Empty; + return Color.FromArgb(alpha, (rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/DevComponents.DotNetBar.Layout.Design.csproj b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/DevComponents.DotNetBar.Layout.Design.csproj new file mode 100644 index 00000000..fa434511 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/DevComponents.DotNetBar.Layout.Design.csproj @@ -0,0 +1,136 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {56C369D3-61C2-4608-9C47-C7494A7875E3} + Library + Properties + DevComponents.DotNetBar.Layout.Design + DevComponents.DotNetBar.Layout.Design + true + dotnetbar.snk + v2.0 + + + 2.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE;LAYOUT + prompt + 4 + AllRules.ruleset + + + bin\ReleaseTrialLayoutDesign\ + TRACE;LAYOUT;TRIAL + true + pdbonly + AnyCPU + prompt + AllRules.ruleset + + + + + + + + + + + + + + + + + + + + + + Component + + + + + + + {1641B2CE-259C-4A52-A460-48C936B13951} + DevComponents.DotNetBar.Layout + + + {36546CE3-335C-4AB6-A2F3-40F8C818BC66} + DotNetBar + + + + + + + + TextMarkupEditor.cs + Designer + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/Helpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/Helpers.cs new file mode 100644 index 00000000..f993acbb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/Helpers.cs @@ -0,0 +1,69 @@ +using System; +using System.Text; +using System.Drawing; +using System.Reflection; + +namespace DevComponents.DotNetBar.Layout.Design +{ + internal static class Helpers + { + internal static Bitmap LoadBitmap(string imageName) + { + DotNetBarResourcesAttribute att = Attribute.GetCustomAttribute(System.Reflection.Assembly.GetExecutingAssembly(), typeof(DotNetBarResourcesAttribute)) as DotNetBarResourcesAttribute; + if (att != null && att.NamespacePrefix != "") + { + return new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream(att.NamespacePrefix + "." + imageName)); + } + else + return new Bitmap(typeof(DevComponents.DotNetBar.DotNetBarManager), imageName); + } + + internal static Icon LoadIcon(string imageName) + { + DotNetBarResourcesAttribute att = Attribute.GetCustomAttribute(System.Reflection.Assembly.GetExecutingAssembly(), typeof(DotNetBarResourcesAttribute)) as DotNetBarResourcesAttribute; + if (att != null && att.NamespacePrefix != "") + { + return new Icon(Assembly.GetExecutingAssembly().GetManifestResourceStream(att.NamespacePrefix + "." + imageName)); + } + else + return new Icon(typeof(DevComponents.DotNetBar.DotNetBarManager), imageName); + } + + public static void DrawDesignTimeSelection(Graphics g, Rectangle r, Color backColor, Color border, int penWidth) + { + if (r.Width <= 0 || r.Height <= 0) + return; + if (!backColor.IsEmpty && backColor != Color.Transparent) + { + if ((double)backColor.GetBrightness() < 0.5) + border = System.Windows.Forms.ControlPaint.Light(backColor); + else + border = System.Windows.Forms.ControlPaint.Dark(backColor); + } + using (Pen pen = new Pen(border, penWidth)) + { + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; + r.Width--; + r.Height--; + g.DrawRectangle(pen, r); + } + } + + public static bool IsOffice2007Style(eDotNetBarStyle style) + { + if (style == eDotNetBarStyle.StyleManagerControlled) + style = StyleManager.GetEffectiveStyle(); + return (style == eDotNetBarStyle.Office2007 || style == eDotNetBarStyle.Office2010 || style == eDotNetBarStyle.Windows7 || StyleManager.IsMetro(style)); + } + + internal static string GetItemErrorInfo(System.Xml.XmlElement xmlItem) + { + string s = ""; + if (xmlItem.HasAttribute("assembly")) + s = s + xmlItem.GetAttribute("assembly"); + if (xmlItem.HasAttribute("class")) + s = s + xmlItem.GetAttribute("class"); + return s; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutControlDesigner.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutControlDesigner.cs new file mode 100644 index 00000000..74a06041 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutControlDesigner.cs @@ -0,0 +1,767 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.Layout; +using System.Drawing; +using System.ComponentModel.Design; +using System.Windows.Forms; +using System.ComponentModel; +using System.Collections; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Layout.Design +{ + public class LayoutControlDesigner : ParentControlDesigner + { + #region Constructor + + #endregion + + #region Implementation + public override void Initialize(System.ComponentModel.IComponent component) + { + base.Initialize(component); + + IComponentChangeService changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService)); + if (changeService != null) + { + changeService.ComponentAdded += new ComponentEventHandler(ComponentAdded); + changeService.ComponentAdding += new ComponentEventHandler(ComponentAdding); + changeService.ComponentChanged += new ComponentChangedEventHandler(ComponentChanged); + changeService.ComponentRemoved += OnComponentRemoved; + changeService.ComponentRemoving += OnComponentRemoving; + } + //ISelectionService selectionService = (ISelectionService)GetService(typeof(ISelectionService)); + //if (selectionService != null) + // selectionService.SelectionChanged += SelectionChanged; + } + + protected override void Dispose(bool disposing) + { + IComponentChangeService ss = (IComponentChangeService)GetService(typeof(IComponentChangeService)); + if (ss != null) + { + ss.ComponentAdded -= ComponentAdded; + ss.ComponentAdding -= ComponentAdding; + ss.ComponentChanged -= ComponentChanged; + ss.ComponentRemoved -= OnComponentRemoved; + } + + //ISelectionService selectionService = (ISelectionService)GetService(typeof(ISelectionService)); + //if (selectionService != null) + // selectionService.SelectionChanged -= SelectionChanged; + base.Dispose(disposing); + } + + private bool _ControlDeleting = false; + private void DestroyChildItems(LayoutItemBase parent, IDesignerHost dh) + { + LayoutGroup group = parent as LayoutGroup; + if (group == null) return; + + foreach (LayoutItemBase item in group.Items) + { + DestroyChildItems(item, dh); + dh.DestroyComponent(item); + } + } + private void OnComponentRemoving(object sender, ComponentEventArgs e) + { + if (e.Component != this.Component) + return; + + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + if (dh == null) + return; + + _ControlDeleting = true; + + LayoutControl lc = (LayoutControl)e.Component; + if (lc.RootGroup.Items.Count == 0) return; + + LayoutItemBase[] items = new LayoutItemBase[lc.RootGroup.Items.Count]; + lc.RootGroup.Items.CopyTo(items); + foreach (LayoutItemBase item in items) + { + DestroyChildItems(item, dh); + dh.DestroyComponent(item); + } + + _ControlDeleting = false; + } + + private void OnComponentRemoved(object sender, ComponentEventArgs e) + { + if (_ControlDeleting) return; + if (e.Component is LayoutItemBase && ((LayoutItemBase)e.Component).GetLayoutControl() == this.Control && !_DestroyingItem) + { + CleanupRemovedControls(false); + CleanupRemovedItems((LayoutItemBase)e.Component, true, false); + } + else if (e.Component is Control && IsContained((Control)e.Component)) + { + LayoutControl lc = (LayoutControl)this.Control; + if (lc != null) + { + LayoutItemBase item = lc.FindControlItem((Control)e.Component); + if (item != null) + CleanupRemovedItems(item, false, true); + } + } + + } + private bool IsContained(Control c) + { + LayoutControl lc = (LayoutControl)this.Control; + if (lc == null || c == null || lc == c) return false; + Control stopParent = lc.Parent; + Control test = c; + do + { + if (test == lc) return true; + test = test.Parent; + } while (test != null && test != stopParent); + return false; + } + private bool _DestroyingItem = false; + private void CleanupRemovedItems(LayoutItemBase item, bool removeControl, bool destroyItem) + { + if (item == null || item.Parent == null) return; + LayoutControl lc = this.Control as LayoutControl; + if (lc == null) return; + + IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); + IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService)); + DesignerTransaction dt = host.CreateTransaction("Removing Layout Item"); + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["RootGroup"]); + ISelectionService ss = (ISelectionService)GetService(typeof(ISelectionService)); + ICollection selectedComponents = ss.GetSelectedComponents(); + if (IsSelected(selectedComponents, item)) + { + ss.SetSelectedComponents(new IComponent[] { item }, SelectionTypes.Remove); + } + + if (item.Parent is LayoutGroup) + { + LayoutGroup parentGroup = null; + if (item.Parent != lc.RootGroup && item.Parent is LayoutGroup) + { + parentGroup = (LayoutGroup)item.Parent; + cc.OnComponentChanging(parentGroup, TypeDescriptor.GetProperties(parentGroup)["Items"]); + } + ((LayoutGroup)item.Parent).Items.Remove(item); + if (parentGroup != null) + cc.OnComponentChanged(parentGroup, TypeDescriptor.GetProperties(parentGroup)["Items"], null, null); + if (destroyItem) + { + _DestroyingItem = true; + try + { + host.DestroyComponent(item); + } + finally + { + _DestroyingItem = false; + } + } + } + if (removeControl && item is LayoutControlItem) + { + LayoutControlItem lci = (LayoutControlItem)item; + if (lci.Control != null && lci.Control.Parent == lc) + { + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["Controls"]); + lc.Controls.Remove(lci.Control); + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["Controls"], null, null); + host.DestroyComponent(lci.Control); + } + } + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["RootGroup"], null, null); + dt.Commit(); + lc.PerformLayout(); + ss.SetSelectedComponents(new IComponent[] { lc }, SelectionTypes.Replace); + + } + private void CleanupRemovedControls(bool destroyComponents) + { + LayoutControl lc = this.Control as LayoutControl; + if (lc == null) return; + List removed = lc.FindOrphanedControlItems(); + if (removed != null && removed.Count > 0) + { + + IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); + IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService)); + DesignerTransaction dt = host.CreateTransaction("Removing Layout Control Item"); + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["RootGroup"]); + ISelectionService ss = (ISelectionService)GetService(typeof(ISelectionService)); + ICollection selectedComponents = ss.GetSelectedComponents(); + foreach (LayoutItemBase item in removed) + { + LayoutControlItem lci = item as LayoutControlItem; + if (IsSelected(selectedComponents, item)) + { + ss.SetSelectedComponents(new IComponent[] { item }, SelectionTypes.Remove); + } + if (lci != null && IsSelected(selectedComponents, lci.Control)) + { + ss.SetSelectedComponents(new IComponent[] { lci.Control }, SelectionTypes.Remove); + } + lci.Control = null; + + if (lci.Parent is LayoutGroup) + { + LayoutGroup parentGroup = null; + if (item.Parent != lc.RootGroup && item.Parent is LayoutGroup) + { + parentGroup = (LayoutGroup)item.Parent; + cc.OnComponentChanging(parentGroup, TypeDescriptor.GetProperties(parentGroup)["Items"]); + } + ((LayoutGroup)lci.Parent).Items.Remove(item); + if (parentGroup != null) + cc.OnComponentChanged(parentGroup, TypeDescriptor.GetProperties(parentGroup)["Items"], null, null); + } + if (destroyComponents) + host.DestroyComponent(item); + } + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["RootGroup"], null, null); + dt.Commit(); + lc.PerformLayout(); + ss.SetSelectedComponents(new IComponent[] { lc }, SelectionTypes.Replace); + } + } + private bool IsControlSelected + { + get + { + ISelectionService ss = (ISelectionService)GetService(typeof(ISelectionService)); + if (ss == null) return false; + ICollection selected = ss.GetSelectedComponents(); + if (IsSelected(selected, this.Control)) + return true; + return false; + } + } + private bool IsSelected(ICollection selectedComponents, object item) + { + foreach (object o in selectedComponents) + { + if (o == item) return true; + } + return false; + } + void ComponentChanged(object sender, ComponentChangedEventArgs e) + { + if (e.Component == this.Control) + { + if (e.Member != null && e.Member.Name == "Controls") + { + // Find out what changed... + LayoutControl lc = (LayoutControl)this.Control; + if (lc == null) return; + foreach (Control c in lc.Controls) + { + if (lc.IsSystemControl(c)) continue; + LayoutItemBase item = lc.FindControlItem(c); + if (item == null) + { + IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); + IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService)); + DesignerTransaction dt = host.CreateTransaction("Creating Layout Control Item"); + LayoutControlItem lci = (LayoutControlItem)host.CreateComponent(typeof(LayoutControlItem)); + TypeDescriptor.GetProperties(lci)["Control"].SetValue(lci, c); + lc.SetupControlItem(lci); + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["RootGroup"]); + cc.OnComponentChanging(lc.RootGroup, TypeDescriptor.GetProperties(lc)["Items"]); + + lc.RootGroup.Items.Add(lci); + + cc.OnComponentChanged(lc.RootGroup, TypeDescriptor.GetProperties(lc)["Items"], null, null); + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["RootGroup"], null, null); + + dt.Commit(); + lc.PerformLayout(); + } + } + + // Check removed + CleanupRemovedControls(true); + } + } + } + protected override bool AllowSetChildIndexOnDrop + { + get + { + return false; + } + } + + protected override void OnMouseDragBegin(int x, int y) + { + //base.OnMouseDragBegin(x, y); + } + protected override void OnDragEnter(DragEventArgs de) + { + if (de.Data is LayoutItemDataObject) + { + de.Effect = DragDropEffects.Move; + //LayoutControl lc = (LayoutControl)this.Control; + //lc.Text = string.Format("{0} DragEnter", DateTime.Now.TimeOfDay); + //lc.Invalidate(); + return; + } + + base.OnDragEnter(de); + } + protected override void OnDragOver(DragEventArgs de) + { + LayoutControl lc = (LayoutControl)this.Control; + if (lc == null) return; + //lc.Text = de.Data.GetType().ToString(); + //lc.Invalidate(); + //lc.Text = "DragOver"; + //lc.Invalidate(); + ISelectionService selectionService = (ISelectionService)this.GetService(typeof(ISelectionService)); + //lc.Text = string.Format("GetSelectedComponents().Count={0}", selectionService.GetSelectedComponents().Count); + if (selectionService != null && (selectionService.PrimarySelection is Control || de.Data is LayoutItemDataObject) && selectionService.GetSelectedComponents().Count == 1) + { + LayoutItemBase item = null; + if (de.Data is LayoutItemDataObject) + { + LayoutItemDataObject d = (LayoutItemDataObject)de.Data; + item = d.DragComponent; + } + else + { + Control c = (Control)selectionService.PrimarySelection; + item = lc.FindControlItem(c); + } + if (item != null) + { + HitTestInsertInfo info = lc.GetHitTestInsertInfo(item, lc.PointToClient(new Point(de.X, de.Y))); + if (!info.InsertMarkerBounds.IsEmpty) + lc.ShowInsertMarker(info.InsertMarkerBounds); + else + lc.HideInsertMarker(); + de.Effect = DragDropEffects.Move; + return; + } + } + + base.OnDragOver(de); + } + + protected override void OnDragLeave(EventArgs e) + { + LayoutControl lc = (LayoutControl)this.Control; + if (lc == null) return; + lc.HideInsertMarker(); + base.OnDragLeave(e); + } + + protected override void OnDragDrop(DragEventArgs de) + { + LayoutControl lc = (LayoutControl)this.Control; + if (lc == null) return; + lc.HideInsertMarker(); + + ISelectionService selectionService = (ISelectionService)this.GetService(typeof(ISelectionService)); + if (selectionService != null && (selectionService.PrimarySelection is Control || de.Data is LayoutItemDataObject) && selectionService.GetSelectedComponents().Count == 1) + { + LayoutItemBase item = null; + if (de.Data is LayoutItemDataObject) + { + item = ((LayoutItemDataObject)de.Data).DragComponent; + } + else + { + Control c = (Control)selectionService.PrimarySelection; + item = lc.FindControlItem(c); + } + if (item != null) + { + HitTestInsertInfo info = lc.GetHitTestInsertInfo(item, lc.PointToClient(new Point(de.X, de.Y))); + if (info.Parent != null) + { + IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); + IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService)); + DesignerTransaction dt = host.CreateTransaction("Moving Layout Control Item"); + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["RootGroup"]); + //lc.Text = string.Format("Moving at: {0}", info.InsertIndex); + //lc.Invalidate(); + if (info.Parent != item.Parent) + { + LayoutGroup parentGroup = (LayoutGroup)item.Parent; + if (parentGroup != lc.RootGroup) + cc.OnComponentChanging(parentGroup, TypeDescriptor.GetProperties(parentGroup)["Items"]); + parentGroup.Items.Remove(item); + if (parentGroup != lc.RootGroup) + cc.OnComponentChanged(parentGroup, TypeDescriptor.GetProperties(parentGroup)["Items"], null, null); + if (info.Parent != lc.RootGroup) + cc.OnComponentChanging(info.Parent, TypeDescriptor.GetProperties(parentGroup)["Items"]); + if (info.InsertIndex >= 0) + info.Parent.Items.Insert(info.InsertIndex, item); + else + info.Parent.Items.Add(item); + if (info.Parent != lc.RootGroup) + cc.OnComponentChanged(info.Parent, TypeDescriptor.GetProperties(parentGroup)["Items"], null, null); + } + else + { + LayoutGroup parentGroup = (LayoutGroup)item.Parent; + if (parentGroup != lc.RootGroup) + cc.OnComponentChanging(parentGroup, TypeDescriptor.GetProperties(parentGroup)["Items"]); + info.Parent.Items.Move(item, info.InsertIndex); + if (parentGroup != lc.RootGroup) + cc.OnComponentChanged(parentGroup, TypeDescriptor.GetProperties(parentGroup)["Items"], null, null); + } + + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["RootGroup"], null, null); + dt.Commit(); + lc.PerformLayout(); + + SelectionRefresh(); + } + return; + } + } + + + base.OnDragDrop(de); + } + + void ComponentAdding(object sender, ComponentEventArgs e) + { + //Control c = e.Component as Control; + //if (c != null) + //{ + // if (c != null && c.Parent == this.Control) + // { + // MessageBox.Show("Component ADDING"); + // } + // else + // MessageBox.Show(string.Format("Component ADDING UNRECOGNIZED Parent: {0} Site:{1}", c.Parent, e.Component.Site)); + //} + } + + void ComponentAdded(object sender, ComponentEventArgs e) + { + //Control c = e.Component as Control; + + //if (c != null) + //{ + // if (c != null && c.Parent == this.Control) + // { + // MessageBox.Show("Component ADDED"); + // } + // else + // MessageBox.Show(string.Format("Component ADDED UNRECOGNIZED Parent: {0}", c.Parent)); + //} + } + protected override bool GetHitTest(System.Drawing.Point point) + { + if (base.GetHitTest(point)) + return true; + + LayoutControl c = this.Control as LayoutControl; + if (c == null) return false; + + Point pc = c.PointToClient(point); + if (c.VScrollBar.Visible && c.VScrollBar.Bounds.Contains(pc)) + return true; + if (c.HScrollBar.Visible && c.HScrollBar.Bounds.Contains(pc)) + return true; + + return base.GetHitTest(point); + } + + public void SelectionRefresh() + { + Message m = new Message(); + m.Msg = 0x115; + base.WndProc(ref m); + } + private System.Windows.Forms.Control _DesignerHost = null; + /// + /// Selection support for items on container. + /// + protected override void WndProc(ref Message m) + { + if (_DesignerHost == null) + _DesignerHost = System.Windows.Forms.Control.FromHandle(m.HWnd); + switch (m.Msg) + { + case WinApi.WM_LBUTTONDOWN: + case WinApi.WM_RBUTTONDOWN: + { + if (OnMouseDown(ref m, m.Msg == WinApi.WM_LBUTTONDOWN ? MouseButtons.Left : MouseButtons.Right)) + return; + break; + } + case WinApi.WM_RBUTTONUP: + case WinApi.WM_LBUTTONUP: + { + if (OnMouseUp(ref m, m.Msg == WinApi.WM_LBUTTONDOWN ? MouseButtons.Left : MouseButtons.Right)) + return; + + break; + } + } + + base.WndProc(ref m); + } + + protected virtual bool OnMouseUp(ref Message m, MouseButtons param1) + { + if (_MouseDownSelectionPerformed) + { + _MouseDownSelectionPerformed = false; + return true; + } + return false; + } + private bool _MouseDownSelectionPerformed = false; + protected virtual bool OnMouseDown(ref Message m, MouseButtons button) + { + LayoutControl lc = this.Control as LayoutControl; + if (lc == null) return false; + Point p = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam)); + LayoutItemBase item = lc.HitTest(p); + if (item != null) + { + SelectComponent(item, (Control.ModifierKeys == Keys.Control || Control.ModifierKeys == Keys.Shift) ? SelectionTypes.Add : SelectionTypes.Primary); + _MouseDownSelectionPerformed = true; + return true; + } + else if (!IsControlSelected) + { + SelectComponent(this.Control, SelectionTypes.Replace); + //return true; + } + return false; + } + + protected virtual void SelectComponent(IComponent comp, SelectionTypes selectionType) + { + ISelectionService selection = (ISelectionService)this.GetService(typeof(ISelectionService)); + if (selection != null && comp != null) + { + ArrayList arr = new ArrayList(1); + arr.Add(comp); + selection.SetSelectedComponents(arr, selectionType); + } + } + + public override ICollection AssociatedComponents + { + get + { + ArrayList list = base.AssociatedComponents as ArrayList; + if (list == null) list = new ArrayList(); + + LayoutControl lc = (LayoutControl)this.Control; + if (lc == null) return list; + + if (list != null) + { + foreach (LayoutItemBase item in lc.RootGroup.Items) + { + list.Add(item); + } + } + + return list; + } + } + + protected override void OnPaintAdornments(PaintEventArgs pe) + { + LayoutControl lc = (LayoutControl)base.Component; + if (lc != null && lc.Visible) + { + using (Pen borderPen = this.BorderPen) + { + Rectangle clientRectangle = this.Control.ClientRectangle; + clientRectangle.Width--; + clientRectangle.Height--; + pe.Graphics.DrawRectangle(borderPen, clientRectangle); + } + } + base.OnPaintAdornments(pe); + } + protected Pen BorderPen + { + get + { + Color color = (this.Control.BackColor.GetBrightness() < 0.5) ? ControlPaint.Light(this.Control.BackColor) : ControlPaint.Dark(this.Control.BackColor); + Pen pen = new Pen(color); + pen.DashStyle = DashStyle.Dash; + return pen; + } + } + + public override DesignerVerbCollection Verbs + { + get + { + DesignerVerb[] verbs; + verbs = new DesignerVerb[] + { + new DesignerVerb("Add Spacer", new EventHandler(AddSpacerItem)), + new DesignerVerb("Add Group", new EventHandler(AddGroupItem)) + }; + return new DesignerVerbCollection(verbs); + } + } + //private void AddLabelItem(object sender, EventArgs e) + //{ + // AddLabelItem(); + //} + + //private void AddLabelItem() + //{ + // IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + // LayoutControl lc = this.Control as LayoutControl; + // if (lc == null || dh == null) + // return; + + // DesignerTransaction dt = dh.CreateTransaction("Creating Label Item"); + // try + // { + // IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + // if (cc != null) + // { + // cc.OnComponentChanging(this.Component, null); + // cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["RootGroup"]); + // cc.OnComponentChanging(lc.RootGroup, TypeDescriptor.GetProperties(lc)["Items"]); + // } + + // LayoutLabelItem item = null; + // item = dh.CreateComponent(typeof(LayoutLabelItem)) as LayoutLabelItem; + // item.Width = 100; + // item.WidthType = eLayoutSizeType.Percent; + // item.Height = 22; + // item.Text = "Layout Label"; + // lc.RootGroup.Items.Add(item); + // lc.PerformLayout(); + // if (cc != null) + // { + // cc.OnComponentChanged(lc.RootGroup, TypeDescriptor.GetProperties(lc)["Items"], null, null); + // cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["RootGroup"], null, null); + // cc.OnComponentChanged(this.Component, null, null, null); + // } + + // SelectComponent(item, SelectionTypes.Replace); + // } + // catch + // { + // dt.Cancel(); + // } + // finally + // { + // if (!dt.Canceled) dt.Commit(); + // } + //} + private void AddSpacerItem(object sender, EventArgs e) + { + AddSpacerItem(); + } + + private void AddSpacerItem() + { + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + LayoutControl lc = this.Control as LayoutControl; + if (lc == null || dh == null) + return; + + DesignerTransaction dt = dh.CreateTransaction("Creating Spacer Item"); + try + { + IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if (cc != null) + { + cc.OnComponentChanging(this.Component, null); + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["RootGroup"]); + cc.OnComponentChanging(lc.RootGroup, TypeDescriptor.GetProperties(lc)["Items"]); + } + + LayoutSpacerItem item = null; + item = dh.CreateComponent(typeof(LayoutSpacerItem)) as LayoutSpacerItem; + item.Width = 32; + item.Height = 32; + lc.RootGroup.Items.Add(item); + lc.PerformLayout(); + if (cc != null) + { + cc.OnComponentChanged(lc.RootGroup, TypeDescriptor.GetProperties(lc)["Items"], null, null); + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["RootGroup"], null, null); + cc.OnComponentChanged(this.Component, null, null, null); + } + + SelectComponent(item, SelectionTypes.Replace); + } + catch + { + dt.Cancel(); + } + finally + { + if (!dt.Canceled) dt.Commit(); + } + } + + private void AddGroupItem(object sender, EventArgs e) + { + AddGroupItem(); + } + + private void AddGroupItem() + { + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + LayoutControl lc = this.Control as LayoutControl; + if (lc == null || dh == null) + return; + + DesignerTransaction dt = dh.CreateTransaction("Creating Group Item"); + try + { + IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if (cc != null) + { + cc.OnComponentChanging(this.Component, null); + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["RootGroup"]); + cc.OnComponentChanging(lc.RootGroup, TypeDescriptor.GetProperties(lc)["Items"]); + } + + LayoutGroup item = null; + item = dh.CreateComponent(typeof(LayoutGroup)) as LayoutGroup; + item.Width = 200; + item.Height = 100; + item.TextPosition = eLayoutPosition.Top; + item.MinSize = new Size(120, 32); + lc.RootGroup.Items.Add(item); + lc.PerformLayout(); + if (cc != null) + { + cc.OnComponentChanged(lc.RootGroup, TypeDescriptor.GetProperties(lc)["Items"], null, null); + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["RootGroup"], null, null); + cc.OnComponentChanged(this.Component, null, null, null); + } + + SelectComponent(item, SelectionTypes.Replace); + } + catch + { + dt.Cancel(); + } + finally + { + if (!dt.Canceled) dt.Commit(); + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutControlItemDesigner.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutControlItemDesigner.cs new file mode 100644 index 00000000..86c806d4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutControlItemDesigner.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; +using DevComponents.DotNetBar.Layout; +using System.Collections; + +namespace DevComponents.DotNetBar.Layout.Design +{ + public class LayoutControlItemDesigner : LayoutItemBaseDesigner + { + #region Constructor + + #endregion + + #region Implementation + public override System.Collections.ICollection AssociatedComponents + { + get + { + LayoutControlItem item = (LayoutControlItem)this.Component; + + if (item.Control != null && item.Control.Site != null) + { + ArrayList list = new ArrayList(); + list.Add(item.Control); + return list; + } + + return base.AssociatedComponents; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutGroupDesigner.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutGroupDesigner.cs new file mode 100644 index 00000000..61851e7b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutGroupDesigner.cs @@ -0,0 +1,222 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; +using System.ComponentModel.Design; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout.Design +{ + public class LayoutGroupDesigner : LayoutItemBaseDesigner + { + #region Constructor + + #endregion + + #region Implementation + + public override System.Collections.ICollection AssociatedComponents + { + get + { + LayoutGroup group = (LayoutGroup)this.Component; + + if (group.Items.Count>0) + { + ArrayList list = new ArrayList(); + foreach (LayoutItemBase child in group.Items) + { + if (child.Site != null) + list.Add(child); + } + return list; + } + + return base.AssociatedComponents; + } + } + + public override DesignerVerbCollection Verbs + { + get + { + DesignerVerb[] verbs; + verbs = new DesignerVerb[] + { + new DesignerVerb("Add Spacer", new EventHandler(AddSpacerItem)), + new DesignerVerb("Add Group", new EventHandler(AddGroupItem)), + new DesignerVerb("Apply Panel Style", new EventHandler(PanelStyle)), + new DesignerVerb("Apply Group Panel Style", new EventHandler(GroupPanelStyle)), + new DesignerVerb("Remove Panel Style", new EventHandler(RemovePanelStyle)) + }; + return new DesignerVerbCollection(verbs); + } + } + private void AddSpacerItem(object sender, EventArgs e) + { + AddSpacerItem(); + } + + private void AddSpacerItem() + { + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + LayoutGroup lc = this.Component as LayoutGroup; + if (lc == null || dh == null) + return; + + DesignerTransaction dt = dh.CreateTransaction("Creating Spacer Item"); + try + { + IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if (cc != null) + { + cc.OnComponentChanging(this.Component, null); + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["Items"]); + } + + LayoutSpacerItem item = null; + item = dh.CreateComponent(typeof(LayoutSpacerItem)) as LayoutSpacerItem; + item.Width = 32; + item.Height = 32; + lc.Items.Add(item); + lc.InvalidateLayout(); + if (cc != null) + { + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["Items"], null, null); + cc.OnComponentChanged(this.Component, null, null, null); + } + + SelectComponent(item, SelectionTypes.Replace); + } + catch + { + dt.Cancel(); + } + finally + { + if (!dt.Canceled) dt.Commit(); + } + } + + private void AddGroupItem(object sender, EventArgs e) + { + AddGroupItem(); + } + + private void AddGroupItem() + { + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + LayoutGroup lc = this.Component as LayoutGroup; + if (lc == null || dh == null) + return; + + DesignerTransaction dt = dh.CreateTransaction("Creating Group Item"); + try + { + IComponentChangeService cc = this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + if (cc != null) + { + cc.OnComponentChanging(this.Component, null); + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["Items"]); + } + + LayoutGroup item = null; + item = dh.CreateComponent(typeof(LayoutGroup)) as LayoutGroup; + item.Width = 200; + item.Height = 100; + item.TextPosition = eLayoutPosition.Top; + item.MinSize = new Size(120, 32); + lc.Items.Add(item); + lc.InvalidateLayout(); + if (cc != null) + { + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["Items"], null, null); + cc.OnComponentChanged(this.Component, null, null, null); + } + + SelectComponent(item, SelectionTypes.Replace); + } + catch + { + dt.Cancel(); + } + finally + { + if (!dt.Canceled) dt.Commit(); + } + } + + private void PanelStyle(object sender, EventArgs e) + { + LayoutGroup group = (LayoutGroup)this.Component; + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + if (group == null || dh == null) + return; + + DesignerTransaction dt = dh.CreateTransaction("Apply Panel Style"); + + TypeDescriptor.GetProperties(group)["Appearance"].SetValue(group, eGroupAppearance.Panel); // group.Appearance = eGroupAppearance.Panel; + TypeDescriptor.GetProperties(group)["CaptionHeight"].SetValue(group, 22); // group.CaptionHeight = 22; + TypeDescriptor.GetProperties(group)["TextLineAlignment"].SetValue(group, DevComponents.DotNetBar.Layout.eTextLineAlignment.Middle); // group.TextLineAlignment = DevComponents.DotNetBar.Layout.eTextLineAlignment.Middle; + TypeDescriptor.GetProperties(group)["TextPosition"].SetValue(group, DevComponents.DotNetBar.Layout.eLayoutPosition.Top); // group.TextPosition = DevComponents.DotNetBar.Layout.eLayoutPosition.Top; + TypeDescriptor.GetProperties(group)["TextAlignment"].SetValue(group, eTextAlignment.Default); // group.TextAlignment = eTextAlignment.Default; + if (string.IsNullOrEmpty(group.Text)) + TypeDescriptor.GetProperties(group)["Text"].SetValue(group, "Caption"); // group.Text = "Caption"; + + dt.Commit(); + + } + + private void GroupPanelStyle(object sender, EventArgs e) + { + LayoutGroup group = (LayoutGroup)this.Component; + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + if (group == null || dh == null) + return; + + DesignerTransaction dt = dh.CreateTransaction("Apply Group Panel Style"); + + TypeDescriptor.GetProperties(group)["Appearance"].SetValue(group, eGroupAppearance.GroupPanel); // group.Appearance = eGroupAppearance.GroupPanel; + TypeDescriptor.GetProperties(group)["CaptionHeight"].SetValue(group, 18); // group.CaptionHeight = 18; + TypeDescriptor.GetProperties(group)["TextLineAlignment"].SetValue(group, DevComponents.DotNetBar.Layout.eTextLineAlignment.Middle); // group.TextLineAlignment = DevComponents.DotNetBar.Layout.eTextLineAlignment.Middle; + TypeDescriptor.GetProperties(group)["TextPosition"].SetValue(group, DevComponents.DotNetBar.Layout.eLayoutPosition.Top); // group.TextPosition = DevComponents.DotNetBar.Layout.eLayoutPosition.Top; + TypeDescriptor.GetProperties(group)["TextAlignment"].SetValue(group, eTextAlignment.Center); // group.TextAlignment = eTextAlignment.Center; + if (string.IsNullOrEmpty(group.Text)) + TypeDescriptor.GetProperties(group)["Text"].SetValue(group, "Caption"); // group.Text = "Caption"; + + dt.Commit(); + } + + private void RemovePanelStyle(object sender, EventArgs e) + { + LayoutGroup group = (LayoutGroup)this.Component; + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + if (group == null || dh == null) + return; + + DesignerTransaction dt = dh.CreateTransaction("Remove Panel Style"); + + TypeDescriptor.GetProperties(group)["Appearance"].SetValue(group, eGroupAppearance.None); // group.Appearance = eGroupAppearance.None; + TypeDescriptor.GetProperties(group)["TextLineAlignment"].SetValue(group, DevComponents.DotNetBar.Layout.eTextLineAlignment.Default); // group.TextLineAlignment = DevComponents.DotNetBar.Layout.eTextLineAlignment.Default; + TypeDescriptor.GetProperties(group)["CaptionHeight"].SetValue(group, 0); // group.CaptionHeight = 0; + TypeDescriptor.GetProperties(group)["TextPosition"].SetValue(group, DevComponents.DotNetBar.Layout.eLayoutPosition.Default); // group.TextPosition = DevComponents.DotNetBar.Layout.eLayoutPosition.Default; + TypeDescriptor.GetProperties(group)["TextAlignment"].SetValue(group, eTextAlignment.Default); // group.TextAlignment = eTextAlignment.Default; + TypeDescriptor.GetProperties(group)["Text"].SetValue(group, ""); // group.Text = "Caption"; + dt.Commit(); + + } + + protected virtual void SelectComponent(IComponent comp, SelectionTypes selectionType) + { + ISelectionService selection = (ISelectionService)this.GetService(typeof(ISelectionService)); + if (selection != null && comp != null) + { + ArrayList arr = new ArrayList(1); + arr.Add(comp); + selection.SetSelectedComponents(arr, selectionType); + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutItemBaseDesigner.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutItemBaseDesigner.cs new file mode 100644 index 00000000..73474dce --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/LayoutItemBaseDesigner.cs @@ -0,0 +1,543 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel.Design; +using System.Collections; +using System.Windows.Forms.Design.Behavior; +using System.Windows.Forms; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Layout.Design +{ + public class LayoutItemBaseDesigner : ComponentDesigner + { + #region Constructor + /// + /// Initializes a new instance of the LayoutItemBaseDesigner class. + /// + public LayoutItemBaseDesigner() + { + + } + #endregion + + #region Implementation + public override void Initialize(System.ComponentModel.IComponent component) + { + base.Initialize(component); + + ISelectionService selectionService = (ISelectionService)GetService(typeof(ISelectionService)); + if (selectionService != null) + selectionService.SelectionChanged += SelectionChanged; + + BehaviorService behaviorService = (BehaviorService)GetService(typeof(BehaviorService)); + Adorner designerActionAdorner = new Adorner(); + behaviorService.Adorners.Add(designerActionAdorner); + LayoutItemGlyph glyph = new LayoutItemGlyph(behaviorService, (LayoutItemBase)component); + designerActionAdorner.Glyphs.Add(glyph); + } + protected override void Dispose(bool disposing) + { + ISelectionService selectionService = (ISelectionService)GetService(typeof(ISelectionService)); + if (selectionService != null) + selectionService.SelectionChanged -= SelectionChanged; + base.Dispose(disposing); + } + private void OnComponentRemoved(object sender, ComponentEventArgs e) + { + if (e.Component == this.Component) + { + LayoutItemBase item = e.Component as LayoutItemBase; + LayoutGroup parent = item.Parent as LayoutGroup; + LayoutControl lc = null; + if (parent != null) lc = parent.GetLayoutControl(); + if (item != null && parent != null && parent.Items.Contains(item)) + { + IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService)); + if (cc != null) + cc.OnComponentChanging(parent, TypeDescriptor.GetProperties(parent)["Items"]); + parent.Items.Remove(item); + if (cc != null) + cc.OnComponentChanged(parent, TypeDescriptor.GetProperties(parent)["Items"], null, null); + if (lc != null) + { + lc.Invalidate(); + IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); + if (host != null) + { + IDesigner designer = host.GetDesigner(lc); + if (designer is LayoutControlDesigner) + { + ((LayoutControlDesigner)designer).SelectionRefresh(); + } + } + } + } + } + } + private void SelectionChanged(object sender, EventArgs e) + { + bool selected = false; + ISelectionService selectionService = (ISelectionService)GetService(typeof(ISelectionService)); + if (selectionService.PrimarySelection == this.Component) + selected = true; + else + { + ICollection selectedComponents = selectionService.GetSelectedComponents(); + foreach (object o in selectedComponents) + { + if (o == this.Component) + { + selected = true; + break; + } + } + } + + LayoutItemBase item = (LayoutItemBase)this.Component; + item.IsSelected = selected; + } + + public override System.Collections.ICollection AssociatedComponents + { + get + { + LayoutGroup group = this.Component as LayoutGroup; + if (group == null) + return base.AssociatedComponents; + List items = new List(); + group.Items.CopyTo(items); + return items; + } + } + + protected override void PreFilterProperties(IDictionary properties) + { + base.PreFilterProperties(properties); + properties["Visible"] = TypeDescriptor.CreateProperty(typeof(LayoutItemBaseDesigner), (PropertyDescriptor)properties["Visible"], new Attribute[] + { + new DefaultValueAttribute(true), + new BrowsableAttribute(true), + new CategoryAttribute("Appearance")}); + } + /// + /// Gets or sets whether item is visible. + /// + [DefaultValue(true), Browsable(true), Category("Appearance"), Description("Indicates visiblity of the item.")] + public bool Visible + { + get + { + return (bool)ShadowProperties["Visible"]; + } + set + { + // this value is not passed to the actual control + this.ShadowProperties["Visible"] = value; + } + } + #endregion + } + + class LayoutItemGlyph : Glyph + { + LayoutItemBase _Item; + BehaviorService _BehaviorSvc; + + public LayoutItemGlyph(BehaviorService behaviorSvc, LayoutItemBase item) + : + base(new LayoutItemBehavior()) + { + _BehaviorSvc = behaviorSvc; + _Item = item; + } + + public LayoutItemBase Item + { + get + { + return _Item; + } + } + + public override Rectangle Bounds + { + get + { + // Glyph coordinates are in adorner window coordinates, so we must map using the behavior service. + Rectangle bounds = Rectangle.Empty; + if (_Item != null && _Item.GetLayoutControl() != null) + { + Point edge = _BehaviorSvc.ControlToAdornerWindow(_Item.GetLayoutControl()); + + if (_Item is LayoutControlItem) + bounds = _Item.ActualTextBounds; + else + bounds = _Item.Bounds; + bounds.Offset(edge); + } + + return bounds; + } + } + + public Rectangle CompleteBounds + { + get + { + Rectangle bounds = Rectangle.Empty; + if (_Item != null && _Item.GetLayoutControl() != null) + { + Point edge = _BehaviorSvc.ControlToAdornerWindow(_Item.GetLayoutControl()); + bounds = _Item.Bounds; + bounds.Offset(edge); + } + return bounds; + } + } + + public override Cursor GetHitTest(Point p) + { + if (_Item != null && !_Item.IsSelected) + return null; + // GetHitTest is called to see if the point is + // within this glyph. This gives us a chance to decide + // what cursor to show. Returning null from here means + // the mouse pointer is not currently inside of the glyph. + // Returning a valid cursor here indicates the pointer is + // inside the glyph, and also enables our Behavior property + // as the active behavior. + if (Bounds.Contains(p)) + { + return Cursors.SizeAll; + } + + return null; + } + + private bool GetIsItemVisible() + { + if (_Item == null) + return false; + LayoutControl lc = _Item.GetLayoutControl(); + if (lc != null) + { + if (!lc.Visible) return false; + if (lc.Parent != null && !lc.Parent.Visible) return false; + if(lc.Parent is TabControlPanel && ((TabControlPanel)lc.Parent).TabItem!=null && !((TabControlPanel)lc.Parent).TabItem.IsSelected) + return false; + if (lc.Parent is SuperTabControlPanel && ((SuperTabControlPanel)lc.Parent).TabItem != null && !((SuperTabControlPanel)lc.Parent).TabItem.IsSelected) + return false; + } + return true; + } + + public override void Paint(PaintEventArgs pe) + { + // Draw our glyph + if (_Item != null) + { + if (_Item.IsSelected) + { + Rectangle r = CompleteBounds; + r.Width--; + r.Height--; + Graphics g = pe.Graphics; + using (Pen pen = new Pen(SelectionColor)) + { + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; + g.DrawRectangle(pen, r); + } + } + else if ((!_Item.TextVisible || string.IsNullOrEmpty(_Item.Text)) && GetIsItemVisible()) + { + Rectangle r = CompleteBounds; + r.Width--; + r.Height--; + Graphics g = pe.Graphics; + using (Pen pen = new Pen(SelectableColor)) + { + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; + g.DrawRectangle(pen, r); + } + } + } + + } + + private static readonly Color SelectableColor = ColorHelpers.GetColor(0x8C8C91); + private static readonly Color SelectionColor = ColorHelpers.GetColor(0x696969); + + // By providing our own behavior we can do something interesting + // when the user clicks or manipulates our glyph. + class LayoutItemBehavior : Behavior + { + //public override bool OnMouseUp(Glyph g, MouseButtons button) + //{ + // //MessageBox.Show("Hey, you clicked the mouse here"); + // //return true; // indicating we processed this event. + // return base.OnMouseUp(g, button); + //} + + private Point _MouseDownLocation = Point.Empty; + public override bool OnMouseDown(Glyph g, MouseButtons button, Point mouseLoc) + { + LayoutItemGlyph itemGlyph = (LayoutItemGlyph)g; + if (itemGlyph._Item != null && itemGlyph._Item.Site != null && (!itemGlyph._Item.IsSelected || itemGlyph._Item is LayoutGroup)) + { + LayoutItemBase item = itemGlyph._Item; + IComponent selectItem = item; + if (item is LayoutGroup) + { + LayoutControl lc = item.GetLayoutControl(); + if (lc == null) return base.OnMouseDown(g, button, mouseLoc); + Point loc = lc.PointToClient(Control.MousePosition); + LayoutItemBase itemAt = lc.HitTest(loc); + if (itemAt != null && itemAt != item && itemAt.Site != null) + { + // Selection is selecting something inside of group + selectItem = itemAt; + if (itemAt is LayoutControlItem) + { + LayoutControlItem lci = (LayoutControlItem)itemAt; + if (lci.Control != null && lci.Control.ClientRectangle.Contains(lci.Control.PointToClient(Control.MousePosition)) && lci.Control.Site != null) + selectItem = lci.Control; + } + } + // No need to re-select + if (selectItem == itemGlyph._Item && itemGlyph.Item.IsSelected) + return base.OnMouseDown(g, button, mouseLoc); + } + ISelectionService selectionService = (ISelectionService)selectItem.Site.GetService(typeof(ISelectionService)); + if (selectionService != null && selectItem != null) + { + selectionService.SetSelectedComponents(new IComponent[] { selectItem }); + return true; + } + } + return base.OnMouseDown(g, button, mouseLoc); + } + public override bool OnMouseUp(Glyph g, MouseButtons button) + { + _MouseDownLocation = Point.Empty; + return base.OnMouseUp(g, button); + } + public override bool OnMouseMove(Glyph g, MouseButtons button, Point mouseLoc) + { + if (button == MouseButtons.Left && _MouseDownLocation.IsEmpty) + _MouseDownLocation = mouseLoc; + if (button == MouseButtons.Left && !_MouseDownLocation.IsEmpty && + (Math.Abs(mouseLoc.X - _MouseDownLocation.X) > 1 || Math.Abs(mouseLoc.Y - _MouseDownLocation.Y) > 1)) + { + LayoutItemGlyph glyph = g as LayoutItemGlyph; + if (glyph != null && glyph.Item != null) + { + ISelectionService selectionService = GetSelectionService(glyph.Item); + if (selectionService != null && selectionService.PrimarySelection == glyph.Item && selectionService.GetSelectedComponents().Count == 1) + { + _MouseDownLocation = Point.Empty; + this.DropSource.QueryContinueDrag += new QueryContinueDragEventHandler(this.QueryContinueDrag); + this.DropSource.DoDragDrop(new LayoutItemDataObject(glyph.Item), DragDropEffects.Move | DragDropEffects.Copy | DragDropEffects.Scroll); + } + } + } + + return false;// base.OnMouseMove(g, button, mouseLoc); + } + + public override void OnDragDrop(Glyph g, DragEventArgs e) + { + if (e.Data is LayoutItemDataObject) + { + LayoutItemDataObject d = (LayoutItemDataObject)e.Data; + LayoutControl lc = d.DragComponent.GetLayoutControl(); + if (lc != null) + { + lc.HideInsertMarker(); + LayoutItemBase item = d.DragComponent; + ISelectionService selectionService = GetSelectionService(item); + IDesignerHost host = GetDesignerHostService(item); + IComponentChangeService cc = GetComponentChangeService(item); + if (selectionService != null && host != null && cc != null) + { + HitTestInsertInfo info = lc.GetHitTestInsertInfo(item, lc.PointToClient(new Point(e.X, e.Y))); + if (info.Parent != null) + { + DesignerTransaction dt = host.CreateTransaction("Moving Layout Control Item"); + cc.OnComponentChanging(lc, TypeDescriptor.GetProperties(lc)["RootGroup"]); + //lc.Text = string.Format("Moving at B: {0}", info.InsertIndex); + //lc.Invalidate(); + if (info.Parent != item.Parent) + { + LayoutGroup group = (LayoutGroup)item.Parent; + if (group != lc.RootGroup) + cc.OnComponentChanging(group, TypeDescriptor.GetProperties(lc)["Items"]); + group.Items.Remove(item); + if (group != lc.RootGroup) + cc.OnComponentChanged(group, TypeDescriptor.GetProperties(lc)["Items"], null, null); + if (info.Parent != lc.RootGroup) + cc.OnComponentChanging(info.Parent, TypeDescriptor.GetProperties(lc)["Items"]); + if (info.InsertIndex >= 0) + info.Parent.Items.Insert(info.InsertIndex, item); + else + info.Parent.Items.Add(item); + if (info.Parent != lc.RootGroup) + cc.OnComponentChanged(info.Parent, TypeDescriptor.GetProperties(lc)["Items"], null, null); + } + else + { + if (info.Parent != lc.RootGroup) + cc.OnComponentChanging(info.Parent, TypeDescriptor.GetProperties(lc)["Items"]); + info.Parent.Items.Move(item, info.InsertIndex); + if (info.Parent != lc.RootGroup) + cc.OnComponentChanged(info.Parent, TypeDescriptor.GetProperties(lc)["Items"], null, null); + } + + cc.OnComponentChanged(lc, TypeDescriptor.GetProperties(lc)["RootGroup"], null, null); + dt.Commit(); + lc.PerformLayout(); + lc.Invalidate(true); + + IDesigner designer = host.GetDesigner(lc); + if (designer is LayoutControlDesigner) + ((LayoutControlDesigner)designer).SelectionRefresh(); + } + } + } + } + base.OnDragDrop(g, e); + } + public override void OnDragLeave(Glyph g, EventArgs e) + { + LayoutItemGlyph glyph = g as LayoutItemGlyph; + if (glyph != null && glyph.Item != null) + { + LayoutControl lc = glyph.Item.GetLayoutControl(); + if (lc != null) + lc.HideInsertMarker(); + } + base.OnDragLeave(g, e); + } + + public override void OnDragOver(Glyph g, DragEventArgs e) + { + if (e.Data is LayoutItemDataObject) + { + e.Effect = DragDropEffects.Move; + LayoutItemDataObject d = (LayoutItemDataObject)e.Data; + LayoutControl lc = d.DragComponent.GetLayoutControl(); + if (lc != null) + { + HitTestInsertInfo info = lc.GetHitTestInsertInfo(d.DragComponent, lc.PointToClient(new Point(e.X, e.Y))); + if (!info.InsertMarkerBounds.IsEmpty) + lc.ShowInsertMarker(info.InsertMarkerBounds); + else + lc.HideInsertMarker(); + e.Effect = DragDropEffects.Move; + return; + } + } + e.Effect = DragDropEffects.None; + return; + base.OnDragOver(g, e); + } + + public override void OnDragEnter(Glyph g, DragEventArgs e) + { + if (e.Data is LayoutItemDataObject) + { + e.Effect = DragDropEffects.Move; + } + else + e.Effect = DragDropEffects.None; + return; + base.OnDragEnter(g, e); + } + + private void QueryContinueDrag(object sender, QueryContinueDragEventArgs e) + { + if ((e.Action != DragAction.Continue) && e.EscapePressed) + { + e.Action = DragAction.Cancel; + //ToolStripItem glyphItem = sender as ToolStripItem; + //this.SetParentDesignerValuesForDragDrop(glyphItem, false, Point.Empty); + //ISelectionService selectionService = this.GetSelectionService(glyphItem); + //if (selectionService != null) + //{ + // selectionService.SetSelectedComponents(new IComponent[] { glyphItem }, SelectionTypes.Auto); + //} + //ToolStripDesigner.dragItem = null; + } + } + private ISelectionService GetSelectionService(LayoutItemBase item) + { + if (item.Site != null) + { + return (ISelectionService)item.Site.GetService(typeof(ISelectionService)); + } + return null; + } + private IDesignerHost GetDesignerHostService(LayoutItemBase item) + { + if (item.Site != null) + { + return (IDesignerHost)item.Site.GetService(typeof(IDesignerHost)); + } + return null; + } + private IComponentChangeService GetComponentChangeService(LayoutItemBase item) + { + if (item.Site != null) + { + return (IComponentChangeService)item.Site.GetService(typeof(IComponentChangeService)); + } + return null; + } + + + private Control _DropSource = null; + private Control DropSource + { + get + { + if (_DropSource == null) + { + _DropSource = new Control(); + } + return _DropSource; + } + } + + + + + } + } + + + #region LayoutItemDataObject + internal class LayoutItemDataObject : DataObject + { + private LayoutItemBase _DragComponent; + + // Methods + internal LayoutItemDataObject(LayoutItemBase dragComponents) + { + _DragComponent = dragComponents; + } + + // Properties + internal LayoutItemBase DragComponent + { + get + { + return _DragComponent; + } + } + } + #endregion + + + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/SymbolTypeEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/SymbolTypeEditor.cs new file mode 100644 index 00000000..9a156985 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/SymbolTypeEditor.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms.Design; +using System.ComponentModel; +using System.Windows.Forms; +using System.Drawing.Design; +using System.Reflection; +using DevComponents.DotNetBar; +using System.Runtime.InteropServices; +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Layout.Design +{ + public class SymbolTypeEditor : System.Drawing.Design.UITypeEditor + { + #region Implementation + private IWindowsFormsEditorService edSvc = null; + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + if (context != null + && context.Instance != null + && provider != null) + { + edSvc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; + string stringValue = null; + if (value != null) stringValue = value.ToString(); + + if (edSvc != null) + { + ItemPanel itemPanel = new ItemPanel(); + itemPanel.Font = Symbols.FontAwesome; + itemPanel.MultiLine = true; + itemPanel.AutoScroll = true; + itemPanel.LayoutOrientation = eOrientation.Horizontal; + itemPanel.SelectedIndexChanged += new EventHandler(ItemPanelSelectedIndexChanged); +#if !TRIAL + itemPanel.LicenseKey = "F962CEC7-CD8F-4911-A9E9-CAB39962FC1F"; +#endif + SetColors(itemPanel); + + Dictionary supportedChars = GetFontSupportedChars(itemPanel.Font); + for (int i = 0xf000; i <= 0xf200; i++) + { + if (!supportedChars.ContainsKey(i)) continue; + ButtonItem button = new ButtonItem(); + button.AutoCheckOnClick = true; + button.OptionGroup = "sym"; + button.Text = char.ConvertFromUtf32(i); + button.Tooltip = string.Format("{0:x}", i); + if (button.Text == stringValue) button.Checked = true; + itemPanel.Items.Add(button); + } + edSvc.DropDownControl(itemPanel); + itemPanel.SelectedIndexChanged -= new EventHandler(ItemPanelSelectedIndexChanged); + if (itemPanel.SelectedItem != null) + return itemPanel.SelectedItem.Text; + } + } + + return value; + } + + private void SetColors(ItemPanel itemPanel) + { + Office2007ColorTable table = ((Office2007Renderer)GlobalManager.Renderer).ColorTable; + ElementStyle style = (ElementStyle)table.StyleClasses[ElementStyleClassKeys.ItemPanelKey]; + itemPanel.BackgroundStyle.BackColor = style.BackColor; + itemPanel.BackgroundStyle.BackColor2 = style.BackColor2; + } + + void ItemPanelSelectedIndexChanged(object sender, EventArgs e) + { + if (edSvc != null) + edSvc.CloseDropDown(); + } + + /// + /// Gets the editor style used by the EditValue method. + /// + /// An ITypeDescriptorContext that can be used to gain additional context information. + /// 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 + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + if (context != null && context.Instance != null) + { + return UITypeEditorEditStyle.DropDown; + } + return base.GetEditStyle(context); + } + + // This method indicates to the design environment that + // the type editor will paint additional content in the + // LightShape entry in the PropertyGrid. + public override bool GetPaintValueSupported( + ITypeDescriptorContext context) + { + return true; + } + + public override void PaintValue(PaintValueEventArgs e) + { + string symbol = (string)e.Value; + Font font = Symbols.GetFontAwesome(10); + e.Graphics.DrawString(symbol, font, Brushes.Brown, e.Bounds.X, e.Bounds.Y + 2, StringFormat.GenericDefault); + + } + #endregion + + #region GetFontSupportedChars + private static readonly IntPtr HGDI_ERROR = new IntPtr(-1); + private const int UIntSize = 4; + [DllImport("gdi32.dll")] + private static extern uint GetFontUnicodeRanges(IntPtr hdc, IntPtr lpgs); + [DllImport("gdi32.dll")] + private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); + private Dictionary GetFontSupportedChars(Font font) + { + Dictionary table = new Dictionary(); + + IntPtr glyphSetData = IntPtr.Zero; + IntPtr savedFont = HGDI_ERROR; + IntPtr hdc = IntPtr.Zero; + Graphics g = null; + + try + { + g = Graphics.FromHwnd(IntPtr.Zero); + hdc = g.GetHdc(); + IntPtr hFont = font.ToHfont(); + savedFont = SelectObject(hdc, hFont); + if (savedFont == HGDI_ERROR) + throw new Exception( + "Unexpected failure of SelectObject."); + uint size = GetFontUnicodeRanges(hdc, IntPtr.Zero); + if (size == 0) + throw new Exception( + "Unexpected failure of GetFontUnicodeRanges."); + glyphSetData = Marshal.AllocHGlobal((int)size); + if (GetFontUnicodeRanges(hdc, glyphSetData) == 0) + throw new Exception( + "Unexpected failure of GetFontUnicodeRanges."); + int offset = UIntSize; + uint flags = (uint)Marshal.ReadInt32( + glyphSetData, offset); + offset += UIntSize; + uint codePointCount = (uint)Marshal.ReadInt32( + glyphSetData, offset); + offset += UIntSize; + uint rangeCount = (uint)Marshal.ReadInt32( + glyphSetData, offset); + offset += UIntSize; + for (uint index = 0; index < rangeCount; index++) + { + ushort first = (ushort)Marshal.ReadInt16( + glyphSetData, offset); + offset += Marshal.SizeOf(typeof(ushort)); + ushort count = (ushort)Marshal.ReadInt16( + glyphSetData, offset); + offset += Marshal.SizeOf(typeof(ushort)); + for (int i = first; i < first + count; i++) + { + table.Add(i, true); + } + } + } + finally + { + if (glyphSetData != IntPtr.Zero) + Marshal.FreeHGlobal(glyphSetData); + if (savedFont != HGDI_ERROR) + SelectObject(hdc, savedFont); + if (g != null) + { + if (hdc != IntPtr.Zero) + g.ReleaseHdc(hdc); + g.Dispose(); + } + } + return table; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/SystemImages/ColorPickerButtonImage.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/SystemImages/ColorPickerButtonImage.png new file mode 100644 index 00000000..06c2e80d Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/SystemImages/ColorPickerButtonImage.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/TextMarkupEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/TextMarkupEditor.cs new file mode 100644 index 00000000..8e96c1e4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/TextMarkupEditor.cs @@ -0,0 +1,324 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Layout.Design +{ + /// + /// Summary description for TextMarkupEditor. + /// + [ToolboxItem(false)] + public class TextMarkupEditor : PanelEx + { + public System.Windows.Forms.Button buttonCancel; + public System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Timer timer1; + private DevComponents.DotNetBar.PanelEx previewPanel; + public System.Windows.Forms.TextBox inputText; + private Label label2; + private System.ComponentModel.IContainer components; + private Bar bar1; + private ButtonItem buttonBold; + private ButtonItem buttonItalic; + private ButtonItem buttonUnderline; + private ColorPickerDropDown buttonColor; + private SuperTooltipControl m_Tooltip = null; + + public TextMarkupEditor() + { + // This call is required by the Windows.Forms Form Designer. + InitializeComponent(); + + this.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.Office2007; + this.ApplyLabelStyle(); + this.Style.BorderColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.BarDockedBorder; + this.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; + this.TabStop = false; + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Component Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.inputText = new System.Windows.Forms.TextBox(); + this.previewPanel = new DevComponents.DotNetBar.PanelEx(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.buttonOK = new System.Windows.Forms.Button(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.label2 = new System.Windows.Forms.Label(); + this.bar1 = new DevComponents.DotNetBar.Bar(); + this.buttonBold = new DevComponents.DotNetBar.ButtonItem(); + this.buttonItalic = new DevComponents.DotNetBar.ButtonItem(); + this.buttonUnderline = new DevComponents.DotNetBar.ButtonItem(); + this.buttonColor = new DevComponents.DotNetBar.ColorPickerDropDown(); + ((System.ComponentModel.ISupportInitialize)(this.bar1)).BeginInit(); + this.SuspendLayout(); + // + // inputText + // + this.inputText.AcceptsReturn = true; + this.inputText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.inputText.Location = new System.Drawing.Point(8, 8); + this.inputText.Multiline = true; + this.inputText.Name = "inputText"; + this.inputText.Size = new System.Drawing.Size(332, 110); + this.inputText.TabIndex = 0; + this.inputText.TextChanged += new System.EventHandler(this.inputText_TextChanged); + // + // previewPanel + // + this.previewPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.previewPanel.AutoScroll = true; + this.previewPanel.CanvasColor = System.Drawing.SystemColors.Control; + this.previewPanel.Location = new System.Drawing.Point(8, 152); + this.previewPanel.Name = "previewPanel"; + this.previewPanel.Size = new System.Drawing.Size(332, 75); + this.previewPanel.Style.BackColor1.Color = System.Drawing.Color.White; + this.previewPanel.Style.BackgroundImagePosition = DevComponents.DotNetBar.eBackgroundImagePosition.Tile; + this.previewPanel.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; + this.previewPanel.Style.BorderColor.Color = System.Drawing.Color.DarkGray; + this.previewPanel.Style.ForeColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.ItemText; + this.previewPanel.Style.GradientAngle = 90; + this.previewPanel.Style.LineAlignment = System.Drawing.StringAlignment.Near; + this.previewPanel.TabIndex = 1; + // + // buttonCancel + // + this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonCancel.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.buttonCancel.Location = new System.Drawing.Point(269, 233); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(71, 24); + this.buttonCancel.TabIndex = 4; + this.buttonCancel.Text = "Cancel"; + this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); + // + // buttonOK + // + this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.buttonOK.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.buttonOK.Location = new System.Drawing.Point(194, 233); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(71, 24); + this.buttonOK.TabIndex = 3; + this.buttonOK.Text = "OK"; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // timer1 + // + this.timer1.Interval = 1000; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.label2.BackColor = System.Drawing.Color.WhiteSmoke; + this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label2.Location = new System.Drawing.Point(316, 133); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(24, 16); + this.label2.TabIndex = 5; + this.label2.Text = "?"; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.label2.MouseLeave += new System.EventHandler(this.label2_MouseLeave); + this.label2.MouseEnter += new System.EventHandler(this.label2_MouseEnter); + // + // bar1 + // + this.bar1.Items.AddRange(new DevComponents.DotNetBar.BaseItem[] { + this.buttonBold, + this.buttonItalic, + this.buttonUnderline, + this.buttonColor}); + this.bar1.Location = new System.Drawing.Point(8, 124); + this.bar1.Name = "bar1"; + this.bar1.Size = new System.Drawing.Size(174, 25); + this.bar1.Style = DevComponents.DotNetBar.eDotNetBarStyle.Office2007; + this.bar1.TabIndex = 6; + this.bar1.TabStop = false; + this.bar1.Text = "bar1"; + // + // buttonBold + // + this.buttonBold.Name = "buttonBold"; + this.buttonBold.Shortcuts.Add(DevComponents.DotNetBar.eShortcut.CtrlB); + this.buttonBold.Text = "Bold"; + this.buttonBold.Click += new System.EventHandler(this.buttonBold_Click); + // + // buttonItalic + // + this.buttonItalic.Name = "buttonItalic"; + this.buttonItalic.Shortcuts.Add(DevComponents.DotNetBar.eShortcut.CtrlI); + this.buttonItalic.Text = "Italic"; + this.buttonItalic.Click += new System.EventHandler(this.buttonItalic_Click); + // + // buttonUnderline + // + this.buttonUnderline.Name = "buttonUnderline"; + this.buttonUnderline.Shortcuts.Add(DevComponents.DotNetBar.eShortcut.CtrlU); + this.buttonUnderline.Text = "Underline"; + this.buttonUnderline.Click += new System.EventHandler(this.buttonUnderline_Click); + // + // buttonColor + // + this.buttonColor.Name = "buttonColor"; + this.buttonColor.Tooltip = "Sets the text color"; + this.buttonColor.Image = Helpers.LoadBitmap("SystemImages.ColorPickerButtonImage.png"); + this.buttonColor.SelectedColorImageRectangle = new System.Drawing.Rectangle(2, 2, 12, 12); + this.buttonColor.Click += new System.EventHandler(this.buttonColor_SelectedColorChanged); + // + // TextMarkupEditor + // + this.Controls.Add(this.bar1); + this.Controls.Add(this.label2); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.previewPanel); + this.Controls.Add(this.inputText); + this.Name = "TextMarkupEditor"; + this.Size = new System.Drawing.Size(348, 263); + ((System.ComponentModel.ISupportInitialize)(this.bar1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + void buttonCancel_Click(object sender, EventArgs e) + { + DestroyTooltip(); + this.DialogResult = DialogResult.Cancel; + } + + void buttonOK_Click(object sender, EventArgs e) + { + DestroyTooltip(); + this.DialogResult = DialogResult.OK; + } + #endregion + + private void inputText_TextChanged(object sender, System.EventArgs e) + { + timer1.Stop(); + timer1.Start(); + } + + private void timer1_Tick(object sender, System.EventArgs e) + { + timer1.Stop(); + UpdatePreview(); + } + + private void UpdatePreview() + { + previewPanel.Text = inputText.Text; + } + + protected override void OnGotFocus(EventArgs e) + { + base.OnGotFocus(e); + inputText.Focus(); + } + + private void label2_MouseEnter(object sender, EventArgs e) + { + DestroyTooltip(); + + m_Tooltip = new SuperTooltipControl(); + m_Tooltip.AntiAlias = false; + SuperTooltipInfo info = new SuperTooltipInfo(); + info.HeaderText = "Markup tags available"; + info.BodyText = "b - Bold
" + + "i - Italic
" + + "u - Underline
" + + "p - Paragraph container, width attribute indicates width of block element
" + + "div - Block-level container, width attribute indicates width of block element
" + + "span - Inline container, width attribute indicates width of block element. Can be used to create tables
" + + "br - Line break
" + + "font - Changes font, color, size. size attribute indicates absolute or relative font size. color attribute to change the color" + + "You can use relative sizing for example +1 to increase font size by one point or -1 to decrease by one point. face attribute can be employed to set the specific font name to use.
" + + "h1 - Header markup. You can use h1, h2, h3, h4, h5, h6 to represent header sizes
" + + "a - Denotes hypertext link. href and name attributes are supported
" + + "expand - Displays the expand part of the button" + + "
All tags must be lower case and they must be well formed i.e. each tag must be closed with end tag or be an empty tag."; + info.Color = eTooltipColor.Default; + Point p = label2.PointToScreen(new Point(0, label2.Height + 1)); + m_Tooltip.ShowTooltip(info, p.X, p.Y, true); + } + + private void DestroyTooltip() + { + if (m_Tooltip == null) + return; + m_Tooltip.Hide(); + m_Tooltip.Dispose(); + m_Tooltip = null; + } + + private void label2_MouseLeave(object sender, EventArgs e) + { + DestroyTooltip(); + } + + private void buttonBold_Click(object sender, EventArgs e) + { + ApplyTag("", ""); + } + + private void buttonItalic_Click(object sender, EventArgs e) + { + ApplyTag("", ""); + } + + private void buttonUnderline_Click(object sender, EventArgs e) + { + ApplyTag("", ""); + } + + private void buttonColor_SelectedColorChanged(object sender, EventArgs e) + { + ApplyTag("", ""); + } + + private void ApplyTag(string startTag, string endTag) + { + if (inputText.SelectionLength == 0) + inputText.SelectedText = startTag + endTag; + else + inputText.SelectedText = startTag + inputText.SelectedText + endTag; + + UpdatePreview(); + } + + private string GetHexColor(Color color) + { + return "#" + color.R.ToString("X02") + color.G.ToString("X02") + color.B.ToString("X02"); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/TextMarkupEditor.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/TextMarkupEditor.resx new file mode 100644 index 00000000..fce63f71 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/TextMarkupEditor.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/TextMarkupUIEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/TextMarkupUIEditor.cs new file mode 100644 index 00000000..62c0648d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/TextMarkupUIEditor.cs @@ -0,0 +1,72 @@ +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.DotNetBar.Layout.Design +{ + public class TextMarkupUIEditor : System.Drawing.Design.UITypeEditor + { + #region Private Variables + private IWindowsFormsEditorService m_EditorService = null; + #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) + { + TextMarkupEditor editor = new TextMarkupEditor(); + editor.buttonOK.Click += new EventHandler(MarkupEditorButtonClick); + editor.buttonCancel.Click += new EventHandler(MarkupEditorButtonClick); + + if(value!=null) + editor.inputText.Text = value.ToString(); + + m_EditorService.DropDownControl(editor); + + if (editor.DialogResult == DialogResult.OK) + { + string text = editor.inputText.Text; + editor.Dispose(); + return text; + } + editor.Dispose(); + } + } + + return value; + } + + void MarkupEditorButtonClick(object sender, EventArgs e) + { + if (m_EditorService != null) + m_EditorService.CloseDropDown(); + } + + /// + /// Gets the editor style used by the EditValue method. + /// + /// An ITypeDescriptorContext that can be used to gain additional context information. + /// 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 + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + if (context != null && context.Instance != null) + { + return UITypeEditorEditStyle.DropDown; + } + return base.GetEditStyle(context); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/WinApi.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/WinApi.cs new file mode 100644 index 00000000..b5bc224c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout.Design/WinApi.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout.Design +{ + internal static class WinApi + { + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); + [DllImport("gdi32")] + public static extern bool DeleteObject(IntPtr hObject); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern bool GetTextMetrics(HandleRef hdc, TEXTMETRIC tm); + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class TEXTMETRIC + { + public int tmHeight; + public int tmAscent; + public int tmDescent; + public int tmInternalLeading; + public int tmExternalLeading; + public int tmAveCharWidth; + public int tmMaxCharWidth; + public int tmWeight; + public int tmOverhang; + public int tmDigitizedAspectX; + public int tmDigitizedAspectY; + public char tmFirstChar; + public char tmLastChar; + public char tmDefaultChar; + public char tmBreakChar; + public byte tmItalic; + public byte tmUnderlined; + public byte tmStruckOut; + public byte tmPitchAndFamily; + public byte tmCharSet; + } + + [DllImport("user32")] + public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); + [DllImport("user32")] + public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); + public const int WM_SETREDRAW = 0x000B; + + public const int WM_LBUTTONDOWN = 0x0201; + public const int WM_LBUTTONUP = 0x0202; + public const int WM_RBUTTONDOWN = 0x0204; + public const int WM_RBUTTONUP = 0x0205; + public const int WM_MOUSEMOVE = 0x0200; + public const int WM_MOUSELEAVE = 0x02A3; + public const int WM_HSCROLL = 0x0114; + public const int WM_VSCROLL = 0x0115; + public const int WM_LBUTTONDBLCLK = 0x0203; + + public static int LOWORD(int n) + { + return (short)(n & 0xffff); + } + public static int HIWORD(int n) + { + return (int)((n >> 0x10) & 0xffff); + } + public static int LOWORD(IntPtr n) + { + return LOWORD((int)((long)n)); + } + public static int HIWORD(IntPtr n) + { + return unchecked((short)((uint)n >> 16)); + } + + //[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] + //public static extern int ScrollWindowEx(HandleRef hWnd, int nXAmount, int nYAmount, ref RECT rectScrollRegion, ref RECT rectClip, IntPtr hrgnUpdate, ref RECT prcUpdate, int flags); + //[StructLayout(LayoutKind.Sequential)] + //public struct RECT + //{ + // public int left; + // public int top; + // public int right; + // public int bottom; + // public RECT(int left, int top, int right, int bottom) + // { + // this.left = left; + // this.top = top; + // this.right = right; + // this.bottom = bottom; + // } + + // public RECT(Rectangle r) + // { + // this.left = r.Left; + // this.top = r.Top; + // this.right = r.Right; + // this.bottom = r.Bottom; + // } + + // public static RECT FromXYWH(int x, int y, int width, int height) + // { + // return new RECT(x, y, x + width, y + height); + // } + + // public Size Size + // { + // get + // { + // return new Size(this.right - this.left, this.bottom - this.top); + // } + // } + //} + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Background.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Background.cs new file mode 100644 index 00000000..5fe2e147 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Background.cs @@ -0,0 +1,375 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using System.Globalization; + +namespace DevComponents.DotNetBar.Layout +{ + [TypeConverter(typeof(BackgroundConvertor))] + public class Background : INotifyPropertyChanged + { + #region Constructor + /// + /// Initializes a new instance of the Background class. + /// + public Background() + { + + } + /// + /// Initializes a new instance of the Background class with single solid backgruond color. + /// + public Background(Color backColor) + { + _Colors = new Color[] { backColor }; + } + + /// + /// Initializes a new instance of the Background class. + /// + /// + public Background(Color[] colors) + { + _Colors = colors; + } + /// + /// Initializes a new instance of the Background class. + /// + /// + /// + public Background(Color[] colors, float[] positions) + { + _Colors = colors; + _Positions = positions; + } + /// + /// Initializes a new instance of the Background class. + /// + /// + /// + /// + public Background(Color[] colors, float[] positions, eGradientType gradientType) + { + _Colors = colors; + _Positions = positions; + _GradientType = gradientType; + } + /// + /// Initializes a new instance of the Background class. + /// + /// + /// + /// + /// + public Background(Color[] colors, float[] positions, eGradientType gradientType, int linearGradientAngle) + { + _Colors = colors; + _Positions = positions; + _GradientType = gradientType; + _LinearGradientAngle = linearGradientAngle; + } + #endregion + + #region Implementation + /// + /// Gets whether class is empty. + /// + [Browsable(false)] + public bool IsEmpty + { + get + { + return (_Colors == null || _Colors.Length == 0) && + (_Positions == null || _Positions.Length == 0); + } + } + /// + /// Gets whether background is visible, i.e. colors are assigned. + /// + [Browsable(false)] + public bool IsBackgroundSet + { + get + { + return !(_Colors == null || _Colors.Length == 0); + } + } + /// + /// Creates the brush which represents the background. + /// + /// Bounds for the brush. + /// New instance of the brush or null if brush cannot be created. + public Brush CreateBrush(Rectangle r) + { + if (!IsBackgroundSet) + return null; + if (_Colors.Length == 1) + return new SolidBrush(_Colors[0]); + if (_GradientType == eGradientType.LinearGradient) + { + LinearGradientBrush brush = null; + if (_Colors.Length == 2) + { + brush = new LinearGradientBrush(r, _Colors[0], _Colors[1], _LinearGradientAngle); + if (_Positions != null && _Positions.Length != 2) return brush; + } + else + brush = new LinearGradientBrush(r, _Colors[0], _Colors[_Colors.Length - 1], _LinearGradientAngle); + ColorBlend cb = GetColorBlend(); + if (cb != null) + brush.InterpolationColors = cb; + return brush; + } + else + { + int n = (int)Math.Sqrt(r.Width * r.Width + r.Height * r.Height) + 4; + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(r.X - (n - r.Width) / 2, r.Y - (n - r.Height) / 2, n, n); + + PathGradientBrush pbr = new PathGradientBrush(path); + + pbr.CenterColor = _Colors[0]; + pbr.SurroundColors = new Color[] { _Colors[_Colors.Length - 1] }; + + ColorBlend cb = GetColorBlend(); + + if (cb != null) + pbr.InterpolationColors = cb; + + return (pbr); + } + } + } + private ColorBlend GetColorBlend() + { + if (_Colors != null && + _Colors != null && _Colors.Length > 0) + { + ColorBlend cb = new ColorBlend(_Colors.Length); + + cb.Colors = _Colors; + cb.Positions = GetPositions(); + + return (cb); + } + + return (null); + } + private float[] GetPositions() + { + float[] cp = _Positions; + + if (cp == null || cp.Length != _Colors.Length) + { + cp = new float[_Colors.Length]; + + float f = 1f / _Colors.Length; + + for (int i = 0; i < cp.Length; i++) + cp[i] = i * f; + + cp[_Colors.Length - 1] = 1; + } + + return (cp); + } + + + private Color[] _Colors = null; + /// + /// Indicates the array of colors that make up background. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that make up background."), TypeConverter(typeof(ArrayConverter))] + public Color[] Colors + { + get + { + return _Colors; + } + set + { + if (_Colors != value) + { + _Colors = value; + OnPropertyChanged(new PropertyChangedEventArgs("Colors")); + } + } + } + + private float[] _Positions = null; + /// + /// Indicates the positions for the gradient colors when multiple colors are set to Colors property. When not set + /// the gradient color positions are evenly distributed. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the positions for the gradient colors when multiple colors are set to Colors property."), TypeConverter(typeof(ArrayConverter))] + public float[] Positions + { + get + { + return _Positions; + } + set + { + _Positions = value; + OnPropertyChanged(new PropertyChangedEventArgs("Positions")); + } + } + + private eGradientType _GradientType = eGradientType.LinearGradient; + /// + /// Indicates the gradient type used when multiple Colors are specified. + /// + [DefaultValue(eGradientType.LinearGradient), Category("Appearance"), Description("Indicates the gradient type used when multiple Colors are specified.")] + public eGradientType GradientType + { + get { return _GradientType; } + set { _GradientType = value; OnPropertyChanged(new PropertyChangedEventArgs("GradientType")); } + } + + private int _LinearGradientAngle = 90; + /// + /// Indicates the linear gradient angle. + /// + [DefaultValue(90), Description("Indicates the linear gradient angle."), Category("Appearance")] + public int LinearGradientAngle + { + get { return _LinearGradientAngle; } + set { _LinearGradientAngle = value; OnPropertyChanged(new PropertyChangedEventArgs("LinearGradientAngle")); } + } + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChangedEx(string s) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + { + PropertyChangedEventArgs e = + new PropertyChangedEventArgs(s); + + eh(this, e); + } + } + + #endregion + } + + public enum eGradientType + { + LinearGradient, + RadialGradient + } + + #region BackgroundConvertor + + /// + /// BackgroundConvertor + /// + public class BackgroundConvertor : ExpandableObjectConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType)); + } + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + Background gc = value as Background; + + if (gc != null) + { + if (gc.IsEmpty) + return "(Empty)"; + + if (gc.Colors != null && gc.Colors.Length == 1) + return ColorHelpers.ToArgbString(gc.Colors[0]); + + if (gc.Colors != null && gc.Colors.Length > 1) + return ("Blended"); + + + return ""; + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + string str = value as string; + if (string.IsNullOrEmpty(str)) + { + return new BorderColors(); + } + string str2 = str.Trim(); + if (str2.Length == 0) + { + return null; + } + if (culture == null) + { + culture = CultureInfo.CurrentCulture; + } + if (str2.IndexOf(culture.TextInfo.ListSeparator[0]) == -1) + { + Color c = Color.FromName(str2); + if (c.IsEmpty) + c = ColorHelpers.GetColor(str2); + return new Background(c); + } + + throw new ArgumentException("Text Parsing Failed"); + + //char ch = culture.TextInfo.ListSeparator[0]; + //string[] strArray = str2.Split(new char[] { ch }); + //Color[] numArray = new Color[strArray.Length]; + ////TypeConverter converter = TypeDescriptor.GetConverter(typeof(Color)); + //for (int i = 0; i < numArray.Length; i++) + //{ + // numArray[i] = ColorHelpers.GetColor(strArray[i]);// (Color)converter.ConvertFromString(context, culture, strArray[i]); + //} + + //if (numArray.Length == 1) + //{ + // return new BorderColors(numArray[0]); + //} + + //if (numArray.Length != 4) + //{ + // throw new ArgumentException("Text Parsing Failed"); + //} + //return new BorderColors(numArray[0], numArray[1], numArray[2], numArray[3]); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/BorderColors.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/BorderColors.cs new file mode 100644 index 00000000..f2b445c0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/BorderColors.cs @@ -0,0 +1,339 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Globalization; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Collections; +using System.ComponentModel.Design.Serialization; +using System.Reflection; + +namespace DevComponents.DotNetBar.Layout +{ + + /// + /// Defines BorderColors structure used to define border colors. + /// + [StructLayout(LayoutKind.Sequential), TypeConverter(typeof(BorderColorsConverter))] + public struct BorderColors : IEquatable + { + #region Constructor + private Color _Left; + private Color _Top; + private Color _Right; + private Color _Bottom; + + /// + /// Creates new instance of the object. + /// + /// Uniform BorderColors + public BorderColors(Color uniformBorderColors) + { + _Left = _Top = _Right = _Bottom = uniformBorderColors; + } + /// + /// Creates new instance of the object. + /// + /// Left BorderColors + /// Top BorderColors + /// Right BorderColors + /// Bottom BorderColors + public BorderColors(Color left, Color top, Color right, Color bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + } + #endregion + + #region Implementation + /// + /// Gets whether object equals to this instance. + /// + /// object to test. + /// returns whether objects are Equals + public override bool Equals(object obj) + { + if (obj is BorderColors) + { + BorderColors BorderColors = (BorderColors)obj; + return (this == BorderColors); + } + return false; + } + /// + /// Gets whether object equals to this instance. + /// + /// object to test. + /// returns whether objects are Equals + public bool Equals(BorderColors BorderColors) + { + return (this == BorderColors); + } + /// + /// Returns hash code for object. + /// + /// Hash code + public override int GetHashCode() + { + return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^ _Right.GetHashCode()) ^ _Bottom.GetHashCode()); + } + + const string StringValueSeparator = ","; + /// + /// Returns string representation of object. + /// + /// string representing BorderColors + public override string ToString() + { + return Convert.ToString(_Left) + StringValueSeparator + Convert.ToString(_Top) + StringValueSeparator + Convert.ToString(_Right) + StringValueSeparator + Convert.ToString(_Bottom); + } + /// + /// Gets string representation of object. + /// + /// Culture info. + /// string representing BorderColors + internal string ToString(CultureInfo cultureInfo) + { + return Convert.ToString(_Left, cultureInfo) + StringValueSeparator + Convert.ToString(_Top, cultureInfo) + StringValueSeparator + Convert.ToString(_Right, cultureInfo) + StringValueSeparator + Convert.ToString(_Bottom, cultureInfo); + } + /// + /// Returns whether all values are empty. + /// + [Browsable(false)] + public bool IsEmpty + { + get + { + return (this.Left.IsEmpty && this.Top.IsEmpty && this.Right.IsEmpty && this.Bottom.IsEmpty); + } + } + /// + /// Returns whether all values are the same. + /// + [Browsable(false)] + public bool IsUniform + { + get + { + return (this.Left == this.Top && this.Top == this.Right && this.Right == this.Bottom); + } + } + + public static bool operator ==(BorderColors t1, BorderColors t2) + { + return (t1._Left == t2._Left && t1._Top == t2._Top && t1._Right == t2._Right && t1._Bottom == t2._Bottom); + } + + public static bool operator !=(BorderColors t1, BorderColors t2) + { + return !(t1 == t2); + } + /// + /// Gets or sets the left BorderColors. + /// + public Color Left + { + get + { + return _Left; + } + set + { + _Left = value; + } + } + /// + /// Gets or sets the top BorderColors. + /// + public Color Top + { + get + { + return _Top; + } + set + { + _Top = value; + } + } + /// + /// Gets or sets the Right BorderColors. + /// + public Color Right + { + get + { + return _Right; + } + set + { + _Right = value; + } + } + /// + /// Gets or sets the Bottom BorderColors. + /// + public Color Bottom + { + get + { + return _Bottom; + } + set + { + _Bottom = value; + } + } + #endregion + } + + + #region BorderColorsConverter + /// + /// Provides BorderColors TypeConverter. + /// + public class BorderColorsConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType)); + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType)); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + string str = value as string; + if (string.IsNullOrEmpty(str)) + { + return new BorderColors(); + } + string str2 = str.Trim(); + if (str2.Length == 0) + { + return null; + } + if (culture == null) + { + culture = CultureInfo.CurrentCulture; + } + if (str2.IndexOf(culture.TextInfo.ListSeparator[0]) == -1) + { + Color c = Color.FromName(str2); + if(c.IsEmpty) + c = ColorHelpers.GetColor(str2); + return new BorderColors(c); + } + + char ch = culture.TextInfo.ListSeparator[0]; + string[] strArray = str2.Split(new char[] { ch }); + Color[] numArray = new Color[strArray.Length]; + //TypeConverter converter = TypeDescriptor.GetConverter(typeof(Color)); + for (int i = 0; i < numArray.Length; i++) + { + numArray[i] = ColorHelpers.GetColor(strArray[i]);// (Color)converter.ConvertFromString(context, culture, strArray[i]); + } + + if (numArray.Length == 1) + { + return new BorderColors(numArray[0]); + } + + if (numArray.Length != 4) + { + throw new ArgumentException("Text Parsing Failed"); + } + return new BorderColors(numArray[0], numArray[1], numArray[2], numArray[3]); + } + + private string ToArgbString(Color color) + { + if (color.IsEmpty) return ""; + if (color.A == 255) + return color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2"); + return color.A.ToString("X2") + color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2"); + } + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == null) + { + throw new ArgumentNullException("destinationType"); + } + if (value is BorderColors) + { + if (destinationType == typeof(string)) + { + BorderColors colors = (BorderColors)value; + if (colors.IsEmpty) return ""; + if (colors.IsUniform) return ToArgbString(colors.Left); + if (culture == null) + { + culture = CultureInfo.CurrentCulture; + } + string separator = culture.TextInfo.ListSeparator + " "; + //TypeConverter converter = TypeDescriptor.GetConverter(typeof(Color)); + string[] strArray = new string[4]; + int num = 0; + //strArray[num++] = converter.ConvertToString(context, culture, BorderColors.Left); + //strArray[num++] = converter.ConvertToString(context, culture, BorderColors.Top); + //strArray[num++] = converter.ConvertToString(context, culture, BorderColors.Right); + //strArray[num++] = converter.ConvertToString(context, culture, BorderColors.Bottom); + strArray[num++] = ToArgbString(colors.Left); + strArray[num++] = ToArgbString(colors.Top); + strArray[num++] = ToArgbString(colors.Right); + strArray[num++] = ToArgbString(colors.Bottom); + return string.Join(separator, strArray); + } + if (destinationType == typeof(InstanceDescriptor)) + { + BorderColors BorderColors2 = (BorderColors)value; + ConstructorInfo constructor = typeof(BorderColors).GetConstructor(new Type[] { typeof(Color), typeof(Color), typeof(Color), typeof(Color) }); + if (constructor != null) + { + return new InstanceDescriptor(constructor, new object[] { BorderColors2.Left, BorderColors2.Top, BorderColors2.Right, BorderColors2.Bottom }); + } + } + } + return base.ConvertTo(context, culture, value, destinationType); + } + + public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) + { + if (propertyValues == null) + { + throw new ArgumentNullException("propertyValues"); + } + object left = propertyValues["Left"]; + object top = propertyValues["Top"]; + object right = propertyValues["Right"]; + object bottom = propertyValues["Bottom"]; + if ((((left == null) || (top == null)) || ((right == null) || (bottom == null))) || ((!(left is Color) || !(top is Color)) || (!(right is Color) || !(bottom is Color)))) + { + throw new ArgumentException(string.Format("Property Value Invalid: left={0}, top={1}, right={2}, bottom={3}", left, top, right, bottom)); + } + return new BorderColors((Color)left, (Color)top, (Color)right, (Color)bottom); + } + + public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) + { + return true; + } + + public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) + { + return TypeDescriptor.GetProperties(typeof(BorderColors), attributes).Sort(new string[] { "Left", "Top", "Right", "Bottom" }); + } + + public override bool GetPropertiesSupported(ITypeDescriptorContext context) + { + return true; + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/BorderPattern.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/BorderPattern.cs new file mode 100644 index 00000000..06166941 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/BorderPattern.cs @@ -0,0 +1,493 @@ +using System; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using System.Globalization; + +namespace DevComponents.DotNetBar.Layout +{ + /// + /// Defines Thickness class. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class BorderPattern : IEquatable, INotifyPropertyChanged + { + #region Static data + + /// + /// Returns Empty instance of BorderPattern. + /// + public static BorderPattern Empty + { + get { return (new BorderPattern()); } + } + + #endregion + + #region Private variables + + private LinePattern _Bottom = LinePattern.NotSet; + private LinePattern _Left = LinePattern.NotSet; + private LinePattern _Right = LinePattern.NotSet; + private LinePattern _Top = LinePattern.NotSet; + + #endregion + + #region Constructors + + /// + /// Creates new instance of the object. + /// + /// Left BorderPatternStyle. + /// Top BorderPatternStyle. + /// Right BorderPatternStyle. + /// Bottom BorderPatternStyle. + public BorderPattern(LinePattern left, + LinePattern top, LinePattern right, LinePattern bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + + PropertyChanged = null; + } + + /// + /// Creates new instance of the object. + /// + /// Specifies uniform Thickness. + public BorderPattern(LinePattern all) + : this(all, all, all, all) + { + } + + /// + /// Creates new instance of the object. + /// + public BorderPattern() + { + } + + #endregion + + #region Public properties + + #region All + + /// + /// Gets or sets the thickness of all sides. + /// + //[Browsable(false)] + //[EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public LinePattern All + { + set { _Top = _Left = _Bottom = _Right = value; } + } + + #endregion + + #region Bottom + + /// + /// Gets or sets the bottom Border Pattern + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the bottom Border Pattern")] + public LinePattern Bottom + { + get { return (_Bottom); } + + set + { + if (_Bottom != value) + { + _Bottom = value; + + OnPropertyChanged(new PropertyChangedEventArgs("Bottom")); + } + } + } + + #endregion + + #region Left + + /// + /// Gets or sets the left Border Pattern + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the left Border Pattern")] + public LinePattern Left + { + get { return (_Left); } + + set + { + if (_Left != value) + { + _Left = value; + + OnPropertyChanged(new PropertyChangedEventArgs("Left")); + } + } + } + + #endregion + + #region Right + + /// + /// Gets or sets the Right Border Pattern + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Right Border Pattern")] + public LinePattern Right + { + get { return (_Right); } + + set + { + if (_Right != value) + { + _Right = value; + + OnPropertyChanged(new PropertyChangedEventArgs("Right")); + } + } + } + + #endregion + + #region Top + + /// + /// Gets or sets the Top Border Pattern + /// + [Browsable(true), DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Top Border Pattern")] + public LinePattern Top + { + get { return (_Top); } + + set + { + if (_Top != value) + { + _Top = value; + + OnPropertyChanged(new PropertyChangedEventArgs("Top")); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the item is empty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + return (_Left == LinePattern.NotSet && + _Right == LinePattern.NotSet && + _Top == LinePattern.NotSet && + _Bottom == LinePattern.NotSet); + } + } + + /// + /// Gets whether left border is visible. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsLeftVisible + { + get + { + return (_Left != LinePattern.NotSet && _Left != LinePattern.None); + } + } + /// + /// Gets whether right border is visible. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRightVisible + { + get + { + return (_Right != LinePattern.NotSet && _Right != LinePattern.None); + } + } + /// + /// Gets whether top border is visible. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTopVisible + { + get + { + return (_Top != LinePattern.NotSet && _Top != LinePattern.None); + } + } + /// + /// Gets whether bottom border is visible. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsBottomVisible + { + get + { + return (_Bottom != LinePattern.NotSet && _Bottom != LinePattern.None); + } + } + #endregion + + #endregion + + #region Internal properties + + #region IsUniform + + internal bool IsUniform + { + get + { + return (_Left == _Top && + _Left == _Right && _Left == _Bottom); + } + } + + #endregion + + #endregion + + #region Equals + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to. + /// true if equal otherwise false. + public override bool Equals(object obj) + { + if (obj is BorderPattern) + return (this == (BorderPattern)obj); + + return (false); + } + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to + /// true if equal otherwise false + public bool Equals(BorderPattern borderPattern) + { + return (this == borderPattern); + } + + #endregion + + #region GetHashCode + + /// + /// Returns hash-code. + /// + /// hash-code + public override int GetHashCode() + { + return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^ + _Right.GetHashCode()) ^ _Bottom.GetHashCode()); + } + + #endregion + + #region Operators + + #region "==" operator + + /// + /// Implements == operator. + /// + /// Object 1 + /// Object 2 + /// true if equals + public static bool operator ==(BorderPattern t1, BorderPattern t2) + { + if (ReferenceEquals(t1, t2)) + return (true); + + if (((object)t1 == null) || ((object)t2 == null)) + return (false); + + return (t1._Left == t2._Left && t1._Right == t2._Right && + t1._Top == t2._Top && t1._Bottom == t2._Bottom); + } + + #endregion + + #region "!=" operator + + /// + /// Implements != operator + /// + /// Object 1 + /// Object 2 + /// true if different + public static bool operator !=(BorderPattern t1, BorderPattern t2) + { + return ((t1 == t2) == false); + } + + #endregion + + #endregion + + #region ApplyPattern + + /// + /// Applies the pattern to instance of this pattern. + /// + /// Pattern to apply. + public void ApplyPattern(BorderPattern pattern) + { + if (pattern != null) + { + if (pattern.Top != LinePattern.NotSet) + _Top = pattern.Top; + + if (pattern.Left != LinePattern.NotSet) + _Left = pattern.Left; + + if (pattern.Bottom != LinePattern.NotSet) + _Bottom = pattern.Bottom; + + if (pattern.Right != LinePattern.NotSet) + _Right = pattern.Right; + } + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the BorderPattern. + /// + /// Copy of the BorderPattern. + public BorderPattern Copy() + { + BorderPattern copy = new BorderPattern(_Left, _Top, _Right, _Bottom); + + return (copy); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + #endregion + } + + #region enums + + #region LinePattern + + /// + /// LinePattern + /// + public enum LinePattern + { + /// + /// None + /// + None = -2, + + /// + /// NotSet + /// + NotSet = -1, + + /// + /// Solid + /// + Solid = DashStyle.Solid, + + /// + /// Dash + /// + Dash = DashStyle.Dash, + + /// + /// Dot + /// + Dot = DashStyle.Dot, + + /// + /// DashDot + /// + DashDot = DashStyle.DashDot, + + /// + /// DashDotDot + /// + DashDotDot = DashStyle.DashDotDot, + } + + #endregion + + #endregion + + #region BlankExpandableObjectConverter + + /// + /// BlankExpandableObjectConverter + /// + public class BlankExpandableObjectConverter : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + return (" "); + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ColorHelpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ColorHelpers.cs new file mode 100644 index 00000000..030e635c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ColorHelpers.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout +{ + internal static class ColorHelpers + { + /// + /// Converts hex string to Color type. + /// + /// Hexadecimal color representation. + /// Reference to Color object. + public static Color GetColor(string rgbHex) + { + if (string.IsNullOrEmpty(rgbHex)) + return Color.Empty; + if (rgbHex.Length == 8) + return Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0, 2), 16), + Convert.ToInt32(rgbHex.Substring(2, 2), 16), + Convert.ToInt32(rgbHex.Substring(4, 2), 16), + Convert.ToInt32(rgbHex.Substring(6, 2), 16)); + + return Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0, 2), 16), + Convert.ToInt32(rgbHex.Substring(2, 2), 16), + Convert.ToInt32(rgbHex.Substring(4, 2), 16)); + } + + /// + /// Converts hex string to Color type. + /// + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int rgb) + { + if (rgb == -1) return Color.Empty; + return Color.FromArgb((rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF); + } + + /// + /// Converts hex string to Color type. + /// + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int alpha, int rgb) + { + if (rgb == -1) return Color.Empty; + return Color.FromArgb(alpha, (rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF); + } + + public static string ToArgbString(Color color) + { + if (color.IsEmpty) return ""; + if (color.A == 255) + return color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2"); + return color.A.ToString("X2") + color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2"); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/BlockLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/BlockLayoutManager.cs new file mode 100644 index 00000000..c828e842 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/BlockLayoutManager.cs @@ -0,0 +1,46 @@ +using System.Collections; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + /// + /// Represents block layout manager responsible for sizing the content blocks. + /// + public abstract class BlockLayoutManager + { + private Graphics m_Graphics; + + /// + /// Resizes the content block and sets it's Bounds property to reflect new size. + /// + /// Content block to resize. + /// Content size available for the block in the given line. + public abstract void Layout(IBlock block, Size availableSize); + + /// + /// Performs layout finalization + /// + /// + /// + /// + /// + public abstract Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines); + + /// + /// Gets or sets the graphics object used by layout manager. + /// + public System.Drawing.Graphics Graphics + { + get {return m_Graphics;} + set {m_Graphics=value;} + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/Enums.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/Enums.cs new file mode 100644 index 00000000..e61ff8a7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/Enums.cs @@ -0,0 +1,66 @@ +using System; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Specifies orientation of content. + /// + public enum eContentOrientation + { + /// + /// Indicates Horizontal orientation of the content. + /// + Horizontal, + /// + /// Indicates Vertical orientation of the content. + /// + Vertical + } + + /// + /// Specifies content horizontal alignment. + /// + public enum eContentAlignment + { + /// + /// Content is left aligned.UI + /// + Left, + /// + /// Content is right aligned. + /// + Right, + /// + /// Content is centered. + /// + Center + } + + /// + /// Specifies content vertical alignment. + /// + public enum eContentVerticalAlignment + { + /// + /// Content is top aligned. + /// + Top, + /// + /// Content is bottom aligned. + /// + Bottom, + /// + /// Content is in the middle. + /// + Middle + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/IBlock.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/IBlock.cs new file mode 100644 index 00000000..b2487100 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/IBlock.cs @@ -0,0 +1,35 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar; +using System.Windows.Forms; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Represents a content block interface. + /// + public interface IBlock + { + /// + /// Gets or sets the bounds of the content block. + /// + Rectangle Bounds {get;set;} + /// + /// Gets or sets whether content block is visible. + /// + bool Visible {get;set;} + /// + /// Gets or sets the block margins. + /// + Padding Margin { get;set;} + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/IBlockExtended.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/IBlockExtended.cs new file mode 100644 index 00000000..a263b22b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/IBlockExtended.cs @@ -0,0 +1,28 @@ +using System; +using System.Text; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Represents a extended content block interface for advanced layout information. + /// + public interface IBlockExtended : IBlock + { + bool IsBlockElement { get;} + bool IsNewLineAfterElement { get;} + bool CanStartNewLine { get; } + /// + /// Returns whether element is an container so it receives full available size of parent control for layout. + /// + bool IsBlockContainer { get; } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/IContentLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/IContentLayoutManager.cs new file mode 100644 index 00000000..d9426e1b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/IContentLayoutManager.cs @@ -0,0 +1,29 @@ +using System; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Represents interface for block layout. + /// + public interface IContentLayout + { + /// + /// Performs layout of the content block. + /// + /// Container bounds to layout content blocks in. + /// Content blocks to layout. + /// Block layout manager that resizes the content blocks. + /// The bounds of the content blocks within the container bounds. + Rectangle Layout(Rectangle containerBounds, IBlock[] contentBlocks, BlockLayoutManager blockLayout); + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/SerialContentLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/SerialContentLayoutManager.cs new file mode 100644 index 00000000..a3c251c0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ContentManager/SerialContentLayoutManager.cs @@ -0,0 +1,659 @@ +using System; +using System.Collections; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.UI.ContentManager +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + /// + /// Represents the serial content layout manager that arranges content blocks in series next to each other. + /// + public class SerialContentLayoutManager:IContentLayout + { + #region Events + /// + /// Occurs when X, Y position of next block is calcualted. + /// + public event LayoutManagerPositionEventHandler NextPosition; + + /// + /// Occurs before new block is layed out. + /// + 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 bool m_HorizontalFitContainerHeight = 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; + private bool m_OversizeDistribute = false; + #endregion + + /// + /// Creates new instance of the class. + /// + public SerialContentLayoutManager() + { + } + + #region IContentLayout Members + /// + /// Performs layout of the content block. + /// + /// Container bounds to layout content blocks in. + /// Content blocks to layout. + /// Block layout manager that resizes the content blocks. + /// The bounds of the content blocks within the container bounds. + 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; + bool canStartOnNewLine = true; + 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; + bool isContainer = false; + if (block is IBlockExtended) + { + IBlockExtended ex = block as IBlockExtended; + isBlockElement = ex.IsBlockElement; + isNewLineTriggger = ex.IsNewLineAfterElement; + canStartOnNewLine = ex.CanStartNewLine; + isContainer = ex.IsBlockContainer; + } + else + canStartOnNewLine = true; + + if (!isBlockElement && !isContainer) + { + 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 && canStartOnNewLine || 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 && canStartOnNewLine || 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); + if (block.Visible) currentLine.VisibleItemsCount++; + Rectangle r = new Rectangle(position, block.Bounds.Size); + r.X += block.Margin.Left; + r.Y += block.Margin.Top; + block.Bounds = r; + + if (blocksBounds.IsEmpty) + { + r = block.Bounds; // Make sure that blocks bounds take in account any margin + r.X -= block.Margin.Left; + r.Y -= block.Margin.Top; + r.Width += block.Margin.Horizontal; + r.Height += block.Margin.Vertical; + blocksBounds = r; + } + 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); + + blocksBounds = blockLayout.FinalizeLayout(containerBounds, blocksBounds, lines); + + return blocksBounds; + } + + #endregion + + #region Internals + private struct SizeExtended + { + public int Width; + public int Height; + public float WidthReduction; + public float HeightReduction; + public bool UseAbsoluteWidth; + } + + 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 && m_BlockLineAlignment==eContentVerticalAlignment.Top) + return blocksBounds; + + Point[] offset=new Point[lines.Count]; + SizeExtended[] sizeOffset = new SizeExtended[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) + { + if (m_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width * .75) + { + sizeOffset[lineInfo.Line].Width = (int)Math.Floor((float)(containerBounds.Width - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.VisibleItemsCount); + sizeOffset[lineInfo.Line].UseAbsoluteWidth = true; + } + else + sizeOffset[lineInfo.Line].Width = ((containerBounds.Width - lineInfo.VisibleItemsCount * m_BlockSpacing) - lineInfo.LineSize.Width) / lineInfo.VisibleItemsCount; + sizeOffset[lineInfo.Line].WidthReduction = (float)(containerBounds.Width - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.LineSize.Width; + blocksBounds.Width=containerBounds.Width; + } + + if (m_HorizontalFitContainerHeight && containerBounds.Height > blocksBounds.Height) + sizeOffset[lineInfo.Line].Height = (containerBounds.Height - lineInfo.LineSize.Height) / lines.Count; + } + else + { + if(m_FitContainer && containerBounds.Height>lineInfo.LineSize.Height || + m_FitContainerOversize && lineInfo.LineSize.Height>containerBounds.Height) + { + if (m_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width * .75) + { + sizeOffset[lineInfo.Line].Height = (int)Math.Floor((float)(containerBounds.Height - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.VisibleItemsCount); + sizeOffset[lineInfo.Line].UseAbsoluteWidth = true; + } + else + sizeOffset[lineInfo.Line].Height = ((containerBounds.Height - lineInfo.VisibleItemsCount * m_BlockSpacing) - lineInfo.LineSize.Height) / lineInfo.VisibleItemsCount; + sizeOffset[lineInfo.Line].HeightReduction = (float)(containerBounds.Height - lineInfo.VisibleItemsCount * m_BlockSpacing) / (float)lineInfo.LineSize.Height; + 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: + if (containerBounds.Width > lineInfo.LineSize.Width) + offset[lineInfo.Line].X = containerBounds.Width - lineInfo.LineSize.Width; + break; + case eContentAlignment.Center: + if (containerBounds.Width > lineInfo.LineSize.Width) + 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: + if (containerBounds.Height > lineInfo.LineSize.Height) + offset[lineInfo.Line].Y = containerBounds.Height - lineInfo.LineSize.Height; + break; + case eContentVerticalAlignment.Middle: + if (containerBounds.Height > lineInfo.LineSize.Height) + offset[lineInfo.Line].Y = (containerBounds.Height - lineInfo.LineSize.Height) / 2; + break; + } + } + } + } + + if (m_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width && m_ContentOrientation==eContentOrientation.Vertical) + blocksBounds.Width = containerBounds.Width; + else if(m_HorizontalFitContainerHeight && containerBounds.Height>blocksBounds.Height && m_ContentOrientation==eContentOrientation.Horizontal) + blocksBounds.Height = containerBounds.Height; + + 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) + { + if (m_OversizeDistribute) + { + int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth ? sizeOffset[lineInfo.Line].Width : (int)Math.Floor(r.Width * sizeOffset[lineInfo.Line].WidthReduction); + offset[lineInfo.Line].X += nw - r.Width; + r.Width = nw; + } + else + { + 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 (!m_OversizeDistribute && 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 - block.Margin.Horizontal; + 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) + { + if (m_OversizeDistribute) + { + int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth ? sizeOffset[lineInfo.Line].Height : (int)Math.Floor(r.Height * sizeOffset[lineInfo.Line].HeightReduction); + offset[lineInfo.Line].Y += nw - r.Height; + r.Height = nw; + } + else + { + r.Height += sizeOffset[lineInfo.Line].Height; + offset[lineInfo.Line].Y += sizeOffset[lineInfo.Line].Height; + } + } + block.Bounds=r; + if (newBounds.IsEmpty) + { + r.Y -= block.Margin.Top; // Account for any margin set on first element + r.X -= block.Margin.Left; + r.Width += block.Margin.Horizontal; + r.Height += block.Margin.Vertical; + newBounds = r; + } + else + newBounds = Rectangle.Union(newBounds, block.Bounds); + } + if (!m_OversizeDistribute && 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 + block.Margin.Horizontal; + else + position.Y += block.Bounds.Height + m_BlockSpacing + block.Margin.Vertical; + return position; + } + + internal class BlockLineInfo + { + public BlockLineInfo() {} + public ArrayList Blocks=new ArrayList(); + public Size LineSize=Size.Empty; + public int Line=0; + public int VisibleItemsCount = 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 + /// + /// Gets or sets the spacing in pixels between content blocks. Default value is 0. + /// + public virtual int BlockSpacing + { + get {return m_BlockSpacing;} + set {m_BlockSpacing=value;} + } + + /// + /// 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. + /// + public virtual bool FitContainerOversize + { + get {return m_FitContainerOversize;} + set {m_FitContainerOversize=value;} + } + + /// + /// 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. + /// + public virtual bool FitContainer + { + get {return m_FitContainer;} + set {m_FitContainer=value;} + } + + /// + /// 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. + /// + public virtual bool VerticalFitContainerWidth + { + get { return m_VerticalFitContainerWidth; } + set { m_VerticalFitContainerWidth = value; } + } + + /// + /// Gets or sets whether content blocks are resized (Height) to fit container bounds if they + /// occupy less space than the actual container height. Applies to the Horizontal orientation only. Default value is false. + /// + public virtual bool HorizontalFitContainerHeight + { + get { return m_HorizontalFitContainerHeight; } + set { m_HorizontalFitContainerHeight = value; } + } + + /// + /// Gets or sets the content orientation. Default value is Horizontal. + /// + public virtual eContentOrientation ContentOrientation + { + get {return m_ContentOrientation;} + set {m_ContentOrientation=value;} + } + + /// + /// Gets or sets the content vertical alignment. Default value is Middle. + /// + public virtual eContentVerticalAlignment ContentVerticalAlignment + { + get {return m_ContentVerticalAlignment;} + set {m_ContentVerticalAlignment=value;} + } + + /// + /// Gets or sets the block line vertical alignment. Default value is Middle. + /// + public virtual eContentVerticalAlignment BlockLineAlignment + { + get { return m_BlockLineAlignment; } + set { m_BlockLineAlignment = value; } + } + + /// + /// Gets or sets the content horizontal alignment. Default value is Left. + /// + public virtual eContentAlignment ContentAlignment + { + get {return m_ContentAlignment;} + set {m_ContentAlignment=value;} + } + + /// + /// Gets or sets whether all content blocks are resized so they have same height which is height of the tallest content block. Default value is false. + /// + public virtual bool EvenHeight + { + get {return m_EvenHeight;} + set {m_EvenHeight=value;} + } + + /// + /// Gets or sets whether oversized blocks are resized based on the percentage reduction instead of based on equal pixel distribution. Default value is false. + /// + public virtual bool OversizeDistribute + { + get { return m_OversizeDistribute; } + set { m_OversizeDistribute = value; } + } + + /// + /// Gets or sets whether content is wrapped into new line if it exceeds the width of the container. + /// + public bool MultiLine + { + get {return m_MultiLine;} + set {m_MultiLine=value;} + } + + /// + /// Gets or sets whether layout is right-to-left. + /// + public bool RightToLeft + { + get { return m_RightToLeft; } + set { m_RightToLeft = value; } + } + + #endregion + } + + /// + /// Represents event arguments for SerialContentLayoutManager.NextPosition event. + /// + public class LayoutManagerPositionEventArgs : EventArgs + { + /// + /// Gets or sets the block that is layed out. + /// + public IBlock Block = null; + /// + /// Gets or sets the current block position. + /// + public Point CurrentPosition = Point.Empty; + /// + /// Gets or sets the calculated next block position. + /// + public Point NextPosition = Point.Empty; + /// + /// Cancels default position calculation. + /// + public bool Cancel = false; + } + + /// + /// Represents event arguments for the SerialContentLayoutManager layout events. + /// + public class LayoutManagerLayoutEventArgs : EventArgs + { + /// + /// Gets or sets the reference block object. + /// + public IBlock Block = null; + + /// + /// Gets or sets the position block will assume. + /// + public Point CurrentPosition = Point.Empty; + + /// + /// Cancel the layout of the block, applies only to BeforeXXX layout event. + /// + public bool CancelLayout = false; + + /// + /// Gets or sets the visibility index of the block. + /// + public int BlockVisibleIndex = 0; + + /// + /// Creates new instance of the class and initializes it with default values. + /// + public LayoutManagerLayoutEventArgs(IBlock block, Point currentPosition, int visibleIndex) + { + this.Block = block; + this.CurrentPosition = currentPosition; + this.BlockVisibleIndex = visibleIndex; + } + } + + /// + /// Delegate for SerialContentLayoutManager.NextPosition event. + /// + public delegate void LayoutManagerPositionEventHandler(object sender, LayoutManagerPositionEventArgs e); + + /// + /// Delegate for the SerialContentLayoutManager layout events. + /// + public delegate void LayoutManagerLayoutEventHandler(object sender, LayoutManagerLayoutEventArgs e); + + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DevComponents.DotNetBar.Layout.csproj b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DevComponents.DotNetBar.Layout.csproj new file mode 100644 index 00000000..7a80b6cb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DevComponents.DotNetBar.Layout.csproj @@ -0,0 +1,207 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {1641B2CE-259C-4A52-A460-48C936B13951} + Library + Properties + DevComponents.DotNetBar.Layout + DevComponents.DotNetBar.Layout + + + true + dotnetbar.snk + v2.0 + + + 2.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;LAYOUT + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE;LAYOUT + prompt + 4 + bin\Release\DevComponents.DotNetBar.Layout.XML + AllRules.ruleset + + + bin\ReleaseLayout\ + TRACE + true + pdbonly + AnyCPU + prompt + AllRules.ruleset + + + bin\ReleaseTrialLayout\ + TRACE;LAYOUT;TRIAL + true + pdbonly + AnyCPU + prompt + AllRules.ruleset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + + + Component + + + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + True + Settings.settings + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {36546CE3-335C-4AB6-A2F3-40F8C818BC66} + DotNetBar + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DotNetBarResourcesAttribute.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DotNetBarResourcesAttribute.cs new file mode 100644 index 00000000..64cba962 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DotNetBarResourcesAttribute.cs @@ -0,0 +1,22 @@ +using System; + +namespace DevComponents.DotNetBar.Layout +{ + /// + /// Summary description for DotNetBarResourcesAttribute. + /// + [AttributeUsage(AttributeTargets.Assembly)] + public class DotNetBarLayoutResourcesAttribute:System.Attribute + { + private string m_NamespacePrefix=""; + public DotNetBarLayoutResourcesAttribute(string namespacePrefix) + { + m_NamespacePrefix=namespacePrefix; + } + + public virtual string NamespacePrefix + { + get {return m_NamespacePrefix;} + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DoubleHelpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DoubleHelpers.cs new file mode 100644 index 00000000..840e73f5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DoubleHelpers.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar.Layout +{ + internal static class DoubleHelpers + { + /// + /// Gets whether values are close. + /// + /// First value. + /// Second value + /// true if values are close enough + public static bool AreClose(double value1, double value2) + { + if (value1 == value2) + { + return true; + } + double num2 = ((Math.Abs(value1) + Math.Abs(value2)) + 10.0) * 2.2204460492503131E-16; + double num = value1 - value2; + return ((-num2 < num) && (num2 > num)); + } + /// + /// Gets whether value is zero + /// + /// value to check + /// true if value is considered zero + public static bool IsZero(double value) + { + return (Math.Abs(value) < 2.2204460492503131E-15); + } + + /// + /// Gets whether value is not an number. + /// + /// value to test + /// true if value is not an number + public static bool IsNaN(double value) + { + NanUnion union = new NanUnion(); + union.DoubleValue = value; + ulong num = union.UintValue & 18442240474082181120L; + ulong num2 = union.UintValue & ((ulong)0xfffffffffffffL); + if ((num != 0x7ff0000000000000L) && (num != 18442240474082181120L)) + { + return false; + } + return (num2 != 0L); + } + + [StructLayout(LayoutKind.Explicit)] + private struct NanUnion + { + // Fields + [FieldOffset(0)] + internal double DoubleValue; + [FieldOffset(0)] + internal ulong UintValue; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DrawingHelpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DrawingHelpers.cs new file mode 100644 index 00000000..98fd19f3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/DrawingHelpers.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout +{ + internal static class DrawingHelpers + { + /// + /// Draws the border. + /// + /// Graphics canvas. + /// Bounds for border. + /// Border thickness. + /// Border pattern. + /// Border color. + public static void DrawBorder(Graphics g, RectangleF bounds, Thickness borderThickness, BorderPattern borderPattern, BorderColors borderColor) + { + if (borderColor.IsEmpty || borderThickness.IsZero || borderPattern.IsEmpty) return; + + Region oldClip = g.Clip; + g.SetClip(bounds, System.Drawing.Drawing2D.CombineMode.Intersect); + + bounds.Width -= Math.Max(1, (float)borderThickness.Horizontal / 2); + bounds.Height -= Math.Max(1, (float)borderThickness.Vertical / 2); + + if (borderThickness.Left > 1) + bounds.X += (float)borderThickness.Left / 2; + if (borderThickness.Top > 1) + bounds.Y += (float)borderThickness.Top / 2; + + if (borderThickness.Left > 0d && !borderColor.Left.IsEmpty && borderPattern.IsLeftVisible) + { + using (Pen pen = new Pen(borderColor.Left, (float)borderThickness.Left)) + { + pen.DashStyle = (System.Drawing.Drawing2D.DashStyle)borderPattern.Left; + pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset; + g.DrawLine(pen, bounds.X, bounds.Y - (float)(borderThickness.Top / 2), bounds.X, bounds.Bottom + (float)(borderThickness.Bottom / 2)); + } + } + + if (borderThickness.Right > 0d && !borderColor.Right.IsEmpty && borderPattern.IsRightVisible) + { + using (Pen pen = new Pen(borderColor.Right, (float)borderThickness.Right)) + { + pen.DashStyle = (System.Drawing.Drawing2D.DashStyle)borderPattern.Right; + pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset; + g.DrawLine(pen, bounds.Right, bounds.Y - (float)(borderThickness.Top / 2), bounds.Right, bounds.Bottom + (float)(borderThickness.Bottom / 2)); + } + } + + if (borderThickness.Top > 0d && !borderColor.Top.IsEmpty && borderPattern.IsTopVisible) + { + using (Pen pen = new Pen(borderColor.Top, (float)borderThickness.Top)) + { + pen.DashStyle = (System.Drawing.Drawing2D.DashStyle)borderPattern.Top; + pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset; + g.DrawLine(pen, bounds.X, bounds.Y, bounds.Right, bounds.Y); + } + } + + + + if (borderThickness.Bottom > 0d && !borderColor.Bottom.IsEmpty && borderPattern.IsBottomVisible) + { + using (Pen pen = new Pen(borderColor.Bottom, (float)borderThickness.Bottom)) + { + pen.DashStyle = (System.Drawing.Drawing2D.DashStyle)borderPattern.Bottom; + pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset; + g.DrawLine(pen, bounds.X, bounds.Bottom, bounds.Right, bounds.Bottom); + } + } + + g.Clip = oldClip; + if (oldClip != null) oldClip.Dispose(); + } + + public static void PaintStyle(Graphics g, SimpleStyle style, Rectangle bounds) + { + if (style.IsPainted && !bounds.IsEmpty) + { + if (style.Background.IsBackgroundSet) + { + using (Brush brush = style.Background.CreateBrush(bounds)) + g.FillRectangle(brush, bounds); + } + if (!style.BorderColors.IsEmpty && !style.BorderThickness.IsZero) + { + DrawingHelpers.DrawBorder(g, bounds, style.BorderThickness, style.BorderPattern, style.BorderColors); + } + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Helpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Helpers.cs new file mode 100644 index 00000000..7ebfc735 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Helpers.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar.Layout +{ + internal static class Helpers + { + public static Size Max(Size s1, Size s2) + { + return new Size(Math.Max(s1.Width, s2.Width), Math.Max(s1.Height, s2.Height)); + } + public static Rectangle Deflate(Rectangle r, System.Windows.Forms.Padding padding) + { + r.X += padding.Left; + r.Width -= padding.Horizontal; + r.Y += padding.Top; + r.Height -= padding.Vertical; + + return r; + } + public static Rectangle Deflate(Rectangle r, DevComponents.DotNetBar.Padding padding) + { + r.X += padding.Left; + r.Width -= padding.Horizontal; + r.Y += padding.Top; + r.Height -= padding.Vertical; + + return r; + } + + public static int GetTextBaseline(Control ctrl, ContentAlignment alignment) + { + return GetTextBaseline(ctrl, ctrl.Font, alignment); + } + + public static int GetTextBaseline(Control ctrl, Font font, ContentAlignment alignment) + { + Rectangle clientRect = ctrl.ClientRectangle; + int ascent = 0; + int height = 0; + using (Graphics g = ctrl.CreateGraphics()) + { + IntPtr hdc = g.GetHdc(); + IntPtr hFont = font.ToHfont(); + try + { + IntPtr oldObject = WinApi.SelectObject(hdc, hFont); + WinApi.TEXTMETRIC tm = new WinApi.TEXTMETRIC(); + WinApi.GetTextMetrics(new HandleRef(ctrl, hdc), tm); + ascent = tm.tmAscent + 1; + height = tm.tmHeight; + WinApi.SelectObject(hdc, oldObject); + } + finally + { + WinApi.DeleteObject(hFont); + g.ReleaseHdc(hdc); + } + } + if ((alignment & (ContentAlignment.TopRight | ContentAlignment.TopCenter | ContentAlignment.TopLeft)) != (ContentAlignment)0) + { + return (clientRect.Top + ascent); + } + if ((alignment & (ContentAlignment.MiddleRight | ContentAlignment.MiddleCenter | ContentAlignment.MiddleLeft)) != (ContentAlignment)0) + { + return (((clientRect.Top + (clientRect.Height / 2)) - (height / 2)) + ascent); + } + return ((clientRect.Bottom - height) + ascent); + } + public static bool IsEmpty(System.Windows.Forms.Padding p) + { + return p.Left == 0 && p.Right == 0 && p.Top == 0 && p.Bottom == 0; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/InsertMarker.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/InsertMarker.cs new file mode 100644 index 00000000..2ca8c820 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/InsertMarker.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Layout +{ + internal class InsertMarker : Control + { + #region Constructor + /// + /// Initializes a new instance of the InsertMarker class. + /// + public InsertMarker() + { + this.SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true); + } + #endregion + + #region Implementation + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + using (SolidBrush brush = new SolidBrush(this.ForeColor)) + { + g.FillRectangle(brush, new Rectangle(0, 0, this.Width, 2)); + g.FillRectangle(brush, new Rectangle(0, this.Height - 2, this.Width, 2)); + g.FillRectangle(brush, this.Width / 2 - 1, 0, 2, this.Height); + } + base.OnPaint(e); + } + protected override void OnHandleCreated(EventArgs e) + { + UpdateRegion(); + base.OnHandleCreated(e); + } + protected override void OnResize(EventArgs e) + { + UpdateRegion(); + base.OnResize(e); + } + private void UpdateRegion() + { + GraphicsPath path = new GraphicsPath(); + path.AddLine(0, 0, this.Width, 0); + path.AddLine(this.Width, 0, this.Width, 2); + path.AddLine(this.Width, 2, this.Width / 2 - 1, 2); + path.AddLine(this.Width / 2 + 1, 2, this.Width / 2 + 1, this.Height-2); + path.AddLine(this.Width / 2 + 1, this.Height - 2, this.Width, this.Height-2); + path.AddLine(this.Width, this.Height - 2, this.Width, this.Height); + path.AddLine(this.Width, this.Height, 0, this.Height); + path.AddLine(0, this.Height, 0, this.Height-2); + path.AddLine(0, this.Height - 2, this.Width/2-1, this.Height-2); + path.AddLine(this.Width / 2 - 1, this.Height - 2, this.Width/2-1, 2); + path.AddLine(this.Width / 2 - 1, 2, 0, 2); + path.CloseAllFigures(); + + Region reg = new Region(); + reg.MakeEmpty(); + reg.Union(path); + + path.Widen(SystemPens.Control); + //Region r2 = new Region(path); + reg.Union(path); + + this.Region = reg; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ItemLayout.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ItemLayout.cs new file mode 100644 index 00000000..e1e067bd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/ItemLayout.cs @@ -0,0 +1,371 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout +{ + internal class ItemLayout + { + public void Layout(LayoutGroup group, Rectangle clientBounds, LayoutContext context) + { + if (clientBounds.IsEmpty) return; + List strips = SliceItemsInStrips(group, clientBounds, context); + ResizeStrips(strips, clientBounds); + Rectangle totalBounds = FinalizeItemSize(strips, clientBounds, context); + group.ActualBounds = totalBounds; + //Console.WriteLine("{0} -> {1}", clientBounds, totalBounds); + } + + private LayoutContext CreateLayoutContext(LayoutContext context, int startAbsoluteIndex) + { + LayoutContext newContext = new LayoutContext(context.LayoutControl, context.Graphics, context.Font); + newContext.RightToLeft = context.RightToLeft; + newContext.AbsoluteIndex = startAbsoluteIndex; + return newContext; + } + private Rectangle FinalizeItemSize(List strips, Rectangle clientBounds, LayoutContext context) + { + int sizeLimit = GetSizeLimit(clientBounds); + int stripSizeLimit = GetStripsSizeLimit(clientBounds); + Rectangle totalBounds = new Rectangle(clientBounds.Location, Size.Empty); + Point loc = clientBounds.Location; + Rectangle fullClientBounds = clientBounds; + + int absIndex = context.AbsoluteIndex; + + foreach (LayoutItemStrip strip in strips) + { + LayoutItemBase layoutItem = strip.Items[0]; + int clientBoundsWidth = clientBounds.Width; + if (strip.IsLeftSpanStrip) + { + Size size = new Size(Math.Max(MinItemSize(layoutItem), ActualItemSize(layoutItem, fullClientBounds.Width)), + Math.Max(strip.MinStripHeightAbsolute, clientBounds.Height)); + Rectangle r = new Rectangle(loc, size); + clientBounds.X += size.Width; + clientBounds.Width -= size.Width; + loc = clientBounds.Location; + layoutItem.SetBounds(r, (layoutItem.SharedTextSizeEnabled ? context.LargestTextSize : layoutItem.RealTextSize)); + if (layoutItem is LayoutGroup) + { + LayoutContext groupContext = CreateLayoutContext(context, absIndex++); + ((LayoutGroup)layoutItem).Layout(groupContext); + absIndex = groupContext.AbsoluteIndex; + } + totalBounds = Rectangle.Union(r, totalBounds); + layoutItem.AbsoluteIndex = absIndex++; + continue; + } + else if (strip.IsRightSpanStrip) + { + Size size = new Size(Math.Max(MinItemSize(layoutItem), ActualItemSize(layoutItem, fullClientBounds.Width)), + Math.Max(strip.MinStripHeightAbsolute, clientBounds.Height)); + Rectangle r = new Rectangle(clientBounds.Right - size.Width, clientBounds.Y, size.Width, size.Height); + clientBounds.Width -= size.Width; + layoutItem.SetBounds(r, layoutItem.SharedTextSizeEnabled ? context.LargestTextSize : layoutItem.RealTextSize); + if (layoutItem is LayoutGroup) + { + LayoutContext groupContext = CreateLayoutContext(context, 10000/*absIndex++*/); // Pushing the tab index for right span strip to the right most + ((LayoutGroup)layoutItem).Layout(groupContext); + //absIndex = groupContext.AbsoluteIndex; + } + totalBounds = Rectangle.Union(r, totalBounds); + layoutItem.AbsoluteIndex = absIndex++; + //layoutItem.ActualTextSize = layoutItem.SharedTextSizeEnabled ? context.LargestTextSize : layoutItem.RealTextSize; + continue; + } + + bool repeat = false; + int repeatCount = 0; + int startAbsIndex = absIndex; + do + { + loc.X = clientBounds.X; + repeatCount++; + absIndex = startAbsIndex; + int totalPercentWidth = 0; + foreach (LayoutItemBase item in strip.Items) + { + Size size = new Size(Math.Max(MinItemSize(item), ActualItemSize(item, clientBoundsWidth - strip.TotalFixedWidth)), + strip.StripHeightAbsolute); + if (item.WidthType == eLayoutSizeType.Percent) + totalPercentWidth += item.Width; + if (strip.Items.Count == 1 && size.Width < clientBoundsWidth && clientBoundsWidth >= MinItemSize(item) && item.WidthType == eLayoutSizeType.Percent) + size.Width = clientBoundsWidth; + else if (loc.X + size.Width > clientBounds.X + clientBoundsWidth && strip.Items.Count > 1) + { + if (strip.Items[strip.Items.Count - 1] == item && MinItemSize(item) <= clientBoundsWidth - (loc.X - clientBounds.X)) + size.Width = clientBoundsWidth - (loc.X - clientBounds.X); + else + { + clientBoundsWidth -= (loc.X + size.Width) - (clientBounds.X + clientBoundsWidth); + repeat = true; + break; + } + } + else if(strip.TotalFixedWidth == 0 && totalPercentWidth == 100 && strip.Items[strip.Items.Count - 1] == item && size.Width strips, Rectangle clientBounds) + { + int totalFixedSize = 0; + List percenageStrips = new List(); + foreach (LayoutItemStrip strip in strips) + { + if (strip.StripHeightPercentage == 0) + totalFixedSize += strip.StripHeightAbsolute; + else + percenageStrips.Add(strip); + } + if (percenageStrips.Count > 0) + { + int sizeLimit = GetStripsSizeLimit(clientBounds); + if (totalFixedSize < sizeLimit) + sizeLimit -= totalFixedSize; + foreach (LayoutItemStrip strip in percenageStrips) + { + strip.StripHeightAbsolute = Math.Max(strip.StripHeightAbsolute, (sizeLimit * strip.StripHeightPercentage) / 100); + strip.StripHeightAbsolute = Math.Max(strip.StripHeightAbsolute, strip.MinStripHeightAbsolute); + } + } + } + + private List SliceItemsInStrips(LayoutGroup group, Rectangle clientBounds, LayoutContext context) + { + LayoutItemCollection items = group.Items; + List strips = new List(); + + if (items.Count == 0) return strips; + + int sizeLimit = GetSizeLimit(clientBounds); + int currentPercent = 0; + int currentFixedSize = 0; + int currentTotalMinSize = 0; + int start = 0, end = items.Count; + Size largestTextSize = Size.Empty; + + LayoutItemStrip currentStrip = new LayoutItemStrip(); + + // Check whether first or last item spans total client bounds effectively reducing the client width + int firstVisibleIndex = GetFirstVisibleItemIndex(items); + int lastVisibleIndex = GetLastVisibleItemIndex(items); + LayoutItemBase spanItem = null; + if (firstVisibleIndex >= 0) spanItem = items[firstVisibleIndex]; + if (spanItem != null && !IsFixedStripSize(spanItem) && ItemStripSize(spanItem) >= 100) + { + if (spanItem.IsTextSizeShared) + largestTextSize = Helpers.Max(largestTextSize, spanItem.MeasureText(context)); + else + spanItem.MeasureText(context); + sizeLimit -= ActualItemSize(spanItem, clientBounds.Width); + currentStrip.IsLeftSpanStrip = true; + currentStrip.StripHeightPercentage = 100; + currentStrip.MinStripHeightAbsolute = spanItem.MinSize.Height; + currentStrip.Items.Add(spanItem); + strips.Add(currentStrip); + currentStrip = new LayoutItemStrip(); + start = firstVisibleIndex + 1; + } + if (firstVisibleIndex != lastVisibleIndex && lastVisibleIndex > 0) + { + spanItem = items[lastVisibleIndex]; + if (!IsFixedStripSize(spanItem) && ItemStripSize(spanItem) >= 100 && !(!IsFixedSize(spanItem) && ItemSize(spanItem) >= 100)) + { + if (spanItem.IsTextSizeShared) + largestTextSize = Helpers.Max(largestTextSize, spanItem.MeasureText(context)); + else + spanItem.MeasureText(context); + sizeLimit -= ActualItemSize(spanItem, clientBounds.Width); + currentStrip.IsRightSpanStrip = true; + currentStrip.StripHeightPercentage = 100; + currentStrip.MinStripHeightAbsolute = spanItem.MinSize.Height; + currentStrip.Items.Add(spanItem); + strips.Add(currentStrip); + currentStrip = new LayoutItemStrip(); + end = lastVisibleIndex; + } + } + + for (int i = start; i < end; i++) + { + LayoutItemBase item = items[i]; + if (!item.Visible) continue; + int itemSize = ItemSize(item); + + if (item.IsTextSizeShared) + largestTextSize = Helpers.Max(largestTextSize, item.MeasureText(context)); + else + item.MeasureText(context); + + if (IsFixedSize(item)) + { + if (currentTotalMinSize + itemSize > sizeLimit && currentTotalMinSize > 0 || currentPercent >= 100) + { + // Trigger new line + currentStrip.TotalFixedWidth = currentFixedSize; + strips.Add(currentStrip); + currentStrip = new LayoutItemStrip(); + currentFixedSize = Math.Max(itemSize, MinItemSize(item)); ; + currentTotalMinSize = itemSize; + currentPercent = 0; + } + else + { + currentFixedSize += Math.Max(itemSize, MinItemSize(item)); + currentTotalMinSize += itemSize; + } + if (item.HeightType == eLayoutSizeType.Percent) + currentStrip.StripHeightPercentage = Math.Max(currentStrip.StripHeightPercentage, item.Height); + else + currentStrip.StripHeightAbsolute = Math.Max(currentStrip.StripHeightAbsolute, item.Height); + } + else + { + int minItemSize = MinItemSize(item); + if (currentPercent + itemSize > 100 && currentPercent > 0 || (currentTotalMinSize + minItemSize > sizeLimit || itemSize > 100) && currentTotalMinSize > 0) + { + // Trigger new line + currentStrip.TotalFixedWidth = currentFixedSize; + strips.Add(currentStrip); + currentStrip = new LayoutItemStrip(); + currentFixedSize = 0; + currentTotalMinSize = 0; + currentPercent = 0; + } + //else + //{ + currentPercent += itemSize; + currentTotalMinSize += minItemSize; + //} + if (item.HeightType == eLayoutSizeType.Percent) + currentStrip.StripHeightPercentage = Math.Max(currentStrip.StripHeightPercentage, item.Height); + else + currentStrip.StripHeightAbsolute = Math.Max(currentStrip.StripHeightAbsolute, item.Height); + } + currentStrip.MinStripHeightAbsolute = Math.Max(currentStrip.MinStripHeightAbsolute, item.MinSize.Height); + if (item.IsTextBaselineShared) + currentStrip.LargestTextBaseline = Math.Max(currentStrip.LargestTextBaseline, item.TextBaseline); + currentStrip.Items.Add(item); + } + if (currentStrip.Items.Count > 0) + { + strips.Add(currentStrip); + currentStrip.TotalFixedWidth = currentFixedSize; + } + + context.LargestTextSize = largestTextSize; + + return strips; + } + + private int GetFirstVisibleItemIndex(LayoutItemCollection items) + { + for (int i = 0; i < items.Count; i++) + { + if (items[i].Visible) return i; + } + return -1; + } + private int GetLastVisibleItemIndex(LayoutItemCollection items) + { + for (int i = items.Count - 1; i >= 0; i--) + { + if (items[i].Visible) return i; + } + return -1; + } + + private int ActualItemSize(LayoutItemBase item, int clientSize) + { + if (item.WidthType == eLayoutSizeType.Absolute) + return item.Width; + else + return (Math.Min(100, (item.Width == 99 ? 100 : item.Width)) * clientSize) / 100; // 99% is special case where we have relative size item inside of fixed size items on single line + } + private int MinItemSize(LayoutItemBase item) + { + return item.MinSize.Width; + } + private int GetSizeLimit(Rectangle clientBounds) + { + return clientBounds.Width; + } + private int GetStripsSizeLimit(Rectangle clientBounds) + { + return clientBounds.Height; + } + private int ItemSize(LayoutItemBase item) + { + return item.Width; + } + private int ItemStripSize(LayoutItemBase item) + { + return item.Height; + } + private bool IsFixedSize(LayoutItemBase item) + { + return item.IsWidthFixed; + } + private bool IsFixedStripSize(LayoutItemBase item) + { + return item.IsHeightFixed; + } + } + + internal class LayoutItemStrip + { + /// + /// Collection of items inside of strip. + /// + public List Items = new List(); + /// + /// Total width of all items with fixed width in the strip. + /// + public int TotalFixedWidth = 0; + /// + /// True if this is left most strip in group which spans whole group height. + /// + public bool IsLeftSpanStrip = false; + /// + /// True if this is right most strip in group which spans whole group height. + /// + public bool IsRightSpanStrip = false; + /// + /// Strip height determined as maximum height of items in it. + /// + public int StripHeightAbsolute = 0; + /// + /// Minimum strip height according to the larges MinSize of contained items. + /// + public int MinStripHeightAbsolute = 0; + /// + /// Maximum percentage strip height for all items in it. + /// + public int StripHeightPercentage = 0; + /// + /// The largest text-baseline for all items in strip. + /// + public int LargestTextBaseline = 0; + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutContext.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutContext.cs new file mode 100644 index 00000000..330dc3cc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutContext.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout +{ + public class LayoutContext + { + + /// + /// Initializes a new instance of the LayoutContext class. + /// + /// + /// + /// + public LayoutContext(LayoutControl layoutControl, Graphics graphics, Font font) + { + LayoutControl = layoutControl; + Graphics = graphics; + Font = font; + FontBaseline = Helpers.GetTextBaseline(layoutControl, font, ContentAlignment.TopLeft); + RightToLeft = (layoutControl.RightToLeft == System.Windows.Forms.RightToLeft.Yes); + } + + public LayoutControl LayoutControl = null; + public Graphics Graphics = null; + public Font Font = null; + public Size LargestTextSize = Size.Empty; + public int FontBaseline = 0; + public bool RightToLeft = false; + public int AbsoluteIndex = 0; + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutControl.cs new file mode 100644 index 00000000..50ee9e51 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutControl.cs @@ -0,0 +1,1378 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.Windows.Forms.Layout; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Layout +{ + [ToolboxItem(true)] + [Designer("DevComponents.DotNetBar.Layout.Design.LayoutControlDesigner, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04")] + [ToolboxBitmap(typeof(LayoutControl), "LayoutControl.ico")] + public class LayoutControl : ContainerControl + { + /// + /// Initializes a new instance of the LayoutControl class. + /// + public LayoutControl() + { + this.SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer + | ControlStyles.SupportsTransparentBackColor | ControlStyles.Opaque, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + //this.SetStyle(ControlStyles.Opaque, true); + + _RootGroup.IsRootGroup = true; + + _HScrollBar = new DevComponents.DotNetBar.ScrollBar.HScrollBarAdv(); + _HScrollBar.Height = SystemInformation.HorizontalScrollBarHeight; + _HScrollBar.Visible = false; + _HScrollBar.Scroll += new ScrollEventHandler(HScrollBarScroll); + this.Controls.Add(_HScrollBar); + + _VScrollBar = new VScrollBarAdv(); + _VScrollBar.Width = SystemInformation.VerticalScrollBarWidth; + _VScrollBar.Visible = false; + _VScrollBar.Scroll += VScrollBarScroll; + this.Controls.Add(_VScrollBar); + + _Thumb = new Control(); + _Thumb.Width = SystemInformation.VerticalScrollBarWidth; + _Thumb.Height = SystemInformation.HorizontalScrollBarHeight; + _Thumb.Visible = false; + this.Controls.Add(_Thumb); + + _InsertMarker = new InsertMarker(); + _InsertMarker.Visible = false; + this.Controls.Add(_InsertMarker); + + _RootGroup.LayoutControl = this; + + this.FocusStyle = new SimpleStyle(); + + if (BarFunctions.IsWindows7 && DevComponents.DotNetBar.Touch.TouchHandler.IsTouchEnabled) + { + _TouchHandler = new DevComponents.DotNetBar.Touch.TouchHandler(this, DevComponents.DotNetBar.Touch.eTouchHandlerType.Gesture); + _TouchHandler.PanBegin += new EventHandler(TouchHandlerPanBegin); + _TouchHandler.Pan += new EventHandler(TouchHandlerPan); + _TouchHandler.PanEnd += new EventHandler(TouchHandlerPanEnd); + } + + StyleManager.Register(this); + } + protected override void Dispose(bool disposing) + { + if (disposing) StyleManager.Unregister(this); + base.Dispose(disposing); + } + + private Color _CurrentBackColor = Color.Empty; + private void UpdateBackColor() + { + DevComponents.DotNetBar.Rendering.Office2007ColorTable table = ((DevComponents.DotNetBar.Rendering.Office2007Renderer)DevComponents.DotNetBar.Rendering.GlobalManager.Renderer).ColorTable; + _CurrentBackColor = table.Form.BackColor; + } + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + UpdateBackColor(); + this.Invalidate(true); + } + void HScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.NewValue != e.OldValue) + ScrollControls(-e.NewValue, 0); + } + + void VScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.NewValue != e.OldValue) + ScrollControls(0, -e.NewValue); + //Console.WriteLine("{0} {1} {2}", e.Type, e.NewValue, _RootGroup.ActualBounds.Height); + } + + private Control _Thumb = null; + private DevComponents.DotNetBar.ScrollBar.HScrollBarAdv _HScrollBar = null; + private VScrollBarAdv _VScrollBar = null; + private InsertMarker _InsertMarker = null; + protected override void OnPaint(PaintEventArgs e) + { +#if TRIAL + if(WinApi.ColorExpAlt()) + { + StringFormat format=new StringFormat(StringFormat.GenericDefault); + format.Alignment=StringAlignment.Center; + format.FormatFlags=format.FormatFlags & ~(format.FormatFlags & StringFormatFlags.NoWrap); + e.Graphics.DrawString("Thank you very much for trying DotNetBar. Unfortunately your trial period is over. To continue using DotNetBar you should purchase license at http://www.devcomponents.com",new Font(this.Font.FontFamily,12),SystemBrushes.Highlight,this.ClientRectangle,format); + format.Dispose(); + return; + } +#endif + if ((this.BackColor.IsEmpty || this.BackColor == Color.Transparent)) + { + base.OnPaintBackground(e); + } + else if(this.BackColor == SystemColors.Control && !_CurrentBackColor.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(_CurrentBackColor)) + e.Graphics.FillRectangle(brush, this.ClientRectangle); + } + else + { + using (SolidBrush brush = new SolidBrush(this.BackColor)) + e.Graphics.FillRectangle(brush, this.ClientRectangle); + } + using (PaintContext context = new PaintContext(this, e.Graphics, _HotkeyPrefix)) + { + _RootGroup.Paint(context); + } + //if (!string.IsNullOrEmpty(this.Text)) + // e.Graphics.DrawString(this.Text, this.Font, Brushes.Black, new PointF(0, this.Height - 32)); + base.OnPaint(e); + } + protected override void OnHandleCreated(EventArgs e) + { + UpdateBackColor(); + _RootGroup.SetBounds(GetLayoutBounds()); + //LayoutGroup(); + base.OnHandleCreated(e); + } + private void LayoutGroup() + { + if (this.IsHandleCreated) + { + using (Graphics g = this.CreateGraphics()) + { + LayoutContext context = new LayoutContext(this, g, _LabelFont ?? this.Font); + _RootGroup.Layout(context); + } + } + } + private Rectangle GetLayoutBounds() + { + Rectangle r = this.ClientRectangle; + return r; + } + protected override void OnLayout(LayoutEventArgs levent) + { + if (_VScrollBar == null || _HScrollBar == null || !this.IsHandleCreated) return; + + Rectangle r = GetLayoutBounds(); + if (r.Width <= 0 || r.Height <= 0) return; + + WinApi.SendMessage(this.Handle, WinApi.WM_SETREDRAW, 0, 0); + + r.Offset(_ScrollPosition); + _RootGroup.SetBounds(r); + LayoutGroup(); + + bool hScrollBarVisible = false, vScrollBarVisible = false; + + if (_RootGroup.ActualBounds.Height > r.Height + 1) + { + vScrollBarVisible = true; + + r.Width -= _VScrollBar.Width; + _RootGroup.SetBounds(r); + LayoutGroup(); + + if (_RootGroup.ActualBounds.Width > r.Width + 1) + { + hScrollBarVisible = true; + r.Height -= _HScrollBar.Height; + _RootGroup.SetBounds(r); + LayoutGroup(); + } + + } + else if (_RootGroup.ActualBounds.Width > r.Width + 1) + { + hScrollBarVisible = true; + + r.Height -= _HScrollBar.Height; + + _RootGroup.SetBounds(r); + LayoutGroup(); + + if (_RootGroup.ActualBounds.Height > r.Height + 1) + { + vScrollBarVisible = true; + r.Width -= _VScrollBar.Width; + _RootGroup.SetBounds(r); + LayoutGroup(); + } + + } + + bool performLayout = false; + if (vScrollBarVisible && r.Height > 0) + { + _VScrollBar.Location = new Point(this.ClientRectangle.Right - _VScrollBar.Width, this.ClientRectangle.Y); + _VScrollBar.Height = this.ClientRectangle.Height - (hScrollBarVisible ? _HScrollBar.Height : 0); + if (_VScrollBar.Visible != vScrollBarVisible) + { + _VScrollBar.Value = 0; + _VScrollBar.Visible = true; + _VScrollBar.BringToFront(); + } + _VScrollBar.Minimum = 0; + _VScrollBar.Maximum = _RootGroup.ActualBounds.Height - 1; + _VScrollBar.LargeChange = r.Height; + _VScrollBar.SmallChange = 16; + } + else if (_VScrollBar.Visible) + { + _VScrollBar.Visible = false; + if (_ScrollPosition.Y != 0) + { + _ScrollPosition.Y = 0; + performLayout = true; + } + } + + if (hScrollBarVisible && r.Width > 0) + { + _HScrollBar.Location = new Point(this.ClientRectangle.X, this.ClientRectangle.Bottom - _HScrollBar.Height); + _HScrollBar.Width = this.ClientRectangle.Width - (vScrollBarVisible ? _VScrollBar.Width : 0); + if (_HScrollBar.Visible != hScrollBarVisible) + { + _HScrollBar.Value = 0; + _HScrollBar.Visible = true; + _HScrollBar.BringToFront(); + } + _HScrollBar.Minimum = 0; + _HScrollBar.Maximum = _RootGroup.ActualBounds.Width - 1; + _HScrollBar.LargeChange = r.Width; + _HScrollBar.SmallChange = 16; + } + else if (_HScrollBar.Visible) + { + _HScrollBar.Visible = false; + if (_ScrollPosition.X != 0) + { + _ScrollPosition.X = 0; + performLayout = true; + } + } + + if (vScrollBarVisible && hScrollBarVisible && r.Height > 0 && r.Width > 0) + { + _Thumb.Bounds = new Rectangle(this.ClientRectangle.Right - _VScrollBar.Width, this.ClientRectangle.Bottom - _HScrollBar.Height, _VScrollBar.Width, _HScrollBar.Height); + _Thumb.Visible = true; + _Thumb.BringToFront(); + } + else if (_Thumb.Visible) + _Thumb.Visible = false; + + if (performLayout) + { + r = GetLayoutBounds(); + r.Offset(_ScrollPosition); + _RootGroup.SetBounds(r); + LayoutGroup(); + } + + WinApi.SendMessage(this.Handle, WinApi.WM_SETREDRAW, 1, 0); + this.Refresh(); + base.OnLayout(levent); + } + + protected override void OnMouseWheel(MouseEventArgs e) + { + if (_VScrollBar.Visible) + { + int y = -_VScrollBar.Value + Math.Sign(e.Delta) * _VScrollBar.SmallChange; + if (-y < 0) y = 0; + ScrollControls(0, y); + _VScrollBar.Value = Math.Min(_VScrollBar.Maximum - _VScrollBar.LargeChange, -y); + + } + base.OnMouseWheel(e); + } + + public new void ScrollControlIntoView(Control control) + { + LayoutItemBase item = FindControlItem(control); + if (item == null) return; + ScrollItemIntoView(item); + } + + /// + /// Brings specified item that belongs to this LayoutControl into view by scrolling control if necessary. + /// + /// Item to bring into view. + public void ScrollItemIntoView(LayoutItemBase item) + { + if (item.GetLayoutControl() != this) + throw new ArgumentException("item does not belong to this control"); + if (!_HScrollBar.Visible && !_VScrollBar.Visible) return; + + Rectangle clientRect = this.ClientRectangle; + Rectangle itemBounds = item.Bounds; + //itemBounds.Offset(-_ScrollPosition.X,-_ScrollPosition.Y); + if (clientRect.Contains(itemBounds)) return; + + Point scroll = new Point(); + if (item.Bounds.Y < clientRect.Y) + { + scroll.Y = clientRect.Y - itemBounds.Y; + } + else if (item.Bounds.Bottom > clientRect.Bottom) + { + scroll.Y = Math.Max(-(_VScrollBar.Maximum - _VScrollBar.LargeChange), clientRect.Bottom - itemBounds.Bottom); + } + + if (item.Bounds.X < clientRect.X) + { + scroll.X = clientRect.X - itemBounds.X; + } + else if (item.Bounds.Right > clientRect.Right) + { + scroll.X = clientRect.Right - itemBounds.Right; + } + + if (!scroll.IsEmpty) + { + ScrollControls(_ScrollPosition.X + scroll.X, _ScrollPosition.Y + scroll.Y); + _VScrollBar.Value = Math.Max(0, Math.Min(Math.Abs(_ScrollPosition.Y), _VScrollBar.Maximum)); + } + + } + + private LayoutGroup _RootGroup = new LayoutGroup(); + /// + /// Gets the LayoutGroup for the control. LayoutGroup should not be changed. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(false)] + public LayoutGroup RootGroup + { + get { return _RootGroup; } + set + { + if (value != _RootGroup) + { + LayoutGroup oldValue = _RootGroup; + _RootGroup = value; + OnRootGroupChanged(oldValue, value); + } + } + } + /// + /// Called when RootGroup property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnRootGroupChanged(LayoutGroup oldValue, LayoutGroup newValue) + { + if (oldValue != null) + { + oldValue.LayoutControl = null; + oldValue.IsRootGroup = false; + } + if (newValue != null) + { + newValue.LayoutControl = this; + newValue.IsRootGroup = true; + } + //OnPropertyChanged(new PropertyChangedEventArgs("RootGroup")); + + } + + private Font _LabelFont = null; + /// + /// Indicates font used for the item labels. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates font used for the item labels.")] + public Font LabelFont + { + get { return _LabelFont; } + set + { + if (value != _LabelFont) + { + Font oldValue = _LabelFont; + _LabelFont = value; + OnLabelFontChanged(oldValue, value); + } + } + } + /// + /// Called when LabelFont property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnLabelFontChanged(Font oldValue, Font newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("LabelFont")); + this.PerformLayout(); + this.Invalidate(); + } + + private Color _LabelTextColor = Color.Empty; + /// + /// Gets or sets the color of the label text. + /// + [Category("Appearance"), Description("Indicates color of label text.")] + public Color LabelTextColor + { + get { return _LabelTextColor; } + set { _LabelTextColor = value; /*OnPropertyChanged("LabelTextColor");*/ this.Invalidate(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLabelTextColor() + { + return !_LabelTextColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetLabelTextColor() + { + this.LabelTextColor = Color.Empty; + } + + private eTextAlignment _LabelTextAlignment = eTextAlignment.Default; + /// + /// Indicates the label text alignment within the text bounds. + /// + [DefaultValue(eTextAlignment.Default), Category("Appearance"), Description("Indicates the label text alignment within the text bounds.")] + public eTextAlignment LabelTextAlignment + { + get { return _LabelTextAlignment; } + set + { + if (value != _LabelTextAlignment) + { + eTextAlignment oldValue = _LabelTextAlignment; + _LabelTextAlignment = value; + OnLabelTextAlignmentChanged(oldValue, value); + } + } + } + /// + /// Called when LabelTextAlignment property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnLabelTextAlignmentChanged(eTextAlignment oldValue, eTextAlignment newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("LabelTextAlignment")); + this.Invalidate(); + } + + private EmptyLayoutManager _EmptyLayout = new EmptyLayoutManager(); + public override LayoutEngine LayoutEngine + { + get + { + return _EmptyLayout; + } + } + + /// + /// Sets default property values for LayoutControlItem given the control assigned to it. + /// + /// Reference to LayoutControlItem + public void SetupControlItem(DevComponents.DotNetBar.Layout.LayoutControlItem item) + { + if (item == null || item.Control == null) return; + + Control c = item.Control; + + c.Margin = new System.Windows.Forms.Padding(); + + if (c is TextBoxBase) + { + item.Width = 100; + item.WidthType = eLayoutSizeType.Percent; + item.Height = c.Height + item.Padding.Vertical; + item.Text = "Label:"; + item.MinSize = new Size(120, 0); + } + else if (c is ButtonBase || c is IButtonControl) + { + //item.ControlSize = c.Size; + item.Width = c.Width + item.Padding.Horizontal; + item.Height = c.Height + item.Padding.Vertical; + item.Text = ""; + item.MinSize = new Size(32, 20); + } + else if(c is DevComponents.DotNetBar.Controls.RatingStar) + { + c.Text = ""; + item.Width = c.Width + item.Padding.Horizontal; + item.Height = c.Height + item.Padding.Vertical; + item.Text = "Rating:"; + item.MinSize = new Size(85, 23); + } + else + { + item.Width = c.Width + item.Padding.Horizontal; + item.Height = c.Height + item.Padding.Vertical; + item.Text = "Label:"; + item.MinSize = new Size(64, 18); + } + } + + private LayoutItemBase FindItemForMnemonic(LayoutGroup group, char charCode) + { + foreach (LayoutItemBase item in group.Items) + { + LayoutGroup childGroup = item as LayoutGroup; + if (childGroup != null) + { + LayoutItemBase item2 = FindItemForMnemonic(childGroup, charCode); + if (item2 != null) return item2; + } + else if (item.TextVisible && !string.IsNullOrEmpty(item.Text) && IsMnemonic(charCode, item.Text)) + { + return item; + } + } + return null; + } + private bool IsMnemonicProcessed(char charCode) + { + LayoutItemBase item = FindItemForMnemonic(_RootGroup, charCode); + if (item != null) + return item.ProcessMnemonic(charCode); + + return false; + } + protected override bool ProcessMnemonic(char charCode) + { + if (this.Visible && _MnemonicsEnabled && IsMnemonicProcessed(charCode)) + return true; + return base.ProcessMnemonic(charCode); + } + + private bool _MnemonicsEnabled = true; + /// + /// Indicates whether accelerator keys assigned to item Text property are processed by items which respond to them. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether accelerator keys assigned to item Text property are processed by items which respond to them.")] + public bool MnemonicsEnabled + { + get { return _MnemonicsEnabled; } + set + { + if (value != _MnemonicsEnabled) + { + bool oldValue = _MnemonicsEnabled; + _MnemonicsEnabled = value; + OnMnemonicsEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when MnemonicsEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnMnemonicsEnabledChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("MnemonicsEnabled")); + } + + private System.Drawing.Text.HotkeyPrefix _HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; + /// + /// Indicates visibility of the hot-key prefixes, accelerator keys, that are set using ampersand in item Text. + /// + [DefaultValue(System.Drawing.Text.HotkeyPrefix.Show), Category("Behavior"), Description("Indicates visibility of the hot-key prefixes, accelerator keys, that are set using ampersand in item Text.")] + public System.Drawing.Text.HotkeyPrefix HotkeyPrefix + { + get { return _HotkeyPrefix; } + set + { + if (value != _HotkeyPrefix) + { + System.Drawing.Text.HotkeyPrefix oldValue = _HotkeyPrefix; + _HotkeyPrefix = value; + OnHotkeyPrefixChanged(oldValue, value); + } + } + } + /// + /// Called when HotkeyPrefix property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnHotkeyPrefixChanged(System.Drawing.Text.HotkeyPrefix oldValue, System.Drawing.Text.HotkeyPrefix newValue) + { + this.Invalidate(); + //OnPropertyChanged(new PropertyChangedEventArgs("HotkeyPrefix")); + + } + private Size GetAutoScrollMinSize() + { + Rectangle clientRectangle = GetLayoutBounds(); + Rectangle displayRect = _RootGroup.ActualBounds; + return new Size(Math.Abs(Math.Min(clientRectangle.Width - displayRect.Width, 0)), + Math.Abs(Math.Min(clientRectangle.Height - displayRect.Height, 0))); + } + private Point _ScrollPosition = new Point(); + private void ScrollControls(Point scrollPosition) + { + ScrollControls(scrollPosition.X, scrollPosition.Y); + } + private void ScrollControls(int x, int y) + { + int xScroll = 0; + int yScroll = 0; + Rectangle clientRectangle = GetLayoutBounds(); + if (_VScrollBar.Visible) + clientRectangle.Width -= _VScrollBar.Width; + if (_HScrollBar.Visible) + clientRectangle.Height -= _HScrollBar.Height; + + Rectangle displayRect = _RootGroup.ActualBounds; + int maxXScroll = Math.Min(clientRectangle.Width - displayRect.Width, 0); + int maxYScroll = Math.Min(clientRectangle.Height - displayRect.Height, 0); + if (x > 0) + x = 0; + if (y > 0) + y = 0; + if (x < maxXScroll) + x = maxXScroll; + if (y < maxYScroll) + y = maxYScroll; + if (_ScrollPosition.X != x) + xScroll = x - displayRect.X; + if (_ScrollPosition.Y != y) + yScroll = y - displayRect.Y; + _ScrollPosition.X = x; + _ScrollPosition.Y = y; + + bool useScrollWindowEx = !(_VScrollBar.Visible && _HScrollBar.Visible); + + if ((xScroll != 0) || ((yScroll != 0) && this.IsHandleCreated)) + { + DateTime start = DateTime.Now; + + if (useScrollWindowEx) + { + _RootGroup.UpdateScrollBounds(xScroll, yScroll, false); // Move Items but not controls + Rectangle clipBounds = clientRectangle; + WinApi.RECT rectClip = WinApi.RECT.FromXYWH(clipBounds.X, clipBounds.Y, clipBounds.Width, clipBounds.Height); + WinApi.RECT prcUpdate = WinApi.RECT.FromXYWH(clipBounds.X, clipBounds.Y, clipBounds.Width, clipBounds.Height); + WinApi.RECT rectScroll = WinApi.RECT.FromXYWH(displayRect.X, displayRect.Y, displayRect.Width, displayRect.Height); + WinApi.ScrollWindowEx(new System.Runtime.InteropServices.HandleRef(this, this.Handle), + xScroll, + yScroll, + ref rectScroll, + ref rectClip, + IntPtr.Zero, + ref prcUpdate, + 7); + if (_HScrollBar.Visible) + { + _HScrollBar.Location = new Point(this.ClientRectangle.X, this.ClientRectangle.Bottom - _HScrollBar.Height); + _HScrollBar.BringToFront(); + _HScrollBar.Refresh(); + } + if (_VScrollBar.Visible) + { + _VScrollBar.Location = new Point(this.ClientRectangle.Right - _VScrollBar.Width, this.ClientRectangle.Y); + _VScrollBar.BringToFront(); + _VScrollBar.Refresh(); + } + + Type t = typeof(Control); + System.Reflection.MethodInfo mi = t.GetMethod("UpdateBounds", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, System.Type.DefaultBinder, new Type[0], new System.Reflection.ParameterModifier[0]); + if (mi != null) + { + for (int i = 0; i < base.Controls.Count; i++) + { + Control control = base.Controls[i]; + if ((control != null) && control.IsHandleCreated && control != _VScrollBar && control != _HScrollBar) + { + mi.Invoke(control, null); //control.UpdateBounds(); + } + } + } + this.Refresh(); + } + else + { + WinApi.SendMessage(this.Handle, WinApi.WM_SETREDRAW, 0, 0); + _RootGroup.UpdateScrollBounds(xScroll, yScroll, true); + WinApi.SendMessage(this.Handle, WinApi.WM_SETREDRAW, 1, 0); + this.Refresh(); + } + + DateTime end = DateTime.Now; + //Console.WriteLine("ScrollTime:{0}", end.Subtract(start).TotalMilliseconds); + } + } + + /// + /// Padding property is not supported by LayoutControl. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] + public new System.Windows.Forms.Padding Padding + { + get + { + return base.Padding; + } + set + { + } + } + + private bool _AutoScaleLayout = true; + /// + /// Indicates whether layout control automatically scales the items if the parent Form performs scaling due to AutoScale settings. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether layout control automatically scales the items if the parent Form performs scaling due to AutoScale settings.")] + public bool AutoScaleLayout + { + get { return _AutoScaleLayout; } + set + { + _AutoScaleLayout = value; + } + } + + + protected virtual void ScaleItems(LayoutGroup group, SizeF factor) + { + foreach (LayoutItemBase item in group.Items) + { + item.ScaleItem(factor); + if (item is LayoutGroup) + ScaleItems((LayoutGroup)item, factor); + } + } + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + //Console.WriteLine("ScaleControl factor={0} boundsSpecified={1}", factor, specified); + if (_AutoScaleLayout && (factor.Width != 1f || factor.Height != 1f)) + { + this.SuspendLayout(); + try + { + ScaleItems(_RootGroup, factor); + } + finally + { + ResumeLayout(); + } + } + base.ScaleControl(factor, specified); + } + protected override void ScaleCore(float dx, float dy) + { + //Console.WriteLine("ScaleCore dx={0} dy={1}", dx, dy); + base.ScaleCore(dx, dy); + } + + private SimpleStyle _FocusStyle = null; + /// + /// Indicates the focus style applied to the item which hosts an Control when that control contains input focus. + /// + [Category("Appearance"), Description("Indicates the focus style applied to the item which hosts an Control when that control contains input focus."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SimpleStyle FocusStyle + { + get { return _FocusStyle; } + internal set + { + if (value != _FocusStyle) + { + SimpleStyle oldValue = _FocusStyle; + _FocusStyle = value; + OnFocusStyleChanged(oldValue, value); + } + } + } + /// + /// Called when FocusStyle property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnFocusStyleChanged(SimpleStyle oldValue, SimpleStyle newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= FocusStylePropertyChanged; + if (newValue != null) + newValue.PropertyChanged += FocusStylePropertyChanged; + //OnPropertyChanged(new PropertyChangedEventArgs("FocusStyle")); + + } + private void FocusStylePropertyChanged(object sender, PropertyChangedEventArgs e) + { + this.Invalidate(); + } + + /// + /// Gets the vertical scrollbar used by control. + /// + [Browsable(false)] + public VScrollBarAdv VScrollBar + { + get + { + return _VScrollBar; + } + } + /// + /// Gets the horizontal scrollbar used by the control. + /// + [Browsable(false)] + public DevComponents.DotNetBar.ScrollBar.HScrollBarAdv HScrollBar + { + get + { + return _HScrollBar; + } + } + /// + /// Finds the item which is responsible for the control or returns null if there is no item that represents the control or control is not + /// contained by the layout control. + /// + /// + /// + public LayoutItemBase FindControlItem(Control c) + { + if (c == null || c.Parent != this) return null; + + return FindControlItem(_RootGroup, c); + } + private LayoutItemBase FindControlItem(LayoutGroup group, Control c) + { + foreach (LayoutItemBase item in group.Items) + { + if (item is LayoutControlItem && ((LayoutControlItem)item).Control == c) + return item; + LayoutGroup childGroup = item as LayoutGroup; + if (childGroup != null) + { + LayoutItemBase childItem = FindControlItem(childGroup, c); + if (childItem != null) return childItem; + } + } + return null; + } + + /// + /// Finds the layout items which have controls assigned but controls are not parented by the layout control or one of its child controls. + /// + /// + public List FindOrphanedControlItems() + { + List list = new List(); + FindOrphanedControlItems(list, _RootGroup); + return list; + } + + private void FindOrphanedControlItems(List list, LayoutGroup group) + { + foreach (LayoutItemBase item in group.Items) + { + if (item is LayoutControlItem && !IsChildControl(((LayoutControlItem)item).Control)) + list.Add(item); + else + { + LayoutGroup childGroup = item as LayoutGroup; + if (childGroup != null) + FindOrphanedControlItems(list, childGroup); + } + } + } + private bool IsChildControl(Control control) + { + if (control == null) return true; + do + { + if (control.Parent == this) return true; + control = control.Parent; + } while (control != null && control.Parent != null); + return false; + } + /// + /// Returns whether control is an system control used internally by LayoutControl. + /// + /// + /// + public bool IsSystemControl(Control c) + { + return c == _VScrollBar || c == _HScrollBar || c == _InsertMarker || c == _Thumb; + } + + private bool _DisposeControlsOnRootGroupClear = true; + /// + /// Indicates whether controls associated with layout items are automatically disposed when RootGroup.Clear method is called. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether controls are automatically disposed when RootGroup.Clear method is called.")] + public bool DisposeControlsOnRootGroupClear + { + get { return _DisposeControlsOnRootGroupClear; } + set + { + _DisposeControlsOnRootGroupClear = value; + } + } + + + private LayoutItemBase _MouseOverItem = null; + protected override void OnMouseMove(MouseEventArgs e) + { + if (_MouseOverItem != null && _MouseOverItem.Bounds.Contains(e.Location)) + { + _MouseOverItem.OnMouseMove(this, e); + } + else + { + LayoutItemBase item = HitTest(e.Location); + if (item != _MouseOverItem) + { + if (_MouseOverItem != null) + _MouseOverItem.OnMouseLeave(this, e); + _MouseOverItem = item; + + if (_MouseOverItem != null) + { + _MouseOverItem.OnMouseEnter(this, e); + _MouseOverItem.OnMouseMove(this, e); + } + } + } + + base.OnMouseMove(e); + } + protected override void OnMouseLeave(EventArgs e) + { + if (_MouseOverItem != null) + { + _MouseOverItem.OnMouseLeave(this, e); + _MouseOverItem = null; + } + base.OnMouseLeave(e); + } + protected override void OnMouseDown(MouseEventArgs e) + { + if (_MouseOverItem != null) + _MouseOverItem.OnMouseDown(this, e); + base.OnMouseDown(e); + } + protected override void OnMouseUp(MouseEventArgs e) + { + if (_MouseOverItem != null) + _MouseOverItem.OnMouseUp(this, e); + base.OnMouseUp(e); + } + protected override void OnClick(EventArgs e) + { + if (_MouseOverItem != null) + _MouseOverItem.OnClick(this, e); + base.OnClick(e); + } + protected override void OnMouseHover(EventArgs e) + { + if (_MouseOverItem != null) + _MouseOverItem.OnMouseHover(this, e); + base.OnMouseHover(e); + } + private bool _ShowToolTips = true; + /// + /// Gets or sets whether tooltips are shown when mouse is over the item when Tooltip property is set. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether tooltips are shown when mouse is over the item when Tooltip property is set.")] + public bool ShowToolTips + { + get { return _ShowToolTips; } + set + { + _ShowToolTips = value; + } + } + /// + /// Gets the layout item at specified location. + /// + /// LayoutControl client coordinates to test. + /// Layout item or null. + public LayoutItemBase HitTest(Point clientLoc) + { + return HitTest(_RootGroup, clientLoc); + } + + private LayoutItemBase HitTest(LayoutGroup group, Point clientLoc) + { + foreach (LayoutItemBase item in group.Items) + { + LayoutGroup childGroup = item as LayoutGroup; + if (childGroup != null) + { + LayoutItemBase childItem = HitTest(childGroup, clientLoc); + if (childItem != null) return childItem; + } + if (item.Bounds.Contains(clientLoc)) + return item; + } + return null; + } + private bool IsContainedBy(LayoutItemBase item, LayoutItemBase parent) + { + if (parent == null || item == null) return false; + do + { + if (item.Parent == parent) + return true; + item = item.Parent; + } while (item != null); + return false; + } + /// + /// Gets the HitTestInsertInfo structure that provides information on insertion point for an item based on the + /// specified client coordinates. + /// + /// Client coordinates to determine insert location for. + /// Instance of HitTestInsertInfo or null if item cannot be placed. + public HitTestInsertInfo GetHitTestInsertInfo(LayoutItemBase insertItem, Point clientLoc) + { + HitTestInsertInfo insertInfo = new HitTestInsertInfo(); + insertInfo.Parent = _RootGroup; + LayoutItemBase item = HitTestInsert(_RootGroup, clientLoc); + if (item != null) + { + if (IsContainedBy(item, insertItem) || insertItem.IsChildItem(item)) + return new HitTestInsertInfo(); + else if (item is LayoutGroup && item != _RootGroup && item != insertItem) + { + insertInfo.Parent = (LayoutGroup)item; + if (insertInfo.Parent.Items.Count == 0) + { + insertInfo.InsertIndex = 0; + insertInfo.InsertMarkerBounds = new Rectangle(item.Bounds.X, item.Bounds.Y, 1, item.Bounds.Height); + } + else + { + LayoutItemBase lastItem = insertInfo.Parent.Items[insertInfo.Parent.Items.Count - 1]; + insertInfo.InsertIndex = insertInfo.Parent.Items.Count; + insertInfo.InsertMarkerBounds = new Rectangle(lastItem.Bounds.Right, lastItem.Bounds.Y, 1, lastItem.Bounds.Height); + } + } + else + { + insertInfo.Parent = (LayoutGroup)item.Parent; + if (clientLoc.X < item.Bounds.X + item.Bounds.Width / 2) + { + insertInfo.InsertIndex = insertInfo.Parent.Items.IndexOf(item); + insertInfo.InsertMarkerBounds = new Rectangle(item.Bounds.X, item.Bounds.Y, 1, item.Bounds.Height); + } + else + { + insertInfo.InsertIndex = insertInfo.Parent.Items.IndexOf(item) + 1; + insertInfo.InsertMarkerBounds = new Rectangle(item.Bounds.Right, item.Bounds.Y, 1, item.Bounds.Height); + } + } + } + else + { + if (_RootGroup.Items.Count == 0) + insertInfo.InsertMarkerBounds = new Rectangle(_RootGroup.Bounds.X, _RootGroup.Bounds.Y, 1, insertItem.Bounds.Height); + else + { + insertInfo.InsertIndex = _RootGroup.Items.Count; + LayoutItemBase lastItem = _RootGroup.Items[_RootGroup.Items.Count - 1]; + insertInfo.InsertMarkerBounds = new Rectangle(lastItem.Bounds.Right, lastItem.Bounds.Y, 1, lastItem.Bounds.Height); + } + } + + return insertInfo; + } + /// + /// Returns item which contains specified client point or null. + /// + /// Client location to test. + /// + private LayoutItemBase HitTestInsert(LayoutGroup group, Point clientLoc) + { + LayoutItemBase relItem = null; + foreach (LayoutItemBase item in group.Items) + { + LayoutGroup childGroup = item as LayoutGroup; + + if (childGroup != null) + { + relItem = HitTestInsert(childGroup, clientLoc); + if (relItem != null) + return relItem; + } + + if (item.Bounds.Contains(clientLoc)) + return item; + + if (group.IsRootGroup && clientLoc.Y >= item.Bounds.Y && clientLoc.Y <= item.Bounds.Bottom) + { + if (item.Bounds.X < clientLoc.X || clientLoc.X > item.Bounds.Right) + relItem = item; + } + } + return relItem; + } + + public void HideInsertMarker() + { + _InsertMarker.Visible = false; + } + public void ShowInsertMarker(Rectangle r) + { + if (r.Width < 6) r.Width = 6; + _InsertMarker.Bounds = r; + if (!_InsertMarker.Visible) + _InsertMarker.Visible = true; + _InsertMarker.BringToFront(); + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMargin + { + get + { + return base.AutoScrollMargin; + } + set + { + } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Size AutoScrollMinSize + { + get + { + return base.AutoScrollMinSize; + } + set { } + } + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool AutoScroll + { + get + { + return base.AutoScroll; + } + set + { + //base.AutoScroll = value; + } + } + [Browsable(false)] + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + } + } + + protected override Size DefaultSize + { + get + { + return new Size(200, 200); + } + } + + #region Touch Handling + private DevComponents.DotNetBar.Touch.TouchHandler _TouchHandler = null; + private bool _TouchEnabled = true; + /// + /// Indicates whether touch support for scrolling is enabled. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether touch support for scrolling is enabled.")] + public bool TouchEnabled + { + get { return _TouchEnabled; } + set + { + if (value != _TouchEnabled) + { + bool oldValue = _TouchEnabled; + _TouchEnabled = value; + OnTouchEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when TouchEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTouchEnabledChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TouchEnabled")); + } + private int TriggerPageChangeOffset + { + get + { + return 32; + } + } + private int MaximumReversePageOffset + { + get + { + return 0; //Math.Min(32, this.Width / 6); + } + } + private bool _TouchDrag = false; + private Point _TouchStartLocation = Point.Empty; + private Point _TouchStartScrollPosition = Point.Empty; + private Rectangle _TouchInnerBounds = Rectangle.Empty; + private void TouchHandlerPanBegin(object sender, DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (_TouchEnabled) + { + _TouchInnerBounds = GetLayoutBounds(); + _TouchStartLocation = e.Location; + _TouchStartScrollPosition = _ScrollPosition; + _TouchDrag = true; + e.Handled = true; + } + } + + private void TouchHandlerPanEnd(object sender, DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + EndTouchPan(); + e.Handled = true; + } + } + + private void EndTouchPan() + { + _TouchDrag = false; + Point autoScrollPosition = _ScrollPosition; + Size autoScrollMinSize = GetAutoScrollMinSize(); + if (autoScrollMinSize.Width > 0) + { + if (autoScrollMinSize.Width < -autoScrollPosition.X) + autoScrollPosition = new Point(autoScrollMinSize.Width, autoScrollPosition.Y); + else if (-autoScrollPosition.X < 0) + autoScrollPosition = new Point(0, autoScrollPosition.Y); + } + + if (autoScrollMinSize.Height > 0) + { + if (autoScrollMinSize.Height < -autoScrollPosition.Y) + autoScrollPosition = new Point(autoScrollPosition.X, autoScrollMinSize.Height); + else if (-autoScrollPosition.Y < 0) + autoScrollPosition = new Point(autoScrollPosition.X, 0); + } + + ScrollControls(autoScrollPosition); + UpdateScrollbarsFromScrollPosition(); + } + + private void TouchHandlerPan(object sender, DevComponents.DotNetBar.Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + Point autoScrollPosition = _ScrollPosition; + Size autoScrollMinSize = GetAutoScrollMinSize(); + int offset = (e.Location.X - _TouchStartLocation.X); + int offsetChange = offset + _TouchStartScrollPosition.X; + + bool overflowH = false; + + if (autoScrollMinSize.Width > 0) + { + if (-offsetChange + MaximumReversePageOffset > autoScrollMinSize.Width) + { + autoScrollPosition.X = -(autoScrollMinSize.Width + MaximumReversePageOffset); + overflowH = true; + } + else if (offsetChange > MaximumReversePageOffset) + { + autoScrollPosition.X = MaximumReversePageOffset; + overflowH = true; + } + else + autoScrollPosition.X = offsetChange; + } + + // Y Scroll + bool overflowV = false; + if (autoScrollMinSize.Height > 0) + { + offset = (e.Location.Y - _TouchStartLocation.Y); + offsetChange = offset + _TouchStartScrollPosition.Y; + + if (-offsetChange + MaximumReversePageOffset > autoScrollMinSize.Height) + { + autoScrollPosition.Y = -(autoScrollMinSize.Height + MaximumReversePageOffset); + overflowV = true; + } + else if (offsetChange > MaximumReversePageOffset) + { + autoScrollPosition.Y = MaximumReversePageOffset; + overflowV = true; + } + else + autoScrollPosition.Y = offsetChange; + } + + if (_ScrollPosition != autoScrollPosition) + { + ScrollControls(autoScrollPosition); + Update(); + } + if (overflowH && overflowV && e.IsInertia) EndTouchPan(); + + + UpdateScrollbarsFromScrollPosition(); + e.Handled = true; + } + } + + private void UpdateScrollbarsFromScrollPosition() + { + if (_VScrollBar != null && _VScrollBar.Visible && _VScrollBar.Value != -_ScrollPosition.Y) + _VScrollBar.Value = Math.Min(_VScrollBar.Maximum, Math.Max(0, -_ScrollPosition.Y)); + if (_HScrollBar != null && _HScrollBar.Visible && _HScrollBar.Value != -_ScrollPosition.X) + _HScrollBar.Value = Math.Min(_HScrollBar.Maximum, Math.Max(0, -_ScrollPosition.X)); + } + #endregion + } + + #region HitTestInsertInfo + public class HitTestInsertInfo + { + public LayoutGroup Parent = null; + public int InsertIndex = -1; + public Rectangle InsertMarkerBounds = Rectangle.Empty; + } + #endregion + + #region EmptyLayoutManager + internal class EmptyLayoutManager : LayoutEngine + { + public override void InitLayout(object child, BoundsSpecified specified) + { + + } + + public override bool Layout(object container, LayoutEventArgs layoutEventArgs) + { + return true; + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutControl.ico b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutControl.ico new file mode 100644 index 00000000..33ca4ed9 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutControl.ico differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutControlItem.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutControlItem.cs new file mode 100644 index 00000000..b6023e1d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutControlItem.cs @@ -0,0 +1,484 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout +{ + /// + /// Represents layout item which hosts a Windows Forms Control. + /// + [Designer("DevComponents.DotNetBar.Layout.Design.LayoutControlItemDesigner, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04")] + public class LayoutControlItem : LayoutItemBase + { + #region Constructor + protected override void OnDispose() + { + UnhookControlEventHandlers(_Control); + base.OnDispose(); + } + #endregion + + #region Implementation + protected override void OnUpdateLayout() + { + base.OnUpdateLayout(); + + if (_Control != null) + { + Rectangle bounds = Helpers.Deflate(this.Bounds, this.Padding); + Rectangle r = bounds; + if (this.TextVisible && !string.IsNullOrEmpty(this.Text)) + { + Rectangle actualTextBounds = this.ActualTextBounds; + if (IsImageVisible) + actualTextBounds = Rectangle.Union(actualTextBounds, this.ActualImageBounds); + if (this.TextPosition == eLayoutPosition.Default || this.TextPosition == eLayoutPosition.Left) + { + r.X = actualTextBounds.Right + _TextControlSpacing; + r.Width = bounds.Right - r.X; + } + else if (this.TextPosition == eLayoutPosition.Top) + { + r.Y = actualTextBounds.Bottom + _TextControlSpacing; + r.Height = bounds.Bottom - r.Y; + } + else if (this.TextPosition == eLayoutPosition.Bottom) + { + r.Height = actualTextBounds.Y - bounds.Y - _TextControlSpacing; + } + else if (this.TextPosition == eLayoutPosition.Right) + { + r.Width = actualTextBounds.X - r.X - _TextControlSpacing; + } + } + if (_Control.Margin.Horizontal > 0 || _Control.Margin.Vertical > 0) + { + r.X += _Control.Margin.Left; + r.Width -= _Control.Margin.Horizontal; + r.Y += _Control.Margin.Top; + r.Height -= _Control.Margin.Vertical; + } + + if (!_ControlSize.IsEmpty && _Control.Dock != DockStyle.Fill && (_ControlSize.Width > 0 && r.Width > _ControlSize.Width) || (_ControlSize.Height > 0 && r.Height > _ControlSize.Height)) + { + Size controlSize = new Size(_ControlSize.Width > 0 ? Math.Min(r.Width, _ControlSize.Width) : r.Width, + _ControlSize.Height > 0 ? Math.Min(r.Height, _ControlSize.Height) : r.Height); + if (_Control.Dock != DockStyle.None) + { + if (_Control.Dock == DockStyle.Left) + r = new Rectangle(r.X, r.Y, controlSize.Width, r.Height); + else if (_Control.Dock == DockStyle.Right) + r = new Rectangle(r.Right - controlSize.Width, r.Y, controlSize.Width, r.Height); + else if (_Control.Dock == DockStyle.Top) + r = new Rectangle(r.X, r.Y, r.Width, controlSize.Height); + else if (_Control.Dock == DockStyle.Bottom) + r = new Rectangle(r.X, r.Bottom - controlSize.Height, r.Width, controlSize.Height); + } + else + { + if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom)) + { + // Center into the bounding box + r.X += (r.Width - controlSize.Width) / 2; + r.Y += (r.Height - controlSize.Height) / 2; + r.Size = controlSize; + } + else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Top)) + { + r.Size = controlSize; + } + else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right)) + { + r.X += (r.Width - controlSize.Width) / 2; + r.Size = controlSize; + } + else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom)) + { + r.Y += (r.Height - controlSize.Height) / 2; + r.Size = controlSize; + } + else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Bottom)) + { + r.Y = r.Bottom - controlSize.Height; + r.Size = controlSize; + } + else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right)) + { + r.Y = r.Bottom - controlSize.Height; + r.X += (r.Width - controlSize.Width) / 2; + r.Size = controlSize; + } + else if (_Control.Anchor == (AnchorStyles.Right | AnchorStyles.Top)) + { + r.X = r.Right - controlSize.Width; + r.Size = controlSize; + } + else if (_Control.Anchor == (AnchorStyles.Right | AnchorStyles.Bottom)) + { + r.X = r.Right - controlSize.Width; + r.Y = r.Bottom - controlSize.Height; + r.Size = controlSize; + } + else if (_Control.Anchor == (AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Top)) + { + r.X = r.Right - controlSize.Width; + r.Y += (r.Height - controlSize.Height) / 2; + r.Size = controlSize; + } + else + r.Size = controlSize; + } + } + + _Control.Bounds = r; + } + } + + protected override void OnPaintBackground(PaintContext context) + { + base.OnPaintBackground(context); + + if (IsKeyboardFocusWithin && context.FocusStyle != null) + { + DrawingHelpers.PaintStyle(context.Graphics, context.FocusStyle, this.Bounds); + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public override void ScaleItem(SizeF factor) + { + base.ScaleItem(factor); + + bool widthChanged = factor.Width != 1f; + bool heightChanged = factor.Height != 1f; + + if (!_ControlSize.IsEmpty && (widthChanged || heightChanged)) + { + Size newSize = new Size(); + if (widthChanged) + newSize.Width = (int)(_ControlSize.Width * factor.Width); + else + newSize.Width = _ControlSize.Width; + if (heightChanged) + newSize.Height = (int)(_ControlSize.Height * factor.Height); + else + newSize.Height = _ControlSize.Height; + ControlSize = newSize; + } + } + + internal override void UpdateScrollBounds(int xScroll, int yScroll, bool moveControls) + { + base.UpdateScrollBounds(xScroll, yScroll, moveControls); + if (moveControls && _Control != null) + _Control.Location = new Point(_Control.Location.X + xScroll, _Control.Location.Y + yScroll); + } + + protected override Size OnMeasureText(LayoutContext c) + { + if (_Control is TextBoxBase && this.TextPosition == eLayoutPosition.Default) + { + TextBoxBase textBox = (TextBoxBase)_Control; + int textBaseLine = Helpers.GetTextBaseline(_Control, ContentAlignment.TopLeft); + if (textBox is DevComponents.DotNetBar.Controls.TextBoxX) + textBaseLine += 3; + else if (textBox.BorderStyle == BorderStyle.FixedSingle || textBox.BorderStyle == BorderStyle.None) + textBaseLine += 2; + else if (textBox.BorderStyle == BorderStyle.Fixed3D) + textBaseLine += 3; + _ControlTextBaseline = textBaseLine; + } + else + _ControlTextBaseline = 0; + + return base.OnMeasureText(c); + } + + internal override int TextBaseline + { + get + { + if (_ControlTextBaseline > 0 && _ControlTextBaseline > base.TextBaseline) + return _ControlTextBaseline; + return base.TextBaseline; + } + set + { + base.TextBaseline = value; + } + } + + private int _ControlTextBaseline = 0; + + private Control _Control = null; + /// + /// Gets or sets the control managed by layout item. + /// + [DefaultValue(null), Category("Data"), Description("Indicates control managed by layout item.")] + public Control Control + { + get { return _Control; } + set + { + if (value != _Control) + { + Control oldValue = _Control; + _Control = value; + OnControlChanged(oldValue, value); + } + } + } + private void UnhookControlEventHandlers(Control control) + { + if (control == null) return; + control.Enter -= ControlEnter; + control.Leave -= ControlLeave; + control.MouseHover -= ControlMouseHover; + control.MouseDown -= ControlMouseDown; + control.MouseMove -= ControlMouseMove; + control.MouseLeave -= ControlMouseLeave; + } + /// + /// Called when Control property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnControlChanged(Control oldValue, Control newValue) + { + if (oldValue != null) + { + UnhookControlEventHandlers(oldValue); + } + OnPropertyChanged(new PropertyChangedEventArgs("Control")); + if (_Control != null) + { + _Control.Enter += ControlEnter; + _Control.Leave += ControlLeave; + _Control.MouseHover += ControlMouseHover; + _Control.MouseDown += ControlMouseDown; + _Control.MouseMove += ControlMouseMove; + _Control.MouseLeave += ControlMouseLeave; + + if (_Control.Visible != this.Visible) + _Control.Visible = this.Visible; + } + InvalidateLayout(); + } + private Point _MouseTooltipLocation = Point.Empty; + void ControlMouseLeave(object sender, EventArgs e) + { + _MouseTooltipLocation = Point.Empty; + if (ToolTipVisible) + HideToolTip(); + } + + void ControlMouseMove(object sender, MouseEventArgs e) + { + if (!_MouseTooltipLocation.IsEmpty && ToolTipVisible && (Math.Abs(_MouseTooltipLocation.X - e.X) > 1 || Math.Abs(_MouseTooltipLocation.Y - e.Y) > 1)) + HideToolTip(); + } + + void ControlMouseDown(object sender, MouseEventArgs e) + { + if (ToolTipVisible) + HideToolTip(); + } + + void ControlMouseHover(object sender, EventArgs e) + { + if (_EnableControlTooltip) + { + ShowToolTip(); + _MouseTooltipLocation = _Control.PointToClient(Control.MousePosition); + } + } + + private void ControlLeave(object sender, EventArgs e) + { + IsKeyboardFocusWithin = false; + } + + private void ControlEnter(object sender, EventArgs e) + { + IsKeyboardFocusWithin = true; + } + + private bool _EnableControlTooltip = true; + /// + /// Indicates whether Tooltip for the item is shown when mouse is over the control. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether Tooltip for the item is shown when mouse is over the control.")] + public bool EnableControlTooltip + { + get { return _EnableControlTooltip; } + set + { + if (value != _EnableControlTooltip) + { + bool oldValue = _EnableControlTooltip; + _EnableControlTooltip = value; + OnEnableControlTooltipChanged(oldValue, value); + } + } + } + /// + /// Called when EnableControlTooltip property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnEnableControlTooltipChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("EnableControlTooltip")); + } + + private int _TextControlSpacing = 3; + /// + /// Indicates spacing between text and the control. + /// + [DefaultValue(3), Category("Appearance"), Description("Indicates spacing between text and the control."), RefreshProperties(RefreshProperties.All)] + public int TextControlSpacing + { + get { return _TextControlSpacing; } + set + { + if (value != _TextControlSpacing) + { + int oldValue = _TextControlSpacing; + _TextControlSpacing = value; + OnTextControlSpacingChanged(oldValue, value); + } + } + } + /// + /// Called when TextControlSpacing property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextControlSpacingChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("TextControlSpacing")); + InvalidateLayout(); + } + + /// + /// Processes accelerator key for the item. + /// + /// + internal override bool ProcessMnemonic(char charCode) + { + if (MnemonicsEnabled && _Control != null && _Control.CanSelect) + { + _Control.Select(); + return true; + } + return false; + } + + private Size _ControlSize = Size.Empty; + /// + /// Indicates suggested control size which is used only if calculated layout size for the control exceeds the size specified here. Either width or height may be set or both. + /// ControlSize property can be used in conjuction with Dock and Anchor properties on the Control. When available space for the Control + /// exceeds ControlSize the Dock and Anchor properties will indicate the control position inside of the control box. + /// + [Category("Appearance"), Description("Indicates suggested control size which is used only if calculated layout size for the control exceeds the size specified here. Either width or height may be set or both.")] + public Size ControlSize + { + get { return _ControlSize; } + set + { + if (value != _ControlSize) + { + Size oldValue = _ControlSize; + _ControlSize = value; + OnControlSizeChanged(oldValue, value); + } + } + } + /// + /// Called when ControlSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnControlSizeChanged(Size oldValue, Size newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ControlSize")); + InvalidateLayout(); + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeControlSize() + { + return !_ControlSize.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetControlSize() + { + ControlSize = Size.Empty; + } + + private bool _AutoSetTabIndex = true; + /// + /// Indicates whether Control TabIndex is automatically set based on the position of the item inside of the layout. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether Control TabIndex is automatically set based on the position of the item inside of the layout.")] + public bool AutoSetTabIndex + { + get { return _AutoSetTabIndex; } + set + { + if (value != _AutoSetTabIndex) + { + bool oldValue = _AutoSetTabIndex; + _AutoSetTabIndex = value; + OnAutoSetTabIndexChanged(oldValue, value); + } + } + } + /// + /// Called when AutoSetTabIndex property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnAutoSetTabIndexChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("AutoSetTabIndex")); + + } + + protected override void OnAbsoluteIndexChanged(int oldValue, int newValue) + { + if (_Control != null && _AutoSetTabIndex) _Control.TabIndex = newValue; + + base.OnAbsoluteIndexChanged(oldValue, newValue); + } + + private bool _FocusVisualStyleEnabled = true; + /// + /// Indicates whether LayoutControl.FocusStyle is used to paint background of item when control has input focus. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether LayoutControl.FocusStyle is used to paint background of item when control has input focus.")] + public bool FocusVisualStyleEnabled + { + get { return _FocusVisualStyleEnabled; } + set + { + if (_FocusVisualStyleEnabled == value) + return; + _FocusVisualStyleEnabled = value; + if (this.IsKeyboardFocusWithin) + this.Invalidate(); + OnPropertyChanged(new PropertyChangedEventArgs("FocusVisualStyleEnabled")); + } + } + + protected override void OnVisibleChanged(bool oldValue, bool newValue) + { + if (_Control != null) + _Control.Visible = newValue; + base.OnVisibleChanged(oldValue, newValue); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutGroup.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutGroup.cs new file mode 100644 index 00000000..139001fc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutGroup.cs @@ -0,0 +1,805 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout +{ + [Designer("DevComponents.DotNetBar.Layout.Design.LayoutGroupDesigner, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04")] + public class LayoutGroup : LayoutItemBase + { + #region Constructor + /// + /// Initializes a new instance of the LayoutGroup class. + /// + public LayoutGroup() + { + _CaptionStyle = new SimpleStyle(); + _CaptionStyle.PropertyChanged += CaptionStylePropertyChanged; + + _Items = new LayoutItemCollection(); + _Items.SetParentItem(this); + } + + protected override void OnDispose() + { + _CaptionStyle.PropertyChanged -= CaptionStylePropertyChanged; + base.OnDispose(); + } + #endregion + + #region Implementation + private Rectangle _ActualBounds = Rectangle.Empty; + /// + /// Gets actual bounds of elements inside of group. The actual bounds may differ from requested layout bounds due to minium + /// size constraint. + /// + internal Rectangle ActualBounds + { + get + { + return _ActualBounds; + } + set + { + _ActualBounds = value; + } + } + protected override void OnPaint(PaintContext context) + { + OnPaintBackground(context); + + if (!_CaptionBounds.IsEmpty) + { + bool isImageVisible = this.IsImageVisible; + Graphics g = context.Graphics; + //context.Graphics.FillRectangle(Brushes.Aqua, _CaptionBounds); + + Color textColor = context.LabelTextColor; + bool dispose = false; + Brush textBrush = context.LabelTextBrush; + + if (_Appearance == eGroupAppearance.Panel) + { + textColor = PaintPanelCaption(context); + textBrush = new SolidBrush(textColor); + dispose = true; + } + else if (_Appearance == eGroupAppearance.GroupPanel) + { + textColor = PaintGroupPanelCaption(context); + textBrush = new SolidBrush(textColor); + dispose = true; + } + else if (_CaptionStyle.IsPainted) + { + DrawingHelpers.PaintStyle(g, _CaptionStyle, _CaptionBounds); + } + if (!_CaptionStyle.TextColor.IsEmpty) + { + textColor = _CaptionStyle.TextColor; + textBrush = new SolidBrush(textColor); + dispose = true; + } + if (this.TextPosition == eLayoutPosition.Top || this.TextPosition == eLayoutPosition.Bottom) + { + PaintText(context, isImageVisible, textColor, ActualTextBounds, textBrush); + } + else + { + // Rotate rendering + g.RotateTransform(-90); + //Rectangle r = new Rectangle(_CaptionBounds.Top, -_CaptionBounds.Right, _CaptionBounds.Height, _CaptionBounds.Width); + //Rectangle r = new Rectangle(-_CaptionBounds.Bottom, _CaptionBounds.X, _CaptionBounds.Height, _CaptionBounds.Width); + Rectangle r = new Rectangle(-ActualTextBounds.Bottom, ActualTextBounds.X, ActualTextBounds.Height, ActualTextBounds.Width); + PaintText(context, isImageVisible, textColor, r, textBrush); + g.ResetTransform(); + } + if (dispose) + textBrush.Dispose(); + + if (isImageVisible) + PaintImage(context, textColor); + } + + foreach (LayoutItemBase item in _Items) + { + if (!item.Visible) continue; + item.Paint(context); + } + //context.Graphics.DrawRectangle(Pens.Green, ActualBounds); + } + private Color PaintPanelCaption(PaintContext context) + { + Rectangle bounds = _CaptionBounds; + if (!this.CaptionStyle.Margin.IsEmpty) + bounds = Helpers.Deflate(bounds, this.CaptionStyle.Margin); + Graphics g = context.Graphics; + DevComponents.DotNetBar.Rendering.Office2007ColorTable table = ((DevComponents.DotNetBar.Rendering.Office2007Renderer)DevComponents.DotNetBar.Rendering.GlobalManager.Renderer).ColorTable; + + Color border = table.LegacyColors.PanelBorder; + Color back1 = table.LegacyColors.PanelBackground; + Color back2 = table.LegacyColors.PanelBackground2; + Color textColor = table.LegacyColors.PanelText; + int backAngle = table.LegacyColors.PanelBackgroundGradientAngle; + + PaintRectangle(bounds, g, border, back1, back2, backAngle); + + return textColor; + } + private Color PaintGroupPanelCaption(PaintContext context) + { + Rectangle r = _CaptionBounds; + Graphics g = context.Graphics; + ElementStyleDisplayInfo info = new ElementStyleDisplayInfo(_GroupPanelStyle, g, r); + ElementStyleDisplay.Paint(info); + + return _GroupPanelStyle.TextColor; + } + const int CaptionEdgeDistance = 4; + private Rectangle GetGroupPanelCaptionBounds(Rectangle r) + { + eLayoutPosition textPosition = TextPosition; + eTextAlignment textAlignment = TextAlignment; + Size imageSize = GetImageSize(); + if (!imageSize.IsEmpty) imageSize.Width += this.ImageTextSpacing; + int captionWidth = this.RealTextSize.Width + TextPadding.Horizontal + imageSize.Width; + if (textPosition == eLayoutPosition.Top || textPosition == eLayoutPosition.Bottom) + { + if (textAlignment == eTextAlignment.Left || textAlignment == eTextAlignment.Default) + { + r.Width = captionWidth; + r.X += CaptionEdgeDistance; + } + else if (textAlignment == eTextAlignment.Right) + { + r.X = r.Right - (captionWidth) - CaptionEdgeDistance; + r.Width = captionWidth; + } + else if (textAlignment == eTextAlignment.Center) + { + r.X += (r.Width - captionWidth) / 2; + r.Width = captionWidth; + } + } + else // Left/Right + { + if (textAlignment == eTextAlignment.Left || textAlignment == eTextAlignment.Default) + { + r.Y = r.Bottom - captionWidth - CaptionEdgeDistance; + r.Height = captionWidth; + + } + else if (textAlignment == eTextAlignment.Right) + { + r.Height = captionWidth; + r.Y += CaptionEdgeDistance; + } + else if (textAlignment == eTextAlignment.Center) + { + r.Y += (r.Height - captionWidth) / 2; + r.Height = captionWidth; + } + } + + return r; + } + + /// + /// Paints the background of the item. + /// + /// + protected override void OnPaintBackground(PaintContext context) + { + if (_Appearance == eGroupAppearance.Panel) + PaintPanelBackground(context); + else if (_Appearance == eGroupAppearance.GroupPanel) + PaintGroupPanelBackground(context); + else + base.OnPaintBackground(context); + } + + private void PaintPanelBackground(PaintContext context) + { + Rectangle bounds = this.Bounds; + if (!this.Style.Margin.IsEmpty) + bounds = Helpers.Deflate(bounds, this.Style.Margin); + Graphics g = context.Graphics; + DevComponents.DotNetBar.Rendering.Office2007ColorTable table = ((DevComponents.DotNetBar.Rendering.Office2007Renderer)DevComponents.DotNetBar.Rendering.GlobalManager.Renderer).ColorTable; + + Color border = table.LegacyColors.PanelBorder; + Color back1 = table.LegacyColors.PanelBackground; + Color back2 = table.LegacyColors.PanelBackground2; + int backAngle = table.LegacyColors.PanelBackgroundGradientAngle; + + PaintRectangle(bounds, g, border, back1, back2, backAngle); + } + private static void PaintRectangle(Rectangle bounds, Graphics g, Color border, Color back1, Color back2, int backAngle) + { + if (bounds.Width <= 0 || bounds.Height <= 0) + return; + + if (back2.IsEmpty) + { + if (!back1.IsEmpty) + { + using (SolidBrush brush = new SolidBrush(back1)) + g.FillRectangle(brush, bounds); + } + } + else + { + using (System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(bounds, back1, back2, backAngle)) + g.FillRectangle(brush, bounds); + } + if (!border.IsEmpty) + { + Rectangle borderBounds = bounds; + borderBounds.Width--; borderBounds.Height--; + using (Pen pen = new Pen(border)) + g.DrawRectangle(pen, borderBounds); + } + } + private ElementStyle _GroupPanelStyle = null; + private void PaintGroupPanelBackground(PaintContext context) + { + InitializeGroupPanelStyle(); + DevComponents.DotNetBar.Rendering.Office2007ColorTable table = ((DevComponents.DotNetBar.Rendering.Office2007Renderer)DevComponents.DotNetBar.Rendering.GlobalManager.Renderer).ColorTable; + _GroupPanelStyle.SetColorScheme(table.LegacyColors); + Rectangle bounds = this.Bounds; + if (!_CaptionBounds.IsEmpty) + { + eLayoutPosition tp = this.TextPosition; + if (tp == eLayoutPosition.Top) + { + bounds.Y += _CaptionBounds.Height / 2; + bounds.Height -= _CaptionBounds.Height / 2; + } + else if (tp == eLayoutPosition.Bottom) + bounds.Height -= _CaptionBounds.Height / 2; + else if (tp == eLayoutPosition.Left || tp == eLayoutPosition.Default) + { + bounds.X += _CaptionBounds.Width / 2; + bounds.Width -= _CaptionBounds.Width / 2; + } + else // Right + bounds.Width -= _CaptionBounds.Width / 2; + } + if (!this.Style.Margin.IsEmpty) + bounds = Helpers.Deflate(bounds, this.Style.Margin); + Graphics g = context.Graphics; + ElementStyleDisplayInfo info = new ElementStyleDisplayInfo(_GroupPanelStyle, g, bounds); + ElementStyleDisplay.Paint(info); + } + private void InitializeGroupPanelStyle() + { + if (_GroupPanelStyle != null) return; + _GroupPanelStyle = new ElementStyle(); + _GroupPanelStyle.BackColorSchemePart = eColorSchemePart.PanelBackground; + _GroupPanelStyle.BackColor2SchemePart = eColorSchemePart.PanelBackground2; + _GroupPanelStyle.BorderColorSchemePart = eColorSchemePart.PanelBorder; + _GroupPanelStyle.BackColorGradientAngle = 90; + _GroupPanelStyle.CornerDiameter = 4; + _GroupPanelStyle.BorderWidth = 1; + _GroupPanelStyle.Border = DevComponents.DotNetBar.eStyleBorderType.Solid; + _GroupPanelStyle.CornerType = DevComponents.DotNetBar.eCornerType.Rounded; + _GroupPanelStyle.TextColorSchemePart = eColorSchemePart.PanelText; + } + protected override void OnUpdateLayout() + { + base.OnUpdateLayout(); + } + + private Rectangle _ContentBounds = Rectangle.Empty; + private ItemLayout _Layout = new ItemLayout(); + /// + /// Performs group layout. + /// + /// Layout context information. + public void Layout(LayoutContext context) + { + Rectangle r = this.Bounds; + + // Calculate text-position + r = LayoutGroupCaption(context, r); + + if (!_IsRootGroup) + r = Helpers.Deflate(r, this.Padding); + _ContentBounds = r; + _Layout.Layout(this, r, context); + } + + private int _CaptionHeight = 0; + /// + /// Indicates explicit caption height in pixels. + /// + [DefaultValue(0), Category("Appearance"), Description("Indicates caption height in pixels.")] + public int CaptionHeight + { + get { return _CaptionHeight; } + set + { + if (value != _CaptionHeight) + { + int oldValue = _CaptionHeight; + _CaptionHeight = value; + OnCaptionHeightChanged(oldValue, value); + } + } + } + /// + /// Called when CaptionHeight property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnCaptionHeightChanged(int oldValue, int newValue) + { + this.InvalidateLayout(); + OnPropertyChanged(new PropertyChangedEventArgs("CaptionHeight")); + } + + protected override Font GetTextFont(Font defaultFont) + { + Font font = defaultFont; + if (_CaptionStyle.Font != null) + font = _CaptionStyle.Font; + return font; + } + /// + /// Updates the layout of the text inside of item. + /// + protected override void UpdateTextBounds() + { + if (_CaptionBounds.IsEmpty) return; + + Rectangle actualTextBounds = Helpers.Deflate(_CaptionBounds, this.TextPadding); + Rectangle actualImageBounds = Rectangle.Empty; + bool isImageVisible = IsImageVisible; + Size imageSize = Size.Empty; + if (isImageVisible) + imageSize = GetImageSize(); + + eTextAlignment textAlignment = this.TextAlignment; + Size realTextSize = this.RealTextSize; + + if (isImageVisible) + { + eLayoutPosition imagePosition = ImagePosition; + int imageTextSpacing = ImageTextSpacing; + + if (TextPosition == eLayoutPosition.Top || TextPosition == eLayoutPosition.Bottom) + { + if (imagePosition == eLayoutPosition.Default || imagePosition == eLayoutPosition.Right) + { + if (textAlignment == eTextAlignment.Right) + actualImageBounds = new Rectangle(actualTextBounds.Right - imageSize.Width - imageTextSpacing, actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else if (textAlignment == eTextAlignment.Center) + { + if (Appearance == eGroupAppearance.GroupPanel) + { + actualImageBounds = new Rectangle(actualTextBounds.Right - (imageSize.Width + CaptionEdgeDistance), actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + actualTextBounds.Width = realTextSize.Width; + } + else + actualImageBounds = new Rectangle(actualTextBounds.X + actualTextBounds.Width / 2 + realTextSize.Width / 2 + this.ImageTextSpacing, actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + } + else + { + actualImageBounds = new Rectangle(actualTextBounds.X + imageTextSpacing + realTextSize.Width, actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + if (Appearance == eGroupAppearance.GroupPanel) + actualImageBounds.X -= CaptionEdgeDistance; + } + } + else if (imagePosition == eLayoutPosition.Left) + { + if (textAlignment == eTextAlignment.Right) + { + actualImageBounds = new Rectangle(actualTextBounds.Right - (realTextSize.Width + imageSize.Width + imageTextSpacing), actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + if (Appearance == eGroupAppearance.GroupPanel) + actualImageBounds.X += CaptionEdgeDistance; + } + else if (textAlignment == eTextAlignment.Center) + { + if (Appearance == eGroupAppearance.GroupPanel) + { + actualImageBounds = new Rectangle(actualTextBounds.X + CaptionEdgeDistance, actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + actualTextBounds.X = actualImageBounds.Right; + actualTextBounds.Width = realTextSize.Width; + } + else + actualImageBounds = new Rectangle(actualTextBounds.X + actualTextBounds.Width / 2 - (realTextSize.Width / 2 + this.ImageTextSpacing + imageSize.Width), actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + } + else + { + actualImageBounds = new Rectangle(actualTextBounds.X, actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + actualTextBounds.X += actualImageBounds.Width + imageTextSpacing; + actualTextBounds.Width -= actualImageBounds.Width + imageTextSpacing; + } + } + else if (imagePosition == eLayoutPosition.Top) + { + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, + actualTextBounds.Y - (imageSize.Height + imageTextSpacing), + imageSize.Width, + imageSize.Height); + } + else if (imagePosition == eLayoutPosition.Bottom) + { + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, + actualTextBounds.Bottom + imageTextSpacing, + imageSize.Width, + imageSize.Height); + } + } + else + { + if (imagePosition == eLayoutPosition.Default || imagePosition == eLayoutPosition.Right) + { + if (textAlignment == eTextAlignment.Right) + { + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, actualTextBounds.Y + imageTextSpacing, imageSize.Width, imageSize.Height); + actualTextBounds.Y += imageTextSpacing; + actualImageBounds.Height -= imageTextSpacing; + if (Appearance == eGroupAppearance.GroupPanel) + { + actualTextBounds.Y = actualImageBounds.Bottom - 10; + actualTextBounds.Height = (_CaptionBounds.Bottom - actualTextBounds.Y)+4; + } + } + else if (textAlignment == eTextAlignment.Center) + { + if (Appearance == eGroupAppearance.GroupPanel) + { + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, actualTextBounds.Y + CaptionEdgeDistance, imageSize.Width, imageSize.Height); + actualTextBounds.Y = actualImageBounds.Bottom; + actualTextBounds.Height = _CaptionBounds.Bottom - actualTextBounds.Y; + } + else + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, actualTextBounds.Y + actualTextBounds.Height / 2 - (realTextSize.Width / 2 + imageTextSpacing + imageSize.Height), imageSize.Width, imageSize.Height); + } + else + { + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, actualTextBounds.Bottom - (realTextSize.Width + imageTextSpacing + imageSize.Height), imageSize.Width, imageSize.Height); + if (Appearance == eGroupAppearance.GroupPanel) + actualImageBounds.Y += CaptionEdgeDistance; + } + } + else if (imagePosition == eLayoutPosition.Left) + { + if (textAlignment == eTextAlignment.Right) + { + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, actualTextBounds.Y + imageTextSpacing, imageSize.Width, imageSize.Height); + actualTextBounds.Y += imageTextSpacing; + actualImageBounds.Height -= imageTextSpacing; + if (Appearance == eGroupAppearance.GroupPanel) + { + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, actualTextBounds.Bottom - (CaptionEdgeDistance+imageSize.Width), imageSize.Width, imageSize.Height); + actualTextBounds.Height = actualImageBounds.Y - _CaptionBounds.Y; + } + } + else if (textAlignment == eTextAlignment.Center) + { + if (Appearance == eGroupAppearance.GroupPanel) + { + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, actualTextBounds.Bottom - (imageSize.Height + CaptionEdgeDistance), imageSize.Width, imageSize.Height); + actualTextBounds.Height -= realTextSize.Height; + } + else + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, actualTextBounds.Y + actualTextBounds.Height / 2 + realTextSize.Width / 2 + this.ImageTextSpacing, imageSize.Width, imageSize.Height); + } + else + { + actualImageBounds = new Rectangle(actualTextBounds.X + (actualTextBounds.Width - imageSize.Width) / 2, actualTextBounds.Bottom - imageSize.Height - imageTextSpacing, imageSize.Width, imageSize.Height); + actualTextBounds.Height -= actualImageBounds.Height + imageTextSpacing; + } + } + else if (imagePosition == eLayoutPosition.Top) + { + actualImageBounds = new Rectangle(actualTextBounds.X + imageTextSpacing, + actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, + imageSize.Width, + imageSize.Height); + actualTextBounds.X += imageSize.Width + imageTextSpacing; + actualTextBounds.Width -= imageSize.Width + imageTextSpacing; + } + else if (imagePosition == eLayoutPosition.Bottom) + { + actualImageBounds = new Rectangle(actualTextBounds.Right - (imageSize.Width + imageTextSpacing), + actualTextBounds.Y + (actualTextBounds.Height - imageSize.Height) / 2, + imageSize.Width, + imageSize.Height); + actualTextBounds.Width -= imageSize.Width + imageTextSpacing; + } + } + } + + this.ActualTextBounds = actualTextBounds; + this.ActualImageBounds = actualImageBounds; + } + private Rectangle _CaptionBounds = Rectangle.Empty; + protected virtual Rectangle LayoutGroupCaption(LayoutContext context, Rectangle r) + { + _CaptionBounds = Rectangle.Empty; + if (string.IsNullOrEmpty(this.Text) || !this.TextVisible) + return r; + + eLayoutPosition textPosition = this.TextPosition; + + Size textSize = new Size(); + if (_CaptionHeight > 0) + { + textSize.Width = r.Width; + textSize.Height = _CaptionHeight; + } + else + { + textSize = MeasureText(context); + if (IsImageVisible) + { + Size imageSize = GetImageSize(); + textSize.Height = Math.Max(textSize.Height, imageSize.Height); + } + } + + if (textPosition == eLayoutPosition.Top) + { + _CaptionBounds = new Rectangle(r.X, r.Y, r.Width, textSize.Height); + r.Y += _CaptionBounds.Height; + r.Height -= _CaptionBounds.Height; + } + else if (textPosition == eLayoutPosition.Bottom) + { + _CaptionBounds = new Rectangle(r.X, r.Bottom - textSize.Height, r.Width, textSize.Height); + r.Height -= _CaptionBounds.Height; + } + else if (textPosition == eLayoutPosition.Left || textPosition == eLayoutPosition.Default) // Text rotated to the side + { + _CaptionBounds = new Rectangle(r.X, r.Y, textSize.Height, r.Height); + r.X += _CaptionBounds.Width; + r.Width -= _CaptionBounds.Width; + } + else if (textPosition == eLayoutPosition.Right) // Text rotated to the side + { + _CaptionBounds = new Rectangle(r.Right - textSize.Height, r.Y, textSize.Height, r.Height); + r.Width -= _CaptionBounds.Width; + } + + if (Appearance == eGroupAppearance.GroupPanel) + _CaptionBounds = GetGroupPanelCaptionBounds(_CaptionBounds); + + UpdateTextBounds(); + + //if (Appearance == eGroupAppearance.GroupPanel && !ActualImageBounds.IsEmpty) + //{ + // if (textPosition == eLayoutPosition.Top || textPosition == eLayoutPosition.Bottom || textPosition == eLayoutPosition.Default) + // { + // if (TextAlignment != eTextAlignment.Center) + // ActualImageBounds = new Rectangle(ActualImageBounds.X + CaptionEdgeDistance, ActualImageBounds.Y, ActualImageBounds.Width, ActualImageBounds.Height); + // } + // else + // { + // ActualImageBounds = new Rectangle(ActualImageBounds.X, ActualImageBounds.Y + CaptionEdgeDistance, ActualImageBounds.Width, ActualImageBounds.Height); + // } + //} + + return r; + } + + private LayoutItemCollection _Items = null; + /// + /// Gets the collection of layout items objects assigned to the current group. + /// + [Browsable(true), Category("Items"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public LayoutItemCollection Items + { + get + { + return _Items; + } + } + + //private eLayoutType _LayoutType = eLayoutType.Horizontal; + ///// + ///// Indicates layout type performed by the group. + ///// + //[DefaultValue(eLayoutType.Horizontal), Category("Appearance"), Description("Indicates layout type performed by the group.")] + //public eLayoutType LayoutType + //{ + // get { return _LayoutType; } + // set + // { + // if (value != _LayoutType) + // { + // eLayoutType oldValue = _LayoutType; + // _LayoutType = value; + // OnLayoutTypeChanged(oldValue, value); + // } + // } + //} + ///// + ///// Called when LayoutType property has changed. + ///// + ///// Old property value + ///// New property value + //protected virtual void OnLayoutTypeChanged(eLayoutType oldValue, eLayoutType newValue) + //{ + // OnPropertyChanged(new PropertyChangedEventArgs("LayoutType")); + //} + internal override void UpdateScrollBounds(int xScroll, int yScroll, bool moveControls) + { + base.UpdateScrollBounds(xScroll, yScroll, moveControls); + _ActualBounds.Offset(xScroll, yScroll); + _CaptionBounds.Offset(xScroll, yScroll); + _ContentBounds.Offset(xScroll, yScroll); + foreach (LayoutItemBase item in this.Items) + { + item.UpdateScrollBounds(xScroll, yScroll, moveControls); + } + } + + private bool _IsRootGroup = false; + /// + /// Indicates whether group is used as a root group in LayoutControl. + /// + [Browsable(false)] + public bool IsRootGroup + { + get { return _IsRootGroup; } + internal set + { + if (_IsRootGroup == value) + return; + _IsRootGroup = value; + OnPropertyChanged(new PropertyChangedEventArgs("IsRootGroup")); + } + } + + private SimpleStyle _CaptionStyle; + /// + /// Gets the style for the group caption represented by Text property. + /// + [Browsable(true), Category("Appearance"), Description("Gets the style for the group caption represented by Text property"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SimpleStyle CaptionStyle + { + get { return _CaptionStyle; } + } + private void CaptionStylePropertyChanged(object sender, PropertyChangedEventArgs e) + { + this.Invalidate(); + //throw new Exception("The method or operation is not implemented."); + } + /// + /// Returns whether item is contained as child item by this item or one of its children. + /// + /// Item to check. + /// true if item is contained otherwise false + public override bool IsChildItem(LayoutItemBase value) + { + foreach (LayoutItemBase item in _Items) + { + if (item == value) return true; + if (item.IsChildItem(value)) return true; + } + return false; + } + + private eGroupAppearance _Appearance = eGroupAppearance.None; + /// + /// Indicates the built-in appearance of group. When set group is painted using one of the pre-defined styles. + /// When set to None, default value, you can use Style and CaptionStyle properties to change the group appearance. + /// + [DefaultValue(eGroupAppearance.None), Category("Appearance"), Description("Indicates the built-in appearance of group.")] + public eGroupAppearance Appearance + { + get { return _Appearance; } + set + { + if (value != _Appearance) + { + eGroupAppearance oldValue = _Appearance; + _Appearance = value; + OnAppearanceChanged(oldValue, value); + } + } + } + /// + /// Called when Appearance property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnAppearanceChanged(eGroupAppearance oldValue, eGroupAppearance newValue) + { + this.Invalidate(); + this.InvalidateLayout(); + OnPropertyChanged(new PropertyChangedEventArgs("Appearance")); + } + + /// + /// Scales item in response to the scaling of the LayoutControl. Should never be called directly. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void ScaleItem(SizeF factor) + { + base.ScaleItem(factor); + if (_CaptionHeight > 0) + { + bool widthChanged = factor.Width != 1f; + bool heightChanged = factor.Height != 1f; + + if (heightChanged) + { + _CaptionHeight = (int)(_CaptionHeight * factor.Height); + } + } + } + + /// + /// Gets whether this item text-size is shared with other items inside of its parent group. + /// + [Browsable(false)] + public override bool IsTextSizeShared + { + get + { + return false; + } + } + /// + /// Gets whether this item's text-baseline is shared with other items inside of its parent group. + /// + [Browsable(false)] + public override bool IsTextBaselineShared + { + get + { + return false; + } + } + + protected override void OnVisibleChanged(bool oldValue, bool newValue) + { + foreach (LayoutItemBase item in _Items) + { + item.Visible = newValue; + } + base.OnVisibleChanged(oldValue, newValue); + } + #endregion + } + + /// + /// Specifies the layout type. + /// + public enum eLayoutType + { + /// + /// Horizontal layout type where items are first ordered from left to right then wrapped to next line. + /// + Horizontal, + /// + /// Vertical layout type where items are ordered first from top to bottom then wrapped onto the next column. + /// + Vertical + } + + /// + /// Specifies built-in appearance for the LayoutGroup. + /// + public enum eGroupAppearance + { + /// + /// Group does not use any built-in appearance. + /// + None, + /// + /// Group is rendered like standard DotNetBar Panel control. + /// + Panel, + /// + /// Group is rendered like GroupPanel control. + /// + GroupPanel + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutItemBase.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutItemBase.cs new file mode 100644 index 00000000..8d401398 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutItemBase.cs @@ -0,0 +1,2158 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Layout +{ + /// + /// Represents the base item for layout control. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [Designer("DevComponents.DotNetBar.Layout.Design.LayoutItemBaseDesigner, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04")] + public class LayoutItemBase : IComponent, IDisposable, INotifyPropertyChanged + { + #region Constructor + /// + /// Initializes a new instance of the LayoutItemBase class. + /// + public LayoutItemBase() + { + _Style = new SimpleStyle(); + _Style.PropertyChanged += StylePropertyChanged; + } + #endregion + + #region Implementation + /// + /// Paints the item. Actual code doing painting goes into the OnPaint method which should be overridden. + /// + /// Provides Paint Context. + internal void Paint(PaintContext context) + { + OnPaint(context); + } + /// + /// Paints the background of the item. + /// + /// + protected virtual void OnPaintBackground(PaintContext context) + { + Rectangle bounds = _Bounds; + Graphics g = context.Graphics; + + if (_Style.IsPainted) + { + DrawingHelpers.PaintStyle(g, _Style, bounds); + } + } + protected virtual void PaintText(PaintContext context, bool isImageVisible, Color textColor, Rectangle textBounds, Brush textBrush) + { + Graphics g = context.Graphics; + eTextAlignment textAlign = _TextAlignment; + if (textAlign == eTextAlignment.Default) + textAlign = context.TextAlignment; + using (StringFormat format = new StringFormat()) + { + if (textAlign == eTextAlignment.Right) + { + if (isImageVisible && (_ImagePosition == eLayoutPosition.Right || _ImagePosition == eLayoutPosition.Default)) + textBounds.Width -= _ActualImageBounds.Width + _ImageTextSpacing; + format.Alignment = StringAlignment.Far; + } + else if (textAlign == eTextAlignment.Center) + format.Alignment = StringAlignment.Center; + if (_TextLineAlignment == eTextLineAlignment.Middle) + format.LineAlignment = StringAlignment.Center; + else if (_TextLineAlignment == eTextLineAlignment.Bottom) + format.LineAlignment = StringAlignment.Far; + format.HotkeyPrefix = context.HotkeyPrefix; + Font font = GetTextFont(context.DefaultFont); + if (_TextMarkup == null) + g.DrawString(_Text, font, textBrush, textBounds, format); + else + { + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, textColor, false); + d.HotKeyPrefixVisible = (context.HotkeyPrefix == System.Drawing.Text.HotkeyPrefix.Show); + Rectangle mr = new Rectangle(textBounds.X, textBounds.Y, _TextMarkup.Bounds.Width, _TextMarkup.Bounds.Height); + _TextMarkup.Bounds = mr; + _TextMarkup.Render(d); + } + } + } + protected virtual void PaintImage(PaintContext context, Color textColor) + { + Graphics g = context.Graphics; + if (!string.IsNullOrEmpty(_Symbol)) + { + Font font = _SymbolSize > 0 ? Symbols.GetFontAwesome(_SymbolSize) : Symbols.FontAwesome; + TextDrawing.DrawStringLegacy(g, _Symbol, font, + (_SymbolColor.IsEmpty ? textColor : _SymbolColor), + new Rectangle(_ActualImageBounds.Location, Size.Empty), + eTextFormat.Default); + } + else + g.DrawImage(_Image, _ActualImageBounds); + } + /// + /// Actual painting implementation. + /// + /// + protected virtual void OnPaint(PaintContext context) + { + Rectangle bounds = _Bounds; + Graphics g = context.Graphics; + + OnPaintBackground(context); + + bounds = Helpers.Deflate(bounds, _Padding); + bool isImageVisible = IsImageVisible; + Color textColor = context.LabelTextColor; + + if (_TextVisible && !string.IsNullOrEmpty(_Text)) + { + Rectangle textBounds = _ActualTextBounds; + if (_StripTextBaseline > 0 && UseStripBaseline) + textBounds = new Rectangle(textBounds.X, + textBounds.Y + (_StripTextBaseline - _TextBaseline), + textBounds.Width, + textBounds.Height); + + bool dispose = false; + Brush textBrush = context.LabelTextBrush; + + if (this.IsKeyboardFocusWithin && context.FocusStyle != null && !context.FocusStyle.TextColor.IsEmpty) + { + textColor = context.FocusStyle.TextColor; + textBrush = new SolidBrush(textColor); + dispose = true; + } + else if (!_Style.TextColor.IsEmpty) + { + textColor = _Style.TextColor; + textBrush = new SolidBrush(textColor); + dispose = true; + } + + PaintText(context,isImageVisible, textColor, textBounds, textBrush); + + if (dispose) + textBrush.Dispose(); + } + + + if (isImageVisible) + { + PaintImage(context, textColor); + } + + if (_IsSelected) + OnPaintSelection(context); + } + /// + /// Returns whether strip text base line value is used when calculating position of the rendered text label. + /// + protected bool UseStripBaseline + { + get + { + return TextBaseLineEnabled && TextPosition == eLayoutPosition.Default && (!IsImageVisible || IsImageVisible && (_ImagePosition == eLayoutPosition.Default || _ImagePosition == eLayoutPosition.Left || _ImagePosition == eLayoutPosition.Right)); + } + } + + private bool _TextBaseLineEnabled = true; + /// + /// Indicates whether shared text baseline between items is enabled so the text-base aligns. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether shared text baseline between items is enabled so the text-base aligns.")] + public bool TextBaseLineEnabled + { + get { return _TextBaseLineEnabled; } + set + { + if (value != _TextBaseLineEnabled) + { + bool oldValue = _TextBaseLineEnabled; + _TextBaseLineEnabled = value; + OnTextBaseLineEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when TextBaseLineEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextBaseLineEnabledChanged(bool oldValue, bool newValue) + { + UpdateTextBounds(); + this.Invalidate(); + OnPropertyChanged(new PropertyChangedEventArgs("TextBaseLineEnabled")); + } + + + private static readonly Color SelectionColor = ColorHelpers.GetColor(0x696969); + /// + /// Paints the selection adorner around the item. + /// + /// + protected virtual void OnPaintSelection(PaintContext context) + { + if (this.DesignMode) return; + Rectangle r = _Bounds; + r.Width--; + r.Height--; + Graphics g = context.Graphics; + using (Pen pen = new Pen(SelectionColor)) + { + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; + g.DrawRectangle(pen, r); + } + } + + /// + /// Updates bounds of the item in response to the scrolling of LayoutControl. + /// + /// + /// + internal virtual void UpdateScrollBounds(int xScroll, int yScroll, bool moveControls) + { + _Bounds.Offset(xScroll, yScroll); + if (!_ActualTextBounds.IsEmpty) + _ActualTextBounds.Offset(xScroll, yScroll); + if(!_ActualImageBounds.IsEmpty) + _ActualImageBounds.Offset(xScroll, yScroll); + } + + private Rectangle _Bounds; + /// + /// Gets the bounds of the item. + /// + [Browsable(false)] + public virtual Rectangle Bounds + { + get + { + return _Bounds; + } + } + /// + /// Processes accelerator key for the item. + /// + /// + internal virtual bool ProcessMnemonic(char charCode) + { + return false; + } + + /// + /// Sets new bounds of the item. + /// + /// New bounds. + public virtual void SetBounds(Rectangle r) + { + _Bounds = r; + UpdateLayout(); + } + /// + /// Sets new bounds of the item and actual text size. + /// + /// + /// + public virtual void SetBounds(Rectangle r, Size actualTextSize) + { + _Bounds = r; + ActualTextSize = actualTextSize; + UpdateLayout(); + } + /// + /// Updates the item layout. Actual layout is performed in OnUpdateLayout method. + /// + internal void UpdateLayout() + { + OnUpdateLayout(); + } + /// + /// Actual layout update implementation. + /// + protected virtual void OnUpdateLayout() + { + UpdateTextBounds(); + } + /// + /// Updates the layout of the text inside of item. + /// + protected virtual void UpdateTextBounds() + { + Rectangle bounds = Helpers.Deflate(_Bounds, _Padding); + _ActualTextBounds = Helpers.Deflate(bounds, _TextPadding); + _ActualImageBounds = Rectangle.Empty; + bool isImageVisible = IsImageVisible; + Size imageSize = Size.Empty; + if (isImageVisible) + imageSize = GetImageSize(); + + eTextAlignment textAlignment = _TextAlignment; + if (textAlignment == eTextAlignment.Default) + { + LayoutControl lc = GetLayoutControl(); + if (lc != null) + textAlignment = lc.LabelTextAlignment; + } + + if (_TextPosition == eLayoutPosition.Default || _TextPosition == eLayoutPosition.Left || + _TextPosition == eLayoutPosition.Right) + { + if (_TextLineAlignment == eTextLineAlignment.Middle) + _ActualTextBounds.Y += (_ActualTextBounds.Height - _ActualTextSize.Height) / 2; + else if (_TextLineAlignment == eTextLineAlignment.Bottom) + _ActualTextBounds.Y = _ActualTextBounds.Bottom - _ActualTextSize.Height; + } + + if (_TextPosition == eLayoutPosition.Default || _TextPosition == eLayoutPosition.Left || _TextPosition == eLayoutPosition.Top) + { + _ActualTextBounds.Size = _ActualTextSize; + } + else if (_TextPosition == eLayoutPosition.Bottom) + { + _ActualTextBounds.Y = _ActualTextBounds.Bottom - _ActualTextSize.Height; + _ActualTextBounds.Size = _ActualTextSize; + } + else if (_TextPosition == eLayoutPosition.Right) + { + _ActualTextBounds.X = _ActualTextBounds.Right - _ActualTextSize.Width; + _ActualTextBounds.Size = _ActualTextSize; + } + else if (_TextPosition == eLayoutPosition.Top) + { + _ActualTextBounds.Y = _ActualTextBounds.Bottom - _ActualTextSize.Height; + _ActualTextBounds.Size = _ActualTextSize; + } + + if (isImageVisible) + { + if (_ImagePosition == eLayoutPosition.Default || _ImagePosition == eLayoutPosition.Right) + { + if (textAlignment == eTextAlignment.Right) + _ActualImageBounds = new Rectangle(_ActualTextBounds.Right - imageSize.Width, _ActualTextBounds.Y + (-_ActualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else + _ActualImageBounds = new Rectangle(_ActualTextBounds.X + _ImageTextSpacing + _RealTextSize.Width, _ActualTextBounds.Y + (_ActualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + } + else if (_ImagePosition == eLayoutPosition.Left) + { + if (textAlignment == eTextAlignment.Right) + _ActualImageBounds = new Rectangle(_ActualTextBounds.Right - (_RealTextSize.Width + imageSize.Width + _ImageTextSpacing), _ActualTextBounds.Y + (_ActualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + else + { + _ActualImageBounds = new Rectangle(_ActualTextBounds.X, _ActualTextBounds.Y + (_ActualTextBounds.Height - imageSize.Height) / 2, imageSize.Width, imageSize.Height); + _ActualTextBounds.X += _ActualImageBounds.Width + _ImageTextSpacing; + } + } + else if (_ImagePosition == eLayoutPosition.Top) + { + _ActualImageBounds = new Rectangle(_ActualTextBounds.X + (_ActualTextBounds.Width - imageSize.Width) / 2, + _ActualTextBounds.Y - (imageSize.Height + _ImageTextSpacing), + imageSize.Width, + imageSize.Height); + } + else if (_ImagePosition == eLayoutPosition.Bottom) + { + _ActualImageBounds = new Rectangle(_ActualTextBounds.X + (_ActualTextBounds.Width - imageSize.Width) / 2, + _ActualTextBounds.Bottom + _ImageTextSpacing, + imageSize.Width, + imageSize.Height); + } + } + } + protected virtual Size GetImageSize() + { + if (!string.IsNullOrEmpty(_Symbol)) + return _SymbolTextSize; + if (_Image != null) + return _Image.Size; + return Size.Empty; + } + protected bool IsImageVisible + { + get + { + return _Image != null || !string.IsNullOrEmpty(_Symbol); + } + } + /// + /// Scales item in response to the scaling of the LayoutControl. Should never be called directly. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual void ScaleItem(SizeF factor) + { + bool widthChanged = factor.Width != 1f; + bool heightChanged = factor.Height != 1f; + + if (!_MinSize.IsEmpty && (widthChanged || heightChanged)) + { + Size newMinSize = new Size(); + if (widthChanged) + newMinSize.Width = (int)(_MinSize.Width * factor.Width); + else + newMinSize.Width = _MinSize.Width; + if (heightChanged) + newMinSize.Height = (int)(_MinSize.Height * factor.Height); + else + newMinSize.Height = _MinSize.Height; + MinSize = newMinSize; + } + + if (widthChanged && _WidthType == eLayoutSizeType.Absolute) + { + int newWidth = (int)Math.Round(_Width * factor.Width); + + if (_MinSize.Width > newWidth) + newWidth = _MinSize.Width; + + this.Width = newWidth; + } + if (heightChanged && _HeightType == eLayoutSizeType.Absolute) + { + int newHeight = (int)Math.Round(_Height * factor.Height); + + if (_MinSize.Height > newHeight) + newHeight = _MinSize.Height; + + this.Height = newHeight; + } + + if (!_TextSize.IsEmpty && (widthChanged || heightChanged)) + { + Size newTextSize = new Size(); + if (widthChanged) + newTextSize.Width = (int)(_TextSize.Width * factor.Width); + else + newTextSize.Width = _TextSize.Width; + if (heightChanged) + newTextSize.Height = (int)(_TextSize.Height * factor.Height); + else + newTextSize.Height = _TextSize.Height; + TextSize = newTextSize; + } + + if (!Helpers.IsEmpty(_TextPadding) && (widthChanged || heightChanged)) + { + System.Windows.Forms.Padding newTextPadding = _TextPadding; + if (widthChanged) + { + newTextPadding.Left = (int)(_TextPadding.Left * factor.Width); + newTextPadding.Right = (int)(_TextPadding.Right * factor.Width); + } + if (heightChanged) + { + newTextPadding.Top = (int)(_TextPadding.Top * factor.Height); + newTextPadding.Bottom = (int)(_TextPadding.Bottom * factor.Height); + } + TextPadding = newTextPadding; + } + + if (!Helpers.IsEmpty(_Padding) && (widthChanged || heightChanged)) + { + System.Windows.Forms.Padding newPadding = _Padding; + if (widthChanged) + { + newPadding.Left = (int)(_Padding.Left * factor.Width); + newPadding.Right = (int)(_Padding.Right * factor.Width); + } + if (heightChanged) + { + newPadding.Top = (int)(_Padding.Top * factor.Height); + newPadding.Bottom = (int)(_Padding.Bottom * factor.Height); + } + Padding = newPadding; + } + } + + /// + /// Measures the size of the item text. Actual measurement is done in OnMeasureText method. + /// + /// + /// + internal Size MeasureText(LayoutContext c) + { + return OnMeasureText(c); + } + + protected virtual Font GetTextFont(Font defaultFont) + { + Font font = defaultFont; + if (_Style.Font != null) + font = _Style.Font; + return font; + } + /// + /// Returns the size of the items text. + /// + /// + /// + protected virtual Size OnMeasureText(LayoutContext c) + { + if (!_TextVisible) return Size.Empty; + + if (_TextSize.Width > 0 && _TextSize.Height > 0) + return _TextSize; + + Size size = Size.Empty; + Graphics g = c.Graphics; + + Font font = GetTextFont(c.Font); + + if (_TextMarkup == null) + { // Plain Text + if (_TextSize.Width > 0) + { + size = Size.Ceiling(g.MeasureString(_Text, font, _TextSize.Width)); + } + else + { + size = Size.Ceiling(g.MeasureString(_Text, font)); + } + } + else + { + // Text Markup + Size availSize = new Size(_TextSize.Width > 0 ? _TextSize.Width : 1600, 1); + TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, Color.Empty, false); + _TextMarkup.InvalidateElementsSize(); + _TextMarkup.Measure(availSize, d); + availSize = _TextMarkup.Bounds.Size; + d.RightToLeft = c.RightToLeft; + _TextMarkup.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d); + + size = _TextMarkup.Bounds.Size; + } + + if (_TextSize.Height > 0) + size.Height = _TextSize.Height; + size.Width += _TextPadding.Horizontal; + size.Height += _TextPadding.Vertical; + _RealTextSize = size; + _TextBaseline = c.FontBaseline; + + if (IsImageVisible) + { + if (!string.IsNullOrEmpty(_Symbol)) + { + Font symFont = Symbols.GetFontAwesome(_SymbolSize); + + _SymbolTextSize = TextDrawing.MeasureString(g, _Symbol, symFont); + + int descent = (int)Math.Ceiling((symFont.FontFamily.GetCellDescent(symFont.Style) * + symFont.Size / symFont.FontFamily.GetEmHeight(symFont.Style))); + _SymbolTextSize.Height -= descent; + } + else + _SymbolTextSize = Size.Empty; + if (_ImagePosition == eLayoutPosition.Default || _ImagePosition == eLayoutPosition.Left || _ImagePosition == eLayoutPosition.Right) + size.Width += _ImageTextSpacing + GetImageSize().Width; + } + + return size; + } + + private Size _RealTextSize = Size.Empty; + // + // Returns the real text-size for the text label that is valid after MeasureText is called. + // + [Browsable(false)] + public Size RealTextSize + { + get + { + return _RealTextSize; + } + } + + private int _StripTextBaseline = 0; + /// + /// Gets or sets the text-baseline that is used by whole strip. + /// + internal virtual int StripTextBaseline + { + get { return _StripTextBaseline; } + set + { + _StripTextBaseline = value; + } + } + + private int _TextBaseline = 0; + /// + /// Returns the text base line. + /// + internal virtual int TextBaseline + { + get + { + return _TextBaseline; + } + set + { + _TextBaseline = value; + } + } + + private object _Tag = ""; + /// + /// Gets or sets an object that contains additional data attached to the item. + /// + [Bindable(true), DefaultValue(""), Localizable(false), TypeConverter(typeof(StringConverter)), Description("Indicates an object that contains additional data attached to the item")] + public object Tag + { + get { return _Tag; } + set + { + if (value != _Tag) + { + object oldValue = _Tag; + _Tag = value; + OnTagChanged(oldValue, value); + } + } + } + /// + /// Called when Tag property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTagChanged(object oldValue, object newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Tag")); + } + + private string _Text = ""; + /// + /// Indicates the item caption. + /// + [Bindable(true), Category("Text"), DefaultValue(""), Localizable(true), Description("Indicates the item caption.")] + [Editor("DevComponents.DotNetBar.Layout.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04", typeof(System.Drawing.Design.UITypeEditor))] + public virtual string Text + { + get { return _Text; } + set + { + if (value != _Text) + { + string oldValue = _Text; + _Text = value; + OnTextChanged(oldValue, value); + } + } + } + /// + /// Called when Text property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Text")); + MarkupTextChanged(); + InvalidateLayout(); + } + + private Size _TextSize = Size.Empty; + /// + /// Gets or sets the explicit size of the text part of item. + /// + [Category("Appearance"), Description("Indicates explicit size of text part of the item")] + public Size TextSize + { + get { return _TextSize; } + set + { + if (value != _TextSize) + { + Size oldValue = _TextSize; + _TextSize = value; + OnTextSizeChanged(oldValue, value); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextSize() + { + return !_TextSize.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextSize() + { + TextSize = Size.Empty; + } + /// + /// Called when TextSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextSizeChanged(Size oldValue, Size newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("TextSize")); + InvalidateLayout(); + } + + private Rectangle _ActualTextBounds = Rectangle.Empty; + /// + /// Gets actual text bounds. + /// + [Browsable(false)] + public Rectangle ActualTextBounds + { + get + { + return _ActualTextBounds; + } + internal set + { + _ActualTextBounds = value; + } + } + + private Size _ActualTextSize = Size.Empty; + /// + /// Gets actual text-size as used by the layout item. + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] + public Size ActualTextSize + { + get { return _ActualTextSize; } + internal set + { + if (value != _ActualTextSize) + { + Size oldValue = _ActualTextSize; + _ActualTextSize = value; + OnActualTextSizeChanged(oldValue, value); + } + } + } + /// + /// Called when ActualTextSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnActualTextSizeChanged(Size oldValue, Size newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ActualTextSize")); + } + + private System.Windows.Forms.Padding _TextPadding = new System.Windows.Forms.Padding(0, 0, 0, 0); + /// + /// Gets or sets text padding. + /// + [Browsable(true), Category("Appearance"), Description("Gets or sets text padding.")] + public System.Windows.Forms.Padding TextPadding + { + get { return _TextPadding; } + set + { + System.Windows.Forms.Padding oldValue = value; + _TextPadding = value; + OnTextPaddingChanged(oldValue, value); + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextPadding() + { + return _TextPadding.Bottom != 0 || _TextPadding.Top != 0 || _TextPadding.Left != 0 || _TextPadding.Right != 0; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextPadding() + { + _TextPadding = new System.Windows.Forms.Padding(0, 0, 0, 0); + } + /// + /// Called when TextPadding property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextPaddingChanged(System.Windows.Forms.Padding oldValue, System.Windows.Forms.Padding newValue) + { + this.InvalidateLayout(); + this.Invalidate(); + OnPropertyChanged(new PropertyChangedEventArgs("TextPadding")); + } + + private bool _TextVisible = true; + /// + /// Indicates whether caption/text is visible. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether caption/text is visible."), Bindable(true)] + public bool TextVisible + { + get { return _TextVisible; } + set + { + if (value != _TextVisible) + { + bool oldValue = _TextVisible; + _TextVisible = value; + OnTextVisibleChanged(oldValue, value); + } + } + } + /// + /// Called when TextVisible property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextVisibleChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("TextVisible")); + InvalidateLayout(); + } + + private eLayoutPosition _TextPosition = eLayoutPosition.Default; + /// + /// Gets or sets the text position in relation to the other parts of the layout item. Default is same as Left. + /// + [DefaultValue(eLayoutPosition.Default), Category("Appearance"), Description("Indicates text position in relation to the other parts of the layout item.")] + public eLayoutPosition TextPosition + { + get { return _TextPosition; } + set + { + if (value != _TextPosition) + { + eLayoutPosition oldValue = _TextPosition; + _TextPosition = value; + OnTextPositionChanged(oldValue, value); + } + } + } + /// + /// Called when TextPosition property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextPositionChanged(eLayoutPosition oldValue, eLayoutPosition newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("TextPosition")); + InvalidateLayout(); + } + + private int _Width = 0; + /// + /// Indicates the total width of the item. The value specified here depends on the WidthType property setting. When using WidthType=Percentage the value specified here indicates the percent of the available client size of group. + /// For example setting of 20 indicates 20% of the available client width. + /// + [DefaultValue(0), Category("Appearance"), Description("Indicates the total width of the item. The value specified here depends on the WidthType property setting.")] + public int Width + { + get { return _Width; } + set + { + if (value != _Width) + { + int oldValue = _Width; + _Width = value; + OnWidthChanged(oldValue, value); + } + } + } + /// + /// Called when Width property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnWidthChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Width")); + InvalidateLayout(); + } + + private eLayoutSizeType _WidthType = eLayoutSizeType.Absolute; + /// + /// Indicates width type used by the item. + /// + [DefaultValue(eLayoutSizeType.Absolute), Category("Appearance"), Description("Indicates width type used by the item.")] + public eLayoutSizeType WidthType + { + get { return _WidthType; } + set + { + if (value != _WidthType) + { + eLayoutSizeType oldValue = _WidthType; + _WidthType = value; + OnWidthTypeChanged(oldValue, value); + } + } + } + /// + /// Called when WidthType property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnWidthTypeChanged(eLayoutSizeType oldValue, eLayoutSizeType newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("WidthType")); + InvalidateLayout(); + } + + /// + /// Indicates whether width type is the fixed width type, different than eLayoutSizeType.Percent + /// + [Browsable(false)] + public bool IsWidthFixed + { + get + { + return (_WidthType != eLayoutSizeType.Percent); + } + } + + private int _Height = 0; + /// + /// Indicates the total height of the item. The value specified here depends on the HeightType property setting. When using HeightType=Percentage the value specified here indicates the percent of the available client size of group. + /// For example setting of 10 indicates 10% of the available client height. + /// + [DefaultValue(0), Category("Appearance"), Description("Indicates the total height of the item. The value specified here depends on the HeightType property setting.")] + public int Height + { + get { return _Height; } + set + { + if (value != _Height) + { + int oldValue = _Height; + _Height = value; + OnHeightChanged(oldValue, value); + } + } + } + /// + /// Called when Height property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnHeightChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Height")); + InvalidateLayout(); + } + + private eLayoutSizeType _HeightType = eLayoutSizeType.Absolute; + /// + /// Indicates height type used by the item. + /// + [DefaultValue(eLayoutSizeType.Absolute), Category("Appearance"), Description("Indicates height type used by the item.")] + public eLayoutSizeType HeightType + { + get { return _HeightType; } + set + { + if (value != _HeightType) + { + eLayoutSizeType oldValue = _HeightType; + _HeightType = value; + OnHeightTypeChanged(oldValue, value); + } + } + } + /// + /// Called when HeightType property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnHeightTypeChanged(eLayoutSizeType oldValue, eLayoutSizeType newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("HeightType")); + InvalidateLayout(); + } + + /// + /// Indicates whether height type is the fixed height type, different than eLayoutSizeType.Percent + /// + [Browsable(false)] + public bool IsHeightFixed + { + get + { + return (_HeightType != eLayoutSizeType.Percent); + } + } + + private Size _MinSize = Size.Empty; + /// + /// Indicates the minimum size of the item. Setting Width or Height to zero indicates unconstrained minimum size for given dimension. + /// + [Description("Indicates the minimum size of the item"), Category("Appearance")] + public Size MinSize + { + get { return _MinSize; } + set + { + if (value != _MinSize) + { + Size oldValue = _MinSize; + _MinSize = value; + OnMinSizeChanged(oldValue, value); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMinSize() + { + return !_MinSize.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetMinSize() + { + MinSize = Size.Empty; + } + /// + /// Called when MinSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnMinSizeChanged(Size oldValue, Size newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("MinSize")); + InvalidateLayout(); + } + + private int _SuggestedGroupId = 0; + /// + /// When set to value greater than 0 it suggests to layout engine that items with same id that are in collection after each other should be kept on same line if possible. + /// This is only suggestion to layout engine and engine will ignore it if there is insufficient client size available or other size constraints + /// prevent it from keeping items in same line. + /// + [DefaultValue(0), Category("Behavior"), Description("When set to value greater than 0 it suggests to layout engine that items with same id that are in collection after each other should be kept on same line if possible.")] + public int SuggestedGroupId + { + get { return _SuggestedGroupId; } + set + { + if (value != _SuggestedGroupId) + { + int oldValue = _SuggestedGroupId; + _SuggestedGroupId = value; + OnSuggestedGroupIdChanged(oldValue, value); + } + } + } + /// + /// Called when SuggestedGroupId property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSuggestedGroupIdChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("SuggestedGroupId")); + + } + + private bool _MnemonicsEnabled = true; + /// + /// Indicates whether accelerator keys assigned to item Text property are processed by items which respond to them. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether accelerator keys assigned to item Text property are processed by items which respond to them.")] + public bool MnemonicsEnabled + { + get { return _MnemonicsEnabled; } + set + { + if (value != _MnemonicsEnabled) + { + bool oldValue = _MnemonicsEnabled; + _MnemonicsEnabled = value; + OnMnemonicsEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when MnemonicsEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnMnemonicsEnabledChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("MnemonicsEnabled")); + + } + + private SimpleStyle _Style; + /// + /// Gets the style for the background of the control. + /// + [Browsable(true), Category("Appearance"), Description("Gets the style for the background of the item."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public SimpleStyle Style + { + get { return _Style; } + } + private void StylePropertyChanged(object sender, PropertyChangedEventArgs e) + { + this.Invalidate(); + //throw new Exception("The method or operation is not implemented."); + } + private static readonly System.Windows.Forms.Padding DefaultPadding = new System.Windows.Forms.Padding(4); + private System.Windows.Forms.Padding _Padding = DefaultPadding; + /// + /// Specifies the amount of padding inside of the item. Padding is the spacing between the edges of item and its content. + /// + [Category("Appearance"), Description("Specifies the amount of padding inside of the item.")] + public System.Windows.Forms.Padding Padding + { + get { return _Padding; } + set + { + if (value != _Padding) + { + System.Windows.Forms.Padding oldValue = _Padding; + _Padding = value; + OnPaddingChanged(oldValue, value); + } + } + } + /// + /// Called when Padding property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnPaddingChanged(System.Windows.Forms.Padding oldValue, System.Windows.Forms.Padding newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Padding")); + InvalidateLayout(); + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializePadding() + { + return _Padding != DefaultPadding; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetPadding() + { + Padding = DefaultPadding; + } + + private int _AbsoluteIndex = -1; + /// + /// Indicates the absolute index of the item inside of the LayoutControl. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int AbsoluteIndex + { + get { return _AbsoluteIndex; } + internal set + { + if (value != _AbsoluteIndex) + { + int oldValue = _AbsoluteIndex; + _AbsoluteIndex = value; + OnAbsoluteIndexChanged(oldValue, value); + } + } + } + /// + /// Called when AbsoluteIndex property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnAbsoluteIndexChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("AbsoluteIndex")); + } + + /// + /// Returns the LayoutControl which hosts the item, if available. + /// + /// reference to LayoutControl or null. + public LayoutControl GetLayoutControl() + { + if (_LayoutControl != null) return _LayoutControl; + LayoutItemBase item = this.Parent; + while (item != null) + { + if (item.LayoutControl != null) return item.LayoutControl; + item = item.Parent; + } + return null; + } + + /// + /// Invalidates the paint region of the item. + /// + public void Invalidate() + { + LayoutControl control = GetLayoutControl(); + if (control != null) + control.Invalidate(_Bounds); + } + + /// + /// Invalidates layout of the item and causes the LayoutControl to perform layout. + /// + public void InvalidateLayout() + { + LayoutControl control = GetLayoutControl(); + if (control != null) + { + if (this.DesignMode) + control.Invalidate(true); + control.PerformLayout(); + } + } + + private LayoutControl _LayoutControl = null; + /// + /// Gets the LayoutControl this group is directly attached too through RootGroup property. + /// + [Browsable(false)] + internal LayoutControl LayoutControl + { + get + { + return _LayoutControl; + } + set + { + _LayoutControl = value; + } + } + + private LayoutItemBase _Parent = null; + /// + /// Gets the reference to parent item. + /// + [Browsable(false)] + public LayoutItemBase Parent + { + get { return _Parent; } + internal set + { + if (value != _Parent) + { + if (value == this) throw new ArgumentException("Item cannot parent itself"); + if (IsChildItem(value)) throw new ArgumentException("Cannot set as Parent item that is child of this item"); + LayoutItemBase oldValue = _Parent; + _Parent = value; + OnParentChanged(oldValue, value); + } + } + } + /// + /// Called when Parent property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnParentChanged(LayoutItemBase oldValue, LayoutItemBase newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Parent")); + + } + + /// + /// Returns whether item is contained as child item by this item or one of its children. + /// + /// Item to check. + /// true if item is contained otherwise false + public virtual bool IsChildItem(LayoutItemBase value) + { + return false; + } + + private bool _IsKeyboardFocusWithin = false; + /// + /// Gets whether keyboard focus is within the control which is assigned to the item. + /// + [Browsable(false)] + public bool IsKeyboardFocusWithin + { + get + { + return _IsKeyboardFocusWithin; + } + internal set + { + if (value != _IsKeyboardFocusWithin) + { + _IsKeyboardFocusWithin = value; + this.Invalidate(); + } + } + } + + private Image _Image = null; + /// + /// Indicates the image that is displayed next to the item text label. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the image that is displayed next to the item text label.")] + public Image Image + { + get { return _Image; } + set + { + if (value != _Image) + { + Image oldValue = _Image; + _Image = value; + OnImageChanged(oldValue, value); + } + } + } + /// + /// Called when Image property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnImageChanged(Image oldValue, Image newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Image")); + this.InvalidateLayout(); + } + + private int _ImageTextSpacing = 4; + /// + /// Specifies the distance between image and text. + /// + [DefaultValue(4), Category("Appearance"), Description("Specifies the distance between image and text.")] + public int ImageTextSpacing + { + get { return _ImageTextSpacing; } + set + { + if (value != _ImageTextSpacing) + { + int oldValue = _ImageTextSpacing; + _ImageTextSpacing = value; + OnImageTextSpacingChanged(oldValue, value); + } + } + } + /// + /// Called when ImageTextSpacing property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnImageTextSpacingChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ImageTextSpacing")); + this.InvalidateLayout(); + } + + private eLayoutPosition _ImagePosition = eLayoutPosition.Default; + /// + /// Indicates the position of the image in relation to the text label of item. + /// + [DefaultValue(eLayoutPosition.Default), Category("Appearance"), Description("Indicates the position of the image in relation to the text label of item.")] + public eLayoutPosition ImagePosition + { + get { return _ImagePosition; } + set + { + if (value != _ImagePosition) + { + eLayoutPosition oldValue = _ImagePosition; + _ImagePosition = value; + OnImagePositionChanged(oldValue, value); + } + } + } + /// + /// Called when ImagePosition property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnImagePositionChanged(eLayoutPosition oldValue, eLayoutPosition newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ImagePosition")); + this.InvalidateLayout(); + } + + private Rectangle _ActualImageBounds = Rectangle.Empty; + /// + /// Gets actual image bounds if visible or Rectangle.Empty if image is not visible. + /// + [Browsable(false)] + public Rectangle ActualImageBounds + { + get { return _ActualImageBounds; } + internal set { _ActualImageBounds = value; } + } + + private Color _SymbolColor = Color.Empty; + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return _SymbolColor; } + set { _SymbolColor = value; this.Invalidate(); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeSymbolColor() + { + return !_SymbolColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetSymbolColor() + { + this.SymbolColor = Color.Empty; + } + + private Size _SymbolTextSize = Size.Empty; + private string _Symbol = ""; + /// + /// Indicates the symbol displayed on face of the item instead of the image. Setting the symbol overrides the image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("Indicates the symbol displayed on face of the button instead of the image. Setting the symbol overrides the image setting.")] + [Editor("DevComponents.DotNetBar.Layout.Design.SymbolTypeEditor, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return _Symbol; } + set + { + if (value != _Symbol) + { + string oldValue = _Symbol; + _Symbol = value; + OnSymbolChanged(oldValue, value); + } + } + } + /// + /// Called when Symbol property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Symbol")); + this.InvalidateLayout(); + this.Invalidate(); + } + + private float _SymbolSize = 0f; + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(0f), Category("Appearance"), Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return _SymbolSize; } + set + { + if (value != _SymbolSize) + { + float oldValue = _SymbolSize; + _SymbolSize = value; + OnSymbolSizeChanged(oldValue, value); + } + } + } + /// + /// Called when SymbolSize property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSymbolSizeChanged(float oldValue, float newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("SymbolSize")); + this.InvalidateLayout(); + this.Invalidate(); + } + + private bool _SharedTextSizeEnabled = true; + /// + /// Indicates whether uniform text-size is used for text label. When shared text-size is used it ensures that all text-labels in LayoutControl use same text-size which is determined as largest text label size. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether uniform text-size is used for text label. When shared text-size is used it ensures that all text-labels in LayoutControl use same text-size which is determined as largest text label size.")] + public bool SharedTextSizeEnabled + { + get { return _SharedTextSizeEnabled; } + set + { + if (value != _SharedTextSizeEnabled) + { + bool oldValue = _SharedTextSizeEnabled; + _SharedTextSizeEnabled = value; + OnSharedTextSizeEnabledChanged(oldValue, value); + } + } + } + /// + /// Called when SharedTextSizeEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnSharedTextSizeEnabledChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("SharedTextSizeEnabled")); + this.InvalidateLayout(); + this.Invalidate(); + } + + /// + /// Brings item into view by scrolling the control if necessary. + /// + public virtual void BringIntoView() + { + LayoutControl lc = GetLayoutControl(); + if (lc != null) + lc.ScrollItemIntoView(this); + } + #endregion + + #region IDisposable Members + + protected virtual void OnDispose() + { + EventHandler eh = Disposed; + if (eh != null) eh(this, EventArgs.Empty); + + _Style.PropertyChanged -= StylePropertyChanged; + } + public void Dispose() + { + OnDispose(); + } + + #endregion + + #region IComponent Members + /// + /// Occurs when item is disposed. + /// + [Description("Occurs when item is disposed.")] + public event EventHandler Disposed; + + private string _Name = ""; + /// + /// Gets or sets the name of the item. + /// + [DefaultValue(""), Category("Design"), Description("Indicates name of the item.")] + public string Name + { + get + { + if (_ComponentSite != null) + _Name = _ComponentSite.Name; + return _Name; + } + set + { + if (_ComponentSite != null) + _ComponentSite.Name = value; + if (value == null) + _Name = ""; + else + _Name = value; + } + } + + private ISite _ComponentSite = null; + /// + /// Gets or sets the Site associated with this component. Used by Windows forms designer. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual System.ComponentModel.ISite Site + { + get + { + return _ComponentSite; + } + set + { + _ComponentSite = value; + } + } + + private bool _DesignMode = false; + /// + /// Returns whether item is in design mode. + /// + internal bool DesignMode + { + get + { + return _DesignMode || _ComponentSite != null && _ComponentSite.DesignMode; + } + set + { + _DesignMode = value; + } + } + + private bool _IsSelected = false; + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] + public bool IsSelected + { + get { return _IsSelected; } + set + { + if (value != _IsSelected) + { + bool oldValue = _IsSelected; + _IsSelected = value; + OnIsSelectedChanged(oldValue, value); + } + } + } + /// + /// Called when IsSelected property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnIsSelectedChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("IsSelected")); + this.Invalidate(); + } + + public override string ToString() + { + return string.Format("Text:'{0}', Name:{1}, LayoutItemBase"); + + } + + private eTextAlignment _TextAlignment = eTextAlignment.Default; + /// + /// Indicates the text alignment within the text bounds. Depending on layout item type not all alignments are available. + /// + [DefaultValue(eTextAlignment.Default), Category("Appearance"), Description("Indicates the text alignment within the text bounds.")] + public eTextAlignment TextAlignment + { + get { return _TextAlignment; } + set + { + if (value != _TextAlignment) + { + eTextAlignment oldValue = _TextAlignment; + _TextAlignment = value; + OnTextAlignmentChanged(oldValue, value); + } + } + } + /// + /// Called when TextAlignment property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextAlignmentChanged(eTextAlignment oldValue, eTextAlignment newValue) + { + this.InvalidateLayout(); + this.Invalidate(); + OnPropertyChanged(new PropertyChangedEventArgs("TextAlignment")); + } + + private eTextLineAlignment _TextLineAlignment = eTextLineAlignment.Default; + /// + /// Indicates text line alignment. Usually there is no need to change this property value since Default setting will use text-base line so text-box text and captions align. + /// + [DefaultValue(eTextLineAlignment.Default), Category("Appearance"), Description("Indicates text line alignment. Usually there is no need to change this property value since Default setting will use text-base line so text-box text and captions align.")] + public eTextLineAlignment TextLineAlignment + { + get { return _TextLineAlignment; } + set + { + if (value != _TextLineAlignment) + { + eTextLineAlignment oldValue = _TextLineAlignment; + _TextLineAlignment = value; + OnTextLineAlignmentChanged(oldValue, value); + } + } + } + /// + /// Called when TextLineAlignment property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTextLineAlignmentChanged(eTextLineAlignment oldValue, eTextLineAlignment newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("TextLineAlignment")); + this.Invalidate(); + } + + /// + /// Gets whether this item text-size is shared with other items inside of its parent group. + /// + [Browsable(false)] + public virtual bool IsTextSizeShared + { + get + { + return _SharedTextSizeEnabled; + } + } + + /// + /// Gets whether this item's text-baseline is shared with other items inside of its parent group. + /// + [Browsable(false)] + public virtual bool IsTextBaselineShared + { + get + { + return true; + } + } + + private bool _Visible = true; + /// + /// Indicates visibility of the item. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates visibility of the item.")] + public bool Visible + { + get { return _Visible; } + set + { + if (value !=_Visible) + { + bool oldValue = _Visible; + _Visible = value; + OnVisibleChanged(oldValue, value); + } + } + } + /// + /// Called when Visible property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnVisibleChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Visible")); + InvalidateLayout(); + } + #endregion + + #region TextMarkup + ///
+ /// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example: + /// Markup link + /// + [Description("Occurs when text markup link is clicked. Markup links can be created using a tag.")] + public event MarkupLinkClickEventHandler MarkupLinkClick; + protected virtual void TextMarkupLinkClick(object sender, EventArgs e) + { + TextMarkup.HyperLink link = sender as TextMarkup.HyperLink; + if (link != null) + OnMarkupLinkClick(new MarkupLinkClickEventArgs(link.Name, link.HRef)); + + } + protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e) + { + if (this.MarkupLinkClick != null) + MarkupLinkClick(this, e); + } + + private TextMarkup.BodyElement _TextMarkup = null; + + private void MarkupTextChanged() + { + if (!IsMarkupSupported) + return; + + if (_TextMarkup != null) + _TextMarkup.HyperLinkClick -= this.TextMarkupLinkClick; + + _TextMarkup = null; + + if (!TextMarkup.MarkupParser.IsMarkup(ref _Text)) + return; + + _TextMarkup = TextMarkup.MarkupParser.Parse(_Text); + + if (_TextMarkup != null) + _TextMarkup.HyperLinkClick += TextMarkupLinkClick; + } + + /// + /// Gets reference to parsed markup body element if text was markup otherwise returns null. + /// + internal TextMarkup.BodyElement TextMarkupBody + { + get { return _TextMarkup; } + } + + private bool _TextMarkupEnabled = true; + /// + /// Gets or sets whether item supports and renders text markup. Default value is true. + /// + [DefaultValue(true), Category("Behavior"), Description("Gets or sets whether item supports and renders text markup.")] + public bool TextMarkupEnabled + { + get { return _TextMarkupEnabled; } + set + { + if (_TextMarkupEnabled != value) + { + _TextMarkupEnabled = value; + this.InvalidateLayout(); + this.Invalidate(); + } + } + } + + /// + /// Gets whether item supports text markup. Default is false. + /// + protected virtual bool IsMarkupSupported + { + get { return _TextMarkupEnabled; } + } + + private bool _IsMouseOver = false; + /// + /// Gets whether mouse is over the item. + /// + [Browsable(false)] + internal bool IsMouseOver + { + get { return _IsMouseOver; } + set + { + _IsMouseOver = value; + } + } + private bool _HostedItemMouseEntered = false; + protected internal virtual void OnMouseEnter(object sender, EventArgs e) + { + IsMouseOver = true; + LayoutControl lc = GetLayoutControl(); + ResetHover(lc); + } + protected internal virtual void OnMouseMove(object sender, MouseEventArgs e) + { + if (_TextMarkup != null) + _TextMarkup.MouseMove(sender as Control, e); + + if (!IsMouseOver) HideToolTip(); + } + protected internal virtual void OnMouseDown(object sender, MouseEventArgs e) + { + HideToolTip(); + + if (_TextMarkup != null) + _TextMarkup.MouseDown(sender as Control, e); + } + + protected internal virtual void OnMouseUp(object sender, MouseEventArgs e) + { + if (_TextMarkup != null) + _TextMarkup.MouseUp(sender as Control, e); + } + + protected internal virtual void OnMouseLeave(object sender, EventArgs e) + { + HideToolTip(); + + if (_TextMarkup != null) + _TextMarkup.MouseLeave(sender as Control); + + IsMouseOver = false; + } + + protected internal virtual void OnClick(object sender, EventArgs e) + { + if (_TextMarkup != null) + _TextMarkup.Click(sender as Control); + } + + protected internal virtual void OnMouseHover(object sender, EventArgs e) + { + if (System.Windows.Forms.Control.MouseButtons == System.Windows.Forms.MouseButtons.None) + this.ShowToolTip(); + } + #endregion + + #region Tooltip Support + + /// + /// Occurs after Tooltip text has changed. + /// + protected virtual void OnTooltipChanged() { } + private string _Tooltip = ""; + /// + /// Gets/Sets informational text (tooltip) for the cell. + /// + [Browsable(true), DefaultValue(""), Category("Appearance"), Description("Indicates the text that is displayed when mouse hovers over the cell."), Localizable(true)] + public string Tooltip + { + get + { + + return _Tooltip; + } + set + { + if (_Tooltip == value) + return; + if (value == null) value = ""; + _Tooltip = value; + + if (this.ToolTipVisible) + { + if (string.IsNullOrEmpty(_Tooltip)) + this.HideToolTip(); + else + { + DevComponents.DotNetBar.ToolTip tooltipWindow = _ToolTipWnd; + tooltipWindow.Text = _Tooltip; + tooltipWindow.ShowToolTip(); + tooltipWindow.Invalidate(); + } + } + OnTooltipChanged(); + } + } + /// + /// Gets whether tooltip is visible or not. + /// + internal protected bool ToolTipVisible + { + get + { + return (_ToolTipWnd != null); + } + } + /// + /// Called when tooltip is shown and hidden. + /// + /// true if tooltip is being shown otherwise false. + protected virtual void OnTooltip(bool isShown) + { + } + private DevComponents.DotNetBar.ToolTip _ToolTipWnd = null; + /// + /// Shows tooltip for this item. + /// + public virtual void ShowToolTip() + { + if (this.DesignMode) + return; + + LayoutControl lc = this.GetLayoutControl(); + if (lc != null && !lc.ShowToolTips || !this.ShowToolTips) + return; + OnTooltip(true); + if (_Tooltip != "") + { + if (_ToolTipWnd == null) + _ToolTipWnd = new DevComponents.DotNetBar.ToolTip(); + _ToolTipWnd.Style = StyleManager.GetEffectiveStyle(); + _ToolTipWnd.Text = _Tooltip; + _ToolTipWnd.ReferenceRectangle = ScreenRectangle; + + OnToolTipVisibleChanged(new EventArgs()); + _ToolTipWnd.ShowToolTip(); + } + + } + /// + /// Destroys tooltip window. + /// + internal protected void HideToolTip() + { + if (_ToolTipWnd != null) + { + System.Drawing.Rectangle tipRect = _ToolTipWnd.Bounds; + tipRect.Width += 5; + tipRect.Height += 6; + + OnTooltip(false); + OnToolTipVisibleChanged(new EventArgs()); + try + { + if (_ToolTipWnd != null) + { + _ToolTipWnd.Hide(); + _ToolTipWnd.Dispose(); + _ToolTipWnd = null; + } + } + catch { } + LayoutControl lc = this.GetLayoutControl(); + if (lc != null) + { + lc.Invalidate(lc.RectangleToClient(tipRect), false); + } + } + } + /// + /// Resets Hoover timer. + /// + protected virtual void ResetHover(System.Windows.Forms.Control ctrl) + { + if (ctrl == null || ctrl.IsDisposed || !ctrl.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 + WinApi.TRACKMOUSEEVENT tme = new WinApi.TRACKMOUSEEVENT(); + tme.dwFlags = WinApi.TME_QUERY; + tme.hwndTrack = ctrl.Handle; + tme.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(tme); + WinApi.TrackMouseEvent(ref tme); + tme.dwFlags = tme.dwFlags | WinApi.TME_HOVER; + WinApi.TrackMouseEvent(ref tme); + ctrl = null; + } + /// + /// Occurs when item's tooltip visibility has changed. + /// + [System.ComponentModel.Description("Occurs when item's tooltip visibility has changed.")] + public event EventHandler ToolTipVisibleChanged; + private void OnToolTipVisibleChanged(EventArgs eventArgs) + { + EventHandler h = ToolTipVisibleChanged; + if (h != null) + ToolTipVisibleChanged(this, eventArgs); + } + private Rectangle ScreenRectangle + { + get + { + LayoutControl lc = this.GetLayoutControl(); + if (lc == null) return Rectangle.Empty; + return new Rectangle(lc.PointToScreen(this.Bounds.Location), this.Bounds.Size); + } + } + + private bool _ShowToolTips = true; + /// + /// Gets or sets whether tooltips are shown when mouse is over the item when Tooltip property is set. + /// + [DefaultValue(true), Category("Behavior"), Description("Indicates whether tooltips are shown when mouse is over the item when Tooltip property is set.")] + public bool ShowToolTips + { + get { return _ShowToolTips; } + set + { + _ShowToolTips = value; + } + } + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Raises the PropertyChanged event. + /// + /// Provides event arguments. + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) handler(this, e); + } + /// + /// Occurs when property on object has changed. + /// + [Description("Occurs when property on object has changed.")] + public event PropertyChangedEventHandler PropertyChanged; + + #endregion + } + + + /// + /// Specifies how layout items elements should be sized relative to their container. + /// + public enum eLayoutSizeType + { + /// + /// The item should be sized to an exact number of pixels. + /// + Absolute, + /// + /// The item should be sized as a percentage of the parent container. + /// + Percent, + } + + /// + /// Contains values that specify how a specific element is positioned relative to another element. + /// + public enum eLayoutPosition + { + /// + /// Default location, i.e. left. + /// + Default = 0, + /// + /// Item is located at the left edge of another item. + /// + Left = 1, + /// + /// Item is located at the right edge of another item. + /// + Right = 2, + /// + /// Item is located at the top edge of another item. + /// + Top = 3, + /// + /// Item is located at the bottom edge of another item. + /// + Bottom = 4, + } + /// + /// Specifies layout text alignment within the text bounds. + /// + public enum eTextAlignment + { + Default, + Left, + Right, + Center + } + /// + /// Specifies layout text line alignment within the text bounds. + /// + public enum eTextLineAlignment + { + Default, + Top, + Middle, + Bottom + } + + #region MarkupLinkClickEventArgs + /// + /// Provides more information about MarkupLinkClick event. + /// + public class MarkupLinkClickEventArgs : EventArgs + { + /// + /// Gets the value of href attribute from the markup link that was clicked. + /// + public readonly string HRef = ""; + + /// + /// Gets the value of name attribute from the markup link that was clicked. + /// + public readonly string Name = ""; + + /// + /// Creates new instance of the object. + /// + /// Value of name attribute. + /// Value of href attribute. + public MarkupLinkClickEventArgs(string name, string href) + { + this.HRef = href; + this.Name = name; + } + } + + /// + /// Defines delegate for MarkupLinkClick event. + /// + public delegate void MarkupLinkClickEventHandler(object sender, MarkupLinkClickEventArgs e); + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutItemCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutItemCollection.cs new file mode 100644 index 00000000..fc9f8eaa --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutItemCollection.cs @@ -0,0 +1,371 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Layout +{ + /// + /// Represents collection for LayoutItemBase objects. + /// + public class LayoutItemCollection : CollectionBase + { + #region Private Variables + private LayoutItemBase _ParentItem = null; + #endregion + + #region Internal Implementation + public LayoutItemCollection() + { + } + /// + /// Gets or sets the item this collection is associated with. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public LayoutItemBase ParentItem + { + get { return _ParentItem; } + } + /// + /// Sets the item collection belongs to. + /// + /// Item that is parent of this collection. + internal void SetParentItem(LayoutItemBase parent) + { + _ParentItem = parent; + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public virtual int Add(LayoutItemBase item) + { + if (this.List.Contains(item)) + return IndexOf(item); // throw new InvalidOperationException("Item already contained in collection"); + return List.Add(item); + } + + /// + /// Adds an array of objects to the collection. + /// + /// Array of item objects. + public virtual void AddRange(LayoutItemBase[] items) + { + foreach (LayoutItemBase item in items) + this.Add(item); + } + + /// + /// Returns reference to the object in collection based on it's index. + /// + public LayoutItemBase this[int index] + { + get { return (LayoutItemBase)(List[index]); } + set { List[index] = value; } + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public virtual void Insert(int index, LayoutItemBase value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(LayoutItemBase value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(LayoutItemBase value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + public virtual void Remove(LayoutItemBase value) + { + List.Remove(value); + } + + protected override void OnRemove(int index, object value) + { + //if (!_PassiveCollection) + //{ + // AdvTree 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); + if(!_MovingItem) + ItemRemoveComplete(index, value); + } + + private void ItemRemoveComplete(int index, object value) + { + LayoutItemBase item = value as LayoutItemBase; + item.Parent = null; + } + + protected override void OnSetComplete(int index, object oldValue, object newValue) + { + base.OnSetComplete(index, oldValue, newValue); + if (!_MovingItem) + { + ItemRemoveComplete(index, oldValue); + ItemInsertComplete(newValue); + } + } + + protected override void OnSet(int index, object oldValue, object newValue) + { + //if (!_PassiveCollection) + //{ + // AdvTree tree = GetTreeControl(); + + // if (tree != null) + // tree.InvokeBeforeNodeRemove(m_SourceAction, oldValue as Node, m_ParentNode); + + // if (tree != null) + // tree.InvokeBeforeNodeInsert(m_SourceAction, newValue as Node, m_ParentNode); + //} + base.OnSet(index, oldValue, newValue); + } + private bool _MovingItem = false; + /// + /// Moves an item in collection from its current location to new location. + /// + /// + /// + public void Move(DevComponents.DotNetBar.Layout.LayoutItemBase item, int moveToIndex) + { + _MovingItem = true; + try + { + if (moveToIndex > this.Count - 1) moveToIndex = this.Count - 1; + if (moveToIndex < 0) moveToIndex = 0; + List.Remove(item); + List.Insert(moveToIndex, item); + + //LayoutItemBase temp = this[moveToIndex]; + //int index = List.IndexOf(item); + //List[moveToIndex] = item; + //List[index] = temp; + } + finally + { + _MovingItem = false; + } + } + protected override void OnInsert(int index, object value) + { + //if (!_PassiveCollection) + //{ + // AdvTree 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); + if(!_MovingItem) + ItemInsertComplete(value); + } + + private void ItemInsertComplete(object value) + { + LayoutItemBase item = value as LayoutItemBase; + item.Parent = _ParentItem; + //if (!_PassiveCollection) + //{ + // Node node = value as Node; + // if (m_ParentNode != null) + // { + // if (node.Parent != null && node.Parent != m_ParentNode) + // node.Remove(); + // node.SetParent(m_ParentNode); + // if (m_ParentNode.NodesColumns.IsSorted) + // { + // AdvTree parentTree = m_TreeControl; + // if (parentTree == null) parentTree = m_ParentNode.TreeControl; + // if (parentTree != null) + // parentTree.PushSortRequest(m_ParentNode); + // } + // } + // else + // { + // if (node.Parent != null) + // node.Remove(); + // else + // node.InvokeOnParentChanged(); + // if (m_TreeControl != null && m_TreeControl.Columns.IsSorted) + // { + // m_TreeControl.PushSortRequest(); + // } + // } + // node.internalTreeControl = m_TreeControl; + + // if (m_ParentNode != null) + // m_ParentNode.OnChildNodeInserted(node); + // else + // node.SizeChanged = true; + + // AdvTree tree = GetTreeControl(); + // if (tree != null) + // tree.InvokeAfterNodeInsert(m_SourceAction, value as Node, m_ParentNode); + //} + //m_SourceAction = eTreeAction.Code; + } + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(LayoutItemBase[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the item array. + /// + /// Array to copy to. + public void CopyTo(LayoutItemBase[] array) + { + List.CopyTo(array, 0); + } + + /// + /// Copies contained items to the item array. + /// + /// Array to copy to. + public void CopyTo(List list) + { + foreach (LayoutItemBase item in this.List) + { + list.Add(item); + } + } + + protected override void OnClear() + { + foreach (LayoutItemBase item in this.List) + { + item.Parent = null; + } + base.OnClear(); + } + + protected override void OnClearComplete() + { + if (_ParentItem is LayoutGroup && ((LayoutGroup)_ParentItem).IsRootGroup) + { + // Remove all the controls as well from layout control + List controlsToRemove = new List(); + LayoutControl lc = ((LayoutGroup)_ParentItem).LayoutControl; + if (lc != null) + { + lc.SuspendLayout(); + foreach (Control c in lc.Controls) + { + if (!lc.IsSystemControl(c)) + controlsToRemove.Add(c); + } + foreach (Control c in controlsToRemove) + { + lc.Controls.Remove(c); + if (lc.DisposeControlsOnRootGroupClear) + c.Dispose(); + } + lc.ResumeLayout(); + } + } + base.OnClearComplete(); + } + + /// + /// Sorts the elements in the entire collection using the IComparable implementation of each element. + /// + public virtual void Sort() + { + this.Sort(0, this.Count, Comparer.Default); + } + /// + /// Sorts the elements in the entire collection using the specified comparer. + /// + /// The IComparer implementation to use when comparing elements.-or- null to use the IComparable implementation of each element. + public virtual void Sort(IComparer comparer) + { + this.Sort(0, this.Count, comparer); + } + /// + /// Sorts the elements in a range of elements in collection using the specified comparer. + /// + /// + /// + /// + public virtual void Sort(int index, int count, IComparer comparer) + { + //AdvTree tree = GetTreeControl(); + //if (!_PassiveCollection && tree != null) + // tree.BeginUpdate(); + + this.InnerList.Sort(index, count, comparer); + + //if (tree != null && tree.DeepSort) + //{ + // foreach (Node node in this.InnerList) + // { + // node.Nodes.Sort(0, node.Nodes.Count, comparer); + // } + //} + + //if (!_PassiveCollection && tree != null) + // tree.EndUpdate(); + } + + /// + /// Finds the items with specified key, optionally searching sub-nodes. + /// + /// The name of the tree node to search for. + /// true to search child nodes of tree nodes; otherwise, false. + /// An array of Node objects whose Name property matches the specified key. + //public LayoutItemBase[] Find(string name, bool searchAllChildren) + //{ + // ArrayList list = new ArrayList(); + // NodeOperations.FindNodesByName(this, name, searchAllChildren, list); + // Node[] nodes = new Node[list.Count]; + // if (list.Count > 0) list.CopyTo(nodes); + // return nodes; + //} + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutLabelItem.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutLabelItem.cs new file mode 100644 index 00000000..5c6f509c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutLabelItem.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.DotNetBar.Layout +{ + /// + /// Represents the label item. + /// + internal class LayoutLabelItem : LayoutItemBase + { + #region Constructor + + #endregion + + #region Implementation + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutSpacerItem.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutSpacerItem.cs new file mode 100644 index 00000000..098376b3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/LayoutSpacerItem.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Layout +{ + /// + /// Represents the item used as empty spacer element. + /// + public class LayoutSpacerItem : LayoutItemBase + { + #region Constructor + + #endregion + + #region Implementation + protected override void OnPaintBackground(PaintContext context) + { + base.OnPaintBackground(context); + + if (this.DesignMode && !this.IsSelected && this.Bounds.Width > 0 && this.Bounds.Height > 0) + { + using (Pen borderPen = this.DesignTimeBorderPen) + { + Rectangle clientRectangle = this.Bounds; + clientRectangle.Width--; + clientRectangle.Height--; + context.Graphics.DrawRectangle(borderPen, clientRectangle); + } + } + } + protected Pen DesignTimeBorderPen + { + get + { + Color color = (SystemColors.Control.GetBrightness() < 0.5) ? ControlPaint.Light(SystemColors.Control) : ControlPaint.Dark(SystemColors.Control); + LayoutControl lc = GetLayoutControl(); + if (lc != null) + color = (lc.BackColor.GetBrightness() < 0.5) ? ControlPaint.Light(lc.BackColor) : ControlPaint.Dark(lc.BackColor); + Pen pen = new Pen(color); + pen.DashStyle = DashStyle.Dash; + return pen; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/PaintContext.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/PaintContext.cs new file mode 100644 index 00000000..b19980e0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/PaintContext.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout +{ + public class PaintContext : IDisposable + { + /// + /// Initializes a new instance of the PaintContext class. + /// + /// + /// + public PaintContext(LayoutControl control, Graphics graphics, System.Drawing.Text.HotkeyPrefix hotkeyPrefix) + { + Control = control; + Graphics = graphics; + DefaultFont = control.LabelFont ?? control.Font; + HotkeyPrefix = hotkeyPrefix; + if (control.FocusStyle != null && control.FocusStyle.IsPainted) + this.FocusStyle = control.FocusStyle; + if (control.LabelTextColor.IsEmpty) + LabelTextColor = control.ForeColor; + else + LabelTextColor = control.LabelTextColor; + LabelTextBrush = new SolidBrush(LabelTextColor); + TextAlignment = control.LabelTextAlignment; + } + public LayoutControl Control = null; + public Graphics Graphics = null; + public Font DefaultFont = null; + public System.Drawing.Text.HotkeyPrefix HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; + public SimpleStyle FocusStyle = null; + public Color LabelTextColor = Color.Empty; + public Brush LabelTextBrush = null; + public eTextAlignment TextAlignment = eTextAlignment.Default; + #region IDisposable Members + + public void Dispose() + { + if (LabelTextBrush != null) + { + LabelTextBrush.Dispose(); + LabelTextBrush = null; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Resources.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Resources.Designer.cs new file mode 100644 index 00000000..4f7a02b1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DevComponents.DotNetBar.Layout.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DevComponents.DotNetBar.Layout.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Resources.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Resources.resx new file mode 100644 index 00000000..af7dbebb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Settings.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Settings.Designer.cs new file mode 100644 index 00000000..88bbea34 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DevComponents.DotNetBar.Layout.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Settings.settings b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Settings.settings new file mode 100644 index 00000000..39645652 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/SimpleStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/SimpleStyle.cs new file mode 100644 index 00000000..f9af9f06 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/SimpleStyle.cs @@ -0,0 +1,321 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Layout +{ + [TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))] + public class SimpleStyle : INotifyPropertyChanged, IDisposable + { + #region Constructor + /// + /// Initializes a new instance of the SimpleStyle class. + /// + public SimpleStyle() + { + _Background.PropertyChanged += BackgroundPropertyChanged; + _BorderPattern.PropertyChanged += BorderPatternPropertyChanged; + } + #endregion + + #region Implementation + /// + /// Gets whether any properties on the style have been set that would cause style to be painted. + /// + [Browsable(false)] + public bool IsPainted + { + get + { + return _Background.IsBackgroundSet || !_BorderColors.IsEmpty && !_BorderThickness.IsZero || _Font != null; + } + } + private Background _Background = new Background(); + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + return _Background; + } + + set + { + if (_Background != value) + { + if (_Background != null) + _Background.PropertyChanged -= BackgroundPropertyChanged; + _Background = value; + if (_Background != null) + _Background.PropertyChanged += BackgroundPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("Background")); + } + } + } + private void BackgroundPropertyChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(new PropertyChangedEventArgs("Background." + e.PropertyName)); + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && !_Background.IsEmpty); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = new Background(); + } + + + private Color _TextColor = Color.Empty; + /// + /// Gets or sets text color. + /// + [Category("Appearance"), Description("Indicates text color.")] + public Color TextColor + { + get { return _TextColor; } + set { _TextColor = value; OnPropertyChanged(new PropertyChangedEventArgs("TextColor")); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTextColor() + { + return !_TextColor.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTextColor() + { + this.TextColor = Color.Empty; + } + private Font _Font = null; + /// + /// Indicates the text font. + /// + [DefaultValue(null), Category("Appearance"), Description("Indicates the text font.")] + public Font Font + { + get { return _Font; } + set + { + if (value != _Font) + { + Font oldValue = _Font; + _Font = value; + OnFontChanged(oldValue, value); + } + } + } + /// + /// Called when Font property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnFontChanged(Font oldValue, Font newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Font")); + + } + private BorderPattern _BorderPattern = new BorderPattern(); + /// + /// Indicates the border line pattern. + /// + [Category("Appearance"), Description("Indicates the border line pattern.")] + public BorderPattern BorderPattern + { + get { return _BorderPattern; } + set + { + if (value != _BorderPattern) + { + BorderPattern oldValue = _BorderPattern; + _BorderPattern = value; + OnBorderPatternChanged(oldValue, value); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBorderPattern() + { + return !_BorderPattern.IsEmpty; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBorderPattern() + { + this.BorderPattern = new BorderPattern(); + } + /// + /// Called when BorderPattern property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnBorderPatternChanged(BorderPattern oldValue, BorderPattern newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= BorderPatternPropertyChanged; + if (newValue != null) + newValue.PropertyChanged += BorderPatternPropertyChanged; + OnPropertyChanged(new PropertyChangedEventArgs("BorderPattern")); + } + private void BorderPatternPropertyChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(new PropertyChangedEventArgs("BorderPattern" + e.PropertyName)); + } + private BorderColors _BorderColors = new BorderColors(); + /// + /// Gets or sets the border color. + /// + [Category("Appearance"), Description("Indicates border color.")] + public BorderColors BorderColors + { + get { return _BorderColors; } + set { _BorderColors = value; OnPropertyChanged(new PropertyChangedEventArgs("BorderColors")); } + } + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBorderColors() + { + return !_BorderColors.IsEmpty; + } + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBorderColors() + { + this.BorderColors = new BorderColors(); + } + + private Thickness _BorderThickness = new Thickness(); + /// + /// Indicates the border thickness. + /// + [Category("Appearance"), Description("Indicates the border thickness")] + public Thickness BorderThickness + { + get { return _BorderThickness; } + set + { + if (value != _BorderThickness) + { + Thickness oldValue = _BorderThickness; + _BorderThickness = value; + OnBorderThicknessChanged(oldValue, value); + } + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBorderThickness() + { + return _BorderThickness.Bottom != 0 || _BorderThickness.Top != 0 || _BorderThickness.Left != 0 || _BorderThickness.Right != 0; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBorderThickness() + { + _BorderThickness = new Thickness(0); + } + /// + /// Called when BorderThickness property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnBorderThicknessChanged(Thickness oldValue, Thickness newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("BorderThickness")); + } + + private Padding _Margin = new Padding(0); + /// + /// Gets or sets spacing between the edge of the item and the border and background. This does not influence the actual layout or size of the item rather applies to rendering of the style only. + /// + [Browsable(true), Category("Appearance"), Description("Indicates spacing between the edge of the item and the border and background. This does not influence the actual layout or size of the item rather applies to rendering of the style only."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public Padding Margin + { + get { return _Margin; } + set + { + if (_Margin != value) + { + Padding oldValue = _Margin; + _Margin = value; + OnMarginChanged(oldValue, value); + } + + } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMargin() + { + return _Margin.Bottom != 0 || _Margin.Top != 0 || _Margin.Left != 0 || _Margin.Right != 0; + } + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetMargin() + { + _Margin = new Padding(0); + } + /// + /// Called when Margin property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnMarginChanged(Padding oldValue, Padding newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Margin")); + } + #endregion + + #region IDisposable Members + + protected virtual void OnDispose() + { + + } + public void Dispose() + { + OnDispose(); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Raises the PropertyChanged event. + /// + /// Provides event arguments. + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) handler(this, e); + } + /// + /// Occurs when property on object has changed. + /// + [Description("Occurs when property on object has changed.")] + public event PropertyChangedEventHandler PropertyChanged; + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Symbols.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Symbols.cs new file mode 100644 index 00000000..881e2537 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Symbols.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Drawing.Text; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using System.ComponentModel; +using System.IO; +using System.Reflection; +#if LAYOUT +namespace DevComponents.DotNetBar.Layout +#else +namespace DevComponents.DotNetBar +#endif +{ + // Uses Font Awesome - http://fortawesome.github.com/Font-Awesome + [EditorBrowsable(EditorBrowsableState.Never)] + public static class Symbols + { + #region WinApi + [DllImport("gdi32")] + static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, + uint cbFont, + IntPtr pdv, + [In] ref uint pcFonts); + [DllImport("gdi32")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool RemoveFontMemResourceEx(IntPtr fh); + #endregion + + + #region Internal Implementation + private static Dictionary _FontAwesomeCache = new Dictionary(10); + /// + /// Returns FontAwesome at specific size. + /// + /// Font size in points + /// Font in desired size. + public static Font GetFontAwesome(float fontSize) + { + Font font = null; + EnsureFontLoaded(); + if (fontSize <= 0) return _FontAwesome; + if(_FontAwesomeCache.TryGetValue(fontSize, out font)) + return font; + font = new Font(_FontAwesome.FontFamily, fontSize, FontStyle.Regular, GraphicsUnit.Point); + _FontAwesomeCache.Add(fontSize, font); + return font; + } + + private static Font _FontAwesome = null; + /// + /// Gets FontAwesome at default size. + /// + public static Font FontAwesome + { + get + { + EnsureFontLoaded(); + return _FontAwesome; + } + } + /// + /// Returns FontAwesome Family. + /// + public static FontFamily FontAwesomeFamily + { + get + { + EnsureFontLoaded(); + return _FontAwesome.FontFamily; + } + } + + private static PrivateFontCollection _PrivateFontCollection; + private static GCHandle _FontAwesomeHandle; + private static IntPtr _FontAwesomePointer; + private static void EnsureFontLoaded() + { + if (_FontAwesome == null) + { + _PrivateFontCollection = new PrivateFontCollection(); + + byte[] fontAwesomeBuffer = LoadFont("SystemImages.FontAwesome.ttf"); + _FontAwesomeHandle = GCHandle.Alloc(fontAwesomeBuffer, GCHandleType.Pinned); + _PrivateFontCollection.AddMemoryFont(_FontAwesomeHandle.AddrOfPinnedObject(), fontAwesomeBuffer.Length); + uint rsxCnt = 1; + _FontAwesomePointer = AddFontMemResourceEx(_FontAwesomeHandle.AddrOfPinnedObject(), + (uint)fontAwesomeBuffer.Length, IntPtr.Zero, ref rsxCnt); + using (FontFamily ff = _PrivateFontCollection.Families[0]) + { + if (ff.IsStyleAvailable(FontStyle.Regular)) + { + _FontAwesome = new Font(ff, _FontAwesomeDefaultSize, FontStyle.Regular, GraphicsUnit.Point); + _FontAwesomeCache.Add(_FontAwesomeDefaultSize, _FontAwesome); + } + else + { + // Error use default font... + _FontAwesome = SystemInformation.MenuFont; + } + } + } + } + + private static float _FontAwesomeDefaultSize = 18; + /// + /// Gets the default size for the FontAwesome font size in points. + /// + public static float FontAwesomeDefaultSize + { + get { return _FontAwesomeDefaultSize; } + } + + internal static byte[] LoadFont(string fontFileName) + { + DotNetBarLayoutResourcesAttribute att = Attribute.GetCustomAttribute(System.Reflection.Assembly.GetExecutingAssembly(), typeof(DotNetBarLayoutResourcesAttribute)) as DotNetBarLayoutResourcesAttribute; + if (att != null && att.NamespacePrefix != "") + { + using (Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(att.NamespacePrefix + "." + fontFileName)) + { + byte[] fontData = new byte[fontStream.Length]; + fontStream.Read(fontData, 0, fontData.Length); + fontStream.Close(); + return fontData; + } + } + else + { + using (Stream fontStream = typeof(LayoutControl).Module.Assembly.GetManifestResourceStream(typeof(LayoutControl), fontFileName)) + { + byte[] fontData = new byte[fontStream.Length]; + fontStream.Read(fontData, 0, fontData.Length); + fontStream.Close(); + return fontData; + } + } + return new byte[0]; + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/SystemImages/FontAwesome.ttf b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/SystemImages/FontAwesome.ttf new file mode 100644 index 00000000..d3659246 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/SystemImages/FontAwesome.ttf differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextDrawing.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextDrawing.cs new file mode 100644 index 00000000..cde27826 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextDrawing.cs @@ -0,0 +1,276 @@ +using System; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Drawing.Text; +using System.Collections.Generic; + +#if DOTNETBAR +namespace DevComponents.DotNetBar +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout +#else +namespace DevComponents.Tree +#endif +{ + public class TextDrawing + { + static TextDrawing() + { + string lc = Application.CurrentCulture.TwoLetterISOLanguageName; + if (lc == "ja" || lc == "ko" || lc == "zh" || lc == "ar") + UseGenericDefault = true; + } + + public static bool TextDrawingEnabled = true; + public static bool UseTextRenderer = false; + + public static void DrawString(Graphics g, string text, Font font, Color color, int x, int y, eTextFormat format) + { + DrawString(g, text, font, color, new Rectangle(x, y, 0, 0), format); + } + public static void DrawString(Graphics g, string text, Font font, Color color, Rectangle bounds, eTextFormat format) + { + #if FRAMEWORK20 + if (UseTextRenderer && (format & eTextFormat.Vertical) == 0) + TextRenderer.DrawText(g, text, font, bounds, color, GetTextFormatFlags(format)); + else + DrawStringLegacy(g, text, font, color, bounds, format); + #else + DrawStringLegacy(g, text, font, color, bounds, format); + #endif + } + + public static void DrawStringLegacy(Graphics g, string text, Font font, Color color, Rectangle bounds, eTextFormat format) + { + if (color.IsEmpty || !TextDrawingEnabled) + return; + + using (SolidBrush brush = new SolidBrush(color)) + { + //using (StringFormat sf = GetStringFormat(format)) + StringFormat sf = GetStringFormat(format); + g.DrawString(text, font, brush, bounds, sf); + } + } + public static void DrawStringLegacy(Graphics g, string text, Font font, Color color, RectangleF bounds, eTextFormat format) + { + if (color.IsEmpty || !TextDrawingEnabled) + return; + + using (SolidBrush brush = new SolidBrush(color)) + { + StringFormat sf = GetStringFormat(format); + g.DrawString(text, font, brush, bounds, sf); + } + } + + + public static Size MeasureString(Graphics g, string text, Font font) + { + return MeasureString(g, text, font, Size.Empty, eTextFormat.Default); + } + + public static Size MeasureString(Graphics g, string text, Font font, int proposedWidth, eTextFormat format) + { + return MeasureString(g, text, font, new Size(proposedWidth, 0), format); + } + + public static Size MeasureString(Graphics g, string text, Font font, int proposedWidth) + { + return MeasureString(g, text, font, new Size(proposedWidth, 0), eTextFormat.Default); + } + + public static Size MeasureString(Graphics g, string text, Font font, Size proposedSize, eTextFormat format) + { + #if FRAMEWORK20 + if (UseTextRenderer && (format & eTextFormat.Vertical) == 0) + { + format = format & ~(format & eTextFormat.VerticalCenter); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.Bottom); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.HorizontalCenter); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.Right); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.EndEllipsis); // Bug in .NET Framework 2.0 + return Size.Ceiling(TextRenderer.MeasureText(g, text, font, proposedSize, GetTextFormatFlags(format))); + } + //using (StringFormat sf = GetStringFormat(format)) + StringFormat sf = GetStringFormat(format); + return Size.Ceiling(g.MeasureString(text, font, proposedSize, sf)); + #else + //using (StringFormat sf = GetStringFormat(format)) + StringFormat sf = GetStringFormat(format); + return Size.Ceiling(g.MeasureString(text, font, proposedSize, sf)); +#endif + } + + public static Size MeasureStringLegacy(Graphics g, string text, Font font, Size proposedSize, eTextFormat format) + { + //using (StringFormat sf = GetStringFormat(format)) + StringFormat sf = GetStringFormat(format); + return g.MeasureString(text, font, proposedSize, sf).ToSize(); + } + + + public static eTextFormat TranslateHorizontal(StringAlignment align) + { + if (align == StringAlignment.Center) + return eTextFormat.HorizontalCenter; + else if (align == StringAlignment.Far) + return eTextFormat.Right; + return eTextFormat.Default; + } + + public static eTextFormat TranslateVertical(StringAlignment align) + { + if (align == StringAlignment.Center) + return eTextFormat.VerticalCenter; + else if (align == StringAlignment.Far) + return eTextFormat.Bottom; + return eTextFormat.Default; + } + +#if FRAMEWORK20 + private static TextFormatFlags GetTextFormatFlags(eTextFormat format) + { + format |= eTextFormat.PreserveGraphicsTranslateTransform | eTextFormat.PreserveGraphicsClipping; + if((format & eTextFormat.SingleLine)==eTextFormat.SingleLine && (format & eTextFormat.WordBreak)==eTextFormat.WordBreak) + format = format & ~(format & eTextFormat.SingleLine); + return (TextFormatFlags)format; + } +#endif + internal static bool UseGenericDefault = false; + + private static Dictionary _CachedFormats = new Dictionary(); + public static StringFormat GetStringFormat(eTextFormat format) + { + StringFormat sf; + + if (_CachedFormats.TryGetValue(format, out sf)) return sf; + + if (UseGenericDefault) + sf = (StringFormat)StringFormat.GenericDefault.Clone(); //new StringFormat(StringFormat.GenericDefault); + else + sf = (StringFormat)StringFormat.GenericTypographic.Clone(); // new StringFormat(StringFormat.GenericTypographic); + + if (format == eTextFormat.Default) + { + sf.HotkeyPrefix = HotkeyPrefix.Show; + _CachedFormats.Add(format, sf); + return sf; + } + if ((format & eTextFormat.HorizontalCenter) == eTextFormat.HorizontalCenter) + sf.Alignment = StringAlignment.Center; + else if ((format & eTextFormat.Right) == eTextFormat.Right) + sf.Alignment=StringAlignment.Far; + if ((format & eTextFormat.VerticalCenter) == eTextFormat.VerticalCenter) + sf.LineAlignment=StringAlignment.Center; + else if ((format & eTextFormat.Bottom) == eTextFormat.Bottom) + sf.LineAlignment=StringAlignment.Far; + + if ((format & eTextFormat.EndEllipsis) == eTextFormat.EndEllipsis) + sf.Trimming = StringTrimming.EllipsisCharacter; + else + sf.Trimming = StringTrimming.Character; + + if ((format & eTextFormat.HidePrefix) == eTextFormat.HidePrefix) + sf.HotkeyPrefix = HotkeyPrefix.Hide; + else if ((format & eTextFormat.NoPrefix) == eTextFormat.NoPrefix) + sf.HotkeyPrefix = HotkeyPrefix.None; + else + sf.HotkeyPrefix = HotkeyPrefix.Show; + + if ((format & eTextFormat.WordBreak) == eTextFormat.WordBreak) + sf.FormatFlags = sf.FormatFlags & ~(sf.FormatFlags & StringFormatFlags.NoWrap); + else + sf.FormatFlags |= StringFormatFlags.NoWrap; + + if ((format & eTextFormat.LeftAndRightPadding) == eTextFormat.LeftAndRightPadding) + sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces; + + if ((format & eTextFormat.RightToLeft) == eTextFormat.RightToLeft) + sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + + if ((format & eTextFormat.Vertical) == eTextFormat.Vertical) + sf.FormatFlags |= StringFormatFlags.DirectionVertical; + + if ((format & eTextFormat.NoClipping) == eTextFormat.NoClipping) + sf.FormatFlags |= StringFormatFlags.NoClip; + + _CachedFormats.Add(format, sf); + + return sf; + } +#if DOTNETBAR + public static ThemeTextFormat GetTextFormat(eTextFormat format) + { + ThemeTextFormat ttf = ThemeTextFormat.Left; + if (format == eTextFormat.Default) + return ttf; + + if ((format & eTextFormat.HorizontalCenter) == eTextFormat.HorizontalCenter) + ttf |= ThemeTextFormat.Center; + else if ((format & eTextFormat.Right) == eTextFormat.Right) + ttf|= ThemeTextFormat.Right; + if ((format & eTextFormat.VerticalCenter) == eTextFormat.VerticalCenter) + ttf |= ThemeTextFormat.VCenter; + else if ((format & eTextFormat.Bottom) == eTextFormat.Bottom) + ttf |= ThemeTextFormat.Bottom; + + if ((format & eTextFormat.EndEllipsis) == eTextFormat.EndEllipsis) + ttf |= ThemeTextFormat.EndEllipsis; + + if ((format & eTextFormat.HidePrefix) == eTextFormat.HidePrefix) + ttf |= ThemeTextFormat.HidePrefix; + else if ((format & eTextFormat.NoPrefix) == eTextFormat.NoPrefix) + ttf |= ThemeTextFormat.NoPrefix; + + if ((format & eTextFormat.WordBreak) == eTextFormat.WordBreak) + ttf |= ThemeTextFormat.WordBreak; + else + ttf |= ThemeTextFormat.SingleLine; + + if ((format & eTextFormat.RightToLeft) == eTextFormat.RightToLeft) + ttf |= ThemeTextFormat.RtlReading; + + if ((format & eTextFormat.NoClipping) == eTextFormat.NoClipping) + ttf |= ThemeTextFormat.NoClip; + + return ttf; + } +#endif + } + + [Flags] + public enum eTextFormat + { + Bottom = 8, + Default = 0, + EndEllipsis = 0x8000, + ExpandTabs = 0x40, + ExternalLeading = 0x200, + GlyphOverhangPadding = 0, + HidePrefix = 0x100000, + HorizontalCenter = 1, + Internal = 0x1000, + Left = 0, + LeftAndRightPadding = 0x20000000, + ModifyString = 0x10000, + NoClipping = 0x100, + NoFullWidthCharacterBreak = 0x80000, + NoPadding = 0x10000000, + NoPrefix = 0x800, + PathEllipsis = 0x4000, + PrefixOnly = 0x200000, + PreserveGraphicsClipping = 0x1000000, + PreserveGraphicsTranslateTransform = 0x2000000, + Right = 2, + RightToLeft = 0x20000, + SingleLine = 0x20, + TextBoxControl = 0x2000, + Top = 0, + VerticalCenter = 4, + WordBreak = 0x10, + WordEllipsis = 0x40000, + Vertical = 0x40000000 + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/BarUtilities.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/BarUtilities.cs new file mode 100644 index 00000000..3e36cf0a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/BarUtilities.cs @@ -0,0 +1,185 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Drawing.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Layout +{ + /// + /// Represents class with static functions that provide commonly used utility functions when working with + /// Bar objects and items hosted by Bar object. + /// + internal class BarUtilities + { + /// + /// Gets or sets whether StringFormat internally used by all DotNetBar controls to render text is GenericDefault. Default value is false + /// which indicates that GenericTypographic is used. + /// + public static bool UseGenericDefaultStringFormat + { + get { return TextDrawing.UseGenericDefault; } + set { TextDrawing.UseGenericDefault = value; } + } + + /// + /// Gets or sets the anti-alias text rendering hint that will be used to render text on controls that have AntiAlias property set to true. + /// + public static TextRenderingHint AntiAliasTextRenderingHint + { + get + { + return DisplayHelp.AntiAliasTextRenderingHint; + } + set + { + DisplayHelp.AntiAliasTextRenderingHint = value; + } + } + +#if FRAMEWORK20 + /// + /// Gets or sets whether .NET Framework TextRenderer class is used for text rendering instead of Graphics.DrawString. + /// Default value is false. + /// Using TextRenderer will disable the Fade and Animation effects on controls because of issues in TextRenderer when drawing text on transparent + /// surfaces. + /// + public static bool UseTextRenderer + { + get { return TextDrawing.UseTextRenderer; } + set { TextDrawing.UseTextRenderer = value; } + } +#endif + + + private static bool _AlwaysGenerateAccessibilityFocusEvent = false; + /// + /// Gets or sets whether items always generate the Focus accessibility event when mouse enters the item. Default value is false which indicates + /// that focus event will be raised only when item is on menu bar. + /// + public static bool AlwaysGenerateAccessibilityFocusEvent + { + get { return _AlwaysGenerateAccessibilityFocusEvent; } + set + { + _AlwaysGenerateAccessibilityFocusEvent = value; + } + } + + internal static bool IsModalFormOpen + { + get + { +#if (FRAMEWORK20) + for (int i = 0; i < System.Windows.Forms.Application.OpenForms.Count; i++) + { + System.Windows.Forms.Form form = System.Windows.Forms.Application.OpenForms[i]; + if (form.Modal) return true; + } +#endif + return false; + } + } + + private static bool _AutoRemoveMessageFilter = false; + /// + /// Gets or sets whether Application Message Filter that is registered by popup controls + /// is automatically unregistered when last control is disposed. Default value is false and + /// in most cases should not be changed. + /// + public static bool AutoRemoveMessageFilter + { + get { return _AutoRemoveMessageFilter; } + set { _AutoRemoveMessageFilter = value; } + } + + private static int _TextMarkupCultureSpecific = 3; + /// + /// Get or sets the text-markup padding for text measurement when running on Japanese version of Windows. + /// + public static int TextMarkupCultureSpecificPadding + { + get { return _TextMarkupCultureSpecific; } + set + { + _TextMarkupCultureSpecific = value; + } + } + + private static bool _DisposeItemImages = false; + /// + /// Gets or sets whether Image and Icon resources assigned to items and controls are automatically disposed when + /// control or item is disposed. Default value is false. + /// + public static bool DisposeItemImages + { + get + { + return _DisposeItemImages; + } + set + { + _DisposeItemImages = value; + } + } + + /// + /// Disposes image reference and sets it to null. + /// + /// Reference to image to dispose. + internal static void DisposeImage(ref System.Drawing.Image image) + { + if (image == null) return; + image.Dispose(); + image = null; + } + /// + /// Disposes image reference and sets it to null. + /// + /// Reference to image to dispose. + internal static void DisposeImage(ref System.Drawing.Icon icon) + { + if (icon == null) return; + icon.Dispose(); + icon = null; + } + + #region Delayed Invoke + /// + /// Invokes the method asynchronously using the WinForms Timer. + /// + /// Method to invoke. + public static void InvokeDelayed(MethodInvoker method) + { + InvokeDelayed(method, 10); + } + /// + /// Invokes the method asynchronously using the WinForms Timer. + /// + /// Method to invoke. + /// Time in milliseconds after which method is invoked. + public static void InvokeDelayed(MethodInvoker method, int delayInterval) + { + Timer delayedInvokeTimer = new Timer(); + delayedInvokeTimer = new Timer(); + delayedInvokeTimer.Tag = method; + delayedInvokeTimer.Interval = delayInterval; + delayedInvokeTimer.Tick += new EventHandler(DelayedInvokeTimerTick); + delayedInvokeTimer.Start(); + } + private static void DelayedInvokeTimerTick(object sender, EventArgs e) + { + Timer timer = (Timer)sender; + MethodInvoker method = (MethodInvoker)timer.Tag; + timer.Stop(); + timer.Dispose(); + method.Invoke(); + } + #endregion + } + + internal class BarPropertyBagKeys + { + public static string AutoHideSetting="autohide"; + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/BodyElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/BodyElement.cs new file mode 100644 index 00000000..b201c176 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/BodyElement.cs @@ -0,0 +1,91 @@ +using System; +using System.Text; +using System.Windows.Forms; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class BodyElement : ContainerElement + { + #region Private Variables + private MarkupElementCollection m_ActiveElements=null; + private IActiveMarkupElement m_MouseOverElement = null; + internal bool HasExpandElement = false; + internal string PlainText = ""; + #endregion + + #region Events + public event EventHandler HyperLinkClick; + #endregion + + #region Internal Implementation + public BodyElement() + { + m_ActiveElements = new MarkupElementCollection(null); + } + + public MarkupElementCollection ActiveElements + { + get { return m_ActiveElements; } + } + + public void MouseLeave(Control parent) + { + if (m_MouseOverElement != null) + m_MouseOverElement.MouseLeave(parent); + m_MouseOverElement = null; + } + + public void MouseMove(Control parent, MouseEventArgs e) + { + if (m_MouseOverElement != null && m_MouseOverElement.HitTest(e.X, e.Y)) + return; + if (m_MouseOverElement != null) + m_MouseOverElement.MouseLeave(parent); + + m_MouseOverElement = null; + + foreach(IActiveMarkupElement el in m_ActiveElements) + { + if (el.HitTest(e.X, e.Y)) + { + m_MouseOverElement = el; + m_MouseOverElement.MouseEnter(parent); + } + } + } + + public void MouseDown(Control parent, MouseEventArgs e) + { + if (m_MouseOverElement != null) + m_MouseOverElement.MouseDown(parent, e); + } + + public void MouseUp(Control parent, MouseEventArgs e) + { + if (m_MouseOverElement != null) + m_MouseOverElement.MouseUp(parent, e); + } + + public void Click(Control parent) + { + if (m_MouseOverElement != null) + { + m_MouseOverElement.Click(parent); + if (m_MouseOverElement is HyperLink) + { + if (HyperLinkClick != null) + HyperLinkClick(m_MouseOverElement, new EventArgs()); + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/ContainerElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/ContainerElement.cs new file mode 100644 index 00000000..dabe4124 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/ContainerElement.cs @@ -0,0 +1,113 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class ContainerElement : MarkupElement + { + #region Private Variables + private SerialContentLayoutManager m_Layout = null; + private MarkupLayoutManager m_MarkupLayout = null; + #endregion + + #region Internal Implementation + public override void Measure(Size availableSize, MarkupDrawContext d) + { + ArrangeInternal(new Rectangle(Point.Empty, availableSize), d); + } + + protected virtual SerialContentLayoutManager GetLayoutManager(bool mutliLine) + { + if (m_Layout == null) + { + m_Layout = new SerialContentLayoutManager(); + m_Layout.MultiLine = mutliLine; + m_Layout.ContentVerticalAlignment = eContentVerticalAlignment.Top; + m_Layout.BlockLineAlignment = eContentVerticalAlignment.Top; + m_Layout.BlockSpacing = 0; + } + + m_Layout.EvenHeight = true; + return m_Layout; + } + + private MarkupLayoutManager GetMarkupLayout() + { + if (m_MarkupLayout == null) + { + m_MarkupLayout = new MarkupLayoutManager(); + } + return m_MarkupLayout; + } + + public override void Render(MarkupDrawContext d) + { + Point offset = this.GetContainerOffset(); + d.Offset.Offset(offset.X, offset.Y); + + try + { + foreach (MarkupElement e in this.Elements) + { + e.Render(d); + } + } + finally + { + d.Offset.Offset(-offset.X, -offset.Y); + } + } + + protected virtual Point GetContainerOffset() + { + return this.Bounds.Location; + } + + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) + { + this.Bounds = finalRect; + ArrangeInternal(finalRect, d); + } + + protected virtual void ArrangeInternal(Rectangle bounds, MarkupDrawContext d) + { + SerialContentLayoutManager layout = GetLayoutManager(d.AllowMultiLine); + layout.RightToLeft = d.RightToLeft; + MarkupLayoutManager markupLayout = GetMarkupLayout(); + markupLayout.MarkupDrawContext = d; + try + { + MarkupElement[] blocks = new MarkupElement[this.Elements.Count]; + this.Elements.CopyTo(blocks); + + Rectangle r = layout.Layout(new Rectangle(Point.Empty, bounds.Size), blocks, markupLayout); + this.Bounds = new Rectangle(bounds.Location, r.Size); + } + finally + { + markupLayout.MarkupDrawContext = null; + } + } + + /// + /// Returns whether markup element is an block element that always consumes a whole line in layout. + /// + public override bool IsBlockElement + { + get { return true; } + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/DisplayHelp.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/DisplayHelp.cs new file mode 100644 index 00000000..3318673e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/DisplayHelp.cs @@ -0,0 +1,932 @@ +using System.Drawing; +using System.Drawing.Drawing2D; +using System; +using System.Drawing.Text; + +#if AdvTree +namespace DevComponents.Tree +#elif DOTNETBAR +namespace DevComponents.DotNetBar +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout +#endif +{ + /// + /// Summary description for Display. + /// + public 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, DevComponents.DotNetBar.Rendering.LinearGradientColorTable fillColor, Rectangle bounds, int cornerSize) + //{ + // using (Brush fill = CreateBrush(bounds, fillColor)) + // { + // using (Pen pen = new Pen(color)) + // DrawRoundedRectangle(g, pen, fill, bounds.X, bounds.Y, bounds.Width, bounds.Height, cornerSize); + // } + //} +#if !LAYOUT + public static void DrawRoundedRectangle(System.Drawing.Graphics g, Color color, Color fillColor, Rectangle bounds, int cornerSize) + { + using (Brush fill = new SolidBrush(fillColor)) + { + using (Pen pen = new Pen(color)) + DrawRoundedRectangle(g, pen, fill, bounds.X, bounds.Y, bounds.Width, bounds.Height, cornerSize); + } + } + + 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) + { + DrawRoundedRectangle(g, pen, null, x, y, width, height, cornerSize); + } + public static void DrawRoundedRectangle(System.Drawing.Graphics g, System.Drawing.Pen pen, Brush fill, 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)) + { + if (fill != null) + g.FillPath(fill, path); + g.DrawPath(pen, path); + } + + //g.SmoothingMode = sm; + } + + public static GraphicsPath GetRoundedRectanglePath(Rectangle r, int cornerSize) + { + GraphicsPath path = new GraphicsPath(); + if (cornerSize == 0) + path.AddRectangle(r); + else + { + 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 r, int cornerTopLeft, int cornerTopRight, int cornerBottomRight, int cornerBottomLeft) + { + GraphicsPath path = new GraphicsPath(); + ElementStyleDisplay.AddCornerArc(path, r, cornerTopLeft, eCornerArc.TopLeft); + ElementStyleDisplay.AddCornerArc(path, r, cornerTopRight, eCornerArc.TopRight); + ElementStyleDisplay.AddCornerArc(path, r, cornerBottomRight, eCornerArc.BottomRight); + ElementStyleDisplay.AddCornerArc(path, r, cornerBottomLeft, eCornerArc.BottomLeft); + path.CloseAllFigures(); + return path; + } +#endif + //public static GraphicsPath GetRoundedRectanglePath(Rectangle clientRectangle, int cornerSize, eStyleBackgroundPathPart pathPart, + // eCornerType topLeftCornerType, eCornerType topRightCornerType, eCornerType bottomLeftCornerType, eCornerType bottomRightCornerType) + //{ + // return GetRoundedRectanglePath(clientRectangle, cornerSize, pathPart, topLeftCornerType, topRightCornerType, bottomLeftCornerType, bottomRightCornerType, 0); + //} + + //public static GraphicsPath GetRoundedRectanglePath(Rectangle clientRectangle, int cornerSize, eStyleBackgroundPathPart pathPart, + // eCornerType topLeftCornerType, eCornerType topRightCornerType, eCornerType bottomLeftCornerType, eCornerType bottomRightCornerType, float partSize) + //{ + // return GetRoundedRectanglePath(clientRectangle, cornerSize, cornerSize, cornerSize, cornerSize, pathPart, topLeftCornerType, topRightCornerType, bottomLeftCornerType, bottomRightCornerType, partSize); + //} + + //public static GraphicsPath GetRoundedRectanglePath(Rectangle clientRectangle, int topLeftCornerSize, int topRightCornerSize, int bottomLeftCornerSize, int bottomRightCornerSize, eStyleBackgroundPathPart pathPart, + // eCornerType topLeftCornerType, eCornerType topRightCornerType, eCornerType bottomLeftCornerType, eCornerType bottomRightCornerType, float partSize) + //{ + // GraphicsPath path = new GraphicsPath(); + + // if (pathPart == eStyleBackgroundPathPart.TopHalf) + // { + // if (partSize == 0) + // clientRectangle.Height = clientRectangle.Height / 2; + // else + // clientRectangle.Height = (int)(clientRectangle.Height * partSize); + // } + // else if (pathPart == eStyleBackgroundPathPart.BottomHalf) + // { + // int h = clientRectangle.Height; + // if (partSize == 0) + // clientRectangle.Height = clientRectangle.Height / 2; + // else + // clientRectangle.Height = (int)(clientRectangle.Height * partSize); + // 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 && topLeftCornerSize>0) + // { + // ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, topLeftCornerSize, 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 + topLeftCornerSize, clientRectangle.X + topLeftCornerSize, 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 && topRightCornerSize>0) + // { + // ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, topRightCornerSize, 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 - topRightCornerSize - 1, clientRectangle.Y, clientRectangle.Right, clientRectangle.Y + topRightCornerSize); + // } + // 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 && bottomRightCornerSize>0) + // { + // ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, bottomRightCornerSize, 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 - bottomRightCornerSize - 1, clientRectangle.Right - bottomRightCornerSize - 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 && bottomLeftCornerSize>0) + // { + // ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, bottomLeftCornerSize, 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 - bottomLeftCornerSize - 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; + //} +#if !LAYOUT + 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); + } + } +#endif + 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) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + using (SolidBrush brush = new SolidBrush(color1)) + g.FillRectangle(brush, r); + g.SmoothingMode = sm; + } + } + 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) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + using (SolidBrush brush = new SolidBrush(color1)) + g.FillRectangle(brush, r); + g.SmoothingMode = sm; + } + } + 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--; + + if (color2.IsEmpty) + { + using (Pen pen = new Pen(color1, penWidth)) + g.DrawRectangle(pen, r); + return; + } + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddRectangle(r); + + DrawGradientPath(g, path, r, color1, color2, gradientAngle, penWidth); + } + } + + //public static void DrawGradientPath(Graphics g, GraphicsPath path, Rectangle bounds, Rendering.LinearGradientColorTable table, int penWidth) + //{ + // DrawGradientPath(g, path, bounds, table.Start, table.End, table.GradientAngle, penWidth); + //} + + public static void DrawGradientPath(Graphics g, GraphicsPath path, Rectangle bounds, Color color1, Color color2, int gradientAngle, int penWidth) + { + 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); + } + + + 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; + + if (color2.IsEmpty) + { + using (Pen pen = new Pen(color1, penWidth)) + DrawRoundedRectangle(g, pen, bounds, roundCornerSize); + 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); + + using (LinearGradientBrush brush = new LinearGradientBrush(bounds, color1, color2, gradientAngle)) + g.FillPath(brush, roundPath); + } + } + + + 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) + { + if (color1.IsEmpty && color2.IsEmpty) return; + 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); + } + public static void DrawGradientLine(Graphics g, int x1, int y1, int x2, int y2, Rendering.LinearGradientColorTable table, int penWidth) + { + DrawGradientLine(g, new Point(x1, y1), new Point(x2, y2), 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 || penWidth == 1 && start.Y == end.Y && gradientAngle == 90) + { + 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); + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(r, color1, color2, gradientAngle)) + g.FillPath(brush, path); + g.SmoothingMode = sm; + } + } + } + + 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); + } + } + } + } +#if DOTNETBAR + public static Brush CreateBrush(Rectangle bounds, GradientColorTable colorBlend) + { + return CreateBrush(bounds, colorBlend.Colors, colorBlend.LinearGradientAngle, colorBlend.GradientType); + } + public static Brush CreateBrush(Rectangle bounds, DevComponents.DotNetBar.Rendering.LinearGradientColorTable colorTable) + { + if (colorTable.End.IsEmpty) return new SolidBrush(colorTable.Start); + return new LinearGradientBrush(bounds, colorTable.Start, colorTable.End, colorTable.GradientAngle); + } + + public static Brush CreateBrush(Rectangle bounds, BackgroundColorBlendCollection colorBlend, int gradientAngle, eGradientType gradientType) + { + eBackgroundColorBlendType blendType = colorBlend.GetBlendType(); + if (blendType == eBackgroundColorBlendType.Invalid) + return null; + + if (blendType == eBackgroundColorBlendType.SolidColor) + { + return new SolidBrush(colorBlend[0].Color); + } + else if (blendType == eBackgroundColorBlendType.Relative) + { + try + { + if (gradientType == eGradientType.Linear) + { + bounds.Inflate(1, 1); + LinearGradientBrush brush = + DisplayHelp.CreateLinearGradientBrush(bounds, colorBlend[0].Color, colorBlend[colorBlend.Count - 1].Color, + gradientAngle); + brush.InterpolationColors = colorBlend.GetColorBlend(); + return brush; + } + else if (gradientType == eGradientType.Radial) + { + int d = (int)Math.Sqrt(bounds.Width * bounds.Width + bounds.Height * bounds.Height) + 4; + GraphicsPath fillPath = new GraphicsPath(); + fillPath.AddEllipse(bounds.X - (d - bounds.Width) / 2, bounds.Y - (d - bounds.Height) / 2, d, d); + PathGradientBrush brush = new PathGradientBrush(fillPath); + brush.CenterColor = colorBlend[0].Color; + brush.SurroundColors = new Color[] { colorBlend[colorBlend.Count - 1].Color }; + brush.InterpolationColors = colorBlend.GetColorBlend(); + return brush; + } + } + catch + { + return null; + } + } + else + { + BackgroundColorBlendCollection bc = colorBlend; + for (int i = 0; i < bc.Count; i += 2) + { + BackgroundColorBlend b1 = bc[i]; + BackgroundColorBlend b2 = null; + if (i < bc.Count) + b2 = bc[i + 1]; + if (b1 != null && b2 != null) + { + Rectangle rb = new Rectangle(bounds.X, bounds.Y + (int)b1.Position, bounds.Width, + (b2.Position == 1f ? bounds.Height : (int)b2.Position) - (int)b1.Position); + return DisplayHelp.CreateLinearGradientBrush(rb, b1.Color, b2.Color, gradientAngle); + } + } + } + + return null; + } +#endif + public static System.Windows.Forms.ControlStyles DoubleBufferFlag + { + get + { + #if FRAMEWORK20 + return System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer; +#else + return System.Windows.Forms.ControlStyles.DoubleBuffer; +#endif + } + } + + private static TextRenderingHint s_AntiAliasTextRenderingHint = TextRenderingHint.ClearTypeGridFit; + public static TextRenderingHint AntiAliasTextRenderingHint + { + get + { + return s_AntiAliasTextRenderingHint; + } + set + { + s_AntiAliasTextRenderingHint = value; + } + } + + public static Rectangle[] ExcludeRectangle(Rectangle r1, Rectangle exclude) + { + if (r1.X >= exclude.X && exclude.Right < r1.Right) // Left aligned + return new Rectangle[] { new Rectangle(exclude.Right, r1.Y, r1.Width - (exclude.Right - r1.X), r1.Height) }; + else if (r1.Right <= exclude.Right && exclude.X > r1.X) // Right aligned + return new Rectangle[] { new Rectangle(r1.X, r1.Y, r1.Width - (r1.Right - exclude.X), r1.Height) }; + else if (exclude.X > r1.X && exclude.Right < r1.Right) + { + return new Rectangle[] { new Rectangle(r1.X, r1.Y, exclude.X-r1.X, r1.Height), + new Rectangle(exclude.Right, r1.Y, r1.Right - exclude.Right, r1.Height)}; + } + else if (exclude.Bottom >= r1.Bottom && exclude.Y > r1.Y) // Bottom Aligned + { + return new Rectangle[] { new Rectangle(r1.X, r1.Y, r1.Width, Math.Max(0, exclude.Y - r1.Y)) }; + } + else if (exclude.Y <= r1.Y && exclude.Bottom < r1.Bottom) // Top Aligned + { + return new Rectangle[] { new Rectangle(r1.X, exclude.Bottom, r1.Width, r1.Bottom - exclude.Bottom) }; + } + return new Rectangle[] { }; + } + + internal static Size MaxSize(Size size1, Size size2) + { + if (size2.Width > size1.Width) size1.Width = size2.Width; + if (size2.Height > size1.Height) size1.Height = size2.Height; + return size1; + } + + internal static void ExcludeEdgeRect(ref Rectangle captionRect, Rectangle exclude) + { + if (exclude.X + exclude.Width / 2 < captionRect.X + captionRect.Width / 2) + { + // Left aligned + int r = exclude.Right - captionRect.X; + captionRect.X = exclude.Right; + captionRect.Width -= r; + } + else + { + // Right aligned + captionRect.Width -= (captionRect.Right - exclude.X); + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Div.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Div.cs new file mode 100644 index 00000000..4456e1f2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Div.cs @@ -0,0 +1,223 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; +using System.Windows.Forms; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class Div : ContainerElement + { + #region Private Variables + private eParagraphAlignment m_Align = eParagraphAlignment.Left; + private eParagraphVerticalAlignment m_VAlign = eParagraphVerticalAlignment.Top; + private int m_Width = 0; + private int m_Height = 0; + private Padding m_Padding = new Padding(0, 0, 0, 0); + private Color m_BackColor = Color.Empty; + #endregion + + #region Internal Implementation + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + if (!m_BackColor.IsEmpty) + { + DisplayHelp.FillRectangle(d.Graphics, r, m_BackColor); + } + + base.Render(d); + } + + public eParagraphAlignment Align + { + get { return m_Align; } + set { m_Align = value; } + } + + protected override SerialContentLayoutManager GetLayoutManager(bool multiLine) + { + SerialContentLayoutManager sm = base.GetLayoutManager(multiLine); + if (m_Align == eParagraphAlignment.Left) + sm.ContentAlignment = eContentAlignment.Left; + else if (m_Align == eParagraphAlignment.Right) + sm.ContentAlignment = eContentAlignment.Right; + else if (m_Align == eParagraphAlignment.Center) + sm.ContentAlignment = eContentAlignment.Center; + + if (m_VAlign != eParagraphVerticalAlignment.Top) + { + sm.EvenHeight = false; + sm.BlockLineAlignment = (m_VAlign == eParagraphVerticalAlignment.Bottom ? eContentVerticalAlignment.Bottom : eContentVerticalAlignment.Middle); + } + + return sm; + } + + protected override Point GetContainerOffset() + { + if (m_Padding.Left == 0 && m_Padding.Top == 0) + return base.GetContainerOffset(); + + Point p = base.GetContainerOffset(); + p.X += m_Padding.Left; + p.Y += m_Padding.Top; + return p; + } + + protected override void ArrangeInternal(Rectangle bounds, MarkupDrawContext d) + { + Rectangle r = bounds; + if (m_Width > 0) + r.Width = m_Width; + if (m_Height > 0) + r.Height = m_Height; + if (m_Padding.All == 0) + { + base.ArrangeInternal(r, d); + if (m_Width > 0) + this.Bounds = new Rectangle(this.Bounds.X, this.Bounds.Y, m_Width, m_Height > 0 ? m_Height : this.Bounds.Height + m_Padding.Bottom); + else if(m_Height>0) + this.Bounds = new Rectangle(this.Bounds.X, this.Bounds.Y, this.Bounds.Width, m_Height); + } + else + { + r.X += m_Padding.Left; + r.Y += m_Padding.Top; + r.Width -= m_Padding.Horizontal; + r.Height -= m_Padding.Vertical; + base.ArrangeInternal(r, d); + + r = new Rectangle(bounds.X, bounds.Y, this.Bounds.Width + m_Padding.Horizontal, this.Bounds.Height + m_Padding.Vertical); + if (m_Width > 0) + r.Width = m_Width; + if (m_Height > 0) + r.Height = m_Height; + + this.Bounds = r; + } + } + + public override void ReadAttributes(XmlTextReader reader) + { + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "align") + { + string s = reader.Value.ToLower(); + if (s == "left") + m_Align = eParagraphAlignment.Left; + else if (s == "right") + m_Align = eParagraphAlignment.Right; + else if (s == "center") + m_Align = eParagraphAlignment.Center; + } + else if (reader.Name.ToLower() == "valign") + { + string s = reader.Value.ToLower(); + if (s == "top") + m_VAlign = eParagraphVerticalAlignment.Top; + else if (s == "middle") + m_VAlign = eParagraphVerticalAlignment.Middle; + else if (s == "bottom") + m_VAlign = eParagraphVerticalAlignment.Bottom; + } + else if (reader.Name.ToLower() == "width") + { + try + { + m_Width = Int32.Parse(reader.Value); + } + catch + { + m_Width = 0; + } + } + else if (reader.Name.ToLower() == "height") + { + try + { + m_Height = Int32.Parse(reader.Value); + } + catch + { + m_Height = 0; + } + } + else if (reader.Name.ToLower() == "padding") + { + try + { + string[] values = reader.Value.Split(','); + if (values.Length > 0) + m_Padding.Left = Int32.Parse(values[0]); + if (values.Length > 1) + m_Padding.Right = Int32.Parse(values[1]); + if (values.Length > 2) + m_Padding.Top = Int32.Parse(values[2]); + if (values.Length > 3) + m_Padding.Bottom = Int32.Parse(values[3]); + } + catch + { + m_Padding = new Padding(0,0,0,0); + } + } + else if (reader.Name.ToLower() == "bgcolor") + { + try + { + string s = reader.Value; + if (s.StartsWith("#")) + { + if (s.Length == 7) + m_BackColor = ColorHelpers.GetColor(s.Substring(1)); + } + else + { + m_BackColor = Color.FromName(s); + } + } + catch + { + m_BackColor = Color.Empty; + } + } + } + } + #endregion + } + + #region eParagraphAlignment + /// + /// Indicates paragraph content alignment + /// + internal enum eParagraphAlignment + { + Left, + Right, + Center + } + + /// + /// Indicates paragraph content alignment + /// + internal enum eParagraphVerticalAlignment + { + Top, + Middle, + Bottom + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/EndMarkupElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/EndMarkupElement.cs new file mode 100644 index 00000000..6196699b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/EndMarkupElement.cs @@ -0,0 +1,50 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class EndMarkupElement : MarkupElement + { + #region Internap Implementation + private MarkupElement m_StartElement = null; + + public EndMarkupElement(MarkupElement startElement) + { + m_StartElement = startElement; + } + + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + m_StartElement.MeasureEnd(availableSize, d); + this.Bounds = Rectangle.Empty; + } + + public override void Render(MarkupDrawContext d) + { + m_StartElement.RenderEnd(d); + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) + { + this.Bounds = Rectangle.Empty; + } + + /// + /// Gets reference to markup start element. + /// + public MarkupElement StartElement + { + get { return m_StartElement; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/ExpandElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/ExpandElement.cs new file mode 100644 index 00000000..20242bd7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/ExpandElement.cs @@ -0,0 +1,201 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Xml; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class ExpandElement : MarkupElement + { + #region Internal Implementation + private Size m_DefaultSize = new Size(5, 4); + private eExpandDirection m_Direction = eExpandDirection.Default; + + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + this.Bounds = new Rectangle(Point.Empty, m_DefaultSize); + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Graphics g = d.Graphics; + Color color = d.CurrentForeColor; + //Color shadeColor = Color.FromArgb(96, Color.White); + + eExpandDirection direction = eExpandDirection.Bottom; + if (m_Direction != eExpandDirection.Default) + direction = m_Direction; + + #if DOTNETBAR + if(d.ContextObject is ButtonItem) + { + if (m_Direction == eExpandDirection.Default) + { + ButtonItem item = d.ContextObject as ButtonItem; + if (item.IsOnMenu) + { + direction = eExpandDirection.Right; + if (item.PopupSide == ePopupSide.Default && d.RightToLeft || item.PopupSide == ePopupSide.Left) + direction = eExpandDirection.Left; + } + else if (item.PopupSide == ePopupSide.Default) + direction = eExpandDirection.Bottom; + else if (item.PopupSide == ePopupSide.Left) + direction = eExpandDirection.Left; + else if (item.PopupSide == ePopupSide.Right) + direction = eExpandDirection.Right; + else if (item.PopupSide == ePopupSide.Bottom) + direction = eExpandDirection.Bottom; + else if (item.PopupSide == ePopupSide.Top) + direction = eExpandDirection.Top; + } + } + #endif + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + Rectangle shadeRect = r; + if (direction == eExpandDirection.Bottom || direction == eExpandDirection.PopupDropDown) + shadeRect.Offset(0, 1); + else if (direction == eExpandDirection.Top) + shadeRect.Offset(0, -1); + else if (direction == eExpandDirection.Left) + shadeRect.Offset(1, 0); + else if (direction == eExpandDirection.Right) + shadeRect.Offset(-1, 0); + Point[] p = GetExpandPolygon(shadeRect, direction); + //using (SolidBrush brush = new SolidBrush(shadeColor)) + // g.FillPolygon(brush, p); + + p = GetExpandPolygon(r, direction); + using(SolidBrush brush = new SolidBrush(color)) + g.FillPolygon(brush, p); + + if (direction == eExpandDirection.PopupDropDown) + { + using (Pen pen = new Pen(color, 1)) + g.DrawLine(pen, r.X, r.Y - 2, r.Right - 1, r.Y - 2); + //using (Pen pen = new Pen(shadeColor, 1)) + // g.DrawLine(pen, r.X, r.Y - 1, r.Right - 1, r.Y - 1); + } + + g.SmoothingMode = sm; + + this.RenderBounds = r; + } + + private Point[] GetExpandPolygon(Rectangle r, eExpandDirection direction) + { + Point[] p = new Point[3]; + switch (direction) + { + case eExpandDirection.Right: + { + p[0].X = r.Left + 1; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 - 1; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X + 3; + p[2].Y = p[0].Y + 3; + break; + } + case eExpandDirection.Left: + { + p[0].X = r.Left + 3; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 - 1; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X - 3; + p[2].Y = p[0].Y + 3; + break; + } + case eExpandDirection.Top: + { + p[0].X = r.Left - 1; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 + m_DefaultSize.Height; + p[1].X = p[0].X + 6; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 3; + p[2].Y = p[0].Y - 4; + break; + } + case eExpandDirection.Bottom: + case eExpandDirection.PopupDropDown: + { + p[0].X = r.Left; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 + 1; + p[1].X = p[0].X + 5; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 2; + p[2].Y = p[0].Y + 3; + break; + } + } + return p; + } + + public override void ReadAttributes(XmlTextReader reader) + { + m_Direction = eExpandDirection.Default; + + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "direction") + { + string s = reader.Value.ToLower(); + if (s == "left") + m_Direction = eExpandDirection.Left; + else if (s == "right") + m_Direction = eExpandDirection.Right; + else if (s == "top") + m_Direction = eExpandDirection.Top; + else if (s == "bottom") + m_Direction = eExpandDirection.Bottom; + else if (s == "popup") + m_Direction = eExpandDirection.PopupDropDown; + break; + } + } + } + + private enum eExpandDirection + { + Left, + Right, + Top, + Bottom, + Default, + PopupDropDown + } + + /// + /// Returns whether layout manager can start new line with this element. + /// + public override bool CanStartNewLine + { + get { return false; } + } + #endregion + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/FontChangeElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/FontChangeElement.cs new file mode 100644 index 00000000..fbc1c7c7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/FontChangeElement.cs @@ -0,0 +1,57 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class FontChangeElement : MarkupElement + { + #region Private Variables + protected Font m_OldFont = null; + #endregion + + #region Internal Implementation + + public override void Measure(Size availableSize, MarkupDrawContext d) + { + this.Bounds = Rectangle.Empty; + SetFont(d); + } + + public override void Render(MarkupDrawContext d) + { + SetFont(d); + } + + protected virtual void SetFont(MarkupDrawContext d) + { + + } + + public override void RenderEnd(MarkupDrawContext d) + { + if(m_OldFont!=null) + d.CurrentFont = m_OldFont; + m_OldFont = null; + base.RenderEnd(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + if (m_OldFont != null) + d.CurrentFont = m_OldFont; + m_OldFont = null; + base.MeasureEnd(availableSize, d); + } + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) { } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/FontElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/FontElement.cs new file mode 100644 index 00000000..feced86c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/FontElement.cs @@ -0,0 +1,187 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; + +#if AdvTree +using DevComponents.Tree; +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class FontElement : FontChangeElement + { + #region Private Variables + private Color m_ForeColor = Color.Empty; + private Color m_OldForeColor = Color.Empty; + private int m_Size = 0; + private bool m_RelativeSize = false; + private string m_Face = ""; + private string m_SystemColorName = ""; + #endregion + + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + try + { + if (m_Face != "" || m_Size != 0 && m_RelativeSize || m_Size>4 && !m_RelativeSize) + { + if (m_Face != "") + d.CurrentFont = new Font(m_Face, ((m_RelativeSize || m_Size == 0)?font.SizeInPoints + m_Size:m_Size), font.Style); + else + d.CurrentFont = new Font(font.FontFamily, ((m_RelativeSize || m_Size == 0)? font.SizeInPoints + m_Size : m_Size), font.Style); + } + else + font = null; + } + catch + { + font = null; + } + + if (font != null) + m_OldFont = font; + + if (!d.IgnoreFormattingColors) + { + if (!m_ForeColor.IsEmpty) + { + m_OldForeColor = d.CurrentForeColor; + d.CurrentForeColor = m_ForeColor; + } + else if (m_SystemColorName != "") + { +#if DOTNETBAR + if (Rendering.GlobalManager.Renderer is Rendering.Office2007Renderer) + { + m_OldForeColor = d.CurrentForeColor; + d.CurrentForeColor = ((Rendering.Office2007Renderer)Rendering.GlobalManager.Renderer).ColorTable.Form.Active.CaptionTextExtra; + } +#endif + } + } + } + + public override void RenderEnd(MarkupDrawContext d) + { + RestoreForeColor(d); + + base.RenderEnd(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + RestoreForeColor(d); + base.MeasureEnd(availableSize, d); + } + + protected virtual void RestoreForeColor(MarkupDrawContext d) + { + if (d == null) return; + if (!m_OldForeColor.IsEmpty) + d.CurrentForeColor = m_OldForeColor; + m_OldForeColor = Color.Empty; + } + + public Color ForeColor + { + get { return m_ForeColor; } + set { m_ForeColor = value; } + } + + public int Size + { + get { return m_Size; } + set { m_Size = value; } + } + + public string Face + { + get { return m_Face; } + set { m_Face = value; } + } + + private Color GetColorFromName(string name) + { + string s = name.ToLower(); + m_SystemColorName = ""; + if (s == "syscaptiontextextra") + { + m_SystemColorName = s; + return Color.Empty; + } + + return Color.FromName(name); + } + + public override void ReadAttributes(XmlTextReader reader) + { + m_RelativeSize = false; + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "color") + { + try + { + string s = reader.Value; + if (s.StartsWith("#")) + { + if (s.Length == 7) + m_ForeColor = ColorHelpers.GetColor(s.Substring(1)); + } + else + { + m_ForeColor = GetColorFromName(s); + } + } + catch + { + m_ForeColor = Color.Empty; + } + } + else if (reader.Name.ToLower() == "size") + { + string s = reader.Value; + if (s.StartsWith("+")) + { + try + { + m_Size = Int32.Parse(s.Substring(1)); + m_RelativeSize = true; + } + catch + { + m_Size = 0; + } + } + else + { + if (s.StartsWith("-")) + m_RelativeSize = true; + try + { + m_Size = Int32.Parse(s); + } + catch + { + m_Size = 0; + } + } + } + else if (reader.Name.ToLower() == "face") + { + m_Face = reader.Value; + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Heading.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Heading.cs new file mode 100644 index 00000000..fa06d9c2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Heading.cs @@ -0,0 +1,97 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class Heading: ContainerElement + { + #region Private Variables + private int m_Level = 1; + private Font m_OldFont = null; + #endregion + + #region Internal Implementation + public Heading() { } + public Heading(int level) + { + m_Level = level; + } + + public override void Measure(Size availableSize, MarkupDrawContext d) + { + SetFont(d); + base.Measure(availableSize, d); + if (m_OldFont != null) + d.CurrentFont = m_OldFont; + } + + public override void Render(MarkupDrawContext d) + { + SetFont(d); + base.Render(d); + if (m_OldFont != null) + d.CurrentFont = m_OldFont; + } + + protected virtual void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + try + { + float size = d.CurrentFont.SizeInPoints; + if (m_Level == 1) + { + size += 12; + } + else if (m_Level == 2) + { + size += 8; + } + else if (m_Level == 3) + { + size += 6; + } + else if (m_Level == 4) + { + size += 4; + } + else if (m_Level == 5) + { + size += 2; + } + else if (m_Level == 6) + { + size += 1; + } + + d.CurrentFont = new Font(d.CurrentFont.FontFamily, size, FontStyle.Bold); + } + catch + { + font = null; + } + + if (font != null) + m_OldFont = font; + } + + /// + /// Gets or sets heading level. Values from 1 to 6 are valid. Default is 1. + /// + public int Level + { + get { return m_Level; } + set { m_Level = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/HyperLink.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/HyperLink.cs new file mode 100644 index 00000000..93383690 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/HyperLink.cs @@ -0,0 +1,249 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; +using System.Windows.Forms; +using System.Drawing.Drawing2D; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class HyperLink : MarkupElement, IActiveMarkupElement + { + #region Private Variables + private Color m_ForeColor = Color.Empty; + private Color m_OldForeColor = Color.Empty; + private string m_HRef = ""; + private string m_Name = ""; + private Cursor m_OldCursor = null; + private bool m_IsMouseOver = false; + private bool m_Visited = false; + #endregion + + #region Internal Implementation + public override void Measure(Size availableSize, MarkupDrawContext d) + { + this.Bounds = Rectangle.Empty; + SetForeColor(d); + } + + public override void Render(MarkupDrawContext d) + { + d.HyperLink = true; + d.HyperlinkStyle = GetHyperlinkStyle(); + if (!d.HyperlinkStyle.BackColor.IsEmpty) + { + using (GraphicsPath gp = new GraphicsPath()) + { + MarkupElementCollection col = this.Parent.Elements; + int start = col.IndexOf(this) + 1; + for (int i = start; i < col.Count; i++) + { + MarkupElement elem = col[i]; + if (!elem.Visible) continue; + if (elem is EndMarkupElement && ((EndMarkupElement)elem).StartElement == this) + break; + gp.AddRectangle(elem.RenderBounds); + } + + using (SolidBrush brush = new SolidBrush(d.HyperlinkStyle.BackColor)) + d.Graphics.FillPath(brush, gp); + } + } + SetForeColor(d); + } + + private HyperlinkStyle GetHyperlinkStyle() + { + if (m_IsMouseOver && MarkupSettings.MouseOverHyperlink.IsChanged) + return MarkupSettings.MouseOverHyperlink; + else if (m_Visited && MarkupSettings.VisitedHyperlink.IsChanged) + return MarkupSettings.VisitedHyperlink; + + return MarkupSettings.NormalHyperlink; + } + + protected virtual void SetForeColor(MarkupDrawContext d) + { + Color c = Color.Empty; + HyperlinkStyle style = GetHyperlinkStyle(); + if (style != null && !style.TextColor.IsEmpty) + c = style.TextColor; + + if (!m_ForeColor.IsEmpty) + c = m_ForeColor; + if (!c.IsEmpty) + { + m_OldForeColor = d.CurrentForeColor; + d.CurrentForeColor = c; + } + } + + public override void RenderEnd(MarkupDrawContext d) + { + RestoreForeColor(d); + d.HyperLink = false; + d.HyperlinkStyle = null; + base.RenderEnd(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + RestoreForeColor(d); + base.MeasureEnd(availableSize, d); + } + + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) { } + + protected virtual void RestoreForeColor(MarkupDrawContext d) + { + if (d == null) return; + if (!m_OldForeColor.IsEmpty) + d.CurrentForeColor = m_OldForeColor; + m_OldForeColor = Color.Empty; + } + + public Color ForeColor + { + get { return m_ForeColor; } + set { m_ForeColor = value; } + } + + public string HRef + { + get { return m_HRef; } + set { m_HRef = value; } + } + + public string Name + { + get { return m_Name; } + set { m_Name = value; } + } + + public override void ReadAttributes(XmlTextReader reader) + { + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "href") + { + m_HRef = reader.Value; + } + else if (reader.Name.ToLower() == "name") + { + m_Name = reader.Value; + } + else if (reader.Name.ToLower() == "color") + { + try + { + string s = reader.Value; + if (s.StartsWith("#")) + { + if (s.Length == 7) + m_ForeColor = ColorHelpers.GetColor(s.Substring(1)); + } + else + { + m_ForeColor = GetColorFromName(s); + } + } + catch + { + m_ForeColor = Color.Empty; + } + } + } + } + + private Color GetColorFromName(string name) + { + return Color.FromName(name); + } + + /// + /// Returns whether hyper-link contains specified coordinates. + /// + /// + /// + /// + public bool HitTest(int x, int y) + { + if (this.Parent == null) + return false; + + MarkupElementCollection col = this.Parent.Elements; + int start = col.IndexOf(this)+1; + for (int i = start; i < col.Count; i++) + { + MarkupElement el = col[i]; + if (el is EndMarkupElement && ((EndMarkupElement)el).StartElement == this) + break; + + if (col[i].RenderBounds.Contains(x, y)) + return true; + + } + + return false; + } + + public void MouseEnter(Control parent) + { + m_OldCursor = parent.Cursor; + parent.Cursor = Cursors.Hand; + m_IsMouseOver = true; + if (MarkupSettings.MouseOverHyperlink.IsChanged) + { + InvalidateElements(parent); + } + } + + public void MouseLeave(Control parent) + { + if (m_OldCursor != null && parent!=null) + parent.Cursor = m_OldCursor; + m_OldCursor = null; + m_IsMouseOver = false; + if (MarkupSettings.MouseOverHyperlink.IsChanged) + { + InvalidateElements(parent); + } + } + + public void MouseDown(Control parent, MouseEventArgs e) { } + public void MouseUp(Control parent, MouseEventArgs e) { } + public void Click(Control parent) + { + m_Visited = true; + if (MarkupSettings.VisitedHyperlink.IsChanged) + { + InvalidateElements(parent); + } + } + + private void InvalidateElements(Control parent) + { + if (this.Parent == null) return; + MarkupElementCollection col = this.Parent.Elements; + int start = col.IndexOf(this) + 1; + for (int i = start; i < col.Count; i++) + { + MarkupElement elem = col[i]; + if (!elem.Visible) continue; + if (elem is EndMarkupElement && ((EndMarkupElement)elem).StartElement == this) + break; + parent.Invalidate(elem.RenderBounds); + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/IActiveMarkupElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/IActiveMarkupElement.cs new file mode 100644 index 00000000..95fb6608 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/IActiveMarkupElement.cs @@ -0,0 +1,24 @@ +using System; +using System.Text; +using System.Windows.Forms; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal interface IActiveMarkupElement + { + bool HitTest(int x, int y); + void MouseEnter(Control parent); + void MouseLeave(Control parent); + void MouseDown(Control parent, MouseEventArgs e); + void MouseUp(Control parent, MouseEventArgs e); + void Click(Control parent); + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/ImageElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/ImageElement.cs new file mode 100644 index 00000000..d78a25c7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/ImageElement.cs @@ -0,0 +1,202 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; +using System.Reflection; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif + +{ + internal class ImageElement : MarkupElement + { + #region Private Variables + private Size m_ImageSize = Size.Empty; + private string m_ImageSource = ""; + private Image m_Image = null; + #endregion + + #region Internal Implementation + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + if (!m_ImageSize.IsEmpty) + this.Bounds = new Rectangle(Point.Empty, m_ImageSize); + else if (m_ImageSource.Length == 0) + this.Bounds = Rectangle.Empty; + else + { + Image img = this.GetImage(); + if (img != null) + this.Bounds = new Rectangle(Point.Empty, img.Size); + else + this.Bounds = new Rectangle(Point.Empty, new Size(16,16)); + } + } + + public override bool IsBlockElement + { + get + { + return false; + } + } + + private Image GetImage() + { + if (m_Image != null) return m_Image; + Assembly a = null; + + // Try static custom image resolver + ResolveImageEventArgs e = new ResolveImageEventArgs(); + e.Key = m_ImageSource; + e.ResolvedImage = null; + MarkupSettings.InvokeResolveImage(e); + if (e.Handled) + return e.ResolvedImage; + + // Load from format: ClassLibrary1/ClassLibrary1.MyImage.png or ClassLibrary1/global::ClassLibrary1.Resources.MyImage + if (m_ImageSource.IndexOf('/') >= 0) + { + string[] parts = m_ImageSource.Split('/'); + a = Assembly.Load(parts[0]); + string ResourceName = parts[1]; + if (a != null) + { + m_Image = LoadImageGlobalResource(parts[1], a); + if (m_Image == null) + m_Image = LoadImageResource(parts[1], a); + + if (m_Image != null) return m_Image; + } + } + + // Probe Executing Assembly + a = Assembly.GetExecutingAssembly(); + m_Image = LoadImageGlobalResource(m_ImageSource, a); + if(m_Image==null) + m_Image = LoadImageResource(m_ImageSource, a); + + // Probe Entry Assembly + if (m_Image == null) + { + a = Assembly.GetEntryAssembly(); + m_Image = LoadImageGlobalResource(m_ImageSource, a); + if (m_Image == null) + m_Image = LoadImageResource(m_ImageSource, a); + } + + return m_Image; + } + + private Image LoadImageGlobalResource(string imageSource, Assembly a) + { + Image img = null; +#if FRAMEWORK20 + if (imageSource.StartsWith("global::")) + { + string name = imageSource.Substring(8); + if (name.Length > 0) + { + try + { + int i = name.LastIndexOf('.'); + string resName = name.Substring(0, i); + name = name.Substring(i + 1); + System.Resources.ResourceManager r = new System.Resources.ResourceManager(resName, a); + object obj = r.GetObject(name); + img = (Bitmap)obj; + } + catch + { + img = null; + } + } + } +#endif + return img; + } + + private Image LoadImageResource(string imageSource, Assembly a) + { + Image img = null; + try + { + img = new Bitmap(a.GetManifestResourceStream(imageSource)); + } + catch { } + + return img; + } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Image img = this.GetImage(); + if (img != null) + { + Rectangle imageRect = r; + if (m_ImageSize.IsEmpty) + imageRect.Size = img.Size; + else + imageRect.Size = m_ImageSize; + d.Graphics.DrawImage(img, imageRect); + } + else + { + using (SolidBrush brush = new SolidBrush(Color.White)) + { + d.Graphics.FillRectangle(brush, r); + } + using (Pen pen = new Pen(Color.DarkGray, 1)) + { + d.Graphics.DrawRectangle(pen, r); + d.Graphics.DrawLine(pen, r.X, r.Y, r.Right, r.Bottom); + d.Graphics.DrawLine(pen, r.Right, r.Y, r.X, r.Bottom); + } + } + + this.RenderBounds = r; + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + public override void ReadAttributes(XmlTextReader reader) + { + m_ImageSize = Size.Empty; + m_ImageSource = ""; + m_Image = null; + + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "width") + { + string s = reader.Value; + m_ImageSize.Width = int.Parse(s); + } + else if (reader.Name.ToLower() == "height") + { + string s = reader.Value; + m_ImageSize.Height = int.Parse(s); + } + else if (reader.Name.ToLower() == "src") + { + m_ImageSource = reader.Value; + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Italic.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Italic.cs new file mode 100644 index 00000000..d43310c7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Italic.cs @@ -0,0 +1,35 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class Italic : FontChangeElement + { + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + FontStyle style=font.Style | FontStyle.Italic; + + if (!font.Italic && d.CurrentFont.FontFamily.IsStyleAvailable(style)) + d.CurrentFont = new Font(font, style); + else + font = null; + + if (font != null) + m_OldFont = font; + + base.SetFont(d); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupDrawContext.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupDrawContext.cs new file mode 100644 index 00000000..ad87cc3c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupDrawContext.cs @@ -0,0 +1,58 @@ +using System; +using System.Drawing; +using System.Text; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + public class MarkupDrawContext + { + public Graphics Graphics = null; + public Font CurrentFont = null; + public Color CurrentForeColor = SystemColors.ControlText; + public bool RightToLeft = false; + public Point Offset = Point.Empty; + public bool HyperLink = false; + public HyperlinkStyle HyperlinkStyle = null; + public bool Underline = false; + public Rectangle ClipRectangle = Rectangle.Empty; + public bool HotKeyPrefixVisible = false; + public object ContextObject = null; + public bool AllowMultiLine = true; + public bool IgnoreFormattingColors = false; + public bool StrikeOut; + + public MarkupDrawContext(Graphics g, Font currentFont, Color currentForeColor, bool rightToLeft) : this(g, currentFont, currentForeColor, rightToLeft, Rectangle.Empty, false) + { + } + + public MarkupDrawContext(Graphics g, Font currentFont, Color currentForeColor, bool rightToLeft, Rectangle clipRectangle, bool hotKeyPrefixVisible) + { + this.Graphics = g; + this.CurrentFont = currentFont; + this.CurrentForeColor = currentForeColor; + this.RightToLeft = rightToLeft; + this.ClipRectangle = clipRectangle; + this.HotKeyPrefixVisible = hotKeyPrefixVisible; + } + + public MarkupDrawContext(Graphics g, Font currentFont, Color currentForeColor, bool rightToLeft, Rectangle clipRectangle, bool hotKeyPrefixVisible, object contextObject) + { + this.Graphics = g; + this.CurrentFont = currentFont; + this.CurrentForeColor = currentForeColor; + this.RightToLeft = rightToLeft; + this.ClipRectangle = clipRectangle; + this.HotKeyPrefixVisible = hotKeyPrefixVisible; + this.ContextObject = contextObject; + } + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupElement.cs new file mode 100644 index 00000000..c11ebf37 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupElement.cs @@ -0,0 +1,198 @@ +using System; +using System.Drawing; +using System.Text; +using System.Xml; +using System.Windows.Forms; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal abstract class MarkupElement : IBlockExtended + { + #region Private Variables + private MarkupElementCollection m_Elements = null; + private MarkupElement m_Parent = null; + private Rectangle m_Bounds = Rectangle.Empty; + private bool m_Visible = true; + private bool m_SizeValid = false; + private Rectangle m_RenderBounds = Rectangle.Empty; + #endregion + + #region Internal Implementation + public MarkupElement() + { + m_Elements = new MarkupElementCollection(this); + } + /// + /// Returns whether markup element is an container so it receives full available size of parent control for layout. + /// + public virtual bool IsBlockContainer + { + get { return false; } + } + + /// + /// Returns whether markup element is an block element that always consumes a whole line in layout. + /// + public virtual bool IsBlockElement + { + get { return false; } + } + + /// + /// Returns whether layout manager switches to new line after processing this element. + /// + public virtual bool IsNewLineAfterElement + { + get { return false; } + } + + /// + /// Returns whether layout manager can start new line with this element. + /// + public virtual bool CanStartNewLine + { + get { return true; } + } + + /// + /// Gets the collection of child elements if any for this markup element. + /// + public virtual MarkupElementCollection Elements + { + get + { + if (m_Elements == null) + m_Elements = new MarkupElementCollection(this); + return m_Elements; + } + } + + internal void InvalidateElementsSize() + { + this.IsSizeValid = false; + if (m_Elements==null || m_Elements.Count == 0) + return; + foreach (MarkupElement e in m_Elements) + { + e.InvalidateElementsSize(); + e.IsSizeValid = false; + } + } + + /// + /// Gets or sets whether element size is valid. When size is not valid element Measure method will be called to validate size. + /// + public virtual bool IsSizeValid + { + get { return m_SizeValid; } + set { m_SizeValid = value; } + } + + /// + /// Gets element parent or null if parent is not set. + /// + public virtual MarkupElement Parent + { + get { return m_Parent; } + } + + internal void SetParent(MarkupElement parent) + { + m_Parent = parent; + } + + /// + /// Gets or sets actual rendering bounds. + /// + public Rectangle Bounds + { + get { return m_Bounds; } + set { m_Bounds = value; } + } + + /// + /// Gets or sets whether markup element is visible. + /// + public bool Visible + { + get { return m_Visible; } + set { m_Visible = value; } + } + + private Padding _Margin = new Padding(0); + /// + /// Gets or sets the element margin. + /// + public Padding Margin + { + get { return _Margin; } + set { _Margin = value; } + } + + /// + /// Measures the element given available size. + /// + /// Size available to element + /// Reference to graphics object + public abstract void Measure(Size availableSize, MarkupDrawContext d); + + /// + /// Measures the end tag of an element. Most implementations do not need to do anything but implementations like the ones + /// that change color should return state back at this time. + /// + /// + /// + public virtual void MeasureEnd(Size availableSize, MarkupDrawContext d) { } + + /// + /// Renders element. + /// + /// Provides markup drawing context information. + public abstract void Render(MarkupDrawContext d); + + /// + /// Renders element tag end. Most implementations do not need to do anything but mplementations like the ones + /// that change color should return state back at this time. + /// + /// Provides markup drawing context information. + public virtual void RenderEnd(MarkupDrawContext d) { } + + /// + /// Provides final rectangle to element and lets it arrange it's content given new constraint. + /// + /// Final rectangle. + /// + protected abstract void ArrangeCore(Rectangle finalRect, MarkupDrawContext d); + + /// + /// Arranges the element given the final size. Layout is two step process with Measure followed by Arrange. + /// + /// + /// + public void Arrange(Rectangle finalSize, MarkupDrawContext d) + { + this.ArrangeCore(finalSize, d); + } + + public virtual void ReadAttributes(XmlTextReader reader) { } + + /// + /// Gets or sets actual rendered bounds for a give markup element if applicable. + /// + public Rectangle RenderBounds + { + get { return m_RenderBounds; } + set { m_RenderBounds = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupElementCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupElementCollection.cs new file mode 100644 index 00000000..d98ff9dc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupElementCollection.cs @@ -0,0 +1,141 @@ +using System; +using System.Text; +using System.Collections; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class MarkupElementCollection : CollectionBase + { + #region Private Variables + private MarkupElement m_Parent = null; + #endregion + + #region Internal Implementation + /// Creates new instance of the class. + public MarkupElementCollection(MarkupElement parent) + { + m_Parent = parent; + } + + /// + /// Gets or sets the collection parent element. + /// + public MarkupElement Parent + { + get { return m_Parent; } + set { m_Parent = value; } + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(MarkupElement MarkupElement) + { + return List.Add(MarkupElement); + } + /// + /// Returns reference to the object in collection based on it's index. + /// + public MarkupElement this[int index] + { + get {return (MarkupElement)(List[index]);} + set {List[index] = value;} + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, MarkupElement value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(MarkupElement value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(MarkupElement value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + public void Remove(MarkupElement value) + { + List.Remove(value); + } + + protected override void OnRemoveComplete(int index,object value) + { + base.OnRemoveComplete(index,value); + MarkupElement me=value as MarkupElement; + if (m_Parent != null) + { + me.SetParent(null); + m_Parent.IsSizeValid = false; + } + } + protected override void OnInsertComplete(int index,object value) + { + base.OnInsertComplete(index,value); + MarkupElement me=value as MarkupElement; + if (m_Parent != null) + { + me.SetParent(m_Parent); + m_Parent.IsSizeValid = false; + } + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(MarkupElement[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the MarkupElement array. + /// + /// Array to copy to. + internal void CopyTo(MarkupElement[] array) + { + List.CopyTo(array,0); + } + + protected override void OnClear() + { + base.OnClear(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupLayoutManager.cs new file mode 100644 index 00000000..660a8a98 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupLayoutManager.cs @@ -0,0 +1,41 @@ +using System.Collections; +using System.Drawing; +using System.Text; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class MarkupLayoutManager : BlockLayoutManager + { + private MarkupDrawContext m_MarkupDrawContext = null; + + public MarkupDrawContext MarkupDrawContext + { + get { return m_MarkupDrawContext; } + set { m_MarkupDrawContext = value; } + } + + public override void Layout(IBlock block, Size availableSize) + { + if (block is MarkupElement) + { + MarkupElement m = block as MarkupElement; + if(!m.IsSizeValid) + m.Measure(availableSize, m_MarkupDrawContext); + } + } + + public override Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines) + { + return (blocksBounds); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupParser.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupParser.cs new file mode 100644 index 00000000..40462afa --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupParser.cs @@ -0,0 +1,256 @@ +using System; +using System.Text; +using System.IO; +using System.Xml; +using System.Collections; +using System.Text.RegularExpressions; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class MarkupParser + { + #region Private Variables + private static string TextElementName = "text"; + private static string BodyTag = "body"; + #endregion + + #region Internal Implementation + public static BodyElement Parse(string text) + { + StringBuilder plainText = new StringBuilder(text.Length); + BodyElement root = new BodyElement(); + root.HasExpandElement = false; + MarkupElement currentParent = root; + Stack openTags = new Stack(); + openTags.Push(root); + // Input text is not wrapped into the container tag so we wrap it here + text = text.Replace(" ", "{ent_nbsp}"); + text = text.Replace("&zwsp;", "{ent_zwsp}"); + text = text.Replace("<", "{ent_lt}"); + text = text.Replace(">", "{ent_gt}"); + text = text.Replace("&", "{ent_amp}"); + text = text.Replace("|", "{ent_l}"); + text = text.Replace("&", "|"); + text = text.Replace("{ent_nbsp}", " "); + text = text.Replace("{ent_zwsp}", "&zwsp;"); + text = text.Replace("{ent_lt}", "<"); + text = text.Replace("{ent_gt}", ">"); + StringReader sr = new StringReader("<"+BodyTag+">" + text + ""); +#if !DEBUG + try +#endif + { + XmlTextReader reader = new XmlTextReader(sr); + //reader.EntityHandling = EntityHandling.ExpandCharEntities; + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element) + { + if (reader.Name == BodyTag) + continue; + MarkupElement el = CreateMarkupElement(reader.Name); + if (el == null) + { + reader.Skip(); + continue; + } + else if (el is ExpandElement) + root.HasExpandElement = true; + + if (el is IActiveMarkupElement) + root.ActiveElements.Add(el); + + // Parse any attributes here + if (reader.AttributeCount > 0) + { + el.ReadAttributes(reader); + reader.MoveToElement(); + } + + currentParent.Elements.Add(el); + + if (el is ContainerElement) + currentParent = el; + + if (!reader.IsEmptyElement) + openTags.Push(el); + } + else if (reader.NodeType == XmlNodeType.Text) + { + if (reader.Value.Length == 1) + { + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + if (reader.Value == " ") + { + el.TrailingSpace = true; + plainText.Append(' '); + } + else + { + el.Text = reader.Value; + el.Text = el.Text.Replace("|", "&"); + el.Text = el.Text.Replace("{ent_l}", "|"); + el.Text = el.Text.Replace("{ent_amp}", "&&"); + plainText.Append(el.Text+" "); + } + currentParent.Elements.Add(el); + } + else + { + string s = reader.Value; + if (s.StartsWith("\r\n")) + s = s.TrimStart(new char[] { '\r', '\n' }); + s = s.Replace("\r\n", " "); + string[] words = s.Split(' '); + bool space = false; + if (currentParent.Elements.Count > 0 && currentParent.Elements[currentParent.Elements.Count - 1] is NewLine) + space = true; + for (int i = 0; i < words.Length; i++) + { + if (words[i].Length == 0) + { + if (space) + continue; + space = true; + } + else + space = false; + + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + el.Text = words[i].Replace("|","&"); + el.Text = el.Text.Replace("{ent_l}", "|"); + el.Text = el.Text.Replace("{ent_amp}", "&&"); + plainText.Append(el.Text + " "); + if (i < words.Length - 1) + { + el.TrailingSpace = true; + space = true; + } + + currentParent.Elements.Add(el); + } + } + } + else if (reader.NodeType == XmlNodeType.Whitespace) + { + if (reader.Value.IndexOf(' ') >= 0) + { + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + el.TrailingSpace = true; + currentParent.Elements.Add(el); + } + } + else if (reader.NodeType == XmlNodeType.EntityReference) + { + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + if (reader.Name == "nbsp") + { + el.TrailingSpace = true; + } + else if (reader.Name == "zwsp") + { + el.TrailingSpace = false; + } + else + el.Text = reader.Name; + el.EnablePrefixHandling = false; + currentParent.Elements.Add(el); + } + else if (reader.NodeType == XmlNodeType.EndElement) + { + MarkupElement el = openTags.Pop() as MarkupElement; + if (el != currentParent) + { + currentParent.Elements.Add(new EndMarkupElement(el)); + } + else + { + if (currentParent != root) + currentParent = currentParent.Parent; + } + } + } + } +#if !DEBUG + catch + { + return null; + } +#endif + root.PlainText = plainText.ToString(); + return root; + } + + public static MarkupElement CreateMarkupElement(string elementName) + { + if (elementName == "b" || elementName == "strong") + return new Strong(); + else if (elementName == "i" || elementName == "em") + return new Italic(); + else if (elementName == "u") + return new Underline(); + else if (elementName == "br") + return new NewLine(); + else if (elementName == "expand") + return new ExpandElement(); + else if (elementName == "a") + return new HyperLink(); + else if (elementName == "p") + return new Paragraph(); + else if (elementName == "div") + return new Div(); + else if (elementName == "span") + return new Span(); + else if (elementName == "img") + return new ImageElement(); + else if (elementName == "h1") + return new Heading(); + else if (elementName == "h2") + return new Heading(2); + else if (elementName == "h3") + return new Heading(3); + else if (elementName == "h4") + return new Heading(4); + else if (elementName == "h5") + return new Heading(5); + else if (elementName == "h6") + return new Heading(6); + else if (elementName == "font") + return new FontElement(); + else if (elementName == "s" || elementName == "strike") + return new Strike(); + else if (elementName == TextElementName) + return new TextElement(); + else if (elementName == "symbol") + return new SymbolElement(); + + return null; + } + + /// + /// Tests whether input text could be markup text. + /// + /// Text to test. + /// true if text could be markup, otherwise false + public static bool IsMarkup(ref string text) + { + if (text.IndexOf("") < 0) + return false; + return true; + } + + internal static string RemoveExpand(string text) + { + return Regex.Replace(text, "", "", RegexOptions.IgnoreCase); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupSettings.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupSettings.cs new file mode 100644 index 00000000..1f4e47d9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/MarkupSettings.cs @@ -0,0 +1,189 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ +#if FRAMEWORK20 + public static class MarkupSettings +#else + public class MarkupSettings +#endif + { + private static HyperlinkStyle _NormalHyperlink = new HyperlinkStyle(Color.Blue, eHyperlinkUnderlineStyle.SolidLine); + /// + /// Gets the style of the hyperlink in its default state. + /// + public static HyperlinkStyle NormalHyperlink + { + get { return _NormalHyperlink; } + } + + private static HyperlinkStyle _MouseOverHyperlink = new HyperlinkStyle(); + /// + /// Gets the style of the hyperlink when mouse is over the link. + /// + public static HyperlinkStyle MouseOverHyperlink + { + get { return _MouseOverHyperlink; } + } + + private static HyperlinkStyle _VisitedHyperlink = new HyperlinkStyle(); + /// + /// Gets the style of the visited hyperlink. + /// + public static HyperlinkStyle VisitedHyperlink + { + get { return _VisitedHyperlink; } + } + + /// + /// Represents the method that will handle the ResolveImage event. + /// + public delegate void ResolveImageEventHandler(object sender, ResolveImageEventArgs e); + // + /// Occurs when DotNetBar is looking for an image for one of the internal img tags that is + /// used within the minimarkup. You need to set Handled=true if you want your custom image + /// to be used instead of the built-in resource resolving mechanism. + /// + public static event ResolveImageEventHandler ResolveImage; + internal static void InvokeResolveImage(ResolveImageEventArgs e) + { + if (ResolveImage != null) + ResolveImage(null, e); + } + } + + /// + /// Defines the text-markup hyperlink appearance style. + /// + public class HyperlinkStyle + { + /// + /// Initializes a new instance of the HyperlinkStyle class. + /// + public HyperlinkStyle() + { + } + + /// + /// Initializes a new instance of the HyperlinkStyle class. + /// + /// + /// + public HyperlinkStyle(Color textColor, eHyperlinkUnderlineStyle underlineStyle) + { + _TextColor = textColor; + _UnderlineStyle = underlineStyle; + } + + /// + /// Initializes a new instance of the HyperlinkStyle class. + /// + /// + /// + /// + public HyperlinkStyle(Color textColor, Color backColor, eHyperlinkUnderlineStyle underlineStyle) + { + _TextColor = textColor; + _BackColor = backColor; + _UnderlineStyle = underlineStyle; + } + private Color _TextColor = Color.Empty; + /// + /// Gets or sets hyperlink text color. + /// + public Color TextColor + { + get { return _TextColor; } + set + { + if (_TextColor != value) + { + _TextColor = value; + } + } + } + + private Color _BackColor = Color.Empty; + /// + /// Gets or sets hyperlink back color. + /// + public Color BackColor + { + get { return _BackColor; } + set + { + if (_BackColor != value) + { + _BackColor = value; + } + } + } + + private eHyperlinkUnderlineStyle _UnderlineStyle = eHyperlinkUnderlineStyle.None; + /// + /// Gets or sets the underline style for the hyperlink. + /// + public eHyperlinkUnderlineStyle UnderlineStyle + { + get { return _UnderlineStyle; } + set + { + if (_UnderlineStyle != value) + { + _UnderlineStyle = value; + } + } + } + + /// + /// Gets whether style has been changed from its default state. + /// + public bool IsChanged + { + get { return !_TextColor.IsEmpty || !_BackColor.IsEmpty || _UnderlineStyle != eHyperlinkUnderlineStyle.None; } + } + } + + public enum eHyperlinkUnderlineStyle + { + None, + SolidLine, + DashedLine + } + + /// + /// + /// Event arguments for ResolveImage event. + /// + public class ResolveImageEventArgs : EventArgs + { + /// + /// Indicates that event has been handled and that ResolvedImage should be used. + /// + public bool Handled = false; + /// + /// Indicates the string key parameters in url-style for the image that needs to be resolved. + /// + public string Key = ""; + /// + /// Indicates the resolved image value. + /// you need to set this value to the resolved image and you need to set Handled property to true. + /// + public Image ResolvedImage = null; + /// + /// Default constructor. + /// + public ResolveImageEventArgs() { } + } + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/NewLine.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/NewLine.cs new file mode 100644 index 00000000..74085447 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/NewLine.cs @@ -0,0 +1,47 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class NewLine : MarkupElement + { + #region Internal Implementation + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + // Causes layout manager to switch to the new line + this.Bounds = new Rectangle(0, 0, 0, d.CurrentFont.Height); + } + + /// + /// Gets or sets whether element size is valid. When size is not valid element Measure method will be called to validate size. + /// + public override bool IsSizeValid + { + get { return false; } + set { } + } + + public override void Render(MarkupDrawContext d) {} + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + /// + /// Returns whether layout manager switches to new line after processing this element. + /// + public override bool IsNewLineAfterElement + { + get { return true; } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Paragraph.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Paragraph.cs new file mode 100644 index 00000000..e1bac6f6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Paragraph.cs @@ -0,0 +1,29 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class Paragraph : Div + { + #region Internal Implementation + protected override void ArrangeInternal(Rectangle bounds, MarkupDrawContext d) + { + base.ArrangeInternal(bounds, d); + this.Bounds = new Rectangle(this.Bounds.X, this.Bounds.Y, this.Bounds.Width , this.Bounds.Height + d.CurrentFont.Height); + } + #endregion + } + + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Span.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Span.cs new file mode 100644 index 00000000..1947de36 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Span.cs @@ -0,0 +1,25 @@ +using System; +using System.Text; + +#if AdvTree +using DevComponents.Tree; +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class Span : Div + { + /// + /// Returns whether markup element is an block element that always consumes a whole line in layout. + /// + public override bool IsBlockElement + { + get { return false; } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Strike.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Strike.cs new file mode 100644 index 00000000..0d49fd04 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Strike.cs @@ -0,0 +1,36 @@ +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class Strike : MarkupElement + { + public override void Measure(Size availableSize, MarkupDrawContext d) + { + Bounds = Rectangle.Empty; + } + + public override void Render(MarkupDrawContext d) + { + d.StrikeOut = true; + } + + public override void RenderEnd(MarkupDrawContext d) + { + d.StrikeOut = false; + + base.RenderEnd(d); + } + + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) + { + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Strong.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Strong.cs new file mode 100644 index 00000000..c63ba948 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Strong.cs @@ -0,0 +1,35 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class Strong : FontChangeElement + { + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + FontStyle style = d.CurrentFont.Style | FontStyle.Bold; + + if (!font.Bold && font.FontFamily.IsStyleAvailable(style)) + d.CurrentFont = new Font(d.CurrentFont, style); + else + font = null; + + if (font != null) + m_OldFont = font; + + base.SetFont(d); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/SymbolElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/SymbolElement.cs new file mode 100644 index 00000000..f91c0b0e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/SymbolElement.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Xml; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class SymbolElement : MarkupElement + { + #region Internal Implementation + private Size _DefaultSize = new Size(16, 16); + private eSymbol _Symbol = eSymbol.XInCircle; + + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + this.Bounds = new Rectangle(Point.Empty, _DefaultSize); + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Graphics g = d.Graphics; + Color color = d.CurrentForeColor; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + if (_Symbol == eSymbol.XInCircle) + { + Rectangle sr = new Rectangle(r.X + (r.Width - 14) / 2, r.Y + (r.Height - 14) / 2, 14, 14); + using (Pen pen = new Pen(color, 1.51f)) + { + //sr.Width-=2; + //sr.Height-=2; + g.DrawEllipse(pen, sr); + g.DrawLine(pen, sr.X + 4, sr.Y + 4, sr.X + 10, sr.Y + 10); + g.DrawLine(pen, sr.X + 10, sr.Y + 4, sr.X + 4, sr.Y + 10); + } + } + + g.SmoothingMode = sm; + + this.RenderBounds = r; + } + + public override void ReadAttributes(XmlTextReader reader) + { + _Symbol = eSymbol.XInCircle; + + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "type") + { + string s = reader.Value.ToLower(); + if (s == "xincircle") + _Symbol = eSymbol.XInCircle; + break; + } + } + } + + private enum eSymbol + { + XInCircle + } + + /// + /// Returns whether layout manager can start new line with this element. + /// + public override bool CanStartNewLine + { + get { return false; } + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/TextElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/TextElement.cs new file mode 100644 index 00000000..fb2c5797 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/TextElement.cs @@ -0,0 +1,224 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class TextElement : MarkupElement + { + private static bool PadText = false; + static TextElement() + { + string lc = System.Windows.Forms.Application.CurrentCulture.TwoLetterISOLanguageName; + if (lc == "ja") + PadText = true; + } + #region Private Variables + private string m_Text = ""; + private bool m_TrailingSpace = false; + private bool m_EnablePrefixHandling = true; + #endregion + + #region Internal Implementation + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { +#if (FRAMEWORK20) + if (BarUtilities.UseTextRenderer) + { + eTextFormat format = eTextFormat.Default | eTextFormat.NoPadding; + if (!d.HotKeyPrefixVisible || m_EnablePrefixHandling) + format |= eTextFormat.HidePrefix; + Size size = Size.Empty; + if (m_TrailingSpace) + { + if (d.CurrentFont.Italic) + { + size = Size.Ceiling(TextDrawing.MeasureString(d.Graphics, m_Text, d.CurrentFont, 0, format)); + size.Width += (int)(d.Graphics.MeasureString("||", d.CurrentFont).Width / 4); + } + else + size = Size.Ceiling(TextDrawing.MeasureString(d.Graphics, m_Text + (BarFunctions.IsVista && m_Text.Length > 0 ? "|" : "||"), d.CurrentFont, 0, format)); + } + else + size = Size.Ceiling(TextDrawing.MeasureString(d.Graphics, m_Text, d.CurrentFont, 0, format)); + if (PadText) + { + size.Width += BarUtilities.TextMarkupCultureSpecificPadding; + size.Height += BarUtilities.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + else +#endif + { + using (StringFormat format = new StringFormat(StringFormat.GenericTypographic)) + { + format.FormatFlags = StringFormatFlags.NoWrap; + if (d.HotKeyPrefixVisible || !m_EnablePrefixHandling) + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; + else + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide; + + if (m_TrailingSpace) + { + if (d.CurrentFont.Italic) + { + Size size = Size.Ceiling(d.Graphics.MeasureString(m_Text, d.CurrentFont, 0, format)); + size.Width += (int)(d.Graphics.MeasureString("|", d.CurrentFont).Width / 4); + if (PadText) + { + size.Width += BarUtilities.TextMarkupCultureSpecificPadding; + size.Height += BarUtilities.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + else + { + Size size = Size.Ceiling(d.Graphics.MeasureString(m_Text + "|", d.CurrentFont, 0, format)); + if (PadText) + { + size.Width += BarUtilities.TextMarkupCultureSpecificPadding; + size.Height += BarUtilities.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + } + else + { + Size size = Size.Ceiling(d.Graphics.MeasureString(m_Text, d.CurrentFont, 0, format)); + if (PadText) + { + size.Width += BarUtilities.TextMarkupCultureSpecificPadding; + size.Height += BarUtilities.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + } + } + IsSizeValid = true; + } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Graphics g = d.Graphics; + #if (FRAMEWORK20) + if (BarUtilities.UseTextRenderer) + { + eTextFormat format = eTextFormat.Default | eTextFormat.NoClipping | eTextFormat.NoPadding; + if (d.RightToLeft) format |= eTextFormat.RightToLeft; + if (!d.HotKeyPrefixVisible) + format |= eTextFormat.HidePrefix; + + if (!d.ClipRectangle.IsEmpty && r.Right > d.ClipRectangle.Right) + { + format|= eTextFormat.EndEllipsis; + r.Width -= (r.Right - d.ClipRectangle.Right); + } + TextDrawing.DrawString(g, m_Text, d.CurrentFont, d.CurrentForeColor, r, format); + + } + else + #endif + { + using (StringFormat format = new StringFormat(StringFormat.GenericTypographic)) + { + format.FormatFlags |= StringFormatFlags.NoWrap; + if (d.RightToLeft) format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + if (d.HotKeyPrefixVisible) + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; + else + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide; + if (!d.ClipRectangle.IsEmpty && r.Right > d.ClipRectangle.Right) + { + format.Trimming = StringTrimming.EllipsisCharacter; + r.Width -= (r.Right - d.ClipRectangle.Right); + } + + using (SolidBrush brush = new SolidBrush(d.CurrentForeColor)) + g.DrawString(m_Text, d.CurrentFont, brush, r, format); + } + } + + if (d.StrikeOut == true) + { + // StrikeOut + + float descent = d.CurrentFont.FontFamily.GetCellDescent(d.CurrentFont.Style) * + d.CurrentFont.Size / d.CurrentFont.FontFamily.GetEmHeight(d.CurrentFont.Style) + 1; + + using (Pen pen = new Pen(d.CurrentForeColor, 1)) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + + float y = r.Top + (r.Height + descent) / 2; + + g.DrawLine(pen, r.X, y, r.Right - 1, y); + g.SmoothingMode = sm; + } + } + + if ((d.HyperLink && (d.HyperlinkStyle == null || d.HyperlinkStyle.UnderlineStyle != eHyperlinkUnderlineStyle.None)) || d.Underline) + { + // Underline Hyperlink + float descent = d.CurrentFont.FontFamily.GetCellDescent(d.CurrentFont.Style) * d.CurrentFont.Size / d.CurrentFont.FontFamily.GetEmHeight(d.CurrentFont.Style); + using (Pen pen = new Pen(d.CurrentForeColor, 1)) + { + if (d.HyperLink && d.HyperlinkStyle != null && d.HyperlinkStyle.UnderlineStyle == eHyperlinkUnderlineStyle.DashedLine) + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; + descent -= 1; + System.Drawing.Drawing2D.SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + g.DrawLine(pen, r.X, r.Bottom - descent, r.Right - 1, r.Bottom - descent); + g.SmoothingMode = sm; + } + } + + this.RenderBounds = r; + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) {} + + public string Text + { + get { return m_Text; } + set + { + m_Text = value; + this.IsSizeValid = false; + } + } + + public bool TrailingSpace + { + get { return m_TrailingSpace; } + set + { + m_TrailingSpace = value; + this.IsSizeValid = false; + } + } + + public bool EnablePrefixHandling + { + get { return m_EnablePrefixHandling; } + set { m_EnablePrefixHandling = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Underline.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Underline.cs new file mode 100644 index 00000000..1343a8cb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/TextMarkup/Underline.cs @@ -0,0 +1,48 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout.TextMarkup +#endif +{ + internal class Underline : FontChangeElement + { + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + d.Underline = true; + //Font font = d.CurrentFont; + //FontStyle style = d.CurrentFont.Style | FontStyle.Underline; + + //if (!font.Underline && font.FontFamily.IsStyleAvailable(style)) + // d.CurrentFont = new Font(font, style); + //else + // font = null; + + //if (font != null) + // m_OldFont = font; + + base.SetFont(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + d.Underline = false; + base.MeasureEnd(availableSize, d); + } + + public override void RenderEnd(MarkupDrawContext d) + { + d.Underline = false; + base.RenderEnd(d); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Thickness.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Thickness.cs new file mode 100644 index 00000000..8c3eb740 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/Thickness.cs @@ -0,0 +1,376 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.ComponentModel; +using System.Globalization; +using System.Drawing; +using System.Collections; +using System.Reflection; +using System.ComponentModel.Design.Serialization; + +namespace DevComponents.DotNetBar.Layout +{ + /// + /// Defines Thickness structure used by borders and margins. + /// + [StructLayout(LayoutKind.Sequential), TypeConverter(typeof(ThicknessConverter))] + public struct Thickness : IEquatable + { + #region Constructor + private double _Left; + private double _Top; + private double _Right; + private double _Bottom; + + /// + /// Creates new instance of the object. + /// + /// Uniform Thickness + public Thickness(double uniformThickness) + { + _Left = _Top = _Right = _Bottom = uniformThickness; + } + /// + /// Creates new instance of the object. + /// + /// Left Thickness + /// Top Thickness + /// Right Thickness + /// Bottom Thickness + public Thickness(double left, double top, double right, double bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + } + #endregion + + #region Implementation + /// + /// Gets whether object equals to this instance. + /// + /// object to test. + /// returns whether objects are Equals + public override bool Equals(object obj) + { + if (obj is Thickness) + { + Thickness thickness = (Thickness)obj; + return (this == thickness); + } + return false; + } + /// + /// Gets whether object equals to this instance. + /// + /// object to test. + /// returns whether objects are Equals + public bool Equals(Thickness thickness) + { + return (this == thickness); + } + /// + /// Returns hash code for object. + /// + /// Hash code + public override int GetHashCode() + { + return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^ _Right.GetHashCode()) ^ _Bottom.GetHashCode()); + } + + const string StringValueSeparator = ","; + /// + /// Returns string representation of object. + /// + /// string representing Thickness + public override string ToString() + { + return Convert.ToString(_Left) + StringValueSeparator + Convert.ToString(_Top) + StringValueSeparator + Convert.ToString(_Right) + StringValueSeparator + Convert.ToString(_Bottom); + } + /// + /// Gets string representation of object. + /// + /// Culture info. + /// string representing Thickness + internal string ToString(CultureInfo cultureInfo) + { + return Convert.ToString(_Left, cultureInfo) + StringValueSeparator + Convert.ToString(_Top, cultureInfo) + StringValueSeparator + Convert.ToString(_Right, cultureInfo) + StringValueSeparator + Convert.ToString(_Bottom, cultureInfo); + } + /// + /// Returns whether all values are zero. + /// + [Browsable(false)] + public bool IsZero + { + get + { + return (((DoubleHelpers.IsZero(this.Left) && DoubleHelpers.IsZero(this.Top)) && DoubleHelpers.IsZero(this.Right)) && DoubleHelpers.IsZero(this.Bottom)); + } + } + /// + /// Returns whether all values are the same. + /// + [Browsable(false)] + public bool IsUniform + { + get + { + return ((DoubleHelpers.AreClose(this.Left, this.Top) && DoubleHelpers.AreClose(this.Left, this.Right)) && DoubleHelpers.AreClose(this.Left, this.Bottom)); + } + } + /// + /// Returns whether object holds valid value. + /// + /// Specifies whether negative values are allowed. + /// Specifies whether NaN values are allowed. + /// Specifies whether positive infinity values are allowed + /// Specifies whether negative infinity values are allowed + /// true if object holds valid value + internal bool IsValid(bool allowNegative, bool allowNaN, bool allowPositiveInfinity, bool allowNegativeInfinity) + { + if (!allowNegative && (((this.Left < 0.0) || (this.Right < 0.0)) || ((this.Top < 0.0) || (this.Bottom < 0.0)))) + { + return false; + } + if (!allowNaN && ((DoubleHelpers.IsNaN(this.Left) || DoubleHelpers.IsNaN(this.Right)) || (DoubleHelpers.IsNaN(this.Top) || DoubleHelpers.IsNaN(this.Bottom)))) + { + return false; + } + if (!allowPositiveInfinity && ((double.IsPositiveInfinity(this.Left) || double.IsPositiveInfinity(this.Right)) || (double.IsPositiveInfinity(this.Top) || double.IsPositiveInfinity(this.Bottom)))) + { + return false; + } + return (allowNegativeInfinity || ((!double.IsNegativeInfinity(this.Left) && !double.IsNegativeInfinity(this.Right)) && (!double.IsNegativeInfinity(this.Top) && !double.IsNegativeInfinity(this.Bottom)))); + } + /// + /// Returns true if two objects are close. + /// + /// Thickness to test. + /// true if values are close. + internal bool IsClose(Thickness thickness) + { + return (((DoubleHelpers.AreClose(this.Left, thickness.Left) && DoubleHelpers.AreClose(this.Top, thickness.Top)) && DoubleHelpers.AreClose(this.Right, thickness.Right)) && DoubleHelpers.AreClose(this.Bottom, thickness.Bottom)); + } + /// + /// Returns true if two objects are close. + /// + /// Thickness 1 + /// Thickness 2 + /// true if values are close. + internal static bool AreClose(Thickness thickness1, Thickness thickness2) + { + return thickness1.IsClose(thickness2); + } + + public static bool operator ==(Thickness t1, Thickness t2) + { + return (((((t1._Left == t2._Left) || (DoubleHelpers.IsNaN(t1._Left) && DoubleHelpers.IsNaN(t2._Left))) && ((t1._Top == t2._Top) || (DoubleHelpers.IsNaN(t1._Top) && DoubleHelpers.IsNaN(t2._Top)))) && ((t1._Right == t2._Right) || (DoubleHelpers.IsNaN(t1._Right) && DoubleHelpers.IsNaN(t2._Right)))) && ((t1._Bottom == t2._Bottom) || (DoubleHelpers.IsNaN(t1._Bottom) && DoubleHelpers.IsNaN(t2._Bottom)))); + } + + public static bool operator !=(Thickness t1, Thickness t2) + { + return !(t1 == t2); + } + /// + /// Gets or sets the left Thickness. + /// + public double Left + { + get + { + return _Left; + } + set + { + _Left = value; + } + } + /// + /// Gets or sets the top Thickness. + /// + public double Top + { + get + { + return _Top; + } + set + { + _Top = value; + } + } + /// + /// Gets or sets the Right Thickness. + /// + public double Right + { + get + { + return _Right; + } + set + { + _Right = value; + } + } + /// + /// Gets or sets the Bottom Thickness. + /// + public double Bottom + { + get + { + return _Bottom; + } + set + { + _Bottom = value; + } + } + + /// + /// Gets the total horizontal thickness i.e. Left+Right. + /// + [Browsable(false)] + public double Horizontal + { + get + { + return _Left + _Right; + } + } + /// + /// Gets the total vertical thickness i.e. Top+Bottom. + /// + [Browsable(false)] + public double Vertical + { + get + { + return _Top + _Bottom; + } + } + #endregion + } + + #region ThicknessConverter + /// + /// Provides Thickness TypeConverter. + /// + public class ThicknessConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType)); + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType)); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + string str = value as string; + if (str == null) + { + return base.ConvertFrom(context, culture, value); + } + string str2 = str.Trim(); + if (str2.Length == 0) + { + return new Thickness(); + } + if (culture == null) + { + culture = CultureInfo.CurrentCulture; + } + char ch = culture.TextInfo.ListSeparator[0]; + string[] strArray = str2.Split(new char[] { ch }); + double[] numArray = new double[strArray.Length]; + TypeConverter converter = TypeDescriptor.GetConverter(typeof(double)); + for (int i = 0; i < numArray.Length; i++) + { + numArray[i] = (double)converter.ConvertFromString(context, culture, strArray[i]); + } + if (numArray.Length != 4) + { + throw new ArgumentException("Text Parsing Failed"); + } + return new Thickness(numArray[0], numArray[1], numArray[2], numArray[3]); + } + + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == null) + { + throw new ArgumentNullException("destinationType"); + } + if (value is Thickness) + { + if (destinationType == typeof(string)) + { + Thickness Thickness = (Thickness)value; + if (culture == null) + { + culture = CultureInfo.CurrentCulture; + } + string separator = culture.TextInfo.ListSeparator + " "; + TypeConverter converter = TypeDescriptor.GetConverter(typeof(double)); + string[] strArray = new string[4]; + int num = 0; + strArray[num++] = converter.ConvertToString(context, culture, Thickness.Left); + strArray[num++] = converter.ConvertToString(context, culture, Thickness.Top); + strArray[num++] = converter.ConvertToString(context, culture, Thickness.Right); + strArray[num++] = converter.ConvertToString(context, culture, Thickness.Bottom); + return string.Join(separator, strArray); + } + if (destinationType == typeof(InstanceDescriptor)) + { + Thickness Thickness2 = (Thickness)value; + ConstructorInfo constructor = typeof(Thickness).GetConstructor(new Type[] { typeof(double), typeof(double), typeof(double), typeof(double) }); + if (constructor != null) + { + return new InstanceDescriptor(constructor, new object[] { Thickness2.Left, Thickness2.Top, Thickness2.Right, Thickness2.Bottom }); + } + } + } + return base.ConvertTo(context, culture, value, destinationType); + } + + public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) + { + if (propertyValues == null) + { + throw new ArgumentNullException("propertyValues"); + } + object left = propertyValues["Left"]; + object top = propertyValues["Top"]; + object right = propertyValues["Right"]; + object bottom = propertyValues["Bottom"]; + if ((((left == null) || (top == null)) || ((right == null) || (bottom == null))) || ((!(left is double) || !(top is double)) || (!(right is double) || !(bottom is double)))) + { + throw new ArgumentException(string.Format("Property Value Invalid: left={0}, top={1}, right={2}, bottom={3}", left, top, right, bottom)); + } + return new Thickness((double)left, (double)top, (double)right, (double)bottom); + } + + public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) + { + return true; + } + + public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) + { + return TypeDescriptor.GetProperties(typeof(Thickness), attributes).Sort(new string[] { "Left", "Top", "Right", "Bottom" }); + } + + public override bool GetPropertiesSupported(ITypeDescriptorContext context) + { + return true; + } + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/WinApi.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/WinApi.cs new file mode 100644 index 00000000..c1e47230 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Layout/WinApi.cs @@ -0,0 +1,289 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Drawing; + +namespace DevComponents.DotNetBar.Layout +{ + internal static class WinApi + { + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); + [DllImport("gdi32")] + public static extern bool DeleteObject(IntPtr hObject); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern bool GetTextMetrics(HandleRef hdc, TEXTMETRIC tm); + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class TEXTMETRIC + { + public int tmHeight; + public int tmAscent; + public int tmDescent; + public int tmInternalLeading; + public int tmExternalLeading; + public int tmAveCharWidth; + public int tmMaxCharWidth; + public int tmWeight; + public int tmOverhang; + public int tmDigitizedAspectX; + public int tmDigitizedAspectY; + public char tmFirstChar; + public char tmLastChar; + public char tmDefaultChar; + public char tmBreakChar; + public byte tmItalic; + public byte tmUnderlined; + public byte tmStruckOut; + public byte tmPitchAndFamily; + public byte tmCharSet; + } + + [DllImport("user32")] + public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); + [DllImport("user32")] + public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); + public const int WM_SETREDRAW = 0x000B; + + public const int WM_LBUTTONDOWN = 0x0201; + public const int WM_LBUTTONUP = 0x0202; + public const int WM_RBUTTONDOWN = 0x0204; + public const int WM_RBUTTONUP = 0x0205; + public const int WM_MOUSEMOVE = 0x0200; + public const int WM_MOUSELEAVE = 0x02A3; + public const int WM_HSCROLL = 0x0114; + public const int WM_VSCROLL = 0x0115; + public const int WM_LBUTTONDBLCLK = 0x0203; + + public static int LOWORD(int n) + { + return (short)(n & 0xffff); + } + public static int HIWORD(int n) + { + return (int)((n >> 0x10) & 0xffff); + } + public static int LOWORD(IntPtr n) + { + return LOWORD((int)((long)n)); + } + public static int HIWORD(IntPtr n) + { + return unchecked((short)((uint)n >> 16)); + } + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] + public static extern int ScrollWindowEx(HandleRef hWnd, int nXAmount, int nYAmount, ref RECT rectScrollRegion, ref RECT rectClip, IntPtr hrgnUpdate, ref RECT prcUpdate, int flags); + [StructLayout(LayoutKind.Sequential)] + public struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + public RECT(int left, int top, int right, int bottom) + { + this.left = left; + this.top = top; + this.right = right; + this.bottom = bottom; + } + + public RECT(Rectangle r) + { + this.left = r.Left; + this.top = r.Top; + this.right = r.Right; + this.bottom = r.Bottom; + } + + public static RECT FromXYWH(int x, int y, int width, int height) + { + return new RECT(x, y, x + width, y + height); + } + + public Size Size + { + get + { + return new Size(this.right - this.left, this.bottom - this.top); + } + } + } + internal static bool ModifyHwndStyle(IntPtr hwnd, int removeStyle, int addStyle) + { + int curWindowStyle = GetWindowLongPtr(hwnd, (int)GWL.GWL_STYLE).ToInt32(); + int newStyle = (curWindowStyle & ~removeStyle) | addStyle; + if (curWindowStyle == newStyle) + { + return false; + } + + SetWindowLong(hwnd, (int)GWL.GWL_STYLE, newStyle); + return true; + } + // This static method is required because legacy OSes do not support + // GetWindowLongPtr + public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex) + { + if (IntPtr.Size == 8) + return GetWindowLongPtr64(hWnd, nIndex); + else + return new IntPtr(GetWindowLong32(hWnd, nIndex)); + } + + [DllImport("user32.dll", EntryPoint = "GetWindowLong")] + public static extern int GetWindowLong32(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")] + public static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll")] + public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + + public static IntPtr SetWindowLongPtr(IntPtr hwnd, int nIndex, IntPtr dwNewLong) + { + if (IntPtr.Size == 8) + { + return SetWindowLongPtr64(hwnd, nIndex, dwNewLong); + } + return new IntPtr(SetWindowLongPtr32(hwnd, nIndex, dwNewLong.ToInt32())); + } + [DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)] + private static extern int SetWindowLongPtr32(IntPtr hWnd, int nIndex, int dwNewLong); + [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)] + private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong); + public enum GWL + { + GWL_WNDPROC = (-4), + GWL_HINSTANCE = (-6), + GWL_HWNDPARENT = (-8), + GWL_STYLE = (-16), + GWL_EXSTYLE = (-20), + GWL_USERDATA = (-21), + GWL_ID = (-12) + } + + public enum RedrawWindowFlags : uint + { + RDW_INVALIDATE = 0x0001, + RDW_INTERNALPAINT = 0x0002, + RDW_ERASE = 0x0004, + RDW_VALIDATE = 0x0008, + RDW_NOINTERNALPAINT = 0x0010, + RDW_NOERASE = 0x0020, + RDW_NOCHILDREN = 0x0040, + RDW_ALLCHILDREN = 0x0080, + RDW_UPDATENOW = 0x0100, + RDW_ERASENOW = 0x0200, + RDW_FRAME = 0x0400, + RDW_NOFRAME = 0x0800 + } + [Flags()] + public enum WindowStyles + { + WS_VISIBLE = 0x10000000, + WS_CAPTION = 0x00C00000, + WS_BORDER = 0x800000, + WS_DLGFRAME = 0x400000, + WS_THICKFRAME = 0x00040000, + WS_HSCROLL = 0x100000, + WS_VSCROLL = 0x200000 + } + + [StructLayout(LayoutKind.Sequential)] + public struct TRACKMOUSEEVENT + { + public int cbSize; + public uint dwFlags; + public int dwHoverTime; + public IntPtr hwndTrack; + } + [DllImport("user32")] + public static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT tme); + // Track Mouse Event Flags + public const uint + TME_HOVER = 0x00000001, + TME_LEAVE = 0x00000002, + TME_NONCLIENT = 0x00000010, + TME_QUERY = 0x40000000, + TME_CANCEL = 0x80000000, + HOVER_DEFAULT = 0xFFFFFFFF; + +#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\\{57FEED69-A5E0-45e7-8E02-5F4131F5EE63}\\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 + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentHView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentHView.cs new file mode 100644 index 00000000..8f2d5443 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentHView.cs @@ -0,0 +1,495 @@ +#if FRAMEWORK20 +using System; +using DevComponents.Schedule.Model; +using System.Drawing; +using DevComponents.WinForms.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Schedule +{ + public class AppointmentHView : AppointmentView + { + #region Private variables + private eViewEnds _ViewEnds = eViewEnds.Complete; + #endregion + + /// + /// Constructor + /// + /// + /// + public AppointmentHView(BaseView baseView, Appointment appointment) + : base(baseView, appointment) + { + } + + #region Private properties + + /// + /// Gets whether the appointment is mutable + /// + private bool IsMutable + { + get + { + return (IsSelected == true && + Appointment.Locked == false && + Appointment.IsRecurringInstance == false); + } + } + + #endregion + + #region Protected properties + + protected eViewEnds ViewEnds + { + get { return (_ViewEnds); } + set { _ViewEnds = value; } + } + + protected virtual Rectangle ParentBounds + { + get { return (Bounds); } + } + + #endregion + + #region Start/End TimeChanged event handling + + /// + /// Handles StartTime value changes + /// + /// CalendarItem + /// EventArgs + protected override void AppointmentView_StartTimeChanged(object sender, EventArgs e) + { + base.AppointmentView_StartTimeChanged(sender, e); + + SetViewEnds(); + } + + /// + /// Handles EndTime value changes + /// + /// CalendarItem + /// EventArgs + protected override void AppointmentView_EndTimeChanged(object sender, EventArgs e) + { + base.AppointmentView_EndTimeChanged(sender, e); + + SetViewEnds(); + } + + #endregion + + #region SetViewEnds + + /// + /// Sets the view display end types + /// + protected virtual void SetViewEnds() + { + _ViewEnds = eViewEnds.Complete; + } + + #endregion + + #region Appointment rendering + + /// + /// Paint processing + /// + /// ItemPaintArgs + public override void Paint(ItemPaintArgs e) + { + SetViewEnds(); + + AppointmentColor.SetColorTable(); + + int n = (Bounds.Width < 20) ? 0 : 5; + + CornerRadius cornerRadius = new CornerRadius(n); + Rectangle r = GetViewRect(ref cornerRadius); + + if (r.Width > 1 && r.Height > 0) + { + if (EffectiveStyle == eDotNetBarStyle.Office2010 || StyleManager.IsMetro(EffectiveStyle)) + DrawMetroAppointment(e, r); + else + DrawDefaultAppointment(e, r, n, cornerRadius); + + if (IsMutable == true) + DrawGribits(e, r); + } + } + + #region DrawMetroAppointment + + private void DrawMetroAppointment(ItemPaintArgs e, Rectangle r) + { + Graphics g = e.Graphics; + + using (Brush br = BackBrush(r)) + e.Graphics.FillRectangle(br, r); + + if (BaseView.CalendarView.DoAppointmentViewPreRender(this, g, r, null) == false) + { + DrawContent(e, r); + + BaseView.CalendarView.DoAppointmentViewPostRender(this, g, r, null); + } + + DrawMetroBorder(e, r); + } + + #region DrawMetroBorder + + private void DrawMetroBorder(ItemPaintArgs e, Rectangle r) + { + Graphics g = e.Graphics; + + if ((_ViewEnds & eViewEnds.PartialLeft) != eViewEnds.PartialLeft) + { + if (r.Width > 10) + DrawTimeMarker(g, r, 0); + } + + if (IsSelected == true) + { + if (r.Width > 10) + { + using (Pen pen = new Pen(Color.Black, 2)) + g.DrawRectangle(pen, r); + } + else + { + g.DrawRectangle(Pens.Black, r); + } + } + else + { + using (Pen pen = BorderPen) + g.DrawRectangle(pen, r); + } + } + + #endregion + + #endregion + + #region DrawDefaultAppointment + + private void DrawDefaultAppointment(ItemPaintArgs e, + Rectangle r, int n, CornerRadius cornerRadius) + { + Graphics g = e.Graphics; + + using (GraphicsPath path = GetItemPath(r, n * 2, cornerRadius)) + { + using (Brush br = BackBrush(r)) + g.FillPath(br, path); + + if (BaseView.CalendarView.DoAppointmentViewPreRender(this, g, r, path) == false) + { + DrawContent(e, r); + + BaseView.CalendarView.DoAppointmentViewPostRender(this, g, r, path); + } + + DrawDefaultBorder(e, r, path, n); + } + } + + #region DrawDefaultBorder + + private void DrawDefaultBorder(ItemPaintArgs e, + Rectangle r, GraphicsPath path, int n) + { + Graphics g = e.Graphics; + + if ((_ViewEnds & eViewEnds.PartialLeft) != eViewEnds.PartialLeft) + { + if (r.Width > 10) + DrawTimeMarker(g, r, n); + } + + if (IsSelected == true) + { + if (r.Width > 10) + { + using (Pen pen = SelectedBorderPen) + g.DrawPath(pen, path); + } + else + { + g.DrawPath(Pens.Black, path); + } + } + else + { + using (Pen pen = BorderPen) + g.DrawPath(pen, path); + } + } + + #endregion + + #endregion + + #region DrawContent + + private void DrawContent(ItemPaintArgs e, Rectangle r) + { + Image image = Image; + + Rectangle rText = r; + rText.X += 4; + rText.Width -= 6; + + if (Appointment.TimeMarkedAs != null) + { + rText.X += 4; + rText.Width -= 4; + } + + Rectangle rImage = GetItemBounds(rText, ref rText, image); + + DrawContentImage(e, r, rImage, image); + DrawContentText(e, rText); + } + + #region DrawContentText + + /// + /// DrawContentText + /// + /// + /// + private void DrawContentText(ItemPaintArgs e, Rectangle r) + { + Graphics g = e.Graphics; + + // Format the appointment text + + if (DisplayTemplateText(e, r) == false) + { + string s = (Appointment.IsMultiDayOrAllDayEvent) + ? Appointment.Subject + : String.Format("{0} {1}", Appointment.StartTime.ToShortTimeString(), Appointment.Subject); + + // Output the appointment text and + // appropriately weighted bounding path + + Font font = Font ?? e.Font; + const eTextFormat tf = eTextFormat.VerticalCenter | + eTextFormat.EndEllipsis | eTextFormat.NoPadding | eTextFormat.NoPrefix; + + if (r.Width > 10) + TextDrawing.DrawString(g, s, font, TextColor, r, tf); + + Size size = TextDrawing.MeasureString(g, s, font, r.Width, tf); + + IsTextClipped = (r.Width < size.Width || r.Height < size.Height); + } + } + + #endregion + + #endregion + + #region GetViewRect + + /// + /// Gets the view rect for the appointment + /// + /// Corner radius + /// View rect + private Rectangle GetViewRect(ref CornerRadius cornerRadius) + { + Rectangle r = DisplayRectangle; + + r.Intersect(ParentBounds); + + if (r.Left == ParentBounds.Left) + { + r.X++; + r.Width--; + } + + if ((_ViewEnds & eViewEnds.PartialLeft) == eViewEnds.PartialLeft) + cornerRadius.TopLeft = cornerRadius.BottomLeft = 0; + + if ((_ViewEnds & eViewEnds.PartialRight) == eViewEnds.PartialRight) + cornerRadius.TopRight = cornerRadius.BottomRight = 0; + + // If the view is selected, then allow + // for a thicker selection rect + + if (IsSelected == true) + r.Height--; + + return (r); + } + + #endregion + + #region GetItemPath + + /// + /// Gets a path defining the item + /// + /// + /// + /// + /// + private GraphicsPath GetItemPath(Rectangle viewRect, int radius, CornerRadius cornerRadius) + { + GraphicsPath path = new GraphicsPath(); + + Rectangle r = viewRect; + + Rectangle ar = new + Rectangle(r.Right - radius, r.Bottom - radius, radius, radius); + + if (cornerRadius.BottomRight > 0) + path.AddArc(ar, 0, 90); + else + path.AddLine(r.Right, r.Bottom, r.Right, r.Bottom); + + ar.X = r.X; + + if (cornerRadius.BottomLeft > 0) + path.AddArc(ar, 90, 90); + else + path.AddLine(r.Left, r.Bottom, r.Left, r.Bottom); + + ar.Y = r.Y; + + if (cornerRadius.TopLeft > 0) + path.AddArc(ar, 180, 90); + else + path.AddLine(r.Left, r.Top, r.Left, r.Top); + + ar.X = r.Right - radius; + + if (cornerRadius.TopRight > 0) + path.AddArc(ar, 270, 90); + else + path.AddLine(r.Right, r.Top, r.Right, r.Top); + + path.CloseAllFigures(); + + return (path); + } + + #endregion + + #region DrawGribits + + /// + /// Draws the resize gribits for the view + /// + /// + /// View rectangle + private void DrawGribits(ItemPaintArgs e, Rectangle r) + { + if (r.Width >= 8) + { + Graphics g = e.Graphics; + + Rectangle r2 = + new Rectangle(r.X, r.Y + (r.Height / 2) - 2, 5, 5); + + // Left gribit + + if ((_ViewEnds & eViewEnds.PartialLeft) == 0) + { + r2.X = r.X - 3; + + g.FillRectangle(Brushes.White, r2); + g.DrawRectangle(Pens.Black, r2); + } + + // Right gribit + + if ((_ViewEnds & eViewEnds.PartialRight) == 0) + { + r2.X = r.Right - 2; + + g.FillRectangle(Brushes.White, r2); + g.DrawRectangle(Pens.Black, r2); + } + } + } + + #endregion + + #endregion + + #region Mouse processing + + /// + /// Handles mouseDown processing + /// + /// MouseEventArgs + public override void InternalMouseMove(MouseEventArgs objArg) + { + HitArea = GetHitArea(objArg); + + base.InternalMouseMove(objArg); + } + + /// + /// Gets the HitArea from the current + /// mouse position + /// + /// + /// + private eHitArea GetHitArea(MouseEventArgs objArg) + { + if (IsMutable == true) + { + CornerRadius cornerRadius = new CornerRadius(5); + Rectangle r = GetViewRect(ref cornerRadius); + + //if (r.Width > 10) + { + Rectangle r2 = + new Rectangle(r.X, r.Y + (r.Height / 2) - 2, 5, 5); + + if ((_ViewEnds & eViewEnds.PartialLeft) == 0) + { + r2.X = r.X - 3; + + r2.Inflate(2, 2); + + if (r2.Contains(objArg.Location)) + return (eHitArea.LeftResize); + } + + if ((_ViewEnds & eViewEnds.PartialRight) == 0) + { + r2.X = r.Right - 2; + + r2.Inflate(2, 2); + + if (r2.Contains(objArg.Location)) + return (eHitArea.RightResize); + } + } + + // By default we are in the move area + + return (eHitArea.Move); + } + + return (eHitArea.None); + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentMonthView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentMonthView.cs new file mode 100644 index 00000000..a25c1d05 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentMonthView.cs @@ -0,0 +1,81 @@ +#if FRAMEWORK20 +using System; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class AppointmentMonthView : AppointmentHView + { + #region Constants + private const int DaysInWeek = 7; + #endregion + + #region Private variables + private MonthWeek _MonthWeek; + #endregion + + /// + /// Constructor + /// + /// + /// + public AppointmentMonthView(BaseView baseView, Appointment appointment) + : base(baseView, appointment) + { + } + + #region Public properties + + /// + /// Gets and sets View MonthWeek + /// + public MonthWeek MonthWeek + { + get { return (_MonthWeek); } + + set + { + if (_MonthWeek != value) + { + _MonthWeek = value; + + SetViewEnds(); + } + } + } + + #endregion + + #region SetViewEnds + + /// + /// Sets the view display end types + /// + protected override void SetViewEnds() + { + if (_MonthWeek != null) + { + DateTime start = _MonthWeek.FirstDayOfWeek; + DateTime end = start.AddDays(DaysInWeek); + + ViewEnds = eViewEnds.Complete; + + // Check to see if we can only display + // a partial representation for the view + + if (EndTime >= start && StartTime < end) + { + if (StartTime < start) + ViewEnds |= eViewEnds.PartialLeft; + + if (EndTime > end) + ViewEnds |= eViewEnds.PartialRight; + } + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentTimeLineView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentTimeLineView.cs new file mode 100644 index 00000000..51bd5963 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentTimeLineView.cs @@ -0,0 +1,81 @@ +#if FRAMEWORK20 +using DevComponents.Schedule.Model; +using System.Drawing; + +namespace DevComponents.DotNetBar.Schedule +{ + public class AppointmentTimeLineView : AppointmentHView + { + #region Private variables + private TimeLineView _TimeLineView; + #endregion + + /// + /// Constructor + /// + /// + /// + public AppointmentTimeLineView(BaseView baseView, Appointment appointment) + : base(baseView, appointment) + { + } + + #region Public properties + + public TimeLineView TimeLineView + { + get { return (_TimeLineView); } + + set + { + if (_TimeLineView != value) + { + _TimeLineView = value; + + if (_TimeLineView != null) + SetViewEnds(); + } + } + } + + #endregion + + #region SetViewEnds + + /// + /// Sets the view display end types + /// + protected override void SetViewEnds() + { + ViewEnds = eViewEnds.Complete; + + Rectangle r = DisplayRectangle; + Rectangle p = ParentBounds; + + if (r.Left < p.Left) + ViewEnds |= eViewEnds.PartialLeft; + + if (r.Right > p.Right) + ViewEnds |= eViewEnds.PartialRight; + } + + #endregion + + #region Protected properties + + protected override Rectangle ParentBounds + { + get + { + if (_TimeLineView != null) + return (_TimeLineView.ClientRect); + + return (base.ParentBounds); + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentView.cs new file mode 100644 index 00000000..ff573c06 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentView.cs @@ -0,0 +1,804 @@ +#if FRAMEWORK20 +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using DevComponents.DotNetBar.Rendering; +using DevComponents.DotNetBar.TextMarkup; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class AppointmentView : CalendarItem + { + #region enums + + [Flags] + public enum eViewEnds // View display ends + { + Complete = 0, + PartialLeft = 1, + PartialRight = 2 + } + + #endregion + + #region Static variables + + static private AppointmentColor _appointmentColor = new AppointmentColor(); + + #endregion + + #region Private variables + + private Font _Font; + private BaseView _BaseView; + private Appointment _Appointment; + private bool _IsTextClipped; + private int _BorderWidth; + + #endregion + + /// + /// Constructor + /// + /// + /// + public AppointmentView(BaseView baseView, Appointment appointment) + { + _BaseView = baseView; + _Appointment = appointment; + + MouseUpNotification = true; + + StartTime = appointment.StartTime; + EndTime = appointment.EndTime; + ModelItem = appointment; + + IsRecurring = (appointment.IsRecurringInstance == true || + appointment.Recurrence != null); + + RootItem = (appointment.IsRecurringInstance == true) ? + appointment.RootAppointment : appointment; + + StartTimeChanged += AppointmentView_StartTimeChanged; + EndTimeChanged += AppointmentView_EndTimeChanged; + } + + #region Public properties + + #region Appointment + + /// + /// Gets and sets the view Appointment + /// + public Appointment Appointment + { + get { return (_Appointment); } + set { _Appointment = value; } + } + + #endregion + + #region AppointmentColor + + /// + /// Gets and sets the appointment color + /// + public AppointmentColor AppointmentColor + { + get { return (_appointmentColor); } + set { _appointmentColor = value; } + } + + #endregion + + #region BorderWidth + + public int BorderWidth + { + get { return (_BorderWidth); } + + set + { + if (_BorderWidth != value) + { + _BorderWidth = value; + + Invalidate(_BaseView.CalendarView); + } + } + } + + #endregion + + #region Font + + /// + /// Gets and sets the view font + /// + public Font Font + { + get { return (_Font); } + set { _Font = value; } + } + + #endregion + + #region IsTextClipped + + /// + /// Gets whether the Appointment display Text is clipped + /// + public bool IsTextClipped + { + get { return (_IsTextClipped); } + internal set { _IsTextClipped = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region BaseView + + /// + /// BaseView + /// + internal BaseView BaseView + { + get { return (_BaseView); } + } + + #endregion + + #region Image + + /// + /// Image + /// + internal Image Image + { + get + { + if (string.IsNullOrEmpty(Appointment.ImageKey) == true) + return (null); + + ImageList images; + + switch (_BaseView.CalendarView.ImageSize) + { + case eBarImageSize.Medium: + images = _BaseView.CalendarView.ImagesMedium; + break; + + case eBarImageSize.Large: + images = _BaseView.CalendarView.ImagesLarge; + break; + + default: + images = _BaseView.CalendarView.Images; + break; + } + + return (images != null ? + images.Images[Appointment.ImageKey] : null); + } + } + + #endregion + + #endregion + + #region Start/End TimeChanged event handling + + /// + /// Handles StartTime value changes + /// + /// CalendarItem + /// EventArgs + protected virtual void AppointmentView_StartTimeChanged(object sender, EventArgs e) + { + _Appointment.StartTime = StartTime; + } + + /// + /// Handles EndTime value changes + /// + /// CalendarItem + /// EventArgs + protected virtual void AppointmentView_EndTimeChanged(object sender, EventArgs e) + { + _Appointment.EndTime = EndTime; + } + + #endregion + + #region DisplayTemplateText + + /// + /// DisplayTemplateText + /// + /// + /// + /// true is displayed + internal bool DisplayTemplateText(ItemPaintArgs e, Rectangle r) + { + if (_BaseView.CalendarView.EnableMarkup == true) + { + if (string.IsNullOrEmpty(Appointment.DisplayTemplate) == false) + { + Text = GetDisplayTemplateText(r); + } + else + { + string text = Appointment.Subject; + + if (IsUsingTextMarkup) + { + if (Appointment.IsMultiDayOrAllDayEvent == false) + text += "
" + Appointment.Description; + } + + Text = text; + } + + if (IsUsingTextMarkup) + { + Graphics g = e.Graphics; + + MarkupDrawContext d = + new MarkupDrawContext(g, Font ?? e.Font, TextColor, true); + + Size size = new Size(5000, 5000); + + TextMarkupBodyMeasure(size, d); + + d.RightToLeft = false; + + r.Y += 3; + r.Height -= 3; + + TextMarkupBodyArrange(new Rectangle(r.Location, TextMarkupBodyBounds.Size), d); + + _IsTextClipped = (TextMarkupBodyBounds.Size.Width > r.Width || + TextMarkupBodyBounds.Size.Height > r.Height); + + Region oldClip = g.Clip; + Rectangle clipRect = r; + + g.SetClip(clipRect, CombineMode.Intersect); + + TextMarkupBodyRender(d); + + g.Clip = oldClip; + + return (true); + } + } + + return (false); + } + + #endregion + + #region GetDisplayTemplateText + + /// + /// GetDisplayTemplateText + /// + /// + /// Templatized text + private string GetDisplayTemplateText(Rectangle r) + { + string s = Appointment.DisplayTemplate; + + if (String.IsNullOrEmpty(s) == true) + return (s); + + Regex reg = new Regex("\\[\\w+\\]"); + MatchCollection mc = reg.Matches(s); + + int index = 0; + StringBuilder sb = new StringBuilder(); + + sb.Append("

"); + + for (int i = 0; i < mc.Count; i++) + { + Match ma = mc[i]; + + if (ma.Index > index) + sb.Append(s.Substring(index, ma.Index - index)); + + switch (ma.Value) + { + case "[StartTime]": + sb.Append(Appointment.StartTime.ToString("t", + _BaseView.CalendarView.Is24HourFormat ? DateTimeFormatInfo.InvariantInfo : null)); + break; + + case "[StartDate]": + sb.Append(Appointment.StartTime.ToShortDateString()); + break; + + case "[EndTime]": + sb.Append(Appointment.EndTime.ToString("t", + _BaseView.CalendarView.Is24HourFormat ? DateTimeFormatInfo.InvariantInfo : null)); + break; + + case "[EndDate]": + sb.Append(Appointment.EndTime.ToShortDateString()); + break; + + case "[Subject]": + sb.Append(Appointment.Subject); + break; + + case "[Description]": + sb.Append(Appointment.Description); + break; + + case "[Id]": + sb.Append(Appointment.Id); + break; + + case "[Tag]": + sb.Append(Appointment.Tag.ToString()); + break; + + default: + sb.Append(_BaseView.CalendarView.DoGetDisplayTemplateText(this, ma.Value, ma.Value)); + break; + } + + index = ma.Index + ma.Length; + } + + if (s.Length > index) + sb.Append(s.Substring(index)); + + sb.Append("

"); + + return (sb.ToString()); + } + + #endregion + + #region Paint + + /// + /// Paint processing + /// + /// ItemPaintArgs + public override void Paint(ItemPaintArgs e) + { + } + + #region GetItemBounds + + /// + /// Gets the item text and image bounds + /// + /// + /// + /// + /// + protected virtual Rectangle GetItemBounds(Rectangle r, ref Rectangle rText, Image image) + { + Rectangle ri = r; + + if (Image != null) + { + const int vpad = 2; + const int hpad = 3; + + ri.Inflate(0, -vpad); + + switch (Appointment.ImageAlign) + { + case eImageContentAlignment.TopLeft: + rText.X += (image.Size.Width + hpad); + rText.Width -= (image.Size.Width + hpad); + break; + + case eImageContentAlignment.TopRight: + ri.X = rText.Right - image.Size.Width; + rText.Width -= image.Size.Width; + break; + + case eImageContentAlignment.TopCenter: + ri.X += (ri.Width - image.Size.Width) / 2; + rText.Y += (image.Size.Height + hpad); + rText.Height -= (image.Size.Height + hpad); + break; + + case eImageContentAlignment.MiddleLeft: + ri.Y += (ri.Height - image.Size.Height) / 2; + rText.X += (image.Size.Width + hpad); + rText.Width -= (image.Size.Width + hpad); + break; + + case eImageContentAlignment.MiddleRight: + ri.X = ri.Right - image.Size.Width; + ri.Y += (ri.Height - image.Size.Height) / 2; + rText.Width -= (image.Size.Width + hpad); + break; + + case eImageContentAlignment.MiddleCenter: + ri.X = ri.X + (ri.Width - image.Size.Width) / 2; + ri.Y += (ri.Height - image.Size.Height) / 2; + break; + + case eImageContentAlignment.BottomLeft: + ri.Y = ri.Bottom - image.Size.Height; + rText.X += (image.Size.Width + hpad); + rText.Width -= (image.Size.Width + hpad); + break; + + case eImageContentAlignment.BottomRight: + ri.X = ri.Right - image.Size.Width; + ri.Y = ri.Bottom - image.Size.Height; + rText.Width -= (image.Size.Width - hpad); + break; + + default: + ri.X = ri.X + (ri.Width - image.Size.Width) / 2; + ri.Y = ri.Bottom - image.Size.Height; + break; + } + + ri.Size = image.Size; + + if (ri.X < r.X) + ri.X = r.X; + + if (ri.Y < r.Y + vpad) + ri.Y = r.Y + vpad; + } + + return (ri); + } + + #endregion + + #region DrawContentImage + + /// + /// DrawContentImage + /// + /// + /// + /// + /// + protected virtual void DrawContentImage( + ItemPaintArgs e, Rectangle r, Rectangle rImage, Image image) + { + if (image != null) + { + Graphics g = e.Graphics; + + rImage.Intersect(r); + g.DrawImageUnscaledAndClipped(image, rImage); + } + } + + #endregion + + #region DrawTimeMarker + + #region DrawTimeMarker + + /// + /// Initiates the drawing of the appointment Time Marker + /// + /// Graphics + /// Appointment rectangle + /// Corner radius + protected virtual void DrawTimeMarker(Graphics g, Rectangle r, int corner) + { + if (Appointment.TimeMarkedAs != null) + { + if (Appointment.TimeMarkedAs.Equals(Appointment.TimerMarkerTentative)) + { + using (HatchBrush br = + new HatchBrush(HatchStyle.WideUpwardDiagonal, BorderColor, Color.White)) + { + g.RenderingOrigin = new Point(r.X, r.Y); + + RenderMarker(g, br, r, corner); + } + } + else + { + using (Brush br = TimeMarkerBrush(r)) + { + if (br != null) + RenderMarker(g, br, r, corner); + } + } + } + } + + #endregion + + #region RenderMarker + + /// + /// RenderMarker + /// + /// + /// Brush + /// Rectangle + /// Corner + private void RenderMarker(Graphics g, Brush br, Rectangle r, int corner) + { + using (Pen pen = BorderPen) + { + if (corner > 0) + { + using (GraphicsPath path = GetLeftRoundedRectanglePath(r, corner)) + { + g.FillPath(br, path); + g.DrawPath(pen, path); + } + } + else + { + int x = Math.Min(5, r.Height / 2); + x = Math.Min(x, r.Width / 2); + + r.Width = x; + + g.FillRectangle(br, r); + g.DrawRectangle(pen, r); + } + } + } + + #endregion + + #region GetLeftRoundedRectanglePath + + /// + /// Creates a left rounded rectangle path to be + /// used for the Time Marker + /// + /// Appointment rectangle + /// Corner radius + /// Graphics path + private GraphicsPath GetLeftRoundedRectanglePath(Rectangle r, int corner) + { + GraphicsPath path = new GraphicsPath(); + + ElementStyleDisplay.AddCornerArc(path, r, corner, eCornerArc.TopLeft); + path.AddLine(r.X + corner, r.Y, r.X + corner, r.Bottom); + ElementStyleDisplay.AddCornerArc(path, r, corner, eCornerArc.BottomLeft); + + return (path); + } + + #endregion + + #endregion + + #endregion + + #region Color support + + #region BackBrush + + /// + /// Gets the appointment BackGround brush + /// + /// Bounding rectangle + /// + protected Brush BackBrush(Rectangle r) + { + string category = _Appointment.CategoryColor; + + if (category != null) + { + // Check to see if we have any user defined + // AppointmentCategoryColors + + if (_BaseView.CalendarView.HasCategoryColors == true) + { + AppointmentCategoryColor acc = + _BaseView.CalendarView.CategoryColors[category]; + + if (acc != null) + return (_appointmentColor.BrushPart(acc.BackColor, r)); + } + + // Just use the default color set + + if (category.StartsWith("#") == true) + return (new SolidBrush(ColorFactory.Empty.GetColor(category.Substring(1)))); + + if (category.Equals(Appointment.CategoryBlue)) + return (_appointmentColor.BrushPart((int)eAppointmentPart.BlueBackground, r)); + + if (category.Equals(Appointment.CategoryGreen)) + return (_appointmentColor.BrushPart((int)eAppointmentPart.GreenBackground, r)); + + if (category.Equals(Appointment.CategoryOrange)) + return (_appointmentColor.BrushPart((int)eAppointmentPart.OrangeBackground, r)); + + if (category.Equals(Appointment.CategoryPurple)) + return (_appointmentColor.BrushPart((int)eAppointmentPart.PurpleBackground, r)); + + if (category.Equals(Appointment.CategoryRed)) + return (_appointmentColor.BrushPart((int)eAppointmentPart.RedBackground, r)); + + if (category.Equals(Appointment.CategoryYellow)) + return (_appointmentColor.BrushPart((int)eAppointmentPart.YellowBackground, r)); + } + + return (_appointmentColor.BrushPart((int)eAppointmentPart.DefaultBackground, r)); + } + + #endregion + + #region BorderColor + + /// + /// Gets the border color for the Category + /// + protected Color BorderColor + { + get + { + string category = _Appointment.CategoryColor; + + if (category != null) + { + // Check to see if we have any user defined + // AppointmentCategoryColors + + if (_BaseView.CalendarView.HasCategoryColors == true) + { + AppointmentCategoryColor acc = + _BaseView.CalendarView.CategoryColors[category]; + + if (acc != null) + return (acc.BorderColor); + } + + // Just use the default color set + + if (category.Equals(Appointment.CategoryBlue)) + return (_appointmentColor.GetColor((int)eAppointmentPart.BlueBorder)); + + if (category.Equals(Appointment.CategoryGreen)) + return (_appointmentColor.GetColor((int)eAppointmentPart.GreenBorder)); + + if (category.Equals(Appointment.CategoryOrange)) + return (_appointmentColor.GetColor((int)eAppointmentPart.OrangeBorder)); + + if (category.Equals(Appointment.CategoryPurple)) + return (_appointmentColor.GetColor((int)eAppointmentPart.PurpleBorder)); + + if (category.Equals(Appointment.CategoryRed)) + return (_appointmentColor.GetColor((int)eAppointmentPart.RedBorder)); + + if (category.Equals(Appointment.CategoryYellow)) + return (_appointmentColor.GetColor((int)eAppointmentPart.YellowBorder)); + } + + return (_appointmentColor.GetColor((int)eAppointmentPart.DefaultBorder)); + } + } + + #endregion + + #region BorderPen + + /// + /// Gets the border pen + /// + protected Pen BorderPen + { + get + { + int n = (_BorderWidth > 0) ? + _BorderWidth : _BaseView.CalendarView.AppointmentBorderWidth; + + return (new Pen(BorderColor, n)); + } + } + + #endregion + + #region SelectedBorderPen + + /// + /// Gets the selected border pen + /// + protected Pen SelectedBorderPen + { + get + { + int n = (_BorderWidth > 0) ? + _BorderWidth : _BaseView.CalendarView.AppointmentBorderWidth; + + return (new Pen(Color.Black, n + 1)); + } + } + + #endregion + + #region TextColor + + /// + /// Gets the Text color for the Category + /// + protected Color TextColor + { + get + { + string category = _Appointment.CategoryColor; + + // Check to see if we have any user defined + // AppointmentCategoryColors + + if (category != null) + { + if (_BaseView.CalendarView.HasCategoryColors == true) + { + AppointmentCategoryColor acc = + _BaseView.CalendarView.CategoryColors[category]; + + if (acc != null) + return (acc.TextColor); + } + } + + return (Color.Black); + } + } + + #endregion + + #region TimeMarkerBrush + + /// + /// Gets the appointment TimeMarkerBrush + /// + /// Bounding rectangle + /// + protected Brush TimeMarkerBrush(Rectangle r) + { + string timeMarkedAs = _Appointment.TimeMarkedAs; + + if (timeMarkedAs != null) + { + if (timeMarkedAs.StartsWith("#") == true) + return (new SolidBrush(ColorFactory.Empty.GetColor(timeMarkedAs.Substring(1)))); + + if (timeMarkedAs.Equals(Appointment.TimerMarkerFree)) + return (_appointmentColor.BrushPart((int)eAppointmentPart.FreeTimeMarker, r)); + + if (timeMarkedAs.Equals(Appointment.TimerMarkerBusy)) + return (_appointmentColor.BrushPart((int)eAppointmentPart.BusyTimeMarker, r)); + + if (timeMarkedAs.Equals(Appointment.TimerMarkerOutOfOffice)) + return (_appointmentColor.BrushPart((int)eAppointmentPart.OutOfOfficeTimeMarker, r)); + } + + return (null); + } + + #endregion + + #endregion + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentWeekDayView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentWeekDayView.cs new file mode 100644 index 00000000..99f72fb1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/AppointmentView/AppointmentWeekDayView.cs @@ -0,0 +1,527 @@ +#if FRAMEWORK20 +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class AppointmentWeekDayView : AppointmentView + { + #region Private variables + + private DayColumn _DayColumn; + private AllDayPanel _AllDayPanel; + private eViewEnds _ViewEnds = eViewEnds.Complete; + + #endregion + + /// + /// Constructor + /// + /// + /// + public AppointmentWeekDayView(BaseView baseView, Appointment appointment) + : base(baseView, appointment) + { + SetViewEnds(); + } + + #region Public properties + + /// + /// Gets and sets View DayColumn + /// + public DayColumn DayColumn + { + get { return (_DayColumn); } + set { _DayColumn = value; } + } + + /// + /// Gets and sets View AllDayPanel + /// + public AllDayPanel AllDayPanel + { + get { return (_AllDayPanel); } + + set + { + if (_AllDayPanel != value) + { + _AllDayPanel = value; + + SetViewEnds(); + } + } + } + + #endregion + + #region Private properties + + /// + /// Gets the default horizontal padding + /// + private int HorizontalPadding + { + get { return (6); } + } + + /// + /// Gets whether the appointment is mutable + /// + private bool IsMutable + { + get + { + WeekDayView wv = (WeekDayView)BaseView; + + return (IsSelected == true && + wv.IsAllDayItem(this) == false && + Appointment.Locked == false && + Appointment.IsRecurringInstance == false); + } + } + + #endregion + + #region Start/End TimeChanged event handling + + /// + /// Handles StartTime value changes + /// + /// CalendarItem + /// EventArgs + protected override void AppointmentView_StartTimeChanged(object sender, EventArgs e) + { + base.AppointmentView_StartTimeChanged(sender, e); + + SetViewEnds(); + } + + /// + /// Handles EndTime value changes + /// + /// CalendarItem + /// EventArgs + protected override void AppointmentView_EndTimeChanged(object sender, EventArgs e) + { + base.AppointmentView_EndTimeChanged(sender, e); + + SetViewEnds(); + } + + #endregion + + #region SetViewEnds + + /// + /// Sets the view display end types + /// + private void SetViewEnds() + { + if (_AllDayPanel != null) + { + _ViewEnds = eViewEnds.Complete; + + int col, n; + + DateTime start = GetDateCol(StartTime, out col, out n); + DateTime end = start.AddDays(n); + + // Check to see if we can only display + // a partial representation for the view + + if (col > 0 || start > StartTime) + _ViewEnds |= eViewEnds.PartialLeft; + + TimeSpan ts = new TimeSpan(24, 0, 0); + + if (end > EndTime || EndTime - end > ts) + _ViewEnds |= eViewEnds.PartialRight; + } + else + { + _ViewEnds = eViewEnds.PartialLeft | eViewEnds.PartialRight; + } + } + + /// + /// Gets the initial starting DayColumn col and max col + /// for the given date + /// + /// Selection date + /// Column + /// Max col + /// + private DateTime GetDateCol(DateTime selDate, out int col, out int n) + { + DayColumn[] dayColumns = _AllDayPanel.WeekDayView.DayColumns; + + // Loop through each column + + col = 0; + n = 0; + + for (int i = 0; i < dayColumns.Length; i++) + { + DateTime date = dayColumns[i].Date; + + // If we have found our containing column, then + // calculate the absolute slice value and return it + + if (date.Year >= selDate.Year || + date.Month >= selDate.Month || date.Day >= selDate.Day) + { + col = i; + n = dayColumns.Length - col - 1; + + return (date); + } + } + + return (selDate); + } + + #endregion + + #region Appointment rendering + + /// + /// Paint processing + /// + /// ItemPaintArgs + public override void Paint(ItemPaintArgs e) + { + AppointmentColor.SetColorTable(); + + Rectangle r = GetViewRect(); + + if (r.Width > 1 && r.Height > 0) + { + if (EffectiveStyle == eDotNetBarStyle.Office2010 || StyleManager.IsMetro(EffectiveStyle)) + DrawMetroAppointment(e, r); + else + DrawDefaultAppointment(e, r); + + if (IsMutable == true) + DrawResizeHandles(e, r); + } + } + + #region DrawDefaultAppointment + + private void DrawDefaultAppointment(ItemPaintArgs e, Rectangle r) + { + Graphics g = e.Graphics; + + int top = Math.Min(Math.Min(r.Width / 2, r.Height / 2), 5); + int bot = top; + + if (DayColumn != null) + { + if (StartTime.Date < DayColumn.Date.Date) + top = 0; + + if (EndTime.Date > DayColumn.Date.Date.AddDays(1)) + bot = 0; + } + + using (GraphicsPath path = DisplayHelp.GetRoundedRectanglePath(r, top, top, bot, bot)) + { + using (Brush br = BackBrush(r)) + g.FillPath(br, path); + + if (BaseView.CalendarView.DoAppointmentViewPreRender(this, g, r, path) == false) + { + DrawContent(e, r); + + BaseView.CalendarView.DoAppointmentViewPostRender(this, g, r, path); + } + + DrawDefaultBorder(g, top, bot, r, path); + } + } + + #region DrawDefaultBorder + + private void DrawDefaultBorder(Graphics g, + int top, int bot, Rectangle r, GraphicsPath path) + { + DrawTimeMarker(g, r, top); + + if (IsSelected == true) + { + using (Pen pen = SelectedBorderPen) + g.DrawPath(pen, path); + } + else + { + using (Pen pen = BorderPen) + g.DrawPath(pen, path); + } + } + + #endregion + + #endregion + + #region DrawMetroAppointment + + private void DrawMetroAppointment(ItemPaintArgs e, Rectangle r) + { + Graphics g = e.Graphics; + + using (Brush br = BackBrush(r)) + g.FillRectangle(br, r); + + if (BaseView.CalendarView.DoAppointmentViewPreRender(this, g, r, null) == false) + { + DrawContent(e, r); + + BaseView.CalendarView.DoAppointmentViewPostRender(this, g, r, null); + } + + DrawMetroBorder(g, r); + } + + #region DrawMetroBorder + + private void DrawMetroBorder(Graphics g, Rectangle r) + { + DrawTimeMarker(g, r, 0); + + if (IsSelected == true) + { + using (Pen pen = new Pen(Color.Black, 2)) + g.DrawRectangle(pen, r); + } + else + { + using (Pen pen = BorderPen) + g.DrawRectangle(pen, r); + } + } + + #endregion + + #endregion + + #region GetViewRect + + /// + /// Gets the view rect for the appointment + /// + /// View rect + private Rectangle GetViewRect() + { + Rectangle r = DisplayRectangle; + + if ((_ViewEnds & eViewEnds.PartialLeft) != eViewEnds.PartialLeft) + { + r.X += HorizontalPadding; + r.Width -= HorizontalPadding; + } + + if ((_ViewEnds & eViewEnds.PartialRight) != eViewEnds.PartialRight) + r.Width -= HorizontalPadding; + + // If the view is selected, then allow + // for a thicker selection rect + + if (IsSelected == true && Appointment.IsMultiDayOrAllDayEvent == false) + r.Height -= 1; + + return (r); + } + + #endregion + + #region DrawContent + + /// + /// DrawContent + /// + /// + /// + private void DrawContent(ItemPaintArgs e, Rectangle r) + { + Image image = Image; + + Rectangle rText = r; + rText.X += 4; + rText.Width -= 6; + + if (Appointment.TimeMarkedAs != null) + { + rText.X += 4; + rText.Width -= 4; + } + + Rectangle rImage = GetItemBounds(rText, ref rText, image); + + DrawContentImage(e, r, rImage, image); + DrawContentText(e, rText); + } + + #region DrawContentText + + /// + /// Draws the content text + /// + /// + /// + private void DrawContentText(ItemPaintArgs e, Rectangle r) + { + Graphics g = e.Graphics; + + if (DisplayTemplateText(e, r) == false) + { + string s = Appointment.Subject; + + eTextFormat tf = eTextFormat.NoPadding | eTextFormat.NoPrefix; + WeekDayView wv = BaseView as WeekDayView; + + if (wv != null && wv.IsAllDayItem(Appointment) == false) + { + s += "\n" + Appointment.Description; + + r.Y += 3; + r.Height -= 3; + + tf |= eTextFormat.WordBreak; + } + else + { + tf |= eTextFormat.VerticalCenter; + } + + Font font = Font ?? e.Font; + + if (r.Width > 4) + TextDrawing.DrawString(g, s, font, TextColor, r, tf); + + Size size = TextDrawing.MeasureString(g, s, font, r.Width, tf); + + IsTextClipped = (r.Width < size.Width || r.Height < size.Height); + } + } + + #endregion + + #endregion + + #region DrawResizeHandles + + /// + /// Draws the resize handles for the view + /// + /// + /// View rectangle + private void DrawResizeHandles(ItemPaintArgs e, Rectangle r) + { + if (r.Width > 6) + { + Graphics g = e.Graphics; + + Rectangle r2 = + new Rectangle(r.X + (r.Width / 2) - 2, r.Y - 3, 5, 5); + + if (DayColumn != null) + { + // Top handle + + if (StartTime >= DayColumn.Date) + { + g.FillRectangle(Brushes.White, r2); + g.DrawRectangle(Pens.Black, r2); + } + + // Bottom handle + + if (EndTime <= DayColumn.Date.AddDays(1)) + { + r2.Y = r.Bottom - 2; + + g.FillRectangle(Brushes.White, r2); + g.DrawRectangle(Pens.Black, r2); + } + } + } + } + + #endregion + + #endregion + + #region Mouse processing + + #region MouseMove processing + + /// + /// Handles mouseDown processing + /// + /// MouseEventArgs + public override void InternalMouseMove(MouseEventArgs objArg) + { + HitArea = GetHitArea(objArg); + + base.InternalMouseMove(objArg); + } + + /// + /// Gets the HitArea from the current + /// mouse position + /// + /// + /// eHitArea + private eHitArea GetHitArea(MouseEventArgs objArg) + { + if (IsMutable == true) + { + Rectangle r = GetViewRect(); + + Rectangle r2 = + new Rectangle(r.X + (r.Width / 2) - 7, r.Y - 7, 14, 14); + + if (DayColumn != null) + { + // See if we are in the top resize area + + if (StartTime >= DayColumn.Date) + { + if (r2.Contains(objArg.Location)) + return (eHitArea.TopResize); + } + + // See if we are in the bottom resize area + + if (EndTime <= DayColumn.Date.AddDays(1)) + { + r2.Y = r.Bottom - 10; + + if (r2.Contains(objArg.Location)) + return (eHitArea.BottomResize); + } + } + + // By default we are in the move area + + return (eHitArea.Move); + } + + // No valid area to report + + return (eHitArea.None); + } + + #endregion + + #endregion + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/BaseView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/BaseView.cs new file mode 100644 index 00000000..f19585e4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/BaseView.cs @@ -0,0 +1,2286 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class BaseView : BaseItem + { + #region Events + + /// + /// Occurs when SelectedItem has Changed + /// + public event EventHandler SelectedItemChanged; + + /// + /// Occurs when CalendarColor has Changed + /// + public event EventHandler CalendarColorChanged; + + #endregion + + #region Constants + + protected const int DaysInWeek = 7; + private const int TabRadius = 3; + private const int TabDia = TabRadius * 2; + + #endregion + + #region Static variables + + private static DateTime _oldStartTime; // Pre-move/resize CalendarItem StartTime + private static DateTime _oldEndTime; // Pre-move/resize CalendarItem EndTime + private static string _oldOwnerKey; // Pre-move CalendarItem OwnerKey + + #endregion + + #region SubClasses + + internal class NonClientData + { + #region Data members + + public eTabOrientation TabOrientation; // Tab orientation + + public int TabBorder; // Tab border color + public int TabFore; // Tab foreground color + public int TabBack; // Tab background color + public int ContBack; // Tab content background + public int TabSelFore; // Tab selected foreground + public int TabSelBack; // Tab selected background + + #endregion + + /// + /// Constructor + /// + /// Tab Orientation + /// Tab border color + /// Tab foreground color + /// Tab background color + /// Tab content background + /// Tab selected foreground + /// Tab selected background + public NonClientData( + eTabOrientation tabOrientation, + int tabBorder, int tabFore, int tabBack, + int contBack, int tabSelFore, int tabSelBack) + { + TabOrientation = tabOrientation; + + TabBorder = tabBorder; + TabFore = tabFore; + TabBack = tabBack; + ContBack = contBack; + TabSelFore = tabSelFore; + TabSelBack = tabSelBack; + } + } + + #endregion + + #region Private variables + + private CalendarView _CalendarView; // CalendarView + private eCalendarView _ECalendarView; // Enum CalendarView + + private ModelViewConnector _Connector; // Connector + + private DateTime? _DateSelectionStart; // Date selection start + private DateTime? _DateSelectionEnd; // Date selection end + private DateTime? _DateSelectionAnchor; // Date selection anchor + + private DateTime _StartDate; // Display start date + private DateTime _EndDate; // Display end date + private bool _DateRangeChanged; // Date range has changed + + private CalendarColor _CalendarColor; // CalendarColor + + private Rectangle _ClientRect; // View client area + private NonClientData _NClientData; // Non-client data + private int _TabWidth; // Tab width + + private PosWin _PosWin; // Move/Resize Position window + + private bool _IsMouseDown; // Mouse is down + private bool _IsMoving; // Flag denoting app moving + private bool _IsStartResizing; // Flag denoting appt start resizing + private bool _IsEndResizing; // Flag denoting appt end resizing + private bool _IsTabMoving; // Flag denoting Tab is moving + private bool _IsCondMoving; // Flag denoting Condensed view movement + private bool _IsCopyDrag; // Flag denoting Appointment copy is dragging + private bool _IsNewCopyDrag; + + private int _LastViewIndex; // Last MultiUser view index + + private string _OwnerKey; // Owner key + private string _DisplayName; // Display name + private int _DisplayedOwnerKeyIndex = -1; // DisplayedOwnerKey index + + private bool _IsViewSelected; // View selected? + private bool _IsSelecting; // Selection inprogress flag + private CalendarItem _SelectedItem; // Selected CalendarItem + + private bool _NeedRecalcLayout = true; // Layout needs recalculated + + private DaysOfTheWeek _DaysOfTheWeek; // Days of the week + + private Font _Font = SystemFonts.CaptionFont; // Display font + + private Font _BoldFont = // Bold display font + new Font(SystemFonts.CaptionFont, FontStyle.Bold); + + #endregion + + /// + /// Constructor + /// + /// + /// + public BaseView(CalendarView calendarView, eCalendarView ecv) + { + // Save the provided CalendarView and + // tell the system we are a container + + _CalendarView = calendarView; + _ECalendarView = ecv; + + SetIsContainer(true); + + SubItems.AllowParentRemove = false; + + // Make sure we see all our mouse events + + MouseDownCapture = true; + MouseUpNotification = true; + + // Hook our events + + HookEvents(true); + } + + #region Public properties + + #region BoldFont + + /// + /// Gets the Bold display font + /// + public Font BoldFont + { + get { return (_BoldFont); } + } + + #endregion + + #region Bounds + + /// + /// Gets and sets the view bounding rectangle + /// + public override Rectangle Bounds + { + get { return (base.Bounds); } + + set + { + if (base.Bounds != value) + { + Rectangle r = base.Bounds; + base.Bounds = value; + + InvalidateRect(r); + + NeedRecalcLayout = true; + } + } + } + + #endregion + + #region DisplayedOwnerKey + + /// + /// Gets and sets the DisplayedOwnerKey + /// + public string DisplayedOwnerKey + { + get + { + if (_DisplayedOwnerKeyIndex < 0 || + _DisplayedOwnerKeyIndex > _CalendarView.DisplayedOwners.Count) + { + return (""); + } + + return (_CalendarView.DisplayedOwners[_DisplayedOwnerKeyIndex]); + } + } + + /// + /// Gets and sets the DisplayedOwnerKeyIndex + /// + public int DisplayedOwnerKeyIndex + { + get { return (_DisplayedOwnerKeyIndex); } + internal set { _DisplayedOwnerKeyIndex = value; } + } + + /// + /// Gets and sets the view Owner Key + /// + public string OwnerKey + { + get { return (_OwnerKey); } + internal set { _OwnerKey = value; } + } + + /// + /// Gets and sets the view Display Name + /// + public string DisplayName + { + get { return (_DisplayName); } + + set + { + if (_DisplayName != value) + { + _DisplayName = value; + + this.Refresh(); + } + } + } + + #endregion + + #region Start/EndDate + + /// + /// Gets and sets the display start date + /// + public DateTime StartDate + { + get { return (_StartDate); } + + set + { + if (_StartDate != value) + { + _StartDate = value; + _DateRangeChanged = true; + + NeedRecalcLayout = true; + } + } + } + + /// + /// Gets and sets the display end date + /// + public DateTime EndDate + { + get { return (_EndDate); } + + set + { + if (_EndDate != value) + { + _EndDate = value; + _DateRangeChanged = true; + + NeedRecalcLayout = true; + } + } + } + + #endregion + + #region DateSelectionStart + + /// + /// Gets and sets the date selection start + /// + public DateTime? DateSelectionStart + { + get { return (_DateSelectionStart); } + + set + { + if (_DateSelectionStart != value) + { + _DateSelectionStart = value; + + // Update our dayRects selection status + + UpdateDateSelection(); + } + } + } + + #endregion + + #region DateSelectionEnd + + /// + /// Gets or sets the end date of selection. + /// + public DateTime? DateSelectionEnd + { + get { return (_DateSelectionEnd); } + + set + { + if (_DateSelectionEnd != value) + { + _DateSelectionEnd = value; + + // Update our dayRects selection status + + UpdateDateSelection(); + } + } + } + + #endregion + + #region CalendarColorTable + + /// + /// Gets and sets the CalendarColorTable + /// + public CalendarColor CalendarColorTable + { + get { return (_CalendarColor); } + internal set { _CalendarColor = value; } + } + + #endregion + + #region CalendarColor + + /// + /// Gets and sets the display calendar color scheme + /// + public eCalendarColor CalendarColor + { + get { return (_CalendarColor.ColorSch); } + + set + { + if (_CalendarColor.ColorSch != value) + { + eCalendarColor oldValue = _CalendarColor.ColorSch; + _CalendarColor.ColorSch = value; + + OnCalendarColorChanged(oldValue, value); + + if (IsViewSelected == true) + InvalidateRect(Bounds); + } + } + } + + /// + /// OnCalendarColorChanged event propagation + /// + protected virtual void + OnCalendarColorChanged(eCalendarColor oldValue, eCalendarColor newValue) + { + if (CalendarColorChanged != null) + { + CalendarColorChanged(this, + new CalendarColorChangedEventArgs(oldValue, newValue)); + } + + // Reflect the change in alternate views + + CalendarView.UpdateAltViewCalendarColor(newValue, DisplayedOwnerKeyIndex); + + // Update the CalendarModel ColorScheme + + OwnerCollection owners = CalendarView.CalendarModel.Owners; + + foreach (Owner owner in owners) + { + if (owner.Key.Equals(OwnerKey) == true) + { + owner.ColorScheme = newValue; + break; + } + } + } + + #endregion + + #region Font + + /// + /// Get and sets the calendar font. + /// + public virtual Font Font + { + get { return (_Font); } + + set + { + if (value != null && _Font.Equals(value) == false) + { + if (_Font != null) + _Font.Dispose(); + + if (_BoldFont != null) + _BoldFont.Dispose(); + + _Font = value; + _BoldFont = new Font(_Font, FontStyle.Bold); + + InvalidateRect(true); + } + } + } + + #endregion + + #region Selection support + + /// + /// Gets and sets the currently selected CalendarItem + /// + public CalendarItem SelectedItem + { + get { return _SelectedItem; } + + set + { + if (_SelectedItem != value) + { + CalendarItem oldValue = _SelectedItem; + _SelectedItem = value; + + if (value != null) + { + CalendarView.DateSelectionStart = null; + CalendarView.DateSelectionEnd = null; + + DateSelectionAnchor = null; + + UpdateItemOrder(value); + } + + SetSelectedItem(oldValue, value); + + OnSelectedItemChanged(oldValue, value); + } + } + } + + internal void UpdateItemOrder(CalendarItem ci) + { + int n = SubItems.IndexOf(ci); + int index = FirstCalendarItem(); + + if (index >= 0 && index < n) + { + SubItems._RemoveAt(n); + SubItems._Insert(index, ci); + } + } + + private int FirstCalendarItem() + { + for (int i = 0; i < SubItems.Count; i++) + { + if (SubItems[i] is CalendarItem) + return (i); + } + + return (-1); + } + + /// + /// SelectedItemChanged event propagation + /// + protected virtual void + OnSelectedItemChanged(CalendarItem oldValue, CalendarItem newValue) + { + if (SelectedItemChanged != null) + { + SelectedItemChanged(this, + new SelectedItemChangedEventArgs(oldValue, newValue)); + } + } + + /// + /// Gets the selected state of the view + /// + public bool IsViewSelected + { + get { return (_IsViewSelected); } + internal set {_IsViewSelected = value; } + } + + #endregion + + #region SelectedAppointments + + /// + /// Gets a ReadOnlyCollection of the + /// currently selected appointments for the view + /// + public ReadOnlyCollection SelectedAppointments + { + get + { + List apps = new List(); + + AppointmentView view = _SelectedItem as AppointmentView; + + if (view != null) + apps.Add(view); + + return (new ReadOnlyCollection(apps)); + } + } + + #endregion + + #endregion + + #region Protected properties + + #region CalendarModel + + /// + /// Gets the View CalendarModel + /// + protected CalendarModel CalendarModel + { + get { return (CalendarView.CalendarModel); } + } + + #endregion + + #region Mouse related properties + + /// + /// IsMouseDown + /// + protected bool IsMouseDown + { + get { return (_IsMouseDown); } + set { _IsMouseDown = value; } + } + + /// + /// IsStartResizing + /// + protected bool IsStartResizing + { + get { return (_IsStartResizing); } + set { _IsStartResizing = value; } + } + + /// + /// IsEndResizing + /// + protected bool IsEndResizing + { + get { return (_IsEndResizing); } + set { _IsEndResizing = value; } + } + + /// + /// IsResizing + /// + protected bool IsResizing + { + get { return (_IsStartResizing || _IsEndResizing); } + } + + /// + /// IsMoving + /// + protected bool IsMoving + { + get { return (_IsMoving); } + set { _IsMoving = value; } + } + + /// + /// IsTabMoving + /// + protected bool IsTabMoving + { + get { return (_IsTabMoving); } + set { _IsTabMoving = value; } + } + + /// + /// IsConMoving + /// + protected bool IsCondMoving + { + get { return (_IsCondMoving); } + set { _IsCondMoving = value; } + } + + /// + /// CanDrag + /// + protected bool CanDrag + { + get { return (SelectedItem != null && CalendarView.EnableDragDrop == true); } + } + + /// + /// Pre-move/resize StartTime + /// + protected DateTime OldStartTime + { + get { return (_oldStartTime); } + set { _oldStartTime = value; } + } + + /// + /// Pre-move/resize EndTime + /// + protected DateTime OldEndTime + { + get { return (_oldEndTime); } + set { _oldEndTime = value; } + } + + #endregion + + #region Cursor properties + + /// + /// Sets local view cursor + /// + protected Cursor MyCursor + { + set { CalendarView.ViewCursor = value; } + } + + /// + /// Gets CalendarView default cursor + /// + protected Cursor DefaultCursor + { + get { return (CalendarView.DefaultViewCursor); } + } + + #endregion + + #region PosWin + + /// + /// Gets and sets the view position window + /// + protected PosWin PosWin + { + get { return (_PosWin); } + set { _PosWin = value; } + } + + #endregion + + #endregion + + #region Internal properties + + /// + /// Gets the CalendarView + /// + internal CalendarView CalendarView + { + get { return (_CalendarView); } + } + + /// + /// Gets the ECalendarView + /// + internal eCalendarView ECalendarView + { + get { return (_ECalendarView); } + } + + /// + /// Gets and sets the ModelViewConnector + /// + internal ModelViewConnector Connector + { + get { return (_Connector); } + + set + { + if (value != _Connector) + { + _Connector = value; + + _Connector.DisplayOwnerKey = DisplayedOwnerKey; + _Connector.Connect(); + } + } + } + + /// + /// Gets the DayOfWeekHeader height + /// + internal int DayOfWeekHeaderHeight + { + get { return (Font.Height + 4); } + } + + /// + /// IsCopyDrag + /// + internal bool IsCopyDrag + { + get { return (_IsCopyDrag); } + set { _IsCopyDrag = value; } + } + + /// + /// IsNewCopyDrag + /// + internal bool IsNewCopyDrag + { + get { return (_IsNewCopyDrag); } + set { _IsNewCopyDrag = value; } + } + + /// + /// OldOwnerKey + /// + internal string OldOwnerKey + { + get { return (_oldOwnerKey); } + set { _oldOwnerKey = value; } + } + + #region MonthHeaderHeight + + internal int MonthHeaderHeight + { + get { return (Font.Height + 4); } + } + + #endregion + + /// + /// Gets the MultiUserTabHeight + /// + internal int MultiUserTabHeight + { + get { return (_CalendarView.MultiUserTabHeight); } + } + + /// + /// Gets the MultiUserTabWidth + /// + internal int MultiUserTabWidth + { + get { return (_CalendarView.TimeLineMultiUserTabWidth); } + } + + /// + /// Gets the Appointment height + /// + internal int AppointmentHeight + { + get { return (Font.Height + 4); } + } + + /// + /// Gets and sets the date selection anchor + /// + internal DateTime? DateSelectionAnchor + { + get { return (_DateSelectionAnchor); } + set { _DateSelectionAnchor = value; } + } + + /// + /// Gets and sets the Days of the week object + /// + internal DaysOfTheWeek DaysOfTheWeek + { + get { return (_DaysOfTheWeek); } + set { _DaysOfTheWeek = value; } + } + + /// + /// Gets and sets the selecting status + /// + internal bool IsSelecting + { + get { return (_IsSelecting); } + set { _IsSelecting = value; } + } + + /// + /// Gets and sets recalc layout need + /// + internal bool NeedRecalcLayout + { + get { return (_NeedRecalcLayout); } + + set + { + _NeedRecalcLayout = value; + + if (value == true) + InvalidateRect(true); + } + } + + /// + /// Gets and sets the view client rectangle + /// + internal Rectangle ClientRect + { + get { return (_ClientRect); } + set { _ClientRect = value; } + } + + /// + /// Gets and sets the DateRangeChanged state + /// + internal bool DateRangeChanged + { + get { return (_DateRangeChanged); } + set { _DateRangeChanged = value; } + } + + /// + /// Gets and sets the base non-client data + /// + internal NonClientData NClientData + { + get { return (_NClientData); } + set { _NClientData = value; } + } + + #endregion + + #region HookEvents + + /// + /// Hooks and unhooks our object events + /// + /// True - hook, false - unhook + private void HookEvents(bool hook) + { + if (hook == true) + { + CalendarView.ModelChanged += CalendarViewModelChanged; + CalendarView.DateSelectionStartChanged += CalendarViewDateSelectionStartChanged; + CalendarView.DateSelectionEndChanged += CalendarViewDateSelectionEndChanged; + } + else + { + CalendarView.ModelChanged -= CalendarViewModelChanged; + CalendarView.DateSelectionStartChanged -= CalendarViewDateSelectionStartChanged; + CalendarView.DateSelectionEndChanged -= CalendarViewDateSelectionEndChanged; + } + } + + #endregion + + #region Event processing + + /// + /// DateSelectionEndChanged + /// + /// + /// + void CalendarViewDateSelectionEndChanged(object sender, DateSelectionEventArgs e) + { + if (CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex) + this.DateSelectionEnd = CalendarView.DateSelectionEnd; + else + this.DateSelectionEnd = null; + } + + /// + /// DateSelectionStartChanged + /// + /// + /// + void CalendarViewDateSelectionStartChanged(object sender, DateSelectionEventArgs e) + { + if (CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex) + this.DateSelectionStart = CalendarView.DateSelectionStart; + else + this.DateSelectionStart = null; + } + + /// + /// ModelChanged + /// + /// + /// + void CalendarViewModelChanged(object sender, ModelEventArgs e) + { + ResetView(); + } + + #endregion + + #region RecalcSize + + /// + /// Performs NeedRecalcSize requests + /// + public override void RecalcSize() + { + base.RecalcSize(); + + Rectangle r = Bounds; + + if (CalendarView.IsMultiCalendar == true) + { + if (NClientData.TabOrientation == eTabOrientation.Horizontal) + { + r.Inflate(-2, -2); + + if (CalendarView.ShowTabs == true) + { + r.Y += MultiUserTabHeight; + r.Height -= MultiUserTabHeight; + } + } + else + { + if (CalendarView.ShowTabs == true) + { + if (CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Vertical) + { + r.X += MultiUserTabHeight + Dpi.Width4; + r.Width -= (MultiUserTabHeight + Dpi.Width4); + } + else + { + r.X += MultiUserTabWidth + Dpi.Width4; + r.Width -= (MultiUserTabWidth + Dpi.Width4); + } + } + } + } + + ClientRect = r; + } + + #endregion + + #region Paint processing + + /// + /// Paint processing + /// + /// + public override void Paint(ItemPaintArgs e) + { + if (CalendarView.IsMultiCalendar == true) + { + if (NClientData.TabOrientation == eTabOrientation.Horizontal) + DrawHorizontalLayout(e); + else + DrawVerticalLayout(e); + } + } + + #region DrawHorizontalLayout + + /// + /// Draws horizontal tab layout + /// + /// + private void DrawHorizontalLayout(ItemPaintArgs e) + { + Graphics g = e.Graphics; + + Rectangle r = Bounds; + r.Width = _ClientRect.Width; + r.Height = MultiUserTabHeight + 3; + + if (r.Width > 0) + { + // Size-up the tab dimensions + + string s = string.IsNullOrEmpty(DisplayName) ? OwnerKey : DisplayName; + Size sz = TextDrawing.MeasureString(g, s, Font); + + // Draw the control background border, and tab, + + DrawBackBorder(g, sz.Width); + DrawHTab(e, s, sz.Width, r); + } + } + + #region DrawBackBorder + + /// + /// Draws the background border around + /// the entire control view + /// + /// + /// + private void DrawBackBorder(Graphics g, int width) + { + Rectangle r = _ClientRect; + + if (g.ClipBounds.X > r.X) + { + r.Width -= (int) (g.ClipBounds.X - r.X); + r.X = (int) g.ClipBounds.X + 1; + } + + if (g.ClipBounds.Right < r.Right) + r.Width = (int) g.ClipBounds.Right - r.X - 1; + + if (CalendarView.DoRenderViewBorder(g, this, r) == false) + { + using (Pen pen = new + Pen(_CalendarColor.GetColor(_NClientData.ContBack))) + { + g.DrawLines(pen, new Point[] + { + new Point(r.Left - 1, r.Y - 1), + new Point(r.Right, r.Top - 1), + new Point(r.Right, r.Bottom), + new Point(r.Left - 1, r.Bottom), + new Point(r.Left - 1, r.Top - 2), + new Point(r.Right, r.Top - 2), + }); + } + + using (Pen pen = new + Pen(_CalendarColor.GetColor(_NClientData.TabBorder))) + { + // Draw the tab border + + if (width + MultiUserTabHeight < _ClientRect.Width) + { + g.DrawLine(pen, + _ClientRect.Left + width + MultiUserTabHeight, _ClientRect.Top - 2, + _ClientRect.Right + 1, _ClientRect.Top - 2); + } + + g.DrawLines(pen, new Point[] + { + new Point(_ClientRect.Right + 1, _ClientRect.Top - 2), + new Point(_ClientRect.Right + 1, _ClientRect.Bottom + 1), + new Point(_ClientRect.Left - 2, _ClientRect.Bottom + 1), + new Point(_ClientRect.Left - 2, _ClientRect.Top - 2), + }); + } + } + } + + #endregion + + #region DrawHTab + + /// + /// Draws the tab - border and content + /// + /// ItemPaintArgs + /// Tab text + /// Text measured width + /// Bounding rectangle + private void DrawHTab(ItemPaintArgs e, string text, int width, Rectangle r) + { + _TabWidth = Math.Min(width, _ClientRect.Width); + + if (CalendarView.ShowTabs == true) + { + if (e.ClipRectangle.Y < _ClientRect.Y) + { + Graphics g = e.Graphics; + + bool isSelected = + (CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex); + + // Draw the tab + + using (GraphicsPath path = GetHTabPath(_TabWidth)) + { + if (CalendarView.DoRenderTabBackground(g, path, this, isSelected) == false) + { + using (Brush br = _CalendarColor.BrushPart( + isSelected ? _NClientData.TabSelBack : _NClientData.TabBack, r)) + { + g.FillPath(br, path); + } + + using (Pen pen = new + Pen(_CalendarColor.GetColor(_NClientData.TabBorder))) + { + g.DrawPath(pen, path); + } + } + + // Draw the tab text + + if (CalendarView.DoRenderTabContent( + g, path, this, ref text, isSelected) == false) + { + r.X += 4; + + Color color = _CalendarColor.GetColor(isSelected + ? _NClientData.TabSelFore : _NClientData.TabFore); + + TextDrawing.DrawString(g, text, Font, color, r, eTextFormat.VerticalCenter); + } + } + } + } + } + + #endregion + + #region GetHTabPath + + /// + /// Gets the tab graphics path + /// + /// Tab width + /// GraphicsPath + protected GraphicsPath GetHTabPath(int tabWidth) + { + GraphicsPath path = new GraphicsPath(); + + Rectangle r = ClientRect; + + r.Width = tabWidth; + r.Height = MultiUserTabHeight; + + path.AddLine(ClientRect.Left - 2, ClientRect.Top - 2, + ClientRect.Left - 2, Bounds.Top + TabRadius); + + path.AddArc(ClientRect.Left - 2, Bounds.Y, TabDia, TabDia, 180, 90); + + if (tabWidth + MultiUserTabHeight < ClientRect.Width) + { + // Full tab + + path.AddLines(new Point[] { + new Point(ClientRect.Left - 2 + TabRadius, Bounds.Top), + new Point(ClientRect.Left + tabWidth, Bounds.Top), + new Point(ClientRect.Left + tabWidth + MultiUserTabHeight, ClientRect.Top - 2) }); + } + else if (tabWidth < ClientRect.Width) + { + // Partial tab with end slant + + int n = ClientRect.Width - tabWidth + 2; + + path.AddLines(new Point[] { + new Point(ClientRect.Left - 2 + TabRadius, Bounds.Top), + new Point(ClientRect.Left + tabWidth, Bounds.Top), + new Point(ClientRect.Left - 2 + tabWidth + n, Bounds.Top + n), + new Point(ClientRect.Left - 2 + tabWidth + n, ClientRect.Top - 2) }); + } + else + { + // partial tab with no end slant + + path.AddLines(new Point[] { + new Point(ClientRect.Left - 2 + TabRadius, Bounds.Top), + new Point(ClientRect.Right + 1, Bounds.Top), + new Point(ClientRect.Right + 1, ClientRect.Top - 2) }); + } + + return (path); + } + + #endregion + + #endregion + + #region DrawVerticalLayout + + /// + /// Draws vertical tab layout + /// + /// + private void DrawVerticalLayout(ItemPaintArgs e) + { + if (CalendarView.ShowTabs == true) + { + Rectangle r = ClientRect; + + if (r.Height > 0) + { + if (CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Vertical) + { + r.X -= MultiUserTabHeight; + r.Width = MultiUserTabHeight; + + DrawVTab(e, string.IsNullOrEmpty(DisplayName) + ? OwnerKey + : DisplayName, r); + } + else + { + r.X -= MultiUserTabWidth; + r.Width = MultiUserTabWidth; + + DrawVTab2(e, string.IsNullOrEmpty(DisplayName) + ? OwnerKey + : DisplayName, r); + } + } + } + } + + #region DrawVTab + + /// + /// Draws the tab - border and content + /// + /// ItemPaintArgs + /// Tab text + /// Bounding rectangle + private void DrawVTab(ItemPaintArgs e, string text, Rectangle r) + { + if (e.ClipRectangle.X < _ClientRect.X) + { + Graphics g = e.Graphics; + + _TabWidth = _ClientRect.Height - MultiUserTabHeight; + + if (_TabWidth < MultiUserTabHeight) + _TabWidth = Math.Min(MultiUserTabHeight, Math.Max(0, _ClientRect.Height - 4)); + + bool isSelected = CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex; + + using (GraphicsPath path = GetVTabPath(_TabWidth)) + { + // Draw the tab + + if (CalendarView.DoRenderTabBackground(g, path, this, isSelected) == false) + { + using (Brush br = _CalendarColor.BrushPart( + isSelected ? _NClientData.TabSelBack : _NClientData.TabBack, r)) + { + g.FillPath(br, path); + } + + using (Pen pen = new + Pen(_CalendarColor.GetColor(_NClientData.TabBorder))) + { + g.DrawPath(pen, path); + } + } + + // Draw the tab text + + if (CalendarView.DoRenderTabContent(g, path, this, ref text, isSelected) == false) + { + r.Height -= 4; + + // Set uo our output to have vertically centered text + + StringFormat sf = new StringFormat(); + + sf.FormatFlags = StringFormatFlags.NoWrap; + sf.Alignment = StringAlignment.Center; + + // Calc our rect origin and prepare to + // output the SideBar text + + PointF ptf = new PointF(r.X, r.Bottom); + Rectangle rf = new Rectangle(0, 0, _TabWidth, MultiUserTabHeight); + + g.TranslateTransform(ptf.X, ptf.Y); + g.RotateTransform(-90); + + using (Brush br = _CalendarColor.BrushPart( + isSelected ? _NClientData.TabSelFore : _NClientData.TabFore, rf)) + { + g.DrawString(text, Font, br, rf, sf); + } + + g.ResetTransform(); + } + } + } + } + + #endregion + + #region GetVTabPath + + /// + /// Gets the tab graphics path + /// + /// Tab width + /// GraphicsPath + protected GraphicsPath GetVTabPath(int tabWidth) + { + GraphicsPath path = new GraphicsPath(); + + Rectangle r = ClientRect; + + r.X -= (MultiUserTabHeight + 1); + r.Width = MultiUserTabHeight; + + path.AddLine(r.Right, r.Bottom - 1, + r.X + TabRadius, r.Bottom - 1); + + path.AddArc(r.X, r.Bottom - 1 - TabDia, TabDia, TabDia, 90, 90); + + if (r.Height > MultiUserTabHeight * 2) + { + // Full tab + + path.AddLines(new Point[] { + new Point(r.X, r.Bottom - TabRadius), + new Point(r.X, r.Bottom - tabWidth), + new Point(r.Right, r.Bottom - tabWidth - MultiUserTabHeight) }); + } + else if (r.Height > MultiUserTabHeight) + { + // Partial tab with end slant + + int n = r.Height - MultiUserTabHeight; + + path.AddLines(new Point[] { + new Point(r.X, r.Bottom - TabRadius), + new Point(r.X, r.Top + n), + new Point(r.X + n, r.Y), + new Point(r.Right, r.Y) }); + } + else + { + // partial tab with no end slant + + path.AddLines(new Point[] { + new Point(r.X, Bounds.Bottom - TabRadius), + new Point(r.X, Bounds.Top), + new Point(r.X + MultiUserTabHeight, Bounds.Top) }); + } + + return (path); + } + + #endregion + + #region DrawVTab2 + + /// + /// Draws the tab - border and content + /// + /// ItemPaintArgs + /// Tab text + /// Bounding rectangle + private void DrawVTab2(ItemPaintArgs e, string text, Rectangle r) + { + if (e.ClipRectangle.X < _ClientRect.X) + { + Graphics g = e.Graphics; + + _TabWidth = _ClientRect.Width - MultiUserTabWidth; + + if (_TabWidth < MultiUserTabWidth) + _TabWidth = Math.Min(MultiUserTabWidth, Math.Max(0, _ClientRect.Width - 4)); + + bool isSelected = CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex; + + using (GraphicsPath path = GetVTab2Path(_TabWidth)) + { + // Draw the tab + + if (CalendarView.DoRenderTabBackground(g, path, this, isSelected) == false) + { + using (Brush br = _CalendarColor.BrushPart( + isSelected ? _NClientData.TabSelBack : _NClientData.TabBack, r)) + { + g.FillPath(br, path); + } + + using (Pen pen = new + Pen(_CalendarColor.GetColor(_NClientData.TabBorder))) + { + g.DrawPath(pen, path); + } + } + + // Draw the tab text + + if (CalendarView.DoRenderTabContent(g, path, this, ref text, isSelected) == false) + { + r.Y += 2; + r.Height -= 4; + + // Set uo our output to have vertically centered text + + StringFormat sf = new StringFormat(); + + sf.FormatFlags = StringFormatFlags.NoWrap; + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + // Calc our rect origin and prepare to + // output the SideBar text + + using (Brush br = _CalendarColor.BrushPart( + isSelected ? _NClientData.TabSelFore : _NClientData.TabFore, r)) + { + g.DrawString(text, Font, br, r, sf); + } + } + } + } + } + + #endregion + + #region GetVTab2Path + + /// + /// Gets the tab graphics path + /// + /// Tab width + /// GraphicsPath + protected GraphicsPath GetVTab2Path(int tabWidth) + { + GraphicsPath path = new GraphicsPath(); + + Rectangle r = ClientRect; + + r.X -= (MultiUserTabWidth + 1); + r.Width = MultiUserTabWidth; + + path.AddLine(r.Right, r.Bottom - 1, + r.X + TabRadius, r.Bottom - 1); + + path.AddArc(r.X, r.Bottom - 1 - TabDia, TabDia, TabDia, 90, 90); + path.AddArc(r.X, r.Top, TabDia, TabDia, 180, 90); + + path.AddLine(r.Right, r.Top, r.Right, r.Bottom - 1); + + path.CloseFigure(); + + return (path); + } + + #endregion + + #endregion + + #endregion + + #region GetTabPath + + /// + /// Gets the multiuser tab path + /// + /// + /// + GraphicsPath GetTabPath(int tabWidth) + { + if (NClientData.TabOrientation == eTabOrientation.Horizontal) + return (GetHTabPath(tabWidth)); + + if (CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Horizontal) + return (GetVTab2Path(tabWidth)); + + return (GetVTabPath(tabWidth)); + } + + #endregion + + #region PointInTab + + /// + /// Determines if the given Point is + /// within the View tab area + /// + /// Point in question + /// true if the Point is in the tab + private bool PointInTab(Point pt) + { + bool isInTab = false; + + if (CalendarView.IsMultiCalendar == true) + { + if (NClientData.TabOrientation == eTabOrientation.Horizontal) + { + if (pt.Y < ClientRect.Y) + { + using (GraphicsPath path = GetHTabPath(_TabWidth)) + { + if (path.IsVisible(pt) == true) + isInTab = true; + } + } + } + else + { + if (pt.X < ClientRect.X) + { + if (CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Vertical) + { + using (GraphicsPath path = GetVTabPath(_TabWidth)) + { + if (path.IsVisible(pt) == true) + isInTab = true; + } + } + else + { + using (GraphicsPath path = GetVTab2Path(_TabWidth)) + { + if (path.IsVisible(pt) == true) + isInTab = true; + } + } + } + } + + } + + return (isInTab); + } + + #endregion + + #region Mouse support + + #region InternalMouseDown + + /// + /// MouseDown processing + /// + /// MouseEventArgs + public override void InternalMouseDown(MouseEventArgs objArg) + { + // Pass the event on through + + base.InternalMouseDown(objArg); + + // Check to see if the use is attempting to reorder + // the view via MouseDown in the view tab + + Point pt = objArg.Location; + + if (PointInTab(pt) == true) + { + SelectedItem = null; + + _CalendarView.SelectedOwnerIndex = DisplayedOwnerKeyIndex; + + if (objArg.Button == MouseButtons.Left) + { + if (CalendarView.AllowTabReorder && CalendarView.DisplayedOwners.Count > 1) + { + _IsTabMoving = true; + _LastViewIndex = CalendarView.GetViewIndexFromPoint(pt); + } + } + } + else if (pt.Y >= ClientRect.Y) + { + _CalendarView.SelectedOwnerIndex = DisplayedOwnerKeyIndex; + } + + IsNewCopyDrag = false; + } + + #endregion + + #region InternalMouseMove + + /// + /// MouseMove processing + /// + /// + public override void InternalMouseMove(MouseEventArgs objArg) + { + // Pass the event on through + + base.InternalMouseMove(objArg); + + // If the user has initiated a tab reorder, then + // track the tab movement + + if (_IsTabMoving == true) + { + Point pt = objArg.Location; + + int viewIndex = CalendarView.GetViewIndexFromPoint(pt); + + // If the user has dragged the tab to another view location + // then reorder the tabs accordingly + + if (viewIndex >= 0 && viewIndex != _LastViewIndex) + { + CalendarView.ReorderViews(_LastViewIndex, viewIndex); + _LastViewIndex = viewIndex; + } + + MyCursor = Cursors.SizeAll; + } + } + + #endregion + + #region InternalMouseUp + + /// + /// MouseUp processing + /// + /// + public override void InternalMouseUp(MouseEventArgs objArg) + { + base.InternalMouseUp(objArg); + + // Hide our PosWindow if it is visible + + if (_PosWin != null) + _PosWin.Hide(); + + if (SelectedItem != null) + { + // DoAppointmentViewChanged + + if (IsMoving == true) + { + if (TimeChanged(SelectedItem) == true || OwnerChanged() == true || + IsCopyDrag == true || IsNewCopyDrag == true) + { + DoViewChanged(SelectedItem, eViewOperation.AppointmentMove); + } + } + else if (IsResizing == true) + { + if (TimeChanged(SelectedItem) == true) + DoViewChanged(SelectedItem, eViewOperation.AppointmentResize); + } + } + + // Reset our mouse states + + ClearMouseStates(); + } + + private bool TimeChanged(CalendarItem item) + { + return (item.StartTime != _oldStartTime || item.EndTime != _oldEndTime); + } + + private bool OwnerChanged() + { + if (OwnerKey != null) + return (OwnerKey.Equals(_oldOwnerKey) == false); + + return (false); + } + + private void DoViewChanged(CalendarItem item, eViewOperation eop) + { + if (item.StartTime != _oldStartTime) + UpdateReminders(item, _oldStartTime); + + CalendarView.DoAppointmentViewChanged(item, _oldOwnerKey, _oldStartTime, _oldEndTime, eop, _IsNewCopyDrag); + } + + /// + /// Clears all mouse related state flags + /// + protected void ClearMouseStates() + { + _IsMouseDown = false; + _IsMoving = false; + _IsStartResizing = false; + _IsEndResizing = false; + _IsTabMoving = false; + _IsCondMoving = false; + _IsCopyDrag = false; + } + + #endregion + + #endregion + + #region DragItem + + /// + /// Initiates dragging of a copy of the + /// current selectedItem - if the ctrl-key is pressed + /// + /// + protected bool DragCopy() + { + if (CalendarView.EnableDragCopy == true) + { + if (IsCopyDrag == false && IsNewCopyDrag == false && + (Control.ModifierKeys & Keys.Control) == Keys.Control) + { + AppointmentView av = SelectedItem as AppointmentView; + + if (av != null) + { + Appointment ap = av.Appointment.Copy(); + + CalendarModel.Appointments.Add(ap); + + IsNewCopyDrag = true; + + return (true); + } + } + } + + return (false); + } + + #endregion + + #region UpdateReminders + + /// + /// Updates associated appointment reminders + /// after an appointment has been moved + /// + protected void UpdateReminders(CalendarItem item, DateTime oldStartTime) + { + //AppointmentView view = item as AppointmentView; + + //if (view != null) + //{ + // ReminderCollection rc = view.Appointment.Reminders; + + // if (rc != null && rc.Count > 0) + // { + // TimeSpan ts = item.StartTime - oldStartTime; + + // for (int i = 0; i < rc.Count; i++) + // rc[i].ReminderTime = rc[i].ReminderTime.Add(ts); + // } + //} + } + + #endregion + + #region GetViewAreaFromPoint + + /// + /// Gets the view area under the given mouse + /// point (tab, header, content, etc) + /// + /// Point + /// eViewArea + public virtual eViewArea GetViewAreaFromPoint(Point pt) + { + if (Bounds.Contains(pt) == true) + { + if (NClientData.TabOrientation == eTabOrientation.Horizontal) + { + if (pt.Y < ClientRect.Y) + { + using (GraphicsPath path = GetTabPath(_TabWidth)) + { + if (path.IsVisible(pt) == true) + return (eViewArea.InTab); + } + } + } + else + { + if (pt.X < ClientRect.X) + { + using (GraphicsPath path = GetTabPath(_TabWidth)) + { + if (path.IsVisible(pt) == true) + return (eViewArea.InTab); + } + } + } + } + + return (eViewArea.NotInView); + } + + #endregion + + #region GetDateSelectionFromPoint + + /// + /// Gets the date selection from the given point. The startDate + /// and endDate will vary based upon the view type (WeekDay / Month) + /// + /// Point in question + /// out start date + /// out end date + /// True if a valid selection exists + /// at the given point + public virtual bool GetDateSelectionFromPoint( + Point pt, out DateTime startDate, out DateTime endDate) + { + startDate = new DateTime(); + endDate = new DateTime(); + + return (false); + } + + #endregion + + #region GetAppointmentView + + /// + /// Gets the appointment view created for an appointment in this view + /// + /// The appointment + /// Reference to AppointmentView or null if no view is found + public virtual AppointmentView GetAppointmentView(Appointment appointment) + { + for (int i = 0; i < SubItems.Count; i++) + { + AppointmentView view = SubItems[i] as AppointmentView; + + if (view != null) + { + if (view.Appointment == appointment) + return (view); + } + } + + return (null); + } + + #endregion + + #region GetAppointmentViewFromPoint + + /// + /// Gets the appointment view created for an appointment in this view + /// + /// The appointment + /// Reference to AppointmentView or null if no view is found + public virtual AppointmentView GetAppointmentViewFromPoint(Point pt) + { + for (int i = 0; i < SubItems.Count; i++) + { + AppointmentView view = SubItems[i] as AppointmentView; + + if (view != null) + { + if (view.Bounds.Contains(pt)) + return (view); + } + } + + return (null); + } + + #endregion + + + #region CustomCalendarItem + + /// + /// Gets the CustomCalendarItem created for this view + /// + /// Reference to CustomCalendarItem or null if none found + public virtual CustomCalendarItem GetCustomCalendarItem(CustomCalendarItem item) + { + if (item.BaseCalendarItem != null) + item = item.BaseCalendarItem; + + for (int i = 0; i < SubItems.Count; i++) + { + CustomCalendarItem view = SubItems[i] as CustomCalendarItem; + + if (view != null) + { + if (view == item || view.BaseCalendarItem == item) + return (view); + } + } + + return (null); + } + + #endregion + + #region Invalidate routines + + /// + /// Invalidates the given rectangle + /// + internal void InvalidateRect() + { + InvalidateRect(ClientRect, false); + } + + /// + /// Invalidates the entire calendar + /// bounding rect area + /// + /// NeedRecalcSize flag + internal void InvalidateRect(bool needRecalc) + { + InvalidateRect(ClientRect, needRecalc); + } + + /// + /// Invalidates the entire calendar + /// bounding rect area + /// + internal void InvalidateRect(Rectangle rect) + { + InvalidateRect(rect, false); + } + + /// + /// Invalidates the given rectangle + /// + /// Rectangle to invalidate + /// NeedRecalcSize flag + internal void InvalidateRect(Rectangle rect, bool needRecalc) + { + Control c = (Control)this.GetContainerControl(true); + + if (c != null) + { + rect.Height += 0; + rect.Width += 0; + + if (rect.Bottom >= ClientRect.Bottom) + rect.Width += 0; + + c.Invalidate(rect); + } + + if (needRecalc == true) + this.NeedRecalcSize = true; + } + + #endregion + + #region ResetView + + /// + /// Disconnects and resets the Model connection + /// + internal virtual void ResetView() + { + if (_Connector != null) + { + // Disconnect the Model + + _Connector.Disconnect(); + _Connector = null; + + // Reset our selected item + + SelectedItem = null; + } + + DateRangeChanged = false; + + NeedRecalcLayout = true; + NeedRecalcSize = true; + } + + #endregion + + #region ReloadView + + internal void ReloadView() + { + if (CalendarModel != null) + { + CalendarModel.BeginUpdate(); + CalendarModel.EndUpdate(); + } + } + + #endregion + + #region SetSelectedItem + + /// + /// Sets the current selected item + /// + /// Previously selected CalendarItem + /// New CalendarItem to select + /// Base selected CalendarItem + protected virtual CalendarItem SetSelectedItem(CalendarItem pci, CalendarItem nci) + { + return (null); + } + + #endregion + + #region UpdateDateSelection + + /// + /// Updates each monthWeeks DayRects to reflect + /// the date selection start and end values + /// + protected virtual void UpdateDateSelection() + { + } + + internal void SetDateSelection(DateTime dateStart, DateTime dateEnd) + { + UpdateDateSelection(); + } + + #endregion + + #region AutoSyncViewDate + + /// + /// AutoSync our view start date + /// + /// + protected void AutoSyncViewDate(eCalendarView syncView) + { + if (CalendarView.AutoSyncViewDates == true) + { + if (CalendarView.AutoSyncDate != DateTime.MinValue) + { + DateTime syncDate = CalendarView.AutoSyncDate; + + CalendarView.ShowViewDate(this.ECalendarView, syncDate); + + CalendarView.AutoSyncDate = syncDate; + } + } + } + + #endregion + + #region ExtendSelection + + /// + /// Extends the selection if the shift-key + /// is pressed with selection + /// + /// + /// + protected void ExtendSelection(ref DateTime startDate, ref DateTime endDate) + { + if (DateSelectionAnchor.HasValue == false || + ((Control.ModifierKeys & Keys.Shift) != Keys.Shift)) + { + DateSelectionAnchor = startDate; + } + else + { + if (DateSelectionAnchor < startDate) + startDate = DateSelectionAnchor.Value; + + else + { + DateTime anchorEnd = DateSelectionAnchor.Value.Add(endDate - startDate); + + if (anchorEnd > endDate) + endDate = anchorEnd; + } + } + + CalendarView.AutoSyncDate = startDate; + } + + #endregion + + #region ValidDateSelection + + protected bool ValidDateSelection() + { + if (DateSelectionStart.HasValue && DateSelectionEnd.HasValue) + { + if (DateSelectionAnchor.HasValue == false) + DateSelectionAnchor = DateSelectionStart; + + return (DateSelectionStart <= DateSelectionEnd); + } + + return (false); + } + + #endregion + + #region PosWindow support + + /// + /// Pos window update + /// + protected void UpdatePosWin(Rectangle viewRect) + { + if (IsStartResizing || IsEndResizing || IsMoving) + { + // Only display if the Alt key is pressed + + if ((Control.ModifierKeys & Keys.Alt) == Keys.Alt) + { + // Allocate our pos window if not + // previously allocated + + if (PosWin == null) + { + PosWin = new PosWin(this); + PosWin.Size = new Size(1, 1); + + Control c = (Control)this.GetContainerControl(true); + + if (c != null) + PosWin.Owner = c.FindForm(); + } + + PosWin.UpdateWin(viewRect); + } + else + { + if (PosWin != null) + PosWin.Hide(); + } + } + } + + #endregion + + #region GetIndicatorRect + + internal virtual Rectangle GetIndicatorRect(TimeIndicator ti) + { + return (Rectangle.Empty); + } + + internal virtual Rectangle GetIndicatorRect(TimeIndicator ti, DateTime time) + { + return (Rectangle.Empty); + } + + + #endregion + + #region InternalKeyUp + + internal virtual void InternalKeyUp(KeyEventArgs e) + { + } + + #endregion + + #region Copy implementation + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + BaseView objCopy = new BaseView(_CalendarView, _ECalendarView); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the BaseView specific properties to new instance of the item. + /// + /// New BaseView instance + protected override void CopyToItem(BaseItem copy) + { + BaseView objCopy = copy as BaseView; + + if (objCopy != null) + { + base.CopyToItem(objCopy); + + objCopy._DateSelectionStart = this._DateSelectionStart; + objCopy._DateSelectionEnd = this._DateSelectionEnd; + objCopy._DisplayName = this._DisplayName; + objCopy._EndDate = this._EndDate; + objCopy._StartDate = this._StartDate; + } + } + + #endregion + + #region IDisposable Members + + protected override void Dispose(bool disposing) + { + if (disposing == true && IsDisposed == false) + { + ResetView(); + HookEvents(false); + } + + base.Dispose(disposing); + } + + #endregion + } + + #region enums + + public enum eViewArea + { + NotInView, + + InTab, + InContent, + InAllDayPanel, + InDayOfWeekHeader, + InWeekHeader, + InSideBarPanel, + InIntervalHeader, + InPeriodHeader, + InCondensedView, + InMonthHeader + } + + public enum eTabOrientation + { + Vertical, + Horizontal, + } + + #endregion + + #region EventsArgs + /// + /// SelectedItemChangedEventArgs + /// + public class SelectedItemChangedEventArgs : ValueChangedEventArgs + { + public SelectedItemChangedEventArgs(CalendarItem oldValue, CalendarItem newValue) + : base(oldValue, newValue) + { + } + } + + /// + /// CalendarColorChangedEventArgs + /// + public class CalendarColorChangedEventArgs : ValueChangedEventArgs + { + public CalendarColorChangedEventArgs(eCalendarColor oldValue, eCalendarColor newValue) + : base(oldValue, newValue) + { + } + } + + #endregion +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarItem.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarItem.cs new file mode 100644 index 00000000..f903f26a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarItem.cs @@ -0,0 +1,420 @@ +#if FRAMEWORK20 +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class CalendarItem : PopupItem + { + #region enums + + public enum eHitArea + { + None, + Move, + LeftResize, + RightResize, + TopResize, + BottomResize + } + + #endregion + + #region Events + + /// + /// Occurs when CategoryColor has changed + /// + [Description("Occurs when the CategoryColor property has changed.")] + public event EventHandler CategoryColorChanged; + + /// + /// Occurs when StartTime has Changed + /// + public event EventHandler StartTimeChanged; + + /// + /// Occurs when EndTime has Changed + /// + public event EventHandler EndTimeChanged; + + /// + /// Occurs when IsSelected has Changed + /// + public event EventHandler IsSelectedChanged; + + /// + /// Occurs when CollateId has Changed + /// + public event EventHandler CollateIdChanged; + + #endregion + + #region Private variables + + private DateTime _StartTime; // Start time + private DateTime _EndTime; // End time + private string _CategoryColor; // CategoryColor + + private int _CollateId = -1; + + private object _ModelItem; // Model item + private object _RootItem; // Root model item + private bool _IsRecurring; // Is recurring + private bool _IsSelected; // Is selected + + private eHitArea _HitArea = eHitArea.None; + private DateTime _LastMouseDown = DateTime.MinValue; + + private uint _RefreshCount; + + #endregion + + /// + /// Constructor + /// + public CalendarItem() + { + // Set our default Model item + + _ModelItem = this; + + MouseUpNotification = true; + + SetIsContainer(true); + } + + #region Public properties + + #region CollateId + + /// + /// Gets or sets the CollateId used for TimeLine row collation. + /// + public virtual int CollateId + { + get { return (_CollateId); } + + set + { + if (_CollateId != value) + { + _CollateId = value; + + OnCollateIdChanged(); + } + } + } + + protected virtual void OnCollateIdChanged() + { + if (CollateIdChanged != null) + CollateIdChanged(this, new EventArgs()); + + this.Refresh(); + } + + #endregion + + #region StartTime + + /// + /// Gets or sets the CalendarItem Start time. + /// + public virtual DateTime StartTime + { + get { return (_StartTime); } + + set + { + if (_StartTime != value) + { + _StartTime = value; + + OnStartTimeChanged(); + } + } + } + + protected virtual void OnStartTimeChanged() + { + if (StartTimeChanged != null) + StartTimeChanged(this, new EventArgs()); + + this.Refresh(); + } + + #endregion + + #region EndTime + + /// + /// Gets or sets the CalendarItem End time. + /// + public virtual DateTime EndTime + { + get { return (_EndTime); } + + set + { + if (_EndTime != value) + { + _EndTime = value; + + OnEndTimeChanged(); + } + } + } + + protected virtual void OnEndTimeChanged() + { + if (EndTimeChanged != null) + EndTimeChanged(this, new EventArgs()); + + this.Refresh(); + } + + #endregion + + #region CategoryColor + + /// + /// Gets or sets the category color used for TimeLine CondensedView markers. + /// Use static members on Appointment class to assign the category color for example Appointment.CategoryRed. + /// + public virtual string CategoryColor + { + get { return (_CategoryColor); } + + set + { + if (_CategoryColor == null || _CategoryColor.Equals(value) == false) + { + string oldValue = _CategoryColor; + _CategoryColor = value; + + OnCategoryColorChanged(oldValue, value); + } + } + } + + /// + /// Sends ChangedEvent for the CategoryColor property + /// + /// Old CategoryColor + /// New CategoryColor + protected virtual void OnCategoryColorChanged(string oldValue, string newValue) + { + if (CategoryColorChanged != null) + CategoryColorChanged(this, new CategoryColorChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region ModelItem + + /// + /// Gets and sets the Model item + /// + public object ModelItem + { + get { return (_ModelItem); } + set { _ModelItem = value; } + } + + #endregion + + #region RootItem + + /// + /// Gets and sets the Root Model item + /// + public object RootItem + { + get { return (_RootItem); } + set { _RootItem = value; } + } + + #endregion + + #region IsRecurring + + /// + /// Gets and sets the IsRecurring item status + /// + public bool IsRecurring + { + get { return (_IsRecurring); } + set { _IsRecurring = value; } + } + + #endregion + + #region IsSelected + + /// + /// Gets and sets the selection state + /// + public virtual bool IsSelected + { + get { return (_IsSelected); } + + set + { + if (_IsSelected != value) + { + _IsSelected = value; + + Control c = this.ContainerControl as Control; + + if (c != null) + { + Rectangle r = Bounds; + r.Inflate(4, 4); + + c.Invalidate(r); + } + + Appointment ap = ModelItem as Appointment; + + if (ap != null) + ap.IsSelected = value; + + OnIsSelectedChanged(); + } + } + } + + private void OnIsSelectedChanged() + { + if (IsSelectedChanged != null) + IsSelectedChanged(this, new EventArgs()); + } + + #endregion + + #region HitArea + + /// + /// Gets and sets the last hit area + /// + public eHitArea HitArea + { + get { return (_HitArea); } + set { _HitArea = value; } + } + + #endregion + + #endregion + + #region Internal properties + + internal uint RefreshCount + { + get { return (_RefreshCount); } + set { _RefreshCount = value; } + } + + #endregion + + #region Mouse support + + /// + /// Handles control MouseDown events + /// + /// MouseEventArgs + public override void InternalMouseDown(MouseEventArgs objArg) + { + base.InternalMouseDown(objArg); + + if (objArg.Button == MouseButtons.Left) + { + if (IsSimpleMouseDown()) + this.IsSelected = true; + + InternalMouseMove(objArg); + + _LastMouseDown = DateTime.Now; + } + } + + /// + /// Determines if it is a simple, single-click MouseDown + /// + /// + private bool IsSimpleMouseDown() + { + return (_LastMouseDown == DateTime.MinValue || + _LastMouseDown != DateTime.MinValue && + DateTime.Now.Subtract(_LastMouseDown).TotalMilliseconds > SystemInformation.DoubleClickTime); + } + + #endregion + + #region RecalcSize + + public override void RecalcSize() + { + } + + #endregion + + #region Paint + + public override void Paint(ItemPaintArgs p) + { + } + + #endregion + + #region IsMarkupSupported + + /// + /// IsMarkupSupported + /// + protected override bool IsMarkupSupported + { + get { return (true); } + } + + #endregion + + #region Copy object + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + CalendarItem objCopy = new CalendarItem(); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the CalendarItem specific properties to new instance of the item. + /// + /// New CalendarItem instance + protected override void CopyToItem(BaseItem copy) + { + CalendarItem objCopy = copy as CalendarItem; + + if (objCopy != null) + { + base.CopyToItem(objCopy); + + objCopy._StartTime = this._StartTime; + objCopy._EndTime = this._EndTime; + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView.ico b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView.ico new file mode 100644 index 00000000..6b06e7ec Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView.ico differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/CalendarPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/CalendarPanel.cs new file mode 100644 index 00000000..250b561b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/CalendarPanel.cs @@ -0,0 +1,1339 @@ +#if FRAMEWORK20 +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.ScrollBar; +using DevComponents.DotNetBar.Touch; + +namespace DevComponents.DotNetBar.Schedule +{ + public class CalendarPanel : BaseItem + { + #region Private variables + + private CalendarView _CalendarView; // Associated CalendarView + + private HScrollBarAdv _HScrollBar; // Horizontal scroll bar + private int _HScrollPos; + private int _HsMaximum; + + private VScrollBarAdv _VScrollBar; // Vertical scroll bar + private int _VScrollPos; + private int _VsMaximum; + + private Size _AutoScrollMinSize = Size.Empty; + private Point _AutoScrollPosition = Point.Empty; + + private TouchHandler _TouchHandler; + private Rectangle _InnerBounds; + + private HScrollBarAdv _AHScrollBar; // Active Horizontal scroll bar + private VScrollBarAdv _AVScrollBar; // Active Vertical scroll bar + + #endregion + + /// + /// This is the main container panel for all + /// BaseView and TimeRulerPanel objects + /// + /// CalendarView + public CalendarPanel(CalendarView calendarView) + { + _CalendarView = calendarView; + + SetIsContainer(true); + + _CalendarView.SelectedViewChanged += _CalendarView_SelectedViewChanged; + + if (BarFunctions.IsWindows7 && TouchHandler.IsTouchEnabled) + { + _TouchHandler = new TouchHandler(_CalendarView, eTouchHandlerType.Gesture); + + _TouchHandler.PanBegin += TouchHandlerPanBegin; + _TouchHandler.Pan += TouchHandlerPan; + _TouchHandler.PanEnd += TouchHandlerPanEnd; + } + } + + #region Internal properties + + #region AutoScrollMinSize + + internal Size AutoScrollMinSize + { + get { return (_AutoScrollMinSize); } + + set + { + _AutoScrollMinSize = value; + + RecalcSize(); + } + } + + #endregion + + #region AutoScrollPosition + + internal Point AutoScrollPosition + { + get + { + Point pt = Point.Empty; + + if (_AHScrollBar != null && _AHScrollBar.Visible == true) + pt.X = _AHScrollBar.Value * _CalendarView.TimeLineColumnWidth; + + if (_AVScrollBar != null && _AVScrollBar.Visible == true) + pt.Y = _AVScrollBar.Value; + + return (pt); + } + + set + { + if (_CalendarView.SelectedView == eCalendarView.TimeLine) + { + if (_CalendarView.TimeLineColumnWidth > 0) + value.X /= _CalendarView.TimeLineColumnWidth; + } + + if (_AHScrollBar != null && _AHScrollBar.Visible == true) + { + if (value.X != _AHScrollBar.Value) + { + _AHScrollBar.Value = + Math.Min(_AHScrollBar.Maximum, + Math.Max(_AHScrollBar.Minimum, value.X)); + } + } + + if (_AVScrollBar != null && _AVScrollBar.Visible == true) + { + if (value.Y != _AVScrollBar.Value) + { + _AVScrollBar.Value = + Math.Min(_AVScrollBar.Maximum, + Math.Max(_AVScrollBar.Minimum, value.Y)); + } + } + } + } + + #endregion + + #region AHScrollBar + + internal HScrollBarAdv AHScrollBar + { + get { return (_AHScrollBar); } + set { _AHScrollBar = value; } + } + + #endregion + + #region AVScrollBar + + internal VScrollBarAdv AVScrollBar + { + get { return (_AVScrollBar); } + set { _AVScrollBar = value; } + } + + #endregion + + #region Checkit + + internal bool Checkit + { + get { return (m_CheckMouseMovePressed); } + set { m_CheckMouseMovePressed = value; } + } + + #endregion + + #region HScrollBar + + internal HScrollBarAdv HScrollBar + { + get { return (_HScrollBar); } + } + + #endregion + + #region InnerBounds + + internal Rectangle InnerBounds + { + get { return (_InnerBounds); } + } + + #endregion + + #region VScrollBar + + internal VScrollBarAdv VScrollBar + { + get { return (_VScrollBar); } + } + + #endregion + + #endregion + + #region Event processing + + /// + /// Handles SelectedView changes + /// + /// + /// + void _CalendarView_SelectedViewChanged(object sender, SelectedViewEventArgs e) + { + if (e.OldValue == eCalendarView.TimeLine) + { + if (_AVScrollBar != null) + _AVScrollBar.Visible = false; + } + + if (e.NewValue == eCalendarView.TimeLine) + { + if (_HScrollBar != null) + _HScrollBar.Visible = false; + } + + switch (e.NewValue) + { + case eCalendarView.TimeLine: + AVScrollBar = VScrollBar; + AHScrollBar = _CalendarView.TimeLineHScrollPanel.ScrollBar; + break; + + case eCalendarView.Day: + case eCalendarView.Week: + AVScrollBar = _CalendarView.WeekDayVScrollBar; + AHScrollBar = HScrollBar; + break; + + case eCalendarView.Year: + AVScrollBar = _CalendarView.YearVScrollPanel.ScrollBar; + AHScrollBar = HScrollBar; + break; + + default: + AVScrollBar = null; + AHScrollBar = null; + break; + } + + Size asMinSize = Size.Empty; + + if (_AVScrollBar != null && _AVScrollBar.Visible == true) + asMinSize.Height = _AVScrollBar.Maximum; + + if (_AHScrollBar != null && _AHScrollBar.Visible == true) + { + asMinSize.Width = _AHScrollBar.Maximum; + + if (e.NewValue == eCalendarView.TimeLine) + asMinSize.Width *= _CalendarView.TimeLineColumnWidth; + } + + _AutoScrollMinSize = asMinSize; + } + + #endregion + + #region RecalcSize + + /// + /// Performs object recalc processing + /// + public override void RecalcSize() + { + _InnerBounds = Bounds; + + if (SubItems.Count > 0) + { + if (Bounds.Width > 0 && Bounds.Height > 0) + { + switch (_CalendarView.SelectedView) + { + case eCalendarView.Day: + case eCalendarView.Week: + RecalcWeekDay(); + break; + + case eCalendarView.Month: + RecalcMonth(); + break; + + case eCalendarView.Year: + RecalcYear(); + break; + + case eCalendarView.TimeLine: + RecalcTimeLine(); + break; + } + + base.RecalcSize(); + } + } + } + + #region RecalcWeekDay + + /// + /// Recalculates all WeekDay views + /// + private void RecalcWeekDay() + { + // Calculate the necessary params for calculating + // the divided width for each subItems in our panel + + int trWidth = 0; + int vsWidth = 0; + + int vCount = SubItems.Count; + + if (SubItems[0] is VScrollPanel) + { + vCount--; + vsWidth = _CalendarView.VsWidth; + + if (SubItems[1] is TimeRulerPanel) + { + vCount--; + trWidth = _CalendarView.TimeRulerWidth; + } + } + + // Configure the subItems based upon the + // previously calculated display params + + if (vCount > 0) + ConfigureWeekDayItems(vCount, trWidth, vsWidth); + + _InnerBounds.X += trWidth; + _InnerBounds.Width -= (trWidth + vsWidth); + + _InnerBounds.Y += _CalendarView.WeekDayVScrollBar.Location.Y; + _InnerBounds.Height -= _InnerBounds.Y; + } + + #region ConfigureWeekDayItems + + /// + /// Configures the CalendarPanel subItems + /// + /// View count + /// TimeRuler width + /// Vert Scrollbar width + private void ConfigureWeekDayItems(int vCount, int trWidth, int vsWidth) + { + Rectangle r = Bounds; + + // Calculate our default viewWidth + + int bvWidth = Bounds.Width - (trWidth + vsWidth); + float viewWidth = (float)bvWidth / vCount; + + // Sync our current item params with our current + // horizontal scrollBar states + + ConfigDhScrollBar(ref r, + ref viewWidth, vCount, trWidth, vsWidth); + + // If we have a TimRulerPanel, then + // set it's location and size + + if (trWidth > 0) + { + r.X = Bounds.X; + r.Width = trWidth; + + SubItems[1].Bounds = r; + SubItems[1].RecalcSize(); + } + + // Loop through each BaseView item, + // setting it's location and size + + _CalendarView.StartSlice = -1; + _CalendarView.NumberOfSlices = 0; + + float fxPos = Bounds.X + trWidth + _HScrollPos; + BaseView view = null; + + int n = vCount; + + for (int i = 0; i < SubItems.Count; i++) + { + if (SubItems[i] is BaseView) + { + r.X = (int)fxPos; + fxPos += viewWidth; + + r.Width = (int)(fxPos - r.X - (--n > 0 ? 2 : 0)); + + SubItems[i].Bounds = r; + SubItems[i].Displayed = r.IntersectsWith(Bounds); + + if (SubItems[i].Displayed == true) + { + view = SubItems[i] as BaseView; + + if (view != null) + { + view.NeedRecalcLayout = true; + view.RecalcSize(); + } + } + } + } + + // If we need to align the WorkDay times, then + // make sure all displayed WeekDay views are kept in sync + + if (_CalendarView.ShowOnlyWorkDayHours == true && _CalendarView.IsMultiCalendar == true) + { + for (int i = 0; i < SubItems.Count; i++) + { + WeekDayView wv = SubItems[i] as WeekDayView; + + if (wv != null && wv.Displayed == true) + { + if (wv.LocalStartSlice != _CalendarView.StartSlice || + wv.LocalNumberOfSlices != _CalendarView.NumberOfSlices) + { + wv.NeedRecalcLayout = true; + wv.RecalcSize(); + } + } + } + } + + // If we have a VScrollPanel, then + // set it's location and size + + if (vsWidth > 0) + { + r.X = Bounds.Right - vsWidth; + r.Width = vsWidth; + + int delta = _CalendarView.AllDayPanelHeight; + + r.Y = delta; + r.Height = 50; + + if (view != null) + { + r.Y += view.ClientRect.Y + view.DayOfWeekHeaderHeight; + r.Height = Math.Max(r.Height, view.ClientRect.Height - (delta + view.DayOfWeekHeaderHeight)); + } + + SubItems[0].Bounds = r; + SubItems[0].RecalcSize(); + } + } + + #endregion + + #endregion + + #region RecalcMonth + + /// + /// Recalculates Month views + /// + private void RecalcMonth() + { + // Configure the subItems based upon the + // previously calculated display params + + ConfigureMonthItems(SubItems.Count); + } + + #region ConfigureMonthItems + + /// + /// Configures the CalendarPanel subItems + /// + /// View count + private void ConfigureMonthItems(int vCount) + { + Rectangle r = Bounds; + + // Calculate our default viewWidth + + float viewWidth = (float)Bounds.Width / vCount; + + // Sync our current item params with our current + // horizontal scrollBar states + + ConfigDhScrollBar(ref r, ref viewWidth, vCount, 0, 0); + + // Loop through each BaseView item, + // setting it's location and size + + float fxPos = Bounds.X + _HScrollPos; + int n = vCount; + + for (int i = 0; i < SubItems.Count; i++) + { + if (SubItems[i] is BaseView) + { + r.X = (int)fxPos; + fxPos += viewWidth; + + r.Width = (int)(fxPos - r.X - (--n > 0 ? 2 : 0)); + + SubItems[i].Bounds = r; + SubItems[i].Displayed = r.IntersectsWith(Bounds); + + if (SubItems[i].Displayed == true) + { + BaseView view = SubItems[i] as BaseView; + + if (view != null) + { + view.NeedRecalcLayout = true; + view.RecalcSize(); + } + } + } + } + } + + #endregion + + #endregion + + #region RecalcYear + + /// + /// Recalculates all Year views + /// + private void RecalcYear() + { + // Calculate the necessary params for calculating + // the divided width for each subItems in our panel + + int vsWidth = 0; + + int vCount = SubItems.Count; + + if (SubItems[0] is VScrollPanel) + { + vCount--; + vsWidth = _CalendarView.VsWidth; + } + + // Configure the subItems based upon the + // previously calculated display params + + if (vCount > 0) + ConfigureYearItems(vCount, vsWidth); + + _InnerBounds.Y = _CalendarView.YearVScrollPanel.ScrollBar.Location.Y; + _InnerBounds.Height -= _InnerBounds.Y; + + } + + #region ConfigureYearItems + + /// + /// Configures the CalendarPanel subItems + /// + /// View count + /// Vert Scrollbar width + private void ConfigureYearItems(int vCount, int vsWidth) + { + Rectangle r = Bounds; + + // Calculate our default viewWidth + + int bvWidth = Bounds.Width; + float viewWidth = (float) bvWidth/vCount; + + // Sync our current item params with our current + // horizontal scrollBar states + + ConfigDhScrollBar(ref r, ref viewWidth, vCount, 0, vsWidth); + + // Locate and calculate the default size of our YearView + + BaseView view = null; + + for (int i = 0; i < SubItems.Count; i++) + { + view = SubItems[i] as BaseView; + + if (view != null) + { + Rectangle t = r; + t.Width = (int) viewWidth; + + SubItems[i].Bounds = t; + + view.NeedRecalcLayout = true; + view.RecalcSize(); + + break; + } + } + + if (view != null) + { + // If we have a VScrollPanel, then + // set it's location and size + + if (vsWidth > 0) + { + if (_CalendarView.YearViewMax + 1 == view.ClientRect.Height) + { + SubItems[0].Visible = false; + ((VScrollPanel)SubItems[0]).DisableScrollBar(); + } + else + { + bvWidth = Bounds.Width - vsWidth; + viewWidth = (float)bvWidth / vCount; + + r = Bounds; + ConfigDhScrollBar(ref r, ref viewWidth, vCount, 0, vsWidth); + + Rectangle t = r; + t.Y += view.ClientRect.Y; + t.Height = Math.Max(50, view.ClientRect.Height); + + t.X = Bounds.Right - vsWidth; + t.Width = vsWidth; + + SubItems[0].Bounds = t; + SubItems[0].RecalcSize(); + SubItems[0].Visible = true; + } + } + + // Loop through each BaseView item, + // setting it's location and size + + float fxPos = Bounds.X + _HScrollPos; + int n = vCount; + + for (int i = 0; i < SubItems.Count; i++) + { + if (SubItems[i] is BaseView) + { + r.X = (int) fxPos; + fxPos += viewWidth; + + r.Width = (int) (fxPos - r.X - (--n > 0 ? 2 : 0)); + + SubItems[i].Bounds = r; + SubItems[i].Displayed = r.IntersectsWith(Bounds); + + if (SubItems[i].Displayed == true) + { + view = SubItems[i] as BaseView; + + if (view != null) + { + view.NeedRecalcLayout = true; + view.RecalcSize(); + } + } + } + } + } + } + + #endregion + + #endregion + + #region RecalcTimeLine + + /// + /// Recalculates TimeLine views + /// + private void RecalcTimeLine() + { + int vCount = SubItems.Count; + + if (SubItems.Contains("TimeLineHScrollPanel")) + vCount--; + + if (SubItems.Contains("TimeLineHeaderPanel")) + vCount--; + + if (vCount > 0) + ConfigureTItems(vCount); + } + + #region ConfigureTItems + + /// + /// Configures TimeLine view items + /// + /// + private void ConfigureTItems(int vCount) + { + Rectangle r = Bounds; + + if (_CalendarView.TimeLineShowHScrollBar == true) + r.Height -= _CalendarView.HsHeight; + + // TimeLineHeaderPanel + + int headerHeight = 0; + int iHeaderPanel = SubItems.IndexOf("TimeLineHeaderPanel"); + + if (iHeaderPanel >= 0) + { + if (iHeaderPanel != 0) + { + BaseItem bi = SubItems[iHeaderPanel]; + + SubItems.RemoveAt(iHeaderPanel); + SubItems.Insert(0, bi); + + iHeaderPanel = 0; + } + + if (_CalendarView.TimeLineShowIntervalHeader == true) + headerHeight += _CalendarView.TimeLineIntervalHeaderHeight; + + if (_CalendarView.TimeLineShowPeriodHeader == true) + headerHeight += _CalendarView.TimeLinePeriodHeaderHeight; + + r.Y += headerHeight; + r.Height -= headerHeight; + } + + _InnerBounds.Y = r.Y; + _InnerBounds.Height = r.Height; + + // Calculate our viewHeight + + int vsWidth = 0; + + float viewHeight = (float) r.Height/vCount; + + if (_CalendarView.TimeLineHeight > viewHeight) + { + viewHeight = _CalendarView.TimeLineHeight; + vsWidth = _CalendarView.VsWidth; + } + + // VScrollPanel + + ConfigureTvScrollBar(r, vCount, vsWidth); + + // Sync our current item params with our current + // horizontal scrollBar states + + r.Width -= vsWidth; + + Rectangle r2 = r; + + if (_CalendarView.IsMultiCalendar == true && + _CalendarView.ShowTabs == true) + { + if (_CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Vertical) + { + r2.X += _CalendarView.MultiUserTabHeight + 4; + r2.Width -= (_CalendarView.MultiUserTabHeight + 4); + } + else + { + r2.X += _CalendarView.TimeLineMultiUserTabWidth + 4; + r2.Width -= (_CalendarView.TimeLineMultiUserTabWidth + 4); + } + + _InnerBounds.X = r2.X; + _InnerBounds.Width = r2.Width; + } + + // TimeLineHeaderPanel + + if (iHeaderPanel >= 0) + { + r2.Y = Bounds.Y; + r2.Height = headerHeight; + + SubItems[iHeaderPanel].Bounds = r2; + SubItems[iHeaderPanel].RecalcSize(); + } + + // TimeLineView + + r2 = r; + + float fxPos = r2.Y + _VScrollPos; + + for (int i = 0; i < SubItems.Count; i++) + { + if (SubItems[i] is TimeLineView) + { + r2.Y = (int) fxPos; + fxPos += viewHeight; + + r2.Height = (int) (fxPos - r2.Y); + + SubItems[i].Bounds = r2; + SubItems[i].Displayed = r2.IntersectsWith(Bounds); + + if (SubItems[i].Displayed == true) + SubItems[i].RecalcSize(); + } + } + + // If we have an HScrollPanel, then + // set it's location and size + + int iScrollPanel = SubItems.IndexOf("TimeLineHScrollPanel"); + + if (iScrollPanel >= 0) + { + if (_CalendarView.IsMultiCalendar == true && + _CalendarView.ShowTabs == true) + { + if (_CalendarView.TimeLineMultiUserTabOrientation == eOrientation.Vertical) + { + r.X += (_CalendarView.MultiUserTabHeight + 4); + r.Width -= (_CalendarView.MultiUserTabHeight + 4); + } + else + { + r.X += (_CalendarView.TimeLineMultiUserTabWidth + 4); + r.Width -= (_CalendarView.TimeLineMultiUserTabWidth + 4); + } + } + + r.Y = Bounds.Bottom - _CalendarView.HsHeight; + r.Height = _CalendarView.HsHeight; + + SubItems[iScrollPanel].Bounds = r; + SubItems[iScrollPanel].RecalcSize(); + } + } + + #endregion + + #endregion + + #region Horizontal scrollbar support + + #region ConfigDhScrollBar + + /// + /// Configures default view horizontal scrollBar + /// + /// + /// + /// + /// + /// + private void ConfigDhScrollBar(ref Rectangle r, + ref float viewWidth, int vCount, int trWidth, int vsWidth) + { + if (_CalendarView.ViewWidth > viewWidth) + { + viewWidth = _CalendarView.ViewWidth + 2; + r.Height -= _CalendarView.HsHeight; + + _HsMaximum = (int)(viewWidth * vCount); + + if (_HScrollBar == null) + SetUpDhScrollBar(); + + if (_HScrollBar != null) + { + UpdateDhScrollBar(trWidth, vsWidth); + + if (_HScrollBar.Value > _HsMaximum - _HScrollBar.LargeChange + 1) + { + _HScrollPos = -_HsMaximum - _HScrollBar.LargeChange; + _HScrollBar.Value = _HsMaximum - _HScrollBar.LargeChange; + } + } + } + else + { + if (_HScrollBar != null) + { + _HScrollPos = 0; + _HScrollBar.Value = 0; + + _HScrollBar.Visible = false; + } + } + } + + #endregion + + #region SetUpDhScrollBar + + /// + /// Sets up default view horizontal scrollbar + /// + private void SetUpDhScrollBar() + { + _HScrollBar = new HScrollBarAdv(); + _HScrollBar.Height = _CalendarView.HsHeight; + + Control c = (Control)this.GetContainerControl(true); + + if (c != null) + c.Controls.Add(_HScrollBar); + + _HScrollBar.ValueChanged += DhScrollBarValueChanged; + } + + #endregion + + #region UpdateDhScrollBar + + /// + /// Updates default view horizontal scrollbar + /// + private void UpdateDhScrollBar(int trWidth, int vsWidth) + { + Point pt = new Point(Bounds.X + trWidth, + Bounds.Bottom - _CalendarView.HsHeight); + + _HScrollBar.Location = pt; + _HScrollBar.Width = Math.Max(50, Bounds.Width - (trWidth + vsWidth)); + + _HScrollBar.SmallChange = 10; + _HScrollBar.LargeChange = _HScrollBar.Width; + _HScrollBar.Maximum = _HsMaximum; + + _HScrollBar.Visible = true; + _HScrollBar.BringToFront(); + + _HScrollBar.Refresh(); + } + + #endregion + + #region DhScrollBarValueChanged + + /// + /// Processes default view horizontal + /// scrollbar value changes + /// + /// + /// + void DhScrollBarValueChanged(object sender, EventArgs e) + { + if (_HScrollPos != -_HScrollBar.Value) + { + _HScrollPos = -_HScrollBar.Value; + + NeedRecalcSize = true; + Refresh(); + } + } + + #endregion + + #endregion + + #region Vertical scrollbar support + + #region ConfigureTvScrollBar + + /// + /// Configures TimeLine View vertical scrollbar + /// + /// + /// + /// + private void ConfigureTvScrollBar(Rectangle r, int vCount, int vsWidth) + { + if (vsWidth > 0) + { + _VsMaximum = _CalendarView.TimeLineHeight * vCount + 2; + + if (_VScrollBar == null) + SetUpTvScrollBar(); + + if (_VScrollBar != null) + { + UpdateTvScrollBar(r, vsWidth); + + if (_VScrollBar.Value > _VsMaximum) + _VScrollBar.Value = _VsMaximum; + } + } + else + { + if (_VScrollBar != null) + { + _VScrollPos = 0; + _VScrollBar.Value = 0; + + _VScrollBar.Visible = false; + } + } + } + + #endregion + + #region SetUpTvScrollBar + + /// + /// Sets up TimeLine vertical scrollbar + /// + private void SetUpTvScrollBar() + { + _VScrollBar = new VScrollBarAdv(); + _VScrollBar.Width = _CalendarView.VsWidth; + + Control c = (Control)this.GetContainerControl(true); + + if (c != null) + c.Controls.Add(_VScrollBar); + + _VScrollBar.ValueChanged += VScrollBar_ValueChanged; + } + + #endregion + + #region UpdateTvScrollBar + + /// + /// Updates our vertical scrollbar + /// + /// + /// + private void UpdateTvScrollBar(Rectangle r, int vsWidth) + { + Point pt = new Point(r.Right - vsWidth, r.Top); + + _VScrollBar.Location = pt; + _VScrollBar.Height = Math.Max(30, r.Height); + + _VScrollBar.SmallChange = _CalendarView.TimeLineHeight; + _VScrollBar.LargeChange = _VScrollBar.Height; + _VScrollBar.Maximum = _VsMaximum; + + _VScrollBar.Visible = true; + _VScrollBar.BringToFront(); + + _VScrollBar.Refresh(); + } + + #endregion + + #region VScrollBar_ValueChanged + + /// + /// Processes TimeLine vertical scrollbar changes + /// + /// + /// + void VScrollBar_ValueChanged(object sender, EventArgs e) + { + if (_VScrollPos != -_VScrollBar.Value) + { + _VScrollPos = -_VScrollBar.Value; + + NeedRecalcSize = true; + Refresh(); + } + } + + #endregion + + #endregion + + #endregion + + #region Paint + + /// + /// Paint processing + /// + /// + public override void Paint(ItemPaintArgs e) + { + if (_CalendarView.IsUpdateSuspended == false) + { + if (SubItems.Count > 0) + { + PaintNonViewItems(e); + PaintBaseViewItems(e); + } + } + } + + /// + /// Paints the non-BaseView items + /// + /// ItemPaintArgs + private void PaintNonViewItems(ItemPaintArgs e) + { + // Loop through each item, initiating + // a paint on each one + + for (int i = 0; i < SubItems.Count; i++) + { + if ((SubItems[i] is BaseView) == false) + { + if (SubItems[i].Bounds.IntersectsWith(e.ClipRectangle)) + SubItems[i].Paint(e); + } + } + } + + /// + /// Paints the BaseView items + /// + /// ItemPaintArgs + private void PaintBaseViewItems(ItemPaintArgs e) + { + Rectangle r = Bounds; + + if (_CalendarView.SelectedView == eCalendarView.TimeLine) + { + int n = 0; + + if (_CalendarView.TimeLineShowIntervalHeader == true) + n += _CalendarView.TimeLineIntervalHeaderHeight; + + if (_CalendarView.TimeLineShowPeriodHeader == true) + n += _CalendarView.TimeLinePeriodHeaderHeight; + + r.Y += n; + + if (_CalendarView.TimeLineShowHScrollBar == true) + r.Height -= (_CalendarView.HsHeight + n); + } + else + { + if (SubItems[0] is VScrollPanel) + { + if (SubItems[0].Visible == true) + r.Width -= _CalendarView.VsWidth; + } + + if (SubItems.Count > 1 && SubItems[1] is TimeRulerPanel) + { + r.X = _CalendarView.TimeRulerWidth; + r.Width -= _CalendarView.TimeRulerWidth; + } + } + + Region rgnSave = e.Graphics.Clip; + + using (Region rgn = new Region(r)) + { + e.Graphics.Clip = rgn; + + for (int i = 0; i < SubItems.Count; i++) + { + if (SubItems[i] is BaseView) + { + if (SubItems[i].Displayed == true) + SubItems[i].Paint(e); + } + } + } + + e.Graphics.Clip = rgnSave; + } + + #endregion + + #region Touch Handling + + #region Private variables + + private bool _TouchDrag; + + private Point _TouchStartLocation; + private Point _TouchStartScrollPosition; + + private Rectangle _TouchInnerBounds; + + #endregion + + #region Private properties + + private int MaximumReversePageOffset + { + get { return 0; } + } + + #endregion + + #region TouchHandlerPanBegin + + private void TouchHandlerPanBegin(object sender, Touch.GestureEventArgs e) + { + if (_CalendarView.TouchEnabled == true) + { + _TouchInnerBounds = _InnerBounds; + _TouchStartLocation = e.Location; + _TouchStartScrollPosition = AutoScrollPosition; + _TouchDrag = true; + + e.Handled = true; + } + } + + #endregion + + #region TouchHandlerPan + + private void TouchHandlerPan(object sender, Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + Point autoScrollPosition = AutoScrollPosition; + Size autoScrollMinSize = AutoScrollMinSize; + + int offset = (_TouchStartLocation.X - e.Location.X); + int offsetChange = offset + _TouchStartScrollPosition.X; + + // X Scroll + + bool overflowH = false; + + if (autoScrollMinSize.Width > _TouchInnerBounds.Width) + { + if (offsetChange + MaximumReversePageOffset > autoScrollMinSize.Width) + { + autoScrollPosition.X = autoScrollMinSize.Width; + overflowH = true; + } + else if (offsetChange < MaximumReversePageOffset) + { + autoScrollPosition.X = MaximumReversePageOffset; + overflowH = true; + } + else + autoScrollPosition.X = offsetChange; + } + + // Y Scroll + + bool overflowV = false; + + if (autoScrollMinSize.Height > _TouchInnerBounds.Height) + { + offset = (_TouchStartLocation.Y - e.Location.Y); + offsetChange = offset + _TouchStartScrollPosition.Y; + + if (offsetChange + MaximumReversePageOffset > autoScrollMinSize.Height) + { + autoScrollPosition.Y = autoScrollMinSize.Height; + overflowV = true; + } + else if (offsetChange < MaximumReversePageOffset) + { + autoScrollPosition.Y = MaximumReversePageOffset; + overflowV = true; + } + else + autoScrollPosition.Y = offsetChange; + } + + if (AutoScrollPosition != autoScrollPosition) + { + AutoScrollPosition = autoScrollPosition; + Update(); + } + + if (overflowH && overflowV && e.IsInertia) + EndTouchPan(); + + e.Handled = true; + } + } + + #endregion + + #region TouchHandlerPanEnd + + private void TouchHandlerPanEnd(object sender, Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + EndTouchPan(); + + e.Handled = true; + } + } + + #endregion + + #region EndTouchPan + + private void EndTouchPan() + { + _TouchDrag = false; + + Point autoScrollPosition = AutoScrollPosition; + Size autoScrollMinSize = AutoScrollMinSize; + + if (autoScrollMinSize.Width > _TouchInnerBounds.Width) + { + if (autoScrollMinSize.Width < autoScrollPosition.X) + autoScrollPosition = new Point(autoScrollMinSize.Width, autoScrollPosition.Y); + + else if (autoScrollPosition.X < 0) + autoScrollPosition = new Point(0, autoScrollPosition.Y); + } + + if (autoScrollMinSize.Height > _TouchInnerBounds.Height) + { + if (autoScrollMinSize.Height < autoScrollPosition.Y) + autoScrollPosition = new Point(autoScrollPosition.X, autoScrollMinSize.Height); + + else if (autoScrollPosition.Y < 0) + autoScrollPosition = new Point(autoScrollPosition.X, 0); + } + + if (AutoScrollPosition != autoScrollPosition) + AutoScrollPosition = autoScrollPosition; + } + + #endregion + + #endregion + + #region Copy + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + CalendarPanel objCopy = new CalendarPanel(_CalendarView); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the CalendarPanel specific properties to new instance of the item. + /// + /// New CalendarPanel instance + protected override void CopyToItem(BaseItem copy) + { + CalendarPanel objCopy = copy as CalendarPanel; + base.CopyToItem(objCopy); + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/CalendarView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/CalendarView.cs new file mode 100644 index 00000000..0ba005fb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/CalendarView.cs @@ -0,0 +1,10346 @@ +#if FRAMEWORK20 +using System; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.Rendering; +using DevComponents.DotNetBar.ScrollBar; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + [ToolboxItem(true), ToolboxBitmap(typeof(CalendarView), "Schedule.CalendarView.ico")] + [Designer("DevComponents.DotNetBar.Design.CalendarViewDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class CalendarView : ItemControl + { + #region Constants + + private const int MinutesPerHour = 60; + private const int HoursPerDay = 24; + private const int DaysPerYear = 365; + + private const int MinutesPerDay = MinutesPerHour * HoursPerDay; + private const int MinutesPerYear = MinutesPerDay * DaysPerYear; + + private const int MaxMinuteDuration = 60; + private const int MaxHourDuration = 24; + private const int MaxDayDuration = 365; + private const int MaxYearDuration = 10; + + #endregion + + #region Events + + #region BaseView Events + + /// + /// Occurs when CalendarModel has changed + /// + [Description("Occurs when CalendarModel has changed.")] + public event EventHandler ModelChanged; + + /// + /// Occurs when DateSelectionStart has changed + /// + [Description("Occurs when DateSelectionStart has changed.")] + public event EventHandler DateSelectionStartChanged; + + /// + /// Occurs when DateSelectionEnd has changed + /// + [Description("Occurs when DateSelectionEnd has changed.")] + public event EventHandler DateSelectionEndChanged; + + /// + /// Occurs when the Day, Week, or Month view date(s) have changed + /// + [Description("Occurs when the Day, Week, or Month view date(s) have changed.")] + public event EventHandler ViewDateChanged; + + /// + /// Occurs when SelectedView has Changed + /// + [Description("Occurs when SelectedView has Changed.")] + public event EventHandler SelectedViewChanged; + + /// + /// Occurs when SelectedOwner has Changed + /// + [Description("Occurs when SelectedOwner has Changed.")] + public event EventHandler SelectedOwnerChanged; + + /// + /// Occurs when EnableDragDrop has changed + /// + [Description("Occurs when EnableDragDrop has changed.")] + public event EventHandler EnableDragDropChanged; + + /// + /// Occurs when DisplayedOwners has Changed + /// + [Description("Occurs when DisplayedOwners has Changed.")] + public event EventHandler DisplayedOwnersChanged; + + /// + /// Occurs when TimeIndicators has changed + /// + [Description("Occurs when TimeIndicators has changed.")] + public event EventHandler TimeIndicatorsChanged; + + /// + /// Occurs when a TimeIndicator time has changed + /// + [Description("Occurs when a TimeIndicator time has changed.")] + public event EventHandler TimeIndicatorTimeChanged; + + /// + /// Occurs when a TimeIndicator Color has changed + /// + [Description("Occurs when a TimeIndicator Color has changed.")] + public event EventHandler TimeIndicatorColorChanged; + + /// + /// Occurs when ViewDisplayCustomizations have changed + /// + [Description("Occurs when ViewDisplayCustomizations have changed.")] + public event EventHandler ViewDisplayCustomizationsChanged; + + /// + /// Occurs when a Tab's background needs rendered + /// + [Description("Occurs when a Tab's background needs rendered.")] + public event EventHandler RenderTabBackground; + + /// + /// Occurs when a Tab's content (text, etc) needs rendered + /// + [Description("Occurs when a Tab's content (text, etc) needs rendered.")] + public event EventHandler RenderTabContent; + + /// + /// Occurs when a View Border needs rendered + /// + [Description("Occurs when a View Border needs rendered.")] + public event EventHandler RenderViewBorder; + + /// + /// Occurs when a view load/reload has occurred + /// + [Description("Occurs when a view load/reload has occurred.")] + public event EventHandler ViewLoadComplete; + + /// + /// Occurs when a View date is changing + /// + [Description("Occurs when a View date is changing.")] + public event EventHandler ViewDateChanging; + + #endregion + + #region AppointmentView Events + + /// + /// Occurs before an AppointmentView is about to change + /// + [Description("Occurs before an AppointmentView is about to change.")] + public event EventHandler BeforeAppointmentViewChange; + + /// + /// Occurs when an AppointmentView is changing + /// + [Description("Occurs when an AppointmentView is changing.")] + public event EventHandler AppointmentViewChanging; + + /// + /// Occurs when an AppointmentView has changed + /// + [Description("Occurs when an AppointmentView has changed.")] + public event EventHandler AppointmentViewChanged; + + /// + /// Occurs when Appointment Reminder has been reached.")] + /// + [Description("Occurs when Appointment Reminder has been reached.")] + public event EventHandler AppointmentReminder; + + /// + /// Occurs when Appointment StartTime has been reached.")] + /// + [Description("Occurs when Appointment StartTime has been reached.")] + public event EventHandler AppointmentStartTimeReached; + + /// + /// Occurs when Appointment DisplayTemplate text is needed + /// + [Description("Occurs when Appointment DisplayTemplate text is needed.")] + public event EventHandler GetDisplayTemplateText; + + /// + /// Occurs when an AppointmentView is about to be rendered + /// + [Description("Occurs when an AppointmentView is about to be rendered.")] + public event EventHandler AppointmentViewPreRender; + + /// + /// Occurs when an AppointmentView has been rendered + /// + [Description("Occurs when an AppointmentView has been rendered.")] + public event EventHandler AppointmentViewPostRender; + + /// + /// Occurs when Appointment GroupId is needed (used to logically group + /// appointments together when displayed in the WeekDay view) + /// + [Description("Occurs when Appointment GroupId is needed (used to logically group appointments together when displayed in the WeekDay view).")] + public event EventHandler GetAppointmentGroupId; + + /// + /// Occurs when two CalendarItems need detail sorting. + /// When items are of equal sort value, based upon their calendar time, this + /// event will be raised to give the user the ability to perform more detailed + /// sorting as needed - such as via Subject and/or Description, etc). + /// + [Description("Occurs when two CalendarItems need detail sorting. When items are of equal sort value, based upon their calendar time, this event will be raised to give the user the ability to perform more detailed sorting as needed - such as via Subject and/or Description, etc).")] + public event EventHandler CalendarItemDetailSort; + + #endregion + + #region DayView Events + + /// + /// Occurs when DayViewDate has Changed + /// + [Description("Occurs when DayViewDate has Changed.")] + public event EventHandler DayViewDateChanged; + + #endregion + + #region WeekView Events + + /// + /// Occurs when WeekViewStartDate has Changed + /// + [Description("Occurs when WeekViewStartDate has Changed.")] + public event EventHandler WeekViewStartDateChanged; + + /// + /// Occurs when WeekViewEndDate has Changed + /// + [Description("Occurs when WeekViewEndDate has Changed.")] + public event EventHandler WeekViewEndDateChanged; + + #endregion + + #region WeekDayView Events + + /// + /// Occurs when LabelTimeSlots has changed + /// + [Description("Occurs when LabelTimeSlots has changed.")] + public event EventHandler LabelTimeSlotsChanged; + + /// + /// Occurs when TimeSlotDuration has changed + /// + [Description("Occurs when TimeSlotDuration has changed.")] + public event EventHandler TimeSlotDurationChanged; + + /// + /// Occurs when Is24HourFormat has changed + /// + [Description("Occurs when Is24HourFormat has changed.")] + public event EventHandler Is24HourFormatChanged; + + /// + /// Occurs when FixedAllDayPanelHeight has changed + /// + [Description("Occurs when FixedAllDayPanelHeight has changed.")] + public event EventHandler FixedAllDayPanelHeightChanged; + + /// + /// Occurs when MaximumAllDayPanelHeight has Changed + /// + [Description("Occurs when MaximumAllDayPanelHeight has Changed.")] + public event EventHandler MaximumAllDayPanelHeightChanged; + + /// + /// Occurs when MinimumTimeSlotHeight has Changed + /// + [Description("Occurs when MinimumTimeSlotHeight has Changed.")] + public event EventHandler MinimumTimeSlotHeightChanged; + + /// + /// Occurs when IsTimeRulerVisible has changed + /// + [Description("Occurs when IsTimeRulerVisible has changed.")] + public event EventHandler IsTimeRulerVisibleChanged; + + /// + /// Occurs when ShowOnlyWorkDayHours has changed + /// + [Description("Occurs when ShowOnlyWorkDayHours has changed.")] + public event EventHandler ShowOnlyWorkDayHoursChanged; + + /// + /// Occurs when DaySlotAppearance Text needs rendered + /// + [Description("Occurs when DaySlotAppearance Text needs rendered.")] + public event EventHandler RenderDaySlotAppearanceText; + + /// + /// Occurs when WeekDayCanExtendRange has changed + /// + [Description("Occurs when WeekDayCanExtendRange has changed.")] + public event EventHandler WeekDayCanExtendRangeChanged; + + /// + /// Occurs when the WeekDay DaySlot background needs to be rendered + /// + [Description("Occurs when a WeekDay DaySlot background needs to be rendered.")] + public event EventHandler PreRenderWeekDaySlotBackground; + + /// + /// Occurs when the WeekDay DaySlot background has been rendered + /// + [Description("Occurs when the WeekDay DaySlot background has been rendered.")] + public event EventHandler PostRenderWeekDaySlotBackground; + + /// + /// Occurs when the WeekDay header is about to be rendered + /// + [Description("Occurs when the WeekDay header is about to be rendered.")] + public event EventHandler PreRenderWeekDayHeader; + + /// + /// Occurs when the WeekDay header has been rendered + /// + [Description("Occurs when the WeekDay header has been rendered.")] + public event EventHandler PostRenderWeekDayHeader; + + #endregion + + #region MonthView Events + + /// + /// Occurs when MonthViewStartDate has Changed + /// + [Description("Occurs when MonthViewStartDate has Changed.")] + public event EventHandler MonthViewStartDateChanged; + + /// + /// Occurs when MonthViewEndDate has Changed + /// + [Description("Occurs when MonthViewEndDate has Changed.")] + public event EventHandler MonthViewEndDateChanged; + + /// + /// Occurs when IsMonthSideBarVisible has changed + /// + [Description("Occurs when IsMonthSideBarVisible has changed.")] + public event EventHandler IsMonthSideBarVisibleChanged; + + /// + /// Occurs when IsMonthMoreItemsIndicatorVisible has changed + /// + [Description("Occurs when IsMonthMoreItemsIndicatorVisible has changed.")] + public event EventHandler IsMonthMoreItemsIndicatorVisibleChanged; + + /// + /// Occurs when a MonthView Slot Background is about to be rendered + /// + [Description("Occurs when a MonthView Slot Background is about to be rendered.")] + public event EventHandler MonthViewPreRenderSlotBackground; + + /// + /// Occurs when a MonthView Slot Background has just been rendered + /// + [Description("Occurs when a MonthView Slot Background has just been rendered.")] + public event EventHandler MonthViewPostRenderSlotBackground; + + /// + /// Occurs when a MonthView 'MoreItemsIndicator' has been clicked + /// + [Description("Occurs when a MonthView 'MoreItemsIndicator' has been clicked.")] + public event EventHandler MonthMoreItemsIndicatorClick; + + /// + /// Occurs when the MonthView header is about to be rendered + /// + [Description("Occurs when the MonthView header is about to be rendered.")] + public event EventHandler PreRenderMonthHeader; + + /// + /// Occurs when the MonthView header has been rendered + /// + [Description("Occurs when the MonthView header has been rendered.")] + public event EventHandler PostRenderMonthHeader; + + /// + /// Occurs when MonthViewHorizontalPadding has changed + /// + [Description("Occurs when MonthViewHorizontalPadding has changed.")] + public event EventHandler MonthViewHorizontalPaddingChanged; + + #endregion + + #region YearView Events + + /// + /// Occurs when YearViewStartDate has Changed + /// + [Description("Occurs when YearViewStartDate has Changed.")] + public event EventHandler YearViewStartDateChanged; + + /// + /// Occurs when YearViewEndDate has Changed + /// + [Description("Occurs when YearViewEndDate has Changed.")] + public event EventHandler YearViewEndDateChanged; + + /// + /// Occurs when YearViewShowGridLines has changed + /// + [Description("Occurs when YearViewShowGridLines has changed.")] + public event EventHandler YearViewShowGridLinesChanged; + + /// + /// Occurs when YearViewAllowDateSelection has changed + /// + [Description("Occurs when YearViewAllowDateSelection has changed.")] + public event EventHandler YearViewAllowDateSelectionChanged; + + /// + /// Occurs when YearViewLinkView has changed + /// + [Description("Occurs when YearViewLinkView has changed.")] + public event EventHandler YearViewLinkViewChanged; + + /// + /// Occurs when YearViewAppointmentLink has changed + /// + [Description("Occurs when YearViewAppointmentLink has changed.")] + public event EventHandler YearViewAppointmentLinkChanged; + + /// + /// Occurs when YearViewLinkAction has changed + /// + [Description("Occurs when YearViewLinkAction has changed.")] + public event EventHandler YearViewLinkActionChanged; + + /// + /// Occurs when YearViewNonAppointmentLink has changed + /// + [Description("Occurs when YearViewNonAppointmentLink has changed.")] + public event EventHandler YearViewNonAppointmentLinkChanged; + + /// + /// Occurs when YearViewLinkStyle has changed + /// + [Description("Occurs when YearViewLinkStyle has changed.")] + public event EventHandler YearViewLinkStyleChanged; + + /// + /// Occurs when YearViewLink has been selected + /// + [Description("Occurs when YearViewLink has been selected.")] + public event EventHandler YearViewLinkSelected; + + /// + /// Occurs when YearView Day Background needs drawn + /// + [Description("Occurs when YearView Day Background needs drawn.")] + public event EventHandler YearViewDrawDayBackground; + + /// + /// Occurs when YearView Day Text needs drawn + /// + [Description("Occurs when YearView Day Text needs drawn.")] + public event EventHandler YearViewDrawDayText; + + #endregion + + #region TimeLine Events + + /// + /// Occurs when TimeLineViewStartDate has Changed + /// + [Description("Occurs when TimeLineViewStartDate has Changed.")] + public event EventHandler TimeLineViewStartDateChanged; + + /// + /// Occurs when TimeLineViewEndDate has Changed + /// + [Description("Occurs when TimeLineViewEndDate has Changed.")] + public event EventHandler TimeLineViewEndDateChanged; + + /// + /// Occurs when TimeLineViewViewScrollDate has Changed + /// + [Description("Occurs when TimeLineViewViewScrollDate has Changed.")] + public event EventHandler TimeLineViewScrollDateChanged; + + /// + /// Occurs when TimeLineInterval has Changed + /// + [Description("Occurs when TimeLineInterval has Changed.")] + public event EventHandler TimeLineIntervalChanged; + + /// + /// Occurs when TimeLineIntervalPeriod has Changed + /// + [Description("Occurs when TimeLineIntervalPeriod has Changed.")] + public event EventHandler TimeLineIntervalPeriodChanged; + + /// + /// Occurs when TimeLineColumnWidth has changed + /// + [Description("Occurs when TimeLineColumnWidth has changed.")] + public event EventHandler TimeLineColumnWidthChanged; + + /// + /// Occurs when TimeLineMaxColumnCount has changed + /// + [Description("Occurs when TimeLineMaxColumnCount has changed.")] + public event EventHandler TimeLineMaxColumnCountChanged; + + /// + /// Occurs when TimeLineHorizontalPadding has changed + /// + [Description("Occurs when TimeLineHorizontalPadding has changed.")] + public event EventHandler TimeLineHorizontalPaddingChanged; + + /// + /// Occurs when TimeLineShowPeriodHeader has changed + /// + [Description("Occurs when TimeLineShowPeriodHeader has changed.")] + public event EventHandler TimeLineShowPeriodHeaderChanged; + + /// + /// Occurs when TimeLineShowIntervalHeader has changed + /// + [Description("Occurs when TimeLineShowIntervalHeader has changed.")] + public event EventHandler TimeLineShowIntervalHeaderChanged; + + /// + /// Occurs when TimeLineShowPageNavigation has changed + /// + [Description("Occurs when TimeLineShowPageNavigation has changed.")] + public event EventHandler TimeLineShowPageNavigationChanged; + + /// + /// Occurs when TimeLineCondensedViewVisibility has changed + /// + [Description("Occurs when TimeLineCondensedViewVisibility has changed.")] + public event EventHandler TimeLineCondensedViewVisibilityChanged; + + /// + /// Occurs when TimeLineCondensedViewHeight has changed + /// + [Description("Occurs when TimeLineCondensedViewHeight has changed.")] + public event EventHandler TimeLineCondensedViewHeightChanged; + + /// + /// Occurs when TimeLineView Period Header needs rendered + /// + [Description("Occurs when TimeLineView Period Header needs rendered.")] + public event EventHandler TimeLineRenderPeriodHeader; + + /// + /// Occurs when a TimeLineView Slot Background is about to be rendered + /// + [Description("Occurs when a TimeLineView Slot Background is about to be rendered.")] + public event EventHandler TimeLinePreRenderSlotBackground; + + /// + /// Occurs when a TimeLineView Slot Background has just been rendered + /// + [Description("Occurs when a TimeLineView Slot Background has just been rendered.")] + public event EventHandler TimeLinePostRenderSlotBackground; + + /// + /// Occurs when a TimeLineView Slot Border needs rendered + /// + [Description("Occurs when a TimeLineView Slot Border needs rendered.")] + public event EventHandler TimeLineRenderSlotBorder; + + /// + /// Occurs when a TimeLineView Border needs rendered + /// + [Description("Occurs when a TimeLineView Border needs rendered.")] + public event EventHandler TimeLineRenderViewBorder; + + /// + /// Occurs when TimeLineView needs to get the Appointment row height + /// + [Description("Occurs when TimeLineView needs to get the Appointment row height.")] + public event EventHandler TimeLineGetRowHeight; + + /// + /// Occurs when TimeLineView needs to get the row collate Id (used to group rows). + /// + [Description("Occurs when TimeLineView needs to get the row collate Id (used to group rows).")] + public event EventHandler TimeLineGetRowCollateId; + + /// + /// Occurs when a PageNavigator control button has been clicked + /// + [Description("Occurs when a PageNavigator control button has been clicked.")] + public event EventHandler PageNavigatorClick; + + /// + /// Occurs when the TimeLineView needs Date Header Text for a column + /// + [Description("Occurs when the TimeLineView needs Date Header Text for a column.")] + public event EventHandler TimeLineGetHeaderText; + + #endregion + + #endregion + + #region Private variables + + #region Base variables + + private CalendarModel _CalendarModel; // Calendar Model + private CalendarPanel _CalendarPanel; // Calendar Panel + + private DateTime _AutoSyncDate; // AutoSync Start Date + private DateTime? _DateSelectionStart; // Selection start + private DateTime? _DateSelectionEnd; // Selection ent + + private eCalendarView _SelectedView = eCalendarView.None; // Selected view + + private DisplayedOwnerCollection _DisplayedOwners; + private int _SelectedOwnerIndex = -1; // Selected owner index + private int _ViewWidth = 250; + + private bool _AllowTabReorder = true; // Can reorder multi-user tabs? + private bool _AutoSyncViewDates = true; // View dates AutoSynced? + private bool _EnableDragDrop = true; // DragDrop enabled state + private bool _EnableDragCopy = true; + private bool _EnableMarkup = true; + private bool _SetCursor; // Local cursor set flag + private bool _HighlightCurrentDay; + + private Cursor _DefaultViewCursor; // Default View cursor + private int _DefaultCalendarColor; + + private AppointmentCategoryColorCollection _CategoryColors; + + private TimeIndicatorCollection _TimeIndicators; + private TimeIndicator _TimeIndicator; + + private CustomCalendarItemCollection + _CustomItems = new CustomCalendarItemCollection(); + + private ViewDisplayCustomizations _ViewDisplayCustomizations; + + private bool _ShowTabs = true; + private int _AppointmentBorderWidth = 1; + + private bool _TouchEnabled = true; + + #endregion + + #region WeekDay variables + + private DayView _DayView; + private DateTime _DayViewDate; + + private WeekView _WeekView; + private DateTime _WeekViewStartDate; + private DateTime _WeekViewEndDate; + + private CalendarViewCollection _MultiCalendarDayViews; + private CalendarViewCollection _MultiCalendarWeekViews; + + private bool _Is24HourFormat; + private bool _IsTimeRulerVisible = true; + private bool _LabelTimeSlots; + private bool _ShowOnlyWorkDayHours; + private bool _WeekDayCanExtendRange = true; + + private int _TimeSlotDuration = 30; + private int _FixedAllDayPanelHeight = -1; + private int _MinimumTimeSlotHeight; + private int _MaximumAllDayPanelHeight = 120; + private int _NumberOfSlices; + private int _StartSlice; + private int _SlotsPerHour; + private float _TimeSliceHeight; + + private TimeRulerPanel _TimeRulerPanel; + private WeekDayVScrollPanel _WeekDayVScrollPanel; + + private eAllDayDisplayMode _AllDayDisplayMode = eAllDayDisplayMode.ByDayBoundary; + + private Font _TimeRulerFont; + private Font _TimeRulerFontSm; + + #endregion + + #region Month variables + + private MonthView _MonthView; + private DateTime _MonthViewStartDate; + private DateTime _MonthViewEndDate; + + private CalendarViewCollection _MultiCalendarMonthViews; + + private bool _IsMonthSideBarVisible = true; + private bool _IsMonthMoreItemsIndicatorVisible = true; + + private int _MonthViewHorizontalPadding = 6; + + #endregion + + #region YearView variables + + private YearView _YearView; + private DateTime _YearViewStartDate; + private DateTime _YearViewEndDate; + + private CalendarViewCollection _MultiCalendarYearViews; + + private bool _YearViewShowGridLines = true; + private bool _YearViewAllowDateSelection = true; + + private eCalendarView _YearViewLinkView = eCalendarView.Day; + private eYearViewLinkAction _YearViewLinkAction = eYearViewLinkAction.GoToDate; + private eYearViewDayLink _YearViewAppointmentLink = eYearViewDayLink.Click; + private eYearViewDayLink _YearViewNonAppointmentLink = eYearViewDayLink.DoubleClick; + private eYearViewLinkStyle _YearViewAppointmentLinkStyle = eYearViewLinkStyle.Style1; + + private YearVScrollPanel _YearVScrollPanel; + + private int _YearViewMax; + + #endregion + + #region TimeLineView variables + + private TimeLineView _TimeLineView; + private DateTime _TimeLineViewStartDate; + private DateTime _TimeLineViewEndDate; + + private CalendarViewCollection _MultiCalendarTimeLineViews; + + private bool _TimeLinePeriodHeaderEnableMarkup = true; + private bool _TimeLineShowPeriodHeader = true; + private bool _TimeLineShowIntervalHeader = true; + private bool _TimeLineShowPageNavigation = true; + private bool _TimeLineStretchRowHeight; + private bool _TimeLineCanExtendRange = true; + private bool _TimeLineShowCollateLines; + + private int _TimeLineColumnCount; + private int _TimeLineMaxColumnCount = 500; + private int _TimeLineColumnWidth = 80; + private int _TimeLineMinAppointmentWidth = 20; + private int _TimeLineHeight = 100; + private int _TimeLineHorizontalPadding = 6; + private int _TimeLineCondensedViewHeight = 20; + private int _TimeLinePeriodHeaderHeight = -1; + private int _TimeLineInterval = 30; + private double _BaseInterval = 30; + + private eOrientation _TimeLineMultiUserTabOrientation = eOrientation.Vertical; + private int _TimeLineMultiUserTabWidth = 80; + + private DateTime _TimeLineViewScrollStartDate; + private TimeLineHeaderPanel _TimeLineHeaderPanel; + private TimeLineHScrollPanel _TimeLineHScrollPanel; + + private eItemAlignment _TimeLinePeriodHeaderAlignment = eItemAlignment.Center; + + private eCondensedViewVisibility + _TimeLineCondensedViewVisibility = eCondensedViewVisibility.AllResources; + + private eTimeLinePeriod _TimeLinePeriod = eTimeLinePeriod.Minutes; + + private string _TimeLinePageNavigatorTodayTooltip = "Today"; + private string _TimeLinePageNavigatorNextPageTooltip = "Next Page"; + private string _TimeLinePageNavigatorPreviousPageTooltip = "Previous Page"; + + private bool _TimeLineShowHScrollBar = true; + + private TimeLineStretchRowHeightMode + _TimeLineStretchRowHeightMode = TimeLineStretchRowHeightMode.Partial; + + #endregion + + #endregion + + /// + /// CalendarView constructor + /// + public CalendarView() + { + // Allocate our CalendarPanel to hold all our + // BaseView and TimeRulerPanel objects + + _CalendarPanel = new CalendarPanel(this); + + _CalendarPanel.Bounds = ClientRectangle; + + _CalendarPanel.GlobalItem = false; + _CalendarPanel.ContainerControl = this; + _CalendarPanel.Stretch = false; + _CalendarPanel.Displayed = true; + _CalendarPanel.SetOwner(this); + + SetBaseItemContainer(_CalendarPanel); + + // Allocate our DisplayedOwners collection, used + // to track all multi-user calendar views + + _DisplayedOwners = new DisplayedOwnerCollection(this); + + // Establish our default view dates and + // set our default view to single-user Day + + InitDefaultViews(); + SelectedView = eCalendarView.Day; + + // Register with the StyleManager + + StyleManager.Register(this); + CalendarPanel.Style = eDotNetBarStyle.StyleManagerControlled; + + // Alloc our default CalendarModel + + CalendarModel = new CalendarModel(); + } + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + Dpi.SetScaling(factor); + + base.ScaleControl(factor, specified); + + _CalendarPanel.RecalcSize(); + _CalendarPanel.Refresh(); + } + + #region DefaultSize + + protected override Size DefaultSize + { + get + { + return new Size(300, 150); + } + } + #endregion + + #region Public properties + + #region Licensing +#if !TRIAL + private string _LicenseKey = ""; + [Browsable(false), DefaultValue("")] + public string LicenseKey + { + get { return _LicenseKey; } + set + { + if (NativeFunctions.ValidateLicenseKey(value)) + return; + _LicenseKey = (!NativeFunctions.CheckLicenseKey(value) ? "9dsjkhds7" : value); + } + } +#endif + #endregion + + #region Browsable properties + + #region AllowTabReorder + + /// + /// Gets and sets whether the control will permit + /// tab reordering via the user interface + /// + [DefaultValue(true)] + [Category("Behavior")] + [Description("Indicates whether the user can reorder Multi-User tabs through the user interface.")] + public bool AllowTabReorder + { + get { return (_AllowTabReorder); } + set { _AllowTabReorder = value; } + } + + #endregion + + #region AutoSyncViewDates + /// + /// Gets or sets whether view dates are automatically + /// synced to the currently viewed date range + /// + [DefaultValue(true)] + [Category("Behavior")] + [Description("Indicates whether view dates are automatically synced to the currently viewed date range.")] + public bool AutoSyncViewDates + { + get { return (_AutoSyncViewDates); } + set { _AutoSyncViewDates = value; } + } + + #endregion + + #region AppointmentBorderWidth + + /// + /// Gets and sets the default appointment border width + /// + [DefaultValue(1)] + [Category("Appearance")] + [Description("Indicates whether the default appointment border width.")] + public int AppointmentBorderWidth + { + get { return (_AppointmentBorderWidth); } + + set + { + if (_AppointmentBorderWidth != value) + { + _AppointmentBorderWidth = value; + + Refresh(); + } + } + } + + #endregion + + #region AllDayDisplayMode + + /// + /// Gets or sets how DayView "AllDay" appointments are displayed + /// + [DefaultValue(eAllDayDisplayMode.ByDayBoundary), Category("Appearance")] + [Description("Indicates how DayView 'AllDay' appointments are displayed.")] + public eAllDayDisplayMode AllDayDisplayMode + { + get { return (_AllDayDisplayMode); } + + set + { + if (_AllDayDisplayMode != value) + { + _AllDayDisplayMode = value; + + if (_CalendarModel != null) + { + _CalendarModel.BeginUpdate(); + _CalendarModel.EndUpdate(); + } + + Refresh(); + } + } + } + + #endregion + + #region EnableMarkup + + /// + /// Gets or sets whether Appointment text-markup support is enabled + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Appointment text-markup support is enabled.")] + public bool EnableMarkup + { + get { return (_EnableMarkup); } + + set + { + if (_EnableMarkup != value) + { + _EnableMarkup = value; + Refresh(); + } + } + } + + #endregion + + #region SelectedView + + /// + /// Gets and sets the selected calendar view + /// + [DefaultValue(eCalendarView.Day)] + [Category("Appearance")] + [Description("Indicates whether the Day, Week, or Month view is displayed.")] + public eCalendarView SelectedView + { + get { return (_SelectedView); } + + set + { + if (_SelectedView != value) + { + eCalendarView oldView = _SelectedView; + + SetSelectedView(value); + + OnSelectedViewChanged(oldView, _SelectedView); + } + } + } + + /// + /// SelectedViewChanged event propagation + /// + protected virtual void OnSelectedViewChanged(eCalendarView oldView, eCalendarView newView) + { + if (SelectedViewChanged != null) + SelectedViewChanged(this, new SelectedViewEventArgs(oldView, newView)); + } + + #endregion + + #region FixedAllDayPanelHeight + + /// + /// Gets and sets the fixed (constant) AllDayPanel + /// height for all WeekDay views. Setting this value to -1 + /// will let the height change dynamically + /// + [DefaultValue(-1)] + [Category("Layout")] + [Description("Indicates the fixed (constant) AllDayPanel height for all Day and Week views. Setting this value to -1 will let the height change dynamically.")] + public int FixedAllDayPanelHeight + { + get { return (_FixedAllDayPanelHeight); } + + set + { + if (_FixedAllDayPanelHeight != value) + { + int oldValue = _FixedAllDayPanelHeight; + _FixedAllDayPanelHeight = value; + + OnFixedAllDayPanelHeightChanged(oldValue, value); + } + } + } + + /// + /// Propagates FixedAllDayPanelHeightChanged events + /// + /// Old value + /// New value + private void OnFixedAllDayPanelHeightChanged(int oldValue, int newValue) + { + if (FixedAllDayPanelHeightChanged != null) + { + FixedAllDayPanelHeightChanged(this, + new FixedAllDayPanelHeightChangedEventArgs(oldValue, newValue)); + } + } + + #endregion + + #region HilightCurrentDay + + /// + /// Gets or sets whether the current calendar day is highlighted + /// + [DefaultValue(false)] + [Category("Appearance")] + [Description("Indicates whether the current calendar day is highlighted.")] + public bool HighlightCurrentDay + { + get { return (_HighlightCurrentDay); } + + set + { + if (_HighlightCurrentDay != value) + { + _HighlightCurrentDay = value; + + Refresh(); + } + } + } + + #endregion + + #region MaximumAllDayPanelHeight + + /// + /// Gets or sets the maximum height of the All Day Appointment panel + /// + [DefaultValue(120)] + [Category("Layout")] + [Description("Indicates the maximum AllDayPanel height for all Day and Week views.")] + public int MaximumAllDayPanelHeight + { + get { return (_MaximumAllDayPanelHeight); } + + set + { + if (_MaximumAllDayPanelHeight != value) + { + int oldValue = _MaximumAllDayPanelHeight; + _MaximumAllDayPanelHeight = value; + + OnMaximumAllDayPanelHeightChanged(oldValue, value); + } + } + } + + /// + /// Propagates MaximumAllDayPanelHeightChanged events + /// + /// Old value + /// New value + private void OnMaximumAllDayPanelHeightChanged(int oldValue, int newValue) + { + if (MaximumAllDayPanelHeightChanged != null) + { + MaximumAllDayPanelHeightChanged(this, + new MaximumAllDayPanelHeightChangedEventArgs(oldValue, newValue)); + } + } + + #endregion + + #region MinimumTimeSlotHeight + + /// + /// Gets or sets the minimum height of the WeekDay time slots + /// + [DefaultValue(0)] + [Category("Layout")] + [Description("Indicates the minimum height of the WeekDay time slots.")] + public int MinimumTimeSlotHeight + { + get { return (_MinimumTimeSlotHeight); } + + set + { + if (_MinimumTimeSlotHeight != value) + { + int oldValue = _MinimumTimeSlotHeight; + _MinimumTimeSlotHeight = value; + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + + OnMinimumTimeSlotHeightChanged(oldValue, value); + } + } + } + + /// + /// Propagates MinimumTimeSlotHeightChanged events + /// + /// Old value + /// New value + private void OnMinimumTimeSlotHeightChanged(int oldValue, int newValue) + { + if (MinimumTimeSlotHeightChanged != null) + { + MinimumTimeSlotHeightChanged(this, + new MinimumTimeSlotHeightChangedEventArgs(oldValue, newValue)); + } + } + + #endregion + + #region MultiUserTabHeight + + private int _MultiUserTabHeight; + + /// + /// Gets and sets the Calendar multi-user tab height + /// + [DefaultValue(0)] + [Category("Layout")] + [Description("Indicates the Calendar multi-user tab height.")] + public int MultiUserTabHeight + { + get + { + return ((_MultiUserTabHeight > 0) + ? _MultiUserTabHeight : Font.Height + Dpi.Height(6)); + } + + set + { + if (_MultiUserTabHeight != value) + { + _MultiUserTabHeight = value; + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeIndicator + + /// + /// Gets or sets the default TimeIndicator + /// + [Browsable(true)] + [Description("Default CalendarView TimeIndicator.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TimeIndicator TimeIndicator + { + get + { + if (_TimeIndicator == null) + TimeIndicator = new TimeIndicator(); + + return (_TimeIndicator); + } + + set + { + if (_TimeIndicator != null) + { + _TimeIndicator.IsProtected = false; + + TimeIndicators.Remove(_TimeIndicator); + } + + _TimeIndicator = value; + + if (value != null) + { + _TimeIndicator.IsProtected = true; + _TimeIndicator.IsDesignMode = DesignMode; + + TimeIndicators.Add(_TimeIndicator); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTimeIndicator() + { + TimeIndicator = new TimeIndicator(); + } + + #endregion + + #region TimeSlotDuration + + /// + /// Gets and sets the Time slot duration for all Day and Week views. + /// This value, in minutes, must be greater than 0 and less than or + /// equal to 30. Set values must also evenly divide the hour. This means + /// that values like 6, 10 and 20 are valid values, whereas 7, 11 and 31 are not + /// + [DefaultValue(MaxMinuteDuration)] + [Category("Layout")] + [Description("Indicates the Time Slot Duration for all Day and Week views. This value, in minutes, must be greater than 0 and less than or equal to 30. Set values must also evenly divide the hour. This means that values like 6, 10 and 20 are valid values, whereas 7, 11 and 31 are not.")] + public int TimeSlotDuration + { + get { return (_TimeSlotDuration); } + + set + { + value = GetValidIntervalMinutes(value); + + if (_TimeSlotDuration != value) + { + int oldValue = _TimeSlotDuration; + _TimeSlotDuration = value; + + _SlotsPerHour = MinutesPerHour / _TimeSlotDuration; + + OnTimeSlotDurationChanged(oldValue, value); + } + } + } + + /// + /// OnTimeSlotDurationChanged event propagation + /// + protected virtual void OnTimeSlotDurationChanged(int oldVal, int newVal) + { + if (TimeSlotDurationChanged != null) + TimeSlotDurationChanged(this, new TimeSlotDurationChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region TimeRulerFont + + /// + /// Gets and sets the TimeRuler Font. If not set, the default used + /// is a percentage of the System Caption Font. + /// + [Category("Layout")] + [Description("Indicates the TimeRuler Font. If not set, the default used is a percentage of the System Caption Font.")] + public Font TimeRulerFont + { + get + { + if (_TimeRulerFont == null) + _TimeRulerFont = new Font(SystemFonts.CaptionFont.FontFamily, SystemFonts.CaptionFont.Size * 1.3f); + + return (_TimeRulerFont); + } + + set + { + if (_TimeRulerFont != null) + _TimeRulerFont.Dispose(); + + _TimeRulerFont = value; + + Refresh(); + } + } + + #endregion + + #region TimeRulerFontSm + + /// + /// Gets and sets the TimeRuler 'Small' Font. If not set, the default used + /// is a percentage of the System Caption Font. + /// + [Category("Layout")] + [Description("Indicates the TimeRuler 'Small' Font. If not set, the default used is a percentage of the System Caption Font.")] + public Font TimeRulerFontSm + { + get + { + if (_TimeRulerFontSm == null) + _TimeRulerFontSm = new Font(SystemFonts.CaptionFont.FontFamily, SystemFonts.CaptionFont.Size * .8f); + + return (_TimeRulerFontSm); + } + + set + { + if (_TimeRulerFontSm != null) + _TimeRulerFontSm.Dispose(); + + _TimeRulerFontSm = value; + + Refresh(); + } + } + + #endregion + + #region Is24HourFormat + + /// + /// Gets and sets the 12 or 24 hour + /// formatting that is used in the Day and Week views + /// + [DefaultValue(false)] + [Category("Appearance")] + [Description("Indicates whether 12 or 24 hour formatting is used in the Day and Week views.")] + public bool Is24HourFormat + { + get { return (_Is24HourFormat); } + + set + { + if (_Is24HourFormat != value) + { + _Is24HourFormat = value; + + OnIs24HourFormatChanged(!value, value); + } + } + } + + /// + /// OnIs24HourFormatChanged event propagation + /// + private void OnIs24HourFormatChanged(bool oldValue, bool newValue) + { + if (Is24HourFormatChanged != null) + Is24HourFormatChanged(this, new Is24HourFormatChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region LabelTimeSlots + + /// + /// Gets and sets whether time slot labels are + /// displayed in the Day and Week view TimeRulerPanel + /// + [DefaultValue(false)] + [Category("Appearance")] + [Description("Indicates whether minor time labels are displayed in the Day and Week view TimeRulerPanel.")] + public bool LabelTimeSlots + { + get { return (_LabelTimeSlots); } + + set + { + if (_LabelTimeSlots != value) + { + bool oldValue = _LabelTimeSlots; + _LabelTimeSlots = value; + + OnLabelTimeSlotsChanged(oldValue, value); + } + } + } + + /// + /// OnLabelTimeSlotsChanged event propagation + /// + protected virtual void OnLabelTimeSlotsChanged(bool oldVal, bool newVal) + { + if (LabelTimeSlotsChanged != null) + LabelTimeSlotsChanged(this, new LabelTimeSlotsChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region ShowOnlyWorkDayHours + + /// + /// Gets and sets whether only WorkDay hours are + /// displayed in the Day and Week views + /// + [DefaultValue(false)] + [Category("Appearance")] + [Description("Indicates whether only WorkDay hours are displayed in the Day and Week views.")] + public bool ShowOnlyWorkDayHours + { + get { return (_ShowOnlyWorkDayHours); } + + set + { + if (_ShowOnlyWorkDayHours != value) + { + bool oldValue = _ShowOnlyWorkDayHours; + _ShowOnlyWorkDayHours = value; + + CalendarPanel.RecalcSize(); + + OnShowOnlyWorkDayHoursChanged(oldValue, value); + } + } + } + + /// + /// OnShowOnlyWorkDayHoursChanged event propagation + /// + protected virtual void OnShowOnlyWorkDayHoursChanged(bool oldVal, bool newVal) + { + if (ShowOnlyWorkDayHoursChanged != null) + ShowOnlyWorkDayHoursChanged(this, new ShowOnlyWorkDayHoursChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region ShowTabs + + /// + /// Gets and sets multi-user tab visibility + /// + [Browsable(true), DefaultValue(true), Category("Appearance")] + [Description("Indicates multi-user tab visibility.")] + public bool ShowTabs + { + get { return (_ShowTabs); } + + set + { + if (_ShowTabs != value) + { + _ShowTabs = value; + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region IsMonthSideBarVisible + + /// + /// Gets and sets the default Month view SideBar visibility + /// + [DefaultValue(true)] + [Category("Behavior")] + [Description("Indicates the default Month view SideBar visibility.")] + public bool IsMonthSideBarVisible + { + get { return (_IsMonthSideBarVisible); } + + set + { + if (_IsMonthSideBarVisible != value) + { + bool oldValue = _IsMonthSideBarVisible; + _IsMonthSideBarVisible = value; + + OnIsMonthSideBarVisibleChanged(oldValue, value); + + Refresh(); + } + } + } + + /// + /// OnIsMonthSideBarVisibleChanged event propagation + /// + protected virtual void OnIsMonthSideBarVisibleChanged(bool oldVal, bool newVal) + { + if (IsMonthSideBarVisibleChanged != null) + IsMonthSideBarVisibleChanged(this, new IsMonthSideBarVisibleChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region IsMonthMoreItemsIndicatorVisible + + /// + /// Gets and sets the Month view 'More Items' indicator visibility + /// + [DefaultValue(true)] + [Category("Behavior")] + [Description("Indicates the Month view 'More Items' indicator visibility.")] + public bool IsMonthMoreItemsIndicatorVisible + { + get { return (_IsMonthMoreItemsIndicatorVisible); } + + set + { + if (_IsMonthMoreItemsIndicatorVisible != value) + { + bool oldValue = _IsMonthMoreItemsIndicatorVisible; + _IsMonthMoreItemsIndicatorVisible = value; + + OnIsMonthMoreItemsIndicatorVisibleChanged(oldValue, value); + + Refresh(); + } + } + } + + /// + /// OnIsMonthMoreItemsIndicatorVisibleChanged event propagation + /// + protected virtual void OnIsMonthMoreItemsIndicatorVisibleChanged(bool oldVal, bool newVal) + { + if (IsMonthMoreItemsIndicatorVisibleChanged != null) + IsMonthMoreItemsIndicatorVisibleChanged(this, new IsMonthMoreItemsIndicatorVisibleChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region IsTimeRulerVisible + + /// + /// Gets and sets whether the Week/Day view TimeRuler is visible + /// + [DefaultValue(true)] + [Category("Behavior")] + [Description("Indicates whether the Week/Day view TimeRuler is visible.")] + public bool IsTimeRulerVisible + { + get { return (_IsTimeRulerVisible); } + + set + { + if (_IsTimeRulerVisible != value) + { + bool oldValue = _IsTimeRulerVisible; + _IsTimeRulerVisible = value; + + OnIsTimeRulerVisibleChanged(oldValue, value); + + SetSelectedView(SelectedView); + } + } + } + + /// + /// OnIsTimeRulerVisibleChanged event propagation + /// + protected virtual void OnIsTimeRulerVisibleChanged(bool oldVal, bool newVal) + { + if (IsTimeRulerVisibleChanged != null) + IsTimeRulerVisibleChanged(this, new IsTimeRulerVisibleChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region EnableDragDrop + + /// + /// Gets and sets whether DragDrop across calendar views is enabled + /// + [DefaultValue(true)] + [Category("Behavior")] + [Description("Indicates whether DragDrop operations are enabled between calendar views.")] + public bool EnableDragDrop + { + get { return (_EnableDragDrop); } + + set + { + if (_EnableDragDrop != value) + { + _EnableDragDrop = value; + + OnEnableDragDropChanged(!value, value); + } + } + } + + /// + /// OnEnableDragDropChanged event propagation + /// + protected virtual void OnEnableDragDropChanged(bool oldVal, bool newVal) + { + if (EnableDragDropChanged != null) + EnableDragDropChanged(this, new EnableDragDropChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region EnableDragCopy + + /// + /// Gets or sets whether a new copy of an item will be + /// created when holding the Control-Key while dragging it. + /// + [DefaultValue(true)] + [Category("Behavior")] + [Description("Indicates whether a new copy of an item will be created when holding the Control-Key while dragging it.")] + public bool EnableDragCopy + { + get { return (_EnableDragCopy); } + set { _EnableDragCopy = value; } + } + + #endregion + + #region TouchEnabled + + /// + /// Indicates whether touch support for scrolling is enabled. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether touch support for scrolling is enabled.")] + public bool TouchEnabled + { + get { return _TouchEnabled; } + set { _TouchEnabled = value; } + } + + #endregion + + #region YearViewAllowDateSelection + + /// + /// Gets and sets whether date selection is permitted + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether YearView date selection is permitted.")] + public bool YearViewAllowDateSelection + { + get { return (_YearViewAllowDateSelection); } + + set + { + if (_YearViewAllowDateSelection != value) + { + bool oldValue = _YearViewAllowDateSelection; + _YearViewAllowDateSelection = value; + + OnYearViewAllowDateSelectionChanged(oldValue, value); + } + } + } + + /// + /// YearViewAllowDateSelectionChanged event propagation + /// + protected virtual void OnYearViewAllowDateSelectionChanged(bool oldVal, bool newVal) + { + if (YearViewAllowDateSelectionChanged != null) + YearViewAllowDateSelectionChanged(this, new AllowDateSelectionChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region YearViewAppointmentLink + + /// + /// Gets and sets the YearView Appointment Link mode. This defines the + /// interaction between the mouse and YearView days that contain appointments. + /// + [Browsable(true), DefaultValue(eYearViewDayLink.Click), Category("Behavior")] + [Description("Indicates the YearView Appointment Link mode. This defines the interaction between the mouse and YearView days that contain appointments.")] + public eYearViewDayLink YearViewAppointmentLink + { + get { return (_YearViewAppointmentLink); } + + set + { + if (_YearViewAppointmentLink != value) + { + eYearViewDayLink oldValue = _YearViewAppointmentLink; + _YearViewAppointmentLink = value; + + OnYearViewAppointmentLinkChanged(oldValue, value); + } + } + } + + /// + /// YearViewAppointmentLinkChanged event propagation + /// + private void OnYearViewAppointmentLinkChanged(eYearViewDayLink oldVal, eYearViewDayLink newVal) + { + if (YearViewAppointmentLinkChanged != null) + YearViewAppointmentLinkChanged(this, new DayLinkChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region YearViewNonAppointmentLink + + /// + /// Gets and sets the YearView Non-Appointment Link mode. This defines the + /// interaction between the mouse and YearView days that do not contain appointments. + /// + [Browsable(true), DefaultValue(eYearViewDayLink.DoubleClick), Category("Behavior")] + [Description("Indicates the YearView Non-Appointment Link mode. This defines the interaction between the mouse and YearView days that do not contain appointments.")] + public eYearViewDayLink YearViewNonAppointmentLink + { + get { return (_YearViewNonAppointmentLink); } + + set + { + if (_YearViewNonAppointmentLink != value) + { + eYearViewDayLink oldValue = _YearViewNonAppointmentLink; + _YearViewNonAppointmentLink = value; + + OnYearViewNonAppointmentLinkChanged(oldValue, value); + } + } + } + + /// + /// YearViewNonAppointmentLinkChanged event propagation + /// + private void OnYearViewNonAppointmentLinkChanged(eYearViewDayLink oldVal, eYearViewDayLink newVal) + { + if (YearViewNonAppointmentLinkChanged != null) + YearViewNonAppointmentLinkChanged(this, new DayLinkChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region YearViewLinkView + + /// + /// Gets or sets the Link Calendar View. This defines the + /// View that is activated when a YearView date 'link' is selected. + /// + [Browsable(true), DefaultValue(eCalendarView.Day), Category("Behavior")] + [Description("Indicates the Link Calendar View. This defines the View that is activated when a YearView date 'link' is selected.")] + public eCalendarView YearViewLinkView + { + get { return (_YearViewLinkView); } + + set + { + if (_YearViewLinkView != value) + { + eCalendarView oldValue = _YearViewLinkView; + _YearViewLinkView = value; + + OnYearYearViewLinkViewChanged(oldValue, value); + } + } + } + + /// + /// YearYearViewLinkViewChanged event propagation + /// + protected virtual void OnYearYearViewLinkViewChanged(eCalendarView oldVal, eCalendarView newVal) + { + if (YearViewLinkViewChanged != null) + YearViewLinkViewChanged(this, new LinkViewChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region YearViewLinkAction + + /// + /// Gets or sets the Link action. This defines the + /// action that is taken when a YearView date 'link' is selected. + /// + [Browsable(true), DefaultValue(eYearViewLinkAction.GoToDate), Category("Behavior")] + [Description("Indicates the Link Calendar View. This defines the View that is activated when a YearView date 'link' is selected.")] + public eYearViewLinkAction YearViewLinkAction + { + get { return (_YearViewLinkAction); } + + set + { + if (_YearViewLinkAction != value) + { + eYearViewLinkAction oldValue = _YearViewLinkAction; + _YearViewLinkAction = value; + + OnYearViewLinkActionChanged(oldValue, value); + } + } + } + + /// + /// YearViewLinkActionChanged event propagation + /// + private void OnYearViewLinkActionChanged(eYearViewLinkAction oldVal, eYearViewLinkAction newVal) + { + if (YearViewLinkActionChanged != null) + YearViewLinkActionChanged(this, new LinkViewActionChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region YearViewAppointmentLinkStyle + + /// + /// Gets or sets the AppointmentLink display style. This defines the + /// style that is used when 'highlighting' YearView date links. + /// + [Browsable(true), DefaultValue(eYearViewLinkStyle.Style1), Category("Appearance")] + [Description("Indicates the AppointmentLink display style. This defines the style that is used when 'highlighting' YearView date links.")] + public eYearViewLinkStyle YearViewAppointmentLinkStyle + { + get { return (_YearViewAppointmentLinkStyle); } + + set + { + if (_YearViewAppointmentLinkStyle != value) + { + eYearViewLinkStyle oldValue = _YearViewAppointmentLinkStyle; + _YearViewAppointmentLinkStyle = value; + + OnYearViewLinkStyleChanged(oldValue, value); + + Refresh(); + } + } + } + + /// + /// YearViewLinkStyleChanged event propagation + /// + private void OnYearViewLinkStyleChanged(eYearViewLinkStyle oldVal, eYearViewLinkStyle newVal) + { + if (YearViewLinkStyleChanged != null) + YearViewLinkStyleChanged(this, new LinkViewStyleChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region YearViewShowGridLines + + /// + /// Gets and sets the YearView grid lines visibility + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates the YearView grid lines visibility.")] + public bool YearViewShowGridLines + { + get { return (_YearViewShowGridLines); } + + set + { + if (_YearViewShowGridLines != value) + { + bool oldValue = _YearViewShowGridLines; + _YearViewShowGridLines = value; + + OnYearViewShowGridLinesChanged(oldValue, value); + + Refresh(); + } + } + } + + /// + /// OnYearViewShowGridLinesChanged event propagation + /// + protected virtual void OnYearViewShowGridLinesChanged(bool oldVal, bool newVal) + { + if (YearViewShowGridLinesChanged != null) + YearViewShowGridLinesChanged(this, new ShowGridLinesChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #region WeekDayCanExtendRange + + /// + /// Gets or sets whether the Week or Day View Start and End dates can be + /// can be automatically extended by the control when the user presses + /// the left or right arrow keys. + /// + [Browsable(true), DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the Week or Day View Start and End dates can be can be automatically extended by the control when the user presses the left or right arrow keys..")] + public bool WeekDayCanExtendRange + { + get { return (_WeekDayCanExtendRange); } + + set + { + if (_WeekDayCanExtendRange != value) + { + bool oldValue = _WeekDayCanExtendRange; + _WeekDayCanExtendRange = value; + + OnWeekDayCanExtendRangeChanged(oldValue, value); + } + } + } + + /// + /// OnWeekDayCanExtendRangeChanged event propagation + /// + protected virtual void OnWeekDayCanExtendRangeChanged(bool oldVal, bool newVal) + { + if (WeekDayCanExtendRangeChanged != null) + WeekDayCanExtendRangeChanged(this, new WeekDayCanExtendRangeChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #endregion + + #region Non-Browsable properties + + #region AutoScrollMinSize + + public new Size AutoScrollMinSize + { + get { return (CalendarPanel.AutoScrollMinSize); } + set { CalendarPanel.AutoScrollMinSize = value; } + } + + #endregion + + #region AutoScrollPosition + + public new Point AutoScrollPosition + { + get { return (CalendarPanel.AutoScrollPosition); } + set { CalendarPanel.AutoScrollPosition = value; } + } + + #endregion + + #region CalendarModel + + /// + /// Gets and sets the calendar Model + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CalendarModel CalendarModel + { + get { return (_CalendarModel); } + + set + { + if (_CalendarModel != value) + { + if (_CalendarModel != null) + HookModelEvents(false); + + CalendarModel oldModel = _CalendarModel; + _CalendarModel = value; + + HookModelEvents(true); + + OnModelChanged(oldModel, value); + } + } + } + + /// + /// OnModelChanged event propagation + /// + protected virtual void OnModelChanged(CalendarModel oldModel, CalendarModel newModel) + { + if (ModelChanged != null) + ModelChanged(this, new ModelEventArgs(oldModel, newModel)); + + if (IsMultiCalendar) + { + for (int i = 0; i < DisplayedOwners.Count; i++) + { + if (MultiCalendarDayViews.Views[i] != null) + UpdateModelData(i, MultiCalendarDayViews.Views[i]); + + if (MultiCalendarWeekViews.Views[i] != null) + UpdateModelData(i, MultiCalendarWeekViews.Views[i]); + + if (MultiCalendarMonthViews.Views[i] != null) + UpdateModelData(i, MultiCalendarMonthViews.Views[i]); + + if (MultiCalendarYearViews.Views[i] != null) + UpdateModelData(i, MultiCalendarYearViews.Views[i]); + + if (MultiCalendarTimeLineViews.Views[i] != null) + UpdateModelData(i, MultiCalendarTimeLineViews.Views[i]); + } + } + + _CalendarPanel.RecalcSize(); + } + + #region UpdateModelData + + private void UpdateModelData(int index, BaseView view) + { + Owner owner = _CalendarModel.Owners[view.OwnerKey]; + + if (owner != null) + { + view.CalendarColor = owner.ColorScheme; + view.DisplayName = owner.DisplayName; + } + else + { + view.CalendarColor = GetViewColor(null, index); + view.DisplayName = view.OwnerKey; + } + } + + #endregion + + #endregion + + #region CategoryColors + + /// + /// Appointment CategoryColors + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AppointmentCategoryColorCollection CategoryColors + { + get + { + if (_CategoryColors == null) + { + _CategoryColors = new AppointmentCategoryColorCollection(); + + _CategoryColors.AppointmentCategoryColorCollectionChanged += + CategoryColorsAppointmentCategoryColorCollectionChanged; + } + + return (_CategoryColors); + } + } + + #endregion + + #region CustomItems + + /// + /// Gets the collection of user defined custom + /// CalendarItems + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CustomCalendarItemCollection CustomItems + { + get { return (_CustomItems); } + } + + #endregion + + #region DateSelectionStart + + /// + /// Gets or sets the selection start date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime? DateSelectionStart + { + get { return (_DateSelectionStart); } + + set + { + if (_DateSelectionStart != value) + { + DateTime? oldDate = _DateSelectionStart; + _DateSelectionStart = value; + + OnDateSelectionStartChanged(oldDate, value); + } + } + } + + /// + /// OnDateSelectionStartChanged event propagation + /// + protected virtual void OnDateSelectionStartChanged(DateTime? oldDate, DateTime? newDate) + { + if (DateSelectionStartChanged != null) + DateSelectionStartChanged(this, new DateSelectionEventArgs(oldDate, newDate)); + } + + #endregion + + #region DateSelectionEnd + + /// + /// Gets or sets the end date selection + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime? DateSelectionEnd + { + get { return (_DateSelectionEnd); } + + set + { + if (_DateSelectionEnd != value) + { + DateTime? oldDate = _DateSelectionEnd; + _DateSelectionEnd = value; + + OnDateSelectionEndChanged(oldDate, value); + } + } + } + + /// + /// OnDateSelectionEndChanged event propagation + /// + protected virtual void OnDateSelectionEndChanged(DateTime? oldDate, DateTime? newDate) + { + if (DateSelectionEndChanged != null) + DateSelectionEndChanged(this, new DateSelectionEventArgs(oldDate, newDate)); + } + + #endregion + + #region DayView properties + + /// + /// Gets the Day View + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DayView DayView + { + get + { + if (_DayView == null) + { + // Single-user DayView is not accessible + // when in multi-user mode + + if (IsMultiCalendar == false) + { + _DayView = new DayView(this); + + _DayView.StartDate = _DayViewDate; + _DayView.EndDate = _DayViewDate; + + _DayView.CalendarColor = GetViewColor(_DayView, 0); + } + } + + return (_DayView); + } + + internal set + { + if (_DayView != value) + { + if (_DayView != null) + _DayView.Dispose(); + + _DayView = value; + } + } + } + + #region DayViewDate + + /// + /// Gets and sets the DayView date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime DayViewDate + { + get { return (_DayViewDate); } + + set + { + value = value.Date; + + if (_DayViewDate != value) + { + DateTime oldDate = _DayViewDate; + _DayViewDate = value; + + // Inform interested parties of the change + + OnDayViewDateChanged(oldDate, value); + OnViewDateChanged(DayView, oldDate, value, oldDate, value); + + // Save AutoSyncDate + + _AutoSyncDate = value; + } + } + } + + /// + /// Sends DayViewDateChanged event + /// + /// Old date + /// New date + private void OnDayViewDateChanged(DateTime oldDate, DateTime newDate) + { + if (DayViewDateChanged != null) + DayViewDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + private void OnViewDateChanged(BaseView view, DateTime oldStartDate, + DateTime newStartDate, DateTime oldEndDate, DateTime newEndDate) + { + if (ViewDateChanged != null) + { + ViewDateChanged(this, new ViewDateChangedEventArgs( + view, oldStartDate, newStartDate, oldEndDate, newEndDate)); + } + } + + #endregion + + #endregion + + #region HScrollBar + + /// + /// Gets and sets the Calendar Multiuser Horizontal scrollbar + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public HScrollBarAdv HScrollBar + { + get { return (_CalendarPanel.HScrollBar); } + } + + #endregion + + #region WeekView properties + + /// + /// Gets the Week View + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public WeekView WeekView + { + get + { + if (_WeekView == null) + { + // Single-user WeekView is not accessible + // when in multi-user mode + + if (IsMultiCalendar == false) + { + _WeekView = new WeekView(this); + + _WeekView.StartDate = _WeekViewStartDate; + _WeekView.EndDate = _WeekViewEndDate; + + _WeekView.CalendarColor = GetViewColor(_WeekView, 0); + } + } + + return (_WeekView); + } + + internal set + { + if (_WeekView != value) + { + if (_WeekView != null) + _WeekView.Dispose(); + + _WeekView = value; + } + } + } + + #region WeekViewStartDate + + /// + /// Gets and sets the week start date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime WeekViewStartDate + { + get { return (_WeekViewStartDate); } + + set + { + value = value.Date; + + if (_WeekViewStartDate.Equals(value) == false) + { + DateTime oldDate = _WeekViewStartDate; + _WeekViewStartDate = value; + + // Inform interested parties of the change + + OnWeekViewStartDateChanged(oldDate, value); + + OnViewDateChanged(WeekView, + oldDate, value, _WeekViewEndDate, _WeekViewEndDate); + + // Save AutoSyncDate + + _AutoSyncDate = value; + } + } + } + + /// + /// Sends WeekViewStartDateChanged event + /// + /// Old date + /// New date + private void OnWeekViewStartDateChanged(DateTime oldDate, DateTime newDate) + { + if (WeekViewStartDateChanged != null) + WeekViewStartDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + #endregion + + #region WeekViewEndDate + + /// + /// Gets the week end date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime WeekViewEndDate + { + get { return (_WeekViewEndDate); } + + set + { + value = value.Date; + + if (_WeekViewEndDate.Equals(value) == false) + { + DateTime oldDate = _WeekViewEndDate; + _WeekViewEndDate = value; + + // Inform interested parties of the change + + OnWeekViewEndDateChanged(oldDate, value); + + OnViewDateChanged(WeekView, + _WeekViewStartDate, _WeekViewStartDate, oldDate, value); + } + } + } + + /// + /// Sends WeekViewEndDateChanged event + /// + /// Old date + /// New date + private void OnWeekViewEndDateChanged(DateTime oldDate, DateTime newDate) + { + if (WeekViewEndDateChanged != null) + WeekViewEndDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + #endregion + + #endregion + + #region MonthView properties + + /// + /// Gets the Month View + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public MonthView MonthView + { + get + { + if (_MonthView == null) + { + // Single-user MonthView is not accessible + // when in multi-user mode + + if (IsMultiCalendar == false) + { + _MonthView = new MonthView(this); + + _MonthView.StartDate = _MonthViewStartDate; + _MonthView.EndDate = _MonthViewEndDate; + + _MonthView.IsSideBarVisible = _IsMonthSideBarVisible; + _MonthView.CalendarColor = GetViewColor(_MonthView, 0); + } + } + + return (_MonthView); + } + + internal set + { + if (_MonthView != value) + { + if (_MonthView != null) + _MonthView.Dispose(); + + _MonthView = value; + } + } + } + + #region MonthViewStartDate + + /// + /// Gets and sets the month start date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime MonthViewStartDate + { + get { return (_MonthViewStartDate); } + + set + { + value = value.Date; + + if (_MonthViewStartDate.Equals(value) == false) + { + DateTime oldDate = _MonthViewStartDate; + _MonthViewStartDate = value; + + // Inform interested parties of the change + + OnMonthViewStartDateChanged(oldDate, value); + + OnViewDateChanged(MonthView, + oldDate, value, _MonthViewEndDate, _MonthViewEndDate); + + // Save AutoSyncDate + + _AutoSyncDate = value; + } + } + } + + /// + /// Sends MonthViewStartDateChanged event + /// + /// Old date + /// New date + private void OnMonthViewStartDateChanged(DateTime oldDate, DateTime newDate) + { + if (MonthViewStartDateChanged != null) + MonthViewStartDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + #endregion + + #region MonthViewEndDate + + /// + /// Gets the month end date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime MonthViewEndDate + { + get { return (_MonthViewEndDate); } + + set + { + value = value.Date; + + if (_MonthViewEndDate.Equals(value) == false) + { + DateTime oldDate = _MonthViewEndDate; + _MonthViewEndDate = value; + + // Inform interested parties of the change + + OnMonthViewEndDateChanged(oldDate, value); + + OnViewDateChanged(MonthView, + _MonthViewStartDate, _MonthViewStartDate, oldDate, value); + } + } + } + + /// + /// Sends MonthViewEndDateChanged event + /// + /// Old date + /// New date + private void OnMonthViewEndDateChanged(DateTime oldDate, DateTime newDate) + { + if (MonthViewEndDateChanged != null) + MonthViewEndDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + #endregion + + #region MonthViewHorizontalPadding + + /// + /// Gets and sets the horizontal padding used between + /// items displayed in the Month view + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int MonthViewHorizontalPadding + { + get { return (_MonthViewHorizontalPadding); } + + set + { + if (_MonthViewHorizontalPadding != value) + { + int oldValue = _MonthViewHorizontalPadding; + _MonthViewHorizontalPadding = value; + + CalendarPanel.Refresh(); + + // Inform interested parties of the change + + OnMonthViewHorizontalPaddingChanged(oldValue, value); + } + } + } + + /// + /// Sends MonthViewHorizontalPaddingChanged events + /// + /// Old padding + /// New padding + private void OnMonthViewHorizontalPaddingChanged(int oldValue, int newValue) + { + if (MonthViewHorizontalPaddingChanged != null) + MonthViewHorizontalPaddingChanged(this, new MonthViewHorizontalPaddingChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #endregion + + #region YearView properties + + /// + /// Gets the Year View + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public YearView YearView + { + get + { + if (_YearView == null) + { + // Single-user YearView is not accessible + // when in multi-user mode + + if (IsMultiCalendar == false) + { + _YearView = new YearView(this); + + _YearView.StartDate = _YearViewStartDate; + _YearView.EndDate = _YearViewEndDate; + + _YearView.CalendarColor = GetViewColor(_YearView, 0); + } + } + + return (_YearView); + } + + internal set + { + if (_YearView != value) + { + if (_YearView != null) + _YearView.Dispose(); + + _YearView = value; + } + } + } + + #region YearViewStartDate + + /// + /// Gets and sets the YearView start date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime YearViewStartDate + { + get { return (_YearViewStartDate); } + + set + { + value = value.Date; + + if (_YearViewStartDate.Equals(value) == false) + { + DateTime oldDate = _YearViewStartDate; + _YearViewStartDate = value; + + // Inform interested parties of the change + + OnYearViewStartDateChanged(oldDate, value); + + OnViewDateChanged(YearView, + oldDate, value, _YearViewStartDate, _YearViewEndDate); + + // Save AutoSyncDate + + _AutoSyncDate = value; + } + } + } + + /// + /// Sends OnYearViewStartDateChanged event + /// + /// Old date + /// New date + private void OnYearViewStartDateChanged(DateTime oldDate, DateTime newDate) + { + if (YearViewStartDateChanged != null) + YearViewStartDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + #endregion + + #region YearViewEndDate + + /// + /// Gets the YearView end date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime YearViewEndDate + { + get { return (_YearViewEndDate); } + + set + { + value = value.Date; + + if (_YearViewEndDate.Equals(value) == false) + { + DateTime oldDate = _YearViewEndDate; + _YearViewEndDate = value; + + // Inform interested parties of the change + + OnYearViewEndDateChanged(oldDate, value); + + OnViewDateChanged(MonthView, + _YearViewStartDate, _YearViewStartDate, oldDate, value); + } + } + } + + /// + /// Sends OnYearViewEndDateChanged event + /// + /// Old date + /// New date + private void OnYearViewEndDateChanged(DateTime oldDate, DateTime newDate) + { + if (YearViewEndDateChanged != null) + YearViewEndDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + #endregion + + #endregion + + #region TimeLineView properties + + /// + /// Gets the TimeLine View + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TimeLineView TimeLineView + { + get + { + if (_TimeLineView == null) + { + _TimeLineView = new TimeLineView(this, eCalendarView.TimeLine); + + _TimeLineView.StartDate = _TimeLineViewStartDate; + _TimeLineView.EndDate = _TimeLineViewEndDate; + } + + return (_TimeLineView); + } + + internal set + { + if (_TimeLineView != value) + { + if (_TimeLineView != null) + _TimeLineView.Dispose(); + + _TimeLineView = value; + } + } + } + + #region TimeLineViewStartDate + + /// + /// Gets and sets the TimeLine start date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime TimeLineViewStartDate + { + get { return (_TimeLineViewStartDate); } + + set + { + if (_TimeLineViewStartDate.Equals(value) == false) + { + DateTime oldDate = _TimeLineViewStartDate; + _TimeLineViewStartDate = value; + + // Update our column count and scrollBar values + + CalcTimeLineColumnCount(true); + TimeLineHScrollPanel.UpdatePanel(); + + // Inform interested parties of the change + + OnTimeLineViewStartDateChanged(oldDate, value); + + OnViewDateChanged(TimeLineView, + oldDate, value, _TimeLineViewEndDate, _TimeLineViewEndDate); + + // Save AutoSyncDate + + _AutoSyncDate = TimeLineViewScrollStartDate; + } + } + } + + /// + /// Sends TimeLineViewStartDateChanged event + /// + /// Old date + /// New date + private void OnTimeLineViewStartDateChanged(DateTime oldDate, DateTime newDate) + { + if (TimeLineViewStartDateChanged != null) + TimeLineViewStartDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + #endregion + + #region TimeLineViewEndDate + + /// + /// Gets or sets the TimeLine end date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime TimeLineViewEndDate + { + get { return (_TimeLineViewEndDate); } + + set + { + if (_TimeLineViewEndDate.Equals(value) == false) + { + DateTime oldDate = _TimeLineViewEndDate; + _TimeLineViewEndDate = value; + + // Update our column count and scrollBar values + + CalcTimeLineColumnCount(false); + TimeLineHScrollPanel.UpdatePanel(); + + // Inform interested parties of the change + + OnTimeLineViewEndDateChanged(oldDate, value); + + OnViewDateChanged(TimeLineView, + _TimeLineViewStartDate, _TimeLineViewStartDate, oldDate, value); + } + } + } + + /// + /// Sends TimeLineViewEndDateChanged event + /// + /// Old date + /// New date + private void OnTimeLineViewEndDateChanged(DateTime oldDate, DateTime newDate) + { + if (TimeLineViewEndDateChanged != null) + TimeLineViewEndDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + #endregion + + #region TimeLineViewScrollStartDate + + /// + /// Gets and sets the TimeLine Scrolled start date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime TimeLineViewScrollStartDate + { + get { return (_TimeLineViewScrollStartDate); } + + set + { + if (_TimeLineViewScrollStartDate.Equals(value) == false) + { + DateTime oldValue = _TimeLineViewScrollStartDate; + _TimeLineViewScrollStartDate = value; + + value = UpdateViewScroll(value); + + // Tell others about the change + + OnTimeLineViewScrollDateChanged(oldValue, value); + } + } + } + + /// + /// Updates the TimeLine scroll value + /// + /// Value + private DateTime UpdateViewScroll(DateTime value) + { + TimeLineHScrollPanel.BeginUpdate(); + + bool canScroll = _TimeLineCanExtendRange; + + if (value < _TimeLineViewStartDate) + { + if (canScroll == true) + TimeLineViewStartDate = value; + } + else + { + DateTime endDate; + int n = Bounds.Width / TimeLineColumnWidth; + + try + { + endDate = value.AddMinutes(n * BaseInterval); + + if (endDate > _TimeLineViewEndDate) + { + if (canScroll == true) + TimeLineViewEndDate = endDate; + } + else + { + canScroll = true; + } + } + catch + { + if (canScroll == true) + { + endDate = new DateTime(9970, 1, 1); + value = endDate.AddMinutes(-n * BaseInterval); + + _TimeLineViewScrollStartDate = value; + TimeLineViewEndDate = endDate; + } + } + } + + if (canScroll == true) + { + TimeSpan ts = value - _TimeLineViewStartDate; + + TimeLineHScrollPanel.ScrollBar.Value = + (int)(ts.TotalMinutes / _BaseInterval); + } + + TimeLineHScrollPanel.EndUpdate(); + + return (value); + } + + /// + /// Sends TimeLineViewScrollDateChanged event + /// + /// Old date + /// New date + private void OnTimeLineViewScrollDateChanged(DateTime oldDate, DateTime newDate) + { + if (TimeLineViewScrollDateChanged != null) + TimeLineViewScrollDateChanged(this, new DateChangeEventArgs(oldDate, newDate)); + } + + #endregion + + #region TimeLineViewScrollEndDate + + /// + /// Gets the TimeLine Scrolled end date + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime TimeLineViewScrollEndDate + { + get + { + DateTime date = TimeLineViewScrollStartDate; + + if (TimeLineHScrollPanel != null) + { + int intervals = + _TimeLineHeaderPanel.Bounds.Width / _TimeLineColumnWidth; + + date = date.AddMinutes(_BaseInterval * intervals); + } + + return (date); + } + } + + #endregion + + #region CalcTimeLineColumnCount + + /// + /// Calculates number of TimeLine columns + /// + /// + private void CalcTimeLineColumnCount(bool alterEnd) + { + TimeSpan ts = _TimeLineViewEndDate - _TimeLineViewStartDate; + + double tc = Math.Max(1, ts.TotalMinutes / _BaseInterval); + + if (Math.Floor(tc) > _TimeLineMaxColumnCount) + { + AdjustViewTime(alterEnd, _TimeLineMaxColumnCount); + } + else if (tc * TimeLineColumnWidth >= Int32.MaxValue) + { + AdjustViewTime(alterEnd, Int32.MaxValue / TimeLineColumnWidth); + } + else + { + if (tc * TimeLineColumnWidth < Bounds.Width) + tc = Bounds.Width / TimeLineColumnWidth * 2; + + _TimeLineColumnCount = (int)tc; + } + } + + private void AdjustViewTime(bool alterEnd, int tc) + { + if (alterEnd == true) + TimeLineViewEndDate = TimeLineAddInterval(TimeLineViewStartDate, tc); + else + TimeLineViewStartDate = TimeLineAddInterval(TimeLineViewEndDate, -tc); + } + + #endregion + + #region TimeLineColumnWidth + + /// + /// Gets and sets the Calendar TimeLineColumnWidth + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLineColumnWidth + { + get { return (_TimeLineColumnWidth); } + + set + { + if (_TimeLineColumnWidth != value) + { + int oldValue = _TimeLineColumnWidth; + _TimeLineColumnWidth = value; + + CalcTimeLineColumnCount(true); + TimeLineHScrollPanel.UpdatePanel(); + + // Inform interested parties of the change + + OnTimeLineColumnWidthChanged(oldValue, value); + } + } + } + + /// + /// Sends TimeLineColumnWidthChanged event + /// + /// Old width + /// New width + private void OnTimeLineColumnWidthChanged(int oldValue, int newValue) + { + if (TimeLineColumnWidthChanged != null) + TimeLineColumnWidthChanged(this, new TimeLineColumnWidthChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region TimeLineHorizontalPadding + + /// + /// Gets and sets the horizontal padding used between + /// items displayed in the TimeLine view + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLineHorizontalPadding + { + get { return (_TimeLineHorizontalPadding); } + + set + { + if (_TimeLineHorizontalPadding != value) + { + int oldValue = _TimeLineHorizontalPadding; + _TimeLineHorizontalPadding = value; + + CalendarPanel.Refresh(); + + // Inform interested parties of the change + + OnTimeLineHorizontalPaddingChanged(oldValue, value); + } + } + } + + /// + /// Sends TimeLineHorizontalPaddingChanged events + /// + /// Old padding + /// New padding + private void OnTimeLineHorizontalPaddingChanged(int oldValue, int newValue) + { + if (TimeLineHorizontalPaddingChanged != null) + TimeLineHorizontalPaddingChanged(this, new TimeLineHorizontalPaddingChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region TimeLineIntervalHeaderHeight + + private int _TimeLineIntervalHeaderHeight; + + /// + /// Gets and sets the TimeLine Interval Header height + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLineIntervalHeaderHeight + { + get + { + return ((_TimeLineIntervalHeaderHeight > 0) + ? _TimeLineIntervalHeaderHeight : Font.Height + 7); + } + + set + { + if (_TimeLineIntervalHeaderHeight != value) + { + _TimeLineIntervalHeaderHeight = value; + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLinePeriodHeaderAlignment + + /// + /// Gets or sets the text alignment for the TimeLineView Period Header text + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public eItemAlignment TimeLinePeriodHeaderAlignment + { + get { return (_TimeLinePeriodHeaderAlignment); } + + set + { + if (_TimeLinePeriodHeaderAlignment != value) + { + _TimeLinePeriodHeaderAlignment = value; + + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLinePeriodHeaderEnableMarkup + + /// + /// Gets or sets whether text-markup support is enabled for the + /// TimeLineView Period Header text + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TimeLinePeriodHeaderEnableMarkup + { + get { return (_TimeLinePeriodHeaderEnableMarkup); } + + set + { + if (_TimeLinePeriodHeaderEnableMarkup != value) + { + _TimeLinePeriodHeaderEnableMarkup = value; + + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLineMaxColumnCount + + /// + /// Gets and sets the Calendar TimeLineMaxColumnCount + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLineMaxColumnCount + { + get { return (_TimeLineMaxColumnCount); } + + set + { + value = Math.Max(100, value); + + if (_TimeLineMaxColumnCount != value) + { + int oldValue = _TimeLineMaxColumnCount; + _TimeLineMaxColumnCount = value; + + CalcTimeLineColumnCount(true); + TimeLineHScrollPanel.UpdatePanel(); + + // Inform interested parties of the change + + OnTimeLineMaxColumnCountChanged(oldValue, value); + } + } + } + + /// + /// Sends TimeLineMaxColumnCountChanged event + /// + /// Old width + /// New width + private void OnTimeLineMaxColumnCountChanged(int oldValue, int newValue) + { + if (TimeLineMaxColumnCountChanged != null) + TimeLineMaxColumnCountChanged(this, new TimeLineMaxColumnCountChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region TimeLineInterval + + /// + /// Gets and sets the Calendar TimeLineInterval + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLineInterval + { + get { return (_TimeLineInterval); } + + set + { + value = GetValidInterval(value); + + if (_TimeLineInterval != value) + { + int oldValue = _TimeLineInterval; + _TimeLineInterval = value; + + UpdateBaseInterval(); + + DateTime date = + TimeLineViewStartDate.Date.AddMinutes(_BaseInterval * 200); + + if (date > TimeLineViewEndDate) + { + TimeLineViewEndDate = date.Date; + } + else + { + TimeLineViewStartDate = TimeLineViewStartDate.Date; + CalcTimeLineColumnCount(true); + } + + TimeLineHScrollPanel.ScrollBar.Value = 0; + TimeLineHScrollPanel.UpdatePanel(); + + OnTimeLineIntervalChanged(oldValue, value); + } + } + } + + /// + /// Sends TimeLineIntervalChanged events + /// + /// + /// + private void OnTimeLineIntervalChanged(int oldValue, int newValue) + { + if (TimeLineIntervalChanged != null) + TimeLineIntervalChanged(this, new TimeLineIntervalChangedEventArgs(oldValue, newValue)); + } + + #region GetValidInterval + + /// + /// Coerces the user supplied interval period into + /// an evenly divisible duration + /// + /// Original value + /// Validated value + private int GetValidInterval(int value) + { + if (value < 1) + return (1); + + switch (_TimeLinePeriod) + { + case eTimeLinePeriod.Minutes: + return (GetValidIntervalMinutes(value)); + + case eTimeLinePeriod.Hours: + return (GetValidIntervalHours(value)); + + case eTimeLinePeriod.Days: + return (value >= MaxDayDuration ? MaxDayDuration : value); + + case eTimeLinePeriod.Years: + return (value >= MaxYearDuration ? MaxYearDuration : value); + } + + return (1); + } + + #region GetValidIntervalMinutes + + /// + /// Gets a valid minute interval from the + /// given user supplied value + /// + /// Supplied value + /// Valid interval + private int GetValidIntervalMinutes(int value) + { + if (value < MaxMinuteDuration) + { + for (int i = 0; i < MaxMinuteDuration; i++) + { + if (MaxMinuteDuration % (value + i) == 0) + return (value + i); + } + } + + return (MaxMinuteDuration); + } + + #endregion + + #region GetValidIntervalHours + + /// + /// Gets a valid hour interval from the + /// given user supplied value + /// + /// Supplied value + /// Valid interval + private int GetValidIntervalHours(int value) + { + if (value < MaxHourDuration) + { + for (int i = 0; i < MaxHourDuration; i++) + { + if (HoursPerDay % (value + i) == 0) + return (value + i); + } + } + + return (MaxHourDuration); + } + + #endregion + + #endregion + + #region UpdateBaseInterval + + /// + /// Updates the BaseInterval value (interval total minutes) + /// + private void UpdateBaseInterval() + { + switch (_TimeLinePeriod) + { + case eTimeLinePeriod.Minutes: + _BaseInterval = _TimeLineInterval; + break; + + case eTimeLinePeriod.Hours: + _BaseInterval = _TimeLineInterval * MinutesPerHour; + break; + + case eTimeLinePeriod.Days: + _BaseInterval = _TimeLineInterval * MinutesPerDay; + break; + + case eTimeLinePeriod.Years: + _BaseInterval = _TimeLineInterval * MinutesPerYear; + break; + } + + TimeLineViewStartDate = (_TimeLinePeriod == eTimeLinePeriod.Years) ? + new DateTime(TimeLineViewStartDate.Year, 1, 1) : TimeLineViewStartDate.Date; + } + + #endregion + + #endregion + + #region TimeLinePeriod + + /// + /// Gets and sets the Calendar TimeLinePeriod + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public eTimeLinePeriod TimeLinePeriod + { + get { return (_TimeLinePeriod); } + + set + { + if (_TimeLinePeriod != value) + { + eTimeLinePeriod oldValue = _TimeLinePeriod; + _TimeLinePeriod = value; + + TimeLineInterval = + (value == eTimeLinePeriod.Minutes) ? 30 : 1; + + UpdateBaseInterval(); + UpdateBasePeriod(); + + TimeLineHScrollPanel.ScrollBar.Value = 0; + + OnTimeLineIntervalPeriodChanged(oldValue, value); + } + } + } + + /// + /// Sends TimeLineIntervalPeriodChanged events + /// + /// + /// + private void OnTimeLineIntervalPeriodChanged( + eTimeLinePeriod oldValue, eTimeLinePeriod newValue) + { + if (TimeLineIntervalPeriodChanged != null) + TimeLineIntervalPeriodChanged(this, new TimeLineIntervalPeriodChangedEventArgs(oldValue, newValue)); + } + + #region UpdateBasePeriod + + /// + /// Updates the view end date period given the + /// new base interval + /// + private void UpdateBasePeriod() + { + int intervals = 1; + + switch (_TimeLinePeriod) + { + case eTimeLinePeriod.Minutes: + intervals = (7 * 24 * 2); + break; + + case eTimeLinePeriod.Hours: + intervals = (7 * 24); + break; + + case eTimeLinePeriod.Days: + intervals = (365 / 2); + break; + + case eTimeLinePeriod.Years: + intervals = _TimeLineMaxColumnCount; + break; + } + + TimeLineViewStartDate = (_TimeLinePeriod == eTimeLinePeriod.Years) ? + new DateTime(TimeLineViewStartDate.Year, 1, 1) : TimeLineViewStartDate.Date; + + TimeLineViewEndDate = TimeLineAddInterval(TimeLineViewStartDate, intervals); + } + + #endregion + + #endregion + + #region TimeLinePeriodHeaderHeight + + /// + /// Gets or sets the TimeLine period header height. Set to -1 for default. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLinePeriodHeaderHeight + { + get + { + if (_TimeLinePeriodHeaderHeight < 0) + return (Font.Height + 7); + + return (_TimeLinePeriodHeaderHeight); + } + + set + { + if (_TimeLinePeriodHeaderHeight != value) + { + _TimeLinePeriodHeaderHeight = value; + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLineHeight + + /// + /// Gets and sets the Calendar TimeLineHeight + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLineHeight + { + get { return (_TimeLineHeight); } + + set + { + if (_TimeLineHeight != value) + { + _TimeLineHeight = value; + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLineShowPeriodHeader + + /// + /// Gets and sets the Calendar TimeLineShowPeriodHeader + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TimeLineShowPeriodHeader + { + get { return (_TimeLineShowPeriodHeader); } + + set + { + if (_TimeLineShowPeriodHeader != value) + { + _TimeLineShowPeriodHeader = value; + + OnTimeLineShowPeriodHeaderChanged(!value, value); + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + /// + /// Sends TimeLineShowPeriodHeaderChanged event + /// + /// + /// + private void OnTimeLineShowPeriodHeaderChanged(bool oldValue, bool newValue) + { + if (TimeLineShowPeriodHeaderChanged != null) + TimeLineShowPeriodHeaderChanged(this, new TimeLineShowPeriodHeaderChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region TimeLineShowIntervalHeader + + /// + /// Gets and sets the Calendar TimeLineShowIntervalHeader + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TimeLineShowIntervalHeader + { + get { return (_TimeLineShowIntervalHeader); } + + set + { + if (_TimeLineShowIntervalHeader != value) + { + _TimeLineShowIntervalHeader = value; + + OnTimeLineShowIntervalHeaderChanged(!value, value); + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + /// + /// Sends TimeLineShowIntervalHeader event + /// + /// + /// + private void OnTimeLineShowIntervalHeaderChanged(bool oldValue, bool newValue) + { + if (TimeLineShowIntervalHeaderChanged != null) + TimeLineShowIntervalHeaderChanged(this, new TimeLineShowIntervalHeaderChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region TimeLineShowPageNavigation + + /// + /// Gets and sets the Calendar TimeLineShowPageNavigation + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TimeLineShowPageNavigation + { + get { return (_TimeLineShowPageNavigation); } + + set + { + if (_TimeLineShowPageNavigation != value) + { + _TimeLineShowPageNavigation = value; + + OnTimeLineShowPageNavigationChanged(!value, value); + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + /// + /// Sends TimeLineShowPageNavigationChanged event + /// + /// + /// + private void OnTimeLineShowPageNavigationChanged(bool oldValue, bool newValue) + { + if (TimeLineShowPageNavigationChanged != null) + TimeLineShowPageNavigationChanged(this, new TimeLineShowPageNavigationChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region TimeLineShowHScrollBar + + /// + /// Gets or sets whether the Horizontal TimeLine scroll bar is shown + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TimeLineShowHScrollBar + { + get { return (_TimeLineShowHScrollBar); } + + set + { + if (_TimeLineShowHScrollBar != value) + { + _TimeLineShowHScrollBar = value; + + if (_TimeLineHScrollPanel != null) + { + if (value == true) + { + _TimeLineHScrollPanel.Visible = true; + _TimeLineHScrollPanel.Displayed = true; + } + else + { + _TimeLineHScrollPanel.Visible = false; + _TimeLineHScrollPanel.Displayed = false; + } + } + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLineCondensedViewVisibility + + /// + /// Gets and sets the Condensed View visibility + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public eCondensedViewVisibility TimeLineCondensedViewVisibility + { + get { return (_TimeLineCondensedViewVisibility); } + + set + { + if (_TimeLineCondensedViewVisibility != value) + { + eCondensedViewVisibility oldValue = _TimeLineCondensedViewVisibility; + _TimeLineCondensedViewVisibility = value; + + OnTimeLineCondensedViewVisibilityChanged(oldValue, value); + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + /// + /// Sends OnTimeLineCondensedViewVisibilityChanged event + /// + /// + /// + private void OnTimeLineCondensedViewVisibilityChanged( + eCondensedViewVisibility oldValue, eCondensedViewVisibility newValue) + { + if (TimeLineCondensedViewVisibilityChanged != null) + TimeLineCondensedViewVisibilityChanged(this, + new TimeLineCondensedViewVisibilityChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region TimeLineCondensedViewHeight + + /// + /// Gets and sets the Condensed View height + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLineCondensedViewHeight + { + get { return (_TimeLineCondensedViewHeight); } + + set + { + if (_TimeLineCondensedViewHeight != value) + { + int oldValue = _TimeLineCondensedViewHeight; + _TimeLineCondensedViewHeight = value; + + OnTimeLineCondensedViewHeightChanged(oldValue, value); + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + /// + /// Sends OnTimeLineCondensedViewHeightChanged event + /// + /// + /// + private void OnTimeLineCondensedViewHeightChanged(int oldValue, int newValue) + { + if (TimeLineCondensedViewHeightChanged != null) + TimeLineCondensedViewHeightChanged(this, + new TimeLineCondensedViewHeightChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region TimeLineStretchRowHeight + + /// + /// Gets or sets whether the row height is stretched + /// to fill the TimeLine appointment content area + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TimeLineStretchRowHeight + { + get { return (_TimeLineStretchRowHeight); } + + set + { + if (_TimeLineStretchRowHeight != value) + { + _TimeLineStretchRowHeight = value; + + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLineStretchRowHeightMode + + /// + /// Gets or sets how the row height is stretched to fill the TimeLine + /// appointment content area (TimeLineStretchRowHeight must be set to true). + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TimeLineStretchRowHeightMode TimeLineStretchRowHeightMode + { + get { return (_TimeLineStretchRowHeightMode); } + + set + { + if (_TimeLineStretchRowHeightMode != value) + { + _TimeLineStretchRowHeightMode = value; + + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLineCanExtendRange + + /// + /// Gets or sets whether the TimeLine Start and End dates can be + /// can be automatically extended by the control + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TimeLineCanExtendRange + { + get { return (_TimeLineCanExtendRange); } + set { _TimeLineCanExtendRange = value; } + } + + #endregion + + #region TimeLineShowCollateLines + + /// + /// Gets or sets whether the TimeLine view will draw collate lines + /// between each group of collated rows (see TimeLineViewGetRowCollateId event) + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool TimeLineShowCollateLines + { + get { return (_TimeLineShowCollateLines); } + set { _TimeLineShowCollateLines = value; } + } + + #endregion + + #region TimeLineMultiUserTabWidth + + /// + /// Gets and sets the Calendar TimeLine horizontal tab width + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLineMultiUserTabWidth + { + get { return (_TimeLineMultiUserTabWidth); } + + set + { + if (_TimeLineMultiUserTabWidth != value) + { + _TimeLineMultiUserTabWidth = value; + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLineMultiUserTabOrientation + + /// + /// Gets and sets the Calendar TimeLine horizontal tab orientation + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public eOrientation TimeLineMultiUserTabOrientation + { + get { return (_TimeLineMultiUserTabOrientation); } + + set + { + if (_TimeLineMultiUserTabOrientation != value) + { + _TimeLineMultiUserTabOrientation = value; + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region TimeLinePageNavigatorTodayTooltip + + /// + /// Gets or sets the Calendar TimeLineView PageNavigator TodayTooltip + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string TimeLinePageNavigatorTodayTooltip + { + get { return (_TimeLinePageNavigatorTodayTooltip); } + + set + { + _TimeLinePageNavigatorTodayTooltip = value; + + if (_TimeLineHScrollPanel != null && _TimeLineHScrollPanel.PageNavigator != null) + _TimeLineHScrollPanel.PageNavigator.TodayTooltip = value; + } + } + + #endregion + + #region TimeLinePageNavigatorPreviousPageTooltip + + /// + /// Gets or sets the Calendar TimeLineView PageNavigator PreviousPageTooltip + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string TimeLinePageNavigatorPreviousPageTooltip + { + get { return (_TimeLinePageNavigatorPreviousPageTooltip); } + + set + { + _TimeLinePageNavigatorPreviousPageTooltip = value; + + if (_TimeLineHScrollPanel != null && _TimeLineHScrollPanel.PageNavigator != null) + _TimeLineHScrollPanel.PageNavigator.PreviousPageTooltip = value; + } + } + + #endregion + + #region TimeLinePageNavigatorNextPageTooltip + + /// + /// Gets or sets the Calendar TimeLineView PageNavigator NextPageTooltip + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string TimeLinePageNavigatorNextPageTooltip + { + get { return (_TimeLinePageNavigatorNextPageTooltip); } + + set + { + _TimeLinePageNavigatorNextPageTooltip = value; + + if (_TimeLineHScrollPanel != null && _TimeLineHScrollPanel.PageNavigator != null) + _TimeLineHScrollPanel.PageNavigator.NextPageTooltip = value; + } + } + + #endregion + + #region TimeLineMinAppointmentWidth + + /// + /// Gets and sets the Calendar TimeLineView Minimum Appointment Width + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TimeLineMinAppointmentWidth + { + get { return (_TimeLineMinAppointmentWidth); } + + set + { + if (_TimeLineMinAppointmentWidth != value) + { + _TimeLineMinAppointmentWidth = value; + + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #endregion + + #region MultiCalendarView properties + + /// + /// Gets the multiCalendar state or mode + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsMultiCalendar + { + get { return (MultiCalendarDayViews != null); } + } + + /// + /// Gets the MultiCalendarDayViews collection + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CalendarViewCollection MultiCalendarDayViews + { + get { return (_MultiCalendarDayViews); } + } + + /// + /// Gets the MultiCalendarWeekViews collection + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CalendarViewCollection MultiCalendarWeekViews + { + get { return (_MultiCalendarWeekViews); } + } + + /// + /// Gets the MultiCalendarMonthViews collection + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CalendarViewCollection MultiCalendarMonthViews + { + get { return (_MultiCalendarMonthViews); } + } + + /// + /// Gets the MultiCalendarYearViews collection + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CalendarViewCollection MultiCalendarYearViews + { + get { return (_MultiCalendarYearViews); } + } + + /// + /// Gets the MultiCalendarTimeLineViews collection + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CalendarViewCollection MultiCalendarTimeLineViews + { + get { return (_MultiCalendarTimeLineViews); } + } + + #endregion + + #region DisplayedOwners + + /// + /// Gets the DisplayedOwners collection + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DisplayedOwnerCollection DisplayedOwners + { + get { return (_DisplayedOwners); } + } + + #endregion + + #region SelectedOwner + + /// + /// Gets and sets the current selected multi-user owner + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string SelectedOwner + { + get + { + if (_SelectedOwnerIndex >= 0 && _SelectedOwnerIndex < _DisplayedOwners.Count) + return (_DisplayedOwners[_SelectedOwnerIndex]); + + return (""); + } + + set + { + SelectedOwnerIndex = _DisplayedOwners.IndexOf(value); + } + } + + /// + /// Gets and sets the current selected multi-user owner + /// using a DisplayedOwner index + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectedOwnerIndex + { + get { return (_SelectedOwnerIndex); } + + set + { + if (_SelectedOwnerIndex != value) + { + if (value < 0 || value >= _DisplayedOwners.Count) + value = -1; + + int oldValue = _SelectedOwnerIndex; + _SelectedOwnerIndex = value; + + RefreshDisplayTabs(oldValue, value); + + DateSelectionStart = null; + DateSelectionEnd = null; + + OnSelectedOwnerChanged(oldValue, value); + } + } + } + + #region RefreshDisplayTabs + + /// + /// Refreshes the deselected and newly selected tabs + /// + /// Old tab index + /// New tab index + private void RefreshDisplayTabs(int oldValue, int newValue) + { + if (IsMultiCalendar == true) + { + switch (SelectedView) + { + case eCalendarView.Day: + if (oldValue >= 0 && oldValue < MultiCalendarDayViews.Views.Count) + RefreshHTab(MultiCalendarDayViews.Views[oldValue], true); + + if (newValue >= 0 && newValue < MultiCalendarDayViews.Views.Count) + RefreshHTab(MultiCalendarDayViews.Views[newValue], false); + break; + + case eCalendarView.Week: + if (oldValue >= 0 && oldValue < MultiCalendarWeekViews.Views.Count) + RefreshHTab(MultiCalendarWeekViews.Views[oldValue], true); + + if (newValue >= 0 && newValue < MultiCalendarWeekViews.Views.Count) + RefreshHTab(MultiCalendarWeekViews.Views[newValue], false); + break; + + case eCalendarView.Month: + if (oldValue >= 0 && oldValue < MultiCalendarMonthViews.Views.Count) + RefreshHTab(MultiCalendarMonthViews.Views[oldValue], true); + + if (newValue >= 0 && newValue < MultiCalendarMonthViews.Views.Count) + RefreshHTab(MultiCalendarMonthViews.Views[newValue], false); + break; + + case eCalendarView.Year: + if (oldValue >= 0 && oldValue < MultiCalendarYearViews.Views.Count) + RefreshHTab(MultiCalendarYearViews.Views[oldValue], true); + + if (newValue >= 0 && newValue < MultiCalendarYearViews.Views.Count) + RefreshHTab(MultiCalendarYearViews.Views[newValue], false); + break; + + case eCalendarView.TimeLine: + if (oldValue >= 0 && oldValue < MultiCalendarTimeLineViews.Views.Count) + RefreshVTab(MultiCalendarTimeLineViews.Views[oldValue], true); + + if (newValue >= 0 && newValue < MultiCalendarTimeLineViews.Views.Count) + RefreshVTab(MultiCalendarTimeLineViews.Views[newValue], false); + break; + } + } + } + + #endregion + + #region RefreshHTab + + /// + /// Invalidates the given view tab + /// + /// + /// + private void RefreshHTab(BaseView view, bool resetSelItem) + { + Rectangle r = view.Bounds; + r.Height = MultiUserTabHeight; + + view.InvalidateRect(r); + + // Reset the selected item for the old view + + if (resetSelItem == true) + view.SelectedItem = null; + + // Invalidate any active TimeIndicators + + InvalidateTimeIndicators(view); + } + + #endregion + + #region RefreshVTab + + /// + /// Invalidates the given view tab + /// + /// + /// + private void RefreshVTab(TimeLineView view, bool resetSelItem) + { + Rectangle r = view.Bounds; + + if (_TimeLineMultiUserTabOrientation == eOrientation.Vertical) + r.Width = view.MultiUserTabHeight + 4; + else + r.Width = _TimeLineMultiUserTabWidth + 4; + + view.InvalidateRect(r); + + // Reset the selected item for the old view + + if (resetSelItem == true) + view.SelectedItem = null; + + // Invalidate any condensed views and any + // active TimeIndicators + + InvalidateCondensedViews(view); + InvalidateTimeIndicators(view); + } + + #endregion + + #region InvalidateCondensedViews + + /// + /// InvalidateCondensedViews + /// + /// + private void InvalidateCondensedViews(TimeLineView view) + { + // If the user has condensed TimeLine showing + // then make sure it gets refreshed + + if (TimeLineCondensedViewVisibility != eCondensedViewVisibility.Hidden) + { + view.UpdateCondensedColumnList(); + + Rectangle r = view.ClientRect; + + r.Y = r.Bottom - TimeLineCondensedViewHeight; + r.Height = TimeLineCondensedViewHeight; + + view.InvalidateRect(r); + } + } + + #endregion + + #region InvalidateTimeIndicators + + /// + /// InvalidateTimeIndicators + /// + /// + private void InvalidateTimeIndicators(BaseView view) + { + for (int i = 0; i < TimeIndicators.Count; i++) + { + TimeIndicator ti = TimeIndicators[i]; + + if (ti.Visibility == eTimeIndicatorVisibility.SelectedResource) + InvalidateTimeIndicator(view, ti, ti.IndicatorDisplayTime); + } + } + + #endregion + + #region InvalidateTimeIndicator + + /// + /// Invalidates TimeIndicator display area + /// for the given view DateTime + /// + /// + /// + /// + private void InvalidateTimeIndicator(BaseView view, TimeIndicator ti, DateTime dateTime) + { + Rectangle r = view.GetIndicatorRect(ti, dateTime); + + if (r.IsEmpty == false) + { + r.Inflate(4, 4); + + view.InvalidateRect(r); + } + } + + #endregion + + #region OnSelectedOwnerChanged + + /// + /// Propagates SelectedOwnerChanged events + /// + /// Old index + /// New index + private void OnSelectedOwnerChanged(int oldValue, int newValue) + { + if (SelectedOwnerChanged != null) + { + SelectedOwnerChanged(this, + new SelectedOwnerChangedEventArgs(oldValue, newValue)); + } + } + + #endregion + + #endregion + + #region SelectedAppointments + + /// + /// Gets the read-only collection of currently selected + /// appointments in the current view + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ReadOnlyCollection SelectedAppointments + { + get + { + if (IsMultiCalendar == true) + { + switch (_SelectedView) + { + case eCalendarView.Day: + return (_MultiCalendarDayViews[_SelectedOwnerIndex].SelectedAppointments); + + case eCalendarView.Week: + return (_MultiCalendarWeekViews[_SelectedOwnerIndex].SelectedAppointments); + + case eCalendarView.Month: + return (_MultiCalendarMonthViews[_SelectedOwnerIndex].SelectedAppointments); + + case eCalendarView.TimeLine: + return (_MultiCalendarTimeLineViews[_SelectedOwnerIndex].SelectedAppointments); + } + } + else + { + switch (SelectedView) + { + case eCalendarView.Day: + return (DayView.SelectedAppointments); + + case eCalendarView.Week: + return (WeekView.SelectedAppointments); + + case eCalendarView.Month: + return (MonthView.SelectedAppointments); + + case eCalendarView.TimeLine: + return (TimeLineView.SelectedAppointments); + } + } + + return (null); + } + } + + #endregion + + #region TimeIndicators + + /// + /// TimeIndicators + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TimeIndicatorCollection TimeIndicators + { + get + { + if (_TimeIndicators == null) + { + _TimeIndicators = new TimeIndicatorCollection(); + + _TimeIndicators.TimeIndicatorCollectionChanged += TimeIndicatorsTimeIndicatorCollectionChanged; + _TimeIndicators.TimeIndicatorTimeChanged += TimeIndicatorsTimeIndicatorTimeChanged; + _TimeIndicators.TimeIndicatorColorChanged += TimeIndicatorsTimeIndicatorColorChanged; + } + + return (_TimeIndicators); + } + } + + #endregion + + #region ViewDisplayCustomizations + + /// + /// Gets the CalendarView ViewDisplayCustomizations + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ViewDisplayCustomizations ViewDisplayCustomizations + { + get + { + if (_ViewDisplayCustomizations == null) + { + _ViewDisplayCustomizations = new ViewDisplayCustomizations(this); + + _ViewDisplayCustomizations.CollectionChanged += ViewDisplayCustomizationsCollectionChanged; + } + + return (_ViewDisplayCustomizations); + } + } + + #endregion + + #region ViewWidth + + /// + /// Gets and sets the Calendar ViewWidth + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [DefaultValue(250)] + public int ViewWidth + { + get { return (_ViewWidth); } + + set + { + if (_ViewWidth != value) + { + _ViewWidth = value; + + if (CalendarPanel.HScrollBar != null) + CalendarPanel.HScrollBar.Value = 0; + + CalendarPanel.NeedRecalcSize = true; + CalendarPanel.Refresh(); + } + } + } + + #endregion + + #region VScrollBar + + /// + /// Gets the Calendar Multiuser Vertical scrollbar + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public VScrollBarAdv VScrollBar + { + get { return (_CalendarPanel.VScrollBar); } + } + + #endregion + + #region WeekDayVScrollBar + + /// + /// Gets the WeekDay Vertical scrollbar + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public VScrollBarAdv WeekDayVScrollBar + { + get { return (WeekDayVScrollPanel != null ? WeekDayVScrollPanel.ScrollBar : null); } + } + + #endregion + + #region Style + + /// + /// Gets/Sets the visual style of the CalendarView + /// + [Browsable(false), DevCoBrowsable(true)] + [Category("Appearance"), Description("Specifies the visual style of the Control.")] + [DefaultValue(eDotNetBarStyle.StyleManagerControlled)] + public eDotNetBarStyle Style + { + get + { + return (CalendarPanel.Style); + } + set + { + if (CalendarPanel.Style != value) + { + CalendarPanel.Style = value; + + Invalidate(); + } + } + } + + #endregion + + #endregion + + #endregion + + #region Private properties + + /// + /// Gets the default (cycling) color scheme + /// + private eCalendarColor DefaultCalendarColor + { + get + { + if (IsMultiCalendar == true) + { + eCalendarColor c = (eCalendarColor)_DefaultCalendarColor++; + + if (_DefaultCalendarColor >= (int)eCalendarColor.Automatic) + _DefaultCalendarColor = 0; + + return (c); + } + + return (eCalendarColor.Automatic); + } + } + + #endregion + + #region Internal properties + + #region Base properties + + /// + /// Gets the CalendarPanel object + /// + internal CalendarPanel CalendarPanel + { + get { return (_CalendarPanel); } + } + + /// + /// Gets the width of a vertical scrollbar + /// + internal int VsWidth + { + get { return (SystemInformation.VerticalScrollBarWidth); } + } + + /// + /// Gets the height of a horizontal scrollbar + /// + internal int HsHeight + { + get { return (SystemInformation.HorizontalScrollBarHeight); } + } + + /// + /// Gets and sets the AutoSyncDate + /// + internal DateTime AutoSyncDate + { + get { return (_AutoSyncDate); } + set { _AutoSyncDate = value; } + } + + /// + /// Gets whether any CategoryColors have been defined + /// + internal bool HasCategoryColors + { + get { return (_CategoryColors != null); } + } + + #endregion + + #region WeekDay properties + + /// + /// Gets the default TimeSlice height + /// + internal float TimeSliceHeight + { + get { return (_TimeSliceHeight); } + + set + { + int n = (_MinimumTimeSlotHeight > 0) + ? _MinimumTimeSlotHeight : Font.Height + Dpi.Height(7); + + if (value < n) + value = n; + + _TimeSliceHeight = value; + } + } + + /// + /// Gets the number of WeekDay time slices + /// + internal int NumberOfSlices + { + get { return (_NumberOfSlices); } + set { _NumberOfSlices = value; } + } + + /// + /// Gets the NumberOfActiveSlices + /// + internal int NumberOfActiveSlices + { + get { return (_NumberOfSlices - 1); } + } + + /// + /// WeekDay starting Slice + /// + internal int StartSlice + { + get { return (_StartSlice); } + set { _StartSlice = value; } + } + + /// + /// Gets the number of slots per hour + /// + internal int SlotsPerHour + { + get { return (_SlotsPerHour); } + } + + /// + /// Gets the WeekDay Vertical Scroll panel + /// + internal WeekDayVScrollPanel WeekDayVScrollPanel + { + get + { + if (_WeekDayVScrollPanel == null) + _WeekDayVScrollPanel = new WeekDayVScrollPanel(this); + + return (_WeekDayVScrollPanel); + } + } + + /// + /// Gets the Year Vertical Scroll panel + /// + internal YearVScrollPanel YearVScrollPanel + { + get + { + if (_YearVScrollPanel == null) + _YearVScrollPanel = new YearVScrollPanel(this); + + return (_YearVScrollPanel); + } + } + + /// + /// Gets the AllDay panel height + /// + internal int AllDayPanelHeight + { + get + { + for (int i = 0; i < _CalendarPanel.SubItems.Count; i++) + { + WeekDayView wv = _CalendarPanel.SubItems[i] as WeekDayView; + + if (wv != null) + return (wv.AllDayPanel.PanelHeight); + } + + return (0); + } + } + + /// + /// Gets the TimerRuler width + /// + internal int TimeRulerWidth + { + get { return (Dpi.Width(40)); } + } + + #endregion + + #region Year properties + + internal int YearViewMax + { + get { return (_YearViewMax); } + set { _YearViewMax = value; } + } + + #endregion + + #region TimeLine properties + + /// + /// Gets the base interval (total minutes) + /// + internal double BaseInterval + { + get { return (_BaseInterval); } + } + + /// + /// Gets the TimeLine column count + /// + internal int TimeLineColumnCount + { + get { return (_TimeLineColumnCount); } + } + + /// + /// Gets the TimeLine Horizontal Scroll panel + /// + internal TimeLineHScrollPanel TimeLineHScrollPanel + { + get + { + if (_TimeLineHScrollPanel == null) + _TimeLineHScrollPanel = new TimeLineHScrollPanel(this); + + return (_TimeLineHScrollPanel); + } + } + + internal bool HasTimeLineSlotBackgroundCallout + { + get + { + return (TimeLinePreRenderSlotBackground != null || + TimeLinePostRenderSlotBackground != null); + } + } + + internal bool HasTimeLineGetRowCollateIdCallout + { + get { return (TimeLineGetRowCollateId != null); } + } + + #endregion + + #region HasViewDisplayCustomizations + + /// + /// Gets whether the user has defined any ViewDisplayCustomizations + /// + internal bool HasViewDisplayCustomizations + { + get { return (_ViewDisplayCustomizations != null); } + } + + #endregion + + #region Cursor support + + /// + /// Sets the local view cursor + /// + internal Cursor ViewCursor + { + set + { + try + { + _SetCursor = true; + + Cursor = value; + } + finally + { + _SetCursor = false; + } + } + } + + /// + /// Gets the default cursor + /// + internal Cursor DefaultViewCursor + { + get { return (_DefaultViewCursor); } + } + + #endregion + + #endregion + + #region Public methods + + #region ShowDate + + /// + /// Navigates the current calendar view to show the given date + /// + /// Date to show in the calendar view + public void ShowDate(DateTime date) + { + ShowViewDate(SelectedView, date.Date); + } + + /// + /// Navigates the given view to show date + /// + /// View to navigate + /// Date to navigate to + internal void ShowViewDate(eCalendarView view, DateTime date) + { + if (view == eCalendarView.Day) + { + DayViewDate = date; + } + else if (view == eCalendarView.Week && + (date < WeekViewStartDate || date > WeekViewEndDate)) + { + WeekViewStartDate = DateHelper.GetDateForDayOfWeek(date, DateHelper.GetFirstDayOfWeek()); + WeekViewEndDate = WeekViewStartDate.AddDays(6); + } + else if (view == eCalendarView.Month && + (date < MonthViewStartDate || date > MonthViewEndDate)) + { + MonthViewStartDate = date.AddDays(-(date.Day - 1)); + MonthViewEndDate = MonthViewStartDate.AddMonths(1).AddMinutes(-1); + } + else if (view == eCalendarView.Year && + (date < YearViewStartDate || date > YearViewEndDate)) + { + int monthSpan = (YearViewEndDate.Year * 12 + YearViewEndDate.Month) - + (YearViewStartDate.Year * 12 + YearViewStartDate.Month) + 1; + + YearViewStartDate = date.AddDays(-(date.Day - 1)); + YearViewEndDate = YearViewStartDate.AddMonths(monthSpan).AddDays(-1); + } + else if (view == eCalendarView.TimeLine && + (date < TimeLineViewScrollStartDate || date > TimeLineViewScrollEndDate)) + { + TimeLineViewScrollStartDate = date; + } + } + + #endregion + + #region ScrollToTime + + /// + /// Scrolls the Day/Week calendar view to the + /// specified hour and minute + /// + /// Hour to scroll to + /// Minute to scroll to + public void ScrollToTime(int hour, int minute) + { + if (SelectedView == eCalendarView.Day || SelectedView == eCalendarView.Week) + { + int offset = (int)(hour * _SlotsPerHour * TimeSliceHeight + + (TimeSliceHeight * minute) / _TimeSlotDuration); + + offset -= (int)(StartSlice * TimeSliceHeight); + + offset = Math.Min(offset, _WeekDayVScrollPanel.ScrollBar.Maximum); + offset = Math.Max(offset, 0); + + _WeekDayVScrollPanel.ScrollBar.Value = offset; + } + } + + #endregion + + #region EnsureVisible + + /// + /// Ensures that the given Appointment is visible + /// in the current view. It will change the view date and + /// scroll as necessary to ensure the appointment is visible + /// + /// Appointment to bring into view + public void EnsureVisible(Appointment appointment) + { + EnsureVisible(appointment.StartTime, appointment.EndTime); + } + + /// + /// Ensures that the given CustomCalendarItem is visible + /// in the current view. It will change the view date and + /// scroll as necessary to ensure the item is visible + /// + /// Appointment to bring into view + public void EnsureVisible(CustomCalendarItem item) + { + EnsureVisible(item.StartTime, item.EndTime); + } + + /// + /// Ensures that the given calendarItem is visible + /// in the current view. It will change the view date and + /// scroll as necessary to ensure it is visible + /// + /// Item start time + /// Item end time + public void EnsureVisible(DateTime startTime, DateTime endTime) + { + bool multiday = (startTime < endTime && + (endTime.Subtract(startTime).TotalDays >= 1 || + DateTimeHelper.IsSameDay(startTime, endTime) == false)); + + switch (SelectedView) + { + case eCalendarView.Day: + DayViewDate = startTime.Date; + + if (multiday == false) + ScrollToTime(startTime.Hour, startTime.Minute); + break; + + case eCalendarView.Week: + if (startTime < WeekViewStartDate || startTime > WeekViewEndDate) + { + TimeSpan span = TimeSpan.FromDays(6); + + if (WeekViewStartDate != DateTime.MinValue && WeekViewEndDate != DateTime.MinValue) + span = WeekViewEndDate.Subtract(WeekViewStartDate); + + DateTime date = DateHelper.GetDateForDayOfWeek(startTime, + DateHelper.GetFirstDayOfWeek()); + + WeekViewStartDate = date.Date; + WeekViewEndDate = WeekViewStartDate.Add(span); + } + + if (multiday == false) + ScrollToTime(startTime.Hour, startTime.Minute); + break; + + case eCalendarView.Month: + if (startTime < MonthViewStartDate || startTime > MonthViewEndDate) + { + DateTime date = startTime.Date; + + MonthViewStartDate = date.Date.AddDays(-(date.Day - 1)); + MonthViewEndDate = MonthViewStartDate.AddMonths(1).AddMinutes(-1); + } + break; + + case eCalendarView.TimeLine: + if (startTime < TimeLineViewScrollStartDate || + startTime > TimeLineViewScrollEndDate) + { + TimeLineViewScrollStartDate = startTime; + } + break; + } + } + + #endregion + + #region GetAppointmentView + + /// + /// Gets the AppointmentView in the current displayed + /// view that was created for the given appointment + /// + /// Reference to AppointmentView or null if not found + public AppointmentView GetAppointmentView(Appointment appointment) + { + for (int i = 0; i < _CalendarPanel.SubItems.Count; i++) + { + BaseView view = _CalendarPanel.SubItems[i] as BaseView; + + if (view != null) + { + AppointmentView apv = view.GetAppointmentView(appointment); + + if (apv != null) + return (apv); + } + } + + return (null); + } + + #endregion + + #region GetAppointmentViewFromPoint + + /// + /// Gets the AppointmentView in the current displayed + /// view that was created for the given appointment + /// + /// Reference to AppointmentView or null if not found + public AppointmentView GetAppointmentViewFromPoint(Point pt) + { + BaseView bv = GetViewFromPoint(pt); + + if (bv != null) + return (bv.GetAppointmentViewFromPoint(pt)); + + return (null); + } + + #endregion + + #region GetDateSelectionFromPoint + + /// + /// Gets the default date selection from the given point. The startDate + /// and endDate will vary based upon the view type (WeekDay / Month) + /// + /// Point in question + /// [out] Start date + /// [out] End date + /// True if a valid selection exists + /// at the given point + public bool GetDateSelectionFromPoint( + Point pt, out DateTime startDate, out DateTime endDate) + { + BaseView bv = GetViewFromPoint(pt); + + if (bv != null) + return (bv.GetDateSelectionFromPoint(pt, out startDate, out endDate)); + + startDate = new DateTime(); + endDate = new DateTime(); + + return (false); + } + + #endregion + + #region GetViewFromPoint + + /// + /// Gets the View that contains the given point + /// + /// Point in question + /// BaseView containing the given point, or null + public BaseView GetViewFromPoint(Point pt) + { + if (_CalendarPanel != null) + { + for (int i = 0; i < _CalendarPanel.SubItems.Count; i++) + { + BaseView bv = _CalendarPanel.SubItems[i] as BaseView; + + if (bv != null) + { + if (bv.Bounds.Contains(pt)) + return (bv); + } + } + } + + return (null); + } + + #endregion + + #region GetSelectedView + + /// + /// Gets the current selected BaseView + /// + /// + public BaseView GetSelectedView() + { + if (_CalendarPanel != null) + { + for (int i = 0; i < _CalendarPanel.SubItems.Count; i++) + { + BaseView bv = _CalendarPanel.SubItems[i] as BaseView; + + if (bv != null) + { + if (bv.IsViewSelected == true && + bv.DisplayedOwnerKeyIndex == SelectedOwnerIndex) + { + return (bv); + } + } + } + } + + return (null); + } + + #endregion + + #endregion + + #region Internal methods + + internal DateTime TimeLineAddInterval(DateTime startDate, int interval) + { + return ((TimeLinePeriod == eTimeLinePeriod.Years) ? + startDate.AddYears(interval * TimeLineInterval) : + startDate.AddMinutes(interval * BaseInterval)); + } + + #endregion + + #region HookModelEvents + + /// + /// Hooks needed events + /// + /// True to hook, false to unhook + private void HookModelEvents(bool hook) + { + if (hook == true) + { + _CalendarModel.AppointmentStartTimeReached += + CalendarModelAppointmentStartTimeReached; + + _CalendarModel.ReminderNotification += + CalendarModelReminderNotification; + } + else + { + _CalendarModel.AppointmentStartTimeReached -= + CalendarModelAppointmentStartTimeReached; + + _CalendarModel.ReminderNotification -= + CalendarModelReminderNotification; + } + } + + #endregion + + #region Event handling + + #region Theme Changing + + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + if (BarFunctions.IsHandleValid(this)) + Invalidate(true); + + BackColor = ((Office2007Renderer) + GlobalManager.Renderer).ColorTable.CalendarView.TimeRulerColors[0].Colors[0]; + } + + #endregion + + #region ReminderNotification + + /// + /// ReminderNotification + /// + /// + /// + private void CalendarModelReminderNotification(object sender, ReminderEventArgs e) + { + if (AppointmentReminder != null) + ReminderNotification(e); + } + + /// + /// Dispatches ReminderNotification to UI thread + /// + /// + private void ReminderNotification(ReminderEventArgs e) + { + if (InvokeRequired) + { + BeginInvoke(new + MethodInvoker(delegate { ReminderNotification(e); })); + } + else + { + AppointmentReminder(this, e); + } + } + + #endregion + + #region AppointmentStartTimeReached + + /// + /// AppointmentStartTimeReached + /// + /// + /// + private void CalendarModelAppointmentStartTimeReached(object sender, AppointmentEventArgs e) + { + if (AppointmentStartTimeReached != null) + StartTimeReachedNotification(e); + } + + /// + /// Dispatches AppointmentStartTimeReached to UI thread + /// + /// + private void StartTimeReachedNotification(AppointmentEventArgs e) + { + if (InvokeRequired) + { + BeginInvoke(new + MethodInvoker(delegate { StartTimeReachedNotification(e); })); + } + else + { + AppointmentStartTimeReached(this, e); + } + } + + #endregion + + #region AppointmentCategoryColorCollectionChanged + + /// + /// AppointmentCategoryColorCollectionChanged + /// + /// + /// + void CategoryColorsAppointmentCategoryColorCollectionChanged(object sender, EventArgs e) + { + Invalidate(); + } + + #endregion + + #region TimeIndicatorCollectionChanged + + /// + /// TimeIndicatorCollectionChanged + /// + /// + /// + void TimeIndicatorsTimeIndicatorCollectionChanged(object sender, EventArgs e) + { + if (TimeIndicatorsChanged != null) + TimeIndicatorsChanged(this, EventArgs.Empty); + + Invalidate(); + } + + #endregion + + #region TimeIndicatorColorChanged + + /// + /// Processes TimeIndicatorColorChanged events + /// + /// + /// + void TimeIndicatorsTimeIndicatorColorChanged(object sender, TimeIndicatorColorChangedEventArgs e) + { + if (TimeIndicatorColorChanged != null) + TimeIndicatorColorChanged(this, e); + + TimeIndicator ti = e.TimeIndicator; + + if (ti.Visibility != eTimeIndicatorVisibility.Hidden && + (ti.IndicatorArea == eTimeIndicatorArea.All || + ti.IndicatorArea == eTimeIndicatorArea.Content)) + { + for (int i = 0; i < CalendarPanel.SubItems.Count; i++) + { + BaseView view = CalendarPanel.SubItems[i] as BaseView; + + if (view != null && view.Displayed == true) + InvalidateTimeIndicator(view, ti, ti.IndicatorDisplayTime); + } + } + } + + #endregion + + #region TimeIndicatorTimeChanged + + /// + /// Processes TimeIndicatorTimeChanged events + /// + /// + /// + void TimeIndicatorsTimeIndicatorTimeChanged(object sender, TimeIndicatorTimeChangedEventArgs e) + { + if (TimeIndicatorTimeChanged != null) + TimeIndicatorTimeChanged(this, e); + + TimeIndicator ti = e.TimeIndicator; + + if (ti.Visibility != eTimeIndicatorVisibility.Hidden && + (ti.IndicatorArea == eTimeIndicatorArea.All || + ti.IndicatorArea == eTimeIndicatorArea.Content)) + { + for (int i = 0; i < CalendarPanel.SubItems.Count; i++) + { + BaseView view = CalendarPanel.SubItems[i] as BaseView; + + if (view != null && view.Displayed == true) + { + InvalidateTimeIndicator(view, ti, e.OldTime); + InvalidateTimeIndicator(view, ti, e.NewTime); + } + } + } + } + + #endregion + + #region ViewDisplayCustomizations_CollectionChanged + + void ViewDisplayCustomizationsCollectionChanged(object sender, EventArgs e) + { + if (ViewDisplayCustomizationsChanged != null) + ViewDisplayCustomizationsChanged(this, e); + } + + #endregion + + #endregion + + #region InitDefaultViews + + /// + /// InitDefaultViews + /// + private void InitDefaultViews() + { + _DayViewDate = DateTime.Today; + _AutoSyncDate = _DayViewDate; + _WeekViewStartDate = DateHelper.GetDateForDayOfWeek(DateTime.Today, DateHelper.GetFirstDayOfWeek()); + _WeekViewEndDate = WeekViewStartDate.AddDays(6); + + _MonthViewStartDate = DateTime.Today.AddDays(-(DateTime.Today.Day - 1)); + _MonthViewEndDate = MonthViewStartDate.AddMonths(1).AddDays(-1); + + _YearViewStartDate = DateTime.Today.AddDays(-(DateTime.Today.Day - 1)); + _YearViewEndDate = _YearViewStartDate.AddMonths(12).AddDays(-1); + + _TimeLineViewStartDate = DateTime.Today; + _TimeLineViewEndDate = _TimeLineViewStartDate.AddDays(7); + + CalcTimeLineColumnCount(true); + + _NumberOfSlices = HoursPerDay * (MinutesPerHour / _TimeSlotDuration); + _SlotsPerHour = MinutesPerHour / _TimeSlotDuration; + } + + #endregion + + #region SetSelectedView + + /// + /// Sets the selected view + /// + /// View to select + internal void SetSelectedView(eCalendarView value) + { + _SelectedView = value; + + _CalendarPanel.SubItems.Clear(); + + if (IsMultiCalendar) + InstallMultiCalendar(value); + else + InstallSingleCalendar(value); + + _CalendarPanel.RecalcSize(); + _CalendarPanel.Refresh(); + } + + #region Single Calendar Install + + /// + /// Installs single-user calendar + /// + /// eCalendarView + private void InstallSingleCalendar(eCalendarView value) + { + switch (value) + { + case eCalendarView.Day: + SetupWeekDayView(); + InstallView(DayView); + break; + + case eCalendarView.Week: + SetupWeekDayView(); + InstallView(WeekView); + break; + + case eCalendarView.Month: + SetupMonthView(); + InstallView(MonthView); + break; + + case eCalendarView.Year: + SetupYearView(); + InstallView(YearView); + break; + + case eCalendarView.TimeLine: + SetupTimeLineView(); + InstallView(TimeLineView); + break; + } + } + + #endregion + + #region MultiCalendar Install + + /// + /// Installs multi-user calendar + /// + /// + private void InstallMultiCalendar(eCalendarView value) + { + switch (value) + { + case eCalendarView.Day: + InstallMultiDayCalendar(); + break; + + case eCalendarView.Week: + InstallMultiWeekCalendar(); + break; + + case eCalendarView.Month: + InstallMultiMonthCalendar(); + break; + + case eCalendarView.Year: + InstallMultiYearCalendar(); + break; + + case eCalendarView.TimeLine: + InstallMultiTimeLineCalendar(); + break; + } + } + + #region InstallMultiDayCalendar + + /// + /// Installs multi-user DayView calendar + /// + private void InstallMultiDayCalendar() + { + if (_MultiCalendarDayViews.Count > 0) + { + SetupWeekDayView(); + + for (int i = 0; i < _MultiCalendarDayViews.Count; i++) + InstallView(_MultiCalendarDayViews[i]); + } + } + + #endregion + + #region InstallMultiWeekCalendar + + /// + /// Installs multi-user WeekView calendar + /// + private void InstallMultiWeekCalendar() + { + if (_MultiCalendarWeekViews.Count > 0) + { + SetupWeekDayView(); + + for (int i = 0; i < _MultiCalendarWeekViews.Count; i++) + InstallView(_MultiCalendarWeekViews[i]); + } + } + + #endregion + + #region InstallMultiMonthCalendar + + /// + /// Installs multi-user MonthView calendar + /// + private void InstallMultiMonthCalendar() + { + if (_MultiCalendarMonthViews.Count > 0) + { + SetupMonthView(); + + for (int i = 0; i < _MultiCalendarMonthViews.Count; i++) + InstallView(_MultiCalendarMonthViews[i]); + } + } + + #endregion + + #region InstallMultiYearCalendar + + /// + /// Installs multi-user YearView calendar + /// + private void InstallMultiYearCalendar() + { + if (_MultiCalendarYearViews.Count > 0) + { + SetupYearView(); + + for (int i = 0; i < _MultiCalendarYearViews.Count; i++) + InstallView(_MultiCalendarYearViews[i]); + } + } + + #endregion + + #region InstallMultiTimeLineCalendar + + /// + /// Installs multi-user TimeLineView calendar + /// + private void InstallMultiTimeLineCalendar() + { + if (_MultiCalendarTimeLineViews.Count > 0) + { + SetupTimeLineView(); + + for (int i = 0; i < _MultiCalendarTimeLineViews.Count; i++) + InstallView(_MultiCalendarTimeLineViews[i]); + } + } + + #endregion + + #region TimeRulePanel support + + /// + /// Installs the TimeRulerPanel + /// + private void InstallTimerPanel() + { + if (_IsTimeRulerVisible == true) + { + if (_TimeRulerPanel == null) + _TimeRulerPanel = new TimeRulerPanel(this); + + _TimeRulerPanel.Displayed = true; + + _CalendarPanel.SubItems.Add(_TimeRulerPanel); + } + } + + /// + /// Release the TimeRulerPanel + /// + private void ReleaseTimeRulerPanel() + { + if (_TimeRulerPanel != null) + _TimeRulerPanel.Displayed = false; + } + + #endregion + + #region WeekDayVScrollPanel support + + private void InstallWeekDayVScrollPanel() + { + if (_WeekDayVScrollPanel == null) + _WeekDayVScrollPanel = new WeekDayVScrollPanel(this); + + _WeekDayVScrollPanel.Visible = true; + _WeekDayVScrollPanel.Displayed = true; + + _CalendarPanel.SubItems.Add(_WeekDayVScrollPanel); + } + + private void ReleaseWeekDayVScrollPanel() + { + if (_WeekDayVScrollPanel != null) + _WeekDayVScrollPanel.Visible = false; + } + + #endregion + + #region YearVScrollPanel support + + private void InstallYearVScrollPanel() + { + if (_YearVScrollPanel == null) + _YearVScrollPanel = new YearVScrollPanel(this); + + _CalendarPanel.SubItems.Add(_YearVScrollPanel); + } + + private void ReleaseYearVScrollPanel() + { + if (_YearVScrollPanel != null) + _YearVScrollPanel.Visible = false; + } + + #endregion + + #region TimeLineHeaderPanel support + + private void InstallTimeLineHeaderPanel() + { + if (_TimeLineHeaderPanel == null) + _TimeLineHeaderPanel = new TimeLineHeaderPanel(this); + + _TimeLineHeaderPanel.Displayed = true; + + _CalendarPanel.SubItems.Add(_TimeLineHeaderPanel); + } + + /// + /// Release the TimeLineHeaderPanel + /// + private void ReleaseTimeLineHeaderPanel() + { + if (_TimeLineHeaderPanel != null) + _TimeLineHeaderPanel.Displayed = false; + } + + #endregion + + #region TimeLineHScrollPanel support + + /// + /// Installs the TimeLine Horizontal Scroll Panel + /// + private void InstallTimeLineHScrollPanel() + { + if (_TimeLineHScrollPanel == null) + _TimeLineHScrollPanel = new TimeLineHScrollPanel(this); + + _TimeLineHScrollPanel.ScrollPanelChanged -= ScrollPanelChanged; + _TimeLineHScrollPanel.ScrollPanelChanged += ScrollPanelChanged; + + if (_TimeLineShowHScrollBar == true) + { + _TimeLineHScrollPanel.Visible = true; + _TimeLineHScrollPanel.Displayed = true; + } + else + { + _TimeLineHScrollPanel.Visible = false; + _TimeLineHScrollPanel.Displayed = false; + } + + _CalendarPanel.SubItems.Add(_TimeLineHScrollPanel); + } + + /// + /// Handles Scroll Panel updates + /// + /// + /// + private void ScrollPanelChanged(object sender, EventArgs e) + { + TimeLineViewScrollStartDate = + _TimeLineViewStartDate.AddMinutes(_BaseInterval * TimeLineHScrollPanel.ScrollBar.Value); + } + + /// + /// Releases the Horizontal Scroll Panel + /// + private void ReleaseTimeLineHScrollPanel() + { + if (_TimeLineHScrollPanel != null) + { + _TimeLineHScrollPanel.Visible = false; + + _TimeLineHScrollPanel.ScrollPanelChanged -= ScrollPanelChanged; + } + } + + #endregion + + #endregion + + #region SetupView support + + #region SetupWeekDayView + + private void SetupWeekDayView() + { + ReleaseTimeLineHeaderPanel(); + ReleaseTimeLineHScrollPanel(); + ReleaseYearVScrollPanel(); + + InstallWeekDayVScrollPanel(); + InstallTimerPanel(); + } + + #endregion + + #region SetupMonthView + + private void SetupMonthView() + { + ReleaseTimeRulerPanel(); + ReleaseWeekDayVScrollPanel(); + ReleaseYearVScrollPanel(); + ReleaseTimeLineHeaderPanel(); + ReleaseTimeLineHScrollPanel(); + } + + #endregion + + #region SetupYearView + + private void SetupYearView() + { + ReleaseTimeRulerPanel(); + ReleaseWeekDayVScrollPanel(); + ReleaseTimeLineHeaderPanel(); + ReleaseTimeLineHScrollPanel(); + + InstallYearVScrollPanel(); + } + + #endregion + + #region SetupTimeLineView + + private void SetupTimeLineView() + { + ReleaseTimeRulerPanel(); + ReleaseWeekDayVScrollPanel(); + ReleaseYearVScrollPanel(); + + InstallTimeLineHScrollPanel(); + InstallTimeLineHeaderPanel(); + } + + #endregion + + #endregion + + #region InstallView + + /// + /// Installs the given View into the CalendarPanel + /// + /// View to install + private void InstallView(BaseView view) + { + if (view != null) + { + view.Displayed = true; + view.IsViewSelected = true; + view.Style = _CalendarPanel.Style; + + _CalendarPanel.SubItems.Add(view); + } + } + + #endregion + + #endregion + + #region AppointmentView + + #region DoAppointmentViewChanging + + /// + /// Routine to initiate the OnChange user events + /// + /// Affected item + /// + /// New start time + /// New end time + /// Move, resize, etc + /// + /// + internal bool DoAppointmentViewChanging(CalendarItem calendarItem, string ownerKey, + DateTime startTime, DateTime endTime, eViewOperation viewOperation, bool isCopyDrag) + { + bool cancel = OnAppointmentViewChanging( + calendarItem, ownerKey, startTime, endTime, viewOperation, isCopyDrag); + + return (cancel); + } + + #endregion + + #region DoBeforeAppointmentViewChange + + /// + /// Routine to initiate the BeforeAppointmentViewChange event + /// + /// BaseView + /// Affected item + /// Move, resize, etc + /// + internal bool DoBeforeAppointmentViewChange(BaseView baseView, + CalendarItem calendarItem, eViewOperation viewOperation) + { + return (OnBeforeAppointmentViewChange(baseView, calendarItem, viewOperation)); + } + + #endregion + + #region OnBeforeAppointmentViewChange + + /// + /// OnBeforeAppointmentViewChange event propagation + /// + protected virtual bool OnBeforeAppointmentViewChange(BaseView baseView, + CalendarItem calendarItem, eViewOperation viewOperation) + { + if (BeforeAppointmentViewChange != null) + { + bool isCopyDrag = ((baseView.IsCopyDrag == false) && + (ModifierKeys & Keys.Control) == Keys.Control); + + BeforeAppointmentViewChangeEventArgs ev = new + BeforeAppointmentViewChangeEventArgs(calendarItem, viewOperation, isCopyDrag); + + BeforeAppointmentViewChange(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region OnAppointmentViewChanging + + /// + /// OnAppointmentViewChanging event propagation + /// + protected virtual bool OnAppointmentViewChanging(CalendarItem calendarItem, + string ownerKey, DateTime startTime, DateTime endTime, eViewOperation viewOperation, bool isCopyDrag) + { + if (AppointmentViewChanging != null) + { + AppointmentViewChangingEventArgs ev = new AppointmentViewChangingEventArgs( + calendarItem, ownerKey, startTime, endTime, viewOperation, isCopyDrag); + + AppointmentViewChanging(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoAppointmentViewChanged + + /// + /// DoAppointmentViewChanged event propagation + /// + internal virtual void DoAppointmentViewChanged(CalendarItem calendarItem, string oldOwnerKey, + DateTime oldStartTime, DateTime oldEndTime, eViewOperation viewOperation, bool isCopyDrag) + { + if (AppointmentViewChanged != null) + { + AppointmentViewChanged(this, new AppointmentViewChangedEventArgs( + calendarItem, oldOwnerKey, oldStartTime, oldEndTime, viewOperation, isCopyDrag)); + } + } + + #endregion + + #region DoGetDisplayTemplateText + + /// + /// DoGetDisplayTemplateText event propagation + /// + internal virtual int DoGetAppointmentGroupId( + CalendarItem calendarItem, int groupId) + { + if (GetAppointmentGroupId != null) + { + GetAppointmentGroupIdEventArgs e = + new GetAppointmentGroupIdEventArgs(calendarItem, groupId); + + GetAppointmentGroupId(this, e); + + return (e.GroupId); + } + + return (groupId); + } + + #endregion + + #region DoGetDisplayTemplateText + + /// + /// DoGetDisplayTemplateText event propagation + /// + internal virtual string DoGetDisplayTemplateText( + CalendarItem calendarItem, string displayTemplate, string displayText) + { + if (GetDisplayTemplateText != null) + { + GetDisplayTemplateTextEventArgs e = + new GetDisplayTemplateTextEventArgs(calendarItem, displayTemplate, displayText); + + GetDisplayTemplateText(this, e); + + return (e.DisplayText); + } + + return (displayText); + } + + #endregion + + #region DoAppointmentViewPreRender + + /// + /// Handles DoAppointmentViewPreRender events + /// + internal bool DoAppointmentViewPreRender( + CalendarItem calendarItem, Graphics g, Rectangle bounds, GraphicsPath path) + { + if (AppointmentViewPreRender != null) + { + AppointmentViewPreRenderEventArgs ev = new + AppointmentViewPreRenderEventArgs(calendarItem, g, bounds, path); + + AppointmentViewPreRender(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoAppointmentViewPostRender + + /// + /// Handles DoAppointmentViewPostRender events + /// + internal void DoAppointmentViewPostRender( + CalendarItem calendarItem, Graphics g, Rectangle bounds, GraphicsPath path) + { + if (AppointmentViewPostRender != null) + { + AppointmentViewPostRenderEventArgs ev = new + AppointmentViewPostRenderEventArgs(calendarItem, g, bounds, path); + + AppointmentViewPostRender(this, ev); + } + } + + #endregion + + #endregion + + #region DoViewDateChanged + + internal void DoViewDateChanged(BaseView view, + DateTime oldStartDate, DateTime oldEndDate, DateTime newStartDate, DateTime newEndDate) + { + if (ViewDateChanged != null) + { + ViewDateChangedEventArgs ev = new ViewDateChangedEventArgs( + view, oldStartDate, oldEndDate, newStartDate, newEndDate); + + ViewDateChanged(this, ev); + } + } + + #endregion + + #region DoViewDateChanging + + internal bool DoViewDateChanging(BaseView view, + DateTime oldStartDate, DateTime oldEndDate, ref DateTime newStartDate, ref DateTime newEndDate) + { + if (ViewDateChanging != null) + { + ViewDateChangingEventArgs ev = new ViewDateChangingEventArgs( + view, oldStartDate, oldEndDate, newStartDate, newEndDate); + + ViewDateChanging(this, ev); + + if (ev.Cancel == true) + return (true); + + newStartDate = ev.NewStartTime; + newEndDate = ev.NewEndTime; + } + + return (false); + } + + #endregion + + #region DoDetailSortEvent + + /// + /// DoDetailSortEvent + /// + internal void DoDetailSortEvent( + BaseView view, CalendarItem item1, CalendarItem item2, ref int result) + { + if (CalendarItemDetailSort != null) + { + CalendarItemEventArgs e = + new CalendarItemEventArgs(view, item1, item2); + + CalendarItemDetailSort(this, e); + + result = e.Result; + } + } + + #endregion + + #region DoTimeLineViewRenderPeriodHeader + + /// + /// Handles invocation of DoTimeLineViewRenderPeriodHeader event + /// + /// + /// + /// + /// + /// + /// + internal bool DoTimeLineViewRenderPeriodHeader(Graphics g, + DateTime startTime, DateTime endTime, Rectangle bounds, ref string text) + { + if (TimeLineRenderPeriodHeader != null) + { + TimeLineRenderPeriodHeaderEventArgs ev = new + TimeLineRenderPeriodHeaderEventArgs(g, startTime, endTime, bounds, text); + + TimeLineRenderPeriodHeader(this, ev); + + text = ev.Text; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoTimeLineViewPreRenderSlotBackground + + /// + /// Handles invocation of DoTimeLineViewPreRenderSlotBackground event + /// + /// + /// + /// + /// + /// + /// + /// + internal bool DoTimeLineViewPreRenderSlotBackground(Graphics g, BaseView view, + DateTime startTime, DateTime endTime, Rectangle bounds, ref eSlotDisplayState state) + { + if (TimeLinePreRenderSlotBackground != null) + { + TimeLinePreRenderSlotBackgroundEventArgs ev = new + TimeLinePreRenderSlotBackgroundEventArgs(g, view, startTime, endTime, bounds, state); + + TimeLinePreRenderSlotBackground(this, ev); + + state = ev.State; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoTimeLineViewPostRenderSlotBackground + + /// + /// Handles invocation of DoTimeLineViewPostRenderSlotBackground event + /// + /// + /// + /// + /// + /// + /// + /// + internal void DoTimeLineViewPostRenderSlotBackground(Graphics g, BaseView view, + DateTime startTime, DateTime endTime, Rectangle bounds, eSlotDisplayState state) + { + if (TimeLinePostRenderSlotBackground != null) + { + TimeLinePostRenderSlotBackgroundEventArgs ev = new + TimeLinePostRenderSlotBackgroundEventArgs(g, view, startTime, endTime, bounds, state); + + TimeLinePostRenderSlotBackground(this, ev); + } + } + + #endregion + + #region DoTimeLineViewRenderSlotBorder + + /// + /// DoTimeLineViewRenderSlotBorder + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + internal bool DoTimeLineViewRenderSlotBorder( + Graphics g, TimeLineView view, int col, bool hourly, + eSlotDisplayState state, Point pt1, Point pt2, Pen pen) + { + if (TimeLineRenderSlotBorder != null) + { + DateTime startTime = view.StartDate.AddMinutes(col * _BaseInterval); + + TimeLineRenderSlotBorderEventArgs ev = new + TimeLineRenderSlotBorderEventArgs(g, startTime, hourly, state, pt1, pt2, pen.Color); + + TimeLineRenderSlotBorder(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoTimeLineViewRenderViewBorder + + /// + /// DoTimeLineViewRenderViewBorder + /// + /// + /// + /// + /// + /// + /// + /// + internal bool DoTimeLineViewRenderViewBorder( + Graphics g, TimeLineView view, int startColumn, int endColumn, Rectangle bounds, Color color) + { + if (TimeLineRenderViewBorder != null) + { + TimeLineRenderViewBorderEventArgs ev = new + TimeLineRenderViewBorderEventArgs(g, startColumn, endColumn, bounds, color); + + TimeLineRenderViewBorder(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoTimeLineGetRowHeight + + /// + /// DoTimeLineGetRowHeight + /// + /// + internal void DoTimeLineGetRowHeight(TimeLineGetRowHeightEventArgs e) + { + if (TimeLineGetRowHeight != null) + TimeLineGetRowHeight(this, e); + } + + #endregion + + #region DoTimeLineGetRowCollateId + + /// + /// DoTimeLineGetRowCollateId + /// + /// + internal void DoTimeLineGetRowCollateId(TimeLineGetRowCollateIdEventArgs e) + { + if (TimeLineGetRowCollateId != null) + TimeLineGetRowCollateId(this, e); + } + + #endregion + + #region DoTimeLineGetHeaderText + + /// + /// DoTimeLineGetHeaderText + /// + /// + /// + /// + internal void DoTimeLineGetHeaderText( + TimeLineHeaderPanel header, DateTime date, ref string text) + { + if (TimeLineGetHeaderText != null) + { + TimeLineGetHeaderTextEventArgs e = + new TimeLineGetHeaderTextEventArgs(header, date, text); + + TimeLineGetHeaderText(this, e); + + text = e.Text; + } + } + + #endregion + + #region DoPageNavigatorClick + + /// + /// Handles invocation of PageNavigatorClick events + /// + /// + internal bool DoPageNavigatorClick(BaseView view, + PageNavigator pageNavigator, PageNavigatorButton button, ref DateTime navigateTime) + { + if (PageNavigatorClick != null) + { + PageNavigatorClickEventArgs ev = new + PageNavigatorClickEventArgs(view, pageNavigator, button, navigateTime); + + PageNavigatorClick(this, ev); + + navigateTime = ev.NavigateTime; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoYearViewLinkSelected + + /// + /// Handles invocation of DoYearViewLinkSelected event + /// + internal bool DoYearViewLinkSelected( + ref DateTime startDate, ref DateTime endDate, ref eCalendarView calendarView) + { + if (YearViewLinkSelected != null) + { + LinkViewSelectedEventArgs ev = new + LinkViewSelectedEventArgs(startDate, endDate, calendarView); + + YearViewLinkSelected(this, ev); + + startDate = ev.StartDate; + endDate = ev.EndDate; + calendarView = ev.ECalendarView; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoYearViewDrawDayBackground + + /// + /// Handles invocation of YearViewDrawDayBackground event + /// + internal bool DoYearViewDrawDayBackground(Graphics g, + YearMonth yearMonth, DateTime date, Rectangle bounds, ref eYearViewLinkStyle style) + { + if (YearViewDrawDayBackground != null) + { + YearViewDrawDayBackgroundEventArgs ev = new + YearViewDrawDayBackgroundEventArgs(g, yearMonth, date, bounds, style); + + YearViewDrawDayBackground(this, ev); + + style = ev.LinkStyle; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoYearViewDrawDayText + + /// + /// Handles invocation of YearViewDrawDayText event + /// + internal bool DoYearViewDrawDayText(Graphics g, + YearMonth yearMonth, DateTime date, Rectangle bounds) + { + if (YearViewDrawDayText != null) + { + YearViewDrawDayTextEventArgs ev = new + YearViewDrawDayTextEventArgs(g, yearMonth, date, bounds); + + YearViewDrawDayText(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoMonthViewPreRenderSlotBackground + + /// + /// Handles invocation of MonthViewPreRenderSlotBackground event + /// + /// + /// + /// + /// + /// + /// + /// + internal bool DoMonthViewPreRenderSlotBackground(Graphics g, BaseView view, + DateTime startTime, DateTime endTime, Rectangle bounds, ref eSlotDisplayState state) + { + if (MonthViewPreRenderSlotBackground != null) + { + MonthViewPreRenderSlotBackgroundEventArgs ev = new + MonthViewPreRenderSlotBackgroundEventArgs(g, view, startTime, endTime, bounds, state); + + MonthViewPreRenderSlotBackground(this, ev); + + state = ev.State; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoMonthViewPostRenderSlotBackground + + /// + /// Handles invocation of MonthViewPostRenderSlotBackground event + /// + /// + /// + /// + /// + /// + /// + /// + internal void DoMonthViewPostRenderSlotBackground(Graphics g, BaseView view, + DateTime startTime, DateTime endTime, Rectangle bounds, eSlotDisplayState state) + { + if (MonthViewPostRenderSlotBackground != null) + { + MonthViewPostRenderSlotBackgroundEventArgs ev = new + MonthViewPostRenderSlotBackgroundEventArgs(g, view, startTime, endTime, bounds, state); + + MonthViewPostRenderSlotBackground(this, ev); + } + } + + #endregion + + #region DoRenderDaySlotAppearanceText + + /// + /// Handles invocation of RenderDaySlotAppearanceText events + /// + internal bool DoRenderDaySlotAppearanceText(Graphics g, Rectangle bounds, + DaySlotAppearance appearance, DateTime startTime, DateTime endTime, bool selected, ref string text) + { + if (RenderDaySlotAppearanceText != null) + { + RenderDaySlotAppearanceTextEventArgs ev = new + RenderDaySlotAppearanceTextEventArgs(g, bounds, appearance, startTime, endTime, selected); + + RenderDaySlotAppearanceText(this, ev); + + text = ev.Text; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoRenderTabBackground + + /// + /// Handles invocation of RenderTabBackground event + /// + internal bool DoRenderTabBackground( + Graphics g, GraphicsPath path, BaseView view, bool isSelected) + { + if (RenderTabBackground != null) + { + RenderTabBackgroundEventArgs ev = new + RenderTabBackgroundEventArgs(g, path, view, isSelected); + + RenderTabBackground(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoRenderTabContent + + /// + /// Handles invocation of RenderTabContent events + /// + internal bool DoRenderTabContent(Graphics g, + GraphicsPath path, BaseView view, ref string text, bool isSelected) + { + if (RenderTabContent != null) + { + RenderTabContentEventArgs ev = new + RenderTabContentEventArgs(g, path, view, isSelected, text); + + RenderTabContent(this, ev); + + text = ev.Text; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoRenderViewBorder + + /// + /// DoRenderViewBorder + /// + /// + /// + /// + /// + internal bool DoRenderViewBorder( + Graphics g, BaseView view, Rectangle bounds) + { + if (RenderViewBorder != null) + { + RenderViewBorderEventArgs ev = new + RenderViewBorderEventArgs(g, bounds); + + RenderViewBorder(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoViewLoadComplete + + /// + /// Handles invocation of ViewLoadComplete events + /// + internal void DoViewLoadComplete(BaseView view) + { + if (ViewLoadComplete != null) + { + ViewLoadCompleteEventArgs ev = new + ViewLoadCompleteEventArgs(view); + + ViewLoadComplete(this, ev); + } + } + + #endregion + + #region DoMonthMoreItemsIndicatorClick + + /// + /// Handles invocation of MonthMoreItemsIndicatorClick events + /// + /// + internal bool DoMonthMoreItemsIndicatorClick( + BaseView view, ref eCalendarView selectView, ref DateTime startTime) + { + if (MonthMoreItemsIndicatorClick != null) + { + MonthMoreItemsIndicatorClickEventArgs ev = new + MonthMoreItemsIndicatorClickEventArgs(view, selectView, startTime); + + MonthMoreItemsIndicatorClick(this, ev); + + startTime = ev.StartTime; + selectView = ev.SelectView; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoPreRenderWeekDaySlotBackground + + internal bool DoPreRenderWeekDaySlotBackground( + Graphics g, WeekDayView view, int dayColumnIndex, int daySliceIndex, Rectangle bounds) + { + if (PreRenderWeekDaySlotBackground != null) + { + PreRenderWeekDaySlotBackgroundEventArgs ev = new + PreRenderWeekDaySlotBackgroundEventArgs(g, view, dayColumnIndex, daySliceIndex, bounds); + + PreRenderWeekDaySlotBackground(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoPostRenderWeekDaySlotBackground + + internal void DoPostRenderWeekDaySlotBackground( + Graphics g, WeekDayView view, int dayColumnIndex, int daySliceIndex, Rectangle bounds) + { + if (PostRenderWeekDaySlotBackground != null) + { + PostRenderWeekDaySlotBackgroundEventArgs ev = new + PostRenderWeekDaySlotBackgroundEventArgs(g, view, dayColumnIndex, daySliceIndex, bounds); + + PostRenderWeekDaySlotBackground(this, ev); + } + } + + #endregion + + #region DoPreRenderWeekDayHeader + + internal bool DoPreRenderWeekDayHeader( + Graphics g, WeekDayView view, int colIndex, Rectangle bounds) + { + if (PreRenderWeekDayHeader != null) + { + PreRenderWeekDayHeaderEventArgs ev = new + PreRenderWeekDayHeaderEventArgs(g, view, colIndex, bounds); + + PreRenderWeekDayHeader(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoPostRenderWeekDayHeader + + internal void DoPostRenderWeekDayHeader( + Graphics g, WeekDayView view, int colIndex, Rectangle bounds) + { + if (PostRenderWeekDayHeader != null) + { + PostRenderWeekDayHeaderEventArgs ev = new + PostRenderWeekDayHeaderEventArgs(g, view, colIndex, bounds); + + PostRenderWeekDayHeader(this, ev); + } + } + + #endregion + + #region DoPreRenderMonthHeader + + internal bool DoPreRenderMonthHeader( + Graphics g, MonthView view, int colIndex, Rectangle bounds) + { + if (PreRenderMonthHeader != null) + { + PreRenderMonthHeaderEventArgs ev = new + PreRenderMonthHeaderEventArgs(g, view, colIndex, bounds); + + PreRenderMonthHeader(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DoPostRenderMonthHeader + + internal void DoPostRenderMonthHeader( + Graphics g, MonthView view, int colIndex, Rectangle bounds) + { + if (PostRenderMonthHeader != null) + { + PostRenderMonthHeaderEventArgs ev = new + PostRenderMonthHeaderEventArgs(g, view, colIndex, bounds); + + PostRenderMonthHeader(this, ev); + } + } + + #endregion + + #region DisplayedsOwner support + + #region DisplayedOwnersAdded + + /// + /// This routine is called after an element has been + /// added to the DisplayedOwners list. It is responsible + /// for updating the MultiCalendar views accordingly. + /// + internal void DisplayedOwnersAdded(int index) + { + if (_MultiCalendarDayViews == null) + { + _MultiCalendarDayViews = new CalendarViewCollection(this); + _MultiCalendarWeekViews = new CalendarViewCollection(this); + _MultiCalendarMonthViews = new CalendarViewCollection(this); + _MultiCalendarYearViews = new CalendarViewCollection(this); + _MultiCalendarTimeLineViews = new CalendarViewCollection(this); + + // No need to keep the single-user views + // while we are in multi-user mode + + DayView = null; + WeekView = null; + MonthView = null; + YearView = null; + TimeLineView = null; + + SelectedOwnerIndex = 0; + } + + // Are we appending, or inserting? + + if (index == _MultiCalendarDayViews.Count) + { + // Loop through all newly added DisplayOwners, creating + // corresponding Day, Week, and Month views for each one + + for (int i = _MultiCalendarDayViews.Count; i < _DisplayedOwners.Count; i++) + { + _MultiCalendarDayViews.Views.Add(null); + _MultiCalendarWeekViews.Views.Add(null); + _MultiCalendarMonthViews.Views.Add(null); + _MultiCalendarYearViews.Views.Add(null); + _MultiCalendarTimeLineViews.Views.Add(null); + } + } + else + { + // Add the new view to the end of the list and + // then reorder the lists to reflect the change + + _MultiCalendarDayViews.Views.Add(null); + _MultiCalendarWeekViews.Views.Add(null); + _MultiCalendarMonthViews.Views.Add(null); + _MultiCalendarYearViews.Views.Add(null); + _MultiCalendarTimeLineViews.Views.Add(null); + + ReorderDayViews(_DisplayedOwners.Count - 1, index); + ReorderWeekViews(_DisplayedOwners.Count - 1, index); + ReorderMonthViews(_DisplayedOwners.Count - 1, index); + ReorderYearViews(_DisplayedOwners.Count - 1, index); + ReorderTimeLineViews(_DisplayedOwners.Count - 1, index); + } + + // Reflect the changes to the display + + SetSelectedView(SelectedView); + + // Tell the user things changed + + OnDisplayedOwnersChanged(); + } + + #endregion + + #region DisplayedOwnersRemoved + + /// + /// This routine is called after an element has been + /// removed from the DisplayedOwners list. It is responsible + /// for updating the MultiCalendar views accordingly. + /// + /// Starting index to remove + /// Ending index to remove + internal void DisplayedOwnersRemoved(int start, int end) + { + // Remove each view individually + + for (int i = end - 1; i >= start; i--) + RemoveView(i); + + // If all multi-user entries have been removed + // then revert back to single-user mode + + if (_MultiCalendarDayViews == null || _MultiCalendarDayViews.Count == 0) + { + _MultiCalendarDayViews = null; + _MultiCalendarWeekViews = null; + _MultiCalendarMonthViews = null; + _MultiCalendarYearViews = null; + _MultiCalendarTimeLineViews = null; + } + + // Reflect the changes to the user + + int n = _SelectedOwnerIndex; + + if (n >= _DisplayedOwners.Count) + n = _DisplayedOwners.Count - 1; + + _SelectedOwnerIndex = -1; + SelectedOwnerIndex = n; + + SetSelectedView(_SelectedView); + + // Tell the user things changed + + OnDisplayedOwnersChanged(); + } + + /// + /// Removes individual views + /// + /// Index to remove + private void RemoveView(int index) + { + // Day views + + if (_MultiCalendarDayViews.Views[index] != null) + _MultiCalendarDayViews.Views[index].Dispose(); + + _MultiCalendarDayViews.Views.RemoveAt(index); + + for (int i = index; i < _MultiCalendarDayViews.Views.Count; i++) + { + if (_MultiCalendarDayViews.Views[i] != null) + _MultiCalendarDayViews.Views[i].DisplayedOwnerKeyIndex = i; + } + + // Week views + + if (_MultiCalendarWeekViews.Views[index] != null) + _MultiCalendarWeekViews.Views[index].Dispose(); + + _MultiCalendarWeekViews.Views.RemoveAt(index); + + for (int i = index; i < _MultiCalendarWeekViews.Views.Count; i++) + { + if (_MultiCalendarWeekViews.Views[i] != null) + _MultiCalendarWeekViews.Views[i].DisplayedOwnerKeyIndex = i; + } + + // Month views + + if (_MultiCalendarMonthViews.Views[index] != null) + _MultiCalendarMonthViews.Views[index].Dispose(); + + _MultiCalendarMonthViews.Views.RemoveAt(index); + + for (int i = index; i < _MultiCalendarMonthViews.Views.Count; i++) + { + if (_MultiCalendarMonthViews.Views[i] != null) + _MultiCalendarMonthViews.Views[i].DisplayedOwnerKeyIndex = i; + } + + // Year views + + if (_MultiCalendarYearViews.Views[index] != null) + _MultiCalendarYearViews.Views[index].Dispose(); + + _MultiCalendarYearViews.Views.RemoveAt(index); + + for (int i = index; i < _MultiCalendarYearViews.Views.Count; i++) + { + if (_MultiCalendarYearViews.Views[i] != null) + _MultiCalendarYearViews.Views[i].DisplayedOwnerKeyIndex = i; + } + + // TimeLine views + + if (_MultiCalendarTimeLineViews.Views[index] != null) + _MultiCalendarTimeLineViews.Views[index].Dispose(); + + _MultiCalendarTimeLineViews.Views.RemoveAt(index); + + for (int i = index; i < _MultiCalendarTimeLineViews.Views.Count; i++) + { + if (_MultiCalendarTimeLineViews.Views[i] != null) + _MultiCalendarTimeLineViews.Views[i].DisplayedOwnerKeyIndex = i; + } + } + + #endregion + + #region DisplayedOwnersSet + + /// + /// This routine is called after an element has been + /// reset in the DisplayedOwners list. It is responsible + /// for updating the MultiCalendar views accordingly. + /// + /// + internal void DisplayedOwnersSet(int index) + { + // Day view + + if (_MultiCalendarDayViews.Views[index] != null) + SetView(_MultiCalendarDayViews.Views[index], index); + + // Week view + + if (_MultiCalendarWeekViews.Views[index] != null) + SetView(_MultiCalendarWeekViews.Views[index], index); + + // Month view + + if (_MultiCalendarMonthViews.Views[index] != null) + SetView(_MultiCalendarMonthViews.Views[index], index); + + // Year view + + if (_MultiCalendarYearViews.Views[index] != null) + SetView(_MultiCalendarYearViews.Views[index], index); + + // TimeLine view + + if (_MultiCalendarTimeLineViews.Views[index] != null) + SetView(_MultiCalendarTimeLineViews.Views[index], index); + + if (SelectedOwnerIndex == index) + { + _SelectedOwnerIndex = -1; + + SelectedOwnerIndex = index; + } + + // Tell the user things changed + + OnDisplayedOwnersChanged(); + } + + #endregion + + #region GetViewIndexFromPoint + + /// + /// Gets the view index from a given Point + /// + /// Point + /// + internal int GetViewIndexFromPoint(Point pt) + { + if (IsMultiCalendar == true) + { + switch (SelectedView) + { + case eCalendarView.Day: + for (int i = 0; i < MultiCalendarDayViews.Count; i++) + { + if (MultiCalendarDayViews.Views[i].Bounds.Contains(pt)) + return (i); + } + break; + + case eCalendarView.Week: + for (int i = 0; i < MultiCalendarWeekViews.Count; i++) + { + if (MultiCalendarWeekViews.Views[i].Bounds.Contains(pt)) + return (i); + } + break; + + case eCalendarView.Month: + for (int i = 0; i < MultiCalendarMonthViews.Count; i++) + { + if (MultiCalendarMonthViews.Views[i].Bounds.Contains(pt)) + return (i); + } + break; + + case eCalendarView.Year: + for (int i = 0; i < MultiCalendarYearViews.Count; i++) + { + if (MultiCalendarYearViews.Views[i].Bounds.Contains(pt)) + return (i); + } + break; + + case eCalendarView.TimeLine: + for (int i = 0; i < MultiCalendarTimeLineViews.Count; i++) + { + if (MultiCalendarTimeLineViews.Views[i].Bounds.Contains(pt)) + return (i); + } + break; + } + } + + return (-1); + } + + #endregion + + #region ReorderViews + + #region ReorderViews + + /// + /// Reorders views in the MultiCalendar and + /// DisplayOwner arrays + /// + /// Starting index + /// Ending index + internal void ReorderViews(int startIndex, int endIndex) + { + if (IsMultiCalendar == true && startIndex != endIndex) + { + try + { + DisplayedOwners.SuspendUpdate = true; + + ReorderDayViews(startIndex, endIndex); + ReorderWeekViews(startIndex, endIndex); + ReorderMonthViews(startIndex, endIndex); + ReorderYearViews(startIndex, endIndex); + ReorderTimeLineViews(startIndex, endIndex); + + ReorderDisplayedOwners(startIndex, endIndex); + } + finally + { + DisplayedOwners.SuspendUpdate = false; + } + + SelectedOwnerIndex = endIndex; + SetSelectedView(SelectedView); + + // Tell the user things changed + + OnDisplayedOwnersChanged(); + } + } + + /// + /// SelectedViewChanged event propagation + /// + protected virtual void OnDisplayedOwnersChanged() + { + if (DisplayedOwnersChanged != null) + DisplayedOwnersChanged(this, EventArgs.Empty); + } + + #endregion + + #region ReorderDayViews + + /// + /// Reorders Day view in the MultiCalendar and + /// DisplayOwner arrays + /// + /// Starting index + /// Ending index + private void ReorderDayViews(int startIndex, int endIndex) + { + DayView dayView = MultiCalendarDayViews.Views[startIndex]; + + int n = (startIndex > endIndex) ? -1 : 1; + + while (startIndex != endIndex) + { + MultiCalendarDayViews.Views[startIndex] = MultiCalendarDayViews.Views[startIndex + n]; + + if (MultiCalendarDayViews.Views[startIndex] != null) + MultiCalendarDayViews.Views[startIndex].DisplayedOwnerKeyIndex = startIndex; + + startIndex += n; + } + + MultiCalendarDayViews.Views[endIndex] = dayView; + + if (dayView != null) + dayView.DisplayedOwnerKeyIndex = endIndex; + } + + #endregion + + #region ReorderWeekViews + + /// + /// Reorders Week view in the MultiCalendar and + /// DisplayOwner arrays + /// + /// Starting index + /// Ending index + private void ReorderWeekViews(int startIndex, int endIndex) + { + WeekView weekView = MultiCalendarWeekViews.Views[startIndex]; + + int n = (startIndex > endIndex) ? -1 : 1; + + while (startIndex != endIndex) + { + MultiCalendarWeekViews.Views[startIndex] = MultiCalendarWeekViews.Views[startIndex + n]; + + if (MultiCalendarWeekViews.Views[startIndex] != null) + MultiCalendarWeekViews.Views[startIndex].DisplayedOwnerKeyIndex = startIndex; + + startIndex += n; + } + + MultiCalendarWeekViews.Views[endIndex] = weekView; + + if (weekView != null) + weekView.DisplayedOwnerKeyIndex = endIndex; + } + + #endregion + + #region ReorderMonthViews + + /// + /// Reorders Month view in the MultiCalendar and + /// DisplayOwner arrays + /// + /// Starting index + /// Ending index + private void ReorderMonthViews(int startIndex, int endIndex) + { + MonthView monthView = MultiCalendarMonthViews.Views[startIndex]; + + int n = (startIndex > endIndex) ? -1 : 1; + + while (startIndex != endIndex) + { + MultiCalendarMonthViews.Views[startIndex] = MultiCalendarMonthViews.Views[startIndex + n]; + + if (MultiCalendarMonthViews.Views[startIndex] != null) + MultiCalendarMonthViews.Views[startIndex].DisplayedOwnerKeyIndex = startIndex; + + startIndex += n; + } + + MultiCalendarMonthViews.Views[endIndex] = monthView; + + if (monthView != null) + monthView.DisplayedOwnerKeyIndex = endIndex; + } + + #endregion + + #region ReorderYearViews + + /// + /// Reorders Year view in the MultiCalendar and + /// DisplayOwner arrays + /// + /// Starting index + /// Ending index + private void ReorderYearViews(int startIndex, int endIndex) + { + YearView yearView = MultiCalendarYearViews.Views[startIndex]; + + int n = (startIndex > endIndex) ? -1 : 1; + + while (startIndex != endIndex) + { + MultiCalendarYearViews.Views[startIndex] = MultiCalendarYearViews.Views[startIndex + n]; + + if (MultiCalendarYearViews.Views[startIndex] != null) + MultiCalendarYearViews.Views[startIndex].DisplayedOwnerKeyIndex = startIndex; + + startIndex += n; + } + + MultiCalendarYearViews.Views[endIndex] = yearView; + + if (yearView != null) + yearView.DisplayedOwnerKeyIndex = endIndex; + } + + #endregion + + #region ReorderTimeLineViews + + /// + /// Reorders TimeLine view in the MultiCalendar and + /// DisplayOwner arrays + /// + /// Starting index + /// Ending index + private void ReorderTimeLineViews(int startIndex, int endIndex) + { + TimeLineView timeView = MultiCalendarTimeLineViews.Views[startIndex]; + + int n = (startIndex > endIndex) ? -1 : 1; + + while (startIndex != endIndex) + { + MultiCalendarTimeLineViews.Views[startIndex] = + MultiCalendarTimeLineViews.Views[startIndex + n]; + + if (MultiCalendarTimeLineViews.Views[startIndex] != null) + MultiCalendarTimeLineViews.Views[startIndex].DisplayedOwnerKeyIndex = startIndex; + + startIndex += n; + } + + MultiCalendarTimeLineViews.Views[endIndex] = timeView; + + if (timeView != null) + timeView.DisplayedOwnerKeyIndex = endIndex; + } + + #endregion + + #region ReorderDisplayedOwners + + /// + /// Reorders the DisplayedOwner list + /// + /// Starting index + /// Ending index + private void ReorderDisplayedOwners(int startIndex, int endIndex) + { + string owner = DisplayedOwners[startIndex]; + + int n = (startIndex > endIndex) ? -1 : 1; + + while (startIndex != endIndex) + { + DisplayedOwners[startIndex] = DisplayedOwners[startIndex + n]; + startIndex += n; + } + + DisplayedOwners[endIndex] = owner; + } + + #endregion + + #endregion + + #endregion + + #region NewView + + /// + /// Creates a new calendar base view of + /// the given type + /// + /// Type of view to create + /// DisplayedOwner index + /// Created view + internal object NewView(Type type, int index) + { + if (type == typeof(DayView)) + return (NewDayView(index)); + + if (type == typeof(WeekView)) + return (NewWeekView(index)); + + if (type == typeof(MonthView)) + return (NewMonthView(index)); + + if (type == typeof(YearView)) + return (NewYearView(index)); + + return (NewTimeLineView(index)); + } + + /// + /// Creates new DayViews + /// + /// DisplayedOwner index + /// Created DayView + private DayView NewDayView(int index) + { + DayView dv = new DayView(this); + + dv.StartDate = _DayViewDate; + dv.EndDate = _DayViewDate; + + SetView(dv, index); + + return (dv); + } + + /// + /// Creates new WeekViews + /// + /// DisplayedOwner index + /// Created WeekView + private WeekView NewWeekView(int index) + { + WeekView wv = new WeekView(this); + + wv.StartDate = _WeekViewStartDate; + wv.EndDate = _WeekViewEndDate; + + SetView(wv, index); + + return (wv); + } + + /// + /// Creates new MonthViews + /// + /// DisplayedOwner index + /// Created MonthView + private MonthView NewMonthView(int index) + { + MonthView mv = new MonthView(this); + + mv.StartDate = _MonthViewStartDate; + mv.EndDate = _MonthViewEndDate; + + mv.IsSideBarVisible = _IsMonthSideBarVisible; + + SetView(mv, index); + + return (mv); + } + + /// + /// Creates new YearView + /// + /// DisplayedOwner index + /// Created YearView + private YearView NewYearView(int index) + { + YearView yv = new YearView(this); + + yv.StartDate = _YearViewStartDate; + yv.EndDate = _YearViewEndDate; + + SetView(yv, index); + + return (yv); + } + + /// + /// Creates new TimeLineViews + /// + /// DisplayedOwner index + /// Created WeekView + private TimeLineView NewTimeLineView(int index) + { + TimeLineView tv = new TimeLineView(this, eCalendarView.TimeLine); + + tv.StartDate = _TimeLineViewStartDate; + tv.EndDate = _TimeLineViewEndDate; + + SetView(tv, index); + + return (tv); + } + + #endregion + + #region SetView + + /// + /// Completes the setup of the created view + /// + /// Newly created view + /// DisplayedOwner index + private void SetView(BaseView view, int index) + { + view.DisplayedOwnerKeyIndex = index; + view.OwnerKey = _DisplayedOwners[index]; + + // Check to see it the CalendarModel has + // any new info to give us for this view + + Owner owner = _CalendarModel.Owners[view.OwnerKey]; + + if (owner != null) + { + view.DisplayName = owner.DisplayName; + view.CalendarColor = owner.ColorScheme; + } + else + { + view.DisplayName = view.OwnerKey; + view.CalendarColor = GetViewColor(view, index); + } + + // View is all setup, let it know it + // needs to recalculate it's entire layout + + view.ResetView(); + view.NeedRecalcLayout = true; + } + + /// + /// Gets the default eCalendarColor for the view + /// + /// View in question + /// Index of view + /// View color + private eCalendarColor GetViewColor(BaseView view, int index) + { + if (IsMultiCalendar == true) + { + BaseView bv = MultiCalendarDayViews.Views[index]; + + if (bv != null && bv != view) + return (bv.CalendarColor); + + bv = MultiCalendarWeekViews.Views[index]; + + if (bv != null && bv != view) + return (bv.CalendarColor); + + bv = MultiCalendarMonthViews.Views[index]; + + if (bv != null && bv != view) + return (bv.CalendarColor); + + bv = MultiCalendarYearViews.Views[index]; + + if (bv != null && bv != view) + return (bv.CalendarColor); + + bv = MultiCalendarTimeLineViews.Views[index]; + + if (bv != null && bv != view) + return (bv.CalendarColor); + } + else + { + if (_DayView != null && view != _DayView) + return (_DayView.CalendarColor); + + if (_WeekView != null && view != _WeekView) + return (_WeekView.CalendarColor); + + if (_MonthView != null && view != _MonthView) + return (_MonthView.CalendarColor); + + if (_YearView != null && view != _YearView) + return (_YearView.CalendarColor); + + if (_TimeLineView != null && view != _TimeLineView) + return (_TimeLineView.CalendarColor); + } + + return (DefaultCalendarColor); + } + + #endregion + + #region UpdateAltViewCalendarColor + + /// + /// Updates all view CalendarColor settings + /// + /// New color + /// Multi-user index + internal void UpdateAltViewCalendarColor(eCalendarColor color, int index) + { + if (IsMultiCalendar == true) + { + if (MultiCalendarDayViews.Views[index] != null) + MultiCalendarDayViews.Views[index].CalendarColor = color; + + if (MultiCalendarWeekViews.Views[index] != null) + MultiCalendarWeekViews.Views[index].CalendarColor = color; + + if (MultiCalendarMonthViews.Views[index] != null) + MultiCalendarMonthViews.Views[index].CalendarColor = color; + + if (MultiCalendarYearViews.Views[index] != null) + MultiCalendarYearViews.Views[index].CalendarColor = color; + + if (MultiCalendarTimeLineViews.Views[index] != null) + MultiCalendarTimeLineViews.Views[index].CalendarColor = color; + } + else + { + if (_DayView != null) + _DayView.CalendarColor = color; + + if (_WeekView != null) + _WeekView.CalendarColor = color; + + if (_MonthView != null) + _MonthView.CalendarColor = color; + + if (_YearView != null) + _YearView.CalendarColor = color; + + if (_TimeLineView != null) + _TimeLineView.CalendarColor = color; + } + } + + #endregion + + #region OnMousewheel support + + /// + /// Mouse Wheel support + /// + /// Window handle + /// wParam + /// lParam + /// false + protected override bool OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam) + { + Rectangle r = this.DisplayRectangle; + r.Location = this.PointToScreen(r.Location); + + Point mousePos = MousePosition; + + if (r.Contains(mousePos)) + { + IntPtr handle = WinApi.WindowFromPoint(new WinApi.POINT(mousePos)); + Control c = FromChildHandle(handle) ?? FromHandle(handle); + + if (c is CalendarView) + { + short detents = (short)WinApi.HIWORD(wParam); + + int delta = (detents / SystemInformation.MouseWheelScrollDelta); + MouseWheelHandler(delta); + return true; + } + } + + return (false); + } + private void MouseWheelHandler(int delta) + { + int value = -(delta * SystemInformation.MouseWheelScrollLines); + + switch (SelectedView) + { + case eCalendarView.Week: + case eCalendarView.Day: + value *= (int)TimeSliceHeight; + value += _WeekDayVScrollPanel.ScrollBar.Value; + + value = Math.Max(value, 0); + value = Math.Min(value, _WeekDayVScrollPanel.ScrollBar.Maximum); + + _WeekDayVScrollPanel.ScrollBar.Value = value; + break; + + case eCalendarView.Year: + if (_YearVScrollPanel.Visible == true) + { + value *= 10; + value += _YearVScrollPanel.ScrollBar.Value; + + value = Math.Max(value, 0); + value = Math.Min(value, _YearVScrollPanel.ScrollBar.Maximum); + + _YearVScrollPanel.ScrollBar.Value = value; + } + break; + + case eCalendarView.TimeLine: + if (CalendarPanel.VScrollBar != null && CalendarPanel.VScrollBar.Visible) + { + value = -delta * TimeLineHeight; + value += CalendarPanel.VScrollBar.Value; + + value = Math.Max(value, 0); + value = Math.Min(value, CalendarPanel.VScrollBar.Maximum); + + CalendarPanel.VScrollBar.Value = value; + } + break; + } + } + protected override void OnMouseWheel(MouseEventArgs e) + { + MouseWheelHandler(e.Delta / SystemInformation.MouseWheelScrollDelta); + base.OnMouseWheel(e); + } + #endregion + + #region OnMouseDown support + + /// + /// OnMouseDown + /// + /// + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + this.Focus(); + } + + #endregion + + #region ProcessCmdKey + + /// + /// Processes KeyDown events + /// + /// + /// + /// + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + BaseView view = GetSelectedView(); + + if (view != null) + { + KeyEventArgs args = new KeyEventArgs(keyData); + + view.InternalKeyDown(args); + + if (args.Handled == true) + return (true); + } + + return (base.ProcessCmdKey(ref msg, keyData)); + } + + protected override void OnKeyUp(KeyEventArgs e) + { + base.OnKeyUp(e); + + BaseView view = GetSelectedView(); + + if (view != null) + view.InternalKeyUp(e); + } + + #endregion + + #region OnResize handling + + /// + /// Control resize processing + /// + /// + protected override void OnResize(EventArgs e) + { + _CalendarPanel.Bounds = this.ClientRectangle; + + _CalendarPanel.RecalcSize(); + _CalendarPanel.Refresh(); + + base.OnResize(e); + } + + #endregion + + #region OnCursorChanged + + /// + /// OnCursorChanged + /// + /// + protected override void OnCursorChanged(EventArgs e) + { + base.OnCursorChanged(e); + + if (_SetCursor == false) + _DefaultViewCursor = Cursor; + } + + #endregion + + #region Refresh + + public override void Refresh() + { + if (IsUpdateSuspended == false) + base.Refresh(); + } + + #endregion + + #region Trial Version + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); +#if TRIAL + Graphics g = e.Graphics; + using (Font font = new Font(this.Font.FontFamily, 14, FontStyle.Bold)) + { + using (SolidBrush brush = new SolidBrush(Color.FromArgb(40, Color.Black))) + g.DrawString("DotNetBar Trial", font, brush, (this.ClientRectangle.Width - 64) / 2, this.ClientRectangle.Height - font.SizeInPoints - 14); + } +#endif + } + #endregion + + protected override void Dispose(bool disposing) + { + if (_TimeIndicator != null) + { + _TimeIndicator.Dispose(); + + _TimeIndicator = null; + } + + if (_TimeIndicators != null) + { + _TimeIndicators.TimeIndicatorCollectionChanged -= TimeIndicatorsTimeIndicatorCollectionChanged; + _TimeIndicators.TimeIndicatorTimeChanged -= TimeIndicatorsTimeIndicatorTimeChanged; + _TimeIndicators.TimeIndicatorColorChanged -= TimeIndicatorsTimeIndicatorColorChanged; + + _TimeIndicators.Dispose(); + + _TimeIndicators = null; + } + + ReleaseTimeLineHScrollPanel(); + + // Dispose of our fonts + + TimeRulerFont = null; + TimeRulerFontSm = null; + + base.Dispose(disposing); + } + } + + #region enums + + #region eViewOperation + + /// + /// Defines the available view operations + /// + public enum eViewOperation + { + AppointmentMove, // Appointment move + AppointmentResize // Appointment resize + } + + #endregion + + #region eCalendarView + + /// + /// Defines views available on CalendarView control. + /// + public enum eCalendarView + { + Day, + Week, + Month, + Year, + TimeLine, + + None + } + + #endregion + + #region eTimeLinePeriod + + /// + /// Defines TimeLine interval period + /// + public enum eTimeLinePeriod + { + Minutes, + Hours, + Days, + Years + } + + #endregion + + #region TimeLineStretchRowHeightMode + + /// + /// Defines TimeLine interval period + /// + public enum TimeLineStretchRowHeightMode + { + /// + /// Row height is partially stretched, based upon the + /// number of overlapping rows. + /// + Partial, + + /// + /// Row height is extended fully (if possible), irrespective of the + /// number of overlapping rows. + /// + Full + } + + #endregion + + #region eCondensedViewVisibility + + /// + /// Defines Condensed View visibility + /// + public enum eCondensedViewVisibility + { + AllResources, + SelectedResource, + Hidden + } + + #endregion + + #region eYearViewDayLink + + /// + /// Defines link mode for YearView dates containing appointments + /// + [Flags] + public enum eYearViewDayLink + { + None = 0, + + Click = 1 << 0, + CtrlClick = 1 << 1, + DoubleClick = 1 << 2 + } + + #endregion + + #region eYearViewLinkAction + + /// + /// Defines link action for YearView dates containing Appointments or CalendarItems + /// + public enum eYearViewLinkAction + { + GoToDate, + GoToFirstCalendarItem, + } + + #endregion + + #region eYearViewLinkStyle + + /// + /// Defines link mode for YearView dates containing appointments + /// + public enum eYearViewLinkStyle + { + None, + + Style1, + Style2, + Style3, + Style4, + Style5 + } + + #endregion + + #region eSlotDisplayState + + /// + /// Defines the "display state" (work, inactive, selected) of the slot + /// + [Flags] + public enum eSlotDisplayState + { + None = 0, + + Work = (1 << 0), + Selected = (1 << 2) + } + + #endregion + + #region eAllDayDisplayMode + + /// + /// Defines how All "All Day" appointments are displayed + /// + public enum eAllDayDisplayMode + { + None, // AllDay area will not be displayed. + + ByDayBoundary, // AllDay items displayed by day boundary (default). + ByDayPeriod // AllDay items displayed by 24 hr day period. + } + + #endregion + + #endregion + + #region EventArgs + + #region ValueChangedEventArgs + + /// + /// Generic ValueChangedEventArgs + /// + /// oldValue type + /// newValue type + public class ValueChangedEventArgs : EventArgs + { + #region Private variables + + private T1 _OldValue; + private T2 _NewValue; + + #endregion + + public ValueChangedEventArgs(T1 oldValue, T2 newValue) + { + _OldValue = oldValue; + _NewValue = newValue; + } + + #region Public properties + + /// + /// Gets the old value + /// + public T1 OldValue + { + get { return (_OldValue); } + } + + /// + /// Gets the new value + /// + public T2 NewValue + { + get { return (_NewValue); } + } + + #endregion + } + + #endregion + + #region SelectedViewEventArgs + /// + /// SelectedViewEventArgs + /// + public class SelectedViewEventArgs : ValueChangedEventArgs + { + public SelectedViewEventArgs(eCalendarView oldValue, eCalendarView newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region ModelEventArgs + /// + /// ModelEventArgs + /// + public class ModelEventArgs : ValueChangedEventArgs + { + public ModelEventArgs(CalendarModel oldValue, CalendarModel newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region DateSelectionEventArgs + /// + /// DateSelectionEventArgs + /// + public class DateSelectionEventArgs : ValueChangedEventArgs + { + public DateSelectionEventArgs(DateTime? oldValue, DateTime? newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region LabelTimeSlotsChangedEventArgs + /// + /// LabelTimeSlotsChangedEventArgs + /// + public class LabelTimeSlotsChangedEventArgs : ValueChangedEventArgs + { + public LabelTimeSlotsChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeSlotDurationChangedEventArgs + /// + /// TimeSlotDurationChangedEventArgs + /// + public class TimeSlotDurationChangedEventArgs : ValueChangedEventArgs + { + public TimeSlotDurationChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region Is24HourFormatChangedEventArgs + /// + /// Is24HourFormatChangedEventArgs + /// + public class Is24HourFormatChangedEventArgs : ValueChangedEventArgs + { + public Is24HourFormatChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region IsMonthSideBarVisibleChangedEventArgs + /// + /// IsMonthSideBarVisibleChangedEventArgs + /// + public class IsMonthSideBarVisibleChangedEventArgs : ValueChangedEventArgs + { + public IsMonthSideBarVisibleChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region IsMonthMoreItemsIndicatorVisibleChangedEventArgs + /// + /// IsMonthMoreItemsIndicatorVisibleChangedEventArgs + /// + public class IsMonthMoreItemsIndicatorVisibleChangedEventArgs : ValueChangedEventArgs + { + public IsMonthMoreItemsIndicatorVisibleChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region IsTimeRulerVisibleChangedEventArgs + /// + /// IsTimeRulerVisibleChangedEventArgs + /// + public class IsTimeRulerVisibleChangedEventArgs : ValueChangedEventArgs + { + public IsTimeRulerVisibleChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region BeforeAppointmentViewChangeEventArgs + /// + /// BeforeAppointmentViewChangeEventArgs + /// + public class BeforeAppointmentViewChangeEventArgs : CancelEventArgs + { + #region Private variables + + private CalendarItem _CalendarItem; + private eViewOperation _eViewOperation; + private bool _IsCopyDrag; + + #endregion + + public BeforeAppointmentViewChangeEventArgs( + CalendarItem calendarItem, eViewOperation eViewOperation, bool isCopyDrag) + { + _CalendarItem = calendarItem; + _eViewOperation = eViewOperation; + _IsCopyDrag = isCopyDrag; + } + + #region Public properties + + /// + /// Gets the CalendarItem being affected + /// + public CalendarItem CalendarItem + { + get { return (_CalendarItem); } + } + + /// + /// Gets the operation to be performed + /// + public eViewOperation eViewOperation + { + get { return (_eViewOperation); } + } + + /// + /// Gets whether the operation is being + /// performed on a drag created copy item + /// + public bool IsCopyDrag + { + get { return (_IsCopyDrag); } + } + + #endregion + } + #endregion + + #region AppointmentViewChangingEventArgs + /// + /// AppointmentViewChangingEventArgs + /// + public class AppointmentViewChangingEventArgs : CancelEventArgs + { + #region Private variables + + private CalendarItem _CalendarItem; + + private string _OwnerKey; + private DateTime _StartTime; + private DateTime _EndTime; + + private eViewOperation _eViewOperation; + private bool _IsCopyDrag; + + #endregion + + public AppointmentViewChangingEventArgs(CalendarItem calendarItem, string ownerKey, + DateTime startTime, DateTime endTime, eViewOperation eViewOperation, bool isCopyDrag) + { + _CalendarItem = calendarItem; + + _OwnerKey = ownerKey; + _StartTime = startTime; + _EndTime = endTime; + + _eViewOperation = eViewOperation; + _IsCopyDrag = isCopyDrag; + } + + #region Public properties + + /// + /// Gets the CalendarItem being changed + /// + public CalendarItem CalendarItem + { + get { return (_CalendarItem); } + } + + /// + /// Gets the OwnerKey to be applied. + /// This value will be null if no new OwnerKey is to be applied. + /// + public string OwnerKey + { + get { return (_OwnerKey); } + } + + /// + /// Gets the new StartTime to be applied + /// + public DateTime StartTime + { + get { return (_StartTime); } + } + + /// + /// Gets the new EndTime to be applied + /// + public DateTime EndTime + { + get { return (_EndTime); } + } + + /// + /// Gets the operation to be performed + /// + public eViewOperation eViewOperation + { + get { return (_eViewOperation); } + } + + /// + /// Gets whether the operation is being + /// performed on a drag created copy item + /// + public bool IsCopyDrag + { + get { return (_IsCopyDrag); } + } + #endregion + } + #endregion + + #region AppointmentViewChangedEventArgs + /// + /// AppointmentViewChangedEventArgs + /// + public class AppointmentViewChangedEventArgs : EventArgs + { + #region Private variables + + private CalendarItem _CalendarItem; + + private string _OldOwnerKey; + private DateTime _OldStartTime; + private DateTime _OldEndTime; + + private eViewOperation _eViewOperation; + private bool _IsCopyDrag; + + #endregion + + public AppointmentViewChangedEventArgs(CalendarItem calendarItem, string oldOwnerKey, + DateTime oldStartTime, DateTime oldEndTime, eViewOperation eViewOperation, bool isCopyDrag) + { + _CalendarItem = calendarItem; + + _OldOwnerKey = oldOwnerKey; + _OldStartTime = oldStartTime; + _OldEndTime = oldEndTime; + + _eViewOperation = eViewOperation; + _IsCopyDrag = isCopyDrag; + } + + #region Public properties + + /// + /// Gets the CalendarItem that was changed + /// + public CalendarItem CalendarItem + { + get { return (_CalendarItem); } + } + + /// + /// Gets th old, previous OwnerKey + /// + public string OldOwnerKey + { + get { return (_OldOwnerKey); } + } + + /// + /// Gets th old, previous start time + /// + public DateTime OldStartTime + { + get { return (_OldStartTime); } + } + + /// + /// Gets the old, previous end time + /// + public DateTime OldEndTime + { + get { return (_OldEndTime); } + } + + /// + /// Gets the operation that was performed + /// + public eViewOperation eViewOperation + { + get { return (_eViewOperation); } + } + + /// + /// Gets whether the operation is being + /// performed on a drag created copy item + /// + public bool IsCopyDrag + { + get { return (_IsCopyDrag); } + } + + #endregion + } + #endregion + + #region AppointmentViewPostRenderEventArgs + + /// + /// AppointmentViewPostRenderEventArgs + /// + public class AppointmentViewPostRenderEventArgs : EventArgs + { + #region Private variables + + private CalendarItem _CalendarItem; + private Graphics _Graphics; + private Rectangle _Bounds; + private GraphicsPath _GraphicsPath; + + #endregion + + public AppointmentViewPostRenderEventArgs( + CalendarItem calendarItem, Graphics g, Rectangle bounds, GraphicsPath path) + { + _CalendarItem = calendarItem; + _Graphics = g; + _Bounds = bounds; + _GraphicsPath = path; + } + + #region Public properties + + /// + /// Gets the CalendarItem being changed + /// + public CalendarItem CalendarItem + { + get { return (_CalendarItem); } + } + + /// + /// Gets the associated Graphics object. + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated GraphicsPath. + /// This item may be null, based upon appointment style. + /// + public GraphicsPath GraphicsPath + { + get { return (_GraphicsPath); } + } + + /// + /// Gets the item bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region AppointmentViewPreRenderEventArgs + + /// + /// AppointmentViewPreRenderEventArgs + /// + public class AppointmentViewPreRenderEventArgs : AppointmentViewPostRenderEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + public AppointmentViewPreRenderEventArgs( + CalendarItem calendarItem, Graphics g, Rectangle bounds, GraphicsPath path) + : base(calendarItem, g, bounds, path) + { + } + + #region Public properties + + /// + /// Gets or sets whether to cancel + /// further item rendering. + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GetAppointmentGroupIdEventArgs + /// + /// GetAppointmentGroupIdEventArgs + /// + public class GetAppointmentGroupIdEventArgs : EventArgs + { + #region Private variables + + private CalendarItem _CalendarItem; + + private int _GroupId; + + #endregion + + public GetAppointmentGroupIdEventArgs(CalendarItem calendarItem, int groupId) + { + _CalendarItem = calendarItem; + + _GroupId = groupId; + } + + #region Public properties + + /// + /// Gets the CalendarItem that was changed + /// + public CalendarItem CalendarItem + { + get { return (_CalendarItem); } + } + + /// + /// Gets or sets the GroupId + /// + public int GroupId + { + get { return (_GroupId); } + set { _GroupId = value; } + } + + #endregion + } + #endregion + + #region GetDisplayTemplateTextEventArgs + /// + /// GetDisplayTemplateTextEventArgs + /// + public class GetDisplayTemplateTextEventArgs : EventArgs + { + #region Private variables + + private CalendarItem _CalendarItem; + + private string _DisplayTemplate; + private string _DisplayText; + + #endregion + + public GetDisplayTemplateTextEventArgs(CalendarItem calendarItem, + string displayTemplate, string displayText) + { + _CalendarItem = calendarItem; + + _DisplayTemplate = displayTemplate; + _DisplayText = displayText; + } + + #region Public properties + + /// + /// Gets the CalendarItem that was changed + /// + public CalendarItem CalendarItem + { + get { return (_CalendarItem); } + } + + /// + /// Gets the DisplayTemplate + /// + public string DisplayTemplate + { + get { return (_DisplayTemplate); } + } + + /// + /// Gets or sets the Display Text for the given DisplayTemplate + /// + public string DisplayText + { + get { return (_DisplayText); } + set { _DisplayText = value; } + } + + #endregion + } + #endregion + + #region DateChangeEventArgs + /// + /// DateChangeEventArgs + /// + public class DateChangeEventArgs : ValueChangedEventArgs + { + public DateChangeEventArgs(DateTime oldValue, DateTime newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region ViewDateChangedEventArgs + /// + /// ViewDateChangedEventArgs + /// + public class ViewDateChangedEventArgs : EventArgs + { + #region Private variables + + private BaseView _View; + + private DateTime _OldStartTime; + private DateTime _NewStartTime; + private DateTime _OldEndTime; + private DateTime _NewEndTime; + + #endregion + + public ViewDateChangedEventArgs(BaseView view, + DateTime oldStartTime, DateTime newStartTime, DateTime oldEndTime, DateTime newEndTime) + { + _View = view; + + _OldStartTime = oldStartTime; + _NewStartTime = newStartTime; + _OldEndTime = oldEndTime; + _NewEndTime = newEndTime; + } + + #region Public properties + + /// + /// Gets the View + /// + public BaseView View + { + get { return (_View); } + } + + /// + /// Gets the eCalendarView + /// + public eCalendarView eCalendarView + { + get { return (_View.ECalendarView); } + } + + /// + /// Gets th old, previous start time + /// + public DateTime OldStartTime + { + get { return (_OldStartTime); } + } + + /// + /// Gets the old, previous end time + /// + public DateTime OldEndTime + { + get { return (_OldEndTime); } + } + + /// + /// Gets or sets the new start time + /// + public DateTime NewStartTime + { + get { return (_NewStartTime); } + set { _NewStartTime = value; } + } + + /// + /// Gets or sets the new end time + /// + public DateTime NewEndTime + { + get { return (_NewEndTime); } + set { _NewStartTime = value; } + } + + #endregion + } + + #endregion + + #region ViewDateChangingEventArgs + + /// + /// DateViewChangingEventArgs + /// + public class ViewDateChangingEventArgs : CancelEventArgs + { + #region Private variables + + private BaseView _View; + private eCalendarView _eCalendarView; + + private DateTime _OldStartTime; + private DateTime _NewStartTime; + private DateTime _OldEndTime; + private DateTime _NewEndTime; + + #endregion + + public ViewDateChangingEventArgs(BaseView view, + DateTime oldStartTime, DateTime oldEndTime, DateTime newStartTime, DateTime newEndTime) + { + _View = view; + + _OldStartTime = oldStartTime; + _NewStartTime = newStartTime; + _OldEndTime = oldEndTime; + _NewEndTime = newEndTime; + } + + #region Public properties + + /// + /// Gets the View + /// + public BaseView View + { + get { return (_View); } + } + + /// + /// Gets the eCalendarView + /// + public eCalendarView eCalendarView + { + get { return (_View.ECalendarView); } + } + + /// + /// Gets th old, previous start time + /// + public DateTime OldStartTime + { + get { return (_OldStartTime); } + } + + /// + /// Gets the old, previous end time + /// + public DateTime OldEndTime + { + get { return (_OldEndTime); } + } + + /// + /// Gets or sets the new start time + /// + public DateTime NewStartTime + { + get { return (_NewStartTime); } + set { _NewStartTime = value; } + } + + /// + /// Gets or sets the new end time + /// + public DateTime NewEndTime + { + get { return (_NewEndTime); } + set { _NewStartTime = value; } + } + + #endregion + } + + #endregion + + #region CalendarItemEventArgs + + /// + /// CalendarItemEventArgs + /// + public class CalendarItemEventArgs : EventArgs + { + #region Private variables + + private BaseView _View; + + private CalendarItem _Item1; + private CalendarItem _Item2; + + private int _Result; + + #endregion + + public CalendarItemEventArgs(BaseView view, CalendarItem item1, CalendarItem item2) + { + _View = view; + + _Item1 = item1; + _Item2 = item2; + } + + #region Public properties + + /// + /// Gets the View + /// + public BaseView View + { + get { return (_View); } + } + + /// + /// Gets the eCalendarView + /// + public eCalendarView eCalendarView + { + get { return (_View.ECalendarView); } + } + + /// + /// Gets item1 comparison element + /// + public CalendarItem Item1 + { + get { return (_Item1); } + } + + /// + /// Gets item2 comparison element + /// + public CalendarItem Item2 + { + get { return (_Item2); } + } + + /// + /// Gets or sets the comparison result. + /// (-1 item1 < item2, 0 item1 == item2, +1 item1 > item2) + /// + public int Result + { + get { return (_Result); } + set { _Result = value; } + } + + #endregion + } + + #endregion + + #region SelectedOwnerChangedEventArgs + /// + /// SelectedOwnerChangedEventArgs + /// + /// + public class SelectedOwnerChangedEventArgs : ValueChangedEventArgs + { + public SelectedOwnerChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region FixedAllDayPanelHeightChangedEventArgs + /// + /// FixedAllDayPanelHeightChangedEventArgs + /// + /// + public class FixedAllDayPanelHeightChangedEventArgs : ValueChangedEventArgs + { + public FixedAllDayPanelHeightChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region MaximumAllDayPanelHeightChangedEventArgs + /// + /// MaximumAllDayPanelHeightChangedEventArgs + /// + /// + public class MaximumAllDayPanelHeightChangedEventArgs : ValueChangedEventArgs + { + public MaximumAllDayPanelHeightChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + + #endregion + + #region MinimumTimeSlotHeightChangedEventArgs + /// + /// MinimumTimeSlotHeightChangedEventArgs + /// + /// + public class MinimumTimeSlotHeightChangedEventArgs : ValueChangedEventArgs + { + public MinimumTimeSlotHeightChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + + #endregion + + #region TimeLineIntervalChangedEventArgs + /// + /// TimeLineIntervalChangedEventArgs + /// + public class TimeLineIntervalChangedEventArgs : ValueChangedEventArgs + { + public TimeLineIntervalChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineIntervalPeriodChangedEventArgs + /// + /// TimeLineIntervalPeriodChangedEventArgs + /// + public class TimeLineIntervalPeriodChangedEventArgs : ValueChangedEventArgs + { + public TimeLineIntervalPeriodChangedEventArgs(eTimeLinePeriod oldValue, eTimeLinePeriod newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region EnableDragDropChangedEventArgs + /// + /// EnableDragDropChangedEventArgs + /// + public class EnableDragDropChangedEventArgs : ValueChangedEventArgs + { + public EnableDragDropChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineColumnWidthChangedEventArgs + /// + /// TimeLineColumnWidthChangedEventArgs + /// + public class TimeLineColumnWidthChangedEventArgs : ValueChangedEventArgs + { + public TimeLineColumnWidthChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineMaxColumnCountChangedEventArgs + /// + /// TimeLineMaxColumnCountChangedEventArgs + /// + public class TimeLineMaxColumnCountChangedEventArgs : ValueChangedEventArgs + { + public TimeLineMaxColumnCountChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineHorizontalPaddingChangedEventArgs + /// + /// TimeLineHorizontalPaddingChangedEventArgs + /// + public class TimeLineHorizontalPaddingChangedEventArgs : ValueChangedEventArgs + { + public TimeLineHorizontalPaddingChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineShowPeriodHeaderChangedEventArgs + /// + /// TimeLineShowPeriodHeaderChangedEventArgs + /// + public class TimeLineShowPeriodHeaderChangedEventArgs : ValueChangedEventArgs + { + public TimeLineShowPeriodHeaderChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineShowIntervalHeaderChangedEventArgs + /// + /// TimeLineShowIntervalHeaderChangedEventArgs + /// + public class TimeLineShowIntervalHeaderChangedEventArgs : ValueChangedEventArgs + { + public TimeLineShowIntervalHeaderChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineShowPageNavigationChangedEventArgs + /// + /// TimeLineShowPageNavigationChangedEventArgs + /// + public class TimeLineShowPageNavigationChangedEventArgs : ValueChangedEventArgs + { + public TimeLineShowPageNavigationChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineCondensedViewVisibilityChangedEventArgs + /// + /// TimeLineCondensedViewVisibilityChangedEventArgs + /// + public class TimeLineCondensedViewVisibilityChangedEventArgs : + ValueChangedEventArgs + { + public TimeLineCondensedViewVisibilityChangedEventArgs( + eCondensedViewVisibility oldValue, eCondensedViewVisibility newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineCondensedViewHeightChangedEventArgs + /// + /// TimeLineCondensedViewHeightChangedEventArgs + /// + public class TimeLineCondensedViewHeightChangedEventArgs : ValueChangedEventArgs + { + public TimeLineCondensedViewHeightChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineRenderPeriodHeaderEventArgs + /// + /// TimeLineRenderPeriodHeaderEventArgs + /// + public class TimeLineRenderPeriodHeaderEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private DateTime _StartTime; + private DateTime _EndTime; + private Rectangle _Bounds; + private string _Text; + + #endregion + + public TimeLineRenderPeriodHeaderEventArgs(Graphics graphics, + DateTime startTime, DateTime endTime, Rectangle bounds, string text) + { + _Graphics = graphics; + + _StartTime = startTime; + _EndTime = endTime; + + _Bounds = bounds; + _Text = text; + } + + #region Public properties + + /// + /// Gets the Graphics object used to render + /// the Period Header + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the Bounding Text Rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the visible display StartTime + /// + public DateTime StartTime + { + get { return (_StartTime); } + } + + /// + /// Gets the visible display EndTime + /// + public DateTime EndTime + { + get { return (_EndTime); } + } + + /// + /// Gets or sets the header Text + /// + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + } + #endregion + + #region TimeLinePreRenderSlotBackgroundEventArgs + /// + /// TimeLinePreRenderSlotBackgroundEventArgs + /// + public class TimeLinePreRenderSlotBackgroundEventArgs : TimeLinePostRenderSlotBackgroundEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + public TimeLinePreRenderSlotBackgroundEventArgs(Graphics graphics, BaseView view, + DateTime startTime, DateTime endTime, Rectangle bounds, eSlotDisplayState state) + : base(graphics, view, startTime, endTime, bounds, state) + { + } + + #region Public properties + + /// + /// Gets or Sets whether the event should be canceled + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + #endregion + + #region TimeLinePostRenderSlotBackgroundEventArgs + /// + /// TimeLinePreRenderSlotBackgroundEventArgs + /// + public class TimeLinePostRenderSlotBackgroundEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private DateTime _StartTime; + private DateTime _EndTime; + private Rectangle _Bounds; + + private eSlotDisplayState _State; + private BaseView _View; + + #endregion + + public TimeLinePostRenderSlotBackgroundEventArgs(Graphics graphics, BaseView view, + DateTime startTime, DateTime endTime, Rectangle bounds, eSlotDisplayState state) + { + _Graphics = graphics; + + _View = view; + _StartTime = startTime; + _EndTime = endTime; + + _Bounds = bounds; + _State = state; + } + + #region Public properties + + /// + /// Gets the Graphics object used to render + /// the slot + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the slot bounding Rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the slot StartTime + /// + public DateTime StartTime + { + get { return (_StartTime); } + } + + /// + /// Gets the slot EndTime + /// + public DateTime EndTime + { + get { return (_EndTime); } + } + + /// + /// Gets the slot display state + /// + public eSlotDisplayState State + { + get { return (_State); } + set { _State = value; } + } + + /// + /// Gets the associated View + /// + public BaseView View + { + get { return (_View); } + } + + #endregion + } + #endregion + + #region TimeLineRenderSlotBorderEventArgs + /// + /// TimeLineRenderSlotBorderEventArgs + /// + public class TimeLineRenderSlotBorderEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private DateTime _StartTime; + private bool _Hourly; + private eSlotDisplayState _State; + private Point _StartPoint; + private Point _EndPoint; + private Color _Color; + + #endregion + + public TimeLineRenderSlotBorderEventArgs(Graphics graphics, + DateTime startTime, bool hourly, eSlotDisplayState state, Point pt1, Point pt2, Color color) + { + _Graphics = graphics; + + _StartTime = startTime; + _Hourly = hourly; + _State = state; + _StartPoint = pt1; + _EndPoint = pt2; + _Color = color; + } + + #region Public properties + + /// + /// Gets the Graphics object used to render + /// the slot + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets whether the border if an hourly border + /// + public bool Hourly + { + get { return (_Hourly); } + } + + /// + /// Gets the slot display state + /// + public eSlotDisplayState State + { + get { return (_State); } + set { _State = value; } + } + + /// + /// Gets the slot Starting Time + /// + public DateTime StartTime + { + get { return (_StartTime); } + } + + /// + /// Gets the slot starting Point + /// + public Point StartPoint + { + get { return (_StartPoint); } + } + + /// + /// Gets the slot ending Point + /// + public Point EndPoint + { + get { return (_EndPoint); } + } + + /// + /// Gets the slot border Color + /// + public Color Color + { + get { return (_Color); } + } + + #endregion + } + #endregion + + #region TimeLineRenderViewBorderEventArgs + /// + /// TimeLineRenderViewBorderEventArgs + /// + public class TimeLineRenderViewBorderEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private int _ColumnStart; + private int _ColumnEnd; + private Rectangle _Bounds; + private Color _Color; + + #endregion + + public TimeLineRenderViewBorderEventArgs(Graphics graphics, + int columnStart, int columnEnd, Rectangle bounds, Color color) + { + _Graphics = graphics; + + _ColumnStart = columnStart; + _ColumnEnd = columnEnd; + _Bounds = bounds; + _Color = color; + } + + #region Public properties + + /// + /// Gets the Graphics object used to render + /// the slot + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the starting column + /// + public int ColumnStart + { + get { return (_ColumnStart); } + } + + /// + /// Gets the ending column + /// + public int ColumnEnd + { + get { return (_ColumnEnd); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the default border Pen + /// + public Color Color + { + get { return (_Color); } + } + + #endregion + } + #endregion + + #region ShowOnlyWorkDayHoursChangedEventArgs + /// + /// ShowOnlyWorkDayHoursChangedEventArgs + /// + public class ShowOnlyWorkDayHoursChangedEventArgs : ValueChangedEventArgs + { + public ShowOnlyWorkDayHoursChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region TimeLineGetRowHeightEventArgs + /// + /// TimeLineGetRowHeightEventArgs + /// + public class TimeLineGetRowHeightEventArgs : EventArgs + { + #region Private variables + + private CalendarItem _CalendarItem; + private int _Height; + + #endregion + + public TimeLineGetRowHeightEventArgs(CalendarItem calendarItem, int height) + { + _CalendarItem = calendarItem; + _Height = height; + } + + #region Public properties + + /// + /// Gets or sets the Height + /// + public int Height + { + get { return (_Height); } + set { _Height = value; } + } + + /// + /// Gets the associated CalendarItem + /// + public CalendarItem CalendarItem + { + get { return (_CalendarItem); } + } + + #endregion + } + + #endregion + + #region TimeLineGetRowCollateIdEventArgs + /// + /// TimeLineGetRowCollateIdEventArgs + /// + public class TimeLineGetRowCollateIdEventArgs : EventArgs + { + #region Private variables + + private CalendarItem _CalendarItem; + private int _CollateId; + + #endregion + + public TimeLineGetRowCollateIdEventArgs(CalendarItem calendarItem) + { + _CalendarItem = calendarItem; + } + + #region Public properties + + /// + /// Gets or sets the row CollateId + /// + public int CollateId + { + get { return (_CollateId); } + + set + { + if (value < 0) + throw new Exception("CollateId must be 0 or greater."); + + _CollateId = value; + } + } + + /// + /// Gets the associated CalendarItem + /// + public CalendarItem CalendarItem + { + get { return (_CalendarItem); } + } + + #endregion + } + + #endregion + + #region PageNavigatorClickEventArgs + /// + /// PageNavigatorClickEventArgs + /// + public class PageNavigatorClickEventArgs : CancelEventArgs + { + #region Private variables + + private BaseView _View; + private PageNavigator _PageNavigator; + private PageNavigatorButton _Button; + private DateTime _NavigateTime; + + #endregion + + public PageNavigatorClickEventArgs(BaseView view, + PageNavigator pageNavigator, PageNavigatorButton button, DateTime navigateTime) + { + _View = view; + _PageNavigator = pageNavigator; + _Button = button; + _NavigateTime = navigateTime; + } + + #region Public properties + + /// + /// Gets the PageNavigator + /// + public PageNavigator PageNavigator + { + get { return (_PageNavigator); } + } + + /// + /// Gets the associated CalendarView + /// + public BaseView View + { + get { return (_View); } + } + + /// + /// Gets which button was clicked + /// + public PageNavigatorButton Button + { + get { return (_Button); } + } + + /// + /// Gets or sets the time to navigate to + /// + public DateTime NavigateTime + { + get { return (_NavigateTime); } + set { _NavigateTime = value; } + } + + #endregion + } + + #endregion + + #region AllowDateSelectionChangedEventArgs + /// + /// AllowDateSelectionChangedEventArgs + /// + public class AllowDateSelectionChangedEventArgs : ValueChangedEventArgs + { + public AllowDateSelectionChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region DayLinkChangedEventArgs + /// + /// DayLinkChangedEventArgs + /// + public class DayLinkChangedEventArgs : ValueChangedEventArgs + { + public DayLinkChangedEventArgs(eYearViewDayLink oldValue, eYearViewDayLink newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region LinkViewChangedEventArgs + /// + /// LinkViewChangedEventArgs + /// + public class LinkViewChangedEventArgs : ValueChangedEventArgs + { + public LinkViewChangedEventArgs(eCalendarView oldValue, eCalendarView newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region LinkViewActionChangedEventArgs + /// + /// LinkViewActionChangedEventArgs + /// + public class LinkViewActionChangedEventArgs : ValueChangedEventArgs + { + public LinkViewActionChangedEventArgs(eYearViewLinkAction oldValue, eYearViewLinkAction newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region LinkViewStyleChangedEventArgs + /// + /// LinkViewStyleChangedEventArgs + /// + public class LinkViewStyleChangedEventArgs : ValueChangedEventArgs + { + public LinkViewStyleChangedEventArgs(eYearViewLinkStyle oldValue, eYearViewLinkStyle newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region LinkViewSelectedEventArgs + /// + /// LinkViewSelectedEventArgs + /// + public class LinkViewSelectedEventArgs : CancelEventArgs + { + #region Private variables + + private DateTime _StartDate; + private DateTime _EndDate; + private eCalendarView _ECalendarView; + + #endregion + + public LinkViewSelectedEventArgs( + DateTime startDate, DateTime endDate, eCalendarView calendarView) + { + _StartDate = startDate; + _EndDate = endDate; + _ECalendarView = calendarView; + } + + #region Public properties + + /// + /// Gets the selected StartDate + /// + public DateTime StartDate + { + get { return (_StartDate); } + set { _StartDate = value; } + } + + /// + /// Gets the selected EndDate + /// + public DateTime EndDate + { + get { return (_EndDate); } + set { _EndDate = value; } + } + + /// + /// Gets the eCalendarView to activate + /// + public eCalendarView ECalendarView + { + get { return (_ECalendarView); } + set { _ECalendarView = value; } + } + #endregion + } + #endregion + + #region ShowGridLinesChangedEventArgs + /// + /// ShowGridLinesChangedEventArgs + /// + public class ShowGridLinesChangedEventArgs : ValueChangedEventArgs + { + public ShowGridLinesChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region YearViewDrawDayBackgroundEventArgs + /// + /// YearViewDrawDayBackgroundEventArgs + /// + public class YearViewDrawDayBackgroundEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private YearMonth _YearMonth; + private DateTime _Date; + private Rectangle _Bounds; + private eYearViewLinkStyle _LinkStyle; + + #endregion + + public YearViewDrawDayBackgroundEventArgs(Graphics g, YearMonth yearMonth, + DateTime date, Rectangle bounds, eYearViewLinkStyle linkStyle) + { + _Graphics = g; + _YearMonth = yearMonth; + _Date = date; + _Bounds = bounds; + _LinkStyle = linkStyle; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the YearMonth + /// + public YearMonth YearMonth + { + get { return (_YearMonth); } + } + + /// + /// Gets the date to draw + /// + public DateTime Date + { + get { return (_Date); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets or sets the Appointment Link style + /// + public eYearViewLinkStyle LinkStyle + { + get { return (_LinkStyle); } + set { _LinkStyle = value; } + } + + #endregion + } + #endregion + + #region YearViewDrawDayTextEventArgs + /// + /// YearViewDrawDayTextEventArgs + /// + public class YearViewDrawDayTextEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private YearMonth _YearMonth; + private DateTime _Date; + private Rectangle _Bounds; + + #endregion + + public YearViewDrawDayTextEventArgs(Graphics g, + YearMonth yearMonth, DateTime date, Rectangle bounds) + { + _Graphics = g; + _YearMonth = yearMonth; + _Date = date; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the YearMonth + /// + public YearMonth YearMonth + { + get { return (_YearMonth); } + } + + /// + /// Gets the date to draw + /// + public DateTime Date + { + get { return (_Date); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + #endregion + + #region RenderDaySlotAppearanceTextEventArgs + /// + /// RenderDaySlotAppearanceTextEventArgs + /// + public class RenderDaySlotAppearanceTextEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private Rectangle _Bounds; + private DaySlotAppearance _Appearance; + private DateTime _StartTime; + private DateTime _EndTime; + private string _Text; + private bool _Selected; + + #endregion + + public RenderDaySlotAppearanceTextEventArgs(Graphics g, Rectangle bounds, + DaySlotAppearance appearance, DateTime startTime, DateTime endTime, bool selected) + { + _Graphics = g; + _Bounds = bounds; + _Appearance = appearance; + _StartTime = startTime; + _EndTime = endTime; + _Selected = selected; + + _Text = appearance.Text; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the DaySlotAppearance + /// + public DaySlotAppearance Appearance + { + get { return (_Appearance); } + } + + /// + /// Gets the start DateTime + /// + public DateTime StartTime + { + get { return (_StartTime); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the end DateTime + /// + public DateTime EndTime + { + get { return (_EndTime); } + } + + /// + /// Gets whether the area is selected + /// + public bool Selected + { + get { return (_Selected); } + } + + /// + /// Gets or Sets the Text to render + /// + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + } + #endregion + + #region MonthViewPreRenderSlotBackgroundEventArgs + /// + /// MonthViewPreRenderSlotBackgroundEventArgs + /// + public class MonthViewPreRenderSlotBackgroundEventArgs : TimeLinePreRenderSlotBackgroundEventArgs + { + public MonthViewPreRenderSlotBackgroundEventArgs(Graphics graphics, BaseView view, + DateTime startTime, DateTime endTime, Rectangle bounds, eSlotDisplayState state) + : base(graphics, view, startTime, endTime, bounds, state) + { + } + } + #endregion + + #region MonthViewPostRenderSlotBackgroundEventArgs + /// + /// MonthViewPreRenderSlotBackgroundEventArgs + /// + public class MonthViewPostRenderSlotBackgroundEventArgs : TimeLinePostRenderSlotBackgroundEventArgs + { + public MonthViewPostRenderSlotBackgroundEventArgs(Graphics graphics, BaseView view, + DateTime startTime, DateTime endTime, Rectangle bounds, eSlotDisplayState state) + : base(graphics, view, startTime, endTime, bounds, state) + { + } + } + #endregion + + #region MonthViewHorizontalPaddingChangedEventArgs + /// + /// MonthViewHorizontalPaddingChangedEventArgs + /// + public class MonthViewHorizontalPaddingChangedEventArgs : ValueChangedEventArgs + { + public MonthViewHorizontalPaddingChangedEventArgs(int oldValue, int newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region RenderTabBackgroundEventArgs + /// + /// RenderTabBackgroundEventArgs + /// + public class RenderTabBackgroundEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private GraphicsPath _Path; + private BaseView _View; + private bool _IsSelected; + + #endregion + + public RenderTabBackgroundEventArgs( + Graphics graphics, GraphicsPath path, BaseView view, bool isSelected) + { + _Graphics = graphics; + _Path = path; + _View = view; + _IsSelected = isSelected; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the tab GraphicsPath + /// + public GraphicsPath Path + { + get { return (_Path); } + } + + /// + /// Gets the tab BaseView + /// + public BaseView View + { + get { return (_View); } + } + + /// + /// Gets whether the tab is selected or not + /// + public bool IsSelected + { + get { return (_IsSelected); } + } + + #endregion + } + #endregion + + #region RenderTabBackgroundEventArgs + /// + /// RenderTabBackgroundEventArgs + /// + public class RenderTabContentEventArgs : RenderTabBackgroundEventArgs + { + #region Private variables + + private string _Text; + + #endregion + + public RenderTabContentEventArgs(Graphics graphics, + GraphicsPath path, BaseView view, bool isSelected, string text) + : base(graphics, path, view, isSelected) + { + _Text = text; + } + + #region Public properties + + /// + /// Gets or sets the tab text + /// + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + } + #endregion + + #region RenderViewBorderEventArgs + /// + /// RenderViewBorderEventArgs + /// + public class RenderViewBorderEventArgs : CancelEventArgs + { + #region Private variables + + private Graphics _Graphics; + private Rectangle _Bounds; + + #endregion + + public RenderViewBorderEventArgs(Graphics graphics, Rectangle bounds) + { + _Graphics = graphics; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the Graphics object used to render + /// the slot + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + #endregion + + #region ViewLoadCompleteEventArgs + /// + /// ViewLoadCompleteEventArgs + /// + public class ViewLoadCompleteEventArgs : EventArgs + { + #region Private variables + + private BaseView _View; + + #endregion + + public ViewLoadCompleteEventArgs(BaseView view) + { + _View = view; + } + + #region Public properties + + /// + /// Gets the tab BaseView + /// + public BaseView View + { + get { return (_View); } + } + + #endregion + } + #endregion + + #region MonthMoreItemsIndicatorClickEventArgs + + /// + /// MonthMoreItemsIndicatorClickEventArgs + /// + public class MonthMoreItemsIndicatorClickEventArgs : CancelEventArgs + { + #region Private variables + + private BaseView _View; + private eCalendarView _SelectView; + private DateTime _StartTime; + + #endregion + + public MonthMoreItemsIndicatorClickEventArgs( + BaseView view, eCalendarView selectView, DateTime startTime) + { + _View = view; + _SelectView = selectView; + _StartTime = startTime; + } + + #region Public properties + + /// + /// Gets the associated MonthView + /// + public BaseView View + { + get { return (_View); } + } + + /// + /// Gets the eCalendarView to select + /// + public eCalendarView SelectView + { + get { return (_SelectView); } + set { _SelectView = value; } + } + + /// + /// Gets or sets the starting time to navigate to + /// + public DateTime StartTime + { + get { return (_StartTime); } + set { _StartTime = value; } + } + + #endregion + } + + #endregion + + #region TimeLineGetHeaderTextEventArgs + /// + /// TimeLineGetHeaderTextEventArgs + /// + public class TimeLineGetHeaderTextEventArgs : EventArgs + { + #region Private variables + + private DateTime _Date; + private TimeLineHeaderPanel _Header; + private string _Text; + + #endregion + + public TimeLineGetHeaderTextEventArgs( + TimeLineHeaderPanel header, DateTime date, string text) + { + _Header = header; + _Date = date; + _Text = text; + } + + #region Public properties + + /// + /// Gets the associated TimeLineHeaderPanel + /// + public TimeLineHeaderPanel Header + { + get { return (_Header); } + } + + /// + /// Gets the Header date / time + /// + public DateTime Date + { + get { return (_Date); } + } + + /// + /// Gets or sets the Header Text + /// + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + } + + #endregion + + #region WeekDayCanExtendRangeChangedEventArgs + /// + /// WeekDayCanExtendRangeChangedEventArgs + /// + public class WeekDayCanExtendRangeChangedEventArgs : ValueChangedEventArgs + { + public WeekDayCanExtendRangeChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #region PostRenderWeekDayHeaderEventArgs + + /// + /// PostRenderWeekDayHeaderEventArgs + /// + public class PostRenderWeekDayHeaderEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private WeekDayView _View; + private int _ColumnIndex; + private Rectangle _Bounds; + + #endregion + + public PostRenderWeekDayHeaderEventArgs( + Graphics g, WeekDayView view, int colIndex, Rectangle bounds) + { + _Graphics = g; + _View = view; + _ColumnIndex = colIndex; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the WeekDayView + /// + public WeekDayView View + { + get { return (_View); } + } + + /// + /// Gets the DayColumn index + /// + public int ColumnIndex + { + get { return (_ColumnIndex); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PreRenderWeekDaySlotBackgroundEventArgs + + /// + /// PreRenderWeekDaySlotBackgroundEventArgs + /// + public class PreRenderWeekDaySlotBackgroundEventArgs : PostRenderWeekDaySlotBackgroundEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + public PreRenderWeekDaySlotBackgroundEventArgs(Graphics g, + WeekDayView view, int dayColumnIndex,int daySliceIndex, Rectangle bounds) + : base(g, view, dayColumnIndex, daySliceIndex, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether to cancel default rendering + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region PostRenderWeekDaySlotBackgroundEventArgs + + /// + /// PostRenderWeekDaySlotBackgroundEventArgs + /// + public class PostRenderWeekDaySlotBackgroundEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private WeekDayView _View; + private int _DayColumnIndex; + private int _DaySliceIndex; + private Rectangle _Bounds; + + #endregion + + public PostRenderWeekDaySlotBackgroundEventArgs( + Graphics g, WeekDayView view, int dayColumnIndex, int daySliceIndex, Rectangle bounds) + { + _Graphics = g; + _View = view; + _DayColumnIndex = dayColumnIndex; + _DaySliceIndex = daySliceIndex; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the WeekDayView + /// + public WeekDayView View + { + get { return (_View); } + } + + /// + /// Gets the associated DayColumn index + /// + public int DayColumnIndex + { + get { return (_DayColumnIndex); } + } + + /// + /// Gets the associated Slice index + /// + public int DaySliceIndex + { + get { return (_DaySliceIndex); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PreRenderWeekDayHeaderEventArgs + + /// + /// PreRenderWeekDayHeaderEventArgs + /// + public class PreRenderWeekDayHeaderEventArgs : PostRenderWeekDayHeaderEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + public PreRenderWeekDayHeaderEventArgs(Graphics g, WeekDayView view, int colIndex, Rectangle bounds) + : base (g, view, colIndex, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether to cancel default rendering + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region PostRenderMonthHeaderEventArgs + + /// + /// PostRenderMonthHeaderEventArgs + /// + public class PostRenderMonthHeaderEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private MonthView _View; + private int _ColumnIndex; + private Rectangle _Bounds; + + #endregion + + public PostRenderMonthHeaderEventArgs( + Graphics g, MonthView view, int colIndex, Rectangle bounds) + { + _Graphics = g; + _View = view; + _ColumnIndex = colIndex; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the MonthView + /// + public MonthView View + { + get { return (_View); } + } + + /// + /// Gets the column index + /// + public int ColumnIndex + { + get { return (_ColumnIndex); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + #endregion + } + + #endregion + + #region PreRenderMonthHeaderEventArgs + + /// + /// PreRenderMonthHeaderEventArgs + /// + public class PreRenderMonthHeaderEventArgs : PostRenderMonthHeaderEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + public PreRenderMonthHeaderEventArgs(Graphics g, MonthView view, int colIndex, Rectangle bounds) + : base(g, view, colIndex, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether to cancel default rendering + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #endregion +} + +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/CalendarViewCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/CalendarViewCollection.cs new file mode 100644 index 00000000..59a1886a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/CalendarViewCollection.cs @@ -0,0 +1,112 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; + +namespace DevComponents.DotNetBar.Schedule +{ + public class CalendarViewCollection where T : BaseView + { + #region Private variables + + private CalendarView _CalendarView; // Assoc CalendarView + private List _Views = new List(); // BaseView items + + #endregion + + /// + /// Constructor + /// + /// CalendarView + public CalendarViewCollection(CalendarView calendarView) + { + _CalendarView = calendarView; + } + + #region Public properties + + /// + /// Gets the count of items in the collection + /// + public int Count + { + get { return (_Views.Count); } + } + + /// + /// Gets the view at the given index + /// + /// Index + /// Requested view + public T this[int index] + { + get { return (GetView(index)); } + } + + /// + /// Gets the view for the given DisplayedOwner + /// + /// DisplayedOwner + /// Requested view + public T this[string key] + { + get { return (GetView(FindDisplayedOwner(key))); } + } + + /// + /// Locates the view index from the given + /// DisplayedOwner text + /// + /// DisplayedOwner + /// View index, or -1 if not found + private int FindDisplayedOwner(string key) + { + for (int i = 0; i < _CalendarView.DisplayedOwners.Count; i++) + { + if (_CalendarView.DisplayedOwners[i].Equals(key)) + return (i); + } + + return (-1); + } + + /// + /// Returns the given view at the specified index. + /// + /// This routine will initiate the creation + /// of the view if it has not previously been created. + /// + /// Index + /// Requested view + private T GetView(int index) + { + if (index >= 0 && index < _Views.Count) + { + if (_Views[index] == null) + { + Type type = typeof(T); + + _Views[index] = (T)_CalendarView.NewView(type, index); + } + + return (_Views[index]); + } + + return (default(T)); + } + + #endregion + + #region Internal properties + + /// + /// Gets the collection view list + /// + internal List Views + { + get { return (_Views); } + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/DisplayedOwnerCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/DisplayedOwnerCollection.cs new file mode 100644 index 00000000..3e431a6f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/DisplayedOwnerCollection.cs @@ -0,0 +1,142 @@ +#if FRAMEWORK20 +using System.Collections.ObjectModel; + +namespace DevComponents.DotNetBar.Schedule +{ + public class DisplayedOwnerCollection : Collection + { + #region Private variables + + private CalendarView _CalendarView; // Assoc CalendarView + private bool _IsRangeSet; // Range set flag + private bool _SuspendUpdate; + + #endregion + + /// + /// Constructor + /// + /// CalendarView + public DisplayedOwnerCollection(CalendarView calendarView) + { + _CalendarView = calendarView; + } + + #region Internal properties + + /// + /// Gets and sets the SuspendUpdate state + /// + internal bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region AddRange + + /// + /// Adds a range of Owners to the DisplayedOwner collection + /// + /// Array of Owners to add + public void AddRange(string[] items) + { + int index = Count; + + try + { + _IsRangeSet = true; + + for (int i = 0; i < items.Length; i++) + Add(items[i]); + } + finally + { + _IsRangeSet = false; + + _CalendarView.DisplayedOwnersAdded(index); + } + } + + #endregion + + #region RemoveItem + + /// + /// Processes list RemoveItem calls + /// + /// Index to remove + protected override void RemoveItem(int index) + { + base.RemoveItem(index); + + if (_SuspendUpdate == false) + _CalendarView.DisplayedOwnersRemoved(index, index + 1); + } + + #endregion + + #region InsertItem + + /// + /// Processes list InsertItem calls + /// + /// Index to add + /// Text to add + protected override void InsertItem(int index, string item) + { + if (string.IsNullOrEmpty(item) == false) + { + base.InsertItem(index, item); + + if (_SuspendUpdate == false) + { + if (_IsRangeSet == false) + _CalendarView.DisplayedOwnersAdded(index); + } + } + } + + #endregion + + #region SetItem + + /// + /// Processes list SetItem calls (e.g. replace) + /// + /// Index to replace + /// Text to replace + protected override void SetItem(int index, string newItem) + { + base.SetItem(index, newItem); + + if (_SuspendUpdate == false) + _CalendarView.DisplayedOwnersSet(index); + } + + #endregion + + #region ClearItems + + /// + /// Processes list Clear calls (e.g. remove all) + /// + protected override void ClearItems() + { + if (Count > 0) + { + int n = Count; + + base.ClearItems(); + + _CalendarView.DisplayedOwnersRemoved(0, n); + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/ViewDisplayCustomizations.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/ViewDisplayCustomizations.cs new file mode 100644 index 00000000..2981ddbc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CalendarView/ViewDisplayCustomizations.cs @@ -0,0 +1,916 @@ +using System; +using System.Collections.ObjectModel; +using System.Drawing; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + /// + /// ViewDisplayCustomizations + /// + public class ViewDisplayCustomizations + { + #region Events + + /// + /// Occurs when the ViewDisplayCustomizations have changed + /// + public event EventHandler CollectionChanged; + + #endregion + + #region Private variables + + private CalendarView _CalendarView; + private DaySlotBackgrounds _DaySlotBackgrounds; + + #endregion + + /// + /// ViewDisplayCustomizations + /// + /// + public ViewDisplayCustomizations(CalendarView calendarView) + { + _CalendarView = calendarView; + } + + #region Public properties + + /// + /// DaySlotBackgrounds + /// + public DaySlotBackgrounds DaySlotBackgrounds + { + get + { + if (_DaySlotBackgrounds == null) + { + _DaySlotBackgrounds = new DaySlotBackgrounds(); + _DaySlotBackgrounds.CollectionChanged += _DaySlotBackgrounds_CollectionChanged; + } + + return (_DaySlotBackgrounds); + } + + set + { + if (_DaySlotBackgrounds != null) + _DaySlotBackgrounds.CollectionChanged -= _DaySlotBackgrounds_CollectionChanged; + + _DaySlotBackgrounds = value; + + if (_DaySlotBackgrounds != null) + _DaySlotBackgrounds.CollectionChanged += _DaySlotBackgrounds_CollectionChanged; + } + } + + #endregion + + #region Event handling + + /// + /// Handles DaySlotBackgrounds CollectionChanged events + /// + /// + /// + void _DaySlotBackgrounds_CollectionChanged(object sender, EventArgs e) + { + _CalendarView.Refresh(); + + if (CollectionChanged != null) + CollectionChanged(this, EventArgs.Empty); + } + + #endregion + + #region GetDaySlotAppearance + + /// + /// Retrieves the DaySlotAppearance from the given criteris + /// + /// + /// + /// + /// + /// + internal DaySlotAppearance GetDaySlotAppearance( + string ownerKey, DateTime dateTime, WorkTime wkStart, WorkTime wkEnd) + { + foreach (DaySlotBackground dsb in DaySlotBackgrounds) + { + if (IsValidSlot(dsb, dateTime, wkStart, wkEnd) == true) + { + if (IsValidOwner(dsb, ownerKey) == true) + return (dsb.Appearance); + } + } + + return (null); + } + + #endregion + + #region IsValidSlot + + /// + /// Determines if the given slot is a valid + /// day and time slot + /// + /// + /// + /// + /// + /// + private bool IsValidSlot(DaySlotBackground dsb, + DateTime dateTime, WorkTime wkStart, WorkTime wkEnd) + { + if (IsValidDaySlot(dsb, dateTime) == true) + return (IsValidTimeSlot(dsb, wkStart, wkEnd)); + + return (false); + } + + #endregion + + #region IsValidTimeSlot + + /// + /// Determines if the given slot is a valid time slot + /// + /// + /// + /// + /// + private bool IsValidTimeSlot(DaySlotBackground dsb, WorkTime wkStart, WorkTime wkEnd) + { + return (wkStart < dsb.Appearance.EndTime && wkEnd > dsb.Appearance.StartTime); + } + + #endregion + + #region IsValidDaySlot + + /// + /// Determines if the given slot is a valid time slot + /// + /// + /// + /// + private bool IsValidDaySlot(DaySlotBackground dsb, DateTime dateTime) + { + if (dsb.DateTime == DateTime.MinValue) + return (dsb.DayOfWeek == dateTime.DayOfWeek); + + return (dsb.DateTime.Date == dateTime.Date); + } + + #endregion + + #region IsValidOwner + + /// + /// Determines if the given owner key is valid for the slot + /// + /// + /// + /// + private bool IsValidOwner(DaySlotBackground dsb, string ownerKey) + { + if (dsb.HasOwnerKeys == true) + { + if (dsb.OwnerKeys.Contains("") == true) + return (true); + + if (dsb.OwnerKeys.Contains(ownerKey) == false) + return (false); + } + + return (true); + } + + #endregion + } + + /// + /// DaySlotBackgrounds + /// + public class DaySlotBackgrounds : Collection + { + #region Events + + /// + /// Occurs when the DaySlotBackgrounds collection changes + /// + public event EventHandler CollectionChanged; + + #endregion + + #region Private variables + + private bool _IsRangeSet; + private bool _SuspendUpdate; + + #endregion + + #region Internal properties + + /// + /// Gets and sets the SuspendUpdate state + /// + internal bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region Remove + + /// + /// Removes the DaySlotBackground for the given DateTime + /// + /// + public void Remove(DateTime dateTime) + { + int n = Items.Count; + + try + { + SuspendUpdate = true; + + for (int i = Items.Count - 1; i >= 0; i--) + { + DaySlotBackground dsb = Items[i]; + + if (dsb.DateTime.Equals(dateTime) == true) + RemoveAt(i); + } + } + finally + { + SuspendUpdate = false; + + if (Items.Count != n) + OnCollectionChanged(); + } + } + + /// + /// Removes the DaySlotBackground for the given DayOfWeek + /// + /// + public void Remove(DayOfWeek dayOfWeek) + { + int n = Items.Count; + + try + { + SuspendUpdate = true; + + for (int i = Items.Count - 1; i >= 0; i--) + { + DaySlotBackground dsb = Items[i]; + + if (dsb.DateTime.Equals(DateTime.MinValue) == true) + { + if (dsb.DayOfWeek == dayOfWeek) + RemoveAt(i); + } + } + } + finally + { + SuspendUpdate = false; + + if (Items.Count != n) + OnCollectionChanged(); + } + } + + #endregion + + #region AddRange + + /// + /// Adds a range of DaySlotBackgrounds + /// + /// + public void AddRange(DaySlotBackgrounds daySlotBackgrounds) + { + try + { + _IsRangeSet = true; + + foreach (DaySlotBackground dsb in daySlotBackgrounds) + Add(dsb); + } + finally + { + _IsRangeSet = false; + + OnCollectionChanged(); + } + } + + #endregion + + #region RemoveItem + + /// + /// Processes list RemoveItem calls + /// + /// Index to remove + protected override void RemoveItem(int index) + { + base.RemoveItem(index); + + OnCollectionChanged(); + } + + #endregion + + #region InsertItem + + /// + /// Processes list InsertItem calls + /// + /// Index to add + /// Text to add + protected override void InsertItem(int index, DaySlotBackground item) + { + if (item != null) + { + base.InsertItem(index, item); + + item.DaySlotBackgrounds = this; + + OnCollectionChanged(); + } + } + + #endregion + + #region SetItem + + /// + /// Processes list SetItem calls (e.g. replace) + /// + /// Index to replace + /// Text to replace + protected override void SetItem(int index, DaySlotBackground newItem) + { + base.SetItem(index, newItem); + + newItem.DaySlotBackgrounds = this; + + OnCollectionChanged(); + } + + #endregion + + #region ClearItems + + /// + /// Processes list Clear calls (e.g. remove all) + /// + protected override void ClearItems() + { + if (Count > 0) + { + base.ClearItems(); + + OnCollectionChanged(); + } + } + + #endregion + + #region OnCollectionChanged + + /// + /// Handles collection change notification + /// + private void OnCollectionChanged() + { + if (_SuspendUpdate == false && _IsRangeSet == false) + { + if (CollectionChanged != null) + CollectionChanged(this, EventArgs.Empty); + } + } + + #endregion + } + + /// + /// DaySlotBackground + /// + public class DaySlotBackground + { + #region Events + + /// + /// Occurs when the DaySlotBackground collection changes + /// + public event EventHandler CollectionChanged; + + #endregion + + #region Private variables + + private DayOfWeek _DayOfWeek; + private DateTime _DateTime = DateTime.MinValue; + + private DaySlotAppearance _Appearance; + private DaySlotBackgrounds _DaySlotBackgrounds; + + private OwnerKeyCollection _OwnerKeys; + + #endregion + + #region Constructors + + public DaySlotBackground(DateTime dateTime, DaySlotAppearance appearance) + { + _DateTime = dateTime; + + _Appearance = appearance; + } + + public DaySlotBackground(DayOfWeek dayOfWeek, DaySlotAppearance appearance) + { + _DayOfWeek = dayOfWeek; + _DateTime = DateTime.MinValue; + + _Appearance = appearance; + } + + #endregion + + #region Public properties + + #region Appearance + + /// + /// Gets or sets the Appearance + /// + public DaySlotAppearance Appearance + { + get { return (_Appearance); } + + set + { + _Appearance = value; + + OnCollectionChanged(); + } + } + + #endregion + + #region DateTime + + /// + /// Gets or sets the DateTime + /// + public DateTime DateTime + { + get { return (_DateTime); } + + set + { + if (_DateTime != value) + { + _DateTime = value; + + OnCollectionChanged(); + } + } + } + + #endregion + + #region DayOfWeek + + /// + /// Gets or sets the DayOfWeek + /// + public DayOfWeek DayOfWeek + { + get { return (_DayOfWeek); } + + set + { + if (_DayOfWeek != value) + { + _DayOfWeek = value; + + OnCollectionChanged(); + } + } + } + + #endregion + + #region OwnerKeys + + /// + /// Gets or sets the OwnerKeyCollection + /// + public OwnerKeyCollection OwnerKeys + { + get + { + if (_OwnerKeys == null) + { + _OwnerKeys = new OwnerKeyCollection(); + + _OwnerKeys.CollectionChanged += OwnerKeys_CollectionChanged; + } + + return (_OwnerKeys); + } + + set + { + if (_OwnerKeys != null) + _OwnerKeys.CollectionChanged -= OwnerKeys_CollectionChanged; + + _OwnerKeys = value; + + if (_OwnerKeys != null) + _OwnerKeys.CollectionChanged += OwnerKeys_CollectionChanged; + } + } + + #endregion + + #endregion + + #region Internal properties + + #region DaySlotBackgrounds + + /// + /// Gets or sets the DaySlotBackgrounds + /// + internal DaySlotBackgrounds DaySlotBackgrounds + { + get { return (_DaySlotBackgrounds); } + + set + { + _DaySlotBackgrounds = value; + + OnCollectionChanged(); + } + } + + #endregion + + #region HasOwnerKeys + + /// + /// HasOwnerKeys + /// + internal bool HasOwnerKeys + { + get { return (_OwnerKeys != null && _OwnerKeys.Count > 0); } + } + + #endregion + + #endregion + + #region Event processing + + /// + /// Processes OwnerKeys_CollectionChanged events + /// + /// + /// + private void OwnerKeys_CollectionChanged(object sender, EventArgs e) + { + OnCollectionChanged(); + } + + #endregion + + #region OnCollectionChanged + + /// + /// Handles collection change notification + /// + private void OnCollectionChanged() + { + if (CollectionChanged != null) + CollectionChanged(this, EventArgs.Empty); + } + + #endregion + } + + /// + /// DaySlotAppearance + /// + public class DaySlotAppearance + { + #region Private variables + + private WorkTime _StartTime; + private WorkTime _EndTime; + + private Color _BackColor; + private Color _HourBorderColor; + private Color _HalfHourBorderColor; + + private string _Text; + private ContentAlignment _TextAlignment; + private Color _TextColor; + private Color _SelectedTextColor; + private Font _Font; + + private bool _OnTop; + private bool _ShowTextWhenSelected = true; + + #endregion + + #region Constructors + + public DaySlotAppearance(WorkTime startTime, WorkTime endTime, + Color backColor, Color hourBorderColor, Color halfHourBorderColor) + { + _StartTime = startTime; + _EndTime = endTime; + + _BackColor = backColor; + _HourBorderColor = hourBorderColor; + _HalfHourBorderColor = halfHourBorderColor; + } + + public DaySlotAppearance(int startHour, int startMinute, + int endHour, int endMinute, Color backColor, Color hourBorderColor, Color halfHourBorderColor) + : this(new WorkTime(startHour, startMinute), new WorkTime(endHour, endMinute), backColor, hourBorderColor, halfHourBorderColor) + { + } + + #endregion + + #region Public properties + + #region BackColor + + /// + /// Gets or sets the BackColor + /// + public Color BackColor + { + get { return (_BackColor); } + set { _BackColor = value; } + } + + #endregion + + #region EndTime + + /// + /// Gets or sets the Appearance end time + /// + public WorkTime EndTime + { + get { return (_EndTime); } + set { _EndTime = value; } + } + + #endregion + + #region Font + + /// + /// Gets or sets the DaySlot Font + /// + public Font Font + { + get { return (_Font); } + set { _Font = value; } + } + + #endregion + + #region HalfHourBorderColor + + /// + /// Gets or sets the HalfHourBorderColor + /// + public Color HalfHourBorderColor + { + get { return (_HalfHourBorderColor); } + set { _HalfHourBorderColor = value; } + } + + #endregion + + #region HourBorderColor + + /// + /// Gets or sets the HourBorderColor + /// + public Color HourBorderColor + { + get { return (_HourBorderColor); } + set { _HourBorderColor = value; } + } + + #endregion + + #region OnTop + + /// + /// Gets or sets whether the Text is on top of the borders + /// + public bool OnTop + { + get { return (_OnTop); } + set { _OnTop = value; } + } + + #endregion + + #region StartTime + + /// + /// Gets or sets the Appearance start time + /// + public WorkTime StartTime + { + get { return (_StartTime); } + set { _StartTime = value; } + } + + #endregion + + #region Text + + /// + /// Gets or sets the Text + /// + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + + #region TextAlignment + + /// + /// Gets or sets the Text Alignment + /// + public ContentAlignment TextAlignment + { + get { return (_TextAlignment); } + set { _TextAlignment = value; } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text Color + /// + public Color TextColor + { + get { return (_TextColor); } + set { _TextColor = value; } + } + + #endregion + + #region SelectedTextColor + + /// + /// Gets or sets the Selected Text Color + /// + public Color SelectedTextColor + { + get { return (_SelectedTextColor); } + set { _SelectedTextColor = value; } + } + + #endregion + + #region ShowTextWhenSelected + + /// + /// Gets or sets wheter the Text is displayed when cells are selected + /// + public bool ShowTextWhenSelected + { + get { return (_ShowTextWhenSelected); } + set { _ShowTextWhenSelected = value; } + } + + #endregion + + #endregion + } + + /// + /// OwnerKeyCollection + /// + public class OwnerKeyCollection : Collection + { + #region Events + + /// + /// Occurs when the OwnerKeyCollection changes + /// + public event EventHandler CollectionChanged; + + #endregion + + #region RemoveItem + + /// + /// Processes list RemoveItem calls + /// + /// Index to remove + protected override void RemoveItem(int index) + { + base.RemoveItem(index); + + OnCollectionChanged(); + } + + #endregion + + #region InsertItem + + /// + /// Processes list InsertItem calls + /// + /// Index to add + /// Text to add + protected override void InsertItem(int index, string item) + { + if (item != null) + { + base.InsertItem(index, item); + + OnCollectionChanged(); + } + } + + #endregion + + #region SetItem + + /// + /// Processes list SetItem calls (e.g. replace) + /// + /// Index to replace + /// Text to replace + protected override void SetItem(int index, string newItem) + { + base.SetItem(index, newItem); + + OnCollectionChanged(); + } + + #endregion + + #region ClearItems + + /// + /// Processes list Clear calls (e.g. remove all) + /// + protected override void ClearItems() + { + if (Count > 0) + { + base.ClearItems(); + + OnCollectionChanged(); + } + } + + #endregion + + #region OnCollectionChanged + + /// + /// Handles collection change notification + /// + private void OnCollectionChanged() + { + if (CollectionChanged != null) + CollectionChanged(this, EventArgs.Empty); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/AppointmentCategoryColor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/AppointmentCategoryColor.cs new file mode 100644 index 00000000..24805959 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/AppointmentCategoryColor.cs @@ -0,0 +1,149 @@ +#if FRAMEWORK20 +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.Schedule +{ + public class AppointmentCategoryColor + { + #region Events + + /// + /// Occurs when AppointmentCategoryColorCollection has changed + /// + [Description("Occurs when the AppointmentCategoryColorCollection has changed.")] + public event EventHandler AppointmentCategoryColorChanged; + + #endregion + + #region Private variables + + private string _ColorName; + private Color _TextColor; + private Color _BorderColor; + private ColorDef _BackColor; + + #endregion + + /// + /// AppointmentCategoryColor + /// + /// Color name + /// Text Color + /// Border Color + /// Background Color + public AppointmentCategoryColor(string colorName, + Color textColor, Color borderColor, ColorDef backColor) + { + _ColorName = colorName; + + _TextColor = textColor; + _BorderColor = borderColor; + _BackColor = backColor; + } + + /// + /// AppointmentCategoryColor + /// + /// Color name + public AppointmentCategoryColor(string colorName) + : this(colorName, Color.Black, Color.Black, new ColorDef(Color.White)) + { + } + + #region Public properties + + #region ColorName + + /// + /// Color name + /// + public string ColorName + { + get { return (_ColorName); } + internal set { _ColorName = value; } + } + + #endregion + + #region TextColor + + /// + /// Text Color + /// + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnAppointmentCategoryColorChanged(); + } + } + } + + #endregion + + #region BorderColor + + /// + /// Border Color + /// + public Color BorderColor + { + get { return (_BorderColor); } + + set + { + if (_BorderColor != value) + { + _BorderColor = value; + + OnAppointmentCategoryColorChanged(); + } + } + } + + #endregion + + #region BackColor + + /// + /// Background Color + /// + public ColorDef BackColor + { + get { return (_BackColor); } + + set + { + if (_BackColor != value) + { + _BackColor = value; + + OnAppointmentCategoryColorChanged(); + } + } + } + + #endregion + + #endregion + + #region OnAppointmentCategoryColorChanged + + private void OnAppointmentCategoryColorChanged() + { + if (AppointmentCategoryColorChanged != null) + AppointmentCategoryColorChanged(this, EventArgs.Empty); + } + + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/AppointmentCategoryColorCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/AppointmentCategoryColorCollection.cs new file mode 100644 index 00000000..cea048ee --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/AppointmentCategoryColorCollection.cs @@ -0,0 +1,178 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Schedule +{ + public class AppointmentCategoryColorCollection + { + #region Events + + /// + /// Occurs when AppointmentCategoryColorCollection has changed + /// + [Description("Occurs when the AppointmentCategoryColorCollection has changed.")] + public event EventHandler AppointmentCategoryColorCollectionChanged; + + #endregion + + #region Private variables + + private Dictionary _List; + + #endregion + + /// + /// AppointmentCategoryColorCollection + /// + public AppointmentCategoryColorCollection() + { + _List = new Dictionary(); + } + + #region Public properties + + /// + /// Gets the Count of items defined + /// + public int Count + { + get { return (_List.Count); } + } + + #endregion + + #region Add + + /// + /// Adds a AppointmentCategoryColor to the collection + /// + /// + public void Add(AppointmentCategoryColor acc) + { + _List[acc.ColorName] = acc; + + acc.AppointmentCategoryColorChanged += CategoryColorChanged; + + OnAppointmentCategoryColorCollectionChanged(); + } + + #endregion + + #region Remove + + /// + /// Removes an entry from the collection, by color name + /// + /// Color name + public void Remove(string colorName) + { + if (_List.ContainsKey(colorName)) + { + _List[colorName].AppointmentCategoryColorChanged -= CategoryColorChanged; + + _List.Remove(colorName); + + OnAppointmentCategoryColorCollectionChanged(); + } + } + + /// + /// Removes an entry from the collection, by AppointmentCategoryColor + /// + /// AppointmentCategoryColor + public void Remove(AppointmentCategoryColor categoryColor) + { + Remove(categoryColor.ColorName); + } + + #endregion + + #region Clear + + /// + /// Clears the AppointmentCategoryColor collection + /// + public void Clear() + { + foreach (AppointmentCategoryColor ac in _List.Values) + ac.AppointmentCategoryColorChanged -= CategoryColorChanged; + + _List.Clear(); + + OnAppointmentCategoryColorCollectionChanged(); + } + + #endregion + + #region Items + + /// + /// Gets the entire list of added AppointmentCategoryColor items + /// + public AppointmentCategoryColor[] Items + { + get + { + AppointmentCategoryColor[] items = new AppointmentCategoryColor[_List.Count]; + + _List.Values.CopyTo(items, 0); + + return (items); + } + } + + #endregion + + #region this + + /// + /// Gets the AppointmentCategoryColor from the given + /// color name string index + /// + /// + /// + public AppointmentCategoryColor this[string colorName] + { + get + { + AppointmentCategoryColor acc; + + _List.TryGetValue(colorName, out acc); + + return (acc); + } + } + + #endregion + + #region CategoryColorChanged + + /// + /// CategoryColorChanged + /// + /// + /// + void CategoryColorChanged(object sender, EventArgs e) + { + OnAppointmentCategoryColorCollectionChanged(); + } + + #endregion + + #region OnAppointmentCategoryColorCollectionChanged + + /// + /// OnAppointmentCategoryColorCollectionChanged + /// + private void OnAppointmentCategoryColorCollectionChanged() + { + if (AppointmentCategoryColorCollectionChanged != null) + AppointmentCategoryColorCollectionChanged(this, EventArgs.Empty); + } + + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/AppointmentColor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/AppointmentColor.cs new file mode 100644 index 00000000..73e2d325 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/AppointmentColor.cs @@ -0,0 +1,121 @@ +#if FRAMEWORK20 +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Schedule +{ + #region enum definitions + + /// + /// Appointment parts enum + /// + public enum eAppointmentPart + { + DefaultBorder, + DefaultBackground, + + BlueBorder, + BlueBackground, + + GreenBorder, + GreenBackground, + + OrangeBorder, + OrangeBackground, + + PurpleBorder, + PurpleBackground, + + RedBorder, + RedBackground, + + YellowBorder, + YellowBackground, + + BusyTimeMarker, + FreeTimeMarker, + OutOfOfficeTimeMarker + } + + #endregion + + public class AppointmentColor : CalendarColor + { + /// + /// Constructor + /// + public AppointmentColor() + : base(eCalendarColor.Automatic) + { + } + + #region SetColorTable routine + + /// + /// Sets our current color table to either + /// a local or global definition + /// + public override void SetColorTable() + { + // Use the globally set color table + + Office2007Renderer r = + GlobalManager.Renderer as Office2007Renderer; + + ColorTable = (r != null) + ? r.ColorTable.CalendarView.AppointmentColors + : _LocalColorTable; + } + + #endregion + + #region Static Color definitions + + // Array of predefined colors + + static ColorDef[] _LocalColorTable = new ColorDef[] + { + new ColorDef(0x4B71A2), // DefaultBorder + + new ColorDef(new int[] {0xFDFEFF, 0xC1D3EA}, // DefaultBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x28518E), // BlueBorder + + new ColorDef(new int[] {0xB1C5EC, 0x759DDA}, // BlueBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x2C6524), // GreenBorder + + new ColorDef(new int[] {0xC2E8BC, 0x84D17B}, // GreenBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x8B3E0A), // OrangeBorder + + new ColorDef(new int[] {0xF9C7A0, 0xF49758}, // OrangeBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x3E2771), // PurpleBorder + + new ColorDef(new int[] {0xC5B5E6, 0x957BD2}, // PurpleBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x86171C), // RedBorder + + new ColorDef(new int[] {0xF1AAAC, 0xE5676E}, // RedBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x7C7814), // YellowBorder + + new ColorDef(new int[] {0xFFFCAA, 0xFFF958}, // YellowBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(-1), // BusyTimeMarker + new ColorDef(0xFFFFFF), // FreeTimeMarker + new ColorDef(0x800080), // OutOfOfficeTimeMarker + }; + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarColor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarColor.cs new file mode 100644 index 00000000..a982364c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarColor.cs @@ -0,0 +1,439 @@ +#if FRAMEWORK20 +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Schedule +{ + //#region ColorDef + + ///// + ///// Color definition class + ///// + //[TypeConverter(typeof(ColorDefConvertor))] + //public class ColorDef + //{ + // #region Events + + // /// + // /// Event raised when the SuperTabColorStates is changed + // /// + // [Description("Event raised when the ColorDef is changed")] + // public event EventHandler ColorDefChanged; + + // #endregion + + // #region Private variables + + // private Color[] _Colors; // Color values + // private float[] _Positions; // Gradient color positions + // private float _Angle; // Gradient angle + + // #endregion + + // #region Constructors + + // public ColorDef() + // { + // } + + // /// + // /// Constructor - solid def + // /// + // /// RGB value + // public ColorDef(int rgb) + // : this(ColorScheme.GetColor(rgb)) + // { + // } + + // /// + // /// Constructor - solid def + // /// + // /// Color + // public ColorDef(Color color) + // { + // _Colors = new Color[1]; + + // _Colors[0] = color; + // _Positions = null; + // } + + // /// + // /// Constructor - 2 color def + // /// + // /// Start Color + // /// End Color + // public ColorDef(Color start, Color end) + // : this(start, end, 90f) + // { + // } + + // /// + // /// Constructor - 2 color def + // /// + // /// Start Color + // /// End Color + // /// Gradient angle + // public ColorDef(Color start, Color end, float angle) + // { + // _Colors = new Color[] { start, end }; + // _Positions = new float[] { 0, 1 }; + + // _Angle = angle; + // } + + // /// + // /// Constructor - Gradient def + // /// + // /// Array of RGB values + // /// Gradient positions + // public ColorDef(int[] rgbs, float[] cPositions) + // : this(rgbs, cPositions, 90f) + // { + // } + + // /// + // /// Constructor - Gradient def + // /// + // /// Array of Color values + // /// Gradient positions + // public ColorDef(Color[] colors, float[] cPositions) + // : this(colors, cPositions, 90f) + // { + // } + + // /// + // /// Constructor - Gradient def + // /// + // /// Array of RGB values + // /// Gradient positions + // /// Gradient angle + // public ColorDef(int[] rgbs, float[] cPositions, float angle) + // { + // _Colors = new Color[rgbs.Length]; + + // for (int i = 0; i < rgbs.Length; i++) + // _Colors[i] = ColorScheme.GetColor(rgbs[i]); + + // _Positions = cPositions; + // _Angle = angle; + // } + + // /// + // /// Constructor - Gradient def + // /// + // /// Array of Color values + // /// Gradient positions + // /// Gradient angle + // public ColorDef(Color[] colors, float[] cPositions, float angle) + // { + // _Colors = colors; + // _Positions = cPositions; + // _Angle = angle; + // } + + // #endregion + + // #region Public properties + + // #region Colors + + // /// + // /// Gets or sets the Color array + // /// + // [Browsable(true), DefaultValue(null)] + // [NotifyParentProperty(true)] + // [Description("Indicates the Color array")] + // public Color[] Colors + // { + // get { return (_Colors); } + // set { _Colors = value; OnColorDefChanged(); } + // } + + // #endregion + + // #region Positions + + // /// + // /// Gets or sets the Color Positions + // /// + // [Browsable(true), DefaultValue(null)] + // [NotifyParentProperty(true)] + // [Description("Indicates the Color Positions.")] + // public float[] Positions + // { + // get { return (_Positions); } + // set { _Positions = value; OnColorDefChanged(); } + // } + + // #endregion + + // #region Angle + + // /// + // /// Gets or sets the Gradient Angle + // /// + // [Browsable(true), DefaultValue(0f)] + // [NotifyParentProperty(true)] + // [Description("Indicates the Gradient Angle.")] + // public float Angle + // { + // get { return (_Angle); } + // set { _Angle = value; OnColorDefChanged(); } + // } + + // #endregion + + // #region IsEmpty + + // /// + // /// IsEmpty + // /// + // [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + // public bool IsEmpty + // { + // get { return (_Colors == null || + // _Colors.Length == 1 && _Colors[0].IsEmpty); } + // } + + // #endregion + + // #endregion + + // #region OnColorDefChanged + + // /// + // /// OnColorDefChanged + // /// + // private void OnColorDefChanged() + // { + // if (ColorDefChanged != null) + // ColorDefChanged(this, EventArgs.Empty); + // } + + // #endregion + //} + + //#region ColorDefConvertor + + ///// + ///// ColorDefConvertor + ///// + //public class ColorDefConvertor : ExpandableObjectConverter + //{ + // public override object ConvertTo( + // ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + // { + // if (destinationType == typeof(string)) + // { + // ColorDef cd = value as ColorDef; + + // if (cd != null) + // { + // ColorConverter cvt = new ColorConverter(); + + // if (cd.Colors != null) + // { + // if (cd.Colors[0] != Color.Empty) + // return (cvt.ConvertToString(cd.Colors[0])); + + // if (cd.Colors.Length > 1 && cd.Colors[1] != Color.Empty) + // return (cvt.ConvertToString(cd.Colors[1])); + // } + + // if (cd.Angle != 0) + // return (cd.Angle.ToString()); + // } + + // return (String.Empty); + // } + + // return (base.ConvertTo(context, culture, value, destinationType)); + // } + //} + + //#endregion + + //#endregion + + #region CalendarColor + + public class CalendarColor + { + #region Private variables + + private eCalendarColor _ColorSch; // Current color scheme enum + private ColorDef[] _ColorTable; // Color scheme definition + + #endregion + + /// + /// Constructor + /// + /// eCalendarColor + public CalendarColor(eCalendarColor colorSch) + { + _ColorSch = colorSch; + + SetColorTable(); + } + + #region Public properties + + /// + /// Gets and sets ColorTable + /// + public ColorDef[] ColorTable + { + get { return (_ColorTable); } + set { _ColorTable = value; } + } + + /// + /// Gets and sets calendar color scheme + /// + public eCalendarColor ColorSch + { + get { return (_ColorSch); } + + set + { + if (_ColorSch != value) + { + _ColorSch = value; + + SetColorTable(); + } + } + } + + #region SetColorTable + + public virtual void SetColorTable() + { + } + + #endregion + + #endregion + + #region Get Color + + /// + /// Gets the Color of the calendar part + /// + /// Calendar part + /// Color + public Color GetColor(int part) + { + return (_ColorTable[part].Colors[0]); + } + + #endregion + + #region GetColorDef + + /// + /// Gets the ColorDef of the part + /// + /// Calendar part + /// Part ColorDef + public ColorDef GetColorDef(int part) + { + return (_ColorTable[part]); + } + + #endregion + + #region BrushPart routines + + /// + /// Creates a LinearGradientBrush from the given part + /// + /// Color part + /// Gradient Rectangle + /// Created Brush + public Brush BrushPart(int part, Rectangle r) + { + return (BrushPart(GetColorDef(part), r)); + } + + /// + /// Creates a LinearGradientBrush from the given ColorDef + /// + /// ColorDef + /// Gradient Rectangle + /// Created Brush + public Brush BrushPart(ColorDef cDef, Rectangle r) + { + return (BrushPart(cDef, r, cDef.Angle)); + } + + /// + /// Creates a LinearGradientBrush from the given ColorDef + /// + /// ColorDef + /// Gradient Rectangle + /// Gradient angle + /// Created Brush + public Brush BrushPart(ColorDef cDef, Rectangle r, float angle) + { + if (cDef.Colors.Length == 1) + return (new SolidBrush(cDef.Colors[0])); + + LinearGradientBrush lbr = + new LinearGradientBrush(r, Color.White, Color.White, angle); + + lbr.InterpolationColors = GetColorBlend(cDef); + + return (lbr); + } + + /// + /// Creates a ColorBlend from the given ColorDef + /// + /// ColorDef for blend + /// ColorBlend + private ColorBlend GetColorBlend(ColorDef cDef) + { + ColorBlend cb = new ColorBlend(cDef.Colors.Length); + + // Set each Color and position from the + // provided color definition + + cb.Colors = cDef.Colors; + cb.Positions = GetPositions(cDef); + + return (cb); + } + + /// + /// Gets the array of color positions + /// + /// + /// + private float[] GetPositions(ColorDef cDef) + { + float[] cp = cDef.Positions; + + if (cp == null || cp.Length != cDef.Colors.Length) + { + cp = new float[cDef.Colors.Length]; + + float f = 1f / cDef.Colors.Length; + + for (int i = 0; i < cp.Length; i++) + cp[i] = i * f; + + cp[cDef.Colors.Length - 1] = 1; + } + + return (cp); + } + + #endregion + } + + #endregion +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarMonthColor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarMonthColor.cs new file mode 100644 index 00000000..44858963 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarMonthColor.cs @@ -0,0 +1,691 @@ +#if FRAMEWORK20 +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Schedule +{ + #region enum definitions + + /// + /// Month calendar parts enum + /// + public enum eCalendarMonthPart + { + DayOfTheWeekHeaderBorder, + DayOfTheWeekHeaderBackground, + DayOfTheWeekHeaderForeground, + + SideBarBorder, + SideBarBackground, + SideBarForeground, + + DayHeaderBorder, + DayHeaderBackground, + DayHeaderForeground, + + DayContentBorder, + DayContentSelectionBackground, + DayContentActiveBackground, + DayContactInactiveBackground, + + OwnerTabBorder, + OwnerTabBackground, + OwnerTabForeground, + OwnerTabContentBackground, + OwnerTabSelectedForeground, + OwnerTabSelectedBackground, + + NowDayHeaderBorder, + NowDayHeaderForeground, + NowDayHeaderBackground, + + ContentLinkForeground, + ContentLinkBackground, + } + + #endregion + + public class CalendarMonthColor : CalendarColor + { + #region Private variables + + private ColorDef[][] _LocalColorTable = + { _Blue, _Green, _Maroon, _Steel, _Teal, _Purple, _Olive, + _Red, _DarkPeach, _DarkSteel, _DarkGreen, _Yellow}; + + #endregion + + /// + /// Constructor + /// + /// Default color + public CalendarMonthColor(eCalendarColor eColor) + : base(eColor) + { + } + + #region SetColorTable routine + + /// + /// Sets our current color table to either + /// a local or global definition + /// + public override void SetColorTable() + { + if (ColorSch != eCalendarColor.Automatic) + { + // Use the requested local color table + + ColorTable = _LocalColorTable[(int)ColorSch]; + } + else + { + // Use the globally set color table + + Office2007Renderer r = + GlobalManager.Renderer as Office2007Renderer; + + ColorTable = (r != null) + ? r.ColorTable.CalendarView.MonthViewColors + : _LocalColorTable[(int)eCalendarColor.Blue]; + } + } + + #endregion + + #region Static Color definitions + + // Array of predefined color + + #region Blue + + static ColorDef[] _Blue = new ColorDef[] + { + new ColorDef(0x8DAED9), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xE4ECF6, 0xD6E2F1, 0xC2D4EB, 0xD0DEEF}, // DayOfWeekHeaderBackground + new float[] {0f, .6f, .6f, 1f}, 90f), + + new ColorDef(0x000000), // DayOfWeekHeaderForeground - 0x15428B + new ColorDef(0x5D8CC9), // SideBarBorder + + new ColorDef(new int[] {0xE4ECF6, 0xD6E2F1, 0xC2D4EB, 0xD0DEEF}, // SideBarBackground + new float[] {0f, .6f, .6f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground - 0x15428B + new ColorDef(0x5D8CC9), // DayHeaderBorder + + new ColorDef(new int[] {0xE4ECF6, 0xD6E2F1, 0xC2D4EB, 0xD0DEEF}, // DayHeaderBackground + new float[] {0f, .6f, .6f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0x8DAED9), // DayContentBorder + new ColorDef(0xE6EDF7), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xA5BFE1), // DayContentInactiveDayBackground + + new ColorDef(0x5D8CC9), // OwnerTabBorder + + new ColorDef(new int[] {0xBBCFE9, 0x8DAED9}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x8DAED9), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region Green + + static ColorDef[] _Green = new ColorDef[] + { + new ColorDef(0x72A45A), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xE7F0E4, 0xDDE8D7, 0xCCDEC2, 0xD8E5D0}, // DayOfWeekHeaderBackground + new float[] {0f, .6f, .6f, 1f}, 90f), + + new ColorDef(0x50734D), // DayOfWeekHeaderForeground + new ColorDef(0x72A45A), // SideBarBorder + + new ColorDef(new int[] {0xE7F0E4, 0xDEE9D8, 0xCBDDC2, 0xD7E5D0}, // SideBarBackground + new float[] {0f, .6f, .6f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x50733F), // DayHeaderBorder + + new ColorDef(new int[] {0xE7F0E4, 0xDDE8D7, 0xCCDEC2, 0xD8E5D0}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0x72A45A), // DayContentBorder + new ColorDef(0xE9F1E6), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xB1CDA4), // DayContentInactiveDayBackground + + new ColorDef(0x72A45A), // OwnerTabBorder + + new ColorDef(new int[] {0xC3D9B9, 0x9CBF8B}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x9CBF8B), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region Maroon + + static ColorDef[] _Maroon = new ColorDef[] + { + new ColorDef(0x85495E), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xF4E6EB, 0xEFDAE2, 0xE6C6D2, 0xEDD4DD}, // DayOfWeekHeaderBackground + new float[] {0f, .6f, .6f, 1f}, 90f), + + new ColorDef(0x85496B), // DayOfWeekHeaderForeground + new ColorDef(0xBE6886), // SideBarBorder + + new ColorDef(new int[] {0xF4E6EB, 0xF0DBE3, 0xE7C7D3, 0xECD4DD}, // SideBarBackground + new float[] {0f, .6f, .6f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x85495E), // DayHeaderBorder + + new ColorDef(new int[] {0xF4E6EB, 0xEFDAE2, 0xE6C6D2, 0xEDD4DD}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0xBE6886), // DayContentBorder + new ColorDef(0xF5E8EC), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xDBACBC), // DayContentInactiveDayBackground + + new ColorDef(0xBE6886), // OwnerTabBorder + + new ColorDef(new int[] {0xE4BFCB, 0xD195AA}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xD195AA), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region Steel + + static ColorDef[] _Steel = new ColorDef[] + { + new ColorDef(0x9199A4), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xDCDFE2, 0xD3D6DA, 0xB4BAC1, 0xCBCED4}, // DayOfWeekHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x616A76), // DayOfWeekHeaderForeground + new ColorDef(0x9199A4), // SideBarBorder + + new ColorDef(new int[] {0xDCDFE2, 0xD2D5DA, 0xB7BCC3, 0xCACED4}, // SideBarBackground + new float[] {0f, .6f, .6f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x9199A4), // DayHeaderBorder + + new ColorDef(new int[] {0xDCDFE2, 0xD3D6DA, 0xB4BAC1, 0xCBCED4}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0x9199A4), // DayContentBorder + new ColorDef(0xE8EAEC), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xC7CBD1), // DayContentInactiveDayBackground + + new ColorDef(0x9199A4), // OwnerTabBorder + + new ColorDef(new int[] {0xCFD2D8, 0xB0B6BE}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xB0B6BE), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region Teal + + static ColorDef[] _Teal = new ColorDef[] + { + new ColorDef(0x3F7373), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xDCDFE2, 0xD7E8E8, 0xC0DDDD, 0xD0E5E5}, // DayOfWeekHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x3F7380), // DayOfWeekHeaderForeground + new ColorDef(0x5AA4A4), // SideBarBorder + + new ColorDef(new int[] {0xE4F0F0, 0xD6E8E8, 0xC2DDDD, 0xD0E5E5}, // SideBarBackground + new float[] {0f, .6f, .6f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x3F7373), // DayHeaderBorder + + new ColorDef(new int[] {0xDCDFE2, 0xD7E8E8, 0xC0DDDD, 0xD0E5E5}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0x5AA4A4), // DayContentBorder + new ColorDef(0xE6F1F1), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xA4CDCD), // DayContentInactiveDayBackground + + new ColorDef(0x5AA4A4), // OwnerTabBorder + + new ColorDef(new int[] {0xB9D9D9, 0x8CBFC0}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x8CBFC0), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region Purple + + static ColorDef[] _Purple = new ColorDef[] + { + new ColorDef(0x7171CD), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xE6E6F6, 0xDCDCF2, 0xC9C9EC, 0xD7D7F0}, // DayOfWeekHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x4F4F90), // DayOfWeekHeaderForeground + new ColorDef(0x7171CD), // SideBarBorder + + new ColorDef(new int[] {0xE6E6F6, 0xDCDCF2, 0xC9C9EC, 0xD7D7F0}, // SideBarBackground + new float[] {0f, .55f, .58f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x4F4F90), // DayHeaderBorder + + new ColorDef(new int[] {0xE6E6F6, 0xDCDCF2, 0xC9C9EC, 0xD7D7F0}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0x7171CD), // DayContentBorder + new ColorDef(0xE9E9F7), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0x9B9BDC), // DayContentInactiveDayBackground + + new ColorDef(0x7171CD), // OwnerTabBorder + + new ColorDef(new int[] {0xC1C1EA, 0x8C8CD7}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x8C8CD7), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region Olive + + static ColorDef[] _Olive = new ColorDef[] + { + new ColorDef(0x9D9D57), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xEFEFE3, 0xE8E8D8, 0xDADABF, 0xE3E3CF}, // DayOfWeekHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x6E6E3D), // DayOfWeekHeaderForeground + new ColorDef(0x9D9D57), // SideBarBorder + + new ColorDef(new int[] {0xEFEFE3, 0xE8E8D8, 0xDADABF, 0xE3E3CF}, // SideBarBackground + new float[] {0f, .55f, .58f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x6E6E3D), // DayHeaderBorder + + new ColorDef(new int[] {0xEFEFE3, 0xE8E8D8, 0xDADABF, 0xE3E3CF}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0x9D9D57), // DayContentBorder + new ColorDef(0xF0F0E5), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xC9C9A2), // DayContentInactiveDayBackground + + new ColorDef(0x9D9D57), // OwnerTabBorder + + new ColorDef(new int[] {0xD5D5B8, 0xBABA89}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xBABA89), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region Red + + static ColorDef[] _Red = new ColorDef[] + { + new ColorDef(0xC16969), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xF5E6E6, 0xEFDADA, 0xE7C6C6, 0xEDD4D4}, // DayOfWeekHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x874A4A), // DayOfWeekHeaderForeground + new ColorDef(0xC16969), // SideBarBorder + + new ColorDef(new int[] {0xF5E6E6, 0xEFDADA, 0xE7C6C6, 0xEDD4D4}, // SideBarBackground + new float[] {0f, .55f, .58f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x874A4A), // DayHeaderBorder + + new ColorDef(new int[] {0xF5E6E6, 0xEFDADA, 0xE7C6C6, 0xEDD4D4}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0xC16969), // DayContentBorder + new ColorDef(0xF6E8E8), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xDDACAC), // DayContentInactiveDayBackground + + new ColorDef(0xC16969), // OwnerTabBorder + + new ColorDef(new int[] {0xE5BFBF, 0xD39696}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xD39696), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region DarkPeach + + static ColorDef[] _DarkPeach = new ColorDef[] + { + new ColorDef(0xA98F5D), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xF1EDE4, 0xE9E4D7, 0xDFD5C1, 0xE6E0D1}, // DayOfWeekHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x776441), // DayOfWeekHeaderForeground + new ColorDef(0xA98F5D), // SideBarBorder + + new ColorDef(new int[] {0xF1EDE4, 0xDFD5C1, 0xDFD5C1, 0xE6E0D1}, // SideBarBackground + new float[] {0f, .55f, .58f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x776441), // DayHeaderBorder + + new ColorDef(new int[] {0xF1EDE4, 0xE9E4D7, 0xDFD5C1, 0xE6E0D1}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0xA98F5D), // DayContentBorder + new ColorDef(0xF2EEE6), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xCFC1A5), // DayContentInactiveDayBackground + + new ColorDef(0xA98F5D), // OwnerTabBorder + + new ColorDef(new int[] {0xDBCFBA, 0xC3B08D}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xC3B08D), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region DarkSteel + + static ColorDef[] _DarkSteel = new ColorDef[] + { + new ColorDef(0x6197B1), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xE5EEF2, 0xD8E5EB, 0xC3D7E1, 0xD2E2E9}, // DayOfWeekHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x446A96), // DayOfWeekHeaderForeground + new ColorDef(0x6197B1), // SideBarBorder + + new ColorDef(new int[] {0xE5EEF2, 0xD8E5EB, 0xC3D7E1, 0xD2E2E9}, // SideBarBackground + new float[] {0f, .55f, .58f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x446A7C), // DayHeaderBorder + + new ColorDef(new int[] {0xE5EEF2, 0xD8E5EB, 0xC3D7E1, 0xD2E2E9}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0x6197B1), // DayContentBorder + new ColorDef(0xE7EFF3), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xA8C5D4), // DayContentInactiveDayBackground + + new ColorDef(0x6197B1), // OwnerTabBorder + + new ColorDef(new int[] {0xBCD2DE, 0x90B6C8}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x90B6C8), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region DarkGreen + + static ColorDef[] _DarkGreen = new ColorDef[] + { + new ColorDef(0x5AA48C), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xE4F0EC, 0xD7E8E3, 0xC0DDD4, 0xD0E5DF}, // DayOfWeekHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x3F7362), // DayOfWeekHeaderForeground + new ColorDef(0x5AA48C), // SideBarBorder + + new ColorDef(new int[] {0xE4F0EC, 0xD7E8E3, 0xC0DDD4, 0xD0E5DF}, // SideBarBackground + new float[] {0f, .55f, .58f, 1f}, 0f), + + new ColorDef(0x000000), // SideBarForeground + new ColorDef(0x3F7362), // DayHeaderBorder + + new ColorDef(new int[] {0xE4F0EC, 0xD7E8E3, 0xC0DDD4, 0xD0E5DF}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0x5AA48C), // DayContentBorder + new ColorDef(0xE6F1ED), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xA4CDBF), // DayContentInactiveDayBackground + + new ColorDef(0x5AA48C), // OwnerTabBorder + + new ColorDef(new int[] {0xB9D9CE, 0x8BBFAE}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x8BBFAE), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #region Yellow + + static ColorDef[] _Yellow = new ColorDef[] + { + new ColorDef(0xFFD151), // DayOfWeekHeaderBorder + + new ColorDef(new int[] {0xFFF8E2, 0xFFF5D7, 0xFFEDBD, 0xFFF2CE}, // DayOfWeekHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x7F6628), // DayOfWeekHeaderForeground + new ColorDef(0xFFD151), // SideBarBorder + + new ColorDef(new int[] {0xFFF8E2, 0xFFF5D7, 0xFFEDBD, 0xFFF2CE}, // SideBarBackground + new float[] {0f, .55f, .58f, 1f}, 0f), + + new ColorDef(0x7F6628), // SideBarForeground + new ColorDef(0xD3AC40), // DayHeaderBorder + + new ColorDef(new int[] {0xFFF8E2, 0xFFF5D7, 0xFFEDBD, 0xFFF2CE}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x000000), // DayHeaderForeground + new ColorDef(0xFFD151), // DayContentBorder + new ColorDef(0xFFF8E4), // DayContentSelectionBackground + new ColorDef(0xFFFFFF), // DayContentActiveDayBackground + new ColorDef(0xFFE69F), // DayContentInactiveDayBackground + + new ColorDef(0xFFD151), // OwnerTabBorder + + new ColorDef(new int[] {0xFFEBB6, 0xFFDF86}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xFFDF86), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(0x000000), // ContentLinkForeground - DayHeaderForeground + new ColorDef(0xFFFFFF), // ContentLinkBackground - DayContentActiveBackground + }; + + #endregion + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarViewColor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarViewColor.cs new file mode 100644 index 00000000..6aadee11 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarViewColor.cs @@ -0,0 +1,73 @@ +#if FRAMEWORK20 +namespace DevComponents.DotNetBar.Schedule +{ + #region enum definitions + + #region eCalendarViewPart + + /// + /// View calendar parts enum + /// + public enum eCalendarViewPart + { + OwnerTabBorder, + OwnerTabBackground, + OwnerTabForeground, + OwnerTabContentBackground + } + + #endregion + + #region eCalendarColor + + /// + /// Defines available custom calendar color + /// + public enum eCalendarColor + { + Blue, + Green, + Maroon, + Steel, + Teal, + Purple, + Olive, + Red, + DarkPeach, + DarkSteel, + DarkGreen, + Yellow, + + Automatic + } + + #endregion + + #endregion + + public class CalendarViewColor : CalendarColor + { + /// + /// Constructor + /// + /// Default color + public CalendarViewColor(eCalendarColor eColor) + : base(eColor) + { + } + + #region SetColorTable routine + + /// + /// Sets our current color table to either + /// a local or global definition + /// + public override void SetColorTable() + { + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarWeekDayColor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarWeekDayColor.cs new file mode 100644 index 00000000..135d675a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/CalendarWeekDayColor.cs @@ -0,0 +1,667 @@ +#if FRAMEWORK20 +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Schedule +{ + #region enum definitions + + /// + /// Week/Day calendar parts enum + /// + public enum eCalendarWeekDayPart : int + { + DayViewBorder, + + DayHeaderForeground, + DayHeaderBackground, + DayHeaderBorder, + + DayWorkHoursBackground, + DayAllDayEventBackground, + DayOffWorkHoursBackground, + + DayHourBorder, + DayHalfHourBorder, + + SelectionBackground, + + OwnerTabBorder, + OwnerTabBackground, + OwnerTabForeground, + OwnerTabContentBackground, + OwnerTabSelectedForeground, + OwnerTabSelectedBackground, + + CondensedViewBackground, + + NowDayHeaderBorder, + NowDayHeaderForeground, + NowDayHeaderBackground, + + TimeIndicator, + TimeIndicatorBorder + } + + #endregion + + public class CalendarWeekDayColor : CalendarColor + { + #region Private variables + + private ColorDef[][] _LocalColorTable = + { _Blue, _Green, _Maroon, _Steel, _Teal, _Purple, _Olive, + _Red, _DarkPeach, _DarkSteel, _DarkGreen, _Yellow}; + + #endregion + + /// + /// Constructor + /// + /// Default color + public CalendarWeekDayColor(eCalendarColor eColor) + : base(eColor) + { + } + + #region SetColorTable routine + + /// + /// Sets our current color table to either + /// a local or global definition + /// + public override void SetColorTable() + { + if (ColorSch != eCalendarColor.Automatic) + { + // Use the requested local color table + + ColorTable = _LocalColorTable[(int)ColorSch]; + } + else + { + // Use the globally set color table + + Office2007Renderer r = + GlobalManager.Renderer as Office2007Renderer; + + ColorTable = (r != null) + ? r.ColorTable.CalendarView.WeekDayViewColors + : _LocalColorTable[(int)eCalendarColor.Blue]; + } + } + + #endregion + + #region Static Color definitions + + // Array of predefined color + + #region Blue + + static ColorDef[] _Blue = new ColorDef[] + { + new ColorDef(0x5D8CC9), // DayViewBorder + new ColorDef(0x000000), // DayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xE4ECF6, 0xD6E2F1, 0xC2D4EB, 0xD0DEEF}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x8DAED9), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0x8DAED9), // DayAllDayEventBackground + new ColorDef(0xE6EDF7), // DayOffWorkHoursBackground + + new ColorDef(0xA5BFE1), // DayHourBorder + new ColorDef(0xD5E1F1), // DayHalfHourBorder + + new ColorDef(0x294C7A), // SelectionBackground + + new ColorDef(0x5D8CC9), // OwnerTabBorder + + new ColorDef(new int[] {0xBBCFE9, 0x8DAED9}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x8DAED9), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region Green + + static ColorDef[] _Green = new ColorDef[] + { + new ColorDef(0x72A45A), // DayViewBorder + new ColorDef(0x50734D), // DayHeaderForeground + + new ColorDef(new int[] {0xE7F0E4, 0xDDE8D7, 0xCADDC0, 0xD8E5D0}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x72A45A), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xB1CDA4), // DayAllDayEventBackground + new ColorDef(0xE9F1E6), // DayOffWorkHoursBackground + + new ColorDef(0xB1CDA4), // DayHourBorder + new ColorDef(0xD6DDD2), // DayHalfHourBorder + + new ColorDef(0x3F5B32), // SelectionBackground + + new ColorDef(0x72A45A), // OwnerTabBorder + + new ColorDef(new int[] {0xC3D9B9, 0x9CBF8B}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x9CBF8B), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region Maroon + + static ColorDef[] _Maroon = new ColorDef[] + { + new ColorDef(0xBE6886), // DayViewBorder + new ColorDef(0x85496B), // DayHeaderForeground + + new ColorDef(new int[] {0xF4E6EB, 0xEFDAE2, 0xE7C8D3, 0xEDD4DD}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0xBE6886), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xDBACBC), // DayAllDayEventBackground + new ColorDef(0xF5E8EC), // DayOffWorkHoursBackground + + new ColorDef(0xDBACBC), // DayHourBorder + new ColorDef(0xE5D3D9), // DayHalfHourBorder + + new ColorDef(0x693A4A), // SelectionBackground + + new ColorDef(0xBE6886), // OwnerTabBorder + + new ColorDef(new int[] {0xE4BFCB, 0xD195AA}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xD195AA), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region Steel + + static ColorDef[] _Steel = new ColorDef[] + { + new ColorDef(0x616A76), // DayViewBorder + new ColorDef(0x616A76), // DayHeaderForeground + + new ColorDef(new int[] {0xDCDFE2, 0xD3D6DA, 0xB4BAC1, 0xCBCED4}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x9199A4), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xC7CBD1), // DayAllDayEventBackground + new ColorDef(0xE8EAEC), // DayOffWorkHoursBackground + + new ColorDef(0xC7CBD1), // DayHourBorder + new ColorDef(0xDDDDDD), // DayHalfHourBorder + + new ColorDef(0x4C535C), // SelectionBackground + + new ColorDef(0x9199A4), // OwnerTabBorder + + new ColorDef(new int[] {0xCFD2D8, 0xB0B6BE}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xB0B6BE), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region Teal + + static ColorDef[] _Teal = new ColorDef[] + { + new ColorDef(0x5AA4A4), // DayViewBorder + new ColorDef(0x3F7380), // DayHeaderForeground + + new ColorDef(new int[] {0xE4F0F0, 0xD7E8E8, 0xC0DDDD, 0xD0E5E5}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x8CBFC0), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xA4CDCD), // DayAllDayEventBackground + new ColorDef(0xE6F1F1), // DayOffWorkHoursBackground + + new ColorDef(0xA4CDCD), // DayHourBorder + new ColorDef(0xD2DDDD), // DayHalfHourBorder + + new ColorDef(0x325B5B), // SelectionBackground + + new ColorDef(0x5AA4A4), // OwnerTabBorder + + new ColorDef(new int[] {0xB9D9D9, 0x8CBFC0}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x8CBFC0), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region Purple + + static ColorDef[] _Purple = new ColorDef[] + { + new ColorDef(0x7171CD), // DayViewBorder + new ColorDef(0x4F4F90), // DayHeaderForeground + + new ColorDef(new int[] {0xE7E7F6, 0xDCDCF2, 0xC9C9EC, 0xD7D7F0}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x8C8CD7), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0x9B9BDC), // DayAllDayEventBackground + new ColorDef(0xE9E9F7), // DayOffWorkHoursBackground + + new ColorDef(0x9B9BDC), // DayHourBorder + new ColorDef(0xD5D5E8), // DayHalfHourBorder + + new ColorDef(0x3E3E71), // SelectionBackground + + new ColorDef(0x7171CD), // OwnerTabBorder + + new ColorDef(new int[] {0xC1C1EA, 0x8C8CD7}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x8C8CD7), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region Olive + + static ColorDef[] _Olive = new ColorDef[] + { + new ColorDef(0x9D9D57), // DayViewBorder + new ColorDef(0x6E6E3D), // DayHeaderForeground + + new ColorDef(new int[] {0xEFEFE3, 0xE8E8D8, 0xDADABF, 0xE3E3CF}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0xBABA89), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xC9C9A2), // DayAllDayEventBackground + new ColorDef(0xF0F0E5), // DayOffWorkHoursBackground + + new ColorDef(0xC9C9A2), // DayHourBorder + new ColorDef(0xDBDBD0), // DayHalfHourBorder + + new ColorDef(0x575730), // SelectionBackground + + new ColorDef(0x9D9D57), // OwnerTabBorder + + new ColorDef(new int[] {0xD5D5B8, 0xBABA89}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xBABA89), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region Red + + static ColorDef[] _Red = new ColorDef[] + { + new ColorDef(0xC16969), // DayViewBorder + new ColorDef(0x874A4A), // DayHeaderForeground + + new ColorDef(new int[] {0xF5E6E6, 0xEFDADA, 0xE7C6C6, 0xEDD4D4}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0xD39696), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xDDACAC), // DayAllDayEventBackground + new ColorDef(0xF6E8E8), // DayOffWorkHoursBackground + + new ColorDef(0xDDACAC), // DayHourBorder + new ColorDef(0xE8D7D7), // DayHalfHourBorder + + new ColorDef(0x6B3A3A), // SelectionBackground + + new ColorDef(0xC16969), // OwnerTabBorder + + new ColorDef(new int[] {0xE5BFBF, 0xD39696}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xD39696), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region DarkPeach + + static ColorDef[] _DarkPeach = new ColorDef[] + { + new ColorDef(0xA98F5D), // DayViewBorder + new ColorDef(0x776441), // DayHeaderForeground + + new ColorDef(new int[] {0xF1EDE4, 0xE9E4D7, 0xDFD5C1, 0xE6E0D1}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0xC3B08D), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xCFC1A5), // DayAllDayEventBackground + new ColorDef(0xF2EEE6), // DayOffWorkHoursBackground + + new ColorDef(0xCFC1A5), // DayHourBorder + new ColorDef(0xE0D7C5), // DayHalfHourBorder + + new ColorDef(0x5D4F33), // SelectionBackground + + new ColorDef(0xA98F5D), // OwnerTabBorder + + new ColorDef(new int[] {0xDBCFBA, 0xC3B08D}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xC3B08D), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region DarkSteel + + static ColorDef[] _DarkSteel = new ColorDef[] + { + new ColorDef(0x6197B1), // DayViewBorder + new ColorDef(0x446A96), // DayHeaderForeground + + new ColorDef(new int[] {0xE5EEF2, 0xD8E5EB, 0xC3D7E1, 0xD2E2E9}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x90B6C8), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xA8C5D4), // DayAllDayEventBackground + new ColorDef(0xE7EFF3), // DayOffWorkHoursBackground + + new ColorDef(0xA8C5D4), // DayHourBorder + new ColorDef(0xDCE5E3), // DayHalfHourBorder + + new ColorDef(0x365362), // SelectionBackground + + new ColorDef(0x6197B1), // OwnerTabBorder + + new ColorDef(new int[] {0xBCD2DE, 0x90B6C8}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x90B6C8), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region DarkGreen + + static ColorDef[] _DarkGreen = new ColorDef[] + { + new ColorDef(0x5AA48C), // DayViewBorder + new ColorDef(0x3F7362), // DayHeaderForeground + + new ColorDef(new int[] {0xE4F0EC, 0xD7E8E3, 0xC0DDD4, 0xD0E5DF}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0x8BBFAE), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xA4CDBF), // DayAllDayEventBackground + new ColorDef(0xE6F1ED), // DayOffWorkHoursBackground + + new ColorDef(0xA4CDBF), // DayHourBorder + new ColorDef(0xD0DDD9), // DayHalfHourBorder + + new ColorDef(0x325B4D), // SelectionBackground + + new ColorDef(0x5AA48C), // OwnerTabBorder + + new ColorDef(new int[] {0xB9D9CE, 0x8BBFAE}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0x8BBFAE), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #region Yellow + + static ColorDef[] _Yellow = new ColorDef[] + { + new ColorDef(0xFFD151), // DayViewBorder + new ColorDef(0x7F6628), // DayHeaderForeground + + new ColorDef(new int[] {0xFFF8E2, 0xFFF5D7, 0xFFEDBD, 0xFFF2CE}, // DayHeaderBackground + new float[] {0f, .55f, .58f, 1f}, 90f), + + new ColorDef(0xFFDF86), // DayHeaderBorder + + new ColorDef(0xFFFFFF), // DayWorkHoursBackground + new ColorDef(0xFFE69F), // DayAllDayEventBackground + new ColorDef(0xFFF8E4), // DayOffWorkHoursBackground + + new ColorDef(0xFFE69F), // DayHourBorder + new ColorDef(0xFFE69F), // DayHalfHourBorder + + new ColorDef(0xB39540), // SelectionBackground + + new ColorDef(0xFFD151), // OwnerTabBorder + + new ColorDef(new int[] {0xFFEBB6, 0xFFDF86}, // OwnerTabBackground + new float[] {0f, 1f}, 90f), + + new ColorDef(0x000000), // OwnerTabForeground + new ColorDef(0xFFDF86), // OwnerTabContentBackground + new ColorDef(0x000000), // OwnerTabSelectedForeground + new ColorDef(0xFFFFFF), // OwnerTabSelectionBackground + + new ColorDef(0xF5F5F5), // CondensedViewBackground + + new ColorDef(0xEB8900), // NowDayViewBorder + new ColorDef(0x000000), // NowDayHeaderForeground - 0x15428B + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // NowDayHeaderBackground + new float[] {0f, .55f, .058f, 1f}, 90f), + + new ColorDef(new int[] {0xFFED79, 0xFFD86B, 0xFFBB00, 0xFFEA77}, // TimeIndicator + new float[] {0f, .55f ,58f, 1f}, 90f), + + new ColorDef(0xEB8900), // TimeIndicatorBorder + }; + + #endregion + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/TimeRulerColor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/TimeRulerColor.cs new file mode 100644 index 00000000..4f9a780d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Color/TimeRulerColor.cs @@ -0,0 +1,54 @@ +#if FRAMEWORK20 +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Schedule +{ + #region enum definitions + + /// + /// Week/Day calendar parts enum + /// + public enum eTimeRulerPart : int + { + TimeRulerBackground, + TimeRulerForeground, + TimeRulerBorder, + TimeRulerTickBorder, + + TimeRulerIndicator, + TimeRulerIndicatorBorder + } + + #endregion + + public class TimeRulerColor : CalendarColor + { + /// + /// Constructor + /// + public TimeRulerColor() + : base(eCalendarColor.Automatic) + { + } + + #region SetColorTable routine + + /// + /// Sets our current color table to either + /// a local or global definition + /// + public override void SetColorTable() + { + // Use the globally set color table + + Office2007Renderer r = + GlobalManager.Renderer as Office2007Renderer; + + if (r != null) + ColorTable = r.ColorTable.CalendarView.TimeRulerColors; + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CustomCalendarItem.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CustomCalendarItem.cs new file mode 100644 index 00000000..6a895d9f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CustomCalendarItem.cs @@ -0,0 +1,480 @@ +#if FRAMEWORK20 +using System; +using System.Windows.Forms; +using DevComponents.Schedule.Model; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Schedule +{ + public class CustomCalendarItem : CalendarItem + { + #region Events + + /// + /// Occurs when the OwnerKey has changed + /// + [Description("Occurs when the OwnerKey has changed.")] + public event EventHandler OwnerKeyChanged; + + /// + /// Occurs when Locked has changed + /// + [Description("Occurs when the Locked property has changed.")] + public event EventHandler LockedChanged; + + #endregion + + #region Private variables + + private string _OwnerKey = ""; // OwnerKey + private bool _Locked; // Locked state + + private CustomCalendarItem _BaseCalendarItem; // Base CalendarItem + private CalendarView _CalendarView; + + #endregion + + #region Public properties + + #region CollateId + + /// + /// Gets or sets the CollateId used for TimeLine row collation. + /// + public override int CollateId + { + get + { + if (_BaseCalendarItem != null) + return (_BaseCalendarItem.CollateId); + + return (base.CollateId); + } + + set + { + if (_BaseCalendarItem != null) + _BaseCalendarItem.CollateId = value; + + base.CollateId = value; + } + } + + #endregion + + #region OwnerKey + + /// + /// Gets and sets the item OwnerKey + /// + public string OwnerKey + { + get + { + if (_BaseCalendarItem != null) + return (_BaseCalendarItem.OwnerKey); + + return (_OwnerKey); + } + + set + { + if (_BaseCalendarItem != null) + { + _BaseCalendarItem.OwnerKey = value; + } + else + { + if (value == null) + value = ""; + + if (_OwnerKey.Equals(value) == false) + { + string oldValue = _OwnerKey; + _OwnerKey = value; + + OnOwnerKeyChanged(oldValue, value); + } + } + } + } + + /// + /// Sends ChangedEvent for the OwnerKey property + /// + /// Old OwnerKey + /// New OwnerKey + protected virtual void OnOwnerKeyChanged(string oldValue, string newValue) + { + if (OwnerKeyChanged != null) + OwnerKeyChanged(this, new OwnerKeyChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region Locked + + /// + /// Gets and set whether modification is enabled + /// through the user interface" + /// + public bool Locked + { + get + { + if (_BaseCalendarItem != null) + return (_BaseCalendarItem.Locked); + + return (_Locked); + } + + set + { + if (_BaseCalendarItem != null) + { + _BaseCalendarItem.Locked = value; + } + else + { + if (_Locked != value) + { + bool oldValue = _Locked; + _Locked = value; + + OnLockedChanged(oldValue, value); + } + } + } + } + + /// + /// Sends ChangedEvent for the Locked property + /// + /// Old OwnerKey + /// New OwnerKey + protected virtual void OnLockedChanged(bool oldValue, bool newValue) + { + if (LockedChanged != null) + LockedChanged(this, new LockedChangedEventArgs(oldValue, newValue)); + } + + #endregion + + #region StartTime + + public override DateTime StartTime + { + get + { + if (_BaseCalendarItem != null) + return (_BaseCalendarItem.StartTime); + + return (base.StartTime); + } + + set + { + if (_BaseCalendarItem != null) + _BaseCalendarItem.StartTime = value; + + base.StartTime = value; + } + } + + #endregion + + #region EndTime + + public override DateTime EndTime + { + get + { + if (_BaseCalendarItem != null) + return (_BaseCalendarItem.EndTime); + + return (base.EndTime); + } + + set + { + if (_BaseCalendarItem != null) + _BaseCalendarItem.EndTime = value; + + base.EndTime = value; + } + } + + #endregion + + #region BaseCalendarItem + + /// + /// Base CalendarItem + /// + /// This property holds the base CalendarItem from which + /// each displayed CustomItem (of this type) is based. + /// + /// In order to keep all displayed items "in-sync", it is necessary + /// to propagate data to and from the base CalendarItem. This is + /// accomplished via hooking those members you are interested in, at + /// both the item (HookEvents) and BaseCalendarItem (HookBaseEvents) + /// level. + /// + /// + public virtual CustomCalendarItem BaseCalendarItem + { + get { return (_BaseCalendarItem); } + set { _BaseCalendarItem = value; } + } + + #endregion + + #region IsMultiDayOrAllDayEvent + + public bool IsMultiDayOrAllDayEvent + { + get + { + return (StartTime < EndTime && + (EndTime.Subtract(StartTime).TotalDays >= 1 || + DateTimeHelper.IsSameDay(StartTime, EndTime) == false)); + } + } + + #endregion + + #region CategoryColor + + /// + /// Gets or sets the category color used for TimeLine CondensedView markers. + /// Use static members on Appointment class to assign the category color for example Appointment.CategoryRed. + /// + public override string CategoryColor + { + get + { + if (_BaseCalendarItem != null) + return (_BaseCalendarItem.CategoryColor); + + return (base.CategoryColor); + } + + set + { + if (_BaseCalendarItem != null) + _BaseCalendarItem.CategoryColor = value; + + base.CategoryColor = value; + } + } + + #endregion + + #region IsSelected + + /// + /// Gets or sets whether the item is selected. + /// + public override bool IsSelected + { + get + { + if (_BaseCalendarItem != null) + return (_BaseCalendarItem.IsSelected); + + return (base.IsSelected); + } + + set + { + if (_BaseCalendarItem != null) + _BaseCalendarItem.IsSelected = value; + + base.IsSelected = value; + } + } + + #endregion + + #region Visible + + /// + /// Gets and sets the item Visibility + /// + public override bool Visible + { + get + { + if (_BaseCalendarItem != null) + return (_BaseCalendarItem.Visible); + + return (base.Visible); + } + + set + { + if (_BaseCalendarItem != null) + { + _BaseCalendarItem.Visible = value; + } + else + { + if (_BaseCalendarItem != null) + _BaseCalendarItem.Visible = value; + + base.Visible = value; + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region CalendarView + + internal CalendarView CalendarView + { + get { return (_CalendarView); } + set { _CalendarView = value; } + } + + #endregion + + #endregion + + #region Refresh + + public override void Refresh() + { + if (_CalendarView != null) + { + Control c = (Control)_CalendarView.GetContainerControl(); + + if (c != null) + { + foreach (BaseItem item in _CalendarView.CalendarPanel.SubItems) + { + BaseView view = item as BaseView; + + if (view != null) + RefreshItems(c, view.SubItems); + } + } + } + } + + private void RefreshItems(Control c, SubItemsCollection subItems) + { + foreach (BaseItem item in subItems) + { + CustomCalendarItem ci = item as CustomCalendarItem; + + if (ci != null) + { + if (ci == this || ci.BaseCalendarItem == this) + ci.Invalidate(c); + } + else if (item is AllDayPanel) + { + RefreshItems(c, item.SubItems); + } + } + } + + #endregion + + #region Paint + + public override void Paint(ItemPaintArgs e) + { + } + + #endregion + + #region Copy + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + CustomCalendarItem objCopy = new CustomCalendarItem(); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the CustomCalendarItem specific properties to new instance of the item. + /// + /// New CustomCalendarItem instance + protected override void CopyToItem(BaseItem copy) + { + CustomCalendarItem objCopy = copy as CustomCalendarItem; + + if (objCopy != null) + { + base.CopyToItem(objCopy); + + objCopy._OwnerKey = this._OwnerKey; + objCopy._Locked = this.Locked; + objCopy._CalendarView = this.CalendarView; + } + } + + #endregion + } + + #region OwnerKeyChangedEventArgs + + /// + /// OwnerKeyChangedEventArgs + /// + /// + public class OwnerKeyChangedEventArgs : ValueChangedEventArgs + { + public OwnerKeyChangedEventArgs(string oldValue, string newValue) + : base(oldValue, newValue) + { + } + } + + #endregion + + #region LockedChangedEventArgs + + /// + /// LockedChangedEventArgs + /// + /// + public class LockedChangedEventArgs : ValueChangedEventArgs + { + public LockedChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + + #endregion + + #region CategoryColorChangedEventArgs + + /// + /// CategoryColorChangedEventArgs + /// + /// + public class CategoryColorChangedEventArgs : ValueChangedEventArgs + { + public CategoryColorChangedEventArgs(string oldValue, string newValue) + : base(oldValue, newValue) + { + } + } + + #endregion + +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CustomCalendarItemCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CustomCalendarItemCollection.cs new file mode 100644 index 00000000..1be60e38 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/CustomCalendarItemCollection.cs @@ -0,0 +1,288 @@ +#if FRAMEWORK20 +using System; +using System.Collections.ObjectModel; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Schedule +{ + public class CustomCalendarItemCollection : Collection, IDisposable + { + #region Events + + /// + /// Occurs when the collection has changed + /// + [Description("Occurs when the collection has changed.")] + public event EventHandler CollectionChanged; + + #endregion + + #region Private variables + + private int _UpdateCount; + + #endregion + + #region AddRange + + /// + /// Adds a range of CustomCalendarItems to the collection + /// + /// Array of items to add + public void AddRange(CustomCalendarItem[] items) + { + for (int i = 0; i < items.Length; i++) + Add(items[i]); + + OnCollectionChanged(); + } + + #endregion + + #region Remove + + /// + /// Removes a CustomCalendarItem from + /// the collection. + /// + /// Item to remove + public new void Remove(CustomCalendarItem item) + { + if (item.BaseCalendarItem != null) + item = item.BaseCalendarItem; + + base.Remove(item); + } + + #endregion + + #region RemoveItem + + /// + /// Processes list RemoveItem calls + /// + /// Index to remove + protected override void RemoveItem(int index) + { + HookItem(Items[index], false); + + base.RemoveItem(index); + + OnCollectionChanged(); + } + + #endregion + + #region InsertItem + + /// + /// Processes list InsertItem calls + /// + /// Index to add + /// CustomCalendarItem to add + protected override void InsertItem(int index, CustomCalendarItem item) + { + if (item != null) + { + HookItem(item, true); + + base.InsertItem(index, item); + + OnCollectionChanged(); + } + } + + #endregion + + #region SetItem + + /// + /// Processes list SetItem calls (e.g. replace) + /// + /// Index to replace + /// CustomCalendarItem to replace + protected override void SetItem(int index, CustomCalendarItem newItem) + { + if (newItem != null) + { + HookItem(Items[index], false); + HookItem(newItem, true); + + base.SetItem(index, newItem); + + OnCollectionChanged(); + } + } + + #endregion + + #region ClearItems + + /// + /// Processes list Clear calls (e.g. remove all) + /// + protected override void ClearItems() + { + for (int i = 0; i < Count; i++) + HookItem(Items[i], false); + + base.ClearItems(); + + OnCollectionChanged(); + } + + #endregion + + #region HookItem + + /// + /// Hooks needed system events + /// + /// + /// + private void HookItem(CustomCalendarItem item, bool hook) + { + if (hook == true) + { + item.StartTimeChanged += ItemStartTimeChanged; + item.EndTimeChanged += ItemEndTimeChanged; + item.OwnerKeyChanged += ItemOwnerKeyChanged; + item.CategoryColorChanged += ItemCategoryColorChanged; + item.VisibleChanged += ItemVisibleChanged; + item.CollateIdChanged += ItemCollateIdChanged; + } + else + { + item.StartTimeChanged -= ItemStartTimeChanged; + item.EndTimeChanged -= ItemEndTimeChanged; + item.OwnerKeyChanged -= ItemOwnerKeyChanged; + item.CategoryColorChanged -= ItemCategoryColorChanged; + item.VisibleChanged -= ItemVisibleChanged; + item.CollateIdChanged -= ItemCollateIdChanged; + } + } + + #endregion + + #region Event processing + + /// + /// Processes OwnerKeyChanged events + /// + /// + /// + private void ItemOwnerKeyChanged(object sender, EventArgs e) + { + OnCollectionChanged(); + } + + /// + /// Processes StartTimeChanged events + /// + /// + /// + private void ItemStartTimeChanged(object sender, EventArgs e) + { + OnCollectionChanged(); + } + + /// + /// Processes EndTimeChanged events + /// + /// + /// + private void ItemEndTimeChanged(object sender, EventArgs e) + { + OnCollectionChanged(); + } + + /// + /// Processes ItemCategoryColorChanged events + /// + /// + /// + void ItemCategoryColorChanged(object sender, EventArgs e) + { + OnCollectionChanged(); + } + + /// + /// Processes ItemVisibleChanged events + /// + /// + /// + void ItemVisibleChanged(object sender, EventArgs e) + { + OnCollectionChanged(); + } + + /// + /// Processes ItemCollateIdChanged events + /// + /// + /// + void ItemCollateIdChanged(object sender, EventArgs e) + { + OnCollectionChanged(); + } + + #endregion + + #region OnCollectionChanged + + /// + /// Propagates CollectionChanged events + /// + protected virtual void OnCollectionChanged() + { + if (_UpdateCount == 0) + { + if (CollectionChanged != null) + CollectionChanged(this, EventArgs.Empty); + } + } + + #endregion + + #region Begin/EndUpdate + + /// + /// Begins Update block + /// + public void BeginUpdate() + { + _UpdateCount++; + } + + /// + /// Ends update block + /// + public void EndUpdate() + { + if (_UpdateCount == 0) + { + throw new InvalidOperationException( + "EndUpdate must be called After BeginUpdate"); + } + + _UpdateCount--; + + if (_UpdateCount == 0) + OnCollectionChanged(); + } + + #endregion + + #region IDisposable + + public void Dispose() + { + for (int i = 0; i < Count; i++) + HookItem(Items[i], false); + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateHelper.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateHelper.cs new file mode 100644 index 00000000..077ebe6f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateHelper.cs @@ -0,0 +1,154 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows; +using System.Globalization; + +namespace DevComponents.DotNetBar.Schedule +{ + internal static class DateHelper + { + #region Date/Time Helpers + + /// + /// Returns the date that is 30 minutes before or after input date if input date minute is 0 or 30. Otherwise it returns next increment to 0 or 30. + /// + /// Date and time. + /// Indicates whether to add or subtract minutes. + /// New date time. + public static DateTime GetNext30Minute(DateTime date, bool forward) + { + if (date.Minute == 0 || date.Minute == 30) + return (date.AddMinutes(forward ? 30 : -30)); + + return (date.AddMinutes((forward ? 1 : -1) * Math.Abs(30 - date.Minute))); + } + + /// + /// Returns date that starts with the day. If passed date is not on the requested date function returns first date with day that is before passed date. + /// + /// Date to inspect. + /// Day of week + /// Date that starts on given day of week. + public static DateTime GetDateForDayOfWeek(DateTime date, DayOfWeek dayOfWeek) + { + if (date.DayOfWeek != dayOfWeek) + { + // Go back to the first day of week + while (date.DayOfWeek != dayOfWeek) + { + date = date.AddDays(-1); + } + } + + return (date); + } + + public static DateTime GetEndOfWeek(DateTime date, DayOfWeek lastDayOfWeek) + { + while (date.DayOfWeek != lastDayOfWeek) + date = date.AddDays(1); + + return (date); + } + + internal static DayOfWeek GetFirstDayOfWeek() + { + return (ScheduleSettings.GetActiveCulture().DateTimeFormat.FirstDayOfWeek); + } + + internal static DayOfWeek GetLastDayOfWeek() + { + DayOfWeek firstDay = GetFirstDayOfWeek(); + + int lastDay = (int)firstDay + 6; + + if (lastDay > 6) + lastDay = lastDay - 7; + + return (DayOfWeek)lastDay; + } + + /// + /// Returns whether two days fall on same month and year. + /// + /// First date + /// Second date + /// true if dates are on same month and year + public static bool IsSameMonth(DateTime date1, DateTime date2) + { + return (date1.Year == date2.Year && date1.Month == date2.Month); + } + + public static DayOfWeek GetNextDay(DayOfWeek currentDay) + { + if ((int)currentDay == 6) + return (DayOfWeek)0; + + return (DayOfWeek)(currentDay + 1); + } + + /// + /// Returns true if time periods overlap. + /// + /// Start of first period. + /// End of first period. + /// Start of second period. + /// End of second period. + /// true if periods overlap + public static bool TimePeriodsOverlap(DateTime startTime1, DateTime endTime1, DateTime startTime2, DateTime endTime2) + { + return (startTime1 <= startTime2 && endTime1 > startTime2 || + startTime1 >= startTime2 && startTime1 < endTime2); + } + + public static int GetNumberOfWeeks(DateTime startDate, DateTime endDate) + { + if (startDate == DateTime.MinValue && endDate == DateTime.MinValue) + { + startDate = DateTime.Today.Date; + endDate = startDate.AddMonths(1); + } + + if (startDate == DateTime.MinValue || endDate == DateTime.MinValue || endDate < startDate) + { + return (0); + } + + endDate = GetEndOfWeek(endDate, DateHelper.GetLastDayOfWeek()); + startDate = GetDateForDayOfWeek(startDate, DateHelper.GetFirstDayOfWeek()); + + return ((int)Math.Max(Math.Ceiling(endDate.Subtract(startDate).TotalDays / 7), 1)); + } + + /// + /// Gets the abbreviated month name for + /// the given date + /// + /// Date + /// Abbreviated name + public static string GetThreeLetterMonth(DateTime date) + { + CultureInfo ci = ScheduleSettings.GetActiveCulture(); + + return (ci.DateTimeFormat.GetAbbreviatedMonthName(date.Month)); + } + + /// + /// Gets the abbreviated day name for + /// the given date + /// + /// Day of week + /// Abbreviated name + public static string GetThreeLetterDayOfWeek(DayOfWeek dayOfWeek) + { + CultureInfo ci = ScheduleSettings.GetActiveCulture(); + + return (ci.DateTimeFormat.GetAbbreviatedDayName(dayOfWeek)); + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.Designer.cs new file mode 100644 index 00000000..77262545 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.Designer.cs @@ -0,0 +1,94 @@ +#if FRAMEWORK20 +namespace DevComponents.DotNetBar.Schedule +{ + partial class DateNavigator + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) + CalendarView = null; + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.CurrentDateLabel = new LabelX(); + this.NavigateForward = new DevComponents.DotNetBar.ButtonX(); + this.NavigateBack = new DevComponents.DotNetBar.ButtonX(); + this.SuspendLayout(); + // + // CurrentDateLabel + // + this.CurrentDateLabel.AutoSize = true; + this.CurrentDateLabel.AutoSize = true; + this.CurrentDateLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.CurrentDateLabel.Location = new System.Drawing.Point(54, 4); + this.CurrentDateLabel.Name = "CurrentDateLabel"; + this.CurrentDateLabel.Size = new System.Drawing.Size(132, 20); + this.CurrentDateLabel.TabIndex = 1; + this.CurrentDateLabel.Text = "October 20, 2009"; + // + // NavigateForward + // + this.NavigateForward.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + this.NavigateForward.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.NavigateForward.Location = new System.Drawing.Point(31, 4); + this.NavigateForward.Name = "NavigateForward"; + this.NavigateForward.Shape = new DevComponents.DotNetBar.EllipticalShapeDescriptor(); + this.NavigateForward.Size = new System.Drawing.Size(20, 20); + this.NavigateForward.TabIndex = 0; + this.NavigateForward.Click += new System.EventHandler(this.NavigateForwardClick); + this.NavigateForward.FocusCuesEnabled = false; + // + // NavigateBack + // + this.NavigateBack.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + this.NavigateBack.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.NavigateBack.Location = new System.Drawing.Point(5, 4); + this.NavigateBack.Name = "NavigateBack"; + this.NavigateBack.Shape = new DevComponents.DotNetBar.EllipticalShapeDescriptor(); + this.NavigateBack.Size = new System.Drawing.Size(20, 20); + this.NavigateBack.TabIndex = 0; + this.NavigateBack.Click += new System.EventHandler(this.NavigateBackClick); + this.NavigateBack.FocusCuesEnabled = false; + // + // DateNavigator + // + this.Controls.Add(this.CurrentDateLabel); + this.Controls.Add(this.NavigateForward); + this.Controls.Add(this.NavigateBack); + this.Name = "DateNavigator"; + this.Size = new System.Drawing.Size(223, 30); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ButtonX NavigateBack; + private ButtonX NavigateForward; + private LabelX CurrentDateLabel; + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.cs new file mode 100644 index 00000000..f2e8c3b7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.cs @@ -0,0 +1,1713 @@ +#if FRAMEWORK20 +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.Schedule +{ + /// + /// Represents date-navigation control that is used with CalendarView to provide calendar date navigation. + /// + [ToolboxItem(true), ToolboxBitmap(typeof(DateNavigator), "Schedule.DateNavigator.ico")] + [Designer("DevComponents.DotNetBar.Design.DateNavigatorDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public partial class DateNavigator : PanelEx + { + #region Events + + /// + /// Occurs when a date Navigation is occurring + /// + [Description("Occurs when a date Navigation is occurring.")] + public event EventHandler DateChanging; + + /// + /// Occurs when a date Navigation has occurred + /// + [Description("Occurs when a date Navigation has occurred.")] + public event EventHandler DateChanged; + + /// + /// Occurs when the DateNavigator needs a formatted date label + /// + [Description("Occurs when the DateNavigator needs a formatted date label.")] + public event EventHandler GetDateLabel; + + #endregion + + #region Constants + + private const int MaxYearMonthSpan = 120; + + #endregion + + #region Private variables + + private CalendarView _CalendarView; + + private string _CurrentDayLabel = "MMMM dd, yyyy"; + + private string _CurrentWeekStartLabel = "MMMM dd, yyyy"; + private string _CurrentWeekEndLabel = "MMMM dd, yyyy"; + private string _CurrentWeekSameYearStartLabel = "MMMM dd"; + private string _CurrentWeekSameYearEndLabel = "MMMM dd, yyyy"; + private string _CurrentWeekSameMonthYearStartLabel = "MMMM dd"; + private string _CurrentWeekSameMonthYearEndLabel = "dd, yyyy"; + + private string _CurrentMonthStartLabel = "MMMM yyyy"; + private string _CurrentMonthEndLabel = "MMMM yyyy"; + + private string _CurrentYearStartLabel = "MMMM yyyy"; + private string _CurrentYearEndLabel = "MMMM yyyy"; + + private string _CurrentTimeLineHourLabel = "MMMM dd, yyyy"; + private string _CurrentTimeLineDayStartLabel = "MMMM dd, yyyy"; + private string _CurrentTimeLineDayEndLabel = "MMMM dd, yyyy"; + private string _CurrentTimeLineDaySameYearStartLabel = "MMMM dd"; + private string _CurrentTimeLineDaySameYearEndLabel = "MMMM dd, yyyy"; + private string _CurrentTimeLineDaySameMonthYearStartLabel = "MMMM dd"; + private string _CurrentTimeLineDaySameMonthYearEndLabel = "dd, yyyy"; + private string _CurrentTimeLineYearStartLabel = "yyyy"; + private string _CurrentTimeLineYearEndLabel = "yyyy"; + + #endregion + + public DateNavigator() + { + InitializeComponent(); + UpdateButtonImages(); + + Style.BackColor1.Color = + ((Office2007Renderer)GlobalManager.Renderer).ColorTable.CalendarView.TimeRulerColors[0].Colors[0]; + + StyleManager.Register(this); + } + + #region Public properties + + #region CalendarView + + /// + /// Gets or sets the CalendarView date navigation will be applied to. + /// + [DefaultValue(null), Category("Behavior")] + [Description("Indicates CalendarView date navigation will be applied to.")] + public CalendarView CalendarView + { + get { return _CalendarView; } + + set + { + if (_CalendarView != null) + { + _CalendarView.SelectedViewChanged -= CalendarSelectedViewChanged; + _CalendarView.ViewDateChanged -= CalendarViewViewDateChanged; + _CalendarView.TimeLineViewScrollDateChanged -= CalendarViewTimeLineViewScrollDateChanged; + } + + _CalendarView = value; + + if (_CalendarView != null) + { + _CalendarView.SelectedViewChanged += CalendarSelectedViewChanged; + _CalendarView.ViewDateChanged += CalendarViewViewDateChanged; + _CalendarView.TimeLineViewScrollDateChanged += CalendarViewTimeLineViewScrollDateChanged; + } + + UpdateDisplay(); + } + } + + /// + /// Handles CalendarView ViewDateChanged events + /// + /// + /// + void CalendarViewViewDateChanged(object sender, ViewDateChangedEventArgs e) + { + UpdateDisplay(); + } + + /// + /// Handle CalendarView SelectedViewChanged events + /// + /// + /// + private void CalendarSelectedViewChanged(object sender, SelectedViewEventArgs e) + { + UpdateDisplay(); + } + + /// + /// Handles CalendarView_TimeLineViewScrollDateChanged events + /// + /// + /// + void CalendarViewTimeLineViewScrollDateChanged(object sender, EventArgs e) + { + UpdateDisplay(); + } + + #endregion + + #region CurrentDayLabel + + /// + /// Gets or sets the current Day format label + /// + [Localizable(true), DefaultValue("MMMM dd, yyyy"), Category("Appearance")] + [Description("Indicates the current Day format label.")] + public string CurrentDayLabel + { + get { return (_CurrentDayLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentDayLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentWeekStartLabel + + /// + /// Gets or sets the current Week, start format label + /// + [Localizable(true), DefaultValue("MMMM dd, yyyy"), Category("Appearance")] + [Description("Indicates the current Week, start format label.")] + public string CurrentWeekStartLabel + { + get { return (_CurrentWeekStartLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentWeekStartLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentWeekEndLabel + + /// + /// Gets or sets the current Week, end format label + /// + [Localizable(true), DefaultValue("MMMM dd, yyyy"), Category("Appearance")] + [Description("Indicates the current Week, end format label.")] + public string CurrentWeekEndLabel + { + get { return (_CurrentWeekEndLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentWeekEndLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentWeekSameYearStartLabel + + /// + /// Gets or sets the current Week, same Year, start format label + /// + [Localizable(true), DefaultValue("MMMM dd"), Category("Appearance")] + [Description("Indicates the current Week, same Year, start format label.")] + public string CurrentWeekSameYearStartLabel + { + get { return (_CurrentWeekSameYearStartLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentWeekSameYearStartLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentWeekSameYearEndLabel + + /// + /// Gets or sets the current Week, same Year, end format label + /// + [Localizable(true), DefaultValue("MMMM dd, yyyy"), Category("Appearance")] + [Description("Indicates the current Week, same Year, end format label.")] + public string CurrentWeekSameYearEndLabel + { + get { return (_CurrentWeekSameYearEndLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentWeekSameYearEndLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentWeekSameMonthYearStartLabel + + /// + /// Gets or sets the current Week, same Month & Year, start format label + /// + [Localizable(true), DefaultValue("MMMM dd"), Category("Appearance")] + [Description("Indicates the current Week, same Month & Year, start format label.")] + public string CurrentWeekSameMonthYearStartLabel + { + get { return (_CurrentWeekSameMonthYearStartLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentWeekSameMonthYearStartLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentWeekSameMonthYearEndLabel + + /// + /// Gets or sets the current Week, same Month & Year, end format label + /// + [Localizable(true), DefaultValue("dd, yyyy"), Category("Appearance")] + [Description("Indicates the current Week, same Month & Year, end format label.")] + public string CurrentWeekSameMonthYearEndLabel + { + get { return (_CurrentWeekSameMonthYearEndLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentWeekSameMonthYearEndLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentMonthStartLabel + + /// + /// Gets or sets the current Month, start format label + /// + [Localizable(true), DefaultValue("MMMM yyyy"), Category("Appearance")] + [Description("Indicates the current Month, start format label.")] + public string CurrentMonthStartLabel + { + get { return (_CurrentMonthStartLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentMonthStartLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentMonthEndLabel + + /// + /// Gets or sets the current Month, end format label + /// + [Localizable(true), DefaultValue("MMMM yyyy"), Category("Appearance")] + [Description("Indicates the current Month, end format label.")] + public string CurrentMonthEndLabel + { + get { return (_CurrentMonthEndLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentMonthEndLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentYearStartLabel + + /// + /// Gets or sets the current Year, start format label + /// + [Localizable(true), DefaultValue("MMMM yyyy"), Category("Appearance")] + [Description("Indicates the current Year, start format label.")] + public string CurrentYearStartLabel + { + get { return (_CurrentYearStartLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentYearStartLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentYearEndLabel + + /// + /// Gets or sets the current Year, end format label + /// + [Localizable(true), DefaultValue("MMMM yyyy"), Category("Appearance")] + [Description("Indicates the current Year, end format label.")] + public string CurrentYearEndLabel + { + get { return (_CurrentYearEndLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentYearEndLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentTimeLineHourLabel + + /// + /// Gets or sets the current TimeLine Hour format label + /// + [Localizable(true), DefaultValue("MMMM dd, yyyy"), Category("Appearance")] + [Description("Indicates the current TimeLine Hour format label.")] + public string CurrentTimeLineHourLabel + { + get { return (_CurrentTimeLineHourLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentTimeLineHourLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentTimeLineDayStartLabel + + /// + /// Gets or sets the current TimeLine Day, start format label + /// + [Localizable(true), DefaultValue("MMMM dd, yyyy"), Category("Appearance")] + [Description("Indicates the current TimeLine Day, start format label.")] + public string CurrentTimeLineDayStartLabel + { + get { return (_CurrentTimeLineDayStartLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentTimeLineDayStartLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentTimeLineDayEndLabel + + /// + /// Gets or sets the current TimeLine Day, end format label + /// + [Localizable(true), DefaultValue("MMMM dd, yyyy"), Category("Appearance")] + [Description("Indicates the current TimeLine Day, end format label.")] + public string CurrentTimeLineDayEndLabel + { + get { return (_CurrentTimeLineDayEndLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentTimeLineDayEndLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentTimeLineDaySameYearStartLabel + + /// + /// Gets or sets the current TimeLine Day, same Year, start format label + /// + [Localizable(true), DefaultValue("MMMM dd"), Category("Appearance")] + [Description("Indicates the current TimeLine Day, same Year, start format label.")] + public string CurrentTimeLineDaySameYearStartLabel + { + get { return (_CurrentTimeLineDaySameYearStartLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentTimeLineDaySameYearStartLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentTimeLineDaySameYearEndLabel + + /// + /// Gets or sets the current TimeLine Day, same Year, end format label + /// + [Localizable(true), DefaultValue("MMMM dd, yyyy"), Category("Appearance")] + [Description("Indicates the current TimeLine Day, same Year, end format label.")] + public string CurrentTimeLineDaySameYearEndLabel + { + get { return (_CurrentTimeLineDaySameYearEndLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentTimeLineDaySameYearEndLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentTimeLineDaySameMonthYearStartLabel + + /// + /// Gets or sets the current TimeLine Day, same Month & Year, start format label + /// + [Localizable(true), DefaultValue("MMMM dd"), Category("Appearance")] + [Description("Indicates the current TimeLine Day, same Month & Year, start format label.")] + public string CurrentTimeLineDaySameMonthYearStartLabel + { + get { return (_CurrentTimeLineDaySameMonthYearStartLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentTimeLineDaySameMonthYearStartLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentTimeLineDaySameMonthYearEndLabel + + /// + /// Gets or sets the current TimeLine Day, same Month & Year, end format label + /// + [Localizable(true), DefaultValue("dd, yyyy"), Category("Appearance")] + [Description("Indicates the current TimeLine Day, same Month & Year, end format label.")] + public string CurrentTimeLineDaySameMonthYearEndLabel + { + get { return (_CurrentTimeLineDaySameMonthYearEndLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentTimeLineDaySameMonthYearEndLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentTimeLineYearStartLabel + + /// + /// Gets or sets the current TimeLine Year, start format label + /// + [Localizable(true), DefaultValue("yyyy"), Category("Appearance")] + [Description("Indicates the current TimeLine Year, start format label.")] + public string CurrentTimeLineYearStartLabel + { + get { return (_CurrentTimeLineYearStartLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentTimeLineYearStartLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region CurrentTimeLineYearEndLabel + + /// + /// Gets or sets the current TimeLine Year, end format label + /// + [Localizable(true), DefaultValue("yyyy"), Category("Appearance")] + [Description("Indicates the current TimeLine Year, end format label.")] + public string CurrentTimeLineYearEndLabel + { + get { return (_CurrentTimeLineYearEndLabel); } + + set + { + if (value == null) + value = ""; + + _CurrentTimeLineYearEndLabel = value; + + UpdateDisplay(); + } + } + + #endregion + + #region WeekDaysNavigationEnabled + + private bool _WeekDaysNavigationEnabled = true; + + /// + /// Gets or sets whether in Week View week-days navigation is enabled. Default value is true. When week-days navigation is enabled + /// and start date points to Monday and end date points to Friday, navigating to next day will navigate to next Monday-Friday view. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether in Week View week-days navigation is enabled. When week-days navigation is enabled and start date points to Monday and end date points to Friday, navigating to next day will navigate to next Monday-Friday view.")] + public bool WeekDaysNavigationEnabled + { + get { return _WeekDaysNavigationEnabled; } + set + { + _WeekDaysNavigationEnabled = value; + } + } + + #endregion + + #endregion + + #region StyleManagerStyleChanged + + /// + /// Called by StyleManager to notify control that style on manager has changed and that control should refresh its appearance if + /// its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + base.StyleManagerStyleChanged(newStyle); + UpdateButtonImages(); + this.Style.BackColor1.Color = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.CalendarView.TimeRulerColors[0].Colors[0]; + } + + #endregion + + #region Navigate_click routines + + /// + /// Handles NavigateForward button clicks + /// + /// + /// + private void NavigateForwardClick(object sender, EventArgs e) + { + NavigateDatesForward(); + } + + /// + /// Handles NavigateBack button clicks + /// + /// + /// + private void NavigateBackClick(object sender, EventArgs e) + { + NavigateDatesBack(); + } + + #endregion + + #region NavigateDatesForward + + /// + /// Navigates forward + /// + private void NavigateDatesForward() + { + if (_CalendarView != null) + { + switch (_CalendarView.SelectedView) + { + case eCalendarView.Day: + NavigateDayForward(); + break; + + case eCalendarView.Week: + NavigateWeekForward(); + break; + + case eCalendarView.Month: + NavigateMonthForward(); + break; + + case eCalendarView.Year: + NavigateYearForward(); + break; + + case eCalendarView.TimeLine: + NavigateTimeLineForward(); + break; + } + + UpdateDisplay(); + } + } + + #region NavigateDayForward + + /// + /// NavigateDayForward + /// + private void NavigateDayForward() + { + DateTime oldDate = _CalendarView.DayViewDate; + DateTime newDate = _CalendarView.DayViewDate.AddDays(1); + + if (DoDateChanging(NavigationDirection.Forward, + oldDate, oldDate, ref newDate, ref newDate) == false) + { + _CalendarView.DayViewDate = newDate; + + DoDateChanged(NavigationDirection.Forward, oldDate, oldDate, newDate, newDate); + } + } + + #endregion + + #region NavigateWeekForward + + /// + /// NavigateWeekForward + /// + private void NavigateWeekForward() + { + DateTime calendarStart = _CalendarView.WeekViewStartDate; + DateTime calendarEnd = _CalendarView.WeekViewEndDate; + + TimeSpan span = calendarEnd.Subtract(calendarStart); + DateTime start = calendarStart.AddDays(1).Add(span); + DateTime end = calendarEnd.AddDays(1).Add(span); + + if (WeekDaysNavigationEnabled && + calendarStart.DayOfWeek == DayOfWeek.Monday && calendarEnd.DayOfWeek == DayOfWeek.Friday) + { + // Browse week-days only + + start = calendarStart.AddDays(7); + end = start.AddDays(4); + } + + if (DoDateChanging(NavigationDirection.Forward, + calendarStart, calendarEnd, ref start, ref end) == false) + { + _CalendarView.WeekViewStartDate = start; + _CalendarView.WeekViewEndDate = end; + + DoDateChanged(NavigationDirection.Forward, calendarStart, calendarEnd, start, end); + } + } + + #endregion + + #region NavigateMonthForward + + /// + /// NavigateMonthForward + /// + private void NavigateMonthForward() + { + DateTime calendarStart = _CalendarView.MonthViewStartDate; + DateTime calendarEnd = _CalendarView.MonthViewEndDate; + + TimeSpan span = calendarEnd.Subtract(calendarStart); + DateTime start = calendarStart.AddMonths(1); + DateTime end = start.Add(span); + + if (calendarStart.Day == 1 && + calendarEnd.Day == ScheduleSettings.GetActiveCulture().Calendar.GetDaysInMonth(calendarEnd.Year, calendarEnd.Month)) + { + end = start.AddMonths(1).AddMinutes(-1); + } + + if (DoDateChanging(NavigationDirection.Forward, + calendarStart, calendarEnd, ref start, ref end) == false) + { + _CalendarView.MonthViewStartDate = start; + _CalendarView.MonthViewEndDate = end; + + DoDateChanged(NavigationDirection.Forward, calendarStart, calendarEnd, start, end); + } + } + + #endregion + + #region NavigateYearForward + + /// + /// NavigateYearForward + /// + private void NavigateYearForward() + { + DateTime calendarStart = _CalendarView.YearViewStartDate; + DateTime calendarEnd = _CalendarView.YearViewEndDate; + + int months = CountMonthSpan(calendarStart, calendarEnd); + + DateTime start = calendarEnd.AddMonths(1); + start = start.AddDays(-start.Day + 1); + + DateTime end = start.AddMonths(months + 1); + end = end.AddDays(-1); + + if (DoDateChanging(NavigationDirection.Forward, + calendarStart, calendarEnd, ref start, ref end) == false) + { + _CalendarView.YearViewStartDate = start; + _CalendarView.YearViewEndDate = end; + + DoDateChanged(NavigationDirection.Forward, calendarStart, calendarEnd, start, end); + } + } + + #endregion + + #region NavigateTimeLineForward + + /// + /// NavigateTimeLineForward + /// + private void NavigateTimeLineForward() + { + DateTime calendarStart = _CalendarView.TimeLineViewScrollStartDate; + DateTime calendarEnd = _CalendarView.TimeLineViewScrollEndDate; + + DateTime start = GetForwardPeriodDate(_CalendarView.TimeLineViewScrollStartDate); + DateTime end = start; + + if (DoDateChanging(NavigationDirection.Forward, + calendarStart, calendarEnd, ref start, ref end) == false) + { + _CalendarView.TimeLineViewScrollStartDate = start; + + DoDateChanged(NavigationDirection.Forward, calendarStart, calendarEnd, + _CalendarView.TimeLineViewScrollStartDate, _CalendarView.TimeLineViewScrollEndDate); + } + } + + #endregion + + #region GetForwardPeriodDate + + /// + /// Gets the next forward TimeLine Period Date + /// + /// Current date + /// Next Period Date + private DateTime GetForwardPeriodDate(DateTime calendarStart) + { + // Hours or Minutes + + if (_CalendarView.TimeLinePeriod == eTimeLinePeriod.Minutes || + _CalendarView.TimeLinePeriod == eTimeLinePeriod.Hours) + { + // Move forward by a day + + calendarStart = calendarStart.AddDays(1); + + return (new DateTime(calendarStart.Year, + calendarStart.Month, calendarStart.Day, 0, 0, 0)); + } + + // Days + + if (_CalendarView.TimeLinePeriod == eTimeLinePeriod.Days) + { + // If our interval is a single day, then + // move forward by a month + + if (_CalendarView.TimeLineInterval == 1) + { + calendarStart = calendarStart.AddMonths(1); + + return (new DateTime(calendarStart.Year, calendarStart.Month, 1)); + } + + // The interval is multiple days, so + // move forward by a year + + calendarStart = calendarStart.AddYears(1); + + if (calendarStart.AddMinutes(_CalendarView.BaseInterval).Year > calendarStart.Year) + calendarStart = calendarStart.AddYears(1); + + return (new DateTime(calendarStart.Year, 1, 1)); + } + + // Years + + if (_CalendarView.TimeLinePeriod == eTimeLinePeriod.Years) + { + TimeSpan ts = calendarStart - _CalendarView.TimeLineViewStartDate; + + // Move forward by 10 columns at a time + + int interval = (int)(ts.TotalMinutes / _CalendarView.BaseInterval); + + interval = ((interval + 10) / 10) * 10; + + return (_CalendarView.TimeLineViewStartDate.AddMinutes( + interval * _CalendarView.BaseInterval)); + } + + return (calendarStart); + } + + #endregion + + #endregion + + #region NavigateDatesBack + + /// + /// Navigates back + /// + private void NavigateDatesBack() + { + if (_CalendarView != null) + { + switch (_CalendarView.SelectedView) + { + case eCalendarView.Day: + NavigateDayBack(); + break; + + case eCalendarView.Week: + NavigateWeekBack(); + break; + + case eCalendarView.Month: + NavigateMonthBack(); + break; + + case eCalendarView.Year: + NavigateYearBack(); + break; + + case eCalendarView.TimeLine: + NavigateTimeLineBack(); + break; + } + + UpdateDisplay(); + } + } + + #region NavigateDayBack + + /// + /// NavigateDayBack + /// + private void NavigateDayBack() + { + DateTime oldDate = _CalendarView.DayViewDate; + DateTime newDate = _CalendarView.DayViewDate.AddDays(-1); + + if (DoDateChanging(NavigationDirection.Backward, + oldDate, oldDate, ref newDate, ref newDate) == false) + { + _CalendarView.DayViewDate = newDate; + + DoDateChanged(NavigationDirection.Backward, oldDate, oldDate, newDate, newDate); + } + } + + #endregion + + #region NavigateWeekBack + + /// + /// NavigateWeekBack + /// + private void NavigateWeekBack() + { + DateTime calendarStart = _CalendarView.WeekViewStartDate; + DateTime calendarEnd = _CalendarView.WeekViewEndDate; + + TimeSpan span = calendarEnd.Subtract(calendarStart).Negate(); + DateTime start = calendarStart.AddDays(-1).Add(span); + DateTime end = calendarEnd.AddDays(-1).Add(span); + + if (WeekDaysNavigationEnabled && + calendarStart.DayOfWeek == DayOfWeek.Monday && calendarEnd.DayOfWeek == DayOfWeek.Friday) + { + // Browse week-days only + + start = calendarStart.AddDays(-7); + end = start.AddDays(4); + } + + if (DoDateChanging(NavigationDirection.Backward, + calendarStart, calendarEnd, ref start, ref end) == false) + { + _CalendarView.WeekViewStartDate = start; + _CalendarView.WeekViewEndDate = end; + + DoDateChanged(NavigationDirection.Backward, calendarStart, calendarEnd, start, end); + } + } + + #endregion + + #region NavigateMonthBack + + /// + /// NavigateMonthBack + /// + private void NavigateMonthBack() + { + DateTime calendarStart = _CalendarView.MonthViewStartDate; + DateTime calendarEnd = _CalendarView.MonthViewEndDate; + + TimeSpan span = calendarEnd.Subtract(calendarStart); + DateTime start = calendarStart.AddMonths(-1); + DateTime end = start.Add(span); + + if (calendarStart.Day == 1 && + calendarEnd.Day == ScheduleSettings.GetActiveCulture().Calendar.GetDaysInMonth(calendarEnd.Year, calendarEnd.Month)) + { + end = start.AddMonths(1).AddMinutes(-1); + } + + if (DoDateChanging(NavigationDirection.Backward, + calendarStart, calendarEnd, ref start, ref end) == false) + { + _CalendarView.MonthViewStartDate = start; + _CalendarView.MonthViewEndDate = end; + + DoDateChanged(NavigationDirection.Backward, calendarStart, calendarEnd, start, end); + } + } + + #endregion + + #region NavigateYearBack + + /// + /// NavigateYearBack + /// + private void NavigateYearBack() + { + DateTime calendarStart = _CalendarView.YearViewStartDate; + DateTime calendarEnd = _CalendarView.YearViewEndDate; + + int months = CountMonthSpan(calendarStart, calendarEnd); + + DateTime end = calendarStart.AddDays(-1); + DateTime start = end.AddMonths(-months); + start = start.AddDays(-start.Day + 1); + + if (DoDateChanging(NavigationDirection.Backward, + calendarStart, calendarEnd, ref start, ref end) == false) + { + _CalendarView.YearViewStartDate = start; + _CalendarView.YearViewEndDate = end; + + DoDateChanged(NavigationDirection.Backward, calendarStart, calendarEnd, start, end); + } + } + + #endregion + + #region NavigateTimeLineBack + + /// + /// NavigateTimeLineBack + /// + private void NavigateTimeLineBack() + { + DateTime calendarStart = _CalendarView.TimeLineViewScrollStartDate; + DateTime calendarEnd = _CalendarView.TimeLineViewScrollEndDate; + + DateTime start = GetBackPeriodDate(_CalendarView.TimeLineViewScrollStartDate); + DateTime end = start; + + if (DoDateChanging(NavigationDirection.Backward, + calendarStart, calendarEnd, ref start, ref end) == false) + { + _CalendarView.TimeLineViewScrollStartDate = start; + + DoDateChanged(NavigationDirection.Backward, calendarStart, calendarEnd, + _CalendarView.TimeLineViewScrollStartDate, _CalendarView.TimeLineViewScrollEndDate); + } + } + + #endregion + + #region GetBackPeriodDate + + /// + /// Gets the next back TimeLine Period Date + /// + /// Current date + /// Next back Period Date + private DateTime GetBackPeriodDate(DateTime calendarStart) + { + // Hours or minutes + + if (_CalendarView.TimeLinePeriod == eTimeLinePeriod.Minutes || + _CalendarView.TimeLinePeriod == eTimeLinePeriod.Hours) + { + // Go back by a day + + if (calendarStart.Hour == 0) + calendarStart = calendarStart.AddDays(-1); + + return (new DateTime(calendarStart.Year, + calendarStart.Month, calendarStart.Day, 0, 0, 0)); + } + + // Days + + if (_CalendarView.TimeLinePeriod == eTimeLinePeriod.Days) + { + // If the interval is a single day + // then go back by a month + + if (_CalendarView.TimeLineInterval == 1) + { + if (calendarStart.Day == 1) + calendarStart = calendarStart.AddMonths(-1); + + return (new DateTime(calendarStart.Year, calendarStart.Month, 1)); + } + + // Multi-day interval, go back + // by a year + + if (calendarStart.AddMinutes(-_CalendarView.BaseInterval).Year < calendarStart.Year) + calendarStart = calendarStart.AddYears(-1); + + return (new DateTime(calendarStart.Year, 1, 1)); + } + + // Years + + if (_CalendarView.TimeLinePeriod == eTimeLinePeriod.Years) + { + TimeSpan ts = calendarStart - _CalendarView.TimeLineViewStartDate; + + // Go back 10 columns + + int interval = (int)(ts.TotalMinutes / _CalendarView.BaseInterval); + + interval = ((interval % 10 == 0) + ? interval - 10 : (interval / 10) * 10); + + return (_CalendarView.TimeLineViewStartDate.AddMinutes( + interval * _CalendarView.BaseInterval)); + } + + return (calendarStart); + } + + #endregion + + #endregion + + #region CountMonthSpan + + /// + /// CountMonthSpan + /// + /// + /// + /// + private int CountMonthSpan(DateTime calendarStart, DateTime calendarEnd) + { + int monthSpan = (calendarEnd.Year * 12 + calendarEnd.Month) - + (calendarStart.Year * 12 + calendarStart.Month); + + return (monthSpan > MaxYearMonthSpan ? MaxYearMonthSpan : monthSpan); + } + + #endregion + + #region UpdateDisplay + + #region UpdateDisplay + + /// + /// Updates the Date Label text + /// + public void UpdateDisplay() + { + if (IsDisposed == false) + { + if (_CalendarView == null) + { + CurrentDateLabel.Text = ""; + } + else + { + if (GetDateLabel != null) + { + GetDateLabelEventArgs args = new GetDateLabelEventArgs(); + + GetDateLabel(this, args); + + if (string.IsNullOrEmpty(args.DateLabel) == false) + { + CurrentDateLabel.Text = args.DateLabel; + return; + } + } + + IFormatProvider formatProvider = + ScheduleSettings.GetActiveCulture(); //.GetFormat(typeof (DateTime)); + + switch (_CalendarView.SelectedView) + { + case eCalendarView.Day: + UpdateDayDisplay(formatProvider, _CalendarView.DayViewDate); + break; + + case eCalendarView.Week: + UpdateWeekDisplay(formatProvider, + _CalendarView.WeekViewStartDate, _CalendarView.WeekViewEndDate); + break; + + case eCalendarView.Month: + UpdateMonthDisplay(formatProvider, + _CalendarView.MonthViewStartDate, _CalendarView.MonthViewEndDate); + break; + + case eCalendarView.Year: + UpdateYearDisplay(formatProvider, + _CalendarView.YearViewStartDate, _CalendarView.YearViewEndDate); + break; + + case eCalendarView.TimeLine: + UpdateTimeLineDisplay(formatProvider, + _CalendarView.TimeLineViewScrollStartDate, + _CalendarView.TimeLineViewScrollEndDate); + break; + } + } + } + } + + #endregion + + #region UpdateDayDisplay + + /// + /// Updates the DayView display + /// + /// + /// + private void UpdateDayDisplay(IFormatProvider formatProvider, DateTime start) + { + CurrentDateLabel.Text = (start == DateTime.MinValue) + ? "" : start.ToString(CurrentDayLabel, formatProvider); + } + + #endregion + + #region UpdateWeekDisplay + + /// + /// Updates the WeekView display + /// + /// + /// + /// + private void UpdateWeekDisplay(IFormatProvider formatProvider, DateTime start, DateTime end) + { + if (start == DateTime.MinValue || end == DateTime.MinValue) + { + CurrentDateLabel.Text = ""; + } + else + { + if (start.Year == end.Year && start.Month == end.Month) + { + CurrentDateLabel.Text = + start.ToString(CurrentWeekSameYearStartLabel, formatProvider) + @" - " + + end.ToString(CurrentWeekSameYearEndLabel, formatProvider); + } + else if (start.Year == end.Year) + { + CurrentDateLabel.Text = + start.ToString(CurrentWeekSameMonthYearStartLabel, formatProvider) + @" - " + + end.ToString(CurrentWeekSameMonthYearEndLabel, formatProvider); + } + else + { + CurrentDateLabel.Text = + start.ToString(CurrentWeekStartLabel, formatProvider) + @" - " + + end.ToString(CurrentWeekEndLabel, formatProvider); + } + } + } + + #endregion + + #region UpdateMonthDisplay + + /// + /// Updates the MonthView display + /// + /// + /// + /// + private void UpdateMonthDisplay(IFormatProvider formatProvider, DateTime start, DateTime end) + { + if (start == DateTime.MinValue || end == DateTime.MinValue) + { + CurrentDateLabel.Text = ""; + } + else + { + string s = start.ToString(CurrentMonthStartLabel, formatProvider); + + if (end.Year != start.Year) + s += " - " + end.ToString(CurrentMonthEndLabel, formatProvider); + + CurrentDateLabel.Text = s; + } + } + + #endregion + + #region UpdateYearDisplay + + /// + /// Updates the YearView display + /// + /// + /// + /// + private void UpdateYearDisplay(IFormatProvider formatProvider, DateTime start, DateTime end) + { + if (start == DateTime.MinValue) + { + CurrentDateLabel.Text = ""; + } + else + { + string s = start.ToString(CurrentYearStartLabel, formatProvider); + + if (start.Month != end.Month || start.Year != end.Year) + s += " - " + end.ToString(CurrentYearEndLabel, formatProvider); + + CurrentDateLabel.Text = s; + } + } + + #endregion + + #region UpdateTimeLineDisplay + + /// + /// Updates the TimeLineView display + /// + /// + /// + /// + private void UpdateTimeLineDisplay(IFormatProvider formatProvider, DateTime start, DateTime end) + { + if (start == DateTime.MinValue || end == DateTime.MinValue) + { + CurrentDateLabel.Text = ""; + } + else + { + switch (_CalendarView.TimeLinePeriod) + { + case eTimeLinePeriod.Hours: + case eTimeLinePeriod.Minutes: + CurrentDateLabel.Text = start.ToString(CurrentTimeLineHourLabel, formatProvider); + break; + + case eTimeLinePeriod.Days: + if (start.Year == end.Year && start.Month == end.Month) + { + CurrentDateLabel.Text = + start.ToString(CurrentTimeLineDaySameMonthYearStartLabel, formatProvider) + @" - " + + end.ToString(CurrentTimeLineDaySameMonthYearEndLabel, formatProvider); + } + else if (start.Year == end.Year) + { + CurrentDateLabel.Text = + start.ToString(CurrentTimeLineDaySameYearStartLabel, formatProvider) + @" - " + + end.ToString(CurrentTimeLineDaySameYearEndLabel, formatProvider); + } + else + { + CurrentDateLabel.Text = + start.ToString(CurrentTimeLineDayStartLabel, formatProvider) + @" - " + + end.ToString(CurrentTimeLineDayEndLabel, formatProvider); + } + break; + + case eTimeLinePeriod.Years: + CurrentDateLabel.Text = + start.ToString(CurrentTimeLineYearStartLabel, formatProvider) + @" - " + + end.ToString(CurrentTimeLineYearEndLabel, formatProvider); + break; + } + } + } + + #endregion + + #endregion + + #region UpdateButtonImages + + /// + /// Updates the button images + /// + private void UpdateButtonImages() + { + Bitmap image = new Bitmap(10, 10, PixelFormat.Format32bppArgb); + using (Graphics g = Graphics.FromImage(image)) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + using (Pen pen = new Pen(GetImageForeColor(), 2)) + { + g.DrawLines(pen, new Point[] { + new Point(5,0), + new Point(1,4), + new Point(5,8) + }); + g.DrawLines(pen, new Point[] { + new Point(1,4), + new Point(9,4) + }); + + } + } + if (NavigateBack.Image != null) + { + Image img = NavigateBack.Image; + NavigateBack.Image = null; + img.Dispose(); + } + NavigateBack.Image = image; + + + image = new Bitmap(10, 10, PixelFormat.Format32bppArgb); + using (Graphics g = Graphics.FromImage(image)) + { + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + using (Pen pen = new Pen(GetImageForeColor(), 2)) + { + g.DrawLines(pen, new Point[] { + new Point(0,4), + new Point(8,4), + new Point(4,0), + new Point(8,4), + new Point(4,8) + }); + } + } + if (NavigateForward.Image != null) + { + Image img = NavigateForward.Image; + NavigateForward.Image = null; + img.Dispose(); + } + NavigateForward.Image = image; + } + + /// + /// Gets image fore color + /// + /// + private Color GetImageForeColor() + { + if (GlobalManager.Renderer is Office2007Renderer) + { + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.CheckBoxItem.Default.Text; + } + + return this.ColorScheme.ItemText; + } + + #endregion + + #region DoDateChanging + + private bool DoDateChanging(NavigationDirection direction, + DateTime oldStartDate, DateTime oldEndDate, ref DateTime newStartDate, ref DateTime newEndDate) + { + if (DateChanging != null) + { + DateChangingEventArgs ev = new DateChangingEventArgs( + direction, oldStartDate, oldEndDate, newStartDate, newEndDate); + + DateChanging(this, ev); + + if (ev.Cancel == true) + return (true); + + newStartDate = ev.NewStartDate; + newEndDate = ev.NewEndDate; + } + + return (false); + } + + #endregion + + #region DoDateChanged + + private void DoDateChanged(NavigationDirection direction, + DateTime oldStartDate, DateTime oldEndDate, DateTime newStartDate, DateTime newEndDate) + { + if (DateChanged != null) + { + DateChangedEventArgs ev = new DateChangedEventArgs( + direction, oldStartDate, oldEndDate, newStartDate, newEndDate); + + DateChanged(this, ev); + } + } + + #endregion + + #region DateChangingEventArgs + + /// + /// DateChangingEventArgs + /// + public class DateChangingEventArgs : DateChangedEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + public DateChangingEventArgs(NavigationDirection direction, + DateTime oldStartDate, DateTime oldEndDate, DateTime newStartDate, DateTime newEndDate) + : base(direction, oldStartDate, oldEndDate, newStartDate, newEndDate) + { + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region DateChangedEventArgs + + /// + /// DateChangingEventArgs + /// + public class DateChangedEventArgs : EventArgs + { + #region Private variables + + NavigationDirection _Direction; + + private DateTime _OldStartDate; + private DateTime _OldEndDate; + private DateTime _NewStartDate; + private DateTime _NewEndDate; + + #endregion + + public DateChangedEventArgs(NavigationDirection direction, + DateTime oldStartDate, DateTime oldEndDate, DateTime newStartDate, DateTime newEndDate) + { + _Direction = direction; + + _OldStartDate = oldStartDate; + _OldEndDate = oldEndDate; + _NewStartDate = newStartDate; + _NewEndDate = newEndDate; + } + + #region Public properties + + /// + /// Gets the navigation direction + /// + public NavigationDirection Direction + { + get { return (_Direction); } + set { _Direction = value; } + } + + /// + /// Gets the old navigation start date + /// + public DateTime OldStartDate + { + get { return (_OldStartDate); } + } + + /// + /// Gets the old navigation end date + /// + public DateTime OldEndDate + { + get { return (_OldEndDate); } + } + + /// + /// Gets or sets the new navigation start date + /// + public DateTime NewStartDate + { + get { return (_NewStartDate); } + set { _NewStartDate = value; } + } + + /// + /// Gets or sets the new navigation end date + /// + public DateTime NewEndDate + { + get { return (_NewEndDate); } + set { _NewEndDate = value; } + } + + #endregion + } + + #endregion + + #region GetDateLabelEventArgs + + /// + /// GetDateLabelEventArgs + /// + public class GetDateLabelEventArgs : EventArgs + { + #region Private variables + + private string _DateLabel; + + #endregion + + #region Public properties + + /// + /// Gets the formatted DateLabel + /// + public string DateLabel + { + get { return (_DateLabel); } + set { _DateLabel = value; } + } + + #endregion + } + + #endregion + } + + #region enums + + public enum NavigationDirection + { + Forward, + Backward + } + + #endregion +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.ico b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.ico new file mode 100644 index 00000000..017d6e9a Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.ico differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DateNavigator.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DaysOfTheWeek.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DaysOfTheWeek.cs new file mode 100644 index 00000000..4e4f49b3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DaysOfTheWeek.cs @@ -0,0 +1,158 @@ +#if FRAMEWORK20 +using System; +using System.Drawing; + +namespace DevComponents.DotNetBar.Schedule +{ + public class DaysOfTheWeek + { + #region enums + + public enum eDayType + { + Long, // Long text + Short, // Short text + Single, + None + } + + #endregion + + #region Private variables + + private int _DayCount; // Count of days + + private string[][] _DayText; // Days of the week text + private Size[][] _DaySize; // Days of the week measure + + private bool _NeedsMeasured; // Text measure flag + + #endregion + + /// + /// Constructor + /// + public DaysOfTheWeek() + : this(DateHelper.GetFirstDayOfWeek(), 7) + { + } + + /// + /// Constructor + /// + /// Day of the week + /// Count of days + public DaysOfTheWeek(DayOfWeek day, int count) + { + LoadDays(day, count); + } + + #region Public properties + + /// + /// Gets the DayText string arrays + /// + public string[][] DayText + { + get { return (_DayText); } + } + + /// + /// Gets the DaySize Size arrays + /// + public Size[][] DaySize + { + get {return (_DaySize); } + } + + /// + /// Day text NeedsMeasured flag + /// + public bool NeedsMeasured + { + get { return (_NeedsMeasured); } + set { _NeedsMeasured = value; } + } + + #endregion + + #region LoadDays + + /// + /// Loads the DayText arrays + /// + /// Starting day of week + /// Count of days + public void LoadDays(DayOfWeek day, int count) + { + _DayCount = count; + + // Allocate our Day text and Size arrays + + _DayText = new string[3][]; + _DaySize = new Size[3][]; + + for (int i = 0; i < 3; i++) + { + _DayText[i] = new string[count]; + _DaySize[i] = new Size[count]; + } + + // Loop through each day of the week, getting + // the long and short text strings for the day + + for (int i = 0; i < _DayCount; i++) + { + _DayText[0][i] = + ScheduleSettings.GetActiveCulture().DateTimeFormat.GetDayName(day); + + _DayText[1][i] = + DateHelper.GetThreeLetterDayOfWeek(day); + + _DayText[2][i] = _DayText[1][i].Substring(0, 1); + + day = DateHelper.GetNextDay(day); + } + + // Flag that the text will need to be measured + + _NeedsMeasured = true; + } + + #endregion + + #region MeasureText + + /// + /// Measures the day text + /// + /// Graphics + /// Text font + public void MeasureText(Graphics g, Font font) + { + // Calculate our header text threshold, if + // we haven't done so already + + if (_NeedsMeasured == true) + { + for (int i = 0; i < _DayCount; i++) + { + _DaySize[0][i] = + TextDrawing.MeasureString(g, _DayText[0][i], font); + + _DaySize[1][i] = + TextDrawing.MeasureString(g, _DayText[1][i], font); + + _DaySize[2][i] = + TextDrawing.MeasureString(g, _DayText[2][i], font); + } + + _NeedsMeasured = false; + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DevComponents.DotNetBar.Schedule.csproj b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DevComponents.DotNetBar.Schedule.csproj new file mode 100644 index 00000000..bad49602 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/DevComponents.DotNetBar.Schedule.csproj @@ -0,0 +1,268 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {C25DFA40-9897-47FA-A525-7528C5BE7724} + Library + Properties + DevComponents.DotNetBar.Schedule + DevComponents.DotNetBar.Schedule + true + dotnetbar.snk + v2.0 + + + 2.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;FRAMEWORK20 + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE;FRAMEWORK20 + prompt + 4 + bin\Release\DevComponents.DotNetBar.Schedule.XML + AllRules.ruleset + + + bin\Release\ + FRAMEWORK20;TRIAL + bin\Release\DevComponents.DotNetBar.Schedule.XML + AllRules.ruleset + + + + + + + + + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + + + + + + + + + + + + Component + + + + + Component + + + DateNavigator.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + + + Form + + + PosWin.cs + + + + + + + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + + + Component + + + + Component + + + Component + + + Component + + + Component + + + + + + Component + + + Component + + + + + + DateNavigator.cs + Designer + + + + + + PosWin.cs + Designer + + + + + + + + {36546CE3-335C-4AB6-A2F3-40F8C818BC66} + DotNetBar + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/ItemRect.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/ItemRect.cs new file mode 100644 index 00000000..63afa52f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/ItemRect.cs @@ -0,0 +1,128 @@ +#if FRAMEWORK20 +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Schedule +{ + /// + /// DayRect array management class + /// + public class ItemRects + { + #region Private variables + + private ItemRect[] _ItemRects; + + #endregion + + /// + /// Constructor + /// + /// + /// Rectangle array length + public ItemRects(BaseItem baseItem, int length) + { + _ItemRects = new ItemRect[length]; + + for (int i = 0; i < length; i++) + _ItemRects[i] = new ItemRect(baseItem); + } + + #region Public properties + + /// + /// Gets the Rectangle array + /// + public ItemRect[] Rects + { + get { return (_ItemRects); } + } + + /// + /// Gets and sets a specific array Rectangle + /// + /// Rectangle index to get + /// Rectangle + public ItemRect this[int index] + { + get { return (_ItemRects[index]); } + set { _ItemRects[index] = value; } + } + + #endregion + } + + /// + /// Simple DayRect class + /// + public class ItemRect + { + #region Private variables + + private BaseItem _BaseItem; // BaseItem + private Rectangle _Bounds; // Bounds + private bool _IsSelected; // Rect selection + + #endregion + + /// + /// Constructor + /// + /// BaseItem + public ItemRect(BaseItem baseItem) + { + _BaseItem = baseItem; + } + + #region Public properties + + /// + /// Gets and sets the bounding rect + /// + public Rectangle Bounds + { + get { return (_Bounds); } + set { _Bounds = value; } + } + + /// + /// Gets and sets the rect selection status + /// + public bool IsSelected + { + get { return (_IsSelected); } + + set + { + if (_IsSelected != value) + { + _IsSelected = value; + + Invalidate(); + } + } + } + + #endregion + + #region Public methods + + /// + /// Invalidates the given rectangle + /// + public void Invalidate() + { + if (_BaseItem != null) + { + Control c = (Control)_BaseItem.GetContainerControl(true); + + if (c != null) + c.Invalidate(_Bounds); + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Appointment.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Appointment.cs new file mode 100644 index 00000000..f563b001 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Appointment.cs @@ -0,0 +1,1214 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Collections.ObjectModel; +using System.Collections; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents an calendar appointment. + /// + public class Appointment : INotifyPropertyChanged, INotifySubPropertyChanged + { + #region Private Variables + + private static long AutoIdCounter; + private States _States; + + #endregion + + #region Events + /// + /// Occurs when system time reaches the appointment start time and StartTimeAction is set to fire event. Note that event handler will be called on the thread of System.Timer which is different + /// than UI thread. You should use BeginInvoke calls to marshal the calls to your UI thread. + /// + [Description("Occurs when system time reaches the appointment start time and StartTimeAction is set to fire event.")] + public event EventHandler StartTimeReached; + + #endregion + + #region Constructor + /// + /// Initializes a new instance of the Appointment class. + /// + public Appointment() + { + InitDefaultStates(); + + _Reminders = new ReminderCollection(this); + _AutoId = ++AutoIdCounter; + } + /// + /// Initializes a new instance of the Appointment class. + /// + /// Appointment subject. + /// Appointment start time + /// Appointment end time + public Appointment(DateTime startTime, DateTime endTime, string subject) + : this() + { + Subject = subject; + StartTime = startTime; + EndTime = endTime; + } + + /// + /// Initializes a new instance of the Appointment class. + /// + /// Appointment subject. + /// Appointment start time + /// Appointment end time + /// Appointment owner key + public Appointment(DateTime startTime, DateTime endTime, string subject, string ownerKey) + : this() + { + Subject = subject; + StartTime = startTime; + EndTime = endTime; + OwnerKey = ownerKey; + } + + /// + /// Initializes a new instance of the Appointment class. + /// + /// Appointment subject. + /// Appointment start time + /// Appointment duration in minutes + public Appointment(DateTime startTime, double durationInMinutes, string subject) + : this() + { + Subject = subject; + StartTime = startTime; + EndTime = startTime.AddMinutes(durationInMinutes); + } + + /// + /// Initializes a new instance of the Appointment class. + /// + /// Appointment subject. + /// Appointment start time + /// Appointment duration in minutes + /// Appointment owner key + public Appointment(DateTime startTime, double durationInMinutes, string subject, string ownerKey) + : this() + { + Subject = subject; + StartTime = startTime; + EndTime = startTime.AddMinutes(durationInMinutes); + OwnerKey = ownerKey; + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(States.Visible, true); + } + + #endregion + + #endregion + + #region Internal Implementation + + /// + /// Gets or sets whether appointment is 'private'. This only has + /// meaning in ICS import/export procesing. Default value is false. + /// + [DefaultValue(false)] + public bool Private + { + get { return (TestState(States.Private)); } + + set + { + if (value != Private) + { + bool oldValue = Private; + + SetState(States.Private, value); + + OnPropertyChanged(new PropertyChangedEventArgs("Private")); + } + } + } + + /// + /// Gets or sets whether appointment is visible in user interface views. Default value is true. + /// + [DefaultValue(true)] + public bool Visible + { + get { return (TestState(States.Visible)); } + + set + { + if (value != Visible) + { + bool oldValue = Visible; + + SetState(States.Visible, value); + + OnVisibleChanged(oldValue, value); + } + } + } + + /// + /// Called when Visible property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnVisibleChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Visible")); + } + + private string _Tooltip = ""; + /// + /// Gets or sets the tooltip that is assigned to the appointment view. + /// + [DefaultValue("")] + public string Tooltip + { + get { return _Tooltip; } + set + { + if (value == null) value = ""; + if (value != _Tooltip) + { + object oldValue = _Tooltip; + _Tooltip = value; + OnTooltipChanged(oldValue, value); + } + } + } + + private void OnTooltipChanged(object oldValue, object newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Tooltip")); + + } + private string _CategoryColor; + /// + /// Gets or sets the appointment category color string based key that is used to lookup for appointment background and border colors. + /// Use static members on Appointment class to assign the category color for example Appointment.CategoryRed. + /// + public string CategoryColor + { + get { return _CategoryColor; } + set + { + if (value != _CategoryColor) + { + string oldValue = _CategoryColor; + _CategoryColor = value; + OnCategoryColorChanged(oldValue, value); + } + } + } + + private void OnCategoryColorChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("CategoryColor")); + } + + private string _TimeMarkedAs; + /// + /// Gets or sets how the time used by appointment is marked on calendar. For example Free, Tentative, Busy etc. + /// Use static members on Appointment class to assign the time marker for example Appointment.TimeMarkerBusy + /// + public string TimeMarkedAs + { + get { return _TimeMarkedAs; } + set + { + if (value != _TimeMarkedAs) + { + string oldValue = _TimeMarkedAs; + _TimeMarkedAs = value; + OnTimeMarkedAsChanged(oldValue, value); + } + } + } + private void OnTimeMarkedAsChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("TimeMarkedAs")); + + } + + private ReminderCollection _Reminders = null; + /// + /// Gets the collection of reminders associated with this Appointment. + /// + [Browsable(false)] + public ReminderCollection Reminders + { + get { return _Reminders; } + } + + private string _Subject = ""; + /// + /// Gets or sets the appointment subject. + /// + [DefaultValue("")] + public string Subject + { + get { return _Subject; } + set + { + if (_Subject != value) + { + string oldValue = _Subject; + _Subject = value; + OnSubjectChanged(oldValue, _Subject); + } + } + } + + private void OnSubjectChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Subject")); + } + + private string _Description = ""; + /// + /// Gets or sets the appointment description. + /// + [DefaultValue("")] + public string Description + { + get { return _Description; } + set + { + if (_Description != value) + { + string oldValue = _Description; + _Description = value; + OnDescriptionChanged(oldValue, _Description); + } + } + } + + private void OnDescriptionChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Description")); + } + + private string _DisplayTemplate = ""; + /// + /// Gets or sets the appointment display template. + /// + [DefaultValue("")] + public string DisplayTemplate + { + get { return _DisplayTemplate; } + + set + { + if (_DisplayTemplate != value) + { + _DisplayTemplate = value; + + OnDisplayTemplateChanged(); + } + } + } + + private void OnDisplayTemplateChanged() + { + OnPropertyChanged(new PropertyChangedEventArgs("DisplayTemplate")); + } + + /// + /// Gets or sets whether appointment is selected in the user interface. + /// + [Browsable(false)] + public bool IsSelected + { + get { return (TestState(States.Selected)); } + + set + { + if (value != IsSelected) + { + bool oldValue = IsSelected; + + SetState(States.Selected, value); + + OnIsSelectedChanged(oldValue, value); + } + } + } + + private void OnIsSelectedChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("IsSelected")); + + } + + /// + /// Gets or sets whether appointment modification through user interface is disabled. Default value is false. + /// + [DefaultValue(false)] + public bool Locked + { + get { return (TestState(States.Locked)); } + + set + { + if (value != Locked) + { + bool oldValue = Locked; + + SetState(States.Locked, value); + + OnLockedChanged(oldValue, value); + } + } + } + + private void OnLockedChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Locked")); + + } + + private DateTime _StartTime; + /// + /// Gets or sets the appointment start time. + /// + public DateTime StartTime + { + get { return GetTimeZoneDateTime(_StartTime); } + set + { + value = GetUTCDateTime(CalendarModel.GetCalendarDateTime(value)); + if (!_StartTime.Equals(value)) + { + bool oldMultiDay = this.IsMultiDayOrAllDayEvent; + DateTime oldValue = _StartTime; + _StartTime = value; + OnStartTimeChanged(oldValue, _StartTime); + if(oldMultiDay!=this.IsMultiDayOrAllDayEvent) + OnPropertyChanged(new PropertyChangedEventArgs("IsMultiDayOrAllDayEvent")); + } + } + } + + private void UpdateReminderStartTime(DateTime oldStartTime, DateTime newStartTime) + { + if(oldStartTime==DateTime.MinValue) return; + + foreach (Reminder item in _Reminders) + { + item.ReminderTime = newStartTime.Add(item.ReminderTime.Subtract(oldStartTime)); + } + } + private void OnStartTimeChanged(DateTime oldValue, DateTime newValue) + { + UpdateReminderStartTime(oldValue, newValue); + UpdateNotification(); + OnPropertyChanged(new AppointmentTimePropertyChangedEventArgs("StartTime", oldValue, newValue)); + OnPropertyChanged(new PropertyChangedEventArgs("LocalStartTime")); + } + + internal void InvokeLocalTimePropertyChange() + { + OnPropertyChanged(new PropertyChangedEventArgs("LocalStartTime")); + OnPropertyChanged(new PropertyChangedEventArgs("LocalEndTime")); + } + + private DateTime _EndTime; + /// + /// Gets or sets the appointment end time. + /// + public DateTime EndTime + { + get + { + return GetTimeZoneDateTime(_EndTime); + } + set + { + value = GetUTCDateTime(CalendarModel.GetCalendarDateTime(value)); + if (!_EndTime.Equals(value)) + { + bool oldMultiDay = this.IsMultiDayOrAllDayEvent; + + DateTime oldValue = _EndTime; + _EndTime = value; + OnEndTimeChanged(oldValue, _EndTime); + + if (oldMultiDay != this.IsMultiDayOrAllDayEvent) + OnPropertyChanged(new PropertyChangedEventArgs("IsMultiDayOrAllDayEvent")); + } + } + } + + private void OnEndTimeChanged(DateTime oldValue, DateTime newValue) + { + OnPropertyChanged(new AppointmentTimePropertyChangedEventArgs("EndTime", oldValue, newValue)); + OnPropertyChanged(new PropertyChangedEventArgs("LocalEndTime")); + } + + internal bool InMoveTo + { + get { return TestState(States.InMoveTo); } + set { SetState(States.InMoveTo, value); } + } + + internal bool StartTimeNotificationRegistered + { + get { return TestState(States.StartTimeNotificationRegistered); } + set { SetState(States.StartTimeNotificationRegistered, value); } + } + + /// + /// Moves the appointment to the specified date and time while keeping its duration constant. + /// + /// New start date and time for appointment. + public void MoveTo(DateTime newStartTime) + { + TimeSpan duration = EndTime.Subtract(StartTime); + DateTime oldStartTime = this.LocalStartTime; + try + { + InMoveTo = true; + this.LocalStartTime = newStartTime; + this.LocalEndTime = newStartTime.Add(duration); + + foreach (Reminder item in this.Reminders) + { + TimeSpan span = item.ReminderTime.Subtract(oldStartTime); + item.ReminderTime = newStartTime.Add(span); + } + } + finally + { + InMoveTo = false; + } + } + + private TimeZoneInfo _TimeZone; + /// + /// Gets or sets the time-zone this appointment is defined in. Default value is null which indicates that appointment is + /// in current system time zone. Note that setting the time zone will affect StartTime and EndTime of appointment if set. + /// It will convert them to the TimeZone you set but as absolute values meaning that 10:00 AM in previous time zone + /// will become 10:00 AM in TimeZone you just assigned. + /// + [DefaultValue(null)] + public TimeZoneInfo TimeZone + { + get { return _TimeZone; } + set + { + if (value != _TimeZone) + { + TimeZoneInfo oldValue = _TimeZone; + _TimeZone = value; + OnTimeZoneChanged(oldValue, value); + } + } + } + + private void OnTimeZoneChanged(TimeZoneInfo oldValue, TimeZoneInfo newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("TimeZone")); + // Update start and end time + if (_StartTime.Kind == DateTimeKind.Utc) + { + DateTime date = TimeZoneInfo.ConvertTimeFromUtc(_StartTime, oldValue ?? TimeZoneInfo.Local); + this.StartTime = date; + } + if (_EndTime.Kind == DateTimeKind.Utc) + { + DateTime date = TimeZoneInfo.ConvertTimeFromUtc(_EndTime, oldValue ?? TimeZoneInfo.Local); + this.EndTime = date; + } + } + + internal DateTime GetValidDateTime(DateTime date) + { + if (date == DateTime.MinValue || date == DateTime.MaxValue || date.Kind == DateTimeKind.Utc) + return date; + TimeZoneInfo timeZone = _TimeZone ?? TimeZoneInfo.Local; + if (timeZone.IsInvalidTime(date)) + { + while (timeZone.IsInvalidTime(date)) + date = date.AddHours(1); + } + return date; + } + + internal DateTime GetUTCDateTime(DateTime date) + { + if (date == DateTime.MinValue || date == DateTime.MaxValue || date.Kind == DateTimeKind.Utc) + return date; + if (_TimeZone == null) + return TimeZoneInfo.ConvertTimeToUtc(date); + return TimeZoneInfo.ConvertTimeToUtc(date, _TimeZone); + } + + private DateTime GetTimeZoneDateTime(DateTime date) + { + if (date.Kind != DateTimeKind.Utc) return date; + TimeZoneInfo zone = _TimeZone; + if (zone == null) zone = TimeZoneInfo.Local; + return TimeZoneInfo.ConvertTimeFromUtc(date, zone); + } + + /// + /// Gets or sets the StartTime of appointment in local, display time-zone. + /// + public DateTime LocalStartTime + { + get + { + return GetLocalDateTime(_StartTime); + } + set + { + StartTime = LocalToCurrenTimeZone(value); + } + } + + /// + /// Gets or sets the StartTime of appointment in local, display time-zone. + /// + public DateTime LocalEndTime + { + get + { + return GetLocalDateTime(_EndTime); + } + set + { + EndTime = LocalToCurrenTimeZone(value); + } + } + + /// + /// Gets the UTC Start Time of appointment. + /// + public DateTime UtcStartTime + { + get { return _StartTime; } + } + + /// + /// Gets the UTC End Time of appointment. + /// + public DateTime UtcEndTime + { + get { return _EndTime; } + } + + private DateTime LocalToCurrenTimeZone(DateTime value) + { + if (_TimeZone == null) + { + return TimeZoneInfo.ConvertTimeFromUtc(TimeZoneInfo.ConvertTimeToUtc(value, GetLocalTimeZone()), TimeZoneInfo.Local); + } + + DateTime date = TimeZoneInfo.ConvertTimeToUtc(value, GetLocalTimeZone()); + return TimeZoneInfo.ConvertTimeFromUtc(date, _TimeZone); + } + + internal DateTime GetLocalDateTime(DateTime value) + { + if (value.Kind != DateTimeKind.Utc || value == DateTime.MinValue || value == DateTime.MaxValue) return value; + return TimeZoneInfo.ConvertTimeFromUtc(value, GetLocalTimeZone()); + } + + private TimeZoneInfo GetLocalTimeZone() + { + if (!string.IsNullOrEmpty(_OwnerKey) && _Calendar != null) + { + Owner owner = _Calendar.Owners[_OwnerKey]; + if (owner != null && owner.DisplayTimeZone != null) + return owner.DisplayTimeZone; + } + if (_Calendar == null || _Calendar.DisplayTimeZone == null) return TimeZoneInfo.Local; + return _Calendar.DisplayTimeZone; + } + + private CalendarModel _Calendar = null; + /// + /// Gets the calendar appointment is associated with. + /// + [Browsable(false)] + public CalendarModel Calendar + { + get { return _Calendar; } + internal set + { + if (_Calendar != value) + { + _Calendar = value; + UpdateNotification(); + } + } + } + + private void UpdateNotification() + { + if (_Calendar == null) + { + if (StartTimeNotificationRegistered) + NotificationServer.Unregister(this.StartTimeNotificationRequest); + StartTimeNotificationRegistered = false; + this.StartTimeNotificationRequest = null; + + foreach (Reminder reminder in this.Reminders) + { + reminder.UpdateNotifications(); + } + return; + } + + // Get Now in UTC of current machine, _StartTime is already UTC + DateTime now = TimeZoneInfo.ConvertTimeToUtc(CalendarModel.GetCalendarDateTime(CalendarModel.CurrentDateTime)); + + // Check start-time notification requirement + if (_StartTime != DateTime.MinValue && _StartTimeAction != eStartTimeAction.None && _StartTime > now) + { + if (StartTimeNotificationRegistered) + NotificationServer.Unregister(this.StartTimeNotificationRequest); + NotificationServer.Register(this.StartTimeNotificationRequest); + StartTimeNotificationRegistered = true; + } + else if (StartTimeNotificationRegistered) + NotificationServer.Unregister(this.StartTimeNotificationRequest); + + // Check reminders notification requirement + foreach (Reminder reminder in this.Reminders) + { + reminder.UpdateNotifications(); + } + } + + private DateTime GetNextNotificationTime() + { + DateTime nextNotify = DateTime.MinValue; + + if (_StartTime != DateTime.MinValue && _StartTimeAction != eStartTimeAction.None) + nextNotify = _StartTime; + + return nextNotify; + } + + private bool NeedsNotification + { + get + { + if (_StartTime > DateTime.MinValue && _StartTimeAction != eStartTimeAction.None) + return true; + // Check reminders + + return false; + } + } + + private eStartTimeAction _StartTimeAction = eStartTimeAction.None; + /// + /// Gets or sets the action performed when StartTime of appointment is reached. Default is none. + /// + [DefaultValue(eStartTimeAction.None)] + public eStartTimeAction StartTimeAction + { + get { return _StartTimeAction; } + set + { + if (_StartTimeAction != value) + { + eStartTimeAction oldValue = _StartTimeAction; + _StartTimeAction = value; + OnStartTimeActionChanged(oldValue, _StartTimeAction); + } + } + } + + private void OnStartTimeActionChanged(eStartTimeAction oldValue, eStartTimeAction newValue) + { + if (oldValue == eStartTimeAction.None || newValue == eStartTimeAction.None) + UpdateNotification(); + OnPropertyChanged(new PropertyChangedEventArgs("StartTimeAction")); + } + + private NotificationRequest _StartTimeNotificationRequest = null; + private NotificationRequest StartTimeNotificationRequest + { + get + { + if (_StartTimeNotificationRequest == null) + { + _StartTimeNotificationRequest = new NotificationRequest(_StartTime, new NotificationServerEventHandler(OnStartTimeNotification)); + } + else + _StartTimeNotificationRequest.NotificationTime = _StartTime; + return _StartTimeNotificationRequest; + } + set + { + _StartTimeNotificationRequest = value; + } + } + + private void OnStartTimeNotification(NotificationRequest request, NotificationServerEventArgs e) + { + if (_StartTimeAction != eStartTimeAction.None) + { + this.StartTimeNotificationRequest = null; + ProcessStartTimeReachedActions(); + } + } + + private void ProcessStartTimeReachedActions() + { + if (_Calendar != null) + { + _Calendar.InvokeAppointmentStartTimeReached(this); + } + + if (_StartTimeAction == eStartTimeAction.None) return; + + if ((_StartTimeAction & eStartTimeAction.StartTimeReachedEvent) != 0) + { + OnStartTimeReached(new EventArgs()); + } + + if ((_StartTimeAction & eStartTimeAction.Command) != 0) + { + throw new NotImplementedException(); + } + } + + /// + /// Raises the StartTimeReached event. + /// + /// Provides event arguments. + protected virtual void OnStartTimeReached(EventArgs e) + { + EventHandler h = StartTimeReached; + if (h != null) + h(this, e); + } + + /// + /// Gets whether this appointment is the recurring appointment instance. + /// + [Browsable(false)] + public bool IsRecurringInstance + { + get { return (TestState(States.RecurringInstance)); } + + set + { + if (value != IsRecurringInstance) + { + bool oldValue = IsRecurringInstance; + + SetState(States.RecurringInstance, value); + + OnIsRecurringInstanceChanged(oldValue, value); + } + } + } + + private void OnIsRecurringInstanceChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("IsRecurringInstance")); + } + + private Appointment _RootAppointment = null; + /// + /// Gets or sets the root appointment if this instance is an recurring appointment instance (IsRecurringInstance=true). + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Appointment RootAppointment + { + get { return _RootAppointment; } + internal set { _RootAppointment = value; } + } + + private object _Tag = null; + /// + /// Gets or sets additional data associated with the object. + /// + [DefaultValue(null)] + public object Tag + { + get { return _Tag; } + set + { + if (value != _Tag) + { + object oldValue = _Tag; + _Tag = value; + OnTagChanged(oldValue, value); + } + } + } + + private void OnTagChanged(object oldValue, object newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Tag")); + + } + + private AppointmentRecurrence _Recurrence = null; + /// + /// Gets or sets the reference to the appointment recurrence definition object which defines + /// recurring appointment properties and range. + /// + [DefaultValue(null)] + public AppointmentRecurrence Recurrence + { + get { return _Recurrence; } + set + { + if (value != _Recurrence) + { + AppointmentRecurrence oldValue = _Recurrence; + _Recurrence = value; + OnRecurrenceChanged(oldValue, value); + } + } + } + + private void OnRecurrenceChanged(AppointmentRecurrence oldValue, AppointmentRecurrence newValue) + { + if (oldValue != null) + { + oldValue.Appointment = null; + oldValue.SubPropertyChanged -= this.ChildPropertyChangedEventHandler; + } + + if (newValue != null) + { + if (newValue.Appointment != null) + throw new ArgumentException("Recurrence value already assigned to the appointment. Recurrence can be assigned to single appointment only"); + newValue.Appointment = this; + newValue.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + } + OnPropertyChanged(new PropertyChangedEventArgs("Recurrence")); + } + + private SubPropertyChangedEventHandler _ChildPropertyChangedEventHandler = null; + private SubPropertyChangedEventHandler ChildPropertyChangedEventHandler + { + get + { + if (_ChildPropertyChangedEventHandler == null) _ChildPropertyChangedEventHandler = new SubPropertyChangedEventHandler(ChildPropertyChanged); + return _ChildPropertyChangedEventHandler; + } + } + + private void ChildPropertyChanged(object sender, SubPropertyChangedEventArgs e) + { + OnSubPropertyChanged(e); + } + + /// + /// Creates an copy of the appointment. + /// + /// Appointment copy. + public virtual Appointment Copy() + { + Appointment copy = + Activator.CreateInstance(this.GetType()) as Appointment; + + copy.OwnerKey = this.OwnerKey; + copy.Description = this.Description; + copy.EndTime = this.EndTime; + copy.CategoryColor = this.CategoryColor; + copy.DisplayTemplate = this.DisplayTemplate; + copy.ImageAlign = this.ImageAlign; + copy.ImageKey = this.ImageKey; + copy.Locked = this.Locked; + copy.TimeMarkedAs = this.TimeMarkedAs; + copy.TimeZone = this.TimeZone; + copy.Tooltip = this.Tooltip; + + if (_Reminders != null) + { + foreach (Reminder rem in _Reminders) + copy.Reminders.Add(rem.Copy()); + } + + copy.StartTime = this.StartTime; + copy.StartTimeAction = this.StartTimeAction; + + if (StartTimeReached != null) + copy.StartTimeReached = (EventHandler)this.StartTimeReached.Clone(); + + copy.Subject = this.Subject; + copy.Tag = this.Tag; + + return copy; + } + + private string _OwnerKey = ""; + /// + /// Gets or sets the owner of the appointment. Default value is empty string which indicates default owner. + /// + public string OwnerKey + { + get { return _OwnerKey; } + set + { + if (value == null) value = ""; + if (value != _OwnerKey) + { + string oldValue = _OwnerKey; + _OwnerKey = value; + OnOwnerKeyChanged(oldValue, value); + } + } + } + + private void OnOwnerKeyChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("OwnerKey")); + } + + /// + /// Gets whether appointment is all day event or whether it spans multiple days. + /// + public bool IsMultiDayOrAllDayEvent + { + get + { + if (this.StartTime < this.EndTime && (this.EndTime.Subtract(this.StartTime).TotalDays >= 1 || !DateTimeHelper.IsSameDay(this.StartTime, this.EndTime))) + return true; + return false; + } + } + + private int _Id = 0; + /// + /// Gets or sets the appointment identifier. This property is provided for your usage in serialization scenarios. It is not set by the control. + /// + [DefaultValue(0)] + public int Id + { + get { return _Id; } + set + { + if (value != _Id) + { + int oldValue = _Id; + _Id = value; + OnIdChanged(oldValue, value); + } + } + } + + private void OnIdChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Id")); + } + + private long _AutoId; + /// + /// Gets the automatically generated identifier that identifies appointment. + /// + public long AutoId + { + get + { + return _AutoId; + } + } + + public override string ToString() + { + return string.Format("Subject: {0}, StartTime: {1}, EndTime: {2}, Id: {3}, AutoId: {4}", this.Subject, this.StartTime, this.EndTime, this.Id, this.AutoId); + } + + private string _ImageKey; + /// + /// Gets or sets the image key for the image displayed on appointment view. ImageList property on CalendarView must be set for this property to work. + /// + public string ImageKey + { + get { return _ImageKey; } + set + { + if (value != _ImageKey) + { + string oldValue = _ImageKey; + _ImageKey = value; + OnImageKeyChanged(oldValue, value); + } + } + } + + private void OnImageKeyChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ImageKey")); + } + + private eImageContentAlignment _ImageAlign = eImageContentAlignment.TopLeft; + /// + /// Gets or sets the image alignment in relation to the appointment view content. Default value is TopLeft. + /// + public eImageContentAlignment ImageAlign + { + get { return _ImageAlign; } + set + { + if (value != _ImageAlign) + { + eImageContentAlignment oldValue = _ImageAlign; + _ImageAlign = value; + OnImageAlignChanged(oldValue, value); + } + } + } + + private void OnImageAlignChanged(eImageContentAlignment oldValue, eImageContentAlignment newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ImageAlign")); + + } + #endregion + + #region States + + [Flags] + private enum States : uint + { + ReminderNotificationRegistered = (1U << 0), + StartTimeNotificationRegistered = (1U << 1), + + Locked = (1U << 2), + Selected = (1U << 3), + Private = (1U << 4), + Visible = (1U << 5), + + InMoveTo = (1U << 6), + RecurringInstance = (1U << 7), + } + + #region TestState + + private bool TestState(States state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(States state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #endregion + + #region Static Members + public static readonly string CategoryYellow = "Yellow"; + public static readonly string CategoryDefault = null; + public static readonly string CategoryBlue = "Blue"; + public static readonly string CategoryGreen = "Green"; + public static readonly string CategoryOrange = "Orange"; + public static readonly string CategoryPurple = "Purple"; + public static readonly string CategoryRed = "Red"; + + public static readonly string TimerMarkerDefault = null; + public static readonly string TimerMarkerBusy = "Busy"; + public static readonly string TimerMarkerFree = "Free"; + public static readonly string TimerMarkerTentative = "Tentative"; + public static readonly string TimerMarkerOutOfOffice = "OutOfOffice"; + + internal static readonly string RecurrencePropertyName = "Recurrence"; + #endregion + + #region INotifyPropertyChanged Members + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + if (eh != null) eh(this, e); + OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e)); + } + #endregion + + #region INotifySubPropertyChanged Members + /// + /// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key + /// difference that it occurs for the property changed of child objects as well. + /// + public event SubPropertyChangedEventHandler SubPropertyChanged; + /// + /// Raises the SubPropertyChanged event. + /// + /// Event arguments + protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e) + { + SubPropertyChangedEventHandler eh = SubPropertyChanged; + if (eh != null) eh(this, e); + } + #endregion + } + /// + /// Provides more information about the time change for appointment StartTime and EndTime property changes. + /// + public class AppointmentTimePropertyChangedEventArgs : PropertyChangedEventArgs + { + /// + /// Gets the old value. + /// + public readonly DateTime OldTimeValue; + /// + /// Gets the new value. + /// + public readonly DateTime NewTimeValue; + + /// + /// Initializes a new instance of the AppointmentTimePropertyChangedEventArgs class. + /// + /// + /// + public AppointmentTimePropertyChangedEventArgs(string propertyName, DateTime oldTimeValue, DateTime newTimeValue) + : base(propertyName) + { + OldTimeValue = oldTimeValue; + NewTimeValue = newTimeValue; + } + } + + public enum eImageContentAlignment + { + BottomCenter = 0x200, + BottomLeft = 0x100, + BottomRight = 0x400, + MiddleCenter = 0x20, + MiddleLeft = 0x10, + MiddleRight = 0x40, + TopCenter = 2, + TopLeft = 1, + TopRight = 4 + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/AppointmentCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/AppointmentCollection.cs new file mode 100644 index 00000000..c88b7d4e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/AppointmentCollection.cs @@ -0,0 +1,105 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; + +namespace DevComponents.Schedule.Model +{ + public class AppointmentCollection : Collection + { + #region Constructor + /// + /// Initializes a new instance of the AppointmentCollection class. + /// + /// + public AppointmentCollection(CalendarModel calendar) + { + _Calendar = calendar; + } + + #endregion + + #region Internal Implementation + + + private CalendarModel _Calendar = null; + /// + /// Gets the calendar collection is associated with. + /// + public CalendarModel Calendar + { + get { return _Calendar; } + internal set { _Calendar = value; } + } + + protected override void InsertItem(int index, Appointment item) + { + OnBeforeInsert(index, item); + base.InsertItem(index, item); + OnAfterInsert(index, item); + } + + private void OnAfterInsert(int index, Appointment item) + { + _Calendar.InternalAppointmentAdded(item); + } + + private void OnBeforeInsert(int index, Appointment item) + { + item.Calendar = _Calendar; + } + + protected override void SetItem(int index, Appointment item) + { + Appointment app = this[index]; + OnBeforeSetItem(index, app, item); + base.SetItem(index, item); + OnAfterSetItem(index, app, item); + } + + private void OnAfterSetItem(int index, Appointment oldItem, Appointment newItem) + { + _Calendar.InternalAppointmentRemoved(oldItem, false); + _Calendar.InternalAppointmentAdded(newItem); + } + + private void OnBeforeSetItem(int index, Appointment oldItem, Appointment newItem) + { + oldItem.Calendar = null; + newItem.Calendar = _Calendar; + } + + protected override void RemoveItem(int index) + { + Appointment app = this[index]; + OnBeforeRemove(index); + base.RemoveItem(index); + OnAfterRemove(index, app); + } + + private void OnAfterRemove(int index, Appointment app) + { + _Calendar.InternalAppointmentRemoved(app, false); + } + + private void OnBeforeRemove(int index) + { + this[index].Calendar = null; + } + + protected override void ClearItems() + { + foreach (Appointment item in this) + { + item.Calendar = null; + _Calendar.InternalAppointmentRemoved(item, true); + } + base.ClearItems(); + _Calendar.InternalAppointmentsCleared(); + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/AppointmentRecurrence.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/AppointmentRecurrence.cs new file mode 100644 index 00000000..4a488efe --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/AppointmentRecurrence.cs @@ -0,0 +1,378 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using DevComponents.Schedule.Model.Primitives; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents appointment recurrence definition. + /// + public class AppointmentRecurrence : INotifyPropertyChanged, INotifySubPropertyChanged + { + #region Internal Implementation + public AppointmentRecurrence() + { + _SkippedRecurrences = new CustomCollection(); + _SkippedRecurrences.CollectionChanged += new NotifyCollectionChangedEventHandler(SkippedRecurrencesCollectionChanged); + } + + private eRecurrenceRangeLimitType _RangeType = eRecurrenceRangeLimitType.NoEndDate; + /// + /// Gets or sets the range type for the recurrence. Default value is no end date for recurrence. + /// + [DefaultValue(eRecurrenceRangeLimitType.NoEndDate)] + public eRecurrenceRangeLimitType RangeLimitType + { + get { return _RangeType; } + set + { + if (_RangeType != value) + { + eRecurrenceRangeLimitType oldValue = _RangeType; + _RangeType = value; + OnRangeTypeChanged(oldValue, _RangeType); + } + } + } + + private void OnRangeTypeChanged(eRecurrenceRangeLimitType oldValue, eRecurrenceRangeLimitType newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RangeLimitType")); + } + + private DateTime _RangeEndDate = DateTime.MinValue; + /// + /// Gets or sets the recurrence end date. To specify the end date for recurrence set this property and RangeLimitType property to RangeEndDate. + /// + public DateTime RangeEndDate + { + get { return _RangeEndDate; } + set + { + if (_RangeEndDate != value) + { + DateTime oldValue = _RangeEndDate; + _RangeEndDate = value; + OnRangeEndDateChanged(oldValue, _RangeEndDate); + } + } + } + + private void OnRangeEndDateChanged(DateTime oldValue, DateTime newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RangeEndDate")); + } + + private int _RangeNumberOfOccurrences = 0; + /// + /// Gets or sets number of occurrences after which recurrence ends. To specify limited number of recurrences + /// set this property and set RangeLimitType to RangeNumberOfOccurrences. + /// + [DefaultValue(0)] + public int RangeNumberOfOccurrences + { + get { return _RangeNumberOfOccurrences; } + set + { + if (_RangeNumberOfOccurrences != value) + { + if (value < 0) throw new ArgumentException("Negative values not allows for range limit."); + + int oldValue = _RangeNumberOfOccurrences; + _RangeNumberOfOccurrences = value; + OnRangeNumberOfOccurrencesChanged(oldValue, _RangeNumberOfOccurrences); + } + } + } + + private void OnRangeNumberOfOccurrencesChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RangeNumberOfOccurrences")); + } + + private object _Tag = null; + /// + /// Gets or sets additional data associated with the object. + /// + [DefaultValue(null)] + public object Tag + { + get { return _Tag; } + set + { + if (value != _Tag) + { + object oldValue = _Tag; + _Tag = value; + OnTagChanged(oldValue, value); + } + } + } + + private void OnTagChanged(object oldValue, object newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Tag")); + + } + + private eRecurrencePatternType _RecurrenceType = eRecurrencePatternType.Daily; + /// + /// Gets or sets the recurring frequency for appointment i.e. daily, weekly, monthly or yearly. + /// Default value is Daily. + /// + [DefaultValue(eRecurrencePatternType.Daily)] + public eRecurrencePatternType RecurrenceType + { + get { return _RecurrenceType; } + set + { + if (value != _RecurrenceType) + { + eRecurrencePatternType oldValue = _RecurrenceType; + _RecurrenceType = value; + OnRecurrenceTypeChanged(oldValue, value); + } + } + } + + private void OnRecurrenceTypeChanged(eRecurrencePatternType oldValue, eRecurrencePatternType newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RecurrenceType")); + } + + internal void GenerateSubset(AppointmentSubsetCollection subsetCollection, DateTime startDate, DateTime endDate) + { + IRecurrenceGenerator generator = GetRecurrenceGenerator(); + + if (_RecurrenceType == eRecurrencePatternType.Daily) + { + generator.GenerateDailyRecurrence(subsetCollection, this, startDate, endDate); + } + else if (_RecurrenceType == eRecurrencePatternType.Weekly) + { + generator.GenerateWeeklyRecurrence(subsetCollection, this, startDate, endDate); + } + else if (_RecurrenceType == eRecurrencePatternType.Monthly) + { + generator.GenerateMonthlyRecurrence(subsetCollection, this, startDate, endDate); + } + else if (_RecurrenceType == eRecurrencePatternType.Yearly) + { + generator.GenerateYearlyRecurrence(subsetCollection, this, startDate, endDate); + } + } + + private IRecurrenceGenerator _Generator = null; + private IRecurrenceGenerator GetRecurrenceGenerator() + { + if (_Generator == null) _Generator = new RecurrenceGenerator(); + return _Generator; + } + + private Appointment _Appointment; + /// + /// Gets reference to appointment recurrence is assigned to. + /// + [Browsable(false)] + public Appointment Appointment + { + get { return _Appointment; } + internal set { _Appointment = value; } + } + + private DailyRecurrenceSettings _Daily; + /// + /// Gets the settings for Daily recurrence type. + /// + [Browsable(false)] + public DailyRecurrenceSettings Daily + { + get + { + if (_Daily == null) + { + _Daily = new DailyRecurrenceSettings(this); + _Daily.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + } + return _Daily; + } + } + + private WeeklyRecurrenceSettings _Weekly; + /// + /// Gets the settings for Weekly recurrence type. + /// + public WeeklyRecurrenceSettings Weekly + { + get + { + if (_Weekly == null) + { + _Weekly = new WeeklyRecurrenceSettings(this); + _Weekly.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + } + return _Weekly; + } + } + + private MonthlyRecurrenceSettings _Monthly; + /// + /// Gets the settings for monthly recurrence type. + /// + [Browsable(false)] + public MonthlyRecurrenceSettings Monthly + { + get + { + if (_Monthly == null) + { + _Monthly = new MonthlyRecurrenceSettings(this); + _Monthly.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + } + return _Monthly; + } + } + + private YearlyRecurrenceSettings _Yearly = null; + /// + /// Gets the settings for yearly recurrence type. + /// + public YearlyRecurrenceSettings Yearly + { + get + { + if (_Yearly == null) + { + _Yearly = new YearlyRecurrenceSettings(this); + _Yearly.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + } + return _Yearly; + } + } + + private DateTime _RecurrenceStartDate = DateTime.MinValue; + /// + /// Gets or sets the recurrence start date. Default value is DateTime.MinValue which indicates that recurrence starts after + /// the appointment ends. + /// + public DateTime RecurrenceStartDate + { + get { return _RecurrenceStartDate; } + set + { + if (value != _RecurrenceStartDate) + { + DateTime oldValue = _RecurrenceStartDate; + _RecurrenceStartDate = value; + OnRecurrenceStartDateChanged(oldValue, value); + } + } + } + + private void OnRecurrenceStartDateChanged(DateTime oldValue, DateTime newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RecurrenceStartDate")); + } + + private SubPropertyChangedEventHandler _ChildPropertyChangedEventHandler = null; + private SubPropertyChangedEventHandler ChildPropertyChangedEventHandler + { + get + { + if (_ChildPropertyChangedEventHandler == null) _ChildPropertyChangedEventHandler = new SubPropertyChangedEventHandler(ChildPropertyChanged); + return _ChildPropertyChangedEventHandler; + } + } + + private void ChildPropertyChanged(object sender, SubPropertyChangedEventArgs e) + { + OnSubPropertyChanged(e); + } + + private CustomCollection _SkippedRecurrences = null; + /// + /// Gets or set the list of dates on which the recurrences are skipped. + /// + public CustomCollection SkippedRecurrences + { + get + { + return _SkippedRecurrences; + } + } + private void SkippedRecurrencesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + OnPropertyChanged(new PropertyChangedEventArgs("SkippedRecurrences")); + } + + private bool _IndependentVisibility = false; + /// + /// Gets or sets whether generated recurring appointments have independent Visible property setting from root Appointment. + /// When set to true recurring appointment instances will not by default have Visible property set to the Visible property of root appointment. + /// Default value is false which means recurring instances by default have Visible property set to the root appointment Visible property. + /// + public bool IndependentVisibility + { + get { return _IndependentVisibility; } + set + { + if (value != _IndependentVisibility) + { + bool oldValue = _IndependentVisibility; + _IndependentVisibility = value; + OnIndependentVisibilityChanged(oldValue, value); + } + } + } + /// + /// Called when IndependentVisibility property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnIndependentVisibilityChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("IndependentVisibility")); + } + + #endregion + + #region INotifyPropertyChanged Members + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + if (eh != null) eh(this, e); + OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e)); + } + #endregion + + #region INotifySubPropertyChanged Members + /// + /// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key + /// difference that it occurs for the property changed of child objects as well. + /// + public event SubPropertyChangedEventHandler SubPropertyChanged; + /// + /// Raises the SubPropertyChanged event. + /// + /// Event arguments + protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e) + { + SubPropertyChangedEventHandler eh = SubPropertyChanged; + if (eh != null) eh(this, e); + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/AppointmentSubsetCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/AppointmentSubsetCollection.cs new file mode 100644 index 00000000..995fd1a2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/AppointmentSubsetCollection.cs @@ -0,0 +1,232 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; +using DevComponents.Schedule.Model.Primitives; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents subset of appointments collection. + /// + public class AppointmentSubsetCollection : CustomCollection + { + #region Private Variables + private DateTime _StartDate = DateTime.MinValue; + private DateTime _EndDate = DateTime.MinValue; + #endregion + + #region Constructor + /// + /// Initializes a new instance of the AppointmentSubsetCollection class with appointments between given start and end date. + /// + /// + /// + /// + public AppointmentSubsetCollection(CalendarModel calendar, DateTime start, DateTime end) + { + _Calendar = calendar; + _StartDate = start; + _EndDate = end; + PopulateCollection(); + } + #endregion + + #region Internal Implementation + + private CalendarModel _Calendar = null; + /// + /// Gets the calendar collection is associated with this collection. + /// + public CalendarModel Calendar + { + get { return _Calendar; } + internal set { _Calendar = value; } + } + + protected override void InsertItem(int index, Appointment item) + { + OnBeforeInsert(index, item); + base.InsertItem(index, item); + } + + private void OnBeforeInsert(int index, Appointment item) + { + item.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + item.Calendar = _Calendar; + if (item.IsRecurringInstance && _Calendar != null) + _Calendar.InternalAppointmentAdded(item); + + } + + protected override void SetItem(int index, Appointment item) + { + OnBeforeSetItem(index, item); + base.SetItem(index, item); + } + + private void OnBeforeSetItem(int index, Appointment item) + { + Appointment app = this[index]; + app.SubPropertyChanged -= this.ChildPropertyChangedEventHandler; + app.Calendar = null; + item.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + app.Calendar = _Calendar; + } + + protected override void RemoveItem(int index) + { + OnBeforeRemove(index); + base.RemoveItem(index); + } + + private void OnBeforeRemove(int index) + { + Appointment item = this[index]; + OnAppointmentRemoved(item); + } + + private void OnAppointmentRemoved(Appointment item) + { + item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler; + if (item.IsRecurringInstance && _Calendar != null) + _Calendar.InternalAppointmentRemoved(item, false); + if (item.IsRecurringInstance) + item.Calendar = null; + } + protected override void ClearItems() + { + foreach (Appointment item in this.GetItemsDirect()) + { + OnAppointmentRemoved(item); + } + base.ClearItems(); + } + + private void PopulateCollection() + { + this.Clear(); + + foreach (Appointment app in _Calendar.Appointments) + { + if (app.LocalStartTime >= _StartDate && app.LocalStartTime <= _EndDate || app.LocalEndTime > _StartDate && (app.LocalEndTime <= _EndDate || app.LocalStartTime < _StartDate)) + { + this.Add(app); + } + if (app.Recurrence != null && IsRecurrenceInRange(app, _StartDate, _EndDate)) + { + int count = this.GetItemsDirect().Count; + app.Recurrence.GenerateSubset(this, _StartDate, _EndDate); + if (count == this.GetItemsDirect().Count && TotalDaysDuration(app.StartTime, app.EndTime) >= 1 && + app.LocalEndTime < _StartDate) + { + // Nothing generated lets wind back and look to see is there an recurrence that needs to be captured in this view + int daysLookBack = TotalDaysDuration(app.StartTime, app.EndTime); + DateTime start = _StartDate; + for (int i = 0; i < daysLookBack; i++) + { + start = start.AddDays(-1); + AppointmentSubsetCollection dayCollection = _Calendar.GetDay(start).Appointments; + foreach (Appointment subAppointment in dayCollection) + { + if (subAppointment.IsRecurringInstance && subAppointment.RootAppointment == app && + (subAppointment.LocalStartTime >= _StartDate && subAppointment.LocalStartTime <= _EndDate || + subAppointment.LocalEndTime > _StartDate && (subAppointment.LocalEndTime <= _EndDate || + subAppointment.LocalStartTime < _StartDate))) + { + this.Add(subAppointment); + daysLookBack = -1; + break; + } + } + } + } + } + } + _IsCollectionUpToDate = true; + } + + private int TotalDaysDuration(DateTime startTime, DateTime endTime) + { + if (endTime.Hour == 0 && endTime.Minute == 0 && endTime.Second == 0) + endTime = endTime.AddMinutes(-1); + return (int)Math.Max(0, Math.Ceiling(endTime.Date.Subtract(startTime.Date).TotalDays)); + } + + private bool IsRecurrenceInRange(Appointment app, DateTime startDate, DateTime endDate) + { + if (app.Recurrence.RecurrenceType == eRecurrencePatternType.Yearly) + { + // Simple range check on number of occurrences + if (app.Recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && app.LocalEndTime.Subtract(endDate).TotalDays / 365 > app.Recurrence.RangeNumberOfOccurrences) + return false; + // Date check based on next expected recurrence date + if (app.Recurrence.Yearly.RepeatInterval > 1) + { + DateTime nextRecurrence = DateTimeHelper.MaxDate(app.Recurrence.RecurrenceStartDate, app.EndTime.AddDays(1).Date); + while (nextRecurrence < startDate) + nextRecurrence = RecurrenceGenerator.GetNextYearlyRecurrence(app.Recurrence, nextRecurrence); + if (nextRecurrence > endDate || nextRecurrence.Add(endDate.Subtract(startDate)) < startDate) + return false; + } + else + { + + DateTime nextRecurrence = RecurrenceGenerator.GetNextYearlyRecurrence(app.Recurrence, startDate.Date.AddDays(-startDate.DayOfYear)); + if (nextRecurrence > endDate || nextRecurrence.Add(endDate.Subtract(startDate)) < startDate) + return false; + } + } + + if (app.Recurrence.RangeEndDate == DateTime.MinValue || app.Recurrence.RangeEndDate >= _EndDate || app.Recurrence.RangeEndDate < _EndDate && app.Recurrence.RangeEndDate > _StartDate) + return true; + + return false; + } + + private SubPropertyChangedEventHandler _ChildPropertyChangedEventHandler = null; + private SubPropertyChangedEventHandler ChildPropertyChangedEventHandler + { + get + { + if (_ChildPropertyChangedEventHandler == null) _ChildPropertyChangedEventHandler = new SubPropertyChangedEventHandler(ChildPropertyChanged); + return _ChildPropertyChangedEventHandler; + } + } + + private void ChildPropertyChanged(object sender, SubPropertyChangedEventArgs e) + { + InvalidateCollection(); + } + + /// + /// Invalidates collection content due to the change to appointments or some other condition. Invalidating collection + /// content causes the collection elements to be re-generated on next collection read access. + /// + public virtual void InvalidateCollection() + { + _IsCollectionUpToDate = false; + } + + protected override void OnCollectionReadAccess() + { + if (!_IsCollectionUpToDate) PopulateCollection(); + base.OnCollectionReadAccess(); + } + + private bool _IsCollectionUpToDate = false; + internal bool IsCollectionUpToDate + { + get { return _IsCollectionUpToDate; } + set + { + _IsCollectionUpToDate = value; + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/BaseWorkDay.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/BaseWorkDay.cs new file mode 100644 index 00000000..050d0b9e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/BaseWorkDay.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Defines a working day. + /// + public abstract class BaseWorkDay : INotifyPropertyChanged, INotifySubPropertyChanged + { + #region Internal Implementation + protected WorkTime _WorkStartTime = new WorkTime(8, 0); + /// + /// Gets or sets the work start time. + /// + public WorkTime WorkStartTime + { + get { return _WorkStartTime; } + set + { + WorkTime oldValue = _WorkStartTime; + _WorkStartTime = value; + OnWorkStartTimeChanged(oldValue, value); + } + } + /// + /// Called when WorkStartTime has changed. + /// + /// Old property value. + /// New property value. + protected virtual void OnWorkStartTimeChanged(WorkTime oldValue, WorkTime newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("WorkStartTime")); + } + + protected WorkTime _WorkEndTime = new WorkTime(17, 0); + /// + /// Gets or sets the work end time. + /// + public WorkTime WorkEndTime + { + get { return _WorkEndTime; } + set + { + WorkTime oldValue = _WorkEndTime; + _WorkEndTime = value; + OnWorkEndTimeChanged(oldValue, value); + } + } + /// + /// Called when WorkEndTime has changed. + /// + /// Old property value. + /// New property value. + protected virtual void OnWorkEndTimeChanged(WorkTime oldValue, WorkTime newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("WorkEndTime")); + + } + + private CalendarModel _Calendar = null; + /// + /// Gets the calendar work day is associated with. + /// + [Browsable(false)] + public CalendarModel Calendar + { + get { return _Calendar; } + internal set + { + if (_Calendar != value) + { + _Calendar = value; + } + } + } + #endregion + + + #region INotifyPropertyChanged Members + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + if (eh != null) eh(this, e); + OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e)); + } + #endregion + + #region INotifySubPropertyChanged Members + /// + /// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key + /// difference that it occurs for the property changed of child objects as well. + /// + public event SubPropertyChangedEventHandler SubPropertyChanged; + /// + /// Raises the SubPropertyChanged event. + /// + /// Event arguments + protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e) + { + SubPropertyChangedEventHandler eh = SubPropertyChanged; + if (eh != null) eh(this, e); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/CalendarModel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/CalendarModel.cs new file mode 100644 index 00000000..610da751 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/CalendarModel.cs @@ -0,0 +1,595 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Globalization; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents the calendar model control. + /// + public class CalendarModel : INotifyPropertyChanged, INotifySubPropertyChanged + { + #region Events + /// + /// Occurs when an appointment has been added to the model. + /// + public event AppointmentEventHandler AppointmentAdded; + /// + /// Occurs when an appointment has been removed from the model. + /// + public event AppointmentEventHandler AppointmentRemoved; + /// + /// Occurs when AppointmentStartTime has been reached. This event can be used to trigger appointment reminders. Note that event handler will be called on the thread of System.Timer which is different + /// than UI thread. You should use BeginInvoke calls to marshal the calls to your UI thread. + /// + public event AppointmentEventHandler AppointmentStartTimeReached; + /// + /// Occurs when Reminder's ReminderTime has been reached. Note that event handler will be called on the thread of System.Timer which is different + /// than UI thread. You should use BeginInvoke calls to marshal the calls to your UI thread. + /// + [Description("Occurs when Reminder's ReminderTime has been reached.")] + public event ReminderEventHandler ReminderNotification; + /// + /// Occurs when Appointments collection has been cleared. + /// + public event EventHandler AppointmentsCleared; + #endregion + + #region Constructor + + /// + /// Initializes a new instance of the CalendarModel class. + /// + public CalendarModel() + { + _Appointments = new AppointmentCollection(this); + _Owners = new OwnerCollection(this); + _WorkDays = new WorkDayCollection(this); + _CalendarWorkDays = new CalendarWorkDayCollection(this); + // Initialize default work-days + _WorkDays.Add(new WorkDay(DayOfWeek.Monday)); + _WorkDays.Add(new WorkDay(DayOfWeek.Tuesday)); + _WorkDays.Add(new WorkDay(DayOfWeek.Wednesday)); + _WorkDays.Add(new WorkDay(DayOfWeek.Thursday)); + _WorkDays.Add(new WorkDay(DayOfWeek.Friday)); + } + #endregion + + #region Internal Implementation + private AppointmentCollection _Appointments; + /// + /// Gets appointments associated with this calendar. + /// + public AppointmentCollection Appointments + { + get { return _Appointments; } + } + + private OwnerCollection _Owners; + /// + /// Gets owners of appointments associated with this calendar. + /// + public OwnerCollection Owners + { + get { return _Owners; } + } + + private WorkDayCollection _WorkDays; + /// + /// Gets working days associated with this calendar. + /// + public WorkDayCollection WorkDays + { + get { return _WorkDays; } + } + + private CalendarWorkDayCollection _CalendarWorkDays = null; + /// + /// Gets the calendar/date based working days collection. This collection allows you to specify working time for specific dates. Values specified here take precedence over working hours set through WorkDays collection. + /// + public CalendarWorkDayCollection CalendarWorkDays + { + get { return _CalendarWorkDays; } + } + + /// + /// Gets reference to the Day object which represents day in calendar. + /// + /// Date to retrieve day for. + /// Returns reference to Day object. + public Day GetDay(DateTime date) + { + Year year = null; + if(!_Years.TryGetValue(date.Year, out year)) + year = CreateYear(date.Year); + + return year.Months[date.Month - 1].Days[date.Day - 1]; + //return new Day(date, this); + } + + private Year CreateYear(int y) + { + Year year = new Year(y, this); + _Years.Add(y, year); + return year; + } + + /// + /// Returns true if appointment overlapps with one or more of the appointments in the model. + /// + /// Appointment to check overlap for. + /// true if there are appointments overlapping appointment otherwise false. + public bool ContainsOverlappingAppointments(Appointment app) + { + int duration = (int)Math.Max(1, app.EndTime.Subtract(app.StartTime).TotalDays); + for (int i = 0; i < duration; i++) + { + DateTime date = app.StartTime.Date.AddDays(i); + Day day = GetDay(date); + foreach (Appointment item in day.Appointments) + { + if (item != app && DateTimeHelper.TimePeriodsOverlap(item.StartTime, item.EndTime, app.StartTime, app.EndTime)) + return true; + } + } + return false; + } + + /// + /// Finds appointments that overlap with the parameter appointment. + /// + /// Appointment to use to find overlapps + /// Array of appointments that overlap parameter. + public Appointment[] FindOverlappingAppointments(Appointment app) + { + List overlaps = new List(); + int duration = (int)Math.Max(1, app.EndTime.Subtract(app.StartTime).TotalDays); + for (int i = 0; i < duration; i++) + { + DateTime date = app.StartTime.Date.AddDays(i); + Day day = GetDay(date); + foreach (Appointment item in day.Appointments) + { + if (item != app && DateTimeHelper.TimePeriodsOverlap(item.StartTime, item.EndTime, app.StartTime, app.EndTime)) + overlaps.Add(item); + } + } + + return overlaps.ToArray(); + } + + //public Month GetMonth(int year, int month) + //{ + // return null; + //} + + //private HolidaysCollection _Holidays; + ///// + ///// Gets the collection of holidays associated with calendar. + ///// + //public HolidaysCollection Holidays + //{ + // get { return _Holidays; } + //} + + /// + /// Returns the calendar date time which has seconds part set to 0. + /// + /// + /// + public static DateTime GetCalendarDateTime(DateTime dt) + { + if (_PreciseDateTimeValues) + return dt; + return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0); + } + + private static bool _PreciseDateTimeValues = false; + /// + /// Gets or sets whether Appointment StartTime and EndTime values retain seconds and milliseconds. When + /// set to false seconds and milliseconds are discarded. When set to true the DateTime set to appointment + /// StartTime and EndTime is used as is including seconds and milliseconds. Default value is false. + /// + public static bool PreciseDateTimeValues + { + get + { + return _PreciseDateTimeValues; + } + set + { + _PreciseDateTimeValues = value; + } + } + + public static DateTime CurrentDateTime + { + get + { + DateTime dt = DateTime.Now; + return dt; + } + } + + internal System.Globalization.Calendar GetCalendar() + { + return CultureInfo.CurrentCulture.Calendar; + } + + private Dictionary _Years = new Dictionary(); + + internal void InternalAppointmentRemoved(Appointment item, bool isClearing) + { + item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler; + if (!item.IsRecurringInstance && !isClearing) + InvalidateAppointmentCache(item); + if (!isClearing) + OnAppointmentRemoved(new AppointmentEventArgs(item)); + } + + internal void InternalAppointmentsCleared() + { + InvalidateAppointmentCache(); + OnAppointmentsCleared(EventArgs.Empty); + } + + protected virtual void OnAppointmentsCleared(EventArgs e) + { + EventHandler handler = AppointmentsCleared; + if (handler != null) handler(this, e); + } + + /// + /// Raises the AppointmentRemoved event. + /// + /// Event arguments + protected virtual void OnAppointmentRemoved(AppointmentEventArgs appointmentEventArgs) + { + AppointmentEventHandler handler = AppointmentRemoved; + if (handler != null) handler(this, appointmentEventArgs); + } + + internal void InternalAppointmentAdded(Appointment item) + { + item.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + if (!item.IsRecurringInstance) + InvalidateAppointmentCache(item); + OnAppointmentAdded(new AppointmentEventArgs(item)); + } + + /// + /// Raises the AppointmentAdded event. + /// + /// Event arguments + protected virtual void OnAppointmentAdded(AppointmentEventArgs appointmentEventArgs) + { + AppointmentEventHandler handler = AppointmentAdded; + if (handler != null) handler(this, appointmentEventArgs); + } + + internal void OwnerRemoved(Owner item) + { + item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler; + OnPropertyChanged(new PropertyChangedEventArgs("Owners")); + } + + internal void OwnerAdded(Owner item) + { + item.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + OnPropertyChanged(new PropertyChangedEventArgs("Owners")); + } + + internal void WorkDayRemoved(WorkDay item) + { + item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler; + OnPropertyChanged(new PropertyChangedEventArgs("WorkDays")); + } + + internal void WorkDayAdded(WorkDay item) + { + item.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + OnPropertyChanged(new PropertyChangedEventArgs("WorkDays")); + } + + internal void CalendarWorkDateRemoved(CalendarWorkDay item) + { + item.SubPropertyChanged -= this.ChildPropertyChangedEventHandler; + OnPropertyChanged(new PropertyChangedEventArgs("CalendarWorkDays")); + } + + internal void CalendarWorkDateAdded(CalendarWorkDay item) + { + item.SubPropertyChanged += this.ChildPropertyChangedEventHandler; + OnPropertyChanged(new PropertyChangedEventArgs("CalendarWorkDays")); + } + + private SubPropertyChangedEventHandler _ChildPropertyChangedEventHandler = null; + private SubPropertyChangedEventHandler ChildPropertyChangedEventHandler + { + get + { + if (_ChildPropertyChangedEventHandler == null) _ChildPropertyChangedEventHandler = new SubPropertyChangedEventHandler(ChildPropertyChanged); + return _ChildPropertyChangedEventHandler; + } + } + + private void ChildPropertyChanged(object sender, SubPropertyChangedEventArgs e) + { + Appointment app = sender as Appointment; + OnSubPropertyChanged(e); + + if (app != null) + { + if (IsNonTimeProperty(e.PropertyChangedArgs.PropertyName)) return; + if (app.InMoveTo && e.PropertyChangedArgs.PropertyName != "EndTime") return; + if (IsRecurranceProperty(e.PropertyChangedArgs.PropertyName) || + e.Source is DailyRecurrenceSettings || + e.Source is WeeklyRecurrenceSettings || + e.Source is YearlyRecurrenceSettings || + e.Source is MonthlyRecurrenceSettings) + InvalidateAppointmentCache(); + else + InvalidateAppointmentCache(app); + } + } + + private bool IsRecurranceProperty(string propertyName) + { + return propertyName == Appointment.RecurrencePropertyName; + } + + private void InvalidateAppointmentCache(Appointment app) + { + if (IsUpdateSuspended) return; + if (app.Recurrence != null) + { + // Invalidate all + InvalidateAppointmentCache(); + } + else if (_Years.ContainsKey(app.LocalStartTime.Year)) + { + DateTime d = DateTimeHelper.BeginningOfDay(app.LocalStartTime); + DateTime end = app.LocalEndTime; + int year = d.Year; + while (d < end) + { + _Years[d.Year].InvalidateAppointments(d.Month, d.Day); + d = d.AddDays(1); + if (d.Year != year && !_Years.ContainsKey(d.Year)) + break; + } + } + AccessToday(); + OnPropertyChanged(new PropertyChangedEventArgs(AppointmentsPropertyName)); + } + + /// + /// Invalidates appointments cache store and causes recurrences to be regenerated when requested. + /// + public void InvalidateAppointmentCache() + { + if (IsUpdateSuspended) return; + + // Invalidate all + foreach (Year year in _Years.Values) + { + year.InvalidateAppointments(); + } + AccessToday(); + OnPropertyChanged(new PropertyChangedEventArgs(AppointmentsPropertyName)); + } + + private void AccessToday() + { + DateTime today = DateTime.Today; + Day day = this.GetDay(today); + int appCount = day.Appointments.Count; + } + private bool IsNonTimeProperty(string propertyName) + { + if (propertyName == "Description" || propertyName == "IsRecurringInstance" || propertyName == "Tag" + || propertyName == "OwnerKey" || propertyName == "IsSelected" || propertyName == "Locked" || propertyName=="LocalStartTime" || propertyName=="LocalEndTime") + return true; + return false; + } + + private int _UpdatesCount = 0; + /// + /// Suspends internal control updates to the cache structures etc. When making changes on multiple appointments + /// time related properties or when adding multiple appointments before doing so call BeginUpdate and after + /// updates are done call EndUpdate method to optimize performance. + /// Calls to BeginUpdate method can be nested and only last outer most EndUpdate call will resume internal control updates. + /// + public void BeginUpdate() + { + _UpdatesCount++; + } + /// + /// Resumes internal control updates that were suspended using BeginUpdate call and invalidates internal cache. + /// + public void EndUpdate() + { + if (_UpdatesCount == 0) + throw new InvalidOperationException("EndUpdate must be called AFTER BeginUpdate"); + _UpdatesCount--; + if (_UpdatesCount == 0) + InvalidateAppointmentCache(); + } + + /// + /// Gets whether internal control update is suspended due to the call to BeginUpdate method. + /// + [Browsable(false)] + public bool IsUpdateSuspended + { + get + { + return _UpdatesCount > 0; + } + } + + internal static string AppointmentsPropertyName + { + get { return "Appointments"; } + } + internal static string WorkDaysPropertyName + { + get { return "WorkDays"; } + } + internal static string CalendarWorkDaysPropertyName + { + get { return "CalendarWorkDays"; } + } + + private TimeZoneInfo _DisplayTimeZone = null; + /// + /// Gets or sets the default display time zone used for the appointments. Default value is null which indicates that system time-zone is used. + /// Display Time zone can also be set for each Owner on Owner object. Value set here is used if specific display time-zone is not set on user. + /// + [DefaultValue(null)] + public TimeZoneInfo DisplayTimeZone + { + get { return _DisplayTimeZone; } + set + { + if (value != _DisplayTimeZone) + { + TimeZoneInfo oldValue = _DisplayTimeZone; + _DisplayTimeZone = value; + InvalidateAppointmentTimes(); + InvalidateAppointmentCache(); + OnDisplayTimeZoneChanged(oldValue, value); + } + } + } + + private void InvalidateAppointmentTimes() + { + foreach (Appointment item in _Appointments) + { + item.InvokeLocalTimePropertyChange(); + } + } + + private void OnDisplayTimeZoneChanged(TimeZoneInfo oldValue, TimeZoneInfo newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("DisplayTimeZone")); + + } + + + internal void InvokeAppointmentStartTimeReached(Appointment appointment) + { + OnAppointmentStartTimeReached(new AppointmentEventArgs(appointment)); + } + + /// + /// Raises AppointmentStartTimeReached event. + /// + /// Event arguments + protected virtual void OnAppointmentStartTimeReached(AppointmentEventArgs appointmentEventArgs) + { + AppointmentEventHandler handler = AppointmentStartTimeReached; + if (handler != null) + handler(this, appointmentEventArgs); + } + + internal void InvokeReminderNotification(Reminder reminder) + { + OnReminderNotification(new ReminderEventArgs(reminder)); + } + /// + /// Raises ReminderNotification event. + /// + /// Event arguments + protected virtual void OnReminderNotification(ReminderEventArgs e) + { + ReminderEventHandler h = ReminderNotification; + if (h != null) + h(this, e); + } + #endregion + + #region INotifyPropertyChanged Members + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + + OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e)); + } + + #endregion + + #region INotifySubPropertyChanged Members + + /// + /// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key + /// difference that it occurs for the property changed of child objects as well. + /// + public event SubPropertyChangedEventHandler SubPropertyChanged; + /// + /// Raises the SubPropertyChanged event. + /// + /// Event arguments + protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e) + { + SubPropertyChangedEventHandler eh = SubPropertyChanged; + if (eh != null) eh(this, e); + } + #endregion + + #region CustomReminders + private ReminderCollection _CustomReminders = null; + /// + /// Gets the collection of custom reminders that are not associated with appointments. + /// + public ReminderCollection CustomReminders + { + get + { + if (_CustomReminders == null) _CustomReminders = new ReminderCollection(this); + return _CustomReminders; + } + } + #endregion + } + + #region Events Support + public delegate void AppointmentEventHandler(object sender, AppointmentEventArgs e); + /// + /// Defines arguments for appointment related events. + /// + public class AppointmentEventArgs : EventArgs + { + /// + /// Gets the appointment referenced by this event. + /// + public Appointment Appointment; + + /// + /// Initializes a new instance of the AppointmentEventArgs class. + /// + /// + public AppointmentEventArgs(Appointment appointment) + { + Appointment = appointment; + } + } + #endregion + +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/CalendarWorkDay.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/CalendarWorkDay.cs new file mode 100644 index 00000000..3fc6c4f2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/CalendarWorkDay.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents specific date based work day. + /// + public class CalendarWorkDay : BaseWorkDay + { + #region Internal Implementation + /// + /// Initializes a new instance of the WorkDay class. + /// + public CalendarWorkDay() + { + } + + /// + /// Initializes a new instance of the WorkDay class. + /// + /// Date this work-day represents + public CalendarWorkDay(DateTime date) + { + _Date = date; + } + + private DateTime _Date = DateTime.MinValue; + /// + /// Gets or sets the date this day represents. + /// + public DateTime Date + { + get { return _Date; } + set + { + value = value.Date; + if (value != _Date) + { + DateTime oldValue = _Date; + _Date = value; + OnDateChanged(oldValue, value); + } + } + } + /// + /// Called when Date property has changed. + /// + /// Old property value. + /// New property value. + protected virtual void OnDateChanged(DateTime oldValue, DateTime newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Date")); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/CalendarWorkDayCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/CalendarWorkDayCollection.cs new file mode 100644 index 00000000..7ce1f987 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/CalendarWorkDayCollection.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents collection of calendar work days. + /// + public class CalendarWorkDayCollection : Collection + { + #region Constructor + /// + /// Initializes a new instance of the AppointmentCollection class. + /// + /// + public CalendarWorkDayCollection(CalendarModel calendar) + { + _Calendar = calendar; + } + + /// + /// Initializes a new instance of the CalendarWorkDayCollection class. + /// + /// + public CalendarWorkDayCollection(Owner owner) + { + _Owner = owner; + } + #endregion + + #region Internal Implementation + private Dictionary _ItemsDictionary = new Dictionary(); + + private Owner _Owner = null; + /// + /// Gets the Owner of work-day collection. + /// + public Owner Owner + { + get { return _Owner; } + internal set { _Owner = value; } + } + + private CalendarModel _Calendar = null; + /// + /// Gets the calendar collection is associated with. + /// + public CalendarModel Calendar + { + get { return _Calendar; } + internal set + { + _Calendar = value; + UpdateItemsCalendarModel(); + } + } + + internal void UpdateItemsCalendarModel() + { + CalendarModel model = GetCalendarModel(); + foreach (CalendarWorkDay item in this.Items) + { + item.Calendar = model; + } + } + + protected override void RemoveItem(int index) + { + CalendarWorkDay day = this[index]; + OnBeforeRemove(index, day); + base.RemoveItem(index); + OnAfterRemove(index, day); + } + + private void OnAfterRemove(int index, CalendarWorkDay day) + { + _ItemsDictionary.Remove(day.Date); + + CalendarModel model = GetCalendarModel(); + if (model != null) + model.CalendarWorkDateRemoved(day); + } + + private void OnBeforeRemove(int index, CalendarWorkDay day) + { + day.Calendar = null; + } + + protected override void InsertItem(int index, CalendarWorkDay item) + { + OnBeforeInsert(index, item); + base.InsertItem(index, item); + OnAfterInsert(index, item); + } + + private void OnAfterInsert(int index, CalendarWorkDay item) + { + CalendarModel model = GetCalendarModel(); + if (model != null) + model.CalendarWorkDateAdded(item); + _ItemsDictionary.Add(item.Date, item); + } + + private void OnBeforeInsert(int index, CalendarWorkDay item) + { + if (this[item.Date] != null) + throw new InvalidOperationException("Date '" + item.Date.ToString() + "' already in collection."); + item.Calendar = GetCalendarModel(); + } + + private CalendarModel GetCalendarModel() + { + if (_Calendar != null) return _Calendar; + if (_Owner != null) return _Owner.Calendar; + return null; + } + + protected override void SetItem(int index, CalendarWorkDay newItem) + { + CalendarWorkDay oldItem = this[index]; + OnBeforeSetItem(index, oldItem, newItem); + base.SetItem(index, newItem); + OnAfterSetItem(index, oldItem, newItem); + } + + private void OnAfterSetItem(int index, CalendarWorkDay oldItem, CalendarWorkDay newItem) + { + CalendarModel model = GetCalendarModel(); + if (model != null) + { + model.CalendarWorkDateRemoved(oldItem); + model.CalendarWorkDateAdded(newItem); + } + } + + private void OnBeforeSetItem(int index, CalendarWorkDay oldItem, CalendarWorkDay newItem) + { + if (this[newItem.Date] != null) + throw new InvalidOperationException("Date '" + newItem.Date.ToString() + "' already in collection."); + + oldItem.Calendar = null; + newItem.Calendar = GetCalendarModel(); + } + + protected override void ClearItems() + { + CalendarModel model = GetCalendarModel(); + foreach (CalendarWorkDay item in this) + { + item.Calendar = null; + if (model != null) + model.CalendarWorkDateRemoved(item); + } + base.ClearItems(); + } + + /// + /// Gets the item based on the Key assigned to the item + /// + /// Date to retrieve data for. + /// Reference to CalendarWorkDay or null if no day in collection. + public CalendarWorkDay this[DateTime date] + { + get + { + CalendarWorkDay item = null; + if (_ItemsDictionary.TryGetValue(date.Date, out item)) + return item; + + return null; + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/DailyRecurrenceSettings.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/DailyRecurrenceSettings.cs new file mode 100644 index 00000000..32f1b883 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/DailyRecurrenceSettings.cs @@ -0,0 +1,142 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Defines the daily recurrence settings. + /// + public class DailyRecurrenceSettings : INotifyPropertyChanged, INotifySubPropertyChanged + { + #region Internal Implementation + private AppointmentRecurrence _Recurrence = null; + + /// + /// Initializes a new instance of the DailyRecurrenceSettings class. + /// + /// + public DailyRecurrenceSettings(AppointmentRecurrence recurrence) + { + _Recurrence = recurrence; + } + + private eDailyRecurrenceRepeat _RepeatOnDaysOfWeek = eDailyRecurrenceRepeat.All; + /// + /// Gets or sets the days of week on which appointment is repeated. + /// + [DefaultValue(eDailyRecurrenceRepeat.All)] + public eDailyRecurrenceRepeat RepeatOnDaysOfWeek + { + get { return _RepeatOnDaysOfWeek; } + set + { + if (value != _RepeatOnDaysOfWeek) + { + eDailyRecurrenceRepeat oldValue = _RepeatOnDaysOfWeek; + _RepeatOnDaysOfWeek = value; + OnRepeatOnDaysOfWeekChanged(oldValue, value); + } + } + } + + private void OnRepeatOnDaysOfWeekChanged(eDailyRecurrenceRepeat oldValue, eDailyRecurrenceRepeat newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnDaysOfWeek")); + } + + private int _RepeatInterval = 1; + /// + /// Gets or sets the interval between recurring appointments. Default value is 1. Setting this value to for example 3 means that + /// recurrence is repeated every 3 days. + /// + [DefaultValue(1)] + public int RepeatInterval + { + get { return _RepeatInterval; } + set + { + if (value != _RepeatInterval) + { + int oldValue = _RepeatInterval; + _RepeatInterval = value; + OnRepeatIntervalChanged(oldValue, value); + } + } + } + + private void OnRepeatIntervalChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatInterval")); + } + + private bool _ExplicitDailyRecurrence = false; + /// + /// Indicates whether appointment is explicitly repeated every day regardless of its end time. By default end time of appointment + 1 day is considered as next + /// starting point for appointment. When this property is set to true appointment start time + 1 day is used as next starting point of recurrence. + /// + [DefaultValue(false), Description("Indicates whether appointment is explicitly repeated every day regardless of its end time. By default end time of appointment + 1 day is considered as next starting point for appointment. When this property is set to true appointment start time + 1 day is used as next starting point of recurrence.")] + public bool ExplicitDailyRecurrence + { + get { return _ExplicitDailyRecurrence; } + set + { + if (value != _ExplicitDailyRecurrence) + { + bool oldValue = _ExplicitDailyRecurrence; + _ExplicitDailyRecurrence = value; + OnExplicitDailyRecurrenceChanged(oldValue, value); + } + } + } + /// + /// Called when ExplicitDailyRecurrence property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnExplicitDailyRecurrenceChanged(bool oldValue, bool newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ExplicitDailyRecurrence")); + + } + #endregion + + #region INotifyPropertyChanged Members + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + if (eh != null) eh(this, e); + OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e)); + } + #endregion + + #region INotifySubPropertyChanged Members + /// + /// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key + /// difference that it occurs for the property changed of child objects as well. + /// + public event SubPropertyChangedEventHandler SubPropertyChanged; + /// + /// Raises the SubPropertyChanged event. + /// + /// Event arguments + protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e) + { + SubPropertyChangedEventHandler eh = SubPropertyChanged; + if (eh != null) eh(this, e); + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/DateTimeHelper.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/DateTimeHelper.cs new file mode 100644 index 00000000..6a106360 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/DateTimeHelper.cs @@ -0,0 +1,206 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.Schedule.Model +{ + public static class DateTimeHelper + { + /// + /// Returns number of weekdays (Monday-Friday) between two dates. + /// + /// Start date + /// End date + /// Total number of weekdays between two dates + public static int TotalWeekDays(DateTime startDateTime, DateTime endDateTime) + { + int totalDays = 0; + startDateTime = new DateTime(startDateTime.Year, startDateTime.Month, startDateTime.Day); + endDateTime = new DateTime(endDateTime.Year, endDateTime.Month, endDateTime.Day, 23, 59, 0); + + // Start date to monday + if (startDateTime.DayOfWeek == DayOfWeek.Saturday) + startDateTime = startDateTime.AddDays(2); + else if (startDateTime.DayOfWeek == DayOfWeek.Sunday) + startDateTime = startDateTime.AddDays(1); + else + { + DateTime newStartDateTime = startDateTime.AddDays(8 - (int)startDateTime.DayOfWeek); + if (newStartDateTime > endDateTime) + { + if (endDateTime.DayOfWeek == DayOfWeek.Saturday) + endDateTime = endDateTime.AddDays(-1); + else if (endDateTime.DayOfWeek == DayOfWeek.Sunday) + endDateTime = endDateTime.AddDays(-2); + return (int)Math.Ceiling(Math.Max(0, endDateTime.Subtract(startDateTime).TotalDays)); + } + totalDays = 6 - (int)startDateTime.DayOfWeek; + startDateTime = newStartDateTime; + } + + // End date to Sunday + if (endDateTime.DayOfWeek == DayOfWeek.Saturday) + endDateTime = endDateTime.AddDays(1); + else if (endDateTime.DayOfWeek != DayOfWeek.Sunday) + { + int d = (int)endDateTime.DayOfWeek; + DateTime newEndDateTime = endDateTime.AddDays(-(int)endDateTime.DayOfWeek); + totalDays += d; + endDateTime=newEndDateTime; + } + + int t = (int)Math.Max(0, Math.Ceiling(endDateTime.Subtract(startDateTime).TotalDays)); + if (t > 0) + totalDays += (t / 7) * 5; + + return totalDays; + + } + + /// + /// Return total number of days specified by day parameter between two dates. + /// + /// Start date. + /// End date. + /// Day of week + /// Number of days between two dates + public static int TotalDays(DateTime startDate, DateTime endDate, DayOfWeek day) + { + if (endDate < startDate) return 0; + + + if (startDate.DayOfWeek > day) + startDate = startDate.AddDays(7 - ((int)startDate.DayOfWeek - (int)day)); + else + startDate = startDate.AddDays(day - startDate.DayOfWeek); + if (endDate < startDate) return 0; + + if (endDate.DayOfWeek < day) + endDate = endDate.AddDays(-(7 - ((int)day - (int)endDate.DayOfWeek))); + else + endDate = endDate.AddDays(day - endDate.DayOfWeek); + + if (endDate.Subtract(startDate).TotalDays <= 1) return 1; + + int t = (int)Math.Ceiling(endDate.Subtract(startDate).TotalDays); + int totalDays = (int)Math.Floor(Math.Max(1, (double)t / 7)) + 1; // +1 since endDate is always on the day + //if (endDate.RelativeDayOfWeek == day) totalDays++; + return totalDays; + } + + public static int TotalNumberOfDays(DateTime startDate, DateTime endDate, eDayOfWeekRecurrence daysOfWeek) + { + int totalDays=0; + if (daysOfWeek == eDayOfWeekRecurrence.All) + return (int)Math.Ceiling(endDate.Subtract(startDate).TotalDays); + + if ((daysOfWeek & eDayOfWeekRecurrence.Friday) != 0) + totalDays += TotalDays(startDate, endDate, DayOfWeek.Friday); + if ((daysOfWeek & eDayOfWeekRecurrence.Monday) != 0) + totalDays += TotalDays(startDate, endDate, DayOfWeek.Monday); + if ((daysOfWeek & eDayOfWeekRecurrence.Saturday) != 0) + totalDays += TotalDays(startDate, endDate, DayOfWeek.Saturday); + if ((daysOfWeek & eDayOfWeekRecurrence.Sunday) != 0) + totalDays += TotalDays(startDate, endDate, DayOfWeek.Sunday); + if ((daysOfWeek & eDayOfWeekRecurrence.Thursday) != 0) + totalDays += TotalDays(startDate, endDate, DayOfWeek.Thursday); + if ((daysOfWeek & eDayOfWeekRecurrence.Tuesday) != 0) + totalDays += TotalDays(startDate, endDate, DayOfWeek.Tuesday); + if ((daysOfWeek & eDayOfWeekRecurrence.Wednesday) != 0) + totalDays += TotalDays(startDate, endDate, DayOfWeek.Wednesday); + + return totalDays; + } + + /// + /// Returns the date/time that represents end of the day value. + /// + /// + /// + public static DateTime EndOfDay(DateTime day) + { + return new DateTime(day.Year, day.Month, day.Day, 23, 59, 59); + } + + /// + /// Returns the date/time that represents beginning of the day value. + /// + /// + /// + public static DateTime BeginningOfDay(DateTime day) + { + return new DateTime(day.Year, day.Month, day.Day, 0, 0, 0); + } + + /// + /// Returns true if date falls at begging of the day 12:00 AM + /// + /// + /// + public static bool IsBeginningOfDay(DateTime day) + { + return day.Equals(BeginningOfDay(day)); + } + + internal static bool HasDay(DayOfWeek dayOfWeek, eDayOfWeekRecurrence days) + { + if (dayOfWeek == DayOfWeek.Monday && (days & eDayOfWeekRecurrence.Monday) != 0) return true; + if (dayOfWeek == DayOfWeek.Tuesday && (days & eDayOfWeekRecurrence.Tuesday) != 0) return true; + if (dayOfWeek == DayOfWeek.Wednesday && (days & eDayOfWeekRecurrence.Wednesday) != 0) return true; + if (dayOfWeek == DayOfWeek.Thursday && (days & eDayOfWeekRecurrence.Thursday) != 0) return true; + if (dayOfWeek == DayOfWeek.Friday && (days & eDayOfWeekRecurrence.Friday) != 0) return true; + if (dayOfWeek == DayOfWeek.Saturday && (days & eDayOfWeekRecurrence.Saturday) != 0) return true; + if (dayOfWeek == DayOfWeek.Sunday && (days & eDayOfWeekRecurrence.Sunday) != 0) return true; + + return false; + } + + public static bool IsWeekendDay(DateTime currentDay) + { + return currentDay.DayOfWeek == DayOfWeek.Sunday || currentDay.DayOfWeek == DayOfWeek.Saturday; + } + + /// + /// Gets greater date between two dates. + /// + /// Date 1 + /// Date 2 + /// Greater date. + public static DateTime MaxDate(DateTime date1, DateTime date2) + { + return date1 > date2 ? date1 : date2; + } + + /// + /// Returns true if both dates are on same day and year. + /// + /// First date + /// Second date + /// true if dates are on same day and year + public static bool IsSameDay(DateTime date1, DateTime date2) + { + return (date1.Year == date2.Year && date1.Month == date2.Month && + date1.Day == date2.Day) || date1.Date.AddDays(1) == date2; + + //return date1.Year == date2.Year && date1.Month == date2.Month && date1.Day == date2.Day; + } + + /// + /// Returns true if time periods overlap. + /// + /// Start of first period. + /// End of first period. + /// Start of second period. + /// End of second period. + /// true if periods overlap + public static bool TimePeriodsOverlap(DateTime startTime1, DateTime endTime1, DateTime startTime2, DateTime endTime2) + { + if (startTime1 <= startTime2 && endTime1 > startTime2 || startTime1 >= startTime2 && startTime1 < endTime2) + return true; + return false; + } + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Day.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Day.cs new file mode 100644 index 00000000..f9888b87 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Day.cs @@ -0,0 +1,77 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents the calendar day. + /// + public class Day + { + #region Constructor + /// + /// Initializes a new instance of the Day class. + /// + /// + /// + public Day(DateTime dayDate, CalendarModel calendar) + { + _DayDate = dayDate; + _Calendar = calendar; + } + + #endregion + + #region Internal Implementation + private AppointmentSubsetCollection _Appointments; + /// + /// Gets appointments that start on this day. + /// + public AppointmentSubsetCollection Appointments + { + get + { + if (_Appointments == null) + _Appointments = new AppointmentSubsetCollection(_Calendar, _DayDate, DateTimeHelper.EndOfDay(_DayDate)); + return _Appointments; + } + } + + /// + /// Invalidate the day appointments + /// + internal void InvalidateAppointments() + { + if (_Appointments != null) + _Appointments.InvalidateCollection(); + } + + private DateTime _DayDate = DateTime.MinValue; + /// + /// Gets the date this day represents. + /// + [Browsable(false)] + public DateTime DayDate + { + get { return _DayDate; } + internal set { _DayDate = value; } + } + + private CalendarModel _Calendar; + /// + /// Gets the Calendar this day is part of. + /// + [Browsable(false)] + public CalendarModel Calendar + { + get { return _Calendar; } + internal set { _Calendar = value; } + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Enums.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Enums.cs new file mode 100644 index 00000000..3eec83f0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Enums.cs @@ -0,0 +1,191 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.Schedule.Model +{ + /// + /// Specifies notification type when appointment start time has been reached. + /// + [Flags()] + public enum eStartTimeAction + { + /// + /// No action is taken. + /// + None = 0, + /// + /// StartTimeReached event is fired. + /// + StartTimeReachedEvent = 1, + /// + /// StartTimeCommand is executed. + /// + Command = 2, + /// + /// Both event and command are performed. + /// + StartTimeReachedEventAndCommand = StartTimeReachedEvent | Command + } + + /// + /// Specifies notification type when reminder time has been reached. + /// + [Flags()] + public enum eReminderAction + { + /// + /// No action is taken. + /// + None = 0, + /// + /// Reminder event is fired. + /// + Event = 1, + /// + /// Reminder Command is executed. + /// + Command = 2, + /// + /// Both event and command are performed. + /// + EventAndCommand = Event | Command + } + + /// + /// Specifies the recurrence range type. + /// + public enum eRecurrenceRangeLimitType + { + /// + /// Recurrence range has no end date specified. + /// + NoEndDate, + /// + /// Recurrence ends on date specified by RangeEndDate property. + /// + RangeEndDate, + /// + /// Recurrence ends after specified number of repeats by RangeNumberOfOccurrences property. + /// + RangeNumberOfOccurrences + } + + /// + /// Specifies the pattern type for appointment recurrence. + /// + public enum eRecurrencePatternType + { + /// + /// Appointment recurs daily. + /// + Daily, + /// + /// Appointment recurs weekly. + /// + Weekly, + /// + /// Appointment recurs monthly. + /// + Monthly, + /// + /// Appointment recurs yearly. + /// + Yearly + } + + /// + /// Specifies the relative day in month for recurrence. + /// + public enum eRelativeDayInMonth + { + /// + /// No value specified. + /// + None, + /// + /// The first occurrence of the specified day in its month. + /// + First, + /// + /// The second occurrence of the specified day in its month. + /// + Second, + /// + /// The third occurrence of the specified day in its month. + /// + Third, + /// + /// The fourth occurrence of the specified day in its month. + /// + Fourth, + /// + /// The last occurrence of the specified day in its month. + /// + Last + } + + /// + /// Specifies on which day the appointment is repeated. + /// + [Flags()] + public enum eDayOfWeekRecurrence + { + None = 0, + Monday = 1, + Tuesday = 2, + Wednesday = 4, + Thursday = 8, + Friday = 16, + Saturday = 32, + Sunday = 64, + WeekendDays = Saturday | Sunday, + WeekDays = Monday | Tuesday | Wednesday | Thursday | Friday, + All = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday + } + + /// + /// Specifies on which days daily recurrence is repeated. + /// + public enum eDailyRecurrenceRepeat + { + /// + /// Appointment is repeated on all days. + /// + All = eDayOfWeekRecurrence.Monday | eDayOfWeekRecurrence.Tuesday | eDayOfWeekRecurrence.Wednesday | eDayOfWeekRecurrence.Thursday | eDayOfWeekRecurrence.Friday | eDayOfWeekRecurrence.Saturday | eDayOfWeekRecurrence.Sunday, + + /// + /// Appointment is repeated on week-days only, Monday-Friday. + /// + WeekDays = eDayOfWeekRecurrence.Monday | eDayOfWeekRecurrence.Tuesday | eDayOfWeekRecurrence.Wednesday | eDayOfWeekRecurrence.Thursday | eDayOfWeekRecurrence.Friday, + + /// + /// Appointment is repeated on weekend-days only, Saturday-Sunday. + /// + WeekendDays = eDayOfWeekRecurrence.WeekendDays + } + + /// + /// Specifies on which month monthly appointment recurrence is repeated. + /// + [Flags()] + public enum eMonthRecurrence + { + January = 1, + February = 2, + March = 4, + April = 8, + May = 16, + June = 32, + July = 64, + August = 128, + September = 256, + October = 512, + November = 1024, + December = 2048, + All = January | February | March | April | May | June | July | August | September | October | November | December + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/HolidaysCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/HolidaysCollection.cs new file mode 100644 index 00000000..dcd1b0bf --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/HolidaysCollection.cs @@ -0,0 +1,16 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents collection of holidays. + /// + public class HolidaysCollection + { + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/INotifySubPropertyChanged.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/INotifySubPropertyChanged.cs new file mode 100644 index 00000000..0dfa7393 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/INotifySubPropertyChanged.cs @@ -0,0 +1,48 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Defines an interface for property notification change. + /// + public interface INotifySubPropertyChanged + { + /// + /// Occurs when property on object or its sub-objects has changed. + /// + event SubPropertyChangedEventHandler SubPropertyChanged; + } + + public delegate void SubPropertyChangedEventHandler(object sender, SubPropertyChangedEventArgs e); + /// + /// Defines event arguments for SubPropertyChanged event. + /// + public class SubPropertyChangedEventArgs : EventArgs + { + /// + /// Reference to PropertyChangedArgs of changed property. + /// + public PropertyChangedEventArgs PropertyChangedArgs = null; + /// + /// Reference to the source object of the event. + /// + public object Source = null; + + /// + /// Initializes a new instance of the SubPropertyChangedEventArgs class. + /// + /// + /// + public SubPropertyChangedEventArgs(object source, PropertyChangedEventArgs propertyChangedArgs) + { + PropertyChangedArgs = propertyChangedArgs; + Source = source; + } + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ImportExport/CalendarEntry.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ImportExport/CalendarEntry.cs new file mode 100644 index 00000000..89ca21d4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ImportExport/CalendarEntry.cs @@ -0,0 +1,156 @@ +using System.Collections.Generic; + +namespace DevComponents.Schedule.Model.Serialization +{ + public class CalendarEntry + { + #region Private variables + + private string _Id = ""; + private string _Value = ""; + + private List _Attributes; + + private int _LineStart; + private int _LineEnd; + + #endregion + + /// + /// Constructor + /// + /// Text line start + /// Text line end + public CalendarEntry(int lineStart, int lineEnd) + { + _LineStart = lineStart; + _LineEnd = lineEnd; + + _Attributes = new List(); + } + + #region Public properties + + #region Attributes + + /// + /// Attributes + /// + public List Attributes + { + get { return (_Attributes); } + set { _Attributes = value; } + } + + #endregion + + #region Id + + /// + /// Id + /// + public string Id + { + get { return (_Id); } + set { _Id = value; } + } + + #endregion + + #region LineEnd + + /// + /// LineEnd + /// + public int LineEnd + { + get { return (_LineEnd); } + set { _LineEnd = value; } + } + + #endregion + + #region LineStart + + /// + /// LineStart + /// + public int LineStart + { + get { return (_LineStart); } + set { _LineStart = value; } + } + + #endregion + + #region Value + + /// + /// Value + /// + public string Value + { + get { return (_Value); } + set { _Value = value; } + } + + #endregion + + #endregion + } + + #region AttributeData + + public class AttributeData + { + #region Private variables + + private string _Id; + private string _Value; + + #endregion + + /// + /// Constructor + /// + /// Id + /// Value + public AttributeData(string id, string value) + { + _Id = id; + _Value = value; + } + + #region Public properties + + #region Id + + /// + /// Gets or sets the attribute Id + /// + public string Id + { + get { return (_Id); } + set { _Id = value; } + } + + #endregion + + #region Value + + /// + /// Gets or sets the attribute value + /// + public string Value + { + get { return (_Value); } + set { _Value = value; } + } + + #endregion + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ImportExport/ICS/IcsExporter.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ImportExport/ICS/IcsExporter.cs new file mode 100644 index 00000000..b50c2319 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ImportExport/ICS/IcsExporter.cs @@ -0,0 +1,989 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +namespace DevComponents.Schedule.Model.Serialization +{ + /// + /// Export DNB internal Model/Appointment data layout into + /// ICS (Internet Calendaring and Scheduling - RFC5545) format file. + /// + public class IcsExporter + { + #region Private constants + + private const int FoldCount = 74; + + #endregion + + #region Private variables + + private DateTime _DtStamp = DateTime.Now; + + private string _ProdId = "PRODID:-//DotNetBar\\, Inc//iCal 1.0//EN"; + + private CalendarModel _Model; + + private string[] _CalNames; + private string[] _OwnerKeys; + + private string _ExportFile; + private StreamWriter _StreamWriter; + + #endregion + + #region Constructors + + /// + /// IcsExporter + /// + public IcsExporter() + { + } + + /// + /// IcsExporter + /// + /// + public IcsExporter(CalendarModel model) + { + Model = model; + } + + #endregion + + #region Public properties + + #region ProdId + + /// + /// Gets or sets the Calendar Product Id. + /// + public string ProdId + { + get { return (_ProdId); } + set { _ProdId = value; } + } + + #endregion + + #region Model + + /// + /// CalendarModel + /// + public CalendarModel Model + { + get { return (_Model); } + set { _Model = value; } + } + + #endregion + + #endregion + + #region Export + + /// + /// Exports Appointment data in the iCalendar format + /// + /// Array of OwnerKeys + /// Array of CalendarNames + /// Export StreamWriter + public void Export(string[] ownerKeys, string[] calNames, StreamWriter streamWriter) + { + if (_Model == null) + throw new Exception("Model can not be null."); + + _CalNames = calNames; + _OwnerKeys = ownerKeys; + + if (streamWriter == null) + throw new Exception("Invalid StreamWriter."); + + _StreamWriter = streamWriter; + + if (String.IsNullOrEmpty(_ExportFile) == true) + _ExportFile = streamWriter.BaseStream.ToString(); + + ExportOwnerData(); + + streamWriter.Flush(); + } + + #region Export variations + + /// + /// Exports all appointments to the given export file. + /// + /// Output file path + public void Export(string exportFile) + { + Export((string[])null, null, exportFile); + } + + /// + /// Exports all appointments to the given export stream. + /// + /// Output StreamWriter + public void Export(StreamWriter streamWriter) + { + Export((string[])null, null, streamWriter); + } + + /// + /// Exports all appointments for the specified OwnerKey to + /// the given export file. + /// + /// Appointment OwnerKey + /// Output file path + public void Export(string ownerKey, string exportFile) + { + Export(ownerKey, ownerKey, exportFile); + } + + /// + /// Exports all appointments for the specified OwnerKey to + /// the given export stream. + /// + /// Appointment OwnerKey + /// Output StreamWriter + public void Export(string ownerKey, StreamWriter streamWriter) + { + Export(ownerKey, ownerKey, streamWriter); + } + + /// + /// Exports all appointments for the specified OwnerKey to + /// the given export file, using the specified calendar name. + /// + /// Appointment OwnerKey + /// Associated Calendar Name + /// Output file path + public void Export(string ownerKey, string calName, string exportFile) + { + string[] ownerKeys = new string[] { ownerKey }; + string[] calNames = new string[] { calName }; + + Export(ownerKeys, calNames, exportFile); + } + + /// + /// Exports all appointments for the specified OwnerKey to + /// the given export stream, using the specified calendar name. + /// + /// Appointment OwnerKey + /// Associated Calendar Name + /// Output StreamWriter + public void Export(string ownerKey, string calName, StreamWriter streamWriter) + { + string[] ownerKeys = new string[] { ownerKey }; + string[] calNames = new string[] { calName }; + + Export(ownerKeys, calNames, streamWriter); + } + + /// + /// Exports all appointments for the specified OwnerKey array to + /// the given export file, using the specified associated calendar name array. + /// + /// Array of OwnerKeys + /// Array of 1:1 associated Calendar Names + /// Output file path + public virtual void Export(string[] ownerKeys, string[] calNames, string exportFile) + { + using (StreamWriter streamWriter = new StreamWriter(exportFile)) + Export(ownerKeys, calNames, streamWriter); + } + + #endregion + + #endregion + + #region ExportOwnerData + + /// + /// Exports model data for each requested OwnerKey + /// + private void ExportOwnerData() + { + if (_OwnerKeys == null) + _OwnerKeys = GetDefaultOwnerKeys(); + + if (_CalNames == null) + _CalNames = _OwnerKeys; + + string lastCalName = null; + + for (int i = 0; i < _OwnerKeys.Length; i++) + { + string ownerKey = _OwnerKeys[i] ?? ""; + + string calName = ((i < _CalNames.Length) + ? _CalNames[i] + : _CalNames[_CalNames.Length - 1]) ?? ownerKey; + + if (calName.Equals(lastCalName) == false) + { + if (lastCalName != null) + ExportCalEnd(); + + ExportCalBegin(calName); + + lastCalName = calName; + } + + foreach (Appointment app in Model.Appointments) + { + if (IsAppointmentVisible(app, ownerKey) == true) + ExportVEvent(app); + } + } + + if (lastCalName != null) + ExportCalEnd(); + } + + #endregion + + #region ExportCalBegin + + /// + /// Exports the beginning calendar sequence + /// + /// + private void ExportCalBegin(string calName) + { + ExportLine("BEGIN:VCALENDAR"); + ExportLine("CALSCALE:GREGORIAN"); + + if (_ProdId != null) + ExportLine(_ProdId); + + ExportLine("X-WR-CALNAME;VALUE=TEXT:" + calName); + ExportLine("VERSION:2.0"); + } + + #endregion + + #region ExportCalEnd + + /// + /// Exports the ending calendar sequence + /// + private void ExportCalEnd() + { + ExportLine("END:VCALENDAR\n"); + } + + #endregion + + #region ExportVEvent + + #region ExportVEvent + + /// + /// Exports a calendar event (appointment) + /// + /// + private void ExportVEvent(Appointment app) + { + ExportLine("\nBEGIN:VEVENT"); + + if (String.IsNullOrEmpty(app.Subject) == false) + ExportLine("SUMMARY:" + AddMetaData(app.Subject)); + + if (String.IsNullOrEmpty(app.Description) == false) + ExportLine("DESCRIPTION:" + AddMetaData(app.Description)); + + ExportLine("UID:" + Guid.NewGuid().ToString()); + ExportLine("DTSTAMP:" + GetUniversalTime(_DtStamp)); + + if (String.IsNullOrEmpty(app.CategoryColor) == false) + ExportLine("X-DNB-CATEGORYCOLOR:" + app.CategoryColor); + + if (String.IsNullOrEmpty(app.DisplayTemplate) == false) + ExportLine("X-DNB-DISPLAYTEMPLATE:" + AddMetaData(app.DisplayTemplate)); + + if (app.ImageAlign != eImageContentAlignment.TopLeft) + ExportLine("X-DNB-IMAGEALIGN:" + Enum.GetName(typeof(eImageContentAlignment), app.ImageAlign)); + + if (String.IsNullOrEmpty(app.ImageKey) == false) + ExportLine("X-DNB-IMAGEKEY:" + app.ImageKey); + + if (app.Locked == true) + ExportLine("X-DNB-LOCKED:true"); + + if (app.StartTimeAction != eStartTimeAction.None) + ExportLine("X-DNB-STARTTIMEACTION:" + Enum.GetName(typeof(eStartTimeAction), app.StartTimeAction)); + + if (String.IsNullOrEmpty(app.TimeMarkedAs) == false) + ExportLine("X-DNB-TIMEMARKEDAS:" + app.TimeMarkedAs); + + if (String.IsNullOrEmpty(app.Tooltip) == false) + ExportLine("X-DNB-TOOLTIP:" + AddMetaData(app.Tooltip)); + + if ((app.StartTime.Hour == 0 && app.StartTime.Minute == 0) && + (app.EndTime.Hour == 0 && app.EndTime.Minute == 0)) + { + ExportLine("DTSTART;VALUE=DATE:" + app.StartTime.ToString("yyyyMMdd")); + + if ((app.EndTime - app.StartTime).TotalMinutes != 60 * 24) + ExportLine("DTEND;VALUE=DATE:" + app.EndTime.ToString("yyyyMMdd")); + } + else + { + ExportLine("DTSTART:" + GetUniversalTime(app.StartTime)); + ExportLine("DTEND:" + GetUniversalTime(app.EndTime)); + } + + if (app.Private == true) + ExportLine("CLASS:PRIVATE"); + + ExportRRule(app); + ExportAlarms(app); + + ExportLine("END:VEVENT"); + } + + #region ExportRRule + + #region ExportRRule + + /// + /// Exports the appointment Recurrence Rule + /// + /// + private void ExportRRule(Appointment app) + { + if (app.Recurrence != null) + { + switch (app.Recurrence.RecurrenceType) + { + case eRecurrencePatternType.Daily: + ExportDailyRRule(app.Recurrence); + break; + + case eRecurrencePatternType.Weekly: + ExportWeeklyRRule(app.Recurrence); + break; + + case eRecurrencePatternType.Monthly: + ExportMonthlyRRule(app.Recurrence); + break; + + default: + ExportYearlyRRule(app); + break; + } + + ExportExDate(app.Recurrence); + } + } + + #endregion + + #region ExportDailyRRule + + /// + /// ExportDailyRRule + /// + /// + private void ExportDailyRRule(AppointmentRecurrence recur) + { + StringBuilder sb = new StringBuilder(); + + sb.Append("RRULE:FREQ=DAILY"); + + AddRRuleInterval(sb, recur.Daily.RepeatInterval); + AddRRuleByDay(sb, recur); + + AddRRuleRangeInfo(sb, recur); + + ExportLine(sb.ToString()); + } + + #endregion + + #region ExportWeeklyRRule + + /// + /// ExportWeeklyRRule + /// + /// + private void ExportWeeklyRRule(AppointmentRecurrence recur) + { + StringBuilder sb = new StringBuilder(); + + sb.Append("RRULE:FREQ=WEEKLY"); + + AddRRuleInterval(sb, recur.Weekly.RepeatInterval); + + if (recur.Weekly.RepeatOnDaysOfWeek != eDayOfWeekRecurrence.None) + AddRRuleByDay(sb, recur.Weekly.RepeatOnDaysOfWeek); + + AddRRuleRangeInfo(sb, recur); + + ExportLine(sb.ToString()); + } + + #endregion + + #region ExportMonthlyRRule + + /// + /// ExportMonthlyRRule + /// + /// + private void ExportMonthlyRRule(AppointmentRecurrence recur) + { + StringBuilder sb = new StringBuilder(); + + sb.Append("RRULE:FREQ=MONTHLY"); + + AddRRuleInterval(sb, recur.Monthly.RepeatInterval); + + if (recur.Monthly.RepeatOnRelativeDayInMonth == eRelativeDayInMonth.None) + sb.AppendFormat("{0}{1:D}", ";BYMONTHDAY=", recur.Monthly.RepeatOnDayOfMonth); + else + AddRRuleByDay(sb, recur.Monthly.RepeatOnRelativeDayInMonth, recur.Monthly.RelativeDayOfWeek); + + AddRRuleRangeInfo(sb, recur); + + ExportLine(sb.ToString()); + } + + #endregion + + #region ExportYearlyRRule + + /// + /// ExportYearlyRRule + /// + /// + private void ExportYearlyRRule(Appointment app) + { + AppointmentRecurrence recur = app.Recurrence; + + StringBuilder sb = new StringBuilder(); + + sb.Append("RRULE:FREQ=YEARLY"); + sb.AppendFormat("{0}{1:D}", ";BYMONTH=", recur.Yearly.RepeatOnMonth); + + if (recur.Yearly.RepeatOnRelativeDayInMonth == eRelativeDayInMonth.None) + { + if (recur.Yearly.RepeatOnDayOfMonth != app.StartTime.Day) + sb.AppendFormat("{0}{1:D}", ";BYMONTHDAY=", recur.Yearly.RepeatOnDayOfMonth); + } + else + { + AddRRuleByDay(sb, recur.Yearly.RepeatOnRelativeDayInMonth, recur.Yearly.RelativeDayOfWeek); + } + + AddRRuleRangeInfo(sb, recur); + + ExportLine(sb.ToString()); + } + + #endregion + + #region AddRRuleByDay + + /// + /// AddRRuleByDay + /// + /// + /// + private void AddRRuleByDay(StringBuilder sb, eDayOfWeekRecurrence repeat) + { + sb.Append(";BYDAY="); + + if ((repeat & eDayOfWeekRecurrence.Sunday) != 0) + sb.Append("SU,"); + + if ((repeat & eDayOfWeekRecurrence.Monday) != 0) + sb.Append("MO,"); + + if ((repeat & eDayOfWeekRecurrence.Tuesday) != 0) + sb.Append("TU,"); + + if ((repeat & eDayOfWeekRecurrence.Wednesday) != 0) + sb.Append("WE,"); + + if ((repeat & eDayOfWeekRecurrence.Thursday) != 0) + sb.Append("TH,"); + + if ((repeat & eDayOfWeekRecurrence.Friday) != 0) + sb.Append("FR,"); + + if ((repeat & eDayOfWeekRecurrence.Saturday) != 0) + sb.Append("SA,"); + + sb.Length--; + } + + #endregion + + #region AddRRuleByDay + + /// + /// AddRRuleByDay + /// + /// + /// + private void AddRRuleByDay(StringBuilder sb, AppointmentRecurrence recur) + { + if (recur.Daily.RepeatInterval > 1) + { + sb.Append(";BYDAY="); + } + else + { + switch (recur.Daily.RepeatOnDaysOfWeek) + { + case eDailyRecurrenceRepeat.All: + sb.Append(";BYDAY=SU,MO,TU,WE,TH,FR,SA"); + break; + + case eDailyRecurrenceRepeat.WeekDays: + sb.Append(";BYDAY=MO,TU,WE,TH,FR"); + break; + + default: + sb.Append(";BYDAY=SA,SU"); + break; + } + } + } + + #endregion + + #region AddRRuleByDay + + /// + /// AddRRuleByDay + /// + /// + /// + /// + private void AddRRuleByDay(StringBuilder sb, eRelativeDayInMonth rday, DayOfWeek dow) + { + sb.Append(";BYDAY="); + + switch (dow) + { + case DayOfWeek.Sunday: + sb.Append("SU"); + break; + + case DayOfWeek.Monday: + sb.Append("MO"); + break; + + case DayOfWeek.Tuesday: + sb.Append("TU"); + break; + + case DayOfWeek.Wednesday: + sb.Append("WE"); + break; + + case DayOfWeek.Thursday: + sb.Append("TH"); + break; + + case DayOfWeek.Friday: + sb.Append("FR"); + break; + + default: + sb.Append("SA"); + break; + } + + switch (rday) + { + case eRelativeDayInMonth.First: + sb.Append(";BYSETPOS=1"); + break; + + case eRelativeDayInMonth.Second: + sb.Append(";BYSETPOS=2"); + break; + + case eRelativeDayInMonth.Third: + sb.Append(";BYSETPOS=3"); + break; + + case eRelativeDayInMonth.Fourth: + sb.Append(";BYSETPOS=4"); + break; + + case eRelativeDayInMonth.Last: + sb.Append(";BYSETPOS=-1"); + break; + } + } + + #endregion + + #region AddRRuleInterval + + /// + /// AddRRuleInterval + /// + /// + /// + private void AddRRuleInterval(StringBuilder sb, int interval) + { + if (interval > 1) + sb.Append(";INTERVAL=" + interval.ToString()); + } + + #endregion + + #region AddRRuleRangeInfo + + /// + /// AddRRuleRangeInfo + /// + /// + /// + private void AddRRuleRangeInfo(StringBuilder sb, AppointmentRecurrence recur) + { + switch (recur.RangeLimitType) + { + case eRecurrenceRangeLimitType.RangeNumberOfOccurrences: + if (recur.RangeNumberOfOccurrences > 0) + sb.Append(";COUNT=" + (recur.RangeNumberOfOccurrences + 1).ToString()); + break; + + case eRecurrenceRangeLimitType.RangeEndDate: + sb.Append(";UNTIL=" + GetUtcDate(recur.RangeEndDate)); + break; + } + + if (recur.RecurrenceStartDate != DateTime.MinValue && recur.RecurrenceStartDate != recur.Appointment.StartTime) + ExportLine("X-DNB-RECSTARTDATE=" + GetUtcDate(recur.RecurrenceStartDate)); + } + + #endregion + + #endregion + + #region ExportExDate + + /// + /// ExportExDate + /// + /// + private void ExportExDate(AppointmentRecurrence recur) + { + if (recur.SkippedRecurrences != null) + { + foreach (DateTime date in recur.SkippedRecurrences) + ExportLine("EXDATE:" + GetUtcDate(date)); + } + } + + #endregion + + #region ExportAlarms + + /// + /// ExportAlarms + /// + /// + private void ExportAlarms(Appointment app) + { + if (app.Reminders != null) + { + foreach (Reminder rem in app.Reminders) + { + ExportLine("\nBEGIN:VALARM"); + + if (string.IsNullOrEmpty(rem.Description) == false) + ExportLine("DESCRIPTION:" + rem.Description); + + ExportLine("TRIGGER;VALUE=DURATION:" + GetDuration(rem.ReminderTime - app.StartTime)); + ExportLine("ACTION:DISPLAY"); + ExportLine("END:VALARM"); + } + } + + if (app.StartTimeAction != eStartTimeAction.None) + { + ExportLine("\nBEGIN:VALARM"); + ExportLine("TRIGGER;VALUE=DURATION:PT0M"); + ExportLine("ACTION:DISPLAY"); + ExportLine("END:VALARM\n"); + } + } + + #endregion + + #region GetDuration + + /// + /// GetDuration + /// + /// + /// + private string GetDuration(TimeSpan ts) + { + StringBuilder sb = new StringBuilder(); + + if (ts.TotalMinutes < 0) + sb.Append("-"); + + sb.Append("P"); + + int totalMinutes = (int)Math.Abs(ts.TotalMinutes); + + int days = totalMinutes / (24 * 60); + + if (days > 0) + { + sb.Append(days + "D"); + totalMinutes %= (24 * 60); + } + + if (totalMinutes > 0) + { + sb.Append("T"); + + int hours = totalMinutes / 60; + + if (hours > 0) + { + sb.Append(hours + "H"); + totalMinutes %= 60; + } + + if (totalMinutes > 0) + sb.Append(totalMinutes + "M"); + } + + return (sb.ToString()); + } + + #endregion + + #region GetUtcDate + + /// + /// GetUtcDate + /// + /// + /// + private string GetUtcDate(DateTime dateTime) + { + DateTime date = dateTime.ToUniversalTime(); + + return (date.ToString("yyyyMMdd\\tHHmms\\z")); + } + + #endregion + + #endregion + + #region AddMetaData + + /// + /// Adds escape chars to text meta data + /// + /// + /// + private string AddMetaData(string s) + { + Regex p = new Regex("[,;\\n]"); + MatchCollection mc = p.Matches(s); + + if (mc.Count > 0) + { + StringBuilder sb = new StringBuilder(); + + int index = 0; + + foreach (Match ma in mc) + { + if (index < ma.Index) + sb.Append(s.Substring(index, ma.Index - index)); + + index = ma.Index + ma.Length; + + char c = ma.Value[0]; + + if (c == '\n') + c = 'n'; + + sb.Append('\\'); + sb.Append(c); + } + + if (index < s.Length) + sb.Append(s.Substring(index, s.Length - index)); + + return (sb.ToString()); + } + + return (s); + } + + #endregion + + #endregion + + #region ExportLine + + /// + /// Exports a line + /// + /// + private void ExportLine(string text) + { + _StreamWriter.WriteLine(WrapLine(text, FoldCount)); + } + + #region WrapLine + + /// + /// Performs line wrapping (aka folding) + /// + /// Text to wrap + /// Wrapping length + /// + private string WrapLine(string text, int wrapLength) + { + if (text.Length <= wrapLength) + return (text); + + StringBuilder sb = new StringBuilder(); + + int len; + + for (int i = 0; i < text.Length; i += len) + { + len = text.Length - i; + + if (len > wrapLength) + len = BreakLine(text, i, wrapLength); + + if (i > 0) + sb.Append("\n "); + + sb.Append(text, i, len); + } + + return (sb.ToString()); + } + + #endregion + + #region BreakLine + + /// + /// Determines where to break a line of text + /// + /// Text + /// Current text pos + /// Max line length + /// + private int BreakLine(string text, int pos, int max) + { + int i = max - 1; + + while (i > 0 && IsBreakChar(text[pos + i]) == false) + i--; + + if (i <= 0) + return (max); + + while (i >= 0 && Char.IsWhiteSpace(text[pos + i]) == true) + i--; + + return (i + 1); + } + + #endregion + + #region IsBreakChar + + /// + /// Determines if a char is a break char + /// + /// + /// true if break char + private bool IsBreakChar(char c) + { + return (Char.IsWhiteSpace(c) || c == ',' || c == ';'); + } + + #endregion + + #endregion + + #region GetDefaultOwnerKeys + + /// + /// GetDefaultOwnerKeys + /// + /// A list of all defined model OwnerKeys + private string[] GetDefaultOwnerKeys() + { + List list = new List(); + + foreach (Appointment app in Model.Appointments) + { + string key = app.OwnerKey ?? ""; + + if (list.Contains(app.OwnerKey) == false) + list.Add(key); + } + + list.Sort(); + + string[] ownerKeys = new string[list.Count]; + list.CopyTo(ownerKeys); + + return (ownerKeys); + } + + #endregion + + #region GetUniversalTime + + /// + /// GetUniversalTime + /// + /// + /// + private string GetUniversalTime(DateTime date) + { + return (date.ToUniversalTime().ToString("yyyyMMdd\\tHHmms\\z")); + } + + #endregion + + #region IsAppointmentVisible + + /// + /// Determines if an appointment is visible + /// with respect to the given ownerKey + /// + /// + /// + /// + protected virtual bool IsAppointmentVisible(Appointment app, string ownerKey) + { + if (string.IsNullOrEmpty(ownerKey)) + return (true); + + return (app.OwnerKey == ownerKey); + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ImportExport/ICS/IcsImporter.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ImportExport/ICS/IcsImporter.cs new file mode 100644 index 00000000..48143c37 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ImportExport/ICS/IcsImporter.cs @@ -0,0 +1,4206 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +namespace DevComponents.Schedule.Model.Serialization +{ + /// + /// ICS (Internet Calendaring and Scheduling - RFC5545) import into + /// corresponding DNB internal Model/Appointment data layout + /// + public class IcsImporter + { + #region Static data + + #region Component token data + + private static TokenRegistry[] _components = new TokenRegistry[] + { + new TokenRegistry("daylight", (int)ComponentToken.Daylight), + new TokenRegistry("standard", (int)ComponentToken.Standard), + new TokenRegistry("valarm", (int)ComponentToken.VAlarm), + new TokenRegistry("vcalendar", (int)ComponentToken.VCalendar), + new TokenRegistry("vevent", (int)ComponentToken.VEvent), + new TokenRegistry("vfreebusy", (int)ComponentToken.VFreeBusy), + new TokenRegistry("vjournal", (int)ComponentToken.VJournal), + new TokenRegistry("vtimezone", (int)ComponentToken.VTimezone), + new TokenRegistry("vtodo", (int)ComponentToken.VTodo), + }; + + #endregion + + #region Property token data + + private static TokenRegistry[] _properties = new TokenRegistry[] + { + //new TokenRegistry("action", (int)PropertyToken.Action), + //new TokenRegistry("attach", (int)PropertyToken.Attach), + //new TokenRegistry("attendee", (int)PropertyToken.Attendee), + new TokenRegistry("begin", (int)PropertyToken.Begin), + new TokenRegistry("calscale", (int)PropertyToken.CalScale), + //new TokenRegistry("categories", (int)PropertyToken.Categories), + new TokenRegistry("class", (int)PropertyToken.Class), + new TokenRegistry("comment", (int)PropertyToken.Comment), + //new TokenRegistry("completed", (int)PropertyToken.Completed), + //new TokenRegistry("contact", (int)PropertyToken.Contact), + //new TokenRegistry("created", (int)PropertyToken.Created), + new TokenRegistry("description", (int)PropertyToken.Description), + new TokenRegistry("dtend", (int)PropertyToken.DtEnd), + new TokenRegistry("dtstamp", (int)PropertyToken.DtStamp), + new TokenRegistry("dtstart", (int)PropertyToken.DtStart), + new TokenRegistry("due", (int)PropertyToken.Due), + new TokenRegistry("duration", (int)PropertyToken.Duration), + new TokenRegistry("end", (int)PropertyToken.End), + new TokenRegistry("exdate", (int)PropertyToken.ExDate), + //new TokenRegistry("exrule", (int)PropertyToken.ExRule), + //new TokenRegistry("freebusy", (int)PropertyToken.FreeBusy), + //new TokenRegistry("geo", (int)PropertyToken.Geo), + //new TokenRegistry("last-modified", (int)PropertyToken.LastModified), + //new TokenRegistry("location", (int)PropertyToken.Location), + //new TokenRegistry("method", (int)PropertyToken.Method), + //new TokenRegistry("organizer", (int)PropertyToken.Organizer), + //new TokenRegistry("percent-complete", (int)PropertyToken.PercentComplete), + //new TokenRegistry("priority", (int)PropertyToken.Priority), + //new TokenRegistry("progid", (int)PropertyToken.ProgId), + new TokenRegistry("rdate", (int)PropertyToken.RDate), + new TokenRegistry("recurrence-id", (int)PropertyToken.RecurrenceId), + //new TokenRegistry("related-to", (int)PropertyToken.RelatedTo), + //new TokenRegistry("repeat", (int)PropertyToken.Repeat), + //new TokenRegistry("request-status", (int)PropertyToken.RequestStatus), + //new TokenRegistry("resources", (int)PropertyToken.Resources), + new TokenRegistry("rrule", (int)PropertyToken.RRule), + //new TokenRegistry("sequence", (int)PropertyToken.Sequence), + //new TokenRegistry("status", (int)PropertyToken.Status), + new TokenRegistry("summary", (int)PropertyToken.Summary), + //new TokenRegistry("transp", (int)PropertyToken.Transp), + new TokenRegistry("trigger", (int)PropertyToken.Trigger), + new TokenRegistry("tzid", (int)PropertyToken.TzId), + new TokenRegistry("tzname", (int)PropertyToken.TzName), + new TokenRegistry("tzoffsetfrom", (int)PropertyToken.TzOffsetFrom), + new TokenRegistry("tzoffsetto", (int)PropertyToken.TzOffsetTo), + //new TokenRegistry("tzurl", (int)PropertyToken.TzUrl), + new TokenRegistry("uid", (int)PropertyToken.Uid), + //new TokenRegistry("url", (int)PropertyToken.Url), + new TokenRegistry("version", (int)PropertyToken.Version), + new TokenRegistry("x-dnb-categorycolor", (int)PropertyToken.XDnbCategoryColor), + new TokenRegistry("x-dnb-displaytemplate", (int)PropertyToken.XDnbDisplayTemplate), + new TokenRegistry("x-dnb-imagealign", (int)PropertyToken.XDnbImageAlign), + new TokenRegistry("x-dnb-imagekey", (int)PropertyToken.XDnbImageKey), + new TokenRegistry("x-dnb-locked", (int)PropertyToken.XDnbLocked), + new TokenRegistry("x-dnb-recstartdate", (int)PropertyToken.XDnbRecStartDate), + new TokenRegistry("x-dnb-starttimeaction", (int)PropertyToken.XDnbStartTimeAction), + new TokenRegistry("x-dnb-timemarkedas", (int)PropertyToken.XDnbTimeMarkedAs), + new TokenRegistry("x-dnb-tooltip", (int)PropertyToken.XDnbTooltip), + new TokenRegistry("x-wr-calname", (int)PropertyToken.XWrCalname), + }; + + #endregion + + #region Parameter token data + + private static TokenRegistry[] _parameters = new TokenRegistry[] + { + //new TokenRegistry("altrep", (int)eParameterToken.AltRep), + //new TokenRegistry("cn", (int)eParameterToken.Cn), + //new TokenRegistry("cutype", (int)eParameterToken.CuType), + //new TokenRegistry("delegated-from", (int)eParameterToken.DelegatedFrom), + //new TokenRegistry("delegated-to", (int)eParameterToken.DelegatedTo), + //new TokenRegistry("dir", (int)eParameterToken.Dir), + //new TokenRegistry("encoding", (int)eParameterToken.Encoding), + //new TokenRegistry("fmttype", (int)eParameterToken.FmtType), + //new TokenRegistry("fbtype", (int)eParameterToken.FbType), + //new TokenRegistry("language", (int)eParameterToken.Language), + //new TokenRegistry("member", (int)eParameterToken.Member), + //new TokenRegistry("parstat", (int)eParameterToken.ParStat), + //new TokenRegistry("range", (int)eParameterToken.Range), + //new TokenRegistry("related", (int)eParameterToken.Related), + //new TokenRegistry("reltype", (int)eParameterToken.RelType), + //new TokenRegistry("role", (int)eParameterToken.Role), + //new TokenRegistry("rsvp", (int)eParameterToken.Rsvp), + //new TokenRegistry("sent-by", (int)eParameterToken.SentBy), + new TokenRegistry("tzid", (int)ParameterToken.TzId), + new TokenRegistry("value", (int)ParameterToken.Value), + }; + + #endregion + + #region Value token data + + private static TokenRegistry[] _values = new TokenRegistry[] + { + new TokenRegistry("byday", (int)ValueToken.ByDay), + new TokenRegistry("byhour", (int)ValueToken.ByHour), + new TokenRegistry("byminute", (int)ValueToken.ByMinute), + new TokenRegistry("bymonth", (int)ValueToken.ByMonth), + new TokenRegistry("bymonthday", (int)ValueToken.ByMonthDay), + new TokenRegistry("bysecond", (int)ValueToken.BySecond), + new TokenRegistry("bysetpos", (int)ValueToken.BySetPos), + new TokenRegistry("byweekno", (int)ValueToken.ByWeekNo), + new TokenRegistry("byyearday", (int)ValueToken.ByYearDay), + new TokenRegistry("count", (int)ValueToken.Count), + new TokenRegistry("daily", (int)ValueToken.Daily), + new TokenRegistry("date", (int)ValueToken.Date), + new TokenRegistry("datetime", (int)ValueToken.DateTime), + new TokenRegistry("duration", (int)ValueToken.Duration), + new TokenRegistry("end", (int)ValueToken.End), + new TokenRegistry("fr", (int)ValueToken.Fr), + new TokenRegistry("freq", (int)ValueToken.Freq), + new TokenRegistry("gregorian", (int)ValueToken.Gregorian), + new TokenRegistry("hourly", (int)ValueToken.Hourly), + new TokenRegistry("interval", (int)ValueToken.Interval), + new TokenRegistry("minutely", (int)ValueToken.Minutely), + new TokenRegistry("mo", (int)ValueToken.Mo), + new TokenRegistry("monthly", (int)ValueToken.Monthly), + new TokenRegistry("period", (int)ValueToken.Period), + new TokenRegistry("sa", (int)ValueToken.Sa), + new TokenRegistry("secondly", (int)ValueToken.Secondly), + new TokenRegistry("start", (int)ValueToken.Start), + new TokenRegistry("su", (int)ValueToken.Su), + new TokenRegistry("text", (int)ValueToken.Text), + new TokenRegistry("th", (int)ValueToken.Th), + new TokenRegistry("tu", (int)ValueToken.Tu), + new TokenRegistry("until", (int)ValueToken.Until), + new TokenRegistry("we", (int)ValueToken.We), + new TokenRegistry("weekly", (int)ValueToken.Weekly), + new TokenRegistry("wkst", (int)ValueToken.WkSt), + new TokenRegistry("yearly", (int)ValueToken.Yearly), + }; + + #endregion + + #endregion + + #region Constants + + private const string Version = "2.0"; + + #endregion + + #region Constructors + + public IcsImporter() + { + } + + public IcsImporter(CalendarModel model) + { + Model = model; + } + + #endregion + + #region Private variables + + private int _EntryIndex; + + private IcsComponent _IncludeComponent = IcsComponent.All; + private Dictionary> _Uid = new Dictionary>(); + private List _CalendarTimeZone; + + private List _CalendarEntries = new List(); + + private CalendarModel _Model; + + private string[] _CalNames; + private string[] _OwnerKeys; + + private string _ImportFile; + + private bool _IgnoreErrors; + + #endregion + + #region Public properties + + #region IgnoreErrors + + /// + /// Ignore import Errors + /// + public bool IgnoreErrors + { + get { return (_IgnoreErrors); } + set { _IgnoreErrors = value; } + } + + #endregion + + #region IncludeComponent + + /// + /// Gets or sets the iCalendar components to include in the import. + /// + [DefaultValue(IcsComponent.All)] + [Description("Indicates which iCalendar component to include in the import.")] + public IcsComponent IncludeComponent + { + get { return (_IncludeComponent); } + set { _IncludeComponent = value; } + } + + #endregion + + #region Model + + /// + /// CalendarModel + /// + public CalendarModel Model + { + get { return (_Model); } + set { _Model = value; } + } + + #endregion + + #endregion + + #region Import + + /// + /// Imports all appointments from the given export file's + /// calName array Calendar entries, and associates them with the + /// given OwnerKey array entries. + /// + /// Array of Calendar names + /// Array of associated OwnerKeys + /// Import file path. + public void Import(string[] calNames, string[] ownerKeys, StreamReader streamReader) + { + if (_Model == null) + throw new Exception("Model can not be null."); + + if (streamReader == null) + throw new Exception("Invalid StreamReader."); + + _CalNames = calNames; + _OwnerKeys = ownerKeys; + + if (String.IsNullOrEmpty(_ImportFile) == true) + _ImportFile = streamReader.BaseStream.ToString(); + + _CalendarEntries.Clear(); + + Parse(streamReader); + + if (_CalendarEntries.Count > 0) + { + CalendarEntry entry = GetFirstEntry(); + + try + { + Model.BeginUpdate(); + + ProcessCalendarEntries(entry); + } + finally + { + Model.EndUpdate(); + } + } + } + + #region Import variations + + /// + /// Imports all appointments from the given input file. + /// + /// Input file + public void Import(string importFile) + { + Import((string[])null, null, importFile); + } + + /// + /// Imports all appointments from the given input stream. + /// + /// Input file StreamReader + public void Import(StreamReader streamReader) + { + Import((string[])null, null, streamReader); + } + + /// + /// Imports all appointments from the given export file + /// calName Calendar entry. + /// + /// Calendar entry name + /// Import file path. + public void Import(string calName, string importFile) + { + Import(calName, calName, importFile); + } + + /// + /// Imports all appointments from the given export stream + /// calName Calendar entry. + /// + /// Calendar entry name + /// Import file StreamReader. + public void Import(string calName, StreamReader streamReader) + { + Import(calName, calName, streamReader); + } + + /// + /// Imports all appointments from the given export file + /// calName Calendar entry, and associates them with the + /// given OwnerKey. + /// + /// Calendar entry name + /// Associated OwnerKey + /// Import file path. + public void Import(string calName, string ownerKey, string importFile) + { + string[] calNames = new string[] { calName }; + string[] ownerKeys = new string[] { ownerKey }; + + Import(calNames, ownerKeys, importFile); + } + + /// + /// Imports all appointments from the given export stream + /// calName Calendar entry, and associates them with the + /// given OwnerKey. + /// + /// Calendar entry name + /// Associated OwnerKey + /// Import file StreamReader. + public void Import(string calName, string ownerKey, StreamReader streamReader) + { + string[] calNames = new string[] { calName }; + string[] ownerKeys = new string[] { ownerKey }; + + Import(calNames, ownerKeys, streamReader); + } + + /// + /// Imports all appointments from the given export file + /// calName array Calendar entries, and associates them with the + /// given OwnerKey array entries. + /// + /// Array of Calendar names + /// Array of associated OwnerKeys + /// Import file path. + public void Import(string[] calNames, string[] ownerKeys, string importFile) + { + _ImportFile = importFile; + + using (StreamReader streamReader = new StreamReader(importFile)) + Import(calNames, ownerKeys, streamReader); + } + + #endregion + + #endregion + + #region ProcessCalendarEntries + + /// + /// Initiates the processing of each calendar component entry + /// + /// + private void ProcessCalendarEntries(CalendarEntry entry) + { + while (entry != null) + { + switch ((PropertyToken)GetToken(_properties, entry.Id)) + { + case PropertyToken.Begin: + switch ((ComponentToken)GetToken(_components, entry.Value)) + { + case ComponentToken.VCalendar: + ProcessVCalendar(); + break; + } + break; + } + + entry = GetNextEntry(); + } + } + + #endregion + + #region ProcessVCalendar + + #region ProcessVCalendar + + /// + /// Processes individual calendar component entries + /// + private void ProcessVCalendar() + { + string ownerKey = ""; + bool validCalName = true; + + CalendarEntry entry = GetNextEntry(); + + while (entry != null) + { + switch ((PropertyToken) GetToken(_properties, entry.Id)) + { + case PropertyToken.Begin: + bool include = false; + ComponentToken ctkn = (ComponentToken)GetToken(_components, entry.Value); + + if (validCalName == true) + { + switch (ctkn) + { + case ComponentToken.VEvent: + include = (_IncludeComponent & IcsComponent.Event) != 0; + + if (include == true) + ProcessVEvent(ownerKey); + break; + + case ComponentToken.VTimezone: + include = (_IncludeComponent & IcsComponent.Timezone) != 0; + + if (include == true) + ProcessVTimezone(); + break; + + case ComponentToken.VTodo: + include = (_IncludeComponent & IcsComponent.Todo) != 0; + + if (include == true) + ProcessVTodo(ownerKey); + break; + + case ComponentToken.VFreeBusy: + case ComponentToken.VJournal: + break; + + default: + ReportError(entry, "Unexpected \"BEGIN:" + entry.Value.ToUpper() + "\""); + break; + } + } + + if (include == false) + SkipComponent(ctkn); + break; + + case PropertyToken.CalScale: + ProcessCalScale(entry); + break; + + case PropertyToken.End: + ProcessCalEnd(entry); + return; + + case PropertyToken.Version: + ProcessVersion(entry); + break; + + case PropertyToken.XWrCalname: + string calName = ProcessWrCalName(entry); + + validCalName = IsValidCalName(calName); + + if (validCalName == true) + ownerKey = GetOwnerKey(calName); + break; + } + + entry = GetNextEntry(); + } + + ReportError(entry, "Expected \"END:VCALENDAR\""); + } + + #endregion + + #region ProcessCalEnd + + /// + /// Processes final Calendar component termination + /// + /// + private void ProcessCalEnd(CalendarEntry entry) + { + if ((ComponentToken)GetToken(_components, entry.Value) != ComponentToken.VCalendar) + ReportError(entry, "Expected \"END:VCALENDAR\""); + } + + #endregion + + #region ProcessCalScale + + /// + /// Processes Calendar Scale (Gregorian only support) + /// + /// + private void ProcessCalScale(CalendarEntry entry) + { + ValueToken tkn = (ValueToken)GetToken(_values, entry.Value); + + if (tkn != ValueToken.Gregorian) + ReportError(entry, "Only GREGORIAN calendar scale is supported"); + } + + #endregion + + #region ProcessVersion + + /// + /// Processes Calendar version entries + /// + /// + private void ProcessVersion(CalendarEntry entry) + { + if (entry.Value.Equals(Version) == false) + ReportError(entry, "iCalendar VERSION 2.0 is required"); + } + + #endregion + + #region ProcessVEvent + + #region ProcessVEvent + + /// + /// Processes Event components for the given OwnerKey + /// + /// Associated OwnerKey + private void ProcessVEvent(string ownerKey) + { + Appointment app = new Appointment(); + app.OwnerKey = ownerKey; + + VEventData evData = new VEventData(); + + CalendarEntry entry = GetNextEntry(); + + while (entry != null) + { + PropertyToken tkn = (PropertyToken)GetToken(_properties, entry.Id); + + switch (tkn) + { + case PropertyToken.Begin: + ComponentToken ctkn = (ComponentToken)GetToken(_components, entry.Value); + + switch (ctkn) + { + case ComponentToken.VAlarm: + ProcessVAlarm(evData); + break; + + default: + ReportError(entry, "Unexpected \"BEGIN:" + entry.Value.ToUpper() + "\""); + SkipComponent(ctkn); + break; + } + break; + + case PropertyToken.Class: + app.Private = ProcessClass(entry, evData); + break; + + case PropertyToken.Description: + app.Description = ProcessDescription(entry, evData); + break; + + case PropertyToken.DtEnd: + app.EndTime = ProcessDate(entry, ref evData.IsDtEndValue); + break; + + case PropertyToken.DtStart: + app.StartTime = ProcessDate(entry, ref evData.IsDtStartValue); + break; + + case PropertyToken.Duration: + evData.Duration = ProcessDuration(entry, entry.Value); + break; + + case PropertyToken.End: + if ((ComponentToken)GetToken(_components, entry.Value) != ComponentToken.VEvent) + ReportError(entry, "Expected \"END:VEVENT\""); + + ProcessVEventEnd(entry, app, evData); + return; + + case PropertyToken.ExDate: + ProcessExDate(entry, evData); + break; + + case PropertyToken.RDate: + evData.RecurDate = ProcessRDate(entry, evData.RecurDate); + break; + + case PropertyToken.RecurrenceId: + evData.RecIdDate = ProcessRecurrenceId(entry); + break; + + case PropertyToken.RRule: + evData.RecurRule = ProcessRRule(entry); + break; + + case PropertyToken.Summary: + app.Subject = ProcessSummary(entry, evData); + break; + + case PropertyToken.Uid: + evData.UidApps = ProcessUid(entry, app); + break; + + case PropertyToken.XDnbCategoryColor: + app.CategoryColor = ProcessXDnbCategoryColor(entry, evData); + break; + + case PropertyToken.XDnbDisplayTemplate: + app.DisplayTemplate = ProcessXDnbDisplayTemplate(entry, evData); + break; + + case PropertyToken.XDnbImageAlign: + app.ImageAlign = ProcessXDnbImageAlign(entry, evData); + break; + + case PropertyToken.XDnbImageKey: + app.ImageKey = ProcessXDnbImageKey(entry, evData); + break; + + case PropertyToken.XDnbLocked: + app.Locked = ProcessXDnbLocked(entry, evData); + break; + + case PropertyToken.XDnbRecStartDate: + evData.RecStartDate = ProcessXDnbRecStartDate(entry); + break; + + case PropertyToken.XDnbStartTimeAction: + app.StartTimeAction = ProcessXDnbStartTimeAction(entry, evData); + break; + + case PropertyToken.XDnbTimeMarkedAs: + app.TimeMarkedAs = ProcessXDnbTimeMarkedAs(entry, evData); + break; + + case PropertyToken.XDnbTooltip: + app.Tooltip = ProcessXDnbTooltip(entry, evData); + break; + } + + entry = GetNextEntry(); + } + + ReportError(entry, "Expected \"END:VEVENT\""); + } + + #endregion + + #region ProcessVEventEnd + + #region ProcessVEventEnd + + /// + /// Processes Event termination + /// + /// + /// + /// + private void ProcessVEventEnd(CalendarEntry entry, Appointment app, VEventData evData) + { + if (evData.RecIdDate != DateTime.MinValue) + ProcessRecurrenceId(entry, app, evData); + else + ProcessEventEndEx(Model, entry, app, evData); + } + + #endregion + + #region ProcessEventEndEx + + /// + /// ProcessEventEndEx + /// + /// + /// + /// + /// + private void ProcessEventEndEx(CalendarModel model, + CalendarEntry entry, Appointment app, VEventData evData) + { + if (ValidateAppTime(entry, app, evData) == true) + { + if (evData.UidApps == null) + { + evData.UidApps = new List(); + evData.UidApps.Add(app); + } + + if (evData.RecurRule != null) + { + switch (evData.RecurRule.Freq) + { + case Frequency.Daily: + ProcessDailyRecurrence(model, app, evData); + break; + + case Frequency.Weekly: + ProcessWeeklyRecurrence(model, app, evData); + break; + + case Frequency.Monthly: + ProcessMonthlyRecurrence(model, app, evData); + break; + + case Frequency.Yearly: + ProcessYearlyRecurrence(model, app, evData); + break; + } + + ProcessRDateRange(model, app, evData); + } + else + { + model.Appointments.Add(app); + } + + ProcessVEventReminder(evData); + } + } + + #region ValidateAppTime + + private bool ValidateAppTime(CalendarEntry entry, Appointment app, VEventData evData) + { + if (app.StartTime == DateTime.MinValue) + { + ReportError(entry, "DTSTART not set"); + return (false); + } + + if (evData.Duration.TotalSeconds != 0) + app.EndTime = app.StartTime.Add(evData.Duration); + + else if (app.EndTime == DateTime.MinValue) + { + app.EndTime = (evData.IsDtStartValue == true) + ? app.StartTime.AddDays(1) + : app.StartTime; + } + + if (app.StartTime > app.EndTime) + { + ReportError(entry, "DTSTART is greater than DTEND"); + return (false); + } + + evData.StartTime = app.StartTime; + evData.EndTime = app.EndTime; + + return (true); + } + + #endregion + + #endregion + + #region ProcessDailyRecurrence + + /// + /// Processes Daily recurrences + /// + /// + /// + /// + private void ProcessDailyRecurrence(CalendarModel model, Appointment app, VEventData evData) + { + AppointmentRecurrence recur = new AppointmentRecurrence(); + + recur.RecurrenceType = eRecurrencePatternType.Daily; + + recur.Daily.RepeatInterval = evData.RecurRule.Interval; + + switch (evData.RecurRule.ByDays) + { + case eDayOfWeekRecurrence.WeekDays: + recur.Daily.RepeatOnDaysOfWeek = eDailyRecurrenceRepeat.WeekDays; + break; + + case eDayOfWeekRecurrence.WeekendDays: + recur.Daily.RepeatOnDaysOfWeek = eDailyRecurrenceRepeat.WeekendDays; + break; + } + + ProcessRecurrenceRange(app, recur, evData); + + app.Recurrence = recur; + + model.Appointments.Add(app); + } + + #endregion + + #region ProcessWeeklyRecurrence + + /// + /// Processes Weekly recurrences + /// + /// + /// + /// + private void ProcessWeeklyRecurrence(CalendarModel model, Appointment app, VEventData evData) + { + AppointmentRecurrence recur = new AppointmentRecurrence(); + + recur.RecurrenceType = eRecurrencePatternType.Weekly; + + recur.Weekly.RepeatInterval = evData.RecurRule.Interval; + + recur.Weekly.RepeatOnDaysOfWeek = (evData.RecurRule.ByDays == eDayOfWeekRecurrence.None) + ? GetRecurrenceDay(app.StartTime) + : evData.RecurRule.ByDays; + + ProcessRecurrenceRange(app, recur, evData); + + app.Recurrence = recur; + + model.Appointments.Add(app); + } + + #region GetRecurrenceDay + + private eDayOfWeekRecurrence GetRecurrenceDay(DateTime dateTime) + { + switch (dateTime.DayOfWeek) + { + case DayOfWeek.Monday: + return (eDayOfWeekRecurrence.Monday); + + case DayOfWeek.Tuesday: + return (eDayOfWeekRecurrence.Tuesday); + + case DayOfWeek.Wednesday: + return (eDayOfWeekRecurrence.Wednesday); + + case DayOfWeek.Thursday: + return (eDayOfWeekRecurrence.Thursday); + + case DayOfWeek.Friday: + return (eDayOfWeekRecurrence.Friday); + + case DayOfWeek.Saturday: + return (eDayOfWeekRecurrence.Saturday); + + default: + return (eDayOfWeekRecurrence.Sunday); + } + } + + #endregion + + #endregion + + #region ProcessMonthlyRecurrence + + #region ProcessMonthlyRecurrence + + /// + /// Processes Monthly recurrences + /// + /// + /// + /// + private void ProcessMonthlyRecurrence(CalendarModel model, Appointment app, VEventData evData) + { + RRule rrule = evData.RecurRule; + + if (rrule.ByDays == eDayOfWeekRecurrence.None) + { + if (rrule.ByMonthDay != null) + { + foreach (int day in rrule.ByMonthDay) + AddMonthlyByMonthDay(model, app, day, evData); + } + else + { + AddMonthlyByMonthDay(model, app, app.StartTime.Day, evData); + } + } + else + { + for (int i = 0; i < rrule.ByDay.Length; i++) + { + eDayOfWeekRecurrence eday = ((eDayOfWeekRecurrence)(1 << i)); + DayOfWeek dayOfWeek = GetRelativeDayOfWeek(eday); + + if ((rrule.ByDays & eday) != 0) + { + foreach (int byDay in rrule.ByDay[i]) + AddMonthlyByDay(model, app, dayOfWeek, byDay, evData); + } + } + } + } + + #endregion + + #region AddMonthlyByDay + + #region AddMonthlyByDay + + private void AddMonthlyByDay(CalendarModel model, + Appointment app, DayOfWeek dayOfWeek, int byDay, VEventData evData) + { + AppointmentRecurrence recur = new AppointmentRecurrence(); + + recur.RecurrenceType = eRecurrencePatternType.Monthly; + + recur.Monthly.RepeatInterval = evData.RecurRule.Interval; + recur.Monthly.RelativeDayOfWeek = dayOfWeek; + recur.Monthly.RepeatOnRelativeDayInMonth = GetRelativeDay(byDay); + + if (app.Recurrence != null) + { + app = app.Copy(); + + app.StartTime = evData.StartTime; + app.EndTime = evData.EndTime; + + evData.UidApps.Add(app); + } + + model.Appointments.Add(app); + + DateTime oldStartTime = app.StartTime; + + SetNewByDayAppStartTime(app, dayOfWeek, byDay, evData.RecurRule.BySetPos); + + if (app.StartTime < oldStartTime) + recur.SkippedRecurrences.Add(app.StartTime); + + ProcessRecurrenceRange(app, recur, evData); + + app.Recurrence = recur; + } + + #endregion + + #region SetNewByDayAppStartTime + + /// + /// SetNewByDayAppStartTime + /// + /// + /// + /// + private void SetNewByDayAppStartTime( + Appointment app, DayOfWeek dayOfWeek, int byDay, int bySetPos) + { + DateTime date = app.StartTime.AddDays(-app.StartTime.Day + 1); + + if (byDay >= 0) + { + while (date.DayOfWeek != dayOfWeek) + date = date.AddDays(1); + + if (byDay > 0) + date = date.AddDays((byDay - 1) * 7); + } + else + { + date = date.AddMonths(1).AddDays(-1); + + while (date.DayOfWeek != dayOfWeek) + date = date.AddDays(-1); + } + + if (bySetPos != 0) + { + if (bySetPos == -1) + { + while (date.AddDays(7).Month == date.Month) + date = date.AddDays(7); + } + else if (bySetPos > 1) + { + date = date.AddDays(7 * (bySetPos - 1)); + } + } + + if (app.StartTime != date) + app.MoveTo(date); + } + + #endregion + + #endregion + + #region AddMonthlyByMonthDay + + private void AddMonthlyByMonthDay(CalendarModel model, + Appointment app, int byMonthDay, VEventData evData) + { + AppointmentRecurrence recur = new AppointmentRecurrence(); + + recur.RecurrenceType = eRecurrencePatternType.Monthly; + + recur.Monthly.RepeatOnRelativeDayInMonth = eRelativeDayInMonth.None; + recur.Monthly.RepeatOnDayOfMonth = byMonthDay; + recur.Monthly.RepeatInterval = evData.RecurRule.Interval; + + if (app.Recurrence != null) + { + app = app.Copy(); + + evData.UidApps.Add(app); + } + + model.Appointments.Add(app); + + int day = DateTime.DaysInMonth(app.StartTime.Year, app.StartTime.Month); + + if (day < byMonthDay) + byMonthDay = day; + + DateTime startTime = new DateTime(app.StartTime.Year, + app.StartTime.Month, byMonthDay, app.StartTime.Hour, app.StartTime.Minute, 0); + + if (startTime < app.StartTime) + recur.SkippedRecurrences.Add(startTime); + + if (app.StartTime != startTime) + app.MoveTo(startTime); + + ProcessRecurrenceRange(app, recur, evData); + + app.Recurrence = recur; + } + + #endregion + + #endregion + + #region ProcessYearlyRecurrence + + #region ProcessYearlyRecurrence + + /// + /// Processes Yearly recurrences + /// + /// + /// + /// + private void ProcessYearlyRecurrence( + CalendarModel model, Appointment app, VEventData evData) + { + RRule rrule = evData.RecurRule; + + if (rrule.ByMonth == null) + { + rrule.ByMonth = new int[1]; + rrule.ByMonth[0] = app.StartTime.Month; + } + + foreach (int byMonth in rrule.ByMonth) + { + if (rrule.ByDays == eDayOfWeekRecurrence.None) + { + if (rrule.ByMonthDay != null) + { + foreach (int day in rrule.ByMonthDay) + AddYearlyByMonthDay(model, app, byMonth, day, evData); + } + else + { + AddYearlyByMonthDay(model, app, byMonth, app.StartTime.Day, evData); + } + } + else + { + for (int i = 0; i < rrule.ByDay.Length; i++) + { + eDayOfWeekRecurrence eday = ((eDayOfWeekRecurrence)(1 << i)); + DayOfWeek dayOfWeek = GetRelativeDayOfWeek(eday); + + if ((rrule.ByDays & eday) != 0) + { + foreach (int byDay in rrule.ByDay[i]) + AddYearlyByDay(model, app, byMonth, dayOfWeek, byDay, evData); + } + } + } + } + } + + #endregion + + #region AddYearlyByDay + + private void AddYearlyByDay(CalendarModel model, Appointment app, + int byMonth, DayOfWeek dayOfWeek, int byDay, VEventData evData) + { + AppointmentRecurrence recur = new AppointmentRecurrence(); + + recur.RecurrenceType = eRecurrencePatternType.Yearly; + + recur.Yearly.RepeatOnMonth = byMonth; + recur.Yearly.RelativeDayOfWeek = dayOfWeek; + recur.Yearly.RepeatOnRelativeDayInMonth = GetRelativeDay(byDay); + + if (app.Recurrence != null) + { + app = app.Copy(); + + evData.UidApps.Add(app); + } + + model.Appointments.Add(app); + + DateTime oldStartTime = app.StartTime; + + SetNewByDayAppStartTime(app, dayOfWeek, byDay, evData.RecurRule.BySetPos); + + if (app.StartTime < oldStartTime) + recur.SkippedRecurrences.Add(app.StartTime); + + ProcessRecurrenceRange(app, recur, evData); + + app.Recurrence = recur; + } + + #endregion + + #region AddYearlyByMonthDay + + private void AddYearlyByMonthDay(CalendarModel model, + Appointment app, int byMonth, int byMonthDay, VEventData evData) + { + AppointmentRecurrence recur = new AppointmentRecurrence(); + + recur.RecurrenceType = eRecurrencePatternType.Yearly; + + recur.Yearly.RepeatOnMonth = byMonth; + recur.Yearly.RepeatOnRelativeDayInMonth = eRelativeDayInMonth.None; + recur.Yearly.RepeatOnDayOfMonth = byMonthDay; + + if (app.Recurrence != null) + { + app = app.Copy(); + + evData.UidApps.Add(app); + } + + model.Appointments.Add(app); + + int day = DateTime.DaysInMonth(app.StartTime.Year, byMonth); + + if (day < byMonthDay) + byMonthDay = day; + + DateTime startTime = new DateTime(app.StartTime.Year, + byMonth, byMonthDay, app.StartTime.Hour, app.StartTime.Minute, 0); + + if (startTime < app.StartTime) + recur.SkippedRecurrences.Add(startTime); + + if (app.StartTime != startTime) + app.MoveTo(startTime); + + ProcessRecurrenceRange(app, recur, evData); + + app.Recurrence = recur; + } + + #endregion + + #endregion + + #region ProcessVEventReminder + + /// + /// Processes event reminders + /// + /// + private void ProcessVEventReminder(VEventData evData) + { + if (evData.VAlarms != null) + { + foreach (VAlarm valarm in evData.VAlarms) + { + foreach (Appointment app in evData.UidApps) + { + if ((valarm.Rel == Related.Start && valarm.Duration.TotalSeconds == 0) || + (valarm.Rel == Related.Date && valarm.Date.Add(valarm.Duration) == app.StartTime)) + { + app.StartTimeAction = eStartTimeAction.StartTimeReachedEvent; + } + else + { + string s = String.IsNullOrEmpty(valarm.Description) + ? app.Description + : valarm.Description; + + DateTime date = app.StartTime; + + switch (valarm.Rel) + { + case Related.End: + date = app.EndTime; + break; + + case Related.Date: + date = valarm.Date; + break; + } + + date = date.Add(valarm.Duration); + + app.Reminders.Add(new Reminder(s, date)); + } + } + } + } + } + + #endregion + + #region ProcessRecurrenceId + + /// + /// Processes RecurrenceId events + /// + /// + /// + /// + private void ProcessRecurrenceId(CalendarEntry entry, Appointment app, VEventData evData) + { + if (evData.UidApps != null) + { + Appointment uidApp = null; + + foreach (Appointment uApp in evData.UidApps) + { + if (uApp.Recurrence != null) + { + if (uidApp == null) + uidApp = uApp; + + uApp.Recurrence.SkippedRecurrences.Add(evData.RecIdDate); + } + } + + if (uidApp != null) + { + if (app.StartTime == DateTime.MinValue) + app.StartTime = evData.RecIdDate; + + if (evData.Duration.TotalSeconds != 0) + app.EndTime = app.StartTime.Add(evData.Duration); + + else if (app.EndTime == DateTime.MinValue) + app.EndTime = app.StartTime.Add(uidApp.EndTime - uidApp.StartTime); + + if (app.StartTime > app.EndTime) + { + ReportError(entry, "DTSTART is greater than DTEND"); + app.EndTime = app.StartTime.Add(uidApp.EndTime - uidApp.StartTime); + } + + if ((evData.AppPropSet & AppProp.Description) == 0) + app.Description = uidApp.Description; + + if ((evData.AppPropSet & AppProp.Summary) == 0) + app.Subject = uidApp.Subject; + + if ((evData.AppPropSet & AppProp.XDnbCategoryColor) == 0) + app.CategoryColor = uidApp.CategoryColor; + + if ((evData.AppPropSet & AppProp.XDnbDisplayTemplate) == 0) + app.DisplayTemplate = uidApp.DisplayTemplate; + + if ((evData.AppPropSet & AppProp.XDnbImageAlign) == 0) + app.ImageAlign = uidApp.ImageAlign; + + if ((evData.AppPropSet & AppProp.XDnbImageKey) == 0) + app.ImageKey = uidApp.ImageKey; + + if ((evData.AppPropSet & AppProp.XDnbLocked) == 0) + app.Locked = uidApp.Locked; + + if ((evData.AppPropSet & AppProp.XDnbStartTimeAction) == 0) + app.StartTimeAction = uidApp.StartTimeAction; + + if ((evData.AppPropSet & AppProp.XDnbTimeMarkedAs) == 0) + app.TimeMarkedAs = uidApp.TimeMarkedAs; + + if ((evData.AppPropSet & AppProp.XDnbTooltip) == 0) + app.Tooltip = uidApp.Tooltip; + + Model.Appointments.Add(app); + } + } + } + + #endregion + + #region ProcessRecurrenceRange + + /// + /// Processes Recurrence range values + /// + /// + /// + /// + private void ProcessRecurrenceRange( + Appointment app, AppointmentRecurrence recur, VEventData evData) + { + recur.RecurrenceStartDate = + (evData.RecStartDate != DateTime.MinValue) ? evData.RecStartDate : app.StartTime; + + if (evData.RecurRule.BySetPos != 0) + { + if (evData.RecurRule.BySetPos == -1) + recur.Monthly.RepeatOnRelativeDayInMonth = eRelativeDayInMonth.Last; + + else if (evData.RecurRule.BySetPos == 1) + recur.Monthly.RepeatOnRelativeDayInMonth = eRelativeDayInMonth.First; + + else if (evData.RecurRule.BySetPos == 2) + recur.Monthly.RepeatOnRelativeDayInMonth = eRelativeDayInMonth.Second; + + else if (evData.RecurRule.BySetPos == 3) + recur.Monthly.RepeatOnRelativeDayInMonth = eRelativeDayInMonth.Third; + + else if (evData.RecurRule.BySetPos == 4) + recur.Monthly.RepeatOnRelativeDayInMonth = eRelativeDayInMonth.Fourth; + } + + if (evData.RecurRule.Count > 0) + { + recur.RangeLimitType = eRecurrenceRangeLimitType.RangeNumberOfOccurrences; + recur.RangeNumberOfOccurrences = evData.RecurRule.Count - 1; + } + + if (evData.RecurRule.Until != DateTime.MinValue) + { + recur.RangeLimitType = eRecurrenceRangeLimitType.RangeEndDate; + recur.RangeEndDate = evData.RecurRule.Until; + } + + if (evData.ExDates != null) + { + foreach (DateTime date in evData.ExDates) + { + if (date >= app.StartTime) + { + if (IsSkippableDate(app, date, evData) == true) + recur.SkippedRecurrences.Add(date); + } + } + } + } + + #region IsSkippableDate + + #region IsSkippableDate + + /// + /// Determines if the given date is a valid + /// SkippedRecurrence date. + /// + /// + /// + /// + /// + private bool IsSkippableDate(Appointment app, DateTime date, VEventData evData) + { + if (IsSkippableByMonth(app, date, evData) == false) + return (false); + + if (IsSkippableByMonthDay(app, date, evData) == false) + return (false); + + return (IsSkippableByDay(date, evData)); + } + + #endregion + + #region IsSkippableByMonthDay + + /// + /// Determines if the given date is a skippable + /// byMonthDate + /// + /// + /// + /// + /// + private bool IsSkippableByMonthDay(Appointment app, DateTime date, VEventData evData) + { + if (evData.RecurRule.ByMonthDay != null) + { + if (date.Day != app.StartTime.Day) + return (false); + } + + return (true); + } + + #endregion + + #region IsSkippableByMonth + + /// + /// Determines if the given date is a skippable ByMonth date + /// + /// + /// + /// + /// + private bool IsSkippableByMonth(Appointment app, DateTime date, VEventData evData) + { + if (evData.RecurRule.ByMonth != null) + { + if (date.Month != app.StartTime.Month) + return (false); + } + + return (true); + } + + #endregion + + #region IsSkippableByDay + + /// + /// Determines if the given date is a skippable ByDays date + /// + /// + /// + /// + private bool IsSkippableByDay(DateTime date, VEventData evData) + { + if (evData.RecurRule.ByDays != eDayOfWeekRecurrence.None) + { + string s = Enum.GetName(typeof(DayOfWeek), date.DayOfWeek); + eDayOfWeekRecurrence edow = (eDayOfWeekRecurrence)Enum.Parse(typeof(eDayOfWeekRecurrence), s); + + return ((evData.RecurRule.ByDays & edow) == edow); + } + + return (true); + } + + #endregion + + #endregion + + #endregion + + #region ProcessRDateRange + + /// + /// ProcessRDateRange + /// + /// + /// + /// + private void ProcessRDateRange( + CalendarModel model, Appointment app, VEventData evData) + { + if (evData.RecurDate != null) + { + if (evData.RecurDate.DtRange != null) + { + foreach (DateRange range in evData.RecurDate.DtRange) + { + Appointment appRange = app.Copy(); + + appRange.StartTime = range.StartTime; + appRange.EndTime = range.EndTime; + + model.Appointments.Add(appRange); + } + } + } + } + + #endregion + + #endregion + + #region ProcessClass + + /// + /// Processes event Class values + /// + /// + /// + /// + private bool ProcessClass(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.Class; + + if (string.IsNullOrEmpty(entry.Value)) + return (false); + + return (entry.Value.ToUpper().Equals("PRIVATE")); + } + + #endregion + + #region ProcessDate + + #region ProcessDate + + /// + /// Processes Attribute date values + /// + /// + /// + /// + private DateTime ProcessDate(CalendarEntry entry, ref bool isDateValue) + { + isDateValue = false; + + if (entry.Attributes.Count > 0) + { + foreach (AttributeData attr in entry.Attributes) + { + ParameterToken tkn = (ParameterToken)GetToken(_parameters, attr.Id); + + switch (tkn) + { + case ParameterToken.TzId: + return (ProcessTzIdDateTime(attr.Value, entry, entry.Value)); + + case ParameterToken.Value: + switch ((ValueToken)GetToken(_values, attr.Value)) + { + case ValueToken.Date: + isDateValue = true; + + return (ProcessDateValue(entry, entry.Value)); + + case ValueToken.DateTime: + return (ProcessDateTime(entry, entry.Value)); + + default: + ReportError(entry, + "Unrecognized Date attribute Value (" + attr.Id + "=" + attr.Value + ")"); + + return (DateTime.MinValue); + } + } + } + } + + if (entry.Value.Length > 8) + return (ProcessDateTime(entry, entry.Value)); + + isDateValue = true; + + return (ProcessDateValue(entry, entry.Value)); + } + + #endregion + + #region ProcessDateTime + + /// + /// Processes attribute DateTime values + /// + /// + /// + /// + private DateTime ProcessDateTime(CalendarEntry entry, string sdate) + { + sdate = sdate.ToLower(); + + DateTime date; + + if (sdate.EndsWith("z")) + { + if (DateTime.TryParseExact(sdate, "yyyyMMdd\\tHHmms\\z", + CultureInfo.InvariantCulture, DateTimeStyles.None, out date) == false) + { + ReportError(entry, "Invalid DateTime value specified"); + } + else + { + date = date.ToLocalTime(); + } + } + else + { + if (DateTime.TryParseExact(sdate, "yyyyMMdd\\tHHmms", + CultureInfo.InvariantCulture, DateTimeStyles.None, out date) == false) + { + ReportError(entry, "Invalid DateTime value specified"); + } + } + + return (date); + } + + #endregion + + #region ProcessDateValue + + /// + /// Processes Value=Date entries + /// + /// + /// + /// + private DateTime ProcessDateValue(CalendarEntry entry, string sDate) + { + DateTime date; + + if (DateTime.TryParseExact(sDate, "yyyyMMdd", + CultureInfo.InvariantCulture, DateTimeStyles.None, out date) == false) + { + ReportError(entry, "Invalid Date Value specified"); + } + + return (date); + } + + #endregion + + #region ProcessTzIdDateTime + + #region ProcessTzIdDateTime + + /// + /// Processes TxId attribute DateTime values + /// + /// + /// + /// + /// + private DateTime ProcessTzIdDateTime(string tzId, CalendarEntry entry, string sdate) + { + sdate = sdate.ToLower(); + + DateTime date = ProcessDateTime(entry, sdate); + + if (sdate.EndsWith("z")) + return (date); + + date = date.ToLocalTime(); + + TimeSpan ts = GetTzIdDelta(tzId, date); + + return (date.Add(ts)); + } + + #endregion + + #region GetTzIdDelta + + /// + /// GetTzIdDelta + /// + /// + /// + /// + private TimeSpan GetTzIdDelta(string tzId, DateTime date) + { + CalendarTimeZone zone = GetTimeZone(tzId); + + if (zone != null && zone.Part != null) + { + TimeZonePart tzPart = null; + TimeSpan tzSpan = TimeSpan.MaxValue; + + foreach (TimeZonePart part in zone.Part) + { + if (part.RecurRule != null) + { + DateTime pdate = GetLastPartDate(part, date); + + TimeSpan span = date - pdate; + + if (span >= TimeSpan.Zero && span < tzSpan) + { + tzSpan = span; + tzPart = part; + } + } + } + + if (tzPart != null) + return (new TimeSpan(0, -tzPart.OffsetTo, 0)); + } + + return (TimeSpan.Zero); + } + + #endregion + + #region GetLastPartDate + + /// + /// GetLastPartDate + /// + /// + /// + /// + private DateTime GetLastPartDate(TimeZonePart part, DateTime date) + { + DateTime pdate = part.StartDate; + + if (part.Appc == null) + { + CalendarModel model = new CalendarModel(); + Appointment app = new Appointment(); + + app.StartTime = part.StartDate.Date; + app.EndTime = app.StartTime; + + VEventData evData = new VEventData(); + + evData.RecurRule = part.RecurRule; + + ProcessEventEndEx(model, null, app, evData); + + part.Appc = new AppointmentSubsetCollection(model, part.StartDate, date); + } + + if (part.Appc.Count > 0) + { + foreach (Appointment app in part.Appc) + { + if (app.StartTime > pdate && app.StartTime <= date) + pdate = app.StartTime; + } + } + + return (pdate); + } + + #endregion + + #region GetTimeZone + + /// + /// GetTimeZone + /// + /// + /// + private CalendarTimeZone GetTimeZone(string tzId) + { + if (_CalendarTimeZone != null) + { + foreach (CalendarTimeZone zone in _CalendarTimeZone) + { + if (zone.TzId.Equals(tzId) == true) + return (zone); + } + } + + return (null); + } + + #endregion + + #endregion + + #endregion + + #region ProcessDescription + + /// + /// Processes event Description values + /// + /// + /// + /// + private string ProcessDescription(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.Description; + + return (entry.Value); + } + + #endregion + + #region ProcessDuration + + /// + /// Processes event Duration values + /// + /// + /// + /// + private TimeSpan ProcessDuration(CalendarEntry entry, string value) + { + const string s = "^(?[+-]+)*"; + const string d = "P((?\\d+)D)*"; + const string t = "(T((?\\d+)H)*((?\\d+)M)*((?\\d+)S)*)*"; + const string w = "((?\\d+)W)*"; + + Regex p = new Regex(s + d + t + w); + Match ma = p.Match(value); + + if (ma.Success == true) + { + int sign = ma.Groups["sign"].Value.Equals("-") ? -1 : 1; + + int days = GetGroupIntValue(ma, "days", sign); + int hours = GetGroupIntValue(ma, "hours", sign); + int minutes = GetGroupIntValue(ma, "minutes", sign); + int seconds = GetGroupIntValue(ma, "seconds", sign); + int weeks = GetGroupIntValue(ma, "weeks", sign); + + return (new TimeSpan(weeks * 7 + days, hours, minutes, seconds)); + } + + ReportError(entry, "Invalid DURATION specified"); + + return (TimeSpan.Zero); + } + + #region GetGroupIntValue + + /// + /// Gets the int value from the given Regex Match + /// + /// + /// + /// + /// + private int GetGroupIntValue(Match ma, string group, int sign) + { + string s = ma.Groups[group].Value; + + return (string.IsNullOrEmpty(s) ? 0 : int.Parse(s) * sign); + } + + #endregion + + #endregion + + #region ProcessExDate + + /// + /// Processes event ExDate values + /// + /// + /// + private void ProcessExDate(CalendarEntry entry, VEventData evData) + { + List exDates = null; + + if (entry.Attributes.Count > 0) + { + foreach (AttributeData attr in entry.Attributes) + { + ParameterToken tkn = (ParameterToken) GetToken(_parameters, attr.Id); + + switch (tkn) + { + case ParameterToken.TzId: + if (exDates != null) + ReportError(entry, "Multiple EXDATE parameter types"); + + exDates = ProcessTzIdExDateTimeValues(attr.Value, entry, entry.Value); + break; + + case ParameterToken.Value: + if (exDates != null) + ReportError(entry, "Multiple EXDATE parameter types"); + + switch ((ValueToken)GetToken(_values, attr.Value)) + { + case ValueToken.Date: + exDates = ProcessExDateValues(entry); + break; + + case ValueToken.DateTime: + exDates = ProcessExDateTimeValues(entry, entry.Value); + break; + + default: + ReportError(entry, "Unrecognized ExDate attribute Value (" + + attr.Id + "=" + attr.Value + ")"); + + break; + } + break; + } + } + } + + if (exDates == null) + exDates = ProcessExDateTimeValues(entry, entry.Value); + + UnionExDates(evData, exDates); + } + + #region ProcessExDateValues + + /// + /// Processes ExDate Value=Date values + /// + /// + /// + private List ProcessExDateValues(CalendarEntry entry) + { + string[] dates = entry.Value.Split(','); + + if (dates.Length > 0) + { + List exDates = new List(dates.Length); + + for (int i = 0; i < dates.Length; i++) + exDates.Add(ProcessDateValue(entry, dates[i])); + + return (exDates); + } + + return (null); + } + + #endregion + + #region ProcessExDateTimeValues + + /// + /// Processes ExDate Value=DateTime values + /// + /// + /// + /// + private List ProcessExDateTimeValues(CalendarEntry entry, string value) + { + string[] dates = value.Split(','); + + if (dates.Length > 0) + { + List exDates = new List(dates.Length); + + for (int i = 0; i < dates.Length; i++) + exDates.Add(ProcessDateTime(entry, dates[i])); + + return (exDates); + } + + return (null); + } + + #endregion + + #region ProcessTzIdExDateTimeValues + + /// + /// Processes ExDate Value=DateTime values + /// + /// + /// + /// + /// + private List ProcessTzIdExDateTimeValues(string tzId, CalendarEntry entry, string value) + { + string[] dates = value.Split(','); + + if (dates.Length > 0) + { + List exDates = new List(dates.Length); + + for (int i = 0; i < dates.Length; i++) + exDates.Add(ProcessTzIdDateTime(tzId, entry, dates[i])); + + return (exDates); + } + + return (null); + } + + #endregion + + #region UnionExDates + + /// + /// Combines the main evData exDates list with a secondary + /// accumulated exDates list + /// + /// + /// + private void UnionExDates(VEventData evData, List exDates) + { + if (evData.ExDates == null) + { + evData.ExDates = exDates; + } + else if (exDates != null) + { + foreach (DateTime date in exDates) + { + if (evData.ExDates.Contains(date) == false) + evData.ExDates.Add(date); + } + } + } + + #endregion + + #endregion + + #region ProcessRDate + + #region ProcessRDate + + /// + /// Processes RDate attributes and values + /// + /// + /// + /// + private RDate ProcessRDate(CalendarEntry entry, RDate rdateOld) + { + RDate rdateNew = null; + + if (entry.Attributes.Count > 0) + { + foreach (AttributeData attr in entry.Attributes) + { + ParameterToken tkn = (ParameterToken)GetToken(_parameters, attr.Id); + + switch (tkn) + { + case ParameterToken.TzId: + if (rdateNew != null) + ReportError(entry, "Multiple RDATE parameter types"); + + rdateNew = ProcessTzIdRDateTimeValues(attr.Value, entry, entry.Value); + break; + + case ParameterToken.Value: + if (rdateNew != null) + ReportError(entry, "Multiple RDATE parameter types"); + + switch ((ValueToken)GetToken(_values, attr.Value)) + { + case ValueToken.Date: + rdateNew = ProcessRDateValues(entry); + break; + + case ValueToken.DateTime: + rdateNew = ProcessRDateTimeValues(entry, entry.Value); + break; + + case ValueToken.Period: + rdateNew = ProcessRDatePeriod(entry); + break; + + default: + ReportError(entry, "Unrecognized RDate attribute Value (" + + attr.Id + "=" + attr.Value + ")"); + + break; + } + break; + } + } + } + + if (rdateNew == null) + rdateNew = ProcessRDateTimeValues(entry, entry.Value); + + return (UnionRDates(rdateOld, rdateNew)); + } + + #endregion + + #region ProcessRDateValues + + /// + /// Processes RDate Value=Date values + /// + /// + /// + private RDate ProcessRDateValues(CalendarEntry entry) + { + string[] dates = entry.Value.Split(','); + + if (dates.Length > 0) + { + RDate rdate = new RDate(); + + rdate.DtRange = new DateRange[dates.Length]; + + for (int i = 0; i < dates.Length; i++) + rdate.DtRange[i].StartTime = ProcessDateValue(entry, dates[i]); + + return (rdate); + } + + return (null); + } + + #endregion + + #region ProcessRDateTimeValues + + /// + /// Processes RDate Value=DateTime values + /// + /// + /// + /// + private RDate ProcessRDateTimeValues(CalendarEntry entry, string value) + { + string[] dates = value.Split(','); + + if (dates.Length > 0) + { + RDate rdate = new RDate(); + + rdate.DtRange = new DateRange[dates.Length]; + + for (int i = 0; i < dates.Length; i++) + rdate.DtRange[i].StartTime = ProcessDateTime(entry, dates[i]); + + return (rdate); + } + + return (null); + } + + #endregion + + #region ProcessTzIdRDateTimeValues + + /// + /// Processes RDate Value=DateTime values + /// + /// + /// + /// + /// + private RDate ProcessTzIdRDateTimeValues(string tzId, CalendarEntry entry, string value) + { + string[] dates = value.Split(','); + + if (dates.Length > 0) + { + RDate rdate = new RDate(); + + rdate.DtRange = new DateRange[dates.Length]; + + for (int i = 0; i < dates.Length; i++) + rdate.DtRange[i].StartTime = ProcessTzIdDateTime(tzId, entry, dates[i]); + + return (rdate); + } + + return (null); + } + + #endregion + + #region ProcessRDatePeriod + + /// + /// Processes RDate Value=Period values + /// + /// + /// + private RDate ProcessRDatePeriod(CalendarEntry entry) + { + string[] dates = entry.Value.Split(','); + + if (dates.Length > 0) + { + RDate rdate = new RDate(); + + rdate.DtRange = new DateRange[dates.Length]; + + for (int i = 0; i < dates.Length; i++) + { + string[] parts = dates[i].Split('/'); + + if (parts.Length != 2) + { + ReportError(entry, "RDATE PERIOD not formed correctly"); + break; + } + + rdate.DtRange[i] = new DateRange(); + rdate.DtRange[i].StartTime = ProcessDateTime(entry, parts[0]); + + parts[1] = parts[1].TrimStart(' '); + + if (parts[1].StartsWith("P") == true) + { + TimeSpan duration = ProcessDuration(entry, parts[1]); + + rdate.DtRange[i].EndTime = + rdate.DtRange[i].StartTime.Add(duration); + } + else + { + rdate.DtRange[i].EndTime = ProcessDateTime(entry, parts[1]); + } + } + + return (rdate); + } + + return (null); + } + + #endregion + + #region UnionRDates + + /// + /// Combines RDate values + /// + /// + /// + /// + private RDate UnionRDates(RDate rdateOld, RDate rdateNew) + { + if (rdateNew != null) + { + if (rdateOld != null) + { + DateRange[] range = new + DateRange[rdateOld.DtRange.Length + rdateNew.DtRange.Length]; + + Array.Copy(rdateOld.DtRange, range, rdateOld.DtRange.Length); + Array.Copy(rdateNew.DtRange, 0, range, rdateOld.DtRange.Length, rdateNew.DtRange.Length); + + rdateNew.DtRange = range; + } + + return (rdateNew); + } + + return (rdateOld); + } + + #endregion + + #endregion + + #region ProcessRecurrenceId + + /// + /// Processes RecurrenceId entries + /// + /// + /// + private DateTime ProcessRecurrenceId(CalendarEntry entry) + { + bool isDateValue = true; + + return (ProcessDate(entry, ref isDateValue)); + } + + #endregion + + #region ProcessRRule + + #region ProcessRRule + + /// + /// Processes RRule entries + /// + /// + /// + private RRule ProcessRRule(CalendarEntry entry) + { + RRule rrule = new RRule(); + List attributes = new List(); + + string s = ";" + entry.Value; + + ParseAttributeData(attributes, ref s); + + foreach (AttributeData attr in attributes) + { + ValueToken tkn = (ValueToken)GetToken(_values, attr.Id); + + switch (tkn) + { + case ValueToken.ByDay: + ProcessByDay(entry, rrule, attr.Value); + break; + + case ValueToken.ByMonth: + rrule.ByMonth = ProcessByIntValues(entry, attr.Value, 1, 12, tkn); + break; + + case ValueToken.ByMonthDay: + rrule.ByMonthDay = ProcessByIntValues(entry, attr.Value, 1, 31, tkn); + break; + + case ValueToken.Count: + ProcessCount(entry, rrule, attr); + break; + + case ValueToken.Freq: + ProcessFreq(entry, rrule, attr); + break; + + case ValueToken.Interval: + ProcessInterval(entry, rrule, attr); + break; + + case ValueToken.Until: + ProcessUntil(entry, rrule, attr); + break; + + case ValueToken.BySetPos: + ProcessBySetPos(entry, rrule, attr); + break; + + case ValueToken.BySecond: + case ValueToken.ByMinute: + case ValueToken.ByHour: + case ValueToken.ByYearDay: + case ValueToken.ByWeekNo: + case ValueToken.WkSt: + break; + + default: + ReportError(entry, "Unrecognized RRULE Value - " + attr.Id); + break; + } + } + + return (rrule); + } + + #endregion + + #region ProcessByDay + + /// + /// Processes ByDay= attribute entries + /// + /// + /// + /// + private void ProcessByDay(CalendarEntry entry, RRule rrule, string value) + { + rrule.ByDays = eDayOfWeekRecurrence.None; + + Regex p = new Regex("(?[+-]{0,1}\\d+)*(?\\w+)"); + MatchCollection mc = p.Matches(value); + + if (mc.Count > 0) + { + rrule.ByDay = new List[7]; + + foreach (Match ma in mc) + { + int dayOfWeek; + eDayOfWeekRecurrence weekDay = ProcessWeekDay(entry, ma.Groups["weekDay"].Value, out dayOfWeek); + + rrule.ByDays |= weekDay; + + string s = ma.Groups["dayNum"].Value; + + int n = 0; + + if (String.IsNullOrEmpty(s) == false) + { + n = int.Parse(s); + + if (Math.Abs(n) > 53) + { + ReportError(entry, + String.Format("BYDAY value ({0}) is not in the range +/- 1 to 53", n)); + + n = 0; + } + } + + if (rrule.ByDay[dayOfWeek] == null) + rrule.ByDay[dayOfWeek] = new List(); + + rrule.ByDay[dayOfWeek].Add(n); + } + } + } + + #region ProcessWeekDay + + /// + /// Processes individual ByDay.WeekDay entries + /// + /// + /// + /// + /// + private eDayOfWeekRecurrence ProcessWeekDay( + CalendarEntry entry, string s, out int dayOfWeek) + { + ValueToken tkn = (ValueToken)GetToken(_values, s); + + switch (tkn) + { + case ValueToken.Mo: + dayOfWeek = 0; + return (eDayOfWeekRecurrence.Monday); + + case ValueToken.Tu: + dayOfWeek = 1; + return (eDayOfWeekRecurrence.Tuesday); + + case ValueToken.We: + dayOfWeek = 2; + return (eDayOfWeekRecurrence.Wednesday); + + case ValueToken.Th: + dayOfWeek = 3; + return (eDayOfWeekRecurrence.Thursday); + + case ValueToken.Fr: + dayOfWeek = 4; + return (eDayOfWeekRecurrence.Friday); + + case ValueToken.Sa: + dayOfWeek = 5; + return (eDayOfWeekRecurrence.Saturday); + + case ValueToken.Su: + dayOfWeek = 6; + return (eDayOfWeekRecurrence.Sunday); + + default: + dayOfWeek = 0; + ReportError(entry, "Unrecognized WeekDay - " + s); + return (eDayOfWeekRecurrence.None); + } + } + + #endregion + + #endregion + + #region ProcessByIntValues + + /// + /// Processes ByMonth= and ByMonthDay= attribute entries + /// + /// + /// + /// + /// + /// + /// + private int[] ProcessByIntValues(CalendarEntry entry, + string value, int minValue, int maxValue, ValueToken tkn) + { + string[] byValues = value.Split(','); + + if (byValues.Length > 0) + { + int[] byIntValues = new int[byValues.Length]; + + for (int i = 0; i < byValues.Length; i++) + { + int n; + + if (int.TryParse(byValues[i], out n) == false) + { + ReportError(entry, String.Format("\"{0}\" is not a valid Integer value", byValues[i])); + + n = minValue; + } + else + { + int absn = Math.Abs(n); + + if (absn < minValue || absn > maxValue) + { + ReportError(entry, String.Format( + "{0} value ({1}) is not in the range +/- {2} to {3}", + n, _values[(int) tkn].Text.ToUpper(), minValue, maxValue)); + + break; + } + } + + byIntValues[i] = n; + } + + return (byIntValues); + } + + return (null); + } + + #endregion + + #region ProcessBySetPos + + private void ProcessBySetPos(CalendarEntry entry, RRule rrule, AttributeData attr) + { + int n; + + if (int.TryParse(attr.Value, out n) == false) + { + n = 1; + ReportError(entry, String.Format("\"{0}\" is not a valid INTERVAL value", attr.Value)); + } + + rrule.BySetPos = n; + } + + #endregion + + #region ProcessCount + + /// + /// Processes RRule Count attribute entries + /// + /// + /// + /// + private void ProcessCount(CalendarEntry entry, RRule rrule, AttributeData attr) + { + int n; + + if (int.TryParse(attr.Value, out n) == false) + { + n = 1; + ReportError(entry, String.Format("\"{0}\" is not a valid COUNT value", attr.Value)); + } + + rrule.Count = n; + } + + #endregion + + #region ProcessFreq + + /// + /// Processes Freq= attribute entries + /// + /// + /// + /// + private void ProcessFreq(CalendarEntry entry, RRule rrule, AttributeData attr) + { + ValueToken tkn = (ValueToken)GetToken(_values, attr.Value); + + switch (tkn) + { + case ValueToken.Secondly: + rrule.Freq = Frequency.Secondly; + break; + + case ValueToken.Minutely: + rrule.Freq = Frequency.Minutely; + break; + + case ValueToken.Hourly: + rrule.Freq = Frequency.Hourly; + break; + + case ValueToken.Daily: + rrule.Freq = Frequency.Daily; + break; + + case ValueToken.Weekly: + rrule.Freq = Frequency.Weekly; + break; + + case ValueToken.Monthly: + rrule.Freq = Frequency.Monthly; + break; + + case ValueToken.Yearly: + rrule.Freq = Frequency.Yearly; + break; + + default: + ReportError(entry, "Invalid FREQ value"); + rrule.Freq = Frequency.Daily; + break; + } + } + + #endregion + + #region ProcessInterval + + /// + /// Processes Interval= attribute entries + /// + /// + /// + /// + private void ProcessInterval(CalendarEntry entry, RRule rrule, AttributeData attr) + { + int n; + + if (int.TryParse(attr.Value, out n) == false) + { + n = 1; + ReportError(entry, String.Format("\"{0}\" is not a valid INTERVAL value", attr.Value)); + } + + rrule.Interval = n; + } + + #endregion + + #region ProcessUntil + + /// + /// Processes Until= attribute entries + /// + /// + /// + /// + private void ProcessUntil(CalendarEntry entry, RRule rrule, AttributeData attr) + { + rrule.Until = (attr.Value.Length > 8) + ? ProcessDateTime(entry, attr.Value) + : ProcessDateValue(entry, attr.Value); + } + + #endregion + + #endregion + + #region ProcessSummary + + /// + /// Processes Summary entries + /// + /// + /// + /// + private string ProcessSummary(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.Summary; + + return (entry.Value); + } + + #endregion + + #region ProcessUid + + /// + /// Processes UID entries + /// + /// + /// + /// + private List ProcessUid(CalendarEntry entry, Appointment app) + { + List uidApp; + + if (_Uid.TryGetValue(entry.Value, out uidApp) == false) + { + uidApp = new List(); + uidApp.Add(app); + + _Uid.Add(entry.Value, uidApp); + } + + return (uidApp); + } + + #endregion + + #region ProcessVAlarm + + /// + /// Processes VAlarm component entries + /// + /// + private void ProcessVAlarm(VEventData evData) + { + VAlarm valarm = new VAlarm(); + + CalendarEntry entry = GetNextEntry(); + + while (entry != null) + { + PropertyToken tkn = (PropertyToken)GetToken(_properties, entry.Id); + + switch (tkn) + { + case PropertyToken.Description: + valarm.Description = entry.Value; + break; + + case PropertyToken.End: + if ((ComponentToken)GetToken(_components, entry.Value) != ComponentToken.VAlarm) + ReportError(entry, "Expected \"END:VALARM\""); + + if (evData.VAlarms == null) + evData.VAlarms = new List(); + + evData.VAlarms.Add(valarm); + return; + + case PropertyToken.Trigger: + ProcessTrigger(entry, valarm); + break; + } + + entry = GetNextEntry(); + } + + ReportError(entry, "Expected \"END:VALARM\""); + } + + #region ProcessTrigger + + /// + /// Processes VAlarm Trigger properties + /// + /// + /// + private void ProcessTrigger(CalendarEntry entry, VAlarm valarm) + { + if (entry.Attributes.Count > 0) + { + foreach (AttributeData attr in entry.Attributes) + { + ParameterToken tkn = (ParameterToken)GetToken(_parameters, attr.Id); + + switch (tkn) + { + case ParameterToken.Related: + valarm.Rel = ProcessRelated(entry, attr.Value); + break; + + case ParameterToken.Value: + switch ((ValueToken)GetToken(_values, attr.Value)) + { + case ValueToken.Date: + valarm.Rel = Related.Date; + valarm.Date = ProcessDateValue(entry, entry.Value); + break; + + case ValueToken.DateTime: + valarm.Rel = Related.Date; + valarm.Date = ProcessDateTime(entry, entry.Value); + break; + + case ValueToken.Duration: + valarm.Duration = ProcessDuration(entry, entry.Value); + break; + } + break; + } + } + } + else + { + valarm.Duration = ProcessDuration(entry, entry.Value); + } + } + + #region ProcessRelated + + private Related ProcessRelated(CalendarEntry entry, string value) + { + ValueToken rtkn = (ValueToken)GetToken(_values, value); + + switch (rtkn) + { + case ValueToken.Start: + return (Related.Start); + + case ValueToken.End: + return (Related.End); + + default: + ReportError(entry, "Invalid RELATED value: " + value.ToUpper()); + return (Related.Date); + } + } + + #endregion + + #endregion + + #endregion + + #region Process DNB specific + + #region ProcessXDnbCategoryColor + + /// + /// Processes DNB CategoryColor entries + /// + /// + /// + /// + private string ProcessXDnbCategoryColor(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.XDnbCategoryColor; + + return(entry.Value); + } + + #endregion + + #region ProcessXDnbDisplayTemplate + + /// + /// Processes DNB DisplayTemplate entries + /// + /// + /// + /// + private string ProcessXDnbDisplayTemplate(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.XDnbDisplayTemplate; + + return (entry.Value); + } + + #endregion + + #region ProcessXDnbImageAlign + + /// + /// Processes DNB specific ImageAlign entries + /// + /// + /// + /// + private eImageContentAlignment ProcessXDnbImageAlign(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.XDnbImageAlign; + + return ((eImageContentAlignment) + GetEnumValue(typeof(eImageContentAlignment), entry.Value)); + } + + #endregion + + #region ProcessXDnbImageKey + + /// + /// Processes DNB ImageKey entries + /// + /// + /// + /// + private string ProcessXDnbImageKey(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.XDnbImageKey; + + return (entry.Value); + } + + #endregion + + #region ProcessXDnbLocked + + /// + /// Processes DNB Locked entries + /// + /// + /// + /// + private bool ProcessXDnbLocked(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.XDnbLocked; + + return (entry.Value.ToLower().Equals("true")); + } + + #endregion + + #region ProcessXDnbRecStartDate + + /// + /// Processes DNB RecStartDate entries + /// + /// + /// + private DateTime ProcessXDnbRecStartDate(CalendarEntry entry) + { + return (ProcessDateTime(entry, entry.Value)); + } + + #endregion + + #region ProcessXDnbStartTimeAction + + /// + /// Processes DNB StartTimeAction entries + /// + /// + /// + /// + private eStartTimeAction ProcessXDnbStartTimeAction(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.XDnbStartTimeAction; + + return ((eStartTimeAction) + GetEnumValue(typeof(eStartTimeAction), entry.Value)); + } + + #endregion + + #region ProcessXDnbTimeMarkedAs + + /// + /// Processes DNB TimeMarkedAs entries + /// + /// + /// + /// + private string ProcessXDnbTimeMarkedAs(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.XDnbTimeMarkedAs; + + return (entry.Value); + } + + #endregion + + #region ProcessXDnbTooltip + + /// + /// Processes DNB ToolTip entries + /// + /// + /// + /// + private string ProcessXDnbTooltip(CalendarEntry entry, VEventData evData) + { + evData.AppPropSet |= AppProp.XDnbTooltip; + + return (entry.Value); + } + + #endregion + + #endregion + + #endregion + + #region ProcessVTimezone + + #region ProcessVTimezone + + /// + /// Processes VTimeZone components + /// + private void ProcessVTimezone() + { + CalendarTimeZone zone = new CalendarTimeZone(); + + CalendarEntry entry = GetNextEntry(); + + while (entry != null) + { + PropertyToken tkn = (PropertyToken)GetToken(_properties, entry.Id); + + switch (tkn) + { + case PropertyToken.Begin: + ComponentToken ctkn = (ComponentToken) GetToken(_components, entry.Value); + + switch (ctkn) + { + case ComponentToken.Daylight: + case ComponentToken.Standard: + ProcessZonePart(zone, ctkn); + break; + } + break; + + case PropertyToken.End: + ProcessVTimezoneEnd(entry, zone); + return; + + case PropertyToken.TzId: + zone.TzId = ProcessTzId(entry); + break; + } + + entry = GetNextEntry(); + } + + ReportError(entry, "Expected \"END:VTIMEZONE\""); + } + + #endregion + + #region ProcessTzId + + /// + /// Processes TxId values + /// + /// + /// + private string ProcessTzId(CalendarEntry entry) + { + return (entry.Value); + } + + #endregion + + #region ProcessTzOffset + + /// + /// Processes TzOffset values + /// + /// + /// + private int ProcessTzOffset(CalendarEntry entry) + { + const string s = "^(?[+-]+)*"; + const string t = "((?\\d{2})(?\\d{2})*)*"; + + Regex p = new Regex(s + t); + Match ma = p.Match(entry.Value); + + if (ma.Success == true) + { + int sign = ma.Groups["sign"].Value.Equals("-") ? -1 : 1; + + int hours = GetGroupIntValue(ma, "hours", sign); + int minutes = GetGroupIntValue(ma, "minutes", sign); + + return (hours * 60 + minutes); + } + + ReportError(entry, "Invalid TZOFFSET"); + + return (0); + } + + #endregion + + #region ProcessVTimezoneEnd + + /// + /// ProcessVTimezoneEnd + /// + /// + /// + private void ProcessVTimezoneEnd(CalendarEntry entry, CalendarTimeZone zone) + { + if ((ComponentToken)GetToken(_components, entry.Value) != ComponentToken.VTimezone) + ReportError(entry, "Expected \"END:VTIMEZONE\""); + + if (_CalendarTimeZone == null) + _CalendarTimeZone = new List(); + + _CalendarTimeZone.Add(zone); + } + + #endregion + + #region ProcessZonePart + + /// + /// Processes VTimeZone parts (DayLight, Standard) + /// + /// + /// + private void ProcessZonePart(CalendarTimeZone zone, ComponentToken tkn) + { + bool isDtStartValue = false; + + TimeZonePart part = new TimeZonePart(); + + CalendarEntry entry = GetNextEntry(); + + while (entry != null) + { + switch ((PropertyToken) GetToken(_properties, entry.Id)) + { + case PropertyToken.DtStart: + part.StartDate = ProcessDate(entry, ref isDtStartValue); + break; + + case PropertyToken.RDate: + part.RecurDate = ProcessRDate(entry, part.RecurDate); + break; + + case PropertyToken.RRule: + part.RecurRule = ProcessRRule(entry); + break; + + case PropertyToken.TzOffsetTo: + part.OffsetTo = ProcessTzOffset(entry); + break; + + case PropertyToken.End: + ProcessZonePartEnd(entry, zone, part, tkn); + return; + } + + entry = GetNextEntry(); + } + + ReportError(entry, "Expected \"END:" + _components[(int)tkn].Text.ToUpper() + "\""); + } + + private void ProcessZonePartEnd(CalendarEntry entry, + CalendarTimeZone zone, TimeZonePart part, ComponentToken tkn) + { + if ((ComponentToken)GetToken(_components, entry.Value) != tkn) + ReportError(entry, "Expected \"END:" + _components[(int)tkn].Text.ToUpper() + "\""); + + if (zone.Part == null) + zone.Part = new List(); + + zone.Part.Add(part); + } + + #endregion + + #endregion + + #region ProcessVTodo + + /// + /// Processes VToDo entries + /// + /// + private void ProcessVTodo(string ownerKey) + { + Appointment app = new Appointment(); + app.OwnerKey = ownerKey; + + VEventData evData = new VEventData(); + + CalendarEntry entry = GetNextEntry(); + + while (entry != null) + { + PropertyToken tkn = (PropertyToken)GetToken(_properties, entry.Id); + + switch (tkn) + { + case PropertyToken.Begin: + ComponentToken ctkn = (ComponentToken)GetToken(_components, entry.Value); + + switch (ctkn) + { + case ComponentToken.VAlarm: + ProcessVAlarm(evData); + break; + + default: + ReportError(entry, "Unexpected \"BEGIN:" + entry.Value.ToUpper() + "\""); + SkipComponent(ctkn); + break; + } + break; + + case PropertyToken.Description: + app.Description = entry.Value; + break; + + case PropertyToken.DtEnd: + case PropertyToken.Due: + app.EndTime = ProcessDate(entry, ref evData.IsDtEndValue); + break; + + case PropertyToken.DtStart: + app.StartTime = ProcessDate(entry, ref evData.IsDtStartValue); + break; + + case PropertyToken.Duration: + evData.Duration = ProcessDuration(entry, entry.Value); + break; + + case PropertyToken.End: + if ((ComponentToken)GetToken(_components, entry.Value) != ComponentToken.VTodo) + ReportError(entry, "Expected \"END:VTODO\""); + + ProcessVEventEnd(entry, app, evData); + return; + + case PropertyToken.RDate: + evData.RecurDate = ProcessRDate(entry, evData.RecurDate); + break; + + case PropertyToken.RRule: + evData.RecurRule = ProcessRRule(entry); + break; + + case PropertyToken.Summary: + app.Subject = entry.Value; + break; + } + + entry = GetNextEntry(); + } + + ReportError(entry, "Expected \"END:VTODO\""); + } + + #endregion + + #region ProcessWrCalName + + /// + /// Processes X-WR-CALNAME entries + /// + /// + /// + private string ProcessWrCalName(CalendarEntry entry) + { + if (entry.Attributes.Count > 0) + { + foreach (AttributeData attr in entry.Attributes) + { + ParameterToken tkn = (ParameterToken)GetToken(_parameters, attr.Id); + + if (tkn == ParameterToken.Value) + return (entry.Value); + } + } + + return (null); + } + + #endregion + + #endregion + + #region SkipComponent + + /// + /// Skips the given component block (until it reaches + /// the corresponding ctkn:END value) + /// + /// + private void SkipComponent(ComponentToken ctkn) + { + int level = 1; + + CalendarEntry entry = GetNextEntry(); + + while (entry != null) + { + PropertyToken tkn = (PropertyToken) GetToken(_properties, entry.Id); + + switch (tkn) + { + case PropertyToken.Begin: + level++; + break; + + case PropertyToken.End: + level--; + + if (level == 0) + { + if ((ComponentToken) GetToken(_components, entry.Value) != ctkn) + { + ReportError(entry, "Expected \"END:" + + Enum.GetName(typeof(ComponentToken), ctkn).ToUpper() + "\""); + } + return; + } + break; + } + + entry = GetNextEntry(); + } + + ReportError(entry, "Expected \"END:" + + Enum.GetName(typeof(ComponentToken), ctkn).ToUpper() + "\""); + } + + #endregion + + #region Token processing + + #region GetToken + + /// + /// Gets the token associated with the given text + /// + /// Token registry + /// Token text + /// Token, or -1 if not found + private int GetToken(TokenRegistry[] reg, string text) + { + int index = Array.BinarySearch(reg, text.ToLower()); + + if (index >= 0) + return (reg[index].Token); + + return (-1); + } + + #endregion + + #region GetFirstEntry + + /// + /// Gets the first CalendarEntry + /// + /// + private CalendarEntry GetFirstEntry() + { + _EntryIndex = 0; + + return (GetNextEntry()); + } + + #endregion + + #region GetNextEntry + + /// + /// Gets the next CalendarEntry + /// + /// + private CalendarEntry GetNextEntry() + { + if (_EntryIndex >= _CalendarEntries.Count) + return (null); + + return (_CalendarEntries[_EntryIndex++]); + } + + #endregion + + #region GetEnumValue + + /// + /// Gets the enum value, given the token type and text + /// + /// + /// + /// + public int GetEnumValue(Type type, string name) + { + return ((int)Enum.Parse(type, name)); + } + + #endregion + + #endregion + + #region Parse support + + #region Parse + + /// + /// Initiates the parsing of the given import file + /// + /// + private void Parse(StreamReader streamReader) + { + int lineStart = 1; + int lineEnd = 1; + + string s = GetNextLine(streamReader, ref lineStart, ref lineEnd); + + while (s != null) + { + ParseLine(s, lineStart, lineEnd); + + s = GetNextLine(streamReader, ref lineStart, ref lineEnd); + } + } + + #endregion + + #region GetNextLine + + /// + /// Gets the next logical line of text + /// + /// + /// + /// + /// + private string GetNextLine( + StreamReader sr, ref int lineStart, ref int lineEnd) + { + string s = null; + + if (sr.EndOfStream == false) + { + s = sr.ReadLine(); + + lineStart = lineEnd; + lineEnd++; + + while (sr.EndOfStream == false) + { + if (Char.IsWhiteSpace((char)sr.Peek()) == false) + break; + + string t = sr.ReadLine(); + + if (t.Length > 0) + s += t.Substring(1); + + lineEnd++; + } + } + + return (s); + } + + #endregion + + #region ParseLine + + /// + /// Initiates the syntactic parsing of the given line + /// + /// + /// + /// + private void ParseLine(string s, int lineStart, int lineEnd) + { + if (IsBlankLine(s) == false) + { + CalendarEntry entry = new CalendarEntry(lineStart, lineEnd); + + if (ParseId(entry, ref s) == true) + { + ParseAttributes(entry, ref s); + ParseValue(entry, ref s); + + _CalendarEntries.Add(entry); + } + } + } + + #region IsBlankLine + + /// + /// Determines if the given line is blank + /// + /// + /// + private bool IsBlankLine(IEnumerable s) + { + foreach (char c in s) + { + if (Char.IsWhiteSpace(c) == false) + return (false); + } + + return (true); + } + + #endregion + + #endregion + + #region ParseId + + /// + /// Parses the Id portion of the given line + /// + /// + /// + /// + private bool ParseId(CalendarEntry entry, ref string s) + { + Regex p = new Regex("^[^;:]+\\s*"); + Match ma = p.Match(s); + + if (ma.Success == false) + { + ReportError(entry, "Expected ID:"); + return (false); + } + + entry.Id = ma.Value; + + s = s.Substring(ma.Index + ma.Length); + + return (true); + } + + #endregion + + #region ParseAttributes + + #region ParseAttributes + + /// + /// Initiates the parsing of the line attributes + /// + /// + /// + private void ParseAttributes(CalendarEntry entry, ref string s) + { + if (s.StartsWith(";") == true) + ParseAttributeData(entry.Attributes, ref s); + } + + #endregion + + #region ParseAttributeData + + /// + /// Parses line attribute data + /// + /// + /// + private void ParseAttributeData(List list, ref string s) + { + Regex p = new Regex("\\s*;\\s*(?\\w+)\\s*=\\s*((?\"[^\"]*\")|(?[^;:]+))"); + MatchCollection mc = p.Matches(s); + + if (mc.Count > 0) + { + for (int i = 0; i < mc.Count; i++) + { + AttributeData attr = new + AttributeData(mc[i].Groups["id"].Value, mc[i].Groups["value"].Value); + + list.Add(attr); + } + + s = s.Substring(mc[mc.Count - 1].Index + mc[mc.Count - 1].Length); + } + } + + #endregion + + #endregion + + #region ParseValue + + #region ParseValue + + /// + /// Parses the value portion of the given line + /// + /// + /// + private void ParseValue(CalendarEntry entry, ref string s) + { + Regex p = new Regex("^:\\s*((?\"[^\"]\")|(?.+))"); + Match ma = p.Match(s); + + if (ma.Success == true) + { + entry.Value = RemoveMetaData(ma.Groups["value"].Value); + + s = s.Substring(ma.Index + ma.Length); + } + } + + #endregion + + #region RemoveMetaData + + /// + /// Removes Meta data from the value text + /// + /// + /// + private string RemoveMetaData(string s) + { + Regex p = new Regex("\\\\[\\\\,;nN]"); + MatchCollection mc = p.Matches(s); + + if (mc.Count > 0) + { + StringBuilder sb = new StringBuilder(); + + int index = 0; + + foreach (Match ma in mc) + { + if (index < ma.Index) + sb.Append(s.Substring(index, ma.Index - index)); + + index = ma.Index + ma.Length; + + char c = ma.Value[1]; + + if (c == 'n' || c == 'N') + c = '\n'; + + sb.Append(c); + } + + if (index < s.Length) + sb.Append(s.Substring(index, s.Length - index)); + + return (sb.ToString()); + } + + return (s); + } + + #endregion + + #endregion + + #endregion + + #region GetRelativeDay + + /// + /// Gets the eRelativeDayInMonth from the given dayOfWeek + /// + /// + /// + protected virtual eRelativeDayInMonth GetRelativeDay(int dayOfWeek) + { + switch (dayOfWeek) + { + case 0: + return eRelativeDayInMonth.First; + + case 1: + case 2: + case 3: + case 4: + return ((eRelativeDayInMonth)dayOfWeek); + + default: + return (eRelativeDayInMonth.Last); + } + } + + #endregion + + #region GetRelativeDayOfWeek + + /// + /// Gets the DayOfWeek from the given eDayOfWeekRecurrence + /// + /// + /// + protected virtual DayOfWeek GetRelativeDayOfWeek(eDayOfWeekRecurrence byDays) + { + if ((byDays & eDayOfWeekRecurrence.Monday) != 0) + return (DayOfWeek.Monday); + + if ((byDays & eDayOfWeekRecurrence.Tuesday) != 0) + return (DayOfWeek.Tuesday); + + if ((byDays & eDayOfWeekRecurrence.Wednesday) != 0) + return (DayOfWeek.Wednesday); + + if ((byDays & eDayOfWeekRecurrence.Thursday) != 0) + return (DayOfWeek.Thursday); + + if ((byDays & eDayOfWeekRecurrence.Friday) != 0) + return (DayOfWeek.Friday); + + if ((byDays & eDayOfWeekRecurrence.Saturday) != 0) + return (DayOfWeek.Saturday); + + return (DayOfWeek.Sunday); + } + + #endregion + + #region IsValidCalName + + /// + /// Determines if the given Calendar (by it's name) is + /// a valid calendar to import + /// + /// + /// + protected virtual bool IsValidCalName(string calName) + { + if (_CalNames == null) + return (true); + + if (String.IsNullOrEmpty(calName) == true) + return (true); + + for (int i = 0; i < _CalNames.Length; i++) + { + string name = _CalNames[i]; + + if (string.IsNullOrEmpty(name) || name.Equals(calName)) + return (true); + } + + return (false); + } + + #endregion + + #region GetOwnerKey + + /// + /// Gets the OwnerKey based upon the + /// given Calendar name + /// + /// + /// + protected virtual string GetOwnerKey(string calName) + { + if (String.IsNullOrEmpty(calName) == true) + return (""); + + if (_CalNames != null && _OwnerKeys != null) + { + for (int i = 0; i < _CalNames.Length; i++) + { + string name = _CalNames[i]; + + if (string.IsNullOrEmpty(name) || name.Equals(calName)) + { + if (_OwnerKeys.Length > i) + return (_OwnerKeys[i] ?? ""); + + break; + } + } + } + + return (calName); + } + + #endregion + + #region ReportError + + /// + /// Reports encountered import errors + /// + /// + /// + private void ReportError(CalendarEntry entry, string text) + { + if (IgnoreErrors == false) + { + if (entry != null) + { + string s = String.Format("Error: {0}. \n{1}: Line {2}", + text, _ImportFile, entry.LineStart); + + if (entry.LineEnd - entry.LineStart > 1) + s += ("-" + (entry.LineEnd - 1)); + + throw new Exception(s); + } + else + { + string s = String.Format("Error: {0}. {1}:", text, _ImportFile); + + throw new Exception(s); + } + } + } + + #endregion + + #region Class defs + + #region CalendarTimeZone + + private class CalendarTimeZone + { + #region Public variables + + public string TzId; + public List Part; + + #endregion + } + + #endregion + + #region RDate + + #region RDate + + private class RDate + { + #region Public variables + + public DateRange[] DtRange; + + #endregion + } + + #endregion + + #region DateRange + + private class DateRange + { + #region Public variables + + public DateTime StartTime; + public DateTime EndTime; + + #endregion + } + + #endregion + + #endregion + + #region RRule + + private class RRule + { + #region Public variables + + public Frequency Freq; + public DateTime Until; + + public int Count; + public int Interval = 1; + public int BySetPos; + + public List[] ByDay; + + public int[] ByMonth; + public int[] ByMonthDay; + + public eDayOfWeekRecurrence ByDays; + + #endregion + } + + #endregion + + #region TimeZonePart + + private class TimeZonePart + { + #region Public variables + + public DateTime StartDate; + + public int OffsetTo; + + public RRule RecurRule; + public RDate RecurDate; + + public AppointmentSubsetCollection Appc; + + #endregion + } + + #endregion + + #region TokenRegistry + + private class TokenRegistry : IComparable + { + #region Public variables + + public int Token; + public string Text; + + #endregion + + public TokenRegistry(string text, int token) + { + Token = token; + Text = text; + } + + #region IComparable Members + + public int CompareTo(object obj) + { + string s = obj as string; + + return (s != null ? Text.CompareTo(s) : 0); + } + + #endregion + } + + #endregion + + #region VAlarm + + private class VAlarm + { + #region Public variables + + public DateTime Date; + public TimeSpan Duration; + public Related Rel = Related.Start; + public string Description; + + #endregion + } + + #endregion + + #region VEventData + + private class VEventData + { + #region Public variables + + public bool IsDtEndValue; + public bool IsDtStartValue; + + public RRule RecurRule; + public RDate RecurDate; + + public TimeSpan Duration; + public List VAlarms; + public List UidApps; + + public DateTime RecIdDate; + public DateTime RecStartDate; + + public AppProp AppPropSet; + + public List ExDates; + + public DateTime StartTime; + public DateTime EndTime; + + #endregion + } + + #endregion + + #endregion + + #region Private enums + + #region Frequency + + private enum Frequency + { + Secondly, + Minutely, + Hourly, + Daily, + Weekly, + Monthly, + Yearly + } + + #endregion + + #region Related + + private enum Related + { + Start, + End, + Date, + } + + #endregion + + #region AppProp + + [Flags] + private enum AppProp + { + Class = (1 << 0), + Description = (1 << 1), + Summary = (1 << 2), + + XDnbCategoryColor = (1 << 3), + XDnbDisplayTemplate = (1 << 4), + XDnbImageAlign = (1 << 5), + XDnbImageKey = (1 << 6), + XDnbLocked = (1 << 7), + XDnbStartTimeAction = (1 << 8), + XDnbTimeMarkedAs = (1 << 9), + XDnbTooltip = (1 << 10), + } + + #endregion + + #region Registry tokens + + #region ComponentToken + + private enum ComponentToken + { + Daylight, + Standard, + VAlarm, + VCalendar, + VEvent, + VFreeBusy, + VJournal, + VTimezone, + VTodo, + } + + #endregion + + #region PropertyToken + + private enum PropertyToken + { + //Action, + //Attach, + //Attendee, + Begin, + CalScale, + //Categories, + Class, + Comment, + //Completed, + //Contact, + //Created, + Description, + DtEnd, + DtStamp, + DtStart, + Due, + Duration, + End, + ExDate, + //ExRule, + //FreeBusy, + //Geo, + //LastModified, + //Location, + //Method, + //Organizer, + //PercentComplete, + //Priority, + //ProgId, + RDate, + RecurrenceId, + //RelatedTo, + //Repeat, + //RequestStatus, + //Resources, + RRule, + //Sequence, + //Status, + Summary, + //Transp, + Trigger, + TzId, + TzName, + TzOffsetFrom, + TzOffsetTo, + //TzUrl, + Uid, + //Url, + Version, + XDnbCategoryColor, + XDnbDisplayTemplate, + XDnbImageAlign, + XDnbImageKey, + XDnbLocked, + XDnbRecStartDate, + XDnbStartTimeAction, + XDnbTimeMarkedAs, + XDnbTooltip, + XWrCalname, + } + + #endregion + + #region ParameterToken + + private enum ParameterToken + { + //AltRep, + //Cn, + //CuType, + //DelegatedFrom, + //DelegatedTo, + //Dir, + //Encoding, + //FmtType, + //FbType, + //Language, + //Member, + //ParStat, + //Range, + Related, + //RelType, + //Role, + //Rsvp, + //SentBy, + TzId, + Value, + } + + #endregion + + #region ValueToken + + private enum ValueToken + { + ByDay, + ByHour, + ByMinute, + ByMonth, + ByMonthDay, + BySecond, + BySetPos, + ByWeekNo, + ByYearDay, + Count, + Daily, + Date, + DateTime, + Duration, + End, + Fr, + Freq, + Gregorian, + Hourly, + Interval, + Minutely, + Mo, + Monthly, + Period, + Sa, + Secondly, + Start, + Su, + Text, + Th, + Tu, + Until, + We, + Weekly, + WkSt, + Yearly, + } + + #endregion + + #endregion + + #endregion + + #region Public enums + + [Flags] + public enum IcsComponent + { + None = 0, + + Alarm = (1 << 0), + Event = (1 << 1), + Timezone = (1 << 2), + Todo = (1 << 3), + + All = (Alarm | Event | Timezone |Todo), + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Month.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Month.cs new file mode 100644 index 00000000..6db5c9b1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Month.cs @@ -0,0 +1,114 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Globalization; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents the calendar month. + /// + public class Month + { + #region Private Variables + private int _Year = 0, _Month = 0; + private ReadOnlyCollection _ReadOnlyDays = null; + private List _Days = null; + private CalendarModel _CalendarModel = null; + #endregion + + #region Internal Implementation + /// + /// Initializes a new instance of the Month class. + /// + /// + /// + public Month(CalendarModel calendar, int year, int month) + { + _CalendarModel = calendar; + _Year = year; + _Month = month; + } + + /// + /// Gets collection of days in this month. + /// + public ReadOnlyCollection Days + { + get + { + if (_ReadOnlyDays == null) + CreateDayCollection(); + return _ReadOnlyDays; + } + } + + private void CreateDayCollection() + { + Calendar cal = _CalendarModel.GetCalendar(); + int daysCount = cal.GetDaysInMonth(_Year, _Month); + _Days = new List(daysCount); + for (int i = 0; i < daysCount; i++) + { + Day day = new Day(new DateTime(_Year, _Month, i + 1), _CalendarModel); + + _Days.Add(day); + } + _ReadOnlyDays = new ReadOnlyCollection(_Days); + } + + /// + /// Gets the month year. + /// + [Browsable(false)] + public int Year + { + get { return _Year; } + } + + /// + /// Gets the month. + /// + [Browsable(false)] + public int MonthOfYear + { + get { return _Month; } + } + + /// + /// Gets the Calendar this day is part of. + /// + [Browsable(false)] + public CalendarModel CalendarModel + { + get { return _CalendarModel; } + internal set { _CalendarModel = value; } + } + + internal void InvalidateAppointments() + { + if (_Days == null) return; + + foreach (Day day in _Days) + { + day.InvalidateAppointments(); + } + } + + internal void InvalidateAppointments(int day) + { + if (_Days == null) return; + + _Days[day - 1].InvalidateAppointments(); + } + #endregion + + + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/MonthlyRecurrenceSettings.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/MonthlyRecurrenceSettings.cs new file mode 100644 index 00000000..37666d88 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/MonthlyRecurrenceSettings.cs @@ -0,0 +1,195 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Defines monthly recurrence settings. + /// + public class MonthlyRecurrenceSettings : INotifyPropertyChanged, INotifySubPropertyChanged + { + #region Internal Implementation + private AppointmentRecurrence _Recurrence = null; + /// + /// Initializes a new instance of the MonthlyRecurrenceSettings class. + /// + /// + public MonthlyRecurrenceSettings(AppointmentRecurrence recurrence) + { + _Recurrence = recurrence; + } + + + private int _RepeatOnDayOfMonth = 1; + /// + /// Gets or sets the day of month on which appointment is repeated. + /// When RepeatOnRelativeDayInMonth property is set to value other than None value of this property is not used. + /// + [DefaultValue(1)] + public int RepeatOnDayOfMonth + { + get { return _RepeatOnDayOfMonth; } + set + { + if (value != _RepeatOnDayOfMonth) + { + int oldValue = _RepeatOnDayOfMonth; + _RepeatOnDayOfMonth = value; + OnRepeatOnDayOfMonthChanged(oldValue, value); + } + } + } + + private void OnRepeatOnDayOfMonthChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnDayOfMonth")); + } + + + private eRelativeDayInMonth _RepeatOnRelativeDayInMonth = eRelativeDayInMonth.None; + /// + /// Gets or sets whether appointment should repeat on first, second, third, fourth or last day in month as specified + /// by RepeatOnDayOfMonth property. Property applies only for RecurrenceType Monthly or Yearly. + /// + [DefaultValue(eRelativeDayInMonth.None)] + public eRelativeDayInMonth RepeatOnRelativeDayInMonth + { + get { return _RepeatOnRelativeDayInMonth; } + set + { + if (value != _RepeatOnRelativeDayInMonth) + { + eRelativeDayInMonth oldValue = _RepeatOnRelativeDayInMonth; + _RepeatOnRelativeDayInMonth = value; + OnRepeatOnRelativeDayInMonthChanged(oldValue, value); + } + } + } + + private void OnRepeatOnRelativeDayInMonthChanged(eRelativeDayInMonth oldValue, eRelativeDayInMonth newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnRelativeDayInMonth")); + } + + private int _RepeatInterval = 1; + /// + /// Gets or sets the interval between recurring appointments. Default value is 1. + /// + /// For example, setting RepeatInterval to 2 means that appointment will recur every 2 months. + /// + /// + [DefaultValue(1)] + public int RepeatInterval + { + get { return _RepeatInterval; } + set + { + if (value != _RepeatInterval) + { + int oldValue = _RepeatInterval; + _RepeatInterval = value; + OnRepeatIntervalChanged(oldValue, value); + } + } + } + + private void OnRepeatIntervalChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatInterval")); + } + + private DayOfWeek _RelativeDayOfWeek = DayOfWeek.Monday; + /// + /// Gets or sets the day of week on which relative repeat as specified by RepeatOnRelativeDayInMonth is effective. + /// For example setting RepeatOnRelativeDayInMonth to First and RelativeDayOfWeek to Monday will repeat the appointment on first + /// Monday in a month. + /// + [DefaultValue(DayOfWeek.Monday)] + public DayOfWeek RelativeDayOfWeek + { + get { return _RelativeDayOfWeek; } + set + { + if (value != _RelativeDayOfWeek) + { + DayOfWeek oldValue = _RelativeDayOfWeek; + _RelativeDayOfWeek = value; + OnRelativeDayOfWeekChanged(oldValue, value); + } + } + } + + private void OnRelativeDayOfWeekChanged(DayOfWeek oldValue, DayOfWeek newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RelativeDayOfWeek")); + } + + private eMonthRecurrence _RepeatOnMonths = eMonthRecurrence.All; + /// + /// Gets or sets the months on which appointment is repeated. This property is represented by bit-flag enum + /// which means that you can combine the values from eMonthRecurrence enum using OR operator to specify multiple values. + /// Default value is All. + /// + /// For example you could set this property to eMonthRecurrence.January | eMonthRecurrence.July to repeat appointments on January and July only. + /// + /// + [DefaultValue(eMonthRecurrence.All)] + public eMonthRecurrence RepeatOnMonths + { + get { return _RepeatOnMonths; } + set + { + if (value != _RepeatOnMonths) + { + eMonthRecurrence oldValue = _RepeatOnMonths; + _RepeatOnMonths = value; + OnRepeatOnMonthsChanged(oldValue, value); + } + } + } + private void OnRepeatOnMonthsChanged(eMonthRecurrence oldValue, eMonthRecurrence newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnMonths")); + } + #endregion + + #region INotifyPropertyChanged Members + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + if (eh != null) eh(this, e); + OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e)); + } + #endregion + + #region INotifySubPropertyChanged Members + /// + /// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key + /// difference that it occurs for the property changed of child objects as well. + /// + public event SubPropertyChangedEventHandler SubPropertyChanged; + /// + /// Raises the SubPropertyChanged event. + /// + /// Event arguments + protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e) + { + SubPropertyChangedEventHandler eh = SubPropertyChanged; + if (eh != null) eh(this, e); + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/NotificationRequest.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/NotificationRequest.cs new file mode 100644 index 00000000..3e10c797 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/NotificationRequest.cs @@ -0,0 +1,58 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.Schedule.Model +{ + internal class NotificationRequest + { + #region Internal Implementation + /// + /// Initializes a new instance of the NotificationRequest class. + /// + /// + /// + public NotificationRequest(DateTime notificationTime, NotificationServerEventHandler notificationHandler) + { + _NotificationTime = notificationTime; + _NotificationHandler = notificationHandler; + _ThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; + } + + private int _ThreadId; + public int ThreadId + { + get { return _ThreadId; } + } + + + + private DateTime _NotificationTime = DateTime.MinValue; + /// + /// Gets or sets requested notification time. + /// + public DateTime NotificationTime + { + get { return _NotificationTime; } + set + { + _NotificationTime = value; + } + } + + private NotificationServerEventHandler _NotificationHandler = null; + /// + /// Gets the callback handler for notification when notification time is reached. + /// + public NotificationServerEventHandler NotificationHandler + { + get { return _NotificationHandler; } + } + + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/NotificationServer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/NotificationServer.cs new file mode 100644 index 00000000..514ae8ca --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/NotificationServer.cs @@ -0,0 +1,173 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Win32; +using System.Timers; + +namespace DevComponents.Schedule.Model +{ + /// + /// Provides notification support for appointments. + /// + internal static class NotificationServer + { + #region Private Variables + private static Timer _Timer = null; + internal static event NotificationServerEventHandler NotifySubscribers; + private static DateTime _NextEventTime; + private static List _RequestList = new List(); + #endregion + + #region Constructor + static NotificationServer() + { + _Timer = new Timer(); + _Timer.Elapsed += new ElapsedEventHandler(NotificationEventTimerTick); + SystemEvents.TimeChanged += new EventHandler(SystemEvents_TimeChanged); + _NextEventTime = DateTime.MinValue; + } + + static void SystemEvents_TimeChanged(object sender, EventArgs e) + { + if (_NextEventTime > DateTime.MinValue && UtcNow.Subtract(_NextEventTime).TotalSeconds <= 0) + NotifySubscribersOnTimeEvent(); + } + + static void NotificationEventTimerTick(object sender, ElapsedEventArgs e) + { + NotifySubscribersOnTimeEvent(); + } + + private static bool _Notifying = false; + private static void NotifySubscribersOnTimeEvent() + { + try + { + _Notifying = true; + _Timer.Stop(); +#if DEBUG + Console.WriteLine("{0} NotificationServer notifying subscribers count: {1}", DateTime.Now, _RequestList.Count); +#endif + // Reset next notification time... + _NextEventTime = DateTime.MinValue; + + if (_RequestList.Count == 0) + { + return; + } + DateTime now = CalendarModel.GetCalendarDateTime(UtcNow); + NotificationRequest[] requestList = new NotificationRequest[_RequestList.Count]; + _RequestList.CopyTo(requestList); + DateTime nextNotification = DateTime.MinValue; + foreach (NotificationRequest item in requestList) + { + if (item.NotificationTime <= now) + { + if (item.NotificationHandler != null) + { + //if (System.Threading.Thread.CurrentThread.ManagedThreadId != item.ThreadId) + //{ + + // //System.Threading.SendOrPostCallback callback = new System.Threading.SendOrPostCallback(SendNotification); + // //System.Windows.Threading.DispatcherSynchronizationContext.Current.Post(callback, item); + //} + //else + item.NotificationHandler(item, new NotificationServerEventArgs(now)); + } + _RequestList.Remove(item); + } + else if (item.NotificationTime < nextNotification || nextNotification == DateTime.MinValue) + nextNotification = item.NotificationTime; + } + + if (nextNotification > DateTime.MinValue) + { + SetNextEventTime(nextNotification); + } + //else + // Console.WriteLine("Not setting next notification time..."); + } + finally + { + _Notifying = false; + } + } + + private static void SendNotification(object e) + { + NotificationRequest item = (NotificationRequest)e; + if (item.NotificationHandler != null) + { + if (System.Threading.Thread.CurrentThread.ManagedThreadId != item.ThreadId) + { + Console.WriteLine("Different THREAD"); + } + else + { + DateTime now = CalendarModel.GetCalendarDateTime(UtcNow); + item.NotificationHandler(item, new NotificationServerEventArgs(now)); + } + } + } + + + private static void SetNextEventTime(DateTime dateTime) + { + DateTime now = CalendarModel.GetCalendarDateTime(UtcNow); + if (dateTime.Subtract(now).TotalSeconds <= 0) + { + if (!_Notifying) + NotifySubscribersOnTimeEvent(); + else + _NextEventTime = DateTime.MinValue; + } + else if (dateTime.Subtract(now).TotalSeconds > 0 && (_NextEventTime == DateTime.MinValue || dateTime < _NextEventTime)) + { + double nextEvent = dateTime.Subtract(UtcNow).TotalSeconds + 1; + if (nextEvent > int.MaxValue / 1000) + nextEvent = (int.MaxValue - 1) / 1000; + _Timer.Interval = (int)Math.Max(5, nextEvent * 1000); +#if DEBUG + Console.WriteLine("{0} NotificationServer scheduling next event on: {1}, previous scheduled event on: {2}", DateTime.Now, dateTime, _NextEventTime); +#endif + _Timer.Start(); + _NextEventTime = dateTime; + } + //else + // _NextEventTime = DateTime.MinValue; + } + + private static DateTime UtcNow + { + get + { + return TimeZoneInfo.ConvertTimeToUtc(CalendarModel.CurrentDateTime); + } + } + + public static void UpdateNotification(NotificationRequest request) + { + SetNextEventTime(request.NotificationTime); + } + + #endregion + + #region Internal Implementation + public static void Register(NotificationRequest request) + { + _RequestList.Add(request); + SetNextEventTime(request.NotificationTime); + } + + public static void Unregister(NotificationRequest request) + { + _RequestList.Remove(request); + } + #endregion + } + + internal delegate void NotificationServerEventHandler(NotificationRequest sender, NotificationServerEventArgs e); +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/NotificationServerEventArgs.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/NotificationServerEventArgs.cs new file mode 100644 index 00000000..d8a61ce4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/NotificationServerEventArgs.cs @@ -0,0 +1,49 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; + +namespace DevComponents.Schedule.Model +{ + internal class NotificationServerEventArgs : EventArgs + { + /// + /// Initializes a new instance of the NotificationServerEventArgs class. + /// + /// + public NotificationServerEventArgs(DateTime notificationTime) + { + _NotificationTime = notificationTime; + } + + private DateTime _NotificationTime; + /// + /// Gets the time notification is sent on. + /// + public DateTime NotificationTime + { + get { return _NotificationTime; } + } + + private DateTime _NextRequestedNotificationTime = DateTime.MinValue; + /// + /// Gets or sets the next requested notification time by the handler of the event. + /// Handler of event must set this to the desired next notification time in order to be notified. + /// The value recorded will be the lowest value set by all handlers. + /// + public DateTime NextRequestedNotificationTime + { + get { return _NextRequestedNotificationTime; } + set + { + value = CalendarModel.GetCalendarDateTime(value); + if (value > NotificationTime && (value < _NextRequestedNotificationTime || _NextRequestedNotificationTime == DateTime.MinValue)) + { + _NextRequestedNotificationTime = value; + } + } + } + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Owner.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Owner.cs new file mode 100644 index 00000000..f14cf9b0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Owner.cs @@ -0,0 +1,296 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using DevComponents.DotNetBar.Schedule; + +namespace DevComponents.Schedule.Model +{ + public class Owner : INotifyPropertyChanged, INotifySubPropertyChanged + { + #region Constructors + /// + /// Initializes a new instance of the Owner class. + /// + public Owner() + { + _WorkDays = new WorkDayCollection(this); + _CalendarWorkDays = new CalendarWorkDayCollection(this); + } + + /// + /// Initializes a new instance of the Owner class. + /// + /// + public Owner(string key) + : this() + { + _Key = key; + } + + /// + /// Initializes a new instance of the Owner class. + /// + /// + /// + public Owner(string key, string displayName) + : this() + { + _Key = key; + _DisplayName = displayName; + } + + /// + /// Initializes a new instance of the Owner class. + /// + /// + /// + /// + public Owner(string key, string displayName, eCalendarColor colorScheme) + : this() + { + _Key = key; + _ColorScheme = colorScheme; + _DisplayName = displayName; + } + + /// + /// Initializes a new instance of the Owner class. + /// + /// + /// + public Owner(string key, eCalendarColor colorScheme) + : this() + { + _Key = key; + _ColorScheme = colorScheme; + } + #endregion + + #region Internal Implementation + private WorkDayCollection _WorkDays; + /// + /// Gets working days associated with this owner. If empty WorkDays from CalendarModel are used instead. + /// + public WorkDayCollection WorkDays + { + get { return _WorkDays; } + } + + private CalendarWorkDayCollection _CalendarWorkDays; + /// + /// Gets date based working days associated with this owner. Date specific working days take precedence over days specified in WorkDays collection. If empty WorkDays on owner or from CalendarModel are used instead. + /// + public CalendarWorkDayCollection CalendarWorkDays + { + get { return _CalendarWorkDays; } + } + + private string _Key = ""; + /// + /// Gets or sets the unique key that identifies the owner. + /// + [DefaultValue("")] + public string Key + { + get { return _Key; } + set + { + if (value != _Key) + { + string oldValue = _Key; + _Key = value; + OnKeyChanged(oldValue, value); + } + } + } + + private void OnKeyChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Key")); + } + + private string _Description = ""; + /// + /// Gets or sets the owner description. For example if owner represents person, it would be person name or if owner represents resource + /// like room it would be the room name. + /// + [DefaultValue("")] + public string Description + { + get { return _Description; } + set + { + if (value != _Description) + { + string oldValue = _Description; + _Description = value; + OnDescriptionChanged(oldValue, value); + } + } + } + + private void OnDescriptionChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Description")); + + } + + private object _Tag = null; + /// + /// Gets or sets custom data associated with the object. + /// + [DefaultValue(null)] + public object Tag + { + get { return _Tag; } + set + { + if (value != _Tag) + { + object oldValue = _Tag; + _Tag = value; + OnTagChanged(oldValue, value); + } + } + } + + private void OnTagChanged(object oldValue, object newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("Tag")); + } + + private CalendarModel _Calendar = null; + /// + /// Gets the calendar owner is associated with. + /// + [Browsable(false)] + public CalendarModel Calendar + { + get { return _Calendar; } + internal set + { + if (_Calendar != value) + { + _Calendar = value; + } + } + } + + private TimeZoneInfo _DisplayTimeZone = null; + /// + /// Gets or sets the display time-zone for this owner. Default value is null. + /// + [DefaultValue(null)] + public TimeZoneInfo DisplayTimeZone + { + get { return _DisplayTimeZone; } + set + { + if (value != _DisplayTimeZone) + { + TimeZoneInfo oldValue = _DisplayTimeZone; + _DisplayTimeZone = value; + OnDisplayTimeZoneChanged(oldValue, value); + } + } + } + + private void OnDisplayTimeZoneChanged(TimeZoneInfo oldValue, TimeZoneInfo newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("DisplayTimeZone")); + + } + + + private eCalendarColor _ColorScheme = eCalendarColor.Automatic; + /// + /// Gets or sets the owner color scheme used to represent owner data in user interface. + /// + [DefaultValue(eCalendarColor.Automatic)] + public eCalendarColor ColorScheme + { + get { return _ColorScheme; } + set + { + if (value != _ColorScheme) + { + eCalendarColor oldValue = _ColorScheme; + _ColorScheme = value; + OnColorSchemeChanged(oldValue, value); + } + } + } + + private void OnColorSchemeChanged(eCalendarColor oldValue, eCalendarColor newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("ColorScheme")); + + } + private string _DisplayName = null; + /// + /// Gets or sets the display name for the owner. Display name is used in User Interface to identify the owner. + /// If not specified the Key is used instead in UI. + /// + [DefaultValue(null)] + public string DisplayName + { + get { return _DisplayName; } + set + { + if (value != _DisplayName) + { + string oldValue = _DisplayName; + _DisplayName = value; + OnDisplayNameChanged(oldValue, value); + } + } + } + + private void OnDisplayNameChanged(string oldValue, string newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("DisplayName")); + + } + + internal static string DisplayNamePropertyName = "DisplayName"; + #endregion + + #region INotifyPropertyChanged Members + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + if (eh != null) eh(this, e); + OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e)); + } + #endregion + + #region INotifySubPropertyChanged Members + /// + /// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key + /// difference that it occurs for the property changed of child objects as well. + /// + public event SubPropertyChangedEventHandler SubPropertyChanged; + /// + /// Raises the SubPropertyChanged event. + /// + /// Event arguments + protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e) + { + SubPropertyChangedEventHandler eh = SubPropertyChanged; + if (eh != null) eh(this, e); + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/OwnerCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/OwnerCollection.cs new file mode 100644 index 00000000..0976fef1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/OwnerCollection.cs @@ -0,0 +1,123 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; + +namespace DevComponents.Schedule.Model +{ + public class OwnerCollection : Collection + { + #region Constructor + /// + /// Initializes a new instance of the AppointmentCollection class. + /// + /// + public OwnerCollection(CalendarModel calendar) + { + _Calendar = calendar; + } + + #endregion + #region Internal Implementation + private CalendarModel _Calendar = null; + /// + /// Gets the calendar collection is associated with. + /// + public CalendarModel Calendar + { + get { return _Calendar; } + internal set { _Calendar = value; } + } + + protected override void RemoveItem(int index) + { + Owner owner = this[index]; + OnBeforeRemove(index, owner); + base.RemoveItem(index); + OnAfterRemove(index, owner); + } + + private void OnAfterRemove(int index, Owner owner) + { + _Calendar.OwnerRemoved(owner); + } + + private void OnBeforeRemove(int index, Owner owner) + { + owner.Calendar = null; + } + + protected override void InsertItem(int index, Owner item) + { + OnBeforeInsert(index, item); + base.InsertItem(index, item); + OnAfterInsert(index, item); + } + + private void OnAfterInsert(int index, Owner item) + { + _Calendar.OwnerAdded(item); + } + + private void OnBeforeInsert(int index, Owner item) + { + item.Calendar = _Calendar; + } + + protected override void SetItem(int index, Owner newItem) + { + Owner oldItem = this[index]; + OnBeforeSetItem(index, oldItem, newItem); + base.SetItem(index, newItem); + OnAfterSetItem(index, oldItem, newItem); + } + + private void OnAfterSetItem(int index, Owner oldItem, Owner newItem) + { + _Calendar.OwnerRemoved(oldItem); + _Calendar.OwnerAdded(newItem); + } + + private void OnBeforeSetItem(int index, Owner oldItem, Owner newItem) + { + oldItem.Calendar = null; + newItem.Calendar = _Calendar; + } + + protected override void ClearItems() + { + foreach (Owner item in this) + { + item.Calendar = null; + _Calendar.OwnerRemoved(item); + } + base.ClearItems(); + } + + /// + /// Gets the item based on the Key assigned to the item + /// + /// + /// + public Owner this[string ownerKey] + { + get + { + foreach (Owner item in this.Items) + { + if (item.Key == ownerKey) return item; + } + return null; + } + //set + //{ + // Owner owner = this[ownerKey]; + // this[IndexOf(owner)] = value; + //} + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Primitives/CustomCollectionBase.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Primitives/CustomCollectionBase.cs new file mode 100644 index 00000000..5cafab77 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Primitives/CustomCollectionBase.cs @@ -0,0 +1,1006 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Collections.Specialized; + +namespace DevComponents.Schedule.Model.Primitives +{ + /// + /// Represents custom collection with INotifyPropertyChanged and INotifyCollectionChanged interface support. + /// + /// + [Serializable, DebuggerDisplay("Count = {Count}"), ComVisible(false)] + public class CustomCollection : IList, ICollection, IEnumerable, IList, ICollection, IEnumerable, INotifyPropertyChanged, INotifyCollectionChanged + { + #region Events + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + #endregion + + #region Internal Implementation + private SimpleMonitor _monitor; + + [NonSerialized] + private object _syncRoot; + private IList items; + + /// + /// Creates new instance of object. + /// + public CustomCollection() + { + this._monitor = new SimpleMonitor(); + this.items = new List(); + } + /// + /// Creates new instance of object. + /// + /// List to initialize collection with. + public CustomCollection(IList list) + { + if (list == null) + { + throw new ArgumentNullException("list"); + } + this._monitor = new SimpleMonitor(); + this.items = list; + } + /// + /// Add item to collection. + /// + /// Item to add. + public void Add(T item) + { + if (this.items.IsReadOnly) + { + throw new NotSupportedException("collection is read-only"); + } + int count = this.items.Count; + this.InsertItem(count, item); + } + /// + /// Remove all items from collection. + /// + public void Clear() + { + if (this.items.IsReadOnly) + { + throw new NotSupportedException("collection is read-only"); + } + this.ClearItems(); + } + /// + /// Remove all items from collection. + /// + protected virtual void ClearItems() + { + this.CheckReentrancy(); + this.items.Clear(); + OnPropertyChanged(new PropertyChangedEventArgs(this.CountString)); + OnPropertyChanged(new PropertyChangedEventArgs(this.ItemString)); + this.OnCollectionReset(); + } + /// + /// Checks whether collection contains item. + /// + /// Item to look for. + /// true if item is in collection. + public bool Contains(T item) + { + OnCollectionReadAccess(); + return this.items.Contains(item); + } + /// + /// Copy collection to array. + /// + /// Array to copy to. + /// Index to copy from. + public void CopyTo(T[] array, int index) + { + OnCollectionReadAccess(); + this.items.CopyTo(array, index); + } + /// + /// Gets enumerator for collection. + /// + /// Enumerator. + public IEnumerator GetEnumerator() + { + OnCollectionReadAccess(); + return this.items.GetEnumerator(); + } + /// + /// Returns index of an item. + /// + /// Reference to item. + /// Index of item. + public int IndexOf(T item) + { + OnCollectionReadAccess(); + return this.items.IndexOf(item); + } + /// + /// Insert item at specified location. + /// + /// Index to insert item in. + /// Item to insert. + public void Insert(int index, T item) + { + if ((index < 0) || (index > this.items.Count)) + { + throw new ArgumentOutOfRangeException("index"); + } + this.InsertItem(index, item); + } + /// + /// Inserts item. + /// + /// Index to insert item at. + /// Reference to item. + protected virtual void InsertItem(int index, T item) + { + this.CheckReentrancy(); + this.items.Insert(index, item); + OnPropertyChanged(new PropertyChangedEventArgs(this.CountString)); + this.OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index); + } + + private static bool IsCompatibleObject(object value) + { + if (!(value is T) && ((value != null) || typeof(T).IsValueType)) + { + return false; + } + return true; + } + /// + /// Removes item from collection. + /// + /// Item to remove. + /// true if item was removed. + public bool Remove(T item) + { + if (this.items.IsReadOnly) + { + throw new NotSupportedException("collection is read-only"); + } + int index = this.items.IndexOf(item); + if (index < 0) + { + return false; + } + this.RemoveItem(index); + return true; + } + /// + /// Remove item at specified location. + /// + /// Index of item to remove. + public void RemoveAt(int index) + { + if (this.items.IsReadOnly) + { + throw new NotSupportedException("collection is read-only"); + } + if ((index < 0) || (index >= this.items.Count)) + { + throw new ArgumentOutOfRangeException(); + } + this.RemoveItem(index); + } + /// + /// Remove item at specified location. + /// + /// Index of item to remove. + protected virtual void RemoveItem(int index) + { + this.CheckReentrancy(); + + object item = items[index]; + this.items.RemoveAt(index); + OnPropertyChanged(new PropertyChangedEventArgs(this.CountString)); + this.OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, index); + } + /// + /// Set item on location. + /// + /// Index + /// Item to assign. + protected virtual void SetItem(int index, T item) + { + this.CheckReentrancy(); + T oldItem = items[index]; + this.items[index] = item; + OnPropertyChanged(new PropertyChangedEventArgs(this.CountString)); + OnPropertyChanged(new PropertyChangedEventArgs(this.ItemString)); + this.OnCollectionChanged(NotifyCollectionChangedAction.Replace, oldItem, item, index); + } + + void ICollection.CopyTo(Array array, int index) + { + this.CheckReentrancy(); + OnCollectionReadAccess(); + if (array == null) + { + throw new ArgumentNullException("array"); + } + if (array.Rank != 1) + { + throw new ArgumentException("Argument array.Rank multi-dimensional not supported"); + } + if (array.GetLowerBound(0) != 0) + { + throw new ArgumentException("Argument array non zero lower bound not supported"); + } + if (index < 0) + { + throw new ArgumentOutOfRangeException("index must be non-negative number"); + } + if ((array.Length - index) < this.Count) + { + throw new ArgumentException("array too small"); + } + T[] localArray = array as T[]; + if (localArray != null) + { + this.items.CopyTo(localArray, index); + } + else + { + Type elementType = array.GetType().GetElementType(); + Type c = typeof(T); + if (!elementType.IsAssignableFrom(c) && !c.IsAssignableFrom(elementType)) + { + throw new ArgumentException("Argument array of invalid type"); + } + object[] objArray = array as object[]; + if (objArray == null) + { + throw new ArgumentException("Argument array invalid type"); + } + int count = this.items.Count; + try + { + for (int i = 0; i < count; i++) + { + objArray[index++] = this.items[i]; + } + } + catch (ArrayTypeMismatchException) + { + throw new ArgumentException("Argument array invalid type"); + } + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + OnCollectionReadAccess(); + return this.items.GetEnumerator(); + } + + int IList.Add(object value) + { + if (this.items.IsReadOnly) + { + throw new NotSupportedException("collection is read-only"); + } + VerifyValueType(value); + this.Add((T)value); + return (this.Count - 1); + } + + private static void VerifyValueType(object value) + { + if (!IsCompatibleObject(value)) + { + throw new ArgumentException("value is of wrong type"); + } + } + + + bool IList.Contains(object value) + { + return (CustomCollection.IsCompatibleObject(value) && this.Contains((T)value)); + } + + int IList.IndexOf(object value) + { + OnCollectionReadAccess(); + if (CustomCollection.IsCompatibleObject(value)) + { + return this.IndexOf((T)value); + } + return -1; + } + + void IList.Insert(int index, object value) + { + if (this.items.IsReadOnly) + { + throw new NotSupportedException("collection is read-only"); + } + VerifyValueType(value); + this.Insert(index, (T)value); + } + + void IList.Remove(object value) + { + if (this.items.IsReadOnly) + { + throw new NotSupportedException("collection is read-only"); + } + if (CustomCollection.IsCompatibleObject(value)) + { + this.Remove((T)value); + } + } + + /// + /// Returns number of items in collection. + /// + public int Count + { + get + { + OnCollectionReadAccess(); + return this.items.Count; + } + } + + /// + /// Returns item at index. + /// + /// Index of item. + /// Item at index. + public T this[int index] + { + get + { + OnCollectionReadAccess(); + return this.items[index]; + } + set + { + if (this.items.IsReadOnly) + { + throw new NotSupportedException("collection is read-only"); + } + if ((index < 0) || (index >= this.items.Count)) + { + throw new ArgumentOutOfRangeException(); + } + this.SetItem(index, value); + } + } + + /// + /// Returns the IList interface for items in collection. + /// + protected IList Items + { + get + { + OnCollectionReadAccess(); + return this.items; + } + } + /// + /// Returns items directly without checks. + /// + /// List of items. + protected IList GetItemsDirect() + { + return this.items; + } + + bool ICollection.IsReadOnly + { + get + { + return this.items.IsReadOnly; + } + } + + bool ICollection.IsSynchronized + { + get + { + return false; + } + } + + object ICollection.SyncRoot + { + get + { + if (this._syncRoot == null) + { + ICollection items = this.items as ICollection; + if (items != null) + { + this._syncRoot = items.SyncRoot; + } + else + { + System.Threading.Interlocked.CompareExchange(ref this._syncRoot, new object(), null); + } + } + return this._syncRoot; + } + } + + bool IList.IsFixedSize + { + get + { + IList items = this.items as IList; + return ((items != null) && items.IsFixedSize); + } + } + + bool IList.IsReadOnly + { + get + { + return this.items.IsReadOnly; + } + } + + object IList.this[int index] + { + get + { + OnCollectionReadAccess(); + return this.items[index]; + } + set + { + VerifyValueType(value); + this[index] = (T)value; + } + } + /// + /// Occurs when collection is read. + /// + protected virtual void OnCollectionReadAccess() + { + } + /// + /// Occurs when collection property has changed. + /// + /// Event arguments. + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (this.PropertyChanged != null) + { + this.PropertyChanged(this, e); + } + } + + private string CountString + { + get { return "Count"; } + } + private string ItemString + { + get { return "Item[]"; } + } + /// + /// Blocks the collection re-entrancy. + /// + /// IDisposable to end re-entrancy + protected IDisposable BlockReentrancy() + { + this._monitor.Enter(); + return this._monitor; + } + /// + /// Checks whether call creates re-entrancy. + /// + protected void CheckReentrancy() + { + if ((this._monitor.Busy && (this.CollectionChanged != null)) && (this.CollectionChanged.GetInvocationList().Length > 1)) + { + throw new InvalidOperationException("CustomCollectionReentrancyNotAllowed"); + } + } + + + #region SimpleMonitor + [Serializable] + private class SimpleMonitor : IDisposable + { + // Fields + private int _busyCount; + + // Methods + public void Dispose() + { + this._busyCount--; + } + + public void Enter() + { + this._busyCount++; + } + + // Properties + public bool Busy + { + get + { + return (this._busyCount > 0); + } + } + } + #endregion + + #endregion + + #region INotifyCollectionChanged Members + /// + /// Occurs when collection has changed. + /// + public event NotifyCollectionChangedEventHandler CollectionChanged; + + private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index) + { + this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index)); + } + + private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index, int oldIndex) + { + this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index, oldIndex)); + } + + private void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem, object newItem, int index) + { + this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index)); + } + + private void OnCollectionReset() + { + this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + } + + /// + /// Called when collection has changed. + /// + /// Event arguments. + protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + { + if (this.CollectionChanged != null) + { + using (this.BlockReentrancy()) + { + this.CollectionChanged(this, e); + } + } + } + #endregion + } + + #region INotifyCollectionChanged + /// + /// Represents collection changed notification interface. + /// + public interface INotifyCollectionChanged + { + /// + /// Occurs when collection changed. + /// + event NotifyCollectionChangedEventHandler CollectionChanged; + } + /// + /// Defines change actions. + /// + public enum NotifyCollectionChangedAction + { + /// + /// Items were added. + /// + Add, + /// + /// Items were removed. + /// + Remove, + /// + /// Items were replaced. + /// + Replace, + /// + /// Items were moved. + /// + Move, + /// + /// Collection was reset. + /// + Reset + } + /// + /// Defines delegate for collection notification events. + /// + /// Event sender. + /// Event arguments. + public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e); + /// + /// Defines collection change notification event arguments. + /// + public class NotifyCollectionChangedEventArgs : EventArgs + { + #region Private Vars + private NotifyCollectionChangedAction _action; + private IList _newItems; + private int _newStartingIndex; + private IList _oldItems; + private int _oldStartingIndex; + #endregion + + /// + /// Create new instance of object. + /// + /// Action + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Reset) + { + throw new ArgumentException("WrongActionForCtor"); + } + this.InitializeAdd(action, null, -1); + } + /// + /// Creates new instance of object. + /// + /// Specifies action. + /// List of changed items. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItems != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + this.InitializeAdd(action, null, -1); + } + else + { + if (changedItems == null) + { + throw new ArgumentNullException("changedItems"); + } + this.InitializeAddOrRemove(action, changedItems, -1); + } + } + /// + /// Creates new instance of object. + /// + /// Specifies action. + /// Item that was changed. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItem != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + this.InitializeAdd(action, null, -1); + } + else + { + this.InitializeAddOrRemove(action, new object[] { changedItem }, -1); + } + } + + /// + /// Creates new instance of object. + /// + /// Action. + /// New items in collection. + /// Old items in collection. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (newItems == null) + { + throw new ArgumentNullException("newItems"); + } + if (oldItems == null) + { + throw new ArgumentNullException("oldItems"); + } + this.InitializeMoveOrReplace(action, newItems, oldItems, -1, -1); + } + /// + /// Creates new instance of object. + /// + /// Action. + /// List of changed items. + /// Starting index of change. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int startingIndex) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItems != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + if (startingIndex != -1) + { + throw new ArgumentException("ResetActionRequiresIndexMinus1"); + } + this.InitializeAdd(action, null, -1); + } + else + { + if (changedItems == null) + { + throw new ArgumentNullException("changedItems"); + } + if (startingIndex < -1) + { + throw new ArgumentException("IndexCannotBeNegative"); + } + this.InitializeAddOrRemove(action, changedItems, startingIndex); + } + } + /// + /// Creates new instance of object. + /// + /// Action + /// Changed item + /// Index of change + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItem != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + if (index != -1) + { + throw new ArgumentException("ResetActionRequiresIndexMinus1"); + } + this.InitializeAdd(action, null, -1); + } + else + { + this.InitializeAddOrRemove(action, new object[] { changedItem }, index); + } + } + /// + /// Creates new instance of object. + /// + /// Action + /// New item + /// Old item + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + this.InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, -1, -1); + } + /// + /// Creates new instance of object. + /// + /// Action + /// New items. + /// Removed items. + /// Starting index of change. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (newItems == null) + { + throw new ArgumentNullException("newItems"); + } + if (oldItems == null) + { + throw new ArgumentNullException("oldItems"); + } + this.InitializeMoveOrReplace(action, newItems, oldItems, startingIndex, startingIndex); + } + /// + /// Creates new instance of object. + /// + /// Action + /// Changed items + /// New index + /// Old index + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Move) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (index < 0) + { + throw new ArgumentException("IndexCannotBeNegative"); + } + this.InitializeMoveOrReplace(action, changedItems, changedItems, index, oldIndex); + } + /// + /// Creates new instance of object. + /// + /// Action + /// Changed item + /// New index + /// Old index + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Move) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (index < 0) + { + throw new ArgumentException("IndexCannotBeNegative"); + } + object[] newItems = new object[] { changedItem }; + this.InitializeMoveOrReplace(action, newItems, newItems, index, oldIndex); + } + /// + /// Creates new instance of object. + /// + /// Action. + /// New item + /// Old item + /// New index + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem, int index) + { + this._newStartingIndex = -1; + this._oldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + this.InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, index, index); + } + + private void InitializeAdd(NotifyCollectionChangedAction action, IList newItems, int newStartingIndex) + { + this._action = action; + this._newItems = (newItems == null) ? null : ArrayList.ReadOnly(newItems); + this._newStartingIndex = newStartingIndex; + } + + private void InitializeAddOrRemove(NotifyCollectionChangedAction action, IList changedItems, int startingIndex) + { + if (action == NotifyCollectionChangedAction.Add) + { + this.InitializeAdd(action, changedItems, startingIndex); + } + else if (action == NotifyCollectionChangedAction.Remove) + { + this.InitializeRemove(action, changedItems, startingIndex); + } + else + { + //Invariant.Assert(false, "Unsupported action: {0}", action.ToString()); + } + } + + private void InitializeMoveOrReplace(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex, int oldStartingIndex) + { + this.InitializeAdd(action, newItems, startingIndex); + this.InitializeRemove(action, oldItems, oldStartingIndex); + } + + private void InitializeRemove(NotifyCollectionChangedAction action, IList oldItems, int oldStartingIndex) + { + this._action = action; + this._oldItems = (oldItems == null) ? null : ArrayList.ReadOnly(oldItems); + this._oldStartingIndex = oldStartingIndex; + } + + /// + /// Gets the type of the collection change action. + /// + public NotifyCollectionChangedAction Action + { + get + { + return this._action; + } + } + /// + /// Gets list of newly added items. + /// + public IList NewItems + { + get + { + return this._newItems; + } + } + /// + /// Gets new starting index. + /// + public int NewStartingIndex + { + get + { + return this._newStartingIndex; + } + } + /// + /// Gets list of removed items. + /// + public IList OldItems + { + get + { + return this._oldItems; + } + } + /// + /// Old starting index. + /// + public int OldStartingIndex + { + get + { + return this._oldStartingIndex; + } + } + } + #endregion + +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/RecurrenceGenerator.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/RecurrenceGenerator.cs new file mode 100644 index 00000000..c64e70c1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/RecurrenceGenerator.cs @@ -0,0 +1,600 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Globalization; + +namespace DevComponents.Schedule.Model +{ + internal class RecurrenceGenerator : IRecurrenceGenerator + { + + #region IRecurrenceGenerator Members + + /// + /// Generates Daily recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well. + /// + /// Collection to add generated recurrences to + /// Recurrence description, must be of Daily recurrence type. + /// Start date for generation. + /// End date for generation. + public void GenerateDailyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate) + { + Appointment app = recurrence.Appointment; + int appointmentDaysDuration = recurrence.Daily.ExplicitDailyRecurrence ? 0 : (int)Math.Max(0, Math.Ceiling(app.EndTime.Date.Subtract(app.StartTime.Date).TotalDays)); + DateTime recurrenceStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate, + recurrence.Daily.ExplicitDailyRecurrence ? (app.StartTime.AddDays(1).Date) : (DateTimeHelper.IsBeginningOfDay(app.EndTime) ? app.EndTime : app.EndTime.AddDays(recurrence.Daily.RepeatInterval).Date)); + + if (recurrenceStartDate > endDate) return; + + int repeats = 0; + + // Check the range first + if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate) + { + if (startDate > recurrence.RangeEndDate) return; + } + else if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences) + { + DateTime rangeStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate, + recurrence.Daily.ExplicitDailyRecurrence ? (app.LocalStartTime.AddDays(1).Date) : (DateTimeHelper.IsBeginningOfDay(app.LocalEndTime) ? app.LocalEndTime : app.LocalEndTime.AddDays(recurrence.Daily.RepeatInterval).Date)); + int totalDays = (int)Math.Ceiling(startDate.Subtract(rangeStartDate).TotalDays); + + switch (recurrence.Daily.RepeatOnDaysOfWeek) + { + case eDailyRecurrenceRepeat.All: + repeats = Math.Max(0, totalDays / (recurrence.Daily.RepeatInterval + appointmentDaysDuration)); + + if (repeats >= recurrence.RangeNumberOfOccurrences) + return; + break; + + case eDailyRecurrenceRepeat.WeekDays: + repeats = Math.Max(0, DateTimeHelper.TotalWeekDays(recurrenceStartDate, startDate) / (recurrence.Daily.RepeatInterval + appointmentDaysDuration)); + + // Assume weekdays repeat + if (repeats > recurrence.RangeNumberOfOccurrences) + return; + break; + + default: + repeats = Math.Max(0, DateTimeHelper.TotalWeekDays(recurrenceStartDate, startDate)); + repeats = Math.Max(0, totalDays - repeats); + + // Assume weekend days repeat + if (repeats > recurrence.RangeNumberOfOccurrences) + return; + break; + } + + //repeats = 0; + } + + DateTime currentDay = recurrenceStartDate; // DateTimeHelper.MaxDate(startDate, recurrenceStartDate); + + while (currentDay <= endDate) + { + if (currentDay >= startDate || currentDay < startDate && IsRecurringOnDay(currentDay, startDate, endDate, app)) + { + if (!IsRecurringOnDay(currentDay, startDate, endDate, app)) break; + if (recurrence.Daily.RepeatOnDaysOfWeek == eDailyRecurrenceRepeat.All || + (recurrence.Daily.RepeatOnDaysOfWeek == eDailyRecurrenceRepeat.WeekDays && !DateTimeHelper.IsWeekendDay(currentDay)) || + (recurrence.Daily.RepeatOnDaysOfWeek == eDailyRecurrenceRepeat.WeekendDays && DateTimeHelper.IsWeekendDay(currentDay))) + { + if (!IsIgnoredRecurrence(currentDay, recurrence)) + { + subsetCollection.Add(CreateRecurringAppointmentInstance(currentDay, app)); + repeats++; + } + } + } + + switch (recurrence.Daily.RepeatOnDaysOfWeek) + { + case eDailyRecurrenceRepeat.All: + currentDay = currentDay.AddDays(recurrence.Daily.RepeatInterval + appointmentDaysDuration); + break; + + case eDailyRecurrenceRepeat.WeekDays: + //currentDay = currentDay.AddDays(currentDay.DayOfWeek == DayOfWeek.Saturday ? 2 : Math.Max(1, recurrence.Daily.RepeatInterval + appointmentDaysDuration)); + currentDay = currentDay.AddDays(Math.Max(1, recurrence.Daily.RepeatInterval + appointmentDaysDuration)); // Changed for consistency + break; + + case eDailyRecurrenceRepeat.WeekendDays: + while (true) + { + currentDay = currentDay.AddDays(1); + + if (DateTimeHelper.IsWeekendDay(currentDay) == true) + break; + } + break; + } + + if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDay >= recurrence.RangeEndDate || + recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && repeats >= recurrence.RangeNumberOfOccurrences) + break; + } + } + + private static bool IsIgnoredRecurrence(DateTime currentDay, AppointmentRecurrence recurrence) + { + if (recurrence.SkippedRecurrences.Count == 0) return false; + foreach (DateTime date in recurrence.SkippedRecurrences) + { + if (date.Date == currentDay.Date) + return true; + } + return false; + } + + private bool IsRecurringOnDay(DateTime currentDay, DateTime rangeStart, DateTime rangeEnd, Appointment rootAppointment) + { + TimeSpan duration = rootAppointment.EndTime.Subtract(rootAppointment.StartTime); + DateTime startTime = rootAppointment.GetValidDateTime(new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, rootAppointment.StartTime.Hour, rootAppointment.StartTime.Minute, 0)); + DateTime endTime = rootAppointment.GetValidDateTime(startTime.Add(duration)); + + DateTime localStartTime = rootAppointment.GetLocalDateTime(rootAppointment.GetUTCDateTime(startTime)); + DateTime localEndTime = rootAppointment.GetLocalDateTime(rootAppointment.GetUTCDateTime(endTime)); + + // If time-zone is not used return false + //if (startTime == localStartTime) return currentDay >= rangeStart; + + return DateTimeHelper.TimePeriodsOverlap(localStartTime, localEndTime, rangeStart, rangeEnd); + } + + private DateTime GetAppointmentEndTime(DateTime currentDay, Appointment rootAppointment) + { + TimeSpan duration = rootAppointment.EndTime.Subtract(rootAppointment.StartTime); + DateTime startTime = rootAppointment.GetValidDateTime(new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, rootAppointment.StartTime.Hour, rootAppointment.StartTime.Minute, 0)); + DateTime endTime = rootAppointment.GetValidDateTime(startTime.Add(duration)); + + return endTime; + } + + private Appointment CreateRecurringAppointmentInstance(DateTime currentDay, Appointment rootAppointment) + { + Appointment app = rootAppointment.Copy(); + TimeSpan duration = rootAppointment.EndTime.Subtract(rootAppointment.StartTime); + DateTime startTime = app.GetValidDateTime(new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, rootAppointment.StartTime.Hour, rootAppointment.StartTime.Minute, 0)); + DateTime endTime = app.GetValidDateTime(startTime.Add(duration)); + + app.StartTime = startTime; + app.EndTime = endTime; + app.IsRecurringInstance = true; + app.RootAppointment = rootAppointment; + app.Tooltip = rootAppointment.Tooltip; + if (rootAppointment.Recurrence == null || !rootAppointment.Recurrence.IndependentVisibility) + app.Visible = rootAppointment.Visible; + + foreach (Reminder reminder in app.Reminders) + { + //reminder.ReminderTime = app.StartTime.Add(reminder.ReminderTime.Subtract(rootAppointment.StartTime)); + reminder.IsActive = true; + } + + return app; + } + + /// + /// Generates Weekly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well. + /// + /// Collection to add generated recurrences to + /// Recurrence description, must be of Weekly recurrence type. + /// Start date for generation. + /// End date for generation. + public void GenerateWeeklyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate) + { + Appointment app = recurrence.Appointment; + + DateTime baseStartDate = app.EndTime.Date; + if (app.EndTime.Date > app.StartTime.Date && app.EndTime.TimeOfDay > app.StartTime.TimeOfDay && baseStartDate != DateTime.MinValue) + baseStartDate = baseStartDate.AddDays(1); + DateTime recurrenceStartDate = baseStartDate; + int repeatInterval = recurrence.Weekly.RepeatInterval; + + if (RepeatsOnSingleDayOnly(recurrence.Weekly.RepeatOnDaysOfWeek) && !(app.StartTime.Date == startDate.Date && endDate.Date == startDate.Date)) + { + recurrenceStartDate = baseStartDate.AddMilliseconds(-1).AddDays((repeatInterval) * 7 /*+ (recurrence.Weekly.RepeatInterval > 1 ? (8 - (int)baseStartDate.DayOfWeek) : 1)*/).Date; + if (recurrenceStartDate.DayOfWeek != GetDayOfWeek(recurrence.Weekly.RepeatOnDaysOfWeek)) + { + DayOfWeek dayOfWeek = GetDayOfWeek(recurrence.Weekly.RepeatOnDaysOfWeek); + while (recurrenceStartDate.DayOfWeek != dayOfWeek) + recurrenceStartDate = recurrenceStartDate.AddDays(1); + } + } + else + { + if (app.EndTime.Date > app.StartTime.Date && app.EndTime.TimeOfDay < app.StartTime.TimeOfDay) + recurrenceStartDate = app.StartTime.Date.AddDays(1); + else + recurrenceStartDate = app.EndTime.Date.AddDays(1); + } + + recurrenceStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate, recurrenceStartDate); + + if (recurrenceStartDate > endDate) return; + + int totalRecurrences = 0; + // Check the range first + if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate) + { + if (startDate > recurrence.RangeEndDate) return; + } + else if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && repeatInterval == 1) + { + int totalDays = (int)Math.Ceiling(endDate.Subtract(recurrenceStartDate).TotalDays); + int occurrencesPerWeek = GetNumberOfDays(recurrence.Weekly.RepeatOnDaysOfWeek); + if (occurrencesPerWeek == 0) + throw new ArgumentException("Weekly recurrence must have at least single day selected using RepeatOnDaysOfWeek property."); + totalRecurrences = DateTimeHelper.TotalNumberOfDays(recurrenceStartDate, endDate, recurrence.Weekly.RepeatOnDaysOfWeek); + if (totalRecurrences > recurrence.RangeNumberOfOccurrences) return; + } + + bool countTotalRecurrences = false; + if (repeatInterval > 1 && recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences) + countTotalRecurrences = true; + + bool spansDays = app.StartTime.Day != app.EndTime.Day && endDate.Subtract(startDate).TotalDays <= 1; + + DateTime currentDay = recurrenceStartDate;// DateTimeHelper.MaxDate(recurrenceStartDate, startDate); + while (currentDay <= endDate) + { + if ((currentDay >= startDate || spansDays && GetAppointmentEndTime(currentDay, app) >= startDate) && DateTimeHelper.HasDay(currentDay.DayOfWeek, recurrence.Weekly.RepeatOnDaysOfWeek) && + !IsIgnoredRecurrence(currentDay, recurrence)) + { + subsetCollection.Add(CreateRecurringAppointmentInstance(currentDay, app)); + totalRecurrences++; + } + else if (countTotalRecurrences && currentDay < startDate && DateTimeHelper.HasDay(currentDay.DayOfWeek, recurrence.Weekly.RepeatOnDaysOfWeek) + && !IsIgnoredRecurrence(currentDay, recurrence)) + { + totalRecurrences++; + if (totalRecurrences >= recurrence.RangeNumberOfOccurrences) + return; + } + + if (currentDay.DayOfWeek != DayOfWeek.Sunday) + { + while (currentDay.DayOfWeek != DayOfWeek.Sunday) + { + currentDay = currentDay.AddDays(1); + if (currentDay > endDate || recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDay > recurrence.RangeEndDate) + break; + if ((currentDay >= startDate || spansDays && GetAppointmentEndTime(currentDay, app) >= startDate) && DateTimeHelper.HasDay(currentDay.DayOfWeek, recurrence.Weekly.RepeatOnDaysOfWeek) + && !IsIgnoredRecurrence(currentDay, recurrence)) + { + subsetCollection.Add(CreateRecurringAppointmentInstance(currentDay, app)); + } + else if (countTotalRecurrences && currentDay < startDate && DateTimeHelper.HasDay(currentDay.DayOfWeek, recurrence.Weekly.RepeatOnDaysOfWeek) + && !IsIgnoredRecurrence(currentDay, recurrence)) + { + totalRecurrences++; + if (totalRecurrences >= recurrence.RangeNumberOfOccurrences) + return; + } + } + } + currentDay = currentDay.AddDays(1 + (repeatInterval - 1) * 7); + if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDay > recurrence.RangeEndDate || + recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && totalRecurrences > recurrence.RangeNumberOfOccurrences) + break; + } + } + + private DayOfWeek GetDayOfWeek(eDayOfWeekRecurrence d) + { + if (d == eDayOfWeekRecurrence.Monday) + return DayOfWeek.Monday; + else if (d == eDayOfWeekRecurrence.Tuesday) + return DayOfWeek.Tuesday; + else if (d == eDayOfWeekRecurrence.Wednesday) + return DayOfWeek.Wednesday; + else if (d == eDayOfWeekRecurrence.Thursday) + return DayOfWeek.Thursday; + else if (d == eDayOfWeekRecurrence.Friday) + return DayOfWeek.Friday; + else if (d == eDayOfWeekRecurrence.Saturday) + return DayOfWeek.Saturday; + else + return DayOfWeek.Sunday; + } + + private bool RepeatsOnSingleDayOnly(eDayOfWeekRecurrence dow) + { + return dow == eDayOfWeekRecurrence.Monday || dow == eDayOfWeekRecurrence.Tuesday || + dow == eDayOfWeekRecurrence.Wednesday || dow == eDayOfWeekRecurrence.Thursday || + dow == eDayOfWeekRecurrence.Friday || dow == eDayOfWeekRecurrence.Saturday || dow == eDayOfWeekRecurrence.Sunday; + } + + private int GetNumberOfDays(eDayOfWeekRecurrence daysOfWeek) + { + int days = 0; + if ((daysOfWeek & eDayOfWeekRecurrence.Friday) != 0) + days++; + if ((daysOfWeek & eDayOfWeekRecurrence.Monday) != 0) + days++; + if ((daysOfWeek & eDayOfWeekRecurrence.Saturday) != 0) + days++; + if ((daysOfWeek & eDayOfWeekRecurrence.Sunday) != 0) + days++; + if ((daysOfWeek & eDayOfWeekRecurrence.Thursday) != 0) + days++; + if ((daysOfWeek & eDayOfWeekRecurrence.Tuesday) != 0) + days++; + if ((daysOfWeek & eDayOfWeekRecurrence.Wednesday) != 0) + days++; + + return days; + } + + /// + /// Generates Monthly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well. + /// + /// Collection to add generated recurrences to + /// Recurrence description, must be of Monthly recurrence type. + /// Start date for generation. + /// End date for generation. + public void GenerateMonthlyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate) + { + Appointment app = recurrence.Appointment; + DateTime recurrenceStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate, app.EndTime/*.AddDays(1).Date*/); + if (recurrenceStartDate > endDate) return; + + int totalRecurrences = 0; + // Check the range first + if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate) + { + if (startDate > recurrence.RangeEndDate) return; + } + else if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && recurrence.RangeNumberOfOccurrences > 0) + { + int count = recurrence.RangeNumberOfOccurrences + 1; + DateTime testDate = DateTimeHelper.BeginningOfDay(recurrenceStartDate); + DateTime startDateOnly = DateTimeHelper.BeginningOfDay(startDate); + while (count > 0 && testDate < startDateOnly) + { + int repeatInterval = recurrence.Monthly.RepeatInterval; + while (repeatInterval > 0) + { + testDate = GetNextMonthlyRecurrence(recurrence, testDate); + repeatInterval--; + } + if (testDate < startDate) + totalRecurrences++; + count--; + } + if (count == 0) return; + } + + DateTime currentDate = recurrenceStartDate;// DateTimeHelper.MaxDate(recurrenceStartDate, startDate).AddMonths(-1); + + do + { + int repeatCount = recurrence.Monthly.RepeatInterval; + do + { + repeatCount--; + currentDate = GetNextMonthlyRecurrence(recurrence, currentDate); + } while (repeatCount > 0); + + if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDate > recurrence.RangeEndDate || + recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && totalRecurrences >= recurrence.RangeNumberOfOccurrences) + break; + + if (currentDate >= startDate && currentDate <= endDate && !IsIgnoredRecurrence(currentDate, recurrence)) + { + subsetCollection.Add(CreateRecurringAppointmentInstance(currentDate, app)); + totalRecurrences++; + } + } while (currentDate <= endDate); + } + + private DateTime GetNextMonthlyRecurrence(AppointmentRecurrence recurrence, DateTime startDate) + { + MonthlyRecurrenceSettings monthly = recurrence.Monthly; + return GetNextMonthlyRecurrence(startDate, monthly.RepeatOnRelativeDayInMonth, + monthly.RelativeDayOfWeek, monthly.RepeatOnDayOfMonth, monthly.RepeatOnMonths); + } + + private static void AdjustForRepeatOnMonths(ref DateTime dt, eMonthRecurrence repeatOnMonths) + { + while (((int)Math.Pow(2, (dt.Month - 1)) & (int)repeatOnMonths) == 0) + dt = dt.AddMonths(1); + } + private static DateTime GetNextMonthlyRecurrence(DateTime startDate, eRelativeDayInMonth repeatOnRelativeDayInMonth, DayOfWeek relativeDayOfWeek, int repeatOnDayOfMonth, eMonthRecurrence repeatOnMonths) + { + Calendar cal = GetCalendar(); + + if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.None) + { + DateTime dt = startDate.AddDays(cal.GetDaysInMonth(startDate.Year, startDate.Month) - startDate.Day + 1); + if (repeatOnMonths != eMonthRecurrence.All) AdjustForRepeatOnMonths(ref dt, repeatOnMonths); // Adjust for repeat on Months + return dt.AddDays(Math.Min(cal.GetDaysInMonth(dt.Year, dt.Month), repeatOnDayOfMonth) - 1); + } + else + { + if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.First) + { + DateTime dt = startDate.AddDays(cal.GetDaysInMonth(startDate.Year, startDate.Month) - startDate.Day + 1); + if (repeatOnMonths != eMonthRecurrence.All) AdjustForRepeatOnMonths(ref dt, repeatOnMonths); // Adjust for repeat on Months + while (dt.DayOfWeek != relativeDayOfWeek) + dt = dt.AddDays(1); + return dt; + } + else if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.Last) + { + DateTime dt = startDate.AddDays(cal.GetDaysInMonth(startDate.Year, startDate.Month) - startDate.Day + 1); + if (repeatOnMonths != eMonthRecurrence.All) AdjustForRepeatOnMonths(ref dt, repeatOnMonths); // Adjust for repeat on Months + dt = dt.AddDays(cal.GetDaysInMonth(dt.Year, dt.Month) - 1); + while (dt.DayOfWeek != relativeDayOfWeek) + dt = dt.AddDays(-1); + return dt; + } + else + { + // Second, third and forth + int relCount = 2; + if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.Third) + relCount = 3; + else if (repeatOnRelativeDayInMonth == eRelativeDayInMonth.Fourth) + relCount = 4; + DateTime dt = startDate.AddDays(cal.GetDaysInMonth(startDate.Year, startDate.Month) - startDate.Day); + if (repeatOnMonths != eMonthRecurrence.All) AdjustForRepeatOnMonths(ref dt, repeatOnMonths); // Adjust for repeat on Months + while (relCount > 0) + { + dt = dt.AddDays(1); + if (dt.DayOfWeek == relativeDayOfWeek) + relCount--; + } + return dt; + } + } + throw new InvalidOperationException("Could not find the next relative date for monthly recurrence starting on " + startDate.ToString() + " RelativeDayInMonth=" + repeatOnRelativeDayInMonth.ToString() + " RelativeDayOfWeek=" + relativeDayOfWeek.ToString()); + } + + private static Calendar GetCalendar() + { + return CultureInfo.CurrentCulture.Calendar; + } + + /// + /// Generates Yearly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well. + /// + /// Collection to add generated recurrences to + /// Recurrence description, must be of Monthly recurrence type. + /// Start date for generation. + /// End date for generation. + public void GenerateYearlyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate) + { + Appointment app = recurrence.Appointment; + DateTime recurrenceStartDate = DateTimeHelper.MaxDate(recurrence.RecurrenceStartDate, app.EndTime.AddDays(1).Date); + if (recurrenceStartDate > endDate) return; + + if (!(startDate.Month <= recurrence.Yearly.RepeatOnMonth && endDate.Month >= recurrence.Yearly.RepeatOnMonth) && endDate.Subtract(startDate).TotalDays < 28) + return; + int totalRecurrences = 0; + // Check the range first + if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate) + { + if (startDate > recurrence.RangeEndDate) return; + } + else if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && recurrence.RangeNumberOfOccurrences > 0 && recurrenceStartDate < startDate) + { + int count = recurrence.RangeNumberOfOccurrences + 1; + DateTime testDate = DateTimeHelper.BeginningOfDay(recurrenceStartDate.AddDays(-(recurrenceStartDate.Day - 1))).AddMonths(-1); + if (testDate < app.EndTime) + testDate = app.EndTime.Date.AddDays(1); + DateTime startDateOnly = DateTimeHelper.BeginningOfDay(startDate); + while (count > 0 && testDate < startDateOnly) + { + testDate = GetNextYearlyRecurrence(recurrence, testDate); + if (testDate >= startDateOnly) break; + count--; + totalRecurrences++; + } + if (count == 0) return; + } + + DateTime currentDate = DateTimeHelper.MaxDate(startDate, recurrenceStartDate).AddDays(-1); + if (recurrence.Yearly.RepeatInterval > 1) + currentDate = recurrenceStartDate; + do + { + currentDate = GetNextYearlyRecurrence(recurrence, currentDate); + + if (recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeEndDate && currentDate > recurrence.RangeEndDate || + recurrence.RangeLimitType == eRecurrenceRangeLimitType.RangeNumberOfOccurrences && totalRecurrences >= recurrence.RangeNumberOfOccurrences) + break; + + if (currentDate >= startDate && currentDate <= endDate && !IsIgnoredRecurrence(currentDate, recurrence)) + { + subsetCollection.Add(CreateRecurringAppointmentInstance(currentDate, app)); + totalRecurrences++; + } + } while (currentDate <= endDate); + } + internal static DateTime GetNextYearlyRecurrence(AppointmentRecurrence recurrence, DateTime startDate) + { + YearlyRecurrenceSettings yearly = recurrence.Yearly; + if (yearly.RepeatInterval > 1) + { + DateTime currentDate = startDate; + for (int i = 0; i < yearly.RepeatInterval; i++) + { + currentDate = GetNextSingleYearlyRecurrence(recurrence, currentDate); + } + return currentDate; + } + else + { + return GetNextSingleYearlyRecurrence(recurrence, startDate); + } + } + internal static DateTime GetNextSingleYearlyRecurrence(AppointmentRecurrence recurrence, DateTime startDate) + { + YearlyRecurrenceSettings yearly = recurrence.Yearly; + Calendar cal = GetCalendar(); + + if (startDate.Month < yearly.RepeatOnMonth) + { + startDate = startDate.AddMonths((yearly.RepeatOnMonth - startDate.Month) - 1); + return GetNextMonthlyRecurrence(startDate, yearly.RepeatOnRelativeDayInMonth, yearly.RelativeDayOfWeek, yearly.RepeatOnDayOfMonth, eMonthRecurrence.All); + } + else if (startDate.Month == yearly.RepeatOnMonth) + { + DateTime refDate = startDate.AddDays(-(startDate.Day)); + DateTime ret = GetNextMonthlyRecurrence(refDate, yearly.RepeatOnRelativeDayInMonth, yearly.RelativeDayOfWeek, yearly.RepeatOnDayOfMonth, eMonthRecurrence.All); + if (ret > startDate) return ret; + } + + // Forward to next year and right month + startDate = startDate.AddDays(cal.GetDaysInYear(startDate.Year) - startDate.DayOfYear).AddMonths(yearly.RepeatOnMonth - 1); + return GetNextMonthlyRecurrence(startDate, yearly.RepeatOnRelativeDayInMonth, yearly.RelativeDayOfWeek, yearly.RepeatOnDayOfMonth, eMonthRecurrence.All); + } + + #endregion + } + + internal interface IRecurrenceGenerator + { + /// + /// Generates Daily recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well. + /// + /// Collection to add generated recurrences to + /// Recurrence description, must be of Daily recurrence type. + /// Start date for generation. + /// End date for generation. + void GenerateDailyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate); + + /// + /// Generates Weekly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well. + /// + /// Collection to add generated recurrences to + /// Recurrence description, must be of Weekly recurrence type. + /// Start date for generation. + /// End date for generation. + void GenerateWeeklyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate); + + /// + /// Generates Monthly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well. + /// + /// Collection to add generated recurrences to + /// Recurrence description, must be of Monthly recurrence type. + /// Start date for generation. + /// End date for generation. + void GenerateMonthlyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate); + + /// < + /// summary> + /// Generates Yearly recurring appointments. If appointment is assigned to calendar method must populate the Calendar.Appointments collection as well. + ///
+ /// Collection to add generated recurrences to + /// Recurrence description, must be of Monthly recurrence type. + /// Start date for generation. + /// End date for generation. + void GenerateYearlyRecurrence(AppointmentSubsetCollection subsetCollection, AppointmentRecurrence recurrence, DateTime startDate, DateTime endDate); + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Reminder.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Reminder.cs new file mode 100644 index 00000000..070de8c3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Reminder.cs @@ -0,0 +1,482 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents an appointment reminder. + /// + public class Reminder + { + #region Private variables + private bool _NotificationRequestRegistered = false; + + #endregion + + #region Constructors + /// + /// Initializes a new instance of the Reminder class. + /// + public Reminder() + { + } + + /// + /// Initializes a new instance of the Reminder class. + /// + /// + public Reminder(DateTime reminderTime) + { + ReminderTime = reminderTime; + } + + /// + /// Initializes a new instance of the Reminder class. + /// + /// + /// + public Reminder(string description, DateTime reminderTime) + { + Description = description; + ReminderTime = reminderTime; + } + #endregion + + #region Events + /// + /// Occurs when ReminderTime has been reached. Note that event handler will be called on the thread of System.Timer which is different + /// than UI thread. You should use BeginInvoke calls to marshal the calls to your UI thread. + /// + [Description("Occurs when ReminderTime has been reached.")] + public event ReminderEventHandler ReminderNotification; + + #endregion + + #region Internal Implementation + private bool _IsActiveForPastAppointments = true; + /// + /// Gets or sets whether reminder will be active for appointments that are in the past. Default value is true. + /// This property is useful if you are creating recurring appointments with reminders that start in past but don't want reminders + /// for past instances of appointment to be active. + /// + public bool IsActiveForPastAppointments + { + get { return _IsActiveForPastAppointments; } + set + { + if (value != _IsActiveForPastAppointments) + { + bool oldValue = _IsActiveForPastAppointments; + _IsActiveForPastAppointments = value; + OnIsActiveForPastAppointmentsChanged(oldValue, value); + } + } + } + + private void OnIsActiveForPastAppointmentsChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("IsActiveForPastAppointments")); + ReminderCollection parentCollection = this.ParentCollection; + + if (parentCollection != null) + { + Appointment app = this.ParentCollection.Appointment; + if (app != null) + { + UpdateNotifications(); + } + } + } + + private string _Description = ""; + /// + /// Gets or sets the reminder description. + /// + public string Description + { + get { return _Description; } + set + { + if (value != _Description) + { + string oldValue = _Description; + _Description = value; + OnDescriptionChanged(oldValue, _Description); + } + } + } + + private void OnDescriptionChanged(string oldValue, string newValue) + { + + } + + private object _Tag = null; + /// + /// Gets or sets additional data associated with the object. + /// + [DefaultValue(null)] + public object Tag + { + get { return _Tag; } + set + { + if (value != _Tag) + { + object oldValue = _Tag; + _Tag = value; + OnTagChanged(oldValue, value); + } + } + } + + private void OnTagChanged(object oldValue, object newValue) + { + + } + + + /// + /// Gets or sets the date and time reminder will be executed at. + /// + /// Unless you mark reminder as inactive by setting the IsActive=false the reminder will occur next time + /// notifications are updated or when appointment data is loaded. + /// + /// + private DateTime _ReminderTime = DateTime.MinValue; + public DateTime ReminderTime + { + get { return GetTimeZoneDateTime(_ReminderTime); } + set + { + value = GetUTCDateTime(CalendarModel.GetCalendarDateTime(value)); + if (_ReminderTime != value) + { + DateTime oldValue = _ReminderTime; + _ReminderTime = value; + OnReminderTimeChanged(oldValue, _ReminderTime); + } + } + } + + private DateTime GetUTCDateTime(DateTime date) + { + if (date == DateTime.MinValue || date == DateTime.MaxValue || date.Kind == DateTimeKind.Utc) + return date; + return TimeZoneInfo.ConvertTimeToUtc(date); + } + + private DateTime GetTimeZoneDateTime(DateTime date) + { + if (date.Kind != DateTimeKind.Utc) return date; + TimeZoneInfo zone = TimeZoneInfo.Local; + return TimeZoneInfo.ConvertTimeFromUtc(date, zone); + } + + private void OnReminderTimeChanged(DateTime oldValue, DateTime newValue) + { + if (NeedsNotification) + UpdateNotifications(); + } + + private bool NeedsNotification + { + get + { + return _ReminderAction != eReminderAction.None && _IsActive; + } + } + + /// + /// Gets or sets the action performed when reminder time is reached. Default value is Event and Command. + /// + private eReminderAction _ReminderAction = eReminderAction.EventAndCommand; + [DefaultValue(eReminderAction.EventAndCommand)] + public eReminderAction ReminderAction + { + get { return _ReminderAction; } + set + { + if (_ReminderAction != value) + { + eReminderAction oldValue = _ReminderAction; + _ReminderAction = value; + OnReminderActionChanged(oldValue, _ReminderAction); + } + } + } + + private void OnReminderActionChanged(eReminderAction oldValue, eReminderAction newValue) + { + if (oldValue == eReminderAction.None || newValue == eReminderAction.None) + UpdateNotifications(); + } + + internal void UpdateNotifications() + { + if (_Appointment != null && !_IsActiveForPastAppointments && _Appointment.StartTime.Date < DateTime.Today) + { + UnregisterNotification(); + return; + } + + if ((_Appointment != null && _Appointment.Calendar != null || _Parent != null && _Parent.ParentModel != null) && + _IsActive && _ReminderTime > DateTime.MinValue && _ReminderAction != eReminderAction.None) + { + NotificationRequest request = this.NotificationRequest; + RegisterNotification(request); + } + else + { + UnregisterNotification(); + } + } + + private void RegisterNotification(NotificationRequest request) + { + if (_NotificationRequestRegistered) + NotificationServer.UpdateNotification(request); + else + NotificationServer.Register(request); + _NotificationRequestRegistered = true; + } + + private Appointment _Appointment; + /// + /// Gets the Appointment reminder is attached to. + /// + [Browsable(false)] + public Appointment Appointment + { + get { return _Appointment; } + internal set + { + if (_Appointment != value) + { + _Appointment = value; + if (NeedsNotification) UpdateNotifications(); + } + } + } + + private bool _IsActive = true; + /// + /// Gets or sets whether reminder is active. Active reminders fire events or execute commands when + /// reminder time has been reached. Set this value to false to dismiss the reminder. + /// + [DefaultValue(true)] + public bool IsActive + { + get { return _IsActive; } + set + { + if (_IsActive != value) + { + bool oldValue = _IsActive; + _IsActive = value; + OnIsActiveChanged(oldValue, _IsActive); + } + } + } + + private void OnIsActiveChanged(bool oldValue, bool newValue) + { + UpdateNotifications(); + } + + private NotificationRequest _NotificationRequest = null; + private NotificationRequest NotificationRequest + { + get + { + if (_NotificationRequest == null) + { + _NotificationRequest = new NotificationRequest(((_IsSnoozeReminder && _SnoozeDateTime != DateTime.MinValue) ? _SnoozeDateTime : _ReminderTime), new NotificationServerEventHandler(OnReminderNotification)); + } + else + _NotificationRequest.NotificationTime = ((_IsSnoozeReminder && _SnoozeDateTime != DateTime.MinValue) ? _SnoozeDateTime : _ReminderTime); + return _NotificationRequest; + } + set + { + _NotificationRequest = value; + } + } + + private DateTime _SnoozeDateTime = DateTime.MinValue; + /// + /// Gets or sets the next snooze time for the reminder. Use the Snooze method if you want to snooze the reminder correctly. + /// + public DateTime SnoozeDateTime + { + get { return _SnoozeDateTime; } + set + { + value = CalendarModel.GetCalendarDateTime(value); + value = value.Kind == DateTimeKind.Utc ? value : GetUTCDateTime(value); + if (value != _SnoozeDateTime) + { + DateTime oldValue = _SnoozeDateTime; + _SnoozeDateTime = value; + if (_SnoozeDateTime == DateTime.MinValue) + { + this.IsSnoozeReminder = false; + UnregisterNotification(); + } + OnSnoozeDateTimeChanged(oldValue, value); + } + } + } + + private void OnSnoozeDateTimeChanged(DateTime oldValue, DateTime newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("SnoozeDateTime")); + + } + + /// + /// Snoozes reminder so it occurs at specified notification time. This method should be used instead of the SnoozeDateTime property and it will + /// set the SnoozeDateTime property to the next notification time. + /// + /// Next reminder notification time. + public void Snooze(DateTime nextNotificationTime) + { + nextNotificationTime = CalendarModel.GetCalendarDateTime(nextNotificationTime); + DateTime utcTime = nextNotificationTime.Kind == DateTimeKind.Utc ? nextNotificationTime : GetUTCDateTime(nextNotificationTime); + UnregisterNotification(); + this.SnoozeDateTime = nextNotificationTime; + this.IsSnoozeReminder = true; + NotificationRequest request = this.NotificationRequest; + request.NotificationTime = utcTime; + RegisterNotification(request); + } + + private void UnregisterNotification() + { + if (_NotificationRequestRegistered) + { + NotificationServer.Unregister(this.NotificationRequest); + _NotificationRequestRegistered = false; + this.NotificationRequest = null; + } + } + + private void OnReminderNotification(NotificationRequest request, NotificationServerEventArgs e) + { + if (_ReminderAction != eReminderAction.None) + { + this.NotificationRequest = null; + ProcessNotification(); + } + } + + /// + /// Runs the ReminderNotification as if the reminder time has been reached. + /// This method is automatically called by reminder once ReminderTime has been reached. + /// + public void ProcessNotification() + { + if (_Appointment != null && _Appointment.Calendar != null) + _Appointment.Calendar.InvokeReminderNotification(this); + else if (_Parent != null && _Parent.ParentModel != null) + _Parent.ParentModel.InvokeReminderNotification(this); + + if (_ReminderAction == eReminderAction.None) return; + + if ((_ReminderAction & eReminderAction.Event) != 0) + { + OnReminderNotification(new ReminderEventArgs(this)); + } + + if ((_ReminderAction & eReminderAction.Command) != 0) + { + //throw new NotImplementedException(); + } + } + + /// + /// Raises the ReminderNotification event. + /// + /// + protected virtual void OnReminderNotification(ReminderEventArgs eventArgs) + { + ReminderEventHandler h = ReminderNotification; + if (h != null) + h(this, eventArgs); + } + + /// + /// Creates an copy of the reminder. + /// + /// Reminder copy. + public Reminder Copy() + { + Reminder copy = new Reminder(); + copy.Description = _Description; + copy.Tag = _Tag; + copy.IsActive = _IsActive; + copy.ReminderAction = _ReminderAction; + copy.IsActiveForPastAppointments = this.IsActiveForPastAppointments; + if (ReminderNotification != null) + copy.ReminderNotification = (ReminderEventHandler)ReminderNotification.Clone(); + copy.ReminderTime = ReminderTime; + copy.IsSnoozeReminder = _IsSnoozeReminder; + return copy; + } + + private bool _IsSnoozeReminder = false; + /// + /// Gets or sets whether this reminder is snooze reminder usually created by Reminder dialog when user hits the Snooze button. + /// Default value is false. + /// + public bool IsSnoozeReminder + { + get { return _IsSnoozeReminder; } + set + { + _IsSnoozeReminder = value; + } + } + + private ReminderCollection _Parent = null; + internal ReminderCollection ParentCollection + { + get { return _Parent; } + set + { + _Parent = value; + if (NeedsNotification) + UpdateNotifications(); + } + } + #endregion + } + + #region Events Support + public delegate void ReminderEventHandler(object sender, ReminderEventArgs e); + /// + /// Defines arguments for reminder related events. + /// + public class ReminderEventArgs : EventArgs + { + /// + /// Gets the reminder referenced by this event. + /// + public Reminder Reminder = null; + + /// + /// Initializes a new instance of the ReminderEventArgs class. + /// + /// + public ReminderEventArgs(Reminder reminder) + { + Reminder = reminder; + } + } + #endregion +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ReminderCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ReminderCollection.cs new file mode 100644 index 00000000..87193b7f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/ReminderCollection.cs @@ -0,0 +1,107 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents collection of reminders. + /// + public class ReminderCollection : Collection + { + #region Constructor + /// + /// Initializes a new instance of the ReminderCollection class. + /// + /// + public ReminderCollection(Appointment parent) + { + _Appointment = parent; + } + CalendarModel _Model = null; + /// + /// Initializes a new instance of the ReminderCollection class. + /// + /// + public ReminderCollection(CalendarModel parentModel) + { + _Model = parentModel; + } + #endregion + + #region Internal Implementation + protected override void InsertItem(int index, Reminder item) + { + OnBeforeInsert(index, item); + base.InsertItem(index, item); + } + + private void OnBeforeInsert(int index, Reminder item) + { + item.Appointment = _Appointment; + item.ParentCollection = this; + } + + protected override void SetItem(int index, Reminder item) + { + OnBeforeSetItem(index, item); + base.SetItem(index, item); + } + + private void OnBeforeSetItem(int index, Reminder item) + { + this[index].Appointment = null; + this[index].ParentCollection = null; + item.Appointment = _Appointment; + item.ParentCollection = this; + } + + protected override void RemoveItem(int index) + { + OnBeforeRemove(index); + base.RemoveItem(index); + } + + private void OnBeforeRemove(int index) + { + this[index].Appointment = null; + this[index].ParentCollection = null; + } + + protected override void ClearItems() + { + foreach (Reminder item in this) + { + item.Appointment = null; + } + base.ClearItems(); + } + + private Appointment _Appointment; + /// + /// Gets parent appointment. + /// + public Appointment Appointment + { + get { return _Appointment; } + internal set + { + _Appointment = value; + } + } + + /// + /// Gets parent model if collection is custom reminders collection. + /// + public CalendarModel ParentModel + { + get { return _Model; } + internal set { _Model = value; } + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/TimeZoneInfo/NativeMethods.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/TimeZoneInfo/NativeMethods.cs new file mode 100644 index 00000000..c43d93cc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/TimeZoneInfo/NativeMethods.cs @@ -0,0 +1,128 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +namespace DevComponents.Schedule +{ + internal class NativeMethods + { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct TimeZoneInformation + { + [MarshalAs(UnmanagedType.I4)] + public int Bias; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string StandardName; + public NativeMethods.SystemTime StandardDate; + [MarshalAs(UnmanagedType.I4)] + public int StandardBias; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string DaylightName; + public NativeMethods.SystemTime DaylightDate; + [MarshalAs(UnmanagedType.I4)] + public int DaylightBias; + public TimeZoneInformation(NativeMethods.DynamicTimeZoneInformation dtzi) + { + this.Bias = dtzi.Bias; + this.StandardName = dtzi.StandardName; + this.StandardDate = dtzi.StandardDate; + this.StandardBias = dtzi.StandardBias; + this.DaylightName = dtzi.DaylightName; + this.DaylightDate = dtzi.DaylightDate; + this.DaylightBias = dtzi.DaylightBias; + } + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct DynamicTimeZoneInformation + { + [MarshalAs(UnmanagedType.I4)] + public int Bias; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string StandardName; + public NativeMethods.SystemTime StandardDate; + [MarshalAs(UnmanagedType.I4)] + public int StandardBias; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string DaylightName; + public NativeMethods.SystemTime DaylightDate; + [MarshalAs(UnmanagedType.I4)] + public int DaylightBias; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x80)] + public string TimeZoneKeyName; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct SystemTime + { + [MarshalAs(UnmanagedType.U2)] + public short Year; + [MarshalAs(UnmanagedType.U2)] + public short Month; + [MarshalAs(UnmanagedType.U2)] + public short DayOfWeek; + [MarshalAs(UnmanagedType.U2)] + public short Day; + [MarshalAs(UnmanagedType.U2)] + public short Hour; + [MarshalAs(UnmanagedType.U2)] + public short Minute; + [MarshalAs(UnmanagedType.U2)] + public short Second; + [MarshalAs(UnmanagedType.U2)] + public short Milliseconds; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct RegistryTimeZoneInformation + { + [MarshalAs(UnmanagedType.I4)] + public int Bias; + [MarshalAs(UnmanagedType.I4)] + public int StandardBias; + [MarshalAs(UnmanagedType.I4)] + public int DaylightBias; + public NativeMethods.SystemTime StandardDate; + public NativeMethods.SystemTime DaylightDate; + public RegistryTimeZoneInformation(NativeMethods.TimeZoneInformation tzi) + { + this.Bias = tzi.Bias; + this.StandardDate = tzi.StandardDate; + this.StandardBias = tzi.StandardBias; + this.DaylightDate = tzi.DaylightDate; + this.DaylightBias = tzi.DaylightBias; + } + + public RegistryTimeZoneInformation(byte[] bytes) + { + if ((bytes == null) || (bytes.Length != 0x2c)) + { + throw new ArgumentException("Argument_InvalidREG_TZI_FORMAT", "bytes"); + } + this.Bias = BitConverter.ToInt32(bytes, 0); + this.StandardBias = BitConverter.ToInt32(bytes, 4); + this.DaylightBias = BitConverter.ToInt32(bytes, 8); + this.StandardDate.Year = BitConverter.ToInt16(bytes, 12); + this.StandardDate.Month = BitConverter.ToInt16(bytes, 14); + this.StandardDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x10); + this.StandardDate.Day = BitConverter.ToInt16(bytes, 0x12); + this.StandardDate.Hour = BitConverter.ToInt16(bytes, 20); + this.StandardDate.Minute = BitConverter.ToInt16(bytes, 0x16); + this.StandardDate.Second = BitConverter.ToInt16(bytes, 0x18); + this.StandardDate.Milliseconds = BitConverter.ToInt16(bytes, 0x1a); + this.DaylightDate.Year = BitConverter.ToInt16(bytes, 0x1c); + this.DaylightDate.Month = BitConverter.ToInt16(bytes, 30); + this.DaylightDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x20); + this.DaylightDate.Day = BitConverter.ToInt16(bytes, 0x22); + this.DaylightDate.Hour = BitConverter.ToInt16(bytes, 0x24); + this.DaylightDate.Minute = BitConverter.ToInt16(bytes, 0x26); + this.DaylightDate.Second = BitConverter.ToInt16(bytes, 40); + this.DaylightDate.Milliseconds = BitConverter.ToInt16(bytes, 0x2a); + } + } + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/TimeZoneInfo/TimeZoneInfo.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/TimeZoneInfo/TimeZoneInfo.cs new file mode 100644 index 00000000..3f5c7568 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/TimeZoneInfo/TimeZoneInfo.cs @@ -0,0 +1,2655 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Security.Permissions; +using System.Runtime.Serialization; +using System.Globalization; +using System.Security; +using Microsoft.Win32; +using System.Runtime.InteropServices; +using System.Security.AccessControl; +using System.IO; +using System.Runtime.ConstrainedExecution; + +namespace DevComponents.Schedule +{ + [Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] + public sealed class TimeZoneInfo : IEquatable, ISerializable, IDeserializationCallback + { + // Fields + private const string c_daylightValue = "Dlt"; + private const string c_disableDST = "DisableAutoDaylightTimeSet"; + private const string c_disableDynamicDST = "DynamicDaylightTimeDisabled"; + private const string c_displayValue = "Display"; + private const string c_firstEntryValue = "FirstEntry"; + private const string c_lastEntryValue = "LastEntry"; + private const string c_localId = "Local"; + private const int c_maxKeyLength = 0xff; + private const string c_muiDaylightValue = "MUI_Dlt"; + private const string c_muiDisplayValue = "MUI_Display"; + private const string c_muiStandardValue = "MUI_Std"; + private const string c_standardValue = "Std"; + private const long c_ticksPerDay = 0xc92a69c000L; + private const long c_ticksPerDayRange = 0xc92a6998f0L; + private const long c_ticksPerHour = 0x861c46800L; + private const long c_ticksPerMillisecond = 0x2710L; + private const long c_ticksPerMinute = 0x23c34600L; + private const long c_ticksPerSecond = 0x989680L; + private const string c_timeZoneInfoRegistryHive = @"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"; + private const string c_timeZoneInfoRegistryHivePermissionList = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation"; + private const string c_timeZoneInfoValue = "TZI"; + private const string c_timeZonesRegistryHive = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"; + private const string c_timeZonesRegistryHivePermissionList = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"; + private const string c_utcId = "UTC"; + private AdjustmentRule[] m_adjustmentRules; + private TimeSpan m_baseUtcOffset; + private string m_daylightDisplayName; + private string m_displayName; + private string m_id; + private string m_standardDisplayName; + private bool m_supportsDaylightSavingTime; + private static bool s_allSystemTimeZonesRead = false; + private static object s_hiddenInternalSyncObject; + private static Dictionary s_hiddenSystemTimeZones; + private static TimeZoneInfo s_localTimeZone; + private static List s_readOnlySystemTimeZones; + private static TimeZoneInfo s_utcTimeZone; + + // Methods + private TimeZoneInfo(NativeMethods.TimeZoneInformation zone, bool dstDisabled) + { + if (string.IsNullOrEmpty(zone.StandardName)) + { + this.m_id = "Local"; + } + else + { + this.m_id = zone.StandardName; + } + this.m_baseUtcOffset = new TimeSpan(0, -zone.Bias, 0); + if (!dstDisabled) + { + NativeMethods.RegistryTimeZoneInformation timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation(zone); + AdjustmentRule rule = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date); + if (rule != null) + { + this.m_adjustmentRules = new AdjustmentRule[] { rule }; + } + } + ValidateTimeZoneInfo(this.m_id, this.m_baseUtcOffset, this.m_adjustmentRules, out this.m_supportsDaylightSavingTime); + this.m_displayName = zone.StandardName; + this.m_standardDisplayName = zone.StandardName; + this.m_daylightDisplayName = zone.DaylightName; + } + + private TimeZoneInfo(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + this.m_id = (string)info.GetValue("Id", typeof(string)); + this.m_displayName = (string)info.GetValue("DisplayName", typeof(string)); + this.m_standardDisplayName = (string)info.GetValue("StandardName", typeof(string)); + this.m_daylightDisplayName = (string)info.GetValue("DaylightName", typeof(string)); + this.m_baseUtcOffset = (TimeSpan)info.GetValue("BaseUtcOffset", typeof(TimeSpan)); + this.m_adjustmentRules = (AdjustmentRule[])info.GetValue("AdjustmentRules", typeof(AdjustmentRule[])); + this.m_supportsDaylightSavingTime = (bool)info.GetValue("SupportsDaylightSavingTime", typeof(bool)); + } + + private TimeZoneInfo(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, AdjustmentRule[] adjustmentRules, bool disableDaylightSavingTime) + { + bool flag; + ValidateTimeZoneInfo(id, baseUtcOffset, adjustmentRules, out flag); + if ((!disableDaylightSavingTime && (adjustmentRules != null)) && (adjustmentRules.Length > 0)) + { + this.m_adjustmentRules = (AdjustmentRule[])adjustmentRules.Clone(); + } + this.m_id = id; + this.m_baseUtcOffset = baseUtcOffset; + this.m_displayName = displayName; + this.m_standardDisplayName = standardDisplayName; + this.m_daylightDisplayName = disableDaylightSavingTime ? null : daylightDisplayName; + this.m_supportsDaylightSavingTime = flag && !disableDaylightSavingTime; + } + + [SecurityCritical, SecurityTreatAsSafe] + private static bool CheckDaylightSavingTimeDisabled() + { + try + { + PermissionSet set = new PermissionSet(PermissionState.None); + set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation")); + set.Assert(); + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\TimeZoneInformation", RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) + { + if (key == null) + { + return false; + } + int num = 0; + try + { + num = (int)key.GetValue("DisableAutoDaylightTimeSet", 0, RegistryValueOptions.None); + } + catch (InvalidCastException) + { + } + if (num != 1) + { + try + { + num = (int)key.GetValue("DynamicDaylightTimeDisabled", 0, RegistryValueOptions.None); + } + catch (InvalidCastException) + { + } + if (num != 1) + { + goto Label_009C; + } + } + return true; + } + } + finally + { + PermissionSet.RevertAssert(); + } + Label_009C: + return false; + } + + private static bool CheckDaylightSavingTimeNotSupported(NativeMethods.TimeZoneInformation timeZone) + { + return (((((timeZone.DaylightDate.Year == timeZone.StandardDate.Year) && (timeZone.DaylightDate.Month == timeZone.StandardDate.Month)) && ((timeZone.DaylightDate.DayOfWeek == timeZone.StandardDate.DayOfWeek) && (timeZone.DaylightDate.Day == timeZone.StandardDate.Day))) && (((timeZone.DaylightDate.Hour == timeZone.StandardDate.Hour) && (timeZone.DaylightDate.Minute == timeZone.StandardDate.Minute)) && (timeZone.DaylightDate.Second == timeZone.StandardDate.Second))) && (timeZone.DaylightDate.Milliseconds == timeZone.StandardDate.Milliseconds)); + } + + private static bool CheckIsDst(DateTime startTime, DateTime time, DateTime endTime) + { + if (startTime.Year != endTime.Year) + { + endTime = endTime.AddYears(startTime.Year - endTime.Year); + } + if (startTime.Year != time.Year) + { + time = time.AddYears(startTime.Year - time.Year); + } + if (startTime > endTime) + { + return ((time < endTime) || (time >= startTime)); + } + return ((time >= startTime) && (time < endTime)); + } + + public static void ClearCachedData() + { + lock (s_internalSyncObject) + { + s_localTimeZone = null; + s_utcTimeZone = null; + s_systemTimeZones = null; + s_readOnlySystemTimeZones = null; + s_allSystemTimeZonesRead = false; + } + } + + public static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo destinationTimeZone) + { + if (destinationTimeZone == null) + { + throw new ArgumentNullException("destinationTimeZone"); + } + if (dateTime.Kind == DateTimeKind.Utc) + { + lock (s_internalSyncObject) + { + return ConvertTime(dateTime, Utc, destinationTimeZone); + } + } + lock (s_internalSyncObject) + { + return ConvertTime(dateTime, Local, destinationTimeZone); + } + } + + public static DateTimeOffset ConvertTime(DateTimeOffset dateTimeOffset, TimeZoneInfo destinationTimeZone) + { + if (destinationTimeZone == null) + { + throw new ArgumentNullException("destinationTimeZone"); + } + DateTime utcDateTime = dateTimeOffset.UtcDateTime; + TimeSpan utcOffsetFromUtc = GetUtcOffsetFromUtc(utcDateTime, destinationTimeZone); + long ticks = utcDateTime.Ticks + utcOffsetFromUtc.Ticks; + if (ticks > DateTimeOffset.MaxValue.Ticks) + { + return DateTimeOffset.MaxValue; + } + if (ticks < DateTimeOffset.MinValue.Ticks) + { + return DateTimeOffset.MinValue; + } + return new DateTimeOffset(ticks, utcOffsetFromUtc); + } + + public static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone) + { + return ConvertTime(dateTime, sourceTimeZone, destinationTimeZone, TimeZoneInfoOptions.None); + } + + internal static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone, TimeZoneInfoOptions flags) + { + if (sourceTimeZone == null) + { + throw new ArgumentNullException("sourceTimeZone"); + } + if (destinationTimeZone == null) + { + throw new ArgumentNullException("destinationTimeZone"); + } + DateTimeKind correspondingKind = sourceTimeZone.GetCorrespondingKind(); + if ((((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && (dateTime.Kind != DateTimeKind.Unspecified)) && (dateTime.Kind != correspondingKind)) + { + throw new ArgumentException("Argument_ConvertMismatch", "sourceTimeZone"); + } + AdjustmentRule adjustmentRuleForTime = sourceTimeZone.GetAdjustmentRuleForTime(dateTime); + TimeSpan baseUtcOffset = sourceTimeZone.BaseUtcOffset; + if (adjustmentRuleForTime != null) + { + bool flag = false; + DaylightTime daylightTime = GetDaylightTime(dateTime.Year, adjustmentRuleForTime); + if (((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && GetIsInvalidTime(dateTime, adjustmentRuleForTime, daylightTime)) + { + throw new ArgumentException("Argument_DateTimeIsInvalid", "dateTime"); + } + flag = GetIsDaylightSavings(dateTime, adjustmentRuleForTime, daylightTime); + baseUtcOffset += flag ? adjustmentRuleForTime.DaylightDelta : TimeSpan.Zero; + } + DateTimeKind kind = destinationTimeZone.GetCorrespondingKind(); + if (((dateTime.Kind != DateTimeKind.Unspecified) && (correspondingKind != DateTimeKind.Unspecified)) && (correspondingKind == kind)) + { + return dateTime; + } + long ticks = dateTime.Ticks - baseUtcOffset.Ticks; + DateTime time2 = ConvertUtcToTimeZone(ticks, destinationTimeZone); + if (kind == DateTimeKind.Local) + { + kind = DateTimeKind.Unspecified; + } + return new DateTime(time2.Ticks, kind); + } + + public static DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, string destinationTimeZoneId) + { + return ConvertTime(dateTime, FindSystemTimeZoneById(destinationTimeZoneId)); + } + + public static DateTimeOffset ConvertTimeBySystemTimeZoneId(DateTimeOffset dateTimeOffset, string destinationTimeZoneId) + { + return ConvertTime(dateTimeOffset, FindSystemTimeZoneById(destinationTimeZoneId)); + } + + public static DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, string sourceTimeZoneId, string destinationTimeZoneId) + { + if ((dateTime.Kind == DateTimeKind.Local) && (string.Compare(sourceTimeZoneId, Local.Id, StringComparison.OrdinalIgnoreCase) == 0)) + { + lock (s_internalSyncObject) + { + return ConvertTime(dateTime, Local, FindSystemTimeZoneById(destinationTimeZoneId)); + } + } + if ((dateTime.Kind == DateTimeKind.Utc) && (string.Compare(sourceTimeZoneId, Utc.Id, StringComparison.OrdinalIgnoreCase) == 0)) + { + lock (s_internalSyncObject) + { + return ConvertTime(dateTime, Utc, FindSystemTimeZoneById(destinationTimeZoneId)); + } + } + return ConvertTime(dateTime, FindSystemTimeZoneById(sourceTimeZoneId), FindSystemTimeZoneById(destinationTimeZoneId)); + } + + public static DateTime ConvertTimeFromUtc(DateTime dateTime, TimeZoneInfo destinationTimeZone) + { + lock (s_internalSyncObject) + { + return ConvertTime(dateTime, Utc, destinationTimeZone); + } + } + + public static DateTime ConvertTimeToUtc(DateTime dateTime) + { + if (dateTime.Kind == DateTimeKind.Utc) + { + return dateTime; + } + lock (s_internalSyncObject) + { + return ConvertTime(dateTime, Local, Utc); + } + } + + public static DateTime ConvertTimeToUtc(DateTime dateTime, TimeZoneInfo sourceTimeZone) + { + lock (s_internalSyncObject) + { + return ConvertTime(dateTime, sourceTimeZone, Utc); + } + } + + private static DateTime ConvertUtcToTimeZone(long ticks, TimeZoneInfo destinationTimeZone) + { + DateTime maxValue; + if (ticks > DateTime.MaxValue.Ticks) + { + maxValue = DateTime.MaxValue; + } + else if (ticks < DateTime.MinValue.Ticks) + { + maxValue = DateTime.MinValue; + } + else + { + maxValue = new DateTime(ticks); + } + TimeSpan utcOffsetFromUtc = GetUtcOffsetFromUtc(maxValue, destinationTimeZone); + ticks += utcOffsetFromUtc.Ticks; + if (ticks > DateTime.MaxValue.Ticks) + { + return DateTime.MaxValue; + } + if (ticks < DateTime.MinValue.Ticks) + { + return DateTime.MinValue; + } + return new DateTime(ticks); + } + + private static AdjustmentRule CreateAdjustmentRuleFromTimeZoneInformation(NativeMethods.RegistryTimeZoneInformation timeZoneInformation, DateTime startDate, DateTime endDate) + { + if (timeZoneInformation.StandardDate.Month == 0) + { + return null; + } + TransitionTime? nullable = TransitionTimeFromTimeZoneInformation(timeZoneInformation, true); + if (!nullable.HasValue) + { + return null; + } + TransitionTime? nullable2 = TransitionTimeFromTimeZoneInformation(timeZoneInformation, false); + if (!nullable2.HasValue) + { + return null; + } + if (nullable.Equals(nullable2)) + { + return null; + } + return AdjustmentRule.CreateAdjustmentRule(startDate, endDate, new TimeSpan(0, -timeZoneInformation.DaylightBias, 0), nullable.Value, nullable2.Value); + } + + public static TimeZoneInfo CreateCustomTimeZone(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName) + { + return new TimeZoneInfo(id, baseUtcOffset, displayName, standardDisplayName, standardDisplayName, null, false); + } + + public static TimeZoneInfo CreateCustomTimeZone(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, AdjustmentRule[] adjustmentRules) + { + return new TimeZoneInfo(id, baseUtcOffset, displayName, standardDisplayName, daylightDisplayName, adjustmentRules, false); + } + + public static TimeZoneInfo CreateCustomTimeZone(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, AdjustmentRule[] adjustmentRules, bool disableDaylightSavingTime) + { + return new TimeZoneInfo(id, baseUtcOffset, displayName, standardDisplayName, daylightDisplayName, adjustmentRules, disableDaylightSavingTime); + } + + public bool Equals(TimeZoneInfo other) + { + return (((other != null) && (string.Compare(this.m_id, other.m_id, StringComparison.OrdinalIgnoreCase) == 0)) && this.HasSameRules(other)); + } + + [SecurityCritical, SecurityTreatAsSafe] + private static string FindIdFromTimeZoneInformation(NativeMethods.TimeZoneInformation timeZone, out bool dstDisabled) + { + dstDisabled = false; + try + { + PermissionSet set = new PermissionSet(PermissionState.None); + set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones")); + set.Assert(); + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) + { + if (key == null) + { + return null; + } + foreach (string str in key.GetSubKeyNames()) + { + if (TryCompareTimeZoneInformationToRegistry(timeZone, str, out dstDisabled)) + { + return str; + } + } + } + } + finally + { + PermissionSet.RevertAssert(); + } + return null; + } + + public static TimeZoneInfo FindSystemTimeZoneById(string id) + { + if (string.Compare(id, "UTC", StringComparison.OrdinalIgnoreCase) == 0) + { + return Utc; + } + lock (s_internalSyncObject) + { + return GetTimeZone(id); + } + } + + public static TimeZoneInfo FromSerializedString(string source) + { + if (source == null) + { + throw new ArgumentNullException("source"); + } + if (source.Length == 0) + { + throw new ArgumentException("Argument_InvalidSerializedString source"); + } + return StringSerializer.GetDeserializedTimeZoneInfo(source); + } + + private AdjustmentRule GetAdjustmentRuleForTime(DateTime dateTime) + { + if ((this.m_adjustmentRules != null) && (this.m_adjustmentRules.Length != 0)) + { + DateTime date = dateTime.Date; + for (int i = 0; i < this.m_adjustmentRules.Length; i++) + { + if ((this.m_adjustmentRules[i].DateStart <= date) && (this.m_adjustmentRules[i].DateEnd >= date)) + { + return this.m_adjustmentRules[i]; + } + } + } + return null; + } + + public AdjustmentRule[] GetAdjustmentRules() + { + if (this.m_adjustmentRules == null) + { + return new AdjustmentRule[0]; + } + return (AdjustmentRule[])this.m_adjustmentRules.Clone(); + } + + public TimeSpan[] GetAmbiguousTimeOffsets(DateTime dateTime) + { + DateTime time; + bool flag; + if (!this.m_supportsDaylightSavingTime) + { + throw new ArgumentException("Argument_DateTimeIsNotAmbiguous", "dateTime"); + } + if (dateTime.Kind == DateTimeKind.Local) + { + lock (s_internalSyncObject) + { + time = ConvertTime(dateTime, Local, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); + goto Label_007D; + } + } + if (dateTime.Kind == DateTimeKind.Utc) + { + lock (s_internalSyncObject) + { + time = ConvertTime(dateTime, Utc, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); + goto Label_007D; + } + } + time = dateTime; + Label_007D: + flag = false; + AdjustmentRule adjustmentRuleForTime = this.GetAdjustmentRuleForTime(time); + if (adjustmentRuleForTime != null) + { + DaylightTime daylightTime = GetDaylightTime(time.Year, adjustmentRuleForTime); + flag = GetIsAmbiguousTime(time, adjustmentRuleForTime, daylightTime); + } + if (!flag) + { + throw new ArgumentException("Argument_DateTimeIsNotAmbiguous", "dateTime"); + } + TimeSpan[] spanArray = new TimeSpan[2]; + if (adjustmentRuleForTime.DaylightDelta > TimeSpan.Zero) + { + spanArray[0] = this.m_baseUtcOffset; + spanArray[1] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta; + return spanArray; + } + spanArray[0] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta; + spanArray[1] = this.m_baseUtcOffset; + return spanArray; + } + + public TimeSpan[] GetAmbiguousTimeOffsets(DateTimeOffset dateTimeOffset) + { + if (!this.m_supportsDaylightSavingTime) + { + throw new ArgumentException("Argument_DateTimeOffsetIsNotAmbiguous", "dateTimeOffset"); + } + DateTime dateTime = ConvertTime(dateTimeOffset, this).DateTime; + bool flag = false; + AdjustmentRule adjustmentRuleForTime = this.GetAdjustmentRuleForTime(dateTime); + if (adjustmentRuleForTime != null) + { + DaylightTime daylightTime = GetDaylightTime(dateTime.Year, adjustmentRuleForTime); + flag = GetIsAmbiguousTime(dateTime, adjustmentRuleForTime, daylightTime); + } + if (!flag) + { + throw new ArgumentException("Argument_DateTimeOffsetIsNotAmbiguous", "dateTimeOffset"); + } + TimeSpan[] spanArray = new TimeSpan[2]; + if (adjustmentRuleForTime.DaylightDelta > TimeSpan.Zero) + { + spanArray[0] = this.m_baseUtcOffset; + spanArray[1] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta; + return spanArray; + } + spanArray[0] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta; + spanArray[1] = this.m_baseUtcOffset; + return spanArray; + } + + private DateTimeKind GetCorrespondingKind() + { + if (this == s_utcTimeZone) + { + return DateTimeKind.Utc; + } + if (this == s_localTimeZone) + { + return DateTimeKind.Local; + } + return DateTimeKind.Unspecified; + } + + private static DaylightTime GetDaylightTime(int year, AdjustmentRule rule) + { + TimeSpan daylightDelta = rule.DaylightDelta; + DateTime start = TransitionTimeToDateTime(year, rule.DaylightTransitionStart); + return new DaylightTime(start, TransitionTimeToDateTime(year, rule.DaylightTransitionEnd), daylightDelta); + } + + public override int GetHashCode() + { + return this.m_id.ToUpperInvariant().GetHashCode(); + } + + private static bool GetIsAmbiguousTime(DateTime time, AdjustmentRule rule, DaylightTime daylightTime) + { + bool flag = false; + if ((rule != null) && (rule.DaylightDelta != TimeSpan.Zero)) + { + DateTime end; + DateTime time3; + DateTime time4; + DateTime time5; + if (rule.DaylightDelta > TimeSpan.Zero) + { + end = daylightTime.End; + time3 = daylightTime.End - rule.DaylightDelta; + } + else + { + end = daylightTime.Start; + time3 = daylightTime.Start + rule.DaylightDelta; + } + flag = (time >= time3) && (time < end); + if (flag || (end.Year == time3.Year)) + { + return flag; + } + try + { + time4 = end.AddYears(1); + time5 = time3.AddYears(1); + flag = (time >= time5) && (time < time4); + } + catch (ArgumentOutOfRangeException) + { + } + if (flag) + { + return flag; + } + try + { + time4 = end.AddYears(-1); + time5 = time3.AddYears(-1); + flag = (time >= time5) && (time < time4); + } + catch (ArgumentOutOfRangeException) + { + } + } + return flag; + } + + private static bool GetIsDaylightSavings(DateTime time, AdjustmentRule rule, DaylightTime daylightTime) + { + if (rule == null) + { + return false; + } + bool flag = rule.DaylightDelta > TimeSpan.Zero; + DateTime startTime = daylightTime.Start + (flag ? rule.DaylightDelta : TimeSpan.Zero); + DateTime endTime = daylightTime.End + (flag ? -(rule.DaylightDelta) : TimeSpan.Zero); + return CheckIsDst(startTime, time, endTime); + } + + private static bool GetIsDaylightSavingsFromUtc(DateTime time, int Year, TimeSpan utc, AdjustmentRule rule) + { + if (rule == null) + { + return false; + } + TimeSpan span = utc; + DaylightTime daylightTime = GetDaylightTime(Year, rule); + DateTime startTime = daylightTime.Start - span; + DateTime endTime = (daylightTime.End - span) - rule.DaylightDelta; + return CheckIsDst(startTime, time, endTime); + } + + private static bool GetIsInvalidTime(DateTime time, AdjustmentRule rule, DaylightTime daylightTime) + { + bool flag = false; + if ((rule != null) && (rule.DaylightDelta != TimeSpan.Zero)) + { + DateTime end; + DateTime time3; + DateTime time4; + DateTime time5; + if (rule.DaylightDelta < TimeSpan.Zero) + { + end = daylightTime.End; + time3 = daylightTime.End - rule.DaylightDelta; + } + else + { + end = daylightTime.Start; + time3 = daylightTime.Start + rule.DaylightDelta; + } + flag = (time >= end) && (time < time3); + if (flag || (end.Year == time3.Year)) + { + return flag; + } + try + { + time4 = end.AddYears(1); + time5 = time3.AddYears(1); + flag = (time >= time4) && (time < time5); + } + catch (ArgumentOutOfRangeException) + { + } + if (flag) + { + return flag; + } + try + { + time4 = end.AddYears(-1); + time5 = time3.AddYears(-1); + flag = (time >= time4) && (time < time5); + } + catch (ArgumentOutOfRangeException) + { + } + } + return flag; + } + + [SecurityCritical] + private static TimeZoneInfo GetLocalTimeZone() + { + string id = null; + try + { + TimeZoneInfo info; + Exception exception; + TimeZoneInfo info2; + Exception exception2; + NativeMethods.DynamicTimeZoneInformation lpDynamicTimeZoneInformation = new NativeMethods.DynamicTimeZoneInformation(); + long dynamicTimeZoneInformation = UnsafeNativeMethods.GetDynamicTimeZoneInformation(out lpDynamicTimeZoneInformation); + if (dynamicTimeZoneInformation == -1L) + { + return CreateCustomTimeZone("Local", TimeSpan.Zero, "Local", "Local"); + } + NativeMethods.TimeZoneInformation timeZone = new NativeMethods.TimeZoneInformation(lpDynamicTimeZoneInformation); + bool dstDisabled = CheckDaylightSavingTimeDisabled(); + if (!string.IsNullOrEmpty(lpDynamicTimeZoneInformation.TimeZoneKeyName) && (TryGetTimeZone(lpDynamicTimeZoneInformation.TimeZoneKeyName, dstDisabled, out info, out exception) == TimeZoneInfoResult.Success)) + { + return info; + } + id = FindIdFromTimeZoneInformation(timeZone, out dstDisabled); + if ((id != null) && (TryGetTimeZone(id, dstDisabled, out info2, out exception2) == TimeZoneInfoResult.Success)) + { + return info2; + } + return GetLocalTimeZoneFromWin32Data(timeZone, dstDisabled); + } + catch (EntryPointNotFoundException) + { + bool flag2; + TimeZoneInfo info3; + Exception exception3; + NativeMethods.TimeZoneInformation lpTimeZoneInformation = new NativeMethods.TimeZoneInformation(); + long timeZoneInformation = UnsafeNativeMethods.GetTimeZoneInformation(out lpTimeZoneInformation); + if (timeZoneInformation == -1L) + { + return CreateCustomTimeZone("Local", TimeSpan.Zero, "Local", "Local"); + } + id = FindIdFromTimeZoneInformation(lpTimeZoneInformation, out flag2); + if ((id != null) && (TryGetTimeZone(id, flag2, out info3, out exception3) == TimeZoneInfoResult.Success)) + { + return info3; + } + return GetLocalTimeZoneFromWin32Data(lpTimeZoneInformation, flag2); + } + } + + private static TimeZoneInfo GetLocalTimeZoneFromWin32Data(NativeMethods.TimeZoneInformation timeZoneInformation, bool dstDisabled) + { + TimeZoneInfo info = null; + try + { + info = new TimeZoneInfo(timeZoneInformation, dstDisabled); + } + catch (ArgumentException) + { + } + catch (InvalidTimeZoneException) + { + } + return info; + try + { + info = new TimeZoneInfo(timeZoneInformation, true); + } + catch (ArgumentException) + { + } + catch (InvalidTimeZoneException) + { + } + return info; + } + + [SecurityTreatAsSafe, SecurityCritical] + public static List GetSystemTimeZones() + { + lock (s_internalSyncObject) + { + if (!s_allSystemTimeZonesRead) + { + PermissionSet set = new PermissionSet(PermissionState.None); + set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones")); + set.Assert(); + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) + { + if (key == null) + { + List list; + if (s_systemTimeZones != null) + { + list = new List(s_systemTimeZones.Values); + } + else + { + list = new List(); + } + s_readOnlySystemTimeZones = new List(list); + s_allSystemTimeZonesRead = true; + return s_readOnlySystemTimeZones; + } + foreach (string str in key.GetSubKeyNames()) + { + TimeZoneInfo info; + Exception exception; + TryGetTimeZone(str, false, out info, out exception); + } + } + IComparer comparer = new TimeZoneInfoComparer(); + List list2 = new List(s_systemTimeZones.Values); + list2.Sort(comparer); + s_readOnlySystemTimeZones = new List(list2); + s_allSystemTimeZonesRead = true; + } + return s_readOnlySystemTimeZones; + } + } + + private static TimeZoneInfo GetTimeZone(string id) + { + TimeZoneInfo info; + Exception exception; + if (id == null) + { + throw new ArgumentNullException("id"); + } + if (((id.Length == 0) || (id.Length > 0xff)) || id.Contains("\0")) + { + throw new TimeZoneNotFoundException("TimeZoneNotFound_MissingRegistryData, id"); + } + switch (TryGetTimeZone(id, false, out info, out exception)) + { + case TimeZoneInfoResult.Success: + return info; + + case TimeZoneInfoResult.InvalidTimeZoneException: + throw new InvalidTimeZoneException("InvalidTimeZone_InvalidRegistryData, id", exception); + + case TimeZoneInfoResult.SecurityException: + throw new SecurityException("Security_CannotReadRegistryData, id", exception); + } + throw new TimeZoneNotFoundException("TimeZoneNotFound_MissingRegistryData, id", exception); + } + + public TimeSpan GetUtcOffset(DateTime dateTime) + { + if (dateTime.Kind == DateTimeKind.Local) + { + DateTime time; + lock (s_internalSyncObject) + { + if (this.GetCorrespondingKind() == DateTimeKind.Local) + { + return GetUtcOffset(dateTime, this); + } + time = ConvertTime(dateTime, Local, Utc, TimeZoneInfoOptions.NoThrowOnInvalidTime); + } + return GetUtcOffsetFromUtc(time, this); + } + if (dateTime.Kind != DateTimeKind.Utc) + { + return GetUtcOffset(dateTime, this); + } + if (this.GetCorrespondingKind() == DateTimeKind.Utc) + { + return this.m_baseUtcOffset; + } + return GetUtcOffsetFromUtc(dateTime, this); + } + + public TimeSpan GetUtcOffset(DateTimeOffset dateTimeOffset) + { + return GetUtcOffsetFromUtc(dateTimeOffset.UtcDateTime, this); + } + + private static TimeSpan GetUtcOffset(DateTime time, TimeZoneInfo zone) + { + TimeSpan baseUtcOffset = zone.BaseUtcOffset; + AdjustmentRule adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(time); + if (adjustmentRuleForTime != null) + { + DaylightTime daylightTime = GetDaylightTime(time.Year, adjustmentRuleForTime); + bool flag = GetIsDaylightSavings(time, adjustmentRuleForTime, daylightTime); + baseUtcOffset += flag ? adjustmentRuleForTime.DaylightDelta : TimeSpan.Zero; + } + return baseUtcOffset; + } + + private static TimeSpan GetUtcOffsetFromUtc(DateTime time, TimeZoneInfo zone) + { + bool flag; + return GetUtcOffsetFromUtc(time, zone, out flag); + } + + private static TimeSpan GetUtcOffsetFromUtc(DateTime time, TimeZoneInfo zone, out bool isDaylightSavings) + { + int year; + AdjustmentRule adjustmentRuleForTime; + isDaylightSavings = false; + TimeSpan baseUtcOffset = zone.BaseUtcOffset; + if (time > new DateTime(0x270f, 12, 0x1f)) + { + adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(DateTime.MaxValue); + year = 0x270f; + } + else if (time < new DateTime(1, 1, 2)) + { + adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(DateTime.MinValue); + year = 1; + } + else + { + DateTime dateTime = time + baseUtcOffset; + year = time.Year; + adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(dateTime); + } + if (adjustmentRuleForTime != null) + { + isDaylightSavings = GetIsDaylightSavingsFromUtc(time, year, zone.m_baseUtcOffset, adjustmentRuleForTime); + baseUtcOffset += isDaylightSavings ? adjustmentRuleForTime.DaylightDelta : TimeSpan.Zero; + } + return baseUtcOffset; + } + + public bool HasSameRules(TimeZoneInfo other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + if ((this.m_baseUtcOffset != other.m_baseUtcOffset) || (this.m_supportsDaylightSavingTime != other.m_supportsDaylightSavingTime)) + { + return false; + } + AdjustmentRule[] adjustmentRules = this.m_adjustmentRules; + AdjustmentRule[] ruleArray2 = other.m_adjustmentRules; + bool flag = ((adjustmentRules == null) && (ruleArray2 == null)) || ((adjustmentRules != null) && (ruleArray2 != null)); + if (!flag) + { + return false; + } + if (adjustmentRules != null) + { + if (adjustmentRules.Length != ruleArray2.Length) + { + return false; + } + for (int i = 0; i < adjustmentRules.Length; i++) + { + if (!adjustmentRules[i].Equals(ruleArray2[i])) + { + return false; + } + } + } + return flag; + } + + public bool IsAmbiguousTime(DateTime dateTime) + { + DateTime time; + AdjustmentRule rule; + if (!this.m_supportsDaylightSavingTime) + { + return false; + } + if (dateTime.Kind == DateTimeKind.Local) + { + lock (s_internalSyncObject) + { + time = ConvertTime(dateTime, Local, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); + goto Label_0068; + } + } + if (dateTime.Kind == DateTimeKind.Utc) + { + lock (s_internalSyncObject) + { + time = ConvertTime(dateTime, Utc, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); + goto Label_0068; + } + } + time = dateTime; + Label_0068: + rule = this.GetAdjustmentRuleForTime(time); + if (rule != null) + { + DaylightTime daylightTime = GetDaylightTime(time.Year, rule); + return GetIsAmbiguousTime(time, rule, daylightTime); + } + return false; + } + + public bool IsAmbiguousTime(DateTimeOffset dateTimeOffset) + { + if (!this.m_supportsDaylightSavingTime) + { + return false; + } + DateTimeOffset offset = ConvertTime(dateTimeOffset, this); + return this.IsAmbiguousTime(offset.DateTime); + } + + public bool IsDaylightSavingTime(DateTime dateTime) + { + DateTime time; + AdjustmentRule rule; + if (!this.m_supportsDaylightSavingTime || (this.m_adjustmentRules == null)) + { + return false; + } + if (dateTime.Kind == DateTimeKind.Local) + { + lock (s_internalSyncObject) + { + time = ConvertTime(dateTime, Local, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); + goto Label_0064; + } + } + if (dateTime.Kind == DateTimeKind.Utc) + { + bool flag; + if (this.GetCorrespondingKind() == DateTimeKind.Utc) + { + return false; + } + GetUtcOffsetFromUtc(dateTime, this, out flag); + return flag; + } + time = dateTime; + Label_0064: + rule = this.GetAdjustmentRuleForTime(time); + if (rule != null) + { + DaylightTime daylightTime = GetDaylightTime(time.Year, rule); + return GetIsDaylightSavings(time, rule, daylightTime); + } + return false; + } + + public bool IsDaylightSavingTime(DateTimeOffset dateTimeOffset) + { + bool flag; + GetUtcOffsetFromUtc(dateTimeOffset.UtcDateTime, this, out flag); + return flag; + } + + public bool IsInvalidTime(DateTime dateTime) + { + bool flag = false; + if ((dateTime.Kind != DateTimeKind.Unspecified) && ((dateTime.Kind != DateTimeKind.Local) || (this.GetCorrespondingKind() != DateTimeKind.Local))) + { + return flag; + } + AdjustmentRule adjustmentRuleForTime = this.GetAdjustmentRuleForTime(dateTime); + if (adjustmentRuleForTime != null) + { + DaylightTime daylightTime = GetDaylightTime(dateTime.Year, adjustmentRuleForTime); + return GetIsInvalidTime(dateTime, adjustmentRuleForTime, daylightTime); + } + return false; + } + + void IDeserializationCallback.OnDeserialization(object sender) + { + try + { + bool flag; + ValidateTimeZoneInfo(this.m_id, this.m_baseUtcOffset, this.m_adjustmentRules, out flag); + if (flag != this.m_supportsDaylightSavingTime) + { + throw new SerializationException("Serialization_CorruptField, SupportsDaylightSavingTime" ); + } + } + catch (ArgumentException exception) + { + throw new SerializationException("Serialization_InvalidData", exception); + } + catch (InvalidTimeZoneException exception2) + { + throw new SerializationException("Serialization_InvalidData", exception2); + } + } + + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + info.AddValue("Id", this.m_id); + info.AddValue("DisplayName", this.m_displayName); + info.AddValue("StandardName", this.m_standardDisplayName); + info.AddValue("DaylightName", this.m_daylightDisplayName); + info.AddValue("BaseUtcOffset", this.m_baseUtcOffset); + info.AddValue("AdjustmentRules", this.m_adjustmentRules); + info.AddValue("SupportsDaylightSavingTime", this.m_supportsDaylightSavingTime); + } + + public string ToSerializedString() + { + return StringSerializer.GetSerializedString(this); + } + + public override string ToString() + { + return this.DisplayName; + } + + private static TransitionTime? TransitionTimeFromTimeZoneInformation(NativeMethods.RegistryTimeZoneInformation timeZoneInformation, bool readStartDate) + { + TransitionTime time; + if (timeZoneInformation.StandardDate.Month == 0) + { + return null; + } + if (readStartDate) + { + if (timeZoneInformation.DaylightDate.Year == 0) + { + time = TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, timeZoneInformation.DaylightDate.Hour, timeZoneInformation.DaylightDate.Minute, timeZoneInformation.DaylightDate.Second, timeZoneInformation.DaylightDate.Milliseconds), timeZoneInformation.DaylightDate.Month, timeZoneInformation.DaylightDate.Day, (DayOfWeek)timeZoneInformation.DaylightDate.DayOfWeek); + } + else + { + time = TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, timeZoneInformation.DaylightDate.Hour, timeZoneInformation.DaylightDate.Minute, timeZoneInformation.DaylightDate.Second, timeZoneInformation.DaylightDate.Milliseconds), timeZoneInformation.DaylightDate.Month, timeZoneInformation.DaylightDate.Day); + } + } + else if (timeZoneInformation.StandardDate.Year == 0) + { + time = TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, timeZoneInformation.StandardDate.Hour, timeZoneInformation.StandardDate.Minute, timeZoneInformation.StandardDate.Second, timeZoneInformation.StandardDate.Milliseconds), timeZoneInformation.StandardDate.Month, timeZoneInformation.StandardDate.Day, (DayOfWeek)timeZoneInformation.StandardDate.DayOfWeek); + } + else + { + time = TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, timeZoneInformation.StandardDate.Hour, timeZoneInformation.StandardDate.Minute, timeZoneInformation.StandardDate.Second, timeZoneInformation.StandardDate.Milliseconds), timeZoneInformation.StandardDate.Month, timeZoneInformation.StandardDate.Day); + } + return new TransitionTime?(time); + } + + private static DateTime TransitionTimeToDateTime(int year, TransitionTime transitionTime) + { + DateTime time; + DateTime timeOfDay = transitionTime.TimeOfDay; + if (transitionTime.IsFixedDateRule) + { + int num = DateTime.DaysInMonth(year, transitionTime.Month); + return new DateTime(year, transitionTime.Month, (num < transitionTime.Day) ? num : transitionTime.Day, timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond); + } + if (transitionTime.Week <= 4) + { + time = new DateTime(year, transitionTime.Month, 1, timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond); + int dayOfWeek = (int)time.DayOfWeek; + int num3 = ((int)transitionTime.DayOfWeek) - dayOfWeek; + if (num3 < 0) + { + num3 += 7; + } + num3 += 7 * (transitionTime.Week - 1); + if (num3 > 0) + { + time = time.AddDays((double)num3); + } + return time; + } + int day = DateTime.DaysInMonth(year, transitionTime.Month); + time = new DateTime(year, transitionTime.Month, day, timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond); + int num6 = (int)(time.DayOfWeek - transitionTime.DayOfWeek); + if (num6 < 0) + { + num6 += 7; + } + if (num6 > 0) + { + time = time.AddDays((double)-num6); + } + return time; + } + + private static bool TryCompareStandardDate(NativeMethods.TimeZoneInformation timeZone, NativeMethods.RegistryTimeZoneInformation registryTimeZoneInfo) + { + return ((((((timeZone.Bias == registryTimeZoneInfo.Bias) && (timeZone.StandardBias == registryTimeZoneInfo.StandardBias)) && ((timeZone.StandardDate.Year == registryTimeZoneInfo.StandardDate.Year) && (timeZone.StandardDate.Month == registryTimeZoneInfo.StandardDate.Month))) && (((timeZone.StandardDate.DayOfWeek == registryTimeZoneInfo.StandardDate.DayOfWeek) && (timeZone.StandardDate.Day == registryTimeZoneInfo.StandardDate.Day)) && ((timeZone.StandardDate.Hour == registryTimeZoneInfo.StandardDate.Hour) && (timeZone.StandardDate.Minute == registryTimeZoneInfo.StandardDate.Minute)))) && (timeZone.StandardDate.Second == registryTimeZoneInfo.StandardDate.Second)) && (timeZone.StandardDate.Milliseconds == registryTimeZoneInfo.StandardDate.Milliseconds)); + } + + [SecurityTreatAsSafe, SecurityCritical] + private static bool TryCompareTimeZoneInformationToRegistry(NativeMethods.TimeZoneInformation timeZone, string id, out bool dstDisabled) + { + bool flag2; + dstDisabled = false; + try + { + PermissionSet set = new PermissionSet(PermissionState.None); + set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones")); + set.Assert(); + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", new object[] { @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", id }), RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) + { + NativeMethods.RegistryTimeZoneInformation information; + if (key == null) + { + return false; + } + try + { + information = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue("TZI", null, RegistryValueOptions.None)); + } + catch (InvalidCastException) + { + return false; + } + catch (ArgumentException) + { + return false; + } + if (!TryCompareStandardDate(timeZone, information)) + { + return false; + } + dstDisabled = CheckDaylightSavingTimeDisabled(); + bool flag = (dstDisabled || CheckDaylightSavingTimeNotSupported(timeZone)) || (((((timeZone.DaylightBias == information.DaylightBias) && (timeZone.DaylightDate.Year == information.DaylightDate.Year)) && ((timeZone.DaylightDate.Month == information.DaylightDate.Month) && (timeZone.DaylightDate.DayOfWeek == information.DaylightDate.DayOfWeek))) && (((timeZone.DaylightDate.Day == information.DaylightDate.Day) && (timeZone.DaylightDate.Hour == information.DaylightDate.Hour)) && ((timeZone.DaylightDate.Minute == information.DaylightDate.Minute) && (timeZone.DaylightDate.Second == information.DaylightDate.Second)))) && (timeZone.DaylightDate.Milliseconds == information.DaylightDate.Milliseconds)); + if (flag) + { + string strA = key.GetValue("Std", string.Empty, RegistryValueOptions.None) as string; + flag = string.Compare(strA, timeZone.StandardName, StringComparison.Ordinal) == 0; + } + flag2 = flag; + } + } + finally + { + PermissionSet.RevertAssert(); + } + return flag2; + } + + private static bool TryCreateAdjustmentRules(string id, NativeMethods.RegistryTimeZoneInformation defaultTimeZoneInformation, out AdjustmentRule[] rules, out Exception e) + { + e = null; + try + { + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(CultureInfo.InvariantCulture, @"{0}\{1}\Dynamic DST", new object[] { @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", id }), RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) + { + if (key == null) + { + AdjustmentRule rule = CreateAdjustmentRuleFromTimeZoneInformation(defaultTimeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date); + if (rule == null) + { + rules = null; + } + else + { + rules = new AdjustmentRule[] { rule }; + } + return true; + } + int year = (int)key.GetValue("FirstEntry", -1, RegistryValueOptions.None); + int num2 = (int)key.GetValue("LastEntry", -1, RegistryValueOptions.None); + if (((year == -1) || (num2 == -1)) || (year > num2)) + { + rules = null; + return false; + } + NativeMethods.RegistryTimeZoneInformation timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue(year.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None)); + if (year == num2) + { + AdjustmentRule rule2 = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date); + if (rule2 == null) + { + rules = null; + } + else + { + rules = new AdjustmentRule[] { rule2 }; + } + return true; + } + List list = new List(1); + AdjustmentRule item = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, DateTime.MinValue.Date, new DateTime(year, 12, 0x1f)); + if (item != null) + { + list.Add(item); + } + for (int i = year + 1; i < num2; i++) + { + timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue(i.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None)); + AdjustmentRule rule4 = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, new DateTime(i, 1, 1), new DateTime(i, 12, 0x1f)); + if (rule4 != null) + { + list.Add(rule4); + } + } + timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue(num2.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None)); + AdjustmentRule rule5 = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, new DateTime(num2, 1, 1), DateTime.MaxValue.Date); + if (rule5 != null) + { + list.Add(rule5); + } + rules = list.ToArray(); + if ((rules != null) && (rules.Length == 0)) + { + rules = null; + } + } + } + catch (InvalidCastException exception) + { + rules = null; + e = exception; + return false; + } + catch (ArgumentOutOfRangeException exception2) + { + rules = null; + e = exception2; + return false; + } + catch (ArgumentException exception3) + { + rules = null; + e = exception3; + return false; + } + return true; + } + + [SecurityTreatAsSafe, SecurityCritical, FileIOPermission(SecurityAction.Assert, AllLocalFiles = FileIOPermissionAccess.PathDiscovery)] + private static string TryGetLocalizedNameByMuiNativeResource(string resource) + { + string str; + int num; + if (string.IsNullOrEmpty(resource)) + { + return string.Empty; + } + string[] strArray = resource.Split(new char[] { ',' }, StringSplitOptions.None); + if (strArray.Length != 2) + { + return string.Empty; + } + string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.System); + string str3 = strArray[0].TrimStart(new char[] { '@' }); + try + { + str = Path.Combine(folderPath, str3); + } + catch (ArgumentException) + { + return string.Empty; + } + if (!int.TryParse(strArray[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) + { + return string.Empty; + } + num = -num; + try + { + StringBuilder fileMuiPath = new StringBuilder(260); + fileMuiPath.Length = 260; + int fileMuiPathLength = 260; + int languageLength = 0; + long enumerator = 0L; + if (!UnsafeNativeMethods.GetFileMUIPath(0x10, str, null, ref languageLength, fileMuiPath, ref fileMuiPathLength, ref enumerator)) + { + return string.Empty; + } + return TryGetLocalizedNameByNativeResource(fileMuiPath.ToString(), num); + } + catch (EntryPointNotFoundException) + { + return string.Empty; + } + } + + [SecurityCritical] + private static string TryGetLocalizedNameByNativeResource(string filePath, int resource) + { + if (File.Exists(filePath)) + { + using (SafeLibraryHandle handle = UnsafeNativeMethods.LoadLibraryEx(filePath, IntPtr.Zero, 2)) + { + if (!handle.IsInvalid) + { + StringBuilder buffer = new StringBuilder(500); + buffer.Length = 500; + if (UnsafeNativeMethods.LoadString(handle, resource, buffer, buffer.Length) != 0) + { + return buffer.ToString(); + } + } + } + } + return string.Empty; + } + + private static bool TryGetLocalizedNamesByRegistryKey(RegistryKey key, out string displayName, out string standardName, out string daylightName) + { + displayName = string.Empty; + standardName = string.Empty; + daylightName = string.Empty; + string str = key.GetValue("MUI_Display", string.Empty, RegistryValueOptions.None) as string; + string str2 = key.GetValue("MUI_Std", string.Empty, RegistryValueOptions.None) as string; + string str3 = key.GetValue("MUI_Dlt", string.Empty, RegistryValueOptions.None) as string; + if (!string.IsNullOrEmpty(str)) + { + displayName = TryGetLocalizedNameByMuiNativeResource(str); + } + if (!string.IsNullOrEmpty(str2)) + { + standardName = TryGetLocalizedNameByMuiNativeResource(str2); + } + if (!string.IsNullOrEmpty(str3)) + { + daylightName = TryGetLocalizedNameByMuiNativeResource(str3); + } + if (string.IsNullOrEmpty(displayName)) + { + displayName = key.GetValue("Display", string.Empty, RegistryValueOptions.None) as string; + } + if (string.IsNullOrEmpty(standardName)) + { + standardName = key.GetValue("Std", string.Empty, RegistryValueOptions.None) as string; + } + if (string.IsNullOrEmpty(daylightName)) + { + daylightName = key.GetValue("Dlt", string.Empty, RegistryValueOptions.None) as string; + } + return true; + } + + private static TimeZoneInfoResult TryGetTimeZone(string id, bool dstDisabled, out TimeZoneInfo value, out Exception e) + { + TimeZoneInfoResult success = TimeZoneInfoResult.Success; + e = null; + TimeZoneInfo info = null; + if (s_systemTimeZones.TryGetValue(id, out info)) + { + if (dstDisabled && info.m_supportsDaylightSavingTime) + { + value = CreateCustomTimeZone(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName); + return success; + } + value = new TimeZoneInfo(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName, info.m_daylightDisplayName, info.m_adjustmentRules, false); + return success; + } + if (!s_allSystemTimeZonesRead) + { + success = TryGetTimeZoneByRegistryKey(id, out info, out e); + if (success == TimeZoneInfoResult.Success) + { + s_systemTimeZones.Add(id, info); + if (dstDisabled && info.m_supportsDaylightSavingTime) + { + value = CreateCustomTimeZone(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName); + return success; + } + value = new TimeZoneInfo(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName, info.m_daylightDisplayName, info.m_adjustmentRules, false); + return success; + } + value = null; + return success; + } + success = TimeZoneInfoResult.TimeZoneNotFoundException; + value = null; + return success; + } + + [SecurityCritical, SecurityTreatAsSafe] + private static TimeZoneInfoResult TryGetTimeZoneByRegistryKey(string id, out TimeZoneInfo value, out Exception e) + { + TimeZoneInfoResult invalidTimeZoneException; + e = null; + try + { + PermissionSet set = new PermissionSet(PermissionState.None); + set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones")); + set.Assert(); + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", new object[] { @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", id }), RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) + { + NativeMethods.RegistryTimeZoneInformation information; + AdjustmentRule[] ruleArray; + string str; + string str2; + string str3; + if (key == null) + { + value = null; + return TimeZoneInfoResult.TimeZoneNotFoundException; + } + try + { + information = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue("TZI", null, RegistryValueOptions.None)); + } + catch (InvalidCastException exception) + { + value = null; + e = exception; + return TimeZoneInfoResult.InvalidTimeZoneException; + } + catch (ArgumentException exception2) + { + value = null; + e = exception2; + return TimeZoneInfoResult.InvalidTimeZoneException; + } + if (!TryCreateAdjustmentRules(id, information, out ruleArray, out e)) + { + value = null; + return TimeZoneInfoResult.InvalidTimeZoneException; + } + if (!TryGetLocalizedNamesByRegistryKey(key, out str, out str2, out str3)) + { + value = null; + invalidTimeZoneException = TimeZoneInfoResult.InvalidTimeZoneException; + } + else + { + try + { + value = new TimeZoneInfo(id, new TimeSpan(0, -information.Bias, 0), str, str2, str3, ruleArray, false); + invalidTimeZoneException = TimeZoneInfoResult.Success; + } + catch (ArgumentException exception3) + { + value = null; + e = exception3; + invalidTimeZoneException = TimeZoneInfoResult.InvalidTimeZoneException; + } + catch (InvalidTimeZoneException exception4) + { + value = null; + e = exception4; + invalidTimeZoneException = TimeZoneInfoResult.InvalidTimeZoneException; + } + } + } + } + finally + { + PermissionSet.RevertAssert(); + } + return invalidTimeZoneException; + } + + internal static bool UtcOffsetOutOfRange(TimeSpan offset) + { + if (offset.TotalHours >= -14.0) + { + return (offset.TotalHours > 14.0); + } + return true; + } + + private static void ValidateTimeZoneInfo(string id, TimeSpan baseUtcOffset, AdjustmentRule[] adjustmentRules, out bool adjustmentRulesSupportDst) + { + adjustmentRulesSupportDst = false; + if (id == null) + { + throw new ArgumentNullException("id"); + } + if (id.Length == 0) + { + throw new ArgumentException("Argument_InvalidId , id"); + } + if (UtcOffsetOutOfRange(baseUtcOffset)) + { + throw new ArgumentOutOfRangeException("baseUtcOffset", "ArgumentOutOfRange_UtcOffset"); + } + if ((baseUtcOffset.Ticks % 0x23c34600L) != 0L) + { + throw new ArgumentException("Argument_TimeSpanHasSeconds", "baseUtcOffset"); + } + if ((adjustmentRules != null) && (adjustmentRules.Length != 0)) + { + adjustmentRulesSupportDst = true; + AdjustmentRule rule = null; + AdjustmentRule rule2 = null; + for (int i = 0; i < adjustmentRules.Length; i++) + { + rule = rule2; + rule2 = adjustmentRules[i]; + if (rule2 == null) + { + throw new InvalidTimeZoneException("Argument_AdjustmentRulesNoNulls"); + } + if (UtcOffsetOutOfRange(baseUtcOffset + rule2.DaylightDelta)) + { + throw new InvalidTimeZoneException("ArgumentOutOfRange_UtcOffsetAndDaylightDelta"); + } + if ((rule != null) && (rule2.DateStart <= rule.DateEnd)) + { + throw new InvalidTimeZoneException("Argument_AdjustmentRulesOutOfOrder"); + } + } + } + } + + // Properties + public TimeSpan BaseUtcOffset + { + get + { + return this.m_baseUtcOffset; + } + } + + public string DaylightName + { + get + { + if (this.m_daylightDisplayName != null) + { + return this.m_daylightDisplayName; + } + return string.Empty; + } + } + + public string DisplayName + { + get + { + if (this.m_displayName != null) + { + return this.m_displayName; + } + return string.Empty; + } + } + + public string Id + { + get + { + return this.m_id; + } + } + + public static TimeZoneInfo Local + { + [SecurityCritical] + get + { + TimeZoneInfo info = s_localTimeZone; + if (info != null) + { + return info; + } + lock (s_internalSyncObject) + { + if (s_localTimeZone == null) + { + TimeZoneInfo localTimeZone = GetLocalTimeZone(); + s_localTimeZone = new TimeZoneInfo(localTimeZone.m_id, localTimeZone.m_baseUtcOffset, localTimeZone.m_displayName, localTimeZone.m_standardDisplayName, localTimeZone.m_daylightDisplayName, localTimeZone.m_adjustmentRules, false); + } + return s_localTimeZone; + } + } + } + + private static object s_internalSyncObject + { + get + { + if (s_hiddenInternalSyncObject == null) + { + object obj2 = new object(); + System.Threading.Interlocked.CompareExchange(ref s_hiddenInternalSyncObject, obj2, null); + } + return s_hiddenInternalSyncObject; + } + } + + private static Dictionary s_systemTimeZones + { + get + { + if (s_hiddenSystemTimeZones == null) + { + s_hiddenSystemTimeZones = new Dictionary(); + } + return s_hiddenSystemTimeZones; + } + set + { + s_hiddenSystemTimeZones = value; + } + } + + public string StandardName + { + get + { + if (this.m_standardDisplayName != null) + { + return this.m_standardDisplayName; + } + return string.Empty; + } + } + + public bool SupportsDaylightSavingTime + { + get + { + return this.m_supportsDaylightSavingTime; + } + } + + public static TimeZoneInfo Utc + { + get + { + TimeZoneInfo info = s_utcTimeZone; + if (info != null) + { + return info; + } + lock (s_internalSyncObject) + { + if (s_utcTimeZone == null) + { + s_utcTimeZone = CreateCustomTimeZone("UTC", TimeSpan.Zero, "UTC", "UTC"); + } + return s_utcTimeZone; + } + } + } + + // Nested Types + [Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true), HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] + public sealed class AdjustmentRule : IEquatable, ISerializable, IDeserializationCallback + { + // Fields + private DateTime m_dateEnd; + private DateTime m_dateStart; + private TimeSpan m_daylightDelta; + private TimeZoneInfo.TransitionTime m_daylightTransitionEnd; + private TimeZoneInfo.TransitionTime m_daylightTransitionStart; + + // Methods + private AdjustmentRule() + { + } + + private AdjustmentRule(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + this.m_dateStart = (DateTime)info.GetValue("DateStart", typeof(DateTime)); + this.m_dateEnd = (DateTime)info.GetValue("DateEnd", typeof(DateTime)); + this.m_daylightDelta = (TimeSpan)info.GetValue("DaylightDelta", typeof(TimeSpan)); + this.m_daylightTransitionStart = (TimeZoneInfo.TransitionTime)info.GetValue("DaylightTransitionStart", typeof(TimeZoneInfo.TransitionTime)); + this.m_daylightTransitionEnd = (TimeZoneInfo.TransitionTime)info.GetValue("DaylightTransitionEnd", typeof(TimeZoneInfo.TransitionTime)); + } + + public static TimeZoneInfo.AdjustmentRule CreateAdjustmentRule(DateTime dateStart, DateTime dateEnd, TimeSpan daylightDelta, TimeZoneInfo.TransitionTime daylightTransitionStart, TimeZoneInfo.TransitionTime daylightTransitionEnd) + { + ValidateAdjustmentRule(dateStart, dateEnd, daylightDelta, daylightTransitionStart, daylightTransitionEnd); + TimeZoneInfo.AdjustmentRule rule = new TimeZoneInfo.AdjustmentRule(); + rule.m_dateStart = dateStart; + rule.m_dateEnd = dateEnd; + rule.m_daylightDelta = daylightDelta; + rule.m_daylightTransitionStart = daylightTransitionStart; + rule.m_daylightTransitionEnd = daylightTransitionEnd; + return rule; + } + + public bool Equals(TimeZoneInfo.AdjustmentRule other) + { + return ((((((other != null) && (this.m_dateStart == other.m_dateStart)) && (this.m_dateEnd == other.m_dateEnd)) && (this.m_daylightDelta == other.m_daylightDelta)) && this.m_daylightTransitionEnd.Equals(other.m_daylightTransitionEnd)) && this.m_daylightTransitionStart.Equals(other.m_daylightTransitionStart)); + } + + public override int GetHashCode() + { + return this.m_dateStart.GetHashCode(); + } + + void IDeserializationCallback.OnDeserialization(object sender) + { + try + { + ValidateAdjustmentRule(this.m_dateStart, this.m_dateEnd, this.m_daylightDelta, this.m_daylightTransitionStart, this.m_daylightTransitionEnd); + } + catch (ArgumentException exception) + { + throw new SerializationException("Serialization_InvalidData", exception); + } + } + + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + info.AddValue("DateStart", this.m_dateStart); + info.AddValue("DateEnd", this.m_dateEnd); + info.AddValue("DaylightDelta", this.m_daylightDelta); + info.AddValue("DaylightTransitionStart", this.m_daylightTransitionStart); + info.AddValue("DaylightTransitionEnd", this.m_daylightTransitionEnd); + } + + private static void ValidateAdjustmentRule(DateTime dateStart, DateTime dateEnd, TimeSpan daylightDelta, TimeZoneInfo.TransitionTime daylightTransitionStart, TimeZoneInfo.TransitionTime daylightTransitionEnd) + { + if (dateStart.Kind != DateTimeKind.Unspecified) + { + throw new ArgumentException("Argument_DateTimeKindMustBeUnspecified", "dateStart"); + } + if (dateEnd.Kind != DateTimeKind.Unspecified) + { + throw new ArgumentException("Argument_DateTimeKindMustBeUnspecified", "dateEnd"); + } + if (daylightTransitionStart.Equals(daylightTransitionEnd)) + { + throw new ArgumentException("Argument_TransitionTimesAreIdentical", "daylightTransitionEnd"); + } + if (dateStart > dateEnd) + { + throw new ArgumentException("Argument_OutOfOrderDateTimes", "dateStart"); + } + if (TimeZoneInfo.UtcOffsetOutOfRange(daylightDelta)) + { + throw new ArgumentOutOfRangeException("daylightDelta", daylightDelta, "ArgumentOutOfRange_UtcOffset"); + } + if ((daylightDelta.Ticks % 0x23c34600L) != 0L) + { + throw new ArgumentException("Argument_TimeSpanHasSeconds", "daylightDelta"); + } + if (dateStart.TimeOfDay != TimeSpan.Zero) + { + throw new ArgumentException("Argument_DateTimeHasTimeOfDay", "dateStart"); + } + if (dateEnd.TimeOfDay != TimeSpan.Zero) + { + throw new ArgumentException("Argument_DateTimeHasTimeOfDay", "dateEnd"); + } + } + + // Properties + public DateTime DateEnd + { + get + { + return this.m_dateEnd; + } + } + + public DateTime DateStart + { + get + { + return this.m_dateStart; + } + } + + public TimeSpan DaylightDelta + { + get + { + return this.m_daylightDelta; + } + } + + public TimeZoneInfo.TransitionTime DaylightTransitionEnd + { + get + { + return this.m_daylightTransitionEnd; + } + } + + public TimeZoneInfo.TransitionTime DaylightTransitionStart + { + get + { + return this.m_daylightTransitionStart; + } + } + } + + private sealed class StringSerializer + { + // Fields + private const string dateTimeFormat = "MM:dd:yyyy"; + private const char esc = '\\'; + private const string escapedEsc = @"\\"; + private const string escapedLhs = @"\["; + private const string escapedRhs = @"\]"; + private const string escapedSep = @"\;"; + private const string escString = @"\"; + private const int initialCapacityForString = 0x40; + private const char lhs = '['; + private const string lhsString = "["; + private int m_currentTokenStartIndex; + private string m_serializedText; + private State m_state; + private const char rhs = ']'; + private const string rhsString = "]"; + private const char sep = ';'; + private const string sepString = ";"; + private const string timeOfDayFormat = "HH:mm:ss.FFF"; + + // Methods + private StringSerializer(string str) + { + this.m_serializedText = str; + this.m_state = State.StartOfToken; + } + + public static TimeZoneInfo GetDeserializedTimeZoneInfo(string source) + { + TimeZoneInfo info; + TimeZoneInfo.StringSerializer serializer = new TimeZoneInfo.StringSerializer(source); + string nextStringValue = serializer.GetNextStringValue(false); + TimeSpan nextTimeSpanValue = serializer.GetNextTimeSpanValue(false); + string displayName = serializer.GetNextStringValue(false); + string standardDisplayName = serializer.GetNextStringValue(false); + string daylightDisplayName = serializer.GetNextStringValue(false); + TimeZoneInfo.AdjustmentRule[] nextAdjustmentRuleArrayValue = serializer.GetNextAdjustmentRuleArrayValue(false); + try + { + info = TimeZoneInfo.CreateCustomTimeZone(nextStringValue, nextTimeSpanValue, displayName, standardDisplayName, daylightDisplayName, nextAdjustmentRuleArrayValue); + } + catch (ArgumentException exception) + { + throw new SerializationException("Serialization_InvalidData", exception); + } + catch (InvalidTimeZoneException exception2) + { + throw new SerializationException("Serialization_InvalidData", exception2); + } + return info; + } + + private TimeZoneInfo.AdjustmentRule[] GetNextAdjustmentRuleArrayValue(bool canEndWithoutSeparator) + { + List list = new List(1); + int num = 0; + for (TimeZoneInfo.AdjustmentRule rule = this.GetNextAdjustmentRuleValue(true); rule != null; rule = this.GetNextAdjustmentRuleValue(true)) + { + list.Add(rule); + num++; + } + if (!canEndWithoutSeparator) + { + if (this.m_state == State.EndOfLine) + { + throw new SerializationException("Serialization_InvalidData"); + } + if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) + { + throw new SerializationException("Serialization_InvalidData"); + } + } + if (num == 0) + { + return null; + } + return list.ToArray(); + } + + private TimeZoneInfo.AdjustmentRule GetNextAdjustmentRuleValue(bool canEndWithoutSeparator) + { + TimeZoneInfo.AdjustmentRule rule; + if (this.m_state == State.EndOfLine) + { + if (!canEndWithoutSeparator) + { + throw new SerializationException("Serialization_InvalidData"); + } + return null; + } + if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) + { + throw new SerializationException("Serialization_InvalidData"); + } + if (this.m_serializedText[this.m_currentTokenStartIndex] == ';') + { + return null; + } + if (this.m_serializedText[this.m_currentTokenStartIndex] != '[') + { + throw new SerializationException("Serialization_InvalidData"); + } + this.m_currentTokenStartIndex++; + DateTime nextDateTimeValue = this.GetNextDateTimeValue(false, "MM:dd:yyyy"); + DateTime dateEnd = this.GetNextDateTimeValue(false, "MM:dd:yyyy"); + TimeSpan nextTimeSpanValue = this.GetNextTimeSpanValue(false); + TimeZoneInfo.TransitionTime nextTransitionTimeValue = this.GetNextTransitionTimeValue(false); + TimeZoneInfo.TransitionTime daylightTransitionEnd = this.GetNextTransitionTimeValue(false); + if ((this.m_state == State.EndOfLine) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) + { + throw new SerializationException("Serialization_InvalidData"); + } + if (this.m_serializedText[this.m_currentTokenStartIndex] != ']') + { + this.SkipVersionNextDataFields(1); + } + else + { + this.m_currentTokenStartIndex++; + } + try + { + rule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(nextDateTimeValue, dateEnd, nextTimeSpanValue, nextTransitionTimeValue, daylightTransitionEnd); + } + catch (ArgumentException exception) + { + throw new SerializationException("Serialization_InvalidData", exception); + } + if (this.m_currentTokenStartIndex >= this.m_serializedText.Length) + { + this.m_state = State.EndOfLine; + return rule; + } + this.m_state = State.StartOfToken; + return rule; + } + + private DateTime GetNextDateTimeValue(bool canEndWithoutSeparator, string format) + { + DateTime time; + if (!DateTime.TryParseExact(this.GetNextStringValue(canEndWithoutSeparator), format, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out time)) + { + throw new SerializationException("Serialization_InvalidData"); + } + return time; + } + + private int GetNextInt32Value(bool canEndWithoutSeparator) + { + int num; + if (!int.TryParse(this.GetNextStringValue(canEndWithoutSeparator), NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out num)) + { + throw new SerializationException("Serialization_InvalidData"); + } + return num; + } + + private string GetNextStringValue(bool canEndWithoutSeparator) + { + if (this.m_state == State.EndOfLine) + { + if (!canEndWithoutSeparator) + { + throw new SerializationException("Serialization_InvalidData"); + } + return null; + } + if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) + { + throw new SerializationException("Serialization_InvalidData"); + } + State notEscaped = State.NotEscaped; + StringBuilder builder = new StringBuilder(0x40); + for (int i = this.m_currentTokenStartIndex; i < this.m_serializedText.Length; i++) + { + if (notEscaped == State.Escaped) + { + VerifyIsEscapableCharacter(this.m_serializedText[i]); + builder.Append(this.m_serializedText[i]); + notEscaped = State.NotEscaped; + } + else if (notEscaped == State.NotEscaped) + { + switch (this.m_serializedText[i]) + { + case '[': + throw new SerializationException("Serialization_InvalidData"); + + case '\\': + notEscaped = State.Escaped; + break; + + case ']': + if (!canEndWithoutSeparator) + { + throw new SerializationException("Serialization_InvalidData"); + } + this.m_currentTokenStartIndex = i; + this.m_state = State.StartOfToken; + return builder.ToString(); + + case ';': + this.m_currentTokenStartIndex = i + 1; + if (this.m_currentTokenStartIndex >= this.m_serializedText.Length) + { + this.m_state = State.EndOfLine; + } + else + { + this.m_state = State.StartOfToken; + } + return builder.ToString(); + + case '\0': + throw new SerializationException("Serialization_InvalidData"); + + default: + builder.Append(this.m_serializedText[i]); + break; + } + } + } + if (notEscaped == State.Escaped) + { + throw new SerializationException("Serialization_InvalidEscapeSequence"); + } + if (!canEndWithoutSeparator) + { + throw new SerializationException("Serialization_InvalidData"); + } + this.m_currentTokenStartIndex = this.m_serializedText.Length; + this.m_state = State.EndOfLine; + return builder.ToString(); + } + + private TimeSpan GetNextTimeSpanValue(bool canEndWithoutSeparator) + { + TimeSpan span; + int minutes = this.GetNextInt32Value(canEndWithoutSeparator); + try + { + span = new TimeSpan(0, minutes, 0); + } + catch (ArgumentOutOfRangeException exception) + { + throw new SerializationException("Serialization_InvalidData", exception); + } + return span; + } + + private TimeZoneInfo.TransitionTime GetNextTransitionTimeValue(bool canEndWithoutSeparator) + { + TimeZoneInfo.TransitionTime time; + if ((this.m_state == State.EndOfLine) || ((this.m_currentTokenStartIndex < this.m_serializedText.Length) && (this.m_serializedText[this.m_currentTokenStartIndex] == ']'))) + { + throw new SerializationException("Serialization_InvalidData"); + } + if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) + { + throw new SerializationException("Serialization_InvalidData"); + } + if (this.m_serializedText[this.m_currentTokenStartIndex] != '[') + { + throw new SerializationException("Serialization_InvalidData"); + } + this.m_currentTokenStartIndex++; + int num = this.GetNextInt32Value(false); + if ((num != 0) && (num != 1)) + { + throw new SerializationException("Serialization_InvalidData"); + } + DateTime nextDateTimeValue = this.GetNextDateTimeValue(false, "HH:mm:ss.FFF"); + nextDateTimeValue = new DateTime(1, 1, 1, nextDateTimeValue.Hour, nextDateTimeValue.Minute, nextDateTimeValue.Second, nextDateTimeValue.Millisecond); + int month = this.GetNextInt32Value(false); + if (num == 1) + { + int day = this.GetNextInt32Value(false); + try + { + time = TimeZoneInfo.TransitionTime.CreateFixedDateRule(nextDateTimeValue, month, day); + goto Label_015B; + } + catch (ArgumentException exception) + { + throw new SerializationException("Serialization_InvalidData", exception); + } + } + int week = this.GetNextInt32Value(false); + int num5 = this.GetNextInt32Value(false); + try + { + time = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(nextDateTimeValue, month, week, (DayOfWeek)num5); + } + catch (ArgumentException exception2) + { + throw new SerializationException("Serialization_InvalidData", exception2); + } + Label_015B: + if ((this.m_state == State.EndOfLine) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) + { + throw new SerializationException("Serialization_InvalidData"); + } + if (this.m_serializedText[this.m_currentTokenStartIndex] != ']') + { + this.SkipVersionNextDataFields(1); + } + else + { + this.m_currentTokenStartIndex++; + } + bool flag = false; + if ((this.m_currentTokenStartIndex < this.m_serializedText.Length) && (this.m_serializedText[this.m_currentTokenStartIndex] == ';')) + { + this.m_currentTokenStartIndex++; + flag = true; + } + if (!flag && !canEndWithoutSeparator) + { + throw new SerializationException("Serialization_InvalidData"); + } + if (this.m_currentTokenStartIndex >= this.m_serializedText.Length) + { + this.m_state = State.EndOfLine; + return time; + } + this.m_state = State.StartOfToken; + return time; + } + + public static string GetSerializedString(TimeZoneInfo zone) + { + StringBuilder serializedText = new StringBuilder(); + serializedText.Append(SerializeSubstitute(zone.Id)); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(zone.BaseUtcOffset.TotalMinutes.ToString(CultureInfo.InvariantCulture))); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(zone.DisplayName)); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(zone.StandardName)); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(zone.DaylightName)); + serializedText.Append(';'); + TimeZoneInfo.AdjustmentRule[] adjustmentRules = zone.GetAdjustmentRules(); + if ((adjustmentRules != null) && (adjustmentRules.Length > 0)) + { + for (int i = 0; i < adjustmentRules.Length; i++) + { + TimeZoneInfo.AdjustmentRule rule = adjustmentRules[i]; + serializedText.Append('['); + serializedText.Append(SerializeSubstitute(rule.DateStart.ToString("MM:dd:yyyy", DateTimeFormatInfo.InvariantInfo))); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(rule.DateEnd.ToString("MM:dd:yyyy", DateTimeFormatInfo.InvariantInfo))); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(rule.DaylightDelta.TotalMinutes.ToString(CultureInfo.InvariantCulture))); + serializedText.Append(';'); + SerializeTransitionTime(rule.DaylightTransitionStart, serializedText); + serializedText.Append(';'); + SerializeTransitionTime(rule.DaylightTransitionEnd, serializedText); + serializedText.Append(';'); + serializedText.Append(']'); + } + } + serializedText.Append(';'); + return serializedText.ToString(); + } + + private static string SerializeSubstitute(string text) + { + text = text.Replace(@"\", @"\\"); + text = text.Replace("[", @"\["); + text = text.Replace("]", @"\]"); + return text.Replace(";", @"\;"); + } + + private static void SerializeTransitionTime(TimeZoneInfo.TransitionTime time, StringBuilder serializedText) + { + serializedText.Append('['); + serializedText.Append((time.IsFixedDateRule ? 1 : 0).ToString(CultureInfo.InvariantCulture)); + serializedText.Append(';'); + if (time.IsFixedDateRule) + { + serializedText.Append(SerializeSubstitute(time.TimeOfDay.ToString("HH:mm:ss.FFF", DateTimeFormatInfo.InvariantInfo))); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(time.Month.ToString(CultureInfo.InvariantCulture))); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(time.Day.ToString(CultureInfo.InvariantCulture))); + serializedText.Append(';'); + } + else + { + serializedText.Append(SerializeSubstitute(time.TimeOfDay.ToString("HH:mm:ss.FFF", DateTimeFormatInfo.InvariantInfo))); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(time.Month.ToString(CultureInfo.InvariantCulture))); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(time.Week.ToString(CultureInfo.InvariantCulture))); + serializedText.Append(';'); + serializedText.Append(SerializeSubstitute(((int)time.DayOfWeek).ToString(CultureInfo.InvariantCulture))); + serializedText.Append(';'); + } + serializedText.Append(']'); + } + + private void SkipVersionNextDataFields(int depth) + { + if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) + { + throw new SerializationException("Serialization_InvalidData"); + } + State notEscaped = State.NotEscaped; + for (int i = this.m_currentTokenStartIndex; i < this.m_serializedText.Length; i++) + { + switch (notEscaped) + { + case State.Escaped: + { + VerifyIsEscapableCharacter(this.m_serializedText[i]); + notEscaped = State.NotEscaped; + continue; + } + case State.NotEscaped: + switch (this.m_serializedText[i]) + { + case '[': + { + depth++; + continue; + } + case '\\': + { + notEscaped = State.Escaped; + continue; + } + case ']': + depth--; + if (depth != 0) + { + continue; + } + this.m_currentTokenStartIndex = i + 1; + if (this.m_currentTokenStartIndex < this.m_serializedText.Length) + { + goto Label_00B5; + } + this.m_state = State.EndOfLine; + return; + + case '\0': + throw new SerializationException("Serialization_InvalidData"); + } + break; + } + continue; + Label_00B5: + this.m_state = State.StartOfToken; + return; + } + throw new SerializationException("Serialization_InvalidData"); + } + + private static void VerifyIsEscapableCharacter(char c) + { + if (((c != '\\') && (c != ';')) && ((c != '[') && (c != ']'))) + { + throw new SerializationException("Serialization_InvalidEscapeSequence " + c.ToString()); + } + } + + // Nested Types + private enum State + { + Escaped, + NotEscaped, + StartOfToken, + EndOfLine + } + } + + private class TimeZoneInfoComparer : IComparer + { + // Methods + int IComparer.Compare(TimeZoneInfo x, TimeZoneInfo y) + { + return DevComponents.AdvTree.Utilities.CompareAlphaNumeric(x.Id, y.Id); + } + } + + private enum TimeZoneInfoResult + { + Success, + TimeZoneNotFoundException, + InvalidTimeZoneException, + SecurityException + } + + [Serializable, StructLayout(LayoutKind.Sequential), HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true), HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] + public struct TransitionTime : IEquatable, ISerializable, IDeserializationCallback + { + private DateTime m_timeOfDay; + private byte m_month; + private byte m_week; + private byte m_day; + private DayOfWeek m_dayOfWeek; + private bool m_isFixedDateRule; + public DateTime TimeOfDay + { + get + { + return this.m_timeOfDay; + } + } + public int Month + { + get + { + return this.m_month; + } + } + public int Week + { + get + { + return this.m_week; + } + } + public int Day + { + get + { + return this.m_day; + } + } + public DayOfWeek DayOfWeek + { + get + { + return this.m_dayOfWeek; + } + } + public bool IsFixedDateRule + { + get + { + return this.m_isFixedDateRule; + } + } + public override bool Equals(object obj) + { + return ((obj is TimeZoneInfo.TransitionTime) && this.Equals((TimeZoneInfo.TransitionTime)obj)); + } + + public static bool operator ==(TimeZoneInfo.TransitionTime left, TimeZoneInfo.TransitionTime right) + { + return left.Equals(right); + } + + public static bool operator !=(TimeZoneInfo.TransitionTime left, TimeZoneInfo.TransitionTime right) + { + return !left.Equals(right); + } + + public bool Equals(TimeZoneInfo.TransitionTime other) + { + bool flag = ((this.m_isFixedDateRule == other.m_isFixedDateRule) && (this.m_timeOfDay == other.m_timeOfDay)) && (this.m_month == other.m_month); + if (!flag) + { + return flag; + } + if (other.m_isFixedDateRule) + { + return (this.m_day == other.m_day); + } + return ((this.m_week == other.m_week) && (this.m_dayOfWeek == other.m_dayOfWeek)); + } + + public override int GetHashCode() + { + return (this.m_month ^ (this.m_week << 8)); + } + + public static TimeZoneInfo.TransitionTime CreateFixedDateRule(DateTime timeOfDay, int month, int day) + { + return CreateTransitionTime(timeOfDay, month, 1, day, DayOfWeek.Sunday, true); + } + + public static TimeZoneInfo.TransitionTime CreateFloatingDateRule(DateTime timeOfDay, int month, int week, DayOfWeek dayOfWeek) + { + return CreateTransitionTime(timeOfDay, month, week, 1, dayOfWeek, false); + } + + private static TimeZoneInfo.TransitionTime CreateTransitionTime(DateTime timeOfDay, int month, int week, int day, DayOfWeek dayOfWeek, bool isFixedDateRule) + { + ValidateTransitionTime(timeOfDay, month, week, day, dayOfWeek); + TimeZoneInfo.TransitionTime time = new TimeZoneInfo.TransitionTime(); + time.m_isFixedDateRule = isFixedDateRule; + time.m_timeOfDay = timeOfDay; + time.m_dayOfWeek = dayOfWeek; + time.m_day = (byte)day; + time.m_week = (byte)week; + time.m_month = (byte)month; + return time; + } + + private static void ValidateTransitionTime(DateTime timeOfDay, int month, int week, int day, DayOfWeek dayOfWeek) + { + if (timeOfDay.Kind != DateTimeKind.Unspecified) + { + throw new ArgumentException("Argument_DateTimeKindMustBeUnspecified", "timeOfDay"); + } + if ((month < 1) || (month > 12)) + { + throw new ArgumentOutOfRangeException("month", "ArgumentOutOfRange_Month"); + } + if ((day < 1) || (day > 0x1f)) + { + throw new ArgumentOutOfRangeException("day", "ArgumentOutOfRange_Day"); + } + if ((week < 1) || (week > 5)) + { + throw new ArgumentOutOfRangeException("week", "ArgumentOutOfRange_Week"); + } + if ((dayOfWeek < DayOfWeek.Sunday) || (dayOfWeek > DayOfWeek.Saturday)) + { + throw new ArgumentOutOfRangeException("dayOfWeek", "ArgumentOutOfRange_DayOfWeek"); + } + if (((timeOfDay.Year != 1) || (timeOfDay.Month != 1)) || ((timeOfDay.Day != 1) || ((timeOfDay.Ticks % 0x2710L) != 0L))) + { + throw new ArgumentException("Argument_DateTimeHasTicks", "timeOfDay"); + } + } + + void IDeserializationCallback.OnDeserialization(object sender) + { + try + { + ValidateTransitionTime(this.m_timeOfDay, this.m_month, this.m_week, this.m_day, this.m_dayOfWeek); + } + catch (ArgumentException exception) + { + throw new SerializationException("Serialization_InvalidData", exception); + } + } + + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + info.AddValue("TimeOfDay", this.m_timeOfDay); + info.AddValue("Month", this.m_month); + info.AddValue("Week", this.m_week); + info.AddValue("Day", this.m_day); + info.AddValue("RelativeDayOfWeek", this.m_dayOfWeek); + info.AddValue("IsFixedDateRule", this.m_isFixedDateRule); + } + + private TransitionTime(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + this.m_timeOfDay = (DateTime)info.GetValue("TimeOfDay", typeof(DateTime)); + this.m_month = (byte)info.GetValue("Month", typeof(byte)); + this.m_week = (byte)info.GetValue("Week", typeof(byte)); + this.m_day = (byte)info.GetValue("Day", typeof(byte)); + this.m_dayOfWeek = (DayOfWeek)info.GetValue("RelativeDayOfWeek", typeof(DayOfWeek)); + this.m_isFixedDateRule = (bool)info.GetValue("IsFixedDateRule", typeof(bool)); + } + } + } + + [Flags] + internal enum TimeZoneInfoOptions + { + None = 1, + NoThrowOnInvalidTime = 2 + } + + [Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] + public class InvalidTimeZoneException : Exception + { + // Methods + public InvalidTimeZoneException() + { + } + + public InvalidTimeZoneException(string message) + : base(message) + { + } + + protected InvalidTimeZoneException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + public InvalidTimeZoneException(string message, Exception innerException) + : base(message, innerException) + { + } + } + + [Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] + public class TimeZoneNotFoundException : Exception + { + // Methods + public TimeZoneNotFoundException() + { + } + + public TimeZoneNotFoundException(string message) + : base(message) + { + } + + protected TimeZoneNotFoundException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + public TimeZoneNotFoundException(string message, Exception innerException) + : base(message, innerException) + { + } + } + + [SuppressUnmanagedCodeSecurity, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] + internal sealed class SafeLibraryHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid + { + // Methods + internal SafeLibraryHandle() + : base(true) + { + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + private static extern bool FreeLibrary(IntPtr hModule); + [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags); + protected override bool ReleaseHandle() + { + return FreeLibrary(base.handle); + } + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/TimeZoneInfo/UnsafeNativeMethods.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/TimeZoneInfo/UnsafeNativeMethods.cs new file mode 100644 index 00000000..35e36361 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/TimeZoneInfo/UnsafeNativeMethods.cs @@ -0,0 +1,36 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Security; + +namespace DevComponents.Schedule +{ + [SuppressUnmanagedCodeSecurity] + internal static class UnsafeNativeMethods + { + [DllImport("kernel32.dll", SetLastError=true, ExactSpelling=true)] + internal static extern int GetDynamicTimeZoneInformation(out NativeMethods.DynamicTimeZoneInformation lpDynamicTimeZoneInformation); + + [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] + internal static extern int GetTimeZoneInformation(out NativeMethods.TimeZoneInformation lpTimeZoneInformation); + + [return: MarshalAs(UnmanagedType.Bool)] + [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] + internal static extern bool GetFileMUIPath(int flags, [MarshalAs(UnmanagedType.LPWStr)] string filePath, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder language, ref int languageLength, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder fileMuiPath, ref int fileMuiPathLength, ref long enumerator); + + [SecurityCritical, DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags); + + [SecurityCritical, DllImport("user32.dll", EntryPoint = "LoadStringW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] + internal static extern int LoadString(SafeLibraryHandle handle, int id, StringBuilder buffer, int bufferLength); + + + + + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WeeklyRecurrenceSettings.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WeeklyRecurrenceSettings.cs new file mode 100644 index 00000000..90a279bc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WeeklyRecurrenceSettings.cs @@ -0,0 +1,122 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Defines weekly recurrence settings. + /// + public class WeeklyRecurrenceSettings : INotifyPropertyChanged, INotifySubPropertyChanged + { + #region Internal Implementation + private AppointmentRecurrence _Recurrence = null; + /// + /// Initializes a new instance of the WeeklyRecurrenceSettings class. + /// + /// + public WeeklyRecurrenceSettings(AppointmentRecurrence recurrence) + { + _Recurrence = recurrence; + } + + + private eDayOfWeekRecurrence _RepeatOnDaysOfWeek = eDayOfWeekRecurrence.All; + /// + /// Gets or sets the days of week on which appointment is repeated. This property is represented by bit-flag enum + /// which means that you can combine the values from eDayOfWeekRecurrence enum using OR operator to specify multiple values. + /// Default value is All. + /// + /// This property value cannot be set to eDayOfWeekRecurrence.None. + /// + /// + [DefaultValue(eDayOfWeekRecurrence.All)] + public eDayOfWeekRecurrence RepeatOnDaysOfWeek + { + get { return _RepeatOnDaysOfWeek; } + set + { + if (value == eDayOfWeekRecurrence.None) + throw new ArgumentException("RepeatOnDaysOfWeek cannot be set to eDayOfWeekRecurrence.None"); + + if (value != _RepeatOnDaysOfWeek) + { + eDayOfWeekRecurrence oldValue = _RepeatOnDaysOfWeek; + _RepeatOnDaysOfWeek = value; + OnRepeatOnDaysOfWeekChanged(oldValue, value); + } + } + } + + private void OnRepeatOnDaysOfWeekChanged(eDayOfWeekRecurrence oldValue, eDayOfWeekRecurrence newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnDaysOfWeek")); + } + + private int _RepeatInterval = 1; + /// + /// Gets or sets the interval between recurring appointments. Default value is 1. + /// + /// For example, setting RepeatInterval to 2 means that appointment will recur every 2 weeks. + /// + /// + [DefaultValue(1)] + public int RepeatInterval + { + get { return _RepeatInterval; } + set + { + if (value != _RepeatInterval) + { + int oldValue = _RepeatInterval; + _RepeatInterval = value; + OnRepeatIntervalChanged(oldValue, value); + } + } + } + + private void OnRepeatIntervalChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatInterval")); + } + #endregion + + #region INotifyPropertyChanged Members + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + if (eh != null) eh(this, e); + OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e)); + } + #endregion + + #region INotifySubPropertyChanged Members + /// + /// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key + /// difference that it occurs for the property changed of child objects as well. + /// + public event SubPropertyChangedEventHandler SubPropertyChanged; + /// + /// Raises the SubPropertyChanged event. + /// + /// Event arguments + protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e) + { + SubPropertyChangedEventHandler eh = SubPropertyChanged; + if (eh != null) eh(this, e); + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WorkDay.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WorkDay.cs new file mode 100644 index 00000000..a19bd64d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WorkDay.cs @@ -0,0 +1,70 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents working day in calendar. + /// + public class WorkDay : BaseWorkDay + { + #region Internal Implementation + /// + /// Initializes a new instance of the WorkDay class. + /// + public WorkDay() + { + } + + /// + /// Initializes a new instance of the WorkDay class. + /// + /// + public WorkDay(DayOfWeek dayOfWeek) + { + _DayOfWeek = dayOfWeek; + } + + /// + /// Initializes a new instance of the WorkDay class. + /// + /// + /// + /// + public WorkDay(DayOfWeek dayOfWeek, WorkTime workStartTime, WorkTime workEndTime) + { + _DayOfWeek = dayOfWeek; + _WorkStartTime = workStartTime; + _WorkEndTime = workEndTime; + } + + private DayOfWeek _DayOfWeek = DayOfWeek.Monday; + /// + /// Gets or sets the day of week this instance represents. + /// + public DayOfWeek DayOfWeek + { + get { return _DayOfWeek; } + set + { + if (value != _DayOfWeek) + { + DayOfWeek oldValue = _DayOfWeek; + _DayOfWeek = value; + OnDayOfWeekChanged(oldValue, value); + } + } + } + + private void OnDayOfWeekChanged(DayOfWeek oldValue, DayOfWeek newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("DayOfWeek")); + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WorkDayCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WorkDayCollection.cs new file mode 100644 index 00000000..8269ef37 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WorkDayCollection.cs @@ -0,0 +1,171 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents collection of working days. + /// + public class WorkDayCollection : Collection + { + #region Constructor + /// + /// Initializes a new instance of the AppointmentCollection class. + /// + /// + public WorkDayCollection(CalendarModel calendar) + { + _Calendar = calendar; + } + + /// + /// Initializes a new instance of the WorkDayCollection class. + /// + /// + public WorkDayCollection(Owner owner) + { + _Owner = owner; + } + #endregion + #region Internal Implementation + private Owner _Owner = null; + /// + /// Gets the Owner of work-day collection. + /// + public Owner Owner + { + get { return _Owner; } + internal set { _Owner = value; } + } + + private CalendarModel _Calendar = null; + /// + /// Gets the calendar collection is associated with. + /// + public CalendarModel Calendar + { + get { return _Calendar; } + internal set + { + _Calendar = value; + UpdateItemsCalendarModel(); + } + } + + internal void UpdateItemsCalendarModel() + { + CalendarModel model = GetCalendarModel(); + foreach (WorkDay item in this.Items) + { + item.Calendar = model; + } + } + + protected override void RemoveItem(int index) + { + WorkDay day = this[index]; + OnBeforeRemove(index, day); + base.RemoveItem(index); + OnAfterRemove(index, day); + } + + private void OnAfterRemove(int index, WorkDay day) + { + CalendarModel model = GetCalendarModel(); + if (model != null) + model.WorkDayRemoved(day); + } + + private void OnBeforeRemove(int index, WorkDay day) + { + day.Calendar = null; + } + + protected override void InsertItem(int index, WorkDay item) + { + OnBeforeInsert(index, item); + base.InsertItem(index, item); + OnAfterInsert(index, item); + } + + private void OnAfterInsert(int index, WorkDay item) + { + CalendarModel model = GetCalendarModel(); + if (model != null) + model.WorkDayAdded(item); + } + + private void OnBeforeInsert(int index, WorkDay item) + { + if (this[item.DayOfWeek] != null) + throw new InvalidOperationException("Day '" + item.DayOfWeek.ToString() + "' already in collection."); + item.Calendar = GetCalendarModel(); + } + + private CalendarModel GetCalendarModel() + { + if (_Calendar != null) return _Calendar; + if (_Owner != null) return _Owner.Calendar; + return null; + } + + protected override void SetItem(int index, WorkDay newItem) + { + WorkDay oldItem = this[index]; + OnBeforeSetItem(index, oldItem, newItem); + base.SetItem(index, newItem); + OnAfterSetItem(index, oldItem, newItem); + } + + private void OnAfterSetItem(int index, WorkDay oldItem, WorkDay newItem) + { + CalendarModel model = GetCalendarModel(); + if (model != null) + { + model.WorkDayRemoved(oldItem); + model.WorkDayAdded(newItem); + } + } + + private void OnBeforeSetItem(int index, WorkDay oldItem, WorkDay newItem) + { + oldItem.Calendar = null; + newItem.Calendar = GetCalendarModel(); + } + + protected override void ClearItems() + { + CalendarModel model = GetCalendarModel(); + foreach (WorkDay item in this) + { + item.Calendar = null; + if (model != null) + model.WorkDayRemoved(item); + } + base.ClearItems(); + } + + /// + /// Gets the item based on the Key assigned to the item + /// + /// Day of week to retrive data for. + /// Reference to WorkDay or null if no day in collection. + public WorkDay this[DayOfWeek day] + { + get + { + foreach (WorkDay item in this.Items) + { + if (item.DayOfWeek == day) return item; + } + return null; + } + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WorkTime.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WorkTime.cs new file mode 100644 index 00000000..fd8bd243 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/WorkTime.cs @@ -0,0 +1,132 @@ +#if FRAMEWORK20 +using System; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents a work time. + /// + public struct WorkTime + { + #region Private variables + + private int _Hour; // Hour + private int _Minute; // Minute + + #endregion + + /// + /// Initializes a new instance of the WorkTime structure. + /// + /// + /// + public WorkTime(int hour, int minute) + { + if (hour < 0 || hour > 23) + throw new ArgumentException("Hour value must be from 0 to 23"); + + if (minute < 0 || minute > 59) + throw new ArgumentException("Minute value must be from 0 to 59"); + + _Hour = hour; + _Minute = minute; + } + + #region Public properties + + /// + /// Gets or sets the hour from 0 to 23 this time instance represents. + /// + public int Hour + { + get { return _Hour; } + + set + { + if (value < 0 || value > 23) + throw new ArgumentException("Hour value must be from 0 to 23"); + + _Hour = value; + } + } + + /// + /// Gets or sets the minute from 0 to 59 this time instance represents. + /// + public int Minute + { + get { return _Minute; } + + set + { + if (value < 0 || value > 59) + throw new ArgumentException("Minute value must be from 0 to 59"); + + _Minute = value; + } + } + + /// + /// Determines if the WorkTime is Empty + /// + public bool IsEmpty + { + get + { + return (_Hour == 0 && _Minute == 0); + } + } + + #endregion + + #region Operator overloades + + public static bool operator >=(WorkTime op1, WorkTime op2) + { + if ((op1.Hour > op2.Hour) || + (op1.Hour == op2.Hour && op1.Minute >= op2.Minute)) + { + return (true); + } + + return (false); + } + + public static bool operator <=(WorkTime op1, WorkTime op2) + { + if ((op1.Hour < op2.Hour) || + (op1.Hour == op2.Hour && op1.Minute <= op2.Minute)) + { + return (true); + } + + return (false); + } + + public static bool operator >(WorkTime op1, WorkTime op2) + { + if ((op1.Hour > op2.Hour) || + (op1.Hour == op2.Hour && op1.Minute > op2.Minute)) + { + return (true); + } + + return (false); + } + + public static bool operator <(WorkTime op1, WorkTime op2) + { + if ((op1.Hour < op2.Hour) || + (op1.Hour == op2.Hour && op1.Minute < op2.Minute)) + { + return (true); + } + + return (false); + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Year.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Year.cs new file mode 100644 index 00000000..4e24b8de --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/Year.cs @@ -0,0 +1,72 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Represents the calendar year. + /// + public class Year + { + #region Internal Implementation + private int _Year = 0; + private CalendarModel _CalendarModel = null; + private ReadOnlyCollection _ReadOnlyMonths = null; + private List _Months = null; + + /// + /// Initializes a new instance of the Year class. + /// + /// + /// + public Year(int year, CalendarModel calendarModel) + { + _Year = year; + _CalendarModel = calendarModel; + } + + /// + /// Returns read-only collection of months in year. + /// + public ReadOnlyCollection Months + { + get + { + if (_ReadOnlyMonths == null) + CreateCollection(); + return _ReadOnlyMonths; + } + } + + private void CreateCollection() + { + _Months = new List(12); + for (int i = 0; i < 12; i++) + { + _Months.Add(new Month(_CalendarModel, _Year, i + 1)); + } + _ReadOnlyMonths = new ReadOnlyCollection(_Months); + } + + internal void InvalidateAppointments() + { + if (_Months == null) return; + foreach (Month month in _Months) + { + month.InvalidateAppointments(); + } + } + + internal void InvalidateAppointments(int month, int day) + { + if (_Months == null) return; + _Months[month - 1].InvalidateAppointments(day); + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/YearlyRecurrenceSettings.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/YearlyRecurrenceSettings.cs new file mode 100644 index 00000000..fbf0a1a0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/Model/YearlyRecurrenceSettings.cs @@ -0,0 +1,193 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace DevComponents.Schedule.Model +{ + /// + /// Defines yearly recurrence settings. + /// + public class YearlyRecurrenceSettings : INotifyPropertyChanged, INotifySubPropertyChanged + { + #region Internal Implementation + private AppointmentRecurrence _Recurrence = null; + + /// + /// Initializes a new instance of the YearlyRecurrenceSettings class. + /// + /// + public YearlyRecurrenceSettings(AppointmentRecurrence recurrence) + { + _Recurrence = recurrence; + } + + private int _RepeatInterval = 1; + /// + /// Gets or sets the interval between recurring appointments. Default value is 1. + /// + /// For example, setting RepeatInterval to 2 means that appointment will recur every 2 years. + /// + /// + [DefaultValue(1)] + public int RepeatInterval + { + get { return _RepeatInterval; } + set + { + if (value != _RepeatInterval) + { + int oldValue = _RepeatInterval; + _RepeatInterval = value; + OnRepeatIntervalChanged(oldValue, value); + } + } + } + + private void OnRepeatIntervalChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatInterval")); + } + + private int _RepeatOnDayOfMonth = 1; + /// + /// Gets or sets the day of month on which appointment is repeated. + /// When RepeatOnRelativeDayInMonth property is set to value other than None value of this property is not used. + /// + [DefaultValue(1)] + public int RepeatOnDayOfMonth + { + get { return _RepeatOnDayOfMonth; } + set + { + if (value != _RepeatOnDayOfMonth) + { + int oldValue = _RepeatOnDayOfMonth; + _RepeatOnDayOfMonth = value; + OnRepeatOnDayOfMonthChanged(oldValue, value); + } + } + } + + private void OnRepeatOnDayOfMonthChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnDayOfMonth")); + } + + + private eRelativeDayInMonth _RepeatOnRelativeDayInMonth = eRelativeDayInMonth.None; + /// + /// Gets or sets whether appointment should repeat on first, second, third, fourth or last day in month as specified + /// by RepeatOnDayOfMonth property. Default value is None. + /// + [DefaultValue(eRelativeDayInMonth.None)] + public eRelativeDayInMonth RepeatOnRelativeDayInMonth + { + get { return _RepeatOnRelativeDayInMonth; } + set + { + if (value != _RepeatOnRelativeDayInMonth) + { + eRelativeDayInMonth oldValue = _RepeatOnRelativeDayInMonth; + _RepeatOnRelativeDayInMonth = value; + OnRepeatOnRelativeDayInMonthChanged(oldValue, value); + } + } + } + + private void OnRepeatOnRelativeDayInMonthChanged(eRelativeDayInMonth oldValue, eRelativeDayInMonth newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnRelativeDayInMonth")); + } + + private DayOfWeek _RelativeDayOfWeek = DayOfWeek.Monday; + /// + /// Gets or sets the day of week on which relative repeat as specified by RepeatOnRelativeDayInMonth is effective. + /// For example setting RepeatOnRelativeDayInMonth to First and RelativeDayOfWeek to Monday will repeat the appointment on first + /// Monday in a month. + /// + [DefaultValue(DayOfWeek.Monday)] + public DayOfWeek RelativeDayOfWeek + { + get { return _RelativeDayOfWeek; } + set + { + if (value != _RelativeDayOfWeek) + { + DayOfWeek oldValue = _RelativeDayOfWeek; + _RelativeDayOfWeek = value; + OnRelativeDayOfWeekChanged(oldValue, value); + } + } + } + + private void OnRelativeDayOfWeekChanged(DayOfWeek oldValue, DayOfWeek newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RelativeDayOfWeek")); + } + + private int _RepeatOnMonth = 1; + /// + /// Gets or sets the month the appointment is repeated on every year. + /// + [DefaultValue(1)] + public int RepeatOnMonth + { + get { return _RepeatOnMonth; } + set + { + if (value < 1 || value > 12) + throw new ArgumentException("Valid RepeatOnMonth values are between 1-12"); + if (value != _RepeatOnMonth) + { + int oldValue = _RepeatOnMonth; + _RepeatOnMonth = value; + OnRepeatOnMonthChanged(oldValue, value); + } + } + } + + private void OnRepeatOnMonthChanged(int oldValue, int newValue) + { + OnPropertyChanged(new PropertyChangedEventArgs("RepeatOnMonth")); + } + #endregion + + #region INotifyPropertyChanged Members + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + if (eh != null) eh(this, e); + OnSubPropertyChanged(new SubPropertyChangedEventArgs(this, e)); + } + #endregion + + #region INotifySubPropertyChanged Members + /// + /// Occurs when property or property of child objects has changed. This event is similar to PropertyChanged event with key + /// difference that it occurs for the property changed of child objects as well. + /// + public event SubPropertyChangedEventHandler SubPropertyChanged; + /// + /// Raises the SubPropertyChanged event. + /// + /// Event arguments + protected virtual void OnSubPropertyChanged(SubPropertyChangedEventArgs e) + { + SubPropertyChangedEventHandler eh = SubPropertyChanged; + if (eh != null) eh(this, e); + } + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/ModelViewConnector.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/ModelViewConnector.cs new file mode 100644 index 00000000..51293b1c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/ModelViewConnector.cs @@ -0,0 +1,113 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + /// + /// Represents base class for the model to view connectors. + /// + internal abstract class ModelViewConnector + { + #region Internal Implementation + + #region Private variables + + private string _DisplayOwnerKey = ""; + + #endregion + + #region Abstract defines + + /// + /// Connects View to a model. + /// + public abstract void Connect(); + + /// + /// Disconnects view from model. + /// + public abstract void Disconnect(); + + /// + /// Gets whether connector has connected model to a view. + /// + public abstract bool IsConnected { get; } + + public abstract eCalendarView GetView(); + + #endregion + + #region Virtual methods + + protected virtual bool IsAppointmentVisible(Appointment app) + { + if (app.Visible == false) + return (false); + + if (string.IsNullOrEmpty(_DisplayOwnerKey)) + return (true); + + return (app.OwnerKey == _DisplayOwnerKey); + } + + protected virtual bool IsCustomItemVisible(CustomCalendarItem item) + { + if (item.Visible == false) + return (false); + + if (string.IsNullOrEmpty(_DisplayOwnerKey)) + return (true); + + return (item.OwnerKey.Equals(_DisplayOwnerKey)); + } + + /// + /// Gets or sets the owner key of the owner of the appointments displayed on the view. + /// + public virtual string DisplayOwnerKey + { + get { return _DisplayOwnerKey; } + + set + { + if (value == null) + value = ""; + + if (_DisplayOwnerKey != null) + { + _DisplayOwnerKey = value; + } + } + } + + public virtual List + GetAppointmentList(CalendarModel model, DateTime startDate, DateTime endDate) + { + List appts = new List(); + + for (DateTime date = startDate; date <= endDate; date = date.AddDays(1)) + { + Day day = model.GetDay(date); + + if (day.Appointments.Count > 0) + { + foreach (Appointment ap in day.Appointments) + { + if (appts.Contains(ap) == false) + appts.Add(ap); + } + } + } + + return (appts); + } + + #endregion + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/MonthView/ModelMonthViewConnector.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/MonthView/ModelMonthViewConnector.cs new file mode 100644 index 00000000..386cb539 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/MonthView/ModelMonthViewConnector.cs @@ -0,0 +1,598 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using DevComponents.Schedule.Model; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Schedule +{ + internal class ModelMonthViewConnector : ModelViewConnector + { + #region Constants + + private const int DaysInWeek = 7; + + #endregion + + #region Private variables + + private CalendarModel _Model; // The associated CalendarModel + private MonthView _View; // The associated MonthView + + private bool _IsConnected; // Connection status + private uint _RefreshCount; + + #endregion + + /// + /// Constructor + /// + /// Assoc CalendarModel + /// Assoc MonthView + public ModelMonthViewConnector(CalendarModel model, MonthView monthView) + { + _Model = model; + _View = monthView; + } + + #region Public properties + + /// + /// Gets the connection status + /// + public override bool IsConnected + { + get { return _IsConnected; } + } + + #endregion + + #region Connect + + /// + /// Performs Model connection processing + /// + public override void Connect() + { + VerifyModel(); + + // Load the connection data + + if (_IsConnected) + Disconnect(); + + LoadData(); + + // Get notification on Model property changes + + _Model.PropertyChanged += ModelPropertyChanged; + _Model.SubPropertyChanged += ModelSubPropertyChanged; + + _View.CalendarView.CustomItems.CollectionChanged += CustomItemsCollectionChanged; + + _IsConnected = true; + } + + #endregion + + #region Disconnect + + /// + /// Severs the Model/MonthView connection + /// + public override void Disconnect() + { + VerifyModel(); + + if (_IsConnected) + { + // Loop through each week, clearing each + // associated view connection + + for (int i = 0; i < _View.MonthWeeks.Length; i++) + ClearMonthWeek(_View.MonthWeeks[i]); + + _View.SubItems.Clear(); + + // Stop notification on Model property changes + + _Model.PropertyChanged -= ModelPropertyChanged; + _Model.SubPropertyChanged -= ModelSubPropertyChanged; + + _View.CalendarView.CustomItems.CollectionChanged -= CustomItemsCollectionChanged; + + _IsConnected = false; + } + } + + /// + /// Clears individual MonthWeek view connections + /// + /// MonthWeek + private void ClearMonthWeek(MonthWeek monthWeek) + { + if (monthWeek.CalendarItems.Count > 0) + { + // Loop through each CalendarItem, resetting + // it's associated connection + + for (int i = monthWeek.CalendarItems.Count - 1; i >= 0; i--) + { + AppointmentMonthView view = + monthWeek.CalendarItems[i] as AppointmentMonthView; + + if (view != null) + { + view.IsSelectedChanged -= _View.ItemIsSelectedChanged; + + view.Appointment = null; + view.IsSelected = false; + view.MonthWeek = null; + } + + monthWeek.CalendarItems.RemoveAt(i); + } + } + } + + #endregion + + #region LoadData + + /// + /// Loads Model/MonthView connection data + /// + private void LoadData() + { + MonthWeek[] wks = _View.MonthWeeks; + + if (wks.Length > 0) + { + _RefreshCount++; + + DateTime startDate = wks[0].FirstDayOfWeek; + DateTime endDate = DateTimeHelper.EndOfDay(wks[wks.Length - 1].LastDayOfWeek); + + DateTime appStartDate = startDate.AddMonths(-1); + + List appts = GetAppointmentList(_Model, appStartDate, endDate); + + for (int i = 0; i < wks.Length; i++) + { + MonthWeek monthWeek = wks[i]; + + startDate = monthWeek.FirstDayOfWeek; + endDate = DateTimeHelper.EndOfDay(monthWeek.LastDayOfWeek); + + UpdateWeekView(monthWeek, appts, startDate, endDate); + UpdateCustomItems(monthWeek, startDate, endDate); + } + } + } + + #endregion + + #region RefreshData + + /// + /// Refreshes the data in a previously established + /// and loaded connection + /// + public void RefreshData() + { + LoadData(); + + List removedViews = null; + + foreach (MonthWeek monthWeek in _View.MonthWeeks) + RemoveOutdatedViews(monthWeek, ref removedViews); + + ProcessRemovedData(removedViews); + } + + #region RemoveOutdatedViews + + private void RemoveOutdatedViews( + MonthWeek monthWeek, ref List removedViews) + { + for (int i = monthWeek.CalendarItems.Count - 1; i >= 0; i--) + { + CalendarItem view = monthWeek.CalendarItems[i]; + + if (view != null) + { + if (view.RefreshCount != _RefreshCount) + { + if (removedViews == null) + removedViews = new List(); + + removedViews.Add(view); + + _View.SubItems._Remove(view); + _View.NeedRecalcSize = true; + + monthWeek.CalendarItems.RemoveAt(i); + } + } + } + } + + #endregion + + #region ProcessRemovedData + + private void ProcessRemovedData(List removedViews) + { + if (removedViews != null && removedViews.Count > 0) + { + for (int i = 0; i < removedViews.Count; i++) + { + CalendarItem item = removedViews[i]; + + item.IsSelectedChanged -= _View.ItemIsSelectedChanged; + + item.Dispose(); + } + + _View.NeedRecalcLayout = true; + } + } + + #endregion + + #endregion + + #region UpdateWeekView + + private void UpdateWeekView(MonthWeek monthWeek, + List apps, DateTime startDate, DateTime endDate) + { + // Loop through each appointment + // updating the assoc view accordingly + + foreach (Appointment app in apps) + { + if (app.StartTime < endDate && app.EndTime > startDate) + { + if (IsAppointmentVisible(app)) + { + // Get the assoc view + + AppointmentMonthView view = GetViewFromWeek(monthWeek, app) ?? + GetNewView(app); + + // Set the view start and end times to + // match the assoc appointment + + view.StartTime = app.StartTime; + view.EndTime = app.EndTime; + + view.RefreshCount = _RefreshCount; + + // And update the MonthWeek data + + if (view.MonthWeek == null) + { + view.MonthWeek = monthWeek; + + monthWeek.CalendarItems.Add(view); + + _View.SubItems.Add(view); + } + + view.IsSelected = app.IsSelected; + } + } + } + } + + #endregion + + #region UpdateCustomItems + + private void UpdateCustomItems( + MonthWeek monthWeek, DateTime startDate, DateTime endDate) + { + CustomCalendarItemCollection items = _View.CalendarView.CustomItems; + + if (items != null && items.Count > 0) + { + for (int i = 0; i < items.Count; i++) + { + CustomCalendarItem item = items[i]; + + if (IsCustomItemVisible(item) == true && + (item.StartTime < endDate && item.EndTime > startDate)) + { + item.CalendarView = _View.CalendarView; + + CustomCalendarItem ci = GetItemFromWeek(monthWeek, item); + + if (ci == null) + { + ci = GetNewCustomItem(item); + + monthWeek.CalendarItems.Add(ci); + + _View.SubItems.Insert(0, ci); + } + + ci.RefreshCount = _RefreshCount; + + if (ci.BaseCalendarItem != item) + { + ci.StartTime = item.StartTime; + ci.EndTime = item.EndTime; + } + } + } + } + } + + #endregion + + #region GetViewFrom + + private List GetViewsFromAll(Appointment app) + { + List list = new List(); + + for (int i = 0; i < _View.MonthWeeks.Length; i++) + { + AppointmentMonthView view = + GetViewFromWeek(_View.MonthWeeks[i], app); + + if (view != null) + list.Add(view); + } + + return (list); + } + + private AppointmentMonthView GetViewFromWeek(MonthWeek monthWeek, Appointment appointment) + { + foreach (CalendarItem item in monthWeek.CalendarItems) + { + AppointmentMonthView view = item as AppointmentMonthView; + + if (view != null && view.Appointment == appointment) + return (view); + } + + return (null); + } + + #endregion + + #region GetItemFromWeek + + private CustomCalendarItem GetItemFromWeek(MonthWeek monthWeek, CustomCalendarItem item) + { + foreach (CalendarItem citem in monthWeek.CalendarItems) + { + CustomCalendarItem view = citem as CustomCalendarItem; + + if (view != null && (view == item || view.BaseCalendarItem == item)) + return (view); + } + + return (null); + } + + #endregion + + #region GetNewView + + /// + /// Gets a new appointment view + /// + /// Appointment + /// New view + private AppointmentMonthView GetNewView(Appointment appointment) + { + AppointmentMonthView view = new AppointmentMonthView(_View, appointment); + + view.Tooltip = appointment.Tooltip; + + // Set the selected state to match any current + // views that are present for this appointment + + for (int i = 0; i < _View.MonthWeeks.Length; i++) + { + AppointmentMonthView viewPart = + GetViewFromWeek(_View.MonthWeeks[i], appointment); + + if (viewPart != null) + { + view.IsSelected = viewPart.IsSelected; + break; + } + } + + view.IsSelectedChanged += _View.ItemIsSelectedChanged; + + return (view); + } + + #endregion + + #region GetNewCustomItem + + /// + /// Gets a new CustomItem + /// + /// + /// + private CustomCalendarItem GetNewCustomItem(CustomCalendarItem item) + { + CustomCalendarItem ci = (CustomCalendarItem)item.Copy(); + + ci.BaseCalendarItem = item; + ci.ModelItem = item; + + // Set the selected state to match any current + // views that are present for this appointment + + for (int i = 0; i < _View.MonthWeeks.Length; i++) + { + CustomCalendarItem viewPart = + GetItemFromWeek(_View.MonthWeeks[i], item); + + if (viewPart != null) + { + ci.IsSelected = viewPart.IsSelected; + break; + } + } + + ci.IsSelectedChanged += _View.ItemIsSelectedChanged; + + return (ci); + } + + #endregion + + #region GetView + + /// + /// Returns the Month view + /// + /// + public override eCalendarView GetView() + { + return (eCalendarView.Month); + } + + /// + /// Verifies the Model and MonthView are valid + /// + private void VerifyModel() + { + if (_Model == null) + throw new NullReferenceException("CalendarModel must be set on connector."); + + if (_View == null) + throw new NullReferenceException("MonthCalendarView must be set on connector."); + } + + #endregion + + #region ModelPropertyChanged + + /// + /// Handles Model property change notifications + /// + /// + /// + private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == CalendarModel.AppointmentsPropertyName) + { + RefreshData(); + + _View.NeedRecalcSize = true; + _View.Refresh(); + } + } + + #endregion + + #region ModelSubPropertyChanged + + /// + /// Handles ModelSubProperty change notifications + /// + /// object + /// SubPropertyChangedEventArgs + private void ModelSubPropertyChanged(object sender, SubPropertyChangedEventArgs e) + { + if (e.Source is Owner) + { + Owner owner = (Owner)e.Source; + + if (_View.OwnerKey != null && _View.OwnerKey.Equals(owner.Key)) + { + if (e.PropertyChangedArgs.PropertyName == Owner.DisplayNamePropertyName) + _View.DisplayName = owner.DisplayName; + + else if (e.PropertyChangedArgs.PropertyName.Equals("ColorScheme")) + _View.CalendarColor = owner.ColorScheme; + } + } + else if (e.Source is Appointment) + { + Appointment app = e.Source as Appointment; + List list; + + string name = e.PropertyChangedArgs.PropertyName; + + if (name.Equals("Tooltip")) + { + list = GetViewsFromAll(app); + + for (int i = 0; i < list.Count; i++) + list[i].Tooltip = app.Tooltip; + } + else if (name.Equals("IsSelected")) + { + list = GetViewsFromAll(app); + + for (int i = 0; i < list.Count; i++) + list[i].IsSelected = app.IsSelected; + } + else if (name.Equals("CategoryColor") || name.Equals("TimeMarkedAs")) + { + list = GetViewsFromAll(app); + + for (int i = 0; i < list.Count; i++) + list[i].Refresh(); + } + else if (name.Equals("OwnerKey")) + { + if (_View.CalendarView.IsMultiCalendar == true) + { + if (_View.OwnerKey == app.OwnerKey) + { + RefreshData(); + + _View.NeedRecalcSize = true; + _View.Refresh(); + } + else + { + list = GetViewsFromAll(app); + + if (list.Count > 0) + { + RefreshData(); + + _View.NeedRecalcSize = true; + _View.Refresh(); + } + } + } + } + else if (name.Equals("Visible")) + { + RefreshData(); + } + } + } + + #endregion + + #region CustomItems_CollectionChanged + + void CustomItemsCollectionChanged(object sender, EventArgs e) + { + RefreshData(); + + _View.NeedRecalcSize = true; + _View.Refresh(); + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/MonthView/MonthView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/MonthView/MonthView.cs new file mode 100644 index 00000000..65367731 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/MonthView/MonthView.cs @@ -0,0 +1,2755 @@ +#if FRAMEWORK20 +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Schedule +{ + public class MonthView : BaseView + { + #region Constants + private const int MaxNumberOfWeeks = 52; + #endregion + + #region Events + + public event EventHandler IsSideBarVisibleChanged; + + #endregion + + #region Private variables + + private int _NumberOfWeeks; // Number of week in display + private MonthWeek[] _MonthWeeks; // Array of weeks + + private CalendarMonthColor _ViewColor = // View display color table + new CalendarMonthColor(eCalendarColor.Automatic); + + private int _DaysOffset; // Moving day offset + private bool _IsSideBarVisible = true; // Flag denoting SideBar visibility + + private Size _MoreImageSize = new Size(16, 16); + private Bitmap _MoreImage; + private Bitmap _MoreImageHot; + + private ItemRect _MoreRect; + + #endregion + + /// + /// Constructor + /// + /// Parent CalendarView + public MonthView(CalendarView calendarView) + : base(calendarView, eCalendarView.Month) + { + // Set our non-client drawing info and our CalendarColor + + NClientData = new NonClientData( + eTabOrientation.Horizontal, + (int)eCalendarMonthPart.OwnerTabBorder, + (int)eCalendarMonthPart.OwnerTabForeground, + (int)eCalendarMonthPart.OwnerTabBackground, + (int)eCalendarMonthPart.OwnerTabContentBackground, + (int)eCalendarMonthPart.OwnerTabSelectedForeground, + (int)eCalendarMonthPart.OwnerTabSelectedBackground); + + CalendarColorTable = _ViewColor; + + // Hook onto needed event + + HookEvents(true); + } + + #region Public properties + + #region MonthWeek + + public MonthWeek[] MonthWeeks + { + get { return (_MonthWeeks); } + } + + #endregion + + #region IsSideBarVisible + + /// + /// Gets and sets the SideBar visibility + /// + public bool IsSideBarVisible + { + get { return (_IsSideBarVisible); } + + set + { + if (_IsSideBarVisible != value) + { + bool oldValue = _IsSideBarVisible; + _IsSideBarVisible = value; + + OnIsSideBarVisibleChanged(oldValue, value); + + InvalidateRect(true); + } + } + } + + /// + /// OnIsSideBarVisibleChanged event propagation + /// + protected virtual void OnIsSideBarVisibleChanged(bool oldVal, bool newVal) + { + if (IsSideBarVisibleChanged != null) + IsSideBarVisibleChanged(this, new IsSideBarVisibleChangedEventArgs(oldVal, newVal)); + } + + #endregion + + #endregion + + #region Private properties + + /// + /// Gets the sidebar width + /// + private int SideBarWidth + { + get + { + return (_IsSideBarVisible ? Font.Height + 6 : 0); + } + } + + /// + /// Gets the DayHeader height + /// + private int DayHeaderHeight + { + get { return (Font.Height + 4); } + } + + #endregion + + #region HookEvents + + /// + /// Hooks (or unhooks) needed events + /// + /// True to hook, false to unhook + private void HookEvents(bool hook) + { + if (hook == true) + { + CalendarView.SelectedViewChanged += SelectedViewChanged; + CalendarView.MonthViewStartDateChanged += MonthViewStartDateChanged; + CalendarView.MonthViewEndDateChanged += MonthViewEndDateChanged; + CalendarView.IsMonthSideBarVisibleChanged += IsMonthSideBarVisibleChanged; + } + else + { + CalendarView.SelectedViewChanged -= SelectedViewChanged; + CalendarView.MonthViewStartDateChanged -= MonthViewStartDateChanged; + CalendarView.MonthViewEndDateChanged -= MonthViewEndDateChanged; + CalendarView.IsMonthSideBarVisibleChanged -= IsMonthSideBarVisibleChanged; + } + } + + #endregion + + #region Event handling + + #region SelectedViewChanged + + /// + /// Processes CalendarView SelectedViewChanged events + /// + /// CalendarView + /// SelectedViewEventArgs + void SelectedViewChanged(object sender, SelectedViewEventArgs e) + { + IsViewSelected = (e.NewValue == eCalendarView.Month); + + if (IsViewSelected == true) + { + AutoSyncViewDate(e.OldValue); + UpdateDateSelection(); + } + else + { + ResetView(); + } + } + + #endregion + + #region MonthViewStartDateChanged + + /// + /// Processes StartDate changes + /// + /// + /// + void MonthViewStartDateChanged(object sender, DateChangeEventArgs e) + { + StartDate = e.NewValue; + } + + #endregion + + #region MonthViewEndDateChanged + + /// + /// Processes EndDate changes + /// + /// + /// + void MonthViewEndDateChanged(object sender, DateChangeEventArgs e) + { + EndDate = e.NewValue; + } + + #endregion + + #region IsMonthSideBarVisibleChanged + + /// + /// Processes CalendarView IsMonthSideBarVisibleChanged events + /// + /// CalendarView + /// SelectedViewEventArgs + void IsMonthSideBarVisibleChanged( + object sender, IsMonthSideBarVisibleChangedEventArgs e) + { + IsSideBarVisible = e.NewValue; + } + + #endregion + + #endregion + + #region GetViewAreaFromPoint + + /// + /// Gets the view area under the given mouse + /// point (tab, header, content, etc) + /// + /// Point + /// eViewArea + public override eViewArea GetViewAreaFromPoint(Point pt) + { + if (Bounds.Contains(pt) == true) + { + if (ClientRect.Contains(pt)) + { + if (pt.X < Bounds.X + SideBarWidth) + return (eViewArea.InSideBarPanel); + + if (pt.Y < ClientRect.Y + DayOfWeekHeaderHeight) + return (eViewArea.InDayOfWeekHeader); + + if (pt.X >= _MonthWeeks[0].Bounds.X) + { + for (int i = 0; i < _NumberOfWeeks; i++) + { + if (pt.Y < _MonthWeeks[i].Bounds.Y + DayHeaderHeight) + return (eViewArea.InWeekHeader); + + if (pt.Y < _MonthWeeks[i].Bounds.Bottom) + return (eViewArea.InContent); + } + } + + return (eViewArea.NotInView); + } + + return (base.GetViewAreaFromPoint(pt)); + } + + return (eViewArea.NotInView); + } + + #endregion + + #region GetDateSelectionFromPoint + + /// + /// Gets the date selection from the given point. The startDate + /// and endDate will vary based upon the view type (WeekDay / Month) + /// + /// Point in question + /// out start date + /// out end date + /// True if a valid selection exists + /// at the given point + public override bool GetDateSelectionFromPoint( + Point pt, out DateTime startDate, out DateTime endDate) + { + base.GetDateSelectionFromPoint(pt, out startDate, out endDate); + + int week, day; + + if (GetPointItem(pt, out week, out day)) + { + startDate = _MonthWeeks[week].FirstDayOfWeek.AddDays(day); + endDate = startDate.AddDays(1); + + return (true); + } + + return (false); + } + + #endregion + + #region GetItemWeek + + public MonthWeek GetItemWeek(CalendarItem item) + { + for (int i = 0; i < _NumberOfWeeks; i++) + { + if (_MonthWeeks[i].CalendarItems.Contains(item)) + return (_MonthWeeks[i]); + } + + return (null); + } + + #endregion + + #region SetSelectedItem + + /// + /// Handles selected item changes + /// + /// CalendarItem + /// EventArgs + public void ItemIsSelectedChanged(object sender, EventArgs e) + { + CalendarItem ci = sender as CalendarItem; + + if (ci != null && IsSelecting == false) + { + try + { + IsSelecting = true; + + if (ci.IsSelected == true) + { + SelectedItem = SetSelectedItem(SelectedItem, ci); + } + else + { + if (ci == SelectedItem) + SelectedItem = null; + } + } + finally + { + IsSelecting = false; + } + } + } + + /// + /// Sets the current selected item + /// + /// Previous CalendarItem + /// New CalendarItem to select + /// Base selected CalendarItem + protected override CalendarItem SetSelectedItem(CalendarItem pci, CalendarItem nci) + { + CalendarItem selItem = null; + + for (int i = 0; i < _NumberOfWeeks; i++) + { + List items = _MonthWeeks[i].CalendarItems; + + for (int j = 0; j < items.Count; j++) + { + CalendarItem item = items[j]; + + item.IsSelected = (nci != null ? (item.ModelItem == nci.ModelItem) : false); + + if (item.IsSelected == true && selItem == null) + { + selItem = item; + SelectedItem = item; + } + } + } + + return (selItem); + } + + #endregion + + #region UpdateDateSelection + + /// + /// Updates each monthWeeks DayRects to reflect + /// the date selection start and end values + /// + protected override void UpdateDateSelection() + { + if (IsViewSelected == true) + { + // Loop through each week + + for (int i = 0; i < _NumberOfWeeks; i++) + { + DateTime date = _MonthWeeks[i].FirstDayOfWeek; + + // loop through each day of the week, setting + // the selection status according to the date + // selection range + + for (int j = 0; j < DaysInWeek; j++) + { + bool selected = (DateSelectionStart.HasValue && DateSelectionEnd.HasValue && + date >= DateSelectionStart && date < DateSelectionEnd); + + _MonthWeeks[i].DayRects[j].IsSelected = selected; + + date = date.AddDays(1); + } + } + } + } + + #endregion + + #region RecalcSize routines + + /// + /// Performs NeedRecalcSize requests + /// + public override void RecalcSize() + { + base.RecalcSize(); + + if (IsViewSelected == true) + { + // Normalize our start and end dates + + DateTime startDate; + DateTime endDate; + + NormalizeDates(out startDate, out endDate); + + // Calculate each weeks display info + + CalcMonthWeeks(startDate, endDate); + + // Update our Model connection and views + + UpdateView(); + UpdateDateSelection(); + + if (DaysOfTheWeek != null) + DaysOfTheWeek.NeedsMeasured = true; + + NeedRecalcLayout = false; + } + } + + #region NormalizeDates + + /// + /// Normalizes the user specified start and end dates + /// + /// [out] Normalized start date + /// [out] Normalized end date + private void NormalizeDates(out DateTime startDate, out DateTime endDate) + { + startDate = this.StartDate; + endDate = this.EndDate; + + // If both values are unset, then set them to + // today's date / + 1 month + + if (startDate == DateTime.MinValue && endDate == DateTime.MinValue) + { + startDate = DateTime.Today.Date; + endDate = startDate.AddMonths(1); + } + + endDate = DateHelper.GetEndOfWeek(endDate, DateHelper.GetLastDayOfWeek()); + startDate = DateHelper.GetDateForDayOfWeek(startDate, DateHelper.GetFirstDayOfWeek()); + + DaysOfTheWeek = new DaysOfTheWeek(); + } + + #endregion + + #region Update View + + /// + /// Updates our connection model view + /// + private void UpdateView() + { + // If we have had a date range change, just + // reset our entire view + + if (DateRangeChanged == true) + ResetView(); + + // If we have no Model connection, attempt + // to reconnect if this view is selected + + if (Connector == null) + { + if (CalendarModel != null) + Connector = new ModelMonthViewConnector(CalendarModel, this); + } + + // We have a connection, so update our CalendarItems + + if (Connector != null) + { + UpdateCalendarItems(); + + CalendarView.DoViewLoadComplete(this); + } + } + + #region UpdateCalendarItems + + /// + /// Updates our CalendarItems list + /// + private void UpdateCalendarItems() + { + // Get a working list of our CalendarItems + + List[] items = SortCalendarItems(); + + // Go through our CalendarItems on a per week basis + + bool moreItems = false; + + int days = _NumberOfWeeks * DaysInWeek; + + ulong[] acc = new ulong[days]; + + for (int i = 0; i < _NumberOfWeeks; i++) + { + // Calculate the display bounds for each item + + for (int j = 0; j < items[i].Count; j++) + CalcAppointmentBounds(items[i][j], i, acc); + + moreItems |= UpdateMoreItems(_MonthWeeks[i], acc, i); + } + + // If we have no need of our previously allocated "More" + // images then dispose of them and reset our handles + + if (moreItems == false) + { + if (_MoreImage != null) + { + _MoreImage.Dispose(); + _MoreImage = null; + } + + if (_MoreImageHot != null) + { + _MoreImageHot.Dispose(); + _MoreImageHot = null; + } + } + + // Update our current day selection + + UpdateDateSelection(); + } + + #region SortCalendarItems + + /// + /// Sorts the provided CalendarItems + /// + /// Sorted CalendarItems + private List[] SortCalendarItems() + { + List[] items = new List[_NumberOfWeeks]; + + for (int i = 0; i < _NumberOfWeeks; i++) + { + items[i] = new List(_MonthWeeks[i].CalendarItems.Count); + + if (_MonthWeeks[i].CalendarItems.Count > 0) + { + items[i].AddRange(_MonthWeeks[i].CalendarItems); + + items[i].Sort( + + delegate(CalendarItem c1, CalendarItem c2) + { + int n = c1.StartTime.TimeOfDay.CompareTo(c2.StartTime.TimeOfDay); + + if (n != 0) + return (n); + + n = c1.StartTime.CompareTo(c2.StartTime); + + if (n != 0) + return (n); + + n = c1.EndTime.CompareTo(c2.EndTime); + + if (n != 0) + return (n); + + int result = 0; + CalendarView.DoDetailSortEvent(this, c1, c2, ref result); + + return (result); + } + ); + } + } + + return (items); + } + + #endregion + + #region CalcAppointmentBounds + + /// + /// Calculates the display bounds for the AppointmentView + /// + /// CalendarItem + /// Week associated with the view + /// Row accumulator + private void CalcAppointmentBounds( + CalendarItem item, int week, ulong[] acc) + { + // Determine the starting day index for + // the given appointment + + int ns = GetDayIndex(week, item); + + // Calculate the top and height for the item + + Rectangle r = _MonthWeeks[week].DayRects[ns].Bounds; + + r.Y += DayHeaderHeight + 1; + r.Height = AppointmentHeight; + r.Width = 0; + + // Determine the ending day index + + DateTime st = _MonthWeeks[week].FirstDayOfWeek.AddDays(ns); + + int ne = ns + (item.EndTime - st).Days; + + if (item.EndTime.Hour > 0 || item.EndTime.Minute > 0 || item.EndTime.Second > 0) + ne++; + + if (ne > DaysInWeek) + ne = DaysInWeek; + + int weekOffset = week * DaysInWeek; + + int freeAcc = GetFreeAcc(weekOffset + ns, weekOffset + ne, acc); + + if (freeAcc >= 0) + { + ulong u = (1ul << freeAcc); + + for (int i = ns; i < ne; i++) + { + r.Width += _MonthWeeks[week].DayRects[i].Bounds.Width; + + acc[weekOffset + i] |= u; + } + + r.Y += (freeAcc * AppointmentHeight); + } + else + { + r.Y = _MonthWeeks[week].Bounds.Bottom; + } + + DateTime start = _MonthWeeks[week].FirstDayOfWeek; + DateTime end = start.AddDays(DaysInWeek); + + // Check to see if we can only display + // a partial representation for the view + + if (item.EndTime >= start && item.StartTime < end) + { + int hpad = CalendarView.MonthViewHorizontalPadding; + + if (item.StartTime >= start) + { + r.X += hpad; + r.Width -= hpad; + } + + if (item.EndTime <= end) + r.Width -= hpad; + } + + // Now that we have calculated the items height and + // width, invoke a Recalc on the item + + item.WidthInternal = r.Width - 1; + item.HeightInternal = r.Height - 1; + + item.RecalcSize(); + + // Set our bounds for the item + + r.Width = item.WidthInternal; + r.Height = item.HeightInternal; + + item.Bounds = r; + + // Set it's display state + + if (CalendarView.IsMonthMoreItemsIndicatorVisible == true) + item.Displayed = (r.Bottom < _MonthWeeks[week].Bounds.Bottom - _MoreImageSize.Height); + else + item.Displayed = (r.Top < _MonthWeeks[week].Bounds.Bottom - 2); + } + + #region GetFreeAcc + + private int GetFreeAcc(int ns, int ne, ulong[] acc) + { + for (int i = 0; i < sizeof(ulong) * 8; i++) + { + if (CheckFreeAcc(ns, ne, acc, i) == true) + return (i); + } + + return (-1); + } + + #region CheckFreeAcc + + private bool CheckFreeAcc(int ns, int ne, ulong[] acc, int n) + { + for (int i = ns; i < ne; i++) + { + ulong u = acc[i]; + + if ((u & (1ul << n)) != 0) + return (false); + } + + return (true); + } + + #endregion + + #endregion + + #region GetDayIndex + + /// + /// Gets the starting day index for the given appointment + /// + /// Week index + /// CalendarItem + /// Day of week index (0-6) + private int GetDayIndex(int week, CalendarItem item) + { + DateTime date = _MonthWeeks[week].FirstDayOfWeek; + + for (int i = 0; i < DaysInWeek; i++) + { + date = date.AddDays(1); + + if (date > item.StartTime) + return (i); + } + + return (0); + } + + #endregion + + #endregion + + #region UpdateMoreItems + + /// + /// UpdateMoreItems + /// + /// + /// + /// + private bool UpdateMoreItems(MonthWeek monthWeek, ulong[] acc, int week) + { + bool moreItems = false; + int weekOffset = week * DaysInWeek; + + int rowHeight = monthWeek.DayRects[0].Bounds.Height - + DayHeaderHeight - _MoreImageSize.Height - 1; + + for (int j = 0; j < DaysInWeek; j++) + { + int height = GetMoreHeight(acc[weekOffset + j]); + + if (CalendarView.IsMonthMoreItemsIndicatorVisible == false || height <= rowHeight) + { + monthWeek.MoreItems[j].Bounds = Rectangle.Empty; + } + else + { + moreItems = true; + + Rectangle r = monthWeek.DayRects[j].Bounds; + + r.X = r.Right - _MoreImageSize.Width; + r.Y = r.Bottom - _MoreImageSize.Height; + r.Size = _MoreImageSize; + + monthWeek.MoreItems[j].Bounds = r; + } + } + + return (moreItems); + } + + #region GetMoreHeight + + private int GetMoreHeight(ulong u) + { + int height = 0; + + while (u != 0) + { + height += AppointmentHeight; + + u = u >> 1; + } + + return (height); + } + + #endregion + + #endregion + + #endregion + + #region CalcMonthWeeks + + /// + /// Calculates display info for the MonthWeek data + /// + /// Start date + /// End date + private void CalcMonthWeeks(DateTime startDate, DateTime endDate) + { + // Get the number of weeks for the date range + + _NumberOfWeeks = DateHelper.GetNumberOfWeeks(startDate, endDate); + + _NumberOfWeeks = Math.Max(1, _NumberOfWeeks); + _NumberOfWeeks = Math.Min(_NumberOfWeeks, MaxNumberOfWeeks); + + // Allocate our MonthWeeks array to + // hold our weeks info + + if (_MonthWeeks == null || _MonthWeeks.Length != _NumberOfWeeks) + _MonthWeeks = new MonthWeek[_NumberOfWeeks]; + + // Update display info on each week + + float dy = 0; + + float weekHeight = + ((float)ClientRect.Height - DayOfWeekHeaderHeight) / _NumberOfWeeks; + + int sx = ClientRect.X + SideBarWidth; + int sy = ClientRect.Y + DayOfWeekHeaderHeight; + int y2 = sy; + + // Loop through each week + + for (int i = 0; i < _NumberOfWeeks; i++) + { + if (_MonthWeeks[i] == null) + _MonthWeeks[i] = new MonthWeek(this); + + // Set the weeks first day of the week + + _MonthWeeks[i].FirstDayOfWeek = startDate.AddDays(i * DaysInWeek); + + // Calculate the bounding rect limits + + dy += weekHeight; + + int y1 = y2; + y2 = sy + (int)dy; + + if (i + 1 == _NumberOfWeeks) + y2 = ClientRect.Y + ClientRect.Height - 1; + + // Set the bounding rect + + _MonthWeeks[i].Bounds = + new Rectangle(sx, y1, ClientRect.Width - SideBarWidth - 1, y2 - y1); + } + } + + #endregion + + #endregion + + #endregion + + #region Paint processing + + #region Root paint code + + /// + /// Paint processing + /// + /// ItemPaintArgs + public override void Paint(ItemPaintArgs e) + { + // Set our current color table + + _ViewColor.SetColorTable(); + + // Only draw something if we have something to draw + + if (_NumberOfWeeks > 0) + { + // Calculate our drawing ranges + + int dayStart, dayEnd, dayCount; + int weekStart, weekEnd, weekCount; + + if (e.ClipRectangle.Contains(ClientRect)) + { + // The clipping rect encompasses our entire calendar + // so set our start and end values accordingly + + dayStart = 0; dayEnd = DaysInWeek - 1; + dayCount = DaysInWeek; + + weekStart = 0; weekEnd = _NumberOfWeeks - 1; + weekCount = _NumberOfWeeks; + } + else + { + // We only need to draw part of our calendar, so + // calculate our day and week count and range + + dayCount = GetDayRange(e, out dayStart, out dayEnd); + weekCount = GetWeekRange(e, out weekStart, out weekEnd); + } + + // Draw our calendar parts + + if (dayCount > 0) + { + DrawDayOfTheWeekHeader(e, dayStart, dayEnd); + + if (weekCount > 0) + { + DrawDays(e, weekStart, weekEnd, dayStart, dayEnd); + + if (Connector != null && Connector.IsConnected) + DrawWeekAppointments(e, weekStart, weekEnd); + } + } + + if (_IsSideBarVisible == true && weekCount > 0) + DrawSideBarHeader(e, weekStart, weekEnd); + } + + // Let the base painting take place + + base.Paint(e); + } + + #region Clip range routines + + /// + /// Calculates the range of days needed to be drawn + /// to satisfy the specified paint request + /// + /// ItemPaintArgs + /// [out] Day start index + /// [out] Day end index + /// Day range count (end - start) + private int GetDayRange(ItemPaintArgs e, out int dayStart, out int dayEnd) + { + // Calc our starting index + + int start = 0; + + while (start < DaysInWeek) + { + Rectangle dr1 = _MonthWeeks[0].DayRects[start].Bounds; + + if (dr1.Right >= e.ClipRectangle.X) + break; + + start++; + } + + // Calc our ending index + + int end = start; + + while (end < DaysInWeek) + { + Rectangle dr2 = _MonthWeeks[0].DayRects[end].Bounds; + + if (dr2.X >= e.ClipRectangle.Right) + break; + + end++; + } + + // Set the user supplied 'out' values, and + // return the range count to the caller + + if (end - start == 0) + { + dayStart = 0; + dayEnd = 0; + + return (0); + } + + dayStart = start; + dayEnd = end - 1; + + return (end - start); + } + + /// + /// Calculates the range of weeks needed to be drawn + /// to satisfy the specified paint request + /// + /// ItemPaintArgs + /// [out] Week start index + /// [out] Week end index + /// Week range count (end - start) + private int GetWeekRange(ItemPaintArgs e, out int weekStart, out int weekEnd) + { + // Calc our starting index + + int start = 0; + + while (start < _NumberOfWeeks) + { + if (_MonthWeeks[start].Bounds.Bottom > e.ClipRectangle.Y) + break; + + start++; + } + + // Calc our ending index + + int end = start; + + while (end < _NumberOfWeeks) + { + if (_MonthWeeks[end].Bounds.Y >= e.ClipRectangle.Bottom) + break; + + end++; + } + + // Set the user supplied 'out' values, and + // return the range count to the caller + + if (end - start == 0) + { + weekStart = 0; + weekEnd = 0; + + return (0); + } + + weekStart = start; + weekEnd = end - 1; + + return (end - start); + } + + #endregion + + #endregion + + #region DayOfTheWeek header drawing + + #region DrawDayOfTheWeekHeader + + /// + /// Draws the top Day of the week header + /// + /// ItemPaintArgs + /// Start day index + /// End day index + private void DrawDayOfTheWeekHeader(ItemPaintArgs e, int dayStart, int dayEnd) + { + Graphics g = e.Graphics; + + Rectangle r = new Rectangle(ClientRect.X - 1, ClientRect.Y - 1, + SideBarWidth + 1, DayOfWeekHeaderHeight + 1); + + using (Brush br = + _ViewColor.BrushPart((int)eCalendarMonthPart.OwnerTabContentBackground, r)) + { + g.FillRectangle(br, r); + } + + // Calculate our contiguous header rect + // area so we can fill it all at once + + r = new Rectangle( + _MonthWeeks[0].DayRects[dayStart].Bounds.X, ClientRect.Y, + _MonthWeeks[0].DayRects[dayEnd].Bounds.Right - + _MonthWeeks[0].DayRects[dayStart].Bounds.X, DayOfWeekHeaderHeight); + + if (r.Width > 0 && r.Height > 0) + { + using (Brush lbr = + _ViewColor.BrushPart((int)eCalendarMonthPart.DayOfTheWeekHeaderBackground, r)) + { + g.FillRectangle(lbr, r); + } + + // Establish our Days Of The Week text type + + DaysOfTheWeek.eDayType type = GetDaysOfTheWeekType(g); + + // Loop through each day, drawing the + // day of the week text in the header area + + eTextFormat tf = eTextFormat.VerticalCenter | eTextFormat.NoPadding; + + using (Pen pen = new Pen( + _ViewColor.GetColor((int)eCalendarMonthPart.DayOfTheWeekHeaderBorder))) + { + for (int i = dayStart; i <= dayEnd; i++) + { + r.X = _MonthWeeks[0].DayRects[i].Bounds.X; + r.Width = _MonthWeeks[0].DayRects[i].Bounds.Width; + + if (CalendarView.DoPreRenderMonthHeader(g, this, i, r) == false) + { + // Center the header text until the text + // will no longer fit, then left justify it + + if (DaysOfTheWeek.DaySize[(int) type][i].Width < r.Width) + tf |= eTextFormat.HorizontalCenter; + + // Draw the text and header border + + TextDrawing.DrawString(g, DaysOfTheWeek.DayText[(int) type][i], Font, + _ViewColor.GetColor((int) eCalendarMonthPart.DayOfTheWeekHeaderForeground), r, tf); + + CalendarView.DoPostRenderMonthHeader(g, this, i, r); + } + + g.DrawRectangle(pen, r); + } + } + } + } + + #endregion + + #region GetDaysOfTheWeekType + + private DaysOfTheWeek.eDayType GetDaysOfTheWeekType(Graphics g) + { + // Determine if the current DayRect bounds + // are constrained by the text threshold + + DaysOfTheWeek.MeasureText(g, Font); + + for (int i = 0; i < DaysInWeek; i++) + { + if (_MonthWeeks[0].DayRects[i].Bounds.Width < + DaysOfTheWeek.DaySize[(int)DaysOfTheWeek.eDayType.Long][i].Width) + { + return (DaysOfTheWeek.eDayType.Short); + } + } + + return (DaysOfTheWeek.eDayType.Long); + } + + #endregion + + #endregion + + #region Day drawing + + #region DrawDays + + /// + /// Draws day header and content + /// + /// ItemPaintArgs + /// Week start index + /// Week end index + /// Day start index + /// Day end index + private void DrawDays(ItemPaintArgs e, + int weekStart, int weekEnd, int dayStart, int dayEnd) + { + Graphics g = e.Graphics; + + Rectangle r = new Rectangle( + _MonthWeeks[0].DayRects[dayStart].Bounds.X, 0, + _MonthWeeks[0].DayRects[dayEnd].Bounds.Right - + _MonthWeeks[0].DayRects[dayStart].Bounds.X, DayHeaderHeight); + + if (r.Width > 0 && r.Height > 0) + { + // Loop through each day in each week, displaying + // the associated day content and header + + int nowHeaderWeek = -1; + int nowHeaderDay = -1; + + DateTime now = DateTime.Now; + + using (Pen pen1 = new Pen( + _ViewColor.GetColor((int) eCalendarMonthPart.DayContentBorder))) + { + using (Pen pen2 = new Pen( + _ViewColor.GetColor((int) eCalendarMonthPart.DayHeaderBorder))) + { + for (int i = weekStart; i <= weekEnd; i++) + { + for (int j = dayStart; j <= dayEnd; j++) + { + if (CalendarView.HighlightCurrentDay == true) + { + DateTime date = _MonthWeeks[i].FirstDayOfWeek.AddDays(j); + + if (now.Date.Equals(date.Date) == true) + { + nowHeaderDay = i; + nowHeaderWeek = j; + + continue; + } + } + + DrawDayBackground(g, i, j, eCalendarMonthPart.DayHeaderBackground); + + DrawDayContent(g, i, j, pen1); + DrawDayHeader(g, i, j, pen2); + } + } + } + } + + // Draw "Now" day header and border + + if (nowHeaderDay >= 0) + { + using (Pen pen1 = new Pen( + _ViewColor.GetColor((int) eCalendarMonthPart.NowDayHeaderBorder))) + { + using (Pen pen2 = new Pen( + _ViewColor.GetColor((int) eCalendarMonthPart.NowDayHeaderBorder))) + { + DrawDayBackground(g, nowHeaderDay, nowHeaderWeek, eCalendarMonthPart.NowDayHeaderBackground); + + DrawDayContent(g, nowHeaderDay, nowHeaderWeek, pen1); + DrawDayHeader(g, nowHeaderDay, nowHeaderWeek, pen2); + } + } + } + } + } + + #region DrawDayBackground + + /// + /// DrawDayBackground + /// + /// + /// + /// + /// + private void DrawDayBackground(Graphics g, + int week, int day, eCalendarMonthPart part) + { + Rectangle r = _MonthWeeks[week].DayRects[day].Bounds; + r.Height = DayHeaderHeight; + + using (Brush br = _ViewColor.BrushPart((int)part, r)) + g.FillRectangle(br, r); + } + + #endregion + + #endregion + + #region DrawDayContent + + /// + /// Draws the day content + /// + /// + /// Week index + /// Day index + /// Pen + private void DrawDayContent(Graphics g, int iweek, int iday, Pen pen) + { + Rectangle r = _MonthWeeks[iweek].DayRects[iday].Bounds; + + r.Y += DayHeaderHeight; + r.Height -= DayHeaderHeight; + + DrawBackground(g, iweek, iday, r); + DrawMoreImage(g, iweek, iday, r); + DrawBorder(g, pen, iweek, r); + } + + #region DrawBackground + + private void DrawBackground(Graphics g, + int iweek, int iday, Rectangle r) + { + DateTime date = _MonthWeeks[iweek].FirstDayOfWeek.AddDays(iday); + int dayMonth = date.Month; + + DateTime startTime = date; + DateTime endTime = date.AddDays(1).AddMinutes(-1); + + eSlotDisplayState state = GetSlotState(iweek, iday, dayMonth); + + if (CalendarView.DoMonthViewPreRenderSlotBackground( + g, this, startTime, endTime, r, ref state) == false) + { + eCalendarMonthPart part = GetContentPart(state); + + using (Brush br = _ViewColor.BrushPart((int)part, r)) + g.FillRectangle(br, r); + + CalendarView.DoMonthViewPostRenderSlotBackground( + g, this, startTime, endTime, r, state); + } + } + + #region GetSlotState + + /// + /// GetSlotState + /// + /// + private eSlotDisplayState + GetSlotState(int iweek, int iday, int dayMonth) + { + eSlotDisplayState state = eSlotDisplayState.None; + + if (DisplayedOwnerKeyIndex == CalendarView.SelectedOwnerIndex) + { + if (_MonthWeeks[iweek].DayRects[iday].IsSelected) + state |= eSlotDisplayState.Selected; + } + + if (dayMonth == StartDate.Month) + state |= eSlotDisplayState.Work; + + return (state); + } + + #endregion + + #region GetContentPart + + /// + /// Gets the content calendar part for the given + /// week and dayMonth + /// + /// + private eCalendarMonthPart GetContentPart(eSlotDisplayState state) + { + if ((state & eSlotDisplayState.Selected) == eSlotDisplayState.Selected) + return (eCalendarMonthPart.DayContentSelectionBackground); + + if ((state & eSlotDisplayState.Work) == eSlotDisplayState.Work) + return (eCalendarMonthPart.DayContentActiveBackground); + + return (eCalendarMonthPart.DayContactInactiveBackground); + } + + #endregion + + #endregion + + #region DrawMoreImage + + private void DrawMoreImage(Graphics g, int iweek, int iday, Rectangle r) + { + ItemRect moreRect = _MonthWeeks[iweek].MoreItems[iday]; + + if (moreRect.Bounds.IsEmpty == false) + { + Bitmap bm = moreRect.IsSelected ? GetMoreImageHot(g) : GetMoreImage(g); + + if (bm != null) + { + Region regSave = g.Clip; + + g.SetClip(r, CombineMode.Intersect); + g.DrawImageUnscaledAndClipped(bm, moreRect.Bounds); + g.Clip = regSave; + } + } + } + + #endregion + + #region DrawBorder + + private void DrawBorder( + Graphics g, Pen pen, int iweek, Rectangle r) + { + if (iweek < _NumberOfWeeks - 1) + r.Height--; + + g.DrawRectangle(pen, r); + } + + #endregion + + #endregion + + #region DrawDayHeader + + /// + /// Draws day header + /// + /// + /// Week index + /// Day index + /// Text pen + private void DrawDayHeader(Graphics g, int iweek, int iday, Pen pen) + { + // Calculate the display rect and draw the text + + Rectangle r = _MonthWeeks[iweek].DayRects[iday].Bounds; + r.Height = Math.Min(DayHeaderHeight, r.Height); + + if (r.Height > 0) + { + // Draw the border area + + g.DrawRectangle(pen, r); + + // Get the associated day and text + + DateTime day = _MonthWeeks[iweek].FirstDayOfWeek.AddDays(iday); + + string s = GetDayHeaderText(day); + + r.Inflate(-2, 0); + + TextDrawing.DrawString(g, s, BoldFont, + _ViewColor.GetColor((int)eCalendarMonthPart.DayHeaderForeground), r, + eTextFormat.VerticalCenter | eTextFormat.Left | eTextFormat.NoPadding); + } + } + + #region GetDayHeaderText + + /// + /// GetDayHeaderText + /// + /// + /// + private string GetDayHeaderText(DateTime date) + { + if (date.Day == 1) + { + DateTimeFormatInfo dtfi = + ScheduleSettings.GetActiveCulture().DateTimeFormat; + + string s = dtfi.MonthDayPattern.Replace("dd", "d"); + + return (date.ToString(s)); + } + + return (String.Format("{0}", date.Day)); + } + + #endregion + + #endregion + + #endregion + + #region DrawWeekAppointments + + /// + /// Initiates the drawing of weekly appointments + /// + /// ItemPaintArgs + /// Week start index + /// Week end index + private void DrawWeekAppointments(ItemPaintArgs e, int weekStart, int weekEnd) + { + Graphics g = e.Graphics; + + // Loop through each subItem - on a weekly basis - so that + // we can set an appropriate clipping region for the week + + for (int i = weekStart; i <= weekEnd; i++) + { + List items = _MonthWeeks[i].CalendarItems; + + if (items.Count > 0) + { + // Set our week-based clipping region + + Rectangle r = _MonthWeeks[i].Bounds; + r.Height -= 1; + + Region regSave = g.Clip; + + g.SetClip(r, CombineMode.Intersect); + + // Loop through each CalendarItem in the week + + for (int j = 0; j < items.Count; j++) + { + // If we can display the item, then initiate the paint + + if (items[j].Displayed == true) + { + if (e.ClipRectangle.IsEmpty || + e.ClipRectangle.IntersectsWith(items[j].DisplayRectangle)) + { + items[j].Paint(e); + } + } + } + + // Restore the original clip region + + g.Clip = regSave; + + regSave.Dispose(); + } + } + } + + #endregion + + #region GetMoreImage + + private Bitmap GetMoreImage(Graphics g) + { + if (_MoreImage == null) + _MoreImage = GetMoreBitmap(g, Color.LightGray); + + return (_MoreImage); + } + + #endregion + + #region GetMoreImageHot + + private Bitmap GetMoreImageHot(Graphics g) + { + if (_MoreImageHot == null) + _MoreImageHot = GetMoreBitmap(g, _ViewColor.GetColor((int)eCalendarMonthPart.NowDayHeaderBorder)); + + return (_MoreImageHot); + } + + #endregion + + #region GetMoreBitmap + + private Bitmap GetMoreBitmap(Graphics g, Color color) + { + Bitmap bmp = new Bitmap(_MoreImageSize.Width, _MoreImageSize.Height, g); + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + gBmp.CompositingQuality = CompositingQuality.HighQuality; + gBmp.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = GetMoreImagePath()) + { + using (Brush br = new SolidBrush(color)) + gBmp.FillPath(br, path); + + gBmp.DrawPath(Pens.White, path); + } + } + + return (bmp); + } + + #endregion + + #region GetMoreImagePath + + /// + /// Gets the More image path + /// + /// + private GraphicsPath GetMoreImagePath() + { + GraphicsPath path = new GraphicsPath(); + + path.AddLines(new Point[] + { + new Point(2, 3), + new Point(7, 11), + new Point(12, 3) + }); + + path.CloseAllFigures(); + + return (path); + } + + #endregion + + #region SideBar header drawing + + /// + /// Draws the SideBar header + /// + /// ItemPaintArgs + /// Week start index + /// Week end index + private void DrawSideBarHeader(ItemPaintArgs e, int weekStart, int weekEnd) + { + // Calc the contiguous SideBar background rect + + Rectangle r = new Rectangle(ClientRect.X, _MonthWeeks[weekStart].Bounds.Y, + SideBarWidth, _MonthWeeks[weekEnd].Bounds.Bottom - _MonthWeeks[weekStart].Bounds.Y); + + // Make sure we have something to draw + + if (r.Height > 0 && r.Width > 0 && e.ClipRectangle.IntersectsWith(r)) + { + Graphics g = e.Graphics; + + // Fill the bar with our color gradient + + using (Brush lbr = _ViewColor.BrushPart((int)eCalendarMonthPart.SideBarBackground, r)) + { + g.FillRectangle(lbr, r); + } + + // Set uo our output to have both + // vertically and horizontally centered text + + using (StringFormat sf = new StringFormat()) + { + sf.FormatFlags = StringFormatFlags.NoWrap; + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + // Calc our rect origin and prepare to + // output the SideBar text + + PointF ptf = new PointF(ClientRect.X, 0); + Rectangle rf = new Rectangle(0, 0, 0, SideBarWidth); + + using (Brush br = + _ViewColor.BrushPart((int)eCalendarMonthPart.SideBarForeground, rf)) + { + using (Pen pen = new Pen( + _ViewColor.GetColor((int)eCalendarMonthPart.SideBarBorder))) + { + // Loop through each individual week, displaying + // the rotated header text appropriately + + for (int i = weekStart; i <= weekEnd; i++) + { + rf.Width = _MonthWeeks[i].Bounds.Height; + + if (rf.Width > 0) + { + ptf.Y = _MonthWeeks[i].Bounds.Y + rf.Width; + + g.TranslateTransform(ptf.X, ptf.Y); + g.RotateTransform(-90); + + g.DrawString(_MonthWeeks[i].WeekRange, Font, br, rf, sf); + g.DrawRectangle(pen, rf.X, rf.Y, rf.Width, rf.Height); + + g.ResetTransform(); + } + } + } + } + } + } + } + + #endregion + + #endregion + + #region Mouse routines + + #region MouseDown processing + + /// + /// MouseDown event processing + /// + /// + public override void InternalMouseDown(MouseEventArgs objArg) + { + // Forward on the event + + base.InternalMouseDown(objArg); + + if (objArg.Button == MouseButtons.Left) + { + if (IsTabMoving == false) + { + // Locate where the event took place + + int week, day; + + if (GetPointItem(objArg.Location, out week, out day)) + { + MyCursor = GetCursor(); + + if (ProcessCilButtonDown(week, day) == false) + { + if (ProcessMoreButtonDown(week, day) == false) + ProcessMvlButtonDown(week, day); + } + } + + IsCopyDrag = false; + } + } + } + + #region CalendarItem MouseDown processing + + /// + /// CalendarItem left mouseDown processing + /// + /// Week index + /// Day index + private bool ProcessCilButtonDown(int week, int day) + { + CalendarItem item = m_HotSubItem as CalendarItem; + + if (item != null) + { + if (item.HitArea != CalendarItem.eHitArea.None) + { + // Give the user a chance to cancel the + // operation before it starts + + if (CalendarView.DoBeforeAppointmentViewChange(this, item, + ((item.HitArea == CalendarItem.eHitArea.Move) ? + eViewOperation.AppointmentMove : eViewOperation.AppointmentResize)) == false) + { + if (IsResizing == false && IsMoving == false) + { + OldStartTime = item.StartTime; + OldEndTime = item.EndTime; + OldOwnerKey = OwnerKey; + } + + // Flag appropriate action + + if (item.HitArea == CalendarItem.eHitArea.LeftResize) + IsStartResizing = true; + + else if (item.HitArea == CalendarItem.eHitArea.RightResize) + IsEndResizing = true; + + else if (item.HitArea == CalendarItem.eHitArea.Move) + { + TimeSpan ts = _MonthWeeks[week].FirstDayOfWeek.AddDays(day) - item.StartTime; + + _DaysOffset = (int)(Math.Ceiling(ts.TotalDays)); + + IsMoving = true; + } + } + } + + return (true); + } + + return (false); + } + + #endregion + + #region MonthView MouseDown processing + + /// + /// Handles MonthView left MouseDown events + /// + /// Week index + /// Day index + private void ProcessMvlButtonDown(int week, int day) + { + DateTime startDate = _MonthWeeks[week].FirstDayOfWeek.AddDays(day); + DateTime endDate = startDate.AddDays(1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + SelectedItem = null; + } + + #endregion + + #region MoreItems MouseDown processing + + /// + /// ProcessMoreButtonDown + /// + /// + /// + /// + private bool ProcessMoreButtonDown(int week, int day) + { + if (CalendarView.IsMonthMoreItemsIndicatorVisible == true) + { + ItemRect moreRect = _MonthWeeks[week].MoreItems[day]; + + if (moreRect.IsSelected == true) + { + eCalendarView calendarView = eCalendarView.Day; + DateTime startDate = _MonthWeeks[week].FirstDayOfWeek.AddDays(day); + + if (CalendarView.DoMonthMoreItemsIndicatorClick( + this, ref calendarView, ref startDate) == false) + { + moreRect.IsSelected = false; + + DateSelectionAnchor = null; + CalendarView.DateSelectionStart = null; + CalendarView.DateSelectionEnd = null; + + CalendarView.SelectedView = calendarView; + CalendarView.EnsureVisible(startDate, startDate); + } + + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region MouseMove processing + + /// + /// MouseMove event processing + /// + /// MouseEventArgs + public override void InternalMouseMove(MouseEventArgs objArg) + { + // Forward on the event, but only if we are not in + // the middle of moving or resizing a CalendarItem + + if (Control.MouseButtons == MouseButtons.None) + ClearMouseStates(); + + if (!IsMoving && !IsStartResizing && !IsEndResizing) + base.InternalMouseMove(objArg); + + if (IsTabMoving == false) + { + // Set the cursor + + MyCursor = GetCursor(); + + int week, day; + + bool inItem = GetPointItem(objArg.Location, out week, out day); + + switch (objArg.Button) + { + case MouseButtons.Left: + if (DragDropAppointment(objArg) == false) + { + // Locate where the event took place + // and process it accordingly + + if (inItem == true) + { + if (DateSelectionAnchor != null) + { + ProcessMvMouseMove(week, day); + } + else if (SelectedItem != null) + { + if (IsMoving == true) + ProcessItemMove(week, day); + + else if (IsStartResizing == true) + ProcessItemLeftResize(week, day); + + else if (IsEndResizing == true) + ProcessItemRightResize(week, day); + } + } + } + break; + + case MouseButtons.None: + if (inItem == true) + ProcessMoreMouseMove(week, day, objArg); + break; + } + } + } + + #region GetCursor + + /// + /// Gets the cursor + /// + /// Cursor + private Cursor GetCursor() + { + CalendarItem item = m_HotSubItem as CalendarItem; + + if (item != null) + { + switch (item.HitArea) + { + case CalendarItem.eHitArea.LeftResize: + case CalendarItem.eHitArea.RightResize: + return (Cursors.SizeWE); + + case CalendarItem.eHitArea.Move: + return (IsMoving ? Cursors.SizeAll : DefaultCursor); + } + } + + return (DefaultCursor); + } + + #endregion + + #region DragDropAppointment + + /// + /// Initiates a user "DragDrop" operation - if enabled + /// + /// + /// True if operation started + private bool DragDropAppointment(MouseEventArgs objArgs) + { + if (IsMoving == true && CanDrag == true) + { + Point pt = objArgs.Location; + BaseView bv = CalendarView.GetViewFromPoint(pt); + MonthView mv = bv as MonthView; + + if (mv != null && mv != this) + { + eViewArea area = mv.GetViewAreaFromPoint(pt); + + if (area == eViewArea.InContent) + { + bool isNewCopyDrag = IsNewCopyDrag; + + if (CalendarView.DoAppointmentViewChanging(SelectedItem, mv.OwnerKey, SelectedItem.StartTime, + SelectedItem.EndTime, eViewOperation.AppointmentMove, isNewCopyDrag) == false) + { + DragCopy(); + ClearMouseStates(); + + if (PosWin != null) + PosWin.Hide(); + + AppointmentView av = SelectedItem as AppointmentView; + + if (av != null) + return (mv.DragAppointment(this, av, pt, isNewCopyDrag)); + + CustomCalendarItem ci = SelectedItem as CustomCalendarItem; + + if (ci != null) + return (mv.DragCustomItem(this, ci, pt, isNewCopyDrag)); + } + } + } + } + + return (false); + } + + #region DragCustomItem + + private bool DragCustomItem( + MonthView pv, CustomCalendarItem ci, Point pt, bool isNewCopyDrag) + { + // Set the new owner and selected view, and + // recalc the new layout + + ci.OwnerKey = OwnerKey; + + DateTime sd = ci.StartTime; + TimeSpan ts = ci.EndTime.Subtract(ci.StartTime); + + int week = GetPointWeek(pt); + int day = GetPointDay(pt, week); + + MonthWeek mw = _MonthWeeks[week]; + DateTime date = mw.FirstDayOfWeek.AddDays(day - pv._DaysOffset); + + ci.StartTime = new + DateTime(date.Year, date.Month, date.Day, sd.Hour, sd.Minute, 0); + + ci.EndTime = ci.StartTime.Add(ts); + + NeedRecalcLayout = true; + RecalcSize(); + + CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex; + + // Get the new view + + CustomCalendarItem view = GetCustomCalendarItem(ci); + + if (view != null) + SetNewDragItem(pv, view, isNewCopyDrag); + + return (true); + } + + #endregion + + #region DragAppointment + + /// + /// Drags the given appointment from one view to another + /// + /// Previous view + /// AppointmentView + /// Point + private bool DragAppointment( + MonthView pv, AppointmentView av, Point pt, bool isNewCopyDrag) + { + // Set the new owner and selected view, and + // recalc the new layout + + av.Appointment.OwnerKey = OwnerKey; + + DateTime sd = av.Appointment.StartTime; + + int week = GetPointWeek(pt); + + if (week >= 0) + { + int day = GetPointDay(pt, week); + + MonthWeek mw = _MonthWeeks[week]; + + DateTime date = mw.FirstDayOfWeek.AddDays(day - pv._DaysOffset); + + av.Appointment.MoveTo( + new DateTime(date.Year, date.Month, date.Day, sd.Hour, sd.Minute, 0)); + + NeedRecalcLayout = true; + RecalcSize(); + + CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex; + + // Get the new appointment view + + AppointmentView view = GetAppointmentView(av.Appointment); + + if (view != null) + SetNewDragItem(pv, view, isNewCopyDrag); + } + + return (true); + } + + #endregion + + #region SetNewDragItem + + private void SetNewDragItem(MonthView pv, CalendarItem view, bool isNewCopyDrag) + { + CalendarView.CalendarPanel.InternalMouseMove(new + MouseEventArgs(MouseButtons.None, 0, view.Bounds.X + 5, view.Bounds.Y, 0)); + + MouseEventArgs args = new + MouseEventArgs(MouseButtons.Left, 1, view.Bounds.X + 5, view.Bounds.Y, 0); + + IsMoving = true; + + InternalMouseMove(args); + CalendarView.CalendarPanel.InternalMouseDown(args); + + _DaysOffset = pv._DaysOffset; + + SelectedItem = view; + + IsCopyDrag = true; + IsNewCopyDrag = isNewCopyDrag; + } + + #endregion + + #endregion + + #region MonthView mouseMove processing + + /// + /// Processes MonthView mouseMove events + /// + /// + /// + private void ProcessMvMouseMove(int week, int day) + { + DateTime date = _MonthWeeks[week].FirstDayOfWeek.AddDays(day); + + // Let the user select forwards or backwards + + if (date >= DateSelectionAnchor) + { + CalendarView.DateSelectionStart = DateSelectionAnchor.Value; + CalendarView.DateSelectionEnd = date.AddDays(1); + } + else + { + CalendarView.DateSelectionStart = date; + CalendarView.DateSelectionEnd = DateSelectionAnchor.Value.AddDays(1); + } + } + + #endregion + + #region MoreItems MouseMove processing + + /// + /// ProcessMoreMouseMove + /// + /// + /// + /// + private void ProcessMoreMouseMove(int week, int day, MouseEventArgs objArg) + { + ItemRect moreRect = _MonthWeeks[week].MoreItems[day]; + + if (moreRect.Bounds.Contains(objArg.Location) == true) + { + if (_MoreRect != moreRect) + { + if (_MoreRect != null) + _MoreRect.IsSelected = false; + + _MoreRect = moreRect; + _MoreRect.IsSelected = true; + } + } + else + { + if (_MoreRect != null) + { + _MoreRect.IsSelected = false; + _MoreRect = null; + } + } + } + + #endregion + + #region CalendarItem mouseMove processing + + /// + /// Processes CalendarItem mouseMove events + /// + /// Week index + /// Day index + private void ProcessItemMove(int week, int day) + { + day -= _DaysOffset; + + DateTime date = + _MonthWeeks[week].FirstDayOfWeek.AddDays(day); + + DateTime newDate = new DateTime(date.Year, date.Month, date.Day, + SelectedItem.StartTime.Hour, SelectedItem.StartTime.Minute, + SelectedItem.StartTime.Second); + + TimeSpan ts = SelectedItem.EndTime - SelectedItem.StartTime; + + int startWeek1, endWeek1; + int day1 = GetCalendarItemWeekRange(SelectedItem, out startWeek1, out endWeek1); + + if (startWeek1 != week || day1 != day) + { + if (DragCopy() == false) + { + try + { + if (SelectedItem is CustomCalendarItem) + CalendarView.CustomItems.BeginUpdate(); + else + CalendarModel.BeginUpdate(); + + // Let the user cancel the operation if desired + + if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, newDate, + newDate + ts, eViewOperation.AppointmentMove, IsNewCopyDrag) == false) + { + SelectedItem.StartTime = newDate; + SelectedItem.EndTime = newDate + ts; + + int startWeek2, endWeek2; + GetCalendarItemWeekRange(SelectedItem, out startWeek2, out endWeek2); + + startWeek1 = Math.Min(startWeek1, startWeek2); + endWeek1 = Math.Max(endWeek1, endWeek2); + + for (int i = startWeek1; i <= endWeek1; i++) + InvalidateRect(_MonthWeeks[i].Bounds, true); + } + } + finally + { + if (SelectedItem is CustomCalendarItem) + CalendarView.CustomItems.EndUpdate(); + else + CalendarModel.EndUpdate(); + } + } + } + } + + /// + /// Gets the CalendarItems current week/day range + /// + /// CalendarItem + /// [out] Start week index + /// [out] End week index + /// Day index + private int GetCalendarItemWeekRange( + CalendarItem item, out int startWeek, out int endWeek) + { + startWeek = -1; + endWeek = -1; + + int day = 0; + + for (int i = 0; i < _NumberOfWeeks; i++) + { + DateTime startTime = _MonthWeeks[i].FirstDayOfWeek; + DateTime endTime = startTime.AddDays(DaysInWeek); + + if (item.StartTime < endTime && item.EndTime > startTime) + { + if (startWeek < 0) + { + startWeek = i; + day = item.StartTime.Day - startTime.Day; + } + + endWeek = i; + } + } + + if (startWeek == -1) + { + startWeek = 0; + endWeek = _NumberOfWeeks - 1; + + day = 0; + } + + return (day); + } + + #endregion + + #region CalendarItem mouseResize processing + + /// + /// Processes CalendarItem left resizing + /// + /// Week index + /// Day index + private void ProcessItemLeftResize(int week, int day) + { + DateTime date = + _MonthWeeks[week].FirstDayOfWeek.AddDays(day); + + DateTime newStartTime = new DateTime(date.Year, date.Month, date.Day, + SelectedItem.StartTime.Hour, SelectedItem.StartTime.Minute, + SelectedItem.StartTime.Second); + + if (newStartTime < SelectedItem.EndTime && SelectedItem.StartTime != newStartTime) + { + // Let the user cancel the operation if desired + + if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, newStartTime, + SelectedItem.EndTime, eViewOperation.AppointmentResize, IsNewCopyDrag) == false) + { + SelectedItem.StartTime = newStartTime; + + InvalidateRect(true); + } + } + } + + /// + /// Processes CalendarItem right resizing + /// + /// Week index + /// Day index + private void ProcessItemRightResize(int week, int day) + { + DateTime date = + _MonthWeeks[week].FirstDayOfWeek.AddDays(day); + + DateTime newEndTime = new DateTime(date.Year, date.Month, date.Day, + SelectedItem.EndTime.Hour, SelectedItem.EndTime.Minute, + SelectedItem.EndTime.Second); + + if (newEndTime.Hour == 0 && newEndTime.Minute == 0 && newEndTime.Second == 0) + newEndTime = newEndTime.AddDays(1); + + if (newEndTime > SelectedItem.StartTime && SelectedItem.EndTime != newEndTime) + { + // Let the user cancel the operation if desired + + if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, SelectedItem.StartTime, + newEndTime, eViewOperation.AppointmentResize, IsNewCopyDrag) == false) + { + SelectedItem.EndTime = newEndTime; + + InvalidateRect(true); + } + } + } + + #endregion + + #endregion + + #region Mouse support routines + + /// + /// Gets the week and day index item for + /// the given point + /// + /// Point + /// [out] Week index + /// [out] Day index + /// Success or failure + private bool GetPointItem(Point pt, out int week, out int day) + { + day = -1; + + if ((week = GetPointWeek(pt)) >= 0) + { + if ((day = GetPointDay(pt, week)) >= 0) + return (true); + } + + return (false); + } + + /// + /// Gets the week index for the given point + /// + /// Point + /// Week index + private int GetPointWeek(Point pt) + { + for (int i = 0; i < _NumberOfWeeks; i++) + { + Rectangle r = _MonthWeeks[i].Bounds; + + if (pt.X >= r.X && pt.X <= r.Right && pt.Y > r.Y && pt.Y < r.Bottom) + return (i); + } + + return (-1); + } + + /// + /// Gets the day index for the given point + /// + /// Point + /// Week index + /// Day index + private int GetPointDay(Point pt, int week) + { + ItemRects rs = _MonthWeeks[week].DayRects; + + for (int i = 0; i < DaysInWeek; i++) + { + Rectangle r = rs[i].Bounds; + + if (pt.X >= r.X && pt.X <= r.Right && pt.Y > r.Y && pt.Y < r.Bottom) + return (i); + } + + return (-1); + } + + #endregion + + #endregion + + #region InternalKeyDown + + #region InternalKeyDown + + /// + /// Processes KeyDown events + /// + /// + public override void InternalKeyDown(KeyEventArgs objArg) + { + switch (objArg.KeyData) + { + case Keys.Up: + case Keys.Up | Keys.Shift: + case Keys.Up | Keys.Control: + case Keys.Up | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, -7); + break; + + case Keys.Down: + case Keys.Down | Keys.Shift: + case Keys.Down | Keys.Control: + case Keys.Down | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, 7); + break; + + case Keys.Left: + case Keys.Left | Keys.Shift: + case Keys.Left | Keys.Control: + case Keys.Left | Keys.Control | Keys.Shift: + ProcessLeftRightKey(objArg, -1); + break; + + case Keys.Right: + case Keys.Right | Keys.Shift: + case Keys.Right | Keys.Control: + case Keys.Right | Keys.Control | Keys.Shift: + ProcessLeftRightKey(objArg, 1); + break; + + case Keys.Home: + case Keys.Home | Keys.Shift: + case Keys.Home | Keys.Control: + case Keys.Home | Keys.Control | Keys.Shift: + ProcessHomeKey(objArg); + break; + + case Keys.End: + case Keys.End | Keys.Shift: + case Keys.End | Keys.Control: + case Keys.End | Keys.Control | Keys.Shift: + ProcessEndKey(objArg); + break; + + case Keys.PageUp: + case Keys.PageUp | Keys.Shift: + case Keys.PageUp | Keys.Control: + case Keys.PageUp | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, -7); + break; + + case Keys.PageDown: + case Keys.PageDown | Keys.Shift: + case Keys.PageDown | Keys.Control: + case Keys.PageDown | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, 7); + break; + } + } + + #endregion + + #region ProcessUpDownKey + + /// + /// Processes Up and Down Key events + /// + /// + /// + protected virtual void ProcessUpDownKey(KeyEventArgs objArg, int dy) + { + if (ValidDateSelection()) + { + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + if (startDate.Equals(DateSelectionAnchor.Value) == true) + startDate = endDate.AddDays(-1); + + startDate = startDate.AddDays(dy); + endDate = startDate.AddDays(1); + + int week = GetWeekFromDate(startDate); + + if (week >= 0) + { + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + } + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessLeftRightKey + + /// + /// Processes Left and Right key events + /// + /// + /// + protected virtual void ProcessLeftRightKey(KeyEventArgs objArg, int dx) + { + if (ValidDateSelection()) + { + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + if (startDate.Equals(DateSelectionAnchor.Value) == true) + startDate = endDate.AddDays(-1); + + startDate = startDate.AddDays(dx); + endDate = startDate.AddDays(1); + + DateTime viewStart = _MonthWeeks[0].FirstDayOfWeek; + DateTime viewEnd = _MonthWeeks[_MonthWeeks.Length - 1].FirstDayOfWeek.AddDays(7); + + bool cancelled = false; + + if (startDate < viewStart || endDate > viewEnd) + { + cancelled = CalendarView.DoViewDateChanging(this, + StartDate, EndDate, ref startDate, ref endDate); + + if (cancelled == false) + CalendarView.EnsureVisible(startDate, startDate.AddDays(1)); + } + + if (cancelled == false) + { + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + } + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessHomeKey + + /// + /// Processes Hoe key events + /// + /// + protected virtual void ProcessHomeKey(KeyEventArgs objArg) + { + int week = ((objArg.Modifiers & Keys.Control) != Keys.Control) + ? GetHomeEndWeek() + : 0; + + if (week >= 0) + { + DateTime startDate = _MonthWeeks[week].FirstDayOfWeek; + DateTime endDate = startDate.AddDays(1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + SelectedItem = null; + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessEndKey + + /// + /// Processes End key events + /// + /// + protected virtual void ProcessEndKey(KeyEventArgs objArg) + { + int week = ((objArg.Modifiers & Keys.Control) != Keys.Control) + ? GetHomeEndWeek() + : _NumberOfWeeks - 1; + + if (week >= 0) + { + DateTime startDate = _MonthWeeks[week].FirstDayOfWeek.AddDays(6); + DateTime endDate = startDate.AddDays(1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + SelectedItem = null; + } + + objArg.Handled = true; + } + + #endregion + + #region GetWeekFromDate + + /// + /// Gets the week containing the given date + /// + /// + /// Week or -1 + private int GetWeekFromDate(DateTime date) + { + for (int i = 0; i < _NumberOfWeeks; i++) + { + DateTime dc = _MonthWeeks[i].FirstDayOfWeek; + + if (dc <= date && dc.AddDays(7) > date) + return (i); + } + + return (-1); + } + + #endregion + + #region GetHomeEndWeek + + /// + /// Gets the Home and End week from the + /// current selection range + /// + /// + private int GetHomeEndWeek() + { + if (ValidDateSelection() == true) + { + if (CalendarView.DateSelectionStart.Equals(DateSelectionAnchor.Value) == true) + return (GetWeekFromDate(DateSelectionEnd.Value.AddDays(-1))); + + return (GetWeekFromDate(DateSelectionStart.Value)); + } + + return (-1); + } + + #endregion + + #endregion + + #region IDisposable Members + + protected override void Dispose(bool disposing) + { + if (disposing == true && IsDisposed == false) + { + ResetView(); + HookEvents(false); + } + + base.Dispose(disposing); + } + + #endregion + + #region Copy object + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + MonthView objCopy = new MonthView(this.CalendarView); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the MonthView specific properties to new instance of the item. + /// + /// New MonthView instance + protected override void CopyToItem(BaseItem copy) + { + MonthView objCopy = copy as MonthView; + + if (objCopy != null) + { + base.CopyToItem(objCopy); + + objCopy._IsSideBarVisible = this._IsSideBarVisible; + } + } + + #endregion + } + + #region EventArgs + + #region IsSideBarVisibleChangedEventArgs + /// + /// IsSideBarVisibleChangedEventArgs + /// + public class IsSideBarVisibleChangedEventArgs : ValueChangedEventArgs + { + public IsSideBarVisibleChangedEventArgs(bool oldValue, bool newValue) + : base(oldValue, newValue) + { + } + } + #endregion + + #endregion +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/MonthView/MonthWeek.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/MonthView/MonthWeek.cs new file mode 100644 index 00000000..d8d00b32 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/MonthView/MonthWeek.cs @@ -0,0 +1,216 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Drawing; + +namespace DevComponents.DotNetBar.Schedule +{ + public class MonthWeek + { + #region Private constants + + private const int DaysInWeek = 7; + + #endregion + + #region Private variables + + private DateTime _FirstDayOfWeek; // First day of the week + private DateTime _LastDayOfWeek; // Last day of the week + + private Rectangle _Bounds; // Week bounding rectangle + private ItemRects _DayRects; // Day bounding Rectangles + private ItemRects _MoreItems; + + private List + _CalendarItems = new List(); + + #endregion + + /// + /// Constructor + /// + /// + public MonthWeek(BaseItem baseItem) + { + // Allocate our DayRects array + + _DayRects = new ItemRects(baseItem, DaysInWeek); + _MoreItems = new ItemRects(baseItem, DaysInWeek); + } + + #region Public properties + + #region CalendarItems + + /// + /// Gets array of CalendarItems + /// + public List CalendarItems + { + get { return (_CalendarItems); } + } + + #endregion + + #region FirstDayOfWeek + + /// + /// Gets the first day of the week + /// + public DateTime FirstDayOfWeek + { + get { return (_FirstDayOfWeek); } + + internal set + { + _FirstDayOfWeek = value; + + _LastDayOfWeek = _FirstDayOfWeek.AddDays(DaysInWeek - 1); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region Bounds + + /// + /// Gets and sets the week bounding Rectangle + /// + internal Rectangle Bounds + { + get { return (_Bounds); } + + set + { + if (_Bounds.Equals(value) == false) + { + _Bounds = value; + + CalcDayRects(); + } + } + } + + #endregion + + #region DayRects + + /// + /// Gets the day Rectangles + /// + internal ItemRects DayRects + { + get { return (_DayRects); } + } + + #endregion + + #region LastDayOfWeek + + internal DateTime LastDayOfWeek + { + get { return (_LastDayOfWeek); } + } + + #endregion + + #region MoreItems + + /// + /// Gets the MoreItems + /// + internal ItemRects MoreItems + { + get { return (_MoreItems); } + } + + #endregion + + #region WeekRange + + /// + /// Gets the week day range text + /// + internal string WeekRange + { + get + { + string s1 = String.Format("{0:MMM} {1:d} - ", + _FirstDayOfWeek, _FirstDayOfWeek.Day); + + if (_FirstDayOfWeek.Month.Equals(_LastDayOfWeek.Month) == false) + s1 = s1 + String.Format("{0:MMM} ", _LastDayOfWeek); + + s1 = s1 + String.Format("{0:d}", _LastDayOfWeek.Day); + + return (s1); + } + } + + #endregion + + #endregion + + #region Private properties + + /// + /// Gets day height + /// + private int DayHeight + { + get { return (_Bounds.Height); } + } + + /// + /// Gets day width + /// + private float DayWidth + { + get { return ((float)_Bounds.Width / DaysInWeek); } + } + + #endregion + + #region DayRect calculation + + /// + /// Calculates the day rectangles for the + /// current bounding rectangle + /// + private void CalcDayRects() + { + float dx = 0; + + int sx = _Bounds.X; + int sy = _Bounds.Y; + + int x2 = sx; + + // Loop through each day in the week + + for (int i = 0; i < DaysInWeek; i++) + { + int x1 = x2; + + x2 = sx + (int)(dx + DayWidth); + + dx += DayWidth; + + if (i + 1 == DaysInWeek) + x2 = _Bounds.X + _Bounds.Width; + + _DayRects[i].Bounds = + new Rectangle(x1, sy, x2 - x1, DayHeight); + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/NativeFunctions.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/NativeFunctions.cs new file mode 100644 index 00000000..f0401a5e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/NativeFunctions.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.Schedule +{ + internal class NativeFunctions + { + #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) + { + // F962CEC7-CD8F-4911-A9E9-CAB39962FC1F, 189, 266 + string[] parts = key.Split('-'); + int test = 0; + for (int i = parts.Length - 1; i >= 0; i--) + { + if (parts[i] == "A9E9") + test += 11; + else if (parts[i] == "F962CEC7") + test += 12; + else if (parts[i] == "CAB39962FC1F") + test += 2; + else if (parts[i] == "4911") + test += 99; + else if (parts[i] == "CD8F") + test += 65; + } + + keyValidated2 = test + 77; + + if (test == 23) + return false; + + return true; + } +#endif + #endregion + +#if TRIAL + private static Color m_ColorExpFlag=Color.Empty; + internal static bool CheckedThrough = false; + internal static bool ColorExpAlt() + { +#if NOTIMELIMIT + return false; +#else + Color clr=SystemColors.Control; + Color clr2; + Color clr3; + clr2=clr; + if(clr2.ToArgb()==clr.ToArgb()) + { + clr3=clr2; + } + else + { + clr3=clr; + } + + if(!m_ColorExpFlag.IsEmpty) + { + return (m_ColorExpFlag==Color.Black?false:true); + } + try + { + Microsoft.Win32.RegistryKey key=Microsoft.Win32.Registry.ClassesRoot; + try + { + key = key.CreateSubKey("CLSID\\{57FEED69-A5E0-45e7-8E02-5F4131F5EE63}\\InprocServer32"); + } + catch (System.UnauthorizedAccessException) + { + key = key.OpenSubKey("CLSID\\{57FEED69-A5E0-45e7-8E02-5F4131F5EE63}\\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>28) + { + m_ColorExpFlag=Color.White; + key.SetValue("","windows4.dll"); + key.Close(); + key=null; + return true; + } + if(((TimeSpan)DateTime.Today.Subtract(date)).TotalDays<0) + { + m_ColorExpFlag=Color.White; + key.SetValue("","windows3.dll"); + key.Close(); + key=null; + return true; + } + } + } + finally + { + if(key!=null) + key.Close(); + CheckedThrough = true; + } + } + catch{} + m_ColorExpFlag=Color.Black; + return false; +#endif + } +#endif + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/PosWin.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/PosWin.Designer.cs new file mode 100644 index 00000000..f03e287f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/PosWin.Designer.cs @@ -0,0 +1,59 @@ +#if FRAMEWORK20 +namespace DevComponents.DotNetBar.Schedule +{ + partial class PosWin + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // PosWin + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.CausesValidation = false; + this.ClientSize = new System.Drawing.Size(1, 1); + this.ControlBox = false; + this.DoubleBuffered = true; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Location = new System.Drawing.Point(1000, 1000); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "PosWin"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; + this.Text = "PosWin"; + this.Paint += new System.Windows.Forms.PaintEventHandler(this.PosWin_Paint); + this.ResumeLayout(false); + + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/PosWin.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/PosWin.cs new file mode 100644 index 00000000..1eb736e6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/PosWin.cs @@ -0,0 +1,219 @@ +#if FRAMEWORK20 +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Globalization; + +namespace DevComponents.DotNetBar.Schedule +{ + public partial class PosWin : Form + { + #region Private variables + + private BaseView _View; // BaseView + + private string _PosText = ""; // Window content + private int _PosHeight; // Calculated window height + + #endregion + + /// + /// Constructor + /// + public PosWin(BaseView view) + { + _View = view; + + InitializeComponent(); + } + + #region CreateParams / show support + + // This code permits us to be able to create a + // window with a drop shadow + + private const int CsDropshadow = 0x00020000; + + protected override CreateParams CreateParams + { + get + { + CreateParams parameters = base.CreateParams; + + parameters.ClassStyle = + (parameters.ClassStyle | CsDropshadow); + + return (parameters); + } + } + + protected override bool ShowWithoutActivation + { + get { return true; } + } + + #endregion + + #region Public properties + + /// + /// Gets and sets the window content text + /// + public string PosText + { + get { return (_PosText); } + + set + { + if (_PosText != value) + { + _PosText = value; + + this.Refresh(); + } + } + } + + /// + /// Gets the calculated window height + /// + public int PosHeight + { + get + { + if (_PosHeight <= 0) + { + using (Graphics g = CreateGraphics()) + { + Size sz = TextDrawing.MeasureString(g, "ABC", SystemFonts.CaptionFont, 0, + eTextFormat.Default | eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter); + + _PosHeight = sz.Height + 4; + } + } + + return (_PosHeight); + } + } + + #endregion + + #region UpdateWin + + /// + /// Updates the posWin + /// + /// View rectangle + public void UpdateWin(Rectangle viewRect) + { + CalendarItem item = _View.SelectedItem; + + if (item != null) + { + // Calculate where the window should be positioned + // and what time should be displayed + + Point pt = item.Bounds.Location; + DateTime time = item.StartTime; + + pt.X += item.Bounds.Width + 4; + + if (pt.X > _View.ClientRect.Right) + pt.X = _View.ClientRect.Right + 4; + + if (_View.NClientData.TabOrientation == eTabOrientation.Horizontal) + { + if (_View.SelectedItem.HitArea == CalendarItem.eHitArea.BottomResize) + { + pt.Y += (item.Bounds.Height - PosHeight); + time = item.EndTime; + } + } + else + { + if (_View.SelectedItem.HitArea == CalendarItem.eHitArea.RightResize) + time = item.EndTime; + } + + if (pt.Y < viewRect.Y) + pt.Y = viewRect.Y; + + // Convert the point to global coordinates + // and set our window position accordingly + + Control c = (Control)_View.GetContainerControl(true); + + if (c != null) + pt = c.PointToScreen(pt); + + Location = pt; + + // Set the window text and show the window + + string fmt = "t"; + + if (_View.ECalendarView == eCalendarView.TimeLine) + { + switch (_View.CalendarView.TimeLinePeriod) + { + case eTimeLinePeriod.Years: + fmt = ""; + PosText = time.Year.ToString(); + break; + + case eTimeLinePeriod.Days: + fmt = "g"; + break; + } + } + + if (fmt != "") + { + PosText = _View.CalendarView.Is24HourFormat == true + ? time.ToString(fmt, DateTimeFormatInfo.InvariantInfo) + : time.ToString(fmt, null); + } + + Show(); + } + } + + #endregion + + #region Paint processing + + /// + /// Paint processing + /// + /// + /// + private void PosWin_Paint(object sender, PaintEventArgs e) + { + Graphics g = e.Graphics; + + const eTextFormat tf = + eTextFormat.Default | eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter; + + Size sz = TextDrawing.MeasureString(g, _PosText, SystemFonts.CaptionFont, 0, tf); + + sz.Width += 6; + sz.Height += 4; + + this.Size = sz; + + int swidth = Screen.FromControl(this).Bounds.Width; + + if (Location.X + sz.Width > swidth) + Location = new Point(swidth - sz.Width, Location.Y); + + Rectangle r = new Rectangle(0, 0, sz.Width - 1, sz.Height - 1); + + g.DrawRectangle(Pens.Black, r); + + TextDrawing.DrawString(g, _PosText, SystemFonts.CaptionFont, Color.Black, r, tf); + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/PosWin.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/PosWin.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/PosWin.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/ScheduleSettings.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/ScheduleSettings.cs new file mode 100644 index 00000000..88115503 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/ScheduleSettings.cs @@ -0,0 +1,41 @@ +#if FRAMEWORK20 +using System.Globalization; + +namespace DevComponents.DotNetBar.Schedule +{ + public static class ScheduleSettings + { + public static double TimeSlotSliceHeight = 23d; + public static string TimeRulerHourFormatString = "00"; + public static string TimeRulerMinuteFormatString = "00"; + + private static CultureInfo _currentCulture; + + /// + /// Gets or sets the CultureInfo for the culture used by the DateTime and Numeric Input controls. + /// Default value is null which indicates that controls will use CurrentUICulture. + /// + public static CultureInfo CurrentCulture + { + get + { + return _currentCulture; + } + set + { + _currentCulture = value; + } + } + + /// + /// Gets the Culture used by the date time input and month calendar controls + /// + /// reference to CultureInfo + public static CultureInfo GetActiveCulture() + { + return (_currentCulture ?? CultureInfo.CurrentCulture); + } + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeIndicator/TimeIndicator.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeIndicator/TimeIndicator.cs new file mode 100644 index 00000000..67282afb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeIndicator/TimeIndicator.cs @@ -0,0 +1,600 @@ +#if FRAMEWORK20 +using System; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +namespace DevComponents.DotNetBar.Schedule +{ + [TypeConverter(typeof(TimeIndicatorConvertor))] + public class TimeIndicator : IDisposable + { + #region Events + + /// + /// Occurs when the collection has changed + /// + [Description("Occurs when the TimeIndicator has changed.")] + public event EventHandler TimeIndicatorChanged; + + /// + /// Occurs when a TimeIndicator time has changed + /// + [Description("Occurs when a TimeIndicator time has changed.")] + public event EventHandler TimeIndicatorTimeChanged; + + /// + /// Occurs when a TimeIndicator Color has changed + /// + [Description("Occurs when a TimeIndicator Color has changed.")] + public event EventHandler TimeIndicatorColorChanged; + + #endregion + + #region Private variables + + private DateTime _IndicatorTime; + private TimeSpan _IndicatorTimeOffset; + + private eTimeIndicatorArea _IndicatorArea; + private eTimeIndicatorSource _IndicatorSource = eTimeIndicatorSource.SystemTime; + private eTimeIndicatorVisibility _Visibility = eTimeIndicatorVisibility.Hidden; + private eTimeIndicatorLevel _IndicatorLevel = eTimeIndicatorLevel.Bottom; + + private Color _BorderColor; + private ColorDef _IndicatorColor = new ColorDef(); + + private int _Thickness = 4; + + private bool _Enabled = true; + private bool _IsProtected; + private bool _IsDesignMode; + + private int _UpdateCount; + private object _Tag; + + #endregion + + /// + /// Constructor + /// + public TimeIndicator() + { + _IndicatorTime = DateTime.Now; + + _IndicatorColor.ColorDefChanged += IndicatorColor_ColorDefChanged; + } + + #region Internal properties + + #region IndicatorDisplayTime + + /// + /// Gets the Indicator display time. + /// + /// The DisplayTime is the addition of the IndicatorTime + /// and IndicatorTimeOffset. + /// + internal DateTime IndicatorDisplayTime + { + get + { + if (_IsDesignMode == true) + return (DateTime.Now.Date.AddHours(3)); + + return (_IndicatorTime.Add(_IndicatorTimeOffset)); + } + } + + #endregion + + #region DesignMode + + /// + /// Gets or sets whether we are in design mode + /// + internal bool IsDesignMode + { + get { return (_IsDesignMode); } + set { _IsDesignMode = value; } + } + + #endregion + + #region IsProtected + + /// + /// Gets or sets whether the timer indicator + /// is protected (can't be deleted) + /// + internal bool IsProtected + { + get { return (_IsProtected); } + set { _IsProtected = value; } + } + + #endregion + + #endregion + + #region Public properties + + #region BorderColor + + /// + /// Gets or sets the leading edge border color + /// + [Browsable(true), DefaultValue(typeof(Color), "Empty")] + [Description("Indicates the leading edge border color.")] + public Color BorderColor + { + get { return (_BorderColor); } + + set + { + if (_BorderColor.Equals(value) == false) + { + _BorderColor = value; + + OnTimeIndicatorChanged(); + } + } + } + + #endregion + + #region Enabled + + /// + /// Gets or sets whether automatic time updates are enabled. + /// This property, whose default is true, is only utilized when + /// the IndicatorSource is set to eTimeIndicatorSource.SystemTime + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool Enabled + { + get { return (_Enabled); } + + set + { + if (_Enabled != value) + { + _Enabled = value; + + if (_Enabled == true && + _IndicatorSource == eTimeIndicatorSource.SystemTime) + { + IndicatorTime = DateTime.Now; + } + } + } + } + + #endregion + + #region IndicatorArea + + /// + /// Gets or sets the Indicator Display Area. + /// + /// This property determines where the Indicator is + /// drawn: in the Time Header, View Content, or both. + /// + [Browsable(true), DefaultValue(eTimeIndicatorArea.Header)] + [Description("Indicates the Indicator display area.")] + public eTimeIndicatorArea IndicatorArea + { + get { return (_IndicatorArea); } + + set + { + if (_IndicatorArea != value) + { + _IndicatorArea = value; + + OnTimeIndicatorChanged(); + } + } + } + + #endregion + + #region IndicatorColor + + /// + /// Gets or sets the Indicator color + /// + [Browsable(true)] + [Description("Indicates the Indicator color.")] + [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)] + public ColorDef IndicatorColor + { + get { return (_IndicatorColor); } + + set + { + if (_IndicatorColor != null) + _IndicatorColor.ColorDefChanged -= IndicatorColor_ColorDefChanged; + + _IndicatorColor = value; + + if (_IndicatorColor != null) + _IndicatorColor.ColorDefChanged += IndicatorColor_ColorDefChanged; + + OnTimeIndicatorColorChanged(); + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public void ResetIndicatorColor() + { + IndicatorColor = new ColorDef(); + } + + #endregion + + #region IndicatorLevel + + /// + /// Gets or sets the IndicatorTime display level + /// + [Browsable(true), DefaultValue(eTimeIndicatorLevel.Bottom)] + [Description("Indicates the Indicator display level.")] + public eTimeIndicatorLevel IndicatorLevel + { + get { return (_IndicatorLevel); } + + set + { + if (_IndicatorLevel != value) + { + _IndicatorLevel = value; + + OnTimeIndicatorChanged(); + } + } + } + + #endregion + + #region IndicatorTime + + /// + /// Gets or sets the Indicator time + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DateTime IndicatorTime + { + get { return (_IndicatorTime); } + + set + { + if (_IndicatorTime.Equals(value) == false) + { + DateTime oldValue = IndicatorDisplayTime; + _IndicatorTime = value; + + OnTimeIndicatorTimeChanged(oldValue, _IndicatorTime.Add(_IndicatorTimeOffset)); + } + } + } + + #endregion + + #region IndicatorTimeOffset + + /// + /// Gets or sets the Indicator time offset. + /// + /// This value is added to the current IndicatorTime + /// before displaying the indicator. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public TimeSpan IndicatorTimeOffset + { + get { return (_IndicatorTimeOffset); } + + set + { + if (_IndicatorTimeOffset.Equals(value) == false) + { + _IndicatorTimeOffset = value; + + OnTimeIndicatorChanged(); + } + } + } + + #endregion + + #region Visibility + + /// + /// Gets or sets the Indicator visibility + /// + [Browsable(true)] + [DefaultValue(eTimeIndicatorVisibility.Hidden)] + [Description("Indicates the Indicator visibility.")] + public eTimeIndicatorVisibility Visibility + { + get { return (_Visibility); } + + set + { + if (_Visibility != value) + { + _Visibility = value; + + OnTimeIndicatorChanged(); + } + } + } + + #endregion + + #region Tag + + /// + /// Gets or sets the User defined data associated with the object + /// + [Browsable(false)] + public object Tag + { + get { return (_Tag); } + set { _Tag = value; } + } + + #endregion + + #region Thickness + + /// + /// Gets or sets the thickness of the Indicator + /// + [Browsable(true), DefaultValue(4)] + [Description("Indicates the thickness of the Indicator.")] + public int Thickness + { + get { return (_Thickness); } + + set + { + if (_Thickness != value) + { + _Thickness = value; + + OnTimeIndicatorChanged(); + } + } + } + + #endregion + + #region IndicatorSource + + /// + /// Gets or sets the IndicatorTime source + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public eTimeIndicatorSource IndicatorSource + { + get { return (_IndicatorSource); } + + set + { + if (_IndicatorSource != value) + { + _IndicatorSource = value; + + OnTimeIndicatorChanged(); + } + } + } + + #endregion + + #endregion + + #region IsVisible + + /// + /// Gets whether the indicator is visible + /// + /// + internal bool IsVisible() + { + return (_Visibility != eTimeIndicatorVisibility.Hidden); + } + + /// + /// Gets whether the indicator is visible + /// in the given view + /// + /// + /// + /// + internal bool IsVisible(CalendarView calendarView, BaseView view) + { + if (_Visibility == eTimeIndicatorVisibility.Hidden) + return (false); + + if (_Visibility == eTimeIndicatorVisibility.AllResources) + return (true); + + return ((calendarView == null || view.DisplayedOwnerKeyIndex == -1 || + calendarView.SelectedOwnerIndex == view.DisplayedOwnerKeyIndex)); + } + + #endregion + + #region IndicatorColor_ColorDefChanged + + /// + /// Handles ColorDefChanged events + /// + /// + /// + void IndicatorColor_ColorDefChanged(object sender, EventArgs e) + { + OnTimeIndicatorChanged(); + } + + #endregion + + #region OnTimeIndicatorChanged + + /// + /// Handles TimeIndicatorChanged propagation + /// + private void OnTimeIndicatorChanged() + { + if (TimeIndicatorChanged != null) + TimeIndicatorChanged(this, EventArgs.Empty); + } + + #endregion + + #region OnTimeIndicatorColorChanged + + /// + /// Handles OnTimeIndicatorColorChanged propagation + /// + private void OnTimeIndicatorColorChanged() + { + if (TimeIndicatorColorChanged != null) + TimeIndicatorColorChanged(this, new TimeIndicatorColorChangedEventArgs(this)); + } + + #endregion + + #region OnTimeIndicatorTimeChanged + + /// + /// Handles TimeIndicatorTimeChanged propagation + /// + /// + /// + private void OnTimeIndicatorTimeChanged(DateTime oldValue, DateTime newValue) + { + if (TimeIndicatorTimeChanged != null) + TimeIndicatorTimeChanged(this, new TimeIndicatorTimeChangedEventArgs(this, oldValue, newValue)); + } + + #endregion + + #region Begin/EndUpdate + + /// + /// Begins Update block + /// + public void BeginUpdate() + { + _UpdateCount++; + } + + /// + /// Ends update block + /// + public void EndUpdate() + { + if (_UpdateCount == 0) + { + throw new InvalidOperationException( + "EndUpdate must be called After BeginUpdate"); + } + + _UpdateCount--; + + if (_UpdateCount == 0) + OnTimeIndicatorChanged(); + } + + #endregion + + #region IDisposable + + public void Dispose() + { + if (_IndicatorColor != null) + _IndicatorColor.ColorDefChanged -= IndicatorColor_ColorDefChanged; + } + + #endregion + } + + #region TimeIndicatorConvertor + + /// + /// TimeIndicatorConvertor + /// + public class TimeIndicatorConvertor : ExpandableObjectConverter + { + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + return (String.Empty); + } + } + + #endregion + + #region enums + + #region eTimeIndicatorSource + + /// + /// Specifies the source for the IndicatorTime + /// + public enum eTimeIndicatorSource + { + SystemTime, + UserSpecified + } + + #endregion + + #region eTimeIndicatorVisibility + + /// + /// Specifies the Indicator visibility + /// + public enum eTimeIndicatorVisibility + { + AllResources, + SelectedResource, + Hidden + } + + #endregion + + #region eTimeIndicatorArea + + /// + /// Specifies the Indicator display area + /// + public enum eTimeIndicatorArea + { + Header, + Content, + All + } + + #endregion + + #region eTimeIndicatorLevel + + /// + /// Specifies the Indicator display level + /// + public enum eTimeIndicatorLevel + { + Bottom, + Top + } + + #endregion + + #endregion +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeIndicator/TimeIndicatorCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeIndicator/TimeIndicatorCollection.cs new file mode 100644 index 00000000..24e67604 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeIndicator/TimeIndicatorCollection.cs @@ -0,0 +1,498 @@ +#if FRAMEWORK20 +using System; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Schedule +{ + public class TimeIndicatorCollection : Collection, IDisposable + { + #region Events + + /// + /// Occurs when the TimeIndicator collection has changed + /// + [Description("Occurs when the TimeIndicator collection has changed.")] + public event EventHandler TimeIndicatorCollectionChanged; + + /// + /// Occurs when a TimeIndicator time has changed + /// + [Description("Occurs when a TimeIndicator time has changed.")] + public event EventHandler TimeIndicatorTimeChanged; + + /// + /// Occurs when a TimeIndicator Color has changed + /// + [Description("Occurs when a TimeIndicator Color has changed.")] + public event EventHandler TimeIndicatorColorChanged; + + #endregion + + #region Private variables + + private int _UpdateCount; + private Timer _Timer; + + #endregion + + #region AddRange + + /// + /// Adds a range of TimeIndicators to the collection + /// + /// Array of items to add + public void AddRange(TimeIndicator[] items) + { + try + { + BeginUpdate(); + + for (int i = 0; i < items.Length; i++) + Add(items[i]); + } + finally + { + EndUpdate(); + } + } + + #endregion + + #region RemoveItem + + /// + /// Processes list RemoveItem calls + /// + /// Index to remove + protected override void RemoveItem(int index) + { + if (Items[index].IsProtected == false) + { + Items[index].TimeIndicatorChanged -= IndicatorCollectionChanged; + Items[index].TimeIndicatorTimeChanged -= IndicatorTimeChanged; + Items[index].TimeIndicatorColorChanged -= IndicatorColorChanged; + + base.RemoveItem(index); + + OnCollectionChanged(); + } + } + + #endregion + + #region InsertItem + + /// + /// Processes list InsertItem calls + /// + /// Index to add + /// TimeIndicator to add + protected override void InsertItem(int index, TimeIndicator item) + { + if (item != null) + { + item.TimeIndicatorChanged += IndicatorCollectionChanged; + item.TimeIndicatorTimeChanged += IndicatorTimeChanged; + item.TimeIndicatorColorChanged += IndicatorColorChanged; + + base.InsertItem(index, item); + + OnCollectionChanged(); + } + } + + #endregion + + #region SetItem + + /// + /// Processes list SetItem calls (e.g. replace) + /// + /// Index to replace + /// TimeIndicator to replace + protected override void SetItem(int index, TimeIndicator newItem) + { + if (Items[index].IsProtected == false) + { + if (newItem != null) + { + Items[index].TimeIndicatorChanged -= IndicatorCollectionChanged; + Items[index].TimeIndicatorTimeChanged -= IndicatorTimeChanged; + Items[index].TimeIndicatorColorChanged -= IndicatorColorChanged; + + newItem.TimeIndicatorChanged += IndicatorCollectionChanged; + newItem.TimeIndicatorTimeChanged += IndicatorTimeChanged; + newItem.TimeIndicatorColorChanged += IndicatorColorChanged; + + base.SetItem(index, newItem); + + OnCollectionChanged(); + } + } + } + + #endregion + + #region ClearItems + + /// + /// Processes list Clear calls (e.g. remove all) + /// + protected override void ClearItems() + { + try + { + BeginUpdate(); + + for (int i = Count - 1; i>=0 ; i--) + { + if (Items[i].IsProtected == false) + { + Items[i].TimeIndicatorChanged -= IndicatorCollectionChanged; + Items[i].TimeIndicatorTimeChanged -= IndicatorTimeChanged; + Items[i].TimeIndicatorColorChanged -= IndicatorColorChanged; + + RemoveAt(i); + } + } + } + finally + { + EndUpdate(); + } + } + + #endregion + + #region Events + + #region IndicatorCollectionChanged + + /// + /// IndicatorCollectionChanged + /// + /// + /// + void IndicatorCollectionChanged(object sender, EventArgs e) + { + OnCollectionChanged(); + } + + #endregion + + #region IndicatorColorChanged + + /// + /// IndicatorColorChanged + /// + /// + /// + void IndicatorColorChanged(object sender, TimeIndicatorColorChangedEventArgs e) + { + OnTimeIndicatorColorChanged(e); + } + + #endregion + + #region IndicatorTimeChanged + + /// + /// IndicatorTimeChanged + /// + /// + /// + void IndicatorTimeChanged(object sender, TimeIndicatorTimeChangedEventArgs e) + { + OnTimeIndicatorTimeChanged(e); + } + + #endregion + + #endregion + + #region OnCollectionChanged + + /// + /// Propagates TimeIndicatorCollectionChanged events + /// + protected virtual void OnCollectionChanged() + { + if (_UpdateCount == 0) + { + UpdateTimerUse(); + + if (TimeIndicatorCollectionChanged != null) + TimeIndicatorCollectionChanged(this, EventArgs.Empty); + } + } + + #endregion + + #region OnTimeIndicatorColorChanged + + /// + /// Propagates OnTimeIndicatorColorChanged events + /// + /// + protected virtual void OnTimeIndicatorColorChanged(TimeIndicatorColorChangedEventArgs e) + { + if (_UpdateCount == 0) + { + if (TimeIndicatorColorChanged != null) + TimeIndicatorColorChanged(this, e); + } + } + + #endregion + + #region OnTimeIndicatorTimeChanged + + /// + /// Propagates OnTimeIndicatorTimeChanged events + /// + /// + protected virtual void OnTimeIndicatorTimeChanged(TimeIndicatorTimeChangedEventArgs e) + { + if (_UpdateCount == 0) + { + if (TimeIndicatorTimeChanged != null) + TimeIndicatorTimeChanged(this, e); + } + } + + #endregion + + #region System Timer support + + #region UpdateTimerUse + + /// + /// Updates our system timer use + /// + private void UpdateTimerUse() + { + // If we need a timer, then allocate it + // and initialize it to fire approx every minute + + if (TimerNeeded() == true) + { + if (_Timer == null) + { + _Timer = new Timer(); + + _Timer.Tick += Timer_Tick; + + DateTime now = DateTime.Now; + _Timer.Interval = (60 - now.Second) * 1000 + (1050 - now.Millisecond); + + _Timer.Enabled = true; + } + } + else + { + if (_Timer != null) + { + _Timer.Enabled = false; + + _Timer.Tick -= Timer_Tick; + + _Timer.Dispose(); + _Timer = null; + } + } + } + + #endregion + + #region TimerNeeded + + /// + /// Determines if a system timer is needed + /// + /// true if needed + private bool TimerNeeded() + { + for (int i = 0; i < Items.Count; i++) + { + TimeIndicator ti = Items[i]; + + if (ti.IsDesignMode == true) + return (false); + + if (ti.Enabled == true && + ti.IndicatorSource == eTimeIndicatorSource.SystemTime) + { + return (true); + } + } + + return (false); + } + + #endregion + + #region Timer_Tick + + /// + /// Handles our timer tick events + /// + /// + /// + void Timer_Tick(object sender, EventArgs e) + { + DateTime now = DateTime.Now; + _Timer.Interval = (60 - now.Second) * 1000 + (1050 - now.Millisecond); + + for (int i = 0; i < Items.Count; i++) + { + TimeIndicator ti = Items[i]; + + if (ti.Enabled == true && + ti.IndicatorSource == eTimeIndicatorSource.SystemTime) + { + ti.IndicatorTime = now; + } + } + } + + #endregion + + #endregion + + #region Begin/EndUpdate + + /// + /// Begins Update block + /// + public void BeginUpdate() + { + _UpdateCount++; + } + + /// + /// Ends update block + /// + public void EndUpdate() + { + if (_UpdateCount == 0) + { + throw new InvalidOperationException( + "EndUpdate must be called After BeginUpdate"); + } + + _UpdateCount--; + + if (_UpdateCount == 0) + OnCollectionChanged(); + } + + #endregion + + #region IDisposable + + public void Dispose() + { + for (int i = Count - 1; i >= 0; i--) + { + Items[i].TimeIndicatorChanged -= IndicatorCollectionChanged; + Items[i].TimeIndicatorTimeChanged -= IndicatorTimeChanged; + Items[i].TimeIndicatorColorChanged -= IndicatorColorChanged; + } + } + + #endregion + } + + #region TimeIndicatorTimeChangedEventArgs + + /// + /// TimeIndicatorTimeChangedEventArgs + /// + public class TimeIndicatorTimeChangedEventArgs : EventArgs + { + #region Private variables + + private TimeIndicator _TimeIndicator; + + private DateTime _OldTime; + private DateTime _NewTime; + + #endregion + + public TimeIndicatorTimeChangedEventArgs( + TimeIndicator timeIndicator, DateTime oldTime, DateTime newTime) + { + _TimeIndicator = timeIndicator; + + _OldTime = oldTime; + _NewTime = newTime; + } + + #region Public properties + + /// + /// Gets the TimeIndicator being affected + /// + public TimeIndicator TimeIndicator + { + get { return (_TimeIndicator); } + } + + /// + /// Gets the old DateTime + /// + public DateTime OldTime + { + get { return (_OldTime); } + } + + /// + /// Gets the new DateTime + /// + public DateTime NewTime + { + get { return (_NewTime); } + } + + #endregion + } + + #endregion + + #region TimeIndicatorColorChangedEventArgs + + /// + /// TimeIndicatorColorChangedEventArgs + /// + public class TimeIndicatorColorChangedEventArgs : EventArgs + { + #region Private variables + + private TimeIndicator _TimeIndicator; + + #endregion + + public TimeIndicatorColorChangedEventArgs(TimeIndicator timeIndicator) + { + _TimeIndicator = timeIndicator; + } + + #region Public properties + + /// + /// Gets the TimeIndicator being affected + /// + public TimeIndicator TimeIndicator + { + get { return (_TimeIndicator); } + } + + #endregion + } + + #endregion +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/DayInfo.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/DayInfo.cs new file mode 100644 index 00000000..4bc32788 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/DayInfo.cs @@ -0,0 +1,38 @@ +#if FRAMEWORK20 +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class DayInfo + { + #region Private data + + private WorkTime _WorkStartTime; + private WorkTime _WorkEndTime; + + #endregion + + #region Public properties + + /// + /// Gets and sets work start time + /// + public WorkTime WorkStartTime + { + get { return (_WorkStartTime); } + set { _WorkStartTime = value; } + } + + /// + /// Gets and sets work end time + /// + public WorkTime WorkEndTime + { + get { return (_WorkEndTime); } + set { _WorkEndTime = value; } + } + + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/ModelTimeLineViewConnector.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/ModelTimeLineViewConnector.cs new file mode 100644 index 00000000..c83e357d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/ModelTimeLineViewConnector.cs @@ -0,0 +1,845 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using DevComponents.Schedule.Model; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Schedule +{ + internal class ModelTimeLineViewConnector : ModelViewConnector + { + #region Const + + private const int DaysInWeek = 7; + + #endregion + + #region Static data + + static private AppointmentSubsetCollection _lineAppts; + static private List _listAppts; + + static private DateTime _lineStartTime; // TimeLine start date + static private DateTime _lineEndTime; // TimeLine end date + static private int _lineState; // Refresh state + + static private List _periodAppts; + + static private DateTime _periodStartTime; // Period start date + static private DateTime _periodEndTime; // Period end date + + #endregion + + #region Private variables + + private CalendarModel _Model; // The associated CalendarModel + private TimeLineView _View; // The associated _TimeLineView + + private DateTime _ViewStartTime; // View start time + private DateTime _ViewEndTime; // View end time + private int _ViewState; // View refresh state + + private DayInfo[] _DayInfo; // DayInfo array (WorkStartTimes) + + private bool _IsConnected; // Connection status + + #endregion + + /// + /// Constructor + /// + /// Assoc CalendarModel + /// Assoc TimeLineView + public ModelTimeLineViewConnector(CalendarModel model, TimeLineView timeLineView) + { + _Model = model; + _View = timeLineView; + } + + #region Public properties + + /// + /// Gets the connection status + /// + public override bool IsConnected + { + get { return (_IsConnected); } + } + + /// + /// Gets the internal AppointmentSubsetCollection + /// + public AppointmentSubsetCollection Appts + { + get + { + if (_lineAppts == null) + _lineAppts = new AppointmentSubsetCollection(_Model, _lineStartTime, _lineEndTime); + + return (_lineAppts); + } + } + + /// + /// Gets the list of line appointments + /// + public List ListAppts + { + get { return (_listAppts); } + } + + /// + /// Gets the DayInfo array + /// + public DayInfo[] DayInfo + { + get { return (_DayInfo); } + } + + #endregion + + #region Connect processing + + /// + /// Performs Model connection processing + /// + public override void Connect() + { + VerifyModel(); + + if (_IsConnected) + Disconnect(); + + LoadData(); + + // Get notification on Model property changes + + HookEvents(true); + + _IsConnected = true; + } + + #endregion + + #region Hook events + + /// + /// Hooks or unhooks our system events + /// + /// + private void HookEvents(bool hook) + { + if (hook == true) + { + _Model.PropertyChanged += ModelPropertyChanged; + _Model.SubPropertyChanged += ModelSubPropertyChanged; + + _View.CalendarView.CustomItems.CollectionChanged += CustomItemsCollectionChanged; + } + else + { + _Model.PropertyChanged -= ModelPropertyChanged; + _Model.SubPropertyChanged -= ModelSubPropertyChanged; + + _View.CalendarView.CustomItems.CollectionChanged -= CustomItemsCollectionChanged; + } + } + + #endregion + + #region Event processing + + #region Model property change processing + + /// + /// Handles Model property change notifications + /// + /// + /// + private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == CalendarModel.AppointmentsPropertyName) + { + _ViewStartTime = new DateTime(); + + RefreshData(_ViewState == _lineState); + + _View.NeedRecalcLayout = true; + _View.NeedRecalcSize = true; + } + else if (e.PropertyName == CalendarModel.WorkDaysPropertyName) + { + UpdateWorkDayDetails(); + + _View.Refresh(); + } + } + + #endregion + + #region ModelSubPropertyChanged + + /// + /// Handles ModelSubProperty change notifications + /// + /// object + /// SubPropertyChangedEventArgs + private void ModelSubPropertyChanged(object sender, SubPropertyChangedEventArgs e) + { + if (e.Source is WorkDay) + { + UpdateWorkDayDetails(); + } + else if (e.Source is Owner) + { + Owner owner = (Owner)e.Source; + + if (_View.OwnerKey != null && _View.OwnerKey.Equals(owner.Key)) + { + if (e.PropertyChangedArgs.PropertyName == Owner.DisplayNamePropertyName) + _View.DisplayName = owner.DisplayName; + + else if (e.PropertyChangedArgs.PropertyName.Equals("ColorScheme")) + _View.CalendarColor = owner.ColorScheme; + } + } + else if (e.Source is Appointment) + { + Appointment app = e.Source as Appointment; + AppointmentTimeLineView appView; + + string name = e.PropertyChangedArgs.PropertyName; + + if (name.Equals("Tooltip")) + { + appView = GetViewFromTimeLine(app); + + if (appView != null) + appView.Tooltip = app.Tooltip; + } + else if (name.Equals("IsSelected")) + { + appView = GetViewFromTimeLine(app); + + if (appView != null) + appView.IsSelected = app.IsSelected; + } + else if (name.Equals("CategoryColor") || name.Equals("TimeMarkedAs")) + { + appView = GetViewFromTimeLine(app); + + if (appView != null) + appView.Refresh(); + } + else if (name.Equals("OwnerKey")) + { + if (_View.CalendarView.IsMultiCalendar == true) + { + if (_View.OwnerKey == app.OwnerKey) + { + _ViewStartTime = new DateTime(); + + RefreshData(false); + + _View.NeedRecalcLayout = true; + _View.RecalcSize(); + } + else + { + appView = GetViewFromTimeLine(app); + + if (appView != null) + { + _ViewStartTime = new DateTime(); + + RefreshData(false); + + _View.NeedRecalcLayout = true; + _View.RecalcSize(); + } + } + } + } + else if (name.Equals("Visible")) + { + RefreshData(true); + } + } + } + + #endregion + + #region CustomItems_CollectionChanged + + /// + /// Handles CustomItemCollection change events + /// + /// + /// + void CustomItemsCollectionChanged(object sender, EventArgs e) + { + _ViewStartTime = new DateTime(); + + RefreshData(_ViewState == _lineState); + + _View.NeedRecalcLayout = true; + _View.NeedRecalcSize = true; + } + + #endregion + + #endregion + + #region Disconnect processing + + /// + /// Severs the Model/TimeLineView connection + /// + public override void Disconnect() + { + VerifyModel(); + + if (_IsConnected) + { + _IsConnected = false; + _lineState = 0; + + // Clear our TimeLine items and + // stop notification on Model property changes + + ClearTimeLineItems(); + + HookEvents(false); + } + } + + /// + /// Clears TimeLine view items + /// + private void ClearTimeLineItems() + { + if (_View.CalendarItems.Count > 0) + { + // Loop through each CalendarItem, resetting + // it's associated connection + + for (int i = _View.CalendarItems.Count - 1; i >= 0; i--) + { + AppointmentTimeLineView view = + _View.CalendarItems[i] as AppointmentTimeLineView; + + if (view != null) + { + view.IsSelectedChanged -= _View.ItemIsSelectedChanged; + + view.Appointment = null; + view.IsSelected = false; + } + + _View.CalendarItems.RemoveAt(i); + } + } + + _View.SubItems.Clear(); + } + + #endregion + + #region LoadData processing + + /// + /// Loads Model/TimeLineView connection data + /// + private void LoadData() + { + LoadViewData(true, false); + + UpdateWorkDayDetails(); + } + + #endregion + + #region LoadViewData + + /// + /// Loads the view data + /// + /// Forceful reload + /// Validation needed + private void LoadViewData(bool reload, bool validate) + { + DateTime startTime, endTime; + GetDateRange(out startTime, out endTime); + + reload = LoadPeriodData(reload, startTime, endTime); + + if (reload == true || + _ViewStartTime != startTime || _ViewEndTime != endTime) + { + _ViewStartTime = startTime; + _ViewEndTime = endTime; + + if (validate == true) + { + RemoveOutdatedViews(_periodAppts); + RemoveOutdatedCustomItems(); + } + + UpdateTimeLineView(_periodAppts); + UpdateCustomItems(); + } + } + + #endregion + + #region LoadPeriodData + + /// + /// Loads the Period data (visible view range) + /// + /// Forceful reload + /// + /// + /// reload flag + private bool LoadPeriodData(bool reload, DateTime startTime, DateTime endTime) + { + reload = LoadLineData(reload); + + if (reload == true || + _periodStartTime != startTime || _periodEndTime != endTime) + { + _periodStartTime = startTime; + _periodEndTime = endTime; + + _periodAppts = new List(); + + if (_listAppts != null) + { + for (int i = 0; i < _listAppts.Count; i++) + { + Appointment app = _listAppts[i]; + + if (app.EndTime > _periodStartTime && app.StartTime < _periodEndTime) + _periodAppts.Add(app); + } + } + + reload = true; + } + + return (reload); + } + + #endregion + + #region LoadLineData + + /// + /// Loads the TimeLine appointment data + /// + /// + private bool LoadLineData(bool reload) + { + if (reload == true || + _lineStartTime != _View.StartDate || _lineEndTime != _View.EndDate) + { + _lineStartTime = _View.StartDate; + _lineEndTime = _View.EndDate; + + _lineAppts = null; // Legacy... + + _listAppts = GetAppointmentList(_Model, _View.StartDate, _View.EndDate.AddDays(1)); + + _lineState = _lineState ^ 1; + } + + if (_ViewState != _lineState) + { + _ViewState = _lineState; + + _View.ModelReloaded = true; + + reload = true; + } + + return (reload); + } + + #endregion + + #region RefreshData processing + + /// + /// Refreshes the data in a previously established + /// and loaded connection + /// + public void RefreshData(bool reload) + { + if (_View.Displayed == true) + LoadViewData(reload, true); + } + + #endregion + + #region GetDateRange + + /// + /// Gets the range of appointment dates + /// + /// + /// + private void GetDateRange(out DateTime startDate, out DateTime endDate) + { + int scol = _View.FirstVisibleColumn; + int ncols = _View.ClientRect.Width / _View.ColumnWidth; + + startDate = _View.StartDate; + endDate = startDate; + + try + { + startDate = startDate.AddMinutes(scol * _View.CalendarView.BaseInterval); + endDate = startDate.AddMinutes(ncols * _View.CalendarView.BaseInterval); + + startDate = startDate.AddMinutes(-_View.CalendarView.BaseInterval); + endDate = endDate.AddMinutes(_View.CalendarView.BaseInterval); + } +// ReSharper disable EmptyGeneralCatchClause + catch +// ReSharper restore EmptyGeneralCatchClause + { + } + } + + #endregion + + #region UpdateTimeLineView + + /// + /// Updates the TimeLine view + /// + /// + private void UpdateTimeLineView(List appointments) + { + // Loop through each appointment + // updating the assoc view accordingly + + foreach (Appointment appointment in appointments) + { + if (IsAppointmentVisible(appointment)) + { + // Get the assoc view + + AppointmentTimeLineView view = + GetViewFromTimeLine(appointment) ?? GetNewView(appointment); + + // Set the view start and end times to + // match the assoc appointment + + view.StartTime = appointment.StartTime; + view.EndTime = appointment.EndTime; + + // Update the item data + + if (view.TimeLineView == null) + { + view.TimeLineView = _View; + + _View.CalendarItems.Add(view); + _View.SubItems.Add(view); + + view.IsSelectedChanged += _View.ItemIsSelectedChanged; + } + } + } + } + + #endregion + + #region UpdateCustomItems + + /// + /// Updates the TimeLine CustomItems + /// + private void UpdateCustomItems() + { + CustomCalendarItemCollection items = _View.CalendarView.CustomItems; + + if (items != null) + { + for (int i = 0; i < items.Count; i++) + { + CustomCalendarItem item = items[i]; + + if (IsCustomItemVisible(item) == true && + (item.StartTime < _ViewEndTime && item.EndTime > _ViewStartTime)) + { + item.CalendarView = _View.CalendarView; + + CustomCalendarItem ci = + GetItemFromTimeLine(item) ?? GetNewCustomItem(item); + + if (ci.StartTime != item.StartTime || ci.EndTime != item.EndTime) + { + ci.StartTime = item.StartTime; + ci.EndTime = item.EndTime; + } + } + } + } + } + + #endregion + + #region UpdateWorkDayDetails + + /// + /// Updates the WorkDay details array + /// + private void UpdateWorkDayDetails() + { + // Update workDay timings + + if (_DayInfo == null) + _DayInfo = new DayInfo[DaysInWeek]; + + for (int i = 0; i < DaysInWeek; i++) + { + if (_DayInfo[i] == null) + _DayInfo[i] = new DayInfo(); + + Owner owner = _Model.Owners[_View.OwnerKey]; + + WorkDay workDay = (owner != null && owner.WorkDays.Count > 0) + ? owner.WorkDays[(DayOfWeek)i] : _Model.WorkDays[(DayOfWeek)i]; + + if (workDay != null) + { + _DayInfo[i].WorkStartTime = workDay.WorkStartTime; + _DayInfo[i].WorkEndTime = workDay.WorkEndTime; + } + else + { + _DayInfo[i].WorkStartTime = new WorkTime(); + _DayInfo[i].WorkEndTime = new WorkTime(); + } + } + } + + #endregion + + #region RemoveOutdatedViews + + /// + /// Removes Outdated Views + /// + /// + private void RemoveOutdatedViews(List appts) + { + for (int i=_View.CalendarItems.Count - 1; i>=0; i--) + { + AppointmentTimeLineView view = + _View.CalendarItems[i] as AppointmentTimeLineView; + + if (view != null) + { + if (ValidViewAppointment(appts, view) == false) + { + view.TimeLineView = null; + + _View.NeedRecalcLayout = true; + + _View.SubItems._Remove(view); + _View.CalendarItems.RemoveAt(i); + + if (view == _View.SelectedItem) + _View.SelectedItem = null; + + view.IsSelectedChanged -= _View.ItemIsSelectedChanged; + } + } + } + } + + /// + /// Determines if the provided view is valid, given + /// the current list of Appointments + /// + /// + /// + /// + private bool ValidViewAppointment( + List appts, AppointmentTimeLineView view) + { + if (IsAppointmentVisible(view.Appointment) == false) + return (false); + + if (view.IsSelected == true) + { + if (_Model.Appointments.Contains(view.Appointment) == true) + return (true); + } + + return (appts.Contains(view.Appointment)); + } + + #endregion + + #region RemoveOutdatedCustomItems + + /// + /// Removes out dated CustomItems + /// + private void RemoveOutdatedCustomItems() + { + for (int i = _View.CalendarItems.Count - 1; i >= 0; i--) + { + CustomCalendarItem item = _View.CalendarItems[i] as CustomCalendarItem; + + if (item != null) + { + if (IsValidItem(item) == false || + (item.IsSelected == false && (item.EndTime < _ViewStartTime || item.StartTime > _ViewEndTime))) + { + _View.NeedRecalcSize = true; + _View.SubItems._Remove(item); + _View.CalendarItems.RemoveAt(i); + + if (item == _View.SelectedItem) + _View.SelectedItem = null; + + item.IsSelectedChanged -= _View.ItemIsSelectedChanged; + } + } + } + } + + /// + /// Determines if the given CustomItem is valid + /// for the current view + /// + /// + /// + private bool IsValidItem(CustomCalendarItem view) + { + return (IsCustomItemVisible(view) == true && + _View.CalendarView.CustomItems.Contains(view.BaseCalendarItem) == true); + } + + #endregion + + #region GetViewFromTimeLine + + /// + /// Gets the AppointmentView from the timeline + /// + /// + /// AppointmentView or null + private AppointmentTimeLineView GetViewFromTimeLine(Appointment appointment) + { + foreach (CalendarItem item in _View.CalendarItems) + { + AppointmentTimeLineView view = item as AppointmentTimeLineView; + + if (view != null && view.Appointment == appointment) + return (view); + } + + return (null); + } + + #endregion + + #region GetItemFromTimeLine + + /// + /// Gets the CustomCalendarItem from the timeline. + /// + /// + /// CustomCalendarItem or null + private CustomCalendarItem GetItemFromTimeLine(CustomCalendarItem item) + { + foreach (CalendarItem citem in _View.CalendarItems) + { + CustomCalendarItem view = citem as CustomCalendarItem; + + if (view != null && (view == item || view.BaseCalendarItem == item)) + return (view); + } + + return (null); + } + + #endregion + + #region GetNewView + + /// + /// Gets a new appointment view + /// + /// Appointment + /// New view + private AppointmentTimeLineView GetNewView(Appointment appointment) + { + AppointmentTimeLineView view = new AppointmentTimeLineView(_View, appointment); + + view.Tooltip = appointment.Tooltip; + + return (view); + } + + #endregion + + #region GetNewCustomItem + + /// + /// Gets a new CustomCalendarItem + /// + /// + /// CustomCalendarItem + private CustomCalendarItem GetNewCustomItem(CustomCalendarItem item) + { + CustomCalendarItem ci = (CustomCalendarItem)item.Copy(); + ci.BaseCalendarItem = item; + + _View.CalendarItems.Add(ci); + _View.NeedRecalcLayout = true; + + _View.SubItems.Add(ci); + + ci.IsSelectedChanged += _View.ItemIsSelectedChanged; + + return (ci); + } + + #endregion + + #region View support routines + + /// + /// Returns the view + /// + /// + public override eCalendarView GetView() + { + return (eCalendarView.TimeLine); + } + + /// + /// Verifies the Model and MonthView are valid + /// + private void VerifyModel() + { + if (_Model == null) + throw new NullReferenceException("CalendarModel must be set on connector."); + + if (_View == null) + throw new NullReferenceException("AppointmentTimeLineView must be set on connector."); + } + + #endregion + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineHScrollPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineHScrollPanel.cs new file mode 100644 index 00000000..5ae72323 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineHScrollPanel.cs @@ -0,0 +1,716 @@ +#if FRAMEWORK20 +using System; +using System.Windows.Forms; +using DevComponents.DotNetBar.ScrollBar; +using System.Drawing; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.Schedule +{ + public class TimeLineHScrollPanel : BaseItem + { + #region Events + + public event EventHandler ScrollPanelChanged; + + #endregion + + #region Private variables + + private CalendarView _CalendarView; // CalendarView + + private HScrollBarAdv _ScrollBar; // Scroll bar + private PageNavigator _PageNavigator; // PageNavigator + + private int _UpdateCount; + + #endregion + + /// + /// Constructor + /// + /// _CalendarView + public TimeLineHScrollPanel(CalendarView calendarView) + { + _CalendarView = calendarView; + Name = "TimeLineHScrollPanel"; + + SetUpPanel(); + + Visible = false; + } + + #region Public properties + + /// + /// Gets and sets the display bounds + /// + public override Rectangle Bounds + { + get { return (base.Bounds); } + + set + { + if (base.Bounds != value) + { + base.Bounds = value; + + UpdatePanel(); + } + } + } + + /// + /// Gets and sets the visible status + /// + public override bool Visible + { + get { return (base.Visible); } + + set + { + if (base.Visible != value) + { + base.Visible = value; + + _ScrollBar.Visible = value; + + if (_PageNavigator != null) + _PageNavigator.Visible = value; + } + } + } + + /// + /// Gets the ScrollBar + /// + public HScrollBarAdv ScrollBar + { + get { return (_ScrollBar); } + } + + #endregion + + #region Internal properties + + internal PageNavigator PageNavigator + { + get { return (_PageNavigator); } + } + + #endregion + + #region Private properties + + /// + /// Gets the scrollBar SmallChange value + /// + private int ScrollPanelSmallChange + { + get { return (1); } + } + + /// + /// Gets the scrollBar LargeChange value + /// + private int ScrollPanelLargeChange + { + get { return (Math.Min(ScrollPanelMaximum, ScrollBar.Width / _CalendarView.TimeLineColumnWidth)); } + } + + /// + /// Gets the scrollBar Maximum value + /// + private int ScrollPanelMaximum + { + get { return (_CalendarView.TimeLineColumnCount); } + } + + #endregion + + #region HookScrollEvents + + /// + /// Hooks our ScrollBar events + /// + /// + private void HookScrollEvents(bool hook) + { + if (hook == true) + { + ScrollBar.Scroll += ScrollBarScroll; + ScrollBar.ValueChanged += ScrollBarValueChanged; + } + else + { + ScrollBar.Scroll -= ScrollBarScroll; + ScrollBar.ValueChanged -= ScrollBarValueChanged; + } + } + + #endregion + + #region HookNavigateEvents + + /// + /// Hooks our PageNavigator events + /// + /// + private void HookNavigateEvents(bool hook) + { + if (_PageNavigator != null) + { + if (hook == true) + { + _PageNavigator.NavigateNextPage += NavigateNextPage; + _PageNavigator.NavigatePreviousPage += NavigatePreviousPage; + _PageNavigator.NavigateToday += NavigateToday; + } + else + { + _PageNavigator.NavigateNextPage -= NavigateNextPage; + _PageNavigator.NavigatePreviousPage -= NavigatePreviousPage; + _PageNavigator.NavigateToday -= NavigateToday; + } + } + } + + #endregion + + #region Event handling + + #region ScrollBar_Scroll + + /// + /// ScrollBar Scroll event handler + /// + /// + /// + void ScrollBarScroll(object sender, ScrollEventArgs e) + { + if (e.Type == ScrollEventType.SmallIncrement) + { + // The user has right-arrow scrolled to the very end of + // the scrollbar, so add another time slice to timeline + + if (ScrollBar.Value >= ScrollBar.Maximum - ScrollBar.LargeChange) + IncreaseEndDate(1); + } + else if (e.Type == ScrollEventType.SmallDecrement) + { + // The user has left-arrow scrolled to the very beginning of + // the scrollbar, so add another time slice to timeline + + if (ScrollBar.Value == 0) + DecreaseStartDate(1); + } + } + + #endregion + + #region ScrollBar_ValueChanged + + /// + /// Processes ScrollBar ValueChanged events + /// + /// + /// + void ScrollBarValueChanged(object sender, EventArgs e) + { + OnScrollPanelUpdate(); + } + + #endregion + + #region NavigatePreviousPage + + /// + /// Navigates to the previous page + /// + /// + /// + void NavigatePreviousPage(object sender, EventArgs e) + { + DateTime startDate; + + int n = ScrollBar.LargeChange; + int value = ScrollBar.Value - n; + + if (value < 0) + { + startDate = GetDecreaseStartDate(n); + } + else + { + startDate = + _CalendarView.TimeLineViewStartDate.AddMinutes( + _CalendarView.BaseInterval * -n); + } + + if (_CalendarView.DoPageNavigatorClick(_CalendarView.TimeLineView, + _PageNavigator, PageNavigatorButton.PreviousPage, ref startDate) == false) + { + _CalendarView.TimeLineViewStartDate = GetIntervalStartDate(startDate); + } + } + + #endregion + + #region NavigateToday + + /// + /// Navigates to Today + /// + /// + /// + void NavigateToday(object sender, EventArgs e) + { + DateTime startDate = DateTime.Today; + + if (_CalendarView.DoPageNavigatorClick(_CalendarView.TimeLineView, + _PageNavigator, PageNavigatorButton.Today, ref startDate) == false) + { + if (startDate < _CalendarView.TimeLineViewScrollStartDate || + startDate > _CalendarView.TimeLineViewScrollEndDate) + { + _CalendarView.TimeLineViewScrollStartDate = + GetIntervalStartDate(startDate); + } + } + } + + #endregion + + #region NavigateNextPage + + /// + /// Navigates to the Next page + /// + /// + /// + void NavigateNextPage(object sender, EventArgs e) + { + DateTime startDate; + + int n = ScrollBar.LargeChange; + int value = ScrollBar.Value + n; + + if (value > ScrollBar.Maximum - n) + { + startDate = GetIncreaseEndDate(n); + } + else + { + startDate = + _CalendarView.TimeLineViewStartDate.AddMinutes( + _CalendarView.BaseInterval * n); + } + + if (_CalendarView.DoPageNavigatorClick(_CalendarView.TimeLineView, + _PageNavigator, PageNavigatorButton.NextPage, ref startDate) == false) + { + _CalendarView.TimeLineViewStartDate = GetIntervalStartDate(startDate); + } + } + + #endregion + + #region IncreaseEndDate + + /// + /// Increases timeline EndDate + /// + /// Amount to add + private void IncreaseEndDate(int n) + { + if (_CalendarView.TimeLineCanExtendRange == true) + { + _CalendarView.TimeLineViewEndDate = GetIncreaseEndDate(n); + + int value = ScrollBar.Value + n; + + if (value > ScrollBar.Maximum - ScrollBar.LargeChange) + value = ScrollBar.Maximum - ScrollBar.LargeChange; + + if (ScrollBar.Value != value) + ScrollBar.Value = value; + else + OnScrollPanelUpdate(); + } + } + + #endregion + + #region GetIncreaseEndDate + + /// + /// Increases timeline EndDate + /// + /// Amount to add + private DateTime GetIncreaseEndDate(int n) + { + if (_CalendarView.TimeLineCanExtendRange == true) + { + DateTime end = new DateTime(9900, 1, 1); + + try + { + DateTime date = + _CalendarView.TimeLineViewEndDate.AddMinutes( + _CalendarView.BaseInterval * n); + + if (date > end) + date = end; + + return (date); + } + catch + { + return (end); + } + } + + return (_CalendarView.TimeLineViewEndDate); + } + + #endregion + + #region DecreaseStartDate + + /// + /// Decreases the timeline StartDate + /// + /// Amount to del + private void DecreaseStartDate(int n) + { + if (_CalendarView.TimeLineCanExtendRange == true) + { + DateTime startDate = GetDecreaseStartDate(n); + + _CalendarView.TimeLineViewStartDate = startDate; + + UpdatePanel(); + } + } + + #endregion + + #region GetDecreaseStartDate + + /// + /// Decreases the timeline StartDate + /// + /// Amount to del + private DateTime GetDecreaseStartDate(int n) + { + if (_CalendarView.TimeLineCanExtendRange == true) + { + try + { + return (_CalendarView.TimeLineViewStartDate.AddMinutes( + -_CalendarView.BaseInterval * n)); + } + catch + { + return (new DateTime(1, 1, 1)); + } + } + + return (_CalendarView.TimeLineViewStartDate); + } + + #endregion + + #region GetIntervalStartDate + + private DateTime GetIntervalStartDate(DateTime startDate) + { + TimeSpan ts = new TimeSpan(startDate.Hour, startDate.Minute, 0); + + int interval = _CalendarView.TimeLineInterval; + int minutes = ((int)ts.TotalMinutes / interval) * interval; + + return (startDate.Date.AddMinutes(minutes)); + } + + #endregion + + #endregion + + #region Begin/EndUpdate + + /// + /// Begins Update block + /// + public void BeginUpdate() + { + _UpdateCount++; + } + + /// + /// Ends update block + /// + public void EndUpdate() + { + if (_UpdateCount == 0) + { + throw new InvalidOperationException( + "EndUpdate must be called After BeginUpdate"); + } + + _UpdateCount--; + + if (_UpdateCount == 0) + OnScrollPanelUpdate(); + } + + #endregion + + #region SetUpPanel + + /// + /// Performs panel setup + /// + private void SetUpPanel() + { + Control c = (Control)_CalendarView.CalendarPanel.GetContainerControl(true); + + if (c != null) + { + SetupPageNavigator(c); + SetupScrollBar(c); + + UpdatePanel(); + } + } + + #endregion + + #region SetupPageNavigator + + /// + /// Sets-up the PageNavigator + /// + /// + private void SetupPageNavigator(Control c) + { + _PageNavigator = new PageNavigator(); + + _PageNavigator.Visible = false; + _PageNavigator.FocusCuesEnabled = false; + + HookNavigateEvents(true); + + c.Controls.Add(_PageNavigator); + + _PageNavigator.NextPageTooltip = _CalendarView.TimeLinePageNavigatorNextPageTooltip; + _PageNavigator.PreviousPageTooltip = _CalendarView.TimeLinePageNavigatorPreviousPageTooltip; + _PageNavigator.TodayTooltip = _CalendarView.TimeLinePageNavigatorTodayTooltip; + } + + #endregion + + #region SetupScrollBar + + private void SetupScrollBar(Control c) + { + _ScrollBar = new HScrollBarAdv(); + + _ScrollBar.Visible = false; + _ScrollBar.Height = SystemInformation.HorizontalScrollBarHeight; + + HookScrollEvents(true); + + c.Controls.Add(_ScrollBar); + } + + #endregion + + #region UpdatePanel + + /// + /// Updates the panel + /// + public void UpdatePanel() + { + if (Bounds.Width > 0) + { + UpdatePageNavigator(); + UpdateScrollBar(); + + OnScrollPanelUpdate(); + } + } + + #endregion + + #region UpdatePageNavigator + + /// + /// Updates the PageNavigator + /// + private void UpdatePageNavigator() + { + if (_CalendarView.TimeLineShowPageNavigation == true) + { + // We are to show the PageNavigator, so allocate it + // if we haven't done so already + + if (_PageNavigator == null) + { + Control c = (Control)_CalendarView.CalendarPanel.GetContainerControl(true); + + if (c != null) + { + SetupPageNavigator(c); + + if (_PageNavigator != null) + _PageNavigator.Visible = Visible; + } + } + } + else + { + // We are not to show a PageNavigator, so if we have already + // allocated one, see that we release it appropriately + + if (_PageNavigator != null) + { + Control c = (Control)_CalendarView.CalendarPanel.GetContainerControl(true); + + if (c != null) + { + c.Controls.Remove(_PageNavigator); + + HookNavigateEvents(false); + + _PageNavigator = null; + } + } + } + } + + #endregion + + #region UpdateScrollBar + + /// + /// Updates our ScrollBar + /// + private void UpdateScrollBar() + { + _ScrollBar.Maximum = ScrollPanelMaximum; + _ScrollBar.SmallChange = ScrollPanelSmallChange; + _ScrollBar.LargeChange = ScrollPanelLargeChange; + + if (_ScrollBar.Value > _ScrollBar.Maximum - _ScrollBar.LargeChange) + _ScrollBar.Value = _ScrollBar.Maximum - _ScrollBar.LargeChange; + + _ScrollBar.Refresh(); + } + + #endregion + + #region OnScrollPanelUpdate + + /// + /// Passes the scroll onto others + /// + protected void OnScrollPanelUpdate() + { + if (_UpdateCount == 0) + { + if (ScrollPanelChanged != null) + ScrollPanelChanged(this, EventArgs.Empty); + } + } + + #endregion + + #region RecalcSize + + /// + /// Performs control recalc + /// + public override void RecalcSize() + { + // Update our PageNavigator + + UpdatePageNavigator(); + + int navWidth = 0; + + if (_PageNavigator != null) + { + navWidth = _PageNavigator.Width; + + _PageNavigator.Location = + new Point(Bounds.Right - navWidth, Bounds.Y); + } + + // Update our ScrollBar + + UpdateScrollBar(); + + if (_ScrollBar != null) + { + _ScrollBar.Location = Bounds.Location; + _ScrollBar.Width = Bounds.Width - navWidth; + } + + base.RecalcSize(); + } + + #endregion + + #region Paint + + public override void Paint(ItemPaintArgs p) + { + } + + #endregion + + #region Copy + + /// + /// Returns copy of the item + /// + public override BaseItem Copy() + { + TimeLineHScrollPanel objCopy = new TimeLineHScrollPanel(_CalendarView); + + this.CopyToItem(objCopy); + + return (objCopy); + } + /// + /// Copies the TimeLineHScrollPanel specific properties to + /// new instance of the item + /// + /// New PageNavigatorItem instance + protected override void CopyToItem(BaseItem copy) + { + TimeLineHScrollPanel c = copy as TimeLineHScrollPanel; + base.CopyToItem(c); + } + + #endregion + + #region Dispose + + protected override void Dispose(bool disposing) + { + if (disposing == true && IsDisposed == false) + { + HookScrollEvents(false); + HookNavigateEvents(false); + } + + base.Dispose(disposing); + } + + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineHeaderPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineHeaderPanel.cs new file mode 100644 index 00000000..9ce6100b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineHeaderPanel.cs @@ -0,0 +1,1083 @@ +#if FRAMEWORK20 +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; + +namespace DevComponents.DotNetBar.Schedule +{ + public class TimeLineHeaderPanel : BaseItem + { + #region Private Variables + + private CalendarView _CalendarView; // Assoc CalendarView + + private int _HScrollPos; // Horizontal scroll position + + private CalendarWeekDayColor _ViewColor = // View display color table + new CalendarWeekDayColor(eCalendarColor.Automatic); + + #endregion + + /// + /// Constructor + /// + /// + public TimeLineHeaderPanel(CalendarView calendarView) + { + _CalendarView = calendarView; + + MouseUpNotification = true; + Name = "TimeLineHeaderPanel"; + + HookEvents(true); + } + + #region Private properties + + #region Column properties + + /// + /// Gets the ColumnWidth + /// + private int ColumnWidth + { + get { return (_CalendarView.TimeLineColumnWidth); } + } + + /// + /// Gets the TimeLineColumnCount + /// + private int ColumnCount + { + get { return (_CalendarView.TimeLineColumnCount); } + } + + #endregion + + #region Header properties + + /// + /// Gets the ShowPeriodHeader property + /// + private bool ShowPeriodHeader + { + get { return (_CalendarView.TimeLineShowPeriodHeader); } + } + + /// + /// Gets the ShowIntervalHeader property + /// + private bool ShowIntervalHeader + { + get { return (_CalendarView.TimeLineShowIntervalHeader); } + } + + + /// + /// Interval header height + /// + private int IntervalHeaderHeight + { + get { return (_CalendarView.TimeLineIntervalHeaderHeight); } + } + + /// + /// Period header height + /// + private int PeriodHeaderHeight + { + get + { + return (ShowPeriodHeader && _CalendarView.TimeLinePeriodHeaderHeight > 0 ? + _CalendarView.TimeLinePeriodHeaderHeight - 1 : 0); + } + } + + /// + /// Header font + /// + private Font HeaderFont + { + get { return (_CalendarView.Font); } + } + + #endregion + + #region StartDate + + /// + /// TimeLine start date + /// + private DateTime StartDate + { + get { return (_CalendarView.TimeLineViewStartDate); } + } + + #endregion + + #endregion + + #region Public properties + + /// + /// Gets and sets the view color + /// + public eCalendarColor CalendarColor + { + get { return (_ViewColor.ColorSch); } + + set + { + _ViewColor.ColorSch = value; + Refresh(); + } + } + #endregion + + #region HookEvents + + /// + /// Routine hooks all necessary events for this control + /// + /// True to hook, false to unhook + private void HookEvents(bool hook) + { + if (hook == true) + { + _CalendarView.TimeLineIntervalChanged += TimeLineIntervalChanged; + _CalendarView.TimeLineIntervalPeriodChanged += TimeLineIntervalPeriodChanged; + _CalendarView.TimeIndicatorsChanged += TimeIndicatorCollectionChanged; + _CalendarView.TimeIndicatorTimeChanged += TimeIndicatorTimeChanged; + + _CalendarView.TimeLineHScrollPanel.ScrollPanelChanged += ScrollPanelChanged; + } + else + { + _CalendarView.TimeLineIntervalChanged -= TimeLineIntervalChanged; + _CalendarView.TimeLineIntervalPeriodChanged -= TimeLineIntervalPeriodChanged; + _CalendarView.TimeIndicatorsChanged -= TimeIndicatorCollectionChanged; + _CalendarView.TimeIndicatorTimeChanged -= TimeIndicatorTimeChanged; + + _CalendarView.TimeLineHScrollPanel.ScrollPanelChanged -= ScrollPanelChanged; + } + } + + #endregion + + #region Event processing + + #region TimeLineIntervalPeriodChanged + + /// + /// TimeLineIntervalPeriod Change notification + /// + /// + /// + void TimeLineIntervalPeriodChanged(object sender, TimeLineIntervalPeriodChangedEventArgs e) + { + Refresh(); + } + + #endregion + + #region TimeLineIntervalChanged + + /// + /// TimeLineInterval Change notification + /// + /// + /// + void TimeLineIntervalChanged(object sender, TimeLineIntervalChangedEventArgs e) + { + Refresh(); + } + + #endregion + + #region TimeIndicatorCollectionChanged + + /// + /// Handles TimeIndicatorCollectionChanged events + /// + /// + /// + void TimeIndicatorCollectionChanged(object sender, EventArgs e) + { + Refresh(); + } + + #endregion + + #region TimeIndicatorTimeChanged + + /// + /// Handles TimeIndicatorTimeChanged events + /// + /// + /// + void TimeIndicatorTimeChanged(object sender, TimeIndicatorTimeChangedEventArgs e) + { + Refresh(); + } + + #endregion + + #region ScrollPanelChanged + + /// + /// Horizontal Scroll Panel change notification + /// + /// + /// + void ScrollPanelChanged(object sender, EventArgs e) + { + _HScrollPos = -_CalendarView.TimeLineHScrollPanel.ScrollBar.Value * + _CalendarView.TimeLineColumnWidth; + + // Redraw our view + + Refresh(); + } + + #endregion + + #endregion + + #region IsMarkupSupported + + /// + /// IsMarkupSupported + /// + protected override bool IsMarkupSupported + { + get { return (_CalendarView != null ? + _CalendarView.TimeLinePeriodHeaderEnableMarkup : true); } + } + + #endregion + + #region GetViewAreaFromPoint + + /// + /// Gets the view area under the given mouse point + /// + /// Point + /// eViewArea + public eViewArea GetViewAreaFromPoint(Point pt) + { + if (Bounds.Contains(pt) == true) + { + if (ShowPeriodHeader == true) + { + if (pt.Y < PeriodHeaderHeight) + return (eViewArea.InPeriodHeader); + } + + return (eViewArea.InIntervalHeader); + } + + return (eViewArea.NotInView); + } + + #endregion + + #region GetIntervalDateFromPoint + + /// + /// Gets the IntervalHeader Start Date under the given mouse point + /// + /// Point + /// ref to interval start date. + /// 'true' if valid date is returned. + public bool GetIntervalDateFromPoint(Point pt, ref DateTime startDate) + { + if (GetViewAreaFromPoint(pt) == eViewArea.InIntervalHeader) + { + int scol = -_HScrollPos / ColumnWidth; + int ecol = (-_HScrollPos + Bounds.Width + ColumnWidth - 2) / ColumnWidth; + + DateTime date = _CalendarView.TimeLineAddInterval(StartDate, scol); + + for (int i = scol; i <= ecol; i++) + { + Rectangle r = GetColumnRect(i); + + if (r.Contains(pt) == true) + { + startDate = date; + + return (true); + } + + date = _CalendarView.TimeLineAddInterval(date, 1); + } + } + + return (false); + } + + #endregion + + #region Paint processing + + /// + /// Paint processing routine + /// + /// + public override void Paint(ItemPaintArgs e) + { + if (ShowPeriodHeader == true || ShowIntervalHeader == true) + { + // Set our current color table + + _ViewColor.SetColorTable(); + + // Only draw something if we have something to draw + + if (_CalendarView.TimeLineColumnCount > 0) + { + // Draw our calendar parts + + int colStart, colEnd; + + if (GetColRange(e.ClipRectangle, out colStart, out colEnd) > 0) + { + Region rgnSave = e.Graphics.Clip; + + using (Region rgn = new Region(Bounds)) + { + e.Graphics.Clip = rgn; + + if (ShowPeriodHeader == true) + DrawDateHeader(e); + + if (ShowIntervalHeader == true) + DrawIntervalHeader(e, colStart, colEnd); + } + + e.Graphics.Clip = rgnSave; + } + } + } + } + + #region DrawDateHeader + + /// + /// Draws the encompassing Date header + /// + /// ItemPaintArgs + private void DrawDateHeader(ItemPaintArgs e) + { + int scol = -_HScrollPos / ColumnWidth; + int ecol = (-_HScrollPos + Bounds.Width + ColumnWidth - 2) / ColumnWidth; + + DateTime date1 = _CalendarView.TimeLineAddInterval(StartDate, scol); + DateTime date2 = date1; + + for (int i = scol + 1; i < ecol; i++) + { + date2 = _CalendarView.TimeLineAddInterval(StartDate, i); + + if (PeriodChange(date1, date2, i) == true) + { + DrawDatePeriod(e, scol, i - 1, date1, date2.AddMinutes(-1)); + + scol = i; + date1 = date2; + } + } + + DrawDatePeriod(e, scol, ecol, date1, date2); + } + + #region PeriodChange + + /// + /// Determines if a date period change has occurred + /// + /// Initial date + /// Current date + /// Current column + /// + private bool PeriodChange(DateTime date1, DateTime date2, int col) + { + switch (_CalendarView.TimeLinePeriod) + { + case eTimeLinePeriod.Days: + if (_CalendarView.TimeLineInterval == 1) + return (date1.Month != date2.Month); + + return (date1.Year != date2.Year); + + case eTimeLinePeriod.Years: + return ((col > 0) && (col % 10 == 0)); + + default: + return (date1.Day != date2.Day); + } + } + + #endregion + + #region DrawDatePeriod + + /// + /// Draws a given date period or range + /// + /// + /// Starting column + /// Ending column + /// + /// + private void DrawDatePeriod(ItemPaintArgs e, + int scol, int ecol, DateTime startDate, DateTime endDate) + { + Graphics g = e.Graphics; + + Rectangle rs = GetColumnRect(scol); + Rectangle re = GetColumnRect(ecol); + + Rectangle r = new Rectangle(rs.X, rs.Y, re.Right - rs.X, PeriodHeaderHeight); + + // Keep us in bounds + + if (r.X < Bounds.X) + { + r.Width -= (Bounds.X - r.X); + r.X = Bounds.X; + } + + if (r.Right > Bounds.Right) + r.Width -= (r.Right - Bounds.Right) + 1; + + if (r.Width > 0 && r.Height > 0) + { + // Fill the area + + using (Brush lbr = + _ViewColor.BrushPart((int)eCalendarWeekDayPart.DayHeaderBackground, r)) + { + g.FillRectangle(lbr, r); + } + + // Format the period text and output it both + // vertically and horizontally centered + + string text = GetDatePeriodText(ref startDate, ref endDate); + + if (_CalendarView.DoTimeLineViewRenderPeriodHeader(g, startDate, endDate, r, ref text) == false) + { + if (String.IsNullOrEmpty(text) == false) + { + Text = text; + + if (IsUsingTextMarkup) + { + TextMarkup.MarkupDrawContext d = + new TextMarkup.MarkupDrawContext(g, HeaderFont, _ViewColor.GetColor( + (int) eCalendarWeekDayPart.DayHeaderForeground), IsRightToLeft); + + TextMarkupBodyMeasure(new Size(5000, 5000), d); + + TextMarkupBodyArrange(new Rectangle(Point.Empty, TextMarkupBodyBounds.Size), d); + + TextMarkupBodyBounds = AlignMarkUpText(r); + + RenderMarkup(g, d); + } + else + { + Size sz = TextDrawing.MeasureString(g, Text, HeaderFont); + + eTextFormat tf = eTextFormat.VerticalCenter; + + switch (_CalendarView.TimeLinePeriodHeaderAlignment) + { + case eItemAlignment.Center: + if (sz.Width < r.Width) + tf |= eTextFormat.HorizontalCenter; + break; + + case eItemAlignment.Far: + if (sz.Width < r.Width) + tf |= eTextFormat.Right; + break; + } + + // Draw the text + + TextDrawing.DrawString(g, Text, HeaderFont, _ViewColor.GetColor( + (int) eCalendarWeekDayPart.DayHeaderForeground), r, tf); + } + } + } + + // Draw the border + + using (Pen pen = new Pen( + _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHeaderBorder))) + { + g.DrawRectangle(pen, r); + } + } + } + + #region AlignMarkUpText + + /// + /// Aligns the MarkUp text + /// + /// + /// + private Rectangle AlignMarkUpText(Rectangle r) + { + if (r.Height > TextMarkupBodyBounds.Height) + r.Y += (r.Height - TextMarkupBodyBounds.Height) / 2; + + if (r.Width > TextMarkupBodyBounds.Width) + { + switch (_CalendarView.TimeLinePeriodHeaderAlignment) + { + case eItemAlignment.Center: + r.X += (r.Width - TextMarkupBodyBounds.Width) / 2; + break; + + case eItemAlignment.Far: + r.X += (r.Width - TextMarkupBodyBounds.Width); + break; + + default: + r.X += 3; + break; + } + } + + return (r); + } + + #endregion + + #region RenderMarkup + + /// + /// Renders the current MarkUp + /// + /// + /// + private void RenderMarkup(Graphics g, TextMarkup.MarkupDrawContext d) + { + Region oldClip = g.Clip; + Rectangle clipRect = TextMarkupBodyBounds; + + g.SetClip(clipRect, CombineMode.Intersect); + + TextMarkupBodyRender(d); + + g.Clip = oldClip; + } + + #endregion + + #region GetDatePeriodText + + /// + /// Gets the default Period text + /// + /// + /// + /// + private string GetDatePeriodText(ref DateTime startDate, ref DateTime endDate) + { + // Days text + + if (_CalendarView.TimeLinePeriod == eTimeLinePeriod.Days) + { + if (_CalendarView.TimeLineInterval == 1) + return (startDate.ToString("y")); + + return (startDate.Year.ToString()); + } + + // Years text + + if (_CalendarView.TimeLinePeriod == eTimeLinePeriod.Years) + { + int n = _CalendarView.TimeLineInterval * 10; + int m = startDate.Year - _CalendarView.TimeLineViewStartDate.Year; + + m = (m / n) * n; + + startDate = _CalendarView.TimeLineViewStartDate.AddYears(m); + endDate = startDate.AddYears(n - 1); + + return (startDate.Year + " - " + endDate.Year); + } + + // Everything else + + return (startDate.Date.ToShortDateString()); + } + + #endregion + + #endregion + + #endregion + + #region DrawIntervalHeader + + /// + /// Draws the time interval header + /// + /// ItemPaintArgs + /// Starting column + /// Ending column + private void DrawIntervalHeader(ItemPaintArgs e, int colStart, int colEnd) + { + Graphics g = e.Graphics; + + Rectangle rs = GetColumnRect(colStart); + Rectangle re = GetColumnRect(colEnd); + + Rectangle r = new Rectangle(rs.X, rs.Y + PeriodHeaderHeight, + re.Right - rs.X, IntervalHeaderHeight); + + if (r.Width > 0 && r.Height > 0) + { + DrawBackground(g, r); + DrawTimeIndicators(g, colStart, colEnd, r); + DrawContent(g, colStart, colEnd, r); + } + } + + #region DrawBackground + + /// + /// DrawBackground + /// + /// + /// + private void DrawBackground(Graphics g, Rectangle r) + { + using (Brush lbr = _ViewColor.BrushPart((int)eCalendarWeekDayPart.DayHeaderBackground, r)) + g.FillRectangle(lbr, r); + } + + #endregion + + #region DrawTimeIndicators + + #region DrawTimeIndicators + + /// + /// Draws view TimeIndicators + /// + /// + /// + /// + /// + private void DrawTimeIndicators(Graphics g, + int colStart, int colEnd, Rectangle r) + { + DateTime start = _CalendarView.TimeLineAddInterval(StartDate, colStart); + DateTime end = _CalendarView.TimeLineAddInterval(StartDate, colEnd); + + for (int i = 0; i < _CalendarView.TimeIndicators.Count; i++) + { + TimeIndicator ti = _CalendarView.TimeIndicators[i]; + + if (ti.IndicatorArea == eTimeIndicatorArea.All || + ti.IndicatorArea == eTimeIndicatorArea.Header) + { + if (ti.IsVisible()) + { + DateTime time = ti.IndicatorDisplayTime; + + if (time >= start && time < end) + DrawTimeIndicator(g, start, r, ti); + } + } + } + } + + #endregion + + #region DrawTimeIndicator + + #region DrawTimeIndicator + + /// + /// Draws individual view TimeIndicator + /// + /// + /// + /// + /// + private void DrawTimeIndicator(Graphics g, + DateTime startDate, Rectangle sRect, TimeIndicator ti) + { + Rectangle r = GetIndicatorRect(ti, startDate, sRect); + + if (r.IntersectsWith(sRect) == true) + { + if (r.Width > 0) + { + ColorDef cdef = GetIndicatorColor(ti); + + if (cdef != null) + { + float angle = cdef.Angle - 90; + + using (Brush br = _ViewColor.BrushPart(cdef, r, angle)) + { + if (br is LinearGradientBrush) + ((LinearGradientBrush) br).WrapMode = WrapMode.TileFlipX; + + g.FillRectangle(br, r); + } + } + } + + Color color = GetIndicatorBorder(ti); + + if (color.IsEmpty == false) + { + using (Pen pen = new Pen(color)) + g.DrawLine(pen, r.Right, r.Top, r.Right, r.Bottom - 1); + } + } + } + + #endregion + + #region GetIndicatorColor + + /// + /// Gets the Indicator Back color + /// + /// + /// + private ColorDef GetIndicatorColor(TimeIndicator ti) + { + ColorDef cdef = ti.IndicatorColor; + + if (cdef == null || cdef.IsEmpty == true) + cdef = _ViewColor.GetColorDef((int)eCalendarWeekDayPart.TimeIndicator); + + return (cdef); + } + + #endregion + + #region GetIndicatorBorder + + /// + /// Gets the Indicator Border color + /// + /// + /// + private Color GetIndicatorBorder(TimeIndicator ti) + { + return (ti.BorderColor.IsEmpty == false ? ti.BorderColor : + _ViewColor.GetColor((int)eCalendarWeekDayPart.TimeIndicatorBorder)); + } + + #endregion + + #endregion + + #region GetIndicatorRect + + /// + /// CalcIndicatorRect + /// + /// + /// + /// + /// + private Rectangle GetIndicatorRect( + TimeIndicator ti, DateTime startDate, Rectangle sRect) + { + double x = ColumnWidth / _CalendarView.BaseInterval; + + int offset = (int)((ti.IndicatorDisplayTime - startDate).TotalMinutes * x); + + sRect.X += (offset - ti.Thickness - 1); + sRect.Width = ti.Thickness; + + return (sRect); + } + + #endregion + + #endregion + + #region DrawContent + + /// + /// DrawContent + /// + /// + /// + /// + /// + private void DrawContent(Graphics g, + int colStart, int colEnd, Rectangle r) + { + bool dcDay = _CalendarView.HighlightCurrentDay == true && + _CalendarView.TimeLinePeriod == eTimeLinePeriod.Days && _CalendarView.TimeLineInterval == 1; + + DateTime now = DateTime.Now.Date; + DateTime date = _CalendarView.TimeLineAddInterval(StartDate, colStart); + + r.Width = ColumnWidth; + + int x = -1; + + using (Pen pen = new Pen( + _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHeaderBorder))) + { + // Loop through each column, drawing the + // time text in the header area + + for (int i = colStart; i <= colEnd; i++) + { + if (dcDay == false || date.Date.Equals(now) == false) + { + // Draw the text and header border + + TextDrawing.DrawString(g, GetIntervalText(date), HeaderFont, + _ViewColor.GetColor((int) eCalendarWeekDayPart.DayHeaderForeground), + r, eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter); + + g.DrawRectangle(pen, r); + } + else + { + x = r.X; + } + + date = _CalendarView.TimeLineAddInterval(date, 1); + + r.X += ColumnWidth; + } + } + + if (x >= 0) + { + r.X = x; + + using (Brush br = _ViewColor.BrushPart((int)eCalendarWeekDayPart.NowDayHeaderBackground, r)) + g.FillRectangle(br, r); + + TextDrawing.DrawString(g, GetIntervalText(now), HeaderFont, + _ViewColor.GetColor((int)eCalendarWeekDayPart.NowDayHeaderForeground), + r, eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter); + + using (Pen pen = new Pen(_ViewColor.GetColor((int)eCalendarWeekDayPart.NowDayHeaderBorder))) + g.DrawRectangle(pen, r); + } + } + + #region GetIntervalText + + /// + /// Gets the interval text + /// + /// DateTime + /// Interval text + public string GetIntervalText(DateTime date) + { + string s; + + switch (_CalendarView.TimeLinePeriod) + { + case eTimeLinePeriod.Days: + s = GetDayIntervalText(date); + break; + + case eTimeLinePeriod.Years: + s = GetYearIntervalText(date); + break; + + default: + s = GetMinuteIntervalText(date); + break; + } + + _CalendarView.DoTimeLineGetHeaderText(this, date, ref s); + + return (s); + } + + /// + /// Gets minute interval text + /// + /// DateTime + /// Interval text + private string GetMinuteIntervalText(DateTime date) + { + if (_CalendarView.Is24HourFormat == true) + return (date.ToString("t", DateTimeFormatInfo.InvariantInfo)); + + return (date.ToString("t", null)); + } + + /// + /// Gets Day interval text + /// + /// + /// Interval text + private string GetDayIntervalText(DateTime date) + { + DateTimeFormatInfo dtfi = + ScheduleSettings.GetActiveCulture().DateTimeFormat; + + string s = dtfi.MonthDayPattern; + + s = s.Replace("MMMM", "M"); + s = s.Replace(" ", dtfi.DateSeparator); + + return (date.ToString(s)); + } + + /// + /// Gets year interval text + /// + /// + /// Interval text + private string GetYearIntervalText(DateTime date) + { + return (date.Year.ToString()); + } + + #endregion + + #endregion + + #endregion + + #region GetColumnRect + + private Rectangle GetColumnRect(int col) + { + int x = Bounds.X + (col * ColumnWidth) + _HScrollPos; + + return (new Rectangle(x, Bounds.Y, + ColumnWidth, Bounds.Height)); + } + + #endregion + + #region GetColRange + + /// + /// Calculates the range of days needed to be drawn + /// to satisfy the specified paint request + /// + /// Clip rectangle + /// [out] Column start index + /// [out] Column end index + /// Day range count (end - start) + private int GetColRange(Rectangle clip, out int colStart, out int colEnd) + { + // Calc our starting index + + int start = -_HScrollPos / ColumnWidth; + int x = Bounds.X + start * ColumnWidth + _HScrollPos; + + while (start < ColumnCount) + { + if (x + ColumnWidth > clip.X) + break; + + x += ColumnWidth; + + start++; + } + + // Calc our ending index + + int end = start; + + while (end < ColumnCount) + { + if (x >= clip.Right) + break; + + x += ColumnWidth; + + end++; + } + + end++; + + // Set the user supplied 'out' values, and + // return the range count to the caller + + if (end - start == 0) + { + colStart = 0; + colEnd = 0; + + return (0); + } + + colStart = start; + colEnd = end; + + return (end - start); + } + + #endregion + + #endregion + + #region IDisposable Members + + protected override void Dispose(bool disposing) + { + if (disposing == true && IsDisposed == false) + HookEvents(false); + + base.Dispose(disposing); + } + + #endregion + + #region Copy + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + TimeLineHeaderPanel objCopy = new TimeLineHeaderPanel(_CalendarView); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the TimeLineHeaderPanel specific properties to new instance of the item. + /// + /// New TimeLineHeaderPanel instance + protected override void CopyToItem(BaseItem copy) + { + TimeLineHeaderPanel objCopy = copy as TimeLineHeaderPanel; + + if (objCopy != null) + { + base.CopyToItem(objCopy); + + objCopy.CalendarColor = this.CalendarColor; + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineVScrollPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineVScrollPanel.cs new file mode 100644 index 00000000..7d5a960c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineVScrollPanel.cs @@ -0,0 +1,40 @@ +#if FRAMEWORK20 +namespace DevComponents.DotNetBar.Schedule +{ + public class TimeLineVScrollPanel : VScrollPanel + { + /// + /// Constructor + /// + /// + public TimeLineVScrollPanel(CalendarView calendarView) + : base(calendarView) + { + } + + #region Private properties + + /// + /// Gets the ScrollBar SmallChange value + /// + protected override int ScrollPanelSmallChange + { + get { return (CalendarView.TimeLineHeight); } + } + + /// + /// Gets the ScrollBar Maximum value + /// + protected override int ScrollPanelMaximum + { + get + { + return (CalendarView.TimeLineHeight * + CalendarView.DisplayedOwners.Count); + } + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineView.cs new file mode 100644 index 00000000..21d6d7f7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/TimeLineView/TimeLineView.cs @@ -0,0 +1,3356 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.ScrollBar; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class TimeLineView : BaseView + { + #region Static variables + + static private AppointmentColor _appointmentColor = new AppointmentColor(); + + #endregion + + #region Private variables + + private CalendarWeekDayColor _ViewColor = // View display color table + new CalendarWeekDayColor(eCalendarColor.Automatic); + + private List + _CalendarItems = new List(); + + private Point _LastMovePoint; // Last mouse move Point + private Point _LastPointOffset; // Last Point offset + private Rectangle _LastBounds; // MouseDown item bounds + + private int _SelectedColStart; // Column start selection + private int _SelectedColEnd; // Column end selection + + private Timer _ScrollViewTimer; // Timer used to implement auto view scrolling + private int _ScrollDwell; // Scroll dwell (pause, throttle) counter + + private Color _WorkColor; // Cached Brush colors + private Color _OffWorkColor; + private Color _SelectedColor; + + private Brush _WorkBrush; // Cached Brushes + private Brush _OffWorkBrush; + private Brush _SelectedBrush; + + private int _HScrollPos; // Horizontal scroll position + + private List _CondensedColList; + private List _CollateLines = new List(); + + private bool _ModelReloaded = true; + + #endregion + + public TimeLineView(CalendarView calendarView, eCalendarView eCalendarView) + : base(calendarView, eCalendarView) + { + // Set our non-client drawing info and CalendarColor + + NClientData = new NonClientData( + eTabOrientation.Vertical, + (int)eCalendarWeekDayPart.OwnerTabBorder, + (int)eCalendarWeekDayPart.OwnerTabForeground, + (int)eCalendarWeekDayPart.OwnerTabBackground, + (int)eCalendarWeekDayPart.OwnerTabContentBackground, + (int)eCalendarWeekDayPart.OwnerTabSelectedForeground, + (int)eCalendarWeekDayPart.OwnerTabSelectedBackground); + + CalendarColorTable = _ViewColor; + + // Hook onto our events + + HookEvents(true); + + if (calendarView.TimeLineHScrollPanel.ScrollBar != null) + { + _HScrollPos = -calendarView.TimeLineHScrollPanel.ScrollBar.Value * + calendarView.TimeLineColumnWidth; + } + } + + #region Public properties + + #region CalendarItems + + /// + /// Gets array of CalendarItems + /// + public List CalendarItems + { + get { return (_CalendarItems); } + } + + #endregion + + #region StartDate + + /// + /// Start date - readonly + /// + public new DateTime StartDate + { + get { return (base.StartDate); } + internal set { base.StartDate = value; } + } + + #endregion + + #region EndDate + + /// + /// End date - readonly + /// + public new DateTime EndDate + { + get { return (base.EndDate); } + internal set { base.EndDate = value; } + } + + #endregion + + #region ColumnWidth + + /// + /// Gets the ColumnWidth + /// + public int ColumnWidth + { + get { return (CalendarView.TimeLineColumnWidth); } + } + + #endregion + + #region BaseInterval + + /// + /// Gets the BaseInterval (interval in total minutes) + /// + public double BaseInterval + { + get { return (CalendarView.BaseInterval); } + } + + #endregion + + #region TimeLineColumnCount + + /// + /// Gets the number of Columns + /// + public int TimeLineColumnCount + { + get { return (CalendarView.TimeLineColumnCount); } + } + + #endregion + + #region MinAppointmentWidth + + /// + /// Gets the MinAppointmentWidth + /// + public int MinAppointmentWidth + { + get { return (CalendarView.TimeLineMinAppointmentWidth); } + } + + #endregion + + #endregion + + #region Private properties + + #region ShowCondensed + + /// + /// Gets the CondensedView visibility state + /// + private bool ShowCondensed + { + get + { + if (CalendarView.TimeLineCondensedViewVisibility == eCondensedViewVisibility.Hidden) + return (false); + + if (CalendarView.TimeLineCondensedViewHeight < 10) + return (false); + + if (CalendarView.TimeLineCondensedViewVisibility == eCondensedViewVisibility.AllResources) + return (true); + + return (CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex); + } + } + + #endregion + + #region Cached Brushes + + #region WorkBrush + + /// + /// Gets and sets the Work time brush + /// + private Brush WorkBrush + { + get + { + Color color = _ViewColor.GetColor( + (int)eCalendarWeekDayPart.DayWorkHoursBackground); + + if (_WorkColor != color) + { + _WorkColor = color; + + WorkBrush = new SolidBrush(color); + } + + return (_WorkBrush); + } + + set + { + if (_WorkBrush != value) + { + if (_WorkBrush != null) + _WorkBrush.Dispose(); + + _WorkBrush = value; + } + } + } + + #endregion + + #region OffWorkBrush + + /// + /// Gets and sets the Off-hours work time brush + /// + private Brush OffWorkBrush + { + get + { + Color color = _ViewColor.GetColor( + (int)eCalendarWeekDayPart.DayOffWorkHoursBackground); + + if (_OffWorkColor != color) + { + _OffWorkColor = color; + + OffWorkBrush = new SolidBrush(color); + } + + return (_OffWorkBrush); + } + + set + { + if (_OffWorkBrush != value) + { + if (_OffWorkBrush != null) + _OffWorkBrush.Dispose(); + + _OffWorkBrush = value; + } + } + } + + #endregion + + #region SelectedBrush + + /// + /// Gets and sets the selected brush + /// + private Brush SelectedBrush + { + get + { + Color color = _ViewColor.GetColor( + (int)eCalendarWeekDayPart.SelectionBackground); + + if (_SelectedColor != color) + { + _SelectedColor = color; + + SelectedBrush = new SolidBrush(color); + } + + return (_SelectedBrush); + } + + set + { + if (_SelectedBrush != value) + { + if (_SelectedBrush != null) + _SelectedBrush.Dispose(); + + _SelectedBrush = value; + } + } + } + + #endregion + + #endregion + + #endregion + + #region Internal Properties + + /// + /// Gets the first visible timeline column + /// + internal int FirstVisibleColumn + { + get { return (-_HScrollPos / ColumnWidth); } + } + + /// + /// Gets the condensed time line height + /// + internal int CondensedLineHeight + { + get { return (CalendarView.TimeLineCondensedViewHeight); } + } + + /// + /// Gets and sets the model reload state + /// + internal bool ModelReloaded + { + get { return (_ModelReloaded); } + set { _ModelReloaded = value; } + } + + #endregion + + #region Hook / Unhook Events + + /// + /// Routine hooks all necessary events for this control + /// + /// True to hook, false to unhook + private void HookEvents(bool hook) + { + if (hook == true) + { + CalendarView.SelectedViewChanged += SelectedViewChanged; + CalendarView.SelectedOwnerChanged += SelectedOwnerChanged; + + CalendarView.TimeLineViewStartDateChanged += TimeLineViewStartDateChanged; + CalendarView.TimeLineViewEndDateChanged += TimeLineViewEndDateChanged; + CalendarView.TimeLineIntervalChanged += TimeLineIntervalChanged; + CalendarView.TimeLineIntervalPeriodChanged += TimeLineIntervalPeriodChanged; + CalendarView.TimeLineCondensedViewVisibilityChanged += TimeLineCondensedViewVisibilityChanged; + + CalendarView.TimeLineHScrollPanel.ScrollPanelChanged += ScrollPanelChanged; + } + else + { + CalendarView.SelectedViewChanged -= SelectedViewChanged; + CalendarView.SelectedOwnerChanged -= SelectedOwnerChanged; + + CalendarView.TimeLineViewStartDateChanged -= TimeLineViewStartDateChanged; + CalendarView.TimeLineViewEndDateChanged -= TimeLineViewEndDateChanged; + CalendarView.TimeLineIntervalChanged -= TimeLineIntervalChanged; + CalendarView.TimeLineIntervalPeriodChanged -= TimeLineIntervalPeriodChanged; + CalendarView.TimeLineCondensedViewVisibilityChanged -= TimeLineCondensedViewVisibilityChanged; + + CalendarView.TimeLineHScrollPanel.ScrollPanelChanged -= ScrollPanelChanged; + } + } + + #endregion + + #region Event handling routines + + #region SelectedViewChanged + + /// + /// Processes view changes + /// + /// object + /// SelectedViewEventArgs + void SelectedViewChanged(object sender, SelectedViewEventArgs e) + { + // Update our IsViewSelected state + + IsViewSelected = (e.NewValue == ECalendarView); + + if (IsViewSelected == true) + { + AutoSyncViewDate(e.OldValue); + UpdateDateSelection(); + } + else + { + ResetView(); + } + } + + #endregion + + #region SelectedOwnerChanged + + void SelectedOwnerChanged(object sender, SelectedOwnerChangedEventArgs e) + { + if (CalendarView.TimeLineStretchRowHeight == true) + { + if (CalendarView.TimeLineCondensedViewVisibility == eCondensedViewVisibility.SelectedResource) + NeedRecalcLayout = true; + } + } + + #endregion + + #region TimeLineViewStartDateChanged + + /// + /// Processes StartDate changes + /// + /// + /// + void TimeLineViewStartDateChanged(object sender, DateChangeEventArgs e) + { + StartDate = e.NewValue; + } + + #endregion + + #region TimeLineViewEndDateChanged + + /// + /// Processes EndDate changes + /// + /// + /// + void TimeLineViewEndDateChanged(object sender, DateChangeEventArgs e) + { + EndDate = e.NewValue; + } + + #endregion + + #region TimeLineIntervalPeriodChanged + + /// + /// Handles IntervalPeriodChange notification + /// + /// + /// + void TimeLineIntervalPeriodChanged(object sender, TimeLineIntervalPeriodChangedEventArgs e) + { + NeedRecalcSize = true; + NeedRecalcLayout = true; + } + + #endregion + + #region TimeLineIntervalChanged + + /// + /// Handles IntervalChange notification + /// + /// + /// + void TimeLineIntervalChanged(object sender, TimeLineIntervalChangedEventArgs e) + { + NeedRecalcSize = true; + NeedRecalcLayout = true; + } + + #endregion + + #region TimeLineCondensedViewVisibilityChanged + + void TimeLineCondensedViewVisibilityChanged( + object sender, TimeLineCondensedViewVisibilityChangedEventArgs e) + { + if (CalendarView.TimeLineStretchRowHeight == true) + NeedRecalcLayout = true; + } + + #endregion + + #region ScrollPanelChanged + + /// + /// Handles ScrollPanel change notification + /// + /// + /// + void ScrollPanelChanged(object sender, EventArgs e) + { + TimeLineHScrollPanel panel = sender as TimeLineHScrollPanel; + + if (panel != null) + { + HScrollBarAdv hScrollBar = panel.ScrollBar; + + _HScrollPos = -hScrollBar.Value * CalendarView.TimeLineColumnWidth; + + // Redraw our view + + if (Displayed == true) + { + NeedRecalcLayout = true; + + InvalidateRect(true); + Refresh(); + } + } + } + + #endregion + + #endregion + + #region GetViewAreaFromPoint + + /// + /// Gets the view area under the given mouse + /// point (tab, header, content, etc) + /// + /// Point + /// eViewArea + public override eViewArea GetViewAreaFromPoint(Point pt) + { + if (Bounds.Contains(pt) == true) + { + if (pt.X >= ClientRect.X) + { + // CondensedView + + if (ShowCondensed == true) + { + if (GetCondensedRect().Contains(pt) == true) + return (eViewArea.InCondensedView); + } + + return (eViewArea.InContent); + } + + return (base.GetViewAreaFromPoint(pt)); + } + + return (eViewArea.NotInView); + } + + #endregion + + #region GetDateSelectionFromPoint + + /// + /// Gets the date selection from the given point. The startDate + /// and endDate will vary based upon the view type + /// + /// Point in question + /// out start date + /// out end date + /// True if a valid selection exists + /// at the given point + public override bool GetDateSelectionFromPoint( + Point pt, out DateTime startDate, out DateTime endDate) + { + base.GetDateSelectionFromPoint(pt, out startDate, out endDate); + + int col; + + if (GetPointItem(pt, out col, true) == true) + { + startDate = CalendarView.TimeLineAddInterval(StartDate, col); + endDate = CalendarView.TimeLineAddInterval(startDate, 1); + + return (true); + } + + return (false); + } + + #endregion + + #region SetSelectedItem + + /// + /// Handles selected item changes + /// + /// CalendarItem + /// EventArgs + public void ItemIsSelectedChanged(object sender, EventArgs e) + { + CalendarItem ci = sender as CalendarItem; + + if (ci != null) + { + if (ci.IsSelected == true) + { + if (SelectedItem != null && ci != SelectedItem) + SelectedItem.IsSelected = false; + + SelectedItem = ci; + } + else + { + if (ci == SelectedItem) + SelectedItem = null; + } + + // Make sure the selection is reflected + // in the condensed view (if present) + + if (ShowCondensed == true) + InvalidateRect(GetCondensedRect()); + } + } + + /// + /// Sets the current selected item + /// + /// Previous CalendarItem + /// New CalendarItem + /// New selected CalendarItem + protected override CalendarItem SetSelectedItem(CalendarItem pci, CalendarItem nci) + { + if (nci != null) + nci.IsSelected = true; + + else if (pci != null) + pci.IsSelected = false; + + return (nci); + } + + #endregion + + #region UpdateDateSelection + + /// + /// Updates our slice selection range to reflect + /// the given date selection start and end values + /// + protected override void UpdateDateSelection() + { + if (IsViewSelected == true) + { + // Get the new absolute slice selection range + + int colStart = GetDateCol(DateSelectionStart); + int colEnd = GetDateCol(DateSelectionEnd); + + // Limit our range to only those columns + // that are visible on the screen + + int c1 = -_HScrollPos / ColumnWidth; + int c2 = c1 + ClientRect.Width / ColumnWidth + 1; + + if (c2 > c1) + { + ProcessSelRange(colStart, colEnd, c1, c2); + + // Save our new selection range + + _SelectedColStart = colStart; + _SelectedColEnd = colEnd; + } + + if (ShowCondensed == true) + { + Rectangle r = GetCondensedRect(); + + this.InvalidateRect(r); + } + } + } + + /// + /// Processes the selection time column range + /// + /// Column range start + /// Column range end + /// Column start limit + /// Column end limit + private void ProcessSelRange(int colStart, int colEnd, int c1, int c2) + { + bool[] oldSelected = SelectedColumns(c1, c2, _SelectedColStart, _SelectedColEnd); + bool[] newSelected = SelectedColumns(c1, c2, colStart, colEnd); + + // Invalidate those slices whose + // selection status changed + + Rectangle r = GetColRect(c1); + + if (r.Width > 0 && r.Height > 0) + { + for (int i = 0; i < c2 - c1; i++) + { + if (oldSelected[i] != newSelected[i]) + InvalidateRect(r); + + r.X += ColumnWidth; + } + } + } + + /// + /// Gets an array of column selection values + /// over the given range of columns + /// + /// Column start limit + /// Column end limit + /// Slice range start + /// Slice range end + /// Array of selection values + private bool[] SelectedColumns(int c1, int c2, int colStart, int colEnd) + { + // Calculate our number of entries and + // allocate our IsSelected array accordingly + + int n = c2 - c1; + bool[] sel = new bool[n + 1]; + + // Loop through the range of entries determining if + // the specific col is within the selection range + + for (int i = 0; i < n; i++) + sel[i] = (c1 + i >= colStart && c1 + i < colEnd); + + // Return the array to the caller + + return (sel); + } + + #endregion + + #region RecalcSize routines + + /// + /// Performs NeedRecalcSize requests + /// + public override void RecalcSize() + { + base.RecalcSize(); + + if (IsViewSelected == true) + { + // Normalize our start and end dates + + DateTime startDate; + DateTime endDate; + NormalizeDates(out startDate, out endDate); + + // Update our Model connection view, + // CalendarItems, and DateSelection + + UpdateView(); + UpdateDateSelection(); + } + + NeedRecalcLayout = false; + } + + #region NormalizeDates + + /// + /// Normalizes the user specified start and end dates + /// + /// [out] Normalized start date + /// [out] Normalized end date + protected virtual void NormalizeDates(out DateTime startDate, out DateTime endDate) + { + startDate = this.StartDate; + endDate = this.EndDate; + } + + #endregion + + #region UpdateView + + /// + /// Updates our connection model view + /// + private void UpdateView() + { + // Make sure we have a model connection + + if (Connector == null) + { + if (CalendarModel != null) + Connector = new ModelTimeLineViewConnector(CalendarModel, this); + } + else + { + // The timeline range could have changed, so let + // the connection refresh the data if needed + + ((ModelTimeLineViewConnector)Connector).RefreshData(false); + } + + // We have a connection, so update our CalendarItems + + if (Connector != null) + { + UpdateCalendarItems(); + + if (ShowCondensed == true) + UpdateCondensedColumnList(); + + CalendarView.DoViewLoadComplete(this); + } + } + + #endregion + + #region ResetView + + /// + /// Disconnects and resets the Model connection + /// + internal override void ResetView() + { + _ModelReloaded = true; + + base.ResetView(); + } + + #endregion + + #region UpdateCalendarItems + + /// + /// Updates our CalendarItems list + /// + private void UpdateCalendarItems() + { + if (NeedRecalcLayout == true) + { + _CollateLines.Clear(); + + if (_CalendarItems.Count > 0) + { + List items = SortCalendarItems(_CalendarItems); + + if (CalendarView.HasTimeLineGetRowCollateIdCallout) + { + SortedDictionary> ditems = CollateCalendarItems(items); + + int dy = 0; + + foreach (KeyValuePair> kvp in ditems) + { + ColumnList colList = new ColumnList(); + + for (int i = 0; i < kvp.Value.Count; i++) + colList.AddColumnSlot(kvp.Value[i], 0); + + colList.CountColumns(); + + dy = CalcAppointmentBounds(colList, dy, true); + + _CollateLines.Add(dy); + } + } + else + { + ColumnList colList = new ColumnList(); + + for (int i = 0; i < items.Count; i++) + colList.AddColumnSlot(items[i], 0); + + colList.CountColumns(); + + CalcAppointmentBounds(colList, 0, false); + } + } + + NeedRecalcLayout = false; + + InvalidateRect(); + } + } + + #region CollateCalendarItems + + private SortedDictionary> + CollateCalendarItems(List items) + { + SortedDictionary> citems = + new SortedDictionary>(); + + for (int i = 0; i < items.Count; i++) + { + if (items[i].CollateId < 0) + { + TimeLineGetRowCollateIdEventArgs e = + new TimeLineGetRowCollateIdEventArgs(items[i]); + + CalendarView.DoTimeLineGetRowCollateId(e); + + items[i].CollateId = e.CollateId; + } + + int collateId = items[i].CollateId; + + if (citems.ContainsKey(collateId) == false) + citems.Add(collateId, new List()); + + citems[collateId].Add(items[i]); + } + + return (citems); + } + + #endregion + + #region SortCalendarItems + + /// + /// Sorts the provided CalendarItems + /// + /// Sorted CalendarItems + private List SortCalendarItems(IEnumerable clist) + { + List items = new List(); + + items.AddRange(clist); + + if (items.Count > 0) + { + items.Sort( + + delegate(CalendarItem c1, CalendarItem c2) + { + if (c1.StartTime > c2.StartTime) + return (1); + + if (c1.StartTime < c2.StartTime) + return (-1); + + if (c1.EndTime < c2.EndTime) + return (1); + + if (c1.EndTime > c2.EndTime) + return (-1); + + int result = 0; + CalendarView.DoDetailSortEvent(this, c1, c2, ref result); + + return (result); + } + ); + } + + return (items); + } + + #endregion + + #region CalcAppointmentBounds + + /// + /// Calculates normal appointment bounds + /// + /// Accumulated ColumnList + /// + /// + private int CalcAppointmentBounds(ColumnList colList, int dy, bool collate) + { + if (colList.SList.Count > 0) + { + // If we are stretching the rows height, then calculate + // the default row height and the row spread, to evenly + // distribute the fill remainder + + bool stretchRow = (collate == false && + CalendarView.TimeLineStretchRowHeight == true); + + int height = GetColRect(0).Height; + + int rowSpread; + int rowHeight = GetColumnRowHeight(colList.SList.Count, stretchRow, height, out rowSpread) - 2; + + for (int i = 0; i < colList.SList.Count; i++) + { + int maxRowHeight = 0; + + for (int j = 0; j < colList.SList[i].Count; j++) + { + SlotItem sitem = colList.SList[i][j]; + CalendarItem item = sitem.CItem; + + Rectangle r = new Rectangle(); + + r.Y = ClientRect.Y + dy; + r.Height = rowHeight; + + if (stretchRow == false) + r.Height = GetRowHeight(item, rowHeight); + + TimeSpan ts1 = item.StartTime - StartDate; + TimeSpan ts2 = item.EndTime - item.StartTime; + + int pos = (int) ((ts1.TotalMinutes * ColumnWidth) / BaseInterval); + int width = (int) ((ts2.TotalMinutes * ColumnWidth) / BaseInterval); + + if (CalendarView.TimeLinePeriod == eTimeLinePeriod.Years) + { + int years = item.StartTime.Year - StartDate.Year; + + pos = (years * ColumnWidth) / CalendarView.TimeLineInterval; + } + + if (width < MinAppointmentWidth) + width = MinAppointmentWidth; + + if (width < 4) + width = 4; + + r.X = ClientRect.X + pos + _HScrollPos; + r.Width = width; + + Rectangle p = ClientRect; + int hpad = CalendarView.TimeLineHorizontalPadding; + + if (r.Left >= p.Left) + { + r.X += hpad; + r.Width -= hpad; + } + + if (r.Right <= p.Right) + r.Width -= hpad; + + if (i < rowSpread) + r.Height++; + + if (item.StartTime != item.EndTime) + { + if (r.Height + 2 > maxRowHeight) + maxRowHeight = r.Height + 2; + } + + if (stretchRow == true) + { + if (CalendarView.TimeLineStretchRowHeightMode == TimeLineStretchRowHeightMode.Full) + { + if (sitem.SList == null) + { + r.Height = height - dy - 2; + } + else + { + int n = GetColumnCount(sitem); + + r.Height = (rowHeight + 1) * n - 1; + + for (int k = 0; k < n; k++) + { + if (i + k >= rowSpread) + break; + + r.Height++; + } + } + } + } + + r.Height++; + + item.Bounds = r; + + // Set it's display state + + item.Displayed = r.IntersectsWith(ClientRect); + } + + dy += maxRowHeight; + } + } + + return (dy); + } + + #region GetColumnCount + + private int GetColumnCount(SlotItem sitem) + { + int column = int.MaxValue; + + for (int i = 0; i < sitem.SList.Count; i++) + { + if (sitem.SList[i].Column < column) + column = sitem.SList[i].Column; + } + + return (column - sitem.Column); + } + + #endregion + + #region GetColumnRowHeight + + private int GetColumnRowHeight(int count, bool stretchRow, int height, out int rowSpread) + { + rowSpread = 0; + + int rowHeight = AppointmentHeight; + + if (stretchRow == true) + { + rowHeight = height / count; + + if (rowHeight < AppointmentHeight) + rowHeight = AppointmentHeight; + else + rowSpread = height - (count * rowHeight); + } + + return (rowHeight); + } + + #endregion + + #region GetRowHeight + + /// + /// Get the RowHeight for the given CalendarItem + /// + /// CalendarItem + /// Calculated height + /// + private int GetRowHeight(CalendarItem item, int height) + { + TimeLineGetRowHeightEventArgs e = + new TimeLineGetRowHeightEventArgs(item, height); + + CalendarView.DoTimeLineGetRowHeight(e); + + return (e.Height); + } + + #endregion + + #endregion + + #endregion + + #region UpdateCondensedColumnList + + /// + /// Updates the condensed view column list + /// + internal void UpdateCondensedColumnList() + { + if (_ModelReloaded == true && Connector != null) + { + _CondensedColList = new List(); + + List items = new List(); + + // Get our appointment collection + + GetCondensedAppts(items); + GetCondensedCustomItems(items); + + // If we have any items, sort them and + // create a corresponding ColumnList + + if (items.Count > 0) + { + items = SortCalendarItems(items); + + if (CalendarView.HasTimeLineGetRowCollateIdCallout) + { + SortedDictionary> ditems = CollateCalendarItems(items); + + foreach (KeyValuePair> kvp in ditems) + { + ColumnList colList = new ColumnList(); + + for (int i = 0; i < kvp.Value.Count; i++) + colList.AddColumnSlot(kvp.Value[i], 0); + + colList.CountColumns(); + + _CondensedColList.Add(colList); + } + } + else + { + _CondensedColList.Add(new ColumnList()); + + for (int i = 0; i < items.Count; i++) + _CondensedColList[0].AddColumnSlot(items[i], 0); + + _CondensedColList[0].CountColumns(); + } + } + + _ModelReloaded = false; + } + } + + #region GetCondensedAppts + + private void GetCondensedAppts(List items) + { + List appts = + ((ModelTimeLineViewConnector)Connector).ListAppts; + + if (appts != null && appts.Count > 0) + { + int n = Math.Min(appts.Count, 500); + n = Math.Max(appts.Count / n, 1); + + for (int i = 0; i < appts.Count; i += n) + { + if (IsAppointmentVisible(appts[i]) == true) + { + CalendarItem ci = new CalendarItem(); + + ci.StartTime = appts[i].StartTime; + ci.EndTime = appts[i].EndTime; + ci.ModelItem = appts[i]; + + items.Add(ci); + } + } + } + } + + /// + /// Determines if an appointment is visible + /// for the given DisplayOwner + /// + /// + /// + private bool IsAppointmentVisible(Appointment app) + { + if (string.IsNullOrEmpty(DisplayedOwnerKey)) + return (true); + + return (app.OwnerKey == DisplayedOwnerKey); + } + + #endregion + + #region GetCondensedCustomItems + + private void GetCondensedCustomItems(List items) + { + for (int i = 0; i < CalendarView.CustomItems.Count; i++) + { + CustomCalendarItem item = CalendarView.CustomItems[i]; + + if (IsCustomItemVisible(item) == true && + (item.StartTime < EndDate && item.EndTime > StartDate)) + { + CalendarItem ci = new CalendarItem(); + + ci.StartTime = item.StartTime; + ci.EndTime = item.EndTime; + ci.ModelItem = item; + + items.Add(ci); + } + } + } + + private bool IsCustomItemVisible(CustomCalendarItem item) + { + if (string.IsNullOrEmpty(Connector.DisplayOwnerKey)) + return (true); + + return (item.OwnerKey.Equals(Connector.DisplayOwnerKey)); + } + + #endregion + + #endregion + + #endregion + + #region Paint processing + + #region Root paint code + + /// + /// Paint processing + /// + /// ItemPaintArgs + public override void Paint(ItemPaintArgs e) + { + Graphics g = e.Graphics; + + // Set our current color table + + _ViewColor.SetColorTable(); + + // calculate our Column count and range + + int colStart, colEnd; + + if (GetColRange(e, out colStart, out colEnd) > 0) + { + Region rgnSave = g.Clip; + + g.SetClip(ClientRect, CombineMode.Intersect); + + // Draw the TimeLine + + DrawTimeLine(g, colStart, colEnd); + DrawTimeIndicators(g, colStart, colEnd, eTimeIndicatorLevel.Bottom); + + if (Connector != null && ShowCondensed == true) + DrawCondensedLine(g); + + // If we have a model connection then + // draw our appointments + + if (Connector != null && Connector.IsConnected) + { + Rectangle r = ClientRect; + r.X += 1; + + if (ShowCondensed == true) + { + Rectangle r2 = GetCondensedRect(); + + if (r.Bottom > r2.Top) + r.Height -= (r.Bottom - r2.Top); + } + + g.SetClip(r, CombineMode.Intersect); + + DrawAppointments(e); + } + + DrawTimeIndicators(g, colStart, colEnd, eTimeIndicatorLevel.Top); + + g.Clip = rgnSave; + + // Update our pos window + + UpdatePosWin(ClientRect); + } + + // Let the base painting take place + + base.Paint(e); + } + + #endregion + + #region DrawTimeLine + + /// + /// Initiates the drawing of the TimeLine + /// + /// Graphics + /// Starting column + /// Ending column + private void DrawTimeLine(Graphics g, int colStart, int colEnd) + { + int n = colEnd - colStart; + + eSlotDisplayState[] states = new eSlotDisplayState[n + 1]; + + for (int i = 0; i <= n; i++) + states[i] = GetSlotState(colStart + i); + + DrawContent(g, colStart, colEnd, states); + DrawBorder(g, colStart, colEnd, states); + } + + #region DrawContent + + /// + /// Draws the content area of the TimeLine + /// + /// + /// Starting column + /// Ending column + /// + private void DrawContent(Graphics g, + int colStart, int colEnd, eSlotDisplayState[] states) + { + Rectangle r = GetColRect(colStart); + + if (CalendarView.HasTimeLineSlotBackgroundCallout == true) + { + for (int i = colStart; i <= colEnd; i++) + { + int n = i - colStart; + + DateTime startTime = StartDate.AddMinutes(i * BaseInterval); + DateTime endTime = startTime.AddMinutes(BaseInterval); + + if (CalendarView.DoTimeLineViewPreRenderSlotBackground( + g, this, startTime, endTime, r, ref states[n]) == false) + { + g.FillRectangle(GetContentBrush(states[n]), r); + + DrawCollateLines(g, r); + + CalendarView.DoTimeLineViewPostRenderSlotBackground( + g, this, startTime, endTime, r, states[n]); + } + + r.X += ColumnWidth; + } + } + else + { + Rectangle t = r; + + for (int i = 0; i <= colEnd - colStart; i++) + { + g.FillRectangle(GetContentBrush(states[i]), t); + + t.X += ColumnWidth; + } + + r.Width += (t.Right - r.Right); + + DrawCollateLines(g, r); + } + } + + #region DrawCollateLines + + private void DrawCollateLines(Graphics g, Rectangle r) + { + if (CalendarView.TimeLineShowCollateLines == true && + _CollateLines.Count > 1) + { + using (Pen pen = new Pen( + _ViewColor.GetColor((int) eCalendarWeekDayPart.DayHalfHourBorder))) + { + for (int i = 0; i < _CollateLines.Count - 1; i++) + { + int y = _CollateLines[i]; + + g.DrawLine(pen, r.X, r.Y + y, r.Right, r.Y + y); + } + } + } + } + + #endregion + + #region GetSlotState + + /// + /// GetSlotState + /// + /// + /// + private eSlotDisplayState GetSlotState(int col) + { + eSlotDisplayState state = eSlotDisplayState.None; + + if (DisplayedOwnerKeyIndex == CalendarView.SelectedOwnerIndex) + { + if (col >= _SelectedColStart && col < _SelectedColEnd) + state |= eSlotDisplayState.Selected; + } + + DateTime date = StartDate.AddMinutes(col * CalendarView.BaseInterval); + WorkTime workTime = new WorkTime(date.Hour, date.Minute); + + if (IsWorkTime((int)date.DayOfWeek, workTime) == true) + state |= eSlotDisplayState.Work; + + return (state); + } + + #endregion + + #region GetContentBrush + + /// + /// Gets the background content brush + /// for the given time slice + /// + /// Background brush + private Brush GetContentBrush(eSlotDisplayState state) + { + if ((state & eSlotDisplayState.Selected) == eSlotDisplayState.Selected) + return (SelectedBrush); + + if ((state & eSlotDisplayState.Work) == eSlotDisplayState.Work) + return (WorkBrush); + + return (OffWorkBrush); + } + + #endregion + + #region IsWorkTime + + /// + /// Determines if the given time is tagged as a "Work time" + /// + /// Day of week + /// WorkTime to test + /// true if specified "time" is a Work time + private bool IsWorkTime(int day, WorkTime time) + { + ModelTimeLineViewConnector tlc = + (ModelTimeLineViewConnector)Connector; + + WorkTime workStartTime = tlc.DayInfo[day].WorkStartTime; + WorkTime workEndTime = tlc.DayInfo[day].WorkEndTime; + + return (time >= workStartTime && time < workEndTime); + } + + #endregion + + #endregion + + #region DrawBorder + + /// + /// Draws the TimeLine border + /// + /// + /// Starting column + /// Ending column + /// + private void DrawBorder(Graphics g, + int colStart, int colEnd, eSlotDisplayState[] states) + { + Rectangle r = GetColRect(colStart); + + // Draw the vertical borders + + if (CalendarView.TimeLinePeriod == eTimeLinePeriod.Minutes) + DrawHalfHourBorders(g, colStart, colEnd, r, states); + else + DrawHourBorders(g, colStart, colEnd, r, states); + + // Now draw the horizontal border + + r.Width = (colEnd - colStart + 1) * ColumnWidth; + r.Height = ClientRect.Height; + + Color color = _ViewColor.GetColor((int)eCalendarWeekDayPart.DayViewBorder); + + if (CalendarView.DoTimeLineViewRenderViewBorder(g, this, colStart, colEnd, r, color) == false) + { + using (Pen pen1 = new Pen(color)) + { + Point pt1 = new Point(r.X, r.Bottom - 1); + Point pt2 = new Point(r.Right - 1, pt1.Y); + + g.DrawLine(pen1, pt1, pt2); + + if (CalendarView.TimeLineShowPeriodHeader == false && + CalendarView.TimeLineShowIntervalHeader == false) + { + pt1 = new Point(r.X, r.Top); + pt2 = new Point(r.Right - 1, pt1.Y); + + g.DrawLine(pen1, pt1, pt2); + } + } + } + } + + #region DrawHalfHourBorders + + /// + /// DrawHalfHourBorders + /// + /// + /// + /// + /// + /// + private void DrawHalfHourBorders(Graphics g, + int colStart, int colEnd, Rectangle bounds, eSlotDisplayState[] states) + { + // Draw the vertical hour and half hour borders + + using (Pen pen1 = new Pen( + _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHourBorder))) + { + using (Pen pen2 = new Pen( + _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHalfHourBorder))) + { + Point pt1 = new Point(bounds.X, ClientRect.Y); + Point pt2 = new Point(bounds.X, ClientRect.Bottom - 1); + + int n = 60 / CalendarView.TimeLineInterval; + int start = -_HScrollPos / ColumnWidth; + + for (int i = colStart; i <= colEnd; i++) + { + bool isHour = (i == start || (i % n) == 0); + Pen pen = (isHour ? pen1 : pen2); + + if (CalendarView.DoTimeLineViewRenderSlotBorder( + g, this, i, isHour, states[i - colStart], pt1, pt2, pen) == false) + { + g.DrawLine((isHour ? pen1 : pen2), pt1, pt2); + } + + pt1.X = pt2.X = (pt1.X + ColumnWidth); + } + } + } + } + + #endregion + + #region DrawHourBorders + + /// + /// DrawHourBorders + /// + /// + /// + /// + /// + /// + private void DrawHourBorders(Graphics g, + int colStart, int colEnd, Rectangle bounds, eSlotDisplayState[] states) + { + // Draw the vertical hour borders + + using (Pen pen = new Pen( + _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHourBorder))) + { + Point pt1 = new Point(bounds.X, ClientRect.Y); + Point pt2 = new Point(bounds.X, ClientRect.Bottom - 1); + + for (int i = colStart; i <= colEnd; i++) + { + if (CalendarView.DoTimeLineViewRenderSlotBorder( + g, this, i, true, states[i - colStart], pt1, pt2, pen) == false) + { + g.DrawLine(pen, pt1, pt2); + } + + pt1.X = pt2.X = (pt1.X + ColumnWidth); + } + } + } + + #endregion + + #endregion + + #region DrawTimeIndicators + + #region DrawTimeIndicators + + /// + /// Draws view TimeIndicators + /// + /// + /// + /// + private void DrawTimeIndicators(Graphics g, + int colStart, int colEnd, eTimeIndicatorLevel level) + { + DateTime start = CalendarView.TimeLineAddInterval(StartDate, colStart); + DateTime end = CalendarView.TimeLineAddInterval(StartDate, colEnd); + + Rectangle r = Rectangle.Union(GetColRect(colStart), GetColRect(colEnd)); + + for (int i = 0; i < CalendarView.TimeIndicators.Count; i++) + { + TimeIndicator ti = CalendarView.TimeIndicators[i]; + + if (ti.IndicatorLevel == level) + { + if (ti.IndicatorArea == eTimeIndicatorArea.All || + ti.IndicatorArea == eTimeIndicatorArea.Content) + { + if (ti.IsVisible(CalendarView, this)) + { + DateTime time = ti.IndicatorDisplayTime; + + if (time >= start && time < end) + DrawTimeIndicator(g, start, r, ti); + } + } + } + } + } + + #endregion + + #region DrawTimeIndicator + + #region DrawTimeIndicator + + /// + /// Draws individual view TimeIndicator + /// + /// + /// + /// + /// + private void DrawTimeIndicator(Graphics g, + DateTime startDate, Rectangle sRect, TimeIndicator ti) + { + Rectangle r = GetIndicatorRect(ti, startDate, sRect); + + if (r.IntersectsWith(sRect) == true) + { + if (r.Width > 0) + { + ColorDef cdef = GetIndicatorColor(ti); + + if (cdef != null) + { + float angle = cdef.Angle - 90; + + using (Brush br = _ViewColor.BrushPart(cdef, r, angle)) + { + if (br is LinearGradientBrush) + ((LinearGradientBrush) br).WrapMode = WrapMode.TileFlipX; + + g.FillRectangle(br, r); + } + } + } + + Color color = GetIndicatorBorder(ti); + + if (color.IsEmpty == false) + { + using (Pen pen = new Pen(color)) + g.DrawLine(pen, r.Right, r.Top, r.Right, r.Bottom - 1); + } + } + } + + #endregion + + #region GetIndicatorColor + + /// + /// Gets the Indicator Back color + /// + /// + /// + private ColorDef GetIndicatorColor(TimeIndicator ti) + { + ColorDef cdef = ti.IndicatorColor; + + if (cdef == null || cdef.IsEmpty == true) + cdef = _ViewColor.GetColorDef((int)eCalendarWeekDayPart.TimeIndicator); + + return (cdef); + } + + #endregion + + #region GetIndicatorBorder + + /// + /// Gets the Indicator Border color + /// + /// + /// + private Color GetIndicatorBorder(TimeIndicator ti) + { + return (ti.BorderColor.IsEmpty == false ? ti.BorderColor : + _ViewColor.GetColor((int)eCalendarWeekDayPart.TimeIndicatorBorder)); + } + + #endregion + + #endregion + + #region GetIndicatorRect + + /// + /// Gets the TimeIndicator Rectangle + /// + /// + /// + /// + /// + private Rectangle GetIndicatorRect( + TimeIndicator ti, DateTime startDate, Rectangle sRect) + { + double x = ColumnWidth / CalendarView.BaseInterval; + + int offset = (int)((ti.IndicatorDisplayTime - startDate).TotalMinutes * x); + + sRect.X += (offset - ti.Thickness - 1); + sRect.Width = ti.Thickness; + + return (sRect); + } + + /// + /// Gets the TimeIndicator Rectangle + /// + /// + /// + internal override Rectangle GetIndicatorRect(TimeIndicator ti) + { + return (GetIndicatorRect(ti, ti.IndicatorDisplayTime)); + } + + /// + /// Gets the TimeIndicator Rectangle for the given date + /// + /// + /// + /// + internal override Rectangle GetIndicatorRect(TimeIndicator ti, DateTime time) + { + int colStart = -_HScrollPos / ColumnWidth; + DateTime startDate = CalendarView.TimeLineAddInterval(StartDate, colStart); + + double x = ColumnWidth / CalendarView.BaseInterval; + int offset = (int)((time - startDate).TotalMinutes * x); + + Rectangle r = GetColRect(colStart); + + r.X += (offset - ti.Thickness - 1); + r.Width = ti.Thickness; + + return (r); + } + + #endregion + + #endregion + + #endregion + + #region DrawCondensedLine + + /// + /// Draws the condensed TimeLine + /// + /// + private void DrawCondensedLine(Graphics g) + { + TimeSpan ts0 = EndDate - StartDate; + float scale = (float)(ClientRect.Width / (ts0.TotalMinutes + BaseInterval)); + + Rectangle r = GetCondensedRect(); + + using (GraphicsPath path = GetCondensedViewPath(r, scale)) + { + using (Brush br = + _ViewColor.BrushPart((int)eCalendarWeekDayPart.CondensedViewBackground, r)) + { + g.FillRectangle(br, r); + } + + g.FillPath(Brushes.White, path); + + DrawCondensedContent(g, r, scale); + DrawCondensedAppointments(g, scale); + + g.DrawPath(Pens.Gray, path); + } + } + + #region DrawCondensedContent + + /// + /// Draws the Condensed Content area + /// + /// + /// + /// + private void DrawCondensedContent(Graphics g, Rectangle vRect, float scale) + { + using (Pen pen = new Pen( + _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHourBorder))) + { + int selCols = _SelectedColEnd - _SelectedColStart; + + if (selCols > 0) + { + Rectangle r = vRect; + + r.X += (int)(_SelectedColStart * BaseInterval * scale); + r.Width = (int)(selCols * BaseInterval * scale); + + using (Brush br = + _ViewColor.BrushPart((int)eCalendarWeekDayPart.DayOffWorkHoursBackground, r)) + { + g.FillRectangle(br, r); + } + + g.DrawRectangle(pen, r); + } + + g.DrawLine(pen, vRect.Left, vRect.Y, vRect.Right, vRect.Y); + } + } + + #endregion + + #region GetCondensedViewPath + + /// + /// Gets the condensed view display path + /// + /// Scale factor + /// Condensed view rect + /// Path + private GraphicsPath GetCondensedViewPath(Rectangle vRect, float scale) + { + int pos = (int)(FirstVisibleColumn * BaseInterval * scale); + int width = (int)((BaseInterval * ClientRect.Width) / ColumnWidth * scale); + + Rectangle r = new + Rectangle(ClientRect.X + pos, vRect.Y, width, vRect.Height); + + r.Inflate(0, -1); + + return (DisplayHelp.GetRoundedRectanglePath(r, 2, 2, 2, 2)); + } + + #endregion + + #region DrawCondensedAppointments + + /// + /// Draws condensed appointments + /// + /// Graphics + /// Scale factor + private void DrawCondensedAppointments(Graphics g, float scale) + { + // Display each item + + SmoothingMode saveMode = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + int dy = 3; + + foreach (ColumnList clist in _CondensedColList) + { + for (int i = 0; i < clist.SList.Count; i++) + { + for (int j = 0; j < clist.SList[i].Count; j++) + { + CalendarItem item = clist.SList[i][j].CItem; + + TimeSpan ts1 = item.StartTime - StartDate; + TimeSpan ts2 = item.EndTime - item.StartTime; + + int pos = (int)(ts1.TotalMinutes * scale); + int width = (int)(ts2.TotalMinutes * scale); + + if (width < 4) + width = 4; + + Point pt1 = new Point(ClientRect.X + pos, + ClientRect.Bottom - CondensedLineHeight + (i * 3) + dy); + + Point pt2 = new Point(pt1.X + width, pt1.Y); + + using (Pen pen = GetCondensedPen(item.ModelItem)) + g.DrawLine(pen, pt1, pt2); + } + } + + dy += (clist.SList.Count * 3); + } + + g.SmoothingMode = saveMode; + } + + #region GetCondensedPen + + /// + /// Gets the appointments condensed pen + /// + /// Appointment object + /// + private Pen GetCondensedPen(object o) + { + string category = null; + + if (o is Appointment) + category = (o as Appointment).CategoryColor; + + else if (o is CustomCalendarItem) + category = (o as CustomCalendarItem).CategoryColor; + + if (category != null) + { + // Check to see if we have any user defined + // AppointmentCategoryColors + + if (CalendarView.HasCategoryColors == true) + { + AppointmentCategoryColor acc = + CalendarView.CategoryColors[category]; + + if (acc != null) + { + ColorDef cdef = acc.BackColor; + + return (new Pen(cdef.Colors[cdef.Colors.Length - 1], 2)); + } + } + + if (category.Equals(Appointment.CategoryBlue)) + return (GetCategoryPen(eAppointmentPart.BlueBackground)); + + if (category.Equals(Appointment.CategoryGreen)) + return (GetCategoryPen(eAppointmentPart.GreenBackground)); + + if (category.Equals(Appointment.CategoryOrange)) + return (GetCategoryPen(eAppointmentPart.OrangeBackground)); + + if (category.Equals(Appointment.CategoryPurple)) + return (GetCategoryPen(eAppointmentPart.PurpleBackground)); + + if (category.Equals(Appointment.CategoryRed)) + return (GetCategoryPen(eAppointmentPart.RedBackground)); + + if (category.Equals(Appointment.CategoryYellow)) + return (GetCategoryPen(eAppointmentPart.YellowBackground)); + } + + return (GetCategoryPen(eAppointmentPart.DefaultBackground)); + } + + #endregion + + #region GetCategoryPen + + /// + /// GetCategoryPen + /// + /// + /// + private Pen GetCategoryPen(eAppointmentPart part) + { + ColorDef cdef = _appointmentColor.GetColorDef((int)part); + + return (new Pen(cdef.Colors[cdef.Colors.Length - 1], 2)); + } + + #endregion + + #endregion + + #endregion + + #region DrawAppointments + + /// + /// Draws TimeLine appointments + /// + /// + private void DrawAppointments(ItemPaintArgs e) + { + List items = CalendarItems; + + if (items.Count > 0) + { + // Loop through each CalendarItem in the week + + int selItem = -1; + + for (int i = 0; i < items.Count; i++) + { + // If we can display the item, then initiate the paint + + if (items[i].Displayed == true) + { + if (e.ClipRectangle.IsEmpty || + e.ClipRectangle.IntersectsWith(items[i].DisplayRectangle)) + { + if (items[i].IsSelected == true) + selItem = i; + else + items[i].Paint(e); + } + } + } + + if (selItem >= 0) + { + for (int i = 0; i < items.Count; i++) + { + // If we can display the item, then initiate the paint + + if (items[i].Displayed == true) + { + if (e.ClipRectangle.IsEmpty || + e.ClipRectangle.IntersectsWith(items[i].DisplayRectangle)) + { + if (items[i].IsSelected == true) + items[i].Paint(e); + } + } + } + } + } + } + + #endregion + + #region GetColRange + + /// + /// Calculates the range of columns needed to be drawn + /// to satisfy the specified paint request + /// + /// ItemPaintArgs + /// [out] Column start index + /// [out] Column end index + /// Column range count (end - start) + private int GetColRange(ItemPaintArgs e, out int colStart, out int colEnd) + { + // Calc our starting index + + int start = -_HScrollPos / ColumnWidth; + int x = ClientRect.X + start * ColumnWidth + _HScrollPos; + + while (start < TimeLineColumnCount) + { + if (x + ColumnWidth > e.ClipRectangle.X) + break; + + x += ColumnWidth; + + start++; + } + + // Calc our ending index + + int end = start; + + while (end < TimeLineColumnCount) + { + if (x >= e.ClipRectangle.Right) + break; + + x += ColumnWidth; + + end++; + } + + end++; + + // Set the user supplied 'out' values, and + // return the range count to the caller + + if (end - start == 0) + { + colStart = 0; + colEnd = 0; + + return (0); + } + + colStart = start; + colEnd = end; + + return (end - start); + } + + #endregion + + #endregion + + #region GetColRect + + /// + /// Gets the display rectangle for the given column + /// + /// Column + /// Display rectangle + private Rectangle GetColRect(int col) + { + Rectangle r = ClientRect; + + r.X += ((col * ColumnWidth) + _HScrollPos); + r.Width = ColumnWidth; + + r.Height -= 1; + + if (ShowCondensed == true) + r.Height -= (CondensedLineHeight - 1); + + return (r); + } + + #endregion + + #region GetCondensedRect + + /// + /// Gets the CondensedView rectangle + /// + /// CondensedView rectangle + private Rectangle GetCondensedRect() + { + Rectangle r = ClientRect; + + r.X += 1; + r.Width -= 1; + + r.Y = r.Bottom - CondensedLineHeight; + r.Height = CondensedLineHeight - 1; + + return (r); + } + + #endregion + + #region GetDateCol + + /// + /// Gets the absolute column value for the given date + /// + /// Selection date + /// Absolute column + private int GetDateCol(DateTime? selDate) + { + if (selDate.HasValue) + { + TimeSpan ts = selDate.Value - StartDate; + + return (int)(ts.TotalMinutes / CalendarView.BaseInterval); + } + + return (0); + } + + #endregion + + #region Mouse routines + + #region MouseDown processing + + /// + /// MouseDown event processing + /// + /// + public override void InternalMouseDown(MouseEventArgs objArg) + { + // Forward on the event + + base.InternalMouseDown(objArg); + + if (objArg.Button == MouseButtons.Left) + { + if (IsTabMoving == false) + { + // Locate where the event took place + + if (ClientRect.Contains(objArg.Location) == true) + { + if (PointInCondensedView(objArg.Location) == true) + { + // User is mousing in the CondensedView area + + MyCursor = Cursors.Hand; + + ProcessCvlButtonDown(objArg); + + IsCondMoving = true; + } + else + { + int col; + + if (GetPointItem(objArg.Location, out col, true) == true) + { + // User is mouseing in the Content area + + MyCursor = GetContentCursor(); + + if (ProcessCilButtonDown(objArg) == false) + ProcessTvlButtonDown(col); + + IsMouseDown = true; + } + + IsCopyDrag = false; + } + } + } + } + } + + #region CondensedView MouseDown processing + + /// + /// Handles CondensedView Left Button Down events + /// + /// + private void ProcessCvlButtonDown(MouseEventArgs objArg) + { + ProcessCvlPoint(objArg); + } + + #region ProcessCvlPoint + + /// + /// Processes CondensedView point selection + /// + /// + private void ProcessCvlPoint(MouseEventArgs objArg) + { + TimeSpan ts0 = EndDate - StartDate; + + float scale = (float)((ClientRect.Width + 2) / ts0.TotalMinutes); + int width = (int)((BaseInterval * ClientRect.Width) / ColumnWidth * scale); + + double x = (objArg.Location.X - ClientRect.X - (width / 2)) / scale; + int col = (int)(x / BaseInterval); + + // Make sure we stay within our bounds, and + // then set our new scroll value accordingly + + HScrollBarAdv hScrollBar = CalendarView.TimeLineHScrollPanel.ScrollBar; + + if (col < hScrollBar.Minimum) + col = hScrollBar.Minimum; + + if (col > hScrollBar.Maximum - hScrollBar.LargeChange) + col = hScrollBar.Maximum - hScrollBar.LargeChange; + + hScrollBar.Value = col; + } + + #endregion + + #endregion + + #region CalendarItem MouseDown processing + + /// + /// CalendarItem left mouseDown processing + /// + /// MouseEventArgs + private bool ProcessCilButtonDown(MouseEventArgs objArg) + { + CalendarItem item = m_HotSubItem as CalendarItem; + + if (item != null) + { + if (item.HitArea != CalendarItem.eHitArea.None) + { + // Give the user a chance to cancel the + // operation before it starts + + if (CalendarView.DoBeforeAppointmentViewChange(this, item, + ((item.HitArea == CalendarItem.eHitArea.Move) ? + eViewOperation.AppointmentMove : eViewOperation.AppointmentResize)) == false) + { + _LastBounds = item.Bounds; + _LastPointOffset = objArg.Location; + _LastMovePoint = objArg.Location; + + if (IsResizing == false && IsMoving == false) + { + OldStartTime = item.StartTime; + OldEndTime = item.EndTime; + OldOwnerKey = OwnerKey; + } + + // Flag appropriate action + + if (item.HitArea == CalendarItem.eHitArea.LeftResize) + IsStartResizing = true; + + else if (item.HitArea == CalendarItem.eHitArea.RightResize) + IsEndResizing = true; + + else if (item.HitArea == CalendarItem.eHitArea.Move) + IsMoving = true; + + // Update our initial PosWin display + + UpdatePosWin(ClientRect); + } + } + + return (true); + } + + return (false); + } + + #endregion + + #region TimeLineView MouseDown processing + + /// + /// Handles TimeLineView left MouseDown events + /// + /// Column index + private void ProcessTvlButtonDown(int col) + { + DateTime startDate = CalendarView.TimeLineAddInterval(StartDate, col); + DateTime endDate = CalendarView.TimeLineAddInterval(startDate, 1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + SelectedItem = null; + } + + #endregion + + #endregion + + #region MouseUp processing + + /// + /// MouseUp event processing + /// + /// MouseEventArgs + public override void InternalMouseUp(MouseEventArgs objArg) + { + base.InternalMouseUp(objArg); + + // Cancel our scroll timer + + CancelScrollTimer(); + } + + #endregion + + #region MouseMove processing + + /// + /// MouseMove event processing + /// + /// MouseEventArgs + public override void InternalMouseMove(MouseEventArgs objArg) + { + // Forward on the event, but only if we are not in + // the middle of moving or resizing a CalendarItem + + if (Control.MouseButtons == MouseButtons.None) + ClearMouseStates(); + + if (!IsMoving && !IsStartResizing && !IsEndResizing) + base.InternalMouseMove(objArg); + + if (IsTabMoving == false) + { + if (IsCondMoving == true || PointInCondensedView(objArg.Location) == true) + { + // The user in the CondensedView area + + MyCursor = Cursors.Hand; + + if (IsCondMoving == true) + ProcessCvlMouseMove(objArg); + } + else + { + // The user in the Content area + + MyCursor = GetContentCursor(); + + if (objArg.Button == MouseButtons.Left) + ProcessContentMove(objArg); + } + } + } + + #region ProcessCvlMouseMove + + /// + /// Handles CondensedView mouse moves + /// + /// + private void ProcessCvlMouseMove(MouseEventArgs objArg) + { + ProcessCvlPoint(objArg); + } + + #endregion + + #region ProcessContentMove + + /// + /// Processes content mouse moves + /// + /// MouseEventArgs + private void ProcessContentMove(MouseEventArgs objArg) + { + // Locate where the event took place + // and process it accordingly + + int col; + + if (GetPointItem(objArg.Location, out col, false) == true) + { + // The col is visible, so no need to + // enable scrolling - just process the event + + EnableViewScrolling(false); + + ProcessMouseMove(col, objArg); + } + else if (IsMouseDown == true) + { + // Check to see if the user is performing + // a "DragDrop" operation + + if (DragDropAppointment(objArg) == false) + { + // The selected slice is not visible, + // so we need to enable scrolling + + EnableViewScrolling(true); + + // Only process the event if the user is selecting + // time cells (auto moving apps is intrusive looking) + + if (DateSelectionAnchor != null) + ProcessMouseMove(col, objArg); + } + } + } + + #region DragDropAppointment + + /// + /// Initiates a user "DragDrop" operation - if enabled + /// + /// + /// True if operation started + private bool DragDropAppointment(MouseEventArgs objArgs) + { + if (IsMoving == true && CanDrag == true) + { + Point pt = objArgs.Location; + BaseView bv = CalendarView.GetViewFromPoint(pt); + TimeLineView tlv = bv as TimeLineView; + + if (tlv != null && tlv != this) + { + eViewArea area = bv.GetViewAreaFromPoint(pt); + + if (area == eViewArea.InContent) + { + if (CalendarView.DoAppointmentViewChanging(SelectedItem, tlv.OwnerKey, SelectedItem.StartTime, + SelectedItem.EndTime, eViewOperation.AppointmentMove, IsNewCopyDrag) == false) + { + DragCopy(); + + ClearMouseStates(); + CancelScrollTimer(); + + if (PosWin != null) + PosWin.Hide(); + + AppointmentView av = SelectedItem as AppointmentView; + + if (av != null) + return (tlv.DragAppointment(this, av)); + + CustomCalendarItem ci = SelectedItem as CustomCalendarItem; + + if (ci != null) + return (tlv.DragCustomItem(this, ci)); + } + } + } + } + + return (false); + } + + #region DragCustomItem + + private bool DragCustomItem(TimeLineView pv, CustomCalendarItem ci) + { + // Set the new owner and selected view, and + // recalc the new layout + + ci.OwnerKey = OwnerKey; + + NeedRecalcLayout = true; + RecalcSize(); + + CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex; + + // Get the new view + + CustomCalendarItem view = GetCustomCalendarItem(ci); + + if (view != null) + SetNewDragItem(pv, view); + + return (true); + } + + #endregion + + #region DragAppointment + + /// + /// Drags the given appointment from one view to another + /// + /// Previous view + /// Item to drag + private bool DragAppointment(TimeLineView pv, AppointmentView av) + { + // Set the new owner and selected view, and + // recalc the new layout + + av.Appointment.OwnerKey = OwnerKey; + + NeedRecalcLayout = true; + RecalcSize(); + + CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex; + + // Get the new view + + AppointmentView view = GetAppointmentView(av.Appointment); + + if (view != null) + SetNewDragItem(pv, view); + + return (true); + } + + #endregion + + #region SetNewDragItem + + private void SetNewDragItem(TimeLineView pv, CalendarItem view) + { + _LastBounds = pv._LastBounds; + _LastMovePoint = pv._LastMovePoint; + _LastPointOffset = pv._LastPointOffset; + + int dx = _LastPointOffset.X - _LastBounds.X; + + CalendarView.CalendarPanel.InternalMouseMove(new + MouseEventArgs(MouseButtons.None, 0, view.Bounds.X + dx, view.Bounds.Y, 0)); + + MouseEventArgs args = new + MouseEventArgs(MouseButtons.Left, 1, view.Bounds.X + dx, view.Bounds.Y, 0); + + IsMoving = true; + + InternalMouseMove(args); + CalendarView.CalendarPanel.InternalMouseDown(args); + + SelectedItem = view; + + IsCopyDrag = true; + } + + #endregion + + #endregion + + #endregion + + #region GetContentCursor + /// + /// Gets the cursor + /// + /// Cursor + private Cursor GetContentCursor() + { + CalendarItem item = m_HotSubItem as CalendarItem; + + if (item != null) + { + switch (item.HitArea) + { + case CalendarItem.eHitArea.LeftResize: + case CalendarItem.eHitArea.RightResize: + return (Cursors.SizeWE); + + case CalendarItem.eHitArea.Move: + return (IsMoving ? Cursors.SizeAll : DefaultCursor); + } + } + + return (DefaultCursor); + } + + #endregion + + #region ProcessMouseMove + + /// + /// Processes user MouseMove + /// + /// DayColumn + /// + private void ProcessMouseMove(int col, MouseEventArgs objArg) + { + if (DateSelectionAnchor != null) + { + ProcessTvMouseMove(col); + } + else if (SelectedItem != null) + { + if (objArg.Location.Equals(_LastMovePoint) == false) + { + if (IsMoving == true) + ProcessItemMove(col, objArg); + + else if (IsStartResizing == true) + ProcessItemLeftResize(col, objArg); + + else if (IsEndResizing == true) + ProcessItemRightResize(col, objArg); + + _LastMovePoint = objArg.Location; + } + } + } + + #endregion + + #region ProcessTvMouseMove + + /// + /// Processes TimeLineView mouseMove events + /// + /// Column + private void ProcessTvMouseMove(int col) + { + if (DateSelectionAnchor != null) + { + DateTime date = CalendarView.TimeLineAddInterval(StartDate, col); + + // Let the user select forwards or backwards + + if (date >= DateSelectionAnchor) + { + CalendarView.DateSelectionStart = DateSelectionAnchor.Value; + CalendarView.DateSelectionEnd = CalendarView.TimeLineAddInterval(date, 1); + } + else + { + CalendarView.DateSelectionStart = date; + CalendarView.DateSelectionEnd = CalendarView.TimeLineAddInterval(DateSelectionAnchor.Value, 1); + } + } + } + + #endregion + + #region CalendarItem MouseMove processing + + /// + /// Processes CalendarItem mouseMove events + /// + /// Column + /// MouseEventArgs + private void ProcessItemMove(int col, MouseEventArgs objArg) + { + // Calculate our new item date + + DateTime newDate; + + if (CalendarView.TimeLinePeriod == eTimeLinePeriod.Years) + { + newDate = StartDate.AddYears( + GetDeltaYears(col, true, objArg)); + } + else + { + newDate = StartDate.AddMinutes( + GetDeltaMinutes(col, true, objArg)); + } + + if (newDate != SelectedItem.StartTime) + { + if (DragCopy() == false) + { + TimeSpan ts = SelectedItem.EndTime - SelectedItem.StartTime; + + try + { + if (SelectedItem is CustomCalendarItem) + CalendarView.CustomItems.BeginUpdate(); + else + CalendarModel.BeginUpdate(); + + // Make the move + + if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, newDate, + newDate + ts, eViewOperation.AppointmentMove, IsNewCopyDrag) == false) + { + SelectedItem.StartTime = newDate; + SelectedItem.EndTime = newDate + ts; + + NeedRecalcLayout = true; + } + } + finally + { + if (SelectedItem is CustomCalendarItem) + CalendarView.CustomItems.EndUpdate(); + else + CalendarModel.EndUpdate(); + } + } + } + } + + #endregion + + #region CalendarItem MouseResize processing + + /// + /// Processes CalendarItem left resizing + /// + /// Column + /// + private void ProcessItemLeftResize(int col, MouseEventArgs objArg) + { + DateTime date = (CalendarView.TimeLinePeriod == eTimeLinePeriod.Years) ? + StartDate.AddYears(GetDeltaYears(col, true, objArg)) : + StartDate.AddMinutes(GetDeltaMinutes(col, true, objArg)); + + if (date < SelectedItem.EndTime && SelectedItem.StartTime != date) + ResizeItem(date, SelectedItem.EndTime); + } + + /// + /// Processes CalendarItem right resizing + /// + /// Column + /// + private void ProcessItemRightResize(int col, MouseEventArgs objArg) + { + DateTime date = (CalendarView.TimeLinePeriod == eTimeLinePeriod.Years) ? + StartDate.AddYears(GetDeltaYears(col, false, objArg)) : + StartDate.AddMinutes(GetDeltaMinutes(col, false, objArg)); + + if (date > SelectedItem.StartTime && SelectedItem.EndTime != date) + ResizeItem(SelectedItem.StartTime, date); + } + + /// + /// Initiates the resize of the selected item + /// + /// + /// + private void ResizeItem(DateTime startTime, DateTime endTime) + { + // Let the user cancel the operation if desired + + if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, startTime, + endTime, eViewOperation.AppointmentResize, IsNewCopyDrag) == false) + { + SelectedItem.StartTime = startTime; + SelectedItem.EndTime = endTime; + + NeedRecalcLayout = true; + } + } + + #endregion + + #region GetDeltaMinutes + + /// + /// Gets the change from the last offset (in minutes) + /// + /// Column + /// Are we going left or right + /// MouseEventArgs + /// Change in mnutes + private double GetDeltaMinutes(int col, bool left, MouseEventArgs objArg) + { + // Calculate our delta minutes + + Rectangle r = GetColRect(col); + + double dm = (objArg.Location.X - _LastPointOffset.X); + + dm += left ? _LastBounds.Left - r.Left + : _LastBounds.Right - r.Right; + + dm = BaseInterval * dm / ColumnWidth; + + // If the Alt key is not pressed, then round + // our value off to the nearest column + + if ((Control.ModifierKeys & Keys.Alt) != Keys.Alt) + { + col += (int)(dm / BaseInterval); + dm = 0; + } + + dm += (col * BaseInterval); + + // Make sure we don't cross our day boundaries + + if (left == true) + { + if (dm < 0) + dm = 0; + } + else + { + dm += BaseInterval; + } + + return (dm); + } + + #endregion + + #region GetDeltaYears + + /// + /// Gets the change from the last offset (in years) + /// + /// Column + /// Are we going left or right + /// MouseEventArgs + /// Change in years + private int GetDeltaYears(int col, bool left, MouseEventArgs objArg) + { + // Calculate our delta minutes + + Rectangle r = GetColRect(col); + + int dm = (objArg.Location.X - _LastPointOffset.X); + + dm += left ? _LastBounds.Left - r.Left + : _LastBounds.Right - r.Right; + + dm = CalendarView.TimeLineInterval * dm / ColumnWidth; + + // If the Alt key is not pressed, then round + // our value off to the nearest column + + if ((Control.ModifierKeys & Keys.Alt) != Keys.Alt) + { + col += dm / CalendarView.TimeLineInterval; + dm = 0; + } + + dm += (col * CalendarView.TimeLineInterval); + + // Make sure we don't cross our day boundaries + + if (left == true) + { + if (dm < 0) + dm = 0; + } + else + { + dm += CalendarView.TimeLineInterval; + } + + return (dm); + } + + #endregion + + #region View Scrolling support + + /// + /// Routine to enable or disable view scrolling + /// + /// true to enable + private void EnableViewScrolling(bool enable) + { + if (enable == true) + { + if (_ScrollViewTimer == null) + { + _ScrollViewTimer = new Timer(); + + _ScrollViewTimer.Interval = 10; + _ScrollViewTimer.Tick += ScrollViewTimerTick; + _ScrollViewTimer.Start(); + } + + _ScrollDwell = 0; + } + else + { + CancelScrollTimer(); + } + } + + /// + /// Cancels the view scroll timer + /// + private void CancelScrollTimer() + { + // Dispose of our scroll timer + + if (_ScrollViewTimer != null) + { + _ScrollViewTimer.Stop(); + _ScrollViewTimer.Tick -= ScrollViewTimerTick; + + _ScrollViewTimer = null; + } + } + + /// + /// Determines the amount to scroll (which is + /// based loosely upon the delta magnitude) + /// + /// Point delta + /// Scroll amount + private int ScrollAmount(int delta) + { + _ScrollDwell++; + + int dx = Math.Abs(delta); + int n = (dx < 16 ? 8 : dx < 32 ? 4 : 1); + + if (_ScrollDwell % n == 0) + return (delta < 0 ? -1 : 1); + + return (0); + } + + /// + /// Handles view scroll timer ticks + /// + /// object + /// EventArgs + void ScrollViewTimerTick(object sender, EventArgs e) + { + Control c = (Control)this.GetContainerControl(true); + + if (c != null) + { + // Calculate our delta + + Point pt = c.PointToClient(Cursor.Position); + Rectangle r = ClientRect; + + int n = r.X + (ClientRect.Width / ColumnWidth) * ColumnWidth; + + int dx = (pt.X < r.Left) ? ScrollAmount(pt.X - r.Left) : + (pt.X >= n) ? ScrollAmount(pt.X - n) : 0; + + // Make sure we stay within our upper bounds + + if (dx < 0) + { + if (CalendarView.TimeLineHScrollPanel.ScrollBar.Value + dx < 0) + dx = -CalendarView.TimeLineHScrollPanel.ScrollBar.Value; + } + else + { + int maxValue = CalendarView.TimeLineHScrollPanel.ScrollBar.Maximum - + CalendarView.TimeLineHScrollPanel.ScrollBar.LargeChange; + + if (CalendarView.TimeLineHScrollPanel.ScrollBar.Value + dx > maxValue) + dx = maxValue - CalendarView.TimeLineHScrollPanel.ScrollBar.Value; + } + + // Scroll if necessary + + if (dx != 0) + { + CalendarView.TimeLineHScrollPanel.ScrollBar.Value += dx; + + if (PosWin != null) + PosWin.Hide(); + + InternalMouseMove(new + MouseEventArgs(MouseButtons.Left, 0, pt.X, pt.Y, 0)); + } + } + } + + #endregion + + #endregion + + #region GetPointItem + + /// + /// Gets the item column at the given point + /// + /// Point in question + /// [out] Column + /// True if partial hits are ok + /// True if valid item + private bool GetPointItem(Point pt, out int col, bool partial) + { + int start = -_HScrollPos / ColumnWidth; + int end = start + ClientRect.Width / ColumnWidth; + + Rectangle r = GetColRect(start); + + for (int i = start; i <= end; i++) + { + if (r.Contains(pt) == true) + { + col = i; + + return (IsColVisible(r, partial)); + } + + r.X += ColumnWidth; + } + + col = (pt.X < ClientRect.X) ? 0 : TimeLineColumnCount; + + return (false); + } + + /// + /// Determines if a given column is visible + /// + /// Display rectangle + /// True if partial visibility is ok + /// True if visible + private bool IsColVisible(Rectangle r, bool partial) + { + if (partial == true) + { + if (r.Right < ClientRect.Left) + return (false); + + if (r.Left > ClientRect.Right) + return (false); + } + else + { + if (r.Left < ClientRect.Left) + return (false); + + if (r.Right > ClientRect.Right) + return (false); + } + + return (true); + } + + #endregion + + #region PointInCondensedView + + /// + /// Determines if the given point in in + /// the CondensedView area + /// + /// + /// + private bool PointInCondensedView(Point pt) + { + if (ShowCondensed == true) + return (GetCondensedRect().Contains(pt)); + + return (false); + } + + #endregion + + #endregion + + #region InternalKeyDown + + #region InternalKeyDown + + /// + /// Processes KeyDown events + /// + /// + public override void InternalKeyDown(KeyEventArgs objArg) + { + switch (objArg.KeyData) + { + case Keys.Up: + case Keys.Up | Keys.Shift: + case Keys.Up | Keys.Control: + case Keys.Up | Keys.Control | Keys.Shift: + objArg.Handled = true; + break; + + case Keys.Down: + case Keys.Down | Keys.Shift: + case Keys.Down | Keys.Control: + case Keys.Down | Keys.Control | Keys.Shift: + objArg.Handled = true; + break; + + case Keys.Left: + case Keys.Left | Keys.Shift: + case Keys.Left | Keys.Control: + case Keys.Left | Keys.Control | Keys.Shift: + ProcessLeftRightKey(objArg, -1); + break; + + case Keys.Right: + case Keys.Right | Keys.Shift: + case Keys.Right | Keys.Control: + case Keys.Right | Keys.Control | Keys.Shift: + ProcessLeftRightKey(objArg, 1); + break; + + case Keys.Home: + case Keys.Home | Keys.Shift: + case Keys.Home | Keys.Control: + case Keys.Home | Keys.Control | Keys.Shift: + ProcessHomeKey(objArg); + break; + + case Keys.End: + case Keys.End | Keys.Shift: + case Keys.End | Keys.Control: + case Keys.End | Keys.Control | Keys.Shift: + ProcessEndKey(objArg); + break; + } + } + + #endregion + + #region ProcessLeftRightKey + + /// + /// Processes Left and Right Key events + /// + /// + /// + protected virtual void ProcessLeftRightKey(KeyEventArgs objArg, int dx) + { + if (ValidDateSelection()) + { +// ReSharper disable PossibleInvalidOperationException + + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + if (startDate.Equals(DateSelectionAnchor.Value) == true) + startDate = CalendarView.TimeLineAddInterval(endDate, -1); + +// ReSharper restore PossibleInvalidOperationException + + startDate = CalendarView.TimeLineAddInterval(startDate, dx); + endDate = CalendarView.TimeLineAddInterval(startDate, 1); + + DateTime viewStart = CalendarView.TimeLineViewScrollStartDate; + DateTime viewEnd = CalendarView.TimeLineViewScrollEndDate; + + if (startDate < viewStart) + { + CalendarView.TimeLineViewScrollStartDate = startDate; + } + else if (endDate > viewEnd) + { + CalendarView.TimeLineViewScrollStartDate = + CalendarView.TimeLineAddInterval(CalendarView.TimeLineViewScrollStartDate, 1); + } + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessHomeKey + + /// + /// Handles Home key events + /// + /// + protected virtual void ProcessHomeKey(KeyEventArgs objArg) + { + DateTime startDate = CalendarView.TimeLineViewScrollStartDate; + DateTime endDate = CalendarView.TimeLineAddInterval(startDate, 1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + SelectedItem = null; + + objArg.Handled = true; + } + + #endregion + + #region ProcessEndKey + + /// + /// Processes End key events + /// + /// + protected virtual void ProcessEndKey(KeyEventArgs objArg) + { + DateTime endDate = CalendarView.TimeLineViewScrollEndDate; + DateTime startDate = CalendarView.TimeLineAddInterval(endDate, -1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + SelectedItem = null; + + objArg.Handled = true; + } + + #endregion + + #endregion + + #region IDisposable Members + + protected override void Dispose(bool disposing) + { + if (disposing == true && IsDisposed == false) + { + ResetView(); + + WorkBrush = null; + OffWorkBrush = null; + SelectedBrush = null; + + HookEvents(false); + } + + base.Dispose(disposing); + } + + #endregion + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/VScrollPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/VScrollPanel.cs new file mode 100644 index 00000000..9c3b32d5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/VScrollPanel.cs @@ -0,0 +1,237 @@ +#if FRAMEWORK20 +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Schedule +{ + public class VScrollPanel : BaseItem + { + #region Events + public event EventHandler ScrollBarChanged; + #endregion + + #region Variables + + protected CalendarView CalendarView; // CalendarView + private VScrollBarAdv _ScrollBar; // Scroll bar + + #endregion + + /// + /// Constructor + /// + /// + public VScrollPanel(CalendarView calendarView) + { + CalendarView = calendarView; + + SetUpScrollBar(); + } + + #region Public properties + + /// + /// Gets and sets the panel Bounds + /// + public override Rectangle Bounds + { + get { return (base.Bounds); } + + set + { + base.Bounds = value; + + UpdateScrollBar(); + } + } + + /// + /// Gets and sets the control visibility + /// + public override bool Visible + { + get { return (base.Visible); } + + set + { + if (base.Visible != value) + { + base.Visible = value; + + ScrollBar.Visible = value; + + if (value == true) + ScrollBar.BringToFront(); + } + } + } + + /// + /// Gets the scrollBar + /// + public VScrollBarAdv ScrollBar + { + get { return (_ScrollBar); } + } + + #endregion + + #region Private properties + + /// + /// Gets the scrollBar SmallChange value + /// + protected virtual int ScrollPanelSmallChange + { + get { return (1); } + } + + /// + /// Gets the scrollBar Maximum value + /// + protected virtual int ScrollPanelMaximum + { + get { return (100); } + } + + #endregion + + #region SetupScrollBar + + /// + /// Performs scrollBar setup + /// + private void SetUpScrollBar() + { + _ScrollBar = new VScrollBarAdv(); + + Control c = (Control)CalendarView.CalendarPanel.GetContainerControl(true); + + if (c != null) + c.Controls.Add(_ScrollBar); + + _ScrollBar.ValueChanged += ValueChanged; + + UpdateScrollBar(); + } + + #endregion + + #region UpdateScrollBar + + /// + /// Updates our scrollbar + /// + internal void UpdateScrollBar() + { + _ScrollBar.Location = Bounds.Location; + _ScrollBar.Height = Bounds.Height; + _ScrollBar.Width = Bounds.Width; + + _ScrollBar.LargeChange = Bounds.Height; + _ScrollBar.SmallChange = 1; + _ScrollBar.SmallChange = ScrollPanelSmallChange; + _ScrollBar.Maximum = ScrollPanelMaximum; + + int n = _ScrollBar.Maximum - _ScrollBar.LargeChange + 1; + + if (n < 0) + { + _ScrollBar.Maximum = Bounds.Height; + _ScrollBar.Value = 0; + + _ScrollBar.Enabled = false; + } + else + { + _ScrollBar.Enabled = true; + + if (_ScrollBar.Value > n) + _ScrollBar.Value = n; + else + Refresh(); + } + + OnScrollBarUpdate(); + } + + #endregion + + #region DisableScrollBar + + /// + /// Disables the scrollbar + /// + internal void DisableScrollBar() + { + _ScrollBar.Location = Bounds.Location; + _ScrollBar.Height = Bounds.Height; + + _ScrollBar.LargeChange = Bounds.Height; + _ScrollBar.SmallChange = 1; + _ScrollBar.SmallChange = ScrollPanelSmallChange; + _ScrollBar.Maximum = Bounds.Height; + + _ScrollBar.Value = 0; + _ScrollBar.Enabled = false; + + OnScrollBarUpdate(); + } + + #endregion + + #region ValueChanged + + /// object + /// EventArgs + void ValueChanged(object sender, EventArgs e) + { + OnScrollBarUpdate(); + } + + /// + /// Passes the scroll onto others + /// + private void OnScrollBarUpdate() + { + if (ScrollBarChanged != null) + ScrollBarChanged(this, EventArgs.Empty); + } + + #endregion + + #region IDisposable Members + + protected override void Dispose(bool disposing) + { + if (_ScrollBar != null) + { + _ScrollBar.ValueChanged -= ValueChanged; + _ScrollBar.Dispose(); + } + + base.Dispose(disposing); + } + + #endregion + + #region Paint + + public override void Paint(ItemPaintArgs p) + { + } + + #endregion + + #region Copy + + public override BaseItem Copy() + { + return (null); + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/AllDayPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/AllDayPanel.cs new file mode 100644 index 00000000..e23b7f5c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/AllDayPanel.cs @@ -0,0 +1,613 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Schedule +{ + public class AllDayPanel : BaseItem + { + #region Private variables + + private WeekDayView _WeekDayView; // Assoc WeekDayView + + private List // CalendarItems list + _CalendarItems = new List(); + + private VScrollBarAdv _VScrollBar; // Vertical scroll bar + private int _VScrollPos; // Vertical scrollbar pos + + private int _PanelHeight; // Panel height (current) + private int _MaximumPanelHeight; // Panel height (max) + + #endregion + + /// + /// Constructor + /// + /// WeekDayView + public AllDayPanel(WeekDayView weekDayView) + { + // Save the provided weekDayView and + // tell the system we are a container + + _WeekDayView = weekDayView; + + SetIsContainer(true); + + SubItems.AllowParentRemove = false; + } + + #region Public properties + + /// + /// Gets and sets the panel bounding rectangle + /// + public override Rectangle Bounds + { + get { return (base.Bounds); } + + set + { + base.Bounds = value; + + UpdateVScrollBar(); + } + } + + /// + /// Gets the DayPanel Height + /// + public int PanelHeight + { + get { return (_PanelHeight); } + } + + /// + /// Gets the panel's CalendarItem list + /// + public List CalendarItems + { + get { return (_CalendarItems); } + } + + /// + /// Gets WeekDayView + /// + public WeekDayView WeekDayView + { + get { return (_WeekDayView); } + } + + #endregion + + #region Private properties + + /// + /// gets the Fixed AllDayPanel height + /// + private int FixedAllDayPanelHeight + { + get { return (_WeekDayView.CalendarView.FixedAllDayPanelHeight); } + } + + /// + /// gets the Maximum AllDayPanel height + /// + private int MaximumAllDayPanelHeight + { + get { return (_WeekDayView.CalendarView.MaximumAllDayPanelHeight); } + } + + /// + /// Gets the Appointment height + /// + private int AppointmentPadding + { + get { return (6); } + } + + /// + /// Gets the width of a vertical scrollbar + /// + private int VsWidth + { + get { return (SystemInformation.VerticalScrollBarWidth); } + } + + #endregion + + #region RecalcSize + + /// + /// Performs panel recalc support + /// + public override void RecalcSize() + { + // Reset our panel heights + + _PanelHeight = 0; + _MaximumPanelHeight = 0; + + if (_CalendarItems.Count > 0) + { + // Sort the items + + List items = SortCalendarItems(); + + // Go through our CalendarItems on a per column basis + // accumulating extended appointment data + + ulong[] acc = new ulong[DaysInWeek]; + + int maxAcc = -1; + + for (int i = 0; i < items.Count; i++) + { + int freeAcc = CalcAppointmentBounds(items[i], acc); + + if (freeAcc > maxAcc) + maxAcc = freeAcc; + } + + // Determine our current panel height from our processed data + + if (_WeekDayView.CalendarView.IsMultiCalendar == false) + { + _MaximumPanelHeight = (maxAcc + 1) * _WeekDayView.AppointmentHeight; + + // Set out current and maximum panel heights + + _MaximumPanelHeight += AppointmentPadding; + _PanelHeight = _MaximumPanelHeight; + + if (_PanelHeight > MaximumAllDayPanelHeight) + _PanelHeight = MaximumAllDayPanelHeight; + } + } + + // Take into account the FixedAllDayPanelHeight setting + + if (_WeekDayView.CalendarView.IsMultiCalendar == true) + { + _PanelHeight = (FixedAllDayPanelHeight >= 0) ? FixedAllDayPanelHeight : 50; + _MaximumPanelHeight = _PanelHeight; + } + else if (FixedAllDayPanelHeight >= 0) + { + _PanelHeight = FixedAllDayPanelHeight; + } + + HeightInternal = _PanelHeight; + + base.RecalcSize(); + } + + #region SortCalendarItems + + /// + /// Sorts the CalendarItems + /// + private List SortCalendarItems() + { + List items = + new List(_CalendarItems.Count); + + items.AddRange(_CalendarItems); + + items.Sort( + + delegate(CalendarItem c1, CalendarItem c2) + { + if (c1.StartTime > c2.StartTime) + return (1); + + if (c1.StartTime < c2.StartTime) + return (-1); + + if (c1.EndTime > c2.EndTime) + return (-1); + + if (c1.EndTime < c2.EndTime) + return (1); + + return (0); + } + ); + + return (items); + } + + #endregion + + #region CalcAppointmentBounds + + const int DaysInWeek = 7; + + /// + /// Calculates the display bounds for the AppointmentView + /// + /// CalendarItem + /// Row accumulator + private int CalcAppointmentBounds(CalendarItem item, ulong[] acc) + { + // Determine the starting day index for + // the given appointment + + int ns = GetDayIndex(item); + + // Calculate the top and height for the item + + Rectangle r = _WeekDayView.DayColumns[ns].Bounds; + + r.Width = 0; + + r.Y = _WeekDayView.ClientRect.Y + _WeekDayView.DayOfWeekHeaderHeight + _VScrollPos + 2; + r.Height = _WeekDayView.AppointmentHeight; + + int maxAcc = -1; + + // Determine the ending day index + + DateTime st = _WeekDayView.DayColumns[ns].Date; + + int ne = ns + (item.EndTime - st).Days; + + if (item.EndTime.Hour > 0 || item.EndTime.Minute > 0 || item.EndTime.Second > 0) + ne++; + + if (ne > DaysInWeek) + ne = DaysInWeek; + + int freeAcc = GetFreeAcc(ns, ne, acc); + + if (freeAcc >= 0) + { + ulong u = (1ul << freeAcc); + + for (int i = ns; i < ne; i++) + { + if (i < _WeekDayView.NumberOfColumns) + r.Width += _WeekDayView.DayColumns[i].Bounds.Width; + + acc[i] |= u; + } + + r.Y += (freeAcc * _WeekDayView.AppointmentHeight); + + if (freeAcc > maxAcc) + maxAcc = freeAcc; + } + else + { + r.Y = _WeekDayView.DayColumns[0].Bounds.Bottom; + } + + DateTime start = _WeekDayView.DayColumns[0].Date; + DateTime end = _WeekDayView.DayColumns[_WeekDayView.DayColumns.Length - 1].Date; + + // Check to see if we can only display + // a partial representation for the view + + if (item.EndTime >= start && item.StartTime < end) + { + int hpad = 4; + + if (item.StartTime >= start) + { + r.X += hpad; + r.Width -= hpad; + } + + if (item.EndTime <= end) + r.Width -= hpad; + } + + // Now that we have calculated the items height and + // width, invoke a Recalc on the item + + item.WidthInternal = r.Width; + item.HeightInternal = r.Height - 1; + + item.RecalcSize(); + + // Set our bounds for the item + + r.Width = item.WidthInternal; + r.Height = item.HeightInternal; + + item.Bounds = r; + + // Set it's display state + + item.Displayed = true; + + return (maxAcc); + } + + #region GetFreeAcc + + private int GetFreeAcc(int ns, int ne, ulong[] acc) + { + for (int i = 0; i < sizeof(ulong) * 8; i++) + { + if (CheckFreeAcc(ns, ne, acc, i) == true) + return (i); + } + + return (-1); + } + + #region CheckFreeAcc + + private bool CheckFreeAcc(int ns, int ne, ulong[] acc, int n) + { + for (int i = ns; i < ne; i++) + { + ulong u = acc[i]; + + if ((u & (1ul << n)) != 0) + return (false); + } + + return (true); + } + + #endregion + + #endregion + + #region GetDayIndex + + /// + /// Gets the starting day index for the given appointment + /// + /// Day of week index (0-6) + private int GetDayIndex(CalendarItem item) + { + DateTime date = _WeekDayView.DayColumns[0].Date; + + for (int i = 0; i < _WeekDayView.DayColumns.Length; i++) + { + date = date.AddDays(1); + + if (date > item.StartTime) + return (i); + } + + return (0); + } + + #endregion + + #endregion + + #endregion + + #region Scrollbar routines + + #region UpdateVScrollBar + + /// + /// Updates our vertical scrollbar + /// + private void UpdateVScrollBar() + { + if (_PanelHeight > 0 && _PanelHeight < _MaximumPanelHeight) + { + // If we don't have one already, allocate it + + if (_VScrollBar == null) + { + _VScrollBar = new VScrollBarAdv(); + _VScrollBar.Width = VsWidth; + + Control c = (Control)this.GetContainerControl(true); + + if (c != null) + c.Controls.Add(_VScrollBar); + + _VScrollBar.ValueChanged += _VExtScrollBar_ValueChanged; + } + + // Initialize the scrollbar + + _VScrollBar.Location = new Point(Bounds.Right + 1, Bounds.Y); + _VScrollBar.Height = _PanelHeight; + + _VScrollBar.SmallChange = _PanelHeight / 2; + _VScrollBar.LargeChange = _WeekDayView.AppointmentHeight * 2; + + _VScrollBar.Maximum = _MaximumPanelHeight - + _VScrollBar.Height + _VScrollBar.LargeChange; + + if (_VScrollBar.Visible == false) + { + _VScrollPos = 0; + _VScrollBar.Value = 0; + + _VScrollBar.Show(); + _VScrollBar.BringToFront(); + } + else + { + if (_VScrollBar.Value > _VScrollBar.Maximum - _VScrollBar.LargeChange) + _VScrollBar.Value = _VScrollBar.Maximum - _VScrollBar.LargeChange; + } + + _VScrollBar.Refresh(); + } + else if (_VScrollBar != null) + { + _VScrollPos = 0; + + _VScrollBar.ValueChanged -= _VExtScrollBar_ValueChanged; + + _VScrollBar.Dispose(); + _VScrollBar = null; + } + } + + #endregion + + #region _VExtScrollBar_ValueChanged + + /// + /// Processes Extended appointments scrollBar changes + /// + /// object + /// EventArgs + void _VExtScrollBar_ValueChanged(object sender, EventArgs e) + { + int vdelta = -_VScrollBar.Value - _VScrollPos; + + if (vdelta != 0) + { + _VScrollPos = -_VScrollBar.Value; + + // Now that we have calculated the items height and + // width, invoke a Recalc on the item + + for (int i = 0; i < _CalendarItems.Count; i++) + { + CalendarItem item = _CalendarItems[i]; + + Rectangle r = item.Bounds; + r.Y += vdelta; + + item.Bounds = r; + } + + Refresh(); + } + } + + #endregion + + #endregion + + #region Reset / update view + + /// + /// Resets the AllDayPanel view + /// + public void ResetView() + { + _VScrollPos = 0; + + if (_VScrollBar != null) + { + _VScrollBar.ValueChanged -= _VExtScrollBar_ValueChanged; + _VScrollBar.Dispose(); + _VScrollBar = null; + } + } + + /// + /// Updates the AllDayPanel view + /// + public void UpdateView() + { + if (_WeekDayView.IsViewSelected == true) + { + if (_VScrollBar != null) + _VScrollBar.Show(); + } + else + { + if (_VScrollBar != null) + _VScrollBar.Hide(); + } + } + + #endregion + + #region Paint processing + + /// + /// Draws extended appointments + /// + /// ItemPaintArgs + public override void Paint(ItemPaintArgs e) + { + Graphics g = e.Graphics; + + if (e.ClipRectangle.IntersectsWith(Bounds)) + { + Region regSave = g.Clip; + g.SetClip(Bounds, CombineMode.Intersect); + + using (Brush br = + _WeekDayView.WeekDayColor.BrushPart( + (int) eCalendarWeekDayPart.DayAllDayEventBackground, Bounds)) + { + g.FillRectangle(br, Bounds); + } + + using (Pen pen = new Pen( + _WeekDayView.WeekDayColor.GetColor((int) eCalendarWeekDayPart.DayViewBorder))) + { + g.DrawLine(pen, Bounds.X, Bounds.Y, Bounds.X, Bounds.Bottom); + g.DrawLine(pen, Bounds.Right - 1, Bounds.Y, Bounds.Right - 1, Bounds.Bottom); + } + + // Loop through each day in each week, displaying + // the associated day content + + int selItem = -1; + + for (int i = 0; i < _CalendarItems.Count; i++) + { + // Initiate the paint + + if (_CalendarItems[i].Displayed == true) + { + if (_CalendarItems[i].IsSelected == true) + selItem = i; + else + _CalendarItems[i].Paint(e); + } + } + + if (selItem >= 0) + _CalendarItems[selItem].Paint(e); + + // Restore the original clip region + + g.Clip = regSave; + } + } + + #endregion + + #region Copy implementation + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + AllDayPanel objCopy = new AllDayPanel(WeekDayView); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the AllDayPanel specific properties to new instance of the item. + /// + /// New AllDayPanel instance + protected override void CopyToItem(BaseItem copy) + { + AllDayPanel objCopy = copy as AllDayPanel; + base.CopyToItem(objCopy); + } + + #endregion + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/ColumnList.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/ColumnList.cs new file mode 100644 index 00000000..167cb6c1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/ColumnList.cs @@ -0,0 +1,319 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class ColumnList + { + #region Private variables + + private List> _SList = new List>(); + private int _Id; + + #endregion + + public ColumnList() + { + } + + public ColumnList(int id) + { + _Id = id; + } + + #region Public properties + + /// + /// Gets the column slot Id + /// + public int Id + { + get { return (_Id); } + set { _Id = value; } + } + + /// + /// Gets the column slot list + /// + public List> SList + { + get { return (_SList); } + } + + #endregion + + #region Public methods + + #region AddColumnSlot + + /// + /// Adds a CalendarItem to the running slot list + /// + /// CalendarItem to add + /// Slot level to add the item to + /// The added slot item + public SlotItem AddColumnSlot(CalendarItem item, int n) + { + // Add a new SlotItem list if we have exceeded + // the current list count + + if (n >= _SList.Count) + _SList.Add(new List()); + + // Determine whether this item can fit in the + // the slot list at the current level + + SlotItem si = GetColumnSlot(item, n); + + if (si != null) + { + // The item won't fit, so allocate a new slot + // item and add it to the list + + si.AddPeerSlot( + AddColumnSlot(item, n + 1), n + 1); + } + else + { + // The item will fit, so add it to the list + + si = new SlotItem(item); + + _SList[n].Add(si); + + // Look ahead to see it we have a peer slot + // in a future slot list + + while (n + 1 < _SList.Count) + { + n++; + + SlotItem ni = GetColumnSlot(item, n); + + if (ni != null) + { + si.AddPeerSlot(ni, n); + break; + } + } + } + + // Return the added slot item + + return (si); + } + + /// + /// Returns the SlotItem (if present) in the given list for + /// the CalendarItem in question + /// + /// CalendarItem + /// Slot level to scan + /// SlotItem, if found + private SlotItem GetColumnSlot(CalendarItem item, int n) + { + if (n < _SList.Count) + { + // Loop through each SlotItem at the given + // level, looking for an intersection with the + // given CalendarItem + + List list = _SList[n]; + + for (int i = 0; i < list.Count; i++) + { + SlotItem si = list[i]; + + DateTime start = item.StartTime > si.CItem.StartTime ? item.StartTime : si.CItem.StartTime; + DateTime end = item.EndTime < si.CItem.EndTime ? item.EndTime : si.CItem.EndTime; + + // If we found an item, return it + + if ((start < end) || + (start <= end && ( item.StartTime == item.EndTime || si.CItem.StartTime == si.CItem.EndTime))) + return (si); + } + } + + // Nothing currently at that slot + + return (null); + } + + #endregion + + #region CountColumns + + /// + /// Counts the number of columns for + /// each column zero entry slot lists + /// + public void CountColumns() + { + if (_SList.Count > 0) + { + for (int i = 0; i < _SList[0].Count; i++) + { + SlotItem si = _SList[0][i]; + + SetColumnCount(si, GetColumnCount(si, 1)); + } + } + } + + /// + /// Gets the max column count from all + /// zero level slot paths + /// + /// Initial SlotItem + /// Running level count + /// + private int GetColumnCount(SlotItem si, int count) + { + if (si.Count > 0) + return (si.Count); + + int maxCount = count; + + if (si.SList != null) + { + for (int i = 0; i < si.SList.Count; i++) + { + int c = GetColumnCount(si.SList[i], count + 1); + + if (c > maxCount) + maxCount = c; + } + } + + return (maxCount); + } + + /// + /// Sets all column entry counts to the given + /// count + /// + /// Initial SlotItem + /// Count + private void SetColumnCount(SlotItem si, int count) + { + if (si.SList != null) + { + for (int i = 0; i < si.SList.Count; i++) + SetColumnCount(si.SList[i], count); + } + + if (si.Count == 0) + si.Count = count; + } + + #endregion + + #region Clear + + /// + /// Clears the Column slot list + /// + public void Clear() + { + _SList.Clear(); + } + + #endregion + + #endregion + } + + #region SlotItem class definition + + public class SlotItem + { + #region Private variables + + private CalendarItem _CItem; // CalendarItem + private List _SList; // List of peer SlotItems + private int _Count; // Count of peer items + private int _Column; + + #endregion + + /// + /// Constructor + /// + /// CalendarItem + public SlotItem(CalendarItem cItem) + { + _CItem = cItem; + } + + #region Public properties + + /// + /// Gets and sets the slots CalendarItem + /// + public CalendarItem CItem + { + get { return (_CItem); } + set { _CItem = value; } + } + + /// + /// Gets the peer SlotItem list + /// + public List SList + { + get { return (_SList); } + } + + /// + /// Gets and sets the peer level count + /// + public int Count + { + get { return (_Count); } + set { _Count = value; } + } + + /// + /// Gets and sets the peer column + /// + public int Column + { + get { return (_Column); } + set { _Column = value; } + } + + #endregion + + #region Public methods + + /// + /// Adds a slot to the peer SlotItem list + /// + /// SlotItem to add + /// Slot column + public void AddPeerSlot(SlotItem si, int column) + { + if (si != null) + { + if (_SList == null) + _SList = new List(); + + if (_SList.Contains(si) == false) + { + si.Column = column; + + _SList.Add(si); + } + } + } + + #endregion + } + + #endregion +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/DayColumn.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/DayColumn.cs new file mode 100644 index 00000000..9754df62 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/DayColumn.cs @@ -0,0 +1,212 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Drawing; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class DayColumn + { + #region Consts + + public const int NumberOfTimeSlices = 48; + + #endregion + + #region Private variables + + private Rectangle _Bounds; // Slot bounding rectangle + + private DateTime _Date; // Column date + + private float _TimeSliceHeight; // TimeSlice height + + private WorkTime _BusyStartTime; // Busy time + private WorkTime _BusyEndTime; + + private WorkTime _WorkStartTime; // Work time + private WorkTime _WorkEndTime; + + private List // Column CalendarItems + _CalendarItems = new List(); + + private bool _NeedRecalcLayout = true; + + #endregion + + /// + /// Constructor + /// + /// Slice height + public DayColumn(float timeSliceHeight) + { + _TimeSliceHeight = timeSliceHeight; + } + + #region Public properties + + #region BoundingRect + + /// + /// Gets and sets the week bounding Rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + + set + { + if (_Bounds.Equals(value) == false) + { + int yOffset = value.Y - _Bounds.Y; + + _Bounds = value; + + if (yOffset != 0) + OffsetItemRects(yOffset); + } + } + } + + /// + /// Offsets the bounding rectangles for the + /// DayColumn's non-extended appointments + /// + /// Amount to offset + private void OffsetItemRects(int yOffset) + { + for (int i = 0; i < _CalendarItems.Count; i++) + { + Rectangle r = _CalendarItems[i].Bounds; + + r.Y += yOffset; + + _CalendarItems[i].Bounds = r; + } + } + + #endregion + + #region Date + + /// + /// Gets and sets the column date + /// + public DateTime Date + { + get { return (_Date); } + set { _Date = value; } + } + + #endregion + + #region TimeSliceHeight + + /// + /// Gets and sets the TimeSlice height + /// + public float TimeSliceHeight + { + get { return (_TimeSliceHeight); } + set { _TimeSliceHeight = value; } + } + + #endregion + + #region WorkTime properties + + /// + /// Gets and sets the busy time start + /// + public WorkTime BusyStartTime + { + get { return (_BusyStartTime); } + set { _BusyStartTime = value; } + } + + /// + /// Gets and sets the busy time end + /// + public WorkTime BusyEndTime + { + get { return (_BusyEndTime); } + set { _BusyEndTime = value; } + } + + /// + /// Gets and sets the work time start + /// + public WorkTime WorkStartTime + { + get { return (_WorkStartTime); } + set { _WorkStartTime = value; } + } + + /// + /// Gets and sets the work time end + /// + public WorkTime WorkEndTime + { + get { return (_WorkEndTime); } + set { _WorkEndTime = value; } + } + + #endregion + + #region CalendarItems + + /// + /// Gets the column CalendarItems list + /// + public List CalendarItems + { + get { return (_CalendarItems); } + } + + #endregion + + #region NeedRecalcLayout + + public bool NeedRecalcLayout + { + get { return (_NeedRecalcLayout); } + set { _NeedRecalcLayout = value; } + } + + #endregion + + #endregion + + #region Public methods + + /// + /// Determines if the given time is tagged as a "Busy time" + /// + /// WorkTime to test + /// true if specified "time" is a Busy time + public bool IsBusyTime(WorkTime time) + { + return ((!BusyStartTime.IsEmpty && !BusyEndTime.IsEmpty) && + (time >= BusyStartTime && time < BusyEndTime)); + } + + /// + /// Determines if the given time is tagged as a "Work time" + /// + /// WorkTime to test + /// true if specified "time" is a Work time + public bool IsWorkTime(WorkTime time) + { + if (WorkStartTime <= WorkEndTime) + return (time >= WorkStartTime && time < WorkEndTime); + + return (time < WorkEndTime || time >= WorkStartTime); + } + + #endregion + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/DayView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/DayView.cs new file mode 100644 index 00000000..f9973746 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/DayView.cs @@ -0,0 +1,44 @@ +#if FRAMEWORK20 +using System; + +namespace DevComponents.DotNetBar.Schedule +{ + public class DayView : WeekDayView + { + /// + /// Constructor + /// + /// + public DayView(CalendarView calendarView) + : base(calendarView, eCalendarView.Day) + { + } + + #region RecalcSize support + + /// + /// Normalizes the user specified start and end dates + /// + /// [out] Normalized start date + /// [out] Normalized end date + protected override void NormalizeDates(out DateTime startDate, out DateTime endDate) + { + startDate = this.StartDate; + + // If both values are unset, then set them to + // today's date + + if (startDate == DateTime.MinValue) + startDate = DateTime.Today.Date; + + endDate = startDate; + + DaysOfTheWeek = new DaysOfTheWeek(startDate.DayOfWeek, 1); + } + + #endregion + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/ModelWeekDayViewConnector.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/ModelWeekDayViewConnector.cs new file mode 100644 index 00000000..da52ff97 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/ModelWeekDayViewConnector.cs @@ -0,0 +1,986 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using DevComponents.Schedule.Model; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.Schedule +{ + internal class ModelWeekDayViewConnector : ModelViewConnector + { + #region Private variables + + private CalendarModel _Model; // The associated CalendarModel + private WeekDayView _View; // The associated WeekDayView + + private bool _IsConnected; // Connection status + private uint _RefreshCount; + + #endregion + + /// + /// Constructor + /// + /// Assoc CalendarModel + /// Assoc WeekDayView + public ModelWeekDayViewConnector(CalendarModel model, WeekDayView weekDayView) + { + _Model = model; + _View = weekDayView; + } + + #region Public properties + + /// + /// Gets the connection status + /// + public override bool IsConnected + { + get { return (_IsConnected); } + } + + #endregion + + #region Connect processing + + /// + /// Performs Model connection processing + /// + public override void Connect() + { + VerifyModel(); + + if (_IsConnected) + Disconnect(); + + LoadData(); + + // Get notification on Model property changes + + _Model.PropertyChanged += ModelPropertyChanged; + _Model.SubPropertyChanged += ModelSubPropertyChanged; + + _View.CalendarView.CustomItems.CollectionChanged += + CustomItemsCollectionChanged; + + _IsConnected = true; + } + + #endregion + + #region Disconnect processing + + /// + /// Severs the Model/WeekDayView connection + /// + public override void Disconnect() + { + VerifyModel(); + + if (_IsConnected) + { + // Clear all AllDayPanel items + + ClearAllDayPanelItems(); + + // Loop through each DayColumn, clearing each + // associated view connection + + for (int i = 0; i < _View.DayColumns.Length; i++) + ClearWeekDayColumn(_View.DayColumns[i]); + + _View.SubItems.Clear(); + + // Stop notification on Model property changes + + _Model.PropertyChanged -= ModelPropertyChanged; + _Model.SubPropertyChanged -= ModelSubPropertyChanged; + + _View.CalendarView.CustomItems.CollectionChanged -= + CustomItemsCollectionChanged; + + _IsConnected = false; + + OnSubItemsChanged(); + } + } + + #region ClearAllDayPanelItems + + private void ClearAllDayPanelItems() + { + List items = _View.AllDayPanel.CalendarItems; + + for (int i = items.Count - 1; i >= 0; i--) + { + AppointmentWeekDayView view = items[i] as AppointmentWeekDayView; + + if (view != null) + { + view.IsSelectedChanged -= _View.ItemIsSelectedChanged; + + view.Appointment = null; + view.IsSelected = false; + view.AllDayPanel = null; + } + + items.RemoveAt(i); + } + + _View.AllDayPanel.SubItems.Clear(); + } + + #endregion + + #region ClearWeekDayColumn + + /// + /// Clears individual DayColumn view connections + /// + /// DayColumn + private void ClearWeekDayColumn(DayColumn dayColumn) + { + if (dayColumn.CalendarItems.Count > 0) + { + // Loop through each CalendarItem, resetting + // it's associated connection + + for (int i = dayColumn.CalendarItems.Count - 1; i >= 0; i--) + { + AppointmentWeekDayView view = + dayColumn.CalendarItems[i] as AppointmentWeekDayView; + + if (view != null) + { + view.IsSelectedChanged -= _View.ItemIsSelectedChanged; + + view.Appointment = null; + view.IsSelected = false; + view.DayColumn = null; + } + + dayColumn.CalendarItems.RemoveAt(i); + } + } + } + + #endregion + + #endregion + + #region LoadData processing + + /// + /// Loads Model/WeekDayView connection data + /// + private void LoadData() + { + DayColumn[] dcs = _View.DayColumns; + + if (dcs.Length > 0) + { + _RefreshCount++; + + DateTime startDate = dcs[0].Date; + DateTime endDate = DateTimeHelper.EndOfDay(dcs[dcs.Length - 1].Date); + + DateTime appStartDate = startDate.AddMonths(-1); + + List appts = GetAppointmentList(_Model, appStartDate, endDate); + + for (int i = 0; i < dcs.Length; i++) + { + DayColumn dc = dcs[i]; + + UpdateColumnAppts(dc, appts); + UpdateCustomItems(dc); + } + + UpdateAllDayPanelView(appts, startDate, endDate); + UpdateAllDayPanelCustomItems(); + + OnSubItemsChanged(); + } + } + + #region UpdateColumnAppts + + private void UpdateColumnAppts(DayColumn dayColumn, List appointments) + { + foreach (Appointment app in appointments) + { + DateTime date = dayColumn.Date.Date; + + if (date >= app.StartTime.Date && date <= app.EndTime.Date) + { + if (IsAppointmentVisible(app)) + { + // Get the assoc view + + if (_View.IsAllDayItem(app) == false) + { + AppointmentWeekDayView view = GetViewFromColumn(dayColumn, app, false) ?? + GetViewFromAllDayPanel(app, true) ?? + GetNewView(app); + + if (view.StartTime != app.StartTime || view.EndTime != app.EndTime) + dayColumn.NeedRecalcLayout = true; + + // Set the view start and end times to + // match the assoc appointment + + view.StartTime = app.StartTime; + view.EndTime = app.EndTime; + + view.RefreshCount = _RefreshCount; + + // Update the DayColumn data + + if (view.DayColumn == null) + { + view.DayColumn = dayColumn; + + dayColumn.CalendarItems.Add(view); + dayColumn.NeedRecalcLayout = true; + + _View.SubItems.Add(view); + _View.UpdateItemOrder(view); + } + } + } + } + } + + // Update workDay details + + UpdateWorkDayDetails(dayColumn); + } + + #endregion + + #region UpdateCustomItems + + private void UpdateCustomItems(DayColumn dayColumn) + { + CustomCalendarItemCollection items = _View.CalendarView.CustomItems; + + if (items != null) + { + for (int i = 0; i < items.Count; i++) + { + CustomCalendarItem item = items[i]; + + if (IsCustomItemVisible(item) == true && _View.IsAllDayItem(item) == false && + (item.StartTime < dayColumn.Date.AddDays(1) && item.EndTime > dayColumn.Date)) + { + item.CalendarView = _View.CalendarView; + + CustomCalendarItem ci = GetItemFromColumn(dayColumn, item, false); + + if (ci == null) + { + ci = GetItemFromAllDayPanel(item, true) ?? GetNewCustomItem(item); + + dayColumn.CalendarItems.Add(ci); + dayColumn.NeedRecalcLayout = true; + + _View.SubItems.Add(ci); + _View.UpdateItemOrder(ci); + } + + ci.StartTime = item.StartTime; + ci.EndTime = item.EndTime; + + ci.RefreshCount = _RefreshCount; + + dayColumn.NeedRecalcLayout = true; + } + } + } + } + + #endregion + + #endregion + + #region RefreshData processing + + /// + /// Refreshes the data in a previously established + /// and loaded connection + /// + public void RefreshData() + { + CalendarItem selItem = _View.SelectedItem; + + LoadData(); + + List removedViews = null; + + foreach (DayColumn dc in _View.DayColumns) + RemoveOutdatedViews(dc, ref removedViews); + + RemoveOutdatedAllDayViews(ref removedViews); + + ProcessRemovedData(removedViews); + + if (selItem != null) + { + selItem.IsSelected = false; + selItem.IsSelected = true; + } + } + + #region RemoveOutdatedViews + + private void RemoveOutdatedViews( + DayColumn dayColumn, ref List removedViews) + { + for (int i = dayColumn.CalendarItems.Count - 1; i >= 0; i--) + { + CalendarItem view = dayColumn.CalendarItems[i]; + + if (view != null) + { + if (view.RefreshCount != _RefreshCount) + { + if (removedViews == null) + removedViews = new List(); + + removedViews.Add(view); + + _View.SubItems._Remove(view); + _View.NeedRecalcSize = true; + + dayColumn.CalendarItems.Remove(view); + } + } + } + } + + #endregion + + #region RemoveOutdatedAllDayViews + + private void RemoveOutdatedAllDayViews(ref List removedViews) + { + for (int i = _View.AllDayPanel.CalendarItems.Count - 1; i >= 0; i--) + { + CalendarItem view = + _View.AllDayPanel.CalendarItems[i] as CalendarItem; + + if (view != null) + { + if (view.RefreshCount != _RefreshCount || + _View.IsAllDayItem(view) == false) + { + if (removedViews == null) + removedViews = new List(); + + removedViews.Add(view); + + _View.AllDayPanel.CalendarItems.RemoveAt(i); + _View.AllDayPanel.SubItems.Remove(view); + + _View.NeedRecalcLayout = true; + } + } + } + } + + #endregion + + #region ProcessRemovedData + + private void ProcessRemovedData(List removedViews) + { + if (removedViews != null && removedViews.Count > 0) + { + for (int i = 0; i < removedViews.Count; i++) + { + CalendarItem item = removedViews[i]; + + item.IsSelectedChanged -= _View.ItemIsSelectedChanged; + + item.Dispose(); + } + + _View.NeedRecalcLayout = true; + } + } + + #endregion + + #endregion + + #region UpdateAllDayPanelView + + private void UpdateAllDayPanelView( + List appts, DateTime startDate, DateTime endDate) + { + // Loop through each appointment + // updating the assoc view accordingly + + foreach (Appointment app in appts) + { + if (app.StartTime < endDate && app.EndTime > startDate) + { + if (IsAppointmentVisible(app)) + { + // Get the assoc view + + if (_View.IsAllDayItem(app) == true) + { + AppointmentWeekDayView view = + GetViewFromAllColumns(app, true) ?? + GetViewFromAllDayPanel(app, false) ?? + GetNewView(app); + + // Set the view start and end times to + // match the assoc appointment + + view.StartTime = app.StartTime; + view.EndTime = app.EndTime; + + view.RefreshCount = _RefreshCount; + + if (view.AllDayPanel == null) + { + view.AllDayPanel = _View.AllDayPanel; + + _View.AllDayPanel.CalendarItems.Add(view); + _View.AllDayPanel.SubItems.Add(view); + + _View.NeedRecalcLayout = true; + } + } + } + } + } + } + + #endregion + + #region UpdateAllDayPanelCustomItems + + private void UpdateAllDayPanelCustomItems() + { + CustomCalendarItemCollection items = _View.CalendarView.CustomItems; + + if (items != null) + { + DateTime startDate = _View.StartDate; + DateTime endDate = _View.EndDate.AddDays(1); + + for (int i = 0; i < items.Count; i++) + { + CustomCalendarItem item = items[i]; + + if (IsCustomItemVisible(item) == true && _View.IsAllDayItem(item) == true && + (item.StartTime < endDate && item.EndTime > startDate)) + { + item.CalendarView = _View.CalendarView; + + CustomCalendarItem ci = GetItemFromAllDayPanel(item, false); + + if (ci == null) + { + ci = GetItemFromAllColumns(item, true); + + if (ci == null) + ci = GetNewCustomItem(item); + + _View.AllDayPanel.CalendarItems.Add(ci); + _View.NeedRecalcLayout = true; + + _View.AllDayPanel.SubItems.Add(ci); + } + + if (ci.StartTime != item.StartTime || ci.EndTime != item.EndTime) + { + ci.StartTime = item.StartTime; + ci.EndTime = item.EndTime; + + _View.NeedRecalcLayout = true; + } + } + } + } + } + + #endregion + + #region UpdateWorkDayDetails + + /// + /// Updates DayColumn workday details + /// + /// DayColumn to update + private void UpdateWorkDayDetails(DayColumn dayColumn) + { + // Update workDay timings + + Owner owner = _Model.Owners[_View.OwnerKey]; + + if (owner == null || GetCalendarWorkDays(dayColumn, owner.CalendarWorkDays) == false) + { + if (GetCalendarWorkDays(dayColumn, _Model.CalendarWorkDays) == false) + { + if (owner == null || GetWorkDays(dayColumn, owner.WorkDays) == false) + { + if (GetWorkDays(dayColumn, _Model.WorkDays) == false) + { + dayColumn.WorkStartTime = new WorkTime(); + dayColumn.WorkEndTime = new WorkTime(); + } + } + } + } + } + + #region GetCalendarWorkDays + + /// + /// GetCalendarWorkDays + /// + /// + /// + /// + private bool GetCalendarWorkDays( + DayColumn dayColumn, CalendarWorkDayCollection calendarWorkDays) + { + if (calendarWorkDays != null && calendarWorkDays.Count > 0) + { + CalendarWorkDay cwd = calendarWorkDays[dayColumn.Date]; + + if (cwd != null) + { + dayColumn.WorkStartTime = cwd.WorkStartTime; + dayColumn.WorkEndTime = cwd.WorkEndTime; + + return (true); + } + } + + return (false); + } + + #endregion + + #region GetWorkDays + + /// + /// GetWorkDays + /// + /// + /// + /// + private bool GetWorkDays( + DayColumn dayColumn, WorkDayCollection workDays) + { + if (workDays != null && workDays.Count > 0) + { + WorkDay wd = workDays[dayColumn.Date.DayOfWeek]; + + if (wd != null) + { + dayColumn.WorkStartTime = wd.WorkStartTime; + dayColumn.WorkEndTime = wd.WorkEndTime; + } + else + { + dayColumn.WorkStartTime = new WorkTime(); + dayColumn.WorkEndTime = new WorkTime(); + } + + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region GetView routines + + #region GetViewFromAll + + private AppointmentWeekDayView + GetViewFromAll(Appointment app, bool remove) + { + AppointmentWeekDayView view = GetViewFromAllColumns(app, remove); + + if (view != null) + return (view); + + return (GetViewFromAllDayPanel(app, remove)); + } + + #endregion + + #region GetViewFromAllColumns + + private AppointmentWeekDayView + GetViewFromAllColumns(Appointment app, bool remove) + { + for (int i = 0; i < _View.NumberOfColumns; i++) + { + AppointmentWeekDayView view = + GetViewFromColumn(_View.DayColumns[i], app, remove); + + if (view != null) + return (view); + } + + return (null); + } + + #endregion + + #region GetViewFromColumn + + private AppointmentWeekDayView + GetViewFromColumn(DayColumn dayColumn, Appointment appointment, bool remove) + { + foreach (CalendarItem item in dayColumn.CalendarItems) + { + AppointmentWeekDayView view = item as AppointmentWeekDayView; + + if (view != null && view.Appointment == appointment) + { + if (remove == true) + { + dayColumn.CalendarItems.Remove(view); + _View.SubItems.Remove(view); + + view.DayColumn = null; + } + + return (view); + } + } + + return (null); + } + + #endregion + + #region GetViewFromAllDayPanel + + private AppointmentWeekDayView + GetViewFromAllDayPanel(Appointment appointment, bool remove) + { + foreach (CalendarItem item in _View.AllDayPanel.CalendarItems) + { + AppointmentWeekDayView view = item as AppointmentWeekDayView; + + if (view != null && view.Appointment == appointment) + { + if (remove == true) + { + _View.AllDayPanel.CalendarItems.Remove(view); + _View.AllDayPanel.SubItems.Remove(view); + + view.AllDayPanel = null; + } + + return (view); + } + } + + return (null); + } + + #endregion + + #endregion + + #region GetItem routines + + #region GetItemFromColumn + + private CustomCalendarItem + GetItemFromColumn(DayColumn dayColumn, CustomCalendarItem item, bool remove) + { + foreach (CalendarItem citem in dayColumn.CalendarItems) + { + CustomCalendarItem view = citem as CustomCalendarItem; + + if (view != null && (view == item || view.BaseCalendarItem == item)) + { + if (remove == true) + dayColumn.CalendarItems.Remove(view); + + return (view); + } + } + + return (null); + } + + #endregion + + #region GetItemFromAllColumns + + private CustomCalendarItem + GetItemFromAllColumns(CustomCalendarItem item, bool remove) + { + for (int i = 0; i < _View.NumberOfColumns; i++) + { + CustomCalendarItem view = + GetItemFromColumn(_View.DayColumns[i], item, false); + + if (view != null) + return (view); + } + + return (null); + } + + #endregion + + #region GetItemFromAllDayPanel + + private CustomCalendarItem + GetItemFromAllDayPanel(CustomCalendarItem item, bool remove) + { + foreach (CalendarItem citem in _View.AllDayPanel.CalendarItems) + { + CustomCalendarItem view = citem as CustomCalendarItem; + + if (view != null && (view == item || view.BaseCalendarItem == item)) + { + if (remove == true) + _View.AllDayPanel.CalendarItems.Remove(view); + + return (view); + } + } + + return (null); + } + + #endregion + + #endregion + + #region GetNewView + + /// + /// Gets a new appointment view + /// + /// Appointment + /// New view + private AppointmentWeekDayView GetNewView(Appointment appointment) + { + AppointmentWeekDayView view = new AppointmentWeekDayView(_View, appointment); + + view.Tooltip = appointment.Tooltip; + + view.IsSelectedChanged += _View.ItemIsSelectedChanged; + + return (view); + } + + #endregion + + #region GetNewCustomItem + + private CustomCalendarItem GetNewCustomItem(CustomCalendarItem item) + { + CustomCalendarItem ci = (CustomCalendarItem)item.Copy(); + ci.BaseCalendarItem = item; + + ci.IsSelectedChanged += _View.ItemIsSelectedChanged; + + return (ci); + } + + #endregion + + #region View support routines + + /// + /// Returns the view + /// + /// + public override eCalendarView GetView() + { + return (eCalendarView.Week); + } + + /// + /// Verifies the Model and MonthView are valid + /// + private void VerifyModel() + { + if (_Model == null) + throw new NullReferenceException("CalendarModel must be set on connector."); + + if (_View == null) + throw new NullReferenceException("WeekDayCalendarView must be set on connector."); + } + + #endregion + + #region Model property change processing + + /// + /// Handles Model property change notifications + /// + /// + /// + private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == CalendarModel.AppointmentsPropertyName) + { + RefreshData(); + UpdateDisplay(); + } + else if (e.PropertyName == CalendarModel.WorkDaysPropertyName) + { + for (int i = 0; i < _View.NumberOfColumns; i++) + UpdateWorkDayDetails(_View.DayColumns[i]); + + _View.CalendarView.CalendarPanel.RecalcSize(); + } + } + + #endregion + + #region ModelSubPropertyChanged + + /// + /// Handles ModelSubProperty change notifications + /// + /// object + /// SubPropertyChangedEventArgs + private void ModelSubPropertyChanged(object sender, SubPropertyChangedEventArgs e) + { + if (e.Source is WorkDay) + { + for (int i = 0; i < _View.NumberOfColumns; i++) + UpdateWorkDayDetails(_View.DayColumns[i]); + + _View.CalendarView.CalendarPanel.RecalcSize(); + } + else if (e.Source is Owner) + { + Owner owner = (Owner) e.Source; + + if (_View.OwnerKey != null && _View.OwnerKey.Equals(owner.Key)) + { + if (e.PropertyChangedArgs.PropertyName == Owner.DisplayNamePropertyName) + _View.DisplayName = owner.DisplayName; + + else if (e.PropertyChangedArgs.PropertyName.Equals("ColorScheme")) + _View.CalendarColor = owner.ColorScheme; + } + } + else if (e.Source is Appointment) + { + Appointment app = e.Source as Appointment; + AppointmentWeekDayView appView; + + string name = e.PropertyChangedArgs.PropertyName; + + if (name.Equals("Tooltip")) + { + appView = GetViewFromAll(app, false); + + if (appView != null) + appView.Tooltip = app.Tooltip; + } + else if (name.Equals("IsSelected")) + { + appView = GetViewFromAll(app, false); + + if (appView != null) + appView.IsSelected = app.IsSelected; + } + else if (name.Equals("CategoryColor") || name.Equals("TimeMarkedAs") || name.Equals("ImageKey")) + { + appView = GetViewFromAll(app, false); + + if (appView != null) + appView.Refresh(); + } + else if (name.Equals("OwnerKey")) + { + if (_View.CalendarView.IsMultiCalendar == true) + { + if (_View.OwnerKey == app.OwnerKey) + { + RefreshData(); + UpdateDisplay(); + } + else + { + appView = GetViewFromAll(app, false); + + if (appView != null) + { + RefreshData(); + UpdateDisplay(); + } + } + } + } + else if (name.Equals("Visible")) + { + RefreshData(); + UpdateDisplay(); + } + } + } + + #endregion + + #region CustomItems_CollectionChanged + + void CustomItemsCollectionChanged(object sender, EventArgs e) + { + RefreshData(); + UpdateDisplay(); + } + + #endregion + + #region UpdateDisplay + + private void UpdateDisplay() + { + if (_View.Displayed == true) + { + if (_View.NeedRecalcLayout == false) + { + for (int i = 0; i < _View.NumberOfColumns; i++) + { + if (_View.DayColumns[i].NeedRecalcLayout) + { + _View.RecalcSize(); + break; + } + } + } + } + } + + #endregion + + #region OnSubItemsChanged + + private void OnSubItemsChanged() + { + System.Windows.Forms.Cursor.Position = + System.Windows.Forms.Cursor.Position; + } + + #endregion + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/PosWin.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/PosWin.Designer.cs new file mode 100644 index 00000000..f03e287f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/PosWin.Designer.cs @@ -0,0 +1,59 @@ +#if FRAMEWORK20 +namespace DevComponents.DotNetBar.Schedule +{ + partial class PosWin + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // PosWin + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.CausesValidation = false; + this.ClientSize = new System.Drawing.Size(1, 1); + this.ControlBox = false; + this.DoubleBuffered = true; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Location = new System.Drawing.Point(1000, 1000); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "PosWin"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; + this.Text = "PosWin"; + this.Paint += new System.Windows.Forms.PaintEventHandler(this.PosWin_Paint); + this.ResumeLayout(false); + + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/PosWin.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/PosWin.cs new file mode 100644 index 00000000..821a93f5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/PosWin.cs @@ -0,0 +1,132 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Schedule +{ + public partial class PosWin : Form + { + #region Private variables + + private string _PosText = ""; // Window content + private int _PosHeight; // Calculated window height + + #endregion + + /// + /// Constructor + /// + public PosWin() + { + InitializeComponent(); + } + + #region CreateParams / show support + + // This code permits us to be able to create a + // window with a drop shadow + + private const int CS_DROPSHADOW = 0x00020000; + + protected override CreateParams CreateParams + { + get + { + CreateParams parameters = base.CreateParams; + + parameters.ClassStyle = + (parameters.ClassStyle | CS_DROPSHADOW); + + return (parameters); + } + } + + protected override bool ShowWithoutActivation + { + get { return true; } + } + + #endregion + + #region Public properties + + /// + /// Gets and sets the window content text + /// + public string PosText + { + get { return (_PosText); } + + set + { + if (_PosText != value) + { + _PosText = value; + + this.Refresh(); + } + } + } + + /// + /// Gets the calculated window height + /// + public int PosHeight + { + get + { + if (_PosHeight <= 0) + { + using (Graphics g = CreateGraphics()) + { + eTextFormat tf = eTextFormat.Default | + eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter; + + Size sz = TextDrawing.MeasureString(g, "ABC", SystemFonts.CaptionFont, 0, tf); + + _PosHeight = sz.Height + 4; + } + } + + return (_PosHeight); + } + } + + #endregion + + #region Paint processing + + private void PosWin_Paint(object sender, PaintEventArgs e) + { + Graphics g = e.Graphics; + + eTextFormat tf = eTextFormat.Default | eTextFormat.HorizontalCenter | eTextFormat.VerticalCenter; + + Size sz = TextDrawing.MeasureString(g, _PosText, SystemFonts.CaptionFont, 0, tf); + + sz.Width += 6; + sz.Height += 4; + + this.Size = sz; + + int swidth = Screen.FromControl(this).Bounds.Width; + + if (Location.X + sz.Width > swidth) + Location = new Point(swidth - sz.Width, Location.Y); + + Rectangle r = new Rectangle(0, 0, sz.Width - 1, sz.Height - 1); + + g.DrawRectangle(Pens.Black, r); + + TextDrawing.DrawString(g, _PosText, SystemFonts.CaptionFont, Color.Black, r, tf); + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/PosWin.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/PosWin.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/PosWin.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/TimeRulerPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/TimeRulerPanel.cs new file mode 100644 index 00000000..e8945c80 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/TimeRulerPanel.cs @@ -0,0 +1,760 @@ +#if FRAMEWORK20 +using System; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.Schedule +{ + public class TimeRulerPanel : BaseItem + { + #region Private Variables + + private CalendarView _CalendarView; // Assoc CalendarView + + private int _VScrollPos; // Vertical scroll position + + private TimeRulerColor _ViewColor = // View display color table + new TimeRulerColor(); + + #endregion + + /// + /// Constructor + /// + /// + public TimeRulerPanel(CalendarView calendarView) + { + _CalendarView = calendarView; + + Name = "TimeRulerPanel"; + + HookEvents(true); + } + + #region Private properties + + #region General display properties + + /// + /// Gets the TimeRuler font + /// + private Font TimeRulerFont + { + get { return (_CalendarView.TimeRulerFont); } + } + + /// + /// Gets the TimeRuler font (small) + /// + private Font TimeRulerFontSm + { + get { return (_CalendarView.TimeRulerFontSm); } + } + + #endregion + + #region Time Slice Properties + + /// + /// Gets the default Time Slice height + /// + private float TimeSliceHeight + { + get { return (_CalendarView.TimeSliceHeight); } + } + + /// + /// Gets the TimeSlotDuration + /// + private int TimeSlotDuration + { + get { return (_CalendarView.TimeSlotDuration); } + } + + /// + /// Gets the SlotsPerHour + /// + private int SlotsPerHour + { + get { return (_CalendarView.SlotsPerHour); } + } + + /// + /// Gets the NumberOfSlices + /// + private int NumberOfSlices + { + get { return (_CalendarView.NumberOfSlices); } + } + + /// + /// Gets the starting Time Slice + /// + private int StartSlice + { + get { return (_CalendarView.StartSlice); } + } + + #endregion + + #region AM / PM designators + + /// + /// Gets the culturally correct AM time designator + /// + private string AmDesignator + { + get + { + return (ScheduleSettings.GetActiveCulture(). + DateTimeFormat.AMDesignator.ToLower()); + } + } + + /// + /// Gets the culturally correct PM time designator + /// + private string PmDesignator + { + get + { + return (ScheduleSettings.GetActiveCulture(). + DateTimeFormat.PMDesignator.ToLower()); + } + } + + #endregion + + #endregion + + #region Hook / Unhook Events + + /// + /// Routine hooks all necessary events for this control + /// + /// True to hook, false to unhook + private void HookEvents(bool hook) + { + if (hook == true) + { + _CalendarView.LabelTimeSlotsChanged += CalendarView_LabelTimeSlotsChanged; + _CalendarView.Is24HourFormatChanged += CalendarView_Is24HourFormatChanged; + _CalendarView.TimeSlotDurationChanged += CalendarView_TimeSlotDurationChanged; + _CalendarView.TimeIndicatorsChanged += CalendarView_TimeIndicatorsChanged; + _CalendarView.TimeIndicatorTimeChanged += CalendarView_TimeIndicatorTimeChanged; + + _CalendarView.WeekDayVScrollPanel.ScrollBarChanged += VScrollPanel_ScrollBarChanged; + } + else + { + _CalendarView.LabelTimeSlotsChanged -= CalendarView_LabelTimeSlotsChanged; + _CalendarView.Is24HourFormatChanged -= CalendarView_Is24HourFormatChanged; + _CalendarView.TimeSlotDurationChanged -= CalendarView_TimeSlotDurationChanged; + _CalendarView.TimeIndicatorsChanged -= CalendarView_TimeIndicatorsChanged; + _CalendarView.TimeIndicatorTimeChanged -= CalendarView_TimeIndicatorTimeChanged; + + _CalendarView.WeekDayVScrollPanel.ScrollBarChanged -= VScrollPanel_ScrollBarChanged; + } + } + + #endregion + + #region Event Processing + + #region CalendarView_LabelTimeSlotsChanged + + /// + /// Processes LabelTimeSlotsChanged events + /// + /// + /// + void CalendarView_LabelTimeSlotsChanged( + object sender, LabelTimeSlotsChangedEventArgs e) + { + Refresh(); + } + + #endregion + + #region CalendarView_Is24HourFormatChanged + + /// + /// Processes Is24HourFormatChanged events + /// + /// + /// + void CalendarView_Is24HourFormatChanged( + object sender, Is24HourFormatChangedEventArgs e) + { + Refresh(); + } + + #endregion + + #region CalendarView_TimeSlotDurationChanged + + /// + /// Processes TimeSlotDurationChanged events + /// + /// + /// + void CalendarView_TimeSlotDurationChanged( + object sender, TimeSlotDurationChangedEventArgs e) + { + Refresh(); + } + + #endregion + + #region CalendarView_TimeIndicatorsChanged + + /// + /// Processes CalendarView_TimeIndicatorsChanged events + /// + /// + /// + void CalendarView_TimeIndicatorsChanged(object sender, EventArgs e) + { + Refresh(); + } + + #endregion + + #region CalendarView_TimeIndicatorTimeChanged + + /// + /// Processes CalendarView_TimeIndicatorTimeChanged events + /// + /// + /// + void CalendarView_TimeIndicatorTimeChanged( + object sender, TimeIndicatorTimeChangedEventArgs e) + { + Refresh(); + } + + #endregion + + #region VScrollPanel_ScrollBarChanged + + void VScrollPanel_ScrollBarChanged(object sender, EventArgs e) + { + Refresh(); + + Rectangle r = Bounds; + + r.Y = _CalendarView.WeekDayVScrollPanel.Bounds.Y; + r.Height = _CalendarView.WeekDayVScrollPanel.Bounds.Height; + + Bounds = r; + + _VScrollPos = -_CalendarView.WeekDayVScrollPanel.ScrollBar.Value; + + Refresh(); + } + + #endregion + + #endregion + + #region Paint processing + + /// + /// Paint processing routine + /// + /// + public override void Paint(ItemPaintArgs e) + { + int sliceStart, sliceEnd; + int sliceCount = GetSliceRange(e, out sliceStart, out sliceEnd); + + if (sliceCount > 0) + { + _ViewColor.SetColorTable(); + + DrawTimeRuler(e, sliceStart, sliceEnd); + } + } + + #region Slice Support Routines + + /// + /// Calculates the range of slices needed to be drawn + /// to satisfy the specified paint request + /// + /// ItemPaintArgs + /// [out] Slice start index + /// [out] Slice end index + /// Slice range count (end - start) + internal int GetSliceRange(ItemPaintArgs e, out int sliceStart, out int sliceEnd) + { + // Calc our starting index + + int start = 0; + + while (start < NumberOfSlices) + { + Rectangle r = GetSliceRect(start); + + if (r.Bottom > Bounds.Top) + { + if (r.Bottom > e.ClipRectangle.Y) + break; + } + + start++; + } + + // Calc our ending index + + int end = start; + + while (end < NumberOfSlices) + { + Rectangle r = GetSliceRect(end); + + if (r.Y >= e.ClipRectangle.Bottom) + break; + + end++; + } + + // Set the user supplied 'out' values, and + // return the range count to the caller + + if (end - start == 0) + { + sliceStart = 0; + sliceEnd = 0; + + return (0); + } + + sliceStart = start; + sliceEnd = end - 1; + + return (end - start); + } + + /// + /// Gets the given slice rectangle + /// + /// Slice + /// Bounding rectangle + private Rectangle GetSliceRect(int slice) + { + Rectangle r = Bounds; + + float n = slice * TimeSliceHeight; + + r.Y += (int)(n) + _VScrollPos; + r.Height = (int)(n + TimeSliceHeight) - (int)n; + + return (r); + } + + #endregion + + #region DrawTimeRuler + + /// + /// Draws the TimeRuler + /// + /// ItemPaintArgs + /// + /// + private void DrawTimeRuler(ItemPaintArgs e, int sliceStart, int sliceEnd) + { + Graphics g = e.Graphics; + + Region regSav = g.Clip; + g.SetClip(Bounds); + + DrawBackGround(g); + DrawTimeIndicators(g, sliceStart, sliceEnd); + DrawRulerContent(g, sliceStart, sliceEnd); + + // Restore our original clip region + + g.Clip = regSav; + } + + #endregion + + #region DrawBackGround + + /// + /// DrawBackGround + /// + /// + private void DrawBackGround(Graphics g) + { + using (Brush br = _ViewColor.BrushPart((int)eTimeRulerPart.TimeRulerBackground, Bounds)) + g.FillRectangle(br, Bounds); + } + + #endregion + + #region DrawTimeIndicators + + #region DrawTimeIndicators + + /// + /// Draws TimeIndicators + /// + /// + /// + /// + private void DrawTimeIndicators(Graphics g, int sliceStart, int sliceEnd) + { + DateTime start, end; + GetViewDates(out start, out end); + + Rectangle r = Rectangle.Union(GetSliceRect(sliceStart), GetSliceRect(sliceEnd)); + + for (int i = 0; i < _CalendarView.TimeIndicators.Count; i++) + { + TimeIndicator ti = _CalendarView.TimeIndicators[i]; + + if (ti.IndicatorArea == eTimeIndicatorArea.All || + ti.IndicatorArea == eTimeIndicatorArea.Header) + { + if (ti.IsVisible()) + { + DateTime time = ti.IndicatorDisplayTime; + + if (time >= start && time < end) + DrawTimeIndicator(g, r, ti); + } + } + } + } + + #endregion + + #region DrawTimeIndicator + + #region DrawTimeIndicator + + /// + /// Draws individual TimeIndicators + /// + /// + /// + /// + private void DrawTimeIndicator(Graphics g, Rectangle sRect, TimeIndicator ti) + { + Rectangle r = GetIndicatorRect(ti); + + if (r.IntersectsWith(sRect) == true) + { + if (r.Height > 0) + { + ColorDef cdef = GetIndicatorColor(ti); + + if (cdef != null) + { + using (Brush br = _ViewColor.BrushPart(cdef, r)) + { + if (br is LinearGradientBrush) + ((LinearGradientBrush)br).WrapMode = WrapMode.TileFlipX; + + g.FillRectangle(br, r); + } + } + } + + Color color = GetIndicatorBorder(ti); + + if (color.IsEmpty == false) + { + using (Pen pen = new Pen(color)) + g.DrawLine(pen, r.X + 1, r.Bottom, r.Right - 1, r.Bottom); + } + } + } + + #endregion + + #region GetIndicatorColor + + /// + /// Gets the Indicator Back color + /// + /// + /// + private ColorDef GetIndicatorColor(TimeIndicator ti) + { + ColorDef cdef = ti.IndicatorColor; + + if (cdef == null || cdef.IsEmpty == true) + cdef = _ViewColor.GetColorDef((int)eTimeRulerPart.TimeRulerIndicator); + + return (cdef); + } + + #endregion + + #region GetIndicatorBorder + + /// + /// Gets the Indicator Border color + /// + /// + /// + private Color GetIndicatorBorder(TimeIndicator ti) + { + return (ti.BorderColor.IsEmpty == false ? ti.BorderColor : + _ViewColor.GetColor((int)eTimeRulerPart.TimeRulerIndicatorBorder)); + } + + #endregion + + #endregion + + #region GetViewDates + + /// + /// GetViewDates + /// + /// + /// + private void GetViewDates(out DateTime start, out DateTime end) + { + switch (_CalendarView.SelectedView) + { + case eCalendarView.Day: + start = _CalendarView.DayViewDate; + end = _CalendarView.DayViewDate.AddDays(1); + break; + + default: + start = _CalendarView.WeekViewStartDate; + end = _CalendarView.WeekViewEndDate.AddDays(1); + break; + } + } + + #endregion + + #region GetIndicatorRect + + /// + /// GetIndicatorRect + /// + /// + /// + private Rectangle GetIndicatorRect(TimeIndicator ti) + { + DateTime time = ti.IndicatorDisplayTime; + + int offset = (int)(time.Hour * SlotsPerHour * TimeSliceHeight + + (TimeSliceHeight * time.Minute) / TimeSlotDuration); + + offset -= (int)(StartSlice * TimeSliceHeight); + + Rectangle r = Bounds; + + r.Y += (offset - ti.Thickness + _VScrollPos); + r.Height = ti.Thickness; + + return (r); + } + + #endregion + + #endregion + + #region DrawRulerContent + + private void DrawRulerContent(Graphics g, int sliceStart, int sliceEnd) + { + Point pt1 = new Point(); + Point pt2 = new Point(); + + using (Pen pen = new Pen( + _ViewColor.GetColor((int)eTimeRulerPart.TimeRulerBorder))) + { + pt1.X = 3; + pt2.X = Bounds.Width - 4; + + for (int i = sliceStart; i <= sliceEnd; i++) + { + Rectangle r = GetSliceRect(i); + + // Draw an hourly separation border line + + if ((i % SlotsPerHour) == 0) + { + pt1.Y = pt2.Y = r.Y; + + g.DrawLine(pen, pt1, pt2); + } + + // Draw the time text + + DrawTimeRulerText(g, r, i); + } + } + } + + #endregion + + #region DrawTimeRulerText + + /// + /// Draws the time text + /// + /// + /// + /// + private void DrawTimeRulerText(Graphics g, Rectangle r, int slice) + { + // Get our hour and minute display text + + slice += StartSlice; + + int hour = slice / SlotsPerHour; + int minute = (slice % SlotsPerHour) * TimeSlotDuration; + + if (_CalendarView.LabelTimeSlots == true || minute == 0) + { + string sHour = GetRulerHour(hour); + string sMinute = GetRulerMinute(hour, minute); + + // Setup for our output + + Color color = _ViewColor.GetColor( + (int)eTimeRulerPart.TimeRulerForeground); + + eTextFormat tf = eTextFormat.Top | eTextFormat.Left | eTextFormat.NoPadding; + + Size sz = TextDrawing.MeasureString(g, sHour, TimeRulerFont, 0, tf); + + Rectangle r2 = new Rectangle(Bounds.X, r.Y + 1, + Bounds.Width / 2, (int)TimeSliceHeight - 1); + + // If we are displaying an hourly marker, then display + // it as an offset hour and minute (or AM/PM designator) display + + if (minute == 0) + { + r2.X = r2.Right - sz.Width; + + if (r2.X < 0) + r2.X = 0; + + r2.Width = sz.Width; + + TextDrawing.DrawString(g, sHour, TimeRulerFont, color, r2, tf); + + r2.X = r2.Right + 2; + r2.Y += 1; + + tf = eTextFormat.Top | eTextFormat.Left | eTextFormat.NoPadding; + + TextDrawing.DrawString(g, sMinute, TimeRulerFontSm, color, r2, tf); + } + else + { + // Non-hourly display + + r2.Width = Bounds.Width - 4; + r2.Y += 2; + + tf = eTextFormat.Top | eTextFormat.Right | eTextFormat.NoPadding; + + TextDrawing.DrawString(g, + sHour + ScheduleSettings.GetActiveCulture().DateTimeFormat.TimeSeparator + + sMinute, TimeRulerFontSm, color, r2, tf); + } + } + } + + /// + /// Gets the hourly display text + /// + /// Hour + /// Hourly text + private string GetRulerHour(int hour) + { + if (_CalendarView.Is24HourFormat == false) + { + int h = hour % 12; + hour = (h == 0) ? 12 : h; + } + else + { + int h = hour % 24; + hour = (h == 0) ? 0 : h; + } + + return (hour.ToString(ScheduleSettings.TimeRulerHourFormatString)); + } + + /// + /// Gets the minute display text + /// + /// Hour + /// Minute + /// Minute text + private string GetRulerMinute(int hour, int minute) + { + if (minute == 0 && _CalendarView.Is24HourFormat == false) + { + hour %= 24; + + if (hour == 0) + return (AmDesignator); + + if (hour == 12) + return (PmDesignator); + } + + return (minute.ToString(ScheduleSettings.TimeRulerMinuteFormatString)); + } + + #endregion + + #endregion + + #region IDisposable Members + + protected override void Dispose(bool disposing) + { + if (disposing == true && IsDisposed == false) + HookEvents(false); + + base.Dispose(disposing); + } + + #endregion + + #region Copy + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + TimeRulerPanel objCopy = new TimeRulerPanel(_CalendarView); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the TimeRulerPanel specific properties to new instance of the item. + /// + /// New TimeRulerPanel instance + protected override void CopyToItem(BaseItem copy) + { + TimeRulerPanel objCopy = copy as TimeRulerPanel; + base.CopyToItem(objCopy); + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/WeekDayVScrollPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/WeekDayVScrollPanel.cs new file mode 100644 index 00000000..66a2115d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/WeekDayVScrollPanel.cs @@ -0,0 +1,27 @@ +#if FRAMEWORK20 +namespace DevComponents.DotNetBar.Schedule +{ + public class WeekDayVScrollPanel : VScrollPanel + { + public WeekDayVScrollPanel(CalendarView calendarView) + : base(calendarView) + { + } + + #region Private properties + + protected override int ScrollPanelSmallChange + { + get { return ((int)CalendarView.TimeSliceHeight); } + } + + protected override int ScrollPanelMaximum + { + get { return ((int)(CalendarView.TimeSliceHeight * CalendarView.NumberOfSlices)); } + } + + #endregion + + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/WeekDayView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/WeekDayView.cs new file mode 100644 index 00000000..b2c6299b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/WeekDayView.cs @@ -0,0 +1,4460 @@ +#if FRAMEWORK20 +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class WeekDayView : BaseView + { + #region Constants + + private const int HoursPerDay = 24; + private const int MinutesPerHour = 60; + private const int MaxNumberOfColumns = 3 * 31; + + #endregion + + #region Private variables + + private AllDayPanel _AllDayPanel; // AllDay items panel + + private DayColumn[] _DayColumns; // Array of DayColumns + private int _NumberOfColumns; // Number of DayColumns + private Size[] _DayColumnSize; // Array of day text sizes + + private CalendarWeekDayColor _ViewColor = // View display color table + new CalendarWeekDayColor(eCalendarColor.Automatic); + + private int _LastCol; // Last processed column + private Point _LastMovePoint; // Last mouse move Point + private Point _LastPointOffset; // Last Point offset + private Rectangle _LastBounds; // MouseDown item bounds + + int _LastMoveCol; + int _LastDm; + + private bool _IsPanelResizing; // Flag denoting panel resizing + private bool _WasAllDayItem; + + private int _SelectedSliceStart; // Absolute slice start + private int _SelectedSliceEnd; // Absolute slice end (e.g. 450 - 1440) + + private Timer _ScrollViewTimer; // Timer used to implement auto view scrolling + private int _VScrollPos; // Vertical scroll bar pos + + private Color _BusyColor; // Cached brush colors + private Color _WorkColor; + private Color _OffWorkColor; + private Color _SelectedColor; + + private Brush _BusyBrush; // Cached brushes + private Brush _WorkBrush; + private Brush _OffWorkBrush; + private Brush _SelectedBrush; + private Brush _AllDayBrush; + private Color _AllDayColor; + + private int _LocalStartSlice; + private int _LocalNumberOfSlices; + + #endregion + + /// + /// Constructor + /// + /// CalendarView + /// + public WeekDayView(CalendarView calendarView, eCalendarView eCalendarView) + : base(calendarView, eCalendarView) + { + // Allocate our AllDayPanel + + _AllDayPanel = new AllDayPanel(this); + _AllDayPanel.Displayed = true; + + // Set our non-client drawing info and CalendarColor + + NClientData = new NonClientData( + eTabOrientation.Horizontal, + (int)eCalendarWeekDayPart.OwnerTabBorder, + (int)eCalendarWeekDayPart.OwnerTabForeground, + (int)eCalendarWeekDayPart.OwnerTabBackground, + (int)eCalendarWeekDayPart.OwnerTabContentBackground, + (int)eCalendarWeekDayPart.OwnerTabSelectedForeground, + (int)eCalendarWeekDayPart.OwnerTabSelectedBackground); + + CalendarColorTable = _ViewColor; + + // Hook onto our events + + HookEvents(true); + } + + #region Public properties + + #region DayColumns + + /// + /// Gets the view DayColumns + /// + public DayColumn[] DayColumns + { + get { return (_DayColumns); } + } + + #endregion + + #region NumberOfColumns + + /// + /// Gets the view's number of DayColumns + /// + public int NumberOfColumns + { + get { return (_NumberOfColumns); } + } + + #endregion + + #region VScrollBar + + /// + /// Gets the WeekDay vertical scrollbar + /// + public VScrollBarAdv VScrollBar + { + get { return (CalendarView.WeekDayVScrollBar ); } + } + + #endregion + + #endregion + + #region Internal properties + + #region Base calendar properties + + /// + /// Gets the Sub-Day view rectangle + /// + internal Rectangle ViewRect + { + get + { + Rectangle r = ClientRect; + + int n = DayOfWeekHeaderHeight + _AllDayPanel.PanelHeight; + + r.Y += n; + r.Height -= (n + 1); + + return (r); + } + } + + /// + /// Gets the CalendarColor + /// + internal CalendarWeekDayColor WeekDayColor + { + get { return (_ViewColor); } + } + + #endregion + + #region DayColumn properties + + /// + /// Gets the local StartSlice + /// + internal int LocalStartSlice + { + get { return (_LocalStartSlice); } + } + + /// + /// Gets the local NumberOfSlices + /// + internal int LocalNumberOfSlices + { + get { return (_LocalNumberOfSlices); } + } + + #endregion + + #region AllDayPanel properties + + /// + /// Gets the view's AllDayPanel + /// + internal AllDayPanel AllDayPanel + { + get { return (_AllDayPanel); } + } + + #endregion + + #endregion + + #region Private properties + + #region DayColumnWidth + + /// + /// Gets the DayColumnWidth + /// + private float DayColumnWidth + { + get { return (((float)ClientRect.Width - 1) / _NumberOfColumns); } + } + + #endregion + + #region AllDay Panel properties + + /// + /// Gets the maximum AllDayPanel height + /// + private int MaximumAllDayPanelHeight + { + get { return (CalendarView.MaximumAllDayPanelHeight); } + } + + #endregion + + #region Time Slice properties + + /// + /// Gets the TimeSlotDuration + /// + private int TimeSlotDuration + { + get { return (CalendarView.TimeSlotDuration); } + } + + /// + /// Gets the default Time Slice height + /// + private float TimeSliceHeight + { + get { return (CalendarView.TimeSliceHeight); } + set { CalendarView.TimeSliceHeight = value; } + } + + /// + /// Gets the SlotsPerHour + /// + private int SlotsPerHour + { + get { return (CalendarView.SlotsPerHour); } + } + + /// + /// Gets the NumberOfSlices + /// + private int NumberOfSlices + { + get { return (CalendarView.NumberOfSlices); } + set { CalendarView.NumberOfSlices = value; } + } + + /// + /// Gets the NumberOfActiveSlices + /// + private int NumberOfActiveSlices + { + get { return (CalendarView.NumberOfActiveSlices); } + } + + /// + /// Gets the StartSlice + /// + private int StartSlice + { + get { return (CalendarView.StartSlice); } + set { CalendarView.StartSlice = value; } + } + + #endregion + + #region BusyBrush + + /// + /// Gets and sets the Busy time brush + /// + private Brush BusyBrush + { + get + { + Color color = _ViewColor.GetColor( + (int)eCalendarWeekDayPart.DayAllDayEventBackground); + + if (_BusyColor != color) + { + _BusyColor = color; + + BusyBrush = new SolidBrush(color); + } + + return (_BusyBrush); + } + + set + { + if (_BusyBrush != value) + { + if (_BusyBrush != null) + _BusyBrush.Dispose(); + + _BusyBrush = value; + } + } + } + + #endregion + + #region WorkBrush + + /// + /// Gets and sets the Work time brush + /// + private Brush WorkBrush + { + get + { + Color color = _ViewColor.GetColor( + (int)eCalendarWeekDayPart.DayWorkHoursBackground); + + if (_WorkColor != color) + { + _WorkColor = color; + + WorkBrush = new SolidBrush(color); + } + + return (_WorkBrush); + } + + set + { + if (_WorkBrush != value) + { + if (_WorkBrush != null) + _WorkBrush.Dispose(); + + _WorkBrush = value; + } + } + } + + #endregion + + #region OffWorkBrush + + /// + /// Gets and sets the Off-hours work time brush + /// + private Brush OffWorkBrush + { + get + { + Color color = _ViewColor.GetColor( + (int)eCalendarWeekDayPart.DayOffWorkHoursBackground); + + if (_OffWorkColor != color) + { + _OffWorkColor = color; + + OffWorkBrush = new SolidBrush(color); + } + + return (_OffWorkBrush); + } + + set + { + if (_OffWorkBrush != value) + { + if (_OffWorkBrush != null) + _OffWorkBrush.Dispose(); + + _OffWorkBrush = value; + } + } + } + + #endregion + + #region AllDayBrush + + /// + /// Gets and sets the Off-hours work time brush + /// + private Brush AllDayBrush + { + get + { + Color color = _ViewColor.GetColor( + (int)eCalendarWeekDayPart.DayAllDayEventBackground); + + if (_AllDayColor != color) + { + _AllDayColor = color; + + AllDayBrush = new SolidBrush(color); + } + + return (_AllDayBrush); + } + + set + { + if (_AllDayBrush != value) + { + if (_AllDayBrush != null) + _AllDayBrush.Dispose(); + + _AllDayBrush = value; + } + } + } + + #endregion + + #region SelectedBrush + + /// + /// Gets and sets the selected brush + /// + private Brush SelectedBrush + { + get + { + Color color = _ViewColor.GetColor( + (int)eCalendarWeekDayPart.SelectionBackground); + + if (_SelectedColor != color) + { + _SelectedColor = color; + + SelectedBrush = new SolidBrush(color); + } + + return (_SelectedBrush); + } + + set + { + if (_SelectedBrush != value) + { + if (_SelectedBrush != null) + _SelectedBrush.Dispose(); + + _SelectedBrush = value; + } + } + } + + #endregion + + #region FirstOnScreenSlice + + private int FirstOnScreenSlice + { + get { return ((int)(-_VScrollPos / TimeSliceHeight)); } + } + + #endregion + + #region LastOnScreenSlice + + private int LastOnScreenSlice + { + get { return (FirstOnScreenSlice + OnScreenSlices - 1); } + } + + #endregion + + #region OnScreenSlices + + private int OnScreenSlices + { + get { return ((int)Math.Ceiling(VsPanel.ScrollBar.Height / TimeSliceHeight)); } + } + + #endregion + + #region VsPanel + + /// + /// Gets the WeekDay vertical scroll panel + /// + private VScrollPanel VsPanel + { + get { return (CalendarView.WeekDayVScrollPanel); } + } + + #endregion + + #endregion + + #region Hook / Unhook Events + + /// + /// Routine hooks all necessary events for this control + /// + /// True to hook, false to unhook + private void HookEvents(bool hook) + { + if (hook == true) + { + CalendarView.SelectedViewChanged += SelectedViewChanged; + CalendarView.TimeSlotDurationChanged += TimeSlotDurationChanged; + CalendarView.FixedAllDayPanelHeightChanged += FixedAllDayPanelHeightChanged; + CalendarView.MaximumAllDayPanelHeightChanged += MaximumAllDayPanelHeightChanged; + CalendarView.WeekDayVScrollPanel.ScrollBarChanged += VScrollPanelScrollBarChanged; + + if (this.ECalendarView == eCalendarView.Day) + { + CalendarView.DayViewDateChanged += DayViewDateChanged; + } + else + { + CalendarView.WeekViewStartDateChanged += WeekViewStartDateChanged; + CalendarView.WeekViewEndDateChanged += WeekViewEndDateChanged; + } + } + else + { + CalendarView.SelectedViewChanged -= SelectedViewChanged; + CalendarView.TimeSlotDurationChanged -= TimeSlotDurationChanged; + CalendarView.FixedAllDayPanelHeightChanged -= FixedAllDayPanelHeightChanged; + CalendarView.MaximumAllDayPanelHeightChanged -= MaximumAllDayPanelHeightChanged; + CalendarView.WeekDayVScrollPanel.ScrollBarChanged -= VScrollPanelScrollBarChanged; + + if (this.ECalendarView == eCalendarView.Day) + { + CalendarView.DayViewDateChanged -= DayViewDateChanged; + } + else + { + CalendarView.WeekViewStartDateChanged -= WeekViewStartDateChanged; + CalendarView.WeekViewEndDateChanged -= WeekViewEndDateChanged; + } + } + } + + #endregion + + #region Event handling routines + + #region SelectedViewChanged + + /// + /// Processes view changes + /// + /// object + /// SelectedViewEventArgs + void SelectedViewChanged(object sender, SelectedViewEventArgs e) + { + // Update our IsViewSelected state + + IsViewSelected = (e.NewValue == this.ECalendarView); + + if (IsViewSelected == true) + { + AutoSyncViewDate(e.OldValue); + + UpdateDateSelection(); + } + else + { + ResetView(); + } + + // Update our AllDayPanel view + + _AllDayPanel.UpdateView(); + + } + + #endregion + + #region DayViewDateChanged + + /// + /// Processes DayViewDate changes + /// + /// + /// + void DayViewDateChanged(object sender, DateChangeEventArgs e) + { + StartDate = e.NewValue; + EndDate = e.NewValue; + } + + #endregion + + #region WeekViewStartDateChanged + + /// + /// Processes StartDate changes + /// + /// + /// + void WeekViewStartDateChanged(object sender, DateChangeEventArgs e) + { + StartDate = e.NewValue; + } + + #endregion + + #region WeekViewEndDateChanged + + /// + /// Processes EndDate changes + /// + /// + /// + void WeekViewEndDateChanged(object sender, DateChangeEventArgs e) + { + EndDate = e.NewValue; + } + + #endregion + + #region TimeSlotDurationChanged + + /// + /// Handles TimeSlotDurationChanged events + /// + /// object + /// TimeSlotDurationChangedEventArgs + void TimeSlotDurationChanged( + object sender, TimeSlotDurationChangedEventArgs e) + { + // Reset our slice selection range and + // invalidate our control + + _SelectedSliceStart = 0; + _SelectedSliceEnd = 0; + + NeedRecalcLayout = true; + RecalcSize(); + } + + #endregion + + #region FixedAllDayPanelHeightChanged + + /// + /// Handles FixedAllDayPanelHeightChanged events + /// + /// + /// + void FixedAllDayPanelHeightChanged( + object sender, FixedAllDayPanelHeightChangedEventArgs e) + { + NeedRecalcLayout = true; + } + + #endregion + + #region MaximumAllDayPanelHeightChanged + + /// + /// Handles MaximumAllDayPanelHeightChanged events + /// + /// + /// + void MaximumAllDayPanelHeightChanged( + object sender, MaximumAllDayPanelHeightChangedEventArgs e) + { + NeedRecalcLayout = true; + } + + #endregion + + #region VScrollPanel_ScrollBarChanged + + /// + /// Handles ScrollBarChanged events + /// + /// + /// + void VScrollPanelScrollBarChanged(object sender, EventArgs e) + { + int vdelta = -VsPanel.ScrollBar.Value - _VScrollPos; + + if (vdelta != 0) + { + _VScrollPos = -VsPanel.ScrollBar.Value; + + // Offset our DayColumn accordingly + + for (int i = 0; i < _NumberOfColumns; i++) + { + DayColumn dayColumn = _DayColumns[i]; + + Rectangle r = dayColumn.Bounds; + r.Y += vdelta; + + dayColumn.Bounds = r; + + for (int j = 0; j < dayColumn.CalendarItems.Count; j++) + { + dayColumn.CalendarItems[j].Displayed = + dayColumn.CalendarItems[j].Bounds.IntersectsWith(ClientRect); + } + } + + // Redraw our view + + InvalidateRect(ViewRect); + } + } + + #endregion + + #endregion + + #region GetViewAreaFromPoint + + /// + /// Gets the view area under the given mouse + /// point (tab, header, content, etc) + /// + /// Point + /// eViewArea + public override eViewArea GetViewAreaFromPoint(Point pt) + { + if (Bounds.Contains(pt) == true) + { + if (pt.Y >= ClientRect.Y) + { + if (AllDayPanel.Bounds.Contains(pt)) + return (eViewArea.InAllDayPanel); + + if (pt.Y < ClientRect.Y + DayOfWeekHeaderHeight) + return (eViewArea.InDayOfWeekHeader); + + return (eViewArea.InContent); + } + + return (base.GetViewAreaFromPoint(pt)); + } + + return (eViewArea.NotInView); + } + + #endregion + + #region GetDateSelectionFromPoint + + /// + /// Gets the date selection from the given point. The startDate + /// and endDate will vary based upon the view type (WeekDay / Month) + /// + /// Point in question + /// out start date + /// out end date + /// True if a valid selection exists + /// at the given point + public override bool GetDateSelectionFromPoint( + Point pt, out DateTime startDate, out DateTime endDate) + { + base.GetDateSelectionFromPoint(pt, out startDate, out endDate); + + int col, slice; + + if (GetPointItem(pt, out col, out slice, true) == true) + { + startDate = GetTime(_DayColumns[col].Date, slice, 0); + endDate = startDate.AddMinutes(TimeSlotDuration); + + return (true); + } + + return (false); + } + + #endregion + + #region GetDateBounds + + /// + /// Gets the bounding display rectangle for the given date/time. + /// + /// The date/time + /// Bounding display rectangle + public Rectangle GetDateBounds(DateTime date) + { + int col = GetColumnFromDate(date); + + if (col >= 0) + { + int slice = GetDateSlice(date); + + if (slice >= 0) + return (GetSliceRect(col, slice)); + } + + return (Rectangle.Empty); + } + + /// + /// Gets the bounding display rectangle for the given + /// starting and ending date/time range. + /// + /// Start date + /// End date + /// Bounding display rectangle + public Rectangle GetDateBounds(DateTime startDate, DateTime endDate) + { + Rectangle r1 = GetDateBounds(startDate); + Rectangle r2 = GetDateBounds(endDate); + + return (Rectangle.Union(r1, r2)); + } + + #endregion + + #region IsAllDayItem + + internal bool IsAllDayItem(CalendarItem item) + { + if (item.Equals(SelectedItem) && + (IsEndResizing || IsStartResizing || IsMoving)) + { + return (false); + } + + return (IsAllDayItem(item.StartTime, item.EndTime)); + } + + internal bool IsAllDayItem(Appointment item) + { + if (SelectedItem != null && item.Equals(SelectedItem.ModelItem) && + (IsEndResizing || IsStartResizing || IsMoving)) + { + return (false); + } + + return (IsAllDayItem(item.StartTime, item.EndTime)); + } + + private bool IsAllDayItem(DateTime startTime, DateTime endTime) + { + //if (NumberOfColumns > 1 || + if ( CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None) + { + if ((endTime - startTime).TotalDays >= 1) + return (true); + } + + //if (NumberOfColumns > 1 || + if ( CalendarView.AllDayDisplayMode == eAllDayDisplayMode.ByDayBoundary) + { + return (startTime.Day != endTime.Day || + (endTime - startTime).TotalDays > 1); + } + + return (false); + } + + #endregion + + #region SetSelectedItem + + /// + /// Handles selected item changes + /// + /// CalendarItem + /// EventArgs + internal void ItemIsSelectedChanged(object sender, EventArgs e) + { + CalendarItem ci = sender as CalendarItem; + + if (ci != null) + { + if (ci.IsSelected == true) + { + SelectedItem = SetSelectedItem(SelectedItem, ci); + } + else + { + if (ci == SelectedItem) + SelectedItem = null; + } + } + } + + #region SetSelectedItem + + protected override CalendarItem SetSelectedItem(CalendarItem pci, CalendarItem nci) + { + CalendarItem selItem = null; + + for (int i = 0; i < DayColumns.Length; i++) + selItem = SetSelectedCalendarItem(nci, DayColumns[i].CalendarItems, selItem); + + selItem = SetSelectedCalendarItem(nci, AllDayPanel.CalendarItems, selItem); + + return (selItem); + } + + #region SetSelectedCalendarItem + + private CalendarItem SetSelectedCalendarItem( + CalendarItem nci, List items, CalendarItem selItem) + { + for (int i = 0; i < items.Count; i++) + { + CalendarItem item = items[i]; + + item.IsSelected = (nci != null ? (item.ModelItem == nci.ModelItem) : false); + + if (item.IsSelected == true && selItem == null) + { + selItem = item; + SelectedItem = item; + } + } + + return (selItem); + } + + #endregion + + #endregion + + #endregion + + #region UpdateDateSelection + + #region UpdateDateSelection + + /// + /// Updates our slice selection range to reflect + /// the given date selection start and end values + /// + protected override void UpdateDateSelection() + { + if (IsViewSelected == true) + { + // Get the new absolute slice selection range + + int sliceStart = 0; + int sliceEnd = 0; + + if (DateSelectionStart.HasValue && DateSelectionEnd.HasValue) + { + sliceStart = GetDateSlice(DateSelectionStart); + sliceEnd = GetDateSlice(DateSelectionEnd); + + if (sliceStart < 0 && sliceEnd < 0) + { + sliceStart = 0; + sliceEnd = 0; + } + + if (sliceStart < 0) + sliceStart = 0; + + if (sliceEnd < 0) + sliceEnd = _NumberOfColumns * NumberOfActiveSlices; + } + + // Limit our range to only those slices + // that are visible on the screen + + int s1 = (int)(-_VScrollPos / TimeSliceHeight); + int s2 = (int)(s1 + ViewRect.Height / TimeSliceHeight + 2); + + if (s2 > s1) + { + ProcessSelRange(sliceStart, sliceEnd, s1, s2); + + // Save our new selection range + + _SelectedSliceStart = sliceStart; + _SelectedSliceEnd = sliceEnd; + } + } + } + + #endregion + + #region GetDateSlice + + /// + /// Gets the absolute slice value for the given date + /// + /// Selection date + /// Absolute slice + private int GetDateSlice(DateTime? selDate) + { + if (selDate.HasValue) + return (GetDateSlice(selDate.Value)); + + return (-1); + } + + private int GetDateSlice(DateTime selDate) + { + // Loop through each column + + for (int i = 0; i < _NumberOfColumns; i++) + { + DateTime date = _DayColumns[i].Date; + + // If we have found our containing column, then + // calculate the absolute slice value and return it + + if (selDate >= date && selDate < date.AddDays(1)) + { + int slice = ((selDate.Hour * MinutesPerHour) + selDate.Minute) / TimeSlotDuration; + + return (i * NumberOfActiveSlices + slice - StartSlice); + } + } + + return (-1); + } + + #endregion + + #region ProcessSelRange + + /// + /// Processes the selection time slice range + /// + /// Slice range start + /// Slice range end + /// Slice start limit + /// Slice end limit + private void ProcessSelRange(int sliceStart, int sliceEnd, int s1, int s2) + { + // Calculate our starting and ending column range + + int fcol = Math.Min(_SelectedSliceStart / NumberOfActiveSlices, sliceStart / NumberOfActiveSlices); + int lcol = Math.Max(_SelectedSliceEnd / NumberOfActiveSlices, sliceEnd / NumberOfActiveSlices); + + lcol = Math.Min(_NumberOfColumns - 1, lcol); + + // Loop through each column + + for (int i = fcol; i <= lcol; i++) + { + // Get the selection status for the given range + + bool[] oldSelected = SelectedSlices(s1, s2, i, _SelectedSliceStart, _SelectedSliceEnd); + bool[] newSelected = SelectedSlices(s1, s2, i, sliceStart, sliceEnd); + + // Invalidate those slices whose + // selection status changed + + Rectangle vRect = ViewRect; + + for (int j = 0; j < s2 - s1; j++) + { + if (oldSelected[j] != newSelected[j]) + { + Rectangle r = GetSliceRect(i, s1 + j); + + r.Intersect(vRect); + + if (r.Width > 0 && r.Height > 0) + InvalidateRect(r); + } + } + } + } + + #endregion + + #region SelectedSlices + + /// + /// Gets an array of slice selection values + /// over the given range of column slices + /// + /// Slice start limit + /// Slice end limit + /// Column + /// Slice range start + /// Slice range end + /// Array of selection values + private bool[] SelectedSlices(int s1, int s2, int col, int sliceStart, int sliceEnd) + { + // Calculate our number of entries and + // allocate our IsSelected array accordingly + + int n = s2 - s1; + + bool[] sel = new bool[n + 1]; + + // Loop through the range of entries determining if + // the specific slice is within the selection range + + int slice = col * NumberOfActiveSlices + s1; + + for (int i = 0; i < n; i++) + { + sel[i] = (slice >= sliceStart && slice < sliceEnd); + + slice++; + } + + // Return the array to the caller + + return (sel); + } + + #endregion + + #endregion + + #region RecalcSize routines + + #region RecalcSize + + /// + /// Performs NeedRecalcSize requests + /// + public override void RecalcSize() + { + base.RecalcSize(); + + if (IsViewSelected == true) + { + // Normalize our start and end dates + + DateTime startDate; + DateTime endDate; + + NormalizeDates(out startDate, out endDate); + + if (NeedRecalcLayout == true) + _DayColumnSize = null; + + // Allocate our DayColumns + + AllocateDayColumns(startDate, endDate); + + // Update our Model connection view, + // AllDayPanel, CalendarItems, and DateSelection + + UpdateView(); + + UpdateAllDayPanelItems(); + UpdateDayColumns(startDate, endDate); + UpdateCalendarItems(); + + UpdateDateSelection(); + + // Set our display view rectangle + + Rectangle r = ClientRect; + + r.Y += DayOfWeekHeaderHeight; + r.Height -= DayOfWeekHeaderHeight; + + SetViewRectangle(r); + + // Final Recalc cleanup + + if (DaysOfTheWeek != null) + DaysOfTheWeek.NeedsMeasured = true; + + NeedRecalcLayout = false; + + CalendarView.DoViewLoadComplete(this); + } + } + + #endregion + + #region NormalizeDates + + /// + /// Normalizes the user specified start and end dates + /// + /// [out] Normalized start date + /// [out] Normalized end date + protected virtual void NormalizeDates(out DateTime startDate, out DateTime endDate) + { + startDate = this.StartDate; + endDate = this.EndDate; + } + + #endregion + + #region AllocateDayColumns + + /// + /// Allocates out DayColumns + /// + /// + /// + private void AllocateDayColumns(DateTime startDate, DateTime endDate) + { + // Allocate our DayColumns array to + // hold our info + + _NumberOfColumns = (endDate - startDate).Days + 1; + _NumberOfColumns = Math.Max(_NumberOfColumns, 1); + _NumberOfColumns = Math.Min(_NumberOfColumns, MaxNumberOfColumns); + + if (_DayColumns == null || _DayColumns.Length != _NumberOfColumns) + _DayColumns = new DayColumn[_NumberOfColumns]; + + // Prepare to update display info on each time slot + + Rectangle r = ViewRect; + r.Y += _VScrollPos; + + // Loop through each day column + + float dcWidth = DayColumnWidth; + float x1 = r.X; + + // Update each DayColumn + + for (int i = 0; i < _NumberOfColumns; i++) + { + if (_DayColumns[i] == null) + _DayColumns[i] = new DayColumn(0); + + _DayColumns[i].Date = startDate.AddDays(i); + + float x2 = (i == _NumberOfColumns - 1) ? r.Right - 1 : x1 + dcWidth; + + if (IsLayoutNeeded(i) == true) + _DayColumns[i].Bounds = new Rectangle((int) x1, r.Y, (int) x2 - (int) x1, r.Height); + + x1 = x2; + } + } + + #endregion + + #region UpdateView + + /// + /// Updates our connection model view + /// + private void UpdateView() + { + // If we have had a date range change, just + // reset our entire view + + if (DateRangeChanged == true) + ResetView(); + + // If we have no Model connection, attempt + // to reconnect if this view is selected + + if (Connector == null) + { + if (CalendarModel != null) + { + Connector = new ModelWeekDayViewConnector(CalendarModel, this); + + SubItems.Insert(0, _AllDayPanel); + } + } + } + + #endregion + + #region ResetView + + /// + /// Disconnects and resets the Model connection + /// + internal override void ResetView() + { + _AllDayPanel.ResetView(); + + base.ResetView(); + } + + #endregion + + #region UpdateAllDayPanelItems + + /// + /// Updates our AllDayPanel items + /// + private void UpdateAllDayPanelItems() + { + if (NeedRecalcLayout == true) + { + // Initiate a RecalcSize for the panel + + _AllDayPanel.WidthInternal = ClientRect.Width; + _AllDayPanel.HeightInternal = MaximumAllDayPanelHeight; + + _AllDayPanel.RecalcSize(); + + // Set the panel's bounding rect accordingly + + Rectangle r = ClientRect; + + r.Width = _AllDayPanel.WidthInternal; + + r.Y += DayOfWeekHeaderHeight; + r.Height = _AllDayPanel.HeightInternal; + + _AllDayPanel.Bounds = r; + } + } + + private bool IsLayoutNeeded(int col) + { + return (NeedRecalcLayout == true || + _DayColumns[col].NeedRecalcLayout == true); + } + + #endregion + + #region UpdateDayColumns + + /// + /// Calculates and updates DayColumn bounds + /// + /// Start date + /// End date + protected void UpdateDayColumns(DateTime startDate, DateTime endDate) + { + // Establish our current TimeSlice range + + GetTimeSliceData(); + + // Updating display info on each column + + Rectangle r = ViewRect; + + r.Y += _VScrollPos; + r.Height = (int) (TimeSliceHeight * NumberOfSlices); + + for (int i = 0; i < _NumberOfColumns; i++) + { + _DayColumns[i].TimeSliceHeight = TimeSliceHeight; + + if (IsLayoutNeeded(i) == true) + { + _DayColumns[i].Bounds = new + Rectangle(_DayColumns[i].Bounds.X, r.Y, _DayColumns[i].Bounds.Width, r.Height); + + InvalidateRect(_DayColumns[i].Bounds); + } + } + } + + #region GetTimeSliceData + + private void GetTimeSliceData() + { + _LocalStartSlice = 0; + _LocalNumberOfSlices = (HoursPerDay * MinutesPerHour) / TimeSlotDuration + 1; + + if (CalendarView.ShowOnlyWorkDayHours == true) + { + WorkTime startTime = new WorkTime(23, 59); + WorkTime endTime = new WorkTime(0, 0); + + for (int i = 0; i < NumberOfColumns; i++) + { + DayColumn dc = _DayColumns[i]; + + if (dc.WorkStartTime.IsEmpty == false || dc.WorkEndTime.IsEmpty == false) + { + if (dc.WorkStartTime <= dc.WorkEndTime) + { + if (dc.WorkStartTime < startTime) + startTime = dc.WorkStartTime; + + if (dc.WorkEndTime > endTime) + endTime = dc.WorkEndTime; + } + else + { + startTime = new WorkTime(0, 0); + endTime = new WorkTime(23, 59); + + break; + } + } + } + + if (endTime > startTime) + { + int startMinutes = (startTime.Hour * MinutesPerHour) + startTime.Minute; + int endMinutes = (endTime.Hour * MinutesPerHour) + endTime.Minute; + + _LocalStartSlice = startMinutes / TimeSlotDuration; + _LocalNumberOfSlices = (endMinutes - startMinutes) / TimeSlotDuration + 1; + } + + if (StartSlice >= 0) + { + int endSlice = _LocalStartSlice + _LocalNumberOfSlices - 1; + + if (_LocalStartSlice > StartSlice) + _LocalStartSlice = StartSlice; + + if (StartSlice + NumberOfSlices > endSlice) + endSlice = StartSlice + NumberOfSlices - 1; + + _LocalNumberOfSlices = endSlice - _LocalStartSlice + 1; + } + } + + StartSlice = _LocalStartSlice; + NumberOfSlices = _LocalNumberOfSlices; + + TimeSliceHeight = (float)ViewRect.Height / NumberOfActiveSlices; + } + + #endregion + + #endregion + + #region UpdateCalendarItems + + /// + /// Updates our CalendarItems list + /// + private void UpdateCalendarItems() + { + List list = new List(); + + for (int i = 0; i < _NumberOfColumns; i++) + { + if (IsLayoutNeeded(i) == true) + { + if (_DayColumns[i].CalendarItems.Count > 0) + { + List items = SortCalendarItems(i); + + list.Clear(); + + for (int j = 0; j < items.Count; j++) + { + ColumnList colList = GetColList(list, items[j]); + + colList.AddColumnSlot(items[j], 0); + } + + foreach (ColumnList colList in list) + colList.CountColumns(); + + CalcAppointmentBounds(i, list); + } + + _DayColumns[i].NeedRecalcLayout = false; + } + } + } + + #region GetColList + + private ColumnList GetColList(List list, CalendarItem item) + { + int id = CalendarView.DoGetAppointmentGroupId(item, -1); + + int index; + if (GetColListIndex(list, id, out index) == true) + return (list[index]); + + ColumnList clist = new ColumnList(id); + + if (index < list.Count) + list.Insert(index, clist); + else + list.Add(clist); + + return (clist); + } + + #region GetColListIndex + + private bool GetColListIndex(List list, int id, out int index) + { + for (index=0; index < list.Count; index++) + { + ColumnList colList = list[index]; + + if (colList.Id == id) + return (true); + + if (colList.Id > id) + break; + } + + return (false); + } + + #endregion + + #endregion + + #region SortCalendarItems + + /// + /// Sorts the DayColumn CalendarItem list + /// + /// DayColumn index + private List SortCalendarItems(int col) + { + List items = new List(); + + items.AddRange(_DayColumns[col].CalendarItems); + + if (items.Count > 0) + { + items.Sort( + + delegate(CalendarItem c1, CalendarItem c2) + { + if (c1.StartTime > c2.StartTime) + return (1); + + if (c1.StartTime < c2.StartTime) + return (-1); + + if (c1.EndTime - c1.StartTime > c2.EndTime - c2.StartTime) + return (1); + + if (c1.EndTime - c1.StartTime < c2.EndTime - c2.StartTime) + return (-1); + + int result = 0; + CalendarView.DoDetailSortEvent(this, c1, c2, ref result); + + return (result); + } + ); + } + + return (items); + } + + #endregion + + #region CalcAppointmentBounds + + /// + /// Calculates normal appointment bounds + /// + /// DayColumn column + /// Accumulated ColumnList + private void CalcAppointmentBounds(int col, List list) + { + Rectangle r = _DayColumns[col].Bounds; + + r.X++; + r.Width -= 8; + + for (int k = 0; k < list.Count; k++) + { + ColumnList colList = list[k]; + + Rectangle r3 = r; + float dx3 = (float)r3.Width / list.Count; + + r3.X += (int)(dx3 * k); + r3.Width = (int)dx3; + + for (int i = 0; i < colList.SList.Count; i++) + { + for (int j = 0; j < colList.SList[i].Count; j++) + { + Rectangle r2 = r3; + SlotItem si = colList.SList[i][j]; + CalendarItem item = si.CItem; + + float dx = (float)r2.Width / si.Count; + r2.X += (int)(dx * i); + + if (si.SList != null && si.SList.Count == 1) + r2.Width = (int)(dx * (si.SList[0].Column - si.Column)); + + else if (si.SList == null) + r2.Width = r3.Width - (r2.X - r3.X); + + else + r2.Width = (int)dx; + + DateTime startTime = item.StartTime; + + if (startTime.Date < _DayColumns[col].Date) + startTime = _DayColumns[col].Date; + + DateTime endTime = item.EndTime; + + if (endTime > _DayColumns[col].Date.AddDays(1)) + endTime = _DayColumns[col].Date.AddDays(1); + + DateTime date = startTime.Date; + + TimeSpan ts1 = startTime.AddMinutes(-StartSlice * TimeSlotDuration) - date; + TimeSpan ts2 = endTime - startTime; + + int pos = (int)(ts1.TotalMinutes / TimeSlotDuration * TimeSliceHeight); + int height = (int)Math.Round(ts2.TotalMinutes / TimeSlotDuration * TimeSliceHeight); + + AppointmentView view = item as AppointmentView; + + if (view != null) + { + Font font = view.Font ?? CalendarView.Font; + + if (font != null) + height = Math.Max(font.Height + 6, height); + } + + r2.Y = r.Y + (int)pos; + r2.Height = height; + + // Now that we have calculated the items height and + // width, invoke a Recalc on the item + + item.WidthInternal = r2.Width; + item.HeightInternal = r2.Height - 1; + + item.RecalcSize(); + + // Set our bounds for the item + + r2.Width = item.WidthInternal; + r2.Height = item.HeightInternal; + + if (item.Bounds != r2) + { + InvalidateRect(item.Bounds); + InvalidateRect(r2); + } + + item.Bounds = r2; + + // Set it's display state + + item.Displayed = r2.IntersectsWith(ClientRect); + } + } + } + } + + #endregion + + #endregion + + #endregion + + #region Paint processing + + #region Root paint code + + /// + /// Paint processing + /// + /// ItemPaintArgs + public override void Paint(ItemPaintArgs e) + { + Graphics g = e.Graphics; + + // Set our current color table + + _ViewColor.SetColorTable(); + + // Only draw something if we have something to draw + + if (_DayColumns != null) + { + // Calculate our drawing ranges + + int dayStart, dayEnd; + int sliceStart, sliceEnd; + + int dayCount = GetDayRange(e, out dayStart, out dayEnd); + int sliceCount = GetSliceRange(e, out sliceStart, out sliceEnd); + + // Draw our calendar parts + + if (dayCount > 0) + DrawDayOfTheWeekHeader(e, dayStart, dayEnd); + + if (sliceCount > 0 && dayCount > 0) + { + // Set our clipping region + + Rectangle r = ViewRect; + + r.X = ClientRect.X; + r.Width = ClientRect.Width; + + Region regSave = g.Clip; + g.SetClip(r, CombineMode.Intersect); + + // Draw our slices and appointments + + DrawSlices(e, sliceStart, sliceEnd, dayStart, dayEnd); + DrawTimeIndicators(g, sliceStart, sliceEnd, eTimeIndicatorLevel.Bottom); + + if (Connector != null && Connector.IsConnected) + DrawWeekAppointments(e, dayStart, dayEnd); + + DrawTimeIndicators(g, sliceStart, sliceEnd, eTimeIndicatorLevel.Top); + + // Restore our original clip region + + g.Clip = regSave; + } + + // Initiate the painting of our AllDay Panel + + _AllDayPanel.Paint(e); + + // Update our Alt-Key window + + UpdatePosWin(ViewRect); + } + + // Let the base painting take place + + base.Paint(e); + } + + #region Clip range routines + + /// + /// Calculates the range of days needed to be drawn + /// to satisfy the specified paint request + /// + /// ItemPaintArgs + /// [out] Day start index + /// [out] Day end index + /// Day range count (end - start) + private int GetDayRange(ItemPaintArgs e, out int dayStart, out int dayEnd) + { + // Calc our starting index + + int start = 0; + + while (start < _NumberOfColumns) + { + if (_DayColumns[start].Bounds.Right > e.ClipRectangle.X) + break; + + start++; + } + + // Calc our ending index + + int end = start; + + while (end < _NumberOfColumns) + { + if (_DayColumns[end].Bounds.X >= e.ClipRectangle.Right) + break; + + end++; + } + + // Set the user supplied 'out' values, and + // return the range count to the caller + + if (end - start == 0) + { + dayStart = 0; + dayEnd = 0; + + return (0); + } + + dayStart = start; + dayEnd = end - 1; + + return (end - start); + } + + /// + /// Calculates the range of slices needed to be drawn + /// to satisfy the specified paint request + /// + /// ItemPaintArgs + /// [out] Slice start index + /// [out] Slice end index + /// Slice range count (end - start) + internal int GetSliceRange(ItemPaintArgs e, out int sliceStart, out int sliceEnd) + { + // Calc our starting index + + int start = 0; + + Rectangle v = ViewRect; + + while (start < NumberOfSlices) + { + Rectangle r = GetSliceRect(0, start); + + if (r.Bottom > v.Top) + { + if (r.Bottom > e.ClipRectangle.Y) + break; + } + + start++; + } + + // Calc our ending index + + int end = start; + + while (end < NumberOfSlices) + { + Rectangle r = GetSliceRect(0, end); + + if (r.Y >= e.ClipRectangle.Bottom) + break; + + end++; + } + + // Set the user supplied 'out' values, and + // return the range count to the caller + + if (end - start == 0) + { + sliceStart = 0; + sliceEnd = 0; + + return (0); + } + + sliceStart = start; + sliceEnd = end - 1; + + return (end - start); + } + + private bool SliceIsSelected(int col, int slice) + { + int nslice = col * NumberOfActiveSlices + slice; + + return (nslice >= _SelectedSliceStart && nslice < _SelectedSliceEnd); + } + + #endregion + + #endregion + + #region DayOfTheWeek header drawing + + #region DrawDayOfTheWeekHeader + + /// + /// Draws the top Day of the week header + /// + /// ItemPaintArgs + /// Start day index + /// End day index + private void DrawDayOfTheWeekHeader(ItemPaintArgs e, int dayStart, int dayEnd) + { + Graphics g = e.Graphics; + + Rectangle r = new Rectangle( + _DayColumns[dayStart].Bounds.X, ClientRect.Y, + _DayColumns[dayEnd].Bounds.Right - + _DayColumns[dayStart].Bounds.X, DayOfWeekHeaderHeight); + + if (r.Width > 0 && r.Height > 0) + { + // Establish our Days Of The Week text type + + DaysOfTheWeek.eDayType type = GetDaysOfTheWeekType(g); + + // Loop through each day, drawing the + // day of the week text in the header area + + int nowHeader = -1; + + using (Brush br = + _ViewColor.BrushPart((int) eCalendarWeekDayPart.DayHeaderBackground, r)) + { + using (Pen pen = new Pen( + _ViewColor.GetColor((int) eCalendarWeekDayPart.DayHeaderBorder))) + { + for (int i = dayStart; i <= dayEnd; i++) + { + if (CalendarView.HighlightCurrentDay == true && + _DayColumns[i].Date.Date.Equals(DateTime.Now.Date)) + { + nowHeader = i; + continue; + } + + DrawColumnHeader(g, i, type, r, br, pen, eCalendarWeekDayPart.DayHeaderForeground); + } + } + } + + // Draw the current "Now" header + + if (nowHeader >= 0) + { + using (Brush br = + _ViewColor.BrushPart((int) eCalendarWeekDayPart.NowDayHeaderBackground, r)) + { + using (Pen pen = new Pen( + _ViewColor.GetColor((int) eCalendarWeekDayPart.NowDayHeaderBorder))) + { + DrawColumnHeader(g, nowHeader, type, r, br, pen, eCalendarWeekDayPart.NowDayHeaderForeground); + } + } + } + } + } + + #region DrawColumnHeader + + /// + /// DrawColumnHeader + /// + /// + /// + /// + /// + /// + /// + /// + private void DrawColumnHeader(Graphics g, int i, + DaysOfTheWeek.eDayType type, Rectangle r, Brush br, Pen pen, eCalendarWeekDayPart part) + { + r.X = _DayColumns[i].Bounds.X; + r.Width = _DayColumns[i].Bounds.Width; + + g.FillRectangle(br, r); + g.DrawRectangle(pen, r); + + Rectangle t = r; + + if (CalendarView.DoPreRenderWeekDayHeader(g, this, i, t) == false) + { + // Draw the header text + + int n = i % DaysInWeek; + + eTextFormat tf = eTextFormat.VerticalCenter | eTextFormat.NoPadding; + + r.Inflate(-2, 0); + r.X += 1; + + TextDrawing.DrawString(g, + _DayColumns[i].Date.Day.ToString(), BoldFont, Color.Black, r, tf); + + r.X += _DayColumnSize[n].Width; + r.Width -= _DayColumnSize[n].Width; + + if (type != DaysOfTheWeek.eDayType.None) + { + tf |= eTextFormat.HorizontalCenter; + + TextDrawing.DrawString(g, DaysOfTheWeek.DayText[(int) type][n], + Font, _ViewColor.GetColor((int) part), r, tf); + } + + CalendarView.DoPostRenderWeekDayHeader(g, this, i, t); + } + } + + #endregion + + #endregion + + #region GetDaysOfTheWeekType + + /// + /// Get the index for our day of the week text + /// + /// Graphics handle + /// Index to header text + private DaysOfTheWeek.eDayType GetDaysOfTheWeekType(Graphics g) + { + // Resize our DayColumn day text if it + // hasn't been resized previously + + if (_DayColumnSize == null) + { + _DayColumnSize = new Size[_NumberOfColumns]; + + for (int i = 0; i < _NumberOfColumns; i++) + { + _DayColumnSize[i] = TextDrawing.MeasureString(g, + _DayColumns[i].Date.Day.ToString(), BoldFont, 0, eTextFormat.NoPadding); + } + } + + // Determine if the current DayRect bounds + // are constrained by the text threshold + + DaysOfTheWeek.MeasureText(g, Font); + + for (int i = 0; i < _NumberOfColumns; i++) + { + if (_DayColumns[i].Bounds.Width < + _DayColumnSize[i].Width + DaysOfTheWeek.DaySize[(int)DaysOfTheWeek.eDayType.Short][i % 7].Width) + { + return (DaysOfTheWeek.eDayType.None); + } + } + + for (int i = 0; i < _NumberOfColumns; i++) + { + if (_DayColumns[i].Bounds.Width < + _DayColumnSize[i].Width + DaysOfTheWeek.DaySize[(int)DaysOfTheWeek.eDayType.Long][i % 7].Width) + { + return (DaysOfTheWeek.eDayType.Short); + } + } + + return (DaysOfTheWeek.eDayType.Long); + } + + #endregion + + #endregion + + #region DrawSlices + + #region DrawSlices + + /// + /// Draws Normal Appointment time slices + /// + /// ItemPaintArgs + /// Start slice + /// End slice + /// Day start + /// Day end + private void DrawSlices(ItemPaintArgs e, + int sliceStart, int sliceEnd, int dayStart, int dayEnd) + { + Graphics g = e.Graphics; + + DaySlot[,] daySlots = GetDaySlots(sliceStart, sliceEnd, dayStart, dayEnd); + + DrawContent(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots); + DrawDaySlot(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots, false); + + DrawBorders(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots); + DrawDaySlot(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots, true); + } + + #endregion + + #region GetDaySlots + + /// + /// Gets the array of DaySlot information + /// + /// + /// + /// + /// + /// array of DaySlots + private DaySlot[,] GetDaySlots(int sliceStart, int sliceEnd, int dayStart, int dayEnd) + { + DaySlot[,] daySlots = new DaySlot[dayEnd - dayStart + 1, sliceEnd - sliceStart + 1]; + + for (int i = dayStart; i <= dayEnd; i++) + { + for (int j = sliceStart; j <= sliceEnd; j++) + { + DaySlot daySlot = new DaySlot(); + + daySlots[i - dayStart, j - sliceStart] = daySlot; + + daySlot.Bounds = GetSliceRect(i, j); + daySlot.Selected = SliceIsSelected(i, j); + + if (j <= sliceEnd && + CalendarView.HasViewDisplayCustomizations == true) + { + int start = ((StartSlice + j) * TimeSlotDuration) % 1440; + int end = Math.Min(start + TimeSlotDuration, 1439); + + WorkTime wkStart = new WorkTime(start / MinutesPerHour, start % MinutesPerHour); + WorkTime wkEnd = new WorkTime(end / MinutesPerHour, end % MinutesPerHour); + + daySlot.Appearance = CalendarView.ViewDisplayCustomizations.GetDaySlotAppearance( + OwnerKey, _DayColumns[i].Date, wkStart, wkEnd); + } + } + } + + return (daySlots); + } + + #endregion + + #region DrawContent + + /// + /// Time slice content drawing + /// + /// Graphics + /// Start slice + /// End slice + /// Day start + /// Day end + /// + private void DrawContent(Graphics g, + int sliceStart, int sliceEnd, int dayStart, int dayEnd, DaySlot[,] daySlots) + { + // Loop through each day in each week, displaying + // the associated day content + + for (int i = dayStart; i <= dayEnd; i++) + { + for (int j = sliceStart; j <= sliceEnd; j++) + { + DaySlot daySlot = daySlots[i - dayStart, j - sliceStart]; + DaySlotAppearance dsa = daySlot.Appearance; + + if (CalendarView.DoPreRenderWeekDaySlotBackground(g, this, i, j, daySlot.Bounds) == false) + { + if (dsa != null && daySlot.Selected == false) + { + using (Brush br = new SolidBrush(dsa.BackColor)) + g.FillRectangle(br, daySlot.Bounds); + + continue; + } + + g.FillRectangle(GetContentBrush(daySlot, i, j), daySlot.Bounds); + } + + CalendarView.DoPostRenderWeekDaySlotBackground(g, this, i, j, daySlot.Bounds); + } + } + } + + #region GetContentBrush + + /// + /// Gets the background content brush + /// for the given time slice + /// + /// + /// Column index + /// Time slice + /// Background brush + private Brush GetContentBrush(DaySlot daySlot, int col, int slice) + { + int start = (StartSlice + slice) * TimeSlotDuration; + + if (slice < NumberOfActiveSlices) + { + if (daySlot.Selected == true) + return (SelectedBrush); + + WorkTime wkStart = new + WorkTime(start / MinutesPerHour, start % MinutesPerHour); + + if (_DayColumns[col].IsWorkTime(wkStart) == true) + return (WorkBrush); + + if (_DayColumns[col].IsBusyTime(wkStart) == true) + return (BusyBrush); + } + else + { + return (AllDayBrush); + } + + return (OffWorkBrush); + } + + #endregion + + #endregion + + #region DrawDaySlot + + /// + /// Initiates DaySlot drawing + /// + /// + /// + /// + /// + /// + /// + /// On top of borders + private void DrawDaySlot(Graphics g, int sliceStart, + int sliceEnd, int dayStart, int dayEnd, DaySlot[,] daySlots, bool onTop) + { + List dsaList = null; + Rectangle dRect = Rectangle.Empty; + + for (int i = dayStart; i <= dayEnd; i++) + { + DaySlot lastDaySlot = null; + + for (int j = sliceStart; j <= sliceEnd; j++) + { + DaySlot daySlot = daySlots[i - dayStart, j - sliceStart]; + + Rectangle r = daySlot.Bounds; + DaySlotAppearance dsa = daySlot.Appearance; + + if (lastDaySlot != null && + (lastDaySlot.Appearance != dsa || lastDaySlot.Selected != daySlot.Selected)) + { + FlushDaySlotText(g, i, dsaList, ref dRect, lastDaySlot.Selected); + } + + lastDaySlot = daySlot; + + if (dsa != null) + { + if (dsa.OnTop == onTop) + { + if (daySlot.Selected == true) + { + if (dsa.ShowTextWhenSelected == true) + dRect = dRect.IsEmpty ? r : Rectangle.Union(dRect, r); + } + else + { + dRect = dRect.IsEmpty ? r : Rectangle.Union(dRect, r); + } + + if (dsaList == null) + dsaList = new List(); + + if (dsaList.Contains(dsa) == false) + dsaList.Add(dsa); + } + + continue; + } + } + + if (lastDaySlot != null) + FlushDaySlotText(g, i, dsaList, ref dRect, lastDaySlot.Selected); + } + } + + #region FlushDaySlotText + + /// + /// Flushes out pending DaySlot drawing + /// + /// + /// + /// + /// Display rect + /// + private void FlushDaySlotText(Graphics g, + int dayCol, List dsaList, ref Rectangle dRect, bool selected) + { + if (dsaList != null && dsaList.Count > 0) + { + if (dRect.IsEmpty == false) + DrawDaySlotText(g, dayCol, dsaList, dRect, selected); + + dsaList.Clear(); + + dRect = Rectangle.Empty; + } + } + + #endregion + + #region DrawDaySlotText + + /// + /// Draws the DaySlot Text + /// + /// + /// + /// + /// + /// + private void DrawDaySlotText(Graphics g, + int dayCol, IEnumerable dsaList, Rectangle cRect, bool selected) + { + foreach (DaySlotAppearance dsa in dsaList) + { + DateTime startTime = GetSlotTime(dayCol, dsa.StartTime); + DateTime endTime = GetSlotTime(dayCol, dsa.EndTime); + + DateTime e = endTime.AddMinutes(-1); + WorkTime wkEnd = new WorkTime(e.Hour, e.Minute); + + int start = GetWorkTimeSlice(dsa.StartTime); + int end = GetWorkTimeSlice(wkEnd); + + Rectangle r = GetSliceRect(dayCol, start); + r = Rectangle.Union(r, GetSliceRect(dayCol, end)); + + Region rgnSave = g.Clip; + g.SetClip(cRect, CombineMode.Intersect); + + string text = dsa.Text; + + if (CalendarView.DoRenderDaySlotAppearanceText(g, + r, dsa, startTime, endTime, selected, ref text) == false) + { + if (String.IsNullOrEmpty(dsa.Text) == false) + { + eTextFormat tf = GetTextFormat(dsa.TextAlignment); + + Font font = dsa.Font ?? Font; + + Color color = (selected == true) + ? (dsa.SelectedTextColor.IsEmpty ? Color.Black : dsa.SelectedTextColor) + : (dsa.TextColor.IsEmpty ? Color.Black : dsa.TextColor); + + TextDrawing.DrawString(g, text, font, color, r, tf); + } + } + + g.Clip = rgnSave; + } + } + + #region GetSlotTime + + private DateTime GetSlotTime(int dayCol, WorkTime wkTime) + { + DateTime time = _DayColumns[dayCol].Date; + + time = time.AddHours(wkTime.Hour); + time = time.AddMinutes(wkTime.Minute); + + return (time); + } + + #endregion + + #region GetWorkTimeSlice + + private int GetWorkTimeSlice(WorkTime wkTime) + { + int slice = ((wkTime.Hour * MinutesPerHour) + + wkTime.Minute) / TimeSlotDuration; + + return (slice - StartSlice); + } + + #region GetTextFormat + + private eTextFormat GetTextFormat(ContentAlignment alignment) + { + eTextFormat tf = eTextFormat.WordBreak; + + switch (alignment) + { + case ContentAlignment.TopLeft: + tf |= eTextFormat.Top | eTextFormat.Left; + break; + + case ContentAlignment.TopCenter: + tf |= eTextFormat.Top | eTextFormat.HorizontalCenter; + break; + + case ContentAlignment.TopRight: + tf |= eTextFormat.Top | eTextFormat.Right; + break; + + case ContentAlignment.MiddleLeft: + tf |= eTextFormat.VerticalCenter | eTextFormat.Left; + break; + + case ContentAlignment.MiddleCenter: + tf |= eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter; + break; + + case ContentAlignment.MiddleRight: + tf |= eTextFormat.VerticalCenter | eTextFormat.Right; + break; + + case ContentAlignment.BottomLeft: + tf |= eTextFormat.Bottom | eTextFormat.Left; + break; + + case ContentAlignment.BottomCenter: + tf |= eTextFormat.Bottom | eTextFormat.HorizontalCenter; + break; + + case ContentAlignment.BottomRight: + tf |= eTextFormat.Bottom | eTextFormat.Right; + break; + } + + return (tf); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region DrawTimeIndicators + + #region DrawTimeIndicators + + /// + /// Draw view TimeIndicators + /// + /// + /// + /// + private void DrawTimeIndicators(Graphics g, + int sliceStart, int sliceEnd, eTimeIndicatorLevel level) + { + DateTime start = _DayColumns[0].Date; + DateTime end = _DayColumns[_NumberOfColumns - 1].Date.AddDays(1); + Rectangle r = Rectangle.Union(GetSliceRect(0, sliceStart), GetSliceRect(0, sliceEnd)); + + for (int i = 0; i < CalendarView.TimeIndicators.Count; i++) + { + TimeIndicator ti = CalendarView.TimeIndicators[i]; + + if (ti.IndicatorLevel == level) + { + if (ti.IndicatorArea == eTimeIndicatorArea.All || + ti.IndicatorArea == eTimeIndicatorArea.Content) + { + if (ti.IsVisible(CalendarView, this)) + { + DateTime time = ti.IndicatorDisplayTime; + + if (time >= start && time < end) + DrawTimeIndicator(g, r, ti); + } + } + } + } + } + + #endregion + + #region DrawTimeIndicator + + #region DrawTimeIndicator + + /// + /// Draws individual view TimeIndicator + /// + /// + /// + /// + private void DrawTimeIndicator(Graphics g, Rectangle sRect, TimeIndicator ti) + { + Rectangle r = GetIndicatorRect(ti); + + if (r.IntersectsWith(sRect) == true) + { + if (r.Height > 0) + { + ColorDef cdef = GetIndicatorColor(ti); + + if (cdef != null) + { + using (Brush br = _ViewColor.BrushPart(cdef, r)) + { + if (br is LinearGradientBrush) + ((LinearGradientBrush) br).WrapMode = WrapMode.TileFlipX; + + g.FillRectangle(br, r); + } + } + } + + Color color = GetIndicatorBorder(ti); + + if (color.IsEmpty == false) + { + using (Pen pen = new Pen(color)) + g.DrawLine(pen, r.X + 1, r.Bottom, r.Right - 1, r.Bottom); + } + } + } + + #endregion + + #region GetIndicatorRect + + /// + /// Gets the TimeIndicator rectangle + /// + /// + /// + internal override Rectangle GetIndicatorRect(TimeIndicator ti) + { + return (GetIndicatorRect(ti, ti.IndicatorDisplayTime)); + } + + /// + /// Gets the TimeIndicator rectangle for the + /// given DataTime + /// + /// + /// + /// + internal override Rectangle GetIndicatorRect(TimeIndicator ti, DateTime time) + { + DateTime startTime = GetTime(_DayColumns[0].Date, 0, 0); + DateTime endTime = GetTime(_DayColumns[NumberOfColumns - 1].Date, NumberOfActiveSlices, 0); + + if (time >= startTime && time < endTime) + { + int offset = (int) (time.Hour * SlotsPerHour * TimeSliceHeight + + (TimeSliceHeight * time.Minute) / TimeSlotDuration); + + offset -= (int) (StartSlice * TimeSliceHeight); + + Rectangle r = ViewRect; + r.Width -= 1; + + r.Y = _DayColumns[0].Bounds.Y + offset - ti.Thickness; + r.Height = ti.Thickness; + + return (r); + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetIndicatorColor + + /// + /// Gets the Indicator Back color + /// + /// + /// + private ColorDef GetIndicatorColor(TimeIndicator ti) + { + ColorDef cdef = ti.IndicatorColor; + + if (cdef == null || cdef.IsEmpty == true) + cdef = _ViewColor.GetColorDef((int)eCalendarWeekDayPart.TimeIndicator); + + return (cdef); + } + + #endregion + + #region GetIndicatorBorder + + /// + /// Gets the Indicator Border color + /// + /// + /// + private Color GetIndicatorBorder(TimeIndicator ti) + { + return (ti.BorderColor.IsEmpty == false ? ti.BorderColor : + _ViewColor.GetColor((int)eCalendarWeekDayPart.TimeIndicatorBorder)); + } + + #endregion + + #endregion + + #endregion + + #region DrawBorders + + #region DrawBorders + + /// + /// Draws time slice borders + /// + /// Graphics + /// Start slice + /// End slice + /// Day start + /// Day end + /// + private void DrawBorders(Graphics g, + int sliceStart, int sliceEnd, int dayStart, int dayEnd, DaySlot[,] daySlots) + { + // Draw the horizontal and vertical borders, and + // the current "Now" border + + DrawHorizontalBorders(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots); + DrawVerticalBorders(g, sliceStart, sliceEnd, dayStart, dayEnd); + + if (CalendarView.HighlightCurrentDay == true) + DrawNowBorder(g, dayStart, dayEnd); + } + + #endregion + + #region DrawHorizontalBorders + + /// + /// Draws horizontal borders + /// + /// + /// + /// + /// + /// + /// + private void DrawHorizontalBorders(Graphics g, + int sliceStart, int sliceEnd, int dayStart, int dayEnd, DaySlot[,] daySlots) + { + if (CalendarView.HasViewDisplayCustomizations == true) + { + int n = MinutesPerHour / TimeSlotDuration; + + Color hourBorderColor = _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHourBorder); + Color halfHourBorderColor = _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHalfHourBorder); + + for (int i = dayStart; i <= dayEnd; i++) + { + for (int j = sliceStart; j <= sliceEnd; j++) + { + DaySlot daySlot = daySlots[i - dayStart, j - sliceStart]; + + Rectangle r = daySlot.Bounds; + DaySlotAppearance dsa = daySlot.Appearance; + + Point pt1 = r.Location; + Point pt2 = new Point(r.Right - 1, r.Y); + + if (dsa != null && daySlot.Selected == false) + { + using (Pen pen = new Pen(j % n == 0 ? dsa.HourBorderColor : dsa.HalfHourBorderColor)) + g.DrawLine(pen, pt1, pt2); + + continue; + } + + using (Pen pen = new Pen(j % n == 0 ? hourBorderColor : halfHourBorderColor)) + g.DrawLine(pen, pt1, pt2); + } + } + } + else + { + using (Pen pen1 = new Pen( + _ViewColor.GetColor((int) eCalendarWeekDayPart.DayHourBorder))) + { + using (Pen pen2 = new Pen( + _ViewColor.GetColor((int) eCalendarWeekDayPart.DayHalfHourBorder))) + { + Point pt1 = new Point(_DayColumns[dayStart].Bounds.X, 0); + Point pt2 = new Point(_DayColumns[dayEnd].Bounds.Right - 1, 0); + + int n = MinutesPerHour/TimeSlotDuration; + + for (int i = sliceStart; i <= sliceEnd; i++) + { + Rectangle r = GetSliceRect(0, i); + + pt1.Y = pt2.Y = r.Y; + + g.DrawLine((i%n) == 0 ? pen1 : pen2, pt1, pt2); + } + } + } + } + } + + #endregion + + #region DrawVerticalBorders + + /// + /// Draws the vertical borders + /// + /// + /// + /// + /// + /// + private void DrawVerticalBorders(Graphics g, + int sliceStart, int sliceEnd, int dayStart, int dayEnd) + { + Rectangle r1 = GetSliceRect(0, sliceStart); + Rectangle r2 = GetSliceRect(0, sliceEnd); + + using (Pen pen1 = new Pen( + _ViewColor.GetColor((int)eCalendarWeekDayPart.DayViewBorder))) + { + Point pt1 = new Point(0, r1.Y); + Point pt2 = new Point(0, r2.Bottom); + + for (int i = dayStart; i <= dayEnd; i++) + { + pt1.X = pt2.X = _DayColumns[i].Bounds.X; + + g.DrawLine(pen1, pt1, pt2); + } + + pt1.X = pt2.X = _DayColumns[dayEnd].Bounds.Right; + + g.DrawLine(pen1, pt1, pt2); + } + } + + #endregion + + #region DrawNowBorder + + /// + /// Draws the Current-Day Now border + /// + /// + /// + /// + private void DrawNowBorder(Graphics g, int dayStart, int dayEnd) + { + // Draw the "Current" day border + + for (int i = dayStart; i <= dayEnd; i++) + { + if (_DayColumns[i].Date.Date.Equals(DateTime.Now.Date)) + { + Rectangle r = _DayColumns[i].Bounds; + + using (Pen pen = new Pen( + _ViewColor.GetColor((int)eCalendarWeekDayPart.NowDayHeaderBorder))) + { + g.DrawRectangle(pen, r); + } + break; + } + } + } + + #endregion + + #endregion + + #endregion + + #region DrawWeekAppointments + + /// + /// Initiates the drawing of weekly appointments + /// + /// ItemPaintArgs + /// Day start index + /// Day end index + private void DrawWeekAppointments(ItemPaintArgs e, int dayStart, int dayEnd) + { + if (e.ClipRectangle.IntersectsWith(ViewRect) == true) + { + // Loop through each day in each week, displaying + // the associated day content + + List selItems = null; + + for (int i = 0; i <= dayEnd; i++) + { + List items = _DayColumns[i].CalendarItems; + + if (items != null && items.Count > 0) + { + int right = _DayColumns[i].Bounds.Right - 1; + + for (int j = 0; j < items.Count; j++) + { + CalendarItem item = items[j]; + + if ((item.Displayed == true) && + (i >= dayStart || item.Bounds.Right > right)) + { + if (item.IsSelected == false) + { + item.Paint(e); + } + else + { + if (selItems == null) + selItems = new List(); + + selItems.Add(item); + } + } + } + } + } + + if (selItems != null) + { + foreach (CalendarItem item in selItems) + item.Paint(e); + } + } + } + + #endregion + + #endregion + + #region Mouse routines + + #region MouseDown processing + + /// + /// MouseDown event processing + /// + /// + public override void InternalMouseDown(MouseEventArgs objArg) + { + // Forward on the event + + base.InternalMouseDown(objArg); + + if (SelectedItem != null) + _WasAllDayItem = IsAllDayItem(SelectedItem); + + if (objArg.Button == MouseButtons.Left) + { + if (IsTabMoving == false) + { + // Locate where the event took place + + if (InPanelResize(objArg.Location) == true) + { + MyCursor = Cursors.HSplit; + + _IsPanelResizing = true; + } + else if (ViewRect.Contains(objArg.Location) == true) + { + int col, slice; + + if (GetPointItem(objArg.Location, out col, out slice, true)) + { + MyCursor = GetContentCursor(); + + if (ProcessCilButtonDown(col, objArg) == false) + ProcessDvlButtonDown(col, slice); + + IsMouseDown = true; + } + + IsCopyDrag = false; + } + } + } + } + + #region CalendarItem MouseDown processing + + /// + /// CalendarItem left mouseDown processing + /// + /// DayColumn col index + /// MouseEventArgs + private bool ProcessCilButtonDown(int col, MouseEventArgs objArg) + { + CalendarItem item = m_HotSubItem as CalendarItem; + + if (item != null) + { + _WasAllDayItem = IsAllDayItem(item); + + if (item.HitArea != CalendarItem.eHitArea.None) + { + // Give the user a chance to cancel the + // operation before it starts + + if (CalendarView.DoBeforeAppointmentViewChange(this, item, + ((item.HitArea == CalendarItem.eHitArea.Move) ? + eViewOperation.AppointmentMove : eViewOperation.AppointmentResize)) == false) + { + _LastCol = col; + _LastBounds = item.Bounds; + _LastPointOffset = objArg.Location; + _LastMovePoint = objArg.Location; + + _LastMoveCol = -1; + _LastDm = int.MinValue; + + if (IsResizing == false && IsMoving == false) + { + OldStartTime = item.StartTime; + OldEndTime = item.EndTime; + OldOwnerKey = OwnerKey; + } + + // Flag appropriate action + + if (item.HitArea == CalendarItem.eHitArea.TopResize) + IsStartResizing = true; + + else if (item.HitArea == CalendarItem.eHitArea.BottomResize) + IsEndResizing = true; + + else if (item.HitArea == CalendarItem.eHitArea.Move) + IsMoving = true; + + // Update our initial PosWin display + + UpdatePosWin(ViewRect); + } + } + + return (true); + } + + return (false); + } + + #endregion + + #region DayView MouseDown processing + + /// + /// Handles DayView left MouseDown events + /// + /// DayColumn col index + /// Time slice + private void ProcessDvlButtonDown(int col, int slice) + { + DateTime startDate = GetTime(_DayColumns[col].Date, slice, 0); + DateTime endDate = startDate.AddMinutes(TimeSlotDuration); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + SelectedItem = null; + } + + #endregion + + #endregion + + #region MouseUp processing + + /// + /// MouseUp event processing + /// + /// MouseEventArgs + public override void InternalMouseUp(MouseEventArgs objArg) + { + base.InternalMouseUp(objArg); + + CancelScrollTimer(); + + // Reset our panel resizing flag + + _IsPanelResizing = false; + + if (SelectedItem != null && + (IsAllDayItem(SelectedItem) != _WasAllDayItem)) + { + ReloadView(); + } + } + + #endregion + + #region MouseMove processing + + #region InternalMouseMove + + /// + /// MouseMove event processing + /// + /// MouseEventArgs + public override void InternalMouseMove(MouseEventArgs objArg) + { + // Forward on the event, but only if we are not in + // the middle of moving or resizing a CalendarItem + + if (Control.MouseButtons == MouseButtons.None) + ClearMouseStates(); + + if (!IsMoving && !IsStartResizing && !IsEndResizing) + base.InternalMouseMove(objArg); + + if (IsTabMoving == false) + { + if (_IsPanelResizing == true) + { + MyCursor = Cursors.HSplit; + + ProcessPanelMove(objArg); + } + else + { + if (InPanelResize(objArg.Location) == true) + { + MyCursor = Cursors.HSplit; + } + else + { + MyCursor = GetContentCursor(); + + if (objArg.Button == MouseButtons.Left) + ProcessContentMove(objArg); + } + } + } + } + + #endregion + + #region InPanelResize + + /// + /// Determines if the mouse is in the + /// panel resize area + /// + /// Mouse location + /// true if in the resize area + private bool InPanelResize(Point pt) + { + if (CalendarView.IsMultiCalendar == true) + { + Rectangle r = ViewRect; + + if (pt.X > r.Left && pt.X < r.Right && + pt.Y > r.Y - 3 && pt.Y < r.Y + 3) + { + return (true); + } + } + + return (false); + } + + #endregion + + #region ProcessPanelMove + + /// + /// Processes the actual panel resizing + /// + /// MouseEventArgs + private void ProcessPanelMove(MouseEventArgs objArg) + { + if (_IsPanelResizing == true) + { + Point pt = objArg.Location; + + if (pt.Y < ClientRect.Y + DayOfWeekHeaderHeight) + pt.Y = ClientRect.Y + DayOfWeekHeaderHeight; + + else if (pt.Y > ClientRect.Bottom - 50) + pt.Y = ClientRect.Bottom - 50; + + int n = pt.Y - (ClientRect.Y + DayOfWeekHeaderHeight); + + CalendarView.FixedAllDayPanelHeight = n; + } + } + + #endregion + + #region ProcessContentMove + + /// + /// Processes content mouse moves + /// + /// MouseEventArgs + private void ProcessContentMove(MouseEventArgs objArg) + { + // Locate where the event took place + // and process it accordingly + + int col, slice; + + if (GetPointItem(objArg.Location, out col, out slice, false)) + { + // The slice is visible, so no need to + // enable scrolling - just process the event + + EnableViewScrolling(false); + + ProcessMouseMove(col, slice, objArg); + } + else if (IsMouseDown == true) + { + if (DragDropAppointment(objArg) == false) + { + // The selected slice is not visible, + // so we need to enable scrolling + + EnableViewScrolling(true); + + // Only process the event if the user is selecting + // time slice cells (auto moving apps is intrusive looking) + + if (DateSelectionAnchor != null) + { + if (col >= 0) + { + if (slice < 0) + slice = 0; + + ProcessDvMouseMove(col, slice); + } + } + } + } + } + + #region DragDropAppointment + + /// + /// Initiates a user "DragDrop" operation - if enabled + /// + /// + /// True if operation started + private bool DragDropAppointment(MouseEventArgs objArgs) + { + if (IsMoving == true && CanDrag == true) + { + Point pt = objArgs.Location; + BaseView bv = CalendarView.GetViewFromPoint(pt); + WeekDayView wv = bv as WeekDayView; + + if (wv != null && wv != this) + { + eViewArea area = bv.GetViewAreaFromPoint(pt); + + if (area == eViewArea.InContent) + { + if (CalendarView.DoAppointmentViewChanging(SelectedItem, wv.OwnerKey, SelectedItem.StartTime, + SelectedItem.EndTime, eViewOperation.AppointmentMove, IsNewCopyDrag) == false) + { + DragCopy(); + + ClearMouseStates(); + CancelScrollTimer(); + + if (PosWin != null) + PosWin.Hide(); + + AppointmentView av = SelectedItem as AppointmentView; + + if (av != null) + return (wv.DragAppointment(this, av, objArgs.Location)); + + CustomCalendarItem ci = SelectedItem as CustomCalendarItem; + + if (ci != null) + return (wv.DragCustomItem(this, ci, objArgs.Location)); + } + } + } + } + + return (false); + } + + #region DragCustomItem + + private bool DragCustomItem(WeekDayView pv, CustomCalendarItem ci, Point pt) + { + // Set the new owner and selected view, and + // recalc the new layout + + if (ci.BaseCalendarItem != null) + ci = ci.BaseCalendarItem; + + ci.OwnerKey = OwnerKey; + + _LastMoveCol = 0; + _LastDm = int.MinValue; + + if (NumberOfColumns > 1) + { + DateTime sd = ci.StartTime; + TimeSpan ts = ci.EndTime.Subtract(ci.StartTime); + + if (Bounds.X > pv.Bounds.X) + { + ci.StartTime = new DateTime(_DayColumns[0].Date.Year, + _DayColumns[0].Date.Month, _DayColumns[0].Date.Day, sd.Hour, sd.Minute, 0); + } + else + { + _LastMoveCol = NumberOfColumns - 1; + + ci.StartTime = new DateTime(_DayColumns[NumberOfColumns - 1].Date.Year, + _DayColumns[NumberOfColumns - 1].Date.Month, + _DayColumns[NumberOfColumns - 1].Date.Day, sd.Hour, sd.Minute, 0); + } + + ci.EndTime = ci.StartTime.Add(ts); + } + + NeedRecalcLayout = true; + RecalcSize(); + + CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex; + + // Get the new view + + CustomCalendarItem view = GetCustomCalendarItem(ci); + + if (view != null) + SetNewDragItem(pv, view, pt); + + return (true); + } + + #endregion + + #region DragAppointment + + /// + /// Drags the given appointment from one view to another + /// + /// Previous view + /// Item to move + private bool DragAppointment(WeekDayView pv, AppointmentView av, Point pt) + { + // Set the new owner and selected view, and + // recalc the new layout + + av.Appointment.OwnerKey = OwnerKey; + + _LastMoveCol = 0; + _LastDm = int.MinValue; + + if (NumberOfColumns > 1) + { + DateTime sd = av.Appointment.StartTime; + + if (Bounds.X > pv.Bounds.X) + { + av.Appointment.MoveTo( + new DateTime(_DayColumns[0].Date.Year, _DayColumns[0].Date.Month, + _DayColumns[0].Date.Day, sd.Hour, sd.Minute, 0)); + } + else + { + _LastMoveCol = NumberOfColumns - 1; + + av.Appointment.MoveTo( + new DateTime(_DayColumns[NumberOfColumns - 1].Date.Year, + _DayColumns[NumberOfColumns - 1].Date.Month, + _DayColumns[NumberOfColumns - 1].Date.Day, sd.Hour, sd.Minute, 0)); + } + } + + NeedRecalcLayout = true; + RecalcSize(); + + CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex; + + // Get the new view + + AppointmentView view = GetAppointmentView(av.Appointment); + + if (view != null) + SetNewDragItem(pv, view, pt); + + return (true); + } + + #endregion + + #region SetNewDragItem + + private void SetNewDragItem(WeekDayView pv, CalendarItem view, Point pt) + { + _LastBounds = pv._LastBounds; + _LastMovePoint = pv._LastMovePoint; + _LastPointOffset = pv._LastPointOffset; + + int dy = _LastPointOffset.Y - _LastBounds.Y; + + CalendarView.CalendarPanel.InternalMouseMove(new + MouseEventArgs(MouseButtons.None, 0, view.Bounds.X, view.Bounds.Y - dy, 0)); + + MouseEventArgs args = new + MouseEventArgs(MouseButtons.Left, 1, view.Bounds.X, view.Bounds.Y + dy, 0); + + IsMoving = true; + + InternalMouseMove(args); + CalendarView.CalendarPanel.InternalMouseDown(args); + + SelectedItem = view; + + IsNewCopyDrag = true; + } + + #endregion + + #endregion + + #endregion + + #region GetContentCursor + + /// + /// Gets the cursor + /// + /// Cursor + private Cursor GetContentCursor() + { + CalendarItem item = m_HotSubItem as CalendarItem; + + if (item != null) + { + switch (item.HitArea) + { + case CalendarItem.eHitArea.TopResize: + case CalendarItem.eHitArea.BottomResize: + return (Cursors.SizeNS); + + case CalendarItem.eHitArea.Move: + return (IsMoving ? Cursors.SizeAll : DefaultCursor); + } + } + + return (DefaultCursor); + } + + #endregion + + #region ProcessMouseMove + + /// + /// Processes user MouseMove + /// + /// DayColumn + /// Slice + /// + private void ProcessMouseMove(int col, int slice, MouseEventArgs objArg) + { + if (DateSelectionAnchor != null) + { + ProcessDvMouseMove(col, slice); + } + else if (SelectedItem != null) + { + if (objArg.Location.Equals(_LastMovePoint) == false) + { + if (IsMoving == true) + ProcessItemMove(col, slice, objArg); + + else if (IsStartResizing == true) + ProcessItemTopResize(col, slice, objArg); + + else if (IsEndResizing == true) + ProcessItemBottomResize(col, slice, objArg); + + _LastMovePoint = objArg.Location; + } + } + } + + #endregion + + #region DayView mouseMove processing + + /// + /// Processes DayView mouseMove events + /// + /// DayColumn col index + /// Time slice + private void ProcessDvMouseMove(int col, int slice) + { + DateTime date = GetTime(_DayColumns[col].Date, slice, 0); + + // Let the user select forwards or backwards + + if (date >= DateSelectionAnchor) + { + CalendarView.DateSelectionStart = DateSelectionAnchor.Value; + CalendarView.DateSelectionEnd = date.AddMinutes(TimeSlotDuration); + } + else + { + CalendarView.DateSelectionStart = date; + CalendarView.DateSelectionEnd = DateSelectionAnchor.Value.AddMinutes(TimeSlotDuration); + } + } + + #endregion + + #region CalendarItem MouseMove processing + + #region ProcessItemMove + + /// + /// Processes CalendarItem mouseMove events + /// + /// DayColumn col index + /// Time slice + /// + private void ProcessItemMove(int col, int slice, MouseEventArgs objArg) + { + // Calculate our new item date + + int dm = GetDeltaMinutes(slice, true, objArg); + + if (_LastDm == int.MinValue) + _LastDm = dm; + + int ddm = dm - _LastDm; + + if (_LastMoveCol == -1) + _LastMoveCol = col; + + if (col != _LastMoveCol) + ddm += ((col - _LastMoveCol) * HoursPerDay * MinutesPerHour); + + _LastDm = dm; + _LastMoveCol = col; + + DateTime newDate = SelectedItem.StartTime.AddMinutes(ddm); + TimeSpan ts = SelectedItem.EndTime - SelectedItem.StartTime; + + if (newDate != SelectedItem.StartTime) + { + if (CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None) + { + // Make sure we don't cross day boundaries + + DateTime start = GetTime(_DayColumns[col].Date, 0, 0); + DateTime end = start.AddMinutes(NumberOfActiveSlices * TimeSlotDuration); + + if (newDate < start) + newDate = start; + + if (newDate + ts > end) + newDate -= (newDate + ts) - end; + } + + // If we have a new date, set our item to it + + if (newDate != SelectedItem.StartTime) + { + if (DragCopy() == false) + { + try + { + if (SelectedItem is CustomCalendarItem) + CalendarView.CustomItems.BeginUpdate(); + else + CalendarModel.BeginUpdate(); + + // Make the move + + if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, newDate, + newDate + ts, eViewOperation.AppointmentMove, + IsCopyDrag) == false) + { + SelectedItem.StartTime = newDate; + SelectedItem.EndTime = newDate + ts; + + InvalidateItems(col); + } + } + finally + { + if (SelectedItem is CustomCalendarItem) + CalendarView.CustomItems.EndUpdate(); + else + CalendarModel.EndUpdate(); + } + } + else + { + _LastMoveCol = _LastCol; + } + } + } + } + + #endregion + + #endregion + + #region CalendarItem MouseResize processing + + #region ProcessItemTopResize + + /// + /// Processes CalendarItem left resizing + /// + /// Time slice + /// + private void ProcessItemTopResize(int col, int slice, MouseEventArgs objArg) + { + int dm = GetDeltaMinutes(slice, true, objArg); + + DateTime newStartTime; + + if (CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None) + { + newStartTime = new DateTime( + SelectedItem.StartTime.Year, SelectedItem.StartTime.Month, SelectedItem.StartTime.Day); + + newStartTime = GetTime(newStartTime, 0, dm); + } + else + { + newStartTime = GetTime(_DayColumns[col].Date.Date, 0, dm); + + if (newStartTime < _DayColumns[0].Date) + newStartTime = _DayColumns[0].Date; + } + + if (newStartTime != SelectedItem.StartTime && newStartTime < SelectedItem.EndTime) + { + if ((SelectedItem.EndTime - newStartTime).TotalMinutes < 0) + newStartTime = SelectedItem.EndTime.AddMinutes(-1); + + ResizeItem(_LastCol, newStartTime, SelectedItem.EndTime); + } + } + + #endregion + + #region ProcessItemBottomResize + + /// + /// Processes CalendarItem right resizing + /// + /// Time slice + /// + private void ProcessItemBottomResize(int col, int slice, MouseEventArgs objArg) + { + int dm = GetDeltaMinutes(slice, false, objArg); + + DateTime newEndTime; + DateTime end; + + if (CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None) + { + newEndTime = new DateTime( + SelectedItem.StartTime.Year, SelectedItem.StartTime.Month, SelectedItem.StartTime.Day); + + if (newEndTime < _DayColumns[0].Date) + newEndTime = _DayColumns[0].Date; + + newEndTime = GetTime(newEndTime, 0, dm); + + end = GetTime(_DayColumns[_LastCol].Date, NumberOfActiveSlices, 0); + } + else + { + newEndTime = GetTime(_DayColumns[col].Date.Date, 0, dm); + + if (newEndTime < _DayColumns[0].Date) + newEndTime = _DayColumns[0].Date; + + end = GetTime(_DayColumns[_DayColumns.Length - 1].Date, NumberOfActiveSlices, 0); + } + + if (newEndTime > end) + newEndTime = end; + + if (newEndTime != SelectedItem.EndTime && newEndTime > SelectedItem.StartTime) + { + if ((newEndTime - SelectedItem.StartTime).TotalMinutes < 0) + newEndTime = SelectedItem.StartTime.AddMinutes(1); + + ResizeItem(_LastCol, SelectedItem.StartTime, newEndTime); + } + } + + #endregion + + #region ResizeItem + + /// + /// Initiates the resize of the selected item + /// + /// + /// + /// + private void ResizeItem(int col, DateTime startTime, DateTime endTime) + { + // Let the user cancel the operation if desired + + if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, startTime, + endTime, eViewOperation.AppointmentResize, IsNewCopyDrag) == false) + { + InvalidateItems(col); + + SelectedItem.StartTime = startTime; + SelectedItem.EndTime = endTime; + } + } + + #endregion + + #endregion + + #region GetDeltaMinutes + + /// + /// Gets the changes in minutes + /// from the last mouse operation (move or resize) + /// + /// Current slice + /// Flag denoting top or bottom delta + /// MouseEventArgs + /// Delta minutes + private int GetDeltaMinutes(int slice, bool ftop, MouseEventArgs objArg) + { + // Calculate our delta minutes + + Rectangle t = GetSliceRect(0, slice); + + int dm = (objArg.Location.Y - _LastPointOffset.Y); + + dm += ftop ? _LastBounds.Top - t.Top + : _LastBounds.Bottom - t.Bottom; + + dm = (int)(TimeSlotDuration * dm / TimeSliceHeight); + + // If the Alt key is not pressed, then round + // our value off to the nearest slice + + if ((Control.ModifierKeys & Keys.Alt) != Keys.Alt) + { + slice += (dm / TimeSlotDuration); + dm = 0; + } + + dm += (slice * TimeSlotDuration); + + // Make sure we don't cross our day boundaries + + if (CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None) + { + if (ftop == true) + { + if (dm < 0) + dm = 0; + } + else + { + dm += TimeSlotDuration; + + if (dm >= MinutesPerHour * HoursPerDay) + dm = MinutesPerHour * HoursPerDay - 1; + } + } + + return (dm); + } + + #endregion + + #region InvalidateItems + + /// + /// Invalidates altered DayColumns + /// + /// Current column + internal void InvalidateItems(int col) + { + if (SelectedItem.IsRecurring == false) + { + _DayColumns[_LastCol].NeedRecalcLayout = true; + _DayColumns[col].NeedRecalcLayout = true; + + InvalidateRect(_DayColumns[col].Bounds, true); + + if (_LastCol != col) + InvalidateRect(_DayColumns[_LastCol].Bounds); + } + else + { + NeedRecalcLayout = true; + } + + _LastCol = col; + } + + #endregion + + #region View Scrolling support + + #region EnableViewScrolling + + /// + /// Routine to enable or disable view scrolling + /// + /// true to enable + private void EnableViewScrolling(bool enable) + { + if (enable == true) + { + if (VsPanel.ScrollBar.Maximum > VsPanel.ScrollBar.LargeChange) + { + if (_ScrollViewTimer == null) + { + _ScrollViewTimer = new Timer(); + + _ScrollViewTimer.Interval = 10; + _ScrollViewTimer.Tick += ScrollViewTimerTick; + _ScrollViewTimer.Start(); + } + } + } + else + { + CancelScrollTimer(); + } + } + + #endregion + + #region CancelScrollTimer + + /// + /// Cancels the view scroll timer + /// + private void CancelScrollTimer() + { + // Dispose of our scroll timer + + if (_ScrollViewTimer != null) + { + _ScrollViewTimer.Stop(); + _ScrollViewTimer.Tick -= ScrollViewTimerTick; + + _ScrollViewTimer = null; + } + } + + #endregion + + #region ScrollAmount + + /// + /// Determines the amount to scroll (which is + /// based loosely upon the delta magnitude) + /// + /// Point delta + /// Scroll amount + private int ScrollAmount(int delta) + { + int dy = Math.Abs(delta); + int amt = (dy < 16 ? 2 : dy < 32 ? 8 : 32); + + return (delta < 0 ? -amt : amt); + } + + #endregion + + #region ScrollViewTimer_Tick + + /// + /// Handles view scroll timer ticks + /// + /// object + /// EventArgs + private void ScrollViewTimerTick(object sender, EventArgs e) + { + Control c = (Control)this.GetContainerControl(true); + + if (c != null) + { + // Calculate our delta + + Point pt = c.PointToClient(Cursor.Position); + Rectangle r = ViewRect; + + int dy = (pt.Y < r.Top) ? ScrollAmount(pt.Y - r.Top) : + (pt.Y >= r.Bottom) ? ScrollAmount(pt.Y - r.Bottom) : 0; + + // Scroll if necessary + + if (dy != 0) + { + int value = VsPanel.ScrollBar.Value + dy; + + value = Math.Max(value, 0); + value = Math.Min(value, VsPanel.ScrollBar.Maximum); + + if (VsPanel.ScrollBar.Value != value) + { + VsPanel.ScrollBar.Value = value; + + if (PosWin != null) + PosWin.Hide(); + + InternalMouseMove(new + MouseEventArgs(MouseButtons.Left, 0, pt.X, pt.Y, 0)); + } + } + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region InternalKeyDown + + #region InternalKeyDown + + /// + /// Processes KeyDown events + /// + /// + public override void InternalKeyDown(KeyEventArgs objArg) + { + switch (objArg.KeyData) + { + case Keys.Up: + case Keys.Up | Keys.Shift: + case Keys.Up | Keys.Control: + case Keys.Up | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, -CalendarView.TimeSlotDuration); + break; + + case Keys.Down: + case Keys.Down | Keys.Shift: + case Keys.Down | Keys.Control: + case Keys.Down | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, CalendarView.TimeSlotDuration); + break; + + case Keys.Left: + case Keys.Left | Keys.Shift: + case Keys.Left | Keys.Control: + case Keys.Left | Keys.Control | Keys.Shift: + ProcessLeftRightKey(objArg, -1); + break; + + case Keys.Right: + case Keys.Right | Keys.Shift: + case Keys.Right | Keys.Control: + case Keys.Right | Keys.Control | Keys.Shift: + ProcessLeftRightKey(objArg, 1); + break; + + case Keys.Home: + case Keys.Home | Keys.Shift: + case Keys.Home | Keys.Control: + case Keys.Home | Keys.Control | Keys.Shift: + ProcessHomeKey(objArg); + break; + + case Keys.End: + case Keys.End | Keys.Shift: + case Keys.End | Keys.Control: + case Keys.End | Keys.Control | Keys.Shift: + ProcessEndKey(objArg); + break; + + case Keys.PageUp: + case Keys.PageUp | Keys.Shift: + case Keys.PageUp | Keys.Control: + case Keys.PageUp | Keys.Control | Keys.Shift: + ProcessPageUpDownKey(objArg, -1); + break; + + case Keys.PageDown: + case Keys.PageDown | Keys.Shift: + case Keys.PageDown | Keys.Control: + case Keys.PageDown | Keys.Control | Keys.Shift: + ProcessPageUpDownKey(objArg, 1); + break; + } + } + + #endregion + + #region ProcessUpDownKey + + /// + /// Processes Up and Down key events + /// + /// + /// + protected virtual void ProcessUpDownKey(KeyEventArgs objArg, int dy) + { + if (ValidDateSelection()) + { + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + if (startDate.Equals(DateSelectionAnchor.Value) == true) + startDate = endDate.AddMinutes(-TimeSlotDuration); + + startDate = startDate.AddMinutes(dy); + + DateTime viewStart = GetTime(DayColumns[0].Date, 0, 0); + DateTime viewEnd = viewStart.AddMinutes(NumberOfActiveSlices * TimeSlotDuration); + + endDate = startDate.AddMinutes(TimeSlotDuration); + + if (startDate >= viewStart && endDate <= viewEnd) + { + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + EnsureSelectionVisible(); + } + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessLeftRightKey + + /// + /// Processes Left and Right key events + /// + /// + /// + protected virtual void ProcessLeftRightKey(KeyEventArgs objArg, int dx) + { + if (CalendarView.WeekDayCanExtendRange == true) + { + DateTime oldDate = CalendarView.DayViewDate; + DateTime newDate = CalendarView.DayViewDate.AddDays(dx); + + if (CalendarView.DoViewDateChanging(this, + oldDate, oldDate, ref newDate, ref newDate) == false) + { + if (ValidDateSelection()) + { + dx = (newDate - oldDate).Days; + + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + startDate = startDate.AddDays(dx); + endDate = endDate.AddDays(dx); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + DateSelectionAnchor = DateSelectionAnchor.Value.AddDays(dx); + } + + CalendarView.DayViewDate = CalendarView.DayViewDate.AddDays(dx); + } + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessHomeKey + + /// + /// Processes Home key events + /// + /// + protected virtual void ProcessHomeKey(KeyEventArgs objArg) + { + int col = GetHomeEndCol(); + + if (col >= 0) + { + DateTime startDate = GetTime(DayColumns[col].Date, 0, 0); + + if ((objArg.Modifiers & Keys.Control) != Keys.Control) + { + WorkTime wt = DayColumns[col].WorkStartTime; + + if (wt.IsEmpty == false) + startDate = DayColumns[col].Date.AddMinutes(wt.Hour * 60 + wt.Minute); + } + + DateTime endDate = startDate.AddMinutes(TimeSlotDuration); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + EnsureSelectionVisible(); + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessEndKey + + /// + /// Processes End Key events + /// + /// + protected virtual void ProcessEndKey(KeyEventArgs objArg) + { + int col = GetHomeEndCol(); + + if (col >= 0) + { + DateTime startDate = GetTime(DayColumns[col].Date, NumberOfActiveSlices, 0); + + if ((objArg.Modifiers & Keys.Control) != Keys.Control) + { + WorkTime wt = DayColumns[col].WorkEndTime; + + if (wt.IsEmpty == false) + startDate = DayColumns[col].Date.AddMinutes(wt.Hour * 60 + wt.Minute); + } + + DateTime endDate = startDate; + startDate = startDate.AddMinutes(-TimeSlotDuration); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + EnsureSelectionVisible(); + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessPageUpDownKey + + /// + /// Processes Page Up and Down key events + /// + /// + /// Paging direction (-1, 1) + protected virtual void ProcessPageUpDownKey(KeyEventArgs objArg, int dy) + { + if (ValidDateSelection()) + { + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + int col = GetColumnFromDate(startDate); + + if ((uint)col < DayColumns.Length) + { + DateTime viewStart = GetTime(DayColumns[col].Date, 0, 0); + DateTime viewEnd = viewStart.AddMinutes(NumberOfActiveSlices * TimeSlotDuration); + + if (startDate.Equals(DateSelectionAnchor.Value) == true) + startDate = endDate.AddMinutes(-TimeSlotDuration); + + startDate = (dy < 0) + ? GetPageUpStartDate(viewStart, startDate) + : GetPageDownStartDate(viewStart, viewEnd, startDate); + + endDate = startDate.AddMinutes(TimeSlotDuration); + + if (startDate >= viewStart && endDate <= viewEnd) + { + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + EnsureSelectionVisible(); + } + } + } + + objArg.Handled = true; + } + + private DateTime GetPageUpStartDate( + DateTime viewStart, DateTime startDate) + { + DateTime fosDate = viewStart.AddMinutes(TimeSlotDuration*FirstOnScreenSlice); + + if (startDate.Equals(fosDate) == false) + return (fosDate); + + startDate = startDate.AddMinutes(-TimeSlotDuration * OnScreenSlices); + + if (startDate < viewStart) + startDate = viewStart; + + return (startDate); + } + + private DateTime GetPageDownStartDate( + DateTime viewStart, DateTime viewEnd, DateTime startDate) + { + DateTime eosDate = viewStart.AddMinutes(TimeSlotDuration * LastOnScreenSlice); + + if (startDate.Equals(eosDate) == false) + return (eosDate); + + startDate = eosDate.AddMinutes(TimeSlotDuration * OnScreenSlices); + + if (startDate > viewEnd) + startDate = viewEnd; + + return (startDate); + } + + #endregion + + #region GetHomeEndCol + + /// + /// Gets the Home and End column from the current + /// selection range + /// + /// + private int GetHomeEndCol() + { + if (ValidDateSelection() == true) + { + if (CalendarView.DateSelectionStart.Equals(DateSelectionAnchor.Value) == true) + return (GetColumnFromDate(DateSelectionEnd.Value.AddMinutes(-TimeSlotDuration))); + + return (GetColumnFromDate(DateSelectionStart.Value)); + } + + return ((NumberOfColumns == 1) ? 0 : -1); + } + + #endregion + + #region GetColumnFromDate + + /// + /// Gets the view column from the given date + /// + /// + /// The DayColumns index, or -1 if invalid. + public int GetColumnFromDate(DateTime date) + { + for (int i = 0; i < DayColumns.Length; i++) + { + DateTime dc = DayColumns[i].Date.Date; + + if (dc <= date && dc.AddDays(1) > date) + return (i); + } + + return (-1); + } + + #endregion + + #region EnsureSelectionVisible + + /// + /// Ensures the given selection is visible + /// + protected virtual void EnsureSelectionVisible() + { + DateTime start = CalendarView.DateSelectionStart.Value; + DateTime end = CalendarView.DateSelectionEnd.Value; + + bool refreshed = start.Equals(DateSelectionAnchor) ? + EnsureDateVisible(end.AddMinutes(-CalendarView.TimeSlotDuration)) : + EnsureDateVisible(start); + + if (refreshed == false) + Refresh(); + } + + #endregion + + #region EnsureDateVisible + + /// + /// Ensures the given date is visible + /// + /// + /// + protected virtual bool EnsureDateVisible(DateTime date) + { + if (CalendarView.WeekDayVScrollPanel.ScrollBar.Maximum > + CalendarView.WeekDayVScrollPanel.ScrollBar.LargeChange) + { + Rectangle r = ViewRect; + + int offset = (int)(date.Hour * CalendarView.SlotsPerHour * CalendarView.TimeSliceHeight + + (CalendarView.TimeSliceHeight * date.Minute) / CalendarView.TimeSlotDuration); + + offset -= (int)(CalendarView.StartSlice * CalendarView.TimeSliceHeight); + + int top = CalendarView.WeekDayVScrollPanel.ScrollBar.Value; + int bottom = top + r.Height; + + if (offset < top || offset + CalendarView.TimeSliceHeight > bottom) + { + if (offset + CalendarView.TimeSliceHeight > bottom) + offset -= (int)(r.Height - CalendarView.TimeSliceHeight); + + offset = Math.Min(offset, CalendarView.WeekDayVScrollPanel.ScrollBar.Maximum); + offset = Math.Max(offset, 0); + + CalendarView.WeekDayVScrollPanel.ScrollBar.Value = offset; + + return (true); + } + + return (false); + } + + return (true); + } + + #endregion + + #endregion + + #region TimeSlice support routines + + #region GetPointItem + + /// + /// Gets the column and slice index item for + /// the given point + /// + /// Point + /// [out] DayColumn column + /// [out] Time slice + /// + /// Item visible state + private bool GetPointItem(Point pt, out int col, out int slice, bool partial) + { + slice = -1; + + if ((col = GetPointCol(pt)) >= 0) + { + slice = GetPointSlice(pt, col); + + if (slice >= 0 && slice < NumberOfActiveSlices) + return (IsSliceVisible(col, slice, partial)); + } + + return (false); + } + + #endregion + + #region IsSliceVisible + + /// + /// Determines if a given slice is visible + /// + /// DayColumn + /// Slice in question + /// Partially visible is ok + /// Slice visibility + private bool IsSliceVisible(int col, int slice, bool partial) + { + Rectangle r = GetSliceRect(col, slice); + Rectangle t = ViewRect; + + if (partial == true) + { + if (r.Bottom < t.Top) + return (false); + + if (r.Top > t.Bottom) + return (false); + } + else + { + if (r.Top < t.Top) + return (false); + + if (r.Bottom > t.Bottom) + return (false); + } + + return (true); + } + + #endregion + + #region GetSliceRect + + /// + /// Gets the given slice rectangle + /// + /// Column + /// Slice + /// Bounding rectangle + private Rectangle GetSliceRect(int col, int slice) + { + if ((uint)col < _DayColumns.Length) + { + Rectangle r = _DayColumns[col].Bounds; + + float n = slice * TimeSliceHeight; + + r.Y += (int)(n); + r.Height = (int)(n + TimeSliceHeight) - (int)n; + + return (r); + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetPointCol + + /// + /// Gets the col index for the given point + /// + /// Point + /// Column + private int GetPointCol(Point pt) + { + for (int i = 0; i < _NumberOfColumns; i++) + { + if (pt.X >= _DayColumns[i].Bounds.X && + pt.X < _DayColumns[i].Bounds.Right) + { + return (i); + } + } + + return (-1); + } + + #endregion + + #region GetPointSlice + + /// + /// Gets the slice index for the given point + /// + /// Point + /// + /// Slice index + private int GetPointSlice(Point pt, int col) + { + int s1 = (int)(-_VScrollPos / TimeSliceHeight); + + Rectangle r = GetSliceRect(col, s1); + + if (pt.Y < r.Top) + return (s1 - 1); + + for (int i = s1; i < NumberOfActiveSlices; i++) + { + r = GetSliceRect(col, i); + + if (pt.Y >= r.Top && pt.Y < r.Bottom) + return (i); + } + + return (NumberOfActiveSlices - 1); + } + + #endregion + + #region GetTime + + /// + /// Gets the DateTime adjusted by the given + /// slice and minutes delta + /// + /// + /// + /// + /// + private DateTime GetTime(DateTime date, int slice, int minutes) + { + return (date.AddMinutes((StartSlice + slice) * TimeSlotDuration + minutes)); + } + + #endregion + + #endregion + + #region IDisposable Members + + protected override void Dispose(bool disposing) + { + if (disposing == true && IsDisposed == false) + { + ResetView(); + + BusyBrush = null; + WorkBrush = null; + OffWorkBrush = null; + SelectedBrush = null; + + HookEvents(false); + } + + base.Dispose(disposing); + } + + #endregion + + #region Copy object support + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + WeekDayView objCopy = new WeekDayView(this.CalendarView, this.ECalendarView); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the WeekDayView specific properties to new instance of the item. + /// + /// New WeekDayView instance + protected override void CopyToItem(BaseItem copy) + { + WeekDayView objCopy = copy as WeekDayView; + base.CopyToItem(objCopy); + } + + #endregion + + #region DaySlot class def + + private class DaySlot + { + public Rectangle Bounds; + public bool Selected; + public DaySlotAppearance Appearance; + } + + #endregion + } +} +#endif diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/WeekView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/WeekView.cs new file mode 100644 index 00000000..f8361477 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WeekView/WeekView.cs @@ -0,0 +1,177 @@ +#if FRAMEWORK20 +using System; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Schedule +{ + public class WeekView : WeekDayView + { + public WeekView(CalendarView calendarView) + : base(calendarView, eCalendarView.Week) + { + } + + #region RecalcSize support + + /// + /// Normalizes the user specified start and end dates + /// + /// [out] Normalized start date + /// [out] Normalized end date + protected override void NormalizeDates(out DateTime startDate, out DateTime endDate) + { + startDate = this.StartDate; + endDate = this.EndDate; + + DaysOfTheWeek = new DaysOfTheWeek(startDate.DayOfWeek, DaysInWeek); + } + + #endregion + + #region ProcessUpDownKey + + /// + /// Processes Up and Down key events + /// + /// + /// + protected override void ProcessUpDownKey(KeyEventArgs objArg, int dy) + { + if (ValidDateSelection()) + { + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + if (startDate.Equals(DateSelectionAnchor.Value) == true) + startDate = endDate.AddMinutes(-CalendarView.TimeSlotDuration); + + int col = GetColumnFromDate(startDate); + + startDate = startDate.AddMinutes(dy); + + if (GetColumnFromDate(startDate) == col) + { + if (col < 0) + { + startDate = CalendarView.DateSelectionStart.Value; + col = GetColumnFromDate(startDate); + } + + if (col < 0) + { + startDate = CalendarView.DateSelectionEnd.Value; + col = GetColumnFromDate(startDate); + } + + if (col >= 0) + { + endDate = startDate.AddMinutes(CalendarView.TimeSlotDuration); + + DateTime sd = DayColumns[col].Date.AddMinutes(CalendarView.StartSlice * CalendarView.TimeSlotDuration); + DateTime ed = sd.AddMinutes(CalendarView.NumberOfActiveSlices * CalendarView.TimeSlotDuration); + + if (startDate >= sd && endDate <= ed) + { + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + EnsureSelectionVisible(); + } + } + } + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessLeftRightKey + + /// + /// Processes Left and Right Key events + /// + /// + /// + protected override void ProcessLeftRightKey(KeyEventArgs objArg, int dx) + { + objArg.Handled = true; + + if (ValidDateSelection()) + { + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + bool newRange = (startDate < DayColumns[0].Date || + endDate > DayColumns[NumberOfColumns - 1].Date.AddDays(1)); + + if (CalendarView.WeekDayCanExtendRange == true || newRange == false) + { + bool cancelled = false; + + if ((objArg.Modifiers & Keys.Shift) == Keys.Shift) + { + if (startDate.Equals(DateSelectionAnchor.Value) == true) + startDate = endDate.AddMinutes(-CalendarView.TimeSlotDuration); + + startDate = startDate.AddDays(dx); + endDate = startDate.AddMinutes(CalendarView.TimeSlotDuration); + + if (IsNewRange(startDate, endDate) == true) + { + if (CalendarView.WeekDayCanExtendRange == false) + return; + + cancelled = CalendarView.DoViewDateChanging(this, + StartDate, EndDate, ref startDate, ref endDate); + + if (cancelled == false) + CalendarView.EnsureVisible(startDate, startDate.AddDays(1)); + } + + ExtendSelection(ref startDate, ref endDate); + } + else + { + startDate = startDate.AddDays(dx); + endDate = endDate.AddDays(dx); + + if (IsNewRange(startDate, endDate) == true) + { + if (CalendarView.WeekDayCanExtendRange == false) + return; + + cancelled = CalendarView.DoViewDateChanging(this, + StartDate, EndDate, ref startDate, ref endDate); + + if (cancelled == false) + CalendarView.EnsureVisible(startDate, startDate.AddDays(1)); + } + + DateSelectionAnchor = startDate; + } + + if (cancelled == false) + { + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + } + + EnsureSelectionVisible(); + } + } + } + + private bool IsNewRange(DateTime startDate, DateTime endDate) + { + return (startDate < DayColumns[0].Date || + endDate > DayColumns[NumberOfColumns - 1].Date.AddDays(1)); + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WinApi.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WinApi.cs new file mode 100644 index 00000000..61ba30c6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/WinApi.cs @@ -0,0 +1,769 @@ +using System; +using System.Text; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace DevComponents.DotNetBar.Schedule +{ + internal class WinApi + { + #region Windows Messages + public enum WindowsMessages + { + WM_NCPAINT = 0x0085, + WM_NCCALCSIZE = 0x0083, + WM_NCACTIVATE = 0x0086, + WM_SETTEXT = 0x000C, + WM_INITMENUPOPUP = 0x0117, + WM_WINDOWPOSCHANGED = 0x0047, + WM_NCHITTEST = 0x0084, + WM_ERASEBKGND = 0x0014, + WM_NCMOUSEMOVE = 0xA0, + WM_NCLBUTTONDOWN = 0xA1, + WM_NCMOUSELEAVE = 0x2A2, + WM_NCLBUTTONUP = 0xA2, + WM_NCMOUSEHOVER = 0x2A0, + WM_SETCURSOR = 0x20, + WM_SETICON = 0x0080, + WM_HSCROLL = 0x0114, + WM_VSCROLL = 0x115, + WM_MOUSEWHEEL = 0x020A, + WM_STYLECHANGED = 0x7D, + WM_NCLBUTTONDBLCLK = 0xA3, + WM_MOUSEACTIVATE = 0x21, + WM_MOUSEMOVE = 0x0200, + WM_MDISETMENU = 0x230, + WM_MDIREFRESHMENU = 0x234, + WM_KEYDOWN = 0x0100, + WM_SIZE = 0x5, + WM_DWMCOMPOSITIONCHANGED = 0x031E, + WM_DRAWITEM = 0x002B, + SBM_SETPOS = 0x00E0, + SBM_SETSCROLLINFO = 0x00E9, + EM_GETMODIFY = 0x00B8, + EM_SETMODIFY = 0x00B9, + WM_LBUTTONUP = 0x0202, + WM_LBUTTONDOWN = 0x0201, + WM_LBUTTONDBLCLK = 0x0203, + WM_SYSTIMER = 0x0118, + WM_SETFOCUS = 0x0007, + WM_KILLFOCUS = 0x0008, + WM_PAINT = 0x000F, + WM_COMMAND = 0x0111, + WM_CTLCOLORBTN = 0x0135, + WM_CTLCOLORSCROLLBAR = 0x0137, + WM_MDIACTIVATE = 0x222, + WM_CAPTURECHANGED = 0x0215, + CB_GETDROPPEDSTATE = 0x0157, + WVR_VALIDRECTS = 0x400, + WM_GETMINMAXINFO = 0x0024, + WM_APPCOMMAND = 0x0319 + } + + public enum ComboNotificationCodes : int + { + CBN_DROPDOWN = 7, + CBN_CLOSEUP = 8 + } + + public enum MouseKeyState : int + { + MK_LBUTTON = 0x0001, + MK_RBUTTON = 0x0002, + MK_SHIFT = 0x0004, + MK_CONTROL = 0x0008, + MK_MBUTTON = 0x0010, + MK_XBUTTON1 = 0x0020, + MK_XBUTTON2 = 0x0040 + + } + + /// Options available when a form is tested for mose positions. + public enum WindowHitTestRegions + { + /// HTERROR: On the screen background or on a dividing line between windows + /// (same as HTNOWHERE, except that the DefWindowProc function produces a system + /// beep to indicate an error). + Error = -2, + /// HTTRANSPARENT: In a window currently covered by another window in the + /// same thread (the message will be sent to underlying windows in the same thread + /// until one of them returns a code that is not HTTRANSPARENT). + TransparentOrCovered = -1, + /// HTNOWHERE: On the screen background or on a dividing line between + /// windows. + NoWhere = 0, + /// HTCLIENT: In a client area. + ClientArea = 1, + /// HTCAPTION: In a title bar. + TitleBar = 2, + /// HTSYSMENU: In a window menu or in a Close button in a child window. + SystemMenu = 3, + /// HTGROWBOX: In a size box (same as HTSIZE). + GrowBox = 4, + /// HTMENU: In a menu. + Menu = 5, + /// HTHSCROLL: In a horizontal scroll bar. + HorizontalScrollBar = 6, + /// HTVSCROLL: In the vertical scroll bar. + VerticalScrollBar = 7, + /// HTMINBUTTON: In a Minimize button. + MinimizeButton = 8, + /// HTMAXBUTTON: In a Maximize button. + MaximizeButton = 9, + /// HTLEFT: In the left border of a resizable window (the user can click + /// the mouse to resize the window horizontally). + LeftSizeableBorder = 10, + /// HTRIGHT: In the right border of a resizable window (the user can click + /// the mouse to resize the window horizontally). + RightSizeableBorder = 11, + /// HTTOP: In the upper-horizontal border of a window. + TopSizeableBorder = 12, + /// HTTOPLEFT: In the upper-left corner of a window border. + TopLeftSizeableCorner = 13, + /// HTTOPRIGHT: In the upper-right corner of a window border. + TopRightSizeableCorner = 14, + /// HTBOTTOM: In the lower-horizontal border of a resizable window (the + /// user can click the mouse to resize the window vertically). + BottomSizeableBorder = 15, + /// HTBOTTOMLEFT: In the lower-left corner of a border of a resizable + /// window (the user can click the mouse to resize the window diagonally). + BottomLeftSizeableCorner = 16, + /// HTBOTTOMRIGHT: In the lower-right corner of a border of a resizable + /// window (the user can click the mouse to resize the window diagonally). + BottomRightSizeableCorner = 17, + /// HTBORDER: In the border of a window that does not have a sizing + /// border. + NonSizableBorder = 18, + /// HTOBJECT: Unknown...No Documentation Found + Object = 19, + /// HTCLOSE: In a Close button. + CloseButton = 20, + /// HTHELP: In a Help button. + HelpButton = 21, + /// HTSIZE: In a size box (same as HTGROWBOX). (Same as GrowBox). + SizeBox = GrowBox, + /// HTREDUCE: In a Minimize button. (Same as MinimizeButton). + ReduceButton = MaximizeButton, + /// HTZOOM: In a Maximize button. (Same as MaximizeButton). + ZoomButton = MaximizeButton, + } + + public enum GWL + { + GWL_WNDPROC = (-4), + GWL_HINSTANCE = (-6), + GWL_HWNDPARENT = (-8), + GWL_STYLE = (-16), + GWL_EXSTYLE = (-20), + GWL_USERDATA = (-21), + GWL_ID = (-12) + } + + public enum RedrawWindowFlags : uint + { + RDW_INVALIDATE = 0x0001, + RDW_INTERNALPAINT = 0x0002, + RDW_ERASE = 0x0004, + RDW_VALIDATE = 0x0008, + RDW_NOINTERNALPAINT = 0x0010, + RDW_NOERASE = 0x0020, + RDW_NOCHILDREN = 0x0040, + RDW_ALLCHILDREN = 0x0080, + RDW_UPDATENOW = 0x0100, + RDW_ERASENOW = 0x0200, + RDW_FRAME = 0x0400, + RDW_NOFRAME = 0x0800 + } + [Flags()] + public enum WindowStyles + { + WS_VISIBLE = 0x10000000, + WS_CAPTION = 0x00C00000, + WS_BORDER = 0x800000, + WS_DLGFRAME = 0x400000, + WS_THICKFRAME = 0x00040000 + } + #endregion + + #region Windows API + [DllImport("user32")] + public static extern IntPtr WindowFromPoint(POINT p); + + [DllImport("user32.dll")] + public static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable); + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern short GetKeyState(int keyCode); + + [DllImport("user32.dll")] + public static extern bool IsZoomed(IntPtr hWnd); + //[DllImport("user32.dll")] + //public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); + + [System.Runtime.InteropServices.DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] + public static extern IntPtr BeginPaint(IntPtr hWnd, ref PAINTSTRUCT ps); + + [System.Runtime.InteropServices.DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] + public static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT ps); + + [DllImport("gdi32.dll")] + public static extern int ExcludeClipRect(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); + + [DllImport("user32")] + public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern bool GetTextMetrics(HandleRef hdc, TEXTMETRIC tm); + + [DllImport("user32.dll")] + public static extern bool SetMenu(IntPtr hWnd, IntPtr hMenu); + + [DllImport("user32.dll")] + public static extern IntPtr GetMenu(IntPtr hWnd); + + [DllImport("user32")] + public static extern bool RedrawWindow(IntPtr hWnd, [In] ref RECT lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags); + [DllImport("user32")] + public static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags); + + [DllImport("user32")] + public static extern bool GetWindowRect(IntPtr hWnd, ref RECT r); + + [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetScrollBarInfo")] + public static extern int GetScrollBarInfo(IntPtr hWnd, uint idObject, ref SCROLLBARINFO psbi); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi); + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern int SetScrollInfo(HandleRef hWnd, int fnBar, ref SCROLLINFO si, bool redraw); + + [DllImport("user32.dll")] + public static extern IntPtr GetWindowDC(IntPtr hWnd); + [DllImport("user32.dll")] + public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + public static extern bool AdjustWindowRectEx(ref RECT lpRect, int dwStyle, + bool bMenu, int dwExStyle); + + // This static method is required because legacy OSes do not support + // GetWindowLongPtr + public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex) + { + if (IntPtr.Size == 8) + return GetWindowLongPtr64(hWnd, nIndex); + else + return new IntPtr(GetWindowLong32(hWnd, nIndex)); + } + + [DllImport("user32.dll", EntryPoint = "GetWindowLong")] + public static extern int GetWindowLong32(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")] + public static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll")] + public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern int MapWindowPoints(IntPtr hwndFrom, IntPtr hwndTo, ref POINT lpPoints, [MarshalAs(UnmanagedType.U4)] int cPoints); + + [DllImport("user32")] + public static extern bool PostMessage(int hWnd, int Msg, int wParam, int lParam); + [DllImport("user32")] + public static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern bool DeleteDC(IntPtr hDC); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr CreateCompatibleDC(IntPtr hDC); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr CreateDIBSection(IntPtr hdc, BITMAPINFO pbmi, uint iUsage, int ppvBits, IntPtr hSection, uint dwOffset); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop); + + [DllImport("gdi32")] + public static extern bool DeleteObject(IntPtr hObject); + [DllImport("gdi32")] + public static extern bool DeleteObject(int hObject); + + public delegate void TimerDelegate(IntPtr hWnd, IntPtr uMsg, IntPtr idEvent, int dwTime); + [DllImport("user32.dll")] + public static extern UIntPtr SetTimer(IntPtr hWnd, UIntPtr nIDEvent, uint uElapse, TimerDelegate lpTimerFunc); + [DllImport("user32.dll")] + public static extern bool KillTimer(IntPtr hWnd, UIntPtr uIDEvent); + + #endregion + + #region Structures + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class TEXTMETRIC + { + public int tmHeight; + public int tmAscent; + public int tmDescent; + public int tmInternalLeading; + public int tmExternalLeading; + public int tmAveCharWidth; + public int tmMaxCharWidth; + public int tmWeight; + public int tmOverhang; + public int tmDigitizedAspectX; + public int tmDigitizedAspectY; + public char tmFirstChar; + public char tmLastChar; + public char tmDefaultChar; + public char tmBreakChar; + public byte tmItalic; + public byte tmUnderlined; + public byte tmStruckOut; + public byte tmPitchAndFamily; + public byte tmCharSet; + } + + [StructLayout(LayoutKind.Sequential)] + public struct SCROLLBARINFO + { + public int cbSize; + public RECT rcScrollBar; + public int dxyLineButton; + public int xyThumbTop; + public int xyThumbBottom; + public int reserved; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public int[] rgstate; + } + + public enum eScrollBarDirection + { + SB_HORZ = 0, + SB_VERT = 1 + } + + public enum eScrollInfoMask + { + SIF_RANGE = 0x1, + SIF_PAGE = 0x2, + SIF_POS = 0x4, + SIF_DISABLENOSCROLL = 0x8, + SIF_TRACKPOS = 0x10, + SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS + } + + [StructLayout(LayoutKind.Sequential)] + public struct SCROLLINFO + { + public int cbSize; + public int fMask; + public int nMin; + public int nMax; + public int nPage; + public int nPos; + public int nTrackPos; + } + + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public int x; + public int y; + + public POINT(System.Drawing.Point p) + { + this.x = p.X; + this.y = p.Y; + } + public POINT(int x, int y) + { + this.x = x; + this.y = y; + } + + public override string ToString() + { + return string.Format("{0},{1}", x, y); + } + } + public enum ShowWindowCommands : int + { + /// + /// Hides the window and activates another window. + /// + Hide = 0, + /// + /// Activates and displays a window. If the window is minimized or + /// maximized, the system restores it to its original size and position. + /// An application should specify this flag when displaying the window + /// for the first time. + /// + Normal = 1, + /// + /// Activates the window and displays it as a minimized window. + /// + ShowMinimized = 2, + /// + /// Maximizes the specified window. + /// + Maximize = 3, // is this the right value? + /// + /// Activates the window and displays it as a maximized window. + /// + ShowMaximized = 3, + /// + /// Displays a window in its most recent size and position. This value + /// is similar to , except + /// the window is not actived. + /// + ShowNoActivate = 4, + /// + /// Activates the window and displays it in its current size and position. + /// + Show = 5, + /// + /// Minimizes the specified window and activates the next top-level + /// window in the Z order. + /// + Minimize = 6, + /// + /// Displays the window as a minimized window. This value is similar to + /// , except the + /// window is not activated. + /// + ShowMinNoActive = 7, + /// + /// Displays the window in its current size and position. This value is + /// similar to , except the + /// window is not activated. + /// + ShowNA = 8, + /// + /// Activates and displays the window. If the window is minimized or + /// maximized, the system restores it to its original size and position. + /// An application should specify this flag when restoring a minimized window. + /// + Restore = 9, + /// + /// Sets the show state based on the SW_* value specified in the + /// STARTUPINFO structure passed to the CreateProcess function by the + /// program that started the application. + /// + ShowDefault = 10, + /// + /// Windows 2000/XP: Minimizes a window, even if the thread + /// that owns the window is not responding. This flag should only be + /// used when minimizing windows from a different thread. + /// + ForceMinimize = 11 + } + + public struct WINDOWPLACEMENT + { + public int length; + public int flags; + public int showCmd; + public POINT ptMinPosition; + public POINT ptMaxPosition; + public RECT rcNormalPosition; + } + /// + /// Retrieves the show state and the restored, minimized, and maximized positions of the specified window. + /// + /// + /// A handle to the window. + /// + /// + /// A pointer to the WINDOWPLACEMENT structure that receives the show state and position information. + /// + /// Before calling GetWindowPlacement, set the length member to sizeof(WINDOWPLACEMENT). GetWindowPlacement fails if lpwndpl-> length is not set correctly. + /// + /// + /// + /// If the function succeeds, the return value is nonzero. + /// + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + [DllImport("user32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl); + + [StructLayout(LayoutKind.Sequential)] + public struct NCCALCSIZE_PARAMS + { + public RECT rgrc0, rgrc1, rgrc2; + public IntPtr lppos; + } + + [StructLayout(LayoutKind.Sequential)] + public struct WINDOWPOS + { + public IntPtr hwnd; + public IntPtr hwndInsertAfter; + public int x, y; + public int cx, cy; + public int flags; + public override string ToString() + { + return string.Format("x={0}, y={1}, right={2}, bottom={3}", x, y, cx, cy); + } + } + + [Serializable, StructLayout(LayoutKind.Sequential)] + public struct RECT + { + public int Left; + public int Top; + public int Right; + public int Bottom; + + public RECT(int left_, int top_, int right_, int bottom_) + { + Left = left_; + Top = top_; + Right = right_; + Bottom = bottom_; + } + + public RECT(Rectangle r) + { + Left = r.Left; + Top = r.Top; + Right = r.Right; + Bottom = r.Bottom; + } + + public int Height { get { return Bottom - Top; } } + public int Width { get { return Right - Left; } } + public Size Size { get { return new Size(Width, Height); } } + + public Point Location { get { return new Point(Left, Top); } } + + // Handy method for converting to a System.Drawing.Rectangle + public Rectangle ToRectangle() + { return Rectangle.FromLTRB(Left, Top, Right, Bottom); } + + public static RECT FromRectangle(Rectangle rectangle) + { + return new RECT(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom); + } + + public override int GetHashCode() + { + return Left ^ ((Top << 13) | (Top >> 0x13)) + ^ ((Width << 0x1a) | (Width >> 6)) + ^ ((Height << 7) | (Height >> 0x19)); + } + + #region Operator overloads + + public static implicit operator Rectangle(RECT rect) + { + return Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom); + } + + public static implicit operator RECT(Rectangle rect) + { + return new RECT(rect.Left, rect.Top, rect.Right, rect.Bottom); + } + + public override string ToString() + { + return "Left=" + this.Left + ", Top=" + this.Top + ", Right=" + this.Right + ", Bottom=" + this.Bottom; + } + #endregion + } + + [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] + public struct PAINTSTRUCT + { + public IntPtr hdc; + public int fErase; + public WinApi.RECT rcPaint; + public int fRestore; + public int fIncUpdate; + public int Reserved1; + public int Reserved2; + public int Reserved3; + public int Reserved4; + public int Reserved5; + public int Reserved6; + public int Reserved7; + public int Reserved8; + } + + [StructLayout(LayoutKind.Sequential)] + public class BITMAPINFO + { + public int biSize = 0; + public int biWidth = 0; + public int biHeight = 0; + public short biPlanes = 0; + public short biBitCount = 0; + public int biCompression = 0; + public int biSizeImage = 0; + public int biXPelsPerMeter = 0; + public int biYPelsPerMeter = 0; + public int biClrUsed = 0; + public int biClrImportant = 0; + public byte bmiColors_rgbBlue = 0; + public byte bmiColors_rgbGreen = 0; + public byte bmiColors_rgbRed = 0; + public byte bmiColors_rgbReserved = 0; + } + + public enum eObjectId : uint + { + OBJID_CLIENT = 0xFFFFFFFC, + OBJID_VSCROLL = 0xFFFFFFFB, + OBJID_HSCROLL = 0xFFFFFFFA + } + + public enum eStateFlags + { + STATE_SYSTEM_INVISIBLE = 0x00008000, + STATE_SYSTEM_OFFSCREEN = 0x00010000, + STATE_SYSTEM_PRESSED = 0x00000008, + STATE_SYSTEM_UNAVAILABLE = 0x00000001 + } + #endregion + + #region Functions + public enum AppCommands + { + APPCOMMAND_BROWSER_BACKWARD = 1, + APPCOMMAND_BROWSER_FORWARD = 2 + } + private static int FAPPCOMMAND_MASK = 0xF000; + public static int GetAppCommandLParam(IntPtr lParam) + { + return HIWORD(lParam) & ~FAPPCOMMAND_MASK; + } + public static int LOWORD(int n) + { + return (short)(n & 0xffff); + } + public static int HIWORD(int n) + { + return (int)((n >> 0x10) & 0xffff); + } + public static int LOWORD(IntPtr n) + { + return LOWORD((int)((long)n)); + } + public static int HIWORD(IntPtr n) + { + return HIWORD((int)((long)n)); + } + + public static IntPtr CreateLParam(int loWord, int hiWord) + { + byte[] bx = BitConverter.GetBytes(loWord); + byte[] by = BitConverter.GetBytes(hiWord); + byte[] blp = new byte[] { bx[0], bx[1], by[0], by[1] }; + return new IntPtr(BitConverter.ToInt32(blp, 0)); + } + #endregion + + #region DWM + [StructLayout(LayoutKind.Sequential)] + public struct MARGINS + { + public int cxLeftWidth; + public int cxRightWidth; + public int cyTopHeight; + public int cyBottomHeight; + } + + [DllImport("dwmapi.dll")] + public static extern int DwmSetWindowAttribute( + IntPtr hWnd, + int dwAttribute, + ref int attributeValue, + int sizeOfValueRetrived + ); + [DllImport("dwmapi.dll")] + public static extern int DwmGetWindowAttribute( + IntPtr hwnd, + int dwAttribute, + ref int pvAttribute, + int sizeOfValueRetrived); + + [DllImport("dwmapi.dll", PreserveSig = false)] + static extern bool DwmIsCompositionEnabled(); + + [DllImport("dwmapi.dll")] + public static extern int DwmDefWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, out IntPtr plResult); + [DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "DefWindowProcW")] + public static extern IntPtr DefWindowProc(IntPtr hWnd, WindowsMessages Msg, IntPtr wParam, IntPtr lParam); + [DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "DefWindowProcW")] + public static extern IntPtr DefWindowProc(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); + + [DllImport("dwmapi.dll")] + public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins); + + public static void ExtendGlass(IntPtr handle, int glassHeight) + { + MARGINS margins = new MARGINS(); + margins.cxLeftWidth = 0; + margins.cxRightWidth = 0; + margins.cyTopHeight = glassHeight; + margins.cyBottomHeight = 0; + + int result = DwmExtendFrameIntoClientArea(handle, ref margins); + + } + + public static bool IsGlassEnabled + { + get + { + if (System.Environment.OSVersion.Version.Major < 6) + return false; + return DwmIsCompositionEnabled(); + } + } + + public enum DWMWINDOWATTRIBUTE : int + { + DWMWA_NCRENDERING_ENABLED = 1, + DWMWA_NCRENDERING_POLICY = 2, + DWMWA_TRANSITIONS_FORCEDISABLED = 3, + DWMWA_ALLOW_NCPAINT = 4, + DWMWA_LAST = 5 + } + + public enum DWMNCRENDERINGPOLICY : int + { + DWMNCRP_USEWINDOWSTYLE = 0, + DWMNCRP_DISABLED = 1, + DWMNCRP_ENABLED = 2, + DWMNCRP_LAST = 3 + } + + public enum WVR + { + ALIGNTOP = 0x0010, + ALIGNLEFT = 0x0020, + ALIGNBOTTOM = 0x0040, + ALIGNRIGHT = 0x0080, + HREDRAW = 0x0100, + VREDRAW = 0x0200, + VALIDRECTS = 0x0400, + REDRAW = HREDRAW | VREDRAW, + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/ModelYearViewConnector.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/ModelYearViewConnector.cs new file mode 100644 index 00000000..fa00571c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/ModelYearViewConnector.cs @@ -0,0 +1,395 @@ +#if FRAMEWORK20 +using System; +using DevComponents.Schedule.Model; +using System.ComponentModel; +using System.Collections.Generic; + +namespace DevComponents.DotNetBar.Schedule +{ + internal class ModelYearViewConnector : ModelViewConnector + { + #region Static data + + static private List _lineAppts; + + static private int _lineState; // Refresh state + static private DateTime _lineStartTime; // YearView start date + static private DateTime _lineEndTime; // YearView end date + + #endregion + + #region Private variables + + private CalendarModel _Model; // The associated CalendarModel + private YearView _View; // The associated YearView + + private bool _IsConnected; // Connection status + private int _ViewState; // View refresh state + + #endregion + + /// + /// Constructor + /// + /// Assoc CalendarModel + /// Assoc YearView + public ModelYearViewConnector(CalendarModel model, YearView yearView) + { + _Model = model; + _View = yearView; + } + + #region Public properties + + /// + /// Gets the connection status + /// + public override bool IsConnected + { + get { return _IsConnected; } + } + + #endregion + + #region Internal properties + + internal int ViewState + { + get { return (_ViewState); } + } + + #endregion + + #region Connect processing + + /// + /// Performs Model connection processing + /// + public override void Connect() + { + // Load the connection data + + if (_IsConnected) + Disconnect(); + + LoadData(_ViewState == _lineState); + + // Get notification on Model property changes + + _Model.PropertyChanged += ModelPropertyChanged; + _Model.SubPropertyChanged += ModelSubPropertyChanged; + _View.CalendarView.CustomItems.CollectionChanged += CustomItemsCollectionChanged; + + _IsConnected = true; + } + + #endregion + + #region Disconnect processing + + /// + /// Severs the Model/MonthView connection + /// + public override void Disconnect() + { + if (_IsConnected) + { + // Loop through each week, clearing each + // associated view connection + + for (int i = 0; i < _View.YearMonths.Length; i++) + _View.YearMonths[i].AppBits.SetAll(false); + + // Stop notification on Model property changes + + _Model.PropertyChanged -= ModelPropertyChanged; + _Model.SubPropertyChanged -= ModelSubPropertyChanged; + _View.CalendarView.CustomItems.CollectionChanged -= CustomItemsCollectionChanged; + + _IsConnected = false; + } + } + + #endregion + + #region LoadData processing + + /// + /// Loads Model/YearView connection data + /// + private void LoadData(bool reload) + { + if (reload == true || + _lineStartTime != _View.StartDate || _lineEndTime != _View.EndDate) + { + _lineStartTime = _View.StartDate; + _lineEndTime = _View.EndDate; + + _lineAppts = GetAppointmentList(_Model, _View.StartDate, _View.EndDate.AddDays(1)); + } + + if (reload == true) + _lineState = _lineState ^ 1; + + _ViewState = _lineState; + + foreach (YearMonth yearMonth in _View.YearMonths) + yearMonth.AppBits.SetAll(false); + + int rootMonth = _View.StartDate.Year * 12 + _View.StartDate.Month; + + for (int i = 0; i < _lineAppts.Count; i++) + { + Appointment app = _lineAppts[i]; + + if (IsAppointmentVisible(app) == true) + { + int day = app.StartTime.Day - 1; + int month = (app.StartTime.Year * 12 + app.StartTime.Month) - rootMonth; + + DateTime date = app.StartTime; + + if (month < 0) + { + day = 0; + month = 0; + + if (_View.YearMonths.Length > 0) + date = _View.YearMonths[0].StartDate; + } + + if (month < _View.YearMonths.Length) + { + YearMonth ym = _View.YearMonths[month]; + + while (date < app.EndTime || (date == app.EndTime && app.StartTime == app.EndTime)) + { + if (day >= ym.DaysInMonth) + { + month++; + + if (month >= _View.YearMonths.Length) + break; + + ym = _View.YearMonths[month]; + day = 0; + } + + ym.AppBits.Set(day++, true); + + date = date.AddDays(1); + } + } + } + } + + foreach (YearMonth yearMonth in _View.YearMonths) + UpdateCustomItems(yearMonth); + } + + #endregion + + #region UpdateCustomItems + + /// + /// UpdateCustomItems + /// + /// + private void UpdateCustomItems(YearMonth yearMonth) + { + CustomCalendarItemCollection items = _View.CalendarView.CustomItems; + + if (items != null && items.Count > 0) + { + for (int i = 0; i < items.Count; i++) + { + CustomCalendarItem item = items[i]; + + if (IsCustomItemVisible(item) == true && + (item.StartTime.Year == yearMonth.StartDate.Year && item.StartTime.Month == yearMonth.StartDate.Month)) + { + yearMonth.AppBits.Set(item.StartTime.Day - 1, true); + break; + } + } + } + } + + #endregion + + #region CustomItems_CollectionChanged + + /// + /// Handles CustomItemCollection change events + /// + /// + /// + void CustomItemsCollectionChanged(object sender, EventArgs e) + { + LoadData(_ViewState == _lineState); + + _View.NeedRecalcLayout = true; + _View.NeedRecalcSize = true; + } + + #endregion + + #region GetFirstAppointment + + /// + /// GetFirstAppointment + /// + /// + /// + internal Appointment GetFirstAppointment(DateTime date) + { + Appointment app = null; + AppointmentSubsetCollection asc = _Model.GetDay(date).Appointments; + + if (asc.Count > 0) + { + for (int i = 0; i < asc.Count; i++) + { + if (IsAppointmentVisible(asc[i]) == true) + { + if (app == null || asc[i].StartTime < app.StartTime) + app = asc[i]; + } + } + + return (app); + } + + return (null); + } + + #endregion + + #region GetFirstCustomItem + + /// + /// GetFirstCustomItem + /// + /// + /// + internal CustomCalendarItem GetFirstCustomItem(DateTime date) + { + CustomCalendarItemCollection items = _View.CalendarView.CustomItems; + + if (items != null && items.Count > 0) + { + for (int i = 0; i < items.Count; i++) + { + CustomCalendarItem item = items[i]; + + if (IsCustomItemVisible(item) == true && + (item.StartTime.Date == date.Date)) + { + return (item); + } + } + } + + return (null); + } + + #endregion + + #region GetView + + /// + /// Returns the Month view + /// + /// + public override eCalendarView GetView() + { + return (eCalendarView.Year); + } + + #endregion + + #region ResetModelData + + /// + /// ResetModelData + /// + static internal void ResetModelData() + { + _lineStartTime = DateTime.MinValue; + } + + #endregion + + #region ModelPropertyChanged + + /// + /// Handles Model property change notifications + /// + /// + /// + private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == CalendarModel.AppointmentsPropertyName) + { + LoadData(_ViewState == _lineState); + + _View.NeedRecalcSize = true; + _View.Refresh(); + } + } + + #endregion + + #region ModelSubPropertyChanged + + /// + /// Handles ModelSubProperty change notifications + /// + /// object + /// SubPropertyChangedEventArgs + private void ModelSubPropertyChanged(object sender, SubPropertyChangedEventArgs e) + { + if (e.Source is Owner) + { + Owner owner = (Owner)e.Source; + + if (_View.OwnerKey != null && _View.OwnerKey.Equals(owner.Key)) + { + if (e.PropertyChangedArgs.PropertyName == Owner.DisplayNamePropertyName) + _View.DisplayName = owner.DisplayName; + + else if (e.PropertyChangedArgs.PropertyName.Equals("ColorScheme")) + _View.CalendarColor = owner.ColorScheme; + } + } + else if (e.Source is Appointment) + { + Appointment app = e.Source as Appointment; + + string name = e.PropertyChangedArgs.PropertyName; + + if (name.Equals("OwnerKey")) + { + if (_View.CalendarView.IsMultiCalendar == true) + { + if (_View.OwnerKey == app.OwnerKey) + { + LoadData(_ViewState == _lineState); + + _View.NeedRecalcSize = true; + _View.Refresh(); + } + } + } + else if (name.Equals("Visible")) + { + LoadData(true); + } + } + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/YearMonth.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/YearMonth.cs new file mode 100644 index 00000000..fa4d3f57 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/YearMonth.cs @@ -0,0 +1,1119 @@ +#if FRAMEWORK20 +using System; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.Schedule +{ + public class YearMonth + { + #region Private constants + + private const int MaxRows = 6; + private const int MaxCols = 7; + private const int MaxDays = (MaxRows * MaxCols); + + private const int CellPadding = 4; + + #endregion + + #region Private variables + + private YearView _YearView; + + private DateTime _RootDate; + private DateTime _StartDate; + private DateTime _EndDate; + + private Rectangle _Bounds; + private Rectangle _ContentBounds; + private Rectangle _MonthHeaderBounds; + private Rectangle _DayOfWeekHeaderBounds; + + private int _DaysInMonth; + private int _DaysOffset; + + private ItemRects _DayRects; + + private BitArray _AppBits; + private bool _DaysSelected; + + private DaysOfTheWeek.eDayType _DayType = DaysOfTheWeek.eDayType.None; + + #endregion + + /// + /// Constructor + /// + /// + /// + public YearMonth(YearView yearView, DateTime date) + { + _YearView = yearView; + + StartDate = date; + + _DayRects = new ItemRects(yearView, MaxDays); + _AppBits = new BitArray(32); + } + + #region Internal properties + + #region AppBits + + /// + /// Appointment (and CustomItem) bit array + /// + internal BitArray AppBits + { + get { return (_AppBits); } + set { _AppBits = value; } + } + + #endregion + + #region DayOfWeekHeaderHeight + + /// + /// DayOfWeekHeaderHeight + /// + internal int DayOfWeekHeaderHeight + { + get { return (_YearView.Font.Height + 4); } + } + + #endregion + + #region DayRects + + /// + /// Gets the day Rectangles + /// + internal ItemRects DayRects + { + get { return (_DayRects); } + } + + #endregion + + #region MonthHeaderHeight + + /// + /// MonthHeaderHeight + /// + internal int MonthHeaderHeight + { + get { return (_YearView.Font.Height + 4); } + } + + #endregion + + #endregion + + #region Public properties + + #region Bounds + + /// + /// Gets and sets the week bounding Rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + + internal set + { + if (_Bounds.Equals(value) == false) + { + _Bounds = value; + _DayType = DaysOfTheWeek.eDayType.None; + + CalcBoundingRects(); + CalcDayRects(); + } + } + } + + #endregion + + #region DaysInMonth + + /// + /// Gets the number of Days in the Month + /// + public int DaysInMonth + { + get { return (_DaysInMonth); } + } + + #endregion + + #region StartDate + + /// + /// Gets or sets the month starting date + /// + public DateTime StartDate + { + get { return (_StartDate); } + + internal set + { + value = value.Date.AddDays(-(value.Day - 1)); + + if (_StartDate.Equals(value) == false) + { + _StartDate = value; + + _DaysInMonth = DateTime.DaysInMonth(_StartDate.Year, _StartDate.Month); + _RootDate = DateHelper.GetDateForDayOfWeek(_StartDate, DateHelper.GetFirstDayOfWeek()); + _EndDate = _StartDate.AddDays(_DaysInMonth).AddDays(-1); + + _DaysOffset = (_StartDate.Date - _RootDate.Date).Days; + } + } + } + + #endregion + + #region EndDate + + /// + /// Gets the month end date + /// + public DateTime EndDate + { + get { return (_EndDate); } + } + + #endregion + + #region YearView + + /// + /// Gets the parent YearView + /// + public YearView YearView + { + get { return (_YearView); } + } + + #endregion + + #endregion + + #region CalcBoundingRects + + /// + /// Calculates the control's Bounding Rects + /// + private void CalcBoundingRects() + { + // Calculate main content bounding rects + + _ContentBounds = _Bounds; + _ContentBounds.Y += (MonthHeaderHeight + DayOfWeekHeaderHeight); + _ContentBounds.Height -= (MonthHeaderHeight + DayOfWeekHeaderHeight); + + _MonthHeaderBounds = _Bounds; + _MonthHeaderBounds.Height = MonthHeaderHeight; + + _DayOfWeekHeaderBounds = _Bounds; + _DayOfWeekHeaderBounds.Y += MonthHeaderHeight; + _DayOfWeekHeaderBounds.Height = DayOfWeekHeaderHeight; + } + + #endregion + + #region CalcDayRects + + /// + /// Calculates the day rectangles for the + /// current bounding rectangle + /// + private void CalcDayRects() + { + // Loop through each day in the week + + Size cellSize = _YearView.CellSize; + Rectangle r = new Rectangle(_Bounds.Location, cellSize); + + r.X += CellPadding; + r.Y += DayOfWeekHeaderHeight + MonthHeaderHeight + CellPadding; + + int bWidth = _Bounds.Width - (CellPadding * 2); + int bHeight = _Bounds.Height - (DayOfWeekHeaderHeight + MonthHeaderHeight) - (CellPadding * 2); + + int dx = (bWidth - (cellSize.Width * MaxCols)) / MaxCols; + int dy = (bHeight - (cellSize.Height * MaxRows)) / MaxRows; + + int width = (dx + cellSize.Width) * MaxCols; + int colSpread = (width < bWidth) ? bWidth - width : 0; + + int height = (dy + cellSize.Height) * MaxRows; + int rowSpread = (height < bHeight) ? bHeight - height : 0; + + for (int i = 0; i < MaxRows; i++) + { + r.Height = cellSize.Height + dy; + + if (i < rowSpread) + r.Height++; + + for (int j = 0; j < MaxCols; j++) + { + r.Width = cellSize.Width + dx; + + if (j < colSpread) + r.Width++; + + _DayRects[i * MaxCols + j].Bounds = r; + + r.X += r.Width; + } + + r.X = _Bounds.X + CellPadding; + r.Y += r.Height; + } + } + + #endregion + + #region GetDateFromIndex + + /// + /// Gets the month date from the given day index + /// + /// + /// + public DateTime GetDateFromIndex(int dayIndex) + { + if ((uint)dayIndex < MaxDays) + return (_RootDate.AddDays(dayIndex).Date); + + return (_RootDate.Date); + } + + #endregion + + #region GetDateFromPoint + + /// + /// Gets the month date from the given Point + /// + /// + /// + /// + public bool GetDateFromPoint(Point pt, ref DateTime date) + { + int dayIndex = GetDayIndexFromPoint(pt); + + if (dayIndex >= _DaysOffset && dayIndex < _DaysOffset + _DaysInMonth) + { + date = _RootDate.AddDays(dayIndex); + + return (true); + } + + return (false); + } + + #endregion + + #region GetViewAreaFromPoint + + /// + /// Gets the month view area from the given Point + /// + /// + /// + public eViewArea GetViewAreaFromPoint(Point pt) + { + if (_ContentBounds.Contains(pt)) + return (eViewArea.InContent); + + if (_MonthHeaderBounds.Contains(pt)) + return (eViewArea.InMonthHeader); + + if (_DayOfWeekHeaderBounds.Contains(pt)) + return (eViewArea.InDayOfWeekHeader); + + return (eViewArea.NotInView); + } + + #endregion + + #region GetNormalizedDayIndex + + /// + /// Gets the normalized month date for the given dayIndex + /// + /// + /// + internal int GetNormalizedDayIndex(int dayIndex) + { + if (dayIndex < _DaysOffset) + dayIndex = _DaysOffset; + + else if (dayIndex >= _DaysOffset + _DaysInMonth) + dayIndex = _DaysOffset + _DaysInMonth - 1; + + return (dayIndex); + } + + #endregion + + #region GetDayIndexFromPoint + + /// + /// Gets the month dayIndex from the given Point + /// + /// + /// + internal int GetDayIndexFromPoint(Point pt) + { + for (int i = 0; i < MaxDays; i++) + { + if (_DayRects[i].Bounds.Contains(pt)) + return (i); + } + + return (-1); + } + + #endregion + + #region GetDayIndexFromDate + + /// + /// Gets the month dayIndex from the given date + /// + /// + /// + internal int GetDayIndexFromDate(DateTime date) + { + if (ContainsDate(date) == true) + return (date.Day - _StartDate.Day + _DaysOffset); + + return (-1); + } + + #endregion + + #region ContainsDate + + /// + /// Determines if the given date is contained in the month + /// + /// + /// + public bool ContainsDate(DateTime date) + { + return (date >= _StartDate && date <= _EndDate); + } + + #endregion + + #region DayHasAppointments + + /// + /// Determines if the given day of the month has + /// Appointments or CustomItems associated with it + /// + /// Day of the month + /// true, if there are Appointments associated with this day + public bool DayHasAppointments(int day) + { + return (DayIndexHasAppointments(day + _DaysOffset - 1)); + } + + /// + /// Determines if the given dayIndex has + /// Appointments or CustomItems associated with it + /// + /// + /// + internal bool DayIndexHasAppointments(int dayIndex) + { + dayIndex -= _DaysOffset; + + return (_AppBits.Count > (uint)dayIndex && _AppBits[dayIndex] == true); + + } + + #endregion + + #region DayIsSelected + + /// + /// Determines if the given day of the month is selected + /// + /// Day of the month + /// true if selected + public bool DayIsSelected(int day) + { + day += (_DaysOffset - 1); + + return (_DayRects.Rects.Length > (uint)day && _DayRects[day].IsSelected == true); + } + + #endregion + + #region UpdateDateSelection + + /// + /// Updates the date selection for the month + /// + internal void UpdateDateSelection() + { + if (_YearView.DateSelectionStart.HasValue == false || + _YearView.DateSelectionEnd.HasValue == false) + { + ClearSelection(); + } + else + { + DateTime selStart = _YearView.DateSelectionStart.Value; + DateTime selEnd = _YearView.DateSelectionEnd.Value; + + if (_StartDate > selEnd || _EndDate < selStart) + { + ClearSelection(); + } + else + { + _DaysSelected = false; + + DateTime startDate = _StartDate; + + for (int i = 0; i < _DaysInMonth; i++) + { + DateTime endDate = startDate.AddDays(1); + + bool selected = (endDate > selStart && startDate < selEnd); + + DayRects[i + _DaysOffset].IsSelected = selected; + + _DaysSelected |= selected; + + startDate = startDate.AddDays(1); + } + } + } + } + + #region ClearSelection + + /// + /// ClearSelection + /// + private void ClearSelection() + { + if (_DaysSelected == true) + { + for (int i = 0; i < MaxDays; i++) + _DayRects[i].IsSelected = false; + + _DaysSelected = false; + } + } + + #endregion + + #endregion + + #region GetPreferredSize + + /// + /// Gets the Preferred control size for the month + /// + /// + internal Size GetPreferredSize() + { + Size size = _YearView.CellSize; + + size.Width = (size.Width + CellPadding) * MaxCols; + + size.Height = (size.Height + CellPadding) * MaxRows + + DayOfWeekHeaderHeight + MonthHeaderHeight; + + return (size); + } + + #endregion + + #region Paint + + /// + /// Paint + /// + /// + /// + internal void Paint(ItemPaintArgs e, bool isNow) + { + DrawContent(e); + + DrawMonthHeader(e, isNow); + DrawDayOfWeekHeader(e, isNow); + DrawBorder(e, isNow); + } + + #region DrawContent + + /// + /// DrawContent + /// + /// + private void DrawContent(ItemPaintArgs e) + { + DrawBackground(e); + DrawDayContent(e); + DrawGridLines(e); + DrawNowHighlight(e); + } + + #region DrawBackground + + /// + /// DrawBackground + /// + /// + private void DrawBackground(ItemPaintArgs e) + { + Graphics g = e.Graphics; + + using (Brush br = _YearView.ViewColor.BrushPart( + (int)eCalendarMonthPart.DayContentActiveBackground, _ContentBounds)) + { + g.FillRectangle(br, _Bounds); + } + } + + #endregion + + #region DrawDayContent + + /// + /// DrawDayContent + /// + /// + private void DrawDayContent(ItemPaintArgs e) + { + Graphics g = e.Graphics; + + Color color1 = _YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayContactInactiveBackground); + Color color2 = _YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayContentActiveBackground); + + DateTime date = _StartDate; + + for (int i = 0; i < _DaysInMonth; i++) + { + ItemRect ir = _DayRects[i + _DaysOffset]; + + DrawDayContentBackground(g, date, ir, color1, color2); + DrawDayContentText(g, date, ir); + + date = date.AddDays(1); + } + } + + #region DrawDayContentBackground + + /// + /// DrawDayContentBackground + /// + /// + /// + /// + /// + /// + private void DrawDayContentBackground(Graphics g, + DateTime date, ItemRect ir, Color color1, Color color2) + { + CalendarView cv = _YearView.CalendarView; + + if (_YearView.AllowDateSelection == false || ir.IsSelected == false) + { + if (_AppBits.Get(date.Day - 1) == true) + { + using (Brush br = _YearView.ViewColor.BrushPart( + (int) eCalendarMonthPart.ContentLinkBackground, ir.Bounds)) + { + g.FillRectangle(br, ir.Bounds); + } + } + } + + eYearViewLinkStyle linkStyle = cv.YearViewAppointmentLinkStyle; + + if (cv.DoYearViewDrawDayBackground( + g, this, date, ir.Bounds, ref linkStyle) == false) + { + if (_YearView.AllowDateSelection == true && ir.IsSelected == true) + { + using (Brush br = _YearView.ViewColor.BrushPart( + (int) eCalendarMonthPart.DayContentSelectionBackground, ir.Bounds)) + { + g.FillRectangle(br, ir.Bounds); + } + } + + if (_AppBits.Get(date.Day - 1) == true) + { + if (ir.IsSelected == false) + DrawDayHighLight(g, linkStyle, ir.Bounds, color1, color2); + } + } + } + + #endregion + + #region DrawDayContentText + + /// + /// DrawDayContentText + /// + /// + /// + /// + private void DrawDayContentText( + Graphics g, DateTime date, ItemRect ir) + { + if (_YearView.CalendarView.DoYearViewDrawDayText(g, this, date, ir.Bounds) == false) + { + Font font = _YearView.Font; + Color color = _YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayHeaderForeground); + + if (_AppBits.Get(date.Day - 1) == true) + { + font = _YearView.BoldFont; + color = _YearView.ViewColor.GetColor((int)eCalendarMonthPart.ContentLinkForeground); + } + + TextDrawing.DrawString(g, date.Day.ToString(), font, color, ir.Bounds, + eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter | + eTextFormat.NoPadding); + } + } + + #endregion + + #endregion + + #region DrawDayHighLight + + /// + /// Draws the day highlight + /// + /// + /// + /// + /// + /// + private void DrawDayHighLight(Graphics g, + eYearViewLinkStyle style, Rectangle r, Color color1, Color color2) + { + switch (style) + { + case eYearViewLinkStyle.Style1: + DrawDayHighLightStyle1(g, r, color1, color2); + break; + + case eYearViewLinkStyle.Style2: + DrawDayHighLightStyle2(g, r, color1, color2); + break; + + case eYearViewLinkStyle.Style3: + DrawDayHighLightStyle3(g, r, color1, color2); + break; + + case eYearViewLinkStyle.Style4: + DrawDayHighLightStyle4(g, r, color1, color2); + break; + + case eYearViewLinkStyle.Style5: + DrawDayHighLightStyle5(g, r, color1); + break; + } + } + + #region DrawDayHighLightStyle1 + + private void DrawDayHighLightStyle1(Graphics g, Rectangle r, Color color1, Color color2) + { + using (Brush br = new LinearGradientBrush(r, color2, color1, 45f)) + g.FillRectangle(br, r); + } + + #endregion + + #region DrawDayHighLightStyle2 + + private void DrawDayHighLightStyle2(Graphics g, Rectangle r, Color color1, Color color2) + { + using (GraphicsPath path = new GraphicsPath()) + { + Rectangle t = r; + + if (t.Height > t.Width) + { + t.Y += (t.Height - t.Width) / 2; + t.Height = t.Width; + } + else if (t.Width > t.Height) + { + t.X += (t.Width - t.Height) / 2; + t.Width = t.Height; + } + + t.Inflate(2, 2); + + path.AddEllipse(t); + + using (PathGradientBrush pbr = new PathGradientBrush(path)) + { + pbr.CenterPoint = new + PointF(r.X + r.Width / 2, r.Y + r.Height / 2); + + pbr.CenterColor = color1; + pbr.SurroundColors = new Color[] { color2 }; + + g.FillPath(pbr, path); + } + } + } + + #endregion + + #region DrawDayHighLightStyle3 + + private void DrawDayHighLightStyle3(Graphics g, Rectangle r, Color color1, Color color2) + { + r.Height /= 2; + + using (LinearGradientBrush br = new LinearGradientBrush(r, color1, color2, 90f)) + { + r.Height *= 2; + br.WrapMode = WrapMode.TileFlipXY; + + g.FillRectangle(br, r); + } + } + + #endregion + + #region DrawDayHighLightStyle4 + + private void DrawDayHighLightStyle4(Graphics g, Rectangle r, Color color1, Color color2) + { + r.Width /= 2; + + using (LinearGradientBrush br = new LinearGradientBrush(r, color1, color2, 0f)) + { + r.Width *= 2; + br.WrapMode = WrapMode.TileFlipXY; + + g.FillRectangle(br, r); + } + } + + #endregion + + #region DrawDayHighLightStyle5 + + private void DrawDayHighLightStyle5(Graphics g, Rectangle r, Color color1) + { + using (Brush br = new SolidBrush(color1)) + g.FillRectangle(br, r); + } + + #endregion + + #endregion + + #region DrawGridLines + + /// + /// DrawGridLines + /// + /// + private void DrawGridLines(ItemPaintArgs e) + { + if (_YearView.ShowGridLines == true) + { + Graphics g = e.Graphics; + + using (Pen pen = new Pen( + ControlPaint.Light(_YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayContentBorder)))) + { + int right = DayRects[MaxCols - 1].Bounds.Right; + + for (int i = 1; i < MaxRows; i++) + { + Point pt1 = DayRects[i * MaxCols].Bounds.Location; + Point pt2 = new Point(right, pt1.Y); + + g.DrawLine(pen, pt1, pt2); + } + + int bottom = DayRects[(MaxRows - 1) * MaxCols].Bounds.Bottom; + + for (int i = 1; i < MaxCols; i++) + { + Point pt1 = DayRects[i].Bounds.Location; + Point pt2 = new Point(pt1.X, bottom); + + g.DrawLine(pen, pt1, pt2); + } + } + } + } + + #endregion + + #region DrawNowHighlight + + /// + /// DrawNowHighlight + /// + /// + private void DrawNowHighlight(ItemPaintArgs e) + { + if (_YearView.CalendarView.HighlightCurrentDay) + { + Graphics g = e.Graphics; + + int nowDay = GetDayIndexFromDate(DateTime.Now); + + if (nowDay >= 0) + { + Rectangle r = DayRects[nowDay].Bounds; + + using (Pen pen = new Pen( + _YearView.ViewColor.GetColor((int)eCalendarMonthPart.NowDayHeaderBorder), 1)) + { + r.Inflate(-1, -1); + + g.DrawRectangle(pen, r); + } + + using (Pen pen = new Pen( + _YearView.ViewColor.GetColor((int)eCalendarMonthPart.DayContentActiveBackground))) + { + r.Inflate(1, 1); + + g.DrawRectangle(pen, r); + } + } + } + } + + #endregion + + #endregion + + #region DrawMonthHeader + + /// + /// DrawMonthHeader + /// + /// + /// + private void DrawMonthHeader(ItemPaintArgs e, bool isNow) + { + Graphics g = e.Graphics; + + // Draw the header background + + Rectangle r = _MonthHeaderBounds; + + if (r.Width > 0 && r.Height > 0) + { + if (isNow == true) + { + using (Brush br = _YearView.ViewColor.BrushPart( + (int)eCalendarMonthPart.NowDayHeaderBackground, r)) + { + g.FillRectangle(br, r); + } + } + else + { + using (Brush br = _YearView.ViewColor.BrushPart( + (int) eCalendarMonthPart.DayHeaderBackground, r)) + { + g.FillRectangle(br, r); + } + } + + // Draw the header content + + string s = String.Format("{0:y}", _StartDate); + + Color color = _YearView.ViewColor.GetColor(isNow == true + ? (int)eCalendarMonthPart.NowDayHeaderForeground + : (int)eCalendarMonthPart.DayHeaderForeground); + + TextDrawing.DrawString(g, s, _YearView.Font, color, _MonthHeaderBounds, + eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter | eTextFormat.NoPadding); + } + } + + #endregion + + #region DrawDayOfWeekHeader + + /// + /// DrawDayOfWeekHeader + /// + /// + /// + private void DrawDayOfWeekHeader(ItemPaintArgs e, bool isNow) + { + Graphics g = e.Graphics; + + // Draw the header background + + Rectangle r = _DayOfWeekHeaderBounds; + + if (r.Width > 0 && r.Height > 0) + { + if (isNow == true) + { + using (Brush br = _YearView.ViewColor.BrushPart( + (int)eCalendarMonthPart.NowDayHeaderBackground, r)) + { + g.FillRectangle(br, r); + } + } + else + { + using (Brush br = _YearView.ViewColor.BrushPart( + (int)eCalendarMonthPart.DayOfTheWeekHeaderBackground, r)) + { + g.FillRectangle(br, r); + } + } + + // Establish our Days Of The Week text type + + DaysOfTheWeek.eDayType type = GetDaysOfTheWeekType(e); + + // Loop through each day, drawing the + // day of the week text in the header area + + const eTextFormat tf = eTextFormat.VerticalCenter | + eTextFormat.HorizontalCenter | eTextFormat.NoPadding; + + r = _DayOfWeekHeaderBounds; + + int width = r.Width / MaxCols; + int spread = r.Width - (width * MaxCols); + + Color color = _YearView.ViewColor.GetColor(isNow == true + ? (int)eCalendarMonthPart.NowDayHeaderForeground + : (int)eCalendarMonthPart.DayOfTheWeekHeaderForeground); + + for (int i = 0; i < MaxCols; i++) + { + r.Width = width; + + if (i < spread) + r.Width++; + + TextDrawing.DrawString(g, + _YearView.DaysOfTheWeek.DayText[(int)type][i], _YearView.Font, color, r, tf); + + r.X += r.Width; + } + } + } + + #endregion + + #region DrawBorder + + /// + /// DrawBorder + /// + /// + /// + private void DrawBorder(ItemPaintArgs e, bool isNow) + { + Graphics g = e.Graphics; + + if (isNow == true) + { + using (Pen pen = new Pen(_YearView.ViewColor.GetColor( + (int)eCalendarMonthPart.NowDayHeaderBorder))) + { + g.DrawRectangle(pen, _MonthHeaderBounds); + g.DrawRectangle(pen, _DayOfWeekHeaderBounds); + g.DrawRectangle(pen, _ContentBounds); + } + } + else + { + using (Pen pen = new Pen( + _YearView.ViewColor.GetColor((int) eCalendarMonthPart.DayContentBorder))) + { + g.DrawRectangle(pen, _MonthHeaderBounds); + g.DrawRectangle(pen, _DayOfWeekHeaderBounds); + } + + using (Pen pen = new Pen( + _YearView.ViewColor.GetColor((int) eCalendarMonthPart.DayHeaderBorder))) + { + g.DrawRectangle(pen, _ContentBounds); + } + } + } + + #endregion + + #region GetDaysOfTheWeekType + + /// + /// GetDaysOfTheWeekType + /// + /// + /// + private DaysOfTheWeek.eDayType GetDaysOfTheWeekType(ItemPaintArgs e) + { + if (_DayType != DaysOfTheWeek.eDayType.None) + return (_DayType); + + Graphics g = e.Graphics; + + _YearView.DaysOfTheWeek.MeasureText(g, _YearView.Font); + + int width = _Bounds.Width/MaxCols; + + for (int i = 0; i < MaxCols; i++) + { + if (_YearView.DaysOfTheWeek.DaySize[ + (int) DaysOfTheWeek.eDayType.Long][i].Width > width) + { + if (_YearView.DaysOfTheWeek.DaySize[ + (int) DaysOfTheWeek.eDayType.Short][i].Width > width) + { + return (DaysOfTheWeek.eDayType.Single); + } + + return (DaysOfTheWeek.eDayType.Short); + } + } + + return (DaysOfTheWeek.eDayType.Long); + } + + #endregion + + #endregion + + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/YearView.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/YearView.cs new file mode 100644 index 00000000..0a1d2a90 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/YearView.cs @@ -0,0 +1,1678 @@ +#if FRAMEWORK20 +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.Schedule.Model; + +namespace DevComponents.DotNetBar.Schedule +{ + public class YearView : BaseView + { + #region Constants + + private const int MaxNumberOfMonths = 120; + + #endregion + + #region Private variables + + private YearMonth[] _YearMonths; // Array of YearMonths + private int _NumberOfMonths; // Number of months in display + private int _NumberOfCols; + private int _NumberOfRows; + + private CalendarMonthColor _ViewColor = + new CalendarMonthColor(eCalendarColor.Automatic); + + private bool _RecalcInProgress; + + private int _MouseDownMonthIndex = -1; + private int _MouseDownDayIndex = -1; + private int _LastMouseDownDayIndex = -1; + private DateTime _LastMouseUpTime = DateTime.MinValue; + + private int _VScrollPos; + + private Size _PreferredSize; + private Size _CellSize; + + #endregion + + /// + /// Constructor + /// + /// Parent CalendarView + public YearView(CalendarView calendarView) + : base(calendarView, eCalendarView.Year) + { + // Set our non-client drawing info and our CalendarColor + + NClientData = new NonClientData( + eTabOrientation.Horizontal, + (int)eCalendarMonthPart.OwnerTabBorder, + (int)eCalendarMonthPart.OwnerTabForeground, + (int)eCalendarMonthPart.OwnerTabBackground, + (int)eCalendarMonthPart.OwnerTabContentBackground, + (int)eCalendarMonthPart.OwnerTabSelectedForeground, + (int)eCalendarMonthPart.OwnerTabSelectedBackground); + + CalendarColorTable = _ViewColor; + + // Hook onto needed event + + HookEvents(true); + } + + #region Internal properties + + #region AllowDateSelection + + /// + /// Gets whether date selections are permitted + /// + internal bool AllowDateSelection + { + get { return (CalendarView.YearViewAllowDateSelection); } + } + + #endregion + + #region CellSize + + /// + /// Gets the default day cell size + /// + internal Size CellSize + { + get + { + if (_CellSize.IsEmpty) + { + Control container = GetContainerControl(true) as Control; + + if (container != null) + { + using (Graphics g = BarFunctions.CreateGraphics(container)) + _CellSize = g.MeasureString("00", Font).ToSize(); + } + } + + return (_CellSize); + } + } + + #endregion + + #region ShowGridLines + + /// + /// Gets whether Grid lines are to be displayed + /// + internal bool ShowGridLines + { + get { return (CalendarView.YearViewShowGridLines); } + } + + #endregion + + #region YearViewAppointmentLink + + /// + /// Gets the Appointment Link click style + /// + internal eYearViewDayLink YearViewAppointmentLink + { + get { return (CalendarView.YearViewAppointmentLink); } + } + + #endregion + + #region YearViewNonAppointmentLink + + /// + /// Gets the non-Appointment Link click style + /// + internal eYearViewDayLink YearViewNonAppointmentLink + { + get { return (CalendarView.YearViewNonAppointmentLink); } + } + + #endregion + + #region ViewColor + + /// + /// Gets the Month Color table + /// + internal CalendarMonthColor ViewColor + { + get { return (_ViewColor); } + } + + #endregion + + #region VsPanel + + /// + /// Gets the Year vertical scroll panel + /// + private VScrollPanel VsPanel + { + get { return (CalendarView.YearVScrollPanel); } + } + + #endregion + + #endregion + + #region Public properties + + #region Font + + /// + /// Gets or sets the display font + /// + [Category("Behavior")] + [Description("Indicates the display font.")] + public override Font Font + { + get { return (base.Font ?? CalendarView.Font); } + + set + { + base.Font = value; + + if (DaysOfTheWeek != null) + DaysOfTheWeek.NeedsMeasured = true; + + _CellSize = Size.Empty; + _PreferredSize = Size.Empty; + } + } + + #endregion + + #region YearMonths + + /// + /// Gets the array of YearMonths + /// + public YearMonth[] YearMonths + { + get { return (_YearMonths); } + } + + #endregion + + #endregion + + #region HookEvents + + /// + /// Hooks (or unhooks) needed events + /// + /// True to hook, false to unhook + private void HookEvents(bool hook) + { + if (hook == true) + { + CalendarView.SelectedViewChanged += SelectedViewChanged; + CalendarView.YearViewStartDateChanged += YearViewStartDateChanged; + CalendarView.YearViewEndDateChanged += YearViewEndDateChanged; + CalendarView.YearViewShowGridLinesChanged += YearViewShowGridLinesChanged; + CalendarView.YearViewAllowDateSelectionChanged += YearViewAllowDateSelectionChanged; + CalendarView.YearVScrollPanel.ScrollBarChanged += VScrollPanelScrollBarChanged; + } + else + { + CalendarView.SelectedViewChanged -= SelectedViewChanged; + CalendarView.YearViewStartDateChanged -= YearViewStartDateChanged; + CalendarView.YearViewEndDateChanged -= YearViewEndDateChanged; + CalendarView.YearViewShowGridLinesChanged -= YearViewShowGridLinesChanged; + CalendarView.YearViewAllowDateSelectionChanged -= YearViewAllowDateSelectionChanged; + CalendarView.YearVScrollPanel.ScrollBarChanged -= VScrollPanelScrollBarChanged; + } + } + + #endregion + + #region Event handling + + #region SelectedViewChanged + + /// + /// Processes CalendarView SelectedViewChanged events + /// + /// CalendarView + /// SelectedViewEventArgs + void SelectedViewChanged(object sender, SelectedViewEventArgs e) + { + IsViewSelected = (e.NewValue == eCalendarView.Year); + + if (IsViewSelected == true && Displayed == true) + { + AutoSyncViewDate(e.OldValue); + + UpdateView(); + UpdateDateSelection(); + } + else + { + ResetView(); + } + } + + #endregion + + #region YearViewStartDateChanged + + /// + /// Processes StartDate changes + /// + /// + /// + void YearViewStartDateChanged(object sender, DateChangeEventArgs e) + { + StartDate = e.NewValue; + } + + #endregion + + #region YearViewEndDateChanged + + /// + /// Processes EndDate changes + /// + /// + /// + void YearViewEndDateChanged(object sender, DateChangeEventArgs e) + { + EndDate = e.NewValue; + } + + #endregion + + #region YearViewAllowDateSelectionChanged + + /// + /// Handles YearViewAllowDateSelectionChanged events + /// + /// + /// + void YearViewAllowDateSelectionChanged(object sender, AllowDateSelectionChangedEventArgs e) + { + Refresh(); + } + + #endregion + + #region YearViewShowGridLinesChanged + + /// + /// Processes CalendarView YearViewShowGridLinesChanged events + /// + /// CalendarView + /// SelectedViewEventArgs + void YearViewShowGridLinesChanged(object sender, ShowGridLinesChangedEventArgs e) + { + Refresh(); + } + + #endregion + + #region VScrollPanel_ScrollBarChanged + + /// + /// Handles ScrollBarChanged events + /// + /// + /// + void VScrollPanelScrollBarChanged(object sender, EventArgs e) + { + int vdelta = -VsPanel.ScrollBar.Value - _VScrollPos; + + if (vdelta != 0) + { + _VScrollPos = -VsPanel.ScrollBar.Value; + + // Offset our DayColumn accordingly + + for (int i = 0; i < _NumberOfMonths; i++) + { + YearMonth ym = _YearMonths[i]; + + Rectangle r = ym.Bounds; + r.Y += vdelta; + + ym.Bounds = r; + } + + // Redraw our view + + InvalidateRect(); + } + } + + #endregion + + #endregion + + #region GetViewAreaFromPoint + + /// + /// Gets the view area under the given mouse + /// point (tab, header, content, etc) + /// + /// Point + /// eViewArea + public override eViewArea GetViewAreaFromPoint(Point pt) + { + if (Bounds.Contains(pt) == true) + { + if (ClientRect.Contains(pt)) + { + for (int i = 0; i < _NumberOfMonths; i++) + { + eViewArea area = _YearMonths[i].GetViewAreaFromPoint(pt); + + if (area != eViewArea.NotInView) + return (area); + } + + return (eViewArea.NotInView); + } + + return (base.GetViewAreaFromPoint(pt)); + } + + return (eViewArea.NotInView); + } + + #endregion + + #region GetDateSelectionFromPoint + + /// + /// Gets the date selection from the given point. + /// + /// Point in question + /// out start date + /// out end date + /// True if a valid selection exists + /// at the given point + public override bool GetDateSelectionFromPoint( + Point pt, out DateTime startDate, out DateTime endDate) + { + base.GetDateSelectionFromPoint(pt, out startDate, out endDate); + + int monthIndex = GetMonthIndexFromPoint(pt); + + if (monthIndex >= 0) + { + if (_YearMonths[monthIndex].GetDateFromPoint(pt, ref startDate)) + { + endDate = startDate.AddDays(1); + + return (true); + } + } + + return (false); + } + + #endregion + + #region UpdateDateSelection + + /// + /// Updates each monthWeeks DayRects to reflect + /// the date selection start and end values + /// + protected override void UpdateDateSelection() + { + if (IsViewSelected == true) + { + // Loop through each month, setting + // the selection status according to the date + // selection range + + for (int i = 0; i < _NumberOfMonths; i++) + _YearMonths[i].UpdateDateSelection(); + } + } + + #endregion + + #region RecalcSize routines + + /// + /// Performs NeedRecalcSize requests + /// + public override void RecalcSize() + { + if (_RecalcInProgress == false) + { + try + { + _RecalcInProgress = true; + + RecalcDisplaySize(); + } + finally + { + _RecalcInProgress = false; + } + } + } + + #region RecalcDisplaySize + + /// + /// Performs all necessary recalc operations + /// + private void RecalcDisplaySize() + { + base.RecalcSize(); + + if (IsViewSelected == true) + { + // Normalize our start and end dates + + DateTime startDate; + DateTime endDate; + + NormalizeDates(out startDate, out endDate); + + // Calculate each months display info and then + // initiate a YearMonth layout + + CalcYearMonths(startDate, endDate); + LayoutYearMonths(startDate); + + // Update our Model connection and views + + UpdateView(); + UpdateDateSelection(); + + NeedRecalcLayout = false; + } + } + + #endregion + + #region NormalizeDates + + /// + /// Normalizes the user specified start and end dates + /// + /// [out] Normalized start date + /// [out] Normalized end date + private void NormalizeDates(out DateTime startDate, out DateTime endDate) + { + startDate = this.StartDate.Date; + endDate = this.EndDate.Date; + + // If both values are unset, then set them to + // today's date / + 12 months + + if (startDate == DateTime.MinValue && endDate == DateTime.MinValue) + { + startDate = DateTime.Today.AddDays(-(DateTime.Today.Day - 1)); + endDate = startDate.AddMonths(12).AddDays(-1); + } + + if (DaysOfTheWeek == null) + DaysOfTheWeek = new DaysOfTheWeek(); + } + + #endregion + + #region Update View + + /// + /// Updates our connection model view + /// + private void UpdateView() + { + // If we have had a date range change, just + // reset our entire view + + if (DateRangeChanged == true) + ResetView(); + + // If we have no Model connection, attempt + // to reconnect if this view is selected + + if (Connector == null) + { + if (CalendarModel != null) + { + Connector = new ModelYearViewConnector(CalendarModel, this); + + CalendarView.DoViewLoadComplete(this); + } + } + } + + #endregion + + #region ResetView + + /// + /// Disconnects and resets the Model connection + /// + internal override void ResetView() + { + base.ResetView(); + + ModelYearViewConnector.ResetModelData(); + } + + #endregion + + #region CalcYearMonths + + /// + /// Calculates display info for the YearMonth data + /// + /// Start date + /// End date + private void CalcYearMonths(DateTime startDate, DateTime endDate) + { + // Get the number of months for the date range + + _NumberOfMonths = (endDate.Year * 12 + endDate.Month) - + (startDate.Year * 12 + startDate.Month) + 1; + + _NumberOfMonths = Math.Max(1, _NumberOfMonths); + _NumberOfMonths = Math.Min(_NumberOfMonths, MaxNumberOfMonths); + + // Allocate our MonthWeeks array to + // hold our weeks info + + if (_YearMonths == null || _YearMonths.Length != _NumberOfMonths) + _YearMonths = new YearMonth[_NumberOfMonths]; + } + + #endregion + + #region LayoutYearMonths + + /// + /// Performs size and positioning layout for the control + /// + /// + private void LayoutYearMonths(DateTime startDate) + { + Size size = GetPreferredSize(startDate); + + if (size.Width > 0 && size.Height > 0) + { + int maxCols = Math.Max(1, (ClientRect.Width - 1) / size.Width); + int maxRows = Math.Max(1, (ClientRect.Height - 1) / size.Height); + + int targetCols = (int)Math.Ceiling(Math.Sqrt(_NumberOfMonths)); + + if (targetCols >= maxCols) + { + targetCols = maxCols; + } + else + { + while (targetCols < maxCols) + { + int targetRows = + Math.Max(1, (_NumberOfMonths + targetCols - 1) / targetCols); + + if (targetRows <= maxRows) + break; + + targetCols++; + } + } + + _NumberOfRows = Math.Max(1, (_NumberOfMonths + targetCols - 1) / targetCols); + _NumberOfCols = (_NumberOfMonths + _NumberOfRows - 1) / _NumberOfRows; + + int monthHeight = (ClientRect.Height - 1) / _NumberOfRows; + int monthWidth = (ClientRect.Width - 1) / _NumberOfCols; + + int rowSpread = 0; + + if (monthHeight < size.Height) + monthHeight = size.Height; + else + rowSpread = ClientRect.Height - (_NumberOfRows * monthHeight) - 1; + + int colSpread = 0; + + if (monthWidth < size.Width) + monthWidth = size.Width; + else + colSpread = ClientRect.Width - (_NumberOfCols * monthWidth) - 1; + + // Loop through each week + + int n = 0; + DateTime date = startDate; + + Rectangle r = new Rectangle(ClientRect.X, ClientRect.Y, monthWidth, monthHeight); + r.Y += _VScrollPos; + + for (int i = 0; i < _NumberOfRows; i++) + { + if (i < rowSpread) + r.Height++; + + for (int j = 0; j < _NumberOfCols; j++) + { + if (n >= _NumberOfMonths) + break; + + if (_YearMonths[n] == null) + _YearMonths[n] = new YearMonth(this, date); + else + _YearMonths[n].StartDate = date; + + // Calculate the bounding rect limits + + r.Width = monthWidth; + + if (j < colSpread) + r.Width++; + + // Set the bounding rect + + _YearMonths[n].Bounds = r; + + r.X += r.Width; + n++; + + date = date.AddMonths(1); + } + + r.X = ClientRect.X; + r.Y += r.Height; + r.Height = monthHeight; + } + + CalendarView.YearViewMax = (r.Y - (ClientRect.Y + _VScrollPos)); + } + } + + #endregion + + #region GetPreferredSize + + /// + /// Gets the preferred size of the control + /// + /// + /// + private Size GetPreferredSize(DateTime startDate) + { + if (_PreferredSize.IsEmpty) + { + if (_YearMonths[0] == null) + _YearMonths[0] = new YearMonth(this, startDate); + + _PreferredSize = _YearMonths[0].GetPreferredSize(); + } + + return (_PreferredSize); + } + + #endregion + + #endregion + + #region Paint processing + + #region Root paint code + + /// + /// Paint processing + /// + /// ItemPaintArgs + public override void Paint(ItemPaintArgs e) + { + // Set our current color table + + _ViewColor.SetColorTable(); + + // Only draw something if we have something to draw + + if (_NumberOfMonths > 0) + { + // Calculate our drawing ranges + + int colStart, colEnd; + int rowStart, rowEnd; + + int colCount = GetColRange(e, out colStart, out colEnd); + int rowCount = GetRowRange(e, out rowStart, out rowEnd); + + // Draw our calendar parts + + if (colCount > 0 && rowCount > 0) + DrawContent(e, rowStart, rowEnd, colStart, colEnd); + } + + // Let the base painting take place + + base.Paint(e); + } + + #endregion + + #region DrawContent + + /// + /// Draws YearMonth header and content + /// + /// ItemPaintArgs + /// Row start index + /// Row end index + /// Col start index + /// Col end index + private void DrawContent(ItemPaintArgs e, + int rowStart, int rowEnd, int colStart, int colEnd) + { + Graphics g = e.Graphics; + + // Set our clipping region + + Rectangle r = ClientRect; + + r.X = ClientRect.X; + r.Width = ClientRect.Width; + + Region regSave = g.Clip; + g.SetClip(r, CombineMode.Intersect); + + // Loop through each day in each week, displaying + // the associated day content and header + + DateTime date = DateTime.Now; + + int nowMonth = -1; + + for (int i = rowStart; i <= rowEnd; i++) + { + for (int j = colStart; j <= colEnd; j++) + { + int n = (i * _NumberOfCols) + j; + + if (n < _NumberOfMonths) + { + YearMonth ym = _YearMonths[n]; + + bool now = CalendarView.HighlightCurrentDay == true && + ym.StartDate.Month == date.Month && ym.StartDate.Year == date.Year; + + if (now == true) + nowMonth = n; + else + ym.Paint(e, false); + } + } + } + + if (nowMonth >= 0) + _YearMonths[nowMonth].Paint(e, true); + + // Restore our original clip region + + g.Clip = regSave; + } + + #endregion + + #region GetRange + + #region GetColRange + + /// + /// Calculates the range of columns needed to be drawn + /// to satisfy the specified paint request + /// + /// ItemPaintArgs + /// [out] Col start index + /// [out] COl end index + /// Col range count (end - start) + private int GetColRange(ItemPaintArgs e, out int colStart, out int colEnd) + { + // Calc our starting index + + int nCols = Math.Min(_NumberOfMonths, _NumberOfCols); + int start = 0; + + while (start < nCols) + { + Rectangle dr1 = _YearMonths[start].Bounds; + + if (dr1.Right > e.ClipRectangle.X) + break; + + start++; + } + + // Calc our ending index + + int end = start; + + while (end < nCols) + { + Rectangle dr2 = _YearMonths[end].Bounds; + + if (dr2.X >= e.ClipRectangle.Right) + break; + + end++; + } + + // Set the user supplied 'out' values, and + // return the range count to the caller + + if (end - start == 0) + { + colStart = 0; + colEnd = 0; + + return (0); + } + + colStart = start; + colEnd = end - 1; + + return (end - start); + } + + #endregion + + #region GetRowRange + + /// + /// Calculates the range of rows needed to be drawn + /// to satisfy the specified paint request + /// + /// ItemPaintArgs + /// [out] Row start index + /// [out] Row end index + /// Row range count (end - start) + private int GetRowRange(ItemPaintArgs e, out int rowStart, out int rowEnd) + { + // Calc our starting index + + int start = 0; + + while (start < _NumberOfRows) + { + if (_YearMonths[start * _NumberOfCols].Bounds.Bottom > e.ClipRectangle.Y) + break; + + start++; + } + + // Calc our ending index + + int end = start; + + while (end < _NumberOfRows) + { + if (_YearMonths[end * _NumberOfCols].Bounds.Y >= e.ClipRectangle.Bottom) + break; + + end++; + } + + // Set the user supplied 'out' values, and + // return the range count to the caller + + if (end - start == 0) + { + rowStart = 0; + rowEnd = 0; + + return (0); + } + + rowStart = start; + rowEnd = end - 1; + + return (end - start); + } + + #endregion + + #endregion + + #endregion + + #region MouseMove processing + + /// + /// MouseMove event processing + /// + /// MouseEventArgs + public override void InternalMouseMove(MouseEventArgs objArg) + { + // Forward on the event, but only if we are not in + // the middle of moving or resizing a CalendarItem + + if (Control.MouseButtons == MouseButtons.None) + ClearMouseStates(); + + base.InternalMouseMove(objArg); + + if (IsTabMoving == false) + { + // Locate where the event took place + // and process it accordingly + + int monthIndex, dayIndex, ndayIndex; + + if (GetPointItem(objArg.Location, out monthIndex, out dayIndex, out ndayIndex)) + { + if (objArg.Button == MouseButtons.Left) + ProcessMouseMove(monthIndex, ndayIndex); + } + + // Set the cursor + + MyCursor = GetCursor(monthIndex, dayIndex, ndayIndex); + } + } + + #region ProcessMouseMove + + /// + /// Processes view mouseMove events + /// + /// + /// + private void ProcessMouseMove(int monthIndex, int dayIndex) + { + if (AllowDateSelection == true) + { + if (DateSelectionAnchor != null) + { + DateTime date = _YearMonths[monthIndex].GetDateFromIndex(dayIndex); + + // Let the user select forwards or backwards + + if (date >= DateSelectionAnchor) + { + CalendarView.DateSelectionStart = DateSelectionAnchor.Value; + CalendarView.DateSelectionEnd = date.AddDays(1); + } + else + { + CalendarView.DateSelectionStart = date; + CalendarView.DateSelectionEnd = DateSelectionAnchor.Value.AddDays(1); + } + } + } + } + + #endregion + + #endregion + + #region MouseDown processing + + #region InternalMouseDown + + /// + /// MouseDown event processing + /// + /// + public override void InternalMouseDown(MouseEventArgs objArg) + { + // Forward on the event + + base.InternalMouseDown(objArg); + + if (objArg.Button == MouseButtons.Left) + { + if (IsTabMoving == false) + { + // Locate where the event took place + + int monthIndex, dayIndex, ndayIndex; + + if (GetPointItem(objArg.Location, out monthIndex, out dayIndex, out ndayIndex)) + { + if (dayIndex == ndayIndex || + (Control.ModifierKeys & Keys.Shift) == Keys.Shift) + { + ProcessMouseDown(monthIndex, ndayIndex); + } + else + { + CalendarView.DateSelectionStart = null; + CalendarView.DateSelectionEnd = null; + DateSelectionAnchor = null; + } + } + + MyCursor = GetCursor(monthIndex, dayIndex, ndayIndex); + } + } + } + + #endregion + + #region ProcessMouseDown + + /// + /// Handles MonthView left MouseDown events + /// + /// Month index + /// Day index + private void ProcessMouseDown(int monthIndex, int dayIndex) + { + if (AllowDateSelection == true) + { + DateTime startDate = _YearMonths[monthIndex].GetDateFromIndex(dayIndex); + DateTime endDate = startDate.AddDays(1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + } + + _MouseDownMonthIndex = monthIndex; + _MouseDownDayIndex = dayIndex; + } + + #endregion + + #endregion + + #region MouseUp processing + + #region InternalMouseUp + + /// + /// Handles InternalMouseUp events + /// + /// + public override void InternalMouseUp(MouseEventArgs objArg) + { + // Forward on the event + + base.InternalMouseUp(objArg); + + ClearMouseStates(); + + if (objArg.Button == MouseButtons.Left) + { + if (IsTabMoving == false) + { + // Locate where the event took place + + int monthIndex, dayIndex, ndayIndex; + + if (GetPointItem(objArg.Location, out monthIndex, out dayIndex, out ndayIndex)) + ProcessMouseUp(monthIndex, ndayIndex); + + MyCursor = GetCursor(monthIndex, dayIndex, ndayIndex); + } + } + } + + #endregion + + #region ProcessMouseUp + + /// + /// Process mouse up events + /// + /// + /// + private void ProcessMouseUp(int monthIndex, int dayIndex) + { + // If the user is mousing-up on the same day that he + // moused-down on, then check to see if we need to navigate + // to a linked Calendar view + + if (_MouseDownMonthIndex == monthIndex && _MouseDownDayIndex == dayIndex) + { + YearMonth ym = _YearMonths[monthIndex]; + DateTime date = ym.GetDateFromIndex(dayIndex); + + eYearViewDayLink dl = (ym.DayIndexHasAppointments(dayIndex) == true) + ? YearViewAppointmentLink : YearViewNonAppointmentLink; + + if (((dl & eYearViewDayLink.DoubleClick) != eYearViewDayLink.DoubleClick) || _LastMouseDownDayIndex != dayIndex || + _LastMouseUpTime == DateTime.MinValue || + DateTime.Now.Subtract(_LastMouseUpTime).TotalMilliseconds > SystemInformation.DoubleClickTime) + { + _LastMouseUpTime = DateTime.Now; + + if ((dl & eYearViewDayLink.Click) == eYearViewDayLink.Click) + { + if ((Control.ModifierKeys & Keys.Control) != Keys.Control) + PerformLinkSelect(date); + } + else if ((dl & eYearViewDayLink.CtrlClick) == eYearViewDayLink.CtrlClick) + { + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + PerformLinkSelect(date); + } + } + else + { + _LastMouseUpTime = DateTime.MinValue; + + PerformLinkSelect(date); + } + } + + _LastMouseDownDayIndex = _MouseDownDayIndex; + + _MouseDownMonthIndex = -1; + _MouseDownDayIndex = -1; + } + + #endregion + + #region PerformLinkSelect + + /// + /// Performs a day link selection + /// + /// + private void PerformLinkSelect(DateTime date) + { + DateTime startDate = date; + + if (CalendarView.YearViewLinkAction == eYearViewLinkAction.GoToFirstCalendarItem) + { + if (Connector != null) + { + Appointment app = ((ModelYearViewConnector) Connector).GetFirstAppointment(date); + + if (app != null) + startDate = date.Date.AddHours(app.StartTime.Hour).AddMinutes(app.StartTime.Minute); + + CustomCalendarItem cci = ((ModelYearViewConnector) Connector).GetFirstCustomItem(date); + + if (cci != null) + { + if (app == null || cci.StartTime < startDate) + startDate = date.Date.AddHours(cci.StartTime.Hour).AddMinutes(cci.StartTime.Minute); + } + } + } + + DateTime endDate = startDate; + eCalendarView calendarView = CalendarView.YearViewLinkView; + + if (CalendarView.DoYearViewLinkSelected(ref startDate, ref endDate, ref calendarView) == false) + { + if (CalendarView.YearViewLinkView != eCalendarView.None && + CalendarView.YearViewLinkView != eCalendarView.Year) + { + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + CalendarView.SelectedView = calendarView; + CalendarView.EnsureVisible(startDate, endDate); + } + } + } + + #endregion + + #endregion + + #region InternalKeyDown + + #region InternalKeyDown + + /// + /// Processes KeyDown events + /// + /// + public override void InternalKeyDown(KeyEventArgs objArg) + { + switch (objArg.KeyData) + { + case Keys.Up: + case Keys.Up | Keys.Shift: + case Keys.Up | Keys.Control: + case Keys.Up | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, -7); + break; + + case Keys.Down: + case Keys.Down | Keys.Shift: + case Keys.Down | Keys.Control: + case Keys.Down | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, 7); + break; + + case Keys.Left: + case Keys.Left | Keys.Shift: + case Keys.Left | Keys.Control: + case Keys.Left | Keys.Control | Keys.Shift: + ProcessLeftRightKey(objArg, -1); + break; + + case Keys.Right: + case Keys.Right | Keys.Shift: + case Keys.Right | Keys.Control: + case Keys.Right | Keys.Control | Keys.Shift: + ProcessLeftRightKey(objArg, 1); + break; + + case Keys.Home: + case Keys.Home | Keys.Shift: + case Keys.Home | Keys.Control: + case Keys.Home | Keys.Control | Keys.Shift: + ProcessHomeKey(objArg); + break; + + case Keys.End: + case Keys.End | Keys.Shift: + case Keys.End | Keys.Control: + case Keys.End | Keys.Control | Keys.Shift: + ProcessEndKey(objArg); + break; + + case Keys.LButton | Keys.ShiftKey | Keys.Control: + ProcessControlKey(); + break; + + case Keys.Enter: + case Keys.Space: + ProcessEnterKey(); + break; + + case Keys.PageUp: + case Keys.PageUp | Keys.Shift: + case Keys.PageUp | Keys.Control: + case Keys.PageUp | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, -7); + break; + + case Keys.PageDown: + case Keys.PageDown | Keys.Shift: + case Keys.PageDown | Keys.Control: + case Keys.PageDown | Keys.Control | Keys.Shift: + ProcessUpDownKey(objArg, 7); + break; + } + } + + #endregion + + #region ProcessUpDownKey + + /// + /// Processes Up and Down Key events + /// + /// + /// + protected virtual void ProcessUpDownKey(KeyEventArgs objArg, int dy) + { + if (ValidDateSelection()) + { + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + if (DateSelectionAnchor != null) + { + if (startDate.Equals(DateSelectionAnchor.Value) == true) + startDate = endDate.AddDays(-1); + } + + startDate = startDate.AddDays(dy); + endDate = startDate.AddDays(1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessLeftRightKey + + /// + /// Processes Left and Right key events + /// + /// + /// + protected virtual void ProcessLeftRightKey(KeyEventArgs objArg, int dx) + { + if (ValidDateSelection()) + { + DateTime startDate = CalendarView.DateSelectionStart.Value; + DateTime endDate = CalendarView.DateSelectionEnd.Value; + + if (DateSelectionAnchor != null) + { + if (startDate.Equals(DateSelectionAnchor.Value) == true) + startDate = endDate.AddDays(-1); + } + + startDate = startDate.AddDays(dx); + endDate = startDate.AddDays(1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessHomeKey + + /// + /// Processes Hoe key events + /// + /// + protected virtual void ProcessHomeKey(KeyEventArgs objArg) + { + int monthIndex = ((objArg.Modifiers & Keys.Control) != Keys.Control) + ? GetHomeEndMonth() + : 0; + + if (monthIndex >= 0) + { + DateTime startDate = _YearMonths[monthIndex].StartDate; + DateTime endDate = startDate.AddDays(1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + SelectedItem = null; + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessEndKey + + /// + /// Processes End key events + /// + /// + protected virtual void ProcessEndKey(KeyEventArgs objArg) + { + int monthIndex = ((objArg.Modifiers & Keys.Control) != Keys.Control) + ? GetHomeEndMonth() + : _NumberOfMonths - 1; + + if (monthIndex >= 0) + { + DateTime startDate = _YearMonths[monthIndex].EndDate; + DateTime endDate = startDate.AddDays(1); + + ExtendSelection(ref startDate, ref endDate); + + CalendarView.DateSelectionStart = startDate; + CalendarView.DateSelectionEnd = endDate; + + SelectedItem = null; + } + + objArg.Handled = true; + } + + #endregion + + #region ProcessControlKey + + private void ProcessControlKey() + { + Point pt = Control.MousePosition; + + Control container = GetContainerControl(true) as Control; + + if (container != null) + { + pt = container.PointToClient(pt); + + CalendarView.CalendarPanel.InternalMouseMove(new + MouseEventArgs(MouseButtons.None, 0, pt.X, pt.Y, 0)); + } + } + + #endregion + + #region ProcessEnterKey + + private void ProcessEnterKey() + { + if (ValidDateSelection()) + { + TimeSpan ts = CalendarView.DateSelectionEnd.Value - + CalendarView.DateSelectionStart.Value; + + if (ts.Days == 1) + PerformLinkSelect(CalendarView.DateSelectionStart.Value); + } + } + + #endregion + + #region GetMonthFromDate + + /// + /// Gets the month containing the given date + /// + /// + /// MonthIndex or -1 + private int GetMonthFromDate(DateTime date) + { + for (int i = 0; i < _NumberOfMonths; i++) + { + YearMonth ym = _YearMonths[i]; + + if (ym.ContainsDate(date)) + return (i); + } + + return (-1); + } + + #endregion + + #region GetHomeEndMonth + + /// + /// Gets the Home and End month from the + /// current selection range + /// + /// + private int GetHomeEndMonth() + { + if (ValidDateSelection() == true) + { + if (CalendarView.DateSelectionStart.Equals(DateSelectionAnchor.Value) == true) + return (GetMonthFromDate(DateSelectionEnd.Value.AddDays(-1))); + + return (GetMonthFromDate(DateSelectionStart.Value)); + } + + return (-1); + } + + #endregion + + #endregion + + #region InternalKeyUp + + /// + /// InternalKeyUp + /// + /// + internal override void InternalKeyUp(KeyEventArgs e) + { + base.InternalKeyUp(e); + + switch (e.KeyData) + { + case Keys.LButton | Keys.ShiftKey: + ProcessControlKey(); + break; + } + } + + #endregion + + #region GetCursor + + /// + /// Gets the cursor + /// + /// Cursor + private Cursor GetCursor(int monthIndex, int dayIndex, int ndayIndex) + { + if (monthIndex >= 0 && dayIndex >= 0 && dayIndex == ndayIndex) + { + if (_MouseDownMonthIndex < 0 || + (_MouseDownMonthIndex == monthIndex && _MouseDownDayIndex == dayIndex)) + { + YearMonth ym = _YearMonths[monthIndex]; + + eYearViewDayLink dl = (ym.DayIndexHasAppointments(dayIndex) == true) + ? YearViewAppointmentLink + : YearViewNonAppointmentLink; + + if ((dl & eYearViewDayLink.Click) == eYearViewDayLink.Click) + { + if ((Control.ModifierKeys & Keys.Control) != Keys.Control) + return (Cursors.Hand); + } + else if ((dl & eYearViewDayLink.CtrlClick) == eYearViewDayLink.CtrlClick) + { + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + return (Cursors.Hand); + } + } + } + + return (DefaultCursor); + } + + #endregion + + #region GetPointItem + + /// + /// Gets the month and dey index for the given Point + /// + /// + /// Month index + /// Day index + /// Normalized day index + /// + private bool GetPointItem(Point pt, + out int monthIndex, out int dayIndex, out int ndayIndex) + { + monthIndex = GetMonthIndexFromPoint(pt); + + if (monthIndex >= 0) + { + YearMonth ym = _YearMonths[monthIndex]; + + dayIndex = ym.GetDayIndexFromPoint(pt); + ndayIndex = ym.GetNormalizedDayIndex(dayIndex); + } + else + { + dayIndex = -1; + ndayIndex = -1; + } + + return (dayIndex >= 0); + } + + #endregion + + #region GetMonthIndexFromPoint + + /// + /// Gets the month index from the given point + /// + /// Point + /// month index or -1 + private int GetMonthIndexFromPoint(Point pt) + { + for (int i = 0; i < _NumberOfMonths; i++) + { + if (_YearMonths[i].Bounds.Contains(pt)) + return (i); + } + + return (-1); + } + + #endregion + + #region IDisposable Members + + protected override void Dispose(bool disposing) + { + if (disposing == true && IsDisposed == false) + { + ResetView(); + HookEvents(false); + } + + base.Dispose(disposing); + } + + #endregion + + #region Copy object + + /// + /// Returns copy of the item. + /// + public override BaseItem Copy() + { + YearView objCopy = new YearView(this.CalendarView); + CopyToItem(objCopy); + + return (objCopy); + } + + /// + /// Copies the YearView specific properties to new instance of the item. + /// + /// New YearView instance + protected override void CopyToItem(BaseItem copy) + { + YearView objCopy = copy as YearView; + + if (objCopy != null) + base.CopyToItem(objCopy); + } + + #endregion + } +} +#endif + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/YearViewVScrollPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/YearViewVScrollPanel.cs new file mode 100644 index 00000000..8a1ad579 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.Schedule/YearView/YearViewVScrollPanel.cs @@ -0,0 +1,27 @@ +#if FRAMEWORK20 +namespace DevComponents.DotNetBar.Schedule +{ + public class YearVScrollPanel : VScrollPanel + { + public YearVScrollPanel(CalendarView calendarView) + : base(calendarView) + { + } + + #region Private properties + + protected override int ScrollPanelSmallChange + { + get { return (10); } + } + + protected override int ScrollPanelMaximum + { + get { return (CalendarView.YearViewMax); } + } + + #endregion + + } +} +#endif \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/BlockLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/BlockLayoutManager.cs new file mode 100644 index 00000000..c92a50b3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/BlockLayoutManager.cs @@ -0,0 +1,38 @@ +using System.Collections; +using System.Drawing; + +namespace DevComponents.SuperGrid.TextMarkup +{ + /// + /// Represents block layout manager responsible for sizing the content blocks. + /// + public abstract class BlockLayoutManager + { + private Graphics _Graphics; + + /// + /// Resizes the content block and sets it's Bounds property to reflect new size. + /// + /// Content block to resize. + /// Content size available for the block in the given line. + public abstract void Layout(IBlock block, Size availableSize); + + /// + /// Performs layout finalization + /// + /// + /// + /// + /// + public abstract Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines); + + /// + /// Gets or sets the graphics object used by layout manager. + /// + public Graphics Graphics + { + get {return _Graphics;} + set {_Graphics = value;} + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/Enums.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/Enums.cs new file mode 100644 index 00000000..b00b2a45 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/Enums.cs @@ -0,0 +1,55 @@ +namespace DevComponents.SuperGrid.TextMarkup +{ + /// + /// Specifies orientation of content. + /// + public enum eContentOrientation + { + /// + /// Indicates Horizontal orientation of the content. + /// + Horizontal, + /// + /// Indicates Vertical orientation of the content. + /// + Vertical + } + + /// + /// Specifies content horizontal alignment. + /// + public enum eContentAlignment + { + /// + /// Content is left aligned.UI + /// + Left, + /// + /// Content is right aligned. + /// + Right, + /// + /// Content is centered. + /// + Center + } + + /// + /// Specifies content vertical alignment. + /// + public enum eContentVerticalAlignment + { + /// + /// Content is top aligned. + /// + Top, + /// + /// Content is bottom aligned. + /// + Bottom, + /// + /// Content is in the middle. + /// + Middle + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/IBlock.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/IBlock.cs new file mode 100644 index 00000000..535eb54e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/IBlock.cs @@ -0,0 +1,20 @@ +using System.Drawing; + +namespace DevComponents.SuperGrid.TextMarkup +{ + /// + /// Represents a content block interface. + /// + public interface IBlock + { + /// + /// Gets or sets the bounds of the content block. + /// + Rectangle Bounds {get;set;} + + /// + /// Gets or sets whether content block is visible. + /// + bool Visible {get;set;} + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/IBlockExtended.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/IBlockExtended.cs new file mode 100644 index 00000000..9a8cfaad --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/IBlockExtended.cs @@ -0,0 +1,23 @@ +namespace DevComponents.SuperGrid.TextMarkup +{ + /// + /// Represents a extended content block interface for advanced layout information. + /// + public interface IBlockExtended : IBlock + { + /// + /// Gets whether element is block level element. + /// + bool IsBlockElement { get;} + + /// + /// Gets whether new line is required after the element. + /// + bool IsNewLineAfterElement { get;} + + /// + /// Gets whether element can be on new line. + /// + bool CanStartNewLine { get; } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/IContentLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/IContentLayoutManager.cs new file mode 100644 index 00000000..d6dbb317 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/IContentLayoutManager.cs @@ -0,0 +1,19 @@ +using System.Drawing; + +namespace DevComponents.SuperGrid.TextMarkup +{ + /// + /// Represents interface for block layout. + /// + public interface IContentLayout + { + /// + /// Performs layout of the content block. + /// + /// Container bounds to layout content blocks in. + /// Content blocks to layout. + /// Block layout manager that resizes the content blocks. + /// The bounds of the content blocks within the container bounds. + Rectangle Layout(Rectangle containerBounds, IBlock[] contentBlocks, BlockLayoutManager blockLayout); + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/SerialContentLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/SerialContentLayoutManager.cs new file mode 100644 index 00000000..9acf97ba --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/ContentManager/SerialContentLayoutManager.cs @@ -0,0 +1,709 @@ +using System; +using System.Collections; +using System.Drawing; + +namespace DevComponents.SuperGrid.TextMarkup +{ + /// + /// Represents the serial content layout manager that arranges content blocks in series next to each other. + /// + public class SerialContentLayoutManager:IContentLayout + { + #region Events + + /// + /// Occurs when X, Y position of next block is calcualted. + /// + public event LayoutManagerPositionEventHandler NextPosition; + + /// + /// Occurs before new block is layed out. + /// + public event LayoutManagerLayoutEventHandler BeforeNewBlockLayout; + + #endregion + + #region Private Variables + + private int _BlockSpacing; + private bool _FitContainerOversize; + private bool _FitContainer; + private bool _VerticalFitContainerWidth; + private bool _HorizontalFitContainerHeight; + private bool _EvenHeight; + private bool _MultiLine; + private bool _RightToLeft; + private bool _OversizeDistribute; + + private eContentAlignment _ContentAlignment = eContentAlignment.Left; + private eContentOrientation _ContentOrientation = eContentOrientation.Horizontal; + private eContentVerticalAlignment _ContentVerticalAlignment = eContentVerticalAlignment.Middle; + private eContentVerticalAlignment _BlockLineAlignment = eContentVerticalAlignment.Middle; + + #endregion + + #region IContentLayout Members + + /// + /// Performs layout of the content block. + /// + /// Container bounds to layout content blocks in. + /// Content blocks to layout. + /// Block layout manager that resizes the content blocks. + /// The bounds of the content blocks within the container bounds. + 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; + bool canStartOnNewLine; + + if (block is IBlockExtended) + { + IBlockExtended ex = block as IBlockExtended; + + isBlockElement = ex.IsBlockElement; + isNewLineTriggger = ex.IsNewLineAfterElement; + canStartOnNewLine = ex.CanStartNewLine; + } + else + canStartOnNewLine = true; + + if (!isBlockElement) + { + if (_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 (_MultiLine && currentLine.Blocks.Count > 0) + { + if (_ContentOrientation == eContentOrientation.Horizontal && + position.X + block.Bounds.Width > containerBounds.Right && canStartOnNewLine || isBlockElement || + switchToNewLine) + { + position.X = containerBounds.X; + position.Y += (currentLine.LineSize.Height + _BlockSpacing); + + currentLine = new BlockLineInfo(); + + currentLine.Line = lines.Count; + + lines.Add(currentLine); + } + else if (_ContentOrientation == eContentOrientation.Vertical && + position.Y + block.Bounds.Height > containerBounds.Bottom && canStartOnNewLine || isBlockElement || + switchToNewLine) + { + position.Y = containerBounds.Y; + position.X += (currentLine.LineSize.Width + _BlockSpacing); + + currentLine = new BlockLineInfo(); + + currentLine.Line = lines.Count; + + lines.Add(currentLine); + } + } + + if (_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 (_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); + + if (block.Visible) + currentLine.VisibleItemsCount++; + + 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 (_RightToLeft) + blocksBounds = MirrorContent(containerBounds, blocksBounds, contentBlocks); + + blocksBounds = blockLayout.FinalizeLayout(containerBounds, blocksBounds, lines); + + return blocksBounds; + } + + #endregion + + #region Internals + + private struct SizeExtended + { + public int Width; + public int Height; + public float WidthReduction; + public float HeightReduction; + public bool UseAbsoluteWidth; + } + + 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 (_ContentAlignment == eContentAlignment.Left && _ContentVerticalAlignment == eContentVerticalAlignment.Top && + !_FitContainer && !_FitContainerOversize && !_EvenHeight && _BlockLineAlignment == eContentVerticalAlignment.Top) + return blocksBounds; + + Point[] offset=new Point[lines.Count]; + SizeExtended[] sizeOffset = new SizeExtended[lines.Count]; + foreach(BlockLineInfo lineInfo in lines) + { + if (_ContentOrientation == eContentOrientation.Horizontal) + { + if (_FitContainer && containerBounds.Width > lineInfo.LineSize.Width || + _FitContainerOversize && lineInfo.LineSize.Width > containerBounds.Width) + { + if (_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width * .75) + { + sizeOffset[lineInfo.Line].Width = (int)Math.Floor((float)(containerBounds.Width - lineInfo.VisibleItemsCount * _BlockSpacing) / (float)lineInfo.VisibleItemsCount); + sizeOffset[lineInfo.Line].UseAbsoluteWidth = true; + } + else + sizeOffset[lineInfo.Line].Width = ((containerBounds.Width - lineInfo.VisibleItemsCount * _BlockSpacing) - lineInfo.LineSize.Width) / lineInfo.VisibleItemsCount; + sizeOffset[lineInfo.Line].WidthReduction = (float)(containerBounds.Width - lineInfo.VisibleItemsCount * _BlockSpacing) / (float)lineInfo.LineSize.Width; + blocksBounds.Width = containerBounds.Width; + } + + if (_HorizontalFitContainerHeight && containerBounds.Height > blocksBounds.Height) + sizeOffset[lineInfo.Line].Height = (containerBounds.Height - lineInfo.LineSize.Height) / lines.Count; + } + else + { + if (_FitContainer && containerBounds.Height > lineInfo.LineSize.Height || + _FitContainerOversize && lineInfo.LineSize.Height > containerBounds.Height) + { + if (_OversizeDistribute && containerBounds.Width < lineInfo.LineSize.Width*.75) + { + sizeOffset[lineInfo.Line].Height = (int) + Math.Floor((float) (containerBounds.Height - lineInfo.VisibleItemsCount*_BlockSpacing)/ + (float) lineInfo.VisibleItemsCount); + + sizeOffset[lineInfo.Line].UseAbsoluteWidth = true; + } + else + sizeOffset[lineInfo.Line].Height = ((containerBounds.Height - + lineInfo.VisibleItemsCount*_BlockSpacing) - + lineInfo.LineSize.Height)/lineInfo.VisibleItemsCount; + sizeOffset[lineInfo.Line].HeightReduction = + (float) (containerBounds.Height - lineInfo.VisibleItemsCount*_BlockSpacing)/ + (float) lineInfo.LineSize.Height; + blocksBounds.Height = containerBounds.Height; + } + + if (_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width) + sizeOffset[lineInfo.Line].Width = (containerBounds.Width - lineInfo.LineSize.Width)/lines.Count; + } + + + if (_ContentOrientation == eContentOrientation.Horizontal && !_FitContainer) + { + if (containerBounds.Width > blocksBounds.Width && _FitContainerOversize || !_FitContainerOversize) + { + switch (_ContentAlignment) + { + case eContentAlignment.Right: + if (containerBounds.Width > lineInfo.LineSize.Width) + offset[lineInfo.Line].X = containerBounds.Width - lineInfo.LineSize.Width; + break; + + case eContentAlignment.Center: + if (containerBounds.Width > lineInfo.LineSize.Width) + offset[lineInfo.Line].X = (containerBounds.Width - lineInfo.LineSize.Width)/2; + break; + } + } + } + + if (_ContentOrientation == eContentOrientation.Vertical && !_FitContainer) + { + if (containerBounds.Height > blocksBounds.Height && _FitContainerOversize || !_FitContainerOversize) + { + switch (_ContentVerticalAlignment) + { + case eContentVerticalAlignment.Bottom: + if (containerBounds.Height > lineInfo.LineSize.Height) + offset[lineInfo.Line].Y = containerBounds.Height - lineInfo.LineSize.Height; + break; + + case eContentVerticalAlignment.Middle: + if (containerBounds.Height > lineInfo.LineSize.Height) + offset[lineInfo.Line].Y = (containerBounds.Height - lineInfo.LineSize.Height)/2; + break; + } + } + } + } + + if (_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width && _ContentOrientation==eContentOrientation.Vertical) + blocksBounds.Width = containerBounds.Width; + + else if(_HorizontalFitContainerHeight && containerBounds.Height>blocksBounds.Height && _ContentOrientation==eContentOrientation.Horizontal) + blocksBounds.Height = containerBounds.Height; + + if(_ContentOrientation==eContentOrientation.Horizontal) + { + foreach(BlockLineInfo lineInfo in lines) + { + foreach (IBlock block in lineInfo.Blocks) + { + if (!block.Visible) + continue; + + Rectangle r = block.Bounds; + + if (_EvenHeight && lineInfo.LineSize.Height > 0) + r.Height = lineInfo.LineSize.Height; + + r.Offset(offset[lineInfo.Line]); + + if (_ContentVerticalAlignment == eContentVerticalAlignment.Middle) + { + // Takes care of offset rounding error when both content is vertically centered and blocks in line are centered + + if (_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 (_BlockLineAlignment == eContentVerticalAlignment.Bottom) + r.Offset(0, lineInfo.LineSize.Height - r.Height); + } + else if (_ContentVerticalAlignment == eContentVerticalAlignment.Bottom) + r.Offset(0, containerBounds.Height - blocksBounds.Height); + + // To avoid rounding offset errors when dividing this is split see upper part + + if (_ContentVerticalAlignment != eContentVerticalAlignment.Middle) + { + // Line alignment of the block + + if (_BlockLineAlignment == eContentVerticalAlignment.Middle) + r.Offset(0, (lineInfo.LineSize.Height - r.Height)/2); + + else if (_BlockLineAlignment == eContentVerticalAlignment.Bottom) + r.Offset(0, lineInfo.LineSize.Height - r.Height); + } + + if (sizeOffset[lineInfo.Line].Width != 0) + { + if (_OversizeDistribute) + { + int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth + ? sizeOffset[lineInfo.Line].Width + : (int) Math.Floor(r.Width*sizeOffset[lineInfo.Line].WidthReduction); + + offset[lineInfo.Line].X += nw - r.Width; + + r.Width = nw; + } + else + { + 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 (!_OversizeDistribute && 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(_EvenHeight && lineInfo.LineSize.Width>0) + r.Width=lineInfo.LineSize.Width; + + r.Offset(offset[lineInfo.Line]); + + if(_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(_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) + { + if (_OversizeDistribute) + { + int nw = sizeOffset[lineInfo.Line].UseAbsoluteWidth + ? sizeOffset[lineInfo.Line].Height : (int)Math.Floor(r.Height * sizeOffset[lineInfo.Line].HeightReduction); + + offset[lineInfo.Line].Y += nw - r.Height; + r.Height = nw; + } + else + { + 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 (!_OversizeDistribute && 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(_ContentOrientation==eContentOrientation.Horizontal) + position.X+=block.Bounds.Width+_BlockSpacing; + else + position.Y+=block.Bounds.Height+_BlockSpacing; + + return position; + } + + internal class BlockLineInfo + { + public ArrayList Blocks=new ArrayList(); + public Size LineSize = Size.Empty; + public int Line; + public int VisibleItemsCount; + } + + private Rectangle MirrorContent(Rectangle containerBounds, Rectangle blockBounds, IBlock[] contentBlocks) + { + 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 + /// + /// Gets or sets the spacing in pixels between content blocks. Default value is 0. + /// + public virtual int BlockSpacing + { + get {return _BlockSpacing;} + set {_BlockSpacing=value;} + } + + /// + /// 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. + /// + public virtual bool FitContainerOversize + { + get {return _FitContainerOversize;} + set {_FitContainerOversize=value;} + } + + /// + /// 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. + /// + public virtual bool FitContainer + { + get {return _FitContainer;} + set {_FitContainer=value;} + } + + /// + /// 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. + /// + public virtual bool VerticalFitContainerWidth + { + get { return _VerticalFitContainerWidth; } + set { _VerticalFitContainerWidth = value; } + } + + /// + /// Gets or sets whether content blocks are resized (Height) to fit container bounds if they + /// occupy less space than the actual container height. Applies to the Horizontal orientation only. Default value is false. + /// + public virtual bool HorizontalFitContainerHeight + { + get { return _HorizontalFitContainerHeight; } + set { _HorizontalFitContainerHeight = value; } + } + + /// + /// Gets or sets the content orientation. Default value is Horizontal. + /// + public virtual eContentOrientation ContentOrientation + { + get {return _ContentOrientation;} + set {_ContentOrientation=value;} + } + + /// + /// Gets or sets the content vertical alignment. Default value is Middle. + /// + public virtual eContentVerticalAlignment ContentVerticalAlignment + { + get {return _ContentVerticalAlignment;} + set {_ContentVerticalAlignment=value;} + } + + /// + /// Gets or sets the block line vertical alignment. Default value is Middle. + /// + public virtual eContentVerticalAlignment BlockLineAlignment + { + get { return _BlockLineAlignment; } + set { _BlockLineAlignment = value; } + } + + /// + /// Gets or sets the content horizontal alignment. Default value is Left. + /// + public virtual eContentAlignment ContentAlignment + { + get {return _ContentAlignment;} + set {_ContentAlignment=value;} + } + + /// + /// Gets or sets whether all content blocks are resized so they have same height which is height of the tallest content block. Default value is false. + /// + public virtual bool EvenHeight + { + get {return _EvenHeight;} + set {_EvenHeight=value;} + } + + /// + /// Gets or sets whether oversized blocks are resized based on the percentage reduction instead of based on equal pixel distribution. Default value is false. + /// + public virtual bool OversizeDistribute + { + get { return _OversizeDistribute; } + set { _OversizeDistribute = value; } + } + + /// + /// Gets or sets whether content is wrapped into new line if it exceeds the width of the container. + /// + public bool MultiLine + { + get {return _MultiLine;} + set {_MultiLine=value;} + } + + /// + /// Gets or sets whether layout is right-to-left. + /// + public bool RightToLeft + { + get { return _RightToLeft; } + set { _RightToLeft = value; } + } + + #endregion + } + + /// + /// Represents event arguments for SerialContentLayoutManager.NextPosition event. + /// + public class LayoutManagerPositionEventArgs : EventArgs + { + /// + /// Gets or sets the block that is layed out. + /// + public IBlock Block; + + /// + /// Gets or sets the current block position. + /// + public Point CurrentPosition = Point.Empty; + + /// + /// Gets or sets the calculated next block position. + /// + public Point NextPosition = Point.Empty; + + /// + /// Cancels default position calculation. + /// + public bool Cancel; + } + + /// + /// Represents event arguments for the SerialContentLayoutManager layout events. + /// + public class LayoutManagerLayoutEventArgs : EventArgs + { + /// + /// Gets or sets the reference block object. + /// + public IBlock Block; + + /// + /// Gets or sets the position block will assume. + /// + public Point CurrentPosition = Point.Empty; + + /// + /// Cancel the layout of the block, applies only to BeforeXXX layout event. + /// + public bool CancelLayout; + + /// + /// Gets or sets the visibility index of the block. + /// + public int BlockVisibleIndex; + + /// + /// Creates new instance of the class and initializes it with default values. + /// + public LayoutManagerLayoutEventArgs(IBlock block, Point currentPosition, int visibleIndex) + { + this.Block = block; + this.CurrentPosition = currentPosition; + this.BlockVisibleIndex = visibleIndex; + } + } + + /// + /// Delegate for SerialContentLayoutManager.NextPosition event. + /// + public delegate void LayoutManagerPositionEventHandler(object sender, LayoutManagerPositionEventArgs e); + + /// + /// Delegate for the SerialContentLayoutManager layout events. + /// + public delegate void LayoutManagerLayoutEventHandler(object sender, LayoutManagerLayoutEventArgs e); + + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/ColorHelpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/ColorHelpers.cs new file mode 100644 index 00000000..44a6b01f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/ColorHelpers.cs @@ -0,0 +1,59 @@ +using System; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Provides helpers when working with colors. + /// + internal static class ColorHelpers + { + /// + /// Converts hex string to Color type. + /// + /// Hexadecimal color representation. + /// Reference to Color object. + public static Color GetColor(string rgbHex) + { + if (string.IsNullOrEmpty(rgbHex)) + return Color.Empty; + + if (rgbHex.Length == 8) + return Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0, 2), 16), + Convert.ToInt32(rgbHex.Substring(2, 2), 16), + Convert.ToInt32(rgbHex.Substring(4, 2), 16), + Convert.ToInt32(rgbHex.Substring(6, 2), 16)); + + return Color.FromArgb(Convert.ToInt32(rgbHex.Substring(0, 2), 16), + Convert.ToInt32(rgbHex.Substring(2, 2), 16), + Convert.ToInt32(rgbHex.Substring(4, 2), 16)); + } + + /// + /// Converts hex string to Color type. + /// + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int rgb) + { + if (rgb == -1) + return Color.Empty; + + return Color.FromArgb((rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF); + } + + /// + /// Converts hex string to Color type. + /// + /// Alpha component for color. + /// Color representation as 32-bit RGB value. + /// Reference to Color object. + public static Color GetColor(int alpha, int rgb) + { + if (rgb == -1) + return Color.Empty; + + return Color.FromArgb(alpha, (rgb & 0xFF0000) >> 16, (rgb & 0xFF00) >> 8, rgb & 0xFF); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/ConvertValue.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/ConvertValue.cs new file mode 100644 index 00000000..c9fa7299 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/ConvertValue.cs @@ -0,0 +1,72 @@ +using System; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// ConvertValue + /// + static public class ConvertValue + { + /// + /// ConvertTo + /// + /// + /// + /// + static public object ConvertTo(object o, Type type) + { + if (o == null || o is DBNull) + return (o); + + if (o.GetType() == type) + return (o); + + if (type == typeof (decimal)) + return (Convert.ToDecimal(o)); + + if (type == typeof (double)) + return (Convert.ToDouble(o)); + + if (type == typeof (Int16)) + return (Convert.ToInt16(o)); + + if (type == typeof (Int32)) + return (Convert.ToInt32(o)); + + if (type == typeof (Int64)) + return (Convert.ToInt64(o)); + + if (type == typeof (Single)) + return (Convert.ToSingle(o)); + + if (type == typeof (UInt16)) + return (Convert.ToUInt16(o)); + + if (type == typeof (UInt32)) + return (Convert.ToUInt32(o)); + + if (type == typeof (UInt64)) + return (Convert.ToUInt64(o)); + + if (type == typeof(sbyte)) + return (Convert.ToSByte(o)); + + if (type == typeof(byte)) + return (Convert.ToByte(o)); + + if (type == typeof(bool)) + return (Convert.ToBoolean(o)); + + if (type == typeof(char)) + return (Convert.ToChar(o)); + + if (type == typeof(string)) + return (Convert.ToString(o)); + + if (type == typeof(DateTime)) + return (Convert.ToDateTime(o)); + + return (o); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/DragDrop.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/DragDrop.cs new file mode 100644 index 00000000..f5b9549d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/DragDrop.cs @@ -0,0 +1,18 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.SuperGrid +{ + internal static class DragDrop + { + public static bool DragStarted(Point pt1, Point pt2) + { + Rectangle r = new Rectangle(pt1.X, pt1.Y, 0, 0); + + r.Inflate(SystemInformation.DragSize.Width, + SystemInformation.DragSize.Height); + + return (r.Contains(pt2.X, pt2.Y) == false); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/TextHelpers.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/TextHelpers.cs new file mode 100644 index 00000000..f1dfa2cb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Helpers/TextHelpers.cs @@ -0,0 +1,55 @@ +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Provides helpers when working with text. + /// + internal static class TextHelper + { + private static int _textMarkupCultureSpecific = 3; + + /// + /// Get or sets the text-markup padding for text + /// measurement when running on Japanese version of Windows. + /// + public static int TextMarkupCultureSpecificPadding + { + get { return _textMarkupCultureSpecific; } + set { _textMarkupCultureSpecific = value; } + } + + /// + /// MeasureText always adds about 1/2 em width of white space on the right, + /// even when NoPadding is specified. It returns zero for an empty string. + /// To get the precise string width, measure the width of a string containing a + /// single period and subtract that from the width of our original string plus a period. + /// + public static Size MeasureText(Graphics g, + string s, Font font, Size csize, eTextFormat tf) + { + return (TextDrawing.MeasureString(g, s, font, csize, tf)); + + if (font.Italic == true) + return (TextDrawing.MeasureString(g, s, font, csize, tf)); + + Size sz1 = TextDrawing.MeasureString(g, ".", font, csize, tf); + Size sz2 = TextDrawing.MeasureString(g, s + ".", font, csize, tf); + + return (new Size(sz2.Width - sz1.Width, sz2.Height)); + } + + public static Size MeasureText(Graphics g, string s, Font font) + { + return (TextDrawing.MeasureString(g, s, font)); + + if (font.Italic == true) + return (TextDrawing.MeasureString(g, s, font)); + + Size sz1 = TextDrawing.MeasureString(g, ".", font); + Size sz2 = TextDrawing.MeasureString(g, s + ".", font); + + return (new Size(sz2.Width - sz1.Width, sz2.Height)); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage.png new file mode 100644 index 00000000..b72f802b Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage16.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage16.png new file mode 100644 index 00000000..7a5b5c8b Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage16.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage20.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage20.png new file mode 100644 index 00000000..5f18420c Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage20.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage24.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage24.png new file mode 100644 index 00000000..c7d37863 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage24.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage32.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage32.png new file mode 100644 index 00000000..0ec0375b Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InfoImage32.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow.png new file mode 100644 index 00000000..31d5206e Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow16.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow16.png new file mode 100644 index 00000000..0a1b7d0c Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow16.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow20.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow20.png new file mode 100644 index 00000000..fb02a6b8 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow20.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow24.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow24.png new file mode 100644 index 00000000..dbd4345f Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow24.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow32.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow32.png new file mode 100644 index 00000000..c800304a Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/InsertRow32.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil16.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil16.png new file mode 100644 index 00000000..33455005 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil16.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil20.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil20.png new file mode 100644 index 00000000..6f21ca47 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil20.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil24.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil24.png new file mode 100644 index 00000000..923cc2b6 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil24.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil3.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil3.png new file mode 100644 index 00000000..fb9a6ec8 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil3.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil32.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil32.png new file mode 100644 index 00000000..433ed042 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Pencil32.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Program.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Program.cs new file mode 100644 index 00000000..b5be5b4e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Program.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace SuperGrid +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Resources.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Resources.Designer.cs new file mode 100644 index 00000000..e5ce2441 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.5448 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DevComponents.DotNetBar.SuperGrid.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DevComponents.DotNetBar.SuperGrid.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Resources.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Resources.resx new file mode 100644 index 00000000..7080a7d1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Resources.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Settings.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Settings.Designer.cs new file mode 100644 index 00000000..b78ae54e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.5448 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DevComponents.DotNetBar.SuperGrid.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Settings.settings b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Settings.settings new file mode 100644 index 00000000..39645652 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SampleExpr.rtf b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SampleExpr.rtf new file mode 100644 index 00000000..5ad2f179 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SampleExpr.rtf @@ -0,0 +1,392 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch0\stshfloch31506\stshfhich31506\stshfbi31506\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} +{\f36\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;} +{\f39\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0502040204020203}Segoe UI;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;} +{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f40\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f41\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\f43\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f44\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f45\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f46\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f47\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f48\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f380\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f381\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;} +{\f383\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f384\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f387\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f388\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);} +{\f400\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\f401\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\f403\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\f404\fbidi \froman\fcharset162\fprq2 Cambria Tur;} +{\f407\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\f408\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\f410\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f411\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\f413\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f414\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f417\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f418\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);} +{\f420\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}{\f421\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f423\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f424\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;} +{\f425\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f426\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f427\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f428\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);} +{\f429\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\f430\fbidi \fswiss\fcharset238\fprq2 Segoe UI CE;}{\f431\fbidi \fswiss\fcharset204\fprq2 Segoe UI Cyr;}{\f433\fbidi \fswiss\fcharset161\fprq2 Segoe UI Greek;} +{\f434\fbidi \fswiss\fcharset162\fprq2 Segoe UI Tur;}{\f436\fbidi \fswiss\fcharset178\fprq2 Segoe UI (Arabic);}{\f437\fbidi \fswiss\fcharset186\fprq2 Segoe UI Baltic;}{\f438\fbidi \fswiss\fcharset163\fprq2 Segoe UI (Vietnamese);} +{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;} +{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;} +{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} +{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} +{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; +\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\caccentone\ctint255\cshade191\red54\green95\blue145;\caccentone\ctint255\cshade255\red79\green129\blue189;\red220\green20\blue60; +\red165\green42\blue42;\red139\green0\blue0;}{\*\defchp \f31506\fs22 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{ +\s1\ql \li0\ri0\sb480\sl276\slmult1\keep\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 +\b\fs28\cf17\lang1033\langfe1033\loch\f31502\hich\af31502\dbch\af31501\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink15 \sqformat \spriority9 \styrsid5309040 heading 1;}{\s2\ql \li0\ri0\sb200\sl276\slmult1 +\keep\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs26\alang1025 \ltrch\fcs0 \b\fs26\cf18\lang1033\langfe1033\loch\f31502\hich\af31502\dbch\af31501\cgrid\langnp1033\langfenp1033 +\sbasedon0 \snext0 \slink16 \sunhideused \sqformat \spriority9 \styrsid5577294 heading 2;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31506\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive +\rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\fs28\cf17\loch\f31502\hich\af31502\dbch\af31501 \sbasedon10 \slink1 \slocked \spriority9 \styrsid5309040 Heading 1 Char;}{\*\cs16 \additive \rtlch\fcs1 \ab\af0\afs26 \ltrch\fcs0 +\b\fs26\cf18\loch\f31502\hich\af31502\dbch\af31501 \sbasedon10 \slink2 \slocked \spriority9 \styrsid5577294 Heading 2 Char;}{\*\ts17\tsrowd\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 +\trbrdrv\brdrs\brdrw10 \trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv +\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon11 \snext17 \spriority59 \styrsid5309040 +Table Grid;}{\*\cs18 \additive \rtlch\fcs1 \ai\af0 \ltrch\fcs0 \i \sbasedon10 \sqformat \spriority20 \styrsid5309040 Emphasis;}}{\*\rsidtbl \rsid68473\rsid1339969\rsid1911172\rsid2585630\rsid2703695\rsid2703989\rsid5197621\rsid5309040\rsid5577294 +\rsid6763582\rsid7805558\rsid11556279\rsid12418639\rsid14490061\rsid14880401\rsid15015837\rsid15694138\rsid16671883}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info +{\author Brianta}{\operator Brianta}{\creatim\yr2012\mo3\dy30\hr23\min33}{\revtim\yr2012\mo4\dy19\hr11\min37}{\version8}{\edmins170}{\nofpages3}{\nofwords360}{\nofchars2052}{\nofcharsws2408}{\vern49273}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/o +ffice/word/2003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt630\margb1440\gutter0\ltrsect +\deftab2160\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1 +\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin630\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct +\asianbrkrule\rsidroot2703695\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0 +{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sectrsid2585630\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\s1\ql \li0\ri0\sl276\slmult1\keep\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid16671883 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 +\b\fs28\cf17\lang1033\langfe1033\loch\af31502\hich\af31502\dbch\af31501\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2703695 \hich\af31502\dbch\af31501\loch\f31502 Operators: +\par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid16671883 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid5309040 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 + \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Add +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 - \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Subtract}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 *\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Multiply}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 / \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Divide}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 = \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Equal}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid14880401 !}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 = \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Not}{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\insrsid2703695 Equal}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5309040\charrsid2703695 +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 < \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Less Than}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 <= \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Less}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 }{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Than}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid15694138 o}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid2703695\charrsid2703695 r}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Equal}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 > \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Greater Than}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 >=\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Gre}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 ater}{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\insrsid2703695 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Than}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid15694138 o}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 r}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Equal +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 (\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 L}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 eft Parenthesis}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 )\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 R}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 ight Parenthesis}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 &&\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Conditional}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 And}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 AND\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Conditional}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 And}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 ||\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Conditional}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Or}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 OR \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Conditional}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Or +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 &\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Logical}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 And}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 |\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Logical}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Or +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 ^\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 Logical}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Xor +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5309040 XOR\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid2703695 Logical}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294 Xor}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid2703695 +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 %\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Mod}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5309040 ulus}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid2703695 +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 <<\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 S}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 hift Left}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 >>\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Shift Right +\par +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138 [IS] }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid2703695\charrsid5309040 LIKE\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 Like (matches only what is specified)}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 [IS] }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5309040 NOT\tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294 Negate}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid2703695\charrsid2703695 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138 [IS] }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5309040 BETWEEN}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294 \tab Between (range comparison)}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695\charrsid2703695 +\par }\pard \ltrpar\ql \li0\ri0\widctlpar\brdrb\brdrs\brdrw15\brsp20 \wrapdefault\faauto\rin0\lin0\itap0\pararsid16671883 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 +\par }\pard\plain \ltrpar\s1\ql \li0\ri0\sb240\sl276\slmult1\keep\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid16671883 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 +\b\fs28\cf17\lang1033\langfe1033\loch\af31502\hich\af31502\dbch\af31501\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5577294 \hich\af31502\dbch\af31501\loch\f31502 Functions: +\par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid16671883 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 N}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ow}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid5309040 Today\rquote s DateTime}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 D}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ate}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid5309040 Date portion of DateTime}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 T}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 od}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid5309040 Time of day}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 TimeOfD}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ay}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 \tab }{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5309040 Time of day}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294 +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid15694138\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 D}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ow}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Day of Week}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 DayOfW}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 eek}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 \tab }{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5309040 Day of Week}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 D}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 oy}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Day of Year}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 DayOfY}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ear}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 \tab }{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5309040 Day of Year}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid12418639 {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639 FirstOfMonth}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639\charrsid5197621 \tab }{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid12418639 First of month}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid7805558 (DateTime)}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid12418639\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639 End}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639 OfMonth}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639\charrsid5197621 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid12418639 End}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid12418639 of month}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid7805558 (DateTime)}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid12418639 +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid12418639\charrsid5577294 +\par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid16671883 {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 Y}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ear}{\rtlch\fcs1 +\ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid15694138 Year}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 Y}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ears}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Year}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 M}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 onth}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Month}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 M}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 onths}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Months}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 Ho}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ur}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Hour}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 H}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ours}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Hours}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 M}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 inute}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Minutes}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 M}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 inutes}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Minutess}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 S}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 econd}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Second}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 S}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 econds}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid15694138 Seconds}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 TotalY}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ears }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138 \tab }{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\insrsid15694138 Total Years}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 TotalD}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ays}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138 \tab }{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\insrsid15694138 Total Days}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 TotalH}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ours }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138 \tab }{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\insrsid15694138 Total Hours}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 TotalM}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 inutes}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138 \tab }{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\insrsid15694138 Total Minutes}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 TotalS}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 econds}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138 \tab }{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\insrsid15694138 Total Seconds}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 C}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 eiling}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid15694138 Smallest integral greater than or equal to the value}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 Floor\tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15694138 Largest integral greater than or equal to the value}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid15694138\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid15694138\charrsid5197621 Round}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15694138 Rounds to a specified number of digits}{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\insrsid15694138\charrsid5577294 +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid15694138 \tab }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 L}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ength}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid6763582 Length of string}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 Ri}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ght}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid6763582 Right part of a string with the specified number of characters}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 L}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 eft}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid6763582 Left part of a string with the specified number of characters}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 S}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ubstring}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid6763582 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid6763582 Part of a string with the specified number of characters}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294 +\par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid12418639 {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639 IndexOf}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid12418639 Gets the first occurrence of the specified string}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid12418639 +\par }\pard \ltrpar\qc \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid12418639 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid16671883 {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 T}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 ostring}{ +\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid6763582 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6763582 String representation of the specified value}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 T}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 olower}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid6763582 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid6763582 Lowercase representation of the specified string}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 T}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 oupper}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid6763582 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid6763582 Uppercase representation of the specified string}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 T}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 rim}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid6763582 Leading }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15015837 and trailing whitespace removed}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 LT}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5577294\charrsid5197621 rim}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid6763582 Leading }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15015837 whitespace removed}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid5577294\charrsid5577294 +\par }\pard \ltrpar\ql \li0\ri0\widctlpar\brdrb\brdrs\brdrw15\brsp20 \wrapdefault\faauto\rin0\lin0\itap0\pararsid16671883 {\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid5309040\charrsid5197621 RT}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 +\cs18\i\insrsid5577294\charrsid5197621 rim}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid16671883 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6763582 Tr}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15015837 ailing whitespace removed}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid5577294 +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12418639 +\par }{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639\charrsid5197621 R}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639 aw}{\rtlch\fcs1 \ai\af0 \ltrch\fcs0 \cs18\i\insrsid12418639 \tab }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12418639 +Unevaluated string contents +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2585630 +\par }\pard\plain \ltrpar\s1\ql \li0\ri0\sb240\sl276\slmult1\keep\keepn\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid16671883 \rtlch\fcs1 \ab\af0\afs28\alang1025 \ltrch\fcs0 +\b\fs28\cf17\lang1033\langfe1033\loch\af31502\hich\af31502\dbch\af31501\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5577294 \hich\af31502\dbch\af31501\loch\f31502 Examples: +\par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid16671883 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid5577294 +\par }\pard \ltrpar\ql \li0\ri0\sl360\slmult1\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid16671883 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid6763582 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid6763582 LastName}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid6763582 >=}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf19\insrsid6763582 "T}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid1911172 olstoy}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid6763582 "}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 ) }{ +\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid6763582 OR}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 ((}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid6763582 Age}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid6763582 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid6763582 >}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 20) }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid6763582 AND}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid6763582 Age}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf2\insrsid6763582 <}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 45))}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid6763582 +\par (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid6763582 FirstName}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid6763582 LIKE}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid6763582 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid6763582 "Al"}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 ) }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid6763582 AND}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid6763582 "Count"}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf2\insrsid6763582 =}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 (30 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid6763582 /}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 }{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid6763582 Index}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid6763582 )) +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid2703989 ToString}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid2703989 HireDate}{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 ) }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid2703989 LIKE}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid2703989 +"6/15" +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid2703989 HireDate}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid2703989 = }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\insrsid2703695 #12/31/2010#}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703989 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703695 +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid2703989 Date}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid2703989 HireDate}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid2703989 ) }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid2703989 =}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid2703989 Date}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid2703989 Now}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 ()) +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid2703989 ToUpper}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid2703989 FirstName}{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 ) }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid2703989 =}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid1911172 "SMY}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid2703989 TH}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid1911172 E}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid2703989 " +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703989 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid2703989 Age}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 +\f39\fs14\cf2\insrsid2703989 IS BETWEEN}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 20 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid2703989 AND}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 30) }{ +\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid2703989 AND}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid2703989 Age}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid2703989 !=}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 25) +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid2703989 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid2703989 LastName}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 +\f39\fs14\cf2\insrsid2703989 IS}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid14490061 NOT }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid2703989 EMPTY}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 )}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid2703989 AND}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid2703989 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid2703989 Age}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid2703989 IS}{\rtlch\fcs1 +\af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid2703989 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid14490061 NOT}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 +\f39\fs14\cf2\insrsid2703989 NULL}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 ) +\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid14490061 "Street"}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid14490061 IS}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid14490061 }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid14490061 NOT LIKE}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid14490061 "Los"}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl360\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid16671883 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid14490061 Right}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid14490061 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid14490061 LastName}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 ,3) }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 !=}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid14490061 "son"\line }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid14490061 (((}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf11\insrsid14490061 Age}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 %}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 10) }{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 =}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 0) }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid14490061 AND}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid14490061 ((}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid14490061 "Circ"}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 /}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 25) }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 >}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 250)) }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 +\f39\fs14\cf2\insrsid14490061 OR}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 ((}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid14490061 "Circ"}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 }{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 <<}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 2) }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 >}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid14490061 100)\line }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\insrsid14490061 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid14490061 Length}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 (}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid14490061 LastName}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 ) }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 >}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid14490061 3) }{\rtlch\fcs1 \af39\afs14 \ltrch\fcs0 \f39\fs14\cf2\insrsid14490061 AND}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid14490061 Substring}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid14490061 LastName}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 ,2,1) }{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 =}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf19\insrsid14490061 "c"}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 ) +\line }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid14490061 Year}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid14490061 HireDate}{\rtlch\fcs1 \af39\afs18 +\ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 ) }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 =}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 1996\line }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf20\insrsid14490061 Month}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf11\insrsid14490061 HireDate}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 ) }{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf2\insrsid14490061 =}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid14490061 Month}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 +\f39\fs18\cf1\insrsid14490061 (}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf20\insrsid14490061 Now}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid14490061 ())}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid1911172 \line }{ +\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf21\insrsid11556279 IndexOf}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid11556279 (}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf21\insrsid11556279 Left}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 +\f38\fs16\cf1\insrsid11556279 (}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf11\insrsid11556279 FirstName}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid11556279 , 1), }{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf19\insrsid11556279 +"AEIOUY"}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid11556279 ) }{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf2\insrsid11556279 >=}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid11556279 0}{\rtlch\fcs1 \af38\afs16 +\ltrch\fcs0 \f38\fs16\cf1\insrsid11556279 \line }{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf21\insrsid11556279 Left}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid11556279 (}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 +\f38\fs16\cf21\insrsid11556279 Raw}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid11556279 (), 5) }{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf2\insrsid11556279 =}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid11556279 }{ +\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf19\insrsid11556279 "=sum("}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf19\insrsid7805558 \line }{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf21\insrsid7805558 Day}{\rtlch\fcs1 \af38\afs16 +\ltrch\fcs0 \f38\fs16\cf1\insrsid7805558 (}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf21\insrsid7805558 EndOfMonth}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid7805558 (}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 +\f38\fs16\cf11\insrsid7805558 HireDate}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid7805558 )) }{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf2\insrsid7805558 =}{\rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16\cf1\insrsid7805558 29}{ +\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \f39\fs18\cf1\insrsid1911172\charrsid14490061 +\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a +9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad +5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 +b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 +0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 +a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f +c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 +0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 +a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 +6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b +4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b +4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210030dd4329a8060000a41b0000160000007468656d652f7468656d652f +7468656d65312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87 +615b8116d8a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad +79482a9c0498f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b +5d8a314d3c94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab +999fb7b4717509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9 +699640f6719e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd586 +8b37a088d1e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d6 +0cf03ac1a5193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f +9e7ef3f2d117d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be +15c308d3f28acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a9979 +3849c26ae66252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d +32a423279a668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2a +f074481847bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86 +e877f0034e16bafb0e258ebb4faf06b769e888340b103d331115bebc4eb813bf83291b63624a0d1475a756c734f9bbc2cd28546ecbe1e20a3794ca175f3fae90 +fb6d2dd99bb07b55e5ccf68942bd0877b23c77b908e8db5f9db7f024d9239010f35bd4bbe2fcae387bfff9e2bc289f2fbe24cfaa301468dd8bd846dbb4ddf1c2 +ae7b4c191ba8292337a469bc25ec3d411f06f53a73e224c5292c8de0516732307070a1c0660d125c7d44553488700a4d7bddd3444299910e254ab984c3a219ae +a4adf1d0f82b7bd46cea4388ad1c12ab5d1ed8e1153d9c9f350a3246aad01c6873462b9ac05999ad5cc988826eafc3acae853a33b7ba11cd1445875ba1b236b1 +399483c90bd560b0b0263435085a21b0f22a9cf9356b38ec6046026d77eba3dc2dc60b17e92219e180643ed27acffba86e9c94c7ca9c225a0f1b0cfae0788ad5 +4adc5a9aec1b703b8b93caec1a0bd8e5de7b132fe5113cf312503b998e2c2927274bd051db6b35979b1ef271daf6c6704e86c73805af4bdd476216c26593af84 +0dfb5393d964f9cc9bad5c313709ea70f561ed3ea7b053075221d51696910d0d339585004b34272bff7213cc7a510a5454a3b349b1b206c1f0af490176745d4b +c663e2abb2b34b23da76f6352ba57ca2881844c1111ab189d8c7e07e1daaa04f40255c77988aa05fe06e4e5bdb4cb9c5394bbaf28d98c1d971ccd20867e556a7 +689ec9166e0a522183792b8907ba55ca6e943bbf2a26e52f48957218ffcf54d1fb09dc3eac04da033e5c0d0b8c74a6b43d2e54c4a10aa511f5fb021a07533b20 +5ae07e17a621a8e082dafc17e450ffb739676998b48643a4daa7211214f623150942f6a02c99e83b85583ddbbb2c4996113211551257a656ec1139246ca86be0 +aadedb3d1441a89b6a929501833b197fee7b9641a3503739e57c732a59b1f7da1cf8a73b1f9bcca0945b874d4393dbbf10b1680f66bbaa5d6f96e77b6f59113d +316bb31a795600b3d256d0cad2fe354538e7566b2bd69cc6cbcd5c38f0e2bcc63058344429dc2121fd07f63f2a7c66bf76e80d75c8f7a1b622f878a18941d840 +545fb28d07d205d20e8ea071b283369834296bdaac75d256cb37eb0bee740bbe278cad253b8bbfcf69eca23973d939b97891c6ce2cecd8da8e2d343578f6648a +c2d0383fc818c798cf64e52f597c740f1cbd05df0c264c49134cf09d4a60e8a107260f20f92d47b374e32f000000ffff0300504b030414000600080000002100 +0dd1909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f7 +8277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89 +d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd500 +1996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0f +bfff0000001c0200001300000000000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6 +a7e7c0000000360100000b00000000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a +0000001c00000000000000000000000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d00140006000800000021 +0030dd4329a8060000a41b00001600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d001400060008 +00000021000dd1909fb60000001b0100002700000000000000000000000000b20900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000ad0a00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; +\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; +\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 +4d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e50000000000000000000000008062 +b5795b1ecd01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid.csproj b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid.csproj new file mode 100644 index 00000000..8ef843d3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid.csproj @@ -0,0 +1,489 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {A344305F-D2E2-4350-B61E-D7277959A5B4} + Library + Properties + DevComponents.DotNetBar.SuperGrid + DevComponents.DotNetBar.SuperGrid + + + true + SuperGrid.snk + v2.0 + + + + + 2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;SUPERGRID + prompt + 4 + bin\Debug\DevComponents.DotNetBar.SuperGrid.XML + x86 + + + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE;SUPERGRID + prompt + 4 + bin\Release\DevComponents.DotNetBar.SuperGrid.XML + AllRules.ruleset + + + bin\Release\ + SUPERGRID;TRIAL + bin\Release\DevComponents.DotNetBar.SuperGrid.XML + AllRules.ruleset + + + bin\Release\ + TRACE;SUPERGRID;TRIAL + true + pdbonly + AnyCPU + prompt + bin\Release\DevComponents.DotNetBar.SuperGrid.XML + AllRules.ruleset + + + + + + + + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + Designer + FloatWindow.cs + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + True + Settings.settings + True + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + Form + + + CellInfoWindow.cs + + + + + + + Form + + + FloatWindow.cs + + + Component + + + Component + + + + + Component + + + Form + + + CustomFilter.cs + + + Form + + + CustomFilterEx.cs + + + + UserControl + + + FilterDateTimePicker.cs + + + + UserControl + + + FilterExprEdit.cs + + + Component + + + Component + + + + + Component + + + Component + + + + Form + + + SampleExpr.cs + + + Component + + + Component + + + Component + + + + + Component + + + Component + + + + + + + + + + + + + + + + + + + + + + + + Component + + + + Component + + + Component + + + + Component + + + + Component + + + + + + + + + + + + Component + + + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Designer + CellInfoWindow.cs + + + + + + CustomFilter.cs + Designer + + + CustomFilterEx.cs + Designer + + + FilterDateTimePicker.cs + Designer + + + FilterExprEdit.cs + Designer + + + SampleExpr.cs + Designer + + + + + {36546CE3-335C-4AB6-A2F3-40F8C818BC66} + DotNetBar + + + {3084E369-3D7B-4918-958F-2776DA03E6BC} + DevComponents.Instrumentation + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid.snk b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid.snk new file mode 100644 index 00000000..644c4bc8 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid.snk differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/EditorPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/EditorPanel.cs new file mode 100644 index 00000000..70c56cd6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/EditorPanel.cs @@ -0,0 +1,105 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// EditorPanel + /// + [ToolboxItem(false)] + public class EditorPanel : Control + { + #region Private variables + + private Size _SizeEx; + private Point _OffsetEx; + private GridCell _GridCell; + + #endregion + + /// + /// Constructor + /// + public EditorPanel() + { + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + } + + #region Public properties + + #region GridCell + + /// + /// GridCell + /// + public GridCell GridCell + { + get { return (_GridCell); } + internal set { _GridCell = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region OffsetEx + + internal Point OffsetEx + { + get { return (_OffsetEx); } + set { _OffsetEx = value; } + } + + #endregion + + #region SizeEx + + internal Size SizeEx + { + get { return (_SizeEx); } + set { _SizeEx = value; } + } + + #endregion + + #endregion + + #region OnPaintBackground + + /// + /// Background painting + /// + /// + protected override void OnPaintBackground(PaintEventArgs e) + { + Graphics g = e.Graphics; + + if (_GridCell != null && _GridCell.GridColumn != null) + { + Rectangle r = new Rectangle(_OffsetEx, _SizeEx); + VisualStyle style = _GridCell.GetEffectiveStyle(); + + if (r.IsEmpty == false) + { + if (_GridCell.SuperGrid.DoPreRenderCellEvent(g, _GridCell, RenderParts.Background, r) == false) + { + using (Brush br = style.Background.GetBrush(r)) + g.FillRectangle(br, r); + + _GridCell.SuperGrid.DoPostRenderCellEvent(g, _GridCell, RenderParts.Background, r); + } + } + } + else + { + base.OnPaintBackground(e); + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridBubbleBarEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridBubbleBarEditControl.cs new file mode 100644 index 00000000..ff9e6966 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridBubbleBarEditControl.cs @@ -0,0 +1,517 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridCheckBoxEditControl + /// + [ToolboxItem(false)] + public class GridBubbleBarEditControl : BubbleBar, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.Both; + + #endregion + + /// + /// GridBubbleBarEditControl + /// + public GridBubbleBarEditControl() + { + ShowTooltips = false; + + ButtonClick += EditControlButtonClick; + +#if !TRIAL + LicenseKey = "F962CEC7-CD8F-4911-A9E9-CAB39962FC1F"; +#endif + } + + #region Hidden properties + + /// + /// ShowTooltips + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool ShowTooltips + { + get { return (base.ShowTooltips); } + set { base.ShowTooltips = value; } + } + + #endregion + + #region EditControlButtonClick + + private void EditControlButtonClick(object sender, ClickEventArgs e) + { + if (_SuspendUpdate == false) + { + if (_Cell != null) + { + _Cell.Value = SelectedTab.Buttons.IndexOf((BubbleButton) sender); + _Cell.EditorValueChanged(this); + + _Cell.EndEdit(); + } + } + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaint + + /// + /// OnPaint + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + + PaintControl(e); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public virtual bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get { return (Text); } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + + set + { + if (_EditorPanel != null) + _EditorPanel.VisibleChanged -= EditorPanelVisibleChanged; + + _EditorPanel = value; + + if (_EditorPanel != null) + _EditorPanel.VisibleChanged += EditorPanelVisibleChanged; + } + } + + void EditorPanelVisibleChanged(object sender, EventArgs e) + { + if (_EditorPanel.Visible == false) + StopBubbleEffect(); + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (_Cell.Value); } + set { } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public virtual bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.None); } + } + + #endregion + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + if (constraintSize.Height == 0) + size.Height = Dpi.Height50; + + return (size); + } + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + + Font = style.Font; + ForeColor = style.TextColor; + } + + _ValueChanged = false; + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// false + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// false + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + Focus(); + + switch (e.KeyData) + { + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridButtonEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridButtonEditControl.cs new file mode 100644 index 00000000..a52dd70c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridButtonEditControl.cs @@ -0,0 +1,501 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridButtonXEditControl + /// + [ToolboxItem(false)] + public class GridButtonEditControl : Button, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + private bool _UseCellValueAsButtonText = true; + + private StretchBehavior _StretchBehavior = StretchBehavior.Both; + + #endregion + + /// + /// GridButtonEditControl + /// + public GridButtonEditControl() + { + AccessibleRole = AccessibleRole.PushButton; + + Click += ButtonClick; + } + + #region Public properties + + #region UseCellValueAsButtonText + + /// + /// UseCellValueAsButtonText + /// + public bool UseCellValueAsButtonText + { + get { return (_UseCellValueAsButtonText); } + set { _UseCellValueAsButtonText = value; } + } + + #endregion + + #endregion + + #region ButtonClick + + private void ButtonClick(object sender, EventArgs e) + { + EditorValueChanged = true; + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual string GetValue(object value) + { + if (_UseCellValueAsButtonText == false) + return (Text); + + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (_Cell.NullString); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (value.ToString()); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get { return (Text); } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Text); } + set { Text = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public virtual bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + + Font = style.Font; + ForeColor = style.TextColor; + } + + Text = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + if (constraintSize.Height == 0) + size.Height = Dpi.Height23; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + OnKeyDown(e); + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + + if (Bounds.Contains(e.Location) == true) + OnClick(EventArgs.Empty); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridButtonXEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridButtonXEditControl.cs new file mode 100644 index 00000000..aaa5ef53 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridButtonXEditControl.cs @@ -0,0 +1,610 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridButtonXEditControl + /// + [ToolboxItem(false)] + public class GridButtonXEditControl : ButtonX, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + private bool _UseCellValueAsButtonText = true; + + private StretchBehavior _StretchBehavior = StretchBehavior.Both; + + #endregion + + /// + /// GridButtXEditControl + /// + public GridButtonXEditControl() + { + AutoCheckOnClick = false; + AutoExpandOnClick = false; + AutoSizeMode = AutoSizeMode.GrowAndShrink; + + ColorTable = eButtonColor.OrangeWithBackground; + Style = eDotNetBarStyle.StyleManagerControlled; + + Click += ButtonXClick; + ButtonItem.ExpandChange += ButtonXExpandChanged; + } + + #region Hidden properties + + /// + /// AutoCheckOnClick + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool AutoCheckOnClick + { + get { return (base.AutoCheckOnClick); } + set { base.AutoCheckOnClick = value; } + } + + #endregion + + #region Public properties + + #region FocusCuesEnabled + + /// + /// FocusCuesEnabled + /// + public override bool FocusCuesEnabled + { + get { return (false); } + set { base.FocusCuesEnabled = value; } + } + + #endregion + + #region UseCellValueAsButtonText + + /// + /// UseCellValueAsButtonText + /// + public bool UseCellValueAsButtonText + { + get { return (_UseCellValueAsButtonText); } + set { _UseCellValueAsButtonText = value; } + } + + #endregion + + #endregion + + #region ButtonXExpandChanged + + private void ButtonXExpandChanged(object sender, EventArgs e) + { + if (Expanded == false) + { + _Cell.SuperGrid.PostInternalMouseMove(); + _Cell.SuperGrid.Focus(); + } + } + + #endregion + + #region ButtonXClick + + private void ButtonXClick(object sender, EventArgs e) + { + EditorValueChanged = true; + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual string GetValue(object value) + { + if (_UseCellValueAsButtonText == false) + return (Text); + + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (_Cell.NullString); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (value.ToString()); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (Expanded == false && IsMouseDown == false); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.NonModal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get { return (Text); } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Text); } + set { Text = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public virtual bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + + Font = style.Font; + ForeColor = style.TextColor; + } + + Text = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + // Perform a little kludge work here, since getting the base.PreferredSize + // on a button with empty text seems to add height to the size of the + // button each time it is called. + + string oldText = Text; + + if (string.IsNullOrEmpty(Text)) + Text = " "; + + Size size = GetPreferredSize(constraintSize); + + if (constraintSize.Width > 0) + { + ButtonItem.RecalcSize(); + + if (String.IsNullOrEmpty(ButtonItem.Text) == false) + { + size = ButtonItem.TextDrawRect.Size; + size.Height += Dpi.Height8; + } + } + else + { + size.Width += Dpi.Width1; + } + + if (string.IsNullOrEmpty(oldText)) + Text = oldText; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + Expanded = false; + + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + Expanded = false; + + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + OnKeyDown(e); + OnKeyUp(e); + + Checked = false; + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + Point pt = _Cell.SuperGrid.PointToClient(MousePosition); + + if (_Cell.Bounds.Contains(pt) == false) + StopFade(); + + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + if (_Cell != null) + { + Point pt = _Cell.SuperGrid.PointToClient(MousePosition); + + if (_Cell.Bounds.Contains(pt) == false) + StopFade(); + + OnMouseLeave(e); + + _Cell.GridRow.EditorDirty = false; + + Refresh(); + } + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + Click -= ButtonXClick; + ButtonItem.ExpandChange -= ButtonXExpandChanged; + + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridCheckBoxEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridCheckBoxEditControl.cs new file mode 100644 index 00000000..75d936c2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridCheckBoxEditControl.cs @@ -0,0 +1,612 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridCheckBoxEditControl + /// + [ToolboxItem(false)] + public class GridCheckBoxEditControl : CheckBox, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private object _CheckValueChecked; + private object _CheckValueUnchecked; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridCheckBoxEditControl + /// + public GridCheckBoxEditControl() + { + BackColor = Color.Transparent; + + CheckedChanged += ControlCheckedChanged; + } + + #region Public properties + + #region CheckValueChecked + + /// + /// CheckValueChecked + /// + public object CheckValueChecked + { + get { return (_CheckValueChecked); } + set { _CheckValueChecked = value; } + } + + #endregion + + #region CheckValueUnchecked + + /// + /// CheckValueUnchecked + /// + public object CheckValueUnchecked + { + get { return (_CheckValueUnchecked); } + set { _CheckValueUnchecked = value; } + } + + #endregion + + #endregion + + #region ControlCheckedChanged + + private void ControlCheckedChanged(object sender, EventArgs e) + { + if (_SuspendUpdate == false) + { + if (Checked == true) + _Cell.Value = _CheckValueChecked ?? true; + else + _Cell.Value = _CheckValueUnchecked ?? false; + + _Cell.EditorValueChanged(this); + } + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + /// + public virtual bool GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (false); + } + + Type type = value.GetType(); + + if (CheckValueChecked != null) + { + if (value.Equals(CheckValueChecked)) + return (true); + } + else + { + if (type == typeof(bool)) + return ((bool)value); + + if (type == typeof(string)) + { + string s = (string)value; + + if (_Cell.IsValueExpression == true) + s = _Cell.GetExpValue(s); + + switch (s.ToLower()) + { + case "y": + case "yes": + case "t": + case "true": + case "1": + return (true); + } + } + else + { + int n = Convert.ToInt32(value); + + if (n == 1) + return (true); + } + } + + if (CheckValueUnchecked != null) + { + if (value.Equals(CheckValueUnchecked)) + return (true); + } + else + { + if (type == typeof(bool)) + return ((bool)value); + + if (type == typeof(string)) + { + string s = (string)value; + + if (_Cell.IsValueExpression == true) + s = _Cell.GetExpValue(s); + + switch (s.ToLower()) + { + case "n": + case "no": + case "f": + case "false": + case "0": + return (false); + } + } + else + { + int n = Convert.ToInt32(value); + + if (n == 0) + return (false); + } + } + + throw new Exception("Invalid checkBox cell value (" + value + ")."); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.NonModal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Checked); } + set { Checked = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + + Font = style.Font; + ForeColor = style.TextColor; + } + + Checked = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + Focus(); + + switch (e.KeyData) + { + case Keys.T: + if (Checked == false) + Checked = true; + break; + + case Keys.F: + if (Checked == true) + Checked = false; + break; + + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.T: + case Keys.F: + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridCheckBoxXEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridCheckBoxXEditControl.cs new file mode 100644 index 00000000..96bf965a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridCheckBoxXEditControl.cs @@ -0,0 +1,676 @@ +using System; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridCheckBoxEditControl + /// + [ToolboxItem(false)] + public class GridCheckBoxXEditControl : CheckBoxX, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridCheckBoxXEditControl + /// + public GridCheckBoxXEditControl() + { + CheckValueChecked = null; + CheckValueUnchecked = null; + + Text = ""; + + CheckedChanged += ControlCheckedChanged; + } + + #region ControlCheckedChanged + + private void ControlCheckedChanged(object sender, EventArgs e) + { + if (_SuspendUpdate == false) + { + if (CheckState == CheckState.Checked) + { + _Cell.Value = (CheckValueChecked ?? true); + } + else if (CheckState == CheckState.Unchecked) + { + _Cell.Value = (CheckValueUnchecked ?? false); + } + else + { + _Cell.Value = CheckValueIndeterminate; + } + + _Cell.EditorValueChanged(this); + } + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaint + + /// + /// OnPaint + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + + PaintControl(e); + } + + #endregion + + #region Text + + /// + /// Text + /// + public override string Text + { + get { return (base.Text); } + + set + { + if (string.IsNullOrEmpty(value)) + { + value = ""; + + TextVisible = false; + } + else + { + TextVisible = true; + } + + base.Text = value; + } + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + /// + public virtual CheckState GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (ThreeState ? CheckState.Indeterminate : CheckState.Unchecked); + } + + Type type = value.GetType(); + + if (CheckValueChecked != null) + { + if (value.Equals(CheckValueChecked)) + return (CheckState.Checked); + } + + if (CheckValueUnchecked != null) + { + if (value.Equals(CheckValueUnchecked)) + return (CheckState.Unchecked); + } + + if (type == typeof (bool)) + return ((bool) value ? CheckState.Checked : CheckState.Unchecked); + + if (type == typeof (string)) + { + string s = (string) value; + + if (_Cell.IsValueExpression == true) + s = _Cell.GetExpValue(s); + + switch (s.ToLower()) + { + case "y": + case "yes": + case "t": + case "true": + case "1": + return (CheckState.Checked); + + case "": + case "0": + case "n": + case "no": + case "f": + case "false": + return (CheckState.Unchecked); + } + } + else if (type == typeof (SqlBoolean)) + { + SqlBoolean sb = (SqlBoolean) value; + + if (sb.IsNull == true) + return (ThreeState ? CheckState.Indeterminate : CheckState.Unchecked); + + return (sb.IsTrue ? CheckState.Checked : CheckState.Unchecked); + } + else if (type == typeof(char)) + { + char c = (char)value; + + switch (Char.ToLower(c)) + { + case 't': + case 'y': + case '1': + return (CheckState.Checked); + + case 'f': + case 'n': + case '0': + return (CheckState.Unchecked); + } + } + else + { + int n = Convert.ToInt32(value); + + return (n == 0 ? CheckState.Unchecked : CheckState.Checked); + } + + throw new Exception("Invalid checkBox cell value (" + value + ")."); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (EditorValue.ToString()); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (CheckState); } + set { CheckState = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(bool)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + + Font = style.Font; + ForeColor = style.TextColor; + } + + CheckState = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + HostItem.RecalcSize(); + Size size = HostItem.Size; + + if (TextVisible == false) + { + // RadioButtons are not actually 13 - they are 14, even + // though the system thinks they are 13. + + if (CheckBoxStyle == eCheckBoxStyle.RadioButton) + size.Height += Dpi.Height1; + + if (size.Width < size.Height) + size.Width = size.Height; + } + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + switch (e.KeyData) + { + case Keys.T: + case Keys.Y: + if (Checked == false) + Checked = true; + break; + + case Keys.F: + case Keys.N: + if (Checked == true) + Checked = false; + break; + + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.T: + case Keys.F: + case Keys.Y: + case Keys.N: + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + eCheckBoxStyle style = CheckBoxStyle; + CheckBoxStyle = eCheckBoxStyle.CheckBox; + + try + { + OnMouseUp(e); + } + finally + { + CheckBoxStyle = style; + } + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + CheckedChanged -= ControlCheckedChanged; + + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridColorPickerEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridColorPickerEditControl.cs new file mode 100644 index 00000000..69529d13 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridColorPickerEditControl.cs @@ -0,0 +1,602 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridColorPickerEditControl + /// + [ToolboxItem(false)] + public class GridColorPickerEditControl : ColorPickerButton, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridColorPickerEditControl + /// + public GridColorPickerEditControl() + { + AccessibleRole = AccessibleRole.PushButton; + AutoSizeMode = AutoSizeMode.GrowAndShrink; + ColorTable = eButtonColor.Flat; + + InternalAutoExpandOnClick = true; + InternalFocusCuesEnabled = false; + InternalStyle = eDotNetBarStyle.StyleManagerControlled; + + SetSelectedColorImageEx(); + + SelectedColorChanged += ControlSelectedColorChanged; + } + + #region SetSelectedColorImage + + /// + /// Creates and sets the Image and SelectedColorImageRectangle. + /// + protected virtual void SetSelectedColorImage() + { + SetSelectedColorImageEx(); + } + + private void SetSelectedColorImageEx() + { + Rectangle r = new Rectangle(0, 0, 16, 16); + + Bitmap image = new Bitmap(r.Width, r.Height); + + using (Graphics g = Graphics.FromImage(image)) + g.FillRectangle(Brushes.Black, r); + + r.Inflate(-1, -1); + + Image = image; + SelectedColorImageRectangle = r; + } + + #endregion + + #region ControlSelectedColorChanged + + private void ControlSelectedColorChanged(object sender, EventArgs e) + { + if (_SuspendUpdate == false) + { + Type dataType = _Cell.GridColumn.DataType; + + if (dataType == null && _Cell.Value != null) + dataType = _Cell.Value.GetType(); + + if (dataType == typeof(Color)) + { + _Cell.Value = SelectedColor; + } + else if (dataType == typeof(string)) + { + if (SelectedColor.IsKnownColor) + _Cell.Value = SelectedColor.Name; + else + _Cell.Value = SelectedColor.ToArgb().ToString(); + } + else + { + _Cell.Value = SelectedColor.ToArgb(); + } + + _Cell.EditorValueChanged(this); + } + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated processing. + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual int GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (0); + } + + if (value.GetType() == typeof(int)) + return ((int)value); + + if (value.GetType() == typeof(Color)) + return (((Color)value).ToArgb()); + + if (value is string) + { + Color color = Color.FromName((string)value); + + if (color.IsKnownColor == true) + return (color.ToArgb()); + + int x; + if (int.TryParse((string)value, out x) == true) + return (x); + + if (int.TryParse((string)value, + NumberStyles.HexNumber, CultureInfo.InvariantCulture, out x) == true) + return (x); + } + + throw new Exception("Invalid cell value (" + value + ")."); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (Expanded == false && IsMouseDown == false); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.NonModal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return String.IsNullOrEmpty(SelectedColor.Name) ? "" : SelectedColor.Name; + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (SelectedColor.ToArgb()); } + + set + { + Color color = Color.FromArgb(GetValue(value)); + + if (SelectedColor != color) + SelectedColor = color; + } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(int)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public virtual bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + + Font = style.Font; + ForeColor = style.TextColor; + BackColor = Color.Transparent; + } + + int value = GetValue(_Cell.Value); + + if (value != 0) + SelectedColor = Color.FromArgb(value); + else + SelectedColor = Color.Empty; + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + OnKeyDown(e); + OnKeyUp(e); + + Checked = false; + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + Refresh(); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + if (_Cell != null) + { + Refresh(); + OnMouseLeave(e); + } + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + Image image = Image; + + if (image != null) + { + Image = null; + + image.Dispose(); + } + + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridComboBoxExEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridComboBoxExEditControl.cs new file mode 100644 index 00000000..6e7dd078 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridComboBoxExEditControl.cs @@ -0,0 +1,871 @@ +using System; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridComboBoxExEditControl + /// + [ToolboxItem(false)] + public class GridComboBoxExEditControl : ComboBoxEx, IGridCellEditControl + { + #region DllImports + + [DllImport("kernel32.dll")] + private static extern int GetCurrentThreadId(); + + [DllImport("user32.dll")] + private static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern void GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); + + [DllImport("user32.dll")] + private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam); + + private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); + + #endregion + + #region Static data + + static bool _StaticIsOpen; + + #endregion + + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + private bool _PanelShown; + private bool _CacheDisplayMembers = true; + + private int _ValueIndex; + private string _ValueText; + + private int[] _ValueIndicees; + private object[] _ValueMembers; + + private CurrencyManager _CurrentDataManager; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridComboBoxExEditControl + /// + public GridComboBoxExEditControl() + { + DrawMode = DrawMode.OwnerDrawFixed; + DisconnectedPopupDataSource = true; + + BindingContext = new BindingContext(); + } + + #region OnDataSourceChanged + + /// + /// OnDataSourceChanged + /// + /// + protected override void OnDataSourceChanged(EventArgs e) + { + if (_CurrentDataManager != null) + _CurrentDataManager.ListChanged -= DataManagerListChanged; + + base.OnDataSourceChanged(e); + + _ValueMembers = null; + _ValueIndicees = null; + + _CurrentDataManager = DataManager; + + if (_CurrentDataManager != null) + _CurrentDataManager.ListChanged += DataManagerListChanged; + + if (IsDisposed == false) + { + if (_Cell != null && _Cell.GridPanel != null) + InitializeContext(_Cell, null); + } + } + + #endregion + + #region DataManagerListChanged + + /// + /// DataManager_ListChanged + /// + /// + /// + void DataManagerListChanged(object sender, ListChangedEventArgs e) + { + _ValueMembers = null; + _ValueIndicees = null; + } + + #endregion + + #region OnTextChanged + + /// + /// OnTextChanged + /// + /// + protected override void OnTextChanged(EventArgs e) + { + if (IsDisposed == false) + { + if (_Cell != null && _SuspendUpdate == false) + { + _Cell.EditorValueChanged(this); + + _ValueIndex = -1; + } + } + + base.OnTextChanged(e); + } + + #endregion + + #region OnSelectedIndexChanged + + /// + /// OnSelectedIndexChanged + /// + /// + protected override void OnSelectedIndexChanged(EventArgs e) + { + if (IsDisposed == false) + { + if (_Cell != null && _SuspendUpdate == false) + { + _ValueIndex = SelectedIndex; + + _Cell.EditorValueChanged(this); + + EditorValueChanged = true; + } + } + + base.OnSelectedIndexChanged(e); + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual object GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (""); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (value); + } + + #endregion + + #region SetValue + + private void SetValue(object o, bool initEdit) + { + _ValueText = ""; + _ValueIndex = -1; + + bool oldSuspend = SuspendUpdate; + SuspendUpdate = true; + + SelectedIndex = -1; + + SuspendUpdate = oldSuspend; + + if (o != null) + { + _ValueText = o.ToString(); + + if (string.IsNullOrEmpty(_ValueText) == false && + string.IsNullOrEmpty(ValueMember) == false && + string.IsNullOrEmpty(DisplayMember) == false) + { + if (Items.Count > 0) + { + if (Items[0] is DataRowView && + initEdit == false && _CacheDisplayMembers == true) + { + SetSelectedDrvValue(o); + } + else + { + SetSelectedValue(o); + } + } + } + else + { + Text = _ValueText; + _ValueIndex = SelectedIndex; + } + } + } + + #region SetSelectedDrvValue + + private void SetSelectedDrvValue(object o) + { + if (_ValueMembers == null) + { + SuspendUpdate = true; + + _ValueMembers = new object[Items.Count]; + _ValueIndicees = new int[Items.Count]; + + for (int i = 0; i < Items.Count; i++) + { + DataRowView drv = (DataRowView)Items[i]; + + _ValueMembers[i] = drv.Row[ValueMember]; + _ValueIndicees[i] = i; + } + + Array.Sort(_ValueMembers, _ValueIndicees); + + SuspendUpdate = false; + } + + int n = -1; + + try + { + n = Array.BinarySearch(_ValueMembers, o); + } + catch { } + + if (n >= 0) + { + _ValueIndex = _ValueIndicees[n]; + _ValueText = GetItemText(Items[_ValueIndex]); + } + else + { + Text = _ValueText; + } + } + + #endregion + + #region SetSelectedValue + + private void SetSelectedValue(object o) + { + try + { + SelectedValue = o; + _ValueIndex = SelectedIndex; + + if (SelectedValue != null) + _ValueText = Text; + } + catch + { + Text = _ValueText; + } + } + + #endregion + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CacheDisplayMembers + + /// + /// Informs the control to cache DataRowView + /// ValueMember/DisplayMember information (default is true). + /// + public bool CacheDisplayMembers + { + get { return (_CacheDisplayMembers); } + + set + { + _CacheDisplayMembers = value; + + if (value == false) + { + _ValueMembers = null; + _ValueIndicees = null; + } + } + } + + #endregion + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public virtual bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + CellEditMode _CellEditMode = CellEditMode.Modal; + + /// + /// CellEditMode + /// + public virtual CellEditMode CellEditMode + { + get { return (_CellEditMode); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (_ValueText); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get + { + if (_ValueIndex >= 0) + SelectedIndex = _ValueIndex; + + if (string.IsNullOrEmpty(ValueMember) == false) + return (SelectedValue ?? Text); + + if (string.IsNullOrEmpty(DisplayMember) == false) + return (Text); + + return (this.SelectedValue ?? this.SelectedItem ?? Text); + } + + set { SetValue(GetValue(value), true); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + } + + SetValue(GetValue(_Cell.Value), false); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + eTextFormat tf = eTextFormat.NoClipping | + eTextFormat.WordEllipsis | eTextFormat.NoPrefix; + + if (style.AllowWrap == Tbool.True) + tf |= eTextFormat.WordBreak; + + string s = EditorFormattedValue; + + if (String.IsNullOrEmpty(s) == true) + s = " "; + + Size size = (constraintSize.IsEmpty == true) + ? TextHelper.MeasureText(g, s, style.Font) + : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); + + if (ItemHeight > size.Height) + size.Height = ItemHeight; + + size.Height += Dpi.Height(DefaultMargin.Vertical); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + // If we are caching Display/Value member info, then + // force the ComboBox to now set the correct SelectedValue. + + if (CacheDisplayMembers == true) + { + object o = EditorValue; + } + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + if (IsPopupOpen == true) + IsPopupOpen = false; + + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + if (IsPopupOpen == true) + IsPopupOpen = false; + + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + if (_PanelShown == false) + { + _EditorPanel.Show(); + _EditorPanel.Hide(); + + _PanelShown = true; + } + + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + Focus(); + + switch (e.KeyData) + { + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Space: + case Keys.Up: + case Keys.Down: + return (true); + + case Keys.Enter: + if (DroppedDown == true || IsPopupOpen == true) + return (true); + + if (AutoCompleteMode != AutoCompleteMode.None) + { + if (string.IsNullOrEmpty(DropDownColumns) == true) + { + if (IsAutoSuggestOpen() == true) + return (true); + } + } + break; + } + + return (gridWantsKey == false); + } + + #region IsAutoSuggestOpen + + private bool IsAutoSuggestOpen() + { + _StaticIsOpen = false; + + EnumThreadWindows(GetCurrentThreadId(), EnumThreadWindowCallback, IntPtr.Zero); + + return (_StaticIsOpen); + } + + #region EnumThreadWindowCallback + + private static bool EnumThreadWindowCallback(IntPtr hWnd, IntPtr lParam) + { + if (IsWindowVisible(hWnd) == true) + { + if ((GetClassName(hWnd) == "Auto-Suggest Dropdown")) + { + _StaticIsOpen = true; + + return (false); + } + } + + return true; + } + + #region GetClassName + + private static string GetClassName(IntPtr hRef) + { + StringBuilder lpClassName = new StringBuilder(256); + + GetClassName(hRef, lpClassName, 256); + + return (lpClassName.ToString()); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + if (_CurrentDataManager != null) + _CurrentDataManager.ListChanged -= DataManagerListChanged; + + BindingContext = null; + + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridComboTreeEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridComboTreeEditControl.cs new file mode 100644 index 00000000..b3dc50a2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridComboTreeEditControl.cs @@ -0,0 +1,622 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using DevComponents.AdvTree; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridComboTreeEditControl + /// + [ToolboxItem(false)] + public class GridComboTreeEditControl : ComboTree, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + private bool _PanelShown; + + private string _ValueText; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridComboTreeEditControl + /// + public GridComboTreeEditControl() + { + BindingContext = new BindingContext(); + + ButtonDropDown.Visible = true; + } + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + BindingContext = null; + + base.Dispose(disposing); + } + + #endregion + + #region OnTextChanged + + /// + /// OnTextChanged + /// + /// + protected override void OnTextChanged(EventArgs e) + { + if (IsDisposed == false) + { + if (_Cell != null && _SuspendUpdate == false) + _Cell.EditorValueChanged(this); + } + + base.OnTextChanged(e); + } + + #endregion + + #region OnSelectedIndexChanged + + /// + /// OnSelectedIndexChanged + /// + /// + protected override void OnSelectedIndexChanged(EventArgs e) + { + if (IsDisposed == false) + { + if (_Cell != null && _SuspendUpdate == false) + { + _Cell.EditorValueChanged(this); + + EditorValueChanged = true; + } + } + + base.OnSelectedIndexChanged(e); + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual object GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (""); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (value); + } + + #endregion + + #region SetValue + + private void SetValue(object o) + { + if (o == null) + { + _ValueText = ""; + SelectedIndex = -1; + } + else + { + _ValueText = o.ToString(); + + if (string.IsNullOrEmpty(ValueMember) == false) + { + try + { + SelectedValue = o; + + if (SelectedValue != null) + _ValueText = Text; + } + catch + { + Text = ""; + } + } + else + { + SelectedIndex = -1; + + string s = o.ToString(); + + if (string.IsNullOrEmpty(s) == false) + { + Node node = AdvTree.FindNodeByCellText(s); + + if (node != null) + { + SelectedNode = node; + + if (string.IsNullOrEmpty(SelectedDisplayMember) == false) + _ValueText = GetSelectedDisplayMemberText(node); + } + else + { + Text = s; + } + } + } + } + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (_ValueText); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get + { + if (string.IsNullOrEmpty(ValueMember) == false) + return (SelectedValue); + + return (Text); + } + + set { SetValue(GetValue(value)); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + } + + SetValue(GetValue(_Cell.Value)); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + eTextFormat tf = eTextFormat.NoPadding | eTextFormat.NoClipping | + eTextFormat.WordEllipsis | eTextFormat.NoPrefix; + + if (style.AllowWrap == Tbool.True) + tf |= eTextFormat.WordBreak; + + string s = String.IsNullOrEmpty(Text) ? " " : Text; + + Size size = (constraintSize.IsEmpty == true) + ? TextHelper.MeasureText(g, s, style.Font, new Size(10000, 0), tf) + : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); + + if (size.Height < Dpi.Height22) + size.Height = Dpi.Height22; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + UpdateTreeSize(); + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + if (_PanelShown == false) + { + _EditorPanel.Show(); + _EditorPanel.Hide(); + + _PanelShown = true; + } + + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + Focus(); + + switch (e.KeyData) + { + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Space: + case Keys.Up: + case Keys.Down: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridDateTimeInputEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridDateTimeInputEditControl.cs new file mode 100644 index 00000000..929a18ac --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridDateTimeInputEditControl.cs @@ -0,0 +1,506 @@ +using System; +using System.ComponentModel; +using System.Data; +using System.Data.SqlTypes; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.Editors.DateTimeAdv; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridTextBoxEditControl + /// + [ToolboxItem(false)] + public class GridDateTimeInputEditControl : DateTimeInput, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private DateTime _OrigValue; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridDateTimeInputEditControl + /// + public GridDateTimeInputEditControl() + { + ShowUpDown = true; + } + + #region OnValueChanged + + /// + /// OnValueChanged + /// + /// + protected override void OnValueChanged(EventArgs e) + { + if (_Cell != null && _SuspendUpdate == false) + { + if (_OrigValue.Year != Value.Year || _OrigValue.Month != Value.Month || + _OrigValue.Day != Value.Day || _OrigValue.Hour != Value.Hour || + _OrigValue.Minute != Value.Minute || _OrigValue.Second != Value.Second) + { + _Cell.EditorValueChanged(this); + } + } + + base.OnValueChanged(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual DateTime GetValue(object value) + { + if (value == null || value == Convert.DBNull || + (value is string && String.IsNullOrEmpty((string)value) == true)) + { + return (DateTime.MinValue); + } + + if (value is DateTime) + return (Convert.ToDateTime(value)); + + if (value is SqlDateTime) + { + SqlDateTime sdt = (SqlDateTime)value; + + if (sdt.IsNull == true) + return (DateTime.MinValue); + + return (sdt.Value); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + if (value is string && CurrentCulture != null) + { + DateTime d; + + if (DateTime.TryParse(value.ToString(), GetActiveCulture().DateTimeFormat, + System.Globalization.DateTimeStyles.None, out d)) + { + return (d); + } + } + + return (Convert.ToDateTime(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (Text); + } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Value); } + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(DateTime)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + ForeColor = style.TextColor; + Font = style.Font; + } + + _OrigValue = GetValue(cell.Value); + + Value = _OrigValue; + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + Show(); + Focus(); + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Left: + case Keys.Right: + case Keys.Home: + case Keys.End: + case Keys.Up: + case Keys.Down: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridDateTimePickerEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridDateTimePickerEditControl.cs new file mode 100644 index 00000000..ebf04b51 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridDateTimePickerEditControl.cs @@ -0,0 +1,490 @@ +using System; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridDateTimePickerEditControl + /// + [ToolboxItem(false)] + public class GridDateTimePickerEditControl : DateTimePicker, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + ///GridDateTimePickerEditControl + /// + public GridDateTimePickerEditControl() + { + Format = DateTimePickerFormat.Short; + } + + #region OnValueChanged + + /// + /// OnValueChanged + /// + /// + protected override void OnValueChanged(EventArgs e) + { + if (_Cell != null && _SuspendUpdate == false) + _Cell.EditorValueChanged(this); + + base.OnValueChanged(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual DateTime GetValue(object value) + { + if (value == null || value == Convert.DBNull || + (value is string && String.IsNullOrEmpty((string)value) == true)) + { + return (MinDate); + } + + if (value is DateTime) + return ((DateTime)value); + + if (value is SqlDateTime) + { + SqlDateTime sdt = (SqlDateTime)value; + + if (sdt.IsNull == true) + return (DateTime.MinValue); + + return (sdt.Value); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToDateTime(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Value); } + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(DateTime)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + // Control colors are tied to Windows System Colors + // therefore there is not an easy way to pass along color settings. + + Enabled = (_Cell.ReadOnly == false); + Font = style.Font; + } + + Value = GetValue(cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + // We seem to have to recreate the control to override it's + // internal client area offsetting when previously sized too + // small for the given constraintSize + + //RecreateHandle(); + + Show(); + Focus(); + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Left: + case Keys.Right: + case Keys.Home: + case Keys.End: + case Keys.Up: + case Keys.Down: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridDoubleInputEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridDoubleInputEditControl.cs new file mode 100644 index 00000000..378824bb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridDoubleInputEditControl.cs @@ -0,0 +1,621 @@ +using System; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridDoubleInputEditControl + /// + [ToolboxItem(false)] + public class GridDoubleInputEditControl : DoubleInput, IGridCellEditControl, IGridCellEditorFocus + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridIntegerInputEditControl + /// + public GridDoubleInputEditControl() + { + InitInputControl(false); + } + + #region InitInputControl + + /// + /// InitInputControl + /// + /// + protected void InitInputControl(bool isIntegral) + { + ShowUpDown = true; + + if (isIntegral == true) + DisplayFormat = "G"; + } + + #endregion + + #region OnValueChanged + + /// + /// OnValueChanged + /// + /// + protected override void OnValueChanged(EventArgs e) + { + if (_Cell != null && _SuspendUpdate == false) + _Cell.EditorValueChanged(this); + + base.OnValueChanged(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual double GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (0); + } + + if (value is SqlSingle) + { + SqlSingle sdt = (SqlSingle)value; + + if (sdt.IsNull == true) + return (0); + + return (sdt.Value); + } + + if (value is SqlDouble) + { + SqlDouble sdt = (SqlDouble)value; + + if (sdt.IsNull == true) + return (0); + + return (sdt.Value); + } + + if (value is SqlDecimal) + { + SqlDecimal sdt = (SqlDecimal)value; + + if (sdt.IsNull == true) + return (0); + + return (Convert.ToDouble(sdt.Value)); + } + + if (value is SqlInt64) + { + SqlDecimal sdt = (SqlInt64)value; + + if (sdt.IsNull == true) + return (0); + + return (Convert.ToDouble(sdt.Value)); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToDouble(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Value); } + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(double)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + } + + Value = GetValue(cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + if (FreeTextEntryMode == true) + { + TextBox box = GetFreeTextBox() as TextBox; + + if (box != null) + { + if (selectAll == true) + box.SelectAll(); + } + } + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + CloseDropDown(); + + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + CloseDropDown(); + + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + if ((key & Keys.KeyCode) == Keys.Tab) + { + ApplyFreeTextValue(); + + return (false); + } + + if (IsCalculatorDisplayed == true) + return (true); + + switch (key & Keys.KeyCode) + { + case Keys.Left: + case Keys.Right: + case Keys.Home: + case Keys.End: + case Keys.Up: + case Keys.Down: + return (true); + + case Keys.Enter: + ApplyFreeTextValue(); + return (gridWantsKey == false); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + + #region IGridCellEditorFocus members + + #region FocusEditor + + /// + /// Gives focus to the editor + /// + public void FocusEditor() + { + if (IsEditorFocused == false) + { + if (FreeTextEntryMode == true) + { + TextBox box = GetFreeTextBox() as TextBox; + + if (box != null) + box.Focus(); + } + else + { + Focus(); + } + } + } + + #endregion + + #region IsEditorFocused + + /// + /// Gets whether editor has the focus + /// + public bool IsEditorFocused + { + get + { + if (FreeTextEntryMode == true) + { + TextBox box = GetFreeTextBox() as TextBox; + + if (box != null) + return (box.Focused); + } + + return (Focused); + } + } + + #endregion + + #endregion + } + + /// + /// GridDoubleIntInputEditControl + /// + [ToolboxItem(false)] + public class GridDoubleIntInputEditControl : GridDoubleInputEditControl + { + /// + /// GridDoubleIntInputEditControl + /// + public GridDoubleIntInputEditControl() + { + InitInputControl(true); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridGaugeEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridGaugeEditControl.cs new file mode 100644 index 00000000..9210f6d6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridGaugeEditControl.cs @@ -0,0 +1,548 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.Instrumentation; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridGaugeEditControl + /// + [ToolboxItem(false)] + public class GridGaugeEditControl : GaugeControl, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private string _PointerName = "Pointer1"; + + private StretchBehavior _StretchBehavior = StretchBehavior.Both; + + #endregion + + /// + /// GridGaugeEditControl + /// + public GridGaugeEditControl() + { + PointerValueChanged += OnValueChanged; +#if !TRIAL + LicenseKey = "F962CEC7-CD8F-4911-A9E9-CAB39962FC1F"; +#endif + } + + #region Public properties + + /// + /// PointerName + /// + public string PointerName + { + get { return (_PointerName); } + set { _PointerName = value; } + } + + #endregion + + #region OnValueChanged + + /// + /// Pointer Value changed + /// + /// + /// + protected virtual void OnValueChanged(object sender, PointerChangedEventArgs e) + { + if (_Cell != null && _SuspendUpdate == false) + { + _Cell.Value = e.NewValue; + _Cell.EditorValueChanged(this); + } + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaintBackground + + /// + /// OnPaintBackground + /// + /// + protected override void OnPaintBackground(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual double GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (0); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToDouble(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get { return (Text); } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (GetPointerValue(_PointerName)); } + set { SetPointerValue(_PointerName, GetValue(value), false); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + } + + SetPointerValue(_PointerName, GetValue(_Cell.Value), false); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = constraintSize; + size.Height = size.Width; + + if (size.Width == 0) + size.Width = cell.Size.Width - Dpi.Width2; + + size.Height = Dpi.Height50; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + switch (e.KeyData) + { + case Keys.T: + break; + + case Keys.F: + break; + + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.T: + case Keys.F: + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + + _Cell.SuperGrid.GridCursor = Cursor; + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + PointerValueChanged -= OnValueChanged; + + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridImageEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridImageEditControl.cs new file mode 100644 index 00000000..d21d0553 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridImageEditControl.cs @@ -0,0 +1,900 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridImageEditControl + /// + [ToolboxItem(false)] + public class GridImageEditControl : Control, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private int _ImageIndex = -1; + private ImageList _ImageList; + private string _ImageKey; + + private Image _Image; + private string _ImageLocation; + private Image _LocationImage; + private ImageSizeMode _ImageSizeMode = ImageSizeMode.Normal; + + private Image _StreamImage; + private MemoryStream _ImageMemoryStream; + private byte[] _ImageData; + + private StretchBehavior _StretchBehavior = StretchBehavior.Both; + + #endregion + + #region Public properties + + #region Image + + /// + /// Image + /// + public Image Image + { + get { return (_Image); } + set { _Image = value; } + } + + #endregion + + #region ImageData + + /// + /// ImageData + /// + public byte[] ImageData + { + get { return (_ImageData); } + + set + { + _ImageData = value; + + StreamImage = null; + } + } + + #endregion + + #region ImageIndex + + /// + /// ImageKey + /// + public int ImageIndex + { + get { return (_ImageIndex); } + set { _ImageIndex = value; } + } + + #endregion + + #region ImageKey + + /// + /// ImageKey + /// + public string ImageKey + { + get { return (_ImageKey); } + set { _ImageKey = value; } + } + + #endregion + + #region ImageList + + /// + /// ImageList + /// + public ImageList ImageList + { + get { return (_ImageList); } + set { _ImageList = value; } + } + + #endregion + + #region ImageLocation + + /// + /// ImageLocation + /// + public string ImageLocation + { + get { return (_ImageLocation); } + + set + { + _ImageLocation = value; + + LocationImage = null; + } + } + + #endregion + + #region ImageSizeMode + + /// + /// ImageSizeMode + /// + public ImageSizeMode ImageSizeMode + { + get { return (_ImageSizeMode); } + set { _ImageSizeMode = value; } + } + + #endregion + + #endregion + + #region Private properties + + #region EffectiveImage + + private Image EffectiveImage + { + get + { + if (_Image != null) + return (_Image); + + if (StreamImage != null) + return (StreamImage); + + if (_ImageList != null) + { + _ImageList.TransparentColor = Color.Magenta; + + if ((uint)_ImageIndex < _ImageList.Images.Count) + return (_ImageList.Images[_ImageIndex]); + + if (_ImageKey != null) + return (_ImageList.Images[_ImageKey]); + } + + return (LocationImage); + } + } + + #endregion + + #region ImageMemoryStream + + private MemoryStream ImageMemoryStream + { + get + { + if (_ImageMemoryStream == null) + _ImageMemoryStream = new MemoryStream(); + + return (_ImageMemoryStream); + } + + set + { + if (_ImageMemoryStream != null) + _ImageMemoryStream.Dispose(); + + _ImageMemoryStream = value; + } + } + + #endregion + + #region LocationImage + + private Image LocationImage + { + get { return (_LocationImage); } + + set + { + if (_LocationImage != null) + _LocationImage.Dispose(); + + _LocationImage = value; + + if (string.IsNullOrEmpty(_ImageLocation) == false) + { + using (FileStream fs = new FileStream(_ImageLocation, FileMode.Open)) + _LocationImage = Image.FromStream(fs); + } + } + } + + #endregion + + #region StreamImage + + private Image StreamImage + { + get + { + if (_StreamImage == null) + { + if (_ImageData != null) + { + MemoryStream ms = ImageMemoryStream; + + if (ms != null) + { + ms.SetLength(0); + ms.Write(_ImageData, 0, _ImageData.Length); + + StreamImage = Image.FromStream(ms); + } + } + } + + return (_StreamImage); + } + + set + { + if (_StreamImage != null) + _StreamImage.Dispose(); + + _StreamImage = value; + } + } + + #endregion + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaintBackground + + /// + /// OnPaintBackground + /// + /// + protected override void OnPaintBackground(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + ResetImageInfo(); + + ImageMemoryStream = null; + + base.Dispose(disposing); + } + + #endregion + + #region SetValue + + /// + /// SetValue + /// + /// + public virtual void SetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (panel.IsDesignerHosted == false) + { + ResetImageInfo(); + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + } + else if (value is Image) + { + Image = (Image)value; + } + else if (value is string) + { + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + if (SetImageKey((string)value) == false) + { + int index; + + if (int.TryParse((string)value, out index) == true) + SetImageIndex(index); + else + ImageLocation = (string)value; + } + } + else if (value is byte[]) + { + ImageData = (byte[])value; + } + else + { + int index = Convert.ToInt32(value); + + SetImageIndex(index); + } + } + } + + #region ResetImageInfo + + private void ResetImageInfo() + { + Image = null; + ImageKey = null; + ImageIndex = -1; + ImageLocation = null; + ImageData = null; + } + + #endregion + + #region SetImageKey + + private bool SetImageKey(string key) + { + if (_ImageList != null) + { + if (_ImageList.Images.ContainsKey(key)) + { + _ImageKey = key; + + return (true); + } + } + + return (false); + } + + #endregion + + #region SetImageIndex + + private void SetImageIndex(int index) + { + if (_ImageList != null && index < _ImageList.Images.Count) + ImageIndex = index; + } + + #endregion + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.Value != null) + return (_Cell.Value.ToString()); + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get + { + if (String.IsNullOrEmpty(ImageLocation) == false) + return (ImageLocation); + + if (String.IsNullOrEmpty(_ImageKey) == false) + return (_ImageKey); + + return (_ImageIndex); + } + + set { SetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + Enabled = (_Cell.IsReadOnly == false); + + SetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Image image = EffectiveImage; + + Size size = (image != null) + ? image.Size : Dpi.Size(20, 20); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + Image image = EffectiveImage; + + if (image != null) + { + Rectangle r = _Cell.GetCellEditBounds(this); + + switch (_ImageSizeMode) + { + case ImageSizeMode.Normal: + Rectangle sr = r; + sr.Location = Point.Empty; + + g.DrawImage(image, r, sr, GraphicsUnit.Pixel); + break; + + case ImageSizeMode.CenterImage: + RenderImageCentered(g, image, r); + break; + + case ImageSizeMode.StretchImage: + g.DrawImage(image, r); + break; + + case ImageSizeMode.Zoom: + RenderImageScaled(g, image, r); + break; + } + } + } + + #region RenderImageCentered + + private void RenderImageCentered(Graphics g, Image image, Rectangle r) + { + Rectangle sr = r; + sr.Location = Point.Empty; + + if (image.Width > r.Width) + sr.X += (image.Width - r.Width) / 2; + else + r.X += (r.Width - image.Width) / 2; + + if (image.Height > r.Height) + sr.Y += (image.Height - r.Height) / 2; + else + r.Y += (r.Height - image.Height) / 2; + + g.DrawImage(image, r, sr, GraphicsUnit.Pixel); + } + + #endregion + + #region RenderImageScaled + + private void RenderImageScaled(Graphics g, Image image, Rectangle r) + { + SizeF size = new SizeF(image.Width / image.HorizontalResolution, + image.Height / image.VerticalResolution); + + float scale = Math.Min(r.Width / size.Width, r.Height / size.Height); + + size.Width *= scale; + size.Height *= scale; + + g.DrawImage(image, r.X + (r.Width - size.Width) / 2, + r.Y + (r.Height - size.Height) / 2, + size.Width, size.Height); + } + + #endregion + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + OnKeyDown(e); + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + return (gridWantsKey == false); + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } + + #region ImageSizeMode + + /// + /// ImageSizeMode + /// + public enum ImageSizeMode + { + /// + /// The image is placed in the upper-left + /// corner of the cell and is clipped if needed to fit. + /// + Normal, + + /// + /// The image is stretched or shrunk to fit the cell. + /// + StretchImage, + + /// + /// The image is displayed in the center of the cell if + /// the cell is larger than the image. If the image is larger + /// than the cell, the image is placed in the center of the + /// cell and the outside edges are clipped. + /// + CenterImage, + + /// + /// The size of the image is increased or decreased to fit the + /// cell, maintaining the size ratio. + /// + Zoom + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridIntegerInputEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridIntegerInputEditControl.cs new file mode 100644 index 00000000..319e72d5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridIntegerInputEditControl.cs @@ -0,0 +1,570 @@ +using System; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridIntegerInputEditControl + /// + [ToolboxItem(false)] + public class GridIntegerInputEditControl : IntegerInput, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridIntegerInputEditControl + /// + public GridIntegerInputEditControl() + { + ShowUpDown = true; + } + + #region OnValueChanged + + /// + /// OnValueChanged + /// + /// + protected override void OnValueChanged(EventArgs e) + { + if (_Cell != null && _SuspendUpdate == false) + _Cell.EditorValueChanged(this); + + base.OnValueChanged(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual int GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (0); + } + + if (value is SqlInt16) + { + SqlInt16 sdt = (SqlInt16) value; + + if (sdt.IsNull == true) + return (0); + + return (sdt.Value); + } + + if (value is SqlInt32) + { + SqlInt32 sdt = (SqlInt32)value; + + if (sdt.IsNull == true) + return (0); + + return (sdt.Value); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToInt32(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Value); } + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(int)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + } + + Value = GetValue(cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + if (FreeTextEntryMode == true) + { + TextBox box = GetFreeTextBox() as TextBox; + + if (box != null) + { + if (selectAll == true) + box.SelectAll(); + } + } + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + CloseDropDown(); + + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + CloseDropDown(); + + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + if ((key & Keys.KeyCode) == Keys.Tab) + { + ApplyFreeTextValue(); + + return (false); + } + + if (IsCalculatorDisplayed == true) + return (true); + + switch (key & Keys.KeyCode) + { + case Keys.Left: + case Keys.Right: + case Keys.Home: + case Keys.End: + case Keys.Up: + case Keys.Down: + return (true); + + case Keys.Enter: + ApplyFreeTextValue(); + return (gridWantsKey == false); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + + #region IGridCellEditorFocus members + + #region FocusEditor + + /// + /// Gives focus to the editor + /// + public void FocusEditor() + { + if (IsEditorFocused == false) + { + if (FreeTextEntryMode == true) + { + TextBox box = GetFreeTextBox() as TextBox; + + if (box != null) + box.Focus(); + } + else + { + Focus(); + } + } + } + + #endregion + + #region IsEditorFocused + + /// + /// Gets whether editor has the focus + /// + public bool IsEditorFocused + { + get + { + if (FreeTextEntryMode == true) + { + TextBox box = GetFreeTextBox() as TextBox; + + if (box != null) + return (box.Focused); + } + + return (Focused); + } + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridIpAddressInputEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridIpAddressInputEditControl.cs new file mode 100644 index 00000000..be95cef4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridIpAddressInputEditControl.cs @@ -0,0 +1,463 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.Editors; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridIpAddressInputEditControl + /// + [ToolboxItem(false)] + public class GridIpAddressInputEditControl : IpAddressInput, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + #region OnValueChanged + + /// + /// OnValueChanged + /// + /// + protected override void OnValueChanged(EventArgs e) + { + if (_SuspendUpdate == false) + _Cell.EditorValueChanged(this); + + base.OnValueChanged(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual string GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (""); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToString(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Value); } + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(int)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + } + + Value = GetValue(cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + Show(); + Focus(); + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Left: + case Keys.Right: + case Keys.Home: + case Keys.End: + case Keys.Up: + case Keys.Down: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridLabelEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridLabelEditControl.cs new file mode 100644 index 00000000..0b3aff19 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridLabelEditControl.cs @@ -0,0 +1,513 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridLabelEditControl + /// + [ToolboxItem(false)] + public class GridLabelEditControl : Label, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaintBackground + + /// + /// OnPaintBackground + /// + /// + protected override void OnPaintBackground(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual string GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (""); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToString(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Text); } + set { Text = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + + SetTextAlign(style); + } + + Text = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #region SetTextAlign + + private void SetTextAlign(CellVisualStyle style) + { + switch (style.Alignment) + { + case Alignment.TopLeft: + TextAlign = ContentAlignment.TopLeft; + break; + + case Alignment.TopCenter: + TextAlign = ContentAlignment.TopCenter; + break; + + case Alignment.TopRight: + TextAlign = ContentAlignment.TopRight; + break; + + case Alignment.MiddleLeft: + TextAlign = ContentAlignment.MiddleLeft; + break; + + case Alignment.MiddleCenter: + TextAlign = ContentAlignment.MiddleCenter; + break; + + case Alignment.MiddleRight: + TextAlign = ContentAlignment.MiddleRight; + break; + + case Alignment.BottomLeft: + TextAlign = ContentAlignment.BottomLeft; + break; + + case Alignment.BottomCenter: + TextAlign = ContentAlignment.BottomCenter; + break; + + case Alignment.BottomRight: + TextAlign = ContentAlignment.BottomRight; + break; + } + } + + #endregion + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + return (gridWantsKey == false); + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridLabelXEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridLabelXEditControl.cs new file mode 100644 index 00000000..6cd83b85 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridLabelXEditControl.cs @@ -0,0 +1,555 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridLabelEditControl + /// + [ToolboxItem(false)] + public class GridLabelXEditControl : LabelX, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaint + + /// + /// OnPaint + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + + PaintControl(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual string GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (" "); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + string s = Convert.ToString(value); + + if (string.IsNullOrEmpty(s) == true) + s = " "; + + return (s); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (PlainText); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Text); } + set { Text = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateLayout); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Font = style.Font; + WordWrap = (style.AllowWrap == Tbool.True); + Enabled = (_Cell.IsReadOnly == false); + + SetTextAlign(style); + + ForeColor = style.TextColor; + BackColor = Color.Transparent; + } + + EnableMarkup = !EnableMarkup; + EnableMarkup = !EnableMarkup; + + Text = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #region SetTextAlign + + private void SetTextAlign(CellVisualStyle style) + { + switch (style.Alignment) + { + case Alignment.TopLeft: + TextLineAlignment = StringAlignment.Near; + TextAlignment = StringAlignment.Near; + break; + + case Alignment.TopCenter: + TextLineAlignment = StringAlignment.Near; + TextAlignment = StringAlignment.Center; + break; + + case Alignment.TopRight: + TextLineAlignment = StringAlignment.Near; + TextAlignment = StringAlignment.Far; + break; + + case Alignment.MiddleLeft: + TextLineAlignment = StringAlignment.Center; + TextAlignment = StringAlignment.Near; + break; + + case Alignment.MiddleCenter: + TextLineAlignment = StringAlignment.Center; + TextAlignment = StringAlignment.Center; + break; + + case Alignment.MiddleRight: + TextLineAlignment = StringAlignment.Center; + TextAlignment = StringAlignment.Far; + break; + + case Alignment.BottomLeft: + TextLineAlignment = StringAlignment.Far; + TextAlignment = StringAlignment.Near; + break; + + case Alignment.BottomCenter: + TextLineAlignment = StringAlignment.Far; + TextAlignment = StringAlignment.Center; + break; + + case Alignment.BottomRight: + TextLineAlignment = StringAlignment.Far; + TextAlignment = StringAlignment.Far; + break; + } + } + + #endregion + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size maxSize = MaximumSize; + MaximumSize = constraintSize; + + InvalidateAutoSize(); + + Size size = GetPreferredSize(constraintSize); + + MaximumSize = maxSize; + + if (constraintSize.Width > 0 && EnableMarkup == true) + size.Width = constraintSize.Width; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + // Force a resize (LabelX seems to need this) + + Bounds = new Rectangle(); + + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + return (gridWantsKey == false); + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + + _Cell.SuperGrid.GridCursor = Cursor; + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + + OnClick(EventArgs.Empty); + + Cursor = Cursors.Default; + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridMaskedTextBoxEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridMaskedTextBoxEditControl.cs new file mode 100644 index 00000000..f855b489 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridMaskedTextBoxEditControl.cs @@ -0,0 +1,526 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridMaskedTextBoxEditControl + /// + [ToolboxItem(false)] + public class GridMaskedTextBoxEditControl : MaskedTextBox, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + #region OnTextChanged + + /// + /// OnTextChanged + /// + /// + protected override void OnTextChanged(EventArgs e) + { + if (_Cell != null && _SuspendUpdate == false) + _Cell.EditorValueChanged(this); + + base.OnTextChanged(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual string GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (""); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToString(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return ((PasswordChar == '\0') + ? Text : PasswordText()); + } + } + + #region PasswordText + + private string PasswordText() + { + if (string.IsNullOrEmpty(Mask)) + return (new string(PasswordChar, TextLength)); + + string text = Mask; + + char[] c = new char[text.Length]; + + int n = 0; + + for (int i = 0; i < text.Length; i++) + { + if ("09#L?&CAa".IndexOf(text[i]) >= 0) + c[n++] = PasswordChar; + + else if ("<>|".IndexOf(text[i]) < 0) + c[n++] = text[i]; + } + + return (new string(c)); + } + + #endregion + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Text); } + set { Text = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + ForeColor = style.TextColor; + Font = style.Font; + + SetTextAlign(style); + } + + Text = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #region SetTextAlign + + private void SetTextAlign(CellVisualStyle style) + { + switch (style.Alignment) + { + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + TextAlign = HorizontalAlignment.Left; + break; + + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + TextAlign = HorizontalAlignment.Center; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + TextAlign = HorizontalAlignment.Right; + break; + } + } + + #endregion + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + Show(); + Focus(); + + if (selectAll == true) + SelectAll(); + else + Select(Text.Length, 1); + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + // Let the TextBox handle the following keys + + switch (key & Keys.KeyCode) + { + case Keys.Left: + case Keys.Right: + case Keys.Home: + case Keys.End: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridMicroChartEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridMicroChartEditControl.cs new file mode 100644 index 00000000..8e411101 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridMicroChartEditControl.cs @@ -0,0 +1,488 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridMicroChartEditControl + /// + [ToolboxItem(false)] + public class GridMicroChartEditControl : MicroChart, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.Both; + + #endregion + + /// + /// GridMicroChartEditControl + /// + public GridMicroChartEditControl() + { + FocusCuesEnabled = false; + AnimationEnabled = false; + } + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaint + + /// + /// OnPaint + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + + PaintControl(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual List GetValue(object value) + { + List dps = new List(); + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + string s = value as string; + + if (s != null) + { + string[] values = s.Split(new char[] { ',', ' ', '\t', '|' }); + + foreach (string t in values) + { + double d; + + if (double.TryParse(t, out d) == true) + dps.Add(d); + } + } + + return (dps); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.Value == null) + return (_Cell.NullString); + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (null); } + set { DataPoints = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + Enabled = (_Cell.IsReadOnly == false); + + DataPoints = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + size.Width += Dpi.Width1; + + if (constraintSize.Height == 0) + size.Height = Dpi.Height24; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + OnKeyDown(e); + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + return (gridWantsKey == false); + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridNumericUpDownEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridNumericUpDownEditControl.cs new file mode 100644 index 00000000..89531c1c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridNumericUpDownEditControl.cs @@ -0,0 +1,549 @@ +using System; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridNumericUpDownEditControl + /// + [ToolboxItem(false)] + public class GridNumericUpDownEditControl : NumericUpDown, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridNumericUpDownEditControl + /// + public GridNumericUpDownEditControl() + { + DecimalPlaces = 4; + } + + #region OnTextChanged + + /// + /// OnTextChanged + /// + /// + protected override void OnTextChanged(EventArgs e) + { + if (_Cell != null && _SuspendUpdate == false) + _Cell.EditorValueChanged(this); + + base.OnTextChanged(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual decimal GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (0); + } + + if (value is SqlDecimal) + { + SqlDecimal sdt = (SqlDecimal)value; + + if (sdt.IsNull == true) + return (0); + + return (sdt.Value); + } + + if (value is SqlSingle) + { + SqlSingle sdt = (SqlSingle)value; + + if (sdt.IsNull == true) + return (0); + + return (Convert.ToDecimal(sdt.Value)); + } + + if (value is SqlDouble) + { + SqlDouble sdt = (SqlDouble)value; + + if (sdt.IsNull == true) + return (0); + + return (Convert.ToDecimal(sdt.Value)); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToDecimal(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (Value.ToString()); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get + { + if (string.IsNullOrEmpty(Text) == true) + return (0); + + return (Value); + } + + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(decimal)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + ForeColor = style.TextColor; + Font = style.Font; + + SetTextAlign(style); + } + + Value = GetValue(cell.Value); + Text = Value.ToString(); + + _ValueChanged = false; + } + + #region SetTextAlign + + private void SetTextAlign(CellVisualStyle style) + { + switch (style.Alignment) + { + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + TextAlign = HorizontalAlignment.Left; + break; + + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + TextAlign = HorizontalAlignment.Center; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + TextAlign = HorizontalAlignment.Right; + break; + } + } + + #endregion + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + AutoSize = true; + Size size = GetPreferredSize(constraintSize); + AutoSize = false; + + if (constraintSize.Width > 0) + size.Width = constraintSize.Width; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + if (selectAll == true) + Select(0, 100); + else + Select(Text.Length, 1); + + Show(); + Focus(); + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Left: + case Keys.Right: + case Keys.Home: + case Keys.End: + case Keys.Up: + case Keys.Down: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridProgressBarXEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridProgressBarXEditControl.cs new file mode 100644 index 00000000..56ed9312 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridProgressBarXEditControl.cs @@ -0,0 +1,481 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridProgressBarXEditControl + /// + [ToolboxItem(false)] + public class GridProgressBarXEditControl : ProgressBarX, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.Both; + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaint + + /// + /// OnPaint + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + + PaintControl(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual int GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (0); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToInt32(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get { return (Text); } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Value); } + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + Value = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + if (constraintSize.Height == 0) + size.Height = Dpi.Height23; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + switch (e.KeyCode) + { + case Keys.Add: + Value += Step; + break; + + case Keys.Subtract: + Value -= Step; + break; + + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Add: + case Keys.Subtract: + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridRadialMenuEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridRadialMenuEditControl.cs new file mode 100644 index 00000000..706fbe27 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridRadialMenuEditControl.cs @@ -0,0 +1,575 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridButtonXEditControl + /// + [ToolboxItem(false)] + public class GridRadialMenuEditControl : RadialMenu, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + /// + /// GridRadialMenuEditControl + /// + public GridRadialMenuEditControl() + { + this.SetStyle( + ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.Opaque | + ControlStyles.ResizeRedraw | + DisplayHelp.DoubleBufferFlag | + ControlStyles.SupportsTransparentBackColor, true); + + BackColor = Color.Transparent; + Colors.RadialMenuButtonBackground = Color.Transparent; + + ItemClick += GridRadialMenuEditControl_ItemClick; + } + + #region GridRadialMenuEditControl_ItemClick + + /// + /// RadialMenu item click handler + /// + /// + /// + private void GridRadialMenuEditControl_ItemClick(object sender, EventArgs e) + { + if (_SuspendUpdate == false) + { + RadialMenuItem item = sender as RadialMenuItem; + + if (item != null) + OnGridRadialMenuEditControl_ItemClick(item); + } + } + + #region OnGridRadialMenuEditControl_ItemClick + + /// + /// RadialMenu item click handler + /// + /// + public virtual void OnGridRadialMenuEditControl_ItemClick(RadialMenuItem item) + { + if ((item.Text != null && item.Text.Equals(_Cell.Value) == false) || + (item.Text == null && _Cell.Value != null)) + { + _Cell.Value = item.Text; + + _Cell.EditorValueChanged(this); + } + } + + #endregion + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual string GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (_Cell.NullString); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (value.ToString()); + } + + #endregion + + #region FindItemByText + + /// + /// Finds the RadialMenuItem based upon the given item Text. + /// + /// + /// + /// RadialMenuItem or null + public RadialMenuItem FindItemByText(SubItemsCollection items, string text) + { + if (string.IsNullOrEmpty(text)) + return (null); + + foreach (RadialMenuItem item in items) + { + if (item.Text.Equals(text)) + return (item); + + if (item.SubItems.Count > 0) + { + RadialMenuItem item2 = FindItemByText(item.SubItems, text); + + if (item2 != null) + return (item2); + } + } + + return (null); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.NonModal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get { return (Text); } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Text); } + set { Text = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public virtual bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + + Font = style.Font; + ForeColor = style.TextColor; + } + + Text = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(Size.Empty); + + int n = Dpi.Width(CenterButtonDiameter); + + if (n > size.Width) + size.Width = n; + + n = Dpi.Height(CenterButtonDiameter); + + if (n > size.Height) + size.Height = n; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + OnKeyDown(e); + OnKeyUp(e); + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + Point pt = _Cell.SuperGrid.PointToClient(MousePosition); + + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + if (_Cell != null) + { + Refresh(); + OnMouseLeave(e); + } + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridRatingStarEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridRatingStarEditControl.cs new file mode 100644 index 00000000..a4125a86 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridRatingStarEditControl.cs @@ -0,0 +1,506 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridRatingStarEditControl + /// + [ToolboxItem(false)] + public class GridRatingStarEditControl : RatingStar, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + #region OnRatingChanged + + /// + /// OnRatingChanged + /// + /// + protected override void OnRatingChanged(EventArgs eventArgs) + { + if (_SuspendUpdate == false) + { + _Cell.Value = Rating; + _Cell.EditorValueChanged(this); + } + + base.OnRatingChanged(eventArgs); + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaint + + /// + /// OnPaint + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + + PaintControl(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual int GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (0); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToInt32(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get { return (Text); } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Rating); } + set { Rating = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + } + + Rating = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + GetPreferredSize(constraintSize); + + return (CalcSize); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + switch (e.KeyCode) + { + case Keys.Add: + Rating += 1; + break; + + case Keys.Subtract: + Rating -= 1; + break; + + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Add: + case Keys.Subtract: + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + + OnClick(EventArgs.Empty); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridSliderEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridSliderEditControl.cs new file mode 100644 index 00000000..f1eeec4b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridSliderEditControl.cs @@ -0,0 +1,510 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridSliderEditControl + /// + [ToolboxItem(false)] + public class GridSliderEditControl : Slider, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.HorizontalOnly; + + #endregion + + #region OnValueChanged + + /// + /// OnValueChanged + /// + /// + protected override void OnValueChanged(EventArgs e) + { + if (_SuspendUpdate == false) + { + _Cell.Value = Value; + _Cell.EditorValueChanged(this); + } + + base.OnValueChanged(e); + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region OnPaint + + /// + /// OnPaint + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + + PaintControl(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual int GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (0); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToInt32(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get { return (Text); } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Value); } + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + } + + Value = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + if (constraintSize.Width == 0) + size.Width = Dpi.Width80; + + if (constraintSize.Height == 0) + size.Height = Dpi.Height20; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + switch (e.KeyCode) + { + case Keys.Add: + Value += Step; + break; + + case Keys.Subtract: + Value -= Step; + break; + + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Add: + case Keys.Subtract: + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridSwitchButtonEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridSwitchButtonEditControl.cs new file mode 100644 index 00000000..dfbb1c9b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridSwitchButtonEditControl.cs @@ -0,0 +1,593 @@ +using System; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridSwitchButtonEditControl + /// + [ToolboxItem(false)] + public class GridSwitchButtonEditControl : SwitchButton, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private object _OnValue; + private object _OffValue; + + private StretchBehavior _StretchBehavior = StretchBehavior.Both; + + #endregion + + /// + /// GridSwitchButtonEditControl + /// + public GridSwitchButtonEditControl() + { + FocusCuesEnabled = false; + Style = eDotNetBarStyle.StyleManagerControlled; + } + + #region Public properties + + #region OnValue + + /// + /// OnValue + /// + public object OnValue + { + get { return (_OnValue); } + set { _OnValue = value; } + } + + #endregion + + #region OffValue + + /// + /// OffValue + /// + public object OffValue + { + get { return (_OffValue); } + set { _OffValue = value; } + } + + #endregion + + #endregion + + #region OnValueChanged + + /// + /// OnValueChanged + /// + /// + protected override void OnValueChanged(EventArgs e) + { + if (_SuspendUpdate == false) + { + _Cell.UpdateCellValue(this); + _Cell.EditorValueChanged(this); + } + + base.OnValueChanged(e); + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_Cell != null && _SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + /// + public virtual bool GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (false); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + Type type = value.GetType(); + + if (_OnValue != null) + { + if (value.Equals(_OnValue)) + return (true); + } + + if (_OffValue != null) + { + if (value.Equals(_OffValue)) + return (false); + } + + if (type == typeof(bool)) + return ((bool)value); + + if (type == typeof(string)) + { + string s = ((string)value).ToLower(); + + if (s.Equals("true") || s.Equals("yes") || s.Equals("1")) + return (true); + + if (s.Equals("false") || s.Equals("no") || s.Equals("0")) + return (false); + } + else if (type == typeof(SqlBoolean)) + { + SqlBoolean sb = (SqlBoolean)value; + + if (sb.IsNull == true) + return (false); + + return (sb.IsTrue); + } + else if (type == typeof(char)) + { + char c = (char)value; + + switch (Char.ToLower(c)) + { + case 't': + case 'y': + case '1': + return (true); + + case 'f': + case 'n': + case '0': + return (false); + } + } + else + { + int n = Convert.ToInt32(value); + + return (n == 0 ? false : true); + } + + throw new Exception("Invalid checkBox cell value (" + value + ")."); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.InPlace); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null) + { + if (_Cell.Value == null || _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (_Cell.Value.ToString()); + } + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Value); } + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(bool)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.IsReadOnly == false); + Font = style.Font; + ForeColor = style.TextColor; + } + + Value = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + size.Width += Dpi.Width4; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + OnKeyDown(e); + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + OnMouseEnter(e); + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + + CancelAnimation(); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridTextBoxDropDownEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridTextBoxDropDownEditControl.cs new file mode 100644 index 00000000..29df828e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridTextBoxDropDownEditControl.cs @@ -0,0 +1,577 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridTextBoxDropDownControl + /// + [ToolboxItem(false)] + public class GridTextBoxDropDownEditControl : TextBoxDropDown, IGridCellEditControl + { + #region DllImports / delegates + + private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp); + + [DllImport("user32.dll")] + private static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp); + + [DllImport("user32.dll")] + private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen); + + [DllImport("kernel32.dll")] + private static extern int GetCurrentThreadId(); + + #endregion + + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + private bool _AutoSuggestDropdownOpen; + + #endregion + + /// + /// GridTextBoxDropDownEditControl + /// + public GridTextBoxDropDownEditControl() + { + BackgroundStyle.Class = "TextBoxBorder"; + Style = eDotNetBarStyle.StyleManagerControlled; + } + + #region OnTextChanged + + /// + /// OnTextChanged + /// + /// + protected override void OnTextChanged(EventArgs e) + { + if (_SuspendUpdate == false) + _Cell.EditorValueChanged(this); + + base.OnTextChanged(e); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual string GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (""); + } + + if (_Cell.IsValueExpression == true) + value = _Cell.GetExpValue((string)value); + + return (Convert.ToString(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return (Text); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Text); } + set { Text = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + ForeColor = style.TextColor; + Font = style.Font; + + SetTextAlign(style); + } + + Text = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #region SetTextAlign + + private void SetTextAlign(CellVisualStyle style) + { + switch (style.Alignment) + { + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + TextAlign = HorizontalAlignment.Left; + break; + + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + TextAlign = HorizontalAlignment.Center; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + TextAlign = HorizontalAlignment.Right; + break; + } + } + + #endregion + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + Size size = GetPreferredSize(constraintSize); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + Show(); + Focus(); + + if (selectAll == true) + SelectAll(); + else + Select(Text.Length, 1); + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + CloseDropDown(); + + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + CloseDropDown(); + + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + // Let the TextBox handle the following keys + + switch (key & Keys.KeyCode) + { + case Keys.Left: + case Keys.Right: + case Keys.Home: + case Keys.End: + return (true); + + case Keys.Down: + case Keys.Up: + if (IsAutoSuggestDropdownOpen()) + return (true); + + return (gridWantsKey == false); + + default: + return (gridWantsKey == false); + } + } + + #region IsAutoSuggestDropdownOpen + + private bool IsAutoSuggestDropdownOpen() + { + _AutoSuggestDropdownOpen = false; + + if (AutoCompleteMode == AutoCompleteMode.Suggest || + AutoCompleteMode == AutoCompleteMode.SuggestAppend) + { + EnumThreadWndProc callback = CheckWindow; + EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero); + } + + return (_AutoSuggestDropdownOpen); + } + + #region CheckWindow + + private bool CheckWindow(IntPtr hWnd, IntPtr lp) + { + StringBuilder sb = new StringBuilder(260); + GetClassName(hWnd, sb, sb.Capacity); + + if (sb.ToString() == "Auto-Suggest Dropdown") + { + _AutoSuggestDropdownOpen = IsWindowVisible(hWnd); + + return (false); + } + + return (true); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridTextBoxXEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridTextBoxXEditControl.cs new file mode 100644 index 00000000..2cf15763 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridTextBoxXEditControl.cs @@ -0,0 +1,587 @@ +using System; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridTextBoxEditControl + /// + [ToolboxItem(false)] + public class GridTextBoxXEditControl : TextBoxX, IGridCellEditControl + { + /// + /// GridTextBoxXEditControl + /// + public GridTextBoxXEditControl() + { + Multiline = true; + } + + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.None; + + #endregion + + #region OnTextChanged + + /// + /// OnTextChanged + /// + /// + protected override void OnTextChanged(EventArgs e) + { + if (_SuspendUpdate == false) + _Cell.EditorValueChanged(this); + + base.OnTextChanged(e); + } + + #endregion + + #region OnPaintBackground + + /// + /// OnPaintBackground + /// + /// + protected override void OnPaintBackground(PaintEventArgs e) + { + _Cell.PaintEditorBackground(e, this); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual string GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (""); + } + + if (value is SqlString) + { + SqlString sdt = (SqlString) value; + + if (sdt.IsNull == true) + return (""); + + return (sdt.Value); + } + + return (Convert.ToString(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.Modal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get + { + if (_Cell != null && _Cell.IsValueNull == true) + return (_Cell.NullString); + + return ((PasswordChar == '\0') + ? Text : new string(PasswordChar, TextLength)); + } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (Text); } + set { Text = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get + { + return ((Multiline == true) + ? StretchBehavior.VerticalOnly : StretchBehavior.None ); + } + + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateLayout); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + { + Enabled = (_Cell.ReadOnly == false); + WordWrap = (style.AllowWrap == Tbool.True); + ForeColor = style.TextColor; + Font = style.Font; + Multiline = WordWrap; + } + + Text = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #region SetTextAlign + + private void SetTextAlign(CellVisualStyle style) + { + switch (style.Alignment) + { + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + TextAlign = HorizontalAlignment.Left; + break; + + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + TextAlign = HorizontalAlignment.Center; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + TextAlign = HorizontalAlignment.Right; + break; + } + } + + #endregion + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + eTextFormat tf = style.GetTextFormatFlags(); + + string s = String.IsNullOrEmpty(Text) ? " " : Text; + + SetTextAlign(style); + + Size size = (constraintSize.IsEmpty == true) + ? TextHelper.MeasureText(g, s, style.Font, new Size(10000, 0), tf) + : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + if (selectAll == true) + SelectAll(); + else + Select(Text.Length, 1); + + Show(); + Focus(); + + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + // Let the TextBox handle the following keys + + if (Multiline == true) + { + switch (key & Keys.KeyCode) + { + case Keys.Up: + if (GetLineFromCharIndex(SelectionStart) != 0) + return (true); + break; + + case Keys.Down: + int lastLine = GetLineFromCharIndex(int.MaxValue); + + if (GetLineFromCharIndex(SelectionStart) < lastLine) + return (true); + break; + + case Keys.Enter: + if (AcceptsReturn == true) + return (true); + break; + } + } + + switch (key & Keys.KeyCode) + { + case Keys.Left: + case Keys.Right: + case Keys.Home: + case Keys.End: + return (true); + + case Keys.Tab: + if (AcceptsTab == true) + return (true); + break; + } + + return (gridWantsKey == false); + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + } + + #endregion + + #endregion + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + try + { + base.Dispose(disposing); + } + catch + { + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridTrackBarEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridTrackBarEditControl.cs new file mode 100644 index 00000000..219397cd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/GridTrackBarEditControl.cs @@ -0,0 +1,500 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridButtXEditControl + /// + [ToolboxItem(false)] + public class GridTrackBarEditControl : TrackBar, IGridCellEditControl + { + #region Private variables + + private GridCell _Cell; + private EditorPanel _EditorPanel; + private Bitmap _EditorCellBitmap; + + private bool _ValueChanged; + private bool _SuspendUpdate; + + private StretchBehavior _StretchBehavior = StretchBehavior.Both; + + #endregion + + /// + /// GridTrackBarEditControl + /// + public GridTrackBarEditControl() + { + AutoSize = false; + Maximum = 100; + TickFrequency = 10; + } + + #region OnValueChanged + + /// + /// OnValueChanged + /// + /// + protected override void OnValueChanged(EventArgs e) + { + if (_Cell != null && _SuspendUpdate == false) + { + _Cell.Value = Value; + _Cell.EditorValueChanged(this); + } + + base.OnValueChanged(e); + } + + #endregion + + #region OnInvalidated + + /// + /// OnInvalidated + /// + /// + protected override void OnInvalidated(InvalidateEventArgs e) + { + base.OnInvalidated(e); + + if (_SuspendUpdate == false) + _Cell.InvalidateRender(); + } + + #endregion + + #region GetValue + + /// + /// GetValue + /// + /// + /// + public virtual int GetValue(object value) + { + GridPanel panel = _Cell.GridPanel; + + if (value == null || + (panel.NullValue == NullValue.DBNull && value == DBNull.Value)) + { + return (0); + } + + return (Convert.ToInt32(value)); + } + + #endregion + + #region IGridCellEditControl Members + + #region Public properties + + #region CanInterrupt + + /// + /// CanInterrupt + /// + public bool CanInterrupt + { + get { return (true); } + } + + #endregion + + #region CellEditMode + + /// + /// CellEditMode + /// + public CellEditMode CellEditMode + { + get { return (CellEditMode.NonModal); } + } + + #endregion + + #region EditorCell + + /// + /// EditorCell + /// + public GridCell EditorCell + { + get { return (_Cell); } + set { _Cell = value; } + } + + #endregion + + #region EditorCellBitmap + + /// + /// EditorCellBitmap + /// + public Bitmap EditorCellBitmap + { + get { return (_EditorCellBitmap); } + + set + { + if (_EditorCellBitmap != null) + _EditorCellBitmap.Dispose(); + + _EditorCellBitmap = value; + } + } + + #endregion + + #region EditorFormattedValue + + /// + /// EditorFormattedValue + /// + public virtual string EditorFormattedValue + { + get { return (Text); } + } + + #endregion + + #region EditorPanel + + /// + /// EditorPanel + /// + public EditorPanel EditorPanel + { + get { return (_EditorPanel); } + set { _EditorPanel = value; } + } + + #endregion + + #region EditorValue + + /// + /// EditorValue + /// + public virtual object EditorValue + { + get { return (_Cell.Value); } + set { Value = GetValue(value); } + } + + #endregion + + #region EditorValueChanged + + /// + /// EditorValueChanged + /// + public virtual bool EditorValueChanged + { + get { return (_ValueChanged); } + + set + { + if (_ValueChanged != value) + { + _ValueChanged = value; + + if (value == true) + _Cell.SetEditorDirty(this); + } + } + } + + #endregion + + #region EditorValueType + + /// + /// EditorValueType + /// + public virtual Type EditorValueType + { + get { return (typeof(string)); } + } + + #endregion + + #region StretchBehavior + + /// + /// StretchBehavior + /// + public virtual StretchBehavior StretchBehavior + { + get { return (_StretchBehavior); } + set { _StretchBehavior = value; } + } + + #endregion + + #region SuspendUpdate + + /// + /// SuspendUpdate + /// + public bool SuspendUpdate + { + get { return (_SuspendUpdate); } + set { _SuspendUpdate = value; } + } + + #endregion + + #region ValueChangeBehavior + + /// + /// ValueChangeBehavior + /// + public virtual ValueChangeBehavior ValueChangeBehavior + { + get { return (ValueChangeBehavior.InvalidateRender); } + } + + #endregion + + #endregion + + #region InitializeContext + + /// + /// InitializeContext + /// + /// + /// + public virtual void InitializeContext(GridCell cell, CellVisualStyle style) + { + _Cell = cell; + + if (style != null) + Enabled = (_Cell.IsReadOnly == false); + + Value = GetValue(_Cell.Value); + + _ValueChanged = false; + } + + #endregion + + #region GetProposedSize + + /// + /// GetProposedSize + /// + /// + /// + /// + /// + /// + public virtual Size GetProposedSize(Graphics g, + GridCell cell, CellVisualStyle style, Size constraintSize) + { + _SuspendUpdate = true; + + Rectangle r = Bounds; + + AutoSize = true; + Size size = GetPreferredSize(constraintSize); + AutoSize = false; + + Bounds = r; + + _SuspendUpdate = false; + + return (size); + } + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// BeginEdit + /// + /// + /// + public virtual bool BeginEdit(bool selectAll) + { + return (false); + } + + #endregion + + #region EndEdit + + /// + /// EndEdit + /// + /// + public virtual bool EndEdit() + { + return (false); + } + + #endregion + + #region CancelEdit + + /// + /// CancelEdit + /// + /// + public virtual bool CancelEdit() + { + return (false); + } + + #endregion + + #endregion + + #region CellRender + + /// + /// CellRender + /// + /// + public virtual void CellRender(Graphics g) + { + _Cell.CellRender(this, g); + } + + #endregion + + #region Keyboard support + + #region CellKeyDown + + /// + /// CellKeyDown + /// + public virtual void CellKeyDown(KeyEventArgs e) + { + switch (e.KeyCode) + { + case Keys.Add: + Value += SmallChange; + break; + + case Keys.Subtract: + Value -= SmallChange; + break; + + default: + OnKeyDown(e); + break; + } + } + + #endregion + + #region WantsInputKey + + /// + /// WantsInputKey + /// + /// + /// + /// + public virtual bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key & Keys.KeyCode) + { + case Keys.Add: + case Keys.Subtract: + case Keys.Space: + return (true); + + default: + return (gridWantsKey == false); + } + } + + #endregion + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// OnCellMouseMove + /// + /// + public virtual void OnCellMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + #endregion + + #region OnCellMouseEnter + + /// + /// OnCellMouseEnter + /// + /// + public virtual void OnCellMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnCellMouseLeave + + /// + /// OnCellMouseLeave + /// + /// + public virtual void OnCellMouseLeave(EventArgs e) + { + OnMouseLeave(e); + } + + #endregion + + #region OnCellMouseUp + + /// + /// OnCellMouseUp + /// + /// + public virtual void OnCellMouseUp(MouseEventArgs e) + { + OnMouseUp(e); + } + + #endregion + + #region OnCellMouseDown + + /// + /// OnCellMouseDown + /// + /// + public virtual void OnCellMouseDown(MouseEventArgs e) + { + OnMouseDown(e); + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/IGridCellEditControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/IGridCellEditControl.cs new file mode 100644 index 00000000..e0818ff7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellEditors/IGridCellEditControl.cs @@ -0,0 +1,466 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// IGridCellEditControl + /// + public interface IGridCellEditControl + { + #region Properties + + #region CanInterrupt + + /// + /// Specifies whether the Grid can automatically interrupt the + /// current NonModal cell edit operation when the mouse leaves the cell. + /// + /// This is utilized in cases, such as the ButtonX editor, where multilevel + /// controls may be involved. In the ButtonX case this specifically enables + /// the mouse to to leave the main cell window and not be interrupted by the + /// grid until the current operation is complete by the editor itself. + /// + /// + bool CanInterrupt { get; } + + #endregion + + #region CellEditMode + + /// + /// Specifies the cell editor activation mode. There are three modes + /// available for choice, and their usage depends upon the desired + /// editor presentation, as well as how well the given underlying + /// control interacts with the grid control. + /// + /// The modes are as follows: + /// + /// InPlace: + /// Edit operations occur 'in place', always live, always + /// in a state of interaction with the user. The CheckBoxEx, + /// and ButtonX editors are examples of this. + /// + /// Modal: + /// Edit operations will be performed as a modal, widowed edit + /// controlled via calls to BeginEdit, EndEdit, and CancelEdit. + /// The TextBoxEx and IntegerInput editors are examples of this. + /// + /// NonModal: + /// Edit operation will be performed as a nonNodal, windowed edit + /// automatically invoked upon entry to the cell. The ButtonEx, + /// BubbleBar, and TrackBar are examples of this. + /// + /// + CellEditMode CellEditMode { get; } + + #endregion + + #region EditorCell + + /// + /// Specifies the editor's current associated grid cell + /// + GridCell EditorCell { get; set; } + + #endregion + + #region EditorCellBitmap + + /// + /// Called to get or set the editor's + /// associated cell bitmap (internal use only) + /// + Bitmap EditorCellBitmap { get; set; } + + #endregion + + #region EditorFormattedValue + + /// + /// Called to get the formatted editor value + /// + string EditorFormattedValue { get; } + + #endregion + + #region EditorPanel + + /// + /// Called to get or set the editor's + /// associated cell panel (internal use only) + /// + EditorPanel EditorPanel { get; set; } + + #endregion + + #region EditorValue + + /// + /// Called to get or set the editor value + /// + object EditorValue { get; set;} + + #endregion + + #region EditorValueChanged + + /// + /// Called to get or set whether the editor value has changed + /// + bool EditorValueChanged { get; set;} + + #endregion + + #region EditorValueType + + /// + /// Called to get the editor's default value data type + /// + Type EditorValueType { get; } + + #endregion + + #region StretchBehavior + + /// + /// Called to get the editor's desired 'stretch' behavior. + /// + /// The StretchBehavior defines whether the editor wants to + /// automatically have it's size stretched to fill the given cell. + /// + /// Editors, such as ButtonX, want to fill the cell horizontally and + /// vertically, whereas other editors, such as the Slider, may only + /// want to stretch horizontally (or potentially not at all). + /// + StretchBehavior StretchBehavior { get; } + + #endregion + + #region SuspendUpdate + + /// + /// Called to get or set whether updates to the grid + /// state is suspended + /// + bool SuspendUpdate { get; set; } + + #endregion + + #region ValueChangeBehavior + + /// + /// Called to get the behavior + /// needed when a value changes in the editor. + /// + /// For instance, CheckBoxEx value changes result in only requiring + /// the cell to be redisplayed with the new state, whereas editors such + /// as the TextBoxEx editor, may result in a new layout when the text changes. + /// + /// + ValueChangeBehavior ValueChangeBehavior { get; } + + #endregion + + #endregion + + #region CellRender + + /// + /// Called to initiate the actual rendering of the editor + /// value into the grid cell. In most cases this can be (and is) + /// handled by a simple call to EditorCell.CellRender(this, graphics). + /// If additional rendering is required by the editor, then the editor + /// can completely render the cell contents itself (and never even call + /// Editor.CellRender) or optionally perform additional rendering before + /// or after the default cell rendering. + /// + /// + void CellRender(Graphics g); + + #endregion + + #region CellKeyDown + + /// + /// Called when a KeyDown occurs and the + /// CellEditMode is InPlace (otherwise the key event is + /// automatically directed straight to the editor control). + /// + /// + void CellKeyDown(KeyEventArgs e); + + #endregion + + #region Edit support + + #region BeginEdit + + /// + /// Called when a Modal cell edit is about to be initiated. + /// + ///Signifies whether to select all editable content + ///true to cancel the edit operation + bool BeginEdit(bool selectAll); + + #endregion + + #region EndEdit + + /// + /// Called when the edit operation is about to end. + /// + ///true to cancel the operation. + bool EndEdit(); + + #endregion + + #region CancelEdit + + /// + /// Called when the edit operation is being cancelled. + /// + ///true to cancel the operation. + bool CancelEdit(); + + #endregion + + #endregion + + #region GetProposedSize + + /// + /// Called to retrieve the editors proposed size + /// for the given cell, using the provided effective + /// style and size constraint. + /// + ///Graphics object + ///Associated grid cell + ///Cell's effective style + ///The constraining cell size + /// + Size GetProposedSize(Graphics g, GridCell cell, CellVisualStyle style, Size constraintSize); + + #endregion + + #region InitializeContext + + /// + /// Called to initialize the editor's context + /// environment (value, properties, style, etc) + /// + /// + /// + void InitializeContext(GridCell cell, CellVisualStyle style); + + #endregion + + #region Mouse support + + #region OnCellMouseMove + + /// + /// Called when a MouseMove event occurs and the + /// CellEditMode is InPlace (otherwise the event is + /// automatically directed straight to the editor control). + /// + /// + void OnCellMouseMove(MouseEventArgs e); + + #endregion + + #region OnCellMouseEnter + + /// + /// Called when a MouseEnter event occurs and the + /// CellEditMode is InPlace (otherwise the event is + /// automatically directed straight to the editor control). + /// + /// + void OnCellMouseEnter(EventArgs e); + + #endregion + + #region OnCellMouseLeave + + /// + /// Called when a MouseLeave event occurs and the + /// CellEditMode is InPlace (otherwise the event is + /// automatically directed straight to the editor control). + /// + /// + void OnCellMouseLeave(EventArgs e); + + #endregion + + #region OnCellMouseUp + + /// + /// Called when a MouseUp event occurs and the + /// CellEditMode is InPlace (otherwise the event is + /// automatically directed straight to the editor control). + /// + /// + void OnCellMouseUp(MouseEventArgs e); + + #endregion + + #region OnCellMouseDown + + /// + /// Called when a MouseDown event occurs and the + /// CellEditMode is InPlace (otherwise the event is + /// automatically directed straight to the editor control). + /// + /// + void OnCellMouseDown(MouseEventArgs e); + + #endregion + + #endregion + + #region WantsInputKey + + /// + /// Called to determine if the editor wants to process and + /// handle the given key + /// + ///Key in question + ///Whether the grid, by default, wants the key + ///true is the control wants the key + bool WantsInputKey(Keys key, bool gridWantsKey); + + #endregion + } + + #region IGridCellConvertTo + + /// + ///IGridCellConvertTo + /// + public interface IGridCellConvertTo + { + /// + ///TryConvertTo + /// + ///Value to convert + ///Data type to convert to + ///Converted value + /// + bool TryConvertTo(object value, Type dataType, out object result); + } + + #endregion + + #region IGridCellEditorFocus + + /// + ///IGridCellEditorFocus + /// + public interface IGridCellEditorFocus + { + /// + ///Indicates whether the editor has the input focus + /// + /// + bool IsEditorFocused { get; } + + /// + ///Gives the editor the input focus + /// + void FocusEditor(); + } + + #endregion + + #region enums + + #region CellEditMode + + /// + /// Specifies the mode of cell editor activation + /// + public enum CellEditMode + { + /// + /// Edit operation will be performed as a modal, widowed + /// edit controlled via BeginEdit, EndEdit, and CancelEdit. + /// + Modal, + + /// + /// Edit operation will be performed as a nonNodal, windowed + /// edit automatically invoked upon entry to the cell. + /// + NonModal, + + /// + /// Edit operation will be performed in-place, as a non-windowed + /// edit automatically invoked upon entry to the cell. + /// + InPlace, + } + + #endregion + + #region StretchBehavior + + /// + /// Defines how the editor is stretched to + /// have it's size fill the given cell. + /// + public enum StretchBehavior + { + /// + /// No stretching to fill the cell + /// + None, + + /// + /// Auto stretch horizontally only + /// + HorizontalOnly, + + /// + /// Auto stretch vertically only + /// + VerticalOnly, + + /// + /// Auto stretch both horizontally and vertically + /// + Both, + } + + #endregion + + #region ValueChangeBehavior + + /// + /// Defines how the grid should respond to + /// editor content / value changes + /// + public enum ValueChangeBehavior + { + /// + /// No action needed + /// + None, + + /// + /// Grid layout needs invalidated + /// + InvalidateLayout, + + /// + /// Cell needs rendered + /// + InvalidateRender, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellInfoWindow.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellInfoWindow.Designer.cs new file mode 100644 index 00000000..95e409c5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellInfoWindow.Designer.cs @@ -0,0 +1,43 @@ +namespace DevComponents.DotNetBar.SuperGrid +{ + partial class CellInfoWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // CellInfoWindow + // + this.ClientSize = new System.Drawing.Size(16, 16); + this.Name = "CellInfoWindow"; + this.ResumeLayout(false); + + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellInfoWindow.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellInfoWindow.cs new file mode 100644 index 00000000..119ee7e3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellInfoWindow.cs @@ -0,0 +1,154 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.SuperGrid +{ + public partial class CellInfoWindow : FloatWindow + { + #region Private variables + + private SuperGridControl _SuperGrid; + private GridCell _Cell; + + private System.Windows.Forms.ToolTip _ToolTip; + + #endregion + + public CellInfoWindow(SuperGridControl superGrid, GridCell cell) + { + InitializeComponent(); + + Image image = cell.GetInfoImage(); + + if (image != null) + Size = image.Size; + + TopLevel = false; + + _SuperGrid = superGrid; + _Cell = cell; + + _ToolTip = new System.Windows.Forms.ToolTip(); + + using (GraphicsPath path = GetImageGraphicsPath()) + Region = new Region(path); + + Paint += CellInfoWindowPaint; + MouseClick += CellInfoWindowMouseClick; + MouseDoubleClick += CellInfoWindowMouseDoubleClick; + + MouseEnter += CellInfoWindowMouseEnter; + MouseLeave += CellInfoWindowMouseLeave; + } + + #region Public properties + + #region ToolTip + + public System.Windows.Forms.ToolTip ToolTip + { + get { return (_ToolTip); } + internal set { _ToolTip = value; } + } + + #endregion + + #endregion + + #region CellInfoWindowMouseEnter + + void CellInfoWindowMouseEnter(object sender, EventArgs e) + { + if (_SuperGrid.DoCellInfoEnterEvent(_Cell, this, _ToolTip, MousePosition) == false) + _ToolTip.SetToolTip(this, _Cell.InfoText); + else + _ToolTip.SetToolTip(this, ""); + } + + #endregion + + #region CellInfoWindowMouseLeave + + void CellInfoWindowMouseLeave(object sender, EventArgs e) + { + _SuperGrid.DoCellInfoLeaveEvent(_Cell, this, _ToolTip); + } + + #endregion + + #region GetImageGraphicsPath + + private GraphicsPath GetImageGraphicsPath() + { + Bitmap bitmap = new Bitmap(_Cell.GetInfoImage()); + GraphicsPath graphicsPath = new GraphicsPath(); + + Color colorTransparent = bitmap.GetPixel(0, 0); + + for (int row = 0; row < bitmap.Height; row++) + { + for (int col = 0; col < bitmap.Width; col++) + { + if (bitmap.GetPixel(col, row) != colorTransparent) + { + int colOpaquePixel = col; + int colNext; + + for (colNext = colOpaquePixel; colNext < bitmap.Width; colNext++) + { + if (bitmap.GetPixel(colNext, row) == colorTransparent) + break; + } + + graphicsPath.AddRectangle(new Rectangle(colOpaquePixel, + row, colNext - colOpaquePixel, 1)); + + col = colNext; + } + } + } + + return (graphicsPath); + } + + #endregion + + #region CellInfoWindowPaint + + void CellInfoWindowPaint(object sender, PaintEventArgs e) + { + Image image = _Cell.GetInfoImage(); + + if (image != null) + { + Rectangle r = Bounds; + r.Location = Point.Empty; + + e.Graphics.DrawImageUnscaledAndClipped(image, r); + } + } + + #endregion + + #region CellInfoWindowMouseClick + + void CellInfoWindowMouseClick(object sender, MouseEventArgs e) + { + _SuperGrid.DoCellInfoClickEvent(_Cell, e); + } + + #endregion + + #region CellInfoWindowMouseDoubleClick + + void CellInfoWindowMouseDoubleClick(object sender, MouseEventArgs e) + { + _SuperGrid.DoCellInfoDoubleClickEvent(_Cell, e); + } + + #endregion + } +} + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellInfoWindow.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellInfoWindow.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CellInfoWindow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CheckDisplay.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CheckDisplay.cs new file mode 100644 index 00000000..474b7030 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/CheckDisplay.cs @@ -0,0 +1,37 @@ +using System.Drawing; +using System.Windows.Forms; +using System.Windows.Forms.VisualStyles; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// CheckDisplay + /// + static public class CheckDisplay + { + /// + /// RenderCheckbox + /// + /// + /// + /// + /// + static public void RenderCheckbox( + Graphics g, Rectangle bounds, CheckBoxState cstate, ButtonState bstate) + { + Size csize = CheckBoxRenderer.GetGlyphSize(g, cstate); + + if (Application.RenderWithVisualStyles == true) + { + Point pt = bounds.Location; + pt.Y += (bounds.Height - csize.Height) / 2; + + CheckBoxRenderer.DrawCheckBox(g, pt, cstate); + } + else + { + ControlPaint.DrawCheckBox(g, bounds, bstate); + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/DataBinder.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/DataBinder.cs new file mode 100644 index 00000000..fc1a1c1c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/DataBinder.cs @@ -0,0 +1,3203 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Data.SqlTypes; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// DataBinding helper class + /// + public class DataBinder : IDisposable + { + #region Private variables + + private readonly GridPanel _Panel; + + private CurrencyManager _CurrencyManager; + private PropertyDescriptorCollection _Pdc; + private DataView _DataView; + private DataRow _TempDataRow; + + private BindingSource _BindingSource; + private BindingSource _BaseBindingSource; + private object _BaseDataSource; + private string _BaseDataMember; + + private bool _ConnectionInProgress; + private bool _NotificationInProgress; + private bool _UpdateInProgress; + private bool _UpdatePosInProgress; + + private ushort _DataResetCount; + private ushort _BeginUpdateCount; + + private object _LastDataItemAdded; + + #endregion + + /// + /// DataBinding + /// + /// + internal DataBinder(GridPanel panel) + { + _Panel = panel; + } + + #region Internal properties + + #region BaseDataMember + + internal string BaseDataMember + { + get { return (_BaseDataMember); } + set { _BaseDataMember = value; } + } + + #endregion + + #region BaseDataSource + + internal object BaseDataSource + { + get { return (_BaseDataSource); } + set { _BaseDataSource = value; } + } + + #endregion + + #region CanDeleteRow + + internal bool CanDeleteRow + { + get + { + if (CurrencyManager != null) + { + if (_DataView != null) + return (_DataView.AllowDelete); + } + + return (true); + } + } + + #endregion + + #region CanInsertRow + + internal bool CanInsertRow + { + get + { + if (CurrencyManager != null) + { + if (_DataView != null) + return (_DataView.AllowNew); + } + + return (true); + } + } + + #endregion + + #region ConnectionInProgress + + internal bool ConnectionInProgress + { + get { return (_ConnectionInProgress); } + set { _ConnectionInProgress = value; } + } + + #endregion + + #region CurrencyManager + + internal CurrencyManager CurrencyManager + { + get { return (_CurrencyManager); } + + set + { + if (_CurrencyManager != value) + { + if (_CurrencyManager != null) + { + _CurrencyManager.ListChanged -= CurrencyManagerListChanged; + _CurrencyManager.PositionChanged -= CmPositionChanged; + _CurrencyManager.MetaDataChanged -= CurrencyManagerMetaDataChanged; + + _Panel.SuperGrid.LoadVirtualRow -= SuperGridLoadVirtualRow; + } + + _CurrencyManager = value; + + if (_BaseBindingSource != null) + _BaseBindingSource.PositionChanged -= BsPositionChanged; + + _BaseBindingSource = null; + + if (_CurrencyManager != null) + { + _Pdc = CurrencyManager.GetItemProperties(); + + if (_Panel.IsSubPanel == false) + _CurrencyManager.PositionChanged += CmPositionChanged; + + _BaseBindingSource = _Panel.DataSource as BindingSource; + + if (_BaseBindingSource != null) + _BaseBindingSource.PositionChanged += BsPositionChanged; + + _CurrencyManager.MetaDataChanged += CurrencyManagerMetaDataChanged; + + if (_Panel.VirtualMode == true) + { + _Panel.VirtualRowCount = _CurrencyManager.Count; + + _Panel.SuperGrid.LoadVirtualRow += SuperGridLoadVirtualRow; + } + } + else + { + _Pdc = null; + } + } + } + } + + #region CurrencyManagerMetaDataChanged + + void CurrencyManagerMetaDataChanged(object sender, EventArgs e) + { + if (CurrencyManager != null) + { + _Pdc = CurrencyManager.GetItemProperties(); + + _Panel.InvalidateMerge(); + } + } + + #endregion + + #endregion + + #region DataResetCount + + internal ushort DataResetCount + { + get { return (_DataResetCount); } + + set + { + _DataResetCount = value; + + if (_Panel.VirtualMode == true) + _Panel.VirtualRows.Clear(); + + if (_UpdatingFilter == true) + { + _Panel.NeedToUpdateBoundData = true; + } + else + { + _Panel.NeedToUpdateBindings = true; + _Panel.NeedToUpdateDataFilter = true; + } + + _Panel.UnDeleteAll(); + _Panel.InvalidateMerge(); + } + } + + #endregion + + #region DataView + + internal DataView DataView + { + get { return (_DataView); } + set { _DataView = value; } + } + + #endregion + + #region GetValue + + internal object GetValue(GridCell cell, object value) + { + if (cell.GridRow.IsTempInsertRow == false) + { + if (CurrencyManager != null && _Pdc != null) + { + if ((uint)cell.GridRow.DataItemIndex < CurrencyManager.List.Count) + { + int index = cell.GridRow.DataItemIndex; + + if (_Panel.VirtualMode == true && _Panel.VirtualTempInsertRow != null) + { + if (index > _Panel.VirtualTempInsertRow.RowIndex) + index--; + } + + object dataItem = CurrencyManager.List[index]; + PropertyDescriptorCollection pdc = GetPdc(dataItem); + + GridColumn col = _Panel.Columns[cell.ColumnIndex]; + PropertyDescriptor pd = FindPropertyDescriptor(pdc, col); + + if (pd != null) + return (pd.GetValue(dataItem)); + } + } + } + + return (value); + } + + #endregion + + #region IsSortable + + internal bool IsSortable + { + get + { + if (_BaseDataSource is DataSet) + return (true); + + if (_BaseDataSource is IBindingList) + { + IBindingList list = (IBindingList)_BaseDataSource; + + return (list.SupportsSorting); + } + + if (_BaseDataSource is IListSource) + { + IList list2 = ((IListSource)_BaseDataSource).GetList(); + + if (list2 is IBindingList) + return (((IBindingList)list2).SupportsSorting); + } + + return (false); + } + } + + #endregion + + #region IsUpdateSuspended + + internal bool IsUpdateSuspended + { + get { return (_BeginUpdateCount > 0); } + } + + #endregion + + #region NotificationInProgress + + internal bool NotificationInProgress + { + get { return (_NotificationInProgress); } + set { _NotificationInProgress = value; } + } + + #endregion + + #region Pdc + + internal PropertyDescriptorCollection Pdc + { + get { return (_Pdc); } + set { _Pdc = value; } + } + + #endregion + + #region RowCount + + internal int RowCount + { + get + { + if (CurrencyManager != null) + return (CurrencyManager.Count); + + return (0); + } + } + + #endregion + + #region SetValue + + internal void SetValue(GridCell cell, object value) + { + if (cell.GridRow.IsTempInsertRow == false) + { + if (CurrencyManager != null && _Pdc != null) + { + GridRow row = (GridRow)cell.GridRow; + + if ((uint)row.DataItemIndex < CurrencyManager.List.Count) + { + object dataItem = CurrencyManager.List[row.DataItemIndex]; + + PropertyDescriptorCollection pdc = GetPdc(dataItem); + + GridColumn col = _Panel.Columns[cell.ColumnIndex]; + PropertyDescriptor pd = FindPropertyDescriptor(pdc, col); + + if (pd != null) + { + if (pd.IsReadOnly == false) + { + object cvalue = value; + + if ((value != null && Convert.IsDBNull(value) == false) && + value.GetType() != pd.PropertyType && (value is IConvertible)) + { + cvalue = Convert.ChangeType(value, Nullable.GetUnderlyingType(pd.PropertyType) ?? pd.PropertyType); + } + + pd.SetValue(dataItem, cvalue); + + UpdatePosInProgress = true; + CurrencyManager.EndCurrentEdit(); + UpdatePosInProgress = false; + } + } + } + } + } + } + + #endregion + + #region UpdateInProgress + + internal bool UpdateInProgress + { + get { return (_UpdateInProgress); } + set { _UpdateInProgress = value; } + } + + #endregion + + #region UpdatePosInProgress + + internal bool UpdatePosInProgress + { + get { return (_UpdatePosInProgress); } + set { _UpdatePosInProgress = value; } + } + + #endregion + + #endregion + + #region Clear + + internal void Clear() + { + if (_Panel.SuperGrid != null) + _Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand; + + CurrencyManager = null; + + _BaseDataSource = null; + _BaseDataMember = null; + + _DataView = null; + _BindingSource = null; + + _Panel.ActiveRow = null; + _Panel.MergeScan = null; + _Panel.DataRelation = null; + + if (_Panel.VirtualMode == true) + { + _Panel.VirtualTempInsertRow = null; + _Panel.VirtualRows.Clear(); + } + + _TempDataRow = null; + _LastDataItemAdded = null; + } + + #endregion + + #region DataConnect + + internal void DataConnect() + { + _BaseDataSource = _Panel.DataSource; + _BaseDataMember = _Panel.DataMember; + + if (_BaseDataSource != null) + { + _BindingSource = _BaseDataSource as BindingSource; + + if (_BindingSource != null) + { + BindingSource bs = _BindingSource.DataSource as BindingSource; + + if (bs != null) + { + if (string.IsNullOrEmpty(_BindingSource.DataMember) == false) + _BaseDataMember = _BindingSource.DataMember; + else + _BindingSource = null; + + while (bs.DataSource is BindingSource) + bs = (BindingSource)bs.DataSource; + + DataSet dss = bs.DataSource as DataSet; + + if (dss != null) + { + DataRelation dsr = dss.Relations[_BaseDataMember]; + + if (dsr != null) + { + _BaseDataSource = dss; + _BaseDataMember = dsr.ChildTable.TableName; + } + } + } + else + { + _BaseDataSource = _BindingSource.DataSource; + _BaseDataMember = _BindingSource.DataMember; + } + } + + DataView = null; + + if (_BaseDataSource is DataSet) + AddDataSetTable((DataSet)_BaseDataSource, _BaseDataMember); + + //else if (_BaseDataSource is DataTable) + // AddDataTable((DataTable)_BaseDataSource); + + else if (_BaseDataSource is IBindingList) + AddIList((IBindingList)_BaseDataSource); + + else if (_BaseDataSource is IList) + AddIList((IList)_BaseDataSource); + + else if (_BaseDataSource is IListSource) + { + DataTable dt = _BaseDataSource as DataTable; + + if (dt != null) + DataView = dt.DefaultView; + + AddIList(((IListSource)_BaseDataSource).GetList()); + } + else + AddDefaultObject(_BaseDataSource); + } + } + + #endregion + + #region SetDataConnection + + private bool SetDataConnection(object dataSource) + { + if (ConnectionInProgress == false) + { + ClearDataNotification(dataSource); + + if (_BindingSource != null || _Panel.SuperGrid.BindingContext != null) + { + ConnectionInProgress = true; + + try + { + SetDataNotification(dataSource); + } + finally + { + ConnectionInProgress = false; + } + } + } + + return (NotificationInProgress == false); + } + + #endregion + + #region SetDataNotification + + private void SetDataNotification(object dataSource) + { + ISupportInitializeNotification notification = + dataSource as ISupportInitializeNotification; + + if (notification == null || notification.IsInitialized == true) + { + CurrencyManager = (_BindingSource != null) + ? _BindingSource.CurrencyManager + : _Panel.SuperGrid.BindingContext[DataView ?? dataSource] as CurrencyManager; + } + else + { + CurrencyManager = null; + + if (NotificationInProgress == false) + { + notification.Initialized += DataSourceInitialized; + NotificationInProgress = true; + } + } + } + + #endregion + + #region ClearDataNotification + + private void ClearDataNotification(object dataSource) + { + ISupportInitializeNotification notification = + dataSource as ISupportInitializeNotification; + + if (notification != null && NotificationInProgress == true) + { + notification.Initialized -= DataSourceInitialized; + + NotificationInProgress = false; + } + } + + #endregion + + #region DataSourceInitialized + + private void DataSourceInitialized(object sender, EventArgs e) + { + ISupportInitializeNotification dataSource = + _Panel.DataSource as ISupportInitializeNotification; + + if (dataSource != null) + { + NotificationInProgress = false; + + dataSource.Initialized -= DataSourceInitialized; + + CurrencyManager = + _Panel.SuperGrid.BindingContext[dataSource] as CurrencyManager; + } + } + + #endregion + + #region CmPositionChanged + + void CmPositionChanged(object sender, EventArgs e) + { + if (IsUpdateSuspended == false && UpdatePosInProgress == false) + { + CurrencyManager cm = sender as CurrencyManager; + + if (cm != null && cm == _CurrencyManager) + UpdatePosition(cm.Position); + } + } + + #region BsPositionChanged + + void BsPositionChanged(object sender, EventArgs e) + { + if (_UpdatePosInProgress == false) + { + BindingSource bs = sender as BindingSource; + + if (bs != null) + UpdatePosition(bs.Position); + } + } + + #endregion + + #region UpdatePosition + + private void UpdatePosition(int position) + { + if (_Panel.IsSubPanel == false) + { + GridRow row = FindDataGridRowIndex(position); + + if (row != null && _Panel.ActiveRow != row) + { + try + { + _UpdatePosInProgress = true; + + if (row.Visible == false) + row.Visible = true; + + if (_Panel.AutoSelectNewBoundRows == true) + { + _Panel.ClearAll(); + + _Panel.SetActiveRow(row, true); + _Panel.SetSelectedRows(row.GridIndex, 1, true); + + bool skey = (_Panel.MultiSelect == true) ? + ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) : false; + + if (skey == false || _Panel.SelectionRowAnchor == null) + _Panel.SelectionRowAnchor = row; + + row.EnsureVisible(); + } + } + finally + { + _UpdatePosInProgress = false; + } + } + } + } + + #endregion + + #endregion + + #region SetPosition + + internal bool SetPosition(GridRow row) + { + if (_UpdatePosInProgress == false) + { + if (row != null && row.IsTempInsertRow == false) + { + if (CurrencyManager != null) + { + if (SetCmPosition(row) == false) + return (false); + + _Panel.ActiveRow = row; + + if (_Panel.IsSubPanel == false) + { + if (_BaseBindingSource != null) + _BaseBindingSource.Position = CurrencyManager.Position; + } + } + } + } + + return (true); + } + + #region SetCmPosition + + private bool SetCmPosition(GridRow row) + { + if (CurrencyManager == null) + return (false); + + while (true) + { + _UpdatePosInProgress = true; + + try + { + CurrencyManager.Position = row.DataItemIndex; + break; + } + catch (Exception exp) + { + GridRow crow = null; + + if ((uint)CurrencyManager.Position < _Panel.Rows.Count) + { + crow = _Panel.Rows[CurrencyManager.Position] as GridRow; + + if (crow != null) + ReloadRow(crow); + } + + bool retry = false; + bool throwException = false; + + if (_Panel.SuperGrid.HasDataErrorHandler == true) + { + object value = crow; + + if (_Panel.SuperGrid.DoDataErrorEvent(_Panel, null, exp, + DataContext.SetRowPosition, ref value, ref throwException, ref retry) == true) + { + return (false); + } + } + + if (throwException == true) + throw; + + if (retry == false) + return (false); + } + finally + { + _UpdatePosInProgress = false; + } + } + + return (true); + } + + #endregion + + #endregion + + #region AddIList + + internal void AddIList(IList list) + { + bool autogen = _Panel.AutoGenerateColumns; + ProcessChildRelations crVisibility = _Panel.ProcessChildRelations; + + if (_Panel.SuperGrid.DoDataBindingStartEvent( + _Panel, null, null, ref autogen, ref crVisibility) == false) + { + AddIList(list, autogen, crVisibility); + } + } + + #region AddIList + + internal void AddIList(IList list, bool autogen, ProcessChildRelations crProcess) + { + if (SetDataConnection(list) == true) + { + if (_Pdc != null) + { + if (autogen == true && _Panel.IsDesignerHosted == false) + AutoGenerateListColumns(null); + + if (_Panel.VirtualMode == false) + { + if (crProcess != ProcessChildRelations.Never) + { + bool rowsUnresolved = false; + + for (int i = 0; i < list.Count; i++) + { + object o = list[i]; + + if (o != null) + { + GridRow row = GetNewRow(o); + + row.DataItem = o; + row.DataItemIndex = i; + + Type type = o.GetType(); + + if (type != null) + { + if (CheckNestedFields(row, type, crProcess) == false) + CheckNestedProperties(row, type, crProcess); + } + + rowsUnresolved |= row.RowsUnresolved; + + _Panel.Rows.Add(row); + } + } + + if (rowsUnresolved == true) + { + _Panel.ShowTreeButtons = true; + _Panel.ShowTreeLines = true; + + _Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand; + _Panel.SuperGrid.BeforeExpand += SuperGridBeforeExpand; + } + } + } + + UpdateSuperGridSort(false); + } + + if (CurrencyManager != null) + { + CurrencyManager.ListChanged -= CurrencyManagerListChanged; + CurrencyManager.ListChanged += CurrencyManagerListChanged; + } + + _Panel.SuperGrid.DoDataBindingCompleteEvent(_Panel); + + if (_Panel.ShowInsertRow == true) + { + _Panel.ShowInsertRow = false; + _Panel.ShowInsertRow = true; + } + } + } + + #region CheckNestedFields + + private bool CheckNestedFields(GridRow row, Type type, ProcessChildRelations crProcess) + { + if ((_Panel.NestedListScanTypes & NestedListScanTypes.Fields) == NestedListScanTypes.Fields) + { + FieldInfo[] fia = type.GetFields(); + + foreach (FieldInfo fi in fia) + { + if (IsNestedList(fi.FieldType.Name) == true) + { + if (IsVisibleItem(type, fi) == true) + { + if (crProcess == ProcessChildRelations.Always || fia.Length > 0) + { + row.RowsUnresolved = true; + + return (true); + } + } + } + } + } + + return (false); + } + + #endregion + + #region CheckNestedProperties + + private bool CheckNestedProperties(GridRow row, Type type, ProcessChildRelations crProcess) + { + if ((_Panel.NestedListScanTypes & NestedListScanTypes.Properties) == NestedListScanTypes.Properties) + { + PropertyInfo[] pia = type.GetProperties(); + + foreach (PropertyInfo pi in pia) + { + if (IsNestedList(pi.PropertyType.Name) == true) + { + if (IsVisibleItem(type, pi) == true) + { + if (crProcess == ProcessChildRelations.Always || pia.Length > 0) + row.RowsUnresolved = true; + + return (true); + } + } + } + } + + return (false); + } + + #endregion + + #region IsNestedList + + private bool IsNestedList(string name) + { + return (name.Equals("List`1") || name.Equals("BindingList`1")); + } + + #endregion + + #endregion + + #region AutoGenerateListColumns + + private void AutoGenerateListColumns(GetNewGridColumn callBack) + { + if (_Pdc != null) + { + foreach (PropertyDescriptor pd in _Pdc) + { + if (pd.PropertyType.IsInterface == false) + { + if (IsNestedList(pd.PropertyType.Name) == false && IsVisibleItem(pd) == true) + { + if (FindGridColumn(_Panel, pd.Name) == null) + { + GridColumn gcol = (callBack != null) ? callBack() : new GridColumn(); + + if (gcol != null) + { + gcol.DataPropertyName = pd.Name; + gcol.Name = pd.DisplayName; + gcol.Width = 100; + + SetColumnEditor(pd.PropertyType, gcol); + + _Panel.Columns.Add(gcol); + } + } + } + } + } + } + } + + #endregion + + #region IsVisibleItem + + private bool IsVisibleItem(Type type, FieldInfo fi) + { + foreach (Attribute attr in fi.GetCustomAttributes(true)) + { + IsVisibleToSuperGrid dattr = attr as IsVisibleToSuperGrid; + + if (dattr != null) + return (dattr.Visible); + } + + return (true); + } + + private bool IsVisibleItem(Type type, PropertyInfo pi) + { + foreach (Attribute attr in pi.GetCustomAttributes(true)) + { + IsVisibleToSuperGrid dattr = attr as IsVisibleToSuperGrid; + + if (dattr != null) + return (dattr.Visible); + } + + return (true); + } + + private bool IsVisibleItem(PropertyDescriptor pd) + { + foreach (Attribute attr in pd.Attributes) + { + IsVisibleToSuperGrid dattr = attr as IsVisibleToSuperGrid; + + if (dattr != null) + return (dattr.Visible); + } + + return (true); + } + + #endregion + + #region GetNewRow + + private GridRow GetNewRow(object o) + { + GridRow row = new GridRow(); + PropertyDescriptorCollection pdc = GetPdc(o); + + foreach (GridColumn col in _Panel.Columns) + { + PropertyDescriptor pd = FindPropertyDescriptor(pdc, col); + + object value = (pd != null) + ? pd.GetValue(o) : null; + + row.Cells.Add(new GridCell(value)); + } + + return (row); + } + + #endregion + + #endregion + + #region AddDataSetTable + + internal void AddDataSetTable(DataSet dataSet, string dataMember) + { + if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0) + dataMember = dataSet.Tables[0].TableName; + + if (string.IsNullOrEmpty(dataMember) == false) + AddDataTable(dataSet.Tables[dataMember]); + } + + #endregion + + #region AddDataTable + + internal void AddDataTable(DataTable dt) + { + bool autogen = _Panel.AutoGenerateColumns; + ProcessChildRelations crVisibility = _Panel.ProcessChildRelations; + + if (_Panel.SuperGrid.DoDataBindingStartEvent( + _Panel, null, dt.TableName, ref autogen, ref crVisibility) == false) + { + AddDataTable(dt, autogen, crVisibility); + } + } + + internal void AddDataTable( + DataTable dt, bool autogen, ProcessChildRelations crProcess) + { + if (SetDataConnection(dt) == true) + { + if (CurrencyManager != null) + { + CurrencyManager.ListChanged -= CurrencyManagerListChanged; + CurrencyManager.ListChanged += CurrencyManagerListChanged; + + if (autogen == true && _Panel.IsDesignerHosted == false) + AutoGenerateDataTableColumns(dt, null); + + if (_Panel.VirtualMode == false) + { + int pindex = (crProcess != ProcessChildRelations.Never) ? GetPrimaryColumnIndex(dt) : -1; + + bool rowsUnresolved = (pindex >= 0 && dt.ChildRelations.Count > 0); + + for (int i = 0; i < CurrencyManager.Count; i++) + { + DataRowView view = CurrencyManager.List[i] as DataRowView; + + if (view != null) + { + GridRow row = GetNewRow(dt, view); + row.DataItem = view; + row.DataItemIndex = i; + + row.RowsUnresolved = rowsUnresolved; + + _Panel.Rows.Add(row); + } + } + + if (rowsUnresolved == true) + { + _Panel.PrimaryColumnIndex = pindex; + + _Panel.ShowTreeButtons = true; + _Panel.ShowTreeLines = true; + + _Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand; + _Panel.SuperGrid.BeforeExpand += SuperGridBeforeExpand; + } + } + else + { + if (_Panel.IsFiltered == true) + dt.DefaultView.RowFilter = ""; + } + + DataView = dt.DefaultView; + + UpdateSuperGridSort(false); + + _Panel.SuperGrid.DoDataBindingCompleteEvent(_Panel); + } + } + } + + #endregion + + #region AddDefaultObject + + private void AddDefaultObject(object source) + { + if (SetDataConnection(source) == true) + { + if (_Pdc != null) + { + if (_Panel.AutoGenerateColumns == true && _Panel.IsDesignerHosted == false) + AutoGenerateListColumns(null); + + IList list = CurrencyManager.List; + + for (int i = 0; i < list.Count; i++) + { + object o = list[i]; + + if (o != null) + { + GridRow row = GetNewRow(o); + + row.DataItem = o; + row.DataItemIndex = i; + + _Panel.Rows.Add(row); + } + } + + _Panel.SuperGrid.DoDataBindingCompleteEvent(_Panel); + } + + if (CurrencyManager != null) + { + CurrencyManager.ListChanged -= CurrencyManagerListChanged; + CurrencyManager.ListChanged += CurrencyManagerListChanged; + } + } + } + + #endregion + + #region GetPrimaryColumnIndex + + private int GetPrimaryColumnIndex(DataTable dt) + { + if (dt.ChildRelations.Count > 0) + { + DataRelation dr = dt.ChildRelations[0]; + + if (dr.ParentColumns.Length > 0) + { + GridColumn col = + FindGridColumn(_Panel, dr.ParentColumns[0].ColumnName); + + if (col != null) + return (col.ColumnIndex); + } + } + + return (-1); + } + + #endregion + + #region AutoGenerateDataTableColumns + + private void AutoGenerateDataTableColumns(DataTable dt, GetNewGridColumn callBack) + { + foreach (DataColumn dtColumn in dt.Columns) + { + if ((dtColumn.ColumnMapping & MappingType.Hidden) != MappingType.Hidden) + { + if (FindGridColumn(_Panel, dtColumn.ColumnName) == null) + { + GridColumn gcol = (callBack != null) ? callBack() : new GridColumn(); + + if (gcol != null) + { + gcol.DataPropertyName = dtColumn.ColumnName; + gcol.Name = dtColumn.ColumnName; + gcol.Width = 100; + + gcol.DefaultNewRowCellValue = dtColumn.DefaultValue; + gcol.ReadOnly = dtColumn.ReadOnly; + + if (String.IsNullOrEmpty(dtColumn.Caption) == false) + gcol.HeaderText = dtColumn.Caption; + + SetColumnEditor(dtColumn.DataType, gcol); + + _Panel.Columns.Add(gcol); + } + } + } + } + } + + #region SetColumnEditor + + private void SetColumnEditor(Type type, GridColumn col) + { + col.DataType = type; + + if (type != null) + { + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + Type type2 = Nullable.GetUnderlyingType(type); + + if (type2 != null) + type = type2; + } + + if (type == typeof(String) || type == typeof(SqlString)) + { + col.EditorType = typeof(GridTextBoxXEditControl); + } + else if (type == typeof(Boolean) || type == typeof(SqlBoolean)) + { + col.EditorType = typeof(GridCheckBoxXEditControl); + } + else if (type == typeof(DateTime) || type == typeof(SqlDateTime) + || type == typeof(TimeSpan)) + { + col.EditorType = typeof(GridDateTimeInputEditControl); + } + else if (type == typeof(Decimal) || type == typeof(SqlDecimal) || + type == typeof(Double) || type == typeof(SqlDouble) || + type == typeof(Single) || type == typeof(SqlSingle)) + { + col.EditorType = typeof(GridDoubleInputEditControl); + } + else if (type == typeof(Int64) || type == typeof(SqlInt64)) + { + col.EditorType = typeof(GridDoubleIntInputEditControl); + } + else if (type == typeof(Int16) || (type == typeof(SqlInt16) || + type == typeof(Int32) || type == typeof(SqlInt32))) + { + col.EditorType = typeof(GridIntegerInputEditControl); + } + } + } + + #endregion + + #endregion + + #region AutoGenerateColumns + + internal void AutoGenerateColumns(GetNewGridColumn callBack) + { + if (CurrencyManager != null) + { + DataSet dataSet = _BaseDataSource as DataSet; + + if (dataSet != null) + { + string dataMember = _BaseDataMember; + + if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0) + dataMember = dataSet.Tables[0].TableName; + + if (string.IsNullOrEmpty(dataMember) == false) + AutoGenerateDataTableColumns(dataSet.Tables[dataMember], callBack); + } + else + { + AutoGenerateListColumns(callBack); + } + } + } + + #endregion + + #region GetNewRow + + private GridRow GetNewRow(DataTable dt, DataRowView view) + { + GridRow row = new GridRow(); + + for (int i = 0; i < _Panel.Columns.Count; i++) + { + GridColumn col = _Panel.Columns[i]; + DataColumn dtColumn = FindDataColumn(dt, col); + + object o = (dtColumn != null) + ? view.Row.ItemArray[dtColumn.Ordinal] : null; + + row.Cells.Add(new GridCell(o)); + } + + return (row); + } + + #endregion + + #region IsColumnDataBound + + internal bool IsColumnDataBound(GridColumn col) + { + if (_Pdc != null) + { + PropertyDescriptor pd = FindPropertyDescriptor(_Pdc, col); + + return (pd != null); + } + + return (false); + } + + #endregion + + #region GetPdc + + private PropertyDescriptorCollection GetPdc(object dataItem) + { + if (_Panel.EnableDiscreteBoundRows == true) + { + if (dataItem != null) + return (TypeDescriptor.GetProperties(dataItem.GetType())); + } + + return (_Pdc); + } + + #endregion + + #region FindPropertyDescriptor + + private PropertyDescriptor FindPropertyDescriptor(PropertyDescriptorCollection pdc, GridColumn col) + { + if (pdc != null) + { + foreach (PropertyDescriptor pd in pdc) + { + if (string.IsNullOrEmpty(col.DataPropertyName) == true) + { + if (pd.Name.Equals(col.Name) == true) + return (pd); + } + else + { + if (pd.Name.Equals(col.DataPropertyName) == true) + return (pd); + } + } + } + + return (null); + } + + #endregion + + #region FindDataColumn + + private DataColumn FindDataColumn(DataTable dt, GridColumn col) + { + foreach (DataColumn dtColumn in dt.Columns) + { + if (string.IsNullOrEmpty(col.DataPropertyName) == true) + { + if (dtColumn.ColumnName.Equals(col.Name) == true) + return (dtColumn); + } + else + { + if (dtColumn.ColumnName.Equals(col.DataPropertyName) == true) + return (dtColumn); + } + } + + return (null); + } + + #endregion + + #region FindGridColumn + + private GridColumn FindGridColumn(GridPanel panel, string name) + { + foreach (GridColumn col in panel.Columns) + { + if (string.IsNullOrEmpty(col.DataPropertyName) == true) + { + if (name.Equals(col.Name) == true) + return (col); + } + else + { + if (name.Equals(col.DataPropertyName) == true) + return (col); + } + } + + return (null); + } + + #endregion + + #region SuperGridBeforeExpand + + void SuperGridBeforeExpand(object sender, GridBeforeExpandEventArgs e) + { + if (e.GridPanel == _Panel) + ResolveRow(e.GridContainer); + } + + #endregion + + #region ResolveRow + + internal void ResolveRow(GridContainer crow) + { + if (crow.RowsUnresolved == true) + { + crow.RowsUnresolved = false; + + GridRow row = crow as GridRow; + + if (row != null) + { + DataRowView view = row.DataItem as DataRowView; + + if (view != null) + { + DataTable dt = view.DataView.Table; + + StringBuilder sb = new StringBuilder(); + + foreach (DataRelation dr in dt.ChildRelations) + CreateNestedTablePanel(_Panel, row, dr, sb); + } + else if (_BaseDataSource is IList) + { + object o = row.DataItem; + + Type type = o.GetType(); + + if (type != null) + { + FieldInfo[] fia = type.GetFields(); + + foreach (FieldInfo fi in fia) + CreateNestedListFieldPanel(_Panel, row, type, fi); + + PropertyInfo[] pia = type.GetProperties(); + + foreach (PropertyInfo pi in pia) + CreateNestedListPropertyPanel(_Panel, row, type, pi); + + } + } + } + } + } + + #region CreateNestedTablePanel + + private void CreateNestedTablePanel(GridPanel panel, + GridRow row, DataRelation dr, StringBuilder sb) + { + DataTable ct = dr.ChildTable; + + bool autogen = true; + ProcessChildRelations crProcess = _Panel.ProcessChildRelations; + + if (_Panel.SuperGrid.DoDataBindingStartEvent( + _Panel, row, ct.TableName, ref autogen, ref crProcess) == false) + { + if (crProcess != ProcessChildRelations.Never) + { + sb.Length = 0; + + for (int i = 0; i < dr.ParentColumns.Length; i++) + { + DataColumn col = dr.ParentColumns[i]; + GridColumn gc = FindGridColumn(panel, col.ColumnName); + + if (gc != null) + { + object val = row.Cells[gc.ColumnIndex].Value; + + if (val != null) + { + string sval = val.ToString(); + + if (sval.Length > 0) + { + if (sb.Length > 0) + sb.Append(" AND "); + + sb.Append("[" + dr.ChildColumns[i] + "]="); + + if (sval.Contains("'") == true) + sval = sval.Replace("'", "''"); + + sb.Append("'" + sval + "'"); + } + } + } + } + + string t = sb.ToString(); + + DataView view = new + DataView(ct, t, "", DataViewRowState.CurrentRows); + + if (view.Count > 0 || crProcess == ProcessChildRelations.Always) + { + GridPanel ipanel = new GridPanel(); + + ipanel.Name = ct.TableName; + ipanel.AutoGenerateColumns = autogen; + ipanel.ProcessChildRelations = crProcess; + + ipanel.SetDataSource(panel.DataSource); + ipanel.SetDataMember(ct.TableName); + + ipanel.DataRelation = dr; + + ipanel.DataBinder.DataView = view; + ipanel.DataBinder.BaseDataSource = ipanel.DataSource; + ipanel.DataBinder.BaseDataMember = ipanel.DataMember; + + row.Rows.Add(ipanel); + + ipanel.DataBinder.AddDataTable(ct, autogen, crProcess); + } + else + { + view.Dispose(); + } + } + } + } + + #endregion + + #region CreateNestedListFieldPanel + + private void CreateNestedListFieldPanel(GridPanel _Panel, + GridRow row, Type type, FieldInfo fi) + { + bool autogen = true; + ProcessChildRelations crProcess = _Panel.ProcessChildRelations; + + if (IsNestedList(fi.FieldType.Name) == true) + { + if (IsVisibleItem(type, fi) == true) + { + IList list = fi.GetValue(row.DataItem) as IList; + + if (list != null) + { + GridPanel ipanel = new GridPanel(); + + ipanel.Name = fi.Name; + ipanel.AutoGenerateColumns = autogen; + ipanel.ProcessChildRelations = crProcess; + + ipanel.NestedListScanTypes = _Panel.NestedListScanTypes; + + if (_Panel.SuperGrid.DoDataBindingStartEvent( + _Panel, row, null, ref autogen, ref crProcess) == false) + { + if (crProcess != ProcessChildRelations.Never) + { + if (list.Count > 0 || crProcess == ProcessChildRelations.Always) + { + ipanel.SetDataSource(list); + ipanel.DataBinder.BaseDataSource = ipanel.DataSource; + + row.Rows.Add(ipanel); + + ipanel.DataBinder.AddIList((IList)ipanel.DataSource, autogen, crProcess); + } + } + } + } + } + } + } + + #endregion + + #region CreateNestedListPropertyPanel + + private void CreateNestedListPropertyPanel(GridPanel _Panel, + GridRow row, Type type, PropertyInfo pi) + { + bool autogen = true; + ProcessChildRelations crProcess = _Panel.ProcessChildRelations; + + if (IsNestedList(pi.PropertyType.Name) == true) + { + if (IsVisibleItem(type, pi) == true) + { + IList list = pi.GetValue(row.DataItem, null) as IList; + + if (list != null) + { + GridPanel ipanel = new GridPanel(); + + ipanel.Name = pi.Name; + ipanel.AutoGenerateColumns = autogen; + ipanel.ProcessChildRelations = crProcess; + + ipanel.NestedListScanTypes = _Panel.NestedListScanTypes; + + if (_Panel.SuperGrid.DoDataBindingStartEvent( + ipanel, row, null, ref autogen, ref crProcess) == false) + { + if (crProcess != ProcessChildRelations.Never) + { + if (list.Count > 0 || crProcess == ProcessChildRelations.Always) + { + ipanel.SetDataSource(list); + ipanel.DataBinder.BaseDataSource = ipanel.DataSource; + + row.Rows.Add(ipanel); + + ipanel.DataBinder.AddIList((IList)ipanel.DataSource, autogen, crProcess); + } + } + } + } + } + } + } + + #endregion + + #endregion + + #region CurrencyManagerListChanged + + void CurrencyManagerListChanged(object sender, ListChangedEventArgs e) + { + if (_Panel.SuperGrid.InvokeRequired) + { + _Panel.SuperGrid.BeginInvoke( + new MethodInvoker(delegate { CurrencyManagerListChangedUIThread(sender, e); })); + } + else + { + CurrencyManagerListChangedUIThread(sender, e); + } + } + + void CurrencyManagerListChangedUIThread(object sender, ListChangedEventArgs e) + { + if (IsUpdateSuspended == false && UpdateInProgress == false) + { + GridRow row = null; + + try + { + UpdateInProgress = true; + + CurrencyManager cm = sender as CurrencyManager; + + if (cm != null && cm == _CurrencyManager) + { + IList list = cm.List; + + bool updateGrouping = true; + + if (e.ListChangedType == ListChangedType.ItemAdded) + { + if ((uint)e.NewIndex < CurrencyManager.Count) + { + row = AddDataGridRow(list, e.NewIndex); + + if (row != null) + _Panel.SuperGrid.DoRowLoadedEvent(_Panel, row); + } + } + else + { + switch (e.ListChangedType) + { + case ListChangedType.ItemChanged: + UpdateDataGridRow(list, e.NewIndex); + updateGrouping = false; + break; + + case ListChangedType.ItemDeleted: + DeleteDataGridRow(e.NewIndex); + break; + + case ListChangedType.ItemMoved: + MoveDataGridRow(e.OldIndex, e.NewIndex); + break; + + case ListChangedType.Reset: + _Panel.FlushActiveRow(); + + DataResetCount++; + + if (_Panel.VirtualMode == false) + { + _Panel.Rows.Clear(); + + if (_Panel.ShowInsertRow == true) + _Panel.LoadInsertRow = true; + } + else + { + _Panel.VirtualRows.Clear(); + + Refresh(); + } + + UpdateSuperGridSort(true); + break; + } + + _LastDataItemAdded = null; + } + + if (updateGrouping == true) + UpdateGrouping(); + } + } + finally + { + UpdateInProgress = false; + } + } + } + + #region AddDataGridRow + + private GridRow AddDataGridRow(IList list, int index) + { + GridElement selItem = _Panel.SuperGrid.ActiveElement; + + if (_Panel.VirtualMode == true) + { + _Panel.VirtualRows.MaxRowIndex = index - 1; + _Panel.VirtualRowCount = CurrencyManager.Count; + + _Panel.InvalidateRender(); + + if (_Panel.AutoSelectNewBoundRows == false) + { + if (_Panel.ActiveRow != null) + index = _Panel.ActiveRow.RowIndex; + else + index = -1; + } + + if (index > _Panel.VirtualRowCount) + index = _Panel.VirtualRowCount - 1; + + if (index >= 0) + SelectRow(_Panel, index); + + return (null); + } + else + { + GridRow row = null; + + object o = list[index]; + + if (o != _LastDataItemAdded) + { + row = GetNewRow(o); + + row.DataItem = o; + row.DataItemIndex = index; + + AddNestedLink(list, row); + + UpdateRowsDataIndex(index, 1); + + if (_Panel.IsGrouped == true) + { + _Panel.Rows.Insert(0, row); + } + else + { + _Panel.Rows.Insert(index, row); + _Panel.UpdateRowPosition(row); + + index = row.RowIndex; + } + + if (_Panel.AutoSelectNewBoundRows == true) + { + SelectRow(_Panel, index); + } + else + { + int selCount = _Panel.SelectedRowCount; + ushort selUpdateCount = _Panel.SelectionUpdateCount; + + _Panel.ClearAll(); + + SelectLastElement(selItem); + + if (selCount == 1) + _Panel.SelectionUpdateCount = selUpdateCount; + } + } + else + { + row = UpdateDataGridRow(list, index); + } + + _LastDataItemAdded = o; + + return (row); + } + } + + #region AddNestedLink + + private void AddNestedLink(IList list, GridRow row) + { + if (_BaseDataSource is DataSet) + AddDataSetLink(row); + + else if (_BaseDataSource is IBindingList) + AddIListLink(row); + + else if (_BaseDataSource is IList) + AddIListLink(row); + + else if (_BaseDataSource is IListSource) + AddIListLink(row); + } + + #region AddDataSetLink + + private void AddDataSetLink(GridRow row) + { + DataRowView view = row.DataItem as DataRowView; + + if (view != null) + { + DataTable dt = view.DataView.Table; + + if (dt != null) + { + bool autogen = _Panel.AutoGenerateColumns; + ProcessChildRelations crVisibility = _Panel.ProcessChildRelations; + + if (_Panel.SuperGrid.DoDataBindingStartEvent( + _Panel, null, dt.TableName, ref autogen, ref crVisibility) == false) + { + AddDataTableLink(row, dt, autogen, crVisibility); + } + } + } + } + + #region AddDataTableLink + + private void AddDataTableLink(GridRow row, + DataTable dt, bool autogen, ProcessChildRelations crProcess) + { + int pindex = (crProcess != ProcessChildRelations.Never) ? GetPrimaryColumnIndex(dt) : -1; + + row.RowsUnresolved = (pindex >= 0 && dt.ChildRelations.Count > 0); + + if (row.RowsUnresolved == true) + { + _Panel.ShowTreeButtons = true; + _Panel.ShowTreeLines = true; + + _Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand; + _Panel.SuperGrid.BeforeExpand += SuperGridBeforeExpand; + } + } + + #endregion + + #endregion + + #region AddIListLink + + private void AddIListLink(GridRow row) + { + bool autogen = _Panel.AutoGenerateColumns; + ProcessChildRelations crVisibility = _Panel.ProcessChildRelations; + + if (_Panel.SuperGrid.DoDataBindingStartEvent( + _Panel, null, null, ref autogen, ref crVisibility) == false) + { + AddIListLink(row, autogen, crVisibility); + } + } + + #region AddIListLink + + private void AddIListLink(GridRow row, bool autogen, ProcessChildRelations crProcess) + { + if (crProcess != ProcessChildRelations.Never) + { + bool rowsUnresolved = false; + + if (row.DataItem != null) + { + Type type = row.DataItem.GetType(); + + if (type != null) + { + if (CheckNestedFields(row, type, crProcess) == false) + CheckNestedProperties(row, type, crProcess); + } + + rowsUnresolved |= row.RowsUnresolved; + } + + if (rowsUnresolved == true) + { + _Panel.ShowTreeButtons = true; + _Panel.ShowTreeLines = true; + + _Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand; + _Panel.SuperGrid.BeforeExpand += SuperGridBeforeExpand; + } + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region DeleteDataGridRow + + private void DeleteDataGridRow(int dataItemIndex) + { + GridRow row = FindDataGridRowIndex(dataItemIndex); + + if (row != null) + { + if (row.DataItem != null) + { + GridElement selItem = _Panel.SuperGrid.ActiveElement; + + UpdateRowsDataIndex(row.DataItemIndex, -1); + + row.DataItem = null; + row.DataItemIndex = -1; + + int index = row.RowIndex; + + if (_Panel.VirtualMode == true) + { + _Panel.VirtualRows.MaxRowIndex = index - 1; + _Panel.VirtualRowCount--; + + _Panel.InvalidateRender(); + + if (_Panel.AutoSelectDeleteBoundRows == false) + { + if (_Panel.ActiveRow != null) + index = _Panel.ActiveRow.RowIndex; + else + index = -1; + } + + if (index > _Panel.VirtualRowCount) + index = _Panel.VirtualRowCount - 1; + + if (index >= 0) + SelectRow(_Panel, index); + } + else + { + GridContainer cont = (GridContainer) row.Parent; + cont.Rows.RemoveAt(index); + + if (_Panel.AutoSelectDeleteBoundRows == true) + { + if (index >= cont.Rows.Count) + index--; + + if ((uint)index < cont.Rows.Count) + { + SelectRow(cont, index); + + row = cont.Rows[index] as GridRow; + + if (row != null) + CurrencyManager.Position = row.DataItemIndex; + } + } + else + { + SelectLastElement(selItem); + } + } + } + } + } + + #endregion + + #region SelectLastElement + + private void SelectLastElement(GridElement selItem) + { + _Panel.SuperGrid.NeedToUpdateIndicees = true; + _Panel.UpdateIndicees(_Panel, _Panel.Rows, true); + + if (selItem is GridCell) + _Panel.SetSelected((GridCell)selItem, true); + + else if (selItem is GridRow) + _Panel.SetSelected((GridRow)selItem, true); + } + + #endregion + + #region MoveDataGridRow + + private void MoveDataGridRow(int oldDataIndex, int newDataIndex) + { + if (_Panel.VirtualMode == true) + { + _Panel.VirtualRows.Clear(); + } + else + { + GridRow oldRow = FindDataGridRowIndex(oldDataIndex); + GridRow newRow = FindDataGridRowIndex(newDataIndex); + + if (oldRow != null && newRow != null) + { + GridContainer cont = (GridContainer) oldRow.Parent; + + int newIndex = newRow.RowIndex; + + if (oldRow.RowIndex < newRow.RowIndex) + { + for (int i = oldRow.RowIndex; i < newRow.RowIndex; i++) + { + cont.Rows[i] = cont.Rows[i + 1]; + + ((GridRow) cont.Rows[i]).DataItemIndex--; + ((GridRow) cont.Rows[i]).RowIndex--; + } + } + else + { + for (int i = oldRow.RowIndex; i > newRow.RowIndex; i--) + { + cont.Rows[i] = cont.Rows[i - 1]; + + ((GridRow) cont.Rows[i]).DataItemIndex++; + ((GridRow) cont.Rows[i]).RowIndex++; + } + } + + cont.Rows[newIndex] = oldRow; + + newRow.RowIndex = newIndex; + newRow.DataItemIndex = newDataIndex; + } + } + } + + #endregion + + #region UpdateDataGridRow + + private GridRow UpdateDataGridRow(IList list, int dataIndex) + { + GridRow row = FindDataGridRowIndex(dataIndex); + + if (row != null) + UpdateListRow(row, list[dataIndex]); + + return (row); + } + + #endregion + + #region UpdateListRow + + private void UpdateListRow(GridRow row, object o) + { + PropertyDescriptorCollection pdc = GetPdc(o); + + foreach (GridColumn col in _Panel.Columns) + { + if (col.ColumnIndex < row.Cells.Count) + { + PropertyDescriptor pd = FindPropertyDescriptor(pdc, col); + + if (pd != null) + { + object value = pd.GetValue(o); + object value2 = row.Cells[col.ColumnIndex].ValueEx; + + row.Cells[col.ColumnIndex].ValueEx = value; + + if (col.Visible == true) + row.Cells[col.ColumnIndex].InvalidateRender(); + + int cval = -2; + + if (_Panel.GroupColumns.Contains(col) == true) + { + if ((cval = CompareVal.CompareTo(value, value2)) != 0) + _Panel.NeedsGrouped = true; + } + + if (_Panel.KeepRowsSorted == true) + { + if (col.IsSortColumn == true) + { + if (cval == -2) + cval = CompareVal.CompareTo(value, value2); + + if (cval != 0) + { + if (row == _Panel.ActiveRow) + row.RowNeedsSorted = true; + else + _Panel.NeedsSorted = true; + } + } + } + } + } + } + + row.DataItem = o; + + DataRowView drv = o as DataRowView; + + if (drv != null) + { + if (drv.Row.RowState == DataRowState.Unchanged) + row.RowDirty = false; + } + + _Panel.NeedsFilterScan = true; + } + + #endregion + + #region UpdateGrouping + + private void UpdateGrouping() + { + if (_Panel.GroupColumns.Count > 0) + { + _Panel.NeedsGrouped = true; + + _Panel.InvalidateLayout(); + } + } + + #endregion + + #endregion + + #region FindDataGridRowIndex + + private GridRow FindDataGridRowIndex(int dataItemIndex) + { + if (_Panel.ActiveRow != null) + { + GridRow row = _Panel.ActiveRow as GridRow; + + if (row != null && + row.IsTempInsertRow == false && row.IsInsertRow == false) + { + if (row.DataItemIndex == dataItemIndex) + return (row); + } + } + + if (_Panel.VirtualMode == true) + return (FindDataGridVirtualRowIndex(dataItemIndex)); + + return (FindDataGridRealRowIndex(_Panel.Rows, dataItemIndex)); + } + + private GridRow FindDataGridVirtualRowIndex(int dataItemIndex) + { + if ((uint)dataItemIndex < _Panel.VirtualRowCount) + return (_Panel.VirtualRows[dataItemIndex]); + + return (null); + } + + private GridRow FindDataGridRealRowIndex( + IEnumerable items, int dataItemIndex) + { + foreach (GridElement item in items) + { + if (item is GridRow) + { + GridRow row = item as GridRow; + + if (row.IsTempInsertRow == false && row.IsInsertRow == false) + { + if (row.DataItemIndex == dataItemIndex) + return (row); + } + } + else if (item is GridGroup) + { + GridRow row = FindDataGridRealRowIndex(((GridGroup)item).Rows, dataItemIndex); + + if (row != null) + return (row); + } + } + + return (null); + } + + #endregion + + #region FindDataGridRow + + private GridRow FindDataGridRow(int dataItemIndex) + { + if (_Panel.ActiveRow != null) + { + GridRow row = _Panel.ActiveRow as GridRow; + + if (row != null && + row.IsTempInsertRow == false && row.IsInsertRow == false) + { + if (row.DataItem == CurrencyManager.List[dataItemIndex]) + return (row); + } + } + + if (_Panel.VirtualMode == true) + return (FindDataGridVirtualRowIndex(dataItemIndex)); + + return (FindDataGridRealRow(_Panel.Rows, dataItemIndex)); + } + + #region FindDataGridRealRow + + private GridRow FindDataGridRealRow(IEnumerable items, int dataItemIndex) + { + foreach (GridElement item in items) + { + if (item is GridRow) + { + GridRow row = item as GridRow; + + if (row.IsTempInsertRow == false && row.IsInsertRow == false) + { + if (row.DataItem == CurrencyManager.List[dataItemIndex]) + return (row); + } + } + else if (item is GridGroup) + { + GridRow row = FindDataGridRealRowIndex(((GridGroup)item).Rows, dataItemIndex); + + if (row != null) + return (row); + } + } + + return (null); + } + + #endregion + + #endregion + + #region SelectRow + + private void SelectRow(GridContainer cont, int index) + { + _Panel.LatentActiveContainer = cont; + _Panel.LatentActiveRowIndex = index; + } + + #endregion + + #region UpdateRowsDataIndex + + private void UpdateRowsDataIndex(int index, int n) + { + if (_Panel.VirtualMode == false) + UpdateRowsDataIndexEx(_Panel.Rows, index, n); + } + + private void UpdateRowsDataIndexEx( + IEnumerable items, int index, int n) + { + foreach (GridContainer item in items) + { + GridRow row = item as GridRow; + + if (row != null) + { + if (row.DataItemIndex >= index) + row.DataItemIndex += n; + } + + if (item.Rows.Count > 0) + UpdateRowsDataIndexEx(item.Rows, index, n); + } + } + + #endregion + + #region RemoveRow + + internal void RemoveRow(GridRow row) + { + if (CurrencyManager != null) + { + UpdateInProgress = true; + UpdatePosInProgress = true; + + try + { + int index = row.DataItemIndex; + + CurrencyManager.RemoveAt(index); + } + finally + { + UpdateInProgress = false; + UpdatePosInProgress = false; + + _Panel.UpdateRowCount(); + } + + if (row.DataItem != null) + UpdateRowsDataIndex(row.DataItemIndex, -1); + } + } + + #endregion + + #region InsertRow + + internal void InsertRow(int index, GridRow row) + { + if (CurrencyManager != null && _Pdc != null) + { + if (index > CurrencyManager.Count) + index = CurrencyManager.Count; + + UpdateInProgress = true; + UpdatePosInProgress = true; + + object dataSource = _Panel.DataSource; + string dataMember = _Panel.DataMember; + + try + { + while (dataSource is BindingSource) + { + BindingSource bs = (BindingSource)dataSource; + + dataSource = bs.DataSource; + + if (dataMember == null) + dataMember = bs.DataMember; + } + + if (dataSource is DataSet) + InsertDataSetRow((DataSet)dataSource, dataMember, index, row); + + else if (dataSource is DataTable) + InsertDataTableRow((DataTable)dataSource, index, row); + + else + InsertListRow(index, row); + } + finally + { + UpdateInProgress = false; + UpdatePosInProgress = false; + } + } + } + + #region InsertDataSetRow + + private void InsertDataSetRow(DataSet dataSet, + string dataMember, int index, GridRow row) + { + DataTable table = GetDataTable(dataSet, dataMember); + + if (table != null) + InsertDataTableRow(table, index, row); + } + + #endregion + + #region InsertDataTableRow + + private void InsertDataTableRow(DataTable table, int index, GridRow row) + { + DataRow drow = _TempDataRow ?? table.NewRow(); + + _TempDataRow = null; + + for (int i = 0; i < Pdc.Count; i++) + { + PropertyDescriptor pd = Pdc[i]; + + GridColumn col = FindGridColumn(_Panel, pd.Name); + + if (col != null) + { + object value = (col.ColumnIndex < row.Cells.Count) ? + row.Cells[col.ColumnIndex].ValueEx ?? DBNull.Value : DBNull.Value; + + drow[i] = value; + } + } + + UpdateRowsDataIndex(index, 1); + + row.DataItem = drow; + row.DataItemIndex = index; + + if (index < CurrencyManager.Count) + { + DataRowView drv = CurrencyManager.List[index] as DataRowView; + + if (drv != null) + { + int idx = table.Rows.IndexOf(drv.Row); + + if (idx >= 0) + index = idx; + } + + table.Rows.InsertAt(drow, index); + } + else + { + table.Rows.Add(drow); + } + } + + #endregion + + #region InsertListRow + + private void InsertListRow(int index, GridRow row) + { + if (Pdc.Count > 0) + { + Type type = Pdc[0].ComponentType; + + object item; + + if (type == typeof(DataRowView)) + item = ((DataView)_BaseDataSource).AddNew(); + else + item = Activator.CreateInstance(type); + + for (int i = 0; i < Pdc.Count; i++) + { + PropertyDescriptor pd = Pdc[i]; + + GridColumn col = FindGridColumn(_Panel, pd.Name); + + if (col != null) + { + object o = row.Cells[col.ColumnIndex].ValueEx; + + if (o != null && o is DBNull == false) + pd.SetValue(item, o); + } + } + + UpdateRowsDataIndex(index, 1); + + row.DataItem = item; + row.DataItemIndex = index; + + _UpdatePosInProgress = true; + + if (type != typeof(DataRowView)) + { + if (CurrencyManager != null) + CurrencyManager.List.Insert(index, item); + } + else + { + DataRowView dv = (DataRowView)item; + + dv.EndEdit(); + } + + _UpdatePosInProgress = false; + } + } + + #endregion + + #endregion + + #region GetDefaultValues + + internal void GetDefaultValues(GridRow row) + { + if (CurrencyManager != null) + { + object dataSource = _Panel.DataSource; + string dataMember = _Panel.DataMember; + + while (dataSource is BindingSource) + { + BindingSource bs = (BindingSource) dataSource; + + dataSource = bs.DataSource; + + if (dataMember == null) + dataMember = bs.DataMember; + } + + if (dataSource is DataSet) + GetDataSetDefaultValues((DataSet) dataSource, dataMember, row); + + else if (dataSource is DataTable) + GetTableDefaultValues((DataTable)dataSource, row); + } + + GridColumnCollection columns = _Panel.Columns; + + for (int i = 0; i < columns.Count; i++) + { + if (columns[i].DefaultNewRowCellValue != null) + row.Cells[i].ValueEx = columns[i].DefaultNewRowCellValue; + } + + if (_Panel.SuperGrid != null) + _Panel.SuperGrid.DoRowSetDefaultValuesEvent(_Panel, row, NewRowContext.RowInit); + } + + #region GetDataSetDefaultValues + + private void GetDataSetDefaultValues + (DataSet dataSet, string dataMember, GridRow row) + { + DataTable table = GetDataTable(dataSet, dataMember); + + if (table != null) + GetTableDefaultValues(table, row); + } + + #endregion + + #region GetTableDefaultValues + + private void GetTableDefaultValues(DataTable table, GridRow row) + { + _TempDataRow = table.NewRow(); + + UpdateForeignKey(table, _TempDataRow); + + for (int i = 0; i < Pdc.Count; i++) + { + GridColumn col = FindGridColumn(_Panel, Pdc[i].Name); + + if (col != null) + { + if (col.ColumnIndex < row.Cells.Count) + row.Cells[col.ColumnIndex].ValueEx = _TempDataRow[i]; + } + } + } + + #region UpdateForeignKey + + private void UpdateForeignKey(DataTable table, DataRow drow) + { + DataRelation dataRel = _Panel.DataRelation; + + if (dataRel != null && + dataRel.ParentColumns != null && dataRel.ChildColumns != null) + { + BindingSource bs = _Panel.DataSource as BindingSource; + + if (bs != null) + { + bs = bs.DataSource as BindingSource; + + if (bs != null && bs.Current != null) + UpdateDataRowForeignKey(dataRel, drow, bs.Current); + } + else + { + GridRow row = _Panel.Parent as GridRow; + + if (row != null) + UpdateDataRowForeignKey(dataRel, drow, row.DataItem); + } + } + } + + #region UpdateDataRowForeignKey + + private void UpdateDataRowForeignKey( + DataRelation dataRel, DataRow drow, object item) + { + DataRowView drv = item as DataRowView; + + if (drv != null) + { + for (int i = 0; i < dataRel.ParentColumns.Length; i++) + { + if (i < dataRel.ChildColumns.Length) + { + drow[dataRel.ChildColumns[i].ColumnName] = + drv[dataRel.ParentColumns[i].ColumnName]; + } + } + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetDataTable + + private DataTable GetDataTable(DataSet dataSet, string dataMember) + { + if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0) + dataMember = dataSet.Tables[0].TableName; + + if (_Panel.DataRelation == null) + _Panel.DataRelation = dataSet.Relations[dataMember]; + + DataTable table = (_Panel.DataRelation != null) + ? _Panel.DataRelation.ChildTable : dataSet.Tables[dataMember]; + + return (table); + } + + #endregion + + #region ReloadRow + + internal void ReloadRow(GridRow row) + { + if (CurrencyManager != null && _Pdc != null) + { + if ((uint)row.RowIndex < CurrencyManager.List.Count) + { + PropertyDescriptorCollection pdc = GetPdc(row.DataItem); + + foreach (GridCell cell in row.Cells) + { + GridColumn col = _Panel.Columns[cell.ColumnIndex]; + PropertyDescriptor pd = FindPropertyDescriptor(pdc, col); + + if (pd != null) + cell.ValueEx = pd.GetValue(row.DataItem); + } + } + } + } + + #endregion + + #region UpdateSuperGridSort + + private void UpdateSuperGridSort(bool reset) + { + if (reset == true || + (_Panel.SortColumns == null || _Panel.SortColumns.Count == 0)) + { + if (CurrencyManager != null) + { + if (_BaseDataSource is DataView) + { + SetSuperGridDataSetSort(((DataView)_BaseDataSource).Sort); + } + else if (_BaseDataSource is IBindingList) + { + SetSuperGridListSort((IBindingList)_BaseDataSource); + } + else if (_BaseDataSource is IListSource) + { + IList list = ((IListSource)_BaseDataSource).GetList(); + + if (list is IBindingList) + SetSuperGridListSort((IBindingList)list); + } + } + } + } + + #region SetSuperGridDataSetSort + + private void SetSuperGridDataSetSort(string sort) + { + _Panel.ClearSort(); + + if (string.IsNullOrEmpty(sort) == false) + { + const string cref = @"((\[(?\w+)\])|(?\w+))\s*(?ASC|DESC)*"; + + Regex p = new Regex(cref); + MatchCollection mc = p.Matches(sort); + + foreach (Match ma in mc) + { + GridColumn col = FindGridColumn(_Panel, ma.Groups["name"].Value); + + if (col != null) + { + SortDirection dir = SortDirection.Ascending; + + Group grp = ma.Groups["order"]; + + if (grp != null) + { + dir = grp.Value.Equals("DESC") + ? SortDirection.Descending : SortDirection.Ascending; + } + + _Panel.AddSort(col, dir); + } + } + + _Panel.SuperGrid.DoRowsSortedEvent(_Panel); + } + + _Panel.NeedsSorted = false; + } + + #endregion + + #region SetSuperGridListSort + + private void SetSuperGridListSort(IBindingList list) + { + _Panel.ClearSort(); + + if (list.SupportsSorting == true && list.IsSorted == true) + { + if (list.SortProperty != null) + { + string name = list.SortProperty.Name; + + GridColumn col = FindGridColumn(_Panel, name); + + if (col != null) + { + SortDirection dir = (list.SortDirection == ListSortDirection.Ascending) + ? SortDirection.Ascending + : SortDirection.Descending; + + _Panel.AddSort(col, dir); + } + + _Panel.SuperGrid.DoRowsSortedEvent(_Panel); + } + } + + _Panel.NeedsSorted = false; + } + + #endregion + + #endregion + + #region UpdateDataSourceSort + + internal void UpdateDataSourceSort() + { + if (CurrencyManager != null) + { + if (CurrencyManager.List.Count > 0) + { + DataRowView drv = CurrencyManager.List[0] as DataRowView; + + if (drv != null) + { + string sort = GetSortString(drv); + + drv.DataView.Sort = sort; + } + else if (_BaseDataSource is IBindingList) + UpdateListSort((IBindingList)_BaseDataSource); + + else if (_BaseDataSource is IListSource) + { + IList list = ((IListSource)_BaseDataSource).GetList(); + + if (list is IBindingList) + UpdateListSort((IBindingList)list); + } + } + + if (_Panel.VirtualMode == true) + _Panel.VirtualRows.Clear(); + } + } + + #endregion + + #region UpdateListSort + + private void UpdateListSort(IBindingList iBindingList) + { + if (iBindingList.SupportsSorting == true) + { + List sortColumns = _Panel.SortColumns; + + if (sortColumns != null && sortColumns.Count > 0) + { + IBindingListView blv = iBindingList as IBindingListView; + + if (blv != null && blv.SupportsAdvancedSorting == true) + { + PropertyDescriptorCollection pdc = GetPdc(null); + + ListSortDescription[] lsd = new ListSortDescription[sortColumns.Count]; + + for (int i = 0; i < sortColumns.Count; i++) + { + GridColumn col = sortColumns[i]; + + PropertyDescriptor pd = FindPropertyDescriptor(pdc, col); + + ListSortDirection dir = (col.SortDirection == SortDirection.Ascending) + ? ListSortDirection.Ascending + : ListSortDirection.Descending; + + lsd[i] = new ListSortDescription(pd, dir); + } + + blv.ApplySort(new ListSortDescriptionCollection(lsd)); + } + else + { + GridColumn col = sortColumns[0]; + + PropertyDescriptorCollection pdc = GetPdc(null); + PropertyDescriptor pd = FindPropertyDescriptor(pdc, col); + + if (pd != null) + { + ListSortDirection dir = (col.SortDirection == SortDirection.Ascending) + ? ListSortDirection.Ascending + : ListSortDirection.Descending; + + iBindingList.ApplySort(pd, dir); + } + } + } + else if (iBindingList.IsSorted == true) + { + iBindingList.RemoveSort(); + } + } + } + + #endregion + + #region GetSortString + + private string GetSortString(DataRowView drv) + { + List sortColumns = _Panel.SortColumns; + + if (sortColumns != null && sortColumns.Count > 0) + { + StringBuilder sb = new StringBuilder(); + + foreach (GridColumn column in sortColumns) + GetColumnSort(drv, column, sb); + + if (sb.Length > 0) + sb.Length--; + + return (sb.ToString()); + } + + return (null); + } + + #endregion + + #region GetColumnSort + + private void GetColumnSort( + DataRowView drv, GridColumn column, StringBuilder sb) + { + DataColumn dc = FindDataColumn(drv.DataView.Table, column); + + if (dc != null) + { + sb.Append("["); + sb.Append(dc.ColumnName); + sb.Append("]"); + sb.Append(column.SortDirection == SortDirection.Ascending ? " ASC," : " DESC,"); + } + } + + #endregion + + #region FlushRow + + internal bool FlushRow() + { + if (CurrencyManager != null) + { + while (true) + { + _UpdateInProgress = true; + _UpdatePosInProgress = true; + + try + { + CurrencyManager.EndCurrentEdit(); + break; + } + catch (Exception exp) + { + GridRow crow = null; + + if ((uint) CurrencyManager.Position < _Panel.Rows.Count) + { + crow = _Panel.Rows[CurrencyManager.Position] as GridRow; + + if (crow != null) + ReloadRow(crow); + } + + bool retry = false; + bool throwException = false; + + if (_Panel.SuperGrid.HasDataErrorHandler == true) + { + object value = crow; + + if (_Panel.SuperGrid.DoDataErrorEvent(_Panel, null, exp, + DataContext.RowFlush, ref value, + ref throwException, ref retry) == true) + { + return (false); + } + } + + if (throwException == true) + throw; + + if (retry == false) + return (false); + } + finally + { + _UpdateInProgress = false; + _UpdatePosInProgress = false; + } + } + } + + return (true); + } + + #endregion + + #region SuperGridLoadVirtualRow + + void SuperGridLoadVirtualRow(object sender, GridVirtualRowEventArgs e) + { + if (CurrencyManager != null && _Pdc != null) + { + GridRow row = e.GridRow; + GridRow vrow = _Panel.VirtualTempInsertRow; + + int index = e.Index; + + if (vrow != null) + { + if (index == vrow.RowIndex) + { + for (int i = 0; i < _Panel.Columns.Count; i++) + row.Cells[i].ValueEx = vrow.Cells[i].Value; + + row.RowNeedsSorted = true; + row.RowNeedsStored = true; + row.IsTempInsertRow = vrow.IsTempInsertRow; + + return; + } + + if (index > vrow.RowIndex) + index--; + } + + if (index == _Panel.VirtualRowCount) + { + if (_Panel.ShowInsertRow == true) + { + vrow = _Panel.VirtualInsertRow; + + if (vrow != null) + { + for (int i = 0; i < _Panel.Columns.Count; i++) + row.Cells[i].ValueEx = vrow.Cells[i].Value; + + row.RowNeedsSorted = true; + row.RowNeedsStored = true; + row.IsTempInsertRow = vrow.IsTempInsertRow; + + return; + } + } + } + + if ((uint)index < CurrencyManager.List.Count) + { + row.DataItem = CurrencyManager.List[index]; + row.DataItemIndex = index; + + PropertyDescriptorCollection pdc = GetPdc(row.DataItem); + + foreach (GridColumn col in _Panel.Columns) + { + PropertyDescriptor pd = FindPropertyDescriptor(pdc, col); + + if (pd != null) + row.Cells[col.ColumnIndex].ValueEx = pd.GetValue(row.DataItem); + } + } + } + } + + #endregion + + #region Filter management + + #region UpdateFilter + + private bool _UpdatingFilter; + + internal void UpdateFilter() + { + if (CurrencyManager != null) + { + DataTable dt = null; + + if (_BaseDataSource is DataSet) + { + DataSet dataSet = _BaseDataSource as DataSet; + string dataMember = _BaseDataMember; + + if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0) + dataMember = dataSet.Tables[0].TableName; + + if (string.IsNullOrEmpty(dataMember) == false) + dt = dataSet.Tables[dataMember]; + } + else if (_BaseDataSource is DataTable) + { + dt = _BaseDataSource as DataTable; + } + + if (dt != null) + { + _UpdatingFilter = true; + + try + { + dt.DefaultView.RowFilter = GetDataViewRowFilter(); + } + catch (Exception exp) + { + MessageBoxEx.Show(exp.Message); + } + finally + { + Refresh(); + + _UpdatingFilter = false; + } + } + } + } + + #endregion + + #region GetDataViewRowFilter + + private string GetDataViewRowFilter() + { + StringBuilder sb = new StringBuilder(); + + if (String.IsNullOrEmpty(_Panel.FilterExpr) == false) + { + sb.Append("("); + sb.Append(_Panel.FilterExpr); + sb.Append(") && "); + } + + foreach (GridColumn col in _Panel.Columns) + { + if (String.IsNullOrEmpty(col.FilterExpr) == false) + { + sb.Append("("); + sb.Append(col.FilterExpr); + sb.Append(") and "); + } + } + + if (sb.Length > 0) + sb.Length -= 4; + + string s = sb.ToString(); + + return (s); + } + + #endregion + + #endregion + + #region Begin/EndUpdate + + internal void BeginUpdate() + { + _BeginUpdateCount++; + } + + internal void EndUpdate() + { + if (_BeginUpdateCount > 0) + { + --_BeginUpdateCount; + + if (_BeginUpdateCount == 0) + Refresh(); + } + } + + #endregion + + #region Refresh + + private void Refresh() + { + if (CurrencyManager != null) + { + CurrencyManager.Refresh(); + + if (_Panel.VirtualMode == true) + _Panel.VirtualRowCount = _CurrencyManager.Count; + } + + _Panel.UpdateRowCount(); + } + + #endregion + + #region Dispose + + /// + /// Data Binder Dispose + /// + public void Dispose() + { + Clear(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/EEval.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/EEval.cs new file mode 100644 index 00000000..7bb3247e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/EEval.cs @@ -0,0 +1,1374 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Expression evaluator + /// + public class EEval + { + #region Private data + + private int _TCount; + private int _PCount; + private ETokens[] _PTokens = new ETokens[10]; + private List _PfTokens = new List(); + + private GridCell _Cell; + private GridPanel _GridPanel; + private List _UsedCells; + + private string _Source; + private List _StringPool = new List(); + + private object _Tag; + + #endregion + + /// + /// Expression evaluator constructor + /// + ///Associated GridPanel + ///'Excel-like' expression (eg. =d4+d5) + public EEval(GridPanel gridPanel, string source) + : this(null, source, new List()) + { + _GridPanel = gridPanel; + } + + internal EEval(GridCell cell, string source) + : this(cell, source, new List()) + { + } + + private EEval(GridCell cell, string source, List usedCells) + { + _Cell = cell; + _UsedCells = usedCells; + + if (_Cell != null) + _GridPanel = cell.GridPanel; + + Source = source; + } + + #region Public properties + + #region Cell + + /// + /// Gets the associated Grid Cell, if any + /// + public GridCell Cell + { + get { return (_Cell); } + } + + #endregion + + #region GridPanel + + /// + /// Gets the associated Grid Panel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + #endregion + + #region Source + + /// + /// Gets or sets the expression source + /// + public string Source + { + get { return (_Source); } + + set + { + _Source = value; + + Tokenize(value); + } + } + + #endregion + + #region Tag + + /// + /// Gets or sets user-defined data associated with the object + /// + public object Tag + { + get { return (_Tag); } + set { _Tag = value; } + } + + #endregion + + #endregion + + #region Tokenize code + + private void Tokenize(string source) + { + const string sref = @"([\.]|[a-zA-Z_]+|""[^""]+"")\s*([\.]|\d+)"; + + Regex p = new Regex( + "(" + sref + "\\s*:\\s*" + sref + ")|(" + sref + ")|" + + "([a-zA-Z0-9.]+)|" + + "\"([^\"]+)\"|" + + "([()+\\-*/%,|&\\^])|(<<)|(>>)"); + + MatchCollection mc = p.Matches(source); + + Expr(mc); + + ETokens t = GetToken(mc); + + if (t != ETokens.BadToken) + throw new Exception("Expression error."); + } + + #region Expr + + /// + /// Main expression entry routine + /// + private void Expr(MatchCollection mc) + { + Term1(mc); + + ETokens t = GetToken(mc); + + while (t == ETokens.BitwiseOr) + { + Term1(mc); + + _PfTokens.Add(t); + + t = GetToken(mc); + } + + PutToken(t); + } + + #endregion + + #region Term1 + + /// + /// Handles the ^ operator + /// + private void Term1(MatchCollection mc) + { + Term2(mc); + + ETokens t = GetToken(mc); + + while (t == ETokens.BitwiseXor) + { + Term2(mc); + + _PfTokens.Add(t); + + t = GetToken(mc); + } + + PutToken(t); + } + + #endregion + + #region Term2 + + /// + /// Handles the Ampersand operator + /// + private void Term2(MatchCollection mc) + { + Term3(mc); + + ETokens t = GetToken(mc); + + while (t == ETokens.BitwiseAnd) + { + Term3(mc); + + _PfTokens.Add(t); + + t = GetToken(mc); + } + + PutToken(t); + } + + #endregion + + #region Term3 + + /// + /// Handles the shift left and right operators + /// + private void Term3(MatchCollection mc) + { + Term4(mc); + + ETokens t = GetToken(mc); + + while (t == ETokens.ShiftLeft || t == ETokens.ShiftRight) + { + Term4(mc); + + _PfTokens.Add(t); + + t = GetToken(mc); + } + + PutToken(t); + } + + #endregion + + #region Term4 + + /// + /// Handles %, *, and / operators + /// + private void Term4(MatchCollection mc) + { + Term5(mc); + + ETokens t = GetToken(mc); + + while (t == ETokens.Add || t == ETokens.Subtract) + { + Term5(mc); + + _PfTokens.Add(t); + + t = GetToken(mc); + } + + PutToken(t); + } + + #endregion + + #region Term5 + + /// + /// Handles %, *, and / operators + /// + private void Term5(MatchCollection mc) + { + Factor(mc); + + ETokens t = GetToken(mc); + + while (t == ETokens.Mod || + t == ETokens.Multiply || t == ETokens.Divide) + { + Factor(mc); + + _PfTokens.Add(t); + + t = GetToken(mc); + } + + PutToken(t); + } + + #endregion + + #region Factor + + /// + /// Handles factor processing + /// + private void Factor(MatchCollection mc) + { + ETokens t = GetToken(mc); + + int n = 0; + + // Unary operators + + while (t == ETokens.Add || t == ETokens.Subtract) + { + if (t == ETokens.Subtract) + n++; + + t = GetToken(mc); + } + + // Operand processing + + if (t < ETokens.Operator) + { + if (Function(mc, t) == false) + _PfTokens.Add(t); + } + else if (t == ETokens.LParen) + { + Expr(mc); + + t = GetToken(mc); + + if (t != ETokens.RParen) + throw new Exception("Expecting right parenthesis."); + } + else + { + PutToken(t); + } + + if (n % 2 == 1) + { + if (_PfTokens.Count == 0) + throw new Exception("Invalid expression."); + + _PfTokens.Add(ETokens.Negate); + } + } + + #endregion + + #region Function + + /// + /// Handles function parsing + /// + /// + /// + /// + private bool Function(MatchCollection mc, ETokens e) + { + string s = _StringPool[(int)e].ToUpper(); + + ETokens t = GetFunction(mc, s); + + if (t != ETokens.BadToken) + { + _PfTokens.Add(t); + + t = GetToken(mc); + + if (t != ETokens.LParen) + throw new Exception("Expecting left parenthesis."); + + ParameterList(mc, e); + + t = GetToken(mc); + + if (t != ETokens.RParen) + throw new Exception("Expecting right parenthesis."); + + return (true); + } + + return (false); + } + + #region GetFunction + + /// + /// Determines whether the parsed string + /// is a one of our function keywords + /// + /// + /// + /// + private ETokens GetFunction(MatchCollection mc, string s) + { + ETokens t = GetToken(mc); + + if (t == ETokens.LParen) + { + PutToken(t); + + switch (s) + { + case "AVG": + return (ETokens.Avg); + + case "CEILING": + return (ETokens.Ceiling); + + case "FLOOR": + return (ETokens.Floor); + + case "MIN": + return (ETokens.Min); + + case "MAX": + return (ETokens.Max); + + case "ROUND": + return (ETokens.Round); + + case "SUM": + return (ETokens.Sum); + + default: + return (ETokens.User); + } + } + + PutToken(t); + + return (ETokens.BadToken); + } + + #endregion + + #endregion + + #region ParameterList + + /// + /// Handles function parameters + /// + private void ParameterList(MatchCollection mc, ETokens e) + { + int n = 0; + + if (_PfTokens[_PfTokens.Count - 1] == ETokens.User) + { + _PfTokens.Add(e); + n++; + } + + ETokens t = GetToken(mc); + + while (t != ETokens.RParen && t != ETokens.BadToken) + { + PutToken(t); + + int count = _PfTokens.Count; + + Expr(mc); + + if (_PfTokens.Count > count) + n++; + + t = GetToken(mc); + + if (t != ETokens.Comma) + break; + + t = GetToken(mc); + } + + PutToken(t); + + _PfTokens.Add(ETokens.Function); + _PfTokens.Add((ETokens) n); + } + + #endregion + + #region GetToken + + /// + /// Gets the next parsed token + /// + /// + private ETokens GetToken(MatchCollection mc) + { + ETokens t = ETokens.BadToken; + + if (_PCount > 0) + { + t = _PTokens[--_PCount]; + } + else + { + if (_TCount < mc.Count) + { + string s = mc[_TCount].Value; + + switch (s) + { + case "|": + t = ETokens.BitwiseOr; + break; + + case "^": + t = ETokens.BitwiseXor; + break; + + case "&": + t = ETokens.BitwiseAnd; + break; + + case "<<": + t = ETokens.ShiftLeft; + break; + + case ">>": + t = ETokens.ShiftRight; + break; + + case "+": + t = ETokens.Add; + break; + + case "-": + t = ETokens.Subtract; + break; + + case "*": + t = ETokens.Multiply; + break; + + case "/": + t = ETokens.Divide; + break; + + case "%": + t = ETokens.Mod; + break; + + case "(": + t = ETokens.LParen; + break; + + case ")": + t = ETokens.RParen; + break; + + case ",": + t = ETokens.Comma; + break; + + default: + int index = _StringPool.IndexOf(s); + + if (index < 0) + { + _StringPool.Add(s); + + index = _StringPool.Count - 1; + } + + t = (ETokens)(index); + break; + } + + _TCount++; + } + } + + return (t); + } + + #endregion + + #region PutToken + + /// + /// Saves the given token for future use + /// + /// + private void PutToken(ETokens t) + { + _PTokens[_PCount++] = t; + } + + #endregion + + #endregion + + #region Evaluate + + /// + /// Evaluates the previously tokenized code + /// + /// + public object Evaluate() + { + _UsedCells.Clear(); + + if (_Cell != null) + _UsedCells.Add(_Cell); + + return (EvaluateEx()); + } + + internal object EvaluateEx() + { + Stack myStack = new Stack(); + + for (int i = 0; i < _PfTokens.Count; i++) + { + if (_PfTokens[i] < ETokens.Operator) + { + myStack.Push(_StringPool[(int)_PfTokens[i]]); + } + else if (_PfTokens[i] > ETokens.Functions) + { + myStack.Push(_PfTokens[i]); + } + else + { + if (_PfTokens[i] == ETokens.Negate) + { + object value = ProcessValue(myStack.Pop()); + + if (value is double == false) + throw new Exception("Invalid negation value"); + + myStack.Push(-(double)value); + } + else if (_PfTokens[i] == ETokens.Function) + { + if (++i == _PfTokens.Count) + throw new Exception("Expecting function parameter count"); + + EvalFunction(myStack, (int)_PfTokens[i]); + } + else + { + object value1 = ProcessValue(myStack.Pop()); + object value2 = ProcessValue(myStack.Pop()); + + if (value1 == null || value2 == null) + { + if (value1 == null && value2 == null) + value1 = value2 = 0d; + + else if (value1 == null) + { + if (value2 is string) + value1 = ""; + else + value1 = 0d; + } + else + { + if (value1 is string) + value2 = ""; + else + value2 = 0d; + } + } + + if (value1 is string || value2 is string) + OpStringValue(myStack, _PfTokens[i], value1.ToString(), value2.ToString()); + else + OpDoubleValue(myStack, _PfTokens[i], (double)value1, (double)value2); + } + } + } + + if (myStack.Count > 0) + return (ProcessValue(myStack.Pop())); + + return (0); + } + + #region OpStringValue + + private void OpStringValue(Stack myStack, ETokens op, string s1, string s2) + { + switch (op) + { + case ETokens.Add: + myStack.Push(s2 + s1); + break; + + default: + throw new Exception("Invalid string operation."); + } + } + + #endregion + + #region OpDoubleValue + + private void OpDoubleValue( + Stack myStack, ETokens op, double d1, double d2) + { + switch (op) + { + case ETokens.BitwiseAnd: + myStack.Push((double)((int)d2 & (int)d1)); + break; + + case ETokens.BitwiseOr: + myStack.Push((double)((int)d2 | (int)d1)); + break; + + case ETokens.BitwiseXor: + myStack.Push((double)((int)d2 ^ (int)d1)); + break; + + case ETokens.Add: + myStack.Push(d2 + d1); + break; + + case ETokens.Subtract: + myStack.Push(d2 - d1); + break; + + case ETokens.Multiply: + myStack.Push(d2 * d1); + break; + + case ETokens.Divide: + myStack.Push(d2 / d1); + break; + + case ETokens.Mod: + myStack.Push(d2 % d1); + break; + + case ETokens.ShiftLeft: + myStack.Push((double)((int)d2 << (int)d1)); + break; + + case ETokens.ShiftRight: + myStack.Push((double)((int)d2 >> (int)d1)); + break; + } + } + + #endregion + + #region EvalFunction + + /// + /// Evaluates the current function + /// + /// + /// + private void EvalFunction(Stack myStack, int count) + { + object[] args = new object[count]; + + for (int i = count - 1; i >= 0; i--) + args[i] = myStack.Pop(); + + switch ((ETokens)myStack.Pop()) + { + case ETokens.Avg: + myStack.Push(Avg(args)); + break; + + case ETokens.Ceiling: + myStack.Push(Ceiling(args)); + break; + + case ETokens.Floor: + myStack.Push(Floor(args)); + break; + + case ETokens.Min: + myStack.Push(Min(args)); + break; + + case ETokens.Max: + myStack.Push(Max(args)); + break; + + case ETokens.Round: + myStack.Push(Round(args)); + break; + + case ETokens.Sum: + myStack.Push(Sum(args)); + break; + + case ETokens.User: + myStack.Push(User(args)); + break; + } + } + + #region Average + + /// + /// Calculates the average of the given set of values + /// + /// + /// + private double Avg(IEnumerable args) + { + double d = 0; + int count = 1; + + foreach (object o in args) + { + object value = ProcessValue(o, ref count); + + if (value is double) + d += (double) value; + else + throw new Exception("Can't AVERAGE non-numeric data."); + } + + return (d / count); + } + + #endregion + + #region Ceiling + + /// + /// Returns the smallest whole value + /// greater than or equal to the given value. + /// + /// + /// + private double Ceiling(object[] args) + { + if (args.Length != 1) + throw new Exception("Ceiling(): Invalid number of arguments."); + + object value = ProcessValue(args[0]); + + if (value is double == false) + throw new Exception("Ceiling(): Invalid data type."); + + return (Math.Ceiling((double)value)); + } + + #endregion + + #region Floor + + /// + /// Returns the largest whole value + /// less than or equal to the given value. + /// + /// + /// + private double Floor(object[] args) + { + if (args.Length != 1) + throw new Exception("Floor(): Invalid number of arguments."); + + object value = ProcessValue(args[0]); + + if (value is double == false) + throw new Exception("Floor(): Invalid data type."); + + return (Math.Floor((double)value)); + } + + #endregion + + #region Minimum + + /// + /// Calculates the minimum from the given set of values + /// + /// + /// + private double Min(ICollection args) + { + if (args.Count == 0) + return (0); + + double d = double.PositiveInfinity; + + foreach (object o in args) + { + double n = ProcessMinMaxValue(o, true); + + if (n < d) + d = n; + } + + return (d); + } + + #endregion + + #region Maximum + + /// + /// Calculates the maximum from the given set of values + /// + /// + /// + private double Max(ICollection args) + { + if (args.Count == 0) + return (0); + + double d = double.NegativeInfinity; + + foreach (object o in args) + { + double n = ProcessMinMaxValue(o, false); + + if (n > d) + d = n; + } + + return (d); + } + + #endregion + + #region Round + + /// + /// Returns the largest whole value + /// less than or equal to the given value. + /// + /// + /// + private double Round(object[] args) + { + if (args.Length != 1 && args.Length != 2) + throw new Exception("Round(): Invalid number of arguments."); + + object value = ProcessValue(args[0]); + object decimals = args.Length == 2 ? ProcessValue(args[1]) : 0d; + + if (value is double == false) + throw new Exception("Round(): Invalid value type."); + + if (decimals is double == false) + throw new Exception("Round(): Invalid decimals type."); + + return (Math.Round((double)value, Convert.ToInt32(decimals))); + } + + #endregion + + #region Sum + + /// + /// Calculates the sum of the given set of values + /// + /// + /// + private double Sum(IEnumerable args) + { + double d = 0; + int count = 0; + + foreach (object o in args) + { + object value = ProcessValue(o, ref count); + + if (value is double) + d += (double)value; + else + throw new Exception("Can't SUM non-numeric data."); + } + + return (d); + } + + #endregion + + #region User + + /// + /// Calculates the sum of the given set of values + /// + /// + /// + private object User(object[] args) + { + object d = null; + int count = 0; + + object[] uargs = new object[args.Length]; + + for (int i = 0; i < args.Length; i++) + uargs[i] = ProcessValue(args[i], ref count); + + _GridPanel.SuperGrid.DoCellUserFunctionEvent(_Cell, uargs, ref d); + + return (d); + } + + #endregion + + #region ProcessValue + + /// + /// Process the given object value + /// + /// + /// + private object ProcessValue(object o) + { + int count = 0; + + return (ProcessValue(o, ref count)); + } + + private object ProcessValue(object o, ref int count) + { + count = 1; + + if (o is double) + return (double)o; + + if (o is string) + { + string s = (string)o; + + if (s.Length > 0) + { + if (s[0] == '.' || s[0] == '"' || char.IsLetter(s[0]) == true) + { + object d = null; + + List cells = GetCellReferences(s); + + if (cells != null && cells.Count > 0) + { + foreach (GridCell cell in cells) + { + object n; + + if (ProcessCellValue(cell, out n) == true) + { + if (d == null) + { + d = n; + } + else + { + if (n is string || d is string) + d = d + n.ToString(); + else + d = (double)d + (double)n; + } + + count++; + } + } + } + else + { + return (s); + } + + return (d); + } + + return (GetValue(s)); + } + } + + return (0d); + } + + #endregion + + #region ProcessMinMaxValue + + /// + /// Processes the given MinMax object value + /// + /// + /// + /// + private double ProcessMinMaxValue(object o, bool min) + { + if (o is double) + return (double) o; + + if (o is string) + { + string s = (string)o; + + if (s.Length > 0) + { + if (s[0] == '.' || s[0] == '"' || char.IsLetter(s[0]) == true) + { + double d = 0; + + IEnumerable cells = GetCellReferences(s); + + bool valueSet = false; + + foreach (GridCell cell in cells) + { + object value; + + if (ProcessCellValue(cell, out value) == true) + { + if (value is double == false) + throw new Exception("Cannot Min/Max non-numeric values."); + + double n = (double)value; + + if (valueSet == false || (min ? n < d : n > d)) + { + d = n; + + valueSet = true; + } + } + } + + return (d); + } + + return ((double)GetValue(s)); + } + } + + return (0); + } + + #endregion + + #region ProcessCellValue + + /// + /// Processes the given cell reference value + /// + /// + /// + /// + private bool ProcessCellValue(GridCell cell, out object value) + { + value = cell.Value ?? ""; + + string s = value.ToString(); + + if (string.IsNullOrEmpty(s) == false) + { + if (s[0] == '=') + { + if (_UsedCells.Contains(cell) == true) + throw new Exception("Recursive cell reference"); + + _UsedCells.Add(cell); + + EEval eval = new EEval(cell, s, _UsedCells); + + value = eval.EvaluateEx(); + + _UsedCells.Remove(cell); + + return (true); + } + + value = GetValue(s); + + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region GetValue + + /// + /// Gets the double value from the given string + /// + /// + /// + private object GetValue(string s) + { + double d; + + if (double.TryParse(s, out d) == true) + return (d); + + return (s); + } + + #endregion + + #endregion + + #region GetCellReferences + + internal List GetCellReferences() + { + return (GetCellReferences(_Source)); + } + + private List GetCellReferences(string item) + { + const string sref1 = @"(?[\.]|[a-zA-Z_]+|""[^""]+"")\s*(?[\.]|\d+)"; + const string sref2 = @"(?[\.]|[a-zA-Z_]+|""[^""]+"")\s*(?[\.]|\d+)"; + + Regex reg = new Regex( + "(" + sref1 + ":" + sref2 + ")|" + + "(" + sref1 + ")"); + + MatchCollection mc = reg.Matches(item); + + if (mc.Count > 0) + { + List cells = new List(); + + for (int i = 0; i < mc.Count; i++) + AddCellRange(_GridPanel, cells, mc[i].Groups); + + return (cells); + } + + return (null); + } + + #region AddCellRange + + private void AddCellRange( + GridPanel panel, List cells, GroupCollection groups) + { + int row1; + int col1 = GetRowCol(panel, groups["col1"].Value, + groups["row1"].Value, out row1); + + int row2 = row1; + int col2 = col1; + + if (groups["col2"].Success == true) + { + col2 = GetRowCol(panel, groups["col2"].Value, + groups["row2"].Value, out row2); + } + + if (col1 >= 0 && col2 >= 0) + ProcessRange(panel, cells, col1, row1, col2, row2); + } + + #region GetRowCol + + private int GetRowCol(GridPanel panel, + string scol, string srow, out int row) + { + scol = scol.Replace("\"", ""); + + if (_Cell != null) + { + if (srow.Equals(".") == true) + row = _Cell.GridRow.RowIndex; + else + int.TryParse(srow, out row); + + if (scol.Equals(".") == true) + return (_Cell.ColumnIndex); + } + else + { + int.TryParse(srow, out row); + } + + int col; + if (int.TryParse(scol, out col) == true) + return (col); + + GridColumn column = panel.Columns[scol]; + + if (column != null) + return (column.ColumnIndex); + + return (-1); + } + + #endregion + + #region ProcessRange + + private void ProcessRange(GridPanel panel, + ICollection cells, int col1, + int row1, int col2, int row2) + { + GridContainer cont = _Cell.GridRow.Parent as GridContainer; + + if (cont != null) + { + for (int i = row1; i <= row2; i++) + { + for (int j = col1; j <= col2; j++) + { + GridCell cell = cont.GetCell(i, j); + + if (cell != null) + cells.Add(cell); + } + } + } + } + + #endregion + + #endregion + + #endregion + } + + #region enums + + #region ETokens + + /// + /// ETokens + /// + internal enum ETokens + { + // Anything before this, is an operand + + Operator = 512, + + // Normal operators + + Negate, + + LParen, + RParen, + + Multiply, + Divide, + Mod, + + Add, + Subtract, + + ShiftLeft, + ShiftRight, + + BitwiseAnd, + BitwiseOr, + BitwiseXor, + + Function, + Comma, + + BadToken, + + // Anything after this is a function + + Functions, + + Avg, + Ceiling, + Floor, + Max, + Min, + Round, + Sum, + User, + }; + + #endregion + + #endregion +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/ExpandDisplay.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/ExpandDisplay.cs new file mode 100644 index 00000000..75baf5a6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/ExpandDisplay.cs @@ -0,0 +1,54 @@ +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// CheckDisplay + /// + static public class ExpandDisplay + { + #region RenderButton + + /// + /// RenderButton + /// + /// + /// + /// + /// + static public Size RenderButton(Graphics g, + Image image, Rectangle buttonBounds, Rectangle clipBounds) + { + if (image != null && buttonBounds.IsEmpty == false) + { + Rectangle r = buttonBounds; + r.Width++; + r.Height++; + + Size isize = Dpi.Size(image.Size); + + if (r.Width > isize.Width) + { + r.X += (r.Width - isize.Width) / 2; + r.Width = isize.Width; + } + + if (r.Height > isize.Height) + { + r.Y += (r.Height - isize.Height) / 2; + r.Height = isize.Height; + } + + r.Intersect(clipBounds); + + g.DrawImageUnscaledAndClipped(image, r); + + return (r.Size); + } + + return (Size.Empty); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/FloatWindow.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/FloatWindow.Designer.cs new file mode 100644 index 00000000..193d8bcb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/FloatWindow.Designer.cs @@ -0,0 +1,51 @@ +namespace DevComponents.DotNetBar.SuperGrid +{ + partial class FloatWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // FloatWindow + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.CausesValidation = false; + this.ClientSize = new System.Drawing.Size(90, 23); + this.ControlBox = false; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FloatWindow"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.ResumeLayout(false); + + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/FloatWindow.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/FloatWindow.cs new file mode 100644 index 00000000..a6b8e2de --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/FloatWindow.cs @@ -0,0 +1,48 @@ +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// FloatWindow + /// + public partial class FloatWindow : Form + { + /// + /// Constructor + /// + public FloatWindow() + { + InitializeComponent(); + + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + SetStyle(ControlStyles.Selectable, false); + } + + const int WS_EX_NOACTIVATE = 0x08000000; + + /// + /// CreateParams + /// + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + + cp.ExStyle |= WS_EX_NOACTIVATE; + + return (cp); + } + } + + /// + /// ShowWithoutActivation + /// + protected override bool ShowWithoutActivation + { + get { return true; } + } + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/FloatWindow.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/FloatWindow.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/FloatWindow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridCaption.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridCaption.cs new file mode 100644 index 00000000..847a0f8b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridCaption.cs @@ -0,0 +1,106 @@ +using System.ComponentModel; +using System.Drawing; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridCaption + /// + public class GridCaption : GridTextRow + { + #region Constructors + + /// + /// GridCaption + /// + public GridCaption() + : this(null) + { + } + + /// + /// GridCaption + /// + /// + public GridCaption(string text) + : base(text) + { + } + + #endregion + + #region Hidden properties + + #region RowHeaderVisibility + + /// + /// RowHeaderVisibility + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new RowHeaderVisibility RowHeaderVisibility + { + get { return (base.RowHeaderVisibility); } + } + + #endregion + + #endregion + + #region RenderBorder + + /// + /// RenderBorder + /// + /// + /// + /// + /// + protected override void RenderBorder(Graphics g, + GridPanel panel, GridPanelVisualStyle pstyle, Rectangle r) + { + using (Pen pen = new Pen(pstyle.HeaderLineColor)) + { + r.Height--; + g.DrawLine(pen, r.X, r.Bottom, r.Right - 1, r.Bottom); + } + } + + #endregion + + #region CanShowRowHeader + + /// + /// CanShowRowHeader + /// + /// + /// + protected override bool CanShowRowHeader(GridPanel panel) + { + return (false); + } + + #endregion + + #region Style support + + /// + /// ApplyStyleEx + /// + /// + /// + protected override void ApplyStyleEx(TextRowVisualStyle style, StyleType[] css) + { + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.CaptionStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.CaptionStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.CaptionStyles[cs]); + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridCell.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridCell.cs new file mode 100644 index 00000000..fc3b32ec --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridCell.cs @@ -0,0 +1,8014 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Globalization; +using System.Media; +using System.Reflection; +using System.Windows.Forms; +using System.Windows.Forms.VisualStyles; +using DevComponents.DotNetBar.SuperGrid.Primitives; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.SuperGrid.TextMarkup; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Represents grid cell. + /// + public class GridCell : GridElement, IComparable, IDisposable + { + #region Constants + + private const int CheckBoxSpacing = 3; + + #endregion + + #region Static variables + + private static CellInfoWindow _cellInfoWindow; + + private static CellArea _hitArea; + private static CellArea _lastHitArea; + private static GridCell _hitCell; + + private static CellArea _mouseDownHitArea; + private static GridCell _mouseDownHitCell; + private static Point _mouseDownPoint; + private static IGridCellEditControl _mouseRenderer; + + private static bool _mouseInItem; + private static bool _mouseDownInItem; + private static bool _needsMouseEnter; + private static bool _dragSelection; + private static bool _dragStarted; + + private static int _anchorRowIndex; + private static int _anchorColumnIndex; + + private static string _toolTipText; + + #endregion + + #region Private variables + + private int _ColumnIndex; + private int _IndentLevel; + + private Size _CellSize; + private Size _ContentSize; + private Size _MeasuredSize; + + private Rectangle _Bounds; + private Rectangle _BackBounds; + + private string _InfoText; + private Image _InfoImage; + + private Cs _States; + private EditorInfo _EditorInfo; + + private ushort _BoundsUpdateCount; + private ushort _ColumnMeasureCount; + private ushort _DataResetCount; + private ushort _MergeUpdateCount; + private ushort _RowMeasureCount; + private ushort _SelectionClearCount; + private ushort _SelectionUpdateCount; + private ushort _StyleUpdateCount; + + private object _Value; + private object _ExpValue; + + private CellVisualStyles _Styles; + private CellVisualStyles _EffectiveStyles; + + #endregion + + #region Constructors + + /// + /// GridCell + /// + public GridCell() + { + SetState(Cs.AllowEdit, true); + } + + /// + /// GridCell + /// + /// + public GridCell(object value) + : this() + { + _Value = value; + } + + #endregion + + #region Internal properties + + #region AllowNullMerge + + internal bool AllowNullMerge + { + get + { + Tbool ns = GridColumn.AllowNullCellMerge; + + if (ns != Tbool.NotSet) + return (ns == Tbool.True ? true : false); + + return (GridPanel.AllowNullCellMerge); + } + } + + #endregion + + #region CanModify + + internal bool CanModify + { + get + { + GridColumn col = GridColumn; + + if (col == null || (col.AllowEdit == false || col.AllowSelection == false)) + return (false); + + GridRow row = GridRow; + + if (row == null || (row.AllowEdit == false || row.AllowSelection == false || row.IsDeleted == true)) + return (false); + + GridPanel panel = GridPanel; + + if (panel == null || (panel.AllowEdit == false || panel.AllowSelection == false)) + return (false); + + if (Visible == false || AllowEdit == false || + AllowSelection == false || IsEmptyCell == true || IsReadOnly == true) + { + return (false); + } + + return (true); + } + } + + #endregion + + #region CanModifyMerge + + internal bool CanModifyMerge + { + get + { + if (CanModify == false) + return (false); + + return (Merged == false || MergeSuspended == true); + } + } + + #endregion + + #region AnySelected + + internal bool AnySelected + { + get { return (TestState(Cs.AnySelected)); } + set { SetState(Cs.AnySelected, value); } + } + + #endregion + + #region CellSize + + internal Size CellSize + { + get { return (_CellSize); } + set { _CellSize = value; } + } + + #endregion + + #region CellEditMode + + internal CellEditMode CellEditMode + { + get + { + IGridCellEditControl editor = (EditControl ?? (GridColumn != null ? GridColumn.EditControl : null)); + + if (editor == null) + editor = GetInternalEditControl(); + + if (editor != null) + return (editor.CellEditMode); + + return (CellEditMode.InPlace); + } + } + + #endregion + + #region CheckBoxBounds + + internal Rectangle CheckBoxBounds + { + get { return (GridRow.CheckBoxBounds); } + } + + #endregion + + #region ContentSize + + internal Size ContentSize + { + get { return(_ContentSize); } + } + + #endregion + + #region RowContainer + + internal GridContainer RowContainer + { + get + { + GridRow row = GridRow; + + if (row != null) + return (row.Parent as GridContainer); + + return (null); + } + } + + #endregion + + #region HitArea + + internal CellArea HitArea + { + get { return (_hitArea); } + set { _hitArea = value; } + } + + #endregion + + #region IndentLevel + + internal int IndentLevel + { + get { return (_IndentLevel); } + set { _IndentLevel = value; } + } + + #endregion + + #region IsDragSelection + + internal bool IsDragSelection + { + get { return (_dragSelection); } + set { _dragSelection = value; } + } + + #endregion + + #region IsDragStarted + + internal bool IsDragStarted + { + get { return (_dragStarted); } + set { _dragStarted = value; } + } + + #endregion + + #region MergeUpdateCount + + internal ushort MergeUpdateCount + { + get { return (_MergeUpdateCount); } + set { _MergeUpdateCount = value; } + } + + #endregion + + #region MeasuredSize + + internal Size MeasuredSize + { + get { return (_MeasuredSize); } + } + + #endregion + + #region Modified + + internal bool Modified + { + get { return (TestState(Cs.Modified)); } + set { SetState(Cs.Modified, value); } + } + + #endregion + + #region MouseRenderer + + internal IGridCellEditControl MouseRenderer + { + get { return (_mouseRenderer); } + set { _mouseRenderer = value; } + } + + #endregion + + #region NeedsMeasured + + internal override bool NeedsMeasured + { + get + { + if (_ColumnMeasureCount != GridColumn.MeasureCount) + return (true); + + if (_RowMeasureCount != GridRow.MeasureCount) + return (true); + + return (base.NeedsMeasured); + } + + set + { + if (value == false) + { + _ColumnMeasureCount = GridColumn.MeasureCount; + _RowMeasureCount = GridRow.MeasureCount; + } + + base.NeedsMeasured = value; + } + } + + #endregion + + #region Selected + + internal bool Selected + { + get + { + if (AllowSelection == false) + return (false); + + GridPanel panel = GridPanel; + + if (panel != null) + { + if (_SelectionClearCount != panel.SelectionClearCount) + { + _SelectionClearCount = panel.SelectionClearCount; + + Selected = false; + + if (GridRow.ExpandedVisible(panel) == true) + panel.SetSelectedEx(this, false); + + InvalidateRender(); + } + } + + return (TestState(Cs.Selected)); + } + + set + { + SetState(Cs.Selected, value); + + GridPanel panel = GridPanel; + + if (panel != null) + _SelectionClearCount = panel.SelectionClearCount; + } + } + + #endregion + + #region SelectionUpdateCount + + internal ushort SelectionUpdateCount + { + get { return (_SelectionUpdateCount); } + set { _SelectionUpdateCount = value; } + } + + #endregion + + #region ValueEx + + internal object ValueEx + { + get { return (_Value); } + + set + { + if ((value != null && value.Equals(_Value) == false) || + (value == null && _Value != null)) + { + object oldValue = _Value; + _Value = value; + + OnValueChanged(oldValue, value, DataContext.CellValueLoad); + } + } + } + + #endregion + + #region ValueExx + + internal object ValueExx + { + get { return (_Value); } + set { _Value = value; } + } + + #endregion + + #endregion + + #region Public properties + + #region AllowEdit + + /// + /// Gets or sets whether the cell can be edited by the user. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the cell can be edited by the user.")] + public bool AllowEdit + { + get { return (TestState(Cs.AllowEdit)); } + + set + { + if (value != AllowEdit) + { + SetState(Cs.AllowEdit, value); + + OnPropertyChanged("AllowEdit"); + } + } + } + + #endregion + + #region BackBounds + + /// + /// Gets the scroll adjusted background bounds of the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle BackBounds + { + get + { + if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount) + UpdateBoundingRects(); + + return (_BackBounds); + } + } + + #endregion + + #region Bounds + + /// + /// Gets the scroll adjusted bounds of the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle Bounds + { + get + { + if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount) + UpdateBoundingRects(); + + GridPanel panel = GridPanel; + + if (panel != null) + { + CellRange cr = GetStateCellRange(); + + if (cr != null) + return (GetBounds(panel, cr.BackBounds)); + } + + return (_Bounds); + } + } + + #endregion + + #region BoundsRelative + + /// + /// Gets or sets the relative bounds of the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle BoundsRelative + { + get { return (base.BoundsRelative); } + + internal set + { + base.BoundsRelative = value; + + _BoundsUpdateCount = 0; + } + } + + #endregion + + #region CellBounds + + /// + /// Gets the clipped, scroll adjusted, bounding rectangle of the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle CellBounds + { + get + { + if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount) + UpdateBoundingRects(); + + GridPanel panel = GridPanel; + + if (panel != null) + return (GetCellBounds(panel)); + + return (Bounds); + } + } + + #endregion + + #region CellStyles + + /// + /// Gets or sets the visual styles assigned to the cell + /// + [Category("Style")] + [Description("Indicates the visual styles assigned to the cell.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CellVisualStyles CellStyles + { + get + { + if (_Styles == null) + { + _Styles = new CellVisualStyles(); + + StyleVisualChangeHandler(null, _Styles); + } + + return (_Styles); + } + + set + { + if (_Styles != value) + { + CellVisualStyles oldValue = _Styles; + + _Styles = value; + + OnCellStyleChanged("CellVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + private void OnCellStyleChanged(string property, + CellVisualStyles oldValue, CellVisualStyles newValue) + { + StyleVisualChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #endregion + + #region ColumnIndex + + /// + /// Gets the associated Column index for the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int ColumnIndex + { + get { return (_ColumnIndex); } + internal set { _ColumnIndex = value; } + } + + #endregion + + #region ContentBounds + + /// + /// Gets the scroll adjusted, content only, bounding rectangle of the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle ContentBounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + return (GetContentBounds(panel)); + + return (Rectangle.Empty); + } + } + + #endregion + + #region EditBounds + + /// + /// Gets the clipped, scroll adjusted, edit bounding rectangle of the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle EditBounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + return (GetEditBounds(panel)); + + return (Rectangle.Empty); + } + } + + #endregion + + #region EditControl + + /// + /// Gets the Edit Control used for the cell. The cell level + /// edit control is a non-shared control, created and based + /// upon the cell level EditorType and EditorParams properties. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IGridCellEditControl EditControl + { + get + { + if (_EditorInfo == null || _EditorInfo.EditorType == null) + return (null); + + if (_EditorInfo.EditControl == null) + EditControl = GetEditControl(_EditorInfo.EditorType, _EditorInfo.EditorParams); + + return (_EditorInfo.EditControl); + } + + internal set + { + if (_EditorInfo == null) + _EditorInfo = new EditorInfo(); + + if (_EditorInfo.EditControl != value) + { + if (_EditorInfo.EditControl != null) + { + if (_EditorInfo.EditControl.EditorPanel.Parent != null) + SuperGrid.Controls.Remove(_EditorInfo.EditControl.EditorPanel); + + _EditorInfo.EditControl.EditorCellBitmap = null; + + if (_EditorInfo.EditorType != null) + ((Control)_EditorInfo.EditControl).Dispose(); + } + + _EditorInfo.EditControl = value; + + if (_EditorInfo.EditControl != null) + { + if (_EditorInfo.EditControl.EditorPanel.Parent == null) + SuperGrid.Controls.Add(_EditorInfo.EditControl.EditorPanel); + } + } + } + } + + #endregion + + #region EditorDirty + + /// + /// Gets or sets whether the value + /// being edited has been changed in the editor + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool EditorDirty + { + get { return (GridRow.EditorDirty); } + + set + { + GridRow.EditorDirty = value; + + // If it is a non-modal edit event then we want the + // editor's dirty state to be cleared immediately. + + if (SuperGrid.EditorActive == false) + GridRow.EditorDirty = false; + } + } + + #endregion + + #region EditorParams + + /// + /// Gets or sets an array of arguments that match in number, + /// order, and type the parameters of the EditControl constructor + /// to invoke. If empty or null, the default constructor is invoked. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object[] EditorParams + { + get + { + if (_EditorInfo == null) + return (null); + + return (_EditorInfo.EditorParams); + } + + set + { + if (_EditorInfo == null) + _EditorInfo = new EditorInfo(); + + if (IsSameParams(_EditorInfo.EditorParams, value) == false) + { + _EditorInfo.EditorParams = value; + + EditControl = null; + RenderControl = null; + + NeedsMeasured = true; + + OnPropertyChangedEx("EditorParams", VisualChangeType.Layout); + } + + if (_EditorInfo.IsEmpty == true) + _EditorInfo = null; + } + } + + #region IsSameParams + + private bool IsSameParams(object[] p1, object[] p2) + { + if (p1 == null || p2 == null) + return (p1 == p2); + + if (p1.Length != p2.Length) + return (false); + + for (int i = 0; i < p1.Length; i++) + { + if (p1[i] != p2[i]) + return (false); + } + + return (true); + } + + #endregion + + #endregion + + #region EditorType + + /// + /// Indicates the cell editor type. This is the control type + /// used to perform the actual modification of the cell value + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the cell editor type. This is the control type used to perform the actual modification of the cell value.")] + [TypeConverter(typeof(EditTypeConverter))] + [Editor("DevComponents.SuperGrid.Design.EditTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public Type EditorType + { + get + { + if (_EditorInfo == null) + return (null); + + return (_EditorInfo.EditorType); + } + + set + { + if (value != null || _EditorInfo != null) + { + if (_EditorInfo == null) + _EditorInfo = new EditorInfo(); + + if (_EditorInfo.EditorType != value) + { + _EditorInfo.EditorType = value; + _EditorInfo.EditControl = null; + _EditorInfo.RenderControl = null; + + NeedsMeasured = true; + + OnPropertyChangedEx("EditorType", VisualChangeType.Layout); + } + + if (_EditorInfo.IsEmpty == true) + _EditorInfo = null; + } + } + } + + #endregion + + #region ExpValue + + /// + /// Gets the last evaluated expression value for the cell. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object ExpValue + { + get { return (_ExpValue); } + } + + #endregion + + #region FormattedValue + + /// + /// Gets the associated Formatted Value for the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string FormattedValue + { + get { return (GetFormattedValue()); } + } + + #endregion + + #region GridColumn + + /// + /// Gets the GridColumn associated with the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn GridColumn + { + get + { + GridPanel panel = GridPanel; + + if (panel == null && GridRow != null) + panel = GridRow.AllocPanel; + + if (panel != null) + { + if (_ColumnIndex < panel.Columns.Count) + return (panel.Columns[_ColumnIndex]); + } + + return (null); + } + } + + #endregion + + #region GridRow + + /// + /// Gets the GridRow associated with the cell. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridRow GridRow + { + get { return (Parent as GridRow); } + } + + #endregion + + #region HighLightBounds + + /// + /// Gets the scroll adjusted, bounding rectangle used + /// to highlight the cell contents when selected. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle HighLightBounds + { + get + { + Rectangle r = Rectangle.Empty; + GridPanel panel = GridPanel; + + if (panel != null) + { + switch (GetCellHighlightMode(panel)) + { + case CellHighlightMode.Content: + IGridCellEditControl editor = GetInternalRenderControl(); + + r = GetAdjustedBounds(ContentBounds); + r = GetEditPanelBounds(editor, r); + + r.Inflate(1, 1); + break; + + case CellHighlightMode.Partial: + r = GetAdjustedBounds(ContentBounds); + r.Inflate(1, 1); + break; + + case CellHighlightMode.Full: + r = GetAdjustedBounds(); + + Rectangle t = SViewRect; + + if (t.X == 0 && r.X == 0) + { + r.X += Dpi.Width1; + r.Width -= Dpi.Width1; + } + break; + } + } + + return (r); + } + } + + #endregion + + #region InfoImage + + /// + /// Gets or sets the cell informational Image (the image + /// to display when InfoText is non-empty) + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the cell informational Image (the image to display when InfoText is non-empty).")] + public Image InfoImage + { + get { return (_InfoImage); } + + set + { + if (_InfoImage != value) + { + _InfoImage = value; + + OnPropertyChangedEx("InfoImage", VisualChangeType.Render); + } + } + } + + #region GetInfoImage + + internal Image GetInfoImage() + { + return (_InfoImage ?? GridColumn.GetInfoImage()); + } + + #endregion + + #endregion + + #region InfoImageBounds + + /// + /// Gets the scroll adjusted, bounding + /// rectangle for the current set info image + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle InfoImageBounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Image image = GetInfoImage(); + + if (image != null) + { + if (ShowInfoCellImage(panel) == true) + { + Rectangle r = GetAdjustedBounds(ContentBounds); + r.Inflate(-2, -1); + + Rectangle t = r; + + switch (GridColumn.InfoImageAlignment) + { + case Alignment.TopCenter: + r.X += (r.Width - image.Width) / 2; + break; + + case Alignment.TopRight: + r.X = (r.Right - image.Width); + break; + + case Alignment.MiddleLeft: + if (GridColumn.InfoImageOverlay == false) + r.X -= (image.Width + 4); + + r.Y += (r.Height - image.Height) / 2; + break; + + case Alignment.MiddleCenter: + r.X += (r.Width - image.Width) / 2; + r.Y += (r.Height - image.Height) / 2; + break; + + case Alignment.MiddleRight: + r.X = (GridColumn.InfoImageOverlay == true) + ? (r.Right - image.Width) : (r.Right + 4); + + r.Y += (r.Height - image.Height) / 2; + break; + + case Alignment.BottomLeft: + r.Y = (r.Bottom - image.Height); + break; + + case Alignment.BottomCenter: + r.X += (r.Width - image.Width) / 2; + r.Y = (r.Bottom - image.Height); + break; + + case Alignment.BottomRight: + r.X = (r.Right - image.Width); + r.Y = (r.Bottom - image.Height); + break; + } + + if (r.Y < t.Y) + r.Y = t.Y; + + r.Width = image.Width; + r.Height = image.Height; + + return (r); + } + } + } + + return (Rectangle.Empty); + } + } + + #endregion + + #region InfoText + + /// + /// Gets or sets the informational text associated with + /// the cell. If the InfoText is non-null, then the cells + /// associated InfoImage is displayed in the cell, with the + /// InfoText being displayed as the ToolTip for the InfoImage. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the informational text associated with the cell. If the InfoText is non-null, then the cells associated InfoImage is displayed in the cell, with the InfoText being displayed as the ToolTip for the InfoImage.")] + public string InfoText + { + get { return (_InfoText); } + + set + { + if (_InfoText != value) + { + _InfoText = value; + + UpdateInfoWindow(); + + OnPropertyChangedEx("InfoText", VisualChangeType.Render); + } + } + } + + #endregion + + #region IsActiveCell + + /// + /// Gets whether the cell is the Active cell. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsActiveCell + { + get + { + if (SuperGrid != null) + return (SuperGrid.ActiveCell == this); + + return(false); + } + } + + #endregion + + #region IsCellVisible + + /// + /// Gets whether the cell is visible (taking row visibility, + /// column visibility, and expanded row state into account). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsCellVisible + { + get + { + if (BoundsRelative.Width > 0) + { + GridRow row = GridRow; + + if (row != null) + { + if (GridColumn.Visible == false) + return (false); + + return (row.IsExpandedVisible); + } + } + + return (false); + } + } + + #endregion + + #region IsDataError + + /// + /// Gets whether setting the cell Value has caused a Data Error + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDataError + { + get { return (TestState(Cs.DataError)); } + internal set { SetState(Cs.DataError, value); } + } + + #endregion + + #region IsEditorCell + + /// + /// Gets whether the cell is the cell being edited. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEditorCell + { + get + { + if (SuperGrid != null) + return (SuperGrid.EditorCell == this); + + return (false); + } + } + + #endregion + + #region IsEmptyCell + + /// + /// Gets whether the cell is an Empty cell. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmptyCell + { + get { return (TestState(Cs.EmptyCell)); } + internal set { SetState(Cs.EmptyCell, value); } + } + + #endregion + + #region IsHFrozen + + /// + /// Gets whether the cell is horizontally frozen + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsHFrozen + { + get + { + GridColumn column = GridColumn; + + if (column != null) + return (column.IsHFrozen); + + return (false); + } + } + + #endregion + + #region IsPrimaryCell + + /// + /// Gets whether the cell is the defined PrimaryCell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPrimaryCell + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + return (panel.PrimaryColumnIndex == _ColumnIndex); + + return (false); + } + } + + #endregion + + #region IsReadOnly + + /// + /// Gets whether the cell is ReadOnly due to + /// row, column, or cell ReadOnly property status. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsReadOnly + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.ReadOnly || GridColumn.ReadOnly || GridRow.ReadOnly) + return (true); + } + + return (TestState(Cs.ReadOnly)); + } + } + + #endregion + + #region IsSelectable + + /// + /// Gets whether the cell is selectable due to + /// row, column, or cell AllowSelection property status. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSelectable + { + get + { + return (AllowSelection == true && + GridRow.AllowSelection == true && + GridColumn.AllowSelection == true); + } + } + + #endregion + + #region IsSelected + + /// + /// Gets or sets whether the cell is selected. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSelected + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (AllowSelection == true && panel.AllowSelection == true) + { + if (_SelectionUpdateCount != panel.SelectionUpdateCount) + { + _SelectionUpdateCount = panel.SelectionUpdateCount; + + AnySelected = false; + + if (GridRow != null && GridColumn != null) + { + if (GridRow.IsSelected == true || GridColumn.IsSelected == true) + { + AnySelected = true; + } + else + { + CellRange cr = GetCellRange(); + + if (cr != null && cr.Suspended == false) + { + AnySelected = cr.IsSelected(panel, RowContainer); + } + else + { + if (GridRow.ExpandedVisible(panel) == true) + Selected = panel.IsItemSelectedEx(this); + + AnySelected = Selected; + } + } + } + } + + return (AnySelected); + } + } + + return (false); + } + + set + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (Selected != value) + { + Selected = value; + + if (GridRow != null) + { + if (GridRow.ExpandedVisible(panel) == true) + panel.SetSelectedEx(this, value); + + if (value == true) + { + AnySelected = true; + + _SelectionUpdateCount = panel.SelectionUpdateCount; + } + + InvalidateRender(); + } + } + } + } + } + + #endregion + + #region IsValueExpression + + /// + /// Gets whether the cell Value is an expression. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsValueExpression + { + get { return (TestState(Cs.ValueExpression)); } + internal set { SetState(Cs.ValueExpression, value); } + } + + #endregion + + #region IsValueNull + + /// + /// Gets whether the cell Value is null. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsValueNull + { + get + { + object value = Value; + + return (((GridPanel != null && GridPanel.NullValue == NullValue.DBNull) + ? DBNull.Value : null) == value); + } + } + + #endregion + + #region Merged + + /// + ///Gets whether the cell is merged + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool Merged + { + get { return (TestState(Cs.Merged)); } + + internal set + { + if (value != Merged) + { + SetState(Cs.Merged, value); + + ClearEffectiveStyles(); + + if (value == true && _mouseDownHitCell == this) + DoRendererMouseLeave(EventArgs.Empty); + } + } + } + + #endregion + + #region MergedBottom + + /// + ///Gets or sets whether the cell is Merged at the Bottom + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool MergedBottom + { + get { return (TestState(Cs.MergedBottom)); } + set { SetState(Cs.MergedBottom, value); } + } + + #endregion + + #region MergedLeft + + /// + ///Gets or sets whether the cell is Merged to the Left + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool MergedLeft + { + get { return (TestState(Cs.MergedLeft)); } + set { SetState(Cs.MergedLeft, value); } + } + + #endregion + + #region MergedRight + + /// + ///Gets or sets whether the cell is Merged to the Right + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool MergedRight + { + get { return (TestState(Cs.MergedRight)); } + set { SetState(Cs.MergedRight, value); } + } + + #endregion + + #region MergedTop + + /// + ///Gets or sets whether the cell is Merged at the Top + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool MergedTop + { + get { return (TestState(Cs.MergedTop)); } + set { SetState(Cs.MergedTop, value); } + } + + #endregion + + #region MergeSuspended + + /// + ///Gets whether the cell is merged and suspended. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool MergeSuspended + { + get + { + CellRange cr = GetCellRange(); + + return (cr != null && cr.Suspended == true); + } + } + + #endregion + + #region NullString + + /// + /// Gets how null values are displayed + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string NullString + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + return (GridColumn.NullString ?? panel.NullString); + + return (String.Empty); + } + } + + #endregion + + #region ReadOnly + + /// + /// Gets or sets whether the user can change cell contents + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether the user can change cell contents.")] + public bool ReadOnly + { + get { return (TestState(Cs.ReadOnly)); } + + set + { + if (value != ReadOnly) + { + SetState(Cs.ReadOnly, value); + + OnPropertyChangedEx("ReadOnly", VisualChangeType.Render); + } + } + } + + #endregion + + #region RenderControl + + /// + /// Gets the current set Render Control for the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IGridCellEditControl RenderControl + { + get + { + if (_EditorInfo == null || + (_EditorInfo.RenderType == null && _EditorInfo.EditorType == null)) + { + return (null); + } + + if (_EditorInfo.RenderControl == null) + { + RenderControl = (_EditorInfo.RenderType != null) + ? GetEditControl(_EditorInfo.RenderType, _EditorInfo.RenderParams) + : GetEditControl(_EditorInfo.EditorType, _EditorInfo.EditorParams); + } + + return (_EditorInfo.RenderControl); + } + + internal set + { + if (_EditorInfo == null) + _EditorInfo = new EditorInfo(); + + if (_EditorInfo.RenderControl != value) + { + if (_EditorInfo.RenderControl != null) + { + if (_EditorInfo.RenderControl.EditorPanel.Parent != null) + SuperGrid.Controls.Remove(_EditorInfo.RenderControl.EditorPanel); + + _EditorInfo.RenderControl.EditorCellBitmap = null; + + if (_EditorInfo.RenderType != null || _EditorInfo.EditorType != null) + ((Control)_EditorInfo.RenderControl).Dispose(); + } + + _EditorInfo.RenderControl = value; + + if (_EditorInfo.RenderControl != null) + { + if (_EditorInfo.RenderControl.EditorPanel.Parent == null) + SuperGrid.Controls.Add(_EditorInfo.RenderControl.EditorPanel); + } + } + } + } + + #endregion + + #region RenderParams + + /// + /// Gets or sets an array of arguments that match in number, + /// order, and type the parameters of the RenderControl constructor + /// to invoke. If empty or null, the default constructor is invoked. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object[] RenderParams + { + get + { + if (_EditorInfo == null) + return (null); + + return (_EditorInfo.RenderParams); + } + + set + { + if (_EditorInfo == null) + _EditorInfo = new EditorInfo(); + + if (IsSameParams(_EditorInfo.RenderParams, value) == false) + { + _EditorInfo.RenderParams = value; + + RenderControl = null; + + NeedsMeasured = true; + + OnPropertyChangedEx("RenderParams", VisualChangeType.Layout); + } + + if (_EditorInfo.IsEmpty == true) + _EditorInfo = null; + } + } + + #endregion + + #region RenderType + + /// + /// Gets or sets the cell render type. This is the control + /// type used to perform the default rendering of the cell value + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the cell render type. This is the control type used to perform the default rendering of the cell value.")] + [TypeConverter(typeof(EditTypeConverter))] + [Editor("DevComponents.SuperGrid.Design.EditTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public Type RenderType + { + get + { + if (_EditorInfo == null) + return (null); + + return (_EditorInfo.RenderType); + } + + set + { + if (value != null || _EditorInfo != null) + { + if (_EditorInfo == null) + _EditorInfo = new EditorInfo(); + + if (_EditorInfo.RenderType != value) + { + _EditorInfo.RenderType = value; + _EditorInfo.RenderControl = null; + + NeedsMeasured = true; + + OnPropertyChangedEx("RenderType", VisualChangeType.Layout); + } + + if (_EditorInfo.IsEmpty == true) + _EditorInfo = null; + } + } + } + + #endregion + + #region RowIndex + + /// + /// Gets the associated Row index for the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int RowIndex + { + get + { + GridRow row = GridRow; + + return (row != null ? row.RowIndex : -1); + } + } + + #endregion + + #region UnMergedBounds + + /// + /// Gets the scroll adjusted un-merged bounds of the cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle UnMergedBounds + { + get + { + if (_BoundsUpdateCount != SuperGrid.BoundsUpdateCount) + UpdateBoundingRects(); + + return (_Bounds); + } + } + + #endregion + + #region Value + + /// + /// Gets or sets the cell value + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the cell value.")] + [TypeConverter(typeof(ValueTypeConverter))] + [Editor("DevComponents.SuperGrid.Design.ValueTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public object Value + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + object o = GetValue(panel); + + if (SuperGrid != null) + SuperGrid.DoGetCellValueEvent(this, ref o); + + return (o); + } + + return (_Value); + } + + set + { + if ((value != null && value.Equals(_Value) == false) || + (value == null && _Value != null)) + { + object oldValue = _Value; + + SetValue(value); + + GridRow row = GridRow; + + if (row != null && row.Loading == false) + OnValueChanged(oldValue, value, DataContext.CellEdit); + } + } + } + + #region GetValue + + /// + /// GetValue + /// + /// + /// + protected virtual object GetValue(GridPanel panel) + { + if (panel.DataSource != null) + { + if (ActiveIList(panel) == true || + _DataResetCount != panel.DataBinder.DataResetCount) + { + _DataResetCount = panel.DataBinder.DataResetCount; + + object o = panel.DataBinder.GetValue(this, _Value); + + if ((o == null && o != _Value) || + (o != null && o.Equals(_Value) == false)) + { + _Value = o; + + GridColumn.NeedsFilterScan = true; + + InvalidateRender(); + + return (o); + } + } + } + + return (_Value); + } + + #region ActiveIList + + private bool ActiveIList(GridPanel panel) + { + if (panel.DataSource is IList && + (panel.DataSource is IListSource == false && + panel.DataSource is IBindingList == false)) + { + GridRow row = GridRow; + + if (row != null) + { + if (panel.LatentActiveRowIndex < 0 && row.IsTempInsertRow == false) + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region SetValue + + /// + /// SetValue + /// + /// + protected virtual void SetValue(object value) + { + _Value = value; + + GridPanel panel = GridPanel; + + if (panel != null) + { + GridRow row = GridRow; + + if (row.Loading == false && IsLoading() == false) + { + GridColumn column = GridColumn; + + panel.DataBinder.SetValue(this, value); + + row.RowNeedsStored = true; + column.NeedsFilterScan = true; + + if (column.IsGroupColumn == true) + { + if (row == panel.ActiveRow) + row.RowNeedsGrouped = true; + else + panel.NeedsGrouped = true; + } + + if (panel.KeepRowsSorted == true) + { + if (column.IsSortColumn == true) + { + if (row.IsTempInsertRow == false) + { + if (row == panel.ActiveRow) + row.RowNeedsSorted = true; + else + panel.NeedsSorted = true; + } + } + } + } + } + } + + private bool IsLoading() + { + SuperGridControl sg = SuperGrid; + + return (sg == null || sg.Parent == null); + } + + #endregion + + #region OnValueChanged + + private void OnValueChanged(object oldValue, object newValue, DataContext context) + { + NeedsMeasured = true; + + IsDataError = false; + + ClearEffectiveStyles(); + + if (GridRow.Loading == false) + RefreshCellEditor(); + + OnPropertyChanged("Value"); + + GridPanel panel = GridPanel; + + if (panel != null) + { + SuperGrid.DoCellValueChangedEvent(this, oldValue, newValue, context); + + if (panel.EnableCellExpressions == true) + { + if (GridRow.Loading == false) + UpdateCellExp(panel, oldValue, newValue); + } + + UpdateMerge(panel); + } + } + + #region RefreshCellEditor + + private void RefreshCellEditor() + { + if (SuperGrid != null) + { + IGridCellEditControl editor = GetInternalEditControl(true); + + if (editor != null) + { + if (SuperGrid.NonModalEditorCell == this) + RefreshNonModalEditor(); + + else if (SuperGrid.EditorCell == this) + RefreshEditor(editor); + + switch (editor.ValueChangeBehavior) + { + case ValueChangeBehavior.InvalidateLayout: + GridColumn.NeedsResized = true; + GridRow.NeedsMeasured = true; + + InvalidateLayout(); + break; + + default: + InvalidateRender(); + break; + } + } + } + } + + #region RefreshEditor + + private void RefreshEditor(IGridCellEditControl editor) + { + editor.SuspendUpdate = true; + + try + { + CellVisualStyle style = GetEffectiveStyle(); + + editor.InitializeContext(this, style); + } + finally + { + editor.SuspendUpdate = false; + } + } + + #endregion + + #region RefreshNonModalEditor + + private void RefreshNonModalEditor() + { + if (SuperGrid.ActiveNonModalEditor != null) + { + SuperGrid.ActiveNonModalEditor.EditorValue = _Value; + + CellVisualStyle style = GetEffectiveStyle(); + + InitializeContext(DataContext.CellValueLoad, + SuperGrid.ActiveNonModalEditor, style); + } + } + + #endregion + + #endregion + + #region UpdateMerge + + private void UpdateMerge(GridPanel panel) + { + CellRange cr = GetCellRange(); + + if (cr != null && cr.Suspended == true) + { + Modified = true; + cr.Modified = true; + } + else + { + if (CellCanMerge(panel) == true) + { + MergeUpdateCount--; + + if (RowContainer.IsMergeSuspended == true) + RowContainer.MergeUpdateCount++; + + RowContainer.NeedMergeLayout = true; + + RowContainer.InvalidateLayout(); + } + } + } + + #region CellCanMerge + + private bool CellCanMerge(GridPanel panel) + { + if (panel != null && panel.EnableCellMerging == true) + { + CellMergeMode cMode = GridColumn.CellMergeMode; + + if (cMode == CellMergeMode.NotSet) + cMode = panel.CellMergeMode; + + return (cMode != CellMergeMode.None); + } + + return (false); + } + + #endregion + + #endregion + + #endregion + + #region UpdateCellExp + + internal void UpdateCellExp( + GridPanel panel, object oldValue, object value) + { + string oldExp = oldValue as string; + string newExp = value as string; + + if (oldExp != null) + { + oldExp = oldExp.Trim(); + + if (oldExp.StartsWith("=")) + { + panel.ExpDictionary.Remove(this); + + InfoText = null; + } + } + + IsValueExpression = false; + + if (newExp != null) + { + newExp = newExp.Trim(); + + if (newExp.StartsWith("=")) + SetCellExp(panel, newExp); + } + + RefreshExpressions(panel, this, new List()); + } + + #region RefreshExpressions + + private void RefreshExpressions( + GridPanel panel, GridCell gridCell, List usedCells) + { + foreach (KeyValuePair item in panel.ExpDictionary) + { + List cells = item.Value.GetCellReferences(); + + if (cells != null) + { + if (cells.Contains(gridCell) == true) + { + item.Key.InvalidateRender(); + + if (usedCells.Contains(item.Key) == false) + { + usedCells.Add(item.Key); + + RefreshExpressions(panel, item.Key, usedCells); + + usedCells.Remove(item.Key); + } + } + } + } + } + + #endregion + + #region SetCellExp + + internal void SetCellExp(GridPanel panel, string newExp) + { + if (panel.EnableCellExpressions == true) + { + IsValueExpression = false; + + while (true) + { + try + { + EEval eval = new EEval(this, newExp); + + panel.ExpDictionary[this] = eval; + + InfoText = null; + IsValueExpression = true; + + break; + } + catch (Exception exp) + { + bool retry = false; + bool throwException = false; + + if (SuperGrid.HasDataErrorHandler == true) + { + object value = newExp; + + if (SuperGrid.DoDataErrorEvent(GridPanel, this, exp, + DataContext.CellExpressionParse, ref value, ref throwException, ref retry) == true) + { + return; + } + } + + if (throwException == true) + throw; + + InfoText = exp.Message; + + if (retry == false) + break; + } + } + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region TestState + + private bool TestState(Cs state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(Cs state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #region MeasureOverride + + //private int _MeasureCount; + + /// + /// Performs the layout of the item and sets + /// the Size property to size that item will take. + /// + /// Layout information. + /// + /// + protected override void MeasureOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + //_MeasureCount++; + + MeasureCell(layoutInfo.Graphics, + stateInfo.GridPanel, stateInfo.IndentLevel, constraintSize); + } + + #region MeasureCell + + private void MeasureCell(Graphics g, + GridPanel panel, int indentLevel, Size constraintSize) + { + Size sizeNeeded = Size.Empty; + + if (ColumnIndex < panel.Columns.Count) + { + CellVisualStyle style = GetSizingStyle(panel); + Size imageSize = style.GetFigureSize(panel); + + Alignment imageAlignment = style.ImageAlignment; + + if (style.IsOverlayImage == true) + imageAlignment = Alignment.MiddleCenter; + + int width = constraintSize.Width; + + Size borderSize = style.GetBorderSize(true); + + int bwidth = borderSize.Width + Dpi.Width2; + int bheight = borderSize.Height + Dpi.Height2; + + if (constraintSize.Width > 1) + { + switch (imageAlignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + break; + + default: + width -= imageSize.Width; + break; + } + + width -= bwidth; + + if (BoundsRelative.X == GridPanel.Bounds.X) + width -= Dpi.Width1; + } + + _ContentSize = + GetProposedSize(g, style, new Size(width, 0)); + + switch (imageAlignment) + { + case Alignment.MiddleCenter: + sizeNeeded.Height = Math.Max(imageSize.Height, _ContentSize.Height) + bheight; + sizeNeeded.Width = Math.Max(_ContentSize.Width, imageSize.Width) + bwidth; + break; + + case Alignment.TopCenter: + case Alignment.BottomCenter: + sizeNeeded.Width = Math.Max(_ContentSize.Width, imageSize.Width) + bwidth; + sizeNeeded.Height = _ContentSize.Height + imageSize.Height + bheight; + break; + + default: + sizeNeeded.Width = _ContentSize.Width + imageSize.Width + bwidth; + sizeNeeded.Height = Math.Max(imageSize.Height, _ContentSize.Height) + bheight; + break; + } + + if (panel.GroupColumns.Count > 0) + { + if (panel.Columns.FirstVisibleColumn == GridColumn) + sizeNeeded.Width += Dpi.Width(panel.LevelIndentSize.Width * (indentLevel + 1)); + } + + if (GridRow != null && + (GridRow.Rows.Count > 0 || GridRow.RowsUnresolved == true)) + { + if (panel.ExpandImage != null) + { + sizeNeeded.Height = Math.Max(sizeNeeded.Height, + Dpi.Height(panel.ExpandImage.Height + 4)); + } + + if (panel.CollapseImage != null) + { + sizeNeeded.Height = Math.Max(sizeNeeded.Height, + Dpi.Height(panel.CollapseImage.Height + 4)); + } + } + + if (panel.CheckBoxes == true) + { + sizeNeeded.Height = Math.Max(sizeNeeded.Height, + Dpi.Height(panel.CheckBoxSize.Height)); + + sizeNeeded.Width += Dpi.Width(CheckBoxSpacing * 2); + } + } + + sizeNeeded.Width += Dpi.Width3; + sizeNeeded.Height += Dpi.Width3; + + if (constraintSize.Width > 0) + sizeNeeded.Width = constraintSize.Width; + + _MeasuredSize = sizeNeeded; + + Size = sizeNeeded; + } + + #endregion + + #endregion + + #region ArrangeOverride + + /// + /// Performs the arrange pass layout of the item + /// when final position and size of the item has been set. + /// + /// Layout information. + /// + /// + protected override void ArrangeOverride(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + GridPanel panel = stateInfo.GridPanel; + Rectangle r = layoutBounds; + + r.X += _IndentLevel * Dpi.Width(panel.LevelIndentSize.Width); + r.Width = panel.TreeButtonIndent; + + ArrangeExpandButton(panel, ref r); + ArrangeCheckBox(panel, r); + + _toolTipText = null; + } + + #region ArrangeExpandButton + + private void ArrangeExpandButton(GridPanel panel, ref Rectangle r) + { + if (IsPrimaryCell == true) + { + Rectangle t = Rectangle.Empty; + + if (panel.ShowTreeButtons == true) + { + if (NeedsExpandButton() == true) + { + t = r; + + Size size = panel.GetTreeButtonSize(); + + t.X += (r.Width - size.Width) / 2; + t.Y += (r.Height - size.Height) / 2 - 1; + + t.Size = size; + } + + int tbi = panel.TreeButtonIndent; + + r.X += tbi; + r.Width -= tbi; + } + else + { + if (panel.CheckBoxes == true) + { + int cbs = Dpi.Width(CheckBoxSpacing); + + r.X += cbs; + r.Width -= cbs; + } + } + + GridRow.ExpandButtonBounds = t; + } + } + + #region NeedsExpandButton + + private bool NeedsExpandButton() + { + GridRow row = GridRow; + + if (row != null) + { + if (row.ShowTreeButton == true) + { + if (row.RowsUnresolved || row.HasVisibleItems) + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region ArrangeCheckBox + + private void ArrangeCheckBox(GridPanel panel, Rectangle r) + { + if (IsPrimaryCell == true) + { + if (GridRow.HasCheckBox == true) + { + Size cbSize = Dpi.Size(panel.CheckBoxSize); + + int n = Math.Max(cbSize.Width, cbSize.Height); + + r.Y += (r.Height - n) / 2; + + r.Width = n; + r.Height = n; + + GridRow.CheckBoxBounds = r; + } + else + { + GridRow.CheckBoxBounds = Rectangle.Empty; + } + } + } + + #endregion + + #endregion + + #region RenderOverride + + /// + /// Performs drawing of the item and its children. + /// + /// Holds contextual rendering information. + protected override void RenderOverride(GridRenderInfo renderInfo) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Graphics g = renderInfo.Graphics; + + CheckMeasure(panel, g); + + CellRange cr = GetStateCellRange(); + + bool rendered = (cr != null && (cr.RenderCount == panel.RenderCount)); + + Rectangle backBounds = (cr != null) ? cr.BackBounds : BackBounds; + Rectangle bounds = GetBounds(panel, backBounds); + + if (backBounds.IntersectsWith(SuperGrid.ViewRectEx) == true) + { + if (rendered == false) + { + CellHighlightMode mode = GetCellHighlightMode(panel); + CellVisualStyle style = GetEffectiveStyle(); + + RenderCellBackground(g, panel, backBounds, mode); + RenderGridBorder(g, panel, backBounds); + + int n = RenderLevelData(g, panel); + + Rectangle r = bounds; + r.X += n; + r.Width -= n; + + RenderCellBorder(g, panel, r, style); + RenderImageAndValue(g, panel, bounds, mode, style); + + if (this.IsDataError == true) + RenderDataError(g); + + else if (GridRow.IsDeleted == true) + RenderDeleted(g); + + RenderFocusRect(g, panel, cr, backBounds); + + if (cr != null) + cr.RenderCount = panel.RenderCount; + } + else + { + RenderLevelData(g, panel); + } + } + } + } + + #region CheckMeasure + + private void CheckMeasure(GridPanel panel, Graphics g) + { + if (NeedsMeasured == true) + { + NeedsMeasured = false; + + Size size = new Size(GridColumn.Size.Width, GridRow.Size.Height); + + if (panel.VirtualMode == false) + MeasureCell(g, panel, IndentLevel, size); + + size.Height = GridRow.FixedRowHeight; + Size = size; + + UpdateBoundingRects(); + } + } + + #endregion + + #region RenderCellBackground + + private void RenderCellBackground(Graphics g, + GridPanel panel, Rectangle r, CellHighlightMode mode) + { + if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Background, r) == false) + { + RenderCellBackgroundEx(panel, g, r, mode); + SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Background, r); + } + } + + #region RenderCellBackgroundEx + + private void RenderCellBackgroundEx(GridPanel panel, + Graphics g, Rectangle r, CellHighlightMode type) + { + if (SuperGrid.EditorCell == this) + { + TextBox tb = GetInternalEditControl() as TextBox; + + if (tb != null) + { + using (Brush br = new SolidBrush(tb.BackColor)) + RenderBackground(g, r, type, br); + + return; + } + } + + using (Brush br = GetContentBrush(panel, r, type)) + RenderBackground(g, r, type, br); + } + + #region RenderBackground + + private void RenderBackground( + Graphics g, Rectangle r, CellHighlightMode type, Brush br) + { + if (type == CellHighlightMode.Partial || + type == CellHighlightMode.Content) + { + r = RenderPartialBackground(g, r, type); + } + + if (r.Width > 0 && r.Height > 0) + g.FillRectangle(br, r); + } + + #endregion + + #region RenderPartialBackground + + private Rectangle RenderPartialBackground( + Graphics g, Rectangle r, CellHighlightMode type) + { + CellVisualStyle defaultStyle = + GetEffectiveStyle(StyleType.Default); + + using (Brush br = defaultStyle.Background.GetBrush(r)) + g.FillRectangle(br, r); + + r = GetAdjustedBounds(ContentBounds); + + if (type == CellHighlightMode.Content) + { + IGridCellEditControl editor = GetInternalRenderControl(); + + r = GetEditPanelBounds(editor, r); + } + + r.Inflate(1, 1); + + return (r); + } + + #endregion + + #region GetContentBrush + + private Brush GetContentBrush( + GridPanel panel, Rectangle r, CellHighlightMode type) + { + if (IsEmptyCell == true && panel.AllowEmptyCellSelection == false) + { + CellVisualStyle style = + GetEffectiveStyle(StyleType.Empty); + + return (style.Background.GetBrush(r)); + } + + if (IsSelectable == false) + { + CellVisualStyle style = + GetEffectiveStyle(StyleType.NotSelectable); + + return (style.Background.GetBrush(r)); + } + + if (type == CellHighlightMode.None) + { + CellVisualStyle style = + GetEffectiveStyle(false); + + return (style.Background.GetBrush(r)); + } + + CellVisualStyle contentStyle = GetContentStyle(panel); + + return (contentStyle.Background.GetBrush(r)); + } + + #endregion + + #region GetContentStyle + + private CellVisualStyle GetContentStyle(GridPanel panel) + { + if (panel.SelectionGranularity == SelectionGranularity.Row) + { + StyleState cellState = StyleState.Default; + + if (IsReadOnly == true) + cellState |= StyleState.ReadOnly; + + Rectangle t = ViewRect; + Rectangle r = GridRow.Bounds; + + CellRange cr = GetCellRange(); + + if (cr != null) + r = Rectangle.Union(r, cr.BackBounds); + + r.Intersect(t); + + if (SuperGrid.ScrollBarScrolling == false) + { + if (panel.RowHighlightType == RowHighlightType.Full) + { + if (GridRow.IsMouseOver == true) + cellState |= StyleState.MouseOver; + } + else + { + if (r.Contains(SuperGrid.PointToClient(Control.MousePosition))) + cellState |= StyleState.MouseOver; + } + } + + if (IsSelected == true) + cellState |= StyleState.Selected; + + return (GetEffectiveStyle(cellState)); + } + + return (GetEffectiveStyle()); + } + + #endregion + + #region GetCellHighlightMode + + private CellHighlightMode GetCellHighlightMode(GridPanel panel) + { + if (panel.SelectionGranularity != SelectionGranularity.Cell) + { + switch (panel.RowHighlightType) + { + case RowHighlightType.None: + return (CellHighlightMode.None); + + case RowHighlightType.PrimaryColumnOnly: + return (IsPrimaryCell == true + ? CellHighlightMode.Full : CellHighlightMode.None); + + default: + return (CellHighlightMode.Full); + } + } + + if (GridRow.IsSelected == true) + return (CellHighlightMode.Full); + + return (GridColumn.CellHighlightMode); + } + + #endregion + + #endregion + + #endregion + + #region RenderGridBorder + + private void RenderGridBorder( + Graphics g, GridPanel panel, Rectangle r) + { + if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Border, r) == false) + { + RenderGridBorderEx(g, panel, r); + SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Border, r); + } + } + + private void RenderGridBorderEx( + Graphics g, GridPanel panel, Rectangle r) + { + if (panel.GridLines != GridLines.None) + { + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + if (panel.GridLines == GridLines.Both) + RenderBothGridBorders(g, pstyle, r); + + else if (panel.GridLines == GridLines.Vertical) + RenderVGridBorder(g, pstyle, r); + + else if (panel.GridLines == GridLines.Horizontal) + RenderHGridBorder(g, pstyle, r); + } + } + + #region RenderBothGridBorders + + private void RenderBothGridBorders( + Graphics g, GridPanelVisualStyle pstyle, Rectangle r) + { + RenderHGridBorder(g, pstyle, r); + RenderVGridBorder(g, pstyle, r); + } + + #endregion + + #region RenderHGridBorder + + private void RenderHGridBorder(Graphics g, GridPanelVisualStyle pstyle, Rectangle r) + { + if (pstyle.HorizontalLinePattern != LinePattern.None && + pstyle.HorizontalLinePattern != LinePattern.NotSet) + { + using (Pen pen = new Pen(pstyle.HorizontalLineColor, Dpi.Height1)) + { + pen.DashStyle = (DashStyle)pstyle.HorizontalLinePattern; + pen.DashOffset = r.X % 2; + + g.DrawLine(pen, r.X, r.Top - 1, r.Right - 1, r.Top - 1); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + } + } + } + + #endregion + + #region RenderVGridBorder + + private void RenderVGridBorder(Graphics g, GridPanelVisualStyle pstyle, Rectangle r) + { + if (pstyle.VerticalLinePattern != LinePattern.None && + pstyle.VerticalLinePattern != LinePattern.NotSet) + { + using (Pen pen = new Pen(pstyle.VerticalLineColor, Dpi.Width1)) + { + pen.DashStyle = (DashStyle)pstyle.VerticalLinePattern; + pen.DashOffset = r.Top % 2; + + g.DrawLine(pen, r.Right - 1, r.Top, r.Right - 1, r.Bottom); + } + } + } + + #endregion + + #endregion + + #region RenderLevelData + + private int RenderLevelData(Graphics g, GridPanel panel) + { + int n = 0; + + if (IsPrimaryCell == true) + { + Rectangle r = BackBounds; + + int x = r.X; + + RenderCellTreeData(g, panel, ref r); + RenderCellCheckBox(g, panel, ref r); + + n = r.X - x; + } + else + { + if (panel.GroupColumns.Count > 0) + { + if (panel.Columns.FirstVisibleColumn == GridColumn) + n = Dpi.Width(panel.LevelIndentSize.Width * _IndentLevel); + } + } + + return (n); + } + + #region RenderCellTreeData + + private void RenderCellTreeData( + Graphics g, GridPanel panel, ref Rectangle r) + { + int liw = Dpi.Width(panel.LevelIndentSize.Width); + + if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true) + { + GridRow row = GridRow; + Rectangle t = row.ExpandButtonBounds; + + if (row.IsVFrozen == false) + t.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || GridColumn.IsHFrozen == false) + t.X -= HScrollOffset; + + bool hasExpandButton = (panel.ShowTreeButtons == true && + row.ExpandButtonBounds.IsEmpty == false); + + int tbi = panel.TreeButtonIndent; + + if (panel.ShowTreeLines == true) + { + Rectangle p = r; + + p.Y--; + p.Height++; + + TreeDisplay.RenderLines(g, + panel, p, row, _IndentLevel, liw, tbi, hasExpandButton); + } + + if (hasExpandButton == true) + { + Point pt = Control.MousePosition; + pt = SuperGrid.PointToClient(pt); + + bool hot = t.Contains(pt); + + Image image = (row.Expanded == true) + ? panel.GetCollapseButton(g, hot) : panel.GetExpandButton(g, hot); + + ExpandDisplay.RenderButton(g, image, t, r); + } + + r.X += tbi; + r.Width -= tbi; + } + + int n = liw * _IndentLevel; + + r.X += n; + r.Width -= n; + } + + #endregion + + #region RenderCellCheckBox + + private void RenderCellCheckBox( + Graphics g, GridPanel panel, ref Rectangle r) + { + if (GridRow.HasCheckBox == true) + { + Rectangle t = CheckBoxBounds; + + if (GridRow.IsVFrozen == false) + t.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || GridColumn.IsHFrozen == false) + t.X -= HScrollOffset; + + Region clip = null; + + if (t.Right >= r.Right || t.Height >= r.Height) + { + Rectangle z = r; + z.Width--; + z.Height--; + + clip = g.Clip; + g.SetClip(z, CombineMode.Intersect); + } + + if (GridRow.Checked == true) + { + CheckDisplay.RenderCheckbox(g, t, + CheckBoxState.CheckedNormal, ButtonState.Checked); + } + else + { + CheckDisplay.RenderCheckbox(g, t, + CheckBoxState.UncheckedNormal, ButtonState.Normal); + } + + if (clip != null) + g.Clip = clip; + + r.X += panel.CheckBoxSize.Width + (CheckBoxSpacing * 2); + r.Width -= (panel.CheckBoxSize.Width + (CheckBoxSpacing * 2)); + } + } + + #endregion + + #endregion + + #region RenderCellBorder + + private void RenderCellBorder(Graphics g, + GridPanel panel, Rectangle r, CellVisualStyle style) + { + if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Border, r) == false) + { + RenderCellBorderEx(g, panel, r, style); + SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Border, r); + } + } + + #region RenderCellBorderEx + + private void RenderCellBorderEx( + Graphics g, GridPanel panel, Rectangle r, CellVisualStyle style) + { + Rectangle t = GetBorderRect(panel, r, style); + + style.RenderBorder(g, t); + } + + #region GetBorderRect + + private Rectangle GetBorderRect( + GridPanel panel, Rectangle r, CellVisualStyle style) + { + r.X += Dpi.Width(style.Margin.Left); + r.Width -= Dpi.Width(style.Margin.Horizontal); + + r.Y += Dpi.Height(style.Margin.Top); + r.Height -= Dpi.Height(style.Margin.Vertical); + + if (panel.GridLines == GridLines.Horizontal || panel.GridLines == GridLines.Both) + r.Height -= Dpi.Height1; + + if (panel.GridLines == GridLines.Vertical || panel.GridLines == GridLines.Both) + r.Width -= Dpi.Width1; + + return (r); + } + + #endregion + + #endregion + + #endregion + + #region RenderImageAndValue + + private void RenderImageAndValue(Graphics g, + GridPanel panel, Rectangle bounds, CellHighlightMode mode, CellVisualStyle style) + { + Rectangle r = GetAdjustedBounds(GetContentBounds(panel, bounds)); + + if (style.ImageOverlay != ImageOverlay.Top) + RenderCellImage(g, panel, style, bounds, r, mode); + + if (CanRenderCellValue() == true) + { + if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Content, r) == false) + { + RenderCellValue(g, style, r); + SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Content, r); + } + } + else + { + if (SuperGrid.EditorCell == this && Visible == true && IsEmptyCell == false) + RenderCellInfo(g, panel); + } + + if (style.ImageOverlay == ImageOverlay.Top) + RenderCellImage(g, panel, style, bounds, r, mode); + } + + #region RenderCellImage + + private void RenderCellImage(Graphics g, GridPanel panel, + CellVisualStyle style, Rectangle bounds, Rectangle r, CellHighlightMode type) + { + object figure = style.GetFigure(panel); + + if (figure != null) + { + r = style.GetFigureBounds(panel, r); + r.Intersect(bounds); + + if (r.Width > 0 && r.Height > 0) + { + if (figure is Image) + { + if (CanHighlightCell(style, type) == true) + DrawHighlightImage(g, (Image)figure, style, r); + else + g.DrawImageUnscaledAndClipped((Image)figure, r); + } + else + { + SymbolDef sd = (SymbolDef)figure; + + using (Brush br = new SolidBrush(sd.SymbolColor)) + g.DrawString(sd.SymbolRealized, sd.SymbolFont, br, r); + } + } + } + } + + #region CanHighlightCell + + private bool CanHighlightCell( + CellVisualStyle style, CellHighlightMode type) + { + switch (style.ImageHighlightMode) + { + case ImageHighlightMode.Always: + return (true); + + case ImageHighlightMode.Never: + return (false); + + default: + if (IsSelected == false) + return (false); + + return (type == CellHighlightMode.Content || + type == CellHighlightMode.Partial); + } + } + + #endregion + + #region DrawHighlightImage + + private void DrawHighlightImage(Graphics g, + Image image, CellVisualStyle style, Rectangle r) + { + Color color = GetSimpleColor(style); + + float[][] ptsArray = + { + new float[] {(float)color.R / 255, 0, 0, 0, 0}, + new float[] {0, (float)color.G / 255, 0, 0, 0}, + new float[] {0, 0, (float)color.B / 255, 0, 0}, + new float[] {0f, 0, 0, 1, 0}, + new float[] {.15f, .15f, .15f, 0, 1} + }; + + ColorMatrix clrMatrix = new ColorMatrix(ptsArray); + ImageAttributes imgAttribs = new ImageAttributes(); + + imgAttribs.SetColorMatrix(clrMatrix, + ColorMatrixFlag.Default, ColorAdjustType.Default); + + g.DrawImage(image, r, + 0, 0, style.Image.Width, image.Height, + GraphicsUnit.Pixel, imgAttribs); + } + + #endregion + + #region GetSimpleColor + + private Color GetSimpleColor(CellVisualStyle style) + { + Color color1; + Color color2; + + if (style.Background.BackColorBlend.Colors != null && + style.Background.BackColorBlend.Colors.Length > 0) + { + Color[] colors = style.Background.BackColorBlend.Colors; + + color1 = colors[0]; + color2 = colors[colors.Length - 1]; + } + else + { + color1 = style.Background.Color1; + color2 = style.Background.Color2; + } + + if (color2.IsEmpty == true) + return (color1); + + switch (style.Alignment) + { + case Alignment.TopLeft: + case Alignment.TopCenter: + case Alignment.TopRight: + return (color1); + + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + return (Color.FromArgb((color1.R + color2.R) / 2, (color1.G + color2.G) / 2, (color1.B + color2.B) / 2)); + + default: + return (color2); + } + } + + #endregion + + #endregion + + #region CanRenderCellValue + + private bool CanRenderCellValue() + { + if (Visible == false || IsEmptyCell == true || SuperGrid.EditorCell == this) + return (false); + + if (SuperGrid.NonModalEditorCell == this) + return (false); + + return (true); + } + + #endregion + + #region RenderCellValue + + //private int _RenderCount; + + private void RenderCellValue( + Graphics g, CellVisualStyle style, Rectangle r) + { + if (r.Width > 0) + { + GridColumn column = GridColumn; + + if (column != null) + { + IGridCellEditControl renderer; + + if (SuperGrid.ActiveEditor != null || + (MouseRenderer == null || MouseRenderer.EditorCell != this)) + { + renderer = GetInternalRenderControl(); + } + else + { + renderer = MouseRenderer; + } + + if (renderer != null && ((Control)renderer).IsDisposed == false) + { + CellRender(g, style, renderer); + + //using (StringFormat sf = new StringFormat()) + //{ + // sf.Alignment = StringAlignment.Far; + // sf.LineAlignment = StringAlignment.Far; + // sf.Trimming = StringTrimming.EllipsisCharacter; + + // g.DrawString((++_RenderCount).ToString(), + // SystemFonts.DefaultFont, Brushes.Red, r, sf); + + // //sf.LineAlignment = StringAlignment.Near; + + // //g.DrawString((_MeasureCount).ToString(), + // // SystemFonts.DefaultFont, Brushes.Blue, r, sf); + //} + } + } + } + } + + #endregion + + #endregion + + #region RenderDataError + + private void RenderDataError(Graphics g) + { + Rectangle r = Bounds; + + int w = Dpi.Width5; + int h = Dpi.Width5; + + if (r.Width > w && r.Height > h) + r.Inflate(-w, -h); + + using (SolidBrush br = new SolidBrush(Color.FromArgb(64, Color.Crimson))) + g.FillRectangle(br, r); + } + + #endregion + + #region RenderDeleted + + private void RenderDeleted(Graphics g) + { + using (SolidBrush br = new SolidBrush(Color.FromArgb(128, Color.LightGray))) + g.FillRectangle(br, Bounds); + } + + #endregion + + #region RenderFocusRect + + private void RenderFocusRect(Graphics g, + GridPanel panel, CellRange cr, Rectangle backBounds) + { + if (panel.FocusCuesEnabled == true) + { + if (IsFocused() == true) + { + if (panel.EnableCellMerging == true && IsFocusedRow(cr) == true) + RenderRowFocusRect(g, panel, backBounds, cr); + + else if (IsFocusedCell(cr) == true) + { + Rectangle r; + + if (cr != null) + { + r = backBounds; + + if (r.X <= 0) + { + r.X++; + r.Width--; + } + + r.Width -= Dpi.Width1; + r.Height -= Dpi.Height1; + } + else + { + r = HighLightBounds; + } + + RenderCellFocusRect(g, r); + } + } + } + } + + #region IsFocused + + private bool IsFocused() + { + if (IsDesignerHosted == true) + return (false); + + return (SuperGrid.ContainsFocus == true); + } + + #endregion + + #region IsFocusedRow + + private bool IsFocusedRow(CellRange cr) + { + if (SuperGrid.ActiveElement is GridRow) + { + GridRow arow = SuperGrid.ActiveElement as GridRow; + + if (cr == null) + return (arow == GridRow); + + if (arow.Parent == GridRow.Parent) + return (arow.RowIndex >= cr.RowStart && arow.RowIndex < cr.RowEnd); + } + + return (false); + } + + #endregion + + #region IsFocusedCell + + private bool IsFocusedCell(CellRange cr) + { + GridCell acell = SuperGrid.ActiveElement as GridCell; + + if (acell == null) + return (false); + + if (cr != null) + return (cr == acell.GetCellRange()); + + return (IsSameCell(acell)); + } + + #region IsSameCell + + internal bool IsSameCell(GridCell cell) + { + if (cell != null) + { + return (ColumnIndex == cell.ColumnIndex && + GridRow == cell.GridRow); + } + + return (false); + } + + #endregion + + #endregion + + #region RenderRowFocusRect + + private void RenderRowFocusRect( + Graphics g, GridPanel panel, Rectangle r, CellRange cr) + { + if (IsEmptyCell == false) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + Rectangle t = (IsVFrozen == true ? r : SViewRect); + + Rectangle lc = GetLeftCell(panel, t, cr); + Rectangle rc = GetRightCell(panel, t, cr); + + if (lc.IsEmpty == true && rc.IsEmpty == true) + { + RenderCellFocusRect(g, r); + } + else + { + using (Pen pen = new Pen(Color.Black, 1)) + { + pen.DashStyle = DashStyle.Dot; + + r.Width -= Dpi.Width1 + 1; + r.Height -= Dpi.Height1 + 1; + + r.Intersect(t); + + RenderVertFocus(g, r, lc, rc, pen); + RenderHorzFocus(g, r, lc, rc, pen); + } + } + + g.SmoothingMode = sm; + } + } + + #region RenderVertFocus + + private void RenderVertFocus(Graphics g, + Rectangle r, Rectangle lc, Rectangle rc, Pen pen) + { + pen.DashOffset = (r.X % 2); + + if (lc.IsEmpty == false) + { + if (r.Width > 1) + { + if (r.Y < lc.Y - pen.DashOffset) + g.DrawLine(pen, r.X, r.Y, r.X, lc.Y); + + if (lc.Bottom < r.Bottom - pen.DashOffset) + g.DrawLine(pen, r.X, lc.Bottom, r.X, r.Bottom); + } + } + else + { + if (r.Height > 1) + g.DrawLine(pen, r.X, r.Y, r.X, r.Bottom); + } + + if (rc.IsEmpty == false) + { + if (r.Width > 1) + { + if (r.Y < rc.Y - pen.DashOffset) + g.DrawLine(pen, r.Right, rc.Y, r.Right, r.Y); + + if (rc.Bottom < r.Bottom - pen.DashOffset) + g.DrawLine(pen, r.Right, rc.Bottom, r.Right, r.Bottom); + } + } + else + { + if (r.Height > 1) + g.DrawLine(pen, r.Right, r.Y, r.Right, r.Bottom); + } + } + + #endregion + + #region RenderHorzFocus + + private void RenderHorzFocus(Graphics g, + Rectangle r, Rectangle lc, Rectangle rc, Pen pen) + { + if (r.Width > 1) + { + int x1 = 0; + int x2 = 0; + + if (lc.IsEmpty == false) + { + if (lc.Y <= r.Y) + x1 = r.X - lc.Right; + } + + if (rc.IsEmpty == false) + { + if (rc.Y <= r.Y) + { + if (rc.X > r.Right) + x2 = rc.X - r.Right + 1; + } + } + + pen.DashOffset = ((r.X - x1) % 2); + + if (r.Right + x2 - (r.X - x1) > pen.DashOffset) + g.DrawLine(pen, r.X - x1, r.Y, r.Right + x2, r.Y); + + x1 = 0; + x2 = 0; + + if (lc.IsEmpty == false) + { + if (lc.Bottom >= r.Bottom) + { + x1 = r.X - lc.Right; + x2 = x1 - 1; + } + } + + if (rc.IsEmpty == false) + { + if (rc.Bottom >= r.Bottom) + { + if (rc.X > r.Right) + x2 = rc.X - r.Right + 1; + } + } + + pen.DashOffset = ((r.X - x1) % 2); + + if (r.Right + x2 - (r.X - x1) > pen.DashOffset) + g.DrawLine(pen, r.X - x1, r.Bottom, r.Right + x2, r.Bottom); + } + } + + #endregion + + #region GetLeftCell + + private Rectangle GetLeftCell(GridPanel panel, Rectangle t, CellRange cr) + { + GridColumnCollection columns = panel.Columns; + + GridColumn col = (cr != null) + ? columns.GetPrevVisibleColumn(columns.ColumnAtDisplayIndex(cr.ColumnStart)) + : columns.GetPrevVisibleColumn(GridColumn); + + Rectangle r = GetCellRect(col); + + r.Width -= Dpi.Width1 + 1; + r.Height -= Dpi.Height1 + 1; + + t.Intersect(r); + + return (t); + } + + #endregion + + #region GetRightCell + + private Rectangle GetRightCell(GridPanel panel, Rectangle t, CellRange cr) + { + GridColumnCollection columns = panel.Columns; + + GridColumn col = (cr != null) + ? columns.GetNextVisibleColumn(columns.ColumnAtDisplayIndex(cr.ColumnEnd - 1)) + : columns.GetNextVisibleColumn(GridColumn); + + while (col != null) + { + if (col.IsOnScreen == true) + break; + + col = columns.GetNextVisibleColumn(col); + } + + Rectangle r = GetCellRect(col); + + r.Width -= Dpi.Width1 + 1; + r.Height -= Dpi.Height1 + 1; + + t.Intersect(r); + + return (t); + } + + #endregion + + #region GetCellRect + + private Rectangle GetCellRect(GridColumn col) + { + if (col != null) + { + GridRow arow = SuperGrid.ActiveElement as GridRow; + + if (arow != null) + { + GridCell cell = arow.GetCell(col.ColumnIndex); + + if (cell != null) + { + CellRange cr2 = cell.GetStateCellRange(); + + if (cr2 != null) + return (cr2.BackBounds); + + return (cell.Bounds); + } + } + } + + return (Rectangle.Empty); + } + + #endregion + + #endregion + + #region RenderCellFocusRect + + private void RenderCellFocusRect(Graphics g, Rectangle bounds) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + ControlPaint.DrawFocusRectangle(g, bounds); + + g.SmoothingMode = sm; + } + + #endregion + + #endregion + + #endregion + + #region GetCellRange + + /// + ///Gets the CellRange, if any, that the cell is a member of. + /// + ///CellRange or null. + public CellRange GetCellRange() + { + GridContainer cont = RowContainer; + + if (cont != null) + return (cont.GetCellRange(this)); + + return (null); + } + + internal CellRange GetStateCellRange() + { + CellRange cr = GetCellRange(); + + if (cr != null) + { + if (cr.Suspended == true) + cr = null; + } + + Merged = (cr != null); + + return (cr); + } + + #endregion + + #region SuspendMerge + + /// + ///If the cell is currently participating in a merged range of + ///cells, then the merge will be suspended until the user clicks + ///away from the merged range (or ResumeMerge is called for the cell). + /// + ///If true, cell will be made the active cell. + public bool SuspendMerge(bool activate) + { + CellRange cr = GetStateCellRange(); + + if (cr != null) + SuspendMerge(cr); + + if (cr == null || cr.Suspended == true) + { + if (activate == true) + { + if (CanSetActiveCell(GridPanel) == true) + { + _needsMouseEnter = true; + + SetActive(true); + } + } + + return (true); + } + + return (false); + } + + internal void SuspendMerge(CellRange cr) + { + GridContainer cont = RowContainer; + + if (cont != null) + cont.SuspendMerge(cr); + } + + #endregion + + #region ResumeMerge + + /// + ///Resumes the suspended merge where the cell is a participant + /// + public void ResumeMerge(GridCell aCell) + { + GridContainer cont = RowContainer; + + if (cont != null) + { + if (ShouldResumeMerge(cont, aCell) == true) + RowContainer.ResumeMerge(); + } + } + + private bool ShouldResumeMerge(GridContainer cont, GridCell aCell) + { + if (aCell == null) + return (true); + + GridContainer aCont = aCell.RowContainer; + + if (aCont != cont) + return (true); + + CellRange cr = cont.SuspendedRange; + + if (cr != null) + { + if (cr.Equals(aCont.GetCellRange(aCell)) == true) + return (false); + } + + return (true); + } + + #endregion + + #region GetProposedSize + + private Size GetProposedSize(Graphics g, CellVisualStyle style, Size constraintSize) + { + return (GetProposedSize(g, style, constraintSize, null, CellSizingSource.ActualAndFormattedValues)); + } + + private Size GetProposedSize(Graphics g, + CellVisualStyle style, Size constraintSize, IGridCellEditControl editor, CellSizingSource sizingSource) + { + Size size = Size.Empty; + + if (IsValueExpression == true && ExpValue != null) + { + size = GetModalSize(g, ExpValue.ToString(), style, constraintSize); + } + else + { + if (editor == null) + { + if (CellEditMode != CellEditMode.Modal) + { + if (MouseRenderer == null || MouseRenderer.EditorCell == this) + editor = GetInternalEditControl(); + + if (editor != null && editor.EditorCell != this) + { + if (SuperGrid.ActiveNonModalEditor == editor) + editor = null; + } + + if (editor == null) + editor = GetInternalRenderControl(); + } + else + { + editor = SuperGrid.EditorCell == this + ? GetInternalEditControl() : GetInternalRenderControl(); + } + } + + if (editor != null) + { + bool suspended = editor.SuspendUpdate; + + try + { + editor.SuspendUpdate = true; + + if (SuperGrid.EditorCell != this) + InitializeContext(DataContext.CellProposedSize, editor, style); + + if (editor.CellEditMode == CellEditMode.Modal) + { + Size sizeActual = Size.Empty; + Size sizeFormatted = Size.Empty; + + string s = editor.EditorFormattedValue; + + SuperGrid.DoGetCellFormattedValueEvent(this, ref s, ref sizingSource); + + if ((sizingSource & CellSizingSource.ActualValue) == CellSizingSource.ActualValue) + sizeActual = editor.GetProposedSize(g, this, style, constraintSize); + + if ((sizingSource & CellSizingSource.FormattedValue) == CellSizingSource.FormattedValue) + sizeFormatted = GetModalSize(g, s, style, constraintSize); + + size.Height = Math.Max(sizeActual.Height, sizeFormatted.Height); + size.Width = Math.Max(sizeActual.Width, sizeFormatted.Width); + } + else + { + size = editor.GetProposedSize(g, this, style, constraintSize); + } + } + finally + { + editor.SuspendUpdate = suspended; + } + } + } + + return (size); + } + + #region GetModalSize + + private Size GetModalSize(Graphics g, + string text, CellVisualStyle style, Size constraintSize) + { + eTextFormat tf = style.GetTextFormatFlags(); + + string s = String.IsNullOrEmpty(text) ? " " : text; + + Size size = (constraintSize.IsEmpty == true) + ? TextHelper.MeasureText(g, s, style.Font) + : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); + + return (size); + } + + #endregion + + #endregion + + #region Mouse support + + #region InternalMouseEnter + + internal override void InternalMouseEnter(EventArgs e) + { + base.InternalMouseEnter(e); + + if (GridColumn != null) + { + GridColumn.IsMouseOver = true; + + DoRendererMouseEnter(); + + SuperGrid.ToolTipText = ""; + _toolTipText = null; + + if (GridPanel.SelectionGranularity != SelectionGranularity.Cell) + GridRow.InvalidateRender(GridRow.Bounds); + + SuperGrid.DoCellMouseEnterEvent(this); + } + } + + #region DoRendererMouseEnter + + private void DoRendererMouseEnter() + { + if (CellEditMode != DotNetBar.SuperGrid.CellEditMode.Modal) + { + CellRange cr = GetStateCellRange(); + + if (cr != null && cr.Suspended == false) + return; + } + + _needsMouseEnter = true; + + if (SuperGrid.ActiveEditor == null) + { + _needsMouseEnter = false; + + if (IsEmptyCell == false) + { + CellVisualStyle style = GetEffectiveStyle(); + + MouseRenderer = null; + + if (CellEditMode != CellEditMode.Modal) + MouseRenderer = GetInternalEditControl(); + + if (MouseRenderer == null) + MouseRenderer = GetInternalRenderControl(); + + if (MouseRenderer != null) + { + switch (CellEditMode) + { + case CellEditMode.InPlace: + InitializeContext(DataContext.CellMouseEvent, MouseRenderer, style); + GetCurrentContentSize(style, MouseRenderer); + break; + + case CellEditMode.NonModal: + if (CanModifyMerge == true) + { + if (SuperGrid.ActiveNonModalEditor == null || + SuperGrid.ActiveNonModalEditor.CanInterrupt == true) + { + if (SuperGrid.ActiveNonModalEditor != null) + { + SuperGrid.DeactivateNonModalEditor(); + + if (MouseRenderer == null) + _needsMouseEnter = true; + } + + if (MouseRenderer != null) + { + InitializeContext(DataContext.CellMouseEvent, MouseRenderer, style); + + PositionEditControl(MouseRenderer); + + MouseRenderer.BeginEdit(false); + MouseRenderer.OnCellMouseEnter(EventArgs.Empty); + + SuperGrid.ActivateNonModalEditor(MouseRenderer, this); + } + } + else + { + MouseRenderer = null; + _needsMouseEnter = true; + } + } + break; + } + + if (MouseRenderer != null) + InvalidateRender(); + } + } + else + { + InvalidateRender(); + } + } + } + + #endregion + + #endregion + + #region InternalMouseLeave + + internal override void InternalMouseLeave(EventArgs e) + { + if (GridColumn != null) + { + DoRendererMouseLeave(e); + + GridColumn.IsMouseOver = false; + + if (_lastHitArea == CellArea.InCellInfo) + ProcessCellInfoLeave(); + + if (GridPanel != null) + { + if (GridPanel.SelectionGranularity != SelectionGranularity.Cell) + GridRow.InvalidateRender(GridRow.Bounds); + else + InvalidateRender(); + } + + SuperGrid.DoCellMouseLeaveEvent(this); + + SuperGrid.ToolTipText = ""; + _toolTipText = null; + + _lastHitArea = CellArea.NoWhere; + } + + base.InternalMouseLeave(e); + } + + #region DoRendererMouseLeave + + internal void DoRendererMouseLeave(EventArgs e) + { + if (MouseRenderer != null && + ((Control) MouseRenderer).IsDisposed == false) + { + if (CellEditMode != CellEditMode.InPlace || _mouseInItem == true) + MouseRenderer.OnCellMouseLeave(e); + } + + _mouseInItem = false; + MouseRenderer = null; + _needsMouseEnter = false; + + InvalidateRender(); + } + + #endregion + + #endregion + + #region InternalMouseMove + + internal override void InternalMouseMove(MouseEventArgs e) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (CapturedItem != null && e.Button != MouseButtons.None) + ProcessMouseDownMove(e, panel); + + ProcessMouseMove(e); + + base.InternalMouseMove(e); + + DoRendererMouseMove(e); + + SuperGrid.DoCellMouseMoveEvent(this, e); + } + } + + #region DoRendererMouseMove + + private void DoRendererMouseMove(MouseEventArgs e) + { + if (_needsMouseEnter == true) + DoRendererMouseEnter(); + + if (MouseRenderer != null && + ((Control)MouseRenderer).IsDisposed == false) + { + if (CellEditMode == CellEditMode.InPlace) + { + DoInPlaceMouseMove(e); + } + else + { + if (CanModify == true) + { + Rectangle r = GetAdjustedBounds(EditBounds); + Point pt = SuperGrid.PointToClient(Control.MousePosition); + + if (r.Contains(pt) == true) + MouseRenderer.OnCellMouseMove(GetControlMouseArgs(e)); + } + } + } + } + + #region DoInPlaceMouseMove + + private void DoInPlaceMouseMove(MouseEventArgs e) + { + if (IsMouseDown == false || _mouseDownInItem == true) + { + if (MouseRenderer != null) + { + if (MouseRenderer.EditorCell != this) + InitializeContext(DataContext.CellMouseEvent, MouseRenderer, null); + + Rectangle r = GetAdjustedBounds(ContentBounds); + r = GetEditPanelBounds(MouseRenderer, r); + + bool inItem = r.Contains(e.Location); + + if (_mouseInItem != inItem) + { + if (inItem == true) + MouseRenderer.OnCellMouseEnter(EventArgs.Empty); + else + MouseRenderer.OnCellMouseLeave(EventArgs.Empty); + + _mouseInItem = inItem; + } + + if (_mouseInItem == true) + MouseRenderer.OnCellMouseMove(GetControlMouseArgs(e, r)); + } + } + } + + #endregion + + #endregion + + #region ProcessMouseDownMove + + private void ProcessMouseDownMove(MouseEventArgs e, GridPanel panel) + { + if (_mouseDownHitCell != null) + { + if (_mouseDownHitArea == CellArea.InContent) + { + Rectangle r = ViewRect; + + if (MouseDownPoint.Y < r.Y) + { + int n = SuperGrid.PrimaryGrid.FixedRowHeight - + SuperGrid.PrimaryGrid.FixedHeaderHeight; + + r.Y -= n; + r.Height += n; + } + + if ((e.Y >= r.Y && e.Y < r.Bottom) && (e.X >= r.X && e.X < r.Right)) + { + SuperGrid.DisableAutoScrolling(); + + ProcessInContent(panel, e); + } + else + { + SuperGrid.EnableAutoScrolling( + AutoScrollEnable.Horizontal | AutoScrollEnable.Vertical, r); + } + } + } + } + + #region ProcessInContent + + private void ProcessInContent(GridPanel panel, MouseEventArgs e) + { + Point pt = e.Location; + + Rectangle t = SViewRect; + pt.X = Math.Min(t.Right - 1, pt.X); + pt.X = Math.Max(t.X, pt.X); + + Rectangle v = panel.BoundsRelative; + v.Location = panel.PointToScroll(v.Location); + pt.X = Math.Min(v.Right - 1, pt.X); + pt.X = Math.Max(v.X, pt.X); + + GridCell lastCell = _hitCell; + + _hitCell = GetCellAt(panel, pt); + + if (DragStarted(panel, pt, e) == false) + { + if (_hitCell != null && _hitArea == CellArea.InContent) + { + if (panel.MultiSelect == true) + { + if (lastCell != null) + lastCell.IsMouseOver = false; + + _hitCell.IsMouseOver = true; + + if (panel.CellDragBehavior == CellDragBehavior.ExtendSelection) + { + if (panel.LastProcessedItem is GridCell && + _hitCell != panel.LastProcessedItem) + { + if (SuperGrid.ActiveEditor == null) + ProcessExtendSelection(panel, true); + } + } + } + } + } + } + + #region DragStarted + + private bool DragStarted(GridPanel panel, Point pt, MouseEventArgs e) + { + if (IsDragSelection == true) + { + if (IsDragStarted == false) + { + if (DragDrop.DragStarted(_mouseDownPoint, pt) == true) + { + IsDragStarted = true; + + if (SuperGrid.DoItemDragEvent(this, e) == true) + { + IsDragSelection = false; + + ExtendSelection(panel); + } + } + } + + return (true); + } + + return (false); + } + + #endregion + + #region GetCellAt + + private GridCell GetCellAt(GridPanel panel, Point pt) + { + Rectangle t = ViewRect; + pt.X = Math.Min(t.Right - 1, pt.X); + pt.X = Math.Max(t.X, pt.X); + + Rectangle v = panel.BoundsRelative; + v.Location = panel.PointToScroll(v.Location); + pt.X = Math.Min(v.Right - 1, pt.X); + pt.X = Math.Max(v.X, pt.X); + + GridRow row = panel.InternalGetElementAt(pt.X, pt.Y) as GridRow; + + while (row != null) + { + GridElement item = row.InternalGetElementAt(pt.X, pt.Y); + + if (item is GridCell) + return (item as GridCell); + + row = item as GridRow; + } + + return (null); + } + + #endregion + + #endregion + + #endregion + + #region ProcessMouseMove + + private void ProcessMouseMove(MouseEventArgs e) + { + _hitArea = GetCellAreaAt(e); + _hitCell = this; + + if (_hitArea == CellArea.InContent) + SuperGrid.GridCursor = Cursors.Default; + + if (_hitArea != _lastHitArea) + { + ProcessToolTipText(e); + + _lastHitArea = _hitArea; + + InvalidateRender(); + } + + base.InternalMouseMove(e); + } + + #region ProcessToolTipText + + private void ProcessToolTipText(MouseEventArgs e) + { + if (_hitArea == CellArea.InContent) + ProcessCellToolTip(); + + else if (_hitArea == CellArea.InCellInfo) + ProcessCellInfoEnter(e); + + if (_lastHitArea == CellArea.InCellInfo) + ProcessCellInfoLeave(); + } + + #region ProcessCellToolTip + + private void ProcessCellToolTip() + { + SetToolTip(GridPanel.ShowToolTips ? GetToolTipText() : string.Empty); + } + + #region GetToolTipText + + private string GetToolTipText() + { + if (_toolTipText == null) + { + CellRange cr = GetStateCellRange(); + + if (cr != null) + { + _toolTipText = cr.ToolTip ?? ""; + } + else + { + string s = ""; + + if (SuperGrid.DoGetCellToolTipEvent(GridPanel, this, ref s) == false) + { + _toolTipText = ""; + + if (IsEmptyCell == false) + { + CellVisualStyle style = GetEffectiveStyle(); + + Rectangle r = GetAdjustedBounds(ContentBounds); + + if (MouseRenderer != null && + ((Control)MouseRenderer).IsDisposed == false) + { + Size size = new + Size(style.AllowWrap == Tbool.True ? r.Width : 0, 0); + + using (Graphics g = SuperGrid.CreateGraphics()) + size = GetProposedSize(g, style, size, MouseRenderer, CellSizingSource.FormattedValue); + + if (size.Width > r.Width || size.Height > r.Height) + _toolTipText = String.IsNullOrEmpty(s) ? GetFormattedValue(MouseRenderer) : s; + } + } + } + else + { + _toolTipText = s; + } + } + } + + return (_toolTipText); + } + + #endregion + + #endregion + + #region ProcessCellInfoEnter + + private void ProcessCellInfoEnter(MouseEventArgs e) + { + SetToolTip(SuperGrid.DoCellInfoEnterEvent(this, + SuperGrid, SuperGrid.ToolTip, e.Location) ? "" : InfoText); + } + + #endregion + + #region ProcessCellInfoLeave + + private void ProcessCellInfoLeave() + { + SuperGrid.DoCellInfoLeaveEvent(this, SuperGrid, SuperGrid.ToolTip); + } + + #endregion + + #region SetToolTip + + private void SetToolTip(string toolTipText) + { + if (SuperGrid.ToolTipText != _toolTipText) + SuperGrid.ToolTip.Hide(SuperGrid); + + SuperGrid.ToolTipText = toolTipText; + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region InternalMouseDown + + internal override void InternalMouseDown(MouseEventArgs e) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + SuperGrid.DoCellMouseDownEvent(this, e); + + _mouseDownPoint = e.Location; + + IsDragSelection = false; + IsDragStarted = false; + + if (_hitArea == CellArea.InContent || _hitArea == CellArea.InCellInfo) + { + _mouseDownHitArea = CellArea.NoWhere; + + if (_hitCell != null && + _hitCell.CanSetActiveCell(panel) == true) + { + _mouseDownHitArea = _hitArea; + _mouseDownHitCell = _hitCell; + + if (panel.SelectionGranularity == SelectionGranularity.Cell) + { + panel.LastProcessedItem = _hitCell; + + InitSelectOrDrag(panel); + } + + DoRendererMouseDown(e); + } + } + } + + base.InternalMouseDown(e); + } + + #region DoRendererMouseDown + + private void DoRendererMouseDown(MouseEventArgs e) + { + if (CanModifyMerge == true) + { + if (_needsMouseEnter == true) + DoRendererMouseEnter(); + + if (MouseRenderer != null) + { + if (_mouseInItem == true) + { + _mouseDownInItem = true; + + if (MouseRenderer.EditorCell != this) + InitializeContext(DataContext.CellMouseEvent, MouseRenderer, null); + + MouseRenderer.OnCellMouseDown(GetControlMouseArgs(e)); + } + } + } + } + + #endregion + + #region CanSetActiveCell + + internal bool CanSetActiveCell(GridPanel panel) + { + GridCell acell = SuperGrid.ActiveCell; + + if (acell != this) + { + if (IsSelectable == false || + (IsEmptyCell == true && panel.AllowEmptyCellSelection == false)) + { + if (SuperGrid.DoPlayingSoundEvent(panel, this, PlaySoundContext.CellActivate) == false) + SystemSounds.Beep.Play(); + + return (false); + } + + GridCell ecell = SuperGrid.EditorCell; + + if (ecell != null) + { + if (ecell.EndEdit() == false) + return (false); + } + + if (acell != null) + acell.ResumeMerge(this); + + if (GridRow.IsActive == false) + { + if (GridRow.CanSetActiveRow(false) == false) + return (false); + + if (panel.SetActiveRow(GridRow, true) == false) + return (false); + } + + if (panel.SelectionGranularity != SelectionGranularity.Row) + { + if (SuperGrid.DoCellActivatingEvent(panel, acell, this) == true) + return (false); + + SuperGrid.ActiveCell = this; + + if (panel.SelectionGranularity == SelectionGranularity.Cell) + { + SuperGrid.ActiveElement = this; + + panel.LastProcessedItem = this; + } + } + } + + return (true); + } + + #endregion + + #region ProcessExtendSelection + + private void ProcessExtendSelection(GridPanel panel, bool extend) + { + bool ckey = (panel.MultiSelect == true) ? + ((Control.ModifierKeys & Keys.Control) == Keys.Control) : false; + + if (ckey == true) + ProcessControlExtend(panel, extend); + else + ProcessNonControlExtend(panel, extend); + + panel.LastProcessedItem = _hitCell; + } + + #region ProcessControlExtend + + private void ProcessControlExtend(GridPanel panel, bool extend) + { + GridCell cell = panel.LastProcessedItem as GridCell; + + if (cell != null) + { + int startRowIndex = cell.GridRow.GridIndex; + int startColumnIndex = panel.Columns.GetDisplayIndex(cell.GridColumn); + + int[] map = panel.Columns.DisplayIndexMap; + + if (extend == false) + { + int columnIndex = map[startColumnIndex]; + + SetSelectedMerge(panel, startRowIndex, + startColumnIndex, startRowIndex, startColumnIndex, 0); + + panel.SetSelectedCells(startRowIndex, columnIndex, + 1, 1, !panel.IsCellSelected(startRowIndex, columnIndex)); + + cell.InvalidateRender(); + + panel.ColumnHeader.InvalidateRowHeader(); + } + else + { + int endRowIndex = _hitCell.GridRow.GridIndex; + int endColumnIndex = panel.Columns.GetDisplayIndex(_hitCell.GridColumn); + + if (endColumnIndex - startColumnIndex != 0) + { + SelectControlColumn(panel, map, + startColumnIndex, endColumnIndex, startRowIndex); + } + + if (endRowIndex - startRowIndex != 0) + { + SelectControlRow(panel, map, + startRowIndex, endRowIndex, endColumnIndex); + } + } + } + } + + #region SelectControlColumn + + private void SelectControlColumn(GridPanel panel, int[] map, + int startColumnIndex, int endColumnIndex, int startRowIndex) + { + int endRowIndex = startRowIndex; + + panel.NormalizeIndices(true, + _anchorColumnIndex, ref startColumnIndex, ref endColumnIndex); + + panel.NormalizeIndices(false, + _anchorRowIndex, ref startRowIndex, ref endRowIndex); + + if (endRowIndex > _anchorRowIndex) + startRowIndex = _anchorRowIndex; + + else if (startRowIndex < _anchorRowIndex) + endRowIndex = _anchorRowIndex; + + for (int i = startRowIndex; i <= endRowIndex; i++) + { + for (int j = startColumnIndex; j <= endColumnIndex; j++) + { + if (j != _anchorColumnIndex) + { + int columnIndex = map[j]; + + panel.SetSelectedCells(i, columnIndex, 1, 1, + !panel.IsCellSelected(i, columnIndex)); + } + } + } + + panel.InvalidateCells(startRowIndex, + endRowIndex, startColumnIndex, endColumnIndex); + } + + #endregion + + #region SelectControlRow + + private void SelectControlRow(GridPanel panel, int[] map, + int startRowIndex, int endRowIndex, int endColumnIndex) + { + int startColumnIndex = endColumnIndex; + + panel.NormalizeIndices(false, + _anchorColumnIndex, ref startColumnIndex, ref endColumnIndex); + + panel.NormalizeIndices(true, + _anchorRowIndex, ref startRowIndex, ref endRowIndex); + + if (endColumnIndex > _anchorColumnIndex) + startColumnIndex = _anchorColumnIndex; + + else if (startColumnIndex < _anchorColumnIndex) + endColumnIndex = _anchorColumnIndex; + + for (int i = startRowIndex; i <= endRowIndex; i++) + { + for (int j = startColumnIndex; j <= endColumnIndex; j++) + { + if (i != _anchorRowIndex) + { + int columnIndex = map[j]; + + panel.SetSelectedCells(i, columnIndex, 1, 1, + !panel.IsCellSelected(i, columnIndex)); + } + } + } + + panel.InvalidateCells(startRowIndex, + endRowIndex, startColumnIndex, endColumnIndex); + } + + #endregion + + #endregion + + #region ProcessNonControlExtend + + private void ProcessNonControlExtend(GridPanel panel, bool extend) + { + bool skey = (panel.MultiSelect == true) ? + ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) : false; + + if (skey == false || + panel.SelectionRowAnchor == null || + panel.SelectionColumnAnchor == null) + { + panel.SelectionRowAnchor = _mouseDownHitCell.GridRow; + panel.SelectionColumnAnchor = _mouseDownHitCell.GridColumn; + } + + ExtendSelection(panel, _hitCell, extend); + } + + #endregion + + #endregion + + #region InitSelectOrDrag + + private void InitSelectOrDrag(GridPanel panel) + { + if (panel.SuperGrid.HasItemDragHandler == false || panel.IsItemSelected(this) == false || + ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) != Keys.None)) + { + ExtendSelection(panel); + } + else if (IsMouseDown == true) + { + IsDragSelection = true; + + Capture = true; + } + } + + #endregion + + #endregion + + #region InternalMouseUp + + internal override void InternalMouseUp(MouseEventArgs e) + { + if (GridColumn != null) + { + if (CanModifyMerge == true) + DoRendererMouseUp(e); + + _mouseDownInItem = false; + + SuperGrid.DoCellMouseUpEvent(this, e); + + if (InfoImageBounds.Contains(e.X, e.Y) == true) + { + SuperGrid.DoCellInfoClickEvent(this, e); + } + else + { + if (_mouseDownHitCell == this && IsMouseOver == true) + { + if (SuperGrid.DoCellClickEvent(this, e) == false) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if ((e.Button & MouseButtons.Left) == MouseButtons.Left) + { + if (IsDragSelection == true) + ExtendSelectionEx(panel); + + if (_hitArea == CellArea.InContent) + { + if (panel.MouseEditMode == MouseEditMode.SingleClick) + { + //if (Bounds.Contains(e.X, e.Y) == true) + { + if (CanSetActiveCell(GridPanel) == true) + BeginEdit(true); + } + } + } + } + } + } + } + } + } + + IsDragSelection = false; + + base.InternalMouseUp(e); + } + + #region DoRendererMouseUp + + private void DoRendererMouseUp(MouseEventArgs e) + { + if (MouseRenderer != null) + { + if (_mouseDownInItem == true) + { + if (MouseRenderer.EditorCell != this) + InitializeContext(DataContext.CellMouseEvent, MouseRenderer, null); + + MouseRenderer.OnCellMouseUp(GetControlMouseArgs(e)); + + SuperGrid.Focus(); + } + } + } + + #endregion + + #endregion + + #region InternalMouseDoubleClick + + internal override void InternalMouseDoubleClick(MouseEventArgs e) + { + GridPanel panel = GridPanel; + + if (InfoImageBounds.Contains(e.X, e.Y) == true) + { + SuperGrid.DoCellInfoDoubleClickEvent(this, e); + } + else + { + if (SuperGrid.DoCellDoubleClickEvent(this, e) == false) + { + if (_hitArea == CellArea.InContent && + panel.MouseEditMode == MouseEditMode.DoubleClick) + { + if (CanSetActiveCell(panel) == true) + { + CellRange cr = GetStateCellRange(); + + if (cr != null && cr.Suspended == false) + { + if (cr.AllowSuspend == true) + { + SuspendMerge(cr); + + if (_mouseDownHitCell != null) + { + _needsMouseEnter = true; + _mouseDownHitCell.SetActive(true); + } + } + else + { + if (SuperGrid.DoPlayingSoundEvent(panel, cr, PlaySoundContext.CellActivate) == false) + SystemSounds.Beep.Play(); + } + } + else + { + BeginEdit(true); + } + } + } + + _mouseDownHitCell = null; + } + } + } + + #region DoRendererMouseDoubleClick + + private void DoRendererMouseDoubleClick(MouseEventArgs e) + { + if (CanModify == true) + { + if (MouseRenderer != null) + { + if (_mouseDownInItem == true) + { + if (MouseRenderer.EditorCell != this) + InitializeContext(DataContext.CellMouseEvent, MouseRenderer, null); + + MouseRenderer.OnCellMouseDown(GetControlMouseArgs(e)); + } + } + } + } + + #endregion + + #endregion + + #endregion + + #region GetControlMouseArgs + + private MouseEventArgs GetControlMouseArgs(MouseEventArgs e) + { + Rectangle r = GetAdjustedBounds(ContentBounds); + r = GetEditPanelBounds(MouseRenderer, r); + + return (GetControlMouseArgs(e, r)); + } + + private MouseEventArgs + GetControlMouseArgs(MouseEventArgs e, Rectangle r) + { + int x = e.X - r.X; + int y = e.Y - r.Y; + + MouseEventArgs args = new + MouseEventArgs(e.Button, e.Clicks, x, y, e.Delta); + + return (args); + } + + #endregion + + #region ExtendSelection + + internal void ExtendSelection(GridPanel panel, GridCell endCell, bool extend) + { + if (panel.SelectionColumnAnchor is GridColumn) + { + int startRowIndex = panel.SelectionRowAnchor.GridIndex; + int startColumnIndex = panel.Columns.GetDisplayIndex((GridColumn)(panel.SelectionColumnAnchor)); + + int endRowIndex = endCell.GridRow.GridIndex; + int endColumnIndex = panel.Columns.GetDisplayIndex(endCell.GridColumn); + + if (startRowIndex < 0) + startRowIndex = endRowIndex; + + panel.NormalizeIndices(false, 0, ref startRowIndex, ref endRowIndex); + panel.NormalizeIndices(false, 0, ref startColumnIndex, ref endColumnIndex); + + if (startColumnIndex < 0) + startColumnIndex = 0; + + if (endColumnIndex < 0) + endColumnIndex = 0; + + if (panel.OnlyCellsSelected( + startRowIndex, startColumnIndex, endRowIndex, endColumnIndex) == false) + { + ClearSelected(panel, extend); + + if (startRowIndex >= 0 && endRowIndex >= 0) + { + SetSelected(panel, startRowIndex, + startColumnIndex, endRowIndex, endColumnIndex); + + InvalidateSelected(panel, startRowIndex, + startColumnIndex, endRowIndex, endColumnIndex); + } + } + } + } + + #region InvalidateSelected + + private void InvalidateSelected(GridPanel panel, + int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) + { + GridCell lastCell = (Control.MouseButtons == MouseButtons.None) + ? SuperGrid.LastActiveCell : panel.LastProcessedItem as GridCell; + + if (lastCell != null) + { + int lastIndex = panel.Columns.GetDisplayIndex(lastCell.ColumnIndex); + + if (lastIndex < startColumnIndex) + startColumnIndex = lastIndex; + + else if (lastIndex > endColumnIndex) + endColumnIndex =lastIndex; + + if (lastCell.GridRow.GridIndex < startRowIndex) + startRowIndex = lastCell.GridRow.GridIndex; + + else if (lastCell.GridRow.GridIndex > endRowIndex) + endRowIndex = lastCell.GridRow.GridIndex; + } + + panel.InvalidateCells(startRowIndex, + endRowIndex, startColumnIndex, endColumnIndex); + } + + #endregion + + #region SetSelected + + private void SetSelected(GridPanel panel, + int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) + { + SetSelectedMerge(panel, startRowIndex, + startColumnIndex, endRowIndex, endColumnIndex, 1); + + int[] map = panel.Columns.DisplayIndexMap; + + for (int i = startColumnIndex; i <= endColumnIndex; i++) + { + panel.SetSelectedCells(startRowIndex, map[i], + endRowIndex - startRowIndex + 1, 1, true); + } + } + + #region SetSelectedMerge + + private void SetSelectedMerge(GridPanel panel, int startRowIndex, + int startColumnIndex, int endRowIndex, int endColumnIndex, int selected) + { + if (panel.EnableCellMerging == true) + { + GridContainer cont = RowContainer; + + if (cont != null) + { + GridContainer srow = panel.GetRowFromIndex(startRowIndex); + GridContainer erow = panel.GetRowFromIndex(endRowIndex); + + if (srow != null && erow != null) + { + int sRowIndex = panel.GetRowFromIndex(startRowIndex).RowIndex; + int eRowIndex = panel.GetRowFromIndex(endRowIndex).RowIndex; + + cont.SetMergeSelection(sRowIndex, + eRowIndex, startColumnIndex, endColumnIndex, selected); + } + } + } + } + + #endregion + + #endregion + + #region ClearSelected + + private void ClearSelected(GridPanel panel, bool extend) + { + if (panel.IsGrouped == false && + (panel.SelectedCellCount < 50 && panel.SelectedRowCount < 10 && panel.SelectedColumnCount < 10)) + { + foreach (GridCell cell in panel.SelectedCells) + cell.IsSelected = false; + + foreach (GridColumn col in panel.SelectedColumns) + col.IsSelected = false; + + foreach (GridContainer row in panel.SelectedRows) + { + if (row != null) + row.IsSelected = false; + } + + RowContainer.ClearAllMergeSelected(); + } + else + { + panel.ClearAll(extend == false); + } + + panel.SelectionClearCount++; + } + + #endregion + + #endregion + + #region GetNextCell + + internal GridCell GetNextCell(bool canSelect) + { + return (GetNextCell(canSelect, true)); + } + + internal GridCell GetNextCell(bool canSelect, bool multiRow) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + int[] map = panel.Columns.DisplayIndexMap; + int index = panel.Columns.GetDisplayIndex(GridColumn); + + int anchor = index; + + GridRow row = GridRow; + + while (row != null) + { + if (row.AllowSelection == true) + { + while (++index < map.Length) + { + if (multiRow == false && index == anchor) + return (null); + + GridColumn column = panel.Columns[map[index]]; + + if (column.Visible == true && + (canSelect == false || column.AllowSelection == true)) + { + GridCell cell = row.GetCell( + column.ColumnIndex, panel.AllowEmptyCellSelection); + + if (cell != null) + { + if (canSelect == false || cell.AllowSelection == true) + return (cell); + } + } + } + } + + if (multiRow == true) + row = row.NextVisibleRow as GridRow; + else + break; + + index = -1; + } + } + + return (null); + } + + #endregion + + #region GetPreviousCell + + internal GridCell GetPreviousCell(bool canSelect) + { + return (GetPreviousCell(canSelect, true)); + } + + internal GridCell GetPreviousCell(bool canSelect, bool multiRow) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + int[] map = panel.Columns.DisplayIndexMap; + int index = panel.Columns.GetDisplayIndex(GridColumn); + + int anchor = index; + + GridRow row = GridRow; + + while (row != null) + { + if (row.AllowSelection == true) + { + while (--index >= 0) + { + if (multiRow == false && index == anchor) + return (null); + + GridColumn column = panel.Columns[map[index]]; + + if (column.Visible == true && + (canSelect == false || column.AllowSelection == true)) + { + GridCell cell = row.GetCell( + column.ColumnIndex, panel.AllowEmptyCellSelection); + + if (cell != null) + { + if (canSelect == false || cell.AllowSelection == true) + return (cell); + } + } + } + } + + if (multiRow == true) + row = row.PrevVisibleRow as GridRow; + else + break; + + index = map.Length; + } + } + + return (null); + } + + #endregion + + #region GetCellAreaAt + + /// + /// Returns element at specified mouse coordinates + /// + /// Mouse event arguments + /// Reference to child Cell element or null + /// if no element at specified coordinates + protected virtual CellArea GetCellAreaAt(MouseEventArgs e) + { + return GetCellAreaAt(e.X, e.Y); + } + + /// + /// Returns element at specified mouse coordinates + /// + /// Horizontal position + /// Vertical position + /// Reference to child element or null + /// if no element at specified coordinates + protected virtual CellArea GetCellAreaAt(int x, int y) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (InfoImageBounds.Contains(x, y) == true) + return (CellArea.InCellInfo); + + if (IsPrimaryCell == true) + { + GridRow cellRow = GridRow; + + if (cellRow != null) + { + Rectangle r = cellRow.ExpandButtonBounds; + + if (cellRow.IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || GridColumn.IsHFrozen == false) + r.X -= HScrollOffset; + + if (r.Contains(x, y) == true) + return (CellArea.InExpandButton); + + r = cellRow.CheckBoxBounds; + + if (cellRow.IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || GridColumn.IsHFrozen == false) + r.X -= HScrollOffset; + + if (r.Contains(x, y) == true) + return (CellArea.InCheckBox); + } + } + } + + return (CellArea.InContent); + } + + #endregion + + #region EnsureVisible + + /// + /// Ensures that the given cell is visibly centered + /// (as much as possible) in the grid display. + /// + /// + public override void EnsureVisible(bool center) + { + if (GridRow.Visible == true && GridColumn.Visible == true) + { + if (IsVFrozen == false) + GridRow.EnsureVisible(center); + + GridColumn column = GridColumn; + + if (column != null && column.IsHFrozen == false) + column.EnsureVisible(center); + } + } + + #endregion + + #region SetActive + + /// + /// Sets the given cell as Active + /// + ///true - if successful + public bool SetActive() + { + return (SetActive(false)); + } + + /// + /// Makes the given cell active and + /// optionally selects the given cell + /// + ///true, if successful + public bool SetActive(bool select) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.SetActiveCell(this) == true) + { + if (select == true) + { + panel.ClearAll(); + + IsSelected = true; + } + + return (true); + } + } + + return (false); + } + + #endregion + + #region Editor support + + #region GetEditControl + + internal IGridCellEditControl GetEditControl(Type type, object[] args) + { + if (type != null) + { + IGridCellEditControl editor = + Activator.CreateInstance(type, args) as IGridCellEditControl; + + if (editor is Control == false) + throw new Exception("Edit/Render Type must be based on 'Control'."); + + editor.EditorPanel = new EditorPanel(); + editor.EditorPanel.Visible = false; + editor.EditorPanel.Controls.Add((Control) editor); + + return (editor); + } + + return (null); + } + + #endregion + + #region GetInternalEditControl + + internal IGridCellEditControl GetInternalEditControl() + { + return (GetInternalEditControl(CanModify)); + } + + internal IGridCellEditControl GetInternalEditControl(bool canModify) + { + if (canModify == true) + { + if (SuperGrid.EditorCell != this) + { + Type editorType = _EditorInfo != null ? _EditorInfo.EditorType : null; + object[] editorParams = _EditorInfo != null ? _EditorInfo.EditorParams : null; + + SuperGrid.DoGetEditorEvent(GridPanel, this, ref editorType, ref editorParams); + + EditorType = editorType; + EditorParams = editorParams; + } + + return (EditControl ?? (GridColumn != null ? GridColumn.EditControl : null)); + } + + return (null); + } + + #endregion + + #region GetInternalRenderControl + + private IGridCellEditControl GetInternalRenderControl() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Type renderType = _EditorInfo != null ? _EditorInfo.RenderType : null; + object[] renderParams = _EditorInfo != null ? _EditorInfo.RenderParams : null; + + SuperGrid.DoGetRendererEvent(panel, this, ref renderType, ref renderParams); + + RenderType = renderType; + RenderParams = renderParams; + + return (RenderControl ?? (GridColumn != null ? GridColumn.RenderControl : null)); + } + + return (null); + } + + #endregion + + #region BeginEdit + + /// + /// Begins a Modal cell edit operation using + /// the defined column or cell Modal EditControl. + /// + /// + /// + public IGridCellEditControl BeginEdit(bool selectAll) + { + return (BeginEdit(selectAll, null)); + } + + /// + /// Begins a Modal cell edit operation using the defined column + /// or cell Modal EditControl. If a KeyEvent is provided then + /// the event will be presented to the editor control. + /// + ///Cell edit control + public IGridCellEditControl BeginEdit(bool selectAll, KeyEventArgs e) + { + GridCell ecell = SuperGrid.EditorCell; + + if (ecell == this) + return (GetInternalEditControl()); + + if (ecell != null) + throw new Exception("Modal Cell edit is already in process."); + + if (Visible == true && CanModify == true) + { + GridPanel.FlushSelected(); + + IGridCellEditControl editor = GetInternalEditControl(); + + if (editor != null && editor.CellEditMode == CellEditMode.Modal) + { + if (SuspendMerge(false) == true) + { + CellVisualStyle style = GetEffectiveStyle(StyleState.Default); + + SuperGrid.DeactivateNonModalEditor(); + + DoRendererMouseLeave(EventArgs.Empty); + EnsureVisible(); + + GetCurrentContentSize(style, editor); + + InitializeContext(DataContext.CellEdit, editor, style); + + if (SuperGrid.DoBeginEditEvent(GridPanel, this, editor) == false) + { + SuperGrid.ActiveEditor = editor; + SuperGrid.EditorCell = this; + + PositionEditPanel(editor); + + editor.EditorPanel.Show(); + editor.EditorPanel.BringToFront(); + + if (editor.BeginEdit(selectAll) == false) + { + UpdateInfoWindow(); + + FocusEditor(editor); + + if (e != null) + SuperGrid.PressKeyDown((ushort) e.KeyCode); + + return (editor); + } + + CloseEdit(editor); + } + } + } + } + + return (null); + } + + #endregion + + #region EndEdit + + /// + /// This routine ends an in-progress Modal cell edit operation. + /// + ///true if ended + public bool EndEdit() + { + IGridCellEditControl editor = SuperGrid.ActiveEditor; + + if (editor != null && CellEditMode == CellEditMode.Modal) + { + if (editor.EditorCell == this) + { + if (GridRow.EditorDirty == true) + { + if (ValidateCellEdit(editor) == false) + return (false); + + GridRow.EditorDirty = false; + + object value = Value; + + if (UpdateCellValue(editor) == true) + Value = value; + } + + if (SuperGrid.DoEndEditEvent(GridPanel, this, editor) == false) + { + if (editor.EndEdit() == false) + { + CloseEdit(editor); + + return (true); + } + } + + return (false); + } + } + + return (true); + } + + #region UpdateCellValue + + /// + /// Used by IGridCellEditControl editors to update the + /// cell Value from the EditorValue, performing any needed + /// data conversions for proper data typing. + /// + /// + /// + public bool UpdateCellValue(IGridCellEditControl editor) + { + object value = editor.EditorValue; + + while (true) + { + try + { + ConvertValueToType(editor, value); + + return (false); + } + catch (Exception exp) + { + bool throwException = true; + bool retry = false; + + if (SuperGrid.HasDataErrorHandler == true) + { + if (SuperGrid.DoDataErrorEvent(GridPanel, this, exp, + DataContext.CellValueStore, ref value, ref throwException, ref retry) == true) + { + return (true); + } + } + + if (throwException == true) + { + MessageBoxEx.Show(exp.ToString()); + throw; + } + + if (retry == false) + break; + } + } + + return (true); + } + + #region ConvertValueToType + + private void ConvertValueToType(IGridCellEditControl editor, object value) + { + Type dataType = GridColumn.DataType; + + if (editor is IGridCellConvertTo) + { + IGridCellConvertTo cvtEditor = (IGridCellConvertTo)editor; + + object result; + if (cvtEditor.TryConvertTo(value, dataType, out result) == true) + { + Value = result; + + return; + } + } + + if (dataType == null && Value != null) + dataType = Value.GetType(); + + if (dataType == typeof (SqlDateTime)) + Value = SetSqlDateTime(value); + + else if (dataType == typeof (SqlBoolean)) + Value = SetSqlBoolean(value); + + else if (dataType == typeof (SqlString)) + Value = SetSqlString(value); + + else if (dataType == typeof (SqlSingle)) + Value = SetSqlSingle(value); + + else if (dataType == typeof (SqlDouble)) + Value = SetSqlDouble(value); + + else if (dataType == typeof(SqlDecimal)) + Value = SetSqlDecimal(value); + + else if (dataType == typeof (SqlInt16)) + Value = SetSqlInt16(value); + + else if (dataType == typeof (SqlInt32)) + Value = SetSqlInt32(value); + + else if (dataType == typeof (SqlInt64)) + Value = SetSqlInt64(value); + + else if (dataType != null) + Value = ConvertValue.ConvertTo(value, dataType); + + else + Value = value; + } + + #region SetSqlDateTime + + private object SetSqlDateTime(object value) + { + if (value == null) + return (new SqlDateTime()); + + if (value is DateTime) + return (new SqlDateTime((DateTime)value)); + + return (new SqlDateTime(Convert.ToDateTime(value))); + } + + #endregion + + #region SetSqlBoolean + + private object SetSqlBoolean(object value) + { + if (value == null) + return (new SqlBoolean()); + + if (value is CheckState) + { + CheckState cs = (CheckState)value; + + if (cs == CheckState.Checked) + return (new SqlBoolean(true)); + + if (cs == CheckState.Unchecked) + return (new SqlBoolean(false)); + + return (new SqlBoolean()); + } + + return (new SqlBoolean(Convert.ToBoolean(value))); + } + + #endregion + + #region SetSqlBoolean + + private object SetSqlString(object value) + { + if (value == null) + return (new SqlString()); + + return (new SqlString(Convert.ToString(value))); + } + + #endregion + + #region SetSqlSingle + + private object SetSqlSingle(object value) + { + if (value == null) + return (new SqlSingle()); + + return (new SqlSingle(Convert.ToSingle(value))); + } + + #endregion + + #region SetSqlDouble + + private object SetSqlDouble(object value) + { + if (value == null) + return (new SqlDouble()); + + return (new SqlSingle(Convert.ToDouble(value))); + } + + #endregion + + #region SetSqlDecimal + + private object SetSqlDecimal(object value) + { + if (value == null) + return (new SqlDecimal()); + + return (new SqlDecimal(Convert.ToDecimal(value))); + } + + #endregion + + #region SetSqlInt16 + + private object SetSqlInt16(object value) + { + if (value == null) + return (new SqlInt16()); + + return (new SqlInt16(Convert.ToInt16(value))); + } + + #endregion + + #region SetSqlInt32 + + private object SetSqlInt32(object value) + { + if (value == null) + return (new SqlInt32()); + + return (new SqlInt32(Convert.ToInt32(value))); + } + + #endregion + + #region SetSqlInt64 + + private object SetSqlInt64(object value) + { + if (value == null) + return (new SqlInt64()); + + return (new SqlInt64(Convert.ToInt64(value))); + } + + #endregion + + #endregion + + #endregion + + #region ValidateCellEdit + + private bool ValidateCellEdit(IGridCellEditControl editor) + { + try + { + object value = editor.EditorValue; + object formattedValue = GetFormattedValue(editor); + + if (SuperGrid.DoCellValidatingEvent(this, ref value, formattedValue) == true) + { + if (SuperGrid.DoPlayingSoundEvent(GridPanel, this, PlaySoundContext.CellValidate) == false) + SystemSounds.Beep.Play(); + + return (false); + } + + editor.EditorValue = value; + + SuperGrid.DoCellValidatedEvent(this); + } + catch + { + if (SuperGrid.DoPlayingSoundEvent(GridPanel, this, PlaySoundContext.CellValidate) == false) + SystemSounds.Beep.Play(); + + return (false); + } + + return (true); + } + + #endregion + + #endregion + + #region CancelEdit + + /// + /// Cancels the current in-progress Modal cell edit operation. + /// + ///true if canceled + public bool CancelEdit() + { + IGridCellEditControl editor = SuperGrid.ActiveEditor; + + if (editor == null || CellEditMode != CellEditMode.Modal) + throw new Exception("Bad CancelEdit - Modal edit not in progress."); + + if (SuperGrid.DoCancelEditEvent(GridPanel, this, editor) == false) + { + if (editor.CancelEdit() == false) + { + bool rowDirty = GridRow.RowDirty; + bool needsStored = GridRow.RowNeedsStored; + + CloseEdit(editor); + + GridRow.RowDirty = rowDirty; + GridRow.RowNeedsStored = needsStored; + + return (true); + } + } + + return (true); + } + + #endregion + + #region CloseEdit + + private void CloseEdit(IGridCellEditControl editor) + { + CloseCellInfoWindow(); + + IsMouseOver = false; + + bool wasFocused = ((Control)editor).ContainsFocus; + + editor.EditorPanel.Hide(); + editor.EditorPanel.GridCell = null; + + GridRow.EditorDirty = false; + + SuperGrid.ActiveEditor = null; + SuperGrid.EditorCell = null; + + if (wasFocused == true) + SuperGrid.Focus(); + + SuperGrid.DoCloseEditEvent(GridPanel, this); + + if (GridPanel == null || GridPanel.NeedToUpdateDataFilter == true) + InvalidateLayout(); + else + InvalidateRender(); + + SuperGrid.Update(); + } + + #endregion + + #region PositionEditPanel + + internal void PositionEditPanel(IGridCellEditControl editor) + { + PositionEditControl(editor); + + UpdateCellInfoWindowPos(); + + ((Control)editor).Update(); + editor.EditorPanel.Update(); + } + + #endregion + + #region PostCellKeyDown + + /// + /// PostCellKeyDown + /// + /// + internal void PostCellKeyDown(Keys keyData) + { + if (CanModifyMerge == true) + { + SuperGrid.DeactivateNonModalEditor(); + + IGridCellEditControl editor = GetInternalEditControl(); + + if (editor != null) + { + KeyEventArgs e = new KeyEventArgs(keyData); + + CellVisualStyle style = GetEffectiveStyle(); + + InitializeContext(DataContext.CellKeyEvent, editor, style); + + editor.CellKeyDown(e); + } + + PostInternalMouseMove(); + } + } + + #endregion + + #region PositionEditControl + + /// + /// PositionEditControl + /// + /// + private void PositionEditControl(IGridCellEditControl editor) + { + if (GridColumn != null) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Control c = (Control) editor; + + Rectangle r = GetAdjustedBounds(ContentBounds); + Rectangle e = GetEditPanelBounds(editor, r); + e = GetClippedBounds(panel, e); + + switch (editor.CellEditMode) + { + case CellEditMode.Modal: + case CellEditMode.NonModal: + if (GetCellHighlightMode(panel) == CellHighlightMode.Content) + { + r = GetEditPanelBounds(editor, r); + e = GetClippedBounds(panel, r); + } + + editor.EditorPanel.Bounds = e; + + c.Bounds = GetEditorBounds(editor, r, e); + + editor.EditorPanel.SizeEx = Bounds.Size; + editor.EditorPanel.OffsetEx = new Point(Bounds.X - e.X, Bounds.Y - e.Y); + + if (editor.CellEditMode == CellEditMode.NonModal) + { + editor.EditorPanel.BringToFront(); + editor.EditorPanel.Show(); + } + break; + + case CellEditMode.InPlace: + r.Intersect(SuperGrid.SViewRect); + r.Location = Point.Empty; + + c.Bounds = r; + break; + } + } + } + } + + #region GetEditPanelBounds + + private Rectangle GetEditPanelBounds(IGridCellEditControl editor, Rectangle r) + { + CellVisualStyle style = GetEffectiveStyle(); + + int n = r.Right; + + if (SuperGrid.EditorCell != this) + { + AlignHorizontally(editor, style, ref r); + } + else + { + if (GetCellHighlightMode(GridPanel) == CellHighlightMode.Content) + n -= 2; + } + + if (r.Right > n) + r.Width -= (r.Right - n); + + n = r.Bottom - 1; + + AlignVertically(editor, style, ref r); + + if (r.Bottom > n) + r.Height -= (r.Bottom - n); + + return (r); + } + + #endregion + + #region AlignHorizontally + + private void AlignHorizontally( + IGridCellEditControl editor, CellVisualStyle style, ref Rectangle r) + { + Size size = _ContentSize; + + switch (editor.StretchBehavior) + { + case StretchBehavior.Both: + case StretchBehavior.HorizontalOnly: + size.Width = r.Width; + break; + + default: + if (size.Width <= 0) + { + GetCurrentContentSize(style, editor); + + size = _ContentSize; + } + + if (size.Width <= 0) + { + size.Width = r.Width; + } + else if (r.Width > size.Width) + { + switch (style.Alignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + r.X += ((r.Width - size.Width) / 2); + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + r.X += (r.Width - size.Width - 1); + break; + } + } + break; + } + + r.Width = size.Width; + } + + #endregion + + #region AlignVertically + + private void AlignVertically( + IGridCellEditControl editor, CellVisualStyle style, ref Rectangle r) + { + Size size = _ContentSize; + + switch (editor.StretchBehavior) + { + case StretchBehavior.Both: + case StretchBehavior.VerticalOnly: + size.Height = r.Height; + break; + + default: + if (size.Height <= 0) + { + size.Height = r.Height; + } + else if (r.Height > size.Height) + { + switch (style.Alignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + r.Y += ((r.Height - size.Height)/2); + break; + + case Alignment.BottomLeft: + case Alignment.BottomCenter: + case Alignment.BottomRight: + r.Y += r.Height - size.Height; + break; + } + } + break; + } + + r.Height = size.Height; + } + + #endregion + + #region GetEditorBounds + + private Rectangle GetEditorBounds( + IGridCellEditControl editor, Rectangle r, Rectangle e) + { + if (GetCellHighlightMode(GridPanel) == CellHighlightMode.Content) + { + r.X = 0; + r.Y = 0; + } + else + { + r.X = (r.X - e.X); + r.Y = (r.Y - e.Y); + + r = GetEditPanelBounds(editor, r); + } + + return (r); + } + + #endregion + + #endregion + + #region FocusEditor + + internal void FocusEditor(IGridCellEditControl editor) + { + if (((Control)editor).Focused == false) + ((Control)editor).Focus(); + + if (editor is IGridCellEditorFocus) + ((IGridCellEditorFocus)editor).FocusEditor(); + } + + #endregion + + #region CellRender + + /// + /// This routine can be called by a cell editor / renderer to + /// perform default cell rendering provided by the grid. + /// + /// + /// + public void CellRender(IGridCellEditControl editor, Graphics g) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + CellVisualStyle style = GetEffectiveStyle(); + + CellRange cr = GetStateCellRange(); + + Rectangle bounds = (cr != null) ? GetBounds(panel, cr.BackBounds) : Bounds; + Rectangle rc = GetAdjustedBounds(GetContentBounds(panel, bounds)); + + if (rc.Height > 0 && rc.Width > 0) + { + RenderContent(g, panel, editor, style, rc, cr); + RenderCellInfo(g, panel); + } + } + } + + #region RenderContent + + private void RenderContent(Graphics g, GridPanel panel, + IGridCellEditControl editor, CellVisualStyle style, Rectangle rc, CellRange cr) + { + if (cr != null && + (editor.CellEditMode == CellEditMode.Modal || cr.AlwaysDisplayFormattedValue == true)) + RenderRangeContent(g, panel, style, rc, cr); + else + RenderCellContent(g, editor, style, rc); + } + + #region RenderRangeContent + + private void RenderRangeContent(Graphics g, + GridPanel panel, CellVisualStyle style, Rectangle rc, CellRange cr) + { + string s = cr.FormattedValue; + + if (string.IsNullOrEmpty(s) == false) + { + if (panel.EnableCellRangeMarkup == true) + { + if (MarkupParser.IsMarkup(s) == true) + { + BodyElement markup = MarkupParser.Parse(s); + + RenderTextMarkup(g, markup, style, rc); + } + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + TextDrawing.DrawString(g, s, style.Font, style.TextColor, rc, tf); + } + } + } + + #region RenderTextMarkup + + private void RenderTextMarkup(Graphics g, + BodyElement textMarkup, CellVisualStyle style, Rectangle r) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + textMarkup.Arrange(new Rectangle(r.Location, r.Size), d); + + Size size = textMarkup.Bounds.Size; + + switch (style.Alignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + if (r.Height > size.Height) + r.Y += (r.Height - size.Height) / 2; + break; + + default: + if (r.Height > size.Height) + r.Y = r.Bottom - size.Height; + break; + } + + textMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + textMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #endregion + + #region RenderCellContent + + private void RenderCellContent(Graphics g, + IGridCellEditControl editor, CellVisualStyle style, Rectangle rc) + { + switch (editor.CellEditMode) + { + case CellEditMode.Modal: + string s = GetFormattedValueEx(editor); + eTextFormat tf = style.GetTextFormatFlags(); + + if (string.IsNullOrEmpty(s) == false) + TextDrawing.DrawString(g, s, style.Font, style.TextColor, rc, tf); + break; + + case CellEditMode.NonModal: + case CellEditMode.InPlace: + Rectangle re = GetEditPanelBounds(editor, rc); + + if (re.Width > 0 && re.Height > 0) + { + Bitmap bm = GetCellBitmap(editor, rc); + + if (bm != null) + { + PaintButtonContent(editor, bm, rc, re); + + g.DrawImageUnscaledAndClipped(bm, re); + } + } + break; + } + } + + #endregion + + #endregion + + #region RenderCellInfo + + private void RenderCellInfo(Graphics g, GridPanel panel) + { + if (ShowInfoCellImage(panel) == true) + { + Image image = GetInfoImage(); + + if (image != null) + { + Rectangle rc = InfoImageBounds; + + if (rc.Width > 0 && rc.Height > 0) + g.DrawImageUnscaledAndClipped(image, rc); + } + } + } + + #region ShowInfoCellImage + + private bool ShowInfoCellImage(GridPanel panel) + { + if (panel.ShowCellInfo == false || _InfoText == null) + return (false); + + if (_InfoText.Equals("") == false) + return (true); + + return (panel.ShowCellInfoDisplayMode == ShowCellInfoDisplayMode.ShowWithEmptyText); + } + + #endregion + + #endregion + + #region GetExpValue + + /// + /// Gets the resultant value of the evaluated Cell Expression, if + /// applicable. Otherwise returns the given value. + /// + /// + /// + public string GetExpValue(string source) + { + GridPanel panel = GridPanel; + + if (IsValueExpression == true && + panel.EnableCellExpressions == true) + { + EEval eval = panel.ExpDictionary[this]; + + if (eval != null) + { + while (true) + { + try + { + _ExpValue = eval.Evaluate(); + + string s = (_ExpValue != null) + ? _ExpValue.ToString() + : ""; + + InfoText = null; + + return (s); + } + catch (Exception exp) + { + bool retry = false; + bool throwException = false; + + if (SuperGrid.HasDataErrorHandler == true) + { + object value = _Value; + + if (SuperGrid.DoDataErrorEvent(panel, this, exp, + DataContext.CellExpressionEval, ref value, ref throwException, ref retry) == true) + { + return (source); + } + } + + if (throwException == true) + throw; + + InfoText = exp.Message; + + if (retry == false) + return ("####!"); + } + } + } + } + + return (source); + } + + #endregion + + #region GetCellBitmap + + /// + /// Gets the cell paint bitmap + /// + /// + /// + /// + private Bitmap GetCellBitmap(IGridCellEditControl editor, Rectangle r) + { + Bitmap bm = editor.EditorCellBitmap; + + if (bm == null || bm.Size != r.Size) + { + if (bm != null) + bm.Dispose(); + + bm = new Bitmap(r.Width, r.Height); + + editor.EditorCellBitmap = bm; + } + + return (bm); + } + + #endregion + + #region PaintButtonContent + + /// + /// Paints the button background and content + /// + private void PaintButtonContent(IGridCellEditControl editor, + Bitmap bm, Rectangle rc, Rectangle re) + { + Control c = (Control)editor; + + // SizeEx is the size of the Adjusted Content size of the cell + // OffsetEx is the offset from the Editor panel to the cell ContentBounds. + + editor.EditorPanel.Size = re.Size; + editor.EditorPanel.SizeEx = rc.Size; + editor.EditorPanel.OffsetEx = new Point(rc.X - re.X, rc.Y - re.Y); + + // Set the control bounds and initiate the + // transfer of the control image to our bitmap. + + re.Location = Point.Empty; + + editor.SuspendUpdate = true; + + if (editor.EditorPanel.IsHandleCreated == false) + { + editor.EditorPanel.Show(); + editor.EditorPanel.BringToFront(); + editor.EditorPanel.Hide(); + } + + c.Bounds = re; + c.DrawToBitmap(bm, re); + + editor.SuspendUpdate = false; + } + + #endregion + + #endregion + + #region PaintEditorBackground + + /// + /// Performs default cell background painting for the cell. + /// + /// + /// + public void PaintEditorBackground(PaintEventArgs e, IGridCellEditControl editor) + { + Rectangle r = new Rectangle(); + + r.Size = editor.EditorPanel.SizeEx; + r.Location = Point.Empty; + + if (r.Width > 0 && r.Height > 0) + { + Graphics g = e.Graphics; + + if (SuperGrid.DoPreRenderCellEvent(g, this, RenderParts.Background, r) == false) + { + GridPanel panel = GridPanel; + CellHighlightMode mode = GetCellHighlightMode(panel); + + using (Brush br = GetContentBrush(panel, r, mode)) + g.FillRectangle(br, r); + + SuperGrid.DoPostRenderCellEvent(g, this, RenderParts.Background, r); + } + } + } + + #endregion + + #region ExtendSelection + + /// + /// ExtendSelection + /// + internal void ExtendSelection(GridPanel panel) + { + if (IsMouseSelectable() == true) + { + Capture = true; + + ExtendSelectionEx(panel); + } + } + + private void ExtendSelectionEx(GridPanel panel) + { + _mouseDownHitCell = this; + _mouseDownHitArea = CellArea.InContent; + + if (panel.SelectionRowAnchor == null) + panel.SelectionRowAnchor = GridRow; + + if (_hitCell != null) + { + _anchorRowIndex = _hitCell.GridRow.GridIndex; + _anchorColumnIndex = panel.Columns.GetDisplayIndex(GridColumn); + + ProcessExtendSelection(panel, false); + + if (panel.LastProcessedItem != _hitCell) + GridRow.EditorDirty = false; + + if (SuperGrid.ActiveNonModalEditor != null) + { + SuperGrid.Update(); + + if (SuperGrid.ActiveNonModalEditor != null) + SuperGrid.ActiveNonModalEditor.EditorPanel.Invalidate(true); + } + } + } + + #region IsMouseSelectable + + private bool IsMouseSelectable() + { + if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left) + return (true); + + return (IsSelected == false); + } + + #endregion + + #endregion + + #region InitializeContext + + private void InitializeContext(DataContext dataContext, + IGridCellEditControl editor, CellVisualStyle style) + { + if (((Control) editor).Handle != null) + { + object value = Value; + + if (InitializeContextEx(dataContext, editor, style) == true) + Value = value; + } + } + + private bool InitializeContextEx(DataContext dataContext, + IGridCellEditControl editor, CellVisualStyle style) + { + object value = Value; + + while (true) + { + bool suspended = editor.SuspendUpdate; + + try + { + IsDataError = false; + + editor.SuspendUpdate = true; + editor.EditorPanel.GridCell = this; + + editor.InitializeContext(this, style); + + SuperGrid.DoInitEditContextEvent(this, editor); + + return (false); + } + catch (Exception exp) + { + bool retry = false; + bool throwException = false; + + if (SuperGrid.HasDataErrorHandler == true) + { + if (SuperGrid.DoDataErrorEvent(GridPanel, this, exp, + dataContext, ref value, ref throwException, ref retry) == true) + { + return (true); + } + } + else + { + IsDataError = true; + + return (false); + } + + if (throwException == true) + throw; + + if (retry == false) + break; + + Value = value; + } + finally + { + editor.SuspendUpdate = suspended; + } + } + + return (true); + } + + #endregion + + #region CellRender + + private void CellRender(Graphics g, + CellVisualStyle style, IGridCellEditControl renderer) + { + if (renderer.CellEditMode != CellEditMode.Modal) + { + try + { + renderer.SuspendUpdate = true; + + InitializeContext(DataContext.CellRender, renderer, style); + renderer.CellRender(g); + } + finally + { + renderer.SuspendUpdate = false; + } + } + else + { + InitializeContext(DataContext.CellRender, renderer, style); + renderer.CellRender(g); + } + } + + #endregion + + #region SetEditorDirty + + /// + /// Called by the cell editor to conditionally set + /// the cells row level EditorDirty state. + /// + /// + public void SetEditorDirty(IGridCellEditControl editor) + { + if (GridColumn.MarkRowDirtyOnCellValueChange == true) + { + if (SuperGrid.DoRowMarkedDirtyEvent(this, editor) == false) + EditorDirty = true; + } + } + + #endregion + + #region EditorValueChanged + + /// + /// This routine is called by cell editors to signal to the grid + /// that the editor has changed the cell Value. + /// + /// + public void EditorValueChanged(IGridCellEditControl editor) + { + if (editor.SuspendUpdate == false) + { + SuperGrid.DoEditorValueChangedEvent(this, editor); + + editor.EditorValueChanged = true; + } + } + + #endregion + + #endregion + + #region UpdateBoundingRects + + private void UpdateBoundingRects() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + _BoundsUpdateCount = SuperGrid.BoundsUpdateCount; + + _BackBounds = GetBackBounds(panel); + _Bounds = GetBounds(panel); + } + } + + #region GetBackBounds + + /// + /// Gets the scroll adjusted background bounding rectangle + /// + /// + /// + internal Rectangle GetBackBounds(GridPanel panel) + { + Rectangle r = BoundsRelative; + + if (panel.IsSubPanel == false) + { + GridColumn column = GridColumn; + + if (column != null) + { + if (column.IsHFrozen == false) + r.X -= HScrollOffset; + } + } + else + { + r.X -= HScrollOffset; + } + + if (GridRow.IsVFrozen == false) + r.Y -= VScrollOffset; + + return (r); + } + + #endregion + + #region GetBounds + + internal Rectangle GetBounds(GridPanel panel) + { + return (GetBounds(panel, BackBounds)); + } + + /// + /// Gets the scroll adjusted bounding rectangle + /// + /// + /// + /// + internal Rectangle GetBounds(GridPanel panel, Rectangle backBounds) + { + Rectangle r = backBounds; + + r.Y += GridRow.EffectivePreDetailRowHeight; + r.Height -= (GridRow.EffectivePreDetailRowHeight + GridRow.EffectivePostDetailRowHeight); + + return (r); + } + + #endregion + + #region GetCellBounds + + /// + /// Gets the SViewRect clipped Bounds + /// + /// + /// + private Rectangle GetCellBounds(GridPanel panel) + { + return (GetClippedBounds(panel, Bounds)); + } + + #endregion + + #region GetContentBounds + + internal Rectangle GetContentBounds(GridPanel panel) + { + return (GetContentBounds(panel, Bounds)); + } + + /// + /// Gets the cell content (excludes image) bounding rectangle + /// + /// + /// + /// + internal Rectangle GetContentBounds(GridPanel panel, Rectangle bounds) + { + Rectangle r = bounds; + + int n = Dpi.Width(panel.LevelIndentSize.Width * _IndentLevel); + + CellRange cr = GetStateCellRange(); + + if (HasPrimaryCell(panel, cr) == true) + { + if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true) + n += panel.TreeButtonIndent; + + if (panel.CheckBoxes == true) + n += Dpi.Width(panel.CheckBoxSize.Width + (CheckBoxSpacing * 2)); + + if (Merged == true) + { + GridColumn col = panel.Columns.ColumnAtDisplayIndex(cr.ColumnStart); + + n = Math.Max(n - (r.X - col.Bounds.X), 0); + } + + r.X += n; + r.Width -= n; + } + else if (panel.GroupColumns.Count > 0) + { + if (panel.Columns.FirstVisibleColumn == GridColumn) + { + r.X += n; + r.Width -= n; + } + } + + CellVisualStyle style = GetEffectiveStyle(); + + object figure = style.GetFigure(panel); + + if (figure != null) + r = style.GetNonFigureBounds(panel, r); + + if (GridColumn.InfoImageOverlay == false) + { + if (string.IsNullOrEmpty(InfoText) == false) + { + Image image = GetInfoImage(); + + if (image != null) + { + switch (GridColumn.InfoImageAlignment) + { + case Alignment.MiddleLeft: + r.X += (image.Size.Width + 4); + r.Width -= (image.Size.Width + 4); + break; + + case Alignment.MiddleRight: + r.Width -= (image.Size.Width + 4); + break; + } + } + } + } + + r.Inflate(-1, -1); + + return (r); + } + + #region IsPrimaryCell + + private bool HasPrimaryCell(GridPanel panel, CellRange cr) + { + if (cr != null) + return (cr.ColumnStart == panel.Columns.GetDisplayIndex(panel.PrimaryColumn)); + + return (panel.PrimaryColumnIndex == _ColumnIndex); + + } + + #endregion + + #endregion + + #region GetEditBounds + + /// + /// Gets + /// + /// + /// + private Rectangle GetEditBounds(GridPanel panel) + { + Rectangle r = GetClippedBounds(panel, ContentBounds); + + r.Inflate(-1, -1); + + return (r); + } + + #endregion + + #region GetClippedBounds + + private Rectangle GetClippedBounds(GridPanel panel, Rectangle r) + { + Rectangle v = SViewRect; + + if (IsVFrozen == true) + { + int n = panel.FixedRowHeight - panel.FixedHeaderHeight; + + v.Y -= n; + v.Height += n; + } + + if (GridColumn.IsHFrozen == false) + { + GridColumn pcol = panel.Columns.GetLastVisibleFrozenColumn(); + + if (pcol != null) + { + int n = Dpi.Width(pcol.BoundsRelative.Right - v.X); + + v.X += n; + v.Width -= n; + } + } + + r.Intersect(v); + + return (r); + } + + #endregion + + #endregion + + #region GetAdjustedBounds + + #region GetAdjustedBounds() + + private Rectangle GetAdjustedBounds() + { + Rectangle r = Bounds; + + switch (GridPanel.GridLines) + { + case GridLines.Both: + r.Width -= Dpi.Width1; + r.Height -= Dpi.Height1; + break; + + case GridLines.Vertical: + r.Width -= Dpi.Width1; + break; + + case GridLines.Horizontal: + r.Height -= Dpi.Height1; + break; + } + + return (r); + } + + #endregion + + #region GetAdjustedBounds(r) + + private Rectangle GetAdjustedBounds(Rectangle r) + { + CellVisualStyle style = GetEffectiveStyle(); + + r.X += Dpi.Width(style.BorderThickness.Left + style.Margin.Left + style.Padding.Left); + r.Width -= Dpi.Width(style.BorderThickness.Horizontal + style.Margin.Horizontal + style.Padding.Horizontal); + + r.Y += Dpi.Height(style.BorderThickness.Top + style.Margin.Top + style.Padding.Top); + r.Height -= Dpi.Height(style.BorderThickness.Vertical + style.Margin.Vertical + style.Padding.Vertical); + + r.Width--; + + return (r); + } + + #endregion + + #endregion + + #region GetCurrentContentSize + + private void GetCurrentContentSize( + CellVisualStyle style, IGridCellEditControl editor) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Size oldSize = _ContentSize; + int width = Bounds.Size.Width; + + object figure = style.GetFigure(panel); + + if (figure != null) + { + Alignment alignment = style.ImageAlignment; + + if (style.IsOverlayImage == true) + alignment = Alignment.MiddleCenter; + + switch (alignment) + { + case Alignment.TopLeft: + case Alignment.TopRight: + case Alignment.MiddleLeft: + case Alignment.MiddleRight: + case Alignment.BottomLeft: + case Alignment.BottomRight: + width -= style.GetFigureSize(panel).Width; + break; + } + } + + width -= (style.GetBorderSize(true).Width + 2); + + Size constraintSize = new Size(width, 0); + + using (Graphics g = SuperGrid.CreateGraphics()) + _ContentSize = GetProposedSize(g, style, constraintSize, editor, CellSizingSource.ActualAndFormattedValues); + + if (_ContentSize != oldSize) + _BoundsUpdateCount = (ushort)(SuperGrid.BoundsUpdateCount - 1); + } + } + + #endregion + + #region GetCellEditBounds + + /// + /// Get the CellEditBounds for the cell. + /// + /// + /// + public Rectangle GetCellEditBounds(IGridCellEditControl editor) + { + Rectangle r = GetAdjustedBounds(ContentBounds); + + r = GetEditPanelBounds(editor, r); + + return (r); + } + + #endregion + + #region GetFormattedValue + + internal string GetFormattedValue() + { + IGridCellEditControl editor = SuperGrid.EditorCell == this + ? GetInternalEditControl() : GetInternalRenderControl(); + + return (GetFormattedValue(editor)); + } + + internal string GetFormattedValue(IGridCellEditControl editor) + { + string s = null; + + if (editor == null || IsDataError == true) + { + if (_Value != null) + s = _Value.ToString(); + } + else + { + bool suspended = editor.SuspendUpdate; + + try + { + editor.SuspendUpdate = true; + + if (SuperGrid.EditorCell != this) + InitializeContext(DataContext.CellGetFormattedValue, editor, null); + + s = editor.EditorFormattedValue; + } + finally + { + editor.SuspendUpdate = suspended; + } + + if (s != null && s.TrimStart().StartsWith("=") == true) + s = GetExpValue(s); + } + + CellSizingSource sizingSource = CellSizingSource.ActualAndFormattedValues; + + SuperGrid.DoGetCellFormattedValueEvent(this, ref s, ref sizingSource); + + return (s ?? ""); + } + + internal string GetFormattedValueEx(IGridCellEditControl editor) + { + string s = null; + + if (editor == null || IsDataError == true) + { + if (_Value != null) + s = _Value.ToString(); + } + else + { + s = editor.EditorFormattedValue; + + if (s != null && s.TrimStart().StartsWith("=") == true) + s = GetExpValue(s); + } + + CellSizingSource sizingSource = CellSizingSource.ActualAndFormattedValues; + + SuperGrid.DoGetCellFormattedValueEvent(this, ref s, ref sizingSource); + + return (s ?? ""); + } + + #endregion + + #region CellInfoWindow support + + #region UpdateInfoWindow + + private void UpdateInfoWindow() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (SuperGrid.EditorCell != this) + { + CloseCellInfoWindow(); + } + else + { + if (GridColumn.InfoImageOverlay == false) + { + if (SuperGrid.ActiveEditor != null) + PositionEditPanel(SuperGrid.ActiveEditor); + } + else + { + if (CanShowCellInfo(panel) == true) + { + if (_cellInfoWindow == null) + OpenCellInfoWindow(); + + UpdateCellInfoWindowPos(); + + _cellInfoWindow.Show(); + _cellInfoWindow.BringToFront(); + } + else + { + CloseCellInfoWindow(); + } + } + } + } + } + + #endregion + + #region CanShowCellInfo + + private bool CanShowCellInfo(GridPanel panel) + { + if (ShowInfoCellImage(panel) == true) + return (GetInfoImage() != null); + + return (false); + } + + #endregion + + #region UpdateCellInfoWindowPos + + private void UpdateCellInfoWindowPos() + { + if (_cellInfoWindow != null) + { + if (_cellInfoWindow != null) + { + Point pt = InfoImageBounds.Location; + + pt = SuperGrid.PointToScreen(pt); + + if (SuperGrid.ActiveEditor != null) + pt = SuperGrid.ActiveEditor.EditorPanel.PointToClient(pt); + + else if (SuperGrid.ActiveNonModalEditor != null) + pt = SuperGrid.ActiveNonModalEditor.EditorPanel.PointToClient(pt); + + _cellInfoWindow.Location = pt; + } + } + } + + #endregion + + #region OpenCellInfoWindow + + private void OpenCellInfoWindow() + { + _cellInfoWindow = new CellInfoWindow(SuperGrid, this); + _cellInfoWindow.Parent = SuperGrid.ActiveEditor.EditorPanel; + + SuperGrid.ActiveEditor.EditorPanel.Controls.Add(_cellInfoWindow); + } + + #endregion + + #region CloseCellInfoWindow + + private void CloseCellInfoWindow() + { + if (_cellInfoWindow != null) + { + SuperGrid.ToolTipText = ""; + + _cellInfoWindow.Dispose(); + _cellInfoWindow = null; + } + } + + #endregion + + #endregion + + #region Style support + + #region GetEffectiveStyle + + /// + /// Gets the EffectiveStyle for the cell. The effective + /// style is the cached, composite style definition for the + /// given cell, composed from panel, row, column, and cell styles. + /// + /// + public CellVisualStyle GetEffectiveStyle() + { + bool selected = IsSelected; + + StyleState cellState = GetCellState(selected); + CellVisualStyle style = GetEffectiveStyle(cellState); + + return (style); + } + + /// + /// Gets the EffectiveStyle for the cell- for the given StyleType. + /// The effective style is the cached, composite style definition for the + /// given cell, composed from panel, row, column, and cell styles. + /// + /// + /// + public CellVisualStyle GetEffectiveStyle(StyleType type) + { + ValidateStyle(); + + return (GetStyle(type)); + } + + internal CellVisualStyle GetEffectiveStyle(bool selected) + { + StyleState cellState = GetCellState(selected); + + return (GetEffectiveStyle(cellState)); + } + + private CellVisualStyle GetEffectiveStyle(StyleState cellState) + { + ValidateStyle(); + + if (IsDesignerHosted == true) + cellState &= ~(StyleState.MouseOver | StyleState.Selected); + + CellRange cr = GetStateCellRange(); + + if (cr != null) + return (cr.GetEffectiveStyle(RowContainer, cellState)); + + if (IsEmptyCell == true && + (GridPanel.AllowEmptyCellSelection == false || cellState == StyleState.Default)) + { + return (GetStyle(StyleType.Empty)); + } + + if (IsSelectable == false) + return (GetStyle(StyleType.NotSelectable)); + + switch (cellState) + { + case StyleState.MouseOver: + return (GetStyle(StyleType.MouseOver)); + + case StyleState.Selected: + return (GetStyle(StyleType.Selected)); + + case StyleState.Selected | StyleState.MouseOver: + return (GetStyle(StyleType.SelectedMouseOver)); + + case StyleState.ReadOnly: + return (GetStyle(StyleType.ReadOnly)); + + case StyleState.ReadOnly | StyleState.MouseOver: + return (GetStyle(StyleType.ReadOnlyMouseOver)); + + case StyleState.ReadOnly | StyleState.Selected: + return (GetStyle(StyleType.ReadOnlySelected)); + + case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: + return (GetStyle(StyleType.ReadOnlySelectedMouseOver)); + + default: + return (GetStyle(StyleType.Default)); + } + } + + #endregion + + #region GetCellState + + private StyleState GetCellState(bool selected) + { + StyleState cellState = StyleState.Default; + + if (IsReadOnly == true) + cellState |= StyleState.ReadOnly; + + if (SuperGrid.EditorCell != null || SuperGrid.NonModalEditorCell != null) + { + if (SuperGrid.EditorCell == this || SuperGrid.NonModalEditorCell == this) + cellState |= StyleState.MouseOver; + } + else + { + if (CapturedItem == null || CapturedItem is GridCell) + { + Point pt = SuperGrid.PointToClient(Control.MousePosition); + Rectangle r = Bounds; + + GridPanel panel = GridPanel; + + if (Merged == true) + { + CellRange cr = GetStateCellRange(); + + if (cr != null) + r = GetBounds(panel, cr.BackBounds); + } + + Rectangle t = ViewRect; + + r.Intersect(t); + + if (r.Contains(pt) == true) + cellState |= StyleState.MouseOver; + } + } + + if (selected == true) + cellState |= StyleState.Selected; + + return (cellState); + } + + #endregion + + #region GetStyle + + private CellVisualStyle GetStyle(StyleType e) + { + CellVisualStyles cvs = _EffectiveStyles; + + if (cvs == null) + cvs = new CellVisualStyles(); + + if (cvs.IsValid(e) == false) + { + CellVisualStyle style = new CellVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + foreach (StyleType cs in css) + { + GridColumn.ApplyCellStyle(style, cs); + GridRow.ApplyCellStyle(style, cs); + + style.ApplyStyle(CellStyles[cs]); + } + } + + SuperGrid.DoGetCellStyleEvent(this, e, ref style); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + if (style.Font == null) + style.Font = SystemFonts.DefaultFont; + + style.ApplyDefaults(); + + cvs[e] = style; + + _EffectiveStyles = cvs; + } + + return (cvs[e]); + } + + #endregion + + #region GetSizingStyle + + private CellVisualStyle GetSizingStyle(GridPanel panel) + { + StyleType style = panel.GetSizingStyle(); + + if (style == StyleType.NotSet) + { + style = (IsReadOnly == true) + ? StyleType.ReadOnly : StyleType.Default; + } + + return (GetEffectiveStyle(style)); + } + + #endregion + + #region StyleVisualChangeHandler + + private void StyleVisualChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + //NeedsMeasured = true; + + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) + { + ClearEffectiveStyles(); + + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + if (changeType == VisualChangeType.Layout) + { + NeedsMeasured = true; + + if (GridColumn != null) + GridColumn.NeedsMeasured = true; + + InvalidateLayout(); + } + else + { + InvalidateRender(); + } + } + + #endregion + + #region ValidateStyle + + private void ValidateStyle() + { + if (_StyleUpdateCount != SuperGrid.StyleUpdateCount) + { + ClearEffectiveStyles(); + + _StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidates the cached Style + ///definition for all defined StyleTypes + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + + InvalidateLayout(); + } + + /// + ///Invalidate the cached Style + ///definition for the given StyleType + /// + /// + public void InvalidateStyle(StyleType type) + { + if (_EffectiveStyles != null) + { + if (_EffectiveStyles[type] != null) + { + _EffectiveStyles[type].Dispose(); + _EffectiveStyles[type] = null; + + InvalidateLayout(); + } + } + } + + #endregion + + #region ClearEffectiveStyles + + internal void ClearEffectiveStyles() + { + if (_EffectiveStyles != null) + { + _EffectiveStyles.Dispose(); + _EffectiveStyles = null; + } + } + + #endregion + + #endregion + + #region InvalidateRender + + /// + /// InvalidateRender + /// + public override void InvalidateRender() + { + if (SuperGrid != null && GridColumn != null) + { + if (Merged == true) + { + CellRange cr = GetStateCellRange(); + + if (cr != null) + InvalidateRender(cr.BackBounds); + } + else + { + base.InvalidateRender(BackBounds); + } + } + } + + #endregion + + #region IComparable Members + + /// + /// CompareTo + /// + /// + /// + public int CompareTo(GridCell other) + { + int sval = 0; + if (SuperGrid.DoCompareElementsEvent(GridPanel, this, other, ref sval) == true) + return (sval); + + if (GridPanel.SortUsingHiddenColumns == false) + { + if (Visible == false) + return (other.Visible == false ? 0 : -1); + + if (other.Visible == false) + return (1); + } + + object val1 = IsValueExpression ? ExpValue : Value; + object val2 = other.IsValueExpression ? other.ExpValue : other.Value; + + return (CompareVal.CompareTo(val1, val2)); + } + + #endregion + + #region ToString + + /// + /// ToString + /// + /// + public override string ToString() + { + string s = "GridCell " + ColumnIndex + + ": {" + (Value ?? "") + "}"; + + return (s); + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + public void Dispose() + { + MouseRenderer = null; + + EditControl = null; + RenderControl = null; + + CellStyles = null; + + ClearEffectiveStyles(); + + if (SuperGrid != null) + { + if (SuperGrid.ActiveElement == this) + SuperGrid.ActiveElement = null; + } + } + + #endregion + + #region EditorInfo + + private class EditorInfo + { + #region Public variables + + public Type EditorType; + public Type RenderType; + + public IGridCellEditControl EditControl; + public IGridCellEditControl RenderControl; + + public object[] EditorParams; + public object[] RenderParams; + + #endregion + + #region Public properties + + public bool IsEmpty + { + get + { + return (EditorType == null && RenderType == null && + (EditorParams == null && RenderParams == null)); + } + } + + #endregion + } + + #endregion + + #region CellStates + + [Flags] + private enum Cs + { + AllowEdit = (1 << 0), + DataError = (1 << 1), + EmptyCell = (1 << 2), + ReadOnly = (1 << 3), + Selected = (1 << 4), + AnySelected = (1 << 5), + ValueExpression = (1 << 6), + + MergedTop = (1 << 7), + MergedLeft = (1 << 8), + MergedBottom = (1 << 9), + MergedRight = (1 << 10), + Merged = (1 << 11), + + Modified = (1 << 12), + } + + #endregion + } + + #region CompareVal + + internal class CompareVal + { + public static int CompareTo(object val1, object val2) + { + if (val1 != null && val1 != DBNull.Value) + { + if (val2 != null && val2 != DBNull.Value) + { + if (val1.GetType() == val2.GetType()) + { + IComparable icompa = val1 as IComparable; + + if (icompa != null) + return (icompa.CompareTo(val2)); + } + + return (-1); + } + + return (1); + } + + if (val2 != null && val2 != DBNull.Value) + return (-1); + + return (0); + } + } + + #endregion + + #region enums + + #region CellArea + + /// + /// CellArea + /// + public enum CellArea + { + /// + /// NoWhere + /// + NoWhere, + + /// + /// InContent + /// + InContent, + + /// + /// InExpandButton + /// + InExpandButton, + + /// + /// InCheckBox + /// + InCheckBox, + + /// + /// InCellInfo + /// + InCellInfo, + } + + #endregion + + #region CellMergeMode + + /// + /// Specifies the type of merging that is permitted + /// for cells in the given row or column + /// + [Flags] + public enum CellMergeMode + { + /// + /// Not set + /// + NotSet = (0 << 0), + + /// + /// No merging + /// + None = (1 << 0), + + /// + /// Cells can merge horizontally Left + /// + HorizontalLeft = (1 << 1), + + /// + /// Cells can merge horizontally Right + /// + HorizontalRight = (1 << 2), + + /// + /// Cells can merge horizontally (both left and right) + /// + Horizontal = (HorizontalLeft | HorizontalRight), + + /// + /// Cells can merge vertically + /// + Vertical = (1 << 3), + + /// + /// Cells can merge both horizontally and vertically + /// + HorizontalAndVertical = (Horizontal | Vertical), + } + + /// + /// Specifies the type of merging that is permitted + /// for cells in the given row or column + /// + public enum CellMergeOrder + { + /// + /// Cells can merge horizontally, then vertically + /// + HorizontalThenVertical, + + /// + /// Cells can merge vertically, then horizontally (this is the default + /// if CellMergeMode enables both vertical and horizontal merging) + /// + VerticalThenHorizontal, + } + + #endregion + + #region CellSizingSource + + /// + /// Specifies the cell value source for the cell + /// sizing operation (either the actual value, formatted value, + /// or both) + /// + public enum CellSizingSource + { + ActualValue = (1 << 0), // The actual, unformatted cell value + FormattedValue = (1 << 1), // The formatted cell value + + ActualAndFormattedValues = (ActualValue | FormattedValue), // The actual and formatted cell values + // (the maximum width/height of the two is used). + } + + #endregion + + #endregion + + #region ValueTypeConverter + + /// + /// ValueTypeConverter + /// + public class ValueTypeConverter : TypeConverter + { + #region CanConvertTo + + /// + /// CanConvertTo + /// + /// + /// + /// + public override bool CanConvertTo( + ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + return (true); + + return (base.CanConvertTo(context, destinationType)); + } + + #endregion + + #region ConvertTo + + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + string s = value as string; + + if (s != null) + return (s); + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + + #endregion + + #region CanConvertFrom + + /// + /// CanConvertFrom + /// + /// + /// + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + return (true); + + return (base.CanConvertFrom(context, sourceType)); + } + + #endregion + + #region ConvertFrom + + /// + /// ConvertFrom + /// + /// + /// + /// + /// + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + GridCell cell = context.Instance as GridCell; + + if (cell != null) + { + Type type = GetEditType(cell); + + if (type == typeof (GridDoubleInputEditControl)) + return (ConvertFromToDouble((string)value)); + + if (type == typeof (GridIntegerInputEditControl) || + type == typeof (GridProgressBarXEditControl) || + type == typeof (GridSliderEditControl) || + type == typeof (GridTrackBarEditControl)) + { + return (ConvertFromToInteger((string) value)); + } + + if (type == typeof (GridNumericUpDownEditControl)) + return (ConvertFromToDecimal((string)value)); + + if (type == typeof (GridCheckBoxXEditControl) || + type == typeof (GridCheckBoxEditControl) || + type == typeof(GridSwitchButtonEditControl)) + { + return (ConvertFromToBool((string) value)); + } + } + + return (value); + } + + return base.ConvertFrom(context, culture, value); + } + + #region ConvertFromToDouble + + private double ConvertFromToDouble(string value) + { + try + { + return (double.Parse(value)); + } + catch (Exception) + { + throw new ArgumentException("Invalid value to convert to 'double'."); + } + } + + #endregion + + #region ConvertFromToInteger + + private int ConvertFromToInteger(string value) + { + try + { + return (int.Parse(value)); + } + catch (Exception) + { + throw new ArgumentException("Invalid value to convert to 'int'."); + } + } + + #endregion + + #region ConvertFromToDecimal + + private decimal ConvertFromToDecimal(string value) + { + try + { + return (decimal.Parse(value)); + } + catch (Exception) + { + throw new ArgumentException("Invalid value to convert to 'decimal'."); + } + } + + #endregion + + #region ConvertFromToBool + + private bool ConvertFromToBool(string value) + { + switch (value.ToLower()) + { + case "y": + case "yes": + case "t": + case "true": + case "1": + return (true); + + case "": + case "0": + case "n": + case "no": + case "f": + case "false": + case null: + return (false); + + default: + throw new ArgumentException("Invalid value to convert to 'bool'."); + } + } + + #endregion + + #endregion + + #region GetEditType + + private Type GetEditType(GridCell cell) + { + if (cell.EditorType != null) + return (cell.EditorType); + + if (cell.GridColumn != null) + return (cell.GridColumn.EditorType); + + return (null); + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridCellCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridCellCollection.cs new file mode 100644 index 00000000..ff5aad4c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridCellCollection.cs @@ -0,0 +1,82 @@ +using System; +using System.ComponentModel; +using System.Drawing.Design; +using DevComponents.DotNetBar.SuperGrid.Primitives; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Represents the collection of grid cells. + /// + [Editor("DevComponents.SuperGrid.Design.GridCellCollectionEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public class GridCellCollection : CustomCollection + { + #region Indexer (string) + + /// + /// Gets or sets item at ColumnName index + /// + /// Name of Column containing the cell + public GridCell this[string columnName] + { + get + { + GridCell cell = FindCellItem(columnName); + + if (cell != null) + return (Items[cell.ColumnIndex]); + + return (null); + } + + set + { + GridCell cell = FindCellItem(columnName); + + if (cell == null) + throw new Exception("Column \"" + columnName + "\" not found."); + + Items[cell.ColumnIndex] = value; + } + } + + #endregion + + #region Indexer (Column) + + /// + /// Gets or sets item at Column index + /// + /// Column containing the cell + public GridCell this[GridColumn column] + { + get { return (Items[column.ColumnIndex]); } + set { Items[column.ColumnIndex] = value; } + } + + #endregion + + #region FindCellItem + + private GridCell FindCellItem(string columnName) + { + if (string.IsNullOrEmpty(columnName) == true) + throw new Exception("Invalid Column Name."); + + foreach (GridCell cell in Items) + { + GridColumn col = cell.GridColumn; + + if (col == null) + break; + + if (columnName.Equals(col.Name) == true) + return (cell); + } + + return (null); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumn.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumn.cs new file mode 100644 index 00000000..ff79d9ad --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumn.cs @@ -0,0 +1,3910 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.SuperGrid.TextMarkup; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Defines the grid column header + /// + public class GridColumn : GridElement, IDisposable + { + #region Events + + /// + /// Occurs after column header DisplayIndex has changed. + /// + public event EventHandler DisplayIndexChanged; + + #endregion + + #region Static variables + + static Image _InfoImageCache; + + #endregion + + #region Private variables + + private ColumnAutoSizeMode _AutoSizeMode = ColumnAutoSizeMode.NotSet; + private ColumnSortMode _ColumnSortMode = ColumnSortMode.Single; + private ColumnResizeMode _ResizeMode = ColumnResizeMode.MoveFollowingElements; + + private CellHighlightMode _CellHighlightMode = CellHighlightMode.Full; + private CellMergeMode _CellMergeMode = CellMergeMode.NotSet; + + private SortDirection _SortDirection = SortDirection.None; + private SortDirection _GroupDirection = SortDirection.None; + private SortIndicator _SortIndicator = SortIndicator.Auto; + private SortCycle _SortCycle = SortCycle.NotSet; + + private int _ColumnIndex; + private int _DisplayIndex = -1; + + private int _MinimumWidth = 5; + private int _FillWeight = 100; + + private string _NullString; + private string _HeaderText; + + private Size _HeaderSize; + private Size _HeaderTextSize; + + private Cs _States; + + private BodyElement _HeaderTextMarkup; + + private string _Name; + private int _Width = 100; + + private ushort _SelectionUpdateCount; + private SelectedElements _SelectedCells; + + private Type _EditorType = typeof(GridTextBoxXEditControl); + private Type _RenderType; + + private IGridCellEditControl _EditControl; + private IGridCellEditControl _RenderControl; + + private object[] _EditorParams; + private object[] _RenderParams; + + private ushort _MeasureCount; + + private Image _InfoImage; + private Alignment _InfoImageAlignment = Alignment.MiddleRight; + + private string _DataPropertyName; + private object _DefaultNewRowCellValue; + private Type _DataType; + + private CellVisualStyles _CellStyles; + private ColumnHeaderVisualStyles _HeaderStyles; + private FilterColumnHeaderVisualStyles _FilterRowStyles; + + private ColumnHeaderVisualStyles _EffectiveStyles; + private FilterColumnHeaderVisualStyles _EffectiveFilterStyles; + private CellVisualStyles _EffectiveCellStyles; + + private StyleState _LastStyleState; + private int _StyleUpdateCount; + + private Rectangle _SortImageBounds; + + private string _FilterExpr; + private FilterEval _FilterEval; + + private object _FilterValue; + private object _FilterDisplayValue; + + private Tbool _EnableFiltering = Tbool.NotSet; + private Tbool _ShowPanelFilterExpr = Tbool.NotSet; + private Tbool _AllowNullCellMerge = Tbool.NotSet; + + private Rectangle _FilterImageBounds; + private Size _FilterPopupSize = Size.Empty; + private int _FilterPopupMaxItems = 100; + private FilterScan _FilterScan; + + private FilterEditType _FilterEditType = FilterEditType.Auto; + private FilterMatchType _FilterMatchType = FilterMatchType.NotSet; + private GroupBoxEffects _GroupBoxEffects = GroupBoxEffects.NotSet; + + private string _ToolTip; + + #endregion + + #region Constructors + + /// + /// GridColumn + /// + public GridColumn() + { + SetState(Cs.AllowEdit, true); + SetState(Cs.InfoImageOverlay, true); + SetState(Cs.MarkRowDirtyOnCellValueChange, true); + + _SelectedCells = new SelectedElements(SelectedElementType.SelectedCells); + } + + /// + /// GridColumn + /// + public GridColumn(string name) + : this() + { + Name = name; + } + + #endregion + + #region Internal properties + + #region CanResize + + internal bool CanResize + { + get + { + ColumnAutoSizeMode mode = GetAutoSizeMode(); + + switch (mode) + { + case ColumnAutoSizeMode.None: + case ColumnAutoSizeMode.Fill: + return (true); + + default: + return (false); + } + } + } + + #endregion + + #region CanShowFilterExpr + + internal bool CanShowFilterExpr + { + get + { + if (_ShowPanelFilterExpr != Tbool.NotSet) + return (_ShowPanelFilterExpr == Tbool.True); + + if (GridPanel != null) + return (GridPanel.Filter.ShowPanelFilterExpr); + + return (false); + } + } + + #endregion + + #region EffectiveCellStyles + + internal CellVisualStyles EffectiveCellStyles + { + get { return (_EffectiveCellStyles); } + set { _EffectiveCellStyles = value; } + } + + #endregion + + #region EffectiveFilterStyles + + internal FilterColumnHeaderVisualStyles EffectiveFilterStyles + { + get { return (_EffectiveFilterStyles); } + set { _EffectiveFilterStyles = value; } + } + + #endregion + + #region EffectiveStyles + + internal ColumnHeaderVisualStyles EffectiveStyles + { + get { return (_EffectiveStyles); } + set { _EffectiveStyles = value; } + } + + #endregion + + #region FilterError + + internal bool FilterError + { + get { return (TestState(Cs.FilterError)); } + set { SetState(Cs.FilterError, value); } + } + + #endregion + + #region FilterExprUsesName + + internal bool FilterExprUsesName + { + get { return (TestState(Cs.FilterExprUsesName)); } + set { SetState(Cs.FilterExprUsesName, value); } + } + + #endregion + + #region FilterEval + + internal FilterEval FilterEval + { + get { return (_FilterEval); } + set { _FilterEval = value; } + } + + #endregion + + #region FilterImageBounds + + internal Rectangle FilterImageBounds + { + get { return (_FilterImageBounds); } + set { _FilterImageBounds = value; } + } + + #endregion + + #region FilterScan + + internal FilterScan FilterScan + { + get + { + if (_FilterScan == null) + FilterScan = new FilterScan(this); + + return (_FilterScan); + } + + set + { + if (_FilterScan != value) + { + if (_FilterScan != null) + _FilterScan.EndScan(); + + _FilterScan = value; + } + } + } + + #endregion + + #region GroupBoxEffectsEx + + internal GroupBoxEffects GroupBoxEffectsEx + { + get + { + if (_GroupBoxEffects != GroupBoxEffects.NotSet) + return (_GroupBoxEffects); + + GridPanel panel = GridPanel; + + if (panel != null && panel.GroupByRow != null) + { + if (panel.GroupByRow.GroupBoxEffects != GroupBoxEffects.NotSet) + return (panel.GroupByRow.GroupBoxEffects); + } + + return (GroupBoxEffects.Move); + } + } + + #endregion + + #region HeaderSize + + internal Size HeaderSize + { + get { return (_HeaderSize); } + set { _HeaderSize = value; } + } + + #endregion + + #region HeaderTextMarkup + + internal BodyElement HeaderTextMarkup + { + get { return (_HeaderTextMarkup); } + } + + #endregion + + #region HeaderTextSize + + internal Size HeaderTextSize + { + get { return (_HeaderTextSize); } + set { _HeaderTextSize = value; } + } + + #endregion + + #region IsFiltered + + internal bool IsFiltered + { + get { return (IsFilteringEnabled == true && + String.IsNullOrEmpty(FilterExpr) == false); } + } + + #endregion + + #region IsHFrozenEx + + internal bool IsHFrozenEx + { + get + { + GridPanel panel = Parent as GridPanel; + + if (panel != null && panel.IsSubPanel == false) + { + if (panel.FrozenColumnCount > 0) + { + int n = panel.Columns.GetDisplayIndex(this); + + if (n < panel.FrozenColumnCount) + return (true); + } + } + + return (false); + } + } + + #endregion + + #region IsReadOnly + + internal bool IsReadOnly + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.ReadOnly || ReadOnly) + return (true); + } + + return (TestState(Cs.ReadOnly)); + } + } + + #endregion + + #region LastStyleState + + internal StyleState LastStyleState + { + get { return (_LastStyleState); } + set { _LastStyleState = value; } + } + + #endregion + + #region MeasureCount + + internal ushort MeasureCount + { + get { return (_MeasureCount); } + } + + #endregion + + #region NeedsFilterScan + + internal bool NeedsFilterScan + { + get { return (TestState(Cs.NeedsFilterScan)); } + set { SetState(Cs.NeedsFilterScan, value); } + } + + #endregion + + #region NeedsMeasured + + internal override bool NeedsMeasured + { + get { return (base.NeedsMeasured); } + + set + { + if (value == true) + _MeasureCount++; + + base.NeedsMeasured = value; + } + } + + #endregion + + #region NeedsResized + + internal bool NeedsResized + { + get { return (TestState(Cs.NeedsResized)); } + set { SetState(Cs.NeedsResized, value); } + } + + #endregion + + #region Processed + + internal bool Processed + { + get { return (TestState(Cs.Processed)); } + set { SetState(Cs.Processed, value); } + } + + #endregion + + #region ScanItems + + internal List ScanItems + { + get + { + if (_FilterScan != null) + return (_FilterScan.ScanItems); + + return (null); + } + } + + #endregion + + #region SelectedCells + + internal SelectedElements SelectedCells + { + get { return (_SelectedCells); } + set { _SelectedCells = value; } + } + + #endregion + + #region SortImageBounds + + internal Rectangle SortImageBounds + { + get { return (_SortImageBounds); } + set { _SortImageBounds = value; } + } + + #endregion + + #region StyleUpdateCount + + internal int StyleUpdateCount + { + get { return (_StyleUpdateCount); } + set { _StyleUpdateCount = value; } + } + + #endregion + + #endregion + + #region Public properties + + #region AdjustSortImagePositionByMargin + + /// + /// Gets or sets whether the Column Header sort image + /// position is adjusted by the header margin + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the Column Header sort image position is adjusted by the header margin.")] + public bool AdjustSortImagePositionByMargin + { + get { return (TestState(Cs.AdjustSortImagePositionByMargin)); } + + set + { + if (AdjustSortImagePositionByMargin != value) + { + SetState(Cs.AdjustSortImagePositionByMargin, value); + + OnPropertyChangedEx("AdjustSortImagePositionByMargin", VisualChangeType.Render); + } + } + } + + #endregion + + #region AllowEdit + + /// + /// Gets or sets whether column cells can be edited by the user. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether column cells can be edited by the user.")] + public bool AllowEdit + { + get { return (TestState(Cs.AllowEdit)); } + + set + { + if (value != AllowEdit) + { + SetState(Cs.AllowEdit, value); + + OnPropertyChanged("AllowEdit"); + } + } + } + + #endregion + + #region AllowNullCellMerge + + /// + /// Gets or sets whether cells with null/empty values are allowed to be merged. + /// + [DefaultValue(Tbool.NotSet), Category("Behavior")] + [Description("Indicates whether cells with null/empty values are allowed to be merged.")] + public Tbool AllowNullCellMerge + { + get { return (_AllowNullCellMerge); } + + set + { + if (value != _AllowNullCellMerge) + { + _AllowNullCellMerge = value; + + OnPropertyChangedEx("AllowNullCellMerge", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AutoSizeMode + + /// + /// Gets or sets how column auto-sizing is performed + /// + [DefaultValue(ColumnAutoSizeMode.NotSet), Category("Sizing")] + [Description("Indicates how column auto-sizing is performed.")] + public ColumnAutoSizeMode AutoSizeMode + { + get { return (_AutoSizeMode); } + + set + { + if (value != _AutoSizeMode) + { + _AutoSizeMode = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("AutoSizeMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Bounds + + /// + /// Gets the scroll adjusted bounds of the Column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle Bounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = BoundsRelative; + + if (IsHFrozen == false) + r.X -= HScrollOffset; + + if (panel.IsSubPanel == true) + r.Y -= VScrollOffset; + + return (r); + } + + return (Rectangle.Empty); + } + } + + #endregion + + #region CellHighlightMode + + /// + /// Gets or sets the type of highlighting + /// to perform when a cell is selected + /// + [DefaultValue(CellHighlightMode.Full), Category("Behavior")] + [Description("Indicates the type of highlighting to perform when a cell is selected.")] + public CellHighlightMode CellHighlightMode + { + get { return (_CellHighlightMode); } + + set + { + if (value != _CellHighlightMode) + { + _CellHighlightMode = value; + + OnPropertyChanged("CellHighlightType"); + } + } + } + + #endregion + + #region CellMergeMode + + /// + /// Gets or sets the type of cell merging + /// that is supported by each cell in the column + /// + [DefaultValue(CellMergeMode.NotSet), Category("Behavior")] + [Description("Indicates the type of cell merging supported by each cell in the column.")] + public CellMergeMode CellMergeMode + { + get { return (_CellMergeMode); } + + set + { + if (value != _CellMergeMode) + { + _CellMergeMode = value; + + GridPanel panel = GridPanel; + + if (panel != null) + panel.InvalidateMerge(); + + OnPropertyChangedEx("CellMergeMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region CellStyles + + /// + /// Gets or sets the default visual styles assigned to the column cells + /// + [Category("Style")] + [Description("Indicates default visual style assigned to the column cells.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CellVisualStyles CellStyles + { + get + { + if (_CellStyles == null) + { + _CellStyles = new CellVisualStyles(); + + StyleVisualChangeHandler(null, _CellStyles); + } + + return (_CellStyles); + } + + set + { + if (_CellStyles != value) + { + StyleVisualChangeHandler(_CellStyles, value); + + _CellStyles = value; + + OnPropertyChangedEx("CellStyles", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ColumnIndex + + /// + /// Gets the panel level, Columns collection index of the column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int ColumnIndex + { + get { return (_ColumnIndex); } + internal set { _ColumnIndex = value; } + } + + #endregion + + #region ColumnSortMode + + /// + /// Gets or sets how column sorting is performed + /// + [DefaultValue(ColumnSortMode.Single), Category("Sorting")] + [Description("Indicates how column sorting is performed.")] + public ColumnSortMode ColumnSortMode + { + get { return (_ColumnSortMode); } + + set + { + if (value != _ColumnSortMode) + { + _ColumnSortMode = value; + + OnPropertyChanged("ColumnSortMode"); + } + } + } + + #endregion + + #region DataPropertyName + + /// + /// Gets or sets the name of the data source property + /// or database column to which the column is bound + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the data source property or database column to which the column is bound.")] + public string DataPropertyName + { + get { return (_DataPropertyName); } + + set + { + if (value != _DataPropertyName) + { + _DataPropertyName = value; + + if (GridPanel != null) + GridPanel.NeedToUpdateBindings = true; + + OnPropertyChangedEx("DataPropertyName", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DataType + + /// + ///Gets or sets the underlying data type + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Type DataType + { + get { return (_DataType); } + set { _DataType = value; } + } + + #endregion + + #region DefaultNewRowCellValue + + /// + /// Gets or sets the default cell value used when a new row is added + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the default cell value used when a new row is added.")] + [TypeConverter(typeof(ValueTypeConverter))] + [Editor("DevComponents.SuperGrid.Design.ValueTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public object DefaultNewRowCellValue + { + get + { + if (_DefaultNewRowCellValue is DBNull) + return null; + + return (_DefaultNewRowCellValue); + } + + set + { + if (value != _DefaultNewRowCellValue) + { + _DefaultNewRowCellValue = value; + + OnPropertyChanged("DefaultNewRowCellValue"); + } + } + } + + #endregion + + #region DisplayIndex + + /// + /// Gets or sets display index of the column. + /// + /// + /// A lower display index means a column will appear first (to the left) of columns with a higher display index. + /// Allowable values are from 0 to num columns - 1. (-1 is legal only as the default value). SuperGrid enforces + /// that no two columns have the same display index, ie. changing the display index of a column will cause the index + /// of other columns to adjust as well. + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the display index of the column. -1 indicates default value.")] + public int DisplayIndex + { + get { return (_DisplayIndex); } + + set + { + if (value != _DisplayIndex) + { + _DisplayIndex = value; + + OnPropertyChangedEx("DisplayIndex", VisualChangeType.Layout); + OnDisplayIndexChanged(EventArgs.Empty); + } + } + } + + #endregion + + #region EditControl + + /// + /// Gets the default Edit Control used for each cell in the column. + /// The column level edit control is a shared control, created and + /// based upon the column level EditorType and EditorParams properties. + /// Each cell in the column, that does not define its own EditorType, + /// will utilize the column level EditorControl. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IGridCellEditControl EditControl + { + get + { + if (_EditControl == null) + EditControl = GetEditControl(_EditorType, _EditorParams); + + if (_EditControl != null) + { + if (_EditControl.EditorPanel.Parent == null && SuperGrid != null) + SuperGrid.Controls.Add(_EditControl.EditorPanel); + } + + return (_EditControl); + } + + internal set + { + if (_EditControl != value) + { + if (_EditControl != null) + { + if (_EditControl.EditorPanel != null) + { + if (_EditControl.EditorPanel.Parent != null) + SuperGrid.Controls.Remove(_EditControl.EditorPanel); + + _EditControl.EditorPanel.Visible = false; + + if (_EditControl.EditorPanel.Controls.Count > 0) + _EditControl.EditorPanel.Controls[0].Visible = false; + + _EditControl.EditorPanel.Dispose(); + } + + _EditControl.EditorCellBitmap = null; + + ((Control)_EditControl).Dispose(); + + InvalidateLayout(); + } + + _EditControl = value; + } + } + } + + #endregion + + #region EditorParams + + /// + /// Gets or sets an array of arguments that match in number, + /// order, and type the parameters of the EditControl constructor + /// to invoke. If empty or null, the default constructor is invoked. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object[] EditorParams + { + get { return (_EditorParams); } + + set + { + if (_EditorParams != value) + { + _EditorParams = value; + + EditControl = null; + RenderControl = null; + + NeedsMeasured = true; + + OnPropertyChangedEx("EditorParams", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EditorType + + /// + /// Gets or sets the default cell editor type. This is the default + /// control type used to perform the actual modification of the cell value + /// + [DefaultValue(typeof(GridTextBoxXEditControl)), Category("Data")] + [Description("Indicates the default cell editor type. This is the default control type used to perform the actual modification of the cell value.")] + [TypeConverter(typeof(EditTypeConverter))] + [Editor("DevComponents.SuperGrid.Design.EditTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public Type EditorType + { + get { return (_EditorType); } + + set + { + if (value != _EditorType) + { + _EditorType = value; + + EditControl = null; + RenderControl = null; + + NeedsMeasured = true; + + OnPropertyChangedEx("EditorType", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EffectiveCellMergeMode + + /// + ///Gets the "effective" CellMergeMode for the column (ie. returns + ///the GridPanel CellMergeMode if column CellMergeMode is NotSet) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CellMergeMode EffectiveCellMergeMode + { + get + { + if (_CellMergeMode != CellMergeMode.NotSet) + return (_CellMergeMode); + + GridPanel panel = GridPanel; + + return ((panel != null) ? panel.CellMergeMode : CellMergeMode.None); + } + } + + #endregion + + #region EnableFiltering + + /// + /// Gets or sets whether filtering is enabled for the column + /// + [DefaultValue(Tbool.NotSet), Category("Filtering")] + [Description("Indicates whether filtering is enabled for the column.")] + public Tbool EnableFiltering + { + get { return (_EnableFiltering); } + + set + { + if (_EnableFiltering != value) + { + _EnableFiltering = value; + + OnPropertyChangedEx("EnableFiltering", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableGroupHeaderMarkup + + /// + /// Gets or sets whether text-markup support is enabled for the Group Header Text + /// + [DefaultValue(false), Category("Grouping")] + [Description("Indicates whether text-markup support is enabled for the Group Header Text.")] + public bool EnableGroupHeaderMarkup + { + get { return (TestState(Cs.EnableGroupHeaderMarkup)); } + + set + { + if (EnableGroupHeaderMarkup != value) + { + SetState(Cs.EnableGroupHeaderMarkup, value); + + if (GridPanel != null) + GridPanel.NeedsGrouped = true; + + OnPropertyChangedEx("EnableGroupHeaderMarkup", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableHeaderMarkup + + /// + /// Gets or sets whether text-markup support is enabled for the HeaderText + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for the HeaderText.")] + public bool EnableHeaderMarkup + { + get { return (TestState(Cs.EnableHeaderMarkup)); } + + set + { + if (EnableHeaderMarkup != value) + { + SetState(Cs.EnableHeaderMarkup, value); + + MarkupHeaderTextChanged(); + + OnPropertyChangedEx("EnableHeaderMarkup", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterAutoScan + + /// + /// Gets or sets whether the column's FilterPopup + /// is filled by auto-scanning the column contents. + /// + [DefaultValue(false), Category("Filtering")] + [Description("Indicates whether the column's FilterPopup is filled by auto-scanning the column contents.")] + public bool FilterAutoScan + { + get { return (TestState(Cs.FilterAutoScan)); } + + set + { + if (FilterAutoScan != value) + { + SetState(Cs.FilterAutoScan, value); + SetState(Cs.NeedsFilterScan, true); + + if (value == false) + FilterScan = null; + + OnPropertyChangedEx("FilterAutoScan", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterDisplayValue + + /// + /// Gets or sets the value used to filter grid rows. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object FilterDisplayValue + { + get { return (_FilterDisplayValue); } + + set + { + if (_FilterDisplayValue != value) + { + _FilterDisplayValue = value; + + OnPropertyChanged("FilterDisplayValue"); + + if (GridPanel != null) + { + if (GridPanel.ColumnHeader.Visible == true) + GridPanel.ColumnHeader.InvalidateRender(); + } + } + } + } + + #endregion + + #region FilterEditType + + /// + /// Gets or sets the filter edit type + /// + [DefaultValue(FilterEditType.Auto), Category("Filtering")] + [Description("Indicates the filter edit type).")] + public FilterEditType FilterEditType + { + get { return (_FilterEditType); } + + set + { + if (_FilterEditType != value) + { + _FilterEditType = value; + + OnPropertyChangedEx("FilterEditType", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterExpr + + /// + /// Gets or sets the value used to filter grid rows. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string FilterExpr + { + get { return (_FilterExpr); } + + set + { + if ("".Equals(value)) + value = null; + + if ((_FilterExpr == null && _FilterExpr != value) || + (_FilterExpr != null && _FilterExpr.Equals(value) == false)) + { + _FilterExpr = value; + + _FilterEval = null; + + if (_FilterExpr == null) + { + _FilterValue = null; + _FilterDisplayValue = null; + } + + if (GridPanel != null) + { + GridPanel.NeedToUpdateDataFilter = true; + GridPanel.NeedsGrouped = true; + } + + OnPropertyChangedEx("FilterExpr", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterMatchType + + /// + /// Gets or sets the filter data match type (how data elements are matched) + /// + [DefaultValue(FilterMatchType.NotSet), Category("Filtering")] + [Description("Indicates the filter data match style (how data elements are matched).")] + public FilterMatchType FilterMatchType + { + get { return (_FilterMatchType); } + + set + { + if (_FilterMatchType != value) + { + _FilterMatchType = value; + + FilterEval = null; + + if (GridPanel != null) + GridPanel.NeedToUpdateDataFilter = true; + + OnPropertyChangedEx("FilterMatchType", VisualChangeType.Layout); + } + } + } + + #region GetFilterMatchType + + internal FilterMatchType GetFilterMatchType() + { + if (_FilterMatchType != FilterMatchType.NotSet) + return (_FilterMatchType); + + if (GridPanel != null) + return (GridPanel.GetFilterMatchType()); + + return (FilterMatchType.None); + } + + #endregion + + #endregion + + #region FilterPopupMaxItems + + /// + /// Gets or sets the filter popup maximum number of drop-down items + /// + [DefaultValue(100), Category("Filtering")] + [Description("Indicates the filter popup maximum number of drop-down items.")] + public int FilterPopupMaxItems + { + get { return (_FilterPopupMaxItems); } + set { _FilterPopupMaxItems = value; } + } + + #endregion + + #region FilterPopupSize + + /// + /// Gets or sets the filter popup size + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Size FilterPopupSize + { + get { return (_FilterPopupSize); } + set { _FilterPopupSize = value; } + } + + #endregion + + #region FilterRowStyles + + /// + /// Gets or sets the visual styles assigned to the Filter Row + /// + [DefaultValue(null), Category("Style")] + [Description("Indicates visual style assigned to the Filter Row.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public FilterColumnHeaderVisualStyles FilterRowStyles + { + get + { + if (_FilterRowStyles == null) + { + _FilterRowStyles = new FilterColumnHeaderVisualStyles(); + + StyleVisualChangeHandler(null, _FilterRowStyles); + } + + return (_FilterRowStyles); + } + + set + { + if (_FilterRowStyles != value) + { + StyleVisualChangeHandler(_FilterRowStyles, value); + + _FilterRowStyles = value; + + OnPropertyChangedEx("FilterRowStyles", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterValue + + /// + /// Gets or sets the current filter value (the value that is + /// loaded into, or retrieved from, the editing filter control + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object FilterValue + { + get { return (_FilterValue); } + set { _FilterValue = value; } + } + + #endregion + + #region FillWeight + + /// + /// Gets or sets a value which, when AutoSizeMode is Fill, + /// represents the width of the column relative to the widths + /// of other fill-mode columns (default value is 100). + /// + [DefaultValue(100), Category("Sizing")] + [Description("Indicates a value which, when AutoSizeMode is Fill, represents the width of the column relative to the widths of other fill-mode columns (default value is 100).")] + public int FillWeight + { + get { return (_FillWeight); } + + set + { + if (value != _FillWeight) + { + _FillWeight = value; + + GridPanel panel = GridPanel; + + if (panel != null) + panel.NeedsMeasured = true; + + OnPropertyChangedEx("FillWeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupBoxEffects + + /// + /// Gets or sets how the column interacts with the GroupBox + /// + [DefaultValue(GroupBoxEffects.NotSet), Category("Grouping")] + [Description("Indicates how the column interacts with the GroupBox.")] + public GroupBoxEffects GroupBoxEffects + { + get { return (_GroupBoxEffects); } + + set + { + if (_GroupBoxEffects != value) + { + _GroupBoxEffects = value; + + OnPropertyChanged("GroupBoxEffects"); + } + } + } + + #endregion + + #region GroupDirection + + /// + /// Gets or sets the grouping sort direction (ie. ascending or descending). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SortDirection GroupDirection + { + get { return (_GroupDirection); } + + set + { + if (_GroupDirection != value) + { + _GroupDirection = value; + + OnGroupDirectionChanged(); + } + } + } + + #region OnGroupDirectionChanged + + private void OnGroupDirectionChanged() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + panel.NeedsGroupSorted = true; + + if (panel.VirtualMode == true) + panel.VirtualRows.Clear(); + + OnPropertyChangedEx("GroupDirection", VisualChangeType.Layout); + } + } + + #endregion + + #endregion + + #region HeaderText + + /// + /// Gets or sets the column header text. If the HeaderText is null + /// then the Name of the columns is used in its place. + /// + [Localizable(true), DefaultValue(null), Category("Appearance")] + [Description("Indicates the column header text. If the HeaderText is null then the Name of the columns is used in its place.")] + public string HeaderText + { + get { return (_HeaderText); } + + set + { + if (_HeaderText != value) + { + _HeaderText = value; + + MarkupHeaderTextChanged(); + + NeedsMeasured = true; + + OnPropertyChangedEx("HeaderText", VisualChangeType.Layout); + } + } + } + + #endregion + + #region HeaderStyles + + /// + /// Gets or sets the visual styles assigned to the Column Header + /// + [DefaultValue(null), Category("Style")] + [Description("Indicates visual style assigned to the Column Header.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ColumnHeaderVisualStyles HeaderStyles + { + get + { + if (_HeaderStyles == null) + { + _HeaderStyles = new ColumnHeaderVisualStyles(); + + StyleVisualChangeHandler(null, _HeaderStyles); + } + + return (_HeaderStyles); + } + + set + { + if (_HeaderStyles != value) + { + StyleVisualChangeHandler(_HeaderStyles, value); + + _HeaderStyles = value; + + OnPropertyChangedEx("HeaderStyles", VisualChangeType.Layout); + } + } + } + + #endregion + + #region InfoImage + + /// + /// Gets or sets the default cell informational Image + /// (the image to display when InfoText is non-empty). + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the default cell informational Image (the image to display when InfoText is non-empty).")] + public Image InfoImage + { + get { return (_InfoImage); } + + set + { + if (_InfoImage != value) + { + if (_InfoImageCache != null) + { + _InfoImageCache.Dispose(); + _InfoImageCache = null; + } + + _InfoImage = value; + + OnPropertyChangedEx("InfoImage", VisualChangeType.Layout); + } + } + } + + #region GetInfoImage + + internal Image GetInfoImage() + { + if (_InfoImage != null) + return (_InfoImage); + + if (_InfoImageCache == null) + _InfoImageCache = GridPanel.GetResourceImage("InfoImage"); + + return (_InfoImageCache); + } + + #endregion + + #endregion + + #region InfoImageAlignment + + /// + /// Gets or sets how the InfoImage is aligned within the cell + /// + [DefaultValue(Alignment.MiddleRight), Category("Appearance")] + [Description("Indicates how the InfoImage is aligned within the cell.")] + public Alignment InfoImageAlignment + { + get { return (_InfoImageAlignment); } + + set + { + if (_InfoImageAlignment != value) + { + _InfoImageAlignment = value; + + OnPropertyChanged("InfoImageAlignment"); + } + } + } + + #endregion + + #region InfoImageOverlay + + /// + /// Gets or sets how the InfoImage is overlayed with respect to the cell edit control. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates how the InfoImage is overlayed with respect to the cell edit control.")] + public bool InfoImageOverlay + { + get { return (TestState(Cs.InfoImageOverlay)); } + + set + { + if (value != InfoImageOverlay) + { + SetState(Cs.InfoImageOverlay, value); + + OnPropertyChanged("InfoImageOverlay"); + } + } + } + + #endregion + + #region IsDataBound + + /// + /// Gets whether the column is data bound. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDataBound + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + return (panel.DataBinder.IsColumnDataBound(this)); + + return (false); + } + } + + #endregion + + #region IsFilteringEnabled + + /// + /// Gets whether filtering is enabled for the column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsFilteringEnabled + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.EnableFiltering == false) + return (false); + + if (_EnableFiltering != Tbool.NotSet) + return (_EnableFiltering == Tbool.True); + + return (panel.EnableColumnFiltering == true); + } + + return (false); + } + } + + #endregion + + #region IsGroupColumn + + /// + /// Gets whether the column is a Grouping column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsGroupColumn + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + return (panel.GroupColumns.Contains(this)); + + return (false); + } + } + + #endregion + + #region IsHFrozen + + /// + /// Gets whether the column is horizontally frozen + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsHFrozen + { + get + { + GridPanel panel = Parent as GridPanel; + + if (panel != null && panel.IsSubPanel == false) + { + if (panel.FrozenColumnCount > 0) + { + int n = panel.Columns.GetDisplayIndex(this); + + if (n < panel.FrozenColumnCount) + return (true); + + ColumnGroupHeader cgh = panel.ColumnHeader.GetColumnGroupHeader(n); + + if (cgh != null) + return (panel.ColumnHeader.IsGroupHeaderHFrozen(panel, cgh)); + } + } + + return (false); + } + } + + #endregion + + #region IsOnScreen + + /// + /// Gets whether the column is visibly on screen. + /// + [Browsable (false)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public bool IsOnScreen + { + get + { + if (Visible == true) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + Rectangle t = SViewRect; + Rectangle bounds = BoundsRelative; + + if (IsHFrozen == false) + { + bounds.X -= HScrollOffset; + + GridColumn fcol = panel.Columns.GetLastVisibleFrozenColumn(); + + if (fcol != null) + { + int n = fcol.BoundsRelative.Right - t.X; + + t.X = fcol.BoundsRelative.Right; + t.Width -= n; + } + } + + if (panel.IsVFrozen == false) + bounds.Y -= VScrollOffset; + + return (t.IntersectsWith(bounds)); + } + } + + return (false); + } + } + + #endregion + + #region IsPrimaryColumn + + /// + /// Gets whether the column is the Primary column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsPrimaryColumn + { + get + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + return (panel.PrimaryColumn == this); + + return (false); + } + } + + #endregion + + #region IsSelectable + + /// + /// Gets whether the column can be selected. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSelectable + { + get { return (AllowSelection == true); } + } + + #endregion + + #region IsSelected + + /// + /// Gets or sets whether the column is selected + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSelected + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (_SelectionUpdateCount != panel.SelectionUpdateCount) + { + SetState(Cs.Selected, panel.IsItemSelected(this)); + _SelectionUpdateCount = panel.SelectionUpdateCount; + } + + return (TestState(Cs.Selected)); + } + + return (false); + } + + set + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.SetSelected(this, value) == true) + { + SetState(Cs.Selected, value); + _SelectionUpdateCount = panel.SelectionUpdateCount; + + InvalidateRender(); + + panel.ColumnHeader.InvalidateRender(); + } + } + } + } + + #endregion + + #region IsSortColumn + + /// + /// Gets whether the column is a Sort column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSortColumn + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + return (panel.SortColumns.Contains(this)); + + return (false); + } + } + + #endregion + + #region MarkRowDirtyOnCellValueChange + + /// + /// Gets or sets whether cell Value changes within this column + /// will result in the associated Row being marked as 'dirty' + /// + [DefaultValue(true), Category("Data")] + [Description("Indicates whether cell Value changes within this column will result in the associated Row being marked as 'dirty'.")] + public bool MarkRowDirtyOnCellValueChange + { + get { return (TestState(Cs.MarkRowDirtyOnCellValueChange)); } + + set + { + if (value != MarkRowDirtyOnCellValueChange) + { + SetState(Cs.MarkRowDirtyOnCellValueChange, value); + + OnPropertyChanged("MarkRowDirtyOnCellValueChange"); + } + } + } + + #endregion + + #region MinimumWidth + + /// + /// Gets or sets the minimum column width (default value is 5) + /// + [DefaultValue(5), Category("Sizing")] + [Description("Indicates the minimum column width (default value is 5).")] + public int MinimumWidth + { + get { return _MinimumWidth; } + + set + { + if (_MinimumWidth != value) + { + if (value < 0) + throw new ArgumentException("Value must be 0 or greater."); + + _MinimumWidth = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("MinimumWidth", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Name + + /// + /// Gets or sets the Column name. + /// + [DefaultValue(null)] + [Description("Indicates the Column name.")] + public string Name + { + get { return (_Name); } + + set + { + if (_Name != value) + { + _Name = value; + + if (String.IsNullOrEmpty(_HeaderText) == true) + OnPropertyChangedEx("Name", VisualChangeType.Layout); + else + OnPropertyChanged("Name"); + } + } + } + + #endregion + + #region NextVisibleColumn + + /// + /// Gets the next visible column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn NextVisibleColumn + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + return (panel.Columns.GetNextVisibleColumn(this)); + + return (null); + } + } + + #endregion + + #region NullString + + /// + /// Gets or sets the default text to display for null values. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the default text to display for null values.")] + public string NullString + { + get { return (_NullString); } + + set + { + if (_NullString != value) + { + _NullString = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("NullString", VisualChangeType.Layout); + } + } + } + + #endregion + + #region PrevVisibleColumn + + /// + /// Gets the previous visible column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn PrevVisibleColumn + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + return (panel.Columns.GetPrevVisibleColumn(this)); + + return (null); + } + } + + #endregion + + #region ReadOnly + + /// + /// Gets or sets whether the user can change column cell contents + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether the user can change column cell contents.")] + public bool ReadOnly + { + get { return (TestState(Cs.ReadOnly)); } + + set + { + if (ReadOnly != value) + { + SetState(Cs.ReadOnly, value); + + NeedsMeasured = true; + + OnPropertyChangedEx("ReadOnly", VisualChangeType.Render); + } + } + } + + #endregion + + #region RenderControl + + /// + /// Gets the default render control for the column cells + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IGridCellEditControl RenderControl + { + get + { + if (_RenderControl == null) + { + RenderControl = (_RenderType != null) + ? GetEditControl(_RenderType, _RenderParams) + : GetEditControl(_EditorType, _EditorParams); + + if (_RenderControl != null) + { + if (_RenderControl.EditorPanel.Parent == null && SuperGrid != null) + SuperGrid.Controls.Add(_RenderControl.EditorPanel); + } + } + + return (_RenderControl); + } + + internal set + { + if (_RenderControl != value) + { + if (_RenderControl != null) + { + if (_RenderControl.EditorPanel.Parent != null) + { + SuperGrid.Controls.Remove(_RenderControl.EditorPanel); + + _RenderControl.EditorPanel.Visible = false; + + if (_RenderControl.EditorPanel.Controls.Count > 0) + _RenderControl.EditorPanel.Controls[0].Visible = false; + + _RenderControl.EditorPanel.Dispose(); + } + + _RenderControl.EditorCellBitmap = null; + + ((Control)_RenderControl).Dispose(); + + InvalidateLayout(); + } + + _RenderControl = value; + } + } + } + + #endregion + + #region RenderParams + + /// + /// Gets or sets an array of arguments that match in number, + /// order, and type the parameters of the RenderControl constructor + /// to invoke. If empty or null, the default constructor is invoked. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object[] RenderParams + { + get { return (_RenderParams); } + + set + { + if (_RenderParams != value) + { + _RenderParams = value; + + RenderControl = null; + + NeedsMeasured = true; + + OnPropertyChangedEx("RenderParams", VisualChangeType.Layout); + } + } + } + + #endregion + + #region RenderType + + /// + /// Gets or sets the cell render control type (defaults to EditorType, when not set) + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates cell render control type (defaults to EditorType, when not set)")] + [TypeConverter(typeof(EditTypeConverter))] + [Editor("DevComponents.SuperGrid.Design.EditTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public Type RenderType + { + get { return (_RenderType); } + + set + { + if (value != _RenderType) + { + _RenderType = value; + + RenderControl = null; + NeedsMeasured = true; + + OnPropertyChangedEx("RenderType", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ResizeMode + + /// + /// Gets or sets how the column is resized by the user + /// + [DefaultValue(ColumnResizeMode.MoveFollowingElements), Category("Sizing")] + [Description("Indicates how the column is resized by the user.")] + public ColumnResizeMode ResizeMode + { + get { return (_ResizeMode); } + + set + { + if (_ResizeMode != value) + { + _ResizeMode = value; + + OnPropertyChanged("ResizeMode"); + } + } + } + + #endregion + + #region SelectedCellCount + + /// + /// Gets the current count of selected cells in the column. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectedCellCount + { + get + { + int n = 0; + + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == true) + { + foreach (SelectedRange range in _SelectedCells.Ranges) + n += range.Count; + } + else + { + foreach (SelectedRange range in _SelectedCells.Ranges) + { + for (int i = range.StartIndex; i <= range.EndIndex; i++) + { + GridRow row = panel.GetRowFromIndex(i) as GridRow; + + if (row != null) + { + if (row.Cells.Count > _ColumnIndex) + { + if (row.Cells[_ColumnIndex].AllowSelection == true) + n++; + } + else + { + n++; + } + } + } + } + } + } + + return (n); + } + } + + #endregion + + #region ShowCustomFilterExpr + + /// + /// Gets or sets whether the filter expression is displayed in the panel area + /// + [DefaultValue(Tbool.NotSet), Category("Filtering")] + [Description("Indicates whether the filter expression is displayed in the panel area.")] + public Tbool ShowPanelFilterExpr + { + get { return (_ShowPanelFilterExpr); } + + set + { + if (_ShowPanelFilterExpr != value) + { + _ShowPanelFilterExpr = value; + + OnPropertyChangedEx("ShowPanelFilterExpr", VisualChangeType.Render); + } + } + } + + #endregion + + #region SortCycle + + /// + /// Gets or sets how the sort direction cycles + /// when the column header is clicked to sort. + /// + [Browsable(true)] + [DefaultValue(SortCycle.NotSet), Category("Sorting")] + [Description("Indicates how the sort direction cycles when the column header is clicked to sort.")] + public SortCycle SortCycle + { + get { return (_SortCycle); } + + set + { + if (_SortCycle != value) + { + _SortCycle = value; + + OnPropertyChanged("SortCycle"); + } + } + } + + #endregion + + #region SortDirection + + /// + /// Gets or sets the Sorting direction (ascending or descending) + /// + [Browsable(false)] + [DefaultValue(SortDirection.None), Category("Sorting")] + [Description("Indicates the Sorting direction (ascending or descending).")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SortDirection SortDirection + { + get { return (_SortDirection); } + + set + { + if (_SortDirection != value) + { + _SortDirection = value; + + OnSortDirectionChanged(); + OnPropertyChangedEx("SortDirection", VisualChangeType.Render); + } + } + } + + #region OnSortDirectionChanged + + private void OnSortDirectionChanged() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + panel.NeedsSorted = true; + panel.ColumnHeader.InvalidateHeader(panel, this); + + if (panel.VirtualMode == true) + panel.VirtualRows.Clear(); + } + } + + #endregion + + #endregion + + #region SortIndicator + + /// + /// Gets or sets the sort indicator + /// + [DefaultValue(SortIndicator.Auto), Category("Sorting")] + [Description("Indicates the Sorting indicator.")] + public SortIndicator SortIndicator + { + get { return (_SortIndicator); } + + set + { + if (_SortIndicator != value) + { + _SortIndicator = value; + + NeedsMeasured = true; + + OnSortIndicatorChanged(); + } + } + } + + #region OnSortIndicatorChanged + + private void OnSortIndicatorChanged() + { + GridPanel panel = GridPanel; + + if (panel != null) + panel.ColumnHeader.InvalidateRender(); + + OnPropertyChanged("SortIndicator"); + } + + #endregion + + #endregion + + #region ToolTip + + /// + /// Gets or sets the ToolTip text for the column header. + /// + [Localizable(true), DefaultValue(null), Category("Appearance")] + [Description("Indicates ththe ToolTip text for the column header.")] + public string ToolTip + { + get { return (_ToolTip); } + + set + { + if (_ToolTip != value) + { + _ToolTip = value; + + OnPropertyChanged("ToolTip"); + } + } + } + + #endregion + + #region Width + + /// + /// Gets or sets the column width. + /// + [DefaultValue(100), Category("Sizing")] + [Description("Indicates the column width.")] + public int Width + { + get { return _Width; } + + set + { + if (_Width != value) + { + _Width = value; + + OnWidthChanged(); + } + } + } + + #region OnWidthChanged + + private void OnWidthChanged() + { + GridPanel panel = GridPanel; + + if (panel != null) + SuperGrid.DoColumnResizedEvent(panel, this); + + NeedsMeasured = true; + + OnPropertyChangedEx("Width", VisualChangeType.Layout); + } + + #endregion + + #endregion + + #endregion + + #region TestState + + private bool TestState(Cs state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(Cs state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #region OnEvent processing + + #region OnDisplayIndexChanged + + /// + /// Raises DisplayIndexChanged event. + /// + /// Provides event arguments. + protected virtual void OnDisplayIndexChanged(EventArgs e) + { + EventHandler handler = DisplayIndexChanged; + + if (handler != null) + handler(this, e); + } + + #endregion + + #endregion + + #region MeasureOverride + + /// + /// Performs the layout of the item and sets the Size property to size that item will take. + /// + /// Layout information. + /// + /// + protected override void MeasureOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + if (NeedsResized == true || NeedsMeasured == true || stateInfo.GridPanel.NeedsMeasured == true) + { + Size sizeNeeded = Size.Empty; + + ColumnAutoSizeMode autoSizeMode = GetAutoSizeMode(); + + int baseWidth = Dpi.Width(MinimumWidth); + + switch (autoSizeMode) + { + case ColumnAutoSizeMode.AllCells: + case ColumnAutoSizeMode.DisplayedCells: + case ColumnAutoSizeMode.ColumnHeader: + baseWidth = Math.Max(baseWidth, _HeaderSize.Width); + break; + } + + int height = 0; + + switch (autoSizeMode) + { + case ColumnAutoSizeMode.None: + sizeNeeded.Width = Math.Max(baseWidth, Dpi.Width(Width)); + break; + + case ColumnAutoSizeMode.AllCells: + case ColumnAutoSizeMode.AllCellsExceptHeader: + sizeNeeded.Width = GetColumnWidth(layoutInfo, stateInfo, + autoSizeMode, stateInfo.GridPanel.Rows, baseWidth, 0, ref height); + break; + + case ColumnAutoSizeMode.ColumnHeader: + sizeNeeded = new Size(baseWidth, 0); + MarkRowsToMeasure(stateInfo.GridPanel.Rows); + break; + + default: + sizeNeeded.Width = GetColumnWidth(layoutInfo, stateInfo, autoSizeMode, + stateInfo.GridPanel.Rows, baseWidth, layoutInfo.ClientBounds.Height, ref height); + break; + } + + Size = sizeNeeded; + + NeedsResized = false; + } + } + + #region GetColumnWidth + + private int GetColumnWidth(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ColumnAutoSizeMode autoSizeMode, + IEnumerable items, int width, int maxHeight, ref int height) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == true) + { + if (panel.VirtualRowCount > 0) + { + //panel.VirtualRows.Clear(); + + int n = GetVirtualColumnWidthEx(layoutInfo, + stateInfo, autoSizeMode, ref height); + + width = Math.Max(width, n); + } + } + else + { + int n = GetColumnWidthEx(layoutInfo, + stateInfo, autoSizeMode, items, maxHeight, ref height); + + width = Math.Max(width, n); + } + } + + return (width); + } + + #region GetVirtualColumnWidthEx + + private int GetVirtualColumnWidthEx(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ColumnAutoSizeMode autoSizeMode, ref int height) + { + GridPanel panel = GridPanel; + + int start = panel.FirstOnScreenRowIndex; + int end = panel.LastOnScreenRowIndex; + + int width = 0; + + for (int i = start; i <= end; i++) + { + GridRow row = panel.VirtualRows[i]; + + if (ColumnIndex < row.GridPanel.Columns.Count) + { + if (ColumnIndex < row.Cells.Count) + { + GridCell cell = row.Cells[ColumnIndex]; + + MeasureCell(layoutInfo, stateInfo, autoSizeMode, row, cell); + + width = Math.Max(width, cell.CellSize.Width); + height += cell.Size.Height; + } + else + { + width = Math.Max(width, Width); + } + } + } + + return (width); + } + + #endregion + + #region GetColumnWidthEx + + private int GetColumnWidthEx(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ColumnAutoSizeMode autoSizeMode, + IEnumerable items, int maxHeight, ref int height) + { + int width = 0; + + foreach (GridElement item in items) + { + GridRow row = item as GridRow; + + if (row != null && row.Visible == true) + { + if (ColumnIndex < row.GridPanel.Columns.Count) + { + if (ColumnIndex < row.Cells.Count) + { + GridCell cell = row.Cells[ColumnIndex]; + + if (maxHeight <= 0 || height < maxHeight) + { + MeasureCell(layoutInfo, stateInfo, autoSizeMode, row, cell); + + width = Math.Max(width, cell.CellSize.Width); + height += cell.Size.Height; + } + else + { + cell.NeedsMeasured = true; + } + } + else + { + width = Math.Max(width, Width); + } + } + + if (row.Rows != null && row.Expanded == true) + { + GridLayoutStateInfo itemStateInfo = new + GridLayoutStateInfo(stateInfo.GridPanel, stateInfo.IndentLevel + 1); + + width = GetColumnWidth(layoutInfo, itemStateInfo, + autoSizeMode, row.Rows, width, maxHeight, ref height); + } + } + else + { + GridGroup group = item as GridGroup; + + if (group != null) + { + GridPanel panel = group.GridPanel; + + int n = GetColumnWidthEx(layoutInfo, + stateInfo, autoSizeMode, group.Rows, maxHeight, ref height); + + n += panel.TreeButtonIndent + + Dpi.Width(stateInfo.IndentLevel * panel.LevelIndentSize.Width); + + width = Math.Max(width, n); + } + } + } + + return (width); + } + + #endregion + + #endregion + + #region MeasureCell + + private void MeasureCell(GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, + ColumnAutoSizeMode autoSizeMode, GridRow row, GridCell cell) + { + if (cell.NeedsMeasured || NeedsMeasured || + row.NeedsMeasured || stateInfo.GridPanel.NeedsMeasured) + { + int rowHeight = row.GetRowHeight(); + + if (rowHeight > 0) + { + Size size = new Size(Width, rowHeight); + + if (autoSizeMode != ColumnAutoSizeMode.None) + { + cell.Measure(layoutInfo, stateInfo, Size.Empty); + + size.Width = cell.Size.Width; + size.Width += GetColumnIndent(stateInfo.IndentLevel); + } + else + { + cell.Measure(layoutInfo, stateInfo, size); + } + + cell.Size = size; + } + else + { + Size size = Size.Empty; + + if (autoSizeMode == ColumnAutoSizeMode.None) + { + size.Width = Width; + size.Width -= GetColumnIndent(stateInfo.IndentLevel); + size.Width = Math.Max(1, size.Width); + } + + cell.Measure(layoutInfo, stateInfo, new Size(size.Width, 0)); + + if (autoSizeMode != ColumnAutoSizeMode.None) + { + size = cell.Size; + size.Width += GetColumnIndent(stateInfo.IndentLevel); + cell.Size = size; + } + else + { + size = cell.Size; + size.Width = Width; + cell.Size = size; + } + } + + cell.CellSize = cell.Size; + } + } + + #endregion + + #region MarkRowsToMeasure + + private void MarkRowsToMeasure(IEnumerable items) + { + foreach (GridElement item in items) + { + GridRow row = item as GridRow; + + if (row != null && row.Visible == true) + { + if (row.GetRowHeight() <= 0) + row.NeedsMeasured = true; + + if (row.Rows != null && row.Expanded == true) + MarkRowsToMeasure(row.Rows); + } + } + } + + #endregion + + #endregion + + #region ArrangeOverride + + /// + /// Performs the arrange pass layout of the item when final position and size of the item has been set. + /// + /// Layout information. + /// + /// Layout bounds + protected override void ArrangeOverride(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + GridPanel panel = stateInfo.GridPanel; + + if (NeedsFilterScan == true || panel.NeedsFilterScan == true) + { + if (FilterAutoScan == true && + (panel.Filter.Visible == true || panel.ColumnHeader.FilterImageVisibility != ImageVisibility.Never)) + { + NeedsFilterScan = false; + + FilterScan.BeginScan(); + } + } + } + + #endregion + + #region RenderOverride + + /// + /// Performs drawing of the item and its children. + /// + /// Holds contextual rendering information. + protected override void RenderOverride(GridRenderInfo renderInfo) + { + RenderDesignerElement(renderInfo, Bounds); + } + + #region RenderDesignerElement + + private void RenderDesignerElement( + GridRenderInfo renderInfo, Rectangle r) + { + if (SuperGrid.DesignerElement == this) + { + int n = r.Y - (GridPanel.ColumnHeader.Bounds.Y + 4); + + r.X += Dpi.Width2; + r.Y = GridPanel.ColumnHeader.Bounds.Y - Dpi.Width4; + r.Width -= Dpi.Width6; + r.Height += n + Dpi.Width4; + + if (r.Width > 0 && r.Height > 0) + { + using (Pen pen = new Pen(Color.Purple, Dpi.Width1)) + { + pen.DashStyle = DashStyle.Dash; + + renderInfo.Graphics.DrawRectangle(pen, r); + } + } + } + } + + #endregion + + #endregion + + #region GetHeaderText + + internal string GetHeaderText() + { + return (_HeaderText ?? _Name); + } + + #endregion + + #region GetColumnIndent + + internal int GetColumnIndent(int indentLevel) + { + int n = 0; + + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.PrimaryColumn == this) + { + if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true) + n += panel.TreeButtonIndent; + + if (panel.CheckBoxes == true) + { + if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true) + n += Dpi.Width3; + + n += Dpi.Width(panel.CheckBoxSize.Width + 2); + } + + n += Dpi.Width(panel.LevelIndentSize.Width * indentLevel); + } + } + + return (n); + } + + #endregion + + #region GetAutoSizeMode + + internal ColumnAutoSizeMode GetAutoSizeMode() + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + ColumnAutoSizeMode mode = AutoSizeMode; + + if (mode == ColumnAutoSizeMode.NotSet) + { + mode = panel.ColumnAutoSizeMode; + + if (mode != ColumnAutoSizeMode.NotSet) + return (mode); + } + + return (mode); + } + + return (ColumnAutoSizeMode.None); + } + + #endregion + + #region GetMaximumCellSize + + /// + /// This routine calculates and returns the maximum cell + /// size from each cell in the column, as limited by the + /// given row scope ('AllRows' or 'OnScreenRows'). + /// If 'includeHeader' is true, then the width of the header + /// is included in the max calculation. + /// + ///Maximum cell size. + public Size GetMaximumCellSize(RowScope scope, bool includeHeader) + { + Size size = Size.Empty; + GridPanel panel = GridPanel; + + if (panel != null) + { + using (Graphics g = SuperGrid.CreateGraphics()) + { + GridLayoutInfo layoutInfo = new GridLayoutInfo(g, panel.BoundsRelative); + GridLayoutStateInfo layoutState = new GridLayoutStateInfo(panel, 0); + + if (includeHeader == true) + { + Size oldSize = panel.ColumnHeader.Size; + + panel.ColumnHeader.MeasureHeader(layoutInfo, Size.Empty, panel, this); + + size.Width = _HeaderSize.Width; + + panel.ColumnHeader.Size = oldSize; + } + + if (panel.VirtualMode == true) + { + int firstRow = 0; + int lastRow = panel.VirtualRowCountEx; + + if (scope == RowScope.OnScreenRows) + { + firstRow = panel.FirstOnScreenRowIndex; + lastRow = panel.LastOnScreenRowIndex + 1; + } + + for (int i = firstRow; i < lastRow; i++) + { + GridRow row = panel.VirtualRows[i]; + GridCell cell = row.Cells[ColumnIndex]; + + Size oldSize = cell.Size; + + cell.Measure(layoutInfo, layoutState, Size.Empty); + + int n = GetColumnIndent(cell.IndentLevel); + + size.Width = Math.Max(size.Width, cell.Size.Width + n); + size.Height = Math.Max(size.Height, cell.Size.Height); + + cell.Size = oldSize; + } + } + else + { + if (panel.Rows.Count > 0) + { + int firstRow = 0; + int lastRow = panel.Rows.Count; + + if (scope == RowScope.OnScreenRows) + { + firstRow = panel.FirstOnScreenRowIndex; + lastRow = firstRow + 100; + } + + Size cellSize = GetMaximumCellSize( + panel.Rows, firstRow, lastRow, layoutInfo, layoutState); + + size.Width = Math.Max(size.Width, cellSize.Width); + size.Height = Math.Max(size.Height, cellSize.Height); + } + } + } + } + + return (size); + } + + private Size GetMaximumCellSize(GridItemsCollection rows, + int firstRow, int lastRow, GridLayoutInfo layoutInfo, GridLayoutStateInfo layoutState) + { + Size size = Size.Empty; + + for (int i = firstRow; i < lastRow; i++) + { + if (i >= rows.Count) + break; + + GridContainer item = rows[i] as GridContainer; + + if (item != null) + { + Size cellSize = Size.Empty; + + if (item is GridRow) + { + cellSize = GetMaxRowCellSize( + (GridRow) item, layoutInfo, layoutState); + } + else if (item is GridGroup) + { + cellSize = GetMaximumCellSize( + item.Rows, 0, lastRow - i, layoutInfo, layoutState); + } + + size.Width = Math.Max(size.Width, cellSize.Width); + size.Height = Math.Max(size.Height, cellSize.Height); + } + } + + return (size); + } + + #region GetMaxRowCellSize + + private Size GetMaxRowCellSize(GridRow row, + GridLayoutInfo layoutInfo, GridLayoutStateInfo layoutState) + { + if (row.Cells.Count <= ColumnIndex) + return (Size.Empty); + + GridCell cell = row.Cells[ColumnIndex]; + + Size oldSize = cell.Size; + + cell.Measure(layoutInfo, layoutState, Size.Empty); + + Size size = cell.Size; + size.Width += GetColumnIndent(cell.IndentLevel); + + cell.Size = oldSize; + + if (row.Rows.Count > 0 && row.Expanded == true) + { + layoutState.IndentLevel++; + + foreach (GridContainer item in row.Rows) + { + if (item is GridRow) + { + Size cellSize = + GetMaxRowCellSize((GridRow)item, layoutInfo, layoutState); + + size.Width = Math.Max(size.Width, cellSize.Width); + size.Height = Math.Max(size.Height, cellSize.Height); + } + } + + layoutState.IndentLevel--; + } + + return (size); + } + + #endregion + + #endregion + + #region GetSelectedCells + + /// + /// GetSelectedCells + /// + public SelectedElementCollection GetSelectedCells() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + SelectedElementCollection cells = new + SelectedElementCollection(SelectedCells.Count); + + panel.GetSelectedCells(cells, this); + + return (cells); + } + + return (null); + } + + #endregion + + #region EnsureVisible + + /// + /// EnsureVisible + /// + /// + public override void EnsureVisible(bool center) + { + if (Visible == true) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (IsHFrozen == false) + { + Rectangle t = SViewRect; + + GridColumn pcol = panel.Columns.GetLastVisibleFrozenColumn(); + + if (pcol != null) + { + t.Width -= (pcol.BoundsRelative.Right - t.X); + t.X = pcol.BoundsRelative.Right; + } + + Rectangle bounds = BoundsRelative; + + if (bounds.Width >= t.Width || bounds.X - HScrollOffset < t.X) + { + int n = bounds.X - t.X; + + if (center == false || bounds.Width >= t.Width) + SuperGrid.SetHScrollValue(n - 1); + else + SuperGrid.SetHScrollValue(n - (t.Width - bounds.Width)/2); + } + else if (bounds.X - HScrollOffset > t.Right - bounds.Width) + { + int n = bounds.X - (t.Right - bounds.Width); + + if (center == false) + SuperGrid.SetHScrollValue(n + 1); + else + SuperGrid.SetHScrollValue(n + (t.Width - bounds.Width)/2); + } + } + } + } + } + + #endregion + + #region ToggleSort + + /// + /// ToggleSort + /// + public void ToggleSort() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + SortDirection sortDirection; + + switch (_SortDirection) + { + case SortDirection.None: + case SortDirection.Descending: + sortDirection = SortDirection.Ascending; + break; + + default: + sortDirection = SortDirection.Descending; + break; + } + + panel.AddSort(this, sortDirection); + + SuperGrid.DoSortChangedEvent(panel); + } + } + + #endregion + + #region Edit support + + #region GetEditControl + + internal IGridCellEditControl GetEditControl(Type type, object[] args) + { + if (type != null) + { + IGridCellEditControl editor = + Activator.CreateInstance(type, args) as IGridCellEditControl; + + if (editor != null) + { + if (editor is Control == false) + throw new Exception("Edit/Render Type must be based on 'Control'."); + + editor.EditorPanel = new EditorPanel(); + editor.EditorPanel.Visible = false; + editor.EditorPanel.Controls.Add((Control) editor); + } + + return (editor); + } + + return (null); + } + + #endregion + + #endregion + + #region Style support routines + + #region StyleVisualChangeHandler + + private void StyleVisualChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + NeedsMeasured = true; + + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) + { + if (SuperGrid != null) + { + SuperGrid.UpdateStyleCount(); + + VisualChangeType changeType = ((VisualPropertyChangedEventArgs) e).ChangeType; + + if (changeType == VisualChangeType.Layout) + { + NeedsMeasured = true; + + InvalidateLayout(); + } + else + { + GridPanel.InvalidateRender(); + } + } + } + + #endregion + + #region GetFilterStyle + + internal FilterColumnHeaderVisualStyle GetFilterStyle(StyleType e) + { + ValidateStyle(); + + if (EffectiveFilterStyles == null) + EffectiveFilterStyles = new FilterColumnHeaderVisualStyles(); + + if (EffectiveFilterStyles.IsValid(e) == false) + { + FilterColumnHeaderVisualStyle style = new FilterColumnHeaderVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.FilterColumnHeaderStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.FilterColumnHeaderStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.FilterColumnHeaderStyles[cs]); + style.ApplyStyle(FilterRowStyles[cs]); + } + } + + SuperGrid.DoGetFilterColumnHeaderStyleEvent(this, e, ref style); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + if (style.Font == null) + { + Font font = SystemFonts.DefaultFont; + style.Font = font; + } + + EffectiveFilterStyles[e] = style; + } + + return (EffectiveFilterStyles[e]); + } + + #endregion + + #region GetHeaderStyle + + /// + ///Gets the effective header style for the given StyleType. + /// + ///StyleType + /// + public ColumnHeaderVisualStyle GetHeaderStyle(StyleType e) + { + ValidateStyle(); + + if (EffectiveStyles == null) + EffectiveStyles = new ColumnHeaderVisualStyles(); + + if (EffectiveStyles.IsValid(e) == false) + { + ColumnHeaderVisualStyle style = new ColumnHeaderVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + GridColumnHeader colHeader = GridPanel.ColumnHeader; + + ColumnGroupHeader cgh = colHeader.GetParentHeader(this) as ColumnGroupHeader; + + if (cgh != null) + { + if (colHeader.GetAutoApplyGroupColor(cgh) != true) + cgh = null; + } + + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.ColumnHeaderStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.ColumnHeaderStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.ColumnHeaderStyles[cs]); + + style.ApplyStyle(HeaderStyles[cs]); + + if (cgh != null) + { + ColumnHeaderVisualStyle gstyle = colHeader.GetEffectiveStyle(cgh, cs); + + if (gstyle.Background != null) + { + if (HeaderStyles[cs].Background == null || HeaderStyles[cs].Background.IsEmpty) + style.Background = gstyle.Background.Copy(); + } + + if (gstyle.TextColor.IsEmpty == false) + { + if (HeaderStyles[cs].TextColor.IsEmpty) + style.TextColor = gstyle.TextColor; + } + } + } + + style.ApplyDefaults(); + } + + SuperGrid.DoGetColumnHeaderStyleEvent(this, e, ref style); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + if (style.Font == null) + style.Font = SystemFonts.DefaultFont; + + EffectiveStyles[e] = style; + } + + return (EffectiveStyles[e]); + } + + #endregion + + #region ApplyCellStyle + + internal void ApplyCellStyle(CellVisualStyle style, StyleType cs) + { + CellVisualStyle cstyle = GetEffectiveCellStyle(cs); + + style.ApplyStyle(cstyle); + } + + #endregion + + #region GetEffectiveCellStyle + + /// + ///Get the default Effective CellStyle for the given StyleType. + /// + /// + /// + public CellVisualStyle GetEffectiveCellStyle(StyleType type) + { + ValidateStyle(); + + if (_EffectiveCellStyles == null) + _EffectiveCellStyles = new CellVisualStyles(); + + if (_EffectiveCellStyles.IsValid(type) == false) + { + GridPanel panel = GridPanel; + + int colIndex = panel.UseAlternateColumnStyle + ? panel.Columns.GetDisplayIndex(this) : -1; + + CellVisualStyle cstyle = new CellVisualStyle(); + + panel.ApplyCellStyle(cstyle, type); + + if ((colIndex % 2) > 0) + { + cstyle.ApplyStyle(SuperGrid.BaseVisualStyles.AlternateColumnCellStyles[type]); + cstyle.ApplyStyle(SuperGrid.DefaultVisualStyles.AlternateColumnCellStyles[type]); + cstyle.ApplyStyle(GridPanel.DefaultVisualStyles.AlternateColumnCellStyles[type]); + } + + cstyle.ApplyStyle(CellStyles[type]); + + _EffectiveCellStyles[type] = cstyle; + } + + return (_EffectiveCellStyles[type]); + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidates the cached Style + ///definition for all defined StyleTypes + /// + public void InvalidateStyle() + { + if (EffectiveStyles != null) + { + EffectiveStyles.Dispose(); + EffectiveStyles = null; + } + + if (EffectiveFilterStyles != null) + { + EffectiveFilterStyles.Dispose(); + EffectiveFilterStyles = null; + } + + InvalidateLayout(); + } + + /// + ///Invalidate the cached Style + ///definition for the given StyleType + /// + /// + public void InvalidateStyle(StyleType type) + { + if (_EffectiveStyles != null) + { + _EffectiveStyles[type] = null; + _EffectiveFilterStyles[type] = null; + + InvalidateLayout(); + } + } + + #endregion + + #region ValidateStyle + + private void ValidateStyle() + { + if (_StyleUpdateCount != SuperGrid.StyleUpdateCount) + { + ClearEffectiveStyles(); + + _StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #region ClearEffectiveStyles + + internal void ClearEffectiveStyles() + { + if (_EffectiveStyles != null) + { + _EffectiveStyles.Dispose(); + _EffectiveStyles = null; + } + + if (_EffectiveFilterStyles != null) + { + _EffectiveFilterStyles.Dispose(); + _EffectiveFilterStyles = null; + } + + if (_EffectiveCellStyles != null) + { + _EffectiveCellStyles.Dispose(); + _EffectiveCellStyles = null; + } + } + + #endregion + + #endregion + + #region GetFilterPanelType + + internal FilterEditType GetFilterPanelType() + { + FilterEditType filterType = FilterEditType; + + if (filterType == FilterEditType.Auto) + { + IGridCellEditControl editor = EditControl; + + if (editor != null) + { + if (editor is ComboBox) + { + filterType = FilterEditType.ComboBox; + } + else + { + if (editor.EditorValueType == typeof(bool)) + filterType = FilterEditType.CheckBox; + + else if (editor.EditorValueType == typeof(DateTime)) + filterType = FilterEditType.DateTime; + + else + filterType = FilterEditType.TextBox; + } + } + else + { + filterType = FilterEditType.TextBox; + } + } + + SuperGrid.DoGetFilterEditTypeEvent(this, ref filterType); + + return (filterType); + } + + #endregion + + #region Markup support + + private void MarkupHeaderTextChanged() + { + if (_HeaderTextMarkup != null) + _HeaderTextMarkup.HyperLinkClick -= HeaderTextMarkupLinkClick; + + _HeaderTextMarkup = null; + + if (EnableHeaderMarkup == true) + { + if (MarkupParser.IsMarkup(_HeaderText) == true) + { + _HeaderTextMarkup = MarkupParser.Parse(_HeaderText); + + if (_HeaderTextMarkup != null) + _HeaderTextMarkup.HyperLinkClick += HeaderTextMarkupLinkClick; + } + } + } + + /// + /// Occurs when a header text markup link is clicked + /// + protected virtual void HeaderTextMarkupLinkClick(object sender, EventArgs e) + { + HyperLink link = sender as HyperLink; + + SuperGrid.DoColumnHeaderMarkupLinkClickEvent(this, link); + + GridPanel.ColumnHeader.InvalidateHeader(GridPanel, this); + } + + /// + /// Gets plain Header text without text-markup (if text-markup is used in Text) + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public string PlainHeaderText + { + get { return (_HeaderTextMarkup != null ? _HeaderTextMarkup.PlainText : _HeaderText); } + } + + #endregion + + #region ActivateFilterPopup + + /// + ///Activates the column's FilterPopup + /// + public void ActivateFilterPopup() + { + GridPanel panel = GridPanel; + + if (panel != null) + panel.ColumnHeader.ActivateFilterPopup(panel, this); + } + + #endregion + + #region DeactivateFilterPopup + + /// + ///Deactivates the column's FilterPopup + /// + public void DeactivateFilterPopup() + { + GridPanel panel = GridPanel; + + if (panel != null) + panel.ColumnHeader.DeactivateFilterPopup(panel, this); + } + + #endregion + + #region ToString + + /// + /// ToString + /// + /// + public override string ToString() + { + string s = base.ToString(); + + string t = GetHeaderText(); + + if (String.IsNullOrEmpty(t) == false) + s += ": (\"" + t + "\")"; + + return (s); + } + + #endregion + + #region ColumnStates + + [Flags] + private enum Cs + { + AdjustSortImagePositionByMargin = (1 << 0), + AllowEdit = (1 << 1), + + EnableGroupHeaderMarkup = (1 << 2), + EnableHeaderMarkup = (1 << 3), + + FilterAutoScan = (1 << 4), + FilterError = (1 << 5), + FilterExprUsesName = (1 << 6), + + MarkRowDirtyOnCellValueChange = (1 << 7), + + NeedsFilterScan = (1 << 8), + NeedsResized = (1 << 9), + + Processed = (1 << 10), + + ReadOnly = (1 << 11), + Selected = (1 << 12), + + InfoImageOverlay = (1 << 13), + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + CellStyles = null; + HeaderStyles = null; + FilterRowStyles = null; + + if (_HeaderTextMarkup != null) + _HeaderTextMarkup.HyperLinkClick -= HeaderTextMarkupLinkClick; + + ClearEffectiveStyles(); + } + + #endregion + } + + #region enums + + #region ColumnAutoSizeMode + + /// + /// Defines columns auto-sizing mode. + /// + public enum ColumnAutoSizeMode + { + /// + /// The sizing behavior of the column is inherited + /// from the GridPanel.AutoSizeColumnsMode property. + /// + NotSet, + + /// + /// Auto-sizing does not take place. + /// + None, + + /// + /// The column width adjusts so that the widths of all columns + /// exactly fills the display area of the control, requiring + /// horizontal scrolling only to keep column widths above the + /// ColumnHeader.MinimumWidth property values. Relative column widths + /// are determined by the relative Column.FillWeight property values. + /// + Fill, + + /// + /// The column width adjusts to fit the contents of all cells in the column + /// that are in rows currently displayed on screen, excluding the header cell. + /// + DisplayedCellsExceptHeader, + + /// + /// The column width adjusts to fit the contents of all cells in the column + /// that are in rows currently displayed on screen, including the header cell. + /// + DisplayedCells, + + /// + /// The column width adjusts to fit the contents of the column header cell. + /// + ColumnHeader, + + /// + /// The column width adjusts to fit the contents of all + /// cells in the column, excluding the header cell. + /// + AllCellsExceptHeader, + + /// + /// The column width adjusts to fit the contents of all + /// cells in the column, including the header cell. + /// + AllCells + } + + #endregion + + #region ColumnAutoMode + + /// + /// Indicates the column sorting mode + /// + public enum ColumnSortMode + { + /// + /// No sorting permitted + /// + None, + + /// + /// Can participate in Single column sorts only + /// + Single, + + /// + /// Can participate in Single and Multiple column sorts + /// + Multiple, + } + + #endregion + + #region ColumnResizeMode + + /// + /// ColumnResizeMode + /// + public enum ColumnResizeMode + { + /// + /// The element cannot be resized by the user + /// + None, + + /// + /// The size of the element plus that of its adjacent element + /// is changed so that the total size of the elements is maintained + /// + MaintainTotalWidth, + + /// + /// When the element size is changed, all following + /// elements are offset accordingly + /// + MoveFollowingElements, + } + + #endregion + + #region SortIndicator + + /// + /// SortIndicator + /// + public enum SortIndicator + { + /// + /// No indicator is displayed + /// + None, + + /// + /// Ascending indicator is displayed + /// + Ascending, + + /// + /// Descending indicator is displayed + /// + Descending, + + /// + /// Set automatically based on current + /// column sort criteria + /// + Auto, + } + + #endregion + + #region RowScope + + /// + /// RowScope + /// + public enum RowScope + { + /// + /// All Rows + /// + AllRows, + + /// + /// Only On Screen rows + /// + OnScreenRows, + } + + #endregion + + #endregion + + #region EditTypeConverter + + /// + /// EditTypeConverter + /// + public class EditTypeConverter : TypeConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + Type type = value as Type; + + if (type != null) + return (type.Name); + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumnCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumnCollection.cs new file mode 100644 index 00000000..9078ab00 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumnCollection.cs @@ -0,0 +1,787 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing.Design; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Defines the collection of grid columns + /// + [Editor("DevComponents.SuperGrid.Design.GridColumnCollectionEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public class GridColumnCollection : CollectionBase + { + #region Events + + /// + /// Occurs when the collection has changed + /// + [Description("Occurs when collection has changed.")] + public CollectionChangeEventHandler CollectionChanged; + + #endregion + + #region Private Variables + + private GridElement _ParentItem; + private int[] _DisplayIndexMap; + private bool _IsDisplayIndexValid; + + #endregion + + #region Public properties + + #region FirstSelectableColumn + + /// + /// Gets reference to first selectable column + /// or null if there is no first selectable column. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn FirstSelectableColumn + { + get + { + int[] displayMap = DisplayIndexMap; + + for (int i = 0; i < displayMap.Length; i++) + { + GridColumn column = this[displayMap[i]]; + + if (column.Visible == true && column.AllowSelection == true) + return (column); + } + + return (null); + } + } + + #endregion + + #region FirstVisibleColumn + + /// + /// Gets reference to first visible column + /// or null if there is no first visible column. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn FirstVisibleColumn + { + get + { + int[] displayMap = DisplayIndexMap; + + for (int i = 0; i < displayMap.Length; i++) + { + if (this[displayMap[i]].Visible) + return (this[displayMap[i]]); + } + + return (null); + } + } + + #endregion + + #region Index indexer + + /// + /// Returns reference to the object in collection based on it's index. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn this[int index] + { + get { return (GridColumn)(List[index]); } + set { List[index] = value; } + } + + #endregion + + #region Name indexer + + /// + /// Name indexer + /// + /// + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn this[string name] + { + get + { + int index = FindIndexByName(name); + + return (index >= 0 ? this[index] : null); + } + + set + { + int index = FindIndexByName(name); + + if (index < 0) + throw new Exception("Column Name not defined (" + name + ")."); + + List[index] = value; + } + } + + #region FindIndexByName + + private int FindIndexByName(string name) + { + for (int i=0; i + /// Gets reference to last selectable column + /// or null if there is no last selectable column. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn LastSelectableColumn + { + get + { + int[] displayMap = DisplayIndexMap; + + for (int i = displayMap.Length - 1; i >= 0; i--) + { + GridColumn column = this[displayMap[i]]; + + if (column.Visible == true && column.AllowSelection == true) + return (column); + } + + return (null); + } + } + + #endregion + + #region LastVisibleColumn + + /// + /// Gets reference to last visible column + /// or null if there is no last visible column. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn LastVisibleColumn + { + get + { + int[] displayMap = DisplayIndexMap; + + for (int i = displayMap.Length - 1; i >= 0; i--) + { + if (this[displayMap[i]].Visible) + return (this[displayMap[i]]); + } + + return (null); + } + } + + #endregion + + #region ParentItem + + /// + /// Gets or sets the node this collection is associated with. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridElement ParentItem + { + get { return _ParentItem; } + + internal set + { + _ParentItem = value; + + OnParentItemChanged(); + } + } + + private void OnParentItemChanged() + { + } + + #endregion + + #endregion + + #region Add + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(GridColumn value) + { + value.ColumnIndex = List.Add(value); + + return (value.ColumnIndex); + } + + #endregion + + #region Insert + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, GridColumn value) + { + List.Insert(index, value); + + for (int i = 0; i < Count; i++) + ((GridColumn)List[i]).ColumnIndex = i; + } + + #endregion + + #region IndexOf + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(GridColumn value) + { + return (List.IndexOf(value)); + } + + #endregion + + #region Contains + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(GridColumn value) + { + return (List.Contains(value)); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Name of the object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(string name) + { + foreach (GridColumn column in List) + { + if (column.Name.Equals(name) == true) + return (true); + } + + return (false); + } + + #endregion + + #region Remove + + /// + /// Removes specified object from the collection. + /// + /// + public void Remove(GridColumn value) + { + List.Remove(value); + + for (int i = 0; i < Count; i++) + ((GridColumn)List[i]).ColumnIndex = i; + } + + #endregion + + #region OnRemoveComplete + + /// + /// Called when remove of an item is completed. + /// + /// Index of removed item + /// Removed item. + protected override void OnRemoveComplete(int index, object value) + { + if (value is GridColumn) + { + GridColumn column = (GridColumn)value; + GridPanel panel = column.GridPanel; + + ResetColumn(panel, column); + } + + OnCollectionChanged(CollectionChangeAction.Remove, value); + + base.OnRemoveComplete(index, value); + } + + #endregion + + #region Clear + + /// + /// Clears all objects from the collection. + /// + public new void Clear() + { + foreach (GridColumn column in this) + ResetColumn(column.GridPanel, column); + + List.Clear(); + } + + #endregion + + #region OnClearComplete + + /// + /// OnClearComplete + /// + protected override void OnClearComplete() + { + InvalidateDisplayIndexes(); + InvalidateLayout(); + + base.OnClearComplete(); + } + + #endregion + + #region ResetColumn + + private void ResetColumn(GridPanel panel, GridColumn column) + { + column.DisplayIndexChanged -= ColumnDisplayIndexChanged; + + if (panel.DataSource != null) + panel.DataBinder.DataResetCount++; + + GridCell cell = column.SuperGrid.ActiveElement as GridCell; + + if (cell != null) + { + if (cell.ColumnIndex == column.ColumnIndex) + column.SuperGrid.ActiveElement = null; + } + + if (panel.SortColumns.Contains(column)) + panel.SortColumns.Remove(column); + + if (panel.GroupColumns.Contains(column)) + panel.GroupColumns.Remove(column); + + FilterPanel fp = column.SuperGrid.ActiveFilterPanel; + + if (fp != null && fp.GridColumn == column) + fp.EndEdit(); + } + + #endregion + + #region OnInsertComplete + + /// + /// Called when insertion of an item is completed. + /// + /// Insert index. + /// Inserted item. + protected override void OnInsertComplete(int index, object value) + { + if (value is GridColumn) + { + GridColumn column = (GridColumn)value; + + if (column.Parent != null && column.Parent != _ParentItem) + throw new Exception("Column is already a member of another Column collection."); + + column.DisplayIndexChanged += ColumnDisplayIndexChanged; + + column.Parent = _ParentItem; + } + + OnCollectionChanged(CollectionChangeAction.Add, value); + + base.OnInsertComplete(index, value); + } + + #endregion + + #region OnCollectionChanged + + private void OnCollectionChanged( + CollectionChangeAction action, object value) + { + for (int i = 0; i < Count; i++) + ((GridColumn)List[i]).ColumnIndex = i; + + if (action == CollectionChangeAction.Remove) + { + GridColumn rcol = (GridColumn)value; + GridPanel panel = rcol.GridPanel; + + if (rcol.DisplayIndex >= 0) + { + foreach (GridColumn col in panel.Columns) + { + if (col.DisplayIndex > rcol.DisplayIndex) + col.DisplayIndex--; + } + } + } + + InvalidateDisplayIndexes(); + InvalidateLayout(); + + if (CollectionChanged != null) + { + CollectionChangeEventArgs e = new + CollectionChangeEventArgs(action, value); + + CollectionChanged(this, e); + } + } + + #endregion + + #region ColumnDisplayIndexChanged + + private void ColumnDisplayIndexChanged(object sender, EventArgs e) + { + InvalidateDisplayIndexes(); + InvalidateLayout(); + } + + #endregion + + #region InvalidateDisplayIndexes + + /// + /// Invalidates the display indexes and + /// causes them to be re-evaluated on next layout. + /// + public void InvalidateDisplayIndexes() + { + _IsDisplayIndexValid = false; + } + + #endregion + + #region InvalidateLayout + + private void InvalidateLayout() + { + if (_ParentItem != null) + { + _ParentItem.InvalidateLayout(); + + if (_ParentItem.SuperGrid != null) + { + _ParentItem.SuperGrid.NeedMergeLayout = true; + _ParentItem.SuperGrid.DisplayedMergeLayoutCount++; + } + } + } + + #endregion + + #region CopyTo + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(GridColumn[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the ColumnHeader array. + /// + /// Array to copy to. + internal void CopyTo(GridColumn[] array) + { + List.CopyTo(array, 0); + } + + #endregion + + #region OnClear + + /// + /// Called when collection is cleared. + /// + protected override void OnClear() + { + if (Count > 0) + { + GridPanel panel = this[0].Parent as GridPanel; + + if (panel != null) + { + panel.SuperGrid.ActiveElement = null; + + foreach (GridElement item in panel.Rows) + { + GridRow row = item as GridRow; + + if (row != null) + { + foreach (GridCell cell in row.Cells) + { + cell.EditControl = null; + cell.RenderControl = null; + } + } + } + } + } + + foreach (GridColumn item in this) + { + item.EditControl = null; + item.RenderControl = null; + } + + base.OnClear(); + } + + #endregion + + #region DisplayIndexMap + + /// + /// A map of display index (key) to index in the column collection + /// (value). Used to quickly find a column from its display index. + /// + internal int[] DisplayIndexMap + { + get + { + if (!_IsDisplayIndexValid) + UpdateDisplayIndexMap(); + + return (_DisplayIndexMap); + } + } + + #endregion + + #region GetDisplayIndex + + /// + /// Gets the display index for specified column. + /// + /// Column that is part of ColumnHeaderCollection + /// Display index or -1 column is not part of this collection. + public int GetDisplayIndex(GridColumn column) + { + return (GetDisplayIndex(IndexOf(column))); + } + + /// + /// Gets the display index for specified column. + /// + ///Column index + ///Display index or -1 column is not part of this collection. + public int GetDisplayIndex(int index) + { + UpdateDisplayIndexMap(); + + for (int i = 0; i < _DisplayIndexMap.Length; i++) + { + if (_DisplayIndexMap[i] == index) + return (i); + } + + return (-1); + } + + #endregion + + #region ColumnAtDisplayIndex + + /// + /// Returns the column that is displayed at specified display index. + /// + /// 0 based display index. + /// ColumnHeader + public GridColumn ColumnAtDisplayIndex(int displayIndex) + { + UpdateDisplayIndexMap(); + + return (this[_DisplayIndexMap[displayIndex]]); + } + + #endregion + + #region UpdateDisplayIndexMap + + private void UpdateDisplayIndexMap() + { + if (_IsDisplayIndexValid == false) + { + _IsDisplayIndexValid = true; + + _DisplayIndexMap = new int[Count]; + + for (int i = 0; i < Count; i++) + _DisplayIndexMap[i] = -1; + + for (int i = 0; i < Count; i++) + { + int di = this[i].DisplayIndex; + + if (di != -1) + AddIndexToMap(i, di); + } + + int n = 0; + + for (int i = 0; i < Count; i++) + { + int di = this[i].DisplayIndex; + + if (di == -1) + AddIndexToMap(i, n++); + } + } + } + + private void AddIndexToMap(int i, int di) + { + for (int j = 0; j < Count; j++) + { + int n = (di + j) % Count; + + if (_DisplayIndexMap[n] == -1) + { + _DisplayIndexMap[n] = i; + break; + } + } + } + + #endregion + + #region GetNextVisibleColumn + + /// + /// Gets reference to next visible column + /// or null if there is no next visible column + /// + public GridColumn GetNextVisibleColumn(GridColumn column) + { + return (GetNextVisibleColumn(GetDisplayIndex(column))); + } + + internal GridColumn GetNextVisibleColumn(int displayIndex) + { + int[] displayMap = DisplayIndexMap; + + while (++displayIndex < Count) + { + if (this[displayMap[displayIndex]].Visible) + return (this[displayMap[displayIndex]]); + } + + return (null); + } + + #endregion + + #region GetPrevVisibleColumn + + /// + /// Gets reference to previous visible column + /// or null if there is no last visible previous column + /// + public GridColumn GetPrevVisibleColumn(GridColumn column) + { + return (GetPrevVisibleColumn(GetDisplayIndex(column))); + } + + internal GridColumn GetPrevVisibleColumn(int displayIndex) + { + int[] displayMap = DisplayIndexMap; + + while (--displayIndex >= 0) + { + if (this[displayMap[displayIndex]].Visible) + return (this[displayMap[displayIndex]]); + } + + return (null); + } + + #endregion + + #region GetLastVisibleFrozenColumn + + /// + /// Gets reference to the last visible frozen column + /// or null if there is none + /// + public GridColumn GetLastVisibleFrozenColumn() + { + int[] displayMap = DisplayIndexMap; + + if (displayMap.Length > 0) + { + GridPanel panel = this[displayMap[0]].GridPanel; + + if (panel != null && + panel.FrozenColumnCount > 0 && panel.IsSubPanel == false) + { + for (int i = displayMap.Length - 1; i >= 0; i--) + { + GridColumn column = this[displayMap[i]]; + + if (column.Visible == true) + { + if (column.IsHFrozen == true) + return (column); + } + } + } + } + + return (null); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumnGroupHeader.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumnGroupHeader.cs new file mode 100644 index 00000000..34fd8148 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumnGroupHeader.cs @@ -0,0 +1,1121 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using DevComponents.DotNetBar.SuperGrid.Primitives; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.SuperGrid.TextMarkup; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + ///ColumnGroupHeaderCollection + /// + [Editor("DevComponents.SuperGrid.Design.ColumnGroupHeaderCollectionEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public class ColumnGroupHeaderCollection : CustomCollection + { + #region Events + + #region HeaderMarkupLinkClick + + internal event EventHandler GroupHeaderMarkupLinkClick; + + #endregion + + #endregion + + #region Private variables + + private object _Parent; + + #endregion + + #region Public properties + + #region Name indexer + + /// + /// Name indexer + /// + /// + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ColumnGroupHeader this[string name] + { + get + { + int index = FindIndexByName(name); + + return (index >= 0 ? this[index] : null); + } + + set + { + int index = FindIndexByName(name); + + if (index < 0) + throw new Exception("Column Name not defined (" + name + ")."); + + Items[index] = value; + } + } + + #region FindIndexByName + + private int FindIndexByName(string name) + { + for (int i = 0; i < Items.Count; i++) + { + ColumnGroupHeader item = Items[i]; + + if (name != null) + name = name.ToUpper(); + + if (item.Name != null && item.Name.ToUpper().Equals(name)) + return (i); + } + + return (-1); + } + + #endregion + + #endregion + + #region Parent + + /// + /// Parent + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object Parent + { + get { return (_Parent); } + internal set { _Parent = value; } + } + + #endregion + + #endregion + + #region OnCollectionChanged + + /// + /// Handles CollectionChange notifications + /// + /// + protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (INotifyPropertyChanged newValue in e.NewItems) + { + ItemChangeHandler(null, newValue); + PropertyChangeHandler(null, newValue); + } + break; + + case NotifyCollectionChangedAction.Remove: + foreach (INotifyPropertyChanged oldValue in e.OldItems) + { + ItemChangeHandler(null, oldValue); + PropertyChangeHandler(null, oldValue); + } + break; + + case NotifyCollectionChangedAction.Replace: + for (int i = 0; i < e.OldItems.Count; i++) + { + ItemChangeHandler(e.OldItems[i], e.NewItems[i]); + + PropertyChangeHandler((INotifyPropertyChanged)e.OldItems[i], + (INotifyPropertyChanged)e.NewItems[i]); + } + break; + + case NotifyCollectionChangedAction.Reset: + for (int i = 0; i < Items.Count; i++) + { + ItemChangeHandler(Items[i], null); + PropertyChangeHandler(Items[i], null); + } + break; + } + + base.OnCollectionChanged(e); + } + + #endregion + + #region ItemChangeHandler + + private void ItemChangeHandler(object oldValue, object newValue) + { + ColumnGroupHeader cgh = oldValue as ColumnGroupHeader; + + if (cgh != null) + { + cgh.Collection = null; + cgh.GroupHeaderMarkupLinkClick -= CGroupHeaderMarkupLinkClick; + } + + cgh = newValue as ColumnGroupHeader; + + if (cgh != null) + { + cgh.Collection = this; + cgh.GroupHeaderMarkupLinkClick += CGroupHeaderMarkupLinkClick; + } + } + + #endregion + + #region CGroupHeaderMarkupLinkClick + + void CGroupHeaderMarkupLinkClick(object sender, GroupHeaderMarkupLinkClickEventArgs e) + { + if (GroupHeaderMarkupLinkClick != null) + GroupHeaderMarkupLinkClick(sender, e); + } + + #endregion + + #region PropertyChangeHandler + + private void PropertyChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= PropertyValueChanged; + + if (newValue != null) + newValue.PropertyChanged += PropertyValueChanged; + } + + #endregion + + #region PropertyValueChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void PropertyValueChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType)); + } + + #endregion + } + + /// + ///Column GroupHeader + /// + public class ColumnGroupHeader : INotifyPropertyChanged, IDisposable + { + #region Events + + #region HeaderMarkupLinkClick + + internal event EventHandler GroupHeaderMarkupLinkClick; + + #endregion + + #endregion + + #region Private variables + + private int _StartDisplayIndex = -1; + private int _EndDisplayIndex = -1; + + private int _RowHeight; + private int _MinRowHeight; + + private int _StyleUpdateCount; + + private ColumnHeaderVisualStyles _HeaderStyles; + private ColumnHeaderVisualStyles _EffectiveStyles; + + private ColumnGroupHeaderCollection _Collection; + private ColumnGroupHeaderCollection _GroupHeaders; + + private string _Name; + private string _ToolTip; + private string _HeaderText; + + private BodyElement _HeaderTextMarkup; + + private Size _Size; + private Size _ContentSize; + private Size _HeaderTextSize; + private Rectangle _BoundsRelative; + + private Shs _States; + private Tbool _ShowColumnHeaders = Tbool.NotSet; + private Tbool _AutoApplyGroupColors = Tbool.NotSet; + + #endregion + + /// + ///ColumnGroupHeader + /// + public ColumnGroupHeader() + { + AllowSelection = true; + Visible = true; + } + + #region Public properties + + #region AllowSelection + + /// + /// Gets or sets whether the element can be selected + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the element can be selected")] + public bool AllowSelection + { + get { return (TestState(Shs.AllowSelection)); } + + set + { + if (AllowSelection != value) + { + SetState(Shs.AllowSelection, value); + + OnPropertyChangedEx("AllowSelection", VisualChangeType.Render); + } + } + } + + #endregion + + #region AutoApplyGroupColors + + /// + /// Gets or sets whether Group Header color properties + /// (ie. Background and TextColor) are automatically + /// applied to group Column Headers + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether Group Header color properties (ie. Background and TextColor) are automatically applied to group Column Headers.")] + public Tbool AutoApplyGroupColors + { + get { return (_AutoApplyGroupColors); } + + set + { + if (_AutoApplyGroupColors != value) + { + _AutoApplyGroupColors = value; + + OnPropertyChangedEx("AutoApplyGroupColors", VisualChangeType.Render); + } + } + } + + #endregion + + #region Collection + + /// + ///The collection the item is contained within + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ColumnGroupHeaderCollection Collection + { + get { return (_Collection); } + internal set { _Collection = value; } + } + + #endregion + + #region DisplayCount + + /// + /// Gets the count of displayed columns + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int DisplayCount + { + get { return (_EndDisplayIndex - _StartDisplayIndex + 1); } + } + + #endregion + + #region EnableHeaderMarkup + + /// + /// Gets or sets whether text-markup support is enabled for the HeaderText + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for the HeaderText.")] + public bool EnableHeaderMarkup + { + get { return (TestState(Shs.EnableHeaderMarkup)); } + + set + { + if (EnableHeaderMarkup != value) + { + SetState(Shs.EnableHeaderMarkup, value); + + MarkupHeaderTextChanged(); + + OnPropertyChangedEx("EnableHeaderMarkup", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EndDisplayIndex + + /// + /// Gets or sets the end column display index + /// + [DefaultValue(0), Category("Appearance")] + [Description("Indicates the end column display index (inclusive)")] + public int EndDisplayIndex + { + get { return ((_EndDisplayIndex < 0) ? 0 : _EndDisplayIndex); } + + set + { + if (_EndDisplayIndex != value) + { + _EndDisplayIndex = value; + + OnPropertyChangedEx("EndDisplayIndex", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupHeaders + + /// + ///Gets or sets the GroupHeaders contained under the given header + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the GroupHeaders contained under the given header.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ColumnGroupHeaderCollection GroupHeaders + { + get + { + if (_GroupHeaders == null) + { + _GroupHeaders = new ColumnGroupHeaderCollection(); + _GroupHeaders.Parent = this; + + PropertyChangeHandler(null, _GroupHeaders); + GroupCollectionChangeHandler(null, _GroupHeaders); + } + + return (_GroupHeaders); + } + + set + { + if (_GroupHeaders != value) + { + PropertyChangeHandler(_GroupHeaders, value); + GroupCollectionChangeHandler(_GroupHeaders, value); + + _GroupHeaders = value; + + OnPropertyChangedEx("GroupHeaders", VisualChangeType.Layout); + } + } + } + + #region _GroupHeaders + + void GroupHeadersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + ColumnGroupHeaderCollection cgc = sender as ColumnGroupHeaderCollection; + + if (cgc != null) + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + ColumnGroupHeader parent = cgc.Parent as ColumnGroupHeader; + + if (parent != null) + { + foreach (ColumnGroupHeader cgh in e.NewItems) + { + if (parent._StartDisplayIndex < 0 || cgh.StartDisplayIndex < parent.StartDisplayIndex) + parent.StartDisplayIndex = cgh.StartDisplayIndex; + + if (parent._EndDisplayIndex < 0 || cgh.EndDisplayIndex > parent.EndDisplayIndex) + parent.EndDisplayIndex = cgh.EndDisplayIndex; + } + } + } + } + } + + #endregion + + #endregion + + #region HeaderStyles + + /// + /// Gets or sets the visual styles assigned to the Column Header + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates visual style assigned to the Column Header.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ColumnHeaderVisualStyles HeaderStyles + { + get + { + if (_HeaderStyles == null) + { + _HeaderStyles = new ColumnHeaderVisualStyles(); + + PropertyChangeHandler(null, _HeaderStyles); + } + + return (_HeaderStyles); + } + + set + { + if (_HeaderStyles != value) + { + PropertyChangeHandler(_HeaderStyles, value); + + _HeaderStyles = value; + + OnPropertyChangedEx("HeaderStyles", VisualChangeType.Layout); + } + } + } + + #endregion + + #region HeaderText + + /// + /// Gets or sets the Header Text + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Header Text")] + public string HeaderText + { + get { return (_HeaderText); } + + set + { + if (_HeaderText != value) + { + _HeaderText = value; + + MarkupHeaderTextChanged(); + + OnPropertyChangedEx("HeaderText", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsReadOnly + + /// + ///Returns whether the given GroupHeader is ReadOnly (ie. all + ///visible columns/headers it encompasses must be ReadOnly) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsReadOnly + { + get + { + GridColumnHeader gch = GetColumnHeader(); + + if (gch != null) + return (gch.IsGroupHeaderReadOnly(this)); + + return (false); + } + } + + #endregion + + #region IsSelected + + /// + ///Returns whether the given GroupHeader is selected (ie. all + ///visible columns/headers it encompasses must be selected) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSelected + { + get + { + GridColumnHeader gch = GetColumnHeader(); + + if (gch != null) + return (gch.IsGroupHeaderSelected(this)); + + return (false); + } + } + + #endregion + + #region MinRowHeight + + /// + /// Gets or sets the minimum height of the Header row + /// + [DefaultValue(0), Category("Style")] + [Description("Indicates the minimum height of the ColumnHeader row")] + public int MinRowHeight + { + get { return (_MinRowHeight); } + + set + { + if (_MinRowHeight != value) + { + if (value < 0) + throw new Exception("MinRowHeight cannot be negative"); + + _MinRowHeight = value; + + OnPropertyChangedEx("MinRowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Name + + /// + /// Gets or sets the GroupHeader Name + /// + [DefaultValue(null)] + [Description("Indicates the GroupHeader Name")] + public string Name + { + get { return (_Name); } + set { _Name = value; } + } + + #endregion + + #region Parent + + /// + ///The Parent the item + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object Parent + { + get + { + if (_Collection != null) + return (_Collection.Parent); + + return (null); + } + } + + #endregion + + #region RowHeight + + /// + /// Gets or sets the fixed height of the header + /// + [DefaultValue(0), Category("Appearance")] + [Description("Indicates the fixed height of the header")] + public int RowHeight + { + get { return (_RowHeight); } + + set + { + if (_RowHeight != value) + { + _RowHeight = value; + + OnPropertyChangedEx("RowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowColumnHeaders + + /// + /// Gets or sets whether the column headers are shown + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether the root column headers are shown.")] + public Tbool ShowColumnHeaders + { + get { return (_ShowColumnHeaders); } + + set + { + if (_ShowColumnHeaders != value) + { + _ShowColumnHeaders = value; + + OnPropertyChangedEx("ShowColumnHeaders", VisualChangeType.Layout); + } + } + } + + #endregion + + #region StartDisplayIndex + + /// + /// Gets or sets the start column display index + /// + [DefaultValue(-1), Category("Appearance")] + [Description("Indicates the start column index")] + public int StartDisplayIndex + { + get { return ((_StartDisplayIndex < 0) ? 0 : _StartDisplayIndex); } + + set + { + if (_StartDisplayIndex != value) + { + _StartDisplayIndex = value; + + OnPropertyChangedEx("StartDisplayIndex", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ToolTip + + /// + /// Gets or sets the ToolTip text for the sub header. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates ththe ToolTip text for the sub header.")] + public string ToolTip + { + get { return (_ToolTip); } + + set + { + if (_ToolTip != value) + { + _ToolTip = value; + + OnPropertyChanged("ToolTip"); + } + } + } + + #endregion + + #region Visible + + /// + /// Get or sets whether the item is visible + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether item is visible")] + public bool Visible + { + get { return (TestState(Shs.Visible)); } + + set + { + if (Visible != value) + { + SetState(Shs.Visible, value); + + OnPropertyChangedEx("Visible", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region BoundsRelative + + // Does not include sub headers + + internal Rectangle BoundsRelative + { + get { return (_BoundsRelative); } + set { _BoundsRelative = value; } + } + + #endregion + + #region ContentSize + + internal Size ContentSize + { + get { return (_ContentSize); } + set { _ContentSize = value; } + } + + #endregion + + #region EffectiveStyles + + internal ColumnHeaderVisualStyles EffectiveStyles + { + get { return (_EffectiveStyles); } + set { _EffectiveStyles = value; } + } + + #endregion + + #region HeaderTextMarkup + + internal BodyElement HeaderTextMarkup + { + get { return (_HeaderTextMarkup); } + } + + #endregion + + #region HeaderTextSize + + internal Size HeaderTextSize + { + get { return (_HeaderTextSize); } + set { _HeaderTextSize = value; } + } + + #endregion + + #region Size + + // Includes sub headers + + internal Size Size + { + get { return (_Size); } + set { _Size = value; } + } + + #endregion + + #region StyleUpdateCount + + internal int StyleUpdateCount + { + get { return (_StyleUpdateCount); } + set { _StyleUpdateCount = value; } + } + + #endregion + + #endregion + + #region TestState + + private bool TestState(Shs state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(Shs state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #region Contains + + internal bool Contains(int index) + { + return (index >= StartDisplayIndex && index <= EndDisplayIndex); + } + + #endregion + + #region GetColumnHeader + + private GridColumnHeader GetColumnHeader() + { + object parent = Collection.Parent; + + while (parent.GetType() == typeof(ColumnGroupHeader)) + parent = ((ColumnGroupHeader)parent).Collection.Parent; + + return (parent as GridColumnHeader); + } + + #endregion + + #region Markup support + + private void MarkupHeaderTextChanged() + { + if (_HeaderTextMarkup != null) + _HeaderTextMarkup.HyperLinkClick -= HeaderTextMarkupLinkClick; + + _HeaderTextMarkup = null; + + if (EnableHeaderMarkup == true) + { + if (MarkupParser.IsMarkup(_HeaderText) == true) + { + _HeaderTextMarkup = MarkupParser.Parse(_HeaderText); + + if (_HeaderTextMarkup != null) + _HeaderTextMarkup.HyperLinkClick += HeaderTextMarkupLinkClick; + } + } + } + + /// + /// Occurs when a header text markup link is clicked + /// + protected virtual void HeaderTextMarkupLinkClick(object sender, EventArgs e) + { + if (GroupHeaderMarkupLinkClick != null) + { + HyperLink link = (HyperLink)sender; + + GroupHeaderMarkupLinkClickEventArgs ev = + new GroupHeaderMarkupLinkClickEventArgs(this, link); + + GroupHeaderMarkupLinkClick(this, ev); + } + } + + /// + /// Gets plain Header text without text-markup (if text-markup is used in Text) + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public string PlainHeaderText + { + get { return (_HeaderTextMarkup != null ? _HeaderTextMarkup.PlainText : _HeaderText); } + } + + #endregion + + #region GroupCollectionChangeHandler + + private void GroupCollectionChangeHandler( + ColumnGroupHeaderCollection oldValue, ColumnGroupHeaderCollection newValue) + { + if (oldValue != null) + { + oldValue.Parent = null; + oldValue.CollectionChanged -= GroupHeadersCollectionChanged; + } + + if (newValue != null) + { + newValue.Parent = this; + newValue.CollectionChanged += GroupHeadersCollectionChanged; + } + } + + #endregion + + #region PropertyChangeHandler + + private void PropertyChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= PropertyValueChanged; + + if (newValue != null) + newValue.PropertyChanged += PropertyValueChanged; + } + + #endregion + + #region PropertyValueChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void PropertyValueChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s)); + } + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType)); + } + + #endregion + + #region GroupHeaderStates + + [Flags] + private enum Shs + { + AllowSelection = (1 << 0), + EnableHeaderMarkup = (1 << 1), + Visible = (1 << 2), + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + public void Dispose() + { + if (_HeaderTextMarkup != null) + { + _HeaderTextMarkup.HyperLinkClick -= HeaderTextMarkupLinkClick; + + _HeaderTextMarkup = null; + } + } + + #endregion + } + + #region EventArgs + + #region GroupHeaderMarkupLinkClickEventArgs + + /// + /// GroupHeaderMarkupLinkClickEventArgs + /// + internal class GroupHeaderMarkupLinkClickEventArgs : EventArgs + { + #region Private variables + + private ColumnGroupHeader _GroupHeader; + private HyperLink _HyperLink; + + #endregion + + /// + /// GroupHeaderMarkupLinkClickEventArgs + /// + /// + /// + public GroupHeaderMarkupLinkClickEventArgs(ColumnGroupHeader groupHeader, HyperLink hyperLink) + { + _GroupHeader = groupHeader; + _HyperLink = hyperLink; + } + + #region Public properties + + /// + /// Gets the associated GroupHeader + /// + public ColumnGroupHeader GroupHeader + { + get { return (_GroupHeader); } + } + + /// + /// Gets the associated HyperLink + /// + public HyperLink HyperLink + { + get { return (_HyperLink); } + } + + #endregion + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumnHeader.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumnHeader.cs new file mode 100644 index 00000000..0bb5d967 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridColumnHeader.cs @@ -0,0 +1,6532 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Primitives; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.SuperGrid.TextMarkup; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Represents a layout of column headers + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class GridColumnHeader : GridElement + { + #region Constants + + private const int SeparatorWidth = 2; + private const int ImageCacheSize = 8; + + #endregion + + #region Static data + + private static object _lastSelectedItem; + + #endregion + + #region Private variables + + private GridColumnCollection _Columns; + private ColumnGroupHeaderCollection _GroupHeaders; + + private HeaderArea _HitArea; + private object _HitItem; + + private HeaderArea _LastHitArea; + private object _LastHitItem; + + private GridColumn _ResizeColumn; + + private int _MouseDownDelta; + private HeaderArea _MouseDownHitArea; + private object _MouseDownHitItem; + + private Point _MouseDownPoint; + private MouseButtons _MouseDownButtons; + + private bool _DragSelection; + private bool _DragStarted; + + private bool _Reordering; + private bool _Resizing; + private int _ResizeWidth; + + private int _MinRowHeight; + private int _RowHeight; + + private GridColumn _SeparatorColumn; + private bool _SeparatorIsRight; + + private FloatWindow _HeaderFw; + private FloatWindow _SeparatorFw; + + private int _OrderTextOffset; + private int _SelectAllCount; + + private ColumnHeaderRowVisualStyles _EffectiveRowHeaderStyles; + private int _StyleUpdateCount; + + private bool _ShowHeaderImages = true; + + private Image _AscendingSortImage; + private int _AscendingSortImageIndex = -1; + private Image[] _AscendingSortCacheImages = new Image[ImageCacheSize]; + + private Image _DescendingSortImage; + private int _DescendingSortImageIndex = -1; + private Image[] _DescendingSortCacheImages = new Image[ImageCacheSize]; + + private Alignment _SortImageAlignment = Alignment.NotSet; + + private Image _FilterImage; + private int _FilterImageIndex = -1; + private Image[] _FilterCacheImages = new Image[ImageCacheSize * 2]; + + private ImageVisibility _FilterImageVisibility = ImageVisibility.Auto; + private Alignment _FilterImageAlignment = Alignment.NotSet; + + private FilterPopup _FilterMenu; + + private bool _LockedColumn; + private bool _ShowFilterToolTips = true; + private bool _ShowToolTips = true; + private bool _ShowGroupColumnHeaders = true; + private bool _AutoApplyGroupColors = true; + + private string _RowHeaderText; + + #endregion + + #region Internal properties + + #region Columns + + internal GridColumnCollection Columns + { + get { return (_Columns); } + set { _Columns = value; } + } + + #endregion + + #region RowHeaderBounds + + internal Rectangle RowHeaderBounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = Bounds; + r.Width = panel.RowHeaderWidthEx; + + return (r); + } + + return (Rectangle.Empty); + } + } + + #endregion + + #region SelectAllCount + + internal int SelectAllCount + { + get { return (_SelectAllCount); } + set { _SelectAllCount = value; } + } + + #endregion + + #endregion + + #region Public properties + + #region AscendingSortImage + + /// + /// Gets or sets the Ascending sort image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Ascending sort image.")] + public Image AscendingSortImage + { + get { return (_AscendingSortImage); } + + set + { + if (_AscendingSortImage != value) + { + _AscendingSortImage = value; + + OnPropertyChangedEx("AscendingSortImage", VisualChangeType.Render); + } + } + } + + #region GetAscendingSortImage + + internal Image GetAscendingSortImage(GridColumn column) + { + if (_AscendingSortImage != null) + return (_AscendingSortImage); + + if (_AscendingSortImageIndex >= 0) + { + ImageList imageList = GridPanel.ImageList; + + if (imageList != null && _AscendingSortImageIndex < imageList.Images.Count) + return (imageList.Images[_AscendingSortImageIndex]); + } + + return (GetAscendingSortImageEx(column)); + } + + #region GetAscendingSortImageEx + + internal Image GetAscendingSortImageEx(GridColumn column) + { + StyleState state = GetStyleState(column, column.IsSelected); + + Image cacheImage = _AscendingSortCacheImages[(int)state]; + + if (cacheImage == null) + { + int width = Dpi.Width5; + int height = Dpi.Height3; + + if ((width % 2) == 0) + width++; + + Rectangle r = new Rectangle(0, 0, width, height); + Image image = new Bitmap(width, height); + + using (Graphics g = Graphics.FromImage(image)) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = new GraphicsPath()) + { + Point pt = new Point(r.X + r.Width / 2, r.Top); + + Point[] pts = + { + pt, + new Point(r.Right - 1, r.Bottom - 1), + new Point(r.Left, r.Bottom - 1), + pt + }; + + path.AddLines(pts); + + ColumnHeaderRowVisualStyle style = GetEffectiveRowHeaderStyleEx(state); + + Color color = style.SortIndicatorColor; + + if (color.IsEmpty) + color = Color.Black; + + using (Brush br = new SolidBrush(color)) + g.FillPath(br, path); + + using (Pen pen = new Pen(color)) + g.DrawPath(pen, path); + } + } + + _AscendingSortCacheImages[(int)state] = image; + + cacheImage = image; + } + + return (cacheImage); + } + + #endregion + + #endregion + + #endregion + + #region AscendingSortImageIndex + + /// + /// Gets or sets the Ascending Sort Image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the Ascending Sort Image index.")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int AscendingSortImageIndex + { + get { return (_AscendingSortImageIndex); } + + set + { + if (_AscendingSortImageIndex != value) + { + _AscendingSortImageIndex = value; + + OnPropertyChangedEx("AscendingSortImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetAscendingSortImageIndex() + { + _AscendingSortImageIndex = -1; + } + + #endregion + + #region AutoApplyGroupColors + + /// + /// Gets or sets whether Group Header color properties + /// (ie. Background and TextColor) are automatically + /// applied to group Column Headers. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Group Header color properties (ie. Background and TextColor) are automatically applied to group Column Headers.")] + public bool AutoApplyGroupColors + { + get { return (_AutoApplyGroupColors); } + + set + { + if (_AutoApplyGroupColors != value) + { + _AutoApplyGroupColors = value; + + OnPropertyChangedEx("AutoApplyGroupColors", VisualChangeType.Render); + } + } + } + + #endregion + + #region Bounds + + /// + /// Gets the scroll adjusted bounds + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle Bounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = BoundsRelative; + + if (panel.IsSubPanel == true) + { + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + } + + return (r); + } + + return (Rectangle.Empty); + } + } + + #endregion + + #region DescendingSortImage + + /// + /// Gets or sets the Descending sort image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Descending sort image.")] + public Image DescendingSortImage + { + get { return (_DescendingSortImage); } + + set + { + if (_DescendingSortImage != value) + { + _DescendingSortImage = value; + + OnPropertyChangedEx("DescendingSortImage", VisualChangeType.Render); + } + } + } + + #region GetDescendingSortImage + + internal Image GetDescendingSortImage(GridColumn column) + { + if (_DescendingSortImage != null) + return (_DescendingSortImage); + + if (_DescendingSortImageIndex >= 0) + { + ImageList imageList = GridPanel.ImageList; + + if (imageList != null && _DescendingSortImageIndex < imageList.Images.Count) + return (imageList.Images[_DescendingSortImageIndex]); + } + + return (GetDescendingSortImageEx(column)); + } + + #region GetDescendingSortImageEx + + internal Image GetDescendingSortImageEx(GridColumn column) + { + StyleState state = GetStyleState(column, column.IsSelected); + + Image cacheImage = _DescendingSortCacheImages[(int)state]; + + if (cacheImage == null) + { + int width = Dpi.Width5; + int height = Dpi.Height3; + + if ((width % 2) == 0) + width++; + + Rectangle r = new Rectangle(0, 0, width, height); + Image image = new Bitmap(width, height); + + using (Graphics g = Graphics.FromImage(image)) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = new GraphicsPath()) + { + Point pt = new Point(r.X + width / 2, r.Bottom - 1); + + Point[] pts = + { + pt, + new Point(r.Right - 1, r.Top), + new Point(r.Left, r.Top), + pt + }; + + path.AddLines(pts); + + ColumnHeaderRowVisualStyle style = GetEffectiveRowHeaderStyleEx(state); + + Color color = style.SortIndicatorColor; + + if (color.IsEmpty) + color = Color.Black; + + using (Brush br = new SolidBrush(color)) + g.FillPath(br, path); + + using (Pen pen = new Pen(color)) + g.DrawPath(pen, path); + } + } + + _DescendingSortCacheImages[(int)state] = image; + + cacheImage = image; + } + + return (cacheImage); + } + + #endregion + + #endregion + + #endregion + + #region DescendingSortImageIndex + + /// + /// Gets or sets the Descending Sort Image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the Descending Sort Image index.")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int DescendingSortImageIndex + { + get { return (_DescendingSortImageIndex); } + + set + { + if (_DescendingSortImageIndex != value) + { + _DescendingSortImageIndex = value; + + OnPropertyChangedEx("DescendingSortImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetDescendingSortImageIndex() + { + _DescendingSortImageIndex = -1; + } + + #endregion + + #region FilterImage + + /// + /// Gets or sets the default + /// image to display in the column header. + /// + [DefaultValue(null), Category("Filtering")] + [Description("Indicates the default image to display in the column header.")] + public Image FilterImage + { + get { return (_FilterImage); } + + set + { + if (_FilterImage != value) + { + _FilterImage = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("FilterImage", VisualChangeType.Layout); + } + } + } + + #region GetFilterImage + + internal Image GetFilterImage(GridColumn column) + { + bool inFilter; + StyleState state = GetFilterImageState(column, out inFilter); + + return (GetFilterImage(column, state, inFilter)); + } + + internal Image GetFilterImage( + GridColumn column, StyleState state, bool inFilter) + { + if (_FilterImage != null) + return (_FilterImage); + + if (_FilterImageIndex >= 0) + { + ImageList imageList = GridPanel.ImageList; + + if (imageList != null && _FilterImageIndex < imageList.Images.Count) + return (imageList.Images[_FilterImageIndex]); + } + + return (GetFilterImageEx(state, inFilter)); + } + + #region GetFilterImageEx + + private Image GetFilterImageEx(StyleState state, bool inFilter) + { + int n = (int)state; + + if (inFilter == true) + n += ImageCacheSize; + + Image cacheImage = _FilterCacheImages[n]; + + if (cacheImage == null) + { + Image image = new Bitmap(Dpi.Width8, Dpi.Height8); + + using (Graphics g = Graphics.FromImage(image)) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = new GraphicsPath()) + { + Point[] pts = + { + new Point(0, 0), + new Point(Dpi.Width7, 0), + new Point(Dpi.Width7, Dpi.Height1), + new Point(Dpi.Width4, Dpi.Height4), + new Point(Dpi.Width4, Dpi.Height7), + new Point(Dpi.Width3, Dpi.Height6), + new Point(Dpi.Width3, Dpi.Height4), + new Point(0, Dpi.Height1), + new Point(0, 0), + }; + + path.AddLines(pts); + + Rectangle r = new Rectangle(Dpi.Width1, Dpi.Height1, Dpi.Width6, Dpi.Height3); + + ColumnHeaderRowVisualStyle style = GetEffectiveRowHeaderStyleEx(state); + + Color color = style.FilterBorderColor; + + if (color.IsEmpty) + color = Color.DimGray; + + if (inFilter == false) + style = GetEffectiveRowHeaderStyleEx(state & ~StyleState.MouseOver); + + Background back = (style.FilterBackground != null && style.FilterBackground.IsEmpty == false) + ? style.FilterBackground : new Background(Color.White); + + using (Brush br = back.GetBrush(r)) + g.FillPath(br, path); + + using (Pen pen = new Pen(color)) + g.DrawPath(pen, path); + } + } + + _FilterCacheImages[n] = image; + + cacheImage = image; + } + + return (cacheImage); + } + + #region GetFilterImageState + + private StyleState GetFilterImageState(GridColumn column, out bool inFilter) + { + inFilter = false; + + StyleState state = GetRowHeaderState(); + + state &= ~(StyleState.MouseOver | StyleState.Selected); + + GridColumn hitColumn = _HitItem as GridColumn; + + if (column == hitColumn) + { + state |= StyleState.MouseOver; + + if (_HitArea == HeaderArea.InFilterMenu) + inFilter = true; + } + + if (column != null && string.IsNullOrEmpty(column.FilterExpr) == false) + state |= StyleState.Selected; + + return (state); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region FilterImageAlignment + + /// + /// Gets or sets the alignment of the filter Image + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the filter Image.")] + public Alignment FilterImageAlignment + { + get { return (_FilterImageAlignment); } + + set + { + if (_FilterImageAlignment != value) + { + _FilterImageAlignment = value; + + OnPropertyChangedEx("FilterImageAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterImageIndex + + /// + /// Gets or sets the Filter image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the Filter Row image index.")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int FilterImageIndex + { + get { return (_FilterImageIndex); } + + set + { + if (_FilterImageIndex != value) + { + _FilterImageIndex = value; + + OnPropertyChangedEx("FilterImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetFilterImageIndex() + { + _FilterImageIndex = -1; + } + + #endregion + + #region FilterImageVisibility + + /// + /// Gets or sets the visibility of the header filter image + /// + [DefaultValue(ImageVisibility.Auto), Category("Filtering")] + [Description("Indicates the visibility of the header filter image.")] + public ImageVisibility FilterImageVisibility + { + get { return (_FilterImageVisibility); } + + set + { + if (_FilterImageVisibility != value) + { + _FilterImageVisibility = value; + + OnPropertyChangedEx("FilterImageVisibility", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupHeaders + + /// + /// Gets a reference to the collection of grid columns + /// + [Category("Appearance")] + [Description("Indicates the collection of grid columns.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ColumnGroupHeaderCollection GroupHeaders + { + get + { + if (_GroupHeaders == null) + { + _GroupHeaders = new ColumnGroupHeaderCollection(); + + _GroupHeaders.Parent = this; + + _GroupHeaders.CollectionChanged += GroupHeadersCollectionChanged; + _GroupHeaders.PropertyChanged += GroupHeadersPropertyChanged; + _GroupHeaders.GroupHeaderMarkupLinkClick += GroupHeaderMarkupLinkClick; + } + + return (_GroupHeaders); + } + } + + #region GroupHeadersCollectionChanged + + void GroupHeadersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + NeedsMeasured = true; + SuperGrid.StyleUpdateCount++; + + InvalidateLayout(); + } + + #endregion + + #region GroupHeadersPropertyChanged + + void GroupHeadersPropertyChanged(object sender, PropertyChangedEventArgs e) + { + NeedsMeasured = true; + + InvalidateStyle(); + InvalidateLayout(); + } + + #endregion + + #region GroupHeadersMarkupLinkClick + + void GroupHeaderMarkupLinkClick(object sender, GroupHeaderMarkupLinkClickEventArgs e) + { + SuperGrid.DoColumnGroupHeaderMarkupLinkClickEvent( + GridPanel, this, e.GroupHeader, e.HyperLink); + } + + #endregion + + #endregion + + #region MinRowHeight + + /// + /// Gets or sets the minimum height of the ColumnHeader row + /// + [DefaultValue(0), Category("Style")] + [Description("Indicates the minimum height of the ColumnHeader row")] + public int MinRowHeight + { + get { return (_MinRowHeight); } + + set + { + if (_MinRowHeight != value) + { + if (value < 0) + throw new Exception("MinRowHeight cannot be negative"); + + _MinRowHeight = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("MinRowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region RowHeaderText + + /// + /// Gets or sets the associated row header text (only + /// displayed if TopLeftHeaderSelectBehavior is set to NoSelection). + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the associated row header text (only displayed if TopLeftHeaderSelectBehavior is set to NoSelection).")] + public string RowHeaderText + { + get { return (_RowHeaderText); } + + set + { + if (_RowHeaderText != value) + { + _RowHeaderText = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("RowHeaderText", VisualChangeType.Render); + } + } + } + + #endregion + + #region RowHeight + + /// + /// Gets or sets the height of the ColumnHeader row + /// + [DefaultValue(0), Category("Style")] + [Description("Indicates the height of the ColumnHeader row")] + public int RowHeight + { + get { return (_RowHeight); } + + set + { + if (_RowHeight != value) + { + if (value < 0) + throw new Exception("RowHeight cannot be negative"); + + _RowHeight = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("RowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowFilterToolTips + + /// + /// Gets or sets whether tooltips are shown when over the filter image + /// + [DefaultValue(true), Category("Filtering")] + [Description("Indicates whether tooltips are shown when over the filter image.")] + public bool ShowFilterToolTips + { + get { return (_ShowFilterToolTips); } + + set + { + if (value != _ShowFilterToolTips) + { + _ShowFilterToolTips = value; + + OnPropertyChanged("ShowFilterToolTips"); + } + } + } + + #endregion + + #region ShowHeaderImages + + /// + /// Gets or sets whether Column Header images are displayed + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Column Header images are displayed.")] + public bool ShowHeaderImages + { + get { return (_ShowHeaderImages); } + + set + { + if (_ShowHeaderImages != value) + { + _ShowHeaderImages = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("ShowHeaderImages", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowGroupColumnHeaders + + /// + /// Gets or sets whether column headers are shown + /// by default when the columns are within a grouped header + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether column headers are shown by default when the columns are within a grouped header.")] + public bool ShowGroupColumnHeaders + { + get { return (_ShowGroupColumnHeaders); } + + set + { + if (_ShowGroupColumnHeaders != value) + { + _ShowGroupColumnHeaders = value; + + OnPropertyChangedEx("ShowGroupColumnHeaders", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowToolTips + + /// + /// Gets or sets whether tooltips are shown for the column header + /// + [DefaultValue(true), Category("Filtering")] + [Description("Indicates whether tooltips are shown for the column header.")] + public bool ShowToolTips + { + get { return (_ShowToolTips); } + + set + { + if (value != _ShowToolTips) + { + _ShowToolTips = value; + + OnPropertyChanged("ShowToolTips"); + } + } + } + + #endregion + + #region SortImageAlignment + + /// + /// Gets or sets the alignment of the Sort Images + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the Sort Images.")] + public Alignment SortImageAlignment + { + get { return (_SortImageAlignment); } + + set + { + if (_SortImageAlignment != value) + { + _SortImageAlignment = value; + + OnPropertyChangedEx("SortImageAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region MeasureOverride + + /// + /// Performs the layout of the item and sets + /// the Size property to size that item will take. + /// + /// Layout information. + /// + /// + protected override void MeasureOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + GridPanel panel = stateInfo.GridPanel; + + ResetProcessStates(panel); + + Size sizeNeeded = MeasureGroupHeaders(layoutInfo, constraintSize, panel); + MeasureColumnHeaders(layoutInfo, constraintSize, panel, ref sizeNeeded); + + if (panel.ShowRowHeaders == true) + sizeNeeded.Width += panel.RowHeaderWidthEx; + + Size = sizeNeeded; + } + + #region MeasureGroupHeaders + + private Size MeasureGroupHeaders( + GridLayoutInfo layoutInfo, Size constraintSize, GridPanel panel) + { + Size sizeNeeded = Size.Empty; + + if (_GroupHeaders != null) + { + foreach (ColumnGroupHeader cgh in _GroupHeaders) + { + if (cgh.Visible == true) + { + Size size = MeasureGroupHeader(layoutInfo, constraintSize, panel, cgh); + + sizeNeeded.Width += size.Width; + sizeNeeded.Height = Math.Max(size.Height, sizeNeeded.Height); + } + } + } + + return (sizeNeeded); + } + + #region MeasureGroupHeader + + private Size MeasureGroupHeader(GridLayoutInfo layoutInfo, + Size constraintSize, GridPanel panel, ColumnGroupHeader cgh) + { + Size sizeNeeded = MeasureGroupHeaderColumn(layoutInfo, constraintSize, panel, cgh); + + if (cgh.RowHeight > 0) + { + sizeNeeded.Height = Dpi.Height(cgh.RowHeight); + } + else + { + int mrh = Dpi.Height(cgh.MinRowHeight); + + if (sizeNeeded.Height < mrh) + sizeNeeded.Height = mrh; + } + + cgh.ContentSize = sizeNeeded; + + if (cgh.GroupHeaders.Count > 0) + { + Size subSize = Size.Empty; + + foreach (ColumnGroupHeader gh in cgh.GroupHeaders) + { + Size size = MeasureGroupHeader(layoutInfo, constraintSize, panel, gh); + + subSize.Height = Math.Max(subSize.Height, size.Height); + subSize.Width += size.Width; + } + + sizeNeeded.Height += subSize.Height; + sizeNeeded.Width = Math.Max(sizeNeeded.Width, subSize.Width); + } + else + { + Size baseSize = Size.Empty; + GridColumnCollection columns = _Columns; + + bool showColumnHeaders = GetShowRootColumnHeaders(cgh); + + int[] map = columns.DisplayIndexMap; + + for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) + { + if ((uint)i >= map.Length) + break; + + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + if (showColumnHeaders == true) + { + Size size = MeasureHeader(layoutInfo, constraintSize, panel, column); + + baseSize.Width += size.Width; + baseSize.Height = Math.Max(baseSize.Height, size.Height); + } + } + } + + sizeNeeded.Height += baseSize.Height; + + if (constraintSize.Width > 0) + sizeNeeded.Width = baseSize.Width; + else + sizeNeeded.Width = Math.Max(sizeNeeded.Width, baseSize.Width); + } + + cgh.Size = sizeNeeded; + + return (sizeNeeded); + } + + #region MeasureGroupHeaderColumn + + private Size MeasureGroupHeaderColumn(GridLayoutInfo layoutInfo, + Size constraintSize, GridPanel panel, ColumnGroupHeader cgh) + { + ColumnHeaderVisualStyle style = GetSizingStyle(panel, cgh); + + Size sizeNeeded = MeasureGroupHeaderTextAndImage(layoutInfo, constraintSize, panel, cgh, style); + + sizeNeeded.Width += Dpi.Width8; + sizeNeeded.Height += Dpi.Height4; + + return (sizeNeeded); + } + + #region MeasureGroupHeaderTextAndImage + + private Size MeasureGroupHeaderTextAndImage(GridLayoutInfo layoutInfo, Size constraintSize, + GridPanel panel, ColumnGroupHeader cgh, ColumnHeaderVisualStyle style) + { + Size sizeNeeded = Size.Empty; + + object figure = (_ShowHeaderImages == true) ? style.GetFigure(panel) : null; + Size figureSize = style.GetFigureSize(panel); + + Alignment imageAlignment = style.ImageAlignment; + + if (style.IsOverlayImage == true) + imageAlignment = Alignment.MiddleCenter; + + Size borderSize = style.GetBorderSize(true); + + int bwidth = (borderSize.Width * 2); + int bheight = (borderSize.Height * 2); + + int width = constraintSize.Width > 0 ? GetDefaultGroupHeaderWidth(panel, cgh) : 0; + + if (width > 0) + { + width -= bwidth; + + switch (imageAlignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + break; + + default: + width -= figureSize.Width; + break; + } + } + + Size contentSize = + MeasureGroupHeaderText(layoutInfo.Graphics, cgh, style, new Size(width, 0)); + + switch (imageAlignment) + { + case Alignment.MiddleCenter: + sizeNeeded.Height = Math.Max(figureSize.Height, contentSize.Height) + bheight; + sizeNeeded.Width = Math.Max(figureSize.Width, contentSize.Width) + bwidth; + break; + + case Alignment.TopCenter: + case Alignment.BottomCenter: + sizeNeeded.Width = Math.Max(figureSize.Width, contentSize.Width) + bwidth; + sizeNeeded.Height = contentSize.Height + figureSize.Height + bheight; + break; + + default: + sizeNeeded.Width = contentSize.Width + figureSize.Width + bwidth; + sizeNeeded.Height = Math.Max(figureSize.Height, contentSize.Height) + bheight; + break; + } + + return (sizeNeeded); + } + + #region GetDefaultGroupHeaderWidth + + private int GetDefaultGroupHeaderWidth( + GridPanel panel, ColumnGroupHeader cgh) + { + int width = 0; + + GridColumnCollection columns = panel.Columns; + int[] map = columns.DisplayIndexMap; + + for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) + { + if ((uint)i >= map.Length) + break; + + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + width += column.Size.Width; + } + + return (width); + } + + #endregion + + #region MeasureGroupHeaderText + + private Size MeasureGroupHeaderText(Graphics g, + ColumnGroupHeader cgh, CellVisualStyle style, Size constraintSize) + { + Size size = Size.Empty; + + string s = GetHeaderText(cgh); + + if (string.IsNullOrEmpty(s) == false) + { + if (cgh.HeaderTextMarkup != null) + { + size = GetMarkupTextSize(g, + cgh.HeaderTextMarkup, style, constraintSize.Width); + + cgh.HeaderTextSize = size; + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + size = (constraintSize.IsEmpty == true) + ? TextHelper.MeasureText(g, s, style.Font) + : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); + } + } + + return (size); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region MeasureColumnHeaders + + private void MeasureColumnHeaders( + GridLayoutInfo layoutInfo, Size constraintSize, GridPanel panel, ref Size sizeNeeded) + { + GridColumnCollection columns = _Columns; + + for (int i = 0; i < columns.Count; i++) + { + GridColumn column = columns[i]; + + if (column.Processed == false) + { + Size size = MeasureHeader(layoutInfo, constraintSize, panel, column); + + sizeNeeded.Width += size.Width; + sizeNeeded.Height = Math.Max(size.Height, sizeNeeded.Height); + } + } + } + + #endregion + + #region MeasureHeader + + internal Size MeasureHeader(GridLayoutInfo layoutInfo, + Size constraintSize, GridPanel panel, GridColumn column) + { + Size sizeNeeded = Size.Empty; + + ColumnHeaderVisualStyle style = GetSizingStyle(panel, column); + + MeasureTextAndImage(layoutInfo, constraintSize, panel, column, style, ref sizeNeeded); + MeasureSortAndFilter(panel, column, style, ref sizeNeeded); + + sizeNeeded.Width += Dpi.Width8; + sizeNeeded.Height += Dpi.Height4; + + if (Dpi.Height(_RowHeight) > 0) + sizeNeeded.Height = Dpi.Height(_RowHeight); + + else if (sizeNeeded.Height < Dpi.Height(_MinRowHeight)) + sizeNeeded.Height = Dpi.Height(_MinRowHeight); + + column.HeaderSize = sizeNeeded; + + column.Processed = true; + + return (sizeNeeded); + } + + #region MeasureTextAndImage + + private void MeasureTextAndImage(GridLayoutInfo layoutInfo, Size constraintSize, + GridPanel panel, GridColumn column, ColumnHeaderVisualStyle style, ref Size sizeNeeded) + { + Size figureSize = (_ShowHeaderImages == true) + ? style.GetFigureSize(panel) : Size.Empty; + + Alignment imageAlignment = style.ImageAlignment; + + if (style.IsOverlayImage == true) + imageAlignment = Alignment.MiddleCenter; + + Size borderSize = style.GetBorderSize(true); + + int bwidth = (borderSize.Width * 2); + int bheight = (borderSize.Height * 2); + + int width = constraintSize.Width > 0 ? column.Size.Width : 0; + + if (width > 0) + { + width -= bwidth; + + switch (imageAlignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + break; + + default: + width -= figureSize.Width; + break; + } + } + + Size contentSize = + MeasureHeaderText(layoutInfo.Graphics, column, style, new Size(width, 0)); + + if (width == 0) + column.HeaderTextSize = contentSize; + + switch (imageAlignment) + { + case Alignment.MiddleCenter: + sizeNeeded.Height = Math.Max(figureSize.Height, contentSize.Height) + bheight; + sizeNeeded.Width = Math.Max(figureSize.Width, contentSize.Width) + bwidth; + break; + + case Alignment.TopCenter: + case Alignment.BottomCenter: + sizeNeeded.Width = Math.Max(figureSize.Width, contentSize.Width) + bwidth; + sizeNeeded.Height = contentSize.Height + figureSize.Height + bheight; + break; + + default: + sizeNeeded.Width = contentSize.Width + figureSize.Width + bwidth; + sizeNeeded.Height = Math.Max(figureSize.Height, contentSize.Height) + bheight; + break; + } + } + + #region MeasureHeaderText + + private Size MeasureHeaderText(Graphics g, + GridColumn column, CellVisualStyle style, Size constraintSize) + { + Size size = Size.Empty; + + string s = column.GetHeaderText(); + + if (string.IsNullOrEmpty(s) == false) + { + if (column.HeaderTextMarkup != null) + { + size = GetMarkupTextSize(g, + column.HeaderTextMarkup, style, constraintSize.Width > 0 ? constraintSize.Width : 10000); + + column.HeaderTextSize = size; + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + size = (constraintSize.IsEmpty == true) + ? TextHelper.MeasureText(g, s, style.Font) + : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); + } + } + + return (size); + } + + #region GetMarkupTextSize + + private Size GetMarkupTextSize(Graphics g, + BodyElement textMarkup, CellVisualStyle style, int width) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + textMarkup.InvalidateElementsSize(); + textMarkup.Measure(new Size(width, 0), d); + + return (textMarkup.Bounds.Size); + } + + #endregion + + #endregion + + #endregion + + #region MeasureSortAndFilter + + private void MeasureSortAndFilter(GridPanel panel, + GridColumn column, ColumnHeaderVisualStyle style, ref Size sizeNeeded) + { + Alignment sortAlignment = (_SortImageAlignment == Alignment.NotSet) + ? Alignment.TopCenter : _SortImageAlignment; + + Alignment filterAlignment = (_FilterImageAlignment == Alignment.NotSet) + ? Alignment.MiddleLeft : _FilterImageAlignment; + + int imsHeight = 0; + + if (panel.SortLevel != SortLevel.None) + { + imsHeight = GetPartSizeNeeded( + GetAscendingSortImage(column), style, sortAlignment, ref sizeNeeded); + } + + int imfHeight = 0; + + if (FilterCanBeVisible(panel) == true) + { + imfHeight = GetPartSizeNeeded( + GetFilterImage(column), style, filterAlignment, ref sizeNeeded); + } + + if (imsHeight > 0 && imfHeight > 0) + { + if (VAlignment(sortAlignment) == VAlignment(filterAlignment)) + { + int n = Math.Max(imsHeight, imfHeight); + + sizeNeeded.Height += n; + + if (VAlignment(style.Alignment) == 1) + sizeNeeded.Height += n; + } + else + sizeNeeded.Height += (imsHeight + imfHeight); + } + else + { + int n = imsHeight + imfHeight; + + sizeNeeded.Height += n; + + if (VAlignment(style.Alignment) == 1) + sizeNeeded.Height += n; + } + } + + #region GetPartSizeNeeded + + private int GetPartSizeNeeded(Image image, + ColumnHeaderVisualStyle style, Alignment alignment, ref Size sizeNeeded) + { + int height = 0; + + if (image != null) + { + if (alignment != Alignment.TopCenter && + alignment != Alignment.MiddleCenter && + alignment != Alignment.BottomCenter) + { + sizeNeeded.Width += (image.Width + 4); + } + + if (alignment == Alignment.MiddleLeft || + alignment == Alignment.MiddleCenter || + alignment == Alignment.MiddleRight || + VAlignment(alignment) == VAlignment(style.Alignment)) + { + sizeNeeded.Height = Math.Max(sizeNeeded.Height, image.Height); + } + else + { + height = (image.Height + 2); + } + } + + return (height); + } + + #endregion + + #region FilterCanBeVisible + + private bool FilterCanBeVisible(GridPanel panel) + { + if (panel.EnableFiltering == true && panel.EnableColumnFiltering == true) + { + if (FilterImageVisibility != ImageVisibility.Never) + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region ArrangeOverride + + /// + /// Performs the arrange pass layout of the item + /// when final position and size of the item has been set. + /// + /// Layout information. + /// + /// Layout bounds + protected override void ArrangeOverride(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + ArrangeGroupHeader(panel, GroupHeaders, 0); + + foreach (GridColumn col in panel.Columns) + { + if (col.Visible == true) + UpdateImageBounds(panel, col); + } + } + } + + #region ArrangeGroupHeader + + private void ArrangeGroupHeader( + GridPanel panel, IEnumerable csc, int dy) + { + if (csc != null) + { + foreach (ColumnGroupHeader cgh in csc) + { + if (cgh.Visible == true) + { + Size oldSize = cgh.BoundsRelative.Size; + + cgh.BoundsRelative = GetGroupHeaderBounds(panel, cgh, dy); + cgh.Size = new Size(cgh.Size.Width, Bounds.Height - dy); + + ArrangeGroupHeader(panel, cgh.GroupHeaders, dy + cgh.BoundsRelative.Height); + + if (oldSize != cgh.BoundsRelative.Size) + SuperGrid.DoColumnGroupHeaderResizedEvent(panel, cgh, oldSize); + } + } + } + } + + #region GetGroupHeaderBounds + + private Rectangle GetGroupHeaderBounds( + GridPanel panel, ColumnGroupHeader cgh, int dy) + { + GridColumnCollection columns = panel.Columns; + + Rectangle r = Rectangle.Empty; + int[] map = columns.DisplayIndexMap; + + bool showColHeaders = GetShowRootColumnHeaders(cgh) && cgh.GroupHeaders.Count == 0; + + for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) + { + if ((uint)i < columns.Count) + { + GridColumn column = columns[map[i]]; + + if (column.Visible == true) + { + Rectangle q = GetRelativeBounds(panel, column); + + r = (r.IsEmpty == true) ? q : Rectangle.Union(r, q); + + r.Height = (showColHeaders == true) ? column.HeaderSize.Height : 0; + } + } + } + + r.Y += dy; + + if (cgh.GroupHeaders.Count > 0) + { + r.Height = cgh.ContentSize.Height; + } + else + { + if (showColHeaders == true && cgh.RowHeight > 0) + r.Height = Dpi.Height(cgh.RowHeight); + else + r.Height = (Bounds.Bottom - r.Bottom); + } + + return (r); + } + + #endregion + + #endregion + + #endregion + + #region RenderOverride + + /// + /// Performs drawing of the item and its children. + /// + /// Holds contextual rendering information. + protected override void RenderOverride(GridRenderInfo renderInfo) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + ResetProcessStates(panel); + + Graphics g = renderInfo.Graphics; + Rectangle bounds = Bounds; + + ColumnHeaderRowVisualStyle style = GetEffectiveRowHeaderStyle(); + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + if (SuperGrid.DoPreRenderColumnHeaderEvent(g, + this, null, RenderParts.Background, bounds) == false) + { + RenderRowBackground(g, style, bounds); + + SuperGrid.DoPostRenderColumnHeaderEvent(g, + this, null, RenderParts.Background, bounds); + } + + RenderColumnBorder(g, panel, bounds); + + if (HScrollOffset == 0 || panel.IsSubPanel || panel.FrozenColumnCount <= 0) + { + RenderHeaders(panel, renderInfo, false, false); + } + else + { + RenderHeaders(panel, renderInfo, true, false); + RenderHeaders(panel, renderInfo, true, true); + } + + if (panel.FrozenColumnCount > 0) + RenderFrozenColumnMarker(g, panel, pstyle); + + RenderRowHeader(g, panel, style, pstyle); + } + } + + #region RenderRowBackground + + private void RenderRowBackground( + Graphics g, ColumnHeaderRowVisualStyle style, Rectangle bounds) + { + using (Brush br = style.WhiteSpaceBackground.GetBrush(bounds)) + g.FillRectangle(br, bounds); + } + + #endregion + + #region RenderColumnBorder + + private void RenderColumnBorder( + Graphics g, GridPanel panel, Rectangle bounds) + { + Rectangle r = bounds; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + if (pstyle.HeaderHLinePattern != LinePattern.None && + pstyle.HeaderHLinePattern != LinePattern.NotSet) + { + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) + { + pen.DashStyle = (DashStyle)pstyle.HeaderHLinePattern; + + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + g.DrawLine(pen, r.X, r.Top - 1, r.Right - 1, r.Top - 1); + } + } + + if (pstyle.HeaderVLinePattern != LinePattern.None && + pstyle.HeaderVLinePattern != LinePattern.NotSet) + { + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) + { + pen.DashStyle = (DashStyle)pstyle.HeaderVLinePattern; + + g.DrawLine(pen, r.Right - 1, r.Top - 1, r.Right - 1, r.Bottom - 1); + } + } + + g.SmoothingMode = sm; + } + + #endregion + + #region RenderHeaders + + private void RenderHeaders(GridPanel panel, + GridRenderInfo renderInfo, bool chkFrozen, bool frozen) + { + Graphics g = renderInfo.Graphics; + Rectangle clip = renderInfo.ClipRectangle; + + RenderGroupHeaders(g, panel, clip, GroupHeaders, chkFrozen, frozen); + RenderColumnHeaders(g, panel, clip, chkFrozen, frozen); + } + + #region RenderGroupHeaders + + private void RenderGroupHeaders(Graphics g, GridPanel panel, + Rectangle clip, IEnumerable csc, bool chkFrozen, bool frozen) + { + if (csc != null) + { + foreach (ColumnGroupHeader cgh in csc) + { + if (cgh.Visible == true) + { + if (chkFrozen == false || (IsGroupHeaderHFrozen(panel, cgh) == frozen)) + { + Rectangle r = GetSubContScrollBounds(panel, cgh); + + if (clip.IsEmpty == true || r.IntersectsWith(clip) == true) + { + Rectangle bounds = GetSubScrollBounds(panel, cgh); + + RenderGroupHeader(g, panel, cgh, bounds); + + if (cgh.GroupHeaders.Count > 0) + RenderGroupHeaders(g, panel, Rectangle.Empty, cgh.GroupHeaders, chkFrozen, frozen); + + RenderBaseHeaders(g, panel, cgh); + } + else + { + if (cgh.GroupHeaders.Count > 0) + RenderGroupHeaders(g, panel, Rectangle.Empty, cgh.GroupHeaders, chkFrozen, frozen); + } + } + } + } + } + } + + #region RenderGroupHeader + + private void RenderGroupHeader( + Graphics g, GridPanel panel, ColumnGroupHeader cgh, Rectangle bounds) + { + if (bounds.IsEmpty == false) + { + ColumnHeaderVisualStyle style = GetEffectiveStyle(cgh); + + if (bounds.Width > 0 && bounds.Height > 0) + { + if (SuperGrid.DoPreRenderColumnGroupHeaderEvent(g, + this, cgh, RenderParts.Background, bounds) == false) + { + RenderBackground(g, style, bounds); + + SuperGrid.DoPostRenderColumnGroupHeaderEvent(g, + this, cgh, RenderParts.Background, bounds); + } + + RenderColumnBorder(g, panel, bounds); + + Rectangle r = bounds; + Rectangle t = GetContentBounds(panel, style, r); + + t = GetAdjustedBounds(style, t); + + if (style.ImageOverlay == ImageOverlay.None || + style.ImageOverlay == ImageOverlay.Bottom) + { + RenderHeaderImage(g, panel, style, bounds, t); + } + + if (SuperGrid.DoPreRenderColumnGroupHeaderEvent(g, + this, cgh, RenderParts.Content, t) == false) + { + RenderGroupHeaderText(g, style, cgh, t); + + SuperGrid.DoPostRenderColumnGroupHeaderEvent(g, + this, cgh, RenderParts.Content, t); + } + + if (style.ImageOverlay == ImageOverlay.Top) + RenderHeaderImage(g, panel, style, bounds, t); + + r = GetBorderRect(style, r); + + if (SuperGrid.DoPreRenderColumnGroupHeaderEvent(g, + this, cgh, RenderParts.Border, r) == false) + { + if (r.Width > 0 && r.Height > 0) + style.RenderBorder(g, r); + + SuperGrid.DoPostRenderColumnGroupHeaderEvent(g, + this, cgh, RenderParts.Border, r); + } + } + } + } + + #region RenderGroupHeaderText + + private void RenderGroupHeaderText(Graphics g, + ColumnHeaderVisualStyle style, ColumnGroupHeader cgh, Rectangle r) + { + if (_MouseDownButtons == MouseButtons.Left) + r = AdjustTextHeaderBounds(cgh, r, GridPanel.ColumnGroupHeaderClickBehavior); + + if (cgh.HeaderTextMarkup != null) + { + RenderTextMarkup(g, cgh.HeaderTextMarkup, style, r); + } + else + { + string s = GetHeaderText(cgh); + + if (string.IsNullOrEmpty(s) == false) + { + TextDrawing.DrawString(g, s, + style.Font, style.TextColor, r, style.GetTextFormatFlags()); + } + } + } + + #region GetHeaderText + + private string GetHeaderText(ColumnGroupHeader cgh) + { + return (cgh.HeaderText ?? cgh.Name); + } + + #endregion + + #endregion + + #endregion + + #region RenderBaseHeaders + + private void RenderBaseHeaders(Graphics g, GridPanel panel, ColumnGroupHeader cgh) + { + int[] map = panel.Columns.DisplayIndexMap; + + for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) + { + if ((uint)i >= map.Length) + break; + + RenderBaseHeader(g, panel, cgh, map[i]); + } + } + + #region RenderBaseHeader + + private void RenderBaseHeader(Graphics g, + GridPanel panel, ColumnGroupHeader cgh, int i) + { + GridColumn col = panel.Columns[i]; + + if (col.Visible == true && col.Processed == false) + { + Rectangle r = GetBounds(panel, col); + + int n = cgh.Size.Height - cgh.BoundsRelative.Height; + + r.Y = r.Bottom - n; + r.Height = n; + + if (GetShowRootColumnHeaders(cgh) == true || cgh.GroupHeaders.Count > 0) + { + RenderColumnHeader(g, panel, col, r, true); + } + else + { + RenderColumnBorder(g, panel, r); + col.Processed = true; + } + } + } + + #endregion + + #endregion + + #endregion + + #region RenderColumnHeaders + + private void RenderColumnHeaders(Graphics g, + GridPanel panel, Rectangle clip, bool chkFrozen, bool frozen) + { + GridColumnCollection columns = _Columns; + + int[] map = columns.DisplayIndexMap; + + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true && column.Processed == false) + { + if ((chkFrozen == false) || (frozen == column.IsHFrozen)) + { + Rectangle r = GetBounds(panel, column); + + if (r.IntersectsWith(clip) == true) + RenderColumnHeader(g, panel, column, r, true); + } + } + } + } + + #region RenderColumnHeader + + private void RenderColumnHeader(Graphics g, + GridPanel panel, GridColumn column, Rectangle bounds, bool fullRender) + { + ColumnHeaderVisualStyle style = GetEffectiveStyle(column); + + if (bounds.Width > 0 && bounds.Height > 0) + { + if (SuperGrid.DoPreRenderColumnHeaderEvent(g, + this, column, RenderParts.Background, bounds) == false) + { + RenderBackground(g, style, bounds); + + SuperGrid.DoPostRenderColumnHeaderEvent(g, + this, column, RenderParts.Background, bounds); + } + + RenderColumnBorder(g, panel, bounds); + + Rectangle r = bounds; + Rectangle t = GetContentBounds(panel, style, r); + + t = GetAdjustedBounds(style, t); + + if (style.ImageOverlay == ImageOverlay.None || + style.ImageOverlay == ImageOverlay.Bottom) + { + RenderHeaderImage(g, panel, style, bounds, t); + } + + if (fullRender == true) + t = RenderSortAndFilterImage(g, column, style, t); + + if (SuperGrid.DoPreRenderColumnHeaderEvent(g, + this, column, RenderParts.Content, t) == false) + { + RenderText(g, panel, column, style, t); + + SuperGrid.DoPostRenderColumnHeaderEvent(g, + this, column, RenderParts.Content, t); + } + + if (style.ImageOverlay == ImageOverlay.Top) + RenderHeaderImage(g, panel, style, bounds, t); + + r = GetBorderRect(style, r); + + if (SuperGrid.DoPreRenderColumnHeaderEvent(g, + this, column, RenderParts.Border, r) == false) + { + if (r.Width > 0 && r.Height > 0) + style.RenderBorder(g, r); + + SuperGrid.DoPostRenderColumnHeaderEvent(g, + this, column, RenderParts.Border, r); + } + + column.Processed = true; + } + } + + #region GetBorderRect + + private Rectangle GetBorderRect( + ColumnHeaderVisualStyle style, Rectangle r) + { + r.X += style.Margin.Left; + r.Width -= style.Margin.Horizontal; + + r.Y += style.Margin.Top; + r.Height -= style.Margin.Vertical; + + return (r); + } + + #endregion + + #region RenderBackground + + private void RenderBackground(Graphics g, + VisualStyle style, Rectangle r) + { + using (Brush br = style.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + + #endregion + + #region RenderSortAndFilterImage + + private Rectangle RenderSortAndFilterImage( + Graphics g, GridColumn column, ColumnHeaderVisualStyle style, Rectangle t) + { + GridPanel panel = column.Parent as GridPanel; + + if (panel != null) + { + Alignment falign = (_FilterImageAlignment == Alignment.NotSet) + ? Alignment.MiddleLeft : _FilterImageAlignment; + + Alignment salign = (_SortImageAlignment == Alignment.NotSet) + ? Alignment.TopCenter : _SortImageAlignment; + + Rectangle rf = GetFilterImageBounds(panel, column); + + if (rf.IsEmpty == false) + { + Image filterImage = GetColumnFilterImage(column); + + if (filterImage != null) + g.DrawImageUnscaledAndClipped(filterImage, rf); + } + + Rectangle rs = GetSortImageBounds(panel, column, salign, falign, rf); + + if (rs.IsEmpty == false) + { + Image sortImage = GetColumnSortImage(panel, column); + + if (sortImage != null) + g.DrawImageUnscaledAndClipped(sortImage, rs); + } + + if (rf.IsEmpty == false) + t = UpdateContentRect(rf, t, falign, style, column); + + if (rs.IsEmpty == false) + t = UpdateContentRect(rs, t, salign, style, column); + } + + t.X += 2; + t.Width -= 4; + + return (t); + } + + #region GetFilterImageBounds + + private Rectangle GetFilterImageBounds(GridPanel panel, GridColumn column) + { + if (column != null) + { + GridColumn hitColumn = _HitItem as GridColumn; + + if (_FilterImageVisibility == ImageVisibility.Always || + (column == hitColumn) || (string.IsNullOrEmpty(column.FilterExpr) == false)) + { + return (GetScrollBounds(panel, column, column.FilterImageBounds)); + } + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetSortImageBounds + + private Rectangle GetSortImageBounds(GridPanel panel, + GridColumn column, Alignment salign, Alignment falign, Rectangle rf) + { + Rectangle r = GetScrollBounds(panel, column, column.SortImageBounds); + + if (r.IsEmpty == false) + { + if (falign == salign && r.IsEmpty == false) + { + if (salign == Alignment.TopCenter || + salign == Alignment.MiddleCenter || + salign == Alignment.BottomCenter) + { + r.X = rf.X - (r.Width + 1); + } + } + } + + return (r); + } + + #endregion + + #region UpdateContentRect + + private Rectangle UpdateContentRect(Rectangle r, + Rectangle t, Alignment alignment, ColumnHeaderVisualStyle style, GridColumn column) + { + switch (GetStringAlignment(alignment)) + { + case StringAlignment.Near: + int n1 = r.Right - t.Left; + + switch (GetStringAlignment(style.Alignment)) + { + case StringAlignment.Center: + if (n1 + 3 > (t.Width - column.HeaderTextSize.Width) / 2) + { + t.X = r.Right; + t.Width -= n1; + } + break; + + default: + t.X = r.Right; + t.Width -= n1; + break; + } + break; + + case StringAlignment.Far: + int n2 = t.Right - r.Left; + + switch (GetStringAlignment(style.Alignment)) + { + case StringAlignment.Center: + if (n2 + 3 > (t.Width - column.HeaderTextSize.Width) / 2) + t.Width -= n2; + break; + + default: + t.Width -= n2; + break; + } + break; + } + + return (t); + } + + #region GetStringAlignment + + private StringAlignment GetStringAlignment(Alignment alignment) + { + switch (alignment) + { + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + return (StringAlignment.Near); + + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + return (StringAlignment.Center); + + default: + return (StringAlignment.Far); + } + } + + #endregion + + #endregion + + #endregion + + #region RenderText + + private void RenderText(Graphics g, GridPanel panel, + GridColumn column, CellVisualStyle style, Rectangle r) + { + string s = column.GetHeaderText(); + + if (s != null) + { + if (_MouseDownButtons == MouseButtons.Left) + r = AdjustTextHeaderBounds(column, r, panel.ColumnHeaderClickBehavior); + + if (column.HeaderTextMarkup != null) + { + RenderTextMarkup(g, column.HeaderTextMarkup, style, r); + } + else + { + TextDrawing.DrawString(g, s, + style.Font, style.TextColor, r, style.GetTextFormatFlags()); + } + } + } + + #region RenderTextMarkup + + private void RenderTextMarkup(Graphics g, + BodyElement textMarkup, CellVisualStyle style, Rectangle r) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + textMarkup.Arrange(new Rectangle(r.Location, r.Size), d); + + Size size = textMarkup.Bounds.Size; + + switch (style.Alignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + if (r.Height > size.Height) + r.Y += (r.Height - size.Height) / 2; + break; + + default: + if (r.Height > size.Height) + r.Y = r.Bottom - size.Height; + break; + } + + textMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + textMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #endregion + + #region VAlignment + + private int VAlignment(Alignment alignment) + { + switch (alignment) + { + case Alignment.TopLeft: + case Alignment.TopCenter: + case Alignment.TopRight: + return (0); + + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + return (1); + + default: + return (2); + } + } + + #endregion + + #region GetColumnSortImage + + internal Image GetColumnSortImage(GridPanel panel, GridColumn column) + { + SortDirection sortDirection = SortDirection.None; + + if (panel.GroupColumns != null && + panel.GroupColumns.Contains(column) == true) + { + sortDirection = column.GroupDirection; + } + else if (panel.SortLevel != SortLevel.None) + { + sortDirection = column.SortDirection; + + switch (column.SortIndicator) + { + case SortIndicator.None: + sortDirection = SortDirection.None; + break; + + case SortIndicator.Ascending: + sortDirection = SortDirection.Ascending; + break; + + case SortIndicator.Descending: + sortDirection = SortDirection.Descending; + break; + } + } + + switch (sortDirection) + { + case SortDirection.Ascending: + return (GetAscendingSortImage(column)); + + case SortDirection.Descending: + return (GetDescendingSortImage(column)); + } + + return (null); + } + + #endregion + + #region GetFilterImage + + internal Image GetColumnFilterImage(GridColumn column) + { + if (column.IsFilteringEnabled == true) + { + if (_FilterImageVisibility != ImageVisibility.Never) + return (GetFilterImage(column)); + } + + return (null); + } + + #endregion + + #region GetImageBounds + + private Rectangle GetImageBounds( + Image image1, Alignment alignment, ref Rectangle r) + { + Rectangle u = r; + Rectangle t = r; + t.Size = image1.Size; + + switch (alignment) + { + case Alignment.TopLeft: + r.X += t.Width + 2; + r.Width -= (t.Width + 2); + break; + + case Alignment.NotSet: + case Alignment.TopCenter: + t.X += (r.Width - t.Width) / 2; + break; + + case Alignment.TopRight: + t.X = r.Right - t.Width; + r.Width -= (t.Width + 2); + break; + + case Alignment.MiddleLeft: + t.Y += (r.Height - t.Height) / 2; + + r.X += t.Width + 2; + r.Width -= (t.Width + 2); + break; + + case Alignment.MiddleCenter: + t.X += (r.Width - t.Width) / 2; + t.Y += (r.Height - t.Height) / 2; + break; + + case Alignment.MiddleRight: + t.X = r.Right - t.Width; + t.Y += (r.Height - t.Height) / 2; + + r.Width -= (t.Width + 2); + break; + + case Alignment.BottomLeft: + r.X += t.Width + 2; + r.Width -= (t.Width + 2); + t.Y = r.Bottom - t.Height; + break; + + case Alignment.BottomCenter: + t.X += (r.Width - t.Width) / 2; + t.Y = r.Bottom - t.Height; + break; + + case Alignment.BottomRight: + t.X = r.Right - t.Width; + t.Y = r.Bottom - t.Height; + + r.Width -= (t.Width + 2); + break; + } + + t.Intersect(u); + + return (t); + } + + #endregion + + #endregion + + #endregion + + #region AdjustTextHeaderBounds + + private Rectangle AdjustTextHeaderBounds( + object item, Rectangle r, ColumnHeaderClickBehavior cmode) + { + if (_Reordering == false && item == _MouseDownHitItem) + { + if (_MouseDownHitArea == HeaderArea.InMarkup || + (_MouseDownHitArea == HeaderArea.InContent && cmode == ColumnHeaderClickBehavior.SortAndReorder)) + { + r.X++; + + r.Y += 2; + r.Height -= 2; + } + } + + return (r); + } + + #endregion + + #region RenderHeaderImage + + private void RenderHeaderImage(Graphics g, GridPanel panel, + ColumnHeaderVisualStyle style, Rectangle bounds, Rectangle r) + { + if (_ShowHeaderImages == true) + { + object figure = style.GetFigure(panel); + + if (figure != null) + { + Rectangle t = style.GetFigureBounds(panel, r); + + bounds.Inflate(-1, -1); + t.Intersect(bounds); + + style.RenderFigure(g, panel, t); + } + } + } + + #endregion + + #endregion + + #region RenderFrozenColumnMarker + + private void RenderFrozenColumnMarker( + Graphics g, GridPanel panel, GridPanelVisualStyle pstyle) + { + GridColumn col = panel.Columns.GetLastVisibleFrozenColumn(); + + if (col != null) + { + Rectangle bounds = GetBounds(panel, col); + + bounds.Y = Bounds.Y; + bounds.Height = Bounds.Height; + + Rectangle r = col.BoundsRelative; + + r.Y = bounds.Y + Dpi.Width3; + r.Height = bounds.Height - Dpi.Width5; + + if (panel.IsSubPanel == true) + r.X -= HScrollOffset; + + if (r.Height > 0 && r.Width > 0) + { + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) + { + g.DrawLine(pen, r.Right - Dpi.Width3, + r.Top - 1, r.Right - Dpi.Width3, r.Bottom - 1); + } + } + } + } + + #endregion + + #region RenderRowHeader + + private void RenderRowHeader(Graphics g, + GridPanel panel, ColumnHeaderRowVisualStyle style, GridPanelVisualStyle pstyle) + { + Rectangle r = GetRowHeaderBounds(panel); + + if (r.Width > 0 && r.Height > 0) + { + if (SuperGrid.DoPreRenderColumnHeaderEvent(g, + this, null, RenderParts.RowHeader, r) == false) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + using (Brush br = style.RowHeader.Background.GetBrush(r)) + g.FillRectangle(br, r); + + using (Pen pen = new Pen(style.RowHeader.BorderHighlightColor, Dpi.Height1)) + g.DrawLine(pen, r.X, r.Top, r.Right - 1, r.Top); + + using (Pen pen = new Pen(style.RowHeader.BorderHighlightColor, Dpi.Height1)) + g.DrawLine(pen, r.X + 1, r.Top, r.X + 1, r.Bottom - 1); + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X, r.Top - 1, r.Right - 1, r.Top - 1); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + } + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) + g.DrawLine(pen, r.Right - 1, r.Top, r.Right - 1, r.Bottom - 1); + + if (panel.TopLeftHeaderSelectBehavior != TopLeftHeaderSelectBehavior.NoSelection) + { + RenderRowHeaderIndicator(g, panel, style, r); + } + else + { + if (string.IsNullOrEmpty(_RowHeaderText) == false) + RenderRowHeaderText(g, _RowHeaderText, style, r); + } + + SuperGrid.DoPostRenderColumnHeaderEvent(g, + this, null, RenderParts.RowHeader, r); + + g.SmoothingMode = sm; + } + } + } + + #region RenderRowHeaderIndicator + + private void RenderRowHeaderIndicator(Graphics g, + GridPanel panel, ColumnHeaderRowVisualStyle style, Rectangle r) + { + r.Inflate(-Dpi.Width3, -Dpi.Height3); + + if (r.Width > 0 && r.Height > 0) + { + using (GraphicsPath path = new GraphicsPath()) + { + int n = Math.Min(r.Width, r.Height); + + if (n > Dpi.Width10) + n = Dpi.Width10; + + Point[] pts = new Point[3]; + + if (_SelectAllCount != panel.SelectionUpdateCount) + { + r.X--; + r.Y--; + + pts[0] = new Point(r.Right, r.Bottom - n); + pts[1] = new Point(r.Right, r.Bottom); + pts[2] = new Point(r.Right - n, r.Bottom); + } + else + { + pts[0] = new Point(r.X, r.Y); + pts[1] = new Point(r.X + n, r.Y); + pts[2] = new Point(r.X, r.Y + n); + + r.X++; + r.Y++; + } + + path.AddPolygon(pts); + path.CloseFigure(); + + if (style.IndicatorBackground.GradientAngle % 45 == 0) + n /= 2; + + r.Width = n - 1; + r.Height = n - 1; + + if (n > 0) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + + using (Brush br = style.IndicatorBackground.GetBrush(r)) + { + if (br is LinearGradientBrush) + ((LinearGradientBrush)br).WrapMode = WrapMode.Tile; + + g.FillPath(br, path); + } + + using (Pen pen = new Pen(style.IndicatorBorderColor)) + g.DrawPath(pen, path); + } + } + } + } + + #endregion + + #region RenderRowHeaderText + + private void RenderRowHeaderText(Graphics g, + string text, ColumnHeaderRowVisualStyle style, Rectangle r) + { + Font font = style.RowHeader.Font ?? SystemFonts.DefaultFont; + + Size tSize = TextHelper.MeasureText(g, text, font); + + r.Inflate(-Dpi.Width2, -Dpi.Height2); + + eTextFormat tf = ((r.Width <= tSize.Width) + ? eTextFormat.Left + : eTextFormat.HorizontalCenter) | eTextFormat.NoPadding; + + tf |= eTextFormat.WordBreak | eTextFormat.VerticalCenter; + + TextDrawing.DrawString(g, text, + font, style.RowHeader.TextColor, r, tf); + } + + #endregion + + #endregion + + #endregion + + #region ResetProcessStates + + private void ResetProcessStates(GridPanel panel) + { + for (int i = 0; i < panel.Columns.Count; i++) + panel.Columns[i].Processed = false; + } + + #endregion + + #region Mouse support + + #region InternalMouseEnter + + internal override void InternalMouseEnter(EventArgs e) + { + SuperGrid.ToolTipText = ""; + + SuperGrid.DoColumnHeaderMouseEnterEvent(this); + + base.InternalMouseEnter(e); + } + + #endregion + + #region InternalMouseLeave + + internal override void InternalMouseLeave(EventArgs e) + { + if (_LockedColumn == false) + { + ResetColumnState(); + + _HitArea = HeaderArea.NoWhere; + _HitItem = null; + } + + SuperGrid.ToolTipText = ""; + + SuperGrid.DoColumnHeaderMouseLeaveEvent(this); + + base.InternalMouseLeave(e); + } + + #region ResetColumnState + + internal void ResetColumnState() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (_MouseDownHitItem != null) + InvalidateItem(panel, _MouseDownHitItem); + + if (_HitItem != null && (_MouseDownHitItem != _HitItem)) + InvalidateItem(panel, _HitItem); + + if (_HitArea == HeaderArea.InRowHeader) + InvalidateRowHeader(); + + if (_HitArea == HeaderArea.InWhitespace) + InvalidateWhitespace(); + + _MouseDownHitItem = null; + } + + _LockedColumn = false; + } + + internal void ResetColumnStateEx() + { + ResetColumnState(); + + _HitItem = null; + _HitArea = HeaderArea.NoWhere; + } + + #endregion + + #endregion + + #region InternalMouseMove + + internal override void InternalMouseMove(MouseEventArgs e) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (AllowSelection == true) + { + if (_Resizing == false) + { + _LastHitArea = _HitArea; + _LastHitItem = _HitItem; + + _HitArea = GetHitArea(e.Location, ref _HitItem, IsMouseDown); + + if (_Reordering == false) + { + if (_HitItem is GridColumn) + ProcessColumnMouseMove(e, panel); + + else if (_HitItem is ColumnGroupHeader) + ProcessGroupHeaderMouseMove(e, panel); + + else + ProcessRowHeaderMouseMove(panel); + + if (_HitArea != _LastHitArea || _LastHitItem != _HitItem) + { + if (_LastHitItem != null) + InvalidateItem(panel, _LastHitItem); + + if (_HitItem != null) + InvalidateItem(panel, _HitItem); + + if (_HitArea == HeaderArea.InRowHeader || _LastHitArea == HeaderArea.InRowHeader) + InvalidateRowHeader(); + + if (_HitArea == HeaderArea.InWhitespace || _LastHitArea == HeaderArea.InWhitespace) + InvalidateWhitespace(); + + } + } + } + + if (IsMouseDown == true) + { + if (ProcessMouseDownMove(e) == false) + { + if (_MouseDownHitItem != null) + { + SuperGrid.EnableAutoScrolling(AutoScrollEnable.Horizontal, ViewRect); + + StopResize(); + StopReorder(); + } + } + } + } + + SuperGrid.DoColumnHeaderMouseMoveEvent(this, e); + + base.InternalMouseMove(e); + } + } + + #region ProcessColumnMouseMove + + private void ProcessColumnMouseMove(MouseEventArgs e, GridPanel panel) + { + GridColumn hitColumn = (GridColumn) _HitItem; + + switch (_HitArea) + { + case HeaderArea.InContent: + SuperGrid.GridCursor = Cursors.Default; + + if (hitColumn.HeaderTextMarkup != null) + { + hitColumn.HeaderTextMarkup.MouseMove(SuperGrid, e); + + if (hitColumn.HeaderTextMarkup.MouseOverElement != null) + _HitArea = HeaderArea.InMarkup; + } + + if (_ShowToolTips == true) + UpdateToolTip(panel, hitColumn.ToolTip); + break; + + case HeaderArea.InResize: + SuperGrid.GridCursor = Cursors.VSplit; + SuperGrid.ToolTipText = ""; + break; + + case HeaderArea.InFilterMenu: + SuperGrid.GridCursor = Cursors.Hand; + + if (_ShowFilterToolTips == true && hitColumn.IsFilteringEnabled == true) + UpdateToolTip(panel, hitColumn.FilterExpr); + break; + + default: + SuperGrid.GridCursor = Cursors.Default; + SuperGrid.ToolTipText = ""; + break; + } + } + + #endregion + + #region ProcessGroupHeaderMouseMove + + private void ProcessGroupHeaderMouseMove(MouseEventArgs e, GridPanel panel) + { + switch (_HitArea) + { + case HeaderArea.InContent: + SuperGrid.GridCursor = Cursors.Default; + + ColumnGroupHeader cgh = (ColumnGroupHeader)_HitItem; + + if (cgh.HeaderTextMarkup != null) + { + cgh.HeaderTextMarkup.MouseMove(SuperGrid, e); + + if (cgh.HeaderTextMarkup.MouseOverElement != null) + _HitArea = HeaderArea.InMarkup; + } + + if (_ShowToolTips == true) + UpdateToolTip(panel, cgh.ToolTip); + break; + + case HeaderArea.InResize: + SuperGrid.GridCursor = Cursors.VSplit; + SuperGrid.ToolTipText = ""; + break; + + default: + SuperGrid.GridCursor = Cursors.Default; + SuperGrid.ToolTipText = ""; + break; + } + } + + #endregion + + #region ProcessRowHeaderMouseMove + + private void ProcessRowHeaderMouseMove(GridPanel panel) + { + switch (_HitArea) + { + case HeaderArea.InRowHeaderResize: + SuperGrid.GridCursor = Cursors.VSplit; + SuperGrid.ToolTipText = ""; + break; + + case HeaderArea.InRowHeader: + SuperGrid.GridCursor = + (panel.TopLeftHeaderSelectBehavior != TopLeftHeaderSelectBehavior.NoSelection) + ? Cursors.Hand + : Cursors.Default; + + UpdateToolTip(panel, ""); + break; + + default: + SuperGrid.GridCursor = Cursors.Default; + SuperGrid.ToolTipText = ""; + break; + } + } + + #endregion + + #endregion + + #region UpdateToolTip + + private void UpdateToolTip(GridPanel panel, string toolTip) + { + if (_HitArea != _LastHitArea || _LastHitItem != _HitItem) + panel.SetHeaderTooltip(this, _HitItem, _HitArea, toolTip); + } + + #endregion + + #region ProcessMouseDownMove + + private bool ProcessMouseDownMove(MouseEventArgs e) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (_MouseDownHitArea == HeaderArea.InRowHeaderResize) + return (InRowHeaderResize(e.Location, e)); + + if (_MouseDownHitItem is GridColumn) + return (ColumnMouseDownMove(e, panel)); + + if (_MouseDownHitItem is ColumnGroupHeader) + return (GroupHeaderMouseDownMove(e, panel)); + } + + return (false); + } + + #region InRowHeaderResize + + private bool InRowHeaderResize(Point pt, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (_Resizing == false) + { + _Resizing = true; + _ResizeWidth = panel.RowHeaderWidthEx; + + if (panel.ImmediateResize == false) + { + _SeparatorFw = new FloatWindow(); + _SeparatorFw.Opacity = .5; + _SeparatorFw.BackColor = Color.Black; + _SeparatorFw.Owner = SuperGrid.FindForm(); + } + } + else + { + if (panel.ImmediateResize == false) + ContinueRowHeaderResize(panel, pt); + else + ResizeRowHeader(panel, pt.X - MouseDownPoint.X); + } + } + + return (true); + } + + return (false); + } + + #endregion + + #region ColumnMouseDownMove + + private bool ColumnMouseDownMove(MouseEventArgs e, GridPanel panel) + { + GridColumn hitColumn = (GridColumn)_MouseDownHitItem; + Rectangle r = ViewRect; + + if ((_MouseDownHitArea == HeaderArea.InResize) || + (_MouseDownHitArea == HeaderArea.InRowHeaderResize) || + (e.X >= r.X && e.X < r.Right) || + (hitColumn.IsHFrozen == true && panel.IsSubPanel == false)) + { + SuperGrid.DisableAutoScrolling(); + + switch (_MouseDownHitArea) + { + case HeaderArea.InContent: + hitColumn = _MouseDownHitItem as GridColumn; + + if (hitColumn != null) + { + if (_HitArea == HeaderArea.InGroupBox && + hitColumn.GroupBoxEffectsEx != GroupBoxEffects.None) + { + if (ColumnInGroupBox(panel, e, hitColumn) == true) + return (true); + } + } + + if (_HitItem == null) + return (false); + + ColumnInContent(e); + break; + + case HeaderArea.InResize: + ColumnInResize(e.Location, e); + break; + } + + return (true); + } + + return (false); + } + + #region ColumnInGroupBox + + private bool ColumnInGroupBox( + GridPanel panel, MouseEventArgs e, GridColumn hitColumn) + { + if (e.Button == MouseButtons.Left) + { + if (hitColumn != null) + { + if (panel.VisibleColumnCount > 1) + { + if (panel.GroupByRow.DragStart(hitColumn) == true) + { + ResetColumnState(); + StopReorder(); + + _MouseDownHitItem = null; + _HitArea = HeaderArea.NoWhere; + _HitItem = null; + + return (true); + } + } + } + } + + return (false); + } + + #endregion + + #region ColumnInContent + + private void ColumnInContent(MouseEventArgs e) + { + if (IsDesignerHosted == false) + { + if (e.Button == MouseButtons.Left) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (DragStarted(panel, e) == false) + { + if (panel.ColumnDragBehavior == ColumnDragBehavior.ExtendClickBehavior) + { + switch (panel.ColumnHeaderClickBehavior) + { + case ColumnHeaderClickBehavior.SortAndReorder: + ProcessMove(e.Location); + break; + + case ColumnHeaderClickBehavior.Select: + if (_HitItem != _LastHitItem) + ProcessExtendSelection(panel, true); + break; + } + } + } + } + } + } + } + + #region DragStarted + + private bool DragStarted(GridPanel panel, MouseEventArgs e) + { + if (_HitItem is GridColumn) + { + if (_DragSelection == true) + { + if (_DragStarted == false) + { + if (DragDrop.DragStarted(_MouseDownPoint, e.Location) == true) + { + _DragStarted = true; + + if (SuperGrid.DoItemDragEvent((GridColumn)_HitItem, e) == true) + { + _DragSelection = false; + + ExtendSelection(panel, true); + } + } + } + + return (true); + } + } + + return (false); + } + + #endregion + + #region ProcessMove + + private void ProcessMove(Point pt) + { + if (_Reordering == false) + StartReorder(pt); + else + ContinueReorder(pt); + } + + #endregion + + #region ProcessExtendSelection + + private void ProcessExtendSelection(GridPanel panel, bool extend) + { + bool ckey = (panel.MultiSelect == true) ? + ((Control.ModifierKeys & Keys.Control) == Keys.Control) : false; + + if (ckey == true) + ProcessControlExtend(panel); + else + ProcessNonControlExtend(panel, extend); + + _lastSelectedItem = _HitItem; + } + + #region ProcessControlExtend + + private void ProcessControlExtend(GridPanel panel) + { + int startIndex = 0; + int endIndex = 0; + + if (GetSelectionIndicees(panel, + _lastSelectedItem, _HitItem, ref startIndex, ref endIndex, false) == true) + { + int mdStart = 0; + int mdEnd = 0; + + GetSelectionIndicees(panel, + _MouseDownHitItem, _MouseDownHitItem, ref mdStart, ref mdEnd, true); + + panel.NormalizeIndices(true, mdStart, ref startIndex, ref endIndex); + + int[] map = panel.Columns.DisplayIndexMap; + + for (int j = startIndex; j <= endIndex; j++) + { + GridColumn column = panel.Columns[map[j]]; + + if (j < mdStart || j > mdEnd) + column.IsSelected = !column.IsSelected; + } + } + } + + #endregion + + #region ProcessNonControlExtend + + private void ProcessNonControlExtend(GridPanel panel, bool extend) + { + int startIndex = 0; + int endIndex = 0; + + if (GetSelectionIndicees(panel, + panel.SelectionColumnAnchor, _HitItem, ref startIndex, ref endIndex, true) == true) + { + int[] map = panel.Columns.DisplayIndexMap; + + if (panel.OnlyColumnsSelected(startIndex, endIndex) == false) + { + if (extend == false) + panel.ClearAll(); + + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = panel.Columns[index]; + + if (column.Visible == true) + column.IsSelected = (i >= startIndex && i <= endIndex); + } + } + } + } + + #endregion + + #region GetSelectionIndicees + + private bool GetSelectionIndicees(GridPanel panel, + object start, object end, ref int startIndex, ref int endIndex, bool reorder) + { + if (GetSelectionStartIndex(panel, start, ref startIndex) == false) + return (false); + + if (GetSelectionEndIndex(panel, end, ref endIndex) == false) + return (false); + + if (startIndex > endIndex) + { + if (start is ColumnGroupHeader) + startIndex = ((ColumnGroupHeader)start).EndDisplayIndex; + + if (end is ColumnGroupHeader) + endIndex = ((ColumnGroupHeader)end).StartDisplayIndex; + + if (reorder == true) + { + int tempIndex = startIndex; + startIndex = endIndex; + endIndex = tempIndex; + } + } + + return (true); + } + + #endregion + + #region GetSelectionStartIndex + + private bool GetSelectionStartIndex(GridPanel panel, object item, ref int startIndex) + { + startIndex = -1; + + if (item is ColumnGroupHeader) + startIndex = ((ColumnGroupHeader) item).StartDisplayIndex; + + else if (item is GridColumn) + startIndex = panel.Columns.GetDisplayIndex(((GridColumn) item).ColumnIndex); + + return (startIndex >= 0); + } + + #endregion + + #region GetSelectionEndIndex + + private bool GetSelectionEndIndex(GridPanel panel, object item, ref int endIndex) + { + endIndex = -1; + + if (item is ColumnGroupHeader) + endIndex = ((ColumnGroupHeader)item).EndDisplayIndex; + + else if (item is GridColumn) + endIndex = panel.Columns.GetDisplayIndex(((GridColumn) item).ColumnIndex); + + return (endIndex >= 0); + } + + #endregion + + #endregion + + #endregion + + #region ColumnInResize + + private void ColumnInResize(Point pt, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + if (_Resizing == false) + { + StartResize(); + } + else + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (panel.ImmediateResize == false) + ContinueResize(panel, pt); + else + ResizeColumn(panel, pt.X - MouseDownPoint.X); + } + } + } + } + + #endregion + + #endregion + + #region GroupHeaderMouseDownMove + + private bool GroupHeaderMouseDownMove(MouseEventArgs e, GridPanel panel) + { + ColumnGroupHeader cgh = (ColumnGroupHeader)_MouseDownHitItem; + + Rectangle r = ViewRect; + + if ((_MouseDownHitArea == HeaderArea.InResize) || + (_MouseDownHitArea == HeaderArea.InRowHeaderResize) || (e.X >= r.X && e.X < r.Right) || + (panel.IsSubPanel == false && IsGroupHeaderHFrozen(panel, cgh) == true)) + { + SuperGrid.DisableAutoScrolling(); + + switch (_MouseDownHitArea) + { + case HeaderArea.InContent: + GroupHeaderInContent(e); + break; + } + + return (true); + } + + return (false); + } + + #region GroupHeaderInContent + + private void GroupHeaderInContent(MouseEventArgs e) + { + if (IsDesignerHosted == false) + { + if (e.Button == MouseButtons.Left) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (DragStarted(panel, e) == false) + { + if (panel.ColumnDragBehavior == ColumnDragBehavior.ExtendClickBehavior) + { + switch (panel.ColumnGroupHeaderClickBehavior) + { + case ColumnHeaderClickBehavior.SortAndReorder: + ProcessMove(e.Location); + break; + + case ColumnHeaderClickBehavior.Select: + if (_HitItem != _LastHitItem) + ProcessExtendSelection(panel, true); + break; + } + } + } + } + } + } + } + + #endregion + + #endregion + + #endregion + + #region InternalMouseDown + + internal override void InternalMouseDown(MouseEventArgs e) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (EndCurrentOp() == true) + { + _MouseDownPoint = e.Location; + _MouseDownButtons = e.Button; + + _MouseDownHitItem = _HitItem; + _MouseDownHitArea = _HitArea; + + _DragSelection = false; + _DragStarted = false; + + if (_HitItem is GridColumn) + ColumnMouseDown(e, panel); + + else if (_HitItem is ColumnGroupHeader) + GroupHeaderMouseDown(e, panel); + + else + RowHeaderMouseDown(e, panel); + + _lastSelectedItem = _HitItem; + } + + SuperGrid.DoColumnHeaderMouseDownEvent(this, e); + + base.InternalMouseDown(e); + } + } + + #region EndCurrentOp + + private bool EndCurrentOp() + { + GridCell ecell = SuperGrid.EditorCell; + + if (ecell != null) + { + if (ecell.EndEdit() == false) + { + _MouseDownHitArea = HeaderArea.NoWhere; + + return (false); + } + } + + if (_Reordering == true || _Resizing == true) + { + StopResize(); + StopReorder(); + + InvalidateRender(); + } + + return (true); + } + + #endregion + + #region ColumnMouseDown + + private void ColumnMouseDown(MouseEventArgs e, GridPanel panel) + { + GridColumn hitColumn = (GridColumn)_HitItem; + + if (_HitArea == HeaderArea.InContent) + { + Capture = true; + + ColumnInContentMouseDown(e, panel, hitColumn); + } + else if (_HitArea == HeaderArea.InMarkup) + { + InvalidateHeader(panel, hitColumn); + } + else + { + if (e.Button == MouseButtons.Left) + { + Capture = true; + + switch (_HitArea) + { + case HeaderArea.InResize: + ColumnInResizeMouseDown(e, panel); + break; + + case HeaderArea.InFilterMenu: + ColumnInFilterMouseDown(panel, hitColumn); + break; + } + } + } + } + + #region ColumnInContentMouseDown + + private void ColumnInContentMouseDown( + MouseEventArgs e, GridPanel panel, GridColumn hitColumn) + { + _MouseDownDelta = e.X - hitColumn.BoundsRelative.X; + + if (panel.IsSubPanel == true || hitColumn.IsHFrozen == false) + _MouseDownDelta += HScrollOffset; + + if (hitColumn.AllowSelection == true) + { + _LastHitItem = null; + _Reordering = false; + + if (panel.ColumnHeaderClickBehavior == ColumnHeaderClickBehavior.Select) + { + if (hitColumn.IsSelected == false || + ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) != Keys.None)) + { + ExtendSelection(panel, true); + } + else + { + _DragSelection = true; + } + } + else + { + InvalidateItem(panel, _MouseDownHitItem); + } + } + } + + #region ExtendSelection + + private void ExtendSelection(GridPanel panel, bool capture) + { + if (capture == true) + Capture = true; + + if (panel.SelectionColumnAnchor == null || + (Control.ModifierKeys & Keys.Shift) != Keys.Shift) + { + panel.SelectionColumnAnchor = _MouseDownHitItem; + } + + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + { + int startIndex = 0; + int endIndex = 0; + + if (GetSelectionIndicees(panel, _MouseDownHitItem, + _MouseDownHitItem, ref startIndex, ref endIndex, true) == true) + { + int[] map = panel.Columns.DisplayIndexMap; + + for (int i = startIndex; i <= endIndex; i++) + { + GridColumn column = panel.Columns[map[i]]; + + column.IsSelected = !column.IsSelected; + } + } + } + else + { + ProcessNonControlExtend(panel, false); + } + } + + #endregion + + #endregion + + #region ColumnInResizeMouseDown + + private void ColumnInResizeMouseDown(MouseEventArgs e, GridPanel panel) + { + GridColumn hitColumn = _HitItem as GridColumn; + + if (hitColumn != null) + { + Capture = true; + + _MouseDownDelta = e.X - hitColumn.BoundsRelative.X; + + if (panel.IsSubPanel == true || hitColumn.IsHFrozen == false) + _MouseDownDelta += HScrollOffset; + + _Resizing = false; + _LastHitItem = null; + } + } + + #endregion + + #region ColumnInFilterMouseDown + + private void ColumnInFilterMouseDown(GridPanel panel, GridColumn column) + { + ActivateFilterPopup(panel, column); + } + + #endregion + + #endregion + + #region GroupHeaderMouseDown + + private void GroupHeaderMouseDown(MouseEventArgs e, GridPanel panel) + { + ColumnGroupHeader cgh = (ColumnGroupHeader)_HitItem; + + if (_HitArea == HeaderArea.InContent) + { + Capture = true; + + GroupHeaderInContentMouseDown(e, panel, cgh); + } + else if (_HitArea == HeaderArea.InMarkup) + { + InvalidateHeader(panel, cgh); + } + else + { + if (e.Button == MouseButtons.Left) + { + Capture = true; + + switch (_HitArea) + { + case HeaderArea.InResize: + ColumnInResizeMouseDown(e, panel); + break; + } + } + } + } + + #region GroupHeaderInContentMouseDown + + private void GroupHeaderInContentMouseDown( + MouseEventArgs e, GridPanel panel, ColumnGroupHeader cgh) + { + _MouseDownDelta = e.X - cgh.BoundsRelative.X; + + if (panel.IsSubPanel == true || IsGroupHeaderHFrozen(panel, cgh) == false) + _MouseDownDelta += HScrollOffset; + + if (cgh.AllowSelection == true) + { + _LastHitItem = null; + _Reordering = false; + + if (panel.ColumnGroupHeaderClickBehavior == ColumnHeaderClickBehavior.Select) + { + if (IsGroupHeaderSelected(cgh) == false || + ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) != Keys.None)) + { + ExtendSelection(panel, true); + } + else + { + _DragSelection = true; + } + } + else + { + InvalidateItem(panel, _MouseDownHitItem); + } + } + } + + #endregion + + #endregion + + #region RowHeaderMouseDown + + private void RowHeaderMouseDown(MouseEventArgs e, GridPanel panel) + { + if (e.Button == MouseButtons.Left) + { + Capture = true; + + switch (_HitArea) + { + case HeaderArea.InRowHeader: + InRowHeaderMouseDown(panel); + break; + + case HeaderArea.InRowHeaderResize: + InRowHeaderResizeMouseDown(); + break; + } + } + } + + #region InRowHeaderMouseDown + + private void InRowHeaderMouseDown(GridPanel panel) + { + if (panel.TopLeftHeaderSelectBehavior != TopLeftHeaderSelectBehavior.NoSelection) + { + bool select = (_SelectAllCount != panel.SelectionUpdateCount); + + if (select == true) + { + if (panel.MultiSelect == true) + { + panel.SelectAll(); + } + else if (panel.ActiveRow != null) + { + panel.ClearAll(); + panel.ActiveRow.IsSelected = true; + } + } + else + { + panel.ClearAll(); + } + } + } + + #endregion + + #region InRowHeaderResizeMouseDown + + private void InRowHeaderResizeMouseDown() + { + Capture = true; + + _Resizing = false; + } + + #endregion + + #endregion + + #endregion + + #region InternalMouseUp + + internal override void InternalMouseUp(MouseEventArgs e) + { + SuperGrid.DisableAutoScrolling(); + + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (_Reordering == true) + { + StopReorder(); + + if (_SeparatorColumn != null && _HitItem != _MouseDownHitItem) + ReorderItem(panel); + } + else if (_Resizing == true && _ResizeColumn != null) + { + StopResize(); + + if (panel.ImmediateResize == false) + ResizeColumn(panel, e.Location.X - MouseDownPoint.X); + } + else + { + if (_HitItem is GridColumn) + ColumnMouseUp(e, panel); + + else if (_HitItem is ColumnGroupHeader) + GroupHeaderMouseUp(e, panel); + + else + RowHeaderMouseUp(e, panel); + } + } + + _MouseDownHitItem = null; + + SuperGrid.DoColumnHeaderMouseUpEvent(this, e); + + base.InternalMouseUp(e); + } + + #region ColumnMouseUp + + private void ColumnMouseUp(MouseEventArgs e, GridPanel panel) + { + GridColumn hitColumn = (GridColumn)_HitItem; + + switch (_MouseDownHitArea) + { + case HeaderArea.InContent: + case HeaderArea.InMarkup: + if (hitColumn != null && hitColumn == _MouseDownHitItem) + { + if (SuperGrid.DoColumnHeaderClickEvent(panel, hitColumn, e) == false) + { + if (e.Button == MouseButtons.Left) + { + DoHeaderMouseUp(panel, panel.ColumnHeaderClickBehavior, + hitColumn.HeaderTextMarkup, hitColumn); + + InvalidateHeader(panel, hitColumn); + } + } + } + break; + } + } + + #endregion + + #region GroupHeaderMouseUp + + private void GroupHeaderMouseUp(MouseEventArgs e, GridPanel panel) + { + ColumnGroupHeader cgh = (ColumnGroupHeader)_HitItem; + + switch (_MouseDownHitArea) + { + case HeaderArea.InContent: + case HeaderArea.InMarkup: + if (_HitItem == _MouseDownHitItem) + { + if (SuperGrid.DoColumnGroupHeaderClickEvent(panel, this, cgh, e) == false) + { + if (e.Button == MouseButtons.Left) + { + DoHeaderMouseUp(panel, panel.ColumnGroupHeaderClickBehavior, + cgh.HeaderTextMarkup, + panel.Columns.ColumnAtDisplayIndex(cgh.StartDisplayIndex)); + + InvalidateHeader(panel, cgh); + } + } + } + break; + } + } + + #endregion + + #region DoHeaderMouseUp + + private void DoHeaderMouseUp(GridPanel panel, + ColumnHeaderClickBehavior cmode, BodyElement bodyElement, GridColumn hitColumn) + { + if (panel.FlushActiveRow() == true) + { + if (DoMarkupClick(bodyElement) == false) + { + if (_DragSelection == true) + ExtendSelection(panel, false); + + if (cmode == ColumnHeaderClickBehavior.SortAndReorder && panel.IsSortable == true) + SortColumn(panel, hitColumn); + } + } + } + + #region DoMarkupClick + + private bool DoMarkupClick(BodyElement bodyElement) + { + if (bodyElement != null) + { + if (bodyElement.MouseOverElement != null) + { + bodyElement.Click(SuperGrid); + + SuperGrid.Cursor = Cursors.Default; + + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region RowHeaderMouseUp + + private void RowHeaderMouseUp(MouseEventArgs e, GridPanel panel) + { + switch (_MouseDownHitArea) + { + case HeaderArea.InRowHeader: + SuperGrid.DoColumnRowHeaderClickEvent(panel); + break; + + case HeaderArea.InRowHeaderResize: + if (_Resizing == true) + { + StopResize(); + + if (panel.ImmediateResize == false) + ResizeRowHeader(panel, e.Location.X - MouseDownPoint.X); + } + break; + } + } + + #endregion + + #endregion + + #region InternalMouseDoubleClick + + internal override void InternalMouseDoubleClick(MouseEventArgs e) + { + GridColumn hitColumn = _HitItem as GridColumn; + + if (hitColumn != null) + { + if (SuperGrid.DoColumnHeaderDoubleClickEvent(hitColumn, e) == false) + { + switch (_HitArea) + { + case HeaderArea.InResize: + if (hitColumn.GetAutoSizeMode() == ColumnAutoSizeMode.None) + { + RowScope scope = (GridPanel.VirtualMode == true || hitColumn.GridPanel.Rows.Count > 1000) + ? RowScope.OnScreenRows + : RowScope.AllRows; + + hitColumn.Width = Dpi.DescaleWidth(hitColumn.GetMaximumCellSize(scope, true).Width); + } + break; + } + } + } + else + { + if (_HitArea == HeaderArea.InRowHeader) + SuperGrid.DoColumnRowHeaderDoubleClickEvent(GridPanel); + } + + base.InternalMouseDoubleClick(e); + } + + #endregion + + #endregion + + #region Column Reorder + + #region StartReorder + + private void StartReorder(Point pt) + { + if (_MouseDownHitItem != null && Math.Abs(MouseDownPoint.X - pt.X) > 5) + { + Capture = true; + + _Reordering = true; + _SeparatorColumn = null; + + _HeaderFw = new FloatWindow(); + _HeaderFw.Opacity = .3; + _HeaderFw.Owner = SuperGrid.FindForm(); + _HeaderFw.Paint += ColumnHeaderFwPaint; + + _SeparatorFw = new FloatWindow(); + _SeparatorFw.Opacity = .5; + _SeparatorFw.BackColor = Color.Black; + _SeparatorFw.Owner = SuperGrid.FindForm(); + } + } + + #endregion + + #region StopReorder + + private void StopReorder() + { + _Reordering = false; + + if (_HeaderFw != null) + { + _HeaderFw.Close(); + _HeaderFw.Paint -= ColumnHeaderFwPaint; + _HeaderFw.Dispose(); + + _HeaderFw = null; + } + + if (_SeparatorFw != null) + { + HideSeparator(); + + _SeparatorFw.Close(); + _SeparatorFw.Dispose(); + + _SeparatorFw = null; + } + + if (_MouseDownHitItem != null) + InvalidateItem(GridPanel, _MouseDownHitItem); + + if (_HitItem != null) + InvalidateItem(GridPanel, _HitItem); + } + + #endregion + + #region ContinueReorder + + private void ContinueReorder(Point pt) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (_HitItem != null && _MouseDownHitItem != null) + { + ReorderHeader(pt); + + if (ValidReorder() == true) + { + ReorderSeparator(pt); + } + else if (_SeparatorFw != null) + { + HideSeparator(); + + _SeparatorColumn = null; + } + } + } + } + + #region ValidReorder + + private bool ValidReorder() + { + if (IsItemHFrozen(_HitItem) == IsItemHFrozen(_MouseDownHitItem)) + { + object o1 = GetParent(_HitItem); + object o2 = GetParent(_MouseDownHitItem); + + if (o1 is GridColumnHeader) + o1 = null; + + if (o2 is GridColumnHeader) + o2 = null; + + return (o1 == o2); + } + + return (false); + } + + #endregion + + #region ReorderHeader + + private void ReorderHeader(Point pt) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + Rectangle r = GetReorderWindowBounds(panel, pt); + + if (r.Width <= 0 || r.Height <= 0) + { + _HeaderFw.Hide(); + } + else + { + r.Location = SuperGrid.PointToScreen(r.Location); + + Size size = _HeaderFw.Size; + + _HeaderFw.Bounds = r; + + if (_HeaderFw.Visible == false) + _HeaderFw.Show(); + + else if (r.Size.Equals(size) == false) + _HeaderFw.Refresh(); + } + } + } + + #region GetReorderWindowBounds + + private Rectangle GetReorderWindowBounds(GridPanel panel, Point pt) + { + Rectangle r = GetReorderBounds(panel, _MouseDownHitItem); + Rectangle t = SViewRect; + + r.X = (pt.X - _MouseDownDelta); + + int x = Math.Max(r.X, t.X); + + if (r.X < x) + { + _OrderTextOffset = r.X - x; + + r.X = x; + r.Width += _OrderTextOffset; + } + else + { + _OrderTextOffset = 0; + } + + int n = r.Right; + + x = Math.Min(n, t.Right); + + if (r.Right > x) + r.Width -= (r.Right - x); + + if (r.Bottom > t.Bottom) + r.Height -= (r.Bottom - t.Bottom); + + return (r); + } + + #endregion + + #endregion + + #region ReorderSeparator + + private void ReorderSeparator(Point pt) + { + GridPanel panel = GridPanel; + Rectangle r = GetReorderBounds(panel, _HitItem); + + Rectangle t = SViewRect; + + if (r.Right > t.Right) + r.Width = t.Right - r.X; + + bool isRight = (pt.X > r.X + r.Width / 2); + GridColumn column = GetSeparatorColumn(panel, isRight); + + if (_SeparatorColumn != column || _SeparatorIsRight != isRight) + { + _SeparatorColumn = column; + _SeparatorIsRight = isRight; + + if (column != null) + { + r = GetReorderSeparatorBounds(panel, r, isRight); + r.Location = SuperGrid.PointToScreen(r.Location); + + _SeparatorFw.Show(); + + _SeparatorFw.Bounds = r; + _SeparatorFw.Size = r.Size; + } + else + { + HideSeparator(); + } + } + else + { + if (_SeparatorColumn!= null) + _SeparatorFw.Show(); + } + } + + #region HideSeparator + + private void HideSeparator() + { + if (_SeparatorFw != null) + _SeparatorFw.Hide(); + } + + #endregion + + #region GetSeparatorColumn + + private GridColumn GetSeparatorColumn(GridPanel panel, bool isRight) + { + if (_HitItem is GridColumn) + return ((GridColumn) _HitItem); + + ColumnGroupHeader cgh = (ColumnGroupHeader)_HitItem; + + if (cgh != null) + { + GridColumnCollection columns = panel.Columns; + + int index = (isRight == true) + ? cgh.EndDisplayIndex : cgh.StartDisplayIndex; + + return (columns[columns.DisplayIndexMap[index]]); + } + + return (null); + } + + #endregion + + #region GetReorderSeparatorBounds + + private Rectangle GetReorderSeparatorBounds( + GridPanel panel, Rectangle r, bool isRight) + { + if (isRight == true) + r.X = r.Right - (SeparatorWidth >> 1); + else + r.X -= (SeparatorWidth >> 1); + + r.Width = SeparatorWidth; + + if (r.X >= panel.BoundsRelative.Right - 2) + r.X = panel.BoundsRelative.Right - 3; + + Rectangle t = SViewRect; + + if (r.Bottom > t.Bottom) + r.Height -= (r.Bottom - t.Bottom); + + if (r.X < t.X) + r.X = t.X; + + else if (r.Right > t.Right) + r.X = t.Right - SeparatorWidth; + + return (r); + } + + #endregion + + #endregion + + #endregion + + #region GetReorderBounds + + private Rectangle GetReorderBounds(GridPanel panel, object item) + { + Rectangle r = BoundsRelative; + + if (item is GridColumn) + { + GridColumn column = (GridColumn)item; + int index = panel.Columns.GetDisplayIndex(column); + + ColumnGroupHeader cgh = GetParentHeader(index); + + if (cgh != null) + r.Y = r.Bottom - (cgh.Size.Height - cgh.BoundsRelative.Height); + + r.Height = (panel.BoundsRelative.Height - (r.Y - panel.BoundsRelative.Y)); + + r.X = column.BoundsRelative.X; + r.Width = column.BoundsRelative.Width; + + if (panel.IsSubPanel == true || column.IsHFrozen == false) + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + return (r); + } + + if (item is ColumnGroupHeader) + { + ColumnGroupHeader cgh = (ColumnGroupHeader)item; + + r.Y = r.Bottom - cgh.Size.Height; + r.Height = (panel.BoundsRelative.Height - (r.Y - panel.BoundsRelative.Y)); + + r.X = cgh.BoundsRelative.X; + r.Width = cgh.BoundsRelative.Width; + + if (panel.IsSubPanel == true || IsGroupHeaderHFrozen(panel, cgh) == false) + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + } + + return (r); + } + + #endregion + + #region ReorderItem + + private void ReorderItem(GridPanel panel) + { + if (_MouseDownHitItem is GridColumn) + ReorderColumn(panel); + + if (_MouseDownHitItem is ColumnGroupHeader) + ReorderGroupHeader(panel); + } + + #region ReorderColumn + + private void ReorderColumn(GridPanel panel) + { + GridColumn hitColumn = (GridColumn)_MouseDownHitItem; + GridColumnCollection columns = _Columns; + + int[] map = columns.DisplayIndexMap; + + int curIndex = columns.GetDisplayIndex(hitColumn); + int sepIndex = columns.GetDisplayIndex(_SeparatorColumn); + + if (curIndex > sepIndex && _SeparatorIsRight == true && sepIndex < map.Length - 1) + sepIndex++; + + else if (curIndex < sepIndex && _SeparatorIsRight == false && sepIndex > 0) + sepIndex--; + + if (sepIndex != curIndex) + { + ColumnGroupHeader parent = GetParent(hitColumn) as ColumnGroupHeader; + + int[] dmap = new int[map.Length]; + + if (sepIndex < curIndex) + { + for (int i = curIndex; i > sepIndex; i--) + { + map[i] = map[i - 1]; + dmap[i - 1] = 1; + } + } + else + { + for (int i = curIndex; i < sepIndex; i++) + { + map[i] = map[i + 1]; + dmap[i + 1] = -1; + } + } + + map[sepIndex] = hitColumn.ColumnIndex; + dmap[curIndex] = sepIndex - curIndex; + + for (int i = 0; i < map.Length; i++) + columns[map[i]].DisplayIndex = i; + + UpdateGroupHeaderRanges(parent != null ? parent.GroupHeaders : GroupHeaders, dmap); + + SuperGrid.UpdateStyleCount(); + SuperGrid.PrimaryGrid.InvalidateRender(); + + SuperGrid.DoColumnMovedEvent(panel, hitColumn); + } + } + + #endregion + + #region ReorderGroupHeader + + private void ReorderGroupHeader(GridPanel panel) + { + ColumnGroupHeader cgh = (ColumnGroupHeader)_MouseDownHitItem; + GridColumnCollection columns = _Columns; + + int[] map = columns.DisplayIndexMap; + + int curStartIndex = cgh.StartDisplayIndex; + int curEndIndex = cgh.EndDisplayIndex; + + int sepIndex = columns.GetDisplayIndex(_SeparatorColumn); + + if (curStartIndex > sepIndex && _SeparatorIsRight == true && sepIndex < map.Length - 1) + sepIndex++; + + else if (curEndIndex < sepIndex && _SeparatorIsRight == false && sepIndex > 0) + sepIndex--; + + if (sepIndex != curStartIndex && sepIndex != curEndIndex) + { + ColumnGroupHeader parent = GetParent(cgh) as ColumnGroupHeader; + + int n = curEndIndex - curStartIndex + 1; + + int[] temp = new int[n]; + int[] dmap = new int[map.Length]; + + for (int i = 0; i < n; i++) + temp[i] = map[curStartIndex + i]; + + for (int i = 0; i < dmap.Length; i++) + dmap[i] = 0; + + if (sepIndex < curStartIndex) + { + for (int i = curStartIndex - 1; i >= sepIndex; i--) + { + map[i + n] = map[i]; + dmap[i] = n; + } + + for (int i = 0; i < n; i++) + map[sepIndex + i] = temp[i]; + + for (int i = curStartIndex; i <= curEndIndex; i++) + dmap[i] = sepIndex - curStartIndex; + } + else + { + for (int i = curEndIndex + 1; i <= sepIndex; i++) + { + map[i - n] = map[i]; + dmap[i] = -n; + } + + for (int i = 0; i < n; i++) + map[sepIndex - n + i + 1] = temp[i]; + + for (int i = curStartIndex; i <= curEndIndex; i++) + dmap[i] = sepIndex - curEndIndex; + } + + for (int i = 0; i < map.Length; i++) + columns[map[i]].DisplayIndex = i; + + UpdateGroupHeaderRanges(parent != null ? parent.GroupHeaders : cgh.Collection, dmap); + + SuperGrid.UpdateStyleCount(); + SuperGrid.PrimaryGrid.InvalidateRender(); + + for (int i = curStartIndex; i <= curEndIndex; i++) + SuperGrid.DoColumnMovedEvent(panel, columns[map[i]]); + } + } + + #endregion + + #region UpdateGroupHeaderRanges + + private void UpdateGroupHeaderRanges(ColumnGroupHeaderCollection csc, int[] dmap) + { + foreach (ColumnGroupHeader cgh in csc) + { + if (cgh.Visible == true) + { + UpdateGroupHeaderRanges(cgh.GroupHeaders, dmap); + + cgh.StartDisplayIndex += dmap[cgh.StartDisplayIndex]; + cgh.EndDisplayIndex += dmap[cgh.EndDisplayIndex]; + } + } + } + + #endregion + + #endregion + + #region ColumnHeaderFwPaint + + void ColumnHeaderFwPaint(object sender, PaintEventArgs e) + { + GridPanel panel = GridPanel; + + if (_MouseDownHitItem is GridColumn) + { + GridColumn mouseDownHitColumn = (GridColumn)_MouseDownHitItem; + Rectangle r = mouseDownHitColumn.BoundsRelative; + + r.Y = 0; + r.X = _OrderTextOffset; + r.Height = e.ClipRectangle.Height; + + RenderColumnHeader(e.Graphics, panel, mouseDownHitColumn, r, false); + + r.Width--; + r.Height--; + e.Graphics.DrawRectangle(Pens.DimGray, r); + } + else if (_MouseDownHitItem is ColumnGroupHeader) + { + ColumnGroupHeader cgh = (ColumnGroupHeader)_MouseDownHitItem; + Rectangle r = cgh.BoundsRelative; + + r.Y = 0; + r.X = _OrderTextOffset; + r.Height = e.ClipRectangle.Height; + + RenderGroupHeader(e.Graphics, panel, cgh, r); + + r.Width--; + r.Height--; + e.Graphics.DrawRectangle(Pens.DimGray, r); + } + } + + #endregion + + #region SortColumn + + internal void SortColumn(GridPanel panel, GridColumn column) + { + if (panel.IsSortable == true) + { + if (column.IsGroupColumn == true) + { + column.GroupDirection = + ToggleSortDirection(panel, column.GroupDirection, column.SortCycle); + + SuperGrid.DoSortChangedEvent(panel); + } + else if (column.ColumnSortMode != ColumnSortMode.None) + { + SortDirection sortDirection = + ToggleSortDirection(panel, column.SortDirection, column.SortCycle); + + if (column.ColumnSortMode == ColumnSortMode.Multiple && + ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)) + { + panel.AddSort(column, sortDirection); + } + else + { + if (panel.SortColumns.Count > 1) + sortDirection = SortDirection.Ascending; + + panel.SetSort(column, sortDirection); + } + + SuperGrid.DoSortChangedEvent(panel); + } + else + { + InvalidateHeader(panel, column); + } + } + else + { + InvalidateHeader(panel, column); + } + } + + #region ToggleSortDirection + + private SortDirection ToggleSortDirection( + GridPanel panel, SortDirection dir, SortCycle sortCycle) + { + if (dir == SortDirection.Ascending) + return (SortDirection.Descending); + + if (dir == SortDirection.None) + return (SortDirection.Ascending); + + if (sortCycle == SortCycle.NotSet) + { + sortCycle = panel.SortCycle; + + if (sortCycle == SortCycle.NotSet) + sortCycle = SortCycle.AscDesc; + } + + return (sortCycle == SortCycle.AscDescNone ? SortDirection.None : SortDirection.Ascending); + } + + #endregion + + #endregion + + #endregion + + #region Column Resize + + #region StartResize + + private void StartResize() + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + _ResizeColumn = _MouseDownHitItem as GridColumn; + + if (_ResizeColumn != null) + { + _Resizing = true; + _ResizeWidth = _ResizeColumn.Size.Width; + + _HitItem = _ResizeColumn; + _HitArea = HeaderArea.InResize; + + if (panel.ImmediateResize == false) + { + _SeparatorFw = new FloatWindow(); + _SeparatorFw.Opacity = .5; + _SeparatorFw.BackColor = Color.Black; + _SeparatorFw.Owner = SuperGrid.FindForm(); + } + } + } + } + + #endregion + + #region StopResize + + private void StopResize() + { + _Resizing = false; + + if (_SeparatorFw != null) + { + HideSeparator(); + + _SeparatorFw.Close(); + _SeparatorFw.Dispose(); + + _SeparatorFw = null; + } + } + + #endregion + + #region ContinueResize + + private void ContinueResize(GridPanel panel, Point pt) + { + Rectangle r = panel.BoundsRelative; + r.Y = BoundsRelative.Y; + + if (panel.IsSubPanel == true) + r.Y -= VScrollOffset; + + r.X -= HScrollOffset; + + if (pt.X > r.X) + { + Rectangle t = _ResizeColumn.BoundsRelative; + t.X -= HScrollOffset; + + int width = pt.X - t.X; + + int n = Dpi.Width(_ResizeColumn.MinimumWidth); + + if (width < n) + pt.X = t.X + n; + + if (pt.X >= SuperGrid.PrimaryGrid.BoundsRelative.Right - Dpi.Width2) + { + HideSeparator(); + } + else + { + if (pt.X == panel.BoundsRelative.Right - 1) + pt.X -= 1; + + r.X = pt.X; + + r.Width = Dpi.Width(SeparatorWidth); + r.Height -= (BoundsRelative.Y - panel.BoundsRelative.Y); + + t = SViewRect; + + if (r.Bottom > t.Bottom) + r.Height -= (r.Bottom - t.Bottom); + + r.Location = SuperGrid.PointToScreen(r.Location); + + _SeparatorFw.Show(); + + _SeparatorFw.Bounds = r; + _SeparatorFw.Size = r.Size; + } + } + } + + #endregion + + #region ResizeColumn + + #region ResizeColumn + + private void ResizeColumn(GridPanel panel, int width) + { + ColumnAutoSizeMode autoSizeMode = _ResizeColumn.GetAutoSizeMode(); + + if (autoSizeMode == ColumnAutoSizeMode.None) + ResizeNoneColumn(panel, width); + + else if (autoSizeMode == ColumnAutoSizeMode.Fill) + ResizeFillColumn(panel, width); + + } + + #endregion + + #region ResizeNoneColumn + + private void ResizeNoneColumn(GridPanel panel, int width) + { + int newWidth = _ResizeWidth + width; + + int n = Dpi.Width(_ResizeColumn.MinimumWidth); + + if (newWidth < n) + newWidth = n; + + if (_ResizeColumn.ResizeMode == ColumnResizeMode.MoveFollowingElements) + { + _ResizeColumn.Width = Dpi.DescaleWidth(newWidth); + } + else if (_ResizeColumn.ResizeMode == ColumnResizeMode.MaintainTotalWidth) + { + GridColumn ncolumn = panel.Columns.GetNextVisibleColumn(_ResizeColumn); + + if ((ncolumn == null) || (ncolumn.GetAutoSizeMode() != ColumnAutoSizeMode.None)) + { + _ResizeColumn.Width = Dpi.DescaleWidth(newWidth); + } + else + { + int twidth = _ResizeColumn.Size.Width + ncolumn.Size.Width; + int nwidth = twidth - newWidth; + + int n2 = Dpi.Width(ncolumn.MinimumWidth); + + if (nwidth < n2) + nwidth = n2; + + newWidth = twidth - nwidth; + + _ResizeColumn.Width = Dpi.DescaleWidth(newWidth); + ncolumn.Width = Dpi.DescaleWidth(nwidth); + } + } + } + + #endregion + + #region ResizeFillColumn + + private void ResizeFillColumn(GridPanel panel, int width) + { + int fillWeight = 0; + int fillWidth = 0; + + GridColumnCollection columns = _Columns; + + int colDisplayIndex = columns.GetDisplayIndex(_ResizeColumn); + + int[] map = columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + if (column.GetAutoSizeMode() == ColumnAutoSizeMode.Fill) + { + fillWidth += column.Size.Width; + + if (i != colDisplayIndex) + fillWeight += column.FillWeight; + } + } + } + + if (fillWidth > 0 && fillWeight > 0) + { + int nw = _ResizeWidth + width; + int newFillWidth = fillWidth - nw; + + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + if (column.GetAutoSizeMode() == ColumnAutoSizeMode.Fill) + { + float colWidth; + + if (i != colDisplayIndex) + colWidth = (int)(newFillWidth * (float)column.FillWeight / fillWeight); + else + colWidth = nw; + + int n = Dpi.Width(column.MinimumWidth); + + if (colWidth < n) + colWidth = n; + + column.FillWeight = (int)((colWidth * 1000) / fillWidth); + } + } + } + + panel.SuperGrid.Invalidate(); + } + } + + #endregion + + #endregion + + #endregion + + #region RowHeader Resize + + #region ContinueRowHeaderResize + + private void ContinueRowHeaderResize(GridPanel panel, Point pt) + { + Rectangle r = panel.BoundsRelative; + r.Y = BoundsRelative.Y; + + if (panel.IsSubPanel == true) + r.Y -= VScrollOffset; + + r.X -= HScrollOffset; + + if (pt.X > r.X) + { + int width = pt.X - r.X; + + if (width < 5) + pt.X = r.X + 5; + + if (pt.X >= SuperGrid.PrimaryGrid.BoundsRelative.Right - 2) + { + HideSeparator(); + } + else + { + if (pt.X == panel.BoundsRelative.Right - 1) + pt.X--; + + r.X = pt.X; + + r.Width = SeparatorWidth; + r.Height -= (BoundsRelative.Y - panel.BoundsRelative.Y); + + Rectangle t = SViewRect; + + if (r.Bottom > t.Bottom) + r.Height -= (r.Bottom - t.Bottom); + + r.Location = SuperGrid.PointToScreen(r.Location); + + _SeparatorFw.Show(); + + _SeparatorFw.Bounds = r; + _SeparatorFw.Size = r.Size; + } + } + } + + #endregion + + #region ResizeRowHeader + + private void ResizeRowHeader(GridPanel panel, int width) + { + Rectangle t = panel.ViewRect; + + int n = Math.Max(5, _ResizeWidth + width); + + if (t.Right - 10 < n) + n = t.Right - 10; + + n = Dpi.DescaleWidth(n); + + if (panel.RowHeaderWidth != n) + { + panel.RowHeaderWidth = n; + + panel.SuperGrid.Invalidate(); + + SuperGrid.DoRowHeaderResizedEvent(panel); + } + } + + #endregion + + #endregion + + #region ActivateFilterPopup + + internal void ActivateFilterPopup(GridPanel panel, GridColumn column) + { + if (_FilterMenu != null) + _FilterMenu.Dispose(); + + _FilterMenu = new FilterPopup(panel); + + _LockedColumn = true; + _HitArea = HeaderArea.NoWhere; + + _FilterMenu.ActivatePopup(column, ResetColumnState); + } + + #endregion + + #region DeactivateFilterPopup + + internal void DeactivateFilterPopup(GridPanel panel, GridColumn column) + { + FilterPopup fm = _FilterMenu; + + if (fm != null) + fm.DeactivatePopup(); + + } + + #endregion + + #region GetHitArea + + /// + /// Returns the ColumnHeader hit area + /// and column for the given Point + /// + /// + /// + ///HeaderArea + public HeaderArea GetHitArea(Point pt, ref GridColumn column) + { + object hitItem = null; + + HeaderArea area = GetHitArea(pt, ref hitItem, false); + + column = hitItem as GridColumn; + + return (area); + } + + /// + /// Returns the ColumnHeader hit area + /// and hit object for the given Point + /// + /// + /// + /// + public HeaderArea GetHitArea(Point pt, ref object hitItem) + { + return (GetHitArea(pt, ref hitItem, false)); + } + + private HeaderArea GetHitArea( + Point pt, ref object hitItem, bool isMouseDown) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + GridElement hitObject = GetHitObject(panel, pt, isMouseDown); + + if (hitObject == this) + return (GetHeaderHitArea(panel, pt, ref hitItem, isMouseDown)); + + if (hitObject == panel.GroupByRow) + return (HeaderArea.InGroupBox); + } + + return (HeaderArea.NoWhere); + } + + #region GetHitObject + + private GridElement GetHitObject( + GridPanel panel, Point pt, bool isMouseDown) + { + if (isMouseDown == true && panel.GroupByRow.Visible == true) + { + if (panel.GroupByRow.Bounds.Contains(pt) == true) + return (panel.GroupByRow); + } + + if (Capture == true || Bounds.Contains(pt) == true) + return (this); + + return (null); + } + + #endregion + + #region GetHeaderHitArea + + private HeaderArea GetHeaderHitArea(GridPanel panel, + Point pt, ref object hitItem, bool isMouseDown) + { + hitItem = null; + + HeaderArea area = GetRowHeaderArea(panel, pt); + + if (area != HeaderArea.NoWhere) + return (area); + + area = GetGroupHeaderArea(panel, pt, ref hitItem); + + if (area != HeaderArea.NoWhere) + return (area); + + GridColumn column = GetHitColumn(panel, pt, isMouseDown, false); + + area = GetHeaderArea(panel, pt, ref column); + + hitItem = column; + + return (area); + } + + #region GetGroupHeaderArea + + private HeaderArea GetGroupHeaderArea(GridPanel panel, Point pt, ref object hitItem) + { + ColumnGroupHeader cgh = GetHitGroupHeader(panel, pt, _GroupHeaders); + + if (cgh != null) + { + if (GetShowRootColumnHeaders(cgh) == false) + { + GridColumn coll = GetHitColumn(panel, pt, false, true); + + if (coll != null) + { + HeaderArea area = GetHeaderArea(panel, pt, ref coll); + + if (area == HeaderArea.InResize) + { + hitItem = coll; + + return (area); + } + } + } + + hitItem = cgh; + + if (IsMouseDown == false) + { + int[] map = panel.Columns.DisplayIndexMap; + + Rectangle r = GetSubScrollBounds(panel, cgh); + + if (pt.X < r.Left + 3 && pt.X >= r.Left) + { + if ((uint)cgh.StartDisplayIndex < map.Length) + { + GridColumn column = panel.Columns[map[cgh.StartDisplayIndex]]; + + if (InLeftResizeArea(ref column, panel) == true) + { + hitItem = column; + + return (HeaderArea.InResize); + } + } + } + + if ((pt.X > r.Right - 5) && (pt.X < r.Right + 3)) + { + if ((uint)cgh.EndDisplayIndex < map.Length) + { + GridColumn column = panel.Columns[map[cgh.EndDisplayIndex]]; + + if (InRightResizeArea(ref column, panel) == true) + { + hitItem = column; + + return (HeaderArea.InResize); + } + } + } + } + + if (cgh.AllowSelection == true) + return (HeaderArea.InContent); + + return (HeaderArea.NoWhere); + } + + return (HeaderArea.NoWhere); + } + + #endregion + + #region GetHitGroupHeader + + private ColumnGroupHeader GetHitGroupHeader( + GridPanel panel, Point pt, ColumnGroupHeaderCollection csc) + { + if (csc != null) + { + foreach (ColumnGroupHeader cgh in csc) + { + if (cgh.Visible == true) + { + Rectangle r = GetSubScrollBounds(panel, cgh); + + if (r.Contains(pt) == true) + return (cgh); + + ColumnGroupHeader csh2 = GetHitGroupHeader(panel, pt, cgh.GroupHeaders); + + if (csh2 != null) + return (csh2); + } + } + } + + return (null); + } + + #endregion + + #region GetRowHeaderArea + + private HeaderArea GetRowHeaderArea(GridPanel panel, Point pt) + { + Rectangle r = GetRowHeaderBounds(panel); + + r.Width += Dpi.Width2; + + if (r.Contains(pt) == true) + { + if (Capture == true) + return (_HitArea); + + r.Width -= Dpi.Width2; + + if (panel.AllowRowHeaderResize == true) + { + if (pt.X >= r.Right - Dpi.Width5) + return (HeaderArea.InRowHeaderResize); + } + + return (HeaderArea.InRowHeader); + } + + return (HeaderArea.NoWhere); + } + + #endregion + + #region GetHitColumn + + /// + /// Gets the associated column at the given location + /// + /// + /// + /// + public GridColumn GetHitColumn(int x, int y) + { + return (GetHitColumn(new Point(x, y))); + } + + /// + /// Gets the associated column at the given point + /// + /// + /// + public GridColumn GetHitColumn(Point pt) + { + GridPanel panel = GridPanel; + + if (panel != null) + return (GetHitColumn(panel, pt, false, false)); + + return (null); + } + + private GridColumn GetHitColumn( + GridPanel panel, Point pt, bool isMouseDown, bool limit) + { + int dy = (isMouseDown == true) ? 50 : 0; + + GridColumnCollection columns = _Columns; + foreach (GridColumn column in columns) + { + if (column.Visible == true) + { + Rectangle r = GetBounds(panel, column); + + if (pt.X >= r.Left && pt.X < r.Right) + { + int top = limit ? r.Bottom - 10 : r.Top; + + if (pt.Y >= top && pt.Y < r.Bottom + dy) + return (column); + } + } + } + + return (null); + } + + #endregion + + #region GetHeaderArea + + private HeaderArea GetHeaderArea(GridPanel panel, Point pt, ref GridColumn column) + { + GridColumn hcolumn = column; + + if (column == null) + column = panel.Columns.LastVisibleColumn; + + if (column != null) + { + Rectangle r = column.BoundsRelative; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || column.IsHFrozen == false) + r.X -= HScrollOffset; + + if (pt.X < r.Left + 3 && pt.X >= r.Left) + { + if (InLeftResizeArea(ref column, panel) == true) + return (HeaderArea.InResize); + } + + if ((pt.X > r.Right - 5) && (pt.X < r.Right + 3)) + { + if (InRightResizeArea(ref column, panel) == true) + return (HeaderArea.InResize); + } + + if (column.FilterImageBounds.IsEmpty == false) + { + Rectangle t = GetScrollBounds( + panel, column, column.FilterImageBounds); + + t.Inflate(2, 2); + + if (t.Contains(pt) == true) + return (HeaderArea.InFilterMenu); + } + + column = hcolumn; + + if (hcolumn != null) + { + if (column.AllowSelection == true) + return (HeaderArea.InContent); + + return (HeaderArea.NoWhere); + } + } + + return (HeaderArea.InWhitespace); + } + + #region InLeftResizeArea + + private bool InLeftResizeArea(ref GridColumn column, GridPanel panel) + { + GridColumn pcolumn = + panel.Columns.GetPrevVisibleColumn(column); + + if (pcolumn != null) + { + if (pcolumn.CanResize == true && pcolumn.ResizeMode != ColumnResizeMode.None) + { + column = pcolumn; + + return (true); + } + } + + return (false); + } + + #endregion + + #region InRightResizeArea + + private bool InRightResizeArea(ref GridColumn column, GridPanel panel) + { + GridColumn nColumn = + panel.Columns.GetNextVisibleColumn(column); + + if (nColumn != null && nColumn.Size.Width < 5) + { + if (nColumn.CanResize == true && nColumn.ResizeMode != ColumnResizeMode.None) + column = nColumn; + } + + if (column.CanResize == true && column.ResizeMode != ColumnResizeMode.None) + return (true); + + return (false); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetParent + + /// + ///Gets the object that is the "parent" of the given item + ///(either a GridColumn or ColumnGroupHeader). + /// + /// + ///Parent or null + public object GetParent(object item) + { + if (item is GridColumn) + return (GetParentHeader((GridColumn) item)); + + ColumnGroupHeader cgh = item as ColumnGroupHeader; + + if (cgh != null) + return (cgh.Collection.Parent); + + return (null); + } + + #endregion + + #region GetParentHeader + + /// + ///Gets the object that is the "parent" of the given column. + /// + /// + ///parent or null + public object GetParentHeader(GridColumn column) + { + int index = GridPanel.Columns.GetDisplayIndex(column); + + return (GetParentHeader(index)); + } + + /// + ///Gets the ColumnGroupHeader that is the "parent" of the column at + ///the given DISPLAY index. + /// + ///DISPLAY INDEX + ///parent object or null + public ColumnGroupHeader GetParentHeader(int displayIndex) + { + ColumnGroupHeader tcsh = GetColumnGroupHeader(GroupHeaders, displayIndex); + + if (tcsh != null) + { + while (tcsh.GroupHeaders != null) + { + ColumnGroupHeader fcsh = GetColumnGroupHeader(tcsh.GroupHeaders, displayIndex); + + if (fcsh == null || fcsh.Visible == false) + break; + + tcsh = fcsh; + } + } + + return (tcsh); + } + + #endregion + + #region GetColumnGroupHeader + + internal ColumnGroupHeader GetColumnGroupHeader(int index) + { + return (GetColumnGroupHeader(GroupHeaders, index)); + } + + private ColumnGroupHeader GetColumnGroupHeader(IEnumerable csc, int index) + { + if (csc != null) + { + foreach (ColumnGroupHeader cgh in csc) + { + if (cgh.Contains(index)) + return (cgh.Visible == true ? cgh : null); + } + } + + return (null); + } + + #endregion + + #region UpdateImageBounds + + internal void UpdateImageBounds(GridPanel panel, GridColumn column) + { + Rectangle r = GetColumnHeaderBounds(panel, column); + + if (column.AdjustSortImagePositionByMargin == true) + { + VisualStyle style = GetEffectiveStyle(column); + + r.X += (style.BorderThickness.Left + style.Margin.Left); + r.Width -= (style.BorderThickness.Horizontal + style.Margin.Horizontal); + + r.Y += (style.BorderThickness.Top + style.Margin.Top); + r.Height -= (style.BorderThickness.Vertical + style.Margin.Vertical); + } + + r.Inflate(-3, -3); + r.Width--; + + Alignment sortAlignment = (_SortImageAlignment == Alignment.NotSet) + ? Alignment.TopCenter : _SortImageAlignment; + + Alignment filterAlignment = (_FilterImageAlignment == Alignment.NotSet) + ? Alignment.MiddleLeft : _FilterImageAlignment; + + Rectangle rt = r; + + column.SortImageBounds = Rectangle.Empty; + column.FilterImageBounds = Rectangle.Empty; + + Image sortImage = GetColumnSortImage(panel, column); + + if (sortImage != null) + { + Rectangle t = GetImageBounds(sortImage, sortAlignment, ref r); + + column.SortImageBounds = t; + } + + Image filterImage = GetColumnFilterImage(column); + + if (filterImage != null) + { + Rectangle t; + + if (sortImage != null && filterAlignment == sortAlignment) + { + t = GetImageBounds(filterImage, filterAlignment, ref r); + + switch (filterAlignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + t.X = rt.X + (r.Width - (sortImage.Width + + filterImage.Width)) / 2 + sortImage.Width; + break; + + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + break; + } + } + else + { + t = GetImageBounds(filterImage, filterAlignment, ref rt); + + r.Intersect(rt); + } + + column.FilterImageBounds = t; + } + } + + #endregion + + #region GetColumnHeaderBounds + + private Rectangle GetColumnHeaderBounds(GridPanel panel, GridColumn column) + { + Rectangle r = GetRelativeBounds(panel, column); + + r.X = column.BoundsRelative.X; + r.Width = column.BoundsRelative.Width; + + ColumnGroupHeader cgh = GetParentHeader(panel.Columns.GetDisplayIndex(column.ColumnIndex)); + + if (cgh != null) + { + int n = cgh.Size.Height - cgh.BoundsRelative.Height; + + r.Y = r.Bottom - n; + r.Height = n; + } + + return (r); + } + + #endregion + + #region GetRelativeSubSize + + internal int GetRelativeSubSize(ColumnGroupHeader cgh, int index) + { + int n = cgh.BoundsRelative.Height; + + foreach (ColumnGroupHeader sub in cgh.GroupHeaders) + { + if (sub.Contains(index) == true) + n += GetRelativeSubSize(sub, index); + } + + return (n); + } + + #endregion + + #region GetRowHeaderBounds + + private Rectangle GetRowHeaderBounds(GridPanel panel) + { + if (panel.ShowRowHeaders == true) + { + Rectangle r = Bounds; + r.Width = panel.RowHeaderWidthEx; + + Rectangle p = panel.PanelBounds; + + if (r.Y < p.Y) + { + r.Height -= (p.Y - r.Y + 1); + r.Y = p.Y + 1; + } + + return (r); + } + + return (Rectangle.Empty); + } + + #endregion + + #region Style support + + #region GroupHeader Style support + + #region InvalidateStyle + + /// + ///Invalidates the cached Style + ///definition for all defined StyleTypes + /// + public void InvalidateStyle() + { + GridColumnCollection columns = GridPanel.Columns; + + foreach (GridColumn column in columns) + column.InvalidateStyle(); + + InvalidateStyle(GroupHeaders); + } + + /// + ///Invalidates the cached Style + ///definition for all GroupHeader defined StyleTypes + /// + /// + public void InvalidateStyle(ColumnGroupHeader cgh) + { + if (cgh.EffectiveStyles != null) + { + cgh.EffectiveStyles.Dispose(); + cgh.EffectiveStyles = null; + } + + InvalidateStyle(cgh.GroupHeaders); + } + + private void InvalidateStyle(IEnumerable groups) + { + foreach (ColumnGroupHeader cgh in groups) + InvalidateStyle(cgh); + } + + /// + ///Invalidate the cached Style + ///definition for the given StyleType + /// + /// + public void InvalidateStyle(StyleType type) + { + GridColumnCollection columns = GridPanel.Columns; + + foreach (GridColumn column in columns) + column.InvalidateStyle(type); + + InvalidateStyle(GroupHeaders, type); + } + + /// + ///Invalidate the cached Style + ///definition for the given GroupHeader StyleType + /// + /// + /// + public void InvalidateStyle(ColumnGroupHeader cgh, StyleType type) + { + if (cgh.EffectiveStyles != null) + { + cgh.EffectiveStyles[type].Dispose(); + cgh.EffectiveStyles[type] = null; + } + + InvalidateStyle(cgh.GroupHeaders, type); + } + + private void InvalidateStyle(IEnumerable groups, StyleType type) + { + foreach (ColumnGroupHeader cgh in groups) + InvalidateStyle(cgh, type); + } + + #endregion + + #region GetSizingStyle + + private ColumnHeaderVisualStyle GetSizingStyle(GridPanel panel, ColumnGroupHeader cgh) + { + StyleType style = panel.GetSizingStyle(); + + if (style == StyleType.NotSet) + style = StyleType.Default; + + return (GetEffectiveStyle(cgh, style)); + } + + #endregion + + #region GetGroupHeaderStyleState + + private StyleState GetGroupHeaderStyleState(ColumnGroupHeader cgh) + { + StyleState state = StyleState.Default; + + if (_Reordering == true) + { + if (cgh == _MouseDownHitItem) + state |= StyleState.MouseOver; + } + else if (_HitItem == cgh) + { + state |= StyleState.MouseOver; + } + + if (IsGroupHeaderSelected(cgh) == true) + state |= StyleState.Selected; + + if (IsGroupHeaderReadOnly(cgh) == true) + state |= StyleState.ReadOnly; + + return (state); + } + + #endregion + + #region GetEffectiveStyle + + /// + /// GetEffectiveStyle + /// + /// + /// + public ColumnHeaderVisualStyle GetEffectiveStyle(ColumnGroupHeader cgh) + { + StyleState styleState = GetGroupHeaderStyleState(cgh); + ColumnHeaderVisualStyle style = GetEffectiveStyle(cgh, styleState); + + return (style); + } + + /// + ///Gets the EffectiveStyle for the given StyleState + /// + /// + /// + /// + public ColumnHeaderVisualStyle + GetEffectiveStyle(ColumnGroupHeader cgh, StyleState cellState) + { + StyleType type = GetStyleType(cellState); + + return (GetEffectiveStyle(cgh, type)); + } + + internal ColumnHeaderVisualStyle + GetEffectiveStyle(ColumnGroupHeader cgh, StyleType sizingStyle) + { + return (GetGroupHeaderStyle(cgh, sizingStyle)); + } + + #region GetGroupHeaderStyle + + internal ColumnHeaderVisualStyle GetGroupHeaderStyle(ColumnGroupHeader cgh, StyleType e) + { + ValidateGroupHeaderStyle(cgh); + + if (cgh.EffectiveStyles == null) + cgh.EffectiveStyles = new ColumnHeaderVisualStyles(); + + if (cgh.EffectiveStyles.IsValid(e) == false) + { + GridPanel panel = GridPanel; + ColumnHeaderVisualStyle style = new ColumnHeaderVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + ColumnGroupHeader pcgh = GetParent(cgh) as ColumnGroupHeader; + + if (pcgh != null) + { + if (GetAutoApplyGroupColor(cgh) != true) + pcgh = null; + } + + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.ColumnHeaderStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.ColumnHeaderStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.ColumnHeaderStyles[cs]); + + style.ApplyStyle(cgh.HeaderStyles[cs]); + + if (pcgh != null) + { + ColumnHeaderVisualStyle gstyle = GetEffectiveStyle(pcgh, cs); + + if (gstyle.Background != null) + { + if (cgh.HeaderStyles[cs].Background == null || cgh.HeaderStyles[cs].Background.IsEmpty) + style.Background = gstyle.Background.Copy(); + } + + if (gstyle.TextColor.IsEmpty == false) + { + if (cgh.HeaderStyles[cs].TextColor.IsEmpty) + style.TextColor = gstyle.TextColor; + } + } + } + } + + SuperGrid.DoGetColumnGroupHeaderStyleEvent(panel, cgh, e, ref style); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + if (style.Font == null) + style.Font = SystemFonts.DefaultFont; + + cgh.EffectiveStyles[e] = style; + } + + return (cgh.EffectiveStyles[e]); + } + + #region ValidateGroupHeaderStyle + + private void ValidateGroupHeaderStyle(ColumnGroupHeader cgh) + { + if (cgh.StyleUpdateCount != SuperGrid.StyleUpdateCount) + { + if (cgh.EffectiveStyles != null) + { + cgh.EffectiveStyles.Dispose(); + cgh.EffectiveStyles = null; + } + + cgh.StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region ColumnHeader Style support + + #region GetSizingStyle + + private ColumnHeaderVisualStyle GetSizingStyle(GridPanel panel, GridColumn column) + { + StyleType style = panel.GetSizingStyle(); + + if (style == StyleType.NotSet) + style = StyleType.Default; + + return (GetEffectiveStyle(column, style)); + } + + #endregion + + #region GetStyleState + + private StyleState GetStyleState(GridColumn column, bool selected) + { + StyleState state = StyleState.Default; + + if (_Reordering == true) + { + if (column == _MouseDownHitItem) + state |= StyleState.MouseOver; + } + else if (_HitItem == column) + { + state |= StyleState.MouseOver; + } + + if (selected == true) + state |= StyleState.Selected; + + if (column.IsReadOnly == true) + state |= StyleState.ReadOnly; + + return (state); + } + + #endregion + + #region GetStyleType + + private StyleType GetStyleType(StyleState state) + { + switch (state) + { + case StyleState.MouseOver: + return (StyleType.MouseOver); + + case StyleState.Selected: + return (StyleType.Selected); + + case StyleState.Selected | StyleState.MouseOver: + return (StyleType.SelectedMouseOver); + + case StyleState.ReadOnly: + return (StyleType.ReadOnly); + + case StyleState.ReadOnly | StyleState.MouseOver: + return (StyleType.ReadOnlyMouseOver); + + case StyleState.ReadOnly | StyleState.Selected: + return (StyleType.ReadOnlySelected); + + case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: + return (StyleType.ReadOnlySelectedMouseOver); + + default: + return (StyleType.Default); + } + } + + #endregion + + #region GetEffectiveStyle + + /// + /// GetEffectiveStyle + /// + /// + /// + public ColumnHeaderVisualStyle GetEffectiveStyle(GridColumn column) + { + StyleState styleState = GetStyleState(column, column.IsSelected); + ColumnHeaderVisualStyle style = GetEffectiveStyle(column, styleState); + + return (style); + } + + /// + ///Gets the EffectiveStyle for the given StyleState + /// + /// + /// + /// + public ColumnHeaderVisualStyle + GetEffectiveStyle(GridColumn column, StyleState cellState) + { + StyleType type = GetStyleType(cellState); + + return (GetEffectiveStyle(column, type)); + } + + internal ColumnHeaderVisualStyle + GetEffectiveStyle(GridColumn column, StyleType type) + { + return (column.GetHeaderStyle(type)); + } + + #endregion + + #region GetEffectiveRowHeaderStyle + + internal ColumnHeaderRowVisualStyle GetEffectiveRowHeaderStyle() + { + return (GetEffectiveRowHeaderStyleEx(GetRowHeaderState())); + } + + internal ColumnHeaderRowVisualStyle + GetEffectiveRowHeaderStyleEx(StyleState rowState) + { + ValidateRowHeaderStyle(); + + StyleType type = GetStyleType(rowState); + + return (GetRowHeaderStyle(type)); + } + + #region ValidateRowHeaderStyle + + private void ValidateRowHeaderStyle() + { + if (_StyleUpdateCount != SuperGrid.StyleUpdateCount) + { + _EffectiveRowHeaderStyles = null; + + _StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #region GetRowHeaderState + + private StyleState GetRowHeaderState() + { + StyleState rowState = StyleState.Default; + + if (_HitArea == HeaderArea.InRowHeader || _HitArea == HeaderArea.InWhitespace) + rowState |= StyleState.MouseOver; + + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.ReadOnly == true) + rowState |= StyleState.ReadOnly; + + if (panel == SuperGrid.ActiveGrid) + rowState |= StyleState.Selected; + } + + return (rowState); + } + + #endregion + + #region GetRowHeaderStyle + + private ColumnHeaderRowVisualStyle GetRowHeaderStyle(StyleType e) + { + if (_EffectiveRowHeaderStyles == null) + _EffectiveRowHeaderStyles = new ColumnHeaderRowVisualStyles(); + + if (_EffectiveRowHeaderStyles.IsValid(e) == false) + { + ColumnHeaderRowVisualStyle style = new ColumnHeaderRowVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.ColumnHeaderRowStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.ColumnHeaderRowStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.ColumnHeaderRowStyles[cs]); + } + } + + SuperGrid.DoGetColumnHeaderRowHeaderStyleEvent(this, e, ref style); + + if (style.RowHeader.Background == null || style.RowHeader.Background.IsEmpty == true) + style.RowHeader.Background = new Background(Color.WhiteSmoke); + + _EffectiveRowHeaderStyles[e] = style; + } + + return (_EffectiveRowHeaderStyles[e]); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region GetShowRootColumnHeaders + + private bool GetShowRootColumnHeaders(ColumnGroupHeader cgh) + { + while (cgh != null) + { + if (cgh.ShowColumnHeaders != Tbool.NotSet) + return (cgh.ShowColumnHeaders == Tbool.True); + + cgh = cgh.Collection.Parent as ColumnGroupHeader; + } + + return (_ShowGroupColumnHeaders); + } + + #endregion + + #region GetAutoApplyGroupColor + + internal bool GetAutoApplyGroupColor(ColumnGroupHeader cgh) + { + if (cgh.AutoApplyGroupColors != Tbool.NotSet) + return (cgh.AutoApplyGroupColors == Tbool.True); + + return (AutoApplyGroupColors); + } + + #endregion + + #region IsGroupHeaderSelected + + /// + ///Returns whether the given GroupHeader is selected (ie. all + ///visible columns/headers it encompasses must be selected) + /// + ///GroupHeader + ///true, if all selected + public bool IsGroupHeaderSelected(ColumnGroupHeader cgh) + { + GridPanel panel = GridPanel; + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + + bool selected = false; + + for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) + { + if ((uint) i < map.Length) + { + GridColumn column = columns[map[i]]; + + if (column.Visible == true) + { + if (column.IsSelected == false) + return (false); + + selected = true; + } + } + } + + return (selected); + } + + #endregion + + #region IsGroupHeaderReadOnly + + /// + ///Returns whether the given GroupHeader is ReadOnly (ie. all + ///visible columns/headers it encompasses must be ReadOnly) + /// + /// + /// + public bool IsGroupHeaderReadOnly(ColumnGroupHeader cgh) + { + GridPanel panel = GridPanel; + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + + bool readOnly = false; + + for (int i = cgh.StartDisplayIndex; i <= cgh.EndDisplayIndex; i++) + { + if ((uint)i >= map.Length) + break; + + GridColumn column = columns[map[i]]; + + if (column.Visible == true) + { + if (column.IsReadOnly == false) + return (false); + + readOnly = true; + } + } + + return (readOnly); + } + + #endregion + + #region IsItemHFrozen + + internal bool IsItemHFrozen(object item) + { + if (item is GridColumn) + return ((GridColumn)item).IsHFrozenEx; + + if (item is ColumnGroupHeader) + return (IsGroupHeaderHFrozen(GridPanel, (ColumnGroupHeader)item)); + + return (false); + } + + #endregion + + #region IsGroupHeaderHFrozen + + internal bool IsGroupHeaderHFrozen(GridPanel panel, ColumnGroupHeader cgh) + { + if (panel.IsSubPanel == false) + { + if (cgh != null) + return (cgh.StartDisplayIndex < panel.FrozenColumnCount); + } + + return (false); + } + + #endregion + + #region GetBounds + + internal Rectangle GetBounds(GridPanel panel, GridColumn column) + { + Rectangle r = GetRelativeBounds(panel, column); + + return (GetScrollBounds(panel, column, r)); + } + + #endregion + + #region GetRelativeBounds + + internal Rectangle GetRelativeBounds(GridPanel panel, GridColumn column) + { + Rectangle r = BoundsRelative; + + r.X = column.BoundsRelative.X; + r.Width = column.BoundsRelative.Width; + + return (r); + } + + #endregion + + #region GetScrollBounds + + internal Rectangle GetScrollBounds( + GridPanel panel, GridColumn column, Rectangle r) + { + if (r.IsEmpty == false) + { + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || column.IsHFrozen == false) + r.X -= HScrollOffset; + } + + return (r); + } + + #endregion + + #region GetSubScrollBounds + + internal Rectangle GetSubScrollBounds(GridPanel panel, ColumnGroupHeader cgh) + { + Rectangle r = cgh.BoundsRelative; + + if (r.IsEmpty == false) + { + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || IsGroupHeaderHFrozen(panel, cgh) == false) + r.X -= HScrollOffset; + } + + return (r); + } + + #endregion + + #region GetSubContScrollBounds + + internal Rectangle GetSubContScrollBounds(GridPanel panel, ColumnGroupHeader cgh) + { + Rectangle r = cgh.BoundsRelative; + r.Height = cgh.Size.Height; + + if (r.IsEmpty == false) + { + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || IsGroupHeaderHFrozen(panel, cgh) == false) + r.X -= HScrollOffset; + } + + return (r); + } + + #endregion + + #region GetContentBounds + + internal Rectangle GetContentBounds(GridPanel panel, ColumnHeaderVisualStyle style, Rectangle r) + { + if (_ShowHeaderImages == true) + { + object figure = style.GetFigure(panel); + + if (figure != null) + { + Size size = style.GetFigureSize(panel); + + if (style.IsOverlayImage != true) + { + switch (style.ImageAlignment) + { + case Alignment.TopCenter: + r.Y += size.Height; + r.Height -= size.Height; + break; + + case Alignment.MiddleCenter: + break; + + case Alignment.BottomCenter: + r.Height -= size.Height; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + r.Width -= size.Width; + break; + + default: + r.X += size.Width; + r.Width -= size.Width; + break; + } + } + } + } + + return (r); + } + + #endregion + + #region GetAdjustedBounds + + private Rectangle GetAdjustedBounds(VisualStyle style, Rectangle r) + { + r.X += Dpi.Width(style.BorderThickness.Left + style.Margin.Left + style.Padding.Left); + r.Width -= Dpi.Width(style.BorderThickness.Horizontal + style.Margin.Horizontal + style.Padding.Horizontal); + + r.Y += Dpi.Height(style.BorderThickness.Top + style.Margin.Top + style.Padding.Top); + r.Height -= Dpi.Height(style.BorderThickness.Vertical + style.Margin.Vertical + style.Padding.Vertical); + + return (r); + } + + #endregion + + #region GetImageBounds + + /// + /// Gets the bounding rectangle for the + /// given column header image + /// + /// + /// Bounding rectangle + public Rectangle GetImageBounds(GridColumn column) + { + if (_ShowHeaderImages == true) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + SuperGridControl sg = panel.SuperGrid; + + if (sg != null) + { + ColumnHeaderVisualStyle style = GetEffectiveStyle(column); + + object figure = style.GetFigure(panel); + + if (figure != null) + { + Rectangle bounds = GetBounds(panel, column); + + using (Graphics g = sg.CreateGraphics()) + { + Rectangle t = GetAdjustedBounds(style, + GetContentBounds(panel, style, bounds)); + + return (style.GetFigureBounds(panel, t)); + } + } + } + } + } + + return (Rectangle.Empty); + } + + #endregion + + #region InvalidateHeader + + internal void InvalidateHeader(GridPanel panel, GridColumn column) + { + Rectangle bounds = BoundsRelative; + + if (panel.IsVFrozen == false) + bounds.Y -= VScrollOffset; + + bounds.X = column.BoundsRelative.X; + bounds.Width = column.BoundsRelative.Width; + + if (panel.IsSubPanel == true || column.IsHFrozen == false) + bounds.X -= HScrollOffset; + + InvalidateRender(bounds); + } + + private void InvalidateHeader(GridPanel panel, ColumnGroupHeader cgh) + { + Rectangle r = GetSubScrollBounds(panel, cgh); + + InvalidateRender(r); + } + + #endregion + + #region InvalidateRowHeader + + internal void InvalidateRowHeader() + { + InvalidateRender(RowHeaderBounds); + } + + #endregion + + #region InvalidateWhitespace + + internal void InvalidateWhitespace() + { + Rectangle bounds = Bounds; + + GridColumn col = GridPanel.Columns.LastVisibleColumn; + + if (col != null) + { + if (col.Bounds.Right < bounds.Right) + { + int n = bounds.Right - col.Bounds.Right; + + bounds.X = col.Bounds.Right; + bounds.Width = n; + } + + InvalidateRender(bounds); + } + } + + #endregion + + #region InvalidateItem + + private void InvalidateItem(GridPanel panel, object item) + { + if (item is GridColumn) + InvalidateHeader(panel, (GridColumn)item); + + else if (item is ColumnGroupHeader) + InvalidateHeader(panel, (ColumnGroupHeader)item); + } + + #endregion + + #region CancelCapture + + /// + /// Cancels any in progress operations (resize, reorder) + /// that may have the mouse captured. + /// + public override void CancelCapture() + { + StopReorder(); + StopResize(); + + _MouseDownHitItem = null; + + base.CancelCapture(); + } + + #endregion + } + + #region enums + + #region HeaderArea + + /// + /// HeaderArea + /// + public enum HeaderArea + { + /// + /// NoWhere + /// + NoWhere, + + /// + /// InContent + /// + InContent, + + /// + /// InResize + /// + InResize, + + /// + /// InRowHeader + /// + InRowHeader, + + /// + /// InRowHeaderResize + /// + InRowHeaderResize, + + /// + /// InWhitespace + /// + InWhitespace, + + /// + /// InMarkup + /// + InMarkup, + + /// + /// InFilterMenu + /// + InFilterMenu, + + /// + /// InGroupBox + /// + InGroupBox, + } + + #endregion + + #region ImageVisibility + + /// + /// ImageVisibility + /// + public enum ImageVisibility + { + /// + /// NotSet + /// + NotSet = -1, + + /// + /// Auto + /// + Auto, + + /// + /// Always + /// + Always, + + /// + /// Never + /// + Never, + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridContainer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridContainer.cs new file mode 100644 index 00000000..e87c5d74 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridContainer.cs @@ -0,0 +1,4018 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Media; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Defines Grid element with Items collection + /// + public abstract class GridContainer : GridElement, IDisposable + { + #region Private variables + + private GridItemsCollection _Rows; + + private Cs _States; + + private int _Index; + private int _FullIndex; + private int _RowIndex; + private int _GridIndex; + private int _IndentLevel; + + private Rectangle _CheckBoxBounds; + private Rectangle _ContainerBounds; + + private GridElement _MouseOverElement; + + private int _FixedRowHeight; + private int _FixedHeaderHeight; + private int _FirstOnScreenRowIndex; + + private ushort _DeleteUpdateCount; + private ushort _ExpandedUpdateCount; + private ushort _SelectionUpdateCount; + private ushort _SelectionClearCount; + private ushort _StyleUpdateCount; + private ushort _MergeUpdateCount = 1; + + private RowVisualStyles _RowStyles; + private RowVisualStyles _EffectiveRowStyles; + private CellVisualStyles _CellVisualStyles; + + private string _RowHeaderText = ""; + + private List _DisplayedCellRanges; + private CellRange _LastCellRange; + private int _DisplayedMergeLayoutCount; + + private bool _NeedMergeLayout; + private MergeScan _MergeScan; + + private CellRange _SuspendedRange; + + #endregion + + #region Abstract methods + + /// + /// Creates the GridItemsCollection that hosts the items. + /// + /// New instance of GridItemsCollection. + protected abstract GridItemsCollection CreateItemsCollection(); + + /// + /// Disposes of the GridItemsCollection that hosts the items. + /// + protected abstract void DisposeItemsCollection(GridItemsCollection items); + + #endregion + + #region Public properties + + #region Bounds + + /// + /// Gets the scroll adjusted bounds + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle Bounds + { + get + { + Rectangle r = BoundsRelative; + + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + return (r); + } + } + + #endregion + + #region CellStyles + + /// + /// Gets or sets the default Cell visual styles + /// + [Category("Style")] + [Description("Indicates the default Cell visual styles.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CellVisualStyles CellStyles + { + get + { + if (_CellVisualStyles == null) + { + _CellVisualStyles = new CellVisualStyles(); + + UpdateChangeHandler(null, _CellVisualStyles); + } + + return (_CellVisualStyles); + } + + set + { + if (_CellVisualStyles != value) + { + CellVisualStyles oldValue = _CellVisualStyles; + _CellVisualStyles = value; + + OnStyleChanged("CellVisualStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region Checked + + /// + /// Gets or sets the row CheckBox checked state + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates the row CheckBox checked state.")] + public virtual bool Checked + { + get { return (TestState(Cs.Checked)); } + + set + { + if (Checked != value) + { + SetState(Cs.Checked, value); + + OnCheckedChanged(); + } + } + } + + #region OnCheckedChanged + + private void OnCheckedChanged() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (HasCheckBox == true) + { + Rectangle r = _CheckBoxBounds; + + if (panel.IsSubPanel == true || + (panel.PrimaryColumn != null && panel.PrimaryColumn.IsHFrozen == false)) + { + r.X -= HScrollOffset; + } + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + InvalidateRender(r); + } + + OnPropertyChanged("Checked"); + + SuperGrid.DoAfterCheckEvent(panel, this); + } + } + + #endregion + + #endregion + + #region DisplayedRowCount + + /// + /// Gets the count of visible rows on screen + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int DisplayedRowCount + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridContainer frow = FirstOnScreenRow; + GridContainer lrow = LastOnScreenRow; + + if (frow != null && lrow != null) + return (lrow.GridIndex - frow.GridIndex + 1); + } + + return (0); + } + } + + #endregion + + #region Expanded + + /// + /// Gets or sets whether the row is + /// expanded, permitting its child rows to be visible + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the row is expanded, permitting its child rows to be visible.")] + public bool Expanded + { + get { return (TestState(Cs.Expanded)); } + + set + { + if (Expanded != value) + { + SetExpanded(value, ExpandSource.Expand); + + OnPropertyChangedEx("Expanded", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FirstOnScreenRow + + /// + /// Gets the first visible row on screen + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer FirstOnScreenRow + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + int index = FirstOnScreenRowIndex; + + if (panel.VirtualMode == true) + { + if (index < panel.VirtualRowCountEx) + return (panel.VirtualRows[index]); + } + else + { + if ((uint)index < Rows.Count) + { + GridContainer row = panel.Rows[index] as GridContainer; + + if (row != null && row.Visible == true) + { + if (row.Expanded == true && row.Rows.Count > 0) + { + GridContainer roe = + GetFirstOnScreenRow(row.Rows, SuperGrid.ViewRect); + + if (roe != null) + return (roe); + } + + return (row); + } + } + } + } + + return (null); + } + + set + { + if (value != null) + value.ScrollToTop(); + } + } + + #endregion + + #region FirstOnScreenRowIndex + + /// + /// Gets the first visible on screen row index + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int FirstOnScreenRowIndex + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if ((VScrollOffset == 0 && panel.IsFiltered == false && panel.DeletedRowCount == 0) || + (Parent != null && IsVFrozen == true)) + { + _FirstOnScreenRowIndex = 0; + } + else + { + Rectangle r = SuperGrid.ViewRect; + + _FirstOnScreenRowIndex = (panel.VirtualMode == true) + ? GetFirstOnScreenVirtualRowIndex(panel) + : GetFirstOnScreenRealRowIndex(r); + } + } + + if (panel.VirtualMode == true) + { + if (_FirstOnScreenRowIndex >= panel.VirtualRowCount) + _FirstOnScreenRowIndex = 0; + } + else + { + if (_FirstOnScreenRowIndex >= Rows.Count) + _FirstOnScreenRowIndex = 0; + } + + return (_FirstOnScreenRowIndex); + } + + set + { + GridPanel panel = GridPanel; + + if (panel.VirtualMode == true) + { + if ((uint)value < panel.VirtualRowCount) + FirstOnScreenRow = panel.VirtualRows[value]; + } + else + { + if ((uint)value < Rows.Count) + FirstOnScreenRow = Rows[value] as GridContainer; + } + } + } + + #region GetFirstOnScreenVirtualRow + + private int GetFirstOnScreenVirtualRowIndex(GridPanel panel) + { + Rectangle r = BoundsRelative; + + int vrh = Dpi.Height(panel.VirtualRowHeight); + + r.Y += (FixedRowHeight - panel.FrozenRowCount * vrh); + + int y = VScrollOffset; + + if (Parent == null) + y += (panel.FrozenRowCount * vrh); + else + y = (y - r.Y) + SuperGrid.PrimaryGrid.FixedRowHeight; + + int n = y / vrh - 0; + + return (n > 0 ? n : 0); + } + + #endregion + + #region GetFirstOnScreenRealRowIndex + + private int GetFirstOnScreenRealRowIndex(Rectangle r) + { + int lo = 0; + int hi = Rows.Count - 1; + + while (lo < hi) + { + int mid = (lo + hi) / 2; + + GridElement item = Rows[mid]; + Rectangle t = item is GridPanel ? ((GridPanel)item).ContainerBounds : item.BoundsRelative; + + if (item.IsVFrozen == false) + t.Y -= VScrollOffset; + + if (t.Bottom > r.Y) + { + if (t.Y <= r.Y) + { + if (item.Visible == true) + return (mid); + } + + hi = mid - 1; + } + else + { + lo = mid + 1; + } + } + + while (lo < Rows.Count) + { + if (Rows[lo].Visible == true) + break; + + lo++; + } + + return (lo); + } + + #endregion + + #endregion + + #region GetFirstOnScreenRow + + private GridContainer + GetFirstOnScreenRow(GridItemsCollection items, Rectangle t) + { + for (int i = 0; i < items.Count; i++) + { + GridContainer item = items[i] as GridContainer; + + if (item != null) + { + Rectangle r = item.BoundsRelative; + + if (item.IsVFrozen == false) + r.Y -= VScrollOffset; + + if (r.Bottom > t.Top) + { + if (item.Expanded == true && item.Rows.Count > 0) + { + GridContainer row = GetFirstOnScreenRow(item.Rows, t); + + return (row ?? item); + } + + return (item); + } + } + } + + return (null); + } + + #endregion + + #region FirstSelectableRow + + /// + /// Gets the first selectable row + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer FirstSelectableRow + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == true) + { + if (panel.VirtualRowCountEx > 0) + return (panel.VirtualRows[0]); + } + else + { + foreach (GridContainer row in panel.Rows) + { + if (row.Visible == true && row.AllowSelection == true) + return (row); + } + } + } + + return (null); + } + } + + #endregion + + #region FirstVisibleRow + + /// + /// Gets the first visible row + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer FirstVisibleRow + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == true) + { + if (panel.VirtualRowCountEx > 0) + return (panel.VirtualRows[0]); + } + else + { + foreach (GridContainer row in panel.Rows) + { + if (row.Visible == true) + return (row); + } + } + } + + return (null); + } + } + + #endregion + + #region FullIndex + + /// + /// Gets the sequential index for the row + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int FullIndex + { + get + { + CheckIndicees(); + + return (_FullIndex); + } + + internal set { _FullIndex = value; } + } + + #endregion + + #region GridIndex + + /// + /// Gets the sequential index for the visible, expanded row + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int GridIndex + { + get + { + CheckIndicees(); + + return (_GridIndex); + } + + internal set { _GridIndex = value; } + } + + #endregion + + #region Index + + /// + /// Gets the sequential, visible, local container index for the item + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Index + { + get + { + CheckIndicees(); + + return (_Index); + } + + internal set { _Index = value; } + } + + #endregion + + #region IsActive + + /// + /// Gets whether the item is Active + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsActive + { + get { return (this == SuperGrid.ActiveRow); } + } + + #endregion + + #region IsDeleted + + /// + /// Gets whether the item is deleted + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool IsDeleted + { + get + { + GridPanel panel = GetParentPanel(); + + if (panel != null) + { + if (_DeleteUpdateCount != panel.DeleteUpdateCount) + { + SetState(Cs.Deleted, panel.IsRowDeleted(this)); + _DeleteUpdateCount = panel.DeleteUpdateCount; + } + } + + return (TestState(Cs.Deleted)); + } + + set + { + SetState(Cs.Deleted, value); + + GridPanel panel = GetParentPanel(); + + if (panel != null) + { + if (panel.SetDeleted(this, value) == true) + _DeleteUpdateCount = panel.DeleteUpdateCount; + } + } + } + + #endregion + + #region IsExpandedVisible + + /// + /// Gets whether the item is visible + /// and its parental hierarchy is expanded + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsExpandedVisible + { + get + { + if (Visible == false) + return (false); + + GridContainer row = Parent as GridContainer; + + while (row != null) + { + if (row.Visible == false) + return (false); + + if (row is GridPanel == false) + { + if (row.Expanded == false) + return (false); + } + + row = row.Parent as GridContainer; + } + + return (true); + } + } + + #endregion + + #region IsOnScreen + + /// + /// Gets whether the item is visible on screen + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsOnScreen + { + get + { + if (Visible == true) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle t = SViewRect; + Rectangle bounds = Bounds; + + bounds.Width = panel.ColumnHeader.BoundsRelative.Width; + + return (t.IntersectsWith(bounds)); + } + } + + return (false); + } + } + + #endregion + + #region IsSelectable + + /// + /// Gets whether the row can be selected by the user. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSelectable + { + get { return (AllowSelection == true); } + } + + #endregion + + #region IsSelected + + /// + /// Gets or sets whether the item is selected + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSelected + { + get + { + if (AllowSelection == true) + { + GridPanel panel = GetParentPanel(); + + if (panel != null) + { + if ((_SelectionUpdateCount != panel.SelectionUpdateCount) || + (_ExpandedUpdateCount != panel.ExpandedUpdateCount)) + { + if (ExpandedVisible(panel) == true) + Selected = panel.IsItemSelectedEx(this); + + _SelectionUpdateCount = panel.SelectionUpdateCount; + } + + return (Selected); + } + } + + return (false); + } + + set + { + GridPanel panel = GetParentPanel(); + + if (panel != null) + { + if (Selected != value) + { + Selected = value; + + if (ExpandedVisible(panel) == true) + panel.SetSelectedEx(this, value); + + _SelectionUpdateCount = panel.SelectionUpdateCount; + + Rectangle r = ContainerBounds; + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + InvalidateRender(r); + } + } + } + } + + #region ExpandedVisible + + internal bool ExpandedVisible(GridPanel panel) + { + if (_ExpandedUpdateCount != panel.ExpandedUpdateCount) + { + _ExpandedUpdateCount = panel.ExpandedUpdateCount; + + SetState(Cs.ExpandedVisible, IsExpandedVisible); + } + + return (TestState(Cs.ExpandedVisible)); + } + + #endregion + + #endregion + + #region LastOnScreenRow + + /// + /// Gets the last visible on screen row + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer LastOnScreenRow + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == true) + { + int index = LastOnScreenRowIndex; + + if (index < panel.VirtualRowCountEx) + return (panel.VirtualRows[index]); + } + else + { + if (IsExpandedVisible == true) + return (GetLastOnScreenRow(panel.Rows, SuperGrid.ViewRect)); + } + } + + return (null); + } + + set + { + if (value != null) + value.ScrollToBottom(); + } + } + + #region GetLastOnScreenRow + + private GridContainer + GetLastOnScreenRow(GridItemsCollection items, Rectangle t) + { + GridContainer lrow = null; + + for (int i = 0; i < items.Count; i++) + { + GridContainer item = items[i] as GridContainer; + + if (item != null && item.Visible == true) + { + lrow = item; + + Rectangle r = item.BoundsRelative; + + if (item.IsVFrozen == false) + r.Y -= VScrollOffset; + + if (r.Bottom >= t.Bottom || i == items.Count - 1) + { + if (item.Expanded == true && item.Rows.Count > 0) + { + GridContainer row = GetLastOnScreenRow(item.Rows, t); + + return (row ?? item); + } + + return (item); + } + } + } + + return (lrow); + } + + #endregion + + #endregion + + #region LastOnScreenRowIndex + + /// + /// Gets the last visible on screen row index + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int LastOnScreenRowIndex + { + get + { + if (IsExpandedVisible == true) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle t = SuperGrid.ViewRect; + + return (panel.VirtualMode == true) + ? (GetLastOnScreenVirtualRowIndex(panel, t)) + : (GetLastOnScreenRealRowIndex(panel, t)); + } + } + + return (0); + } + + set + { + GridPanel panel = GridPanel; + + if (panel.VirtualMode == true) + { + if ((uint)value < panel.VirtualRowCount) + LastOnScreenRow = panel.VirtualRows[value]; + } + else + { + if ((uint)value < Rows.Count) + LastOnScreenRow = Rows[value] as GridContainer; + } + } + } + + #region GetLastOnScreenVirtualRowIndex + + private int GetLastOnScreenVirtualRowIndex( + GridPanel panel, Rectangle t) + { + int index = FirstOnScreenRowIndex; + GridRow row = panel.VirtualRows[index]; + + int vrh = Dpi.Height(panel.VirtualRowHeight); + + Rectangle r = row.BoundsRelative; + r.Y -= VScrollOffset; + + int n = (t.Bottom - r.Top + vrh - 1) / vrh; + + return (Math.Min(panel.VisibleRowCount - 1, index + n - 1)); + } + + #endregion + + #region GetLastOnScreenRealRowIndex + + private int GetLastOnScreenRealRowIndex(GridPanel panel, Rectangle t) + { + int index = FirstOnScreenRowIndex; + + while (index + 1 < Rows.Count) + { + index++; + + GridContainer item = (GridContainer)panel.Rows[index]; + Rectangle r = item.BoundsRelative; + + if (item.IsVFrozen == false) + r.Y -= VScrollOffset; + + if (r.Bottom >= t.Bottom) + return (index); + } + + return (index); + } + + #endregion + + #endregion + + #region LastSelectableRow + + /// + /// Gets the last user selectable row + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer LastSelectableRow + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == true) + { + if (panel.VirtualRowCountEx > 0) + return (panel.VirtualRows[panel.VirtualRowCountEx - 1]); + } + else + { + return (GetLastSelectableRow(panel.Rows)); + } + } + + return (null); + } + } + + #region GetLastSelectableRow + + private GridContainer GetLastSelectableRow(GridItemsCollection rows) + { + for (int i = rows.Count - 1; i >= 0; i--) + { + GridContainer row = rows[i] as GridContainer; + + if (row != null) + { + if (row.Visible == true && row.AllowSelection == true) + { + if (row.Rows.Count > 0 && row.Expanded == true) + { + GridContainer srow = GetLastSelectableRow(row.Rows); + + if (srow != null) + row = srow; + } + + return (row); + } + } + } + + return (null); + } + + #endregion + + #endregion + + #region LastVisibleRow + + /// + /// Gets the last visible row + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer LastVisibleRow + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == true) + { + if (panel.VirtualRowCountEx > 0) + return (panel.VirtualRows[panel.VirtualRowCountEx - 1]); + } + else + { + for (int i = panel.Rows.Count - 1; i >= 0; i--) + { + GridContainer row = panel.Rows[i] as GridContainer; + + if (row != null) + { + if (row.Visible == true) + return (row); + } + } + } + } + + return (null); + } + } + + #endregion + + #region NextVisibleRow + + /// + /// Gets the next visible row, or null if no + /// subsequent rows are defined + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer NextVisibleRow + { + get + { + GridPanel panel = GetParentPanel(); + + if (panel != null) + { + int index = GridIndex + 1; + + GridElement item = panel.GetRowFromIndex(index); + + while (item != null) + { + if (ItemIsSelectable(panel, item) == true) + return ((GridContainer) item); + + item = panel.GetRowFromIndex(++index); + } + } + + return (null); + } + } + + private bool ItemIsSelectable(GridPanel panel, GridElement item) + { + if (item.Visible == false) + return (false); + + if (item is GridGroup && panel.GroupHeaderKeyBehavior != GroupHeaderKeyBehavior.Select) + return (false); + + return (item is GridContainer); + } + + #endregion + + #region PrevVisibleRow + + /// + /// Gets the previous visible row, or null if + /// no previous rows are defined + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer PrevVisibleRow + { + get + { + GridPanel panel = GetParentPanel(); + + if (panel != null) + { + int index = GridIndex; + + while (--index >= 0) + { + GridElement item = panel.GetRowFromIndex(index); + + if (item == null) + break; + + if (ItemIsSelectable(panel, item) == true) + return ((GridContainer)item); + } + } + + return (null); + } + } + + #endregion + + #region ReadOnly + + /// + /// Gets or sets whether the user can change the row contents + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether the user can change the row contents.")] + public bool ReadOnly + { + get { return (TestState(Cs.ReadOnly)); } + + set + { + if (value != ReadOnly) + { + SetState(Cs.ReadOnly, value); + + OnPropertyChangedEx("ReadOnly", VisualChangeType.Render); + } + } + } + + #endregion + + #region RowHeaderText + + /// + /// Gets or sets the associated row header text. + /// + [DefaultValue(""), Category("Appearance")] + [Description("Indicates the associated row header text.).")] + public string RowHeaderText + { + get { return (_RowHeaderText); } + + set + { + if (_RowHeaderText != value) + { + _RowHeaderText = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("RowHeaderText", VisualChangeType.Render); + } + } + } + + #endregion + + #region RowIndex + + /// + /// Gets the sequential, parental index of the item + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int RowIndex + { + get + { + CheckIndicees(); + + return (_RowIndex); + } + + internal set { _RowIndex = value; } + } + + #region CheckIndicees + + private void CheckIndicees() + { + GridPanel panel = GridPanel; + + if (panel != null) + panel.UpdateIndicees(panel, panel.Rows, true); + } + + #endregion + + #endregion + + #region Rows + + /// + /// Gets the reference to the Rows collection + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the reference to the Rows collection.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public virtual GridItemsCollection Rows + { + get + { + if (_Rows == null) + _Rows = CreateItemsCollection(); + + return (_Rows); + } + + set + { + if (_Rows != null) + DisposeItemsCollection(_Rows); + + _Rows = value; + } + } + + #endregion + + #region RowsUnresolved + + /// + /// Gets or sets whether the rows collection is unknown and has not + /// been resolved (presumes there are rows until set to false) + /// + [DefaultValue(false), Category("Data")] + [Description("Indicates whether the rows collection is unresolved (presumes there are rows until set to false).")] + public bool RowsUnresolved + { + get { return (TestState(Cs.RowsUnresolved)); } + + set + { + if (RowsUnresolved != value) + { + SetState(Cs.RowsUnresolved, value); + + OnPropertyChangedEx("RowsUnresolved", VisualChangeType.Layout); + } + } + } + + #endregion + + #region RowStyles + + /// + /// Gets or sets the visual styles assigned to the row elements + /// + [Category("Style")] + [Description("Indicates visual style assigned to the row elements")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public RowVisualStyles RowStyles + { + get + { + if (_RowStyles == null) + { + _RowStyles = new RowVisualStyles(); + + UpdateChangeHandler(null, _RowStyles); + } + + return (_RowStyles); + } + + set + { + if (_RowStyles != value) + { + RowVisualStyles oldValue = _RowStyles; + _RowStyles = value; + + OnStyleChanged("RowStyles", oldValue, value); + + if (oldValue != null) + oldValue.Dispose(); + } + } + } + + #endregion + + #region ShowCheckBox + + /// + /// Get or sets whether the row CheckBox is shown (Panel.CheckBoxes must also be true) + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the row CheckBox is shown (Panel.CheckBoxes must also be true).")] + public bool ShowCheckBox + { + get { return (TestState(Cs.ShowCheckBox)); } + + set + { + if (ShowCheckBox != value) + { + SetState(Cs.ShowCheckBox, value); + + NeedsMeasured = true; + + OnPropertyChangedEx("ShowCheckBox", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowTreeButton + + /// + /// Gets or sets whether expand / collapse + /// buttons are shown if the row contains nested items + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Tree expand / collapse buttons are shown if the row contains nested items.")] + public bool ShowTreeButton + { + get { return (TestState(Cs.ShowTreeButton)); } + + set + { + if (ShowTreeButton != value) + { + SetState(Cs.ShowTreeButton, value); + + OnPropertyChangedEx("ShowTreeButton", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Constructors + + /// + /// GridContainer + /// + protected GridContainer() + { + SetState(Cs.ShowCheckBox, true); + SetState(Cs.ShowTreeButton, true); + } + + #endregion + + #region Internal properties + + #region CanModify + + internal virtual bool CanModify + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.ReadOnly == true) + return (false); + } + + return (ReadOnly == false && IsDeleted == false); + } + } + + #endregion + + #region CheckBoxBounds + + internal Rectangle CheckBoxBounds + { + get { return (_CheckBoxBounds); } + set { _CheckBoxBounds = value; } + } + + #endregion + + #region ContainerBounds + + internal Rectangle ContainerBounds + { + get { return (_ContainerBounds); } + set { _ContainerBounds = value; } + } + + #endregion + + #region DisplayedCellRanges + + internal List DisplayedCellRanges + { + get { return (_DisplayedCellRanges); } + set { _DisplayedCellRanges = value; } + } + + #endregion + + #region DisplayedMergeLayoutCount + + internal int DisplayedMergeLayoutCount + { + get { return (_DisplayedMergeLayoutCount); } + set { _DisplayedMergeLayoutCount = value; } + } + + #endregion + + #region FixedHeaderHeight + + /// + /// Get or sets the FixedHeaderHeight + /// + internal int FixedHeaderHeight + { + get { return (_FixedHeaderHeight); } + set { _FixedHeaderHeight = value; } + } + + #endregion + + #region FixedRowHeight + + /// + /// Get or sets the FixedRowHeight + /// + internal int FixedRowHeight + { + get { return (_FixedRowHeight); } + set { _FixedRowHeight = value; } + } + + #endregion + + #region HasCheckBox + + internal bool HasCheckBox + { + get + { + GridPanel ppanel = GetParentPanel(); + + if (ppanel != null) + { + if (ppanel.CheckBoxes != true) + return (false); + } + + return (ShowCheckBox); + } + } + + #endregion + + #region HasVisibleItems + + internal bool HasVisibleItems + { + get { return (TestState(Cs.HasVisibleItems)); } + set { SetState(Cs.HasVisibleItems, value); } + } + + #endregion + + #region IndentLevel + + /// + /// Get or sets the panel indent level + /// + internal int IndentLevel + { + get { return (_IndentLevel); } + set { _IndentLevel = value; } + } + + #endregion + + #region IsActiveRow + + internal bool IsActiveRow + { + get + { + GridPanel panel = GridPanel; + + return (panel.ActiveRow != null && + panel.ActiveRow.GridIndex == GridIndex); + } + } + + #endregion + + #region IsDeletedEx + + internal bool IsDeletedEx + { + get { return (TestState(Cs.Deleted)); } + set { IsDeleted = value; } + } + + #endregion + + #region IsMergeSuspended + + internal bool IsMergeSuspended + { + get { return (_SuspendedRange != null); } + } + + #endregion + + #region MaxRowIndex + + internal int MaxRowIndex + { + get + { + GridPanel panel = this as GridPanel; + + if (panel != null && panel.VirtualMode == true) + return (panel.VirtualRowCountEx - 1); + + return (Rows.Count - 1); + } + } + + #endregion + + #region MergeUpdateCount + + internal ushort MergeUpdateCount + { + get { return (_MergeUpdateCount); } + set { _MergeUpdateCount = value; } + } + + #endregion + + #region MergeScan + + internal MergeScan MergeScan + { + get + { + if (_MergeScan == null) + _MergeScan = new MergeScan(this); + + return (_MergeScan); + } + + set { _MergeScan = value; } + } + + #endregion + + #region MouseOverElement + + internal GridElement MouseOverElement + { + get { return (_MouseOverElement); } + } + + #endregion + + #region NeedMergeLayout + + internal bool NeedMergeLayout + { + get { return (_NeedMergeLayout); } + set { _NeedMergeLayout = value; } + } + + #endregion + + #region Selected + + internal bool Selected + { + get + { + if (AllowSelection == false) + return (false); + + GridPanel panel = GetParentPanel(); + + if (panel != null) + { + if (_SelectionClearCount != panel.SelectionClearCount) + { + _SelectionClearCount = panel.SelectionClearCount; + + Selected = false; + + if (ExpandedVisible(panel) == true) + panel.SetSelectedEx(this, false); + + InvalidateRender(); + } + } + + return (TestState(Cs.Selected)); + } + + set + { + SetState(Cs.Selected, value); + + GridPanel panel = GetParentPanel(); + + if (panel != null) + _SelectionClearCount = panel.SelectionClearCount; + } + } + + #endregion + + #region SelectionClearCount + + internal ushort SelectionClearCount + { + get { return (_SelectionClearCount); } + set { _SelectionClearCount = value; } + } + + #endregion + + #region SuspendedRange + + /// + /// Get or sets the current suspended range + /// + internal CellRange SuspendedRange + { + get { return (_SuspendedRange); } + set { _SuspendedRange = value; } + } + + #endregion + + #endregion + + #region TestState + + private bool TestState(Cs state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(Cs state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #region GetVisibleItemCount + + internal int GetVisibleItemCount() + { + int n = 0; + + if (Expanded == true) + { + foreach (GridElement item in Rows) + { + if (item.Visible == true) + { + n++; + + GridContainer row = item as GridContainer; + + if (row != null) + { + if (row.Rows.Count > 0 && row.Expanded == true) + n += row.GetVisibleItemCount(); + } + } + } + } + + return (n); + } + + #endregion + + #region GetNextItem + + internal GridContainer GetNextItem() + { + GridContainer container = Parent as GridContainer; + + if (container != null) + { + GridPanel panel = container as GridPanel; + + if (panel != null && panel.VirtualMode == true) + { + GridRow row = this as GridRow; + + if (row != null) + { + int n = row.GridIndex + 1; + + if (n < panel.VirtualRowCountEx) + return (panel.VirtualRows[n]); + } + } + else + { + int index = RowIndex; + + if (index >= 0) + { + for (int i = index + 1; i < container.Rows.Count; i++) + { + GridContainer item = container.Rows[i] as GridContainer; + + if (item != null && item.Visible == true) + return (item); + } + } + } + } + + return (null); + } + + #endregion + + #region GetPrevItem + + internal GridContainer GetPrevItem() + { + GridContainer container = Parent as GridContainer; + + if (container != null) + { + GridPanel panel = container as GridPanel; + + if (panel != null && panel.VirtualMode == true) + { + GridRow row = this as GridRow; + if (row != null) + { + int n = row.GridIndex - 1; + + if (n >= 0) + return (panel.VirtualRows[n]); + } + } + else + { + for (int i = Index - 1; i >= 0; i--) + { + GridContainer item = container.Rows[i] as GridContainer; + + if (item != null && item.Visible == true) + return (item); + } + } + } + + return (null); + } + + #endregion + + #region FindGridPanel + + /// + /// Finds the GridPanel with the given Name. + /// Only the root Rows collection is searched. + /// + ///GridPanel, or null if not found. + public GridPanel FindGridPanel(string name) + { + return (FindGridPanel(name, false)); + } + + /// + /// Finds the GridPanel with the given Name. + /// Nested Rows are searched if 'includeNested' is true. + /// + ///Name to search + ///Whether to include nested rows in the search. + ///GridPanel, or null if not found. + public GridPanel FindGridPanel(string name, bool includeNested) + { + GridItemsCollection items = Rows; + + foreach (GridElement item in items) + { + GridPanel panel = item as GridPanel; + + if (panel != null) + { + if (panel.Name != null && panel.Name.Equals(name)) + return (panel); + } + } + + if (includeNested == true) + { + foreach (GridElement item in items) + { + GridContainer container = item as GridContainer; + + if (container != null) + { + GridPanel panel = container.FindGridPanel(name, true); + + if (panel != null) + return (panel); + } + } + } + + return (null); + } + + #endregion + + #region SetExpanded + + private void SetExpanded(bool value, ExpandSource source) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + panel.FlushActiveRow(); + + if (Expanded == false) + { + bool dynanic = RowsUnresolved; + + if (SuperGrid == null || + SuperGrid.DoBeforeExpandEvent(panel, this, source) == false) + { + ProcessExpandChange(panel, value); + + if (dynanic == true && RowsUnresolved == false) + { + if (panel.SortColumns.Count > 0) + panel.NeedsSorted = true; + } + + if (SuperGrid != null) + SuperGrid.DoAfterExpandEvent(panel, this, source); + } + } + else + { + if (SuperGrid == null || + SuperGrid.DoBeforeCollapseEvent(panel, this, source) == false) + { + ProcessExpandChange(panel, value); + + if (SuperGrid != null) + SuperGrid.DoAfterCollapseEvent(panel, this, source); + } + } + } + else + { + SetState(Cs.Expanded, value); + } + } + + #region ProcessExpandChange + + private void ProcessExpandChange(GridPanel panel, bool value) + { + if (value == true) + SetState(Cs.Expanded, true); + + //if (SuperGrid.IsUpdateSuspended == false) + { + int index = GridIndex; + int count = GetVisibleItemCount(); + + panel.ExpandSelectedAtIndex(index + 1, count, value); + + if (value == false) + SetState(Cs.Expanded, false); + + if (Parent is GridContainer) + ((GridContainer)Parent).InvalidateMerge(); + } + //else + //{ + // if (value == false) + // SetState(Cs.Expanded, false); + //} + + panel.ExpandedUpdateCount++; + } + + #endregion + + #endregion + + #region ExpandItemTree + + /// + /// Expands the entire tree, as necessary, to display the given row. + /// + /// 'true' if any expanding was actually performed + public bool ExpandItemTree() + { + GridContainer row = Parent as GridContainer; + + bool expandChanged = false; + + while (row != null) + { + if (row is GridRow || row is GridGroup) + { + if (row.Expanded == false) + { + if (row.Rows.Count > 0 || row.RowsUnresolved == true) + { + row.Expanded = true; + + expandChanged = true; + } + } + } + + row = row.Parent as GridContainer; + } + + return (expandChanged); + } + + #endregion + + #region ExpandAll + + /// + /// Expands all rows in the Rows collection. + /// + public void ExpandAll() + { + ExpandAll(-1, true); + } + + /// + /// Expands all rows in the Rows collection to the provided depth. + /// + /// If a depth is provided, then rows will be expanded only to the given depth. + /// In other words, to expand only the first level of rows in the container, you would + /// call ExpandAll(0). To expand the first level as well as 2 levels under it, + /// you would call ExpandAll(2). + /// + public void ExpandAll(int depth) + { + ExpandAll(depth, true); + } + + private void ExpandAll(int depth, bool expand) + { + if (Rows.Count > 0) + { + SuperGrid.BeginUpdate(); + + foreach (GridElement item in Rows) + { + GridContainer row = item as GridContainer; + + if (row != null) + { + if (row.Expanded != expand) + row.SetExpanded(expand, ExpandSource.ExpandAll); + + if (depth != 0) + row.ExpandAll(depth - 1, expand); + } + } + + SuperGrid.EndUpdate(); + + InvalidateLayout(); + GridPanel.InvalidateMerge(); + } + } + + #endregion + + #region CollapseAll + + /// + /// Collapses all expanded rows. + /// + public void CollapseAll() + { + ExpandAll(-1, false); + } + + /// + /// Collapses all rows in the Rows collection to the provided depth. + /// + /// If a depth is provided, then rows will be collapsed only to the given depth. + /// In other words, to collapse only the first level of rows in the container, you would + /// call CollapseAll(0). To collapse the first level as well as 2 levels under it, + /// you would call CollapseAll(2). + /// + public void CollapseAll(int depth) + { + ExpandAll(depth, false); + } + + #endregion + + #region SetActive + + /// + /// Makes the given row active + /// + ///true, if successful + public bool SetActive() + { + return (SetActive(false)); + } + + /// + /// Makes the given row active and + /// optionally selects the given row + /// + ///true, if successful + public bool SetActive(bool select) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.SetActiveRow(this) == true) + { + if (select == true) + { + GridPanel.ClearAll(); + + IsSelected = true; + + if (panel.SelectionRowAnchor == null) + panel.SelectionRowAnchor = this; + } + + return (true); + } + } + + return (false); + } + + #endregion + + #region EnsureVisible + + /// + /// This routine will ensure that the row is visible on + /// the screen. If the row is not visible on screen, the + /// view window will be scrolled to make it visible. + /// + ///If 'true', the row will be centered on screen + public override void EnsureVisible(bool center) + { + if (Visible == true) + { + GridPanel panel = GridPanel; + + if (ExpandItemTree() == true || FixedRowHeight <= 0 || panel.IsLayoutValid == false) + SuperGrid.ArrangeGrid(); + + Rectangle t = SViewRect; + Rectangle bounds = BoundsRelative; + + int fixedHeight = FixedRowHeight; + + if (panel.VirtualMode == true) + { + int vrh = Dpi.Height(panel.VirtualRowHeight); + + bounds = panel.BoundsRelative; + + bounds.Y += (panel.FixedRowHeight - (panel.FrozenRowCount * vrh)); + bounds.Y += (GridIndex * vrh); + + fixedHeight = (this is GridRow) ? vrh : 0; + } + + if (fixedHeight >= t.Height || bounds.Y - VScrollOffset < t.Y) + { + int n = bounds.Y - t.Y; + + if (center == false || fixedHeight >= t.Height) + SuperGrid.SetVScrollValue(n); + else + SuperGrid.SetVScrollValue(n - (t.Height - fixedHeight) / 2); + } + else if (bounds.Y - VScrollOffset > t.Bottom - fixedHeight) + { + int n = bounds.Y - (t.Bottom - fixedHeight); + + if (center == false) + SuperGrid.SetVScrollValue(n); + else + SuperGrid.SetVScrollValue(n + (t.Height - fixedHeight) / 2); + } + } + } + + #endregion + + #region ScrollToTop + + /// + /// Scrolls the row to the 'logical' top of the grid display. + /// + public void ScrollToTop() + { + if (Visible == true) + { + if (IsVFrozen == false) + { + if (ExpandItemTree() == true) + SuperGrid.ArrangeGrid(); + + Rectangle t = SViewRect; + Rectangle bounds = BoundsRelative; + + GridPanel panel = GridPanel; + + if (panel.VirtualMode == true) + { + int vrh = Dpi.Height(panel.VirtualRowHeight); + + bounds = panel.BoundsRelative; + + bounds.Y += (panel.FixedRowHeight - (panel.FrozenRowCount * vrh)); + bounds.Y += (GridIndex * vrh); + } + + int n = bounds.Y - t.Y; + + SuperGrid.SetVScrollValue(n); + } + } + } + + #endregion + + #region ScrollToBottom + + /// + /// Scrolls the row to the 'logical' bottom of the grid display. + /// + public void ScrollToBottom() + { + if (Visible == true) + { + if (IsVFrozen == false) + { + ExpandItemTree(); + SuperGrid.ArrangeGrid(); + + Rectangle t = SViewRect; + Rectangle bounds = BoundsRelative; + + GridPanel panel = GridPanel; + + if (panel.VirtualMode == true) + { + int vrh = Dpi.Height(panel.VirtualRowHeight); + + bounds = panel.BoundsRelative; + + bounds.Y += (panel.FixedRowHeight - (panel.FrozenRowCount * vrh)); + bounds.Y += (GridIndex * vrh); + } + + int n = bounds.Y - (t.Bottom) + FixedRowHeight; + + SuperGrid.SetVScrollValue(n); + } + } + } + + #endregion + + #region ExtendSelection + + internal void ExtendSelection( + GridPanel panel, GridContainer endItem, bool extend) + { + if (panel.SelectionRowAnchor != null) + { + int startIndex = panel.SelectionRowAnchor.GridIndex; + int endIndex = endItem.GridIndex; + + panel.NormalizeIndices(false, 0, ref startIndex, ref endIndex); + + if (panel.OnlyRowsSelected(startIndex, endIndex) == false) + { + if (extend == false) + panel.ClearAllSelected(); + else + panel.ClearAll(false); + + panel.SetSelectedRows(startIndex, endIndex - startIndex + 1, true); + + GridContainer row = GetLastProcessedRow(panel); + + if (extend == true && row != null) + { + if (panel.SelectionRowAnchor.GridIndex < endItem.GridIndex) + startIndex = row.GridIndex; + else + endIndex = row.GridIndex; + } + + InvalidateRows(panel, startIndex, endIndex, extend); + } + } + } + + #region GetLastProcessedRow + + private GridContainer GetLastProcessedRow(GridPanel panel) + { + if (panel.LastProcessedItem is GridContainer) + return ((GridContainer)panel.LastProcessedItem); + + if (panel.LastProcessedItem is GridCell) + return (((GridCell)panel.LastProcessedItem).GridRow); + + return (null); + } + + #endregion + + #endregion + + #region InvalidateRows + + internal void InvalidateRows(GridPanel panel, int start, int end, bool extend) + { + if (start > end) + { + int temp = start; + start = end; + end = temp; + } + + start = Math.Max(0, start); + + if (extend == false && panel.FrozenRowCount > 0) + InvalidateRowRange(panel, 0, panel.FirstOnScreenRowIndex); + + InvalidateRowRange(panel, start, end); + } + + #region InvalidateRowRange + + private void InvalidateRowRange(GridPanel panel, int start, int end) + { + Rectangle t = SuperGrid.ClientRectangle; + + GridContainer rs = panel.GetRowFromIndex(start); + GridContainer re = panel.GetRowFromIndex(end); + + if (rs != null && re != null) + { + Rectangle rsRect = rs.Bounds; + Rectangle reRect = re.Bounds; + + if (rs is GridPanel) + rsRect = GetScrollBounds(rs.ContainerBounds); + + if (re is GridPanel) + reRect = GetScrollBounds(re.ContainerBounds); + + Rectangle r = new Rectangle(rsRect.X, rsRect.Y, + reRect.Width, reRect.Bottom - rsRect.Y); + + if (r.IntersectsWith(t) == true) + panel.InvalidateRender(r); + + if (rs is GridRow) + rs.InvalidateRender(); + + if (re != rs && re is GridRow) + re.InvalidateRender(); + } + } + + #region GetScrollBounds + + private Rectangle GetScrollBounds(Rectangle r) + { + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + return (r); + } + + #endregion + + #endregion + + #endregion + + #region MeasureSubItems + + /// + /// MeasureSubItems + /// + /// + /// + /// + /// + protected Size MeasureSubItems( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + Size sizeNeeded = Size.Empty; + GridPanel panel = stateInfo.GridPanel; + + HasVisibleItems = false; + + GridItemsCollection items = Rows; + foreach (GridElement item in items) + { + if (item.Visible == true) + { + Size size; + GridPanel ipanel = item as GridPanel; + + if (ipanel != null) + { + int n = GetRowIndent(panel, ipanel); + + Rectangle r = layoutInfo.ClientBounds; + r.Inflate((panel.ShowDropShadow ? -5 : 0) - n, 0); + + GridLayoutInfo itemLayoutInfo = new GridLayoutInfo(layoutInfo.Graphics, r); + GridLayoutStateInfo itemStateInfo = new GridLayoutStateInfo(ipanel, 0); + + item.Measure(itemLayoutInfo, itemStateInfo, Size.Empty); + size = item.Size; + + size.Width += n; + size.Height += Dpi.Height(panel.LevelIndentSize.Height * 2); + } + else + { + item.Measure(layoutInfo, stateInfo, constraintSize); + size = item.Size; + } + + sizeNeeded.Width = Math.Max(sizeNeeded.Width, size.Width); + sizeNeeded.Height += size.Height; + + HasVisibleItems = true; + } + } + + return (sizeNeeded); + } + + #endregion + + #region ArrangeSubItems + + /// + /// ArrangeSubItems + /// + /// + /// + /// + protected void ArrangeSubItems(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + Rectangle bounds = layoutBounds; + + GridPanel panel = stateInfo.GridPanel; + int indentLevel = stateInfo.IndentLevel; + + GridItemsCollection items = Rows; + foreach (GridElement item in items) + { + if (item.Visible == true) + { + bounds.Height = item.Size.Height; + + GridPanel ipanel = item as GridPanel; + + if (ipanel != null) + { + ipanel.IndentLevel = indentLevel; + + Rectangle r = layoutBounds; + r.Y = bounds.Y; + r.Height = bounds.Height + Dpi.Height(panel.LevelIndentSize.Height * 2); + + ipanel.ContainerBounds = r; + + int n = GetRowIndent(panel, ipanel); + + r.X = layoutBounds.X + n; + r.Y += Dpi.Height(panel.LevelIndentSize.Height); + + if (ipanel.ShowDropShadow == true) + r.Y--; + + r.Width = ipanel.BoundsRelative.Width; + r.Height -= Dpi.Height(panel.LevelIndentSize.Height * 2); + + ArrangeCheckBox(panel, ipanel, r); + + stateInfo.GridPanel = ipanel; + stateInfo.IndentLevel = 0; + + item.Arrange(layoutInfo, stateInfo, r); + + bounds.Y += Dpi.Height(panel.LevelIndentSize.Height * 2); + } + else + { + stateInfo.GridPanel = panel; + stateInfo.IndentLevel = indentLevel; + + item.Arrange(layoutInfo, stateInfo, bounds); + } + + bounds.Y += item.Size.Height; + } + else + { + item.BoundsRelative = bounds; + } + } + } + + #region ArrangeCheckBox + + private void ArrangeCheckBox( + GridPanel panel, GridPanel ipanel, Rectangle r) + { + if (ipanel.HasCheckBox == true) + { + int k = Math.Max( + Dpi.Width(panel.CheckBoxSize.Width + 3), + Dpi.Height(panel.CheckBoxSize.Height+ 3)); + + r.X -= k; + r.Width = Dpi.Width(panel.CheckBoxSize.Width); + + r.Y += (r.Height - Dpi.Height(panel.CheckBoxSize.Height)) / 2; + r.Height = Dpi.Height(panel.CheckBoxSize.Height); + + ipanel.CheckBoxBounds = r; + } + else + { + ipanel.CheckBoxBounds = Rectangle.Empty; + } + } + + #endregion + + #endregion + + #region GetRowIndent + + /// + /// GetRowIndent + /// + /// + /// + /// + protected int GetRowIndent(GridPanel panel, GridPanel ipanel) + { + int indentLevel = 0; + + GridContainer container = ipanel.Parent as GridContainer; + + if (container != null) + indentLevel = container.IndentLevel + 1; + + int n = 0; + + if (panel.ShowRowHeaders == true) + n += panel.RowHeaderWidthEx; + + if (panel.CheckBoxes == true) + { + n += Math.Max( + Dpi.Width(ipanel.CheckBoxSize.Width + 3), + Dpi.Height(ipanel.CheckBoxSize.Height + 3)); + } + + if (panel.PrimaryColumn != null && + panel.PrimaryColumn.Visible == true) + { + if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true) + n += panel.TreeButtonIndent; + + n += Dpi.Width(panel.LevelIndentSize.Width * indentLevel); + + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (index == panel.PrimaryColumnIndex) + break; + + if (column.Visible == true) + n += column.Size.Width; + } + } + else + { + n += 3; + } + + return (n); + } + + #endregion + + #region GetParentPanel + + /// + /// Gets the Parent GridPanel for the item. + /// + ///GridPanel or null + public GridPanel GetParentPanel() + { + GridElement parent = Parent; + + while (parent != null) + { + if (parent is GridPanel) + return ((GridPanel)parent); + + parent = parent.Parent; + } + + return (null); + } + + #endregion + + #region InvalidateRowHeader + + internal void InvalidateRowHeader() + { + InvalidateRowHeader(this); + } + + internal void InvalidateRowHeader(GridContainer row) + { + if (row != null) + { + GridPanel panel = row.GetParentPanel(); + + if (panel != null) + { + if (panel.ShowRowHeaders == true) + { + Rectangle bounds = panel.BoundsRelative; + + if (panel.IsSubPanel == true) + bounds.X -= HScrollOffset; + + bounds.Y = row.ContainerBounds.Y; + + if (row.IsVFrozen == false) + bounds.Y -= VScrollOffset; + + bounds.Width = panel.RowHeaderWidthEx; + bounds.Height = row.ContainerBounds.Height; + + InvalidateRender(bounds); + } + } + } + } + + #endregion + + #region InvalidateMerge + + /// + /// Invalidates the merge state of the container. + /// + public void InvalidateMerge() + { + MergeUpdateCount++; + NeedMergeLayout = true; + + ResumeMerge(); + + InvalidateLayout(); + } + + #endregion + + #region Mouse Handling + + #region InternalMouseLeave + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal override void InternalMouseLeave(EventArgs e) + { + GridElement mouseOverElement = _MouseOverElement; + + if (mouseOverElement != null) + { + mouseOverElement.InternalMouseLeave(e); + _MouseOverElement = null; + } + + base.InternalMouseLeave(e); + } + + #endregion + + #region InternalMouseMove + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal override void InternalMouseMove(MouseEventArgs e) + { + GridElement element = GetElementAt(e); + + if (element != _MouseOverElement) + { + GridElement mouseOverElement = _MouseOverElement; + + if (mouseOverElement != null) + mouseOverElement.InternalMouseLeave(e); + + if (element != null) + element.InternalMouseEnter(e); + + _MouseOverElement = element; + } + + if (element != null) + element.InternalMouseMove(e); + + base.InternalMouseMove(e); + } + + #endregion + + #region InternalMouseHover + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal override void InternalMouseHover(EventArgs e) + { + GridElement mouseOverElement = _MouseOverElement; + + if (mouseOverElement != null) + mouseOverElement.InternalMouseHover(e); + + base.InternalMouseHover(e); + } + + #endregion + + #region InternalMouseClick + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal override void InternalMouseClick(MouseEventArgs e) + { + GridElement mouseOverElement = _MouseOverElement; + + if (mouseOverElement == null) + InternalMouseMove(e); + + mouseOverElement = _MouseOverElement; + + if (mouseOverElement != null) + mouseOverElement.InternalMouseClick(e); + + base.InternalMouseClick(e); + } + + #endregion + + #region InternalMouseDoubleClick + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal override void InternalMouseDoubleClick(MouseEventArgs e) + { + GridElement mouseOverElement = _MouseOverElement; + + if (mouseOverElement != null) + mouseOverElement.InternalMouseDoubleClick(e); + + base.InternalMouseDoubleClick(e); + } + + #endregion + + #region InternalMouseDown + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal override void InternalMouseDown(MouseEventArgs e) + { + GridElement mouseOverElement = _MouseOverElement; + + if (mouseOverElement == null) + { + MouseEventArgs e2 = new + MouseEventArgs(MouseButtons.None, 0, e.X, e.Y, e.Delta); + + InternalMouseMove(e2); + + mouseOverElement = _MouseOverElement; + } + + if (mouseOverElement != null) + mouseOverElement.InternalMouseDown(e); + + base.InternalMouseDown(e); + } + + #endregion + + #region InternalMouseUp + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal override void InternalMouseUp(MouseEventArgs e) + { + GridElement mouseOverElement = _MouseOverElement; + + if (mouseOverElement != null) + mouseOverElement.InternalMouseUp(e); + + base.InternalMouseUp(e); + } + + #endregion + + #endregion + + #region GetElementAt + + /// + /// Returns element at specified mouse coordinates. + /// + /// Mouse event arguments + /// Reference to child element or null if no element at specified coordinates + public virtual GridElement GetElementAt(MouseEventArgs e) + { + return GetElementAt(e.X, e.Y); + } + + /// + /// Returns element at specified mouse coordinates. + /// + /// Horizontal position + /// Vertical position + /// Reference to child element or null if no element at specified coordinates + public virtual GridElement GetElementAt(int x, int y) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle t = CViewRect; + Rectangle bounds = Rectangle.Empty; + + if (t.Contains(x, y) == true) + { + if (this is GridPanel || Expanded == true) + { + GridItemsCollection items = Rows; + for (int i = 0; i < items.Count; i++) + { + GridElement item = items[i]; + + if (item.IsVFrozen == false) + break; + + if (IsElementAt(item, x, y, ref bounds) == true) + return (item); + + if (bounds.Y > t.Bottom) + break; + } + + for (int i = FirstOnScreenRowIndex; i < items.Count; i++) + { + GridElement item = items[i]; + + if (IsElementAt(item, x, y, ref bounds) == true) + { + GridGroup grp = item as GridGroup; + + if (grp != null) + { + item = grp.GetElementAt(x, y); + + if (item == null) + return (grp); + } + + return (item); + } + + if (bounds.Y > y) + break; + } + } + } + } + + return (null); + } + + private bool IsElementAt( + GridElement item, int x, int y, ref Rectangle bounds) + { + if (item.Visible == true) + { + bounds = item.BoundsRelative; + + if (item.Visible == true) + { + if (item is GridPanel) + bounds = ((GridPanel)item).ContainerBounds; + + bounds.X -= HScrollOffset; + + if (item.IsVFrozen == false) + bounds.Y -= VScrollOffset; + + if (bounds.Contains(x, y)) + return (true); + } + } + + return (false); + } + + #endregion + + #region InternalGetElementAt + + internal GridElement InternalGetElementAt(MouseEventArgs e) + { + return (GetElementAt(e.X, e.Y)); + } + + internal GridElement InternalGetElementAt(int x, int y) + { + return (GetElementAt(x, y)); + } + + #endregion + + #region CanSetActiveRow + + internal bool CanSetActiveRow(bool beep) + { + return (CanSetActiveRow(GridPanel, this, beep)); + } + + internal bool CanSetActiveRow( + GridPanel panel, GridContainer row, bool beep) + { + if (row == null || row.AllowSelection == false) + { + if (beep == true) + { + if (SuperGrid.DoPlayingSoundEvent(panel, row, PlaySoundContext.RowActivate) == false) + SystemSounds.Beep.Play(); + } + + return (false); + } + + if (row.IsActive == false) + { + GridContainer parent = row.Parent as GridContainer; + + if (parent != null) + { + if ((uint)row.RowIndex > parent.MaxRowIndex) + return (false); + + if (panel.SelectionGranularity != SelectionGranularity.Cell) + { + GridContainer cont = Parent as GridContainer; + + if (cont != null) + { + CellRange cr = cont.SuspendedRange; + + if (cr != null && (RowIndex < cr.RowStart || RowIndex > cr.RowEnd)) + cont.ResumeMerge(); + } + } + + return (SuperGrid.DoRowActivatingEvent(panel, SuperGrid.ActiveRow, row) != true); + } + } + + return (row.IsActive); + } + + #endregion + + #region FlushRow + + internal virtual void FlushRow() + { + } + + #endregion + + #region PurgeDeletedRows + + /// + /// Purges all rows marked as 'deleted'. Once rows are purged + /// they cannot be restored. + /// + public void PurgeDeletedRows() + { + PurgeDeletedRows(true); + } + + /// + /// Purges all rows marked as 'deleted'. Once rows are purged + /// they cannot be restored. + /// + ///Determines whether nested rows are also purged. + public void PurgeDeletedRows(bool includeNestedRows) + { + GridPanel panel = GridPanel; + + PurgeDeletedRowsEx(includeNestedRows, panel.IsDeleted); + } + + private void PurgeDeletedRowsEx(bool includeNestedRows, bool isDeleted) + { + GridPanel panel = GridPanel; + + if (SuperGrid.DoRowsPurgingEvent(this, ref includeNestedRows) == false) + { + if (panel.DeletedRowCount > 0) + { + if (panel.ActiveRow != null) + panel.SelectActiveRow = true; + } + + if (panel.VirtualMode == true) + PurgeVirtualDeletedRows(panel); + else + PurgeRealDeletedRows(panel, includeNestedRows, isDeleted); + + SuperGrid.DoRowsPurgedEvent(this); + } + } + + + #region PurgeVirtualDeletedRows + + private void PurgeVirtualDeletedRows(GridPanel panel) + { + SelectedElements sec = panel.InternalDeletedRows; + + if (sec != null && sec.Count > 0) + { + int offset = 0; + int topIndex = 0; + + int activeIndex = + (panel.ActiveRow != null) ? panel.ActiveRow.RowIndex : -1; + + int count = sec.Count; + int index = sec.LastIndex + 1; + + try + { + while (sec.GetPrevIndex(ref index) == true) + { + GridRow row = panel.VirtualRows[index]; + + topIndex = row.RowIndex - 1; + + if (row.RowIndex < activeIndex) + offset++; + + panel.DataBinder.RemoveRow(row); + } + + sec.Clear(); + } + finally + { + panel.VirtualRowCount -= count; + panel.VirtualRows.MaxRowIndex = topIndex; + } + + if (offset > 0) + { + panel.LatentActiveRowIndex = activeIndex - offset; + panel.LatentActiveContainer = this; + } + } + } + + #endregion + + #region PurgeRealDeletedRows + + private void PurgeRealDeletedRows( + GridPanel panel, bool includeNestedRows, bool isDeleted) + { + if (panel.ActiveRow != null) + { + if (panel.ActiveRow.IsDeleted == true) + { + if (panel.VirtualMode == false) + { + GridContainer cont = panel.ActiveRow.Parent as GridContainer; + + if (cont != null) + { + panel.ActiveRow = cont.GetNextLocalItem(panel.ActiveRow.RowIndex); + + panel.SuperGrid.ActiveElement = panel.ActiveRow; + } + } + } + } + + PurgeRealDeletedRowsEx(panel.Rows, includeNestedRows, isDeleted); + } + + #region PurgeRealDeletedRowsEx + + private void PurgeRealDeletedRowsEx( + GridItemsCollection rows, bool includeNestedRows, bool isDeleted) + { + for (int i = rows.Count - 1; i >= 0; i--) + { + GridContainer row = rows[i] as GridContainer; + + if (row != null) + { + bool rowDeleted = (isDeleted | row.IsDeleted); + + if (includeNestedRows == true) + { + if (row.Rows.Count > 0) + { + if (row is GridPanel) + row.PurgeDeletedRowsEx(true, rowDeleted); + else + row.PurgeRealDeletedRowsEx(row.Rows, true, rowDeleted); + } + } + + if (rowDeleted == true) + { + row.IsDeleted = false; + + rows.RemoveAt(i); + } + } + } + } + + #endregion + + #endregion + + #region GetNextLocalItem + + internal GridContainer GetNextLocalItem(int index) + { + GridPanel panel = GridPanel; + + index = GetNextLocalItemIndex(index); + + if (panel.VirtualMode == true) + { + if ((uint)index < panel.VirtualRowCount) + return (panel.VirtualRows[index]); + } + else + { + if ((uint) index < Rows.Count) + return (Rows[index] as GridContainer); + } + + return (null); + } + + #endregion + + #region GetNextLocalItemIndex + + private int GetNextLocalItemIndex(int index) + { + if (GridPanel.VirtualMode == true) + return (GetNextLocalVirtualItemIndex(index)); + + return (GetNextLocalRealItemIndex(index)); + } + + #region GetNextLocalRealItemIndex + + internal int GetNextLocalRealItemIndex(int index) + { + if (Rows.Count > 0 && index >= 0) + { + if (index >= Rows.Count) + index = Rows.Count - 1; + + for (int i = index + 1; i < Rows.Count; i++) + { + GridContainer item = Rows[i] as GridContainer; + + if (item != null && item.Visible == true && item.IsDeleted == false) + return (i); + } + + for (int i = index - 1; i >= 0; i--) + { + GridContainer item = Rows[i] as GridContainer; + + if (item != null && item.Visible == true && item.IsDeleted == false) + return (i); + } + } + + return (-1); + } + + #endregion + + #region GetNextLocalVirtualItemIndex + + internal int GetNextLocalVirtualItemIndex(int index) + { + GridPanel panel = GridPanel; + + if (panel.VirtualRowCount > 0 && index >= 0) + { + if (index >= panel.VirtualRowCount) + index = panel.VirtualRowCount - 1; + + for (int i = index + 1; i < panel.VirtualRowCount; i++) + { + GridContainer item = panel.VirtualRows[i]; + + if (item != null && item.IsDeleted == false) + return (i); + } + + for (int i = index - 1; i >= 0; i--) + { + GridContainer item = panel.VirtualRows[i]; + + if (item != null && item.IsDeleted == false) + return (i); + } + } + + return (-1); + } + + #endregion + + #endregion + + #endregion + + #region DetachNestedRows + + internal void DetachNestedRows(bool dispose) + { + DetachNestedRows(this, dispose); + } + + private void DetachNestedRows(GridContainer cont, bool dispose) + { + cont.MergeScan = null; + + if (dispose == true) + { + if (cont is GridPanel) + { + ((GridPanel)cont).DataBinder.Dispose(); + ((GridPanel)cont).DataBinder = null; + } + } + + if (cont is GridRow) + DetachGridRow((GridRow)cont); + + if (cont.Rows.Count > 0) + { + foreach (GridContainer row in cont.Rows) + { + if (row != null) + DetachNestedRows(row, dispose); + } + } + + if (SuperGrid != null) + { + if (SuperGrid.ActiveRow == cont) + SuperGrid.ActiveRow = null; + } + + if (cont.GridPanel != null) + { + if (cont.GridPanel.ActiveRow == cont) + cont.GridPanel.ActiveRow = null; + } + } + + private void DetachGridRow(GridRow row) + { + foreach (GridCell cell in row.Cells) + { + cell.EditControl = null; + cell.RenderControl = null; + } + + //row.DataItem = null; + //row.DataItemIndex = -1; + } + + #endregion + + #region UpdateMergeFlags + + internal void UpdateMergeFlags() + { + GridPanel panel = GridPanel; + + if (panel.EnableCellMerging == true) + DisplayedCellRanges = MergeScan.GetScanItems(); + else + DisplayedCellRanges = null; + + _LastCellRange = null; + } + + #endregion + + #region GetCellRange + + internal CellRange GetCellRange(GridCell cell) + { + if (DisplayedCellRanges != null) + { + int index = cell.GridPanel.Columns.GetDisplayIndex(cell.GridColumn); + + if (_LastCellRange != null) + { + if (_LastCellRange.Contains(cell.RowIndex, index)) + return (_LastCellRange); + } + + foreach (CellRange cr in DisplayedCellRanges) + { + if (cr.Contains(cell.RowIndex, index)) + { + _LastCellRange = cr; + + return (cr); + } + } + } + + return (null); + } + + #endregion + + #region SuspendMerge + + /// + ///Temporarily suspends the merged display of the + ///cells in the given CellRange. + /// + ///CellRange to temporarily suspend + public void SuspendMerge(CellRange cr) + { + if (cr != null && cr.Suspended == false) + { + ResumeMerge(); + + if (cr.AllowSuspend == true) + { + cr.Suspended = true; + + InvalidateRender(cr.BackBounds); + } + } + + _SuspendedRange = cr; + } + + #endregion + + #region ResumeMerge + + /// + ///Resumes merged display of any current, temporarily + ///suspended CellRange. + /// + public void ResumeMerge() + { + CellRange cr = _SuspendedRange; + _SuspendedRange = null; + + if (cr != null && cr.Suspended == true) + { + cr.Suspended = false; + + if (cr.Modified == true) + { + UpdateCellResumeState(cr); + + cr.Modified = false; + + NeedMergeLayout = true; + + InvalidateLayout(); + } + + GridPanel.SelectionUpdateCount++; + + InvalidateRender(cr.BackBounds); + } + } + + #region UpdateCellResumeState + + private void UpdateCellResumeState(CellRange cr) + { + ushort n = MergeUpdateCount; + + GridPanel panel = GridPanel; + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + + for (int i = cr.RowStart; i < cr.RowEnd; i++) + { + for (int j = cr.ColumnStart; j < cr.ColumnEnd; j++) + { + GridCell cell = GetCell(i, map[j]); + + if (cell != null && cell.Modified == true) + { + cell.MergeUpdateCount = --n; + cell.Modified = false; + } + } + } + } + + #endregion + + #endregion + + #region SetMergeSelection + + internal void SetMergeSelection(int startRowIndex, + int endRowIndex, int startColumnIndex, int endColumnIndex, int selected) + { + List cellRanges = DisplayedCellRanges; + + if (cellRanges != null) + { + GridPanel panel = GridPanel; + + foreach (CellRange cr in cellRanges) + { + if (cr.RowStart <= endRowIndex && cr.RowEnd > startRowIndex && + cr.ColumnStart <= endColumnIndex && cr.ColumnEnd > startColumnIndex) + { + cr.SelectionUpdateCount = panel.SelectionUpdateCount - 1; + + InvalidateRender(cr.BackBounds); + } + } + } + } + + #endregion + + #region ClearAllMergeSelected + + internal virtual void ClearAllMergeSelected() + { + GridPanel panel = GridPanel; + List ranges = DisplayedCellRanges; + + if (ranges != null) + { + foreach (CellRange range in ranges) + range.SelectionUpdateCount = panel.SelectionUpdateCount - 1; + } + + foreach (GridContainer row in Rows) + { + if (row != null) + row.ClearAllMergeSelected(); + } + } + + #endregion + + #region ResolveRows + + /// + /// Resolves the row if marked as RowsUnresolved. + /// + public void ResolveRow() + { + ResolveRow(GridPanel, false); + } + + /// + /// Resolves the row if marked as RowsUnresolved. If includeNested + /// is true, then all RowsUnresolved sub-Rows are also resolved. + /// + /// + public void ResolveRow(bool includeNested) + { + ResolveRow(GridPanel, includeNested); + } + + internal void ResolveRow(GridPanel panel, bool includeNested) + { + panel.DataBinder.ResolveRow(this); + + if (includeNested == true) + ResolveRows(true); + } + + /// + /// Resolves all rows marked as RowsUnresolved. + /// + /// + public void ResolveRows(bool includeNested) + { + if (Rows.Count > 0) + { + GridPanel panel = GridPanel; + + foreach (GridContainer row in Rows) + { + if (row != null) + row.ResolveRow(panel, includeNested); + } + } + } + + #endregion + + #region Style support routines + + #region OnStyleChanged + + private void OnStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + UpdateChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #endregion + + #region UpdateChangeHandler + + private void UpdateChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + NeedsMeasured = true; + + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// StyleChanged + /// + /// + /// + protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) + { + if (SuperGrid != null) + SuperGrid.UpdateStyleCount(); + + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + if (changeType == VisualChangeType.Layout) + { + NeedsMeasured = true; + + InvalidateLayout(); + } + else + { + if (SuperGrid != null) + InvalidateRender(); + } + } + + #endregion + + #region GetEffectiveRowStyle + + /// + /// Gets the 'Effective' row style for the row. The + /// 'Effective' Style is the cached summation of SuperGrid, + /// Panel, Row, and Alternate Row styles. It is the Style + /// that is used to render each row element for the row. + /// + ///RowVisualStyle + public RowVisualStyle GetEffectiveRowStyle() + { + return (GetEffectiveRowStyle(this)); + } + + internal RowVisualStyle GetEffectiveRowStyle(GridContainer item) + { + StyleState rowState = GetRowState(item); + + return (GetEffectiveRowStyle(item, rowState)); + } + + internal RowVisualStyle GetEffectiveRowStyle( + GridContainer item, StyleState rowState) + { + return (GetRowStateStyle(item, rowState)); + } + + #region GetRowState + + internal StyleState GetRowState(GridContainer item) + { + StyleState rowState = StyleState.Default; + + if (IsMouseOver == true) + { + Point pt = SuperGrid.PointToClient(Control.MousePosition); + + Rectangle r = (item is GridPanel) + ? item.ContainerBounds + : item.BoundsRelative; + + r.X -= HScrollOffset; + + if (item.IsVFrozen == false) + r.Y -= VScrollOffset; + + Rectangle t = ViewRect; + + r.Intersect(t); + + if (r.Contains(pt) == true) + rowState |= StyleState.MouseOver; + } + + if (item.IsSelected == true) + rowState |= StyleState.Selected; + + return (rowState); + } + + #endregion + + #region GetRowStateStyle + + private RowVisualStyle GetRowStateStyle(GridContainer item, StyleState rowState) + { + ValidateRowStyle(); + + switch (rowState) + { + case StyleState.MouseOver: + return (GetRowStyle(item, StyleType.MouseOver)); + + case StyleState.Selected: + return (GetRowStyle(item, StyleType.Selected)); + + case StyleState.Selected | StyleState.MouseOver: + return (GetRowStyle(item, StyleType.SelectedMouseOver)); + + case StyleState.ReadOnly: + return (GetRowStyle(item, StyleType.ReadOnly)); + + case StyleState.ReadOnly | StyleState.MouseOver: + return (GetRowStyle(item, StyleType.ReadOnlyMouseOver)); + + case StyleState.ReadOnly | StyleState.Selected: + return (GetRowStyle(item, StyleType.ReadOnlySelected)); + + case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: + return (GetRowStyle(item, StyleType.ReadOnlySelectedMouseOver)); + + default: + return (GetRowStyle(item, StyleType.Default)); + } + } + + #endregion + + #region GetRowStyle + + private RowVisualStyle GetRowStyle(GridContainer item, StyleType e) + { + if (_EffectiveRowStyles.IsValid(e) == false) + { + RowVisualStyle style = new RowVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + GridPanel panel = GridPanel; + + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.RowStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.RowStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.RowStyles[cs]); + style.ApplyStyle(item.RowStyles[cs]); + + if (panel != null && panel.UseAlternateRowStyle == true) + { + if ((GridIndex % 2) > 0) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.AlternateRowCellStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.AlternateRowCellStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.AlternateRowCellStyles[cs]); + } + } + + style.ApplyStyle(item.CellStyles[cs]); + style.ApplyStyle(item.CellStyles[cs]); + } + } + + SuperGrid.DoGetRowStyleEvent(this, e, ref style); + + RowHeaderVisualStyle style2 = style.RowHeaderStyle; + SuperGrid.DoGetRowHeaderStyleEvent(this, e, ref style2); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + _EffectiveRowStyles[e] = style; + } + + return (_EffectiveRowStyles[e]); + } + + #endregion + + #endregion + + #region ValidateRowStyle + + private void ValidateRowStyle() + { + if (_EffectiveRowStyles == null || + (_StyleUpdateCount != SuperGrid.StyleUpdateCount)) + { + if (_EffectiveRowStyles != null) + _EffectiveRowStyles.Dispose(); + + _EffectiveRowStyles = new RowVisualStyles(); + + _StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidates the cached Style + ///definition for all defined StyleTypes + /// + public virtual void InvalidateStyle() + { + if (_EffectiveRowStyles != null) + { + _EffectiveRowStyles.Dispose(); + _EffectiveRowStyles = null; + } + + InvalidateLayout(); + } + + /// + ///Invalidate the cached Style + ///definition for the given StyleType + /// + /// + public void InvalidateStyle(StyleType type) + { + if (_EffectiveRowStyles != null) + { + if (_EffectiveRowStyles[type] != null) + { + _EffectiveRowStyles[type].Dispose(); + _EffectiveRowStyles[type] = null; + + InvalidateLayout(); + } + } + } + + #endregion + + #endregion + + #region IsParentOf + + /// + /// Determines whether the row is + /// a parent row of the given container row. + /// + /// + ///true if the row is a parent of the given row. + public bool IsParentOf(GridContainer row) + { + if (row != null) + return (row.IsChildOf(this)); + + return (false); + } + + #endregion + + #region IsChildOf + + /// + /// Determines whether the row is + /// a child row of the given container row. + /// + /// + ///true if the row is a child of the given row. + public bool IsChildOf(GridContainer row) + { + if (row != null) + { + GridContainer parent = Parent as GridContainer; + + while (parent != null) + { + if (parent == row) + return (true); + + parent = parent.Parent as GridContainer; + } + } + + return (false); + } + + #endregion + + #region GetCell + + /// + /// Gets the GridCell for the given row and column index + /// + /// + /// + ///GridCell, or null if not a valid cell + public GridCell GetCell(int rowIndex, int columnIndex) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridRow row = null; + + if (panel.VirtualMode == true) + { + if ((uint)rowIndex < panel.VirtualRowCount) + row = panel.VirtualRows[rowIndex]; + } + else + { + if ((uint) rowIndex < Rows.Count) + row = Rows[rowIndex] as GridRow; + } + + if (row != null && columnIndex < row.Cells.Count) + return (row.Cells[columnIndex]); + } + + return (null); + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + public virtual void Dispose() + { + if (_EffectiveRowStyles != null) + { + _EffectiveRowStyles.Dispose(); + _EffectiveRowStyles = null; + } + + CellStyles = null; + RowStyles = null; + + if (Rows != null && Rows.Count > 0) + { + foreach (GridElement item in Rows) + { + GridContainer row = item as GridContainer; + + if (row != null) + row.Dispose(); + } + } + } + + #endregion + + #region ContainerStates + + [Flags] + private enum Cs + { + Checked = (1 << 0), + Deleted = (1 << 1), + Expanded = (1 << 2), + HasVisibleItems = (1 << 3), + ReadOnly = (1 << 4), + RowsUnresolved = (1 << 5), + Selected = (1 << 6), + ShowCheckBox = (1 << 7), + ShowTreeButton = (1 << 8), + ExpandedVisible = (1 << 9), + } + + #endregion + } + + #region enums + + #region ExpandSource + + /// + /// Operation source resulting in the Expand call + /// + public enum ExpandSource + { + /// + /// Expand operation + /// + Expand, + + /// + /// ExpandAll operation + /// + ExpandAll, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridElement.cs new file mode 100644 index 00000000..e341daba --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridElement.cs @@ -0,0 +1,1126 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Represents the base grid item. + /// + [DesignTimeVisible(false), ToolboxItem(false)] + public abstract class GridElement : Component, INotifyPropertyChanged + { + #region Events + + /// + /// Occurs when display/rendering of the item is invalidated. + /// + public event EventHandler RenderInvalid; + + /// + /// Occurs when layout of the item is invalidated. + /// + public event EventHandler LayoutInvalid; + + /// + /// Occurs when parent of the item has changed. + /// + public event EventHandler ParentChanged; + + #endregion + + #region Static variables + + static Point _mouseDownPoint; + + #endregion + + #region Private variables + + private Es _States; + private Rectangle _BoundsRelative = Rectangle.Empty; + + private GridElement _Parent; + private SuperGridControl _SuperGrid; + private GridPanel _GridPanel; + + private object _Tag; + + #endregion + + #region Constructor + + /// + /// GridElement + /// + protected GridElement() + { + SetState(Es.AllowSelection, true); + SetState(Es.NeedsMeasured, true); + SetState(Es.Visible, true); + } + + #endregion + + #region Abstract methods + + /// + /// Performs the arrange pass layout of the item when + /// the final position and size of the item has been set. + /// + /// Layout information. + /// + /// + protected abstract void ArrangeOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Rectangle layoutBounds); + + /// + /// Performs the layout of the item + /// and sets the Size property to size that item will take. + /// + /// Layout information. + /// + /// + protected abstract void MeasureOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize); + + /// + /// Performs drawing of the item and its children. + /// + /// Holds contextual rendering information. + protected abstract void RenderOverride(GridRenderInfo renderInfo); + + #endregion + + #region Internal properties + + #region Capture + + internal virtual bool Capture + { + get { return (CapturedItem != null); } + + set + { + if (SuperGrid != null) + CapturedItem = (value == true) ? this : null; + } + } + + #endregion + + #region CapturedItem + + internal GridElement CapturedItem + { + get + { + if (SuperGrid != null) + return (SuperGrid.CapturedItem); + + return (null); + } + + set + { + if (SuperGrid != null) + SuperGrid.CapturedItem = value; + } + } + + #endregion + + #region CViewRect + + /// + /// Client View Rectangle + /// + internal Rectangle CViewRect + { + get + { + if (SuperGrid != null) + return (SuperGrid.CViewRect); + + return (Rectangle.Empty); + } + } + + #endregion + + #region HScrollBounds + + /// + /// Horizontal Scroll Bounds + /// + internal Rectangle HScrollBounds + { + get + { + Rectangle r = BoundsRelative; + r.X -= HScrollOffset; + + return (r); + } + } + + #endregion + + #region HScrollOffset + + internal int HScrollOffset + { + get + { + SuperGridControl sgc = SuperGrid; + + return (sgc != null) + ? sgc.HScrollOffset : 0; + } + } + + #endregion + + #region IsMouseDown + + /// + /// Gets whether mouse is down + /// + internal virtual bool IsMouseDown + { + get { return (Control.MouseButtons != MouseButtons.None); } + } + + #endregion + + #region IsVFrozen + + /// + /// IsFrozen + /// + internal bool IsVFrozen + { + get + { + if (SuperGrid != null) + { + GridPanel panel = SuperGrid.PrimaryGrid; + + return (BoundsRelative.Y < panel.FixedRowHeight); + } + + return (false); + } + } + + #endregion + + #region MouseDownPoint + + /// + /// Gets the mouse down Point + /// + internal virtual Point MouseDownPoint + { + get { return (_mouseDownPoint); } + set { _mouseDownPoint = value; } + } + + #endregion + + #region NeedsMeasured + + /// + /// Get or sets whether item needs measured + /// + internal virtual bool NeedsMeasured + { + get { return (TestState(Es.NeedsMeasured)); } + set { SetState(Es.NeedsMeasured, value); } + } + + #endregion + + #region ScrollBounds + + /// + /// Horizontal and Vertical Scroll Bounds + /// + internal Rectangle ScrollBounds + { + get + { + Rectangle r = BoundsRelative; + r.X -= HScrollOffset; + r.Y -= VScrollOffset; + + return (r); + } + } + + #endregion + + #region SViewRect + + /// + /// Scrollable View Rectangle + /// + internal Rectangle SViewRect + { + get + { + if (SuperGrid != null) + return (SuperGrid.SViewRect); + + return (Rectangle.Empty); + } + } + + #endregion + + #region ViewRect + + /// + /// View Rectangle + /// + internal Rectangle ViewRect + { + get + { + if (SuperGrid != null) + return (SuperGrid.ViewRect); + + return (Rectangle.Empty); + } + } + + #endregion + + #region VScrollBounds + + /// + /// Vertical Scroll Bounds + /// + internal Rectangle VScrollBounds + { + get + { + Rectangle r = BoundsRelative; + r.Y -= VScrollOffset; + + return (r); + } + } + + #endregion + + #region VScrollOffset + + internal int VScrollOffset + { + get + { + SuperGridControl cgc = SuperGrid; + + return (cgc != null) + ? cgc.VScrollOffset : 0; + } + } + + #endregion + + #endregion + + #region Public properties + + #region AllowSelection + + /// + /// Gets or sets whether the element can be selected + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the element can be selected")] + public virtual bool AllowSelection + { + get { return (TestState(Es.AllowSelection)); } + + set + { + if (AllowSelection != value) + { + SetState(Es.AllowSelection, value); + + OnPropertyChangedEx("AllowSelection", VisualChangeType.Render); + } + } + } + + #endregion + + #region Bounds + + /// + /// Gets the scroll adjusted bounds + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual Rectangle Bounds + { + get { return (BoundsRelative); } + } + + #endregion + + #region BoundsRelative + + /// + /// Gets or sets the relative bounds of the item. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual Rectangle BoundsRelative + { + get { return (_BoundsRelative); } + internal set { _BoundsRelative = value; } + } + + #endregion + + #region GridPanel + + /// + /// Gets the parent GridPanel + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridPanel GridPanel + { + get { return (GetParentGridPanel()); } + internal set { _GridPanel = value; } + } + + #region GetParentGridPanel + + private GridPanel GetParentGridPanel() + { + if (_GridPanel != null) + return (_GridPanel); + + GridElement parent = this; + + while (parent != null) + { + if (parent is GridPanel) + return ((GridPanel)parent); + + parent = parent.Parent; + } + + return (null); + } + + #endregion + + #endregion + + #region IsLayoutValid + + /// + /// Gets whether layout for the item is valid. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool IsLayoutValid + { + get { return (TestState(Es.LayoutValid)); } + internal set { SetState(Es.LayoutValid, value); } + } + + #endregion + + #region IsMouseOver + + /// + /// Gets whether mouse is over the element. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool IsMouseOver + { + get { return (TestState(Es.MouseOver)); } + internal set { SetState(Es.MouseOver, value); } + } + + #endregion + + #region LocationRelative + + /// + /// Gets or sets the relative location of the item. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Point LocationRelative + { + get { return _BoundsRelative.Location; } + internal set { _BoundsRelative.Location = value; } + } + + #endregion + + #region Parent + + /// + /// Gets or sets the parent of the item. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual GridElement Parent + { + get { return (_Parent); } + + internal set + { + if (_Parent != value) + { + GridElement oldParent = value; + _Parent = value; + + if (value == null) + { + if (SuperGrid != null) + { + if (SuperGrid.ActiveElement == this) + SuperGrid.ActiveElement = null; + } + } + + OnParentChanged(oldParent, value); + } + } + } + + #endregion + + #region Size + + /// + /// Gets or sets the Size of the item. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Size Size + { + get { return (_BoundsRelative.Size); } + internal set { _BoundsRelative.Size = value; } + } + + #endregion + + #region SuperGrid + + /// + /// Gets the parent super grid control. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SuperGridControl SuperGrid + { + get { return GetParentSuperGrid(); } + internal set { _SuperGrid = value; } + } + + #region GetParentSuperGrid + + private SuperGridControl GetParentSuperGrid() + { + if (_SuperGrid != null) + return (_SuperGrid); + + GridElement parent = _Parent; + + while (parent != null) + { + if (parent.SuperGrid != null) + return (_SuperGrid = parent.SuperGrid); + + parent = parent.Parent; + } + + return (null); + } + + #endregion + + #endregion + + #region Tag + + /// + /// Gets or sets user-defined data associated with the object + /// + [DefaultValue(null)] + [Description("User-defined data associated with the object")] + [TypeConverter(typeof(StringConverter))] + public object Tag + { + get { return (_Tag); } + set { _Tag = value; } + } + + #endregion + + #region Visible + + /// + /// Get or sets whether the item is visible + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether item is visible")] + public virtual bool Visible + { + get { return (TestState(Es.Visible)); } + + set + { + if (Visible != value) + { + SetState(Es.Visible, value); + + OnPropertyChangedEx("Visible", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region TestState + + private bool TestState(Es state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(Es state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #region OnEvent processing + + #region OnLayoutInvalid + + /// + /// Raises LayoutInvalid event. + /// + /// Provides event arguments. + protected virtual void OnLayoutInvalid(EventArgs e) + { + EventHandler handler = LayoutInvalid; + + if (handler != null) + handler(this, e); + } + + #endregion + + #region OnParentChanged + + /// + /// Called after parent of the item has changed. + /// + /// Reference to old parent. + /// Reference to new parent. + protected virtual void OnParentChanged(GridElement oldParent, GridElement newParent) + { + OnParentChanged(EventArgs.Empty); + } + + /// + /// Raises ParentChanged event. + /// + /// Provides event arguments. + protected virtual void OnParentChanged(EventArgs e) + { + EventHandler handler = ParentChanged; + + if (handler != null) + handler(this, e); + } + + #endregion + + #region OnRenderInvalid + + /// + /// Raises RenderInvalid event. + /// + /// Provides event arguments. + protected virtual void OnRenderInvalid(EventArgs e) + { + EventHandler handler = RenderInvalid; + + if (handler != null) + handler(this, e); + } + + #endregion + + #endregion + + #region Measure + + /// + /// This method is used by the items internally to invoke the measure pass to + /// get item size. Override MeasureOverride method to perform actual measuring. + /// + /// Holds contextual layout information. + /// + /// + internal void Measure( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + MeasureOverride(layoutInfo, stateInfo, constraintSize); + + NeedsMeasured = false; + } + + #endregion + + #region Arrange + + /// + /// This method is used by the items internally to invoke the arrange pass after + /// location and size of the item has been set. Override ArrangeOverride method + /// to perform internal arranging. + /// + /// + /// + /// + internal void Arrange( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + IsLayoutValid = true; + + _BoundsRelative = layoutBounds; + + ArrangeOverride(layoutInfo, stateInfo, layoutBounds); + } + + #endregion + + #region Render + + /// + /// This method is used by the items internally to invoke the rendering + /// for the item. Override RenderOverride method to perform actual rendering. + /// + /// Holds contextual rendering information. + internal void Render(GridRenderInfo renderInfo) + { + RenderOverride(renderInfo); + } + + #endregion + + #region InvalidateLayout + + /// + /// Invalidates the layout for the item. + /// + public virtual void InvalidateLayout() + { + IsLayoutValid = false; + + if (_Parent != null) + { + _Parent.InvalidateLayout(); + } + else + { + if (SuperGrid != null) + SuperGrid.Invalidate(); + } + + OnLayoutInvalid(EventArgs.Empty); + } + + #endregion + + #region InvalidateRender + + /// + /// Invalidates the display state of the item + /// + public virtual void InvalidateRender() + { + SuperGridControl grid = SuperGrid; + + if (grid != null) + { + if (grid.InvokeRequired) + grid.BeginInvoke(new MethodInvoker(delegate { grid.InvalidateRender(this); })); + else + grid.InvalidateRender(this); + } + + OnRenderInvalid(EventArgs.Empty); + } + + /// + /// Invalidates the display state of the item + /// + public virtual void InvalidateRender(Rectangle bounds) + { + SuperGridControl grid = SuperGrid; + + if (grid != null) + grid.InvalidateRender(bounds); + + OnRenderInvalid(EventArgs.Empty); + } + + #endregion + + #region Mouse Handling + + #region OnMouseEnter + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalMouseEnter(EventArgs e) + { + IsMouseOver = true; + + OnMouseEnter(e); + } + + /// + /// Called when mouse enter the element. + /// + /// + protected virtual void OnMouseEnter(EventArgs e) + { + } + + #endregion + + #region OnMouseLeave + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalMouseLeave(EventArgs e) + { + IsMouseOver = false; + + OnMouseLeave(e); + } + + /// + /// Called when mouse leaves the element. + /// + /// + protected virtual void OnMouseLeave(EventArgs e) + { + } + + #endregion + + #region OnMouseHover + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalMouseHover(EventArgs e) + { + OnMouseHover(e); + } + + /// + /// Called when mouse hovers over the element. + /// + /// + protected virtual void OnMouseHover(EventArgs e) + { + } + + #endregion + + #region OnMouseDown + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalMouseDown(MouseEventArgs e) + { + MouseDownPoint = e.Location; + + OnMouseDown(e); + } + + /// + /// Called when mouse button is pressed over the element. + /// + /// + protected virtual void OnMouseDown(MouseEventArgs e) + { + } + + #endregion + + #region OnMouseUp + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalMouseUp(MouseEventArgs e) + { + Capture = false; + + OnMouseUp(e); + } + + /// + /// Called when mouse button is released over the element. + /// + /// + protected virtual void OnMouseUp(MouseEventArgs e) + { + } + + #endregion + + #region OnMouseMove + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalMouseMove(MouseEventArgs e) + { + OnMouseMove(e); + } + + /// + /// Called when mouse is moved over the element. + /// + /// + protected virtual void OnMouseMove(MouseEventArgs e) + { + } + + #endregion + + #region OnMouseClick + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalMouseClick(MouseEventArgs e) + { + OnMouseClick(e); + } + /// + /// Called when mouse is clicked on the element. + /// + /// + protected virtual void OnMouseClick(MouseEventArgs e) + { + } + + #endregion + + #region OnMouseDoubleClick + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalMouseDoubleClick(MouseEventArgs e) + { + OnMouseDoubleClick(e); + } + + /// + /// Called when mouse is double clicked on the element. + /// + /// + protected virtual void OnMouseDoubleClick(MouseEventArgs e) + { + } + + #endregion + + #region PostInternalMouseMove + + internal void PostInternalMouseMove() + { + SuperGrid.PostInternalMouseMove(); + } + + #endregion + + #endregion + + #region Keyboard handling + + /// + /// Called by top-level control to pass message into the grid + /// element. To handle it override corresponding On - virtual method. + /// + /// + internal virtual void InternalKeyDown(Keys keyData) + { + OnKeyDown(keyData); + } + + /// + /// Called when mouse button is pressed over the element. + /// + /// + protected virtual void OnKeyDown(Keys keyData) + { + } + + #endregion + + #region EnsureVisible + + /// + /// EnsureVisible + /// + public void EnsureVisible() + { + EnsureVisible(false); + } + + /// + /// EnsureVisible + /// + /// + public virtual void EnsureVisible(bool center) + { + } + + #endregion + + #region CancelCapture + + /// + /// Cancels any inprogress operations that may + /// have the mouse captured (resize, reorder). + /// + public virtual void CancelCapture() + { + if (CapturedItem == this) + Capture = false; + } + + #endregion + + #region IsDesignerHosted + + internal bool IsDesignerHosted + { + get + { + if (SuperGrid != null) + return (SuperGrid.IsDesignerHosted); + + return (false); + } + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + OnPropertyChanged(s); + + if (changeType == VisualChangeType.Layout) + InvalidateLayout(); + else + InvalidateRender(); + } + + #endregion + + #region ElementStates + + [Flags] + private enum Es + { + AllowSelection = (1 << 0), + LayoutValid = (1 << 1), + MouseOver = (1 << 2), + NeedsMeasured = (1 << 3), + Visible = (1 << 4), + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilter.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilter.Designer.cs new file mode 100644 index 00000000..be852187 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilter.Designer.cs @@ -0,0 +1,128 @@ +namespace DevComponents.DotNetBar.SuperGrid +{ + partial class CustomFilter + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomFilter)); + this.btnCancel = new DevComponents.DotNetBar.ButtonX(); + this.btnOk = new DevComponents.DotNetBar.ButtonX(); + this.btnApply = new DevComponents.DotNetBar.ButtonX(); + this.btnClear = new DevComponents.DotNetBar.ButtonX(); + this.lblEnterText = new DevComponents.DotNetBar.LabelX(); + this.filterExprEdit1 = new DevComponents.DotNetBar.SuperGrid.FilterExprEdit(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnCancel, "btnCancel"); + this.btnCancel.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnCancel.Click += new System.EventHandler(this.BtnCancelClick); + // + // btnOk + // + this.btnOk.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnOk, "btnOk"); + this.btnOk.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOk.Name = "btnOk"; + this.btnOk.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnOk.Click += new System.EventHandler(this.BtnOkClick); + // + // btnApply + // + this.btnApply.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnApply, "btnApply"); + this.btnApply.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnApply.Name = "btnApply"; + this.btnApply.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnApply.Click += new System.EventHandler(this.BtnApplyClick); + // + // btnClear + // + this.btnClear.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnClear, "btnClear"); + this.btnClear.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnClear.Name = "btnClear"; + this.btnClear.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnClear.Click += new System.EventHandler(this.BtnClearClick); + // + // lblEnterText + // + resources.ApplyResources(this.lblEnterText, "lblEnterText"); + // + // + // + this.lblEnterText.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.lblEnterText.Name = "lblEnterText"; + // + // filterExprEdit1 + // + resources.ApplyResources(this.filterExprEdit1, "filterExprEdit1"); + this.filterExprEdit1.Name = "filterExprEdit1"; + // + // CustomFilter + // + this.AcceptButton = this.btnApply; + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.CancelButton = this.btnCancel; + this.Controls.Add(this.filterExprEdit1); + this.Controls.Add(this.lblEnterText); + this.Controls.Add(this.btnClear); + this.Controls.Add(this.btnApply); + this.Controls.Add(this.btnOk); + this.Controls.Add(this.btnCancel); + this.DoubleBuffered = true; + this.EnableGlass = false; + this.HelpButton = true; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CustomFilter"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.TitleText = "Custom Filter"; + this.HelpButtonClicked += new System.ComponentModel.CancelEventHandler(this.CustomFilterHelpButtonClicked); + this.Shown += new System.EventHandler(this.CustomFilterShown); + this.ResumeLayout(false); + + } + + #endregion + + private DevComponents.DotNetBar.ButtonX btnCancel; + private DevComponents.DotNetBar.ButtonX btnOk; + private ButtonX btnApply; + private ButtonX btnClear; + private LabelX lblEnterText; + private FilterExprEdit filterExprEdit1; + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilter.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilter.cs new file mode 100644 index 00000000..5aea2d40 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilter.cs @@ -0,0 +1,393 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// CustomFilter + /// + public partial class CustomFilter : Office2007Form + { + #region Static data + + private static bool _localizedStringsLoaded; + + private static string _filterClearString = "Clear"; + private static string _filterCustomFilterString = "Custom Filter"; + private static string _filterEnterExprString = "Enter custom filter expression"; + private static string _filterHelpString = "Click the Title Bar help button for syntax help"; + private static string _filterHelpTitle = "SampleExpr"; + + private static Point _offset = Point.Empty; + private static Size _size = Size.Empty; + + #endregion + + #region Private variables + + private GridPanel _GridPanel; + private GridColumn _GridColumn; + + private string _FilterExpr; + private object _FilterValue; + private object _FilterDisplayValue; + + private bool _LockedResize = true; + + #endregion + + /// + /// CustomFilter + /// + public CustomFilter(GridPanel gridPanel, GridColumn gridColumn) + : this(gridPanel, gridColumn, gridColumn != null ? gridColumn.FilterExpr : gridPanel.FilterExpr) + { + } + + /// + /// CustomFilter + /// + public CustomFilter(GridPanel gridPanel, GridColumn gridColumn, string filterText) + { + _GridPanel = gridPanel; + _GridColumn = gridColumn; + + InitializeComponent(); + InitializeText(); + InitializeFilter(filterText); + + PositionWindow(_GridPanel.SuperGrid); + + StyleManager.UpdateAmbientColors(filterExprEdit1); + + filterExprEdit1.RtbOutput.BackColorRichTextBox = Color.White; + } + + #region Public properties + + #region FilterExpr + + /// + /// FilterExpr + /// + public string FilterExpr + { + get { return (filterExprEdit1.InputText); } + } + + #endregion + + #endregion + + #region Initialization + + #region InitializeText + + private void InitializeText() + { + SuperGridControl superGrid = _GridPanel.SuperGrid; + + LoadLocalizedStrings(superGrid); + + TitleText = _filterCustomFilterString; + + lblEnterText.Text = _filterEnterExprString; + + btnClear.Text = _filterClearString; + btnApply.Text = superGrid.FilterApplyString; + btnOk.Text = superGrid.FilterOkString; + btnCancel.Text = superGrid.FilterCancelString; + + if (superGrid.ShowCustomFilterHelp == true) + filterExprEdit1.WaterMarkText = _filterHelpString; + else + HelpButton = false; + } + + #endregion + + #region InitializeFilter + + private void InitializeFilter(string filterText) + { + if (_GridColumn != null) + { + _FilterExpr = _GridColumn.FilterExpr; + _FilterValue = _GridColumn.FilterValue; + _FilterDisplayValue = _GridColumn.FilterDisplayValue; + } + else + { + _FilterExpr = _GridPanel.FilterExpr; + _FilterValue = null; + _FilterDisplayValue = null; + } + + filterExprEdit1.GridPanel = _GridPanel; + filterExprEdit1.GridColumn = _GridColumn; + filterExprEdit1.InputText = filterText; + } + + #endregion + + #region PositionWindow + + private void PositionWindow(SuperGridControl superGrid) + { + if (_size != Size.Empty) + Size = _size; + + Form form = superGrid.FindForm(); + + if (form != null) + { + Point pt = form.Location; + + if (_offset != Point.Empty) + { + pt.Offset(_offset); + + Location = pt; + } + else + { + Screen screen = Screen.FromControl(form); + + int boundWidth = screen.Bounds.Width; + int boundHeight = screen.Bounds.Height; + + int x = boundWidth - Width; + int y = boundHeight - Height; + + Location = new Point(screen.Bounds.X + x / 2, screen.Bounds.Y + y / 2); + } + } + + _LockedResize = false; + } + + #endregion + + #endregion + + #region Event processong + + #region CustomFilterShown + + private void CustomFilterShown(object sender, EventArgs e) + { + filterExprEdit1.SetFocus(); + } + + #endregion + + #region OnResize + + /// + /// Handles filter resize + /// + /// + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + + if (_LockedResize == false) + _size = Size; + } + + #endregion + + #region OnLocationChanged + + /// + /// LocationChanged processing + /// + /// + protected override void OnLocationChanged(EventArgs e) + { + base.OnLocationChanged(e); + + if (_LockedResize == false) + { + Form form = _GridPanel.SuperGrid.FindForm(); + + if (form != null) + { + Point pt = Location; + + pt.Offset(-form.Location.X, -form.Location.Y); + + _offset = pt; + } + } + } + + #endregion + + #endregion + + #region Button processing + + #region BtnApplyClick + + private void BtnApplyClick(object sender, EventArgs e) + { + ApplyFilter(); + } + + #region ApplyFilter + + private void ApplyFilter() + { + string text = filterExprEdit1.InputText; + + object filterValue = null; + object filterDisplayValue = text; + string filterExpr = text; + + if (_GridColumn != null) + { + if (_GridColumn.SuperGrid.DoFilterEditValueChangedEvent(_GridPanel, _GridColumn, null, + _GridColumn.FilterValue, ref filterValue, ref filterDisplayValue, ref filterExpr) == false) + { + _GridColumn.FilterExpr = text; + _GridColumn.FilterValue = null; + _GridColumn.FilterDisplayValue = text; + } + } + else + { + if (_GridPanel.SuperGrid.DoFilterEditValueChangedEvent(_GridPanel, null, null, + _GridPanel.FilterExpr, ref filterValue, ref filterDisplayValue, ref filterExpr) == false) + { + _GridPanel.FilterExpr = text; + } + } + } + + #endregion + + #endregion + + #region BtnOkClick + + private void BtnOkClick(object sender, EventArgs e) + { + ApplyFilter(); + } + + #endregion + + #region BtnCancelClick + + private void BtnCancelClick(object sender, EventArgs e) + { + CancelFilter(); + } + + private void CancelFilter() + { + if (_GridColumn != null) + { + _GridColumn.FilterExpr = _FilterExpr; + _GridColumn.FilterValue = _FilterValue; + _GridColumn.FilterDisplayValue = _FilterDisplayValue; + } + else + { + _GridPanel.FilterExpr = _FilterExpr; + } + } + + #endregion + + #region BtnClearClick + + private void BtnClearClick(object sender, EventArgs e) + { + filterExprEdit1.InputText = ""; + } + + #endregion + + #region CustomFilterHelpButtonClicked + + /// + /// Sample Expr variable + /// + static protected SampleExpr Se; + + private void CustomFilterHelpButtonClicked(object sender, CancelEventArgs e) + { + if (Se == null) + { + Se = new SampleExpr(_GridPanel.SuperGrid); + Se.TitleText = _filterHelpTitle; + + Se.FormClosed += SeFormClosed; + } + + if (_GridPanel.SuperGrid.DoFilterHelpOpeningEvent(_GridPanel, _GridColumn, Se) == true) + { + Se.Close(); + } + else + { + Se.Show(); + + if (Se.WindowState == FormWindowState.Minimized) + Se.WindowState = FormWindowState.Normal; + + Se.BringToFront(); + } + + e.Cancel = true; + } + + void SeFormClosed(object sender, FormClosedEventArgs e) + { + _GridPanel.SuperGrid.DoFilterHelpClosingEvent(_GridPanel, _GridColumn, Se); + + Se.FormClosed -= SeFormClosed; + Se = null; + } + + #endregion + + #endregion + + #region LoadLocalizedStrings + + private void LoadLocalizedStrings(SuperGridControl sg) + { + if (_localizedStringsLoaded == false) + { + using (LocalizationManager lm = new LocalizationManager(sg)) + { + string s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterCustomHelp)) != "") + _filterHelpString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterEnterExpr)) != "") + _filterEnterExprString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterClear)) != "") + _filterClearString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterCustomFilter)) != "") + _filterCustomFilterString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterHelpTitle)) != "") + _filterHelpTitle = s; + } + + _localizedStringsLoaded = true; + } + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilter.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilter.resx new file mode 100644 index 00000000..f9cbf957 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilter.resx @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Bottom, Right + + + + 315, 157 + + + 65, 23 + + + + 4 + + + Cancel + + + btnCancel + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 5 + + + Bottom, Right + + + 244, 157 + + + 65, 23 + + + 3 + + + OK + + + btnOk + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 4 + + + Bottom, Right + + + 164, 157 + + + 65, 23 + + + 2 + + + Apply + + + btnApply + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 3 + + + Bottom, Left + + + 12, 157 + + + 65, 23 + + + 9 + + + Clear + + + btnClear + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 2 + + + Top, Left, Right + + + 10, 4 + + + 370, 26 + + + 10 + + + labelX1 + + + lblEnterText + + + DevComponents.DotNetBar.LabelX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 1 + + + Top, Bottom, Left, Right + + + 12, 34 + + + 370, 112 + + + 11 + + + filterExprEdit1 + + + DevComponents.DotNetBar.SuperGrid.FilterExprEdit, DevComponents.DotNetBar.SuperGrid, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 0 + + + True + + + 96, 96 + + + 394, 192 + + + 410, 230 + + + Manual + + + CustomFilter + + + DevComponents.DotNetBar.Office2007Form, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilterEx.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilterEx.Designer.cs new file mode 100644 index 00000000..8ee61060 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilterEx.Designer.cs @@ -0,0 +1,231 @@ +namespace DevComponents.DotNetBar.SuperGrid +{ + partial class CustomFilterEx + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomFilterEx)); + this.btnCancel = new DevComponents.DotNetBar.ButtonX(); + this.btnOk = new DevComponents.DotNetBar.ButtonX(); + this.btnApply = new DevComponents.DotNetBar.ButtonX(); + this.btnReset = new DevComponents.DotNetBar.ButtonX(); + this.lblFilterName = new DevComponents.DotNetBar.LabelX(); + this.tbxDesc = new DevComponents.DotNetBar.Controls.TextBoxX(); + this.lblDesc = new DevComponents.DotNetBar.LabelX(); + this.cbFilterName = new DevComponents.DotNetBar.Controls.ComboBoxEx(); + this.btnNewFilter = new DevComponents.DotNetBar.ButtonX(); + this.btnDeleteFilter = new DevComponents.DotNetBar.ButtonX(); + this.lblEnterText = new DevComponents.DotNetBar.LabelX(); + this.cbxShowInPopup = new DevComponents.DotNetBar.Controls.CheckBoxX(); + this.btnClear = new DevComponents.DotNetBar.ButtonX(); + this.filterExprEdit1 = new DevComponents.DotNetBar.SuperGrid.FilterExprEdit(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnCancel, "btnCancel"); + this.btnCancel.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnCancel.Click += new System.EventHandler(this.BtnCancelClick); + // + // btnOk + // + this.btnOk.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnOk, "btnOk"); + this.btnOk.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOk.Name = "btnOk"; + this.btnOk.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnOk.Click += new System.EventHandler(this.BtnOkClick); + // + // btnApply + // + this.btnApply.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnApply, "btnApply"); + this.btnApply.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnApply.Name = "btnApply"; + this.btnApply.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnApply.Click += new System.EventHandler(this.BtnApplyClick); + // + // btnReset + // + this.btnReset.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnReset, "btnReset"); + this.btnReset.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnReset.Name = "btnReset"; + this.btnReset.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnReset.Click += new System.EventHandler(this.BtnResetClick); + // + // lblFilterName + // + // + // + // + this.lblFilterName.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + resources.ApplyResources(this.lblFilterName, "lblFilterName"); + this.lblFilterName.Name = "lblFilterName"; + // + // tbxDesc + // + resources.ApplyResources(this.tbxDesc, "tbxDesc"); + // + // + // + this.tbxDesc.Border.Class = "TextBoxBorder"; + this.tbxDesc.Border.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.tbxDesc.Name = "tbxDesc"; + this.tbxDesc.TextChanged += new System.EventHandler(this.TbxDescTextChanged); + // + // lblDesc + // + resources.ApplyResources(this.lblDesc, "lblDesc"); + // + // + // + this.lblDesc.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.lblDesc.Name = "lblDesc"; + // + // cbFilterName + // + resources.ApplyResources(this.cbFilterName, "cbFilterName"); + this.cbFilterName.DisplayMember = "Text"; + this.cbFilterName.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; + this.cbFilterName.FormattingEnabled = true; + this.cbFilterName.Name = "cbFilterName"; + this.cbFilterName.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.cbFilterName.DropDown += new System.EventHandler(this.CbFilterNameDropDown); + this.cbFilterName.SelectedIndexChanged += new System.EventHandler(this.CbFilterNameSelectedIndexChanged); + this.cbFilterName.TextUpdate += new System.EventHandler(this.CbFilterNameTextUpdate); + // + // btnNewFilter + // + this.btnNewFilter.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnNewFilter, "btnNewFilter"); + this.btnNewFilter.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnNewFilter.Name = "btnNewFilter"; + this.btnNewFilter.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnNewFilter.Click += new System.EventHandler(this.BtnNewFilterClick); + // + // btnDeleteFilter + // + this.btnDeleteFilter.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnDeleteFilter, "btnDeleteFilter"); + this.btnDeleteFilter.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnDeleteFilter.Name = "btnDeleteFilter"; + this.btnDeleteFilter.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnDeleteFilter.Click += new System.EventHandler(this.BtnDeleteFilterClick); + // + // lblEnterText + // + resources.ApplyResources(this.lblEnterText, "lblEnterText"); + // + // + // + this.lblEnterText.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.lblEnterText.Name = "lblEnterText"; + // + // cbxShowInPopup + // + resources.ApplyResources(this.cbxShowInPopup, "cbxShowInPopup"); + // + // + // + this.cbxShowInPopup.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.cbxShowInPopup.Name = "cbxShowInPopup"; + this.cbxShowInPopup.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.cbxShowInPopup.CheckedChanged += new System.EventHandler(this.CbxShowInPopupCheckedChanged); + // + // btnClear + // + this.btnClear.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnClear, "btnClear"); + this.btnClear.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnClear.Name = "btnClear"; + this.btnClear.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnClear.Click += new System.EventHandler(this.BtnClearClick); + // + // filterExprEdit1 + // + resources.ApplyResources(this.filterExprEdit1, "filterExprEdit1"); + this.filterExprEdit1.Name = "filterExprEdit1"; + // + // CustomFilterEx + // + this.AcceptButton = this.btnApply; + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.CancelButton = this.btnCancel; + this.Controls.Add(this.btnClear); + this.Controls.Add(this.filterExprEdit1); + this.Controls.Add(this.tbxDesc); + this.Controls.Add(this.lblEnterText); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.cbxShowInPopup); + this.Controls.Add(this.btnOk); + this.Controls.Add(this.btnNewFilter); + this.Controls.Add(this.btnReset); + this.Controls.Add(this.lblFilterName); + this.Controls.Add(this.btnApply); + this.Controls.Add(this.cbFilterName); + this.Controls.Add(this.lblDesc); + this.Controls.Add(this.btnDeleteFilter); + this.DoubleBuffered = true; + this.EnableGlass = false; + this.HelpButton = true; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CustomFilterEx"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.TitleText = "Custom Filter"; + this.HelpButtonClicked += new System.ComponentModel.CancelEventHandler(this.CustomFilterHelpButtonClicked); + this.Shown += new System.EventHandler(this.CustomFilterShown); + this.ResumeLayout(false); + + } + + #endregion + + private DevComponents.DotNetBar.ButtonX btnCancel; + private DevComponents.DotNetBar.ButtonX btnOk; + private ButtonX btnApply; + private ButtonX btnReset; + private LabelX lblFilterName; + private DevComponents.DotNetBar.Controls.TextBoxX tbxDesc; + private LabelX lblDesc; + private DevComponents.DotNetBar.Controls.ComboBoxEx cbFilterName; + private ButtonX btnNewFilter; + private ButtonX btnDeleteFilter; + private LabelX lblEnterText; + private DevComponents.DotNetBar.Controls.CheckBoxX cbxShowInPopup; + private FilterExprEdit filterExprEdit1; + private ButtonX btnClear; + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilterEx.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilterEx.cs new file mode 100644 index 00000000..fb8c6211 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilterEx.cs @@ -0,0 +1,700 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// CustomFilter + /// + internal partial class CustomFilterEx : Office2007Form + { + #region Static data + + private static bool _localizedStringsLoaded; + + private static string _filterClearString = "Clear"; + private static string _filterResetString = "Reset"; + private static string _filterCustomFilterString = "Custom Filter"; + private static string _filterEnterExprString = "Enter custom filter expression"; + private static string _filterHelpString = "Click the Title Bar help button for syntax help"; + private static string _newFilterExprString = "NewFilter"; + private static string _filterDescriptionString = "Description"; + private static string _filterNameString = "Filter Name:"; + private static string _showInFilterPopupString = "Show in FilterPopup"; + private static string _newFilterString = "New"; + private static string _deleteFilterString = "Delete"; + private static string _filterHelpTitle = "SampleExpr"; + + private static Point _offset = Point.Empty; + private static Size _size = Size.Empty; + + #endregion + + #region Private variables + + private GridPanel _GridPanel; + private GridColumn _GridColumn; + + private string _FilterExpr; + private object _FilterValue; + private object _FilterDisplayValue; + + private List _FilterData; + private UserFilterData _CurrentFilter; + + private bool _CancelFilterEdits; + private bool _LockedResize = true; + + #endregion + + /// + /// CustomFilter + /// + public CustomFilterEx(GridPanel gridPanel, GridColumn gridColumn) + : this(gridPanel, gridColumn, gridColumn != null ? gridColumn.FilterExpr : gridPanel.FilterExpr) + { + } + + /// + /// CustomFilter + /// + public CustomFilterEx(GridPanel gridPanel, + GridColumn gridColumn, string filterText) + { + _GridPanel = gridPanel; + _GridColumn = gridColumn; + + InitializeComponent(); + InitializeText(); + InitializeFilter(filterText); + + PositionWindow(_GridPanel.SuperGrid); + + FormClosing += CustomFilterExFormClosing; + + filterExprEdit1.InputTextChanged += FilterExprEdit1InputTextChanged; + + StyleManager.UpdateAmbientColors(filterExprEdit1); + + filterExprEdit1.RtbOutput.BackColorRichTextBox = Color.White; + } + + #region Public properties + + #region CurrentFilter + + /// + /// Gets or sets the current UserFilterData filter + /// + public UserFilterData CurrentFilter + { + get { return (_CurrentFilter); } + + set + { + if (_CurrentFilter != value) + { + _CurrentFilter = value; + + UpdateDisplay(); + } + } + } + + #endregion + + #region FilterData + + /// + /// Gets or sets the list of UserFilterData + /// + public List FilterData + { + get { return (_FilterData); } + set { _FilterData = value; } + } + + #endregion + + #region FilterExpr + + /// + /// FilterExpr + /// + public string FilterExpr + { + get { return (filterExprEdit1.InputText); } + } + + #endregion + + #region ShowInPopupVisible + + /// + /// ShowInPopupVisible + /// + public bool ShowInPopupVisible + { + get { return (cbxShowInPopup.Visible); } + set { cbxShowInPopup.Visible = value; } + } + + #endregion + + #endregion + + #region Initialization + + #region InitializeText + + private void InitializeText() + { + SuperGridControl superGrid = _GridPanel.SuperGrid; + + LoadLocalizedStrings(superGrid); + + TitleText = _filterCustomFilterString; + + lblEnterText.Text = _filterEnterExprString; + lblDesc.Text = _filterDescriptionString; + lblFilterName.Text = _filterNameString; + + btnNewFilter.Text = _newFilterString; + btnDeleteFilter.Text = _deleteFilterString; + btnReset.Text = _filterResetString; + btnClear.Text = _filterClearString; + + btnApply.Text = superGrid.FilterApplyString; + btnOk.Text = superGrid.FilterOkString; + btnCancel.Text = superGrid.FilterCancelString; + + cbxShowInPopup.Text = _showInFilterPopupString; + + if (superGrid.ShowCustomFilterHelp == true) + filterExprEdit1.WaterMarkText = _filterHelpString; + else + HelpButton = false; + } + + #endregion + + #region InitializeFilter + + private void InitializeFilter(string filterText) + { + if (_GridColumn != null) + { + _FilterExpr = _GridColumn.FilterExpr; + _FilterValue = _GridColumn.FilterValue; + _FilterDisplayValue = _GridColumn.FilterDisplayValue; + } + else + { + _FilterExpr = _GridPanel.FilterExpr; + _FilterValue = null; + _FilterDisplayValue = null; + + cbxShowInPopup.Visible = false; + } + + filterExprEdit1.GridPanel = _GridPanel; + filterExprEdit1.GridColumn = _GridColumn; + filterExprEdit1.InputText = filterText; + + CurrentFilter = GetCurrentFilter(); + } + + #region GetCurrentFilter + + private UserFilterData GetCurrentFilter() + { + _FilterData = FilterUserData.LoadFilterData(_GridPanel); + + foreach (UserFilterData fd in _FilterData) + { + if (string.IsNullOrEmpty(fd.Expression) == false) + { + if (fd.Expression.Equals(filterExprEdit1.InputText) == true) + return (fd); + } + } + + UserFilterData nfd = GetNewFilter(); + + nfd.Expression = filterExprEdit1.InputText; + + return (nfd); + } + + #endregion + + #endregion + + #region PositionWindow + + private void PositionWindow(SuperGridControl superGrid) + { + if (_size != Size.Empty) + Size = _size; + + Form form = superGrid.FindForm(); + + if (form != null) + { + Point pt = form.Location; + + if (_offset != Point.Empty) + { + pt.Offset(_offset); + + Location = pt; + } + else + { + Screen screen = Screen.FromControl(form); + + int boundWidth = screen.Bounds.Width; + int boundHeight = screen.Bounds.Height; + + int x = boundWidth - Width; + int y = boundHeight - Height; + + Location = new Point(screen.Bounds.X + x / 2, screen.Bounds.Y + y / 2); + } + } + + _LockedResize = false; + } + + #endregion + + #endregion + + #region Event processong + + #region CustomFilterExFormClosing + + void CustomFilterExFormClosing(object sender, FormClosingEventArgs e) + { + if (_CancelFilterEdits == false) + FilterUserData.StoreFilterData(_GridPanel, _FilterData); + } + + #endregion + + #region CustomFilterShown + + private void CustomFilterShown(object sender, EventArgs e) + { + filterExprEdit1.SetFocus(); + } + + #endregion + + #region FilterExprEdit1InputTextChanged + + void FilterExprEdit1InputTextChanged(object sender, EventArgs e) + { + CurrentFilter.Expression = filterExprEdit1.InputText; + } + + #endregion + + #region OnLocationChanged + + protected override void OnLocationChanged(EventArgs e) + { + base.OnLocationChanged(e); + + if (_LockedResize == false) + { + Form form = _GridPanel.SuperGrid.FindForm(); + + if (form != null) + { + Point pt = Location; + + pt.Offset(-form.Location.X, -form.Location.Y); + + _offset = pt; + } + } + } + + #endregion + + #region OnResize + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + + if (_LockedResize == false) + _size = Size; + } + + #endregion + + #endregion + + #region UpdateDisplay + + private void UpdateDisplay() + { + cbFilterName.Text = CurrentFilter.Name; + tbxDesc.Text = CurrentFilter.Description; + + if (_GridColumn != null) + cbxShowInPopup.Checked = CurrentFilter.ReferNames.Contains(_GridColumn.Name); + + filterExprEdit1.InputText = CurrentFilter.Expression; + } + + #endregion + + #region Button processing + + #region BtnApplyClick + + private void BtnApplyClick(object sender, EventArgs e) + { + ApplyFilter(filterExprEdit1.InputText); + } + + #endregion + + #region BtnResetClick + + private void BtnResetClick(object sender, EventArgs e) + { + ApplyFilter(null); + + Close(); + } + + #endregion + + #region BtnDeleteFilterClick + + private void BtnDeleteFilterClick(object sender, EventArgs e) + { + if (CurrentFilter != null) + { + _FilterData.Remove(CurrentFilter); + + UpdateFilterNameCombo(); + + CurrentFilter = (_FilterData.Count > 0) + ? _FilterData[0] : GetNewFilter(); + } + } + + #endregion + + #region BtnCancelClick + + private void BtnCancelClick(object sender, EventArgs e) + { + if (_GridColumn != null) + { + _GridColumn.FilterExpr = _FilterExpr; + _GridColumn.FilterValue = _FilterValue; + _GridColumn.FilterDisplayValue = _FilterDisplayValue; + } + else + { + _GridPanel.FilterExpr = _FilterExpr; + } + + _CancelFilterEdits = true; + } + + #endregion + + #region BtnClearClick + + private void BtnClearClick(object sender, EventArgs e) + { + filterExprEdit1.InputText = ""; + } + + #endregion + + #region BtnNewFilterClick + + private void BtnNewFilterClick(object sender, EventArgs e) + { + CurrentFilter = GetNewFilter(); + } + + #region GetNewFilter + + private UserFilterData GetNewFilter() + { + UserFilterData fd = new UserFilterData(); + + fd.Name = GetNewFilterName(); + fd.Description = ""; + + _FilterData.Add(fd); + + return (fd); + } + + #region GetNewFilterName + + private string GetNewFilterName() + { + for (int i = 1; i < 100; i++) + { + string s = _newFilterExprString + i; + + if (FindFilterName(s) < 0) + return(s); + } + + return (_newFilterExprString); + } + + #region FindFilterName + + private int FindFilterName(string s) + { + for (int i = 0; i < _FilterData.Count; i++) + { + if (s.Equals(_FilterData[i].Name) == true) + return (i); + } + + return (-1); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region BtnOkClick + + private void BtnOkClick(object sender, EventArgs e) + { + ApplyFilter(filterExprEdit1.InputText); + } + + #endregion + + #region CustomFilterHelpButtonClicked + + static protected SampleExpr Se; + + private void CustomFilterHelpButtonClicked(object sender, CancelEventArgs e) + { + if (Se == null) + { + Se = new SampleExpr(_GridPanel.SuperGrid); + Se.TitleText = _filterHelpTitle; + + Se.FormClosed += SeFormClosed; + } + + if (_GridPanel.SuperGrid.DoFilterHelpOpeningEvent(_GridPanel, _GridColumn, Se) == true) + { + Se.Close(); + } + else + { + Se.Show(); + + if (Se.WindowState == FormWindowState.Minimized) + Se.WindowState = FormWindowState.Normal; + + Se.BringToFront(); + } + + e.Cancel = true; + } + + void SeFormClosed(object sender, FormClosedEventArgs e) + { + _GridPanel.SuperGrid.DoFilterHelpClosingEvent(_GridPanel, _GridColumn, Se); + + Se.FormClosed -= SeFormClosed; + Se = null; + } + + #endregion + + #region ApplyFilter + + private void ApplyFilter(string text) + { + object filterValue = null; + object filterDisplayValue = text; + string filterExpr = text; + + if (_GridColumn != null) + { + if (_GridColumn.SuperGrid.DoFilterEditValueChangedEvent(_GridPanel, _GridColumn, null, + _GridColumn.FilterValue, ref filterValue, ref filterDisplayValue, ref filterExpr) == false) + { + _GridColumn.FilterExpr = text; + _GridColumn.FilterValue = null; + _GridColumn.FilterDisplayValue = text; + } + } + else + { + if (_GridPanel.SuperGrid.DoFilterEditValueChangedEvent(_GridPanel, null, null, + _GridPanel.FilterExpr, ref filterValue, ref filterDisplayValue, ref filterExpr) == false) + { + _GridPanel.FilterExpr = text; + } + } + } + + #endregion + + #endregion + + #region Checkbox processing + + #region CbxShowInPopupCheckedChanged + + private void CbxShowInPopupCheckedChanged(object sender, EventArgs e) + { + if (_GridColumn != null) + { + if (cbxShowInPopup.Checked == true) + { + if (CurrentFilter.ReferNames.Contains(_GridColumn.Name) == false) + CurrentFilter.ReferNames.Add(_GridColumn.Name); + } + else + { + if (CurrentFilter.ReferNames.Contains(_GridColumn.Name) == true) + CurrentFilter.ReferNames.Remove(_GridColumn.Name); + } + } + } + + #endregion + + #endregion + + #region Combobox processing + + #region CbFilterNameDropDown + + private void CbFilterNameDropDown(object sender, EventArgs e) + { + UpdateFilterNameCombo(); + } + + #region UpdateFilterNameCombo + + private void UpdateFilterNameCombo() + { + cbFilterName.Items.Clear(); + + foreach (UserFilterData fd in _FilterData) + cbFilterName.Items.Add(fd.Name); + } + + #endregion + + #endregion + + #region CbFilterNameSelectedIndexChanged + + private void CbFilterNameSelectedIndexChanged(object sender, EventArgs e) + { + if (cbFilterName.SelectedIndex >= 0) + CurrentFilter = _FilterData[cbFilterName.SelectedIndex]; + } + + #endregion + + #region CbFilterNameTextUpdate + + private void CbFilterNameTextUpdate(object sender, EventArgs e) + { + CurrentFilter.Name = cbFilterName.Text; + } + + #endregion + + #endregion + + #region TextBox processing + + #region TbxDescTextChanged + + private void TbxDescTextChanged(object sender, EventArgs e) + { + CurrentFilter.Description = tbxDesc.Text; + } + + #endregion + + #endregion + + #region LoadLocalizedStrings + + private void LoadLocalizedStrings(SuperGridControl sg) + { + if (_localizedStringsLoaded == false) + { + using (LocalizationManager lm = new LocalizationManager(sg)) + { + string s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterCustomHelp)) != "") + _filterHelpString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterEnterExpr)) != "") + _filterEnterExprString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterClear)) != "") + _filterClearString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterReset)) != "") + _filterResetString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterCustomFilter)) != "") + _filterCustomFilterString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridNewFilterExpr)) != "") + _newFilterExprString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridNewFilter)) != "") + _newFilterString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridDeleteFilter)) != "") + _deleteFilterString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterName)) != "") + _filterNameString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterDescription)) != "") + _filterDescriptionString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridShowInFilterPopup)) != "") + _showInFilterPopupString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterHelpTitle)) != "") + _filterHelpTitle = s; + } + + _localizedStringsLoaded = true; + } + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilterEx.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilterEx.resx new file mode 100644 index 00000000..d4e5784b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/CustomFilterEx.resx @@ -0,0 +1,516 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Bottom, Right + + + + 256, 261 + + + 65, 23 + + + + 9 + + + Cancel + + + btnCancel + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 4 + + + Bottom, Right + + + 327, 261 + + + 65, 23 + + + 10 + + + OK + + + btnOk + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 6 + + + Bottom, Left + + + 86, 261 + + + 65, 23 + + + 8 + + + Apply + + + btnApply + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 10 + + + Bottom, Right + + + 185, 261 + + + 65, 23 + + + 7 + + + Reset + + + btnReset + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 8 + + + 12, 10 + + + 65, 23 + + + 10 + + + Filter Name: + + + lblFilterName + + + DevComponents.DotNetBar.LabelX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 9 + + + Top, Left, Right + + + 12, 65 + + + True + + + 232, 40 + + + 2 + + + tbxDesc + + + DevComponents.DotNetBar.Controls.TextBoxX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 2 + + + Top, Left, Right + + + 12, 41 + + + 232, 22 + + + 0 + + + Description + + + lblDesc + + + DevComponents.DotNetBar.LabelX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 12 + + + Top, Left, Right + + + 15 + + + 83, 12 + + + 161, 21 + + + 1 + + + cbFilterName + + + DevComponents.DotNetBar.Controls.ComboBoxEx, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 11 + + + Top, Right + + + 256, 82 + + + 65, 23 + + + 3 + + + New + + + btnNewFilter + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 7 + + + Top, Right + + + 327, 82 + + + 65, 23 + + + 4 + + + Delete + + + btnDeleteFilter + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 13 + + + Top, Left, Right + + + 12, 115 + + + 377, 23 + + + 0 + + + Enter Custom Expression: + + + lblEnterText + + + DevComponents.DotNetBar.LabelX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 3 + + + Top, Right + + + 259, 12 + + + 133, 23 + + + 5 + + + Show in FilterPopup + + + cbxShowInPopup + + + DevComponents.DotNetBar.Controls.CheckBoxX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 5 + + + Bottom, Left + + + 15, 261 + + + 65, 23 + + + 11 + + + Clear + + + btnClear + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 0 + + + Top, Bottom, Left, Right + + + 10, 136 + + + 383, 114 + + + 6 + + + filterExprEdit1 + + + DevComponents.DotNetBar.SuperGrid.FilterExprEdit, DevComponents.DotNetBar.SuperGrid, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 1 + + + True + + + 96, 96 + + + 401, 292 + + + 410, 330 + + + Manual + + + CustomFilterEx + + + DevComponents.DotNetBar.Office2007Form, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/DataFilter.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/DataFilter.cs new file mode 100644 index 00000000..e380f7db --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/DataFilter.cs @@ -0,0 +1,416 @@ +using System; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// DataBinding helper class + /// + internal static class DataFilter + { + #region Static data + + private static bool _lockFilter; + + #endregion + + /// + /// FilterData + /// + /// + internal static void FilterData(GridPanel panel) + { + if (_lockFilter == true) + return; + + if (panel.SuperGrid.DoDataFilteringStartEvent(panel) == false) + { + _lockFilter = true; + + try + { + if (panel.EnableFiltering == true && + panel.FilterLevel != FilterLevel.None) + { + bool rowFiltered = IsRowFiltered(panel); + bool colFiltered = IsColumnFiltered(panel); + + if (rowFiltered == true || colFiltered == true) + { + if (rowFiltered == true) + rowFiltered = UpdateRowFilter(panel); + + if (colFiltered == true) + UpdateColumnFilter(panel); + + UpdateFilterState(panel, rowFiltered, colFiltered); + + return; + } + } + + UpdateFilterState(panel, false, false); + } + finally + { + _lockFilter = false; + + panel.UpdateVisibleRowCount(); + panel.SuperGrid.DoDataFilteringCompleteEvent(panel); + } + } + else + { + panel.UpdateVisibleRowCount(); + } + } + + #region UpdateRowFilter + + private static bool UpdateRowFilter(GridPanel panel) + { + if (panel.FilterEval == null) + { + try + { + panel.FilterEval = new FilterEval( + panel, null, panel.GetFilterMatchType(), panel.FilterExpr); + } + catch + { + return (false); + } + } + + return (true); + } + + #endregion + + #region UpdateColumnFilter + + private static void UpdateColumnFilter(GridPanel panel) + { + foreach (GridColumn col in panel.Columns) + { + if (col.IsFiltered == true) + { + col.FilterError = false; + + if (col.FilterEval == null) + { + try + { + col.FilterEval = new FilterEval( + panel, col, col.GetFilterMatchType(), col.FilterExpr); + } + catch + { + col.FilterError = true; + } + } + } + } + } + + #endregion + + #region UpdateFilterState + + private static void UpdateFilterState( + GridPanel panel, bool rowFiltered, bool colFiltered) + { + if (IsFilteringEnabled(panel) == true) + { + if (panel.VirtualMode == true) + { + if (panel.SuperGrid.DoRefreshFilter(panel) == false) + { + panel.VirtualRows.Clear(); + + panel.DataBinder.UpdateFilter(); + } + } + else + { + int count = panel.Rows.Count; + + if (panel.ShowInsertRow == true) + count--; + + bool root = (panel.FilterLevel & + (FilterLevel.Root | FilterLevel.RootConditional)) != 0; + + UpdateFilterStateEx(panel, root, + panel.Rows, count, rowFiltered, colFiltered); + } + } + } + + #region UpdateFilterStateEx + + private static void UpdateFilterStateEx(GridPanel panel, bool filter, + GridItemsCollection items, int count, bool rowFiltered, bool colFiltered) + { + for (int i = 0; i < count; i++) + { + GridRow row = items[i] as GridRow; + + if (row != null) + { + if (row.IsTempInsertRow == true) + { + row.IsRowFilteredOut = false; + } + else + { + bool expanded = (panel.FilterLevel & FilterLevel.Expanded) != 0; + + if (row.Rows.Count > 0) + { + UpdateFilterStateEx(panel, expanded, + row.Rows, row.Rows.Count, rowFiltered, colFiltered); + } + + bool filteredOut = false; + + if (filter == true) + { + if ((panel.FilterLevel & FilterLevel.RootConditional) != FilterLevel.RootConditional || + row.AnyVisibleItems() == false) + { + if (rowFiltered == true) + { + if (EvalRowFilterState(panel, row, ref filteredOut) == true) + break; + } + + if (filteredOut == false && colFiltered == true) + EvalColumnFilterState(panel, row, ref filteredOut); + } + } + + row.RowFilteredOut = filteredOut; + } + } + else + { + GridContainer cont = items[i] as GridGroup; + + if (cont != null) + { + UpdateFilterStateEx(panel, + true, cont.Rows, cont.Rows.Count, rowFiltered, colFiltered); + } + } + } + } + + #endregion + + #region EvalRowFilterState + + private static bool EvalRowFilterState( + GridPanel panel, GridRow row, ref bool filteredOut) + { + try + { + filteredOut = (panel.FilterEval.Evaluate(row) == false); + } + catch (Exception exp) + { + filteredOut = false; + + bool throwException = false; + bool postError = true; + + if (panel.SuperGrid.DoFilterRowErrorEvent(panel, + row, exp, ref filteredOut, ref throwException, ref postError) == true) + { + return (true); + } + + if (throwException == true) + throw; + + if (postError == true) + MessageBoxEx.Show(exp.Message); + + return (true); + } + + return (false); + } + + #endregion + + #region EvalColumnFilterState + + private static bool EvalColumnFilterState( + GridPanel panel, GridRow row, ref bool filteredOut) + { + foreach (GridColumn col in panel.Columns) + { + if (col.IsFiltered == true) + { + if (col.FilterError == false) + { + try + { + filteredOut = (col.FilterEval.Evaluate(row) == false); + } + catch (Exception exp) + { + col.FilterError = true; + + filteredOut = false; + + bool throwException = false; + bool postError = col.FilterEval.PostError; + + if (panel.SuperGrid.DoFilterColumnErrorEvent(panel, + row, col, exp, ref filteredOut, ref throwException, ref postError) == true) + { + return (true); + } + + if (throwException == true) + throw; + + if (postError == true) + MessageBoxEx.Show((col.Name ?? "[" + col.ColumnIndex + "]") + ":\n" + exp.Message); + + return (true); + } + } + } + + if (filteredOut == true) + break; + } + + return (false); + } + + #endregion + + #endregion + + #region UpdateRowFilterState + + internal static void UpdateRowFilterState(GridPanel panel, GridRow row) + { + bool isPrimary = (row.Parent is GridPanel); + + bool root = (panel.FilterLevel & + (FilterLevel.Root | FilterLevel.RootConditional)) != 0; + + bool expanded = (panel.FilterLevel & FilterLevel.Expanded) != 0; + + if ((isPrimary == true && root == true) || + (isPrimary == false && expanded == true)) + { + bool filteredOut = false; + + bool rowFiltered = IsRowFiltered(panel); + bool colFiltered = IsColumnFiltered(panel); + + if (rowFiltered == true || colFiltered == true) + { + if (rowFiltered == true) + rowFiltered = UpdateRowFilter(panel); + + if (colFiltered == true) + UpdateColumnFilter(panel); + + if (rowFiltered == true) + { + if (EvalRowFilterState(panel, row, ref filteredOut) == true) + return; + } + + if (filteredOut == false && colFiltered == true) + { + if (EvalColumnFilterState(panel, row, ref filteredOut) == true) + return; + } + } + + if (row.RowFilteredOut != filteredOut) + { + row.RowFilteredOut = filteredOut; + + panel.SuperGrid.NeedToUpdateIndicees = true; + } + } + } + + #endregion + + #region IsFiltered + + internal static bool IsFiltered(GridPanel panel) + { + return (IsRowFiltered(panel) || IsColumnFiltered(panel)); + } + + #endregion + + #region IsRowFiltered + + internal static bool IsRowFiltered(GridPanel panel) + { + return (IsRowFilteringEnabled(panel) && + String.IsNullOrEmpty(panel.FilterExpr) == false); + } + + #endregion + + #region IsColumnFiltered + + internal static bool IsColumnFiltered(GridPanel panel) + { + if (IsColumnFilteringEnabled(panel)) + { + foreach (GridColumn col in panel.Columns) + { + if (col.IsFiltered == true) + return (true); + } + } + + return (false); + } + + #endregion + + #region IsFilteringEnabled + + internal static bool IsFilteringEnabled(GridPanel panel) + { + return (IsRowFilteringEnabled(panel) || IsColumnFilteringEnabled(panel)); + } + + #endregion + + #region IsRowFilteringEnabled + + internal static bool IsRowFilteringEnabled(GridPanel panel) + { + return (panel.EnableFiltering == true && + panel.EnableRowFiltering == true); + } + + #endregion + + #region IsColumnFilteringEnabled + + internal static bool IsColumnFilteringEnabled(GridPanel panel) + { + return (panel.EnableFiltering == true && + panel.EnableColumnFiltering == true); + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterDateTimePicker.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterDateTimePicker.Designer.cs new file mode 100644 index 00000000..cb0288df --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterDateTimePicker.Designer.cs @@ -0,0 +1,366 @@ +namespace DevComponents.DotNetBar.SuperGrid +{ + partial class FilterDateTimePicker + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FilterDateTimePicker)); + this.cboDateRelative = new DevComponents.DotNetBar.Controls.ComboBoxEx(); + this.btnApply = new DevComponents.DotNetBar.ButtonX(); + this.btnCustom = new DevComponents.DotNetBar.ButtonX(); + this.cbxDateRelative = new DevComponents.DotNetBar.Controls.CheckBoxX(); + this.cbxDateRange = new DevComponents.DotNetBar.Controls.CheckBoxX(); + this.cbxShowAll = new DevComponents.DotNetBar.Controls.CheckBoxX(); + this.cbxShowNull = new DevComponents.DotNetBar.Controls.CheckBoxX(); + this.cbxShowNotNull = new DevComponents.DotNetBar.Controls.CheckBoxX(); + this.btnOk = new DevComponents.DotNetBar.ButtonX(); + this.btnCancel = new DevComponents.DotNetBar.ButtonX(); + this.dtiFromDate = new DevComponents.Editors.DateTimeAdv.DateTimeInput(); + this.dtiToDate = new DevComponents.Editors.DateTimeAdv.DateTimeInput(); + this.cbxDateSpecific = new DevComponents.DotNetBar.Controls.CheckBoxX(); + this.dtiSpecificDate = new DevComponents.Editors.DateTimeAdv.DateTimeInput(); + this.cbxCustom = new DevComponents.DotNetBar.Controls.CheckBoxX(); + ((System.ComponentModel.ISupportInitialize)(this.dtiFromDate)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.dtiToDate)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.dtiSpecificDate)).BeginInit(); + this.SuspendLayout(); + // + // cboDateRelative + // + resources.ApplyResources(this.cboDateRelative, "cboDateRelative"); + this.cboDateRelative.DisplayMember = "Text"; + this.cboDateRelative.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; + this.cboDateRelative.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboDateRelative.FormattingEnabled = true; + this.cboDateRelative.Name = "cboDateRelative"; + this.cboDateRelative.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.cboDateRelative.MouseDown += new System.Windows.Forms.MouseEventHandler(this.CboDateRelativeMouseDown); + // + // btnApply + // + this.btnApply.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnApply, "btnApply"); + this.btnApply.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnApply.Name = "btnApply"; + this.btnApply.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnApply.Click += new System.EventHandler(this.BtnApplyClick); + // + // btnCustom + // + this.btnCustom.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnCustom, "btnCustom"); + this.btnCustom.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnCustom.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCustom.Name = "btnCustom"; + this.btnCustom.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnCustom.Click += new System.EventHandler(this.BtnCustomClick); + // + // cbxDateRelative + // + resources.ApplyResources(this.cbxDateRelative, "cbxDateRelative"); + // + // + // + this.cbxDateRelative.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.cbxDateRelative.CheckBoxStyle = DevComponents.DotNetBar.eCheckBoxStyle.RadioButton; + this.cbxDateRelative.Name = "cbxDateRelative"; + this.cbxDateRelative.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + // + // cbxDateRange + // + resources.ApplyResources(this.cbxDateRange, "cbxDateRange"); + // + // + // + this.cbxDateRange.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.cbxDateRange.CheckBoxStyle = DevComponents.DotNetBar.eCheckBoxStyle.RadioButton; + this.cbxDateRange.Name = "cbxDateRange"; + this.cbxDateRange.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + // + // cbxShowAll + // + // + // + // + this.cbxShowAll.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.cbxShowAll.CheckBoxStyle = DevComponents.DotNetBar.eCheckBoxStyle.RadioButton; + this.cbxShowAll.Checked = true; + this.cbxShowAll.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbxShowAll.CheckValue = "Y"; + resources.ApplyResources(this.cbxShowAll, "cbxShowAll"); + this.cbxShowAll.Name = "cbxShowAll"; + this.cbxShowAll.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + // + // cbxShowNull + // + resources.ApplyResources(this.cbxShowNull, "cbxShowNull"); + // + // + // + this.cbxShowNull.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.cbxShowNull.CheckBoxStyle = DevComponents.DotNetBar.eCheckBoxStyle.RadioButton; + this.cbxShowNull.Name = "cbxShowNull"; + this.cbxShowNull.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + // + // cbxShowNotNull + // + resources.ApplyResources(this.cbxShowNotNull, "cbxShowNotNull"); + // + // + // + this.cbxShowNotNull.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.cbxShowNotNull.CheckBoxStyle = DevComponents.DotNetBar.eCheckBoxStyle.RadioButton; + this.cbxShowNotNull.Name = "cbxShowNotNull"; + this.cbxShowNotNull.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + // + // btnOk + // + this.btnOk.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnOk, "btnOk"); + this.btnOk.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnOk.Name = "btnOk"; + this.btnOk.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnOk.Click += new System.EventHandler(this.BtnOkClick); + // + // btnCancel + // + this.btnCancel.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnCancel, "btnCancel"); + this.btnCancel.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnCancel.Click += new System.EventHandler(this.BtnCancelClick); + // + // dtiFromDate + // + this.dtiFromDate.AllowEmptyState = false; + resources.ApplyResources(this.dtiFromDate, "dtiFromDate"); + // + // + // + this.dtiFromDate.BackgroundStyle.Class = "DateTimeInputBackground"; + this.dtiFromDate.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiFromDate.ButtonDropDown.Shortcut = DevComponents.DotNetBar.eShortcut.AltDown; + this.dtiFromDate.ButtonDropDown.Visible = true; + this.dtiFromDate.Format = DevComponents.Editors.eDateTimePickerFormat.Long; + this.dtiFromDate.IsPopupCalendarOpen = false; + // + // + // + // + // + // + this.dtiFromDate.MonthCalendar.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiFromDate.MonthCalendar.CalendarDimensions = new System.Drawing.Size(1, 1); + this.dtiFromDate.MonthCalendar.ClearButtonVisible = true; + // + // + // + this.dtiFromDate.MonthCalendar.CommandsBackgroundStyle.BackColor2SchemePart = DevComponents.DotNetBar.eColorSchemePart.BarBackground2; + this.dtiFromDate.MonthCalendar.CommandsBackgroundStyle.BackColorGradientAngle = 90; + this.dtiFromDate.MonthCalendar.CommandsBackgroundStyle.BackColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.BarBackground; + this.dtiFromDate.MonthCalendar.CommandsBackgroundStyle.BorderTop = DevComponents.DotNetBar.eStyleBorderType.Solid; + this.dtiFromDate.MonthCalendar.CommandsBackgroundStyle.BorderTopColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.BarDockedBorder; + this.dtiFromDate.MonthCalendar.CommandsBackgroundStyle.BorderTopWidth = 1; + this.dtiFromDate.MonthCalendar.CommandsBackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiFromDate.MonthCalendar.DisplayMonth = new System.DateTime(2012, 5, 1, 0, 0, 0, 0); + // + // + // + this.dtiFromDate.MonthCalendar.NavigationBackgroundStyle.BackColor2SchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBackground2; + this.dtiFromDate.MonthCalendar.NavigationBackgroundStyle.BackColorGradientAngle = 90; + this.dtiFromDate.MonthCalendar.NavigationBackgroundStyle.BackColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBackground; + this.dtiFromDate.MonthCalendar.NavigationBackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiFromDate.MonthCalendar.TodayButtonVisible = true; + this.dtiFromDate.Name = "dtiFromDate"; + this.dtiFromDate.ShowUpDown = true; + this.dtiFromDate.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.dtiFromDate.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DtiDateRangeMouseDown); + // + // dtiToDate + // + this.dtiToDate.AllowEmptyState = false; + resources.ApplyResources(this.dtiToDate, "dtiToDate"); + // + // + // + this.dtiToDate.BackgroundStyle.Class = "DateTimeInputBackground"; + this.dtiToDate.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiToDate.ButtonDropDown.Shortcut = DevComponents.DotNetBar.eShortcut.AltDown; + this.dtiToDate.ButtonDropDown.Visible = true; + this.dtiToDate.Format = DevComponents.Editors.eDateTimePickerFormat.Long; + this.dtiToDate.IsPopupCalendarOpen = false; + // + // + // + // + // + // + this.dtiToDate.MonthCalendar.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiToDate.MonthCalendar.CalendarDimensions = new System.Drawing.Size(1, 1); + this.dtiToDate.MonthCalendar.ClearButtonVisible = true; + // + // + // + this.dtiToDate.MonthCalendar.CommandsBackgroundStyle.BackColor2SchemePart = DevComponents.DotNetBar.eColorSchemePart.BarBackground2; + this.dtiToDate.MonthCalendar.CommandsBackgroundStyle.BackColorGradientAngle = 90; + this.dtiToDate.MonthCalendar.CommandsBackgroundStyle.BackColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.BarBackground; + this.dtiToDate.MonthCalendar.CommandsBackgroundStyle.BorderTop = DevComponents.DotNetBar.eStyleBorderType.Solid; + this.dtiToDate.MonthCalendar.CommandsBackgroundStyle.BorderTopColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.BarDockedBorder; + this.dtiToDate.MonthCalendar.CommandsBackgroundStyle.BorderTopWidth = 1; + this.dtiToDate.MonthCalendar.CommandsBackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiToDate.MonthCalendar.DisplayMonth = new System.DateTime(2012, 5, 1, 0, 0, 0, 0); + // + // + // + this.dtiToDate.MonthCalendar.NavigationBackgroundStyle.BackColor2SchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBackground2; + this.dtiToDate.MonthCalendar.NavigationBackgroundStyle.BackColorGradientAngle = 90; + this.dtiToDate.MonthCalendar.NavigationBackgroundStyle.BackColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBackground; + this.dtiToDate.MonthCalendar.NavigationBackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiToDate.MonthCalendar.TodayButtonVisible = true; + this.dtiToDate.Name = "dtiToDate"; + this.dtiToDate.ShowUpDown = true; + this.dtiToDate.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.dtiToDate.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DtiDateRangeMouseDown); + // + // cbxDateSpecific + // + resources.ApplyResources(this.cbxDateSpecific, "cbxDateSpecific"); + // + // + // + this.cbxDateSpecific.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.cbxDateSpecific.CheckBoxStyle = DevComponents.DotNetBar.eCheckBoxStyle.RadioButton; + this.cbxDateSpecific.Name = "cbxDateSpecific"; + this.cbxDateSpecific.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + // + // dtiSpecificDate + // + this.dtiSpecificDate.AllowEmptyState = false; + resources.ApplyResources(this.dtiSpecificDate, "dtiSpecificDate"); + this.dtiSpecificDate.AutoSelectDate = true; + // + // + // + this.dtiSpecificDate.BackgroundStyle.Class = "DateTimeInputBackground"; + this.dtiSpecificDate.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiSpecificDate.ButtonDropDown.Shortcut = DevComponents.DotNetBar.eShortcut.AltDown; + this.dtiSpecificDate.ButtonDropDown.Visible = true; + this.dtiSpecificDate.Format = DevComponents.Editors.eDateTimePickerFormat.Long; + this.dtiSpecificDate.IsPopupCalendarOpen = false; + // + // + // + // + // + // + this.dtiSpecificDate.MonthCalendar.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiSpecificDate.MonthCalendar.CalendarDimensions = new System.Drawing.Size(1, 1); + this.dtiSpecificDate.MonthCalendar.ClearButtonVisible = true; + // + // + // + this.dtiSpecificDate.MonthCalendar.CommandsBackgroundStyle.BackColor2SchemePart = DevComponents.DotNetBar.eColorSchemePart.BarBackground2; + this.dtiSpecificDate.MonthCalendar.CommandsBackgroundStyle.BackColorGradientAngle = 90; + this.dtiSpecificDate.MonthCalendar.CommandsBackgroundStyle.BackColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.BarBackground; + this.dtiSpecificDate.MonthCalendar.CommandsBackgroundStyle.BorderTop = DevComponents.DotNetBar.eStyleBorderType.Solid; + this.dtiSpecificDate.MonthCalendar.CommandsBackgroundStyle.BorderTopColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.BarDockedBorder; + this.dtiSpecificDate.MonthCalendar.CommandsBackgroundStyle.BorderTopWidth = 1; + this.dtiSpecificDate.MonthCalendar.CommandsBackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiSpecificDate.MonthCalendar.DisplayMonth = new System.DateTime(2012, 5, 1, 0, 0, 0, 0); + // + // + // + this.dtiSpecificDate.MonthCalendar.NavigationBackgroundStyle.BackColor2SchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBackground2; + this.dtiSpecificDate.MonthCalendar.NavigationBackgroundStyle.BackColorGradientAngle = 90; + this.dtiSpecificDate.MonthCalendar.NavigationBackgroundStyle.BackColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelBackground; + this.dtiSpecificDate.MonthCalendar.NavigationBackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.dtiSpecificDate.MonthCalendar.TodayButtonVisible = true; + this.dtiSpecificDate.Name = "dtiSpecificDate"; + this.dtiSpecificDate.ShowUpDown = true; + this.dtiSpecificDate.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.dtiSpecificDate.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DtiSpecificDateMouseDown); + // + // cbxCustom + // + resources.ApplyResources(this.cbxCustom, "cbxCustom"); + // + // + // + this.cbxCustom.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.cbxCustom.CheckBoxStyle = DevComponents.DotNetBar.eCheckBoxStyle.RadioButton; + this.cbxCustom.Name = "cbxCustom"; + this.cbxCustom.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + // + // FilterDateTimePicker + // + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.Controls.Add(this.dtiToDate); + this.Controls.Add(this.dtiFromDate); + this.Controls.Add(this.dtiSpecificDate); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOk); + this.Controls.Add(this.cbxShowNotNull); + this.Controls.Add(this.cbxShowNull); + this.Controls.Add(this.cboDateRelative); + this.Controls.Add(this.btnApply); + this.Controls.Add(this.btnCustom); + this.Controls.Add(this.cbxCustom); + this.Controls.Add(this.cbxDateSpecific); + this.Controls.Add(this.cbxDateRelative); + this.Controls.Add(this.cbxDateRange); + this.Controls.Add(this.cbxShowAll); + this.DoubleBuffered = true; + this.MinimumSize = new System.Drawing.Size(258, 340); + this.Name = "FilterDateTimePicker"; + ((System.ComponentModel.ISupportInitialize)(this.dtiFromDate)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.dtiToDate)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.dtiSpecificDate)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private DevComponents.DotNetBar.Controls.CheckBoxX cbxShowAll; + private DevComponents.DotNetBar.Controls.CheckBoxX cbxDateRange; + private DevComponents.DotNetBar.Controls.CheckBoxX cbxDateRelative; + private ButtonX btnCustom; + private DevComponents.DotNetBar.Controls.ComboBoxEx cboDateRelative; + private DevComponents.DotNetBar.Controls.CheckBoxX cbxShowNull; + private DevComponents.DotNetBar.Controls.CheckBoxX cbxShowNotNull; + private ButtonX btnOk; + private ButtonX btnCancel; + internal ButtonX btnApply; + private DevComponents.Editors.DateTimeAdv.DateTimeInput dtiFromDate; + private DevComponents.Editors.DateTimeAdv.DateTimeInput dtiToDate; + private DevComponents.DotNetBar.Controls.CheckBoxX cbxDateSpecific; + private DevComponents.Editors.DateTimeAdv.DateTimeInput dtiSpecificDate; + private DevComponents.DotNetBar.Controls.CheckBoxX cbxCustom; + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterDateTimePicker.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterDateTimePicker.cs new file mode 100644 index 00000000..073ca1b4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterDateTimePicker.cs @@ -0,0 +1,769 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// FilterDateTimePicker + /// + [ToolboxItem(false)] + public partial class FilterDateTimePicker : UserControl + { + #region Events + + #region ValueChanged + + /// + /// Occurs when the DateTimePicker value has changed + /// + [Description("Occurs when the DateTimePicker value has changed.")] + public event EventHandler ValueChanged; + + #endregion + + #endregion + + #region Static data + + private static bool _localizedStringsLoaded; + + private static string _filterByRelativeDateString = "Filter by relative date"; + private static string _filterBySpecificDateString = "Filter by specific date"; + private static string _filterByDateRangeString = "Filter by date range"; + + private static string _currentMonth = "Current month"; + private static string _currentYear = "Current year"; + + private static string _lastMonthPeriod = "Last month period"; + private static string _last3MonthPeriod = "Last 3 month period"; + private static string _last6MonthPeriod = "Last 6 month period"; + private static string _last9MonthPeriod = "Last 9 month period"; + + private static string _lastYear = "Last Year"; + private static string _last5YearPeriod = "Last 5 year period"; + private static string _last10YearPeriod = "Last 10 year period"; + + #endregion + + #region Private variables + + private GridColumn _GridColumn; + private string _CustomExpr; + private bool _Cancel; + + #endregion + + /// + /// FilterDateTimePicker + /// + /// + public FilterDateTimePicker(GridColumn gridColumn) + { + InitializeComponent(); + + SuperGridControl sg = gridColumn.SuperGrid; + + LoadLocalizedStrings(sg); + + cbxShowAll.Text = sg.FilterShowAllString; + cbxShowNull.Text = sg.FilterShowNullString; + cbxShowNotNull.Text = sg.FilterShowNotNullString; + + if (string.IsNullOrEmpty(cbxShowNull.Text) == true) + cbxShowNull.Visible = false; + + if (string.IsNullOrEmpty(cbxShowNotNull.Text) == true) + cbxShowNotNull.Visible = false; + + if (cbxShowNull.Visible == false || cbxShowNotNull.Visible == false) + { + int y = (cbxDateRelative.Location.Y - cbxShowAll.Size.Height) / 2; + + cbxShowAll.Location = new Point(cbxShowAll.Location.X, y); + + if (cbxShowNull.Visible == true) + cbxShowNull.Location = new Point(cbxShowNull.Location.X, y); + + if (cbxShowNotNull.Visible == true) + cbxShowNotNull.Location = new Point(cbxShowNotNull.Location.X, y); + } + + btnApply.Text = sg.FilterApplyString; + + if (sg.FilterCustomString != null) + { + cbxCustom.Text = sg.FilterCustomString; + btnCustom.Text = sg.FilterCustomString + "..."; + } + else + { + cbxCustom.Visible = false; + btnCustom.Visible = false; + } + + cbxDateRelative.Text = _filterByRelativeDateString; + cbxDateSpecific.Text = _filterBySpecificDateString; + cbxDateRange.Text = _filterByDateRangeString; + + cboDateRelative.Items.Add(CurrentMonth); + cboDateRelative.Items.Add(CurrentYear); + cboDateRelative.Items.Add(LastMonthPeriod); + cboDateRelative.Items.Add(Last3MonthPeriod); + cboDateRelative.Items.Add(Last6MonthPeriod); + cboDateRelative.Items.Add(Last9MonthPeriod); + cboDateRelative.Items.Add(LastYear); + cboDateRelative.Items.Add(Last5YearPeriod); + cboDateRelative.Items.Add(Last10YearPeriod); + + cboDateRelative.SelectedIndex = 0; + + _GridColumn = gridColumn; + + FilterColumnHeaderVisualStyle style = _GridColumn.GetFilterStyle(StyleType.Default); + + Font = style.Font; + BackColor = style.Background.Color1; + + Cancel = false; + } + + #region Public properties + + #region AcceptButton + + /// + /// AcceptButton + /// + public IButtonControl AcceptButton + { + get { return (btnApply); } + } + + #endregion + + #region Cancel + + /// + /// Cancel + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + + #region CurrentMonth + + /// + /// CurrentMonth + /// + [Localizable(true)] + public string CurrentMonth + { + get { return (_currentMonth); } + set { _currentMonth = value; } + } + + #endregion + + #region CurrentYear + + /// + /// CurrentYear + /// + [Localizable(true)] + public string CurrentYear + { + get { return (_currentYear); } + set { _currentYear = value; } + } + + #endregion + + #region CustomFilter + + /// + /// CustomFilter + /// + [Localizable(true)] + public string CustomFilter + { + get { return ("Custom Filter"); } + } + + #endregion + + #region LastMonthPeriod + + /// + /// LastMonthPeriod + /// + [Localizable(true)] + public string LastMonthPeriod + { + get { return (_lastMonthPeriod); } + set { _lastMonthPeriod = value; } + } + + #endregion + + #region Last3MonthPeriod + + /// + /// Last3MonthPeriod + /// + [Localizable(true)] + public string Last3MonthPeriod + { + get { return (_last3MonthPeriod); } + set { _last3MonthPeriod = value; } + } + + #endregion + + #region Last6MonthPeriod + + /// + /// Last6MonthPeriod + /// + [Localizable(true)] + public string Last6MonthPeriod + { + get { return (_last6MonthPeriod); } + set { _last6MonthPeriod = value; } + } + + #endregion + + #region Last9MonthPeriod + + /// + /// Last9MonthPeriod + /// + [Localizable(true)] + public string Last9MonthPeriod + { + get { return (_last9MonthPeriod); } + set { _last9MonthPeriod = value; } + } + + #endregion + + #region LastYear + + /// + /// LastYear + /// + [Localizable(true)] + public string LastYear + { + get { return (_lastYear); } + set { _lastYear = value; } + } + + #endregion + + #region Last5YearPeriod + + /// + /// Last5YearPeriod + /// + [Localizable(true)] + public string Last5YearPeriod + { + get { return (_last5YearPeriod); } + set { _last5YearPeriod = value; } + } + + #endregion + + #region Last10YearPeriod + + /// + /// Last10YearPeriod + /// + [Localizable(true)] + public string Last10YearPeriod + { + get { return (_last10YearPeriod); } + set { _last10YearPeriod = value; } + } + + #endregion + + #endregion + + #region GetFilterExpr + + /// + /// GetFilterExpr + /// + /// + public string GetFilterExpr() + { + if (cbxCustom.Checked == true) + return (_CustomExpr); + + if (cbxDateSpecific.Checked == true) + return (DateSpecificExpr); + + if (cbxDateRange.Checked == true) + return (DateRangeExpr); + + if (cbxDateRelative.Checked == true) + return (DateRelativeExpr); + + if (cbxShowNull.Checked == true) + return (ShowNullExpr); + + if (cbxShowNotNull.Checked == true) + return (ShowNotNullExpr); + + return (null); + } + + #region ShowNullExpr + + private string ShowNullExpr + { + get { return ("[" + _GridColumn.Name + "] = null"); } + } + + #endregion + + #region ShowNotNullExpr + + private string ShowNotNullExpr + { + get { return ("[" + _GridColumn.Name + "] != null"); } + } + + #endregion + + #region DateSpecificExpr + + private string DateSpecificExpr + { + get { return ("Date([" + _GridColumn.Name +"]) = Date(#" + + dtiSpecificDate.Value.Date.ToShortDateString() + "#)"); } + } + + #endregion + + #region DateRangeExpr + + private string DateRangeExpr + { + get + { + return ("Date([" + + _GridColumn.Name + "]) >= #" + dtiFromDate.Value.ToShortDateString() + "# And Date([" + + _GridColumn.Name + "]) <= #" + dtiToDate.Value.ToShortDateString() + "#"); + } + } + + #endregion + + #region DateRelativeExpr + + private string DateRelativeExpr + { + get + { + string cname = "[" + _GridColumn.Name + "]"; + + switch (cboDateRelative.SelectedIndex) + { + case (int)RelativeFilter.CurrentMonth: + return (CurrentMonthExpr(cname)); + + case (int)RelativeFilter.CurrentYear: + return (CurrentYearExpr(cname)); + + case (int)RelativeFilter.LastMonthPeriod: + return (LastMonthExpr(cname, 1)); + + case (int)RelativeFilter.Last3MonthPeriod: + return (LastMonthExpr(cname, 3)); + + case (int)RelativeFilter.Last6MonthPeriod: + return (LastMonthExpr(cname, 6)); + + case (int)RelativeFilter.Last9MonthPeriod: + return (LastMonthExpr(cname, 9)); + + case (int) RelativeFilter.LastYear: + return (LastYearExpr(cname, 1)); + + case (int)RelativeFilter.Last5YearPeriod: + return (LastYearExpr(cname, 5)); + + case (int)RelativeFilter.Last10YearPeriod: + return (LastYearExpr(cname, 10)); + } + + return (null); + } + } + + #region CurrentMonthExpr + + private string CurrentMonthExpr(string cname) + { + string s = String.Format( + "Year({0}) = Year() And Month({0}) = Month()", cname); + + return (s); + } + + #endregion + + #region LastMonthExpr + + private string LastMonthExpr(string cname, int span) + { + string s = String.Format( + "Date({0}) Is Between " + + "FirstOfMonth(AddMonths(Date(), {1})) And " + + "EndOfMonth(Date())", cname, -span); + + return (s); + } + + #endregion + + #region CurrentYearExpr + + private string CurrentYearExpr(string cname) + { + string s = String.Format( + "Year({0}) = Year()", cname); + + return (s); + } + + #endregion + + #region LastYearExpr + + private string LastYearExpr(string cname, int span) + { + string s = String.Format( + "Year({0}) Is Between " + + "Year(AddYears(Date(), {1})) And " + + "Year()", cname, -span); + + return (s); + } + + #endregion + + #endregion + + #endregion + + #region ProcessTabKey + + /// + /// ProcessTabKey + /// + /// + /// + protected override bool ProcessTabKey(bool forward) + { + return (SelectNextControl(ActiveControl, forward, false, false, true)); + } + + #endregion + + #region ProcessDialogKey + + /// + /// ProcessDialogKey + /// + /// + /// + protected override bool ProcessDialogKey(Keys keyData) + { + if (keyData == Keys.Escape) + Cancel = true; + + else if (keyData == Keys.Enter) + OnValueChanged(); + + return base.ProcessDialogKey(keyData); + } + + #endregion + + #region BtnCustomClick + + private void BtnCustomClick(object sender, EventArgs e) + { + cbxCustom.Checked = true; + + bool ok = LaunchCustomDialog(_CustomExpr); + + _GridColumn.SuperGrid.Focus(); + + if (ok == true) + OnValueChanged(); + } + + #region LaunchCustomDialog + + private bool LaunchCustomDialog(string filterExpr) + { + GridPanel panel = _GridColumn.GridPanel; + + if (panel.SuperGrid.FilterUseExtendedCustomDialog == true) + { + CustomFilterEx cf = new CustomFilterEx(panel, _GridColumn, filterExpr); + + cf.Text = "'" + _GridColumn.Name + "'" + CustomFilter; + cf.ShowInPopupVisible = false; + + DialogResult dr = cf.ShowDialog(); + + if (dr == DialogResult.OK) + { + _CustomExpr = cf.FilterExpr; + + return (true); + } + } + else + { + CustomFilter cf = new CustomFilter(panel, _GridColumn, filterExpr); + + cf.Text = "'" + _GridColumn.Name + "'" + CustomFilter; + + DialogResult dr = cf.ShowDialog(); + + if (dr == DialogResult.OK) + { + _CustomExpr = cf.FilterExpr; + + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region BtnApplyClick + + private void BtnApplyClick(object sender, EventArgs e) + { + OnValueChanged(); + } + + #endregion + + #region BtnOkClick + + private void BtnOkClick(object sender, EventArgs e) + { + OnClose(); + } + + #endregion + + #region BtnCancelClick + + private void BtnCancelClick(object sender, EventArgs e) + { + OnCancel(); + } + + #endregion + + #region OnValueChanged + + private void OnValueChanged() + { + Parent.Invalidate(); + + if (ValueChanged != null) + ValueChanged(this, EventArgs.Empty); + } + + #endregion + + #region OnClose + + private void OnClose() + { + OnValueChanged(); + + PopupDropDown pdd = Parent as PopupDropDown; + + if (pdd != null) + pdd.Hide(); + } + + #endregion + + #region OnCancel + + private void OnCancel() + { + _Cancel = true; + + PopupDropDown pdd = Parent as PopupDropDown; + + if (pdd != null) + pdd.Hide(); + } + + #endregion + + #region DtiSpecificDateMouseDown + + private void DtiSpecificDateMouseDown(object sender, MouseEventArgs e) + { + cbxDateSpecific.Checked = true; + } + + #endregion + + #region DtiDateRangeMouseDown + + private void DtiDateRangeMouseDown(object sender, MouseEventArgs e) + { + cbxDateRange.Checked = true; + } + + #endregion + + #region CboDateRelativeMouseDown + + private void CboDateRelativeMouseDown(object sender, MouseEventArgs e) + { + cbxDateRelative.Checked = true; + } + + #endregion + + #region LoadLocalizedStrings + + private void LoadLocalizedStrings(SuperGridControl sg) + { + if (_localizedStringsLoaded == false) + { + using (LocalizationManager lm = new LocalizationManager(sg)) + { + string s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterByRelativeDate)) != "") + _filterByRelativeDateString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterBySpecificDate)) != "") + _filterBySpecificDateString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterByDateRange)) != "") + _filterByDateRangeString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterCurrentMonth)) != "") + _currentMonth = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterCurrentYear)) != "") + _currentYear = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterLastMonthPeriod)) != "") + _lastMonthPeriod = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterLast3MonthPeriod)) != "") + _last3MonthPeriod = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterLast6MonthPeriod)) != "") + _last6MonthPeriod = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterLast9MonthPeriod)) != "") + _last9MonthPeriod = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterLastYear)) != "") + _lastYear = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterLast5YearPeriod)) != "") + _last5YearPeriod = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterLast10YearPeriod)) != "") + _last10YearPeriod = s; + } + + _localizedStringsLoaded = true; + } + } + + #endregion + } + + #region enums + + #region RelativeFilter + + /// + /// RelativeFilter + /// + public enum RelativeFilter + { + /// + /// CurrentMonth + /// + CurrentMonth, + + /// + /// CurrentYear + /// + CurrentYear, + + /// + /// LastMonthPeriod + /// + LastMonthPeriod, + + /// + /// Last3MonthPeriod + /// + Last3MonthPeriod, + + /// + /// Last6MonthPeriod + /// + Last6MonthPeriod, + + /// + /// Last9MonthPeriod + /// + Last9MonthPeriod, + + /// + /// LastYear, + /// + LastYear, + + /// + /// Last5YearPeriod + /// + Last5YearPeriod, + + /// + /// Last10YearPeriod + /// + Last10YearPeriod, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterDateTimePicker.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterDateTimePicker.resx new file mode 100644 index 00000000..e101bb32 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterDateTimePicker.resx @@ -0,0 +1,531 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Top, Left, Right + + + + 15 + + + + 25, 77 + + + 219, 21 + + + 4 + + + cboDateRelative + + + DevComponents.DotNetBar.Controls.ComboBoxEx, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 7 + + + Bottom, Left + + + 9, 307 + + + 69, 21 + + + 12 + + + Apply + + + btnApply + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 8 + + + Top, Right + + + 176, 264 + + + 69, 21 + + + 11 + + + Custom... + + + btnCustom + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 9 + + + Top, Left, Right + + + 3, 52 + + + 241, 20 + + + 3 + + + Filter by relative date: + + + cbxDateRelative + + + DevComponents.DotNetBar.Controls.CheckBoxX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 12 + + + Top, Left, Right + + + 2, 175 + + + 243, 20 + + + 7 + + + Filter by date range: + + + cbxDateRange + + + DevComponents.DotNetBar.Controls.CheckBoxX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 13 + + + 4, 7 + + + 97, 20 + + + 0 + + + Show all + + + cbxShowAll + + + DevComponents.DotNetBar.Controls.CheckBoxX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 14 + + + Top, Left, Right + + + 107, 7 + + + 138, 20 + + + 1 + + + Show null + + + cbxShowNull + + + DevComponents.DotNetBar.Controls.CheckBoxX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 6 + + + Top, Left, Right + + + 107, 28 + + + 138, 20 + + + 2 + + + Show not null + + + cbxShowNotNull + + + DevComponents.DotNetBar.Controls.CheckBoxX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 5 + + + Bottom, Right + + + 103, 307 + + + 69, 21 + + + 106 + + + Ok + + + btnOk + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 4 + + + Bottom, Right + + + 178, 307 + + + 69, 21 + + + 107 + + + Cancel + + + btnCancel + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 3 + + + Top, Left, Right + + + 22, 201 + + + 222, 20 + + + 110 + + + dtiFromDate + + + DevComponents.Editors.DateTimeAdv.DateTimeInput, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 1 + + + Top, Left, Right + + + 22, 227 + + + 222, 20 + + + 111 + + + dtiToDate + + + DevComponents.Editors.DateTimeAdv.DateTimeInput, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 0 + + + Top, Left, Right + + + 2, 113 + + + 243, 20 + + + 5 + + + Filter by specific date: + + + cbxDateSpecific + + + DevComponents.DotNetBar.Controls.CheckBoxX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 11 + + + Top, Left, Right + + + 23, 139 + + + 221, 20 + + + 109 + + + dtiSpecificDate + + + DevComponents.Editors.DateTimeAdv.DateTimeInput, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 2 + + + Top, Left, Right + + + 2, 264 + + + 170, 20 + + + 10 + + + Custom + + + cbxCustom + + + DevComponents.DotNetBar.Controls.CheckBoxX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 10 + + + True + + + 96, 96 + + + 260, 340 + + + FilterDateTimePicker + + + System.Windows.Forms.UserControl, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterEval.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterEval.cs new file mode 100644 index 00000000..7f899abb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterEval.cs @@ -0,0 +1,4106 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Filter Expression evaluator + /// + public class FilterEval + { + #region Static data + + static readonly EmptyFilterOp EmptyOp = new EmptyFilterOp(); + + static bool _localizedStringsLoaded; + + static private string _exprErrorString = "Expression error"; + static private string _missingParenString = "Missing parenthesis"; + static private string _missingQuoteString = "Missing quote"; + static private string _invalidArgCountString = "Invalid number of arguments"; + static private string _invalidArgString = "Invalid argument"; + static private string _invalidEmptyOpString = "Invalid 'empty' operation"; + static private string _invalidDateTimeOpString = "Invalid DateTime operation"; + static private string _invalidStringOpString = "Invalid string operation"; + static private string _invalidBoolOpString = "Invalid bool operation"; + static private string _invalidNumericOpString = "Invalid numeric operation"; + static private string _invalidEvalString = "Invalid logical evaluation"; + static private string _undefinedFunctionString = "Undefined function"; + + static private string dsep = Regex.Escape(NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator); + static private string digit = "\\d+(" + dsep + "\\d+)*"; + + static private string Cref = "((\\[[^\\]]*\\])|(" + digit + "))"; + + static private string Dref = + "(([\\w.]+)|" + + "(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")|" + + "(\'(.*)\')|" + + "(#([^#]*)#))"; + + static private string Bop = "(([()+\\-*/%,\"\\^])|(<=)|(>=)|(<>)|(=)|(<<)|(>>)|(<)|(>)|(!=)|(\\|\\|)|(&&)|(&)|(\\|))"; + + static private string Regs = Cref + "|" + Dref + "|" + Bop; + + #endregion + + #region Private data + + private int _TCount; + private int _PCount; + private FToken[] _PTokens = new FToken[10]; + private List _PfTokens; + + private GridPanel _GridPanel; + private GridColumn _GridColumn; + private GridRow _GridRow; + + private string _Source; + private List _OperandPool; + + private Regex _Regex = new Regex(Regs); + private MatchCollection _Mc; + + private object _Tag; + private FilterMatchType _MatchType; + + private bool _Colorize; + private bool _PostError; + + #endregion + + /// + /// Expression evaluator constructor + /// + ///Associated GridPanel + /// + /// + /// + public FilterEval(GridPanel gridPanel, + GridColumn gridColumn, FilterMatchType matchType, string source) + { + _GridPanel = gridPanel; + _GridColumn = gridColumn; + _MatchType = matchType; + + LoadLocalizedStrings(); + + Source = source; + } + + #region Public properties + + #region GridColumn + + /// + /// Gets the associated Grid GridColumn, if any + /// + public GridColumn GridColumn + { + get { return (_GridColumn); } + } + + #endregion + + #region GridPanel + + /// + /// Gets the associated Grid Panel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + #endregion + + #region Source + + /// + /// Gets or sets the expression source + /// + public string Source + { + get { return (_Source); } + + set + { + _Source = value; + + Tokenize(); + } + } + + #endregion + + #region Tag + + /// + /// Gets or sets user-defined data associated with the object + /// + public object Tag + { + get { return (_Tag); } + set { _Tag = value; } + } + + #endregion + + #endregion + + #region internal Properties + + internal bool PostError + { + get { return (_PostError); } + } + + #endregion + + #region Tokenize code + + private void Tokenize() + { + if (string.IsNullOrEmpty(_Source) == false) + { + _TCount = 0; + + _Mc = _Regex.Matches(_Source); + + _PfTokens = new List(_Mc.Count); + _OperandPool = new List(_Mc.Count); + + Expr(); + + FToken t = GetToken(); + + if (t != FToken.BadToken) + throw new Exception(_exprErrorString); + + foreach (FToken token in _PfTokens) + { + if (token > FToken.Operator) + return; + } + + throw new Exception(_exprErrorString); + } + + if (_PfTokens != null) + _PfTokens.Clear(); + } + + #region Expr + + /// + /// Handles conditional Or operator + /// + private void Expr() + { + Term0(); + + FToken t = GetToken(); + + while (t == FToken.ConditionalOr) + { + List pfTokens = _PfTokens; + _PfTokens = new List(_Mc.Count - _TCount); + + Term0(); + + pfTokens.Add(FToken.ConditionalOrRpn); + pfTokens.Add(ProcessObject(_PfTokens)); + pfTokens.Add(t); + + _PfTokens = pfTokens; + + t = GetToken(); + } + + PutToken(t); + } + + #endregion + + #region Term0 + + /// + /// Handles Conditional And operator + /// + private void Term0() + { + Term1(); + + FToken t = GetToken(); + + while (t == FToken.ConditionalAnd) + { + List pfTokens = _PfTokens; + _PfTokens = new List(_Mc.Count - _TCount); + + Term1(); + + pfTokens.Add(FToken.ConditionalAndRpn); + pfTokens.Add(ProcessObject(_PfTokens)); + pfTokens.Add(t); + + _PfTokens = pfTokens; + + t = GetToken(); + } + + PutToken(t); + } + + #endregion + + #region Term1 + + /// + /// Handles the Logical Or operator + /// + private void Term1() + { + Term2(); + + FToken t = GetToken(); + + while (t == FToken.LogicalOr) + { + Term2(); + + _PfTokens.Add(t); + + t = GetToken(); + } + + PutToken(t); + } + + #endregion + + #region Term2 + + /// + /// Handles Logical Xor operator + /// + private void Term2() + { + Term3(); + + FToken t = GetToken(); + + while (t == FToken.LogicalXor) + { + Term3(); + + _PfTokens.Add(t); + + t = GetToken(); + } + + PutToken(t); + } + + #endregion + + #region Term3 + + /// + /// Handles the Logical And operator + /// + private void Term3() + { + Term4(); + + FToken t = GetToken(); + + while (t == FToken.LogicalAnd) + { + Term4(); + + _PfTokens.Add(t); + + t = GetToken(); + } + + PutToken(t); + } + + #endregion + + #region Term4 + + /// + /// Handles the Comparison operators + /// + private void Term4() + { + int n = GetNegate(); + + Term5(); + + n += GetNegate(); + + FToken t = GetToken(); + + while (t == FToken.Equal || t == FToken.NotEqual || t == FToken.NotEqual2 || + t == FToken.GreaterThan || t == FToken.GreaterThanOrEqual || + t == FToken.LessThan || t == FToken.LessThanOrEqual) + { + n += GetNegate(); + + Term5(); + + if (t == FToken.Equal || t == FToken.NotEqual || t == FToken.NotEqual2) + SetMatchString(); + + _PfTokens.Add(t); + + t = GetToken(); + } + + PutToken(t); + + if (n % 2 == 1) + _PfTokens.Add(FToken.Negate); + } + + #endregion + + #region Term5 + + /// + /// Handles Like, Is, and Between operators + /// + private void Term5() + { + Term6(); + + int n = GetNegate(); + + FToken t = GetToken(); + + while (t == FToken.Like || t == FToken.Is || t == FToken.Between) + { + if (t == FToken.Is) + { + n += GetNegate(); + + FToken t2 = GetToken(); + + if (t2 == FToken.Like || t2 == FToken.Between) + t = t2; + else + PutToken(t2); + } + + Term6(); + + if (t == FToken.Like) + { + SetMatchString(); + } + else if (t == FToken.Between) + { + FToken t2 = GetToken(); + + if (t2 != FToken.ConditionalAnd && t2 != FToken.Comma) + PutToken(t2); + + Term6(); + } + + _PfTokens.Add(t); + + t = GetToken(); + } + + PutToken(t); + + if (n % 2 == 1) + PutToken(FToken.Negate); + } + + #region SetMatchString + + private void SetMatchString() + { + if (_MatchType != FilterMatchType.None) + { + FToken lt = _PfTokens[_PfTokens.Count - 1]; + + if (lt < FToken.Operator) + { + string s = _OperandPool[(int)lt] as string; + + if (s != null) + { + if (_PfTokens.Count <= 2 || _PfTokens[_PfTokens.Count - 2] != FToken.Function) + { + s = GetMatchString(s); + + _OperandPool.Add(s); + + _PfTokens[_PfTokens.Count - 1] = + (FToken)(_OperandPool.Count - 1); + } + } + } + } + } + + #region GetMatchString + + private string GetMatchString(string text) + { + string s = text; + + switch (GridPanel.FilterMatchType) + { + case FilterMatchType.None: + if (GridPanel.FilterIgnoreMatchCase == true) + s = s.ToLower(); + break; + + case FilterMatchType.RegularExpressions: + //Regex.Match("", s); + break; + + case FilterMatchType.Wildcards: + s = Wildcard.WildcardToRegex(text); + Regex.Match("", s); + break; + } + + return (s); + } + + #endregion + + #endregion + + #endregion + + #region Term6 + + /// + /// Handles the Shift Left and Right operators + /// + private void Term6() + { + Term7(); + + FToken t = GetToken(); + + while (t == FToken.ShiftLeft || t == FToken.ShiftRight) + { + Term7(); + + if (ReduceTerm(t) == false) + _PfTokens.Add(t); + + t = GetToken(); + } + + PutToken(t); + } + + #endregion + + #region Term7 + + /// + /// Handles +, - operators + /// + private void Term7() + { + Term8(); + + FToken t = GetToken(); + + while (t == FToken.Add || t == FToken.Subtract) + { + Term8(); + + if (ReduceTerm(t) == false) + _PfTokens.Add(t); + + t = GetToken(); + } + + PutToken(t); + } + + #endregion + + #region Term8 + + /// + /// Handles %, *, and / operators + /// + private void Term8() + { + Factor(); + + FToken t = GetToken(); + + while (t == FToken.Mod || + t == FToken.Multiply || t == FToken.Divide) + { + Factor(); + + if (ReduceTerm(t) == false) + _PfTokens.Add(t); + + t = GetToken(); + } + + PutToken(t); + } + + #endregion + + #region Factor + + /// + /// Handles factor processing + /// + private void Factor() + { + FToken t = GetToken(); + + int n = 0; + + // Unary operators + + while (t == FToken.Add || t == FToken.Subtract) + { + if (t == FToken.Subtract) + n++; + + t = GetToken(); + } + + // Operand processing + + if (t == FToken.LParen) + { + Expr(); + + t = GetToken(); + + if (t != FToken.RParen) + throw new Exception(_missingParenString); + } + else if (t < FToken.Operator) + { + if (Function(t) == false) + _PfTokens.Add(t); + } + else + { + if (_GridColumn != null) + { + FToken t2 = ProcessObject(_GridColumn); + + _PfTokens.Add(t2); + } + + PutToken(t); + } + + if (n % 2 == 1) + { + if (_PfTokens.Count == 0) + throw new Exception(_exprErrorString); + + _PfTokens.Add(FToken.Negate); + } + } + + #endregion + + #region Function + + /// + /// Handles function parsing + /// + /// + /// + private bool Function(FToken e) + { + string s = _OperandPool[(int)e] as string; + + if (s == null) + { + GridColumn col = _OperandPool[(int)e] as GridColumn; + + if (col != null) + s = col.Name ?? col.HeaderText; + } + + if (s != null) + { + s = s.ToLower(); + + FToken t = GetFunction(s); + + if (t != FToken.BadToken) + { + _PfTokens.Add(t); + + t = GetToken(); + + if (t != FToken.LParen) + throw new Exception(_missingParenString); + + ParameterList(e); + + t = GetToken(); + + if (t != FToken.RParen) + throw new Exception(_missingParenString); + + return (true); + } + } + + return (false); + } + + #region GetFunction + + /// + /// Determines whether the parsed string + /// is a one of our function keywords + /// + /// + /// + private FToken GetFunction(string s) + { + FToken t = GetToken(); + + if (t == FToken.LParen) + { + PutToken(t); + + t = FTokenList.GetStringToken(s, FTokenList.TokenListC); + + return ((t != FToken.BadToken) ? t : FToken.User); + } + + PutToken(t); + + return (FToken.BadToken); + } + + #endregion + + #endregion + + #region ParameterList + + /// + /// Handles function parameters + /// + private void ParameterList(FToken e) + { + int n = 0; + + if (_PfTokens[_PfTokens.Count - 1] == FToken.User) + { + _PfTokens.Add(e); + n++; + } + + FToken t = GetToken(); + + while (t != FToken.RParen && t != FToken.BadToken) + { + PutToken(t); + + int count = _PfTokens.Count; + + Expr(); + + if (_PfTokens.Count > count) + n++; + + t = GetToken(); + + if (t != FToken.Comma) + break; + + t = GetToken(); + } + + PutToken(t); + + _PfTokens.Add(FToken.Function); + _PfTokens.Add((FToken)n); + } + + #endregion + + #region GetToken + + /// + /// Gets the next parsed token + /// + /// + private FToken GetToken() + { + FToken t = FToken.BadToken; + + if (_PCount > 0) + { + t = _PTokens[--_PCount]; + } + else + { + if (_TCount < _Mc.Count) + { + string s = _Mc[_TCount].Value; + + t = FTokenList.GetToken(s); + + if (t == FToken.BadToken) + t = ProcessOperand(s); + + _TCount++; + } + } + + return (t); + } + + #endregion + + #region ProcessOperand + + private FToken ProcessOperand(string s) + { + object o = GetValue(s); + + return (ProcessObject(o)); + } + + #endregion + + #region ProcessObject + + private FToken ProcessObject(object o) + { + int index = _OperandPool.IndexOf(o); + + if (index < 0) + { + _OperandPool.Add(o); + + index = _OperandPool.Count - 1; + } + + return ((FToken)(index)); + } + + #endregion + + #region GetValue + + /// + /// Gets the 'value' from the given string + /// + /// + /// + private object GetValue(string s) + { + s = s.Trim(); + + if (s.Length >= 2) + { + if (IsValueMarker('"', '"', ref s, false) == true) + return (s); + + if (IsValueMarker('\'', '\'', ref s, false) == true) + return (s); + + if (IsValueMarker('#', '#', ref s, true) == true) + return (GetDateValue(s)); + + if (IsValueMarker('[', ']', ref s, true) == true) + return (GetColumnValue(s)); + } + + if (s.Length > 0) + { + if (s.Equals("\"") == true) + throw new Exception(_missingQuoteString); + + GridColumn col = GetColumn(s); + + if (col != null) + return (col); + + string l = s.ToLower(); + + if (l.Equals("true") == true) + return (true); + + if (l.Equals("false") == true) + return (false); + + if (l.Equals("null") == true) + return (null); + + if (l.Equals("empty") == true) + return (EmptyOp); + + double d; + + if (double.TryParse(s, out d) == true) + return (d); + } + + return (s); + } + + #region GetColumn + + private GridColumn GetColumn(string s) + { + s = s.ToUpper(); + + foreach (GridColumn column in _GridPanel.Columns) + { + if (column.Name != null && column.Name.ToUpper().Equals(s)) + { + column.FilterExprUsesName = true; + + return (column); + } + + if (column.HeaderText != null && column.HeaderText.ToUpper().Equals(s)) + { + column.FilterExprUsesName = false; + + return (column); + } + } + + return (null); + } + + #endregion + + #region GetColumnValue + + private GridColumn GetColumnValue(string s) + { + if (s.Length <= 0 && _GridColumn != null) + return (_GridColumn); + + int index; + if (int.TryParse(s, out index) == true) + { + if ((uint)index < _GridPanel.Columns.Count) + return (_GridPanel.Columns[index]); + } + + return (GetColumn(s)); + } + + #endregion + + #region GetDateValue + + private object GetDateValue(string s) + { + if (s.Length > 0) + { + if (Char.IsDigit(s[0]) == true) + return (DateTime.Parse(s)); + + return ((int)Enum.Parse(typeof(DayOfWeek), s)); + } + + return (null); + } + + #endregion + + #region IsValueMarker + + private bool IsValueMarker( + char c1, char c2, ref string s, bool trim) + { + if (s[0] == c1 && s[s.Length - 1] == c2) + { + s = s.Substring(1, s.Length - 2); + + if (trim == true) + s = s.Trim(); + + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region PutToken + + /// + /// Saves the given token for future use + /// + /// + private void PutToken(FToken t) + { + _PTokens[_PCount++] = t; + } + + #endregion + + #region GetNegate + + private int GetNegate() + { + FToken t = GetToken(); + + int n = 0; + + while (t == FToken.Negate) + { + if (t == FToken.Negate) + n++; + + t = GetToken(); + } + + PutToken(t); + + return (n); + } + + #endregion + + #region ReduceTerm + + private bool ReduceTerm(FToken t) + { + if (_PfTokens.Count >= 2) + { + FToken t1 = _PfTokens[_PfTokens.Count - 1]; + FToken t2 = _PfTokens[_PfTokens.Count - 2]; + + if (t1 < FToken.Operator && t2 < FToken.Operator) + { + object o1 = _OperandPool[(int) t1]; + object o2 = _OperandPool[(int) t2]; + + if (o1 != null && o2 != null && o1.GetType() == o2.GetType()) + { + if (o1 is string) + { + switch (t) + { + case FToken.Add: + string s = (string) o2 + (string) o1; + + _PfTokens.RemoveAt(_PfTokens.Count - 1); + _PfTokens[_PfTokens.Count - 1] = ProcessObject(s); + + return (true); + + default: + return (false); + } + } + + if (o1 is int) + { + double d1 = Convert.ToDouble(o1); + double d2 = Convert.ToDouble(o2); + + double d3; + + if (ReduceNumeric(t, d1, d2, out d3) == false) + return (false); + + int n = (int) d3; + + _PfTokens.RemoveAt(_PfTokens.Count - 1); + _PfTokens[_PfTokens.Count - 1] = ProcessObject(n); + + return (true); + } + + if (o1 is double) + { + double d3; + + if (ReduceNumeric(t, (double) o1, (double) o2, out d3) == false) + return (false); + + _PfTokens.RemoveAt(_PfTokens.Count - 1); + _PfTokens[_PfTokens.Count - 1] = ProcessObject(d3); + + return (true); + } + } + } + } + + return (false); + } + + #region ReduceNumeric + + private bool ReduceNumeric( + FToken t, double d1, double d2, out double d3) + { + d3 = 0; + + switch (t) + { + case FToken.Add: + d3 = d2 + d1; + break; + + case FToken.Subtract: + d3 = d2 - d1; + break; + + case FToken.Divide: + d3 = d2 / d1; + break; + + case FToken.Multiply: + d3 = d2 * d1; + break; + + case FToken.ShiftLeft: + d3 = (int)d2 << (int)d1; + break; + + case FToken.ShiftRight: + d3 = (int)d2 >> (int)d1; + break; + + case FToken.Mod: + d3 = d2 % d1; + break; + + default: + return (false); + } + + return (true); + } + + #endregion + + #endregion + + #endregion + + #region Evaluate + + /// + /// Evaluates the previously tokenized code + /// + /// + public bool Evaluate(GridRow row) + { + _GridRow = row; + + return (EvaluateEx(_PfTokens)); + } + + private bool EvaluateEx(List pfTokens) + { + Stack myStack = new Stack(); + + for (int i = 0; i < pfTokens.Count; i++) + { + if (pfTokens[i] < FToken.Operator) + myStack.Push(_OperandPool[(int) pfTokens[i]]); + + else if (pfTokens[i] > FToken.Functions) + myStack.Push(pfTokens[i]); + + else if (pfTokens[i] == FToken.Negate) + EvalNegate(myStack); + + else if (pfTokens[i] == FToken.ConditionalAndRpn) + EvalShortCircuit(myStack, pfTokens[++i], true); + + else if (pfTokens[i] == FToken.ConditionalOrRpn) + EvalShortCircuit(myStack, pfTokens[++i], false); + + else if (pfTokens[i] == FToken.Function) + EvalFunction(myStack, (int) pfTokens[++i]); + + else + EvalOperator(myStack, pfTokens[i]); + } + + return (EvalResult(myStack)); + } + + #region EvalNegate + + private void EvalNegate(Stack myStack) + { + if (myStack.Count < 1) + throw new Exception(_exprErrorString); + + object value = ProcessValue(myStack.Pop()); + + if (value is double) + myStack.Push(-(double)value); + + else if (value is int) + myStack.Push(-(int)value); + + else if (value is bool) + myStack.Push(!(bool)value); + + else if (value == null) + myStack.Push(0); + + else + myStack.Push(0); + } + + #endregion + + #region EvalShortCircuit + + private void EvalShortCircuit( + Stack myStack, FToken token, bool evres) + { + bool res = (bool)myStack.Peek(); + + if (res == evres) + { + res = EvaluateEx( + (List)_OperandPool[(int)token]); + } + + myStack.Push(res); + } + + #endregion + + #region EvalFunction + + /// + /// Evaluates the current function + /// + /// + /// + private void EvalFunction(Stack myStack, int count) + { + object[] args = new object[count]; + + for (int i = count - 1; i >= 0; i--) + args[i] = myStack.Pop(); + + switch ((FToken)myStack.Pop()) + { + case FToken.AddDays: myStack.Push(AddDays(args)); break; + case FToken.AddHours: myStack.Push(AddHours(args)); break; + case FToken.AddMinutes: myStack.Push(AddMinutes(args)); break; + case FToken.AddMonths: myStack.Push(AddMonths(args)); break; + case FToken.AddSeconds: myStack.Push(AddSeconds(args)); break; + case FToken.AddYears: myStack.Push(AddYears(args)); break; + case FToken.Ceiling: myStack.Push(Ceiling(args)); break; + case FToken.Convert: myStack.Push(ConvertTo(args)); break; + case FToken.Date: myStack.Push(Date(args)); break; + case FToken.Day: myStack.Push(Day(args)); break; + case FToken.DayOfWeek: myStack.Push(Dow(args)); break; + case FToken.DayOfYear: myStack.Push(Doy(args)); break; + case FToken.EndOfMonth: myStack.Push(EndOfMonth(args)); break; + case FToken.FirstOfMonth: myStack.Push(FirstOfMonth(args)); break; + case FToken.Floor: myStack.Push(Floor(args)); break; + case FToken.Hour: myStack.Push(Hour(args)); break; + case FToken.IndexOf: myStack.Push(IndexOf(args)); break; + case FToken.Left: myStack.Push(Left(args)); break; + case FToken.Length: myStack.Push(Length(args)); break; + case FToken.LTrim: myStack.Push(LTrim(args)); break; + case FToken.Minute: myStack.Push(Minute(args)); break; + case FToken.Month: myStack.Push(Month(args)); break; + case FToken.Now: myStack.Push(Now(args)); break; + case FToken.Raw: myStack.Push(Raw(args)); break; + case FToken.Right: myStack.Push(Right(args)); break; + case FToken.Round: myStack.Push(Round(args)); break; + case FToken.RTrim: myStack.Push(RTrim(args)); break; + case FToken.Second: myStack.Push(Second(args)); break; + case FToken.Substring: myStack.Push(Substring(args)); break; + case FToken.TimeOfDay: myStack.Push(TimeOfDay(args)); break; + case FToken.ToLower: myStack.Push(ToLower(args)); break; + case FToken.ToString: myStack.Push(ToString(args)); break; + case FToken.TotalDays: myStack.Push(TotalDays(args)); break; + case FToken.TotalHours: myStack.Push(TotalHours(args)); break; + case FToken.TotalMinutes: myStack.Push(TotalMinutes(args)); break; + case FToken.TotalSeconds: myStack.Push(TotalSeconds(args)); break; + case FToken.TotalYears: myStack.Push(TotalYears(args)); break; + case FToken.ToUpper: myStack.Push(ToUpper(args)); break; + case FToken.Trim: myStack.Push(Trim(args)); break; + case FToken.User: myStack.Push(User(args)); break; + case FToken.Year: myStack.Push(Year(args)); break; + } + } + + #region ConvertTo + + /// + /// Converts the given arg to the + /// specified .Net System data type. + /// + /// + /// + private object ConvertTo(object[] args) + { + if (args.Length < 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 1 ? _GridColumn : args[0]); + + string s = args[args.Length - 1] as string; + + if (s == null) + throw new ExceptionArg(); + + if (value == null || value == EmptyOp) + return (String.Empty); + + switch (s) + { + case "System.Boolean": + return (System.Convert.ToBoolean(value)); + + case "System.Byte": + return (System.Convert.ToByte(value)); + + case "System.Char": + return (System.Convert.ToChar(value)); + + case "System.DateTime": + return (System.Convert.ToDateTime(value)); + + case "System.Decimal": + return (System.Convert.ToDecimal(value)); + + case "System.Double": + return (System.Convert.ToDouble(value)); + + case "System.Int16": + return (System.Convert.ToInt16(value)); + + case "System.Int32": + return (System.Convert.ToInt32(value)); + + case "System.Int64": + return (System.Convert.ToInt64(value)); + + case "System.SByte": + return (System.Convert.ToSByte(value)); + + case "System.Single": + return (System.Convert.ToSingle(value)); + + case "System.String": + return (System.Convert.ToString(value)); + + case "System.UInt16": + return (System.Convert.ToUInt16(value)); + + case "System.UInt32": + return (System.Convert.ToUInt32(value)); + + case "System.UInt64": + return (System.Convert.ToUInt64(value)); + + default: + throw new ExceptionArg(); + } + } + + #endregion + + #region DateTime Functions + + #region AddMonths + + /// + /// Adds Months to the given DateTime. + /// + /// + /// + private object AddMonths(object[] args) + { + if (args.Length != 2) + throw new ExceptionArgCount(); + + object value1 = ProcessValue(args[0]); + object value2 = ProcessValue(args[1]); + + if (value1 is DateTime) + { + if (value2 is int) + return (((DateTime)value1).AddMonths((int)value2)); + + if (value2 is double) + return (((DateTime)value1).AddMonths(Convert.ToInt32(value2))); + } + + if (value1 == null || value1 == EmptyOp) + return (value1); + + throw new ExceptionArg(); + } + + #endregion + + #region AddDays + + /// + /// Adds Days to the given DateTime. + /// + /// + /// + private object AddDays(object[] args) + { + if (args.Length != 2) + throw new ExceptionArgCount(); + + object value1 = ProcessValue(args[0]); + object value2 = ProcessValue(args[1]); + + if (value1 is DateTime) + { + if (value2 is int) + return (((DateTime)value1).AddDays((int)value2)); + + if (value2 is double) + return (((DateTime)value1).AddDays(Convert.ToInt32(value2))); + } + + if (value1 == null || value1 == EmptyOp) + return (value1); + + throw new ExceptionArg(); + } + + #endregion + + #region AddHours + + /// + /// Adds Days to the given DateTime. + /// + /// + /// + private object AddHours(object[] args) + { + if (args.Length != 2) + throw new ExceptionArgCount(); + + object value1 = ProcessValue(args[0]); + object value2 = ProcessValue(args[1]); + + if (value1 is DateTime) + { + if (value2 is int) + return (((DateTime)value1).AddHours((int)value2)); + + if (value2 is double) + return (((DateTime)value1).AddHours(Convert.ToInt32(value2))); + } + + if (value1 == null || value1 == EmptyOp) + return (value1); + + throw new ExceptionArg(); + } + + #endregion + + #region AddMinutes + + /// + /// Adds Minutes to the given DateTime. + /// + /// + /// + private object AddMinutes(object[] args) + { + if (args.Length != 2) + throw new ExceptionArgCount(); + + object value1 = ProcessValue(args[0]); + object value2 = ProcessValue(args[1]); + + if (value1 is DateTime) + { + if (value2 is int) + return (((DateTime)value1).AddMinutes((int)value2)); + + if (value2 is double) + return (((DateTime)value1).AddMinutes(Convert.ToInt32(value2))); + } + + if (value1 == null || value1 == EmptyOp) + return (value1); + + throw new ExceptionArg(); + } + + #endregion + + #region AddYears + + /// + /// Adds Years to the given DateTime. + /// + /// + /// + private object AddYears(object[] args) + { + if (args.Length != 2) + throw new ExceptionArgCount(); + + object value1 = ProcessValue(args[0]); + object value2 = ProcessValue(args[1]); + + if (value1 is DateTime) + { + if (value2 is int) + return (((DateTime)value1).AddYears((int)value2)); + + if (value2 is double) + return (((DateTime)value1).AddYears(Convert.ToInt32(value2))); + } + + if (value1 == null || value1 == EmptyOp) + return (value1); + + throw new ExceptionArg(); + } + + #endregion + + #region AddSeconds + + /// + /// Adds Seconds to the given DateTime. + /// + /// + /// + private object AddSeconds(object[] args) + { + if (args.Length != 2) + throw new ExceptionArgCount(); + + object value1 = ProcessValue(args[0]); + object value2 = ProcessValue(args[1]); + + if (value1 is DateTime) + { + if (value2 is int) + return (((DateTime)value1).AddSeconds((int)value2)); + + if (value2 is double) + return (((DateTime)value1).AddSeconds(Convert.ToInt32(value2))); + } + if (value1 == null || value1 == EmptyOp) + return (value1); + + throw new ExceptionArg(); + } + + #endregion + + #region Date + + /// + /// Returns the Date portion of the given DateTime. + /// + /// + /// + private object Date(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return (((DateTime)value).Date); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Day + + /// + /// Returns the Day of the given DateTime. + /// + /// + /// + private object Day(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return (((DateTime)value).Day); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Dow + + /// + /// Returns the DayOfWeek of the given DateTime. + /// + /// + /// + private object Dow(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return ((int)((DateTime)value).DayOfWeek + 1); + + if (value is string) + { + string s = (string)value; + + if (s.Length > 1) + { + s = s.Substring(0, 1).ToUpper() + s.Substring(1).ToLower(); + + if (Enum.IsDefined(typeof(DayOfWeek), s)) + return ((int)Enum.Parse(typeof(DayOfWeek), s) + 1); + } + + return (null); + } + + if (value is int || value is double) + return (Enum.GetName(typeof(DayOfWeek), (double) value - 1)); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Doy + + /// + /// Returns the DayOfYear of the given DateTime. + /// + /// + /// + private object Doy(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return (((DateTime)value).DayOfYear); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region EndOfMonth + + /// + /// Returns the EndOfMonth of the given DateTime. + /// + /// + /// + private object EndOfMonth(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + { + DateTime dt = (DateTime)value; + + dt = new DateTime(dt.Year, dt.Month, 1); + + return (dt.AddMonths(1).AddDays(-dt.Day)); + } + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region FirstOfMonth + + /// + /// Returns the FirstOfMonth of the given DateTime. + /// + /// + /// + private object FirstOfMonth(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + { + DateTime dt = (DateTime) value; + + return (dt.AddDays(1 - dt.Day)); + } + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Hour + + /// + /// Returns the Hour of the given DateTime. + /// + /// + /// + private object Hour(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return (((DateTime)value).Hour); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Minute + + /// + /// Returns the Minute of the given DateTime. + /// + /// + /// + private object Minute(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return (((DateTime)value).Minute); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Month + + /// + /// Returns the Month of the given DateTime. + /// + /// + /// + private object Month(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return (((DateTime)value).Month); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Now + + /// + /// Returns the current DateTime + /// + /// + /// + static private object Now(object[] args) + { + if (args.Length != 0) + throw new ExceptionArgCount(); + + return (DateTime.Now); + } + + #endregion + + #region Year + + /// + /// Returns the Year of the given DateTime. + /// + /// + /// + private object Year(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return (((DateTime)value).Year); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Second + + /// + /// Returns the Minute of the given DateTime. + /// + /// + /// + private object Second(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return (((DateTime)value).Second); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region TimeOfDay + + /// + /// Returns the TimeOfDay of the given DateTime. + /// + /// + /// + private object TimeOfDay(object[] args) + { + if (args.Length != 0 && args.Length != 1) + throw new ExceptionArgCount(); + + object value = (args.Length == 1) + ? ProcessValue(args[0]) : DateTime.Now; + + if (value is DateTime) + return (((DateTime)value).TimeOfDay); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region TotalDays + + /// + /// Returns the TotalDays of the given TimeSpan. + /// + /// + /// + private object TotalDays(object[] args) + { + if (args.Length != 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args[0]); + + if (value is TimeSpan) + return ((TimeSpan)value).TotalDays; + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region TotalHours + + /// + /// Returns the TotalHours of the given TimeSpan. + /// + /// + /// + private object TotalHours(object[] args) + { + if (args.Length != 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args[0]); + + if (value is TimeSpan) + return ((TimeSpan)value).TotalHours; + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region TotalMinutes + + /// + /// Returns the TotalMinutes of the given TimeSpan. + /// + /// + /// + private object TotalMinutes(object[] args) + { + if (args.Length != 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args[0]); + + if (value is TimeSpan) + return ((TimeSpan)value).TotalMinutes; + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region TotalSeconds + + /// + /// Returns the TotalSeconds of the given TimeSpan. + /// + /// + /// + private object TotalSeconds(object[] args) + { + if (args.Length != 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args[0]); + + if (value is TimeSpan) + return ((TimeSpan)value).TotalSeconds; + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region TotalYears + + /// + /// Returns the TotalDays of the given TimeSpan. + /// + /// + /// + private object TotalYears(object[] args) + { + if (args.Length != 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args[0]); + + if (value is TimeSpan) + return ((TimeSpan)value).TotalDays / 365; + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #endregion + + #region Numeric Functions + + #region Ceiling + + /// + /// Returns the smallest whole value + /// greater than or equal to the given value. + /// + /// + /// + private object Ceiling(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + + if (value is double) + return (Math.Ceiling((double)value)); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Floor + + /// + /// Returns the largest whole value + /// less than or equal to the given value. + /// + /// + /// + private object Floor(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + + if (value is double) + return (Math.Floor((double)value)); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Round + + /// + /// Returns the largest whole value + /// less than or equal to the given value. + /// + /// + /// + private object Round(object[] args) + { + if (args.Length > 2) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + object decimals = args.Length > 1 ? ProcessValue(args[args.Length - 1]) : 0d; + + if (value is double && decimals is double) + return (Math.Round((double)value, Convert.ToInt32(decimals))); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #endregion + + #region String Functions + + #region IndexOf + + /// + /// Returns the index of the given + /// string within the alternate specified string. + /// + /// + /// -1 if not found + private object IndexOf(object[] args) + { + if (args.Length < 2 || args.Length > 4) + throw new ExceptionArgCount(); + + object o1 = ProcessValue(args[0]); + object o2 = ProcessValue(args[1]); + + if (o1 is string && o2 is string) + { + string text = (string)o1; + string subText = (string)o2; + + int start = 0; + int len = text.Length; + + if (args.Length > 2) + { + object o3 = ProcessValue(args[2]); + + if (o3 is double == false && o3 is int == false) + throw new ExceptionArg(); + + start = Convert.ToInt32(o3); + + if (args.Length > 3) + { + object o4 = ProcessValue(args[2]); + + if (o4 is double == false && o4 is int == false) + throw new ExceptionArg(); + + len = Math.Min(len, Convert.ToInt32(o4)); + } + } + + return (text.IndexOf(subText, start, len)); + } + + if (o1 == null || o1 == EmptyOp) + return (-1); + + if (o2 == null || o2 == EmptyOp) + return (-1); + + throw new ExceptionArg(); + } + + #endregion + + #region Left + + /// + /// Returns the left part of the given character + /// string with the specified number of characters. + /// + /// + /// + private object Left(object[] args) + { + if (args.Length != 2) + throw new ExceptionArgCount(); + + object text = ProcessValue(args[0]); + + if (text is string) + { + string s = (string)text; + + object len = ProcessValue(args[1]); + + if (len is double == false && len is int == false) + throw new ExceptionArg(); + + int n = Convert.ToInt32(len); + + if (n > s.Length) + n = s.Length; + + return (s.Substring(0, n)); + } + + if (text == null || text == EmptyOp) + return (text); + + throw new ExceptionArg(); + } + + #endregion + + #region Length + + /// + /// Returns the length the given string. + /// + /// + /// + private object Length(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + + if (value is string) + return ((string)value).Length; + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region LTrim + + /// + /// Removes all leading + /// whitespace characters from the given string. + /// + /// + /// + private object LTrim(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + + if (value is string) + return ((string)value).TrimStart(); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Raw + + /// + /// Returns the raw unevaluated cell text (if the cell + /// contains an expression '=123', it is not evaluated as such). + /// + /// + /// + private object Raw(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + return (args.Length == 0 ? _GridColumn : ProcessRawValue(args[0])); + } + + #endregion + + #region Right + + /// + /// Returns the right part of the given character + /// string with the specified number of characters. + /// + /// + /// + private object Right(object[] args) + { + if (args.Length != 2) + throw new ExceptionArgCount(); + + object text = ProcessValue(args[0]); + + if (text is string) + { + string s = (string)text; + + object len = ProcessValue(args[1]); + + if (len is double == false && len is int == false) + throw new ExceptionArg(); + + int n = Convert.ToInt32(len); + + if (n > s.Length) + n = s.Length; + + return (s.Substring(s.Length - n, n)); + } + + if (text == null || text == EmptyOp) + return (text); + + throw new ExceptionArg(); + } + + #endregion + + #region RTrim + + /// + /// Removes all trailing + /// whitespace characters from the given string. + /// + /// + /// + private object RTrim(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + + if (value is string) + return ((string)value).TrimEnd(); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Substring + + /// + /// Returns a substring of the given string. + /// + /// + /// + private object Substring(object[] args) + { + if (args.Length != 2 && args.Length != 3) + throw new ExceptionArgCount(); + + object text = ProcessValue(args[0]); + + if (text is string) + { + string s = (string)text; + + object index = ProcessValue(args[1]); + + if (index is double == false) + throw new ExceptionArg(); + + int n = Convert.ToInt32(index); + + if (args.Length == 3) + { + object length = ProcessValue(args[2]); + + if (length is double == false) + throw new ExceptionArg(); + + return (s.Substring(n, Convert.ToInt32(length))); + } + + return (s.Substring(n)); + } + + if (text == null || text == EmptyOp) + return (text); + + throw new ExceptionArg(); + } + + #endregion + + #region ToLower + + /// + /// Returns a lower cased copy of the given string + /// + /// + /// + private object ToLower(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + + if (value is string) + return ((string)value).ToLower(); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region ToString + + /// + /// Returns the ToString of the given object. + /// + /// + /// + private object ToString(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + + if (value == null || value == EmptyOp) + return (value); + + return (value.ToString()); + } + + #endregion + + #region ToUpper + + /// + /// Returns an upper cased copy of the given string + /// + /// + /// + private object ToUpper(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + + if (value is string) + return ((string)value).ToUpper(); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #region Trim + + /// + /// Removes all leading and trailing + /// whitespace characters from the given string. + /// + /// + /// + private object Trim(object[] args) + { + if (args.Length > 1) + throw new ExceptionArgCount(); + + object value = ProcessValue(args.Length == 0 ? _GridColumn : args[0]); + + if (value is string) + return ((string)value).Trim(); + + if (value == null || value == EmptyOp) + return (value); + + throw new ExceptionArg(); + } + + #endregion + + #endregion + + #region User + + /// + /// Calculates the sum of the given set of values + /// + /// + /// + private object User(object[] args) + { + object o = null; + + object[] uargs = new object[args.Length]; + + for (int i = 0; i < args.Length; i++) + uargs[i] = ProcessValue(args[i]); + + if (_GridPanel.SuperGrid.DoFilterUserFunctionEvent( + _GridRow, uargs, ref o) == false) + { + string s = uargs[0] + " - " + _undefinedFunctionString; + + throw new Exception(s); + } + + return (o); + } + + #endregion + + #endregion + + #region EvalOperator + + private void EvalOperator(Stack myStack, FToken token) + { + if (myStack.Count < 2) + throw new Exception(_exprErrorString); + + _PostError = true; + + object value1 = ProcessValue(myStack.Pop()); + object value2 = ProcessValue(myStack.Pop()); + + if (value1 == EmptyOp || value2 == EmptyOp) + OpEmptyValue(myStack, token, value1, value2); + + else if (value1 is string || value2 is string) + OpStringValue(myStack, token, value1, value2); + + else if (value1 is bool || value2 is bool) + OpBoolValue(myStack, token, value1, value2); + + else if (value1 is DateTime || value2 is DateTime) + OpDateTimeValue(myStack, token, value1, value2); + + else + OpDoubleValue(myStack, token, value1, value2); + } + + #region ProcessValue + + /// + /// Process the given object value + /// + /// + /// + private object ProcessValue(object o) + { + GridColumn col = o as GridColumn; + + if (col != null) + { + if (col.ColumnIndex < _GridRow.Cells.Count) + { + object value = _GridRow.Cells[col.ColumnIndex].Value; + + if (_GridRow.Cells[col.ColumnIndex].IsValueExpression == true) + value = _GridRow.Cells[col.ColumnIndex].GetExpValue((string)value); + + return (value is DBNull ? null : value); + } + + return (EmptyOp); + } + + return (o); + } + + #endregion + + #region ProcessRawValue + + /// + /// Process the given object value + /// + /// + /// + private object ProcessRawValue(object o) + { + GridColumn col = o as GridColumn; + + if (col != null) + { + if (col.ColumnIndex < _GridRow.Cells.Count) + { + object value = _GridRow.Cells[col.ColumnIndex].Value; + + return (value is DBNull ? null : value); + } + + return (EmptyOp); + } + + return (o); + } + + #endregion + + #region OpEmptyValue + + private void OpEmptyValue( + Stack myStack, FToken op, object o1, object o2) + { + switch (op) + { + case FToken.Is: + case FToken.Like: + case FToken.Equal: + case FToken.LessThanOrEqual: + case FToken.GreaterThanOrEqual: + myStack.Push((o2 == EmptyOp && o1 == EmptyOp)); + break; + + case FToken.NotEqual: + case FToken.NotEqual2: + myStack.Push(o2 != o1); + break; + + case FToken.LessThan: + myStack.Push(o2 == o1 ? false : o2 == EmptyOp); + break; + + case FToken.GreaterThan: + myStack.Push(o2 == o1 ? false : o2 != EmptyOp); + break; + + case FToken.LogicalAnd: + case FToken.LogicalXor: + case FToken.Add: + case FToken.Subtract: + case FToken.Multiply: + case FToken.Divide: + case FToken.Mod: + case FToken.ShiftLeft: + case FToken.ShiftRight: + myStack.Push(EmptyOp); + break; + + default: + throw new Exception(_invalidEmptyOpString); + } + } + + #endregion + + #region OpDateTimeValue + + private void OpDateTimeValue( + Stack myStack, FToken op, object o1, object o2) + { + if (op == FToken.Add) + { + OpDateTimeValueAdd(myStack, o1, o2); + } + else if (op == FToken.Subtract) + { + OpDateTimeValueSubtract(myStack, o1, o2); + } + else if ((o1 is DateTime || o1 == null) && (o2 is DateTime || o2 == null)) + { + DateTime d1 = (DateTime)(o1 ?? DateTime.MinValue); + DateTime d2 = (DateTime)(o2 ?? DateTime.MinValue); + + switch (op) + { + case FToken.Is: + case FToken.Equal: + myStack.Push(d2.Equals(d1)); + break; + + case FToken.NotEqual: + case FToken.NotEqual2: + myStack.Push(d2.Equals(d1) == false); + break; + + case FToken.LessThan: + myStack.Push(d2.CompareTo(d1) < 0); + break; + + case FToken.LessThanOrEqual: + myStack.Push(d2.CompareTo(d1) <= 0); + break; + + case FToken.GreaterThan: + myStack.Push(d2.CompareTo(d1) > 0); + break; + + case FToken.GreaterThanOrEqual: + myStack.Push(d2.CompareTo(d1) >= 0); + break; + + case FToken.Between: + object value = ProcessValue(myStack.Pop()); + + if (value == null || value == EmptyOp) + { + myStack.Push(false); + } + else + { + if (value is DateTime == false) + throw new Exception(_invalidDateTimeOpString); + + DateTime d3 = (DateTime)value; + + myStack.Push(d3 >= d2 && d3 <= d1); + } + break; + + default: + throw new Exception(_invalidDateTimeOpString); + } + } + else + { + throw new Exception(_invalidDateTimeOpString); + } + } + + #region OpDateTimeValueAdd + + private void OpDateTimeValueAdd(Stack myStack, object o1, object o2) + { + if (o2 is DateTime) + { + DateTime d2 = (DateTime)o2; + + if (o1 is TimeSpan) + myStack.Push(d2.Add((TimeSpan)o1)); + + else if (o1 is double) + myStack.Push(d2.AddDays((double)o1)); + + else if (o1 == null) + myStack.Push(d2); + + else + throw new Exception(_invalidDateTimeOpString); + } + else + { + throw new Exception(_invalidDateTimeOpString); + } + } + + #endregion + + #region OpDateTimeValueSubtract + + private void OpDateTimeValueSubtract(Stack myStack, object o1, object o2) + { + if (o2 is DateTime) + { + DateTime d2 = (DateTime)o2; + + if (o1 is TimeSpan) + myStack.Push(d2.Add(-(TimeSpan)o1)); + + else if (o1 is DateTime) + myStack.Push(d2 - (DateTime)o1); + + else if (o1 is double) + myStack.Push(d2.AddDays(-(double)o1)); + + else if (o1 == null) + myStack.Push(new TimeSpan(0)); + + else + throw new Exception(_invalidDateTimeOpString); + } + else + { + throw new Exception(_invalidDateTimeOpString); + } + } + + #endregion + + #endregion + + #region OpStringValue + + private void OpStringValue( + Stack myStack, FToken op, object o1, object o2) + { + string s1 = (o1 != null ? o1.ToString() : ""); + string s2 = (o2 != null ? o2.ToString() : ""); + + switch (op) + { + case FToken.Add: + myStack.Push(s2 + s1); + break; + + case FToken.Is: + case FToken.Equal: + if (_MatchType == FilterMatchType.None) + { + if (GridPanel.FilterIgnoreMatchCase == true) + { + s1 = s1.ToLower(); + s2 = s2.ToLower(); + } + + myStack.Push(s2.Equals(s1)); + } + else + { + if (o1 == null || o2 == null) + { + myStack.Push(false); + } + else + { + _PostError = false; + + myStack.Push(Regex.IsMatch(s2, s1, + GridPanel.FilterIgnoreMatchCase ? RegexOptions.IgnoreCase : RegexOptions.None)); + } + } + break; + + case FToken.NotEqual: + case FToken.NotEqual2: + if (_MatchType == FilterMatchType.None) + { + if (GridPanel.FilterIgnoreMatchCase == true) + { + s1 = s1.ToLower(); + s2 = s2.ToLower(); + } + + myStack.Push(s2.Equals(s1) == false); + } + else + { + if (o1 == null || o2 == null) + { + myStack.Push(true); + } + else + { + _PostError = false; + + myStack.Push(Regex.IsMatch(s2, s1, + GridPanel.FilterIgnoreMatchCase ? RegexOptions.IgnoreCase : RegexOptions.None) == false); + } + } + break; + + case FToken.LessThan: + myStack.Push(s2.CompareTo(s1) < 0); + break; + + case FToken.LessThanOrEqual: + myStack.Push(s2.CompareTo(s1) <= 0); + break; + + case FToken.GreaterThan: + myStack.Push(s2.CompareTo(s1) > 0); + break; + + case FToken.GreaterThanOrEqual: + myStack.Push(s2.CompareTo(s1) >= 0); + break; + + case FToken.Like: + if (_MatchType == FilterMatchType.None) + { + if (GridPanel.FilterIgnoreMatchCase == true) + { + s1 = s1.ToLower(); + s2 = s2.ToLower(); + } + + myStack.Push(s2.StartsWith(s1)); + } + else + { + _PostError = false; + + bool match = Regex.IsMatch(s2, s1, + GridPanel.FilterIgnoreMatchCase ? RegexOptions.IgnoreCase : RegexOptions.None); + + myStack.Push(match); + } + break; + + case FToken.Between: + object value = ProcessValue(myStack.Pop()); + + if (value == null || value == EmptyOp) + { + myStack.Push(false); + } + else + { + string s3 = (string)(value); + + myStack.Push(s3.CompareTo(s2) >= 0 && s3.CompareTo(s1) <= 0); + } + break; + + default: + throw new Exception(_invalidStringOpString); + } + } + + #endregion + + #region OpBoolValue + + private void OpBoolValue( + Stack myStack, FToken op, object o1, object o2) + { + int b1 = GetBoolInt(o1); + int b2 = GetBoolInt(o2); + + switch (op) + { + case FToken.LogicalAnd: + myStack.Push((b2 == 1) && (b1 == 1)); + break; + + case FToken.LogicalOr: + myStack.Push((b2 == 1) || (b1 == 1)); + break; + + case FToken.ConditionalAnd: + myStack.Push((b2 == 1) && (b1 == 1)); + break; + + case FToken.ConditionalOr: + myStack.Push((b2 == 1) || (b1 == 1)); + break; + + case FToken.LogicalXor: + myStack.Push((b2 == 1) ^ (b1 == 1)); + break; + + case FToken.Is: + case FToken.Equal: + case FToken.Like: + myStack.Push(b2 == b1); + break; + + case FToken.NotEqual: + case FToken.NotEqual2: + myStack.Push(b2 != b1); + break; + + default: + throw new Exception(_invalidBoolOpString); + } + } + + #region GetBoolInt + + private int GetBoolInt(object o) + { + if (o == null) + return (-1); + + string s = o as string; + + if (s != null) + { + s = s.ToLower().Trim(); + + switch (s) + { + case "y": + case "yes": + case "t": + case "true": + case "on": + case "1": + return (1); + + case "n": + case "no": + case "f": + case "false": + case "off": + case "0": + return (0); + + case "": + case "null": + return (-1); + } + } + + return (Convert.ToBoolean(o) ? 1 : 0); + } + + #endregion + + #endregion + + #region OpDoubleValue + + private void OpDoubleValue( + Stack myStack, FToken op, object o1, object o2) + { + if (o1 == null && o2 == null) + { + switch (op) + { + case FToken.LogicalAnd: + case FToken.LogicalXor: + case FToken.Add: + case FToken.Subtract: + case FToken.Multiply: + case FToken.Divide: + case FToken.Mod: + case FToken.ShiftLeft: + case FToken.ShiftRight: + myStack.Push(0d); + break; + + case FToken.Is: + case FToken.Equal: + case FToken.LessThanOrEqual: + case FToken.GreaterThanOrEqual: + case FToken.Like: + myStack.Push(true); + break; + + case FToken.NotEqual: + case FToken.NotEqual2: + case FToken.LessThan: + case FToken.GreaterThan: + case FToken.ConditionalAnd: + case FToken.ConditionalOr: + myStack.Push(false); + break; + + default: + throw new Exception(_invalidNumericOpString); + } + } + else + { + double d1 = Convert.ToDouble(o1); + double d2 = Convert.ToDouble(o2); + + switch (op) + { + case FToken.LogicalAnd: + myStack.Push((double)((int)d2 & (int)d1)); + break; + + case FToken.LogicalOr: + myStack.Push((double)((int)d2 | (int)d1)); + break; + + case FToken.LogicalXor: + myStack.Push((double)((int)d2 ^ (int)d1)); + break; + + case FToken.Add: + myStack.Push(d2 + d1); + break; + + case FToken.Subtract: + myStack.Push(d2 - d1); + break; + + case FToken.Multiply: + myStack.Push(d2 * d1); + break; + + case FToken.Divide: + myStack.Push(d2 / d1); + break; + + case FToken.Mod: + myStack.Push(d2 % d1); + break; + + case FToken.ShiftLeft: + myStack.Push((double)((int)d2 << (int)d1)); + break; + + case FToken.ShiftRight: + myStack.Push((double)((int)d2 >> (int)d1)); + break; + + case FToken.Equal: + myStack.Push(o1 == null | o2 == null ? false : d1 == d2); + break; + + case FToken.Is: + case FToken.Like: + myStack.Push(d2 == d1); + break; + + case FToken.NotEqual: + case FToken.NotEqual2: + myStack.Push(o1 == null | o2 == null ? true : d1 != d2); + break; + + case FToken.LessThan: + myStack.Push(d2 < d1); + break; + + case FToken.LessThanOrEqual: + myStack.Push(d2 <= d1); + break; + case FToken.GreaterThan: + myStack.Push(d2 > d1); + break; + + case FToken.GreaterThanOrEqual: + myStack.Push(d2 >= d1); + break; + + case FToken.Between: + object value = ProcessValue(myStack.Pop()); + + if (value == null || value == EmptyOp) + { + myStack.Push(false); + } + else + { + double d3 = Convert.ToDouble(value); + + myStack.Push(d3 >= d2 && d3 <= d1); + } + break; + + default: + throw new Exception(_invalidNumericOpString); + } + } + } + + #endregion + + #endregion + + #region EvalResult + + private bool EvalResult(Stack myStack) + { + if (myStack.Count > 0) + { + object o = ProcessValue(myStack.Pop()); + + if (o is bool) + return ((bool)o); + + throw new Exception(_invalidEvalString); + } + + return (false); + } + + #endregion + + #endregion + + #region GetInfix code + + /// + /// GetInfix + /// + /// + public string GetInfix(bool colorize) + { + if (_PfTokens != null) + { + _Colorize = colorize; + + string s = GetInfixEx(_PfTokens); + + if (s.Length > 2) + { + IsValueMarker('(', ')', ref s, false); + + return (s); + } + } + + return (""); + } + + private string GetInfixEx(List pfTokens) + { + if (pfTokens.Count > 0) + { + Stack myStack = new Stack(); + + for (int i = 0; i < pfTokens.Count; i++) + { + if (pfTokens[i] < FToken.Operator) + { + object o = _OperandPool[(int)pfTokens[i]]; + + myStack.Push((o is string) ? "\"" + o + "\"" : o); + } + else if (pfTokens[i] > FToken.Functions) + myStack.Push(pfTokens[i]); + + else if (pfTokens[i] == FToken.Negate) + InfixNegate(myStack); + + else if (pfTokens[i] == FToken.ConditionalAndRpn) + InfixShortCircuit(myStack, pfTokens[++i]); + + else if (pfTokens[i] == FToken.ConditionalOrRpn) + InfixShortCircuit(myStack, pfTokens[++i]); + + else if (pfTokens[i] == FToken.Function) + InfixFunction(myStack, (int)pfTokens[++i]); + + else + InfixOperator(myStack, pfTokens[i]); + } + + return (InfixValue(myStack.Pop())); + } + + return (""); + } + + #region InfixNegate + + private void InfixNegate(Stack myStack) + { + if (myStack.Count < 1) + throw new Exception(_exprErrorString); + + object o = myStack.Pop(); + + if (o is int || o is double) + { + myStack.Push("-" + InfixValue(o)); + } + else + { + myStack.Push(o); + + myStack.Push("(" + + ColorPart("not ", ExprColorPart.Operator) + + InfixValue(myStack.Pop()) + ")"); + } + } + + #endregion + + #region InfixShortCircuit + + private void InfixShortCircuit( + Stack myStack, FToken token) + { + string s = GetInfixEx((List)_OperandPool[(int)token]); + + myStack.Push(s); + } + + #endregion + + #region InfixFunction + + /// + /// Evaluates the current function + /// + /// + /// + private void InfixFunction(Stack myStack, int count) + { + object[] args = new object[count]; + + for (int i = count - 1; i >= 0; i--) + args[i] = myStack.Pop(); + + FToken t = (FToken)myStack.Pop(); + + string func; + int index = 0; + + if (t == FToken.User) + { + func = args[index++].ToString(); + + IsValueMarker('"', '"', ref func, false); + func = ColorPart(func, ExprColorPart.UserFunction); + } + else + { + func = Enum.GetName(typeof(FToken), t); + func = ColorPart(func, ExprColorPart.SysFunction); + } + + StringBuilder sb = new StringBuilder(); + + for (int i=index; i 0) + sb.Length -= 2; + + sb.Insert(0, func + "("); + sb.Append(")"); + + myStack.Push(sb.ToString()); + } + + #endregion + + #region InfixOperator + + private void InfixOperator(Stack myStack, FToken token) + { + if (myStack.Count < 2) + throw new Exception(_exprErrorString); + + string o1 = InfixValue(myStack.Pop()); + string o2 = InfixValue(myStack.Pop()); + + string op = FTokenList.GetOpTokenText(token); + + string s; + + if (token == FToken.Between) + { + string o3 = InfixValue(myStack.Pop()); + + s = o3 + ColorPart(" is between ", ExprColorPart.Operator) + + o2 + ColorPart(" and ", ExprColorPart.Operator) + o1; + } + else if (token == FToken.Like) + { + s = o2 + ColorPart(" is " + op + " ", ExprColorPart.Operator) + o1; + } + else + { + s = o2 + " " + ColorPart(op, ExprColorPart.Operator) + " " + o1; + } + + myStack.Push("(" + s + ")"); + } + + #region InfixValue + + /// + /// Process the given object value + /// + /// + /// + private string InfixValue(object o) + { + GridColumn col = o as GridColumn; + + if (col != null) + return (ColorPart(GetFilterColumnName(col), ExprColorPart.Column)); + + if (o is EmptyFilterOp) + return (ColorPart("empty", ExprColorPart.Operator)); + + if (o == null) + return (ColorPart("null", ExprColorPart.Operator)); + + string s = o.ToString(); + + if (s.StartsWith("\"") && s.EndsWith("\"")) + return (ColorPart(s, ExprColorPart.String)); + + return (s); + } + + #region GetFilterColumnName + + private string GetFilterColumnName(GridColumn gridColumn) + { + if (gridColumn.FilterExprUsesName == false && + string.IsNullOrEmpty(gridColumn.HeaderText) == false) + { + return (gridColumn.HeaderText); + } + + return (gridColumn.Name); + } + + #endregion + + #endregion + + #endregion + + #region ColorPart + + private string ColorPart(string s, ExprColorPart part) + { + if (_Colorize == true) + s = "#@@#" + (int)part + s + "#@@#0"; + + return (s); + } + + #endregion + + #endregion + + #region LoadLocalizedStrings + + private void LoadLocalizedStrings() + { + if (_localizedStringsLoaded == false) + { + using (LocalizationManager lm = new LocalizationManager(_GridPanel.SuperGrid)) + { + string s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterExprError)) != "") + _exprErrorString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterMissingParen)) != "") + _missingParenString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterMissingQuote)) != "") + _missingQuoteString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterInvalidArgCount)) != "") + _invalidArgCountString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterInvalidArg)) != "") + _invalidArgString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterInvalidEmptyOp)) != "") + _invalidEmptyOpString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterInvalidDateTimeOp)) != "") + _invalidDateTimeOpString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterInvalidStringOp)) != "") + _invalidStringOpString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterInvalidBoolOp)) != "") + _invalidBoolOpString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterInvalidNumericOp)) != "") + _invalidNumericOpString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterInvalidEval)) != "") + _invalidEvalString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterUndefinedFunction)) != "") + _undefinedFunctionString = s; + } + + _localizedStringsLoaded = true; + } + } + + #endregion + + #region FTokenList + + internal class FTokenList + { + #region Static data + + internal static TokenPair[] TokenListA = { + new TokenPair("+", FToken.Add), + new TokenPair("-", FToken.Subtract), + new TokenPair("*", FToken.Multiply), + new TokenPair("/", FToken.Divide), + + new TokenPair("=", FToken.Equal), + new TokenPair("!=", FToken.NotEqual), + new TokenPair("<>", FToken.NotEqual2), + new TokenPair("<", FToken.LessThan), + new TokenPair("<=", FToken.LessThanOrEqual), + new TokenPair(">", FToken.GreaterThan), + new TokenPair(">=", FToken.GreaterThanOrEqual), + new TokenPair("(", FToken.LParen), + new TokenPair(")", FToken.RParen), + + new TokenPair("&&", FToken.ConditionalAnd), + new TokenPair("||", FToken.ConditionalOr), + + new TokenPair("&", FToken.LogicalAnd), + new TokenPair("|", FToken.LogicalOr), + new TokenPair("^", FToken.LogicalXor), + new TokenPair("%", FToken.Mod), + new TokenPair("<<", FToken.ShiftLeft), + new TokenPair(">>", FToken.ShiftRight), + new TokenPair(",", FToken.Comma), + }; + + internal static TokenPair[] TokenListB = { + new TokenPair("and", FToken.ConditionalAnd), + new TokenPair("or", FToken.ConditionalOr), + new TokenPair("like", FToken.Like), + new TokenPair("is", FToken.Is), + new TokenPair("not", FToken.Negate), + new TokenPair("between", FToken.Between), + new TokenPair("xor", FToken.LogicalXor), + }; + + internal static TokenPair[] TokenListC = { + new TokenPair("now", FToken.Now), + new TokenPair("date", FToken.Date), + + new TokenPair("tod", FToken.TimeOfDay), + new TokenPair("timeofday", FToken.TimeOfDay), + + new TokenPair("dow", FToken.DayOfWeek), + new TokenPair("dayofweek", FToken.DayOfWeek), + + new TokenPair("doy", FToken.DayOfYear), + new TokenPair("dayofyear", FToken.DayOfYear), + + new TokenPair("firstofmonth", FToken.FirstOfMonth), + new TokenPair("endofmonth", FToken.EndOfMonth), + + new TokenPair("year", FToken.Year), + new TokenPair("years", FToken.Year), + new TokenPair("month", FToken.Month), + new TokenPair("months", FToken.Month), + new TokenPair("day", FToken.Day), + new TokenPair("days", FToken.Day), + new TokenPair("hour", FToken.Hour), + new TokenPair("hours", FToken.Hour), + new TokenPair("minute", FToken.Minute), + new TokenPair("minutes", FToken.Minute), + new TokenPair("second", FToken.Second), + new TokenPair("seconds", FToken.Second), + + new TokenPair("addyears", FToken.AddYears), + new TokenPair("addmonths", FToken.AddMonths), + new TokenPair("adddays", FToken.AddDays), + new TokenPair("addhours", FToken.AddHours), + new TokenPair("addminutes", FToken.AddMinutes), + new TokenPair("addseconds", FToken.AddSeconds), + + new TokenPair("totalyears", FToken.TotalYears), + new TokenPair("totaldays", FToken.TotalDays), + new TokenPair("totalhours", FToken.TotalHours), + new TokenPair("totalminutes", FToken.TotalMinutes), + new TokenPair("totalseconds", FToken.TotalSeconds), + + new TokenPair("ceiling", FToken.Ceiling), + new TokenPair("floor", FToken.Floor), + new TokenPair("round", FToken.Round), + + new TokenPair("length", FToken.Length), + + new TokenPair("raw", FToken.Raw), + new TokenPair("right", FToken.Right), + new TokenPair("left", FToken.Left), + new TokenPair("substring", FToken.Substring), + new TokenPair("indexof", FToken.IndexOf), + + new TokenPair("convert", FToken.Convert), + new TokenPair("tostring", FToken.ToString), + new TokenPair("tolower", FToken.ToLower), + new TokenPair("toupper", FToken.ToUpper), + + new TokenPair("trim", FToken.Trim), + new TokenPair("ltrim", FToken.LTrim), + new TokenPair("rtrim", FToken.RTrim), + }; + + #endregion + + #region GetToken + + public static FToken GetToken(string text) + { + foreach (TokenPair tp in TokenListA) + { + if (tp.Text.Equals(text) == true) + return (tp.Token); + } + + return (GetStringToken(text, TokenListB)); + } + + #endregion + + #region GetStringToken + + public static FToken + GetStringToken(string text, TokenPair[] tokenList) + { + string s = text.ToLower(); + + foreach (TokenPair tp in tokenList) + { + if (tp.Text.Equals(s) == true) + return (tp.Token); + } + + return (FToken.BadToken); + } + + #endregion + + #region GetOpTokenText + + public static string GetOpTokenText(FToken token) + { + foreach (TokenPair tp in TokenListB) + { + if (tp.Token == token) + return (tp.Text); + } + + foreach (TokenPair tp in TokenListA) + { + if (tp.Token == token) + return (tp.Text); + } + + return ("****"); + } + + #endregion + + #region TokenPair + + internal class TokenPair + { + #region Private data + + public readonly string Text; + public readonly FToken Token; + + #endregion + + public TokenPair(string text, FToken token) + { + Text = text; + Token = token; + } + } + + #endregion + } + + #endregion + + #region ExceptionArg/Count + + private class ExceptionArgCount : Exception + { + public ExceptionArgCount() + : base(Name + "(): " + _invalidArgCountString) + { + } + + private static string Name + { + get { return (new StackTrace().GetFrame(2).GetMethod().Name); } + } + } + + private class ExceptionArg : Exception + { + public ExceptionArg() + : base(Name + "(): " + _invalidArgString) + { + } + + private static string Name + { + get { return (new StackTrace().GetFrame(2).GetMethod().Name); } + } + + } + + #endregion + } + + #region FToken + + /// + /// Filter Tokens + /// + internal enum FToken + { + // Anything before this, is an operand + + Operator = 512, + + // Normal operators + + Negate, + + LParen, + RParen, + + Multiply, + Divide, + Mod, + + Add, + Subtract, + + ShiftLeft, + ShiftRight, + + LogicalOr, + LogicalAnd, + LogicalXor, + + Function, + Comma, + + ConditionalOr, + ConditionalAnd, + + ConditionalOrRpn, + ConditionalAndRpn, + + Equal, + GreaterThan, + GreaterThanOrEqual, + LessThan, + LessThanOrEqual, + NotEqual, + NotEqual2, + + Like, + Is, + Between, + + BadToken, + + // Anything after this is a function + + Functions, + + User, + + Ceiling, + Floor, + Round, + + Length, + + Substring, + IndexOf, + Left, + Right, + Raw, + + Convert, + ToString, + ToLower, + ToUpper, + + Trim, + LTrim, + RTrim, + + Now, + Date, + + TimeOfDay, + DayOfWeek, + DayOfYear, + + FirstOfMonth, + EndOfMonth, + + Year, + Month, + Day, + Hour, + Minute, + Second, + + AddYears, + AddMonths, + AddDays, + AddHours, + AddMinutes, + AddSeconds, + + TotalYears, + TotalDays, + TotalHours, + TotalMinutes, + TotalSeconds, + }; + + #endregion + + #region EmptyFilterOp + + /// + /// Empty Filter Operand + /// + public class EmptyFilterOp + { + } + + #endregion + + #region Wildcard + + internal class Wildcard : Regex + { + public Wildcard(string pattern) + : base(WildcardToRegex(pattern)) + { + } + + public Wildcard(string pattern, RegexOptions options) + : base(WildcardToRegex(pattern), options) + { + } + + public static string WildcardToRegex(string pattern) + { + //return "^" + Regex.Escape(pattern). + // Replace("\\*", "[\\S\\s]*"). + // Replace("\\?", "[\\S\\s]") + "$"; + + StringBuilder sb = new StringBuilder(); + + char lastChar = '\0'; + + sb.Append("^"); + + for (int i = 0; i < pattern.Length; i++) + { + char c = pattern[i]; + + if (lastChar != '\\') + { + switch (c) + { + case '.': + case '$': + case '&': + case '^': + case '(': + case ')': + case '{': + case '}': + case '[': + case ']': + case '<': + case '>': + case '+': + case '|': + case '-': + sb.Append("\\"); + sb.Append(c); + break; + + case '*': + sb.Append("[\\S\\s]*"); + break; + + case '?': + sb.Append("[\\S\\s]"); + break; + + default: + sb.Append(c); + break; + } + + lastChar = c; + } + else + { + sb.Append(c); + + lastChar = '\0'; + } + } + + sb.Append("$"); + + return (sb.ToString()); + } + } + + #endregion + + #region ExprColorPart + + internal enum ExprColorPart + { + Default, + Dim, + + Column, + Operator, + String, + SysFunction, + UserFunction, + Error, + + LastEntry + } + + #endregion + + #region ExpressionColors + + /// + /// Expression syntax Colors + /// + [TypeConverter(typeof(ExpressionColorsConverter))] + public class ExpressionColors + { + #region Private variables + + private Color[] _Colors; + + #endregion + + /// + /// Expression syntax Colors + /// + public ExpressionColors() + { + _Colors = new Color[(int)ExprColorPart.LastEntry]; + + _Colors[(int)ExprColorPart.Default] = Color.Black; + _Colors[(int)ExprColorPart.Dim] = Color.DimGray; + _Colors[(int)ExprColorPart.Column] = Color.Green; + _Colors[(int)ExprColorPart.Operator] = Color.Blue; + _Colors[(int)ExprColorPart.String] = Color.Crimson; + _Colors[(int)ExprColorPart.SysFunction] = Color.DarkRed; + _Colors[(int)ExprColorPart.UserFunction] = Color.Teal; + _Colors[(int)ExprColorPart.Error] = Color.Crimson; + } + + #region Public properties + + #region Default + + /// + /// Default text color + /// + [DefaultValue(typeof(Color), "Black")] + public Color Default + { + get { return (_Colors[(int)ExprColorPart.Default]); } + set { _Colors[(int)ExprColorPart.Default] = value; } + } + + #endregion + + #region Dim + + /// + /// Dim text color + /// + [DefaultValue(typeof(Color), "DimGray")] + public Color Dim + { + get { return (_Colors[(int)ExprColorPart.Dim]); } + set { _Colors[(int)ExprColorPart.Dim] = value; } + } + + #endregion + + #region Column + + /// + /// Column Name text color + /// + [DefaultValue(typeof(Color), "Green")] + public Color Column + { + get { return (_Colors[(int)ExprColorPart.Column]); } + set { _Colors[(int)ExprColorPart.Column] = value; } + } + + #endregion + + #region Operator + + /// + /// Operator text color + /// + [DefaultValue(typeof(Color), "Blue")] + public Color Operator + { + get { return (_Colors[(int)ExprColorPart.Operator]); } + set { _Colors[(int)ExprColorPart.Operator] = value; } + } + + #endregion + + #region String + + /// + /// String text color + /// + [DefaultValue(typeof(Color), "Crimson")] + public Color String + { + get { return (_Colors[(int)ExprColorPart.String]); } + set { _Colors[(int)ExprColorPart.String] = value; } + } + + #endregion + + #region SysFunction + + /// + /// System Function text color + /// + [DefaultValue(typeof(Color), "SaddleBrown")] + public Color SysFunction + { + get { return (_Colors[(int)ExprColorPart.SysFunction]); } + set { _Colors[(int)ExprColorPart.SysFunction] = value; } + } + + #endregion + + #region UserFunction + + /// + /// User Function text color + /// + [DefaultValue(typeof(Color), "Teal")] + public Color UserFunction + { + get { return (_Colors[(int)ExprColorPart.UserFunction]); } + set { _Colors[(int)ExprColorPart.UserFunction] = value; } + } + + #endregion + + #region Error + + /// + /// Error text color + /// + [DefaultValue(typeof(Color), "Crimson")] + public Color Error + { + get { return (_Colors[(int)ExprColorPart.Error]); } + set { _Colors[(int)ExprColorPart.Error] = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region Colors + + internal Color[] Colors + { + get { return (_Colors); } + } + + #endregion + + #endregion + } + + #region ExpressionColorsConverter + + /// + /// ExpressionColorsConverter + /// + public class ExpressionColorsConverter : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + return (" "); + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterExprEdit.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterExprEdit.Designer.cs new file mode 100644 index 00000000..38e61f6f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterExprEdit.Designer.cs @@ -0,0 +1,112 @@ +namespace DevComponents.DotNetBar.SuperGrid +{ + partial class FilterExprEdit + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.rtbOutput = new DevComponents.DotNetBar.Controls.RichTextBoxEx(); + this.rtbInput = new DevComponents.DotNetBar.Controls.RichTextBoxEx(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.BackColor = System.Drawing.Color.White; + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Controls.Add(this.rtbOutput, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.rtbInput, 0, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(398, 92); + this.tableLayoutPanel1.TabIndex = 2; + // + // rtbOutput + // + // + // + // + this.rtbOutput.BackgroundStyle.BackColor = System.Drawing.SystemColors.Control; + this.rtbOutput.BackgroundStyle.Class = "RichTextBoxBorder"; + this.rtbOutput.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.rtbOutput.BackgroundStyle.PaddingBottom = 4; + this.rtbOutput.BackgroundStyle.PaddingLeft = 4; + this.rtbOutput.BackgroundStyle.PaddingRight = 4; + this.rtbOutput.BackgroundStyle.PaddingTop = 4; + this.rtbOutput.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtbOutput.Location = new System.Drawing.Point(3, 49); + this.rtbOutput.Name = "rtbOutput"; + this.rtbOutput.ReadOnly = true; + this.rtbOutput.Rtf = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Microsoft S" + + "ans Serif;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs17\\par\r\n}\r\n"; + this.rtbOutput.Size = new System.Drawing.Size(392, 40); + this.rtbOutput.TabIndex = 2; + // + // rtbInput + // + // + // + // + this.rtbInput.BackgroundStyle.Class = "RichTextBoxBorder"; + this.rtbInput.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.rtbInput.BackgroundStyle.PaddingBottom = 4; + this.rtbInput.BackgroundStyle.PaddingLeft = 4; + this.rtbInput.BackgroundStyle.PaddingRight = 4; + this.rtbInput.BackgroundStyle.PaddingTop = 4; + this.rtbInput.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtbInput.Location = new System.Drawing.Point(3, 3); + this.rtbInput.Name = "rtbInput"; + this.rtbInput.Rtf = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Microsoft S" + + "ans Serif;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs17\\par\r\n}\r\n"; + this.rtbInput.Size = new System.Drawing.Size(392, 40); + this.rtbInput.TabIndex = 1; + this.rtbInput.TextChanged += new System.EventHandler(this.RichTextBoxEx1TextChanged); + // + // FilterExprEdit + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.Controls.Add(this.tableLayoutPanel1); + this.Name = "FilterExprEdit"; + this.Size = new System.Drawing.Size(398, 92); + this.tableLayoutPanel1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private DevComponents.DotNetBar.Controls.RichTextBoxEx rtbOutput; + private DevComponents.DotNetBar.Controls.RichTextBoxEx rtbInput; + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterExprEdit.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterExprEdit.cs new file mode 100644 index 00000000..87d09cdf --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterExprEdit.cs @@ -0,0 +1,285 @@ +using System; +using System.Drawing; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid.SuperGrid; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// FilterExprEdit + /// + internal partial class FilterExprEdit : UserControl + { + #region InputTextChanged + + public event EventHandler InputTextChanged; + + #endregion + + #region Private variables + + private GridPanel _GridPanel; + private GridColumn _GridColumn; + + private string[] _Fonts; + private int _FontSize; + + private string _WaterMarkText; + + #endregion + + /// + /// FilterExprEdit + /// + public FilterExprEdit() + { + InitializeComponent(); + + rtbInput.Font = SystemFonts.DialogFont; + + _FontSize = (int)rtbInput.Font.SizeInPoints; + _Fonts = new string[] { rtbInput.Font.Name }; + } + + #region Public properties + + #region GridColumn + + internal GridColumn GridColumn + { + get { return (_GridColumn); } + set { _GridColumn = value; } + } + + #endregion + + #region GridPanel + + internal GridPanel GridPanel + { + get { return (_GridPanel); } + set { _GridPanel = value; } + } + + #endregion + + #region InputText + + internal string InputText + { + get { return (rtbInput.Text); } + + set + { + rtbInput.Text = value; + + UpdateOutput(); + } + } + + #endregion + + #region RtbOutput + + internal RichTextBoxEx RtbOutput + { + get { return (rtbOutput); } + } + + #endregion + + #region WaterMarkText + + internal string WaterMarkText + { + get { return (_WaterMarkText); } + + set + { + _WaterMarkText = value; + + UpdateOutput(); + } + } + + #endregion + + #endregion + + #region SetFocus + + public void SetFocus() + { + rtbInput.Focus(); + } + + #endregion + + #region RichTextBoxEx1TextChanged + + private void RichTextBoxEx1TextChanged(object sender, EventArgs e) + { + if (InputTextChanged != null) + InputTextChanged(this, EventArgs.Empty); + + UpdateOutput(); + } + + #endregion + + #region UpdateOutput + + private void UpdateOutput() + { + if (string.IsNullOrEmpty(rtbInput.Text) == true) + { + OutPutWaterMarkText(rtbOutput); + } + else + { + try + { + FilterMatchType mtype = (_GridColumn != null) + ? _GridColumn.GetFilterMatchType() + : _GridPanel.GetFilterMatchType(); + + FilterEval eval = new FilterEval( + _GridPanel, _GridColumn, mtype, rtbInput.Text); + + OutputRtf(rtbOutput, + eval.GetInfix(_GridPanel.SuperGrid.FilterColorizeCustomExpr)); + } + catch (Exception exp) + { + OutputRtfError(rtbOutput, rtbInput.Text, exp.Message); + } + } + } + + #region OutPutWaterMarkText + + private void OutPutWaterMarkText(RichTextBoxEx rtbOut) + { + if (_GridPanel != null && + string.IsNullOrEmpty(_WaterMarkText) == false) + { + Rtf myRtf = new Rtf(_Fonts, + _GridPanel.SuperGrid.FilterExprColors.Colors); + + myRtf.BeginGroup(true); + + myRtf.Font = 0; + myRtf.FontSize = _FontSize; + myRtf.CenterAlignText(); + + myRtf.ForeColor = (int)ExprColorPart.Dim; + + myRtf.WriteLine(); + myRtf.WriteText(_WaterMarkText); + + myRtf.EndGroup(); + myRtf.Close(); + + rtbOut.Rtf = myRtf.RtfText; + } + else + { + rtbOut.Clear(); + } + } + + #endregion + + #region OutputRtf + + private void OutputRtf(RichTextBoxEx rtb, string s) + { + s = s.Trim(); + + if (string.IsNullOrEmpty(s) == false) + { + Rtf myRtf = new Rtf(_Fonts, + _GridPanel.SuperGrid.FilterExprColors.Colors); + + myRtf.BeginGroup(true); + + myRtf.Font = 0; + myRtf.FontSize = _FontSize; + myRtf.ForeColor = (int)ExprColorPart.Default; + + Regex r = new Regex("(#@@#\\d)"); + MatchCollection mc = r.Matches(s); + + if (mc.Count > 0) + { + int index = 0; + + for (int i = 0; i < mc.Count; i++) + { + Match ma = mc[i]; + + if (ma.Index > index) + myRtf.WriteText(s.Substring(index, ma.Index - index)); + + index = ma.Index + ma.Length; + + myRtf.ForeColor = s[index - 1] - '0'; + } + + if (s.Length > index) + myRtf.WriteText(s.Substring(index, s.Length - index)); + } + else + { + myRtf.WriteText(s); + } + + myRtf.EndGroup(); + myRtf.Close(); + + rtb.Rtf = myRtf.RtfText; + } + else + { + rtb.Text = ""; + } + } + + #endregion + + #region OutputRtfError + + private void OutputRtfError( + RichTextBoxEx rtbOut, string text, string error) + { + Rtf myRtf = new Rtf(_Fonts, + _GridPanel.SuperGrid.FilterExprColors.Colors); + + myRtf.BeginGroup(true); + + myRtf.Font = 0; + myRtf.FontSize = _FontSize; + myRtf.ForeColor = (int)ExprColorPart.Default; + + myRtf.WriteText(text); + myRtf.WriteText(" "); + + myRtf.ForeColor = (int)ExprColorPart.Error; + + myRtf.WriteLine(); + myRtf.WriteLine(); + myRtf.WriteText("(" + error + ")"); + + myRtf.EndGroup(); + myRtf.Close(); + + rtbOut.Rtf = myRtf.RtfText; + } + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterExprEdit.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterExprEdit.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterExprEdit.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterPanel.cs new file mode 100644 index 00000000..b740d533 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterPanel.cs @@ -0,0 +1,1403 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// FilterPanel + /// + [ToolboxItem(false)] + public class FilterPanel : Control + { + #region Static variables + + static FilterPanel _textBoxPanel; + static FilterPanel _checkBoxPanel; + static FilterPanel _comboBoxPanel; + + #endregion + + #region Private variables + + private FilterEditType _FilterType; + + private string _FilterExpr; + private object _FilterValue; + private object _FilterDisplayValue; + + private Size _SizeEx; + private Point _OffsetEx; + + private GridColumn _GridColumn; + private GridFilter _GridFilter; + private Control _Control; + + private FilterColumnHeaderVisualStyle _Style; + + private bool _LockedSelection; + + #endregion + + /// + /// Constructor + /// + public FilterPanel() + { + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + SetStyle(ControlStyles.Selectable, false); + } + + #region Public properties + + #region Control + + /// + /// Control + /// + public Control Control + { + get { return (_Control); } + + internal set + { + if (_Control != value) + { + if (_Control is MyCheckBoxX) + FilterCheckBox = null; + + else if (_Control is ComboBoxEx) + FilterComboBox = null; + + else if (_Control is TextBoxX) + FilterTextBox = null; + } + + if (value != null) + { + Controls.Clear(); + Controls.Add(value); + } + + _Control = value; + } + } + + #endregion + + #region GridColumn + + /// + /// GridColumn + /// + public GridColumn GridColumn + { + get { return (_GridColumn); } + set { _GridColumn = value; } + } + + #endregion + + #region GridFilter + + /// + /// GridFilter + /// + public GridFilter GridFilter + { + get { return (_GridFilter); } + set { _GridFilter = value; } + } + + #endregion + + #region Style + + /// + /// Style + /// + public FilterColumnHeaderVisualStyle Style + { + get { return (_Style); } + set { _Style = (value != null) ? value.Copy() : null; } + } + + #endregion + + #endregion + + #region Internal properties + + #region FilterCheckBox + + internal MyCheckBoxX FilterCheckBox + { + get + { + MyCheckBoxX mcb = Control as MyCheckBoxX; + + if (mcb == null) + { + mcb = new MyCheckBoxX(); + + mcb.ThreeState = true; + mcb.FocusCuesEnabled = false; + + mcb.CheckedChanged += FilterValueChanged; + mcb.LostFocus += ControlLostFocus; + } + + return (mcb); + } + + set + { + MyCheckBoxX mcb = Control as MyCheckBoxX; + + if (mcb != null) + { + mcb.CheckedChanged -= FilterValueChanged; + mcb.LostFocus -= ControlLostFocus; + } + } + } + + #endregion + + #region FilterComboBox + + internal ComboBoxEx FilterComboBox + { + get + { + ComboBoxEx cb = Control as ComboBoxEx; + + if (cb == null) + { + cb = new ComboBoxEx(); + + cb.DrawMode = DrawMode.OwnerDrawFixed; + cb.DropDownStyle = ComboBoxStyle.DropDownList; + + cb.SelectedValueChanged += FilterValueChanged; + cb.LostFocus += ControlLostFocus; + } + + return (cb); + } + + set + { + ComboBoxEx cb = Control as ComboBoxEx; + + if (cb != null) + { + cb.SelectedValueChanged -= FilterValueChanged; + cb.LostFocus -= ControlLostFocus; + } + } + } + + #endregion + + #region FilterTextBox + + internal TextBoxX FilterTextBox + { + get + { + TextBoxX tb = Control as TextBoxX; + + if (tb == null) + { + tb = new TextBoxX(); + + tb.BorderStyle = BorderStyle.None; + + tb.TextChanged += FilterValueChanged; + tb.LostFocus += ControlLostFocus; + + } + + return (tb); + } + + set + { + TextBoxX tb = Control as TextBoxX; + + if (tb != null) + { + tb.TextChanged -= FilterValueChanged; + tb.LostFocus -= ControlLostFocus; + } + } + } + + #endregion + + #region FilterType + + internal FilterEditType FilterType + { + get { return (_FilterType); } + set { _FilterType = value; } + } + + #endregion + + #region OffsetEx + + internal Point OffsetEx + { + get { return (_OffsetEx); } + set { _OffsetEx = value; } + } + + #endregion + + #region SizeEx + + internal Size SizeEx + { + get { return (_SizeEx); } + set { _SizeEx = value; } + } + + #endregion + + #endregion + + #region OnPaintBackground + + /// + /// OnPaintBackground + /// + /// PaintEventArgs + protected override void OnPaintBackground(PaintEventArgs e) + { + Graphics g = e.Graphics; + + if (_Style != null && _GridColumn != null) + { + Rectangle r = ClientRectangle; + + if (r.IsEmpty == false) + { + using (Brush br = _Style.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + } + else + { + base.OnPaintBackground(e); + } + } + + #endregion + + #region GetPreferredSize + + static TextBoxX _sizeTextBox; + static ComboBoxEx _sizeComboBox; + static MyCheckBoxX _sizeCheckBox; + + static internal Size GetPreferredSize( + GridFilter gridFilter, GridColumn gridColumn) + { + Size size = Size.Empty; + + FilterEditType type = gridColumn.GetFilterPanelType(); + + switch (type) + { + case FilterEditType.ComboBox: + if (_sizeComboBox == null) + _sizeComboBox = new ComboBoxEx(); + + _sizeComboBox.Font = gridFilter.GetEffectiveStyle(gridColumn).Font; + + size = _sizeComboBox.GetPreferredSize(Size.Empty); + + size.Height++; + size.Width++; + break; + + case FilterEditType.TextBox: + case FilterEditType.DateTime: + if (_sizeTextBox == null) + _sizeTextBox = new TextBoxX(); + + _sizeTextBox.BorderStyle = BorderStyle.None; + _sizeTextBox.Font = gridFilter.GetEffectiveStyle(gridColumn).Font; + + size = _sizeTextBox.GetPreferredSize(Size.Empty); + break; + + case FilterEditType.CheckBox: + if (_sizeCheckBox == null) + _sizeCheckBox = new MyCheckBoxX(); + + size = Dpi.Size(13, 13); + break; + } + + return (size); + } + + #endregion + + #region RenderCheckBox + + static internal void RenderCheckBox( + Graphics g, GridFilter gf, GridColumn column, Rectangle bounds) + { + object value = column.FilterValue; + + if (_sizeCheckBox == null) + { + _sizeCheckBox = new MyCheckBoxX(); + + _sizeCheckBox.Text = ""; + _sizeCheckBox.BackColor = Color.Transparent; + } + + int width = Dpi.Width13; + int height = Dpi.Height13; + + _sizeCheckBox.Enabled = false; + _sizeCheckBox.Size = new Size(width, height); + _sizeCheckBox.BackColor = GetSimpleColor(gf.GetEffectiveStyle(column)); + + if (value is CheckState) + _sizeCheckBox.CheckState = (CheckState)value; + else + _sizeCheckBox.CheckState = CheckState.Indeterminate; + + Rectangle r = new Rectangle(0, 0, width, height); + + using (Bitmap bm = new Bitmap(width, height)) + { + _sizeCheckBox.DrawToBitmap(bm, r); + + Rectangle t = bounds; + + if (bounds.Width > r.Width) + { + t.X += (t.Width - r.Width - 1) / 2; + t.Width = r.Width; + } + + if (bounds.Height > r.Height) + { + t.Y += (t.Height - r.Height) / 2; + t.Height = r.Height; + } + + g.DrawImage(bm, t); + } + } + + #endregion + + #region GetFilterPanel + + static internal FilterPanel GetFilterPanel(GridColumn gridColumn) + { + FilterEditType type = gridColumn.GetFilterPanelType(); + + if (type != FilterEditType.None) + { + GridFilter gridFilter = gridColumn.GridPanel.Filter; + + FilterPanel fp = GetFilterPanel(gridFilter, type); + + fp.GridFilter = gridFilter; + fp.GridColumn = gridColumn; + + StyleState styleState = gridFilter.GetStyleState(gridColumn, true); + fp.Style = gridFilter.GetEffectiveStyle(gridColumn, styleState); + + fp.InitEditControl(type); + + return (fp); + } + + return (null); + } + + #region InitEditControl + + private void InitEditControl(FilterEditType type) + { + FilterType = type; + + switch (type) + { + case FilterEditType.CheckBox: + InitCheckBoxEdit(); + break; + + case FilterEditType.ComboBox: + InitComboBoxEdit(); + break; + + case FilterEditType.DateTime: + case FilterEditType.TextBox: + InitTextBoxEdit(); + break; + } + } + + #region InitCheckBoxEdit + + private void InitCheckBoxEdit() + { + MyCheckBoxX cb = FilterCheckBox; + + cb.Text = ""; + cb.Enabled = true; + + cb.BackColor = GetSimpleColor(Style); + + Control = cb; + } + + #endregion + + #region InitComboBoxEdit + + private void InitComboBoxEdit() + { + ComboBoxEx cb = FilterComboBox; + + cb.Items.Clear(); + + cb.BackColor = GetSimpleColor(Style); + cb.Font = Style.Font; + cb.FocusCuesEnabled = false; + + Control = cb; + } + + #endregion + + #region InitTextBoxEdit + + private void InitTextBoxEdit() + { + TextBoxX tb = FilterTextBox; + + tb.BackColor = GetSimpleColor(Style); + tb.ForeColor = Style.TextColor; + tb.Font = Style.Font; + + switch (Style.Alignment) + { + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + tb.TextAlign = HorizontalAlignment.Right; + break; + + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + tb.TextAlign = HorizontalAlignment.Center; + break; + + default: + tb.TextAlign = HorizontalAlignment.Left; + break; + } + + Control = tb; + } + + #endregion + + #endregion + + #region GetFilterPanel + + static private FilterPanel GetFilterPanel( + GridFilter gridFilter, FilterEditType type) + { + switch (type) + { + case FilterEditType.CheckBox: + if (_checkBoxPanel == null || _checkBoxPanel.Parent != gridFilter.SuperGrid) + _checkBoxPanel = GetNewFilterPanel(gridFilter); + + return (_checkBoxPanel); + + case FilterEditType.ComboBox: + if (_comboBoxPanel == null || _comboBoxPanel.Parent != gridFilter.SuperGrid) + _comboBoxPanel = GetNewFilterPanel(gridFilter); + + return (_comboBoxPanel); + + case FilterEditType.DateTime: + case FilterEditType.TextBox: + if (_textBoxPanel == null || _textBoxPanel.Parent != gridFilter.SuperGrid) + _textBoxPanel = GetNewFilterPanel(gridFilter); + + return (_textBoxPanel); + } + + return (null); + } + + #region GetNewFilterPanel + + private static FilterPanel GetNewFilterPanel(GridFilter gridFilter) + { + FilterPanel fp = new FilterPanel(); + fp.Visible = false; + + gridFilter.SuperGrid.Controls.Add(fp); + + return (fp); + } + + #endregion + + #endregion + + #region GetFilterType + + private static Type GetFilterType(FilterPanel fp) + { + IGridCellEditControl editor = fp.GridColumn.EditControl; + + if (editor != null) + return (editor.EditorValueType); + + return (typeof(string)); + } + + #endregion + + #region GetSimpleColor + + static internal Color GetSimpleColor(FilterColumnHeaderVisualStyle style) + { + Color color1; + Color color2; + + if (style.Background.BackColorBlend != null && + style.Background.BackColorBlend.IsEmpty == false) + { + IList colors = style.Background.BackColorBlend.Colors; + + color1 = colors[0]; + color2 = colors[colors.Count - 1]; + } + else + { + color1 = style.Background.Color1; + color2 = style.Background.Color2; + } + + if (color2.IsEmpty == true) + return (color1); + + return (Color.FromArgb((color1.R + color2.R) / 2, + (color1.G + color2.G) / 2, (color1.B + color2.B) / 2)); + } + + #endregion + + #endregion + + #region FilterValueChanged + + void FilterValueChanged(object sender, EventArgs e) + { + if (_LockedSelection == false) + { + Control c = (Control) sender; + + FilterPanel fp = c.Parent as FilterPanel; + + if (fp != null) + { + object filterValue; + object filterDisplayValue; + string filterExpr; + + switch (fp.FilterType) + { + case FilterEditType.CheckBox: + filterExpr = GetCheckBoxFilterExpr( + c, fp, out filterValue, out filterDisplayValue); + break; + + case FilterEditType.ComboBox: + filterExpr = GetComboBoxFilterExpr( + c, fp, out filterValue, out filterDisplayValue); + break; + + default: + filterExpr = GetTextBoxFilterExpr( + c, fp, out filterValue, out filterDisplayValue); + break; + } + + GridColumn column = fp.GridColumn; + + if (column.SuperGrid.DoFilterEditValueChangedEvent(column.GridPanel, column, fp, + column.FilterValue, ref filterValue, ref filterDisplayValue, ref filterExpr) == false) + { + column.FilterValue = filterValue; + column.FilterDisplayValue = filterDisplayValue; + column.FilterExpr = filterExpr; + } + } + } + } + + #region GetCheckBoxFilterExpr + + private string GetCheckBoxFilterExpr(Control c, + FilterPanel fp, out object filterValue, out object filterDisplayValue) + { + filterValue = CheckState.Indeterminate; + filterDisplayValue = CheckState.Indeterminate; + + MyCheckBoxX mcb = c as MyCheckBoxX; + + if (mcb != null) + { + CheckState cs = mcb.CheckState; + + filterValue = cs; + filterDisplayValue = cs; + + if (cs != CheckState.Indeterminate) + { + return ("[" + fp.GridColumn.Name + "] = " + + (cs == CheckState.Checked ? "true" : "false")); + } + } + + return (null); + } + + #endregion + + #region GetComboBoxFilterExpr + + private string GetComboBoxFilterExpr(Control c, + FilterPanel fp, out object filterValue, out object filterDisplayValue) + { + filterValue = null; + filterDisplayValue = null; + + ComboBoxEx cb = c as ComboBoxEx; + + if (cb != null) + { + string s1 = c.Text; + + MyComboItem mci = cb.SelectedItem as MyComboItem; + + if (fp.GridColumn.FilterAutoScan == false) + { + if (mci != null) + { + ComboBox cbx = fp.GridColumn.EditControl as ComboBox; + + if (cbx != null) + { + cbx.SelectedIndex = (int) mci.Value; + + s1 = cbx.Text; + + if (cbx.DataSource != null) + { + if (string.IsNullOrEmpty(cbx.ValueMember) == false && + string.IsNullOrEmpty(cbx.DisplayMember) == false) + { + s1 = cbx.SelectedValue.ToString(); + } + } + } + } + } + else + { + if (mci != null) + { + if (mci.Value is DateTime) + { + filterValue = s1; + filterDisplayValue = c.Text; + + return ("[" + fp.GridColumn.Name + "] = #" + s1 + "#"); + } + } + } + + if (string.IsNullOrEmpty(s1) == false) + { + filterValue = s1; + filterDisplayValue = c.Text; + + return ("[" + fp.GridColumn.Name + "] = '" + s1 + "'"); + } + } + + return (null); + } + + #endregion + + #region GetTextBoxFilterExpr + + private string GetTextBoxFilterExpr(Control c, + FilterPanel fp, out object filterValue, out object filterDisplayValue) + { + filterValue = null; + filterDisplayValue = null; + + object bds = fp.GridColumn.GridPanel.DataBinder.BaseDataSource; + + bool dsFilter = (fp.GridColumn.GridPanel.VirtualMode == true && + (bds is DataSet || bds is DataTable)); + + string s = (c.Text ?? "").Trim(); + + if (string.IsNullOrEmpty(s) == false) + { + filterValue = c.Text; + filterDisplayValue = c.Text; + + if (dsFilter == true) + { + s = "\'*" + s + "*\'"; + + return ("Convert([" + fp.GridColumn.Name + "],System.String) Like " + s); + } + + s = "\'" + s + "\'"; + + if (GetFilterType(fp) == typeof(string)) + return ("[" + fp.GridColumn.Name + "] Like " + s); + + return ("ToString([" + fp.GridColumn.Name + "]) Like " + s); + } + + return (null); + } + + #endregion + + #endregion + + #region ControlLostFocus + + static void ControlLostFocus(object sender, EventArgs e) + { + Control c = sender as Control; + + if (c != null) + { + FilterPanel fp = c.Parent as FilterPanel; + + if (fp != null) + fp.EndEdit(); + } + } + + #endregion + + #region BeginEdit + + internal bool BeginEdit() + { + GridPanel panel = GridColumn.GridPanel; + + if (panel.SuperGrid.DoFilterBeginEditEvent(panel, GridColumn, this) == false) + { + panel.ClearAll(); + + GridColumn.EnsureVisible(); + PositionEditPanel(); + + GridColumn.SuperGrid.ActiveFilterPanel = this; + + _FilterExpr = GridColumn.FilterExpr; + _FilterValue = GridColumn.FilterValue; + _FilterDisplayValue = GridColumn.FilterDisplayValue; + + _LockedSelection = true; + + switch (FilterType) + { + case FilterEditType.CheckBox: + BeginCheckBoxEdit(); + break; + + case FilterEditType.ComboBox: + BeginComboBoxEdit(); + break; + + default: + BeginTextBoxEdit(); + break; + } + + Show(); + BringToFront(); + Control.Focus(); + + _LockedSelection = false; + + InvalidateFilterCell(); + + Control.MouseLeave -= Control_MouseLeave; + Control.MouseLeave += Control_MouseLeave; + + return (false); + } + + return (true); + } + + #region Control_MouseLeave + + void Control_MouseLeave(object sender, EventArgs e) + { + if (GridFilter != null && GridColumn != null) + { + Rectangle r = GridFilter.Bounds; + r.X = GridColumn.Bounds.X; + r.Width = GridColumn.Bounds.Width; + + GridColumn.SuperGrid.InvalidateRender(r); + } + } + + #endregion + + #region BeginCheckBoxEdit + + private void BeginCheckBoxEdit() + { + MyCheckBoxX mcbx = Control as MyCheckBoxX; + + if (mcbx != null) + { + CheckState cs = CheckState.Indeterminate; + + if (_FilterValue != null) + cs = (CheckState)_FilterValue; + + mcbx.CheckState = cs; + } + } + + #endregion + + #region BeginComboBoxEdit + + private void BeginComboBoxEdit() + { + ComboBoxEx cb = Control as ComboBoxEx; + + if (cb != null) + { + if (_GridColumn.SuperGrid.DoFilterLoadItemsEvent(_GridColumn, cb) == false) + { + if (_GridColumn.FilterAutoScan == true) + LoadScanItems(cb); + else + LoadComboItems(cb); + + cb.Text = (_FilterValue != null) ? _FilterValue.ToString() : ""; + + int m = _GridColumn.SuperGrid.FilterMaxDropDownHeight; + + cb.MaxDropDownItems = m / cb.ItemHeight; + cb.IntegralHeight = false; + + _GridColumn.SuperGrid.DoFilterItemsLoadedEvent(_GridColumn, cb); + } + } + } + + #region LoadScanItems + + private void LoadScanItems(ComboBoxEx cb) + { + List list = _GridColumn.ScanItems; + + int n = Math.Min(list.Count, _GridColumn.FilterPopupMaxItems); + + MyComboItem[] items = new MyComboItem[n]; + + bool blankSeen = false; + + for (int i = 0; i < n; i++) + { + object o = list[i]; + + MyComboItem bi; + + if (o is DateTime) + { + DateTime dt = (DateTime)o; + dt = dt.Date; + + string s = dt.ToShortDateString(); + + bi = new MyComboItem("ScanDateEntry", s, dt); + } + else + { + string s = o.ToString(); + + bi = new MyComboItem("ScanTextEntry", s, i); + + if (blankSeen == false && string.IsNullOrEmpty(bi.Text) == true) + blankSeen = true; + } + + items[i] = bi; + } + + if (blankSeen == false) + cb.Items.Add(""); + + cb.Items.AddRange(items); + } + + #endregion + + #region LoadComboItems + + private void LoadComboItems(ComboBoxEx cb) + { + bool blankSeen = false; + + ComboBox cbx = GridColumn.EditControl as ComboBox; + + if (cbx != null && cbx.Items.Count > 0) + { + MyComboItem[] items = new MyComboItem[cbx.Items.Count]; + + for (int i = 0; i < cbx.Items.Count; i++) + { + MyComboItem bi = new + MyComboItem("CbxEntry", cbx.GetItemText(cbx.Items[i]), i); + + if (blankSeen == false && string.IsNullOrEmpty(bi.Text) == true) + blankSeen = true; + + items[i] = bi; + } + + if (blankSeen == false) + cb.Items.Add(""); + + cb.Items.AddRange(items); + } + } + + #endregion + + #endregion + + #region BeginTextBoxEdit + + private void BeginTextBoxEdit() + { + TextBoxX tbx = Control as TextBoxX; + + if (tbx != null) + { + if (_FilterValue is DateTime) + { + tbx.Text = ((DateTime)_FilterValue).ToString("d"); + } + else + { + tbx.Text = (_FilterValue != null) + ? _FilterValue.ToString() : ""; + } + + tbx.SelectAll(); + } + } + + #endregion + + #endregion + + #region CancelEdit + + internal void CancelEdit() + { + GridColumn.FilterValue = _FilterValue; + GridColumn.FilterDisplayValue = _FilterDisplayValue; + GridColumn.FilterExpr = _FilterExpr; + + GridColumn.SuperGrid.DoFilterCancelEditEvent(GridColumn, this); + + CloseEdit(); + } + + #endregion + + #region EndEdit + + internal void EndEdit() + { + GridColumn.SuperGrid.DoFilterEndEditEvent(GridColumn, this); + + CloseEdit(); + } + + #endregion + + #region CloseEdit + + internal void CloseEdit() + { + bool wasFocused = GridColumn.SuperGrid.ContainsFocus; + + Hide(); + + GridColumn.SuperGrid.ActiveFilterPanel = null; + + Control.MouseLeave -= Control_MouseLeave; + Control = null; + + InvalidateFilterCell(); + + if (wasFocused == true) + GridColumn.SuperGrid.Focus(); + } + + #endregion + + #region InvalidateFilterCell + + private void InvalidateFilterCell() + { + Rectangle r = GridFilter.GetBounds(GridColumn.GridPanel, GridColumn); + + GridColumn.SuperGrid.Invalidate(r); + } + + #endregion + + #region PositionEditPanel + + internal void PositionEditPanel() + { + Rectangle r = GridFilter.GetBounds(GridColumn.GridPanel, GridColumn); + + r.X += Dpi.Width1; + r.Y += Dpi.Height1 + 0; + + r.Width -= Dpi.Width2 + 2; + r.Height -= Dpi.Height2 + 2; + + r.X += Dpi.Width(Style.Margin.Left); + r.Y += Dpi.Height(Style.Margin.Top); + + r.Width -= Dpi.Width(Style.Margin.Horizontal); + r.Height -= Dpi.Height(Style.Margin.Vertical); + + Rectangle e = GetClippedBounds(r); + + int xoff = 0; + int yoff = 0; + + if (r.X < e.X) + xoff = r.X - e.X; + + if (r.Y < e.Y) + yoff = r.Y - e.Y; + + Size size = Control.GetPreferredSize(Size.Empty); + + if (Control is MyCheckBoxX == false) + size.Width = Math.Max(Dpi.Width13, r.Width); + + if (size.Height == 0) + size.Height = Dpi.Height13; + + if (size.Width == 0) + size.Width = Dpi.Width13; + + Rectangle t = new Rectangle(xoff, yoff, size.Width, size.Height); + + if (t.Height < e.Height) + t.Y += (e.Height - t.Height) / 2; + + if (t.Width < e.Width) + t.X += (e.Width - t.Width) / 2; + + Bounds = e; + Control.Bounds = t; + } + + #endregion + + #region GetClippedBounds + + private Rectangle GetClippedBounds(Rectangle r) + { + Rectangle v = GridColumn.SViewRect; + + if (GridColumn.GridPanel.IsVFrozen == false) + { + int n = GridColumn.GridPanel.FixedRowHeight - + (GridColumn.GridPanel.FixedHeaderHeight); + + v.Y -= n; + v.Height += n; + } + else + { + if (r.Y < v.Y) + { + v.Height += (v.Y - r.Y); + v.Y = r.Y; + } + } + + if (GridColumn.IsHFrozen == false) + { + GridColumn pcol = GridColumn.GridPanel.Columns.GetLastVisibleFrozenColumn(); + + if (pcol != null) + { + int n = pcol.BoundsRelative.Right - v.X; + + v.X += n; + v.Width -= n; + } + } + + //r.Width += 1; + //r.Height += 1; + + r.Intersect(v); + + return (r); + } + + #endregion + + #region WantsInputKey + + /// + /// + /// + /// + /// + public bool WantsInputKey(Keys key, bool gridWantsKey) + { + switch (key) + { + case Keys.Down | Keys.Control: + return (false); + } + + switch (FilterType) + { + case FilterEditType.ComboBox: + switch (key) + { + case Keys.Space: + case Keys.Up: + case Keys.Down: + return (true); + } + break; + + case FilterEditType.CheckBox: + switch (key) + { + case Keys.Space: + return (true); + } + break; + + case FilterEditType.DateTime: + case FilterEditType.TextBox: + TextBoxX tb = Control as TextBoxX; + + if (tb != null) + { + switch (key) + { + case Keys.Left: + return (tb.SelectionStart > 0); + + case Keys.Right: + return (tb.SelectionStart < tb.TextLength); + } + } + break; + } + + return (gridWantsKey == false); + } + + #endregion + + #region Select + + /// + /// Activates the control + /// + public new void Select() + { + base.Select(); + + if (Control != null) + Control.Select(); + } + + #endregion + } + + #region MyCheckBoxX + + internal class MyCheckBoxX : CheckBoxX + { + protected override void OnKeyDown(KeyEventArgs e) + { + switch (e.KeyData) + { + case Keys.Space: + e.Handled = true; + + switch (CheckState) + { + case CheckState.Unchecked: + CheckState = CheckState.Checked; + break; + + case CheckState.Checked: + CheckState = CheckState.Indeterminate; + break; + + default: + CheckState = CheckState.Unchecked; + break; + } + break; + + default: + base.OnKeyDown(e); + break; + } + } + } + + #endregion + + #region MyComboItem + + internal class MyComboItem + { + private string _Name; + private string _Text; + + private object _Value; + + public MyComboItem(string name) + : this(name, null, -1) + { + } + + public MyComboItem(string name, string text) + : this(name, text, -1) + { + } + + public MyComboItem(string name, string text, object value) + { + _Name = name; + _Text = text; + + _Value = value; + } + + public object Value + { + get { return (_Value); } + set { _Value = value; } + } + + public string Name + { + get { return (_Name); } + set { _Name = value; } + } + + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + public override string ToString() + { + return (_Text); + } + } + + #endregion + + #region enums + + /// + /// FilterEditType + /// + public enum FilterEditType + { + /// + /// Auto + /// + Auto, + + /// + /// None + /// + None, + + /// + /// CheckBox + /// + CheckBox, + + /// + /// ComboBox + /// + ComboBox, + + /// + /// DateTime + /// + DateTime, + + /// + /// TextBox + /// + TextBox, + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterPopup.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterPopup.cs new file mode 100644 index 00000000..805aeadd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterPopup.cs @@ -0,0 +1,1207 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Reflection; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Constructor + /// + public class FilterPopup : IDisposable + { + #region Delegates + + /// + /// PfnReset + /// + public delegate void PfnReset(); + + #endregion + + #region Constants + + private readonly Size _DefaultGripSize = new Size(14, 14); + + private readonly System.Windows.Forms.Padding _DefaultPadding = System.Windows.Forms.Padding.Empty; + private readonly System.Windows.Forms.Padding _DefaultMargin = new System.Windows.Forms.Padding(1); + + #endregion + + #region Private variables + + private GridPanel _Panel; + private GridColumn _GridColumn; + + private PopupControl _PopupControl; + + private ItemPanel _ItemPanel; + private ButtonItem _VisButtonItem; + + private FilterDateTimePicker _FilterDateTimePicker; + + private Control _Control; + + private string _FilterExpr; + private object _FilterValue; + private object _FilterDisplayValue; + + private IButtonControl _SaveButton; + private PfnReset _PfnReset; + + #endregion + + /// + /// Constructor + /// + public FilterPopup(GridPanel panel) + { + _Panel = panel; + + _PopupControl = new PopupControl(); + + _PopupControl.Opened += PopupControlOpened; + _PopupControl.Closed += PopupControlClosed; + + _PopupControl.UserResize += PopupControlUserResize; + + _PopupControl.PreRenderGripBar += PopupControlPreRenderGripBar; + _PopupControl.PostRenderGripBar += PopupControlPostRenderGripBar; + } + + #region Private properties + + #region FilterDateTimePicker + + private FilterDateTimePicker FilterDateTimePicker + { + get + { + if (_FilterDateTimePicker == null) + FilterDateTimePicker = new FilterDateTimePicker(_GridColumn); + + return (_FilterDateTimePicker); + } + + set + { + if (_FilterDateTimePicker != value) + { + if (_FilterDateTimePicker != null) + _FilterDateTimePicker.ValueChanged -= FilterDateTimePickerValueChanged; + + _FilterDateTimePicker = value; + + if (_FilterDateTimePicker != null) + _FilterDateTimePicker.ValueChanged += FilterDateTimePickerValueChanged; + } + } + } + + #endregion + + #region ItemPanel + + private ItemPanel ItemPanel + { + get + { + if (_ItemPanel == null) + { + ItemPanel ip = new ItemPanel(); +#if !TRIAL + ip.LicenseKey = "F962CEC7-CD8F-4911-A9E9-CAB39962FC1F"; +#endif + ip.AutoScroll = true; + ip.FadeEffect = false; + ip.LayoutOrientation = eOrientation.Vertical; + ip.Style = eDotNetBarStyle.StyleManagerControlled; + + ip.MinimumSize = new Size(80, 70); + ip.MaximumSize = new Size(1000, 1000); + + ItemPanel = ip; + } + + return (_ItemPanel); + } + + set + { + if (_ItemPanel != value) + { + if (_ItemPanel != null) + _ItemPanel.ItemClick -= ItemPanelClick; + + _ItemPanel = value; + + if (_ItemPanel != null) + _ItemPanel.ItemClick += ItemPanelClick; + } + } + } + + #endregion + + #endregion + + #region Public properties + + #region Control + + /// + /// Control + /// + public Control Control + { + get { return (_Control); } + set { _Control = value; } + } + + #endregion + + #region GripSize + + /// + /// GripSize + /// + public Size GripSize + { + get { return (_PopupControl.GripSize); } + set { _PopupControl.GripSize = value; } + } + + #endregion + + #region Margin + + /// + /// Margin + /// + public System.Windows.Forms.Padding Margin + { + get { return (_PopupControl.Margin); } + set { _PopupControl.Margin = value; } + } + + #endregion + + #region Padding + + /// + /// Padding + /// + public System.Windows.Forms.Padding Padding + { + get { return (_PopupControl.Padding); } + set { _PopupControl.Padding = value; } + } + + #endregion + + #region PopupControl + + /// + /// Gets the PopupControl + /// + public PopupControl PopupControl + { + get { return (_PopupControl); } + } + + #endregion + + #region ResizeMode + + /// + /// Type of resize mode + /// + public PopupResizeMode ResizeMode + { + get { return (_PopupControl.ResizeMode); } + set { _PopupControl.ResizeMode = value; } + } + + #endregion + + #endregion + + #region Popup event processing + + #region PopupControlOpened + + private void PopupControlOpened(object sender, EventArgs e) + { + _Panel.SuperGrid.PopupControl = _PopupControl; + + if (Control == _ItemPanel) + { + if (_VisButtonItem != null) + _ItemPanel.EnsureVisible(_VisButtonItem); + } + else + { + IButtonControl acceptButton = GetAcceptButton(Control); + + if (acceptButton != null) + { + Form form1 = _Panel.SuperGrid.FindForm(); + + if (form1 != null) + { + _SaveButton = form1.AcceptButton; + + form1.AcceptButton = acceptButton; + } + } + } + } + + #endregion + + #region PopupControlClosed + + void PopupControlClosed(object sender, ToolStripDropDownClosedEventArgs e) + { + FilterDateTimePicker ftp = Control as FilterDateTimePicker; + + if (ftp != null) + { + if (ftp.Cancel == true) + { + _GridColumn.FilterExpr = _FilterExpr; + _GridColumn.FilterValue = _FilterValue; + _GridColumn.FilterDisplayValue = _FilterDisplayValue; + } + } + + if (_SaveButton != null) + { + Form form = _GridColumn.SuperGrid.FindForm(); + + if (form != null) + form.AcceptButton = _SaveButton; + + _SaveButton = null; + } + + _Panel.SuperGrid.PopupControl = null; + _Panel.SuperGrid.GridCursor = Cursors.Default; + + if (_PfnReset != null) + _PfnReset(); + + _Panel.SuperGrid.PostInternalMouseMove(); + _Panel.SuperGrid.DoFilterPopupClosingEvent(_GridColumn, this); + } + + #endregion + + #region PopupControlUserResize + + void PopupControlUserResize(object sender, EventArgs e) + { + _GridColumn.FilterPopupSize = Control.Size; + } + + #endregion + + #endregion + + #region GetAcceptButton + + private IButtonControl GetAcceptButton(object control) + { + Type controlType = control.GetType(); + + PropertyInfo property = controlType.GetProperty( + "AcceptButton", BindingFlags.Instance | BindingFlags.Public); + + if (property != null) + { + if (property.PropertyType == typeof (IButtonControl)) + return (IButtonControl) property.GetValue(control, null); + } + + return (null); + } + + #endregion + + #region PopupControlPreRenderGripBar + + private void PopupControlPreRenderGripBar(object sender, PreRenderGripBarEventArgs e) + { + e.Cancel = _GridColumn.SuperGrid.DoPreRenderFilterPopupGripBarEvent + (e.Graphics, this, _GridColumn, e.Bounds); + } + + #endregion + + #region PopupControlPostRenderGripBar + + private void PopupControlPostRenderGripBar(object sender, PostRenderGripBarEventArgs e) + { + _GridColumn.SuperGrid.DoPostRenderFilterPopupGripBarEvent + (e.Graphics, this, _GridColumn, e.Bounds); + } + + #endregion + + #region ActivatePopup + + internal void ActivatePopup(GridColumn column, PfnReset pfnReset) + { + Rectangle r = _Panel.ColumnHeader.GetScrollBounds( + _Panel, column, column.FilterImageBounds); + + ActivatePopup(column, r, pfnReset); + } + + internal void ActivatePopup( + GridColumn column, Rectangle fiBounds, PfnReset pfnReset) + { + _GridColumn = column; + _PfnReset = pfnReset; + + PopupAnchor anchor; + Point pt = GetPopupPoint(fiBounds, out anchor); + + _PopupControl.ResizeMode = anchor == PopupAnchor.Left + ? PopupResizeMode.BottomRight : PopupResizeMode.BottomLeft; + + if (LoadFilterMenu() == false) + { + _FilterExpr = _GridColumn.FilterExpr; + _FilterValue = _GridColumn.FilterValue; + _FilterDisplayValue = _GridColumn.FilterDisplayValue; + + if (column.FilterPopupSize.IsEmpty == false) + { + Control.Size = column.FilterPopupSize; + } + else + { + if (Control.Size.IsEmpty == true) + Control.Size = Control.MinimumSize; + } + + _Panel.SuperGrid.Cursor = Cursors.Default; + + FilterColumnHeaderVisualStyle style = _GridColumn.GetFilterStyle(StyleType.Default); + + _PopupControl.Background = style.GripBarBackground; + + _PopupControl.Show(Control, pt, anchor, _Panel.SuperGrid.FindForm()); + + return; + } + + if (_PfnReset != null) + _PfnReset(); + + _Panel.SuperGrid.PostInternalMouseMove(); + _Panel.SuperGrid.DoFilterPopupClosingEvent(_GridColumn, this); + } + + #region LoadFilterMenu + + private bool LoadFilterMenu() + { + Control = null; + + Margin = _DefaultMargin; + Padding = _DefaultPadding; + GripSize = _DefaultGripSize; + + if (_Panel.SuperGrid.DoFilterPopupOpeningEvent(_GridColumn, this) == false) + { + if (Control == null) + { + if (_Panel.SuperGrid.DoFilterPopupLoadEvent(_GridColumn, this) == false) + { + FilterEditType type = _GridColumn.GetFilterPanelType(); + + switch (type) + { + case FilterEditType.CheckBox: + LoadCheckBoxItems(); + break; + + case FilterEditType.ComboBox: + if (_GridColumn.FilterAutoScan == true) + LoadDefaultItems(); + else + LoadComboItems(); + break; + + case FilterEditType.DateTime: + LoadDateTimeItems(); + break; + + default: + LoadDefaultItems(); + break; + } + + _Panel.SuperGrid.DoFilterPopupLoadedEvent(_GridColumn, this); + } + + ItemPanel itemPanel = Control as ItemPanel; + + if (itemPanel != null) + AdjustItemPanelSize(itemPanel); + } + + return (false); + } + + return (true); + } + + #region LoadCustomFilterItems + + private void LoadCustomFilterItems(ItemPanel itemPanel) + { + bool firstItem = true; + + if (_GridColumn.SuperGrid.FilterUseExtendedCustomDialog == true) + { + List filterData = + FilterUserData.GetFilterData(_GridColumn.GridPanel); + + foreach (UserFilterData fd in filterData) + { + if (fd.ReferNames.Contains(_GridColumn.Name) == true) + { + FilterPopupItem fpi = new + FilterPopupItem(fd.Name, fd.Name, FilterItemType.UserEntry, fd.Expression); + + if (string.IsNullOrEmpty(fd.Description) == false) + fpi.Tooltip = fd.Description; + + if (firstItem == true) + { + firstItem = false; + + AddBaseItem(itemPanel, "Custom", + _GridColumn.SuperGrid.FilterCustomString, FilterItemType.Custom, "..."); + + int n = itemPanel.Items.Count - 1; + + if (n > 0) + itemPanel.Items[n].BeginGroup = true; + } + + if (fd.Expression.Equals(_GridColumn.FilterDisplayValue) == true) + fpi.FontBold = true; + + itemPanel.Items.Add(fpi); + } + } + } + + if (firstItem == true) + { + AddBaseItem(itemPanel, "Custom", + _GridColumn.SuperGrid.FilterCustomString, FilterItemType.Custom, "..."); + } + } + + #endregion + + #region LoadCheckBoxItems + + private void LoadCheckBoxItems() + { + FilterPopupItem[] items = null; + + CheckBoxX cb = _GridColumn.EditControl as CheckBoxX; + + if (cb != null) + { + items = new FilterPopupItem[(cb.ThreeState == true) ? 3 : 2]; + + items[0] = new FilterPopupItem("CbEntry", "Checked", + FilterItemType.CheckBoxEntry, CheckState.Checked); + + items[1] = new FilterPopupItem("CbEntry", "Unchecked", + FilterItemType.CheckBoxEntry, CheckState.Unchecked); + + if (cb.ThreeState == true) + { + items[2] = new FilterPopupItem("CbEntry", "Indeterminate", + FilterItemType.CheckBoxEntry, CheckState.Indeterminate); + } + } + else if (_GridColumn.EditControl is GridSwitchButtonEditControl) + { + GridSwitchButtonEditControl sw = + (GridSwitchButtonEditControl)_GridColumn.EditControl; + + items = new FilterPopupItem[2]; + + items[0] = new FilterPopupItem("SwEntry", sw.OnText, + FilterItemType.CheckBoxEntry, CheckState.Checked); + + items[1] = new FilterPopupItem("SwEntry", sw.OffText, + FilterItemType.CheckBoxEntry, CheckState.Unchecked); + } + + ItemPanel itemPanel = GetBaseItemPanel(); + + LoadCustomFilterItems(itemPanel); + + if (items != null) + { + if (itemPanel.Items.Count > 0) + items[0].BeginGroup = true; + + itemPanel.Items.AddRange(items); + } + + Control = itemPanel; + } + + #endregion + + #region LoadComboItems + + private void LoadComboItems() + { + ItemPanel itemPanel = GetBaseItemPanel(); + + _VisButtonItem = null; + + ComboBox cbx = _GridColumn.EditControl as ComboBox; + + if (cbx != null && cbx.Items.Count > 0) + { + FilterPopupItem[] items = new FilterPopupItem[cbx.Items.Count]; + + for (int i = 0; i < cbx.Items.Count; i++) + { + FilterPopupItem bi = new FilterPopupItem("CbxEntry", + cbx.GetItemText(cbx.Items[i]), FilterItemType.ComboBoxEntry,i); + + items[i] = bi; + + if (bi.Text.Equals(_GridColumn.FilterDisplayValue) == true) + { + _VisButtonItem = bi; + + bi.FontBold = true; + } + } + + LoadCustomFilterItems(itemPanel); + + if (itemPanel.Items.Count > 0) + { + items[0].BeginGroup = true; + + itemPanel.Items.AddRange(items); + } + + } + + Control = itemPanel; + } + + #endregion + + #region LoadDateTimeItems + + private void LoadDateTimeItems() + { + IGridCellEditControl editor = _GridColumn.EditControl; + + if (editor != null) + { + FilterDateTimePicker fdt = FilterDateTimePicker; + + fdt.Cancel = false; + + Control = fdt; + } + } + + #endregion + + #region LoadDefaultItems + + private void LoadDefaultItems() + { + _VisButtonItem = null; + + ItemPanel itemPanel = GetBaseItemPanel(); + + LoadCustomFilterItems(itemPanel); + + if (_GridColumn.FilterAutoScan == true) + { + List list = _GridColumn.ScanItems; + + if (list != null) + { + int n = Math.Min(list.Count, _GridColumn.FilterPopupMaxItems); + + for (int i = 0; i < n; i++) + { + object o = list[i]; + + FilterPopupItem fpi; + + if (o is DateTime) + { + DateTime dt = (DateTime)o; + dt = dt.Date; + + string s = dt.Date.ToShortDateString(); + + fpi = new FilterPopupItem(s, s, FilterItemType.ScanDateEntry, dt); + } + else + { + string s = o.ToString(); + + fpi = new FilterPopupItem(s, s, FilterItemType.ScanTextEntry, o); + } + + if (i == 0) + fpi.BeginGroup = true; + + if (fpi.Text.Equals(_GridColumn.FilterDisplayValue) == true) + { + fpi.FontBold = true; + + _VisButtonItem = fpi; + } + + itemPanel.Items.Add(fpi); + } + } + } + + Control = itemPanel; + } + + #endregion + + #region GetBaseItemPanel + + private ItemPanel GetBaseItemPanel() + { + ItemPanel itemPanel = ItemPanel; + + FilterColumnHeaderVisualStyle style = _GridColumn.GetFilterStyle(StyleType.Default); + + itemPanel.Font = style.Font; + itemPanel.BackColor = style.Background.Color1; + + itemPanel.Items.Clear(); + + AddBaseItem(itemPanel, "ShowAll", + _GridColumn.SuperGrid.FilterShowAllString, FilterItemType.All, ""); + + AddBaseItem(itemPanel, "ShowNull", + _GridColumn.SuperGrid.FilterShowNullString, FilterItemType.Null, ""); + + AddBaseItem(itemPanel, "ShowNotNull", + _GridColumn.SuperGrid.FilterShowNotNullString, FilterItemType.NotNull, ""); + + return (itemPanel); + } + + #region AddBaseItem + + private void AddBaseItem(ItemPanel itemPanel, + string name, string text, FilterItemType type, string ellipse) + { + if (string.IsNullOrEmpty(text) == false) + itemPanel.Items.Add(new FilterPopupItem(name, text + ellipse, type)); + } + + #endregion + + #endregion + + #region AdjustItemPanelSize + + private void AdjustItemPanelSize(ItemPanel itemPanel) + { + if (_GridColumn.FilterPopupSize.IsEmpty == true) + { + int width = 0; + int height = 0; + + if (itemPanel.Items.Count > 0) + { + int w = 0; + + foreach (BaseItem bi in itemPanel.Items) + { + bi.RecalcSize(); + + if (bi.WidthInternal > w) + w = bi.WidthInternal; + } + + width = Math.Max(w + + SystemInformation.VerticalScrollBarWidth * 2, _GridColumn.Size.Width); + + height = itemPanel.Items.Count * + (itemPanel.Items[0].HeightInternal + itemPanel.ItemSpacing); + } + + width = Math.Max(width, 90); + height = Math.Max(Math.Min(height, _GridColumn.SuperGrid.FilterMaxDropDownHeight), 80); + + itemPanel.Size = new Size(width, height); + } + } + + #endregion + + #endregion + + #region GetPopupPoint + + private Point GetPopupPoint(Rectangle r, out PopupAnchor anchor) + { + Point pt; + + switch (_Panel.ColumnHeader.FilterImageAlignment) + { + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + anchor = PopupAnchor.Right; + pt = new Point(r.Right + 2, r.Bottom + 4); + break; + + default: + anchor = PopupAnchor.Left; + pt = new Point(r.X - 2, r.Bottom + 4); + break; + } + + pt = _Panel.SuperGrid.PointToScreen(pt); + + return (pt); + } + + #endregion + + #endregion + + #region DeactivatePopup + + internal void DeactivatePopup() + { + if (_PopupControl != null) + _PopupControl.Hide(); + } + + #endregion + + #region ItemPanelClick + + void ItemPanelClick(object sender, EventArgs e) + { + FilterPopupItem item = sender as FilterPopupItem; + + if (item != null) + { + object filterValue = null; + object filterDisplayValue = null; + string filterExpr = null; + + switch (item.FilterItemType) + { + case FilterItemType.Null: + filterDisplayValue = item.Text; + filterExpr = "[" + _GridColumn.Name + "] = null"; + break; + + case FilterItemType.NotNull: + filterDisplayValue = item.Text; + filterExpr = "[" + _GridColumn.Name + "] != null"; + break; + + case FilterItemType.ComboBoxEntry: + filterExpr = ComboItemClick(item, ref filterValue, ref filterDisplayValue); + break; + + case FilterItemType.CheckBoxEntry: + filterExpr = CheckBoxItemClick(item, ref filterValue, ref filterDisplayValue); + break; + + case FilterItemType.Custom: + filterValue = _GridColumn.FilterValue; + filterDisplayValue = _GridColumn.FilterDisplayValue; + filterExpr = _GridColumn.FilterExpr; + break; + + case FilterItemType.ScanTextEntry: + filterValue = item.Value; + filterDisplayValue = item.Value; + filterExpr = "= \"" + item.Value + "\""; + break; + + case FilterItemType.ScanDateEntry: + filterValue = item.Value; + filterDisplayValue = ((DateTime)(item.Value)).ToShortDateString(); + filterExpr = "Date([]) = #" + filterDisplayValue + "#"; + break; + + case FilterItemType.UserEntry: + filterDisplayValue = item.Value; + filterExpr = item.Value.ToString(); + break; + } + + if (_GridColumn.SuperGrid.DoFilterPopupValueChangedEvent(_GridColumn, + item.FilterItemType, ref filterValue, ref filterDisplayValue, ref filterExpr) == false) + { + if (item.FilterItemType == FilterItemType.Custom) + { + LaunchCustomDialog(filterExpr); + } + else + { + _GridColumn.FilterExpr = filterExpr; + _GridColumn.FilterValue = filterValue; + _GridColumn.FilterDisplayValue = filterDisplayValue; + } + } + } + + _PopupControl.Hide(); + } + + #region ComboItemClick + + private string ComboItemClick(FilterPopupItem item, + ref object filterValue, ref object filterDisplayValue) + { + ComboBox cbx = _GridColumn.EditControl as ComboBox; + + if (cbx != null) + { + cbx.SelectedIndex = (int)item.Value; + + string s1 = cbx.Text; + + if (cbx.DataSource != null) + { + if (string.IsNullOrEmpty(cbx.ValueMember) == false && + string.IsNullOrEmpty(cbx.DisplayMember) == false) + { + s1 = cbx.SelectedValue.ToString(); + } + } + + if (string.IsNullOrEmpty(s1) == false) + { + filterValue = s1; + filterDisplayValue = item.Text; + + return ("[" + _GridColumn.Name + "] = \"" + s1 + "\""); + } + } + + return (null); + } + + #endregion + + #region CheckBoxItemClick + + private string CheckBoxItemClick(FilterPopupItem item, + ref object filterValue, ref object filterDisplayValue) + { + CheckBoxX cb = _GridColumn.EditControl as CheckBoxX; + + if (cb != null) + { + string s1; + + switch ((CheckState)item.Value) + { + case CheckState.Checked: + s1 = cb.CheckValueChecked != null + ? cb.CheckValueChecked.ToString() : "true"; + break; + + case CheckState.Unchecked: + s1 = cb.CheckValueUnchecked != null + ? cb.CheckValueUnchecked.ToString() : "false"; + break; + + default: + s1 = cb.CheckValueIndeterminate != null + ? cb.CheckValueIndeterminate.ToString() : ""; + break; + } + + filterValue = item.Value; + filterDisplayValue = item.Text; + + return ("[" + _GridColumn.Name + "] = " + s1); + } + + if (_GridColumn.EditControl is GridSwitchButtonEditControl) + { + GridSwitchButtonEditControl sw = + (GridSwitchButtonEditControl)_GridColumn.EditControl; + + filterValue = item.Value; + filterDisplayValue = item.Text; + + string s1; + + if ((CheckState)item.Value == CheckState.Checked) + s1 = sw.OnValue != null ? sw.OnValue.ToString() : "true"; + else + s1 = sw.OffValue != null ? sw.OffValue.ToString() : "false"; + + return ("[" + _GridColumn.Name + "] = \"" + s1 + "\""); + } + + return (null); + } + + #endregion + + #region LaunchCustomDialog + + private void LaunchCustomDialog(string filterExpr) + { + Form form = _Panel.SuperGrid.FindForm(); + + if (_Panel.SuperGrid.FilterUseExtendedCustomDialog == true) + { + CustomFilterEx cf = new CustomFilterEx(_Panel, _GridColumn, filterExpr); + + cf.Text = _GridColumn.Name; + + DialogResult dr = cf.ShowDialog(form); + + if (dr == DialogResult.OK) + { + _GridColumn.FilterExpr = cf.FilterExpr; + _GridColumn.FilterValue = null; + _GridColumn.FilterDisplayValue = cf.FilterExpr; + } + } + else + { + CustomFilter cf = new CustomFilter(_Panel, _GridColumn, filterExpr); + + cf.Text = _GridColumn.Name; + + DialogResult dr = cf.ShowDialog(form); + + if (dr == DialogResult.OK) + { + _GridColumn.FilterExpr = cf.FilterExpr; + _GridColumn.FilterValue = null; + _GridColumn.FilterDisplayValue = cf.FilterExpr; + } + } + + _Panel.ColumnHeader.ResetColumnStateEx(); + + _Panel.SuperGrid.Focus(); + } + + #endregion + + #endregion + + #region FilterDateTimePickerValueChanged + + void FilterDateTimePickerValueChanged(object sender, EventArgs e) + { + FilterDateTimePicker ftp = sender as FilterDateTimePicker; + + if (ftp != null) + { + string expr = ftp.GetFilterExpr(); + + string filterExpr = expr; + object filterValue = null; + object filterDisplayValue = expr; + + if (_GridColumn.SuperGrid.DoFilterPopupValueChangedEvent(_GridColumn, + FilterItemType.DateTimeEntry, ref filterValue, ref filterDisplayValue, ref filterExpr) == false) + { + _GridColumn.FilterExpr = filterExpr; + _GridColumn.FilterValue = filterValue; + _GridColumn.FilterDisplayValue = filterDisplayValue; + } + } + } + + #endregion + + #region IDisposable Members + + /// + /// Dispose + /// + public void Dispose() + { + if (_PopupControl != null) + { + Control = null; + ItemPanel = null; + + _PopupControl.Opened -= PopupControlOpened; + _PopupControl.Closed -= PopupControlClosed; + + _PopupControl.UserResize -= PopupControlUserResize; + + _PopupControl.PreRenderGripBar -= PopupControlPreRenderGripBar; + _PopupControl.PostRenderGripBar -= PopupControlPostRenderGripBar; + + _PopupControl.Reset(); + } + } + + #endregion + } + + #region FilterPopupItem + + /// + /// FilterPopupItem + /// + public class FilterPopupItem : ButtonItem + { + #region Private variables + + private object _Value; + private FilterItemType _FilterItemType; + + #endregion + + #region Constructors + + /// + /// FilterPopupItem + /// + /// + /// + /// + public FilterPopupItem(string name, string text, FilterItemType filterItemType) + : this(name, text, filterItemType, null) + { + } + + /// + /// FilterPopupItem + /// + /// + /// + /// + /// + public FilterPopupItem(string name, + string text, FilterItemType filterItemType, object value) + : base(name, text) + { + _Value = value; + _FilterItemType = filterItemType; + } + + #endregion + + #region Public properties + + /// + /// Associated Value + /// + public object Value + { + get { return (_Value); } + set { _Value = value; } + } + + /// + /// Associated FilterItem type + /// + public FilterItemType FilterItemType + { + get { return (_FilterItemType); } + set { _FilterItemType = value; } + } + + #endregion + } + + #endregion + + #region Enums + + /// + /// FilterItemType + /// + public enum FilterItemType + { + /// + /// All + /// + All, + + /// + /// Null + /// + Null, + + /// + /// NotNull + /// + NotNull, + + /// + /// Custom + /// + Custom, + + /// + /// ComboBoxEntry + /// + ComboBoxEntry, + + /// + /// ComboBoxEntry + /// + CheckBoxEntry, + + /// + /// ScanTextEntry + /// + ScanTextEntry, + + /// + /// ScanDateEntry + /// + ScanDateEntry, + + /// + /// UserEntry + /// + UserEntry, + + /// + /// DateTimeEntry + /// + DateTimeEntry, + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterScan.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterScan.cs new file mode 100644 index 00000000..8ae3a12a --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterScan.cs @@ -0,0 +1,276 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// FilterScan + /// + public class FilterScan + { + #region Events + + /// + /// ScanComplete + /// + public event EventHandler ScanComplete; + + private delegate void ScanListDelegate(List items); + + #endregion + + #region Private variables + + private GridColumn _GridColumn; + + private bool _Scanning; + private Thread _ScanThread; + private EventHandler _OnScanComplete; + private ScanListDelegate _ScanListDelegate; + private List _ScanItems; + + #endregion + + #region Public properties + + /// + /// ScanItems + /// + public List ScanItems + { + get { return (GetScanItems()); } + } + + #endregion + + /// + /// FilterScan + /// + /// + public FilterScan(GridColumn gridColumn) + { + _GridColumn = gridColumn; + + _OnScanComplete = new EventHandler(OnScanComplete); + _ScanListDelegate = new ScanListDelegate(AddScanItems); + } + + #region BeginScan + + /// + /// BeginScan + /// + public void BeginScan() + { + if (_Scanning == false) + { + _Scanning = true; + _ScanItems = null; + + _ScanThread = new Thread(ScanThread); + _ScanThread.Start(); + } + } + + #endregion + + #region EndScan + + /// + /// BeginScan + /// + public void EndScan() + { + if (_Scanning == true) + { + if (_ScanThread.IsAlive) + { + _ScanThread.Abort(); + _ScanThread.Join(); + } + + _ScanThread = null; + _ScanItems = null; + + _Scanning = false; + } + } + + #endregion + + #region ScanThread + + private void ScanThread() + { + GridColumn gridColumn = _GridColumn; + GridPanel panel = gridColumn.GridPanel; + + List scanItems = new List(); + + try + { + if (panel != null) + { + ScanColumn(panel.Rows, gridColumn, scanItems); + + RemoveDuplicates(scanItems); + } + } + catch + { + } + finally + { + _Scanning = false; + + gridColumn.SuperGrid.BeginInvoke( + _ScanListDelegate, new object[] { scanItems }); + + gridColumn.SuperGrid.BeginInvoke( + _OnScanComplete, new object[] { this, EventArgs.Empty }); + } + } + + #region ScanColumn + + private void ScanColumn( + GridItemsCollection rows, GridColumn gridColumn, List scanItems) + { + if (rows != null && rows.Count > 0) + { + for (int i = 0; i < rows.Count; i++) + { + GridContainer cont = rows[i] as GridContainer; + + if (cont != null) + { + GridRow row = cont as GridRow; + + if (row != null) + { + GridCell cell = row.GetCell(gridColumn.ColumnIndex); + + if (cell != null) + { + object value = cell.ValueEx; + + if (value != null && value != DBNull.Value) + { + if (value is DateTime) + value = ((DateTime)value).Date; + + scanItems.Add(value); + } + } + } + + if (cont is GridGroup || + (gridColumn.GridPanel.FilterLevel != FilterLevel.Root && cont is GridPanel == false)) + { + ScanColumn(cont.Rows, gridColumn, scanItems); + } + } + } + } + } + + #endregion + + #region RemoveDuplicates + + private void RemoveDuplicates(List scanItems) + { + GridColumn gridColumn = _GridColumn; + + if (gridColumn.DataType != null) + { + for (int i = scanItems.Count - 1; i >= 0; --i) + { + if (scanItems[i].GetType() != gridColumn.DataType) + scanItems.RemoveAt(i); + } + } + + scanItems.Sort(new ScanComparer()); + + object o = null; + + for (int i = scanItems.Count - 1; i >= 0; --i) + { + if (scanItems[i].Equals(o) == true) + scanItems.RemoveAt(i); + else + o = scanItems[i]; + } + } + + private class ScanComparer : IComparer + { + public int Compare(object val1, object val2) + { + return (CompareVal.CompareTo(val1, val2)); + } + } + + #endregion + + #endregion + + #region AddScanItems + + private void AddScanItems(List items) + { + _ScanItems = items; + } + + #endregion + + #region OnScanComplete + + private void OnScanComplete(object sender, EventArgs e) + { + if (ScanComplete != null) + ScanComplete(sender, e); + } + + #endregion + + #region GetScanItems + + internal List GetScanItems() + { + List list = null; + + if (_GridColumn.NeedsFilterScan == true) + { + _GridColumn.SuperGrid.Cursor = Cursors.AppStarting; + + _GridColumn.NeedsFilterScan = false; + _GridColumn.FilterScan.BeginScan(); + + for (int i = 0; i < 500; i++) + { + Application.DoEvents(); + System.Threading.Thread.Sleep(20); + + list = _ScanItems; + + if (list != null) + break; + } + + _GridColumn.SuperGrid.Cursor = Cursors.Default; + } + else + { + list = _ScanItems; + } + + return (list); + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterUserData.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterUserData.cs new file mode 100644 index 00000000..3c971f1c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/FilterUserData.cs @@ -0,0 +1,299 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Xml; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// FilterUserData + /// + static public class FilterUserData + { + #region Static data + + private static string _filterPath; + private static List _filterData; + + #endregion + + static FilterUserData() + { + _filterPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + + "\\DotNetBar\\UserFilterData.xml"; + } + + #region GetFilterData + + /// + /// GetFilterData + /// + /// + static public List GetFilterData(GridPanel gridPanel) + { + if (_filterData != null) + return (_filterData); + + return (LoadFilterData(gridPanel)); + } + + #endregion + + #region LoadFilterData + + /// + /// LoadFilterData + /// + /// + static public List LoadFilterData(GridPanel gridPanel) + { + _filterData = new List(); + + string path = _filterPath; + + if (gridPanel.SuperGrid.DoFilterLoadUserDataEvent( + gridPanel, ref path, ref _filterData) == false) + { + if (File.Exists(path) == true) + { + using (XmlReader reader = XmlReader.Create(path)) + { + UserFilterData fd = null; + + while (reader.Read()) + { + if (reader.IsStartElement()) + { + switch (reader.Name) + { + case "Filter": + fd = new UserFilterData(); + _filterData.Add(fd); + break; + + case "Name": + if (reader.Read()) + { + if (fd != null) + fd.Name = reader.Value.Trim(); + } + break; + + case "Description": + if (reader.Read()) + { + if (fd != null) + fd.Description = reader.Value.Trim(); + } + break; + + case "Expression": + if (reader.Read()) + { + if (fd != null) + fd.Expression = reader.Value.Trim(); + } + break; + + case "ReferNames": + if (reader.Read()) + { + if (fd != null) + fd.ReferNamesString = reader.Value.Trim(); + } + break; + } + } + } + } + } + } + + return (_filterData); + } + + #endregion + + #region StoreFilterData + + /// + /// StoreFilterData + /// + /// + /// + static public void StoreFilterData(GridPanel gridPanel, List filterData) + { + for (int i = filterData.Count - 1; i >= 0; --i) + { + UserFilterData fd = filterData[i]; + + if (fd.Expression != null) + { + string expr = fd.Expression.Trim(); + + if (expr.Length <= 0) + filterData.RemoveAt(i); + } + } + + string path = _filterPath; + + if (gridPanel.SuperGrid.DoFilterStoreUserDataEvent( + gridPanel, ref path, ref _filterData) == false) + { + string dir = Path.GetDirectoryName(path); + + if (dir != null) + { + if (Directory.Exists(dir) == false) + Directory.CreateDirectory(dir); + + using (XmlWriter writer = XmlWriter.Create(path)) + { + writer.WriteStartDocument(); + writer.WriteStartElement("FilterData"); + + foreach (UserFilterData fd in filterData) + { + if (String.IsNullOrEmpty(fd.Expression) == false) + { + if (String.IsNullOrEmpty(fd.Name) == false) + { + writer.WriteStartElement("Filter"); + writer.WriteElementString("Name", fd.Name); + + if (String.IsNullOrEmpty(fd.Description) == false) + writer.WriteElementString("Description", fd.Description); + + writer.WriteElementString("Expression", fd.Expression); + + if (String.IsNullOrEmpty(fd.ReferNamesString) == false) + writer.WriteElementString("ReferNames", fd.ReferNamesString); + + writer.WriteEndElement(); + } + } + } + + writer.WriteEndElement(); + writer.WriteEndDocument(); + } + } + } + } + + #endregion + } + + /// + /// User Filter expression data + /// + public class UserFilterData + { + #region Private variables + + private string _Name; + private string _Description; + private string _Expression; + + private List _ReferNames = new List(); + + #endregion + + #region Public properties + + #region Description + + /// + /// Description + /// + public string Description + { + get { return (_Description); } + set { _Description = value; } + } + + #endregion + + #region Expression + + /// + /// Expression + /// + public string Expression + { + get { return (_Expression); } + set { _Expression = value; } + } + + #endregion + + #region Name + + /// + /// Name + /// + public string Name + { + get { return (_Name); } + set { _Name = value; } + } + + #endregion + + #region ReferNames + + /// + /// ReferNames + /// + public List ReferNames + { + get { return (_ReferNames); } + } + + #endregion + + #region ReferNamesString + + /// + /// ReferNamesString + /// + public string ReferNamesString + { + get + { + StringBuilder sb = new StringBuilder(); + + foreach (string s in _ReferNames) + { + sb.Append(s); + sb.Append(","); + } + + if (sb.Length > 0) + sb.Length--; + + return (sb.ToString()); + } + + set + { + _ReferNames.Clear(); + + if (value != null) + { + string[] names = value.Split(','); + + foreach (string s in names) + _ReferNames.Add(s); + } + } + } + + #endregion + + #endregion + } +} + diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/GridFilter.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/GridFilter.cs new file mode 100644 index 00000000..453d76e7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/GridFilter.cs @@ -0,0 +1,1564 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Represents a Grid Filter row + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class GridFilter : GridElement + { + #region Constants + + private const int ImageCacheSize = 8; + + #endregion + + #region Private variables + + private int _RowHeight; + + private FilterRowVisualStyles _EffectiveRowHeaderStyles; + private int _StyleUpdateCount; + + private HeaderArea _HitArea; + private GridColumn _HitColumn; + + private HeaderArea _MouseDownHitArea; + private GridColumn _MouseDownHitColumn; + + private Image _FilterImage; + private int _FilterImageIndex = -1; + private Image[] _FilterCacheImages = new Image[ImageCacheSize]; + + private bool _Visible; + private bool _ShowPanelFilterExpr; + private bool _ShowToolTips = true; + private bool _FocusCuesEnabled = true; + + #endregion + + #region Internal properties + + #region RowHeaderBounds + + internal Rectangle RowHeaderBounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = Bounds; + r.Width = panel.RowHeaderWidthEx; + + return (r); + } + + return (Rectangle.Empty); + } + } + + #endregion + + #endregion + + #region Public properties + + #region Bounds + + /// + /// Gets the scroll adjusted bounds + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle Bounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = BoundsRelative; + + if (panel.IsSubPanel == true) + { + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + } + + return (r); + } + + return (Rectangle.Empty); + } + } + + #endregion + + #region FilterImage + + /// + /// Gets or sets the default image to display + /// in the filter row header. + /// + [DefaultValue(null), Category("Filtering")] + [Description("Indicates the default image to display in the filter row header.")] + public Image FilterImage + { + get { return (_FilterImage); } + + set + { + if (_FilterImage != value) + { + _FilterImage = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("FilterImage", VisualChangeType.Layout); + } + } + } + + #region GetFilterImage + + internal Image GetFilterImage(GridPanel panel) + { + if (_FilterImage != null) + return (_FilterImage); + + if (_FilterImageIndex >= 0) + { + ImageList imageList = GridPanel.ImageList; + + if (imageList != null && _FilterImageIndex < imageList.Images.Count) + return (imageList.Images[_FilterImageIndex]); + } + + return (GetFilterImageEx(panel)); + } + + #region GetFilterImageEx + + private Image GetFilterImageEx(GridPanel panel) + { + StyleState state = GetFilterImageState(panel); + + Image cacheImage = _FilterCacheImages[(int)state]; + + if (cacheImage == null) + { + Image image = new Bitmap(Dpi.Width13, Dpi.Height12); + + using (Graphics g = Graphics.FromImage(image)) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = new GraphicsPath()) + { + Point[] pts = + { + new Point(0, 0), + new Point(Dpi.Width12, 0), + new Point(Dpi.Width12, Dpi.Height1), + new Point(Dpi.Width7, Dpi.Height6), + new Point(Dpi.Width7, Dpi.Height11), + new Point(Dpi.Width5, Dpi.Height9), + new Point(Dpi.Width5, Dpi.Height6), + new Point(0, Dpi.Height1), + new Point(0, 0), + }; + + path.AddLines(pts); + + FilterRowVisualStyle style = GetEffectiveRowStyle(state); + + Rectangle r = new + Rectangle(Dpi.Width1, Dpi.Height1, Dpi.Width11, Dpi.Height10); + + Background back = (style.FilterBackground != null && style.FilterBackground.IsEmpty == false) + ? style.FilterBackground : new Background(Color.White); + + using (Brush br = back.GetBrush(r)) + { + g.FillPath(br, path); + } + + Color color = style.FilterBorderColor; + + if (color.IsEmpty) + color = Color.DimGray; + + using (Pen pen = new Pen(color)) + g.DrawPath(pen, path); + } + } + + _FilterCacheImages[(int)state] = image; + + cacheImage = image; + } + + return (cacheImage); + } + + #endregion + + #endregion + + #endregion + + #region FilterImageIndex + + /// + /// Gets or sets the Filter image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the Filter Row image index.")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int FilterImageIndex + { + get { return (_FilterImageIndex); } + + set + { + if (_FilterImageIndex != value) + { + _FilterImageIndex = value; + + OnPropertyChangedEx("FilterImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetFilterImageIndex() + { + _FilterImageIndex = -1; + } + + #endregion + + #region FocusCuesEnabled + + /// + /// Gets or sets whether focus cues are displayed on the focused element + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether focus cues are displayed on the focused element.")] + public bool FocusCuesEnabled + { + get { return (_FocusCuesEnabled); } + + set + { + if (_FocusCuesEnabled != value) + { + _FocusCuesEnabled = value; + + OnPropertyChangedEx("FocusCuesEnabled", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowPanelFilterExpr + + /// + /// Gets or sets whether filter + /// expressions are displayed in the panel area + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether filter expressions are displayed in the panel area.")] + public bool ShowPanelFilterExpr + { + get { return (_ShowPanelFilterExpr); } + + set + { + if (_ShowPanelFilterExpr != value) + { + _ShowPanelFilterExpr = value; + + OnPropertyChangedEx("ShowPanelFilterExpr", VisualChangeType.Render); + } + } + } + + #endregion + + #region RowHeight + + /// + /// Gets or sets the height of the ColumnHeader row + /// + [DefaultValue(0), Category("Style")] + [Description("Indicates the height of the ColumnHeader row")] + public int RowHeight + { + get { return (_RowHeight); } + + set + { + if (_RowHeight != value) + { + if (value < 0) + throw new Exception("RowHeight cannot be negative"); + + _RowHeight = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("RowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowToolTips + + /// + /// Gets or sets whether tooltips are shown for FilterPanel expressions + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether tooltips are shown for FilterPanel expressions.")] + public bool ShowToolTips + { + get { return (_ShowToolTips); } + + set + { + if (value != _ShowToolTips) + { + _ShowToolTips = value; + + OnPropertyChanged("ShowToolTips"); + } + } + } + + #endregion + + #region Visible + + /// + /// Visible + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the item is visible")] + public override bool Visible + { + get { return (_Visible); } + + set + { + if (_Visible != value) + { + _Visible = value; + + if (_Visible == false) + { + if (SuperGrid.ActiveFilterPanel != null) + SuperGrid.ActiveFilterPanel.EndEdit(); + } + + OnPropertyChangedEx("Visible", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region MeasureOverride + + /// + /// Performs the layout of the item and sets + /// the Size property to size that item will take. + /// + /// Layout information. + /// + /// + protected override void MeasureOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + Size sizeNeeded = Size.Empty; + + GridPanel panel = stateInfo.GridPanel; + + sizeNeeded.Width = panel.ColumnHeader.Size.Width; + + sizeNeeded.Height = (_RowHeight > 0) + ? _RowHeight : MeasureHeaderHeight(panel); + + Size = sizeNeeded; + } + + #region MeasureHeader + + private int MeasureHeaderHeight(GridPanel panel) + { + int maxHeight = 0; + + foreach (GridColumn col in panel.Columns) + { + if (col.Visible == true) + { + Size size = FilterPanel.GetPreferredSize(this, col); + + FilterColumnHeaderVisualStyle style = GetEffectiveStyle(col); + + int n = size.Height + style.Margin.Vertical; + + if (n > maxHeight) + maxHeight = n; + } + } + + if (maxHeight > 0) + maxHeight += 4; + + return (maxHeight); + } + + #endregion + + #endregion + + #region ArrangeOverride + + /// + /// Performs the arrange pass layout of the item + /// when final position and size of the item has been set. + /// + /// Layout information. + /// + /// Layout bounds + protected override void ArrangeOverride(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + } + + #endregion + + #region RenderOverride + + /// + /// Performs drawing of the item and its children. + /// + /// Holds contextual rendering information. + protected override void RenderOverride(GridRenderInfo renderInfo) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + Graphics g = renderInfo.Graphics; + Rectangle bounds = Bounds; + + FilterRowVisualStyle style = GetEffectiveRowStyle(); + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + if (SuperGrid.DoPreRenderFilterRowEvent(g, + this, null, RenderParts.Background, bounds) == false) + { + RenderRowBackground(g, style, bounds); + + SuperGrid.DoPostRenderFilterRowEvent(g, + this, null, RenderParts.Background, bounds); + } + + RenderColumnBorder(g, panel, bounds); + + if (panel.IsSubPanel == true || + panel.FrozenColumnCount <= 0) + { + RenderAllColumns(renderInfo, panel); + } + else + { + RenderScrollableColumns(renderInfo, panel); + RenderFrozenColumns(renderInfo, panel); + } + + RenderRowHeader(g, panel, style, pstyle); + } + } + + #region RenderRowBackground + + private void RenderRowBackground( + Graphics g, FilterRowVisualStyle style, Rectangle bounds) + { + using (Brush br = style.WhiteSpaceBackground.GetBrush(bounds)) + g.FillRectangle(br, bounds); + } + + #endregion + + #region RenderAllColumns + + private void RenderAllColumns( + GridRenderInfo renderInfo, GridPanel panel) + { + Graphics g = renderInfo.Graphics; + GridColumnCollection columns = panel.Columns; + + if (columns != null) + { + int[] map = columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + Rectangle r = GetBounds(panel, column); + + if (r.IntersectsWith(renderInfo.ClipRectangle) == true) + RenderColumnHeader(g, panel, column, r); + } + } + } + } + + #endregion + + #region RenderScrollableColumns + + private void RenderScrollableColumns( + GridRenderInfo renderInfo, GridPanel panel) + { + Graphics g = renderInfo.Graphics; + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true && column.IsHFrozen == false) + { + Rectangle r = GetBounds(panel, column); + + if (r.IntersectsWith(renderInfo.ClipRectangle) == true) + RenderColumnHeader(g, panel, column, r); + } + } + } + + #endregion + + #region RenderFrozenColumns + + private void RenderFrozenColumns( + GridRenderInfo renderInfo, GridPanel panel) + { + Graphics g = renderInfo.Graphics; + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + if (column.IsHFrozen == false) + break; + + Rectangle r = GetBounds(panel, column); + + if (r.IntersectsWith(renderInfo.ClipRectangle) == true) + RenderColumnHeader(g, panel, column, r); + } + } + } + + #endregion + + #region RenderRowHeader + + private void RenderRowHeader(Graphics g, + GridPanel panel, FilterRowVisualStyle style, GridPanelVisualStyle pstyle) + { + Rectangle r = GetRowHeaderBounds(panel); + + if (r.Width > 0 && r.Height > 0) + { + if (SuperGrid.DoPreRenderFilterRowEvent(g, + this, null, RenderParts.RowHeader, r) == false) + { + using (Brush br = style.RowHeader.Background.GetBrush(r)) + g.FillRectangle(br, r); + + using (Pen pen = new Pen(style.RowHeader.BorderHighlightColor, Dpi.Width1)) + g.DrawLine(pen, r.X + 1, r.Top, r.X + 1, r.Bottom - 1); + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) + g.DrawLine(pen, r.Right - 1, r.Top, r.Right - 1, r.Bottom - 1); + + using (Pen pen = new Pen(style.RowHeader.BorderHighlightColor, Dpi.Height1)) + g.DrawLine(pen, r.X, r.Top, r.Right - 2, r.Top); + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X, r.Top - 1, r.Right - 2, r.Top - 1); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 2, r.Bottom - 1); + } + + RenderFilterIndicator(g, panel, r); + + SuperGrid.DoPostRenderFilterRowEvent(g, + this, null, RenderParts.RowHeader, r); + } + } + } + + #region RenderFilterIndicator + + private void RenderFilterIndicator(Graphics g, GridPanel panel, Rectangle r) + { + Image image = GetFilterImage(panel); + + if (image != null) + { + Rectangle u = r; + u.Size = image.Size; + + if (r.Width > u.Width) + u.X = r.X + (r.Width - u.Width) / 2; + + if (r.Height > u.Height) + u.Y += (r.Height - u.Height) / 2; + + u.Intersect(r); + + g.DrawImageUnscaledAndClipped(image, u); + } + } + + #endregion + + #endregion + + #region RenderColumnHeader + + private void RenderColumnHeader(Graphics g, + GridPanel panel, GridColumn column, Rectangle bounds) + { + FilterColumnHeaderVisualStyle style = GetEffectiveStyle(column); + + if (bounds.Width > 0 && bounds.Height > 0) + { + if (SuperGrid.DoPreRenderFilterRowEvent(g, + this, column, RenderParts.Background, bounds) == false) + { + RenderBackground(g, column, style, bounds); + + SuperGrid.DoPostRenderFilterRowEvent(g, + this, column, RenderParts.Background, bounds); + } + + if (SuperGrid.DoPreRenderFilterRowEvent(g, + this, column, RenderParts.Border, bounds) == false) + { + RenderColumnBorder(g, panel, bounds); + + SuperGrid.DoPostRenderFilterRowEvent(g, + this, column, RenderParts.Border, bounds); + } + + Rectangle r = bounds; + + r.X += (style.Margin.Left + 1); + r.Width -= (style.Margin.Horizontal + 2); + + r.Y += style.Margin.Top; + r.Height -= style.Margin.Vertical; + + if (r.Width > 0 && r.Height > 0) + { + if (SuperGrid.ActiveFilterPanel == null || + SuperGrid.ActiveFilterPanel.GridColumn != column) + { + if (SuperGrid.DoPreRenderFilterRowEvent(g, + this, column, RenderParts.Content, r) == false) + { + RenderFilterContent(g, column, style, r); + + SuperGrid.DoPostRenderFilterRowEvent(g, + this, column, RenderParts.Content, r); + } + } + } + + RenderFocusRect(g, column, bounds); + } + } + + #region RenderBackground + + internal void RenderBackground(Graphics g, + GridColumn column, FilterColumnHeaderVisualStyle style, Rectangle r) + { + if (style == null) + style = GetEffectiveStyle(column); + + if (column.FilterError == false || style.ErrorBackground == null) + { + using (Brush br = style.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + else + { + using (Brush br = style.ErrorBackground.GetBrush(r)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region RenderColumnBorder + + private void RenderColumnBorder( + Graphics g, GridPanel panel, Rectangle bounds) + { + Rectangle r = bounds; + Rectangle p = panel.PanelBounds; + + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + if (r.Y > 0 && r.Y <= p.Y) + { + r.Height -= (p.Y - r.Y + 1); + r.Y = p.Y + 1; + } + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) + { + g.DrawLine(pen, r.X - 1, r.Top - 1, r.X - 1, r.Bottom - 1); + g.DrawLine(pen, r.Right - 1, r.Top - 1, r.Right - 1, r.Bottom - 1); + } + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X - 1, r.Top - 1, r.Right - 1, r.Top - 1); + g.DrawLine(pen, r.X - 1, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + } + } + + #endregion + + #region RenderFilterContent + + private void RenderFilterContent(Graphics g, + GridColumn column, FilterColumnHeaderVisualStyle style, Rectangle bounds) + { + switch (column.GetFilterPanelType()) + { + case FilterEditType.CheckBox: + FilterPanel.RenderCheckBox(g, this, column, bounds); + break; + + default: + if (column.FilterValue != null || column.CanShowFilterExpr == true) + { + object value = column.FilterDisplayValue; + + if (value != null) + { + string s = value is DateTime + ? ((DateTime)value).ToString("d") + : value.ToString(); + + RenderContent(g, column, s, style, bounds); + } + } + else if (column.FilterExpr != null) + { + string s = column.SuperGrid.FilterCustomString; + + RenderContent(g, column, s, style, bounds); + } + break; + } + } + + #region RenderContent + + private void RenderContent(Graphics g, GridColumn column, + string s, FilterColumnHeaderVisualStyle style, Rectangle bounds) + { + eTextFormat tf = style.GetTextFormatFlags(); + + if (string.IsNullOrEmpty(s) == false) + { + Rectangle r = bounds; + r.Width--; + r.Height -= 2; + + Color color = column.FilterError == false + ? style.TextColor + : style.ErrorTextColor; + + TextDrawing.DrawString(g, s, style.Font, color, r, tf); + } + } + + #endregion + + #endregion + + #region RenderFocusRect + + private void RenderFocusRect(Graphics g, GridColumn column, Rectangle r) + { + if (_FocusCuesEnabled == true) + { + if (SuperGrid.ActiveFilterPanel != null) + { + if (SuperGrid.ActiveFilterPanel.GridColumn == column) + { + r.Width -= Dpi.Width1; + r.Height -= Dpi.Height1; + + ControlPaint.DrawFocusRectangle(g, r); + } + } + } + } + + #endregion + + #endregion + + #endregion + + #region GetRowHeaderBounds + + private Rectangle GetRowHeaderBounds(GridPanel panel) + { + if (panel.ShowRowHeaders == true) + { + Rectangle r = Bounds; + r.Width = panel.RowHeaderWidthEx; + + Rectangle p = panel.PanelBounds; + + if (r.Y <= p.Y) + { + r.Height -= (p.Y - r.Y + 1); + r.Y = p.Y + 1; + } + + return (r); + } + + return (Rectangle.Empty); + } + + #endregion + + #region Mouse support + + #region InternalMouseEnter + + internal override void InternalMouseEnter(EventArgs e) + { + SuperGrid.ToolTipText = ""; + + base.InternalMouseEnter(e); + } + + #endregion + + #region InternalMouseLeave + + internal override void InternalMouseLeave(EventArgs e) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (_HitArea == HeaderArea.InContent || _HitArea == HeaderArea.NoWhere) + InvalidateRender(); + + else if (_HitArea == HeaderArea.InRowHeader || _HitArea == HeaderArea.InFilterMenu) + InvalidateRowHeader(); + + _HitArea = HeaderArea.NoWhere; + _HitColumn = null; + + SuperGrid.ToolTipText = ""; + } + + base.InternalMouseLeave(e); + } + + #endregion + + #region InternalMouseMove + + private HeaderArea _LastHitArea; + private GridColumn _LastHitColumn; + + internal override void InternalMouseMove(MouseEventArgs e) + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + _LastHitArea = _HitArea; + _LastHitColumn = _HitColumn; + + _HitArea = GetHitArea(e.Location, ref _HitColumn, false); + + switch (_HitArea) + { + case HeaderArea.InFilterMenu: + SuperGrid.GridCursor = Cursors.Hand; + UpdateToolTip(panel, panel.FilterExpr); + break; + + case HeaderArea.InContent: + SuperGrid.GridCursor = Cursors.Default; + + if (_HitColumn != null) + { + if (_HitColumn.IsFilteringEnabled == true) + UpdateToolTip(panel, _HitColumn.FilterExpr); + } + break; + + default: + SuperGrid.GridCursor = Cursors.Default; + SuperGrid.ToolTipText = ""; + break; + } + + if (_LastHitArea != _HitArea || _LastHitColumn != _HitColumn) + { + InvalidateRender(); + InvalidateRowHeader(); + } + + base.InternalMouseMove(e); + } + } + + #region UpdateToolTip + + private void UpdateToolTip(GridPanel panel, string toolTip) + { + if (_ShowToolTips == true) + { + if (_HitArea != _LastHitArea || _HitColumn != _LastHitColumn) + panel.SetHeaderTooltip(this, _HitColumn, _HitArea, toolTip); + } + } + + #endregion + + #endregion + + #region InternalMouseDown + + internal override void InternalMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + GridPanel panel = GridPanel; + + if (panel != null) + { + _MouseDownHitArea = _HitArea; + _MouseDownHitColumn = _HitColumn; + + switch (_HitArea) + { + case HeaderArea.InContent: + GridColumn column = _HitColumn; + + if (column != null) + { + if (_HitColumn.IsFilteringEnabled == true) + { + if (panel.SetActiveRow(null, false) == true) + { + FilterPanel fp = FilterPanel.GetFilterPanel(column); + + if (fp != null) + fp.BeginEdit(); + } + } + } + break; + + case HeaderArea.InFilterMenu: + if (panel.SuperGrid.DoFilterBeginEditEvent(panel, null, null) == false) + LaunchCustomDialog(panel, panel.FilterExpr); + break; + } + } + } + + #region LaunchCustomDialog + + private void LaunchCustomDialog(GridPanel panel, string filterExpr) + { + Form form = panel.SuperGrid.FindForm(); + + if (panel.SuperGrid.FilterUseExtendedCustomDialog == true) + { + CustomFilterEx cf = new CustomFilterEx(panel, null, filterExpr); + + cf.Text = panel.Name; + + DialogResult dr = cf.ShowDialog(form); + + if (dr == DialogResult.OK) + panel.FilterExpr = cf.FilterExpr; + } + else + { + CustomFilter cf = new CustomFilter(panel, null, filterExpr); + + cf.Text = panel.Name; + + DialogResult dr = cf.ShowDialog(form); + + if (dr == DialogResult.OK) + panel.FilterExpr = cf.FilterExpr; + } + + SuperGrid.Focus(); + } + + #endregion + + #endregion + + #region InternalMouseUp + + internal override void InternalMouseUp(MouseEventArgs e) + { + GridPanel panel = GridPanel; + + if (panel != null && _HitArea == _MouseDownHitArea) + { + switch (_HitArea) + { + case HeaderArea.InContent: + if (_HitColumn != null && _MouseDownHitColumn == _HitColumn) + SuperGrid.DoFilterHeaderClickEvent(panel, _HitColumn, e); + break; + + case HeaderArea.InRowHeader: + SuperGrid.DoFilterRowHeaderClickEvent(panel); + break; + + case HeaderArea.InFilterMenu: + SuperGrid.DoFilterRowHeaderClickEvent(panel); + break; + } + } + + base.InternalMouseUp(e); + } + + #endregion + + #endregion + + #region GetHitArea + + HeaderArea GetHitArea(Point pt, ref GridColumn column, bool isMouseDown) + { + column = null; + + if (AllowSelection == false) + return (HeaderArea.NoWhere); + + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + Rectangle r = GetRowHeaderBounds(panel); + + r.Width += 2; + + if (r.Contains(pt) == true) + { + if (panel.EnableFiltering == true && panel.EnableRowFiltering == true) + return (HeaderArea.InFilterMenu); + + return (HeaderArea.InRowHeader); + } + + column = GetHitColumn(panel, pt, isMouseDown); + } + + return ((column != null) ? + HeaderArea.InContent : HeaderArea.NoWhere); + } + + #endregion + + #region GetHitColumn + + /// + /// Gets the associated column at the given location + /// + /// + /// + /// + public GridColumn GetHitColumn(int x, int y) + { + return (GetHitColumn(new Point(x, y))); + } + + /// + /// Gets the associated column at the given point + /// + /// + /// + public GridColumn GetHitColumn(Point pt) + { + GridPanel panel = GridPanel; + + if (panel != null) + return (GetHitColumn(panel, pt, false)); + + return (null); + } + + private GridColumn GetHitColumn( + GridPanel panel, Point pt, bool isMouseDown) + { + int dy = (isMouseDown == true) ? 50 : 0; + + GridColumnCollection columns = panel.Columns; + foreach (GridColumn column in columns) + { + if (column.Visible == true) + { + Rectangle r = GetBounds(panel, column); + + if (pt.X >= r.Left && pt.X < r.Right) + { + if (pt.Y >= r.Top - dy && pt.Y < r.Bottom + dy) + return (column); + } + } + } + + return (null); + } + + #endregion + + #region Style support routines + + #region GetStyleState + + internal StyleState GetStyleState(GridColumn column, bool selected) + { + StyleState state = StyleState.Default; + + if (selected == true) + state |= StyleState.Selected; + + Point pt = SuperGrid.PointToClient(Control.MousePosition); + + Rectangle r = Bounds; + r.X = column.Bounds.X; + r.Width = column.Bounds.Width; + + if (r.Contains(pt) == true) + state |= StyleState.MouseOver; + + if (column.IsReadOnly == true) + state |= StyleState.ReadOnly; + + return (state); + } + + #endregion + + #region GetEffectiveStyle + + /// + /// GetEffectiveStyle + /// + /// + /// + public FilterColumnHeaderVisualStyle GetEffectiveStyle(GridColumn column) + { + bool selected = false; + + if (column.SuperGrid.ActiveFilterPanel != null) + { + if (column.SuperGrid.ActiveFilterPanel.GridColumn == column) + selected = true; + } + + StyleState styleState = GetStyleState(column, selected); + FilterColumnHeaderVisualStyle style = GetEffectiveStyle(column, styleState); + + return (style); + } + + internal FilterColumnHeaderVisualStyle + GetEffectiveStyle(GridColumn column, StyleType sizingStyle) + { + ValidateStyle(column); + + return (GetStyle(column, sizingStyle)); + } + + internal FilterColumnHeaderVisualStyle + GetEffectiveStyle(GridColumn column, StyleState cellState) + { + ValidateStyle(column); + + switch (cellState) + { + case StyleState.MouseOver: + return (GetStyle(column, StyleType.MouseOver)); + + case StyleState.Selected: + return (GetStyle(column, StyleType.Selected)); + + case StyleState.Selected | StyleState.MouseOver: + return (GetStyle(column, StyleType.SelectedMouseOver)); + + case StyleState.ReadOnly: + return (GetStyle(column, StyleType.ReadOnly)); + + case StyleState.ReadOnly | StyleState.MouseOver: + return (GetStyle(column, StyleType.ReadOnlyMouseOver)); + + case StyleState.ReadOnly | StyleState.Selected: + return (GetStyle(column, StyleType.ReadOnlySelected)); + + case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: + return (GetStyle(column, StyleType.ReadOnlySelectedMouseOver)); + + default: + return (GetStyle(column, StyleType.Default)); + } + } + + #region ValidateStyle + + private void ValidateStyle(GridColumn column) + { + if (column.StyleUpdateCount != SuperGrid.StyleUpdateCount) + { + ClearEffectiveStyles(column); + + column.StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #region ClearEffectiveStyles + + private void ClearEffectiveStyles(GridColumn column) + { + column.EffectiveFilterStyles = new FilterColumnHeaderVisualStyles(); + + _EffectiveRowHeaderStyles = new FilterRowVisualStyles(); + } + + #endregion + + #region GetStyle + + private FilterColumnHeaderVisualStyle GetStyle(GridColumn column, StyleType e) + { + if (column.EffectiveFilterStyles == null) + column.EffectiveFilterStyles = new FilterColumnHeaderVisualStyles(); + + if (column.EffectiveFilterStyles.IsValid(e) == false) + { + FilterColumnHeaderVisualStyle style = new FilterColumnHeaderVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.FilterColumnHeaderStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.FilterColumnHeaderStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.FilterColumnHeaderStyles[cs]); + style.ApplyStyle(column.FilterRowStyles[cs]); + } + } + + SuperGrid.DoGetFilterColumnHeaderStyleEvent(column, e, ref style); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + if (style.Font == null) + { + Font font = SystemFonts.DefaultFont; + style.Font = font; + } + + column.EffectiveFilterStyles[e] = style; + } + + return (column.EffectiveFilterStyles[e]); + } + + #endregion + + #endregion + + #region GetEffectiveRowStyle + + internal FilterRowVisualStyle GetEffectiveRowStyle() + { + StyleState rowState = GetRowHeaderState(); + + return (GetEffectiveRowStyle(rowState)); + } + + internal FilterRowVisualStyle GetEffectiveRowStyle(StyleState rowState) + { + ValidateRowHeaderStyle(); + + switch (rowState) + { + case StyleState.MouseOver: + return (GetRowHeaderStyle(StyleType.MouseOver)); + + case StyleState.Selected: + return (GetRowHeaderStyle(StyleType.Selected)); + + case StyleState.Selected | StyleState.MouseOver: + return (GetRowHeaderStyle(StyleType.SelectedMouseOver)); + + case StyleState.ReadOnly: + return (GetRowHeaderStyle(StyleType.ReadOnly)); + + case StyleState.ReadOnly | StyleState.MouseOver: + return (GetRowHeaderStyle(StyleType.ReadOnlyMouseOver)); + + case StyleState.ReadOnly | StyleState.Selected: + return (GetRowHeaderStyle(StyleType.ReadOnlySelected)); + + case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: + return (GetRowHeaderStyle(StyleType.ReadOnlySelectedMouseOver)); + + default: + return (GetRowHeaderStyle(StyleType.Default)); + } + } + + #region ValidateRowHeaderStyle + + private void ValidateRowHeaderStyle() + { + if (_EffectiveRowHeaderStyles == null || + (_StyleUpdateCount != SuperGrid.StyleUpdateCount)) + { + _EffectiveRowHeaderStyles = new FilterRowVisualStyles(); + + _StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #region GetRowHeaderState + + private StyleState GetRowHeaderState() + { + StyleState rowState = StyleState.Default; + + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.ReadOnly == true) + rowState |= StyleState.ReadOnly; + + if (panel == SuperGrid.ActiveGrid) + rowState |= StyleState.Selected; + + Rectangle r = GetRowHeaderBounds(panel); + + if (r.Contains(Control.MousePosition) == true) + rowState |= StyleState.MouseOver; + } + + return (rowState); + } + + #endregion + + #region GetRowHeaderStyle + + private FilterRowVisualStyle GetRowHeaderStyle(StyleType e) + { + if (_EffectiveRowHeaderStyles.IsValid(e) == false) + { + FilterRowVisualStyle style = new FilterRowVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.FilterRowStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.FilterRowStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.FilterRowStyles[cs]); + } + } + + SuperGrid.DoGetFilterRowStyleEvent(this, e, ref style); + + if (style.RowHeader.Background == null || style.RowHeader.Background.IsEmpty == true) + style.RowHeader.Background = new Background(Color.WhiteSmoke); + + _EffectiveRowHeaderStyles[e] = style; + } + + return (_EffectiveRowHeaderStyles[e]); + } + + #endregion + + #endregion + + #region GetFilterImageState + + private StyleState GetFilterImageState(GridPanel panel) + { + StyleState state = GetRowHeaderState(); + + state &= ~(StyleState.MouseOver | StyleState.Selected); + + if (_HitArea == HeaderArea.InFilterMenu) + state |= StyleState.MouseOver; + + if (string.IsNullOrEmpty(panel.FilterExpr) == false) + state |= StyleState.Selected; + + return (state); + } + + #endregion + + #endregion + + #region GetBounds + + internal Rectangle GetBounds(GridPanel panel, GridColumn column) + { + Rectangle r = BoundsRelative; + + r.X = column.BoundsRelative.X; + r.Width = column.BoundsRelative.Width; + + if (r.X == 0) + { + r.X++; + r.Width--; + } + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || column.IsHFrozen == false) + r.X -= HScrollOffset; + + return (r); + } + + #endregion + + #region InvalidateRowHeader + + internal void InvalidateRowHeader() + { + GridPanel panel = Parent as GridPanel; + + if (panel != null) + { + if (panel.ShowRowHeaders == true) + InvalidateRender(RowHeaderBounds); + } + } + + #endregion + + #region ActivateFilterEdit + + /// + ///Activates the filter edit control for the given column + /// + /// + public void ActivateFilterEdit(GridColumn column) + { + GridPanel panel = GridPanel; + + if (panel.SetActiveRow(null, false) == true) + { + FilterPanel fp = FilterPanel.GetFilterPanel(column); + + if (fp != null) + fp.BeginEdit(); + } + } + + #endregion + + #region DeactivateFilterEdit + + /// + ///Deactivates the current active filter edit + /// + public void DeactivateFilterEdit() + { + if (SuperGrid != null) + { + FilterPanel fp = SuperGrid.ActiveFilterPanel; + + if (fp != null) + fp.EndEdit(); + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/PopupControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/PopupControl.cs new file mode 100644 index 00000000..f4605d2e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/PopupControl.cs @@ -0,0 +1,1488 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Security.Permissions; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// PopupControl + /// + public class PopupControl + { + #region Events + + #region Closed + + /// + /// Closed event handler + /// + public event ToolStripDropDownClosedEventHandler Closed + { + add { _DropDown.Closed += value; } + remove { _DropDown.Closed -= value; } + } + + #endregion + + #region Closing + + /// + /// Closing event handler + /// + public event ToolStripDropDownClosingEventHandler Closing + { + add { _DropDown.Closing += value; } + remove { _DropDown.Closing -= value; } + } + + #endregion + + #region Opened + + /// + /// Opened event handler + /// + public event EventHandler Opened + { + add { _DropDown.Opened += value; } + remove { _DropDown.Opened -= value; } + } + + #endregion + + #region Opening + + /// + /// Opening event handler + /// + public event CancelEventHandler Opening + { + add { _DropDown.Opening += value; } + remove { _DropDown.Opening -= value; } + } + + #endregion + + #region PostRenderGripBar + + /// + /// Opening event handler + /// + public event EventHandler PostRenderGripBar + { + add { _DropDown.PostRenderGripBar += value; } + remove { _DropDown.PostRenderGripBar -= value; } + } + + #endregion + + #region PreRenderGripBar + + /// + /// Opening event handler + /// + public event EventHandlerPreRenderGripBar + { + add { _DropDown.PreRenderGripBar += value; } + remove { _DropDown.PreRenderGripBar -= value; } + } + + #endregion + + #region UserResize + + /// + /// UserResize event handler + /// + public event EventHandler UserResize + { + add { _DropDown.UserResize += value; } + remove { _DropDown.UserResize -= value; } + } + + #endregion + + #endregion + + #region Private variables + + private ToolStripControlHost _Host; + private PopupDropDown _DropDown; + + private PopupResizeMode _ResizeMode = PopupResizeMode.All; + + private Size _GripSize = new Size(14, 14); + private System.Windows.Forms.Padding _Padding = System.Windows.Forms.Padding.Empty; + private System.Windows.Forms.Padding _Margin = new System.Windows.Forms.Padding(1); + + private bool _AutoReset; + + private Background _Background; + + #endregion + + /// + /// Constructor + /// + public PopupControl() + { + InitializeDropDown(); + } + + #region InitializeDropDown + + /// + /// InitializeDropDown + /// + protected void InitializeDropDown() + { + if (_DropDown == null) + { + _DropDown = new PopupDropDown(false); + + _DropDown.Closed += DropDownClosed; + } + } + + #endregion + + #region Public properties + + #region AutoResetWhenClosed + + /// + /// AutoResetWhenClosed + /// + public bool AutoResetWhenClosed + { + get { return (_AutoReset); } + set { _AutoReset = value; } + } + + #endregion + + #region Background + + /// + ///Background + /// + public Background Background + { + get { return (_Background); } + set { _Background = value; } + } + + #endregion + + #region Control + + /// + /// Associated drop down Control + /// + public Control Control + { + get { return (_Host != null) ? _Host.Control : null; } + } + + #endregion + + #region GripSize + + /// + /// GripSize + /// + public Size GripSize + { + get { return (_GripSize); } + set { _GripSize = value; } + } + + #endregion + + #region Margin + + /// + /// Margin + /// + public System.Windows.Forms.Padding Margin + { + get { return (_Margin); } + set { _Margin = value; } + } + + #endregion + + #region Padding + + /// + /// Padding + /// + public System.Windows.Forms.Padding Padding + { + get { return (_Padding); } + set { _Padding = value; } + } + + #endregion + + #region ResizeMode + + /// + /// Type of resize mode + /// + public PopupResizeMode ResizeMode + { + get { return (_ResizeMode); } + set { _ResizeMode = value; } + } + + #endregion + + #region Visible + + /// + /// Visible + /// + public bool Visible + { + get { return (_DropDown != null && _DropDown.Visible) ? true : false; } + } + + #endregion + + #endregion + + #region Show + + /// + /// Shows the PopupControl + /// + /// + /// + /// + /// + public void Show(Control control, Point pt, PopupAnchor anchor, Form form) + { + Office2007RibbonForm parentForm = form as Office2007RibbonForm; + + if (parentForm != null) parentForm.NonClientPaintEnabled = false; + + InitializeHost(control); + + _DropDown.ResizeMode = _ResizeMode; + _DropDown.PopupAnchor = anchor; + _DropDown.Background = _Background; + + _DropDown.Show(pt); + + control.Focus(); + + if (parentForm != null) { parentForm.NonClientPaintEnabled = true; parentForm.RedrawNonClient(); } + } + + #region InitializeHost + + /// + /// InitializeHost + /// + /// + protected void InitializeHost(Control control) + { + InitializeDropDown(); + + if (control != Control) + DisposeHost(); + + if (_Host == null) + { + _Host = new ToolStripControlHost(control); + + _Host.AutoSize = false; + _Host.Padding = Padding; + _Host.Margin = Margin; + } + + _DropDown.Items.Clear(); + + _DropDown.AutoSize = false; + + _DropDown.GripSize = _GripSize; + + _DropDown.Margin = System.Windows.Forms.Padding.Empty; + _DropDown.Padding = System.Windows.Forms.Padding.Empty; + + _DropDown.Items.Add(_Host); + } + + #endregion + + #endregion + + #region Hide + + /// + /// Hides / closes the PopupControl + /// + public void Hide() + { + if (_DropDown != null && _DropDown.Visible == true) + _DropDown.Hide(); + } + + #endregion + + #region Reset + + /// + /// Resets / disposes of the Host control + /// + public void Reset() + { + DisposeHost(); + } + + #endregion + + #region Event processing + + #region DropDownClosed + + private void DropDownClosed(object sender, ToolStripDropDownClosedEventArgs e) + { + if (AutoResetWhenClosed == true) + DisposeHost(); + } + + #endregion + + #endregion + + #region DisposeHost + + /// + /// DisposeHost + /// + protected void DisposeHost() + { + if (_Host != null) + { + //Type t = _Host.GetType(); + //FieldInfo fi = t.GetField("control", BindingFlags.NonPublic | BindingFlags.Instance); + //if (fi != null) + //{ + // fi.SetValue(_Host, null); + // _Host.Dispose(); + //} + + _Host.Dispose(); + + _Host = null; + } + } + + #endregion + } + + #region PopupDropDown + + /// + /// PopupDropDown + /// + [ToolboxItem(false)] + public class PopupDropDown : ToolStripDropDown + { + #region Events + + #region PostRenderGripBar + + /// + /// Occurs when the popup grip bar has been rendered + /// + [Description("Occurs when the popup grip bar has been rendered.")] + public event EventHandler PostRenderGripBar; + + #endregion + + #region PreRenderGripBar + + /// + /// Occurs when the popup grip bar is about to be rendered + /// + [Description("Occurs when the popup grip bar is about to be rendered.")] + public event EventHandler PreRenderGripBar; + + #endregion + + #region UserResize + + /// + /// Occurs when the user has resized the control + /// + [Description("Occurs when the user has resized the control.")] + public event EventHandler UserResize; + + #endregion + + #endregion + + #region Private variables + + private GripAlignMode _GripAlignMode; + private PopupAnchor _PopupAnchor = PopupAnchor.Left; + private PopupResizeMode _ResizeMode = PopupResizeMode.All; + + private Size _GripSize; + private Rectangle _GripBounds; + + private bool _LockedHostedControlSize; + private bool _LockedThisSize; + private bool _ForceClose; + + private Background _Background; + + #endregion + + /// + /// PopupDropDown + /// + /// + public PopupDropDown(bool autoSize) + { + AutoSize = autoSize; + Padding = System.Windows.Forms.Padding.Empty; + Margin = System.Windows.Forms.Padding.Empty; + } + + #region Public properties + + #region Background + + /// + ///Background + /// + public Background Background + { + get { return (_Background); } + set { _Background = value; } + } + + #endregion + + #region GripAlignMode + + /// + /// Grip align mode + /// + public GripAlignMode GripAlignMode + { + get { return (_GripAlignMode); } + set { _GripAlignMode = value; } + } + + #endregion + + #region GripSize + + /// + /// Size of the grip box + /// + public Size GripSize + { + get { return (_GripSize); } + set { _GripSize = value; } + } + + #endregion + + #region PopupAnchor + + /// + /// PopupAnchor + /// + public PopupAnchor PopupAnchor + { + get { return (_PopupAnchor); } + set { _PopupAnchor = value; } + } + + #endregion + + #region ResizeMode + + /// + /// Type of resize mode + /// + public PopupResizeMode ResizeMode + { + get { return (_ResizeMode); } + set { _ResizeMode = value; } + } + + #endregion + + #endregion + + #region Protected properties + + #region GripBounds + + /// + /// Bounds of active grip box position + /// + protected Rectangle GripBounds + { + get { return (_GripBounds); } + set { _GripBounds = value; } + } + + #endregion + + #region IsGripShown + + /// + /// Indicates when a grip box is shown. + /// + protected bool IsGripShown + { + get { return (GripAlignMode != GripAlignMode.None && + GripSize.Width > 0 && GripSize.Height > 0); } + } + + #endregion + + #endregion + + #region Show + + /// + /// Shows the popup drop down + /// + /// + public new void Show(Point pt) + { + Show(pt.X, pt.Y); + } + + /// + /// Shows the popup drop down + /// + /// + /// + public new void Show(int x, int y) + { + Control hostedControl = GetHostedControl(); + + if (hostedControl != null) + { + _ForceClose = false; + + _LockedHostedControlSize = true; + _LockedThisSize = true; + + // Display actual popup and occupy just 1x1 pixel to avoid automatic reposition + + Size = new Size(1, 1); + + base.Show(x, y); + + _LockedHostedControlSize = false; + _LockedThisSize = false; + + ResizeFromContent(); + + // If popup is overlapping the initial position then move above + + if (y > Top && y <= Bottom) + { + Top = y - Height; + + GripAlignMode previous = GripAlignMode; + + switch (GripAlignMode) + { + case GripAlignMode.BottomLeft: + GripAlignMode = GripAlignMode.TopLeft; + + if (CompareResizeMode(PopupResizeMode.BottomLeft)) + ResizeMode = PopupResizeMode.TopLeft; + break; + + case GripAlignMode.BottomRight: + GripAlignMode = GripAlignMode.TopRight; + + if (CompareResizeMode(PopupResizeMode.BottomRight)) + ResizeMode = PopupResizeMode.TopRight; + break; + } + + if (GripAlignMode != previous) + RecalculateHostedControlLayout(); + } + + hostedControl.SizeChanged += HostedControlSizeChanged; + } + } + + #endregion + + #region Hide + + /// + /// Hide + /// + public new void Hide() + { + _ForceClose = true; + + base.Hide(); + } + + #endregion + + #region ResizeFromContent + + /// + /// ResizeFromContent + /// + protected void ResizeFromContent() + { + if (_LockedThisSize == false) + { + _LockedHostedControlSize = true; + + Rectangle bounds = Bounds; + bounds.Size = SizeFromContent(); + + if (PopupAnchor == PopupAnchor.Right) + bounds.X -= bounds.Width; + + Bounds = bounds; + + _LockedHostedControlSize = false; + } + } + + #region SizeFromContent + + /// + /// SizeFromContent + /// + /// + protected Size SizeFromContent() + { + Size contentSize = Size.Empty; + + Control hostedControl = GetHostedControl(); + + if (hostedControl != null) + { + hostedControl.Location = new Point(1, 1); + + contentSize = SizeFromClientSize(hostedControl.Size); + } + + SetGripAlignMode(); + + if (IsGripShown == true) + contentSize.Height += GripSize.Height + 2; + + contentSize.Width += 2; + contentSize.Height += 2; + + return (contentSize); + } + + #region SetGripAlignMode + + private void SetGripAlignMode() + { + if (CompareResizeMode(PopupResizeMode.BottomRight)) + GripAlignMode = GripAlignMode.BottomRight; + + else if (CompareResizeMode(PopupResizeMode.TopLeft)) + GripAlignMode = GripAlignMode.TopLeft; + + else if (CompareResizeMode(PopupResizeMode.TopRight)) + GripAlignMode = GripAlignMode.TopRight; + + else if (CompareResizeMode(PopupResizeMode.BottomLeft)) + GripAlignMode = GripAlignMode.BottomLeft; + + else + GripAlignMode = GripAlignMode.None; + } + + #endregion + + #endregion + + #endregion + + #region RecalculateHostedControlLayout + + /// + /// RecalculateHostedControlLayout + /// + protected void RecalculateHostedControlLayout() + { + if (_LockedHostedControlSize == false) + { + _LockedThisSize = true; + + Control hostedControl = GetHostedControl(); + + if (hostedControl != null) + { + Rectangle bounds = new + Rectangle(0, 0, ClientRectangle.Width, ClientRectangle.Height); + + if (GripAlignMode == GripAlignMode.TopLeft || GripAlignMode == GripAlignMode.TopRight) + bounds.Y = GripSize.Height + 2; + + bounds.Inflate(-1, -1); + + if (IsGripShown == true) + bounds.Height -= (GripSize.Height + 2); + + if (bounds.Size != hostedControl.Size) + hostedControl.Size = bounds.Size; + + if (bounds.Location != hostedControl.Location) + hostedControl.Location = bounds.Location; + } + + _LockedThisSize = false; + } + } + + #endregion + + #region GetHostedControl + + /// + /// Gets the hosted control + /// + /// + public Control GetHostedControl() + { + if (Items.Count > 0) + { + ToolStripControlHost host = Items[0] as ToolStripControlHost; + + if (host != null) + return (host.Control); + } + + return (null); + } + + #endregion + + #region CompareResizeMode + + /// + /// CompareResizeMode + /// + /// + /// + public bool CompareResizeMode(PopupResizeMode resizeMode) + { + return (ResizeMode & resizeMode) == resizeMode; + } + + #endregion + + #region ToolStripDropDown overrides + + #region OnClosing + + /// + /// OnClosing + /// + /// + protected override void OnClosing(ToolStripDropDownClosingEventArgs e) + { + if (_ForceClose == false && ContainsFocus == true) + { + e.Cancel = true; + } + else + { + Control hostedControl = GetHostedControl(); + + if (hostedControl != null) + hostedControl.SizeChanged -= HostedControlSizeChanged; + + base.OnClosing(e); + } + } + + #endregion + + #region OnPaint + + /// + /// OnPaint + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + + base.OnPaint(e); + + GripBounds = Rectangle.Empty; + + if (IsGripShown == true) + { + int x = Width - (GripSize.Width + 2); + int y = Height - (_GripSize.Height + 1); + + int width = GripSize.Width; + int height = GripSize.Height; + + Rectangle r = new Rectangle(1, 1, Width - 2, height + 1); + + switch (_GripAlignMode) + { + case GripAlignMode.TopLeft: + GripBounds = new Rectangle(2, 1, width, height); + r.Y = 1; + break; + + case GripAlignMode.TopRight: + r.Y = 1; + GripBounds = new Rectangle(x, 1, width, height); + break; + + case GripAlignMode.BottomLeft: + GripBounds = new Rectangle(2, y, width, height); + r.Y = GripBounds.Y - 1; + break; + + case GripAlignMode.BottomRight: + GripBounds = new Rectangle(x, y, width, height); + r.Y = GripBounds.Y - 1; + break; + } + + if (_Background.IsEmpty == false) + { + using (Brush br = _Background.GetBrush(r)) + g.FillRectangle(br, r); + } + + if (DoPreRenderGripBar(g, r) == false) + { + GripRenderer.Render(g, + GripBounds.Location, GripSize, _GripAlignMode); + + DoPostRenderGripBar(g, r); + } + } + } + + #region DoPreRenderGripBar + + private bool DoPreRenderGripBar(Graphics g, Rectangle r) + { + if (PreRenderGripBar != null) + { + PreRenderGripBarEventArgs args = new PreRenderGripBarEventArgs(g, r); + + PreRenderGripBar(this, args); + + return (args.Cancel); + } + + return (false); + } + + #endregion + + #region DoPostRenderGripBar + + private void DoPostRenderGripBar(Graphics g, Rectangle r) + { + if (PostRenderGripBar != null) + { + PostRenderGripBar(this, + new PostRenderGripBarEventArgs(g, r)); + } + } + + #endregion + + #endregion + + #region OnSizeChanged + + /// + /// OnSizeChanged + /// + /// + protected override void OnSizeChanged(EventArgs e) + { + base.OnSizeChanged(e); + + if (_LockedThisSize == false) + RecalculateHostedControlLayout(); + } + + #endregion + + #region ProcessDialogKey + + /// + /// ProcessDialogKey + /// + /// + /// + protected override bool ProcessDialogKey(Keys keyData) + { + if (keyData == Keys.Escape || (keyData & Keys.Alt) == Keys.Alt || + (keyData & Keys.LWin) == Keys.LWin || (keyData & Keys.RWin) == Keys.RWin) + { + _ForceClose = true; + } + + return (base.ProcessDialogKey(keyData)); + } + + #endregion + + #region HostedControlSizeChanged + + /// + /// HostedControlSizeChanged + /// + /// + /// + protected void HostedControlSizeChanged(object sender, EventArgs e) + { + if (_LockedHostedControlSize == false) + ResizeFromContent(); + } + + #endregion + + #endregion + + #region Win32 processing + + #region Win32 defines + + // ReSharper disable InconsistentNaming + + const int WM_GETMINMAXINFO = 0x0024; + const int WM_NCHITTEST = 0x0084; + const int WM_EXITSIZEMOVE = 0x0232; + + const int HTTRANSPARENT = -1; + const int HTLEFT = 10; + const int HTRIGHT = 11; + const int HTTOP = 12; + const int HTTOPLEFT = 13; + const int HTTOPRIGHT = 14; + const int HTBOTTOM = 15; + const int HTBOTTOMLEFT = 16; + const int HTBOTTOMRIGHT = 17; + + [StructLayout(LayoutKind.Sequential)] + internal struct MINMAXINFO + { + public Point reserved; + public Size maxSize; + public Point maxPosition; + public Size minTrackSize; + public Size maxTrackSize; + } + + static int HIWORD(int n) + { + return ((n >> 16) & 0xffff); + } + + static int HIWORD(IntPtr n) + { + return (HIWORD(unchecked((int)(long)n))); + } + + static int LOWORD(int n) + { + return (n & 0xffff); + } + + static int LOWORD(IntPtr n) + { + return (LOWORD(unchecked((int)(long)n))); + } + + // ReSharper restore InconsistentNaming + + #endregion + + #region WndProc + + /// + /// WndProc + /// + /// + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case WM_NCHITTEST: + if (OnNcHitTest(ref m) == true) + return; + break; + + case WM_GETMINMAXINFO: + OnGetMinMaxInfo(ref m); + return; + + case WM_EXITSIZEMOVE: + if (UserResize != null) + UserResize(this, EventArgs.Empty); + break; + } + + base.WndProc(ref m); + } + + #endregion + + #region OnNcHitTest + + private bool OnNcHitTest(ref Message m) + { + Point pt = PointToClient(new Point(LOWORD(m.LParam), HIWORD(m.LParam))); + + if (IsGripShown == true) + { + if (GripBounds.Contains(pt)) + { + switch (_GripAlignMode) + { + case GripAlignMode.TopLeft: + m.Result = (IntPtr)HTTOPLEFT; + break; + + case GripAlignMode.TopRight: + m.Result = (IntPtr)HTTOPRIGHT; + break; + + case GripAlignMode.BottomLeft: + m.Result = (IntPtr) HTBOTTOMLEFT; + break; + + case GripAlignMode.BottomRight: + m.Result = (IntPtr) HTBOTTOMRIGHT; + break; + } + + return (true); + } + } + + if (ResizeMode != PopupResizeMode.None) + { + Rectangle rectClient = ClientRectangle; + + if (pt.X > rectClient.Right - 3 && pt.X <= rectClient.Right) + { + if (CompareResizeMode(PopupResizeMode.Right) == true) + { + m.Result = (IntPtr) HTRIGHT; + return (true); + } + } + else if (pt.Y > rectClient.Bottom - 3 && pt.Y <= rectClient.Bottom) + { + if (CompareResizeMode(PopupResizeMode.Bottom) == true) + { + m.Result = (IntPtr) HTBOTTOM; + return (true); + } + } + else if (pt.X > -1 && pt.X < 3) + { + if (CompareResizeMode(PopupResizeMode.Left) == true) + { + m.Result = (IntPtr) HTLEFT; + return (true); + } + } + else if (pt.Y > -1 && pt.Y < 3) + { + if (CompareResizeMode(PopupResizeMode.Top) == true) + { + m.Result = (IntPtr) HTTOP; + return (true); + } + } + } + + return (false); + } + + #endregion + + #region OnGetMinMaxInfo + + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + private void OnGetMinMaxInfo(ref Message m) + { + Control hostedControl = GetHostedControl(); + + if (hostedControl != null) + { + MINMAXINFO minmax = (MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(MINMAXINFO)); + + if (hostedControl.MaximumSize.Width != 0) + minmax.maxTrackSize.Width = hostedControl.MaximumSize.Width; + + if (hostedControl.MaximumSize.Height != 0) + minmax.maxTrackSize.Height = hostedControl.MaximumSize.Height; + + minmax.minTrackSize = new Size(32, 32); + + if (hostedControl.MinimumSize.Width > minmax.minTrackSize.Width) + minmax.minTrackSize.Width = hostedControl.MinimumSize.Width; + + if (hostedControl.MinimumSize.Height > minmax.minTrackSize.Height) + minmax.minTrackSize.Height = hostedControl.MinimumSize.Height; + + if (IsGripShown == true) + minmax.minTrackSize.Height += GripSize.Height + 4; + + minmax.minTrackSize.Width += 4; + + Marshal.StructureToPtr(minmax, m.LParam, false); + } + } + + #endregion + + #endregion + } + + #endregion + + #region GripRenderer + + /// + /// Grip Renderer + /// + public static class GripRenderer + { + #region Private variables + + private static Bitmap _gripBitmap; + + #endregion + + #region RefreshGrip + + /// + /// Refreshes the Grip + /// + /// + /// + public static void RefreshGrip(Graphics g, Size size) + { + InitializeGripBitmap(g, size, true); + } + + #endregion + + #region InitializeGripBitmap + + private static void InitializeGripBitmap(Graphics g, Size size, bool refresh) + { + if (_gripBitmap == null || refresh == true || _gripBitmap.Size != size) + { + _gripBitmap = new Bitmap(size.Width, size.Height, g); + + using (Graphics gripG = Graphics.FromImage(_gripBitmap)) + ControlPaint.DrawSizeGrip(gripG, SystemColors.ButtonFace, 0, 0, size.Width, size.Height); + } + } + + #endregion + + #region Render + + /// + /// Grip renderer + /// + /// + /// + /// + public static void Render( + Graphics g, Point location, GripAlignMode mode) + { + Render(g, location, new Size(14, 14), mode); + } + + /// + /// Grip renderer + /// + /// + /// + /// + /// + public static void Render(Graphics g, + Point location, Size size, GripAlignMode mode) + { + InitializeGripBitmap(g, size, false); + + switch (mode) + { + case GripAlignMode.TopLeft: + size.Height = -size.Height; + size.Width = -size.Width; + break; + + case GripAlignMode.TopRight: + size.Height = -size.Height; + break; + + case GripAlignMode.BottomLeft: + size.Width = -size.Width; + break; + } + + // Reverse size grip for left-aligned + + if (size.Width < 0) + location.X -= size.Width; + + if (size.Height < 0) + location.Y -= size.Height; + + g.DrawImage(_gripBitmap, location.X, location.Y, size.Width, size.Height); + } + + #endregion + } + + #endregion + + #region Enums + + #region GripAlignMode + + /// + /// GripAlignMode + /// + public enum GripAlignMode + { + /// + /// None + /// + None, + + /// + /// TopLeft + /// + TopLeft, + + /// + /// TopRight + /// + TopRight, + + /// + /// BottomLeft + /// + BottomLeft, + + /// + /// BottomRight + /// + BottomRight, + } + + #endregion + + #region PopupAnchor + + /// + /// PopupAnchor + /// + public enum PopupAnchor + { + /// + /// Left + /// + Left, + + /// + /// Right + /// + Right + } + + #endregion + + #region PopupResizeMode + + /// + /// PopupResizeMode + /// + [Flags] + public enum PopupResizeMode + { + /// + /// None + /// + None = 0, + + /// + /// Left + /// + Left = 1, + + /// + /// Top + /// + Top = 2, + + /// + /// Right + /// + Right = 4, + + /// + /// Bottom + /// + Bottom = 8, + + /// + /// All + /// + All = (Top | Left | Bottom | Right), + + /// + /// TopLeft + /// + TopLeft = (Top | Left), + + /// + /// TopRight + /// + TopRight = (Top | Right), + + /// + /// BottomLeft + /// + BottomLeft = (Bottom | Left), + + /// + /// BottomRight + /// + BottomRight = (Bottom | Right), + } + + #endregion + + #endregion + + #region EventArgs + + #region PostRenderGripBarEventArgs + + /// + /// PostRenderGripBarEventArgs + /// + public class PostRenderGripBarEventArgs : EventArgs + { + #region Private variables + + private Graphics _Graphics; + private Rectangle _Bounds; + + #endregion + + /// + /// PostRenderGripBarEventArgs + /// + /// + /// + public PostRenderGripBarEventArgs(Graphics graphics, Rectangle bounds) + { + _Graphics = graphics; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region PreRenderGripBarEventArgs + + /// + /// PreRenderGripBarEventArgs + /// + public class PreRenderGripBarEventArgs : PostRenderGripBarEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// PreRenderGripBarEventArgs + /// + /// + /// + public PreRenderGripBarEventArgs(Graphics graphics, Rectangle bounds) + : base(graphics, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether the operation is canceled + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/Rtf.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/Rtf.cs new file mode 100644 index 00000000..3ac36607 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/Rtf.cs @@ -0,0 +1,800 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace DevComponents.DotNetBar.SuperGrid.SuperGrid +{ + /// + /// Constructor + /// + public class Rtf + { + #region Private data + + private StringBuilder _SbRtf; // Running Rtf text buffer + private StringBuilder _SbText; // Running plain text buffer + + private int _TextLength; // Running text length + private int _ProLength; // Prolog length (used for Clear()) + + private Group _Group; // RTF Group + private Stack _GStack; // Group Stack + + private bool _Finalized; // RTF has been finalized + private bool _KeepText; // Keep plain text + + #endregion + + #region Class definitions + + private class Group : ICloneable + { + public int Font; // Current font index + public int FontSize; // Current font size + public int ForeColor; // Current ForeColor index + public int BackColor; // Current BackColor index + + public int LeftMargin; // Left margin + public int FirstIndent; // First line indent + public int LeftIndent; // Left indent + + public bool Bold; // Bold + public bool Italicize; // Italicize + public bool SmallCaps; // Small Caps + public bool Strikeout; // Strikeout + public bool SuperScript; // Superscript + public bool Underline; // Underline + + public bool Paragraph; // Paragraph + + #region ICloneable Members + + // Routine to support the IClonable Interface + + public object Clone() + { + Group gp = new Group(); + + gp.Font = Font; + gp.FontSize = FontSize; + gp.ForeColor = ForeColor; + gp.BackColor = BackColor; + + gp.LeftMargin = LeftMargin; + gp.FirstIndent = FirstIndent; + gp.LeftIndent = LeftIndent; + + gp.Bold = Bold; + gp.Italicize = Italicize; + gp.SmallCaps = SmallCaps; + gp.Strikeout = Strikeout; + gp.SuperScript = SuperScript; + gp.Underline = Underline; + + gp.Paragraph = Paragraph; + + return (gp); + } + + #endregion + } + + #endregion + + /// + /// This constructor accepts the Rtf font and + /// color arrays, and initializes the Rtf buffer + /// + /// + /// + public Rtf(string[] sFonts, Color[] cColors) + { + _Group = new Group(); + _GStack = new Stack(); + _SbRtf = new StringBuilder(); + + InitRtf(sFonts, cColors); + } + + #region InitRtf + + /// + /// Initializes our Rtf engine + /// + /// + /// + private void InitRtf(string[] sFonts, Color[] cColors) + { + // Add the RTF prolog, font table, and + // color table + + _SbRtf.Append("{\\rtf1\\ansi\\deff0{\\fonttbl"); + + for (int i = 0; i < sFonts.Length; i++) + _SbRtf.AppendFormat("{0}\\f{1} {2};{3}", '{', i, sFonts[i], '}'); + + _SbRtf.Append("}{\\colortbl;"); + + for (int i = 0; i < cColors.Length; i++) + { + _SbRtf.AppendFormat("\\red{0}\\green{1}\\blue{2};", + cColors[i].R, cColors[i].G, cColors[i].B); + } + + _SbRtf.Append("}"); + + _ProLength = _SbRtf.Length; + } + + #endregion + + #region Close + + /// + /// Closes and finalizes the Rtf document + /// + public void Close() + { + if (_Finalized == false) + { + // Everything should be popped off the + // stack by now + + if (_GStack.Count > 0) + throw new Exception(); + + _SbRtf.Append("}"); + + _Finalized = true; + } + } + + #endregion + + #region Group support code + + #region BeginGroup + + /// + /// This routine begins a new RTF group + /// + /// + /// + public int BeginGroup(bool fParagraph) + { + PushGroup(); + + // The paragraph flag is used when we close + // the group, so save if for later inspection + + _Group.Paragraph = fParagraph; + + _SbRtf.Append("{"); + + return (_GStack.Count); + } + + #endregion + + #region EndGroup + + /// + /// This routine ends the current open group + /// + /// + public int EndGroup() + { + if (_Group.Paragraph == true) + _SbRtf.Append("\\par"); + + _SbRtf.Append("}"); + + PopGroup(); + + return (_GStack.Count); + } + + #endregion + + #region PushGroup + + /// + /// This routine saves all the current group settings + /// + private void PushGroup() + { + Group gp = (Group)_Group.Clone(); + + _GStack.Push(gp); + } + + #endregion + + #region PopGroup + + /// + /// This routine restores all the current + /// group settings + /// + private void PopGroup() + { + if (_GStack.Count <= 0) + throw new Exception(); + + _Group = _GStack.Pop(); + } + + #endregion + + #region GroupCount + + /// + /// Stack group count + /// + public int GroupCount + { + get { return (_GStack.Count); } + } + + #endregion + + #endregion + + #region Font support + + #region FontSize + + /// + /// This routine gets or sets the current + /// group level font size + /// + public int FontSize + { + get { return (_Group.FontSize); } + + set + { + if (_Group.FontSize != value) + { + // The fontsize setting for an RTF document + // is doubled (eg. if you want a 12 point font, then + // you must specify it as size 24) + + _SbRtf.AppendFormat("\\fs{0} ", value * 2); + + _Group.FontSize = value; + } + } + } + + #endregion + + #region Font + + /// + /// This routine gets or sets the current + /// group level font setting + /// + public int Font + { + get { return (_Group.Font); } + + set + { + if (_Group.Font != value) + { + _SbRtf.AppendFormat("\\f{0} ", value); + + _Group.Font = value; + } + } + } + + #endregion + + #region SuperScript + + /// + /// This routine gets or sets the current + /// group level superscript setting + /// + public bool SuperScript + { + get { return (_Group.SuperScript); } + + set + { + if (_Group.SuperScript != value) + { + _SbRtf.Append(value == true ? "\\super " : "\\super0 "); + _Group.SuperScript = value; + } + } + } + + #endregion + + #region SmallCaps + + private int _ScapsFontSize; + + /// + /// This routine gets or sets the current + /// group level smallCaps setting + /// + public bool SmallCaps + { + get { return (_Group.SmallCaps); } + + set + { + if (_Group.SmallCaps != value) + { + // 'scaps' does not appear to work in the system RichTextBox + // so we must simulate it via altering the fontsize a percentage + // of the current size + + if (value == true) + { + _ScapsFontSize = FontSize; + + FontSize = (FontSize * 7) / 8; + } + else + { + FontSize = _ScapsFontSize; + } + + _Group.SmallCaps = value; + } + } + } + + #endregion + + #region Bold + + /// + /// This routine gets or sets the current + /// group level font Bold setting + /// + public bool Bold + { + get { return (_Group.Bold); } + + set + { + if (_Group.Bold != value) + { + _SbRtf.Append(value == true ? "\\b " : "\\b0 "); + _Group.Bold = value; + } + } + } + + #endregion + + #region Italicize + + /// + /// This routine gets or sets the current + /// group level font Italics setting + /// + public bool Italicize + { + get { return (_Group.Italicize); } + + set + { + if (_Group.Italicize != value) + { + _SbRtf.Append(value == true ? "\\i " : "\\i0 "); + _Group.Italicize = value; + } + } + } + + #endregion + + #region Strikeout + + /// + /// This routine gets or sets the current + /// group level font Strikeout setting + /// + public bool Strikeout + { + get { return (_Group.Strikeout); } + + set + { + if (_Group.Strikeout != value) + { + _SbRtf.Append(value == true ? "\\strike " : "\\strike0 "); + _Group.Strikeout = value; + } + } + } + + #endregion + + #region Underline + + /// + /// This routine gets or sets the current + /// group level font Underline setting + /// + public bool Underline + { + get { return (_Group.Underline); } + + set + { + if (_Group.Underline != value) + { + _SbRtf.Append(value == true ? "\\ul " : "\\ul0 "); + + _Group.Underline = value; + } + } + } + + #endregion + + #endregion + + #region Color support + + #region ForeColor + + /// + /// This routine gets or sets the current + /// group level foreColor value + /// + public int ForeColor + { + get { return (_Group.ForeColor); } + + set + { + if (_Group.ForeColor != value) + { + _SbRtf.AppendFormat("\\cf{0} ", value + 1); + + _Group.ForeColor = value; + } + } + } + + #endregion + + #region BackColor + + /// + /// This routine gets or sets the current + /// group level backColor setting + /// + public int BackColor + { + get { return (_Group.BackColor); } + + set + { + if (_Group.BackColor != value) + { + // "\\cb " does not appear to work, so we work + // around this via using the highlight tag + + _SbRtf.AppendFormat("\\highlight{0} ", value + 1); + + _Group.BackColor = value; + } + } + } + + #endregion + + #endregion + + #region Margin / indent support + + #region LeftMargin + + /// + /// This routine gets or sets the current + /// group level left margin setting + /// + public int LeftMargin + { + get { return (_Group.LeftMargin); } + set { _Group.LeftMargin = value; } + } + + #endregion + + #region FirstIndent + + /// + /// This routine gets or sets the current + /// group level first indent setting + /// + public int FirstIndent + { + get { return (_Group.FirstIndent); } + + set + { + if (_Group.FirstIndent != value) + { + // Set the indent value, taking the current + // left margin into account + + _SbRtf.AppendFormat("\\fi{0} ", _Group.LeftMargin + value); + + _Group.FirstIndent = value; + } + } + } + + #endregion + + #region LeftIndent + + /// + /// This routine gets or sets the current + /// group level left indent setting + /// + public int LeftIndent + { + get { return (_Group.LeftIndent); } + + set + { + if (_Group.LeftIndent != value) + { + // Set the indent value, taking the current + // left margin into account + + _SbRtf.AppendFormat("\\li{0} ", _Group.LeftMargin + value); + + _Group.LeftIndent = value; + } + } + } + + #endregion + + #endregion + + #region Text output support + + #region KeepText + + /// + /// This property tells the rtf code whether to + /// keep a running accumulation of plain text + /// + public bool KeepText + { + get { return (_KeepText); } + + set + { + if (_KeepText != value) + { + _SbText = (value == true) ? + new StringBuilder() : null; + + _KeepText = value; + } + } + } + + #endregion + + #region Text + + /// + /// This read-only property returns the current plain + /// text - if the 'KeepText' property was set to true + /// + public string Text + { + get + { + //if (_GStack.Count != 0 || fFinalized == false) + // throw new Exception(); + + //if (sbText == null) + // throw new Exception(); + + return (_SbText.ToString()); + } + } + + #endregion + + #region RtfText + + /// + /// This read-only property returns the current + /// rtf accumulated control text + /// + public string RtfText + { + get + { + if (_GStack.Count != 0 || _Finalized == false) + throw new Exception(); + + return (_SbRtf.ToString()); + } + } + + #endregion + + #region TextLength + + /// + /// This property get/sets the current + /// rtf plain text length + /// + public int TextLength + { + get { return (_TextLength); } + set { _TextLength = value; } + } + + #endregion + + #region Clear + + /// + /// This routine clears the accumulated text + /// + public void Clear() + { + _SbRtf.Length = _ProLength; + + if (_SbText != null) + _SbText.Length = 0; + + _TextLength = 0; + } + + #endregion + + #region WriteText (char) + + /// + /// This routine writes a given char to the rtf buffer + /// + /// + public void WriteText(char c) + { + _SbRtf.Append(c); + + if (_SbText != null) + _SbText.Append(c); + + _TextLength++; + } + + #endregion + + #region WriteText (string) + + /// + /// This routine writes a given string to the rtf buffer + /// + /// + public void WriteText(string s) + { + if (s.Length > 0) + { + _SbRtf.Append(s); + + if (_SbText != null) + _SbText.Append(s); + + _TextLength += s.Length; + } + } + + #endregion + + #region WriteLine + + /// + /// This routine writes a new line to the rtf buffer + /// + public void WriteLine() + { + _SbRtf.Append("\\line "); + + if (_SbText != null) + _SbText.Append('\n'); + + _TextLength++; + } + + #endregion + + #region WriteLine (string) + + /// + /// This routine writes a given string followed + /// by a new line to the rtf buffer + /// + /// + public void WriteLine(string s) + { + WriteText(s); + WriteLine(); + } + + #endregion + + #region WriteTab + + /// + /// This routine writes a tab to the rtf buffer + /// + public void WriteTab() + { + _SbRtf.Append("\\tab "); + + if (_SbText != null) + _SbText.Append('\t'); + + _TextLength++; + } + + #endregion + + #region WriteHex + + /// + /// This routine writes hex chars to the rtf buffer + /// + /// + public void WriteHex(uint x) + { + string hex = + String.Format("{0:x2}", x); + + _SbRtf.AppendFormat("\\'{0}", hex); + + _TextLength++; + } + + #endregion + + #region CenterAlignText + + /// + /// This routine causes the test to be center aligned + /// + public void CenterAlignText() + { + _SbRtf.Append("\\qc "); + } + + #endregion + + #region LeftAlignText + + /// + /// This routine causes the test to be left aligned + /// + public void LeftAlignText() + { + _SbRtf.Append("\\ql "); + } + + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/SampleExpr.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/SampleExpr.Designer.cs new file mode 100644 index 00000000..55975217 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/SampleExpr.Designer.cs @@ -0,0 +1,79 @@ +namespace DevComponents.DotNetBar.SuperGrid +{ + partial class SampleExpr + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SampleExpr)); + this.btnClose = new DevComponents.DotNetBar.ButtonX(); + this.richTextBoxEx1 = new DevComponents.DotNetBar.Controls.RichTextBoxEx(); + this.SuspendLayout(); + // + // btnClose + // + this.btnClose.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + resources.ApplyResources(this.btnClose, "btnClose"); + this.btnClose.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnClose.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnClose.Name = "btnClose"; + this.btnClose.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnClose.Click += new System.EventHandler(this.BtnCloseClick); + // + // richTextBoxEx1 + // + // + // + // + this.richTextBoxEx1.BackgroundStyle.Class = "RichTextBoxBorder"; + this.richTextBoxEx1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; + this.richTextBoxEx1.BackgroundStyle.PaddingLeft = 5; + resources.ApplyResources(this.richTextBoxEx1, "richTextBoxEx1"); + this.richTextBoxEx1.Name = "richTextBoxEx1"; + this.richTextBoxEx1.Rtf = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Microsoft S" + + "ans Serif;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs17\\par\r\n}\r\n"; + // + // SampleExpr + // + this.AcceptButton = this.btnClose; + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.btnClose); + this.Controls.Add(this.richTextBoxEx1); + this.DoubleBuffered = true; + this.EnableGlass = false; + this.Name = "SampleExpr"; + this.ResumeLayout(false); + + } + + #endregion + + private ButtonX btnClose; + private DevComponents.DotNetBar.Controls.RichTextBoxEx richTextBoxEx1; + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/SampleExpr.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/SampleExpr.cs new file mode 100644 index 00000000..c8120e8b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/SampleExpr.cs @@ -0,0 +1,81 @@ +using System; +using System.IO; +using DevComponents.DotNetBar.Controls; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// SampleExpr + /// + public partial class SampleExpr : Office2007Form + { + /// + /// SampleExpr + /// + public SampleExpr(SuperGridControl superGrid) + { + InitializeComponent(); + + btnClose.Text = superGrid.FilterCloseString; + + string s = GetRtbText(superGrid); + + try + { + richTextBoxEx1.Rtf = s; + } + catch + { + richTextBoxEx1.Text = s; + } + } + + #region Public properties + + /// + ///The associated help RichTextBoxEx + /// + public RichTextBoxEx RichTextBoxEx + { + get { return (richTextBoxEx1); } + } + + #endregion + + #region GetRtbText + + internal string GetRtbText(SuperGridControl superGrid) + { + using (LocalizationManager lm = new LocalizationManager(superGrid)) + { + string s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterSampleExpr); + + if (s == "") + { + using (Stream stream = typeof(SampleExpr).Assembly.GetManifestResourceStream( + "DevComponents.DotNetBar.SuperGrid.SampleExpr.rtf")) + { + if (stream != null) + { + using (StreamReader reader = new StreamReader(stream)) + s = reader.ReadToEnd(); + } + } + } + + return (s); + } + } + + #endregion + + #region BtnCloseClick + + private void BtnCloseClick(object sender, System.EventArgs e) + { + Close(); + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/SampleExpr.resx b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/SampleExpr.resx new file mode 100644 index 00000000..725bebbb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFilter/SampleExpr.resx @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Bottom, Right + + + + 491, 216 + + + 82, 23 + + + + 6 + + + Close + + + btnClose + + + DevComponents.DotNetBar.ButtonX, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 0 + + + Fill + + + 0, 0 + + + 605, 251 + + + 7 + + + richTextBoxEx1 + + + DevComponents.DotNetBar.Controls.RichTextBoxEx, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + + $this + + + 1 + + + True + + + 96, 96 + + + 605, 251 + + + CenterScreen + + + SampleExpr + + + SampleExpr + + + DevComponents.DotNetBar.Office2007Form, DevComponents.DotNetBar2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFooter.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFooter.cs new file mode 100644 index 00000000..91b75623 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridFooter.cs @@ -0,0 +1,50 @@ +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridFooter + /// + public class GridFooter : GridTextRow + { + #region Constructors + + /// + /// GridFooter + /// + public GridFooter() + : this(null) + { + } + + /// + /// GridFooter + /// + /// + public GridFooter(string text) + : base(text) + { + } + + #endregion + + #region Style support + + /// + /// ApplyStyleEx + /// + /// + /// + protected override void ApplyStyleEx(TextRowVisualStyle style, StyleType[] css) + { + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.FooterStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.FooterStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.FooterStyles[cs]); + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridGroup.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridGroup.cs new file mode 100644 index 00000000..3ef540b7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridGroup.cs @@ -0,0 +1,1731 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Primitives; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.SuperGrid.TextMarkup; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// GridGroup + /// + public class GridGroup : GridContainer + { + #region Static data + + private static bool _dragSelection; + private static bool _dragStarted; + + #endregion + + #region Private variables + + private GridCell _Cell; + + private string _Text; + private Size _TextSize; + + private Rectangle _ExpandButtonBounds; + + private int _AnchorIndex; + + private GroupArea _HitArea; + private GridContainer _HitItem; + private GroupArea _LastHitArea; + + private GroupArea _MouseDownHitArea; + private Point _MouseDownPoint; + private GridContainer _MouseDownHitRow; + + private GroupHeaderVisualStyles _GroupHeaderVisualStyles; + private GroupHeaderVisualStyles _EffectiveVisualStyles; + + private int _StyleUpdateCount; + + private BodyElement _GroupTextMarkup; + + private object _GroupId; + + #endregion + + #region Public properties + + #region Bounds + + /// + /// Bounds + /// + public override Rectangle Bounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = BoundsRelative; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true) + r.X -= HScrollOffset; + + r.Height = FixedRowHeight; + + Rectangle t = ViewRect; + + if (r.Right > t.Right) + r.Width -= (r.Right - t.Right); + + return (r); + } + + return (Rectangle.Empty); + } + } + + #endregion + + #region Cell + + /// + /// Gets the Group's associated grid cell. + /// + public GridCell Cell + { + get { return (_Cell); } + internal set { _Cell = value; } + } + + #endregion + + #region Column + + /// + /// Gets the Group's associated grid Column. + /// + public GridColumn Column + { + get { return (_Cell != null ? _Cell.GridColumn : null); } + } + + #endregion + + #region GroupHeaderVisualStyles + + /// + /// Gets or sets the visual styles + /// assigned to the element. Default value is null. + /// + [DefaultValue(null), Category("Style")] + [Description("Indicates visual style assigned to the element")] + public GroupHeaderVisualStyles GroupHeaderVisualStyles + { + get + { + if (_GroupHeaderVisualStyles == null) + { + _GroupHeaderVisualStyles = new GroupHeaderVisualStyles(); + + GroupHeaderStyleChangeHandler(null, _GroupHeaderVisualStyles); + } + + return (_GroupHeaderVisualStyles); + } + + set + { + if (_GroupHeaderVisualStyles != value) + { + GroupHeaderVisualStyles oldValue = _GroupHeaderVisualStyles; + _GroupHeaderVisualStyles = value; + + OnCellStyleChanged("GroupHeaderVisualStyle", oldValue, value); + } + } + } + + private void OnCellStyleChanged(string property, + GroupHeaderVisualStyles oldValue, GroupHeaderVisualStyles newValue) + { + GroupHeaderStyleChangeHandler(oldValue, newValue); + + OnPropertyChanged(property); + } + + #endregion + + #region GroupValue + + /// + /// GroupValue + /// + public object GroupValue + { + get { return (_Cell != null ? _Cell.Value : 0); } + } + + #endregion + + #region PlainText + + /// + /// Gets the "Plain" header Text (MiniMarkup stripped) + /// + public string PlainText + { + get + { + if (_GroupTextMarkup != null) + return (_GroupTextMarkup.PlainText); + + return (_Text); + } + } + + #endregion + + #region Text + + /// + /// Text + /// + public string Text + { + get { return (_Text); } + + set + { + if (_Text != value) + { + _Text = value; + + MarkupGroupTextChanged(); + + OnPropertyChangedEx("Text", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region GroupId + + internal object GroupId + { + get { return (_GroupId); } + set { _GroupId = value; } + } + + #endregion + + #region GroupTextMarkup + + internal BodyElement GroupTextMarkup + { + get { return (_GroupTextMarkup); } + set { _GroupTextMarkup = value; } + } + + #endregion + + #endregion + + #region MeasureOverride + + #region MeasureOverride + + /// + /// MeasureOverride + /// + /// + /// + /// + protected override void MeasureOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + Size sizeNeeded = Size.Empty; + GridPanel panel = stateInfo.GridPanel; + Graphics g = layoutInfo.Graphics; + + if (CanShowRowHeader(panel) == true) + sizeNeeded.Width += panel.RowHeaderWidthEx; + + GroupHeaderVisualStyle style = GetSizingStyle(panel); + + Size size = MeasureGroupText(g, style, constraintSize); + + if (size.Height > 0) + { + size.Height += Dpi.Height8; + + size.Width += Dpi.Width(style.Padding.Horizontal); + size.Height += Dpi.Height(style.Padding.Vertical); + } + + size.Height = Math.Max(size.Height, Dpi.Height(panel.GroupHeaderHeight)); + + sizeNeeded.Width += size.Width; + sizeNeeded.Height = Math.Max(size.Height, sizeNeeded.Height); + + if (panel.ShowGroupUnderline == true && size.Height > 0) + sizeNeeded.Height += Dpi.Height4; + + FixedRowHeight = sizeNeeded.Height; + + if (Rows != null && Expanded == true) + { + if (panel.IndentGroups == true) + { + GridLayoutStateInfo itemStateInfo = new + GridLayoutStateInfo(panel, stateInfo.IndentLevel + 1); + + size = MeasureSubItems(layoutInfo, itemStateInfo, constraintSize); + } + else + { + size = MeasureSubItems(layoutInfo, stateInfo, constraintSize); + } + + sizeNeeded.Width = Math.Max(size.Width, sizeNeeded.Width); + sizeNeeded.Height += size.Height; + } + + Size = sizeNeeded; + } + + #endregion + + #region MeasureGroupText + + private Size MeasureGroupText(Graphics g, + GroupHeaderVisualStyle style, Size constraintSize) + { + _TextSize = Size.Empty; + + if (String.IsNullOrEmpty(Text) == false) + { + GridPanel panel = GridPanel; + + if (panel.IsSubPanel == false) + { + if (panel.ShowGroupExpand == true) + { + constraintSize.Width = SViewRect.Width; + + int n = panel.TreeButtonIndent + + Dpi.Width(panel.LevelIndentSize.Width * IndentLevel); + + constraintSize.Width -= n; + } + } + + _TextSize = MeasureHeaderText(g, style, constraintSize); + } + + return (_TextSize); + } + + #region MeasureHeaderText + + private Size MeasureHeaderText(Graphics g, + GroupHeaderVisualStyle style, Size constraintSize) + { + Size size = Size.Empty; + + string s = Text; + + if (string.IsNullOrEmpty(s) == false) + { + if (_GroupTextMarkup != null) + { + size = GetMarkupTextSize(g, + _GroupTextMarkup, style, constraintSize.Width); + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + size = (constraintSize.IsEmpty == true) + ? TextHelper.MeasureText(g, s, style.Font) + : TextHelper.MeasureText(g, s, style.Font, constraintSize, tf); + } + } + + return (size); + } + + #region GetMarkupTextSize + + private Size GetMarkupTextSize(Graphics g, + BodyElement textMarkup, GroupHeaderVisualStyle style, int width) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + textMarkup.InvalidateElementsSize(); + textMarkup.Measure(new Size(width, 0), d); + + return (textMarkup.Bounds.Size); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region ArrangeOverride + + /// + /// ArrangeOverride + /// + /// + /// + /// + protected override void ArrangeOverride(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + Rectangle bounds = layoutBounds; + bounds.Height = FixedRowHeight; + + GridPanel panel = stateInfo.GridPanel; + IndentLevel = stateInfo.IndentLevel; + + if (panel.ShowGroupExpand == true) + { + GroupHeaderVisualStyle style = GetSizingStyle(panel); + + Rectangle r = bounds; + + r.Width = Dpi.Width(panel.LevelIndentSize.Width); + r.Height -= Dpi.Height(style.Padding.Vertical); + + int n = Dpi.Height(panel.GroupHeaderHeight); + + if (r.Height < n) + r.Height = n; + + if (CanShowRowHeader(panel) == true) + r.X += panel.RowHeaderWidthEx; + + n = panel.TreeButtonIndent + + Dpi.Width((panel.LevelIndentSize.Width * IndentLevel) - panel.LevelIndentSize.Width); + + r.X += n; + + if (r.Right > BoundsRelative.Right) + r.Width -= r.Right - BoundsRelative.Right; + + r.X += Dpi.Width(style.Padding.Left); + r.Y += Dpi.Height(style.Padding.Top); + + Size size = panel.GetTreeButtonSize(); + + r.X += (r.Width - size.Width) / 2; + r.Y += (r.Height - size.Height) / 2 - 1; + + r.Size = size; + + _ExpandButtonBounds = r; + } + else + { + _ExpandButtonBounds = Rectangle.Empty; + } + + if (Rows != null && Expanded == true) + { + bounds = layoutBounds; + + bounds.Y += FixedRowHeight; + bounds.Height -= FixedRowHeight; + + if (panel.IndentGroups == true) + { + GridLayoutStateInfo itemStateInfo = + new GridLayoutStateInfo(panel, stateInfo.IndentLevel + 1); + + ArrangeSubItems(layoutInfo, itemStateInfo, bounds); + } + else + { + ArrangeSubItems(layoutInfo, stateInfo, bounds); + } + } + } + + #endregion + + #region RenderOverride + + /// + /// RenderOverride + /// + /// + protected override void RenderOverride(GridRenderInfo renderInfo) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = Bounds; + + if (r.IntersectsWith(renderInfo.ClipRectangle)) + { + Graphics g = renderInfo.Graphics; + GroupHeaderVisualStyle style = GetEffectiveStyle(); + + if (SuperGrid.DoPreRenderGroupHeaderEvent(g, + this, RenderParts.Background | RenderParts.RowHeader, r) == false) + { + RenderGroupBackground(g, style, r); + RenderRowHeader(g, panel, style, r); + + SuperGrid.DoPostRenderGroupHeaderEvent(g, + this, RenderParts.Background | RenderParts.RowHeader, r); + } + + if (CanShowRowHeader(panel) == true) + { + r.X += panel.RowHeaderWidthEx; + r.Width -= panel.RowHeaderWidthEx; + } + + RenderHeaderExpand(g, panel, ref r); + + r = GetAdjustedBounds(style, r); + + int n = Dpi.Width(panel.GroupHeaderHeight); + + if (r.Height < n) + r.Height = n; + + if (SuperGrid.DoPreRenderGroupHeaderEvent(g, + this, RenderParts.Content, r) == false) + { + RenderHeaderText(g, style, r); + RenderHeaderUnderline(g, panel, style, r); + + SuperGrid.DoPostRenderGroupHeaderEvent(g, + this, RenderParts.Content, r); + } + } + + if (Rows != null && Expanded == true) + { + UpdateMergeFlags(); + + foreach (GridElement item in Rows) + { + if (item.Visible == true) + item.Render(renderInfo); + } + } + } + } + + #region GetAdjustedBounds + + private Rectangle GetAdjustedBounds(GroupHeaderVisualStyle style, Rectangle r) + { + r.X += Dpi.Width(style.Padding.Left); + r.Width -= Dpi.Width(style.Padding.Horizontal); + + r.Y += Dpi.Height(style.Padding.Top + 2); + r.Height -= Dpi.Height(style.Padding.Vertical + 2); + + return (r); + } + + #endregion + + #region RenderRowHeader + + private void RenderRowHeader(Graphics g, + GridPanel panel, GroupHeaderVisualStyle style, Rectangle r) + { + if (CanShowRowHeader(panel) == true) + { + r.Width = panel.RowHeaderWidthEx; + + using (Brush br = style.RowHeaderStyle.Background.GetBrush(r)) + g.FillRectangle(br, r); + + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + if (Dpi.Height1 == Dpi.Width1) + { + using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X + 1, r.Top, r.Right - 2, r.Top); + g.DrawLine(pen, r.X + 1, r.Top, r.X + 1, r.Bottom - 1); + } + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X, r.Top - 1, r.Right - 1, r.Top - 1); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 2, r.Bottom - 1); + + g.DrawLine(pen, r.Right - 1, r.Top, r.Right - 1, r.Bottom - 1); + } + } + else + { + using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Height1)) + g.DrawLine(pen, r.X + 1, r.Top, r.Right - 2, r.Top); + + using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Width1)) + g.DrawLine(pen, r.X + 1, r.Top, r.X + 1, r.Bottom - 1); + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X, r.Top - 1, r.Right - 1, r.Top - 1); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 2, r.Bottom - 1); + } + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) + g.DrawLine(pen, r.Right - 1, r.Top, r.Right - 1, r.Bottom - 1); + } + + r.X += Dpi.Width4; + r.Width -= Dpi.Width4; + + int n = RenderIndicatorImage(g, panel, this, r); + + r.X += n; + r.Width -= n; + + if (panel.ShowRowGridIndex == true) + RenderGridIndex(g, this, style.RowHeaderStyle, r); + } + } + + #region RenderIndicatorImage + + private int RenderIndicatorImage(Graphics g, + GridPanel panel, GridContainer row, Rectangle r) + { + RowHeaderVisualStyle style = GetEffectiveRowStyle().RowHeaderStyle; + + Image image = style.GetActiveRowImage(panel); + + if (image != null) + { + if (panel.ActiveRow == row) + { + if (panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Image || + panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Both) + { + Rectangle u = r; + u.Size = image.Size; + + if (r.Height > u.Height) + u.Y += (r.Height - u.Height) / 2; + + u.Intersect(r); + + g.DrawImageUnscaledAndClipped(image, u); + } + } + + return (image.Width); + } + + return (0); + } + + #endregion + + #region RenderGridIndex + + private void RenderGridIndex(Graphics g, + GridContainer row, RowHeaderVisualStyle style, Rectangle r) + { + string text = (row.GridIndex + row.GridPanel.RowHeaderIndexOffset).ToString(); + + Font font = style.Font ?? SystemFonts.DefaultFont; + + r.Inflate(-2, 0); + + TextDrawing.DrawString(g, text, + font, style.TextColor, r, style.GetTextFormatFlags()); + + return; + } + + #endregion + + #endregion + + #region CanShowRowHeader + + /// + /// CanShowRowHeader + /// + /// + /// + protected virtual bool CanShowRowHeader(GridPanel panel) + { + switch (panel.GroupRowHeaderVisibility) + { + case RowHeaderVisibility.Always: + return (true); + + case RowHeaderVisibility.PanelControlled: + return (panel.ShowRowHeaders); + } + + return (false); + } + + #endregion + + #region RenderGroupBackground + + private void RenderGroupBackground( + Graphics g, GroupHeaderVisualStyle style, Rectangle r) + { + if (style.Background != null && style.Background.IsEmpty == false) + { + using (Brush br = style.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + } + + #endregion + + #region RenderHeaderExpand + + private void RenderHeaderExpand( + Graphics g, GridPanel panel, ref Rectangle r) + { + if (panel.ShowGroupExpand == true) + { + Rectangle bounds = _ExpandButtonBounds; + + if (IsVFrozen == false) + bounds.Y -= VScrollOffset; + + if (panel.IsSubPanel == true) + bounds.X -= HScrollOffset; + + bool hot = (_HitArea == GroupArea.ExpandButton); + + Image image = (Expanded == true) + ? panel.GetCollapseButton(g, hot) : panel.GetExpandButton(g, hot); + + ExpandDisplay.RenderButton(g, image, bounds, r); + + int n = panel.TreeButtonIndent + + Dpi.Width(panel.LevelIndentSize.Width * IndentLevel); + + r.X += n; + r.Width -= n; + } + else + { + r.X += Dpi.Width3; + r.Width -= Dpi.Width3; + } + } + + #endregion + + #region RenderHeaderText + + private void RenderHeaderText(Graphics g, + GroupHeaderVisualStyle style, Rectangle r) + { + eTextFormat tf = style.GetTextFormatFlags(); + + if (style.Alignment == Alignment.BottomLeft || + style.Alignment == Alignment.BottomCenter || + style.Alignment == Alignment.BottomRight) + { + r.Height -= Dpi.Height4; + } + + if (r.Width > 0 && r.Height > 0) + { + if (_GroupTextMarkup != null) + RenderTextMarkup(g, _GroupTextMarkup, style, r); + else + TextDrawing.DrawString(g, Text, style.Font, style.TextColor, r, tf); + } + } + + #region RenderTextMarkup + + private void RenderTextMarkup(Graphics g, + BodyElement textMarkup, GroupHeaderVisualStyle style, Rectangle r) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + textMarkup.Arrange(new Rectangle(r.Location, r.Size), d); + + Size size = textMarkup.Bounds.Size; + + switch (style.Alignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + if (r.Height > size.Height) + r.Y += (r.Height - size.Height) / 2; + break; + + default: + if (r.Height > size.Height) + r.Y = r.Bottom - size.Height; + break; + } + + textMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + textMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #endregion + + #region RenderHeaderUnderline + + private void RenderHeaderUnderline(Graphics g, + GridPanel panel, GroupHeaderVisualStyle style, Rectangle r) + { + if (panel.ShowGroupUnderline == true && style.UnderlineColor.IsEmpty == false) + { + switch (style.Alignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + r.Y += (r.Height + _TextSize.Height) / 2 + Dpi.Height4; + break; + + case Alignment.TopLeft: + case Alignment.TopCenter: + case Alignment.TopRight: + r.Y += _TextSize.Height + Dpi.Height6; + break; + + default: + r.Y = r.Bottom - _TextSize.Height / 2; + break; + } + + if (r.Width > SViewRect.Width) + r.Width = SViewRect.Width; + + int n = r.Width; + + r.Height = Dpi.Height1; + r.Width = (int)(r.Width * .75); + + Rectangle t = r; + + Color color1 = style.UnderlineColor; + Color color2 = Color.Transparent; + + switch (style.Alignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + r.X += (n - r.Width) / 2; + r.Width /= 2; + + color1 = Color.Transparent; + color2 = style.UnderlineColor; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + r.X += n - r.Width; + + color1 = Color.Transparent; + color2 = style.UnderlineColor; + break; + } + + t.X = r.X; + + if ((r.Width > 0 && r.Height > 0) && (t.Width > 0 && t.Height > 0)) + { + using (LinearGradientBrush br = new + LinearGradientBrush(r, color1, color2, 0f)) + { + br.WrapMode = WrapMode.TileFlipXY; + + g.FillRectangle(br, t); + } + } + } + } + + #endregion + + #endregion + + #region Mouse support + + #region InternalMouseEnter + + internal override void InternalMouseEnter(EventArgs e) + { + base.InternalMouseEnter(e); + + InvalidateRender(); + } + + #endregion + + #region InternalMouseLeave + + internal override void InternalMouseLeave(EventArgs e) + { + base.InternalMouseLeave(e); + + InvalidateRender(); + } + + #endregion + + #region InternalMouseMove + + internal override void InternalMouseMove(MouseEventArgs e) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (IsMouseDown == true) + ProcessMouseDownMove(e, panel); + + ProcessMouseMove(e, panel); + } + + if (Capture == false) + base.InternalMouseMove(e); + } + + #region ProcessMouseDownMove + + private void ProcessMouseDownMove(MouseEventArgs e, GridPanel panel) + { + Rectangle r = ViewRect; + + if (MouseDownPoint.Y < r.Y) + { + int n = SuperGrid.PrimaryGrid.FixedRowHeight - + SuperGrid.PrimaryGrid.FixedHeaderHeight; + + r.Y -= n; + r.Height += n; + } + + VScrollBarAdv vsb = SuperGrid.VScrollBar; + + if ((e.Y >= r.Y) && + (e.Y < r.Bottom || (vsb.Value >= vsb.Maximum - vsb.LargeChange))) + { + SuperGrid.DisableAutoScrolling(); + + switch (_MouseDownHitArea) + { + case GroupArea.Content: + case GroupArea.RowHeader: + _HitItem = GetRowAt(panel, e.Location); + + if (_HitItem != null) + { + if (DragStarted(panel, e) == false) + { + if (panel.MultiSelect == true) + { + if (_HitItem != panel.LastProcessedItem) + ProcessExtendSelection(panel, true); + } + } + } + break; + } + } + else + { + SuperGrid.EnableAutoScrolling(AutoScrollEnable.Vertical, r); + } + } + + #endregion + + #region ProcessMouseMove + + internal void ProcessMouseMove(MouseEventArgs e, GridPanel panel) + { + _HitArea = GetGroupAreaAt(e); + + switch (_HitArea) + { + case GroupArea.ExpandButton: + SuperGrid.GridCursor = Cursors.Hand; + break; + + default: + SuperGrid.GridCursor = Cursors.Default; + break; + } + + if (_LastHitArea != _HitArea) + { + _LastHitArea = _HitArea; + + InvalidateRender(); + } + } + + #endregion + + #region DragStarted + + private bool DragStarted(GridPanel panel, MouseEventArgs e) + { + if (_dragSelection == true && Capture == true) + { + if (_dragStarted == false) + { + if (DragDrop.DragStarted(_MouseDownPoint, e.Location) == true) + { + _dragStarted = true; + + if (SuperGrid.DoItemDragEvent(this, e) == true) + { + _dragSelection = false; + + Capture = true; + + InitExtendSelection(panel); + } + } + } + + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region InternalMouseDown + + internal override void InternalMouseDown(MouseEventArgs e) + { + _MouseDownHitArea = _HitArea; + _MouseDownHitRow = _HitItem; + _MouseDownPoint = e.Location; + + GridPanel panel = GridPanel; + + if (panel != null) + { + GridCell ecell = SuperGrid.EditorCell; + + if (ecell != null) + { + if (ecell.EndEdit() == false) + return; + } + + _dragSelection = false; + _dragStarted = false; + + if (_MouseDownHitArea != GroupArea.NoWhere) + { + if (_MouseDownHitArea == GroupArea.ExpandButton || + panel.GroupHeaderClickBehavior == GroupHeaderClickBehavior.ExpandCollapse) + { + Expanded = !Expanded; + } + else + { + if (ShouldExtendSelection(panel) == true) + { + InitExtendSelection(panel); + } + else + { + if (IsMouseDown == true) + { + Capture = true; + + _dragSelection = true; + } + } + } + } + } + } + + #region ShouldExtendSelection + + private bool ShouldExtendSelection(GridPanel panel) + { + return (panel.SuperGrid.HasItemDragHandler == false || IsSelected == false || + ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) != Keys.None)); + } + + #endregion + + #region InitExtendSelection + + private void InitExtendSelection(GridPanel panel) + { + if (IsMouseSelectable() == true) + { + Capture = true; + + ExtendSelectionEx(panel); + } + } + + #region IsMouseSelectable + + private bool IsMouseSelectable() + { + return (IsMouseSelectableEx(Control.MouseButtons)); + } + + private bool IsMouseSelectableEx(MouseButtons mb) + { + if ((mb & MouseButtons.Left) == MouseButtons.Left) + return (true); + + return (IsSelected == false); + } + + #endregion + + #region ExtendSelectionEx + + private void ExtendSelectionEx(GridPanel panel) + { + if (_MouseDownHitRow != null && _HitItem != null) + { + _AnchorIndex = _MouseDownHitRow.GridIndex; + + if (panel.LastProcessedItem != this && panel.LastProcessedItem != null) + panel.LastProcessedItem.InvalidateRender(); + + bool ckey = panel.MultiSelect == true + ? ((Control.ModifierKeys & Keys.Control) == Keys.Control) + : false; + + panel.LastProcessedItem = (ckey == true) ? _HitItem : this; + + ProcessExtendSelection(panel, false); + } + } + + #region ProcessExtendSelection + + internal void ProcessExtendSelection(GridPanel panel, bool extend) + { + bool ckey = panel.MultiSelect == true + ? ((Control.ModifierKeys & Keys.Control) == Keys.Control) + : false; + + if (ckey == true) + ProcessControlExtend(panel, extend); + else + ProcessNonControlExtend(panel, extend); + + panel.LastProcessedItem = _HitItem; + } + + #region ProcessControlExtend + + private void ProcessControlExtend(GridPanel panel, bool extend) + { + if (panel.LastProcessedItem == null) + panel.LastProcessedItem = _MouseDownHitRow; + + GridContainer lastRow = panel.LastProcessedItem as GridContainer; + + if (lastRow != null) + { + int startIndex = lastRow.GridIndex; + int endIndex = _HitItem.GridIndex; + + panel.NormalizeIndices(extend, + _AnchorIndex, ref startIndex, ref endIndex); + + for (int i = startIndex; i <= endIndex; i++) + { + if (extend == false || i != _AnchorIndex) + panel.SetSelectedRows(i, 1, !panel.IsRowSelected(i)); + } + + InvalidateRows(panel, startIndex, endIndex, true); + } + } + + #endregion + + #region ProcessNonControlExtend + + private void ProcessNonControlExtend(GridPanel panel, bool extend) + { + bool skey = (panel.MultiSelect == true) ? + ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) : false; + + if (skey == false || panel.SelectionRowAnchor == null) + panel.SelectionRowAnchor = _MouseDownHitRow; + + ExtendSelection(panel, _HitItem, extend); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #endregion + + #region InternalMouseUp + + /// + /// InternalMouseUp + /// + /// + internal override void InternalMouseUp(MouseEventArgs e) + { + SuperGrid.DisableAutoScrolling(); + + if (ExtendDragSelection(GridPanel, e) == false) + { + if (_MouseDownHitArea == _HitArea) + { + if (_MouseDownHitArea == GroupArea.Content || _MouseDownHitArea == GroupArea.RowHeader) + { + GridPanel panel = GridPanel; + + if (GridPanel.GroupHeaderClickBehavior == GroupHeaderClickBehavior.SelectAll) + { + bool ckey = panel.MultiSelect == true + ? ((Control.ModifierKeys & Keys.Control) == Keys.Control) + : false; + + ProcessSelectAll(panel, this, ckey); + } + } + + SuperGrid.DoGroupHeaderClickEvent(this, _MouseDownHitArea, e); + } + } + } + + #region ExtendDragSelection + + private bool ExtendDragSelection(GridPanel panel, MouseEventArgs e) + { + if (_dragSelection == true && Capture == true) + { + if (IsMouseSelectableEx(e.Button) == true) + { + if (_MouseDownHitRow == _HitItem) + { + ExtendSelectionEx(panel); + + return (true); + } + } + } + + return (false); + } + + #endregion + + #region ProcessSelectAll + + private void ProcessSelectAll(GridPanel panel, + GridContainer item, bool ckey) + { + if (item.Rows != null && item.Rows.Count > 0) + { + item.Expanded = true; + + foreach (GridContainer row in item.Rows) + { + if (row is GridGroup) + { + ProcessSelectAll(panel, row, ckey); + } + else + { + int startIndex = ((GridContainer)item.Rows[0]).GridIndex; + int endIndex = ((GridContainer)item.Rows[item.Rows.Count - 1]).GridIndex; + + if (ckey == true) + { + for (int i = startIndex; i <= endIndex; i++) + panel.SetSelectedRows(i, 1, !panel.IsRowSelected(i)); + } + else + { + panel.SetSelectedRows(startIndex, endIndex - startIndex + 1, true); + } + break; + } + } + } + } + + #endregion + + #endregion + + #region InternalMouseDoubleClick + + internal override void InternalMouseDoubleClick(MouseEventArgs e) + { + if (_HitArea == _MouseDownHitArea) + SuperGrid.DoGroupHeaderDoubleClickEvent(this, _MouseDownHitArea, e); + } + + #endregion + + #endregion + + #region GetGroupAreaAt + + /// + /// Returns element at specified mouse coordinates + /// + /// Mouse event arguments + /// Reference to child Group element or null + /// if no element at specified coordinates + protected virtual GroupArea GetGroupAreaAt(MouseEventArgs e) + { + return GetGroupAreaAt(e.X, e.Y); + } + + /// + /// Returns element at specified mouse coordinates + /// + /// Horizontal position + /// Vertical position + /// Reference to child element or null + /// if no element at specified coordinates + protected virtual GroupArea GetGroupAreaAt(int x, int y) + { + GridPanel panel = GridPanel; + + _HitItem = GetRowAt(panel, new Point(x, y)); + + Rectangle r = BoundsRelative; + r.Height = FixedRowHeight; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true) + r.X -= HScrollOffset; + + if (r.Contains(x, y) == true) + { + if (panel.ShowRowHeaders == true) + { + if (x >= r.X && x < r.X + panel.RowHeaderWidthEx) + return (GroupArea.RowHeader); + } + + r = _ExpandButtonBounds; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (GridPanel.IsSubPanel == true) + r.X -= HScrollOffset; + + if (r.Contains(x, y) == true) + return (GroupArea.ExpandButton); + + return (GroupArea.Content); + } + + return (GroupArea.NoWhere); + } + + #endregion + + #region GetRowAt + + private GridContainer GetRowAt(GridPanel panel, Point pt) + { + Rectangle r = panel.ContainerBounds; + r.X -= HScrollOffset; + + if (pt.X < r.X) + pt.X = r.X; + + GridContainer row = panel; + GridElement item = row.InternalGetElementAt(pt.X, pt.Y); + + while (item != null) + { + row = item as GridContainer; + + if (row == null) + break; + + if (row is GridRow) + item = ((GridRow)row).GetRowElementAt(pt.X, pt.Y, false); + else + item = row.GetElementAt(pt.X, pt.Y); + + if (item is GridContainer == false) + return (row); + } + + return (null); + } + + #endregion + + #region InvalidateRender + + /// + /// InvalidateRender + /// + public override void InvalidateRender() + { + Rectangle bounds = BoundsRelative; + + if (IsVFrozen == false) + bounds.Y -= VScrollOffset; + + SuperGridControl grid = SuperGrid; + + if (grid != null) + grid.InvalidateRender(bounds); + + OnRenderInvalid(EventArgs.Empty); + } + + #endregion + + #region Style support routines + + #region GroupHeaderStyleChangeHandler + + private void GroupHeaderStyleChangeHandler( + GroupHeaderVisualStyles oldValue, GroupHeaderVisualStyles newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region GetEffectiveStyle + + /// + /// GetEffectiveStyle + /// + /// + public GroupHeaderVisualStyle GetEffectiveStyle() + { + StyleState state = GetState(); + + return (GetEffectiveStyle(state)); + } + + internal GroupHeaderVisualStyle GetEffectiveStyle(StyleType styleType) + { + ValidateStyle(); + + return (GetStyle(styleType)); + } + + internal GroupHeaderVisualStyle GetEffectiveStyle(StyleState state) + { + ValidateStyle(); + + switch (state) + { + case StyleState.MouseOver: + return (GetStyle(StyleType.MouseOver)); + + case StyleState.Selected: + return (GetStyle(StyleType.Selected)); + + case StyleState.Selected | StyleState.MouseOver: + return (GetStyle(StyleType.SelectedMouseOver)); + + case StyleState.ReadOnly: + return (GetStyle(StyleType.ReadOnly)); + + case StyleState.ReadOnly | StyleState.MouseOver: + return (GetStyle(StyleType.ReadOnlyMouseOver)); + + case StyleState.ReadOnly | StyleState.Selected: + return (GetStyle(StyleType.ReadOnlySelected)); + + case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: + return (GetStyle(StyleType.ReadOnlySelectedMouseOver)); + + default: + return (GetStyle(StyleType.Default)); + } + } + + #endregion + + #region GetStyle + + private GroupHeaderVisualStyle GetStyle(StyleType e) + { + if (_EffectiveVisualStyles.IsValid(e) == false) + { + GroupHeaderVisualStyle style = new GroupHeaderVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.GroupHeaderStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.GroupHeaderStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.GroupHeaderStyles[cs]); + + style.ApplyStyle(GroupHeaderVisualStyles[cs]); + } + } + + SuperGrid.DoGetGroupHeaderStyleEvent(this, e, ref style); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + if (style.Font == null) + style.Font = SystemFonts.DefaultFont; + + if (style.TextColor.IsEmpty) + style.TextColor = Color.Black; + + _EffectiveVisualStyles[e] = style; + } + + return (_EffectiveVisualStyles[e]); + } + + #endregion + + #region ValidateStyle + + private void ValidateStyle() + { + if (_EffectiveVisualStyles == null || + (_StyleUpdateCount != SuperGrid.StyleUpdateCount)) + { + _EffectiveVisualStyles = new GroupHeaderVisualStyles(); + + _StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #region GetState + + internal StyleState GetState() + { + StyleState rowState = StyleState.Default; + + if (IsMouseOver == true) + { + Point pt = SuperGrid.PointToClient(Control.MousePosition); + + if (Bounds.Contains(pt) == true) + rowState |= StyleState.MouseOver; + } + + if (IsSelected == true) + rowState |= StyleState.Selected; + + return (rowState); + } + + #endregion + + #region GetSizingStyle + + private GroupHeaderVisualStyle GetSizingStyle(GridPanel panel) + { + StyleType styleType = panel.GetSizingStyle(); + + if (styleType == StyleType.NotSet) + styleType = StyleType.Default; + + return (GetEffectiveStyle(styleType)); + } + + #endregion + + #endregion + + #region CreateItemsCollection + + /// + /// Creates the GridItemsCollection that hosts the items. + /// + /// New instance of GridItemsCollection. + protected override GridItemsCollection CreateItemsCollection() + { + GridItemsCollection items = new GridItemsCollection(); + + items.CollectionChanged += ItemsCollectionChanged; + + return (items); + } + + #endregion + + #region DisposeItemsCollection + + /// + /// DisposeItemsCollection + /// + /// + protected override void DisposeItemsCollection(GridItemsCollection items) + { + items.CollectionChanged -= ItemsCollectionChanged; + } + + #endregion + + #region ItemsCollectionChanged + + void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + case NotifyCollectionChangedAction.Replace: + + foreach (GridElement item in e.NewItems) + item.Parent = this; + break; + } + + GridPanel panel = GridPanel; + + if (panel != null) + panel.RowCollectionChanged(e); + } + + #endregion + + #region Markup support + + private void MarkupGroupTextChanged() + { + _GroupTextMarkup = null; + + if (Column != null && Column.EnableGroupHeaderMarkup == true) + { + if (MarkupParser.IsMarkup(_Text) == true) + _GroupTextMarkup = MarkupParser.Parse(_Text); + } + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + GroupHeaderVisualStyles = null; + + Rows = null; + + base.Dispose(); + } + + #endregion + } + + #region enums + + #region GroupArea + + /// + /// GroupArea + /// + public enum GroupArea + { + /// + /// Content + /// + Content, + + /// + /// ExpandButton + /// + ExpandButton, + + /// + /// Row Header + /// + RowHeader, + + /// + /// NoWhere + /// + NoWhere, + } + + #endregion + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridGroupBy.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridGroupBy.cs new file mode 100644 index 00000000..f568c13f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridGroupBy.cs @@ -0,0 +1,2430 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.SuperGrid.TextMarkup; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Defines the grid GridGroupBy Row + /// + public class GridGroupByRow : GridTextRow + { + #region Constants + + const int MarkerWidth = 13; + const int MarkerHeight = 7; + + const int MarkerHPad = 10; + const int MarkerVPad = 12; + + const int TextPad = 3; + const int TextHPad = 6; + const int TextVPad = 6; + + const int BoxSpacing = 8; + const int DefaultMinRowHeight = 35; + + #endregion + + #region Private variables + + private bool _Visible; + private bool _UseColumnHeaderColors = true; + private bool _AllowUserSort = true; + private bool _RemoveGroupOnDoubleClick = true; + + private GroupBoxLayout _GroupBoxLayout = GroupBoxLayout.Hierarchical; + private GroupBoxStyle _GroupBoxStyle = GroupBoxStyle.Rectangular; + + private List _GroupBoxes; + private GroupBoxEffects _GroupBoxEffects = GroupBoxEffects.NotSet; + + private bool _Dragging; + private Image _InsertMarker; + + private GridGroupBox _HitGroupBox; + private GridGroupBox _LastHitGroupBox; + private GridGroupBox _MouseDownHitBox; + + private HeaderArea _HitArea; + private HeaderArea _LastHitArea; + private GridColumn _HitColumn; + + private FloatWindow _GroupBoxWindow; + private GridGroupBox _AfterGroupBox; + private Rectangle _InsertRect; + + private FilterPopup _FilterMenu; + private ImageVisibility _FilterImageVisibility = ImageVisibility.NotSet; + + private string _WatermarkText; + + private int _MaxGroupBoxWidth = 200; + private int _CornerRadius = 5; + + #endregion + + #region Constructors + + /// + /// GridHeader + /// + public GridGroupByRow() + : this(null) + { + } + + /// + /// GridHeader + /// + /// + public GridGroupByRow(string text) + : base(text) + { + } + + #endregion + + #region Public properties + + #region AllowUserSort + + /// + /// Gets or sets whether the user can change the group + /// sort direction by clicking on the associated GroupBox + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the user can change the group sort direction by clicking on the associated GroupBox.")] + public bool AllowUserSort + { + get { return (_AllowUserSort); } + + set + { + if (_AllowUserSort != value) + { + _AllowUserSort = value; + + OnPropertyChanged("AllowUserSort"); + } + } + } + + #endregion + + #region CornerRadius + + /// + /// Gets or sets the corner radius to + /// use when GroupBoxStyle is RoundedRectangular + /// + [DefaultValue(5), Category("Behavior")] + [Description("Indicates the corner radius to use when GroupBoxStyle is RoundedRectangular.")] + public int CornerRadius + { + get { return (_CornerRadius); } + + set + { + if (_CornerRadius != value) + { + _CornerRadius = value; + + OnPropertyChangedEx("CornerRadius", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterImageVisibility + + /// + /// Gets or sets the visibility of the header filter image + /// + [DefaultValue(ImageVisibility.NotSet), Category("Appearance")] + [Description("Indicates the visibility of the filter image.")] + public ImageVisibility FilterImageVisibility + { + get { return (_FilterImageVisibility); } + + set + { + if (_FilterImageVisibility != value) + { + _FilterImageVisibility = value; + + OnPropertyChangedEx("FilterImageVisibility", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupBoxEffects + + /// + /// Gets or sets the default for how columns interact with the GroupBox + /// + [DefaultValue(GroupBoxEffects.NotSet), Category("Grouping")] + [Description("Indicates the default for how columns interact with the GroupBox.")] + public GroupBoxEffects GroupBoxEffects + { + get { return (_GroupBoxEffects); } + + set + { + if (_GroupBoxEffects != value) + { + _GroupBoxEffects = value; + + OnPropertyChanged("GroupBoxEffects"); + } + } + } + + #endregion + + #region GroupBoxLayout + + /// + /// Gets or sets the group box layout (Flat, Hierarchical) + /// + [DefaultValue(GroupBoxLayout.Hierarchical), Category("Appearance")] + [Description("Indicates the group box layout (Flat, Hierarchical)")] + public GroupBoxLayout GroupBoxLayout + { + get { return (_GroupBoxLayout); } + + set + { + if (_GroupBoxLayout != value) + { + _GroupBoxLayout = value; + + OnPropertyChangedEx("GroupBoxLayout", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupBoxStyle + + /// + /// Gets or sets the group box Style (Rectangular, RoundedRect) + /// + [DefaultValue(GroupBoxStyle.Rectangular), Category("Appearance")] + [Description("Indicates the group box Style (Rectangular, RoundedRect)")] + public GroupBoxStyle GroupBoxStyle + { + get { return (_GroupBoxStyle); } + + set + { + if (_GroupBoxStyle != value) + { + _GroupBoxStyle = value; + + OnPropertyChangedEx("GroupBoxStyle", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the item is empty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool IsEmpty + { + get { return (false); } + } + + #endregion + + #region MaxGroupBoxWidth + + /// + /// Gets or sets the maximum GroupBox width, in pixels + /// + [DefaultValue(200), Category("Appearance")] + [Description("Indicates the maximum GroupBox width, in pixels.")] + public int MaxGroupBoxWidth + { + get { return (_MaxGroupBoxWidth); } + + set + { + if (_MaxGroupBoxWidth != value) + { + _MaxGroupBoxWidth = value; + + OnPropertyChangedEx("MaxGroupBoxWidth", VisualChangeType.Render); + } + } + } + + #endregion + + #region RemoveGroupOnDoubleClick + + /// + /// Gets or sets whether the grouping column is removed + /// when the user double clicks on the associated GroupBox + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the grouping column is removed when the user double clicks on the associated GroupBox.")] + public bool RemoveGroupOnDoubleClick + { + get { return (_RemoveGroupOnDoubleClick); } + + set + { + if (_RemoveGroupOnDoubleClick != value) + { + _RemoveGroupOnDoubleClick = value; + + OnPropertyChanged("RemoveGroupOnDoubleClick"); + } + } + } + + #endregion + + #region Visible + + /// + /// Visible + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the item is visible")] + public override bool Visible + { + get { return (_Visible); } + + set + { + if (_Visible != value) + { + _Visible = value; + + OnPropertyChangedEx("Visible", VisualChangeType.Layout); + } + } + } + + #endregion + + #region UseColumnHeaderColors + + /// + /// Gets or sets whether Column Header color definitions are used + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether Column Header color definitions are used")] + public bool UseColumnHeaderColors + { + get { return (_UseColumnHeaderColors); } + + set + { + if (_UseColumnHeaderColors != value) + { + _UseColumnHeaderColors = value; + + OnPropertyChangedEx("UseColumnHeaderColors", VisualChangeType.Render); + } + } + } + + #endregion + + #region WatermarkText + + /// + /// Gets or sets the Watermark text to use when no Grouping is active + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Watermark text to use when no Grouping is active")] + public string WatermarkText + { + get { return (_WatermarkText); } + + set + { + if (_WatermarkText != value) + { + _WatermarkText = value; + + OnPropertyChangedEx("WatermarkText", VisualChangeType.Render); + } + } + } + + #region GetWatermarkText + + private string GetWatermarkText() + { + return (_WatermarkText ?? SuperGrid.GroupByWaterMarkText); + } + + #endregion + + #endregion + + #endregion + + #region Private properties + + #region InsertMarker + + private Image InsertMarker + { + get + { + if (_InsertMarker == null) + _InsertMarker = CreateInsertMarker(); + + return (_InsertMarker); + } + + set + { + if (_InsertMarker != null) + _InsertMarker.Dispose(); + + _InsertMarker = value; + } + } + + #region CreateInsertMarker + + private Image CreateInsertMarker() + { + GroupByVisualStyle style = (GroupByVisualStyle)GetEffectiveStyle(); + + Image image = new Bitmap(MarkerWidth, MarkerHeight); + + using (Graphics g = Graphics.FromImage(image)) + { + Point[] pts = + { + new Point(0, 0), + new Point(MarkerWidth - 1, 0), + new Point(MarkerHeight - 1, MarkerHeight - 1), + new Point(0, 0), + }; + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(pts); + + Rectangle r = new Rectangle(0, 0, MarkerWidth, MarkerHeight); + + using (Brush br = style.InsertMarkerBackground.GetBrush(r)) + g.FillPath(br, path); + + using (Pen pen = new Pen(style.InsertMarkerBorderColor)) + g.DrawPath(pen, path); + } + } + + return (image); + } + + #endregion + + #endregion + + #endregion + + #region MeasureRow + + /// + /// MeasureRow + /// + /// + /// + /// + /// + protected override Size MeasureRow( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + Size sizeNeeded = base.MeasureRow(layoutInfo, stateInfo, constraintSize); + + GridPanel panel = stateInfo.GridPanel; + + int height = GetGroupByHeight(panel); + + if (RowHeight == 0) + { + int n = Dpi.Height(DefaultMinRowHeight); + + if (height < n) + height = n; + } + + if (height > sizeNeeded.Height) + sizeNeeded.Height = height; + + return (sizeNeeded); + } + + #region GetGroupByHeight + + private int GetGroupByHeight(GridPanel panel) + { + if (_GroupBoxes == null) + _GroupBoxes = new List(); + else + _GroupBoxes.Clear(); + + GridGroupBox box = new GridGroupBox(this, null); + _GroupBoxes.Add(box); + + int rowHeight = (GroupBoxLayout == GroupBoxLayout.Hierarchical) + ? GetHierarchicalHeight(panel) + : GetFlatHeight(panel); + + rowHeight += Dpi.Height(MarkerVPad * 2); + + TextRowVisualStyle tstyle = GetEffectiveStyle(); + + rowHeight += Dpi.Height(tstyle.BorderThickness.Vertical + + tstyle.Padding.Vertical + tstyle.Margin.Vertical); + + return (rowHeight); + } + + #region GetHierarchicalHeight + + private int GetHierarchicalHeight(GridPanel panel) + { + int rowHeight = 0; + int lastHeight = 0; + + foreach (GridColumn column in panel.GroupColumns) + { + GridGroupBox box = new GridGroupBox(this, column); + + box.GroupBoxStyle = GroupBoxStyle; + box.CornerRadius = CornerRadius; + + _GroupBoxes.Add(box); + + Size size = GetGroupBoxSize(box); + + if (rowHeight == 0) + { + rowHeight = size.Height; + } + else + { + if (size.Height > lastHeight) + rowHeight += (size.Height - lastHeight / 2); + else + rowHeight += (size.Height / 2); + } + + lastHeight = size.Height; + } + + return (rowHeight); + } + + #endregion + + #region GetFlatHeight + + private int GetFlatHeight(GridPanel panel) + { + int rowHeight = 0; + + foreach (GridColumn column in panel.GroupColumns) + { + GridGroupBox box = new GridGroupBox(this, column); + + box.GroupBoxStyle = GroupBoxStyle; + box.CornerRadius = CornerRadius; + + _GroupBoxes.Add(box); + + Size size = GetGroupBoxSize(box); + + if (size.Height > rowHeight) + rowHeight = size.Height; + } + + return (rowHeight); + } + + #endregion + + #region GetGroupBoxSize + + private Size GetGroupBoxSize(GridGroupBox box) + { + Size size = new Size(); + + size.Width = box.Column.HeaderTextSize.Width + Dpi.Width(TextHPad); + size.Height = box.Column.HeaderTextSize.Height + Dpi.Height(TextVPad); + + box.ContentSize = size; + + SuperGrid.DoConfigureGroupBoxEvent(this, box); + + size = box.ContentSize; + + size.Width += Dpi.Width(box.Padding.Horizontal); + size.Height += Dpi.Height(box.Padding.Vertical); + + int n = Dpi.Width(_MaxGroupBoxWidth); + + if (size.Width > n) + size.Width = n; + + size.Width += Dpi.Width(MarkerHPad + TextHPad); + + if (size.Width < Dpi.Width20) + size.Width = Dpi.Width20; + + if (size.Height < Dpi.Height15) + size.Height = Dpi.Height15; + + box.RelativeBounds = new Rectangle(Point.Empty, size); + + return (size); + } + + #endregion + + #endregion + + #endregion + + #region ArrangeRow + + /// + /// ArrangeRow + /// + /// + /// + /// + /// + protected override Size ArrangeRow(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + UpdateGroupBoxes(stateInfo.GridPanel, layoutBounds); + + return (base.ArrangeRow(layoutInfo, stateInfo, layoutBounds)); + } + + #region UpdateGroupBoxes + + private void UpdateGroupBoxes(GridPanel panel, Rectangle r) + { + TextRowVisualStyle tstyle = GetEffectiveStyle(); + + r = GetAdjustedBounds(tstyle, r); + r.Size = Size.Empty; + + if (CanShowRowHeader(panel) == true) + r.X += panel.RowHeaderWidthEx; + + r.X += Dpi.Width(MarkerWidth - MarkerHPad); + r.Y += Dpi.Height(MarkerVPad - MarkerHeight + TextPad); + + GridGroupBox box = _GroupBoxes[0]; + box.RelativeBounds = r; + + int lastHeight = Dpi.Width(MarkerHeight); + int midline = Bounds.Y + Bounds.Height / 2 - 1; + + for (int i = 1; i < _GroupBoxes.Count; i++) + { + box = _GroupBoxes[i]; + + r.X += (r.Width + Dpi.Width(BoxSpacing)); + r.Size = box.RelativeBounds.Size; + + if (GroupBoxLayout == GroupBoxLayout.Hierarchical) + { + r.Y += (r.Height > lastHeight) + ? lastHeight / 2 : lastHeight - r.Height / 2; + } + else + { + r.Y = midline - (r.Height / 2); + } + + UpdateGroupBoxRects(panel, box, ref r); + + lastHeight = r.Height; + } + + _AfterGroupBox = null; + } + + #region UpdateGroupBoxRects + + private void UpdateGroupBoxRects( + GridPanel panel, GridGroupBox box, ref Rectangle r) + { + Rectangle t = r; + + Rectangle ts = GetSortImageBounds(panel, box.Column, t); + Rectangle tf = GetFilterImageBounds(panel, box.Column, t); + + if (ts.Width > 0) + r.Width += (ts.Width + TextPad); + + if (tf.Width > 0) + r.Width += (tf.Width + TextPad); + + r.Width += 3; + + box.RelativeBounds = r; + + if (tf.IsEmpty == false && ts.IsEmpty == false) + { + if (ts.X == tf.X) + { + if (tf.X < r.X + r.Width / 2) + tf.X += ts.Width + TextPad; + else + ts.X += tf.Width + TextPad; + } + else + { + if (tf.X < r.X + r.Width / 2) + ts.X = r.Right - (ts.Width + TextPad); + else + tf.X = r.Right - (tf.Width + TextPad); + } + } + else + { + if (ts.Width > 0 && ts.X > r.X + r.Width / 2) + ts.X = r.Right - (ts.Width + TextPad); + + if (tf.Width > 0 && tf.X > r.X + r.Width / 2) + tf.X = r.Right - (tf.Width + TextPad); + } + + box.FilterImageRelBounds = tf; + box.SortImageRelBounds = ts; + } + + #region GetSortImageBounds + + private Rectangle GetSortImageBounds( + GridPanel panel, GridColumn column, Rectangle r) + { + if (AllowUserSort == true) + { + Image sortImage = panel.ColumnHeader.GetColumnSortImage(panel, column); + + if (sortImage != null) + { + Alignment alignment = (panel.ColumnHeader.SortImageAlignment == Alignment.NotSet) + ? Alignment.MiddleLeft : panel.ColumnHeader.SortImageAlignment; + + return (GetImageBoundsEx(sortImage, alignment, r)); + } + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetFilterImageBounds + + private Rectangle GetFilterImageBounds( + GridPanel panel, GridColumn column, Rectangle r) + { + Image filterImage = null; + + switch (_FilterImageVisibility) + { + case ImageVisibility.Auto: + case ImageVisibility.Always: + if (column.IsFilteringEnabled == true) + filterImage = panel.ColumnHeader.GetFilterImage(column); + break; + + case ImageVisibility.NotSet: + filterImage = panel.ColumnHeader.GetColumnFilterImage(column); + break; + } + + if (filterImage != null) + { + Alignment alignment = panel.ColumnHeader.FilterImageAlignment; + + if (alignment == Alignment.NotSet) + alignment = Alignment.MiddleLeft; + + return (GetImageBoundsEx(filterImage, alignment, r)); + } + + return (Rectangle.Empty); + } + + #endregion + + #region GetImageBoundsEx + + private Rectangle GetImageBoundsEx( + Image image, Alignment alignment, Rectangle r) + { + Rectangle t = r; + t.Size = image.Size; + + t.X += Dpi.Width6; + t.Y += (r.Height - t.Height) / 2; + + switch (alignment) + { + case Alignment.TopLeft: + case Alignment.MiddleLeft: + case Alignment.BottomLeft: + break; + + default: + t.X = r.Right + Dpi.Width3; + break; + } + + return (t); + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region RenderRow + + /// + /// RenderRow + /// + /// + /// + /// + protected override void RenderRow( + GridRenderInfo renderInfo, GridPanel panel, Rectangle r) + { + base.RenderRow(renderInfo, panel, r); + + Graphics g = renderInfo.Graphics; + + if (CanShowRowHeader(panel) == true) + { + r.X += panel.RowHeaderWidthEx; + r.Width -= panel.RowHeaderWidthEx; + } + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + if (_GroupBoxes.Count > 1) + { + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + GridGroupBox lastBox = null; + + foreach (GridGroupBox box in _GroupBoxes) + { + if (box.Column != null) + { + RenderGroupBox(panel, box, lastBox, g, pstyle); + lastBox = box; + } + } + } + else + { + RenderWaterMarkText(panel, g); + } + } + finally + { + g.Clip = oldClip; + } + + if (_InsertRect.IsEmpty == false) + g.DrawImageUnscaled(InsertMarker, _InsertRect); + } + + #region RenderGroupBox + + private void RenderGroupBox(GridPanel panel, + GridGroupBox box, GridGroupBox lastBox, Graphics g, GridPanelVisualStyle pstyle) + { + StyleType type = GetGroupByStyleType(box); + + ColumnHeaderVisualStyle cstyle = panel.ColumnHeader.GetEffectiveStyle(box.Column, type); + GroupByVisualStyle style = GetGroupByEffectiveStyle(box); + + Rectangle r = box.Bounds; + + if (r.Width > 0 && r.Height > 0) + { + if (SuperGrid.DoPreRenderGroupBoxEvent(g, + this, box, RenderParts.Background, r) == false) + { + int radius = GetCornerRadius(box); + + if (radius > 0 && box.GroupBoxStyle == GroupBoxStyle.RoundedRectangular) + RenderRoundedBox(g, style, cstyle, pstyle, lastBox, box, radius); + else + RenderRectBox(g, style, cstyle, pstyle, lastBox, box); + + SuperGrid.DoPostRenderGroupBoxEvent(g, + this, box, RenderParts.Background, r); + } + + Rectangle t = r; + + RenderSortImage(g, panel, box, ref t); + RenderFilterImage(g, panel, box, ref t); + + int n = box.Padding.Left + TextHPad; + + t.X += n; + t.Width -= n; + + if (t.Width - box.ContentSize.Width > 0) + t.Width = box.ContentSize.Width; + + if (SuperGrid.DoPreRenderGroupBoxEvent(g, + this, box, RenderParts.Content, t) == false) + { + Rectangle t2 = t; + + t.Y += box.Padding.Top; + t.Height = box.Column.HeaderTextSize.Height + 6; + + RenderText(g, box.Column, style, cstyle, t); + + SuperGrid.DoPostRenderGroupBoxEvent(g, + this, box, RenderParts.Content, t2); + } + } + } + + #region GetCornerRadius + + internal int GetCornerRadius(GridGroupBox box) + { + int maxRadius = Math.Min( + box.RelativeBounds.Width, box.RelativeBounds.Height) / 2; + + int radius = Math.Min(box.CornerRadius, maxRadius); + + return (radius > 0 ? radius : 0); + } + + #endregion + + #region RenderRoundedBox + + private void RenderRoundedBox(Graphics g, GroupByVisualStyle style, + ColumnHeaderVisualStyle cstyle, GridPanelVisualStyle pstyle, + GridGroupBox leftBox, GridGroupBox box, int radius) + { + Rectangle r = box.Bounds; + + using (GraphicsPath path = GetRoundedPath(r, radius)) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + + if (_UseColumnHeaderColors == true) + { + using (Brush br = cstyle.Background.GetBrush(r)) + g.FillPath(br, path); + + using (Pen pen = new Pen(pstyle.HeaderLineColor)) + g.DrawPath(pen, path); + } + else + { + using (Brush br = style.GroupBoxBackground.GetBrush(r)) + g.FillPath(br, path); + + using (Pen pen = new Pen(style.GroupBoxBorderColor)) + g.DrawPath(pen, path); + } + + if (leftBox != null) + { + Region oldClip = g.Clip; + Region newClip = new Region(Bounds); + + newClip.Exclude(path); + + g.SetClip(newClip, CombineMode.Intersect); + + try + { + if (SuperGrid.DoPreRenderGroupBoxConnectorEvent(g, this, leftBox, box) == false) + { + RenderBoxConnector(g, style, leftBox.Bounds, box.Bounds, true); + + SuperGrid.DoPostRenderGroupBoxConnectorEvent(g, this, leftBox, box); + } + } + finally + { + g.Clip = oldClip; + } + } + + g.SmoothingMode = sm; + } + } + + #region GetRoundedPath + + private GraphicsPath GetRoundedPath(Rectangle r, int radius) + { + int diameter = radius << 1; + + Rectangle t = r; + t.Size = new Size(diameter, diameter); + + GraphicsPath path = new GraphicsPath(); + path.AddArc(t, 180, 90); + + t.X = r.Right - diameter; + path.AddArc(t, 270, 90); + + t.Y = r.Bottom - diameter; + path.AddArc(t, 0, 90); + + t.X = r.X; + path.AddArc(t, 90, 90); + + path.CloseAllFigures(); + + return (path); + } + + #endregion + + #endregion + + #region RenderRectBox + + private void RenderRectBox(Graphics g, GroupByVisualStyle style, + ColumnHeaderVisualStyle cstyle, GridPanelVisualStyle pstyle, + GridGroupBox leftBox, GridGroupBox box) + { + Rectangle r = box.Bounds; + + if (_UseColumnHeaderColors == true) + { + using (Brush br = cstyle.Background.GetBrush(r)) + g.FillRectangle(br, r); + + using (Pen pen = new Pen(pstyle.HeaderLineColor)) + g.DrawRectangle(pen, r); + } + else + { + using (Brush br = style.GroupBoxBackground.GetBrush(r)) + g.FillRectangle(br, r); + + using (Pen pen = new Pen(style.GroupBoxBorderColor)) + g.DrawRectangle(pen, r); + } + + if (leftBox != null) + { + if (SuperGrid.DoPreRenderGroupBoxConnectorEvent(g, this, leftBox, box) == false) + { + RenderBoxConnector(g, style, leftBox.Bounds, r, false); + + SuperGrid.DoPostRenderGroupBoxConnectorEvent(g, this, leftBox, box); + } + } + } + + #endregion + + #region RenderBoxConnector + + private void RenderBoxConnector(Graphics g, + GroupByVisualStyle style, Rectangle l, Rectangle r, bool extend) + { + using (Pen pen = new Pen(style.GroupBoxConnectorColor)) + { + if (GroupBoxLayout == GroupBoxLayout.Hierarchical) + { + Point pt1 = new Point(l.X + l.Width / 2, l.Bottom + 1); + Point pt2 = new Point(pt1.X, l.Bottom + (r.Bottom - l.Bottom) / 2); + Point pt3 = new Point(r.X + (extend ? 10 : -1), pt2.Y); + + g.DrawLines(pen, new Point[] { pt1, pt2, pt3 }); + } + else + { + Point pt1 = new Point(l.Right + 1, l.Y + l.Height / 2 + 1); + Point pt2 = new Point(r.X - 1, pt1.Y); + + g.DrawLine(pen, pt1, pt2); + } + } + } + + #endregion + + #endregion + + #region Render Filter/Sort Image + + #region RenderSortImage + + private void RenderSortImage( + Graphics g, GridPanel panel, GridGroupBox box, ref Rectangle t) + { + GridColumn column = box.Column; + Rectangle bounds = box.SortImageBounds; + + if (bounds.IsEmpty == false) + { + Image sortImage = + panel.ColumnHeader.GetColumnSortImage(panel, column); + + RenderImage(g, sortImage, bounds, ref t); + } + } + + #endregion + + #region RenderFilterImage + + private void RenderFilterImage( + Graphics g, GridPanel panel, GridGroupBox box, ref Rectangle t) + { + GridColumn column = box.Column; + Rectangle bounds = box.FilterImageBounds; + + if (bounds.IsEmpty == false) + { + if (CanShowFilterImage(panel, box) == true) + { + bool inFilter; + StyleState state = GetFilterImageState(box, out inFilter); + + Image filterImage = + panel.ColumnHeader.GetFilterImage(column, state, inFilter); + + RenderImage(g, filterImage, bounds, ref t); + } + } + } + + #region CanShowFilterImage + + private bool CanShowFilterImage(GridPanel panel, GridGroupBox box) + { + switch (_FilterImageVisibility) + { + case ImageVisibility.Auto: + if (box.Column.IsFilteringEnabled == true) + { + if (string.IsNullOrEmpty(box.Column.FilterExpr) == false) + return (true); + + return (_Dragging == false && box.IsEqualTo(_HitGroupBox) == true); + } + break; + + case ImageVisibility.Always: + if (box.Column.IsFilteringEnabled == true) + return (true); + break; + + case ImageVisibility.NotSet: + + switch (panel.ColumnHeader.FilterImageVisibility) + { + case ImageVisibility.Always: + return (true); + + case ImageVisibility.Never: + return (false); + + case ImageVisibility.Auto: + if (string.IsNullOrEmpty(box.Column.FilterExpr) == false) + return (true); + + return (_Dragging == false && box.IsEqualTo(_HitGroupBox) == true); + } + break; + } + + return (false); + } + + #endregion + + #region GetFilterImageState + + private StyleState GetFilterImageState(GridGroupBox box, out bool inFilter) + { + inFilter = false; + + StyleState state = StyleState.Default; + + if (box.IsEqualTo(_HitGroupBox) == true) + { + state = StyleState.MouseOver; + + if (_HitArea == HeaderArea.InFilterMenu) + inFilter = true; + } + + if (string.IsNullOrEmpty(box.Column.FilterExpr) == false) + state |= StyleState.Selected; + + return (state); + } + + #endregion + + #endregion + + #region RenderImage + + private void RenderImage(Graphics g, + Image image, Rectangle r, ref Rectangle t) + { + if (image != null) + { + g.DrawImageUnscaledAndClipped(image, r); + + if (r.X < t.X + t.Width / 2) + { + int n = t.Right - r.Right; + + t.X = r.Right; + t.Width = n; + } + else + { + int n = t.Right - r.Left; + + t.Width -= n; + } + } + } + + #endregion + + #endregion + + #region RenderText + + private void RenderText(Graphics g, GridColumn column, + GroupByVisualStyle style, ColumnHeaderVisualStyle cstyle, Rectangle bounds) + { + string s = column.GetHeaderText(); + + if (s != null) + { + if (column.HeaderTextMarkup != null) + { + RenderTextMarkup(g, column.HeaderTextMarkup, cstyle, bounds); + } + else + { + if (_UseColumnHeaderColors == true) + { + eTextFormat tf = cstyle.GetTextFormatFlags(); + + TextDrawing.DrawString(g, s, + cstyle.Font, cstyle.TextColor, bounds, tf); + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + TextDrawing.DrawString(g, s, + cstyle.Font, style.GroupBoxTextColor, bounds, tf); + } + } + } + } + + #region RenderTextMarkup + + private void RenderTextMarkup(Graphics g, + BodyElement textMarkup, CellVisualStyle style, Rectangle r) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + textMarkup.Arrange(new Rectangle(r.Location, r.Size), d); + + Size size = textMarkup.Bounds.Size; + + switch (style.Alignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + if (r.Height > size.Height) + r.Y += (r.Height - size.Height) / 2; + break; + + default: + if (r.Height > size.Height) + r.Y = r.Bottom - size.Height; + break; + } + + textMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + textMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #endregion + + #region RenderWaterMarkText + + private void RenderWaterMarkText(GridPanel panel, Graphics g) + { + if (AllowSelection == true) + { + string s = GetWatermarkText(); + + if (string.IsNullOrEmpty(s) == false) + { + GroupByVisualStyle style = (GroupByVisualStyle)GetEffectiveStyle(); + Rectangle t = GetAdjustedBounds(style, Bounds); + + if (CanShowRowHeader(panel) == true) + { + t.X += panel.RowHeaderWidthEx; + t.Width -= panel.RowHeaderWidthEx; + } + + TextDrawing.DrawString(g, s, style.WatermarkFont, style.WatermarkTextColor, + t, eTextFormat.VerticalCenter | eTextFormat.Left); + } + } + } + + #endregion + + #endregion + + #region GroupBoxWindowPaint + + void GroupBoxWindowPaint(object sender, PaintEventArgs e) + { + GridPanel panel = GridPanel; + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + RenderGroupBox(panel, + (GridGroupBox)_GroupBoxWindow.Tag, null, e.Graphics, pstyle); + } + + #endregion + + #region Mouse support + + #region InternalMouseLeave + + internal override void InternalMouseLeave(EventArgs e) + { + base.InternalMouseLeave(e); + + if (_LockedColumn == false) + _HitGroupBox = null; + } + + #endregion + + #region InternalMouseMove + + internal override void InternalMouseMove(MouseEventArgs e) + { + base.InternalMouseMove(e); + + SuperGrid.GridCursor = Cursors.Default; + + if (AllowSelection == true) + { + Point pt = e.Location; + + _LastHitArea = _HitArea; + _LastHitGroupBox = _HitGroupBox; + + _HitGroupBox = GetGroupBoxAt(pt); + _HitArea = GetHitArea(pt); + + if (IsMouseDown == true) + { + if (_Dragging == true) + { + DragContinue(pt); + } + else if (_MouseDownHitBox != null) + { + if (Math.Abs(MouseDownPoint.X - pt.X) > 5 || + Math.Abs(MouseDownPoint.Y - pt.Y) > 5) + { + DragStart(_MouseDownHitBox.Column); + } + } + } + else + { + switch (_HitArea) + { + case HeaderArea.InFilterMenu: + SuperGrid.GridCursor = Cursors.Hand; + break; + + default: + SuperGrid.GridCursor = Cursors.Default; + break; + } + } + + if (_HitArea != _LastHitArea || _LastHitGroupBox != _HitGroupBox) + { + if (_LastHitGroupBox != null) + InvalidateRender(_LastHitGroupBox.Bounds); + + if (_HitGroupBox != null) + { + if ((_LastHitGroupBox != _HitGroupBox) || + (_HitArea == HeaderArea.InFilterMenu || _LastHitArea == HeaderArea.InFilterMenu)) + { + InvalidateRender(_HitGroupBox.Bounds); + } + } + } + } + } + + #endregion + + #region InternalMouseDown + + internal override void InternalMouseDown(MouseEventArgs e) + { + base.InternalMouseDown(e); + + if (e.Button == MouseButtons.Left) + { + _MouseDownHitBox = _HitGroupBox; + + if (_MouseDownHitBox != null) + { + Capture = true; + + if (_HitGroupBox.FilterImageRelBounds.Contains(e.Location) == true) + ProcessFilterHit(_MouseDownHitBox); + else + ProcessContentHit(); + + InvalidateRender(_MouseDownHitBox.Bounds); + } + } + } + + #region ProcessContentHit + + private void ProcessContentHit() + { + _Dragging = false; + } + + #endregion + + #region ProcessFilterHit + + private bool _LockedColumn = true; + + private void ProcessFilterHit(GridGroupBox box) + { + if (_FilterMenu != null) + _FilterMenu.Dispose(); + + _LockedColumn = true; + + _FilterMenu = new FilterPopup(GridPanel); + + _FilterMenu.ActivatePopup(box.Column, box.FilterImageRelBounds, ResetState); + } + + #endregion + + #region ResetState + + internal void ResetState() + { + _HitGroupBox = null; + _LockedColumn = false; + } + + #endregion + + #endregion + + #region InternalMouseUp + + internal override void InternalMouseUp(MouseEventArgs e) + { + base.InternalMouseUp(e); + + GridPanel panel = GridPanel; + + if (_GroupBoxWindow != null) + { + GridGroupBox box = (GridGroupBox)_GroupBoxWindow.Tag; + + if (_AfterGroupBox != null) + { + int index = _GroupBoxes.IndexOf(_AfterGroupBox); + + if (box.Column.GroupBoxEffectsEx == GroupBoxEffects.Move) + box.Column.Visible = false; + + panel.InsertGroup(box.Column, index); + } + else if (box.Column.GroupBoxEffectsEx != GroupBoxEffects.None) + { + if (_HitColumn != null) + { + box.Column.Visible = true; + + if (_HitColumn != box.Column) + ReorderColumn(panel, box.Column); + + panel.RemoveGroup(box.Column); + + panel.NeedsSorted = true; + } + } + + DragEnd(); + } + else + { + if (_HitGroupBox != null && _HitGroupBox == _MouseDownHitBox) + { + if (_HitArea == HeaderArea.InContent) + { + if (panel.IsSortable == true && _AllowUserSort == true) + { + if ((Control.ModifierKeys & Keys.Control) != Keys.Control) + { + panel.ColumnHeader.SortColumn(panel, _HitGroupBox.Column); + + SuperGrid.PostInternalMouseMove(); + } + } + } + } + } + + if (_MouseDownHitBox != null) + { + InvalidateRender(_MouseDownHitBox.Bounds); + + _MouseDownHitBox = null; + } + } + + #region ReorderColumn + + private void ReorderColumn(GridPanel panel, GridColumn column) + { + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + + int curIndex = columns.GetDisplayIndex(column); + int sepIndex = columns.GetDisplayIndex(_HitColumn); + + bool isRight = (_InsertRect.X > + _HitColumn.Bounds.X + _HitColumn.Bounds.Width / 2); + + if (curIndex > sepIndex && isRight == true && sepIndex < map.Length - 1) + sepIndex++; + + else if (curIndex < sepIndex && isRight == false && sepIndex > 0) + sepIndex--; + + if (sepIndex != curIndex) + { + if (sepIndex < curIndex) + { + for (int i = curIndex; i > sepIndex; i--) + map[i] = map[i - 1]; + } + else + { + for (int i = curIndex; i < sepIndex; i++) + map[i] = map[i + 1]; + } + + map[sepIndex] = column.ColumnIndex; + + for (int i = 0; i < map.Length; i++) + columns[map[i]].DisplayIndex = i; + + SuperGrid.UpdateStyleCount(); + SuperGrid.PrimaryGrid.InvalidateRender(); + + SuperGrid.DoColumnMovedEvent(panel, column); + } + } + + #endregion + + #endregion + + #region InternalMouseDoubleClick + + internal override void InternalMouseDoubleClick(MouseEventArgs e) + { + base.InternalMouseDoubleClick(e); + + if (_RemoveGroupOnDoubleClick == true) + { + GridGroupBox box = _HitGroupBox; + + if (box != null && box == _MouseDownHitBox) + { + GridPanel panel = GridPanel; + + if (panel.IsSortable == false || _AllowUserSort == false || + (Control.ModifierKeys & Keys.Control) == Keys.Control) + { + panel.RemoveGroup(box.Column); + + panel.NeedsSorted = true; + + box.Column.Visible = true; + } + } + } + } + + #endregion + + #endregion + + #region GetHitArea + + /// + /// GetHitArea + /// + /// + /// + public override HeaderArea GetHitArea(Point pt) + { + if (_HitGroupBox != null) + { + if (_HitGroupBox.FilterImageRelBounds.Contains(pt)) + return (HeaderArea.InFilterMenu); + + return (HeaderArea.InContent); + } + + HeaderArea area = base.GetHitArea(pt); + + if (area != HeaderArea.InContent) + return (area); + + return (HeaderArea.InWhitespace); + } + + #endregion + + #region GetAdjustedBounds + + private Rectangle GetAdjustedBounds(TextRowVisualStyle style, Rectangle r) + { + r.X += (style.BorderThickness.Left + style.Margin.Left + style.Padding.Left); + r.Width -= (style.BorderThickness.Horizontal + style.Margin.Horizontal + style.Padding.Horizontal); + + r.Y += (style.BorderThickness.Top + style.Margin.Top + style.Padding.Top); + r.Height -= (style.BorderThickness.Vertical + style.Margin.Vertical + style.Padding.Vertical); + + return (r); + } + + #endregion + + #region GetScrollBounds + + internal Rectangle GetScrollBounds(Rectangle r) + { + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + r.X -= HScrollOffset; + + return (r); + } + + #endregion + + #region GetGroupBoxAt + + /// + /// Gets the GroupBox containing the given point + /// + /// + ///GroupBox, or null + public GridGroupBox GetGroupBoxAt(Point pt) + { + foreach (GridGroupBox box in _GroupBoxes) + { + if (box.Bounds.Contains(pt) == true) + return (box); + } + + return (null); + } + + #endregion + + #region FindGroupPartition + + private GridGroupBox FindGroupPartition(Point pt) + { + for (int i = _GroupBoxes.Count - 1; i >= 0; i--) + { + GridGroupBox box = _GroupBoxes[i]; + + if (pt.X > box.Bounds.X + box.Bounds.Width / 2) + return (box); + } + + return (_GroupBoxes[0]); + } + + #endregion + + #region Drag support + + #region DragStart + + internal bool DragStart(GridColumn column) + { + GridPanel panel = GridPanel; + + if (panel.VirtualMode == true) + return (false); + + if (AllowSelection == true && panel.ColumnHeader.Visible == true && + column.GroupBoxEffectsEx != GroupBoxEffects.None) + { + Capture = true; + + _Dragging = true; + + _GroupBoxWindow = new FloatWindow(); + _GroupBoxWindow.Opacity = .5; + _GroupBoxWindow.Owner = SuperGrid.FindForm(); + _GroupBoxWindow.Paint += GroupBoxWindowPaint; + + GridGroupBox box = new GridGroupBox(this, column); + + box.GroupBoxStyle = GroupBoxStyle; + box.CornerRadius = CornerRadius; + + Size size = GetGroupBoxSize(box); + Rectangle r = new Rectangle(Point.Empty, size); + + UpdateGroupBoxRects(GridPanel, box, ref r); + + box.RelativeBounds = r; + box.IsDragBox = true; + + _GroupBoxWindow.Size = r.Size; + + int radius = GetCornerRadius(box); + + if (radius > 0 && box.GroupBoxStyle == GroupBoxStyle.RoundedRectangular) + { + using (GraphicsPath path = GetRoundedPath(r, radius)) + { + GraphicsPath cpath = (GraphicsPath)path.Clone(); + + using (Pen pen = new Pen(Color.Black, 2)) + cpath.Widen(pen); + + Region rgn = new Region(path); + rgn.Union(cpath); + + _GroupBoxWindow.Region = rgn; + } + } + + _GroupBoxWindow.Tag = box; + + return (true); + } + + return (false); + } + + #endregion + + #region DragContinue + + private void DragContinue(Point pt) + { + GridGroupBox box = _GroupBoxWindow.Tag as GridGroupBox; + + if (box != null) + { + Point ptStart = pt; + + Size size = box.RelativeBounds.Size; + size.Width++; + size.Height++; + + pt.X -= (size.Width / 2); + pt.Y -= (size.Height / 2); + + pt = SuperGrid.PointToScreen(pt); + + Rectangle r = new Rectangle(pt, size); + + _GroupBoxWindow.Bounds = r; + + if (_GroupBoxWindow.Visible == false) + _GroupBoxWindow.Show(); + + Rectangle t = GetInsertRect(ptStart); + + if (t.Equals(_InsertRect) == false) + { + InvalidateRender(_InsertRect); + + _InsertRect = t; + + InvalidateRender(_InsertRect); + } + } + } + + #region GetInsertRect + + private Rectangle GetInsertRect(Point pt) + { + _HitColumn = null; + _AfterGroupBox = null; + + if (Bounds.Contains(pt) == true) + return (GetGroupBoxInsertRect(pt)); + + return (GetColumnInsertRect(pt)); + } + + #region GetColumnInsertRect + + private Rectangle GetColumnInsertRect(Point pt) + { + GridPanel panel = GridPanel; + + if (panel.Bounds.Contains(pt) == true) + { + if (pt.Y >= Bounds.Bottom && pt.Y < Bounds.Bottom + 50) + { + _HitColumn = GetHitColumn(panel, pt); + + if (_HitColumn == null) + _HitColumn = panel.Columns[0]; + + Rectangle t = Bounds; + Rectangle s = SViewRect; + + if (panel.ShowRowHeaders == true && + RowHeaderVisibility != RowHeaderVisibility.Never) + { + t.X += panel.RowHeaderWidthEx; + } + + t.X += Dpi.Width2; + t.Width = s.Right - t.X - Dpi.Width2; + + Rectangle r = _HitColumn.Bounds; + + if (pt.X > r.X + r.Width / 2) + r.X = r.Right; + + r.X -= (MarkerWidth / 2 + 1); + r.Y = t.Bottom - MarkerHeight - 2; + + r.Width = MarkerWidth; + r.Height = MarkerHeight; + + if (r.X < t.X) + r.X = t.X; + + if (r.X > t.Right - MarkerWidth) + r.X = t.Right - MarkerWidth; + + return (r); + } + } + + return (Rectangle.Empty); + } + + #region GetHitColumn + + private GridColumn GetHitColumn(GridPanel panel, Point pt) + { + if (panel.Bounds.Contains(pt) == true) + { + if (pt.Y >= Bounds.Bottom && pt.Y < Bounds.Bottom + 50) + { + if (panel.FirstVisibleColumn != null && pt.X < panel.FirstVisibleColumn.Bounds.X) + return (panel.FirstVisibleColumn); + + foreach (GridColumn col in panel.Columns) + { + if (col.Visible == true) + { + if (pt.X >= col.Bounds.X && pt.X <= col.Bounds.Right) + return (col); + } + } + + return (panel.LastVisibleColumn); + } + } + + return (null); + } + + #endregion + + #endregion + + #region GetGroupBoxInsertRect + + private Rectangle GetGroupBoxInsertRect(Point pt) + { + Rectangle t = Bounds; + + _AfterGroupBox = FindGroupPartition(pt); + + pt = new Point(_AfterGroupBox.Bounds.Right, _AfterGroupBox.Bounds.Y); + + if (GroupBoxLayout == GroupBoxLayout.Flat) + { + int index = _GroupBoxes.IndexOf(_AfterGroupBox); + + if (index + 1 < _GroupBoxes.Count) + { + GridGroupBox beforeBox = _GroupBoxes[index + 1]; + + if (index == 0 || beforeBox.Bounds.Y < pt.Y) + pt.Y = beforeBox.Bounds.Y; + } + + pt.X -= 2; + pt.Y -= 9; + + if (pt.Y < t.Y + 6) + pt.Y = t.Y + 6; + } + else + { + pt.X += 2; + pt.Y -= 6; + + if (pt.Y < t.Y + 2) + pt.Y = t.Y + 2; + } + + pt.X = Math.Max(pt.X, t.X + 2); + + if (pt.X + MarkerWidth + 2 > ViewRect.Right) + pt.X = ViewRect.Right - MarkerWidth - 2; + + return (new Rectangle(pt.X, pt.Y, MarkerWidth, MarkerHeight)); + } + + #endregion + + #endregion + + #endregion + + #region DragEnd + + private void DragEnd() + { + _Dragging = false; + + if (_GroupBoxWindow != null) + { + _GroupBoxWindow.Close(); + + _GroupBoxWindow = null; + _MouseDownHitBox = null; + + InvalidateRender(_InsertRect); + _InsertRect = Rectangle.Empty; + + SuperGrid.PostInternalMouseMove(); + } + } + + #endregion + + #endregion + + #region CancelCapture + + /// + /// CancelCapture + /// + public override void CancelCapture() + { + if (CapturedItem == this) + { + Capture = false; + + DragEnd(); + } + } + + #endregion + + #region Style support + + #region GetNewVisualStyle + + /// + /// GetNewVisualStyle + /// + /// + protected override TextRowVisualStyle GetNewVisualStyle() + { + return (new GroupByVisualStyle()); + } + + #endregion + + #region ApplyStyleEx + + /// + /// ApplyStyleEx + /// + /// + /// + protected override void ApplyStyleEx(TextRowVisualStyle style, StyleType[] css) + { + GroupByVisualStyle gstyle = style as GroupByVisualStyle; + + if (gstyle != null) + { + foreach (StyleType cs in css) + { + gstyle.ApplyStyle(SuperGrid.BaseVisualStyles.GroupByStyles[cs]); + gstyle.ApplyStyle(SuperGrid.DefaultVisualStyles.GroupByStyles[cs]); + gstyle.ApplyStyle(GridPanel.DefaultVisualStyles.GroupByStyles[cs]); + } + + if (gstyle.GroupBoxBorderColor == Color.Empty) + gstyle.GroupBoxBorderColor = Color.Blue; + + if (gstyle.WatermarkTextColor == Color.Empty) + gstyle.WatermarkTextColor = Color.Gray; + + if (gstyle.WatermarkFont == null) + gstyle.WatermarkFont = SystemFonts.DefaultFont; + } + + InsertMarker = null; + } + + #endregion + + #region GetGroupByEffectiveStyle + + private GroupByVisualStyle GetGroupByEffectiveStyle(GridGroupBox box) + { + return ((GroupByVisualStyle) + GetEffectiveStyle(GetGroupByStyleType(box))); + } + + #endregion + + #region GetGroupByStyleType + + private StyleType GetGroupByStyleType(GridGroupBox box) + { + if (IsMouseDown == true) + { + Point pt = Control.MousePosition; + pt = SuperGrid.PointToClient(pt); + + if (box.FilterImageBounds.Contains(pt) == false) + { + if (box.IsDragBox == true || box.IsEqualTo(_MouseDownHitBox)) + { + if (box.IsEqualTo(_HitGroupBox) == true) + return (StyleType.SelectedMouseOver); + + return (StyleType.Selected); + } + + return (StyleType.Default); + } + } + + if (box.IsEqualTo(_HitGroupBox) == true) + return (StyleType.MouseOver); + + return (StyleType.Default); + } + + #endregion + + #endregion + } + + #region GridGroupBox + + /// + /// GroupBox definition + /// + public class GridGroupBox + { + #region Private properties + + private GridGroupByRow _GridGroupBy; + private GridColumn _Column; + + private Rectangle _RelativeBounds; + private Rectangle _SortImageRelBounds; + private Rectangle _FilterImageRelBounds; + + private Padding _Padding = new Padding(0); + private GroupBoxStyle _GroupBoxStyle = GroupBoxStyle.Rectangular; + + private bool _IsDragBox; + + private Size _ContentSize; + private int _CornerRadius; + + #endregion + + #region Public properties + + #region Bounds + + /// + /// Gets the associated Bounds + /// + public Rectangle Bounds + { + get + { + if (_IsDragBox == true) + return (_RelativeBounds); + + return (_GridGroupBy.GetScrollBounds(_RelativeBounds)); + } + } + + #endregion + + #region Column + + /// + /// Gets the associated GridColumn + /// + public GridColumn Column + { + get { return (_Column); } + internal set { _Column = value; } + } + + #endregion + + #region ContentSize + + /// + /// Gets the associated Content Size + /// + public Size ContentSize + { + get { return (_ContentSize); } + set { _ContentSize = value; } + } + + #endregion + + #region CornerRadius + + /// + /// Gets or sets the corner radius to + /// use when GroupBoxStyle is RoundedRectangular + /// + public int CornerRadius + { + get { return (_CornerRadius); } + set { _CornerRadius = value; } + } + + #endregion + + #region GridGroupBy + + /// + /// Gets the associated GridGroupBy object + /// + public GridGroupByRow GridGroupBy + { + get { return (_GridGroupBy); } + internal set { _GridGroupBy = value; } + } + + #endregion + + #region GroupBoxStyle + + /// + /// GroupBox Style + /// + public GroupBoxStyle GroupBoxStyle + { + get { return (_GroupBoxStyle); } + set { _GroupBoxStyle = value; } + } + + #endregion + + #region Padding + + /// + /// Content padding + /// + public Padding Padding + { + get { return (_Padding); } + set { _Padding = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region FilterImageBounds + + internal Rectangle FilterImageBounds + { + get + { + if (_IsDragBox == true || _FilterImageRelBounds.IsEmpty) + return (_FilterImageRelBounds); + + return (_GridGroupBy.GetScrollBounds(_FilterImageRelBounds)); + } + } + + #endregion + + #region FilterImageRelBounds + + internal Rectangle FilterImageRelBounds + { + get { return (_FilterImageRelBounds); } + set { _FilterImageRelBounds = value; } + } + + #endregion + + #region IsDragBox + + internal bool IsDragBox + { + get { return (_IsDragBox); } + set { _IsDragBox = value; } + } + + #endregion + + #region RelativeBounds + + internal Rectangle RelativeBounds + { + get { return (_RelativeBounds); } + set { _RelativeBounds = value; } + } + + #endregion + + #region SortImageBounds + + internal Rectangle SortImageBounds + { + get + { + if (_IsDragBox == true || _SortImageRelBounds.IsEmpty) + return (_SortImageRelBounds); + + return (_GridGroupBy.GetScrollBounds(_SortImageRelBounds)); + } + } + + #endregion + + #region SortImageRelBounds + + internal Rectangle SortImageRelBounds + { + get { return (_SortImageRelBounds); } + set { _SortImageRelBounds = value; } + } + + #endregion + + #endregion + + internal GridGroupBox(GridGroupByRow groupBy, GridColumn column) + { + _GridGroupBy = groupBy; + _Column = column; + + _GroupBoxStyle = groupBy.GroupBoxStyle; + } + + #region IsEqualTo + + internal bool IsEqualTo(GridGroupBox box) + { + return (box != null && box.Column == Column); + } + + #endregion + } + + #endregion + + #region enums + + #region GroupBoxEffects + + /// + /// GroupBoxEffects + /// + public enum GroupBoxEffects + { + /// + /// Not set. + /// + NotSet = -1, + + /// + /// The Column will not interact with the GroupBox. + /// + None, + + /// + /// The Column presentation will be copied to and + /// from the grid and associated GroupBox. + /// + Copy, + + /// + /// The Column presentation will be moved to and + /// from the grid and associated GroupBox. + /// + Move, + } + + #endregion + + #region GroupBoxLayout + + /// + /// GroupBox Layout + /// + public enum GroupBoxLayout + { + /// + /// Group boxes are Flat, all on the same layout row + /// + Flat, + + /// + /// Group boxes are oriented Hierarchically + /// + Hierarchical, + } + + #endregion + + #region GroupBoxStyle + + /// + /// GroupBox Style + /// + public enum GroupBoxStyle + { + /// + /// Group boxes are drawn Rectangular + /// + Rectangular, + + /// + /// Group boxes are drawn Rounded Rectangular + /// + RoundedRectangular, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridHeader.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridHeader.cs new file mode 100644 index 00000000..cc978fa2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridHeader.cs @@ -0,0 +1,50 @@ +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Defines the grid header + /// + public class GridHeader : GridTextRow + { + #region Constructors + + /// + /// GridHeader + /// + public GridHeader() + : this(null) + { + } + + /// + /// GridHeader + /// + /// + public GridHeader(string text) + : base(text) + { + } + + #endregion + + #region Style support + + /// + /// ApplyStyleEx + /// + /// + /// + protected override void ApplyStyleEx(TextRowVisualStyle style, StyleType[] css) + { + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.HeaderStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.HeaderStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.HeaderStyles[cs]); + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridItemsCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridItemsCollection.cs new file mode 100644 index 00000000..f84c6103 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridItemsCollection.cs @@ -0,0 +1,85 @@ +using System.ComponentModel; +using System.Drawing.Design; +using DevComponents.DotNetBar.SuperGrid.Primitives; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Represents the collection of grid items. + /// + [Editor("DevComponents.SuperGrid.Design.GridRowCollectionEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public class GridItemsCollection : CustomCollection + { + #region ClearItems + + /// + /// ClearItems + /// + protected override void ClearItems() + { + int n = Items.Count; + + for (int i = 0; i < n; i++) + { + GridContainer item = Items[i] as GridContainer; + + if (item != null) + { + GridContainer parent = item.Parent as GridContainer; + + if (parent != null) + parent.MergeScan = null; + + break; + } + } + + + if (FloatLastItem == true) + n--; + + for (int i = 0; i < n; i++) + DetachItem(Items[i] as GridContainer, true); + + base.ClearItems(); + } + + #endregion + + #region RemoveItem + + /// + /// RemoveItem + /// + /// + protected override void RemoveItem(int index) + { + DetachItem(Items[index] as GridContainer, false); + + base.RemoveItem(index); + } + + #endregion + + #region DetachItem + + private void DetachItem(GridContainer item, bool clear) + { + if (item != null) + { + item.DetachNestedRows(false); + + if (clear == false) + item.Parent = null; + + GridPanel panel = item as GridPanel; + + if (panel != null) + panel.DataBinder.Clear(); + + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridLayoutInfo.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridLayoutInfo.cs new file mode 100644 index 00000000..fa17a4bc --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridLayoutInfo.cs @@ -0,0 +1,77 @@ +using System.Drawing; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Provides the layout information for grid layout pass + /// + public class GridLayoutInfo + { + #region Public variables + + /// + /// Gets or sets the Graphics object of the control. + /// + public Graphics Graphics; + + /// + /// Gets or sets whether right-to-left layout is in effect. + /// + public bool RightToLeft; + + /// + /// Gets the client bounds for the layout i.e. client bounds of SuperGridControl. + /// + public Rectangle ClientBounds; + + /// + /// Gets the default visual styles for grid elements. + /// + public DefaultVisualStyles DefaultVisualStyles; + + #endregion + + /// + /// Initializes a new instance of the GridLayoutInfo class. + /// + /// + /// + public GridLayoutInfo(Graphics graphics, Rectangle clientBounds) + { + Graphics = graphics; + ClientBounds = clientBounds; + } + } + + /// + /// Provides the layout state information for grid layout pass + /// + public class GridLayoutStateInfo + { + #region Public variables + + /// + /// Gets or sets the layout GridPanel + /// + public GridPanel GridPanel; + + /// + /// Gets or sets the IndentLevel + /// + public int IndentLevel; + + #endregion + + internal int PassCount; + + /// + /// Initializes a new instance of the GridLayoutStateInfo class + /// + public GridLayoutStateInfo(GridPanel gridPanel, int indentLevel) + { + GridPanel = gridPanel; + IndentLevel = indentLevel; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridMerge/CellRange.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridMerge/CellRange.cs new file mode 100644 index 00000000..75fbabe8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridMerge/CellRange.cs @@ -0,0 +1,858 @@ +using System; +using System.Drawing; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Defines a merged cell range, comprised + /// of a starting and ending row,column index pair. + /// + public class CellRange : DisplayRange + { + #region Private variables + + private Cs _States; + private CellRangeData _CellRangeData; + private object _Tag; + private string _ToolTip; + private ushort _StyleUpdateCount; + + #endregion + + #region Constructors + + /// + /// Defines a merged cell range, comprised + /// of a starting and ending row,column index pair. + /// + public CellRange() + { + AllowSuspend = true; + AllowSelection = true; + } + + /// + /// Defines a merged cell range, comprised + /// of a starting and ending row,column index pair. + /// + ///Initial start and end row index + ///Initial start and end column index + public CellRange(int rowIndex, int columnIndex) + : this() + { + RowStart = rowIndex; + ColumnStart = columnIndex; + + RowCount = 1; + ColumnCount = 1; + } + + /// + /// Defines a merged cell range, comprised + /// of a starting and ending row,column index pair. + /// + ///Starting row index + ///Starting column index + ///Row count + ///Column count + public CellRange(int startRowIndex, int startColumnIndex, int rowCount, int columnCount) + : this() + { + RowStart = startRowIndex; + ColumnStart = startColumnIndex; + + RowCount = rowCount; + ColumnCount = columnCount; + } + + #endregion + + #region Public properties + + #region AllowSelection + + /// + /// Gets or sets whether the range can be selected + /// + public bool AllowSelection + { + get { return (TestState(Cs.AllowSelection)); } + set { SetState(Cs.AllowSelection, value); } + } + + #endregion + + #region AllowSuspend + + /// + /// Gets or sets whether the merged cell range can be temporarily + /// suspended when either the user double clicks the displayed range + /// or the application initiates a cell.SuspendMerge(). + /// + public bool AllowSuspend + { + get { return (TestState(Cs.AllowSuspend)); } + set { SetState(Cs.AllowSuspend, value); } + } + + #endregion + + #region AlwaysDisplayFormattedValue + + /// + /// Gets or sets whether the 'FormattedValue' value will be + /// displayed for all cell types when merged, or only for Modal Cells. + /// + public bool AlwaysDisplayFormattedValue + { + get { return (TestState(Cs.AlwaysDisplayFormattedValue)); } + set { SetState(Cs.AlwaysDisplayFormattedValue, value); } + } + + #endregion + + #region BackBounds + + /// + /// Gets the range display bounds + /// + public Rectangle BackBounds + { + get { return (RangeData.BackBounds); } + internal set { RangeData.BackBounds = value; } + } + + #endregion + + #region CellStyles + + /// + /// Gets or sets the visual styles assigned to the cell + /// + public CellVisualStyles CellStyles + { + get + { + if (RangeData.CellStyles == null) + RangeData.CellStyles = new CellVisualStyles(); + + return (RangeData.CellStyles); + } + + set { RangeData.CellStyles = value; } + } + + #endregion + + #region FormattedValue + + /// + /// Gets or sets the formatted value for the range display. This value will + /// be displayed by default for all Modal Cells - all other cells will + /// have their default cell rendering displayed when merged + /// (unless 'AlwaysDisplayFormattedValue' is set to true). + /// + public string FormattedValue + { + get { return (RangeData.FormattedValue); } + set { RangeData.FormattedValue = value; } + } + + #endregion + + #region Tag + + /// + /// Gets or sets user-defined data associated with the object + /// + public object Tag + { + get { return (_Tag); } + set { _Tag = value; } + } + + #endregion + + #region ToolTip + + /// + /// Gets or sets the ToolTip text for the cell range. + /// + public string ToolTip + { + get { return (_ToolTip); } + set { _ToolTip = value; } + } + + #endregion + + #endregion + + #region Internal properties + + #region Modified + + internal bool Modified + { + get { return (TestState(Cs.Modified)); } + set { SetState(Cs.Modified, value); } + } + + #endregion + + #region RenderCount + + internal int RenderCount + { + get { return (RangeData.RenderCount); } + set { RangeData.RenderCount = value; } + } + + #endregion + + #region SelectionUpdateCount + + internal int SelectionUpdateCount + { + get { return (RangeData.SelectionUpdateCount); } + set { RangeData.SelectionUpdateCount = value; } + } + + #endregion + + #region Suspended + + internal bool Suspended + { + get { return (TestState(Cs.Suspended)); } + set { SetState(Cs.Suspended, value); } + } + + #endregion + + #endregion + + #region Private properties + + #region EffectiveStyles + + /// + /// Gets or sets the 'effective' visual styles assigned to the range + /// + private CellVisualStyles EffectiveStyles + { + get { return (RangeData.EffectiveStyles); } + set { RangeData.EffectiveStyles = value; } + } + + #endregion + + #region RangeData + + private CellRangeData RangeData + { + get + { + if (_CellRangeData == null) + _CellRangeData = new CellRangeData(); + + return (_CellRangeData); + } + } + + #endregion + + #endregion + + #region TestState + + private bool TestState(Cs state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(Cs state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #region GetEffectiveStyle + + internal CellVisualStyle GetEffectiveStyle(GridContainer cont, StyleState cellState) + { + switch (cellState) + { + case StyleState.MouseOver: + return (GetStyle(cont, StyleType.MouseOver)); + + case StyleState.Selected: + return (GetStyle(cont, StyleType.Selected)); + + case StyleState.Selected | StyleState.MouseOver: + return (GetStyle(cont, StyleType.SelectedMouseOver)); + + case StyleState.ReadOnly: + return (GetStyle(cont, StyleType.ReadOnly)); + + case StyleState.ReadOnly | StyleState.MouseOver: + return (GetStyle(cont, StyleType.ReadOnlyMouseOver)); + + case StyleState.ReadOnly | StyleState.Selected: + return (GetStyle(cont, StyleType.ReadOnlySelected)); + + case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: + return (GetStyle(cont, StyleType.ReadOnlySelectedMouseOver)); + + default: + return (GetStyle(cont, StyleType.Default)); + } + } + + #region GetStyle + + private CellVisualStyle GetStyle(GridContainer cont, StyleType e) + { + GridPanel panel = cont.GridPanel; + + ValidateStyle(panel); + + CellVisualStyles cvs = EffectiveStyles ?? new CellVisualStyles(); + + if (cvs.IsValid(e) == false) + { + CellVisualStyle style = new CellVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + { + int cindex = panel.Columns.DisplayIndexMap[ColumnStart]; + + GridRow row = null; + GridColumn column = panel.Columns.ColumnAtDisplayIndex(ColumnStart); + + if (RowCount == 1) + { + GridCell cell = cont.GetCell(RowStart, cindex); + + if (cell != null) + row = cell.GridRow; + } + + foreach (StyleType cs in css) + { + if (column != null) + column.ApplyCellStyle(style, cs); + + if (row != null) + row.ApplyCellStyle(style, cs); + + panel.ApplyMergedCellStyle(style, cs); + + if (RangeData.CellStyles != null) + style.ApplyStyle(RangeData.CellStyles[cs]); + } + } + + panel.SuperGrid.DoGetMergedCellStyleEvent(panel, this, e, ref style); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + if (style.Font == null) + style.Font = SystemFonts.DefaultFont; + + cvs[e] = style; + } + + EffectiveStyles = cvs; + + return (EffectiveStyles[e]); + } + + #endregion + + #region ValidateStyle + + private void ValidateStyle(GridPanel panel) + { + if (_StyleUpdateCount != panel.SuperGrid.StyleUpdateCount) + ClearEffectiveStyles(); + + _StyleUpdateCount = panel.SuperGrid.StyleUpdateCount; + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidates the cached Style + ///definition for all defined StyleTypes + /// + public void InvalidateStyle() + { + ClearEffectiveStyles(); + } + + /// + ///Invalidate the cached Style + ///definition for the given StyleType + /// + /// + public void InvalidateStyle(StyleType type) + { + if (EffectiveStyles != null) + EffectiveStyles[type] = null; + } + + #endregion + + #region ClearEffectiveStyles + + internal void ClearEffectiveStyles() + { + if (EffectiveStyles != null) + { + EffectiveStyles.Dispose(); + EffectiveStyles = null; + } + } + + #endregion + + #endregion + + #region IsSelected + + internal bool IsSelected(GridPanel panel, GridContainer cont) + { + if (AllowSelection == true) + { + if (panel.AllowSelection == true) + { + if (RangeData.SelectionUpdateCount != panel.SelectionUpdateCount) + { + RangeData.SelectionUpdateCount = panel.SelectionUpdateCount; + + SetState(Cs.Selected, IsMergeSelected(panel, cont)); + } + + return (TestState(Cs.Selected)); + } + } + + return (false); + } + + #region IsMergeSelected + + private bool IsMergeSelected(GridPanel panel, GridContainer cont) + { + int rowCount = GetRowCount(panel, cont); + + if (RowIsSelected(panel, cont, rowCount)) + return (true); + + if (ColumnIsSelected(panel)) + return (true); + + return (CellIsSelected(panel, cont, rowCount)); + } + + #region RowIsSelected + + private bool RowIsSelected(GridPanel panel, GridContainer cont, int rowCount) + { + for (int i = RowStart; i < RowEnd; i++) + { + if (i < rowCount) + { + GridContainer row = GetRow(panel, cont, i); + + if (row != null) + { + if (row.IsSelected == true) + return (true); + } + } + } + + return (false); + } + + #endregion + + #region ColumnIsSelected + + private bool ColumnIsSelected(GridPanel panel) + { + int[] map = panel.Columns.DisplayIndexMap; + + for (int i = ColumnStart; i < ColumnEnd; i++) + { + if (i < panel.Columns.Count) + { + if (panel.Columns[map[i]].IsSelected == true) + return (true); + } + } + + return (false); + } + + #endregion + + #region CellIsSelected + + private bool CellIsSelected(GridPanel panel, GridContainer cont, int rowCount) + { + int[] map = panel.Columns.DisplayIndexMap; + + for (int i = RowStart; i < RowEnd; i++) + { + if (i < rowCount) + { + GridRow row = GetRow(panel, cont, i) as GridRow; + + if (row != null) + { + for (int j = ColumnStart; j < ColumnEnd; j++) + { + if (j < panel.Columns.Count) + { + GridCell cell = row.GetCell(map[j]); + + if (cell != null) + { + if (panel.IsItemSelectedEx(cell) == true) + return (true); + } + } + } + } + } + } + + return (false); + } + + #endregion + + #region GetRowCount + + private int GetRowCount(GridPanel panel, GridContainer cont) + { + if (panel.VirtualMode == true) + return (panel.VirtualRowCount); + + return (cont.Rows.Count); + } + + #endregion + + #region GetRow + + private GridContainer GetRow(GridPanel panel, GridContainer cont, int index) + { + return (panel.VirtualMode == true) + ? panel.VirtualRows[index] + : cont.Rows[index] as GridContainer; + } + + #endregion + + #endregion + + #endregion + + #region CellStates + + [Flags] + private enum Cs + { + AllowSelection = (1 << 0), + AllowSuspend = (1 << 1), + AlwaysDisplayFormattedValue = (1 << 2), + Modified = (1 << 3), + Selected = (1 << 4), + Suspended = (1 << 5), + } + + #endregion + + #region CellRangeData + + private class CellRangeData + { + #region Private data + + private int _RenderCount; + private int _SelectionUpdateCount; + + private Rectangle _BackBounds; + + private string _FormattedValue; + + private CellVisualStyles _CellStyles; + private CellVisualStyles _EffectiveStyles; + + #endregion + + #region public properties + + #region BackBounds + + public Rectangle BackBounds + { + get { return (_BackBounds); } + set { _BackBounds = value; } + } + + #endregion + + #region CellStyles + + public CellVisualStyles CellStyles + { + get { return (_CellStyles); } + set { _CellStyles = value; } + } + + #endregion + + #region EffectiveStyles + + public CellVisualStyles EffectiveStyles + { + get { return (_EffectiveStyles); } + set { _EffectiveStyles = value; } + } + + #endregion + + #region FormattedValue + + public string FormattedValue + { + get { return (_FormattedValue); } + set { _FormattedValue = value; } + } + + #endregion + + #region RenderCount + + public int RenderCount + { + get { return (_RenderCount); } + set { _RenderCount = value; } + } + + #endregion + + #region SelectionUpdateCount + + public int SelectionUpdateCount + { + get { return (_SelectionUpdateCount); } + set { _SelectionUpdateCount = value; } + } + + #endregion + + #endregion + } + + #endregion + } + + #region DisplayRange + + /// + ///Row/Column display index range + /// + public class DisplayRange + { + #region Private variables + + private int _RowStart; + private int _RowCount; + + private int _ColumnStart; + private int _ColumnCount; + + #endregion + + #region Public properties + + #region ColumnCount + + /// + ///Number of columns + /// + public int ColumnCount + { + get { return (_ColumnCount); } + + set + { + if (value < 0) + throw new ArgumentException(@"ColumnCount cannot be negative", "value"); + + _ColumnCount = value; + } + } + + #endregion + + #region ColumnEnd + + /// + ///Ending column display index (exclusive) + /// + public int ColumnEnd + { + get { return (_ColumnStart + _ColumnCount); } + + set + { + int count = value - _ColumnStart; + + if (count < 0) + throw new ArgumentException(@"ColumnEnd cannot be less than ColumnStart", "value"); + + ColumnCount = count; + } + } + + #endregion + + #region ColumnStart + + /// + ///Starting column display index + /// + public int ColumnStart + { + get { return (_ColumnStart); } + set { _ColumnStart = value; } + } + + #endregion + + #region Contains + + internal bool Contains(int rowIndex, int columnIndex) + { + return ((rowIndex >= _RowStart && rowIndex < RowEnd) && + (columnIndex >= _ColumnStart && columnIndex < ColumnEnd)); + } + + #endregion + + #region RowCount + + /// + ///Number of rows + /// + public int RowCount + { + get { return (_RowCount); } + + set + { + if (value < 0) + throw new ArgumentException(@"RowCount cannot be negative", "value"); + + _RowCount = value; + } + } + + #endregion + + #region RowEnd + + /// + ///Ending row index (exclusive) + /// + public int RowEnd + { + get { return (_RowStart + _RowCount); } + + set + { + int count = value - _RowStart; + + if (count < 0) + throw new ArgumentException(@"RowEnd cannot be less than RowStart", "value"); + + RowCount = count; + } + } + + #endregion + + #region RowStart + + /// + ///Starting row index + /// + public int RowStart + { + get { return (_RowStart); } + set { _RowStart = value; } + } + + #endregion + + #endregion + + #region IsRangeEqualTo + + /// + ///Returns whether the display range is + ///logically equal to the given item's display range. + /// + /// + /// + public bool IsRangeEqualTo(DisplayRange dr) + { + if (dr != null) + { + return (dr.RowStart == _RowStart && dr.ColumnStart == _ColumnStart && + dr.RowCount == _RowCount && dr.ColumnCount == _ColumnCount); + } + + return (false); + } + + #endregion + + #region ToString + + /// + /// ToString + /// + /// + public override string ToString() + { + return ("RowStart = " + RowStart + ", RowEnd = " + RowEnd + + " ColStart = " + ColumnStart + " ColEnd = " + ColumnEnd); + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridMerge/MergeScan.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridMerge/MergeScan.cs new file mode 100644 index 00000000..43174ec5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridMerge/MergeScan.cs @@ -0,0 +1,1041 @@ +using System.Collections.Generic; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid +{ + internal class MergeScan + { + #region Private variables + + private GridContainer _GridContainer; + private GridPanel _GridPanel; + + private List _ScanItems; + private List _LastDrs; + + #endregion + + #region Public properties + + #region ScanItems + + /// + /// ScanItems + /// + public List ScanItems + { + get { return (GetScanItems()); } + } + + #endregion + + #endregion + + /// + /// MergeScan + /// + /// + public MergeScan(GridContainer gridContainer) + { + _GridContainer = gridContainer; + _GridPanel = _GridContainer.GridPanel; + } + + #region GetScanItems + + internal List GetScanItems() + { + if (_GridContainer != null && _GridPanel != null) + { + int rowCount = GetRowCount(); + + if (rowCount > 0) + { + SuperGridControl sg = _GridPanel.SuperGrid; + + if (sg.NeedMergeLayout == true) + _GridContainer.NeedMergeLayout = true; + + if (_GridContainer.NeedMergeLayout == true || + _GridContainer.DisplayedMergeLayoutCount != sg.DisplayedMergeLayoutCount) + { + _ScanItems = GetDisplayedScanItems(); + + _GridContainer.NeedMergeLayout = false; + _GridContainer.DisplayedMergeLayoutCount = sg.DisplayedMergeLayoutCount; + + sg.PostInternalMouseMove(); + sg.DeactivateNonModalEditor(); + } + + return (_ScanItems); + } + } + + return (null); + } + + #region GetRowCount + + private int GetRowCount() + { + if (_GridPanel.VirtualMode == true) + return (_GridPanel.VirtualRowCount); + + return (_GridContainer.Rows.Count); + } + + #endregion + + #region GetDisplayedScanItems + + private List GetDisplayedScanItems() + { + List drs = GetDisplayRanges(); + + if (drs != null) + { + _GridPanel.SuperGrid.DoGetDisplayRangesEvent(_GridContainer, ref drs); + + if (drs != null && drs.Count > 0) + return (GetCellRanges(drs)); + } + + return (null); + } + + #region GetDisplayRanges + + private List GetDisplayRanges() + { + GridPanel panel = _GridContainer as GridPanel; + + int frCount = 0; + int fcCount = 0; + + if (panel != null) + { + frCount = panel.FrozenRowCount; + + GridColumn lastColumn = panel.Columns.GetLastVisibleFrozenColumn(); + + if (lastColumn != null) + fcCount = panel.Columns.GetDisplayIndex(lastColumn) + 1; + } + + DisplayRange dr = new DisplayRange(); + + if (GetRowRange(dr) > 1 | GetColumnRange(dr) > 1) + { + List drs; + + if (frCount == 0 && fcCount == 0) + { + drs = new List(); + drs.Add(dr); + } + else if (frCount != 0 && fcCount != 0) + { + drs = new List(4); + + drs.Add(GetNewRange(dr, 0, frCount, 0, fcCount)); + drs.Add(GetNewRange(dr, 0, frCount, fcCount, dr.ColumnCount)); + drs.Add(GetNewRange(dr, frCount, dr.RowCount, 0, fcCount)); + drs.Add(GetNewRange(dr, frCount, dr.RowEnd, fcCount, dr.ColumnCount)); + } + else + { + drs = new List(2); + + if (frCount != 0) + { + int n = (dr.RowStart < frCount ? frCount : dr.RowStart); + + drs.Add(GetNewRange(dr, 0, frCount, dr.ColumnStart, dr.ColumnCount)); + drs.Add(GetNewRange(dr, n, dr.RowCount, dr.ColumnStart, dr.ColumnCount)); + } + else + { + int n = (dr.ColumnStart < fcCount ? fcCount : dr.ColumnStart); + + drs.Add(GetNewRange(dr, dr.RowStart, dr.RowCount, 0, fcCount)); + drs.Add(GetNewRange(dr, dr.RowStart, dr.RowCount, n, dr.ColumnCount)); + } + } + + return (drs); + } + + return (null); + } + + #region GetRowRange + + private int GetRowRange(DisplayRange dr) + { + int rowCount = GetRowCount(); + + if (rowCount < 50) + { + dr.RowStart = 0; + dr.RowEnd = rowCount; + } + else + { + Rectangle t = _GridContainer.SuperGrid.ViewRect; + + dr.RowEnd = _GridContainer.FirstOnScreenRowIndex; + dr.RowStart = GetPreviousRowIndex(dr.RowEnd); + + bool fpass = false; + + for (int i = dr.RowStart; i < rowCount; i++) + { + GridContainer item = GetRow(i); + + if (item != null && item.Visible == true) + { + Rectangle r = item.BoundsRelative; + + if (item.IsVFrozen == false) + r.Y -= _GridContainer.VScrollOffset; + + if (r.Y > t.Bottom) + { + if (fpass == true) + break; + + fpass = true; + } + } + + dr.RowEnd = i; + } + + dr.RowEnd = GetNextRowIndex(dr.RowEnd) + 1; + } + + return (dr.RowCount); + } + + #region GetPreviousRowIndex + + private int GetPreviousRowIndex(int index) + { + if ((uint)index < GetRowCount()) + { + for (int i = index - 1; i >= 0; i--) + { + GridContainer row = GetRow(i); + + if (row != null && row.Visible == true) + return (i); + } + } + + return (index); + } + + #endregion + + #region GetNextRowIndex + + private int GetNextRowIndex(int index) + { + int rowCount = GetRowCount(); + + if ((uint)index < rowCount) + { + for (int i = index + 1; i < rowCount; i++) + { + GridContainer row = GetRow(i); + + if (row != null && row.Visible == true) + return (i); + } + } + + return (index); + } + + #endregion + + #endregion + + #region GetColumnRange + + private int GetColumnRange(DisplayRange dr) + { + GridColumnCollection columns = _GridPanel.Columns; + int colCount = columns.Count; + + dr.ColumnStart = 0; + dr.ColumnCount = colCount; + + if (colCount > 10) + { + int[] map = columns.DisplayIndexMap; + + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + GridColumn column = columns[index]; + + if (column.Visible == true) + { + if (column.IsOnScreen == true && column.IsHFrozen == false) + break; + + dr.ColumnStart = i; + } + } + + dr.ColumnEnd = dr.ColumnStart; + + for (int i = dr.ColumnStart + 1; i < map.Length; i++) + { + int index = map[i]; + GridColumn column = columns[index]; + + if (column.Visible == true) + { + dr.ColumnEnd = i; + + if (column.IsOnScreen == false) + break; + } + } + + dr.ColumnEnd++; + } + + return (dr.ColumnCount); + } + + #endregion + + #region GetNewRange + + private DisplayRange GetNewRange(DisplayRange dr, + int rowStart, int rowCount, int columnStart, int columnCount) + { + DisplayRange ndr = new DisplayRange(); + + ndr.RowStart = rowStart; + ndr.RowCount = rowCount; + + if (ndr.RowEnd > dr.RowEnd) + ndr.RowEnd = dr.RowEnd; + + ndr.ColumnStart = columnStart; + ndr.ColumnCount = columnCount; + + if (ndr.ColumnEnd > dr.ColumnEnd) + ndr.ColumnEnd = dr.ColumnEnd; + + return (ndr); + } + + #endregion + + #endregion + + #region GetCellRanges + + private List GetCellRanges(List drs) + { + List cellRanges = null; + + if (_GridPanel.SuperGrid.EditorActive == true || LastScanIsValid(drs) == true) + { + cellRanges = _ScanItems; + } + else + { + foreach (DisplayRange dr in drs) + { + List crs = UpdateMergeRange(dr); + + if (crs != null) + { + if (cellRanges != null) + cellRanges.InsertRange(0, crs); + else + cellRanges = crs; + } + } + + _LastDrs = drs; + } + + if (cellRanges != null) + { + _GridContainer.SuperGrid.BoundsUpdateCount++; + + foreach (CellRange cr in cellRanges) + cr.BackBounds = GetDisplayBounds(cr); + + _GridContainer.GridPanel.UpdateSelectionCount(); + } + + return (cellRanges); + } + + #region LastScanIsValid + + private bool LastScanIsValid(List drs) + { + if (_GridContainer.NeedMergeLayout == false) + { + if (_LastDrs != null) + { + if (drs.Count == _LastDrs.Count) + { + for (int i = 0; i < drs.Count; i++) + { + if (drs[i].IsRangeEqualTo(_LastDrs[i]) == false) + return (false); + } + + return (true); + } + } + } + + return (false); + } + + #endregion + + #region UpdateMergeRange + + private List UpdateMergeRange(DisplayRange dr) + { + UpdateMergeFlags(dr); + UpdateMergeCount(dr); + + List cellRanges = null; + + if (_GridContainer.SuperGrid.DoGetCellRangesEvent(_GridContainer, dr, ref cellRanges) == false) + cellRanges = GetCellMergeRanges(dr); + + if (cellRanges != null) + PostProcessCellRanges(cellRanges); + + _GridContainer.SuperGrid.DoUpdateCellDisplayRangesEvent(_GridContainer, dr, ref cellRanges); + + return (cellRanges); + } + + #endregion + + #region UpdateMergeFlags + + private void UpdateMergeFlags(DisplayRange dr) + { + GridRow lastRow = null; + + for (int i = dr.RowStart; i < dr.RowEnd; i++) + { + GridContainer item = GetRow(i); + + if (item != null && item.Visible == true) + { + GridRow row = item as GridRow; + + if (row != null) + { + SetHMergeFlags(row, dr); + SetVMergeFlags(row, lastRow, dr); + } + + lastRow = row; + } + } + } + + #region SetHMergeFlags + + private void SetHMergeFlags(GridRow row, DisplayRange dr) + { + GridPanel panel = _GridContainer.GridPanel; + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + + GridCell lastCell = null; + + for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + GridCell cell = row[index]; + + if (cell != null) + { + if (lastCell != null) + { + if (_GridContainer.SuperGrid.NeedMergeLayout == true || + cell.MergeUpdateCount != _GridContainer.MergeUpdateCount || + lastCell.MergeUpdateCount != _GridContainer.MergeUpdateCount) + { + bool merged = false; + + if (CanHMergeCells(panel, column, lastCell.GridColumn)) + merged = CanMergeValues(cell, lastCell); + + cell.MergedLeft = merged; + lastCell.MergedRight = merged; + } + } + else + { + cell.MergedLeft = false; + } + } + + lastCell = cell; + } + } + } + + #region CanHMergeCells + + private bool CanHMergeCells( + GridPanel panel, GridColumn column1, GridColumn column2) + { + return (IsHCellMerge(panel, column1.CellMergeMode, CellMergeMode.HorizontalLeft) && + IsHCellMerge(panel, column2.CellMergeMode, CellMergeMode.HorizontalRight)); + } + + #region IsHCellMerge + + private bool IsHCellMerge(GridPanel panel, CellMergeMode cMode, CellMergeMode tMode) + { + if (cMode == CellMergeMode.NotSet) + cMode = panel.CellMergeMode; + + return ((cMode & tMode) == tMode); + } + + #endregion + + #endregion + + #region CanVMergeCells + + private bool CanVMergeCells(GridPanel panel, GridColumn column) + { + return (IsVCellMerge(panel, column.CellMergeMode)); + } + + #region IsVCellMerge + + private bool IsVCellMerge(GridPanel panel, CellMergeMode mode) + { + if (mode == CellMergeMode.NotSet) + mode = panel.CellMergeMode; + + return ((mode & CellMergeMode.Vertical) == CellMergeMode.Vertical); + } + + #endregion + + #endregion + + #endregion + + #region SetVMergeFlags + + private void SetVMergeFlags(GridRow row, GridRow lastRow, DisplayRange dr) + { + GridPanel panel = _GridContainer.GridPanel; + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + + for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + GridCell cell = row[index]; + + if (cell != null) + { + if (lastRow != null) + { + GridCell lastCell = lastRow[index]; + + if (lastRow.Rows.Count <= 0 || lastRow.Expanded == false) + { + if (lastCell != null) + { + if (_GridContainer.SuperGrid.NeedMergeLayout == true || + cell.MergeUpdateCount != _GridContainer.MergeUpdateCount || + cell.MergeUpdateCount != row.MergeUpdateCount || + lastCell.MergeUpdateCount != _GridContainer.MergeUpdateCount || + lastCell.MergeUpdateCount != lastRow.MergeUpdateCount) + { + bool merged = false; + + if (CanVMergeCells(panel, column) == true) + merged = CanMergeValues(cell, lastCell); + + cell.MergedTop = merged; + lastCell.MergedBottom = merged; + } + } + else + { + cell.MergedTop = false; + } + } + else + { + if (lastCell != null) + lastCell.MergedBottom = false; + + cell.MergedTop = false; + } + } + } + } + } + } + + #endregion + + #region CanMergeValues + + private bool CanMergeValues(GridCell cell1, GridCell cell2) + { + if (cell1.IsValueNull || cell2.IsValueNull) + { + if (cell1.Value == cell2.Value) + return (cell1.AllowNullMerge & cell2.AllowNullMerge); + + return (false); + } + + string s1 = cell1.FormattedValue; + string s2 = cell2.FormattedValue; + + return (s1.Equals(s2)); + } + + #endregion + + #endregion + + #region UpdateMergeCount + + private void UpdateMergeCount(DisplayRange dr) + { + GridPanel panel = _GridContainer.GridPanel; + GridColumnCollection columns = panel.Columns; + + int[] map = columns.DisplayIndexMap; + + for (int i = dr.RowStart; i < dr.RowEnd; i++) + { + GridContainer item = GetRow(i); + + if (item != null && item.Visible == true) + { + GridRow row = item as GridRow; + + if (row != null) + { + row.MergeUpdateCount = _GridContainer.MergeUpdateCount; + + for (int j = dr.ColumnStart; j < dr.ColumnEnd; j++) + { + int index = map[j]; + + GridCell cell = row[index]; + + if (cell != null) + cell.MergeUpdateCount = _GridContainer.MergeUpdateCount; + } + } + } + } + } + + #endregion + + #region GetCellMergeRanges + + private List GetCellMergeRanges(DisplayRange dr) + { + switch (_GridPanel.CellMergeOrder) + { + case CellMergeOrder.HorizontalThenVertical: + return (MergeHCells(dr)); + + default: + return (MergeVCells(dr)); + } + } + + #region MergeVCells + + private List MergeVCells(DisplayRange dr) + { + List cellRanges = new List(); + + GridColumnCollection columns = _GridContainer.GridPanel.Columns; + int[] map = columns.DisplayIndexMap; + + for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++) + { + int index = map[i]; + GridColumn column = columns[index]; + + if (column.Visible == true) + { + CellRange cr = null; + + for (int j = dr.RowStart; j < dr.RowEnd; j++) + { + GridRow row = GetRow(j); + + if (row != null && row.Visible == true && row.IsTempInsertRow == false) + { + GridCell cell = row.GetCell(index); + + if (cell != null) + { + if (cell.MergedTop == true) + { + if (cr == null) + cr = new CellRange(j, i); + else + cr.RowEnd = j + 1; + } + else + { + OutputVCellRange(cellRanges, cr, map); + + cr = new CellRange(j, i); + } + } + } + } + + OutputVCellRange(cellRanges, cr, map); + } + } + + return (cellRanges); + } + + #region OutputVCellRange + + private void OutputVCellRange( + List cellRanges, CellRange cr, int[] map) + { + if (cr != null) + { + for (int i = 0; i < cellRanges.Count; i++) + { + CellRange crn = cellRanges[i]; + + if (crn.ColumnEnd == cr.ColumnStart) + { + if (crn.RowStart == cr.RowStart && crn.RowEnd == cr.RowEnd) + { + GridRow row = GetRow(cr.RowStart); + + if (row != null) + { + if (row[map[crn.ColumnEnd - 1]].MergedRight == true) + { + crn.ColumnEnd = cr.ColumnEnd; + cr = null; + } + else + { + if (crn.RowStart == crn.RowEnd && crn.ColumnStart == crn.ColumnEnd) + cellRanges.RemoveAt(i); + } + } + break; + } + } + } + + if (cr != null) + cellRanges.Add(cr); + } + } + + #endregion + + #endregion + + #region MergeHCells + + private List MergeHCells(DisplayRange dr) + { + List cellRanges = new List(); + + GridColumnCollection columns = _GridPanel.Columns; + int[] map = columns.DisplayIndexMap; + + for (int j = dr.RowStart; j < dr.RowEnd; j++) + { + GridRow row = GetRow(j); + + if (row != null && row.Visible == true && row.IsTempInsertRow == false) + { + CellRange cr = null; + + for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + GridCell cell = row[index]; + + if (cell != null) + { + if (cell.MergedLeft == true) + { + if (cr == null) + cr = new CellRange(j, i); + else + cr.ColumnEnd = i + 1; + } + else + { + OutputHCellRange(cellRanges, cr, map); + + cr = new CellRange(j, i); + } + } + } + } + + OutputHCellRange(cellRanges, cr, map); + } + } + + return (cellRanges); + } + + #region OutputHCellRange + + private void OutputHCellRange( + List cellRanges, CellRange cr, int[] map) + { + if (cr != null) + { + for (int i = 0; i < cellRanges.Count; i++) + { + CellRange crn = cellRanges[i]; + + if (crn.RowEnd == cr.RowStart) + { + if (crn.ColumnStart == cr.ColumnStart && crn.ColumnEnd == cr.ColumnEnd) + { + GridRow row = GetRow(crn.RowEnd - 1); + + if (row != null) + { + if (row[map[crn.ColumnEnd - 1]].MergedBottom == true) + { + crn.RowEnd = cr.RowEnd; + cr = null; + } + else + { + if (crn.RowStart == crn.RowEnd && crn.ColumnStart == crn.ColumnEnd) + cellRanges.RemoveAt(i); + } + } + break; + } + } + } + + if (cr != null) + cellRanges.Add(cr); + } + } + + #endregion + + #endregion + + #endregion + + #region PostProcessCellRanges + + private void PostProcessCellRanges(List cellRanges) + { + if (cellRanges != null) + { + for (int i = cellRanges.Count - 1; i >= 0; i--) + { + CellRange cr = cellRanges[i]; + + if (cr.ColumnCount <= 1 && cr.RowCount <= 1) + { + cellRanges.RemoveAt(i); + } + else + { + if (cr.FormattedValue == null) + { + GridCell cell = GetRow(cr.RowStart)[_GridPanel.Columns.DisplayIndexMap[cr.ColumnStart]]; + + if (cell != null) + { + string s = cell.FormattedValue; + + cell.SuperGrid.DoGetCellRangeFormattedValueEvent((GridContainer)cell.GridRow.Parent, cr, ref s); + + cr.FormattedValue = s; + } + else + { + cr.FormattedValue = ""; + } + } + } + } + } + } + + #endregion + + #region GetDisplayBounds + + private Rectangle GetDisplayBounds(CellRange cr) + { + Rectangle r = Rectangle.Empty; + + if (cr != null) + { + GridPanel panel = _GridContainer.GridPanel; + int[] map = panel.Columns.DisplayIndexMap; + + int rowHeight = 200; + + for (int ri = cr.RowStart; ri < cr.RowEnd; ri++) + { + GridRow row = GetRow(ri); + + if (row.Visible == true) + { + for (int ci = cr.ColumnStart; ci < cr.ColumnEnd; ci++) + { + int index = map[ci]; + + GridCell cell = row.GetCell(index); + + if (cell != null) + { + r = (r.IsEmpty == true) + ? cell.BackBounds + : Rectangle.Union(r, cell.BackBounds); + } + } + + if (rowHeight > row.FixedRowHeight) + rowHeight = row.FixedRowHeight; + } + } + + if (r.IsEmpty == false) + r = AdjustMergeRect(panel, map, r, cr, rowHeight); + } + + return (r); + } + + #region AdjustMergeRect + + private Rectangle AdjustMergeRect(GridPanel panel, + int[] map, Rectangle r, CellRange cr, int rowHeight) + { + Rectangle r2 = r; + Rectangle t = _GridContainer.SViewRect; + + if (r.IntersectsWith(t)) + r.Intersect(t); + + if (r.Width > 0 && r.Height > 0) + { + if (r2.Y < t.Y) + { + if (r.Height < rowHeight) + { + r.Y = r.Bottom - rowHeight; + r.Height = rowHeight; + } + } + else if (r2.Bottom > t.Bottom) + { + if (r.Height < rowHeight) + r.Height = rowHeight; + } + + GridColumn cols = panel.Columns[map[cr.ColumnStart]]; + GridColumn cole = panel.Columns[map[cr.ColumnEnd - 1]]; + + if (r2.X < t.X && cole.Bounds.X < t.X) + { + if (r.Width < cole.BoundsRelative.Width) + { + r.X = r2.Right - cole.BoundsRelative.Width; + r.Width = cole.BoundsRelative.Width; + } + } + else if (r2.Right > t.Right && cols.Bounds.Right > r.Right) + { + if (r.Width < cols.BoundsRelative.Width) + { + r.X = r2.X; + r.Width = cols.BoundsRelative.Width; + } + } + } + + return (r); + } + + #endregion + + #endregion + + #endregion + + #region GetRow + + private GridRow GetRow(int index) + { + return (_GridPanel.VirtualMode == true) + ? _GridPanel.VirtualRows[index] + : _GridContainer.Rows[index] as GridRow; + } + + #endregion + + #endregion + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridPanel.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridPanel.cs new file mode 100644 index 00000000..108d4d3b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridPanel.cs @@ -0,0 +1,14939 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.IO; +using System.Media; +using System.Reflection; +using System.Text; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Primitives; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.SuperGrid.TextMarkup; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Represents a grid panel which lays out the grid rows. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class GridPanel : GridContainer + { + #region Private variables + + private string _Name = ""; + + private Psp0 _Psp0; + private Psp1 _Psp1; + private Psi _Psi; + + private GridCaption _Caption; + private GridColumnHeader _ColumnHeader; + + private GridHeader _Header; + private GridFooter _Footer; + private GridTitle _Title; + private GridFilter _Filter; + private GridGroupByRow _GroupByRow; + + private string _NoRowsText; + + private Size _LevelIndentSize = new Size(20, 10); + private int _FrozenColumnCount; + private int _FrozenRowCount; + + private int _PrimaryColumnIndex; + private GridColumnCollection _Columns; + private List _GroupColumns; + + private List _SortColumns; + private SortLevel _SortLevel = SortLevel.Root; + private SortCycle _SortCycle = SortCycle.NotSet; + + private Image _ExpandImage; + private Image _CollapseImage; + private ImageList _ImageList; + + private Size _CheckBoxSize = new Size(13, 13); + private GridLines _GridLines = GridLines.Both; + + private ColumnAutoSizeMode _ColumnAutoSizeMode; + private CellMergeMode _CellMergeMode = CellMergeMode.HorizontalAndVertical; + private CellMergeOrder _CellMergeOrder = CellMergeOrder.VerticalThenHorizontal; + + private KeyboardEditMode _KeyboardEditMode = KeyboardEditMode.EditOnKeystrokeOrF2; + private MouseEditMode _MouseEditMode = MouseEditMode.DoubleClick; + private RowEditMode _RowEditMode = RowEditMode.ClickedCell; + private RowFocusMode _RowFocusMode = RowFocusMode.FullRow; + private RowDoubleClickBehavior _RowDoubleClickBehavior = RowDoubleClickBehavior.Activate; + + private SelectionGranularity _SelectionGranularity = SelectionGranularity.Cell; + private ColumnDragBehavior _ColumnDragBehavior = ColumnDragBehavior.ExtendClickBehavior; + private RowDragBehavior _RowDragBehavior = RowDragBehavior.ExtendSelection; + private CellDragBehavior _CellDragBehavior = CellDragBehavior.ExtendSelection; + + private RowWhitespaceClickBehavior _RowWhitespaceClickBehavior = RowWhitespaceClickBehavior.ClearSelection; + private TopLeftHeaderSelectBehavior _TopLeftHeaderSelectBehavior = TopLeftHeaderSelectBehavior.Deterministic; + + private ColumnHeaderClickBehavior _ColumnHeaderClickBehavior = ColumnHeaderClickBehavior.SortAndReorder; + private ColumnHeaderClickBehavior _ColumnGroupHeaderClickBehavior = ColumnHeaderClickBehavior.SortAndReorder; + + private GroupHeaderKeyBehavior _GroupHeaderKeyBehavior = GroupHeaderKeyBehavior.Skip; + private GroupHeaderClickBehavior _GroupHeaderClickBehavior = GroupHeaderClickBehavior.None; + private WhitespaceClickBehavior _WhitespaceClickBehavior = WhitespaceClickBehavior.ClearSelection; + + private RowHighlightType _RowHighlightType = RowHighlightType.Full; + private ActiveRowIndicatorStyle _ActiveRowIndicatorStyle = ActiveRowIndicatorStyle.Image; + + private RowHeaderVisibility _GroupRowHeaderVisibility = RowHeaderVisibility.PanelControlled; + + private int _RowHeaderWidth = 35; + private int _RowHeaderWidthEx; + + private int _GroupHeaderHeight = 30; + + private int _MaxRowHeight = 500; + private int _MinRowHeight = 5; + private int _DefaultRowHeight = 22; + private int _DefaultPreDetailRowHeight; + private int _DefaultPostDetailRowHeight; + private Size _RowHeaderSize; + private Size _SizeNeeded; + + private int _VirtualRowCount; + private int _VirtualRowHeight = 22; + private GridVirtualRows _VirtualRows; + private GridRow _VirtualInsertRow; + private GridRow _VirtualTempInsertRow; + + private Rectangle _WhiteSpaceRect; + private GridContainer _HotItem; + + private ushort _SelectionClearCount = 1; + private ushort _SelectionUpdateCount = 1; + private ushort _LastSelectionUpdateCount = 1; + private ushort _DeleteUpdateCount = 1; + private ushort _ExpandedUpdateCount = 1; + + private SelectedElements _SelectedRows; + private SelectedElements _SelectedColumns; + + private GridContainer _SelectionRowAnchor; + private object _SelectionColumnAnchor; + private GridElement _LastProcessedItem; + + private SelectedElements _DeletedRows; + + private object _DataSource; + private string _DataMember; + private DataBinder _DataBinder; + + private NullValue _NullValue = NullValue.DBNull; + private string _NullString = String.Empty; + + private GridContainer _ActiveRow; + private GridContainer _LatentActiveContainer; + private int _LatentActiveRowIndex = -1; + private int _LatentActiveCellIndex = -1; + + private Image _InsertRowImage; + private Image _InsertRowImageCache; + private int _InsertRowImageIndex = -1; + + private Image _InsertTempRowImage; + private Image _InsertTempRowImageCache; + private int _InsertTempRowImageIndex = -1; + + private RelativeRow _InitialActiveRow = RelativeRow.FirstRow; + private RelativeSelection _InitialSelection = RelativeSelection.FirstCell; + + private StyleType _SizingStyle = StyleType.NotSet; + private DefaultVisualStyles _DefaultVisualStyles; + private GridPanelVisualStyle _EffectiveStyle; + private CellVisualStyles _EffectiveCellStyles; + private CellVisualStyles _EffectiveMergedCellStyles; + private ushort _StyleUpdateCount; + + private BodyElement _NoRowsMarkup; + + private string _FilterExpr; + private FilterEval _FilterEval; + private FilterMatchType _FilterMatchType = FilterMatchType.NotSet; + private FilterLevel _FilterLevel = FilterLevel.Root; + + private int _NewIndex; + private int _NewFullIndex; + private int _NewGridIndex; + + private ushort _IndiceesUpdateCount; + private ushort _RenderCount; + + private GridContainer[] _GridIndexArray; + private Dictionary _ExpDictionary; + + private int _VisibleRowCount; + private int _FilteredRowCount; + private int _RowHeaderIndexOffset; + + private ExpandButtonType _ExpandButtonType = ExpandButtonType.NotSet; + private Image _ExpandButtonImage; + private Image _ExpandButtonHotImage; + private Image _CollapseButtonImage; + private Image _CollapseButtonHotImage; + + private ProcessChildRelations _ProcessChildRelations = ProcessChildRelations.Always; + private NestedListScanTypes _NestedListScanTypes = NestedListScanTypes.Fields; + private DataRelation _DataRelation; + + private GroupSortElement _GroupSortElement = GroupSortElement.GroupId; + + private ShowRowInfoDisplayMode _ShowRowInfoDisplayMode = ShowRowInfoDisplayMode.ShowWithNonEmptyText; + private ShowCellInfoDisplayMode _ShowCellInfoDisplayMode = ShowCellInfoDisplayMode.ShowWithNonEmptyText; + + #endregion + + /// + /// GridPanel + /// + public GridPanel() + { + InitDefaultStates(); + + _ColumnAutoSizeMode = ColumnAutoSizeMode.None; + + _Columns = new GridColumnCollection(); + _Columns.ParentItem = this; + + _Columns.CollectionChanged += ColumnsCollectionChanged; + + _SortColumns = new List(); + _GroupColumns = new List(); + + _ColumnHeader = new GridColumnHeader(); + _ColumnHeader.Parent = this; + _ColumnHeader.Columns = _Columns; + + _SelectedRows = new SelectedElements(SelectedElementType.SelectedRows); + _SelectedColumns = new SelectedElements(SelectedElementType.SelectedColumns); + _DeletedRows = new SelectedElements(SelectedElementType.DeletedRows); + + _GridIndexArray = new GridContainer[64]; + _ExpDictionary = new Dictionary(); + } + + #region InitDefaultStates + + private void InitDefaultStates() + { + SetState(Psp0.AllowEdit, true); + SetState(Psp0.AllowNullCellMerge, true); + + SetState(Psp0.AutoGenerateColumns, true); + SetState(Psp0.AutoHideDeletedRows, true); + SetState(Psp0.AutoSelectDeleteBoundRows, true); + SetState(Psp0.AutoSelectNewBoundRows, true); + + SetState(Psp0.EnableSelectionBuffering, true); + SetState(Psp1.EnterKeySelectsNextRow, true); + SetState(Psp1.FilterIgnoreMatchCase, true); + SetState(Psp1.FocusCuesEnabled, true); + SetState(Psp1.IndentGroups, true); + SetState(Psp1.KeepRowsSorted, true); + SetState(Psp1.MultiSelect, true); + + SetState(Psp1.ShowCellInfo, true); + SetState(Psp1.ShowDropShadow, true); + SetState(Psp1.ShowEditingImage, true); + SetState(Psp1.ShowGroupExpand, true); + SetState(Psp1.ShowGroupUnderline, true); + SetState(Psp1.ShowInsertRowImage, true); + SetState(Psp1.ShowRowInfo, true); + SetState(Psp1.ShowRowHeaders, true); + SetState(Psp1.ShowRowDirtyMarker, true); + SetState(Psp1.ShowToolTips, true); + SetState(Psp1.ShowWhitespaceRowLines, true); + } + + #endregion + + #region Hidden properties + + #region Expanded + + /// + /// Expanded + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool Expanded + { + get { return (base.Expanded); } + } + + #endregion + + #region Style + + /// + /// Style + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new CellVisualStyles CellStyles + { + get { return (base.CellStyles); } + } + + #endregion + + #region Style + + /// + /// Style + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new string RowHeaderText + { + get { return (base.RowHeaderText); } + } + + #endregion + + #region RowStyles + + /// + /// RowVisualStyles + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new RowVisualStyles RowStyles + { + get { return (base.RowStyles); } + } + + #endregion + + #endregion + + #region Public properties + + #region ActiveCell + + /// + /// Gets the current Active Cell (or null) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell ActiveCell + { + get + { + if (SuperGrid != null) + { + GridCell cell = SuperGrid.ActiveCell; + + if (cell != null && cell.GridPanel == this) + return (cell); + } + + return (null); + } + } + + #endregion + + #region ActiveRow + + /// + /// Gets the current Active Row. This row will have the + /// "Active Row" image presented in the row header (if + /// ActiveRowImage is non-null). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer ActiveRow + { + get { return (_ActiveRow); } + + internal set + { + if (value != _ActiveRow) + { + GridContainer oldActive = _ActiveRow; + _ActiveRow = value; + + if (ActiveRowIndicatorStyle != ActiveRowIndicatorStyle.None) + { + if (oldActive != null) + InvalidateRowHeader(oldActive); + + InvalidateRowHeader(_ActiveRow); + } + } + } + } + + #endregion + + #region ActiveRowIndicatorStyle + + /// + /// Gets or sets how the Active Row + /// is visually indicated in the RowHeader. + /// + [DefaultValue(ActiveRowIndicatorStyle.Image), Category("Rows")] + [Description("Indicates how the Active Row is visually indicated in the RowHeader.")] + public ActiveRowIndicatorStyle ActiveRowIndicatorStyle + { + get { return (_ActiveRowIndicatorStyle); } + + set + { + if (_ActiveRowIndicatorStyle != value) + { + _ActiveRowIndicatorStyle = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("ActiveRowIndicatorStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #region AllowEdit + + /// + /// Gets or sets whether grid cells can be edited by the user. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether grid cells can be edited by the user.")] + public bool AllowEdit + { + get { return (TestState(Psp0.AllowEdit)); } + + set + { + if (value != AllowEdit) + { + SetState(Psp0.AllowEdit, value); + + OnPropertyChanged("AllowEdit"); + } + } + } + + #endregion + + #region AllowEmptyCellSelection + + /// + /// Gets or sets whether empty cells can be + /// selected and interacted with by the user + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether empty cells can be selected and interacted with by the user.")] + public bool AllowEmptyCellSelection + { + get { return (TestState(Psp0.AllowEmptyCellSelection)); } + + set + { + if (value != AllowEmptyCellSelection) + { + SetState(Psp0.AllowEmptyCellSelection, value); + + OnPropertyChanged("AllowEmptyCellSelection"); + } + } + } + + #endregion + + #region AllowNullCellMerge + + /// + /// Gets or sets whether cells with null/empty values + /// are allowed to be merged. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether cells with null/empty values are allowed to be merged.")] + public bool AllowNullCellMerge + { + get { return (TestState(Psp0.AllowNullCellMerge)); } + + set + { + if (value != AllowNullCellMerge) + { + SetState(Psp0.AllowNullCellMerge, value); + + OnPropertyChanged("AllowNullCellMerge"); + } + } + } + + #endregion + + #region AllowRowDelete + + /// + /// Gets or sets whether grid rows can be deleted by the user. + /// Selected rows are deleted by pressing the 'delete' key, and can + /// be restored by pressing the 'shift-delete' key. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether grid rows can be deleted by the user. Selected rows are deleted by pressing the 'delete' key, and can be restored by pressing the 'shift-delete' key.")] + public bool AllowRowDelete + { + get { return (TestState(Psp0.AllowRowDelete)); } + + set + { + if (value != AllowRowDelete) + { + SetState(Psp0.AllowRowDelete, value); + + OnPropertyChanged("AllowRowDelete"); + } + } + } + + #endregion + + #region AllowRowHeaderResize + + /// + /// Gets or sets whether grid row headers can be resized by the user. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether grid row headers can be resized by the user.")] + public bool AllowRowHeaderResize + { + get { return (TestState(Psp0.AllowRowHeaderResize)); } + + set + { + if (value != AllowRowHeaderResize) + { + SetState(Psp0.AllowRowHeaderResize, value); + + OnPropertyChanged("AllowRowHeaderResize"); + } + } + } + + #endregion + + #region AllowRowInsert + + /// + /// Gets or sets whether grid rows can be inserted + /// by the user. Rows can be inserted by selecting + /// a row and pressing the 'insert' key. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether grid rows can be inserted by the user. Rows can be inserted by selecting a row and pressing the 'insert' key.")] + public bool AllowRowInsert + { + get { return (TestState(Psp0.AllowRowInsert)); } + + set + { + if (value != AllowRowInsert) + { + SetState(Psp0.AllowRowInsert, value); + + OnPropertyChanged("AllowRowInsert"); + } + } + } + + #endregion + + #region AllowRowResize + + /// + /// Gets or sets whether grid rows can be resized by the user + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether grid rows can be resized by the user.")] + public bool AllowRowResize + { + get { return (TestState(Psp0.AllowRowResize)); } + + set + { + if (value != AllowRowResize) + { + SetState(Psp0.AllowRowResize, value); + + OnPropertyChanged("AllowRowResize"); + } + } + } + + #endregion + + #region AutoExpandSetGroup + + /// + /// Gets or sets whether new SetGroups are automatically Expanded + /// + [DefaultValue(false), Category("Group")] + [Description("Indicates whether new SetGroups are automatically Expanded)")] + public bool AutoExpandSetGroup + { + get { return (TestState(Psp0.AutoExpandSetGroup)); } + + set + { + if (AutoExpandSetGroup != value) + { + SetState(Psp0.AutoExpandSetGroup, value); + + OnPropertyChanged("AutoExpandSetGroup"); + } + } + } + + #endregion + + #region AutoGenerateColumns + + /// + /// Gets or sets a whether columns are created automatically + /// at run-time when the DataSource property is set + /// + [DefaultValue(true), Category("Data")] + [Description("Indicates whether columns are created automatically at run-time when the DataSource property is set.")] + public bool AutoGenerateColumns + { + get { return (TestState(Psp0.AutoGenerateColumns)); } + + set + { + if (AutoGenerateColumns != value) + { + SetState(Psp0.AutoGenerateColumns, value); + + if (value == true) + NeedToUpdateBindings = true; + + OnPropertyChangedEx("AutoGenerateColumns", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AutoHideDeletedRows + + /// + /// Gets or sets whether newly deleted rows are automatically hidden. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether newly deleted rows are automatically hidden.")] + public bool AutoHideDeletedRows + { + get { return (TestState(Psp0.AutoHideDeletedRows)); } + + set + { + if (AutoHideDeletedRows != value) + { + SetState(Psp0.AutoHideDeletedRows, value); + + OnPropertyChanged("AutoHideDeletedRows"); + } + } + } + + #endregion + + #region AutoSelectDeleteBoundRows + + /// + /// Gets or sets whether the grid will automatically select the + /// next positionally available row following a bound data row deletion. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the grid will automatically select the next positionally available row following a bound data row deletion.")] + public bool AutoSelectDeleteBoundRows + { + get { return (TestState(Psp0.AutoSelectDeleteBoundRows)); } + + set + { + if (AutoSelectDeleteBoundRows != value) + { + SetState(Psp0.AutoSelectDeleteBoundRows, value); + + OnPropertyChanged("AutoSelectDeleteBoundRows"); + } + } + } + + #endregion + + #region AutoSelectNewBoundRows + + /// + /// Gets or sets whether newly added rows + /// (when bound to a data source) are automatically selected. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether newly added rows (when bound to a data source) are automatically selected.")] + public bool AutoSelectNewBoundRows + { + get { return (TestState(Psp0.AutoSelectNewBoundRows)); } + + set + { + if (AutoSelectNewBoundRows != value) + { + SetState(Psp0.AutoSelectNewBoundRows, value); + + OnPropertyChanged("AutoSelectNewBoundRows"); + } + } + } + + #endregion + + #region Bounds + + /// + /// Gets the scroll adjusted bounds of the Grid Panel + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle Bounds + { + get + { + Rectangle r = BoundsRelative; + + if (IsVFrozen == false) + { + if (IsSubPanel == true) + r.X -= HScrollOffset; + + r.Y -= VScrollOffset; + } + + return (r); + } + } + + #endregion + + #region CanDeleteRow + + /// + /// Gets whether row deletes are permitted + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool CanDeleteRow + { + get + { + if (AllowRowDelete == false) + return (false); + + //if (GroupColumns != null && GroupColumns.Count > 0) + // return (false); + + return (DataBinder.CanDeleteRow); + } + } + + #endregion + + #region CanInsertRow + + /// + /// Gets whether row inserts are permitted + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool CanInsertRow + { + get + { + if (AllowRowInsert == false) + return (false); + + if (GroupColumns != null && GroupColumns.Count > 0) + return (false); + + return (DataBinder.CanInsertRow); + } + } + + #endregion + + #region CanMoveRow + + /// + /// Gets whether row moves are permitted + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool CanMoveRow + { + get + { + if (VirtualMode == false || + (RowDragBehavior != RowDragBehavior.Move && RowDragBehavior != RowDragBehavior.GroupMove)) + { + return (false); + } + + return (DataBinder.CurrencyManager == null); + } + } + #endregion + + #region Caption + + /// + /// Gets or sets the Caption, which is displayed at the + /// very top of the panel. The Caption is fixed + /// and it does not move as grid rows are scrolled. + /// + /// + [Category("Header,Footer...")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Description("Indicates the Caption item, which is displayed at the very top of the panel. The Caption is fixed and it does not move as grid rows are scrolled.")] + public GridCaption Caption + { + get + { + if (_Caption == null) + Caption = new GridCaption(); + + return (_Caption); + } + + set + { + if (_Caption != value) + { + if (value != null) + { + if (value.Parent != null) + throw new ArgumentException("Item assigned as Caption already has a parent."); + + } + + _Caption = value; + + if (_Caption != null) + _Caption.Parent = this; + + NeedsMeasured = true; + + OnPropertyChangedEx("Caption", VisualChangeType.Layout); + } + } + } + + #endregion + + #region CellDragBehavior + + /// + /// Gets or sets the behavior when a cell is clicked and dragged + /// + [DefaultValue(CellDragBehavior.ExtendSelection), Category("Behavior")] + [Description("Indicates the behavior when a cell is clicked and dragged.")] + public CellDragBehavior CellDragBehavior + { + get { return (_CellDragBehavior); } + + set + { + if (value != _CellDragBehavior) + { + _CellDragBehavior = value; + + OnPropertyChanged("CellDragBehavior"); + } + } + } + + #endregion + + #region CellMergeMode + + /// + /// Gets or sets the default type of cell + /// merging that is supported by each cell in the panel + /// + [DefaultValue(CellMergeMode.HorizontalAndVertical), Category("Behavior")] + [Description("Indicates the default type of cell merging that is supported by each cell in the panel.")] + public CellMergeMode CellMergeMode + { + get { return (_CellMergeMode); } + + set + { + if (value != _CellMergeMode) + { + _CellMergeMode = value; + + InvalidateMerge(); + + OnPropertyChangedEx("CellMergeMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region CellMergeOrder + + /// + /// Gets or sets the default cell merging order that is supported by each + /// cell in the panel (i.e. horizontal then vertical or vertical then horizontal) + /// + [DefaultValue(CellMergeOrder.VerticalThenHorizontal), Category("Behavior")] + [Description("Indicates the default cell merging order that is supported by each cell in the panel (i.e. horizontal then vertical or vertical then horizontal.")] + public CellMergeOrder CellMergeOrder + { + get { return (_CellMergeOrder); } + + set + { + if (value != _CellMergeOrder) + { + _CellMergeOrder = value; + + InvalidateMerge(); + + OnPropertyChangedEx("CellMergeOrder", VisualChangeType.Layout); + } + } + } + + #endregion + + #region CheckBoxes + + /// + /// Get or sets whether CheckBoxes are present in the grid rows. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether CheckBoxes are present in the grid rows.")] + public bool CheckBoxes + { + get { return (TestState(Psp0.CheckBoxes)); } + + set + { + if (CheckBoxes != value) + { + SetState(Psp0.CheckBoxes, value); + + NeedsMeasured = true; + + OnPropertyChangedEx("CheckBoxes", VisualChangeType.Layout); + } + } + } + + #endregion + + #region CheckBoxSize + + /// + /// Gets or sets the CheckBox size + /// + [Category("Appearance")] + [Description("Indicates the CheckBox size.")] + public Size CheckBoxSize + { + get { return (_CheckBoxSize); } + + set + { + if (value != _CheckBoxSize) + { + _CheckBoxSize = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("CheckBoxSize", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeCheckBoxSize() + { + return (_CheckBoxSize.Height != 13 || _CheckBoxSize.Width != 13); + } + + /// + /// Resets property to its default value + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetCheckBoxSize() + { + CheckBoxSize = new Size(13, 13); + } + + #endregion + + #region CollapseImage + + /// + /// Gets or sets the default TreeButton collapse image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the default TreeButton collapse image.")] + public Image CollapseImage + { + get { return (_CollapseImage); } + + set + { + if (value != _CollapseImage) + { + _CollapseImage = value; + + CollapseButtonImage = null; + CollapseButtonHotImage = null; + + NeedsMeasured = true; + + OnPropertyChangedEx("CollapseImage", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ColumnAutoSizeMode + + /// + /// Gets or sets a value indicating the default mode for determining column widths + /// + [DefaultValue(ColumnAutoSizeMode.None), Category("Columns")] + [Description("Indicates the default mode for determining column widths.")] + public ColumnAutoSizeMode ColumnAutoSizeMode + { + get { return (_ColumnAutoSizeMode); } + + set + { + if (value != _ColumnAutoSizeMode) + { + _ColumnAutoSizeMode = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("ColumnAutoSizeMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ColumnHeader + + /// + /// Gets the column header for the grid. The Column Header + /// is the container object responsible for the definition + /// and control of the Column Header row (container each + /// column header text, etc). + /// + [Category("Columns")] + [Description("Indicates the column header for the grid")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridColumnHeader ColumnHeader + { + get { return (_ColumnHeader); } + } + + #endregion + + #region ColumnHeaderClickBehavior + + /// + /// Gets or sets the behavior when a column header is clicked. + /// + [Category("Columns")] + [DefaultValue(ColumnHeaderClickBehavior.SortAndReorder)] + [Description("Indicates the behavior when a column header is clicked.")] + public ColumnHeaderClickBehavior ColumnHeaderClickBehavior + { + get { return (_ColumnHeaderClickBehavior); } + + set + { + if (value != _ColumnHeaderClickBehavior) + { + _ColumnHeaderClickBehavior = value; + + OnPropertyChanged("ColumnHeaderClickBehavior"); + } + } + } + + #endregion + + #region ColumnDragBehavior + + /// + /// Gets or sets the behavior when a column header is dragged + /// + [DefaultValue(ColumnDragBehavior.ExtendClickBehavior), Category("Columns")] + [Description("Indicates the behavior when a column header is dragged.")] + public ColumnDragBehavior ColumnDragBehavior + { + get { return (_ColumnDragBehavior); } + + set + { + if (value != _ColumnDragBehavior) + { + _ColumnDragBehavior = value; + + OnPropertyChanged("ColumnDragBehavior"); + } + } + } + + #endregion + + #region Columns + + /// + /// Gets a reference to the collection of grid columns + /// + [Category("Columns")] + [Description("Indicates the collection of grid columns.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridColumnCollection Columns + { + get { return (_Columns); } + } + + #endregion + + #region ColumnGroupHeaderClickBehavior + + /// + /// Gets or sets the behavior when a column GroupHeader is clicked. + /// + [Category("Columns")] + [DefaultValue(ColumnHeaderClickBehavior.SortAndReorder)] + [Description("Indicates the behavior when a column header is clicked.")] + public ColumnHeaderClickBehavior ColumnGroupHeaderClickBehavior + { + get { return (_ColumnGroupHeaderClickBehavior); } + + set + { + if (value != _ColumnGroupHeaderClickBehavior) + { + _ColumnGroupHeaderClickBehavior = value; + + OnPropertyChanged("ColumnGroupHeaderClickBehavior"); + } + } + } + + #endregion + + #region DataMember + + /// + /// Gets or sets the name of the list or table + /// in the data source that the grid is bound to. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates the name of the list or table in the data source that the grid is bound to.")] + public string DataMember + { + get { return (_DataMember); } + + set + { + if (_DataBinder != null) + { + _DataBinder.Clear(); + + if (VirtualMode == false) + Rows.Clear(); + } + + if (_DataMember != value) + { + ClearSort(); + ClearGroup(); + } + + _DataMember = value; + + NeedToUpdateBindings = true; + NeedToUpdateDataFilter = true; + + NeedsMeasured = true; + + OnPropertyChangedEx("DataMember", VisualChangeType.Layout); + } + } + + #region SetDataMember + + internal void SetDataMember(string dataMember) + { + _DataMember = dataMember; + } + + #endregion + + #endregion + + #region DataSource + + /// + /// Gets or sets the data source that the grid is bound to + /// + [DefaultValue(null), AttributeProvider(typeof(IListSource)), Category("Data")] + [Description("Indicates the data source that the grid is bound to.")] + public object DataSource + { + get { return (_DataSource); } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + LoadInsertRow = true; + + if (AutoGenerateColumns == true) + { + ClearSort(); + ClearGroup(); + } + + _DataSource = value; + + NeedToUpdateBindings = true; + NeedToUpdateDataFilter = true; + + NeedsSorted = true; + NeedsMeasured = true; + + OnPropertyChangedEx("DataSource", VisualChangeType.Layout); + } + } + + #region SetDataSource + + internal void SetDataSource(object dataSource) + { + _DataSource = dataSource; + } + + #endregion + + #endregion + + #region DefaultPostDetailRowHeight + + /// + /// Gets or sets the default post-detail row height (default is 0) + /// + [DefaultValue(0), Category("Rows")] + [Description("Indicates the default post-detail row height (default is 0)")] + public int DefaultPostDetailRowHeight + { + get { return (_DefaultPostDetailRowHeight); } + + set + { + if (_DefaultPostDetailRowHeight != value) + { + if (value < 0) + throw new ArgumentException("Value must be 0 or greater."); + + _DefaultPostDetailRowHeight = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("DefaultPostDetailRowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DefaultPreDetailRowHeight + + /// + /// Gets or sets the default pre-detail row height (default is 0) + /// + [DefaultValue(0), Category("Rows")] + [Description("Indicates the default pre-detail row height (default is 0)")] + public int DefaultPreDetailRowHeight + { + get { return (_DefaultPreDetailRowHeight); } + + set + { + if (_DefaultPreDetailRowHeight != value) + { + if (value < 0) + throw new ArgumentException("Value must be 0 or greater."); + + _DefaultPreDetailRowHeight = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("DefaultPreDetailRowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DefaultRowHeight + + /// + /// Gets or sets the default row height (default is 20, 0 to autoSize) + /// + [DefaultValue(22), Category("Rows")] + [Description("Indicates the default row height (default is 20, 0 for autoSize)")] + public int DefaultRowHeight + { + get { return (_DefaultRowHeight); } + + set + { + if (_DefaultRowHeight != value) + { + if (value < 0) + throw new ArgumentException("Value must be 0 or greater."); + + _DefaultRowHeight = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("DefaultRowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region DefaultVisualStyles + + /// + /// Gets or sets the Default Visual Styles for each grid element + /// + [Browsable(true), Category("Style")] + [Description("Gets or sets the Default Visual Styles for the each grid element.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DefaultVisualStyles DefaultVisualStyles + { + get + { + if (_DefaultVisualStyles == null) + { + _DefaultVisualStyles = new DefaultVisualStyles(); + + DefaultVisualChangeHandler(null, _DefaultVisualStyles); + } + + return (_DefaultVisualStyles); + } + + set + { + if (_DefaultVisualStyles != value) + { + DefaultVisualStyles oldValue = _DefaultVisualStyles; + _DefaultVisualStyles = value; + + OnDefaultVisualStyleChanged(oldValue, value); + } + } + } + + #region OnDefaultVisualStyleChanged + + private void OnDefaultVisualStyleChanged( + DefaultVisualStyles oldValue, DefaultVisualStyles newValue) + { + DefaultVisualChangeHandler(oldValue, newValue); + + OnPropertyChanged("DefaultVisualStyles"); + } + + #endregion + + #region DefaultVisualChangeHandler + + private void DefaultVisualChangeHandler( + DefaultVisualStyles oldValue, DefaultVisualStyles newValue) + { + NeedsMeasured = true; + + if (oldValue != null) + oldValue.PropertyChanged -= DefaultVisualStylesPropertyChanged; + + if (newValue != null) + newValue.PropertyChanged += DefaultVisualStylesPropertyChanged; + } + + #endregion + + #endregion + + #region DeletedRowCount + + /// + /// Gets the current number of deleted rows. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int DeletedRowCount + { + get { return (_DeletedRows.Count); } + } + + #endregion + + #region DeletedRows + + /// + /// IEnumerable that can be used to enumerate through + /// all root level deleted rows + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable DeletedRows + { + get { return (new SelectedRowsEnumeration(this, _DeletedRows)); } + } + + #endregion + + #region EnableCellExpressions + + /// + /// Gets or sets whether cell expression evaluation is enabled. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether cell expression evaluation is enabled. Cell expressions begin with an equals sign '='.")] + public bool EnableCellExpressions + { + get { return (TestState(Psp0.EnableCellExpressions)); } + + set + { + if (EnableCellExpressions != value) + { + SetState(Psp0.EnableCellExpressions, value); + + OnPropertyChangedEx("EnableCellExpressions", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableCellMerging + + /// + /// Gets or sets whether cell merging is enabled. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether cell merging is enabled.")] + public bool EnableCellMerging + { + get { return (TestState(Psp0.EnableCellMerging)); } + + set + { + if (EnableCellMerging != value) + { + SetState(Psp0.EnableCellMerging, value); + + InvalidateMerge(); + + OnPropertyChangedEx("EnableCellMerging", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableCellRangeMarkup + + /// + /// Gets or sets whether text-markup support is enabled for + /// merged cell text display (CellRange FormattedValue text). + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for merged cell text display (CellRange FormattedValue text).")] + public bool EnableCellRangeMarkup + { + get { return (TestState(Psp0.EnableCellRangeMarkup)); } + + set + { + if (EnableCellRangeMarkup != value) + { + SetState(Psp0.EnableCellRangeMarkup, value); + + OnPropertyChangedEx("EnableCellRangeMarkup", VisualChangeType.Render); + } + } + } + + #endregion + + #region EnableColumnFiltering + + /// + /// Gets or sets whether column level filtering is enabled. + /// + [DefaultValue(false), Category("Filtering")] + [Description("Indicates whether column level filtering is enabled.")] + public bool EnableColumnFiltering + { + get { return (TestState(Psp0.EnableColumnFiltering)); } + + set + { + if (EnableColumnFiltering != value) + { + SetState(Psp0.EnableColumnFiltering, value); + + NeedToUpdateDataFilter = true; + + OnPropertyChangedEx("EnableColumnFiltering", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableDiscreteBoundRows + + /// + /// Gets or sets whether discrete bound row suport is enabled. + /// This property permits each bound row to be a separate object type. + /// + [DefaultValue(false), Category("Filtering")] + [Description("Indicates whether discrete bound row suport is enabled. This property permits each bound row to be a separate object type.")] + public bool EnableDiscreteBoundRows + { + get { return (TestState(Psp0.EnableDiscreteBoundRows)); } + + set + { + if (EnableDiscreteBoundRows != value) + { + SetState(Psp0.EnableDiscreteBoundRows, value); + + NeedToUpdateBindings = true; + NeedToUpdateDataFilter = true; + + OnPropertyChangedEx("EnableDiscreteBoundRows", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableFiltering + + /// + /// Gets or sets whether filtering in general is enabled. + /// + [DefaultValue(false), Category("Filtering")] + [Description("Indicates whether filtering in general is enabled.")] + public bool EnableFiltering + { + get { return (TestState(Psp0.EnableFiltering)); } + + set + { + if (EnableFiltering != value) + { + SetState(Psp0.EnableFiltering, value); + + NeedToUpdateDataFilter = true; + + OnPropertyChangedEx("EnableFiltering", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableNoRowsMarkup + + /// + /// Gets or sets whether text-markup support is enabled for the NoRowsText + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled for the NoRowsText.")] + public bool EnableNoRowsMarkup + { + get { return (TestState(Psp0.EnableNoRowsMarkup)); } + + set + { + if (EnableNoRowsMarkup != value) + { + SetState(Psp0.EnableNoRowsMarkup, value); + + NoRowsMarkupTextChanged(); + + OnPropertyChangedEx("EnableNoRowsMarkup", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableRowFiltering + + /// + /// Gets or sets whether row level filtering is enabled. + /// + [DefaultValue(false), Category("Filtering")] + [Description("Indicates whether row level filtering is enabled.")] + public bool EnableRowFiltering + { + get { return (TestState(Psp0.EnableRowFiltering)); } + + set + { + if (EnableRowFiltering != value) + { + SetState(Psp0.EnableRowFiltering, value); + + NeedToUpdateDataFilter = true; + + OnPropertyChangedEx("EnableRowFiltering", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EnableSelectionBuffering + + /// + /// Gets or sets whether selection buffering is enabled, such + /// that only one SelectionChange event is raised per output refresh. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether selection buffering is enabled, such that only one SelectionChange event is raised per output refresh..")] + public bool EnableSelectionBuffering + { + get { return (TestState(Psp0.EnableSelectionBuffering)); } + + set + { + if (EnableSelectionBuffering != value) + { + SetState(Psp0.EnableSelectionBuffering, value); + + OnPropertyChanged("EnableSelectionBuffering"); + } + } + } + + #endregion + + #region EnsureVisibleAfterGrouping + + /// + /// Gets or sets whether EnsureVisible will be called + /// for the current ActiveRow following a grouping operation. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether EnsureVisible will be called for the current ActiveRow following a grouping operation.")] + public bool EnsureVisibleAfterGrouping + { + get { return (TestState(Psp1.EnsureVisibleAfterGrouping)); } + + set + { + if (value != EnsureVisibleAfterGrouping) + { + SetState(Psp1.EnsureVisibleAfterGrouping, value); + + OnPropertyChanged("EnsureVisibleAfterGrouping"); + } + } + } + + #endregion + + #region EnsureVisibleAfterSort + + /// + /// Gets or sets whether EnsureVisible will be called + /// for the current ActiveRow following a sort operation. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether EnsureVisible will be called for the current ActiveRow following a sort operation.")] + public bool EnsureVisibleAfterSort + { + get { return (TestState(Psp1.EnsureVisibleAfterSort)); } + + set + { + if (value != EnsureVisibleAfterSort) + { + SetState(Psp1.EnsureVisibleAfterSort, value); + + OnPropertyChanged("EnsureVisibleAfterSort"); + } + } + } + + #endregion + + #region EnterKeySelectsNextRow + + /// + /// Gets or sets whether the EnterKey selects the + /// next available row, or stays on the current row + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the EnterKey selects the next available row, or stays on the current row.")] + public bool EnterKeySelectsNextRow + { + get { return (TestState(Psp1.EnterKeySelectsNextRow)); } + + set + { + if (EnterKeySelectsNextRow != value) + { + SetState(Psp1.EnterKeySelectsNextRow, value); + + OnPropertyChanged("EnterKeySelectsNextRow"); + } + } + } + + #endregion + + #region ExpandButtonType + + /// + /// Gets or sets the ExpandButton Type + /// + [DefaultValue(ExpandButtonType.NotSet), Category("Appearance")] + [Description("Indicates the ExpandButton Type.")] + public ExpandButtonType ExpandButtonType + { + get { return (_ExpandButtonType); } + + set + { + if (_ExpandButtonType != value) + { + _ExpandButtonType = value; + + ExpandButtonImage = null; + ExpandButtonHotImage = null; + CollapseButtonImage = null; + CollapseButtonHotImage = null; + + OnPropertyChangedEx("ExpandButtonType", VisualChangeType.Layout); + } + } + } + + #region GetExpandButtonType + + internal ExpandButtonType GetExpandButtonType() + { + ExpandButtonType type = _ExpandButtonType; + + if (type == ExpandButtonType.NotSet) + type = SuperGrid.ExpandButtonType; + + return (type != ExpandButtonType.NotSet ? type : ExpandButtonType.Square); + } + + #endregion + + #endregion + + #region ExpandImage + + /// + /// Gets or sets the default TreeButton expand image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the default TreeButton expand image.")] + public Image ExpandImage + { + get { return (_ExpandImage); } + + set + { + if (value != _ExpandImage) + { + _ExpandImage = value; + + ExpandButtonImage = null; + ExpandButtonHotImage = null; + + NeedsMeasured = true; + + OnPropertyChangedEx("ExpandImage", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilteredRowCount + + /// + /// Gets the current count of rows that have been filtered out. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int FilteredRowCount + { + get { return (_FilteredRowCount); } + } + + #endregion + + #region Filter + + /// + /// Gets or sets the Filter item which is displayed just below + /// the Column Header. The Filter area is fixed and it does + /// not move as grid rows are scrolled. + /// + [Category("Filtering")] + [Description("Indicates the Filter item, which is displayed just below the Column Header. The Filter area is fixed and it does not move as grid rows are scrolled.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridFilter Filter + { + get + { + if (_Filter == null) + Filter = new GridFilter(); + + return (_Filter); + } + + set + { + if (_Filter != value) + { + if (value != null) + { + if (value.Parent != null) + throw new ArgumentException("Item assigned as Filter already has a parent."); + } + + _Filter = value; + + if (_Filter != null) + _Filter.Parent = this; + + NeedsMeasured = true; + + OnPropertyChangedEx("Filter", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterExpr + + /// + /// Gets or sets the Filter expression. + /// + [DefaultValue(null), Category("Filtering")] + [Description("Indicates the Filter expression.")] + public string FilterExpr + { + get + { + return (_FilterExpr); + } + + set + { + if (_FilterExpr != value) + { + _FilterExpr = value; + _FilterEval = null; + + NeedToUpdateDataFilter = true; + + OnPropertyChangedEx("FilterExpr", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterIgnoreMatchCase + + /// + /// Gets or sets the filter data match ignores string case + /// + [DefaultValue(true), Category("Filtering")] + [Description("Indicates the filter data match ignores string case).")] + public bool FilterIgnoreMatchCase + { + get { return (TestState(Psp1.FilterIgnoreMatchCase)); } + + set + { + if (FilterIgnoreMatchCase != value) + { + SetState(Psp1.FilterIgnoreMatchCase, value); + + _FilterEval = null; + ClearColumnFilterEvals(); + + NeedToUpdateDataFilter = true; + + OnPropertyChangedEx("FilterIgnoreCase", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterLevel + + /// + /// Gets or sets the column Filtering level. + /// + [DefaultValue(FilterLevel.Root), Category("Filtering")] + [Description("Indicates the column filtering level.")] + public FilterLevel FilterLevel + { + get { return (_FilterLevel); } + + set + { + if (_FilterLevel != value) + { + _FilterLevel = value; + + NeedsFilterScan = true; + NeedToUpdateDataFilter = true; + + OnPropertyChangedEx("FilterLevel", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FilterMatchType + + /// + /// Gets or sets the filter data match type (how data elements are matched) + /// + [DefaultValue(FilterMatchType.NotSet), Category("Filtering")] + [Description("Indicates the filter data match style (how data elements are matched).")] + public FilterMatchType FilterMatchType + { + get { return (_FilterMatchType); } + + set + { + if (_FilterMatchType != value) + { + _FilterMatchType = value; + + FilterEval = null; + + ClearColumnFilterEvals(); + + NeedToUpdateDataFilter = true; + + OnPropertyChangedEx("FilterMatchType", VisualChangeType.Layout); + } + } + } + + #region GetFilterMatchType + + internal FilterMatchType GetFilterMatchType() + { + if (_FilterMatchType != FilterMatchType.NotSet) + return (_FilterMatchType); + + return (FilterMatchType.None); + } + + #endregion + + #endregion + + #region FirstFrozenColumn + + /// + /// Gets a reference to the first Frozen column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn FirstFrozenColumn + { + get + { + int[] displayMap = Columns.DisplayIndexMap; + + for (int i = 0; i < displayMap.Length; i++) + { + GridColumn column = Columns[displayMap[i]]; + + if (column.Visible == true && column.IsHFrozen == true) + return (column); + } + + return (null); + } + } + + #endregion + + #region FirstOnScreenColumn + + /// + /// Gets a reference to the first on-screen column + /// (after frozen columns) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn FirstOnScreenColumn + { + get + { + int[] displayMap = Columns.DisplayIndexMap; + + for (int i = 0; i < displayMap.Length; i++) + { + GridColumn column = Columns[displayMap[i]]; + + if (column.IsHFrozen == false && column.IsOnScreen == true) + return (column); + } + + return (null); + } + } + + #endregion + + #region FirstVisibleColumn + + /// + /// Gets a reference to the first visible column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn FirstVisibleColumn + { + get { return (_Columns.FirstVisibleColumn); } + } + + #endregion + + #region FlatCheckedRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of checked rows as though they were at + /// the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatCheckedRows + { + get { return (new FlatCheckedRowsEnumeration(this, false)); } + } + + #endregion + + #region FlatCheckedExpandedRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of checked, expanded rows as though they + /// were at the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatCheckedExpandedRows + { + get { return (new FlatCheckedRowsEnumeration(this, true)); } + } + + #endregion + + #region FlatDeletedRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of deleted rows as though they were at + /// the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatDeletedRows + { + get { return (new FlatDeletedRowsEnumeration(this)); } + } + + #endregion + + #region FlatDirtyRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of dirty rows as though they were at + /// the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatDirtyRows + { + get { return (new FlatDirtyRowsEnumeration(this, false)); } + } + + #endregion + + #region FlatDirtyExpandedRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of dirty, expanded rows as though they were at + /// the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatDirtyExpandedRows + { + get { return (new FlatDirtyRowsEnumeration(this, true)); } + } + + #endregion + + #region FlatExpandedRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of expanded rows as though they were at + /// the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatExpandedRows + { + get { return (new FlatRowsEnumeration(this, true, false)); } + } + + #endregion + + #region FlatRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of rows as though they were at the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatRows + { + get { return (new FlatRowsEnumeration(this, false, false)); } + } + + #endregion + + #region FlatSelectedRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of selected rows as though they were at + /// the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatSelectedRows + { + get { return (new FlatSelectedRowsEnumeration(this, false)); } + } + + #endregion + + #region FlatSelectedExpandedRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of selected, expanded rows as though they + /// were at the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatSelectedExpandedRows + { + get { return (new FlatSelectedRowsEnumeration(this, true)); } + } + + #endregion + + #region FlatVisibleExpandedRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of visible, expanded rows as though they + /// were at the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatVisibleExpandedRows + { + get { return (new FlatRowsEnumeration(this, true, true)); } + } + + #endregion + + #region FlatVisibleRows + + /// + /// IEnumerable that can be used to enumerate through + /// all levels of visible rows as though they + /// were at the root level + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable FlatVisibleRows + { + get { return (new FlatRowsEnumeration(this, false, true)); } + } + + #endregion + + #region FocusCuesEnabled + + /// + /// Gets or sets whether focus cues are displayed on the focused element + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether focus cues are displayed on the focused element.")] + public bool FocusCuesEnabled + { + get { return (TestState(Psp1.FocusCuesEnabled)); } + + set + { + if (FocusCuesEnabled != value) + { + SetState(Psp1.FocusCuesEnabled, value); + + OnPropertyChangedEx("FocusCuesEnabled", VisualChangeType.Render); + } + } + } + + #endregion + + #region Footer + + /// + /// Gets or sets the Footer, which is displayed at the + /// very bottom of the panel. The Footer is fixed + /// and it does not move as grid rows are scrolled. + /// + [Category("Header,Footer...")] + [Description("Indicates the Footer item, which is displayed at the very bottom of the panel. The Footer is fixed and does not move as grid rows are scrolled.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridFooter Footer + { + get + { + if (_Footer == null) + Footer = new GridFooter(); + + return (_Footer); + } + + set + { + if (_Footer != value) + { + if (value != null) + { + if (value.Parent != null) + throw new ArgumentException("Item assigned as Footer already has a parent."); + } + + _Footer = value; + + NeedsMeasured = true; + + if (_Footer != null) + _Footer.Parent = this; + + OnPropertyChangedEx("Footer", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FrozenColumnCount + + /// + /// Gets or sets the number of columns that are frozen, counted + /// from the left. Frozen columns are always visible regardless + /// of the horizontal scroll position. + /// + [DefaultValue(0), Category("Columns")] + [Description("Indicates the number of columns that are frozen, counted from the left. Frozen columns are always visible regardless of the horizontal scroll position.")] + public int FrozenColumnCount + { + get { return (_FrozenColumnCount); } + + set + { + if (value != _FrozenColumnCount) + { + _FrozenColumnCount = value; + + OnPropertyChangedEx("FrozenColumnCount", VisualChangeType.Layout); + } + } + } + + #endregion + + #region FrozenRowCount + + /// + /// Gets or sets the number of rows that are frozen, counted + /// from the top. Frozen rows are always visible regardless + /// of the vertical scroll position. + /// + [DefaultValue(0), Category("Rows")] + [Description("Indicates the number of rows that are frozen, counted from the top. Frozen rows are always visible regardless of the vertical scroll position.")] + public int FrozenRowCount + { + get { return (_FrozenRowCount); } + + set + { + if (value != _FrozenRowCount) + { + _FrozenRowCount = value; + + OnPropertyChangedEx("FrozenRowCount", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GridLines + + /// + /// Gets or sets which grid lines (horizontal and vertical) are displayed in the grid + /// + [DefaultValue(GridLines.Both), Category("Appearance")] + [Description("Indicates which grid lines (horizontal and vertical) are displayed in the grid.")] + public GridLines GridLines + { + get { return (_GridLines); } + + set + { + if (_GridLines != value) + { + _GridLines = value; + + OnPropertyChangedEx("GridLines", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupBy + + /// + /// Gets or sets the row which is displayed just above + /// the Column Header, and is used to permit display and user control + /// of column grouping. The GroupByRow is fixed and it does + /// not move as grid rows are scrolled. + /// + [Category("Header,Footer...")] + [Description("Indicates the row, which is displayed just above the Column Header, and is used to display and permit user control of column grouping. The GroupByRow is fixed and it does not move as grid rows are scrolled.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridGroupByRow GroupByRow + { + get + { + if (_GroupByRow == null) + GroupByRow = new GridGroupByRow(); + + return (_GroupByRow); + } + + set + { + if (_GroupByRow != value) + { + if (value != null) + { + if (value.Parent != null) + throw new ArgumentException("Item assigned as GroupByRow already has a parent."); + } + + _GroupByRow = value; + + if (_GroupByRow != null) + _GroupByRow.Parent = this; + + NeedsMeasured = true; + + OnPropertyChangedEx("GroupByRow", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupColumns + + /// + /// Gets or sets the panel Group columns + /// + public List GroupColumns + { + get { return (_GroupColumns); } + } + + #endregion + + #region GroupHeaderClickBehavior + + /// + /// Gets or sets the behavior when a Group header is clicked + /// + [DefaultValue(GroupHeaderClickBehavior.None), Category("Group")] + [Description("Indicates the behavior when a Group header is clicked.")] + public GroupHeaderClickBehavior GroupHeaderClickBehavior + { + get { return (_GroupHeaderClickBehavior); } + + set + { + if (_GroupHeaderClickBehavior != value) + { + _GroupHeaderClickBehavior = value; + + OnPropertyChanged("GroupHeaderClickBehavior"); + } + } + } + + #endregion + + #region GroupHeaderKeyBehavior + + /// + /// Gets or sets the behavior when a Group header + /// is encountered during keyboard navigation + /// + [DefaultValue(GroupHeaderKeyBehavior.Skip), Category("Group")] + [Description("Indicates the behavior when a Group header is encountered during keyboard navigation.")] + public GroupHeaderKeyBehavior GroupHeaderKeyBehavior + { + get { return (_GroupHeaderKeyBehavior); } + + set + { + if (_GroupHeaderKeyBehavior != value) + { + _GroupHeaderKeyBehavior = value; + + OnPropertyChanged("GroupHeaderKeyBehavior"); + } + } + } + + #endregion + + #region GroupHeaderHeight + + /// + /// Gets or sets the height of the Group header + /// + [DefaultValue(30), Category("Group")] + [Description("Indicates the height of the Group header.")] + public int GroupHeaderHeight + { + get { return (_GroupHeaderHeight); } + + set + { + if (_GroupHeaderHeight != value) + { + _GroupHeaderHeight = value; + + OnPropertyChangedEx("GroupHeaderHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupRowHeaderVisibility + + /// + /// Gets or sets whether the Group RowHeader is displayed + /// + [DefaultValue(RowHeaderVisibility.PanelControlled), Category("Group")] + [Description("Indicates whether the Group RowHeader is displayed.")] + public virtual RowHeaderVisibility GroupRowHeaderVisibility + { + get { return (_GroupRowHeaderVisibility); } + + set + { + if (value != _GroupRowHeaderVisibility) + { + _GroupRowHeaderVisibility = value; + + OnPropertyChangedEx("GroupRowHeaderVisibility", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GroupSortElement + + /// + /// Gets or sets the group element used to sort panel groups. + /// + [DefaultValue(GroupSortElement.GroupId), Category("Group")] + [Description("Indicates the group element used to sort panel groups.")] + public GroupSortElement GroupSortElement + { + get { return (_GroupSortElement); } + + set + { + if (_GroupSortElement != value) + { + _GroupSortElement = value; + + OnPropertyChangedEx("GroupSortElement", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Header + + /// + /// Gets or sets the Header item, which is displayed + /// just below the column header. The Header item is fixed + /// and does not move as grid rows are scrolled. + /// + [Category("Header,Footer...")] + [Description("Indicates the Header item, which is displayed just below the column header. The Header is fixed and does not move as grid rows are scrolled.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridHeader Header + { + get + { + if (_Header == null) + Header = new GridHeader(); + + return (_Header); + } + + set + { + if (_Header != value) + { + if (value != null) + { + if (value.Parent != null) + throw new ArgumentException("Item assigned as Header already has a parent."); + } + + _Header = value; + + NeedsMeasured = true; + + if (_Header != null) + _Header.Parent = this; + + OnPropertyChangedEx("Header", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageList + + /// + /// Gets or sets the ImageList used by the Grid elements + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates the ImageList used by the Grid elements.")] + public ImageList ImageList + { + get { return (_ImageList); } + + set + { + if (_ImageList != value) + { + _ImageList = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("ImageList", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImmediateResize + + /// + /// Gets or sets whether resizing panel columns + /// and rows occurs immediately + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether resizing panel columns and rows occurs immediately.")] + public bool ImmediateResize + { + get { return (TestState(Psp1.ImmediateResize)); } + + set + { + if (ImmediateResize != value) + { + SetState(Psp1.ImmediateResize, value); + + OnPropertyChanged("ImmediateResize"); + } + } + } + + #endregion + + #region IndentGroups + + /// + /// Gets or sets whether Nested Groups are indented + /// + [DefaultValue(true), Category("Group")] + [Description("Indicates whether Nested Groups are indented.")] + public bool IndentGroups + { + get { return (TestState(Psp1.IndentGroups)); } + + set + { + if (value != IndentGroups) + { + SetState(Psp1.IndentGroups, value); + + NeedsMeasured = true; + + OnPropertyChangedEx("IndentGroups", VisualChangeType.Layout); + } + } + } + + #endregion + + #region InitialActiveRow + + /// + /// Gets or sets the initial Active Row + /// + [DefaultValue(RelativeRow.FirstRow), Category("Selection")] + [Description("Indicates the initial Active Row")] + public RelativeRow InitialActiveRow + { + get { return (_InitialActiveRow); } + + set + { + if (value != _InitialActiveRow) + { + _InitialActiveRow = value; + + OnPropertyChanged("InitialActiveRow"); + } + } + } + + #endregion + + #region InitialSelection + + /// + /// Gets or sets the initial relative row / cell selection + /// + [DefaultValue(RelativeSelection.FirstCell), Category("Selection")] + [Description("Indicates the initial relative row / cell selection.")] + public RelativeSelection InitialSelection + { + get { return (_InitialSelection); } + + set + { + if (value != _InitialSelection) + { + _InitialSelection = value; + + OnPropertyChanged("InitialSelection"); + } + } + } + + #endregion + + #region InsertRowImage + + /// + /// Gets or sets the default image to display + /// in the row header to denote the Insertion Row. + /// + [DefaultValue(null), Category("Rows")] + [Description("Indicates the image to display in the row header to denote the Insertion Row.")] + public Image InsertRowImage + { + get { return (_InsertRowImage); } + + set + { + if (_InsertRowImage != value) + { + if (_InsertRowImageCache != null) + { + _InsertRowImageCache.Dispose(); + _InsertRowImageCache = null; + } + + _InsertRowImage = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("InsertRowImage", VisualChangeType.Layout); + } + } + } + + #region GetInsertRowImage + + internal Image GetInsertRowImage() + { + if (_InsertRowImage != null) + return (_InsertRowImage); + + if (_InsertRowImageIndex >= 0) + { + ImageList imageList = _ImageList; + + if (imageList != null && _InsertRowImageIndex < imageList.Images.Count) + return (imageList.Images[_InsertRowImageIndex]); + } + + if (_InsertRowImageCache == null) + _InsertRowImageCache = GetResourceImage("InsertRow"); + + return (_InsertRowImageCache); + } + + #endregion + + #endregion + + #region InsertRowImageIndex + + /// + /// Gets or sets the Insert Row image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the Insert Row image index.")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int InsertRowImageIndex + { + get { return (_InsertRowImageIndex); } + + set + { + if (_InsertRowImageIndex != value) + { + _InsertRowImageIndex = value; + + OnPropertyChangedEx("InsertRowImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetInsertRowImageIndex() + { + _InsertRowImageIndex = -1; + } + + #endregion + + #region InsertTempRowImage + + /// + /// Gets or sets the default image to display + /// in the row header to denote a temporary insert Row. + /// + [DefaultValue(null), Category("Rows")] + [Description("Indicates the image to display in the row header to denote a temporary Insertion Row.")] + public Image InsertTempRowImage + { + get { return (_InsertTempRowImage); } + + set + { + if (_InsertTempRowImage != value) + { + if (_InsertTempRowImageCache != null) + { + _InsertTempRowImageCache.Dispose(); + _InsertTempRowImageCache = null; + } + + _InsertTempRowImage = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("InsertTempRowImage", VisualChangeType.Layout); + } + } + } + + #region GetInsertTempRowImage + + internal Image GetInsertTempRowImage() + { + if (_InsertTempRowImage != null) + return (_InsertTempRowImage); + + if (_InsertTempRowImageIndex >= 0) + { + ImageList imageList = _ImageList; + + if (imageList != null && _InsertTempRowImageIndex < imageList.Images.Count) + return (imageList.Images[_InsertTempRowImageIndex]); + } + + return (GetInsertTempRowImageEx()); + } + + #region GetInsertTempRowImageEx + + private Image GetInsertTempRowImageEx() + { + if (_InsertTempRowImageCache == null) + { + RowVisualStyle style = GetEffectiveRowStyle(); + + Rectangle r = new Rectangle(0, 0, Dpi.Width4, Dpi.Height7); + Image image = new Bitmap(Dpi.Width4, Dpi.Height7); + + using (Graphics g = Graphics.FromImage(image)) + { + Point pt = new Point(r.X, r.Y + r.Height / 2); + + Point[] pts = + { + pt, + new Point(pt.X + Dpi.Width4, pt.Y + Dpi.Height4), + new Point(pt.X + Dpi.Width4, pt.Y - Dpi.Height4), + pt + }; + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(pts); + + Color color = style.RowHeaderStyle.ActiveRowIndicatorColor; + + if (color.IsEmpty) + color = Color.Black; + + using (Brush br = new SolidBrush(color)) + g.FillPath(br, path); + } + } + + _InsertTempRowImageCache = image; + } + + return (_InsertTempRowImageCache); + } + + #endregion + + #endregion + + #endregion + + #region InsertTempRowImageIndex + + /// + /// Gets or sets the Insert Temp Row image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the Insert Temp Row image index.")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int InsertTempRowImageIndex + { + get { return (_InsertTempRowImageIndex); } + + set + { + if (_InsertTempRowImageIndex != value) + { + _InsertTempRowImageIndex = value; + + OnPropertyChangedEx("InsertTempRowImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetInsertTempRowImageIndex() + { + _InsertTempRowImageIndex = -1; + } + + #endregion + + #region IsColumnFiltered + + /// + /// Gets whether the GridPanel has column-level filtering + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsColumnFiltered + { + get { return (DataFilter.IsColumnFiltered(this)); } + } + + #endregion + + #region IsFiltered + + /// + /// Gets whether the GridPanel is being filtered + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsFiltered + { + get { return (DataFilter.IsFiltered(this)); } + } + + #endregion + + #region IsGrouped + + /// + /// Gets whether the GridPanel is currently Grouped + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsGrouped + { + get { return (_GroupColumns != null && _GroupColumns.Count > 0); } + } + + #endregion + + #region IsRowFiltered + + /// + /// Gets whether the GridPanel has row-level filtering + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRowFiltered + { + get { return (DataFilter.IsRowFiltered(this)); } + } + + #endregion + + #region IsSortable + + /// + /// Gets whether the GridPanel is able to be sorted + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSortable + { + get + { + if (VirtualMode == true) + { + if (DataBinder.CurrencyManager == null || + DataBinder.CurrencyManager.List.Count <= 0) + { + return (true); + } + + return (DataBinder.IsSortable); + } + + return (true); + } + } + + #endregion + + #region IsSubPanel + + /// + /// Gets whether the GridPanel is a subordinate / nested grid. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsSubPanel + { + get { return (Parent != null); } + } + + #endregion + + #region KeepRowsSorted + + /// + /// Gets or sets whether grid rows are kept sorted + /// on row deactivation, following a cell's Value change + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether grid rows are kept sorted on row deactivation, following a cell's Value change.")] + public bool KeepRowsSorted + { + get { return (TestState(Psp1.KeepRowsSorted)); } + + set + { + if (value != KeepRowsSorted) + { + SetState(Psp1.KeepRowsSorted, value); + + OnPropertyChanged("KeepRowsSorted"); + } + } + } + + #endregion + + #region KeyboardEditMode + + /// + /// Gets or sets how cell editing is initiated by the keyboard + /// + [DefaultValue(KeyboardEditMode.EditOnKeystrokeOrF2), Category("Behavior")] + [Description("Indicates how cell editing is initiated by the keyboard.")] + public KeyboardEditMode KeyboardEditMode + { + get { return (_KeyboardEditMode); } + + set + { + if (value != _KeyboardEditMode) + { + _KeyboardEditMode = value; + + OnPropertyChanged("KeyboardEditMode"); + } + } + } + + #endregion + + #region LastFrozenColumn + + /// + /// Gets a reference to the last Frozen column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn LastFrozenColumn + { + get + { + int[] displayMap = Columns.DisplayIndexMap; + + for (int i = displayMap.Length - 1; i >= 0; i--) + { + GridColumn column = Columns[displayMap[i]]; + + if (column.Visible == true && column.IsHFrozen == true) + return (column); + } + + return (null); + } + } + + #endregion + + #region LastOnScreenColumn + + /// + /// Gets a reference to the last on-screen column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn LastOnScreenColumn + { + get + { + int[] displayMap = Columns.DisplayIndexMap; + + for (int i = displayMap.Length - 1; i >= 0; i--) + { + GridColumn column = Columns[displayMap[i]]; + + if (column.IsOnScreen == true) + return (column); + } + + return (null); + } + } + + #endregion + + #region LastVisibleColumn + + /// + /// Gets a reference to the last visible column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn LastVisibleColumn + { + get { return (Columns.LastVisibleColumn); } + } + + #endregion + + #region LevelIndentSize + + /// + /// Gets or sets the amount to indent the grid data when + /// a new grid level is encountered + /// + [Category("Appearance")] + [Description("Indicates the amount to indent the grid data when a new grid level is encountered.")] + public Size LevelIndentSize + { + get { return (_LevelIndentSize); } + + set + { + if (_LevelIndentSize != value) + { + _LevelIndentSize = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("LevelIndentSize", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializeLevelIndentSize() + { + return (_LevelIndentSize.Height != 10 || _LevelIndentSize.Width != 20); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetLevelIndentSize() + { + LevelIndentSize = new Size(20, 10); + } + + #endregion + + #region MaxRowHeight + + /// + /// Gets or sets the maximum row height + /// + [DefaultValue(500), Category("Rows")] + [Description("Indicates the maximum row height.")] + public int MaxRowHeight + { + get { return (_MaxRowHeight); } + + set + { + if (value != _MaxRowHeight) + { + if (value < 0) + throw new ArgumentException("Value must be 0 or greater."); + + _MaxRowHeight = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("MaxRowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MinRowHeight + + /// + /// Gets or sets the minimum row height + /// + [DefaultValue(5), Category("Rows")] + [Description("Indicates the minimum row height.")] + public int MinRowHeight + { + get { return (_MinRowHeight); } + + set + { + if (value != _MinRowHeight) + { + if (value < 0) + throw new ArgumentException("Value must be 0 or greater."); + + _MinRowHeight = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("MinRowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region MouseEditMode + + /// + /// Gets or sets how cell editing is initiated by the mouse + /// + [DefaultValue(MouseEditMode.DoubleClick), Category("Behavior")] + [Description("Indicates how cell editing is initiated by the mouse.")] + public MouseEditMode MouseEditMode + { + get { return (_MouseEditMode); } + + set + { + if (value != _MouseEditMode) + { + _MouseEditMode = value; + + OnPropertyChanged("MinRowHeight"); + } + } + } + + #endregion + + #region MultiSelect + + /// + /// Gets or sets whether multiple items can be selected by the user + /// + [DefaultValue(true), Category("Selection")] + [Description("Indicates whether multiple items can be selected by the user.")] + public bool MultiSelect + { + get { return (TestState(Psp1.MultiSelect)); } + + set + { + if (value != MultiSelect) + { + SetState(Psp1.MultiSelect, value); + + OnPropertyChanged("MultiSelect"); + } + } + } + + #endregion + + #region Name + + /// + /// Gets or sets the Grid Panel name + /// + [DefaultValue("")] + [Description("Indicates the Grid Panel name.")] + public string Name + { + get { return (_Name); } + + set + { + if (_Name != value) + { + _Name = value; + + OnPropertyChanged("Name"); + } + } + } + + #endregion + + #region NestedListScanTypes + + /// + /// Gets or sets what IList "types" are scanned by the SuperGrid + /// when looking for possible "child" sub-panels in a bound IList data source. + /// + [DefaultValue(NestedListScanTypes.Fields), Category("Data")] + [Description("Indicates what IList 'types' are scanned by the SuperGrid when looking for possible 'child' sub-panels in a bound IList data source.")] + public NestedListScanTypes NestedListScanTypes + { + get { return (_NestedListScanTypes); } + + set + { + if (_NestedListScanTypes != value) + { + _NestedListScanTypes = value; + + OnPropertyChangedEx("NestedListScanTypes", VisualChangeType.Layout); + } + } + } + + #endregion + + #region NoRowsText + + /// + /// Gets or sets the text to show when there are no visible data Rows in the grid + /// + [Localizable(true), DefaultValue(null), Category("Appearance")] + [Description("Indicates the text to show when there are no visible data Rows in the grid.")] + public string NoRowsText + { + get { return (_NoRowsText); } + + set + { + if (_NoRowsText != value) + { + _NoRowsText = value; + + NoRowsMarkupTextChanged(); + + OnPropertyChangedEx("NoRowsText", VisualChangeType.Layout); + } + } + } + + #endregion + + #region NullString + + /// + /// Gets or sets how null values are displayed + /// + [Localizable(true), DefaultValue(""), Category("Data")] + [Description("Indicates how null values are displayed.")] + public string NullString + { + get { return (_NullString); } + + set + { + if (_NullString != value) + { + _NullString = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("NullString", VisualChangeType.Layout); + } + } + } + + #endregion + + #region NullValue + + /// + /// Gets or sets how null values are interpreted + /// + [DefaultValue(NullValue.DBNull), Category("Data")] + [Description("Indicates how null values are interpreted.")] + public NullValue NullValue + { + get { return (_NullValue); } + + set + { + if (_NullValue != value) + { + _NullValue = value; + + OnPropertyChangedEx("NullValue", VisualChangeType.Render); + } + } + } + + #endregion + + #region OnlySendFinalRowActivatedEvents + + /// + /// Gets or sets whether RowActivated events are sent for all rows + /// in the given parent chain, or only for the final active row. + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether RowActivated events are sent for all rows in the given parent chain, or only for the final active row.")] + public bool OnlySendFinalRowActivatedEvents + { + get { return (TestState(Psp1.OnlySendFinalRowActivatedEvents)); } + + set + { + if (value != OnlySendFinalRowActivatedEvents) + { + SetState(Psp1.OnlySendFinalRowActivatedEvents, value); + + OnPropertyChanged("OnlySendFinalRowActivatedEvents"); + } + } + } + + #endregion + + #region OnScreenColumns + + /// + /// IEnumerable that can be used to enumerate through + /// the current on-screen columns + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable OnScreenColumns + { + get { return (new OnScreenColumnsEnumeration(this)); } + } + + #endregion + + #region OnScreenRows + + /// + /// IEnumerable that can be used to enumerate through + /// the current on-screen rows + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable OnScreenRows + { + get { return (new OnScreenRowsEnumeration(this)); } + } + + #endregion + + #region PrimaryColumn + + /// + /// Gets the primary column. The Primary Columns will + /// contain (if enabled) the row checkbox and Tree lines + /// and expand / collapse button. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn PrimaryColumn + { + get + { + if ((uint)_PrimaryColumnIndex < _Columns.Count) + return (_Columns[_PrimaryColumnIndex]); + + return (null); + } + } + + #endregion + + #region PrimaryColumnIndex + + /// + /// Gets or sets the index of the primary column + /// + [DefaultValue(0), Category("Columns")] + [Description("Indicates the index of the primary column.")] + [Editor("DevComponents.SuperGrid.Design.ColumnListTypeEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + public int PrimaryColumnIndex + { + get { return (_PrimaryColumnIndex); } + + set + { + if (_PrimaryColumnIndex != value) + { + _PrimaryColumnIndex = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("PrimaryColumnIndex", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ProcessChildRelations + + /// + /// Gets or sets how the SuperGrid processes child relations + /// + [DefaultValue(ProcessChildRelations.Always), Category("Data")] + [Description("Indicates how the SuperGrid processes child relations.")] + public ProcessChildRelations ProcessChildRelations + { + get { return (_ProcessChildRelations); } + + set + { + if (_ProcessChildRelations != value) + { + _ProcessChildRelations = value; + + OnPropertyChangedEx("ProcessChildRelations", VisualChangeType.Layout); + } + } + } + + #endregion + + #region RowDoubleClickBehavior + + /// + /// Gets or sets the behavior when a row is double clicked + /// + [DefaultValue(RowDoubleClickBehavior.Activate), Category("Behavior")] + [Description("Indicates the behavior when a row is double clicked.")] + public RowDoubleClickBehavior RowDoubleClickBehavior + { + get { return (_RowDoubleClickBehavior); } + + set + { + if (_RowDoubleClickBehavior != value) + { + _RowDoubleClickBehavior = value; + + OnPropertyChanged("RowDoubleClickBehavior"); + } + } + } + + #endregion + + #region RowDragBehavior + + /// + /// Gets or sets the behavior when a row header is clicked and dragged + /// + [DefaultValue(RowDragBehavior.ExtendSelection), Category("Behavior")] + [Description("Indicates the behavior when a row header is clicked and dragged.")] + public RowDragBehavior RowDragBehavior + { + get { return (_RowDragBehavior); } + + set + { + if (value != _RowDragBehavior) + { + _RowDragBehavior = value; + + OnPropertyChanged("RowDragBehavior"); + } + } + } + + #endregion + + #region RowEditMode + + /// + /// Gets or sets whether editing is initiated on the primary cell + /// or the cell under the mouse when row level editing is enabled. + /// + [DefaultValue(RowEditMode.ClickedCell), Category("Behavior")] + [Description("Indicates whether editing is initiated on the primary cell or the cell under the mouse when row level editing is enabled")] + public RowEditMode RowEditMode + { + get { return (_RowEditMode); } + + set + { + if (value != _RowEditMode) + { + _RowEditMode = value; + + OnPropertyChanged("RowEditMode"); + } + } + } + + #endregion + + #region RowFocusMode + + /// + /// Gets or sets what portion of the row is "focused" when active. + /// + [DefaultValue(RowFocusMode.FullRow), Category("Appearance")] + [Description("Indicates what portion of the row is 'focused' when active")] + public RowFocusMode RowFocusMode + { + get { return (_RowFocusMode); } + + set + { + if (value != _RowFocusMode) + { + _RowFocusMode = value; + + OnPropertyChanged("RowFocusMode"); + } + } + } + + #endregion + + #region RowHeaderIndexOffset + + /// + /// Gets or sets the offset value used + /// to adjust the Index displayed in the row header. + /// + [DefaultValue(0), Category("Appearance")] + [Description("Indicates the offset value used to adjust the Index displayed in the row header")] + public int RowHeaderIndexOffset + { + get { return (_RowHeaderIndexOffset); } + + set + { + if (_RowHeaderIndexOffset != value) + { + _RowHeaderIndexOffset = value; + + OnPropertyChangedEx("RowHeaderIndexOffset", VisualChangeType.Render); + } + } + } + + #endregion + + #region RowHeaderWidth + + /// + /// Gets or sets the width of the row header + /// + [DefaultValue(35), Category("Rows")] + [Description("Indicates the width of the row header.")] + public int RowHeaderWidth + { + get { return (_RowHeaderWidth); } + + set + { + if (_RowHeaderWidth != value) + { + _RowHeaderWidth = value; + + NeedsMeasured = true; + + OnPropertyChangedEx("RowHeaderWidth", VisualChangeType.Layout); + } + } + } + + #endregion + + #region RowHighlightType + + /// + /// Gets or sets the type of highlighting + /// to use when a row is selected + /// + [DefaultValue(RowHighlightType.Full), Category("Selection")] + [Description("Indicates the type of highlighting to use when a row is selected.")] + public RowHighlightType RowHighlightType + { + get { return (_RowHighlightType); } + + set + { + if (value != _RowHighlightType) + { + _RowHighlightType = value; + + OnPropertyChanged("RowHeaderWidth"); + } + } + } + + #endregion + + #region RowWhitespaceClickBehavior + + /// + /// Gets or sets the behavior when the user + /// clicks the mouse in the row whitespace + /// + [DefaultValue(RowWhitespaceClickBehavior.ClearSelection), Category("Rows")] + [Description("Indicates the behavior when the user clicks the mouse in the row whitespace.")] + public RowWhitespaceClickBehavior RowWhitespaceClickBehavior + { + get { return (_RowWhitespaceClickBehavior); } + + set + { + if (value != _RowWhitespaceClickBehavior) + { + _RowWhitespaceClickBehavior = value; + + OnPropertyChanged("RowWhitespaceClickBehavior"); + } + } + } + + #endregion + + #region SelectedCellCount + + /// + /// Gets the current selected cell count + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectedCellCount + { + get + { + int n = 0; + + foreach (GridColumn column in Columns) + n += column.SelectedCellCount; + + return (n); + } + } + + #endregion + + #region SelectedCells + + /// + /// IEnumerable that can be used + /// to enumerate through all currently selected cells + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable SelectedCells + { + get { return (new SelectedCellsEnumeration(this)); } + } + + #endregion + + #region SelectedColumnCount + + /// + /// Gets the current selected column count + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectedColumnCount + { + get { return (_SelectedColumns.Count); } + } + + #endregion + + #region SelectedColumns + + /// + /// IEnumerable that can be used + /// to enumerate through all currently selected columns + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable SelectedColumns + { + get { return (new SelectedColumnsEnumeration(this, _SelectedColumns)); } + } + + #endregion + + #region SelectedRowCount + + /// + /// Gets the current selected row count + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectedRowCount + { + get { return (_SelectedRows.Count); } + } + + #endregion + + #region SelectedRows + + /// + /// IEnumerable that can be used + /// to enumerate through all currently selected rows + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable SelectedRows + { + get { return (new SelectedRowsEnumeration(this, _SelectedRows)); } + } + + #endregion + + #region SelectionGranularity + + /// + /// Gets or sets whether element selection + /// is at the row or cell level + /// + [DefaultValue(SelectionGranularity.Cell), Category("Selection")] + [Description("Indicates whether element selection is at the row or cell level.")] + public SelectionGranularity SelectionGranularity + { + get { return (_SelectionGranularity); } + + set + { + if (value != _SelectionGranularity) + { + _SelectionGranularity = value; + + if (SuperGrid != null) + SuperGrid.UpdateStyleCount(); + + OnPropertyChanged("SelectionGranularity"); + } + } + } + + #endregion + + #region ShowCellInfo + + /// + /// Gets or sets whether to show Cell Info Image and Text (if defined). + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether to show Cell Info Image and Text (if defined).")] + public bool ShowCellInfo + { + get { return (TestState(Psp1.ShowCellInfo)); } + + set + { + if (ShowCellInfo != value) + { + SetState(Psp1.ShowCellInfo, value); + + OnPropertyChangedEx("ShowCellInfo", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowCellInfoDisplayMode + + /// + /// Gets or sets when the CellInfoImage is displayed (either when the + /// associated InfoText is empty or not). + /// + [DefaultValue(ShowCellInfoDisplayMode.ShowWithNonEmptyText), Category("Appearance")] + [Description("Indicates when the CellInfoImage is displayed (either when the associated InfoText is empty or not).")] + public ShowCellInfoDisplayMode ShowCellInfoDisplayMode + { + get { return (_ShowCellInfoDisplayMode); } + + set + { + if (value != _ShowCellInfoDisplayMode) + { + _ShowCellInfoDisplayMode = value; + + OnPropertyChangedEx("ShowCellInfoDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowColumnHeader + + /// + /// Gets or sets whether the Column Header is displayed + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the Column Header is displayed.")] + public bool ShowColumnHeader + { + get { return (_ColumnHeader.Visible); } + + set + { + if (value != _ColumnHeader.Visible) + { + _ColumnHeader.Visible = value; + + OnPropertyChangedEx("ShowColumnHeader", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowDropShadow + + /// + /// Gets or sets whether nested Grid Panels display a drop shadow + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether nested Grid Panels display a drop shadow.")] + public bool ShowDropShadow + { + get { return (TestState(Psp1.ShowDropShadow)); } + + set + { + if (value != ShowDropShadow) + { + SetState(Psp1.ShowDropShadow, value); + + OnPropertyChangedEx("ShowDropShadow", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowEditingImage + + /// + /// Gets or sets whether the EditingRowImage is + /// displayed in the row header of the cell being edited. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the EditingRowImage is displayed in the row header of the cell being edited.")] + public bool ShowEditingImage + { + get { return (TestState(Psp1.ShowEditingImage)); } + + set + { + if (value != ShowEditingImage) + { + SetState(Psp1.ShowEditingImage, value); + + OnPropertyChanged("ShowEditingImage"); + } + } + } + + #endregion + + #region ShowGroupExpand + + /// + /// Gets or sets whether the expand button is shown in group headers + /// + [DefaultValue(true), Category("Group")] + [Description("Indicates whether the expand button is shown in group headers.")] + public bool ShowGroupExpand + { + get { return (TestState(Psp1.ShowGroupExpand)); } + + set + { + if (value != ShowGroupExpand) + { + SetState(Psp1.ShowGroupExpand, value); + + OnPropertyChangedEx("ShowGroupExpand", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowGroupUnderline + + /// + /// Gets or sets whether the Group header text is underlined + /// + [DefaultValue(true), Category("Group")] + [Description("Indicates whether the Group header text is underlined.")] + public bool ShowGroupUnderline + { + get { return (TestState(Psp1.ShowGroupUnderline)); } + + set + { + if (value != ShowGroupUnderline) + { + SetState(Psp1.ShowGroupUnderline, value); + + OnPropertyChangedEx("ShowGroupUnderline", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowInsertRow + + /// + /// Gets or sets whether the insert row is displayed + /// at the bottom of the panel for users to add new rows + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the insert row is displayed at the bottom of the panel for users to add new rows.")] + public bool ShowInsertRow + { + get { return (TestState(Psp1.ShowInsertRow)); } + + set + { + if (value != ShowInsertRow) + { + SetState(Psp1.ShowInsertRow, value); + + if (IsDesignerHosted == false) + { + if (value == true) + { + AddNewInsertRow(); + + LoadInsertRow = true; + } + else + { + RemoveNewInsertRow(); + } + } + + OnPropertyChangedEx("ShowInsertionRow", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowInsertRowImage + + /// + /// Gets or sets whether the InsertRowImage is + /// displayed in the row header of the Insert Row. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the InsertRowImage is displayed in the row header of the Insert Row.")] + public bool ShowInsertRowImage + { + get { return (TestState(Psp1.ShowInsertRowImage)); } + + set + { + if (value != ShowInsertRowImage) + { + SetState(Psp1.ShowInsertRowImage, value); + + OnPropertyChanged("ShowInsertRowImage"); + } + } + } + + #endregion + + #region ShowRowInfo + + /// + /// Gets or sets whether to show Row Info Image and Text (if defined) + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether to show Row Info Image and Text (if defined).")] + public bool ShowRowInfo + { + get { return (TestState(Psp1.ShowRowInfo)); } + + set + { + if (ShowRowInfo != value) + { + SetState(Psp1.ShowRowInfo, value); + + OnPropertyChangedEx("ShowRowInfo", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowRowInfoDisplayMode + + /// + /// Gets or sets when the RowInfoImage is displayed (either when the + /// associated InfoText is empty or not). + /// + [DefaultValue(ShowRowInfoDisplayMode.ShowWithNonEmptyText), Category("Appearance")] + [Description("Indicates when the RowInfoImage is displayed (either when the associated InfoText is empty or not).")] + public ShowRowInfoDisplayMode ShowRowInfoDisplayMode + { + get { return (_ShowRowInfoDisplayMode); } + + set + { + if (value != _ShowRowInfoDisplayMode) + { + _ShowRowInfoDisplayMode = value; + + OnPropertyChangedEx("ShowRowInfoDisplayMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowRowHeaders + + /// + /// Gets or sets whether row headers are displayed + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether row headers are displayed.")] + public bool ShowRowHeaders + { + get { return (TestState(Psp1.ShowRowHeaders)); } + + set + { + if (value != ShowRowHeaders) + { + SetState(Psp1.ShowRowHeaders, value); + + OnPropertyChangedEx("ShowRowHeaders", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowRowGridIndex + + /// + /// Gets or sets whether row + /// GridIndex values are displayed in the row headers. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether row GridIndex values are displayed in the row headers. A GridIndex is the 'logical' index for the current visible row.")] + public bool ShowRowGridIndex + { + get { return (TestState(Psp1.ShowRowGridIndex)); } + + set + { + if (ShowRowGridIndex != value) + { + SetState(Psp1.ShowRowGridIndex, value); + + OnPropertyChanged("ShowRowGridIndex"); + + if (ShowRowHeaders == true) + InvalidateRender(); + } + } + } + + #endregion + + #region ShowRowDirtyMarker + + /// + /// Gets or sets whether the DirtyRow marker is displayed, + /// signifying that the row data has been changed by the user + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the DirtyRow marker is displayed, signifying that the row data has been changed by the user.")] + public bool ShowRowDirtyMarker + { + get { return (TestState(Psp1.ShowRowDirtyMarker)); } + + set + { + if (ShowRowDirtyMarker != value) + { + SetState(Psp1.ShowRowDirtyMarker, value); + + OnPropertyChangedEx("ShowRowDirtyMarker", VisualChangeType.Render); + } + } + } + + #endregion + + #region ShowToolTips + + /// + /// Gets or sets whether tooltips are shown + /// for cell data that is truncated by the display + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether tooltips are shown for cell data that is truncated by the display.")] + public bool ShowToolTips + { + get { return (TestState(Psp1.ShowToolTips)); } + + set + { + if (value != ShowToolTips) + { + SetState(Psp1.ShowToolTips, value); + + OnPropertyChanged("ShowToolTips"); + } + } + } + + #endregion + + #region ShowTreeButtons + + /// + /// Gets or sets whether expand / collapse + /// buttons are shown for rows containing nested rows + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether Tree expand / collapse buttons are shown for rows containing nested rows.")] + public bool ShowTreeButtons + { + get { return (TestState(Psp1.ShowTreeButtons)); } + + set + { + if (ShowTreeButtons != value) + { + SetState(Psp1.ShowTreeButtons, value); + + OnPropertyChangedEx("ShowTreeButtons", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowTreeLines + + /// + /// Gets or sets whether hierarchical tree-lines + /// are shown connecting grid rows + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether hierarchical tree-lines are shown connecting grid rows.")] + public bool ShowTreeLines + { + get { return (TestState(Psp1.ShowTreeLines)); } + + set + { + if (ShowTreeLines != value) + { + SetState(Psp1.ShowTreeLines, value); + + OnPropertyChangedEx("ShowTreeLines", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ShowWhitespaceRowLines + + /// + /// Gets or sets whether the row lines are displayed in the Whitespace + /// area following the last visible column in the grid + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the row lines are displayed in the Whitespace area following the last visible column in the grid.")] + public bool ShowWhitespaceRowLines + { + get { return (TestState(Psp1.ShowWhitespaceRowLines)); } + + set + { + if (value != ShowWhitespaceRowLines) + { + SetState(Psp1.ShowWhitespaceRowLines, value); + + OnPropertyChangedEx("ShowWhitespaceRowLines", VisualChangeType.Render); + } + } + } + + #endregion + + #region SizingStyle + + /// + /// Gets or sets which Visual Display Style to use for element sizing + /// + [DefaultValue(StyleType.NotSet), Category("Style")] + [Description("Indicates which Visual Display Style to use for element sizing.")] + public StyleType SizingStyle + { + get { return (_SizingStyle); } + + set + { + if (_SizingStyle != value) + { + _SizingStyle = value; + + OnPropertyChangedEx("SizingStyle", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SortCycle + + /// + /// Gets or sets how each column sort direction cycles + /// when the column header is clicked to sort. + /// + [Browsable(true)] + [DefaultValue(SortCycle.NotSet), Category("Sorting")] + [Description("Indicates how each column sort direction cycles when the column header is clicked to sort.")] + public SortCycle SortCycle + { + get { return (_SortCycle); } + + set + { + if (_SortCycle != value) + { + _SortCycle = value; + + OnPropertyChanged("SortCycle"); + } + } + } + + #endregion + + #region SortColumns + + /// + /// Gets a reference to the list of columns to use for sorting the grid data. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public List SortColumns + { + get { return (_SortColumns); } + } + + #endregion + + #region SortLevel + + /// + /// Gets or sets the column sorting level. + /// + [DefaultValue(SortLevel.Root), Category("Appearance")] + [Description("Indicates the column sorting level.")] + public SortLevel SortLevel + { + get { return (_SortLevel); } + + set + { + if (value != _SortLevel) + { + _SortLevel = value; + + OnPropertyChangedEx("SortLevel", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SortUsingHiddenColumns + + /// + /// Gets or sets whether hidden Columns + /// are used when sorting the grid data + /// + [DefaultValue(false), Category("Behavior")] + [Description("Indicates whether hidden Columns are used when sorting the grid data.")] + public bool SortUsingHiddenColumns + { + get { return (TestState(Psp1.SortUsingHiddenColumns)); } + + set + { + if (SortUsingHiddenColumns != value) + { + SetState(Psp1.SortUsingHiddenColumns, value); + + if (SortColumns != null && SortColumns.Count > 0) + NeedsSorted = true; + + OnPropertyChangedEx("SortUsingHiddenColumns", VisualChangeType.Render); + } + } + } + + #endregion + + #region Title + + /// + /// Gets or sets the item which is displayed just above + /// the Column Header. The Title area is fixed and it does + /// not move as grid rows are scrolled. + /// + [Category("Header,Footer...")] + [Description("Indicates the Title item, which is displayed just above the Column Header. The Title area is fixed and it does not move as grid rows are scrolled.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridTitle Title + { + get + { + if (_Title == null) + Title = new GridTitle(); + + return (_Title); + } + + set + { + if (_Title != value) + { + if (value != null) + { + if (value.Parent != null) + throw new ArgumentException("Item assigned as Title already has a parent."); + } + + _Title = value; + + if (_Title != null) + _Title.Parent = this; + + NeedsMeasured = true; + + OnPropertyChangedEx("Title", VisualChangeType.Layout); + } + } + } + + #endregion + + #region TopLeftHeaderSelectBehavior + + /// + /// Gets or sets the behavior that occurs when + /// the top left header is selected by the user + /// + [DefaultValue(TopLeftHeaderSelectBehavior.Deterministic), Category("Behavior")] + [Description("Indicates the behavior that occurs when the top left header is selected by the user.")] + public TopLeftHeaderSelectBehavior TopLeftHeaderSelectBehavior + { + get { return (_TopLeftHeaderSelectBehavior); } + + set + { + if (value != _TopLeftHeaderSelectBehavior) + { + _TopLeftHeaderSelectBehavior = value; + + OnPropertyChangedEx("TopLeftHeaderSelectBehavior", VisualChangeType.Render); + } + } + } + + #endregion + + #region UseAlternateColumnStyle + + /// + /// Gets or sets whether the AlternateColumn Style is used + /// + [DefaultValue(false), Category("Style")] + [Description("Indicates whether the AlternateColumn Style is used.")] + public bool UseAlternateColumnStyle + { + get { return (TestState(Psp0.UseAlternateColumnStyle)); } + + set + { + if (value != UseAlternateColumnStyle) + { + SetState(Psp0.UseAlternateColumnStyle, value); + + if (SuperGrid != null) + SuperGrid.UpdateStyleCount(); + + OnPropertyChangedEx("UseAlternateColumnStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #region UseAlternateRowStyle + + /// + /// Gets or sets whether the AlternateRow Style is used + /// + [DefaultValue(false), Category("Style")] + [Description("Indicates whether the AlternateRow Style is used")] + public bool UseAlternateRowStyle + { + get { return (TestState(Psp0.UseAlternateRowStyle)); } + + set + { + if (value != UseAlternateRowStyle) + { + SetState(Psp0.UseAlternateRowStyle, value); + + if (SuperGrid != null) + SuperGrid.UpdateStyleCount(); + + OnPropertyChangedEx("UseAlternateRowStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #region VirtualMode + + /// + /// Gets or sets whether the grid data is virtualized (i.e. external to the grid) + /// + [DefaultValue(false), Category("Virtual Mode")] + [Description("Indicates whether the grid data is virtualized (ie. external to the grid).")] + public bool VirtualMode + { + get { return (TestState(Psp1.VirtualMode)); } + + set + { + if (VirtualMode != value) + { + SetState(Psp1.VirtualMode, value); + + _VirtualRowCount = DataBinder.RowCount; + + NeedToUpdateBindings = true; + NeedsSorted = true; + + if (value == true) + { + _VirtualRows = new GridVirtualRows(this); + + if (ShowInsertRow == true) + { + Rows.FloatLastItem = false; + + AddNewInsertRow(); + } + + Rows.Clear(); + } + else + { + _VirtualRowCount = 0; + + _VirtualRows.Clear(); + _VirtualRows = null; + + if (ShowInsertRow == true) + AddNewInsertRow(); + } + + UpdateVisibleRowCount(); + + OnPropertyChangedEx("VirtualMode", VisualChangeType.Layout); + } + } + } + + #endregion + + #region VirtualRowCount + + /// + /// Gets or sets the number of virtual grid rows + /// + [DefaultValue(0), Category("Virtual Mode")] + [Description("Indicates the number of virtual grid rows.")] + public int VirtualRowCount + { + get + { + if (VirtualMode == true && ShowInsertRow == true) + return (_VirtualRowCount - 1); + + return (_VirtualRowCount); + } + + set + { + if (VirtualMode == true) + { + if (value < 0) + value = 0; + + int n = (ShowInsertRow == true) ? 1 : 0; + + if (_VirtualRowCount != value + n) + { + if (SuperGrid != null) + { + if (SuperGrid.ActiveRow != null) + SuperGrid.ActiveRow.FlushRow(); + } + + if (ShowInsertRow == true) + RemoveNewInsertRow(); + + if (value == 0) + { + _VirtualRows.Clear(); + + ClearAll(); + } + else + { + int count = _VirtualRowCount - value; + + if (count > 0) + { + SetSelectedCells(value, 0, count, Columns.Count, false); + SetSelectedRows(value, count, false); + } + + _VirtualRows.MaxRowIndex = value; + } + + _VirtualRowCount = value; + + if (ShowInsertRow == true) + AddNewInsertRow(); + + _VisibleRowCount = _VirtualRowCount; + + if (ActiveRow != null && ActiveRow.RowIndex >= _VirtualRowCount) + ActiveRow = null; + + OnPropertyChangedEx("VirtualRowCount", VisualChangeType.Layout); + } + } + else + { + if (_VirtualRowCount != value) + { + _VirtualRowCount = value; + + OnPropertyChangedEx("VirtualRowCount", VisualChangeType.Layout); + } + } + } + } + + #endregion + + #region VirtualRowHeight + + /// + /// Gets or sets the height of every virtual row + /// + [DefaultValue(22), Category("Virtual Mode")] + [Description("Indicates the height of every virtual row.")] + public int VirtualRowHeight + { + get { return (_VirtualRowHeight); } + + set + { + if (_VirtualRowHeight != value) + { + if (value < 0) + throw new Exception("Row height must be non-negative"); + + _VirtualRowHeight = value; + + OnPropertyChangedEx("VirtualRowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region VirtualRows + + /// + /// Gets the Virtual Mode rows collection object + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridVirtualRows VirtualRows + { + get { return (_VirtualRows); } + } + + #endregion + + #region VisibleColumnCount + + /// + /// Gets the current visible column count + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int VisibleColumnCount + { + get + { + int count = 0; + + GridColumnCollection columns = Columns; + foreach (GridColumn column in columns) + { + if (column.Visible == true) + count++; + } + + return (count); + } + } + + #endregion + + #region VisibleRowCount + + /// + /// Gets the current visible row count + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int VisibleRowCount + { + get + { + if (SuperGrid != null) + { + if (IsLayoutValid == false) + SuperGrid.ArrangeGrid(); + } + + return (_VisibleRowCount); + } + } + + #endregion + + #region WhitespaceClickBehavior + + /// + /// Gets or sets the behavior when the user + /// clicks the mouse in the grid panel whitespace + /// + [DefaultValue(WhitespaceClickBehavior.ClearSelection), Category("Behavior")] + [Description("Indicates the behavior when the user clicks the mouse in the grid panel whitespace.")] + public WhitespaceClickBehavior WhitespaceClickBehavior + { + get { return (_WhitespaceClickBehavior); } + + set + { + if (value != _WhitespaceClickBehavior) + { + _WhitespaceClickBehavior = value; + + OnPropertyChanged("WhitespaceClickBehavior"); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region CollapseButtonHotImage + + internal Image CollapseButtonHotImage + { + get { return (_CollapseButtonHotImage); } + + set + { + if (_CollapseButtonHotImage != null) + _CollapseButtonHotImage.Dispose(); + + _CollapseButtonHotImage = value; + } + } + + #endregion + + #region CollapseButtonImage + + internal Image CollapseButtonImage + { + get { return (_CollapseButtonImage); } + + set + { + if (_CollapseButtonImage != null) + _CollapseButtonImage.Dispose(); + + _CollapseButtonImage = value; + } + } + + #endregion + + #region DataBinder + + internal DataBinder DataBinder + { + get + { + if (_DataBinder == null) + _DataBinder = new DataBinder(this); + + return (_DataBinder); + } + + set + { + if (_DataBinder != null) + _DataBinder.Clear(); + + _DataBinder = value; + } + } + + #endregion + + #region DataRelation + + internal DataRelation DataRelation + { + get { return (_DataRelation); } + set { _DataRelation = value; } + } + + #endregion + + #region DeleteUpdateCount + + internal ushort DeleteUpdateCount + { + get { return (_DeleteUpdateCount); } + set { _DeleteUpdateCount = value; } + } + + #endregion + + #region EnsureRowVisible + + internal bool EnsureRowVisible + { + get { return (TestState(Psi.EnsureRowVisible)); } + set { SetState(Psi.EnsureRowVisible, value); } + } + + #endregion + + #region ExpandButtonHotImage + + internal Image ExpandButtonHotImage + { + get { return (_ExpandButtonHotImage); } + + set + { + if (_ExpandButtonHotImage != null) + _ExpandButtonHotImage.Dispose(); + + _ExpandButtonHotImage = value; + } + } + + #endregion + + #region ExpandButtonImage + + internal Image ExpandButtonImage + { + get { return (_ExpandButtonImage); } + + set + { + if (_ExpandButtonImage != null) + _ExpandButtonImage.Dispose(); + + _ExpandButtonImage = value; + } + } + + #endregion + + #region ExpandedUpdateCount + + internal ushort ExpandedUpdateCount + { + get { return (_ExpandedUpdateCount); } + set { _ExpandedUpdateCount = value; } + } + + #endregion + + #region ExpDictionary + + internal Dictionary ExpDictionary + { + get { return (_ExpDictionary); } + } + + #endregion + + #region FilterEval + + internal FilterEval FilterEval + { + get { return (_FilterEval); } + set { _FilterEval = value; } + } + + #endregion + + #region HasDeletedRows + + internal bool HasDeletedRows + { + get { return (_DeletedRows.FirstIndex >= 0); } + } + + #endregion + + #region HotItem + + internal GridContainer HotItem + { + get { return (_HotItem); } + + set + { + if (_HotItem != value) + { + GridContainer oldValue = _HotItem; + _HotItem = value; + + if (ShowRowHeaders == true) + { + if (oldValue != null) + InvalidateRowHeader(oldValue); + + if (_HotItem != null) + InvalidateRowHeader(_HotItem); + } + } + } + } + + #endregion + + #region InRangeAdd + + internal bool InRangeAdd + { + get { return (TestState(Psi.InRangeAdd)); } + set { SetState(Psi.InRangeAdd, value); } + } + + #endregion + + #region InternalDeletedRows + + /// + /// InternalDeletedRows + /// + internal SelectedElements InternalDeletedRows + { + get { return (_DeletedRows); } + } + + #endregion + + #region InternalSelectedRows + + internal SelectedElements InternalSelectedRows + { + get { return (_SelectedRows); } + } + + #endregion + + #region IsRowMoving + + internal bool IsRowMoving + { + get { return (TestState(Psi.IsRowMoving)); } + set { SetState(Psi.IsRowMoving, value); } + } + + #endregion + + #region IsSorting + + internal bool IsSorting + { + get { return (TestState(Psi.IsSorting)); } + set { SetState(Psi.IsSorting, value); } + } + + #endregion + + #region LastProcessedItem + + internal GridElement LastProcessedItem + { + get { return (_LastProcessedItem); } + + set + { + _LastProcessedItem = value; + + SuperGrid.ActiveElement = value; + } + } + + #endregion + + #region LatentActiveCellIndex + + internal int LatentActiveCellIndex + { + get { return (_LatentActiveCellIndex); } + set { _LatentActiveCellIndex = value; } + } + + #endregion + + #region LatentActiveContainer + + internal GridContainer LatentActiveContainer + { + get { return (_LatentActiveContainer); } + set { _LatentActiveContainer = value; } + } + + #endregion + + #region LatentActiveRowIndex + + internal int LatentActiveRowIndex + { + get { return (_LatentActiveRowIndex); } + set { _LatentActiveRowIndex = value; } + } + + #endregion + + #region LoadInsertRow + + internal bool LoadInsertRow + { + get { return (TestState(Psi.LoadInsertRow)); } + set { SetState(Psi.LoadInsertRow, value); } + } + + #endregion + + #region NeedsFilterScan + + internal bool NeedsFilterScan + { + get { return (TestState(Psi.NeedsFilterScan)); } + set { SetState(Psi.NeedsFilterScan, value); } + } + + #endregion + + #region NeedsGrouped + + internal bool NeedsGrouped + { + get { return (TestState(Psi.NeedsGrouped)); } + set { SetState(Psi.NeedsGrouped, value); } + } + + #endregion + + #region NeedsGroupSorted + + internal bool NeedsGroupSorted + { + get { return (TestState(Psi.NeedsGroupSorted)); } + set { SetState(Psi.NeedsGroupSorted, value); } + } + + #endregion + + #region NeedsSorted + + internal bool NeedsSorted + { + get { return (TestState(Psi.NeedsSorted)); } + set { SetState(Psi.NeedsSorted, value); } + } + + #endregion + + #region NeedToUpdateBindings + + internal bool NeedToUpdateBindings + { + get { return (TestState(Psi.NeedToUpdateBindings)); } + + set + { + SetState(Psi.NeedToUpdateBindings, value); + + if (value == true) + NeedToUpdateBoundData = true; + } + } + + #endregion + + #region NeedToUpdateBoundData + + internal bool NeedToUpdateBoundData + { + get { return (TestState(Psi.NeedToUpdateBoundData)); } + set { SetState(Psi.NeedToUpdateBoundData, value); } + } + + #endregion + + #region NeedToUpdateDataFilter + + internal bool NeedToUpdateDataFilter + { + get { return (TestState(Psi.NeedToUpdateDataFilter)); } + + set + { + if (NeedToUpdateDataFilter != value) + { + SetState(Psi.NeedToUpdateDataFilter, value); + + if (value == true) + { + if (SuperGrid != null) + SuperGrid.UpdateStyleCount(); + + InvalidateMerge(); + } + } + } + } + + #endregion + + #region NeedToUpdateIndicees + + internal bool NeedToUpdateIndicees + { + get + { + if (SuperGrid != null) + return (SuperGrid.IndiceesUpdateCount != _IndiceesUpdateCount); + + return (false); + } + + set + { + if (SuperGrid != null) + { + if (value == true) + _IndiceesUpdateCount = (ushort)(SuperGrid.IndiceesUpdateCount - 1); + else + _IndiceesUpdateCount = SuperGrid.IndiceesUpdateCount; + } + } + } + + #endregion + + #region NewFullIndex + + internal int NewFullIndex + { + get { return (_NewFullIndex); } + set { _NewFullIndex = value; } + } + + #endregion + + #region NewIndex + + internal int NewIndex + { + get { return (_NewIndex); } + set { _NewIndex = value; } + } + + #endregion + + #region PanelBounds + + internal Rectangle PanelBounds + { + get + { + Rectangle r = BoundsRelative; + + if (IsVFrozen == false) + { + if (IsSubPanel == true) + r.X -= HScrollOffset; + + r.Y -= VScrollOffset; + } + + if (_Caption != null && _Caption.Visible == true) + { + r.Y += _Caption.Size.Height; + r.Height -= _Caption.Size.Height; + } + + if (IsSubPanel == true) + { + r.Y--; + r.Height++; + } + + return (r); + } + } + + #endregion + + #region PreActiveRowDirty + + internal bool PreActiveRowDirty + { + get { return (TestState(Psi.PreActiveRowDirty)); } + set { SetState(Psi.PreActiveRowDirty, value); } + } + + #endregion + + #region RenderCount + + internal ushort RenderCount + { + get { return (_RenderCount); } + set { _RenderCount = value; } + } + + #endregion + + #region ReselectActiveItem + + internal bool ReselectActiveItem + { + get { return (TestState(Psi.ReselectActiveItem)); } + set { SetState(Psi.ReselectActiveItem, value); } + } + + #endregion + + #region RowHeaderWidthEx + + internal int RowHeaderWidthEx + { + get { return (_RowHeaderWidthEx); } + } + + #endregion + + #region RowHeaderSize + + internal Size RowHeaderSize + { + get { return (_RowHeaderSize); } + set { _RowHeaderSize = value; } + } + + #endregion + + #region SelectActiveRow + + internal bool SelectActiveRow + { + get { return (TestState(Psi.SelectActiveRow)); } + set { SetState(Psi.SelectActiveRow, value); } + } + + #endregion + + #region SelectionClearCount + + internal ushort SelectionClearCount + { + get { return (_SelectionClearCount); } + set { _SelectionClearCount = value; } + } + + #endregion + + #region SelectionColumnAnchor + + internal object SelectionColumnAnchor + { + get { return (_SelectionColumnAnchor); } + set { _SelectionColumnAnchor = value; } + } + + #endregion + + #region SelectionRowAnchor + + internal GridContainer SelectionRowAnchor + { + get { return (_SelectionRowAnchor); } + set { _SelectionRowAnchor = value; } + } + + #endregion + + #region SelectionUpdateCount + + internal ushort SelectionUpdateCount + { + get { return (_SelectionUpdateCount); } + set { _SelectionUpdateCount = value; } + } + + #endregion + + #region SizeNeeded + + internal Size SizeNeeded + { + get { return (_SizeNeeded); } + set { _SizeNeeded = value; } + } + + #endregion + + #region TreeButtonIndent + + internal int TreeButtonIndent + { + get + { + int n = 20; + + if (_ExpandImage != null) + n = Math.Max(n, _ExpandImage.Width + 4); + + if (_CollapseImage != null) + n = Math.Max(n, _CollapseImage.Width + 4); + + return (Dpi.Width(n)); + } + } + + #endregion + + #region VirtualInsertRow + + internal GridRow VirtualInsertRow + { + get { return (_VirtualInsertRow); } + set { _VirtualInsertRow = value; } + } + + #endregion + + #region VirtualTempInsertRow + + internal GridRow VirtualTempInsertRow + { + get { return (_VirtualTempInsertRow); } + set { _VirtualTempInsertRow = value; } + } + + #endregion + + #region VirtualRowCountEx + + internal int VirtualRowCountEx + { + get { return (_VirtualRowCount); } + set { _VirtualRowCount = value; } + } + + #endregion + + #endregion + + #region TestState + + private bool TestState(Psp0 state) + { + return ((_Psp0 & state) == state); + } + + private bool TestState(Psp1 state) + { + return ((_Psp1 & state) == state); + } + + private bool TestState(Psi state) + { + return ((_Psi & state) == state); + } + + #endregion + + #region SetState + + private void SetState(Psp0 state, bool value) + { + if (value == true) + _Psp0 |= state; + else + _Psp0 &= ~state; + } + + private void SetState(Psp1 state, bool value) + { + if (value == true) + _Psp1 |= state; + else + _Psp1 &= ~state; + } + + private void SetState(Psi state, bool value) + { + if (value == true) + _Psi |= state; + else + _Psi &= ~state; + } + + #endregion + + #region MeasureOverride + + /// + /// Performs the layout of the item and sets + /// the Size property to size that item will take. + /// + /// Layout information. + /// + /// + protected override void MeasureOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + Size sizeNeeded = new Size(); + + if (NeedToUpdateBindings == true) + { + if (_LatentActiveRowIndex < 0 && _ActiveRow != null) + { + _LatentActiveCellIndex = -1; + _LatentActiveRowIndex = _ActiveRow.RowIndex; + _LatentActiveContainer = _ActiveRow.Parent as GridContainer; + + if (_LastProcessedItem is GridCell) + _LatentActiveCellIndex = ((GridCell)_LastProcessedItem).ColumnIndex; + } + } + + if (stateInfo.PassCount == 0) + { + _RowHeaderWidthEx = Dpi.Width(_RowHeaderWidth); + + UpdateDataBindings(); + + if (VirtualMode == true) + UpdateOrderLayout(); + + UpdateDataFiltering(); + + if (VirtualMode == false) + UpdateOrderLayout(); + + LoadLatentInsertRow(); + } + + GridPanel panel = stateInfo.GridPanel; + + if (panel.VirtualMode == false) + UpdateIndicees(panel, panel.Rows, true); + + if (ReselectActiveItem == true) + { + ReselectActiveItem = false; + + if (SuperGrid.ActiveElement != null) + { + if (SuperGrid.ActiveElement is GridCell) + ((GridCell)SuperGrid.ActiveElement).IsSelected = true; + + else if (SuperGrid.ActiveElement is GridContainer) + ((GridContainer)SuperGrid.ActiveElement).IsSelected = true; + } + } + + MeasureColumnHeader(layoutInfo, stateInfo, constraintSize); + MeasureColumns(layoutInfo, stateInfo, ref sizeNeeded); + MeasureColumnHeader(layoutInfo, stateInfo, ref sizeNeeded); + MeasureRows(layoutInfo, stateInfo, constraintSize, ref sizeNeeded); + + SizeColumns(ref sizeNeeded); + SizeColumnHeader(layoutInfo, ref sizeNeeded); + + MeasureElement(_Caption, layoutInfo, stateInfo, ref sizeNeeded); + MeasureElement(_Title, layoutInfo, stateInfo, ref sizeNeeded); + MeasureElement(_Filter, layoutInfo, stateInfo, ref sizeNeeded); + MeasureElement(_Header, layoutInfo, stateInfo, ref sizeNeeded); + MeasureElement(_GroupByRow, layoutInfo, stateInfo, ref sizeNeeded); + MeasureElement(_Footer, layoutInfo, stateInfo, ref sizeNeeded); + + if (Parent != null) + sizeNeeded.Width += 5; + + Size = sizeNeeded; + SizeNeeded = sizeNeeded; + } + + #region LoadLatentInsertRow + + private void LoadLatentInsertRow() + { + if (LoadInsertRow == true) + { + LoadInsertRow = false; + + if (VirtualMode == false && Rows.FloatLastItem == true) + { + GridRow row = Rows[Rows.Count - 1] as GridRow; + + if (row != null) + { + row.RowIndex = Rows.Count - 1; + + for (int i = row.Cells.Count; i < _Columns.Count; i++) + row.Cells.Add(new GridCell()); + + // Make sure we reset any previous set default value, + // and then get any newly set default values. + + for (int i = 0; i < _Columns.Count; i++) + { + if (row.Cells[i] != null) + row.Cells[i].ValueExx = null; + } + + DataBinder.GetDefaultValues(row); + } + } + } + } + + #endregion + + #region UpdateOrderLayout + + internal void UpdateOrderLayout() + { + if (VirtualMode == false) + UpdateRealOrderLayout(); + else + UpdateVirtualOrderLayout(); + } + + #region UpdateRealOrderLayout + + private void UpdateRealOrderLayout() + { + if (NeedsGrouped || NeedsGroupSorted || NeedsSorted) + { + if (SuperGrid.DoLayoutOrderUpdatingEvent(this) == false) + { + if (CanReselectActiveItem() == true) + ReselectActiveItem = true; + + if (_ActiveRow != null) + _ActiveRow.FlushRow(); + + ClearAll(false); + + bool hasDeleted = HasDeletedRows; + + PushDeletedRows(Rows); + + if (NeedsGrouped || NeedsGroupSorted) + { + bool groupChanged = false; + + if (NeedsGrouped == true) + groupChanged |= GroupItems(); + + if (NeedsGroupSorted == true) + groupChanged |= GroupSort(); + + if (groupChanged == true) + { + if (EnsureVisibleAfterGrouping == true && ActiveRow != null) + EnsureRowVisible = true; + + if (AutoExpandSetGroup == true) + ExpandAll(); + } + } + + if (NeedsSorted == true) + { + if (EnsureVisibleAfterSort == true && ActiveRow != null) + EnsureRowVisible = true; + + SortItems(); + } + + if (hasDeleted == true) + { + UnDeleteAll(); + + UpdateRowDelete(Rows); + } + + SuperGrid.DoLayoutOrderUpdatedEvent(this); + } + else + { + NeedsSorted = NeedsGrouped = NeedsGroupSorted = false; + } + } + } + + #region PushDeletedRows + + private void PushDeletedRows(GridItemsCollection rows) + { + foreach (GridContainer row in rows) + { + if (row.IsDeleted == true) + row.IsDeletedEx = true; + + if (row.Rows != null && row.Rows.Count > 0) + PushDeletedRows(row.Rows); + } + } + + #endregion + + #region UpdateRowDelete + + private void UpdateRowDelete(GridItemsCollection rows) + { + foreach (GridContainer row in rows) + { + row.IsDeleted = row.IsDeletedEx; + + if (row.Rows != null && row.Rows.Count > 0) + UpdateRowDelete(row.Rows); + } + } + + #endregion + + #endregion + + #region UpdateVirtualOrderLayout + + private void UpdateVirtualOrderLayout() + { + if (NeedsSorted == true) + { + NeedsSorted = false; + + if (SuperGrid.DoLayoutOrderUpdatingEvent(this) == false) + { + DataBinder.UpdateDataSourceSort(); + + ClearAll(false); + + InvalidateMerge(); + + SuperGrid.DoLayoutOrderUpdatedEvent(this); + } + } + } + + #endregion + + #region CanReselectActiveItem + + private bool CanReselectActiveItem() + { + if (LatentActiveRowIndex < 0) + { + GridElement item = SuperGrid.ActiveElement; + + if (item != null) + { + if (item is GridCell) + return ((GridCell)item).IsSelected; + + else if (item is GridContainer) + return ((GridContainer)item).IsSelected; + } + } + + return (false); + } + + #endregion + + #endregion + + #region UpdateIndicees + + internal void UpdateIndicees( + GridPanel panel, GridItemsCollection items, bool vis) + { + if (NeedToUpdateIndicees == true) + { + NeedToUpdateIndicees = false; + + _NewFullIndex = 0; + _NewGridIndex = 0; + + UpdateIndiceesEx(panel, items, vis); + + panel.TruncateGridIndexArray(); + panel.UpdateVisibleRowCount(); + } + } + + private void UpdateIndiceesEx( + GridPanel panel, GridItemsCollection items, bool vis) + { + int index = 0; + + for (int i = 0; i < items.Count; i++) + { + GridContainer row = items[i] as GridContainer; + + if (row != null) + { + row.RowIndex = i; + row.FullIndex = _NewFullIndex++; + + bool rowVisible = (vis == true && row.Visible); + + if (rowVisible == true) + { + row.Index = index++; + row.GridIndex = panel.GetNewGridIndex(row); + } + + if (row is GridPanel == false) + UpdateIndiceesEx(panel, row.Rows, rowVisible && row.Expanded); + } + } + } + + #endregion + + #region MeasureColumnHeader + + private void MeasureColumnHeader( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + GridColumnHeader columnHeader = _ColumnHeader; + + if (columnHeader != null) + columnHeader.Measure(layoutInfo, stateInfo, constraintSize); + } + + private void MeasureColumnHeader(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ref Size sizeNeeded) + { + GridColumnHeader columnHeader = _ColumnHeader; + + if (columnHeader != null) + { + columnHeader.Measure(layoutInfo, stateInfo, new Size(1, 0)); + + if (columnHeader.Visible == true) + sizeNeeded.Height += columnHeader.Size.Height; + else + sizeNeeded.Height++; + } + } + + #endregion + + #region MeasureColumns + + private void MeasureColumns(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ref Size sizeNeeded) + { + int fillBase; + int noFillWidth; + + CalculateFillData(layoutInfo, + stateInfo, out fillBase, out noFillWidth); + + int width = CalculateColumnWidths( + layoutInfo, fillBase, noFillWidth); + + if (ShowRowHeaders == true) + width += RowHeaderWidthEx; + + sizeNeeded.Width = Math.Max(width, sizeNeeded.Width); + } + + #region CalculateFillData + + private void CalculateFillData(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, out int fillBase, out int noFillWidth) + { + fillBase = 0; + noFillWidth = 0; + + if (ShowRowHeaders == true) + noFillWidth += RowHeaderWidthEx; + + GridColumnCollection columns = _Columns; + foreach (GridColumn column in columns) + { + if (column.Visible == true) + { + if (VirtualMode == true) + { + switch (GetAutoSizeMode(column)) + { + case ColumnAutoSizeMode.None: + case ColumnAutoSizeMode.ColumnHeader: + break; + + default: + column.NeedsMeasured = true; + break; + } + } + + column.Measure(layoutInfo, stateInfo, Size.Empty); + + if (GetAutoSizeMode(column) == ColumnAutoSizeMode.Fill) + fillBase += column.FillWeight; + else + noFillWidth += column.Size.Width; + } + } + } + + #endregion + + #region CalculateColumnWidths + + private int CalculateColumnWidths( + GridLayoutInfo layoutInfo, int fillBase, int noFillWidth) + { + int width = 0; + int n = layoutInfo.ClientBounds.Width - noFillWidth; + + GridColumn lastColumn = _Columns.LastVisibleColumn; + + GridColumnCollection columns = _Columns; + + int[] map = columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + Size size = column.Size; + ColumnAutoSizeMode autoSizeMode = GetAutoSizeMode(column); + + if (fillBase > 0 && autoSizeMode == ColumnAutoSizeMode.Fill) + { + if (column.FillWeight == 0) + { + size.Width = Dpi.Width(column.MinimumWidth); + } + else + { + if (column == lastColumn) + { + size.Width = layoutInfo.ClientBounds.Right - width; + + if (IsSubPanel == false) + { + if (SuperGrid.VScrollBarVisible && (Size.Height - _WhiteSpaceRect.Height >= layoutInfo.ClientBounds.Height)) + size.Width--; + } + + if (ShowRowHeaders == true) + size.Width -= RowHeaderWidthEx; + } + else + { + size.Width = (int)(n * (float)column.FillWeight / fillBase); + } + } + } + else if (autoSizeMode == ColumnAutoSizeMode.None) + { + size.Width = Dpi.Width(column.Width); + } + + size.Width = Math.Max(size.Width, column.MinimumWidth); + + if (column.Size.Width != size.Width) + { + column.Size = size; + + SuperGrid.DoColumnResizedEvent(this, column); + } + + width += size.Width; + } + } + + return (width); + } + + #endregion + + #endregion + + #region MeasureRows + + private void MeasureRows(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Size constraintSize, ref Size sizeNeeded) + { + if (VirtualMode == true) + MeasureVirtualRows(layoutInfo, stateInfo, constraintSize, ref sizeNeeded); + else + MeasureRealRows(layoutInfo, stateInfo, constraintSize, ref sizeNeeded); + } + + #region MeasureVirtualRows + + private void MeasureVirtualRows(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Size constraintSize, ref Size sizeNeeded) + { + if (VirtualRowCountEx > 0) + { + int vrh = Dpi.Height(stateInfo.GridPanel.VirtualRowHeight); + + try + { + sizeNeeded.Height = + checked(sizeNeeded.Height + vrh * VirtualRowCountEx); + } + catch (System.OverflowException e) + { + sizeNeeded.Height = int.MaxValue - 100; + } + } + else + { + Size size = MeasureWhiteSpaceText(layoutInfo, constraintSize); + + sizeNeeded.Height += size.Height; + } + } + + #endregion + + #region MeasureRealRows + + private void MeasureRealRows(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Size constraintSize, ref Size sizeNeeded) + { + RowHeaderSize = Size.Empty; + Rectangle r = Rectangle.Empty; + + constraintSize.Width = sizeNeeded.Width; + + GridItemsCollection items = Rows; + foreach (GridElement item in items) + { + if (item is GridTextRow == false) + { + if (item.Visible == true) + { + item.Measure(layoutInfo, stateInfo, constraintSize); + + r.Y += item.Size.Height; + + sizeNeeded.Height += item.Size.Height; + sizeNeeded.Width = Math.Max(item.Size.Width, sizeNeeded.Width); + } + else + { + item.BoundsRelative = r; + } + } + } + + if (_VisibleRowCount == 0) + { + Size size = MeasureWhiteSpaceText(layoutInfo, constraintSize); + + sizeNeeded.Height += size.Height; + } + } + + #region MeasureWhiteSpaceText + + private Size MeasureWhiteSpaceText( + GridLayoutInfo layoutInfo, Size constraintSize) + { + Size size = Size.Empty; + + if (String.IsNullOrEmpty(_NoRowsText) == false) + { + GridPanelVisualStyle style = GetEffectiveStyle(); + + constraintSize.Width = BoundsRelative.Width - Dpi.Width13; + + if (_NoRowsMarkup != null) + { + size = GetMarkupTextSize(layoutInfo, style, constraintSize.Width); + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + size = TextHelper.MeasureText( + layoutInfo.Graphics, _NoRowsText, style.Font, constraintSize, tf); + } + + size.Height += Dpi.Height10; + } + + return (size); + } + + #region GetMarkupTextSize + + private Size GetMarkupTextSize( + GridLayoutInfo layoutInfo, GridPanelVisualStyle style, int width) + { + Graphics g = layoutInfo.Graphics; + + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + _NoRowsMarkup.InvalidateElementsSize(); + _NoRowsMarkup.Measure(new Size(width, 0), d); + + return (_NoRowsMarkup.Bounds.Size); + } + + #endregion + + #endregion + + #endregion + + #region SizeColumns + + private void SizeColumns(ref Size sizeNeeded) + { + GridColumnCollection columns = _Columns; + foreach (GridColumn column in columns) + { + if (column.Visible == true) + { + Size size = column.Size; + size.Height = sizeNeeded.Height; + + if (ColumnHeader.Visible == true) + size.Height -= ColumnHeader.Size.Height; + + column.Size = size; + } + } + } + + #endregion + + #region SizeColumnHeader + + private void SizeColumnHeader( + GridLayoutInfo layoutInfo, ref Size sizeNeeded) + { + GridColumnHeader columnHeader = _ColumnHeader; + + if (columnHeader != null) + { + Size size = columnHeader.Size; + + size.Width = (Parent == null) + ? Math.Max(sizeNeeded.Width, layoutInfo.ClientBounds.Width) + : sizeNeeded.Width; + + columnHeader.Size = size; + } + } + + #endregion + + #region MeasureElement + + private void MeasureElement(GridElement item, + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, ref Size sizeNeeded) + { + if (item != null && item.Visible == true) + { + item.Measure(layoutInfo, stateInfo, new Size(sizeNeeded.Width, 0)); + + sizeNeeded.Height += item.Size.Height; + } + } + + #endregion + + #endregion + + #endregion + + #region ArrangeOverride + + /// + /// Performs the arrange pass layout of the item when + /// final position and size of the item has been set. + /// + /// Layout information. + /// + /// + protected override void ArrangeOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + Rectangle bounds = layoutBounds; + + ArrangeCaption(layoutInfo, stateInfo, ref bounds); + ArrangeTitle(layoutInfo, stateInfo, ref bounds); + ArrangeGroupBox(layoutInfo, stateInfo, ref bounds); + + Rectangle cbounds = bounds; + ArrangeColumnHeader1(ref bounds); + + ArrangeFilter(layoutInfo, stateInfo, ref bounds); + ArrangeHeader(layoutInfo, stateInfo, ref bounds); + ArrangeFooter(layoutInfo, stateInfo, ref bounds); + + FixedRowHeight = bounds.Y - layoutBounds.Y; + FixedHeaderHeight = FixedRowHeight; + + ArrangeColumns(layoutInfo, stateInfo, bounds); + ArrangeColumnHeader2(layoutInfo, stateInfo, cbounds); + + ArrangeRows(layoutInfo, stateInfo, bounds); + + NeedsFilterScan = false; + + UpdateActivateRow(); + } + + #region ArrangeCaption + + private void ArrangeCaption(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ref Rectangle bounds) + { + GridElement caption = _Caption; + + if (caption != null && caption.Visible == true) + { + caption.Arrange(layoutInfo, stateInfo, + new Rectangle(bounds.Location, caption.Size)); + + bounds.Y += caption.Size.Height; + bounds.Height -= caption.Size.Height; + } + } + + #endregion + + #region ArrangeTitle + + private void ArrangeTitle(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ref Rectangle bounds) + { + GridElement title = _Title; + + if (title != null && title.Visible == true) + { + title.Arrange(layoutInfo, stateInfo, + new Rectangle(bounds.Location, title.Size)); + + bounds.Y += title.Size.Height; + bounds.Height -= title.Size.Height; + } + } + + #endregion + + #region ArrangeColumnHeader + + private void ArrangeColumnHeader1(ref Rectangle bounds) + { + GridElement columnHeader = _ColumnHeader; + + if (columnHeader.Visible == true) + { + bounds.Y += columnHeader.Size.Height; + bounds.Height -= columnHeader.Size.Height; + } + } + + private void ArrangeColumnHeader2(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle bounds) + { + GridElement columnHeader = _ColumnHeader; + + if (columnHeader.Visible == true) + { + columnHeader.Arrange(layoutInfo, stateInfo, + new Rectangle(bounds.Location, columnHeader.Size)); + } + } + + + #endregion + + #region ArrangeHeader + + private void ArrangeHeader(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ref Rectangle bounds) + { + GridElement header = _Header; + + if (header != null && header.Visible == true) + { + header.Arrange(layoutInfo, stateInfo, + new Rectangle(bounds.Location, header.Size)); + + bounds.Y += header.Size.Height; + bounds.Height -= header.Size.Height; + } + } + + #endregion + + #region ArrangeFilter + + private void ArrangeFilter(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ref Rectangle bounds) + { + GridElement filter = _Filter; + + if (filter != null && filter.Visible == true) + { + filter.Arrange(layoutInfo, stateInfo, + new Rectangle(bounds.Location, filter.Size)); + + bounds.Y += filter.Size.Height; + bounds.Height -= filter.Size.Height; + } + } + + #endregion + + #region ArrangeGroupBox + + private void ArrangeGroupBox(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ref Rectangle bounds) + { + GridElement groupBox = _GroupByRow; + + if (groupBox != null && groupBox.Visible == true) + { + groupBox.Arrange(layoutInfo, stateInfo, + new Rectangle(bounds.Location, groupBox.Size)); + + bounds.Y += groupBox.Size.Height; + bounds.Height -= groupBox.Size.Height; + } + } + + #endregion + + #region ArrangeFooter + + private void ArrangeFooter(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, ref Rectangle bounds) + { + GridElement footer = _Footer; + + if (footer != null && footer.Visible == true) + { + Rectangle itemBounds = + new Rectangle(bounds.X, bounds.Bottom - footer.Size.Height, + footer.Size.Width, footer.Size.Height); + + footer.Arrange(layoutInfo, stateInfo, itemBounds); + bounds.Height -= itemBounds.Height; + } + } + + #endregion + + #region ArrangeColumns + + private void ArrangeColumns(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle bounds) + { + if (ShowRowHeaders == true) + { + bounds.X += RowHeaderWidthEx; + bounds.Width -= RowHeaderWidthEx; + } + + GridColumnCollection columns = _Columns; + + int[] map = columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + Size size = column.Size; + + column.Arrange(layoutInfo, stateInfo, + new Rectangle(bounds.Location, size)); + + bounds.X += size.Width; + bounds.Width -= size.Width; + } + } + } + + #endregion + + #region ArrangeRows + + private void ArrangeRows(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle bounds) + { + if (VirtualMode == true) + ArrangeVirtualRows(layoutInfo, stateInfo, bounds); + else + ArrangeRealRows(layoutInfo, stateInfo, bounds); + } + + #region ArrangeVirtualRows + + private void ArrangeVirtualRows( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Rectangle bounds) + { + GridPanel panel = stateInfo.GridPanel; + + _VisibleRowCount = VirtualRowCountEx; + + int vrh = Dpi.Height(panel.VirtualRowHeight); + + FixedRowHeight += (vrh * panel.FrozenRowCount); + + Point currentLocation = bounds.Location; + + if (panel.VirtualRowCount > 0) + { + int start = panel.FirstOnScreenRowIndex; + int end = panel.LastOnScreenRowIndex; + + currentLocation.Y += (start * vrh); + + for (int i = start; i <= end; i++) + { + GridRow row = panel.VirtualRows[i]; + + Size size = new Size(_ColumnHeader.Size.Width, row.Size.Height); + Rectangle itemBounds = new Rectangle(currentLocation, size); + + row.Arrange(layoutInfo, stateInfo, itemBounds); + + currentLocation.Y += itemBounds.Height; + } + + _WhiteSpaceRect = bounds; + + _WhiteSpaceRect.Y += (panel.VisibleRowCount * vrh) - 1; + _WhiteSpaceRect.Height = bounds.Bottom - _WhiteSpaceRect.Y; + } + else + { + _WhiteSpaceRect = bounds; + } + } + + #endregion + + #region ArrangeRealRows + + private void ArrangeRealRows(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle bounds) + { + Point currentLocation = bounds.Location; + Rectangle r = Rectangle.Empty; + r.Location = currentLocation; + + int n = 0; + + GridItemsCollection items = Rows; + foreach (GridElement item in items) + { + if (item.Visible == true) + { + Size size = new Size(_ColumnHeader.Size.Width, item.Size.Height); + Rectangle itemBounds = new Rectangle(currentLocation, size); + + item.Arrange(layoutInfo, stateInfo, itemBounds); + + if (n++ < FrozenRowCount) + FixedRowHeight += itemBounds.Height; + + currentLocation.Y += itemBounds.Height; + } + else + { + r.Y = currentLocation.Y; + item.BoundsRelative = r; + } + } + + _WhiteSpaceRect = bounds; + + _WhiteSpaceRect.Y = currentLocation.Y - 1; + _WhiteSpaceRect.Height = bounds.Bottom - _WhiteSpaceRect.Y; + } + + #endregion + + #endregion + + #region UpdateActivateRow + + private void UpdateActivateRow() + { + GridContainer row = null; + + if (VirtualMode == true) + { + if (LatentActiveRowIndex >= 0 && LatentActiveRowIndex < VirtualRowCountEx) + row = VirtualRows[LatentActiveRowIndex]; + else + SetInitialVirtualSelection(); + } + else + { + if (LatentActiveRowIndex >= 0 && + (LatentActiveContainer != null && LatentActiveRowIndex < LatentActiveContainer.Rows.Count)) + { + row = LatentActiveContainer.Rows[LatentActiveRowIndex] as GridContainer; + } + else + { + SetInitialRealSelection(); + } + } + + LatentActiveRowIndex = -1; + LatentActiveContainer = null; + + if (row != null) + { + ClearAll(); + + SetActiveRow(row, true); + + if (_LatentActiveCellIndex >= 0) + { + GridCell cell = GetCell(row.RowIndex, _LatentActiveCellIndex); + + if (cell != null) + { + SetActiveCell(cell); + SelectCell(cell); + } + } + else + { + row.IsSelected = true; + SelectionRowAnchor = row; + } + + EnsureRowVisible = true; + } + + _LatentActiveCellIndex = -1; + + if (EnsureRowVisible == true) + { + EnsureRowVisible = false; + + if (ActiveRow != null) + ActiveRow.EnsureVisible(false); + } + + if (SelectActiveRow == true) + { + SelectActiveRow = false; + + ClearAll(); + + if (ActiveRow != null) + ActiveRow.IsSelected = true; + + SuperGrid.UpdateInternalMouseMove(); + } + } + + #region SetInitialVirtualSelection + + private void SetInitialVirtualSelection() + { + if (ActiveRow == null && VirtualRowCountEx > 0) + { + int n = 0; + + switch (_InitialActiveRow) + { + case RelativeRow.InsertionRow: + n = VirtualRowCountEx - 1; + break; + + case RelativeRow.LastRow: + n = VirtualRowCountEx - 1; + + if (ShowInsertRow == true && n > 0) + n--; + break; + + case RelativeRow.None: + return; + } + + SetInitialSelection(VirtualRows[n]); + } + } + + #endregion + + #region SetInitialRealSelection + + private void SetInitialRealSelection() + { + if (ActiveRow == null && Rows.Count > 0) + { + int n = 0; + + switch (_InitialActiveRow) + { + case RelativeRow.InsertionRow: + n = Rows.Count - 1; + break; + + case RelativeRow.LastRow: + n = Rows.Count - 1; + + if (ShowInsertRow == true && n > 0) + n--; + break; + + case RelativeRow.None: + return; + } + + if (Rows[n] is GridRow) + SetInitialSelection((GridRow)Rows[n]); + } + } + + #endregion + + #region SetInitialSelection + + private void SetInitialSelection(GridRow row) + { + if (_InitialActiveRow != RelativeRow.None) + SetActiveRow(row, true); + + switch (_InitialSelection) + { + case RelativeSelection.FirstCell: + SetFirstAvailableCell(Columns.FirstVisibleColumn); + break; + + case RelativeSelection.LastCell: + SetLastAvailableCell(Columns.LastVisibleColumn); + break; + + case RelativeSelection.PrimaryCell: + SetFirstAvailableCell(PrimaryColumn); + break; + + case RelativeSelection.Row: + SuperGrid.KeySelectRow(this, row, true, false); + break; + + default: + if (row != null) + row.EnsureVisible(); + break; + } + } + + #endregion + + #region SetFirstAvailableCell + + private void SetFirstAvailableCell(GridColumn column) + { + if (column != null) + { + GridRow row = _ActiveRow as GridRow; + + if (row != null) + { + GridCell ecell = row.GetCell( + column.ColumnIndex, AllowEmptyCellSelection); + + while (ecell != null && ecell.AllowSelection == false) + ecell = ecell.GetNextCell(true, false); + + if (ecell != null) + SelectCell(ecell); + } + } + } + + #endregion + + #region SetLastAvailableCell + + private void SetLastAvailableCell(GridColumn column) + { + if (column != null) + { + GridRow row = _ActiveRow as GridRow; + + if (row != null) + { + GridCell ecell = row.GetCell( + column.ColumnIndex, AllowEmptyCellSelection); + + while (ecell != null && ecell.AllowSelection == false) + ecell = ecell.GetPreviousCell(true, false); + + if (ecell != null) + SelectCell(ecell); + } + } + } + + #endregion + + #region SelectCell + + private void SelectCell(GridCell cell) + { + if (cell != null) + { + if (SetActiveRow(cell.GridRow, true) == true) + { + SelectionRowAnchor = cell.GridRow; + SelectionColumnAnchor = cell.GridColumn; + } + + cell.ExtendSelection(this, cell, false); + + LastProcessedItem = cell; + + if (IsSubPanel == false) + cell.EnsureVisible(); + } + } + + #endregion + + #endregion + + #endregion + + #region RenderOverride + + /// + /// Performs drawing of the item and its children. + /// + /// Holds contextual rendering information. + protected override void RenderOverride(GridRenderInfo renderInfo) + { + Rectangle r = (Parent == null) + ? SuperGrid.ClientRectangle : BoundsRelative; + + if (BoundsRelative.IntersectsWith(r)) + { + RenderRows(renderInfo); + RenderFooter(renderInfo); + RenderColumnHeader(renderInfo); + RenderGroupBox(renderInfo); + RenderFilter(renderInfo); + RenderHeader(renderInfo); + RenderTitle(renderInfo); + RenderCaption(renderInfo); + RenderWhitespace(renderInfo); + RenderBorder(renderInfo); + + if (DisplayedCellRanges != null) + { + if ((CellMergeMode & CellMergeMode.Vertical) == CellMergeMode.Vertical) + SuperGrid.CanScrollEx = false; + } + + if (IsDesignerHosted == true) + { + foreach (GridColumn column in _Columns) + column.Render(renderInfo); + + RenderDesignerElement(renderInfo, Bounds); + } + } + + FlushSelected(); + } + + #region RenderRows + + private void RenderRows(GridRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + Rectangle t = SuperGrid.ViewRect; + Rectangle k = SuperGrid.ViewRectEx; + + GridRenderInfo renderInfo2 = renderInfo; + + Region save = g.Clip; + g.SetClip(k, CombineMode.Intersect); + + if (renderInfo.ClipRectangle.Y < t.Y) + { + Rectangle r = renderInfo.ClipRectangle; + + if (IsVFrozen == false) + { + r.Y = t.Y; + r.Height -= (t.Y - r.Y); + } + + renderInfo2 = new GridRenderInfo(g, r); + } + + RenderCount++; + UpdateMergeFlags(); + + if (VirtualMode == true) + { + RenderVirtualRows(renderInfo2); + RenderFrozenVirtualRows(renderInfo); + } + else + { + RenderRealRows(renderInfo2); + RenderFrozenRealRows(renderInfo); + } + + g.Clip = save; + } + + #region RenderVirtualRows + + private void RenderVirtualRows(GridRenderInfo renderInfo) + { + Rectangle r = BoundsRelative; + + r.Size = new Size(_ColumnHeader.Size.Width, Dpi.Height(VirtualRowHeight)); + + int frow = FirstOnScreenRowIndex; + + GridVirtualRows vrows = VirtualRows; + for (int i = frow; i < VirtualRowCountEx; i++) + { + GridRow row = vrows[i]; + + Rectangle bounds = row.VScrollBounds; + + if (bounds.Size != r.Size) + { + row.FlushRow(); + vrows.FreeRow(i); + + row = vrows[i]; + + bounds = row.VScrollBounds; + } + + if (IsSubPanel == true) + bounds.X -= HScrollOffset; + + if (bounds.Y > renderInfo.ClipRectangle.Bottom) + break; + + if (bounds.IntersectsWith(renderInfo.ClipRectangle)) + row.Render(renderInfo); + } + } + + #endregion + + #region RenderFrozenVirtualRows + + private void RenderFrozenVirtualRows(GridRenderInfo renderInfo) + { + if (FrozenRowCount > 0 && IsSubPanel == false) + { + int vrh = Dpi.Height(VirtualRowHeight); + + Rectangle r = BoundsRelative; + r.Y += (FixedRowHeight - (FrozenRowCount * vrh)); + r.Size = new Size(_ColumnHeader.Size.Width, vrh); + + int n = Math.Min(FrozenRowCount, VirtualRowCountEx); + + GridVirtualRows vrows = VirtualRows; + for (int i = 0; i < n; i++) + { + GridRow row = vrows[i]; + + r.Y += vrh; + + Rectangle bounds = row.BoundsRelative; + + if (IsSubPanel == true) + bounds.X -= HScrollOffset; + + if (bounds.IntersectsWith(renderInfo.ClipRectangle)) + row.Render(renderInfo); + + if (i + 1 == FrozenRowCount) + { + bounds.X -= 3; + bounds.Width += 3; + + AddDropShadow(renderInfo, bounds, true, false); + break; + } + + if (bounds.Y > renderInfo.ClipRectangle.Bottom) + break; + } + } + } + + #endregion + + #region RenderRealRows + + private void RenderRealRows(GridRenderInfo renderInfo) + { + GridItemsCollection items = Rows; + + for (int i = FirstOnScreenRowIndex; i < items.Count; i++) + { + GridElement item = items[i]; + + if (item.Visible == true) + { + Rectangle r = item.BoundsRelative; + + if (IsSubPanel == true) + { + r.X -= HScrollOffset; + + SuperGrid.CanScrollEx = false; + } + + if (item.IsVFrozen == false) + r.Y -= VScrollOffset; + + if (r.Y > renderInfo.ClipRectangle.Bottom) + break; + + if (r.IntersectsWith(renderInfo.ClipRectangle)) + item.Render(renderInfo); + } + } + } + + #endregion + + #region RenderFrozenRealRows + + private void RenderFrozenRealRows(GridRenderInfo renderInfo) + { + if (FrozenRowCount > 0 && IsSubPanel == false) + { + int n = 0; + + GridItemsCollection items = Rows; + foreach (GridElement item in items) + { + if (item.Visible == true) + { + Rectangle r = item.BoundsRelative; + + if (IsSubPanel == true) + r.X -= HScrollOffset; + + if (r.IntersectsWith(renderInfo.ClipRectangle)) + item.Render(renderInfo); + + if (++n >= FrozenRowCount) + { + r.X -= 3; + r.Width += 3; + + AddDropShadow(renderInfo, r, true, false); + break; + } + } + } + } + } + + #endregion + + #endregion + + #region RenderFooter + + private void RenderFooter(GridRenderInfo renderInfo) + { + GridElement footer = _Footer; + + if (footer != null && footer.Visible == true) + footer.Render(renderInfo); + } + + #endregion + + #region RenderColumnHeader + + private void RenderColumnHeader(GridRenderInfo renderInfo) + { + GridElement columnHeader = _ColumnHeader; + + if (columnHeader.Visible == true) + { + Rectangle bounds = columnHeader.BoundsRelative; + + if (IsSubPanel == true) + bounds.X -= HScrollOffset; + + if (IsVFrozen == false) + bounds.Y -= VScrollOffset; + + if (bounds.IntersectsWith(renderInfo.ClipRectangle)) + columnHeader.Render(renderInfo); + } + } + + #endregion + + #region RenderGroupBox + + private void RenderGroupBox(GridRenderInfo renderInfo) + { + GridElement groupBox = _GroupByRow; + + if (groupBox != null && groupBox.Visible == true) + groupBox.Render(renderInfo); + } + + #endregion + + #region RenderFilter + + private void RenderFilter(GridRenderInfo renderInfo) + { + GridElement filter = _Filter; + + if (filter != null && filter.Visible == true) + filter.Render(renderInfo); + } + + #endregion + + #region RenderHeader + + private void RenderHeader(GridRenderInfo renderInfo) + { + GridElement header = _Header; + + if (header != null && header.Visible == true) + header.Render(renderInfo); + } + + #endregion + + #region RenderTitle + + private void RenderTitle(GridRenderInfo renderInfo) + { + GridElement title = _Title; + + if (title != null && title.Visible == true) + title.Render(renderInfo); + } + + #endregion + + #region RenderCaption + + private void RenderCaption(GridRenderInfo renderInfo) + { + GridElement caption = _Caption; + + if (caption != null && caption.Visible == true) + caption.Render(renderInfo); + } + + #endregion + + #region RenderBorder + + private void RenderBorder(GridRenderInfo renderInfo) + { + Graphics g = renderInfo.Graphics; + + Rectangle t = ViewRect; + Rectangle r = PanelBounds; + + if (Parent != null) + { + r.Width = BoundsRelative.Width - 5; + + if (IsVFrozen == false) + { + r.Intersect(t); + + if (r.Y < t.Y) + { + r.Height -= (t.Y - r.Y); + r.Y = t.Y; + } + } + + if (ShowDropShadow == true) + AddDropShadow(renderInfo, r, true, true); + + t.Inflate(4, 4); + + if (r.Bottom > t.Bottom) + r.Height -= (r.Bottom - t.Bottom); + } + else + { + r = SuperGrid.ClientRectangle; + } + + if (r.Width > 0 && r.Height > 0) + { + GridPanelVisualStyle style = GetEffectiveStyle(); + + style.RenderBorder(g, r); + } + } + + #region AddDropShadow + + internal void AddDropShadow( + GridRenderInfo renderInfo, Rectangle r, bool drawBot, bool drawRight) + { + Graphics g = renderInfo.Graphics; + Color color = Color.Black; + + using (Pen pen1 = new Pen(Color.FromArgb(80, color))) + { + using (Pen pen2 = new Pen(Color.FromArgb(48, color))) + { + using (Pen pen3 = new Pen(Color.FromArgb(16, color))) + { + Point pt1 = new Point(r.X + 3, r.Bottom); + Point pt2 = new Point(r.Right - 1, r.Bottom); + Point pt3 = new Point(r.Right, r.Y + 3); + Point pt4 = new Point(r.Right, r.Bottom - 1); + + pt3.Y = Math.Max(pt3.Y, renderInfo.ClipRectangle.Y); + pt4.Y = Math.Min(pt4.Y, renderInfo.ClipRectangle.Bottom); + + if (drawBot == true) + { + g.DrawLine(pen1, pt1, pt2); + + pt1.X++; pt1.Y++; + pt2.X--; pt2.Y++; + + g.DrawLine(pen2, pt1, pt2); + + pt1.X++; pt1.Y++; + pt2.X--; pt2.Y++; + + g.DrawLine(pen3, pt1, pt2); + } + + if (drawRight == true) + { + g.DrawLine(pen1, pt3, pt4); + + pt3.X++; pt3.Y++; + pt4.X++; pt4.Y--; + + g.DrawLine(pen2, pt3, pt4); + + pt3.X++; pt3.Y++; + pt4.X++; pt4.Y -= 2; + + g.DrawLine(pen3, pt3, pt4); + } + } + } + } + } + + #endregion + + #endregion + + #region RenderWhitespace + + private void RenderWhitespace(GridRenderInfo renderInfo) + { + Rectangle r = _WhiteSpaceRect; + + if (IsSubPanel == true) + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + r.Inflate(-1, -1); + + if (r.Width > 0 && r.Height > 0) + { + Graphics g = renderInfo.Graphics; + + if (r.IntersectsWith(renderInfo.ClipRectangle) == true) + { + GridPanelVisualStyle pstyle = GetEffectiveStyle(); + + using (Brush br = pstyle.Background.GetBrush(r)) + g.FillRectangle(br, r); + + if (GridLines == GridLines.Vertical) + { + if (Rows.Count > 0 || + (VirtualMode == true && VirtualRowCount > 0)) + { + using (Pen pen = new Pen(pstyle.HorizontalLineColor)) + { + pen.DashStyle = (DashStyle)pstyle.HorizontalLinePattern; + + g.DrawLine(pen, r.X, r.Y, r.Right, r.Y); + g.DrawLine(pen, r.X, r.Bottom, r.Right, r.Bottom); + } + } + } + + if (VisibleRowCount == 0) + { + r.Inflate(-2, -2); + + if (r.Width > 0 && r.Height > 0) + { + if (String.IsNullOrEmpty(_NoRowsText) == false) + { + GridPanelVisualStyle style = GetEffectiveStyle(); + + if (_NoRowsMarkup != null) + { + RenderTextMarkup(g, style, r); + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + TextDrawing.DrawString(g, + _NoRowsText, style.Font, style.TextColor, r, tf); + } + } + } + } + } + } + } + + #region RenderTextMarkup + + private void RenderTextMarkup( + Graphics g, GridPanelVisualStyle style, Rectangle r) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + _NoRowsMarkup.Arrange(new Rectangle(Point.Empty, r.Size), d); + + Size size = _NoRowsMarkup.Bounds.Size; + + switch (style.Alignment) + { + case Alignment.NotSet: + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + if (r.Height > size.Height) + r.Y += (r.Height - size.Height) / 2; + break; + + case Alignment.BottomLeft: + case Alignment.BottomCenter: + case Alignment.BottomRight: + if (r.Height > size.Height) + r.Y = r.Bottom - size.Height; + break; + } + + _NoRowsMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + _NoRowsMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #endregion + + #region RenderDesignerElement + + private void RenderDesignerElement( + GridRenderInfo renderInfo, Rectangle r) + { + if (IsDesignerHosted == true) + { + if (SuperGrid.DesignerElement == this) + { + r.X -= 2; + r.Y -= 3; + r.Height += 3; + r.Width += 3; + + if (ShowDropShadow == true) + { + r.Width += 2; + r.Height += 2; + } + + if (r.Width > 0 && r.Height > 0) + { + using (Pen pen = new Pen(Color.Purple)) + { + pen.DashStyle = DashStyle.Dash; + + renderInfo.Graphics.DrawRectangle(pen, r); + + } + } + } + } + } + + #endregion + + #region GetTreeButtonSize + + internal Size GetTreeButtonSize() + { + Size size = (ExpandImage != null) + ? ExpandImage.Size : TreeButtonSize; + + Size cSize = (CollapseImage != null) + ? CollapseImage.Size : TreeButtonSize; + + size.Width = Math.Max(size.Width, cSize.Width); + size.Height = Math.Max(size.Height, cSize.Height); + + return (Dpi.Size(size)); + } + + #region TreeButtonSize + + private Size TreeButtonSize + { + get + { + switch (GetExpandButtonType()) + { + case ExpandButtonType.Circle: + return (new Size(12, 12)); + + case ExpandButtonType.Square: + return (new Size(12, 12)); + + case ExpandButtonType.Triangle: + return (new Size(16, 16)); + } + + return (Size.Empty); + } + } + + #endregion + + #endregion + + #region GetExpandButton + + internal Image GetExpandButton(Graphics g, bool hot) + { + if (_ExpandImage != null) + return (_ExpandImage); + + if (hot == true) + { + if (_ExpandButtonHotImage == null) + { + switch (GetExpandButtonType()) + { + case ExpandButtonType.Circle: + + ExpandButtonHotImage = GetCircleExpandButton(g, true); + break; + + case ExpandButtonType.Square: + ExpandButtonHotImage = GetSquareExpandButton(g, true); + break; + + case ExpandButtonType.Triangle: + ExpandButtonHotImage = GetTriangleExpandButton(g, true); + break; + } + } + + return (_ExpandButtonHotImage); + } + + if (_ExpandButtonImage == null) + { + switch (GetExpandButtonType()) + { + case ExpandButtonType.Circle: + ExpandButtonImage = GetCircleExpandButton(g, false); + break; + + case ExpandButtonType.Square: + ExpandButtonImage = GetSquareExpandButton(g, false); + break; + + case ExpandButtonType.Triangle: + ExpandButtonImage = GetTriangleExpandButton(g, false); + break; + } + } + + return (_ExpandButtonImage); + + } + + #endregion + + #region GetCollapseButton + + internal Image GetCollapseButton(Graphics g, bool hot) + { + if (_CollapseImage != null) + return (_CollapseImage); + + if (hot == true) + { + if (_CollapseButtonHotImage == null) + { + switch (GetExpandButtonType()) + { + case ExpandButtonType.Circle: + CollapseButtonHotImage = GetCircleCollapseButton(g, true); + break; + + case ExpandButtonType.Square: + CollapseButtonHotImage = GetSquareCollapseButton(g, true); + break; + + case ExpandButtonType.Triangle: + CollapseButtonHotImage = GetTriangleCollapseButton(g, true); + break; + } + } + + return (_CollapseButtonHotImage); + } + + if (_CollapseButtonImage == null) + { + switch (GetExpandButtonType()) + { + case ExpandButtonType.Circle: + CollapseButtonImage = GetCircleCollapseButton(g, false); + break; + + case ExpandButtonType.Square: + CollapseButtonImage = GetSquareCollapseButton(g, false); + break; + + case ExpandButtonType.Triangle: + CollapseButtonImage = GetTriangleCollapseButton(g, false); + break; + } + } + + return (_CollapseButtonImage); + + } + + #endregion + + #region Circle button support + + #region GetCircleExpandButton + + private Bitmap GetCircleExpandButton(Graphics g, bool hot) + { + Bitmap bmp = new Bitmap(Dpi.Width13, Dpi.Height13, g); + Rectangle r = new Rectangle(0, 0, Dpi.Width12, Dpi.Height12); + + r.Inflate(-Dpi.Width2, -Dpi.Height2); + + GridPanelVisualStyle style = GetEffectiveStyle(); + + Color borderColor = (hot == true) + ? style.CircleTreeButtonStyle.ExpandButton.HotBorderColor + : style.CircleTreeButtonStyle.ExpandButton.BorderColor; + + Color lineColor = (hot == true) + ? style.CircleTreeButtonStyle.ExpandButton.HotLineColor + : style.CircleTreeButtonStyle.ExpandButton.LineColor; + + Background background = (hot == true) + ? style.CircleTreeButtonStyle.ExpandButton.HotBackground + : style.CircleTreeButtonStyle.ExpandButton.Background; + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + gBmp.CompositingQuality = CompositingQuality.HighQuality; + gBmp.SmoothingMode = SmoothingMode.AntiAlias; + + using (Pen pen = new Pen(lineColor)) + { + DrawCircleButtonBase(gBmp, pen, borderColor, background, r); + + int x = r.X + r.Width / 2; + + gBmp.DrawLine(pen, x, r.Y + Dpi.Height2, + x, r.Bottom - Dpi.Height2); + } + } + + return (bmp); + } + + #endregion + + #region GetCircleCollapseButton + + private Bitmap GetCircleCollapseButton(Graphics g, bool hot) + { + Bitmap bmp = new Bitmap(Dpi.Width13, Dpi.Height13, g); + Rectangle r = new Rectangle(0, 0, Dpi.Width12, Dpi.Height12); + + r.Inflate(-Dpi.Width2, -Dpi.Height2); + + GridPanelVisualStyle style = GetEffectiveStyle(); + + Color borderColor = (hot == true) + ? style.CircleTreeButtonStyle.CollapseButton.HotBorderColor + : style.CircleTreeButtonStyle.CollapseButton.BorderColor; + + Color lineColor = (hot == true) + ? style.CircleTreeButtonStyle.CollapseButton.HotLineColor + : style.CircleTreeButtonStyle.CollapseButton.LineColor; + + Background background = (hot == true) + ? style.CircleTreeButtonStyle.CollapseButton.HotBackground + : style.CircleTreeButtonStyle.CollapseButton.Background; + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + gBmp.CompositingQuality = CompositingQuality.HighQuality; + gBmp.SmoothingMode = SmoothingMode.AntiAlias; + + using (Pen pen = new Pen(lineColor)) + DrawCircleButtonBase(gBmp, pen, borderColor, background, r); + } + + return (bmp); + } + + #endregion + + #region DrawCircleButtonBase + + private void DrawCircleButtonBase(Graphics g, + Pen pen, Color borderColor, Background background, Rectangle r) + { + Rectangle t = r; + t.X++; + t.Y++; + t.Width--; + t.Height--; + + using (Brush br = background.GetBrush(r)) + g.FillRectangle(br, t); + + using (Pen penBorder = new Pen(borderColor)) + g.DrawEllipse(penBorder, r); + + int y = r.Y + r.Height / 2; + + g.DrawLine(pen, r.X + Dpi.Width2, y, r.Right - Dpi.Width2, y); + } + + #endregion + + #endregion + + #region Square button support + + #region GetSquareExpandButton + + private Bitmap GetSquareExpandButton(Graphics g, bool hot) + { + Bitmap bmp = new Bitmap(Dpi.Width13, Dpi.Height13, g); + Rectangle r = new Rectangle(0, 0, Dpi.Width12, Dpi.Height12); + + r.Inflate(-Dpi.Width2, -Dpi.Height2); + + GridPanelVisualStyle style = GetEffectiveStyle(); + + Color borderColor = (hot == true) + ? style.SquareTreeButtonStyle.ExpandButton.HotBorderColor + : style.SquareTreeButtonStyle.ExpandButton.BorderColor; + + Color lineColor = (hot == true) + ? style.SquareTreeButtonStyle.ExpandButton.HotLineColor + : style.SquareTreeButtonStyle.ExpandButton.LineColor; + + Background background = (hot == true) + ? style.SquareTreeButtonStyle.ExpandButton.HotBackground + : style.SquareTreeButtonStyle.ExpandButton.Background; + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + int n = Math.Max(Dpi.Width1, Dpi.Height1); + + using (Pen pen = new Pen(lineColor, n)) + { + DrawSquareButtonBase(gBmp, pen, borderColor, background, r); + + int x = r.X + r.Width / 2; + + gBmp.DrawLine(pen, + x, r.Y + Dpi.Height2, x, r.Bottom - Dpi.Height2 - 1); + } + } + + return (bmp); + } + + #endregion + + #region GetSquareCollapseButton + + private Bitmap GetSquareCollapseButton(Graphics g, bool hot) + { + Bitmap bmp = new Bitmap(Dpi.Width13, Dpi.Height13, g); + Rectangle r = new Rectangle(0, 0, Dpi.Width12, Dpi.Height12); + + r.Inflate(-Dpi.Width2, -Dpi.Height2); + + GridPanelVisualStyle style = GetEffectiveStyle(); + + Color borderColor = (hot == true) + ? style.SquareTreeButtonStyle.CollapseButton.HotBorderColor + : style.SquareTreeButtonStyle.CollapseButton.BorderColor; + + Color lineColor = (hot == true) + ? style.SquareTreeButtonStyle.CollapseButton.HotLineColor + : style.SquareTreeButtonStyle.CollapseButton.LineColor; + + Background background = (hot == true) + ? style.SquareTreeButtonStyle.CollapseButton.HotBackground + : style.SquareTreeButtonStyle.CollapseButton.Background; + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + int n = Math.Max(Dpi.Width1, Dpi.Height1); + + using (Pen pen = new Pen(lineColor, n)) + DrawSquareButtonBase(gBmp, pen, borderColor, background, r); + } + + return (bmp); + } + + #endregion + + #region DrawSquareButtonBase + + private void DrawSquareButtonBase(Graphics g, + Pen pen, Color borderColor, Background background, Rectangle r) + { + Rectangle t = r; + t.X++; + t.Y++; + t.Width--; + t.Height--; + + using (Brush br = background.GetBrush(r)) + g.FillRectangle(br, t); + + int n = Math.Max(Dpi.Width1, Dpi.Height1); + + Color foo = Color.FromArgb(140, borderColor); + + using (Pen cpen = new Pen(foo, n)) + g.DrawRectangle(cpen, r); + + using (Pen borderPen = new Pen(borderColor, n)) + { + g.DrawLine(borderPen, r.X + n, r.Y, r.Right - n, r.Y); + g.DrawLine(borderPen, r.Right, r.Y + n, r.Right, r.Bottom - n); + g.DrawLine(borderPen, r.X + n, r.Bottom, r.Right - n, r.Bottom); + g.DrawLine(borderPen, r.X, r.Y + n, r.X, r.Bottom - n); + } + + int y = r.Y + r.Height / 2; + + g.DrawLine(pen, r.X + Dpi.Width2, y, r.Right - Dpi.Width2, y); + } + + #endregion + + #endregion + + #region Triangle button support + + #region GetTriangleExpandButton + + private Image GetTriangleExpandButton(Graphics g, bool hot) + { + Bitmap bmp = new Bitmap(Dpi.Width11, Dpi.Height15, g); + Rectangle r = new Rectangle(0, 0, Dpi.Width11, Dpi.Height15); + + GridPanelVisualStyle style = GetEffectiveStyle(); + + Color borderColor = (hot == true) + ? style.TriangleTreeButtonStyle.ExpandButton.HotBorderColor + : style.TriangleTreeButtonStyle.ExpandButton.BorderColor; + + Background background = (hot == true) + ? style.TriangleTreeButtonStyle.ExpandButton.HotBackground + : style.TriangleTreeButtonStyle.ExpandButton.Background; + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + gBmp.CompositingQuality = CompositingQuality.HighQuality; + gBmp.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(new Point[] + { + new Point(Dpi.Width3, Dpi.Height3), + new Point(Dpi.Width7, Dpi.Height7), + new Point(Dpi.Width3, Dpi.Height11), + }); + + path.CloseAllFigures(); + + using (Brush br = background.GetBrush(r)) + gBmp.FillPath(br, path); + + using (Pen pen = new Pen(borderColor)) + { + gBmp.DrawPath(pen, path); + gBmp.DrawPath(pen, path); + } + } + } + + return (bmp); + } + + #endregion + + #region GetTriangleCollapseButton + + private Bitmap GetTriangleCollapseButton(Graphics g, bool hot) + { + Bitmap bmp = new Bitmap(Dpi.Width12, Dpi.Height12, g); + Rectangle r = new Rectangle(0, 0, Dpi.Width12, Dpi.Height12); + + GridPanelVisualStyle style = GetEffectiveStyle(); + + Color borderColor = (hot == true) + ? style.TriangleTreeButtonStyle.CollapseButton.HotBorderColor + : style.TriangleTreeButtonStyle.CollapseButton.BorderColor; + + Background background = (hot == true) + ? style.TriangleTreeButtonStyle.CollapseButton.HotBackground + : style.TriangleTreeButtonStyle.CollapseButton.Background; + + using (Graphics gBmp = Graphics.FromImage(bmp)) + { + gBmp.CompositingQuality = CompositingQuality.HighQuality; + gBmp.SmoothingMode = SmoothingMode.AntiAlias; + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(new Point[] + { + new Point(Dpi.Width8, Dpi.Height3), + new Point(Dpi.Width8, Dpi.Height8), + new Point(Dpi.Width3, Dpi.Height8), + }); + + path.CloseAllFigures(); + + using (Brush br = background.GetBrush(r)) + gBmp.FillPath(br, path); + + using (Pen pen = new Pen(borderColor)) + { + gBmp.DrawPath(pen, path); + gBmp.DrawPath(pen, path); + } + } + } + + return (bmp); + } + + #endregion + + #endregion + + #endregion + + #region Mouse handling + + #region InternalMouseEnter + + internal override void InternalMouseEnter(EventArgs e) + { + base.InternalMouseEnter(e); + + StyleState rowState = GetRowState(this); + RowVisualStyle style = GetEffectiveRowStyle(this, rowState); + + rowState &= ~StyleState.MouseOver; + + if (GetEffectiveRowStyle(this, rowState).Background != style.Background) + RefreshContainer(); + } + + #endregion + + #region InternalMouseLeave + + internal override void InternalMouseLeave(EventArgs e) + { + HotItem = null; + + base.InternalMouseLeave(e); + + StyleState rowState = GetRowState(this); + RowVisualStyle style = GetEffectiveRowStyle(this, rowState); + + rowState |= StyleState.MouseOver; + + if (GetEffectiveRowStyle(this, rowState).Background != style.Background) + RefreshContainer(); + } + + #endregion + + #region InternalMouseMove + + /// + /// InternalMouseMove + /// + /// + internal override void InternalMouseMove(MouseEventArgs e) + { + if (_WhiteSpaceRect.Contains(e.Location) == true) + { + SuperGrid.GridCursor = Cursors.Default; + + if (_NoRowsMarkup != null) + _NoRowsMarkup.MouseMove(SuperGrid, e); + } + + base.InternalMouseMove(e); + } + + #endregion + + #region InternalMouseDown + + private bool _DownInWhitespace; + + internal override void InternalMouseDown(MouseEventArgs e) + { + if (_WhitespaceClickBehavior == WhitespaceClickBehavior.ClearSelection) + { + _DownInWhitespace = _WhiteSpaceRect.Contains(e.Location); + + if (_DownInWhitespace == true) + { + GridCell ecell = SuperGrid.EditorCell; + + if ((ecell == null) || ecell.EndEdit()) + ClearAll(); + } + } + + base.InternalMouseDown(e); + } + + #endregion + + #region InternalMouseUp + + internal override void InternalMouseUp(MouseEventArgs e) + { + if (_WhiteSpaceRect.Contains(e.Location) == true) + { + if (_DownInWhitespace == true) + { + if (_NoRowsMarkup != null) + _NoRowsMarkup.Click(SuperGrid); + } + } + + base.InternalMouseUp(e); + } + + #endregion + + #region RefreshContainer + + private void RefreshContainer() + { + if (Parent != null) + { + Rectangle r = ContainerBounds; + + if (IsSubPanel == true) + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + Parent.InvalidateRender(r); + } + } + + #endregion + + #endregion + + #region GetElementAt + + /// + /// Gets the current panel element at the given location. + /// + /// + /// + public override GridElement GetElementAt(MouseEventArgs e) + { + return (GetElementAt(e.X, e.Y)); + } + + /// + /// Gets the current panel element at the given location. + /// + /// + /// + /// + public override GridElement GetElementAt(int x, int y) + { + if (SubElementAt(_ColumnHeader, x, y) == true) + return (_ColumnHeader); + + if (SubElementAt(_Caption, x, y) == true) + return (_Caption); + + if (SubElementAt(_GroupByRow, x, y) == true) + return (_GroupByRow); + + if (SubElementAt(_Title, x, y) == true) + return (_Title); + + if (SubElementAt(_Header, x, y) == true) + return (_Header); + + if (SubElementAt(_Filter, x, y) == true) + return (_Filter); + + if (_Footer != null && _Footer.Visible == true) + { + Rectangle r = _Footer.BoundsRelative; + r.X -= HScrollOffset; + + if (r.Contains(x, y) == true) + return (_Footer); + } + + if (VirtualMode == true) + return (GetVirtualElementAt(x, y)); + + return (base.GetElementAt(x, y)); + } + + #region SubElementAt + + private bool SubElementAt(GridElement item, int x, int y) + { + if (item != null && item.Visible == true) + { + Rectangle r = item.BoundsRelative; + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + return (r.Contains(x, y)); + } + + return (false); + } + + #endregion + + #endregion + + #region GetVirtualElementAt + + private GridElement GetVirtualElementAt(int x, int y) + { + GridPanel panel = GridPanel; + if (panel != null && panel.IsSubPanel == false) + { + if (panel.FrozenRowCount > 0) + { + int n = Math.Min(panel.FrozenRowCount, VirtualRowCountEx); + + for (int i = 0; i < n; i++) + { + GridElement item = VirtualRows[i]; + + if (item != null) + { + Rectangle bounds = item.BoundsRelative; + bounds.X -= HScrollOffset; + + if (bounds.Height <= 0 || + bounds.Y > item.SuperGrid.ClientRectangle.Bottom) + break; + + if (bounds.Contains(x, y)) + return (item); + } + } + } + } + + for (int i = FirstOnScreenRowIndex; i < VirtualRowCountEx; i++) + { + GridElement item = VirtualRows[i]; + + if (item != null) + { + Rectangle bounds = item.BoundsRelative; + bounds.X -= HScrollOffset; + + if (item.IsVFrozen == false) + bounds.Y -= VScrollOffset; + + if (bounds.Height <= 0 || + bounds.Y > item.SuperGrid.ClientRectangle.Bottom) + break; + + if (bounds.Contains(x, y)) + return (item); + } + } + + return (null); + } + + #endregion + + #region GetColumnAt + + /// + /// Gets the GridColumn containing the specified location. + /// + ///Point to test + ///Column or null + public GridColumn GetColumnAt(Point pt) + { + Rectangle t = SuperGrid.SViewRect; + + foreach (GridColumn column in _Columns) + { + Rectangle r = column.BoundsRelative; + + if (IsSubPanel == true || column.IsHFrozen == false) + r.X -= HScrollOffset; + + r.Y -= VScrollOffset; + + r.Intersect(t); + + if (r.Contains(pt) == true) + return (column); + } + + return (null); + } + + #endregion + + #region GetNewGridIndex + + internal int GetNewGridIndex(GridContainer item) + { + int gridIndex = _NewGridIndex++; + + if (gridIndex >= _GridIndexArray.Length) + { + int n = _GridIndexArray.Length; + n = Math.Min(n * 2, n + 2048); + + GridContainer[] array = new GridContainer[n]; + + _GridIndexArray.CopyTo(array, 0); + _GridIndexArray = array; + } + + _GridIndexArray[gridIndex] = item; + + return (gridIndex); + } + + #endregion + + #region TruncateGridIndexArray + + internal void TruncateGridIndexArray() + { + if (_GridIndexArray != null) + { + for (int i = _NewGridIndex; i < _GridIndexArray.Length; i++) + _GridIndexArray[i] = null; + } + } + + #endregion + + #region InvalidateRender + + /// + /// Invalidates the display state of the panel. + /// + public override void InvalidateRender() + { + if (ShowDropShadow == true && IsSubPanel == true) + { + Rectangle r = BoundsRelative; + + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + r.Width += 3; + r.Height += 3; + + InvalidateRender(r); + } + else + { + base.InvalidateRender(); + } + } + + #endregion + + #region SetActiveRow + + /// + /// Sets the current Active Row + /// + ///Row to make active. + ///true is successful + public bool SetActiveRow(GridContainer row) + { + if (row != null) + { + if (row.GridPanel != this) + throw new Exception("GridPanel does not contain the given row!"); + } + + return (SetActiveRow(row, true)); + } + + internal bool SetActiveRow(GridContainer ncont, bool activate) + { + if (SuperGrid == null) + return (false); + + GridContainer ocont = SuperGrid.ActiveRow; + + if (ocont != ncont || _LastProcessedItem != ncont) + { + if (DeactivateEdit() == false) + return (false); + + if (ncont is GridPanel == false) + { + if (ocont != ncont) + { + if (DeactivateRow(ocont, ncont) == false) + return (false); + } + + if (ActivateRow(ocont, ncont, activate) == false) + return (false); + } + } + + if (ocont != ncont && ncont != null) + LastProcessedItem = ncont; + + return (true); + } + + #region DeactivateEdit + + internal bool DeactivateEdit() + { + GridCell ecell = SuperGrid.EditorCell; + + if (ecell != null) + { + if (ecell.EndEdit() == false) + return (false); + } + + return (true); + } + + #endregion + + #region DeactivateRow + + private bool DeactivateRow(GridContainer ocont, GridContainer ncont) + { + GridRow orow = ocont as GridRow; + + if (orow != null) + { + if (orow.RowNeedsStored == true || orow.RowCheckChanged == true) + { + if (SuperGrid.DoRowValidatingEvent(orow) == true) + { + if (ncont is GridRow || ncont == null) + { + if (SuperGrid.DoPlayingSoundEvent(GridPanel, orow, PlaySoundContext.RowValidate) == false) + SystemSounds.Beep.Play(); + } + + return (false); + } + + orow.RowCheckChanged = false; + + if (orow.RowNeedsStored == true) + { + if (EnableFiltering == true && FilterLevel != FilterLevel.None) + { + bool rowFiltered = DataFilter.IsRowFiltered(this); + bool colFiltered = DataFilter.IsColumnFiltered(this); + + if (rowFiltered == true || colFiltered == true) + NeedToUpdateDataFilter = true; + } + } + + SuperGrid.DoRowValidatedEvent(orow); + + orow.EditorDirty = false; + + if (orow.IsTempInsertRow == true && orow.IsInsertRow == false) + { + orow.IsTempInsertRow = false; + + if (orow.GridPanel.InsertNewRow(orow, orow.RowIndex) == false) + return (false); + + orow.RowNeedsStored = true; + orow.RowNeedsSorted = true; + + if (VirtualMode == true) + { + VirtualTempInsertRow = null; + VirtualRows.MaxRowIndex = orow.RowIndex; + } + + InvalidateMerge(); + } + + orow.IsTempInsertRow = false; + + if (orow.RowNeedsStored == true) + orow.FlushRow(); + + if (orow.RowNeedsSorted == true) + { + orow.RowNeedsSorted = false; + + if (VirtualMode == false) + UpdateRowPosition(orow); + else + { + VirtualRows.Clear(); + + InvalidateMerge(); + } + } + + if (orow.RowNeedsGrouped == true) + { + orow.RowNeedsGrouped = false; + + if (VirtualMode == false) + { + NeedsGrouped = true; + + if (ncont != null) + { + LatentActiveRowIndex = ncont.RowIndex; + LatentActiveContainer = (GridContainer)ncont.Parent; + } + + InvalidateMerge(); + } + } + } + + if (orow.IsInsertRow == true) + SuperGrid.DoRowSetDefaultValuesEvent(this, orow, NewRowContext.RowDeactivate); + } + + return (true); + } + + #endregion + + #region ActivateRow + + private bool ActivateRow( + GridContainer ocont, GridContainer ncont, bool activate) + { + if (ncont != null) + { + GridRow nrow = ncont as GridRow; + + if (nrow != null) + { + ActiveRow = ncont; + + if (DataBinder.SetPosition(nrow) == false) + { + if (ocont is GridRow) + ((GridRow)ocont).RowDirty = PreActiveRowDirty; + + ActiveRow = ocont; + + return (false); + } + + PreActiveRowDirty = nrow.RowDirty; + } + + ActiveRow = ncont; + + if (activate == true || SuperGrid.ActiveRow != ncont) + { + SuperGrid.ActiveRow = ncont; + SuperGrid.ActiveElement = ncont; + + if (nrow != null && nrow.IsInsertRow == true) + { + for (int i = nrow.Cells.Count; i < _Columns.Count; i++) + nrow.Cells.Add(new GridCell(_Columns[i].DefaultNewRowCellValue)); + + SuperGrid.DoRowSetDefaultValuesEvent(this, nrow, NewRowContext.RowActivate); + } + } + } + else + { + if (activate == true) + { + ActiveRow = ncont; + SuperGrid.ActiveRow = ncont; + } + } + + return (true); + } + + #endregion + + #endregion + + #region FlushActiveRow + + /// + ///Should be called when bound rows have been inserted, to make sure + ///they have been flushed to the data source prior to issuing an Update + /// + ///true if successful + public bool FlushActiveRow() + { + if (ActiveRow != null) + { + if (DeactivateEdit() == true) + return (DeactivateRow(ActiveRow, null)); + } + + return (true); + } + + #endregion + + #region SetActiveCell + + /// + /// Sets the given cell as Active + /// + ///Cell to make active + ///true - if successful + public bool SetActiveCell(GridCell cell) + { + if (cell != null) + { + if (cell.GridPanel != this) + throw new Exception("GridPanel does not contain the given cell!"); + + return (SuperGrid.KeySelectCell(this, cell, false, false)); + } + + GridCell ecell = SuperGrid.EditorCell; + + if (ecell != null) + { + if (ecell.EndEdit() == false) + return (false); + } + + if (SelectionGranularity != SelectionGranularity.Row) + { + if (SuperGrid.DoCellActivatingEvent(this, SuperGrid.ActiveCell, null) == true) + return (false); + + SuperGrid.ActiveCell = null; + + if (SelectionGranularity == SelectionGranularity.Cell) + SuperGrid.ActiveElement = null; + + LastProcessedItem = null; + } + + return (true); + } + + #endregion + + #region ActivateFilterPopup + + /// + ///Activates the given column's FilterPopup + /// + /// + public void ActivateFilterPopup(GridColumn column) + { + if (column != null) + column.ActivateFilterPopup(); + } + + #endregion + + #region DeactivateFilterPopup + + /// + ///Deactivates the the current FilterPopup + /// + public void DeactivateFilterPopup() + { + PopupControl pc = SuperGrid.PopupControl; + + if (pc != null) + pc.Hide(); + } + + #endregion + + #region ClearDirtyRowMarkers + + /// + /// Clears all dirty row markers. + /// + public void ClearDirtyRowMarkers() + { + if (VirtualMode == true) + { + VirtualRows.Clear(); + + InvalidateRender(); + } + else + { + ClearDirtyRowMarkersEx(Rows); + } + } + + #region ClearDirtyRowMarkersEx + + private void ClearDirtyRowMarkersEx(GridItemsCollection items) + { + if (items != null && items.Count > 0) + { + foreach (GridContainer item in items) + { + GridRow row = item as GridRow; + + if (row != null) + row.RowDirty = false; + + ClearDirtyRowMarkersEx(item.Rows); + } + } + } + + #endregion + + #endregion + + #region Sort support + + #region AddSort + + #region AddSort(col) + + /// + /// This routine is used to add a single column to the + /// list of columns used to sort grid data rows. + /// + public void AddSort(GridColumn column) + { + AddSort(column, SortDirection.Ascending); + } + + #endregion + + #region AddSort(col, dir) + + /// + /// This routine is used to add a single column, and + /// its associated sorting direction, to the list of + /// columns used to sort grid data rows. + /// + public void AddSort(GridColumn column, SortDirection sortDirection) + { + column.SortDirection = sortDirection; + + AddSortToList(column); + } + + #endregion + + #region AddSort(col[]) + + /// + /// This routine is used to add an array of column to the + /// list of columns used to sort grid data rows. + /// + public void AddSort(GridColumn[] columns) + { + AddSort(columns, SortDirection.Ascending); + } + + #endregion + + #region AddSort(col[], dir) + + /// + /// This routine is used to add an array of columns and + /// a specified sort direction to the list of columns + /// used to sort grid data rows. + /// + public void AddSort(GridColumn[] columns, SortDirection sortDirection) + { + try + { + InRangeAdd = true; + + foreach (GridColumn column in columns) + AddSort(column, sortDirection); + } + finally + { + InRangeAdd = false; + } + + InvalidateMerge(); + } + + #endregion + + #region AddSort(col[], dir[]) + + /// + /// This routine is used to add an array of columns, and + /// their respective sort directions, to the list of columns + /// used to sort grid data rows. + /// + public void AddSort( + GridColumn[] columns, SortDirection[] sortDirection) + { + try + { + InRangeAdd = true; + + for (int i = 0; i < columns.Length; i++) + AddSort(columns[i], sortDirection[i]); + } + finally + { + InRangeAdd = false; + } + + InvalidateMerge(); + } + + #endregion + + #region AddSortToList + + private void AddSortToList(GridColumn column) + { + NeedsSorted = true; + + if (column.SortDirection != SortDirection.None) + { + if (_SortColumns.Contains(column) == false) + _SortColumns.Add(column); + } + else + { + if (_SortColumns.Contains(column) == true) + _SortColumns.Remove(column); + } + + if (InRangeAdd == false) + InvalidateLayout(); + } + + #endregion + + #endregion + + #region SetSort + + #region SetSort() + + /// + /// Sets the current list of sorting columns to empty. + /// + public void SetSort() + { + if (IsCurrentSort(null, SortDirection.Ascending) == false) + ClearSort(); + } + + #endregion + + #region SetSort(col) + + /// + /// Sets a single column to use for sorting the grid data. + /// + public void SetSort(GridColumn column) + { + if (IsCurrentSort(column, SortDirection.Ascending) == false) + { + ClearSort(false); + + AddSort(column); + } + } + + #endregion + + #region SetSort(col, dir) + + /// + /// Sets a single column, and its associated sort + /// direction (ascending or descending) to use for sorting the grid data. + /// + public void SetSort(GridColumn column, SortDirection sortDirection) + { + if (IsCurrentSort(column, sortDirection) == false) + { + ClearSort(false); + + AddSort(column, sortDirection); + } + } + + #endregion + + #region IsCurrentSort + + private bool IsCurrentSort(GridColumn column, SortDirection sortDirection) + { + if (column == null) + return (_SortColumns.Count == 0); + + if (_SortColumns.Count == 1 && _SortColumns.Contains(column) == true) + return (column.SortDirection == sortDirection); + + return (false); + } + + #endregion + + #region SetSort(col[]) + + /// + /// Sets an array of columns to use for sorting the grid data. + /// + public void SetSort(GridColumn[] columns) + { + ClearSort(false); + + AddSort(columns); + } + + #endregion + + #region SetSort(col[], dir) + + /// + /// Sets an array of columns, and an associated sort + /// direction (ascending or descending) to use for sorting the grid data. + /// + public void SetSort(GridColumn[] columns, SortDirection sortDirection) + { + ClearSort(false); + + AddSort(columns, sortDirection); + } + + #endregion + + #region SetSort(col[], dir[]) + + /// + /// Sets an array of columns, and their respective sort + /// direction (ascending or descending) to use for sorting the grid data. + /// + public void SetSort(GridColumn[] columns, SortDirection[] sortDirection) + { + ClearSort(false); + + AddSort(columns, sortDirection); + } + + #endregion + + #endregion + + #region ClearSort + + /// + /// Clears the currently set column sorting list. + /// + public void ClearSort() + { + ClearSort(true); + } + + internal void ClearSort(bool doSort) + { + GridColumnCollection columns = _Columns; + + foreach (GridColumn column in columns) + column.SortDirection = SortDirection.None; + + _SortColumns.Clear(); + + InvalidateRender(); + + if (doSort == true) + InvalidateMerge(); + } + + #endregion + + #region SortItems + + internal bool SortItems() + { + bool changed = false; + + NeedsSorted = false; + + if (_SortColumns != null && _SortColumns.Count > 0 && Rows.Count > 0) + { + if (SuperGrid.DoRowsSortingEvent(this) == false) + { + try + { + IsSorting = true; + + changed = SortItems(this, _SortLevel); + + } + finally + { + IsSorting = false; + } + + if (changed == true) + { + NeedToUpdateIndicees = true; + + if (UseAlternateRowStyle == true) + SuperGrid.UpdateStyleCount(); + + SuperGrid.DoRowsSortedEvent(this); + + NeedsSorted = false; + } + } + } + + return (changed); + } + + internal bool SortItems(GridContainer container, SortLevel sortLevel) + { + bool changed = false; + + GridItemsCollection items = container.Rows; + + bool isGroup = (items[0] is GridGroup); + + if (items.Count > 0) + { + if (isGroup == true || + (sortLevel & SortLevel.Expanded) == SortLevel.Expanded) + { + for (int i = 0; i < items.Count; i++) + { + if (items[i] is GridRow || items[i] is GridGroup) + { + GridContainer row = items[i] as GridContainer; + + if (row != null && row.Rows.Count > 0) + changed |= SortItems(row, (isGroup ? sortLevel : sortLevel | SortLevel.Root)); + } + } + } + + if (isGroup == false) + { + if ((sortLevel & SortLevel.Root) == SortLevel.Root) + { + int n = GetGroupSortCount(items); + + if (ShowInsertRow == true) + n--; + + if (n > 1) + { + GridElement[] array = new GridElement[n]; + + for (int i = 0; i < n; i++) + array[i] = items[i]; + + Array.Sort(array, 0, n, new RowComparer(_SortColumns)); + + for (int i = 0; i < n; i++) + items[i] = array[i]; + + changed = true; + } + } + } + } + + container.InvalidateMerge(); + + return (changed); + } + + #region RowComparer + + private class RowComparer : IComparer + { + private List _SortColumns; + + public RowComparer(List sortColumns) + { + _SortColumns = sortColumns; + } + + public int Compare(GridElement x, GridElement y) + { + GridRow rowx = x as GridRow; + GridRow rowy = y as GridRow; + + if (rowx == null || rowy == null) + { + if (x is GridTextRow && y is GridTextRow) + return ((GridTextRow)x).Text.CompareTo(((GridTextRow)y).Text); + + if (x is GridTextRow || x is GridGroup) + return (1); + + return (0); + } + + foreach (GridColumn column in _SortColumns) + { + int index = column.ColumnIndex; + + int sval; + + if (index >= rowx.Cells.Count) + sval = (index >= rowy.Cells.Count ? 0 : -1); + + else if (index >= rowy.Cells.Count) + sval = 1; + + else + sval = rowx.Cells[index].CompareTo(rowy.Cells[index]); + + if (sval != 0) + { + return (column.SortDirection == + SortDirection.Ascending) ? sval : -sval; + } + } + + return (0); + } + } + + #endregion + + #endregion + + #region ToggleMultiColumnSort + + /// + /// This routine toggles the current sort direction for the current + /// list of sort columns. + /// + public void ToggleMultiColumnSort() + { + if (_SortColumns.Count > 0) + { + foreach (GridColumn column in _SortColumns) + { + SortDirection sortDirection; + + switch (column.SortDirection) + { + case SortDirection.None: + case SortDirection.Descending: + sortDirection = SortDirection.Ascending; + break; + + default: + sortDirection = SortDirection.Descending; + break; + } + + AddSort(column, sortDirection); + } + + SuperGrid.DoSortChangedEvent(this); + } + } + + #endregion + + #endregion + + #region Group support + + #region AddGroup + + #region AddGroup(col) + + /// + /// This routine is used to add a single column to the + /// list of columns used to group grid data rows together. + /// + public void AddGroup(GridColumn column) + { + AddGroup(column, SortDirection.Ascending); + } + + #endregion + + #region AddGroup(col, dir) + + /// + /// This routine is used to add a single column, and + /// its associated sorting direction, to the list of + /// columns used to group grid data rows together. + /// + public void AddGroup(GridColumn column, SortDirection groupDirection) + { + column.GroupDirection = groupDirection; + + AddGroupToList(column); + } + + #endregion + + #region AddGroup(col[]) + + /// + /// This routine is used to add an array of column to the + /// list of columns used to group grid data rows together. + /// + public void AddGroup(GridColumn[] columns) + { + AddGroup(columns, SortDirection.Ascending); + } + + #endregion + + #region AddGroup(col[], dir) + + /// + /// This routine is used to add an array of columns and + /// a specified sort direction to the list of columns + /// used to group grid data rows together. + /// + public void AddGroup( + GridColumn[] columns, SortDirection groupDirection) + { + try + { + InRangeAdd = true; + + foreach (GridColumn column in columns) + AddGroup(column, groupDirection); + } + finally + { + InRangeAdd = false; + } + + InvalidateMerge(); + } + + #endregion + + #region AddGroup(col[], dir[]) + + /// + /// This routine is used to add an array of columns, and + /// their respective sort directions, to the list of columns + /// used to group grid data rows together. + /// + public void AddGroup( + GridColumn[] columns, SortDirection[] groupDirection) + { + try + { + InRangeAdd = true; + + for (int i = 0; i < columns.Length; i++) + AddGroup(columns[i], groupDirection[i]); + } + finally + { + InRangeAdd = false; + } + + InvalidateLayout(); + } + + #endregion + + #region AddGroupToList + + private void AddGroupToList(GridColumn column) + { + NeedsGrouped = true; + + if (_GroupColumns.Contains(column) == false) + { + _GroupColumns.Add(column); + + SuperGrid.DoGroupChangedEvent(this, GroupChangedAction.Add, column); + } + + if (InRangeAdd == false) + InvalidateMerge(); + } + + #endregion + + #endregion + + #region InsertGroup(col) + + /// + /// This routine is used to insert a single column to the + /// list of columns used to group grid data rows together. + /// + public void InsertGroup(GridColumn column, int index) + { + InsertGroup(column, index, SortDirection.Ascending); + } + + #endregion + + #region InsertGroup(col, dir) + + /// + /// This routine is used to insert a single column, and + /// its associated sorting direction, to the list of + /// columns used to group grid data rows together. + /// + public void InsertGroup( + GridColumn column, int index, SortDirection groupDirection) + { + column.GroupDirection = groupDirection; + + InsertGroupToList(column, index); + } + + #endregion + + #region InsertGroupToList + + private void InsertGroupToList(GridColumn column, int index) + { + NeedsGrouped = true; + + int n = _GroupColumns.IndexOf(column); + + if (n == index) + return; + + if (n >= 0) + { + _GroupColumns.RemoveAt(n); + + if (n < index) + index--; + } + + _GroupColumns.Insert(index, column); + + SuperGrid.DoGroupChangedEvent(this, GroupChangedAction.Add, column); + + InvalidateMerge(); + } + + #endregion + + #region SetGroup + + #region SetGroup() + + /// + /// Resets the Group list to its default empty state. + /// + public void SetGroup() + { + ClearGroup(); + } + + #endregion + + #region SetGroup(col) + + /// + /// Sets the Group list to the given Column. + /// + public void SetGroup(GridColumn column) + { + ClearGroup(); + + AddGroup(column, SortDirection.Ascending); + } + + #endregion + + #region SetGroup(col, dir) + + /// + /// Sets the Group list to the given Column and sort direction. + /// + public void SetGroup( + GridColumn column, SortDirection groupDirection) + { + ClearGroup(); + + AddGroup(column, groupDirection); + } + + #endregion + + #region SetGroup(col[]) + + /// + /// Sets the Group list to the given Column list. + /// + public void SetGroup(GridColumn[] columns) + { + ClearGroup(); + + AddGroup(columns); + } + + #endregion + + #region SetGroup(col[], dir) + + /// + /// Sets the Group list to the + /// given Column list and sort direction. + /// + public void SetGroup( + GridColumn[] columns, SortDirection groupDirection) + { + ClearGroup(); + + AddGroup(columns, groupDirection); + } + + #endregion + + #region SetGroup(col[], dir[]) + + /// + /// Sets the Group list to the + /// given Column list and sort direction. + /// + public void SetGroup( + GridColumn[] columns, SortDirection[] groupDirection) + { + ClearSort(false); + + AddGroup(columns, groupDirection); + } + + #endregion + + #endregion + + #region ClearGroup + + /// + /// Clears all currently set Column Groups. + /// + public void ClearGroup() + { + if (GroupColumns.Count > 0) + { + NeedsGrouped = true; + + GridColumnCollection columns = _Columns; + + foreach (GridColumn column in columns) + column.GroupDirection = SortDirection.None; + + _GroupColumns.Clear(); + + SuperGrid.DoGroupChangedEvent(this, GroupChangedAction.Reset, null); + + InvalidateMerge(); + } + } + + #endregion + + #region RemoveGroup + + /// + /// Removes an individual set Column Group. + /// + public void RemoveGroup(GridColumn column) + { + if (_GroupColumns.Contains(column) == true) + { + NeedsGrouped = true; + + column.GroupDirection = SortDirection.None; + + _GroupColumns.Remove(column); + + SuperGrid.DoGroupChangedEvent(this, GroupChangedAction.Remove, column); + + InvalidateMerge(); + } + } + + #endregion + + #region GroupItems + + #region GroupItems (main) + + private bool GroupItems() + { + bool changed = false; + + NeedsGrouped = false; + + if (SuperGrid.DoRowsGroupingEvent(this) == false) + { + IsSorting = true; + + try + { + GridContainer arow = ActiveRow; + + changed = RemoveGroupRows(); + changed |= AddGroupRows(); + + if (arow != null && arow.Parent != null) + ActiveRow = arow; + } + finally + { + IsSorting = false; + } + + if (changed == true) + { + NeedToUpdateIndicees = true; + NeedsMeasured = true; + + ExpandedUpdateCount++; + + SuperGrid.DoRowsGroupedEvent(this); + + NeedsGrouped = false; + } + } + + return (changed); + } + + #region AddGroupRows + + private bool AddGroupRows() + { + if (_GroupColumns != null && _GroupColumns.Count > 0) + { + ShowInsertRow = false; + + GroupItems(Rows, 0); + + NeedsGroupSorted = true; + + return (true); + } + + return (false); + } + + #endregion + + #region RemoveGroupRows + + private bool RemoveGroupRows() + { + if (Rows.Count > 0 && Rows[0] is GridGroup) + { + List list = new List(); + + RemoveGroups(Rows, list); + Rows.Clear(); + + foreach (GridElement item in list) + { + GridRow row = item as GridRow; + + if (row != null) + { + if (row.IsDetailRow == true || row.IsTempInsertRow == true) + continue; + } + + item.Parent = null; + + Rows.Add(item); + } + + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region GroupItems (sub) + + private void GroupItems(ICollection items, int index) + { + if (index < _GroupColumns.Count) + { + Hashtable groupTable = new Hashtable(); + List groupOrder = new List(); + + ProcessGroup(items, _GroupColumns[index], groupTable, groupOrder); + + IGridCellEditControl editor = _GroupColumns[index].RenderControl; + + if (editor != null) + { + ComboBox cbx = editor as ComboBox; + + if (cbx == null || string.IsNullOrEmpty(cbx.DisplayMember)) + editor = null; + } + + try + { + if (editor != null) + editor.SuspendUpdate = true; + + foreach (GridGroup group in groupOrder) + { + if (editor != null) + { + editor.InitializeContext(group.Cell, null); + + group.Text = editor.EditorFormattedValue; + } + + SuperGrid.DoColumnGroupedEvent(this, _GroupColumns[index], group); + + GroupItems(group.Rows, index + 1); + + GetGroupDetailRows(index, group); + } + } + finally + { + if (editor != null) + editor.SuspendUpdate = false; + } + } + } + + #region GetGroupDetailRows + + private void GetGroupDetailRows(int index, GridGroup group) + { + List preRows; + List postRows; + + if (SuperGrid.DoGetGroupedDetailRowsEvent(this, + _GroupColumns[index], group, out preRows, out postRows) == true) + { + if (preRows != null) + { + for (int i = preRows.Count - 1; i >= 0; i--) + { + preRows[i].IsDetailRow = true; + + group.Rows.Insert(0, preRows[i]); + } + } + + if (postRows != null) + { + for (int i = 0; i < postRows.Count; i++) + { + postRows[i].IsDetailRow = true; + + group.Rows.Add(postRows[i]); + } + } + } + } + + #endregion + + #endregion + + #region GroupSort + + internal bool GroupSort() + { + bool changed = false; + + NeedsGroupSorted = false; + + if (SuperGrid.DoGroupSortingEvent(this) == false) + { + try + { + IsSorting = true; + + changed = GroupSort(this); + } + finally + { + IsSorting = false; + } + + if (changed == true) + { + NeedToUpdateIndicees = true; + NeedsMeasured = true; + + SuperGrid.DoGroupSortedEvent(this); + + NeedsGroupSorted = false; + } + } + + return (changed); + } + + internal bool GroupSort(GridContainer container) + { + bool changed = false; + + GridItemsCollection items = container.Rows; + + if (items.Count > 0) + { + int groupRowIndex = -1; + + for (int i = 0; i < items.Count; i++) + { + if (items[i] is GridGroup) + { + groupRowIndex = i; + + GridContainer row = items[i] as GridContainer; + + if (row != null && row.Rows.Count > 0) + changed |= GroupSort(row); + } + } + + if (groupRowIndex >= 0) + { + if (items.Count > 1) + { + GridGroup group = (GridGroup)items[groupRowIndex]; + GridColumn column = group.Cell.GridColumn; + + if (column != null && + column.GroupDirection != SortDirection.None) + { + int n = GetGroupSortCount(items); + + if (n > 1) + { + GridElement[] array = new GridElement[items.Count]; + + items.CopyTo(array, 0); + Array.Sort(array, 0, n, new GroupComparer(column.GroupDirection)); + + for (int i = 0; i < n; i++) + items[i] = array[i]; + + changed = true; + } + } + } + } + } + + return (changed); + } + + #region GetGroupSortCount + + private int GetGroupSortCount(GridItemsCollection items) + { + for (int i = 0; i < items.Count; i++) + { + GridRow row = items[i] as GridRow; + + if (row != null && row.IsDetailRow == true) + return (i); + } + + return (items.Count); + } + + #endregion + + #region GroupComparer + + private class GroupComparer : IComparer + { + #region Private variables + + private SortDirection _GroupDirection; + + #endregion + + public GroupComparer(SortDirection groupDirection) + { + _GroupDirection = groupDirection; + } + + #region Compare + + public int Compare(GridElement x, GridElement y) + { + GridGroup rowx = x as GridGroup; + GridGroup rowy = y as GridGroup; + + if (rowx == null || rowy == null) + return (-1); + + int sval = 0; + + switch (rowx.GridPanel.GroupSortElement) + { + case GroupSortElement.GroupId: + sval = CompareVal.CompareTo(rowx.GroupId, rowy.GroupId); + break; + + case GroupSortElement.GroupText: + sval = CompareVal.CompareTo(rowx.Text, rowy.Text); + break; + + default: + sval = rowx.Cell.CompareTo(rowy.Cell); + break; + } + + return (_GroupDirection == + SortDirection.Ascending) ? sval : -sval; + } + + #endregion + } + + #endregion + + #endregion + + #region ProcessGroup + + private void ProcessGroup(ICollection items, + GridColumn gridColumn, Hashtable groupTable, List groupOrder) + { + GridCell cell = null; + + foreach (GridElement item in items) + { + GridRow row = item as GridRow; + + if (row != null) + { + if (gridColumn.ColumnIndex < row.Cells.Count) + { + cell = row.Cells[gridColumn.ColumnIndex]; + + AddItemToGroup(groupTable, groupOrder, cell, row); + } + } + else + { + GridGroup group = item as GridGroup; + + if (group != null) + ProcessGroup(group.Rows, gridColumn, groupTable, groupOrder); + else + AddItemToGroup(groupTable, groupOrder, cell, item); + } + } + + items.Clear(); + + foreach (GridGroup group in groupOrder) + { + group.Parent = null; + + items.Add(group); + + bool hasVis = false; + + foreach (GridElement item in group.Rows) + { + if (item.Visible == true) + { + hasVis = true; + break; + } + } + + if (hasVis == false) + group.Visible = false; + } + } + + #endregion + + #region AddItemToGroup + + private void AddItemToGroup(IDictionary groupTable, + List groupOrder, GridCell cell, GridElement row) + { + object groupId = cell.Value ?? ""; + + SuperGrid.DoGetGroupIdEvent(row, cell.GridColumn, ref groupId); + + GridGroup group = groupTable[groupId] as GridGroup; + + if (group == null) + { + group = new GridGroup(); + + group.Cell = cell; + group.GroupId = groupId; + group.Text = (groupId == cell.Value) ? cell.FormattedValue : groupId.ToString(); + + groupTable[groupId] = group; + groupOrder.Add(group); + } + + group.Rows.Add(row); + } + + #endregion + + #region RemoveGroups + + private void RemoveGroups( + IEnumerable items, ICollection list) + { + foreach (GridElement item in items) + { + GridGroup group = item as GridGroup; + + if (group != null) + RemoveGroups(group.Rows, list); + else + list.Add(item); + } + } + + #endregion + + #endregion + + #endregion + + #region Selection Support + + #region GetSelected + + #region GetSelectedElements + + /// + /// Gets a SelectedElementCollection containing + /// a list of currently selected rows, columns, and cells. + /// + public SelectedElementCollection GetSelectedElements() + { + SelectedElementCollection items = + new SelectedElementCollection(); + + GetSelectedElements(items); + + return (items); + } + + internal void GetSelectedElements(SelectedElementCollection items) + { + GetSelectedRows(_SelectedRows, items); + GetSelectedColumns(items); + GetSelectedCells(items); + } + + #endregion + + #region GetSelectedRows + + /// + /// Gets a SelectedElementCollection + /// containing a list of currently selected rows. + /// + public SelectedElementCollection GetSelectedRows() + { + SelectedElementCollection items = + new SelectedElementCollection(SelectedRowCount); + + GetSelectedRows(_SelectedRows, items); + + return (items); + } + + internal void GetSelectedRows(ICollection items) + { + GetSelectedRows(_SelectedRows, items); + } + + internal void GetSelectedRows(SelectedElements se, ICollection items) + { + foreach (SelectedRange range in se.Ranges) + { + for (int i = range.StartIndex; i <= range.EndIndex; i++) + { + GridContainer item = GetRowFromIndex(i); + + if (item != null) + items.Add(item); + } + } + } + + #endregion + + #region GetSelectedColumns + + /// + /// Gets a SelectedElementCollection + /// containing a list of currently selected columns. + /// + public SelectedElementCollection GetSelectedColumns() + { + SelectedElementCollection items = + new SelectedElementCollection(SelectedColumnCount); + + GetSelectedColumns(items); + + return (items); + } + + internal void GetSelectedColumns(ICollection items) + { + foreach (SelectedRange range in _SelectedColumns.Ranges) + { + for (int i = range.StartIndex; i <= range.EndIndex; i++) + items.Add(Columns[i]); + } + } + + #endregion + + #region GetSelectedCells + + /// + /// Gets a SelectedElementCollection + /// containing a list of currently selected cells. + /// + public SelectedElementCollection GetSelectedCells() + { + SelectedElementCollection items = + new SelectedElementCollection(SelectedCellCount); + + GetSelectedCells(items); + + return (items); + } + + internal void GetSelectedCells(SelectedElementCollection items) + { + foreach (GridColumn column in Columns) + GetSelectedCells(items, column); + } + + internal void GetSelectedCells( + SelectedElementCollection items, GridColumn column) + { + foreach (SelectedRange range in column.SelectedCells.Ranges) + { + for (int i = range.StartIndex; i <= range.EndIndex; i++) + { + GridRow row = GetRowFromIndex(i) as GridRow; + + if (row != null) + { + GridCell cell = row.GetCell(column.ColumnIndex, + AllowEmptyCellSelection); + + if (cell != null && cell.AllowSelection == true) + items.Add(cell); + } + } + } + } + + #endregion + + #endregion + + #region Select + + /// + /// Selects the given Row. + /// + /// + public void Select(GridContainer row) + { + if (row != null) + row.IsSelected = true; + } + + /// + /// Selects the given Column. + /// + /// + public void Select(GridColumn column) + { + if (column != null) + column.IsSelected = true; + } + + /// + /// Selects the given Cell. + /// + /// + public void Select(GridCell cell) + { + if (cell != null) + cell.IsSelected = true; + } + + #endregion + + #region SelectAll + + /// + /// Selects all cells, columns, or rows based upon + /// the current TopLeftHeaderSelectBehavior property setting. + /// + public void SelectAll() + { + int count = (VirtualMode == true) + ? VirtualRowCountEx : _NewGridIndex; + + if (count > 0) + { + TopLeftHeaderSelectBehavior tsb = _TopLeftHeaderSelectBehavior; + + if (_TopLeftHeaderSelectBehavior == TopLeftHeaderSelectBehavior.Deterministic) + { + tsb = (_SelectionGranularity == SelectionGranularity.Cell) + ? TopLeftHeaderSelectBehavior.SelectAllCells + : TopLeftHeaderSelectBehavior.SelectAllRows; + } + + ClearAll(); + + switch (tsb) + { + case TopLeftHeaderSelectBehavior.SelectAllCells: + SetSelectedCells(0, 0, count, Columns.Count, true); + break; + + case TopLeftHeaderSelectBehavior.SelectAllColumns: + SetSelectedColumns(0, Columns.Count, true); + break; + + case TopLeftHeaderSelectBehavior.SelectAllRows: + SetSelectedRows(0, count, true); + break; + } + + ColumnHeader.SelectAllCount = SelectionUpdateCount; + } + else + { + ColumnHeader.InvalidateRowHeader(); + } + } + + #endregion + + #region SetSelected + + #region SetSelected (row) + + /// + /// This routine is used to set an individual row as either + /// selected or unselected, based upon the provided 'selected' value. + /// + /// + /// + /// + public bool SetSelected(GridContainer row, bool selected) + { + if (row != null) + { + if (row.IsSelected != selected) + { + row.IsSelected = selected; + + return (row.Selected = selected); + } + } + + return (false); + } + + internal bool SetSelectedEx(GridContainer row, bool selected) + { + int index = row.GridIndex; + + return (SetSelected(_SelectedRows, + index, selected, ref _SelectionUpdateCount)); + } + + /// + /// This routine is used to set a range of rows as either + /// selected or unselected, based upon the provided 'selected' value. + /// + /// + /// + /// + public void SetSelected(GridContainer row, int count, bool selected) + { + int index = row.GridIndex; + + SetSelected(_SelectedRows, + index, count, selected, ref _SelectionUpdateCount); + } + + /// + /// This routine is used to set a range of rows as either + /// selected or unselected, based upon the provided 'selected' value. + /// + /// + /// + /// + public void SetSelectedRows(int startIndex, int count, bool selected) + { + if (count > 0) + { + SetSelected(_SelectedRows, + startIndex, count, selected, ref _SelectionUpdateCount); + + InvalidateRows(this, startIndex, startIndex + count - 1, false); + } + } + + #endregion + + #region SetSelected (column) + + /// + /// This routine is used to set an individual column as either + /// selected or unselected, based upon the provided 'selected' value. + /// + /// + /// + /// + public bool SetSelected(GridColumn column, bool selected) + { + int index = column.ColumnIndex; + + return (SetSelected(_SelectedColumns, + index, selected, ref _SelectionUpdateCount)); + } + + /// + /// This routine is used to set a range of columns as either + /// selected or unselected, based upon the provided 'selected' value. + /// + /// + /// + /// + public void SetSelected(GridColumn column, int count, bool selected) + { + int index = column.ColumnIndex; + + SetSelected(_SelectedColumns, + index, count, selected, ref _SelectionUpdateCount); + } + + /// + /// This routine sets a range of columns as selected + /// or unselected, based upon the provided 'selected' value. + /// + /// + /// + /// + public void SetSelectedColumns(int startIndex, int count, bool selected) + { + if (count > 0 && Columns.Count > 0) + { + SetSelected(_SelectedColumns, + startIndex, count, selected, ref _SelectionUpdateCount); + + InvalidateColumns(startIndex, startIndex + count - 1); + } + } + + #region InvalidateColumns + + internal void InvalidateColumns(int start, int end) + { + if (start > end) + { + int temp = start; + start = end; + end = temp; + } + + if (FrozenColumnCount > 0) + InvalidateColumnRange(0, FirstFrozenColumn.ColumnIndex); + + InvalidateColumnRange(start, end); + } + + #region InvalidateColumnRange + + private void InvalidateColumnRange(int start, int end) + { + Rectangle t = SuperGrid.ClientRectangle; + + start = Math.Max(0, start); + end = Math.Min(start + Columns.Count - 1, end); + + GridColumn rs = Columns[start]; + GridColumn re = Columns[end]; + + Rectangle rsRect = rs.Bounds; + Rectangle reRect = re.Bounds; + + Rectangle r = new Rectangle(rsRect.X, rsRect.Y, + reRect.Right - rsRect.X, reRect.Bottom - rsRect.Y); + + r.IntersectsWith(t); + + InvalidateRender(r); + } + + #endregion + + #endregion + + #endregion + + #region SetSelected (cell) + + /// + /// This routine is used to set an individual cell as either + /// selected or unselected, based upon the provided 'selected' value. + /// + /// + /// + /// + public bool SetSelected(GridCell cell, bool selected) + { + if (cell != null) + { + if (cell.Selected != selected) + { + cell.Selected = selected; + + return (cell.Selected == selected); + } + } + + return (false); + } + + internal bool SetSelectedEx(GridCell cell, bool selected) + { + GridColumn column = cell.GridColumn; + + if (column != null) + { + int index = cell.GridRow.GridIndex; + + return (SetSelected(column.SelectedCells, + index, selected, ref _SelectionUpdateCount)); + } + + return (false); + } + + /// + /// This routine is used to set a range of cells as either + /// selected or unselected, based upon the provided 'selected' value. + /// + /// + /// + /// + /// + /// + public void SetSelectedCells(int startRowIndex, string startColumnName, + int rowCount, int columnCount, bool selected) + { + SetSelectedCells(startRowIndex, + Columns[startColumnName].ColumnIndex, rowCount, columnCount, selected); + } + + /// + /// This routine is used to set a range of cells as either + /// selected or unselected, based upon the provided 'selected' value. + /// + /// + /// + /// + /// + /// + public void SetSelectedCells(int startRowIndex, int startColumnIndex, + int rowCount, int columnCount, bool selected) + { + if (rowCount > 0 && columnCount > 0) + { + for (int i = 0; i < columnCount; i++) + { + SetSelected(Columns[startColumnIndex + i].SelectedCells, + startRowIndex, rowCount, selected, ref _SelectionUpdateCount); + } + + InvalidateCells(startRowIndex, startRowIndex + rowCount - 1, + startColumnIndex, startColumnIndex + columnCount - 1); + } + } + + #region InvalidateCells + + internal void InvalidateCells(int startRowIndex, + int endRowIndex, int startColumnIndex, int endColumnIndex) + { + Rectangle r = Rectangle.Empty; + + int n = Columns.Count; + + int[] map = Columns.DisplayIndexMap; + + if ((uint)startColumnIndex < n && (uint)endColumnIndex < n) + { + if (EnableCellMerging == true) + { + if (endRowIndex - startRowIndex > 100) + { + InvalidateRender(); + } + else + { + for (int i = startRowIndex; i <= endRowIndex; i++) + { + GridRow row = GetRowFromIndex(i) as GridRow; + + if (row != null) + { + for (int j = startColumnIndex; j <= endColumnIndex; j++) + { + GridCell cell = row.GetCell(map[j], true); + + if (cell != null) + cell.InvalidateRender(); + } + } + } + } + } + else + { + int sci = map[startColumnIndex]; + int eci = map[endColumnIndex]; + + Rectangle u = Columns[sci].BoundsRelative; + Rectangle u2 = Columns[eci].BoundsRelative; + + if (Parent == null || Columns[sci].IsHFrozenEx == false) + u.X -= HScrollOffset; + + if (Parent != null || Columns[eci].IsHFrozenEx == false) + u2.X -= HScrollOffset; + + u = Rectangle.Union(u, u2); + + if (startColumnIndex <= endColumnIndex) + InvalidateCellArea(startRowIndex, endRowIndex, u, ref r); + + if (startRowIndex != endRowIndex) + { + int start = startRowIndex; + int end = endRowIndex; + + if (start > end) + { + int temp = start; + start = end; + end = temp; + } + + InvalidateCellArea(start, end, u, ref r); + } + + InvalidateRender(r); + } + } + } + + #region InvalidateCellArea + + private void InvalidateCellArea(int sri, int eri, Rectangle u, ref Rectangle r) + { + GridElement start = GetRowFromIndex(sri); + GridElement end = GetRowFromIndex(eri); + + if (start != null && end != null) + { + GridContainer gcr = GetRowFromIndex(sri); + GridContainer gce = GetRowFromIndex(eri); + + Rectangle t = (gcr != null) ? gcr.BoundsRelative : Rectangle.Empty; + Rectangle t2 = (gce != null) ? gce.BoundsRelative : Rectangle.Empty; + + if (t.IsEmpty == false) + { + if (Parent != null || gcr.BoundsRelative.Y > FixedRowHeight) + t.Y -= VScrollOffset; + } + + if (t2.IsEmpty == false) + { + if (Parent != null || gce.BoundsRelative.Y > FixedRowHeight) + t2.Y -= VScrollOffset; + } + + t.Height = t2.Bottom - t.Top; + + t.X = u.X; + t.Width = u.Width; + + r = (r.IsEmpty == true) ? t : Rectangle.Union(r, t); + } + } + + #endregion + + #endregion + + #endregion + + #region SetSelected (single) + + internal bool SetSelected( + SelectedElements selectedElements, int index, bool selected, ref ushort uCount) + { + SelectedRange range; + bool found = selectedElements.FindRange(index, out range); + + if (selected == true) + { + if (found == false) + { + if (SuperGrid.DoSelectionChangingEvent(this, ref selectedElements, index, 1, selected) == false) + { + uCount++; + selectedElements.AddItem(index); + + if (EnableSelectionBuffering == false) + FlushSelected(); + + return (selectedElements.FindRange(index, out range)); + } + } + } + else + { + if (found == true) + { + if (SuperGrid.DoSelectionChangingEvent(this, ref selectedElements, index, 1, selected) == false) + { + uCount++; + selectedElements.RemoveItem(index, range); + + if (EnableSelectionBuffering == false) + FlushSelected(); + + return (selectedElements.FindRange(index, out range) == false); + } + } + } + + return (false); + } + + #endregion + + #region SetSelected (multiple) + + internal void SetSelected(SelectedElements selectedElements, + int index, int count, bool selected, ref ushort uCount) + { + if (count > 0) + { + if (NeedToSelect(selectedElements, index, count, selected) == true) + { + if (SuperGrid.DoSelectionChangingEvent(this, ref selectedElements, index, count, selected) == false) + { + uCount++; + + if (selected == true) + selectedElements.AddRange(index, index + count - 1); + else + selectedElements.RemoveRange(index, index + count - 1); + } + } + } + } + + #region NeedToSelect + + private bool NeedToSelect( + SelectedElements selectedElements, int startIndex, int count, bool selected) + { + int endIndex = startIndex + count - 1; + + if (selected == true) + { + foreach (SelectedRange range in selectedElements.Ranges) + { + if (range.StartIndex > endIndex) + return (true); + + if (range.StartIndex <= startIndex && range.EndIndex >= endIndex) + return (false); + } + + return (true); + } + else + { + foreach (SelectedRange range in selectedElements.Ranges) + { + if (range.StartIndex > endIndex) + return (false); + + if (range.StartIndex <= endIndex && range.EndIndex >= startIndex) + return (true); + } + + return (false); + } + } + + #endregion + + #endregion + + #endregion + + #region IsItemSelected + + internal bool IsItemSelected( + SelectedElements selectedElements, int index) + { + SelectedRange range; + + return (selectedElements.FindRange(index, out range)); + } + + /// + /// Retrieves whether the given item is selected. + /// + /// + /// + public bool IsItemSelected(GridContainer row) + { + return (row != null ? row.Selected : false); + } + + internal bool IsItemSelectedEx(GridContainer row) + { + return (IsItemSelected(_SelectedRows, row.GridIndex)); + } + + /// + /// Retrieves whether the given item is selected. + /// + /// + /// + public bool IsItemSelected(GridColumn column) + { + if (column != null) + { + int index = column.ColumnIndex; + + return (IsItemSelected(_SelectedColumns, index)); + } + + return (false); + } + + /// + /// Retrieves whether the given item is selected. + /// + /// + /// + public bool IsItemSelected(GridCell cell) + { + return (cell != null ? cell.Selected : false); + } + + internal bool IsItemSelectedEx(GridCell cell) + { + GridColumn column = cell.GridColumn; + + if (column != null) + { + if (cell.GridRow != null) + { + int index = cell.GridRow.GridIndex; + + return (IsItemSelected(column.SelectedCells, index)); + } + } + + return (false); + } + + #endregion + + #region Is(Row/Column/Cell)Selected + + /// + /// IsRowSelected + /// + /// + /// + public bool IsRowSelected(int rowIndex) + { + return (IsItemSelected(_SelectedRows, rowIndex)); + } + + /// + /// Retrieves whether the given column (as + /// specified by the given column index) is selected. + /// + /// + /// + public bool IsColumnSelected(int colIndex) + { + return (IsItemSelected(_SelectedColumns, colIndex)); + } + + /// + /// Retrieves whether the given cell (as specified by the + /// given row and column index) is selected. + /// + /// + /// + /// + public bool IsCellSelected(int rowIndex, int colIndex) + { + SelectedElements selectedElements = + Columns[colIndex].SelectedCells; + + return (IsItemSelected(selectedElements, rowIndex)); + } + + #endregion + + #region OnlyRowsSelected + + internal bool OnlyRowsSelected(int startIndex, int endIndex) + { + if (_SelectedRows.Ranges.Count != 1) + return (false); + + if (_SelectedRows.Ranges[0].StartIndex != startIndex || + _SelectedRows.Ranges[0].EndIndex != endIndex) + { + return (false); + } + + if (_SelectedColumns.Count > 0) + return (false); + + foreach (GridColumn column in Columns) + { + if (column.SelectedCells.Count > 0) + return (false); + } + + return (true); + } + + #endregion + + #region OnlyColumnsSelected + + internal bool OnlyColumnsSelected(int startIndex, int endIndex) + { + if (_SelectedColumns.Ranges.Count != 1) + return (false); + + if (_SelectedColumns.Ranges[0].StartIndex != Columns.DisplayIndexMap[startIndex] || + _SelectedColumns.Ranges[0].EndIndex != Columns.DisplayIndexMap[endIndex]) + { + return (false); + } + + if (_SelectedRows.Count > 0) + return (false); + + foreach (GridColumn column in Columns) + { + if (column.SelectedCells.Count > 0) + return (false); + } + + return (true); + } + + #endregion + + #region OnlyCellsSelected + + internal bool OnlyCellsSelected(int startRowIndex, + int startColIndex, int endRowIndex, int endColIndex) + { + if (_SelectedRows.Ranges.Count > 0) + return (false); + + if (_SelectedColumns.Ranges.Count > 0) + return (false); + + foreach (GridColumn column in Columns) + { + int index = Columns.GetDisplayIndex(column); + + if (index >= startColIndex && index <= endColIndex) + { + if (column.SelectedCells.Ranges.Count != 1) + return (false); + + if (column.SelectedCells.Ranges[0].StartIndex != startRowIndex || + column.SelectedCells.Ranges[0].EndIndex != endRowIndex) + { + return (false); + } + } + else + { + if (column.SelectedCells.Ranges.Count > 0) + return (false); + } + } + + return (true); + } + + #endregion + + #region ClearAll + + /// + /// Clears all cells, rows, and columns + /// from their associated selection lists. + /// + public void ClearAll() + { + ClearAll(true); + } + + internal void ClearAll(bool invalidate) + { + ClearSelected(_SelectedRows); + ClearSelected(_SelectedColumns); + + foreach (GridColumn column in Columns) + ClearSelected(column.SelectedCells); + + ClearAllMergeSelected(); + + if (SuperGrid != null) + { + SuperGrid.LastActiveCell = null; + + if (invalidate == true) + InvalidateRender(); + } + } + + #endregion + + #region ClearAllSelected + + internal void ClearAllSelected() + { + Rectangle t = CViewRect; + + int[] map = Columns.DisplayIndexMap; + + for (int i = 0; i < map.Length; i++) + { + GridColumn col = Columns[map[i]]; + + if (col.Visible && col.Bounds.IntersectsWith(t)) + { + if (col.IsSelected == true) + { + col.InvalidateRender(); + ColumnHeader.InvalidateHeader(this, col); + } + else if (col.SelectedCells.Ranges.Count > 0) + { + col.InvalidateRender(); + } + } + } + + int first = GetFirstOnScreenGridIndex(); + int last = GetLastOnScreenGridIndex(first); + + InvalidateSelectedRows(first, last, t); + + ClearAll(false); + } + + #region InvalidateSelectedRows + + private void InvalidateSelectedRows(int startRow, int endRow, Rectangle t) + { + for (int i = startRow; i <= endRow; i++) + { + GridContainer row = GetRowFromIndex(i); + + if (row != null) + { + if (row.Bounds.Y > t.Bottom) + break; + + Rectangle r = row.ContainerBounds; + + r.Y -= SuperGrid.VScrollOffset; + r.X -= SuperGrid.HScrollOffset; + + if (r.IntersectsWith(t)) + { + if (row.IsSelected == true) + { + if (row is GridPanel) + row.InvalidateRender(r); + else + row.InvalidateRender(); + } + } + } + } + } + + #endregion + + #region GetFirstOnScreenGridIndex + + private int GetFirstOnScreenGridIndex() + { + if ((VScrollOffset == 0 && IsFiltered == false) || + (Parent != null && IsVFrozen == true) || + (VirtualMode == false && IsSubPanel == false && FrozenRowCount > 0)) + { + return (0); + } + + if (VirtualMode == true) + return (GetFirstVirtualOnScreenGridIndex()); + + return (GetFirstRealOnScreenGridIndex()); + } + + #region GetFirstVirtualOnScreenGridIndex + + private int GetFirstVirtualOnScreenGridIndex() + { + Rectangle r = BoundsRelative; + + int vrh = Dpi.Height(VirtualRowHeight); + + r.Y += (FixedRowHeight - FrozenRowCount * vrh); + + int y = VScrollOffset; + + if (Parent == null) + y += (FrozenRowCount * vrh); + else + y = (y - r.Y) + SuperGrid.PrimaryGrid.FixedRowHeight; + + int n = y / vrh; + + return (n > 0 ? n : 0); + } + + #endregion + + #region GetFirstRealOnScreenGridIndex + + private int GetFirstRealOnScreenGridIndex() + { + if (_NewGridIndex <= 0) + return (-1); + + int lo = 0; + int hi = _NewGridIndex - 1; + + Rectangle r = SuperGrid.ViewRect; + + while (lo < hi) + { + int mid = (lo + hi) / 2; + + GridElement item = _GridIndexArray[mid]; + Rectangle t = item is GridPanel ? ((GridPanel)item).ContainerBounds : item.BoundsRelative; + + if (item.IsVFrozen == false) + t.Y -= VScrollOffset; + + if (t.Bottom > r.Y) + { + if (t.Y <= r.Y) + { + if (item.Visible == true) + return (mid); + } + + hi = mid - 1; + } + else + { + lo = mid + 1; + } + } + + return (lo); + } + + #endregion + + #endregion + + #region GetLastOnScreenGridndex + + private int GetLastOnScreenGridIndex(int index) + { + if (VirtualMode == true) + return (GetLastVirtualOnScreenGridIndex()); + + return (GetLastRealOnScreenGridIndex(index)); + } + + #region GetLastVirtualOnScreenGridIndex + + private int GetLastVirtualOnScreenGridIndex() + { + Rectangle r = BoundsRelative; + + int vrh = Dpi.Height(VirtualRowHeight); + + int h = FixedRowHeight - (FrozenRowCount * vrh); + r.Y += h; + r.Height -= h; + + int y = VScrollOffset; + + if (Parent == null) + { + y += (FrozenRowCount * vrh); + r.Height -= FrozenRowCount * vrh; + } + else + { + y = (y - r.Y) + SuperGrid.PrimaryGrid.FixedRowHeight; + } + + int n = (y + r.Height) / vrh; + + return (n > 0 ? n : 0); + } + + #endregion + + #region GetLastRealOnScreenGridIndex + + private int GetLastRealOnScreenGridIndex(int index) + { + Rectangle r = SuperGrid.ViewRect; + + while (index + 1 < _NewGridIndex) + { + index++; + + GridContainer item = _GridIndexArray[index]; + Rectangle t = item.Bounds; + + if (t.Bottom >= r.Bottom) + return (index); + } + + return (index); + } + + #endregion + + #endregion + + #endregion + + #region ClearSelected(rows/columns/cells) + + /// + /// Clears all currently selected Rows. + /// + public void ClearSelectedRows() + { + ClearSelected(_SelectedRows); + + InvalidateRender(); + } + + /// + /// Clears all currently selected Columns. + /// + public void ClearSelectedColumns() + { + ClearSelected(_SelectedColumns); + + InvalidateRender(); + } + + /// + /// Clears all currently selected Cells. + /// + public void ClearSelectedCells() + { + foreach (GridColumn column in Columns) + ClearSelected(column.SelectedCells); + + InvalidateRender(); + } + + private void ClearSelected(SelectedElements selectedElements) + { + if (selectedElements.Count > 0) + { + if (SuperGrid.DoSelectionChangingEvent(this, + ref selectedElements, 0, selectedElements.Count, false) == false) + { + UpdateSelectionCount(); + selectedElements.Clear(); + + } + } + + SelectionClearCount++; + } + + #endregion + + #region ExpandSelectedAtIndex + + internal void ExpandSelectedAtIndex( + int index, int count, bool expand) + { + if (expand == false) + { + SetSelectedRows(index, count, false); + SetSelectedCells(index, 0, count, Columns.Count, false); + + count = -count; + } + + _SelectedRows.OffsetIndices(index, count); + + foreach (GridColumn column in Columns) + column.SelectedCells.OffsetIndices(index, count); + + UpdateRowCountEx(); + + if (expand == true) + { + UpdateIndicees(this, Rows, true); + + for (int i = 0; i < count; i++) + { + GridContainer row = GetRowFromIndex(index + i); + + if (row != null) + { + if (row.Selected == true) + SetSelectedRows(index + i, 1, true); + + GridRow roe = row as GridRow; + + if (roe != null) + { + foreach (GridCell cell in roe.Cells) + { + if (cell.Selected == true) + SetSelectedCells(index + i, cell.ColumnIndex, 1, 1, true); + } + } + } + } + + UpdateSelectionCount(); + } + } + + #endregion + + #region UpdateSelectionCount + + internal void UpdateSelectionCount() + { + _SelectionUpdateCount++; + + if (EnableSelectionBuffering == false) + FlushSelected(); + } + + #endregion + + #region OnSelectionChanged + + internal void OnSelectionChanged() + { + _LastSelectionUpdateCount = _SelectionUpdateCount; + + SuperGrid.DoSelectionChangedEvent(this); + } + + #endregion + + #region NormalizeIndices + + internal void NormalizeIndices( + bool extend, int anchor, ref int startIndex, ref int endIndex) + { + if (startIndex > endIndex) + { + int tempIndex = startIndex; + startIndex = endIndex; + endIndex = tempIndex; + + if (extend == true) + { + if (startIndex > anchor) + startIndex++; + + else if (endIndex < anchor) + endIndex--; + } + } + else + { + if (extend == true) + { + if (endIndex < anchor) + endIndex--; + + else if (startIndex > anchor) + startIndex++; + } + } + } + + #endregion + + #region FlushSelected + + /// + /// Flushes any pending Selections (raises the SelectionChanged event + /// if selections have changed and the event has not been previously raised). + /// + ///true, if event raised. + public bool FlushSelected() + { + if (_SelectionUpdateCount != _LastSelectionUpdateCount) + { + OnSelectionChanged(); + + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region NewRow support + + #region NewRow + + /// + /// Creates a new GridRow, allocating all associated cells + /// and initializing them to their column's default value. + /// The row is not added to the GridPanel. + /// + /// New GridRow + public GridRow NewRow() + { + return (GetNewRow()); + } + + /// + /// Creates and optionally appends a new GridRow, allocating all + /// associated cells and initializing them to their column's default value. + /// + /// New GridRow + public GridRow NewRow(bool append) + { + GridRow row = GetNewRow(); + + if (append == true) + Rows.Add(row); + + return (row); + } + + /// + /// Creates and insert a new GridRow at the given index, allocating all + /// associated cells and initializing them to their column's default value. + /// + /// + /// New GridRow + public GridRow NewRow(int index) + { + GridRow row = GetNewRow(); + + Rows.Insert(index, row); + + return (row); + } + + #endregion + + #region GetNewRow + + private GridRow GetNewRow() + { + GridRow row = new GridRow(); + + row.AllocPanel = this; + + for (int i = 0; i < Columns.Count; i++) + { + GridCell cell = new + GridCell(Columns[i].DefaultNewRowCellValue); + + row.Cells.Add(cell); + } + + SuperGrid.DoRowSetDefaultValuesEvent(this, row, NewRowContext.RowInit); + + return (row); + } + + #endregion + + #endregion + + #region Delete row support + + #region GetDeletedRows + + /// + /// Gets a SelectedElementCollection of the + /// current list of Deleted Rows. + /// + public SelectedElementCollection GetDeletedRows() + { + SelectedElementCollection items = + new SelectedElementCollection(DeletedRowCount); + + SelectedElements sec = InternalDeletedRows; + + int index = -1; + + while (sec.GetNextIndex(ref index) == true) + { + GridRow row = (VirtualMode == true) + ? VirtualRows[index] : (GridRow)Rows[index]; + + if (row.IsDeleted == true) + items.Add(row); + } + + return (items); + } + + #endregion + + #region DeleteAll + + /// + /// This routine marks each data rows as Deleted. + /// + public void DeleteAll() + { + DeleteAllEx(false, false); + } + + /// + /// This routine marks each data rows as Deleted - and sets + /// the Visible state for each deleted row. + /// + /// Visible row state after deletion + public void DeleteAll(bool visible) + { + DeleteAllEx(true, visible); + } + + private void DeleteAllEx(bool useVisible, bool visible) + { + if (VirtualMode == true) + { + if (VirtualRowCountEx > 0) + { + ClearSelected(_DeletedRows); + + SetSelected(_DeletedRows, 0, + VirtualRowCountEx, true, ref _DeleteUpdateCount); + } + } + else + { + if (Rows.Count > 0) + { + int count = Rows.Count; + + ClearSelected(_DeletedRows); + + if (useVisible == true) + SetDeletedRows(0, count, true, visible); + else + SetDeletedRows(0, count, true); + } + } + } + + + #endregion + + #region UnDeleteAll + + /// + /// Undeletes (or restores) all previously deleted grid rows. + /// + public void UnDeleteAll() + { + UnDeleteAll(false); + } + + /// + /// Undeletes (or restores) all previously deleted grid rows. + /// + public void UnDeleteAll(bool visible) + { + if (visible == true) + { + if (_DeletedRows.Count > 0) + { + SelectedElementCollection sec = GetDeletedRows(); + + foreach (GridContainer row in sec) + row.Visible = true; + } + + InvalidateRender(); + } + + ClearSelected(_DeletedRows); + + UpdateDeleteCount(); + } + + #endregion + + #region SetDeleted + + /// + /// Sets the deleted state for the given row. + /// + /// + ///Signifies whether to mark the row as deleted or not + /// + public bool SetDeleted(GridContainer row, bool deleted) + { + bool visible = row.Visible; + + if (deleted == true && AutoHideDeletedRows == true) + visible = false; + + return (SetDeleted(row, deleted, visible)); + } + + /// + /// Sets the deleted and visible state for the given row. + /// + /// + ///Signifies whether to mark the row as deleted or not + ///Signifies whether to mark the row as visible or not + /// + public bool SetDeleted(GridContainer row, bool deleted, bool visible) + { + bool state = SetSelected( + _DeletedRows, row.FullIndex, deleted, ref _DeleteUpdateCount); + + if (VirtualMode == false) + UpdateDeletedRow(row, visible); + else + InvalidateRender(); + + return (state); + } + + /// + /// Sets the deleted state, beginning at the given row, and + /// continuing for the specified count. + /// + ///Row + ///Count of rows + ///Signifies whether to mark each row as deleted or not + public void SetDeleted(GridContainer row, int count, bool deleted) + { + SetDeletedRows(row.FullIndex, count, deleted); + } + + /// + /// Sets the deleted state, beginning at the given row, and + /// continuing for the specified count. + /// + /// + /// + ///Signifies whether to mark each row as deleted or not + ///Signifies whether to mark each row as visible or not + public void SetDeleted(GridContainer row, int count, bool deleted, bool visible) + { + SetDeletedRows(row.FullIndex, count, deleted, visible); + } + + #endregion + + #region SetDeletedRows + + /// + /// Sets the deleted state, beginning at the given row + /// index, and continuing for the specified count. + /// + /// + /// + /// + public void SetDeletedRows(int startIndex, int count, bool deleted) + { + if (count > 0) + { + SetSelected(_DeletedRows, + startIndex, count, deleted, ref _DeleteUpdateCount); + + if (VirtualMode == false) + { + bool autoHide = false; + + if (deleted == true && AutoHideDeletedRows == true) + autoHide = true; + + for (int i = 0; i < count; i++) + { + GridContainer row = + Rows[startIndex + i] as GridContainer; + + UpdateDeletedRow(row, autoHide ? false : row.Visible); + } + } + else + { + InvalidateRender(); + } + } + } + + /// + /// Sets the deleted state, beginning at the given row + /// index, and continuing for the specified count. + /// + ///Start index + ///Count of row to effect + ///Signifies whether to mark each row as deleted or not + ///Signifies whether to mark each row as visible or not + public void SetDeletedRows(int startIndex, int count, bool deleted, bool visible) + { + if (count > 0) + { + SetSelected(_DeletedRows, + startIndex, count, deleted, ref _DeleteUpdateCount); + + if (VirtualMode == false) + { + for (int i = 0; i < count; i++) + { + GridContainer row = + Rows[startIndex + i] as GridContainer; + + UpdateDeletedRow(row, visible); + } + } + else + { + InvalidateRender(); + } + } + } + + #endregion + + #region UpdateDeletedRow + + private void UpdateDeletedRow(GridContainer row, bool visible) + { + if (row != null) + { + if (row.Visible != visible) + { + if (visible == false && row.IsActive == true) + { + SuperGrid.DeactivateNonModalEditor(); + SuperGrid.PostInternalMouseMove(); + + SelectActiveRow = true; + } + + row.Visible = visible; + } + else + { + row.InvalidateRender(); + } + } + } + + #endregion + + #region IsRowDeleted + + /// + /// IsRowDeleted + /// + /// + /// + public bool IsRowDeleted(GridContainer row) + { + int index = row.FullIndex; + + return (IsRowDeleted(index)); + } + + /// + /// IsRowDeleted + /// + /// + /// + public bool IsRowDeleted(int index) + { + return (IsItemSelected(_DeletedRows, index)); + } + + #endregion + + #region UpdateDeleteCount + + internal void UpdateDeleteCount() + { + _DeleteUpdateCount++; + } + + #endregion + + #region ExpandDeletedAtIndex + + internal void ExpandDeletedAtIndex(int index, int count) + { + _DeletedRows.OffsetIndices(index, count); + + UpdateRowCountEx(); + } + + #endregion + + #endregion + + #region InsertRow + + /// + /// Inserts a new row at the given index. + /// + /// + /// + public GridRow InsertRow(int index) + { + if (DeactivateEdit() == false) + return (null); + + if (DeactivateRow(SuperGrid.ActiveRow, null) == false) + return (null); + + if (SuperGrid.DoRowAddingEvent(this, ref index) == false) + { + GridRow row = GetNewRow(); + + DataBinder.GetDefaultValues(row); + + if (VirtualMode == true) + InsertVirtualTempRow(row, index); + else + InsertRealTempRow(row, index); + + return (row); + } + + return (null); + } + + #region InsertVirtualTempRow + + private void InsertVirtualTempRow(GridRow row, int index) + { + if ((uint)index > VirtualRowCount) + throw new Exception("Invalid VirtualRow collection index"); + + row.RowIndex = index; + + row.IsTempInsertRow = true; + row.RowNeedsStored = true; + + VirtualRows.MaxRowIndex = index - 1; + VirtualRowCount++; + + _VirtualTempInsertRow = row; + + LatentActiveRowIndex = index; + LatentActiveContainer = this; + + EnsureRowVisible = true; + + HotItem = null; + ExpandDeletedAtIndex(row.FullIndex + 1, 1); + PostInternalMouseMove(); + + SuperGrid.DoRowSetDefaultValuesEvent(this, row, NewRowContext.RowInit); + SuperGrid.DoRowAddedEvent(this, index); + + InvalidateMerge(); + } + + #endregion + + #region InsertRealTempRow + + private void InsertRealTempRow(GridRow row, int index) + { + if ((uint)index > Rows.Count) + throw new Exception("Invalid Rows collection index"); + + if (index == Rows.Count && ShowInsertRow == true) + index--; + + row.IsTempInsertRow = true; + row.RowNeedsStored = true; + + Rows.Insert(index, row); + UpdateIndicees(this, Rows, true); + + LatentActiveRowIndex = index; + LatentActiveContainer = this; + + EnsureRowVisible = true; + + HotItem = null; + ExpandDeletedAtIndex(row.FullIndex + 1, 1); + PostInternalMouseMove(); + + SuperGrid.DoRowSetDefaultValuesEvent(this, row, NewRowContext.RowInit); + SuperGrid.DoRowAddedEvent(this, index); + + InvalidateMerge(); + } + + #endregion + + #endregion + + #region InsertNewRow + + private bool InsertNewRow(GridRow row, int index) + { + while (true) + { + try + { + DataBinder.UpdatePosInProgress = true; + + DataBinder.InsertRow(index, row); + break; + } + catch (Exception exp) + { + bool retry = false; + bool throwException = false; + + if (SuperGrid.HasDataErrorHandler == true) + { + object value = row; + + if (SuperGrid.DoDataErrorEvent(this, null, exp, + DataContext.InsertRow, ref value, ref throwException, ref retry) == true) + { + return (false); + } + } + + if (throwException == true) + throw; + + if (retry == false) + return (false); + } + finally + { + DataBinder.UpdatePosInProgress = false; + } + } + + return (true); + } + + #endregion + + #region GetRowFromIndex + + /// + /// Gets the Row from the given GridIndex + /// + /// + /// + public GridContainer GetRowFromIndex(int gridIndex) + { + if (gridIndex >= 0) + { + if (VirtualMode == true) + { + if (gridIndex >= VirtualRowCountEx) + return (null); + + return (VirtualRows[gridIndex]); + } + + if (gridIndex < _NewGridIndex && gridIndex < _GridIndexArray.Length) + return (_GridIndexArray[gridIndex]); + } + + return (null); + } + + #endregion + + #region UpdateRowCount + + internal void UpdateRowCount() + { + if (DataBinder.IsUpdateSuspended == false) + { + if (EnableFiltering == true && FilterLevel != FilterLevel.None) + { + bool rowFiltered = DataFilter.IsRowFiltered(this); + bool colFiltered = DataFilter.IsColumnFiltered(this); + + if (rowFiltered == true || colFiltered == true) + NeedToUpdateDataFilter = true; + } + + UpdateRowCountEx(); + } + } + + #endregion + + #region UpdateRowCountEx + + internal void UpdateRowCountEx() + { + if (SuperGrid != null) + { + SuperGrid.NeedToUpdateIndicees = true; + SuperGrid.UpdateStyleCount(); + } + } + + #endregion + + #region CreateItemsCollection + + /// + /// Creates the GridItemsCollection that hosts the items. + /// + /// New instance of GridItemsCollection. + protected override GridItemsCollection CreateItemsCollection() + { + GridItemsCollection items = new GridItemsCollection(); + + items.CollectionChanged += ItemsCollectionChanged; + + return (items); + } + + #endregion + + #region DisposeItemsCollection + + /// + /// DisposeItemsCollection + /// + /// + protected override void DisposeItemsCollection(GridItemsCollection items) + { + items.CollectionChanged -= ItemsCollectionChanged; + } + + #endregion + + #region ItemsCollectionChanged + + void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (IsRowMoving == false) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + case NotifyCollectionChangedAction.Replace: + foreach (GridElement item in e.NewItems) + { + if (item is GridPanel) + throw new Exception("GridPanels can not be nested."); + + if (VirtualMode == true) + throw new Exception("Virtual Panels can not have nested rows."); + + if (item.Parent != null && item.Parent != this) + throw new Exception("Row is already a member of another Rows collection."); + + item.Parent = this; + } + break; + } + + RowCollectionChanged(e); + } + } + + #endregion + + #region RowCollectionChanged + + internal void RowCollectionChanged(NotifyCollectionChangedEventArgs e) + { + if (IsRowMoving == false) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + case NotifyCollectionChangedAction.Replace: + int n = 0; + + foreach (GridElement item in e.NewItems) + { + GridContainer row = item as GridContainer; + GridRow roe = row as GridRow; + + if (SortColumns != null && SortColumns.Count > 0) + { + if (IsSorting == false) + { + item.NeedsMeasured = true; + + if (roe != null && roe.IsTempInsertRow == false) + NeedsSorted = true; + } + } + + if (row != null) + { + row.RowIndex = e.NewStartingIndex + n; + + if (roe != null) + { + if (e.Action == NotifyCollectionChangedAction.Replace) + RemoveFromExpDictionary(roe); + + AddToExpDictionary(roe); + + if (roe.IsTempInsertRow == false && roe.DataItem == null) + { + if (ShowInsertRow == true) + RemoveNewInsertRow(); + + DataBinder.InsertRow(roe.RowIndex, roe); + + if (ShowInsertRow == true) + AddNewInsertRow(); + } + } + } + + n++; + } + break; + + case NotifyCollectionChangedAction.Reset: + ClearAll(); + UnDeleteAll(); + + SetActiveRow(null); + DetachNestedRows(false); + + if (IsSorting == false) + _ExpDictionary.Clear(); + break; + + case NotifyCollectionChangedAction.Remove: + ClearAll(); + + if (_ExpDictionary.Count > 0) + { + foreach (GridContainer item in e.OldItems) + RemoveFromExpDictionary(item as GridRow); + } + + foreach (GridContainer item in e.OldItems) + { + GridRow row = item as GridRow; + + if (row != null) + { + if (row.DataItem != null) + { + if (row.IsTempInsertRow == false) + DataBinder.RemoveRow(row); + + row.DataItem = null; + } + + if (row.IsReordering == false) + { + if (row == ActiveRow) + ActiveRow = null; + } + } + } + break; + } + + if (IsSorting == false) + { + NeedsMeasured = true; + NeedsFilterScan = true; + + if (GroupColumns.Count > 0) + { + if (e.Action != NotifyCollectionChangedAction.Remove) + NeedsGrouped = true; + } + + if (SuperGrid != null && SuperGrid.IsUpdateSuspended == false) + { + UpdateRowCount(); + + InvalidateMerge(); + + if (SuperGrid.NonModalEditorCell != null) + { + SuperGrid.DeactivateNonModalEditor(); + SuperGrid.PostInternalMouseMove(); + } + } + } + } + } + + #endregion + + #region ColumnsCollectionChanged + + private void ColumnsCollectionChanged(object sender, CollectionChangeEventArgs e) + { + if (ShowInsertRow == true) + LoadInsertRow = true; + + InvalidateMerge(); + } + + #endregion + + #region AddToExpDictionary + + internal void AddToExpDictionary(GridContainer cont) + { + if (EnableCellExpressions == true) + { + GridRow row = cont as GridRow; + + if (row != null) + { + foreach (GridCell cell in row.Cells) + { + string newExp = cell.Value as string; + + if (newExp != null) + { + newExp = newExp.Trim(); + + if (newExp.StartsWith("=")) + cell.SetCellExp(this, newExp); + } + } + } + + if (cont.Rows != null) + { + foreach (GridContainer item in cont.Rows) + AddToExpDictionary(item); + } + } + } + + #endregion + + #region RemoveFromExpDictionary + + internal void RemoveFromExpDictionary(GridContainer cont) + { + if (EnableCellExpressions == true) + { + GridRow row = cont as GridRow; + + if (row != null) + { + foreach (GridCell cell in row.Cells) + { + if (cell.IsValueExpression == true) + _ExpDictionary.Remove(cell); + } + } + + if (cont.Rows != null) + { + foreach (GridContainer item in cont.Rows) + RemoveFromExpDictionary(item); + } + } + } + + #endregion + + #region AddNewInsertRow + + internal void AddNewInsertRow() + { + if (VirtualMode == true) + { + if (_VirtualRowCount > 0) + { + _VirtualInsertRow = VirtualRows[_VirtualRowCount]; + + _VirtualInsertRow.IsTempInsertRow = true; + + DataBinder.GetDefaultValues(_VirtualInsertRow); + } + + _VirtualRowCount++; + } + else + { + GridItemsCollection items = Rows; + + GridRow row = new GridRow(); + + for (int i = 0; i < _Columns.Count; i++) + row.Cells.Add(new GridCell()); + + row.Parent = this; + row.IsTempInsertRow = true; + + DataBinder.GetDefaultValues(row); + + items.FloatLastItem = false; + items.Add(row); + items.FloatLastItem = true; + + if (SuperGrid == null) + LoadInsertRow = true; + } + } + + #endregion + + #region RemoveNewInsertRow + + internal void RemoveNewInsertRow() + { + if (VirtualMode == true) + { + _VirtualRowCount--; + + _VirtualInsertRow = null; + + VirtualRows.FreeRow(_VirtualRowCount); + } + else + { + GridItemsCollection items = Rows; + + if (items.Count == 0 || items.FloatLastItem == false) + throw new Exception(); + + GridRow row = items[items.Count - 1] as GridRow; + + if (row == null) + throw new Exception(); + + if (_ActiveRow == row) + SetActiveRow(row.PrevVisibleRow, true); + + items.Remove(row); + + items.FloatLastItem = false; + } + } + + #endregion + + #region GetAutoSizeMode + + private ColumnAutoSizeMode GetAutoSizeMode(GridColumn column) + { + return (column.AutoSizeMode == ColumnAutoSizeMode.NotSet) + ? _ColumnAutoSizeMode : column.AutoSizeMode; + } + + #endregion + + #region GetResourceImage + + internal Image GetResourceImage(string resource) + { + string res = GetDpiImageString(resource); + + Assembly myAssembly = Assembly.GetExecutingAssembly(); + + using (Stream myStream = + myAssembly.GetManifestResourceStream(res)) + { + if (myStream != null) + return (new Bitmap(myStream)); + } + + return (null); + } + + #region GetDpiImageString + + private string GetDpiImageString(string s) + { + SizeF sizef = Dpi.Factor; + float scale = Math.Max(sizef.Width, sizef.Height); + + string t = + (scale >= 2) ? "32" : + (scale >= 1.5) ? "24" : + (scale >= 1.25) ? "20" : "16"; + + return ("DevComponents.DotNetBar.SuperGrid." + s + t + ".png"); + } + + #endregion + + #endregion + + #region PointToScroll + + internal Point PointToScroll(Point pt) + { + if (IsSubPanel == true) + pt.X -= HScrollOffset; + + if (IsVFrozen == false) + pt.Y -= VScrollOffset; + + return (pt); + } + + #endregion + + #region PointToGrid + + /// + /// Converts the given Point + /// into a Grid relative Point. + /// + public Point PointToGrid(Point pt) + { + if (IsSubPanel == true) + { + pt.X += HScrollOffset; + pt.Y += VScrollOffset; + } + else + { + if (FrozenColumnCount == 0) + { + Rectangle t = SuperGrid.SViewRect; + + if (t.Contains(pt) == true) + { + pt.X += HScrollOffset; + pt.Y += VScrollOffset; + } + } + else + { + GridElement item = GetElementAt(pt.X, pt.Y); + + if (item is GridColumnHeader) + pt = PointByColumn(pt); + + else if (item is GridFooter) + pt.Y += VScrollOffset; + + else if (item is GridRow) + { + GridElement sub = ((GridRow)item).GetElementAt(pt.X, pt.Y); + + if (item.IsVFrozen == false) + pt.Y += VScrollOffset; + + if (sub is GridPanel == false) + pt = PointByColumn(pt); + else + pt.X += HScrollOffset; + } + } + } + + return (pt); + } + + #endregion + + #region PointByColumn + + private Point PointByColumn(Point pt) + { + int[] map = Columns.DisplayIndexMap; + + foreach (int index in map) + { + GridColumn column = _Columns[index]; + + if (column.Visible == true) + { + int x = column.BoundsRelative.X; + + if (column.IsHFrozen == false && pt.X > x) + { + pt.X += HScrollOffset; + break; + } + } + } + + return (pt); + } + + #endregion + + #region CopySelectedCellsToClipboard + + /// + /// Copies the currently selected list of tab delimited cells to the system + /// ClipBoard. This routine takes all cell, column, and row selections into + /// account when determining what cell data to write to the clipboard. + /// + public void CopySelectedCellsToClipboard() + { + CopySelectedCellsToClipboard(false, false, '\t', true, false); + } + + /// + /// Copies the currently selected list of tab delimited cells to the system + /// ClipBoard. This routine takes all cell, column, and row selections into + /// account when determining what cell data to write to the clipboard. + /// + ///Whether to copy cell FormattedValue instead of cell Value + public void CopySelectedCellsToClipboard(bool formatValue) + { + CopySelectedCellsToClipboard(false, false, '\t', true, formatValue); + } + + /// + /// Copies the currently selected list of tab delimited cells to the + /// system ClipBoard. This routine takes all cell, column, and row + /// selections into account when determining what cell data to write + /// to the clipboard. + /// + ///If true, the column header text is written. + ///If true, the row GridIndex is written. + public void CopySelectedCellsToClipboard(bool includeColumnHeaders, bool includeGridIndex) + { + CopySelectedCellsToClipboard( + includeColumnHeaders, includeGridIndex, '\t', true, false); + } + + /// + /// Copies the currently selected list of tab delimited cells to the system + /// ClipBoard. This routine takes all cell, column, and row selections into + /// account when determining what cell data to write to the clipboard. + /// + ///If true, the column header text is written. + ///If true, the row GridIndex is written. + ///Whether to copy cell FormattedValue instead of cell Value + public void CopySelectedCellsToClipboard( + bool includeColumnHeaders, bool includeGridIndex, bool formatValue) + { + CopySelectedCellsToClipboard( + includeColumnHeaders, includeGridIndex, '\t', true, formatValue); + } + + /// + /// Copies the currently selected list of tab delimited cells to the system + /// ClipBoard. This routine takes all cell, column, and row selections into + /// account when determining what cell data to write to the clipboard. + /// + ///If true, the column header text is written. + ///If true, the row GridIndex is written. + ///Field delimiter + public void CopySelectedCellsToClipboard( + bool includeColumnHeaders, bool includeGridIndex, char delimiter) + { + CopySelectedCellsToClipboard( + includeColumnHeaders, includeGridIndex, delimiter, true, false); + } + + /// + /// Copies the currently selected list of tab delimited cells to the system + /// ClipBoard. This routine takes all cell, column, and row selections into + /// account when determining what cell data to write to the clipboard. + /// + ///If true, the column header text is written. + ///If true, the row GridIndex is written. + ///Field delimiter + ///Whether to copy all leading columns + public void CopySelectedCellsToClipboard( + bool includeColumnHeaders, bool includeGridIndex, char delimiter, bool fullCopy) + { + CopySelectedCellsToClipboard( + includeColumnHeaders, includeGridIndex, delimiter, fullCopy, false); + } + + /// + /// Copies the currently selected list of tab delimited cells to the system + /// ClipBoard. This routine takes all cell, column, and row selections into + /// account when determining what cell data to write to the clipboard. + /// + ///If true, the column header text is written. + ///If true, the row GridIndex is written. + ///Field delimiter + ///Whether to copy all leading columns + ///Whether to copy cell FormattedValue instead of cell Value + public void CopySelectedCellsToClipboard( + bool includeColumnHeaders, bool includeGridIndex, char delimiter, bool fullCopy, bool formatValue) + { + SelectedElementCollection items = GetSelectedElements(); + List cells = items.GetCells(); + + if (cells.Count > 0) + { + cells.Sort(new CellComparer()); + + BitArray usedColumns = GetUsedColumns(cells); + + if (usedColumns.Count > 0) + { + int fIndex = (fullCopy == true) + ? 0 : GetFirstCellIndex(usedColumns); + + StringBuilder sb = new StringBuilder(); + + if (includeColumnHeaders == true) + { + foreach (GridColumn column in _Columns) + { + if (fullCopy == true || usedColumns[column.ColumnIndex] == true) + { + if (column.ColumnIndex >= fIndex) + { + sb.Append(column.GetHeaderText()); + sb.Append(delimiter); + } + } + } + + if (sb.Length > 0) + { + sb.Length--; + sb.AppendLine(); + } + } + + int cIndex = 0; + int rIndex = -1; + + foreach (GridCell cell in cells) + { + if (fullCopy == true || usedColumns[cell.ColumnIndex] == true) + { + int rowIndex = cell.GridRow.GridIndex; + + if (rowIndex != rIndex) + { + if (rIndex >= 0) + sb.AppendLine(); + + rIndex = rowIndex; + cIndex = fIndex; + + if (includeGridIndex == true) + { + sb.Append(rowIndex); + sb.Append(delimiter); + } + } + + while (cIndex < cell.ColumnIndex) + { + cIndex++; + + if (fullCopy == true || usedColumns[cIndex] == true) + sb.Append(delimiter); + } + + sb.Append((formatValue ? cell.FormattedValue : cell.Value) ?? NullString ?? ""); + } + else + { + cIndex = cell.ColumnIndex; + } + } + + sb.AppendLine(); + + DataObject mData = new DataObject(); + mData.SetData(DataFormats.Text, true, sb.ToString()); + + Clipboard.SetDataObject(mData, true); + } + } + } + + #region CellComparer + + private class CellComparer : IComparer + { + public int Compare(GridCell x, GridCell y) + { + int xcol = x.ColumnIndex; + int xrow = x.GridRow.GridIndex; + + int ycol = y.ColumnIndex; + int yrow = y.GridRow.GridIndex; + + if (xrow < yrow) + return (-1); + + if (xrow > yrow) + return (1); + + if (xcol < ycol) + return (-1); + + if (xcol > ycol) + return (1); + + return (0); + } + } + + #endregion + + #region GetUsedColumns + + private BitArray GetUsedColumns(IEnumerable cells) + { + int visColumns = 0; + + foreach (GridColumn column in Columns) + { + if (column.Visible == true) + visColumns++; + } + + BitArray usedCells = new BitArray(Columns.Count); + + if (visColumns > 0) + { + foreach (GridCell cell in cells) + { + if (cell.GridColumn.Visible == true) + { + usedCells[cell.ColumnIndex] = true; + + if (--visColumns <= 0) + break; + } + } + } + + return (usedCells); + } + + #endregion + + #region GetFirstCellIndex + + private int GetFirstCellIndex(BitArray usedColumns) + { + for (int i = 0; i < usedColumns.Count; i++) + { + if (usedColumns[i] == true) + return (i); + } + + return (0); + } + + #endregion + + #endregion + + #region DataUpdate support + + /// + /// Calling the BeginDataUpdate routine informs the grid + /// that an extended data update phase has begun. The SuperGrid + /// will suspend all data notification and updates + /// until the corresponding EndDataUpdate routine is called. + /// + /// BeginDataUpdate / EndDataUpdate can be nested and must be + /// called in pairs every BeginDataUpdate must have a + /// matching EndDataUpdate call. + /// + public void BeginDataUpdate() + { + DataBinder.BeginUpdate(); + } + + /// + /// Calling the EndDataUpdate routine informs the grid + /// that an extended data update phase has ended. + /// + /// BeginDataUpdate / EndDataUpdate can be nested and must be + /// called in pairs every BeginDataUpdate must have a + /// matching EndDataUpdate call. + /// + public void EndDataUpdate() + { + DataBinder.EndUpdate(); + } + + #endregion + + #region UpdateDataBindings + + private void UpdateDataBindings() + { + if (DataBinder.ConnectionInProgress == false) + { + if (NeedToUpdateBoundData == true) + { + NeedToUpdateBoundData = false; + + if (VirtualMode == false) + Rows.Clear(); + + else if (DataSource != null) + VirtualRows.MaxRowIndex = 0; + + ClearAll(); + UnDeleteAll(); + } + + if (NeedToUpdateBindings == true) + { + NeedToUpdateBindings = false; + + DataBinder.Clear(); + + if (DataSource != null) + { + DataBinder.DataConnect(); + + _FilterEval = null; + + if (DataBinder.CurrencyManager == null) + NeedToUpdateBindings = true; + } + } + } + } + + #endregion + + #region UpdateDataFiltering + + internal void UpdateDataFiltering() + { + if (NeedToUpdateDataFilter == true) + { + GridRow arow = SuperGrid.ActiveRow as GridRow; + + if (arow == null || arow.IsTempInsertRow == false) + { + if (DeactivateEdit() == true) + { + NeedToUpdateDataFilter = false; + + if (arow != null && arow.RowNeedsGrouped == true) + NeedsGrouped = true; + + ClearAll(); + + DataFilter.FilterData(this); + + SuperGrid.NeedToUpdateIndicees = true; + + foreach (GridColumn col in Columns) + { + switch (col.GetAutoSizeMode()) + { + case ColumnAutoSizeMode.AllCells: + case ColumnAutoSizeMode.AllCellsExceptHeader: + case ColumnAutoSizeMode.DisplayedCells: + case ColumnAutoSizeMode.DisplayedCellsExceptHeader: + col.NeedsResized = true; + break; + } + } + } + SuperGrid.NeedToUpdateIndicees = true; + } + } + } + + #endregion + + #region UpdateVisibleRowCount + + internal void UpdateVisibleRowCount() + { + if (VirtualMode == true) + { + _VisibleRowCount = _VirtualRowCount; + _FilteredRowCount = 0; + } + else + { + _VisibleRowCount = 0; + + for (int i = 0; i < Rows.Count; i++) + { + if (Rows[i].Visible == true) + _VisibleRowCount++; + } + + _FilteredRowCount = 0; + + if (IsFiltered == true) + { + for (int i = 0; i < Rows.Count; i++) + { + GridRow row = Rows[i] as GridRow; + + if (row != null) + { + if (row.RowFilteredOut == true) + _FilteredRowCount++; + } + } + } + } + } + + #endregion + + #region ClearAllFilters + + /// + /// Clears all panel and column level filters + /// + public void ClearAllFilters() + { + ClearAllFilters(true, true); + } + + /// + /// Clears all panel and column level filters, as specified. + /// + public void ClearAllFilters( + bool clearPanelFilter, bool clearColumnFilters) + { + if (clearPanelFilter == true) + FilterExpr = null; + + if (clearColumnFilters == true) + { + if (Columns != null) + { + foreach (GridColumn col in Columns) + col.FilterExpr = null; + } + } + } + + #endregion + + #region ClearColumnFilterEvals + + internal void ClearColumnFilterEvals() + { + _FilterEval = null; + + if (_Columns != null) + { + foreach (GridColumn col in _Columns) + col.FilterEval = null; + } + } + + #endregion + + #region DetachDataSource + + /// + /// Detaches the grid from the bound DataSource. + /// If 'keepData' is true, then the data is kept (but no longer bound) + /// + /// + public void DetachDataSource(bool keepData) + { + if (DataSource != null) + { + if (keepData == true) + { + if (IsLayoutValid == false) + SuperGrid.ArrangeGrid(); + + if (VirtualMode == true) + { + VirtualRowCount = 0; + } + else + { + foreach (GridElement item in Rows) + { + GridRow row = item as GridRow; + + if (row != null) + { + foreach (GridCell cell in row.Cells) + cell.ValueExx = DataBinder.GetValue(cell, cell.ValueEx); + } + } + } + } + + DataSource = null; + + if (keepData == true) + { + NeedToUpdateBindings = false; + } + else + { + UpdateDataBindings(); + + if (VirtualMode == false) + Rows.Clear(); + } + } + } + + #endregion + + #region UpdateRowPosition + + internal void UpdateRowPosition(GridRow row) + { + if (KeepRowsSorted == true) + { + if (_SortColumns != null && _SortColumns.Count > 0) + { + RowComparer rc = new RowComparer(_SortColumns); + + GridContainer cont = (GridContainer)row.Parent; + + if (RowPositionOk(cont, row, rc) == false) + SortRow(cont, row, rc); + } + } + } + + #region RowPositionOk + + private bool RowPositionOk( + GridContainer cont, GridRow row, RowComparer rc) + { + if (cont.Rows.Count > 1) + { + GridRow prow = null; + + for (int i = row.RowIndex - 1; i >= 0; --i) + { + prow = cont.Rows[i] as GridRow; + + if (prow != null) + break; + } + + if (prow != null) + { + if (rc.Compare(prow, row) > 0) + return (false); + } + + GridRow nrow = null; + + for (int i = row.RowIndex + 1; i < cont.Rows.Count; i++) + { + nrow = cont.Rows[i] as GridRow; + + if (nrow != null) + break; + } + + if (nrow != null) + { + if (rc.Compare(nrow, row) < 0) + return (false); + } + } + + return (true); + } + + #endregion + + #region SortRow + + private void SortRow( + GridContainer cont, GridRow row, RowComparer rc) + { + int rowIndex = row.RowIndex; + + try + { + IsRowMoving = true; + + cont.Rows.RemoveAt(rowIndex); + + row.Parent = cont; + + int newRowIndex = GetRowPosition(cont, row, rc); + + cont.Rows.Insert(newRowIndex, row); + + if (newRowIndex < rowIndex) + { + int n = rowIndex; + rowIndex = newRowIndex; + newRowIndex = n; + } + + for (int i = rowIndex; i <= newRowIndex; i++) + ((GridContainer)cont.Rows[i]).RowIndex = i; + + if (UseAlternateRowStyle == true) + SuperGrid.UpdateStyleCount(); + } + finally + { + IsRowMoving = false; + + SuperGrid.NeedToUpdateIndicees = true; + ClearAll(); + + InvalidateMerge(); + } + } + + #endregion + + #region GetRowPosition + + private int GetRowPosition( + GridContainer cont, GridRow row, RowComparer rc) + { + int lo = 0; + int hi = cont.Rows.Count - 1; + + while (lo < hi) + { + int mid = (lo + hi) / 2; + + GridRow roe = cont.Rows[mid] as GridRow; + + if (roe != null) + { + int n = rc.Compare(row, roe); + + if (n == 0) + return (mid); + + if (n < 0) + hi = mid - 1; + else + lo = mid + 1; + } + } + + if ((uint)lo < cont.Rows.Count) + { + GridRow roe2 = cont.Rows[lo] as GridRow; + + if (roe2 != null) + { + if (rc.Compare(row, roe2) > 0) + lo++; + } + } + + return (lo); + } + + #endregion + + #endregion + + #region Style support + + #region GetSizingStyle + + internal StyleType GetSizingStyle() + { + return ((_SizingStyle == StyleType.NotSet) + ? SuperGrid.SizingStyle : _SizingStyle); + } + + #endregion + + #region DefaultVisualStylesPropertyChanged + + void DefaultVisualStylesPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (SuperGrid != null) + SuperGrid.UpdateStyleCount(); + + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + if (changeType == VisualChangeType.Layout) + { + NeedsMeasured = true; + + InvalidateMerge(); + } + else + { + InvalidateRender(); + } + } + + #endregion + + #region GetEffectiveStyle + + /// + /// Gets the Effective style used for the panel. + /// + /// + public GridPanelVisualStyle GetEffectiveStyle() + { + ValidateStyle(); + + if (_EffectiveStyle == null) + { + GridPanelVisualStyle style = new GridPanelVisualStyle(); + + style.ApplyStyle(SuperGrid.BaseVisualStyles.GridPanelStyle); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.GridPanelStyle); + style.ApplyStyle(DefaultVisualStyles.GridPanelStyle); + + SuperGrid.DoGetPanelStyleEvent(this, ref style); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + if (style.Font == null) + style.Font = SystemFonts.DefaultFont; + + _EffectiveStyle = style; + } + + return (_EffectiveStyle); + } + + #endregion + + #region ApplyCellStyle + + internal void ApplyCellStyle(CellVisualStyle style, StyleType cs) + { + ValidateStyle(); + + if (_EffectiveCellStyles == null) + _EffectiveCellStyles = new CellVisualStyles(); + + if (_EffectiveCellStyles.IsValid(cs) == false) + { + CellVisualStyle cstyle = new CellVisualStyle(); + + cstyle.ApplyStyle(SuperGrid.BaseVisualStyles.CellStyles[cs]); + cstyle.ApplyStyle(SuperGrid.DefaultVisualStyles.CellStyles[cs]); + cstyle.ApplyStyle(GridPanel.DefaultVisualStyles.CellStyles[cs]); + + _EffectiveCellStyles[cs] = cstyle; + } + + style.ApplyStyle(_EffectiveCellStyles[cs]); + } + + #endregion + + #region ApplyMergedCellStyle + + internal void ApplyMergedCellStyle(CellVisualStyle style, StyleType cs) + { + ValidateStyle(); + + if (_EffectiveMergedCellStyles == null) + _EffectiveMergedCellStyles = new CellVisualStyles(); + + if (_EffectiveMergedCellStyles.IsValid(cs) == false) + { + CellVisualStyle cstyle = new CellVisualStyle(); + + cstyle.ApplyStyle(SuperGrid.BaseVisualStyles.MergedCellStyles[cs]); + cstyle.ApplyStyle(SuperGrid.DefaultVisualStyles.MergedCellStyles[cs]); + cstyle.ApplyStyle(DefaultVisualStyles.MergedCellStyles[cs]); + + _EffectiveMergedCellStyles[cs] = cstyle; + } + + style.ApplyStyle(_EffectiveMergedCellStyles[cs]); + } + + #endregion + + #region ValidateStyle + + private void ValidateStyle() + { + if (_StyleUpdateCount != SuperGrid.StyleUpdateCount) + { + _EffectiveStyle = null; + _EffectiveCellStyles = null; + _EffectiveMergedCellStyles = null; + + ExpandButtonImage = null; + ExpandButtonHotImage = null; + CollapseButtonImage = null; + CollapseButtonHotImage = null; + + _StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #region InvalidateStyle + + /// + ///Invalidates the cached Style definition + /// + public override void InvalidateStyle() + { + if (SuperGrid != null) + _StyleUpdateCount = (ushort)(SuperGrid.StyleUpdateCount - 1); + + base.InvalidateStyle(); + } + + #endregion + + #endregion + + #region Markup support + + private void NoRowsMarkupTextChanged() + { + _NoRowsMarkup = null; + + if (EnableNoRowsMarkup == true) + { + if (MarkupParser.IsMarkup(_NoRowsText) == true) + { + _NoRowsMarkup = MarkupParser.Parse(_NoRowsText); + + if (_NoRowsMarkup != null) + _NoRowsMarkup.HyperLinkClick += NoRowsMarkupLinkClick; + } + } + } + + /// + /// Occurs when a text markup link is clicked + /// + protected virtual void NoRowsMarkupLinkClick(object sender, EventArgs e) + { + HyperLink link = sender as HyperLink; + + SuperGrid.DoNoRowsMarkupLinkClickEvent(this, link); + } + + /// + /// Gets plain text without text-markup (if text-markup is used in NoRowsText) + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public string NoRowsPlainText + { + get { return (_NoRowsMarkup != null ? _NoRowsMarkup.PlainText : _NoRowsText); } + } + + #endregion + + #region SetHeaderTooltip + + internal void SetHeaderTooltip(GridElement item, + object header, HeaderArea hitArea, string toolTip) + { + bool cancel = true; + + if (header is GridColumn) + cancel = SuperGrid.DoGetColumnHeaderToolTipEvent(this, (GridColumn)header, hitArea, ref toolTip); + + else if (header is ColumnGroupHeader) + cancel = SuperGrid.DoGetColumnGroupHeaderToolTipEvent(this, (ColumnGroupHeader)header, hitArea, ref toolTip); + + if (cancel == false) + { + if (SuperGrid.ToolTipText != toolTip) + SuperGrid.ToolTip.Hide(SuperGrid); + + SuperGrid.ToolTipText = toolTip; + } + else + { + SuperGrid.ToolTipText = ""; + } + } + + #endregion + + #region GenerateColumns + + /// + /// Generates base column definitions from the associated DataSource. + /// Note that all previous column definitions are left unaltered. + /// + public void GenerateColumns() + { + GenerateColumns(null); + } + + /// + /// Generates column definitions from the associated DataSource, utilizing + /// the provided callback to perform the actual creation of the associated GridColumn. + /// + public void GenerateColumns(GetNewGridColumn callBack) + { + DataBinder.AutoGenerateColumns(callBack); + } + + #endregion + + #region ToString + + /// + /// ToString + /// + /// + public override string ToString() + { + string s = base.ToString(); + + if (String.IsNullOrEmpty(_Name) == false) + s += ": (\"" + _Name + "\")"; + + return (s); + } + + #endregion + + #region PanelStates + + #region Psi (Panel States - Property 0) + + [Flags] + private enum Psp0 : uint + { + AllowEdit = (1U << 0), + AllowEmptyCellSelection = (1U << 1), + AllowNullCellMerge = (1U << 2), + + AllowRowDelete = (1U << 3), + AllowRowHeaderResize = (1U << 4), + AllowRowInsert = (1U << 5), + AllowRowResize = (1U << 6), + + AutoExpandSetGroup = (1U << 7), + AutoGenerateColumns = (1U << 8), + AutoHideDeletedRows = (1U << 9), + AutoSelectDeleteBoundRows = (1U << 10), + AutoSelectNewBoundRows = (1U << 11), + + CheckBoxes = (1U << 12), + + EnableCellExpressions = (1U << 13), + EnableCellMerging = (1U << 14), + EnableCellRangeMarkup = (1U << 15), + EnableColumnFiltering = (1U << 16), + EnableDiscreteBoundRows = (1U << 17), + EnableFiltering = (1U << 18), + EnableNoRowsMarkup = (1U << 19), + EnableRowFiltering = (1U << 20), + EnableSelectionBuffering = (1U << 21), + + UseAlternateColumnStyle = (1U << 22), + UseAlternateRowStyle = (1U << 23), + } + + #endregion + + #region Psi (Panel States - Property 1) + + [Flags] + private enum Psp1 : uint + { + EnsureVisibleAfterSort = (1U << 0), + EnsureVisibleAfterGrouping = (1U << 1), + + EnterKeySelectsNextRow = (1U << 2), + FilterIgnoreMatchCase = (1U << 3), + FocusCuesEnabled = (1U << 4), + ImmediateResize = (1U << 5), + IndentGroups = (1U << 6), + KeepRowsSorted = (1U << 7), + MultiSelect = (1U << 8), + OnlySendFinalRowActivatedEvents = (1U << 9), + + ShowCellInfo = (1U << 10), + ShowDropShadow = (1U << 11), + ShowEditingImage = (1U << 12), + ShowGroupExpand = (1U << 13), + ShowGroupUnderline = (1U << 14), + ShowInsertRowImage = (1U << 15), + ShowRowHeaders = (1U << 16), + ShowRowInfo = (1U << 17), + ShowRowGridIndex = (1U << 18), + ShowRowDirtyMarker = (1U << 19), + ShowInsertRow = (1U << 20), + ShowToolTips = (1U << 21), + ShowTreeButtons = (1U << 22), + ShowTreeLines = (1U << 23), + ShowWhitespaceRowLines = (1U << 24), + + SortUsingHiddenColumns = (1U << 25), + VirtualMode = (1U << 26), + } + + #endregion + + #region Psi (Panel States - Internal) + + [Flags] + private enum Psi : uint + { + EnsureRowVisible = (1 << 0), + + InRangeAdd = (1 << 1), + IsRowMoving = (1 << 2), + IsSorting = (1 << 3), + + LoadInsertRow = (1 << 4), + + NeedsFilterScan = (1 << 5), + NeedsGrouped = (1 << 6), + NeedsGroupSorted = (1 << 7), + NeedsSorted = (1 << 8), + + NeedToUpdateBindings = (1 << 9), + NeedToUpdateDataFilter = (1 << 10), + + PreActiveRowDirty = (1 << 11), + ReselectActiveItem = (1 << 12), + SelectActiveRow = (1 << 13), + + NeedToUpdateBoundData = (1 << 14), + } + + #endregion + + #endregion + + #region IDispose + + /// + /// Dispose + /// + public override void Dispose() + { + DataBinder = null; + + ExpandButtonImage = null; + ExpandButtonHotImage = null; + CollapseButtonImage = null; + CollapseButtonHotImage = null; + + Rows = null; + + if (_Columns != null) + _Columns.CollectionChanged -= ColumnsCollectionChanged; + + base.Dispose(); + } + + #endregion + } + + #region Attributes + + /// + /// Attribute to control the visibility of individual fields + /// or properties in an IList data source to the SuperGrid. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public class IsVisibleToSuperGrid : Attribute + { + private bool _Visible; + + /// + /// IsVisibleToSuperGrid + /// + /// + public IsVisibleToSuperGrid(bool visible) + { + _Visible = visible; + } + + /// + /// Visible + /// + public bool Visible + { + get { return (_Visible); } + set { _Visible = value; } + } + } + + #endregion + + #region Delegates + + public delegate GridColumn GetNewGridColumn(); + + #endregion + + #region enums + + #region ActiveRowIndicatorStyle + + /// + /// ActiveRowIndicatorStyle + /// + public enum ActiveRowIndicatorStyle + { + /// + /// No indicator will be displayed. + /// + None, + + /// + /// An image will be displayed. + /// + Image, + + /// + /// The Row Header will be highlighted. + /// + Highlight, + + /// + /// An image will be displayed and the + /// Row Header will be highlighted. + /// + Both, + } + + #endregion + + #region CellDragBehavior + + /// + /// Specifies the resultant behavior + /// of clicking and dragging on a grid cell + /// + public enum CellDragBehavior + { + /// + /// Dragging will have no effect + /// + None, + + /// + /// Dragging will extend the selection + /// + ExtendSelection, + } + + #endregion + + #region ColumnHeaderClickBehavior + + /// + /// Specifies the resultant behavior + /// of clicking on a column header + /// + public enum ColumnHeaderClickBehavior + { + /// + /// Clicking on a column header will have no effect + /// + None, + + /// + /// Clicking on a column header will select the + /// column, and dragging will extend the selection + /// if ColumnDragBehavior is set to ExtendClickBehavior + /// + Select, + + /// + /// Clicking on a column header will sort the grid using + /// that column, or will reorder the column if ColumnDragBehavior + /// is set to ExtendClickBehavior + /// + SortAndReorder, + } + + #endregion + + #region ColumnDragBehavior + + /// + /// Specifies the resultant behavior + /// of dragging a column header + /// + public enum ColumnDragBehavior + { + /// + /// Dragging on a column header will have no effect + /// + None, + + /// + /// Dragging a column header will + /// extend the set ColumnHeaderClickBehavior + /// + ExtendClickBehavior, + } + + #endregion + + #region FilterLevel + + /// + /// FilterLevel + /// + [Flags] + public enum FilterLevel + { + /// + /// No data filtered + /// + None = 0, + + /// + /// Root level data filtered + /// + Root = (1 << 0), + + /// + /// Root level data filtered + /// conditional upon Rows collection being empty + /// + RootConditional = (1 << 1), + + /// + /// Expanded level data filtered + /// + Expanded = (1 << 2), + + /// + /// All data filtered + /// + All = (Root | Expanded), + + /// + /// All data filtered, Root Level data filtered + /// conditional upon Rows collection being empty + /// + AllConditional = (RootConditional | Expanded), + } + + #endregion + + #region FilterMatchType + + /// + /// Specifies what match style to use when filtering data elements + /// + public enum FilterMatchType + { + /// + /// Not set + /// + NotSet, + + /// + /// No special matching + /// + None, + + /// + /// Regular Expression matching + /// + RegularExpressions, + + /// + /// Wildcard matching + /// + Wildcards, + } + + #endregion + + #region GridLines + + /// + /// Specifies which grid lines are displayed + /// + public enum GridLines + { + /// + /// No grid lines are displayed + /// + None, + + /// + /// Only horizontal grid lines are displayed + /// + Horizontal, + + /// + /// Only vertical grid lines are displayed + /// + Vertical, + + /// + /// Both horizontal and vertical grid lines are displayed + /// + Both, + } + + #endregion + + #region GroupChangedAction + + /// + /// Specifies how the panel grouping has changed + /// + public enum GroupChangedAction + { + /// + /// Group added + /// + Add, + + /// + /// Group removed + /// + Remove, + + /// + /// Reset - all items cleared + /// + Reset, + } + + #endregion + + #region GroupHeaderClickBehavior + + /// + /// Specifies the behavior when a user + /// clicks on a group header + /// + public enum GroupHeaderClickBehavior + { + /// + /// Clicking on a group header will have no effect + /// + None, + + /// + /// Clicking on a header will + /// expand or collapse the group + /// + ExpandCollapse, + + /// + /// Clicking on a group heading will select the header + /// + Select, + + /// + /// Clicking on a group heading will + /// select all the first-level rows contained in the group + /// + SelectAll, + } + + #endregion + + #region GroupHeaderKeyBehavior + + /// + /// Specifies the behavior when a user + /// moves via the keyboard onto a group header + /// + public enum GroupHeaderKeyBehavior + { + /// + /// Header will be skipped + /// + Skip, + + /// + /// Header will be selected + /// + Select, + } + + #endregion + + #region GroupSortElement + + /// + /// Specifies the group element used to sort panel groups. + /// + public enum GroupSortElement + { + /// + /// Sort by Group Id + GroupId, + + /// + /// Sort by Group Text + /// + GroupText, + + /// + /// Sort by associated cell Value + /// + CellValue, + } + + #endregion + + #region KeyboardEditMode + + /// + /// Which keyboard actions will start a cell edit operation + /// + public enum KeyboardEditMode + { + /// + /// No keyboard action will initiate an edit + /// + None, + + /// + /// Edit initiated when any alphanumeric key + /// is pressed while the cell has focus + /// + EditOnKeystroke, + + /// + /// Edit initiated when F2 is pressed while the cell + /// has focus. This mode places the selection point at + /// the end of the cell contents + /// + EditOnF2, + + /// + /// Editing begins when any alphanumeric key + /// or F2 is pressed while the cell has focus + /// + EditOnKeystrokeOrF2, + + /// + /// Editing begins on entry to a cell + /// + EditOnEntry + } + + #endregion + + #region MouseEditMode + + /// + /// Which mouse actions will start a cell edit operation + /// + public enum MouseEditMode + { + /// + /// No mouse action will initiate an edit + /// + None, + + /// + /// Single clicking a cell will initiate an edit + /// + SingleClick, + + /// + /// Double clicking a cell will initiate an edit + /// + DoubleClick, + } + + #endregion + + #region NestedListScanTypes + + /// + /// Specifies what IList "types" are scanned when looking + /// for possible "child" sub-panel IList entries. + /// + [Flags] + public enum NestedListScanTypes + { + /// + /// No IList "types" are scanned + /// + None = 0, + + /// + /// IList "Fields" are scanned + /// + Fields = (1 << 0), + + /// + /// IList "Properties" are scanned + /// + Properties = (1 << 1), + + /// + /// Both IList "Fields" and "Properties" are scanned + /// + FieldsAndProperties = (Fields | Properties), + } + + #endregion + + #region NullValue + + /// + /// Specifies how null values are interpreted + /// + public enum NullValue + { + /// + /// A null is interpreted to be a null object reference + /// + NullReference, + + /// + /// A null is interpreted to be an instance of DBNull.Value + /// + DBNull, + } + + #endregion + + #region PanelArea + + /// + /// PanelArea + /// + public enum PanelArea + { + /// + /// In Content + /// + InContent, + + /// + /// In WhiteSpace + /// + InWhiteSpace, + } + + #endregion + + #region ProcessChildRelations + + /// + /// Specifies the conditions under which + /// encountered child relations will be processed + /// + public enum ProcessChildRelations + { + /// + /// Always + /// + Always, + + /// + /// Never + /// + Never, + + /// + /// Only when data present + /// + WhenDataPresent, + } + + #endregion + + #region RelativeRow + + /// + /// Relative row (cardinality) + /// + public enum RelativeRow + { + /// + /// No Row + /// + None, + + /// + /// First Row + /// + FirstRow, + + /// + /// Insertion Row + /// + InsertionRow, + + /// + /// Last Row + /// + LastRow, + } + + #endregion + + #region RelativeSelection + + /// + /// RelativeSelection + /// + public enum RelativeSelection + { + /// + /// None + /// + None, + + /// + /// FirstCell + /// + FirstCell, + + /// + /// LastCell + /// + LastCell, + + /// + /// PrimaryCell + /// + PrimaryCell, + + /// + /// Row + /// + Row, + } + + #endregion + + #region RowDragBehavior + + /// + /// Specifies the resultant behavior + /// of clicking and dragging on a row header + /// + public enum RowDragBehavior + { + /// + /// Dragging on a row header will have no effect + /// + None, + + /// + /// Dragging a row header will extend the selection + /// + ExtendSelection, + + /// + /// Dragging a row header will initiate a row move that + /// will be constrained to stay within the current group. + /// + Move, + + /// + /// Dragging a row header will initiate a row move that + /// can cross group row boundaries + /// + GroupMove, + } + + #endregion + + #region RowEditMode + + /// + /// Defines whether editing is initiated on the primary cell + /// or the cell under the mouse when row level editing is enabled + /// + public enum RowEditMode + { + /// + /// Initiate edit on PrimaryCell + /// + PrimaryCell, + + /// + /// Initiate edit on clicked cell + /// + ClickedCell, + } + + #endregion + + #region RowFocusMode + + /// + /// Defines what portion of the row is "focused". + /// Default is "FullRow" + /// + /// + public enum RowFocusMode + { + /// + /// Full row will be focused + /// + FullRow, + + /// + /// Only cells will be focused + /// + CellsOnly, + } + + #endregion + + #region RowHighlightType + + /// + /// Specifies the type of highlighting + /// to employ when a grid row is selected + /// + public enum RowHighlightType + { + /// + /// No highlighting + /// + None, + + /// + /// Entire row will be Highlighted + /// + Full, + + /// + /// Only the PrimaryColumn + /// cell contents will be Highlighted + /// + PrimaryColumnOnly, + } + + #endregion + + #region RowWhitespaceClickBehavior + + /// + /// Specifies the resultant behavior + /// of clicking in the row whitespace area + /// + public enum RowWhitespaceClickBehavior + { + /// + /// No effect + /// + None, + + /// + /// Current selection is cleared + /// + ClearSelection, + + /// + /// Extends the row selection + /// + ExtendSelection, + } + + #endregion + + #region SelectionGranularity + + /// + /// Determines whether row or cell selection is permitted with in the grid + /// + public enum SelectionGranularity + { + /// + /// Individual cells may be selected + /// + Cell, + + /// + /// Only entire rows may be selected + /// + Row, + + /// + /// Only entire rows may be selected, but individual + /// cells will be highlighted when mouse is over cell. + /// + RowWithCellHighlight + } + + #endregion + + #region ShowCellInfoDisplayMode + + /// + /// ShowCellInfoDisplayMode + /// + public enum ShowCellInfoDisplayMode + { + /// + /// Info Image will only be shown when the associated + /// InfoText value is non-empty (null or zero length). + /// + ShowWithNonEmptyText, + + /// + /// Info Image will be shown when the associated + /// InfoText value is any value (empty or not). + /// + ShowWithEmptyText, + } + + #endregion + + #region ShowRowInfoDisplayMode + + /// + /// ShowRowInfoDisplayMode + /// + public enum ShowRowInfoDisplayMode + { + /// + /// Info Image will only be shown when the associated + /// InfoText value is non-empty (null or zero length). + /// + ShowWithNonEmptyText, + + /// + /// Info Image will be shown when the associated + /// InfoText value is any value (empty or not). + /// + ShowWithEmptyText, + } + + #endregion + + #region SortCycle + + /// + /// SortCycle + /// + public enum SortCycle + { + /// + /// Not Set (default is AscDesc) + /// + NotSet, + + /// + /// Cycles between Ascending and Descending + /// + AscDesc, + + /// + /// Cycles between Ascending, Descending, and None + /// + AscDescNone, + + } + + #endregion + + #region SortDirection + + /// + /// SortDirection + /// + public enum SortDirection + { + /// + /// No sorting + /// + None, + + /// + /// Ascending + /// + Ascending, + + /// + /// Descending + /// + Descending + } + + #endregion + + #region SortLevel + + /// + /// SortLevel + /// + [Flags] + public enum SortLevel + { + /// + /// No data sorting + /// + None = 0, + + /// + /// Root level data + /// + Root = (1 << 0), + + /// + /// Expanded level data + /// + Expanded = (1 << 1), + + /// + /// All data + /// + All = (Root | Expanded), + } + + #endregion + + #region TopLeftHeaderSelectBehavior + + /// + /// TopLeftHeaderSelectBehavior + /// + public enum TopLeftHeaderSelectBehavior + { + /// + /// No selection + /// + NoSelection, + + /// + /// No selection + /// + SelectAllCells, + + /// + /// All columns will be selected + /// + SelectAllColumns, + + /// + /// All rows will be selected + /// + SelectAllRows, + + /// + /// Element selection will be determined by + /// the current set SelectionGranularity + /// + Deterministic, + } + + #endregion + + #region WhitespaceClickBehavior + + /// + /// Specifies the resultant behavior + /// of clicking in the grid panel whitespace area + /// + public enum WhitespaceClickBehavior + { + /// + /// No effect + /// + None, + + /// + /// Current selection is cleared + /// + ClearSelection, + } + + #endregion + + #endregion + + #region IEnumeration + + #region FlatEnumeration + + internal class FlatEnumeration : IEnumerator, IEnumerable + { + #region Private variables + + private GridPanel _Panel; + + private int _CurIndex; + private GridContainer _CurItem; + private GridContainer _CurContainer; + + private Stack _IndexStack; + private Stack _ContStack; + + #endregion + + public FlatEnumeration(GridPanel panel) + { + _Panel = panel; + + Reset(); + } + + #region Protected properties + + protected GridContainer CurItem + { + get { return (_CurItem); } + } + + #endregion + + #region IEnumerable support + + #region MoveNext + + public bool MoveNext() + { + PushCurItem(); + + while (GetNextItem() == false) + { + if (_ContStack.Count <= 0) + return (false); + + PopCurItem(); + } + + return (true); + } + + #region GetNextItem + + private bool GetNextItem() + { + if (_Panel.VirtualMode == true) + { + while (++_CurIndex < _Panel.VirtualRowCount) + { + _CurItem = _Panel.VirtualRows[_CurIndex] as GridContainer; + + if (_CurItem != null) + { + if (MatchedItem() == true) + return (true); + + PushCurItem(); + } + } + } + else + { + while (++_CurIndex < _CurContainer.Rows.Count) + { + _CurItem = _CurContainer.Rows[_CurIndex] as GridContainer; + + if (_CurItem != null) + { + if (MatchedItem() == true) + return (true); + + PushCurItem(); + } + } + } + + return (false); + } + + #endregion + + #region MatchedItem + + public virtual bool MatchedItem() + { + return (true); + } + + #endregion + + #region CheckNested + + public virtual bool CheckNested() + { + return (true); + } + + #endregion + + #region PushCurItem + + private void PushCurItem() + { + if (_CurItem != null) + { + if (_Panel.VirtualMode == false && _CurItem.Rows.Count > 0) + { + if (CurItem.RowsUnresolved == false && CheckNested() == true) + { + _ContStack.Push(_CurContainer); + _IndexStack.Push(_CurIndex); + + _CurIndex = -1; + _CurContainer = _CurItem; + } + } + } + } + + #endregion + + #region PopCurItem + + private void PopCurItem() + { + _CurContainer = _ContStack.Pop(); + _CurIndex = _IndexStack.Pop(); + } + + #endregion + + #endregion + + #region Reset + + public void Reset() + { + _CurIndex = -1; + _CurItem = null; + _CurContainer = _Panel; + + _IndexStack = new Stack(); + _ContStack = new Stack(); + } + + #endregion + + #region Current + + public object Current + { + get { return (_CurItem); } + } + + #endregion + + #region GetEnumerator + + public IEnumerator GetEnumerator() + { + return (this); + } + + #endregion + + #endregion + } + + #endregion + + #region FlatCheckedRowsEnumeration + + class FlatCheckedRowsEnumeration : FlatEnumeration + { + #region Private variables + + private bool _InclExpanded; + + #endregion + + public FlatCheckedRowsEnumeration(GridPanel panel, bool inclExpanded) + : base(panel) + { + _InclExpanded = inclExpanded; + } + + #region MatchedItem + + public override bool MatchedItem() + { + return (CurItem.Checked == true && CurItem.IsDeleted == false); + } + + #endregion + + #region CheckNested + + public override bool CheckNested() + { + return (_InclExpanded == true && CurItem.IsDeleted == false); + } + + #endregion + } + + #endregion + + #region FlatDeletedRowsEnumeration + + class FlatDeletedRowsEnumeration : FlatEnumeration + { + public FlatDeletedRowsEnumeration(GridPanel panel) + : base(panel) + { + } + + #region MatchedItem + + public override bool MatchedItem() + { + return (CurItem.IsDeleted); + } + + #endregion + } + + #endregion + + #region FlatDirtyRowsEnumeration + + class FlatDirtyRowsEnumeration : FlatEnumeration + { + #region Private variables + + private bool _InclExpanded; + + #endregion + + public FlatDirtyRowsEnumeration(GridPanel panel, bool inclExpanded) + : base(panel) + { + _InclExpanded = inclExpanded; + } + + #region MatchedItem + + public override bool MatchedItem() + { + if (CurItem.IsDeleted == true) + return (false); + + if (CurItem is GridRow) + return (((GridRow)CurItem).RowDirty); + + return (false); + } + + #endregion + + #region CheckNested + + public override bool CheckNested() + { + return (_InclExpanded == true && CurItem.IsDeleted == false); + } + + #endregion + } + + #endregion + + #region FlatSelectedRowsEnumeration + + class FlatSelectedRowsEnumeration : FlatEnumeration + { + #region Private variables + + private bool _InclExpanded; + + #endregion + + public FlatSelectedRowsEnumeration(GridPanel panel, bool inclExpanded) + : base(panel) + { + _InclExpanded = inclExpanded; + } + + #region MatchedItem + + public override bool MatchedItem() + { + return (CurItem.IsSelected == true && CurItem.IsDeleted == false); + } + + #endregion + + #region CheckNested + + public override bool CheckNested() + { + return (_InclExpanded == true && CurItem.IsDeleted == false); + } + + #endregion + } + + #endregion + + #region FlatRowsEnumeration + + class FlatRowsEnumeration : FlatEnumeration + { + #region Private variables + + private bool _OnlyExpanded; + private bool _OnlyVisible; + + #endregion + + public FlatRowsEnumeration(GridPanel panel, bool onlyExpanded, bool onlyVisible) + : base(panel) + { + _OnlyExpanded = onlyExpanded; + _OnlyVisible = onlyVisible; + } + + #region MatchedItem + + public override bool MatchedItem() + { + if (CurItem.IsDeleted == false) + { + if (_OnlyVisible == false || CurItem.Visible == true) + return (true); + } + + return (false); + } + + #endregion + + #region CheckNested + + public override bool CheckNested() + { + if (CurItem.IsDeleted == true) + return (false); + + return (_OnlyExpanded == false || CurItem.Expanded == true); + } + + #endregion + } + + #endregion + + #region OnScreenColumnsEnumeration + + class OnScreenColumnsEnumeration : IEnumerator, IEnumerable + { + #region Private variables + + private GridPanel _Panel; + + private int _CurIndex; + private GridColumn _CurItem; + + #endregion + + public OnScreenColumnsEnumeration(GridPanel panel) + { + _Panel = panel; + + Reset(); + } + + #region IEnumerable support + + public bool MoveNext() + { + int[] map = _Panel.Columns.DisplayIndexMap; + + while (++_CurIndex < map.Length) + { + _CurItem = _Panel.Columns[map[_CurIndex]]; + + if (_CurItem.IsOnScreen == true) + return (true); + } + + return (false); + } + + public void Reset() + { + _CurIndex = -1; + } + + public object Current + { + get { return (_CurItem); } + } + + public IEnumerator GetEnumerator() + { + return (this); + } + + #endregion + } + + #endregion + + #region OnScreenRowsEnumeration + + class OnScreenRowsEnumeration : IEnumerator, IEnumerable + { + #region Private variables + + private GridPanel _Panel; + + private int _CurIndex; + private GridContainer _CurItem; + + private int _FirstVisibleRow; + private int _LastVisibleRow; + + #endregion + + public OnScreenRowsEnumeration(GridPanel panel) + { + _Panel = panel; + + _FirstVisibleRow = panel.FirstOnScreenRowIndex; + _LastVisibleRow = panel.LastOnScreenRowIndex; + + Reset(); + } + + #region IEnumerable support + + public bool MoveNext() + { + _CurIndex = (_CurIndex == -1) ? + _FirstVisibleRow : _CurIndex + 1; + + if (_CurIndex <= _LastVisibleRow) + { + if (_Panel.VirtualMode == true) + _CurItem = _Panel.VirtualRows[_CurIndex]; + else + _CurItem = (GridContainer)_Panel.Rows[_CurIndex]; + + return (true); + } + + return (false); + } + + public void Reset() + { + _CurIndex = -1; + } + + public object Current + { + get { return (_CurItem); } + } + + public IEnumerator GetEnumerator() + { + return (this); + } + + #endregion + } + + #endregion + + #region SelectedEnumeration + + class SelectedEnumeration : IEnumerator, IEnumerable + { + #region Private variables + + private GridPanel _Panel; + private SelectedElements _SelectedElements; + + private int _CurIndex; + + #endregion + + protected SelectedEnumeration( + GridPanel panel, SelectedElements selectedElements) + { + _Panel = panel; + _SelectedElements = selectedElements; + + Reset(); + } + + #region Protected properties + + protected GridPanel Panel + { + get { return (_Panel); } + } + + protected int CurIndex + { + get { return (_CurIndex); } + } + + #endregion + + #region IEnumerable support + + public bool MoveNext() + { + return (_SelectedElements.GetNextIndex(ref _CurIndex)); + } + + public void Reset() + { + _CurIndex = -1; + } + + public object Current + { + get { return (GetCurrent); } + } + + protected virtual object GetCurrent + { + get { return (null); } + } + + public IEnumerator GetEnumerator() + { + return (this); + } + + #endregion + } + + #endregion + + #region SelectedRowsEnumeration + + class SelectedRowsEnumeration : SelectedEnumeration + { + public SelectedRowsEnumeration(GridPanel panel, SelectedElements selectedElements) + : base(panel, selectedElements) + { + } + + protected override object GetCurrent + { + get { return (Panel.GetRowFromIndex(CurIndex)); } + } + } + + #endregion + + #region SelectedColumnsEnumeration + + class SelectedColumnsEnumeration : SelectedEnumeration + { + public SelectedColumnsEnumeration(GridPanel panel, SelectedElements selectedElements) + : base(panel, selectedElements) + { + } + + protected override object GetCurrent + { + get { return (Panel.Columns[CurIndex]); } + } + } + + #endregion + + #region SelectedCellsEnumeration + + class SelectedCellsEnumeration : IEnumerator, IEnumerable + { + #region Private variables + + private GridPanel _Panel; + + private int _CurIndex; + private int _CurColumnIndex; + + private GridCell _CurGridCell; + private GridCell _EmptyCell; + + #endregion + + public SelectedCellsEnumeration(GridPanel panel) + { + _Panel = panel; + + Reset(); + } + + #region IEnumerable support + + public bool MoveNext() + { + if (_CurColumnIndex == -1) + { + _CurColumnIndex++; + _CurIndex = -1; + } + + while (_CurColumnIndex < _Panel.Columns.Count) + { + GridColumn column = _Panel.Columns[_CurColumnIndex]; + + while (column.SelectedCells.GetNextIndex(ref _CurIndex) == true) + { + GridRow row = _Panel.GetRowFromIndex(_CurIndex) as GridRow; + + if (row != null) + { + _CurGridCell = row.GetCell(_CurColumnIndex); + + if (_CurGridCell == null) + { + _EmptyCell = row.GetEmptyCell(_EmptyCell, _CurColumnIndex); + + if (_EmptyCell != null) + { + _CurGridCell = _EmptyCell; + + return (true); + } + } + else + { + if (_CurGridCell.AllowSelection == true) + return (true); + } + } + } + + _CurColumnIndex++; + _CurIndex = -1; + } + + return (false); + } + + public void Reset() + { + _CurIndex = -1; + _CurColumnIndex = -1; + } + + public object Current + { + get { return (_CurGridCell); } + } + + public IEnumerator GetEnumerator() + { + return (this); + } + + #endregion + } + + #endregion + + #endregion + + #region BlankExpandableObjectConverter + + /// + /// BlankExpandableObjectConverter + /// + public class BlankExpandableObjectConverter : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + return (" "); + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridRenderInfo.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridRenderInfo.cs new file mode 100644 index 00000000..28bf49b7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridRenderInfo.cs @@ -0,0 +1,40 @@ +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Provides the rendering information for grid render pass. + /// + public class GridRenderInfo + { + #region Public properties + + /// + /// Gets or sets the reference to Graphics object used for rendering. + /// + public readonly Graphics Graphics; + + /// + /// Gets or sets the clip rectangle. + /// + public readonly Rectangle ClipRectangle; + + /// + /// Gets or sets whether right-to-left layout is in effect. + /// + public bool RightToLeft; + + #endregion + + /// + /// Initializes a new instance of the GridRenderInfo class. + /// + /// Graphics object + /// Control clip rectangle + public GridRenderInfo(Graphics graphics, Rectangle clipRectangle) + { + Graphics = graphics; + ClipRectangle = clipRectangle; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridRow.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridRow.cs new file mode 100644 index 00000000..84f3fb16 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridRow.cs @@ -0,0 +1,5469 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using System.Windows.Forms; +using System.Windows.Forms.VisualStyles; +using DevComponents.DotNetBar.SuperGrid.Primitives; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Represents a grid row consisting of one or more grid cells. + /// + public class GridRow : GridContainer + { + #region Constants + + private const int SeparatorHeight = 2; + + #endregion + + #region Static data + + private static bool _dragSelection; + private static bool _dragStarted; + + private static FloatWindow _separatorFw; + private static FloatWindow _headerFw; + + #endregion + + #region Private variables + + private readonly GridCellCollection _Cells; + + private int _AnchorIndex; + private int _RowHeight = -1; + private int _PreDetailRowHeight = -1; + private int _PostDetailRowHeight = -1; + private int _EffectivePreDetailRowHeight; + private int _EffectivePostDetailRowHeight; + + private Rs _States; + + private RowArea _HitArea; + private GridContainer _HitItem; + private RowArea _LastArea; + + private RowArea _MouseDownHitArea; + private GridContainer _MouseDownHitRow; + private Point _MouseDownPoint; + private int _MouseDownDelta; + + private GridContainer _SeparatorRow; + + private string _InfoText; + private Rectangle _InfoImageBounds; + private Rectangle _ExpandButtonBounds; + + private object _DataItem; + private int _DataItemIndex = -1; + + private GridCell _EmptyRenderCell; + private GridCell _EmptySelectionCell; + + private ushort _ArrangeLayoutCount; + private ushort _MeasureCount; + private Size _RowHeaderSize; + + private ushort _StyleUpdateCount; + private CellVisualStyles _EffectiveCellStyles; + + private CellMergeMode _CellMergeMode = CellMergeMode.NotSet; + private GridPanel _AllocPanel; + + #endregion + + #region Constructors + + /// + /// Creates a new GridRow + /// + public GridRow() + { + SetState(Rs.AllowEdit, true); + SetState(Rs.Visible, true); + + _Cells = new GridCellCollection(); + _Cells.CollectionChanged += CellsCollectionChanged; + } + + /// + /// Creates a new GridRow + /// + /// + public GridRow(string text) + : this() + { + GridCell cell = new GridCell(); + cell.Value = text; + + _Cells.Add(cell); + } + + /// + /// Creates a new GridRow + /// + /// + public GridRow(IEnumerable cells) + : this() + { + foreach (GridCell cell in cells) + _Cells.Add(cell); + } + + /// + /// Creates a new GridRow + /// + /// + public GridRow(IEnumerable values) + : this() + { + foreach (object o in values) + _Cells.Add(new GridCell(o)); + } + + /// + /// Creates a new GridRow + /// + /// + public GridRow(params object[] values) + : this() + { + foreach (object o in values) + _Cells.Add(new GridCell(o)); + } + + #endregion + + #region Public properties + + #region AllowEdit + + /// + /// Gets or sets whether the row cells can be edited by the user. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether the row cells can be edited by the user.")] + public bool AllowEdit + { + get { return (TestState(Rs.AllowEdit)); } + + set + { + if (value != AllowEdit) + { + SetState(Rs.AllowEdit, value); + + OnPropertyChanged("AllowEdit"); + } + } + } + + #endregion + + #region Bounds + + /// + /// Gets the scroll adjusted bounds of the row + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle Bounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = BoundsRelative; + + if (panel.IsSubPanel == true) + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + r.Height = FixedRowHeight; + + return (r); + } + + return (Rectangle.Empty); + } + } + + #endregion + + #region Checked + + /// + /// Gets or sets the row CheckBox checked state + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates the row CheckBox checked state.")] + public override bool Checked + { + get { return (base.Checked); } + + set + { + if (Checked != value) + { + base.Checked = value; + + RowCheckChanged = true; + } + } + } + + #endregion + + #region Cells + + /// + /// Gets a reference to the Cells collection. Cells in the + /// Cells member are not allocated by default, but are only + /// done so if the cell Values are provided to the GridRow + /// constructor at row allocation time. Row cells can be allocated + /// later, and assigned (or added) to the current Cells collection. + /// Cells are sequentially allocated, thus you can not allocate and + /// assign Cell 10 without also having allocated and assigned cells 0 - 9. + /// + [DefaultValue(null), Category("Data")] + [Description("Indicates a reference to the Cells collection.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridCellCollection Cells + { + get { return (_Cells); } + } + + #endregion + + #region DataItem + + /// + /// Gets the object to which the row is bound. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public object DataItem + { + get { return (_DataItem); } + internal set { _DataItem = value; } + } + + #endregion + + #region EditorDirty + + /// + /// Gets or sets whether the value being edited has changed. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool EditorDirty + { + get { return (TestState(Rs.EditorDirty)); } + + set + { + if (EditorDirty != value) + { + SetState(Rs.EditorDirty, value); + + GridPanel panel = GridPanel; + + if (panel != null) + { + if (value == false) + { + SetState(Rs.RowDirty, true); + SetState(Rs.RowNeedsStored, true); + } + else + { + ProcessNewRowChange(panel); + } + + InvalidateRowHeader(); + } + } + } + } + + #endregion + + #region EffectivePreDetailRowHeight + + /// + /// Gets the effective height of the "pre detail" portion of the + /// row (the area at the bottom of the row). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int EffectivePreDetailRowHeight + { + get { return (_EffectivePreDetailRowHeight); } + } + + #endregion + + #region EffectivePostDetailRowHeight + + /// + /// Gets the effective height of the "post detail" portion of the + /// row (the area at the bottom of the row). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int EffectivePostDetailRowHeight + { + get { return (_EffectivePostDetailRowHeight); } + } + + #endregion + + #region FirstFrozenCell + + /// + /// Gets a reference to the first Frozen cell + /// or null if there is none. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell FirstFrozenCell + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn column = panel.FirstFrozenColumn; + + if (column != null) + { + int index = column.ColumnIndex; + + if (index < _Cells.Count) + return (_Cells[index]); + } + } + + return (null); + } + } + + #endregion + + #region FirstOnScreenCell + + /// + /// Gets a reference to the first on-screen cell + /// (after frozen columns) or null if there is none. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell FirstOnScreenCell + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn column = panel.FirstOnScreenColumn; + + if (column != null) + { + int index = column.ColumnIndex; + + if (index < _Cells.Count) + return (_Cells[index]); + } + } + + return (null); + } + } + + #endregion + + #region FirstSelectableCell + + /// + /// Gets a reference to the first selectable cell + /// or null if there is none defined. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell FirstSelectableCell + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + for (int i = 0; i < panel.Columns.Count; i++) + { + GridColumn column = panel.Columns[i]; + + if (column.Visible == true && column.AllowSelection == true) + { + GridCell cell = + GetCell(i, panel.AllowEmptyCellSelection); + + if (cell != null) + { + if (cell.AllowSelection == true) + return (cell); + } + } + } + } + + return (null); + } + } + + #endregion + + #region FirstVisibleCell + + /// + /// Gets a reference to the first visible cell + /// or null if there is none defined. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell FirstVisibleCell + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn column = panel.Columns.FirstVisibleColumn; + + if (column != null) + { + int index = column.ColumnIndex; + + GridCell cell = + GetCell(index, panel.AllowEmptyCellSelection); + + if (cell != null) + return (cell); + } + } + + return (null); + } + } + + #endregion + + #region Indexer (Column) + + /// + /// Gets or sets Cell item at the given Column + /// + /// Column containing the cell + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell this[GridColumn column] + { + get { return (this[column.ColumnIndex]); } + } + + #endregion + + #region Indexer (int) + + /// + /// Gets or sets Cell item at the given Column + /// + /// Column containing the cell + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell this[int columnIndex] + { + get + { + if (columnIndex < Cells.Count) + return (Cells[columnIndex]); + + return (null); + } + } + + #endregion + + #region Indexer (string) + + /// + /// Gets or sets Cell item at ColumnName index + /// + /// Name of Column containing the cell + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell this[string columnName] + { + get { return (FindCell(columnName)); } + } + + #endregion + + #region InfoImageBounds + + /// + /// Gets the bounds of the InfoImage + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle InfoImageBounds + { + get { return (_InfoImageBounds); } + internal set { _InfoImageBounds = value; } + } + + #endregion + + #region InfoText + + /// + /// Gets or sets the informational text associated with + /// the row. If the InfoText is non-null, then the rows + /// associated InfoImage is displayed in the RowHeader, with + /// the InfoText being displayed as the ToolTip for the InfoImage. + /// + [DefaultValue(null), Category("Appearance")] + [Description("Gets or sets the informational text associated with the row. If the InfoText is non-null, then the rows associated InfoImage is displayed in the RowHeader, with the InfoText being displayed as the ToolTip for the InfoImage.")] + public string InfoText + { + get { return (_InfoText); } + + set + { + if (_InfoText != value) + { + _InfoText = value; + + OnPropertyChangedEx("InfoText", VisualChangeType.Render); + + InvalidateRowHeader(); + } + } + } + + #endregion + + #region IsDeleted + + /// + /// Gets or sets whether the row has been marked as deleted. + /// + [DefaultValue(false), Category("Appearance")] + [Description("Indicates whether the row has been marked as deleted.")] + public override bool IsDeleted + { + get { return (base.IsDeleted); } + + set + { + if (base.IsDeleted != value) + { + SetState(Rs.RowDirty, true); + SetState(Rs.RowNeedsStored, true); + + base.IsDeleted = value; + } + } + } + + #endregion + + #region IsDetailRow + + /// + /// Gets whether the row is marked as a Group Detail row. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsDetailRow + { + get { return (TestState(Rs.DetailRow)); } + internal set { SetState(Rs.DetailRow, value); } + } + + #endregion + + #region IsInsertRow + + /// + /// Gets whether the row is the Insert Row. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsInsertRow + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (IsDesignerHosted == true) + return (false); + + if (panel.ShowInsertRow == true) + { + if (panel.VirtualMode == true) + { + if (GridIndex == panel.VirtualRowCountEx - 1) + return (true); + } + else + { + if (RowIndex == panel.Rows.Count - 1) + return (true); + } + } + } + + return (false); + } + } + + #endregion + + #region IsTempInsertRow + + /// + /// Gets whether the row is a temporary insert Row (created via editing the Insert Row) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsTempInsertRow + { + get { return (TestState(Rs.TempInsertRow)); } + internal set { SetState(Rs.TempInsertRow, value); } + } + + #endregion + + #region LastFrozenCell + + /// + /// Gets a reference to the last Frozen cell + /// or null if there is none. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell LastFrozenCell + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn column = panel.LastFrozenColumn; + + if (column != null) + { + int index = column.ColumnIndex; + + if (index < _Cells.Count) + return (_Cells[index]); + } + } + + return (null); + } + } + + #endregion + + #region LastOnScreenCell + + /// + /// Gets a reference to the last on-screen cell + /// or null if there is none. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell LastOnScreenCell + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn column = panel.LastOnScreenColumn; + + if (column != null) + { + int index = column.ColumnIndex; + + if (index < _Cells.Count) + return (_Cells[index]); + } + } + + return (null); + } + } + + #endregion + + #region LastSelectableCell + + /// + /// Gets a reference to the last selectable cell + /// or null if there is none defined. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell LastSelectableCell + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + for (int i = panel.Columns.Count - 1; i >= 0; i--) + { + GridColumn column = panel.Columns[i]; + + if (column.Visible == true && column.AllowSelection == true) + { + GridCell cell = GetCell(i, panel.AllowEmptyCellSelection); + + if (cell != null) + { + if (cell.AllowSelection == true) + return (cell); + } + } + } + } + + return (null); + } + } + + #endregion + + #region LastVisibleCell + + /// + /// Gets a reference to the last visible cell + /// or null if there is none defined. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell LastVisibleCell + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn column = panel.Columns.LastVisibleColumn; + + if (column != null) + { + int index = column.ColumnIndex; + + if (index < _Cells.Count) + return (_Cells[index]); + } + } + + return (null); + } + } + + #endregion + + #region RowDirty + + /// + /// Gets or sets whether the row state has changed. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool RowDirty + { + get { return (TestState(Rs.RowDirty)); } + + set + { + if (RowDirty != value) + { + SetState(Rs.RowDirty, value); + + InvalidateRowHeader(); + } + } + } + + #endregion + + #region IsRowFilteredOut + + /// + /// Gets whether the row has been filtered out. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsRowFilteredOut + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + panel.UpdateDataFiltering(); + + return (panel.IsFiltered == true && + RowFilteredOut == true); + } + + return (false); + } + + set + { + RowFilteredOut = value; + } + } + + #endregion + + #region RowHeight + + /// + /// Gets or sets the height of the row (0 denotes AutoSize, -1 denotes NotSet). + /// + [DefaultValue(-1), Category("Sizing")] + [Description("Indicates the height of the row (0 denotes AutoSize, -1 denotes NotSet).")] + public int RowHeight + { + get { return (_RowHeight); } + + set + { + if (_RowHeight != value) + { + _RowHeight = (value < 0) ? -1 : value; + + NeedsMeasured = true; + + OnPropertyChangedEx("RowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region PostDetailRowHeight + + /// + /// Gets or sets the height of the "post detail" portion of the + /// row (the area at the bottom of the row). -1 denotes NotSet. + /// + [DefaultValue(-1), Category("Sizing")] + [Description("Indicates the height of the 'post detail' portion of the row (the area at the bottom of the row). -1 denotes NotSet.")] + public int PostDetailRowHeight + { + get { return (_PostDetailRowHeight); } + + set + { + if (_PostDetailRowHeight != value) + { + _PostDetailRowHeight = (value < 0) ? -1 : value; + + NeedsMeasured = true; + + OnPropertyChangedEx("PostDetailRowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region RowPreDetailHeight + + /// + /// Gets or sets the height of the "pre detail" portion of the + /// row (the area at the bottom of the row). -1 denotes NotSet. + /// + [DefaultValue(-1), Category("Sizing")] + [Description("Indicates the height of the 'pre detail' portion of the row (the area at the bottom of the row). -1 denotes NotSet.")] + public int RowPreDetailHeight + { + get { return (_PreDetailRowHeight); } + + set + { + if (_PreDetailRowHeight != value) + { + _PreDetailRowHeight = (value < 0) ? -1 : value; + + NeedsMeasured = true; + + OnPropertyChangedEx("RowPreDetailHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region SelectedCells + + /// + /// Gets an array of the currently Selected Cells. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell[] SelectedCells + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (IsSelected == true) + { + GridCell[] cells = new GridCell[Cells.Count]; + + for (int i = 0; i < Cells.Count; i++) + { + if (Cells[i].AllowSelection == true) + cells[i] = Cells[i]; + } + + return (cells); + } + } + + return (null); + } + } + + #endregion + + #region Visible + + /// + /// Gets or sets whether the row is visible. + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether the row is visible.")] + public override bool Visible + { + get { return (base.Visible); } + + set + { + SetState(Rs.Visible, value); + + if (RowFilteredOut == true) + value = false; + + if (base.Visible != value) + { + base.Visible = value; + + GridPanel panel = GridPanel; + + if (panel != null) + { + int index = GridIndex; + + if (index < panel.Rows.Count) + { + int count = GetVisibleItemCount() + 1; + + panel.ExpandSelectedAtIndex(index, count, value); + } + + if (value == false) + { + if (panel.ActiveRow == this) + { + GridContainer row = GetNextActiveRow(panel, GridIndex); + + panel.SetActiveRow(row, true); + panel.LastProcessedItem = row; + } + } + + panel.UpdateRowCountEx(); + } + } + } + } + + private GridContainer GetNextActiveRow(GridPanel panel, int index) + { + GridContainer row = panel.GetRowFromIndex(index); + + while (row != null) + { + if (panel.CanSetActiveRow(panel, row, false) == true) + return (row); + + row = row.NextVisibleRow; + } + + row = panel.GetRowFromIndex(index - 1); + + while (row != null) + { + if (panel.CanSetActiveRow(false) == true) + return (row); + + row = row.PrevVisibleRow; + } + + return (null); + } + + #endregion + + #region WhiteSpaceBounds + + /// + /// Gets the row WhiteSpace Bounds (the area + /// past the end of the last defined column). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle WhiteSpaceBounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn lastcol = panel.Columns.LastVisibleColumn; + + if (lastcol != null) + { + Rectangle colBounds = lastcol.Bounds; + Rectangle panelBounds = panel.Bounds; + + if (panel.IsSubPanel == true) + panelBounds.Width -= 5; + + if (colBounds.Right < panelBounds.Right) + { + int left = colBounds.Right; + int right = panelBounds.Right; + + if (left < right) + { + Rectangle rowBounds = Bounds; + + rowBounds.X = left; + rowBounds.Width = right - left; + + return (rowBounds); + } + } + } + } + + return (Rectangle.Empty); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region AllocPanel + + internal GridPanel AllocPanel + { + get { return (_AllocPanel); } + set { _AllocPanel = value; } + } + + #endregion + + #region ArrangeLayoutCount + + internal ushort ArrangeLayoutCount + { + get { return (_ArrangeLayoutCount); } + set { _ArrangeLayoutCount = value; } + } + + #endregion + + #region CanModify + + internal override bool CanModify + { + get + { + if (AllowEdit == false) + return (false); + + return (base.CanModify); + } + } + + #endregion + + #region DataItemIndex + + internal int DataItemIndex + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == true) + return (RowIndex); + } + + return (_DataItemIndex); + } + + set { _DataItemIndex = value; } + } + + #endregion + + #region DragSelection + + internal bool DragSelection + { + get { return (_dragSelection); } + set { _dragSelection = value; } + } + + #endregion + + #region ExpandButtonBounds + + internal Rectangle ExpandButtonBounds + { + get { return (_ExpandButtonBounds); } + set { _ExpandButtonBounds = value; } + } + + #endregion + + #region IsReordering + + internal bool IsReordering + { + get { return (TestState(Rs.Reordering)); } + set { SetState(Rs.Reordering, value); } + } + + #endregion + + #region IsResizing + + internal bool IsResizing + { + get { return (TestState(Rs.Resizing)); } + set { SetState(Rs.Resizing, value); } + } + + #endregion + + #region IsControlDown + + internal bool IsControlDown + { + get { return (TestState(Rs.ControlDown)); } + set { SetState(Rs.ControlDown, value); } + } + + #endregion + + #region Loading + + internal bool Loading + { + get { return (TestState(Rs.Loading)); } + set { SetState(Rs.Loading, value); } + } + + #endregion + + #region MeasureCount + + internal ushort MeasureCount + { + get { return (_MeasureCount); } + } + + #endregion + + #region NeedsMeasured + + internal override bool NeedsMeasured + { + get { return (base.NeedsMeasured); } + + set + { + if (value == true) + _MeasureCount++; + + base.NeedsMeasured = value; + } + } + + #endregion + + #region RowCheckChanged + + /// + /// RowCheckChanged + /// + internal bool RowCheckChanged + { + get { return (TestState(Rs.RowCheckChanged)); } + set { SetState(Rs.RowCheckChanged, value); } + } + + #endregion + + #region RowFilteredOut + + internal bool RowFilteredOut + { + get { return (TestState(Rs.RowFilteredOut)); } + + set + { + SetState(Rs.RowFilteredOut, value); + + base.Visible = (value != true) && TestState(Rs.Visible); + + InvalidateMerge(); + } + } + + #endregion + + #region RowNeedsGrouped + + /// + /// RowNeedsGrouped + /// + internal bool RowNeedsGrouped + { + get { return (TestState(Rs.RowNeedsGrouped)); } + set { SetState(Rs.RowNeedsGrouped, value); } + } + + #endregion + + #region RowNeedsSorted + + /// + /// RowNeedsSorted + /// + internal bool RowNeedsSorted + { + get { return (TestState(Rs.RowNeedsSorted)); } + set { SetState(Rs.RowNeedsSorted, value); } + } + + #endregion + + #region RowNeedsStored + + /// + /// RowNeedsStored + /// + internal bool RowNeedsStored + { + get { return (TestState(Rs.RowNeedsStored)); } + set { SetState(Rs.RowNeedsStored, value); } + } + + #endregion + + #region IsSeparatorAtBottom + + internal bool IsSeparatorAtBottom + { + get { return (TestState(Rs.SeparatorAtBottom)); } + set { SetState(Rs.SeparatorAtBottom, value); } + } + + #endregion + + #endregion + + #region TestState + + private bool TestState(Rs state) + { + return ((_States & state) == state); + } + + #endregion + + #region SetState + + private void SetState(Rs state, bool value) + { + if (value == true) + _States |= state; + else + _States &= ~state; + } + + #endregion + + #region MeasureOverride + + #region MeasureOverride + + /// + /// Performs the layout of the item + /// and sets the Size property to size that item will take. + /// + /// Layout information. + /// + /// + protected override void MeasureOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + GridPanel panel = stateInfo.GridPanel; + + Size sizeNeeded = Size.Empty; + + if (panel.ShowRowHeaders == true) + sizeNeeded = MeasureRowHeader(panel); + + Size size = Size.Empty; + + if (panel.VirtualMode == true) + { + size.Width = GetColumnsWidth(stateInfo); + size.Height = Dpi.Height(panel.VirtualRowHeight); + } + else + { + int rowHeight = GetRowHeight(); + + if (rowHeight == 0) + { + size = MeasureCells(layoutInfo, stateInfo); + } + else + { + size.Width = GetColumnsWidth(stateInfo); + size.Height = rowHeight; + } + } + + sizeNeeded.Width += size.Width; + sizeNeeded.Height = Math.Max(size.Height, sizeNeeded.Height); + sizeNeeded.Height = Math.Max(sizeNeeded.Height, Dpi.Height(panel.MinRowHeight)); + sizeNeeded.Height = Math.Min(sizeNeeded.Height, Dpi.Height(panel.MaxRowHeight)); + + _EffectivePreDetailRowHeight = GetRowPreDetailHeight(); + _EffectivePostDetailRowHeight = GetRowPostDetailHeight(); + + SuperGrid.DoRowGetDetailHeightEvent(this, layoutInfo, + sizeNeeded, ref _EffectivePreDetailRowHeight, ref _EffectivePostDetailRowHeight); + + _EffectivePreDetailRowHeight = Dpi.Height(_EffectivePreDetailRowHeight); + _EffectivePostDetailRowHeight = Dpi.Height(_EffectivePostDetailRowHeight); + + sizeNeeded.Height += (_EffectivePreDetailRowHeight + _EffectivePostDetailRowHeight); + + FixedRowHeight = sizeNeeded.Height; + + HasVisibleItems = false; + + if (Rows != null && Rows.Count > 0) + { + if (Expanded == true) + { + GridLayoutStateInfo itemStateInfo = new + GridLayoutStateInfo(panel, stateInfo.IndentLevel + 1); + + size = MeasureSubItems(layoutInfo, itemStateInfo, constraintSize); + + sizeNeeded.Width = Math.Max(size.Width, sizeNeeded.Width); + sizeNeeded.Height += size.Height; + } + else + { + HasVisibleItems = AnyVisibleItems(); + } + } + + Size = sizeNeeded; + } + + #region GetColumnsWidth + + private int GetColumnsWidth(GridLayoutStateInfo stateInfo) + { + int width = 0; + + GridColumnCollection columns = stateInfo.GridPanel.Columns; + foreach (GridColumn column in columns) + { + if (column.Visible == true) + width += column.Size.Width; + } + + return (width); + } + + #endregion + + #region MeasureRowHeader + + private Size MeasureRowHeader(GridPanel panel) + { + Size size = Dpi.Size(panel.RowHeaderSize); + + if (size.IsEmpty == true) + { + if (NeedsMeasured == true) + { + size.Width = panel.RowHeaderWidthEx; + + if (GetRowHeight() == 0) + { + RowHeaderVisualStyle style = GetEffectiveRowStyle().RowHeaderStyle; + + if (panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Image || + panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Both) + { + MaxImageHeight(style.GetActiveRowImage(panel), ref size); + } + + if (panel.ShowEditingImage == true) + MaxImageHeight(style.GetEditingRowImage(panel), ref size); + + if (panel.ShowInsertRow == true) + MaxImageHeight(panel.GetInsertRowImage(), ref size); + } + + _RowHeaderSize = size; + } + + size = _RowHeaderSize; + } + + return (size); + } + + private void MaxImageHeight(Image image, ref Size size) + { + if (image != null) + size.Height = Math.Max(size.Height, image.Height + 6); + } + + #endregion + + #region AnyVisibleItems + + internal bool AnyVisibleItems() + { + GridItemsCollection items = Rows; + foreach (GridElement item in items) + { + if (item.Visible == true) + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region MeasureCells + + private Size MeasureCells(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo) + { + GridPanel panel = stateInfo.GridPanel; + Size sizeNeeded = Size.Empty; + + int rowHeight = GetRowHeight(); + + GridCellCollection cells = _Cells; + foreach (GridCell cell in cells) + { + if (cell.ColumnIndex < panel.Columns.Count) + { + GridColumn column = panel.Columns[cell.ColumnIndex]; + + if (column.Visible == true) + { + ColumnAutoSizeMode mode = column.GetAutoSizeMode(); + Size size = column.BoundsRelative.Size; + + if (column.IsPrimaryColumn == true) + { + size.Width -= stateInfo.IndentLevel * Dpi.Width(panel.LevelIndentSize.Width); + + if (panel.ShowTreeButtons == true || panel.ShowTreeLines == true) + size.Width -= panel.TreeButtonIndent; + + if (panel.CheckBoxes == true) + size.Width -= Dpi.Width(panel.CheckBoxSize.Width + 6); + } + + if ((rowHeight == 0 && mode == ColumnAutoSizeMode.Fill) || + cell.NeedsMeasured == true || column.NeedsMeasured == true || + NeedsMeasured == true || panel.NeedsMeasured == true) + { + cell.Measure(layoutInfo, stateInfo, size); + } + + size.Height = cell.MeasuredSize.Height; + + if (mode != ColumnAutoSizeMode.None) // Was Fill + size.Width = cell.MeasuredSize.Width; + + if (rowHeight != 0) + size.Height = rowHeight; + + cell.Size = size; + + sizeNeeded.Width += cell.Size.Width; + sizeNeeded.Height = Math.Max(cell.Size.Height, sizeNeeded.Height); + } + } + } + + if (sizeNeeded.IsEmpty == true) + sizeNeeded = new Size(Dpi.Width100, rowHeight); + + return (sizeNeeded); + } + + #endregion + + #endregion + + #region ArrangeOverride + + #region ArrangeOverride + + /// + /// Performs the arrange pass layout of the + /// item when final position and size of the item has been set. + /// + /// Layout information. + /// + /// Layout bounds + protected override void ArrangeOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + ContainerBounds = layoutBounds; + + Rectangle bounds = layoutBounds; + bounds.Height = FixedRowHeight; + + GridPanel panel = stateInfo.GridPanel; + IndentLevel = stateInfo.IndentLevel; + + if (panel.ShowRowHeaders == true) + bounds.X += panel.RowHeaderWidthEx; + + ArrangeCells(layoutInfo, stateInfo, bounds); + + if (Rows != null && Expanded == true) + { + bounds = layoutBounds; + + int n = FixedRowHeight; + + bounds.Y += n; + bounds.Height -= n; + + GridLayoutStateInfo itemStateInfo = + new GridLayoutStateInfo(panel, IndentLevel + 1); + + ArrangeSubItems(layoutInfo, itemStateInfo, bounds); + } + + ArrangeLayoutCount = SuperGrid.ArrangeLayoutCount; + } + + #endregion + + #region ArrangeCells + + private void ArrangeCells(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle bounds) + { + GridPanel panel = stateInfo.GridPanel; + + if (panel.Columns.Count > 0) + { + int indentLevel = stateInfo.IndentLevel; + + GridCellCollection cells = _Cells; + GridColumnCollection columns = panel.Columns; + + int j = 0; + + int[] map = columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + if (index < cells.Count) + { + GridCell cell = cells[index]; + + if (panel.GroupColumns.Count > 0) + { + cell.IndentLevel = (j == 0 ? indentLevel : 0); + } + else + { + cell.IndentLevel = + (panel.PrimaryColumnIndex == index) ? indentLevel : 0; + } + + bounds.Width = column.Size.Width; + + cell.Arrange(layoutInfo, stateInfo, bounds); + } + + j++; + + bounds.X += column.Size.Width; + } + } + } + } + + #endregion + + #endregion + + #region RenderOverride + + /// + /// Performs drawing of the item and its children + /// + /// Holds contextual rendering information. + protected override void RenderOverride(GridRenderInfo renderInfo) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle bounds = Bounds; + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + if (bounds.IntersectsWith(renderInfo.ClipRectangle)) + RenderRow(renderInfo, panel, pstyle, bounds); + + if (Rows != null && Rows.Count > 0 && Expanded == true) + { + UpdateMergeFlags(); + + RenderSubItems(renderInfo, panel, pstyle, panel.IsSubPanel, IsVFrozen); + } + + RenderDesignerElement(renderInfo, bounds); + } + } + + #region RenderRow + + private void RenderRow(GridRenderInfo renderInfo, + GridPanel panel, GridPanelVisualStyle pstyle, Rectangle r) + { + Graphics g = renderInfo.Graphics; + + bool cancelled = SuperGrid.DoPreRenderRowEvent(g, this, RenderParts.Background, r); + + if (HScrollOffset == 0 || panel.Parent != null || panel.FrozenColumnCount <= 0) + RenderAllColumns(renderInfo, panel); + else + RenderScrollableColumns(renderInfo, panel); + + if (cancelled == false) + SuperGrid.DoPostRenderRowEvent(g, this, RenderParts.Background, r); + + if (panel.ShowRowHeaders == true) + RenderRowHeader(renderInfo, panel, this, pstyle, r); + + Rectangle w = WhiteSpaceBounds; + + if (w.Width > 0 && w.Height > 0) + RenderRowWhitespace(renderInfo, panel, pstyle, w); + + if (panel.FocusCuesEnabled == true && SuperGrid.ActiveElement == this) + { + if (panel.EnableCellMerging == false) + RenderFocusRect(g, r); + } + } + + #region RenderAllColumns + + private void RenderAllColumns( + GridRenderInfo renderInfo, GridPanel panel) + { + GridCellCollection cells = _Cells; + GridColumnCollection columns = panel.Columns; + + bool isVFrozen = IsVFrozen; + + int[] map = columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = columns[index]; + + if (column.Visible == true) + { + if (column.Bounds.IntersectsWith(renderInfo.ClipRectangle)) + { + if (index < cells.Count) + { + if (RenderCell(renderInfo, cells[index], false, isVFrozen) == false) + break; + } + else + { + RenderEmptyCell(renderInfo, column, false, isVFrozen); + } + } + } + } + } + + #endregion + + #region RenderScrollableColumns + + private void RenderScrollableColumns( + GridRenderInfo renderInfo, GridPanel panel) + { + Graphics g = renderInfo.Graphics; + GridCellCollection cells = _Cells; + GridColumnCollection columns = panel.Columns; + + Region saveClip = null; + + bool isVFrozen = IsVFrozen; + int[] map = columns.DisplayIndexMap; + + GridColumn lastCol = null; + + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + GridColumn column = columns[index]; + + if (column.Visible == true) + { + bool isHFrozen = column.IsHFrozen; + + if (saveClip == null && isHFrozen == false) + saveClip = SetScrollableClip(g, lastCol); + + if (index < cells.Count) + { + if (RenderCell(renderInfo, cells[index], isHFrozen, isVFrozen) == false) + break; + } + else + { + if (RenderEmptyCell(renderInfo, column, isHFrozen, isVFrozen) == false) + break; + } + + lastCol = column; + } + } + + if (saveClip != null) + g.Clip = saveClip; + } + + #region SetScrollableClip + + private Region SetScrollableClip(Graphics g, GridColumn column) + { + Region clip = g.Clip; + + if (column != null) + { + Rectangle r = SuperGrid.ViewRectEx; + r.X = column.Bounds.Right; + g.SetClip(r); + } + + return (clip); + } + + #endregion + + #endregion + + #region RenderCell + + private bool RenderCell(GridRenderInfo renderInfo, + GridCell cell, bool isHFrozen, bool isVFrozen) + { + Rectangle bounds = cell.BoundsRelative; + + if (isHFrozen == false) + bounds.X -= HScrollOffset; + + if (isVFrozen == false) + bounds.Y -= VScrollOffset; + + if (bounds.X > renderInfo.ClipRectangle.Right) + return (false); + + cell.Render(renderInfo); + + return (true); + } + + #endregion + + #region RenderEmptyCell + + private bool RenderEmptyCell(GridRenderInfo renderInfo, + GridColumn column, bool isHFrozen, bool isVFrozen) + { + Rectangle r = column.BoundsRelative; + r.Y = BoundsRelative.Y; + r.Height = FixedRowHeight; + + Rectangle bounds = r; + + if (isHFrozen == false) + bounds.X -= HScrollOffset; + + if (isVFrozen == false) + { + bounds.Y -= VScrollOffset; + bounds.Intersect(SViewRect); + } + + if (bounds.X > renderInfo.ClipRectangle.Right) + return (false); + + GridCell cell = GetEmptyRenderCell(column); + + cell.IsMouseOver = + bounds.Contains(SuperGrid.PointToClient(Control.MousePosition)); + + cell.Render(renderInfo); + + return (true); + } + + #region GetEmptyRenderCell + + private GridCell GetEmptyRenderCell(GridColumn column) + { + if (_EmptyRenderCell == null) + _EmptyRenderCell = new GridCell(); + + int oldIndex = _EmptyRenderCell.ColumnIndex; + + _EmptyRenderCell = GetEmptyCell(_EmptyRenderCell, column.ColumnIndex); + + if (_EmptyRenderCell.ColumnIndex != oldIndex) + _EmptyRenderCell.ClearEffectiveStyles(); + + return (_EmptyRenderCell); + } + + #endregion + + #endregion + + #region RenderFocusRect + + private void RenderFocusRect(Graphics g, Rectangle r) + { + if (SuperGrid.Focused == true && IsDesignerHosted == false) + { + GridCell cell = FirstVisibleCell; + + if (cell != null) + { + Rectangle v = cell.HighLightBounds; + + r.X = v.X; + + if (r.X < 0) + { + r.X = -(r.X % 2); + r.Width -= (r.X - v.X); + } + } + + r.Height = FixedRowHeight; + + switch (GridPanel.GridLines) + { + case GridLines.Both: + r.Width -= Dpi.Width1; + r.Height -= Dpi.Height1; + break; + + case GridLines.Vertical: + r.Width -= Dpi.Width1; + break; + + case GridLines.Horizontal: + r.Height -= Dpi.Height1; + break; + } + + Region clip = null; + + if (IsVFrozen == false) + { + Rectangle t = SViewRect; + + GridPanel panel = GridPanel; + GridColumn col = panel.Columns.LastVisibleColumn; + + if (col != null) + { + switch (panel.RowFocusMode) + { + case RowFocusMode.FullRow: + Rectangle w = panel.Bounds; + + if (r.Right > w.Right) + { + r.Width -= (r.Right - w.Right + 1); + + if (panel.IsSubPanel == true && panel.ShowDropShadow == true) + r.Width -= Dpi.Width5; + } + + if (r.Right < col.Bounds.Right) + r.Width += (col.Bounds.Right - r.Right - 1); + break; + + default: + if (r.Right > col.Bounds.Right) + r.Width -= (r.Right - col.Bounds.Right + 1); + break; + } + } + + clip = g.Clip; + g.SetClip(t); + } + + ControlPaint.DrawFocusRectangle(g, r); + + if (clip != null) + g.Clip = clip; + } + } + + #endregion + + #endregion + + #region RenderRowHeader + + /// + /// RenderRowHeader + /// + /// + /// + /// + /// + /// + protected void RenderRowHeader(GridRenderInfo renderInfo, + GridPanel panel, GridContainer item, GridPanelVisualStyle pstyle, Rectangle r) + { + Graphics g = renderInfo.Graphics; + + r.Width = panel.RowHeaderWidthEx; + + if (r.IntersectsWith(renderInfo.ClipRectangle)) + { + if (r.Height > 100) + r = GetCenterBounds(r); + + RenderRowHeader(g, panel, item, pstyle, r, true); + } + } + + #region RenderRowHeader + + private void RenderRowHeader(Graphics g, GridPanel panel, + GridContainer item, GridPanelVisualStyle pstyle, Rectangle r, bool highlight) + { + r.Width--; + r.Height--; + + if (r.Width > 0 && r.Height > 0) + { + StyleState rowState = GetRowHeaderState(item, r); + RowVisualStyle style = GetEffectiveRowStyle(item, rowState); + + if (SuperGrid.DoPreRenderRowEvent(g, this, RenderParts.RowHeader, r) == false) + { + if (item.IsActiveRow == true && + (panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Highlight || + panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Both)) + { + using (Brush br = style.RowHeaderStyle.ActiveRowBackground.GetBrush(r)) + g.FillRectangle(br, r); + } + else + { + using (Brush br = style.RowHeaderStyle.Background.GetBrush(r)) + g.FillRectangle(br, r); + } + + if (highlight == true) + { + using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Height1)) + g.DrawLine(pen, r.X, r.Top, r.Right, r.Top); + + using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Width1)) + g.DrawLine(pen, r.X + 1, r.Top, r.X + 1, r.Bottom); + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X, r.Top - 1, r.Right, r.Top - 1); + g.DrawLine(pen, r.X, r.Bottom, r.Right, r.Bottom); + } + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) + g.DrawLine(pen, r.Right, r.Top, r.Right, r.Bottom); + } + + if (item is GridRow) + { + if (RowDirty == true && panel.ShowRowDirtyMarker == true) + { + Rectangle t = r; + + t.X++; + t.Width = Dpi.Width3; + + using (Brush br = style.RowHeaderStyle.DirtyMarkerBackground.GetBrush(t)) + g.FillRectangle(br, t); + } + } + + r.Width = panel.RowHeaderWidthEx; + + RenderHeaderInfo(g, panel, item, style, r); + + SuperGrid.DoPostRenderRowEvent(g, this, RenderParts.RowHeader, r); + } + } + } + + #region GetRowHeaderState + + private StyleState GetRowHeaderState( + GridContainer item, Rectangle r) + { + StyleState rowState = StyleState.Default; + + if (IsMouseOver == true) + { + r.Height++; + + if (IsResizing == true || + r.Contains(SuperGrid.PointToClient(Control.MousePosition)) == true) + { + rowState |= StyleState.MouseOver; + } + } + + if (item.IsSelected == true) + rowState |= StyleState.Selected; + + return (rowState); + } + + #endregion + + #endregion + + #region RenderHeaderInfo + + private void RenderHeaderInfo(Graphics g, + GridPanel panel, GridContainer item, RowVisualStyle style, Rectangle r) + { + r.X += Dpi.Width4; + r.Width -= Dpi.Width4; + + GridRow row = item as GridRow; + + int m = RenderInfoImage(g, panel, item, r); + + if (row != null && row.IsInsertRow == true) + { + RenderInsertIndicator(g, panel, r); + RenderIndicatorImage(g, panel, item, r); + } + else + { + if (panel.ShowEditingImage == true && + (row != null && row.EditorDirty == true)) + { + RenderEditingImage(g, panel, r); + } + else + { + int n = RenderIndicatorImage(g, panel, item, r); + + r.X += n; + r.Width -= n; + + string text = item.RowHeaderText; + + if (string.IsNullOrEmpty(text) == true) + { + text = (panel.ShowRowGridIndex == true) + ? (item.GridIndex + panel.RowHeaderIndexOffset).ToString() : ""; + } + + SuperGrid.DoGetRowHeaderTextEvent(item, ref text); + + if (string.IsNullOrEmpty(text) == false) + RenderGridIndex(g, text, style, r, m); + } + } + } + + #region RenderInfoImage + + private int RenderInfoImage( + Graphics g, GridPanel panel, GridContainer item, Rectangle r) + { + GridRow row = item as GridRow; + + if (row != null) + { + row.InfoImageBounds = Rectangle.Empty; + + if (ShowInfoRowImage(panel, row) == true) + { + StyleState rowState = GetRowHeaderState(this, r); + RowHeaderVisualStyle style = GetEffectiveRowStyle(this, rowState).RowHeaderStyle; + + Image image = style.GetInfoRowImage(panel); + + if (image != null) + { + Rectangle u = r; + + Size size = image.Size; + + u.Size = size; + + u.X = r.Right - u.Width - 4; + u.X = Math.Max(r.X, u.X); + + if (r.Height > u.Height) + u.Y += (r.Height - u.Height)/2; + + u.Intersect(r); + + row.InfoImageBounds = u; + + g.DrawImageUnscaledAndClipped(image, u); + + return (size.Width); + } + } + } + + return (0); + } + + #region ShowInfoRowImage + + private bool ShowInfoRowImage(GridPanel panel, GridRow row) + { + if (panel.ShowRowInfo == false || row.InfoText == null) + return (false); + + if (row.InfoText.Equals("") == false) + return (true); + + return (panel.ShowRowInfoDisplayMode == ShowRowInfoDisplayMode.ShowWithEmptyText); + } + + #endregion + + #endregion + + #region RenderEditingImage + + private void RenderEditingImage( + Graphics g, GridPanel panel, Rectangle r) + { + StyleState rowState = GetRowHeaderState(this, r); + RowHeaderVisualStyle style = GetEffectiveRowStyle(this, rowState).RowHeaderStyle; + + Image image = style.GetEditingRowImage(panel); + + if (image != null) + { + Rectangle u = r; + u.Size = image.Size; + + if (r.Width > u.Width) + u.X += (r.Width - u.Width) / 2; + + if (r.Height > u.Height) + u.Y += (r.Height - u.Height) / 2; + + u.Intersect(r); + + g.DrawImageUnscaledAndClipped(image, u); + } + } + + #endregion + + #region RenderInsertIndicator + + private void RenderInsertIndicator( + Graphics g, GridPanel panel, Rectangle r) + { + if (panel.ShowInsertRowImage == true) + { + Image image = panel.GetInsertRowImage(); + + if (image != null) + { + Rectangle u = r; + u.Size = image.Size; + + if (r.Width > u.Width) + u.X = r.X + (r.Width - u.Width) / 2; + + if (r.Height > u.Height) + u.Y += (r.Height - u.Height) / 2; + + u.Intersect(r); + + g.DrawImageUnscaledAndClipped(image, u); + } + } + } + + #endregion + + #region RenderIndicatorImage + + private int RenderIndicatorImage(Graphics g, + GridPanel panel, GridContainer row, Rectangle r) + { + StyleState rowState = GetRowHeaderState(this, r); + RowHeaderVisualStyle style = GetEffectiveRowStyle(this, rowState).RowHeaderStyle; + + Image image = null; + + GridRow grow = row as GridRow; + + if (grow != null) + { + if (grow.IsTempInsertRow == true && grow.IsInsertRow == false) + image = panel.GetInsertTempRowImage(); + else + image = style.GetActiveRowImage(panel); + } + + if (image != null) + { + Size size = image.Size; + + int n = size.Width; + + if (row.IsActiveRow == true) + { + if (panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Image || + panel.ActiveRowIndicatorStyle == ActiveRowIndicatorStyle.Both) + { + Rectangle u = r; + u.Size = size; + + if (r.Height > u.Height) + u.Y += (r.Height - u.Height) / 2; + + u.Intersect(r); + + g.DrawImageUnscaledAndClipped(image, u); + } + } + + return (n); + } + + return (0); + } + + #endregion + + #region RenderGridIndex + + private void RenderGridIndex(Graphics g, + string text, RowVisualStyle style, Rectangle r, int m) + { + Font font = style.RowHeaderStyle.Font ?? SystemFonts.DefaultFont; + + r.Inflate(-Dpi.Width2, 0); + r.Width -= m; + + eTextFormat tf = style.RowHeaderStyle.GetTextFormatFlags(); + + TextDrawing.DrawString(g, text, + font, style.RowHeaderStyle.TextColor, r, tf); + } + + #endregion + + #endregion + + #endregion + + #region RenderRowWhitespace + + private void RenderRowWhitespace(GridRenderInfo renderInfo, + GridPanel panel, GridPanelVisualStyle pstyle, Rectangle r) + { + Graphics g = renderInfo.Graphics; + + if (SuperGrid.DoPreRenderRowEvent(g, this, RenderParts.Whitespace, r) == false) + { + StyleState state = GetWhiteSpaceState(panel); + RowVisualStyle style = GetEffectiveRowStyle(this, state); + + using (Brush br = style.Background.GetBrush(r)) + g.FillRectangle(br, r); + + if (panel.ShowWhitespaceRowLines == true) + { + switch (panel.GridLines) + { + case GridLines.Both: + case GridLines.Horizontal: + if (pstyle.HorizontalLinePattern != LinePattern.None && + pstyle.HorizontalLinePattern != LinePattern.NotSet) + { + using (Pen pen = new Pen(pstyle.HorizontalLineColor, Dpi.Height1)) + { + pen.DashStyle = (DashStyle)pstyle.HorizontalLinePattern; + + g.DrawLine(pen, r.Left, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + g.DrawLine(pen, r.Left, r.Top - 1, r.Right - 1, r.Top - 1); + } + } + break; + } + } + + SuperGrid.DoPostRenderRowEvent(g, this, RenderParts.Whitespace, r); + } + } + + #region GetWhiteSpaceState + + private StyleState GetWhiteSpaceState(GridPanel panel) + { + StyleState rowState = StyleState.Default; + + if (IsMouseOver == true && _HitArea == RowArea.InWhiteSpace) + rowState |= StyleState.MouseOver; + + if (IsSelected == true && panel.RowHighlightType != RowHighlightType.None) + rowState |= StyleState.Selected; + + if (panel.SelectionGranularity != SelectionGranularity.Cell && + panel.RowHighlightType == RowHighlightType.Full) + { + if (Bounds.Contains(SuperGrid.PointToClient(Control.MousePosition))) + rowState |= StyleState.MouseOver; + } + + if (SuperGrid.ScrollBarScrolling == true) + rowState &= ~StyleState.MouseOver; + + return (rowState); + } + + #endregion + + #endregion + + #region RenderSubItems + + /// + /// RenderSubItems + /// + /// + /// + /// + /// + /// + protected void RenderSubItems(GridRenderInfo renderInfo, + GridPanel panel, GridPanelVisualStyle pstyle, bool isSubPanel, bool isFrozen) + { + Rectangle t = SViewRect; + + GridItemsCollection items = Rows; + for (int i = FirstOnScreenRowIndex; i < items.Count; i++) + { + GridElement item = items[i]; + + if (item.Visible == true) + { + GridPanel ipanel = item as GridPanel; + + if (ipanel != null) + { + Graphics g = renderInfo.Graphics; + Rectangle r = ipanel.ContainerBounds; + + if (isFrozen == false) + r.Y -= VScrollOffset; + + if (isSubPanel == true) + r.X -= HScrollOffset; + + if (r.Y > t.Bottom) + break; + + if (r.IntersectsWith(renderInfo.ClipRectangle)) + { + Rectangle r2 = r; + + if (panel.ShowRowHeaders == true) + { + r2.X += panel.RowHeaderWidthEx; + r2.Width -= panel.RowHeaderWidthEx; + } + + if (SuperGrid.DoPreRenderPanelRowEvent(g, + ipanel, RenderParts.Background | RenderParts.Border, r2) == false) + { + RenderRowBackground(g, ipanel, r2); + RenderRowBorder(g, panel, r2); + + SuperGrid.DoPostRenderPanelRowEvent(g, + ipanel, RenderParts.Background | RenderParts.Border, r2); + } + + RenderTreeLines(g, panel, ipanel, r, isSubPanel); + RenderRowCheckBox(g, panel, ipanel); + + item.Render(renderInfo); + + if (panel.ShowRowHeaders == true) + { + r2 = r; + r2.Width = panel.RowHeaderWidthEx; + + if (SuperGrid.DoPreRenderPanelRowEvent(g, + ipanel, RenderParts.RowHeader, r2) == false) + { + RenderRowHeader(renderInfo, panel, ipanel, pstyle, r2); + + SuperGrid.DoPostRenderPanelRowEvent(g, + ipanel, RenderParts.RowHeader, r2); + } + } + } + } + else + { + Rectangle r = item.BoundsRelative; + + if (isFrozen == false) + r.Y -= VScrollOffset; + + if (isSubPanel == true) + r.X -= HScrollOffset; + + if (r.Y > t.Bottom) + break; + + if (r.IntersectsWith(renderInfo.ClipRectangle)) + item.Render(renderInfo); + } + } + } + } + + #endregion + + #region RenderTreeLines + + private void RenderTreeLines(Graphics g, + GridPanel panel, GridPanel ipanel, Rectangle r, bool isSubPanel) + { + if (panel.ShowTreeButtons == true && panel.ShowTreeLines == true) + { + if (panel.PrimaryColumn != null && + panel.PrimaryColumn.Visible == true) + { + int n = panel.PrimaryColumn.BoundsRelative.X - + panel.BoundsRelative.X; + + r.X += n; + r.Width -= n; + + r = GetCenterBounds(r); + + if (panel.PrimaryColumn.IsHFrozen == false) + { + if (isSubPanel == false) + r.X -= HScrollOffset; + } + + TreeDisplay.RenderLines(g, panel, r, ipanel, ipanel.IndentLevel, + Dpi.Width(panel.LevelIndentSize.Width), panel.TreeButtonIndent, false); + } + } + } + + #endregion + + #region RenderRowBackground + + /// + /// RenderRowBackground + /// + /// + /// + /// + protected void RenderRowBackground( + Graphics g, GridContainer item, Rectangle r) + { + if (item is GridPanel) + { + RowVisualStyle style = GetEffectiveRowStyle(item); + + if (style.Background != null && style.Background.IsEmpty == false) + { + Rectangle t = item.ContainerBounds; + + t.X -= HScrollOffset; + + if (IsVFrozen == false) + { + t.Y -= VScrollOffset; + + r.Intersect(SViewRect); + t.Intersect(SViewRect); + t.Y = r.Y; + } + + using (Brush br = style.Background.GetBrush(t)) + g.FillRectangle(br, r); + } + } + } + + #endregion + + #region RenderRowCheckBox + + /// + /// RenderRowCheckBox + /// + /// + /// + /// + protected void RenderRowCheckBox(Graphics g, + GridPanel panel, GridPanel ipanel) + { + if (ipanel.HasCheckBox == true) + { + Rectangle r = GetRowCheckBoxBounds(panel, ipanel); + + if (ipanel.Checked == true) + { + CheckDisplay.RenderCheckbox(g, r, + CheckBoxState.CheckedNormal, ButtonState.Checked); + } + else + { + CheckDisplay.RenderCheckbox(g, r, + CheckBoxState.UncheckedNormal, ButtonState.Normal); + } + } + } + + #endregion + + #region GetRowCheckBoxBounds + + private Rectangle GetRowCheckBoxBounds(GridPanel panel, GridPanel ipanel) + { + Rectangle r = ipanel.CheckBoxBounds; + + if (ipanel.HasCheckBox == true) + { + Rectangle bounds = ipanel.ContainerBounds; + bounds.Location = PointToScroll(ipanel, bounds.Location); + + Rectangle t = GetCenterBounds(bounds); + + r.Y = t.Y + (t.Height - Dpi.Height(panel.CheckBoxSize.Height)) / 2; + r.X -= HScrollOffset; + + if (r.Bottom > bounds.Bottom) + r.Y -= (r.Bottom - bounds.Bottom); + + if (r.Y < bounds.Y) + r.Y = bounds.Y; + + t = r; + t.X += HScrollOffset; + + if (ipanel.IsVFrozen == false) + t.Y += VScrollOffset; + + ipanel.CheckBoxBounds = t; + } + else + { + r = Rectangle.Empty; + ipanel.CheckBoxBounds = r; + } + + return (r); + } + + #endregion + + #region RenderRowBorder + + /// + /// RenderRowBorder + /// + /// + /// + /// + protected void RenderRowBorder( + Graphics g, GridPanel panel, Rectangle r) + { + if (panel.GridLines == GridLines.Horizontal || panel.GridLines == GridLines.Both) + { + if (panel.ShowWhitespaceRowLines == true) + { + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + using (Pen pen = new Pen(pstyle.HorizontalLineColor, Dpi.Height1)) + { + pen.DashStyle = (DashStyle)pstyle.HorizontalLinePattern; + pen.DashOffset = r.X % 2; + + g.DrawLine(pen, r.X, r.Top - 1, r.Right - 1, r.Top - 1); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + } + } + } + } + + #endregion + + #region RenderDesignerElement + + private void RenderDesignerElement( + GridRenderInfo renderInfo, Rectangle r) + { + if (SuperGrid.DesignerElement == this) + { + r.X -= Dpi.Width2; + r.Y += Dpi.Height1; + + r.Height -= Dpi.Height4; + r.Width += Dpi.Width5; + + if (r.Width > 0 && r.Height > 0) + { + using (Pen pen = new Pen(Color.Purple, Dpi.Width1)) + { + pen.DashStyle = DashStyle.Dash; + + renderInfo.Graphics.DrawRectangle(pen, r); + } + } + } + } + + #endregion + + #endregion + + #region GetCenterBounds + + private Rectangle GetCenterBounds(Rectangle bounds) + { + Rectangle r = SuperGrid.ClientRectangle; + + int m = r.Y; + + if (IsVFrozen == false) + m += SuperGrid.PrimaryGrid.FixedRowHeight; + + if (bounds.Y < m) + { + int n = m - bounds.Y; + + bounds.Y = m; + bounds.Height -= n; + } + + m = r.Bottom; + + if (SuperGrid.IsHScrollBarVisible == true) + m -= SuperGrid.HScrollBarHeight; + + if (SuperGrid.PrimaryGrid.Footer != null && + SuperGrid.PrimaryGrid.Footer.Visible == true) + { + m -= SuperGrid.PrimaryGrid.Footer.Size.Height; + } + + if (bounds.Bottom > m) + bounds.Height -= (bounds.Bottom - m) - 1; + + return (bounds); + } + + #endregion + + #region FindCell + + private GridCell FindCell(string columnName) + { + if (string.IsNullOrEmpty(columnName) == true) + throw new Exception("Invalid Column Name."); + + foreach (GridCell cell in Cells) + { + GridColumn col = cell.GridColumn; + + if (col == null) + break; + + if (columnName.Equals(col.Name) == true) + return (cell); + } + + return (null); + } + + #endregion + + #region GetCell + + /// + /// Gets the Row Cell for the given column index. If + /// the cell does not exist,then null will be returned. + /// + /// + /// + public GridCell GetCell(int columnIndex) + { + return (GetCell(columnIndex, false)); + } + + /// + /// Gets the Row Cell for the given column name. If + /// the cell does not exist, null will be returned. + /// + /// + /// + public GridCell GetCell(string name) + { + return (FindCell(name)); + } + + /// + /// Gets the Row Cell for the given column index. If + /// "includeEmpty" is true, and the cell does not exist + /// (i.e. is empty) then a dummy empty cell will be created + /// and returned. + /// + /// + /// + /// + public GridCell GetCell(int columnIndex, bool includeEmpty) + { + if (columnIndex < _Cells.Count) + return (_Cells[columnIndex]); + + if (includeEmpty == true) + return (GetEmptyCell(null, columnIndex)); + + return (null); + } + + #endregion + + #region GetEmptyCell + + internal GridCell GetEmptyCell(GridCell cell, int columnIndex) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (columnIndex < panel.Columns.Count) + { + GridColumn column = panel.Columns[columnIndex]; + + if (cell == null) + cell = new GridCell(); + + Rectangle r = column.BoundsRelative; + r.Y = BoundsRelative.Y; + r.Height = FixedRowHeight; + + cell.BoundsRelative = r; + + cell.Parent = this; + cell.IsEmptyCell = true; + cell.ColumnIndex = columnIndex; + cell.SelectionUpdateCount = (ushort)(GridPanel.SelectionUpdateCount - 1); + cell.Selected = ExpandedVisible(panel) == true ? panel.IsItemSelectedEx(cell) : false; + + return (cell); + } + } + + return (cell); + } + + #endregion + + #region Mouse Handling + + #region InternalMouseEnter + + /// + /// InternalMouseEnter + /// + /// + internal override void InternalMouseEnter(EventArgs e) + { + IsMouseOver = true; + + if (GridPanel.RowHighlightType == RowHighlightType.Full) + InvalidateRender(); + + SuperGrid.DoRowMouseEnterEvent(this); + + base.InternalMouseEnter(e); + } + + #region InvalidateWhitespace + + private void InvalidateWhitespace() + { + Rectangle r = WhiteSpaceBounds; + + if (r.IsEmpty == false) + InvalidateRender(r); + } + + #endregion + + #endregion + + #region InternalMouseLeave + + /// + /// InternalMouseLeave + /// + /// + internal override void InternalMouseLeave(EventArgs e) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + IsMouseOver = false; + + if (GridPanel.RowHighlightType == RowHighlightType.Full) + InvalidateRender(Bounds); + + if (panel.ShowRowHeaders == true) + { + panel.HotItem = null; + + _HitArea = RowArea.NoWhere; + _HitItem = null; + } + + SuperGrid.ToolTip.Hide(SuperGrid); + + if (_LastArea == RowArea.InRowInfo) + ProcessRowInfoLeave(); + } + + CancelCapture(); + + base.InternalMouseLeave(e); + + SuperGrid.DoRowMouseLeaveEvent(this); + } + + #endregion + + #region InternalMouseMove + + /// + /// InternalMouseMove + /// + /// + internal override void InternalMouseMove(MouseEventArgs e) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (IsMouseDown == true && _MouseDownHitRow != null) + ProcessMouseDownMove(e, panel); + + ProcessMouseMove(e, panel); + } + + SuperGrid.DoRowMouseMoveEvent(this, e, _HitArea); + + if (Capture == false) + base.InternalMouseMove(e); + } + + #region ProcessMouseDownMove + + private void ProcessMouseDownMove(MouseEventArgs e, GridPanel panel) + { + if (_MouseDownHitRow != null) + { + Rectangle r = ViewRect; + + if (MouseDownPoint.Y < r.Y) + { + int n = SuperGrid.PrimaryGrid.FixedRowHeight - + SuperGrid.PrimaryGrid.FixedHeaderHeight; + + r.Y -= n; + r.Height += n; + } + + VScrollBarAdv vsb = SuperGrid.VScrollBar; + + if ((e.Y >= r.Y) && + (e.Y < r.Bottom || (vsb.Value >= vsb.Maximum - vsb.LargeChange))) + { + SuperGrid.DisableAutoScrolling(); + + switch (_MouseDownHitArea) + { + case RowArea.InRowHeader: + panel.HotItem = _HitItem; + ProcessInRowHeader(panel, e); + break; + + case RowArea.InRowResize: + ProcessInRowResize(panel, e.Location); + break; + + case RowArea.InContent: + case RowArea.InWhiteSpace: + ProcessInContent(panel, e.Location, e); + break; + } + } + else + { + SuperGrid.EnableAutoScrolling(AutoScrollEnable.Vertical, r); + + StopResize(); + StopReorder(); + } + } + } + + #region ProcessInContent + + private void ProcessInContent( + GridPanel panel, Point pt, MouseEventArgs e) + { + GridContainer container = _MouseDownHitRow.Parent as GridContainer; + + if (container != null) + { + if (panel.SelectionGranularity != SelectionGranularity.Cell) + { + _HitItem = GetRowAt(panel, pt); + + if (_HitItem != null) + { + if (DragStarted(panel, e) == false) + { + if (panel.CellDragBehavior == CellDragBehavior.ExtendSelection) + { + if (panel.MultiSelect == true) + { + if (_HitItem != panel.LastProcessedItem) + ProcessExtendSelection(panel, true); + } + } + } + } + } + } + } + + #endregion + + #endregion + + #region ProcessMouseMove + + private void ProcessMouseMove(MouseEventArgs e, GridPanel panel) + { + _HitArea = GetHitArea(e.Location); + + if (IsMouseDown == false) + { + switch (_HitArea) + { + case RowArea.InRowHeader: + panel.HotItem = _HitItem; + SuperGrid.GridCursor = Cursors.Default; + break; + + case RowArea.InRowCheckBox: + case RowArea.InCellCheckBox: + case RowArea.InCellExpand: + panel.HotItem = null; + SuperGrid.GridCursor = Cursors.Hand; + break; + + case RowArea.InRowResize: + panel.HotItem = _HitItem; + SuperGrid.GridCursor = Cursors.HSplit; + break; + + default: + panel.HotItem = null; + SuperGrid.GridCursor = Cursors.Default; + break; + } + } + else + { + if ((Control.MouseButtons & MouseButtons.Left) != MouseButtons.Left) + SuperGrid.GridCursor = Cursors.Default; + } + + if (_HitArea != _LastArea) + { + if (_HitArea == RowArea.InRowInfo) + ProcessRowInfoEnter(e); + + else if (_LastArea == RowArea.InRowInfo) + ProcessRowInfoLeave(); + + if (_HitArea == RowArea.InWhiteSpace || _LastArea == RowArea.InWhiteSpace) + { + if (panel.RowHighlightType == RowHighlightType.Full) + InvalidateRender(Bounds); + else + InvalidateWhitespace(); + } + + _LastArea = _HitArea; + } + } + + #region ProcessRowInfoEnter + + private void ProcessRowInfoEnter(MouseEventArgs e) + { + if (SuperGrid.DoRowInfoEnterEvent(this, e.Location) == false) + SuperGrid.ToolTipText = InfoText; + } + + #endregion + + #region ProcessRowInfoLeave + + private void ProcessRowInfoLeave() + { + SuperGrid.ToolTipText = ""; + SuperGrid.DoRowInfoLeaveEvent(this); + } + + #endregion + + #endregion + + #endregion + + #region InternalMouseDown + + /// + /// InternalMouseDown + /// + /// + internal override void InternalMouseDown(MouseEventArgs e) + { + GridPanel panel = GridPanel; + + RowArea hitArea = _HitArea; + GridContainer hitItem = _HitItem; + + if (panel != null && hitItem != null) + { + SuperGrid.DoRowMouseDownEvent(this, e, hitArea); + + if (_HitArea == RowArea.InRowResize) + { + _MouseDownHitArea = _HitArea; + _MouseDownHitRow = _HitItem; + _MouseDownPoint = e.Location; + + InitRowResize(e); + return; + } + + if (CanSetActiveRow(panel, hitItem, true) == true) + { + _HitItem = hitItem; + _HitArea = hitArea; + + int rowIndex = RowIndex; + + if (panel.OnlySendFinalRowActivatedEvents == false || hitArea != RowArea.InSubItem) + { + if (panel.SetActiveRow(_HitItem, true) == true) + { + if (_HitArea != RowArea.InContent) + panel.DeactivateEdit(); + + if (rowIndex > RowIndex) + { + SuperGrid.ArrangeGrid(); + + GridContainer row = panel.GetElementAt(e) as GridContainer; + + if (row != null) + { + row.InternalMouseMove(e); + row.InternalMouseDown(e); + return; + } + } + + _MouseDownHitArea = _HitArea; + _MouseDownHitRow = _HitItem; + _MouseDownPoint = e.Location; + + _dragSelection = false; + _dragStarted = false; + + switch (_HitArea) + { + case RowArea.InRowHeader: + panel.LastProcessedItem = _HitItem; + + switch (panel.RowDragBehavior) + { + case RowDragBehavior.Move: + case RowDragBehavior.GroupMove: + InitExtendSelection(panel); + + if ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) == 0) + InitRowMove(panel); + break; + + case RowDragBehavior.ExtendSelection: + InitSelectOrDrag(panel); + break; + } + return; + + case RowArea.InContent: + if (_HitItem is GridPanel || + panel.SelectionGranularity != SelectionGranularity.Cell) + { + InitSelectOrDrag(panel); + } + break; + + case RowArea.InWhiteSpace: + panel.LastProcessedItem = _HitItem; + + GridCell acell = SuperGrid.ActiveCell; + + if (acell != null) + acell.ResumeMerge(null); + + switch (panel.RowWhitespaceClickBehavior) + { + case RowWhitespaceClickBehavior.ClearSelection: + panel.ClearAll(); + break; + + case RowWhitespaceClickBehavior.ExtendSelection: + InitExtendSelection(panel); + break; + } + return; + + case RowArea.InCellExpand: + panel.LastProcessedItem = _HitItem; + + ProcessInExpandButton(e); + + if (panel.SelectionGranularity != SelectionGranularity.Cell) + return; + break; + } + + base.InternalMouseDown(e); + } + else + { + _MouseDownHitArea = RowArea.NoWhere; + _MouseDownHitRow = null; + } + } + else + { + _MouseDownHitArea = _HitArea; + _MouseDownHitRow = _HitItem; + _MouseDownPoint = e.Location; + + base.InternalMouseDown(e); + } + } + } + } + + #region InitSelectOrDrag + + private void InitSelectOrDrag(GridPanel panel) + { + if (panel.SuperGrid.HasItemDragHandler == false || IsSelected == false || + ((Control.ModifierKeys & (Keys.Control | Keys.Shift)) != Keys.None)) + { + InitExtendSelection(panel); + } + else if (IsMouseDown == true) + { + Capture = true; + + _dragSelection = true; + } + } + + #endregion + + #endregion + + #region InternalMouseUp + + /// + /// InternalMouseUp + /// + /// + internal override void InternalMouseUp(MouseEventArgs e) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + SuperGrid.DisableAutoScrolling(); + + if (SuperGrid.DoRowClickEvent(this, _MouseDownHitArea, e) == false) + { + switch (_MouseDownHitArea) + { + case RowArea.InRowInfo: + SuperGrid.DoRowInfoClickEvent(this, e); + break; + + case RowArea.InRowCheckBox: + ProcessInCheckBox(panel, _HitItem, e); + break; + + case RowArea.InRowResize: + if (IsResizing == true) + { + StopResize(); + + if (panel.ImmediateResize == false) + { + ResizeRow(panel, e.Location.Y); + PostInternalMouseMove(); + } + } + break; + + case RowArea.InRowHeader: + if (IsReordering == true) + { + ReorderRow(panel); + + StopReorder(); + PostInternalMouseMove(); + } + else + { + ExtendDragSelection(panel, e); + + panel.ColumnHeader.InvalidateRowHeader(); + } + + SuperGrid.DoRowHeaderClickEvent(panel, this, e); + break; + + case RowArea.InCellCheckBox: + ProcessInCheckBox(panel, this, e); + break; + + case RowArea.InContent: + ExtendDragSelection(panel, e); + break; + } + } + + base.InternalMouseUp(e); + + SuperGrid.DoRowMouseUpEvent(this, e, _MouseDownHitArea); + } + + _MouseDownHitRow = null; + } + + #region ExtendDragSelection + + private void ExtendDragSelection(GridPanel panel, MouseEventArgs e) + { + if (_dragSelection == true && Capture == true) + { + if (IsMouseSelectableEx(e.Button) == true) + ExtendSelectionEx(panel); + } + } + + #endregion + + #endregion + + #region InternalMouseDoubleClick + + internal override void InternalMouseDoubleClick(MouseEventArgs e) + { + if (SuperGrid.EditorCell == null) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (SuperGrid.DoRowDoubleClickEvent(this, _MouseDownHitArea, e) == false) + { + switch (_MouseDownHitArea) + { + case RowArea.InRowHeader: + SuperGrid.DoRowHeaderDoubleClickEvent(this, e); + break; + + case RowArea.InRowInfo: + SuperGrid.DoRowInfoDoubleClickEvent(this, e); + break; + + case RowArea.InRowResize: + int n = Dpi.DescaleHeight(GetMaximumRowHeight()); + + if (panel.VirtualMode == true) + panel.VirtualRowHeight = n; + else + RowHeight = n; + + StopResize(); + break; + + case RowArea.InContent: + if (panel.RowDoubleClickBehavior == RowDoubleClickBehavior.Activate) + { + if (MouseActivateCell(e, panel) == true) + return; + } + else + { + Expanded = !Expanded; + } + break; + } + + base.InternalMouseDoubleClick(e); + } + } + } + } + + #region MouseActivateCell + + private bool MouseActivateCell(MouseEventArgs e, GridPanel panel) + { + if (panel.MouseEditMode == MouseEditMode.DoubleClick) + { + GridCell cell = null; + + if (panel.SelectionGranularity != SelectionGranularity.Cell) + { + if (_HitArea == RowArea.InContent) + { + switch (panel.RowEditMode) + { + case RowEditMode.PrimaryCell: + if (panel.PrimaryColumn != null && + panel.PrimaryColumn.Visible == true) + { + cell = _Cells[panel.PrimaryColumnIndex]; + } + else + { + cell = FirstVisibleCell; + } + break; + + default: + cell = GetCellAt(panel, e.X, e.Y); + break; + } + } + } + else + { + cell = GetCellAt(panel, e.X, e.Y); + } + + if (cell != null) + { + cell.InternalMouseDoubleClick(e); + + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region ProcessInExpandButton + + private void ProcessInExpandButton(MouseEventArgs e) + { + if ((e.Button & MouseButtons.Left) == MouseButtons.Left) + Expanded = !Expanded; + } + + #endregion + + #region ProcessInCheckBox + + internal void ProcessInCheckBox( + GridPanel panel, GridContainer item, MouseEventArgs e) + { + if ((e.Button & MouseButtons.Left) == MouseButtons.Left) + { + if (item != null && item.CanModify == true) + { + ProcessNewRowChange(panel); + + if (SuperGrid.DoBeforeCheckEvent(panel, item) == false) + item.Checked = !item.Checked; + } + } + } + + #endregion + + #region ProcessInRowHeader + + private void ProcessInRowHeader(GridPanel panel, MouseEventArgs e) + { + GridContainer container = _MouseDownHitRow.Parent as GridContainer; + + if (container != null) + { + Point pt = e.Location; + + _HitItem = GetRowAt(panel, pt); + + if (_HitItem != null) + { + switch (panel.RowDragBehavior) + { + case RowDragBehavior.Move: + case RowDragBehavior.GroupMove: + if (IsInsertRow == false && + panel.VirtualMode == false) + { + if (IsReordering == false) + StartReorder(pt); + else + ContinueReorder(panel, pt); + } + break; + + case RowDragBehavior.ExtendSelection: + if (DragStarted(panel, e) == false) + { + if (panel.MultiSelect == true) + { + if (_HitItem != panel.LastProcessedItem) + ProcessExtendSelection(panel, true); + } + } + break; + } + } + } + } + + #region DragStarted + + private bool DragStarted(GridPanel panel, MouseEventArgs e) + { + if (_dragSelection == true && Capture == true) + { + if (_dragStarted == false) + { + if (DragDrop.DragStarted(_MouseDownPoint, e.Location) == true) + { + _dragStarted = true; + + if (SuperGrid.DoItemDragEvent(this, e) == true) + { + _dragSelection = false; + + InitExtendSelection(panel); + } + } + } + + return (true); + } + + return (false); + } + + #endregion + + #endregion + + #region InitExtendSelection + + private void InitExtendSelection(GridPanel panel) + { + if (IsMouseSelectable() == true) + { + Capture = true; + + ExtendSelectionEx(panel); + } + } + + #region ExtendSelectionEx + + private void ExtendSelectionEx(GridPanel panel) + { + if (_MouseDownHitRow != null && _HitItem != null) + { + _AnchorIndex = _MouseDownHitRow.GridIndex; + + if (panel.LastProcessedItem != this && panel.LastProcessedItem != null) + panel.LastProcessedItem.InvalidateRender(); + + bool ckey = panel.MultiSelect == true + ? ((Control.ModifierKeys & Keys.Control) == Keys.Control) + : false; + + panel.LastProcessedItem = (ckey == true) ? _HitItem : this; + + ProcessExtendSelection(panel, false); + } + } + + #endregion + + #endregion + + #region ProcessExtendSelection + + internal void ProcessExtendSelection(GridPanel panel, bool extend) + { + bool ckey = panel.MultiSelect == true + ? ((Control.ModifierKeys & Keys.Control) == Keys.Control) + : false; + + if (ckey == true) + ProcessControlExtend(panel, extend); + else + ProcessNonControlExtend(panel, extend); + + panel.LastProcessedItem = _HitItem; + } + + #region IsMouseSelectable + + private bool IsMouseSelectable() + { + return (IsMouseSelectableEx(Control.MouseButtons)); + } + + private bool IsMouseSelectableEx(MouseButtons mb) + { + if ((mb & MouseButtons.Left) == MouseButtons.Left) + return (true); + + return (IsSelected == false); + } + + #endregion + + #region ProcessControlExtend + + private void ProcessControlExtend(GridPanel panel, bool extend) + { + if (panel.LastProcessedItem == null) + panel.LastProcessedItem = _MouseDownHitRow; + + GridContainer lastRow = panel.LastProcessedItem as GridContainer; + + if (lastRow != null) + { + int startIndex = lastRow.GridIndex; + int endIndex = _HitItem.GridIndex; + + panel.NormalizeIndices(extend, + _AnchorIndex, ref startIndex, ref endIndex); + + for (int i = startIndex; i <= endIndex; i++) + { + if (extend == false || i != _AnchorIndex) + panel.SetSelectedRows(i, 1, !panel.IsRowSelected(i)); + } + + InvalidateRows(panel, startIndex, endIndex, true); + } + } + + #endregion + + #region ProcessNonControlExtend + + private void ProcessNonControlExtend(GridPanel panel, bool extend) + { + bool skey = (panel.MultiSelect == true) ? + ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) : false; + + if (skey == false || panel.SelectionRowAnchor == null) + panel.SelectionRowAnchor = _MouseDownHitRow; + + ExtendSelection(panel, _HitItem, extend); + } + + #endregion + + #endregion + + #region ResizeRow + + #region InitRowResize + + private void InitRowResize(MouseEventArgs e) + { + if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left) + { + Capture = true; + + _MouseDownDelta = e.Y - _MouseDownHitRow.BoundsRelative.Bottom; + + if (IsVFrozen == false) + _MouseDownDelta += VScrollOffset; + + IsResizing = false; + } + else + { + _MouseDownHitArea = RowArea.NoWhere; + } + } + + #endregion + + #region ProcessInRowResize + + private void ProcessInRowResize(GridPanel panel, Point pt) + { + if (IsResizing == false) + { + StartResize(); + } + else + { + if (panel.ImmediateResize == false) + ContinueResize(panel, pt); + else + ResizeRow(panel, pt.Y); + } + } + + #endregion + + #region StartResize + + private void StartResize() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + IsResizing = true; + + if (panel.ImmediateResize == false) + { + _separatorFw = new FloatWindow(); + _separatorFw.Opacity = .5; + _separatorFw.BackColor = Color.Black; + _separatorFw.Owner = SuperGrid.FindForm(); + } + } + } + + #endregion + + #region StopResize + + private void StopResize() + { + IsResizing = false; + + if (_separatorFw != null) + { + _separatorFw.Close(); + _separatorFw.Dispose(); + + _separatorFw = null; + } + } + + #endregion + + #region ContinueResize + + private void ContinueResize(GridPanel panel, Point pt) + { + Rectangle r = panel.BoundsRelative; + + if (panel.Parent != null) + r.Y -= VScrollOffset; + + r.X -= HScrollOffset; + + if (pt.X > r.X) + { + Rectangle t = _MouseDownHitRow.BoundsRelative; + + if (panel.IsSubPanel == true) + t.X -= HScrollOffset; + + if (IsVFrozen == false) + t.Y -= VScrollOffset; + + int height = pt.Y - t.Y; + + if (height < Dpi.Height(panel.MinRowHeight)) + pt.Y = t.Y + Dpi.Height(panel.MinRowHeight); + + if (pt.Y >= SuperGrid.PrimaryGrid.BoundsRelative.Bottom - Dpi.Height2) + { + _separatorFw.Hide(); + } + else + { + if (pt.Y == panel.BoundsRelative.Bottom - 1) + pt.Y--; + + r.Height = SeparatorHeight; + r.Y = pt.Y; + + r.X = t.X; + r.Width = t.Width; + + Rectangle v = SViewRect; + + if (r.X < v.X) + { + r.Width -= (v.X - r.X); + r.X = v.X; + } + + if (r.Right > v.Right) + r.Width -= (r.Right - v.Right); + + r.Location = SuperGrid.PointToScreen(r.Location); + + _separatorFw.Show(); + + _separatorFw.Bounds = r; + _separatorFw.Size = r.Size; + } + } + } + + #endregion + + #region ResizeRow + + private void ResizeRow(GridPanel panel, int y) + { + int ry = _MouseDownHitRow.BoundsRelative.Bottom; + y -= _MouseDownDelta; + + if (IsVFrozen == false) + y += VScrollOffset; + + int dy = y - ry; + + if (dy != 0) + { + int n = Dpi.DescaleHeight(Size.Height + dy + _MouseDownDelta); + + n = Math.Max(n, panel.MinRowHeight); + n = Math.Min(n, panel.MaxRowHeight); + + if (panel.VirtualMode == true) + { + panel.VirtualRowHeight = n; + } + else + { + if (_MouseDownHitRow is GridRow) + ((GridRow)_MouseDownHitRow).RowHeight = n; + } + + SuperGrid.DoRowResizedEvent(panel, _MouseDownHitRow); + } + } + + #endregion + + #endregion + + #region ReorderRow + + #region InitRowMove + + private void InitRowMove(GridPanel panel) + { + if (panel.CanMoveRow == true) + { + Capture = true; + + panel.ClearAll(); + IsSelected = true; + + IsReordering = false; + + panel.SelectionRowAnchor = _MouseDownHitRow; + } + } + + #endregion + + #region StartReorder + + private void StartReorder(Point pt) + { + if (Math.Abs(MouseDownPoint.Y - pt.Y) > 5) + { + IsReordering = true; + _SeparatorRow = null; + + _headerFw = new FloatWindow(); + _headerFw.Opacity = .3; + _headerFw.Owner = SuperGrid.FindForm(); + _headerFw.Paint += RowHeaderFwPaint; + + _separatorFw = new FloatWindow(); + _separatorFw.BackColor = Color.Black; + _separatorFw.Owner = SuperGrid.FindForm(); + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLines(new Point[] + { + new Point(Dpi.Width3, Dpi.Height3), + new Point(0, Dpi.Height6), + new Point(0, 0), + new Point(Dpi.Width3, Dpi.Height3), + }); + + path.CloseFigure(); + + path.AddLines(new Point[] + { + new Point(Dpi.Width4, Dpi.Height3), + new Point(10000, Dpi.Height3), + new Point(10000, Dpi.Height4), + new Point(Dpi.Width4, Dpi.Height4), + new Point(Dpi.Width4, Dpi.Height3), + }); + + path.CloseFigure(); + + Region rgn = new Region(path); + + _separatorFw.Region = rgn; + } + + } + } + + #endregion + + #region StopReorder + + private void StopReorder() + { + IsReordering = false; + + if (_headerFw != null) + { + _headerFw.Close(); + _headerFw.Paint -= RowHeaderFwPaint; + _headerFw.Dispose(); + + _headerFw = null; + } + + if (_separatorFw != null) + { + _separatorFw.Close(); + _separatorFw.Dispose(); + + _separatorFw = null; + } + } + + #endregion + + #region ContinueReorder + + private void ContinueReorder(GridPanel panel, Point pt) + { + GridContainer row = _HitItem; + + if (row != null) + { + ReorderHeader(pt); + + GridContainer mcont = + _MouseDownHitRow.Parent as GridContainer; + + GridContainer ncont = + row.Parent as GridContainer; + + if (mcont != null && ncont != null) + { + if (mcont == ncont || + (panel.RowDragBehavior == RowDragBehavior.GroupMove)) + { + int n = ncont.Rows.IndexOf(row); + int m = mcont.Rows.IndexOf(_MouseDownHitRow); + + if (m >= 0 && n >= 0) + { + if (_MouseDownHitRow.IsVFrozen == row.IsVFrozen) + ReorderSeparator(panel, pt); + } + } + } + } + } + + #region ReorderHeader + + private void ReorderHeader(Point pt) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = BoundsRelative; + r.Location = PointToScroll(panel, r.Location); + + if (r.Height <= 0) + { + _headerFw.Hide(); + } + else + { + Size size = _headerFw.Size; + Rectangle t = panel.IsSubPanel ? SViewRect : ViewRect; + + if (r.X < t.X) + r.X = t.X; + + if (r.Right > t.Right) + r.Width -= (r.Right - t.Right); + + r.Height = _MouseDownHitRow.ContainerBounds.Height; + r.Height = Math.Min(r.Height, panel.MaxRowHeight); + + r.Y = pt.Y - (r.Height / 2); + + r.Location = SuperGrid.PointToScreen(r.Location); + + _headerFw.Bounds = r; + + if (_headerFw.Visible == false) + _headerFw.Show(); + + else if (r.Size.Equals(size) == false) + _headerFw.Refresh(); + + } + } + } + + #endregion + + #region ReorderSeparator + + private void ReorderSeparator(GridPanel panel, Point pt) + { + GridContainer row = _HitItem; + + if (row != null && + (row.IsChildOf(_MouseDownHitRow) == false)) + { + Rectangle bounds = row.ContainerBounds; + bounds.Location = PointToScroll(panel, bounds.Location); + + bool isBottom = (pt.Y > bounds.Y + bounds.Height / 2); + bool isControlDown = (Control.ModifierKeys & Keys.Control) == Keys.Control; + + if (IsControlDown != isControlDown || + _SeparatorRow != row || IsSeparatorAtBottom != isBottom) + { + if (isBottom == false || panel.ShowInsertRow == false) + { + _SeparatorRow = row; + IsSeparatorAtBottom = isBottom; + + IsControlDown = isControlDown; + + Rectangle r = bounds; + r.Y += isBottom ? row.FixedRowHeight - Dpi.Width4 : -Dpi.Width4; + + Rectangle t = SViewRect; + + if (r.X < t.X) + r.X = t.X; + + int level = row.IndentLevel; + + if (IsSeparatorAtBottom == true && isControlDown == true) + level++; + + int n = Dpi.Width(level * panel.LevelIndentSize.Width + 1); + + r.X += n; + r.Width -= n; + + if (r.Right > t.Right) + r.Width -= (r.Right - t.Right); + + if (IsVFrozen == true || (r.Y + 4 >= t.Y && r.Y < t.Bottom)) + { + r.Location = SuperGrid.PointToScreen(r.Location); + + _separatorFw.Show(); + + _separatorFw.Location = r.Location; + _separatorFw.Width = r.Width; + } + } + } + } + else + { + _SeparatorRow = null; + + if (_separatorFw != null) + _separatorFw.Hide(); + } + } + + #endregion + + #endregion + + #region ReorderRow + + private void ReorderRow(GridPanel panel) + { + if ((_MouseDownHitRow != _SeparatorRow) && + (_MouseDownHitRow != null && _SeparatorRow != null)) + { + if (_SeparatorRow.IsChildOf(_MouseDownHitRow) == false) + { + GridContainer mcont = _MouseDownHitRow.Parent as GridContainer; + GridContainer ncont = _SeparatorRow.Parent as GridContainer; + + if (mcont != null && ncont != null) + { + int n = ncont.Rows.IndexOf(_SeparatorRow); + int m = mcont.Rows.IndexOf(_MouseDownHitRow); + + if (panel.RowDragBehavior == RowDragBehavior.GroupMove) + { + if (IsSeparatorAtBottom == true && + ((Control.ModifierKeys & Keys.Control) == Keys.Control)) + { + n = 0; + ncont = _SeparatorRow; + + IsSeparatorAtBottom = false; + } + } + + if (m >= 0 && n >= 0) + { + if (ncont == mcont) + { + if (n > m && IsSeparatorAtBottom == false) + n--; + + else if (m > n && IsSeparatorAtBottom == true) + n++; + + if (m == n) + return; + } + else + { + if (IsSeparatorAtBottom == true) + n++; + } + + if (SuperGrid.DoRowMovingEvent(this, mcont, m, ref ncont, ref n) == false) + { + _MouseDownHitRow.IsSelected = false; + + mcont.Rows.RemoveAt(m); + ncont.Rows.Insert(n, _MouseDownHitRow); + + panel.UpdateIndicees(panel, panel.Rows, true); + + if (_MouseDownHitRow.IsExpandedVisible == true) + _MouseDownHitRow.SetActive(true); + + ncont.InvalidateRender(); + + SuperGrid.DoRowMovedEvent( + mcont.GridPanel, mcont, _MouseDownHitRow); + } + } + } + } + } + } + + #endregion + + #endregion + + #region RowHeaderFwPaint + + void RowHeaderFwPaint(object sender, PaintEventArgs e) + { + Rectangle r = _headerFw.ClientRectangle; + + if (_MouseDownHitRow != null) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + RenderRowHeader(e.Graphics, panel, _MouseDownHitRow, pstyle, r, false); + } + } + + r.Width--; + r.Height--; + e.Graphics.DrawRectangle(Pens.DimGray, r); + } + + #endregion + + #endregion + + #region ExtendSelection + + internal void ExtendSelection(GridPanel panel) + { + _HitItem = this; + + _MouseDownHitRow = _HitItem; + _MouseDownHitArea = RowArea.InContent; + + InvalidateRowHeader(_MouseDownHitRow); + + ProcessExtendSelection(panel, false); + } + + #endregion + + #region GetHitArea + + /// + /// This routine gets the RowArea 'HitArea' containing the + /// given point (e.g. InCellCheckBox, InCellExpand, InRowHeader, etc). + /// + /// + /// + public RowArea GetHitArea(Point pt) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + _HitItem = this; + + Rectangle r = BoundsRelative; + r.Height = FixedRowHeight; + + if (panel.IsSubPanel == true) + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (r.Contains(pt)) + return (GetRowHitArea(pt, panel, r)); + + return (GetItemHitArea(pt, panel)); + } + + return (RowArea.NoWhere); + } + + #region GetRowHitArea + + private RowArea GetRowHitArea( + Point pt, GridPanel panel, Rectangle r) + { + if (panel.ShowRowHeaders == true) + { + if (pt.X >= r.X && pt.X < r.X + panel.RowHeaderWidthEx) + return (GetRowHeaderArea(pt, panel, r)); + } + + GridColumn column = panel.PrimaryColumn; + + if (column != null && column.Visible == true) + { + Rectangle t = _ExpandButtonBounds; + + if (IsVFrozen == false) + t.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || column.IsHFrozen == false) + t.X -= HScrollOffset; + + if (t.Contains(pt) == true) + return (RowArea.InCellExpand); + + if (CanModify == true) + { + t = CheckBoxBounds; + + if (IsVFrozen == false) + t.Y -= VScrollOffset; + + if (panel.IsSubPanel == true || column.IsHFrozen == false) + t.X -= HScrollOffset; + + if (t.Contains(pt) == true) + return (RowArea.InCellCheckBox); + } + + column = panel.Columns.LastVisibleColumn; + + t = column.BoundsRelative; + t.Location = PointToScroll(panel, t.Location); + + if (pt.X > t.Right) + return (RowArea.InWhiteSpace); + } + + return (RowArea.InContent); + } + + #endregion + + #region GetRowHeaderArea + + private RowArea GetRowHeaderArea( + Point pt, GridPanel panel, Rectangle r) + { + if (InfoImageBounds.Contains(pt) == true) + return (RowArea.InRowInfo); + + if (panel.AllowRowResize == true) + { + if (pt.Y > r.Bottom - Dpi.Height6) + return (RowArea.InRowResize); + } + + return (RowArea.InRowHeader); + } + + #endregion + + #region GetItemHitArea + + private RowArea GetItemHitArea(Point pt, GridPanel panel) + { + _HitItem = GetRowElementAt(pt.X, pt.Y, false) as GridContainer; + + if (_HitItem != null) + { + Rectangle t = SViewRect; + GridPanel ipanel = _HitItem as GridPanel; + + if (ipanel != null) + { + Rectangle bounds = ipanel.BoundsRelative; + bounds.X -= HScrollOffset; + + if (IsVFrozen == false) + bounds.Y -= VScrollOffset; + + if (bounds.X < t.X) + { + bounds.Width -= (t.X - bounds.X); + bounds.X = t.X; + } + + if (bounds.Contains(pt)) + return (RowArea.InSubItem); + + if (panel.ShowRowHeaders == true) + { + Rectangle r = ipanel.ContainerBounds; + r.Width = panel.RowHeaderWidthEx; + + if (panel.IsSubPanel == true) + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (r.Contains(pt)) + return (RowArea.InRowHeader); + } + + if (ipanel.HasCheckBox == true && panel.ReadOnly == false) + { + Rectangle r = ipanel.CheckBoxBounds; + r.Location = PointToScroll(ipanel, r.Location); + + if (r.Contains(pt) == true) + return (RowArea.InRowCheckBox); + } + } + else + { + return (RowArea.InSubItem); + } + } + + return (RowArea.InContent); + } + + #endregion + + #endregion + + #region GetElementAt + + /// + /// Gets the row element containing the given coordinates. + /// + /// + /// + /// Element or null + public override GridElement GetElementAt(int x, int y) + { + return (GetRowElementAt(x, y, true)); + } + + #endregion + + #region GetRowElementAt + + internal GridElement GetRowElementAt(int x, int y, bool clip) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = BoundsRelative; + r.Height = FixedRowHeight; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + + if (panel.IsSubPanel == true) + r.X -= HScrollOffset; + + if (r.Contains(x, y)) + { + GridCell cell = GetCellAt(panel, x, y); + + if (cell != null) + return (cell); + } + else + { + return (base.GetElementAt(x, y)); + } + } + + return (null); + } + + #endregion + + #region GetCellAt + + /// + /// Returns element at specified mouse coordinates + /// + /// + /// Horizontal position + /// Vertical position + /// Reference to child element or null + /// if no element at specified coordinates + protected virtual GridCell GetCellAt(GridPanel panel, int x, int y) + { + bool isFrozen = IsVFrozen; + Rectangle t = SViewRect; + + int[] map = panel.Columns.DisplayIndexMap; + for (int i = 0; i < map.Length; i++) + { + int index = map[i]; + + GridColumn column = panel.Columns[index]; + + if (column.Visible == true) + { + if (index < _Cells.Count) + { + Rectangle bounds = _Cells[index].BoundsRelative; + + if (panel.IsSubPanel == true || column.IsHFrozen == false) + bounds.X -= HScrollOffset; + + if (isFrozen == false) + { + bounds.Y -= VScrollOffset; + bounds.Intersect(t); + } + + if (bounds.Contains(x, y)) + return (_Cells[index]); + } + else + { + Rectangle r = column.BoundsRelative; + r.Y = BoundsRelative.Y; + r.Height = BoundsRelative.Height; + + Rectangle bounds = r; + + if (panel.IsSubPanel == true || column.IsHFrozen == false) + bounds.X -= HScrollOffset; + + if (isFrozen == false) + { + bounds.Y -= VScrollOffset; + bounds.Intersect(t); + } + + if (bounds.Contains(x, y)) + return (GetEmptySelectionCell(column)); + + } + } + } + + return (null); + } + + #region GetEmptySelectionCell + + private GridCell GetEmptySelectionCell(GridColumn column) + { + if (_EmptySelectionCell == null || + _EmptySelectionCell.ColumnIndex != column.ColumnIndex) + { + _EmptySelectionCell = new GridCell(); + } + + _EmptySelectionCell = + GetEmptyCell(_EmptySelectionCell, column.ColumnIndex); + + return (_EmptySelectionCell); + } + + #endregion + + #endregion + + #region GetRowAt + + private GridContainer GetRowAt(GridPanel panel, Point pt) + { + Rectangle r = panel.ContainerBounds; + r.X -= HScrollOffset; + + if (pt.X < r.X) + pt.X = r.X; + + GridContainer row = panel; + GridElement item = row.InternalGetElementAt(pt.X, pt.Y); + + while (item != null) + { + row = item as GridContainer; + + if (row == null) + break; + + if (row is GridRow) + item = ((GridRow)row).GetRowElementAt(pt.X, pt.Y, false); + else + item = row.GetElementAt(pt.X, pt.Y); + + if (item is GridContainer == false) + return (row); + } + + return (null); + } + + #endregion + + #region CreateItemsCollection + + /// + /// Creates the GridItemsCollection that hosts the items. + /// + /// New instance of GridItemsCollection. + protected override GridItemsCollection CreateItemsCollection() + { + GridItemsCollection items = new GridItemsCollection(); + + items.CollectionChanged += ItemsCollectionChanged; + + return (items); + } + + #endregion + + #region DisposeItemsCollection + + /// + /// DisposeItemsCollection + /// + /// + protected override void DisposeItemsCollection(GridItemsCollection items) + { + items.CollectionChanged -= ItemsCollectionChanged; + } + + #endregion + + #region ItemsCollectionChanged + + void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + GridPanel panel = GridPanel; + + bool dataRowChange = false; + + switch (e.Action) + { + case NotifyCollectionChangedAction.Replace: + case NotifyCollectionChangedAction.Add: + + foreach (GridElement item in e.NewItems) + { + if (panel != null && panel.VirtualMode == true) + throw new Exception("Virtual Grid can not have nested items."); + + item.Parent = this; + item.NeedsMeasured = true; + + if (panel != null) + { + GridRow row = item as GridRow; + + if (row != null) + { + dataRowChange = true; + + if (e.Action == NotifyCollectionChangedAction.Replace) + panel.RemoveFromExpDictionary(row); + + panel.AddToExpDictionary(row); + } + else + { + panel.NeedToUpdateIndicees = true; + } + + if (SuperGrid.IsUpdateSuspended == false && panel.IsSorting == false) + panel.ExpandDeletedAtIndex(FullIndex + 1, 1); + + panel.NeedToUpdateIndicees = true; + } + } + + if (dataRowChange == true && panel.GroupColumns.Count > 0) + panel.NeedsGrouped = true; + break; + + case NotifyCollectionChangedAction.Reset: + if (panel != null) + { + dataRowChange = true; + + panel.ClearAll(); + + if (panel.IsSorting == false) + panel.ExpDictionary.Clear(); + } + break; + + case NotifyCollectionChangedAction.Remove: + if (panel != null) + { + dataRowChange = true; + + panel.ClearAll(); + + if (panel.ExpDictionary.Count > 0) + { + foreach (GridContainer item in e.OldItems) + panel.RemoveFromExpDictionary(item as GridRow); + } + } + break; + } + + InvalidateMerge(); + + if (dataRowChange == true) + { + panel.UpdateRowCount(); + + SuperGrid.Invalidate(); + } + } + + #endregion + + #region CellsCollectionChanged + + void CellsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + GridPanel panel = GridPanel; + + switch (e.Action) + { + case NotifyCollectionChangedAction.Replace: + case NotifyCollectionChangedAction.Add: + if (e.Action == NotifyCollectionChangedAction.Replace) + { + for (int i = 0; i < e.OldItems.Count; i++) + { + GridCell cell = e.OldItems[i] as GridCell; + + if (cell != null) + { + if (panel.ExpDictionary.ContainsKey(cell)) + panel.ExpDictionary.Remove(cell); + } + } + } + + for (int i = 0; i < e.NewItems.Count; i++) + { + GridCell cell = e.NewItems[i] as GridCell; + + if (cell != null) + { + cell.Parent = this; + cell.ColumnIndex = e.NewStartingIndex + i; + + if (panel != null) + { + string newExp = cell.Value as string; + + if (newExp != null) + { + newExp = newExp.Trim(); + + if (newExp.StartsWith("=")) + cell.SetCellExp(panel, newExp); + } + } + } + } + break; + + default: + for (int i = 0; i < _Cells.Count; i++) + _Cells[i].Parent = this; + break; + } + + for (int i = 0; i < _Cells.Count; i++) + _Cells[i].ColumnIndex = i; + + if (SuperGrid != null) + { + GridCell cell = SuperGrid.ActiveElement as GridCell; + + if (cell != null) + { + if (cell.GridRow == this && cell.ColumnIndex < Cells.Count) + SuperGrid.ActiveElement = Cells[cell.ColumnIndex]; + } + } + + NeedsMeasured = true; + + if (panel != null && panel.VirtualMode == false) + InvalidateMerge(); + } + + #endregion + + #region GetNextVisibleCell + + /// + /// This routine returns the next visible cell in the + /// row, after the given cell. If the given cell is null, + /// the first visible cell in the row will be returned. + /// + /// + ///Next cell, or null + /// + public GridCell GetNextVisibleCell(GridCell cell) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn column; + + if (cell != null) + { + if (cell.Parent != this) + throw new Exception("Cell is not a member of this row."); + + column = cell.GridColumn; + + if (column != null) + column = panel.Columns.GetNextVisibleColumn(column); + } + else + { + column = panel.FirstVisibleColumn; + } + + if (column != null) + return (GetCell(column.ColumnIndex, panel.AllowEmptyCellSelection)); + } + + return (null); + } + + #endregion + + #region GetPrevVisibleCell + + /// + /// This routine returns the previous visible cell in the + /// row, prior to the given cell. If the given cell is null, + /// the last visible cell in the row will be returned. + /// + /// + ///Previous cell, or null + /// + public GridCell GetPrevVisibleCell(GridCell cell) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn column; + + if (cell != null) + { + if (cell.Parent != this) + throw new Exception("Cell is not a member of this row."); + + column = cell.GridColumn; + + if (column != null) + column = panel.Columns.GetPrevVisibleColumn(column); + } + else + { + column = panel.LastVisibleColumn; + } + + if (column != null) + return (GetCell(column.ColumnIndex, panel.AllowEmptyCellSelection)); + } + + return (null); + } + + #endregion + + #region GetRowHeight + + internal int GetRowHeight() + { + return (Dpi.Height(GetRowHeightEx())); + } + + internal int GetRowHeightEx() + { + if (_RowHeight >= 0) + return (_RowHeight); + + GridPanel panel = GridPanel; + + if (panel != null) + return (panel.DefaultRowHeight); + + return (20); + } + + #endregion + + #region GetRowPreDetailHeight + + internal int GetRowPreDetailHeight() + { + if (_PreDetailRowHeight >= 0) + return (_PreDetailRowHeight); + + GridPanel panel = GridPanel; + + if (panel != null) + return (panel.DefaultPreDetailRowHeight); + + return (0); + } + + #endregion + + #region GetRowPostDetailHeight + + internal int GetRowPostDetailHeight() + { + if (_PostDetailRowHeight >= 0) + return (_PostDetailRowHeight); + + GridPanel panel = GridPanel; + + if (panel != null) + return (panel.DefaultPostDetailRowHeight); + + return (0); + } + + #endregion + + #region GetMaximumRowHeight + + /// + /// This routine calculates and returns the maximum + /// row height based upon the individual measured heights + /// of each visible cell in the row. + /// + /// + public int GetMaximumRowHeight() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + GridColumn[] columns = new GridColumn[panel.Columns.Count]; + + int n = 0; + for (int i = 0; i < panel.Columns.Count; i++) + { + if (panel.Columns[i].Visible == true) + columns[n++] = panel.Columns[i]; + } + + return (GetMaximumRowHeight(columns)); + } + + return (GetRowHeight()); + } + + /// + /// This routine calculates and returns the maximum + /// row height based upon the individual measured heights + /// of each cell in the row, based upon the given array of + /// columns to included in the calculation process. + /// + /// + public int GetMaximumRowHeight(GridColumn[] columns) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + int maxHeight = 0; + + using (Graphics g = SuperGrid.CreateGraphics()) + { + GridLayoutInfo layoutInfo = new GridLayoutInfo(g, panel.BoundsRelative); + GridLayoutStateInfo layoutState = new GridLayoutStateInfo(panel, 0); + + foreach (GridColumn column in columns) + { + if (column != null && + column.ColumnIndex < Cells.Count) + { + GridCell cell = Cells[column.ColumnIndex]; + + if (cell != null) + { + Size oldSize = cell.Size; + + cell.Measure(layoutInfo, layoutState, new Size(column.Width, 0)); + + if (cell.Size.Height > maxHeight) + maxHeight = cell.Size.Height; + + cell.Size = oldSize; + } + } + } + } + + if (maxHeight > 0) + return (maxHeight); + } + + return (GetRowHeight()); + } + + #endregion + + #region PointToScroll + + internal Point PointToScroll(GridPanel panel, Point pt) + { + pt.X -= HScrollOffset; + + if (IsVFrozen == false) + pt.Y -= VScrollOffset; + + return (pt); + } + + #endregion + + #region FlushRow + + internal override void FlushRow() + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (RowNeedsStored == true) + { + RowNeedsStored = false; + + panel.DataBinder.FlushRow(); + + if (panel.NeedToUpdateDataFilter == true) + DataFilter.UpdateRowFilterState(panel, this); + + if (panel.VirtualMode == true) + SuperGrid.DoStoreVirtualRowEvent(panel, this); + + if (RowNeedsSorted == true || + IsTempInsertRow == true || IsInsertRow == true) + { + RowNeedsSorted = false; + + if (panel.VirtualMode == true) + { + panel.VirtualRows.Clear(); + panel.InvalidateMerge(); + + panel.DataBinder.UpdateDataSourceSort(); + } + else + { + panel.UpdateRowPosition(this); + } + + panel.DataBinder.SetPosition(this); + } + } + } + + base.FlushRow(); + } + + #endregion + + /// + /// Reloads the row with the current external DataSource data. + /// + public void ReloadRow() + { + GridPanel panel = GridPanel; + + if (panel != null) + panel.DataBinder.ReloadRow(this); + } + + #region ProcessNewRowChange + + private void ProcessNewRowChange(GridPanel panel) + { + if (panel.ShowInsertRow == true) + { + if (IsInsertRow == true) + { + panel.AddNewInsertRow(); + + SuperGrid.DoRowAddedEvent(panel, panel.Rows.Count - 2); + + panel.InvalidateMerge(); + } + } + } + + #endregion + + #region CancelCapture + + /// + /// Cancels any inprogress operations (resize, reorder) + /// that may have the mouse captured. + /// + public override void CancelCapture() + { + StopReorder(); + StopResize(); + + base.CancelCapture(); + } + + #endregion + + #region Style support + + internal void ApplyCellStyle(CellVisualStyle style, StyleType cs) + { + ValidateStyle(); + + if (_EffectiveCellStyles == null) + _EffectiveCellStyles = new CellVisualStyles(); + + if (_EffectiveCellStyles.IsValid(cs) == false) + { + GridPanel panel = GridPanel; + + int rowIndex = panel.UseAlternateRowStyle ? GridIndex : -1; + + if (rowIndex >= 0 && Parent is GridGroup) + rowIndex -= ((GridGroup)Parent).GridIndex + 1; + + CellVisualStyle cstyle = new CellVisualStyle(); + + if ((rowIndex % 2) > 0) + { + cstyle.ApplyStyle(SuperGrid.BaseVisualStyles.AlternateRowCellStyles[cs]); + cstyle.ApplyStyle(SuperGrid.DefaultVisualStyles.AlternateRowCellStyles[cs]); + cstyle.ApplyStyle(GridPanel.DefaultVisualStyles.AlternateRowCellStyles[cs]); + } + + cstyle.ApplyStyle(CellStyles[cs]); + + SuperGrid.DoGetRowCellStyleEvent(this, cs, ref cstyle); + + _EffectiveCellStyles[cs] = cstyle; + } + + style.ApplyStyle(_EffectiveCellStyles[cs]); + } + + #region ValidateStyle + + private void ValidateStyle() + { + if (_StyleUpdateCount != SuperGrid.StyleUpdateCount) + { + if (_EffectiveCellStyles != null) + { + _EffectiveCellStyles.Dispose(); + _EffectiveCellStyles = null; + } + + _StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #region InvalidateCellStyle + + /// + ///Invalidates the cached Style + ///definition for all defined StyleTypes + /// + public void InvalidateCellStyle() + { + if (_EffectiveCellStyles != null) + { + _EffectiveCellStyles.Dispose(); + _EffectiveCellStyles = null; + } + + foreach (GridCell cell in Cells) + cell.InvalidateStyle(); + + InvalidateLayout(); + } + + /// + ///Invalidate the cached Style + ///definition for the given StyleType + /// + /// + public void InvalidateCellStyle(StyleType type) + { + if (_EffectiveCellStyles != null) + { + if (_EffectiveCellStyles[type] != null) + { + _EffectiveCellStyles[type].Dispose(); + _EffectiveCellStyles[type] = null; + } + } + + foreach (GridCell cell in Cells) + cell.InvalidateStyle(); + + InvalidateLayout(); + } + + #endregion + + #endregion + + #region InvalidateRender + + /// + /// InvalidateRender + /// + public override void InvalidateRender() + { + base.InvalidateRender(); + + foreach (GridCell cell in Cells) + cell.InvalidateRender(); + } + + /// + /// InvalidateRender + /// + /// + public override void InvalidateRender(Rectangle bounds) + { + base.InvalidateRender(bounds); + + foreach (GridCell cell in Cells) + cell.InvalidateRender(); + } + + #endregion + + #region ToString + + /// + /// ToString + /// + /// + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + GridPanel panel = GridPanel; + + if (panel != null) + { + sb.Append("GridRow"); + + if (_Cells.Count > 0) + { + sb.Append(" {"); + + foreach (GridCell cell in _Cells) + { + sb.Append(cell.Value == null ? "" : cell.Value.ToString()); + sb.Append(", "); + } + + sb.Length -= 2; + + sb.Append("}"); + } + } + + return (sb.ToString()); + } + + #endregion + + #region IDisposable Members + + /// + /// Dispose + /// + public override void Dispose() + { + if (_EffectiveCellStyles != null) + { + _EffectiveCellStyles.Dispose(); + _EffectiveCellStyles = null; + } + + if (_Cells != null) + { + foreach (GridCell cell in _Cells) + { + if (cell != null) + cell.Dispose(); + } + + _Cells.CollectionChanged -= CellsCollectionChanged; + } + + DetachNestedRows(true); + + Rows = null; + + base.Dispose(); + } + + #endregion + + #region RowStates + + [Flags] + private enum Rs + { + AllowEdit = (1<<0), + EditorDirty = (1<<1), + ControlDown = (1<<2), + + DetailRow = (1<<3), + TempInsertRow = (1<<4), + + Loading = (1<<5), + Resizing = (1<<6), + Reordering = (1<<7), + + RowDirty = (1<<8), + RowFilteredOut = (1<<9), + + RowCheckChanged = (1 << 10), + RowNeedsGrouped = (1 << 11), + RowNeedsSorted = (1<<12), + RowNeedsStored = (1<<13), + + SeparatorAtBottom = (1<<14), + + Visible = (1<<15), + } + + #endregion + } + + #region enums + + #region RowArea + + /// + /// RowArea + /// + public enum RowArea + { + /// + /// NoWhere + /// + NoWhere, + + /// + /// InCellCheckBox + /// + InCellCheckBox, + + /// + /// InCellExpand + /// + InCellExpand, + + /// + /// InRowCheckBox + /// + InRowCheckBox, + + /// + /// InRowHeader + /// + InRowHeader, + + /// + /// InRowInfo + /// + InRowInfo, + + /// + /// InRowResize + /// + InRowResize, + + /// + /// InContent + /// + InContent, + + /// + /// InSubItem + /// + InSubItem, + + /// + /// InWhiteSpace + /// + InWhiteSpace, + } + + #endregion + + #region RowDoubleClickBehavior + + /// + /// Indicates what happens when a row is double clicked + /// + public enum RowDoubleClickBehavior + { + /// + /// The row is activated + /// + Activate, + + /// + /// The row is expanded or collapsed + /// + ExpandCollapse, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridTextRow.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridTextRow.cs new file mode 100644 index 00000000..d690c145 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridTextRow.cs @@ -0,0 +1,1549 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.SuperGrid.TextMarkup; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Defines the grid column header + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public abstract class GridTextRow : GridElement + { + #region Private variables + + private string _Text; + private bool _EnableMarkup = true; + private BodyElement _TextMarkup; + + private int _RowHeight; + + private HeaderArea _HitArea; + private HeaderArea _MouseDownHitArea; + + private RowHeaderVisibility + _RowHeaderVisibility = RowHeaderVisibility.PanelControlled; + + private TextRowVisualStyles _EffectiveRowStyles; + private int _StyleUpdateCount; + + private Image _BackgroundImage; + private GridBackgroundImageLayout _BackgroundImageLayout = GridBackgroundImageLayout.Tile; + + #endregion + + #region Constructors + + /// + /// GridHeader + /// + protected GridTextRow() + { + } + + /// + /// GridHeader + /// + /// + protected GridTextRow(string text) + { + _Text = text; + } + + #endregion + + #region Public properties + + #region BackgroundImage + + /// + /// Gets or sets the Background Image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Background Image")] + public Image BackgroundImage + { + get { return (_BackgroundImage); } + + set + { + if (_BackgroundImage != value) + { + _BackgroundImage = value; + + OnPropertyChangedEx("BackgroundImage", VisualChangeType.Render); + } + } + } + + #endregion + + #region BackgroundImageLayout + + /// + /// Gets or sets the layout of the Background Image + /// + [DefaultValue(GridBackgroundImageLayout.Tile), Category("Appearance")] + [Description("Indicates the layout of the Background Image")] + public GridBackgroundImageLayout BackgroundImageLayout + { + get { return (_BackgroundImageLayout); } + + set + { + if (_BackgroundImageLayout != value) + { + _BackgroundImageLayout = value; + + OnPropertyChangedEx("BackgroundImageLayout", VisualChangeType.Render); + } + } + } + + #endregion + + #region Bounds + + /// + /// Gets the scroll adjusted bounds + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override Rectangle Bounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle r = BoundsRelative; + + if (panel.IsSubPanel == true) + { + r.X -= HScrollOffset; + + if (IsVFrozen == false) + r.Y -= VScrollOffset; + } + + return (r); + } + + return (Rectangle.Empty); + } + } + + #endregion + + #region EnableMarkup + + /// + /// Gets or sets whether text-markup support is enabled + /// + [DefaultValue(true), Category("Appearance")] + [Description("Indicates whether text-markup support is enabled.")] + public bool EnableMarkup + { + get { return (_EnableMarkup); } + + set + { + if (_EnableMarkup != value) + { + _EnableMarkup = value; + + MarkupTextChanged(); + + OnPropertyChangedEx("EnableMarkup", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageBounds + + /// + /// Gets whether the item is empty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Rectangle ImageBounds + { + get + { + GridPanel panel = GridPanel; + + if (panel != null) + { + TextRowVisualStyle style = GetEffectiveStyle(); + + object figure = style.GetFigure(panel); + + if (figure != null) + { + Rectangle tb, ib; + GetItemBounds(panel, style, Bounds, out tb, out ib); + + return (ib); + } + } + + return (Rectangle.Empty); + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the item is empty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public virtual bool IsEmpty + { + get { return (string.IsNullOrEmpty(_Text) == true); } + } + + #endregion + + #region RowHeight + + /// + /// Gets or sets the row height (0 to auto-size) + /// + [DefaultValue(0), Category("Appearance")] + [Description("Indicates the row height (0 to auto-size)")] + public int RowHeight + { + get { return (_RowHeight); } + + set + { + if (_RowHeight != value) + { + _RowHeight = value; + + OnPropertyChangedEx("RowHeight", VisualChangeType.Layout); + } + } + } + + #endregion + + #region RowHeaderVisibility + + /// + /// Gets or sets whether the RowHeader is displayed + /// + [DefaultValue(RowHeaderVisibility.PanelControlled), Category("Appearance")] + [Description("Indicates whether the RowHeader is displayed")] + public virtual RowHeaderVisibility RowHeaderVisibility + { + get { return (_RowHeaderVisibility); } + + set + { + if (value != _RowHeaderVisibility) + { + _RowHeaderVisibility = value; + + OnPropertyChangedEx("RowHeaderVisibility", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Text + + /// + /// Gets or sets the Text + /// + [Localizable(true), DefaultValue(null), Category("Appearance")] + [Description("Indicates the Text.")] + [Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))] + public string Text + { + get { return (_Text); } + + set + { + if (_Text != value) + { + _Text = value; + + MarkupTextChanged(); + + OnPropertyChangedEx("Text", VisualChangeType.Layout); + } + } + } + + #endregion + + #endregion + + #region MeasureOverride + + /// + /// Performs the layout of the item and sets the Size property to size that item will take. + /// + /// Layout information. + /// + /// + protected override void MeasureOverride( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + Size sizeNeeded = MeasureRow(layoutInfo, stateInfo, constraintSize); + + if (constraintSize.Width > 0) + sizeNeeded.Width = constraintSize.Width; + + Size = sizeNeeded; + } + + #region MeasureRow + + /// + /// MeasureRow + /// + /// + /// + /// + /// + protected virtual Size MeasureRow( + GridLayoutInfo layoutInfo, GridLayoutStateInfo stateInfo, Size constraintSize) + { + Size sizeNeeded = Size.Empty; + + if (RowHeight > 0 || IsEmpty == false) + { + GridPanel panel = stateInfo.GridPanel; + + TextRowVisualStyle style = GetSizingStyle(panel); + Size figureSize = style.GetFigureSize(panel); + + Alignment imageAlignment = style.ImageAlignment; + + if (style.IsOverlayImage == true) + imageAlignment = Alignment.MiddleCenter; + + int width = constraintSize.Width; + + if (width > 0) + { + if (panel.IsSubPanel == false) + width = ViewRect.Width; + + if (CanShowRowHeader(panel) == true) + width -= panel.RowHeaderWidthEx; + + switch (imageAlignment) + { + case Alignment.TopCenter: + case Alignment.MiddleCenter: + case Alignment.BottomCenter: + break; + + default: + width -= figureSize.Width; + break; + } + } + + Size borderSize = style.GetBorderSize(true); + + if (constraintSize.Width > 0) + width -= borderSize.Width; + + Size size = GetTextSize(layoutInfo, style, width); + + switch (imageAlignment) + { + case Alignment.MiddleCenter: + sizeNeeded.Height = Math.Max(figureSize.Height, size.Height) + borderSize.Height; + sizeNeeded.Width = Math.Max(size.Width, figureSize.Width) + borderSize.Width; + break; + + case Alignment.TopCenter: + case Alignment.BottomCenter: + sizeNeeded.Width = Math.Max(size.Width, figureSize.Width) + borderSize.Width; + sizeNeeded.Height = size.Height + figureSize.Height + borderSize.Height; + break; + + default: + sizeNeeded.Width = size.Width + figureSize.Width + borderSize.Width; + sizeNeeded.Height = Math.Max(figureSize.Height, size.Height) + borderSize.Height; + break; + } + + if (RowHeight > 0) + sizeNeeded.Height = Dpi.Width(RowHeight); + else + sizeNeeded.Height += Dpi.Width1; + } + + return (sizeNeeded); + } + + #endregion + + #region GetTextSize + + private Size GetTextSize( + GridLayoutInfo layoutInfo, TextRowVisualStyle style, int width) + { + Size size = Size.Empty; + + if (string.IsNullOrEmpty(_Text) == false) + { + if (_TextMarkup != null) + { + size = GetMarkupTextSize(layoutInfo, style, width); + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + if (width <= 0) + { + if (style.AllowWrap == Tbool.True) + tf &= ~eTextFormat.WordBreak; + } + + size = TextHelper.MeasureText( + layoutInfo.Graphics, _Text, style.Font, new Size(width, 0), tf); + } + } + + return (size); + } + + #region GetMarkupTextSize + + private Size GetMarkupTextSize( + GridLayoutInfo layoutInfo, TextRowVisualStyle style, int width) + { + Graphics g = layoutInfo.Graphics; + + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + _TextMarkup.InvalidateElementsSize(); + _TextMarkup.Measure(new Size(width, 0), d); + + return (_TextMarkup.Bounds.Size); + } + + #endregion + + #endregion + + #endregion + + #region GetSizingStyle + + /// + /// GetSizingStyle + /// + /// + /// + protected TextRowVisualStyle GetSizingStyle(GridPanel panel) + { + StyleType style = panel.GetSizingStyle(); + + if (style == StyleType.NotSet) + style = StyleType.Default; + + return (GetEffectiveStyle(style)); + } + + #endregion + + #region ArrangeOverride + + /// + /// Performs the arrange pass layout of the item + /// when final position and size of the item has been set + /// + /// Layout information. + /// + /// Layout bounds + protected override void ArrangeOverride(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + Size = ArrangeRow(layoutInfo, stateInfo, layoutBounds); + } + + /// + /// ArrangeRow + /// + /// + /// + /// + /// + protected virtual Size ArrangeRow(GridLayoutInfo layoutInfo, + GridLayoutStateInfo stateInfo, Rectangle layoutBounds) + { + Size size = Size; + + size.Width = stateInfo.GridPanel.ColumnHeader.BoundsRelative.Width; + + return (size); + } + + #endregion + + #region RenderOverride + + /// + /// Performs drawing of the item and its children. + /// + /// Holds contextual rendering information. + protected override void RenderOverride(GridRenderInfo renderInfo) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + Rectangle bounds = Bounds; + + if (bounds.Height > 0) + { + Rectangle r = bounds; + r.Inflate(2, 2); + + if (r.IntersectsWith(renderInfo.ClipRectangle)) + RenderRow(renderInfo, panel, bounds); + } + } + } + + #region RenderRow + + /// + /// RenderRow + /// + /// + /// + /// + protected virtual void RenderRow( + GridRenderInfo renderInfo, GridPanel panel, Rectangle r) + { + Graphics g = renderInfo.Graphics; + + TextRowVisualStyle style = GetEffectiveStyle(); + GridPanelVisualStyle pstyle = panel.GetEffectiveStyle(); + + object figure = style.GetFigure(panel); + + Rectangle tb, ib; + r = GetItemBounds(panel, style, r, out tb, out ib); + + if (r.Width > 1 && r.Height > 1) + { + if (SuperGrid.DoPreRenderTextRowEvent(g, this, RenderParts.Background, r) == false) + { + RenderRowBackground(g, style, r); + SuperGrid.DoPostRenderTextRowEvent(g, this, RenderParts.Background, r); + } + + RenderBorder(g, panel, pstyle, r); + + if (SuperGrid.DoPreRenderTextRowEvent(g, this, RenderParts.Border, r) == false) + { + RenderRowBorder(g, style, r); + SuperGrid.DoPostRenderTextRowEvent(g, this, RenderParts.Border, r); + } + } + + if (style.ImageOverlay != ImageOverlay.Top) + style.RenderFigure(g, panel, ib); + + if (tb.Width > 0 && tb.Height > 0) + { + if (SuperGrid.DoPreRenderTextRowEvent(g, this, RenderParts.Content, r) == false) + { + RenderRowText(g, style, tb); + SuperGrid.DoPostRenderTextRowEvent(g, this, RenderParts.Content, tb); + } + } + + if (ib.Width > 0 && ib.Height > 0) + { + if (style.ImageOverlay == ImageOverlay.Top) + style.RenderFigure(g, panel, ib); + } + + if (SuperGrid.DoPreRenderTextRowEvent(g, this, RenderParts.RowHeader, r) == false) + { + RenderRowHeader(g, panel, pstyle, r); + SuperGrid.DoPostRenderTextRowEvent(g, this, RenderParts.RowHeader, r); + } + } + + #region GetItemBounds + + private Rectangle GetItemBounds(GridPanel panel, + TextRowVisualStyle style, Rectangle r, out Rectangle tb, out Rectangle ib) + { + Rectangle v = ViewRect; + + if (panel.IsSubPanel == false) + { + r.X = Math.Max(r.X, v.X); + r.Width = v.Width; + } + + if (CanShowRowHeader(panel) == true) + { + r.X += panel.RowHeaderWidthEx; + r.Width -= panel.RowHeaderWidthEx; + } + + tb = GetAdjustedBounds(style, style.GetNonFigureBounds(panel, r)); + ib = style.GetFigureBounds(panel, tb); + + return (r); + } + + #endregion + + #region GetAdjustedBounds + + private Rectangle GetAdjustedBounds(TextRowVisualStyle style, Rectangle r) + { + r.X += (style.BorderThickness.Left + style.Margin.Left + style.Padding.Left); + r.Width -= (style.BorderThickness.Horizontal + style.Margin.Horizontal + style.Padding.Horizontal + 1); + + r.Y += (style.BorderThickness.Top + style.Margin.Top + style.Padding.Top); + r.Height -= (style.BorderThickness.Vertical + style.Margin.Vertical + style.Padding.Vertical + 1); + + return (r); + } + + #endregion + + #region RenderRowBackground + + /// + /// RenderRowBackground + /// + /// + /// + /// + protected void RenderRowBackground( + Graphics g, TextRowVisualStyle style, Rectangle r) + { + r.Width--; + r.Height--; + + using (Brush br = style.Background.GetBrush(r)) + g.FillRectangle(br, r); + + if (_BackgroundImage != null) + { + Rectangle sr = r; + sr.Location = Point.Empty; + + switch (_BackgroundImageLayout) + { + case GridBackgroundImageLayout.TopRight: + OffsetRight(ref sr, ref r); + g.DrawImage(_BackgroundImage, r, sr, GraphicsUnit.Pixel); + break; + + case GridBackgroundImageLayout.BottomLeft: + OffsetBottom(ref sr, ref r); + g.DrawImage(_BackgroundImage, r, sr, GraphicsUnit.Pixel); + break; + + case GridBackgroundImageLayout.BottomRight: + OffsetRight(ref sr, ref r); + OffsetBottom(ref sr, ref r); + g.DrawImage(_BackgroundImage, r, sr, GraphicsUnit.Pixel); + break; + + case GridBackgroundImageLayout.Center: + RenderImageCentered(g, _BackgroundImage, r); + break; + + case GridBackgroundImageLayout.Stretch: + g.DrawImage(_BackgroundImage, r); + break; + + case GridBackgroundImageLayout.Zoom: + RenderImageScaled(g, _BackgroundImage, r); + break; + + case GridBackgroundImageLayout.Tile: + using (TextureBrush tbr = new TextureBrush(_BackgroundImage)) + { + tbr.TranslateTransform(r.X, r.Y); + g.FillRectangle(tbr, r); + } + break; + + default: + g.DrawImage(_BackgroundImage, r, sr, GraphicsUnit.Pixel); + break; + } + } + } + + #region OffsetRight + + private void OffsetRight(ref Rectangle sr, ref Rectangle r) + { + if (_BackgroundImage.Width > r.Width) + sr.X += (_BackgroundImage.Width - r.Width); + else + r.X += (r.Width - _BackgroundImage.Width); + } + + #endregion + + #region OffsetBottom + + private void OffsetBottom(ref Rectangle sr, ref Rectangle r) + { + if (_BackgroundImage.Height > r.Height) + sr.Y += (_BackgroundImage.Height - r.Height); + else + r.Y += (r.Height - _BackgroundImage.Height); + } + + #endregion + + #region RenderImageCentered + + private void RenderImageCentered(Graphics g, Image image, Rectangle r) + { + Rectangle sr = r; + sr.Location = Point.Empty; + + if (image.Width > r.Width) + sr.X += (image.Width - r.Width) / 2; + else + r.X += (r.Width - image.Width) / 2; + + if (image.Height > r.Height) + sr.Y += (image.Height - r.Height) / 2; + else + r.Y += (r.Height - image.Height) / 2; + + g.DrawImage(image, r, sr, GraphicsUnit.Pixel); + } + + #endregion + + #region RenderImageScaled + + private void RenderImageScaled(Graphics g, Image image, Rectangle r) + { + SizeF size = new SizeF(image.Width / image.HorizontalResolution, + image.Height / image.VerticalResolution); + + float scale = Math.Min(r.Width / size.Width, r.Height / size.Height); + + size.Width *= scale; + size.Height *= scale; + + g.DrawImage(image, r.X + (r.Width - size.Width) / 2, + r.Y + (r.Height - size.Height) / 2, + size.Width, size.Height); + } + + #endregion + + #endregion + + #region RenderBorder + + /// + /// RenderBorder + /// + /// + /// + /// + /// + protected virtual void RenderBorder(Graphics g, + GridPanel panel, GridPanelVisualStyle pstyle, Rectangle r) + { + using (Pen pen = new Pen(pstyle.HeaderLineColor)) + { + g.DrawLine(pen, r.X, r.Y - 1, r.Right - 1, r.Y - 1); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right - 1, r.Bottom - 1); + } + } + + #endregion + + #region RenderRowBorder + + /// + /// RenderRowBorder + /// + /// + /// + /// + protected void RenderRowBorder(Graphics g, TextRowVisualStyle style, Rectangle r) + { + if (style.BorderPattern == null || + style.BorderThickness == null || style.BorderColor == null) + { + return; + } + + Rectangle t = r; + t.X += style.Margin.Left; + t.Width -= style.Margin.Horizontal; + + t.Y += style.Margin.Top; + t.Height -= style.Margin.Vertical; + + if (style.BorderColor.IsUniform == true && + style.BorderThickness.IsUniform == true && style.BorderPattern.IsUniform == true) + { + if (style.BorderThickness.Top > 0 && style.BorderColor.Top.IsEmpty == false) + { + t.Width -= style.BorderThickness.Top; + t.Height -= style.BorderThickness.Top; + + using (Pen pen = new + Pen(style.BorderColor.Top, style.BorderThickness.Top)) + { + LinePattern pattern = (style.BorderPattern.Top == LinePattern.NotSet) + ? LinePattern.Solid : style.BorderPattern.Top; + + pen.DashStyle = (DashStyle)pattern; + + g.DrawRectangle(pen, t); + } + } + } + else + { + Pen[] pens = style.GetBorderPens(); + + if (pens[(int)BorderSide.Right] != null) + { + int right = t.Right - (style.BorderThickness.Right / 2); + + g.DrawLine(pens[(int)BorderSide.Right], right, t.Top, right, t.Bottom); + } + + if (pens[(int)BorderSide.Bottom] != null) + { + int bottom = t.Bottom - ((style.BorderThickness.Bottom - 1) / 2); + + g.DrawLine(pens[(int)BorderSide.Bottom], t.X, bottom, t.Right, bottom); + } + + if (pens[(int)BorderSide.Left] != null) + g.DrawLine(pens[(int)BorderSide.Left], t.X, t.Top, t.X, t.Bottom); + + if (pens[(int)BorderSide.Top] != null) + g.DrawLine(pens[(int)BorderSide.Top], t.X, t.Top, t.Right, t.Top); + + foreach (Pen pen in pens) + { + if (pen != null) + pen.Dispose(); + } + } + } + + #endregion + + #region RenderRowText + + /// + /// RenderRowText + /// + /// + /// + /// + protected void RenderRowText(Graphics g, + TextRowVisualStyle style, Rectangle r) + { + string s = _Text; + + if (string.IsNullOrEmpty(s) == false) + { + if (r.Width > 0 && r.Height > 0) + { + if (_TextMarkup != null) + { + RenderTextMarkup(g, style, r); + } + else + { + eTextFormat tf = style.GetTextFormatFlags(); + + TextDrawing.DrawString(g, s, style.Font, style.TextColor, r, tf); + } + } + } + } + + #region RenderTextMarkup + + private void RenderTextMarkup( + Graphics g, TextRowVisualStyle style, Rectangle r) + { + MarkupDrawContext d = + new MarkupDrawContext(g, style.Font, style.TextColor, false); + + _TextMarkup.Arrange(new Rectangle(r.Location, r.Size), d); + + Size size = _TextMarkup.Bounds.Size; + + switch (style.Alignment) + { + case Alignment.MiddleLeft: + case Alignment.MiddleCenter: + case Alignment.MiddleRight: + if (r.Height > size.Height) + r.Y += (r.Height - size.Height)/2; + break; + + default: + if (r.Height > size.Height) + r.Y = r.Bottom - size.Height; + break; + } + + _TextMarkup.Bounds = new Rectangle(r.Location, size); + + Region oldClip = g.Clip; + + try + { + g.SetClip(r, CombineMode.Intersect); + + _TextMarkup.Render(d); + } + finally + { + g.Clip = oldClip; + } + } + + #endregion + + #endregion + + #region RenderRowHeader + + /// + /// RenderRowHeader + /// + /// + /// + /// + /// + protected virtual void RenderRowHeader(Graphics g, + GridPanel panel, GridPanelVisualStyle pstyle, Rectangle r) + { + if (CanShowRowHeader(panel) == true) + { + r.X -= panel.RowHeaderWidthEx; + r.Width = panel.RowHeaderWidthEx - 1; + + if (r.Width > 0 && r.Height > 0) + { + TextRowVisualStyle style = GetEffectiveRowHeaderStyle(); + + using (Brush br = style.RowHeaderStyle.Background.GetBrush(r)) + { + if (br != null) + g.FillRectangle(br, r); + } + + if (Dpi.Width1 == Dpi.Height1) + { + using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X, r.Y, r.Right, r.Y); + + g.DrawLine(pen, r.X, r.Y, r.X, r.Bottom); + } + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X, r.Y - 1, r.Right, r.Y - 1); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right, r.Bottom - 1); + + g.DrawLine(pen, r.Right, r.Y, r.Right, r.Bottom - 1); + } + } + else + { + using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Height1)) + g.DrawLine(pen, r.X, r.Y, r.Right, r.Y); + + using (Pen pen = new Pen(style.RowHeaderStyle.BorderHighlightColor, Dpi.Width1)) + g.DrawLine(pen, r.X, r.Y, r.X, r.Bottom); + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Height1)) + { + g.DrawLine(pen, r.X, r.Y - 1, r.Right, r.Y - 1); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right, r.Bottom - 1); + } + + using (Pen pen = new Pen(pstyle.HeaderLineColor, Dpi.Width1)) + g.DrawLine(pen, r.Right, r.Y, r.Right, r.Bottom - 1); + } + } + } + } + + #endregion + + #endregion + + #endregion + + #region Mouse events + + #region InternalMouseEnter + + internal override void InternalMouseEnter(EventArgs e) + { + base.InternalMouseEnter(e); + + InvalidateRender(); + } + + #endregion + + #region InternalMouseLeave + + internal override void InternalMouseLeave(EventArgs e) + { + _HitArea = HeaderArea.NoWhere; + + InvalidateRender(); + + base.InternalMouseLeave(e); + } + + #endregion + + #region InternalMouseMove + + internal override void InternalMouseMove(MouseEventArgs e) + { + SuperGrid.GridCursor = Cursors.Default; + + HeaderArea area = GetHitArea(e.Location); + + if (_HitArea != area) + { + _HitArea = area; + + InvalidateRender(); + } + + if (AllowSelection == true) + { + if (_TextMarkup != null) + _TextMarkup.MouseMove(SuperGrid, e); + } + + base.InternalMouseMove(e); + } + + #endregion + + #region InternalMouseDown + + internal override void InternalMouseDown(MouseEventArgs e) + { + _MouseDownHitArea = _HitArea; + + base.InternalMouseDown(e); + } + + #endregion + + #region InternalMouseUp + + internal override void InternalMouseUp(MouseEventArgs e) + { + if (AllowSelection == true) + { + if (_HitArea == _MouseDownHitArea) + { + switch (_HitArea) + { + case HeaderArea.InRowHeader: + SuperGrid.DoTextRowHeaderClickEvent(this, e); + break; + + case HeaderArea.InContent: + SuperGrid.DoTextRowClickEvent(this, e); + break; + + case HeaderArea.InMarkup: + SuperGrid.DoTextRowClickEvent(this, e); + + if (_TextMarkup != null) + _TextMarkup.Click(SuperGrid); + + break; + } + } + } + + base.InternalMouseUp(e); + } + + #endregion + + #endregion + + #region CanShowRowHeader + + /// + /// CanShowRowHeader + /// + /// + /// + protected virtual bool CanShowRowHeader(GridPanel panel) + { + switch (_RowHeaderVisibility) + { + case RowHeaderVisibility.Always: + return (true); + + case RowHeaderVisibility.PanelControlled: + return (panel.ShowRowHeaders); + } + + return (false); + } + + #endregion + + #region GetHitArea + + /// + /// GetHitArea + /// + /// + /// + public virtual HeaderArea GetHitArea(Point pt) + { + GridPanel panel = GridPanel; + + if (panel != null) + { + if (CanShowRowHeader(panel) == true) + { + Rectangle r = GetRowHeaderBounds(panel); + + if (r.Contains(pt) == true) + return (HeaderArea.InRowHeader); + } + } + + if (_TextMarkup != null) + { + if (_TextMarkup.MouseOverElement != null) + return (HeaderArea.InMarkup); + } + + return (HeaderArea.InContent); + } + + #endregion + + #region GetRowHeaderBounds + + private Rectangle GetRowHeaderBounds(GridPanel panel) + { + if (panel.ShowRowHeaders == true) + { + Rectangle r = BoundsRelative; + + r.Location = panel.PointToScroll(r.Location); + r.Width = Dpi.Width(panel.RowHeaderWidthEx + 2); + + return (r); + } + + return (Rectangle.Empty); + } + + #endregion + + #region Style support routines + + #region GetEffectiveStyle + + internal TextRowVisualStyle GetEffectiveStyle() + { + ValidateRowStyle(); + + StyleState rowState = GetRowState(); + + switch (rowState) + { + case StyleState.MouseOver: + return (GetStyleEx(StyleType.MouseOver)); + + case StyleState.Selected: + return (GetStyleEx(StyleType.Selected)); + + case StyleState.Selected | StyleState.MouseOver: + return (GetStyleEx(StyleType.SelectedMouseOver)); + + case StyleState.ReadOnly: + return (GetStyleEx(StyleType.ReadOnly)); + + case StyleState.ReadOnly | StyleState.MouseOver: + return (GetStyleEx(StyleType.ReadOnlyMouseOver)); + + case StyleState.ReadOnly | StyleState.Selected: + return (GetStyleEx(StyleType.ReadOnlySelected)); + + case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: + return (GetStyleEx(StyleType.ReadOnlySelectedMouseOver)); + + default: + return (GetStyleEx(StyleType.Default)); + } + } + + internal TextRowVisualStyle GetEffectiveStyle(StyleType type) + { + ValidateRowStyle(); + + return (GetStyleEx(type)); + } + + #region GetRowState + + private StyleState GetRowState() + { + StyleState rowState = StyleState.Default; + + if (IsMouseOver == true) + rowState |= StyleState.MouseOver; + + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel == SuperGrid.ActiveGrid) + rowState |= StyleState.Selected; + + if (panel.ReadOnly == true) + rowState |= StyleState.ReadOnly; + } + + return (rowState); + } + + #endregion + + #endregion + + #region GetEffectiveRowHeaderStyle + + internal TextRowVisualStyle GetEffectiveRowHeaderStyle() + { + ValidateRowStyle(); + + StyleState rowState = GetRowHeaderState(); + + switch (rowState) + { + case StyleState.MouseOver: + return (GetStyleEx(StyleType.MouseOver)); + + case StyleState.Selected: + return (GetStyleEx(StyleType.Selected)); + + case StyleState.Selected | StyleState.MouseOver: + return (GetStyleEx(StyleType.SelectedMouseOver)); + + case StyleState.ReadOnly: + return (GetStyleEx(StyleType.ReadOnly)); + + case StyleState.ReadOnly | StyleState.MouseOver: + return (GetStyleEx(StyleType.ReadOnlyMouseOver)); + + case StyleState.ReadOnly | StyleState.Selected: + return (GetStyleEx(StyleType.ReadOnlySelected)); + + case StyleState.ReadOnly | StyleState.MouseOver | StyleState.Selected: + return (GetStyleEx(StyleType.ReadOnlySelectedMouseOver)); + + default: + return (GetStyleEx(StyleType.Default)); + } + } + + #region GetRowHeaderState + + private StyleState GetRowHeaderState() + { + StyleState rowState = StyleState.Default; + + if (_HitArea == HeaderArea.InRowHeader) + rowState |= StyleState.MouseOver; + + GridPanel panel = GridPanel; + + if (panel != null) + { + if (panel.ReadOnly == true) + rowState |= StyleState.ReadOnly; + + if (panel == SuperGrid.ActiveGrid) + rowState |= StyleState.Selected; + } + + return (rowState); + } + + #endregion + + #endregion + + #region GetStyleEx + + private TextRowVisualStyle GetStyleEx(StyleType e) + { + if (_EffectiveRowStyles.IsValid(e) == false) + { + TextRowVisualStyle style = GetNewVisualStyle(); + + StyleType[] css = style.GetApplyStyleTypes(e); + + if (css != null) + ApplyStyleEx(style, css); + + SuperGrid.DoGetTextRowStyleEvent(this, e, ref style); + + if (style.Background == null || style.Background.IsEmpty == true) + style.Background = new Background(Color.White); + + if (style.Font == null) + style.Font = SystemFonts.CaptionFont; + + style.ApplyDefaults(); + + _EffectiveRowStyles[e] = style; + } + + return (_EffectiveRowStyles[e]); + } + + #region GetNewVisualStyle + + /// + /// GetNewVisualStyle + /// + /// + protected virtual TextRowVisualStyle GetNewVisualStyle() + { + return (new TextRowVisualStyle()); + } + + #endregion + + #region ApplyStyleEx + + /// + /// ApplyStyleEx + /// + /// + /// + protected virtual void ApplyStyleEx(TextRowVisualStyle style, StyleType[] css) + { + } + + #endregion + + #region ValidateRowStyle + + private void ValidateRowStyle() + { + if (_EffectiveRowStyles == null || + (_StyleUpdateCount != SuperGrid.StyleUpdateCount)) + { + _EffectiveRowStyles = new TextRowVisualStyles(); + + _StyleUpdateCount = SuperGrid.StyleUpdateCount; + } + } + + #endregion + + #endregion + + #endregion + + #region InvalidateRender + + /// + /// InvalidateRender + /// + public override void InvalidateRender() + { + if (SuperGrid != null) + InvalidateRender(Bounds); + } + + #endregion + + #region ToString + + /// + /// ToString + /// + /// + public override string ToString() + { + string s = base.ToString(); + + if (String.IsNullOrEmpty(_Text) == false) + s += ": (\"" + _Text + "\")"; + + return (s); + } + + #endregion + + #region Markup support + + private void MarkupTextChanged() + { + _TextMarkup = null; + + if (_EnableMarkup == true) + { + if (MarkupParser.IsMarkup(_Text) == true) + { + _TextMarkup = MarkupParser.Parse(_Text); + + if (_TextMarkup != null) + _TextMarkup.HyperLinkClick += TextMarkupLinkClick; + } + } + } + + /// + /// Occurs when a text markup link is clicked + /// + protected virtual void TextMarkupLinkClick(object sender, EventArgs e) + { + HyperLink link = sender as HyperLink; + + SuperGrid.DoTextRowMarkupLinkClickEvent(this, link); + } + + /// + /// Gets plain text without text-markup (if text-markup is used in Text) + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public string PlainText + { + get { return (_TextMarkup != null ? _TextMarkup.PlainText : Text); } + } + + #endregion + } + + #region enums + + #region GridBackgroundImageLayout + + /// + /// Background Image Layout + /// + public enum GridBackgroundImageLayout + { + /// + /// Image is Top Left aligned and unscaled + /// + TopLeft, + + /// + /// Image is Top Right aligned and unscaled + /// + TopRight, + + /// + /// Image is Bottom Left aligned and unscaled + /// + BottomLeft, + + /// + /// Image is Bottom Right aligned and unscaled + /// + BottomRight, + + /// + /// Image is Centered and unscaled + /// + Center, + + /// + /// Image is Stretched to fill the area + /// + Stretch, + + /// + /// Image is unscaled and tiled + /// + Tile, + + /// + /// Image is proportionally scaled to fit + /// + Zoom, + } + + #endregion + + #region RowHeaderVisibility + + /// + /// RowHeaderVisibility + /// + public enum RowHeaderVisibility + { + /// + /// Always visible + /// + Always, + + /// + /// Never visible + /// + Never, + + /// + /// Controlled via Panel.ShowRowHeaders + /// + PanelControlled, + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridTitle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridTitle.cs new file mode 100644 index 00000000..0245fa92 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridTitle.cs @@ -0,0 +1,71 @@ +using System.ComponentModel; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Defines the grid title + /// + public class GridTitle : GridTextRow + { + #region Constructors + + /// + /// GridHeader + /// + public GridTitle() + : this(null) + { + } + + /// + /// GridHeader + /// + /// + public GridTitle(string text) + : base(text) + { + RowHeaderVisibility = RowHeaderVisibility.Never; + } + + #endregion + + #region Public properties + + #region RowHeaderVisibility + + /// + /// Gets or sets whether the RowHeader is displayed + /// + [DefaultValue(RowHeaderVisibility.Never), Category("Appearance")] + [Description("Indicates whether the RowHeader is displayed")] + public override RowHeaderVisibility RowHeaderVisibility + { + get { return (base.RowHeaderVisibility); } + set { base.RowHeaderVisibility = value; } + } + + #endregion + + #endregion + + #region Style support + + /// + /// ApplyStyleEx + /// + /// + /// + protected override void ApplyStyleEx(TextRowVisualStyle style, StyleType[] css) + { + foreach (StyleType cs in css) + { + style.ApplyStyle(SuperGrid.BaseVisualStyles.TitleStyles[cs]); + style.ApplyStyle(SuperGrid.DefaultVisualStyles.TitleStyles[cs]); + style.ApplyStyle(GridPanel.DefaultVisualStyles.TitleStyles[cs]); + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridVirtualRowCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridVirtualRowCollection.cs new file mode 100644 index 00000000..b335d883 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/GridVirtualRowCollection.cs @@ -0,0 +1,533 @@ +using System; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Defines the collection of Virtual Rows + /// + public class GridVirtualRows + { + #region Private Variables + + private GridContainer _Container; + + private const int MaxRows = 50; + private const int MaxBuckets = 100; + + private int _BucketHead; + private VPageBucket _LastAccessedBucket; + private VPageBucket[] _PageBuckets; + + #endregion + + /// + /// GridVirtualRowList + /// + /// + public GridVirtualRows(GridContainer container) + { + _Container = container; + + _PageBuckets = new VPageBucket[MaxBuckets]; + _PageBuckets[0] = new VPageBucket(_Container, 0); + } + + #region Public properties + + #region MaxRowIndex + + /// + /// MaxRowIndex + /// + /// + public int MaxRowIndex + { + get { return (GetMaxRowIndex()); } + set { TruncateRowIndex(value); } + } + + #region TruncateRowIndex + + private void TruncateRowIndex(int index) + { + _LastAccessedBucket = null; + + for (int i = 0; i < MaxBuckets; i++) + { + int n = (_BucketHead + i) % MaxBuckets; + + if (_PageBuckets[n] != null) + { + if (_PageBuckets[n].StartIndex >= index) + _PageBuckets[n] = null; + + else if (_PageBuckets[n].EndIndex > index) + { + for (int j = 0; j < MaxRows; j++) + { + if (_PageBuckets[n].StartIndex + j > index) + _PageBuckets[n].Rows[j] = null; + } + } + } + } + } + + #endregion + + #region GetMaxRowIndex + + private int GetMaxRowIndex() + { + int maxIndex = 0; + + for (int i = 0; i < MaxBuckets; i++) + { + int n = (_BucketHead + i) % MaxBuckets; + + VPageBucket bucket = _PageBuckets[n]; + + if (bucket != null) + { + int index = bucket.StartIndex; + + if (index >= maxIndex) + { + foreach (GridRow row in bucket.Rows) + { + if (row != null) + { + if (row.GridIndex > maxIndex) + maxIndex = row.GridIndex; + } + } + } + } + } + + return (maxIndex); + } + + #endregion + + #endregion + + #region Row Indexer + + /// + /// Row indexer + /// + /// + public GridRow this[int index] + { + get { return (GetRow(index)); } + } + + #endregion + + #endregion + + #region FindBucket + + private VPageBucket FindBucket(int index) + { + if (_LastAccessedBucket != null) + { + if (_LastAccessedBucket.Contains(index)) + return (_LastAccessedBucket); + } + + for (int i = 0; i < MaxBuckets; i++) + { + int n = (_BucketHead + i) % MaxBuckets; + + if (_PageBuckets[n] != null) + { + if (_PageBuckets[n].Contains(index)) + return (_PageBuckets[n]); + } + } + + return (null); + } + + #endregion + + #region FreeRow + + /// + /// FreeRow + /// + /// + /// + /// + public void FreeRow(int index) + { + VPageBucket bucket = FindBucket(index); + + if (bucket != null) + { + GridRow[] rows = bucket.Rows; + GridRow row = rows[index - bucket.StartIndex]; + + if (row != null) + { + row.Dispose(); + rows[index - bucket.StartIndex] = null; + } + } + } + + #endregion + + #region IsCachedRow + + /// + /// Gets whether the row is currently cached + /// + public bool IsCachedRow(int index) + { + if (_LastAccessedBucket != null) + { + if (_LastAccessedBucket.Contains(index) == true) + return (_LastAccessedBucket.IsCached(index)); + } + + for (int i = 0; i < MaxBuckets; i++) + { + int n = (_BucketHead + i) % MaxBuckets; + + if (_PageBuckets[n] != null) + { + if (_PageBuckets[n].Contains(index) == true) + return (_PageBuckets[n].IsCached(index)); + } + } + + return (false); + } + + #endregion + + #region GetRow + + private GridRow GetRow(int index) + { + if (_LastAccessedBucket != null) + { + if (_LastAccessedBucket.Contains(index)) + return (_LastAccessedBucket[index]); + } + + for (int i = 0; i < MaxBuckets; i++) + { + int n = (_BucketHead + i) % MaxBuckets; + + if (_PageBuckets[n] == null) + return (NewBucketRow(n, index)); + + if (_PageBuckets[n].Contains(index)) + { + _LastAccessedBucket = _PageBuckets[n]; + + return (_LastAccessedBucket[index]); + } + } + + int bucket = _BucketHead; + + GridPanel panel = _Container.GridPanel; + + if (panel != null) + { + for (int i = 0; i < MaxBuckets; i++) + { + bucket = (_BucketHead + i) % MaxBuckets; + + if (panel.FrozenRowCount > 0) + { + if (_PageBuckets[bucket].Contains(0)) + continue; + } + + if (panel.ActiveRow != null) + { + if (_PageBuckets[bucket].Contains(panel.ActiveRow.Index)) + continue; + } + break; + } + } + + _BucketHead = (bucket + 1) % MaxBuckets; + + return (NewBucketRow(bucket, index)); + } + + #endregion + + #region NewBucketRow + + private GridRow NewBucketRow(int n, int index) + { + int startIndex = (index / MaxRows) * MaxRows; + + if (_PageBuckets[n] != null) + _PageBuckets[n].Reset(_Container, startIndex); + else + _PageBuckets[n] = new VPageBucket(_Container, startIndex); + + _LastAccessedBucket = _PageBuckets[n]; + + return (_LastAccessedBucket[index]); + } + + #endregion + + #region Clear + + /// + /// Clear + /// + public void Clear() + { + for (int i = 0; i < MaxBuckets; i++) + { + if (_PageBuckets[i] != null) + _PageBuckets[i].Reset(null, 0); + + _PageBuckets[i] = null; + } + + _BucketHead = 0; + _LastAccessedBucket = null; + } + + #endregion + + #region VPageBucket + + private class VPageBucket + { + #region Static data + + static private GridLayoutInfo _layoutInfo = new GridLayoutInfo(null, Rectangle.Empty); + static private GridLayoutStateInfo _stateInfo = new GridLayoutStateInfo(null, 0); + + #endregion + + #region Private variables + + private GridContainer _Container; + private int _StartIndex; + private int _EndIndex; + + private GridRow[] _Rows; + + #endregion + + public VPageBucket(GridContainer container, int startIndex) + { + _Container = container; + _StartIndex = startIndex; + _EndIndex = startIndex + MaxRows - 1; + + _Rows = new GridRow[MaxRows]; + } + + #region Public properties + + #region EndIndex + + public int EndIndex + { + get { return (_EndIndex); } + } + + #endregion + + #region Row Indexer + + /// + /// Row indexer + /// + /// + public GridRow this[int index] + { + get { return (GetRow(index)); } + } + + #endregion + + #region Rows + + public GridRow[] Rows + { + get { return (_Rows); } + } + + #endregion + + #region StartIndex + + public int StartIndex + { + get { return (_StartIndex); } + } + + #endregion + + #endregion + + #region Contains + + public bool Contains(int index) + { + return (index >= _StartIndex && index <= _EndIndex); + } + + #endregion + + #region IsCached + + public bool IsCached(int index) + { + if (Contains(index) == true) + return (_Rows[index - _StartIndex] != null); + + return (false); + } + + #endregion + + #region GetRow + + private GridRow GetRow(int index) + { + int n = index - _StartIndex; + + if (_Rows[n] == null) + _Rows[n] = AllocNewGridRow(index); + + GridRow row = _Rows[n]; + + if (row.ArrangeLayoutCount != row.SuperGrid.ArrangeLayoutCount) + ArrangeRow(row.GridPanel, row); + + return (row); + } + + #endregion + + #region Reset + + public void Reset(GridContainer container, int startIndex) + { + for (int i = 0; i < MaxRows; i++) + { + GridRow row = _Rows[i]; + + if (row != null) + { + row.Dispose(); + + _Rows[i] = null; + } + } + + _Container = container; + _StartIndex = startIndex; + _EndIndex = startIndex + MaxRows - 1; + } + + #endregion + + #region AllocNewGridRow + + private GridRow AllocNewGridRow(int index) + { + GridPanel panel = _Container.GridPanel; + + if (panel != null) + { + GridRow row = new GridRow(); + + row.Parent = _Container; + + row.GridIndex = index; + row.Index = index; + row.RowIndex = index; + row.FullIndex = index; + + row.MergeUpdateCount = _Container.MergeUpdateCount; + row.MergeUpdateCount--; + + row.Loading = true; + + try + { + GridColumnCollection columns = panel.Columns; + + if (columns.Count > 0) + { + for (int i = 0; i < columns.Count; i++) + { + GridColumn col = panel.Columns[i]; + + GridCell cell = new GridCell(col.DefaultNewRowCellValue); + + cell.Parent = row; + cell.ColumnIndex = i; + + row.Cells.Add(cell); + } + } + + ArrangeRow(panel, row); + + if (columns.Count > 0) + { + _Container.SuperGrid.DoLoadVirtualRowEvent(panel, row); + _Container.SuperGrid.DoVirtualRowLoadedEvent(panel, row); + } + } + finally + { + row.Loading = false; + } + + return (row); + } + + return (null); + } + + #region ArrangeRow + + private void ArrangeRow(GridPanel panel, GridRow row) + { + Rectangle r = panel.BoundsRelative; + + int vrh = Dpi.Height(panel.VirtualRowHeight); + + r.Y += (panel.FixedRowHeight - (panel.FrozenRowCount * vrh)); + r.Y += (row.Index * vrh); + + r.Size = new Size(panel.ColumnHeader.Size.Width, vrh); + + _layoutInfo.ClientBounds = r; + _stateInfo.GridPanel = panel; + + row.FixedRowHeight = r.Size.Height; + row.Arrange(_layoutInfo, _stateInfo, r); + } + + #endregion + + #endregion + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Licensing.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Licensing.cs new file mode 100644 index 00000000..a731f1fb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Licensing.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid +{ + internal class NativeFunctions + { + #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) + { + // F962CEC7-CD8F-4911-A9E9-CAB39962FC1F, 189, 266 + string[] parts = key.Split('-'); + int test = 0; + for (int i = parts.Length - 1; i >= 0; i--) + { + if (parts[i] == "A9E9") + test += 11; + else if (parts[i] == "F962CEC7") + test += 12; + else if (parts[i] == "CAB39962FC1F") + test += 2; + else if (parts[i] == "4911") + test += 99; + else if (parts[i] == "CD8F") + test += 65; + } + + keyValidated2 = test + 77; + + if (test == 23) + return false; + + return true; + } +#endif + #endregion + +#if TRIAL + private static Color m_ColorExpFlag=Color.Empty; + internal static bool CheckedThrough = false; + internal static bool ColorExpAlt() + { +#if NOTIMELIMIT + return false; +#else + Color clr=SystemColors.Control; + Color clr2; + Color clr3; + clr2=clr; + if(clr2.ToArgb()==clr.ToArgb()) + { + clr3=clr2; + } + else + { + clr3=clr; + } + + if(!m_ColorExpFlag.IsEmpty) + { + return (m_ColorExpFlag==Color.Black?false:true); + } + try + { + Microsoft.Win32.RegistryKey key=Microsoft.Win32.Registry.ClassesRoot; + try + { + key = key.CreateSubKey("CLSID\\{AC49A37B-FD89-4763-AB1B-C6DF6709657F}\\InprocServer32"); + } + catch (System.UnauthorizedAccessException) + { + key = key.OpenSubKey("CLSID\\{AC49A37B-FD89-4763-AB1B-C6DF6709657F}\\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>28) + { + m_ColorExpFlag=Color.White; + key.SetValue("","windows4.dll"); + key.Close(); + key=null; + return true; + } + if(((TimeSpan)DateTime.Today.Subtract(date)).TotalDays<0) + { + m_ColorExpFlag=Color.White; + key.SetValue("","windows3.dll"); + key.Close(); + key=null; + return true; + } + } + } + finally + { + if(key!=null) + key.Close(); + CheckedThrough = true; + } + } + catch{} + m_ColorExpFlag=Color.Black; + return false; +#endif + } +#endif + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Primitives/CustomCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Primitives/CustomCollection.cs new file mode 100644 index 00000000..374070f4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Primitives/CustomCollection.cs @@ -0,0 +1,1230 @@ +using System; +using System.Collections.Generic; +using System.Collections; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.SuperGrid.Primitives +{ + /// + /// Represents custom collection with INotifyPropertyChanged and INotifyCollectionChanged interface support. + /// + /// + [Serializable, DebuggerDisplay("Count = {Count}"), ComVisible(false)] + public class CustomCollection : IList, IList, INotifyPropertyChanged, INotifyCollectionChanged + { + #region Events + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + #endregion + + #region Private variables + + private SimpleMonitor _monitor; + private object _SyncRoot; + private readonly IList _Items; + private bool _FloatLastItem; + + #endregion + + #region Constructors + + /// + /// Creates new instance of object. + /// + public CustomCollection() + { + _monitor = new SimpleMonitor(); + _Items = new List(); + } + + /// + /// Creates new instance of object. + /// + public CustomCollection(int capacity) + { + _monitor = new SimpleMonitor(); + _Items = new List(capacity); + } + + /// + /// Creates new instance of object. + /// + /// List to initialize collection with. + public CustomCollection(IList list) + { + if (list == null) + throw new ArgumentNullException("list"); + + _monitor = new SimpleMonitor(); + _Items = list; + } + + #endregion + + #region Add + + /// + /// Add item to collection. + /// + /// Item to add. + public void Add(T item) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + InsertItem(_Items.Count, item); + } + + #endregion + + #region AddRange + + /// + /// Add range of items to collection. + /// + /// + public void AddRange(IEnumerable collection) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + CheckReentrancy(); + + int index = _Items.Count; + + if (_FloatLastItem == true) + { + if (_Items.Count > 0 && index == _Items.Count) + index--; + } + + foreach (T item in collection) + _Items.Insert(index++, item); + + OnPropertyChanged(CountString); + + List list = new List(collection); + + NotifyCollectionChangedEventArgs e = new + NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, list); + + OnCollectionChanged(e); + } + + #endregion + + #region Clear + + /// + /// Remove all items from collection. + /// + public void Clear() + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + ClearItems(); + } + + /// + /// Remove all items from collection. + /// + protected virtual void ClearItems() + { + CheckReentrancy(); + + T item = default(T); + + if (_FloatLastItem == true) + { + if (_Items.Count > 0) + item = _Items[_Items.Count - 1]; + } + + _Items.Clear(); + + OnPropertyChanged(CountString); + OnPropertyChanged(ItemString); + + OnCollectionReset(); + + if (_FloatLastItem == true) + _Items.Add(item); + } + + #endregion + + #region Contains + + /// + /// Checks whether collection contains item. + /// + /// Item to look for. + /// true if item is in collection. + public bool Contains(T item) + { + OnCollectionReadAccess(); + + return (_Items.Contains(item)); + } + + #endregion + + #region CopyTo + + /// + /// Copy collection to array. + /// + /// Array to copy to. + /// Index to copy from. + public void CopyTo(T[] array, int index) + { + OnCollectionReadAccess(); + + _Items.CopyTo(array, index); + } + + #endregion + + #region Count + + /// + /// Returns number of items in collection. + /// + public int Count + { + get + { + OnCollectionReadAccess(); + + return (_Items.Count); + } + } + + #endregion + + #region CountString + + private string CountString + { + get { return ("Count"); } + } + + #endregion + + #region FloatLastItem + + internal bool FloatLastItem + { + get { return (_FloatLastItem); } + set { _FloatLastItem = value; } + } + + #endregion + + #region GetEnumerator + + /// + /// Gets enumerator for collection. + /// + /// Enumerator. + public IEnumerator GetEnumerator() + { + OnCollectionReadAccess(); + + return (_Items.GetEnumerator()); + } + + #endregion + + #region Indexer[int] + + /// + /// Returns item at index. + /// + /// Index of item. + /// Item at index. + public T this[int index] + { + get + { + OnCollectionReadAccess(); + + return (_Items[index]); + } + + set + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + if ((index < 0) || (index >= _Items.Count)) + throw new ArgumentOutOfRangeException(); + + SetItem(index, value); + } + } + + #endregion + + #region IndexOf + + /// + /// Returns index of an item. + /// + /// Reference to item. + /// Index of item. + public int IndexOf(T item) + { + OnCollectionReadAccess(); + return (_Items.IndexOf(item)); + } + + #endregion + + #region Insert + + /// + /// Insert item at specified location. + /// + /// Index to insert item in. + /// Item to insert. + public void Insert(int index, T item) + { + if ((index < 0) || (index > _Items.Count)) + index = _Items.Count; + + InsertItem(index, item); + } + + #endregion + + #region InsertItem + + /// + /// Inserts item. + /// + /// Index to insert item at. + /// Reference to item. + protected virtual void InsertItem(int index, T item) + { + CheckReentrancy(); + + if (_FloatLastItem == true) + { + if (_Items.Count > 0 && index == _Items.Count) + index--; + } + + _Items.Insert(index, item); + + OnPropertyChanged(CountString); + OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index); + } + + #endregion + + #region IsCompatibleObject + + private static bool IsCompatibleObject(object value) + { + return (value is T) || (value == null && !typeof (T).IsValueType); + } + + #endregion + + #region ItemString + + private string ItemString + { + get { return ("Item[]"); } + } + + #endregion + + #region Remove + + /// + /// Removes item from collection. + /// + /// Item to remove. + /// true if item was removed. + public bool Remove(T item) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + int index = _Items.IndexOf(item); + + if (index < 0) + return (false); + + RemoveItem(index); + + return (true); + } + + #endregion + + #region RemoveAt + + /// + /// Remove item at specified location. + /// + /// Index of item to remove. + public void RemoveAt(int index) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + if ((index < 0) || (index >= _Items.Count)) + throw new ArgumentOutOfRangeException(); + + RemoveItem(index); + } + + #endregion + + #region RemoveItem + + /// + /// Remove item at specified location. + /// + /// Index of item to remove. + protected virtual void RemoveItem(int index) + { + CheckReentrancy(); + + object item = _Items[index]; + _Items.RemoveAt(index); + + OnPropertyChanged(CountString); + OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, index); + } + + #endregion + + #region SetItem + + /// + /// Set item on location. + /// + /// Index + /// Item to assign. + protected virtual void SetItem(int index, T item) + { + CheckReentrancy(); + + T oldItem = _Items[index]; + _Items[index] = item; + + OnPropertyChanged(CountString); + OnPropertyChanged(ItemString); + + OnCollectionChanged(NotifyCollectionChangedAction.Replace, oldItem, item, index); + } + + #endregion + + #region IList support + + #region Add + + int IList.Add(object value) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + VerifyValueType(value); + + Add((T)value); + + return (Count - 1); + } + + #endregion + + #region Contains + + bool IList.Contains(object value) + { + return (IsCompatibleObject(value) && Contains((T)value)); + } + + #endregion + + #region GetItemsDirect + + /// + /// Returns items directly without checks. + /// + /// List of items. + protected IList GetItemsDirect() + { + return (_Items); + } + + #endregion + + #region Indexer[int] + + object IList.this[int index] + { + get + { + OnCollectionReadAccess(); + return (_Items[index]); + } + set + { + VerifyValueType(value); + this[index] = (T)value; + } + } + + #region IndexOf + + int IList.IndexOf(object value) + { + OnCollectionReadAccess(); + + return (IsCompatibleObject(value) ? IndexOf((T) value) : -1); + } + + #endregion + + #region Insert + + void IList.Insert(int index, object value) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + VerifyValueType(value); + + Insert(index, (T)value); + } + + #endregion + + #region IsFixedSize + + bool IList.IsFixedSize + { + get + { + IList items = _Items as IList; + + return ((items != null) && items.IsFixedSize); + } + } + + #endregion + + #region IsReadOnly + + bool IList.IsReadOnly + { + get { return (_Items.IsReadOnly); } + } + + #endregion + + #region Items + + /// + /// Returns the IList interface for items in collection. + /// + protected IList Items + { + get + { + OnCollectionReadAccess(); + + return (_Items); + } + } + + #endregion + + #region Remove + + void IList.Remove(object value) + { + if (_Items.IsReadOnly) + throw new NotSupportedException("collection is read-only"); + + if (IsCompatibleObject(value)) + Remove((T)value); + } + + #endregion + + #endregion + + #region VerifyValueType + + private static void VerifyValueType(object value) + { + if (!IsCompatibleObject(value)) + throw new ArgumentException("value is of wrong type"); + } + + #endregion + + #endregion + + #region IEnumerable.GetEnumerator + + IEnumerator IEnumerable.GetEnumerator() + { + OnCollectionReadAccess(); + + return (_Items.GetEnumerator()); + } + + #endregion + + #region ICollection support + + #region CopyTo + + void ICollection.CopyTo(Array array, int index) + { + CheckReentrancy(); + OnCollectionReadAccess(); + + if (array == null) + throw new ArgumentNullException("array"); + + if (array.Rank != 1) + throw new ArgumentException("Argument array.Rank multi-dimensional not supported"); + + if (array.GetLowerBound(0) != 0) + throw new ArgumentException("Argument array non zero lower bound not supported"); + + if (index < 0) + throw new ArgumentOutOfRangeException("index", "index must be non-negative number"); + + if ((array.Length - index) < Count) + throw new ArgumentException("array too small"); + + T[] localArray = array as T[]; + + if (localArray != null) + { + _Items.CopyTo(localArray, index); + } + else + { + Type elementType = array.GetType().GetElementType(); + Type c = typeof(T); + + if (elementType == null || + (!elementType.IsAssignableFrom(c) && !c.IsAssignableFrom(elementType))) + { + throw new ArgumentException("Argument array of invalid type"); + } + + object[] objArray = array as object[]; + + if (objArray == null) + throw new ArgumentException("Argument array invalid type"); + + int count = _Items.Count; + + try + { + for (int i = 0; i < count; i++) + objArray[index++] = _Items[i]; + } + catch (ArrayTypeMismatchException) + { + throw new ArgumentException("Argument array invalid type"); + } + } + } + + #endregion + + #region IsSynchronized + + bool ICollection.IsSynchronized + { + get { return false; } + } + + #endregion + + #region IsReadOnly + + bool ICollection.IsReadOnly + { + get { return (_Items.IsReadOnly); } + } + + #endregion + + #region SyncRoot + + object ICollection.SyncRoot + { + get + { + if (_SyncRoot == null) + { + ICollection items = _Items as ICollection; + + if (items != null) + _SyncRoot = items.SyncRoot; + else + System.Threading.Interlocked.CompareExchange(ref _SyncRoot, new object(), null); + } + + return (_SyncRoot); + } + } + + #endregion + + #endregion + + #region OnCollectionReadAccess + + /// + /// Occurs when collection is read. + /// + protected virtual void OnCollectionReadAccess() + { + } + + #endregion + + #region OnPropertyChanged + + /// + /// Occurs when collection property has changed. + /// + /// Event arguments. + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + #endregion + + #region CheckReentrancy + + /// + /// Checks whether call creates reentrancy. + /// + protected void CheckReentrancy() + { + if ((_monitor.Busy && (CollectionChanged != null)) && + (CollectionChanged.GetInvocationList().Length > 1)) + { + throw new InvalidOperationException("CustomCollectionReentrancyNotAllowed"); + } + } + + #endregion + + #region SimpleMonitor + + [Serializable] + private class SimpleMonitor + { + // Fields + private int _BusyCount; + + public void Enter() + { + _BusyCount++; + } + + public void Leave() + { + _BusyCount--; + } + + // Properties + public bool Busy + { + get { return (_BusyCount > 0); } + } + } + #endregion + + #region INotifyCollectionChanged Members + + /// + /// Occurs when collection has changed. + /// + public event NotifyCollectionChangedEventHandler CollectionChanged; + + private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index) + { + OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index)); + } + + private void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem, object newItem, int index) + { + OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index)); + } + + private void OnCollectionReset() + { + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + } + + /// + /// Called when collection has changed. + /// + /// Event arguments. + protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + { + if (CollectionChanged != null) + { + try + { + _monitor.Enter(); + + CollectionChanged(this, e); + } + finally + { + _monitor.Leave(); + } + } + } + #endregion + } + + #region INotifyCollectionChanged + /// + /// Represents collection changed notification interface. + /// + public interface INotifyCollectionChanged + { + /// + /// Occurs when collection changed. + /// + event NotifyCollectionChangedEventHandler CollectionChanged; + } + /// + /// Defines change actions. + /// + public enum NotifyCollectionChangedAction + { + /// + /// Items were added. + /// + Add, + /// + /// Items were removed. + /// + Remove, + /// + /// Items were replaced. + /// + Replace, + /// + /// Items were moved. + /// + Move, + /// + /// Collection was reset. + /// + Reset + } + /// + /// Defines delegate for collection notification events. + /// + /// Event sender. + /// Event arguments. + public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e); + /// + /// Defines collection change notification event arguments. + /// + public class NotifyCollectionChangedEventArgs : EventArgs + { + #region Private Vars + + private NotifyCollectionChangedAction _Action; + private IList _NewItems; + private int _NewStartingIndex; + private IList _OldItems; + private int _OldStartingIndex; + + #endregion + + /// + /// Create new instance of object. + /// + /// Action + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Reset) + { + throw new ArgumentException("WrongActionForCtor"); + } + InitializeAdd(action, null, -1); + } + /// + /// Creates new instance of object. + /// + /// Specifies action. + /// List of changed items. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItems != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + InitializeAdd(action, null, -1); + } + else + { + if (changedItems == null) + { + throw new ArgumentNullException("changedItems"); + } + InitializeAddOrRemove(action, changedItems, -1); + } + } + /// + /// Creates new instance of object. + /// + /// Specifies action. + /// Item that was changed. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItem != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + InitializeAdd(action, null, -1); + } + else + { + InitializeAddOrRemove(action, new object[] { changedItem }, -1); + } + } + + /// + /// Creates new instance of object. + /// + /// Action. + /// New items in collection. + /// Old items in collection. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (newItems == null) + { + throw new ArgumentNullException("newItems"); + } + if (oldItems == null) + { + throw new ArgumentNullException("oldItems"); + } + InitializeMoveOrReplace(action, newItems, oldItems, -1, -1); + } + /// + /// Creates new instance of object. + /// + /// Action. + /// List of changed items. + /// Starting index of change. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int startingIndex) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItems != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + if (startingIndex != -1) + { + throw new ArgumentException("ResetActionRequiresIndexMinus1"); + } + InitializeAdd(action, null, -1); + } + else + { + if (changedItems == null) + { + throw new ArgumentNullException("changedItems"); + } + if (startingIndex < -1) + { + throw new ArgumentException("IndexCannotBeNegative"); + } + InitializeAddOrRemove(action, changedItems, startingIndex); + } + } + /// + /// Creates new instance of object. + /// + /// Action + /// Changed item + /// Index of change + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset)) + { + throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); + } + if (action == NotifyCollectionChangedAction.Reset) + { + if (changedItem != null) + { + throw new ArgumentException("ResetActionRequiresNullItem"); + } + if (index != -1) + { + throw new ArgumentException("ResetActionRequiresIndexMinus1"); + } + InitializeAdd(action, null, -1); + } + else + { + InitializeAddOrRemove(action, new object[] { changedItem }, index); + } + } + /// + /// Creates new instance of object. + /// + /// Action + /// New item + /// Old item + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, -1, -1); + } + /// + /// Creates new instance of object. + /// + /// Action + /// New items. + /// Removed items. + /// Starting index of change. + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (newItems == null) + { + throw new ArgumentNullException("newItems"); + } + if (oldItems == null) + { + throw new ArgumentNullException("oldItems"); + } + InitializeMoveOrReplace(action, newItems, oldItems, startingIndex, startingIndex); + } + /// + /// Creates new instance of object. + /// + /// Action + /// Changed items + /// New index + /// Old index + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Move) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (index < 0) + { + throw new ArgumentException("IndexCannotBeNegative"); + } + InitializeMoveOrReplace(action, changedItems, changedItems, index, oldIndex); + } + /// + /// Creates new instance of object. + /// + /// Action + /// Changed item + /// New index + /// Old index + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Move) + { + throw new ArgumentException("WrongActionForCtor"); + } + if (index < 0) + { + throw new ArgumentException("IndexCannotBeNegative"); + } + object[] newItems = new object[] { changedItem }; + InitializeMoveOrReplace(action, newItems, newItems, index, oldIndex); + } + /// + /// Creates new instance of object. + /// + /// Action. + /// New item + /// Old item + /// New index + public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem, int index) + { + _NewStartingIndex = -1; + _OldStartingIndex = -1; + if (action != NotifyCollectionChangedAction.Replace) + { + throw new ArgumentException("WrongActionForCtor"); + } + InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, index, index); + } + + private void InitializeAdd(NotifyCollectionChangedAction action, IList newItems, int newStartingIndex) + { + _Action = action; + _NewItems = (newItems == null) ? null : ArrayList.ReadOnly(newItems); + _NewStartingIndex = newStartingIndex; + } + + private void InitializeAddOrRemove(NotifyCollectionChangedAction action, IList changedItems, int startingIndex) + { + if (action == NotifyCollectionChangedAction.Add) + { + InitializeAdd(action, changedItems, startingIndex); + } + else if (action == NotifyCollectionChangedAction.Remove) + { + InitializeRemove(action, changedItems, startingIndex); + } + } + + private void InitializeMoveOrReplace(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex, int oldStartingIndex) + { + InitializeAdd(action, newItems, startingIndex); + InitializeRemove(action, oldItems, oldStartingIndex); + } + + private void InitializeRemove(NotifyCollectionChangedAction action, IList oldItems, int oldStartingIndex) + { + _Action = action; + _OldItems = (oldItems == null) ? null : ArrayList.ReadOnly(oldItems); + _OldStartingIndex = oldStartingIndex; + } + + /// + /// Gets the type of the collection change action. + /// + public NotifyCollectionChangedAction Action + { + get + { + return _Action; + } + } + /// + /// Gets list of newly added items. + /// + public IList NewItems + { + get + { + return _NewItems; + } + } + /// + /// Gets new starting index. + /// + public int NewStartingIndex + { + get + { + return _NewStartingIndex; + } + } + /// + /// Gets list of removed items. + /// + public IList OldItems + { + get + { + return _OldItems; + } + } + /// + /// Old starting index. + /// + public int OldStartingIndex + { + get + { + return _OldStartingIndex; + } + } + } + #endregion + +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Primitives/SymbolDef.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Primitives/SymbolDef.cs new file mode 100644 index 00000000..92908cc2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Primitives/SymbolDef.cs @@ -0,0 +1,476 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Globalization; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid.Primitives +{ + [TypeConverter(typeof(SymbolDefConvertor))] + [Editor(typeof(SymbolDefEditor), typeof(UITypeEditor))] + public class SymbolDef : INotifyPropertyChanged, IDisposable + { + #region Private variables + + private string _Symbol = ""; + private string _SymbolRealized; + + private float _SymbolSize; + private Color _SymbolColor = Color.Empty; + private eSymbolSet _SymbolSet = eSymbolSet.Awesome; + + private Font _SymbolFont; + private Size _RealSymbolSize; + + #endregion + + #region Public properties + + #region Symbol + + /// + /// Indicates the displayed Symbol. Symbol setting takes precedence over Image setting. + /// + [DefaultValue(""), Category("Appearance"), Description("displayed Symbol. Symbol setting takes precedence over Image setting.")] + [Editor("DevComponents.DotNetBar.Design.SymbolTypeEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor))] + public string Symbol + { + get { return (_Symbol); } + + set + { + if (value == null) + value = ""; + + if (value != _Symbol) + { + _Symbol = value; + _SymbolRealized = null; + + OnPropertyChangedEx("Symbol"); + } + } + } + + #endregion + + #region SymbolColor + + /// + /// Gets or sets the color of the Symbol. + /// + [Category("Appearance"), Description("Indicates color of the Symbol.")] + public Color SymbolColor + { + get { return (_SymbolColor); } + + set + { + if (_SymbolColor != value) + { + _SymbolColor = value; + + OnPropertyChangedEx("SymbolColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeSymbolColor() + { + return (_SymbolColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetSymbolColor() + { + SymbolColor = Color.Empty; + } + + #endregion + + #region SymbolRealized + + /// + /// Gets the realized symbol string. + /// + [Browsable(false)] + public string SymbolRealized + { + get + { + if (_SymbolRealized == null) + { + if (_Symbol != null) + _SymbolRealized = Symbols.GetSymbol(_Symbol); + } + + return (_SymbolRealized); + } + } + + #endregion + + #region SymbolSet + + /// + /// Gets or sets the symbol set used to represent the Symbol. + /// + [DefaultValue(eSymbolSet.Awesome)] + public eSymbolSet SymbolSet + { + get { return (_SymbolSet); } + + set + { + if (_SymbolSet != value) + { + _SymbolSet = value; + + _SymbolRealized = null; + _SymbolFont = null; + _RealSymbolSize = Size.Empty; + + OnPropertyChangedEx("SymbolSet"); + } + } + } + + #endregion + + #region SymbolSize + + /// + /// Indicates the size of the symbol in points. + /// + [DefaultValue(0f), Category("Appearance")] + [Description("Indicates the size of the symbol in points.")] + public float SymbolSize + { + get { return (_SymbolSize); } + + set + { + if (value != _SymbolSize) + { + _SymbolSize = value; + _SymbolFont = null; + _RealSymbolSize = Size.Empty; + + OnPropertyChangedEx("SymbolSize"); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether SymbolDef is Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + return ((string.IsNullOrEmpty(_Symbol) == true) && + (_SymbolColor.IsEmpty == true) && + (_SymbolSize == 0f)); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region SymbolFont + + internal Font SymbolFont + { + get + { + if (_SymbolFont == null) + _SymbolFont = Symbols.GetFont(SymbolSize, SymbolSet); + + return (_SymbolFont); + } + + set + { + _SymbolFont = value; + } + } + + #endregion + + #region IsValidSymbol + + internal bool IsValidSymbol + { + get { return (string.IsNullOrEmpty(SymbolRealized) == false); } + } + + #endregion + + #endregion + + #region GetSymbolSize + + internal Size GetSymbolSize(Control control) + { + if (_RealSymbolSize == Size.Empty) + { + if (control != null) + { + Font font = SymbolFont; + + using (Graphics g = control.CreateGraphics()) + { + Size size = g.MeasureString(SymbolRealized, font).ToSize(); + + size.Width++; + size.Height++; + + _RealSymbolSize = size; + } + } + } + + return (_RealSymbolSize); + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the SymbolDef. + /// + /// Copy of the SymbolDef. + public SymbolDef Copy() + { + SymbolDef style = new SymbolDef(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(SymbolDef style) + { + style.Symbol = _Symbol; + + style.SymbolColor = _SymbolColor; + style.SymbolSet = _SymbolSet; + style.SymbolSize = _SymbolSize; + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(VisualPropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChangedEx(string s) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + { + VisualPropertyChangedEventArgs e = + new VisualPropertyChangedEventArgs(s); + + eh(this, e); + } + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + { + VisualPropertyChangedEventArgs e = + new VisualPropertyChangedEventArgs(s, changeType); + + eh(this, e); + } + } + + #endregion + + #region UpdateChangeHandler + + private void UpdateChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// StyleChanged + /// + /// + /// + protected virtual void StyleChanged( + object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged((VisualPropertyChangedEventArgs)e); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + SymbolFont = null; + } + + #endregion + } + + #region SymbolDefConvertor + + /// + /// SymbolDefConvertor + /// + public class SymbolDefConvertor : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + SymbolDef sd = value as SymbolDef; + + if (sd != null) + return (sd.SymbolSet.ToString()); + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + + #region SymbolDefEditor + + /// + /// SymbolDefEditor + /// + public class SymbolDefEditor : UITypeEditor + { + #region GetPaintValueSupported + + /// + /// GetPaintValueSupported + /// + /// + /// + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region PaintValue + + /// + /// PaintValue + /// + /// + public override void PaintValue(PaintValueEventArgs e) + { + SymbolDef sd = e.Value as SymbolDef; + + if (sd != null) + { + Font font = Symbols.GetFont(10, sd.SymbolSet); + + Color color = sd.SymbolColor; + + if (sd.SymbolColor.IsEmpty || sd.SymbolColor == Color.White) + color = Color.Brown; + + using (Brush br = new SolidBrush(color)) + { + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + e.Graphics.DrawString(sd.SymbolRealized, font, br, e.Bounds, sf); + } + } + } + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SelectedElementCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SelectedElementCollection.cs new file mode 100644 index 00000000..3062c4e5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SelectedElementCollection.cs @@ -0,0 +1,241 @@ +using System.Collections.Generic; +using DevComponents.DotNetBar.SuperGrid.Primitives; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// SelectedElementCollection + /// + public class SelectedElementCollection : CustomCollection + { + #region Constructors + + /// + /// SelectedElementCollection + /// + public SelectedElementCollection() + { + } + + /// + /// SelectedElementCollection + /// + /// + public SelectedElementCollection(int capacity) + : base(capacity) + { + } + + #endregion + + #region GetCells + + #region GetCells + + /// + /// GetCells + /// + /// + public List GetCells() + { + List cells = new List(); + + bool hasRows = AddRowCells(cells); + bool hasColumns = AddColumnCells(cells, hasRows); + + AddCellCells(cells, hasRows | hasColumns); + + return (cells); + } + + #region AddRowCells + + private bool AddRowCells(List cells) + { + bool hasRows = false; + + foreach (GridElement item in Items) + { + GridRow row = item as GridRow; + + if (row != null) + { + GridPanel panel = row.GridPanel; + + for (int i = 0; i < panel.Columns.Count; i++) + { + GridCell cell = + row.GetCell(i, panel.AllowEmptyCellSelection); + + if (cell != null) + { + if (cell.AllowSelection == true) + cells.Add(cell); + } + } + + hasRows = true; + } + } + + return (hasRows); + } + + #endregion + + #region AddColumnCells + + private bool AddColumnCells(List cells, bool hasRows) + { + bool hasColumns = false; + + foreach (GridElement item in Items) + { + GridColumn column = item as GridColumn; + + if (column != null) + { + GridContainer container = + column.Parent as GridContainer; + + if (container != null) + { + hasColumns = true; + + AddUniqueColumnCells(container, + cells, column.ColumnIndex, hasRows); + } + } + } + + return (hasColumns); + } + + #region AddUniqueColumnCells + + private void AddUniqueColumnCells(GridContainer container, + ICollection cells, int columnIndex, bool hasRows) + { + if (container != null) + { + GridPanel panel = container.GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == true) + { + for (int i = 0; i < panel.VirtualRowCountEx; i++) + { + GridRow row = panel.VirtualRows[i]; + + if (hasRows == false || row.IsSelected == false) + { + if (row.Cells[columnIndex].AllowSelection == true) + cells.Add(row.Cells[columnIndex]); + } + } + } + else + { + foreach (GridContainer item in container.Rows) + { + GridRow row = item as GridRow; + + if (row != null) + { + if (hasRows == false || row.IsSelected == false) + { + GridCell cell = row.GetCell(columnIndex, + panel.AllowEmptyCellSelection); + + if (cell != null) + { + if (cell.AllowSelection == true) + cells.Add(cell); + } + } + + if (row.Rows.Count > 0 && row.Expanded == true) + AddUniqueColumnCells(item, cells, columnIndex, hasRows); + } + } + } + } + } + } + + #endregion + + #endregion + + #region AddCellCells + + private void AddCellCells(List cells, bool hasRowCol) + { + foreach (GridElement item in Items) + { + GridCell cell = item as GridCell; + + if (cell != null) + { + if (cell.AllowSelection == true) + { + if (hasRowCol == true) + AddUniqueCells(cells, cell); + else + cells.Add(cell); + } + } + } + } + + #region AddUniqueCells + + private void AddUniqueCells( + ICollection cells, GridCell cell) + { + GridPanel panel = cell.GridColumn.Parent as GridPanel; + + if (panel != null) + { + if (cell.GridRow.IsSelected == false) + { + if (cell.GridColumn.IsSelected == false) + cells.Add(cell); + } + } + } + + #endregion + + #endregion + + #endregion + + #endregion + + #region Select + + /// + /// + public void Select(bool value) + { + foreach (GridElement item in Items) + { + if (item is GridPanel) + ((GridPanel)item).IsSelected = value; + + else if (item is GridRow) + ((GridRow)item).IsSelected = value; + + else if (item is GridColumn) + ((GridColumn)item).IsSelected = value; + + else if (item is GridCell) + ((GridCell)item).IsSelected = value; + } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SelectedElements.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SelectedElements.cs new file mode 100644 index 00000000..c66a85de --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SelectedElements.cs @@ -0,0 +1,735 @@ +using System; +using System.Collections.Generic; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// SelectedElements + /// + public class SelectedElements + { + #region Private variables + + private List _Ranges; + private SelectedElementType _ElementType; + + #endregion + + /// + /// SelectedElements + /// + public SelectedElements() + { + _Ranges = new List(); + } + + /// + /// SelectedElements + /// + public SelectedElements(SelectedElementType elementType) + : this() + { + ElementType = elementType; + } + + #region Public properties + + #region Count + + /// + /// Count + /// + public int Count + { + get + { + int count = 0; + + if (_Ranges != null) + { + foreach (SelectedRange range in _Ranges) + count += range.Count; + } + + return (count); + } + } + + #endregion + + #region ElementType + + /// + /// Element Type + /// + public SelectedElementType ElementType + { + get { return (_ElementType); } + set { _ElementType = value; } + } + + #endregion + + #region FirstIndex + + /// + /// FirstIndex + /// + public int FirstIndex + { + get + { + if (_Ranges.Count > 0) + return (_Ranges[0].StartIndex); + + return (-1); + } + } + + #endregion + + #region LastIndex + + /// + /// LastIndex + /// + public int LastIndex + { + get + { + if (_Ranges.Count > 0) + return (_Ranges[_Ranges.Count - 1].EndIndex); + + return (-1); + } + } + + #endregion + + #region Ranges + + /// + /// Items + /// + public List Ranges + { + get { return (_Ranges); } + } + + #endregion + + #endregion + + #region FindRange + + /// + /// FindRange + /// + /// + /// + /// + public bool FindRange(int index, out SelectedRange selRange) + { + foreach (SelectedRange range in _Ranges) + { + if (range.Contains(index) == true) + { + selRange = range; + + return (true); + } + } + + selRange = null; + + return (false); + } + + #endregion + + #region AddItem + + /// + /// AddItem + /// + /// + /// + public void AddItem(int index) + { + for (int i = 0; i < _Ranges.Count; i++) + { + SelectedRange range = _Ranges[i]; + + if (index <= range.EndIndex + 1) + { + AddItem(range, i, index); + return; + } + } + + _Ranges.Add(new SelectedRange(index, index)); + + ValidateRanges(); + } + + private void AddItem(SelectedRange range, int i, int index) + { + if (range.StartIndex - 1 == index) + { + range.StartIndex--; + } + else if (range.EndIndex + 1 == index) + { + range.EndIndex++; + + if (i + 1 < _Ranges.Count) + { + if (_Ranges[i + 1].StartIndex == index + 1) + { + _Ranges[i].EndIndex = _Ranges[i + 1].EndIndex; + _Ranges.RemoveAt(i + 1); + } + } + } + else if (range.Contains(index) == false) + { + SelectedRange selRange = new SelectedRange(index, index); + + _Ranges.Insert(i, selRange); + } + + ValidateRanges(); + } + + #endregion + + #region AddRange + + /// + /// + /// + /// + public void AddRange(int startIndex, int endIndex) + { + for (int i = 0; i < _Ranges.Count; i++) + { + SelectedRange range = _Ranges[i]; + + if (endIndex == range.StartIndex - 1) + { + range.StartIndex = startIndex; + + if (i > 0) + { + if (_Ranges[i - 1].EndIndex + 1 == startIndex) + { + _Ranges[i - 1].EndIndex = range.EndIndex; + _Ranges.RemoveAt(i); + } + } + + CoalesceRanges(); + ValidateRanges(); + return; + } + + if (startIndex == range.EndIndex + 1) + { + range.EndIndex = endIndex; + + if (i + 1 < _Ranges.Count) + { + if (_Ranges[i + 1].StartIndex - 1 == endIndex) + { + range.EndIndex = _Ranges[i + 1].EndIndex; + _Ranges.RemoveAt(i + 1); + } + } + + CoalesceRanges(); + ValidateRanges(); + return; + } + } + + SelectedRange selRange = null; + + for (int i = 0; i < _Ranges.Count; i++) + { + SelectedRange range = _Ranges[i]; + + if (range.StartIndex > startIndex) + { + selRange = new SelectedRange(startIndex, endIndex); + _Ranges.Insert(i, selRange); + break; + } + } + + if (selRange == null) + { + selRange = new SelectedRange(startIndex, endIndex); + _Ranges.Add(selRange); + } + + CoalesceRanges(); + } + + #region CoalesceRanges + + private void CoalesceRanges() + { + SelectedRange xRange = _Ranges[0]; + + for (int i = 1; i < _Ranges.Count; i++) + { + SelectedRange range = _Ranges[i]; + + if (range.StartIndex - 1 <= xRange.EndIndex) + { + if (range.EndIndex > xRange.EndIndex) + xRange.EndIndex = range.EndIndex; + + if (range.StartIndex < xRange.StartIndex) + xRange.StartIndex = range.StartIndex; + + range.StartIndex = -1; + } + else + { + xRange = range; + } + } + + for (int i = _Ranges.Count - 1; i > 0; i--) + { + SelectedRange range = _Ranges[i]; + + if (range.StartIndex == -1) + _Ranges.RemoveAt(i); + } + + ValidateRanges(); + } + + #endregion + + #endregion + + #region RemoveItem + + /// + /// RemoveItem + /// + /// + public void RemoveItem(int index) + { + SelectedRange selRange; + + if (FindRange(index, out selRange) == true) + RemoveItem(index, selRange); + } + + /// + /// RemoveItem + /// + /// + /// + /// + public void RemoveItem(int index, SelectedRange range) + { + if (range.StartIndex == index) + { + range.StartIndex++; + + if (range.StartIndex > range.EndIndex) + _Ranges.Remove(range); + } + else if (range.EndIndex == index) + { + range.EndIndex--; + + if (range.StartIndex > range.EndIndex) + _Ranges.Remove(range); + } + else if (range.Contains(index) == true) + { + int i = _Ranges.IndexOf(range); + int endIndex = range.EndIndex; + + range.EndIndex = index - 1; + + _Ranges.Insert(i + 1, + new SelectedRange(index + 1, endIndex)); + } + + ValidateRanges(); + } + + #endregion + + #region RemoveRange + + /// + /// + /// + /// + public bool RemoveRange(int startIndex, int endIndex) + { + bool itemsRemoved = false; + + for (int i = 0; i < _Ranges.Count; i++) + { + SelectedRange range = _Ranges[i]; + + if (range.EndIndex < startIndex) + continue; + + if (range.StartIndex > endIndex) + break; + + if (range.EndIndex >= startIndex && range.EndIndex <= endIndex) + { + if (range.StartIndex < startIndex) + range.EndIndex = startIndex - 1; + else + range.StartIndex = -1; + + itemsRemoved = true; + } + else if (range.StartIndex >= startIndex && range.StartIndex <= endIndex) + { + if (range.EndIndex > endIndex) + range.StartIndex = endIndex + 1; + else + range.StartIndex = -1; + + itemsRemoved = true; + } + else + { + int index = range.EndIndex; + range.EndIndex = startIndex - 1; + + _Ranges.Insert(i + 1, + new SelectedRange(endIndex + 1, index)); + + itemsRemoved = true; + break; + } + } + + for (int i = _Ranges.Count - 1; i >= 0; i--) + { + SelectedRange range = _Ranges[i]; + + if (range.StartIndex == -1) + _Ranges.RemoveAt(i); + } + + ValidateRanges(); + + return (itemsRemoved); + } + + private void ValidateRanges() + { + int n = -2; + + for (int i = 0; i < _Ranges.Count; i++) + { + SelectedRange range = _Ranges[i]; + + if (range.StartIndex - 1 <= n) + throw new Exception("Invalid Range StartIndex!"); + + if (range.StartIndex > range.EndIndex) + throw new Exception("Invalid Range EndIndex!"); + + n = range.EndIndex; + } + } + + #endregion + + #region Clear + + /// + /// Clear + /// + public void Clear() + { + _Ranges.Clear(); + } + + #endregion + + #region OffsetIndices + + /// + /// OffsetIndices + /// + /// + /// + public void OffsetIndices(int index, int count) + { + for (int i=0; i<_Ranges.Count; i++) + { + SelectedRange range = _Ranges[i]; + + if (range.EndIndex >= index) + { + if (range.StartIndex < index) + { + SelectedRange range2 = new SelectedRange(index, range.EndIndex); + + range.EndIndex = index - 1; + + _Ranges.Insert(++i, range2); + } + + OffsetRanges(i, count); + CoalesceRanges(); + break; + } + } + + ValidateRanges(); + } + + private void OffsetRanges(int n, int count) + { + for (int i = n; i < _Ranges.Count; i++) + { + SelectedRange range = _Ranges[i]; + + range.StartIndex += count; + range.EndIndex += count; + } + } + + #endregion + + #region GetNextIndex + + /// + /// GetNextIndex + /// + /// + /// + public bool GetNextIndex(ref int index) + { + if (Count > 0) + { + if (index < LastIndex) + { + index = (index < 0) + ? FirstIndex : NextIndex(index); + + return (true); + } + } + + return (false); + } + + #region NextIndex + + private int NextIndex(int index) + { + index++; + + foreach (SelectedRange range in _Ranges) + { + if (range.StartIndex >= index) + return (range.StartIndex); + + if (range.EndIndex >= index) + return (index); + } + + return (LastIndex); + } + + #endregion + + #endregion + + #region GetPrevIndex + + /// + /// GetPreviousIndex + /// + /// + /// + public bool GetPrevIndex(ref int index) + { + if (Count > 0) + { + if (index > 0) + { + index = (index > LastIndex) + ? LastIndex : PrevIndex(index); + + return (index >= 0); + } + } + + return (false); + } + + #region PrevIndex + + private int PrevIndex(int index) + { + index--; + + for (int i=_Ranges.Count - 1; i >= 0; --i) + { + SelectedRange range = _Ranges[i]; + + if (range.EndIndex <= index) + return (range.EndIndex); + + if (range.StartIndex <= index) + return (index); + } + + return (-1); + } + + #endregion + + #endregion + + + #region Copy + + internal SelectedElements Copy() + { + SelectedElements copy = new SelectedElements(_ElementType); + + foreach (SelectedRange range in _Ranges) + copy.AddRange(range.StartIndex, range.EndIndex); + + return (copy); + } + + #endregion + } + + #region SelectedRange class + + /// + /// SelectedRange + /// + public class SelectedRange + { + #region Private variables + + private int _StartIndex; + private int _EndIndex; + + #endregion + + /// + /// + /// + /// + public SelectedRange(int startIndex, int endIndex) + { + _StartIndex = startIndex; + _EndIndex = endIndex; + } + + #region Public properties + + #region Count + + /// + /// Count + /// + public int Count + { + get { return (_EndIndex - _StartIndex + 1); } + } + + #endregion + + #region EndIndex + + /// + /// EndIndex + /// + public int EndIndex + { + get { return (_EndIndex); } + set { _EndIndex = value; } + } + + #endregion + + #region StartIndex + + /// + /// StartIndex + /// + public int StartIndex + { + get { return (_StartIndex); } + set { _StartIndex = value; } + } + + #endregion + + #endregion + + #region Contains + + /// + /// Contains + /// + /// + /// + public bool Contains(int index) + { + return (index >= _StartIndex && index <= _EndIndex); + } + + #endregion + } + + #endregion + + #region enums + + public enum SelectedElementType + { + /// + /// Unknown range type + /// + Unknown, + + /// + /// Selected Cells + /// + SelectedCells, + + /// + /// Selected Columns + /// + SelectedColumns, + + /// + /// Selected Rows + /// + SelectedRows, + + /// + /// Deleted Rows + /// + DeletedRows, + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SortableBindingList.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SortableBindingList.cs new file mode 100644 index 00000000..a4cc0f11 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SortableBindingList.cs @@ -0,0 +1,456 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + ///SortableBindingList + /// + /// + public class SortableBindingList : BindingList + { + #region Private variables + + private bool _IsSorted; + + private ListSortDirection _ListSortDirection; + private PropertyDescriptor _PropertyDescriptor; + + private readonly Dictionary> _Comparers; + + #endregion + + #region Constructors + + /// + ///SortableBindingList + /// + public SortableBindingList() + : base(new List()) + { + _Comparers = new Dictionary>(); + } + + /// + ///SortableBindingList + /// + /// + public SortableBindingList(IEnumerable enumeration) + : base(new List(enumeration)) + { + _Comparers = new Dictionary>(); + } + + #endregion + + #region Protected properties + + #region Comparers + + /// + /// Comparers + /// + protected Dictionary> Comparers + { + get { return (_Comparers); } + } + + #endregion + + #region IsSorted + + /// + /// IsSortedCore + /// + protected bool IsSorted + { + get { return (_IsSorted); } + set { _IsSorted = value; } + } + + #endregion + + #region IsSortedCore + + /// + /// IsSortedCore + /// + protected override bool IsSortedCore + { + get { return (_IsSorted); } + } + + #endregion + + #region SortDirectionCore + + /// + /// SortDirectionCore + /// + protected override ListSortDirection SortDirectionCore + { + get { return (_ListSortDirection); } + } + + #endregion + + #region SortPropertyCore + + /// + /// SortPropertyCore + /// + protected override PropertyDescriptor SortPropertyCore + { + get { return (_PropertyDescriptor); } + } + + #endregion + + #region SupportsSearchingCore + + /// + /// SupportsSearchingCore + /// + protected override bool SupportsSearchingCore + { + get { return (true); } + } + + #endregion + + #region SupportsSortingCore + + /// + /// SupportsSortingCore + /// + protected override bool SupportsSortingCore + { + get { return (true); } + } + + #endregion + + #endregion + + #region ApplySortCore + + /// + /// ApplySortCore + /// + /// + /// + protected override void ApplySortCore( + PropertyDescriptor property, ListSortDirection direction) + { + List itemsList = (List) Items; + + Type propertyType = property.PropertyType; + + PropertyComparer comparer; + if (_Comparers.TryGetValue(propertyType, out comparer) == false) + { + comparer = new PropertyComparer(property, direction); + _Comparers.Add(propertyType, comparer); + } + + comparer.SetPropertyAndDirection(property, direction); + + itemsList.Sort(comparer); + + _PropertyDescriptor = property; + _ListSortDirection = direction; + _IsSorted = true; + + OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); + } + + #endregion + + #region RemoveSortCore + + /// + /// RemoveSortCore + /// + protected override void RemoveSortCore() + { + _IsSorted = false; + _PropertyDescriptor = base.SortPropertyCore; + _ListSortDirection = base.SortDirectionCore; + + OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); + } + + #endregion + + #region FindCore + + /// + /// FindCore + /// + /// + /// + /// + protected override int FindCore(PropertyDescriptor property, object key) + { + int count = Count; + + for (int i = 0; i < count; ++i) + { + object o = property.GetValue(this[i]); + + if (o != null && o.Equals(key)) + return (i); + } + + return (-1); + } + + #endregion + + #region PropertyComparer + + /// + ///PropertyComparer + /// + /// + public class PropertyComparer : IComparer + { + #region Private variables + + private ListSortDirection _SortDirection; + private PropertyDescriptor _PropertyDescriptor; + private IComparer _Comparer; + + #endregion + + /// + ///PropertyComparer + /// + /// + /// + public PropertyComparer(PropertyDescriptor property, ListSortDirection direction) + { + _PropertyDescriptor = property; + _SortDirection = direction; + + Type comparerForPropertyType = typeof(Comparer<>).MakeGenericType(property.PropertyType); + + _Comparer = (IComparer)comparerForPropertyType.InvokeMember( + "Default", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public, null, null, null); + } + + #region IComparer Members + + /// + /// Compare + /// + /// + /// + /// + public int Compare(T x, T y) + { + int result = _Comparer.Compare(_PropertyDescriptor.GetValue(x), + _PropertyDescriptor.GetValue(y)); + + if (_SortDirection == ListSortDirection.Descending) + return (result * -1); + + return (result); + } + + #endregion + + #region SetPropertyAndDirection + + /// + ///SetPropertyAndDirection + /// + /// + /// + public void SetPropertyAndDirection( + PropertyDescriptor descriptor, ListSortDirection direction) + { + _PropertyDescriptor = descriptor; + _SortDirection = direction; + } + + #endregion + } + + #endregion + } + + /// + ///MultipleSortableBindingList + /// + /// + public class MultipleSortableBindingList : SortableBindingList, IBindingListView + { + #region Private variables + + private ListSortDescriptionCollection _SortDescriptions; + private List> _SortComparers; + + const string FilteringNotSupported = "IBindingListView-implementation of filtering is not supported."; + + #endregion + + #region Constructors + + /// + ///MultipleSortableBindingList + /// + public MultipleSortableBindingList() + : base(new List()) + { + } + + /// + ///MultipleSortableBindingList + /// + /// + public MultipleSortableBindingList(IEnumerable enumeration) + : base(new List(enumeration)) + { + } + + #endregion + + #region Public properties + + #region Filter + + /// + /// IsSortedCore + /// + public string Filter + { + get { throw new NotSupportedException(FilteringNotSupported); } + set { throw new NotSupportedException(FilteringNotSupported); } + } + + #endregion + + #region SortDescriptions + + /// + /// SortDescriptions + /// + public ListSortDescriptionCollection SortDescriptions + { + get { return (_SortDescriptions); } + } + + #endregion + + #region SupportsAdvancedSorting + + /// + /// SupportsAdvancedSorting + /// + public bool SupportsAdvancedSorting + { + get { return (true); } + } + + #endregion + + #region SupportsFiltering + + /// + /// SupportsFiltering + /// + public bool SupportsFiltering + { + get { return (false); } + } + + #endregion + + #endregion + + #region ApplySort + + /// + /// Sorts the list based on the given System.ComponentModel.ListSortDescriptionCollection. + /// + /// The System.ComponentModel.ListSortDescriptionCollection to sort by. + public void ApplySort(ListSortDescriptionCollection sorts) + { + List items = Items as List; + + if (items != null) + { + _SortDescriptions = sorts; + _SortComparers = new List>(); + + foreach (ListSortDescription sort in sorts) + { + if (sort != null) + { + Type propertyType = sort.PropertyDescriptor.PropertyType; + PropertyComparer comparer; + + if (Comparers.TryGetValue(propertyType, out comparer) == false) + { + comparer = new PropertyComparer(sort.PropertyDescriptor, sort.SortDirection); + Comparers.Add(propertyType, comparer); + } + + _SortComparers.Add(comparer); + } + } + + items.Sort(CompareValuesByProperties); + + IsSorted = true; + } + else + { + IsSorted = false; + } + } + + #region CompareValuesByProperties + + private int CompareValuesByProperties(T x, T y) + { + if (x == null) + return ((y == null) ? 0 : -1); + + if (y == null) + return (1); + + for (int i = 0; i < _SortComparers.Count; i++) + { + PropertyComparer comparer = _SortComparers[i]; + ListSortDescription sort = _SortDescriptions[i]; + + comparer.SetPropertyAndDirection(sort.PropertyDescriptor, sort.SortDirection); + + int retval = comparer.Compare(x, y); + + if (retval != 0) + return (retval); + } + + return (0); + } + + #endregion + + #endregion + + #region RemoveFilter + + public void RemoveFilter() + { + throw new NotSupportedException(FilteringNotSupported); + } + + #endregion + } +} \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BackColorBlend.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BackColorBlend.cs new file mode 100644 index 00000000..44144db4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BackColorBlend.cs @@ -0,0 +1,201 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// BackColorBlend + /// + [TypeConverter(typeof(BackColorBlendConvertor))] + public class BackColorBlend : INotifyPropertyChanged + { + #region Private variables + + private Color[] _Colors; // Color values + private float[] _Positions; // Gradient color positions + + #endregion + + #region Public properties + + #region Colors + + /// + /// Gets or sets the ColorBlend Color array + /// + [Browsable(true), DefaultValue(null)] + [Description("Indicates the ColorBlend Color array")] + [TypeConverter(typeof(ArrayConverter))] + public Color[] Colors + { + get { return (_Colors); } + + set + { + if (value != null && value.Length == 0) + value = null; + + _Colors = value; + + OnPropertyChangedEx("Colors"); + } + } + + #endregion + + #region Positions + + /// + /// Gets or sets the ColorBlend Color Positions + /// + [Browsable(true), DefaultValue(null)] + [Description("Indicates the ColorBlend Color Positions")] + [TypeConverter(typeof(ArrayConverter))] + public float[] Positions + { + get { return (_Positions); } + + set + { + if (value != null && value.Length == 0) + value = null; + + _Positions = value; + + OnPropertyChangedEx("Positions"); + } + } + + #endregion + + #region IsEmpty + + /// + /// IsEmpty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get { return (_Colors == null || _Colors.Length == 1 && _Colors[0].IsEmpty); } + } + + #endregion + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the BackColorBlend. + /// + /// Copy of the BackColorBlend. + public BackColorBlend Copy() + { + BackColorBlend copy = new BackColorBlend(); + + if (_Colors != null) + { + copy.Colors = new Color[_Colors.Length]; + + _Colors.CopyTo(copy.Colors, 0); + } + + if (_Positions != null) + { + copy.Positions = new float[_Positions.Length]; + + _Positions.CopyTo(copy.Positions, 0); + } + + return (copy); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChangedEx(string s) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + { + VisualPropertyChangedEventArgs e = + new VisualPropertyChangedEventArgs(s); + + eh(this, e); + } + } + + #endregion + } + + #region BackColorBlendConvertor + + /// + /// BackColorBlendConvertor + /// + public class BackColorBlendConvertor : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + BackColorBlend cb = value as BackColorBlend; + + if (cb != null) + { + ColorConverter cvt = new ColorConverter(); + + if (cb.Colors != null) + { + if (cb.Colors[0] != Color.Empty) + return (cvt.ConvertToString(cb.Colors[0])); + + if (cb.Colors.Length > 1 && cb.Colors[1] != Color.Empty) + return (cvt.ConvertToString(cb.Colors[1])); + } + } + + return (String.Empty); + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/Background.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/Background.cs new file mode 100644 index 00000000..0f7cd1f6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/Background.cs @@ -0,0 +1,766 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using DevComponents.Instrumentation.Primitives; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Represents background of visual style. + /// + [TypeConverter(typeof(BackgroundConvertor))] + [Editor(typeof(BackgroundEditor), typeof(UITypeEditor))] + public class Background : INotifyPropertyChanged, IDisposable + { + #region Static data + + /// + /// Empty + /// + /// + /// Returns Empty instance of BorderPattern. + /// + public static Background Empty + { + get { return (new Background()); } + } + + #endregion + + #region Private variables + + private Color _Color1 = Color.Empty; + private Color _Color2 = Color.Empty; + + private int _GradientAngle = 90; + + private BackFillType _BackFillType = BackFillType.Angle; + private BackColorBlend _BackColorBlend; + + #endregion + + #region Constructors + + /// + /// Creates new instance of the object. + /// + public Background() { } + + /// + /// Creates new instance of the object. + /// + /// Start color. + public Background(Color color1) + { + _Color1 = color1; + } + + /// + /// Creates new instance of the object. + /// + /// Start color. + /// End color. + public Background(Color color1, Color color2) + { + _Color1 = color1; + _Color2 = color2; + } + + /// + /// Creates new instance of the object. + /// + /// Start color in hexadecimal representation like FFFFFF. + /// End color in hexadecimal representation like FFFFFF. + public Background(string color1, string color2) + { + _Color1 = ColorFactory.GetColor(color1); + _Color2 = ColorFactory.GetColor(color2); + } + + /// + /// Creates new instance of the object. + /// + /// Start color in 32-bit RGB representation. + /// End color in 32-bit RGB representation. + public Background(int color1, int color2) + { + _Color1 = ColorFactory.GetColor(color1); + _Color2 = ColorFactory.GetColor(color2); + } + + /// + /// Creates new instance of the object. + /// + /// Start color in 32-bit RGB representation. + /// End color in 32-bit RGB representation. + /// Gradient angle. + public Background(int color1, int color2, int gradientAngle) + { + _Color1 = ColorFactory.GetColor(color1); + _Color2 = ColorFactory.GetColor(color2); + + GradientAngle = gradientAngle; + } + + /// + /// Creates new instance of the object. + /// + /// Start color. + /// End color. + /// Gradient angle. + public Background(Color color1, Color color2, int gradientAngle) + { + _Color1 = color1; + _Color2 = color2; + + GradientAngle = gradientAngle; + } + + /// + /// Creates new instance of the object. + /// + /// Start color. + /// End color. + /// Gradient angle. + public Background(Color color1, Color color2, BackFillType fillType) + { + _Color1 = color1; + _Color2 = color2; + + _BackFillType = fillType; + } + + #endregion + + #region Public properties + + #region Color1 + + /// + /// Gets or sets the start color. + /// + [Description("Indicates the Starting Gradient Color.")] + public Color Color1 + { + get { return (_Color1); } + + set + { + if (_Color1 != value) + { + _Color1 = value; + + OnPropertyChangedEx("Color1"); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeColor1() + { + return (_Color1.IsEmpty == false); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetColor1() + { + _Color1 = Color.Empty; + } + + #endregion + + #region Color2 + + /// + /// Gets or sets the Ending Gradient Color + /// + [Description("Indicates the Ending Gradient Color")] + public Color Color2 + { + get { return (_Color2); } + + set + { + if (_Color2 != value) + { + _Color2 = value; + + OnPropertyChangedEx("Color2"); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeColor2() + { + return (_Color2.IsEmpty == false); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetColor2() + { + _Color2 = Color.Empty; + } + + #endregion + + #region BackColorBlend + + /// + /// Gets or sets the BackColorBlend. + /// + [Description("Indicates the BackColorBlend.")] + public BackColorBlend BackColorBlend + { + get + { + if (_BackColorBlend == null) + { + _BackColorBlend = new BackColorBlend(); + + UpgateChangeHandler(null, _BackColorBlend); + } + + return (_BackColorBlend); + } + + set + { + if (_BackColorBlend != value) + { + UpgateChangeHandler(_BackColorBlend, value); + + _BackColorBlend = value; + + OnPropertyChangedEx("BackColorBlend"); + } + } + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual bool ShouldSerializeBackColorBlend() + { + return (_BackColorBlend != null && _BackColorBlend.IsEmpty == false); + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + internal virtual void ResetBackColorBlend() + { + BackColorBlend = null; + } + + #endregion + + #region GradientAngle + + /// + /// Gets or sets the gradient angle (default is 90) + /// + [DefaultValue(90)] + [Description("Indicates the Gradient Angle default is 90)")] + public int GradientAngle + { + get { return (_GradientAngle); } + + set + { + if (_GradientAngle != value) + { + _GradientAngle = value; + + OnPropertyChangedEx("GradientAngle"); + } + } + } + + #endregion + + #region BackFillType + + /// + /// Gets or sets the Gradient BackFillType + /// + [DefaultValue(BackFillType.Angle)] + [Description("Indicates the Gradient BackFillType.")] + public BackFillType BackFillType + { + get { return (_BackFillType); } + + set + { + if (_BackFillType != value) + { + _BackFillType = value; + + OnPropertyChangedEx("BackFillType"); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether both colors assigned are empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + return (_Color1.IsEmpty && _Color2.IsEmpty && + (_BackColorBlend == null || _BackColorBlend.IsEmpty)); + } + } + + #endregion + + #region IsEqualTo + + /// + /// Determines if the Background is equal to the given one + /// + /// Background to compare + /// true if equal + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEqualTo(Background background) + { + return (_Color1 == background.Color1 && + _Color2 == background.Color2 && + _BackColorBlend.Equals(background._BackColorBlend) && + _GradientAngle == background.GradientAngle && + _BackFillType == background.BackFillType); + } + + #endregion + + #endregion + + #region GetBrush + + /// + /// GetBrush + /// + /// + /// + public Brush GetBrush(Rectangle r) + { + if (_BackColorBlend != null && _BackColorBlend.IsEmpty == false) + { + if (_BackColorBlend.Colors.Length == 1) + return (new SolidBrush(_BackColorBlend.Colors[0])); + + Brush br = GetLinearBrush(r); + + if (br is LinearGradientBrush) + { + ColorBlend cb = GetColorBlend(); + + if (cb != null) + ((LinearGradientBrush) br).InterpolationColors = cb; + } + + return (br); + } + + if (_Color2.IsEmpty == true) + return (new SolidBrush(_Color1)); + + return (GetLinearBrush(r)); + } + + #region GetLinearBrush + + private Brush GetLinearBrush(Rectangle r) + { + LinearGradientBrush lbr = null; + + if (r.Width > 0 && r.Height > 0) + { + switch (_BackFillType) + { + case BackFillType.Angle: + lbr = new LinearGradientBrush(r, _Color1, _Color2, _GradientAngle); + break; + + case BackFillType.HorizontalCenter: + r.Width /= 2; + r.Width = Math.Max(1, r.Width); + + lbr = new LinearGradientBrush(r, _Color1, _Color2, 0f); + break; + + case BackFillType.VerticalCenter: + r.Height /= 2; + r.Height = Math.Max(1, r.Height); + + lbr = new LinearGradientBrush(r, _Color1, _Color2, 90f); + break; + + case BackFillType.ForwardDiagonal: + lbr = new LinearGradientBrush(r, _Color1, _Color2, LinearGradientMode.ForwardDiagonal); + break; + + case BackFillType.BackwardDiagonal: + lbr = new LinearGradientBrush(r, _Color1, _Color2, LinearGradientMode.BackwardDiagonal); + break; + + case BackFillType.ForwardDiagonalCenter: + r.Width /= 2; + r.Height /= 2; + lbr = new LinearGradientBrush(r, _Color1, _Color2, LinearGradientMode.ForwardDiagonal); + break; + + case BackFillType.BackwardDiagonalCenter: + r.Width /= 2; + r.Height /= 2; + r.X += r.Width; + + lbr = new LinearGradientBrush(r, _Color1, _Color2, LinearGradientMode.BackwardDiagonal); + break; + + case BackFillType.Center: + using (GraphicsPath path = new GraphicsPath()) + { + path.AddRectangle(r); + + PathGradientBrush pbr = new PathGradientBrush(path); + + pbr.CenterColor = _Color1; + pbr.SurroundColors = new Color[] {_Color2}; + + ColorBlend cb = GetColorBlend(); + + if (cb != null) + pbr.InterpolationColors = cb; + + return (pbr); + } + + case BackFillType.Radial: + int n = (int) Math.Sqrt(r.Width*r.Width + r.Height*r.Height) + 4; + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(r.X - (n - r.Width)/2, r.Y - (n - r.Height)/2, n, n); + + PathGradientBrush pbr = new PathGradientBrush(path); + + pbr.CenterColor = _Color1; + pbr.SurroundColors = new Color[] {_Color2}; + + ColorBlend cb = GetColorBlend(); + + if (cb != null) + pbr.InterpolationColors = cb; + + return (pbr); + } + } + + if (lbr != null) + lbr.WrapMode = WrapMode.TileFlipXY; + } + + return (lbr); + } + + #endregion + + #region GetColorBlend + + private ColorBlend GetColorBlend() + { + if (_BackColorBlend != null && + _BackColorBlend.Colors != null && _BackColorBlend.Colors.Length > 0) + { + ColorBlend cb = new ColorBlend(_BackColorBlend.Colors.Length); + + cb.Colors = _BackColorBlend.Colors; + cb.Positions = GetPositions(); + + return (cb); + } + + return (null); + } + + #endregion + + #region GetPositions + + private float[] GetPositions() + { + float[] cp = _BackColorBlend.Positions; + + if (cp == null || cp.Length != _BackColorBlend.Colors.Length) + { + cp = new float[_BackColorBlend.Colors.Length]; + + float f = 1f / _BackColorBlend.Colors.Length; + + for (int i = 0; i < cp.Length; i++) + cp[i] = i * f; + + cp[_BackColorBlend.Colors.Length - 1] = 1; + } + + return (cp); + } + + #endregion + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the background. + /// + /// Copy of the background. + public Background Copy() + { + Background copy = new Background(); + + copy.Color1 = _Color1; + copy.Color2 = _Color2; + + copy.GradientAngle = _GradientAngle; + copy.BackFillType = _BackFillType; + + if (_BackColorBlend != null) + copy.BackColorBlend = _BackColorBlend.Copy(); + + return (copy); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(VisualPropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChangedEx(string s) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + { + VisualPropertyChangedEventArgs e = + new VisualPropertyChangedEventArgs(s); + + eh(this, e); + } + } + + #endregion + + #region UpgateChangeHandler + + private void UpgateChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// StyleChanged + /// + /// + /// + protected virtual void StyleChanged( + object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged((VisualPropertyChangedEventArgs)e); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + BackColorBlend = null; + } + + #endregion + } + + #region enums + + /// + /// BackFillType + /// + public enum BackFillType + { + /// + /// Angle + /// + Angle, + + /// + /// Center + /// + Center, + + /// + /// HorizontalCenter + /// + HorizontalCenter, + + /// + /// VerticalCenter + /// + VerticalCenter, + + /// + /// ForwardDiagonal + /// + ForwardDiagonal, + + /// + /// BackwardDiagonal + /// + BackwardDiagonal, + + /// + /// ForwardDiagonalCenter + /// + ForwardDiagonalCenter, + + /// + /// BackwardDiagonalCenter + /// + BackwardDiagonalCenter, + + /// + /// Radial + /// + Radial, + } + + #endregion + + #region BackgroundConvertor + + /// + /// BackgroundConvertor + /// + public class BackgroundConvertor : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + Background gc = value as Background; + + if (gc != null) + { + if (gc.BackColorBlend != null && gc.BackColorBlend.IsEmpty == false) + return ("Blended"); + + ColorConverter cvt = new ColorConverter(); + + string s = gc.Color1.IsEmpty ? "(Empty)" : cvt.ConvertToString(gc.Color1); + + if (gc.Color2 != Color.Empty) + s += ", " + cvt.ConvertToString(gc.Color2); + + return (s); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + + #region BackgroundEditor + + /// + /// BackgroundEditor + /// + public class BackgroundEditor : UITypeEditor + { + #region GetPaintValueSupported + + /// + /// GetPaintValueSupported + /// + /// + /// + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region PaintValue + + /// + /// PaintValue + /// + /// + public override void PaintValue(PaintValueEventArgs e) + { + Background b = e.Value as Background; + + if (b != null) + { + using (Brush br = b.GetBrush(e.Bounds)) + e.Graphics.FillRectangle(br, e.Bounds); + } + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BaseRowHeaderVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BaseRowHeaderVisualStyle.cs new file mode 100644 index 00000000..db01b4e0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BaseRowHeaderVisualStyle.cs @@ -0,0 +1,414 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Represents the visual style of a Row. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class BaseRowHeaderVisualStyle : BaseVisualStyle + { + #region Static data + + /// + /// Empty + /// + public static BaseRowHeaderVisualStyle Empty + { + get { return (new BaseRowHeaderVisualStyle()); } + } + + #endregion + + #region Private variables + + private Background _Background; + private Color _BorderHighlightColor = Color.Empty; + + private Font _Font; + private Color _TextColor = Color.Empty; + private Tbool _AllowWrap = Tbool.NotSet; + private Alignment _TextAlignment = Alignment.NotSet; + + #endregion + + #region Public properties + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Render); + } + } + } + + #endregion + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates whether the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region BorderHighlightColor + + /// + /// Gets or sets the border Highlight color. + /// + [Description("Indicates whether the border Highlight color")] + public Color BorderHighlightColor + { + get { return (_BorderHighlightColor); } + + set + { + if (_BorderHighlightColor != value) + { + _BorderHighlightColor = value; + + OnPropertyChangedEx("BorderHighlightColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderHighlightColor() + { + return (_BorderHighlightColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderHighlightColor() + { + _BorderHighlightColor = Color.Empty; + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font. + /// + [DefaultValue(null)] + [Description("Indicates the RowHeader Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// IsEmpty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool IsEmpty + { + get + { + return ((_Background == null || _Background.IsEmpty) && + _BorderHighlightColor == Color.Empty && + _Font == null && TextColor == Color.Empty && base.IsEmpty); + } + } + + #endregion + + #region TextAlignment + + /// + /// Gets or sets the alignment of the header text + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the header text.")] + public Alignment TextAlignment + { + get { return (_TextAlignment); } + + set + { + if (_TextAlignment != value) + { + _TextAlignment = value; + + OnPropertyChangedEx("TextAlignment", VisualChangeType.Render); + } + } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color + /// + [Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + _TextColor = Color.Empty; + } + + #endregion + + #endregion + + #region GetTextFormatFlags + + internal eTextFormat GetTextFormatFlags() + { + eTextFormat tf = eTextFormat.WordEllipsis | + eTextFormat.NoPadding | eTextFormat.NoPrefix; + + if (AllowWrap == Tbool.True) + tf |= eTextFormat.WordBreak; + + switch (TextAlignment) + { + case Alignment.TopCenter: + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.TopRight: + tf |= eTextFormat.Right; + break; + + case Alignment.MiddleLeft: + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.NotSet: + case Alignment.MiddleCenter: + tf |= eTextFormat.HorizontalCenter; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleRight: + tf |= eTextFormat.Right; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.BottomLeft: + tf |= eTextFormat.Bottom; + break; + + case Alignment.BottomCenter: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.BottomRight: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.Right; + break; + } + + return (tf); + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(BaseRowHeaderVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.Font != null) + _Font = style.Font; + + if (style.TextColor.IsEmpty == false) + _TextColor = style._TextColor; + + if (style.Background != null && style.Background.IsEmpty == false) + Background = style.Background.Copy(); + + if (style.BorderHighlightColor.IsEmpty == false) + BorderHighlightColor = style.BorderHighlightColor; + + if (style.AllowWrap != Tbool.NotSet) + _AllowWrap = style.AllowWrap; + + if (style.TextAlignment != Alignment.NotSet) + _TextAlignment = style.TextAlignment; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new BaseRowHeaderVisualStyle Copy() + { + BaseRowHeaderVisualStyle style = new BaseRowHeaderVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(BaseRowHeaderVisualStyle copy) + { + base.CopyTo(copy); + + if (_Font != null) + copy.Font = (Font)_Font.Clone(); + + if (_TextColor.IsEmpty == false) + copy.TextColor = _TextColor; + + copy.BorderHighlightColor = BorderHighlightColor; + + if (_Background != null) + copy.Background = _Background.Copy(); + + copy.TextAlignment = _TextAlignment; + copy.AllowWrap = _AllowWrap; + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BaseVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BaseVisualStyle.cs new file mode 100644 index 00000000..6326b2c8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BaseVisualStyle.cs @@ -0,0 +1,451 @@ +using System; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Represents the base visual style. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + public class BaseVisualStyle : INotifyPropertyChanged, IDisposable + { + #region Private variables + + private string _Class = ""; + private object _Tag; + + #endregion + + #region Public properties + + #region Class + + /// + /// Gets or sets the class style belongs to. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string Class + { + get { return (_Class); } + + set + { + if (_Class != value) + { + _Class = value; + + OnPropertyChangedEx("Class", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public virtual bool IsEmpty + { + get { return (_Tag == null); } + } + + #endregion + + #region Tag + + /// + /// Gets or sets the user defined reference Tag. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("User defined reference Tag.")] + public object Tag + { + get { return (_Tag); } + set { _Tag = value; } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(BaseVisualStyle style) + { + } + + #endregion + + #region GetApplyStyleTypes + + internal StyleType[] GetApplyStyleTypes(StyleType e) + { + StyleType[] css = null; + + switch (e) + { + case StyleType.Default: + css = new StyleType[] { StyleType.Default}; + break; + + case StyleType.Empty: + case StyleType.MouseOver: + case StyleType.ReadOnly: + case StyleType.Selected: + case StyleType.NotSelectable: + css = new StyleType[] { StyleType.Default, e }; + break; + + case StyleType.SelectedMouseOver: + css = new StyleType[] { StyleType.Default, StyleType.Selected, e }; + break; + + case StyleType.ReadOnlyMouseOver: + css = new StyleType[] { StyleType.Default, StyleType.ReadOnly, e }; + break; + + case StyleType.ReadOnlySelected: + css = new StyleType[] { StyleType.Default, StyleType.Selected, StyleType.ReadOnly, e }; + break; + + case StyleType.ReadOnlySelectedMouseOver: + css = new StyleType[] { StyleType.Default, StyleType.Selected, StyleType.ReadOnly, StyleType.ReadOnlySelected, e }; + break; + } + + return (css); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public BaseVisualStyle Copy() + { + BaseVisualStyle style = new BaseVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(BaseVisualStyle copy) + { + copy.Class = _Class; + copy.Tag = _Tag; + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s)); + } + + /// + /// Default PropertyChanged processing + /// + /// + /// invalidate + protected void OnPropertyChangedEx(string s, VisualChangeType changeType) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s, changeType)); + } + + #endregion + + #region UpdateChangeHandler + + /// + /// UpdateChangeHandler + /// + /// + /// + protected void UpdateChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= ValuePropertyChanged; + + if (newValue != null) + newValue.PropertyChanged += ValuePropertyChanged; + } + + void ValuePropertyChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public virtual void Dispose() + { + } + + #endregion + } + + #region enums + + #region Alignment + + /// + /// Alignment of the content + /// + public enum Alignment + { + /// + /// + NotSet = -1, + + /// + /// TopLeft + /// + TopLeft, + + /// + /// TopCenter + /// + TopCenter, + + /// + /// TopRight + /// + TopRight, + + /// + /// MiddleLeft + /// + MiddleLeft, + + /// + /// MiddleCenter + /// + MiddleCenter, + + /// + /// MiddleRight + /// + MiddleRight, + + /// + /// BottomLeft + /// + BottomLeft, + + /// + /// BottomCenter + /// + BottomCenter, + + /// + /// BottomRight + /// + BottomRight, + } + + #endregion + + #region BorderSide + + internal enum BorderSide + { + Top, + Left, + Bottom, + Right + } + + #endregion + + #region CellHighlightMode + + /// + /// Specifies the mode of cell highlighting + /// to employ when a grid cell is selected + /// + public enum CellHighlightMode + { + /// + /// No highlighting + /// + None, + + /// + /// Entire cell will be Highlighted + /// + Full, + + /// + /// Partial cell will be Highlighted + /// + Partial, + + /// + /// Cell content only will be Highlighted + /// + Content, + } + + #endregion + + #region ImageHighlightMode + + /// + /// ImageHighlightMode + /// + public enum ImageHighlightMode + { + /// + /// NotSet + /// + NotSet = -1, + + /// + /// Default + /// + Default, + + /// + /// Always + /// + Always, + + /// + /// Never + /// + Never, + } + + #endregion + + #region ImageOverlay + + /// + /// How to Overlay the Image with + /// respect to the content + /// + public enum ImageOverlay + { + /// + /// + NotSet = -1, + + /// + /// None + /// + None, + + /// + /// Top + /// + Top, + + /// + /// Bottom + /// + Bottom, + } + + #endregion + + #region Tbool + + /// + /// TBool - Three state boolean + /// + public enum Tbool + { + /// + /// NotSet + /// + NotSet, + + /// + /// True + /// + True, + + /// + /// False + /// + False + } + + #endregion + + #region VisualChangeType + + /// + /// Defines visual property change type. + /// + public enum VisualChangeType + { + /// + /// Visual style has changed so layout is impacted + /// + Layout, + + /// + /// Visual style has changed so visuals are impacted, but not layout + /// + Render + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BorderColor.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BorderColor.cs new file mode 100644 index 00000000..01a94aea --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BorderColor.cs @@ -0,0 +1,460 @@ +using System; +using System.Drawing; +using System.ComponentModel; +using System.Globalization; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Represents style border color. + /// + [TypeConverter(typeof(BorderColorConverter))] + public class BorderColor : INotifyPropertyChanged + { + #region Static data + + /// + /// Empty + /// + /// + /// Returns Empty instance of BorderColor. + /// + public static BorderColor Empty + { + get { return (new BorderColor()); } + } + + #endregion + + #region Private variables + + private Color _Top = Color.Empty; + private Color _Left = Color.Empty; + private Color _Bottom = Color.Empty; + private Color _Right = Color.Empty; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the BorderColor object. + /// + /// + /// + /// + /// + public BorderColor(Color left, Color top, Color right, Color bottom) + { + _Top = top; + _Bottom = bottom; + _Left = left; + _Right = right; + } + + /// + /// Initializes a new instance of the BorderColor object. + /// + public BorderColor(Color all) + : this(all, all, all, all) + { + } + + /// + /// Initializes a new instance of the BorderColor object. + /// + public BorderColor() + { + } + + #endregion + + #region Public properties + + #region All + + /// + /// Gets or sets the color of all borders. + /// + //[Browsable(false)] + //[EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Color All + { + set { _Top = _Left = _Bottom = _Right = value; } + } + + #endregion + + #region Bottom + + /// + /// Gets or sets the color of the bottom border + /// + [Category("Appearance")] + [Description("Indicates the color of the bottom border")] + public Color Bottom + { + get { return (_Bottom); } + + set + { + if (_Bottom != value) + { + _Bottom = value; + + OnVisualPropertyChanged("Bottom"); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBottom() + { + return (_Bottom.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBottom() + { + _Bottom = Color.Empty; + } + + #endregion + + #region Left + + /// + /// Gets or sets the color of the left border + /// + [Category("Appearance")] + [Description("Indicates the color of the left border")] + public Color Left + { + get { return (_Left); } + + set + { + if (_Left != value) + { + _Left = value; + + OnVisualPropertyChanged("Left"); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLeft() + { + return (_Left.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetLeft() + { + _Left = Color.Empty; + } + + #endregion + + #region Right + + /// + /// Gets or sets the color of the right border + /// + [Category("Appearance")] + [Description("Indicates the color of the right border")] + public Color Right + { + get { return (_Right); } + + set + { + if (_Right != value) + { + _Right = value; + + OnVisualPropertyChanged("Right"); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeRight() + { + return (_Right.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetRight() + { + _Right = Color.Empty; + } + + #endregion + + #region Top + + /// + /// Gets or sets the color of the top border + /// + [Category("Appearance")] + [Description("Indicates the color of the top border")] + public Color Top + { + get { return (_Top); } + + set + { + if (_Top != value) + { + _Top = value; + + OnVisualPropertyChanged("Top"); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeTop() + { + return (_Top.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetTop() + { + _Top = Color.Empty; + } + + #endregion + + #endregion + + #region Internal properties + + #region IsEmpty + + internal bool IsEmpty + { + get + { + return (_Left.IsEmpty && _Top.IsEmpty && + _Right.IsEmpty && _Bottom.IsEmpty); + } + } + + #endregion + + #region IsUniform + + internal bool IsUniform + { + get + { + return (_Left == _Top && + _Left == _Right && _Left == _Bottom); + } + } + + #endregion + + #endregion + + #region Operators + + #region '==' operator + + /// + /// Compares two instances. + /// + /// Instance 1 + /// Instance 2 + /// true if same + public static bool operator ==(BorderColor t1, BorderColor t2) + { + // If both are null, or both are same instance, return true. + + if (ReferenceEquals(t1, t2)) + return (true); + + // If one is null, but not both, return false. + + if (((object)t1 == null) || ((object)t2 == null)) + return (false); + + return (t1._Left == t2._Left && t1._Right == t2._Right && + t1._Top == t2._Top && t1._Bottom == t2._Bottom); + } + + #endregion + + #region "!=" operator + + /// + /// Compares two instances. + /// + /// Instance 1 + /// Instance 2 + /// true if different. + public static bool operator !=(BorderColor t1, BorderColor t2) + { + return ((t1 == t2) == false); + } + + #endregion + + #endregion + + #region GetHashCode + + /// + /// Returns hash-code for object. + /// + /// Hash-code value. + public override int GetHashCode() + { + return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^ + _Right.GetHashCode()) ^ _Bottom.GetHashCode()); + } + + #endregion + + #region Equals + + /// + /// Compares object to this instance. + /// + /// Object to compare. + /// true if same. + public override bool Equals(object obj) + { + if (obj is BorderColor) + return ((BorderColor) obj == this); + + return (false); + } + + /// + /// Compares object to this instance. + /// + /// Border color + /// true if same + public bool Equals(BorderColor borderColor) + { + return (this == borderColor); + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the BorderColor. + /// + /// Copy of the BorderColor. + public BorderColor Copy() + { + BorderColor copy = new BorderColor(_Left, _Top, _Right, _Bottom); + + return (copy); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnVisualPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new VisualPropertyChangedEventArgs(s)); + } + + #endregion + } + + #region BorderColorConverter + + /// + /// BorderColorConverter + /// + public class BorderColorConverter : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + return (String.Empty); + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BorderPattern.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BorderPattern.cs new file mode 100644 index 00000000..2185d553 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/BorderPattern.cs @@ -0,0 +1,418 @@ +using System; +using System.ComponentModel; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Defines Thickness class. + /// + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class BorderPattern : IEquatable, INotifyPropertyChanged + { + #region Static data + + /// + /// Returns Empty instance of BorderPattern. + /// + public static BorderPattern Empty + { + get { return (new BorderPattern()); } + } + + #endregion + + #region Private variables + + private LinePattern _Bottom = LinePattern.NotSet; + private LinePattern _Left = LinePattern.NotSet; + private LinePattern _Right = LinePattern.NotSet; + private LinePattern _Top = LinePattern.NotSet; + + #endregion + + #region Constructors + + /// + /// Creates new instance of the object. + /// + /// Left BorderPatternStyle. + /// Top BorderPatternStyle. + /// Right BorderPatternStyle. + /// Bottom BorderPatternStyle. + public BorderPattern(LinePattern left, + LinePattern top, LinePattern right, LinePattern bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + + PropertyChanged = null; + } + + /// + /// Creates new instance of the object. + /// + /// Specifies uniform Thickness. + public BorderPattern(LinePattern all) + : this(all, all, all, all) + { + } + + /// + /// Creates new instance of the object. + /// + public BorderPattern() + { + } + + #endregion + + #region Public properties + + #region All + + /// + /// Gets or sets the thickness of all sides. + /// + //[Browsable(false)] + //[EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public LinePattern All + { + set { _Top = _Left = _Bottom = _Right = value; } + } + + #endregion + + #region Bottom + + /// + /// Gets or sets the bottom Border Pattern + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the bottom Border Pattern")] + public LinePattern Bottom + { + get { return (_Bottom); } + + set + { + if (_Bottom != value) + { + _Bottom = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Bottom")); + } + } + } + + #endregion + + #region Left + + /// + /// Gets or sets the left Border Pattern + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the left Border Pattern")] + public LinePattern Left + { + get { return (_Left); } + + set + { + if (_Left != value) + { + _Left = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Left")); + } + } + } + + #endregion + + #region Right + + /// + /// Gets or sets the Right Border Pattern + /// + [DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Right Border Pattern")] + public LinePattern Right + { + get { return (_Right); } + + set + { + if (_Right != value) + { + _Right = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Right")); + } + } + } + + #endregion + + #region Top + + /// + /// Gets or sets the Top Border Pattern + /// + [Browsable(true), DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Top Border Pattern")] + public LinePattern Top + { + get { return (_Top); } + + set + { + if (_Top != value) + { + _Top = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Top")); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the item is empty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + return (_Left == LinePattern.NotSet && + _Right == LinePattern.NotSet && + _Top == LinePattern.NotSet && + _Bottom == LinePattern.NotSet); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region IsUniform + + internal bool IsUniform + { + get + { + return (_Left == _Top && + _Left == _Right && _Left == _Bottom); + } + } + + #endregion + + #endregion + + #region Equals + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to. + /// true if equal otherwise false. + public override bool Equals(object obj) + { + if (obj is BorderPattern) + return (this == (BorderPattern)obj); + + return (false); + } + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to + /// true if equal otherwise false + public bool Equals(BorderPattern borderPattern) + { + return (this == borderPattern); + } + + #endregion + + #region GetHashCode + + /// + /// Returns hash-code. + /// + /// hash-code + public override int GetHashCode() + { + return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^ + _Right.GetHashCode()) ^ _Bottom.GetHashCode()); + } + + #endregion + + #region Operators + + #region "==" operator + + /// + /// Implements == operator. + /// + /// Object 1 + /// Object 2 + /// true if equals + public static bool operator ==(BorderPattern t1, BorderPattern t2) + { + if (ReferenceEquals(t1, t2)) + return (true); + + if (((object)t1 == null) || ((object)t2 == null)) + return (false); + + return (t1._Left == t2._Left && t1._Right == t2._Right && + t1._Top == t2._Top && t1._Bottom == t2._Bottom); + } + + #endregion + + #region "!=" operator + + /// + /// Implements != operator + /// + /// Object 1 + /// Object 2 + /// true if different + public static bool operator !=(BorderPattern t1, BorderPattern t2) + { + return ((t1 == t2) == false); + } + + #endregion + + #endregion + + #region ApplyPattern + + /// + /// Applies the pattern to instance of this pattern. + /// + /// Pattern to apply. + public void ApplyPattern(BorderPattern pattern) + { + if (pattern != null) + { + if (pattern.Top != LinePattern.NotSet) + _Top = pattern.Top; + + if (pattern.Left != LinePattern.NotSet) + _Left = pattern.Left; + + if (pattern.Bottom != LinePattern.NotSet) + _Bottom = pattern.Bottom; + + if (pattern.Right != LinePattern.NotSet) + _Right = pattern.Right; + } + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the BorderPattern. + /// + /// Copy of the BorderPattern. + public BorderPattern Copy() + { + BorderPattern copy = new BorderPattern(_Left, _Top, _Right, _Bottom); + + return (copy); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + void OnPropertyChanged(VisualPropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + #endregion + } + + #region enums + + #region LinePattern + + /// + /// LinePattern + /// + public enum LinePattern + { + /// + /// None + /// + None = -2, + + /// + /// NotSet + /// + NotSet = -1, + + /// + /// Solid + /// + Solid = DashStyle.Solid, + + /// + /// Dash + /// + Dash = DashStyle.Dash, + + /// + /// Dot + /// + Dot = DashStyle.Dot, + + /// + /// DashDot + /// + DashDot = DashStyle.DashDot, + + /// + /// DashDotDot + /// + DashDotDot = DashStyle.DashDotDot, + } + + #endregion + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/CellVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/CellVisualStyle.cs new file mode 100644 index 00000000..3e0c0ac4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/CellVisualStyle.cs @@ -0,0 +1,898 @@ +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid.Primitives; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// CellVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class CellVisualStyles : VisualStyles + { + } + + /// + /// Represents the visual style of an element. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class CellVisualStyle : VisualStyle + { + #region Private variables + + private Tbool _AllowWrap = Tbool.NotSet; + private Tbool _AllowMultiLine = Tbool.NotSet; + private Alignment _Alignment = Alignment.NotSet; + + private Image _Image; + private int _ImageIndex = -1; + private Padding _ImagePadding; + private Alignment _ImageAlignment = Alignment.NotSet; + private ImageHighlightMode _ImageHighlightMode = ImageHighlightMode.NotSet; + private ImageOverlay _ImageOverlay = ImageOverlay.NotSet; + + private SymbolDef _SymbolDef; + + #endregion + + #region Public properties + + #region Alignment + + /// + /// Gets or sets the alignment of the content within the cell + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the content within the cell.")] + public Alignment Alignment + { + get { return (_Alignment); } + + set + { + if (_Alignment != value) + { + _Alignment = value; + + OnPropertyChangedEx("Alignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AllowMultiLine + + /// + /// Gets or sets whether multiple text lines (via "\r\n" inclusion) + /// are displayed when text wrapping (AllowWrap) is disabled. + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether multiple text lines (via '\r\n' inclusion) are displayed when text wrapping (AllowWrap) is disabled.")] + public Tbool AllowMultiLine + { + get { return (_AllowMultiLine); } + + set + { + if (_AllowMultiLine != value) + { + _AllowMultiLine = value; + + OnPropertyChangedEx("AllowMultiLine", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Image + + /// + /// Gets or sets the element Image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the element image")] + public Image Image + { + get { return (_Image); } + + set + { + if (_Image != value) + { + _Image = value; + + OnPropertyChangedEx("Image", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageAlignment + + /// + /// Gets or sets the alignment of the Image within the cell + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the Image within the cell.")] + public Alignment ImageAlignment + { + get { return (_ImageAlignment); } + + set + { + if (_ImageAlignment != value) + { + _ImageAlignment = value; + + OnPropertyChangedEx("ImageAlignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImageHighlightMode + + /// + /// Gets or sets how cell images are + /// highlighted when the cell is selected + /// + [DefaultValue(ImageHighlightMode.NotSet), Category("Style")] + [Description("Indicates how cell images are highlighted when the cell is selected")] + public ImageHighlightMode ImageHighlightMode + { + get { return (_ImageHighlightMode); } + + set + { + if (value != _ImageHighlightMode) + { + _ImageHighlightMode = value; + + OnPropertyChangedEx("ImageHighlightMode", VisualChangeType.Render); + } + } + } + + #endregion + + #region ImageIndex + + /// + /// Gets or sets the image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the image index")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int ImageIndex + { + get { return (_ImageIndex); } + + set + { + if (_ImageIndex != value) + { + _ImageIndex = value; + + OnPropertyChangedEx("ImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetImageIndex() + { + ImageIndex = -1; + } + + #endregion + + #region ImageOverlay + + /// + /// Gets or sets how to overlay the cell image with respect to cell content + /// + [DefaultValue(ImageOverlay.NotSet), Category("Appearance")] + [Description("Indicates how to overlay the cell image with respect to cell content.")] + public ImageOverlay ImageOverlay + { + get { return (_ImageOverlay); } + + set + { + if (_ImageOverlay != value) + { + _ImageOverlay = value; + + OnPropertyChangedEx("ImageOverlay", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ImagePadding + + /// + /// Gets or sets the spacing between content and edges of the Image + /// + [Description("Indicates the spacing between content and edges of the Image")] + public Padding ImagePadding + { + get + { + if (_ImagePadding == null) + { + _ImagePadding = Padding.Empty; + + UpdateChangeHandler(null, _ImagePadding); + } + + return (_ImagePadding); + } + + set + { + if (_ImagePadding != value) + { + UpdateChangeHandler(_ImagePadding, value); + + _ImagePadding = value; + + OnPropertyChangedEx("ImagePadding", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeImagePadding() + { + return (_ImagePadding != null && _ImagePadding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetImagePadding() + { + ImagePadding = null; + } + + #endregion + + #region SymbolDef + + /// + /// Gets or sets the element Symbol Definition. Note that + /// Symbol definition takes precedence over Image definition. + /// + [DefaultValue(null), Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Description("Indicates the element Symbol Definition. Note that Symbol definition takes precedence over Image definition.")] + public SymbolDef SymbolDef + { + get + { + if (_SymbolDef == null) + { + _SymbolDef = new SymbolDef(); + + UpdateChangeHandler(null, _SymbolDef); + } + + return (_SymbolDef); + } + + set + { + if (_SymbolDef != value) + { + UpdateChangeHandler(_SymbolDef, value); + + _SymbolDef = value; + + OnPropertyChangedEx("SymbolDef", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeSymbolDef() + { + return (_SymbolDef != null && _SymbolDef.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetSymbolDef() + { + SymbolDef = null; + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Alignment == Alignment.NotSet) && + (_AllowWrap == Tbool.NotSet) && + (_Image == null) && + (_ImageAlignment == Alignment.NotSet) && + (_ImageHighlightMode == ImageHighlightMode.NotSet) && + (_ImageIndex == -1) && + (_ImageOverlay == ImageOverlay.NotSet) && + (_ImagePadding == null || _ImagePadding.IsEmpty == true) && + + (base.IsEmpty == true)); + } + } + + #endregion + + #endregion + + #region Internal properties + + #region IsOverlayImage + + internal bool IsOverlayImage + { + get + { + return (_ImageOverlay == ImageOverlay.Top || + _ImageOverlay == ImageOverlay.Bottom); + } + } + + #endregion + + #region IsSymbolFigure + + internal bool IsSymbolFigure + { + get { return (_SymbolDef != null && _SymbolDef.IsValidSymbol == true); } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(CellVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.Alignment != Alignment.NotSet) + _Alignment = style.Alignment; + + if (style.AllowWrap != Tbool.NotSet) + _AllowWrap = style.AllowWrap; + + if (style.AllowMultiLine != Tbool.NotSet) + _AllowMultiLine = style.AllowMultiLine; + + if (style.ImageIndex >= 0) + { + _Image = null; + _ImageIndex = style.ImageIndex; + } + + if (style.Image != null) + { + _Image = style.Image; + _ImageIndex = -1; + } + + if (style.ImageAlignment != Alignment.NotSet) + _ImageAlignment = style.ImageAlignment; + + if (style.ImageHighlightMode != ImageHighlightMode.NotSet) + _ImageHighlightMode = style.ImageHighlightMode; + + if (style._ImagePadding != null && style._ImagePadding.IsEmpty == false) + _ImagePadding = style._ImagePadding.Copy(); + + if (style.ImageOverlay != ImageOverlay.NotSet) + _ImageOverlay = style.ImageOverlay; + + if (style._SymbolDef != null && style._SymbolDef.IsEmpty == false) + _SymbolDef = style._SymbolDef.Copy(); + } + } + + #endregion + + #region ApplyDefaults + + internal void ApplyDefaults() + { + if (_SymbolDef != null && _SymbolDef.IsValidSymbol == true) + { + if (_SymbolDef.SymbolSize == 0) + { + if (Font != null) + _SymbolDef.SymbolSize = Font.SizeInPoints; + } + + if (_SymbolDef.SymbolColor.IsEmpty == true) + { + _SymbolDef.SymbolColor = + (TextColor.IsEmpty == false) ? TextColor : Color.Black; + } + } + } + + #endregion + + #region GetTextFormatFlags + + internal virtual eTextFormat GetTextFormatFlags() + { + eTextFormat tf = eTextFormat.WordEllipsis | + eTextFormat.NoPadding | eTextFormat.NoPrefix; + + if (AllowWrap == Tbool.True) + { + tf |= eTextFormat.WordBreak; + } + else + { + if (AllowMultiLine != Tbool.True) + tf |= eTextFormat.SingleLine; + } + + switch (Alignment) + { + case Alignment.TopCenter: + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.TopRight: + tf |= eTextFormat.Right; + break; + + case Alignment.MiddleLeft: + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleCenter: + tf |= eTextFormat.HorizontalCenter; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleRight: + tf |= eTextFormat.Right; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.BottomLeft: + tf |= eTextFormat.Bottom; + break; + + case Alignment.BottomCenter: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.BottomRight: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.Right; + break; + } + + return (tf); + } + + #endregion + + #region IsValidFigure + + internal bool IsValidFigure(GridPanel panel) + { + if (IsSymbolFigure == true) + return (true); + + return (GetImage(panel) != null); + } + + #endregion + + #region GetFigure + + internal object GetFigure(GridPanel panel) + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + return (_SymbolDef); + + return (GetImage(panel)); + } + + #region GetImage + + private Image GetImage(GridPanel panel) + { + if (_Image != null) + return (_Image); + + if (_ImageIndex >= 0 && panel != null) + { + ImageList imageList = panel.ImageList; + + if (imageList != null && _ImageIndex < imageList.Images.Count) + return (imageList.Images[_ImageIndex]); + } + + return (null); + } + + #endregion + + #region GetSymbol + + private string GetSymbol() + { + if (_SymbolDef != null && _SymbolDef.IsEmpty == false) + return (_SymbolDef.SymbolRealized); + + return (null); + } + + #endregion + + #endregion + + #region GetFigureSize + + internal Size GetFigureSize(GridPanel panel) + { + Size size = GetFigureSizeEx(panel); + + if (size.IsEmpty == false) + { + size.Width += Dpi.Width(ImagePadding.Horizontal); + size.Height += Dpi.Height(ImagePadding.Vertical); + } + + return (size); + } + + internal Size GetFigureSizeEx(GridPanel panel) + { + Size size = Size.Empty; + + if (IsSymbolFigure == true) + { + size = _SymbolDef.GetSymbolSize(panel.SuperGrid); + } + else + { + Image image = GetImage(panel); + + if (image != null) + size = Dpi.Size(image.Size); + } + + return (size); + } + + #endregion + + #region GetFigureBounds + + internal Rectangle GetFigureBounds(GridPanel panel, Rectangle r) + { + Size size = GetFigureSize(panel); + + return (GetSizeBounds(panel, r, size)); + } + + #region GetSizeBounds + + private Rectangle GetSizeBounds(GridPanel panel, Rectangle r, Size size) + { + bool overlay = IsOverlayImage; + + switch (ImageAlignment) + { + case Alignment.TopLeft: + if (overlay == false) + r.X -= size.Width; + break; + + case Alignment.NotSet: + case Alignment.MiddleLeft: + if (overlay == false) + r.X -= size.Width; + + r.Y += (r.Height - size.Height) / 2; + break; + + case Alignment.BottomLeft: + if (overlay == false) + r.X -= size.Width; + + r.Y = r.Bottom - size.Height; + break; + + case Alignment.TopCenter: + r.X += (r.Width - size.Width) / 2; + + if (overlay == false) + r.Y -= size.Height; + break; + + case Alignment.MiddleCenter: + r.X += (r.Width - size.Width) / 2; + r.Y += (r.Height - size.Height) / 2; + break; + + case Alignment.BottomCenter: + r.X += (r.Width - size.Width) / 2; + r.Y = r.Bottom; + + if (overlay == true) + r.Y -= size.Height; + break; + + case Alignment.TopRight: + r.X = r.Right; + + if (overlay == true) + r.X -= size.Width; + break; + + case Alignment.MiddleRight: + r.X = r.Right; + + if (overlay == true) + r.X -= size.Width; + + r.Y += (r.Height - size.Height) / 2; + + break; + + case Alignment.BottomRight: + r.X = r.Right; + r.Y = r.Bottom - size.Height; + + if (overlay == true) + r.X -= size.Width; + break; + } + + r.Size = GetFigureSizeEx(panel); + + r.X += ImagePadding.Left; + r.Y += ImagePadding.Top; + + return (r); + } + + #endregion + + #endregion + + #region GetNonFigureBounds + + internal Rectangle GetNonFigureBounds(GridPanel panel, Rectangle r) + { + object figure = GetFigure(panel); + + if (figure != null) + { + if (IsOverlayImage == false) + { + Size size = GetFigureSize(panel); + + switch (ImageAlignment) + { + case Alignment.TopCenter: + r.Y += size.Height; + r.Height -= size.Height; + break; + + case Alignment.MiddleCenter: + break; + + case Alignment.BottomCenter: + r.Height -= size.Height; + break; + + case Alignment.TopRight: + case Alignment.MiddleRight: + case Alignment.BottomRight: + r.Width -= size.Width; + break; + + default: + r.X += size.Width; + r.Width -= size.Width; + break; + } + } + } + + return (r); + } + + #endregion + + #region RenderFigure + + internal void RenderFigure(Graphics g, GridPanel panel, Rectangle r) + { + RenderFigure(g, GetFigure(panel), r); + } + + internal void RenderFigure(Graphics g, object figure, Rectangle r) + { + if (r.Width > 0 && r.Height > 0) + { + if (figure is Image) + { + g.DrawImageUnscaledAndClipped((Image)figure, r); + } + else if (figure is SymbolDef) + { + SymbolDef sd = (SymbolDef)figure; + + using (Brush br = new SolidBrush(sd.SymbolColor)) + g.DrawString(sd.SymbolRealized, sd.SymbolFont, br, r); + } + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new CellVisualStyle Copy() + { + CellVisualStyle style = new CellVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(CellVisualStyle style) + { + base.CopyTo(style); + + style.Alignment = _Alignment; + style.AllowWrap = _AllowWrap; + style.AllowMultiLine = _AllowMultiLine; + + style.Image = _Image; + style.ImageAlignment = _ImageAlignment; + style.ImageHighlightMode = _ImageHighlightMode; + style.ImageIndex = _ImageIndex; + style.ImageOverlay = _ImageOverlay; + style.ImagePadding = (_ImagePadding != null) ? _ImagePadding.Copy() : null; + + style.SymbolDef = (_SymbolDef != null) ? _SymbolDef.Copy() : null; + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + ImagePadding = null; + SymbolDef = null; + + base.Dispose(); + } + + #endregion + } + + #region VisualPropertyChangedEventArgs + + /// + /// Represents visual property changed event arguments. + /// + public class VisualPropertyChangedEventArgs : PropertyChangedEventArgs + { + #region Public data + + /// + /// Gets the change type. + /// + public readonly VisualChangeType ChangeType; + + #endregion + + /// + /// Initializes a new instance of the VisualPropertyChangedEventArgs class. + /// + public VisualPropertyChangedEventArgs(string propertyName) + : base(propertyName) + { + ChangeType = VisualChangeType.Layout; + } + + /// + /// Initializes a new instance of the VisualPropertyChangedEventArgs class. + /// + public VisualPropertyChangedEventArgs(string propertyName, VisualChangeType changeType) + : base(propertyName) + { + ChangeType = changeType; + } + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/ColumnHeaderRowStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/ColumnHeaderRowStyle.cs new file mode 100644 index 00000000..b5593f3e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/ColumnHeaderRowStyle.cs @@ -0,0 +1,457 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// ColumnHeaderRowVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ColumnHeaderRowVisualStyles : VisualStyles + { + } + + /// + /// ColumnHeaderRowVisualStyle + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class ColumnHeaderRowVisualStyle : BaseVisualStyle + { + #region Private variables + + private Color _FilterBorderColor = Color.Empty; + private Color _IndicatorBorderColor = Color.Empty; + private Color _SortIndicatorColor = Color.Empty; + + private Background _FilterBackground; + private Background _IndicatorBackground; + private Background _WhiteSpaceBackground; + + private BaseRowHeaderVisualStyle _RowHeaderStyle; + + #endregion + + #region Public properties + + #region FilterBackground + + /// + /// Gets or sets the filter indicator background + /// + [Description("Indicates the RowHeader indicator background.")] + public Background FilterBackground + { + get + { + if (_FilterBackground == null) + { + _FilterBackground = Background.Empty; + + UpdateChangeHandler(null, _FilterBackground); + } + + return (_FilterBackground); + } + + set + { + if (_FilterBackground != value) + { + UpdateChangeHandler(_FilterBackground, value); + + _FilterBackground = value; + + OnPropertyChangedEx("FilterBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeFilterBackground() + { + return (_FilterBackground != null && + _FilterBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetFilterBackground() + { + FilterBackground = null; + } + + #endregion + + #region FilterBorderColor + + /// + /// Gets or sets the Filter border color + /// + [Description("Indicates the Filter border color")] + public Color FilterBorderColor + { + get { return (_FilterBorderColor); } + + set + { + if (_FilterBorderColor != value) + { + _FilterBorderColor = value; + + OnPropertyChangedEx("FilterBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeFilterBorderColor() + { + return (_FilterBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetFilterBorderColor() + { + _FilterBorderColor = Color.Empty; + } + + #endregion + + #region IndicatorBackground + + /// + /// Gets or sets the RowHeader indicator background + /// + [Description("Indicates the RowHeader indicator background.")] + public Background IndicatorBackground + { + get + { + if (_IndicatorBackground == null) + { + _IndicatorBackground = Background.Empty; + + UpdateChangeHandler(null, _IndicatorBackground); + } + + return (_IndicatorBackground); + } + + set + { + if (_IndicatorBackground != value) + { + UpdateChangeHandler(_IndicatorBackground, value); + + _IndicatorBackground = value; + + OnPropertyChangedEx("IndicatorBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeIndicatorBackground() + { + return (_IndicatorBackground != null && + _IndicatorBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetIndicatorBackground() + { + IndicatorBackground = null; + } + + #endregion + + #region IndicatorBorderColor + + /// + /// Gets or sets the RowHeader indicator border color + /// + [Description("Indicates the RowHeader indicator border color")] + public Color IndicatorBorderColor + { + get { return (_IndicatorBorderColor); } + + set + { + if (_IndicatorBorderColor != value) + { + _IndicatorBorderColor = value; + + OnPropertyChangedEx("IndicatorBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeIndicatorBorderColor() + { + return (_IndicatorBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetIndicatorBorderColor() + { + _IndicatorBorderColor = Color.Empty; + } + + #endregion + + #region RowHeader + + /// + /// Gets or sets the visual style of the ColumnHeader RowHeader + /// + [Description("Indicates the visual style of the ColumnHeader RowHeader.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public BaseRowHeaderVisualStyle RowHeader + { + get + { + if (_RowHeaderStyle == null) + { + _RowHeaderStyle = BaseRowHeaderVisualStyle.Empty; + + UpdateChangeHandler(null, _RowHeaderStyle); + } + + return (_RowHeaderStyle); + } + + set + { + if (_RowHeaderStyle != value) + { + UpdateChangeHandler(_RowHeaderStyle, value); + + _RowHeaderStyle = value; + + OnPropertyChangedEx("RowHeader", VisualChangeType.Render); + } + } + } + + #endregion + + #region SortIndicatorColor + + /// + /// Gets or sets the Sort indicator color + /// + [Description("Indicates the Sort indicator color")] + public Color SortIndicatorColor + { + get { return (_SortIndicatorColor); } + + set + { + if (_SortIndicatorColor != value) + { + _SortIndicatorColor = value; + + OnPropertyChangedEx("SortIndicatorColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeSortIndicatorColor() + { + return (_SortIndicatorColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetSortIndicatorColor() + { + _SortIndicatorColor = Color.Empty; + } + + #endregion + + #region WhiteSpaceBackground + + /// + /// Gets or sets the WhiteSpace Background + /// + [Description("Indicates the WhiteSpace Background")] + public Background WhiteSpaceBackground + { + get + { + if (_WhiteSpaceBackground == null) + { + _WhiteSpaceBackground = Background.Empty; + + UpdateChangeHandler(null, _WhiteSpaceBackground); + } + + return (_WhiteSpaceBackground); + } + + set + { + if (_WhiteSpaceBackground != value) + { + UpdateChangeHandler(_WhiteSpaceBackground, value); + + _WhiteSpaceBackground = value; + + OnPropertyChangedEx("WhiteSpaceBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeWhiteSpaceBackground() + { + return (_WhiteSpaceBackground != null && + _WhiteSpaceBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetWhiteSpaceBackground() + { + WhiteSpaceBackground = null; + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(ColumnHeaderRowVisualStyle style) + { + if (style != null) + { + RowHeader.ApplyStyle(style.RowHeader); + + if (style._FilterBackground != null && style._FilterBackground.IsEmpty == false) + FilterBackground = style._FilterBackground.Copy(); + + if (style._FilterBorderColor.IsEmpty == false) + FilterBorderColor = style._FilterBorderColor; + + if (style._IndicatorBackground != null && style.IndicatorBackground.IsEmpty == false) + IndicatorBackground = style._IndicatorBackground.Copy(); + + if (style._IndicatorBorderColor.IsEmpty == false) + IndicatorBorderColor = style._IndicatorBorderColor; + + if (style._SortIndicatorColor.IsEmpty == false) + SortIndicatorColor = style._SortIndicatorColor; + + if (style._WhiteSpaceBackground != null && style._WhiteSpaceBackground.IsEmpty == false) + WhiteSpaceBackground = style._WhiteSpaceBackground.Copy(); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ColumnHeaderRowVisualStyle Copy() + { + ColumnHeaderRowVisualStyle copy = new ColumnHeaderRowVisualStyle(); + + CopyTo(copy); + + return (copy); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(ColumnHeaderRowVisualStyle copy) + { + base.CopyTo(copy); + + if (_RowHeaderStyle != null) + copy.RowHeader = _RowHeaderStyle.Copy(); + + if (_FilterBackground != null) + copy.FilterBackground = _FilterBackground.Copy(); + + if (_IndicatorBackground != null) + copy.IndicatorBackground = _IndicatorBackground.Copy(); + + copy.FilterBorderColor = _FilterBorderColor; + copy.IndicatorBorderColor = _IndicatorBorderColor; + copy.SortIndicatorColor = _SortIndicatorColor; + + if (_WhiteSpaceBackground != null) + copy.WhiteSpaceBackground = _WhiteSpaceBackground.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + IndicatorBackground = null; + RowHeader = null; + WhiteSpaceBackground = null; + FilterBackground = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/ColumnHeaderVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/ColumnHeaderVisualStyle.cs new file mode 100644 index 00000000..f8116578 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/ColumnHeaderVisualStyle.cs @@ -0,0 +1,81 @@ +using System.ComponentModel; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// ColumnHeaderVisualStyles + /// + public class ColumnHeaderVisualStyles : VisualStyles + { + #region Hidden properties + + #region Empty + + /// + /// Empty + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new ColumnHeaderVisualStyle Empty + { + get { return (base.Empty); } + } + + #endregion + + #region NotSelectable + + /// + /// NotSelectable + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new ColumnHeaderVisualStyle NotSelectable + { + get { return (base.NotSelectable); } + } + + #endregion + + #endregion + } + + /// + /// ColumnHeaderVisualStyle + /// + [TypeConverter(typeof(ExpandableObjectConverter))] + public class ColumnHeaderVisualStyle : CellVisualStyle + { + #region GetTextFormatFlags + + internal override eTextFormat GetTextFormatFlags() + { + eTextFormat tf = base.GetTextFormatFlags(); + + tf &= ~eTextFormat.SingleLine; + + return (tf); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new ColumnHeaderVisualStyle Copy() + { + ColumnHeaderVisualStyle style = new ColumnHeaderVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/DefaultVisualStyles.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/DefaultVisualStyles.cs new file mode 100644 index 00000000..3603ac09 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/DefaultVisualStyles.cs @@ -0,0 +1,696 @@ +using System; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Defines set of default visual styles that are defined on the container control. + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class DefaultVisualStyles : INotifyPropertyChanged, IDisposable + { + #region Private variables + + private CellVisualStyles _CellStyles; + private CellVisualStyles _MergedCellStyles; + private CellVisualStyles _AlternateRowCellStyles; + private CellVisualStyles _AlternateColumnCellStyles; + + private ColumnHeaderVisualStyles _ColumnHeaderStyles; + private ColumnHeaderRowVisualStyles _ColumnHeaderRowStyles; + + private RowVisualStyles _RowStyles; + private GroupHeaderVisualStyles _GroupHeaderStyles; + + private TextRowVisualStyles _CaptionStyles; + private TextRowVisualStyles _TitleStyles; + private TextRowVisualStyles _HeaderStyles; + private TextRowVisualStyles _FooterStyles; + private GroupByVisualStyles _GroupByStyles; + private GridPanelVisualStyle _GridPanelStyle; + + private FilterRowVisualStyles _FilterRowStyles; + private FilterColumnHeaderVisualStyles _FilterColumnHeaderStyles; + + #endregion + + #region Public properties + + #region AlternateColumnCellStyles + + /// + /// Gets or sets the visual styles to be used on + /// alternating columns (UseAlternateColumnStyle must be enabled) + /// + [Category("Style")] + [Description("Indicates the visual styles to be used on alternating columns (UseAlternateColumnStyle must be enabled)")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CellVisualStyles AlternateColumnCellStyles + { + get + { + if (_AlternateColumnCellStyles == null) + { + _AlternateColumnCellStyles = new CellVisualStyles(); + + StyleChangeHandler(null, _AlternateColumnCellStyles); + } + + return (_AlternateColumnCellStyles); + } + + set + { + if (_AlternateColumnCellStyles != value) + { + CellVisualStyles oldValue = _AlternateColumnCellStyles; + _AlternateColumnCellStyles = value; + + OnStyleChanged("AlternateColumnCellStyles", oldValue, value); + } + } + } + + #endregion + + #region AlternateRowCellStyles + + /// + /// Gets or sets the visual styles to be used on + /// alternating rows (UseAlternateRowStyle must be enabled) + /// + [Category("Style")] + [Description("Indicates Gets or sets the visual styles to be used on alternating rows (UseAlternateRowStyle must be enabled)")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CellVisualStyles AlternateRowCellStyles + { + get + { + if (_AlternateRowCellStyles == null) + { + _AlternateRowCellStyles = new CellVisualStyles(); + + StyleChangeHandler(null, _AlternateRowCellStyles); + } + + return (_AlternateRowCellStyles); + } + + set + { + if (_AlternateRowCellStyles != value) + { + CellVisualStyles oldValue = _AlternateRowCellStyles; + _AlternateRowCellStyles = value; + + OnStyleChanged("AltRowVisualStyles", oldValue, value); + } + } + } + + #endregion + + #region CaptionStyles + + /// + /// Gets or sets the visual styles to be used for the grid Caption + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid Caption")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TextRowVisualStyles CaptionStyles + { + get + { + if (_CaptionStyles == null) + { + _CaptionStyles = new TextRowVisualStyles(); + + StyleChangeHandler(null, _CaptionStyles); + } + + return (_CaptionStyles); + } + + set + { + if (_CaptionStyles != value) + { + TextRowVisualStyles oldValue = _CaptionStyles; + _CaptionStyles = value; + + OnStyleChanged("CaptionStyles", oldValue, value); + } + } + } + + #endregion + + #region CellStyles + + /// + /// Gets or sets visual styles to be used for the grid Cells + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid Cells")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CellVisualStyles CellStyles + { + get + { + if (_CellStyles == null) + { + _CellStyles = new CellVisualStyles(); + + StyleChangeHandler(null, _CellStyles); + } + + return (_CellStyles); + } + + set + { + if (_CellStyles != value) + { + CellVisualStyles oldValue = _CellStyles; + _CellStyles = value; + + OnStyleChanged("CellStyles", oldValue, value); + } + } + } + + #endregion + + #region ColumnHeaderStyles + + /// + /// Gets or sets visual styles to be used for the grid ColumnHeader + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid ColumnHeader")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ColumnHeaderVisualStyles ColumnHeaderStyles + { + get + { + if (_ColumnHeaderStyles == null) + { + _ColumnHeaderStyles = new ColumnHeaderVisualStyles(); + + StyleChangeHandler(null, _ColumnHeaderStyles); + } + + return (_ColumnHeaderStyles); + } + + set + { + if (_ColumnHeaderStyles != value) + { + ColumnHeaderVisualStyles oldValue = _ColumnHeaderStyles; + _ColumnHeaderStyles = value; + + OnStyleChanged("ColumnHeaderStyles", oldValue, value); + } + } + } + + #endregion + + #region ColumnHeaderRowStyles + + /// + /// Gets or sets visual styles + /// to be used for the grid ColumnHeader Row + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid ColumnHeader Row")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ColumnHeaderRowVisualStyles ColumnHeaderRowStyles + { + get + { + if (_ColumnHeaderRowStyles == null) + { + _ColumnHeaderRowStyles = new ColumnHeaderRowVisualStyles(); + + StyleChangeHandler(null, _ColumnHeaderRowStyles); + } + + return (_ColumnHeaderRowStyles); + } + + set + { + if (_ColumnHeaderRowStyles != value) + { + ColumnHeaderRowVisualStyles oldValue = _ColumnHeaderRowStyles; + _ColumnHeaderRowStyles = value; + + OnStyleChanged("ColumnHeaderRowStyles", oldValue, value); + } + } + } + + #endregion + + #region FilterRowStyles + + /// + /// Gets or sets visual styles to + /// be used for the grid Filter column headers + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid Filter column headers.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public FilterColumnHeaderVisualStyles FilterColumnHeaderStyles + { + get + { + if (_FilterColumnHeaderStyles == null) + { + _FilterColumnHeaderStyles = new FilterColumnHeaderVisualStyles(); + + StyleChangeHandler(null, _FilterColumnHeaderStyles); + } + + return (_FilterColumnHeaderStyles); + } + + set + { + if (_FilterColumnHeaderStyles != value) + { + FilterColumnHeaderVisualStyles oldValue = _FilterColumnHeaderStyles; + _FilterColumnHeaderStyles = value; + + OnStyleChanged("FilterColumnHeaderStyles", oldValue, value); + } + } + } + + #endregion + + #region FilterRowStyles + + /// + /// Gets or sets visual styles to be used for the grid Filter Row + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid Filter Row")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public FilterRowVisualStyles FilterRowStyles + { + get + { + if (_FilterRowStyles == null) + { + _FilterRowStyles = new FilterRowVisualStyles(); + + StyleChangeHandler(null, _FilterRowStyles); + } + + return (_FilterRowStyles); + } + + set + { + if (_FilterRowStyles != value) + { + FilterRowVisualStyles oldValue = _FilterRowStyles; + _FilterRowStyles = value; + + OnStyleChanged("FilterRowStyles", oldValue, value); + } + } + } + + #endregion + + #region FooterStyles + + /// + /// Gets or sets the visual styles to be used for the grid Footer + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid Footer")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TextRowVisualStyles FooterStyles + { + get + { + if (_FooterStyles == null) + { + _FooterStyles = new TextRowVisualStyles(); + + StyleChangeHandler(null, _FooterStyles); + } + + return (_FooterStyles); + } + + set + { + if (_FooterStyles != value) + { + TextRowVisualStyles oldValue = _FooterStyles; + _FooterStyles = value; + + OnStyleChanged("FooterStyles", oldValue, value); + } + } + } + + #endregion + + #region GridPanelStyle + + /// + /// Gets or sets the visual styles to be used for the main grid panel + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the main grid panel")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridPanelVisualStyle GridPanelStyle + { + get + { + if (_GridPanelStyle == null) + { + _GridPanelStyle = new GridPanelVisualStyle(); + + StyleChangeHandler(null, _GridPanelStyle); + } + + return (_GridPanelStyle); + } + + set + { + if (_GridPanelStyle != value) + { + GridPanelVisualStyle oldValue = _GridPanelStyle; + _GridPanelStyle = value; + + OnStyleChanged("GridPanelStyle", oldValue, value); + } + } + } + + #endregion + + #region GroupByStyles + + /// + /// Gets or sets the visual styles to be used for the grid GroupBy Row + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid GroupBy Row")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GroupByVisualStyles GroupByStyles + { + get + { + if (_GroupByStyles == null) + { + _GroupByStyles = new GroupByVisualStyles(); + + StyleChangeHandler(null, _GroupByStyles); + } + + return (_GroupByStyles); + } + + set + { + if (_GroupByStyles != value) + { + GroupByVisualStyles oldValue = _GroupByStyles; + _GroupByStyles = value; + + OnStyleChanged("GroupByStyles", oldValue, value); + } + } + } + + #endregion + + #region GroupHeaderStyles + + /// + /// Gets or sets the visual styles to be used for the Group Header + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the Group Header")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GroupHeaderVisualStyles GroupHeaderStyles + { + get + { + if (_GroupHeaderStyles == null) + { + _GroupHeaderStyles = new GroupHeaderVisualStyles(); + + StyleChangeHandler(null, _GroupHeaderStyles); + } + + return (_GroupHeaderStyles); + } + + set + { + if (_GroupHeaderStyles != value) + { + GroupHeaderVisualStyles oldValue = _GroupHeaderStyles; + _GroupHeaderStyles = value; + + OnStyleChanged("GroupHeaderStyles", oldValue, value); + } + } + } + + #endregion + + #region HeaderStyles + + /// + /// Gets or sets the visual styles to be used for the grid Header + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid Header")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TextRowVisualStyles HeaderStyles + { + get + { + if (_HeaderStyles == null) + { + _HeaderStyles = new TextRowVisualStyles(); + + StyleChangeHandler(null, _HeaderStyles); + } + + return (_HeaderStyles); + } + + set + { + if (_HeaderStyles != value) + { + TextRowVisualStyles oldValue = _HeaderStyles; + _HeaderStyles = value; + + OnStyleChanged("HeaderStyles", oldValue, value); + } + } + } + + #endregion + + #region MergedCellStyles + + /// + /// Gets or sets visual styles to be used for merged grid Cells + /// + [Category("Style")] + [Description("Indicates visual styles to be used for merged grid Cells")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public CellVisualStyles MergedCellStyles + { + get + { + if (_MergedCellStyles == null) + { + _MergedCellStyles = new CellVisualStyles(); + + StyleChangeHandler(null, _MergedCellStyles); + } + + return (_MergedCellStyles); + } + + set + { + if (_MergedCellStyles != value) + { + CellVisualStyles oldValue = _MergedCellStyles; + _MergedCellStyles = value; + + OnStyleChanged("MergedCellStyles", oldValue, value); + } + } + } + + #endregion + + #region RowStyles + + /// + /// Gets or sets the visual styles to be used for the grid rows + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid rows")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public RowVisualStyles RowStyles + { + get + { + if (_RowStyles == null) + { + _RowStyles = new RowVisualStyles(); + + StyleChangeHandler(null, _RowStyles); + } + + return (_RowStyles); + } + + set + { + if (_RowStyles != value) + { + RowVisualStyles oldValue = _RowStyles; + _RowStyles = value; + + OnStyleChanged("RowStyles", oldValue, value); + } + } + } + + #endregion + + #region TitleStyles + + /// + /// Gets or sets the visual styles to be used for the grid Title + /// + [Category("Style")] + [Description("Indicates visual styles to be used for the grid Title")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TextRowVisualStyles TitleStyles + { + get + { + if (_TitleStyles == null) + { + _TitleStyles = new TextRowVisualStyles(); + + StyleChangeHandler(null, _TitleStyles); + } + + return (_TitleStyles); + } + + set + { + if (_TitleStyles != value) + { + TextRowVisualStyles oldValue = _TitleStyles; + _TitleStyles = value; + + OnStyleChanged("TitleStyles", oldValue, value); + } + } + } + + #endregion + + #endregion + + #region OnStyleChanged + + private void OnStyleChanged(string property, + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + StyleChangeHandler(oldValue, newValue); + + OnPropertyChanged(new VisualPropertyChangedEventArgs(property)); + } + + #endregion + + #region StyleChangeHandler + + private void StyleChangeHandler( + INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + AlternateColumnCellStyles = null; + AlternateRowCellStyles = null; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/FilterColumnHeaderVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/FilterColumnHeaderVisualStyle.cs new file mode 100644 index 00000000..f0b8aa3d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/FilterColumnHeaderVisualStyle.cs @@ -0,0 +1,572 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// FilterColumnHeaderVisualStyle + /// + public class FilterColumnHeaderVisualStyles : VisualStyles + { + } + + /// + /// FilterRowVisualStyle + /// + [TypeConverter(typeof(ExpandableObjectConverter))] + public class FilterColumnHeaderVisualStyle : BaseVisualStyle + { + #region Private variables + + private Tbool _AllowWrap = Tbool.NotSet; + private Alignment _Alignment = Alignment.NotSet; + + private Background _Background; + private Background _ErrorBackground; + private Background _GripBarBackground; + + private Color _TextColor = Color.Empty; + private Color _ErrorTextColor = Color.Empty; + + private Font _Font; + + private Padding _Margin; + + #endregion + + #region Public properties + + #region Alignment + + /// + /// Gets or sets the content alignment + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the content alignment.")] + public Alignment Alignment + { + get { return (_Alignment); } + + set + { + if (_Alignment != value) + { + _Alignment = value; + + OnPropertyChangedEx("Alignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region ErrorBackground + + /// + /// Gets or sets the style error background. + /// + [Description("Indicates the style error background")] + public Background ErrorBackground + { + get + { + if (_Background == null) + { + _ErrorBackground = Background.Empty; + + UpdateChangeHandler(null, _ErrorBackground); + } + + return (_ErrorBackground); + } + + set + { + if (_ErrorBackground != value) + { + UpdateChangeHandler(_ErrorBackground, value); + + _ErrorBackground = value; + + OnPropertyChangedEx("ErrorBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeErrorBackground() + { + return (_ErrorBackground != null && _ErrorBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetErrorBackground() + { + ErrorBackground = null; + } + + #endregion + + #region ErrorTextColor + + /// + /// Gets or sets the error Text color + /// + [Description("Indicates the error Text color")] + public Color ErrorTextColor + { + get { return (_ErrorTextColor); } + + set + { + if (_ErrorTextColor != value) + { + _ErrorTextColor = value; + + OnPropertyChangedEx("ErrorTextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeErrorTextColor() + { + return (_ErrorTextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetErrorTextColor() + { + _ErrorTextColor = Color.Empty; + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font + /// + [DefaultValue(null)] + [Description("Indicates the style Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region GripBarBackground + + /// + /// Gets or sets the GripBar style background. + /// + [Description("Indicates the GripBar style background")] + public Background GripBarBackground + { + get + { + if (_GripBarBackground == null) + { + _GripBarBackground = Background.Empty; + + UpdateChangeHandler(null, _GripBarBackground); + } + + return (_GripBarBackground); + } + + set + { + if (_GripBarBackground != value) + { + UpdateChangeHandler(_GripBarBackground, value); + + _GripBarBackground = value; + + OnPropertyChangedEx("GripBarBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeGripBarBackground() + { + return (_GripBarBackground != null && _GripBarBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetGripBarBackground() + { + GripBarBackground = null; + } + + #endregion + + #region Margin + + /// + /// Gets or sets the spacing between the border and outside content. + /// + [Description("Indicates the spacing between the border and outside content")] + public Padding Margin + { + get + { + if (_Margin == null) + { + _Margin = Padding.Empty; + + UpdateChangeHandler(null, _Margin); + } + + return (_Margin); + } + + set + { + if (_Margin != value) + { + UpdateChangeHandler(_Margin, value); + + _Margin = value; + + OnPropertyChangedEx("Margin", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeMargin() + { + return (_Margin != null && _Margin.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetMargin() + { + Margin = null; + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color + /// + [Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + _TextColor = Color.Empty; + } + + #endregion + + #endregion + + #region GetTextFormatFlags + + internal eTextFormat GetTextFormatFlags() + { + eTextFormat tf = eTextFormat.WordEllipsis | + eTextFormat.NoPadding | eTextFormat.NoPrefix; + + if (AllowWrap == Tbool.True) + tf |= eTextFormat.WordBreak; + + switch (Alignment) + { + case Alignment.TopCenter: + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.TopRight: + tf |= eTextFormat.Right; + break; + + case Alignment.MiddleLeft: + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleCenter: + tf |= eTextFormat.HorizontalCenter; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleRight: + tf |= eTextFormat.Right; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.BottomLeft: + tf |= eTextFormat.Bottom; + break; + + case Alignment.BottomCenter: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.BottomRight: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.Right; + break; + } + + return (tf); + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to the instance of this style. + /// + /// Style to apply. + public void ApplyStyle(FilterColumnHeaderVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.Alignment != Alignment.NotSet) + Alignment = style.Alignment; + + if (style.AllowWrap != Tbool.NotSet) + AllowWrap = style.AllowWrap; + + if (style.Background != null && style.Background.IsEmpty == false) + Background = style.Background.Copy(); + + if (style.GripBarBackground != null && style.GripBarBackground.IsEmpty == false) + GripBarBackground = style.GripBarBackground.Copy(); + + if (style.ErrorBackground != null && style.ErrorBackground.IsEmpty == false) + ErrorBackground = style.ErrorBackground.Copy(); + + if (style.Font != null) + Font = style.Font; + + if (style.ErrorTextColor.IsEmpty == false) + ErrorTextColor = style.ErrorTextColor; + + if (style.TextColor.IsEmpty == false) + TextColor = style.TextColor; + + if (style.Margin != null && style.Margin.IsEmpty == false) + Margin = style.Margin.Copy(); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new FilterColumnHeaderVisualStyle Copy() + { + FilterColumnHeaderVisualStyle style = new FilterColumnHeaderVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(FilterColumnHeaderVisualStyle copy) + { + base.CopyTo(copy); + + copy.Alignment = _Alignment; + copy.AllowWrap = _AllowWrap; + copy.ErrorTextColor = _ErrorTextColor; + copy.TextColor = _TextColor; + + if (_Background != null) + copy.Background = _Background.Copy(); + + if (_ErrorBackground != null) + copy.ErrorBackground = _ErrorBackground.Copy(); + + if (_GripBarBackground != null) + copy.GripBarBackground = _GripBarBackground.Copy(); + + if (_Font != null) + copy.Font = _Font; + + if (_Margin != null) + copy.Margin = _Margin.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + ErrorBackground = null; + GripBarBackground = null; + Margin = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/FilterRowVisualStyles.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/FilterRowVisualStyles.cs new file mode 100644 index 00000000..9192df96 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/FilterRowVisualStyles.cs @@ -0,0 +1,305 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// FilterRowVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class FilterRowVisualStyles : VisualStyles + { + } + + /// + /// FilterRowVisualStyle + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class FilterRowVisualStyle : BaseVisualStyle + { + #region Private variables + + private Color _FilterBorderColor = Color.Empty; + + private Background _FilterBackground; + private Background _WhiteSpaceBackground; + + private BaseRowHeaderVisualStyle _RowHeaderStyle; + + #endregion + + #region Public properties + + #region FilterBackground + + /// + /// Gets or sets the filter indicator background + /// + [Description("Indicates the RowHeader indicator background.")] + public Background FilterBackground + { + get + { + if (_FilterBackground == null) + { + _FilterBackground = Background.Empty; + + UpdateChangeHandler(null, _FilterBackground); + } + + return (_FilterBackground); + } + + set + { + if (_FilterBackground != value) + { + UpdateChangeHandler(_FilterBackground, value); + + _FilterBackground = value; + + OnPropertyChangedEx("FilterBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeFilterBackground() + { + return (_FilterBackground != null && + _FilterBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetFilterBackground() + { + FilterBackground = null; + } + + #endregion + + #region FilterBorderColor + + /// + /// Gets or sets the Filter border color + /// + [Description("Indicates the Filter border color")] + public Color FilterBorderColor + { + get { return (_FilterBorderColor); } + + set + { + if (_FilterBorderColor != value) + { + _FilterBorderColor = value; + + OnPropertyChangedEx("FilterBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeFilterBorderColor() + { + return (_FilterBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetFilterBorderColor() + { + _FilterBorderColor = Color.Empty; + } + + #endregion + + #region RowHeader + + /// + /// Gets or sets the visual style of the RowHeader + /// + [Description("Indicates the visual style of the RowHeader.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public BaseRowHeaderVisualStyle RowHeader + { + get + { + if (_RowHeaderStyle == null) + { + _RowHeaderStyle = BaseRowHeaderVisualStyle.Empty; + + UpdateChangeHandler(null, _RowHeaderStyle); + } + + return (_RowHeaderStyle); + } + + set + { + if (_RowHeaderStyle != value) + { + UpdateChangeHandler(_RowHeaderStyle, value); + + _RowHeaderStyle = value; + + OnPropertyChangedEx("RowHeader", VisualChangeType.Render); + } + } + } + + #endregion + + #region WhiteSpaceBackground + + /// + /// Gets or sets the WhiteSpace Background + /// + [Description("Indicates the WhiteSpace Background")] + public Background WhiteSpaceBackground + { + get + { + if (_WhiteSpaceBackground == null) + { + _WhiteSpaceBackground = Background.Empty; + + UpdateChangeHandler(null, _WhiteSpaceBackground); + } + + return (_WhiteSpaceBackground); + } + + set + { + if (_WhiteSpaceBackground != value) + { + UpdateChangeHandler(_WhiteSpaceBackground, value); + + _WhiteSpaceBackground = value; + + OnPropertyChangedEx("WhiteSpaceBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeWhiteSpaceBackground() + { + return (_WhiteSpaceBackground != null && + _WhiteSpaceBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetWhiteSpaceBackground() + { + WhiteSpaceBackground = null; + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(FilterRowVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + RowHeader.ApplyStyle(style.RowHeader); + + if (style.FilterBackground != null && style.FilterBackground.IsEmpty == false) + FilterBackground = style.FilterBackground.Copy(); + + if (style.FilterBorderColor.IsEmpty == false) + FilterBorderColor = style.FilterBorderColor; + + if (style.WhiteSpaceBackground != null && style.WhiteSpaceBackground.IsEmpty == false) + WhiteSpaceBackground = style.WhiteSpaceBackground.Copy(); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new FilterRowVisualStyle Copy() + { + FilterRowVisualStyle copy = new FilterRowVisualStyle(); + + CopyTo(copy); + + return (copy); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(FilterRowVisualStyle copy) + { + base.CopyTo(copy); + + if (_RowHeaderStyle != null) + copy.RowHeader = _RowHeaderStyle.Copy(); + + copy.FilterBorderColor = _FilterBorderColor; + + if (_FilterBackground != null) + copy.FilterBackground = _FilterBackground.Copy(); + + if (_WhiteSpaceBackground != null) + copy.WhiteSpaceBackground = _WhiteSpaceBackground.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + RowHeader = null; + WhiteSpaceBackground = null; + FilterBackground = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/GridPanelVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/GridPanelVisualStyle.cs new file mode 100644 index 00000000..d497d207 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/GridPanelVisualStyle.cs @@ -0,0 +1,717 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// GridPanelVisualStyle + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class GridPanelVisualStyle : VisualStyle + { + #region Private variables + + private Tbool _AllowWrap = Tbool.NotSet; + private Alignment _Alignment = Alignment.NotSet; + + private Color _HeaderLineColor = Color.Empty; + private Color _HorizontalLineColor = Color.Empty; + private Color _VerticalLineColor = Color.Empty; + private Color _TreeLineColor = Color.Empty; + + private TreeButtonVisualStyle _CircleTreeButtonStyle; + private TreeButtonVisualStyle _SquareTreeButtonStyle; + private TreeButtonVisualStyle _TriangleTreeButtonStyle; + + private LinePattern _HeaderHLinePattern = LinePattern.NotSet; + private LinePattern _HeaderVLinePattern = LinePattern.NotSet; + private LinePattern _HorizontalLinePattern = LinePattern.NotSet; + private LinePattern _VerticalLinePattern = LinePattern.NotSet; + private LinePattern _TreeLinePattern = LinePattern.NotSet; + + #endregion + + #region Hidden properties + + #region BorderThickness + + /// + /// Margin + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Thickness BorderThickness + { + get { return (base.BorderThickness); } + set { base.BorderThickness = value; } + } + + #endregion + + #region Margin + + /// + /// Margin + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Padding Margin + { + get { return (base.Margin); } + set { base.Margin = value; } + } + + #endregion + + #region Padding + + /// + /// Padding + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Padding Padding + { + get { return (base.Padding); } + set { base.Padding = value; } + } + + #endregion + + #endregion + + #region Public properties + + #region Alignment + + /// + /// Gets or sets the alignment of the NoRowText within the panel + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the NoRowText within the panel.")] + public Alignment Alignment + { + get { return (_Alignment); } + + set + { + if (_Alignment != value) + { + _Alignment = value; + + OnPropertyChangedEx("Alignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted.")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region CircleTreeButtonStyle + + /// + /// Gets or sets the Circle TreeButton Style + /// + [Category("Appearance")] + [Description("Indicates the Circle TreeButton Style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TreeButtonVisualStyle CircleTreeButtonStyle + { + get + { + if (_CircleTreeButtonStyle == null) + { + _CircleTreeButtonStyle = TreeButtonVisualStyle.Empty; + + UpdateChangeHandler(null, _CircleTreeButtonStyle); + } + + return (_CircleTreeButtonStyle); + } + + set + { + if (_CircleTreeButtonStyle != value) + { + UpdateChangeHandler(_CircleTreeButtonStyle, value); + + _CircleTreeButtonStyle = value; + + OnPropertyChangedEx("CircleTreeButtonStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #region HeaderLineColor + + /// + /// Gets or sets the Header Line Color + /// + [Category("Appearance")] + [Description("Indicates the Header Line Color.")] + public Color HeaderLineColor + { + get { return (_HeaderLineColor); } + + set + { + if (_HeaderLineColor != value) + { + _HeaderLineColor = value; + + OnPropertyChangedEx("HeaderLineColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeHeaderLineColor() + { + return (_HeaderLineColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetHeaderLineColor() + { + _HeaderLineColor = Color.Empty; + } + + #endregion + + #region HeaderHLinePattern + + /// + /// Gets or sets the Header Horizontal Line pattern + /// + [Category("Appearance"), DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Header Line pattern.")] + public LinePattern HeaderHLinePattern + { + get { return (_HeaderHLinePattern); } + + set + { + if (_HeaderHLinePattern != value) + { + _HeaderHLinePattern = value; + + OnPropertyChangedEx("HeaderHLinePattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region HeaderVLinePattern + + /// + /// Gets or sets the Header Vertical Line pattern + /// + [Category("Appearance"), DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Header Line pattern.")] + public LinePattern HeaderVLinePattern + { + get { return (_HeaderVLinePattern); } + + set + { + if (_HeaderVLinePattern != value) + { + _HeaderVLinePattern = value; + + OnPropertyChangedEx("HeaderVLinePattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region HorizontalLineColor + + /// + /// Gets or sets the Horizontal Line Color + /// + [Category("Appearance")] + [Description("Indicates the Horizontal Line Color.")] + public Color HorizontalLineColor + { + get { return (_HorizontalLineColor); } + + set + { + if (_HorizontalLineColor != value) + { + _HorizontalLineColor = value; + + OnPropertyChangedEx("HorizontalLineColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeHorizontalLineColor() + { + return (_HorizontalLineColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetHorizontalLineColor() + { + _HorizontalLineColor = Color.Empty; + } + + #endregion + + #region HorizontalLinePattern + + /// + /// Gets or sets the Horizontal Line pattern + /// + [Category("Appearance"), DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Horizontal Line pattern.")] + public LinePattern HorizontalLinePattern + { + get { return (_HorizontalLinePattern); } + + set + { + if (_HorizontalLinePattern != value) + { + _HorizontalLinePattern = value; + + OnPropertyChangedEx("HorizontalLinePattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region SquareTreeButtonStyle + + /// + /// Gets or sets the Square TreeButton Style + /// + [Category("Appearance")] + [Description("Indicates the Square TreeButton Style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TreeButtonVisualStyle SquareTreeButtonStyle + { + get + { + if (_SquareTreeButtonStyle == null) + { + _SquareTreeButtonStyle = TreeButtonVisualStyle.Empty; + + UpdateChangeHandler(null, _SquareTreeButtonStyle); + } + + return (_SquareTreeButtonStyle); + } + + set + { + if (_SquareTreeButtonStyle != value) + { + UpdateChangeHandler(_SquareTreeButtonStyle, value); + + _SquareTreeButtonStyle = value; + + OnPropertyChangedEx("SquareTreeButtonStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #region TreeLineColor + + /// + /// Gets or sets the Tree Line Color + /// + [Category("Appearance")] + [Description("Indicates the Tree Line Color.")] + public Color TreeLineColor + { + get { return (_TreeLineColor); } + + set + { + if (_TreeLineColor != value) + { + _TreeLineColor = value; + + OnPropertyChangedEx("TreeLineColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTreeLineColor() + { + return (_TreeLineColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTreeLineColor() + { + _TreeLineColor = Color.Empty; + } + + #endregion + + #region TreeLinePattern + + /// + /// Gets or sets the Tree Line pattern + /// + [Category("Appearance"), DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Tree Line pattern.")] + public LinePattern TreeLinePattern + { + get { return (_TreeLinePattern); } + + set + { + if (_TreeLinePattern != value) + { + _TreeLinePattern = value; + + OnPropertyChangedEx("TreeLinePattern", VisualChangeType.Render); + } + } + } + + #endregion + + #region TriangleTreeButtonStyle + + /// + /// Gets or sets the Triangle TreeButton Style + /// + [Category("Appearance")] + [Description("Indicates the Triangle TreeButton Style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public TreeButtonVisualStyle TriangleTreeButtonStyle + { + get + { + if (_TriangleTreeButtonStyle == null) + { + _TriangleTreeButtonStyle = TreeButtonVisualStyle.Empty; + + UpdateChangeHandler(null, _TriangleTreeButtonStyle); + } + + return (_TriangleTreeButtonStyle); + } + + set + { + if (_TriangleTreeButtonStyle != value) + { + UpdateChangeHandler(_TriangleTreeButtonStyle, value); + + _TriangleTreeButtonStyle = value; + + OnPropertyChangedEx("TriangleTreeButtonStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #region VerticalLineColor + + /// + /// Gets or sets the Vertical Line color + /// + [Category("Appearance")] + [Description("Indicates the Vertical Line Color.")] + public Color VerticalLineColor + { + get { return (_VerticalLineColor); } + + set + { + if (_VerticalLineColor != value) + { + _VerticalLineColor = value; + + OnPropertyChangedEx("VerticalLineColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeVerticalLineColor() + { + return (_VerticalLineColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetVerticalLineColor() + { + _VerticalLineColor = Color.Empty; + } + + #endregion + + #region VerticalLinePattern + + /// + /// Gets or sets the Vertical Line pattern + /// + [Category("Appearance"), DefaultValue(LinePattern.NotSet)] + [Description("Indicates the Vertical Line pattern.")] + public LinePattern VerticalLinePattern + { + get { return (_VerticalLinePattern); } + + set + { + if (_VerticalLinePattern != value) + { + _VerticalLinePattern = value; + + OnPropertyChangedEx("VerticalLinePattern", VisualChangeType.Render); + } + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(GridPanelVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.Alignment != Alignment.NotSet) + _Alignment = style.Alignment; + + if (style.AllowWrap != Tbool.NotSet) + _AllowWrap = style.AllowWrap; + + if (style._CircleTreeButtonStyle != null) + CircleTreeButtonStyle.ApplyStyle(style._CircleTreeButtonStyle); + + if (style.HeaderLineColor.IsEmpty == false) + _HeaderLineColor = style.HeaderLineColor; + + if (style.TreeLineColor.IsEmpty == false) + _TreeLineColor = style.TreeLineColor; + + if (style.HorizontalLineColor.IsEmpty == false) + _HorizontalLineColor = style.HorizontalLineColor; + + if (style.VerticalLineColor.IsEmpty == false) + _VerticalLineColor = style.VerticalLineColor; + + if (style.TreeLinePattern != LinePattern.NotSet) + TreeLinePattern = style.TreeLinePattern; + + if (style.HorizontalLinePattern != LinePattern.NotSet) + HorizontalLinePattern = style.HorizontalLinePattern; + + if (style._SquareTreeButtonStyle != null) + SquareTreeButtonStyle.ApplyStyle(style._SquareTreeButtonStyle); + + if (style._TriangleTreeButtonStyle != null) + TriangleTreeButtonStyle.ApplyStyle(style._TriangleTreeButtonStyle); + + if (style.VerticalLinePattern != LinePattern.NotSet) + VerticalLinePattern = style.VerticalLinePattern; + + if (style.HeaderHLinePattern != LinePattern.NotSet) + HeaderHLinePattern = style.HeaderHLinePattern; + + if (style.HeaderVLinePattern != LinePattern.NotSet) + HeaderVLinePattern = style.HeaderVLinePattern; + } + } + + #endregion + + #region GetTextFormatFlags + + internal eTextFormat GetTextFormatFlags() + { + eTextFormat tf = eTextFormat.WordEllipsis | + eTextFormat.NoPadding | eTextFormat.NoPrefix; + + if (AllowWrap == Tbool.True) + tf |= eTextFormat.WordBreak; + + switch (Alignment) + { + case Alignment.TopCenter: + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.TopRight: + tf |= eTextFormat.Right; + break; + + case Alignment.MiddleLeft: + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.NotSet: + case Alignment.MiddleCenter: + tf |= eTextFormat.HorizontalCenter; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleRight: + tf |= eTextFormat.Right; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.BottomLeft: + tf |= eTextFormat.Bottom; + break; + + case Alignment.BottomCenter: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.BottomRight: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.Right; + break; + } + + return (tf); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new GridPanelVisualStyle Copy() + { + GridPanelVisualStyle style = new GridPanelVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(GridPanelVisualStyle copy) + { + base.CopyTo(copy); + + copy.Alignment = _Alignment; + copy.AllowWrap = _AllowWrap; + + copy.HeaderLineColor = _HeaderLineColor; + copy.TreeLineColor = _TreeLineColor; + copy.HorizontalLineColor = _HorizontalLineColor; + copy.VerticalLineColor = _VerticalLineColor; + + copy.TreeLinePattern = _TreeLinePattern; + copy.HorizontalLinePattern = _HorizontalLinePattern; + copy.VerticalLinePattern = _VerticalLinePattern; + copy.HeaderHLinePattern = _HeaderHLinePattern; + copy.HeaderVLinePattern = _HeaderVLinePattern; + + if (_CircleTreeButtonStyle != null) + copy.CircleTreeButtonStyle = _CircleTreeButtonStyle.Copy(); + + if (_SquareTreeButtonStyle != null) + copy.SquareTreeButtonStyle = _SquareTreeButtonStyle.Copy(); + + if (_TriangleTreeButtonStyle != null) + copy.TriangleTreeButtonStyle = _TriangleTreeButtonStyle.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + CircleTreeButtonStyle = null; + SquareTreeButtonStyle = null; + TriangleTreeButtonStyle = null; + + base.Dispose(); + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/GroupByVisualStyles.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/GroupByVisualStyles.cs new file mode 100644 index 00000000..91a0fb37 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/GroupByVisualStyles.cs @@ -0,0 +1,478 @@ +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// FilterRowVisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class GroupByVisualStyles : VisualStyles + { + } + + /// + /// FilterRowVisualStyle + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class GroupByVisualStyle : TextRowVisualStyle + { + #region Private variables + + private Color _GroupBoxBorderColor = Color.Empty; + private Color _GroupBoxConnectorColor = Color.Empty; + private Color _GroupBoxTextColor = Color.Empty; + private Background _GroupBoxBackground; + + private Color _WatermarkTextColor = Color.Empty; + private Font _WatermarkFont; + + private Background _InsertMarkerBackground; + private Color _InsertMarkerBorderColor = Color.Empty; + + #endregion + + #region Public properties + + #region GroupBoxBorderColor + + /// + /// Gets or sets the GroupBox border color + /// + [Description("Indicates the GroupBox border color")] + public Color GroupBoxBorderColor + { + get { return (_GroupBoxBorderColor); } + + set + { + if (_GroupBoxBorderColor != value) + { + _GroupBoxBorderColor = value; + + OnPropertyChangedEx("GroupBoxBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeGroupBoxBorderColor() + { + return (_GroupBoxBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetGroupBoxBorderColor() + { + _GroupBoxBorderColor = Color.Empty; + } + + #endregion + + #region GroupBoxConnectorColor + + /// + /// Gets or sets the GroupBox connector color + /// + [Description("Indicates the GroupBox connector color")] + public Color GroupBoxConnectorColor + { + get { return (_GroupBoxConnectorColor); } + + set + { + if (_GroupBoxConnectorColor != value) + { + _GroupBoxConnectorColor = value; + + OnPropertyChangedEx("GroupBoxConnectorColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeGroupBoxConnectorColor() + { + return (_GroupBoxBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetGroupBoxConnectorColor() + { + _GroupBoxBorderColor = Color.Empty; + } + + #endregion + + #region GroupBoxBackground + + /// + /// Gets or sets the GroupBox indicator background + /// + [Description("Indicates the RowHeader indicator background.")] + public Background GroupBoxBackground + { + get + { + if (_GroupBoxBackground == null) + { + _GroupBoxBackground = Background.Empty; + + UpdateChangeHandler(null, _GroupBoxBackground); + } + + return (_GroupBoxBackground); + } + + set + { + if (_GroupBoxBackground != value) + { + UpdateChangeHandler(_GroupBoxBackground, value); + + _GroupBoxBackground = value; + + OnPropertyChangedEx("GroupBoxBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeGroupBoxBackground() + { + return (_GroupBoxBackground != null && + _GroupBoxBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetGroupBoxBackground() + { + GroupBoxBackground = null; + } + + #endregion + + #region GroupBoxTextColor + + /// + /// Gets or sets the GroupBox Text color + /// + [Description("Indicates the GroupBox Text color")] + public Color GroupBoxTextColor + { + get { return (_GroupBoxTextColor); } + + set + { + if (_GroupBoxTextColor != value) + { + _GroupBoxTextColor = value; + + OnPropertyChangedEx("GroupBoxTextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeGroupBoxTextColor() + { + return (_GroupBoxTextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetGroupBoxTextColor() + { + _GroupBoxTextColor = Color.Empty; + } + + #endregion + + #region InsertMarkerBackground + + /// + /// Gets or sets the Insert Marker background color + /// + [Description("Indicates the Insert Marker background color")] + public Background InsertMarkerBackground + { + get + { + if (_InsertMarkerBackground == null) + { + _InsertMarkerBackground = Background.Empty; + + UpdateChangeHandler(null, _InsertMarkerBackground); + } + + return (_InsertMarkerBackground); + } + + set + { + if (_InsertMarkerBackground != value) + { + UpdateChangeHandler(_InsertMarkerBackground, value); + + _InsertMarkerBackground = value; + + OnPropertyChangedEx("InsertMarkerBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeInsertMarkerBackground() + { + return (_InsertMarkerBackground != null && + _InsertMarkerBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetInsertMarkerBackground() + { + InsertMarkerBackground = null; + } + + #endregion + + #region InsertMarkerBorderColor + + /// + /// Gets or sets the Insert Marker border color + /// + [Description("Indicates the Insert Marker border color")] + public Color InsertMarkerBorderColor + { + get { return (_InsertMarkerBorderColor); } + + set + { + if (_InsertMarkerBorderColor != value) + { + _InsertMarkerBorderColor = value; + + OnPropertyChangedEx("InsertMarkerBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeInsertMarkerBorderColor() + { + return (_InsertMarkerBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetInsertMarkerBorderColor() + { + _InsertMarkerBorderColor = Color.Empty; + } + + #endregion + + #region WatermarkFont + + /// + /// Gets or sets the style Watermark Font + /// + [DefaultValue(null)] + [Description("Indicates the style Watermark Font")] + public Font WatermarkFont + { + get { return (_WatermarkFont); } + + set + { + if (_WatermarkFont != value) + { + _WatermarkFont = value; + + OnPropertyChangedEx("WatermarkFont", VisualChangeType.Layout); + } + } + } + + #endregion + + #region WatermarkTextColor + + /// + /// Gets or sets the Watermark Text color + /// + [Description("Indicates the Watermark Text color")] + public Color WatermarkTextColor + { + get { return (_WatermarkTextColor); } + + set + { + if (_WatermarkTextColor != value) + { + _WatermarkTextColor = value; + + OnPropertyChangedEx("WatermarkTextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeWatermarkTextColor() + { + return (_WatermarkTextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetWatermarkTextColor() + { + _WatermarkTextColor = Color.Empty; + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(GroupByVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.GroupBoxBorderColor.IsEmpty == false) + GroupBoxBorderColor = style.GroupBoxBorderColor; + + if (style.GroupBoxConnectorColor.IsEmpty == false) + GroupBoxConnectorColor = style.GroupBoxConnectorColor; + + if (style.GroupBoxTextColor.IsEmpty == false) + GroupBoxTextColor = style.GroupBoxTextColor; + + if (style.GroupBoxBackground != null && style.GroupBoxBackground.IsEmpty == false) + GroupBoxBackground = style.GroupBoxBackground.Copy(); + + if (style.InsertMarkerBorderColor.IsEmpty == false) + InsertMarkerBorderColor = style.InsertMarkerBorderColor; + + if (style.InsertMarkerBackground != null && style.InsertMarkerBackground.IsEmpty == false) + InsertMarkerBackground = style.InsertMarkerBackground.Copy(); + + if (style.WatermarkTextColor.IsEmpty == false) + WatermarkTextColor = style.WatermarkTextColor; + + if (style.WatermarkFont != null) + WatermarkFont = style.WatermarkFont; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new FilterRowVisualStyle Copy() + { + FilterRowVisualStyle copy = new FilterRowVisualStyle(); + + CopyTo(copy); + + return (copy); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(GroupByVisualStyle copy) + { + base.CopyTo(copy); + + copy.GroupBoxBorderColor = _GroupBoxBorderColor; + copy.GroupBoxTextColor = _GroupBoxTextColor; + copy.GroupBoxConnectorColor = _GroupBoxConnectorColor; + + if (_GroupBoxBackground != null) + copy.GroupBoxBackground = _GroupBoxBackground.Copy(); + + copy.InsertMarkerBorderColor = _InsertMarkerBorderColor; + + if (_InsertMarkerBackground != null) + copy.InsertMarkerBackground = _InsertMarkerBackground.Copy(); + + copy.WatermarkTextColor = _WatermarkTextColor; + + if (_WatermarkFont != null) + copy.Font = (Font)_WatermarkFont.Clone(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + GroupBoxBackground = null; + InsertMarkerBackground = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/GroupHeaderVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/GroupHeaderVisualStyle.cs new file mode 100644 index 00000000..86328318 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/GroupHeaderVisualStyle.cs @@ -0,0 +1,500 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// GroupHeaderVisualStyles + /// + public class GroupHeaderVisualStyles : VisualStyles + { + } + + /// + /// RowHeaderVisualStyle + /// + public class GroupHeaderVisualStyle : BaseVisualStyle + { + #region Static data + + /// + /// Empty + /// + public static GroupHeaderVisualStyle Empty + { + get { return (new GroupHeaderVisualStyle()); } + } + + #endregion + + #region Private variables + + private Font _Font; + private Alignment _Alignment = Alignment.NotSet; + private Tbool _AllowWrap = Tbool.NotSet; + private Color _TextColor = Color.Empty; + private Color _UnderlineColor = Color.Empty; + private Background _Background; + private Padding _Padding; + + private RowHeaderVisualStyle _RowHeaderStyle; + + #endregion + + #region Public properties + + #region Alignment + + /// + /// Gets or sets the alignment of the content within the cell + /// + [DefaultValue(Alignment.NotSet), Category("Appearance")] + [Description("Indicates the alignment of the content.")] + public Alignment Alignment + { + get { return (_Alignment); } + + set + { + if (_Alignment != value) + { + _Alignment = value; + + OnPropertyChangedEx("Alignment", VisualChangeType.Layout); + } + } + } + + #endregion + + #region AllowWrap + + /// + /// Gets or sets whether text wrapping is permitted + /// + [DefaultValue(Tbool.NotSet), Category("Appearance")] + [Description("Indicates whether text wrapping is permitted")] + public Tbool AllowWrap + { + get { return (_AllowWrap); } + + set + { + if (_AllowWrap != value) + { + _AllowWrap = value; + + OnPropertyChangedEx("AllowWrap", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font. + /// + [DefaultValue(null)] + [Description("Indicates the style Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region Padding + + /// + /// Gets or sets the spacing between the content and edges of the element + /// + [Description("Indicates the spacing between the content and edges of the element")] + public Padding Padding + { + get + { + if (_Padding == null) + { + _Padding = Padding.Empty; + + UpdateChangeHandler(null, _Padding); + } + + return (_Padding); + } + + set + { + if (_Padding != value) + { + UpdateChangeHandler(_Padding, value); + + _Padding = value; + + OnPropertyChangedEx("Padding", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializePadding() + { + return (_Padding != null && _Padding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetPadding() + { + Padding = null; + } + #endregion + + #region RowHeaderStyle + + /// + /// Gets or sets the GroupHeader RowHeader Style + /// + [Category("Appearance")] + [Description("Indicates the GroupHeader RowHeader Style")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public RowHeaderVisualStyle RowHeaderStyle + { + get + { + if (_RowHeaderStyle == null) + { + _RowHeaderStyle = RowHeaderVisualStyle.Empty; + + UpdateChangeHandler(null, _RowHeaderStyle); + } + + return (_RowHeaderStyle); + } + + set + { + if (_RowHeaderStyle != value) + { + UpdateChangeHandler(_RowHeaderStyle, value); + + _RowHeaderStyle = value; + + OnPropertyChangedEx("RowHeaderStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color + /// + [Category("Appearance"), Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + _TextColor = Color.Empty; + } + + #endregion + + #region UnderlineColor + + /// + /// Gets or sets the text Underline Color + /// + [Description("Indicates the text Underline Color")] + public Color UnderlineColor + { + get { return (_UnderlineColor); } + + set + { + if (_UnderlineColor != value) + { + _UnderlineColor = value; + + OnPropertyChangedEx("UnderlineColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeUnderlineColor() + { + return (_UnderlineColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetUnderlineColor() + { + _UnderlineColor = Color.Empty; + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(GroupHeaderVisualStyle style) + { + base.ApplyStyle(style); + + if (style.Alignment != Alignment.NotSet) + Alignment = style.Alignment; + + if (style.AllowWrap != Tbool.NotSet) + AllowWrap = style.AllowWrap; + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style.Font != null) + Font = style.Font; + + if (style._Padding != null && style._Padding.IsEmpty == false) + Padding = style._Padding.Copy(); + + if (style.TextColor.IsEmpty == false) + TextColor = style.TextColor; + + if (style.UnderlineColor.IsEmpty == false) + UnderlineColor = style.UnderlineColor; + + if (style._RowHeaderStyle != null) + RowHeaderStyle.ApplyStyle(style._RowHeaderStyle); + } + + #endregion + + #region GetTextFormatFlags + + internal eTextFormat GetTextFormatFlags() + { + eTextFormat tf = eTextFormat.WordEllipsis | + eTextFormat.NoPadding | eTextFormat.NoPrefix; + + if (AllowWrap == Tbool.True) + tf |= eTextFormat.WordBreak; + + switch (Alignment) + { + case Alignment.TopCenter: + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.TopRight: + tf |= eTextFormat.Right; + break; + + case Alignment.MiddleLeft: + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleCenter: + tf |= eTextFormat.HorizontalCenter; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.MiddleRight: + tf |= eTextFormat.Right; + tf |= eTextFormat.VerticalCenter; + break; + + case Alignment.BottomLeft: + tf |= eTextFormat.Bottom; + break; + + case Alignment.BottomCenter: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.HorizontalCenter; + break; + + case Alignment.BottomRight: + tf |= eTextFormat.Bottom; + tf |= eTextFormat.Right; + break; + } + + return (tf); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new GroupHeaderVisualStyle Copy() + { + GroupHeaderVisualStyle copy = new GroupHeaderVisualStyle(); + + CopyTo(copy); + + return (copy); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(GroupHeaderVisualStyle copy) + { + base.CopyTo(copy); + + copy.Alignment = _Alignment; + copy.AllowWrap = _AllowWrap; + + if (_Background != null) + copy.Background = _Background.Copy(); + + if (_Font != null) + copy.Font = (Font)_Font.Clone(); + + if (_Padding != null) + copy.Padding = _Padding.Copy(); + + copy.TextColor = _TextColor; + copy.UnderlineColor = _UnderlineColor; + + if (_RowHeaderStyle != null) + copy.RowHeaderStyle = _RowHeaderStyle.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + Padding = null; + RowHeaderStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/Padding.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/Padding.cs new file mode 100644 index 00000000..362e1f4e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/Padding.cs @@ -0,0 +1,227 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Globalization; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Padding + /// + [TypeConverter(typeof(PaddingTypeConverter))] + public class Padding : Thickness + { + #region Static data + + /// + /// Returns Empty instance of Thickness. + /// + public new static Padding Empty + { + get { return (new Padding()); } + } + + #endregion + + #region Constructors + + /// + /// Creates new instance of the class and initializes it. + /// + /// Left padding + /// Right padding + /// Top padding + /// Bottom padding + public Padding(int left, int top, int right, int bottom) + : base(left, top, right, bottom) + { + } + + /// + /// Initializes a new instance of the Padding class. + /// + /// Uniform padding. + public Padding(int all) + : base(all) + { + } + + /// + /// Initializes a new instance of the Padding class. + /// + public Padding() + { + } + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the Padding. + /// + /// Copy of the Padding. + public new Padding Copy() + { + Padding copy = new Padding(Left, Top, Right, Bottom); + + return (copy); + } + + #endregion + } + + #region PaddingTypeConverter + + /// + /// PaddingTypeConverter + /// + public class PaddingTypeConverter : ExpandableObjectConverter + { + #region CanConvertTo + + /// + /// CanConvertTo + /// + /// + /// + /// + public override bool CanConvertTo( + ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + return (true); + + return (base.CanConvertTo(context, destinationType)); + } + + #endregion + + #region ConvertTo + + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + Padding p = value as Padding; + + if (p != null) + { + if (p.IsUniform == true) + return (p.Left.ToString()); + + return (String.Format("{0:d}, {1:d}, {2:d}, {3:d}", + p.Bottom, p.Left, p.Right, p.Top)); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + + #endregion + + #region CanConvertFrom + + /// + /// CanConvertFrom + /// + /// + /// + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + return (true); + + return (base.CanConvertFrom(context, sourceType)); + } + + #endregion + + #region ConvertFrom + + /// + /// ConvertFrom + /// + /// + /// + /// + /// + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + string[] values = ((string)value).Split(','); + + if (values.Length != 1 && values.Length != 4) + throw new ArgumentException("Invalid value to convert."); + + try + { + int[] v = new int[values.Length]; + + for (int i = 0; i < values.Length; i++) + v[i] = int.Parse(values[i]); + + Padding p = (values.Length == 1) + ? new Padding(v[0]) + : new Padding(v[1], v[3], v[2], v[0]); + + return (p); + } + catch (Exception) + { + throw new ArgumentException("Invalid value to convert."); + } + } + + return base.ConvertFrom(context, culture, value); + } + + #endregion + + #region GetCreateInstanceSupported + + /// + /// GetCreateInstanceSupported + /// + /// + /// + public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region CreateInstance + + /// + /// CreateInstance + /// + /// + /// + /// + public override object CreateInstance( + ITypeDescriptorContext context, IDictionary propertyValues) + { + return (new Padding((int)propertyValues["Left"], (int)propertyValues["Top"], + (int)propertyValues["Right"], (int)propertyValues["Bottom"])); + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/RowHeaderVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/RowHeaderVisualStyle.cs new file mode 100644 index 00000000..920ef83d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/RowHeaderVisualStyle.cs @@ -0,0 +1,609 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.IO; +using System.Reflection; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// RowHeaderVisualStyle + /// + public class RowHeaderVisualStyle : BaseRowHeaderVisualStyle + { + #region Static data + + static Image _ActiveRowImageCache; + static Image _EditingRowImageCache; + static Image _InfoRowImageCache; + + /// + /// Empty + /// + public new static RowHeaderVisualStyle Empty + { + get { return (new RowHeaderVisualStyle()); } + } + + #endregion + + #region Private variables + + private Background _ActiveRowBackground; + private Background _DirtyMarkerBackground; + + private Color _ActiveRowIndicatorColor = Color.Empty; + + private Image _ActiveRowImage; + private int _ActiveRowImageIndex = -1; + + private Image _EditingRowImage; + private int _EditingRowImageIndex = -1; + + private Image _InfoRowImage; + private int _InfoRowImageIndex = -1; + + #endregion + + #region Public properties + + #region ActiveRowBackground + + /// + /// Gets or sets the ActiveRow background + /// + [Description("Indicates the ActiveRow background")] + public Background ActiveRowBackground + { + get + { + if (_ActiveRowBackground == null) + { + _ActiveRowBackground = Background.Empty; + + UpdateChangeHandler(null, _ActiveRowBackground); + } + + return (_ActiveRowBackground); + } + + set + { + if (_ActiveRowBackground != value) + { + UpdateChangeHandler(_ActiveRowBackground, value); + + _ActiveRowBackground = value; + + OnPropertyChangedEx("ActiveRowBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeActiveRowBackground() + { + return (_ActiveRowBackground != null && _ActiveRowBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetActiveRowBackground() + { + ActiveRowBackground = null; + } + + #endregion + + #region ActiveRowImage + + /// + /// Gets or sets the Active Row Image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Active Row image")] + public Image ActiveRowImage + { + get { return (_ActiveRowImage); } + + set + { + if (_ActiveRowImage != value) + { + _ActiveRowImage = value; + + OnPropertyChangedEx("ActiveRowImage", VisualChangeType.Layout); + } + } + } + + #endregion + + #region ActiveRowImageIndex + + /// + /// Gets or sets the Active Row image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the Active Row image index")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int ActiveRowImageIndex + { + get { return (_ActiveRowImageIndex); } + + set + { + if (_ActiveRowImageIndex != value) + { + _ActiveRowImageIndex = value; + + OnPropertyChangedEx("ActiveRowImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetActiveRowImageIndex() + { + _ActiveRowImageIndex = -1; + } + + #endregion + + #region ActiveRowIndicatorColor + + /// + /// Gets or sets the Active Row Indicator color + /// + [Description("Indicates the Active Row Indicator color")] + public Color ActiveRowIndicatorColor + { + get { return (_ActiveRowIndicatorColor); } + + set + { + if (_ActiveRowIndicatorColor != value) + { + _ActiveRowIndicatorColor = value; + + OnPropertyChangedEx("ActiveRowIndicatorColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeActiveRowIndicatorColor() + { + return (_ActiveRowIndicatorColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetActiveRowIndicatorColor() + { + _ActiveRowIndicatorColor = Color.Empty; + } + + #endregion + + #region DirtyMarkerBackground + + /// + /// Gets or sets the DirtyRow marker background + /// + [Description("Indicates the DirtyRow marker background")] + public Background DirtyMarkerBackground + { + get + { + if (_DirtyMarkerBackground == null) + { + _DirtyMarkerBackground = Background.Empty; + + UpdateChangeHandler(null, _DirtyMarkerBackground); + } + + return (_DirtyMarkerBackground); + } + + set + { + if (_DirtyMarkerBackground != value) + { + UpdateChangeHandler(_DirtyMarkerBackground, value); + + _DirtyMarkerBackground = value; + + OnPropertyChangedEx("DirtyMarkerBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeDirtyMarkerBackground() + { + return (_DirtyMarkerBackground != null && _DirtyMarkerBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetDirtyMarkerBackground() + { + DirtyMarkerBackground = null; + } + + #endregion + + #region EditingRowImage + + /// + /// Gets or sets the Editing Row Image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Editing Row image")] + public Image EditingRowImage + { + get { return (_EditingRowImage); } + + set + { + if (_EditingRowImage != value) + { + _EditingRowImage = value; + + OnPropertyChangedEx("EditingRowImage", VisualChangeType.Layout); + } + } + } + + #endregion + + #region EditingRowImageIndex + + /// + /// Gets or sets the Editing Row image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the Editing Row image index")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int EditingRowImageIndex + { + get { return (_EditingRowImageIndex); } + + set + { + if (_EditingRowImageIndex != value) + { + _EditingRowImageIndex = value; + + OnPropertyChangedEx("EditingRowImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetEditingRowImageIndex() + { + _EditingRowImageIndex = -1; + } + + #endregion + + #region InfoRowImage + + /// + /// Gets or sets the Info Row Image + /// + [DefaultValue(null), Category("Appearance")] + [Description("Indicates the Info Row image")] + public Image InfoRowImage + { + get { return (_InfoRowImage); } + + set + { + if (_InfoRowImage != value) + { + _InfoRowImage = value; + + OnPropertyChangedEx("InfoRowImage", VisualChangeType.Layout); + } + } + } + + #endregion + + #region InfoRowImageIndex + + /// + /// Gets or sets the Info Row image index + /// + [Browsable(true), DefaultValue(-1)] + [Category("Appearance"), Description("Indicates the Info Row image index")] + [Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486", typeof(UITypeEditor))] + [TypeConverter(typeof(ImageIndexConverter))] + public int InfoRowImageIndex + { + get { return (_InfoRowImageIndex); } + + set + { + if (_InfoRowImageIndex != value) + { + _InfoRowImageIndex = value; + + OnPropertyChangedEx("InfoRowImageIndex", VisualChangeType.Layout); + } + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetInfoRowImageIndex() + { + _InfoRowImageIndex = -1; + } + + #endregion + + #endregion + + #region GetActiveRowImage + + internal Image GetActiveRowImage(GridPanel panel) + { + if (_ActiveRowImage != null) + return (_ActiveRowImage); + + if (_ActiveRowImageIndex >= 0 && panel != null) + { + ImageList imageList = panel.ImageList; + + if (imageList != null && _ActiveRowImageIndex < imageList.Images.Count) + return (imageList.Images[_ActiveRowImageIndex]); + } + + return (GetActiveRowImage()); + } + + #region GetActiveRowImage + + private Image GetActiveRowImage() + { + if (_ActiveRowImage != null) + return (_ActiveRowImage); + + if (_ActiveRowImageCache == null) + { + Rectangle r = new Rectangle(0, 0, Dpi.Width4, Dpi.Height7); + Image image = new Bitmap(Dpi.Width4, Dpi.Height7); + + using (Graphics g = Graphics.FromImage(image)) + { + using (GraphicsPath path = new GraphicsPath()) + { + Point pt = new Point(r.Right, r.Y + r.Height / 2); + + Point[] pts = + { + pt, + new Point(pt.X - Dpi.Width4, pt.Y + Dpi.Height4), + new Point(pt.X - Dpi.Width4, pt.Y - Dpi.Height4), + pt + }; + + path.AddLines(pts); + + Color color = ActiveRowIndicatorColor; + + if (color.IsEmpty) + color = Color.Black; + + using (Brush br = new SolidBrush(color)) + g.FillPath(br, path); + } + } + + _ActiveRowImageCache = image; + } + + return (_ActiveRowImageCache); + } + + #endregion + + #endregion + + #region GetEditingRowImage + + internal Image GetEditingRowImage(GridPanel panel) + { + if (_EditingRowImage != null) + return (_EditingRowImage); + + if (_EditingRowImageIndex >= 0 && panel != null) + { + ImageList imageList = panel.ImageList; + + if (imageList != null && _EditingRowImageIndex < imageList.Images.Count) + return (imageList.Images[_EditingRowImageIndex]); + } + + if (_EditingRowImageCache == null) + _EditingRowImageCache = panel.GetResourceImage("Pencil"); + + return (_EditingRowImageCache); + } + + #endregion + + #region GetInfoRowImage + + internal Image GetInfoRowImage(GridPanel panel) + { + if (_InfoRowImage != null) + return (_InfoRowImage); + + if (_InfoRowImageIndex >= 0 && panel != null) + { + ImageList imageList = panel.ImageList; + + if (imageList != null && _InfoRowImageIndex < imageList.Images.Count) + return (imageList.Images[_InfoRowImageIndex]); + } + + if (_InfoRowImageCache == null) + _InfoRowImageCache = panel.GetResourceImage("InfoImage"); + + return (_InfoRowImageCache); + } + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(RowHeaderVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._ActiveRowIndicatorColor.IsEmpty == false) + _ActiveRowIndicatorColor = style._ActiveRowIndicatorColor; + + if (style._ActiveRowBackground != null && style._ActiveRowBackground.IsEmpty == false) + _ActiveRowBackground = style._ActiveRowBackground.Copy(); + + if (style._DirtyMarkerBackground != null && style._DirtyMarkerBackground.IsEmpty == false) + _DirtyMarkerBackground = style._DirtyMarkerBackground.Copy(); + + if (style.ActiveRowImageIndex >= 0) + { + _ActiveRowImage = null; + _ActiveRowImageIndex = style.ActiveRowImageIndex; + } + + if (style.ActiveRowImage != null) + { + _ActiveRowImage = style.ActiveRowImage; + _ActiveRowImageIndex = -1; + } + + if (style.EditingRowImageIndex >= 0) + { + _EditingRowImage = null; + _EditingRowImageIndex = style.EditingRowImageIndex; + } + + if (style.EditingRowImage != null) + { + _EditingRowImage = style.EditingRowImage; + _EditingRowImageIndex = -1; + } + + if (style.InfoRowImageIndex >= 0) + { + _InfoRowImage = null; + _InfoRowImageIndex = style.InfoRowImageIndex; + } + + if (style.InfoRowImage != null) + { + _InfoRowImage = style.InfoRowImage; + _InfoRowImageIndex = -1; + } + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new RowHeaderVisualStyle Copy() + { + RowHeaderVisualStyle copy = new RowHeaderVisualStyle(); + + CopyTo(copy); + + return (copy); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(RowHeaderVisualStyle copy) + { + base.CopyTo(copy); + + if (_ActiveRowIndicatorColor.IsEmpty == false) + copy.ActiveRowIndicatorColor = _ActiveRowIndicatorColor; + + if (_ActiveRowBackground != null) + copy.ActiveRowBackground = _ActiveRowBackground.Copy(); + + if (_DirtyMarkerBackground != null) + copy.DirtyMarkerBackground = _DirtyMarkerBackground.Copy(); + + copy.ActiveRowImage = _ActiveRowImage; + copy.ActiveRowImageIndex = _ActiveRowImageIndex; + + copy.EditingRowImage = _EditingRowImage; + copy.EditingRowImageIndex = _EditingRowImageIndex; + + copy.InfoRowImage = _InfoRowImage; + copy.InfoRowImageIndex = _InfoRowImageIndex; + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + DirtyMarkerBackground = null; + ActiveRowBackground = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/RowVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/RowVisualStyle.cs new file mode 100644 index 00000000..360ffc23 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/RowVisualStyle.cs @@ -0,0 +1,192 @@ +using System; +using System.ComponentModel; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// RowVisualStyles + /// + public class RowVisualStyles : VisualStyles + { + } + + /// + /// RowVisualStyle + /// + public class RowVisualStyle : BaseVisualStyle + { + #region Private variables + + private Background _Background; + private RowHeaderVisualStyle _RowHeaderStyle; + + #endregion + + #region Public properties + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region RowHeaderStyle + + /// + /// Gets or sets the RowHeader Style + /// + [Category("Appearance")] + [Description("Indicates the RowHeader Style.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public RowHeaderVisualStyle RowHeaderStyle + { + get + { + if (_RowHeaderStyle == null) + { + _RowHeaderStyle = RowHeaderVisualStyle.Empty; + + UpdateChangeHandler(null, _RowHeaderStyle); + } + + return (_RowHeaderStyle); + } + + set + { + if (_RowHeaderStyle != value) + { + UpdateChangeHandler(_RowHeaderStyle, value); + + _RowHeaderStyle = value; + + OnPropertyChangedEx("RowHeaderStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(RowVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.Background != null && style.Background.IsEmpty == false) + Background = style.Background.Copy(); + + if (style._RowHeaderStyle != null) + RowHeaderStyle.ApplyStyle(style._RowHeaderStyle); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new RowVisualStyle Copy() + { + RowVisualStyle style = new RowVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(RowVisualStyle copy) + { + base.CopyTo(copy); + + if (_Background != null) + copy.Background = _Background.Copy(); + + if (_RowHeaderStyle != null) + copy.RowHeaderStyle = _RowHeaderStyle.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + RowHeaderStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/TextRowVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/TextRowVisualStyle.cs new file mode 100644 index 00000000..8454d604 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/TextRowVisualStyle.cs @@ -0,0 +1,163 @@ +using System.ComponentModel; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// TextRowVisualStyles + /// + public class TextRowVisualStyles : VisualStyles + { + #region Hidden properties + + #region Empty + + /// + /// Empty + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new TextRowVisualStyle Empty + { + get { return (base.Empty); } + } + + #endregion + + #region NotSelectable + + /// + /// NotSelectable + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new TextRowVisualStyle NotSelectable + { + get { return (base.NotSelectable); } + } + + #endregion + + #endregion + } + + /// + /// TextRowVisualStyle + /// + public class TextRowVisualStyle : CellVisualStyle + { + #region Private variables + + private BaseRowHeaderVisualStyle _RowHeaderStyle; + + #endregion + + #region Public properties + + #region RowHeaderStyle + + /// + /// Gets or sets the RowHeader Style + /// + [Category("Appearance")] + [Description("Indicates the RowHeader Style")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public BaseRowHeaderVisualStyle RowHeaderStyle + { + get + { + if (_RowHeaderStyle == null) + { + _RowHeaderStyle = BaseRowHeaderVisualStyle.Empty; + + UpdateChangeHandler(null, _RowHeaderStyle); + } + + return (_RowHeaderStyle); + } + + set + { + if (_RowHeaderStyle != value) + { + UpdateChangeHandler(_RowHeaderStyle, value); + + _RowHeaderStyle = value; + + OnPropertyChangedEx("RowHeaderStyle", VisualChangeType.Render); + } + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(TextRowVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._RowHeaderStyle != null) + RowHeaderStyle.ApplyStyle(style._RowHeaderStyle); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new TextRowVisualStyle Copy() + { + TextRowVisualStyle copy = new TextRowVisualStyle(); + + CopyTo(copy); + + return (copy); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(TextRowVisualStyle copy) + { + base.CopyTo(copy); + + if (_RowHeaderStyle != null) + copy.RowHeaderStyle = _RowHeaderStyle.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + RowHeaderStyle = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/Thickness.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/Thickness.cs new file mode 100644 index 00000000..f0de76cf --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/Thickness.cs @@ -0,0 +1,543 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Defines Thickness class. + /// + [TypeConverter(typeof(ThicknessTypeConverter))] + public class Thickness : IEquatable, INotifyPropertyChanged + { + #region Static data + + /// + /// Returns Empty instance of Thickness. + /// + public static Thickness Empty + { + get { return (new Thickness(0)); } + } + + #endregion + + #region Private variables + + private int _Bottom; + private int _Left; + private int _Right; + private int _Top; + + #endregion + + #region Constructors + + /// + /// Creates new instance of the object. + /// + /// Left thickness in pixels. + /// Top thickness in pixels. + /// Right thickness in pixels. + /// Bottom thickness in pixels. + public Thickness(int left, int top, int right, int bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + } + + /// + /// Creates new instance of the object. + /// + /// Specifies uniform Thickness. + public Thickness(int all) + : this(all, all, all, all) + { + } + + /// + /// Creates new instance of the object. + /// + public Thickness() + { + } + + #endregion + + #region Public properties + + #region All + + /// + /// Gets or sets the thickness of all sides + /// + //[Browsable(false)] + //[EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int All + { + set { _Top = _Left = _Bottom = _Right = value; } + } + + #endregion + + #region Bottom + + /// + /// Gets or sets the Bottom thickness in pixels. + /// + [DefaultValue(0)] + [Description("Indicates the Bottom thickness in pixels.")] + public int Bottom + { + get { return (_Bottom); } + + set + { + if (_Bottom != value) + { + _Bottom = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Bottom")); + } + } + } + + #endregion + + #region Horizontal + + /// + /// Gets horizontal thickness (Left + Right) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Horizontal + { + get { return (_Left + _Right); } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the item is empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsEmpty + { + get + { + return (_Left == 0 && _Right == 0 && + _Top == 0 && _Bottom == 0); + } + } + + #endregion + + #region Left + + /// + /// Gets or sets the left thickness in pixels + /// + [Browsable(true), DefaultValue(0)] + [Description("Indicates the left thickness in pixels")] + public int Left + { + get { return (_Left); } + + set + { + if (_Left != value) + { + _Left = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Left")); + } + } + } + + #endregion + + #region Right + + /// + /// Gets or sets the Right thickness in pixels + /// + [Browsable(true), DefaultValue(0)] + [Description("Indicates the Right thickness in pixels")] + public int Right + { + get { return (_Right); } + + set + { + if (_Right != value) + { + _Right = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Right")); + } + } + } + + #endregion + + #region Top + + /// + /// Gets or sets the Top thickness in pixels + /// + [Browsable(true), DefaultValue(0)] + [Description("Indicates the Top thickness in pixels")] + public int Top + { + get { return (_Top); } + + set + { + if (_Top != value) + { + _Top = value; + + OnPropertyChanged(new VisualPropertyChangedEventArgs("Top")); + } + } + } + + #endregion + + #region Vertical + + /// + /// Gets vertical thickness (Top + Bottom) + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Vertical + { + get { return (_Top + _Bottom); } + } + + #endregion + + #endregion + + #region Internal properties + + #region IsUniform + + internal bool IsUniform + { + get + { + return (Dpi.Factor.Height == Dpi.Factor.Width && + _Left == _Top && _Left == _Right && _Left == _Bottom); + } + } + + #endregion + + #region IsZero + + internal bool IsZero + { + get + { + return (_Left == 0 && _Top == 0 && + _Right == 0 && _Bottom == 0); + } + } + + #endregion + + #region Size + + internal Size Size + { + get { return (new Size(_Left + _Right, _Top + _Bottom)); } + } + + #endregion + + #endregion + + #region Equals + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to. + /// true if equal otherwise false. + public override bool Equals(object obj) + { + if (obj is Thickness) + return (this == (Thickness)obj); + + return (false); + } + + /// + /// Gets whether two instances are equal. + /// + /// Instance to compare to + /// true if equal otherwise false + public bool Equals(Thickness thickness) + { + return (this == thickness); + } + + #endregion + + #region GetHashCode + + /// + /// Returns hash-code. + /// + /// hash-code + public override int GetHashCode() + { + return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^ + _Right.GetHashCode()) ^ _Bottom.GetHashCode()); + } + + #endregion + + #region Operators + + #region "==" operator + + /// + /// Implements == operator. + /// + /// Object 1 + /// Object 2 + /// true if equals + public static bool operator ==(Thickness t1, Thickness t2) + { + if (ReferenceEquals(t1, t2)) + return (true); + + if (((object)t1 == null) || ((object)t2 == null)) + return (false); + + return (t1._Left == t2._Left && t1._Right == t2._Right && + t1._Top == t2._Top && t1._Bottom == t2._Bottom); + } + + #endregion + + #region "!=" operator + + /// + /// Implements != operator + /// + /// Object 1 + /// Object 2 + /// true if different + public static bool operator !=(Thickness t1, Thickness t2) + { + return ((t1 == t2) == false); + } + + #endregion + + #endregion + + #region Copy + + /// + /// Creates an exact copy of the Thickness. + /// + /// Copy of the Thickness. + public Thickness Copy() + { + Thickness copy = new Thickness(_Left, _Top, _Right, _Bottom); + + return (copy); + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + void OnPropertyChanged(VisualPropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + #endregion + } + + #region ThicknessTypeConverter + + /// + /// ThicknessTypeConverter + /// + public class ThicknessTypeConverter : ExpandableObjectConverter + { + #region CanConvertTo + + /// + /// CanConvertTo + /// + /// + /// + /// + public override bool CanConvertTo( + ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + return (true); + + return (base.CanConvertTo(context, destinationType)); + } + + #endregion + + #region ConvertTo + + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + Thickness t = value as Thickness; + + if (t != null) + { + if (t.IsUniform == true) + return (t.Left.ToString()); + + return (String.Format("{0:d}, {1:d}, {2:d}, {3:d}", + t.Bottom, t.Left, t.Right, t.Top)); + } + } + + return (base.ConvertTo(context, culture, value, destinationType)); + } + + #endregion + + #region CanConvertFrom + + /// + /// CanConvertFrom + /// + /// + /// + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + return (true); + + return (base.CanConvertFrom(context, sourceType)); + } + + #endregion + + #region ConvertFrom + + /// + /// ConvertFrom + /// + /// + /// + /// + /// + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + string[] values = ((string)value).Split(','); + + if (values.Length != 1 && values.Length != 4) + throw new ArgumentException("Invalid value to convert."); + + try + { + int[] v = new int[values.Length]; + + for (int i = 0; i < values.Length; i++) + v[i] = int.Parse(values[i]); + + Thickness t = (values.Length == 1) + ? new Thickness(v[0]) + : new Thickness(v[1], v[3], v[2], v[0]); + + return (t); + } + catch (Exception) + { + throw new ArgumentException("Invalid value to convert."); + } + } + + return base.ConvertFrom(context, culture, value); + } + + #endregion + + #region GetCreateInstanceSupported + + /// + /// GetCreateInstanceSupported + /// + /// + /// + public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region CreateInstance + + /// + /// CreateInstance + /// + /// + /// + /// + public override object CreateInstance( + ITypeDescriptorContext context, IDictionary propertyValues) + { + return (new Thickness((int)propertyValues["Left"], (int)propertyValues["Top"], + (int)propertyValues["Right"], (int)propertyValues["Bottom"])); + } + + #endregion + } + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/TreeButtonVisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/TreeButtonVisualStyle.cs new file mode 100644 index 00000000..aacd8999 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/TreeButtonVisualStyle.cs @@ -0,0 +1,655 @@ +using System; +using System.ComponentModel; +using System.Drawing; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Represents the visual style of a Row. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class BaseTreeButtonVisualStyle : BaseVisualStyle + { + #region Static data + + /// + /// Empty + /// + public static BaseTreeButtonVisualStyle Empty + { + get { return (new BaseTreeButtonVisualStyle()); } + } + + #endregion + + #region Private variables + + private Color _BorderColor = Color.Empty; + private Color _HotBorderColor = Color.Empty; + private Color _LineColor = Color.Empty; + private Color _HotLineColor = Color.Empty; + + private Background _Background; + private Background _HotBackground; + + #endregion + + #region Public properties + + #region Background + + /// + /// Gets or sets the TreeButton background. + /// + [Description("Indicates the TreeButton background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + _Background = null; + } + + #endregion + + #region HotBackground + + /// + /// Gets or sets the Hot background. + /// + [Description("Indicates the Hot background")] + public Background HotBackground + { + get + { + if (_HotBackground == null) + { + _HotBackground = Background.Empty; + + UpdateChangeHandler(null, _HotBackground); + } + + return (_HotBackground); + } + + set + { + if (_HotBackground != value) + { + UpdateChangeHandler(_HotBackground, value); + + _HotBackground = value; + + OnPropertyChangedEx("HotBackground", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeHotBackground() + { + return (_HotBackground != null && _HotBackground.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetHotBackground() + { + HotBackground = null; + } + + #endregion + + #region BorderColor + + /// + /// Gets or sets the border Color + /// + [Category("Appearance")] + [Description("Indicates the border Color.")] + public Color BorderColor + { + get { return (_BorderColor); } + + set + { + if (_BorderColor != value) + { + _BorderColor = value; + + OnPropertyChangedEx("BorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderColor() + { + return (_BorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderColor() + { + BorderColor = Color.Empty; + } + + #endregion + + #region HotBorderColor + + /// + /// Gets or sets the Hot border Color + /// + [Category("Appearance")] + [Description("Indicates the Hot border Color.")] + public Color HotBorderColor + { + get { return (_HotBorderColor); } + + set + { + if (_HotBorderColor != value) + { + _HotBorderColor = value; + + OnPropertyChangedEx("HotBorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeHotBorderColor() + { + return (_HotBorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetHotBorderColor() + { + HotBorderColor = Color.Empty; + } + + #endregion + + #region LineColor + + /// + /// Gets or sets the button interior line Color + /// + [Category("Appearance")] + [Description("Indicates the button interior line Color.")] + public Color LineColor + { + get { return (_LineColor); } + + set + { + if (_LineColor != value) + { + _LineColor = value; + + OnPropertyChangedEx("LineColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeLineColor() + { + return (_LineColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetLineColor() + { + LineColor = Color.Empty; + } + + #endregion + + #region HotLineColor + + /// + /// Gets or sets the Hot button interior line Color + /// + [Category("Appearance")] + [Description("Indicates the Hot button interior line Color.")] + public Color HotLineColor + { + get { return (_HotLineColor); } + + set + { + if (_HotLineColor != value) + { + _HotLineColor = value; + + OnPropertyChangedEx("HotLineColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeHotLineColor() + { + return (_HotLineColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetHotLineColor() + { + HotLineColor = Color.Empty; + } + + #endregion + + #region IsEmpty + + /// + /// IsEmpty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool IsEmpty + { + get + { + return + ((_Background == null || _Background.IsEmpty) && + (_HotBackground == null || _HotBackground.IsEmpty) && + (_BorderColor == Color.Empty && _HotBorderColor == Color.Empty && base.IsEmpty)); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(BaseTreeButtonVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style.BorderColor.IsEmpty == false) + BorderColor = style.BorderColor; + + if (style.HotBorderColor.IsEmpty == false) + HotBorderColor = style.HotBorderColor; + + if (style.Background != null && style.Background.IsEmpty == false) + Background = style.Background.Copy(); + + if (style.HotBackground != null && style.HotBackground.IsEmpty == false) + HotBackground = style.HotBackground.Copy(); + + if (style.LineColor.IsEmpty == false) + LineColor = style.LineColor; + + if (style.HotLineColor.IsEmpty == false) + HotLineColor = style.HotLineColor; + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new BaseTreeButtonVisualStyle Copy() + { + BaseTreeButtonVisualStyle style = new BaseTreeButtonVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(BaseTreeButtonVisualStyle copy) + { + base.CopyTo(copy); + + copy.BorderColor = _BorderColor; + copy.HotBorderColor = _HotBorderColor; + copy.LineColor = _LineColor; + copy.HotLineColor = _HotLineColor; + + if (Background != null) + copy.Background = _Background.Copy(); + + if (HotBackground != null) + copy.HotBackground = _HotBackground.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + HotBackground = null; + + base.Dispose(); + } + + #endregion + } + + /// + /// Represents the visual style of a Row. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(BlankExpandableObjectConverter))] + public class TreeButtonVisualStyle : BaseVisualStyle + { + #region Static data + + /// + /// Empty + /// + public static TreeButtonVisualStyle Empty + { + get { return (new TreeButtonVisualStyle()); } + } + + #endregion + + #region Private variables + + private BaseTreeButtonVisualStyle _ExpandButton; + private BaseTreeButtonVisualStyle _CollapseButton; + + #endregion + + #region Public properties + + #region CollapseButton + + /// + /// Gets or sets the CollapseButton. + /// + [Description("Indicates the CollapseButton")] + public BaseTreeButtonVisualStyle CollapseButton + { + get + { + if (_CollapseButton == null) + { + _CollapseButton = BaseTreeButtonVisualStyle.Empty; + + UpdateChangeHandler(null, _CollapseButton); + } + + return (_CollapseButton); + } + + set + { + if (_CollapseButton != value) + { + UpdateChangeHandler(_CollapseButton, value); + + _CollapseButton = value; + + OnPropertyChangedEx("CollapseButton", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeCollapseButton() + { + return (_CollapseButton != null && _CollapseButton.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetCollapseButton() + { + CollapseButton = null; + } + + #endregion + + #region ExpandButton + + /// + /// Gets or sets the ExpandButton. + /// + [Description("Indicates the ExpandButton")] + public BaseTreeButtonVisualStyle ExpandButton + { + get + { + if (_ExpandButton == null) + { + _ExpandButton = BaseTreeButtonVisualStyle.Empty; + + UpdateChangeHandler(null, _ExpandButton); + } + + return (_ExpandButton); + } + + set + { + if (_ExpandButton != value) + { + UpdateChangeHandler(_ExpandButton, value); + + _ExpandButton = value; + + OnPropertyChangedEx("ExpandButton", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeExpandButton() + { + return (_ExpandButton != null && _ExpandButton.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetExpandButton() + { + ExpandButton = null; + } + + #endregion + + #region IsEmpty + + /// + /// IsEmpty + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool IsEmpty + { + get + { + return + ((_CollapseButton == null || _CollapseButton.IsEmpty) && + (_ExpandButton == null || _ExpandButton.IsEmpty) && base.IsEmpty); + } + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(TreeButtonVisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._CollapseButton != null) + CollapseButton.ApplyStyle(style._CollapseButton); + + if (style._ExpandButton != null) + ExpandButton.ApplyStyle(style._ExpandButton); + } + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new TreeButtonVisualStyle Copy() + { + TreeButtonVisualStyle style = new TreeButtonVisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(TreeButtonVisualStyle copy) + { + base.CopyTo(copy); + + if (_CollapseButton != null) + copy.CollapseButton = _CollapseButton.Copy(); + + if (_ExpandButton != null) + copy.ExpandButton = _ExpandButton.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + CollapseButton = null; + ExpandButton = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/VisualStyle.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/VisualStyle.cs new file mode 100644 index 00000000..22940409 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/VisualStyle.cs @@ -0,0 +1,725 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Represents the visual style of a Row. + /// + [ToolboxItem(false), DesignTimeVisible(false)] + [TypeConverter(typeof(ExpandableObjectConverter))] + public class VisualStyle : BaseVisualStyle + { + #region Private variables + + private Background _Background; + private BorderColor _BorderColor; + private BorderPattern _BorderPattern; + private Thickness _BorderThickness; + + private Color _TextColor = Color.Empty; + + private Padding _Margin; + private Padding _Padding; + + private Font _Font; + + #endregion + + #region Public properties + + #region Background + + /// + /// Gets or sets the style background. + /// + [Description("Indicates the style background")] + public Background Background + { + get + { + if (_Background == null) + { + _Background = Background.Empty; + + UpdateChangeHandler(null, _Background); + } + + return (_Background); + } + + set + { + if (_Background != value) + { + UpdateChangeHandler(_Background, value); + + _Background = value; + + OnPropertyChangedEx("Background", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBackground() + { + return (_Background != null && _Background.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBackground() + { + Background = null; + } + + #endregion + + #region BorderColor + + /// + /// Gets or sets the style border color. + /// + [Description("Indicates the style Border Color")] + public BorderColor BorderColor + { + get + { + if (_BorderColor == null) + { + _BorderColor = BorderColor.Empty; + + UpdateChangeHandler(null, _BorderColor); + } + + return (_BorderColor); + } + + set + { + if (_BorderColor != value) + { + UpdateChangeHandler(_BorderColor, value); + + _BorderColor = value; + + OnPropertyChangedEx("BorderColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderColor() + { + return (_BorderColor != null && _BorderColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderColor() + { + BorderColor = null; + } + + #endregion + + #region BorderPattern + + /// + /// Gets or sets the style border pattern (Solid, Dash, ...) + /// + [Description("Indicates the style border pattern (Solid, Dash, ...)")] + public BorderPattern BorderPattern + { + get + { + if (_BorderPattern == null) + { + _BorderPattern = BorderPattern.Empty; + + UpdateChangeHandler(null, _BorderPattern); + } + + return (_BorderPattern); + } + + set + { + if (_BorderPattern != value) + { + UpdateChangeHandler(_BorderPattern, value); + + _BorderPattern = value; + + OnPropertyChangedEx("BorderPattern", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderPattern() + { + return (_BorderPattern != null && _BorderPattern.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderPattern() + { + BorderPattern = null; + } + + #endregion + + #region BorderThickness + + /// + /// Gets or sets the style border thickness. + /// + [Description("Indicates the style border thickness")] + public Thickness BorderThickness + { + get + { + if (_BorderThickness == null) + { + _BorderThickness = Thickness.Empty; + + UpdateChangeHandler(null, _BorderThickness); + } + + return (_BorderThickness); + } + + set + { + if (_BorderThickness != value) + { + UpdateChangeHandler(_BorderThickness, value); + + _BorderThickness = value; + + OnPropertyChangedEx("BorderThickness", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeBorderThickness() + { + return (_BorderThickness != null && _BorderThickness.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetBorderThickness() + { + BorderThickness = null; + } + + #endregion + + #region Font + + /// + /// Gets or sets the style Font + /// + [DefaultValue(null)] + [Description("Indicates the style Font")] + public Font Font + { + get { return (_Font); } + + set + { + if (_Font != value) + { + _Font = value; + + OnPropertyChangedEx("Font", VisualChangeType.Layout); + } + } + } + + #endregion + + #region IsEmpty + + /// + /// Gets whether the style is logically Empty. + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Gets whether the style is logically Empty.")] + public override bool IsEmpty + { + get + { + return ((_Background == null || _Background.IsEmpty == true) && + (_BorderColor == null || _BorderColor.IsEmpty == true) && + (_BorderPattern == null || _BorderPattern.IsEmpty == true) && + (_BorderThickness == null || _BorderThickness.IsEmpty == true) && + (_Margin == null || _Margin.IsEmpty == true) && + (_Padding == null || _Padding.IsEmpty == true) && + (_Font == null) && + (_TextColor.IsEmpty == true || _TextColor == Color.Black) && + + (base.IsEmpty == true)); } + } + + #endregion + + #region Margin + + /// + /// Gets or sets the spacing between the border and outside content. + /// + [Description("Indicates the spacing between the border and outside content")] + public Padding Margin + { + get + { + if (_Margin == null) + { + _Margin = Padding.Empty; + + UpdateChangeHandler(null, _Margin); + } + + return (_Margin); + } + + set + { + if (_Margin != value) + { + UpdateChangeHandler(_Margin, value); + + _Margin = value; + + OnPropertyChangedEx("Margin", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeMargin() + { + return (_Margin != null && _Margin.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetMargin() + { + Margin = null; + } + + #endregion + + #region Padding + + /// + /// Gets or sets spacing between the content and edges of the element. + /// + [Description("Indicates the spacing between the content and edges of the element")] + public Padding Padding + { + get + { + if (_Padding == null) + { + _Padding = Padding.Empty; + + UpdateChangeHandler(null, _Padding); + } + + return (_Padding); + } + + set + { + if (_Padding != value) + { + UpdateChangeHandler(_Padding, value); + + _Padding = value; + + OnPropertyChangedEx("Padding", VisualChangeType.Layout); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializePadding() + { + return (_Padding != null && _Padding.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetPadding() + { + Padding = null; + } + + #endregion + + #region TextColor + + /// + /// Gets or sets the Text color + /// + [Description("Indicates the Text color")] + public Color TextColor + { + get { return (_TextColor); } + + set + { + if (_TextColor != value) + { + _TextColor = value; + + OnPropertyChangedEx("TextColor", VisualChangeType.Render); + } + } + } + + /// + /// Gets whether property should be serialized. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private bool ShouldSerializeTextColor() + { + return (_TextColor.IsEmpty == false); + } + + /// + /// Resets property to its default value. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + private void ResetTextColor() + { + _TextColor = Color.Empty; + } + + #endregion + + #endregion + + #region ApplyStyle + + /// + /// Applies the style to instance of this style. + /// + /// Style to apply. + public void ApplyStyle(VisualStyle style) + { + if (style != null) + { + base.ApplyStyle(style); + + if (style._Background != null && style._Background.IsEmpty == false) + Background = style._Background.Copy(); + + if (style._BorderColor != null && style._BorderColor.IsEmpty == false) + BorderColor = style._BorderColor.Copy(); + + if (style._BorderPattern != null && style._BorderPattern.IsEmpty == false) + BorderPattern.ApplyPattern(style._BorderPattern); + + if (style._BorderThickness != null && style._BorderThickness.IsZero == false) + BorderThickness = style._BorderThickness.Copy(); + + if (style.Font != null) + Font = style.Font; + + if (style._Margin != null && style._Margin.IsEmpty == false) + Margin = style.Margin.Copy(); + + if (style._Padding != null && style._Padding.IsEmpty == false) + Padding = style.Padding.Copy(); + + if (style._TextColor.IsEmpty == false) + TextColor = style._TextColor; + } + } + + #endregion + + #region RenderBorder + + internal void RenderBorder(Graphics g, Rectangle r) + { + if (_BorderPattern == null || BorderThickness == null || BorderColor == null) + return; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + if (BorderColor.IsUniform == true && + BorderThickness.IsUniform == true && BorderPattern.IsUniform == true) + { + if (_BorderPattern.Top != LinePattern.None && + (_BorderThickness.Top > 0 && _BorderColor.Top.IsEmpty == false)) + { + using (Pen pen = new + Pen(_BorderColor.Top, Dpi.Width(_BorderThickness.Top))) + { + LinePattern pattern = (_BorderPattern.Top == LinePattern.NotSet) + ? LinePattern.Solid : _BorderPattern.Top; + + if (pen.Width == 1) + { + r.Width--; + r.Height--; + } + else + { + pen.Alignment = PenAlignment.Inset; + } + + pen.DashStyle = (DashStyle)pattern; + + g.DrawRectangle(pen, r); + } + } + } + else + { + Pen[] pens = GetBorderPens(); + + if (pens[(int) BorderSide.Right] != null) + { + int right = r.Right - + (Dpi.Width(_BorderThickness.Right) + 1) / 2; + + g.DrawLine(pens[(int)BorderSide.Right], + right, r.Top, right, r.Bottom - 1); + } + + if (pens[(int) BorderSide.Bottom] != null) + { + int bottom = r.Bottom - + (Dpi.Height(_BorderThickness.Bottom) + 1) / 2; + + g.DrawLine(pens[(int)BorderSide.Bottom], + r.X, bottom, r.Right - 1, bottom); + } + + if (pens[(int)BorderSide.Left] != null) + { + int left = r.Left + Dpi.Width(_BorderThickness.Left) / 2; + + g.DrawLine(pens[(int)BorderSide.Left], + left, r.Top, left, r.Bottom - 1); + } + + if (pens[(int)BorderSide.Top] != null) + { + int top = r.Top + Dpi.Height(_BorderThickness.Top) / 2; + + g.DrawLine(pens[(int) BorderSide.Top], + r.X, top, r.Right - 1, top); + } + + foreach (Pen pen in pens) + { + if (pen != null) + pen.Dispose(); + } + } + + g.SmoothingMode = sm; + } + + #endregion + + #region GetBorderSize + + internal Size GetBorderSize(bool inclPadding) + { + Size size = Size.Empty; + + size.Width += (BorderThickness.Horizontal + Margin.Horizontal); + size.Height += (BorderThickness.Vertical + Margin.Vertical); + + if (inclPadding == true) + { + size.Width += Padding.Horizontal; + size.Height += Padding.Vertical; + } + + return (Dpi.Size(size)); + } + + #endregion + + #region GetBorderPens + + internal Pen[] GetBorderPens() + { + Pen[] pens = new Pen[4]; + + pens[(int)BorderSide.Top] = GetBorderPen(pens, + BorderColor.Top, Dpi.Height(BorderThickness.Top), BorderPattern.Top); + + pens[(int)BorderSide.Left] = GetBorderPen(pens, + BorderColor.Left, Dpi.Width(BorderThickness.Left), BorderPattern.Left); + + pens[(int)BorderSide.Bottom] = GetBorderPen(pens, + BorderColor.Bottom, Dpi.Height(BorderThickness.Bottom), BorderPattern.Bottom); + + pens[(int)BorderSide.Right] = GetBorderPen(pens, + BorderColor.Right, Dpi.Width(BorderThickness.Right), BorderPattern.Right); + + return (pens); + } + + #endregion + + #region GetBorderPen + + private Pen GetBorderPen(IEnumerable pens, + Color color, int width, LinePattern pattern) + { + if (color.IsEmpty == true || + pattern == LinePattern.None || width <= 0) + { + return (null); + } + + foreach (Pen pen in pens) + { + if (pen != null) + { + if (pen.Color == color && pen.Width == width && + pen.DashStyle == (DashStyle)pattern) + { + return (pen); + } + } + } + + Pen npen = new Pen(color, width); + + if (pattern == LinePattern.NotSet) + pattern = LinePattern.Solid; + + npen.DashStyle = (DashStyle)pattern; + + return (npen); + } + + #endregion + + #region Copy + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public new VisualStyle Copy() + { + VisualStyle style = new VisualStyle(); + + CopyTo(style); + + return (style); + } + + #endregion + + #region CopyTo + + /// + /// Returns the copy of the style. + /// + /// Copy of the style. + public void CopyTo(VisualStyle copy) + { + base.CopyTo(copy); + + copy.TextColor = _TextColor; + + if (_Background != null) + copy.Background = _Background.Copy(); + + if (_BorderColor != null) + copy.BorderColor = _BorderColor.Copy(); + + if (_BorderPattern != null) + copy.BorderPattern = _BorderPattern.Copy(); + + if (_BorderPattern != null) + copy.BorderPattern = _BorderPattern.Copy(); + + if (_BorderThickness != null) + copy.BorderThickness = _BorderThickness.Copy(); + + if (_Font != null) + copy.Font = (Font)_Font.Clone(); + + if (_Margin != null) + copy.Margin = _Margin.Copy(); + + if (_Padding != null) + copy.Padding = _Padding.Copy(); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public override void Dispose() + { + Background = null; + BorderColor = null; + BorderPattern = null; + BorderThickness = null; + Margin = null; + Padding = null; + + base.Dispose(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/VisualStyles.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/VisualStyles.cs new file mode 100644 index 00000000..116157fd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/Style/VisualStyles.cs @@ -0,0 +1,511 @@ +using System; +using System.ComponentModel; +using System.Globalization; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// VisualStyles + /// + [TypeConverter(typeof(VisualStylesConverter))] + public class VisualStyles : IDisposable, INotifyPropertyChanged where T : BaseVisualStyle, new() + { + #region Private variables + + private T[] _Styles; + + #endregion + + /// + /// Constructor + /// + public VisualStyles() + { + _Styles = new T[Enum.GetValues(typeof(StyleType)).Length - 1]; + } + + #region Public properties + + #region Indexer + + /// + /// Gets or sets the visual style + /// assigned to the element. Default value is null. + /// + [DefaultValue(null), Category("Style")] + [Description("Indicates visual style assigned to the element")] + public T this[StyleType e] + { + get + { + int n = ((IConvertible)e).ToInt32(null); + + if (n < 0 || n > _Styles.Length) + throw new Exception("Invalid Style indexer"); + + return (GetStyle(n)); + } + + set + { + int n = ((IConvertible)e).ToInt32(null); + + if (n < 0 || n > _Styles.Length) + throw new Exception("Invalid Style indexer"); + + SetStyle(n, value); + } + } + + #endregion + + #region Default + + /// + /// The normal, default style + /// + [Description("Style to use for normal, default items")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T Default + { + get { return (GetStyle((int) StyleType.Default)); } + set { SetStyle((int) StyleType.Default, value); } + } + + #endregion + + #region Empty + + /// + /// Style to use when a cell item is empty + /// + [Description("Style to use when a cell item is empty")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T Empty + { + get { return (GetStyle((int)StyleType.Empty)); } + set { SetStyle((int)StyleType.Empty, value); } + } + + #endregion + + #region MouseOver + + /// + /// MouseOver + /// + [Description("Style to use when the Mouse is over an item")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T MouseOver + { + get { return (GetStyle((int)StyleType.MouseOver)); } + set { SetStyle((int)StyleType.MouseOver, value); } + } + + #endregion + + #region NotSelectable + + /// + /// Style to use for non-selectable items + /// + [Description("Style to use for non-selectable items")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T NotSelectable + { + get { return (GetStyle((int)StyleType.NotSelectable)); } + set { SetStyle((int)StyleType.NotSelectable, value); } + } + + #endregion + + #region Selected + + /// + /// Style to use for selected items. + /// + [Description("Style to use for selected items.")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T Selected + { + get { return (GetStyle((int)StyleType.Selected)); } + set { SetStyle((int)StyleType.Selected, value); } + } + + #endregion + + #region SelectedMouseOver + + /// + /// Style to use for MouseOver selected items + /// + [Description("Style to use for MouseOver selected items")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T SelectedMouseOver + { + get { return (GetStyle((int)StyleType.SelectedMouseOver)); } + set { SetStyle((int)StyleType.SelectedMouseOver, value); } + } + + #endregion + + #region ReadOnly + + /// + /// Style to use for ReadOnly items + /// + [Description("Style to use for ReadOnly items.")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T ReadOnly + { + get { return (GetStyle((int)StyleType.ReadOnly)); } + set { SetStyle((int)StyleType.ReadOnly, value); } + } + + #endregion + + #region ReadOnlyMouseOver + + /// + /// Style to use for ReadOnly, MouseOver items + /// + [Description("Style to use for ReadOnly, MouseOver items.")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T ReadOnlyMouseOver + { + get { return (GetStyle((int)StyleType.ReadOnlyMouseOver)); } + set { SetStyle((int)StyleType.ReadOnlyMouseOver, value); } + } + + #endregion + + #region ReadOnlySelected + + /// + /// ReadOnlySelected + /// + [Description("Style to use for ReadOnly, Selected items.")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T ReadOnlySelected + { + get { return (GetStyle((int)StyleType.ReadOnlySelected)); } + set { SetStyle((int)StyleType.ReadOnlySelected, value); } + } + + #endregion + + #region ReadOnlySelectedMouseOver + + /// + /// Style to use for ReadOnly, Selected, MouseOver items + /// + [Description("Style to use for ReadOnly, Selected, MouseOver items.")] + [TypeConverter(typeof(VisualStylesConverter))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public T ReadOnlySelectedMouseOver + { + get { return (GetStyle((int)StyleType.ReadOnlySelectedMouseOver)); } + set { SetStyle((int)StyleType.ReadOnlySelectedMouseOver, value); } + } + + #endregion + + #region Styles + + /// + /// Styles array + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public T[] Styles + { + get { return (_Styles); } + } + + #endregion + + #endregion + + #region GetStyle + + private T GetStyle(int n) + { + if (_Styles[n] == null) + { + _Styles[n] = new T(); + + OnStyleChangeHandler(null, _Styles[n]); + } + + return (_Styles[n]); + } + + #endregion + + #region SetStyle + + private void SetStyle(int n, T value) + { + if (_Styles[n] != value) + { + T oldValue = _Styles[n]; + + _Styles[n] = value; + + OnStyleChanged(Enum.GetName(typeof(StyleType), n), oldValue, value); + } + } + + #endregion + + #region OnStyleChanged + + private void OnStyleChanged( + string property, T oldValue, T newValue) + { + OnStyleChangeHandler(oldValue, newValue); + + OnPropertyChanged(new VisualPropertyChangedEventArgs(property)); + } + + #endregion + + #region IsValid + + internal bool IsValid(Enum e) + { + int n = ((IConvertible) e).ToInt32(null); + + if (n < 0 || n > _Styles.Length) + throw new Exception("Invalid Style indexer"); + + return (_Styles[n] != null); + } + + #endregion + + #region Style support routines + + #region StyleVisualChangeHandler + + private void OnStyleChangeHandler(T oldValue, T newValue) + { + if (oldValue != null) + oldValue.PropertyChanged -= StyleChanged; + + if (newValue != null) + newValue.PropertyChanged += StyleChanged; + } + + #endregion + + #region StyleChanged + + /// + /// Occurs when one of element visual styles has property changes. + /// Default implementation invalidates visual appearance of element. + /// + /// VisualStyle that changed. + /// Event arguments. + protected virtual void StyleChanged(object sender, PropertyChangedEventArgs e) + { + OnPropertyChanged(e); + } + + #endregion + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler eh = PropertyChanged; + + if (eh != null) + eh(this, e); + } + + #endregion + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + for (int i = 0; i < _Styles.Length; i++) + { + T style = _Styles[i]; + + if (style != null) + { + SetStyle(i, null); + + style.Dispose(); + } + } + + _Styles = null; + } + + #endregion + } + + #region enums + + #region StyleType + + /// + /// StyleType + /// + public enum StyleType + { + /// + /// CellStyle is Not Set + /// + NotSet = -1, + + /// + /// Default + /// + Default = 0, + + /// + /// MouseOver + /// + MouseOver, + + /// + /// Selected + /// + Selected, + + /// + /// SelectedMouseOver + /// + SelectedMouseOver, + + /// + /// ReadOnly + /// + ReadOnly, + + /// + /// ReadOnlyMouseOver + /// + ReadOnlyMouseOver, + + /// + /// ReadOnlySelected + /// + ReadOnlySelected, + + /// + /// ReadOnlySelectedMouseOver + /// + ReadOnlySelectedMouseOver, + + /// + /// Empty, non-populated cell + /// + Empty, + + /// + /// Empty, mouseOver non-populated cell + /// + EmptyMouseOver, + + /// + /// Empty, MouseOver, Selected, non-populated cell + /// + EmptyMouseOverSelected, + + /// + /// Not Selectable cell + /// + NotSelectable, + } + + #endregion + + #region StyleState + + /// + /// StyleState + /// + [Flags] + public enum StyleState + { + /// + /// Default + /// + Default = 0, + + /// + /// MouseOver + /// + MouseOver = (1 << 0), + + /// + /// Selected + /// + Selected = (1 << 1), + + /// + /// ReadOnly + /// + ReadOnly = (1 << 2), + } + + #endregion + + #endregion + + #region VisualStylesConverter + + /// + /// VisualStylesConverter + /// + public class VisualStylesConverter : ExpandableObjectConverter + { + /// + /// ConvertTo + /// + /// + /// + /// + /// + /// + public override object ConvertTo( + ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + return (" "); + + return (base.ConvertTo(context, culture, value, destinationType)); + } + } + + #endregion + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SuperGridControl.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SuperGridControl.cs new file mode 100644 index 00000000..561d3dbe --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/SuperGridControl.cs @@ -0,0 +1,20020 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Media; +using System.Runtime.InteropServices; +using System.Threading; +using System.Windows.Forms; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.ScrollBar; +using DevComponents.DotNetBar.SuperGrid.Style; +using DevComponents.SuperGrid.TextMarkup; +using Timer = System.Windows.Forms.Timer; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// Represents a Super Grid Control. + /// + [ToolboxItem(true), ToolboxBitmap(typeof(SuperGridControl), "SuperGridControl.png")] + [Designer("DevComponents.SuperGrid.Design.SuperGridDesigner, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=26d81176cfa2b486")] + public class SuperGridControl : Control, INotifyPropertyChanged, IMessageFilter, IOwnerLocalize + { + #region Events + + #region ActiveGridChanged + + /// + /// Occurs when the active grid changes + /// + [Description("Occurs when the active grid changes.")] + public event EventHandler ActiveGridChanged; + + #endregion + + #region CellActivated + + /// + /// Occurs when a cell has been made the Active Cell + /// + [Description("Occurs when a cell has been made the Active Cell.")] + public event EventHandler CellActivated; + + #endregion + + #region CellActivating + + /// + /// Occurs when a cell is about to be made the Active Cell + /// + [Description("Occurs when a cell is about to be made the Active Cell.")] + public event EventHandler CellActivating; + + #endregion + + #region CellClick + + /// + /// Occurs when a cell has been clicked + /// + [Description("Occurs when a cell has been clicked.")] + public event EventHandler CellClick; + + #endregion + + #region CellDoubleClick + + /// + /// Occurs when a cell has been double clicked + /// + [Description("Occurs when a cell has been double clicked.")] + public event EventHandler CellDoubleClick; + + #endregion + + #region CellInfoClick + + /// + /// Occurs when a cell InfoImage has been clicked + /// + [Description("Occurs when a cell InfoImage has been clicked.")] + public event EventHandler CellInfoClick; + + #endregion + + #region CellInfoDoubleClick + + /// + /// Occurs when a cell InfoImage has been double clicked + /// + [Description("Occurs when a cell InfoImage has been double clicked.")] + public event EventHandler CellInfoDoubleClick; + + #endregion + + #region CellInfoEnter + + /// + /// Occurs when a Cell InfoImage has been entered via the mouse + /// + [Description("Occurs when a Cell InfoImage has been entered via the mouse.")] + public event EventHandler CellInfoEnter; + + #endregion + + #region CellInfoLeave + + /// + /// Occurs when a Cell InfoImage has been exited via the mouse + /// + [Description("Occurs when a Cell InfoImage has been exited via the mouse.")] + public event EventHandler CellInfoLeave; + + #endregion + + #region CellMouseDown + + /// + /// Occurs when a mouse button is pressed + /// while the mouse pointer is within a cell + /// + [Description("Occurs when a mouse button is pressed while the mouse pointer is within a cell.")] + public event EventHandler CellMouseDown; + + #endregion + + #region CellMouseEnter + + /// + /// Occurs when the mouse pointer enters a cell + /// + [Description("Occurs when the mouse pointer enters a cell.")] + public event EventHandler CellMouseEnter; + + #endregion + + #region CellMouseLeave + + /// + /// Occurs when the mouse pointer leaves a cell + /// + [Description("Occurs when the mouse pointer leaves a cell.")] + public event EventHandler CellMouseLeave; + + #endregion + + #region CellMouseMove + + /// + /// Occurs when the mouse pointer moves within a cell + /// + [Description("Occurs when the mouse pointer leaves a cell.")] + public event EventHandler CellMouseMove; + + #endregion + + #region CellMouseUp + + /// + /// Occurs when a mouse button is released + /// while the mouse pointer is within a cell + /// + [Description("Occurs when a mouse button is released while the mouse pointer is within a cell.")] + public event EventHandler CellMouseUp; + + #endregion + + #region CellValidating + + /// + /// Occurs when a cell needs validating + /// + [Description("Occurs when a cell needs validating.")] + public event EventHandler CellValidating; + + #endregion + + #region CellValidated + + /// + /// Occurs when a cell has finished validating + /// + [Description("Occurs when a cell has finished validating.")] + public event EventHandler CellValidated; + + #endregion + + #region Check events + + /// + /// Occurs when a row check state is about to change + /// + [Description("Occurs when a row check state is about to change.")] + public event EventHandler BeforeCheck; + + /// + /// Occurs when a row check state has changed + /// + [Description("Occurs when a row check state has changed.")] + public event EventHandler AfterCheck; + + #endregion + + #region Collapse events + + /// + /// Occurs when a row is about to collapse + /// + [Description("Occurs when a row is about to collapse.")] + public event EventHandler BeforeCollapse; + + /// + /// Occurs when a row has just been collapsed + /// + [Description("Occurs when a row has just been collapsed.")] + public event EventHandler AfterCollapse; + + #endregion + + #region CellUserFunction + + /// + /// Occurs when a cell User function needs evaluated + /// + [Description("Occurs when a cell User function needs evaluated.")] + public event EventHandler CellUserFunction; + + #endregion + + #region CellValueChanged + + /// + /// Occurs when any cell Value changes + /// + [Description("Occurs when any cell Value changes.")] + public event EventHandler CellValueChanged; + + #endregion + + #region ColumnGrouped + + /// + /// Occurs when a column has been Grouped + /// + [Description("Occurs when a column has been Grouped.")] + public event EventHandler ColumnGrouped; + + #endregion + + #region ColumnHeaderClick + + /// + /// Occurs when a column header has been clicked + /// + [Description("Occurs when a column header has been clicked.")] + public event EventHandler ColumnHeaderClick; + + #endregion + + #region ColumnHeaderDoubleClick + + /// + /// Occurs when a column header has been double clicked + /// + [Description("Occurs when a column header has been double clicked.")] + public event EventHandler ColumnHeaderDoubleClick; + + #endregion + + #region ColumnHeaderMarkupLinkClick + + /// + /// Occurs when a GridColumn Header has a MarkupLink that has been clicked + /// + [Description("Occurs when a GridColumn Header has a MarkupLink that has been clicked.")] + public event EventHandler ColumnHeaderMarkupLinkClick; + + #endregion + + #region ColumnHeaderMouseDown + + /// + /// Occurs when a mouse button is pressed + /// while the mouse pointer is within the Column Header + /// + [Description("Occurs when a mouse button is pressed while the mouse pointer is within the Column Header.")] + public event EventHandler ColumnHeaderMouseDown; + + #endregion + + #region ColumnHeaderMouseEnter + + /// + /// Occurs when the mouse pointer enters the Column Header + /// + [Description("Occurs when the mouse pointer enters the Column Header.")] + public event EventHandler ColumnHeaderMouseEnter; + + #endregion + + #region ColumnHeaderMouseLeave + + /// + /// Occurs when the mouse pointer leaves the Column Header + /// + [Description("Occurs when the mouse pointer leaves the Column Header.")] + public event EventHandler ColumnHeaderMouseLeave; + + #endregion + + #region ColumnHeaderMouseMove + + /// + /// Occurs when the mouse pointer moves within the Column Header + /// + [Description("Occurs when the mouse pointer leaves the Column Header.")] + public event EventHandler ColumnHeaderMouseMove; + + #endregion + + #region ColumnHeaderMouseUp + + /// + /// Occurs when a mouse button is released + /// while the mouse pointer is within the Column Header + /// + [Description("Occurs when a mouse button is released while the mouse pointer is within the Column Header.")] + public event EventHandler ColumnHeaderMouseUp; + + #endregion + + #region ColumnGroupHeaderClick + + /// + /// Occurs when a column GroupHeader has been clicked + /// + [Description("Occurs when a column GroupHeader has been clicked.")] + public event EventHandler ColumnGroupHeaderClick; + + #endregion + + #region ColumnGroupHeaderDoubleClick + + /// + /// Occurs when a column GroupHeader has been double clicked + /// + [Description("Occurs when a column GroupHeader has been double clicked.")] + public event EventHandler ColumnGroupHeaderDoubleClick; + + #endregion + + #region ColumnGroupHeaderMarkupLinkClick + + /// + /// Occurs when a GridColumn GroupHeader has a MarkupLink that has been clicked + /// + [Description("Occurs when a GridColumn GroupHeader has a MarkupLink that has been clicked.")] + public event EventHandler ColumnGroupHeaderMarkupLinkClick; + + #endregion + + #region ColumnResized + + /// + /// Occurs when a column GroupHeader has been resized + /// + [Description("Occurs when a column GroupHeader has been resized.")] + public event EventHandler ColumnGroupHeaderResized; + + #endregion + + #region ColumnMoved + + /// + /// Occurs when a column has been moved or reordered + /// + [Description("Occurs when a column has been moved or reordered.")] + public event EventHandler ColumnMoved; + + #endregion + + #region ColumnResized + + /// + /// Occurs when a column has been resized + /// + [Description("Occurs when a column has been resized.")] + public event EventHandler ColumnResized; + + #endregion + + #region ColumnRowHeaderClick + + /// + /// Occurs when a column RowHeader has been clicked + /// + [Description("Occurs when a column RowHeader has been clicked.")] + public event EventHandler ColumnRowHeaderClick; + + #endregion + + #region ColumnRowHeaderDoubleClick + + /// + /// Occurs when a column RowHeader has been double clicked + /// + [Description("Occurs when a column RowHeader has been double clicked.")] + public event EventHandler ColumnRowHeaderDoubleClick; + + #endregion + + #region CompareElements + + /// + /// Occurs when the grid needs to compare 1 element with another + /// + [Description("Occurs when the grid needs to compare 1 element with another.")] + public event EventHandler CompareElements; + + #endregion + + #region DataBindingStart + + /// + /// Occurs when the grid is about to start a nested binding operation + /// + [Description("Occurs when the grid is about to start a nested binding operation.")] + public event EventHandler DataBindingStart; + + #endregion + + #region DataBindingComplete + + /// + /// Occurs when a grid's data binding is complete + /// + [Description("Occurs when a grid's data binding is complete.")] + public event EventHandler DataBindingComplete; + + #endregion + + #region DataError + + /// + /// Occurs when an error is encountered while dealing with data + /// + [Description("Occurs when an error is encountered while dealing with data.")] + public event EventHandler DataError; + + #endregion + + #region DataFilteringStart + + /// + /// Occurs when the grid is about to start a data filtering operation + /// + [Description("Occurs when the grid is about to start a data filtering operation.")] + public event EventHandler DataFilteringStart; + + #endregion + + #region DataFilteringComplete + + /// + /// Occurs when a grid's data Filtering is complete + /// + [Description("Occurs when a grid's data filtering is complete.")] + public event EventHandler DataFilteringComplete; + + #endregion + + #region ItemDrag + + /// + /// Occurs when a user begins dragging an item + /// + [Description("Occurs when a user begins dragging an item.")] + public event EventHandler ItemDrag; + + #endregion + + #region Editor events + + #region BeginEdit + + /// + /// Occurs when a modal cell edit is about to begin + /// + [Description("Occurs when a modal cell edit is about to begin.")] + public event EventHandler BeginEdit; + + #endregion + + #region CancelEdit + + /// + /// Occurs when a modal cell edit has been canceled + /// + [Description("Occurs when a modal cell edit has been canceled.")] + public event EventHandler CancelEdit; + + #endregion + + #region CloseEdit + + /// + /// Occurs when a modal cell edit has closed + /// + [Description("Occurs when a modal cell edit has closed.")] + public event EventHandler CloseEdit; + + #endregion + + #region EditorValueChanged + + /// + /// Occurs when a cell editor value has changed + /// + [Description("Occurs when a cell editor value has changed.")] + public event EventHandler EditorValueChanged; + + #endregion + + #region EndEdit + + /// + /// Occurs when a modal cell edit is ending + /// + [Description("Occurs when a modal cell edit is ending.")] + public event EventHandler EndEdit; + + #endregion + + #region GetEditor + + /// + /// Occurs when a cell editor is needed + /// + [Description("Occurs when a cell editor is needed.")] + public event EventHandler GetEditor; + + #endregion + + #region GetRenderer + + /// + /// Occurs when a cell renderer is needed + /// + [Description("Occurs when a cell renderer is needed.")] + public event EventHandler GetRenderer; + + #endregion + + #region InitEditContext + + /// + /// Occurs when a cell editor needs it's context initialized + /// + [Description("Occurs when a cell editor needs it's context initialized.")] + public event EventHandler InitEditContext; + + #endregion + + #endregion + + #region Expand events + + /// + /// Occurs when a row is about to be expanded + /// + [Description("Occurs when a row is about to be expanded.")] + public event EventHandler BeforeExpand; + + /// + /// Occurs when a row has just been expanded + /// + [Description("Occurs when a row has just been expanded.")] + public event EventHandler AfterExpand; + + #endregion + + #region Filter events + + #region FilterBeginEdit + + /// + /// Occurs when a column filter edit is about to begin + /// + [Description("Occurs when a column filter edit is about to begin.")] + public event EventHandler FilterBeginEdit; + + #endregion + + #region FilterCancelEdit + + /// + /// Occurs when a column filter edit has been canceled + /// + [Description("Occurs when a column filter edit has been canceled.")] + public event EventHandler FilterCancelEdit; + + #endregion + + #region FilterColumnError + + /// + /// Occurs when a column filter error has occurred + /// + [Description("Occurs when a column filter error has ocurred.")] + public event EventHandler FilterColumnError; + + #endregion + + #region FilterEditValueChanged + + /// + /// Occurs when a filter edit value has changed + /// + [Description("Occurs when a filter edit value has changed.")] + public event EventHandler FilterEditValueChanged; + + #endregion + + #region FilterEndEdit + + /// + /// Occurs when a column filter edit has ended + /// + [Description("Occurs when a column filter edit has ended.")] + public event EventHandler FilterEndEdit; + + #endregion + + #region FilterHeaderClick + + /// + /// Occurs when a Filter header has been clicked + /// + [Description("Occurs when a Filter header has been clicked.")] + public event EventHandler FilterHeaderClick; + + #endregion + + #region FilterHelpClosing + + /// + /// Occurs when a filter expression help window is about to close + /// + [Description("Occurs when a filter expression help window is about to close.")] + public event EventHandler FilterHelpClosing; + + #endregion + + #region FilterHelpOpening + + /// + /// Occurs when a filter expression help window is about to open + /// + [Description("Occurs when a filter expression help window is about to open.")] + public event EventHandler FilterHelpOpening; + + #endregion + + #region FilterItemsLoaded + + /// + /// Occurs following the loading of the items in the + /// ComboBox, when a ComboBox filter edit is about to begin + /// + [Description("Occurs following the loading of the items in the ComboBox, when a ComboBox filter edit is about to begin.")] + public event EventHandler FilterItemsLoaded; + + #endregion + + #region FilterLoadItems + + /// + /// Occurs when a ComboBox filter edit is about to begin + /// and the items in the comboBox need to be loaded + /// + [Description("Occurs when a ComboBox filter edit is about to begin and the items in the comboBox need to be loaded.")] + public event EventHandler FilterLoadItems; + + #endregion + + #region FilterLoadUserData + + /// + /// Occurs when user defined Filter data needs to be loaded + /// + [Description("Occurs when user defined Filter data needs to be loaded.")] + public event EventHandler FilterLoadUserData; + + #endregion + + #region FilterPopupClosing + + /// + /// Occurs when a column filter menu is closing + /// + [Description("Occurs when a column filter menu is closing.")] + public event EventHandler FilterPopupClosing; + + #endregion + + #region FilterPopupLoad + + /// + /// Occurs when a column filter menu needs loaded + /// + [Description("Occurs when a column filter menu needs loaded.")] + public event EventHandler FilterPopupLoad; + + #endregion + + #region FilterPopupLoaded + + /// + /// Occurs after a column filter menu has been loaded + /// + [Description("Occurs after a column filter menu has been loaded.")] + public event EventHandler FilterPopupLoaded; + + #endregion + + #region FilterPopupOpening + + /// + /// Occurs when a column filter menu is about to open + /// + [Description("Occurs when a column filter menu is about to open.")] + public event EventHandler FilterPopupOpening; + + #endregion + + #region FilterPopupValueChanged + + /// + /// Occurs when a filter popup value has changed + /// + [Description("Occurs when a filter popup value has changed.")] + public event EventHandler FilterPopupValueChanged; + + #endregion + + #region FilterRowError + + /// + /// Occurs when a row filter error has occurred + /// + [Description("Occurs when a row filter error has occurred.")] + public event EventHandler FilterRowError; + + #endregion + + #region FilterRowHeaderClick + + /// + /// Occurs when a Filter RowHeader has been clicked + /// + [Description("Occurs when a Filter RowHeader has been clicked.")] + public event EventHandler FilterRowHeaderClick; + + #endregion + + #region FilterStoreUserData + + /// + /// Occurs when user defined Filter data needs to be stored + /// + [Description("Occurs when user defined Filter data needs to be loaded.")] + public event EventHandler FilterStoreUserData; + + #endregion + + #region FilterUserFunction + + /// + /// Occurs when a Filter User function needs evaluated + /// + [Description("Occurs when a Filter User function needs evaluated.")] + public event EventHandler FilterUserFunction; + + #endregion + + #region GetFilterEditType + + /// + /// Occurs when the column filter edit type is needed + /// + [Description("Occurs when the column filter edit type is needed.")] + public event EventHandler GetFilterEditType; + + #endregion + + #endregion + + #region GetCellRanges + + /// + /// Occurs when the grid needs to get the current merged cell ranges + /// + [Description("Occurs when the grid needs to get the current merged cell ranges.")] + public event EventHandler GetCellRanges; + + #endregion + + #region GetCellFormattedValue + + /// + /// Occurs when a Modal cell Value needs formatted + /// + [Description("Occurs when a Modal cell Value needs formatted.")] + public event EventHandler GetCellFormattedValue; + + #endregion + + #region GetCellRangeFormattedValue + + /// + /// Occurs when a CellRange Formatted Value is needed + /// + [Description("Occurs when a CellRange Formatted Value is needed.")] + public event EventHandler GetCellRangeFormattedValue; + + #endregion + + #region GetCellStyle + + /// + /// Occurs when a Cell Style is needed + /// + [Description("Occurs when a Cell Style is needed.")] + public event EventHandler GetCellStyle; + + #endregion + + #region GetCellToolTip + + /// + /// Occurs when a Cell ToolTip is needed + /// + [Description("Occurs when a Cell ToolTip is needed.")] + public event EventHandler GetCellToolTip; + + #endregion + + #region GetCellValue + + /// + /// Occurs when a Cell Value is needed + /// + [Description("Occurs when a Cell Value is needed.")] + public event EventHandler GetCellValue; + + #endregion + + #region GetColumnGroupHeaderStyle + + /// + /// Occurs when a ColumnGroupHeader style is needed + /// + [Description("Occurs when a ColumnGroupHeader style is needed.")] + public event EventHandler GetColumnGroupHeaderStyle; + + #endregion + + #region GetColumnHeaderRowHeaderStyle + + /// + /// Occurs when a ColumnHeader RowHeader style is needed + /// + [Description("Occurs when a ColumnHeader RowHeader style is needed.")] + public event EventHandler GetColumnHeaderRowHeaderStyle; + + #endregion + + #region GetColumnHeaderStyle + + /// + /// Occurs when a ColumnHeader style is needed + /// + [Description("Occurs when a ColumnHeader style is needed.")] + public event EventHandler GetColumnHeaderStyle; + + #endregion + + #region GetColumnHeaderToolTip + + /// + /// Occurs when a ColumnHeader ToolTip is needed + /// + [Description("Occurs when a ColumnHeader ToolTip is needed.")] + public event EventHandler GetColumnHeaderToolTip; + + #endregion + + #region GetDisplayRanges + + /// + /// Occurs when the grid needs to get the current display ranges + /// + [Description("Occurs when the grid needs to get the current display ranges.")] + public event EventHandler GetDisplayRanges; + + #endregion + + #region GetFilterRowStyle + + /// + /// Occurs when a FilterRow style is needed + /// + [Description("Occurs when a FilterRow style is needed.")] + public event EventHandler GetFilterRowStyle; + + #endregion + + #region GetFilterColumnHeaderStyle + + /// + /// Occurs when a Filter ColumnHeader style is needed + /// + [Description("Occurs when a Filter ColumnHeader style is needed.")] + public event EventHandler GetFilterColumnHeaderStyle; + + #endregion + + #region ConfigureGroupBox + + /// + /// Occurs when a GroupBox Size is needed + /// + [Description("Occurs when a GroupBox needs configured.")] + public event EventHandler ConfigureGroupBox; + + #endregion + + #region GetGroupDetailRows + + /// + /// Occurs when a list of group detail rows is needed + /// + [Description("Occurs when a list of group detail rows is needed.")] + public event EventHandler GetGroupDetailRows; + + #endregion + + #region GetGroupHeaderStyle + + /// + /// Occurs when an GroupHeader style is needed + /// + [Description("Occurs when a GroupHeader style is needed.")] + public event EventHandler GetGroupHeaderStyle; + + #endregion + + #region GetColumnGroupHeaderToolTip + + /// + /// Occurs when a ColumnGroupHeader ToolTip is needed + /// + [Description("Occurs when a ColumnGroupHeader ToolTip is needed.")] + public event EventHandler GetColumnGroupHeaderToolTip; + + #endregion + + #region GetMergedCellStyle + + /// + /// Occurs when a Merged Cell Style is needed + /// + [Description("Occurs when a Merged Cell Style is needed.")] + public event EventHandler GetMergedCellStyle; + + #endregion + + #region GetPanelStyle + + /// + /// Occurs when a GridPanel style is needed + /// + [Description("Occurs when a GridPanel style is needed.")] + public event EventHandler GetPanelStyle; + + #endregion + + #region GetGroupId + + /// + /// Occurs when an element Group identifier is needed + /// + [Description("Occurs when an element Group identifier is needed.")] + public event EventHandler GetGroupId; + + #endregion + + #region GetRowCellStyle + + /// + /// Occurs when a row CellStyle is needed + /// + [Description("Occurs when a row CellStyle is needed.")] + public event EventHandler GetRowCellStyle; + + #endregion + + #region GetRowHeaderStyle + + /// + /// Occurs when a row RowHeader style is needed + /// + [Description("Occurs when a row RowHeader style is needed.")] + public event EventHandler GetRowHeaderStyle; + + #endregion + + #region GetRowHeaderText + + /// + /// Occurs when a row's header text is needed + /// + [Description("Occurs when a row's header text is needed.")] + public event EventHandler GetRowHeaderText; + + #endregion + + #region GetRowStyle + + /// + /// Occurs when a row style is needed + /// + [Description("Occurs when a row style is needed.")] + public event EventHandler GetRowStyle; + + #endregion + + #region GroupSorting + + /// + /// Occurs when a grid Group is about to be sorted + /// + [Description("Occurs when a grid Group are about to be sorted.")] + public event EventHandler GroupSorting; + + #endregion + + #region GroupSorted + + /// + /// Occurs when a grid Group has been sorted + /// + [Description("Occurs when a grid Group has been sorted.")] + public event EventHandler GroupSorted; + + #endregion + + #region GetTextRowStyle + + /// + /// Occurs when a GridTextRow (Header, footer, etc) style is needed + /// + [Description("Occurs when a GridTextRow (Header, footer, etc) style is needed.")] + public event EventHandler GetTextRowStyle; + + #endregion + + #region GroupChanged + + /// + /// Occurs when column Grouping has changed + /// + [Description("Occurs when column Grouping has changed.")] + public event EventHandler GroupChanged; + + #endregion + + #region GroupHeaderClick + + /// + /// Occurs when a Group Header has been clicked + /// + [Description("Occurs when a Group Header has been clicked.")] + public event EventHandler GroupHeaderClick; + + #endregion + + #region GroupHeaderDoubleClick + + /// + /// Occurs when a Group Header has been double clicked + /// + [Description("Occurs when a Group Header has been double clicked.")] + public event EventHandler GroupHeaderDoubleClick; + + #endregion + + #region LayoutOrderUpdating + + /// + /// Occurs when a grid panel's order layout is being updated + /// + [Description("Occurs when a grid panel's order layout is being updated.")] + public event EventHandler LayoutOrderUpdating; + + #endregion + + #region LayoutOrderUpdated + + /// + /// Occurs when a grid panel's order layout has been updated + /// + [Description("Occurs when a grid panel's order layout has been updated.")] + public event EventHandler LayoutOrderUpdated; + + #endregion + + #region LocalizeString + + /// + /// Occurs when the SuperGrid is looking for translated text for one of the internal text that are + /// displayed on menus, toolbars and customize forms. You need to set Handled=true if you want + /// your custom text to be used instead of the built-in system value. + /// + public event DotNetBarManager.LocalizeStringEventHandler LocalizeString; + + #endregion + + #region NoRowsMarkupLinkClick + + /// + /// Occurs when a GridPanel's NoRowsText has a MarkupLink that has been clicked + /// + [Description("Occurs when a GridPanel's NoRowsText has a MarkupLink that has been clicked.")] + public event EventHandler NoRowsMarkupLinkClick; + + #endregion + + #region PlayingSound + + /// + /// Occurs when the grid is about to play a system sound (beep). + /// + [Description("Occurs when the grid is about to play a system sound (beep)..")] + public event EventHandler PlayingSound; + + #endregion + + #region GridPreviewKeyDown + + /// + /// GridPreviewKeyDown + /// + [Description("PreviewKeyDown event, with the ability to specify that the key has been handled.")] + public event EventHandler GridPreviewKeyDown; + + #endregion + + #region PreviewKeyDown + + /// + /// PreviewKeyDown + /// + [Description("Occurs before the System.Windows.Forms.Control.KeyDown event when a key is pressed while focus is on this control.")] + public new event EventHandler PreviewKeyDown; + + #endregion + + #region RefreshFilter + + /// + /// Occurs when the Virtual row filter needs refreshed + /// + [Description("Occurs when the Virtual row filter needs refreshed.")] + public event EventHandler RefreshFilter; + + #endregion + + #region Render events + + #region PostRenderCell + + /// + /// Occurs after a cell has been rendered + /// + [Description("Occurs after a cell has been rendered.")] + public event EventHandler PostRenderCell; + + #endregion + + #region PreRenderCell + + /// + /// Occurs when a cell is about to be rendered + /// + [Description("Occurs when a cell is about to be rendered.")] + public event EventHandler PreRenderCell; + + #endregion + + #region PostRenderPanelRow + + /// + /// Occurs when a nested Panel Row has been rendered + /// + [Description("Occurs when a nested Panel Row has been rendered.")] + public event EventHandler PostRenderPanelRow; + + #endregion + + #region PreRenderPanelRow + + /// + /// Occurs when a nested Panel Row is about to be rendered + /// + [Description("Occurs when a nested Panel Row is about to be rendered.")] + public event EventHandler PreRenderPanelRow; + + #endregion + + #region PostRenderRow + + /// + /// Occurs after a row has been rendered + /// + [Description("Occurs after a row has been rendered.")] + public event EventHandler PostRenderRow; + + #endregion + + #region PreRenderRow + + /// + /// Occurs when a row is about to be rendered + /// + [Description("Occurs when a row is about to be rendered.")] + public event EventHandler PreRenderRow; + + #endregion + + #region PostRenderTextRow + + /// + /// Occurs after a TextRow (Caption, Footer, etc) has been rendered + /// + [Description("Occurs after a TextRow has been rendered.")] + public event EventHandler PostRenderTextRow; + + #endregion + + #region PreRenderTextRow + + /// + /// Occurs when a TextRow (Caption, Footer, etc) is about to be rendered + /// + [Description("Occurs when a TextRow is about to be rendered.")] + public event EventHandler PreRenderTextRow; + + #endregion + + #region PostRenderGroupHeader + + /// + /// Occurs after a Group header has been rendered + /// + [Description("Occurs after a Group header has been rendered.")] + public event EventHandler PostRenderGroupHeader; + + #endregion + + #region PreRenderGroupHeader + + /// + /// Occurs when a Group header is about to be rendered + /// + [Description("Occurs when a Group header is about to be rendered.")] + public event EventHandler PreRenderGroupHeader; + + #endregion + + #region PostRenderColumnHeader + + /// + /// Occurs after a Column header has been rendered + /// + [Description("Occurs after a Column header has been rendered.")] + public event EventHandler PostRenderColumnHeader; + + #endregion + + #region PreRenderColumnHeader + + /// + /// Occurs when a Column header is about to be rendered + /// + [Description("Occurs when a Column header is about to be rendered.")] + public event EventHandler PreRenderColumnHeader; + + #endregion + + #region PostRenderColumnGroupHeader + + /// + /// Occurs after a Column GroupHeader has been rendered + /// + [Description("Occurs after a Column GroupHeader has been rendered.")] + public event EventHandler PostRenderColumnGroupHeader; + + #endregion + + #region PreRenderColumnGroupHeader + + /// + /// Occurs when a Column GroupHeader is about to be rendered + /// + [Description("Occurs when a Column GroupHeader is about to be rendered.")] + public event EventHandler PreRenderColumnGroupHeader; + + #endregion + + #region PostRenderFilterPopupGripBar + + /// + /// Occurs after a FilterPopup GripBar has been rendered + /// + [Description("Occurs after a FilterPopup GripBar has been rendered.")] + public event EventHandler PostRenderFilterPopupGripBar; + + #endregion + + #region PreRenderFilterPopupGripBar + + /// + /// Occurs when a FilterPopup GripBar is about to be rendered + /// + [Description("Occurs when a FilterPopup GripBar is about to be rendered.")] + public event EventHandler PreRenderFilterPopupGripBar; + + #endregion + + #region PostRenderFilterRow + + /// + /// Occurs after a Filter Row has been rendered + /// + [Description("Occurs after a Filter Row has been rendered.")] + public event EventHandler PostRenderFilterRow; + + #endregion + + #region PreRenderFilterRow + + /// + /// Occurs when a Filter Row is about to be rendered + /// + [Description("Occurs when a Filter Row is about to be rendered.")] + public event EventHandler PreRenderFilterRow; + + #endregion + + #region PostRenderGroupBox + + /// + /// Occurs after a GroupBox has been rendered + /// + [Description("Occurs after a GroupBox has been rendered.")] + public event EventHandler PostRenderGroupBox; + + #endregion + + #region PreRenderGroupBox + + /// + /// Occurs when a GroupBox is about to be rendered + /// + [Description("Occurs when a GroupBox is about to be rendered.")] + public event EventHandler PreRenderGroupBox; + + #endregion + + #region PostRenderGroupBoxConnector + + /// + /// Occurs after a GroupBox Connector been rendered + /// + [Description("Occurs after a GroupBox Connectorhas been rendered.")] + public event EventHandler PostRenderGroupBoxConnector; + + #endregion + + #region PreRenderGroupBoxConnector + + /// + /// Occurs when a GroupBox Connector is about to be rendered + /// + [Description("Occurs when a GroupBox Connector is about to be rendered.")] + public event EventHandler PreRenderGroupBoxConnector; + + #endregion + + #endregion + + #region Row events + + #region LoadVirtualRow + + /// + /// Occurs when a virtual row needs loaded + /// + [Description("Occurs when a virtual row needs loaded.")] + public event EventHandler LoadVirtualRow; + + #endregion + + #region RowActivated + + /// + /// Occurs when a row has been made the Active Row + /// + [Description("Occurs when a row has been made the Active Row.")] + public event EventHandler RowActivated; + + #endregion + + #region RowActivating + + /// + /// Occurs when a row is about to be made the Active Row + /// + [Description("Occurs when a row is about to be made the Active Row.")] + public event EventHandler RowActivating; + + #endregion + + #region RowAdded + + /// + /// Occurs when a row has been added + /// + [Description("Occurs when a row has been added.")] + public event EventHandler RowAdded; + + #endregion + + #region RowAdding + + /// + /// Occurs when a row is about to be added + /// + [Description("Occurs when a row is about to be added.")] + public event EventHandler RowAdding; + + #endregion + + #region RowDeleted + + /// + /// Occurs when a row has been deleted + /// + [Description("Occurs when a row has been deleted.")] + public event EventHandler RowDeleted; + + #endregion + + #region RowDeleting + + /// + /// Occurs when a row is about to be deleted + /// + [Description("Occurs when a row is about to be deleted.")] + public event EventHandler RowDeleting; + + #endregion + + #region GetDetailRowHeight + + /// + /// Occurs when a row's 'detail' height is needed + /// + [Description("Occurs when a row's 'detail' height is needed.")] + public event EventHandler GetDetailRowHeight; + + #endregion + + #region RowClick + + /// + /// Occurs when a row has been clicked + /// + [Description("Occurs when a row has been clicked.")] + public event EventHandler RowClick; + + #endregion + + #region RowDoubleClick + + /// + /// Occurs when a row has been double clicked + /// + [Description("Occurs when a row has been double clicked.")] + public event EventHandler RowDoubleClick; + + #endregion + + #region RowHeaderClick + + /// + /// Occurs when a row header has been clicked + /// + [Description("Occurs when a row header has been clicked.")] + public event EventHandler RowHeaderClick; + + #endregion + + #region RowHeaderDoubleClick + + /// + /// Occurs when a row header has been double clicked + /// + [Description("Occurs when a row header has been double clicked.")] + public event EventHandler RowHeaderDoubleClick; + + #endregion + + #region RowHeaderResized + + /// + /// Occurs when the grid Row Header has been resized + /// + [Description("Occurs when the grid Row Header has been resized.")] + public event EventHandler RowHeaderResized; + + #endregion + + #region RowInfoClick + + /// + /// Occurs when a row InfoImage has been clicked + /// + [Description("Occurs when a row InfoImage has been clicked.")] + public event EventHandler RowInfoClick; + + #endregion + + #region RowInfoDoubleClick + + /// + /// Occurs when a row InfoImage has been double clicked + /// + [Description("Occurs when a row InfoImage has been double clicked.")] + public event EventHandler RowInfoDoubleClick; + + #endregion + + #region RowInfoEnter + + /// + /// Occurs when a row InfoImage has been entered via the mouse + /// + [Description("Occurs when a row InfoImage has been entered via the mouse.")] + public event EventHandler RowInfoEnter; + + #endregion + + #region RowInfoLeave + + /// + /// Occurs when a row InfoImage has been exited via the mouse + /// + [Description("Occurs when a row InfoImage has been exited via the mouse.")] + public event EventHandler RowInfoLeave; + + #endregion + + #region RowLoaded + + /// + /// Occurs when a 'bound' data row has been loaded + /// + [Description("Occurs when a 'bound' data row has been loaded.")] + public event EventHandler RowLoaded; + + #endregion + + #region RowMarkedDirty + + /// + /// Occurs when a cell editor marks a row as Dirty + /// + [Description("Occurs when a cell editor marks a row as Dirty.")] + public event EventHandler RowMarkedDirty; + + #endregion + + #region RowMouseDown + + /// + /// Occurs when a mouse button is pressed + /// while the mouse pointer is within a Row + /// + [Description("Occurs when a mouse button is pressed while the mouse pointer is within a Row.")] + public event EventHandler RowMouseDown; + + #endregion + + #region RowMouseEnter + + /// + /// Occurs when the mouse pointer enters a Row + /// + [Description("Occurs when the mouse pointer enters a Row.")] + public event EventHandler RowMouseEnter; + + #endregion + + #region RowMouseLeave + + /// + /// Occurs when the mouse pointer leaves a Row + /// + [Description("Occurs when the mouse pointer leaves a Row.")] + public event EventHandler RowMouseLeave; + + #endregion + + #region RowMouseMove + + /// + /// Occurs when the mouse pointer moves within a Row + /// + [Description("Occurs when the mouse pointer leaves a Row.")] + public event EventHandler RowMouseMove; + + #endregion + + #region RowMouseUp + + /// + /// Occurs when a mouse button is released + /// while the mouse pointer is within a Row + /// + [Description("Occurs when a mouse button is released while the mouse pointer is within a Row.")] + public event EventHandler RowMouseUp; + + #endregion + + #region RowMoved + + /// + /// Occurs when a row has been moved or reordered + /// + [Description("Occurs when a row has been moved or reordered.")] + public event EventHandler RowMoved; + + #endregion + + #region RowMoving + + /// + /// Occurs when a row is about to be moved or reordered + /// + [Description("Occurs when a row is about to be moved or reordered.")] + public event EventHandler RowMoving; + + #endregion + + #region RowResized + + /// + /// Occurs when a row has been resized + /// + [Description("Occurs when a row has been resized.")] + public event EventHandler RowResized; + + #endregion + + #region RowRestored + + /// + /// Occurs when a deleted row has been restored (undeleted) + /// + [Description("Occurs when a deleted row has been restored (undeleted).")] + public event EventHandler RowRestored; + + #endregion + + #region RowRestoring + + /// + /// Occurs when a deleted row is about to be restored (undeleted) + /// + [Description("Occurs when a deleted row is about to be restored (undeleted).")] + public event EventHandler RowRestoring; + + #endregion + + #region RowSetDefaultValues + + /// + /// Occurs when a user enters the Insertion Row + /// or presses the 'insert' key to add a new row, + /// permitting default values to be set for each cell + /// + [Description("Occurs when a user enters the Insertion Row or presses the 'insert' key to add a new row, permitting default values to be set for each cell.")] + public event EventHandler RowSetDefaultValues; + + #endregion + + #region RowsGrouped + + /// + /// Occurs when the grid Rows have been grouped (or ungrouped) + /// + [Description("Occurs when the grids Row have been grouped (or ungrouped).")] + public event EventHandler RowsGrouped; + + #endregion + + #region RowsGrouping + + /// + /// Occurs when the grid Rows are about to be grouped (or ungrouped) + /// + [Description("Occurs when the Rows are about to be grouped (or ungrouped).")] + public event EventHandler RowsGrouping; + + #endregion + + #region RowsPurged + + /// + /// Occurs when grid rows have been purged + /// + [Description("Occurs when grid rows have been purged.")] + public event EventHandler RowsPurged; + + #endregion + + #region RowsPurging + + /// + /// Occurs when grid rows are about to be purged + /// + [Description("Occurs when grid rows are about to be purged.")] + public event EventHandler RowsPurging; + + #endregion + + #region RowsSorting + + /// + /// Occurs when the grid Rows are about to be sorted + /// + [Description("Occurs when the grid Rows are about to be sorted.")] + public event EventHandler RowsSorting; + + #endregion + + #region RowsSorted + + /// + /// Occurs when the grid Rows have been sorted + /// + [Description("Occurs when the grid Rows have been sorted.")] + public event EventHandler RowsSorted; + + #endregion + + #region RowValidating + + /// + /// Occurs when a row needs validating + /// + [Description("Occurs when a row needs validating.")] + public event EventHandler RowValidating; + + #endregion + + #region RowValidated + + /// + /// Occurs after a row has been validated + /// + [Description("Occurs after a row has been validated.")] + public event EventHandler RowValidated; + + #endregion + + #region StoreVirtualRow + + /// + /// Occurs when a virtual row has changed and + /// it's contents need stored + /// + [Description("Occurs when a virtual row has changed and it's contents need stored.")] + public event EventHandler StoreVirtualRow; + + #endregion + + #region VirtualRowLoaded + + /// + /// Occurs when after a virtual row has been loaded + /// + [Description("Occurs after a virtual row has been loaded.")] + public event EventHandler VirtualRowLoaded; + + #endregion + + #endregion + + #region Scroll + + /// + /// Occurs when the Horizontal or Vertical scrollbar has been scrolled + /// + [Description("Occurs when the Horizontal or Vertical scrollbar has been scrolled.")] + public event EventHandler Scroll; + + #endregion + + #region ScrollMin + + /// + /// Occurs when the Horizontal or Vertical + /// scrollbar has been scrolled to the Minimum and released + /// + [Description("Occurs when the Horizontal or Vertical scrollbar has been scrolled to the Minimum and released.")] + public event EventHandler ScrollMin; + + #endregion + + #region ScrollMax + + /// + /// Occurs when the Horizontal or Vertical scrollbar has been scrolled to the Maximum and released + /// + [Description("Occurs when the Horizontal or Vertical scrollbar has been scrolled to the Maximum and released.")] + public event EventHandler ScrollMax; + + #endregion + + #region SelectionChanged + + /// + /// Occurs when the selected items in the grid has changed + /// + [Description("Occurs when the selected items in the grid has changed.")] + public event EventHandler SelectionChanged; + + #endregion + + #region SelectionChanging + + /// + /// Occurs when the selected items in the grid is about to change + /// + [Description("Occurs when the selected items in the grid is about to change.")] + public event EventHandler SelectionChanging; + + #endregion + + #region SortChanged + + /// + /// Occurs when the grid sort order has changed + /// + [Description("Occurs when the grid sort order has changed.")] + public event EventHandler SortChanged; + + #endregion + + #region StyleManagerChanged + + /// + /// Occurs when the StyleManager style has changed + /// + [Description("Occurs when the StyleManager style has changed.")] + public event EventHandler StyleManagerChanged; + + #endregion + + #region TextRowClick + + /// + /// Occurs when a GridTextRow (Title, footer, ...) has been clicked + /// + [Description("Occurs when a GridTextRow (Title, footer, ...) has been clicked.")] + public event EventHandler TextRowClick; + + #endregion + + #region TextRowHeaderClick + + /// + /// Occurs when a GridTextRow (Title, footer, ...) Row Header has been clicked + /// + [Description("Occurs when a GridTextRow (Title, footer, ...) Row Header has been clicked.")] + public event EventHandler TextRowHeaderClick; + + #endregion + + #region TextRowMarkupLinkClick + + /// + /// Occurs when a GridTextRow (Title, footer, ...) has a MarkupLink that has been clicked + /// + [Description("Occurs when a GridTextRow (Title, footer, ...) has a MarkupLink that has been clicked.")] + public event EventHandler TextRowMarkupLinkClick; + + #endregion + + #region UpdateCellDisplayRanges + + /// + /// Occurs after the grid has created its CellDisplayRanges list + /// + [Description("Occurs after the grid has created its CellDisplayRanges list.")] + public event EventHandler UpdateCellDisplayRanges; + + #endregion + + #endregion + + #region Constants + + const int WmSetFocus = 0x7; + + const int WmKeyDown = 0x100; + const int WmKeyUp = 0x101; + + const int WmMouseMove = 0x200; + const int WmMouseDown = 0x201; + const int WmMouseLeave = 0x2a3; + const int WmMouseWheel = 0x20a; + + const int InputKeyboard = 1; + + #endregion + + #region DllImports + + #region SendInput + + #region SendInput32 + + [StructLayout(LayoutKind.Explicit)] + struct Input32 + { + [FieldOffset(0)] + public int type; + + [FieldOffset(4)] + public MouseInput mi; + + [FieldOffset(4)] + public KeyBoardInput ki; + + [FieldOffset(4)] + public HardwareInput hi; + } + + [StructLayout(LayoutKind.Sequential)] + struct KeyBoardInput + { + private ushort vk; + private ushort scan; + private uint flags; + private uint time; + private IntPtr extraInfo; + + public KeyBoardInput(ushort key) + { + vk = key; + + scan = 0; + time = 0; + extraInfo = IntPtr.Zero; + flags = 0; + } + } + + [StructLayout(LayoutKind.Sequential)] + struct MouseInput + { + public int dx; + public int dy; + public uint mouseData; + public uint dwFlags; + public uint time; + public IntPtr dwExtraInfo; + } + + [StructLayout(LayoutKind.Sequential)] + struct HardwareInput + { + public uint uMsg; + public ushort wParamL; + public ushort wParamH; + } + + [DllImport("user32.dll", SetLastError = true)] + private static extern uint SendInput(uint nInputs, Input32[] pInputs, int cbSize); + + #endregion + + #region SendInput64 + + [StructLayout(LayoutKind.Explicit, Pack = 1)] + internal struct Input64 + { + [FieldOffset(0)] + public uint type; + + [FieldOffset(8)] + public KeyboardInput64 ki; + } + + [StructLayout(LayoutKind.Explicit, Pack = 1)] + internal struct KeyboardInput64 + { + [FieldOffset(0)] + public ushort vk; + + [FieldOffset(2)] + public ushort scan; + + [FieldOffset(4)] + public uint flags; + + [FieldOffset(12)] + public uint time; + + [FieldOffset(20)] + public uint extraInfo1; + + [FieldOffset(28)] + public uint extraInfo2; + + public KeyboardInput64(ushort key) + { + vk = key; + + scan = 0; + time = 0; + extraInfo1 = 0; + extraInfo2 = 0; + flags = 0; + } + } + + [DllImport("user32.dll", SetLastError = true)] + private static extern uint SendInput(uint nInputs, Input64[] pInputs, int cbSize); + + #endregion + + #endregion + + #region ScrollWindowEx + + #region RECT definition + + [StructLayout(LayoutKind.Sequential)] + internal struct RECT + { + public int Left, Top, Right, Bottom; + + public RECT(int left, int top, int right, int bottom) + { + Left = left; + Top = top; + Right = right; + Bottom = bottom; + } + + public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { } + + public int X + { + get { return Left; } + set { Right -= (Left - value); Left = value; } + } + + public int Y + { + get { return Top; } + set { Bottom -= (Top - value); Top = value; } + } + + public int Height + { + get { return Bottom - Top; } + set { Bottom = value + Top; } + } + + public int Width + { + get { return Right - Left; } + set { Right = value + Left; } + } + + public Point Location + { + get { return new Point(Left, Top); } + set { X = value.X; Y = value.Y; } + } + + public Size Size + { + get { return new Size(Width, Height); } + set { Width = value.Width; Height = value.Height; } + } + + public static implicit operator Rectangle(RECT r) + { + return new Rectangle(r.Left, r.Top, r.Width, r.Height); + } + + public static implicit operator RECT(Rectangle r) + { + return new RECT(r); + } + + public static bool operator == (RECT r1, RECT r2) + { + return r1.Equals(r2); + } + + public static bool operator != (RECT r1, RECT r2) + { + return !r1.Equals(r2); + } + + public bool Equals(RECT r) + { + return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom; + } + + public override bool Equals(object obj) + { + if (obj is RECT) + return Equals((RECT)obj); + + else if (obj is Rectangle) + return Equals(new RECT((Rectangle)obj)); + + return false; + } + + public override int GetHashCode() + { + return ((Rectangle)this).GetHashCode(); + } + + public override string ToString() + { + return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom); + } + } + + #endregion + + const uint SW_ERASE = (1 << 1); + const uint SW_INVALIDATE = (1 << 2); + + [DllImport("user32.dll")] + private static extern int ScrollWindowEx(IntPtr hWnd, int dx, int dy, + ref RECT scrollRect, ref RECT clipRect, IntPtr hrgn, ref RECT updateRect, uint flags); + + #endregion + + #region GetKeyState + + #region Keyboard + + internal abstract class Keyboard + { + [Flags] + private enum KeyStates + { + None = 0, + Down = 1, + Toggled = 2 + } + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + private static extern short GetKeyState(int keyCode); + + private static KeyStates GetKeyState(Keys key) + { + KeyStates state = KeyStates.None; + + short retVal = GetKeyState((int)key); + + // If the high-order bit is 1, the key is down + + if ((retVal & 0x8000) == 0x8000) + state |= KeyStates.Down; + + // If the low-order bit is 1, the key is toggled + + if ((retVal & 1) == 1) + state |= KeyStates.Toggled; + + return state; + } + + public static bool IsKeyDown(Keys key) + { + return KeyStates.Down == (GetKeyState(key) & KeyStates.Down); + } + + public static bool IsKeyToggled(Keys key) + { + return KeyStates.Toggled == (GetKeyState(key) & KeyStates.Toggled); + } + } + + #endregion + + #endregion + + #endregion + + #region Private variables + + private readonly GridPanel _PrimaryGrid; + + private HScrollBarAdv _HScrollBar; + private VScrollBarAdv _VScrollBar; + + private int _HScrollOffset; + private int _VScrollOffset; + + private bool _HScrollBarEnabled; + private bool _VScrollBarEnabled; + private bool _ScrollBarScrolling; + + private Rectangle _ViewRect = Rectangle.Empty; + private Rectangle _CViewRect = Rectangle.Empty; + + private GridElement _CapturedItem; + + private Timer _AutoScrollTimer; + private AutoScrollEnable _AutoScrollEnable; + private Rectangle _ScrollRect; + + private bool _PostMouseMove; + private ushort _BoundsUpdateCount; + private ushort _BeginUpdateCount; + private Cursor _GridCursor = Cursors.Default; + + private GridCell _EditorCell; + private GridCell _NonModalEditorCell; + private IGridCellEditControl _ActiveEditor; + private IGridCellEditControl _ActiveNonModalEditor; + private FilterPanel _ActiveFilterPanel; + + private GridPanel _ActiveGrid; + private GridContainer _ActiveRow; + private GridCell _ActiveCell; + private GridElement _LastProcessedItem; + private int _LastCellIndex = -1; + private GridCell _LastActiveCell; + + private string _ToolTipText; + private System.Windows.Forms.ToolTip _ToolTip; + + private StyleType _SizingStyle = StyleType.NotSet; + private DefaultVisualStyles _DefaultVisualStyles; + private DefaultVisualStyles _BaseVisualStyles; + + private ushort _StyleUpdateCount = 1; + private ushort _StyleMouseOverUpdateCount = 1; + private ushort _StyleSelectedUpdateCount = 1; + private ushort _StyleSelectedMouseOverUpdateCount = 1; + private ushort _ArrangeLayoutCount = 1; + private ushort _DisplayedMergeLayoutCount = 1; + + private bool _NeedToUpdateIndicees; + private ushort _IndiceesUpdateCount; + + private GridElement _DesignerElement; + + private Keys _LastKeyDown; + private Keys _LastModifierKeys; + + private TabSelection _TabSelection = TabSelection.Cell; + + private bool _KeyPressSent; + private bool _IsInputKey; + + private string _FilterShowAllString = "Show all"; + private string _FilterShowNullString = "Show null"; + private string _FilterShowNotNullString = "Show not null"; + private string _FilterCustomString = "Custom"; + + private string _FilterApplyString = "Apply"; + private string _FilterOkString = "OK"; + private string _FilterCancelString = "Cancel"; + private string _FilterCloseString = "Close"; + private string _GroupByWaterMarkText = "Drag a column header here to group by that column"; + + private bool _FilterColorizeCustomExpr = true; + private bool _ShowCustomFilterHelp = true; + private bool _FilterUseExtendedCustomDialog; + + private int _FilterMaxDropDownHeight = 300; + + private ExpressionColors _FilterExprColors = new ExpressionColors(); + private PopupControl _PopupControl; + + private bool _LocalizedStringsLoaded; + + private ExpandButtonType _ExpandButtonType = ExpandButtonType.NotSet; + + private Cursor _DefaultCursor = Cursors.Default; + private bool _SetGridCursor; + + private bool _HScrollBarVisible = true; + private bool _VScrollBarVisible = true; + + private bool _InArrangeGrid; + private bool _CanScrollEx; + private bool _EnableFastScrolling = true; + + private int _MaxToolTipLength = 2000; + + #endregion + + /// + /// Initializes a new instance of the SuperGridControl class. + /// + public SuperGridControl() + { + SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | + ControlStyles.Opaque | ControlStyles.ResizeRedraw | + ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor, true); + + _PrimaryGrid = new GridPanel(); + + _PrimaryGrid.SuperGrid = this; + _PrimaryGrid.ContainerBounds = ClientRectangle; + + SetupScrollBars(); + + if (DesignMode == false) + { + Application.AddMessageFilter(this); + + base.PreviewKeyDown += SuperGridControlPreviewKeyDown; + } + + UpdateGridStyle(); + + StyleManager.Register(this); + + if (BarFunctions.IsWindows7 && Touch.TouchHandler.IsTouchEnabled) + { + _TouchHandler = new Touch.TouchHandler(this, Touch.eTouchHandlerType.Gesture); + + _TouchHandler.PanBegin += TouchHandlerPanBegin; + _TouchHandler.Pan += TouchHandlerPan; + _TouchHandler.PanEnd += TouchHandlerPanEnd; + } + } + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + Dpi.SetScaling(factor); + + base.ScaleControl(factor, specified); + + SetupScrollBars(); + } + + #region OnEnabledChanged + + /// + /// OnEnabledChanged + /// + /// + protected override void OnEnabledChanged(EventArgs e) + { + base.OnEnabledChanged(e); + + Refresh(); + } + + #endregion + + #region StyleManagerStyleChanged + + /// + /// Called by StyleManager to notify control that style on + /// manager has changed and that control should refresh its + /// appearance if its style is controlled by StyleManager. + /// + /// New active style. + [EditorBrowsable(EditorBrowsableState.Never)] + public void StyleManagerStyleChanged(eDotNetBarStyle newStyle) + { + UpdateGridStyle(); + } + + private void UpdateGridStyle() + { + SuperGridStyle style = SuperGridStyle.Office2010Blue; + + switch (StyleManager.Style) + { + case eStyle.Office2007VistaGlass: + case eStyle.VisualStudio2010Blue: + case eStyle.Windows7Blue: + case eStyle.Office2007Blue: + case eStyle.Office2010Blue: + style = SuperGridStyle.Office2010Blue; + break; + + case eStyle.Office2007Black: + case eStyle.Office2010Black: + style = SuperGridStyle.Office2010Black; + break; + + case eStyle.Office2007Silver: + case eStyle.Office2010Silver: + style = SuperGridStyle.Office2010Silver; + break; + + case eStyle.Metro: + case eStyle.VisualStudio2012Dark: + case eStyle.VisualStudio2012Light: + case eStyle.Office2016: + case eStyle.OfficeMobile2014: + style = SuperGridStyle.Metro; + break; + } + + _BaseVisualStyles = VisualStylesTable.GetStyle(style); + + if (IsHandleCreated == true) + { + UpdateStyleCount(); + + Invalidate(true); + + if (StyleManagerChanged != null) + StyleManagerChanged(this, new EventArgs()); + } + } + + #endregion + + #region Public properties + + #region ActiveCell + + /// + /// Gets the current active cell + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell ActiveCell + { + get { return (_ActiveCell); } + + internal set + { + if (_ActiveCell != value) + { + _LastActiveCell = _ActiveCell; + + if (_ActiveCell != null) + _ActiveCell.EditorDirty = false; + + _ActiveCell = value; + + OnActiveCellChanged(_LastActiveCell, _ActiveCell); + } + } + } + + private void OnActiveCellChanged( + GridCell oldValue, GridCell newValue) + { + GridPanel panel = + (oldValue != null) ? oldValue.GridPanel : + (newValue != null) ? newValue.GridPanel : null; + + DoCellActivatedEvent(panel, oldValue, newValue); + } + + #endregion + + #region ActiveEditor + + /// + /// Gets the currently active cell editor, or null if + /// no edit is in progress + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IGridCellEditControl ActiveEditor + { + get { return (_ActiveEditor); } + internal set {_ActiveEditor = value; } + } + + #endregion + + #region ActiveElement + + /// + /// Gets the current active grid element (Row/Cell), or null if + /// there is no current active element + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridElement ActiveElement + { + get { return (_LastProcessedItem); } + + internal set + { + if (_LastProcessedItem != value) + { + if (_LastProcessedItem != null) + _LastProcessedItem.InvalidateRender(); + + _LastProcessedItem = value; + + if (_LastProcessedItem != null) + _LastProcessedItem.InvalidateRender(); + } + } + } + + #endregion + + #region ActiveFilterPanel + + /// + /// Gets the currently active FilterPanel + /// editor, or null if no edit is in progress + /// + public FilterPanel ActiveFilterPanel + { + get { return (_ActiveFilterPanel); } + internal set { _ActiveFilterPanel = value; } + } + + #endregion + + #region ActiveGrid + + /// + /// Gets the current active grid + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridPanel ActiveGrid + { + get { return (_ActiveGrid); } + + internal set + { + if (_ActiveGrid != value) + { + if (_ActiveGrid != null) + { + if (_ActiveGrid.ActiveRow is GridRow) + ((GridRow)_ActiveGrid.ActiveRow).EditorDirty = false; + } + + GridPanel oldValue = _ActiveGrid; + _ActiveGrid = value; + + OnActiveGridChanged(oldValue); + + ActiveRow = (_ActiveGrid != null) ? _ActiveGrid.ActiveRow : null; + } + } + } + + private void OnActiveGridChanged(GridPanel oldPanel) + { + DoActiveGridChangedEvent(oldPanel); + } + + #endregion + + #region ActiveRow + + /// + /// Gets the current active row, or null if no row + /// is defined or active + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridContainer ActiveRow + { + get + { + if (_ActiveGrid != null) + return (_ActiveGrid.ActiveRow); + + return (null); + } + + internal set + { + if (_ActiveRow != value) + { + if (_ActiveRow != null) + _ActiveRow.FlushRow(); + + GridContainer oldValue = _ActiveRow; + _ActiveRow = value; + + if (_ActiveRow != null) + ActiveGrid = _ActiveRow.GridPanel; + + if (_ActiveGrid != null) + _ActiveGrid.ActiveRow = value; + + OnActiveRowChanged(oldValue, _ActiveRow); + } + } + } + + private void OnActiveRowChanged( + GridContainer oldValue, GridContainer newValue) + { + GridPanel panel = + (oldValue != null) ? oldValue.GridPanel : + (newValue != null) ? newValue.GridPanel : null; + + DoRowActivatedEvent(panel, oldValue, newValue); + } + + #endregion + + #region BaseVisualStyles + + /// + /// BaseVisualStyles - the SuperGrid starting base styles + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public DefaultVisualStyles BaseVisualStyles + { + get { return (_BaseVisualStyles); } + internal set { _BaseVisualStyles = value; } + } + + #endregion + + #region DefaultVisualStyles + + /// + /// Gets or sets the Default Visual Styles for each grid element + /// + [Browsable(true), Category("Appearance"), DefaultValue(null)] + [Description("Indicates the Default Visual Styles for each grid elements.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public DefaultVisualStyles DefaultVisualStyles + { + get + { + if (_DefaultVisualStyles == null) + { + _DefaultVisualStyles = new DefaultVisualStyles(); + + _DefaultVisualStyles.PropertyChanged += DefaultVisualStylesPropertyChanged; + } + + return (_DefaultVisualStyles); + } + + set + { + if (_DefaultVisualStyles != value) + { + if (_DefaultVisualStyles != null) + _DefaultVisualStyles.PropertyChanged -= DefaultVisualStylesPropertyChanged; + + _DefaultVisualStyles = value; + + if (_DefaultVisualStyles != null) + _DefaultVisualStyles.PropertyChanged += DefaultVisualStylesPropertyChanged; + } + } + } + + #region DefaultVisualStylesPropertyChanged + + private void DefaultVisualStylesPropertyChanged(object sender, PropertyChangedEventArgs e) + { + UpdateStyleCount(); + + VisualChangeType changeType = ((VisualPropertyChangedEventArgs)e).ChangeType; + + switch (changeType) + { + case VisualChangeType.Layout: + _PrimaryGrid.NeedsMeasured = true; + _PrimaryGrid.InvalidateMerge(); + break; + + case VisualChangeType.Render: + Invalidate(); + break; + } + } + + #endregion + + #endregion + + #region DesignerElement + + /// + /// For internal use only + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridElement DesignerElement + { + get { return (_DesignerElement); } + + set + { + _DesignerElement = value; + + if (value != null) + { + if (value.NeedsMeasured == true) + ArrangeGrid(); + + value.EnsureVisible(true); + } + + Refresh(); + } + } + + #endregion + + #region EditorActive + + /// + /// Gets whether a cell editor is currently active + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool EditorActive + { + get { return (_ActiveEditor != null); } + } + + #endregion + + #region EditorCell + + /// + /// Gets the currently active editor cell, or null + /// if no cell is currently being edited + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell EditorCell + { + get { return (_EditorCell); } + internal set { _EditorCell = value; } + } + + #endregion + + #region EditorColumn + + /// + /// Gets the column containing the current edit + /// cell, or null if no edit is in progress + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridColumn EditorColumn + { + get + { + if (_EditorCell != null) + return (_EditorCell.GridColumn); + + return (null); + } + } + + #endregion + + #region EditorGrid + + /// + /// Gets the grid containing the cell currently + /// being edited, or null if no edit is in progress + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridPanel EditorGrid + { + get + { + if (_EditorCell != null) + return (_EditorCell.GridPanel); + + return (null); + } + } + + #endregion + + #region EditorRow + + /// + /// Gets the row containing the cell currently + /// being edited, or null if no edit is in progress + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridRow EditorRow + { + get + { + if (_EditorCell != null) + return (_EditorCell.GridRow); + + return (null); + } + } + + #endregion + + #region EnableFastScrolling + + /// + /// Gets or sets whether Fast Scrolling is enabled. Default is true. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether Fast Scrolling is enabled.")] + public bool EnableFastScrolling + { + get { return (_EnableFastScrolling); } + + set + { + if (_EnableFastScrolling != value) + { + _EnableFastScrolling = value; + + OnPropertyChanged("EnableFastScrolling"); + } + } + } + + #endregion + + #region ExpandButtonType + + /// + /// Gets or sets the ExpandButton Type + /// + [DefaultValue(ExpandButtonType.NotSet), Category("Appearance")] + [Description("Indicates the ExpandButton Type.")] + public ExpandButtonType ExpandButtonType + { + get { return (_ExpandButtonType); } + + set + { + if (_ExpandButtonType != value) + { + _ExpandButtonType = value; + + UpdateStyleCount(); + + OnPropertyChanged("ExpandButtonType"); + } + } + } + + #endregion + + #region FilterColorizeCustomExpr + + /// + /// Gets or sets whether the Custom Expression + /// dialog colorizes the output expression + /// + [DefaultValue(true), Category("Filtering")] + [Description("Indicates whether the Custom Expression dialog colorizes the output expression.")] + public bool FilterColorizeCustomExpr + { + get { return (_FilterColorizeCustomExpr); } + + set + { + if (_FilterColorizeCustomExpr != value) + { + _FilterColorizeCustomExpr = value; + + OnPropertyChanged("FilterColorizeCustomExpr"); + } + } + } + + #endregion + + #region FilterExprColors + + /// + /// Gets or sets the expression colors used in the Custom Expression dialog + /// + [Category("Filtering")] + [Description("Indicates the expression colors used in the Custom Expression dialog.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ExpressionColors FilterExprColors + { + get { return (_FilterExprColors); } + + set + { + if (_FilterExprColors != value) + { + _FilterExprColors = value; + + OnPropertyChanged("FilterExprColors"); + } + } + } + + #endregion + + #region FilterMaxDropDownHeight + + /// + /// Gets or sets the max height of + /// the filter panel and filter popup drop-down + /// + [DefaultValue(300), Category("Filtering")] + [Description("Indicates the max height of the filter panel and filter popup dropdown.")] + public int FilterMaxDropDownHeight + { + get { return (_FilterMaxDropDownHeight); } + + set + { + if (_FilterMaxDropDownHeight != value) + { + _FilterMaxDropDownHeight = value; + + OnPropertyChanged("FilterMaxDropDownHeight"); + } + } + } + + #endregion + + #region FilterUseExtendedCustomDialog + + /// + /// Gets or sets whether the Extended Custom Expression dialog + /// is used (permits user filter definition persistence) + /// + [DefaultValue(false), Category("Filtering")] + [Description("Indicates whether the Extended Custom Expression dialog is used (permits user filter definition persistence).")] + public bool FilterUseExtendedCustomDialog + { + get { return (_FilterUseExtendedCustomDialog); } + + set + { + if (_FilterUseExtendedCustomDialog != value) + { + _FilterUseExtendedCustomDialog = value; + + OnPropertyChanged("FilterUseExtendedCustomDialog"); + } + } + } + + #endregion + + #region GridCursor + + /// + /// Gets or sets the logical grid cursor + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Cursor GridCursor + { + get { return (_GridCursor); } + + set + { + if (value == null || value == Cursors.Default) + _GridCursor = _DefaultCursor; + else + _GridCursor = value; + } + } + + #endregion + + #region HScrollBar + + /// + /// Gets a reference to the grids horizontal scrollbar + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public HScrollBarAdv HScrollBar + { + get { return (_HScrollBar); } + } + + #endregion + + #region HScrollMaximum + + /// + /// Gets the horizontal scrollbar maximum value + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int HScrollMaximum + { + get { return (_HScrollBar.Maximum); } + } + + #endregion + + #region HScrollOffset + + /// + /// Gets or sets the horizontal scrollbar offset + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int HScrollOffset + { + get { return (_HScrollOffset); } + set { SetHScrollValue(value); } + } + + #endregion + + #region HScrollBarVisible + + /// + /// Gets or sets whether Horizontal Scroll-bar is shown if needed because content of the control exceeds available width. Default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether Vertical Scroll-bar is shown if needed because content of the control exceeds available height.")] + public bool HScrollBarVisible + { + get { return _HScrollBarVisible; } + + set + { + _HScrollBarVisible = value; + + if (_HScrollBar != null && _HScrollBar.Visible != _HScrollBarVisible) + { + _HScrollBar.Visible = _HScrollBarVisible; + + PrimaryGrid.InvalidateLayout(); + Invalidate(); + } + } + } + + #endregion + + #region IsUpdateSuspended + + /// + /// Gets whether grid updating / rendering is suspended + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool IsUpdateSuspended + { + get { return (_BeginUpdateCount > 0); } + } + + #endregion + + #region NonModalEditorCell + + /// + /// Gets the current NonModal cell being edited, or + /// null if no NonModel cell edit is in progress + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GridCell NonModalEditorCell + { + get { return (_NonModalEditorCell); } + internal set { _NonModalEditorCell = value; } + } + + #endregion + + #region PopupControl + + /// + /// Gets the current active PopupControl + /// (Returns null if none is currently active). + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public PopupControl PopupControl + { + get { return (_PopupControl); } + internal set { _PopupControl = value; } + } + + #endregion + + #region PrimaryGrid + + /// + /// Gets the primary, root grid. + /// + [Browsable(true)] + [Description("Indicates the primary, root grid")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public GridPanel PrimaryGrid + { + get { return (_PrimaryGrid); } + } + + #endregion + + #region ShowCustomFilterHelp + + /// + /// Gets or sets whether the Custom + /// Expression dialog shows user help + /// + [DefaultValue(true), Category("Filtering")] + [Description("Indicates whether the Custom Expression dialog shows user help.")] + public bool ShowCustomFilterHelp + { + get { return (_ShowCustomFilterHelp); } + + set + { + if (_ShowCustomFilterHelp != value) + { + _ShowCustomFilterHelp = value; + + OnPropertyChanged("ShowCustomFilterHelp"); + } + } + } + + #endregion + + #region SizingStyle + + /// + /// Gets or sets which StyleType (Default, MouseOver, etc) to use for element sizing + /// + [Browsable(true), DefaultValue(StyleType.NotSet), Category("Appearance")] + [Description("Indicates which StyleType (Default, MouseOver, etc) to use for element sizing")] + public StyleType SizingStyle + { + get { return (_SizingStyle); } + + set + { + if (_SizingStyle != value) + { + _SizingStyle = value; + + OnSizingStyleChanged(); + } + } + } + + private void OnSizingStyleChanged() + { + _PrimaryGrid.InvalidateLayout(); + + OnPropertyChanged("SizingStyle"); + } + + #endregion + + #region TabSelection + + /// + /// Gets or sets how the TAB key moves the focus when pressed. + /// + [Browsable(true), DefaultValue(TabSelection.Cell), Category("Behavior")] + [Description("Indicates how the TAB key moves the focus when pressed.")] + public TabSelection TabSelection + { + get { return (_TabSelection); } + + set + { + if (_TabSelection != value) + { + _TabSelection = value; + + OnPropertyChanged("TabSelection"); + } + } + } + + #endregion + + #region MaxToolTipLength + + /// + /// Gets or sets the maximum tooltip length + /// + [Browsable(true), DefaultValue(2000), Category("Behavior")] + [Description("Indicates the maximum tooltip length.")] + public int MaxToolTipLength + { + get { return (_MaxToolTipLength); } + set { _MaxToolTipLength = value; } + } + + #endregion + + #region VScrollBar + + /// + /// Gets a reference to the grids vertical scrollbar + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public VScrollBarAdv VScrollBar + { + get { return (_VScrollBar); } + } + + #endregion + + #region VScrollMaximum + + /// + /// Gets the vertical scrollbar maximum value + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int VScrollMaximum + { + get { return (_VScrollBar.Maximum); } + } + + #endregion + + #region VScrollOffset + + /// + /// Gets the vertical scrollbar offset + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int VScrollOffset + { + get { return (_VScrollOffset); } + set { SetVScrollValue(value); } + } + + #endregion + + #region VScrollBarVisible + + /// + /// Gets or sets whether Vertical Scroll-bar is shown if needed because content of the control exceeds available height. Default value is true. + /// + [DefaultValue(true), Category("Appearance"), Description("Indicates whether Vertical Scroll-bar is shown if needed because content of the control exceeds available height.")] + public bool VScrollBarVisible + { + get { return _VScrollBarVisible; } + + set + { + _VScrollBarVisible = value; + + if (_VScrollBar != null && _VScrollBar.Visible != _VScrollBarVisible) + { + _VScrollBar.Visible = _VScrollBarVisible; + + PrimaryGrid.InvalidateLayout(); + Invalidate(); + } + } + } + + #endregion + + #endregion + + #region Internal properties + + #region ActiveNonModalEditor + + /// + /// ActiveNonModalEditor + /// + internal IGridCellEditControl ActiveNonModalEditor + { + get { return (_ActiveNonModalEditor); } + set { _ActiveNonModalEditor = value; } + } + + #endregion + + #region ArrangeLayoutCount + + internal ushort ArrangeLayoutCount + { + get { return (_ArrangeLayoutCount); } + set { _ArrangeLayoutCount = value; } + } + + #endregion + + #region BoundsUpdateCount + + internal ushort BoundsUpdateCount + { + get {return (_BoundsUpdateCount); } + set { _BoundsUpdateCount = value; } + } + + #endregion + + #region CanScrollEx + + internal bool CanScrollEx + { + get { return (_CanScrollEx); } + set { _CanScrollEx = value; } + } + + #endregion + + #region CapturedItem + + internal GridElement CapturedItem + { + get + { + if (Capture == false) + _CapturedItem = null; + + return (_CapturedItem); + } + + set { Capture = ((_CapturedItem = value) != null); } + } + + #endregion + + #region CViewRect + + internal Rectangle CViewRect + { + get + { + if (_CViewRect.IsEmpty == true) + { + _CViewRect = ClientRectangle; + + int n =_PrimaryGrid.FixedHeaderHeight; + + _CViewRect.Y += n; + _CViewRect.Height -= n; + + if (_PrimaryGrid.Footer != null && _PrimaryGrid.Footer.Visible == true) + _CViewRect.Height -= _PrimaryGrid.Footer.Size.Height; + + if (_VScrollBar != null && _VScrollBar.Visible == true) + _CViewRect.Width -= VScrollBarWidth; + + if (_HScrollBar != null && _HScrollBar.Visible == true) + _CViewRect.Height -= HScrollBarHeight; + } + + return (_CViewRect); + } + } + + #endregion + + #region DisplayedMergeLayoutCount + + internal ushort DisplayedMergeLayoutCount + { + get { return (_DisplayedMergeLayoutCount); } + set { _DisplayedMergeLayoutCount = value; } + } + + #endregion + + #region FilterApplyString + + internal string FilterApplyString + { + get { return (LocalizedString(ref _FilterApplyString)); } + } + + #endregion + + #region FilterCancelString + + internal string FilterCancelString + { + get { return (LocalizedString(ref _FilterCancelString)); } + } + + #endregion + + #region FilterCloseString + + internal string FilterCloseString + { + get { return (LocalizedString(ref _FilterCloseString)); } + } + + #endregion + + #region FilterCustomString + + internal string FilterCustomString + { + get { return (LocalizedString(ref _FilterCustomString)); } + } + + #endregion + + #region FilterOkString + + internal string FilterOkString + { + get { return (LocalizedString(ref _FilterOkString)); } + } + + #endregion + + #region FilterShowAllString + + internal string FilterShowAllString + { + get { return (LocalizedString(ref _FilterShowAllString)); } + } + + #endregion + + #region FilterShowNotNullString + + internal string FilterShowNotNullString + { + get { return (LocalizedString(ref _FilterShowNotNullString)); } + } + + #endregion + + #region FilterShowNullString + + internal string FilterShowNullString + { + get { return (LocalizedString(ref _FilterShowNullString)); } + } + + #endregion + + #region GroupByWaterMarkText + + internal string GroupByWaterMarkText + { + get { return (LocalizedString(ref _GroupByWaterMarkText)); } + } + + #endregion + + #region HasDataErrorHandler + + internal bool HasDataErrorHandler + { + get { return (DataError != null); } + } + + #endregion + + #region HasItemDragHandler + + internal bool HasItemDragHandler + { + get { return (ItemDrag != null); } + } + + #endregion + + #region HScrollBarHeight + + internal int HScrollBarHeight + { + get + { + if (_HScrollBar != null) + return (_HScrollBar.Height); + + return (SystemInformation.HorizontalScrollBarHeight); + } + } + + #endregion + + #region SViewRect + + internal Rectangle SViewRect + { + get + { + Rectangle r = ViewRect; + + if (PrimaryGrid.ShowRowHeaders == true) + { + r.X += _PrimaryGrid.RowHeaderWidthEx; + r.Width -= _PrimaryGrid.RowHeaderWidthEx; + + if (r.Width < 0) + r.Width = 0; + } + + return (r); + } + } + + #endregion + + #region IndiceesUpdateCount + + internal ushort IndiceesUpdateCount + { + get { return (_IndiceesUpdateCount); } + } + + #endregion + + #region IsDesignerHosted + + internal bool IsDesignerHosted + { + get { return (DesignMode); } + } + + #endregion + + #region IsHScrollBarVisible + + internal bool IsHScrollBarVisible + { + get { return (_HScrollBar != null && _HScrollBar.Visible); } + } + + #endregion + + #region IsVScrollBarVisible + + internal bool IsVScrollBarVisible + { + get { return (_VScrollBar != null && _VScrollBar.Visible); } + } + + #endregion + + #region LastActiveCell + + internal GridCell LastActiveCell + { + get { return (_LastActiveCell); } + set { _LastActiveCell = value; } + } + + #endregion + + #region NeedMergeLayout + + private bool _NeedMergeLayout; + + internal bool NeedMergeLayout + { + get { return (_NeedMergeLayout); } + set { _NeedMergeLayout = value; } + } + + #endregion + + #region NeedToUpdateIndicees + + internal bool NeedToUpdateIndicees + { + get { return (_NeedToUpdateIndicees); } + + set + { + _NeedToUpdateIndicees = value; + + if (value == true) + _IndiceesUpdateCount++; + } + } + + #endregion + + #region ScrollBarScrolling + + internal bool ScrollBarScrolling + { + get { return (_ScrollBarScrolling); } + set { _ScrollBarScrolling = value; } + } + + #endregion + + #region SetGridCursor + + internal bool SetGridCursor + { + get { return (_SetGridCursor); } + set { _SetGridCursor = value; } + } + + #endregion + + #region StyleMouseOverUpdateCount + + internal ushort StyleMouseOverUpdateCount + { + get { return (_StyleMouseOverUpdateCount); } + set { _StyleMouseOverUpdateCount = value; } + } + + #endregion + + #region StyleSelectedUpdateCount + + internal ushort StyleSelectedUpdateCount + { + get { return (_StyleSelectedUpdateCount); } + set { _StyleSelectedUpdateCount = value; } + } + + #endregion + + #region StyleSelectedMouseOverUpdateCount + + internal ushort StyleSelectedMouseOverUpdateCount + { + get { return (_StyleSelectedMouseOverUpdateCount); } + set { _StyleSelectedMouseOverUpdateCount = value; } + } + + #endregion + + #region StyleUpdateCount + + internal ushort StyleUpdateCount + { + get { return (_StyleUpdateCount); } + set { _StyleUpdateCount = value; } + } + + #endregion + + #region ToolTip + + /// + /// Gets the Tooltip object used for the grid. + /// + public System.Windows.Forms.ToolTip ToolTip + { + get + { + if (_ToolTip == null) + _ToolTip = new System.Windows.Forms.ToolTip(); + + return (_ToolTip); + } + } + + #endregion + + #region ToolTipText + + internal string ToolTipText + { + get { return (_ToolTipText); } + + set + { + if (_ToolTipText != value) + { + _ToolTipText = value; + + if (string.IsNullOrEmpty(value) == false && value.Length > _MaxToolTipLength) + ToolTip.SetToolTip(this, value.Substring(0, _MaxToolTipLength)); + else + ToolTip.SetToolTip(this, value); + + ToolTip.Active = + (string.IsNullOrEmpty(value) == false); + } + } + } + + #endregion + + #region PrimaryGridSize + + internal Size PrimaryGridSize + { + get + { + Size size = _PrimaryGrid.SizeNeeded; + + int n = (_VScrollOffset > 0) ? + _PrimaryGrid.FixedRowHeight : _PrimaryGrid.FixedHeaderHeight; + + size.Height -= (n + 1); + + if (_PrimaryGrid.Footer != null && _PrimaryGrid.Footer.Visible == true) + size.Height -= _PrimaryGrid.Footer.Size.Height; + + if (PrimaryGrid.ShowRowHeaders == true) + size.Width -= _PrimaryGrid.RowHeaderWidthEx; + + if (size.Width < 0) + size.Width = 0; + + if (size.Height < 0) + size.Height = 0; + + return (size); + } + } + + #endregion + + #region ViewRect + + internal Rectangle ViewRect + { + get + { + if (_ViewRect.IsEmpty == true) + _ViewRect = GetAdjustedBounds(ClientRectangle); + + return (_ViewRect); + } + + set + { + _BoundsUpdateCount++; + + _ViewRect = value; + _CViewRect = value; + } + } + + #endregion + + #region GetAdjustedBounds + + private Rectangle GetAdjustedBounds(Rectangle r) + { + int n = (_VScrollOffset > 0) ? + _PrimaryGrid.FixedRowHeight : _PrimaryGrid.FixedHeaderHeight; + + r.Y += n; + r.Height -= (n + 1); + + if (_PrimaryGrid.Footer != null && _PrimaryGrid.Footer.Visible == true) + r.Height -= _PrimaryGrid.Footer.Size.Height; + + if (_VScrollBar != null && _VScrollBar.Visible == true) + r.Width -= (VScrollBarWidth + 1); + + if (_HScrollBar != null && _HScrollBar.Visible == true) + r.Height -= (HScrollBarHeight + 1); + + if (r.Width < 0) + r.Width = 0; + + if (r.Height < 0) + r.Height = 0; + + return (r); + } + + #endregion + + #region ViewRectEx + + internal Rectangle ViewRectEx + { + get + { + Rectangle r = ViewRect; + + int n = (_VScrollOffset > 0) ? + _PrimaryGrid.FixedRowHeight - _PrimaryGrid.FixedHeaderHeight : 0; + + r.Y -= n; + r.Height += n; + + return (r); + } + } + + #endregion + + #region VScrollBarWidth + + internal int VScrollBarWidth + { + get + { + if (_VScrollBar != null) + return (_VScrollBar.Width); + + return (SystemInformation.VerticalScrollBarWidth); + } + } + + #endregion + + #region DefaultSize + + /// + /// DefaultSize + /// + protected override Size DefaultSize + { + get { return new Size(200, 200); } + } + + #endregion + + #endregion + + #region OnPaint + + #region OnPaint + + /// + /// Renders the control. + /// + /// Paint arguments. + protected override void OnPaint(PaintEventArgs e) + { + if (IsUpdateSuspended == false) + { + SmoothingMode sm = e.Graphics.SmoothingMode; + TextRenderingHint th = e.Graphics.TextRenderingHint; + + base.OnPaintBackground(e); + + if (_PrimaryGrid.IsLayoutValid == false) + ArrangeGrid(e.Graphics); + + GridRenderInfo renderInfo = GetGridRenderInfo(e); + + PaintControl(renderInfo); + + e.Graphics.SmoothingMode = sm; + e.Graphics.TextRenderingHint = th; + + base.OnPaint(e); + +#if !TRIAL + if (NativeFunctions.keyValidated2 != 266) + { + TextDrawing.DrawString(e.Graphics, "Invalid License", Font, + Color.FromArgb(180, Color.Red), ClientRectangle, + eTextFormat.Bottom | eTextFormat.HorizontalCenter); + } +#else + RenderWaterMark(renderInfo); +#endif + } + } + + #endregion + + #region PaintControl + + private void PaintControl(GridRenderInfo renderInfo) + { + Rectangle r = ClientRectangle; + r.Intersect(renderInfo.ClipRectangle); + + if (r.Width > 0 && r.Height > 0) + _PrimaryGrid.Render(renderInfo); + + RenderScrollBoxArea(renderInfo); + + NeedMergeLayout = false; + } + + #endregion + + #region RenderScrollBoxArea + + private void RenderScrollBoxArea(GridRenderInfo renderInfo) + { + if (_HScrollBar.Visible && _VScrollBar.Visible) + { + Rectangle r = _HScrollBar.Bounds; + r.X = _VScrollBar.Bounds.X; + r.Width = _VScrollBar.Bounds.Width; + + if (r.IntersectsWith(renderInfo.ClipRectangle)) + { + Graphics g = renderInfo.Graphics; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + g.FillRectangle(SystemBrushes.Control, r); + + g.SmoothingMode = sm; + } + } + } + + #endregion + + #region RenderWaterMark + + private void RenderWaterMark(GridRenderInfo renderInfo) + { + Rectangle r = ViewRect; + r.X = r.Right - 30; + r.Width = 30; + + if (r.IntersectsWith(renderInfo.ClipRectangle) == true) + { + Graphics g = renderInfo.Graphics; + + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + sf.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.DirectionVertical; + + using (Font font = new Font("Times New Roman", 9)) + { + Rectangle t = r; + t.X++; + t.Y++; + + using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Gray))) + { + g.DrawString("DevComponents SuperGrid Trial", + font, brush, t, sf); + } + + using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Gainsboro))) + { + g.DrawString("DevComponents SuperGrid Trial", + font, brush, r, sf); + } + } + } + } + } + + #endregion + + #endregion + + #region ArrangeGrid + + /// + /// OnHandleCreated + /// + /// + protected override void OnHandleCreated(EventArgs e) + { + ArrangeGrid(); + + base.OnHandleCreated(e); + } + + /// + /// Performs grid layout. + /// + public void ArrangeGrid() + { + ArrangeGrid(false); + } + + /// + /// Performs grid layout. + /// + ///Whether to force operation even if layout is valid. + public void ArrangeGrid(bool force) + { + if (force == true || _PrimaryGrid.IsLayoutValid == false) + { + if (_InArrangeGrid == false) + { + _InArrangeGrid = true; + + try + { + using (Graphics g = CreateGraphics()) + ArrangeGrid(g); + } + finally + { + _InArrangeGrid = false; + } + } + } + } + + private void ArrangeGrid(Graphics g) + { + ArrangeLayoutCount++; + DisplayedMergeLayoutCount++; + + GridLayoutInfo layoutInfo = GetGridLayoutInfo(g); + GridLayoutStateInfo stateInfo = new GridLayoutStateInfo(_PrimaryGrid, 0); + + Size constraintSize = Size.Empty; + + _PrimaryGrid.Measure(layoutInfo, stateInfo, constraintSize); + + stateInfo.PassCount++; + + CanScrollEx = true; + NeedToUpdateIndicees = false; + + if (HorizontalIsOver(layoutInfo) == true && _HScrollBarVisible) + { + if(_HScrollBarVisible) + layoutInfo.ClientBounds.Height -= HScrollBarHeight; + + if (VerticalIsOver(layoutInfo) == true && _VScrollBarVisible) + layoutInfo.ClientBounds.Width -= VScrollBarWidth; + + _PrimaryGrid.Measure(layoutInfo, stateInfo, constraintSize); + } + else + { + if (VerticalIsOver(layoutInfo) == true && _VScrollBarVisible) + { + layoutInfo.ClientBounds.Width -= VScrollBarWidth; + + _PrimaryGrid.Measure(layoutInfo, stateInfo, constraintSize); + + if (HorizontalIsOver(layoutInfo) == true && _HScrollBarVisible) + layoutInfo.ClientBounds.Height -= HScrollBarHeight; + } + } + + layoutInfo.ClientBounds.Width = Math.Max(0, layoutInfo.ClientBounds.Width); + layoutInfo.ClientBounds.Height = Math.Max(0, layoutInfo.ClientBounds.Height); + + EnableVScrollBar(layoutInfo); + EnableHScrollBar(layoutInfo); + + ViewRect = Rectangle.Empty; + _PrimaryGrid.Arrange(layoutInfo, stateInfo, layoutInfo.ClientBounds); + ViewRect = Rectangle.Empty; + + UpdateScrollBars(layoutInfo); + + if (_ActiveEditor != null) + EditorCell.PositionEditPanel(_ActiveEditor); + + if (NonModalEditorCell != null) + NonModalEditorCell.PositionEditPanel(_ActiveNonModalEditor); + + if (ActiveFilterPanel != null) + _ActiveFilterPanel.PositionEditPanel(); + } + + #region GetGridLayoutInfo + + private GridLayoutInfo GetGridLayoutInfo(Graphics g) + { + GridLayoutInfo layoutInfo = new GridLayoutInfo(g, GetGridItemBounds()); + + layoutInfo.RightToLeft = (RightToLeft == RightToLeft.No); + layoutInfo.DefaultVisualStyles = _DefaultVisualStyles; + + return (layoutInfo); + } + + #endregion + + #region GetGridItemBounds + + private Rectangle GetGridItemBounds() + { + return (ClientRectangle); + } + + #endregion + + #region GetGridRenderInfo + + private GridRenderInfo GetGridRenderInfo(PaintEventArgs e) + { + GridRenderInfo renderInfo = + new GridRenderInfo(e.Graphics, Rectangle.Ceiling(e.ClipRectangle)); + + renderInfo.RightToLeft = (RightToLeft == RightToLeft.Yes); + + return (renderInfo); + } + + #endregion + + #endregion + + #region Scrollbar support + + #region UpdateScrollBars + + private void UpdateScrollBars(GridLayoutInfo layoutInfo) + { + if (_HScrollBarEnabled == true) + { + _HScrollBar.SmallChange = layoutInfo.ClientBounds.Width / 20; + _HScrollBar.Maximum = Math.Max(0, PrimaryGridSize.Width); + _HScrollBar.LargeChange = Math.Min(SViewRect.Width, _HScrollBar.Maximum); + + if (_HScrollBar.Value + _HScrollBar.LargeChange > _HScrollBar.Maximum) + { + _HScrollBar.Value = _HScrollBar.Maximum - _HScrollBar.LargeChange; + _HScrollOffset = _HScrollBar.Value; + } + + _HScrollBar.Refresh(); + } + + if (_VScrollBarEnabled == true) + { + _VScrollBar.SmallChange = layoutInfo.ClientBounds.Height / 20; + _VScrollBar.Maximum = Math.Max(0, PrimaryGridSize.Height); + _VScrollBar.LargeChange = Math.Min(SViewRect.Height, _VScrollBar.Maximum); + + if (_VScrollBar.Value + _VScrollBar.LargeChange > _VScrollBar.Maximum) + { + _VScrollBar.Value = _VScrollBar.Maximum - _VScrollBar.LargeChange; + _VScrollOffset = _VScrollBar.Value; + } + + _VScrollBar.Refresh(); + } + } + + #endregion + + #region EnableHScrollBar + + private void EnableHScrollBar(GridLayoutInfo layoutInfo) + { + bool enable = _HScrollBarVisible && (_PrimaryGrid.Size.Width > layoutInfo.ClientBounds.Width); + + if (enable == true) + { + _HScrollBar.Location = new + Point(layoutInfo.ClientBounds.Left + 1, + layoutInfo.ClientBounds.Bottom - 1); + + int n = layoutInfo.ClientBounds.Width - 2; + + if (_VScrollBar.Visible == true) + n++; + + _HScrollBar.Width = n; + } + else + { + _HScrollBar.Value = 0; + _HScrollOffset = 0; + } + + _HScrollBarEnabled = enable; + + _HScrollBar.Enabled = enable; + _HScrollBar.Visible = enable; + } + + #endregion + + #region EnableVScrollBar + + private void EnableVScrollBar(GridLayoutInfo layoutInfo) + { + bool enable = _VScrollBarVisible && (_PrimaryGrid.Size.Height > layoutInfo.ClientBounds.Height); + + if (enable == true) + { + _VScrollBar.Location = new + Point(layoutInfo.ClientBounds.Right - 1, + layoutInfo.ClientBounds.Top + 1); + + int n = layoutInfo.ClientBounds.Height - 2; + + if (_HScrollBarVisible && (_PrimaryGrid.Size.Width > layoutInfo.ClientBounds.Width)) + n++; + + _VScrollBar.Height = n; + } + else + { + _VScrollBar.Value = 0; + _VScrollOffset = 0; + } + + _VScrollBarEnabled = enable; + + _VScrollBar.Enabled = enable; + _VScrollBar.Visible = enable; + } + + #endregion + + #region HScrollBarScroll + + private void HScrollBarScroll(object sender, ScrollEventArgs e) + { + ScrollBarAdv sbar = + sender as ScrollBarAdv; + + if (sbar != null) + { + if (_HScrollOffset != e.NewValue) + { + int oldValue = _HScrollOffset; + _HScrollOffset = e.NewValue; + + PostHScrollUpdateEx(oldValue, _HScrollOffset); + + DoScrollEvent(_PrimaryGrid, e, sbar); + } + } + } + + #endregion + + #region VScrollBarScroll + + private void VScrollBarScroll(object sender, ScrollEventArgs e) + { + ScrollBarAdv sbar = + sender as ScrollBarAdv; + + if (sbar != null) + { + if (_VScrollOffset != e.NewValue) + { + int oldValue = _VScrollOffset; + _VScrollOffset = e.NewValue; + + PostVScrollUpdateEx(oldValue, _VScrollOffset); + + DoScrollEvent(_PrimaryGrid, e, sbar); + } + } + } + + #endregion + + #region HorizontalIsOver + + private bool HorizontalIsOver(GridLayoutInfo layoutInfo) + { + return (_PrimaryGrid.Size.Width > layoutInfo.ClientBounds.Width); + } + + #endregion + + #region VerticalIsOver + + private bool VerticalIsOver(GridLayoutInfo layoutInfo) + { + return (_PrimaryGrid.Size.Height > layoutInfo.ClientBounds.Height); + } + + #endregion + + #region SetupScrollBars + + private void SetupScrollBars() + { + if (_VScrollBar == null) + { + _VScrollBar = new VScrollBarAdv(); + _VScrollBar.Width = Dpi.DescaleWidth(SystemInformation.VerticalScrollBarWidth); + _VScrollBar.Scroll += VScrollBarScroll; + _VScrollBar.MouseEnter += ScrollBarMouseEnter; + _VScrollBar.SizeChanged += ScrollBarSizeChanged; + + _VScrollBar.MouseDown += ScrollBar_MouseDown; + _VScrollBar.MouseUp += ScrollBar_MouseUp; + + _VScrollBar.Visible = false; + + Controls.Add(_VScrollBar); + } + + if (_HScrollBar == null) + { + _HScrollBar = new HScrollBarAdv(); + _HScrollBar.Height = Dpi.DescaleHeight(SystemInformation.HorizontalScrollBarHeight); + _HScrollBar.Scroll += HScrollBarScroll; + _HScrollBar.MouseEnter += ScrollBarMouseEnter; + _HScrollBar.SizeChanged += ScrollBarSizeChanged; + + _HScrollBar.MouseDown += ScrollBar_MouseDown; + _HScrollBar.MouseUp += ScrollBar_MouseUp; + + _HScrollBar.Visible = false; + + Controls.Add(_HScrollBar); + } + } + + void ScrollBar_MouseUp(object sender, MouseEventArgs e) + { + ScrollBarScrolling = false; + } + + void ScrollBar_MouseDown(object sender, MouseEventArgs e) + { + ScrollBarScrolling = true; + } + + private void ScrollBarSizeChanged(object sender, EventArgs e) + { + _PrimaryGrid.InvalidateLayout(); + } + + void ScrollBarMouseEnter(object sender, EventArgs e) + { + SetGridCursor = true; + Cursor = Cursors.Default; + SetGridCursor = false; + } + + #endregion + + #region SetVScrollValue + + internal void SetVScrollValue(int value) + { + if (_VScrollBar.Visible == true) + { + int oldValue = _VScrollBar.Value; + + value = Math.Max(value, 0); + value = Math.Min(value, _VScrollBar.Maximum); + + if (value + _VScrollBar.LargeChange - 1 > _VScrollBar.Maximum) + value = _VScrollBar.Maximum - _VScrollBar.LargeChange + 1; + + value = Math.Max(value, 0); + + if (_VScrollBar.Value != value) + { + _VScrollBar.Value = value; + _VScrollOffset = value; + + PostVScrollUpdateEx(oldValue, value); + + if (Scroll != null || ScrollMin != null || ScrollMax != null) + { + ScrollEventArgs e = new ScrollEventArgs(ScrollEventType.EndScroll, + oldValue, value, ScrollOrientation.VerticalScroll); + + DoScrollEvent(_PrimaryGrid, e, _VScrollBar); + } + } + } + } + + #endregion + + #region SetHScrollValue + + internal void SetHScrollValue(int value) + { + if (_HScrollBar.Visible == true) + { + int oldValue = _HScrollBar.Value; + + value = Math.Max(value, 0); + value = Math.Min(value, _HScrollBar.Maximum); + + if (value + _HScrollBar.LargeChange > _HScrollBar.Maximum) + value = _HScrollBar.Maximum - _HScrollBar.LargeChange; + + value = Math.Max(value, 0); + + if (_HScrollBar.Value != value) + { + _HScrollBar.Value = value; + _HScrollOffset = value; + + PostHScrollUpdateEx(oldValue, value); + + if (Scroll != null || ScrollMin != null || ScrollMax != null) + { + ScrollEventArgs e = new ScrollEventArgs(ScrollEventType.EndScroll, + oldValue, value, ScrollOrientation.HorizontalScroll); + + DoScrollEvent(_PrimaryGrid, e, _HScrollBar); + } + } + } + } + + #endregion + + #region PostScrollUpdate + + private void PostScrollUpdate() + { + ViewRect = Rectangle.Empty; + + _PrimaryGrid.InvalidateRender(); + + PostScrollRefresh(); + } + + #endregion + + #region PostVScrollUpdateEx + + private void PostVScrollUpdateEx(int oldValue, int newValue) + { + if (CanVScrollWindowEx()) + { + int dv = oldValue - newValue; + + ViewRect = Rectangle.Empty; + Rectangle vr = ViewRect; + + RECT scroll = new RECT(0, vr.Top, vr.Right, vr.Bottom); + RECT update = new RECT(); + + ScrollWindowEx( + Handle, + 0, + dv, + ref scroll, + ref scroll, + IntPtr.Zero, + ref update, + 0); + + Rectangle r = new Rectangle(update.X, update.Y, update.Width, update.Height); + r.Inflate(0, 4); + + Invalidate(r); + + PostScrollRefresh(); + } + else + { + PostScrollUpdate(); + } + } + + #region CanVScrollWindowEx + + private bool CanVScrollWindowEx() + { + if (IsUpdateSuspended == true || + (EnableFastScrolling == false || CanScrollEx == false)) + { + return (false); + } + + return (_PrimaryGrid.FrozenRowCount == 0); + } + + #endregion + + #endregion + + #region PostHScrollUpdateEx + + private void PostHScrollUpdateEx(int oldValue, int newValue) + { + if (CanHScrollWindowEx() == true) + { + int dh = oldValue - newValue; + + ViewRect = Rectangle.Empty; + Rectangle vr = ViewRect; + + int n = vr.Y - _PrimaryGrid.ColumnHeader.Bounds.Y; + vr.Y -= n; + vr.Height += n; + + if (_PrimaryGrid.ShowRowHeaders == true) + { + vr.X += _PrimaryGrid.RowHeaderWidthEx; + vr.Width -= _PrimaryGrid.RowHeaderWidthEx; + } + else + { + vr.X++; + vr.Width--; + } + + RECT scroll = new RECT(vr.Left, vr.Top, vr.Right - 1, vr.Bottom); + RECT update = new RECT(); + + ScrollWindowEx( + Handle, + dh, + 0, + ref scroll, + ref scroll, + IntPtr.Zero, + ref update, + 0); + + Rectangle r = new Rectangle(update.X, update.Y, update.Width, update.Height); + r.Inflate(4, 0); + + Invalidate(r); + + PostScrollRefresh(); + } + else + { + PostScrollUpdate(); + } + } + + #region CanHScrollWindowEx + + private bool CanHScrollWindowEx() + { + if (IsUpdateSuspended == true || EnableFastScrolling == false) + return (false); + + if (_PrimaryGrid.EnableCellMerging == true || _PrimaryGrid.IsGrouped == true) + return (false); + + if (_PrimaryGrid.Header.Visible == true && _PrimaryGrid.Header.Size.Height > 0) + return (false); + + if (_PrimaryGrid.IsGrouped == true) + return (false); + + return (_PrimaryGrid.FrozenColumnCount == 0); + } + + #endregion + + #endregion + + #region PostScrollRefresh + + private void PostScrollRefresh() + { + if (_EditorCell != null) + _EditorCell.PositionEditPanel(_ActiveEditor); + + if (_ActiveFilterPanel != null) + _ActiveFilterPanel.PositionEditPanel(); + + if (_ActiveNonModalEditor != null) + DeactivateNonModalEditor(); + + PostInternalMouseMove(); + + DisplayedMergeLayoutCount++; + } + + #endregion + + #endregion + + #region InvalidateRender + + /// + /// Invalidates render of the grid element. + /// + /// Element to invalidate rendering for. + internal void InvalidateRender(GridElement gridElement) + { + Rectangle bounds = gridElement.BoundsRelative; + + if (gridElement.Parent != null) + { + if (gridElement is GridColumn == false || ((GridColumn)gridElement).IsHFrozen == false) + bounds.X -= _HScrollOffset; + + if (bounds.Y > _PrimaryGrid.FixedRowHeight) + bounds.Y -= _VScrollOffset; + } + + Invalidate(bounds, true); + } + + internal void InvalidateRender(Rectangle bounds) + { + Invalidate(bounds, InvokeRequired == false); + } + + #endregion + + #region Mouse Support + + #region OnMouseLeave + + /// + /// OnMouseLeave + /// + /// + protected override void OnMouseLeave(EventArgs e) + { + _PrimaryGrid.InternalMouseLeave(e); + + base.OnMouseLeave(e); + } + + #endregion + + #region OnMouseMove + + /// + /// OnMouseMove + /// + /// + protected override void OnMouseMove(MouseEventArgs e) + { + if (CanProcessMouseMove()) + { + if (CapturedItem != null) + CapturedItem.InternalMouseMove(e); + else + _PrimaryGrid.InternalMouseMove(e); + + base.OnMouseMove(e); + + base.Cursor = _GridCursor; + + if (_PrimaryGrid.IsDesignerHosted == true) + Cursor = Cursors.Arrow; + } + } + + private bool CanProcessMouseMove() + { + return (Keyboard.IsKeyDown(Keys.Up) == false && Keyboard.IsKeyDown(Keys.Down) == false && + Keyboard.IsKeyDown(Keys.Left) == false && Keyboard.IsKeyDown(Keys.Right) == false); + } + + #endregion + + #region OnMouseDown + + /// + /// OnMouseDown + /// + /// + protected override void OnMouseDown(MouseEventArgs e) + { + Focus(); + + base.OnMouseDown(e); + + _PrimaryGrid.InternalMouseDown(e); + } + + #endregion + + #region OnMouseUp + + /// + /// OnMouseUp + /// + /// + protected override void OnMouseUp(MouseEventArgs e) + { + DisableAutoScrolling(); + + if (CapturedItem != null) + CapturedItem.InternalMouseUp(e); + else + _PrimaryGrid.InternalMouseUp(e); + + base.OnMouseUp(e); + + if (_ActiveEditor != null) + _ActiveEditor.EditorCell.FocusEditor(_ActiveEditor); + } + + #endregion + + #region OnMouseClick + + /// + /// OnMouseClick + /// + /// + protected override void OnMouseClick(MouseEventArgs e) + { + _PrimaryGrid.InternalMouseClick(e); + + base.OnMouseClick(e); + } + + #endregion + + #region OnMouseDoubleClick + + /// + /// OnMouseDoubleClick + /// + /// + protected override void OnMouseDoubleClick(MouseEventArgs e) + { + _PrimaryGrid.InternalMouseDoubleClick(e); + + base.OnMouseDoubleClick(e); + } + + #endregion + + #region OnMousewheel + + protected override void OnMouseWheel(MouseEventArgs e) + { + if (CanProcessMouseWheel() == true) + MouseWheelHandler(e.Delta / SystemInformation.MouseWheelScrollDelta); + + base.OnMouseWheel(e); + } + + private void MouseWheelHandler(int delta) + { + int value = -(delta * SystemInformation.MouseWheelScrollLines); + + value *= _VScrollBar.SmallChange; + value += _VScrollBar.Value; + + SetVScrollValue(value); + + Cursor.Position = Cursor.Position; + } + + #endregion + + #endregion + + #region Keyboard support + + #region IsInputChar + + /// + /// IsInputChar + /// + /// + /// + protected override bool IsInputChar(char charCode) + { + if (char.IsLetterOrDigit(charCode)) + return (true); + + return (base.IsInputChar(charCode)); + } + + #endregion + + #region OnKeyDown + + /// + /// Handles KeyDown events + /// + /// + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + + if (e.Handled == false) + { + if (e.Handled == true || + ProcessInCellKeyDown(e.KeyData) == true) + { + e.SuppressKeyPress = true; + } + } + } + + #endregion + + #region OnKeyPress + + /// + /// Handles KeyPress events + /// + /// + protected override void OnKeyPress(KeyPressEventArgs e) + { + GridCell cell = GetCellToEdit(); + + if (cell != null) + { + if (cell.CellEditMode == CellEditMode.Modal) + { + switch (cell.GridPanel.KeyboardEditMode) + { + case KeyboardEditMode.EditOnKeystroke: + case KeyboardEditMode.EditOnKeystrokeOrF2: + if (cell.CanSetActiveCell(cell.GridPanel) == true) + { + if (cell.BeginEdit(true) != null) + { + Keys modifiers = ModifierKeys; + + bool shift = ((modifiers & Keys.Shift) == Keys.Shift) ^ + (Console.CapsLock == true); + + if (shift == true) + modifiers |= Keys.Shift; + else + modifiers &= ~Keys.Shift; + + Keys keyData = _LastKeyDown | modifiers; + + if (_ActiveEditor.WantsInputKey(keyData, false) == true) + PressKeyDown((ushort)(keyData)); + } + } + break; + } + } + else + { + cell.PostCellKeyDown(_LastKeyDown); + } + } + + base.OnKeyPress(e); + } + + #endregion + + #region ProcessInCellKeyDown + + private bool ProcessInCellKeyDown(Keys keyData) + { + if (ProcessGridKeyDown(keyData) == false) + { + if (keyData == Keys.F2) + { + GridCell cell = GetCellToEdit(); + + if (cell != null) + { + if (cell.CellEditMode == CellEditMode.Modal) + { + switch (cell.GridPanel.KeyboardEditMode) + { + case KeyboardEditMode.EditOnF2: + case KeyboardEditMode.EditOnKeystrokeOrF2: + if (cell.IsEmptyCell == false) + { + if (cell.CanSetActiveCell(cell.GridPanel) == true) + { + cell.BeginEdit(false); + return (true); + } + } + break; + } + } + } + } + + return (false); + } + + return (true); + } + + #endregion + + #region PressKeyDown + + /// + /// Sends the given input scanCode to the + /// current active edit control + /// + /// + public void PressKeyDown(ushort scanCode) + { + _KeyPressSent = true; + + if (Marshal.SizeOf(new IntPtr()) == 8) + SendInput64(scanCode); + else + SendInput32(scanCode); + } + + private void SendInput32(ushort scanCode) + { + Input32[] inputs = new Input32[1]; + + inputs[0].type = InputKeyboard; + inputs[0].ki = new KeyBoardInput(scanCode); + + SendInput(1, inputs, Marshal.SizeOf(inputs[0])); + } + + private void SendInput64(ushort scanCode) + { + Input64[] inputs = new Input64[1]; + + inputs[0].type = InputKeyboard; + inputs[0].ki = new KeyboardInput64(scanCode); + + SendInput(1, inputs, Marshal.SizeOf(inputs[0])); + } + + #endregion + + #region GetCellToEdit + + private GridCell GetCellToEdit() + { + GridPanel panel = _ActiveGrid; + + if (panel != null && panel.SuperGrid.Focused == true) + { + if (panel.ReadOnly == true) + return (null); + + if (panel.SelectionGranularity != SelectionGranularity.Cell) + { + GridRow row = panel.ActiveRow as GridRow; + + if (row != null) + { + if (panel.PrimaryColumn != null && + panel.PrimaryColumn.Visible == true) + { + if (row.Cells.Count > panel.PrimaryColumnIndex) + return (row.Cells[panel.PrimaryColumnIndex]); + } + + return (row.FirstVisibleCell); + } + } + else + { + GridCell cell = ActiveElement as GridCell; + + if (cell != null) + { + if (cell.AllowSelection == true) + return (cell); + } + } + } + + return (null); + } + + #endregion + + #region SuperGridControlPreviewKeyDown + + void SuperGridControlPreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + DoPreviewKeyDown(e.KeyData); + + if (e.KeyData == Keys.Tab || + e.KeyData == (Keys.Tab | Keys.Shift)) + { + if (_TabSelection != TabSelection.Control) + e.IsInputKey = true; + } + else + { + if (GridWantsKey(e.KeyData) == true) + e.IsInputKey = true; + } + } + + #endregion + + #endregion + + #region ProcessInFilterEditKeyDown + + private bool ProcessInFilterEditKeyDown(Keys keyData) + { + bool wantsKey = GridWantsKey(keyData); + + wantsKey = ActiveFilterPanel.WantsInputKey(keyData, wantsKey); + + if (wantsKey == false) + return (ProcessFilterEditKeyDown(keyData)); + + return (false); + } + + #endregion + + #region ProcessInEditKeyDown + + private bool ProcessInEditKeyDown(Keys keyData) + { + bool wantsKey = GridWantsKey(keyData); + + wantsKey = _ActiveEditor.WantsInputKey(keyData, wantsKey); + + if (wantsKey == false) + ProcessInEditGridKeyDown(keyData); + + return (wantsKey == false); + } + + #endregion + + #region ProcessInEditGridKeyDown + + private void ProcessInEditGridKeyDown(Keys keyData) + { + switch (keyData) + { + case Keys.Escape: + _EditorCell.CancelEdit(); + break; + + case Keys.Enter: + if (_EditorCell.EndEdit() == true) + ProcessGridKeyDown(keyData); + break; + + default: + if (GridWantsKey(keyData) == true) + { + if (_EditorCell.EndEdit() == true) + ProcessGridKeyDown(keyData); + } + break; + } + } + + #endregion + + #region ProcessGridKeyDown + + #region ProcessGridKeyDown + + private bool ProcessGridKeyDown(Keys keyData) + { + if (ActiveElement == null) + { + switch (_PrimaryGrid.SelectionGranularity) + { + case SelectionGranularity.Cell: + SetFirstAvailableCell(_PrimaryGrid, false); + break; + + default: + SetFirstAvailableRow(_PrimaryGrid, false); + break; + } + + switch (keyData) + { + case Keys.Tab | Keys.Control: + Parent.SelectNextControl(this, true, true, true, true); + return (true); + + case Keys.Tab | Keys.Shift | Keys.Control: + Parent.SelectNextControl(this, false, true, true, true); + return (true); + + case Keys.Insert: + if (_PrimaryGrid != null) + { + if (_PrimaryGrid.Rows.Count == 0) + { + if (_PrimaryGrid.DataBinder.CanInsertRow == true) + { + _PrimaryGrid.InsertRow(0); + return (true); + } + } + } + break; + } + + return (false); + } + + if (ActiveElement.GridPanel == null) + return (false); + + bool processed = true; + + if (keyData == Keys.Escape) + CancelCapture(); + + bool ms = ActiveElement.GridPanel.MultiSelect; + + switch (keyData) + { + case Keys.NumLock: + break; + + case Keys.Down: + ProcessDownKey(true, false); + break; + + case Keys.Down | Keys.Control: + ProcessDownKey(false, false); + break; + + case Keys.Down | Keys.Shift: + case Keys.Down | Keys.Shift | Keys.Control: + ProcessDownKey(true, ms); + break; + + case Keys.End: + ProcessEndKey(false); + break; + + case Keys.End | Keys.Shift: + ProcessEndKey(ms); + break; + + case Keys.End | Keys.Control: + ProcessCtrlEndKey(false); + break; + + case Keys.End | Keys.Control | Keys.Shift: + ProcessCtrlEndKey(ms); + break; + + case Keys.Enter: + ProcessEnterKey(true, false); + break; + + case Keys.Enter | Keys.Shift: + case Keys.Enter | Keys.Control: + case Keys.Enter | Keys.Shift | Keys.Control: + ProcessShiftEnterKey(); + break; + + case Keys.Escape: + if (ProcessEscapeKey() == false) + { + Form form = FindForm(); + + if (form != null && form.CancelButton != null) + form.CancelButton.PerformClick(); + } + break; + + case Keys.Home: + ProcessHomeKey(false); + break; + + case Keys.Home | Keys.Shift: + ProcessHomeKey(ms); + break; + + case Keys.Home | Keys.Control: + ProcessCtrlHomeKey(false); + break; + + case Keys.Home | Keys.Control | Keys.Shift: + ProcessCtrlHomeKey(ms); + break; + + case Keys.Left: + ProcessLeftKey(true, false); + break; + + case Keys.Left | Keys.Shift: + case Keys.Left | Keys.Shift | Keys.Control: + ProcessLeftKey(true, ms); + break; + + case Keys.Left | Keys.Control: + ProcessLeftKey(false, false); + break; + + case Keys.PageUp: + ProcessPageUpKey(false); + break; + + case Keys.PageUp | Keys.Shift: + case Keys.PageUp | Keys.Shift | Keys.Control: + ProcessPageUpKey(ms); + break; + + case Keys.PageDown: + ProcessPageDownKey(false); + break; + + case Keys.PageDown | Keys.Shift: + case Keys.PageDown | Keys.Shift | Keys.Control: + ProcessPageDownKey(ms); + break; + + case Keys.Tab: + processed = ProcessTabKey(); + break; + + case Keys.Tab | Keys.Shift: + processed = ProcessShiftTabKey(); + break; + + case Keys.Tab | Keys.Control: + Parent.SelectNextControl(this, true, true, true, true); + break; + + case Keys.Tab | Keys.Shift | Keys.Control: + Parent.SelectNextControl(this, false, true, true, true); + break; + + case Keys.Right: + ProcessRightKey(true, false); + break; + + case Keys.Right | Keys.Shift: + case Keys.Right | Keys.Shift | Keys.Control: + ProcessRightKey(true, ms); + break; + + case Keys.Right | Keys.Control: + ProcessRightKey(false, false); + break; + + case Keys.Space: + if (ActiveElement is GridContainer) + { + GridContainer item = (GridContainer)ActiveElement; + + item.Expanded = !item.Expanded; + } + else + { + processed = false; + + if (ActiveElement is GridCell) + { + GridCell cell = (GridCell)ActiveElement; + + if (cell.Merged && cell.MergeSuspended == false) + { + cell.SuspendMerge(false); + processed = true; + } + } + } + break; + + case Keys.Space | Keys.Shift: + ProcessShiftSpaceKey(ms); + break; + + case Keys.Space | Keys.Control: + ProcessCtrlSpaceKey(ms); + break; + + case Keys.Up: + ProcessUpKey(true, false); + break; + + case Keys.Up | Keys.Shift: + case Keys.Up | Keys.Shift | Keys.Control: + ProcessUpKey(true, ms); + break; + + case Keys.Up | Keys.Control: + ProcessUpKey(false, false); + break; + + case Keys.Delete: + ProcessDeleteKey(); + break; + + case Keys.Delete | Keys.Shift: + ProcessShiftDeleteKey(); + break; + + case Keys.Insert: + ProcessInsertKey(); + break; + + case Keys.Insert | Keys.Shift: + ProcessShiftInsertKey(); + break; + + default: + processed = false; + break; + } + + return (processed); + } + + #endregion + + #region ProcessEscapeKey + + private bool ProcessEscapeKey() + { + if (ActiveElement is GridCell) + { + GridCell cell = (GridCell)ActiveElement; + + if (cell.MergeSuspended == true) + { + cell.ResumeMerge(null); + + return (true); + } + } + + GridRow row = ActiveRow as GridRow; + + if (row != null) + { + GridPanel panel = row.GridPanel; + + if (row.IsInsertRow == false && + row.IsTempInsertRow == true) + { + row.RowNeedsStored = false; + + if (panel.VirtualMode == true) + { + panel.VirtualRowCountEx--; + panel.VirtualRows.MaxRowIndex = row.RowIndex - 1; + + panel.LatentActiveRowIndex = row.RowIndex; + panel.LatentActiveContainer = panel; + + panel.VirtualTempInsertRow = null; + + panel.InvalidateLayout(); + row.Dispose(); + } + else + { + panel.LatentActiveRowIndex = row.RowIndex; + panel.LatentActiveContainer = panel; + + panel.Rows.Remove(row); + + _LastProcessedItem = null; + } + + ActiveRow = null; + panel.ActiveRow = null; + + return (true); + } + } + + return (false); + } + + #endregion + + #region ProcessPageUpKey + + private void ProcessPageUpKey(bool extend) + { + try + { + BeginUpdate(); + + if (ActiveElement is GridCell) + ProcessCellPageUpKey(extend); + + else if (ActiveElement is GridContainer) + ProcessRowPageUpKey(extend); + } + finally + { + EndUpdate(); + } + } + + #region ProcessCellPageUpKey + + private void ProcessCellPageUpKey(bool extend) + { + GridCell cell = (GridCell)ActiveElement; + + GridPanel panel = cell.GridPanel; + GridContainer lrow = cell.GridRow; + + GridContainer container = panel.FirstOnScreenRow; + + if (lrow == container) + { + lrow.ScrollToBottom(); + + container = panel.FirstOnScreenRow; + } + + while (container != null) + { + GridRow row = container as GridRow; + + if (row != null) + { + GridCell ecell = row.GetCell(cell.ColumnIndex, + panel.AllowEmptyCellSelection); + + if (ecell != null) + { + if (ecell.AllowSelection == true) + { + KeySelectCell(panel, ecell, true, extend); + break; + } + } + } + + container = container.PrevVisibleRow; + } + } + + #endregion + + #region ProcessRowPageUpKey + + private void ProcessRowPageUpKey(bool extend) + { + GridContainer lrow = (GridContainer)ActiveElement; + GridPanel panel = lrow.GridPanel; + + GridContainer row = panel.FirstOnScreenRow; + + if (lrow != row) + { + KeySelectRow(panel, row, true, extend); + } + else + { + lrow.ScrollToBottom(); + + KeySelectRow(panel, panel.FirstOnScreenRow, true, extend); + } + } + + #endregion + + #endregion + + #region ProcessPageDownKey + + private void ProcessPageDownKey(bool extend) + { + try + { + BeginUpdate(); + + if (ActiveElement is GridCell) + ProcessCellPageDownKey(extend); + + else if (ActiveElement is GridContainer) + ProcessRowPageDownKey(extend); + } + finally + { + EndUpdate(); + } + } + + #region ProcessCellPageDownKey + + private void ProcessCellPageDownKey(bool extend) + { + GridCell cell = (GridCell)ActiveElement; + + GridPanel panel = cell.GridPanel; + GridContainer lrow = cell.GridRow; + + GridContainer container = panel.LastOnScreenRow; + + if (lrow.GridIndex == container.GridIndex) + { + lrow.ScrollToTop(); + + container = panel.LastOnScreenRow; + } + + while (container != null) + { + GridRow row = container as GridRow; + + if (row != null) + { + GridCell ecell = row.GetCell(cell.ColumnIndex, + panel.AllowEmptyCellSelection); + + if (ecell != null) + { + if (ecell.AllowSelection == true) + { + KeySelectCell(panel, ecell, true, extend); + break; + } + } + } + + container = container.NextVisibleRow; + } + } + + #endregion + + #region ProcessRowPageDownKey + + private void ProcessRowPageDownKey(bool extend) + { + GridContainer lrow = (GridContainer)ActiveElement; + GridPanel panel = lrow.GridPanel; + + GridContainer row = panel.LastOnScreenRow; + + if (lrow != row) + { + KeySelectRow(panel, row, true, extend); + } + else + { + lrow.ScrollToTop(); + + row = panel.LastOnScreenRow; + + KeySelectRow(panel, row, true, extend); + } + } + + #endregion + + #endregion + + #region ProcessEnterKey + + private void ProcessEnterKey(bool select, bool extend) + { + if (ActiveElement is GridCell) + { + GridCell cell = (GridCell) ActiveElement; + GridPanel panel = cell.GridPanel; + + if (cell.GridRow.IsInsertRow == true) + { + cell.BeginEdit(false); + cell.EditorDirty = true; + cell.EndEdit(); + } + else + { + if (panel.EnterKeySelectsNextRow == true) + ProcessCellDownKey(select, extend); + else + cell.EndEdit(); + } + } + else if (ActiveElement is GridContainer) + { + GridContainer row = (GridContainer)ActiveElement; + GridPanel panel = row.GridPanel; + + if (panel.EnterKeySelectsNextRow == true) + ProcessRowDownKey(select, extend); + } + } + + #endregion + + #region ProcessShiftEnterKey + + private void ProcessShiftEnterKey() + { + if (ActiveElement is GridCell) + ProcessCellShiftEnterKey(); + + else if (ActiveElement is GridContainer) + ProcessRowShiftEnterKey(); + } + + #region ProcessCellShiftEnterKey + + private void ProcessCellShiftEnterKey() + { + GridCell cell = (GridCell)ActiveElement; + + KeySelectRow(cell.GridPanel, cell.GridRow, true, false); + } + + #endregion + + #region ProcessRowShiftEnterKey + + private void ProcessRowShiftEnterKey() + { + if (ActiveElement is GridRow) + { + GridRow row = (GridRow)ActiveElement; + + GridPanel panel = row.GridPanel; + GridColumn column = panel.Columns.FirstVisibleColumn; + + if (column != null) + KeySelectCell(panel, row[column.ColumnIndex], true, false); + } + } + + #endregion + + #endregion + + #region ProcessCtrlSpaceKey + + private void ProcessCtrlSpaceKey(bool extend) + { + if (ActiveElement is GridCell) + ProcessCellCtrlSpaceKey(extend); + + else if (ActiveElement is GridContainer) + ProcessRowCtrlSpaceKey(extend); + } + + #region ProcessCellCtrlSpaceKey + + private void ProcessCellCtrlSpaceKey(bool extend) + { + GridCell cell = (GridCell) ActiveElement; + + if (extend == true) + KeyCtrlSelectCell(cell); + else + KeySelectCell(cell.GridPanel, cell, true, false); + } + + #endregion + + #region ProcessRowCtrlSpaceKey + + private void ProcessRowCtrlSpaceKey(bool extend) + { + GridContainer row = (GridContainer)ActiveElement; + + if (extend == true) + KeyCtrlSelectRow(row); + else + KeySelectRow(row.GridPanel, row, true, false); + } + + #endregion + + #endregion + + #region ProcessShiftSpaceKey + + private void ProcessShiftSpaceKey(bool extend) + { + if (ActiveElement is GridCell) + ProcessCellShiftSpaceKey(extend); + + else if (ActiveElement is GridContainer) + ProcessRowShiftSpaceKey(extend); + } + + #region ProcessCellShiftSpaceKey + + private void ProcessCellShiftSpaceKey(bool extend) + { + GridCell cell = (GridCell)ActiveElement; + GridPanel panel = cell.GridPanel; + + KeySelectCell(panel, cell, true, extend); + } + + #endregion + + #region ProcessRowShiftSpaceKey + + private void ProcessRowShiftSpaceKey(bool extend) + { + GridContainer lrow = (GridContainer)ActiveElement; + GridPanel panel = (lrow is GridPanel) ? lrow.GetParentPanel() : lrow.GridPanel; + + KeySelectRow(panel, lrow, true, extend); + } + + #endregion + + #endregion + + #region ProcessUpKey + + private void ProcessUpKey(bool select, bool extend) + { + if (ActiveElement is GridCell) + ProcessCellUpKey(select, extend); + + else if (ActiveElement is GridContainer) + ProcessRowUpKey(select, extend); + } + + #region ProcessCellUpKey + + private void ProcessCellUpKey(bool select, bool extend) + { + GridCell cell = (GridCell)ActiveElement; + GridPanel panel = cell.GridPanel; + + _LastCellIndex = cell.ColumnIndex; + + GridContainer prow = GetPrevRow(cell.GridRow); + + if (panel.GroupHeaderKeyBehavior == GroupHeaderKeyBehavior.Select) + { + if (prow is GridGroup) + { + KeySelectRow(panel, (GridGroup)cell.GridRow.Parent, select, extend); + return; + } + } + + GridCell pcell = GetPrevRowCell(prow, cell.ColumnIndex); + + if (KeySelectCell(panel, pcell, select, extend) == false) + { + if (VScrollOffset > 0) + { + VScrollOffset -= _VScrollBar.SmallChange; + } + else + { + if (select == false && panel.Filter.Visible == true && + cell.GridColumn.IsFilteringEnabled == true) + { + panel.Filter.ActivateFilterEdit(cell.GridColumn); + } + } + } + } + + #region GetPrevRowCell + + private GridCell GetPrevRowCell(GridContainer item, int index) + { + while (item != null) + { + GridRow row = item as GridRow; + + if (row != null) + { + if (item.AllowSelection == true) + { + GridCell cell = row.GetCell(index, + row.GridPanel.AllowEmptyCellSelection); + + if (cell != null) + { + if (cell.AllowSelection == true) + return (cell); + } + } + } + + item = item.PrevVisibleRow; + } + + return (null); + } + + #endregion + + #endregion + + #region ProcessRowUpKey + + private void ProcessRowUpKey(bool select, bool extend) + { + GridContainer lrow = (GridContainer)ActiveElement; + GridPanel panel = (lrow is GridPanel) ? lrow.GetParentPanel() : lrow.GridPanel; + + GridContainer row = GetPrevRow(lrow); + + if (lrow is GridGroup) + { + if (_LastCellIndex >= 0 && (row is GridGroup == false)) + { + GridCell cell = GetPrevRowCell(row, _LastCellIndex); + + KeySelectCell(panel, cell, select, extend); + return; + } + } + else + { + _LastCellIndex = -1; + } + + if (KeySelectRow(panel, row, select, extend) == false) + { + if (VScrollOffset > 0) + { + VScrollOffset -= _VScrollBar.SmallChange; + } + else + { + if (select == false && panel.Filter.Visible == true) + { + GridColumn column = panel.Columns.FirstVisibleColumn; + + while (column != null) + { + if (column.IsFilteringEnabled == true) + { + ActivateFilterPanel(column); + break; + } + + column = column.NextVisibleColumn; + } + } + } + } + } + + #endregion + + #region GetPrevRow + + private GridContainer GetPrevRow(GridContainer lrow) + { + GridContainer row = lrow.PrevVisibleRow; + + while (row != null) + { + if (row.AllowSelection == true) + return (row); + + row = row.PrevVisibleRow; + } + + return (null); + } + + #endregion + + #endregion + + #region ProcessDownKey + + private void ProcessDownKey(bool select, bool extend) + { + if (ActiveElement is GridCell) + ProcessCellDownKey(select, extend); + + else if (ActiveElement is GridContainer) + ProcessRowDownKey(select, extend); + } + + #region ProcessCellDownKey + + private void ProcessCellDownKey(bool select, bool extend) + { + GridCell cell = (GridCell) ActiveElement; + GridPanel panel = cell.GridPanel; + + _LastCellIndex = cell.ColumnIndex; + + GridContainer nrow = GetNextRow(cell.GridRow); + + if (panel.GroupHeaderKeyBehavior == GroupHeaderKeyBehavior.Select) + { + if (nrow is GridGroup) + { + if (KeySelectRow(panel, nrow, select, extend) == false) + VScrollOffset += _VScrollBar.SmallChange; + + return; + } + } + + GridCell ncell = GetNextRowCell(nrow, _LastCellIndex); + + if (KeySelectCell(panel, ncell, select, extend) == false) + { + if (nrow == null) + VScrollOffset += _VScrollBar.SmallChange; + } + } + + #region GetNextRowCell + + private GridCell GetNextRowCell(GridContainer item, int index) + { + while (item != null) + { + GridRow row = item as GridRow; + + if (row != null) + { + if (row.AllowSelection == true) + { + GridCell cell = row.GetCell(index, + row.GridPanel.AllowEmptyCellSelection); + + if (cell != null) + { + if (cell.AllowSelection == true) + return (cell); + } + } + } + + item = item.NextVisibleRow; + } + + return (null); + } + + #endregion + + #endregion + + #region ProcessRowDownKey + + private void ProcessRowDownKey(bool select, bool extend) + { + GridContainer lrow = (GridContainer)ActiveElement; + GridPanel panel = (lrow is GridPanel) ? lrow.GetParentPanel() : lrow.GridPanel; + + GridContainer row = GetNextRow(lrow); + + if (lrow is GridGroup) + { + if (_LastCellIndex >= 0 && (row is GridGroup == false)) + { + GridCell cell = GetNextRowCell(row, _LastCellIndex); + + KeySelectCell(panel, cell, select, extend); + return; + } + } + else + { + _LastCellIndex = -1; + } + + if (KeySelectRow(panel, row, select, extend) == false) + VScrollOffset += _VScrollBar.SmallChange; + } + + #endregion + + #region GetNextRow + + private GridContainer GetNextRow(GridContainer lrow) + { + GridContainer row = lrow.NextVisibleRow; + + while (row != null) + { + if (row.AllowSelection == true) + return (row); + + row = row.NextVisibleRow; + } + + return (null); + } + + #endregion + + #endregion + + #region ProcessLeftKey + + private bool ProcessLeftKey(bool select, bool extend) + { + if (ActiveElement is GridCell) + return (ProcessCellLeftKey(select, extend)); + + if (ActiveElement is GridContainer) + ProcessRowLeftKey(); + + return (true); + } + + #region ProcessCellLeftKey + + private bool ProcessCellLeftKey(bool select, bool extend) + { + GridCell lcell = (GridCell) ActiveElement; + GridPanel panel = lcell.GridPanel; + + if ((ModifierKeys & (Keys.Shift | Keys.Control)) == (Keys.Shift | Keys.Control)) + { + KeySelectRow(panel, lcell.GridRow, true, false); + + return (true); + } + + GridCell cell = lcell.GetPreviousCell(true, !extend); + + bool selected = KeySelectCell(panel, cell, select, extend); + + if (selected == false) + HScrollOffset -= _HScrollBar.SmallChange; + + return (selected); + } + + #endregion + + #region ProcessRowLeftKey + + private void ProcessRowLeftKey() + { + GridContainer lrow = (GridContainer)ActiveElement; + + if (lrow.Expanded == true) + { + lrow.Expanded = false; + } + else + { + GridContainer crow = lrow.Parent as GridContainer; + + if (crow != null && crow.Parent != null) + { + ActiveElement = crow; + + crow.GridPanel.ClearAll(true); + crow.IsSelected = true; + + crow.EnsureVisible(); + } + else + { + GridRow row = lrow as GridRow; + + if (row != null) + { + if (lrow.GridPanel.SelectionGranularity == SelectionGranularity.Cell) + { + GridCell cell = row.LastSelectableCell; + + if (cell != null) + KeySelectCell(row.GridPanel, cell, true, false); + } + else + { + HScrollOffset -= _HScrollBar.SmallChange; + } + } + } + } + } + + #endregion + + #endregion + + #region ProcessRightKey + + private bool ProcessRightKey(bool select, bool extend) + { + if (ActiveElement is GridCell) + return (ProcessCellRightKey(select, extend)); + + if (ActiveElement is GridContainer) + ProcessRowRightKey(); + + return (true); + } + + #region ProcessCellRightKey + + private bool ProcessCellRightKey(bool select, bool extend) + { + GridCell lcell = (GridCell) ActiveElement; + GridPanel panel = lcell.GridPanel; + + GridCell cell = lcell.GetNextCell(true, !extend); + + bool selected = KeySelectCell(panel, cell, select, extend); + + if (selected == false) + HScrollOffset += _HScrollBar.SmallChange; + + return (selected); + } + + #endregion + + #region ProcessRowRightKey + + private void ProcessRowRightKey() + { + GridContainer lrow = (GridContainer)ActiveElement; + + if (lrow is GridPanel) + { + GridPanel panel = (GridPanel)lrow; + GridRow row = panel.GetRowFromIndex(0) as GridRow; + + if (row != null) + { + ActiveElement = row; + + lrow.GetParentPanel().ClearAll(true); + lrow.GridPanel.ClearAll(true); + + row.IsSelected = true; + + row.EnsureVisible(); + } + } + else + { + if (lrow.Rows.Count > 0 || lrow.RowsUnresolved == true) + { + if (lrow.Expanded == false) + lrow.Expanded = true; + } + else + { + GridRow row = lrow as GridRow; + + if (row != null) + { + if (lrow.GridPanel.SelectionGranularity == SelectionGranularity.Cell) + { + GridCell cell = row.FirstSelectableCell; + + if (cell != null) + KeySelectCell(row.GridPanel, cell, true, false); + } + else + { + HScrollOffset += _HScrollBar.SmallChange; + } + } + } + } + } + + #endregion + + #endregion + + #region ProcessTabKey + + private bool ProcessTabKey() + { + if (_TabSelection == TabSelection.Control) + return (false); + + if (ActiveElement is GridCell) + { + GridCell lcell = (GridCell)ActiveElement; + GridPanel panel = lcell.GridPanel; + + GridCell cell = + lcell.GetNextCell(true, _TabSelection == TabSelection.Cell); + + KeySelectCell(panel, cell, true, false); + + return (true); + } + + GridRow row = ActiveElement as GridRow; + + if (row != null) + { + if (row.GridPanel.SelectionGranularity != SelectionGranularity.Cell) + { + GridCell cell = row.FirstOnScreenCell; + + if (cell != null) + { + GridCell cellNext = cell.GetNextCell(false, false); + + if (cellNext != null) + { + int n = 0; + + GridColumn col = row.GridPanel.Columns.FirstVisibleColumn; + + while (col != null && col.ColumnIndex != cellNext.ColumnIndex) + { + n += col.Bounds.Width; + + col = col.NextVisibleColumn; + } + + HScrollOffset = n; + } + } + + return (true); + } + } + + return (ProcessRightKey(true, false)); + } + + #endregion + + #region ProcessShiftTabKey + + private bool ProcessShiftTabKey() + { + if (_TabSelection == TabSelection.Control) + return (false); + + if (ActiveElement is GridCell) + { + GridCell lcell = (GridCell)ActiveElement; + GridPanel panel = lcell.GridPanel; + + GridCell cell = + lcell.GetPreviousCell(true, _TabSelection == TabSelection.Cell); + + return (KeySelectCell(panel, cell, true, false)); + } + + GridRow row = ActiveElement as GridRow; + + if (row != null) + { + if (row.GridPanel.SelectionGranularity != SelectionGranularity.Cell) + { + if (_HScrollOffset > 0) + { + GridCell cell = row.FirstOnScreenCell; + + if (cell != null) + { + Rectangle t = row.GridPanel.ViewRect; + Rectangle r = cell.Bounds; + + GridCell fcell = row.LastFrozenCell; + + if (fcell != null) + t.X = fcell.Bounds.Right; + + if (r.Left >= t.Left) + cell = cell.GetPreviousCell(false, false); + + if (cell != null) + cell.EnsureVisible(); + + return (true); + } + } + } + } + + return (ProcessLeftKey(true, false)); + } + + #endregion + + #region ProcessHomeKey + + private void ProcessHomeKey(bool extend) + { + if (ActiveElement is GridCell) + { + GridCell lcell = (GridCell)ActiveElement; + GridPanel panel = lcell.GridPanel; + + GridCell cell = lcell.GridRow.FirstSelectableCell; + + if (cell != lcell) + KeySelectCell(panel, cell, true, extend); + } + else if (ActiveElement is GridContainer) + { + GridPanel panel = ActiveElement.GridPanel; + + KeySelectRow(panel, panel.FirstSelectableRow, true, extend); + } + } + + #endregion + + #region ProcessCtrlHomeKey + + private void ProcessCtrlHomeKey(bool extend) + { + if (ActiveElement is GridCell) + { + GridCell cell = (GridCell)ActiveElement; + GridPanel panel = cell.GridPanel; + + SetFirstAvailableCell(panel, extend); + } + else if (ActiveElement is GridRow) + { + KeySelectRow(_PrimaryGrid, _PrimaryGrid.FirstSelectableRow, true, extend); + } + } + + #endregion + + #region ProcessEndKey + + private void ProcessEndKey(bool extend) + { + if (ActiveElement is GridCell) + { + GridCell lcell = (GridCell)ActiveElement; + + GridPanel panel = lcell.GridPanel; + GridCell cell = lcell.GridRow.LastSelectableCell; + + if (cell != lcell) + KeySelectCell(panel, cell, true, extend); + } + else if (ActiveElement is GridContainer) + { + GridPanel panel = ActiveElement.GridPanel; + + GridContainer row = panel.LastSelectableRow; + + if (row != null) + KeySelectRow(panel, row, true, extend); + } + } + + #endregion + + #region ProcessCtrlEndKey + + private void ProcessCtrlEndKey(bool extend) + { + if (ActiveElement is GridCell) + { + GridCell cell = (GridCell)ActiveElement; + GridPanel panel = cell.GridPanel; + + SetLastAvailableCell(panel, extend); + } + else if (ActiveElement is GridRow) + { + KeySelectRow(_PrimaryGrid, _PrimaryGrid.LastVisibleRow, true, extend); + } + } + + #endregion + + #region SetFirstAvailableRow + + private void SetFirstAvailableRow(GridPanel panel, bool extend) + { + GridContainer container = panel.FirstVisibleRow; + + while (container != null) + { + GridRow row = container as GridRow; + + if (row != null) + { + if (row.AllowSelection == true) + { + KeySelectRow(panel, row, true, extend); + break; + } + } + + container = container.NextVisibleRow; + } + } + + #endregion + + #region SetFirstAvailableCell + + private void SetFirstAvailableCell(GridPanel panel, bool extend) + { + GridColumn column = panel.Columns.FirstVisibleColumn; + GridContainer container = panel.FirstVisibleRow; + + if (column != null) + { + while (container != null) + { + GridRow row = container as GridRow; + + if (row != null) + { + if (row.AllowSelection == true) + { + GridCell cell = row.GetCell(column.ColumnIndex, + panel.AllowEmptyCellSelection); + + if (cell != null) + { + if (cell.AllowSelection == false) + cell = cell.GetNextCell(true); + + KeySelectCell(panel, cell, true, extend); + } + break; + } + } + + container = container.NextVisibleRow; + } + } + } + + #endregion + + #region SetLastAvailableCell + + private void SetLastAvailableCell(GridPanel panel, bool extend) + { + GridColumn column = panel.Columns.LastVisibleColumn; + GridContainer container = panel.LastVisibleRow; + + while (container != null) + { + GridRow row = container as GridRow; + + if (row != null) + { + if (row.AllowSelection == true) + { + GridCell cell = row.GetCell(column.ColumnIndex, + panel.AllowEmptyCellSelection); + + if (cell != null) + { + if (cell.AllowSelection == false) + cell = cell.GetPreviousCell(true); + + KeySelectCell(panel, cell, true, extend); + } + break; + } + } + + container = container.PrevVisibleRow; + } + } + + #endregion + + #region KeySelectCell + + internal bool KeySelectCell( + GridPanel panel, GridCell cell, bool select, bool extend) + { + if (cell != null) + { + int rowIndex = cell.GridRow.RowIndex; + + if (cell.CanSetActiveCell(panel) == true) + { + if (select == true && extend == false) + { + panel.SelectionRowAnchor = cell.GridRow; + panel.SelectionColumnAnchor = cell.GridColumn; + } + + if (select == true) + { + if (rowIndex != cell.GridRow.RowIndex) + ArrangeGrid(); + + cell.ExtendSelection(panel, cell, extend); + + if (cell.CellEditMode == CellEditMode.Modal) + { + if (panel.KeyboardEditMode == KeyboardEditMode.EditOnEntry) + cell.BeginEdit(true); + } + } + else + { + if (ActiveElement != null) + ActiveElement.InvalidateRender(); + + cell.InvalidateRender(); + } + + panel.LastProcessedItem = cell; + + cell.EnsureVisible(); + + return (true); + } + } + + return (false); + } + + #endregion + + #region KeyCtrlSelectCell + + private void KeyCtrlSelectCell(GridCell cell) + { + if (cell != null) + { + ActiveElement = cell; + + cell.IsSelected = !cell.IsSelected; + + cell.EnsureVisible(); + } + } + + #endregion + + #region KeySelectRow + + internal bool KeySelectRow(GridPanel panel, + GridContainer row, bool select, bool extend) + { + if (row != null) + { + int rowIndex = row.RowIndex; + + if (row.CanSetActiveRow(false) == true) + { + if (select == true && (extend == false || panel.SelectionRowAnchor == null)) + panel.SelectionRowAnchor = row; + + if (select == true) + { + if (rowIndex != row.RowIndex) + ArrangeGrid(); + + row.ExtendSelection(panel, row, extend); + } + else + { + if (ActiveElement != null) + ActiveElement.InvalidateRender(); + + row.InvalidateRender(); + } + + panel.SetActiveRow(row, true); + panel.LastProcessedItem = row; + + row.EnsureVisible(); + } + + return (true); + } + + return (false); + } + + #endregion + + #region KeyCtrlSelectRow + + private void KeyCtrlSelectRow(GridContainer row) + { + if (row != null) + { + ActiveElement = row; + + row.IsSelected = !row.IsSelected; + + row.EnsureVisible(); + } + } + + #endregion + + #region ProcessDeleteKey + + private void ProcessDeleteKey() + { + if (CanDeleteRows() == true) + { + SelectedElements selRows = + _ActiveGrid.InternalSelectedRows.Copy(); + + if (selRows.Count > 0) + { + if (_ActiveGrid.ShowInsertRow == true) + { + if (_ActiveGrid.VirtualMode == true) + { + selRows.RemoveItem(_ActiveGrid.VirtualRowCountEx - 1); + } + else + { + int n = _ActiveGrid.Rows.Count - 1; + + GridRow row = _ActiveGrid.Rows[n] as GridRow; + + if (row != null) + { + if (row.IsInsertRow == false) + throw new Exception(); + + selRows.RemoveItem(row.GridIndex); + } + } + } + } + + if (selRows.Count > 0) + { + if (DoRowDeletingEvent(_ActiveGrid, selRows) == false) + { + if (selRows.Count > 0) + DeleteRows(_ActiveGrid, selRows); + } + } + } + else + { + if (DoPlayingSoundEvent(null, null, PlaySoundContext.RowDeleteAttempt) == false) + SystemSounds.Beep.Play(); + } + } + + #region CanDeleteRows + + private bool CanDeleteRows() + { + if (_ActiveGrid == null) + return (false); + + return (_ActiveGrid.CanDeleteRow); + } + + #endregion + + #region DeleteRows + + private void DeleteRows(GridPanel panel, SelectedElements selRows) + { + BeginUpdate(); + + for (int i = selRows.Ranges.Count - 1; i >= 0; --i) + { + SelectedRange range = selRows.Ranges[i]; + + if (panel.VirtualMode == true) + { + panel.SetDeletedRows(range.StartIndex, range.Count, true); + } + else + { + for (int j = range.EndIndex; j >= range.StartIndex; --j) + { + GridContainer row = panel.GetRowFromIndex(j); + + if (row != null) + row.IsDeleted = true; + } + } + } + + EndUpdate(); + + DoRowDeletedEvent(panel, selRows); + } + + #endregion + + #endregion + + #region ProcessShiftDeleteKey + + private void ProcessShiftDeleteKey() + { + if (_ActiveGrid != null) + { + if (_ActiveGrid.AllowRowDelete == true) + { + BeginUpdate(); + + SelectedElements selRows = + _ActiveGrid.InternalSelectedRows.Copy(); + + if (DoRowRestoringEvent(_ActiveGrid, selRows) == false) + { + if (selRows.Count > 0) + RestoreRows(_ActiveGrid, selRows); + } + + EndUpdate(); + } + } + else + { + if (DoPlayingSoundEvent(null, null, PlaySoundContext.RowUnDeleteAttempt) == false) + SystemSounds.Beep.Play(); + } + } + + #region RestoreRows + + private void RestoreRows(GridPanel panel, SelectedElements selRows) + { + for (int i = selRows.Ranges.Count - 1; i >= 0; --i) + { + SelectedRange range = selRows.Ranges[i]; + + if (panel.VirtualMode == true) + { + panel.SetDeletedRows(range.StartIndex, range.Count, false); + } + else + { + for (int j = range.EndIndex; j >= range.StartIndex; --j) + { + GridContainer row = panel.GetRowFromIndex(j); + + if (row != null) + row.IsDeleted = false; + } + } + } + + DoRowRestoredEvent(panel, selRows); + } + + #endregion + + #endregion + + #region ProcessInsertKey + + private void ProcessInsertKey() + { + ProcessInsert(0); + } + + #endregion + + #region ProcessShiftInsertKey + + private void ProcessShiftInsertKey() + { + ProcessInsert(1); + } + + #endregion + + #region ProcessInsert + + private void ProcessInsert(int offset) + { + if (CanInsertRow() == true) + { + int index = ActiveRow.RowIndex + offset; + + if (index >= 0) + _ActiveGrid.InsertRow(index); + } + else + { + SystemSounds.Beep.Play(); + } + } + + #region CanInsertRow + + private bool CanInsertRow() + { + if (_ActiveGrid == null || + _ActiveRow == null || _ActiveRow.IsDeleted == true) + { + return (false); + } + + return (_ActiveGrid.CanInsertRow); + } + + #endregion + + #endregion + + #endregion + + #region ProcessFilterEditKeyDown + + #region ProcessFilterEditKeyDown + + private bool ProcessFilterEditKeyDown(Keys keyData) + { + bool processed = true; + + switch (keyData) + { + case Keys.Enter: + ExitFilterEdit(false); + break; + + case Keys.Escape: + ExitFilterEdit(true); + break; + + case Keys.Right: + ProcessFilterKeyRight(); + break; + + case Keys.Left: + ProcessFilterKeyLeft(); + break; + + case Keys.Tab: + processed = ProcessFilterTabKey(); + break; + + case Keys.Tab | Keys.Shift: + processed = ProcessFilterShiftTabKey(); + break; + + case Keys.Down | Keys.Control: + ExitFilterEdit(false); + break; + + default: + processed = false; + break; + } + + return (processed); + } + + #region ProcessFilterKeyLeft + + private void ProcessFilterKeyLeft() + { + GridColumn column = ActiveFilterPanel.GridColumn.PrevVisibleColumn; + + while (column != null) + { + if (column.IsFilteringEnabled == true) + { + ActivateFilterPanel(column); + break; + } + + column = column.PrevVisibleColumn; + } + } + + #endregion + + #region ProcessFilterKeyRight + + private void ProcessFilterKeyRight() + { + GridColumn column = ActiveFilterPanel.GridColumn.NextVisibleColumn; + + while (column != null) + { + if (column.IsFilteringEnabled == true) + { + ActivateFilterPanel(column); + break; + } + + column = column.NextVisibleColumn; + } + } + + #endregion + + #region ActivateFilterPanel + + private void ActivateFilterPanel(GridColumn col) + { + if (col != null) + { + if (ActiveFilterPanel != null) + ActiveFilterPanel.EndEdit(); + + FilterPanel fp = FilterPanel.GetFilterPanel(col); + + if (fp != null) + fp.BeginEdit(); + } + } + + #endregion + + #region ExitFilterEdit + + private void ExitFilterEdit(bool cancel) + { + GridColumn column = ActiveFilterPanel.GridColumn; + GridPanel panel = column.GridPanel; + + if (cancel == true) + ActiveFilterPanel.CancelEdit(); + else + ActiveFilterPanel.EndEdit(); + + GridRow row = panel.FirstSelectableRow as GridRow; + + if (row != null) + { + if (_LastProcessedItem is GridContainer) + { + row.SetActive(); + row.IsSelected = true; + } + else if (_LastProcessedItem is GridCell) + { + GridCell cell = GetNextRowCell(row, column.ColumnIndex); + + if (cell != null) + { + cell.SetActive(); + cell.IsSelected = true; + } + } + } + } + + #endregion + + #endregion + + #region ProcessFilterTabKey + + private bool ProcessFilterTabKey() + { + if (_TabSelection == TabSelection.Control) + return (false); + + ProcessFilterKeyRight(); + + return (true); + } + + #endregion + + #region ProcessFilterShiftTabKey + + private bool ProcessFilterShiftTabKey() + { + if (_TabSelection == TabSelection.Control) + return (false); + + ProcessFilterKeyLeft(); + + return (true); + } + + #endregion + + #endregion + + #region GridWantsKey + + private bool GridWantsKey(Keys keyData) + { + switch (keyData) + { + case Keys.Escape: + + case Keys.Up | Keys.Shift: + case Keys.Up: + + case Keys.Down: + case Keys.Down | Keys.Shift: + + case Keys.Left: + case Keys.Left | Keys.Shift: + + case Keys.Right: + case Keys.Right | Keys.Shift: + + case Keys.Enter: + + case Keys.Tab: + case Keys.Tab | Keys.Shift: + return (true); + } + + return (false); + } + + #endregion + + #region DoEvent support + + #region ActiveGridChangedEvent + + /// + /// Handles invocation of ActiveGridChanged events + /// + internal void DoActiveGridChangedEvent(GridPanel oldPanel) + { + if (ActiveGridChanged != null) + { + GridActiveGridChangedEventArgs ev = new + GridActiveGridChangedEventArgs(oldPanel, _ActiveGrid); + + ActiveGridChanged(this, ev); + } + } + + #endregion + + #region CellActivatedEvent + + /// + /// Handles invocation of CellActivated events + /// + internal void DoCellActivatedEvent( + GridPanel gridPanel, GridCell oldCell, GridCell newCell) + { + if (CellActivated != null) + { + GridCellActivatedEventArgs ev = new + GridCellActivatedEventArgs(gridPanel, oldCell, newCell); + + CellActivated(this, ev); + } + } + + #endregion + + #region CellActivatingEvent + + /// + /// Handles invocation of CellActivating events + /// + internal bool DoCellActivatingEvent( + GridPanel gridPanel, GridCell oldCell, GridCell newCell) + { + if (CellActivating != null) + { + GridCellActivatingEventArgs ev = new + GridCellActivatingEventArgs(gridPanel, oldCell, newCell); + + CellActivating(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region CellClickEvent + + /// + /// Handles invocation of CellClick events + /// + internal bool DoCellClickEvent(GridCell gridCell, MouseEventArgs e) + { + if (CellClick != null) + { + GridCellClickEventArgs ev = new + GridCellClickEventArgs(gridCell.GridPanel, gridCell, e); + + CellClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region CellDoubleClickEvent + + /// + /// Handles invocation of CellDoubleClick events + /// + internal bool DoCellDoubleClickEvent(GridCell gridCell, MouseEventArgs e) + { + if (CellDoubleClick != null) + { + GridCellDoubleClickEventArgs ev = new + GridCellDoubleClickEventArgs(gridCell.GridPanel, gridCell, e); + + CellDoubleClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region CellInfoClickEvent + + /// + /// Handles invocation of CellInfoClick events + /// + internal void DoCellInfoClickEvent(GridCell gridCell, MouseEventArgs e) + { + if (CellInfoClick != null) + { + GridCellClickEventArgs ev = new + GridCellClickEventArgs(gridCell.GridPanel, gridCell, e); + + CellInfoClick(this, ev); + } + } + + #endregion + + #region CellInfoDoubleClickEvent + + /// + /// Handles invocation of CellInfoDoubleClick events + /// + internal void DoCellInfoDoubleClickEvent(GridCell gridCell, MouseEventArgs e) + { + if (CellInfoDoubleClick != null) + { + GridCellDoubleClickEventArgs ev = new + GridCellDoubleClickEventArgs(gridCell.GridPanel, gridCell, e); + + CellInfoDoubleClick(this, ev); + } + } + + #endregion + + #region CellInfoEnterEvent + + /// + /// Handles invocation of CellInfoEnter events + /// + internal bool DoCellInfoEnterEvent(GridCell gridCell, + Control control, System.Windows.Forms.ToolTip toolTip, Point pt) + { + if (CellInfoEnter != null) + { + GridCellInfoEnterEventArgs ev = new + GridCellInfoEnterEventArgs(gridCell.GridPanel, gridCell, control, toolTip, pt); + + CellInfoEnter(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region CellInfoLeaveEvent + + /// + /// Handles invocation of CellInfoLeave events + /// + internal void DoCellInfoLeaveEvent( + GridCell gridCell, Control control, System.Windows.Forms.ToolTip toolTip) + { + if (CellInfoLeave != null) + { + GridCellInfoLeaveEventArgs ev = new + GridCellInfoLeaveEventArgs(gridCell.GridPanel, gridCell, control, toolTip); + + CellInfoLeave(this, ev); + } + } + + #endregion + + #region CellMouseDownEvent + + /// + /// Handles invocation of CellMouseDown events + /// + internal void DoCellMouseDownEvent(GridCell gridCell, MouseEventArgs args) + { + if (CellMouseDown != null) + { + GridCellMouseEventArgs ev = new + GridCellMouseEventArgs(gridCell.GridPanel, gridCell, args); + + CellMouseDown(this, ev); + } + } + + #endregion + + #region CellMouseEnterEvent + + /// + /// Handles invocation of CellMouseEnter events + /// + internal void DoCellMouseEnterEvent(GridCell gridCell) + { + if (CellMouseEnter != null) + { + GridCellEventArgs ev = new + GridCellEventArgs(gridCell.GridPanel, gridCell); + + CellMouseEnter(this, ev); + } + } + + #endregion + + #region CellMouseLeaveEvent + + /// + /// Handles invocation of CellMouseLeave events + /// + internal void DoCellMouseLeaveEvent(GridCell gridCell) + { + if (CellMouseLeave != null) + { + GridCellEventArgs ev = new + GridCellEventArgs(gridCell.GridPanel, gridCell); + + CellMouseLeave(this, ev); + } + } + + #endregion + + #region CellMouseMoveEvent + + /// + /// Handles invocation of CellMouseMove events + /// + internal void DoCellMouseMoveEvent(GridCell gridCell, MouseEventArgs args) + { + if (CellMouseMove != null) + { + GridCellMouseEventArgs ev = new + GridCellMouseEventArgs(gridCell.GridPanel, gridCell, args); + + CellMouseMove(this, ev); + } + } + + #endregion + + #region CellMouseUpEvent + + /// + /// Handles invocation of CellMouseUp events + /// + internal void DoCellMouseUpEvent(GridCell gridCell, MouseEventArgs args) + { + if (CellMouseUp != null) + { + GridCellMouseEventArgs ev = new + GridCellMouseEventArgs(gridCell.GridPanel, gridCell, args); + + CellMouseUp(this, ev); + } + } + + #endregion + + #region CellUserFunctionEvent + + /// + /// Handles invocation of CellUserFunction events + /// + internal void DoCellUserFunctionEvent( + GridCell gridCell, object[] args, ref object result) + { + if (CellUserFunction != null) + { + GridCellUserFunctionEventArgs ev = new + GridCellUserFunctionEventArgs(gridCell.GridPanel, gridCell, args, result); + + CellUserFunction(this, ev); + + result = ev.Result; + } + } + + #endregion + + #region CellValidatingEvent + + /// + /// Handles invocation of CellValidating events + /// + internal bool DoCellValidatingEvent( + GridCell gridCell, ref object value, object formattedValue) + { + if (CellValidating != null) + { + GridCellValidatingEventArgs ev = new GridCellValidatingEventArgs( + gridCell.GridPanel, gridCell, value, formattedValue); + + CellValidating(this, ev); + + value = ev.Value; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region CellValidatedEvent + + /// + /// Handles invocation of CellValidated events + /// + internal void DoCellValidatedEvent(GridCell gridCell) + { + if (CellValidated != null) + { + GridCellValidatedEventArgs ev = new + GridCellValidatedEventArgs(gridCell.GridPanel, gridCell); + + CellValidated(this, ev); + } + } + + #endregion + + #region CellValueChangedEvent + + /// + /// Handles invocation of CellValueChanged events + /// + internal void DoCellValueChangedEvent( + GridCell gridCell, object oldValue, object newValue, DataContext context) + { + if (CellValueChanged != null) + { + GridCellValueChangedEventArgs ev = new + GridCellValueChangedEventArgs(gridCell.GridPanel, gridCell, oldValue, newValue, context); + + CellValueChanged(this, ev); + } + } + + #endregion + + #region Check events + + #region AfterCheckEvent + + /// + /// Handles invocation of AfterCheckEvent events + /// + internal void DoAfterCheckEvent(GridPanel gridPanel, GridElement item) + { + if (AfterCheck != null) + { + GridAfterCheckEventArgs ev = new + GridAfterCheckEventArgs(gridPanel, item); + + AfterCheck(this, ev); + } + } + + #endregion + + #region BeforeCheckEvent + + /// + /// Handles invocation of BeforeCheck events + /// + internal bool DoBeforeCheckEvent(GridPanel gridPanel, GridElement gridRow) + { + if (BeforeCheck != null) + { + GridBeforeCheckEventArgs ev = new + GridBeforeCheckEventArgs(gridPanel, gridRow); + + BeforeCheck(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #endregion + + #region Collapse events + + #region AfterCollapseEvent + + /// + /// Handles invocation of AfterCollapse events + /// + internal void DoAfterCollapseEvent(GridPanel gridPanel, GridContainer gridContainer, ExpandSource expandSource) + { + if (AfterCollapse != null) + { + GridAfterCollapseEventArgs ev = new + GridAfterCollapseEventArgs(gridPanel, gridContainer, expandSource); + + AfterCollapse(this, ev); + } + } + + #endregion + + #region BeforeCollapseEvent + + /// + /// Handles invocation of BeforeCollapse events + /// + internal bool DoBeforeCollapseEvent(GridPanel gridPanel, GridContainer gridContainer, ExpandSource expandSource) + { + if (BeforeCollapse != null) + { + GridBeforeCollapseEventArgs ev = new + GridBeforeCollapseEventArgs(gridPanel, gridContainer, expandSource); + + BeforeCollapse(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #endregion + + #region Column events + + #region ColumnGroupedEvent + + /// + /// Handles invocation of ColumnGrouped events + /// + internal void DoColumnGroupedEvent( + GridPanel gridPanel, GridColumn gridColumn, GridGroup gridGroup) + { + if (ColumnGrouped != null) + { + GridColumnGroupedEventArgs ev = new + GridColumnGroupedEventArgs(gridPanel, gridColumn, gridGroup); + + ColumnGrouped(this, ev); + } + } + + #endregion + + #region ColumnHeaderClickEvent + + /// + /// Handles invocation of ColumnHeaderClick events + /// + internal bool DoColumnHeaderClickEvent( + GridPanel gridPanel, GridColumn gridColumn, MouseEventArgs e) + { + if (ColumnHeaderClick != null) + { + GridColumnHeaderClickEventArgs ev = new + GridColumnHeaderClickEventArgs(gridPanel, gridColumn, e); + + ColumnHeaderClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region ColumnHeaderDoubleClickEvent + + /// + /// Handles invocation of ColumnHeaderDoubleClick events + /// + internal bool DoColumnHeaderDoubleClickEvent(GridColumn gridColumn, MouseEventArgs e) + { + if (ColumnHeaderDoubleClick != null) + { + GridColumnHeaderDoubleClickEventArgs ev = new + GridColumnHeaderDoubleClickEventArgs(gridColumn.GridPanel, gridColumn, e); + + ColumnHeaderDoubleClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region ColumnHeaderMarkupLinkClick Event + + /// + /// Handles invocation of ColumnHeaderMarkupLinkClick events + /// + internal void DoColumnHeaderMarkupLinkClickEvent( + GridColumn gridColumn, HyperLink hyperLink) + { + if (ColumnHeaderMarkupLinkClick != null) + { + GridColumnHeaderMarkupLinkClickEventArgs ev = new GridColumnHeaderMarkupLinkClickEventArgs( + gridColumn.GridPanel, gridColumn, hyperLink.Name, hyperLink.HRef); + + ColumnHeaderMarkupLinkClick(this, ev); + } + } + + #endregion + + #region ColumnHeaderMouseDownEvent + + /// + /// Handles invocation of ColumnHeaderMouseDown events + /// + internal void DoColumnHeaderMouseDownEvent(GridColumnHeader gridColumnHeader, MouseEventArgs args) + { + if (ColumnHeaderMouseDown != null) + { + GridColumnHeaderMouseEventArgs ev = new + GridColumnHeaderMouseEventArgs(gridColumnHeader, args); + + ColumnHeaderMouseDown(this, ev); + } + } + + #endregion + + #region ColumnHeaderMouseEnterEvent + + /// + /// Handles invocation of ColumnHeaderMouseEnter events + /// + internal void DoColumnHeaderMouseEnterEvent(GridColumnHeader gridColumnHeader) + { + if (ColumnHeaderMouseEnter != null) + { + GridColumnHeaderEventArgs ev = new + GridColumnHeaderEventArgs(gridColumnHeader); + + ColumnHeaderMouseEnter(this, ev); + } + } + + #endregion + + #region ColumnHeaderMouseLeaveEvent + + /// + /// Handles invocation of ColumnHeaderMouseLeave events + /// + internal void DoColumnHeaderMouseLeaveEvent(GridColumnHeader gridColumnHeader) + { + if (ColumnHeaderMouseLeave != null) + { + GridColumnHeaderEventArgs ev = new + GridColumnHeaderEventArgs(gridColumnHeader); + + ColumnHeaderMouseLeave(this, ev); + } + } + + #endregion + + #region ColumnHeaderMouseMoveEvent + + /// + /// Handles invocation of ColumnHeaderMouseMove events + /// + internal void DoColumnHeaderMouseMoveEvent(GridColumnHeader gridColumnHeader, MouseEventArgs args) + { + if (ColumnHeaderMouseMove != null) + { + GridColumnHeaderMouseEventArgs ev = new + GridColumnHeaderMouseEventArgs(gridColumnHeader, args); + + ColumnHeaderMouseMove(this, ev); + } + } + + #endregion + + #region ColumnHeaderMouseUpEvent + + /// + /// Handles invocation of CellMouseUp events + /// + internal void DoColumnHeaderMouseUpEvent(GridColumnHeader gridColumnHeader, MouseEventArgs args) + { + if (ColumnHeaderMouseUp != null) + { + GridColumnHeaderMouseEventArgs ev = new + GridColumnHeaderMouseEventArgs(gridColumnHeader, args); + + ColumnHeaderMouseUp(this, ev); + } + } + + #endregion + + #region ColumnGroupHeaderClickEvent + + /// + /// Handles invocation of ColumnGroupHeaderClick events + /// + internal bool DoColumnGroupHeaderClickEvent(GridPanel gridPanel, + GridColumnHeader header, ColumnGroupHeader groupHeader, MouseEventArgs e) + { + if (ColumnGroupHeaderClick != null) + { + GridColumnGroupHeaderClickEventArgs ev = new + GridColumnGroupHeaderClickEventArgs(gridPanel, header, groupHeader, e); + + ColumnGroupHeaderClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region ColumnGroupHeaderDoubleClickEvent + + /// + /// Handles invocation of ColumnGroupHeaderDoubleClick events + /// + internal bool DoColumnGroupHeaderDoubleClickEvent(GridPanel gridPanel, + GridColumnHeader header, ColumnGroupHeader groupHeader, MouseEventArgs e) + { + if (ColumnGroupHeaderDoubleClick != null) + { + GridColumnGroupHeaderDoubleClickEventArgs ev = new + GridColumnGroupHeaderDoubleClickEventArgs(gridPanel, header, groupHeader, e); + + ColumnGroupHeaderDoubleClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region ColumnGroupHeaderMarkupLinkClick Event + + /// + /// Handles invocation of ColumnGroupHeaderMarkupLinkClick events + /// + internal void DoColumnGroupHeaderMarkupLinkClickEvent(GridPanel gridPanel, + GridColumnHeader header, ColumnGroupHeader groupHeader, HyperLink hyperLink) + { + if (ColumnGroupHeaderMarkupLinkClick != null) + { + GridColumnGroupHeaderMarkupLinkClickEventArgs ev = new GridColumnGroupHeaderMarkupLinkClickEventArgs( + gridPanel, header, groupHeader, hyperLink.Name, hyperLink.HRef); + + ColumnGroupHeaderMarkupLinkClick(this, ev); + } + } + + #endregion + + #region ColumnGroupHeaderResizedEvent + + /// + /// Handles invocation of ColumnGroupHeaderResized events + /// + internal void DoColumnGroupHeaderResizedEvent( + GridPanel gridPanel, ColumnGroupHeader groupHeader, Size oldSize) + { + if (ColumnGroupHeaderResized != null) + { + GridColumnGroupHeaderResizedEventArgs ev = new + GridColumnGroupHeaderResizedEventArgs(gridPanel, groupHeader, oldSize); + + ColumnGroupHeaderResized(this, ev); + } + } + + #endregion + + #region ColumnRowHeaderClickEvent + + /// + /// Handles invocation of ColumnRowHeaderClick events + /// + internal void DoColumnRowHeaderClickEvent(GridPanel gridPanel) + { + if (ColumnRowHeaderClick != null) + { + GridEventArgs ev = new GridEventArgs(gridPanel); + + ColumnRowHeaderClick(this, ev); + } + } + + #endregion + + #region ColumnRowHeaderDoubleClickEvent + + /// + /// Handles invocation of ColumnRowHeaderDoubleClick events + /// + internal void DoColumnRowHeaderDoubleClickEvent(GridPanel gridPanel) + { + if (ColumnRowHeaderDoubleClick != null) + { + GridEventArgs ev = new GridEventArgs(gridPanel); + + ColumnRowHeaderDoubleClick(this, ev); + } + } + + #endregion + + #region ColumnMovedEvent + + /// + /// Handles invocation of ColumnMoved events + /// + internal void DoColumnMovedEvent(GridPanel gridPanel, GridColumn gridColumn) + { + if (ColumnMoved != null) + { + GridColumnEventArgs ev = new + GridColumnEventArgs(gridPanel, gridColumn); + + ColumnMoved(this, ev); + } + } + + #endregion + + #region ColumnResizedEvent + + /// + /// Handles invocation of ColumnResized events + /// + internal void DoColumnResizedEvent(GridPanel gridPanel, GridColumn gridColumn) + { + if (ColumnResized != null) + { + GridColumnEventArgs ev = new + GridColumnEventArgs(gridPanel, gridColumn); + + ColumnResized(this, ev); + } + } + + #endregion + + #endregion + + #region CompareElementsEvent + + /// + /// Handles invocation of CompareElementsEvent events + /// + internal bool DoCompareElementsEvent(GridPanel panel, + GridElement a, GridElement b, ref int result) + { + if (CompareElements != null) + { + GridCompareElementsEventArgs ev = new + GridCompareElementsEventArgs(panel, a, b); + + CompareElements(this, ev); + + result = ev.Result; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DataBindingStartEvent + + /// + /// Handles invocation of DataBindingStart events + /// + internal bool DoDataBindingStartEvent(GridPanel gridPanel, + GridRow row, string tableName, ref bool autogen, ref ProcessChildRelations crProcess) + { + if (DataBindingStart != null) + { + GridDataBindingStartEventArgs ev = new + GridDataBindingStartEventArgs(gridPanel, row, tableName, autogen, crProcess); + + DataBindingStart(this, ev); + + autogen = ev.AutoGenerateColumns; + crProcess = ev.ProcessChildRelations; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DataBindingCompleteEvent + + /// + /// Handles invocation of DataBindingComplete events + /// + internal void DoDataBindingCompleteEvent(GridPanel gridPanel) + { + if (DataBindingComplete != null) + { + GridDataBindingCompleteEventArgs ev = new + GridDataBindingCompleteEventArgs(gridPanel); + + DataBindingComplete(this, ev); + } + } + + #endregion + + #region DataErrorEvent + + /// + /// Handles invocation of DataError events + /// + internal bool DoDataErrorEvent(GridPanel gridPanel, GridCell gridCell, Exception exception, + DataContext errorContext, ref object value, ref bool throwException, ref bool retry) + { + if (DataError != null) + { + GridDataErrorEventArgs ev = new + GridDataErrorEventArgs(gridPanel, gridCell, exception, errorContext, value); + + DataError(this, ev); + + value = ev.Value; + throwException = ev.ThrowException; + retry = ev.Retry; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DataFilteringStartEvent + + /// + /// Handles invocation of DataFilteringStart events + /// + internal bool DoDataFilteringStartEvent(GridPanel gridPanel) + { + if (DataFilteringStart != null) + { + GridDataFilteringStartEventArgs ev = new + GridDataFilteringStartEventArgs(gridPanel); + + DataFilteringStart(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region DataFilteringCompleteEvent + + /// + /// Handles invocation of DataFilteringCompleteEvent events + /// + internal void DoDataFilteringCompleteEvent(GridPanel gridPanel) + { + if (DataFilteringComplete != null) + { + GridDataFilteringCompleteEventArgs ev = new + GridDataFilteringCompleteEventArgs(gridPanel); + + DataFilteringComplete(this, ev); + } + } + + #endregion + + #region ItemDragEvent + + /// + /// Handles ItemDrag events + /// + internal bool DoItemDragEvent(GridElement element, MouseEventArgs e) + { + if (ItemDrag != null) + { + GridItemDragEventArgs ev = new + GridItemDragEventArgs(element.GridPanel, element, e); + + ItemDrag(this, ev); + + return (ev.Cancel); + } + + return (true); + } + + #endregion + + #region Editor events + + #region BeginEditEvent + + /// + /// Handles invocation of BeginEdit events + /// + internal bool DoBeginEditEvent( + GridPanel gridPanel, GridCell cell, IGridCellEditControl editor) + { + if (BeginEdit != null) + { + GridEditEventArgs ev = new + GridEditEventArgs(gridPanel, cell, editor); + + BeginEdit(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region CancelEditEvent + + /// + /// Handles invocation of CancelEdit events + /// + internal bool DoCancelEditEvent( + GridPanel gridPanel, GridCell cell, IGridCellEditControl editor) + { + if (CancelEdit != null) + { + GridEditEventArgs ev = new + GridEditEventArgs(gridPanel, cell, editor); + + CancelEdit(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region CloseEdit + + /// + /// Handles invocation of CloseEdit events + /// + internal void DoCloseEditEvent(GridPanel gridPanel, GridCell cell) + { + if (CloseEdit != null) + { + GridCloseEditEventArgs ev = new + GridCloseEditEventArgs(gridPanel, cell); + + CloseEdit(this, ev); + } + } + + #endregion + + #region EditorValueChangedEvent + + /// + /// Handles invocation of EditorValueChanged events + /// + internal void DoEditorValueChangedEvent( + GridCell gridCell, IGridCellEditControl editor) + { + if (EditorValueChanged != null) + { + GridEditEventArgs ev = new + GridEditEventArgs(gridCell.GridPanel, gridCell, editor); + + EditorValueChanged(this, ev); + } + } + + #endregion + + #region EndEditEvent + + /// + /// Handles invocation of EndEdit events + /// + internal bool DoEndEditEvent( + GridPanel gridPanel, GridCell cell, IGridCellEditControl editor) + { + if (EndEdit != null) + { + GridEditEventArgs ev = new + GridEditEventArgs(gridPanel, cell, editor); + + EndEdit(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region GetEditorEvent + + /// + /// Handles invocation of GetEditor events + /// + internal void DoGetEditorEvent( + GridPanel gridPanel, GridCell cell, ref Type type, ref object[] editorParams) + { + if (GetEditor != null) + { + GridGetEditorEventArgs ev = new + GridGetEditorEventArgs(gridPanel, cell, type, editorParams); + + GetEditor(this, ev); + + if (ev.EditorType != null) + type = ev.EditorType; + + editorParams = ev.EditorParams; + } + } + + #endregion + + #region GetRendererEvent + + /// + /// Handles invocation of GetRenderer events + /// + internal void DoGetRendererEvent( + GridPanel gridPanel, GridCell cell, ref Type type, ref object[] renderParams) + { + if (GetRenderer != null) + { + GridGetRendererEventArgs ev = new + GridGetRendererEventArgs(gridPanel, cell, type, renderParams); + + GetRenderer(this, ev); + + type = ev.RenderType; + renderParams = ev.RenderParams; + } + } + + #endregion + + #endregion + + #region Expand events + + #region AfterExpandEvent + + /// + /// Handles invocation of AfterExpand events + /// + internal void DoAfterExpandEvent( + GridPanel gridPanel, GridContainer container, ExpandSource expandSource) + { + if (AfterExpand != null) + { + GridAfterExpandEventArgs ev = new + GridAfterExpandEventArgs(gridPanel, container, expandSource); + + AfterExpand(this, ev); + } + } + + #endregion + + #region BeforeExpandEvent + + /// + /// Handles invocation of BeforeExpand events + /// + internal bool DoBeforeExpandEvent( + GridPanel gridPanel, GridContainer container, ExpandSource expandSource) + { + if (BeforeExpand != null) + { + GridBeforeExpandEventArgs ev = new + GridBeforeExpandEventArgs(gridPanel, container, expandSource); + + BeforeExpand(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #endregion + + #region Filter events + + #region FilterBeginEditEvent + + /// + /// Handles invocation of FilterBeginEdit events + /// + internal bool DoFilterBeginEditEvent( + GridPanel panel, GridColumn column, FilterPanel filterPanel) + { + if (FilterBeginEdit != null) + { + GridFilterBeginEditEventArgs ev = new + GridFilterBeginEditEventArgs(panel, column, filterPanel); + + FilterBeginEdit(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterCancelEditEvent + + /// + /// Handles invocation of FilterCancelEdit events + /// + internal void DoFilterCancelEditEvent(GridColumn column, FilterPanel filterPanel) + { + if (FilterCancelEdit != null) + { + GridFilterCancelEditEventArgs ev = new + GridFilterCancelEditEventArgs(column.GridPanel, column, filterPanel); + + FilterCancelEdit(this, ev); + } + } + + #endregion + + #region FilterColumnErrorEvent + + /// + /// Handles invocation of FilterColumnError events + /// + internal bool DoFilterColumnErrorEvent(GridPanel panel, GridRow row, + GridColumn col, Exception exp, ref bool filteredOut, ref bool throwException, ref bool postError) + { + if (FilterColumnError != null) + { + GridFilterColumnErrorEventArgs ev = new GridFilterColumnErrorEventArgs( + panel, row, col, exp, filteredOut, throwException, postError); + + FilterColumnError(this, ev); + + filteredOut = ev.FilteredOut; + throwException = ev.ThrowException; + postError = ev.PostError; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterEditValueChangedEvent + + /// + /// Handles invocation of FilterEditValueChanged events + /// + internal bool DoFilterEditValueChangedEvent(GridPanel panel, GridColumn column, FilterPanel fp, + object oldValue, ref object newValue, ref object newDisplayValue, ref string newExpr) + { + if (FilterEditValueChanged != null) + { + GridFilterEditValueChangedEventArgs ev = new + GridFilterEditValueChangedEventArgs(panel, + column, fp, oldValue, newValue, newDisplayValue, newExpr); + + FilterEditValueChanged(this, ev); + + newValue = ev.NewValue; + newDisplayValue = ev.NewDisplayValue; + newExpr = ev.NewExpr; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterEndEditEvent + + /// + /// Handles invocation of FilterEndEdit events + /// + internal void DoFilterEndEditEvent(GridColumn column, FilterPanel filterPanel) + { + if (FilterEndEdit != null) + { + GridFilterEndEditEventArgs ev = new + GridFilterEndEditEventArgs(column.GridPanel, column, filterPanel); + + FilterEndEdit(this, ev); + } + } + + #endregion + + #region FilterHeaderClickEvent + + /// + /// Handles invocation of FilterHeaderClick events + /// + internal bool DoFilterHeaderClickEvent( + GridPanel gridPanel, GridColumn gridColumn, MouseEventArgs e) + { + if (FilterHeaderClick != null) + { + GridFilterHeaderClickEventArgs ev = new + GridFilterHeaderClickEventArgs(gridPanel, gridColumn, e); + + FilterHeaderClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterHelpClosingEvent + + /// + /// Handles invocation of FilterHelpClosing events + /// + internal void DoFilterHelpClosingEvent(GridPanel panel, GridColumn column, SampleExpr sampleExpr) + { + if (FilterHelpClosing != null) + { + GridFilterHelpClosingEventArgs ev = new + GridFilterHelpClosingEventArgs(panel, column, sampleExpr); + + FilterHelpClosing(this, ev); + } + } + + #endregion + + #region FilterHelpOpeningEvent + + /// + /// Handles invocation of FilterHelpOpening events + /// + internal bool DoFilterHelpOpeningEvent(GridPanel panel, GridColumn column, SampleExpr sampleExpr) + { + if (FilterHelpOpening != null) + { + GridFilterHelpOpeningEventArgs ev = new + GridFilterHelpOpeningEventArgs(panel, column, sampleExpr); + + FilterHelpOpening(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterItemsLoadedEvent + + /// + /// Handles invocation of FilterItemsLoaded events + /// + internal void DoFilterItemsLoadedEvent(GridColumn column, ComboBoxEx comboBox) + { + if (FilterItemsLoaded != null) + { + GridFilterItemsLoadedEventArgs ev = new + GridFilterItemsLoadedEventArgs(column.GridPanel, column, comboBox); + + FilterItemsLoaded(this, ev); + } + } + + #endregion + + #region FilterLoadItemsEvent + + /// + /// Handles invocation of FilterLoadItems events + /// + internal bool DoFilterLoadItemsEvent(GridColumn column, ComboBoxEx comboBox) + { + if (FilterLoadItems != null) + { + GridFilterLoadItemsEventArgs ev = new + GridFilterLoadItemsEventArgs(column.GridPanel, column, comboBox); + + FilterLoadItems(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterLoadUserDataEvent + + /// + /// Handles invocation of FilterLoadUserData events + /// + internal bool DoFilterLoadUserDataEvent( + GridPanel gridPanel, ref string filterPath, ref List filterData) + { + if (FilterLoadUserData != null) + { + GridFilterLoadUserDataEventArgs ev = new + GridFilterLoadUserDataEventArgs(gridPanel, filterPath, filterData); + + FilterLoadUserData(this, ev); + + filterPath = ev.FilterPath; + filterData = ev.FilterData; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterPopupClosingEvent + + /// + /// Handles invocation of FilterPopupClosing events + /// + internal void DoFilterPopupClosingEvent(GridColumn column, FilterPopup filterPopup) + { + if (FilterPopupClosing != null) + { + GridFilterPopupClosingEventArgs ev = new + GridFilterPopupClosingEventArgs(column.GridPanel, column, filterPopup); + + FilterPopupClosing(this, ev); + } + } + + #endregion + + #region FilterPopupLoadEvent + + /// + /// Handles invocation of FilterPopupLoad events + /// + internal bool DoFilterPopupLoadEvent(GridColumn column, FilterPopup filterPopup) + { + if (FilterPopupLoad != null) + { + GridFilterPopupLoadEventArgs ev = new + GridFilterPopupLoadEventArgs(column.GridPanel, column, filterPopup); + + FilterPopupLoad(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterPopupLoadedEvent + + /// + /// Handles invocation of FilterPopupLoaded events + /// + internal void DoFilterPopupLoadedEvent(GridColumn column, FilterPopup filterPopup) + { + if (FilterPopupLoaded != null) + { + GridFilterPopupLoadedEventArgs ev = new + GridFilterPopupLoadedEventArgs(column.GridPanel, column, filterPopup); + + FilterPopupLoaded(this, ev); + } + } + + #endregion + + #region FilterPopupOpeningEvent + + /// + /// Handles invocation of FilterPopupOpening events + /// + internal bool DoFilterPopupOpeningEvent(GridColumn column, FilterPopup filterPopup) + { + if (FilterPopupOpening != null) + { + GridFilterPopupOpeningEventArgs ev = new + GridFilterPopupOpeningEventArgs(column.GridPanel, column, filterPopup); + + FilterPopupOpening(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterPopupValueChangedEvent + + /// + /// Handles invocation of FilterPopupValueChanged events + /// + internal bool DoFilterPopupValueChangedEvent(GridColumn column, FilterItemType filterItemType, + ref object filterValue, ref object filterDisplayValue, ref string filterExpr) + { + if (FilterPopupValueChanged != null) + { + GridFilterPopupValueChangedEventArgs ev = + new GridFilterPopupValueChangedEventArgs(column.GridPanel, + column, filterItemType, filterValue, filterDisplayValue, filterExpr); + + FilterPopupValueChanged(this, ev); + + filterValue = ev.FilterValue; + filterDisplayValue = ev.FilterDisplayValue; + filterExpr = ev.FilterExpr; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterRowErrorEvent + + /// + /// Handles invocation of FilterRowError events + /// + internal bool DoFilterRowErrorEvent(GridPanel panel, GridRow row, + Exception exp, ref bool filteredOut, ref bool throwException, ref bool postError) + { + if (FilterRowError != null) + { + GridFilterRowErrorEventArgs ev = new GridFilterRowErrorEventArgs( + panel, row, exp, filteredOut, throwException, postError); + + FilterRowError(this, ev); + + filteredOut = ev.FilteredOut; + throwException = ev.ThrowException; + postError = ev.PostError; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterRowHeaderClickEvent + + /// + /// Handles invocation of FilterRowHeaderClick events + /// + internal bool DoFilterRowHeaderClickEvent(GridPanel gridPanel) + { + if (FilterRowHeaderClick != null) + { + GridCancelEventArgs ev = new GridCancelEventArgs(gridPanel); + + FilterRowHeaderClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterStoreUserDataEvent + + /// + /// Handles invocation of FilterStoreUserData events + /// + internal bool DoFilterStoreUserDataEvent( + GridPanel gridPanel, ref string filterPath, ref List filterData) + { + if (FilterStoreUserData != null) + { + GridFilterStoreUserDataEventArgs ev = new + GridFilterStoreUserDataEventArgs(gridPanel, filterPath, filterData); + + FilterStoreUserData(this, ev); + + filterPath = ev.FilterPath; + filterData = ev.FilterData; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region FilterUserFunctionEvent + + /// + /// Handles invocation of FilterUserFunction events + /// + internal bool DoFilterUserFunctionEvent( + GridRow gridRow, object[] args, ref object result) + { + if (FilterUserFunction != null) + { + GridFilterUserFunctionEventArgs ev = new + GridFilterUserFunctionEventArgs(gridRow.GridPanel, gridRow, args, result); + + FilterUserFunction(this, ev); + + if (ev.Handled == true) + { + result = ev.Result; + + return (true); + } + } + + return (false); + } + + #endregion + + #region GetFilterColumnHeaderStyleEvent + + /// + /// Handles invocation of GetFilterColumnHeaderStyle events + /// + internal void DoGetFilterColumnHeaderStyleEvent( + GridColumn gridColumn, StyleType eStyle, ref FilterColumnHeaderVisualStyle style) + { + if (GetFilterColumnHeaderStyle != null) + { + GridGetFilterColumnHeaderStyleEventArgs ev = new + GridGetFilterColumnHeaderStyleEventArgs(gridColumn.GridPanel, gridColumn, eStyle, style); + + GetFilterColumnHeaderStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetFilterEditTypeEvent + + /// + /// Handles invocation of GetFilterEditType events + /// + internal void DoGetFilterEditTypeEvent( + GridColumn gridColumn, ref FilterEditType filterType) + { + if (GetFilterEditType != null) + { + GridGetFilterEditTypeEventArgs ev = new + GridGetFilterEditTypeEventArgs(gridColumn.GridPanel, gridColumn, filterType); + + GetFilterEditType(this, ev); + + filterType = ev.FilterEditType; + } + } + + #endregion + + #region GetFilterRowStyleEvent + + /// + /// Handles invocation of GetFilterRowStyle events + /// + internal void DoGetFilterRowStyleEvent( + GridFilter gridFilter, StyleType eStyle, ref FilterRowVisualStyle style) + { + if (GetFilterRowStyle != null) + { + GridGetFilterRowStyleEventArgs ev = new + GridGetFilterRowStyleEventArgs(gridFilter.GridPanel, gridFilter, eStyle, style); + + GetFilterRowStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #endregion + + #region GetCellRangesEvent + + /// + /// Handles invocation of GetCellRanges events + /// + internal bool DoGetCellRangesEvent( + GridContainer gridContainer, DisplayRange displayRange, ref List cellRanges) + { + if (GetCellRanges != null) + { + GridGetCellRangesEventArgs ev = new + GridGetCellRangesEventArgs(gridContainer.GridPanel, gridContainer, displayRange, cellRanges); + + GetCellRanges(this, ev); + + cellRanges = ev.CellRanges; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region GetCellFormattedValueEvent + + /// + /// Handles invocation of GetCellFormattedValue events + /// + internal void DoGetCellFormattedValueEvent( + GridCell gridCell, ref string formattedValue, ref CellSizingSource sizingSource) + { + if (GetCellFormattedValue != null) + { + GridGetCellFormattedValueEventArgs ev = new + GridGetCellFormattedValueEventArgs(gridCell.GridPanel, gridCell, formattedValue, sizingSource); + + GetCellFormattedValue(this, ev); + + formattedValue = ev.FormattedValue; + sizingSource = ev.SizingSource; + } + } + + #endregion + + #region GetCellRangeFormattedValueEvent + + /// + /// Handles invocation of GetCellRangeFormattedValue events + /// + internal void DoGetCellRangeFormattedValueEvent( + GridContainer gridContainer, CellRange cellRange, ref string formattedValue) + { + if (GetCellRangeFormattedValue != null) + { + GridGetCellRangeFormattedValueEventArgs ev = new + GridGetCellRangeFormattedValueEventArgs(gridContainer.GridPanel, gridContainer, cellRange, formattedValue); + + GetCellRangeFormattedValue(this, ev); + + formattedValue = ev.FormattedValue; + } + } + + #endregion + + #region GetCellStyleEvent + + /// + /// Handles invocation of GetCellStyle events + /// + internal void DoGetCellStyleEvent( + GridCell gridCell, StyleType eStyle, ref CellVisualStyle style) + { + if (GetCellStyle != null) + { + GridGetCellStyleEventArgs ev = new + GridGetCellStyleEventArgs(gridCell.GridPanel, gridCell, eStyle, style); + + GetCellStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetCellToolTipEvent + + /// + /// Handles invocation of GetCellToolTipEvent events + /// + internal bool DoGetCellToolTipEvent( + GridPanel panel, GridCell gridCell, ref string toolTip) + { + if (GetCellToolTip != null) + { + GridGetCellToolTipEventArgs ev = new + GridGetCellToolTipEventArgs(panel, gridCell, toolTip); + + GetCellToolTip(this, ev); + + toolTip = ev.ToolTip; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region GetCellValueEvent + + /// + /// Handles invocation of GetCellValue events + /// + internal void DoGetCellValueEvent(GridCell gridCell, ref object value) + { + if (GetCellValue != null) + { + GridGetCellValueEventArgs ev = new + GridGetCellValueEventArgs(gridCell.GridPanel, gridCell, value); + + GetCellValue(this, ev); + + value = ev.Value; + } + } + + #endregion + + #region GetColumnGroupHeaderToolTipEvent + + /// + /// Handles invocation of GetColumnGroupHeaderToolTip events + /// + internal bool DoGetColumnGroupHeaderToolTipEvent(GridPanel panel, + ColumnGroupHeader groupHeader, HeaderArea hitArea, ref string toolTip) + { + if (GetColumnGroupHeaderToolTip != null) + { + GridGetColumnGroupHeaderToolTipEventArgs ev = new + GridGetColumnGroupHeaderToolTipEventArgs(panel, groupHeader, hitArea, toolTip); + + GetColumnGroupHeaderToolTip(this, ev); + + toolTip = ev.ToolTip; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region GetColumnGroupHeaderStyleEvent + + /// + /// Handles invocation of GetColumnGroupHeader events + /// + internal void DoGetColumnGroupHeaderStyleEvent(GridPanel panel, + ColumnGroupHeader cgh, StyleType eStyle, ref ColumnHeaderVisualStyle style) + { + if (GetColumnGroupHeaderStyle != null) + { + GridGetColumnGroupHeaderStyleEventArgs ev = new + GridGetColumnGroupHeaderStyleEventArgs(panel, cgh, eStyle, style); + + GetColumnGroupHeaderStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetColumnHeaderRowHeaderStyleEvent + + /// + /// Handles invocation of GetColumnHeader RowHeader events + /// + internal void DoGetColumnHeaderRowHeaderStyleEvent( + GridColumnHeader columnHeader, StyleType eStyle, ref ColumnHeaderRowVisualStyle style) + { + if (GetColumnHeaderRowHeaderStyle != null) + { + GridGetColumnHeaderRowHeaderStyleEventArgs ev = new + GridGetColumnHeaderRowHeaderStyleEventArgs(columnHeader.GridPanel, columnHeader, eStyle, style); + + GetColumnHeaderRowHeaderStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetColumnHeaderStyleEvent + + /// + /// Handles invocation of GetColumnHeader events + /// + internal void DoGetColumnHeaderStyleEvent( + GridColumn gridColumn, StyleType eStyle, ref ColumnHeaderVisualStyle style) + { + if (GetColumnHeaderStyle != null) + { + GridGetColumnHeaderStyleEventArgs ev = new + GridGetColumnHeaderStyleEventArgs(gridColumn.GridPanel, gridColumn, eStyle, style); + + GetColumnHeaderStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetColumnHeaderToolTipEvent + + /// + /// Handles invocation of GetColumnHeaderToolTip events + /// + internal bool DoGetColumnHeaderToolTipEvent(GridPanel panel, + GridColumn gridColumn, HeaderArea hitArea, ref string toolTip) + { + if (GetColumnHeaderToolTip != null) + { + GridGetColumnHeaderToolTipEventArgs ev = new + GridGetColumnHeaderToolTipEventArgs(panel, gridColumn, hitArea, toolTip); + + GetColumnHeaderToolTip(this, ev); + + toolTip = ev.ToolTip; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region GetDisplayRangesEvent + + /// + /// Handles invocation of GetDisplayRanges events + /// + internal void DoGetDisplayRangesEvent( + GridContainer gridContainer, ref List displayRanges) + { + if (GetDisplayRanges != null) + { + GridGetDisplayRangesEventArgs ev = new + GridGetDisplayRangesEventArgs(gridContainer.GridPanel, gridContainer, displayRanges); + + GetDisplayRanges(this, ev); + + displayRanges = ev.DisplayRanges; + } + } + + #endregion + + #region ConfigureGroupBox + + /// + /// Handles invocation of ConfigureGroupBox events + /// + internal void DoConfigureGroupBoxEvent( + GridGroupByRow groupByRow, GridGroupBox gridGroupBox) + { + if (ConfigureGroupBox != null) + { + GridConfigureGroupBoxEventArgs ev = new + GridConfigureGroupBoxEventArgs(groupByRow.GridPanel, groupByRow, gridGroupBox); + + ConfigureGroupBox(this, ev); + } + } + + #endregion + + #region GetGroupedDetailRowsEvent + + /// + /// Handles invocation of GetGroupedDetailRows events + /// + internal bool DoGetGroupedDetailRowsEvent(GridPanel gridPanel, GridColumn gridColumn, + GridGroup gridGroup, out List preRows, out List postRows) + { + if (GetGroupDetailRows != null) + { + GridGetGroupDetailRowsEventArgs ev = new + GridGetGroupDetailRowsEventArgs(gridPanel, gridColumn, gridGroup); + + GetGroupDetailRows(this, ev); + + preRows = ev.PreDetailRows; + postRows = ev.PostDetailRows; + + return (true); + } + + preRows = null; + postRows = null; + + return (false); + } + + #endregion + + #region GetGroupHeaderStyleEvent + + /// + /// Handles invocation of GetGroupHeaderStyle events + /// + internal void DoGetGroupHeaderStyleEvent( + GridGroup gridRow, StyleType eStyle, ref GroupHeaderVisualStyle style) + { + if (GetGroupHeaderStyle != null) + { + GridGetGroupHeaderStyleEventArgs ev = new + GridGetGroupHeaderStyleEventArgs(gridRow.GridPanel, gridRow, eStyle, style); + + GetGroupHeaderStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetGroupIdEvent + + /// + /// Handles invocation of GetGroupId events + /// + internal void DoGetGroupIdEvent( + GridElement row, GridColumn column, ref object groupId) + { + if (GetGroupId != null) + { + GridGetGroupIdEventArgs ev = new + GridGetGroupIdEventArgs(row.GridPanel, row, column, groupId); + + GetGroupId(this, ev); + + groupId = ev.GroupId ?? ""; + } + } + + #endregion + + #region GetMergedCellStyleEvent + + /// + /// Handles invocation of GetMergedCellStyle events + /// + internal void DoGetMergedCellStyleEvent(GridPanel panel, + CellRange cellRange, StyleType eStyle, ref CellVisualStyle style) + { + if (GetMergedCellStyle != null) + { + GridGetMergedCellStyleEventArgs ev = new + GridGetMergedCellStyleEventArgs(panel, cellRange, eStyle, style); + + GetMergedCellStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetPanelStyleEvent + + /// + /// Handles invocation of GetPanelStyle events + /// + internal void DoGetPanelStyleEvent( + GridPanel gridPanel, ref GridPanelVisualStyle style) + { + if (GetPanelStyle != null) + { + GridGetPanelStyleEventArgs ev = new + GridGetPanelStyleEventArgs(gridPanel, style); + + GetPanelStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetRowCellStyleEvent + + /// + /// Handles invocation of GetRowCellStyle events + /// + internal void DoGetRowCellStyleEvent( + GridContainer gridRow, StyleType eStyle, ref CellVisualStyle style) + { + if (GetRowCellStyle != null) + { + GridGetRowCellStyleEventArgs ev = new + GridGetRowCellStyleEventArgs(gridRow.GridPanel, gridRow, eStyle, style); + + GetRowCellStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetRowHeaderStyleEvent + + /// + /// Handles invocation of GetRowHeader events + /// + internal void DoGetRowHeaderStyleEvent( + GridContainer gridRow, StyleType eStyle, ref RowHeaderVisualStyle style) + { + if (GetRowHeaderStyle != null) + { + GridGetRowHeaderStyleEventArgs ev = new + GridGetRowHeaderStyleEventArgs(gridRow.GridPanel, gridRow, eStyle, style); + + GetRowHeaderStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetRowStyleEvent + + /// + /// Handles invocation of GetRowStyle events + /// + internal void DoGetRowStyleEvent( + GridContainer gridRow, StyleType eStyle, ref RowVisualStyle style) + { + if (GetRowStyle != null) + { + GridGetRowStyleEventArgs ev = new + GridGetRowStyleEventArgs(gridRow.GridPanel, gridRow, eStyle, style); + + GetRowStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GetRowHeaderTextEvent + + /// + /// Handles invocation of GetRowHeaderText events + /// + internal void DoGetRowHeaderTextEvent(GridContainer row, ref string text) + { + if (GetRowHeaderText != null) + { + GridGetRowHeaderTextEventArgs ev = new + GridGetRowHeaderTextEventArgs(row.GridPanel, row, text); + + GetRowHeaderText(this, ev); + + text = ev.Text; + } + } + + #endregion + + #region GetTextRowStyleEvent + + /// + /// Handles invocation of GetTextRowStyle events + /// + internal void DoGetTextRowStyleEvent( + GridTextRow gridTextRow, StyleType eStyle, ref TextRowVisualStyle style) + { + if (GetTextRowStyle != null) + { + GridGetTextRowStyleEventArgs ev = new + GridGetTextRowStyleEventArgs(gridTextRow.GridPanel, gridTextRow, eStyle, style); + + GetTextRowStyle(this, ev); + + style = ev.Style; + } + } + + #endregion + + #region GridPreviewKeyDown + + private bool DoGridPreviewKeyDown(Keys keyData) + { + if (GridPreviewKeyDown != null) + { + GridPreviewKeyDownEventArgs args = + new GridPreviewKeyDownEventArgs(keyData | ModifierKeys); + + args.IsInputKey = _IsInputKey; + + GridPreviewKeyDown(this, args); + + _IsInputKey = args.IsInputKey; + + return (args.Handled); + } + + return (false); + } + + #endregion + + #region GroupChangedEvent + + /// + /// Handles invocation of GroupChanged events + /// + internal void DoGroupChangedEvent( + GridPanel gridPanel, GroupChangedAction action, GridColumn gridColumn) + { + if (GroupChanged != null) + { + GridGroupChangedEventArgs ev = new + GridGroupChangedEventArgs(gridPanel, action, gridColumn); + + GroupChanged(this, ev); + } + } + + #endregion + + #region GroupHeaderClickEvent + + /// + /// Handles invocation of GroupHeaderClick events + /// + internal bool DoGroupHeaderClickEvent(GridGroup group, GroupArea area, MouseEventArgs e) + { + if (GroupHeaderClick != null) + { + GridGroupHeaderClickEventArgs ev = + new GridGroupHeaderClickEventArgs(group.GridPanel, group, area, e); + + GroupHeaderClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region GroupHeaderDoubleClickEvent + + /// + /// Handles invocation of GroupHeaderDoubleClick events + /// + internal bool DoGroupHeaderDoubleClickEvent(GridGroup group, GroupArea area, MouseEventArgs e) + { + if (GroupHeaderDoubleClick != null) + { + GridGroupHeaderDoubleClickEventArgs ev = + new GridGroupHeaderDoubleClickEventArgs(group.GridPanel, group, area, e); + + GroupHeaderDoubleClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region GroupSortingEvent + + /// + /// Handles invocation of GroupSorting events + /// + internal bool DoGroupSortingEvent(GridPanel panel) + { + if (GroupSorting != null) + { + GridCancelEventArgs ev = new GridCancelEventArgs(panel); + + GroupSorting(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region GroupSortedEvent + + /// + /// Handles invocation of GroupSorted events + /// + internal void DoGroupSortedEvent(GridPanel panel) + { + if (GroupSorted != null) + { + GridEventArgs ev = new GridEventArgs(panel); + + GroupSorted(this, ev); + } + } + + #endregion + + #region InitEditContext + + /// + /// Handles invocation of InitEditContext events + /// + internal void DoInitEditContextEvent( + GridCell gridCell, IGridCellEditControl editControl) + { + if (InitEditContext != null) + { + GridInitEditContextEventArgs ev = new + GridInitEditContextEventArgs(gridCell.GridPanel, gridCell, editControl); + + InitEditContext(this, ev); + } + } + + #endregion + + #region LayoutOrderUpdatingEvent + + /// + /// Handles invocation of LayoutOrderUpdating events + /// + internal bool DoLayoutOrderUpdatingEvent(GridPanel panel) + { + if (LayoutOrderUpdating != null) + { + GridCancelEventArgs ev = new GridCancelEventArgs(panel); + + LayoutOrderUpdating(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region LayoutOrderUpdatedEvent + + /// + /// Handles invocation of LayoutOrderUpdated events + /// + internal void DoLayoutOrderUpdatedEvent(GridPanel panel) + { + if (LayoutOrderUpdated != null) + { + GridEventArgs ev = new GridEventArgs(panel); + + LayoutOrderUpdated(this, ev); + } + } + + #endregion + + #region NoRowsMarkupLinkClick Event + + /// + /// Handles invocation of NoRowsTextMarkupLinkClick events + /// + internal void DoNoRowsMarkupLinkClickEvent( + GridPanel gridPanel, HyperLink hyperLink) + { + if (NoRowsMarkupLinkClick != null) + { + GridNoRowsMarkupLinkClickEventArgs ev = new GridNoRowsMarkupLinkClickEventArgs( + gridPanel, hyperLink.Name, hyperLink.HRef); + + NoRowsMarkupLinkClick(this, ev); + } + } + + #endregion + + #region PlayingSoundEvent + + /// + /// Handles invocation of PlayingSound Events + /// + internal bool DoPlayingSoundEvent( + GridPanel panel, object item, PlaySoundContext context) + { + if (PlayingSound != null) + { + GridPlayingSoundEventArgs ev = + new GridPlayingSoundEventArgs(panel, item, context); + + PlayingSound(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PreviewKeyDown + + private void DoPreviewKeyDown(Keys keyData) + { + if (PreviewKeyDown != null) + { + PreviewKeyDownEventArgs args = + new PreviewKeyDownEventArgs(keyData); + + args.IsInputKey = _IsInputKey; + + PreviewKeyDown(this, args); + + _IsInputKey = args.IsInputKey; + } + } + + #endregion + + #region RefreshFilter + + internal bool DoRefreshFilter(GridPanel panel) + { + if (RefreshFilter != null) + { + GridRefreshFilterEventArgs args = + new GridRefreshFilterEventArgs(panel); + + RefreshFilter(this, args); + + return (args.Cancel); + } + + return (false); + } + + #endregion + + #region Render events + + #region PostRenderCellEvent + + /// + /// Handles invocation of PostRenderCell events + /// + internal void DoPostRenderCellEvent(Graphics g, + GridCell gridCell, RenderParts parts, Rectangle bounds) + { + if (PostRenderCell != null) + { + GridPostRenderCellEventArgs ev = new + GridPostRenderCellEventArgs(g, gridCell.GridPanel, gridCell, parts, bounds); + + PostRenderCell(this, ev); + } + } + + #endregion + + #region PreRenderCellEvent + + /// + /// Handles invocation of PreRenderCell events + /// + internal bool DoPreRenderCellEvent(Graphics g, + GridCell gridCell, RenderParts parts, Rectangle bounds) + { + if (PreRenderCell != null) + { + GridPreRenderCellEventArgs ev = new + GridPreRenderCellEventArgs(g, gridCell.GridPanel, gridCell, parts, bounds); + + PreRenderCell(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderColumnHeaderEvent + + /// + /// Handles invocation of PostRenderColumnHeader events + /// + internal void DoPostRenderColumnHeaderEvent(Graphics g, + GridColumnHeader header, GridColumn column, RenderParts parts, Rectangle bounds) + { + if (PostRenderColumnHeader != null) + { + GridPanel panel = header.GridPanel; + + GridPostRenderColumnHeaderEventArgs ev = new + GridPostRenderColumnHeaderEventArgs(g, panel, header, column, parts, bounds); + + PostRenderColumnHeader(this, ev); + } + } + + #endregion + + #region PreRenderColumnHeaderEvent + + /// + /// Handles invocation of PreRenderColumnHeaderEvent events + /// + internal bool DoPreRenderColumnHeaderEvent(Graphics g, + GridColumnHeader header, GridColumn column, RenderParts parts, Rectangle bounds) + { + if (PreRenderColumnHeader != null) + { + GridPanel panel = header.GridPanel; + + GridPreRenderColumnHeaderEventArgs ev = new + GridPreRenderColumnHeaderEventArgs(g, panel, header, column, parts, bounds); + + PreRenderColumnHeader(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderColumnGroupHeaderEvent + + /// + /// Handles invocation of PostRenderColumnGroupHeader events + /// + internal void DoPostRenderColumnGroupHeaderEvent(Graphics g, + GridColumnHeader header, ColumnGroupHeader groupHeader, RenderParts parts, Rectangle bounds) + { + if (PostRenderColumnGroupHeader != null) + { + GridPanel panel = header.GridPanel; + + GridPostRenderColumnGroupHeaderEventArgs ev = new + GridPostRenderColumnGroupHeaderEventArgs(g, panel, header, groupHeader, parts, bounds); + + PostRenderColumnGroupHeader(this, ev); + } + } + + #endregion + + #region PreRenderColumnGroupHeaderEvent + + /// + /// Handles invocation of PreRenderColumnGroupHeader events + /// + internal bool DoPreRenderColumnGroupHeaderEvent(Graphics g, + GridColumnHeader header, ColumnGroupHeader groupHeader, RenderParts parts, Rectangle bounds) + { + if (PreRenderColumnGroupHeader != null) + { + GridPanel panel = header.GridPanel; + + GridPreRenderColumnGroupHeaderEventArgs ev = new + GridPreRenderColumnGroupHeaderEventArgs(g, panel, header, groupHeader, parts, bounds); + + PreRenderColumnGroupHeader(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderFilterPopupGripBarEvent + + /// + /// Handles invocation of PostRenderFilterPopupGripBar events + /// + internal void DoPostRenderFilterPopupGripBarEvent( + Graphics g, FilterPopup filterPopup, GridColumn gridColumn, Rectangle bounds) + { + if (PostRenderFilterPopupGripBar != null) + { + GridPostRenderFilterPopupGripBarEventArgs ev = new + GridPostRenderFilterPopupGripBarEventArgs(g, filterPopup, gridColumn, bounds); + + PostRenderFilterPopupGripBar(this, ev); + } + } + + #endregion + + #region PreRenderFilterPopupGripBarEvent + + /// + /// Handles invocation of PreRenderFilterPopupGripBar events + /// + internal bool DoPreRenderFilterPopupGripBarEvent( + Graphics g, FilterPopup filterPopup, GridColumn gridColumn, Rectangle bounds) + { + if (PreRenderFilterPopupGripBar != null) + { + GridPreRenderFilterPopupGripBarEventArgs ev = new + GridPreRenderFilterPopupGripBarEventArgs(g, filterPopup, gridColumn, bounds); + + PreRenderFilterPopupGripBar(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderFilterRowEvent + + /// + /// Handles invocation of PostRenderFilterRow events + /// + internal void DoPostRenderFilterRowEvent(Graphics g, + GridFilter filter, GridColumn column, RenderParts parts, Rectangle bounds) + { + if (PostRenderFilterRow != null) + { + GridPanel panel = filter.GridPanel; + + GridPostRenderFilterRowEventArgs ev = new + GridPostRenderFilterRowEventArgs(g, panel, filter, column, parts, bounds); + + PostRenderFilterRow(this, ev); + } + } + + #endregion + + #region PreRenderFilterRowEvent + + /// + /// Handles invocation of PreRenderFilterRowEvent events + /// + internal bool DoPreRenderFilterRowEvent(Graphics g, + GridFilter filter, GridColumn column, RenderParts parts, Rectangle bounds) + { + if (PreRenderFilterRow != null) + { + GridPanel panel = filter.GridPanel; + + GridPreRenderFilterRowEventArgs ev = new + GridPreRenderFilterRowEventArgs(g, panel, filter, column, parts, bounds); + + PreRenderFilterRow(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderGroupBoxConnectorEvent + + /// + /// Handles invocation of PostRenderGroupBoxConnector events + /// + internal void DoPostRenderGroupBoxConnectorEvent(Graphics g, + GridGroupByRow groupByRow, GridGroupBox box1, GridGroupBox box2) + { + if (PostRenderGroupBoxConnector != null) + { + GridPostRenderGroupBoxConnectorEventArgs ev = new + GridPostRenderGroupBoxConnectorEventArgs(g, groupByRow.GridPanel, groupByRow, box1, box2); + + PostRenderGroupBoxConnector(this, ev); + } + } + + #endregion + + #region PreRenderGroupBoxConnectorEvent + + /// + /// Handles invocation of PreRenderGroupBoxConnector events + /// + internal bool DoPreRenderGroupBoxConnectorEvent(Graphics g, + GridGroupByRow groupByRow, GridGroupBox box1, GridGroupBox box2) + { + if (PreRenderGroupBoxConnector != null) + { + GridPreRenderGroupBoxConnectorEventArgs ev = new + GridPreRenderGroupBoxConnectorEventArgs(g, groupByRow.GridPanel, groupByRow, box1, box2); + + PreRenderGroupBoxConnector(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderGroupBoxEvent + + /// + /// Handles invocation of PostRenderGroupBox events + /// + internal void DoPostRenderGroupBoxEvent(Graphics g, + GridGroupByRow groupByRow, GridGroupBox box, RenderParts parts, Rectangle bounds) + { + if (PostRenderGroupBox != null) + { + GridPostRenderGroupBoxEventArgs ev = new + GridPostRenderGroupBoxEventArgs(g, groupByRow.GridPanel, groupByRow, box, parts, bounds); + + PostRenderGroupBox(this, ev); + } + } + + #endregion + + #region PreRenderGroupBoxEvent + + /// + /// Handles invocation of PreRenderGroupBox events + /// + internal bool DoPreRenderGroupBoxEvent(Graphics g, + GridGroupByRow groupByRow, GridGroupBox box, RenderParts parts, Rectangle bounds) + { + if (PreRenderGroupBox != null) + { + GridPreRenderGroupBoxEventArgs ev = new + GridPreRenderGroupBoxEventArgs(g, groupByRow.GridPanel, groupByRow, box, parts, bounds); + + PreRenderGroupBox(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderGroupHeaderEvent + + /// + /// Handles invocation of PostRenderGroupHeader events + /// + internal void DoPostRenderGroupHeaderEvent( + Graphics g, GridGroup gridGroup, RenderParts parts, Rectangle bounds) + { + if (PostRenderGroupHeader != null) + { + GridPanel panel = gridGroup.GridPanel; + + GridPostRenderRowEventArgs ev = new + GridPostRenderRowEventArgs(g, panel, gridGroup, parts, bounds); + + PostRenderGroupHeader(this, ev); + } + } + + #endregion + + #region PreRenderGroupHeaderEvent + + /// + /// Handles invocation of PreRenderGroupHeader events + /// + internal bool DoPreRenderGroupHeaderEvent( + Graphics g, GridGroup gridGroup, RenderParts parts, Rectangle bounds) + { + if (PreRenderGroupHeader != null) + { + GridPanel panel = gridGroup.GridPanel; + + GridPreRenderRowEventArgs ev = new + GridPreRenderRowEventArgs(g, panel, gridGroup, parts, bounds); + + PreRenderGroupHeader(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderPanelRowEvent + + /// + /// Handles invocation of PostRenderPanelRow events + /// + internal void DoPostRenderPanelRowEvent( + Graphics g, GridContainer gridRow, RenderParts parts, Rectangle bounds) + { + if (PostRenderPanelRow != null) + { + GridPostRenderRowEventArgs ev = new + GridPostRenderRowEventArgs(g, gridRow.GridPanel, gridRow, parts, bounds); + + PostRenderPanelRow(this, ev); + } + } + + #endregion + + #region PreRenderPanelRowEvent + + /// + /// Handles invocation of PreRenderPanelRow events + /// + internal bool DoPreRenderPanelRowEvent( + Graphics g, GridContainer gridRow, RenderParts parts, Rectangle bounds) + { + if (PreRenderPanelRow != null) + { + GridPreRenderRowEventArgs ev = new + GridPreRenderRowEventArgs(g, gridRow.GridPanel, gridRow, parts, bounds); + + PreRenderPanelRow(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderRowEvent + + /// + /// Handles invocation of PostRenderRow events + /// + internal void DoPostRenderRowEvent( + Graphics g, GridRow gridRow, RenderParts parts, Rectangle bounds) + { + if (PostRenderRow != null) + { + GridPostRenderRowEventArgs ev = new + GridPostRenderRowEventArgs(g, gridRow.GridPanel, gridRow, parts, bounds); + + PostRenderRow(this, ev); + } + } + + #endregion + + #region PreRenderRowEvent + + /// + /// Handles invocation of PreRenderRow events + /// + internal bool DoPreRenderRowEvent(Graphics g, + GridRow gridRow, RenderParts parts, Rectangle bounds) + { + if (PreRenderRow != null) + { + GridPreRenderRowEventArgs ev = new + GridPreRenderRowEventArgs(g, gridRow.GridPanel, gridRow, parts, bounds); + + PreRenderRow(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region PostRenderTextRowEvent + + /// + /// Handles invocation of PostRenderTextRow events + /// + internal void DoPostRenderTextRowEvent( + Graphics g, GridTextRow gridTextRow, RenderParts parts, Rectangle bounds) + { + if (PostRenderTextRow != null) + { + GridPostRenderTextRowEventArgs ev = new + GridPostRenderTextRowEventArgs(g, gridTextRow.GridPanel, gridTextRow, parts, bounds); + + PostRenderTextRow(this, ev); + } + } + + #endregion + + #region PreRenderTextRowEvent + + /// + /// Handles invocation of PreRenderTextRow events + /// + internal bool DoPreRenderTextRowEvent(Graphics g, + GridTextRow gridTextRow, RenderParts parts, Rectangle bounds) + { + if (PreRenderTextRow != null) + { + GridPreRenderTextRowEventArgs ev = new + GridPreRenderTextRowEventArgs(g, gridTextRow.GridPanel, gridTextRow, parts, bounds); + + PreRenderTextRow(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #endregion + + #region Row events + + #region RowLoadedEvent + + /// + /// Handles invocation of RowLoaded events + /// + internal void DoRowLoadedEvent(GridPanel panel, GridRow row) + { + if (RowLoaded != null) + { + GridRowLoadedEventArgs ev = new + GridRowLoadedEventArgs(panel, row); + + RowLoaded(this, ev); + } + } + + #endregion + + #region RowActivatedEvent + + /// + /// Handles invocation of RowActivated events + /// + internal void DoRowActivatedEvent( + GridPanel gridPanel, GridContainer oldRow, GridContainer newRow) + { + if (RowActivated != null) + { + GridRowActivatedEventArgs ev = new + GridRowActivatedEventArgs(gridPanel, oldRow, newRow); + + RowActivated(this, ev); + } + } + + #endregion + + #region RowActivatingEvent + + /// + /// Handles invocation of RowActivating events + /// + internal bool DoRowActivatingEvent( + GridPanel panel, GridContainer orow, GridContainer nrow) + { + if (RowActivating != null) + { + GridRowActivatingEventArgs ev = new + GridRowActivatingEventArgs(panel, orow, nrow); + + RowActivating(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowAddedEvent + + /// + /// Handles invocation of RowAdded events + /// + internal void DoRowAddedEvent(GridPanel panel, int index) + { + if (RowAdded != null) + { + GridRowAddedEventArgs ev = new + GridRowAddedEventArgs(panel, index); + + RowAdded(this, ev); + } + } + + #endregion + + #region RowAddingEvent + + /// + /// Handles invocation of DoRowAdding events + /// + internal bool DoRowAddingEvent(GridPanel panel, ref int index) + { + if (RowAdding != null) + { + GridRowAddingEventArgs ev = new + GridRowAddingEventArgs(panel, index); + + RowAdding(this, ev); + + index = ev.Index; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowClickEvent + + /// + /// Handles invocation of RowClick events + /// + internal bool DoRowClickEvent(GridRow row, RowArea rowArea, MouseEventArgs e) + { + if (RowClick != null) + { + GridRowClickEventArgs ev = + new GridRowClickEventArgs(row.GridPanel, row, rowArea, e); + + RowClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowDeletedEvent + + /// + /// Handles invocation of RowDeleted events + /// + internal void DoRowDeletedEvent(GridPanel panel, SelectedElements selRows) + { + if (RowDeleted != null) + { + GridRowDeletedEventArgs ev = new + GridRowDeletedEventArgs(panel, selRows); + + RowDeleted(this, ev); + } + } + + #endregion + + #region RowDeletingEvent + + /// + /// Handles invocation of RowDeleting events + /// + internal bool DoRowDeletingEvent(GridPanel panel, SelectedElements selRows) + { + if (RowDeleting != null) + { + GridRowDeletingEventArgs ev = new + GridRowDeletingEventArgs(panel, selRows); + + RowDeleting(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowDoubleClickEvent + + /// + /// Handles invocation of RowDoubleClick events + /// + internal bool DoRowDoubleClickEvent(GridRow row, RowArea rowArea, MouseEventArgs e) + { + if (RowDoubleClick != null) + { + GridRowDoubleClickEventArgs ev = new + GridRowDoubleClickEventArgs(row.GridPanel, row, rowArea, e); + + RowDoubleClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowGetDetailHeightEvent + + /// + /// Handles invocation of RowGetDetailHeight events + /// + internal void DoRowGetDetailHeightEvent(GridRow row, + GridLayoutInfo layoutInfo, Size sizeNeeded, ref int preHeight, ref int postHeight) + { + if (GetDetailRowHeight != null) + { + GridGetDetailRowHeightEventArgs ev = new + GridGetDetailRowHeightEventArgs(row.GridPanel, row, layoutInfo, sizeNeeded, preHeight, postHeight); + + GetDetailRowHeight(this, ev); + + preHeight = ev.PreDetailHeight; + postHeight = ev.PostDetailHeight; + } + } + + #endregion + + #region RowHeaderClickEvent + + /// + /// Handles invocation of RowHeaderClick events + /// + internal void DoRowHeaderClickEvent( + GridPanel gridPanel, GridContainer row, MouseEventArgs e) + { + if (RowHeaderClick != null) + { + GridRowHeaderClickEventArgs ev = + new GridRowHeaderClickEventArgs(gridPanel, row, e); + + RowHeaderClick(this, ev); + } + } + + #endregion + + #region RowHeaderDoubleClickEvent + + /// + /// Handles invocation of RowHeaderDoubleClick events + /// + internal bool DoRowHeaderDoubleClickEvent(GridContainer row, MouseEventArgs e) + { + if (RowHeaderDoubleClick != null) + { + GridRowHeaderDoubleClickEventArgs ev = new + GridRowHeaderDoubleClickEventArgs(row.GridPanel, row, e); + + RowHeaderDoubleClick(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowHeaderResizedEvent + + /// + /// Handles invocation of RowHeaderResized events + /// + internal void DoRowHeaderResizedEvent(GridPanel gridPanel) + { + if (RowHeaderResized != null) + { + GridEventArgs ev = new GridEventArgs(gridPanel); + + RowHeaderResized(this, ev); + } + } + + #endregion + + #region RowInfoClickEvent + + /// + /// Handles invocation of RowInfoClick events + /// + internal void DoRowInfoClickEvent(GridRow gridRow, MouseEventArgs e) + { + if (RowInfoClick != null) + { + GridRowClickEventArgs ev = new + GridRowClickEventArgs(gridRow.GridPanel, gridRow, RowArea.InRowInfo, e); + + RowInfoClick(this, ev); + } + } + + #endregion + + #region RowInfoEnterEvent + + /// + /// Handles invocation of RowInfoEnter events + /// + internal bool DoRowInfoEnterEvent(GridRow gridRow, Point pt) + { + if (RowInfoEnter != null) + { + GridRowInfoEnterEventArgs ev = new + GridRowInfoEnterEventArgs(gridRow.GridPanel, gridRow, pt); + + RowInfoEnter(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowInfoLeaveEvent + + /// + /// Handles invocation of RowInfoLeave events + /// + internal void DoRowInfoLeaveEvent(GridRow gridRow) + { + if (RowInfoLeave != null) + { + GridRowInfoLeaveEventArgs ev = new + GridRowInfoLeaveEventArgs(gridRow.GridPanel, gridRow); + + RowInfoLeave(this, ev); + } + } + + #endregion + + #region RowInfoDoubleClickEvent + + /// + /// Handles invocation of RowInfoDoubleClick events + /// + internal void DoRowInfoDoubleClickEvent(GridRow gridRow, MouseEventArgs e) + { + if (RowInfoDoubleClick != null) + { + GridRowDoubleClickEventArgs ev = new + GridRowDoubleClickEventArgs(gridRow.GridPanel, gridRow, RowArea.InRowInfo, e); + + RowInfoDoubleClick(this, ev); + } + } + + #endregion + + #region RowMarkedDirtyEvent + + /// + /// Handles invocation of RowMarkedDirty events + /// + internal bool DoRowMarkedDirtyEvent( + GridCell gridCell, IGridCellEditControl editor) + { + if (RowMarkedDirty != null) + { + GridEditEventArgs ev = new + GridEditEventArgs(gridCell.GridPanel, gridCell, editor); + + RowMarkedDirty(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowMouseDownEvent + + /// + /// Handles invocation of RowMouseDown events + /// + internal void DoRowMouseDownEvent( + GridRow gridRow, MouseEventArgs args, RowArea area) + { + if (RowMouseDown != null) + { + GridRowMouseEventArgs ev = new + GridRowMouseEventArgs(gridRow.GridPanel, gridRow, args, area); + + RowMouseDown(this, ev); + } + } + + #endregion + + #region RowMouseEnterEvent + + /// + /// Handles invocation of RowMouseEnter events + /// + internal void DoRowMouseEnterEvent(GridRow gridRow) + { + if (RowMouseEnter != null) + { + GridRowEventArgs ev = new + GridRowEventArgs(gridRow.GridPanel, gridRow); + + RowMouseEnter(this, ev); + } + } + + #endregion + + #region RowMouseLeaveEvent + + /// + /// Handles invocation of RowMouseLeave events + /// + internal void DoRowMouseLeaveEvent(GridRow gridRow) + { + if (RowMouseLeave != null) + { + GridRowEventArgs ev = new + GridRowEventArgs(gridRow.GridPanel, gridRow); + + RowMouseLeave(this, ev); + } + } + + #endregion + + #region RowMouseMoveEvent + + /// + /// Handles invocation of RowMouseMove events + /// + internal void DoRowMouseMoveEvent(GridRow gridRow, MouseEventArgs args, RowArea area) + { + if (RowMouseMove != null) + { + GridRowMouseEventArgs ev = new + GridRowMouseEventArgs(gridRow.GridPanel, gridRow, args, area); + + RowMouseMove(this, ev); + } + } + + #endregion + + #region RowMouseUpEvent + + /// + /// Handles invocation of RowMouseUp events + /// + internal void DoRowMouseUpEvent(GridRow gridRow, MouseEventArgs args, RowArea area) + { + if (RowMouseUp != null) + { + GridRowMouseEventArgs ev = new + GridRowMouseEventArgs(gridRow.GridPanel, gridRow, args, area); + + RowMouseUp(this, ev); + } + } + + #endregion + + #region RowMovedEvent + + /// + /// Handles invocation of RowMoved events + /// + internal void DoRowMovedEvent( + GridPanel gridPanel, GridContainer gridContainer, GridContainer gridRow) + { + if (RowMoved != null) + { + GridRowMovedEventArgs ev = new + GridRowMovedEventArgs(gridPanel, gridContainer, gridRow); + + RowMoved(this, ev); + } + } + + #endregion + + #region RowMovingEvent + + /// + /// Handles invocation of RowMoving events + /// + internal bool DoRowMovingEvent(GridRow gridRow, + GridContainer srcCont, int srcIndex, ref GridContainer destCont, ref int destIndex) + { + if (RowMoving != null) + { + GridRowMovingEventArgs ev = new GridRowMovingEventArgs( + gridRow.GridPanel, gridRow, srcCont, srcIndex, destCont, destIndex); + + RowMoving(this, ev); + + destIndex = ev.DestIndex; + destCont = ev.DestContainer; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowResizedEvent + + /// + /// Handles invocation of RowResized events + /// + internal void DoRowResizedEvent(GridPanel gridPanel, GridContainer gridRow) + { + if (RowResized != null) + { + GridRowEventArgs ev = new + GridRowEventArgs(gridPanel, gridRow); + + RowResized(this, ev); + } + } + + #endregion + + #region RowRestoredEvent + + /// + /// Handles invocation of RowRestored events + /// + internal void DoRowRestoredEvent(GridPanel panel, SelectedElements selRows) + { + if (RowRestored != null) + { + GridRowRestoredEventArgs ev = new + GridRowRestoredEventArgs(panel, selRows); + + RowRestored(this, ev); + } + } + + #endregion + + #region RowRestoringEvent + + /// + /// Handles invocation of RowRestoring events + /// + internal bool DoRowRestoringEvent(GridPanel panel, SelectedElements selRows) + { + if (RowRestoring != null) + { + GridRowRestoringEventArgs ev = new + GridRowRestoringEventArgs(panel, selRows); + + RowRestoring(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowSetDefaultValuesEvent + + /// + /// Handles invocation of RowSetDefaultValues events + /// + internal void DoRowSetDefaultValuesEvent( + GridPanel panel, GridRow row, NewRowContext context) + { + if (RowSetDefaultValues != null) + { + GridRowSetDefaultValuesEventArgs ev = new + GridRowSetDefaultValuesEventArgs(panel, row, context); + + bool loading = row.Loading; + row.Loading = true; + + try + { + RowSetDefaultValues(this, ev); + } + finally + { + row.Loading = loading; + } + } + } + + #endregion + + #region RowsGroupedEvent + + /// + /// Handles invocation of RowsGroupedEvent events + /// + internal void DoRowsGroupedEvent(GridPanel panel) + { + if (RowsGrouped != null) + { + GridEventArgs ev = new GridEventArgs(panel); + + RowsGrouped(this, ev); + } + } + + #endregion + + #region RowsGroupingEvent + + /// + /// Handles invocation of RowsGrouping events + /// + internal bool DoRowsGroupingEvent(GridPanel panel) + { + if (RowsGrouping != null) + { + GridCancelEventArgs ev = new GridCancelEventArgs(panel); + + RowsGrouping(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowsPurgingEvent + + /// + /// Handles invocation of RowsPurging events + /// + internal bool DoRowsPurgingEvent(GridContainer row, ref bool includeNestedRows) + { + if (RowsPurging != null) + { + GridRowsPurgingEventArgs ev = new + GridRowsPurgingEventArgs(row.GridPanel, row, includeNestedRows); + + RowsPurging(this, ev); + + includeNestedRows = ev.IncludeNestedRows; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowsPurgedEvent + + /// + /// Handles invocation of RowsPurged events + /// + internal void DoRowsPurgedEvent(GridContainer row) + { + if (RowsPurged != null) + { + GridRowEventArgs ev = new GridRowEventArgs(row.GridPanel, row); + + RowsPurged(this, ev); + } + } + + #endregion + + #region RowsSortingEvent + + /// + /// Handles invocation of RowsSorting events + /// + internal bool DoRowsSortingEvent(GridPanel panel) + { + if (RowsSorting != null) + { + GridCancelEventArgs ev = new GridCancelEventArgs(panel); + + RowsSorting(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowsSortedEvent + + /// + /// Handles invocation of RowsSortedEvent events + /// + internal void DoRowsSortedEvent(GridPanel panel) + { + if (RowsSorted != null) + { + GridEventArgs ev = new GridEventArgs(panel); + + RowsSorted(this, ev); + } + } + + #endregion + + #region RowValidatingEvent + + /// + /// Handles invocation of RowValidating events + /// + internal bool DoRowValidatingEvent(GridRow gridRow) + { + if (RowValidating != null) + { + GridRowValidatingEventArgs ev = new + GridRowValidatingEventArgs(gridRow.GridPanel, gridRow); + + RowValidating(this, ev); + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region RowValidatedEvent + + /// + /// Handles invocation of RowValidated events + /// + internal void DoRowValidatedEvent(GridRow gridRow) + { + if (RowValidated != null) + { + GridRowValidatedEventArgs ev = new + GridRowValidatedEventArgs(gridRow.GridPanel, gridRow); + + RowValidated(this, ev); + } + } + + #endregion + + #endregion + + #region ScrollEvent + + /// + /// Handles invocation of Scroll events + /// + internal void DoScrollEvent(GridPanel gridPanel, + ScrollEventArgs args, ScrollBarAdv sbar) + { + if (Scroll != null) + { + GridScrollEventArgs ev = new + GridScrollEventArgs(gridPanel, args); + + Scroll(this, ev); + } + + if (args.Type == ScrollEventType.EndScroll) + { + if (args.NewValue == 0) + DoScrollMinEvent(gridPanel, args); + + else if (args.NewValue + sbar.LargeChange >= sbar.Maximum) + DoScrollMaxEvent(gridPanel, args); + } + } + + #endregion + + #region ScrollMinEvent + + /// + /// Handles invocation of ScrollMin events + /// + internal void DoScrollMinEvent(GridPanel gridPanel, ScrollEventArgs args) + { + if (ScrollMin != null) + { + GridScrollEventArgs ev = new + GridScrollEventArgs(gridPanel, args); + + ScrollMin(this, ev); + } + } + + #endregion + + #region ScrollMaxEvent + + /// + /// Handles invocation of ScrollMax events + /// + internal void DoScrollMaxEvent(GridPanel gridPanel, ScrollEventArgs args) + { + if (ScrollMax != null) + { + GridScrollEventArgs ev = new + GridScrollEventArgs(gridPanel, args); + + ScrollMax(this, ev); + } + } + + #endregion + + #region SelectionChanged Event + + /// + /// Handles invocation of SelectionChanged events + /// + internal void DoSelectionChangedEvent(GridPanel gridPanel) + { + if (SelectionChanged != null) + { + GridEventArgs ev = new + GridEventArgs(gridPanel); + + SelectionChanged(this, ev); + } + } + + #endregion + + #region SelectionChanging Event + + /// + /// Handles invocation of SelectionChanging events + /// + internal bool DoSelectionChangingEvent(GridPanel gridPanel, + ref SelectedElements selectedElements, int index, int count, bool selected) + { + if (SelectionChanging != null) + { + GridSelectionChangingEventArgs ev = new + GridSelectionChangingEventArgs(gridPanel, selectedElements, index, count, selected); + + SelectionChanging(this, ev); + + selectedElements = ev.SelectedElements; + + return (ev.Cancel); + } + + return (false); + } + + #endregion + + #region SortChanged Event + + /// + /// Handles invocation of SortChanged events + /// + internal void DoSortChangedEvent(GridPanel gridPanel) + { + if (SortChanged != null) + { + GridEventArgs ev = new + GridEventArgs(gridPanel); + + SortChanged(this, ev); + } + } + + #endregion + + #region TextRowClickEvent + + /// + /// Handles invocation of TextRowClick events + /// + internal void DoTextRowClickEvent(GridTextRow textRow, MouseEventArgs e) + { + if (TextRowClick != null) + { + GridTextRowEventArgs ev = new + GridTextRowEventArgs(textRow.GridPanel, textRow, e); + + TextRowClick(this, ev); + } + } + + #endregion + + #region TextRowHeaderClickEvent + + /// + /// Handles invocation of TextRowHeaderClick events + /// + internal void DoTextRowHeaderClickEvent(GridTextRow textRow, MouseEventArgs e) + { + if (TextRowHeaderClick != null) + { + GridTextRowEventArgs ev = new + GridTextRowEventArgs(textRow.GridPanel, textRow, e); + + TextRowHeaderClick(this, ev); + } + } + + #endregion + + #region TextRowMarkupLinkClickEvent + + /// + /// Handles invocation of TextRowMarkupLinkClick events + /// + internal void DoTextRowMarkupLinkClickEvent( + GridTextRow textRow, HyperLink hyperLink) + { + if (TextRowMarkupLinkClick != null) + { + GridTextRowMarkupLinkClickEventArgs ev = new GridTextRowMarkupLinkClickEventArgs( + textRow.GridPanel, textRow, hyperLink.Name, hyperLink.HRef); + + TextRowMarkupLinkClick(this, ev); + } + } + + #endregion + + #region UpdateCellDisplayRangesEvent + + /// + /// Handles invocation of UpdateCellDisplayRanges events + /// + internal void DoUpdateCellDisplayRangesEvent( + GridContainer gridContainer, DisplayRange displayRange, ref List cellRanges) + { + if (UpdateCellDisplayRanges != null) + { + GridUpdateCellDisplayRangesEventArgs ev = new + GridUpdateCellDisplayRangesEventArgs(gridContainer.GridPanel, gridContainer, displayRange, cellRanges); + + UpdateCellDisplayRanges(this, ev); + + cellRanges = ev.CellRanges; + } + } + + #endregion + + #region Virtual Row events + + #region DoLoadVirtualRowEvent + + /// + /// Handles invocation of LoadVirtualRow events + /// + internal void DoLoadVirtualRowEvent(GridPanel panel, GridRow row) + { + if (LoadVirtualRow != null) + { + GridVirtualRowEventArgs ev = new + GridVirtualRowEventArgs(panel, row, row.Index); + + LoadVirtualRow(this, ev); + } + } + + #endregion + + #region DoVirtualRowLoadedEvent + + /// + /// Handles invocation of VirtualRowed events + /// + internal void DoVirtualRowLoadedEvent(GridPanel panel, GridRow row) + { + if (VirtualRowLoaded != null) + { + GridVirtualRowEventArgs ev = new + GridVirtualRowEventArgs(panel, row, row.Index); + + VirtualRowLoaded(this, ev); + } + } + + #endregion + + #region DoStoreVirtualRowEvent + + /// + /// Handles invocation of StoreVirtualRow events + /// + internal void DoStoreVirtualRowEvent(GridPanel gridPanel, GridRow gridRow) + { + if (StoreVirtualRow != null) + { + GridVirtualRowEventArgs ev = new + GridVirtualRowEventArgs(gridPanel, gridRow, gridRow.Index); + + StoreVirtualRow(this, ev); + } + } + + #endregion + + #endregion + + #endregion + + #region GetElementAt + + /// + /// Gets the GridElement at the given coordinates + /// + /// + /// + public GridElement GetElementAt(Point pt) + { + return (GetElementAt(pt.X, pt.Y)); + } + + /// + /// Gets the GridElement at the given coordinates + /// + /// + /// + /// + public GridElement GetElementAt(int x, int y) + { + GridElement item = _PrimaryGrid.GetElementAt(x, y); + + if (item == null) + return (_PrimaryGrid); + + while (item is GridContainer) + { + GridElement subItem = ((GridContainer) item).GetElementAt(x, y); + + if (subItem == null) + break; + + item = subItem; + } + + return (item); + } + + #endregion + + #region FindGridPanel + + /// + /// Finds the defined GridPanel with the given Name. + /// Nested GridPanels will not be searched. + /// + ///GridPanel or null + public GridPanel FindGridPanel(string name) + { + return (FindGridPanel(name, false)); + } + + /// + /// Finds the defined GridPanel with the given Name. + /// If 'includeNested' is true, then nested GridPanels + /// will also be searched. + /// + /// + public GridPanel FindGridPanel(string name, bool includeNested) + { + if (_PrimaryGrid != null) + { + if (_PrimaryGrid.Name != null && _PrimaryGrid.Name.Equals(name) == true) + return (_PrimaryGrid); + + return (_PrimaryGrid.FindGridPanel(name, includeNested)); + } + + return (null); + } + + #endregion + + #region GetSelectedElements + + /// + /// This routine returns a SelectedElementCollection, + /// containing a list of the currently selected elements. + /// + ///SelectedElementCollection + public SelectedElementCollection GetSelectedElements() + { + SelectedElementCollection items = + _PrimaryGrid.GetSelectedElements(); + + GetSelectedElements(_PrimaryGrid, items); + + return (items); + } + + private void GetSelectedElements( + GridContainer container, SelectedElementCollection items) + { + foreach (GridElement item in container.Rows) + { + if (item.Visible == true) + { + GridContainer citem = item as GridContainer; + + if (citem != null) + { + GridPanel panel = citem as GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == false) + panel.GetSelectedElements(items); + } + + if (citem.Rows.Count > 0) + GetSelectedElements(citem, items); + } + } + } + } + + #endregion + + #region GetSelectedRows + + /// + /// This routine returns a SelectedElementCollection, + /// containing a list of the currently selected rows. + /// + ///SelectedElementCollection + public SelectedElementCollection GetSelectedRows() + { + SelectedElementCollection items = + _PrimaryGrid.GetSelectedRows(); + + GetSelectedRows(_PrimaryGrid, items); + + return (items); + } + + private void GetSelectedRows( + GridContainer container, ICollection items) + { + foreach (GridElement item in container.Rows) + { + if (item.Visible == true) + { + GridContainer citem = item as GridContainer; + + if (citem != null) + { + GridPanel panel = citem as GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == false) + panel.GetSelectedRows(items); + } + + if (citem.Rows.Count > 0) + GetSelectedRows(citem, items); + } + } + } + } + + #endregion + + #region GetSelectedColumns + + /// + /// This routine returns a SelectedElementCollection, + /// containing a list of the currently selected columns. + /// + ///SelectedElementCollection + public SelectedElementCollection GetSelectedColumns() + { + SelectedElementCollection items = + _PrimaryGrid.GetSelectedColumns(); + + GetSelectedColumns(_PrimaryGrid, items); + + return (items); + } + + private void GetSelectedColumns(GridContainer container, ICollection items) + { + foreach (GridElement item in container.Rows) + { + if (item.Visible == true) + { + GridContainer citem = item as GridContainer; + + if (citem != null) + { + GridPanel panel = citem as GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == false) + panel.GetSelectedColumns(items); + } + + if (citem.Rows.Count > 0) + GetSelectedColumns(citem, items); + } + } + } + } + + #endregion + + #region GetSelectedCells + + /// + /// This routine returns a SelectedElementCollection, + /// containing a list of the currently selected cells. + /// + ///SelectedElementCollection + public SelectedElementCollection GetSelectedCells() + { + SelectedElementCollection items = + _PrimaryGrid.GetSelectedCells(); + + GetSelectedCells(_PrimaryGrid, items); + + return (items); + } + + private void GetSelectedCells(GridContainer container, SelectedElementCollection items) + { + foreach (GridElement item in container.Rows) + { + if (item.Visible == true) + { + GridContainer citem = item as GridContainer; + + if (citem != null) + { + GridPanel panel = citem as GridPanel; + + if (panel != null) + { + if (panel.VirtualMode == false) + panel.GetSelectedCells(items); + } + + if (citem.Rows.Count > 0) + GetSelectedCells(citem, items); + } + } + } + } + + #endregion + + #region GetCell + + /// + /// Gets the GridCell for the given + /// row and column index of the PrimaryGrid + /// + /// + /// + ///GridCell, or null if not a valid cell + public GridCell GetCell(int rowIndex, int columnIndex) + { + return (PrimaryGrid.GetCell(rowIndex, columnIndex)); + } + + /// + /// Gets the GridCell for the given + /// row and column index of the given GridPanel + /// + /// + /// + /// + ///GridCell, or null if not a valid cell + public GridCell GetCell(GridPanel panel, int rowIndex, int columnIndex) + { + return (panel.GetCell(rowIndex, columnIndex)); + } + + #endregion + + #region AutoScrolling support + + #region EnableAutoScrolling + + internal void EnableAutoScrolling( + AutoScrollEnable enable, Rectangle scrollRect) + { + if (Focused == true) + { + _AutoScrollEnable = enable; + + if ((_HScrollBar != null && _HScrollBar.Visible == true) || + (_VScrollBar != null && _VScrollBar.Visible == true)) + { + _ScrollRect = scrollRect; + + if (_AutoScrollTimer == null) + { + _AutoScrollTimer = new Timer(); + + _AutoScrollTimer.Interval = 10; + _AutoScrollTimer.Tick += AutoScrollTimerTick; + _AutoScrollTimer.Start(); + } + } + } + } + + #endregion + + #region DisableAutoScrolling + + internal void DisableAutoScrolling() + { + if (_AutoScrollTimer != null) + { + _AutoScrollTimer.Stop(); + _AutoScrollTimer.Tick -= AutoScrollTimerTick; + + _AutoScrollTimer = null; + } + } + + #endregion + + #region AutoScrollTimerTick + + private void AutoScrollTimerTick(object sender, EventArgs e) + { + Point pt = PointToClient(Cursor.Position); + Rectangle t = _ScrollRect; + + if ((_AutoScrollEnable & AutoScrollEnable.Horizontal) == AutoScrollEnable.Horizontal && + (_HScrollBar != null && _HScrollBar.Visible == true)) + { + int dx = (pt.X < t.X) + ? ScrollAmount(pt.X - t.X) + : (pt.X >= t.Right) ? ScrollAmount(pt.X - t.Right) : 0; + + SetHScrollValue(_HScrollOffset + dx); + } + + if ((_AutoScrollEnable & AutoScrollEnable.Vertical) == AutoScrollEnable.Vertical && + (_VScrollBar != null && _VScrollBar.Visible == true)) + { + int dy = (pt.Y < t.Top) + ? ScrollAmount(pt.Y - t.Top) + : (pt.Y >= t.Bottom) ? ScrollAmount(pt.Y - t.Bottom) : 0; + + SetVScrollValue(_VScrollOffset + dy); + } + } + + #endregion + + #region ScrollAmount + + private int ScrollAmount(int delta) + { + int n = Math.Abs(delta); + int amt = 1 << ((n / 16) + 1); + + return (delta < 0 ? -amt : amt); + } + + #endregion + + #endregion + + #region PostInternalMouseMove + + internal void PostInternalMouseMove() + { + _PostMouseMove = true; + } + + #endregion + + #region UpdateInternalMouseMove + + internal void UpdateInternalMouseMove() + { + if (_PostMouseMove == true) + { + _PostMouseMove = false; + + Cursor.Position = Cursor.Position; + } + } + + #endregion + + #region Cursor + + /// + /// Cursor + /// + public override Cursor Cursor + { + get { return base.Cursor; } + + set + { + base.Cursor = value; + + if (SetGridCursor == true) + GridCursor = value; + else + _DefaultCursor = value; + } + } + + #endregion + + #region OnGotFocus + + /// + /// OnGotFocus + /// + /// + protected override void OnGotFocus(EventArgs e) + { + base.OnGotFocus(e); + + if (_ActiveRow != null) + _ActiveRow.InvalidateRender(); + } + + #endregion + + #region OnLostFocus + + /// + /// OnLostFocus + /// + /// + protected override void OnLostFocus(EventArgs e) + { + CancelCapture(); + + if (_ActiveRow != null) + _ActiveRow.InvalidateRender(); + + base.OnLostFocus(e); + } + + #endregion + + #region OnResize + + /// + /// OnResize + /// + /// + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + + if (_PrimaryGrid != null) + { + _PrimaryGrid.InvalidateLayout(); + _PrimaryGrid.ContainerBounds = ClientRectangle; + } + } + + #endregion + + #region OnValidating + + /// + /// OnValidating + /// + /// + protected override void OnValidating(CancelEventArgs e) + { + if (_ActiveRow != null && _ActiveRow.GridPanel != null) + { + if (_ActiveRow.GridPanel.SetActiveRow(null, false) == false) + { + e.Cancel = true; + + return; + } + } + + base.OnValidating(e); + } + + #endregion + + #region Update support + + /// + /// Calling the BeginUpdate routine informs the grid + /// that an extended update phase has begun. The SuperGrid + /// will suspend all layout calculations and display updates + /// until the corresponding EndUpdate routine is called. + /// + /// BeginUpdate / EndUpdate can be nested and must be + /// called in pairs every BeginUpdate must have a + /// matching EndUpdate call. + /// + public void BeginUpdate() + { + _BeginUpdateCount++; + } + + /// + /// Calling the EndUpdate routine informs the grid + /// that an extended update phase has ended. + /// + /// BeginUpdate / EndUpdate can be nested and must be + /// called in pairs every EndUpdate must have a + /// matching BeginUpdate call. + /// + public void EndUpdate() + { + if (_BeginUpdateCount > 0) + { + if (--_BeginUpdateCount == 0) + _PrimaryGrid.InvalidateMerge(); + } + } + + #endregion + + #region INotifyPropertyChanged Members + + /// + /// Occurs when property value has changed. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the PropertyChanged event. + /// + /// Event arguments + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + PropertyChangedEventHandler handler = PropertyChanged; + + if (handler != null) + handler(this, e); + } + + /// + /// Default PropertyChanged processing + /// + /// + protected void OnPropertyChanged(string s) + { + if (PropertyChanged != null) + OnPropertyChanged(new PropertyChangedEventArgs(s)); + } + + #endregion + + #region IMessageFilter Members + + /// + /// PreFilterMessage + /// + /// + /// + public bool PreFilterMessage(ref Message m) + { + if (DesignMode == true || Enabled == false) + return (false); + + if (ContainsFocus == true || m.Msg == WmMouseDown || m.Msg == WmMouseWheel) + { + switch (m.Msg) + { + case WmKeyDown: + TrackModifiers(); + + if (_KeyPressSent == true) + { + _KeyPressSent = false; + } + else + { + _IsInputKey = false; + + Keys keyData = (Keys) (int) m.WParam & Keys.KeyCode; + + if (DoGridPreviewKeyDown(keyData) == true) + return (true); + + keyData |= ModifierKeys; + + _LastKeyDown = keyData; + + if (_ActiveEditor != null && _EditorCell != null) + return (ProcessInEditKeyDown(keyData)); + + if (_ActiveFilterPanel != null) + return (ProcessInFilterEditKeyDown(keyData)); + } + + return (false); + + case WmKeyUp: + TrackModifiers(); + UpdateInternalMouseMove(); + break; + + case WmMouseDown: + if (IsOverNonModalEditorWindow() == true) + { + Focus(); + ExtendNonModalSelection(); + } + break; + + case WmMouseWheel: + if (CanProcessMouseWheel() == true) + { + if ((LoWord(m.WParam) & 0x8) == 0) + { + if (_VScrollBar.Visible == true) + { + Rectangle r = DisplayRectangle; + r.Location = PointToScreen(r.Location); + + Point mousePos = new Point(LoWord(m.LParam), HiWord(m.LParam)); + + if (r.Contains(mousePos)) + { + short detents = (short)HiWord(m.WParam); + int delta = (detents / SystemInformation.MouseWheelScrollDelta); + + MouseWheelHandler(delta); + + return (true); + } + } + } + } + break; + } + } + + if (_ActiveNonModalEditor != null) + { + switch (m.Msg) + { + case WmMouseMove: + if (IsOverNonModalEditorWindow() == false) + { + if (_ActiveNonModalEditor.CanInterrupt == true) + DeactivateNonModalEditor(); + } + break; + } + } + + return (false); + } + + #region CanProcessMouseWheel + + [System.Runtime.InteropServices.DllImport("user32.dll")] + private static extern IntPtr WindowFromPoint(Point pnt); + + private bool CanProcessMouseWheel() + { + IntPtr hWnd = WindowFromPoint(Control.MousePosition); + + if (hWnd != IntPtr.Zero) + { + Control ctl = Control.FromHandle(hWnd); + + if (ctl == null || ctl.FindForm() != FindForm()) + return (false); + } + + if (_ActiveEditor == null && _ActiveFilterPanel == null) + { + if (_ActiveNonModalEditor != null) + { + if (_ActiveNonModalEditor.CanInterrupt == false) + return (false); + } + + return (true); + } + + return (false); + } + + #endregion + + #region HiWord / LoWord + + private int LoWord(int n) + { + return (short)(n & 0xffff); + } + + private int HiWord(int n) + { + return (n >> 0x10); + } + + private int LoWord(IntPtr n) + { + return LoWord((int)((long)n)); + } + + private int HiWord(IntPtr n) + { + return HiWord((int)((long)n)); + } + + #endregion + + #region TrackModifiers + + private void TrackModifiers() + { + if ((_LastModifierKeys & Keys.Control) != (ModifierKeys & Keys.Control)) + { + _LastModifierKeys = ModifierKeys; + + Cursor.Position = Cursor.Position; + } + } + + #endregion + + #region IsOverNonModalEditorWindow + + private bool IsOverNonModalEditorWindow() + { + if (_ActiveNonModalEditor != null) + { + Point pt = MousePosition; + + if (NonModalEditorCell.GridColumn != null) + { + Rectangle r = NonModalEditorCell.CellBounds; + r.Location = PointToScreen(r.Location); + + bool hit = r.Contains(pt); + + return (hit); + } + } + + return (false); + } + + #endregion + + #endregion + + #region WndProc + + /// + /// WndProc + /// + /// + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case WmSetFocus: + if (_PopupControl != null) + _PopupControl.Hide(); + break; + } + + base.WndProc(ref m); + } + + #endregion + + #region ActivateNonModalEditor + + internal void ActivateNonModalEditor( + IGridCellEditControl editor, GridCell cell) + { + ActiveNonModalEditor = editor; + NonModalEditorCell = cell; + } + + #endregion + + #region DeactivateNonModalEditor + + /// + /// Deactivates any active NonModal editor. + /// + public void DeactivateNonModalEditor() + { + if (_ActiveNonModalEditor != null) + { + _ActiveNonModalEditor.EditorPanel.Hide(); + _ActiveNonModalEditor.OnCellMouseLeave(EventArgs.Empty); + + if (_NonModalEditorCell.GridPanel != null) + { + _NonModalEditorCell.GridPanel.InternalMouseMove(new MouseEventArgs(MouseButtons.None, 0, -1, -1, 0)); + + if (_NonModalEditorCell.GridPanel.SelectionGranularity != SelectionGranularity.Cell) + _NonModalEditorCell.GridRow.InvalidateRender(); + else + _NonModalEditorCell.InvalidateRender(); + } + + if (_NonModalEditorCell.SuperGrid.ContainsFocus == true) + Focus(); + + _ActiveNonModalEditor = null; + _NonModalEditorCell = null; + } + } + + #region ExtendNonModalSelection + + /// + /// ExtendNonModalSelection + /// + internal void ExtendNonModalSelection() + { + GridPanel panel = _NonModalEditorCell.GridPanel; + + if (panel != null) + { + GridCell cell = _NonModalEditorCell; + GridRow row = cell.GridRow; + + panel.SetActiveRow(row, true); + + switch (panel.SelectionGranularity) + { + case SelectionGranularity.Row: + case SelectionGranularity.RowWithCellHighlight: + row.ExtendSelection(panel); + break; + + case SelectionGranularity.Cell: + cell.ExtendSelection(panel); + + if (_ActiveNonModalEditor != null) + cell.PositionEditPanel(_ActiveNonModalEditor); + break; + } + } + } + + #endregion + + #endregion + + #region UpdateStyleCount + + internal int UpdateStyleCount() + { + StyleUpdateCount++; + + return (StyleUpdateCount); + } + + #endregion + + #region CancelCapture + + /// + /// Cancels any in-progress operations that + /// may have the mouse captured (and releases the capture). + /// + public void CancelCapture() + { + if (_CapturedItem != null) + _CapturedItem.CancelCapture(); + } + + #endregion + + #region Dispose + + /// + /// Dispose + /// + /// + protected override void Dispose(bool disposing) + { + EndWorkers(); + + Application.RemoveMessageFilter(this); + StyleManager.Unregister(this); + + PrimaryGrid.Dispose(); + + if (_VScrollBar != null) + { + _VScrollBar.Scroll -= VScrollBarScroll; + _VScrollBar.MouseEnter -= ScrollBarMouseEnter; + _VScrollBar.SizeChanged -= ScrollBarSizeChanged; + } + + if (_HScrollBar != null) + { + _HScrollBar.Scroll -= HScrollBarScroll; + _HScrollBar.MouseEnter -= ScrollBarMouseEnter; + _HScrollBar.SizeChanged -= ScrollBarSizeChanged; + } + + base.Dispose(disposing); + } + + private int _WorkerCount; + internal bool DisposeRequested; + + private List _Threads = new List(); + + internal void BeginWorker(Thread thread) + { + Interlocked.Increment(ref _WorkerCount); + + _Threads.Add(thread); + } + + internal void EndWorker(Thread thread) + { + Interlocked.Decrement(ref _WorkerCount); + + _Threads.Remove(thread); + } + + private void EndWorkers() + { + DisposeRequested = true; + + foreach (Thread th in _Threads) + th.Abort(); + + for (int i = 0; _WorkerCount > 0 && i < 500; i++) + { + Thread.Sleep(10); + + Application.DoEvents(); + } + } + + #endregion + + #region Licensing +#if !TRIAL + private string _LicenseKey = ""; + /// + /// LicenseKey + /// + [Browsable(false), DefaultValue("")] + public string LicenseKey + { + get { return _LicenseKey; } + set + { + if (NativeFunctions.ValidateLicenseKey(value)) + return; + _LicenseKey = (!NativeFunctions.CheckLicenseKey(value) ? "9dsjkhds7" : value); + } + } +#endif + #endregion + + #region Touch Handling + + private Touch.TouchHandler _TouchHandler; + private bool _TouchEnabled = true; + + /// + /// Indicates whether touch support for scrolling is enabled. + /// + [DefaultValue(true), Category("Behavior")] + [Description("Indicates whether touch support for scrolling is enabled.")] + public bool TouchEnabled + { + get { return _TouchEnabled; } + + set + { + if (value != _TouchEnabled) + { + bool oldValue = _TouchEnabled; + _TouchEnabled = value; + + OnTouchEnabledChanged(oldValue, value); + } + } + } + + /// + /// Called when TouchEnabled property has changed. + /// + /// Old property value + /// New property value + protected virtual void OnTouchEnabledChanged(bool oldValue, bool newValue) + { + //OnPropertyChanged(new PropertyChangedEventArgs("TouchEnabled")); + } + + //private int TriggerPageChangeOffset + //{ + // get { return 32; } + //} + + private int MaximumReversePageOffset + { + get { return 0; } //Math.Min(32, this.Width / 6); + } + + private bool _TouchDrag; + private Point _TouchStartLocation = Point.Empty; + private Point _TouchStartScrollPosition = Point.Empty; + private Rectangle _TouchInnerBounds = Rectangle.Empty; + + private void TouchHandlerPanBegin(object sender, Touch.GestureEventArgs e) + { + if (_TouchEnabled) + { + _TouchInnerBounds = SViewRect; + _TouchStartLocation = e.Location; + _TouchStartScrollPosition = AutoScrollPosition; + _TouchDrag = true; + + e.Handled = true; + } + } + + private void TouchHandlerPanEnd(object sender, Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + EndTouchPan(); + + e.Handled = true; + } + } + + private Point AutoScrollPosition + { + get { return new Point(-_HScrollOffset, -_VScrollOffset); } + + set + { + if (value.X != _HScrollOffset) + SetHScrollValue(-value.X); + + if (value.Y != _VScrollOffset) + SetVScrollValue(-value.Y); + } + } + + private void EndTouchPan() + { + _TouchDrag = false; + + Point autoScrollPosition = AutoScrollPosition; + Size autoScrollMinSize = new Size(_HScrollBar.Maximum, _VScrollBar.Maximum); + + if (autoScrollMinSize.Width > _TouchInnerBounds.Width) + { + if (autoScrollMinSize.Width - _TouchInnerBounds.Width < -autoScrollPosition.X) + autoScrollPosition = new Point(autoScrollMinSize.Width - _TouchInnerBounds.Width, autoScrollPosition.Y); + else if (-autoScrollPosition.X < 0) + autoScrollPosition = new Point(0, autoScrollPosition.Y); + } + + if (autoScrollMinSize.Height > _TouchInnerBounds.Height) + { + if (autoScrollMinSize.Height - _TouchInnerBounds.Height < -autoScrollPosition.Y) + autoScrollPosition = new Point(autoScrollPosition.X, autoScrollMinSize.Height - _TouchInnerBounds.Height); + else if (-autoScrollPosition.Y < 0) + autoScrollPosition = new Point(autoScrollPosition.X, 0); + } + + if (AutoScrollPosition != autoScrollPosition) + AutoScrollPosition = autoScrollPosition; + + //ApplyScrollChange(); + + } + + private void TouchHandlerPan(object sender, Touch.GestureEventArgs e) + { + if (_TouchDrag) + { + Point autoScrollPosition = AutoScrollPosition; + Size autoScrollMinSize = new Size(_HScrollBar.Maximum, _VScrollBar.Maximum); + int offset = (e.Location.X - _TouchStartLocation.X); + int offsetChange = offset + _TouchStartScrollPosition.X; + + bool overflowH = false; + + if (autoScrollMinSize.Width > _TouchInnerBounds.Width) + { + if (-offsetChange + MaximumReversePageOffset > autoScrollMinSize.Width - _TouchInnerBounds.Width) + { + autoScrollPosition.X = -(autoScrollMinSize.Width + MaximumReversePageOffset - _TouchInnerBounds.Width); + overflowH = true; + } + else if (offsetChange > MaximumReversePageOffset) + { + autoScrollPosition.X = MaximumReversePageOffset; + overflowH = true; + } + else + autoScrollPosition.X = offsetChange; + } + + // Y Scroll + bool overflowV = false; + if (autoScrollMinSize.Height > _TouchInnerBounds.Height) + { + offset = (e.Location.Y - _TouchStartLocation.Y); + offsetChange = offset + _TouchStartScrollPosition.Y; + + if (-offsetChange + MaximumReversePageOffset > autoScrollMinSize.Height - _TouchInnerBounds.Height) + { + autoScrollPosition.Y = -(autoScrollMinSize.Height + MaximumReversePageOffset - _TouchInnerBounds.Height); + overflowV = true; + } + else if (offsetChange > MaximumReversePageOffset) + { + autoScrollPosition.Y = MaximumReversePageOffset; + overflowV = true; + } + else + autoScrollPosition.Y = offsetChange; + } + + if (AutoScrollPosition != autoScrollPosition) + { + AutoScrollPosition = autoScrollPosition; + Update(); + } + + if (overflowH && overflowV && e.IsInertia) + EndTouchPan(); + + e.Handled = true; + } + } + + #endregion + + #region Localize Members + + #region InvokeLocalizeString + + /// + /// InvokeLocalizeString + /// + /// + public void InvokeLocalizeString(LocalizeEventArgs e) + { + if (LocalizeString != null) + LocalizeString(this, e); + } + + #endregion + + #region LocalizedString + + private string LocalizedString(ref string lstring) + { + LoadLocalizedStrings(); + + return (lstring); + } + + #endregion + + #region LoadLocalizedStrings + + private void LoadLocalizedStrings() + { + if (_LocalizedStringsLoaded == false) + { + using (LocalizationManager lm = new LocalizationManager(this)) + { + string s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterShowAll)) != "") + _FilterShowAllString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterCustom)) != "") + _FilterCustomString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterShowNull)) != "") + _FilterShowNullString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterShowNotNull)) != "") + _FilterShowNotNullString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterApply)) != "") + _FilterApplyString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterOk)) != "") + _FilterOkString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterCancel)) != "") + _FilterCancelString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridFilterClose)) != "") + _FilterCloseString = s; + + if ((s = lm.GetLocalizedString(LocalizationKeys.SuperGridGroupByWaterMarkText)) != "") + _GroupByWaterMarkText = s; + } + + _LocalizedStringsLoaded = true; + } + } + + #endregion + + #endregion + } + + #region enums + + #region AutoScrollEnable + + [Flags] + internal enum AutoScrollEnable + { + None = 0, + Vertical = (1 << 0), + Horizontal = (1 << 1), + } + + #endregion + + #region PlaySoundContext + + /// + /// Context under which system sound ('beep') is played. + /// + public enum PlaySoundContext + { + /// + /// Attempted activation of a cell which is marked as non-selectable + /// or is an EmptyCell with AllowEmptyCellSelection set to false. + /// + CellActivate, + + /// + /// Cell validation failure notification. + /// + CellValidate, + + /// + /// Attempted activation of a grid row which is marked as non-selectable. + /// + RowActivate, + + /// + /// Row validation failure notification. + /// + RowDeactivate, + + /// + /// Row validation failure notification. + /// + RowValidate, + + /// + /// Row deletion failure via DEL key input. + /// + RowDeleteAttempt, + + /// + /// Row un-deletion failure via Shift-DEL key input. + /// + RowUnDeleteAttempt, + + /// + /// Row insert failure via INS key input. + /// + RowInsertAttempt, + + /// + /// Trying to suspend merge of a group of mergesd cells when + /// AllowSuspend is set to false. + /// + MergeSuspend, + } + + + #endregion + + #region DataContext + + /// + /// Context under which data is being accessed + /// + public enum DataContext + { + /// + /// CellEdit + /// + CellEdit, + + /// + /// CellKeyEvent + /// + CellKeyEvent, + + /// + /// CellMouseEvent + /// + CellMouseEvent, + + /// + /// CellProposedSize + /// + CellProposedSize, + + /// + /// CellRender + /// + CellRender, + + /// + /// CellValueLoad + /// + CellValueLoad, + + /// + /// CellValueStore + /// + CellValueStore, + + /// + /// CellExpressionParse + /// + CellExpressionParse, + + /// + /// CellExpressionEval + /// + CellExpressionEval, + + /// + /// CellGetFormattedValue + /// + CellGetFormattedValue, + + /// + /// SetRowPosition + /// + SetRowPosition, + + /// + /// RowFlush + /// + RowFlush, + + /// + /// InsertRow + /// + InsertRow, + } + + #endregion + + #region ExpandButtonType + + /// + /// Expand button type + /// + public enum ExpandButtonType + { + /// + /// NotSet + /// + NotSet = -1, + + /// + /// None + /// + None, + + /// + /// Circle + /// + Circle, + + /// + /// Square + /// + Square, + + /// + /// Triangle + /// + Triangle, + } + + #endregion + + #region NewRowContext + + /// + /// Context under which the New + /// row is being accessed / created + /// + public enum NewRowContext + { + /// + /// RowInit + /// + RowInit, + + /// + /// RowActivate + /// + RowActivate, + + /// + /// RowDeactivate + /// + RowDeactivate, + } + + #endregion + + #region RenderParts + + /// + /// Identifies grid 'parts' to be rendered + /// + [Flags] + public enum RenderParts + { + /// + /// Nothing to render + /// + Nothing = 0, + + /// + /// Background needs to be rendered + /// + Background = (1 << 0), + + /// + /// Border needs to be rendered + /// + Border = (1 << 1), + + /// + /// Content needs to be rendered + /// + Content = (1 << 2), + + /// + /// RowHeader needs to be rendered + /// + RowHeader = (1 << 3), + + /// + /// Whitespace needs to be rendered + /// + Whitespace = (1 << 4), + } + + #endregion + + #region TabSelection + + /// + /// Identifies selection style when the Tab key is pressed + /// + public enum TabSelection + { + /// + /// Previous / Next cell. + /// + Cell, + + /// + /// Previous / Next cell in the same row. + /// + CellSameRow, + + /// + /// Previous / Next Control. + /// + Control, + } + + #endregion + + #endregion + + #region EventArgs + + #region GridCellActivatedEventArgs + + /// + /// GridCellActivatedEventArgs + /// + public class GridCellActivatedEventArgs : GridEventArgs + { + #region Private variables + + private readonly GridCell _OldActiveCell; + private readonly GridCell _NewActiveCell; + + #endregion + + /// + /// GridCellActivatedEventArgs + /// + /// + /// + /// + public GridCellActivatedEventArgs( + GridPanel gridPanel, GridCell oldCell, GridCell newCell) + : base(gridPanel) + { + _OldActiveCell = oldCell; + _NewActiveCell = newCell; + } + + #region Public properties + + /// + /// Gets the old (previous) ActiveCell + /// + public GridCell OldActiveCell + { + get { return (_OldActiveCell); } + } + + /// + /// Gets the new (current) ActiveCell + /// + public GridCell NewActiveCell + { + get { return (_NewActiveCell); } + } + + #endregion + } + + #endregion + + #region GridCellActivatingEventArgs + + /// + /// GridCellActivatingEventArgs + /// + public class GridCellActivatingEventArgs : GridCellActivatedEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridCellActivatedEventArgs + /// + /// + /// + /// + public GridCellActivatingEventArgs( + GridPanel gridPanel, GridCell oldCell, GridCell newCell) + : base(gridPanel, oldCell, newCell) + { + } + + #region Public properties + + /// + /// Gets or sets whether to Cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridActiveGridChangedEventArgs + + /// + /// ActiveGridChangedEventArgs + /// + public class GridActiveGridChangedEventArgs : EventArgs + { + #region Private variables + + private readonly GridPanel _NewGridPanel; + private readonly GridPanel _OldGridPanel; + + #endregion + + /// + /// GridActiveGridChangedEventArgs + /// + /// + /// + public GridActiveGridChangedEventArgs( + GridPanel oldGridPanel, GridPanel newGridPanel) + { + _OldGridPanel = oldGridPanel; + _NewGridPanel = newGridPanel; + } + + #region Public properties + + /// + /// Gets the old (previous) active GridPanel + /// + public GridPanel OldGridPanel + { + get { return (_OldGridPanel); } + } + + /// + /// Gets the new (current) active GridPanel + /// + public GridPanel NewGridPanel + { + get { return (_NewGridPanel); } + } + + #endregion + } + + #endregion + + #region GridAfterCheckEventArgs + + /// + /// GridAfterCheckEventArgs + /// + public class GridAfterCheckEventArgs : GridEventArgs + { + #region Private variables + + private GridElement _Item; + + #endregion + + /// + /// GridAfterCheckEventArgs + /// + /// + /// + public GridAfterCheckEventArgs(GridPanel gridPanel, GridElement item) + : base(gridPanel) + { + _Item = item; + } + + #region Public properties + + /// + /// Gets the Item being checked or unchecked + /// + public GridElement Item + { + get { return (_Item); } + } + + #endregion + } + + #endregion + + #region GridAfterCollapseEventArgs + + /// + /// GridAfterCollapseEventArgs + /// + public class GridAfterCollapseEventArgs : GridAfterExpandEventArgs + { + /// + /// GridRowAfterCollapseEventArgs + /// + /// + /// + /// + public GridAfterCollapseEventArgs(GridPanel gridPanel, GridContainer gridContainer, ExpandSource expandSource) + : base(gridPanel, gridContainer, expandSource) + { + } + } + + #endregion + + #region GridAfterExpandEventArgs + + /// + /// GridAfterExpandChangeEventArgs + /// + public class GridAfterExpandEventArgs : GridEventArgs + { + #region Private variables + + private GridContainer _GridContainer; + private ExpandSource _ExpandSource; + + #endregion + + /// + /// GridAfterExpandChangeEventArgs + /// + /// + /// + /// + public GridAfterExpandEventArgs( + GridPanel gridPanel, GridContainer gridContainer, ExpandSource expandSource) + : base(gridPanel) + { + _GridContainer = gridContainer; + _ExpandSource = expandSource; + } + + #region Public properties + + /// + /// Gets the GridContainer being expanded or collapsed + /// + public GridContainer GridContainer + { + get { return (_GridContainer); } + } + + /// + /// Returns the source of the operation + /// + public ExpandSource ExpandSource + { + get { return (_ExpandSource); } + } + + #endregion + } + + #endregion + + #region GridBeforeCheckEventArgs + + /// + /// GridRowBeforeExpandEventArgs + /// + public class GridBeforeCheckEventArgs : GridAfterCheckEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridBeforeCheckEventArgs + /// + /// + /// + public GridBeforeCheckEventArgs(GridPanel gridPanel, GridElement gridRow) + : base(gridPanel, gridRow) + { + } + + #region Public properties + + /// + /// Gets or sets whether to Cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridBeforeCollapseEventArgs + + /// + /// GridBeforeExpandEventArgs + /// + public class GridBeforeCollapseEventArgs : GridBeforeExpandEventArgs + { + /// + /// GridBeforeExpandEventArgs + /// + /// + /// + /// + public GridBeforeCollapseEventArgs(GridPanel gridPanel, GridContainer gridContainer, ExpandSource expandSource) + : base(gridPanel, gridContainer, expandSource) + { + } + } + + #endregion + + #region GridBeforeExpandEventArgs + + /// + /// GridBeforeExpandEventArgs + /// + public class GridBeforeExpandEventArgs : GridAfterExpandEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridRowBeforeExpandEventArgs + /// + /// + /// + /// + public GridBeforeExpandEventArgs(GridPanel gridPanel, GridContainer gridContainer, ExpandSource expandSource) + : base(gridPanel, gridContainer, expandSource) + { + } + + #region Public properties + + /// + /// Gets or sets whether to Cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridCellEventArgs + + /// + /// GridCellEventArgs + /// + public class GridCellEventArgs : GridEventArgs + { + #region Private variables + + private readonly GridCell _GridCell; + + #endregion + + /// + /// GridCellEventArgs + /// + /// + /// + public GridCellEventArgs(GridPanel gridPanel, GridCell gridCell) + : base(gridPanel) + { + _GridCell = gridCell; + } + + #region Public properties + + /// + /// Gets the associated GridCell + /// + public GridCell GridCell + { + get { return (_GridCell); } + } + + #endregion + } + + #endregion + + #region GridCellClickEventArgs + + /// + /// GridCellClickEventArgs + /// + public class GridCellClickEventArgs : GridCellEventArgs + { + #region Private variables + + private bool _Cancel; + private MouseEventArgs _MouseEventArgs; + + #endregion + + /// + /// GridCellClickEventArgs + /// + /// + /// + /// + public GridCellClickEventArgs( + GridPanel gridPanel, GridCell gridCell, MouseEventArgs e) + : base(gridPanel, gridCell) + { + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + #endregion + } + + #endregion + + #region GridCellDoubleClickEventArgs + + /// + /// GridCellDoubleClickEventArgs + /// + public class GridCellDoubleClickEventArgs : GridCellClickEventArgs + { + /// + /// GridCellDoubleClickEventArgs + /// + /// + /// + /// + public GridCellDoubleClickEventArgs(GridPanel gridPanel, GridCell gridCell, MouseEventArgs e) + : base(gridPanel, gridCell, e) + { + } + } + + #endregion + + #region GridCellInfoEnterEventArgs + + /// + /// GridCellInfoEnterEventArgs + /// + public class GridCellInfoEnterEventArgs : GridCellEventArgs + { + #region Private variables + + private bool _Cancel; + private Point _Location; + private Control _Control; + + private System.Windows.Forms.ToolTip _ToolTip; + + #endregion + + /// + /// GridCellInfoEnterEventArgs + /// + /// + /// + /// + /// + public GridCellInfoEnterEventArgs(GridPanel gridPanel, + GridCell gridCell, Control control, System.Windows.Forms.ToolTip toolTip, Point pt) + : base(gridPanel, gridCell) + { + _Location = pt; + _Control = control; + _ToolTip = toolTip; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the default operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated Control associated with the CellInfo (can + /// either be the GridControl or CellInfoWindow - depending upon + /// whether an edit is currently active or not). + /// + public Control Control + { + get { return (_Control); } + } + + // + /// Gets the associated event ToolTip control + /// + public System.Windows.Forms.ToolTip ToolTip + { + get { return (_ToolTip); } + } + + // + /// Gets the associated event Location + /// + public Point Location + { + get { return (_Location); } + } + + #endregion + } + + #endregion + + #region GridCellInfoLeaveEventArgs + + /// + /// GridCellInfoLeaveEventArgs + /// + public class GridCellInfoLeaveEventArgs : GridCellEventArgs + { + #region Private variables + + private Control _Control; + private System.Windows.Forms.ToolTip _ToolTip; + + #endregion + + /// + /// GridRowInfoLeaveEventArgs + /// + /// + /// + /// + public GridCellInfoLeaveEventArgs(GridPanel gridPanel, + GridCell gridCell, Control control, System.Windows.Forms.ToolTip toolTip) + : base(gridPanel, gridCell) + { + _Control = control; + _ToolTip = toolTip; + } + + #region Public properties + + /// + /// Gets the associated Control associated with the CellInfo (can + /// either be the GridControl or CellInfoWindow - depending upon + /// whether an edit is currently active or not). + /// + public Control Control + { + get { return (_Control); } + } + + // + /// Gets the associated event ToolTip control + /// + public System.Windows.Forms.ToolTip ToolTip + { + get { return (_ToolTip); } + } + + #endregion + } + + #endregion + + #region GridCellMouseEventArgs + + /// + /// GridCellMouseEventArgs + /// + public class GridCellMouseEventArgs : MouseEventArgs + { + #region Private variables + + private readonly GridPanel _GridPanel; + private readonly GridCell _GridCell; + + #endregion + + /// + /// GridCellMouseEventArgs + /// + /// + /// + /// + public GridCellMouseEventArgs(GridPanel gridPanel, GridCell gridCell, MouseEventArgs ev) + : base(ev.Button, ev.Clicks, ev.X, ev.Y, ev.Delta) + { + _GridPanel = gridPanel; + _GridCell = gridCell; + } + + #region Public properties + + /// + /// Gets the associated GridCell + /// + public GridCell GridCell + { + get { return (_GridCell); } + } + + /// + /// Gets the associated GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + #endregion + } + + #endregion + + #region GridCellUserFunctionEventArgs + + /// + /// GridCellUserFunctionEventArgs + /// + public class GridCellUserFunctionEventArgs : GridCellEventArgs + { + #region Private variables + + private object[] _Args; + private object _Result; + + #endregion + + /// + /// GridCellUserFunctionEventArgs + /// + /// + /// + /// + /// + public GridCellUserFunctionEventArgs( + GridPanel gridPanel, GridCell gridCell, object[] args, object result) + : base(gridPanel, gridCell) + { + _Args = args; + _Result = result; + } + + #region Public properties + + /// + /// Gets or sets the associated function arguments + /// + public object[] Args + { + get { return (_Args); } + set { _Args = value; } + } + + /// + /// Gets or sets the associated function result + /// + public object Result + { + get { return (_Result); } + set { _Result = value; } + } + + #endregion + } + + #endregion + + #region GridCellValidatedEventArgs + + /// + /// GridCellValidatedEventArgs + /// + public class GridCellValidatedEventArgs : GridCellEventArgs + { + /// + /// GridCellValidatedEventArgs + /// + /// + /// + public GridCellValidatedEventArgs(GridPanel gridPanel, GridCell gridCell) + : base(gridPanel, gridCell) + { + } + } + + #endregion + + #region GridCellValidatingEventArgs + + /// + /// GridCellValidatingEventArgs + /// + public class GridCellValidatingEventArgs : GridCellEventArgs + { + #region Private variables + + private bool _Cancel; + + private object _Value; + private object _FormattedValue; + + #endregion + + /// + /// GridCellValidatingEventArgs + /// + /// + /// + /// + /// + public GridCellValidatingEventArgs(GridPanel gridPanel, + GridCell gridCell, object value, object formattedValue) + : base(gridPanel, gridCell) + { + _Value = value; + _FormattedValue = formattedValue; + } + + #region Public properties + + /// + /// Gets or sets the Value to validate + /// + public object Value + { + get { return (_Value); } + set { _Value = value; } + } + + /// + /// Gets the formatted Value + /// + public object FormattedValue + { + get { return (_FormattedValue); } + } + + /// + /// Gets or sets whether to cancel the operation + /// resulting in the cell validation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridCellValueChangedEventArgs + + /// + /// GridCellValueChangedEventArgs + /// + public class GridCellValueChangedEventArgs : GridCellEventArgs + { + #region Private variables + + private object _OldValue; + private object _NewValue; + private DataContext _DataContext; + + #endregion + + /// + /// GridCellValueChangedEventArgs + /// + /// + /// + /// + /// + /// + public GridCellValueChangedEventArgs(GridPanel gridPanel, + GridCell gridCell, object oldValue, object newValue, DataContext context) + : base(gridPanel, gridCell) + { + _OldValue = oldValue; + _NewValue = newValue; + + _DataContext = context; + } + + #region Public properties + + /// + /// Gets the context under which + /// the call value was changed + /// + public DataContext DataContext + { + get { return (_DataContext); } + } + + /// + /// Gets the old cell Value + /// + public object OldValue + { + get { return (_OldValue); } + } + + /// + /// Gets the new cell Value + /// + public object NewValue + { + get { return (_NewValue); } + } + + #endregion + } + + #endregion + + #region GridColumnEventArgs + + /// + /// GridColumnEventArgs + /// + public class GridColumnEventArgs : EventArgs + { + #region Private variables + + private GridPanel _GridPanel; + private GridColumn _GridColumn; + + #endregion + + /// + /// GridColumnEventArgs + /// + /// + /// + public GridColumnEventArgs(GridPanel gridPanel, GridColumn gridColumn) + { + _GridPanel = gridPanel; + _GridColumn = gridColumn; + } + + #region Public properties + + /// + /// Gets th associated GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + /// + /// Gets the associated GridColumn + /// + public GridColumn GridColumn + { + get { return (_GridColumn); } + } + + #endregion + } + + #endregion + + #region GridColumnHeaderClickEventArgs + + /// + /// GridColumnHeaderClickEventArgs + /// + public class GridColumnHeaderClickEventArgs : GridColumnEventArgs + { + #region Private variables + + private bool _Cancel; + private MouseEventArgs _MouseEventArgs; + + #endregion + + /// + /// GridColumnHeaderClickEventArgs + /// + /// + /// + /// + public GridColumnHeaderClickEventArgs( + GridPanel gridPanel, GridColumn gridColumn, MouseEventArgs e) + : base(gridPanel, gridColumn) + { + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + #endregion + } + + #endregion + + #region GridColumnHeaderEventArgs + + /// + /// GridColumnHeaderEventArgs + /// + public class GridColumnHeaderEventArgs : EventArgs + { + #region Private variables + + private GridColumnHeader _GridColumnHeader; + + #endregion + + /// + /// GridColumnHeaderEventArgs + /// + /// + /// + public GridColumnHeaderEventArgs(GridColumnHeader gridColumnHeader) + { + _GridColumnHeader = gridColumnHeader; + } + + #region Public properties + + /// + /// Gets th associated GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridColumnHeader.GridPanel); } + } + + /// + /// Gets the associated GridColumnHeader + /// + public GridColumnHeader GridColumnHeader + { + get { return (_GridColumnHeader); } + } + + #endregion + } + + #endregion + + #region GridColumnHeaderMarkupLinkClickEventArgs + + /// + /// GridColumnHeaderMarkupLinkClickEventArgs + /// + public class GridColumnHeaderMarkupLinkClickEventArgs : GridColumnEventArgs + { + #region Private variables + + private string _HRef; + private string _Name; + + #endregion + + /// + /// GridColumnHeaderMarkupLinkClickEventArgs + /// + /// + /// + /// + /// + public GridColumnHeaderMarkupLinkClickEventArgs( + GridPanel gridPanel, GridColumn gridColumn, string name, string href) + : base(gridPanel, gridColumn) + { + _HRef = href; + _Name = name; + } + + #region Public properties + + /// + /// Gets the associated HyperLink HRef + /// + public string HRef + { + get { return (_HRef); } + } + + /// + /// Gets the associated HyperLink Name + /// + public string Name + { + get { return (_Name); } + } + + #endregion + } + + #endregion + + #region GridColumnHeaderDoubleClickEventArgs + + /// + /// GridColumnHeaderDoubleClickEventArgs + /// + public class GridColumnHeaderDoubleClickEventArgs : GridColumnHeaderClickEventArgs + { + /// + /// GridColumnHeaderDoubleClickEventArgs + /// + /// + /// + /// + public GridColumnHeaderDoubleClickEventArgs( + GridPanel gridPanel, GridColumn gridColumn, MouseEventArgs e) + : base(gridPanel, gridColumn, e) + { + } + } + + #endregion + + #region GridColumnHeaderMouseEventArgs + + /// + /// GridColumnHeaderMouseEventArgs + /// + public class GridColumnHeaderMouseEventArgs : MouseEventArgs + { + #region Private variables + + private readonly GridColumnHeader _GridColumnHeader; + + #endregion + + /// + /// GridColumnHeaderMouseEventArgs + /// + /// + /// + /// + public GridColumnHeaderMouseEventArgs(GridColumnHeader gridColumnHeader, MouseEventArgs ev) + : base(ev.Button, ev.Clicks, ev.X, ev.Y, ev.Delta) + { + _GridColumnHeader = gridColumnHeader; + } + + #region Public properties + + /// + /// Gets the associated GridColumnHeader + /// + public GridColumnHeader GridColumnHeader + { + get { return (_GridColumnHeader); } + } + + /// + /// Gets the associated GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridColumnHeader.GridPanel); } + } + + #endregion + } + + #endregion + + #region GridColumnGroupHeaderClickEventArgs + + /// + /// GridColumnGroupHeaderClickEventArgs + /// + public class GridColumnGroupHeaderClickEventArgs : GridEventArgs + { + #region Private variables + + private GridColumnHeader _ColumnHeader; + private ColumnGroupHeader _GroupHeader; + private MouseEventArgs _MouseEventArgs; + + private bool _Cancel; + + #endregion + + /// + /// GridColumnGroupHeaderClickEventArgs + /// + /// + /// + /// + /// + public GridColumnGroupHeaderClickEventArgs(GridPanel gridPanel, + GridColumnHeader header, ColumnGroupHeader groupHeader, MouseEventArgs e) + : base(gridPanel) + { + _ColumnHeader = header; + _GroupHeader = groupHeader; + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated ColumnHeader + /// + public GridColumnHeader ColumnHeader + { + get { return (_ColumnHeader); } + } + + /// + /// Gets the associated GroupHeader + /// + public ColumnGroupHeader GroupHeader + { + get { return (_GroupHeader); } + } + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + #endregion + } + + #endregion + + #region GridColumnGroupHeaderMarkupLinkClickEventArgs + + /// + /// GridColumnGroupHeaderMarkupLinkClickEventArgs + /// + public class GridColumnGroupHeaderMarkupLinkClickEventArgs : GridEventArgs + { + #region Private variables + + private GridColumnHeader _ColumnHeader; + private ColumnGroupHeader _GroupHeader; + + private string _HRef; + private string _Name; + + #endregion + + /// + /// GridColumnGroupHeaderMarkupLinkClickEventArgs + /// + /// + /// + /// + /// + /// + public GridColumnGroupHeaderMarkupLinkClickEventArgs(GridPanel gridPanel, + GridColumnHeader header, ColumnGroupHeader groupHeader, string name, string href) + : base(gridPanel) + { + _ColumnHeader = header; + _GroupHeader = groupHeader; + + _HRef = href; + _Name = name; + } + + #region Public properties + + /// + /// Gets the associated ColumnHeader + /// + public GridColumnHeader ColumnHeader + { + get { return (_ColumnHeader); } + } + + /// + /// Gets the associated GroupHeader + /// + public ColumnGroupHeader GroupHeader + { + get { return (_GroupHeader); } + } + + /// + /// Gets the associated HyperLink HRef + /// + public string HRef + { + get { return (_HRef); } + } + + /// + /// Gets the associated HyperLink Name + /// + public string Name + { + get { return (_Name); } + } + + #endregion + } + + #endregion + + #region GridColumnGroupHeaderDoubleClickEventArgs + + /// + /// GridColumnGroupHeaderDoubleClickEventArgs + /// + public class GridColumnGroupHeaderDoubleClickEventArgs : GridColumnGroupHeaderClickEventArgs + { + /// + /// GridColumnGroupHeaderDoubleClickEventArgs + /// + /// + /// + /// + /// + public GridColumnGroupHeaderDoubleClickEventArgs(GridPanel gridPanel, + GridColumnHeader header, ColumnGroupHeader groupHeader, MouseEventArgs e) + : base(gridPanel, header, groupHeader, e) + { + } + } + + #endregion + + #region GridColumnGroupHeaderResizedEventArgs + + /// + /// GridColumnGroupHeaderResizedEventArgs + /// + public class GridColumnGroupHeaderResizedEventArgs : EventArgs + { + #region Private variables + + private GridPanel _GridPanel; + private ColumnGroupHeader _GroupHeader; + private Size _OldSize; + + #endregion + + /// + /// GridColumnGroupHeaderResizedEventArgs + /// + /// + /// + /// + public GridColumnGroupHeaderResizedEventArgs( + GridPanel gridPanel, ColumnGroupHeader groupHeader, Size oldSize) + { + _GridPanel = gridPanel; + _GroupHeader = groupHeader; + _OldSize = oldSize; + } + + #region Public properties + + /// + /// Gets th associated GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + /// + /// Gets the associated GridHeader + /// + public ColumnGroupHeader GroupHeader + { + get { return (_GroupHeader); } + } + + /// + /// Gets the OldSize + /// + public Size OldSize + { + get { return (_OldSize); } + } + + /// + /// Gets the NewSize + /// + public Size NewSize + { + get { return (_GroupHeader.Size); } + } + + #endregion + } + + #endregion + + #region GridColumnGroupedEventArgs + + /// + /// GridColumnGroupedEventArgs + /// + public class GridColumnGroupedEventArgs : GridColumnEventArgs + { + #region Private variables + + private GridGroup _GridGroup; + + #endregion + + /// + /// GridColumnEventArgs + /// + /// + /// + /// + public GridColumnGroupedEventArgs( + GridPanel gridPanel, GridColumn gridColumn, GridGroup gridGroup) + : base(gridPanel, gridColumn) + { + _GridGroup = gridGroup; + } + + #region Public properties + + /// + /// Gets th associated GridGroup + /// + public GridGroup GridGroup + { + get { return (_GridGroup); } + } + + #endregion + } + + #endregion + + #region GridCompareElementsEventArgs + + /// + /// GridCompareElementsEventArgs + /// + public class GridCompareElementsEventArgs : GridCancelEventArgs + { + #region Private variables + + private readonly GridElement _ElementA; + private readonly GridElement _ElementB; + + private int _Result; + + #endregion + + /// + /// GridCompareElementsEventArgs + /// + /// + /// + /// + public GridCompareElementsEventArgs( + GridPanel gridPanel, GridElement a, GridElement b) + : base(gridPanel) + { + _ElementA = a; + _ElementB = b; + } + + #region Public properties + + /// + /// Gets the left-hand element of the comparison + /// + public GridElement ElementA + { + get { return (_ElementA); } + } + + /// + /// Gets the right-hand element of the comparison + /// + public GridElement ElementB + { + get { return (_ElementB); } + } + + /// + /// Gets or sets the result of the element compare. + /// -1 = ElementA is less than ElementB + /// 0 = ElementA is equal to ElementB + /// +1 = ElementA is greater than ElementB + /// + public int Result + { + get { return (_Result); } + set { _Result = value; } + } + + #endregion + } + + #endregion + + #region GridDataBindingStartEventArgs + + /// + /// GridDataBindingStartEventArgs + /// + public class GridDataBindingStartEventArgs : GridRowCancelEventArgs + { + #region Private variables + + private string _TableName; + private bool _AutoGenerateColumns; + private ProcessChildRelations _ProcessChildRelations; + + #endregion + + /// + /// GridDataBindingStartEventArgs + /// + ///Associated GridPanel + ///Associated GridRow + ///Name of table being bound to + ///Whether to auto-generate columns + /// + public GridDataBindingStartEventArgs(GridPanel gridPanel, + GridRow row, string tableName, bool autoGenerateColumns, ProcessChildRelations crProcess) + : base(gridPanel, row) + { + _TableName = tableName; + _AutoGenerateColumns = autoGenerateColumns; + _ProcessChildRelations = crProcess; + } + + #region Public properties + + /// + /// Gets or sets whether to auto-generate + /// the nested table columns + /// + public bool AutoGenerateColumns + { + get { return (_AutoGenerateColumns); } + set { _AutoGenerateColumns = value; } + } + + /// + /// Gets or sets how Child Relations + /// are processed by the SuperGrid + /// + public ProcessChildRelations ProcessChildRelations + { + get { return (_ProcessChildRelations); } + set { _ProcessChildRelations = value; } + } + + /// + /// Gets the nested table name being bound + /// + public string TableName + { + get { return (_TableName); } + } + + #endregion + } + + #endregion + + #region GridDataBindingCompleteEventArgs + + /// + /// GridDataBindingCompleteEventArgs + /// + public class GridDataBindingCompleteEventArgs : GridEventArgs + { + #region Private variables + + private ListChangedType _ListChangedType; + + #endregion + + /// + /// GridDataBindingCompleteEventArgs + /// + /// + public GridDataBindingCompleteEventArgs(GridPanel gridPanel) + : base(gridPanel) + { + _ListChangedType = ListChangedType.Reset; + } + + #region Public properties + + /// + /// Gets how the list was changed + /// + public ListChangedType ListChangedType + { + get { return (_ListChangedType); } + } + + #endregion + } + + #endregion + + #region GridDataErrorEventArgs + + /// + /// GridDataErrorEventArgs + /// + public class GridDataErrorEventArgs : CancelEventArgs + { + #region Private variables + + private GridPanel _GridPanel; + private GridCell _GridCell; + private Exception _Exception; + private DataContext _ErrorContext; + + private object _Value; + + private bool _Retry; + private bool _ThrowException; + + #endregion + + /// + /// GridDataErrorEventArgs + /// + public GridDataErrorEventArgs( + GridPanel gridPanel, GridCell gridCell, + Exception exception, DataContext context, object value) + { + _GridPanel = gridPanel; + _GridCell = gridCell; + _Exception = exception; + _ErrorContext = context; + _Value = value; + } + + #region Public properties + + /// + /// Gets the associated GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + /// + /// Gets the associated cell + /// + public GridCell GridCell + { + get { return (_GridCell); } + } + + /// + /// Gets the context under which the Exception was thrown + /// + public DataContext ErrorContext + { + get { return (_ErrorContext); } + } + + /// + /// Gets the Exception that was thrown + /// + public Exception Exception + { + get { return (_Exception); } + } + + /// + /// Gets or sets whether the grid should retry the operation + /// + public bool Retry + { + get { return (_Retry); } + set { _Retry = value; } + } + + /// + /// Gets whether the exception should be re-thrown by the grid + /// + public bool ThrowException + { + get { return (_ThrowException); } + set { _ThrowException = value; } + } + + /// + /// Gets the value that caused the Exception + /// + public object Value + { + get { return (_Value); } + set { _Value = value; } + } + + #endregion + } + + #endregion + + #region GridDataFilteringStartEventArgs + + /// + /// GridDataFilteringStartEventArgs + /// + public class GridDataFilteringStartEventArgs : GridCancelEventArgs + { + /// + /// GridDataFilteringStartEventArgs + /// + ///Associated GridPanel + public GridDataFilteringStartEventArgs(GridPanel gridPanel) + : base(gridPanel) + { + } + } + + #endregion + + #region GridDataFilteringCompleteEventArgs + + /// + /// GridDataFilteringCompleteEventArgs + /// + public class GridDataFilteringCompleteEventArgs : GridEventArgs + { + /// + /// GridDataFilteringCompleteEventArgs + /// + /// + public GridDataFilteringCompleteEventArgs(GridPanel gridPanel) + : base(gridPanel) + { + } + } + + #endregion + + #region GridFilterBeginEditEventArgs + + /// + /// GridFilterBeginEditEventArgs + /// + public class GridFilterBeginEditEventArgs : GridFilterEventArgs + { + #region Private variables + + private bool _Cancel; + private FilterPanel _FilterPanel; + + #endregion + + /// + /// GridFilterBeginEditEventArgs + /// + /// + /// + /// + public GridFilterBeginEditEventArgs( + GridPanel gridPanel, GridColumn gridColumn, FilterPanel filterPanel) + : base(gridPanel, gridColumn) + { + _FilterPanel = filterPanel; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated FilterPanel + /// + public FilterPanel FilterPanel + { + get { return (_FilterPanel); } + } + + #endregion + } + + #endregion + + #region GridFilterCancelEditEventArgs + + /// + /// GridFilterCancelEditEventArgs + /// + public class GridFilterCancelEditEventArgs : GridFilterEventArgs + { + #region Private variables + + private FilterPanel _FilterPanel; + + #endregion + + /// + /// GridFilterCancelEditEventArgs + /// + /// + /// + /// + public GridFilterCancelEditEventArgs( + GridPanel gridPanel, GridColumn gridColumn, FilterPanel filterPanel) + : base(gridPanel, gridColumn) + { + _FilterPanel = filterPanel; + } + + #region Public properties + + /// + /// Gets the associated FilterPanel + /// + public FilterPanel FilterPanel + { + get { return (_FilterPanel); } + } + + #endregion + } + + #endregion + + #region GridFilterColumnErrorEventArgs + + /// + /// GridFilterColumnErrorEventArgs + /// + public class GridFilterColumnErrorEventArgs : GridFilterRowErrorEventArgs + { + #region Private variables + + private GridColumn _GridColumn; + + #endregion + + /// + /// GridFilterColumnErrorEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridFilterColumnErrorEventArgs(GridPanel gridPanel, GridRow gridRow, + GridColumn gridColumn, Exception exp, bool filteredOut, bool throwException, bool postError) + : base(gridPanel, gridRow, exp, filteredOut, throwException, postError) + { + _GridColumn = gridColumn; + } + + #region Public properties + + /// + /// Gets the associated GridColumn + /// + public GridColumn GridColumn + { + get { return (_GridColumn); } + } + + #endregion + } + + #endregion + + #region GridFilterEditValueChangedEventArgs + + /// + /// GridFilterEditValueChangedEventArgs + /// + public class GridFilterEditValueChangedEventArgs : GridFilterEventArgs + { + #region Private variables + + private object _OldValue; + + private object _NewValue; + private object _NewDisplayValue; + private string _NewExpr; + + private FilterPanel _FilterPanel; + + private bool _Cancel; + + #endregion + + /// + /// + /// + /// + /// + /// + /// + /// + /// + public GridFilterEditValueChangedEventArgs(GridPanel gridPanel, GridColumn gridColumn, + FilterPanel fp, object oldValue, object newValue, object newDisplayValue, string newExpr) + : base(gridPanel, gridColumn) + { + _FilterPanel = fp; + + _OldValue = oldValue; + + _NewValue = newValue; + _NewDisplayValue = newDisplayValue; + _NewExpr = newExpr; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated FilterPanel + /// + public FilterPanel FilterPanel + { + get { return (_FilterPanel); } + } + + /// + /// Gets the old filter value + /// + public object OldValue + { + get { return (_OldValue); } + } + + /// + /// Gets or sets the new filter value + /// + public object NewValue + { + get { return (_NewValue); } + set { _NewValue = value; } + } + + /// + /// Gets or sets the new filter display value + /// + public object NewDisplayValue + { + get { return (_NewDisplayValue); } + set { _NewDisplayValue = value; } + } + + /// + /// Gets or sets the new filter expression + /// + public string NewExpr + { + get { return (_NewExpr); } + set { _NewExpr = value; } + } + + #endregion + } + + #endregion + + #region GridFilterEndEditEventArgs + + /// + /// GridFilterEndEditEventArgs + /// + public class GridFilterEndEditEventArgs : GridFilterEventArgs + { + #region Private variables + + private FilterPanel _FilterPanel; + + #endregion + + /// + /// GridFilterEndEditEventArgs + /// + /// + /// + /// + public GridFilterEndEditEventArgs( + GridPanel gridPanel, GridColumn gridColumn, FilterPanel filterPanel) + : base(gridPanel, gridColumn) + { + _FilterPanel = filterPanel; + } + + #region Public properties + + /// + /// Gets the associated FilterPanel + /// + public FilterPanel FilterPanel + { + get { return (_FilterPanel); } + } + + #endregion + + } + + #endregion + + #region GridFilterEventArgs + + /// + /// GridFilterEventArgs + /// + public class GridFilterEventArgs : GridColumnEventArgs + { + /// + /// GridFilterEventArgs + /// + /// + /// + public GridFilterEventArgs(GridPanel gridPanel, GridColumn gridColumn) + : base(gridPanel, gridColumn) + { + } + } + + #endregion + + #region GridFilterHeaderClickEventArgs + + /// + /// GridFilterHeaderClickEventArgs + /// + public class GridFilterHeaderClickEventArgs : GridColumnEventArgs + { + #region Private variables + + private bool _Cancel; + private MouseEventArgs _MouseEventArgs; + + #endregion + + /// + /// GridFilterHeaderClickEventArgs + /// + /// + /// + /// + public GridFilterHeaderClickEventArgs( + GridPanel gridPanel, GridColumn gridColumn, MouseEventArgs e) + : base(gridPanel, gridColumn) + { + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + #endregion + } + + #endregion + + #region GridFilterHelpClosingEventArgs + + /// + /// GridFilterHelpClosingEventArgs + /// + public class GridFilterHelpClosingEventArgs : GridFilterEventArgs + { + #region Private variables + + private SampleExpr _SampleExpr; + + #endregion + + /// + /// GridFilterHelpClosingEventArgs + /// + /// + /// + /// + public GridFilterHelpClosingEventArgs( + GridPanel gridPanel, GridColumn gridColumn, SampleExpr sampleExpr) + : base(gridPanel, gridColumn) + { + _SampleExpr = sampleExpr; + } + + #region Public properties + + /// + /// Gets the associated Sample Expression help window + /// + public SampleExpr SampleExpr + { + get { return (_SampleExpr); } + } + + #endregion + } + + #endregion + + #region GridFilterHelpOpeningEventArgs + + /// + /// GridFilterHelpOpeningEventArgs + /// + public class GridFilterHelpOpeningEventArgs : GridFilterEventArgs + { + #region Private variables + + private bool _Cancel; + private SampleExpr _SampleExpr; + + #endregion + + /// + /// GridFilterHelpOpeningEventArgs + /// + /// + /// + /// + public GridFilterHelpOpeningEventArgs( + GridPanel gridPanel, GridColumn gridColumn, SampleExpr sampleExpr) + : base(gridPanel, gridColumn) + { + _SampleExpr = sampleExpr; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated Sample Expression help window + /// + public SampleExpr SampleExpr + { + get { return (_SampleExpr); } + } + + #endregion + } + + #endregion + + #region GridFilterItemsLoadedEventArgs + + /// + /// GridFilterItemsLoadedEventArgs + /// + public class GridFilterItemsLoadedEventArgs : GridFilterEventArgs + { + #region Private variables + + private ComboBoxEx _ComboBox; + + #endregion + + /// + /// GridFilterItemsLoadedEventArgs + /// + /// + /// + /// + public GridFilterItemsLoadedEventArgs( + GridPanel gridPanel, GridColumn gridColumn, ComboBoxEx comboBox) + : base(gridPanel, gridColumn) + { + _ComboBox = comboBox; + } + + #region Public properties + + /// + /// Gets the associated ComboBoxEx + /// + public ComboBoxEx ComboBox + { + get { return (_ComboBox); } + } + + #endregion + } + + #endregion + + #region GridFilterLoadItemsEventArgs + + /// + /// GridFilterLoadItemsEventArgs + /// + public class GridFilterLoadItemsEventArgs : GridFilterEventArgs + { + #region Private variables + + private bool _Cancel; + private ComboBoxEx _ComboBox; + + #endregion + + /// + /// GridFilterBeginEditEventArgs + /// + /// + /// + /// + public GridFilterLoadItemsEventArgs( + GridPanel gridPanel, GridColumn gridColumn, ComboBoxEx comboBox) + : base(gridPanel, gridColumn) + { + _ComboBox = comboBox; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated ComboBoxEx + /// + public ComboBoxEx ComboBox + { + get { return (_ComboBox); } + } + + #endregion + + } + + #endregion + + #region GridFilterLoadUserDataEventArgs + + /// + /// GridFilterLoadUserDataEventArgs + /// + public class GridFilterLoadUserDataEventArgs : GridCancelEventArgs + { + #region Private variables + + private string _FilterPath; + private List _FilterData; + + #endregion + + /// + /// GridFilterLoadUserDataEventArgs + /// + /// + /// + /// + public GridFilterLoadUserDataEventArgs( + GridPanel gridPanel, string filterPath, List filterData) + : base(gridPanel) + { + _FilterPath = filterPath; + _FilterData = filterData; + } + + #region Public properties + + /// + /// Gets or sets the associated FilterData (user defined + /// Custom filter expressions) + /// + public List FilterData + { + get { return (_FilterData); } + set { _FilterData = value; } + } + + /// + /// Gets or sets the associated Path to + /// the user defined filter data expression file + /// + public string FilterPath + { + get { return (_FilterPath); } + set { _FilterPath = value; } + } + + #endregion + } + + #endregion + + #region GridFilterPopupClosingEventArgs + + /// + /// GridFilterPopupClosingEventArgs + /// + public class GridFilterPopupClosingEventArgs : GridFilterEventArgs + { + #region Private variables + + private FilterPopup _FilterPopup; + + #endregion + + /// + /// GridFilterPopupClosingEventArgs + /// + /// + /// + /// + public GridFilterPopupClosingEventArgs( + GridPanel gridPanel, GridColumn gridColumn, FilterPopup filterPopup) + : base(gridPanel, gridColumn) + { + _FilterPopup = filterPopup; + } + + #region Public properties + + /// + /// Gets the associated filter popup + /// + public FilterPopup FilterPopup + { + get { return (_FilterPopup); } + } + + #endregion + } + + #endregion + + #region GridFilterPopupLoadEventArgs + + /// + /// GridFilterPopupLoadEventArgs + /// + public class GridFilterPopupLoadEventArgs : GridFilterEventArgs + { + #region Private variables + + private bool _Cancel; + + private FilterPopup _FilterPopup; + + #endregion + + /// + /// GridFilterPopupLoadEventArgs + /// + /// + /// + /// + public GridFilterPopupLoadEventArgs( + GridPanel gridPanel, GridColumn gridColumn, FilterPopup filterPopup) + : base(gridPanel, gridColumn) + { + _FilterPopup = filterPopup; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated filter popup + /// + public FilterPopup FilterPopup + { + get { return (_FilterPopup); } + } + + #endregion + } + + #endregion + + #region GridFilterPopupLoadedEventArgs + + /// + /// GridFilterPopupLoadedEventArgs + /// + public class GridFilterPopupLoadedEventArgs : GridFilterEventArgs + { + #region Private variables + + private FilterPopup _FilterPopup; + + #endregion + + /// + /// GridFilterPopupLoadedEventArgs + /// + /// + /// + /// + public GridFilterPopupLoadedEventArgs( + GridPanel gridPanel, GridColumn gridColumn, FilterPopup filterPopup) + : base(gridPanel, gridColumn) + { + _FilterPopup = filterPopup; + } + + #region Public properties + + /// + /// Gets the associated filter popup + /// + public FilterPopup FilterPopup + { + get { return (_FilterPopup); } + } + + #endregion + } + + #endregion + + #region GridFilterPopupOpeningEventArgs + + /// + /// GridFilterPopupOpeningEventArgs + /// + public class GridFilterPopupOpeningEventArgs : GridFilterEventArgs + { + #region Private variables + + private bool _Cancel; + + private FilterPopup _FilterPopup; + + #endregion + + /// + /// GridFilterPopupOpeningEventArgs + /// + /// + /// + /// + public GridFilterPopupOpeningEventArgs( + GridPanel gridPanel, GridColumn gridColumn, FilterPopup filterPopup) + : base(gridPanel, gridColumn) + { + _FilterPopup = filterPopup; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated filter popup + /// + public FilterPopup FilterPopup + { + get { return (_FilterPopup); } + } + + #endregion + } + + #endregion + + #region GridFilterPopupValueChangedEventArgs + + /// + /// GridFilterPopupValueChangedEventArgs + /// + public class GridFilterPopupValueChangedEventArgs : GridFilterEventArgs + { + #region Private variables + + private object _FilterValue; + private object _FilterDisplayValue; + private string _FilterExpr; + + private FilterItemType _FilterItemType; + + private bool _Cancel; + + #endregion + + /// + /// + /// + /// + /// + /// + /// + /// + public GridFilterPopupValueChangedEventArgs(GridPanel gridPanel, GridColumn gridColumn, + FilterItemType filterItemType, object filterValue, object filterDisplayValue, string filterExpr) + : base(gridPanel, gridColumn) + { + _FilterItemType = filterItemType; + _FilterValue = filterValue; + _FilterDisplayValue = filterDisplayValue; + _FilterExpr = filterExpr; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets or sets the new filter value + /// + public object FilterValue + { + get { return (_FilterValue); } + set { _FilterValue = value; } + } + + /// + /// Gets or sets the new filter display value + /// + public object FilterDisplayValue + { + get { return (_FilterDisplayValue); } + set { _FilterDisplayValue = value; } + } + + /// + /// Gets or sets the new filter expression + /// + public string FilterExpr + { + get { return (_FilterExpr); } + set { _FilterExpr = value; } + } + + /// + /// Gets the filter popup item selected + /// + public FilterItemType FilterItemType + { + get { return (_FilterItemType); } + } + + #endregion + } + + #endregion + + #region GridFilterRowErrorEventArgs + + /// + /// GridFilterRowErrorEventArgs + /// + public class GridFilterRowErrorEventArgs : GridRowEventArgs + { + #region Private variables + + private bool _Cancel; + + private bool _FilteredOut; + private bool _ThrowException; + private bool _PostError; + + private Exception _Exception; + + #endregion + + /// + /// GridFilterRowErrorEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridFilterRowErrorEventArgs(GridPanel gridPanel, + GridRow gridRow, Exception exp, bool filteredOut, bool throwException, bool postError) + : base(gridPanel, gridRow) + { + _Exception = exp; + _FilteredOut = filteredOut; + _ThrowException = throwException; + _PostError = postError; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated filter Exception + /// + public Exception Exception + { + get { return (_Exception); } + } + + /// + /// Gets or sets whether the row is filtered out + /// + public bool FilteredOut + { + get { return (_FilteredOut); } + set { _FilteredOut = value; } + } + + /// + /// Gets or sets whether to re-throw the exception + /// + public bool ThrowException + { + get { return (_ThrowException); } + set { _ThrowException = value; } + } + + /// + /// Gets or sets whether to post/display the error to the user + /// + public bool PostError + { + get { return (_PostError); } + set { _PostError = value; } + } + + #endregion + } + + #endregion + + #region GridFilterStoreUserDataEventArgs + + /// + /// GridFilterStoreUserDataEventArgs + /// + public class GridFilterStoreUserDataEventArgs : GridCancelEventArgs + { + #region Private variables + + private string _FilterPath; + private List _FilterData; + + #endregion + + /// + /// GridFilterStoreUserDataEventArgs + /// + /// + /// + /// + public GridFilterStoreUserDataEventArgs( + GridPanel gridPanel, string filterPath, List filterData) + : base(gridPanel) + { + _FilterPath = filterPath; + _FilterData = filterData; + } + + #region Public properties + + /// + /// Gets or sets the associated FilterData (user defined + /// Custom filter expressions) + /// + public List FilterData + { + get { return (_FilterData); } + set { _FilterData = value; } + } + + /// + /// Gets or sets the associated Path to + /// the user defined filter data expression file + /// + public string FilterPath + { + get { return (_FilterPath); } + set { _FilterPath = value; } + } + + #endregion + } + + #endregion + + #region GridFilterUserFunctionEventArgs + + /// + /// GridFilterUserFunctionEventArgs + /// + public class GridFilterUserFunctionEventArgs : GridRowEventArgs + { + #region Private variables + + private object[] _Args; + private object _Result; + + private bool _Handled; + + #endregion + + /// + /// GridFilterUserFunctionEventArgs + /// + /// + /// + /// + /// + public GridFilterUserFunctionEventArgs( + GridPanel gridPanel, GridRow gridRow, object[] args, object result) + : base(gridPanel, gridRow) + { + _Args = args; + _Result = result; + } + + #region Public properties + + /// + /// Gets or sets the associated function arguments + /// + public object[] Args + { + get { return (_Args); } + set { _Args = value; } + } + + /// + /// Gets or sets whether the function was handled + /// + public bool Handled + { + get { return (_Handled); } + set { _Handled = value; } + } + + /// + /// Gets or sets the associated function result + /// + public object Result + { + get { return (_Result); } + set { _Result = value; } + } + + #endregion + } + + #endregion + + #region GridGetGroupDetailRowsEventArgs + + /// + /// GridGetGroupDetailRowsEventArgs + /// + public class GridGetGroupDetailRowsEventArgs : GridColumnEventArgs + { + #region Private variables + + private GridGroup _GridGroup; + private List _PreDetailRows; + private List _PostDetailRows; + + #endregion + + /// + /// GridGetGroupDetailRowsEventArgs + /// + /// + /// + /// + public GridGetGroupDetailRowsEventArgs( + GridPanel gridPanel, GridColumn gridColumn, GridGroup gridGroup) + : base(gridPanel, gridColumn) + { + _GridGroup = gridGroup; + } + + #region Public properties + + /// + /// Gets or sets the list of Post grouping DetailRows + /// + [Obsolete] + public List DetailRows + { + get { return (_PostDetailRows); } + set { _PostDetailRows = value; } + } + + /// + /// Gets or sets the list of Post grouping DetailRows + /// + public List PostDetailRows + { + get { return (_PostDetailRows); } + set { _PostDetailRows = value; } + } + + /// + /// Gets or sets the list of Pre grouping DetailRows + /// + public List PreDetailRows + { + get { return (_PreDetailRows); } + set { _PreDetailRows = value; } + } + + /// + /// Gets the associated GridGroup + /// + public GridGroup GridGroup + { + get { return (_GridGroup); } + } + + #endregion + } + + #endregion + + #region GridItemDragEventArgs + + /// + /// GridItemDragEventArgs + /// + public class GridItemDragEventArgs : ItemDragEventArgs + { + #region Private variables + + private GridPanel _GridPanel; + private bool _Cancel; + + #endregion + + /// + /// GridDragStartedEventArgs + /// + /// + /// + /// + public GridItemDragEventArgs(GridPanel gridPanel, GridElement item, MouseEventArgs e) + : base(e.Button, item) + { + _GridPanel = gridPanel; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + #endregion + } + + #endregion + + #region GridGetCellFormattedValueEventArgs + + /// + /// GridGetCellFormattedValueEventArgs + /// + public class GridGetCellFormattedValueEventArgs : GridCellEventArgs + { + #region Private variables + + private string _FormattedValue; + private CellSizingSource _SizingSource; + + #endregion + + /// + /// GridGetCellFormattedValueEventArgs + /// + /// + /// + /// + public GridGetCellFormattedValueEventArgs( + GridPanel gridPanel, GridCell gridCell, string formattedValue, CellSizingSource sizingSource) + : base(gridPanel, gridCell) + { + _FormattedValue = formattedValue; + _SizingSource = sizingSource; + } + + #region Public properties + + /// + /// Gets or sets the associated FormattedValue + /// + public string FormattedValue + { + get { return (_FormattedValue); } + set { _FormattedValue = value; } + } + + /// + /// Gets or sets the associated cell SizingSource + /// + public CellSizingSource SizingSource + { + get { return (_SizingSource); } + set { _SizingSource = value; } + } + + #endregion + } + + #endregion + + #region GridGetCellRangeFormattedValueEventArgs + + /// + /// GridGetCellRangeFormattedValueEventArgs + /// + public class GridGetCellRangeFormattedValueEventArgs : GridRowEventArgs + { + #region Private variables + + private CellRange _CellRange; + private string _FormattedValue; + + #endregion + + /// + /// GridGetCellRangeFormattedValueEventArgs + /// + /// + /// + /// + /// + public GridGetCellRangeFormattedValueEventArgs(GridPanel gridPanel, + GridContainer gridContainer, CellRange cellRange, string formattedValue) + : base(gridPanel, gridContainer) + { + _CellRange = cellRange; + _FormattedValue = formattedValue; + } + + #region Public properties + + /// + /// Gets the associated CellRange + /// + public CellRange CellRange + { + get { return (_CellRange); } + set { _CellRange = value; } + } + + /// + /// Gets or sets the associated FormattedValue + /// + public string FormattedValue + { + get { return (_FormattedValue); } + set { _FormattedValue = value; } + } + + #endregion + } + + #endregion + + #region GridGetCellRangesEventArgs + + /// + /// GridGetCellRangesEventArgs + /// + public class GridGetCellRangesEventArgs : GridEventArgs + { + #region Private variables + + private bool _Cancel; + + private List _CellRanges; + private DisplayRange _DisplayRange; + private GridContainer _GridContainer; + + #endregion + + /// + /// GridGetCellRangesEventArgs + /// + ///Associated GridPanel + ///Associated GridContainer + ///Row/col range being merge evaluated + ///List of CellRanges + public GridGetCellRangesEventArgs(GridPanel gridPanel, + GridContainer gridContainer, DisplayRange displayRange, List cellRanges) + : base(gridPanel) + { + _GridContainer = gridContainer; + _DisplayRange = displayRange; + _CellRanges = cellRanges; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the default operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets or sets the CellRanges + /// + public List CellRanges + { + get { return (_CellRanges); } + set { _CellRanges = value; } + } + + /// + /// Gets the current DisplayRange (row/col range + /// being processed / merged evaluated) + /// + public DisplayRange DisplayRange + { + get { return (_DisplayRange); } + } + + /// + /// Gets the associated GridContainer + /// + public GridContainer GridContainer + { + get { return (_GridContainer); } + } + + #endregion + } + + #endregion + + #region GridGetCellStyleEventArgs + + /// + /// GridGetCellStyleEventArgs + /// + public class GridGetCellStyleEventArgs : GridCellEventArgs + { + #region Private variables + + private StyleType _StyleType; + private CellVisualStyle _Style; + + #endregion + + /// + /// GridGetCellStyleEventArgs + /// + /// + /// + /// + /// + public GridGetCellStyleEventArgs( + GridPanel gridPanel, GridCell gridCell, StyleType styleType, CellVisualStyle style) + : base(gridPanel, gridCell) + { + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public CellVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot be null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetCellToolTipEventArgs + + /// + /// GridGetCellToolTipEventArgs + /// + public class GridGetCellToolTipEventArgs : GridCellEventArgs + { + #region Private variables + + private string _ToolTip; + private bool _Cancel; + + #endregion + + /// + /// GridGetCellToolTipEventArgs + /// + /// + /// + /// + public GridGetCellToolTipEventArgs( + GridPanel gridPanel, GridCell gridCell, string toolTip) + : base(gridPanel, gridCell) + { + _ToolTip = toolTip; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets or sets the associated ToolTip text + /// + public string ToolTip + { + get { return (_ToolTip); } + set { _ToolTip = value; } + } + + #endregion + } + + #endregion + + #region GridGetCellValueEventArgs + + /// + /// GridGetCellValueEventArgs + /// + public class GridGetCellValueEventArgs : GridCellEventArgs + { + #region Private variables + + private object _Value; + + #endregion + + /// + /// GridGetCellValueEventArgs + /// + /// + /// + /// + public GridGetCellValueEventArgs( + GridPanel gridPanel, GridCell gridCell, object value) + : base(gridPanel, gridCell) + { + _Value = value; + } + + #region Public properties + + /// + /// Gets or sets the associated Value + /// + public object Value + { + get { return (_Value); } + set { _Value = value; } + } + + #endregion + } + + #endregion + + #region GridGetColumnGroupHeaderStyleEventArgs + + /// + /// GridGetColumnGroupHeaderStyleEventArgs + /// + public class GridGetColumnGroupHeaderStyleEventArgs : GridEventArgs + { + #region Private variables + + private StyleType _StyleType; + private ColumnHeaderVisualStyle _Style; + private ColumnGroupHeader _GroupHeader; + + #endregion + + /// + /// GridGetColumnGroupHeaderStyleEventArgs + /// + /// + /// + /// + /// + public GridGetColumnGroupHeaderStyleEventArgs(GridPanel gridPanel, + ColumnGroupHeader groupHeader, StyleType styleType, ColumnHeaderVisualStyle style) + : base(gridPanel) + { + _GroupHeader = groupHeader; + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public ColumnHeaderVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + /// + /// Gets the associated ColumnGroupHeader + /// + public ColumnGroupHeader GroupHeader + { + get { return (_GroupHeader); } + } + + #endregion + } + + #endregion + + #region GridGetColumnHeaderRowHeaderStyleEventArgs + + /// + /// GridGetColumnHeaderRowHeaderStyleEventArgs + /// + public class GridGetColumnHeaderRowHeaderStyleEventArgs : GridEventArgs + { + #region Private variables + + private StyleType _StyleType; + private GridColumnHeader _ColumnHeader; + private ColumnHeaderRowVisualStyle _Style; + + #endregion + + /// + /// GridGetColumnHeaderRowHeaderStyleEventArgs + /// + /// + /// + /// + /// + public GridGetColumnHeaderRowHeaderStyleEventArgs(GridPanel gridPanel, + GridColumnHeader columnHeader, StyleType styleType, ColumnHeaderRowVisualStyle style) + : base(gridPanel) + { + _ColumnHeader = columnHeader; + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated ColumnHeader + /// + public GridColumnHeader ColumnHeader + { + get { return (_ColumnHeader); } + } + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public ColumnHeaderRowVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetColumnHeaderStyleEventArgs + + /// + /// GridGetColumnHeaderStyleEventArgs + /// + public class GridGetColumnHeaderStyleEventArgs : GridColumnEventArgs + { + #region Private variables + + private StyleType _StyleType; + private ColumnHeaderVisualStyle _Style; + + #endregion + + /// + /// GridGetColumnHeaderStyleEventArgs + /// + /// + /// + /// + /// + public GridGetColumnHeaderStyleEventArgs( + GridPanel gridPanel, GridColumn gridColumn, StyleType styleType, ColumnHeaderVisualStyle style) + : base(gridPanel, gridColumn) + { + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public ColumnHeaderVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetColumnGroupHeaderToolTipEventArgs + + /// + /// GridGetColumnGroupHeaderToolTipEventArgs + /// + public class GridGetColumnGroupHeaderToolTipEventArgs : GridEventArgs + { + #region Private variables + + private string _ToolTip; + private HeaderArea _HitArea; + private ColumnGroupHeader _GroupHeader; + + private bool _Cancel; + + #endregion + + /// + /// GridGetColumnGroupHeaderToolTipEventArgs + /// + /// + /// + /// + /// + public GridGetColumnGroupHeaderToolTipEventArgs( + GridPanel gridPanel, ColumnGroupHeader groupHeader, HeaderArea hitArea, string toolTip) + : base(gridPanel) + { + _GroupHeader = groupHeader; + + _HitArea = hitArea; + _ToolTip = toolTip; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated ColumnGroupHeader + /// + public ColumnGroupHeader GroupHeader + { + get { return (_GroupHeader); } + } + + /// + /// Gets the associated Header hit area + /// + public HeaderArea HitArea + { + get { return (_HitArea); } + } + + /// + /// Gets or sets the associated ToolTip text + /// + public string ToolTip + { + get { return (_ToolTip); } + set { _ToolTip = value; } + } + + #endregion + } + + #endregion + + #region GridGetColumnHeaderToolTipEventArgs + + /// + /// GridGetColumnHeaderToolTipEventArgs + /// + public class GridGetColumnHeaderToolTipEventArgs : GridColumnEventArgs + { + #region Private variables + + private string _ToolTip; + private HeaderArea _HitArea; + + private bool _Cancel; + + #endregion + + /// + /// GridGetColumnHeaderToolTipEventArgs + /// + /// + /// + /// + /// + public GridGetColumnHeaderToolTipEventArgs( + GridPanel gridPanel, GridColumn gridColumn, HeaderArea hitArea, string toolTip) + : base(gridPanel, gridColumn) + { + _HitArea = hitArea; + _ToolTip = toolTip; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated Header hit area + /// + public HeaderArea HitArea + { + get { return (_HitArea); } + } + + /// + /// Gets or sets the associated ToolTip text + /// + public string ToolTip + { + get { return (_ToolTip); } + set { _ToolTip = value; } + } + + #endregion + } + + #endregion + + #region GridGetDisplayRangesEventArgs + + /// + /// GridGetDisplayRangesEventArgs + /// + public class GridGetDisplayRangesEventArgs : GridEventArgs + { + #region Private variables + + private List _DisplayRanges; + private GridContainer _GridContainer; + + #endregion + + /// + /// GridGetDisplayRangesEventArgs + /// + ///Associated GridPanel + ///Associated GridContainer + ///List of Row/col ranges to be merge evaluated + public GridGetDisplayRangesEventArgs(GridPanel gridPanel, + GridContainer gridContainer, List displayRanges) + : base(gridPanel) + { + _GridContainer = gridContainer; + _DisplayRanges = displayRanges; + } + + #region Public properties + + /// + /// Gets or sets the DisplayRanges + /// + public List DisplayRanges + { + get { return (_DisplayRanges); } + set { _DisplayRanges = value; } + } + + /// + /// Gets the associated GridContainer + /// + public GridContainer GridContainer + { + get { return (_GridContainer); } + } + + #endregion + } + + #endregion + + #region GridGetFilterRowStyleEventArgs + + /// + /// GridGetFilterRowStyleEventArgs + /// + public class GridGetFilterRowStyleEventArgs : GridEventArgs + { + #region Private variables + + private StyleType _StyleType; + private GridFilter _GridFilter; + private FilterRowVisualStyle _Style; + + #endregion + + /// + /// GridGetFilterRowStyleEventArgs + /// + /// + /// + /// + /// + public GridGetFilterRowStyleEventArgs(GridPanel gridPanel, + GridFilter gridFilter, StyleType styleType, FilterRowVisualStyle style) + : base(gridPanel) + { + _GridFilter = gridFilter; + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated GridFilter + /// + public GridFilter GridFilter + { + get { return (_GridFilter); } + } + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public FilterRowVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetFilterColumnHeaderStyleEventArgs + + /// + /// GridGetFilterColumnHeaderStyleEventArgs + /// + public class GridGetFilterColumnHeaderStyleEventArgs : GridColumnEventArgs + { + #region Private variables + + private StyleType _StyleType; + private FilterColumnHeaderVisualStyle _Style; + + #endregion + + /// + /// GridGetFilterColumnHeaderStyleEventArgs + /// + /// + /// + /// + /// + public GridGetFilterColumnHeaderStyleEventArgs(GridPanel gridPanel, + GridColumn gridColumn, StyleType styleType, FilterColumnHeaderVisualStyle style) + : base(gridPanel, gridColumn) + { + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public FilterColumnHeaderVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridConfigureGroupBoxEventArgs + + /// + /// GridConfigureGroupBoxEventArgs + /// + public class GridConfigureGroupBoxEventArgs : GridEventArgs + { + #region Private variables + + private GridGroupByRow _GroupByRow; + private GridGroupBox _GridGroupBox; + + #endregion + + /// + /// GridConfigureGroupBoxEventArgs + /// + /// + /// + /// + public GridConfigureGroupBoxEventArgs(GridPanel gridPanel, + GridGroupByRow groupByRow, GridGroupBox gridGroupBox) + : base(gridPanel) + { + _GroupByRow = groupByRow; + _GridGroupBox = gridGroupBox; + } + + #region Public properties + + /// + /// Gets the associated GroupByRow + /// + public GridGroupByRow GroupByRow + { + get { return (_GroupByRow); } + } + + /// + /// Gets the associated GridColumn + /// + public GridGroupBox GridGroupBox + { + get { return (_GridGroupBox); } + } + + #endregion + } + + #endregion + + #region GridGetGroupHeaderStyleEventArgs + + /// + /// GridGetGroupHeaderStyleEventArgs + /// + public class GridGetGroupHeaderStyleEventArgs : GridEventArgs + { + #region Private variables + + private GridGroup _GridRow; + private StyleType _StyleType; + + private GroupHeaderVisualStyle _Style; + + #endregion + + /// + /// GridGetGroupHeaderStyleEventArgs + /// + /// + /// + /// + /// + public GridGetGroupHeaderStyleEventArgs( + GridPanel gridPanel, GridGroup gridRow, StyleType styleType, GroupHeaderVisualStyle style) + : base(gridPanel) + { + _GridRow = gridRow; + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets the associated Group Header Row + /// + public GridGroup GridRow + { + get { return (_GridRow); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public GroupHeaderVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetMergedCellStyleEventArgs + + /// + /// GridGetMergedCellStyleEventArgs + /// + public class GridGetMergedCellStyleEventArgs : GridEventArgs + { + #region Private variables + + private CellRange _CellRange; + private StyleType _StyleType; + private CellVisualStyle _Style; + + #endregion + + /// + /// GridGetMergedCellStyleEventArgs + /// + /// + /// + /// + /// + public GridGetMergedCellStyleEventArgs( + GridPanel gridPanel, CellRange cellRange, StyleType styleType, CellVisualStyle style) + : base(gridPanel) + { + _CellRange = cellRange; + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated CellRange + /// + public CellRange CellRange + { + get { return (_CellRange); } + } + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public CellVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetPanelStyleEventArgs + + /// + /// GridGetPanelStyleEventArgs + /// + public class GridGetPanelStyleEventArgs : GridEventArgs + { + #region Private variables + + private GridPanelVisualStyle _Style; + + #endregion + + /// + /// GridGetPanelStyleEventArgs + /// + /// + /// + public GridGetPanelStyleEventArgs(GridPanel gridPanel, GridPanelVisualStyle style) + : base(gridPanel) + { + _Style = style; + } + + #region Public properties + + /// + /// Gets or sets the associated VisualStyle + /// + public GridPanelVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetRowCellStyleEventArgs + + /// + /// GridGetRowCellStyleEventArgs + /// + public class GridGetRowCellStyleEventArgs : GridRowEventArgs + { + #region Private variables + + private StyleType _StyleType; + private CellVisualStyle _Style; + + #endregion + + /// + /// GridGetRowCellStyleEventArgs + /// + /// + /// + /// + /// + public GridGetRowCellStyleEventArgs( + GridPanel gridPanel, GridContainer gridRow, StyleType styleType, CellVisualStyle style) + : base(gridPanel, gridRow) + { + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public CellVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetRowHeaderStyleEventArgs + + /// + /// GridGetRowHeaderStyleEventArgs + /// + public class GridGetRowHeaderStyleEventArgs : GridRowEventArgs + { + #region Private variables + + private StyleType _StyleType; + private RowHeaderVisualStyle _Style; + + #endregion + + /// + /// GridGetRowHeaderStyleEventArgs + /// + /// + /// + /// + /// + public GridGetRowHeaderStyleEventArgs( + GridPanel gridPanel, GridContainer row, StyleType styleType, RowHeaderVisualStyle style) + : base(gridPanel, row) + { + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public RowHeaderVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetRowHeaderTextEventArgs + + /// + /// GridGetRowHeaderTextEventArgs + /// + public class GridGetRowHeaderTextEventArgs : GridRowEventArgs + { + #region Private variables + + private string _Text; + + #endregion + + /// + /// GridGetRowHeaderTextEventArgs + /// + ///Associated GridPanel + ///Associated container row + ///Text to display in row header + public GridGetRowHeaderTextEventArgs( + GridPanel gridPanel, GridContainer row, string text) + : base(gridPanel, row) + { + _Text = text; + } + + #region Public properties + + /// + /// Gets or sets the associated header text + /// + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + } + + #endregion + + #region GridGetRowStyleEventArgs + + /// + /// GridGetRowStyleEventArgs + /// + public class GridGetRowStyleEventArgs : GridRowEventArgs + { + #region Private variables + + private StyleType _StyleType; + private RowVisualStyle _Style; + + #endregion + + /// + /// GridGetCellStyleEventArgs + /// + /// + /// + /// + /// + public GridGetRowStyleEventArgs( + GridPanel gridPanel, GridContainer gridRow, StyleType styleType, RowVisualStyle style) + : base(gridPanel, gridRow) + { + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public RowVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + #endregion + } + + #endregion + + #region GridGetTextRowStyleEventArgs + + /// + /// GridGetTextRowStyleEventArgs + /// + public class GridGetTextRowStyleEventArgs : GridEventArgs + { + #region Private variables + + private StyleType _StyleType; + private TextRowVisualStyle _Style; + private readonly GridTextRow _GridTextRow; + + #endregion + + /// + /// GridGetTextRowStyleEventArgs + /// + /// + /// + /// + /// + public GridGetTextRowStyleEventArgs( + GridPanel gridPanel, GridTextRow gridTextRow, StyleType styleType, TextRowVisualStyle style) + : base(gridPanel) + { + _GridTextRow = gridTextRow; + _StyleType = styleType; + _Style = style; + } + + #region Public properties + + /// + /// Gets the associated StyleType + /// + public StyleType StyleType + { + get { return (_StyleType); } + } + + /// + /// Gets or sets the associated VisualStyle + /// + public TextRowVisualStyle Style + { + get { return (_Style); } + + set + { + if (value == null) + throw new Exception("Style cannot by null."); + + _Style = value; + } + } + + /// + /// Gets the associated GridTextRow + /// + public GridTextRow GridTextRow + { + get { return (_GridTextRow); } + } + + #endregion + } + + #endregion + + #region GridEditEventArgs + + /// + /// GridEditEventArgs + /// + public class GridEditEventArgs : CancelEventArgs + { + #region Private variables + + private GridPanel _GridPanel; + private GridCell _GridCell; + private IGridCellEditControl _EditControl; + + #endregion + + /// + /// GridEditEventArgs + /// + public GridEditEventArgs( + GridPanel gridPanel, GridCell gridCell, IGridCellEditControl editControl) + { + _GridPanel = gridPanel; + _GridCell = gridCell; + _EditControl = editControl; + } + + #region Public properties + + /// + /// Gets the associated GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + /// + /// Gets the associated cell + /// + public GridCell GridCell + { + get { return (_GridCell); } + } + + /// + /// Gets the associated cell EditControl + /// + public IGridCellEditControl EditControl + { + get { return (_EditControl); } + } + + #endregion + } + + #endregion + + #region GridEventArgs + + /// + /// GridEventArgs + /// + public class GridEventArgs : EventArgs + { + #region Private variables + + private readonly GridPanel _GridPanel; + + #endregion + + /// + /// GridEventArgs + /// + /// + public GridEventArgs(GridPanel gridPanel) + { + _GridPanel = gridPanel; + } + + #region Public properties + + /// + /// Gets the event Grid + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + #endregion + } + + #endregion + + #region GridCancelEventArgs + + /// + /// GridCancelEventArgs + /// + public class GridCancelEventArgs : GridEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridEventArgs + /// + /// + public GridCancelEventArgs(GridPanel gridPanel) + : base(gridPanel) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridCloseEditEventArgs + + /// + /// GridCloseEditEventArgs + /// + public class GridCloseEditEventArgs : GridCellEventArgs + { + /// + /// GridCloseEditEventArgs + /// + public GridCloseEditEventArgs(GridPanel gridPanel, GridCell gridCell) + : base(gridPanel, gridCell) + { + } + } + + #endregion + + #region GridGetEditorEventArgs + + /// + /// GridGetEditorEventArgs + /// + public class GridGetEditorEventArgs : GridEventArgs + { + #region Private variables + + private readonly GridCell _GridCell; + private Type _EditorType; + private object[] _EditorParams; + + #endregion + + /// + /// GridGetEditorEventArgs + /// + /// + /// + /// + /// + public GridGetEditorEventArgs( + GridPanel gridPanel, GridCell gridCell, Type editorType, object[] editorParams) + : base(gridPanel) + { + _GridCell = gridCell; + _EditorType = editorType; + _EditorParams = editorParams; + } + + #region Public properties + + /// + /// Gets the associated GridCell + /// + public GridCell GridCell + { + get { return (_GridCell); } + } + + /// + /// Gets or sets the associated cell editor Type + /// + public Type EditorType + { + get { return (_EditorType); } + set { _EditorType = value; } + } + + /// + /// Gets or sets the associated cell editor params + /// + public object[] EditorParams + { + get { return (_EditorParams); } + set { _EditorParams = value; } + } + + #endregion + } + + #endregion + + #region GridGetRendererEventArgs + + /// + /// GridGetRendererEventArgs + /// + public class GridGetRendererEventArgs : GridEventArgs + { + #region Private variables + + private readonly GridCell _GridCell; + private Type _RenderType; + private object[] _RenderParams; + + #endregion + + /// + /// GridGetRendererEventArgs + /// + /// + /// + /// + /// + public GridGetRendererEventArgs( + GridPanel gridPanel, GridCell gridCell, Type renderType, object[] renderParams) + : base(gridPanel) + { + _GridCell = gridCell; + _RenderType = renderType; + _RenderParams = renderParams; + } + + #region Public properties + + /// + /// Gets the associated GridCell + /// + public GridCell GridCell + { + get { return (_GridCell); } + } + + /// + /// Gets or sets the associated cell Render Type + /// + public Type RenderType + { + get { return (_RenderType); } + set { _RenderType = value; } + } + + /// + /// Gets or sets the associated cell Render params + /// + public object[] RenderParams + { + get { return (_RenderParams); } + set { _RenderParams = value; } + } + + #endregion + } + + #endregion + + #region GridGetFilterEditTypeEventArgs + + /// + /// GridGetFilterEditTypeEventArgs + /// + public class GridGetFilterEditTypeEventArgs : GridColumnEventArgs + { + #region Private variables + + private FilterEditType _FilterEditType; + + #endregion + + /// + /// GridGetFilterEditTypeEventArgs + /// + /// + /// + /// + public GridGetFilterEditTypeEventArgs( + GridPanel gridPanel, GridColumn gridColumn, FilterEditType filterEditType) + : base(gridPanel, gridColumn) + { + _FilterEditType = filterEditType; + } + + #region Public properties + + /// + /// Gets the associated Filter edit type + /// + public FilterEditType FilterEditType + { + get { return (_FilterEditType); } + set { _FilterEditType = value; } + } + + #endregion + } + + #endregion + + #region GridGroupChangedEventArgs + + /// + /// GridGroupChangedEventArgs + /// + public class GridGroupChangedEventArgs : GridEventArgs + { + #region Private variables + + private GroupChangedAction _Action; + private GridColumn _GridColumn; + + #endregion + + /// + /// GridRowClickEventArgs + /// + /// + /// + /// + public GridGroupChangedEventArgs( + GridPanel gridPanel, GroupChangedAction action, GridColumn column) + : base(gridPanel) + { + _Action = action; + _GridColumn = column; + } + + #region Public properties + + /// + /// Gets the associated GroupChangedAction + /// + public GroupChangedAction Action + { + get { return (_Action); } + } + + /// + /// Gets the associated GridColumn + /// + public GridColumn GridColumn + { + get { return (_GridColumn); } + } + + #endregion + } + + #endregion + + #region GridGroupHeaderClickEventArgs + + /// + /// GridGroupHeaderClickEventArgs + /// + public class GridGroupHeaderClickEventArgs : GridEventArgs + { + #region Private variables + + private GridGroup _GridGroup; + + private bool _Cancel; + private GroupArea _GroupArea; + private MouseEventArgs _MouseEventArgs; + + #endregion + + /// + /// GridRowClickEventArgs + /// + /// + /// + /// + /// + public GridGroupHeaderClickEventArgs( + GridPanel gridPanel, GridGroup gridGroup, GroupArea area, MouseEventArgs e) + : base(gridPanel) + { + _GridGroup = gridGroup; + _GroupArea = area; + + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets the associated GridGroup + /// + public GridGroup GridGroup + { + get { return (_GridGroup); } + } + + /// + /// Gets or sets whether to cancel the default operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + /// + /// Gets the associated GroupArea + /// + public GroupArea GroupArea + { + get { return (_GroupArea); } + } + + #endregion + } + + #endregion + + #region GridGroupHeaderDoubleClickEventArgs + + /// + /// GridGroupHeaderDoubleClickEventArgs + /// + public class GridGroupHeaderDoubleClickEventArgs : GridGroupHeaderClickEventArgs + { + /// + /// GridRowClickEventArgs + /// + /// + /// + /// + /// + public GridGroupHeaderDoubleClickEventArgs( + GridPanel gridPanel, GridGroup gridGroup, GroupArea area, MouseEventArgs e) + : base(gridPanel, gridGroup, area, e) + { + } + } + + #endregion + + #region GridInitEditContextEventArgs + + /// + /// GridInitEditContextEventArgs + /// + public class GridInitEditContextEventArgs : GridCellEventArgs + { + #region Private variables + + private readonly IGridCellEditControl _EditControl; + + #endregion + + /// + /// GridInitEditContextEventArgs + /// + /// + /// + /// + public GridInitEditContextEventArgs(GridPanel gridPanel, + GridCell gridCell, IGridCellEditControl editControl) + : base(gridPanel, gridCell) + { + _EditControl = editControl; + } + + #region Public properties + + /// + /// Gets the associated GridCell + /// + public IGridCellEditControl EditControl + { + get { return (_EditControl); } + } + + #endregion + } + + #endregion + + #region GridNoRowsTextMarkupLinkClickEventArgs + + /// + /// GridNoRowsMarkupLinkClickEventArgs + /// + public class GridNoRowsMarkupLinkClickEventArgs : GridEventArgs + { + #region Private variables + + private string _HRef; + private string _Name; + + #endregion + + /// + /// GridNoRowsMarkupLinkClickEventArgs + /// + /// + /// + /// + public GridNoRowsMarkupLinkClickEventArgs( + GridPanel gridPanel, string name, string href) + : base(gridPanel) + { + _HRef = href; + _Name = name; + } + + #region Public properties + + /// + /// Gets the associated HyperLink HRef + /// + public string HRef + { + get { return (_HRef); } + } + + /// + /// Gets the associated HyperLink Name + /// + public string Name + { + get { return (_Name); } + } + + #endregion + } + + #endregion + + #region GridPlayingSoundEventArgs + + /// + /// GridPlayingSoundEventArgs + /// + public class GridPlayingSoundEventArgs : CancelEventArgs + { + #region Private variables + + private GridPanel _GridPanel; + private object _Item; + private PlaySoundContext _PlaySoundContext; + + #endregion + + /// + /// GridPlayingSoundEventArgs + /// + /// + /// + /// + public GridPlayingSoundEventArgs( + GridPanel panel, object item, PlaySoundContext context) + { + _GridPanel = panel; + _Item = item; + _PlaySoundContext = context; + } + + #region Public properties + + /// + /// Gets the GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + /// + /// Gets the grid "item" (GridCell, GridRow, CellRange, etc) + /// associated with the event. + /// + public object Item + { + get { return (_Item); } + } + + /// + /// Gets the context under which the event is being played. + /// + public PlaySoundContext PlaySoundContext + { + get { return (_PlaySoundContext); } + } + + #endregion + } + + #endregion + + #region GridPostRenderCellEventArgs + + /// + /// GridPostRenderCellEventArgs + /// + public class GridPostRenderCellEventArgs : GridCellEventArgs + { + #region Private variables + + private Rectangle _Bounds; + private Graphics _Graphics; + private RenderParts _RenderParts; + + #endregion + + /// + /// GridPostRenderCellEventArgs + /// + /// + /// + /// + /// + /// + public GridPostRenderCellEventArgs(Graphics graphics, + GridPanel gridPanel, GridCell gridCell, RenderParts parts, Rectangle bounds) + : base(gridPanel, gridCell) + { + _Bounds = bounds; + _Graphics = graphics; + _RenderParts = parts; + } + + #region Public properties + + /// + /// Gets the cell bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the cell parts to render + /// + public RenderParts RenderParts + { + get { return (_RenderParts); } + } + + #endregion + } + + #endregion + + #region GridPreRenderCellEventArgs + + /// + /// GridPreRenderCellEventArgs + /// + public class GridPreRenderCellEventArgs : GridPostRenderCellEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridPreRenderCellEventArgs + /// + /// + /// + /// + /// + /// + public GridPreRenderCellEventArgs(Graphics graphics, + GridPanel gridPanel, GridCell gridCell, RenderParts parts, Rectangle bounds) + : base(graphics, gridPanel, gridCell, parts, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridPostRenderRowEventArgs + + /// + /// GridPostRenderRowEventArgs + /// + public class GridPostRenderRowEventArgs : GridRowEventArgs + { + #region Private variables + + private Graphics _Graphics; + private Rectangle _Bounds; + private RenderParts _RenderParts; + + #endregion + + /// + /// GridPostRenderEventArgs + /// + /// + /// + /// + /// + /// + public GridPostRenderRowEventArgs(Graphics graphics, GridPanel gridPanel, + GridContainer gridRow, RenderParts parts, Rectangle bounds) + : base(gridPanel, gridRow) + { + _Graphics = graphics; + _RenderParts = parts; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the parts to render + /// + public RenderParts RenderParts + { + get { return (_RenderParts); } + } + + #endregion + } + + #endregion + + #region GridPreRenderRowEventArgs + + /// + /// GridPreRenderRowEventArgs + /// + public class GridPreRenderRowEventArgs : GridPostRenderRowEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridPreRenderRowEventArgs + /// + /// + /// + /// + /// + /// + public GridPreRenderRowEventArgs(Graphics graphics, GridPanel gridPanel, + GridContainer gridRow, RenderParts parts, Rectangle bounds) + : base(graphics, gridPanel, gridRow, parts, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridPostRenderColumnHeaderEventArgs + + /// + /// GridPostRenderColumnHeaderEventArgs + /// + public class GridPostRenderColumnHeaderEventArgs : GridEventArgs + { + #region Private variables + + private Rectangle _Bounds; + private Graphics _Graphics; + private GridColumnHeader _ColumnHeader; + private GridColumn _GridColumn; + private RenderParts _RenderParts; + + #endregion + + /// + /// GridPostRenderColumnHeaderEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridPostRenderColumnHeaderEventArgs(Graphics graphics, GridPanel gridPanel, + GridColumnHeader columnHeader, GridColumn column, RenderParts parts, Rectangle bounds) + : base(gridPanel) + { + _Bounds = bounds; + _Graphics = graphics; + _ColumnHeader = columnHeader; + _GridColumn = column; + _RenderParts = parts; + } + + #region Public properties + + /// + /// Gets the cell bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated GridColumnHeader + /// + public GridColumnHeader ColumnHeader + { + get { return (_ColumnHeader); } + } + + /// + /// Gets the associated GridColumn (which can be null + /// if the ColumnHeader's RowHeader is being rendered) + /// + public GridColumn GridColumn + { + get { return (_GridColumn); } + } + + /// + /// Gets the cell parts to render + /// + public RenderParts RenderParts + { + get { return (_RenderParts); } + } + + #endregion + } + + #endregion + + #region GridPreRenderColumnHeaderEventArgs + + /// + /// GridPreRenderColumnHeaderEventArgs + /// + public class GridPreRenderColumnHeaderEventArgs : GridPostRenderColumnHeaderEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridPreRenderColumnHeaderEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridPreRenderColumnHeaderEventArgs(Graphics graphics, GridPanel gridPanel, + GridColumnHeader header, GridColumn column, RenderParts parts, Rectangle bounds) + : base(graphics, gridPanel, header, column, parts, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridPostRenderColumnGroupHeaderEventArgs + + /// + /// GridPostRenderColumnGroupHeaderEventArgs + /// + public class GridPostRenderColumnGroupHeaderEventArgs : GridEventArgs + { + #region Private variables + + private Rectangle _Bounds; + private Graphics _Graphics; + private GridColumnHeader _ColumnHeader; + private ColumnGroupHeader _GroupHeader; + private RenderParts _RenderParts; + + #endregion + + /// + /// GridPostRenderColumnGroupHeaderEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridPostRenderColumnGroupHeaderEventArgs(Graphics graphics, GridPanel gridPanel, + GridColumnHeader columnHeader, ColumnGroupHeader groupHeader, RenderParts parts, Rectangle bounds) + : base(gridPanel) + { + _Bounds = bounds; + _Graphics = graphics; + _ColumnHeader = columnHeader; + _GroupHeader = groupHeader; + _RenderParts = parts; + } + + #region Public properties + + /// + /// Gets the cell bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated ColumnHeader + /// + public GridColumnHeader ColumnHeader + { + get { return (_ColumnHeader); } + } + + /// + /// Gets the associated GroupHeader + /// + public ColumnGroupHeader GroupHeader + { + get { return (_GroupHeader); } + } + + /// + /// Gets the cell parts to render + /// + public RenderParts RenderParts + { + get { return (_RenderParts); } + } + + #endregion + } + + #endregion + + #region GridPreRenderColumnGroupHeaderEventArgs + + /// + /// GridPreRenderColumnGroupHeaderEventArgs + /// + public class GridPreRenderColumnGroupHeaderEventArgs : GridPostRenderColumnGroupHeaderEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridPreRenderColumnGroupHeaderEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridPreRenderColumnGroupHeaderEventArgs(Graphics graphics, GridPanel gridPanel, + GridColumnHeader header, ColumnGroupHeader groupHeader, RenderParts parts, Rectangle bounds) + : base(graphics, gridPanel, header, groupHeader, parts, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridPostRenderFilterPopupGripBarEventArgs + + /// + /// GridPostRenderFilterPopupGripBarEventArgs + /// + public class GridPostRenderFilterPopupGripBarEventArgs : GridColumnEventArgs + { + #region Private variables + + private Graphics _Graphics; + private FilterPopup _FilterPopup; + private Rectangle _Bounds; + + #endregion + + /// + /// GridPostRenderFilterPopupGripBarEventArgs + /// + /// + /// + /// + /// + public GridPostRenderFilterPopupGripBarEventArgs(Graphics graphics, + FilterPopup filterPopup, GridColumn gridColumn, Rectangle bounds) + : base(gridColumn.GridPanel, gridColumn) + { + _Graphics = graphics; + _FilterPopup = filterPopup; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the GripBar bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the FilterPopup object + /// + public FilterPopup FilterPopup + { + get { return (_FilterPopup); } + } + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + #endregion + } + + #endregion + + #region GridPreRenderFilterPopupGripBarEventArgs + + /// + /// GridPreRenderFilterPopupGripBarEventArgs + /// + public class GridPreRenderFilterPopupGripBarEventArgs : GridPostRenderFilterPopupGripBarEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridPreRenderFilterPopupGripBarEventArgs + /// + /// + /// + /// + /// + public GridPreRenderFilterPopupGripBarEventArgs(Graphics graphics, + FilterPopup filterPopup, GridColumn gridColumn, Rectangle bounds) + : base(graphics, filterPopup, gridColumn, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridPostRenderFilterRowEventArgs + + /// + /// GridPostRenderFilterRowEventArgs + /// + public class GridPostRenderFilterRowEventArgs : GridEventArgs + { + #region Private variables + + private Rectangle _Bounds; + private Graphics _Graphics; + private GridFilter _GridFilter; + private GridColumn _GridColumn; + private RenderParts _RenderParts; + + #endregion + + /// + /// GridPostRenderFilterRowEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridPostRenderFilterRowEventArgs(Graphics graphics, GridPanel gridPanel, + GridFilter filter, GridColumn column, RenderParts parts, Rectangle bounds) + : base(gridPanel) + { + _Bounds = bounds; + _Graphics = graphics; + _GridFilter = filter; + _GridColumn = column; + _RenderParts = parts; + } + + #region Public properties + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated GridFilter + /// + public GridFilter GridFilter + { + get { return (_GridFilter); } + } + + /// + /// Gets the associated GridColumn (which can be null + /// if the Filter's RowHeader is being rendered) + /// + public GridColumn GridColumn + { + get { return (_GridColumn); } + } + + /// + /// Gets the parts to render + /// + public RenderParts RenderParts + { + get { return (_RenderParts); } + } + + #endregion + } + + #endregion + + #region GridPreRenderFilterRowEventArgs + + /// + /// GridPreRenderFilterRowEventArgs + /// + public class GridPreRenderFilterRowEventArgs : GridPostRenderFilterRowEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridPreRenderFilterRowEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridPreRenderFilterRowEventArgs(Graphics graphics, GridPanel gridPanel, + GridFilter filter, GridColumn column, RenderParts parts, Rectangle bounds) + : base(graphics, gridPanel, filter, column, parts, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridPostRenderGroupBoxConnectorEventArgs + + /// + /// GridPostRenderGroupBoxConnectorEventArgs + /// + public class GridPostRenderGroupBoxConnectorEventArgs : GridEventArgs + { + #region Private variables + + private Graphics _Graphics; + private GridGroupByRow _GroupByRow; + private GridGroupBox _GridGroupBox1; + private GridGroupBox _GridGroupBox2; + + #endregion + + /// + /// GridPostRenderGroupBoxConnectorEventArgs + /// + /// + /// + /// + /// + /// + public GridPostRenderGroupBoxConnectorEventArgs(Graphics graphics, + GridPanel gridPanel, GridGroupByRow groupByRow, GridGroupBox groupBox1, GridGroupBox groupBox2) + : base(gridPanel) + { + _Graphics = graphics; + _GroupByRow = groupByRow; + _GridGroupBox1 = groupBox1; + _GridGroupBox2 = groupBox2; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the associated GroupByRow + /// + public GridGroupByRow GroupByRow + { + get { return (_GroupByRow); } + } + + /// + /// Gets the first associated GridGroupBox + /// + public GridGroupBox GridGroupBox1 + { + get { return (_GridGroupBox1); } + } + + /// + /// Gets the second associated GridGroupBox + /// + public GridGroupBox GridGroupBox2 + { + get { return (_GridGroupBox2); } + } + + #endregion + } + + #endregion + + #region GridPreRenderGroupBoxConnectorEventArgs + + /// + /// GridPreRenderGroupBoxConnectorEventArgs + /// + public class GridPreRenderGroupBoxConnectorEventArgs : GridPostRenderGroupBoxConnectorEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridPreRenderGroupBoxConnectorEventArgs + /// + /// + /// + /// + /// + /// + public GridPreRenderGroupBoxConnectorEventArgs(Graphics graphics, GridPanel gridPanel, + GridGroupByRow groupByRow, GridGroupBox groupBox1, GridGroupBox groupBox2) + : base(graphics, gridPanel, groupByRow, groupBox1, groupBox2) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridPostRenderGroupBoxEventArgs + + /// + /// GridPostRenderGroupBoxEventArgs + /// + public class GridPostRenderGroupBoxEventArgs : GridEventArgs + { + #region Private variables + + private Graphics _Graphics; + private Rectangle _Bounds; + private RenderParts _RenderParts; + private GridGroupByRow _GroupByRow; + private GridGroupBox _GridGroupBox; + + #endregion + + /// + /// GridPostRenderGroupBoxEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridPostRenderGroupBoxEventArgs(Graphics graphics, GridPanel gridPanel, + GridGroupByRow groupByRow, GridGroupBox gridGroupBox, RenderParts parts, Rectangle bounds) + : base(gridPanel) + { + _Graphics = graphics; + _GroupByRow = groupByRow; + _GridGroupBox = gridGroupBox; + _RenderParts = parts; + _Bounds = bounds; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the parts to render + /// + public RenderParts RenderParts + { + get { return (_RenderParts); } + } + + /// + /// Gets the associated GroupByRow + /// + public GridGroupByRow GroupByRow + { + get { return (_GroupByRow); } + } + + /// + /// Gets the associated GridGroupBox + /// + public GridGroupBox GridGroupBox + { + get { return (_GridGroupBox); } + } + + #endregion + } + + #endregion + + #region GridPreRenderGroupBoxEventArgs + + /// + /// GridPreRenderGroupBoxEventArgs + /// + public class GridPreRenderGroupBoxEventArgs : GridPostRenderGroupBoxEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridPreRenderGroupBoxEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridPreRenderGroupBoxEventArgs(Graphics graphics, GridPanel gridPanel, + GridGroupByRow groupByRow, GridGroupBox gridGroupBox, RenderParts parts, Rectangle bounds) + : base(graphics, gridPanel, groupByRow, gridGroupBox, parts, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridPostRenderTextRowEventArgs + + /// + /// GridPostRenderTextRowEventArgs + /// + public class GridPostRenderTextRowEventArgs : GridEventArgs + { + #region Private variables + + private Graphics _Graphics; + private Rectangle _Bounds; + private RenderParts _RenderParts; + private GridTextRow _GridTextRow; + + #endregion + + /// + /// GridPostRenderTextRowEventArgs + /// + /// + /// + /// + /// + /// + public GridPostRenderTextRowEventArgs(Graphics graphics, GridPanel gridPanel, + GridTextRow gridTextRow, RenderParts parts, Rectangle bounds) + : base(gridPanel) + { + _Graphics = graphics; + _RenderParts = parts; + _Bounds = bounds; + _GridTextRow = gridTextRow; + } + + #region Public properties + + /// + /// Gets the Graphics object + /// + public Graphics Graphics + { + get { return (_Graphics); } + } + + /// + /// Gets the bounding rectangle + /// + public Rectangle Bounds + { + get { return (_Bounds); } + } + + /// + /// Gets the parts to render + /// + public RenderParts RenderParts + { + get { return (_RenderParts); } + } + + /// + /// Gets the associated GridTextRow + /// + public GridTextRow GridTextRow + { + get { return (_GridTextRow); } + } + + #endregion + } + + #endregion + + #region GridPreRenderTextRowEventArgs + + /// + /// GridPreRenderTextRowEventArgs + /// + public class GridPreRenderTextRowEventArgs : GridPostRenderTextRowEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridPreRenderTextRowEventArgs + /// + /// + /// + /// + /// + /// + public GridPreRenderTextRowEventArgs(Graphics graphics, GridPanel gridPanel, + GridTextRow gridTextRow, RenderParts parts, Rectangle bounds) + : base(graphics, gridPanel, gridTextRow, parts, bounds) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridPreviewKeyDownEventArgs + + /// + /// PreviewKeyDown event, with the ability to specify that the key has been handled + /// + public class GridPreviewKeyDownEventArgs : PreviewKeyDownEventArgs + { + #region Private variables + + private bool _Handled; + + #endregion + + /// + /// PreviewKeyDown event, with the ability to specify that the key has been handled + /// + /// + public GridPreviewKeyDownEventArgs(Keys keyData) + : base(keyData) + { + } + + #region Public properties + + /// + /// Gets or sets whether the key was handled + /// + public bool Handled + { + get { return (_Handled); } + set { _Handled = value; } + } + + #endregion + } + + #endregion + + #region GridRefreshFilterEventArgs + + /// + /// GridRefreshFilterEventArgs + /// + public class GridRefreshFilterEventArgs : GridCancelEventArgs + { + /// + /// GridRefreshFilterEventArgs + /// + /// + public GridRefreshFilterEventArgs(GridPanel gridPanel) + : base(gridPanel) + { + } + } + + #endregion + + #region GridRowActivatedEventArgs + + /// + /// GridRowActivatedEventArgs + /// + public class GridRowActivatedEventArgs : GridEventArgs + { + #region Private variables + + private readonly GridContainer _OldActiveRow; + private readonly GridContainer _NewActiveRow; + + #endregion + + /// + /// GridRowActivatedEventArgs + /// + /// + /// + /// + public GridRowActivatedEventArgs(GridPanel gridPanel, + GridContainer oldRow, GridContainer newRow) + : base(gridPanel) + { + _OldActiveRow = oldRow; + _NewActiveRow = newRow; + } + + #region Public properties + + /// + /// Gets the old (previous) ActiveRow + /// + public GridContainer OldActiveRow + { + get { return (_OldActiveRow); } + } + + /// + /// Gets the new (current) ActiveRow + /// + public GridContainer NewActiveRow + { + get { return (_NewActiveRow); } + } + + #endregion + } + + #endregion + + #region GridRowActivatingEventArgs + + /// + /// GridRowActivatingEventArgs + /// + public class GridRowActivatingEventArgs : GridRowActivatedEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridRowActivatingEventArgs + /// + /// + /// + /// + public GridRowActivatingEventArgs(GridPanel gridPanel, GridContainer oldRow, GridContainer newRow) + : base(gridPanel, oldRow, newRow) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridRowAddedEventArgs + + /// + /// GridRowAddedEventArgs + /// + public class GridRowAddedEventArgs : GridEventArgs + { + #region Private variables + + private int _Index; + + #endregion + + /// + /// GridRowAddedEventArgs + /// + /// + /// + public GridRowAddedEventArgs(GridPanel gridPanel, int index) + : base(gridPanel) + { + _Index = index; + } + + #region Public properties + + /// + /// Gets the associated GridPanel.Rows + /// index where the row is to be inserted + /// + public int Index + { + get { return (_Index); } + protected set { _Index = value; } + } + + #endregion + } + + #endregion + + #region GridRowAddingEventArgs + + /// + /// GridRowAddingEventArgs + /// + public class GridRowAddingEventArgs : GridRowAddedEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridRowAddingEventArgs + /// + /// + /// + public GridRowAddingEventArgs(GridPanel gridPanel, int index) + : base(gridPanel, index) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated GridPanel.Rows + /// index where the row is to be inserted + /// + public new int Index + { + get { return (base.Index); } + set { base.Index = value; } + } + + #endregion + } + + #endregion + + #region GridRowCancelEventArgs + + /// + /// GridRowCancelEventArgs + /// + public class GridRowCancelEventArgs : GridRowEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridRowCancelEventArgs + /// + /// + /// + public GridRowCancelEventArgs( + GridPanel gridPanel, GridContainer gridRow) + : base(gridPanel, gridRow) + { + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the operation. + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridRowDeletedEventArgs + + /// + /// GridRowMovedEventArgs + /// + public class GridRowDeletedEventArgs : GridEventArgs + { + #region Private variables + + private readonly SelectedElements _SelectedRows; + + #endregion + + /// + /// GridRowDeletedEventArgs + /// + /// + /// + public GridRowDeletedEventArgs(GridPanel gridPanel, SelectedElements selRows) + : base(gridPanel) + { + _SelectedRows = selRows; + } + + #region Public properties + + /// + /// Gets the associated selection of row indices to delete + /// + public SelectedElements SelectedRows + { + get { return (_SelectedRows); } + } + + #endregion + } + + #endregion + + #region GridRowDeletingEventArgs + + /// + /// GridRowDeletingEventArgs + /// + public class GridRowDeletingEventArgs : GridRowDeletedEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridRowDeletingEventArgs + /// + /// + /// + public GridRowDeletingEventArgs(GridPanel gridPanel, SelectedElements selRows) + : base(gridPanel, selRows) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridRowEventArgs + + /// + /// GridRowEventArgs + /// + public class GridRowEventArgs : GridEventArgs + { + #region Private variables + + private GridContainer _GridRow; + + #endregion + + /// + /// GridRowEventArgs + /// + /// + /// + public GridRowEventArgs(GridPanel gridPanel, GridContainer gridRow) + : base(gridPanel) + { + _GridRow = gridRow; + } + + #region Public properties + + /// + /// Gets the associated GridRow + /// + public GridContainer GridRow + { + get { return (_GridRow); } + } + + #endregion + } + + #endregion + + #region GridRowClickEventArgs + + /// + /// GridRowClickEventArgs + /// + public class GridRowClickEventArgs : GridRowEventArgs + { + #region Private variables + + private bool _Cancel; + private RowArea _RowArea; + private MouseEventArgs _MouseEventArgs; + + #endregion + + /// + /// GridRowClickEventArgs + /// + /// + /// + /// + /// + public GridRowClickEventArgs( + GridPanel gridPanel, GridRow gridRow, RowArea rowArea, MouseEventArgs e) + : base(gridPanel, gridRow) + { + _RowArea = rowArea; + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the default operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + /// + /// Gets the associated RowArea + /// + public RowArea RowArea + { + get { return (_RowArea); } + } + + #endregion + } + + #endregion + + #region GridRowDoubleClickEventArgs + + /// + /// GridRowDoubleClickEventArgs + /// + public class GridRowDoubleClickEventArgs : GridRowClickEventArgs + { + /// + /// GridRowDoubleClickEventArgs + /// + /// + /// + /// + /// + public GridRowDoubleClickEventArgs( + GridPanel gridPanel, GridRow gridRow, RowArea rowArea, MouseEventArgs e) + : base(gridPanel, gridRow, rowArea, e) + { + } + } + + #endregion + + #region GridGetDetailRowHeightEventArgs + + /// + /// GridGetDetailRowHeightEventArgs + /// + public class GridGetDetailRowHeightEventArgs : EventArgs + { + #region Private variables + + private GridRow _GridRow; + private GridPanel _GridPanel; + + private int _PreDetailHeight; + private int _PostDetailHeight; + + private GridLayoutInfo _LayoutInfo; + private Size _SizeNeeded; + + #endregion + + /// + /// GridGetDetailRowHeightEventArgs + /// + ///Associated GridPanel + ///Associated container row + /// + /// + /// + /// + public GridGetDetailRowHeightEventArgs(GridPanel gridPanel, + GridRow gridRow, GridLayoutInfo layoutInfo, Size sizeNeeded, int preHeight, int postHeight) + { + _GridPanel = gridPanel; + _GridRow = gridRow; + + _SizeNeeded = sizeNeeded; + _LayoutInfo = layoutInfo; + + _PreDetailHeight = preHeight; + _PostDetailHeight = postHeight; + } + + #region Public properties + + /// + /// Gets the event Grid + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + /// + /// Gets the associated GridRow + /// + public GridRow GridRow + { + get { return (_GridRow); } + } + + /// + /// Gets or sets the associated row PreDetail Height + /// + public int PreDetailHeight + { + get { return (_PreDetailHeight); } + set { _PreDetailHeight = value; } + } + + /// + /// Gets or sets the associated row PostDetail Height + /// + public int PostDetailHeight + { + get { return (_PostDetailHeight); } + set { _PostDetailHeight = value; } + } + + /// + /// Gets the associated row LayoutInfo + /// + public GridLayoutInfo LayoutInfo + { + get { return (_LayoutInfo); } + } + + /// + /// Gets or sets the associated row's needed size + /// + public Size SizeNeeded + { + get { return (_SizeNeeded); } + set { _SizeNeeded = value; } + } + + #endregion + } + + #endregion + + #region GridGetGroupIdEventArgs + + /// + /// GridGetGroupIdEventArgs + /// + public class GridGetGroupIdEventArgs : EventArgs + { + #region Private variables + + private GridPanel _GridPanel; + private GridElement _GridItem; + private GridColumn _GridColumn; + + private object _GroupId; + + #endregion + + /// + /// GridGetGroupIdEventArgs + /// + ///Associated GridPanel + ///Associated grid element + ///Associated grid column + ///Associated Group identifier + public GridGetGroupIdEventArgs( + GridPanel gridPanel, GridElement gridItem, GridColumn column, object groupId) + { + _GridPanel = gridPanel; + _GridColumn = column; + _GridItem = gridItem; + + _GroupId = groupId; + } + + #region Public properties + + /// + /// Gets the event Grid + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + /// + /// Gets the associated GridElement + /// + public GridElement GridItem + { + get { return (_GridItem); } + } + + /// + /// Gets the associated GridColumn + /// + public GridColumn GridColumn + { + get { return (_GridColumn); } + } + + /// + /// Gets or sets the associated row Group Identifier + /// + public object GroupId + { + get { return (_GroupId); } + set { _GroupId = value; } + } + + #endregion + } + + #endregion + + #region GridRowHeaderClickEventArgs + + /// + /// GridRowHeaderClickEventArgs + /// + public class GridRowHeaderClickEventArgs : GridRowEventArgs + { + #region Private variables + + private bool _Cancel; + private MouseEventArgs _MouseEventArgs; + + #endregion + + /// + /// GridRowHeaderClickEventArgs + /// + /// + /// + /// + public GridRowHeaderClickEventArgs( + GridPanel gridPanel, GridContainer row, MouseEventArgs e) + : base(gridPanel, row) + { + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + /// + /// Gets or sets whether to cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridRowHeaderDoubleClickEventArgs + + /// + /// GridRowHeaderDoubleClickEventArgs + /// + public class GridRowHeaderDoubleClickEventArgs : GridRowHeaderClickEventArgs + { + /// + /// GridRowHeaderDoubleClickEventArgs + /// + /// + /// + /// + public GridRowHeaderDoubleClickEventArgs( + GridPanel gridPanel, GridContainer row, MouseEventArgs e) + : base(gridPanel, row, e) + { + } + } + + #endregion + + #region GridRowInfoEnterEventArgs + + /// + /// GridRowInfoEnterEventArgs + /// + public class GridRowInfoEnterEventArgs : GridRowEventArgs + { + #region Private variables + + private bool _Cancel; + private Point _Location; + + #endregion + + /// + /// GridRowInfoEnterEventArgs + /// + /// + /// + /// + public GridRowInfoEnterEventArgs( + GridPanel gridPanel, GridRow gridRow, Point pt) + : base(gridPanel, gridRow) + { + _Location = pt; + } + + #region Public properties + + /// + /// Gets or sets whether to cancel the default operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated event Location + /// + public Point Location + { + get { return (_Location); } + } + + #endregion + } + + #endregion + + #region GridRowInfoLeaveEventArgs + + /// + /// GridRowInfoLeaveEventArgs + /// + public class GridRowInfoLeaveEventArgs : GridRowEventArgs + { + /// + /// GridRowInfoLeaveEventArgs + /// + /// + /// + public GridRowInfoLeaveEventArgs( + GridPanel gridPanel, GridRow gridRow) + : base(gridPanel, gridRow) + { + } + } + + #endregion + + #region GridRowLoadedEventArgs + + /// + /// GridRowLoadedEventArgs + /// + public class GridRowLoadedEventArgs : GridEventArgs + { + #region Private variables + + private GridRow _GridRow; + + #endregion + + /// + /// GridRowLoadedEventArgs + /// + /// + /// + public GridRowLoadedEventArgs(GridPanel gridPanel, GridRow row) + : base(gridPanel) + { + _GridRow = row; + } + + #region Public properties + + /// + /// Gets a reference to the loaded GridRow + /// + public GridRow GridRow + { + get { return (_GridRow); } + } + + #endregion + } + + #endregion + + #region GridRowMouseEventArgs + + /// + /// GridRowMouseEventArgs + /// + public class GridRowMouseEventArgs : MouseEventArgs + { + #region Private variables + + private readonly GridPanel _GridPanel; + private readonly GridContainer _GridRow; + private readonly RowArea _RowArea; + + #endregion + + /// + /// GridRowMouseEventArgs + /// + /// + /// + /// + /// + public GridRowMouseEventArgs(GridPanel gridPanel, GridContainer gridRow, MouseEventArgs ev, RowArea rowArea) + : base(ev.Button, ev.Clicks, ev.X, ev.Y, ev.Delta) + { + _GridPanel = gridPanel; + _GridRow = gridRow; + _RowArea = rowArea; + } + + #region Public properties + + /// + /// Gets the associated GridRow + /// + public GridContainer GridRow + { + get { return (_GridRow); } + } + + /// + /// Gets the associated GridPanel + /// + public GridPanel GridPanel + { + get { return (_GridPanel); } + } + + /// + /// Gets the associated RowArea + /// + public RowArea RowArea + { + get { return (_RowArea); } + } + + #endregion + } + + #endregion + + #region GridRowMovedEventArgs + + /// + /// GridRowMovedEventArgs + /// + public class GridRowMovedEventArgs : GridRowEventArgs + { + #region Private variables + + private readonly GridContainer _GridContainer; + + #endregion + + /// + /// GridRowMovedEventArgs + /// + /// + /// + /// + public GridRowMovedEventArgs(GridPanel gridPanel, + GridContainer gridContainer, GridContainer gridRow) + : base(gridPanel, gridRow) + { + _GridContainer = gridContainer; + } + + #region Public properties + + /// + /// Gets the associated GridContainer + /// + public GridContainer GridContainer + { + get { return (_GridContainer); } + } + + #endregion + } + + #endregion + + #region GridRowMovingEventArgs + + /// + /// GridRowMovingEventArgs + /// + public class GridRowMovingEventArgs : GridRowCancelEventArgs + { + #region Private variables + + private int _SrcIndex; + private GridContainer _SrcContainer; + + private int _DestIndex; + private GridContainer _DestContainer; + + #endregion + + /// + /// GridRowMovingEventArgs + /// + /// + /// + /// + /// + /// + /// + public GridRowMovingEventArgs(GridPanel gridPanel, GridRow gridRow, + GridContainer srcCont, int srcIndex, GridContainer destCont, int destIndex) + : base(gridPanel, gridRow) + { + _SrcIndex = srcIndex; + _SrcContainer = srcCont; + + _DestIndex = destIndex; + _DestContainer = destCont; + } + + #region Public properties + + /// + /// Gets or sets the Destination Container for the row + /// being moved. + /// + public GridContainer DestContainer + { + get { return (_DestContainer); } + set { _DestContainer = value; } + } + + /// + /// Gets or sets the Destination index for the row + /// being moved. + /// + public int DestIndex + { + get { return (_DestIndex); } + set { _DestIndex = value; } + } + + /// + /// Gets the Source Container of the row + /// being moved. + /// + public GridContainer SrcContainer + { + get { return (_SrcContainer); } + } + + /// + /// Gets the Source index of the row being moved. + /// + public int SrcIndex + { + get { return (_SrcIndex); } + } + + #endregion + } + + #endregion + + #region GridRowsPurgingEventArgs + + /// + /// GridRowsPurgingEventArgs + /// + public class GridRowsPurgingEventArgs : GridRowCancelEventArgs + { + #region Private variables + + private bool _IncludeNestedRows; + + #endregion + + /// + /// GridRowPurgeEventArgs + /// + /// + /// + /// + public GridRowsPurgingEventArgs( + GridPanel gridPanel, GridContainer gridRow, bool includeNestedRows) + : base(gridPanel, gridRow) + { + _IncludeNestedRows = includeNestedRows; + } + + #region Public properties + + /// + /// Gets or sets whether to include the associated GridPanel's + /// nested rows when purging deleted rows. + /// + public bool IncludeNestedRows + { + get { return (_IncludeNestedRows); } + set { _IncludeNestedRows = value; } + } + + #endregion + } + + #endregion + + #region GridRowRestoredEventArgs + + /// + /// GridRowRestoredEventArgs + /// + public class GridRowRestoredEventArgs : GridRowDeletedEventArgs + { + /// + /// GridRowRestoredEventArgs + /// + /// + /// + public GridRowRestoredEventArgs(GridPanel gridPanel, SelectedElements selRows) + : base(gridPanel, selRows) + { + } + } + + #endregion + + #region GridRowRestoringEventArgs + + /// + /// GridRowRestoringEventArgs + /// + public class GridRowRestoringEventArgs : GridRowDeletingEventArgs + { + /// + /// GridRowRestoringEventArgs + /// + /// + /// + public GridRowRestoringEventArgs(GridPanel gridPanel, SelectedElements selRows) + : base(gridPanel, selRows) + { + } + } + + #endregion + + #region GridRowSetDefaultValuesEventArgs + + /// + /// GridRowSetDefaultValuesEventArgs + /// + public class GridRowSetDefaultValuesEventArgs : GridEventArgs + { + #region Private variables + + private readonly GridRow _GridRow; + private readonly NewRowContext _NewRowContext; + + #endregion + + /// + /// GridRowDeletedEventArgs + /// + /// + /// + /// + public GridRowSetDefaultValuesEventArgs( + GridPanel gridPanel, GridRow gridRow, NewRowContext context) + : base(gridPanel) + { + _GridRow = gridRow; + _NewRowContext = context; + } + + #region Public properties + + /// + /// Gets the associated GridRow + /// + public GridRow GridRow + { + get { return (_GridRow); } + } + + /// + /// Gets the associated context under which + /// the new row data needs to be initialized + /// + public NewRowContext NewRowContext + { + get { return (_NewRowContext); } + } + + #endregion + } + + #endregion + + #region GridRowValidatedEventArgs + + /// + /// GridRowValidatedEventArgs + /// + public class GridRowValidatedEventArgs : GridEventArgs + { + #region Private variables + + private readonly GridRow _GridRow; + + #endregion + + /// + /// GridRowDeletedEventArgs + /// + /// + /// + public GridRowValidatedEventArgs(GridPanel gridPanel, GridRow gridRow) + : base(gridPanel) + { + _GridRow = gridRow; + } + + #region Public properties + + /// + /// Gets the associated GridRow + /// + public GridRow GridRow + { + get { return (_GridRow); } + } + + #endregion + } + + #endregion + + #region GridRowValidatingEventArgs + + /// + /// GridRowValidatingEventArgs + /// + public class GridRowValidatingEventArgs : GridRowValidatedEventArgs + { + #region Private variables + + private bool _Cancel; + + #endregion + + /// + /// GridRowValidatingEventArgs + /// + /// + /// + public GridRowValidatingEventArgs(GridPanel gridPanel, GridRow gridRow) + : base(gridPanel, gridRow) + { + } + + #region Public properties + + /// + /// Gets or sets whether + /// to cancel the operation entirely + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + #endregion + } + + #endregion + + #region GridScrollEventArgs + + /// + /// GridScrollEventArgs + /// + public class GridScrollEventArgs : GridEventArgs + { + #region Private variables + + private ScrollEventArgs _ScrollEventArgs; + + #endregion + + /// + /// GridScrollEventArgs + /// + /// + /// + public GridScrollEventArgs( + GridPanel gridPanel, ScrollEventArgs scrollEventArgs) + : base(gridPanel) + { + _ScrollEventArgs = scrollEventArgs; + } + + #region Public properties + + /// + /// Gets the scroll event args + /// + public ScrollEventArgs ScrollEventArgs + { + get { return (_ScrollEventArgs); } + } + + #endregion + } + + #endregion + + #region GridSelectionChangingEventArgs + + /// + /// GridSelectionChangingEventArgs + /// + public class GridSelectionChangingEventArgs : GridEventArgs + { + #region Private variables + + private SelectedElements _SelectedElements; + + private int _Index; + private int _Count; + + private bool _Selected; + private bool _Cancel; + + #endregion + + /// + /// GridSelectionChangingEventArgs + /// + /// + /// + /// + /// + /// + public GridSelectionChangingEventArgs(GridPanel gridPanel, + SelectedElements selectedElements, int index, int count, bool selected) + : base (gridPanel) + { + _SelectedElements = selectedElements; + + _Index = index; + _Count = count; + + _Selected = selected; + } + + #region Public properties + + /// + /// Gets or sets whether to Cancel the operation + /// + public bool Cancel + { + get { return (_Cancel); } + set { _Cancel = value; } + } + + /// + /// Gets the associated SelectedElements collection + /// + public SelectedElements SelectedElements + { + get { return (_SelectedElements); } + set { _SelectedElements = value; } + } + + /// + /// Gets the associated starting selection index + /// + public int Index + { + get { return (_Index); } + } + + /// + /// Gets the associated starting selection count + /// + public int Count + { + get { return (_Count); } + } + + /// + /// Gets the selected state (true/selected, false/cleared) + /// + public bool Selected + { + get { return (_Selected); } + } + + #endregion + + } + + #endregion + + #region GridTextRowEventArgs + + /// + /// GridTextRowEventArgs + /// + public class GridTextRowEventArgs : GridEventArgs + { + #region Private variables + + private readonly GridTextRow _GridTextRow; + private MouseEventArgs _MouseEventArgs; + + #endregion + + /// + /// GridTextRowEventArgs + /// + /// + /// + /// + public GridTextRowEventArgs( + GridPanel gridPanel, GridTextRow textRow, MouseEventArgs e) + : base(gridPanel) + { + _GridTextRow = textRow; + _MouseEventArgs = e; + } + + #region Public properties + + /// + /// Gets the associated GridTextRow + /// + public GridTextRow GridTextRow + { + get { return (_GridTextRow); } + } + + /// + /// Gets the associated MouseEventArgs + /// + public MouseEventArgs MouseEventArgs + { + get { return (_MouseEventArgs); } + } + + #endregion + } + + #endregion + + #region GridTextRowMarkupLinkClickEventArgs + + /// + /// GridTextRowMarkupLinkClickEventArgs + /// + public class GridTextRowMarkupLinkClickEventArgs : GridEventArgs + { + #region Private variables + + private string _HRef; + private string _Name; + private readonly GridTextRow _GridTextRow; + + #endregion + + /// + /// GridTextRowMarkupLinkClickEventArgs + /// + /// + /// + /// + /// + public GridTextRowMarkupLinkClickEventArgs(GridPanel gridPanel, + GridTextRow gridTextRow, string name, string href) + : base(gridPanel) + { + _GridTextRow = gridTextRow; + + _HRef = href; + _Name = name; + } + + #region Public properties + + /// + /// Gets the associated HyperLink HRef + /// + public string HRef + { + get { return (_HRef); } + } + + /// + /// Gets the associated HyperLink Name + /// + public string Name + { + get { return (_Name); } + } + + /// + /// Gets the associated GridTextRow + /// + public GridTextRow GridTextRow + { + get { return (_GridTextRow); } + } + + #endregion + } + + #endregion + + #region GridUpdateCellDisplayRangesEventArgs + + /// + /// GridUpdateCellDisplayRangesEventArgs + /// + public class GridUpdateCellDisplayRangesEventArgs : GridEventArgs + { + #region Private variables + + private DisplayRange _DisplayRange; + private List _CellRanges; + private GridContainer _GridContainer; + + #endregion + + /// + /// GridUpdateCellDisplayRangesEventArgs + /// + ///Associated GridPanel + ///Associated GridContainer + ///Row/col range being merge evaluated + ///List of CellRanges + public GridUpdateCellDisplayRangesEventArgs(GridPanel gridPanel, + GridContainer gridContainer, DisplayRange displayRange, List cellRanges) + : base(gridPanel) + { + _GridContainer = gridContainer; + _DisplayRange = displayRange; + _CellRanges = cellRanges; + } + + #region Public properties + + /// + /// Gets or sets the CellRanges + /// + public List CellRanges + { + get { return (_CellRanges); } + set { _CellRanges = value; } + } + + /// + /// Gets the current DisplayRange (row/col range + /// being processed / merged evaluated) + /// + public DisplayRange DisplayRange + { + get { return (_DisplayRange); } + } + + /// + /// Gets the GridContainer + /// + public GridContainer GridContainer + { + get { return (_GridContainer); } + } + + #endregion + } + + #endregion + + #region GridVirtualRowEventArgs + + /// + /// GridVirtualRowEventArgs + /// + public class GridVirtualRowEventArgs : GridEventArgs + { + #region Private variables + + private GridRow _GridRow; + private int _Index; + + #endregion + + /// + /// GridVirtualRowEventArgs + /// + /// + /// + /// + public GridVirtualRowEventArgs(GridPanel gridPanel, GridRow gridRow, int index) + : base(gridPanel) + { + _GridRow = gridRow; + _Index = index; + } + + #region Public properties + + /// + /// Gets the GridRow + /// + public GridRow GridRow + { + get { return (_GridRow); } + } + + /// + /// Gets the associated row index + /// + public int Index + { + get { return (_Index); } + } + + #endregion + } + + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/TextDrawing.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/TextDrawing.cs new file mode 100644 index 00000000..af3fc1e3 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/TextDrawing.cs @@ -0,0 +1,250 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Drawing.Text; + +namespace DevComponents.DotNetBar.SuperGrid +{ + internal class TextDrawing + { + #region Public / internal variables + + public static bool UseTextRenderer = true; + public static bool TextDrawingEnabled = true; + + internal static bool UseGenericDefault = false; + + #endregion + + #region DrawString + + public static void DrawString(Graphics g, + string text, Font font, Color color, int x, int y, eTextFormat format) + { + DrawString(g, text, font, color, new Rectangle(x, y, 0, 0), format); + } + + public static void DrawString(Graphics g, + string text, Font font, Color color, Rectangle bounds, eTextFormat format) + { + if (UseTextRenderer && (format & eTextFormat.Vertical) == 0) + TextRenderer.DrawText(g, text, font, bounds, color, GetTextFormatFlags(format)); + else + DrawStringLegacy(g, text, font, color, bounds, format); + } + + #endregion + + #region DrawStringLegacy + + public static void DrawStringLegacy(Graphics g, + string text, Font font, Color color, Rectangle bounds, eTextFormat format) + { + if (color.IsEmpty == false && TextDrawingEnabled == true) + { + using (SolidBrush brush = new SolidBrush(color)) + { + using (StringFormat sf = GetStringFormat(format)) + g.DrawString(text, font, brush, bounds, sf); + } + } + } + + #endregion + + #region MeasureString + + public static Size MeasureString(Graphics g, + string text, Font font) + { + return MeasureString(g, text, font, Size.Empty, eTextFormat.Default); + } + + public static Size MeasureString(Graphics g, + string text, Font font, int proposedWidth, eTextFormat format) + { + return MeasureString(g, text, font, new Size(proposedWidth, 0), format); + } + + public static Size MeasureString(Graphics g, + string text, Font font, int proposedWidth) + { + return MeasureString(g, text, font, new Size(proposedWidth, 0), eTextFormat.Default); + } + + public static Size MeasureString(Graphics g, + string text, Font font, Size proposedSize, eTextFormat format) + { + if (UseTextRenderer && (format & eTextFormat.Vertical) == 0) + { + format = format & ~(format & eTextFormat.VerticalCenter); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.Bottom); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.HorizontalCenter); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.Right); // Bug in .NET Framework 2.0 + format = format & ~(format & eTextFormat.EndEllipsis); // Bug in .NET Framework 2.0 + + return (Size.Ceiling(TextRenderer.MeasureText(g, text, font, proposedSize, GetTextFormatFlags(format)))); + } + + using (StringFormat sf = GetStringFormat(format)) + return Size.Ceiling(g.MeasureString(text, font, proposedSize, sf)); + } + + #endregion + + #region MeasureStringLegacy + + public static Size MeasureStringLegacy(Graphics g, + string text, Font font, Size proposedSize, eTextFormat format) + { + using (StringFormat sf = GetStringFormat(format)) + return (g.MeasureString(text, font, proposedSize, sf).ToSize()); + } + + #endregion + + #region TranslateHorizontal + + public static eTextFormat TranslateHorizontal(StringAlignment align) + { + if (align == StringAlignment.Center) + return (eTextFormat.HorizontalCenter); + + if (align == StringAlignment.Far) + return (eTextFormat.Right); + + return (eTextFormat.Default); + } + + #endregion + + #region TranslateVertical + + public static eTextFormat TranslateVertical(StringAlignment align) + { + if (align == StringAlignment.Center) + return (eTextFormat.VerticalCenter); + + if (align == StringAlignment.Far) + return (eTextFormat.Bottom); + + return (eTextFormat.Default); + } + + #endregion + + #region GetTextFormatFlags + + private static TextFormatFlags GetTextFormatFlags(eTextFormat format) + { + format |= eTextFormat.PreserveGraphicsTranslateTransform | + eTextFormat.PreserveGraphicsClipping; + + if ((format & eTextFormat.SingleLine) == eTextFormat.SingleLine && + (format & eTextFormat.WordBreak) == eTextFormat.WordBreak) + { + format = format & ~(format & eTextFormat.SingleLine); + } + + return (TextFormatFlags)format; + } + + #endregion + + #region GetStringFormat + + public static StringFormat GetStringFormat(eTextFormat format) + { + StringFormat sf = new StringFormat(UseGenericDefault + ? StringFormat.GenericDefault : StringFormat.GenericTypographic); + + if (format == eTextFormat.Default) + return sf; + + if ((format & eTextFormat.HorizontalCenter) == eTextFormat.HorizontalCenter) + sf.Alignment = StringAlignment.Center; + + else if ((format & eTextFormat.Right) == eTextFormat.Right) + sf.Alignment = StringAlignment.Far; + + if ((format & eTextFormat.VerticalCenter) == eTextFormat.VerticalCenter) + sf.LineAlignment = StringAlignment.Center; + + else if ((format & eTextFormat.Bottom) == eTextFormat.Bottom) + sf.LineAlignment = StringAlignment.Far; + + if ((format & eTextFormat.EndEllipsis) == eTextFormat.EndEllipsis) + sf.Trimming = StringTrimming.EllipsisCharacter; + else + sf.Trimming = StringTrimming.Character; + + if ((format & eTextFormat.HidePrefix) == eTextFormat.HidePrefix) + sf.HotkeyPrefix = HotkeyPrefix.Hide; + else if ((format & eTextFormat.NoPrefix) == eTextFormat.NoPrefix) + sf.HotkeyPrefix = HotkeyPrefix.None; + else + sf.HotkeyPrefix = HotkeyPrefix.Show; + + if ((format & eTextFormat.WordBreak) == eTextFormat.WordBreak) + sf.FormatFlags = sf.FormatFlags & ~(sf.FormatFlags & StringFormatFlags.NoWrap); + else + sf.FormatFlags |= StringFormatFlags.NoWrap; + + if ((format & eTextFormat.LeftAndRightPadding) == eTextFormat.LeftAndRightPadding) + sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces; + + if ((format & eTextFormat.RightToLeft) == eTextFormat.RightToLeft) + sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + + if ((format & eTextFormat.Vertical) == eTextFormat.Vertical) + sf.FormatFlags |= StringFormatFlags.DirectionVertical; + + if ((format & eTextFormat.NoClipping) == eTextFormat.NoClipping) + sf.FormatFlags |= StringFormatFlags.NoClip; + + return (sf); + } + + #endregion + } + + #region enums + + #region eTextFormat + [Flags] + internal enum eTextFormat + { + Bottom = 8, + Default = 0, + EndEllipsis = 0x8000, + ExpandTabs = 0x40, + ExternalLeading = 0x200, + GlyphOverhangPadding = 0, + HidePrefix = 0x100000, + HorizontalCenter = 1, + Internal = 0x1000, + Left = 0, + LeftAndRightPadding = 0x20000000, + ModifyString = 0x10000, + NoClipping = 0x100, + NoFullWidthCharacterBreak = 0x80000, + NoPadding = 0x10000000, + NoPrefix = 0x800, + PathEllipsis = 0x4000, + PrefixOnly = 0x200000, + PreserveGraphicsClipping = 0x1000000, + PreserveGraphicsTranslateTransform = 0x2000000, + Right = 2, + RightToLeft = 0x20000, + SingleLine = 0x20, + TextBoxControl = 0x2000, + Top = 0, + VerticalCenter = 4, + WordBreak = 0x10, + WordEllipsis = 0x40000, + Vertical = 0x40000000 + } + #endregion + + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/TreeDisplay.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/TreeDisplay.cs new file mode 100644 index 00000000..844ba186 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGrid/TreeDisplay.cs @@ -0,0 +1,210 @@ +using System.Drawing; +using System.Drawing.Drawing2D; +using DevComponents.DotNetBar.SuperGrid.Style; + +namespace DevComponents.DotNetBar.SuperGrid +{ + /// + /// TreeDisplay + /// + public class TreeDisplay + { + #region RenderLines + + /// + /// RenderTreeLines + /// + /// + /// + /// + /// + /// + /// + /// + /// + static public void RenderLines(Graphics g, GridPanel panel, Rectangle bounds, + GridContainer item, int indentLevel, int indentAmount, int width, bool hasButton) + { + if (panel.NewFullIndex <= 1) + return; + + Rectangle r = bounds; + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + GridPanelVisualStyle style = panel.GetEffectiveStyle(); + + if (style.TreeLinePattern == LinePattern.Dot) + { + if (r.Y % 2 == 0) + { + r.Y++; + + if (r.Height % 2 != 0) + r.Height--; + } + } + + GetLineBounds(bounds, ref r, indentLevel, indentAmount, width); + + using (Pen pen = new Pen(style.TreeLineColor, Dpi.Width1)) + { + pen.DashStyle = (DashStyle)style.TreeLinePattern; + + Rectangle t = Rectangle.Empty; + int n = 0; + + if (item is GridPanel) + { + t = item.BoundsRelative; + + t.X -= item.HScrollOffset; + t.Y -= item.VScrollOffset; + + if (item.HasCheckBox == true) + n = Dpi.Width(panel.CheckBoxSize.Width); + } + + if (r.Width > 0) + DrawDash(g, item, style, pen, r, t, n, hasButton); + + int rowIndex = item.GridIndex; + + GridContainer tRow = item; + GridContainer nRow = tRow.GetNextItem(); + + while (tRow != null) + { + int tIndex = (nRow != null) ? nRow.GridIndex : -1; + + if (r.Width > 0) + { + if (t.IsEmpty || r.Right <= t.Left) + { + if (tIndex > rowIndex) + { + if (rowIndex == 0 && item.Parent is GridPanel) + DrawLower(g, style, pen, r); + else + DrawFull(g, pen, r); + } + else + { + if (item == tRow && (indentLevel > 0 || rowIndex > 0)) + DrawUpper(g, pen, r); + } + } + } + + tRow = tRow.Parent as GridRow; + + if (tRow != null) + nRow = tRow.GetNextItem(); + + GetLineBounds(bounds, ref r, --indentLevel, indentAmount, width); + } + } + + g.SmoothingMode = sm; + } + + #endregion + + #region GetLineBounds + + static private void GetLineBounds( + Rectangle bounds, ref Rectangle r, int indentLevel, int indentAmount, int width) + { + r.X = bounds.X + indentAmount * indentLevel; + r.Width = width; + } + + #endregion + + #region DrawDash + + static void DrawDash(Graphics g, GridContainer item, GridPanelVisualStyle style, + Pen pen, Rectangle r, Rectangle t, int n, bool hasButton) + { + int x = r.X + r.Width / 2 + 1; + int y = r.Y + r.Height / 2; + + GridPanel ppanel = item.GetParentPanel(); + + if (ppanel.CheckBoxes == true && item.ShowCheckBox == false) + { + r.Width += Dpi.Width(ppanel.CheckBoxSize.Width); + + if (item is GridPanel) + r.Width += Dpi.Width4; + } + + if (t.Width > 0 && r.Right > t.Left - n) + r.Width -= r.Right - (t.Left - n); + + if (r.Width > 0) + { + if (style.TreeLinePattern == LinePattern.Dot) + { + x++; + + if (hasButton == false) + { + if (y % 2 == 0) + y--; + } + else + { + y -= 2; + } + } + + g.DrawLine(pen, x, y, r.Right, y); + } + } + + #endregion + + #region DrawUpper + + static void DrawUpper(Graphics g, Pen pen, Rectangle r) + { + int x = r.X + r.Width / 2; + + g.DrawLine(pen, x, r.Y, x, r.Y + r.Height / 2); + } + + #endregion + + #region DrawLower + + static void DrawLower(Graphics g, + GridPanelVisualStyle style, Pen pen, Rectangle r) + { + int x = r.X + r.Width / 2; + int y = r.Y + r.Height / 2; + + if (style.TreeLinePattern == LinePattern.Dot) + { + if (y % 2 == 0) + y--; + } + + g.DrawLine(pen, x, y, x, r.Bottom); + } + + #endregion + + #region DrawFull + + static void DrawFull(Graphics g, Pen pen, Rectangle r) + { + g.DrawLine(pen, + r.X + r.Width / 2, r.Y, + r.X + r.Width / 2, r.Bottom); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGridControl.png b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGridControl.png new file mode 100644 index 00000000..df28cefc Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/SuperGridControl.png differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/BodyElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/BodyElement.cs new file mode 100644 index 00000000..37d3d151 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/BodyElement.cs @@ -0,0 +1,95 @@ +using System; +using System.Text; +using System.Windows.Forms; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class BodyElement : ContainerElement + { + #region Private Variables + private MarkupElementCollection m_ActiveElements=null; + private IActiveMarkupElement m_MouseOverElement = null; + internal bool HasExpandElement = false; + internal string PlainText = ""; + #endregion + + #region Events + public event EventHandler HyperLinkClick; + #endregion + + #region Internal Implementation + public BodyElement() + { + m_ActiveElements = new MarkupElementCollection(null); + } + + public MarkupElementCollection ActiveElements + { + get { return m_ActiveElements; } + } + + public void MouseLeave(Control parent) + { + if (m_MouseOverElement != null) + m_MouseOverElement.MouseLeave(parent); + m_MouseOverElement = null; + } + + public void MouseMove(Control parent, MouseEventArgs e) + { + if (m_MouseOverElement != null && m_MouseOverElement.HitTest(e.X, e.Y)) + return; + if (m_MouseOverElement != null) + m_MouseOverElement.MouseLeave(parent); + + m_MouseOverElement = null; + + foreach(IActiveMarkupElement el in m_ActiveElements) + { + if (el.HitTest(e.X, e.Y)) + { + m_MouseOverElement = el; + m_MouseOverElement.MouseEnter(parent); + } + } + } + + public void MouseDown(Control parent, MouseEventArgs e) + { + if (m_MouseOverElement != null) + m_MouseOverElement.MouseDown(parent, e); + } + + public void MouseUp(Control parent, MouseEventArgs e) + { + if (m_MouseOverElement != null) + m_MouseOverElement.MouseUp(parent, e); + } + + public void Click(Control parent) + { + if (m_MouseOverElement != null) + { + m_MouseOverElement.Click(parent); + if (m_MouseOverElement is HyperLink) + { + if (HyperLinkClick != null) + HyperLinkClick(m_MouseOverElement, new EventArgs()); + } + } + } + + internal IActiveMarkupElement MouseOverElement + { + get { return (m_MouseOverElement); } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/ContainerElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/ContainerElement.cs new file mode 100644 index 00000000..fc8c98e7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/ContainerElement.cs @@ -0,0 +1,111 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class ContainerElement : MarkupElement + { + #region Private Variables + private SerialContentLayoutManager m_Layout = null; + private MarkupLayoutManager m_MarkupLayout = null; + #endregion + + #region Internal Implementation + public override void Measure(Size availableSize, MarkupDrawContext d) + { + ArrangeInternal(new Rectangle(Point.Empty, availableSize), d); + } + + protected virtual SerialContentLayoutManager GetLayoutManager(bool mutliLine) + { + if (m_Layout == null) + { + m_Layout = new SerialContentLayoutManager(); + m_Layout.MultiLine = mutliLine; + m_Layout.ContentVerticalAlignment = eContentVerticalAlignment.Top; + m_Layout.BlockLineAlignment = eContentVerticalAlignment.Top; + m_Layout.BlockSpacing = 0; + } + + m_Layout.EvenHeight = true; + return m_Layout; + } + + private MarkupLayoutManager GetMarkupLayout() + { + if (m_MarkupLayout == null) + { + m_MarkupLayout = new MarkupLayoutManager(); + } + return m_MarkupLayout; + } + + public override void Render(MarkupDrawContext d) + { + Point offset = this.GetContainerOffset(); + d.Offset.Offset(offset.X, offset.Y); + + try + { + foreach (MarkupElement e in this.Elements) + { + e.Render(d); + } + } + finally + { + d.Offset.Offset(-offset.X, -offset.Y); + } + } + + protected virtual Point GetContainerOffset() + { + return this.Bounds.Location; + } + + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) + { + this.Bounds = finalRect; + ArrangeInternal(finalRect, d); + } + + protected virtual void ArrangeInternal(Rectangle bounds, MarkupDrawContext d) + { + SerialContentLayoutManager layout = GetLayoutManager(d.AllowMultiLine); + layout.RightToLeft = d.RightToLeft; + MarkupLayoutManager markupLayout = GetMarkupLayout(); + markupLayout.MarkupDrawContext = d; + try + { + MarkupElement[] blocks = new MarkupElement[this.Elements.Count]; + this.Elements.CopyTo(blocks); + + Rectangle r = layout.Layout(new Rectangle(Point.Empty, bounds.Size), blocks, markupLayout); + this.Bounds = new Rectangle(bounds.Location, r.Size); + } + finally + { + markupLayout.MarkupDrawContext = null; + } + } + + /// + /// Returns whether markup element is an block element that always consumes a whole line in layout. + /// + public override bool IsBlockElement + { + get { return true; } + } + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Div.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Div.cs new file mode 100644 index 00000000..a4bf93fb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Div.cs @@ -0,0 +1,168 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +using DevComponents.DotNetBar.SuperGrid.Style; +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class Div : ContainerElement + { + #region Private Variables + private eParagraphAlignment m_Align = eParagraphAlignment.Left; + private eParagraphVerticalAlignment m_VAlign = eParagraphVerticalAlignment.Top; + private int m_Width = 0; + private Padding m_Padding = new Padding(0, 0, 0, 0); + #endregion + + #region Internal Implementation + public eParagraphAlignment Align + { + get { return m_Align; } + set { m_Align = value; } + } + + protected override SerialContentLayoutManager GetLayoutManager(bool multiLine) + { + SerialContentLayoutManager sm = base.GetLayoutManager(multiLine); + if (m_Align == eParagraphAlignment.Left) + sm.ContentAlignment = eContentAlignment.Left; + else if (m_Align == eParagraphAlignment.Right) + sm.ContentAlignment = eContentAlignment.Right; + else if (m_Align == eParagraphAlignment.Center) + sm.ContentAlignment = eContentAlignment.Center; + + if (m_VAlign != eParagraphVerticalAlignment.Top) + { + sm.EvenHeight = false; + sm.BlockLineAlignment = (m_VAlign == eParagraphVerticalAlignment.Bottom ? eContentVerticalAlignment.Bottom : eContentVerticalAlignment.Middle); + } + + return sm; + } + + protected override Point GetContainerOffset() + { + if (m_Padding.Left == 0 && m_Padding.Top == 0) + return base.GetContainerOffset(); + + Point p = base.GetContainerOffset(); + p.X += m_Padding.Left; + p.Y += m_Padding.Top; + return p; + } + + protected override void ArrangeInternal(Rectangle bounds, MarkupDrawContext d) + { + Rectangle r = bounds; + if (m_Width > 0) + r.Width = m_Width; + if (m_Padding.IsEmpty) + { + base.ArrangeInternal(r, d); + if (m_Width > 0) + this.Bounds = new Rectangle(this.Bounds.X, this.Bounds.Y, m_Width, this.Bounds.Height + m_Padding.Bottom); + } + else + { + r.X += m_Padding.Left; + r.Y += m_Padding.Top; + base.ArrangeInternal(r, d); + + r = new Rectangle(bounds.X, bounds.Y, this.Bounds.Width + m_Padding.Horizontal, this.Bounds.Height + m_Padding.Vertical); + if (m_Width > 0) + r.Width = m_Width; + + this.Bounds = r; + } + } + + public override void ReadAttributes(XmlTextReader reader) + { + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "align") + { + string s = reader.Value.ToLower(); + if (s == "left") + m_Align = eParagraphAlignment.Left; + else if (s == "right") + m_Align = eParagraphAlignment.Right; + else if (s == "center") + m_Align = eParagraphAlignment.Center; + } + else if (reader.Name.ToLower() == "valign") + { + string s = reader.Value.ToLower(); + if (s == "top") + m_VAlign = eParagraphVerticalAlignment.Top; + else if (s == "middle") + m_VAlign = eParagraphVerticalAlignment.Middle; + else if (s == "bottom") + m_VAlign = eParagraphVerticalAlignment.Bottom; + } + else if (reader.Name.ToLower() == "width") + { + try + { + m_Width = Int32.Parse(reader.Value); + } + catch + { + m_Width = 0; + } + } + else if (reader.Name.ToLower() == "padding") + { + try + { + string[] values = reader.Value.Split(','); + if (values.Length > 0) + m_Padding.Left = Int32.Parse(values[0]); + if (values.Length > 1) + m_Padding.Right = Int32.Parse(values[1]); + if (values.Length > 2) + m_Padding.Top = Int32.Parse(values[2]); + if (values.Length > 3) + m_Padding.Bottom = Int32.Parse(values[3]); + } + catch + { + m_Padding = new Padding(0,0,0,0); + } + } + } + } + #endregion + } + + #region eParagraphAlignment + /// + /// Indicates paragraph content alignment + /// + internal enum eParagraphAlignment + { + Left, + Right, + Center + } + + /// + /// Indicates paragraph content alignment + /// + internal enum eParagraphVerticalAlignment + { + Top, + Middle, + Bottom + } + #endregion +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/EndMarkupElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/EndMarkupElement.cs new file mode 100644 index 00000000..b9ee4987 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/EndMarkupElement.cs @@ -0,0 +1,48 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class EndMarkupElement : MarkupElement + { + #region Internap Implementation + private MarkupElement m_StartElement = null; + + public EndMarkupElement(MarkupElement startElement) + { + m_StartElement = startElement; + } + + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + m_StartElement.MeasureEnd(availableSize, d); + this.Bounds = Rectangle.Empty; + } + + public override void Render(MarkupDrawContext d) + { + m_StartElement.RenderEnd(d); + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) + { + this.Bounds = Rectangle.Empty; + } + + /// + /// Gets reference to markup start element. + /// + public MarkupElement StartElement + { + get { return m_StartElement; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/ExpandElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/ExpandElement.cs new file mode 100644 index 00000000..43f61f2f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/ExpandElement.cs @@ -0,0 +1,199 @@ +using System; +using System.Text; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Xml; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class ExpandElement : MarkupElement + { + #region Internal Implementation + private Size m_DefaultSize = new Size(5, 4); + private eExpandDirection m_Direction = eExpandDirection.Default; + + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + this.Bounds = new Rectangle(Point.Empty, m_DefaultSize); + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Graphics g = d.Graphics; + Color color = d.CurrentForeColor; + //Color shadeColor = Color.FromArgb(96, Color.White); + + eExpandDirection direction = eExpandDirection.Bottom; + if (m_Direction != eExpandDirection.Default) + direction = m_Direction; + + #if DOTNETBAR + if(d.ContextObject is ButtonItem) + { + if (m_Direction == eExpandDirection.Default) + { + ButtonItem item = d.ContextObject as ButtonItem; + if (item.IsOnMenu) + { + direction = eExpandDirection.Right; + if (item.PopupSide == ePopupSide.Default && d.RightToLeft || item.PopupSide == ePopupSide.Left) + direction = eExpandDirection.Left; + } + else if (item.PopupSide == ePopupSide.Default) + direction = eExpandDirection.Bottom; + else if (item.PopupSide == ePopupSide.Left) + direction = eExpandDirection.Left; + else if (item.PopupSide == ePopupSide.Right) + direction = eExpandDirection.Right; + else if (item.PopupSide == ePopupSide.Bottom) + direction = eExpandDirection.Bottom; + else if (item.PopupSide == ePopupSide.Top) + direction = eExpandDirection.Top; + } + } + #endif + + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + + Rectangle shadeRect = r; + if (direction == eExpandDirection.Bottom || direction == eExpandDirection.PopupDropDown) + shadeRect.Offset(0, 1); + else if (direction == eExpandDirection.Top) + shadeRect.Offset(0, -1); + else if (direction == eExpandDirection.Left) + shadeRect.Offset(1, 0); + else if (direction == eExpandDirection.Right) + shadeRect.Offset(-1, 0); + Point[] p = GetExpandPolygon(shadeRect, direction); + //using (SolidBrush brush = new SolidBrush(shadeColor)) + // g.FillPolygon(brush, p); + + p = GetExpandPolygon(r, direction); + using(SolidBrush brush = new SolidBrush(color)) + g.FillPolygon(brush, p); + + if (direction == eExpandDirection.PopupDropDown) + { + using (Pen pen = new Pen(color, 1)) + g.DrawLine(pen, r.X, r.Y - 2, r.Right - 1, r.Y - 2); + //using (Pen pen = new Pen(shadeColor, 1)) + // g.DrawLine(pen, r.X, r.Y - 1, r.Right - 1, r.Y - 1); + } + + g.SmoothingMode = sm; + + this.RenderBounds = r; + } + + private Point[] GetExpandPolygon(Rectangle r, eExpandDirection direction) + { + Point[] p = new Point[3]; + switch (direction) + { + case eExpandDirection.Right: + { + p[0].X = r.Left + 1; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 - 1; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X + 3; + p[2].Y = p[0].Y + 3; + break; + } + case eExpandDirection.Left: + { + p[0].X = r.Left + 3; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 - 1; + p[1].X = p[0].X; + p[1].Y = p[0].Y + 6; + p[2].X = p[0].X - 3; + p[2].Y = p[0].Y + 3; + break; + } + case eExpandDirection.Top: + { + p[0].X = r.Left - 1; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 + m_DefaultSize.Height; + p[1].X = p[0].X + 6; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 3; + p[2].Y = p[0].Y - 4; + break; + } + case eExpandDirection.Bottom: + case eExpandDirection.PopupDropDown: + { + p[0].X = r.Left; + p[0].Y = r.Top + (r.Height - m_DefaultSize.Height) / 2 + 1; + p[1].X = p[0].X + 5; + p[1].Y = p[0].Y; + p[2].X = p[0].X + 2; + p[2].Y = p[0].Y + 3; + break; + } + } + return p; + } + + public override void ReadAttributes(XmlTextReader reader) + { + m_Direction = eExpandDirection.Default; + + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "direction") + { + string s = reader.Value.ToLower(); + if (s == "left") + m_Direction = eExpandDirection.Left; + else if (s == "right") + m_Direction = eExpandDirection.Right; + else if (s == "top") + m_Direction = eExpandDirection.Top; + else if (s == "bottom") + m_Direction = eExpandDirection.Bottom; + else if (s == "popup") + m_Direction = eExpandDirection.PopupDropDown; + break; + } + } + } + + private enum eExpandDirection + { + Left, + Right, + Top, + Bottom, + Default, + PopupDropDown + } + + /// + /// Returns whether layout manager can start new line with this element. + /// + public override bool CanStartNewLine + { + get { return false; } + } + #endregion + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/FontChangeElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/FontChangeElement.cs new file mode 100644 index 00000000..3bd6835c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/FontChangeElement.cs @@ -0,0 +1,55 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class FontChangeElement : MarkupElement + { + #region Private Variables + protected Font m_OldFont = null; + #endregion + + #region Internal Implementation + + public override void Measure(Size availableSize, MarkupDrawContext d) + { + this.Bounds = Rectangle.Empty; + SetFont(d); + } + + public override void Render(MarkupDrawContext d) + { + SetFont(d); + } + + protected virtual void SetFont(MarkupDrawContext d) + { + + } + + public override void RenderEnd(MarkupDrawContext d) + { + if(m_OldFont!=null) + d.CurrentFont = m_OldFont; + m_OldFont = null; + base.RenderEnd(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + if (m_OldFont != null) + d.CurrentFont = m_OldFont; + m_OldFont = null; + base.MeasureEnd(availableSize, d); + } + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) { } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/FontElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/FontElement.cs new file mode 100644 index 00000000..8cece36e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/FontElement.cs @@ -0,0 +1,186 @@ +using System; +using System.Drawing; +using System.Xml; + +#if AdvTree +using DevComponents.Tree; +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +using DevComponents.DotNetBar.SuperGrid; +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class FontElement : FontChangeElement + { + #region Private Variables + + private Color _MForeColor = Color.Empty; + private Color _MOldForeColor = Color.Empty; + private int _MSize; + private bool _MRelativeSize; + private string _MFace = ""; + private string _MSystemColorName = ""; + + #endregion + + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + try + { + if (_MFace != "" || _MSize != 0 && _MRelativeSize || _MSize>4 && !_MRelativeSize) + { + if (_MFace != "") + d.CurrentFont = new Font(_MFace, ((_MRelativeSize || _MSize == 0)?font.SizeInPoints + _MSize:_MSize), font.Style); + else + d.CurrentFont = new Font(font.FontFamily, ((_MRelativeSize || _MSize == 0)? font.SizeInPoints + _MSize : _MSize), font.Style); + } + else + font = null; + } + catch + { + font = null; + } + + if (font != null) + m_OldFont = font; + + if (!d.IgnoreFormattingColors) + { + if (!_MForeColor.IsEmpty) + { + _MOldForeColor = d.CurrentForeColor; + d.CurrentForeColor = _MForeColor; + } + else if (_MSystemColorName != "") + { +#if DOTNETBAR + if (Rendering.GlobalManager.Renderer is Rendering.Office2007Renderer) + { + m_OldForeColor = d.CurrentForeColor; + d.CurrentForeColor = ((Rendering.Office2007Renderer)Rendering.GlobalManager.Renderer).ColorTable.Form.Active.CaptionTextExtra; + } +#endif + } + } + } + + public override void RenderEnd(MarkupDrawContext d) + { + RestoreForeColor(d); + + base.RenderEnd(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + RestoreForeColor(d); + base.MeasureEnd(availableSize, d); + } + + protected virtual void RestoreForeColor(MarkupDrawContext d) + { + if (!_MOldForeColor.IsEmpty) + d.CurrentForeColor = _MOldForeColor; + _MOldForeColor = Color.Empty; + } + + public Color ForeColor + { + get { return _MForeColor; } + set { _MForeColor = value; } + } + + public int Size + { + get { return _MSize; } + set { _MSize = value; } + } + + public string Face + { + get { return _MFace; } + set { _MFace = value; } + } + + private Color GetColorFromName(string name) + { + string s = name.ToLower(); + _MSystemColorName = ""; + if (s == "syscaptiontextextra") + { + _MSystemColorName = s; + return Color.Empty; + } + + return Color.FromName(name); + } + + public override void ReadAttributes(XmlTextReader reader) + { + _MRelativeSize = false; + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "color") + { + try + { + string s = reader.Value; + if (s.StartsWith("#")) + { + if (s.Length == 7) + _MForeColor = ColorHelpers.GetColor(s.Substring(1)); + } + else + { + _MForeColor = GetColorFromName(s); + } + } + catch + { + _MForeColor = Color.Empty; + } + } + else if (reader.Name.ToLower() == "size") + { + string s = reader.Value; + if (s.StartsWith("+")) + { + try + { + _MSize = Int32.Parse(s.Substring(1)); + _MRelativeSize = true; + } + catch + { + _MSize = 0; + } + } + else + { + if (s.StartsWith("-")) + _MRelativeSize = true; + try + { + _MSize = Int32.Parse(s); + } + catch + { + _MSize = 0; + } + } + } + else if (reader.Name.ToLower() == "face") + { + _MFace = reader.Value; + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Heading.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Heading.cs new file mode 100644 index 00000000..25522df6 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Heading.cs @@ -0,0 +1,95 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class Heading: ContainerElement + { + #region Private Variables + private int m_Level = 1; + private Font m_OldFont = null; + #endregion + + #region Internal Implementation + public Heading() { } + public Heading(int level) + { + m_Level = level; + } + + public override void Measure(Size availableSize, MarkupDrawContext d) + { + SetFont(d); + base.Measure(availableSize, d); + if (m_OldFont != null) + d.CurrentFont = m_OldFont; + } + + public override void Render(MarkupDrawContext d) + { + SetFont(d); + base.Render(d); + if (m_OldFont != null) + d.CurrentFont = m_OldFont; + } + + protected virtual void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + try + { + float size = d.CurrentFont.SizeInPoints; + if (m_Level == 1) + { + size += 12; + } + else if (m_Level == 2) + { + size += 8; + } + else if (m_Level == 3) + { + size += 6; + } + else if (m_Level == 4) + { + size += 4; + } + else if (m_Level == 5) + { + size += 2; + } + else if (m_Level == 6) + { + size += 1; + } + + d.CurrentFont = new Font(d.CurrentFont.FontFamily, size, FontStyle.Bold); + } + catch + { + font = null; + } + + if (font != null) + m_OldFont = font; + } + + /// + /// Gets or sets heading level. Values from 1 to 6 are valid. Default is 1. + /// + public int Level + { + get { return m_Level; } + set { m_Level = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/HyperLink.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/HyperLink.cs new file mode 100644 index 00000000..f7e8d845 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/HyperLink.cs @@ -0,0 +1,221 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; +using System.Windows.Forms; +using System.Drawing.Drawing2D; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class HyperLink : MarkupElement, IActiveMarkupElement + { + #region Private Variables + private Color m_ForeColor = Color.Empty; + private Color m_OldForeColor = Color.Empty; + private string m_HRef = ""; + private string m_Name = ""; + private Cursor m_OldCursor = null; + private bool m_IsMouseOver = false; + private bool m_Visited = false; + #endregion + + #region Internal Implementation + public override void Measure(Size availableSize, MarkupDrawContext d) + { + this.Bounds = Rectangle.Empty; + SetForeColor(d); + } + + public override void Render(MarkupDrawContext d) + { + d.HyperLink = true; + d.HyperlinkStyle = GetHyperlinkStyle(); + if (!d.HyperlinkStyle.BackColor.IsEmpty) + { + using (GraphicsPath gp = new GraphicsPath()) + { + MarkupElementCollection col = this.Parent.Elements; + int start = col.IndexOf(this) + 1; + for (int i = start; i < col.Count; i++) + { + MarkupElement elem = col[i]; + if (!elem.Visible) continue; + if (elem is EndMarkupElement && ((EndMarkupElement)elem).StartElement == this) + break; + gp.AddRectangle(elem.RenderBounds); + } + + using (SolidBrush brush = new SolidBrush(d.HyperlinkStyle.BackColor)) + d.Graphics.FillPath(brush, gp); + } + } + SetForeColor(d); + } + + private HyperlinkStyle GetHyperlinkStyle() + { + if (m_IsMouseOver && MarkupSettings.MouseOverHyperlink.IsChanged) + return MarkupSettings.MouseOverHyperlink; + else if (m_Visited && MarkupSettings.VisitedHyperlink.IsChanged) + return MarkupSettings.VisitedHyperlink; + + return MarkupSettings.NormalHyperlink; + } + + protected virtual void SetForeColor(MarkupDrawContext d) + { + Color c = Color.Empty; + HyperlinkStyle style = GetHyperlinkStyle(); + if (style != null && !style.TextColor.IsEmpty) + c = style.TextColor; + + if (!m_ForeColor.IsEmpty) + c = m_ForeColor; + if (!c.IsEmpty) + { + m_OldForeColor = d.CurrentForeColor; + d.CurrentForeColor = c; + } + } + + public override void RenderEnd(MarkupDrawContext d) + { + RestoreForeColor(d); + d.HyperLink = false; + d.HyperlinkStyle = null; + base.RenderEnd(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + RestoreForeColor(d); + base.MeasureEnd(availableSize, d); + } + + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) { } + + protected virtual void RestoreForeColor(MarkupDrawContext d) + { + if (!m_OldForeColor.IsEmpty) + d.CurrentForeColor = m_OldForeColor; + m_OldForeColor = Color.Empty; + } + + public Color ForeColor + { + get { return m_ForeColor; } + set { m_ForeColor = value; } + } + + public string HRef + { + get { return m_HRef; } + set { m_HRef = value; } + } + + public string Name + { + get { return m_Name; } + set { m_Name = value; } + } + + public override void ReadAttributes(XmlTextReader reader) + { + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "href") + { + m_HRef = reader.Value; + } + else if (reader.Name.ToLower() == "name") + { + m_Name = reader.Value; + } + } + } + + /// + /// Returns whether hyper-link contains specified coordinates. + /// + /// + /// + /// + public bool HitTest(int x, int y) + { + if (this.Parent == null) + return false; + + MarkupElementCollection col = this.Parent.Elements; + int start = col.IndexOf(this)+1; + for (int i = start; i < col.Count; i++) + { + MarkupElement el = col[i]; + if (el is EndMarkupElement && ((EndMarkupElement)el).StartElement == this) + break; + + if (col[i].RenderBounds.Contains(x, y)) + return true; + + } + + return false; + } + + public void MouseEnter(Control parent) + { + m_OldCursor = parent.Cursor; + parent.Cursor = Cursors.Hand; + m_IsMouseOver = true; + if (MarkupSettings.MouseOverHyperlink.IsChanged) + { + InvalidateElements(parent); + } + } + + public void MouseLeave(Control parent) + { + if (m_OldCursor != null && parent!=null) + parent.Cursor = m_OldCursor; + m_OldCursor = null; + m_IsMouseOver = false; + if (MarkupSettings.MouseOverHyperlink.IsChanged) + { + InvalidateElements(parent); + } + } + + public void MouseDown(Control parent, MouseEventArgs e) { } + public void MouseUp(Control parent, MouseEventArgs e) { } + public void Click(Control parent) + { + m_Visited = true; + if (MarkupSettings.VisitedHyperlink.IsChanged) + { + InvalidateElements(parent); + } + } + + private void InvalidateElements(Control parent) + { + if (this.Parent == null) return; + MarkupElementCollection col = this.Parent.Elements; + int start = col.IndexOf(this) + 1; + for (int i = start; i < col.Count; i++) + { + MarkupElement elem = col[i]; + if (!elem.Visible) continue; + if (elem is EndMarkupElement && ((EndMarkupElement)elem).StartElement == this) + break; + parent.Invalidate(elem.RenderBounds); + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/IActiveMarkupElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/IActiveMarkupElement.cs new file mode 100644 index 00000000..66080c79 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/IActiveMarkupElement.cs @@ -0,0 +1,22 @@ +using System; +using System.Text; +using System.Windows.Forms; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal interface IActiveMarkupElement + { + bool HitTest(int x, int y); + void MouseEnter(Control parent); + void MouseLeave(Control parent); + void MouseDown(Control parent, MouseEventArgs e); + void MouseUp(Control parent, MouseEventArgs e); + void Click(Control parent); + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/ImageElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/ImageElement.cs new file mode 100644 index 00000000..4e19d6ac --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/ImageElement.cs @@ -0,0 +1,187 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; +using System.Reflection; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif + +{ + internal class ImageElement : MarkupElement + { + #region Private Variables + private Size m_ImageSize = Size.Empty; + private string m_ImageSource = ""; + private Image m_Image = null; + #endregion + + #region Internal Implementation + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + if (!m_ImageSize.IsEmpty) + this.Bounds = new Rectangle(Point.Empty, m_ImageSize); + else if (m_ImageSource.Length == 0) + this.Bounds = Rectangle.Empty; + else + { + Image img = this.GetImage(); + if (img != null) + this.Bounds = new Rectangle(Point.Empty, img.Size); + else + this.Bounds = new Rectangle(Point.Empty, new Size(16,16)); + } + } + + public override bool IsBlockElement + { + get + { + return false; + } + } + + private Image GetImage() + { + if (m_Image != null) return m_Image; + Assembly a = null; + + // Load from format: ClassLibrary1/ClassLibrary1.MyImage.png or ClassLibrary1/global::ClassLibrary1.Resources.MyImage + if (m_ImageSource.IndexOf('/') >= 0) + { + string[] parts = m_ImageSource.Split('/'); + a = Assembly.Load(parts[0]); + string ResourceName = parts[1]; + if (a != null) + { + m_Image = LoadImageGlobalResource(parts[1], a); + if (m_Image == null) + m_Image = LoadImageResource(parts[1], a); + + if (m_Image != null) return m_Image; + } + } + + // Probe Executing Assembly + a = Assembly.GetExecutingAssembly(); + m_Image = LoadImageGlobalResource(m_ImageSource, a); + if(m_Image==null) + m_Image = LoadImageResource(m_ImageSource, a); + + // Probe Entry Assembly + if (m_Image == null) + { + a = Assembly.GetEntryAssembly(); + m_Image = LoadImageGlobalResource(m_ImageSource, a); + if (m_Image == null) + m_Image = LoadImageResource(m_ImageSource, a); + } + + return m_Image; + } + + private Image LoadImageGlobalResource(string imageSource, Assembly a) + { + Image img = null; +#if FRAMEWORK20 + if (imageSource.StartsWith("global::")) + { + string name = imageSource.Substring(8); + if (name.Length > 0) + { + try + { + int i = name.LastIndexOf('.'); + string resName = name.Substring(0, i); + name = name.Substring(i + 1); + System.Resources.ResourceManager r = new System.Resources.ResourceManager(resName, a); + object obj = r.GetObject(name); + img = (Bitmap)obj; + } + catch + { + img = null; + } + } + } +#endif + return img; + } + + private Image LoadImageResource(string imageSource, Assembly a) + { + Image img = null; + try + { + img = new Bitmap(a.GetManifestResourceStream(imageSource)); + } + catch { } + + return img; + } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Image img = this.GetImage(); + if (img != null) + { + Rectangle imageRect = r; + imageRect.Size = img.Size; + d.Graphics.DrawImage(img, imageRect); + } + else + { + using (SolidBrush brush = new SolidBrush(Color.White)) + { + d.Graphics.FillRectangle(brush, r); + } + using (Pen pen = new Pen(Color.DarkGray, 1)) + { + d.Graphics.DrawRectangle(pen, r); + d.Graphics.DrawLine(pen, r.X, r.Y, r.Right, r.Bottom); + d.Graphics.DrawLine(pen, r.Right, r.Y, r.X, r.Bottom); + } + } + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + public override void ReadAttributes(XmlTextReader reader) + { + m_ImageSize = Size.Empty; + m_ImageSource = ""; + m_Image = null; + + for (int i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + if (reader.Name.ToLower() == "width") + { + string s = reader.Value; + m_ImageSize.Width = int.Parse(s); + } + else if (reader.Name.ToLower() == "height") + { + string s = reader.Value; + m_ImageSize.Height = int.Parse(s); + } + else if (reader.Name.ToLower() == "src") + { + m_ImageSource = reader.Value; + } + } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Italic.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Italic.cs new file mode 100644 index 00000000..aa6b58e4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Italic.cs @@ -0,0 +1,33 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class Italic : FontChangeElement + { + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + FontStyle style=font.Style | FontStyle.Italic; + + if (!font.Italic && d.CurrentFont.FontFamily.IsStyleAvailable(style)) + d.CurrentFont = new Font(font, style); + else + font = null; + + if (font != null) + m_OldFont = font; + + base.SetFont(d); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupDrawContext.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupDrawContext.cs new file mode 100644 index 00000000..e1aaf18f --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupDrawContext.cs @@ -0,0 +1,56 @@ +using System; +using System.Drawing; +using System.Text; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class MarkupDrawContext + { + public Graphics Graphics = null; + public Font CurrentFont = null; + public Color CurrentForeColor = SystemColors.ControlText; + public bool RightToLeft = false; + public Point Offset = Point.Empty; + public bool HyperLink = false; + public HyperlinkStyle HyperlinkStyle = null; + public bool Underline = false; + public Rectangle ClipRectangle = Rectangle.Empty; + public bool HotKeyPrefixVisible = false; + public object ContextObject = null; + public bool AllowMultiLine = true; + public bool IgnoreFormattingColors = false; + public bool StrikeOut; + + public MarkupDrawContext(Graphics g, Font currentFont, Color currentForeColor, bool rightToLeft) : this(g, currentFont, currentForeColor, rightToLeft, Rectangle.Empty, false) + { + } + + public MarkupDrawContext(Graphics g, Font currentFont, Color currentForeColor, bool rightToLeft, Rectangle clipRectangle, bool hotKeyPrefixVisible) + { + this.Graphics = g; + this.CurrentFont = currentFont; + this.CurrentForeColor = currentForeColor; + this.RightToLeft = rightToLeft; + this.ClipRectangle = clipRectangle; + this.HotKeyPrefixVisible = hotKeyPrefixVisible; + } + + public MarkupDrawContext(Graphics g, Font currentFont, Color currentForeColor, bool rightToLeft, Rectangle clipRectangle, bool hotKeyPrefixVisible, object contextObject) + { + this.Graphics = g; + this.CurrentFont = currentFont; + this.CurrentForeColor = currentForeColor; + this.RightToLeft = rightToLeft; + this.ClipRectangle = clipRectangle; + this.HotKeyPrefixVisible = hotKeyPrefixVisible; + this.ContextObject = contextObject; + } + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupElement.cs new file mode 100644 index 00000000..99041396 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupElement.cs @@ -0,0 +1,178 @@ +using System; +using System.Drawing; +using System.Text; +using System.Xml; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal abstract class MarkupElement : IBlockExtended + { + #region Private Variables + private MarkupElementCollection m_Elements = null; + private MarkupElement m_Parent = null; + private Rectangle m_Bounds = Rectangle.Empty; + private bool m_Visible = true; + private bool m_SizeValid = false; + private Rectangle m_RenderBounds = Rectangle.Empty; + #endregion + + #region Internal Implementation + public MarkupElement() + { + m_Elements = new MarkupElementCollection(this); + } + + /// + /// Returns whether markup element is an block element that always consumes a whole line in layout. + /// + public virtual bool IsBlockElement + { + get { return false; } + } + + /// + /// Returns whether layout manager switches to new line after processing this element. + /// + public virtual bool IsNewLineAfterElement + { + get { return false; } + } + + /// + /// Returns whether layout manager can start new line with this element. + /// + public virtual bool CanStartNewLine + { + get { return true; } + } + + /// + /// Gets the collection of child elements if any for this markup element. + /// + public virtual MarkupElementCollection Elements + { + get + { + if (m_Elements == null) + m_Elements = new MarkupElementCollection(this); + return m_Elements; + } + } + + internal void InvalidateElementsSize() + { + this.IsSizeValid = false; + if (m_Elements==null || m_Elements.Count == 0) + return; + foreach (MarkupElement e in m_Elements) + { + e.InvalidateElementsSize(); + e.IsSizeValid = false; + } + } + + /// + /// Gets or sets whether element size is valid. When size is not valid element Measure method will be called to validate size. + /// + public virtual bool IsSizeValid + { + get { return m_SizeValid; } + set { m_SizeValid = value; } + } + + /// + /// Gets element parent or null if parent is not set. + /// + public virtual MarkupElement Parent + { + get { return m_Parent; } + } + + internal void SetParent(MarkupElement parent) + { + m_Parent = parent; + } + + /// + /// Gets or sets actual rendering bounds. + /// + public Rectangle Bounds + { + get { return m_Bounds; } + set { m_Bounds = value; } + } + + /// + /// Gets or sets whether markup element is visible. + /// + public bool Visible + { + get { return m_Visible; } + set { m_Visible = value; } + } + + /// + /// Measures the element given available size. + /// + /// Size available to element + /// Reference to graphics object + public abstract void Measure(Size availableSize, MarkupDrawContext d); + + /// + /// Measures the end tag of an element. Most implementations do not need to do anything but implementations like the ones + /// that change color should return state back at this time. + /// + /// + /// + public virtual void MeasureEnd(Size availableSize, MarkupDrawContext d) { } + + /// + /// Renders element. + /// + /// Provides markup drawing context information. + public abstract void Render(MarkupDrawContext d); + + /// + /// Renders element tag end. Most implementations do not need to do anything but mplementations like the ones + /// that change color should return state back at this time. + /// + /// Provides markup drawing context information. + public virtual void RenderEnd(MarkupDrawContext d) { } + + /// + /// Provides final rectangle to element and lets it arrange it's content given new constraint. + /// + /// Final rectangle. + /// + protected abstract void ArrangeCore(Rectangle finalRect, MarkupDrawContext d); + + /// + /// Arranges the element given the final size. Layout is two step process with Measure followed by Arrange. + /// + /// + /// + public void Arrange(Rectangle finalSize, MarkupDrawContext d) + { + this.ArrangeCore(finalSize, d); + } + + public virtual void ReadAttributes(XmlTextReader reader) { } + + /// + /// Gets or sets actual rendered bounds for a give markup element if applicable. + /// + public Rectangle RenderBounds + { + get { return m_RenderBounds; } + set { m_RenderBounds = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupElementCollection.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupElementCollection.cs new file mode 100644 index 00000000..81b75528 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupElementCollection.cs @@ -0,0 +1,139 @@ +using System; +using System.Text; +using System.Collections; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class MarkupElementCollection : CollectionBase + { + #region Private Variables + private MarkupElement m_Parent = null; + #endregion + + #region Internal Implementation + /// Creates new instance of the class. + public MarkupElementCollection(MarkupElement parent) + { + m_Parent = parent; + } + + /// + /// Gets or sets the collection parent element. + /// + public MarkupElement Parent + { + get { return m_Parent; } + set { m_Parent = value; } + } + + /// + /// Adds new object to the collection. + /// + /// Object to add. + /// Index of newly added object. + public int Add(MarkupElement MarkupElement) + { + return List.Add(MarkupElement); + } + /// + /// Returns reference to the object in collection based on it's index. + /// + public MarkupElement this[int index] + { + get {return (MarkupElement)(List[index]);} + set {List[index] = value;} + } + + /// + /// Inserts new object into the collection. + /// + /// Position of the object. + /// Object to insert. + public void Insert(int index, MarkupElement value) + { + List.Insert(index, value); + } + + /// + /// Returns index of the object inside of the collection. + /// + /// Reference to the object. + /// Index of the object. + public int IndexOf(MarkupElement value) + { + return List.IndexOf(value); + } + + /// + /// Returns whether collection contains specified object. + /// + /// Object to look for. + /// true if object is part of the collection, otherwise false. + public bool Contains(MarkupElement value) + { + return List.Contains(value); + } + + /// + /// Removes specified object from the collection. + /// + /// + public void Remove(MarkupElement value) + { + List.Remove(value); + } + + protected override void OnRemoveComplete(int index,object value) + { + base.OnRemoveComplete(index,value); + MarkupElement me=value as MarkupElement; + if (m_Parent != null) + { + me.SetParent(null); + m_Parent.IsSizeValid = false; + } + } + protected override void OnInsertComplete(int index,object value) + { + base.OnInsertComplete(index,value); + MarkupElement me=value as MarkupElement; + if (m_Parent != null) + { + me.SetParent(m_Parent); + m_Parent.IsSizeValid = false; + } + } + + /// + /// Copies collection into the specified array. + /// + /// Array to copy collection to. + /// Starting index. + public void CopyTo(MarkupElement[] array, int index) + { + List.CopyTo(array, index); + } + + /// + /// Copies contained items to the MarkupElement array. + /// + /// Array to copy to. + internal void CopyTo(MarkupElement[] array) + { + List.CopyTo(array,0); + } + + protected override void OnClear() + { + base.OnClear(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupLayoutManager.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupLayoutManager.cs new file mode 100644 index 00000000..6e36f2a4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupLayoutManager.cs @@ -0,0 +1,39 @@ +using System.Collections; +using System.Drawing; +using System.Text; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class MarkupLayoutManager : BlockLayoutManager + { + private MarkupDrawContext m_MarkupDrawContext = null; + + public MarkupDrawContext MarkupDrawContext + { + get { return m_MarkupDrawContext; } + set { m_MarkupDrawContext = value; } + } + + public override void Layout(IBlock block, Size availableSize) + { + if (block is MarkupElement) + { + MarkupElement m = block as MarkupElement; + if(!m.IsSizeValid) + m.Measure(availableSize, m_MarkupDrawContext); + } + } + + public override Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines) + { + return (blocksBounds); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupParser.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupParser.cs new file mode 100644 index 00000000..86ee5ae9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupParser.cs @@ -0,0 +1,256 @@ +using System; +using System.Text; +using System.IO; +using System.Xml; +using System.Collections; +using System.Text.RegularExpressions; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class MarkupParser + { + #region Private Variables + private static string TextElementName = "text"; + private static string BodyTag = "body"; + #endregion + + #region Internal Implementation + public static BodyElement Parse(string text) + { + StringBuilder plainText = new StringBuilder(text.Length); + BodyElement root = new BodyElement(); + root.HasExpandElement = false; + MarkupElement currentParent = root; + Stack openTags = new Stack(); + openTags.Push(root); + // Input text is not wrapped into the container tag so we wrap it here + text = text.Replace(" ", "{ent_nbsp}"); + text = text.Replace("&zwsp;", "{ent_zwsp}"); + text = text.Replace("<", "{ent_lt}"); + text = text.Replace(">", "{ent_gt}"); + text = text.Replace("&", "{ent_amp}"); + text = text.Replace("|", "{ent_l}"); + text = text.Replace("&", "|"); + text = text.Replace("{ent_nbsp}", " "); + text = text.Replace("{ent_zwsp}", "&zwsp;"); + text = text.Replace("{ent_lt}", "<"); + text = text.Replace("{ent_gt}", ">"); + StringReader sr = new StringReader("<"+BodyTag+">" + text + ""); +#if !DEBUG + try +#endif + { + XmlTextReader reader = new XmlTextReader(sr); + //reader.EntityHandling = EntityHandling.ExpandCharEntities; + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element) + { + if (reader.Name == BodyTag) + continue; + MarkupElement el = CreateMarkupElement(reader.Name); + if (el == null) + { + reader.Skip(); + continue; + } + else if (el is ExpandElement) + root.HasExpandElement = true; + + if (el is IActiveMarkupElement) + root.ActiveElements.Add(el); + + // Parse any attributes here + if (reader.AttributeCount > 0) + { + el.ReadAttributes(reader); + reader.MoveToElement(); + } + + currentParent.Elements.Add(el); + + if (el is ContainerElement) + currentParent = el; + + if (!reader.IsEmptyElement) + openTags.Push(el); + } + else if (reader.NodeType == XmlNodeType.Text) + { + if (reader.Value.Length == 1) + { + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + if (reader.Value == " ") + { + el.TrailingSpace = true; + plainText.Append(' '); + } + else + { + el.Text = reader.Value; + el.Text = el.Text.Replace("|", "&"); + el.Text = el.Text.Replace("{ent_l}", "|"); + el.Text = el.Text.Replace("{ent_amp}", "&&"); + plainText.Append(el.Text+" "); + } + currentParent.Elements.Add(el); + } + else + { + string s = reader.Value; + if (s.StartsWith("\r\n")) + s = s.TrimStart(new char[] { '\r', '\n' }); + s = s.Replace("\r\n", " "); + string[] words = s.Split(' '); + bool space = false; + if (currentParent.Elements.Count > 0 && currentParent.Elements[currentParent.Elements.Count - 1] is NewLine) + space = true; + for (int i = 0; i < words.Length; i++) + { + if (words[i].Length == 0) + { + if (space) + continue; + space = true; + } + else + space = false; + + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + el.Text = words[i].Replace("|","&"); + el.Text = el.Text.Replace("{ent_l}", "|"); + el.Text = el.Text.Replace("{ent_amp}", "&&"); + plainText.Append(el.Text + " "); + if (i < words.Length - 1) + { + el.TrailingSpace = true; + space = true; + } + + currentParent.Elements.Add(el); + } + } + } + else if (reader.NodeType == XmlNodeType.Whitespace) + { + if (reader.Value.IndexOf(' ') >= 0) + { + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + el.TrailingSpace = true; + currentParent.Elements.Add(el); + } + } + else if (reader.NodeType == XmlNodeType.EntityReference) + { + TextElement el = CreateMarkupElement(TextElementName) as TextElement; + if (reader.Name == "nbsp") + { + el.TrailingSpace = true; + } + else if (reader.Name == "zwsp") + { + el.TrailingSpace = false; + } + else + el.Text = reader.Name; + el.EnablePrefixHandling = false; + currentParent.Elements.Add(el); + } + else if (reader.NodeType == XmlNodeType.EndElement) + { + MarkupElement el = openTags.Pop() as MarkupElement; + if (el != currentParent) + { + currentParent.Elements.Add(new EndMarkupElement(el)); + } + else + { + if (currentParent != root) + currentParent = currentParent.Parent; + } + } + } + } +#if !DEBUG + catch + { + return null; + } +#endif + root.PlainText = plainText.ToString(); + return root; + } + + public static MarkupElement CreateMarkupElement(string elementName) + { + if (elementName == "b" || elementName == "strong") + return new Strong(); + else if (elementName == "i" || elementName == "em") + return new Italic(); + else if (elementName == "u") + return new Underline(); + else if (elementName == "br") + return new NewLine(); + else if (elementName == "expand") + return new ExpandElement(); + else if (elementName == "a") + return new HyperLink(); + else if (elementName == "p") + return new Paragraph(); + else if (elementName == "div") + return new Div(); + else if (elementName == "span") + return new Span(); + else if (elementName == "img") + return new ImageElement(); + else if (elementName == "h1") + return new Heading(); + else if (elementName == "h2") + return new Heading(2); + else if (elementName == "h3") + return new Heading(3); + else if (elementName == "h4") + return new Heading(4); + else if (elementName == "h5") + return new Heading(5); + else if (elementName == "h6") + return new Heading(6); + else if (elementName == "font") + return new FontElement(); + else if (elementName == "s" || elementName == "strike") + return new Strike(); + else if (elementName == TextElementName) + return new TextElement(); + + return null; + } + + /// + /// Tests whether input text could be markup text. + /// + /// Text to test. + /// true if text could be markup, otherwise false + public static bool IsMarkup(string text) + { + if (string.IsNullOrEmpty(text) || + (text.IndexOf("") < 0)) + { + return false; + } + + return true; + } + + internal static string RemoveExpand(string text) + { + return Regex.Replace(text, "", "", RegexOptions.IgnoreCase); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupSettings.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupSettings.cs new file mode 100644 index 00000000..b448f45b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/MarkupSettings.cs @@ -0,0 +1,156 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + /// + /// Holds text-markup related settings. + /// + public static class MarkupSettings + { + private static HyperlinkStyle _NormalHyperlink = new HyperlinkStyle(Color.Blue, eHyperlinkUnderlineStyle.SolidLine); + /// + /// Gets the style of the hyperlink in its default state. + /// + public static HyperlinkStyle NormalHyperlink + { + get { return _NormalHyperlink; } + } + + private static HyperlinkStyle _MouseOverHyperlink = new HyperlinkStyle(); + /// + /// Gets the style of the hyperlink when mouse is over the link. + /// + public static HyperlinkStyle MouseOverHyperlink + { + get { return _MouseOverHyperlink; } + } + + private static HyperlinkStyle _VisitedHyperlink = new HyperlinkStyle(); + /// + /// Gets the style of the visited hyperlink. + /// + public static HyperlinkStyle VisitedHyperlink + { + get { return _VisitedHyperlink; } + } + } + + /// + /// Defines the text-markup hyperlink appearance style. + /// + public class HyperlinkStyle + { + /// + /// Initializes a new instance of the HyperlinkStyle class. + /// + public HyperlinkStyle() + { + } + + /// + /// Initializes a new instance of the HyperlinkStyle class. + /// + /// + /// + public HyperlinkStyle(Color textColor, eHyperlinkUnderlineStyle underlineStyle) + { + _TextColor = textColor; + _UnderlineStyle = underlineStyle; + } + + /// + /// Initializes a new instance of the HyperlinkStyle class. + /// + /// + /// + /// + public HyperlinkStyle(Color textColor, Color backColor, eHyperlinkUnderlineStyle underlineStyle) + { + _TextColor = textColor; + _BackColor = backColor; + _UnderlineStyle = underlineStyle; + } + private Color _TextColor = Color.Empty; + /// + /// Gets or sets hyperlink text color. + /// + public Color TextColor + { + get { return _TextColor; } + set + { + if (_TextColor != value) + { + _TextColor = value; + } + } + } + + private Color _BackColor = Color.Empty; + /// + /// Gets or sets hyperlink back color. + /// + public Color BackColor + { + get { return _BackColor; } + set + { + if (_BackColor != value) + { + _BackColor = value; + } + } + } + + private eHyperlinkUnderlineStyle _UnderlineStyle = eHyperlinkUnderlineStyle.None; + /// + /// Gets or sets the underline style for the hyperlink. + /// + public eHyperlinkUnderlineStyle UnderlineStyle + { + get { return _UnderlineStyle; } + set + { + if (_UnderlineStyle != value) + { + _UnderlineStyle = value; + } + } + } + + /// + /// Gets whether style has been changed from its default state. + /// + public bool IsChanged + { + get { return !_TextColor.IsEmpty || !_BackColor.IsEmpty || _UnderlineStyle != eHyperlinkUnderlineStyle.None; } + } + } + + /// + /// Defines hyperlink styles. + /// + public enum eHyperlinkUnderlineStyle + { + /// + /// Hyper links are not marked. + /// + None, + /// + /// Hyper links are underlined using solid line. + /// + SolidLine, + /// + /// Hyper links are underlined using dashed line. + /// + DashedLine + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/NewLine.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/NewLine.cs new file mode 100644 index 00000000..e132ba5d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/NewLine.cs @@ -0,0 +1,45 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class NewLine : MarkupElement + { + #region Internal Implementation + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { + // Causes layout manager to switch to the new line + this.Bounds = new Rectangle(0, 0, 0, d.CurrentFont.Height); + } + + /// + /// Gets or sets whether element size is valid. When size is not valid element Measure method will be called to validate size. + /// + public override bool IsSizeValid + { + get { return false; } + set { } + } + + public override void Render(MarkupDrawContext d) {} + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) { } + + /// + /// Returns whether layout manager switches to new line after processing this element. + /// + public override bool IsNewLineAfterElement + { + get { return true; } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Paragraph.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Paragraph.cs new file mode 100644 index 00000000..a54e772c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Paragraph.cs @@ -0,0 +1,27 @@ +using System; +using System.Text; +using System.Drawing; +using System.Xml; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +using DevComponents.UI.ContentManager; +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class Paragraph : Div + { + #region Internal Implementation + protected override void ArrangeInternal(Rectangle bounds, MarkupDrawContext d) + { + base.ArrangeInternal(bounds, d); + this.Bounds = new Rectangle(this.Bounds.X, this.Bounds.Y, this.Bounds.Width , this.Bounds.Height + d.CurrentFont.Height); + } + #endregion + } + + +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Span.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Span.cs new file mode 100644 index 00000000..77743982 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Span.cs @@ -0,0 +1,23 @@ +using System; +using System.Text; + +#if AdvTree +using DevComponents.Tree; +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class Span : Div + { + /// + /// Returns whether markup element is an block element that always consumes a whole line in layout. + /// + public override bool IsBlockElement + { + get { return false; } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Strike.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Strike.cs new file mode 100644 index 00000000..97578d60 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Strike.cs @@ -0,0 +1,34 @@ +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class Strike : MarkupElement + { + public override void Measure(Size availableSize, MarkupDrawContext d) + { + Bounds = Rectangle.Empty; + } + + public override void Render(MarkupDrawContext d) + { + d.StrikeOut = true; + } + + public override void RenderEnd(MarkupDrawContext d) + { + d.StrikeOut = false; + + base.RenderEnd(d); + } + + protected override void ArrangeCore(Rectangle finalRect, MarkupDrawContext d) + { + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Strong.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Strong.cs new file mode 100644 index 00000000..d8643be7 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Strong.cs @@ -0,0 +1,33 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class Strong : FontChangeElement + { + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + Font font = d.CurrentFont; + FontStyle style = d.CurrentFont.Style | FontStyle.Bold; + + if (!font.Bold && font.FontFamily.IsStyleAvailable(style)) + d.CurrentFont = new Font(d.CurrentFont, style); + else + font = null; + + if (font != null) + m_OldFont = font; + + base.SetFont(d); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/TextElement.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/TextElement.cs new file mode 100644 index 00000000..46934e8b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/TextElement.cs @@ -0,0 +1,222 @@ +using System.Drawing; +using System.Drawing.Drawing2D; +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class TextElement : MarkupElement + { + private static bool PadText; + static TextElement() + { + string lc = System.Windows.Forms.Application.CurrentCulture.TwoLetterISOLanguageName; + if (lc == "ja") + PadText = true; + } + #region Private Variables + private string m_Text = ""; + private bool m_TrailingSpace; + private bool m_EnablePrefixHandling = true; + #endregion + + #region Internal Implementation + public override void Measure(System.Drawing.Size availableSize, MarkupDrawContext d) + { +#if (FRAMEWORK20) + if (BarUtilities.UseTextRenderer) + { + eTextFormat format = eTextFormat.Default | eTextFormat.NoPadding; + if (!d.HotKeyPrefixVisible || m_EnablePrefixHandling) + format |= eTextFormat.HidePrefix; + Size size = Size.Empty; + if (m_TrailingSpace) + { + if (d.CurrentFont.Italic) + { + size = Size.Ceiling(TextDrawing.MeasureString(d.Graphics, m_Text, d.CurrentFont, 0, format)); + size.Width += (int)(d.Graphics.MeasureString("||", d.CurrentFont).Width / 4); + } + else + size = Size.Ceiling(TextDrawing.MeasureString(d.Graphics, m_Text + (BarFunctions.IsVista && m_Text.Length > 0 ? "|" : "||"), d.CurrentFont, 0, format)); + } + else + size = Size.Ceiling(TextDrawing.MeasureString(d.Graphics, m_Text, d.CurrentFont, 0, format)); + if (PadText) + { + size.Width += BarUtilities.TextMarkupCultureSpecificPadding; + size.Height += BarUtilities.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + else +#endif + { + using (StringFormat format = new StringFormat(StringFormat.GenericTypographic)) + { + format.FormatFlags = StringFormatFlags.NoWrap; + if (d.HotKeyPrefixVisible || !m_EnablePrefixHandling) + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; + else + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide; + + if (m_TrailingSpace) + { + if (d.CurrentFont.Italic) + { + Size size = Size.Ceiling(d.Graphics.MeasureString(m_Text, d.CurrentFont, 0, format)); + size.Width += (int)(d.Graphics.MeasureString("|", d.CurrentFont).Width / 4); + if (PadText) + { + size.Width += TextHelper.TextMarkupCultureSpecificPadding; + size.Height += TextHelper.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + else + { + Size size = Size.Ceiling(d.Graphics.MeasureString(m_Text + "|", d.CurrentFont, 0, format)); + if (PadText) + { + size.Width += TextHelper.TextMarkupCultureSpecificPadding; + size.Height += TextHelper.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + } + else + { + Size size = Size.Ceiling(d.Graphics.MeasureString(m_Text, d.CurrentFont, 0, format)); + if (PadText) + { + size.Width += TextHelper.TextMarkupCultureSpecificPadding; + size.Height += TextHelper.TextMarkupCultureSpecificPadding; + } + this.Bounds = new Rectangle(Point.Empty, size); + } + } + } + IsSizeValid = true; + } + + public override void Render(MarkupDrawContext d) + { + Rectangle r = this.Bounds; + r.Offset(d.Offset); + + if (!d.ClipRectangle.IsEmpty && !r.IntersectsWith(d.ClipRectangle)) + return; + + Graphics g = d.Graphics; + #if (FRAMEWORK20) + if (BarUtilities.UseTextRenderer) + { + eTextFormat format = eTextFormat.Default | eTextFormat.NoClipping | eTextFormat.NoPadding; + if (d.RightToLeft) format |= eTextFormat.RightToLeft; + if (!d.HotKeyPrefixVisible) + format |= eTextFormat.HidePrefix; + + if (!d.ClipRectangle.IsEmpty && r.Right > d.ClipRectangle.Right) + { + format|= eTextFormat.EndEllipsis; + r.Width -= (r.Right - d.ClipRectangle.Right); + } + TextDrawing.DrawString(g, m_Text, d.CurrentFont, d.CurrentForeColor, r, format); + + } + else + #endif + { + using (StringFormat format = new StringFormat(StringFormat.GenericTypographic)) + { + format.FormatFlags |= StringFormatFlags.NoWrap; + if (d.RightToLeft) format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + if (d.HotKeyPrefixVisible) + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show; + else + format.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide; + if (!d.ClipRectangle.IsEmpty && r.Right > d.ClipRectangle.Right) + { + format.Trimming = StringTrimming.EllipsisCharacter; + r.Width -= (r.Right - d.ClipRectangle.Right); + } + + using (SolidBrush brush = new SolidBrush(d.CurrentForeColor)) + g.DrawString(m_Text, d.CurrentFont, brush, r, format); + } + } + + if (d.StrikeOut == true) + { + // StrikeOut + + float descent = d.CurrentFont.FontFamily.GetCellDescent(d.CurrentFont.Style) * + d.CurrentFont.Size / d.CurrentFont.FontFamily.GetEmHeight(d.CurrentFont.Style) + 1; + + using (Pen pen = new Pen(d.CurrentForeColor, 1)) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + + float y = r.Top + (r.Height + descent) / 2; + + g.DrawLine(pen, r.X, y, r.Right - 1, y); + g.SmoothingMode = sm; + } + } + + if ((d.HyperLink && (d.HyperlinkStyle == null || d.HyperlinkStyle.UnderlineStyle != eHyperlinkUnderlineStyle.None)) || d.Underline) + { + // Underline Hyperlink + float descent = d.CurrentFont.FontFamily.GetCellDescent(d.CurrentFont.Style) * d.CurrentFont.Size / d.CurrentFont.FontFamily.GetEmHeight(d.CurrentFont.Style); + using (Pen pen = new Pen(d.CurrentForeColor, 1)) + { + if (d.HyperLink && d.HyperlinkStyle != null && d.HyperlinkStyle.UnderlineStyle == eHyperlinkUnderlineStyle.DashedLine) + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; + descent -= 1; + System.Drawing.Drawing2D.SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + g.DrawLine(pen, r.X, r.Bottom - descent, r.Right - 1, r.Bottom - descent); + g.SmoothingMode = sm; + } + } + + this.RenderBounds = r; + } + + protected override void ArrangeCore(System.Drawing.Rectangle finalRect, MarkupDrawContext d) {} + + public string Text + { + get { return m_Text; } + set + { + m_Text = value; + this.IsSizeValid = false; + } + } + + public bool TrailingSpace + { + get { return m_TrailingSpace; } + set + { + m_TrailingSpace = value; + this.IsSizeValid = false; + } + } + + public bool EnablePrefixHandling + { + get { return m_EnablePrefixHandling; } + set { m_EnablePrefixHandling = value; } + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Underline.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Underline.cs new file mode 100644 index 00000000..b2c3fdc1 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/TextMarkup/Underline.cs @@ -0,0 +1,46 @@ +using System; +using System.Text; +using System.Drawing; + +#if AdvTree +namespace DevComponents.Tree.TextMarkup +#elif DOTNETBAR +namespace DevComponents.DotNetBar.TextMarkup +#elif SUPERGRID +namespace DevComponents.SuperGrid.TextMarkup +#endif +{ + internal class Underline : FontChangeElement + { + #region Internal Implementation + protected override void SetFont(MarkupDrawContext d) + { + d.Underline = true; + //Font font = d.CurrentFont; + //FontStyle style = d.CurrentFont.Style | FontStyle.Underline; + + //if (!font.Underline && font.FontFamily.IsStyleAvailable(style)) + // d.CurrentFont = new Font(font, style); + //else + // font = null; + + //if (font != null) + // m_OldFont = font; + + base.SetFont(d); + } + + public override void MeasureEnd(Size availableSize, MarkupDrawContext d) + { + d.Underline = false; + base.MeasureEnd(availableSize, d); + } + + public override void RenderEnd(MarkupDrawContext d) + { + d.Underline = false; + base.RenderEnd(d); + } + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/MetroStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/MetroStyleFactory.cs new file mode 100644 index 00000000..e4263416 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/MetroStyleFactory.cs @@ -0,0 +1,615 @@ +using System.Drawing; +using DevComponents.DotNetBar.Metro.ColorTables; +using DevComponents.DotNetBar.Metro.Rendering; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Create the Metro Visual Style for SuperGridControl. + /// + public class MetroStyleFactory : VisualStyleFactory + { + private MetroPartColors _MetroPartColors; + + /// + /// Initializes a new instance of the MetroStyleFactory class. + /// + public MetroStyleFactory() + { + _MetroPartColors = MetroRender.GetColorTable().MetroPartColors; + } + + /// + /// Initializes a new instance of the MetroStyleFactory class. + /// + /// Metro Part Colors to Initialize Style with. + public MetroStyleFactory(MetroPartColors metroPartColors) + { + _MetroPartColors = metroPartColors; + + if (metroPartColors == null) + _MetroPartColors = MetroRender.GetColorTable().MetroPartColors; + } + + /// + /// Create the DefaultVisualStyle for SuperGridControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class.s + public override DefaultVisualStyles CreateStyle(ColorFactory factory) + { + DefaultVisualStyles visualStyle = new DefaultVisualStyles(); + + InitGridPanelStyle(visualStyle, factory); + + InitCellStyles(visualStyle, factory); + InitMergedCellStyles(visualStyle, factory); + InitAltRowCellStyles(visualStyle, factory); + + InitColumnStyles(visualStyle, factory); + InitAltColumnStyles(visualStyle, factory); + InitColumnHeaderStyles(visualStyle, factory); + + InitRowStyles(visualStyle, factory); + InitTextRowStyles(visualStyle, factory); + + InitGroupHeaderStyles(visualStyle, factory); + + InitFilterRowStyles(visualStyle, factory); + InitFilterColumnHeaderStyles(visualStyle, factory); + + InitGroupByStyles(visualStyle, factory); + + return (visualStyle); + } + + #region InitGridPanelStyle + + private void InitGridPanelStyle(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GridPanelVisualStyle style = new GridPanelVisualStyle(); + + MetroPartColors metroColors = _MetroPartColors; + style.Background = new Background(factory.GetColor(metroColors.EditControlBackColor)); + style.BorderColor = new BorderColor(factory.GetColor(metroColors.CanvasColorDarkShade)); + style.BorderPattern.All = LinePattern.Solid; + style.BorderThickness = new Thickness(1); + style.TextColor = factory.GetColor(metroColors.TextColor); + + style.TreeLineColor = factory.GetColor(metroColors.CanvasColorLighterShade); + style.HeaderLineColor = factory.GetColor(metroColors.CanvasColorDarkShade); + style.HorizontalLineColor = factory.GetColor(metroColors.CanvasColorLighterShade); + style.VerticalLineColor = factory.GetColor(metroColors.CanvasColorLighterShade); + + style.TreeLinePattern = LinePattern.Solid; + style.HorizontalLinePattern = LinePattern.Solid; + style.VerticalLinePattern = LinePattern.Solid; + style.HeaderHLinePattern = LinePattern.Solid; + style.HeaderVLinePattern = LinePattern.Solid; + + BaseTreeButtonVisualStyle tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(metroColors.CanvasColorDarkShade); + tstyle.HotBorderColor = factory.GetColor(metroColors.CanvasColorDarkShade); + tstyle.LineColor = factory.GetColor(metroColors.CanvasColorDarkShade); + tstyle.HotLineColor = factory.GetColor(metroColors.CanvasColorDarkShade); + tstyle.Background = new Background(factory.GetColor(metroColors.EditControlBackColor), factory.GetColor(metroColors.EditControlBackColor), 90); + tstyle.HotBackground = new Background(factory.GetColor(metroColors.CanvasColor), factory.GetColor(metroColors.CanvasColor), 90); + + style.CircleTreeButtonStyle.CollapseButton = tstyle; + style.CircleTreeButtonStyle.ExpandButton = tstyle; + + style.SquareTreeButtonStyle.CollapseButton = tstyle; + style.SquareTreeButtonStyle.ExpandButton = tstyle; + + style.TriangleTreeButtonStyle.CollapseButton = tstyle; + style.TriangleTreeButtonStyle.ExpandButton = tstyle; + + style.TriangleTreeButtonStyle.ExpandButton = tstyle; + visualStyle.GridPanelStyle = style; + } + + #endregion + + #region InitColumnHeaderStyles + + private void InitColumnHeaderStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + ColumnHeaderRowVisualStyle style = new ColumnHeaderRowVisualStyle(); + MetroPartColors metroColors = _MetroPartColors; + + style.FilterBorderColor = factory.GetColor(metroColors.CanvasColorDarkShade); + + style.FilterBackground = new Background( + Color.White, factory.GetColor(metroColors.CanvasColorDarkShade), 0); + + style.WhiteSpaceBackground = new Background(factory.GetColor(metroColors.CanvasColor)); + + style.RowHeader.Background = new + Background(factory.GetColor(metroColors.CanvasColorLighterShade)); + + style.RowHeader.BorderHighlightColor = GetBorderHighlight(); + + style.IndicatorBackground = new Background(factory.GetColor(metroColors.ComplementColor)); + style.IndicatorBorderColor = factory.GetColor(metroColors.ComplementColorDark); + + visualStyle.ColumnHeaderRowStyles[StyleType.Default] = style; + + style = style.Copy(); + + style.FilterBorderColor = factory.GetColor(metroColors.ComplementColor); + + style.FilterBackground = new Background( + Color.White, factory.GetColor(metroColors.ComplementColor), 45); + + visualStyle.ColumnHeaderRowStyles[StyleType.Selected] = style; + + style = style.Copy(); + + style.FilterBorderColor = factory.GetColor(metroColors.CanvasColorDarkShade); + + style.FilterBackground = new Background( + Color.White, factory.GetColor(metroColors.BaseColorDark), 0); + + style.RowHeader.Background = new Background( + factory.GetColor(metroColors.CanvasColorLightShade)); + + visualStyle.ColumnHeaderRowStyles[StyleType.MouseOver] = style; + visualStyle.ColumnHeaderRowStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region InitTextRowStyles + + private void InitTextRowStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + TextRowVisualStyle style = new TextRowVisualStyle(); + MetroPartColors metroColors = _MetroPartColors; + + style.Alignment = Alignment.MiddleCenter; + style.AllowWrap = Tbool.True; + + style.Background = new Background(factory.GetColor(metroColors.EditControlBackColor)); + style.BorderColor = new BorderColor(factory.GetColor(metroColors.CanvasColorLighterShade)); + + style.Padding.All = 2; + + style.TextColor = factory.GetColor(metroColors.TextColor); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(metroColors.CanvasColorLighterShade)); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(); + + visualStyle.TitleStyles[StyleType.Default] = style; + visualStyle.HeaderStyles[StyleType.Default] = style.Copy(); + visualStyle.FooterStyles[StyleType.Default] = style.Copy(); + + style = style.Copy(); + style.Background = new Background(Color.Transparent); + + visualStyle.CaptionStyles[StyleType.Default] = style; + } + + #endregion + + #region InitCellStyles + + private void InitCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + CellVisualStyle style = new CellVisualStyle(); + MetroPartColors metroColors = _MetroPartColors; + + style.Alignment = Alignment.MiddleLeft; + style.Background = new Background(factory.GetColor(metroColors.EditControlBackColor)); + style.BorderColor = new BorderColor(factory.GetColor(metroColors.CanvasColorLighterShade)); + style.BorderPattern.All = LinePattern.Solid; + style.BorderThickness.All = 0; + style.Font = SystemFonts.DefaultFont; + style.ImageAlignment = Alignment.MiddleLeft; + style.ImagePadding.All = 2; + style.Margin.All = 0; + style.ImageOverlay = ImageOverlay.None; + style.Padding.All = 0; + style.TextColor = metroColors.TextColor; + + visualStyle.CellStyles[StyleType.Default] = style; + + style = new CellVisualStyle(); + style.TextColor = metroColors.CanvasColorDarkShade; + visualStyle.CellStyles[StyleType.ReadOnly] = style; + + style = new CellVisualStyle(); + style.Background = GetDefaultSelectedBackground(factory); + style.TextColor = factory.GetColor(metroColors.BaseTextColor); + + visualStyle.CellStyles[StyleType.Selected] = style; + visualStyle.CellStyles[StyleType.ReadOnlySelected] = style.Copy(); + + style = new CellVisualStyle(); + style.Background = GetSelectedMouseOverBackground(factory); + style.TextColor = factory.GetColor(metroColors.BaseColorLightText); + + visualStyle.CellStyles[StyleType.SelectedMouseOver] = style; + visualStyle.CellStyles[StyleType.ReadOnlySelectedMouseOver] = style.Copy(); + + style = new CellVisualStyle(); + style.Background = new Background(factory.GetColor(metroColors.EditControlBackColor)); + + visualStyle.CellStyles[StyleType.Empty] = style; + } + + #endregion + + #region InitMergedCellStyles + + private void InitMergedCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.MergedCellStyles[StyleType.Default] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnly] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.Selected] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnlySelected] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.SelectedMouseOver] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnlySelectedMouseOver] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.Empty] = new CellVisualStyle(); + } + + #endregion + + #region InitAltRowCellStyles + + private void InitAltRowCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + MetroPartColors metroColors = _MetroPartColors; + visualStyle.AlternateRowCellStyles[StyleType.Default].Background = + new Background(factory.GetColor((metroColors.CanvasColor == metroColors.EditControlBackColor) ? metroColors.CanvasColorLightShade : metroColors.CanvasColor)); + } + + #endregion + + #region InitColumnStyles + + private void InitColumnStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + ColumnHeaderVisualStyle colStyle = new ColumnHeaderVisualStyle(); + MetroPartColors metroColors = _MetroPartColors; + + colStyle.Alignment = Alignment.MiddleCenter; + colStyle.BorderColor = new BorderColor(factory.GetColor(metroColors.CanvasColorLightShade)); + colStyle.BorderPattern.All = LinePattern.Solid; + colStyle.BorderThickness.All = 0; + colStyle.Font = SystemFonts.CaptionFont; + colStyle.ImageAlignment = Alignment.MiddleLeft; + colStyle.Margin.All = 0; + colStyle.ImageOverlay = ImageOverlay.None; + colStyle.TextColor = factory.GetColor(metroColors.TextColor); + + colStyle.Background = new Background(factory.GetColor(metroColors.CanvasColorLighterShade)); + + visualStyle.ColumnHeaderStyles[StyleType.Default] = colStyle; + visualStyle.ColumnHeaderStyles[StyleType.ReadOnly] = colStyle.Copy(); + visualStyle.ColumnHeaderStyles[StyleType.ReadOnly].Font = null; + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = new Background(factory.GetColor(metroColors.CanvasColorLightShade)); + visualStyle.ColumnHeaderStyles[StyleType.MouseOver] = colStyle; + visualStyle.ColumnHeaderStyles[StyleType.ReadOnlyMouseOver] = colStyle.Copy(); + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = GetDefaultSelectedColumnBackground(factory); + visualStyle.ColumnHeaderStyles[StyleType.Selected] = colStyle; + visualStyle.ColumnHeaderStyles[StyleType.ReadOnlySelected] = colStyle.Copy(); + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = GetSelectedColumnMouseOverBackground(); + visualStyle.ColumnHeaderStyles[StyleType.SelectedMouseOver] = colStyle; + visualStyle.ColumnHeaderStyles[StyleType.ReadOnlySelectedMouseOver] = colStyle.Copy(); + } + + #endregion + + #region InitAltColumnStyles + + private void InitAltColumnStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + MetroPartColors metroColors = _MetroPartColors; + visualStyle.AlternateColumnCellStyles[StyleType.Default].Background = + new Background(factory.GetColor(metroColors.EditControlBackColor)); + } + + #endregion + + #region InitRowStyles + + private void InitRowStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.RowStyles[StyleType.Default] = GetDefaultRowStyle(); + visualStyle.RowStyles[StyleType.MouseOver] = GetMouseOverRowStyle(); + visualStyle.RowStyles[StyleType.SelectedMouseOver] = GetSelectedMouseOverRowStyle(visualStyle, factory); + } + + #region GetDefaultRowStyle + + private RowVisualStyle GetDefaultRowStyle() + { + MetroPartColors metroColors = _MetroPartColors; + + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = new Background(metroColors.EditControlBackColor); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + + style.Font = SystemFonts.DefaultFont; + style.TextColor = metroColors.TextColor; + + Background bg = new Background(metroColors.CanvasColorLighterShade); + style.Background = bg; + + bg = new Background(metroColors.BaseColor); + style.ActiveRowBackground = bg; + style.DirtyMarkerBackground = new Background(metroColors.BaseColorDarker); + style.BorderHighlightColor = GetBorderHighlight(); + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #region GetMouseOverRowStyle + + private RowVisualStyle GetMouseOverRowStyle() + { + MetroPartColors metroColors = _MetroPartColors; + + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = new Background(metroColors.EditControlBackColor); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + style.Background = new Background(metroColors.CanvasColorLighterShade); + style.ActiveRowBackground = new Background(metroColors.CanvasColorLightShade); + + Background bg = new Background(metroColors.CanvasColorLightShade); + style.Background = bg; + + bg = new Background(metroColors.BaseColor); + style.ActiveRowBackground = bg; + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #region GetSelectedMouseOverRowStyle + + private RowVisualStyle GetSelectedMouseOverRowStyle(DefaultVisualStyles visualStyle, ColorFactory factory) + { + MetroPartColors metroColors = _MetroPartColors; + + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = GetDefaultSelectedBackground(factory); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + style.Background = new Background(metroColors.BaseColor); + style.ActiveRowBackground = new Background(metroColors.BaseColor); + + rowStyle.RowHeaderStyle = style; + + visualStyle.RowStyles[StyleType.Selected] = rowStyle; + + rowStyle = new RowVisualStyle(); + rowStyle.Background = GetSelectedColumnMouseOverBackground(); + + style = new RowHeaderVisualStyle(); + style.Background = new Background(metroColors.BaseColor); + style.ActiveRowBackground = new Background(metroColors.BaseColor); + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #endregion + + #region InitGroupHeaderStyles + + private void InitGroupHeaderStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + MetroPartColors metroColors = _MetroPartColors; + + GroupHeaderVisualStyle style = new GroupHeaderVisualStyle(); + + style.AllowWrap = Tbool.True; + style.Alignment = Alignment.MiddleLeft; + style.Font = SystemFonts.DefaultFont; + + style.Background = new + Background(factory.GetColor(metroColors.EditControlBackColor)); + + style.UnderlineColor = factory.GetColor(metroColors.ComplementColor); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(metroColors.CanvasColorLighterShade)); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(); + style.RowHeaderStyle.Font = SystemFonts.DefaultFont; + + style.TextColor = metroColors.TextColor; + + visualStyle.GroupHeaderStyles[StyleType.Default] = style; + } + + #endregion + + #region GetDefaultSelectedColumnBackground + private Background GetDefaultSelectedColumnBackground(ColorFactory factory) + { + MetroPartColors metroColors = _MetroPartColors; + + Background bg = new Background(factory.GetColor(metroColors.CanvasColorLighterShade), + factory.GetColor(metroColors.CanvasColorLightShade)); + + return (bg); + } + #endregion + + #region GetDefaultSelectedBackground + + private Background GetDefaultSelectedBackground(ColorFactory factory) + { + MetroPartColors metroColors = _MetroPartColors; + + Background bg = new Background(factory.GetColor(metroColors.BaseColor)); + + return (bg); + } + + #endregion + + #region GetDefaultSelectedColumnMouseOverStyle + + private Background GetSelectedColumnMouseOverBackground() + { + MetroPartColors metroColors = _MetroPartColors; + + return (new Background(metroColors.BaseColorLight)); + } + + #endregion + + #region GetDefaultSelectedMouseOverStyle + + private Background GetSelectedMouseOverBackground(ColorFactory factory) + { + MetroPartColors metroColors = _MetroPartColors; + + return (new Background(factory.GetColor(metroColors.BaseColorLight))); + } + + #endregion + + #region InitFilterColumnHeaderStyles + + private void InitFilterColumnHeaderStyles( + DefaultVisualStyles visualStyle, ColorFactory factory) + { + FilterColumnHeaderVisualStyle colStyle = new FilterColumnHeaderVisualStyle(); + MetroPartColors metroColors = _MetroPartColors; + + colStyle.Alignment = Alignment.MiddleCenter; + colStyle.Font = SystemFonts.CaptionFont; + + colStyle.TextColor = factory.GetColor(metroColors.TextColor); + colStyle.ErrorTextColor = factory.GetColor(metroColors.BaseColorDarker); + + colStyle.Background = new Background(factory.GetColor(metroColors.CanvasColorLighterShade)); + colStyle.GripBarBackground = new Background(factory.GetColor(metroColors.CanvasColor)); + visualStyle.FilterColumnHeaderStyles[StyleType.Default] = colStyle; + + colStyle = new FilterColumnHeaderVisualStyle(); + colStyle.Background = new Background(factory.GetColor(metroColors.CanvasColorLightShade)); + visualStyle.FilterColumnHeaderStyles[StyleType.MouseOver] = colStyle; + + colStyle = new FilterColumnHeaderVisualStyle(); + colStyle.Background = GetDefaultSelectedColumnBackground(factory); + visualStyle.FilterColumnHeaderStyles[StyleType.Selected] = colStyle; + + colStyle = new FilterColumnHeaderVisualStyle(); + colStyle.Background = GetSelectedColumnMouseOverBackground(); + visualStyle.FilterColumnHeaderStyles[StyleType.SelectedMouseOver] = colStyle; + } + + #endregion + + #region InitFilterRowStyles + + private void InitFilterRowStyles( + DefaultVisualStyles visualStyle, ColorFactory factory) + { + FilterRowVisualStyle style = new FilterRowVisualStyle(); + MetroPartColors metroColors = _MetroPartColors; + + style.FilterBorderColor = factory.GetColor(0x787D87); + + style.FilterBackground = new Background( + Color.White, factory.GetColor(metroColors.CanvasColorDarkShade), 0); + + style.WhiteSpaceBackground = new Background(factory.GetColor(metroColors.EditControlBackColor)); + + style.RowHeader.Background = new + Background(factory.GetColor(metroColors.CanvasColorLighterShade)); + + style.RowHeader.BorderHighlightColor = GetBorderHighlight(); + + visualStyle.FilterRowStyles[StyleType.Default] = style; + + style = style.Copy(); + + style.FilterBackground = new Background( + Color.White, factory.GetColor(metroColors.ComplementColor), 45); + + visualStyle.FilterRowStyles[StyleType.Selected] = style; + + style = style.Copy(); + + style.FilterBackground = new Background( + Color.White, factory.GetColor(metroColors.BaseColorDark), 0); + + style.RowHeader.Background = new + Background(factory.GetColor(metroColors.CanvasColorLightShade)); + + visualStyle.FilterRowStyles[StyleType.MouseOver] = style; + visualStyle.FilterRowStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region InitGroupByStyles + + private void InitGroupByStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GroupByVisualStyle style = new GroupByVisualStyle(); + MetroPartColors metroColors = _MetroPartColors; + + style.Alignment = Alignment.MiddleCenter; + style.GroupBoxConnectorColor = factory.GetColor(metroColors.BaseColorDark); // Panel border color + style.GroupBoxBorderColor = factory.GetColor(metroColors.BaseColorDark); + + style.InsertMarkerBorderColor = factory.GetColor(metroColors.BaseColorDark); + style.InsertMarkerBackground = GetSelectedColumnMouseOverBackground(); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(metroColors.CanvasColorLighterShade)); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(); + + style.TextColor = factory.GetColor(0x363636); // Col text color + style.GroupBoxBackground = new Background(factory.GetColor(metroColors.CanvasColorLighterShade)); // col background + visualStyle.GroupByStyles[StyleType.Default] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = new Background(factory.GetColor(metroColors.CanvasColorLightShade)); // col background + visualStyle.GroupByStyles[StyleType.MouseOver] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = GetDefaultSelectedColumnBackground(factory); // col background + visualStyle.GroupByStyles[StyleType.Selected] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = GetSelectedColumnMouseOverBackground(); // col background + visualStyle.GroupByStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region GetBorderHighlight + + private Color GetBorderHighlight() + { + return (Color.Transparent); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/Office2010BlackStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/Office2010BlackStyleFactory.cs new file mode 100644 index 00000000..cae45d72 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/Office2010BlackStyleFactory.cs @@ -0,0 +1,590 @@ +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Office2010BlackStyleFactory + /// + public class Office2010BlackStyleFactory : VisualStyleFactory + { + /// + /// Create the DefaultVisualStyle for SuperGridControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class.s + public override DefaultVisualStyles CreateStyle(ColorFactory factory) + { + DefaultVisualStyles visualStyle = new DefaultVisualStyles(); + + InitGridPanelStyle(visualStyle, factory); + + InitCellStyles(visualStyle, factory); + InitMergedCellStyles(visualStyle, factory); + InitAltRowCellStyles(visualStyle, factory); + + InitColumnStyles(visualStyle, factory); + InitAltColumnStyles(visualStyle, factory); + InitColumnHeaderStyles(visualStyle, factory); + + InitRowStyles(visualStyle, factory); + InitTextRowStyles(visualStyle, factory); + + InitGroupHeaderStyles(visualStyle, factory); + + InitFilterRowStyles(visualStyle, factory); + InitFilterColumnHeaderStyles(visualStyle, factory); + + InitGroupByStyles(visualStyle, factory); + + return (visualStyle); + } + + #region InitGridPanelStyle + + private void InitGridPanelStyle(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GridPanelVisualStyle style = new GridPanelVisualStyle(); + + style.Background = new Background(factory.GetColor(0xFFFFFF)); + style.BorderColor = new BorderColor(factory.GetColor(0x313131)); + style.BorderPattern.All = LinePattern.Solid; + style.BorderThickness = new Thickness(1); + style.TextColor = factory.GetColor(0x000000); + + style.TreeLineColor = factory.GetColor(0x484848); + style.HeaderLineColor = factory.GetColor(0x444444); + style.HorizontalLineColor = factory.GetColor(0xDADCDD); + style.VerticalLineColor = factory.GetColor(0xDADCDD); + + style.TreeLinePattern = LinePattern.Solid; + style.HorizontalLinePattern = LinePattern.Solid; + style.VerticalLinePattern = LinePattern.Solid; + style.HeaderHLinePattern = LinePattern.Solid; + style.HeaderVLinePattern = LinePattern.Solid; + + BaseTreeButtonVisualStyle tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(Color.SlateGray); + tstyle.HotBorderColor = factory.GetColor(Color.SlateGray); + tstyle.LineColor = factory.GetColor(Color.DarkSlateGray); + tstyle.HotLineColor = factory.GetColor(Color.DarkSlateGray); + tstyle.Background = new Background(factory.GetColor(Color.White), factory.GetColor(Color.Gainsboro), 90); + tstyle.HotBackground = new Background(factory.GetColor(Color.White), factory.GetColor(Color.Gainsboro), 90); + + style.CircleTreeButtonStyle.CollapseButton = tstyle; + style.CircleTreeButtonStyle.ExpandButton = tstyle; + + style.SquareTreeButtonStyle.CollapseButton = tstyle; + style.SquareTreeButtonStyle.ExpandButton = tstyle; + + tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(Color.Black); + tstyle.HotBorderColor = factory.GetColor(0x27C7F7); + tstyle.Background = new Background(factory.GetColor(Color.Black)); + tstyle.HotBackground = new Background(factory.GetColor(0xC7EBFA)); + + style.TriangleTreeButtonStyle.CollapseButton = tstyle; + + tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(Color.DimGray); + tstyle.HotBorderColor = factory.GetColor(0x27C7F7); + tstyle.Background = new Background(factory.GetColor(Color.White)); + tstyle.HotBackground = new Background(factory.GetColor(0xC7EBFA)); + + style.TriangleTreeButtonStyle.ExpandButton = tstyle; + + visualStyle.GridPanelStyle = style; + } + + #endregion + + #region InitColumnHeaderStyles + + private void InitColumnHeaderStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + ColumnHeaderRowVisualStyle style = new ColumnHeaderRowVisualStyle(); + + style.FilterBorderColor = factory.GetColor(Color.LightGray); + style.FilterBackground = new Background(Color.White, factory.GetColor(Color.LightGray), 0); + + style.WhiteSpaceBackground = new Background(factory.GetColor(0x797979)); + style.RowHeader.Background = new Background(factory.GetColor(0x6A6A6A), factory.GetColor(0x595959), BackFillType.ForwardDiagonal); + + style.RowHeader.BorderHighlightColor = GetBorderHighlight(factory); + + style.IndicatorBackground = new Background(factory.GetColor(0xF9FAFB), factory.GetColor(0xD7DAE2), BackFillType.Angle); + style.IndicatorBorderColor = factory.GetColor(0xBDCFE8); + + visualStyle.ColumnHeaderRowStyles[StyleType.Default] = style; + + style = style.Copy(); + + style.FilterBorderColor = factory.GetColor(Color.LightGreen); + style.FilterBackground = new Background(Color.White, factory.GetColor(Color.Green), 45); + + visualStyle.ColumnHeaderRowStyles[StyleType.Selected] = style; + + style = style.Copy(); + + style.FilterBorderColor = factory.GetColor(0x797979); + style.FilterBackground = new Background(Color.White, factory.GetColor(0xE2AA00), 0); + + style.RowHeader.Background = new Background(factory.GetColor(0x8E8E8E)); + + visualStyle.ColumnHeaderRowStyles[StyleType.MouseOver] = style; + visualStyle.ColumnHeaderRowStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region InitTextRowStyles + + private void InitTextRowStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + TextRowVisualStyle style = new TextRowVisualStyle(); + + style.Alignment = Alignment.MiddleCenter; + style.AllowWrap = Tbool.True; + + style.Background = new Background(factory.GetColor(0x6A6A6A)); + style.BorderColor = new BorderColor(factory.GetColor(0x444444)); + + style.Padding.All = 2; + + style.TextColor = factory.GetColor(0xE2E2E2); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(0x6A6A6A)); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(factory); + + visualStyle.TitleStyles[StyleType.Default] = style; + visualStyle.HeaderStyles[StyleType.Default] = style.Copy(); + visualStyle.FooterStyles[StyleType.Default] = style.Copy(); + + style = style.Copy(); + style.Background = new Background(factory.GetColor(0x686868)); + + visualStyle.CaptionStyles[StyleType.Default] = style; + } + + #endregion + + #region InitCellStyles + + private void InitCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + CellVisualStyle style = new CellVisualStyle(); + + style.Alignment = Alignment.MiddleLeft; + style.Background = new Background(factory.GetColor(Color.White)); + style.Font = SystemFonts.DefaultFont; + style.ImageAlignment = Alignment.MiddleLeft; + style.ImagePadding.All = 2; + style.Margin.All = 0; + style.ImageOverlay = ImageOverlay.None; + style.Padding.All = 0; + style.TextColor = Color.Black; + + visualStyle.CellStyles[StyleType.Default] = style; + + style = new CellVisualStyle(); + style.Background = GetDefaultSelectedBackground(factory); + + visualStyle.CellStyles[StyleType.Selected] = style; + + style = new CellVisualStyle(); + style.Background = GetSelectedMouseOverBackground(factory); + + visualStyle.CellStyles[StyleType.SelectedMouseOver] = style; + + style = new CellVisualStyle(); + style.Background = new Background(factory.GetColor(0xF4F4F4)); + + visualStyle.CellStyles[StyleType.Empty] = style; + } + + #endregion + + #region InitMergedCellStyles + + private void InitMergedCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.MergedCellStyles[StyleType.Default] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnly] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.Selected] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnlySelected] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.SelectedMouseOver] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnlySelectedMouseOver] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.Empty] = new CellVisualStyle(); + } + + #endregion + + #region InitAltRowCellStyles + + private void InitAltRowCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.AlternateRowCellStyles[StyleType.Default].Background = + new Background(factory.GetColor(0xF4F4F4)); + } + + #endregion + + #region InitColumnStyles + + private void InitColumnStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + ColumnHeaderVisualStyle colStyle = new ColumnHeaderVisualStyle(); + + colStyle.Alignment = Alignment.MiddleCenter; + colStyle.Font = SystemFonts.CaptionFont; + colStyle.ImageAlignment = Alignment.MiddleLeft; + colStyle.Margin.All = 0; + colStyle.ImageOverlay = ImageOverlay.None; + colStyle.TextColor = factory.GetColor(0xE2E2E2); + + colStyle.Background = new Background(factory.GetColor(0x6A6A6A)); + visualStyle.ColumnHeaderStyles[StyleType.Default] = colStyle; + colStyle = new ColumnHeaderVisualStyle(); + + colStyle.Background = new Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6)); + colStyle.TextColor = factory.GetColor(0x444444); + visualStyle.ColumnHeaderStyles[StyleType.MouseOver] = colStyle; + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = GetDefaultSelectedColumnBackground(factory); + colStyle.TextColor = factory.GetColor(0x444444); + visualStyle.ColumnHeaderStyles[StyleType.Selected] = colStyle; + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = GetSelectedColumnMouseOverBackground(factory); + colStyle.TextColor = factory.GetColor(0x444444); + visualStyle.ColumnHeaderStyles[StyleType.SelectedMouseOver] = colStyle; + } + + #endregion + + #region InitAltColumnStyles + + private void InitAltColumnStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.AlternateColumnCellStyles[StyleType.Default].Background = + new Background(factory.GetColor(0xEAF2FB)); + } + + #endregion + + #region InitRowStyles + + private void InitRowStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.RowStyles[StyleType.Default] = GetDefaultRowStyle(factory); + visualStyle.RowStyles[StyleType.MouseOver] = GetMouseOverRowStyle(factory); + visualStyle.RowStyles[StyleType.SelectedMouseOver] = GetSelectedMouseOverRowStyle(visualStyle, factory); + } + + #region GetDefaultRowStyle + + private RowVisualStyle GetDefaultRowStyle(ColorFactory factory) + { + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = new Background(factory.GetColor(Color.White)); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + + style.Font = SystemFonts.DefaultFont; + style.TextColor = factory.GetColor(0x1E395B); + + Background bg = new Background(); + BackColorBlend bcb = new BackColorBlend(); + + bcb.Colors = new Color[3]; + bcb.Colors[0] = factory.GetColor(0x6A6A6A); + bcb.Colors[1] = factory.GetColor(0x6A6A6A); + bcb.Colors[2] = factory.GetColor(0x5E5E5E); + + bcb.Positions = new float[3]; + bcb.Positions[0] = 0f; + bcb.Positions[1] = .75f; + bcb.Positions[2] = 1f; + + bg.BackColorBlend = bcb; + bg.GradientAngle = 0; + + style.Background = bg; + style.TextColor = factory.GetColor(0xE2E2E2); + + bg = new Background(factory.GetColor(0x6A6A6A)); + + style.ActiveRowBackground = bg; + style.DirtyMarkerBackground = new Background(factory.GetColor(0xAE054F), factory.GetColor(0xE75E94), BackFillType.VerticalCenter); + style.BorderHighlightColor = GetBorderHighlight(factory); + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #region GetMouseOverRowStyle + + private RowVisualStyle GetMouseOverRowStyle(ColorFactory factory) + { + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = new Background(Color.White); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + style.Background = new Background(Color.Plum); + style.ActiveRowBackground = new Background(Color.Blue); + + Background bg = new Background(); + BackColorBlend bcb = new BackColorBlend(); + + bcb.Colors = new Color[3]; + bcb.Colors[0] = factory.GetColor(0xFFE575); + bcb.Colors[1] = factory.GetColor(0xFFE575); + bcb.Colors[2] = factory.GetColor(0xF2CD66); + + bcb.Positions = new float[3]; + bcb.Positions[0] = 0f; + bcb.Positions[1] = .75f; + bcb.Positions[2] = 1f; + + bg.BackColorBlend = bcb; + bg.GradientAngle = 0; + + style.Background = bg; + style.TextColor = factory.GetColor(0x444444); + + bg = new Background(); + bcb = new BackColorBlend(); + + bcb.Colors = new Color[3]; + bcb.Colors[0] = Color.FromArgb(254 - 20, 240 - 20, 214 - 20); + bcb.Colors[1] = Color.FromArgb(254 - 30, 199 - 30, 104 - 30); + bcb.Colors[2] = Color.FromArgb(229 - 30, 133 - 30, 0); + + bcb.Positions = new float[3]; + bcb.Positions[0] = 0f; + bcb.Positions[1] = .75f; + bcb.Positions[2] = 1f; + + bg.BackColorBlend = bcb; + bg.GradientAngle = 0; + + style.ActiveRowBackground = bg; + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #region GetSelectedMouseOverRowStyle + + private RowVisualStyle GetSelectedMouseOverRowStyle(DefaultVisualStyles visualStyle, ColorFactory factory) + { + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = GetDefaultSelectedBackground(factory); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + style.Background = new Background(factory.GetColor(0xBABABA)); + style.ActiveRowBackground = new Background(factory.GetColor(0xBABABA)); + style.TextColor = factory.GetColor(0x444444); + + rowStyle.RowHeaderStyle = style; + + visualStyle.RowStyles[StyleType.Selected] = rowStyle; + + rowStyle = new RowVisualStyle(); + rowStyle.Background = GetSelectedColumnMouseOverBackground(factory); + + style = new RowHeaderVisualStyle(); + style.Background = new Background(factory.GetColor(0xFFEB91)); + style.ActiveRowBackground = new Background(factory.GetColor(0xB7DBFF)); + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #endregion + + #region InitGroupHeaderStyles + + private void InitGroupHeaderStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GroupHeaderVisualStyle style = new GroupHeaderVisualStyle(); + + style.AllowWrap = Tbool.True; + style.Alignment = Alignment.MiddleLeft; + style.Font = SystemFonts.DefaultFont; + + style.Background = new + Background(factory.GetColor(0xFFFFFF)); + + style.UnderlineColor = factory.GetColor(0x444444); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(0xBABABA)); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(factory); + style.RowHeaderStyle.Font = SystemFonts.DefaultFont; + + visualStyle.GroupHeaderStyles[StyleType.Default] = style; + } + + #endregion + + #region GetDefaultSelectedColumnBackground + private Background GetDefaultSelectedColumnBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xFFD359), factory.GetColor(0xFFEF71))); + } + #endregion + + #region GetDefaultSelectedBackground + + private Background GetDefaultSelectedBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xB7DBFF))); + } + + #endregion + + #region GetDefaultSelectedColumnMouseOverStyle + + private Background GetSelectedColumnMouseOverBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xFFE063), factory.GetColor(0xFFF9A2))); + } + + #endregion + + #region GetDefaultSelectedMouseOverStyle + + private Background GetSelectedMouseOverBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xB0D4F7))); + } + + #endregion + + #region InitFilterColumnHeaderStyles + + private void InitFilterColumnHeaderStyles( + DefaultVisualStyles visualStyle, ColorFactory factory) + { + FilterColumnHeaderVisualStyle colStyle = new FilterColumnHeaderVisualStyle(); + + colStyle.Alignment = Alignment.MiddleCenter; + colStyle.Font = SystemFonts.CaptionFont; + + colStyle.TextColor = factory.GetColor(0xE2E2E2); + colStyle.ErrorTextColor = Color.Red; + + colStyle.Background = new Background(factory.GetColor(0x6A6A6A)); + colStyle.GripBarBackground = new Background(factory.GetColor(0x797979)); + visualStyle.FilterColumnHeaderStyles[StyleType.Default] = colStyle; + + colStyle = new FilterColumnHeaderVisualStyle(); + colStyle.Background = new Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6)); + colStyle.TextColor = factory.GetColor(0x444444); + visualStyle.FilterColumnHeaderStyles[StyleType.MouseOver] = colStyle; + + colStyle = new FilterColumnHeaderVisualStyle(); + colStyle.Background = GetDefaultSelectedColumnBackground(factory); + visualStyle.FilterColumnHeaderStyles[StyleType.Selected] = colStyle; + + colStyle = new FilterColumnHeaderVisualStyle(); + colStyle.Background = GetSelectedColumnMouseOverBackground(factory); + visualStyle.FilterColumnHeaderStyles[StyleType.SelectedMouseOver] = colStyle; + } + + #endregion + + #region InitFilterRowStyles + + private void InitFilterRowStyles( + DefaultVisualStyles visualStyle, ColorFactory factory) + { + FilterRowVisualStyle style = new FilterRowVisualStyle(); + + style.FilterBorderColor = GetBorderHighlight(factory); + style.FilterBackground = new Background(Color.White, factory.GetColor(Color.LightGray), 0); + + style.WhiteSpaceBackground = new Background(factory.GetColor(0x797979)); + + style.RowHeader.Background = new Background(factory.GetColor(0x6A6A6A), + factory.GetColor(0x595959), BackFillType.ForwardDiagonal); + + style.RowHeader.BorderHighlightColor = GetBorderHighlight(factory); + + visualStyle.FilterRowStyles[StyleType.Default] = style; + + style = style.Copy(); + + style.FilterBackground = new Background(Color.White, factory.GetColor(Color.Green), 45); + + visualStyle.FilterRowStyles[StyleType.Selected] = style; + + style = style.Copy(); + + style.FilterBackground = new Background(Color.White, factory.GetColor(0xE2AA00), 0); + style.RowHeader.Background = new Background(factory.GetColor(0x8E8E8E)); + + visualStyle.FilterRowStyles[StyleType.MouseOver] = style; + visualStyle.FilterRowStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region InitGroupByStyles + + private void InitGroupByStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GroupByVisualStyle style = new GroupByVisualStyle(); + + style.Alignment = Alignment.MiddleCenter; + style.GroupBoxConnectorColor = factory.GetColor(0x313131); // Panel border color + style.GroupBoxBorderColor = factory.GetColor(0x313131); + + style.InsertMarkerBorderColor = factory.GetColor(0x313131); + style.InsertMarkerBackground = new Background(factory.GetColor(Color.Red)); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(0x6A6A6A), factory.GetColor(0x595959), BackFillType.ForwardDiagonal); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(factory); + + style.TextColor = factory.GetColor(0x363636); // Col text color + style.GroupBoxBackground = new Background(factory.GetColor(0x6A6A6A)); // col background + visualStyle.GroupByStyles[StyleType.Default] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = new Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6)); // col background + visualStyle.GroupByStyles[StyleType.MouseOver] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = GetDefaultSelectedColumnBackground(factory); // col background + visualStyle.GroupByStyles[StyleType.Selected] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = GetSelectedColumnMouseOverBackground(factory); // col background + visualStyle.GroupByStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region GetBorderHighlight + + private Color GetBorderHighlight(ColorFactory factory) + { + return factory.GetColor("10FFFFFF"); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/Office2010BlueStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/Office2010BlueStyleFactory.cs new file mode 100644 index 00000000..cd7192d4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/Office2010BlueStyleFactory.cs @@ -0,0 +1,593 @@ +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Create the Office 2010 Blue Visual Style for SuperGridControl. + /// + public class Office2010BlueStyleFactory : VisualStyleFactory + { + /// + /// Create the DefaultVisualStyle for SuperGridControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class.s + public override DefaultVisualStyles CreateStyle(ColorFactory factory) + { + DefaultVisualStyles visualStyle = new DefaultVisualStyles(); + + InitGridPanelStyle(visualStyle, factory); + + InitCellStyles(visualStyle, factory); + InitMergedCellStyles(visualStyle, factory); + InitAltRowCellStyles(visualStyle, factory); + + InitColumnStyles(visualStyle, factory); + InitAltColumnStyles(visualStyle, factory); + InitColumnHeaderStyles(visualStyle, factory); + + InitRowStyles(visualStyle, factory); + InitTextRowStyles(visualStyle, factory); + + InitGroupHeaderStyles(visualStyle, factory); + + InitFilterRowStyles(visualStyle, factory); + InitFilterColumnHeaderStyles(visualStyle, factory); + + InitGroupByStyles(visualStyle, factory); + + return (visualStyle); + } + + #region InitGridPanelStyle + + private void InitGridPanelStyle(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GridPanelVisualStyle style = new GridPanelVisualStyle(); + + style.Background = new Background(factory.GetColor(0xFFFFFF)); + style.BorderColor = new BorderColor(factory.GetColor(0x849DBD)); + style.BorderPattern.All = LinePattern.Solid; + style.BorderThickness = new Thickness(1); + style.TextColor = factory.GetColor(0x000000); + + style.TreeLineColor = factory.GetColor(0x484848); + style.HeaderLineColor = factory.GetColor(0x849DBD); + style.HorizontalLineColor = factory.GetColor(0xC4D9F6); + style.VerticalLineColor = factory.GetColor(0xC4D9F6); + + style.TreeLinePattern = LinePattern.Solid; + style.HorizontalLinePattern = LinePattern.Solid; + style.VerticalLinePattern = LinePattern.Solid; + style.HeaderHLinePattern = LinePattern.Solid; + style.HeaderVLinePattern = LinePattern.Solid; + + BaseTreeButtonVisualStyle tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(Color.SlateGray); + tstyle.HotBorderColor = factory.GetColor(Color.SlateGray); + tstyle.LineColor = factory.GetColor(Color.DarkSlateGray); + tstyle.HotLineColor = factory.GetColor(Color.DarkSlateGray); + tstyle.Background = new Background(factory.GetColor(Color.White), factory.GetColor(Color.Gainsboro), 90); + tstyle.HotBackground = new Background(factory.GetColor(Color.White), factory.GetColor(Color.Gainsboro), 90); + + style.CircleTreeButtonStyle.CollapseButton = tstyle; + style.CircleTreeButtonStyle.ExpandButton = tstyle; + + style.SquareTreeButtonStyle.CollapseButton = tstyle; + style.SquareTreeButtonStyle.ExpandButton = tstyle; + + tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(Color.Black); + tstyle.HotBorderColor = factory.GetColor(0x27C7F7); + tstyle.Background = new Background(factory.GetColor(Color.Black)); + tstyle.HotBackground = new Background(factory.GetColor(0xC7EBFA)); + + style.TriangleTreeButtonStyle.CollapseButton = tstyle; + + tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(Color.DimGray); + tstyle.HotBorderColor = factory.GetColor(0x27C7F7); + tstyle.Background = new Background(factory.GetColor(Color.White)); + tstyle.HotBackground = new Background(factory.GetColor(0xC7EBFA)); + + style.TriangleTreeButtonStyle.ExpandButton = tstyle; + + visualStyle.GridPanelStyle = style; + } + + #endregion + + #region InitColumnHeaderStyles + + private void InitColumnHeaderStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + ColumnHeaderRowVisualStyle style = new ColumnHeaderRowVisualStyle(); + + style.FilterBorderColor = factory.GetColor(0x697D96); + style.FilterBackground = new Background(Color.White, factory.GetColor(0x5B92FF), 0); + + style.WhiteSpaceBackground = new Background(factory.GetColor(0xCFDDEE)); + + style.RowHeader.Background = new Background( + factory.GetColor(0xEFF5FB), factory.GetColor(0xE2EDFA), BackFillType.ForwardDiagonal); + + style.RowHeader.BorderHighlightColor = GetBorderHighlight(factory); + + style.IndicatorBackground = new Background(factory.GetColor(0x4488E5)); + style.IndicatorBorderColor = factory.GetColor(0x1F48A1); + + visualStyle.ColumnHeaderRowStyles[StyleType.Default] = style; + + style = style.Copy(); + + style.FilterBorderColor = factory.GetColor(Color.Green); + style.FilterBackground = new Background(Color.White, factory.GetColor(Color.Green), 0); + + visualStyle.ColumnHeaderRowStyles[StyleType.Selected] = style; + + style = style.Copy(); + + style.FilterBorderColor = factory.GetColor(0x697D96); + style.FilterBackground = new Background(Color.White, factory.GetColor(0xE2AA00), 0); + + style.RowHeader.Background = new Background( + factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6), BackFillType.Angle); + + visualStyle.ColumnHeaderRowStyles[StyleType.MouseOver] = style; + visualStyle.ColumnHeaderRowStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region InitTextRowStyles + + private void InitTextRowStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + TextRowVisualStyle style = new TextRowVisualStyle(); + + style.Alignment = Alignment.MiddleCenter; + style.AllowWrap = Tbool.True; + + style.Background = new Background(factory.GetColor(0xEFF5FB), factory.GetColor(0xE2ECFA), BackFillType.Angle); + style.BorderColor = new BorderColor(factory.GetColor(0x849DBD)); + + style.Padding.All = 2; + + style.TextColor = factory.GetColor(0x1E395B); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(0xEFF5FB), factory.GetColor(0xE2ECFA), BackFillType.Angle); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(factory); + + visualStyle.TitleStyles[StyleType.Default] = style; + visualStyle.HeaderStyles[StyleType.Default] = style.Copy(); + visualStyle.FooterStyles[StyleType.Default] = style.Copy(); + + style = style.Copy(); + style.Background = new Background(Color.Transparent); + + visualStyle.CaptionStyles[StyleType.Default] = style; + } + + #endregion + + #region InitCellStyles + + private void InitCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + CellVisualStyle style = new CellVisualStyle(); + + style.Alignment = Alignment.MiddleLeft; + style.Background = new Background(factory.GetColor(Color.White)); + style.BorderColor = new BorderColor(factory.GetColor(0xC4D9F6)); + style.BorderPattern.All = LinePattern.Solid; + style.BorderThickness.All = 0; + style.Font = SystemFonts.DefaultFont; + style.ImageAlignment = Alignment.MiddleLeft; + style.ImagePadding.All = 2; + style.Margin.All = 0; + style.ImageOverlay = ImageOverlay.None; + style.Padding.All = 0; + style.TextColor = Color.Black; + + visualStyle.CellStyles[StyleType.Default] = style; + + style = new CellVisualStyle(); + style.Background = GetDefaultSelectedBackground(factory); + visualStyle.CellStyles[StyleType.Selected] = style; + + style = new CellVisualStyle(); + style.Background = GetSelectedMouseOverBackground(factory); + visualStyle.CellStyles[StyleType.SelectedMouseOver] = style; + + style = new CellVisualStyle(); + style.Background = new Background(factory.GetColor(0xF1F8FF)); + visualStyle.CellStyles[StyleType.Empty] = style; + } + + #endregion + + #region InitMergedCellStyles + + private void InitMergedCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.MergedCellStyles[StyleType.Default] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnly] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.Selected] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnlySelected] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.SelectedMouseOver] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnlySelectedMouseOver] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.Empty] = new CellVisualStyle(); + } + + #endregion + + #region InitAltRowCellStyles + + private void InitAltRowCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.AlternateRowCellStyles[StyleType.Default].Background = + new Background(factory.GetColor(0xF4F4F4)); + } + + #endregion + + #region InitColumnStyles + + private void InitColumnStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + ColumnHeaderVisualStyle colStyle = new ColumnHeaderVisualStyle(); + + colStyle.Alignment = Alignment.MiddleCenter; + colStyle.BorderColor = new BorderColor(factory.GetColor(0xA0B0C7)); + colStyle.BorderPattern.All = LinePattern.Solid; + colStyle.BorderThickness.All = 0; + colStyle.Font = SystemFonts.CaptionFont; + colStyle.ImageAlignment = Alignment.MiddleLeft; + colStyle.Margin.All = 0; + colStyle.ImageOverlay = ImageOverlay.None; + colStyle.TextColor = Color.Black; + + colStyle.Background = new Background(factory.GetColor(0xEFF4FB), factory.GetColor(0xE1ECFA)); + visualStyle.ColumnHeaderStyles[StyleType.Default] = colStyle; + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = new Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6)); + visualStyle.ColumnHeaderStyles[StyleType.MouseOver] = colStyle; + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = GetDefaultSelectedColumnBackground(factory); + visualStyle.ColumnHeaderStyles[StyleType.Selected] = colStyle; + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = GetSelectedColumnMouseOverBackground(factory); + visualStyle.ColumnHeaderStyles[StyleType.SelectedMouseOver] = colStyle; + } + + #endregion + + #region InitAltColumnStyles + + private void InitAltColumnStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.AlternateColumnCellStyles[StyleType.Default].Background = + new Background(factory.GetColor(0xEAF2FB)); + } + + #endregion + + #region InitRowStyles + + private void InitRowStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.RowStyles[StyleType.Default] = GetDefaultRowStyle(factory); + visualStyle.RowStyles[StyleType.MouseOver] = GetMouseOverRowStyle(factory); + visualStyle.RowStyles[StyleType.SelectedMouseOver] = GetSelectedMouseOverRowStyle(visualStyle, factory); + } + + #region GetDefaultRowStyle + + private RowVisualStyle GetDefaultRowStyle(ColorFactory factory) + { + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = new Background(Color.White); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + + style.Font = SystemFonts.DefaultFont; + style.TextColor = factory.GetColor(0x1E395B); + + Background bg = new Background(); + BackColorBlend bcb = new BackColorBlend(); + + bcb.Colors = new Color[3]; + bcb.Colors[0] = factory.GetColor(0xDAE7F5); + bcb.Colors[1] = factory.GetColor(0xDAE7F5); + bcb.Colors[2] = factory.GetColor(0xB4C6E0); + + bcb.Positions = new float[3]; + bcb.Positions[0] = 0f; + bcb.Positions[1] = .75f; + bcb.Positions[2] = 1f; + + bg.BackColorBlend = bcb; + bg.GradientAngle = 0; + + style.Background = bg; + + bg = new Background(factory.GetColor(0xDAE7F5)); + + style.ActiveRowBackground = bg; + style.DirtyMarkerBackground = new Background(factory.GetColor(0xAE054F), factory.GetColor(0xE75E94), BackFillType.VerticalCenter); + style.BorderHighlightColor = GetBorderHighlight(factory); + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #region GetMouseOverRowStyle + + private RowVisualStyle GetMouseOverRowStyle(ColorFactory factory) + { + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = new Background(Color.White); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + style.Background = new Background(Color.Plum); + style.ActiveRowBackground = new Background(Color.Blue); + + Background bg = new Background(); + BackColorBlend bcb = new BackColorBlend(); + + bcb.Colors = new Color[3]; + bcb.Colors[0] = factory.GetColor(0xFFE575); + bcb.Colors[1] = factory.GetColor(0xFFE575); + bcb.Colors[2] = factory.GetColor(0xF2CD66); + + bcb.Positions = new float[3]; + bcb.Positions[0] = 0f; + bcb.Positions[1] = .75f; + bcb.Positions[2] = 1f; + + bg.BackColorBlend = bcb; + bg.GradientAngle = 0; + + style.Background = bg; + + bg = new Background(); + bcb = new BackColorBlend(); + + bcb.Colors = new Color[3]; + bcb.Colors[0] = Color.FromArgb(254 - 20, 240 - 20, 214 - 20); + bcb.Colors[1] = Color.FromArgb(254 - 30, 199 - 30, 104 - 30); + bcb.Colors[2] = Color.FromArgb(229 - 30, 133 - 30, 0); + + bcb.Positions = new float[3]; + bcb.Positions[0] = 0f; + bcb.Positions[1] = .75f; + bcb.Positions[2] = 1f; + + bg.BackColorBlend = bcb; + bg.GradientAngle = 0; + + style.ActiveRowBackground = bg; + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #region GetSelectedMouseOverRowStyle + + private RowVisualStyle GetSelectedMouseOverRowStyle( + DefaultVisualStyles visualStyle, ColorFactory factory) + { + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = GetDefaultSelectedBackground(factory); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + style.Background = new Background(factory.GetColor(0xC7CED6)); + style.ActiveRowBackground = new Background(factory.GetColor(0xC7CED6)); + + rowStyle.RowHeaderStyle = style; + + visualStyle.RowStyles[StyleType.Selected] = rowStyle; + + rowStyle = new RowVisualStyle(); + rowStyle.Background = GetSelectedColumnMouseOverBackground(factory); + + style = new RowHeaderVisualStyle(); + style.Background = new Background(factory.GetColor(0xC7CED6)); + style.ActiveRowBackground = new Background(factory.GetColor(0xC7CED6)); + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #endregion + + #region InitGroupHeaderStyles + + private void InitGroupHeaderStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GroupHeaderVisualStyle style = new GroupHeaderVisualStyle(); + + style.AllowWrap = Tbool.True; + style.Alignment = Alignment.MiddleLeft; + style.Font = SystemFonts.DefaultFont; + + style.Background = new + Background(factory.GetColor(0xFFFFFF)); + + style.UnderlineColor = factory.GetColor(0xC4D9F6); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(0xE3EDFA)); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(factory); + style.RowHeaderStyle.Font = SystemFonts.DefaultFont; + + visualStyle.GroupHeaderStyles[StyleType.Default] = style; + } + + #endregion + + #region GetDefaultSelectedColumnBackground + private Background GetDefaultSelectedColumnBackground(ColorFactory factory) + { + Background bg = new Background(factory.GetColor(0xFFD359), factory.GetColor(0xFFEF71)); + return bg; + } + #endregion + + #region GetDefaultSelectedBackground + + private Background GetDefaultSelectedBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xB0D4F7))); + } + + #endregion + + #region GetDefaultSelectedColumnMouseOverStyle + + private Background GetSelectedColumnMouseOverBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xFFE063), factory.GetColor(0xFFF9A2))); + } + + #endregion + + #region GetDefaultSelectedMouseOverStyle + + private Background GetSelectedMouseOverBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xB0D4F7))); + } + + #endregion + + #region InitFilterColumnHeaderStyles + + private void InitFilterColumnHeaderStyles( + DefaultVisualStyles visualStyle, ColorFactory factory) + { + FilterColumnHeaderVisualStyle style = new FilterColumnHeaderVisualStyle(); + + style.Alignment = Alignment.MiddleLeft; + style.Font = SystemFonts.CaptionFont; + + style.TextColor = Color.Black; + style.ErrorTextColor = Color.Red; + + style.Background = new Background(factory.GetColor(0xEFF4FB), factory.GetColor(0xE1ECFA)); + style.GripBarBackground = new Background(factory.GetColor(0xCFDDEE)); + visualStyle.FilterColumnHeaderStyles[StyleType.Default] = style; + + style = new FilterColumnHeaderVisualStyle(); + style.Background = new Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6)); + visualStyle.FilterColumnHeaderStyles[StyleType.MouseOver] = style; + + style = new FilterColumnHeaderVisualStyle(); + style.Background = GetDefaultSelectedColumnBackground(factory); + visualStyle.FilterColumnHeaderStyles[StyleType.Selected] = style; + + style = new FilterColumnHeaderVisualStyle(); + style.Background = GetSelectedColumnMouseOverBackground(factory); + visualStyle.FilterColumnHeaderStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region InitFilterRowStyles + + private void InitFilterRowStyles( + DefaultVisualStyles visualStyle, ColorFactory factory) + { + FilterRowVisualStyle style = new FilterRowVisualStyle(); + + style.FilterBorderColor = factory.GetColor(0x697D96); + style.FilterBackground = new Background(Color.White, factory.GetColor(0x4168B6), 0); + + style.WhiteSpaceBackground = new Background(factory.GetColor(0xCFDDEE)); + + style.RowHeader.Background = new Background(factory.GetColor(0xEFF5FB), + factory.GetColor(0xE2EDFA), BackFillType.ForwardDiagonal); + + style.RowHeader.BorderHighlightColor = GetBorderHighlight(factory); + + visualStyle.FilterRowStyles[StyleType.Default] = style; + + style = style.Copy(); + + style.FilterBackground = new Background(Color.White, factory.GetColor(Color.Green), 0); + + visualStyle.FilterRowStyles[StyleType.Selected] = style; + + style = style.Copy(); + + style.FilterBackground = new Background(Color.White, factory.GetColor(0xE2AA00), 0); + + style.RowHeader.Background = new + Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6), BackFillType.Angle); + + visualStyle.FilterRowStyles[StyleType.MouseOver] = style; + visualStyle.FilterRowStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region InitGroupByStyles + + private void InitGroupByStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GroupByVisualStyle style = new GroupByVisualStyle(); + + style.Alignment = Alignment.MiddleCenter; + style.GroupBoxConnectorColor = factory.GetColor(0x849DBD); // Panel border color + style.GroupBoxBorderColor = factory.GetColor(0x849DBD); + + style.InsertMarkerBorderColor = factory.GetColor(0x849DBD); + style.InsertMarkerBackground = new Background(factory.GetColor(Color.Red)); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(0xEFF5FB), factory.GetColor(0xE2EDFA), BackFillType.ForwardDiagonal); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(factory); + + style.TextColor = factory.GetColor(0x363636); // Col text color + style.GroupBoxBackground = new Background(factory.GetColor(0xEFF4FB), factory.GetColor(0xE1ECFA)); // col background + visualStyle.GroupByStyles[StyleType.Default] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = new Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6)); // col background + visualStyle.GroupByStyles[StyleType.MouseOver] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = GetDefaultSelectedColumnBackground(factory); // col background + visualStyle.GroupByStyles[StyleType.Selected] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = GetSelectedColumnMouseOverBackground(factory); // col background + visualStyle.GroupByStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region GetBorderHighlight + + private Color GetBorderHighlight(ColorFactory factory) + { + return factory.GetColor("80FFFFFF"); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/Office2010SilverStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/Office2010SilverStyleFactory.cs new file mode 100644 index 00000000..a8963c35 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/Office2010SilverStyleFactory.cs @@ -0,0 +1,598 @@ +using System.Drawing; +using DevComponents.DotNetBar.Rendering; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Create the Office 2010 Silver Visual Style for SuperGridControl. + /// + public class Office2010SilverStyleFactory : VisualStyleFactory + { + /// + /// Create the DefaultVisualStyle for SuperGridControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class.s + public override DefaultVisualStyles CreateStyle(ColorFactory factory) + { + DefaultVisualStyles visualStyle = new DefaultVisualStyles(); + + InitGridPanelStyle(visualStyle, factory); + + InitCellStyles(visualStyle, factory); + InitMergedCellStyles(visualStyle, factory); + InitAltRowCellStyles(visualStyle, factory); + + InitColumnStyles(visualStyle, factory); + InitAltColumnStyles(visualStyle, factory); + InitColumnHeaderStyles(visualStyle, factory); + + InitRowStyles(visualStyle, factory); + InitTextRowStyles(visualStyle, factory); + + InitGroupHeaderStyles(visualStyle, factory); + + InitFilterRowStyles(visualStyle, factory); + InitFilterColumnHeaderStyles(visualStyle, factory); + + InitGroupByStyles(visualStyle, factory); + + return (visualStyle); + } + + #region InitGridPanelStyle + + private void InitGridPanelStyle(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GridPanelVisualStyle style = new GridPanelVisualStyle(); + + style.Background = new Background(factory.GetColor(0xFFFFFF)); + style.BorderColor = new BorderColor(factory.GetColor(0x8B9097)); + style.BorderPattern.All = LinePattern.Solid; + style.BorderThickness = new Thickness(1); + style.TextColor = factory.GetColor(0x000000); + + style.TreeLineColor = factory.GetColor(0x484848); + style.HeaderLineColor = factory.GetColor(0x8B9097); + style.HorizontalLineColor = factory.GetColor(0xDBDEE1); + style.VerticalLineColor = factory.GetColor(0xDBDEE1); + + style.TreeLinePattern = LinePattern.Solid; + style.HorizontalLinePattern = LinePattern.Solid; + style.VerticalLinePattern = LinePattern.Solid; + style.HeaderHLinePattern = LinePattern.Solid; + style.HeaderVLinePattern = LinePattern.Solid; + + BaseTreeButtonVisualStyle tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(Color.SlateGray); + tstyle.HotBorderColor = factory.GetColor(Color.SlateGray); + tstyle.LineColor = factory.GetColor(Color.DarkSlateGray); + tstyle.HotLineColor = factory.GetColor(Color.DarkSlateGray); + tstyle.Background = new Background(factory.GetColor(Color.White), factory.GetColor(Color.Gainsboro), 90); + tstyle.HotBackground = new Background(factory.GetColor(Color.White), factory.GetColor(Color.Gainsboro), 90); + + style.CircleTreeButtonStyle.CollapseButton = tstyle; + style.CircleTreeButtonStyle.ExpandButton = tstyle; + + style.SquareTreeButtonStyle.CollapseButton = tstyle; + style.SquareTreeButtonStyle.ExpandButton = tstyle; + + tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(Color.Black); + tstyle.HotBorderColor = factory.GetColor(0x27C7F7); + tstyle.Background = new Background(factory.GetColor(Color.Black)); + tstyle.HotBackground = new Background(factory.GetColor(0xC7EBFA)); + + style.TriangleTreeButtonStyle.CollapseButton = tstyle; + + tstyle = new BaseTreeButtonVisualStyle(); + + tstyle.BorderColor = factory.GetColor(Color.DimGray); + tstyle.HotBorderColor = factory.GetColor(0x27C7F7); + tstyle.Background = new Background(factory.GetColor(Color.White)); + tstyle.HotBackground = new Background(factory.GetColor(0xC7EBFA)); + + style.TriangleTreeButtonStyle.ExpandButton = tstyle; + visualStyle.GridPanelStyle = style; + } + + #endregion + + #region InitColumnHeaderStyles + + private void InitColumnHeaderStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + ColumnHeaderRowVisualStyle style = new ColumnHeaderRowVisualStyle(); + + style.FilterBorderColor = factory.GetColor(0x787D87); + style.FilterBackground = new Background(Color.White, factory.GetColor(0xB0B6BC), 0); + + style.WhiteSpaceBackground = new Background(factory.GetColor(0xE9EDF1)); + + style.RowHeader.Background = new Background( + factory.GetColor(0xF5F7F9), factory.GetColor(0xEFF2F6), BackFillType.ForwardDiagonal); + + style.RowHeader.BorderHighlightColor = GetBorderHighlight(factory); + + style.IndicatorBackground = new Background(factory.GetColor(0xB0B6BC)); + style.IndicatorBorderColor = factory.GetColor(0x787D87); + + visualStyle.ColumnHeaderRowStyles[StyleType.Default] = style; + + style = style.Copy(); + + style.FilterBorderColor = factory.GetColor(Color.Green); + style.FilterBackground = new Background(Color.White, factory.GetColor(Color.Green), 45); + + visualStyle.ColumnHeaderRowStyles[StyleType.Selected] = style; + + style = style.Copy(); + + style.FilterBorderColor = factory.GetColor(0x797979); + style.FilterBackground = new Background(Color.White, factory.GetColor(0xE2AA00), 0); + + style.RowHeader.Background = new Background( + factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6), BackFillType.Angle); + + visualStyle.ColumnHeaderRowStyles[StyleType.MouseOver] = style; + visualStyle.ColumnHeaderRowStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region InitTextRowStyles + + private void InitTextRowStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + TextRowVisualStyle style = new TextRowVisualStyle(); + + style.Alignment = Alignment.MiddleCenter; + style.AllowWrap = Tbool.True; + + style.Background = new Background(factory.GetColor(0xF5F7F9), factory.GetColor(0xEFF2F6), BackFillType.Angle); + style.BorderColor = new BorderColor(factory.GetColor(0xA5ACB5)); + + style.Padding.All = 2; + + style.TextColor = factory.GetColor(0x3B3B3B); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(0xF5F7F9), factory.GetColor(0xEFF2F6), BackFillType.Angle); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(factory); + + visualStyle.TitleStyles[StyleType.Default] = style; + visualStyle.HeaderStyles[StyleType.Default] = style.Copy(); + visualStyle.FooterStyles[StyleType.Default] = style.Copy(); + + style = style.Copy(); + style.Background = new Background(factory.GetColor(0xE9EDF1)); + + visualStyle.CaptionStyles[StyleType.Default] = style; + } + + #endregion + + #region InitCellStyles + + private void InitCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + CellVisualStyle style = new CellVisualStyle(); + + style.Alignment = Alignment.MiddleLeft; + style.Background = new Background(factory.GetColor(Color.White)); + style.BorderColor = new BorderColor(factory.GetColor(0xDBDEE1)); + style.BorderPattern.All = LinePattern.Solid; + style.BorderThickness.All = 0; + style.Font = SystemFonts.DefaultFont; + style.ImageAlignment = Alignment.MiddleLeft; + style.ImagePadding.All = 2; + style.Margin.All = 0; + style.ImageOverlay = ImageOverlay.None; + style.Padding.All = 0; + style.TextColor = Color.Black; + + visualStyle.CellStyles[StyleType.Default] = style; + + style = new CellVisualStyle(); + style.Background = GetDefaultSelectedBackground(factory); + + visualStyle.CellStyles[StyleType.Selected] = style; + + style = new CellVisualStyle(); + style.Background = GetSelectedMouseOverBackground(factory); + + visualStyle.CellStyles[StyleType.SelectedMouseOver] = style; + + style = new CellVisualStyle(); + style.Background = new Background(factory.GetColor(0xE9EDF1)); + + visualStyle.CellStyles[StyleType.Empty] = style; + } + + #endregion + + #region InitMergedCellStyles + + private void InitMergedCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.MergedCellStyles[StyleType.Default] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnly] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.Selected] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnlySelected] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.SelectedMouseOver] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.ReadOnlySelectedMouseOver] = new CellVisualStyle(); + visualStyle.MergedCellStyles[StyleType.Empty] = new CellVisualStyle(); + } + + #endregion + + #region InitAltRowCellStyles + + private void InitAltRowCellStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.AlternateRowCellStyles[StyleType.Default].Background = + new Background(factory.GetColor(0xF4F4F4)); + } + + #endregion + + #region InitColumnStyles + + private void InitColumnStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + ColumnHeaderVisualStyle colStyle = new ColumnHeaderVisualStyle(); + + colStyle.Alignment = Alignment.MiddleCenter; + colStyle.BorderColor = new BorderColor(factory.GetColor(Color.Transparent)); + colStyle.BorderPattern.All = LinePattern.Solid; + colStyle.BorderThickness.All = 0; + colStyle.Font = SystemFonts.CaptionFont; + colStyle.ImageAlignment = Alignment.MiddleLeft; + colStyle.Margin.All = 0; + colStyle.ImageOverlay = ImageOverlay.None; + colStyle.TextColor = factory.GetColor(0x363636); + + colStyle.Background = new Background(factory.GetColor(0xF5F7F9), factory.GetColor(0xEFF2F6)); + + visualStyle.ColumnHeaderStyles[StyleType.Default] = colStyle; + + colStyle = new ColumnHeaderVisualStyle(); + + colStyle.Background = new Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6)); + + visualStyle.ColumnHeaderStyles[StyleType.MouseOver] = colStyle; + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = GetDefaultSelectedColumnBackground(factory); + + visualStyle.ColumnHeaderStyles[StyleType.Selected] = colStyle; + + colStyle = new ColumnHeaderVisualStyle(); + colStyle.Background = GetSelectedColumnMouseOverBackground(factory); + + visualStyle.ColumnHeaderStyles[StyleType.SelectedMouseOver] = colStyle; + } + + #endregion + + #region InitAltColumnStyles + + private void InitAltColumnStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.AlternateColumnCellStyles[StyleType.Default].Background = + new Background(factory.GetColor(0xF7F7FF)); + } + + #endregion + + #region InitRowStyles + + private void InitRowStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + visualStyle.RowStyles[StyleType.Default] = GetDefaultRowStyle(factory); + visualStyle.RowStyles[StyleType.MouseOver] = GetMouseOverRowStyle(factory); + visualStyle.RowStyles[StyleType.SelectedMouseOver] = GetSelectedMouseOverRowStyle(visualStyle, factory); + } + + #region GetDefaultRowStyle + + private RowVisualStyle GetDefaultRowStyle(ColorFactory factory) + { + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = new Background(Color.White); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + + style.Font = SystemFonts.DefaultFont; + style.TextColor = factory.GetColor(0x363636); + + Background bg = new Background(); + BackColorBlend bcb = new BackColorBlend(); + + bcb.Colors = new Color[3]; + bcb.Colors[0] = factory.GetColor(0xDFE3E8); + bcb.Colors[1] = factory.GetColor(0xDFE3E8); + bcb.Colors[2] = factory.GetColor(0xC6CACF); + + bcb.Positions = new float[3]; + bcb.Positions[0] = 0f; + bcb.Positions[1] = .75f; + bcb.Positions[2] = 1f; + + bg.BackColorBlend = bcb; + bg.GradientAngle = 0; + + style.Background = bg; + + bg = new Background(factory.GetColor(0xDFE3E8)); + + style.ActiveRowBackground = bg; + style.DirtyMarkerBackground = new Background(factory.GetColor(0xAE054F), factory.GetColor(0xE75E94), BackFillType.VerticalCenter); + style.BorderHighlightColor = GetBorderHighlight(factory); + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #region GetMouseOverRowStyle + + private RowVisualStyle GetMouseOverRowStyle(ColorFactory factory) + { + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = new Background(Color.White); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + style.Background = new Background(Color.Plum); + style.ActiveRowBackground = new Background(Color.Blue); + + Background bg = new Background(); + BackColorBlend bcb = new BackColorBlend(); + + bcb.Colors = new Color[3]; + bcb.Colors[0] = factory.GetColor(0xFFE575); + bcb.Colors[1] = factory.GetColor(0xFFE575); + bcb.Colors[2] = factory.GetColor(0xF2CD66); + + bcb.Positions = new float[3]; + bcb.Positions[0] = 0f; + bcb.Positions[1] = .75f; + bcb.Positions[2] = 1f; + + bg.BackColorBlend = bcb; + bg.GradientAngle = 0; + + style.Background = bg; + + bg = new Background(); + bcb = new BackColorBlend(); + + bcb.Colors = new Color[3]; + bcb.Colors[0] = Color.FromArgb(254 - 20, 240 - 20, 214 - 20); + bcb.Colors[1] = Color.FromArgb(254 - 30, 199 - 30, 104 - 30); + bcb.Colors[2] = Color.FromArgb(229 - 30, 133 - 30, 0); + + bcb.Positions = new float[3]; + bcb.Positions[0] = 0f; + bcb.Positions[1] = .75f; + bcb.Positions[2] = 1f; + + bg.BackColorBlend = bcb; + bg.GradientAngle = 0; + + style.ActiveRowBackground = bg; + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #region GetSelectedMouseOverRowStyle + + private RowVisualStyle GetSelectedMouseOverRowStyle(DefaultVisualStyles visualStyle, ColorFactory factory) + { + RowVisualStyle rowStyle = new RowVisualStyle(); + rowStyle.Background = GetDefaultSelectedBackground(factory); + + RowHeaderVisualStyle style = new RowHeaderVisualStyle(); + style.Background = new Background(factory.GetColor(0xAAAAAA)); + style.ActiveRowBackground = new Background(factory.GetColor(0xAAAAAA)); + + rowStyle.RowHeaderStyle = style; + + visualStyle.RowStyles[StyleType.Selected] = rowStyle; + + rowStyle = new RowVisualStyle(); + rowStyle.Background = GetSelectedColumnMouseOverBackground(factory); + + style = new RowHeaderVisualStyle(); + style.Background = new Background(factory.GetColor(0xAAAAAA)); + style.ActiveRowBackground = new Background(factory.GetColor(0xAAAAAA)); + + rowStyle.RowHeaderStyle = style; + + return (rowStyle); + } + + #endregion + + #endregion + + #region InitGroupHeaderStyles + + private void InitGroupHeaderStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GroupHeaderVisualStyle style = new GroupHeaderVisualStyle(); + + style.AllowWrap = Tbool.True; + style.Alignment = Alignment.MiddleLeft; + style.Font = SystemFonts.DefaultFont; + + style.Background = new + Background(factory.GetColor(0xE5E7E9)); + + style.UnderlineColor = factory.GetColor(0xE5E7E9); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(0xDFE3E8)); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(factory); + style.RowHeaderStyle.Font = SystemFonts.DefaultFont; + + visualStyle.GroupHeaderStyles[StyleType.Default] = style; + } + + #endregion + + #region GetDefaultSelectedColumnBackground + private Background GetDefaultSelectedColumnBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xFFD359), factory.GetColor(0xFFEF71))); + } + #endregion + + #region GetDefaultSelectedBackground + + private Background GetDefaultSelectedBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xB7DBFF))); + } + + #endregion + + #region GetDefaultSelectedColumnMouseOverStyle + + private Background GetSelectedColumnMouseOverBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xB0D4F7))); + } + + #endregion + + #region GetDefaultSelectedMouseOverStyle + + private Background GetSelectedMouseOverBackground(ColorFactory factory) + { + return (new Background(factory.GetColor(0xB0D4F7))); + } + + #endregion + + #region InitFilterColumnHeaderStyles + + private void InitFilterColumnHeaderStyles( + DefaultVisualStyles visualStyle, ColorFactory factory) + { + FilterColumnHeaderVisualStyle colStyle = new FilterColumnHeaderVisualStyle(); + + colStyle.Alignment = Alignment.MiddleLeft; + colStyle.Font = SystemFonts.CaptionFont; + + colStyle.TextColor = factory.GetColor(0x363636); + colStyle.ErrorTextColor = Color.Red; + + colStyle.Background = new Background(factory.GetColor(0xF5F7F9), factory.GetColor(0xEFF2F6)); + colStyle.GripBarBackground = new Background(factory.GetColor(0xE9EDF1)); + visualStyle.FilterColumnHeaderStyles[StyleType.Default] = colStyle; + + colStyle = new FilterColumnHeaderVisualStyle(); + colStyle.Background = new Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6)); + visualStyle.FilterColumnHeaderStyles[StyleType.MouseOver] = colStyle; + + colStyle = new FilterColumnHeaderVisualStyle(); + colStyle.Background = GetDefaultSelectedColumnBackground(factory); + visualStyle.FilterColumnHeaderStyles[StyleType.Selected] = colStyle; + + colStyle = new FilterColumnHeaderVisualStyle(); + colStyle.Background = GetSelectedColumnMouseOverBackground(factory); + visualStyle.FilterColumnHeaderStyles[StyleType.SelectedMouseOver] = colStyle; + } + + #endregion + + #region InitFilterRowStyles + + private void InitFilterRowStyles( + DefaultVisualStyles visualStyle, ColorFactory factory) + { + FilterRowVisualStyle style = new FilterRowVisualStyle(); + + style.FilterBorderColor = factory.GetColor(0x787D87); + style.FilterBackground = new Background(Color.White, factory.GetColor(0xB0B6BC), 0); + + style.WhiteSpaceBackground = new Background(factory.GetColor(0xE9EDF1)); + + style.RowHeader.Background = new Background( + factory.GetColor(0xF5F7F9), factory.GetColor(0xEFF2F6), BackFillType.ForwardDiagonal); + + style.RowHeader.BorderHighlightColor = GetBorderHighlight(factory); + + visualStyle.FilterRowStyles[StyleType.Default] = style; + + style = style.Copy(); + + style.FilterBackground = new Background(Color.White, factory.GetColor(Color.Green), 45); + + visualStyle.FilterRowStyles[StyleType.Selected] = style; + + style = style.Copy(); + + style.FilterBackground = new Background(Color.White, factory.GetColor(0xE2AA00), 0); + + style.RowHeader.Background = new Background( + factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6), BackFillType.Angle); + + visualStyle.FilterRowStyles[StyleType.MouseOver] = style; + visualStyle.FilterRowStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region InitGroupByStyles + + private void InitGroupByStyles(DefaultVisualStyles visualStyle, ColorFactory factory) + { + GroupByVisualStyle style = new GroupByVisualStyle(); + + style.Alignment = Alignment.MiddleCenter; + style.GroupBoxConnectorColor = factory.GetColor(0x8B9097); // Panel border color + style.GroupBoxBorderColor = factory.GetColor(0x8B9097); + + style.InsertMarkerBorderColor = factory.GetColor(0x8B9097); + style.InsertMarkerBackground = new Background(factory.GetColor(Color.Red)); + + style.RowHeaderStyle.Background = new Background(factory.GetColor(0xF5F7F9), factory.GetColor(0xEFF2F6), BackFillType.ForwardDiagonal); + style.RowHeaderStyle.BorderHighlightColor = GetBorderHighlight(factory); + + style.TextColor = factory.GetColor(0x363636); // Col text color + style.GroupBoxBackground = new Background(factory.GetColor(0xF5F7F9), factory.GetColor(0xEFF2F6)); // col background + visualStyle.GroupByStyles[StyleType.Default] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = new Background(factory.GetColor(0xFFDF6B), factory.GetColor(0xFFFCE6)); // col background + visualStyle.GroupByStyles[StyleType.MouseOver] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = GetDefaultSelectedColumnBackground(factory); // col background + visualStyle.GroupByStyles[StyleType.Selected] = style; + + style = new GroupByVisualStyle(); + style.GroupBoxBackground = GetSelectedColumnMouseOverBackground(factory); // col background + visualStyle.GroupByStyles[StyleType.SelectedMouseOver] = style; + } + + #endregion + + #region GetBorderHighlight + + private Color GetBorderHighlight(ColorFactory factory) + { + return factory.GetColor("80FFFFFF"); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/VisualStyleFactory.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/VisualStyleFactory.cs new file mode 100644 index 00000000..ecbec3ed --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/VisualStyleFactory.cs @@ -0,0 +1,52 @@ +using System; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// Represents base class that each visual style factory for SuperGridControl inherits from. + /// + public abstract class VisualStyleFactory + { + /// + /// Create the DefaultVisualStyle for SuperGridControl. + /// + /// Color-Factory used to generate colors. + /// New instance of DefaultVisualStyles class. + public abstract DefaultVisualStyles CreateStyle(Rendering.ColorFactory factory); + + /// + /// Create the DefaultVisualStyle for SuperGridControl with empty color factory. + /// + /// New instance of DefaultVisualStyles class. + public virtual DefaultVisualStyles CreateStyle() + { + if (StyleManager.ColorTint.IsEmpty) + return CreateStyle(Rendering.ColorFactory.Empty); + + return CreateStyle(new Rendering.ColorBlendFactory(StyleManager.ColorTint)); + } + + /// + /// Returns the style factory for specified visual style. + /// + /// Style to create factory for. + /// An instance of VisualStyleFactory. + public static VisualStyleFactory GetStyleFactory(SuperGridStyle style) + { + if (style == SuperGridStyle.Office2010Blue) + return new Office2010BlueStyleFactory(); + + if (style == SuperGridStyle.Office2010Silver) + return new Office2010SilverStyleFactory(); + + if (style == SuperGridStyle.Office2010Black) + return new Office2010BlackStyleFactory(); + + if (style == SuperGridStyle.Metro) + return new MetroStyleFactory(); + + throw new ArgumentException(string.Format( + "Specified style '{0}' factory has not been implemented.", style)); + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/VisualStylesTable.cs b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/VisualStylesTable.cs new file mode 100644 index 00000000..72b50953 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.DotNetBar.SuperGrid/VisualStyles/VisualStylesTable.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; + +namespace DevComponents.DotNetBar.SuperGrid.Style +{ + /// + /// VisualStylesTable + /// + public static class VisualStylesTable + { + private static Dictionary + _DefaultStyles = new Dictionary(); + + /// + /// Gets the DefaultVisualStyles for specified SuperGrid style. + /// + /// SuperGridStyle to return. + /// An instance of DefaultVisualStyle. + public static DefaultVisualStyles GetStyle(SuperGridStyle style) + { + DefaultVisualStyles visualStyle; + bool cacheStyle = true; + + if (style == SuperGridStyle.Metro || !StyleManager.ColorTint.IsEmpty) + cacheStyle = false; + + if (cacheStyle == false || !_DefaultStyles.TryGetValue(style, out visualStyle)) + { + VisualStyleFactory factory = VisualStyleFactory.GetStyleFactory(style); + + visualStyle = factory.CreateStyle(); + + if (cacheStyle) // Do not cache Metro style + _DefaultStyles.Add(style, visualStyle); + } + + return visualStyle; + } + + /// + /// Replaces an system style with the specified visual style. + /// + /// SuperGridStyle to replace. + /// DefaultVisualStyles to replace the system style with. + public static void SetStyleFactory(SuperGridStyle style, DefaultVisualStyles visualStyle) + { + _DefaultStyles[style] = visualStyle; + } + } + + /// + /// Defines available pre-defined SuperGrid visual styles. + /// + public enum SuperGridStyle + { + /// + /// Office 2010 Blue style. + /// + Office2010Blue, + /// + /// Office 2010 Silver style. + /// + Office2010Silver, + /// + /// Office 2010 Black style. + /// + Office2010Black, + /// + /// Metro Style. + /// + Metro + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/BoolValueTypeDropDown.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/BoolValueTypeDropDown.cs new file mode 100644 index 00000000..a101a2aa --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/BoolValueTypeDropDown.cs @@ -0,0 +1,45 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.SuperGrid.Design +{ + [ToolboxItem(false)] + public class BoolValueTypeDropDown : ValueTypeDropDown + { + public BoolValueTypeDropDown() + { + } + + public BoolValueTypeDropDown(object value, + IWindowsFormsEditorService editorService, ITypeDescriptorContext context) + : base(value, editorService, context) + { + } + + protected override string[] GetListBoxItems() + { + return (new string[] { "True", "False" }); + } + + protected override int GetSelectedIndex() + { + if (Value is bool) + return ((bool)Value == true ? 0 : 1); + + return (-1); + } + + protected override void ListBoxSelectedIndexChanged(object sender, EventArgs e) + { + ListBox listBox = sender as ListBox; + + if (listBox != null) + { + if (listBox.SelectedIndex >= 0) + Value = (listBox.SelectedIndex == 0); + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ColumnGroupHeaderCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ColumnGroupHeaderCollectionEditor.cs new file mode 100644 index 00000000..9bddd981 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ColumnGroupHeaderCollectionEditor.cs @@ -0,0 +1,232 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.Design +{ + /// + /// ColumnGroupHeaderCollectionEditor + /// + public class ColumnGroupHeaderCollectionEditor : CollectionEditor + { + #region Static variables + + static Size _lastSize = Size.Empty; + static Point _lastLoc = Point.Empty; + + #endregion + + public ColumnGroupHeaderCollectionEditor(Type type) + : base(type) + { + } + + #region CreateCollectionForm + + protected override CollectionForm CreateCollectionForm() + { + CollectionForm collectionForm = base.CreateCollectionForm(); + + if (collectionForm.Controls[0] is TableLayoutPanel) + { + TableLayoutPanel tlpf = + collectionForm.Controls["overArchingTableLayoutPanel"] as TableLayoutPanel; + + if (tlpf != null) + { + PropertyGrid propertyGrid = + tlpf.Controls["propertyBrowser"] as PropertyGrid; + + if (propertyGrid != null) + { + propertyGrid.HelpVisible = true; + + propertyGrid.GotFocus += PropertyGridGotFocus; + propertyGrid.SelectedObjectsChanged += PropertyGridSelectedObjectsChanged; + } + } + } + + collectionForm.Load += CollectionFormLoad; + collectionForm.Resize += CollectionFormResize; + collectionForm.LocationChanged += CollectionFormLocationChanged; + + return (collectionForm); + } + + #region CollectionFormLoad + + void CollectionFormLoad(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null) + { + if (_lastSize != Size.Empty) + form.Size = _lastSize; + + if (_lastLoc != Point.Empty) + form.Location = _lastLoc; + } + } + + #endregion + + #region CollectionFormResize + + void CollectionFormResize(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastSize = form.Size; + } + + #endregion + + #region CollectionFormLocationChanged + + void CollectionFormLocationChanged(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastLoc = form.Location; + } + + #endregion + + #region PropertyGridGotFocus + + void PropertyGridGotFocus(object sender, EventArgs e) + { + PropertyGrid propertyGrid = sender as PropertyGrid; + + if (propertyGrid != null) + UpdateDesignerFocus(propertyGrid); + } + + #endregion + + #region PropertyGridSelectedObjectsChanged + + void PropertyGridSelectedObjectsChanged(object sender, EventArgs e) + { + PropertyGrid propertyGrid = sender as PropertyGrid; + + if (propertyGrid != null) + UpdateDesignerFocus(propertyGrid); + } + + #endregion + + #region UpdateDesignerFocus + + private void UpdateDesignerFocus(PropertyGrid propertyGrid) + { + GridContainer row = Context.Instance as GridContainer; + + if (row != null) + { + GridElement item = propertyGrid.SelectedObject as GridElement; + + if (item != null) + row.SuperGrid.DesignerElement = item; + } + } + + #endregion + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(ColumnGroupHeader); + } + + #endregion + + #region CreateNewItemTypes + + protected override Type[] CreateNewItemTypes() + { + return new Type[] + { + typeof(ColumnGroupHeader), + }; + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + object o = base.EditValue(context, provider, value); + + return (o); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + ColumnGroupHeader item = + (ColumnGroupHeader) base.CreateInstance(typeof (ColumnGroupHeader)); + + if (item != null) + { + GridColumnHeader gch = Context.Instance as GridColumnHeader; + + if (gch != null) + { + item.Name = GetGroupHeaderName(gch.GroupHeaders); + } + else + { + ColumnGroupHeader csh = Context.Instance as ColumnGroupHeader; + + if (csh != null) + { + item.Name = GetGroupHeaderName(csh.GroupHeaders); + + item.StartDisplayIndex = csh.StartDisplayIndex; + item.EndDisplayIndex = csh.EndDisplayIndex; + + item.ShowColumnHeaders = csh.ShowColumnHeaders; + } + } + } + + return (item); + } + + #region GetGroupHeaderName + + private string GetGroupHeaderName(ColumnGroupHeaderCollection csc) + { + for (int i = 1; i < 200; i++) + { + string s = "GroupHeader" + i; + + if (csc[s] == null) + return (s); + } + + return (""); + } + + #endregion + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ColumnListTypeEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ColumnListTypeEditor.cs new file mode 100644 index 00000000..ffdf81da --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ColumnListTypeEditor.cs @@ -0,0 +1,98 @@ +using System; +using System.ComponentModel; +using System.Drawing.Design; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.Design +{ + public class ColumnListTypeEditor : UITypeEditor + { + #region Private variables + + IWindowsFormsEditorService _EditorService; + + #endregion + + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return (UITypeEditorEditStyle.DropDown); + } + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (false); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + _EditorService = + provider.GetService(typeof (IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (_EditorService != null) + { + GridPanel panel = context.Instance as GridPanel; + + if (panel != null) + { + ListBox lb = new ListBox(); + lb.Dock = DockStyle.Fill; + lb.BorderStyle = BorderStyle.None; + + lb.MouseClick += ListBoxMouseClick; + + for (int i = 0; i < panel.Columns.Count; i++) + { + GridColumn col = panel.Columns[i]; + + string s = GetColumnText(col, i); + + lb.Items.Add(s); + } + + _EditorService.DropDownControl(lb); + + if (lb.SelectedIndex >= 0) + return (lb.SelectedIndex); + + return (panel.PrimaryColumnIndex); + } + } + + return (base.EditValue(context, provider, value)); + } + + private string GetColumnText(GridColumn col, int index) + { + string s = index + " "; + + if (string.IsNullOrEmpty(col.Name) == false) + return (s + "-" + col.Name); + + if (string.IsNullOrEmpty(col.HeaderText) == false) + return (s + "-" + col.HeaderText); + + return (s); + } + + private void ListBoxMouseClick(object sender, MouseEventArgs e) + { + _EditorService.CloseDropDown(); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeDropDown.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeDropDown.Designer.cs new file mode 100644 index 00000000..e8332098 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeDropDown.Designer.cs @@ -0,0 +1,64 @@ +namespace DevComponents.SuperGrid.Design +{ + partial class EditTypeDropDown + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.listBox1 = new System.Windows.Forms.ListBox(); + this.SuspendLayout(); + // + // listBox1 + // + this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.listBox1.FormattingEnabled = true; + this.listBox1.Location = new System.Drawing.Point(0, 0); + this.listBox1.Name = "listBox1"; + this.listBox1.Size = new System.Drawing.Size(172, 95); + this.listBox1.TabIndex = 1; + this.listBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.ListBox1MouseClick); + this.listBox1.SelectedIndexChanged += new System.EventHandler(this.ListBox1SelectedIndexChanged); + // + // EditTypeDropDown + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.listBox1); + this.Name = "EditTypeDropDown"; + this.Size = new System.Drawing.Size(172, 95); + this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.DropDownPreviewKeyDown); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ListBox listBox1; + + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeDropDown.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeDropDown.cs new file mode 100644 index 00000000..9103b2a9 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeDropDown.cs @@ -0,0 +1,147 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.Design +{ + [ToolboxItem(false)] + public partial class EditTypeDropDown : UserControl + { + #region Static data + + static readonly Type[] Types = new Type[] + { + typeof(GridButtonXEditControl), typeof(GridCheckBoxXEditControl), + typeof(GridColorPickerEditControl), typeof(GridComboBoxExEditControl), + typeof(GridComboTreeEditControl), typeof(GridDateTimeInputEditControl), + typeof(GridDateTimePickerEditControl), typeof(GridDoubleInputEditControl), + typeof(GridIntegerInputEditControl), typeof(GridIpAddressInputEditControl), + typeof(GridLabelXEditControl), typeof(GridMaskedTextBoxEditControl), + typeof(GridMicroChartEditControl), typeof(GridNumericUpDownEditControl), + typeof(GridImageEditControl), typeof(GridProgressBarXEditControl), + typeof(GridRadialMenuEditControl), typeof(GridSliderEditControl), + typeof(GridSwitchButtonEditControl), typeof(GridTextBoxDropDownEditControl), + typeof(GridTextBoxXEditControl), + }; + + #endregion + + #region Private variables + + private Type _EditType; + + private bool _EscapePressed; + + private IWindowsFormsEditorService _EditorService; + private ITypeDescriptorContext _Context; + + #endregion + + public EditTypeDropDown(Type value, + IWindowsFormsEditorService editorService, ITypeDescriptorContext context) + { + Initialize(); + + _EditorService = editorService; + _Context = context; + + EditType = value; + } + + public EditTypeDropDown() + { + Initialize(); + } + + #region Initialize + + private void Initialize() + { + InitializeComponent(); + + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + + listBox1.Items.Add("(None)"); + + foreach (Type type in Types) + listBox1.Items.Add(type.Name); + } + + #endregion + + #region Public properties + + #region EditorService + + public IWindowsFormsEditorService EditorService + { + get { return (_EditorService); } + set { _EditorService = value; } + } + + #endregion + + #region EscapePressed + + public bool EscapePressed + { + get { return (_EscapePressed); } + set { _EscapePressed = value; } + } + + #endregion + + #region EditType + + public Type EditType + { + get { return (_EditType); } + + set + { + _EditType = value; + + _Context.OnComponentChanging(); + _Context.PropertyDescriptor.SetValue(_Context.Instance, value); + _Context.OnComponentChanged(); + } + } + + #endregion + + #endregion + + #region DropDownPreviewKeyDown + + private void DropDownPreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + if (e.KeyCode == Keys.Escape) + _EscapePressed = true; + } + + #endregion + + #region ListBox1MouseClick + + private void ListBox1MouseClick(object sender, MouseEventArgs e) + { + _EditorService.CloseDropDown(); + } + + #endregion + + #region ListBox1SelectedIndexChanged + + private void ListBox1SelectedIndexChanged(object sender, EventArgs e) + { + EditType = (listBox1.SelectedIndex > 0) + ? Types[listBox1.SelectedIndex - 1] : null; + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeDropDown.resx b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeDropDown.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeDropDown.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeEditor.cs new file mode 100644 index 00000000..26f849a0 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/EditTypeEditor.cs @@ -0,0 +1,55 @@ +using System; +using System.ComponentModel; +using System.Drawing.Design; +using System.Windows.Forms.Design; + +namespace DevComponents.SuperGrid.Design +{ + public class EditTypeEditor : UITypeEditor + { + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return (UITypeEditorEditStyle.DropDown); + } + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (false); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + IWindowsFormsEditorService editorService = + provider.GetService(typeof (IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (editorService != null) + { + EditTypeDropDown pv = new EditTypeDropDown((Type)value, editorService, context); + + pv.EscapePressed = false; + + editorService.DropDownControl(pv); + + if (pv.EscapePressed == true) + context.PropertyDescriptor.SetValue(context.Instance, value); + else + return (pv.EditType); + } + + return (base.EditValue(context, provider, value)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/GridCellCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/GridCellCollectionEditor.cs new file mode 100644 index 00000000..03518601 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/GridCellCollectionEditor.cs @@ -0,0 +1,148 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.Design +{ + /// + /// GridRowCollectionEditor + /// + public class GridCellCollectionEditor : CollectionEditor + { + #region Static variables + + static Size _lastSize = Size.Empty; + static Point _lastLoc = Point.Empty; + + #endregion + + #region Private variables + + private CollectionForm _CollectionForm; + private TableLayoutPanel _LayoutPanel; + + #endregion + + public GridCellCollectionEditor(Type type) + : base(type) + { + } + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(GridCell); + } + + #endregion + + #region CreateCollectionForm + + protected override CollectionForm CreateCollectionForm() + { + _CollectionForm = base.CreateCollectionForm(); + + _LayoutPanel = + _CollectionForm.Controls["overArchingTableLayoutPanel"] as TableLayoutPanel; + + if (_LayoutPanel != null) + { + PropertyGrid propertyGrid = + _LayoutPanel.Controls["propertyBrowser"] as PropertyGrid; + + if (propertyGrid != null) + { + propertyGrid.HelpVisible = true; + propertyGrid.GotFocus += PropertyGridGotFocus; + } + } + + _CollectionForm.Load += CollectionFormLoad; + _CollectionForm.Resize += CollectionFormResize; + _CollectionForm.LocationChanged += CollectionFormLocationChanged; + + return (_CollectionForm); + } + + #region CollectionFormLoad + + void CollectionFormLoad(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null) + { + if (_lastSize != Size.Empty) + form.Size = _lastSize; + + if (_lastLoc != Point.Empty) + form.Location = _lastLoc; + } + } + + #endregion + + #region CollectionFormResize + + void CollectionFormResize(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastSize = form.Size; + } + + #endregion + + #region CollectionFormLocationChanged + + void CollectionFormLocationChanged(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastLoc = form.Location; + } + + #endregion + + #region PropertyGridGotFocus + + void PropertyGridGotFocus(object sender, EventArgs e) + { + _LayoutPanel.Controls[4].Refresh(); + } + + #endregion + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + object o = base.EditValue(context, provider, value); + + return (o); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + object o = base.CreateInstance(itemType); + + return (o); + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/GridColumnCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/GridColumnCollectionEditor.cs new file mode 100644 index 00000000..fc646903 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/GridColumnCollectionEditor.cs @@ -0,0 +1,252 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.Design +{ + /// + /// GridColumnCollectionEditor + /// + public class GridColumnCollectionEditor : CollectionEditor + { + #region Static variables + + static Size _lastSize = Size.Empty; + static Point _lastLoc = Point.Empty; + + #endregion + + public GridColumnCollectionEditor(Type type) + : base(type) + { + } + + #region CreateCollectionForm + + protected override CollectionForm CreateCollectionForm() + { + CollectionForm collectionForm = base.CreateCollectionForm(); + + if (collectionForm.Controls[0] is TableLayoutPanel) + { + TableLayoutPanel tlpf = + collectionForm.Controls["overArchingTableLayoutPanel"] as TableLayoutPanel; + + if (tlpf != null) + { + PropertyGrid propertyGrid = + tlpf.Controls["propertyBrowser"] as PropertyGrid; + + if (propertyGrid != null) + { + propertyGrid.HelpVisible = true; + + propertyGrid.GotFocus += PropertyGridGotFocus; + propertyGrid.SelectedObjectsChanged += PropertyGridSelectedObjectsChanged; + } + } + } + + collectionForm.Load += CollectionFormLoad; + collectionForm.Resize += CollectionFormResize; + collectionForm.LocationChanged += CollectionFormLocationChanged; + + return (collectionForm); + } + + #region CollectionFormLoad + + void CollectionFormLoad(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null) + { + if (_lastSize != Size.Empty) + form.Size = _lastSize; + + if (_lastLoc != Point.Empty) + form.Location = _lastLoc; + } + } + + #endregion + + #region CollectionFormResize + + void CollectionFormResize(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastSize = form.Size; + } + + #endregion + + #region CollectionFormLocationChanged + + void CollectionFormLocationChanged(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastLoc = form.Location; + } + + #endregion + + #region PropertyGridGotFocus + + void PropertyGridGotFocus(object sender, EventArgs e) + { + PropertyGrid propertyGrid = sender as PropertyGrid; + + if (propertyGrid != null) + UpdateDesignerFocus(propertyGrid); + } + + #endregion + + #region PropertyGridSelectedObjectsChanged + + void PropertyGridSelectedObjectsChanged(object sender, EventArgs e) + { + PropertyGrid propertyGrid = sender as PropertyGrid; + + if (propertyGrid != null) + UpdateDesignerFocus(propertyGrid); + } + + #endregion + + #region UpdateDesignerFocus + + private void UpdateDesignerFocus(PropertyGrid propertyGrid) + { + GridContainer row = Context.Instance as GridContainer; + + if (row != null) + { + GridElement item = propertyGrid.SelectedObject as GridElement; + + if (item != null) + row.SuperGrid.DesignerElement = item; + } + } + + #endregion + + #endregion + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(GridColumn); + } + + #endregion + + #region CreateNewItemTypes + + protected override Type[] CreateNewItemTypes() + { + return new Type[] + { + typeof(GridTextBoxXEditControl), + typeof(GridButtonXEditControl), + typeof(GridCheckBoxXEditControl), + typeof(GridColorPickerEditControl), + typeof(GridComboBoxExEditControl), + typeof(GridComboTreeEditControl), + typeof(GridDateTimeInputEditControl), + typeof(GridDateTimePickerEditControl), + typeof(GridDoubleInputEditControl), + typeof(GridImageEditControl), + typeof(GridIntegerInputEditControl), + typeof(GridIpAddressInputEditControl), + typeof(GridLabelXEditControl), + typeof(GridMaskedTextBoxEditControl), + typeof(GridMicroChartEditControl), + typeof(GridNumericUpDownEditControl), + typeof(GridImageEditControl), + typeof(GridProgressBarXEditControl), + typeof(GridRadialMenuEditControl), + typeof(GridRatingStarEditControl), + typeof(GridSliderEditControl), + typeof(GridSwitchButtonEditControl), + typeof(GridTextBoxDropDownEditControl), + }; + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + object o = base.EditValue(context, provider, value); + + if (Context != null) + { + GridPanel panel = Context.Instance as GridPanel; + + if (panel != null) + { + if (panel.SuperGrid.DesignerElement is GridColumn) + panel.SuperGrid.DesignerElement = null; + } + } + + return (o); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + GridColumn item = (GridColumn)base.CreateInstance(typeof(GridColumn)); + + if (item != null) + { + item.EditorType = itemType; + + item.Name = GetColumnName(item); + } + + return (item); + } + + #region GetColumnName + + private string GetColumnName(GridColumn item) + { + GridPanel panel = Context.Instance as GridPanel; + + if (panel != null) + { + for (int i = 1; i < 200; i++) + { + string s = "Column" + i; + + if (panel.Columns[s] == null) + return (s); + } + } + + return (this.GetDisplayText(item)); + } + + #endregion + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/GridRowCollectionEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/GridRowCollectionEditor.cs new file mode 100644 index 00000000..4c1012a4 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/GridRowCollectionEditor.cs @@ -0,0 +1,311 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.Design +{ + /// + /// GridRowCollectionEditor + /// + public class GridRowCollectionEditor : CollectionEditor + { + #region Static variables + + static Size _lastSize = Size.Empty; + static Point _lastLoc = Point.Empty; + + #endregion + + #region Private variables + + private CollectionForm _CollectionForm; + private TableLayoutPanel _LayoutPanel; + private PropertyGrid _PropertyGrid; + + #endregion + + public GridRowCollectionEditor(Type type) + : base(type) + { + } + + #region CreateCollectionItemType + + protected override Type CreateCollectionItemType() + { + return typeof(GridRow); + } + + #endregion + + #region CreateCollectionForm + + protected override CollectionForm CreateCollectionForm() + { + _CollectionForm = base.CreateCollectionForm(); + + _LayoutPanel = + _CollectionForm.Controls["overArchingTableLayoutPanel"] as TableLayoutPanel; + + if (_LayoutPanel != null) + { + _PropertyGrid = + _LayoutPanel.Controls["propertyBrowser"] as PropertyGrid; + + if (_PropertyGrid != null) + { + _PropertyGrid.HelpVisible = true; + + _PropertyGrid.GotFocus += PropertyGridGotFocus; + _PropertyGrid.SelectedObjectsChanged += PropertyGridSelectedObjectsChanged; + } + } + + _CollectionForm.Load += CollectionFormLoad; + _CollectionForm.Resize += CollectionFormResize; + _CollectionForm.LocationChanged += CollectionFormLocationChanged; + + return (_CollectionForm); + } + + #region CollectionFormLoad + + void CollectionFormLoad(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null) + { + if (_lastSize != Size.Empty) + form.Size = _lastSize; + + if (_lastLoc != Point.Empty) + form.Location = _lastLoc; + } + } + + #endregion + + #region CollectionFormResize + + void CollectionFormResize(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastSize = form.Size; + } + + #endregion + + #region CollectionFormLocationChanged + + void CollectionFormLocationChanged(object sender, EventArgs e) + { + CollectionForm form = sender as CollectionForm; + + if (form != null && form.Visible == true) + _lastLoc = form.Location; + } + + #endregion + + #region PropertyGridGotFocus + + void PropertyGridGotFocus(object sender, EventArgs e) + { + UpdateDesignerFocus(); + + _LayoutPanel.Controls[4].Refresh(); + } + + #endregion + + #region PropertyGridSelectedObjectsChanged + + void PropertyGridSelectedObjectsChanged(object sender, EventArgs e) + { + UpdateDesignerFocus(); + } + + #endregion + + #region UpdateDesignerFocus + + private void UpdateDesignerFocus() + { + if (_PropertyGrid != null) + { + GridContainer row = Context.Instance as GridContainer; + + if (row != null) + { + GridElement item = _PropertyGrid.SelectedObject as GridElement; + + if (item != null) + row.SuperGrid.DesignerElement = item; + } + } + } + + #endregion + + #endregion + + #region CreateNewItemTypes + + protected override Type[] CreateNewItemTypes() + { + GridPanel panel = Context.Instance as GridPanel; + + if (panel == null) + { + return new Type[] + { + typeof (GridRow), + typeof (GridPanel), + }; + } + + return (base.CreateNewItemTypes()); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + object o; + + if (_CollectionForm != null && _CollectionForm.Visible) + { + GridRowCollectionEditor editor = + new GridRowCollectionEditor(this.CollectionType); + + o = editor.EditValue(context, provider, value); + } + else + { + o = base.EditValue(context, provider, value); + + GridPanel panel = Context.Instance as GridPanel; + + if (panel != null && panel.Parent == null) + panel.SuperGrid.DesignerElement = null; + } + + return (o); + } + + #endregion + + #region CreateInstance + + protected override object CreateInstance(Type itemType) + { + object o = base.CreateInstance(itemType); + + GridContainer crow = Context.Instance as GridContainer; + + if (crow != null) + { + IDesignerHost dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + + crow.Expanded = true; + + GridPanel cpanel = crow.GridPanel; + + GridRow row = o as GridRow; + + if (row != null) + { + if (cpanel.Columns.Count == 0) + { + if (dh != null) + { + GridColumn col = dh.CreateComponent(typeof(GridColumn)) as GridColumn; + + if (col != null) + { + col.Name = "Column1"; + cpanel.Columns.Add(col); + + GridCell cell = dh.CreateComponent(typeof(GridCell)) as GridCell; + + if (cell != null) + row.Cells.Add(cell); + + row.InvalidateRender(); + } + } + } + } + else + { + GridPanel panel = o as GridPanel; + + if (panel != null) + { + if (cpanel != null) + { + panel.Name = GetPanelName(cpanel); + + if (dh != null) + { + GridColumn col = dh.CreateComponent(typeof(GridColumn)) as GridColumn; + + col.Name = "Column1"; + panel.Columns.Add(col); + } + } + } + } + } + + return (o); + } + + #region GetPanelName + + private string GetPanelName(GridPanel panel) + { + for (int i = 1; i < 200; i++) + { + string s = "GridPanel" + i; + + if (UnusedPanelName(panel, s) == true) + return (s); + } + + return ("GridPanel"); + } + + #region UnusedPanelName + + private bool UnusedPanelName(GridPanel panel, string s) + { + foreach (GridContainer row in panel.Rows) + { + if (row is GridPanel) + { + if (s.Equals(((GridPanel) row).Name) == true) + return (false); + } + } + + return (true); + } + + #endregion + + #endregion + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexEditor.cs new file mode 100644 index 00000000..25e1e863 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexEditor.cs @@ -0,0 +1,124 @@ +using System; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Design; +using System.ComponentModel; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.Design +{ + /// + /// Represents the class used for picking an image from image list + /// + public class ImageIndexEditor : UITypeEditor + { + #region Private variables + + private ImageList _ImageList; + + #endregion + + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + if (context != null) + _ImageList = GetImageList(context); + + return (UITypeEditorEditStyle.DropDown); + } + + #region GetImageList + + private ImageList GetImageList(ITypeDescriptorContext context) + { + IReferenceService r = (IReferenceService)context.GetService(typeof(IReferenceService)); + + object[] objs = r.GetReferences(typeof(GridPanel)); + + if (objs.Length > 0) + { + GridPanel panel = (GridPanel)objs[0]; + GridElement item = panel.SuperGrid.DesignerElement; + + if (item != null) + return (item.GridPanel.ImageList); + + return (panel.ImageList); + } + + return (null); + } + + #endregion + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (true); + } + + #endregion + + #region PaintValue + + public override void PaintValue(PaintValueEventArgs e) + { + if (e.Value != null) + { + Image img = GetImage((int)e.Value); + + if (img != null) + e.Graphics.DrawImage(img, e.Bounds); + } + } + + #region GetImage + + private Image GetImage(int index) + { + if (_ImageList != null && (uint)index < _ImageList.Images.Count) + return (_ImageList.Images[index]); + + return (null); + } + + #endregion + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + IWindowsFormsEditorService editorService = + provider.GetService(typeof (IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (editorService != null && value is int) + { + ImageIndexTypeDropDown dd = new + ImageIndexTypeDropDown((int)value, _ImageList, editorService, context); + + dd.EscapePressed = false; + + editorService.DropDownControl(dd); + + if (dd.EscapePressed == true) + context.PropertyDescriptor.SetValue(context.Instance, value); + else + return (dd.Value); + } + + return (base.EditValue(context, provider, value)); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexTypeDropDown.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexTypeDropDown.Designer.cs new file mode 100644 index 00000000..2fb50957 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexTypeDropDown.Designer.cs @@ -0,0 +1,47 @@ +namespace DevComponents.SuperGrid.Design +{ + partial class ImageIndexTypeDropDown + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // ImageIndexTypeDropDown + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Name = "ImageIndexTypeDropDown"; + this.Size = new System.Drawing.Size(132, 78); + this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.DropDownPreviewKeyDown); + this.ResumeLayout(false); + + } + + #endregion + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexTypeDropDown.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexTypeDropDown.cs new file mode 100644 index 00000000..584b246e --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexTypeDropDown.cs @@ -0,0 +1,155 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.SuperGrid.Design +{ + [ToolboxItem(false)] + public partial class ImageIndexTypeDropDown : UserControl + { + #region Private variables + + private int _Value; + private bool _EscapePressed; + private ImageList _ImageList; + private ImageListBox _ListBox; + + private IWindowsFormsEditorService _EditorService; + private ITypeDescriptorContext _Context; + + #endregion + + public ImageIndexTypeDropDown(int value, ImageList imageList, + IWindowsFormsEditorService editorService, ITypeDescriptorContext context) + { + _EditorService = editorService; + _Context = context; + _Value = value; + _ImageList = imageList; + + Initialize(); + } + + public ImageIndexTypeDropDown() + { + Initialize(); + } + + #region Initialize + + private void Initialize() + { + InitializeComponent(); + + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + + if (_ImageList != null) + { + _ListBox = new ImageListBox(); + + Controls.Add(_ListBox); + + _ListBox.MouseClick += ListBoxMouseClick; + _ListBox.SelectedIndexChanged += ListBoxSelectedIndexChanged; + _ListBox.ImageList = _ImageList; + _ListBox.BorderStyle = BorderStyle.None; + _ListBox.Dock = DockStyle.Fill; + + for (int i = 0; i < _ImageList.Images.Count; i++) + { + ImageListBoxItem item = + new ImageListBoxItem(i.ToString(), i); + + _ListBox.Items.Add(item); + } + + _ListBox.Items.Add(new ImageListBoxItem("(none)", _ImageList.Images.Count)); + + int index = Value; + + _ListBox.SelectedIndex = + (index >= 0 && index < _ImageList.Images.Count) + ? index : _ImageList.Images.Count; + + Size = _ListBox.PreferredSize; + } + } + + #endregion + + #region Public properties + + #region EditorService + + public IWindowsFormsEditorService EditorService + { + get { return (_EditorService); } + set { _EditorService = value; } + } + + #endregion + + #region EscapePressed + + public bool EscapePressed + { + get { return (_EscapePressed); } + set { _EscapePressed = value; } + } + + #endregion + + #region Value + + public int Value + { + get { return (_Value); } + + set + { + _Value = value; + + _Context.OnComponentChanging(); + _Context.PropertyDescriptor.SetValue(_Context.Instance, value); + _Context.OnComponentChanged(); + } + } + + #endregion + + #endregion + + #region DropDownPreviewKeyDown + + private void DropDownPreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + if (e.KeyCode == Keys.Escape) + _EscapePressed = true; + } + + #endregion + + #region ListBoxMouseClick + + private void ListBoxMouseClick(object sender, MouseEventArgs e) + { + _EditorService.CloseDropDown(); + } + + #endregion + + #region ListBoxSelectedIndexChanged + + protected virtual void ListBoxSelectedIndexChanged(object sender, EventArgs e) + { + int index = _ListBox.SelectedIndex; + + Value = (index >= _ImageList.Images.Count ? -1 : index); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexTypeDropDown.resx b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexTypeDropDown.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageIndexTypeDropDown.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageListBox.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageListBox.cs new file mode 100644 index 00000000..605fb5ed --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ImageListBox.cs @@ -0,0 +1,143 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.SuperGrid.Design +{ + [ToolboxItem(false)] + public class ImageListBox : ListBox + { + #region Private variables + + private ImageList _ImageList; + + #endregion + + public ImageListBox() + { + MinimumSize = new Size(20, 20); + IntegralHeight = true; + + DrawMode = DrawMode.OwnerDrawVariable; + } + + #region Public properties + + public ImageList ImageList + { + get { return (_ImageList); } + set { _ImageList = value; } + } + + #endregion + + #region OnMeasureItem + + protected override void OnMeasureItem(MeasureItemEventArgs e) + { + base.OnMeasureItem(e); + + e.ItemWidth += 22; + + if (e.ItemHeight < 20) + e.ItemHeight = 20; + } + + #endregion + + #region OnDrawItem + + protected override void OnDrawItem(DrawItemEventArgs e) + { + Graphics g = e.Graphics; + + e.DrawBackground(); + + if (e.Index < Items.Count) + { + Rectangle r = e.Bounds; + r.Width = 18; + + if (r.Height > 18) + { + r.Y += (r.Height - 18)/2; + r.Height = 18; + } + + ImageListBoxItem item = (ImageListBoxItem) Items[e.Index]; + + Image image = (uint) item.ImageIndex < _ImageList.Images.Count + ? _ImageList.Images[item.ImageIndex] + : null; + + if (image != null) + g.DrawImage(image, r); + + g.DrawRectangle(Pens.Black, r); + + using (Brush br = new SolidBrush(e.ForeColor)) + { + using (StringFormat sf = new StringFormat()) + { + sf.Alignment = StringAlignment.Near; + sf.LineAlignment = StringAlignment.Center; + + r = e.Bounds; + r.X += 30; + r.Width -= 30; + + g.DrawString(item.Text, e.Font, br, r, sf); + } + } + } + } + + #endregion + } + + public class ImageListBoxItem + { + #region Private variables + + private string _Text; + private int _ImageIndex; + + #endregion + + #region Constructors + + public ImageListBoxItem(string text, int index) + { + Text = text; + ImageIndex = index; + } + + public ImageListBoxItem(string text) + : this(text, -1) + { + } + + public ImageListBoxItem() + : this("", -1) + { + } + + #endregion + + #region Public properties + + public int ImageIndex + { + get { return (_ImageIndex); } + set { _ImageIndex = value; } + } + + public string Text + { + get { return (_Text); } + set { _Text = value; } + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridActionList.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridActionList.cs new file mode 100644 index 00000000..1ae72d4d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridActionList.cs @@ -0,0 +1,401 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Data.SqlTypes; +using System.Drawing.Design; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.Design +{ + public class SuperGridActionList : DesignerActionList, + ITypeDescriptorContext, IWindowsFormsEditorService, IServiceProvider + { + #region Private variables + + private SuperGridControl _SuperGrid; + + private PropertyDescriptor _PropertyDescriptor; + private IComponentChangeService _ChangeService; + + private IDesignerHost dh; + + #endregion + + /// + /// SuperGridActionList + /// + /// Associated SuperGridControl + public SuperGridActionList(SuperGridControl superGrid) + : base(superGrid) + { + _SuperGrid = superGrid; + + _ChangeService = Component.Site.GetService(typeof(IComponentChangeService)) as IComponentChangeService; + } + + #region Public properties + + /// + /// Gets or sets the GridPanel DataSource + /// + [AttributeProvider(typeof(IListSource))] + public object DataSource + { + get { return (_SuperGrid.PrimaryGrid.DataSource); } + set { SetValue("DataSource", value); } + } + + /// + /// Gets or sets whether rows can be deleted + /// + public bool AllowRowDelete + { + get { return (_SuperGrid.PrimaryGrid.AllowRowDelete); } + set { SetValue("AllowRowDelete", value); } + } + + /// + /// Gets or sets whether rows can be Inserted + /// + public bool AllowRowInsert + { + get { return (_SuperGrid.PrimaryGrid.AllowRowInsert); } + set { SetValue("AllowRowInsert", value); } + } + + /// + /// Gets or sets whether the Insert Row is displayed at runtime + /// + public bool ShowInsertRow + { + get { return (_SuperGrid.PrimaryGrid.ShowInsertRow); } + set { SetValue("ShowInsertRow", value); } + } + + /// + /// Gets or sets which Grid Lines are displayed + /// + public GridLines GridLines + { + get { return (_SuperGrid.PrimaryGrid.GridLines); } + set { SetValue("GridLines", value); } + } + + /// + /// Gets or sets whether Tree Lines are displayed + /// + public bool ShowTreeLines + { + get { return (_SuperGrid.PrimaryGrid.ShowTreeLines); } + set { SetValue("ShowTreeLines", value); } + } + + /// + /// Gets or sets whether Tree Buttons are displayed + /// + public bool ShowTreeButtons + { + get { return (_SuperGrid.PrimaryGrid.ShowTreeButtons); } + set { SetValue("ShowTreeButtons", value); } + } + + /// + /// Gets or sets whether to use the Alternate Row Style + /// + public bool UseAlternateRowStyle + { + get { return (_SuperGrid.PrimaryGrid.UseAlternateRowStyle); } + set { SetValue("UseAlternateRowStyle", value); } + } + + /// + /// Gets or sets whether to use the Alternate Column Style + /// + public bool UseAlternateColumnStyle + { + get { return (_SuperGrid.PrimaryGrid.UseAlternateColumnStyle); } + set { SetValue("UseAlternateColumnStyle", value); } + } + + /// + /// Gets or sets whether to allow multi selection + /// + public bool MultiSelect + { + get { return (_SuperGrid.PrimaryGrid.MultiSelect); } + set { SetValue("MultiSelect", value); } + } + + /// + /// Gets or sets the selection granularity + /// + public SelectionGranularity SelectionGranularity + { + get { return (_SuperGrid.PrimaryGrid.SelectionGranularity); } + set { SetValue("SelectionGranularity", value); } + } + + #endregion + + #region SetValue + + private void SetValue(string property, object value) + { + _ChangeService.OnComponentChanging(_SuperGrid.PrimaryGrid, null); + + GetPrimaryGridPropertyByName(property).SetValue(_SuperGrid.PrimaryGrid, value); + + _ChangeService.OnComponentChanged(_SuperGrid.PrimaryGrid, null, null, null); + } + + #endregion + + #region GetPrimaryGridPropertyByName + + /// + /// Gets the PrimaryGrid property via the given name + /// + /// Property name + /// PropertyDescriptor + private PropertyDescriptor GetPrimaryGridPropertyByName(string propName) + { + PropertyDescriptor prop = + TypeDescriptor.GetProperties(_SuperGrid.PrimaryGrid)[propName]; + + if (prop == null) + throw new ArgumentException("Matching property not found.", propName); + + return (prop); + } + + #endregion + + #region GetSortedActionItems + + /// + /// Gets the SortedActionItems + /// + /// DesignerActionItemCollection + public override DesignerActionItemCollection GetSortedActionItems() + { + DesignerActionItemCollection items = new DesignerActionItemCollection(); + + items.Add(new DesignerActionPropertyItem("DataSource", "Data Source", + "Data", "Sets the GridPanel Data Source.")); + + items.Add(new DesignerActionPropertyItem("AllowRowDelete", "Allow Row Delete", + "User Interaction", "Determines whether rows can be deleted.")); + + items.Add(new DesignerActionPropertyItem("AllowRowInsert", "Allow Row Insert", + "User Interaction", "Determines whether rows can be inserted.")); + + items.Add(new DesignerActionPropertyItem("ShowInsertRow", "Show Insert Row", + "User Interaction", "Determines whether the InsertRow is shown at runtime.")); + + items.Add(new DesignerActionPropertyItem("GridLines", "Grid Lines", + "Appearance", "Determines which Grid Lines are displayed.")); + + items.Add(new DesignerActionPropertyItem("ShowTreeLines", "Show Tree Lines", + "Appearance", "Determines whether Tree Lines are displayed.")); + + items.Add(new DesignerActionPropertyItem("ShowTreeButtons", "Show Tree Buttons", + "Appearance", "Determines whether Tree Buttons are displayed.")); + + items.Add(new DesignerActionPropertyItem("UseAlternateColumnStyle", "Use Alternate Column Style", + "Style", "Determines whether to use the defined Alternate Column Style.")); + + items.Add(new DesignerActionPropertyItem("UseAlternateRowStyle", "Use Alternate Row Style", + "Style", "Determines whether to use the defined Alternate Row Style.")); + + items.Add(new DesignerActionPropertyItem("SelectionGranularity", "Selection Granularity", + "Behavior", "Determines user selection granularity.")); + + items.Add(new DesignerActionPropertyItem("MultiSelect", "Enable Multi Selection", + "Behavior", "Determines whether Multi Selection is enabled.")); + + if (DataSource != null) + { + items.Add(new DesignerActionMethodItem(this, "GenBoundColumns", "Generate Bound Columns", + "Data1", "Clears all previous bound column definitions and\r\ngenerates new column definitions from current DataSource.")); + } + + items.Add(new DesignerActionMethodItem(this, "EditColumns", "Edit Columns...", "Data2")); + items.Add(new DesignerActionMethodItem(this, "EditRows", "Edit Rows...", "Data2")); + + return (items); + } + + #endregion + + #region EditColumns + + /// + /// EditColumns + /// + private void EditColumns() + { + _PropertyDescriptor = TypeDescriptor.GetProperties(_SuperGrid.PrimaryGrid)["Columns"]; + + UITypeEditor editor = (UITypeEditor)_PropertyDescriptor.GetEditor(typeof(UITypeEditor)); + + if (editor != null) + editor.EditValue(this, this, _SuperGrid.PrimaryGrid.Columns); + } + + #endregion + + #region EditRows + + /// + /// EditRows + /// + private void EditRows() + { + _PropertyDescriptor = TypeDescriptor.GetProperties(_SuperGrid.PrimaryGrid)["Rows"]; + + UITypeEditor editor = (UITypeEditor)_PropertyDescriptor.GetEditor(typeof(UITypeEditor)); + + if (editor != null) + editor.EditValue(this, this, _SuperGrid.PrimaryGrid.Rows); + } + + #endregion + + #region GenBoundColumns + + /// + /// GenBoundColumns + /// + private void GenBoundColumns() + { + dh = (IDesignerHost)GetService(typeof(IDesignerHost)); + + if (dh != null) + { + DesignerTransaction dt = dh.CreateTransaction(); + + try + { + IComponentChangeService change = + GetService(typeof(IComponentChangeService)) as IComponentChangeService; + + if (change != null) + { + change.OnComponentChanging(Component, null); + + GridColumnCollection colc = _SuperGrid.PrimaryGrid.Columns; + + _SuperGrid.PrimaryGrid.GenerateColumns(CreateGridColumn); + + GridColumnCollection cc = _SuperGrid.PrimaryGrid.Columns; + + for (int i = cc.Count - 1; i >= 0; i--) + { + GridColumn col = cc[i]; + + if (string.IsNullOrEmpty(col.DataPropertyName) == false && col.IsDataBound == false) + cc.RemoveAt(i); + } + + change.OnComponentChanged(Component, null, null, null); + } + } + catch + { + dt.Cancel(); + } + finally + { + if (dt.Canceled == false) + dt.Commit(); + } + } + + } + + #region CreateGridColumn + + private GridColumn CreateGridColumn() + { + if (dh != null) + return (dh.CreateComponent(typeof(GridColumn)) as GridColumn); + + return (null); + } + + #endregion + + #endregion + + #region ITypeDescriptorContext Members + + public IContainer Container + { + get { return (Component.Site.Container); } + } + + public object Instance + { + get { return (Component); } + } + + public void OnComponentChanged() + { + object value = _SuperGrid.PrimaryGrid.Columns; + + _ChangeService.OnComponentChanged(Component, _PropertyDescriptor, value, value); + } + + public bool OnComponentChanging() + { + if (Component is SuperGridControl) + _ChangeService.OnComponentChanging(((SuperGridControl)Component).PrimaryGrid, _PropertyDescriptor); + else + _ChangeService.OnComponentChanging(Component, _PropertyDescriptor); + + return true; + } + + public PropertyDescriptor PropertyDescriptor + { + get { return (_PropertyDescriptor); } + } + + #endregion + + #region IWindowsFormsEditorService Members + + public void CloseDropDown() + { + throw new Exception("The method or operation is not implemented."); + } + + public void DropDownControl(Control control) + { + throw new Exception("The method or operation is not implemented."); + } + + public DialogResult ShowDialog(Form dialog) + { + return (dialog.ShowDialog()); + } + + #endregion + + #region IServiceProvider + + object IServiceProvider.GetService(Type serviceType) + { + if (serviceType.Equals(typeof(IWindowsFormsEditorService))) + return (this); + + return GetService(serviceType); + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridDesignTime.csproj b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridDesignTime.csproj new file mode 100644 index 00000000..bc1decc8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridDesignTime.csproj @@ -0,0 +1,169 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {D06A8233-416A-4547-BFF6-7A26345B7396} + Library + Properties + DevComponents.SuperGrid.Design + DevComponents.SuperGrid.Design + + + true + SuperGridDesignTime.snk + v2.0 + + + 2.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE;SUPERGRID + prompt + 4 + + + AllRules.ruleset + + + bin\Release\ + TRACE;SUPERGRID;TRIAL + + + true + pdbonly + AnyCPU + prompt + AllRules.ruleset + + + + + + UserControl + + + + + UserControl + + + ImageIndexTypeDropDown.cs + + + + + Component + + + + + UserControl + + + ValueTypeDropDown.cs + + + + + + + UserControl + + + EditTypeDropDown.cs + + + + + + + {A344305F-D2E2-4350-B61E-D7277959A5B4} + SuperGrid + + + {36546CE3-335C-4AB6-A2F3-40F8C818BC66} + DotNetBar + + + + + + + + + + + + + + + + + ImageIndexTypeDropDown.cs + Designer + + + ValueTypeDropDown.cs + Designer + + + EditTypeDropDown.cs + Designer + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridDesignTime.snk b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridDesignTime.snk new file mode 100644 index 00000000..d9c2a028 Binary files /dev/null and b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridDesignTime.snk differ diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridDesigner.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridDesigner.cs new file mode 100644 index 00000000..5e9484a2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/SuperGridDesigner.cs @@ -0,0 +1,278 @@ +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.Controls; +using DevComponents.DotNetBar.SuperGrid; +using System; +using System.Collections; + +namespace DevComponents.SuperGrid.Design +{ + /// + /// SuperGridDesigner + /// + public class SuperGridDesigner : ControlDesigner + { + #region Private variables + + private SuperGridControl _SuperGrid; + private DesignerActionListCollection _ActionLists; + + #endregion + + #region Initialize + + /// + /// Initializes our designer + /// + /// + public override void Initialize(IComponent component) + { + base.Initialize(component); + + if (component.Site.DesignMode == true) + _SuperGrid = component as SuperGridControl; + +#if !TRIAL + IDesignerHost dh = this.GetService(typeof(IDesignerHost)) as IDesignerHost; + if (dh != null) + dh.LoadComplete += new EventHandler(DesignerLoadComplete); +#endif + + // If our component is removed we need to clean-up + IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService)); + + if (cc != null) + cc.ComponentRemoving += new ComponentEventHandler(OnComponentRemoving); + } + + #endregion + + #region Dispose + + protected override void Dispose(bool disposing) + { + // If our component is removed we need to clean-up + IComponentChangeService cc = (IComponentChangeService)GetService(typeof(IComponentChangeService)); + + if (cc != null) + cc.ComponentRemoving -= new ComponentEventHandler(OnComponentRemoving); + } + + #endregion + + #region Verbs + + /// + /// Creates our verb collection + /// + public override DesignerVerbCollection Verbs + { + get + { + DesignerVerb[] verbs = new DesignerVerb[] + { + //new DesignerVerb("KnobStyle 1", SetStyle1), + //new DesignerVerb("KnobStyle 2", SetStyle2), + //new DesignerVerb("KnobStyle 3", SetStyle3), + //new DesignerVerb("KnobStyle 4", SetStyle4), + }; + + return (new DesignerVerbCollection(verbs)); + } + } + + #endregion + + #region ActionLists + + /// + /// Gets our DesignerActionListCollection list + /// + public override DesignerActionListCollection ActionLists + { + get + { + if (_ActionLists == null) + { + _ActionLists = new DesignerActionListCollection(); + + _ActionLists.Add(new SuperGridActionList(_SuperGrid)); + } + + return (_ActionLists); + } + } + + #endregion + + #region OnSetCursor + + protected override void OnSetCursor() + { + if (InScrollBar(Control.MousePosition) == true) + Cursor.Current = Cursors.Default; + + base.OnSetCursor(); + } + + #region InScrollBar + + private bool InScrollBar(Point point) + { + if (_SuperGrid != null) + { + Point pt = _SuperGrid.PointToClient(point); + + if (_SuperGrid.HScrollBar.Visible) + { + if (_SuperGrid.HScrollBar.Bounds.Contains(pt)) + return (true); + } + + if (_SuperGrid.VScrollBar.Visible) + { + if (_SuperGrid.VScrollBar.Bounds.Contains(pt)) + return (true); + } + } + + return (false); + } + + #endregion + + #endregion + + #region OnComponentRemoving + + /// Called when component is about to be removed from designer. + /// Event sender. + /// Event arguments. + 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(AssociatedComponents); + + foreach (IComponent c in list) + dh.DestroyComponent(c); + } + } + + #endregion + + #region AssociatedComponents + + /// + /// Returns all components associated with this control + /// + public override ICollection AssociatedComponents + { + get + { + ArrayList c = new ArrayList(base.AssociatedComponents); + + SuperGridControl sg = Control as SuperGridControl; + + if (sg != null) + GetComponents(sg.PrimaryGrid, c); + + return (c); + } + } + + #region GetComponents + + private void GetComponents(GridContainer cont, ArrayList c) + { + if (cont is GridPanel) + { + foreach (GridColumn col in ((GridPanel)cont).Columns) + c.Add(col); + } + + if (cont.Rows != null && cont.Rows.Count > 0) + { + foreach (GridElement item in cont.Rows) + { + c.Add(item); + + if (item is GridRow) + { + foreach (GridCell cell in ((GridRow)item).Cells) + c.Add(cell); + } + + if (item is GridContainer) + GetComponents((GridContainer)item, c); + } + } + } + + #endregion + + #endregion + + #region GetHitTest + + protected override bool GetHitTest(Point point) + { + if (InScrollBar(point) == true) + return (true); + + return (base.GetHitTest(point)); + } + + #endregion + + #region Licensing Stuff + public override void InitializeNewComponent(IDictionary defaultValues) + { + base.InitializeNewComponent(defaultValues); + SetDesignTimeDefaults(); + } + private void SetDesignTimeDefaults() + { + SuperGridControl c = this.Control as SuperGridControl; +#if !TRIAL + string key = GetLicenseKey(); + c.LicenseKey = key; +#endif + } +#if !TRIAL + internal static 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.DotNetBar.DotNetBarManager2"); + if (keyValue != null) + key = keyValue.ToString(); + } + return key; + } + private void DesignerLoadComplete(object sender, EventArgs e) + { + IDesignerHost dh = this.GetService(typeof(IDesignerHost)) as IDesignerHost; + if (dh != null) + dh.LoadComplete -= new EventHandler(DesignerLoadComplete); + + string key = GetLicenseKey(); + SuperGridControl grid = this.Control as SuperGridControl; + if (key != "" && grid != null && grid.LicenseKey == "" && grid.LicenseKey != key) + TypeDescriptor.GetProperties(grid)["LicenseKey"].SetValue(grid, key); + } +#endif + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeDropDown.Designer.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeDropDown.Designer.cs new file mode 100644 index 00000000..7a508a3c --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeDropDown.Designer.cs @@ -0,0 +1,66 @@ +namespace DevComponents.SuperGrid.Design +{ + partial class ValueTypeDropDown + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.listBox1 = new System.Windows.Forms.ListBox(); + this.SuspendLayout(); + // + // listBox1 + // + this.listBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.listBox1.FormattingEnabled = true; + this.listBox1.IntegralHeight = false; + this.listBox1.Location = new System.Drawing.Point(0, 0); + this.listBox1.Name = "listBox1"; + this.listBox1.Size = new System.Drawing.Size(172, 78); + this.listBox1.TabIndex = 1; + this.listBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.ListBoxMouseClick); + this.listBox1.SelectedIndexChanged += new System.EventHandler(this.ListBoxSelectedIndexChanged); + // + // ValueTypeDropDown + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.listBox1); + this.Name = "ValueTypeDropDown"; + this.Size = new System.Drawing.Size(172, 78); + this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.DropDownPreviewKeyDown); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ListBox listBox1; + + + + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeDropDown.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeDropDown.cs new file mode 100644 index 00000000..63ec820b --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeDropDown.cs @@ -0,0 +1,151 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace DevComponents.SuperGrid.Design +{ + [ToolboxItem(false)] + public partial class ValueTypeDropDown : UserControl + { + #region Private variables + + private object _Value; + private bool _EscapePressed; + + private IWindowsFormsEditorService _EditorService; + private ITypeDescriptorContext _Context; + + #endregion + + public ValueTypeDropDown(object value, + IWindowsFormsEditorService editorService, ITypeDescriptorContext context) + { + _EditorService = editorService; + _Context = context; + _Value = value; + + Initialize(); + } + + public ValueTypeDropDown() + { + Initialize(); + } + + #region Initialize + + private void Initialize() + { + InitializeComponent(); + + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + + string[] items = GetListBoxItems(); + + listBox1.Items.Clear(); + listBox1.Items.AddRange(items); + + listBox1.SelectedIndex = GetSelectedIndex(); + + int height = 0; + int width = 0; + + foreach (string s in listBox1.Items) + { + Size size = TextRenderer.MeasureText(s, listBox1.Font); + + width = Math.Max(width, size.Width); + height += listBox1.ItemHeight; + } + + height += 5; + + Size = new Size(width, height); + } + + protected virtual string[] GetListBoxItems() + { + return (null); + } + + protected virtual int GetSelectedIndex() + { + return (0); + } + + #endregion + + #region Public properties + + #region EditorService + + public IWindowsFormsEditorService EditorService + { + get { return (_EditorService); } + set { _EditorService = value; } + } + + #endregion + + #region EscapePressed + + public bool EscapePressed + { + get { return (_EscapePressed); } + set { _EscapePressed = value; } + } + + #endregion + + #region Value + + public object Value + { + get { return (_Value); } + + set + { + _Value = value; + + _Context.OnComponentChanging(); + _Context.PropertyDescriptor.SetValue(_Context.Instance, value); + _Context.OnComponentChanged(); + } + } + + #endregion + + #endregion + + #region DropDownPreviewKeyDown + + private void DropDownPreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + if (e.KeyCode == Keys.Escape) + _EscapePressed = true; + } + + #endregion + + #region ListBoxMouseClick + + private void ListBoxMouseClick(object sender, MouseEventArgs e) + { + _EditorService.CloseDropDown(); + } + + #endregion + + #region ListBoxSelectedIndexChanged + + protected virtual void ListBoxSelectedIndexChanged(object sender, EventArgs e) + { + } + + #endregion + } +} diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeDropDown.resx b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeDropDown.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeDropDown.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeEditor.cs b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeEditor.cs new file mode 100644 index 00000000..b571e0cd --- /dev/null +++ b/PROMS/DotNetBar Source Code/DevComponents.SuperGrid.Design/ValueTypeEditor.cs @@ -0,0 +1,144 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; +using System.Windows.Forms.Design; +using DevComponents.DotNetBar.SuperGrid; + +namespace DevComponents.SuperGrid.Design +{ + public class ValueTypeEditor : UITypeEditor + { + #region Private variables + + private GridCell _Cell; + private GridColumn _Column; + + private bool _HasBoolDropDown; + + #endregion + + #region GetEditStyle + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + if (context != null) + { + _Cell = context.Instance as GridCell; + + if (_Cell != null) + { + _HasBoolDropDown = HasBoolDropDown(_Cell); + } + else + { + _Column = context.Instance as GridColumn; + + if (_Column != null) + _HasBoolDropDown = HasBoolDropDown(_Column); + } + } + + return (UITypeEditorEditStyle.DropDown); + } + + #region HasBoolDropDown + + private bool HasBoolDropDown(GridCell cell) + { + if (cell.EditorType != null) + return (HasBoolDropDown(cell.EditorType)); + + return (HasBoolDropDown(cell.GridColumn)); + } + + private bool HasBoolDropDown(GridColumn column) + { + if (column != null) + return (HasBoolDropDown(column.EditorType)); + + return (false); + } + + private bool HasBoolDropDown(Type type) + { + if (type == typeof(GridCheckBoxEditControl) || + type == typeof(GridCheckBoxXEditControl) || + type == typeof(GridSwitchButtonEditControl)) + { + return (true); + } + + return (false); + } + + #endregion + + #region IsDropDownResizable + + public override bool IsDropDownResizable + { + get { return (_HasBoolDropDown == false); } + } + + #endregion + + #endregion + + #region GetPaintValueSupported + + public override bool GetPaintValueSupported(ITypeDescriptorContext context) + { + return (false); + } + + #endregion + + #region EditValue + + public override object EditValue( + ITypeDescriptorContext context, IServiceProvider provider, object value) + { + IWindowsFormsEditorService editorService = + provider.GetService(typeof (IWindowsFormsEditorService)) as IWindowsFormsEditorService; + + if (editorService != null) + { + if (_HasBoolDropDown == true) + { + BoolValueTypeDropDown bv = new BoolValueTypeDropDown(value, editorService, context); + + bv.EscapePressed = false; + + editorService.DropDownControl(bv); + + if (bv.EscapePressed == true) + context.PropertyDescriptor.SetValue(context.Instance, value); + else + return (bv.Value); + } + else + { + TextBox tb = new TextBox(); + + tb.Multiline = true; + tb.Size = new Size(300, 100); + tb.ScrollBars = ScrollBars.Both; + + if (value != null) + tb.Text = value.ToString(); + + editorService.DropDownControl(tb); + + return (tb.Text); + } + } + + return (base.EditValue(context, provider, value)); + } + + #endregion + } +} + diff --git a/PROMS/DotNetBar Source Code/Display.cs b/PROMS/DotNetBar Source Code/Display.cs new file mode 100644 index 00000000..bfc7c0b2 --- /dev/null +++ b/PROMS/DotNetBar Source Code/Display.cs @@ -0,0 +1,60 @@ +using System.Drawing; +using System.Drawing.Drawing2D; + +#if TREEGX +namespace DevComponents.Tree +#elif DOTNETBAR +namespace DevComponents.DotNetBar +#endif +{ + /// + /// Summary description for Display. + /// + internal class Display + { + private Display() + { + } + + 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; + } + } +} diff --git a/PROMS/DotNetBar Source Code/DisplayHelp.cs b/PROMS/DotNetBar Source Code/DisplayHelp.cs new file mode 100644 index 00000000..b47669f5 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DisplayHelp.cs @@ -0,0 +1,1068 @@ +using System.Drawing; +using System.Drawing.Drawing2D; +using System; +using System.Drawing.Text; +using System.Windows.Forms.VisualStyles; + +#if AdvTree +namespace DevComponents.Tree +#elif DOTNETBAR +namespace DevComponents.DotNetBar +#elif LAYOUT +namespace DevComponents.DotNetBar.Layout +#endif +{ + /// + /// Summary description for Display. + /// + public class DisplayHelp + { + private DisplayHelp() + { + } + public static Brush CreateBrush(RectangleF bounds, Color[] backColors, int backColorsGradientAngle, float[] backColorsPositions) + { + return CreateBrush(Rectangle.Round(bounds), backColors, backColorsGradientAngle, backColorsPositions); + } + public static Brush CreateBrush(Rectangle bounds, Color[] backColors, int backColorsGradientAngle, float[] backColorsPositions) + { + if (backColors.Length == 0) + return new SolidBrush(Color.White); + else if (backColors.Length == 1) + return new SolidBrush(backColors[0]); + else + { + LinearGradientBrush brush = new LinearGradientBrush(bounds, backColors[0], backColors[backColors.Length - 1], backColorsGradientAngle); + if (backColors.Length > 2) + { + ColorBlend blend = new ColorBlend(); + blend.Colors = backColors; + if (backColorsPositions.Length > 0) + blend.Positions = backColorsPositions; + else + { + float[] pos=new float[backColors.Length]; + float f = 1/backColors.Length; + pos[backColors.Length - 1] = 1f; + for (int i = 1; i < backColors.Length - 1; i++) + { + pos[i] = f*1; + } + blend.Positions = pos; + } + brush.InterpolationColors = blend; + } + return brush; + } + } + 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); + } + + private static Pen GetPen(Color color, Color lastColor, Pen lastPen) + { + if (lastPen == null || color != lastColor) + { + if (lastPen != null) + lastPen.Dispose(); + return new Pen(color); + } + else + { + + return lastPen; + } + } + public static void DrawRoundedRectangle(System.Drawing.Graphics g, Rectangle r, Color[] borderColors, int cornerRadius) + { + if (cornerRadius <= 0) + { + // Square corners consider borderColors array differently. For less than 4 colors each color specifies color + // for all 4 sides of borders. For 4 colors or more in array the array of colors is considered as: Left, Top, Right, Bottom specification + if (borderColors.Length < 4) + { + Pen pen = null; + Color lastColor = Color.Empty; + r.Width--; + r.Height--; // GDI+ render bug fix + for (int i = 0; i < borderColors.Length; i++) + { + if (borderColors[i].IsEmpty) continue; + pen = GetPen(borderColors[i], lastColor, pen); + g.DrawRectangle(pen, r); + r.Inflate(-1,-1); + } + if (pen != null) + { + pen.Dispose(); + pen = null; + } + } + else + { + Pen pen = null; + Color lastColor = Color.Empty; + for (int i = 0; i < borderColors.Length; i += 4) + { + Color left = borderColors[i]; + Color top = borderColors[i+1]; + Color right = borderColors[i + 2]; + Color bottom = borderColors[i + 3]; + if (!left.IsEmpty) + { + pen = GetPen(left, lastColor, pen); + g.DrawLine(pen, r.X, r.Y, r.X, r.Bottom); + lastColor = left; + } + if (!top.IsEmpty) + { + pen = GetPen(top, lastColor, pen); + g.DrawLine(pen, r.X, r.Y, r.Right, r.Y); + lastColor = top; + } + if (!right.IsEmpty) + { + pen = GetPen(right, lastColor, pen); + g.DrawLine(pen, r.Right - 1, r.Y, r.Right - 1, r.Bottom); + lastColor = right; + } + if (!bottom.IsEmpty) + { + pen = GetPen(bottom, lastColor, pen); + g.DrawLine(pen, r.X, r.Bottom - 1, r.Right, r.Bottom - 1); + lastColor = bottom; + } + } + if (pen != null) + { + pen.Dispose(); + pen = null; + } + } + } + else + { + for (int i = 0; i < borderColors.Length; i++) + { + DrawRoundedRectangle(g, borderColors[i], r, cornerRadius); + r.Inflate(-1, -1); + } + } + } + + public static void DrawRoundedRectangle(System.Drawing.Graphics g, Color color, DevComponents.DotNetBar.Rendering.LinearGradientColorTable fillColor, Rectangle bounds, int cornerSize) + { + using (Brush fill = CreateBrush(bounds, fillColor)) + { + using (Pen pen = new Pen(color)) + DrawRoundedRectangle(g, pen, fill, bounds.X, bounds.Y, bounds.Width, bounds.Height, cornerSize); + } + } + + public static void DrawRoundedRectangle(System.Drawing.Graphics g, Color color, Color fillColor, Rectangle bounds, int cornerSize) + { + using (Brush fill = new SolidBrush(fillColor)) + { + using (Pen pen = new Pen(color)) + DrawRoundedRectangle(g, pen, fill, bounds.X, bounds.Y, bounds.Width, bounds.Height, cornerSize); + } + } + + 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) + { + DrawRoundedRectangle(g, pen, null, x, y, width, height, cornerSize); + } + public static void DrawRoundedRectangle(System.Drawing.Graphics g, System.Drawing.Pen pen, Brush fill, 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)) + { + if (fill != null) + g.FillPath(fill, path); + g.DrawPath(pen, path); + } + + //g.SmoothingMode = sm; + } + + public static GraphicsPath GetRoundedRectanglePath(Rectangle r, int cornerSize) + { + GraphicsPath path = new GraphicsPath(); + if (cornerSize == 0) + path.AddRectangle(r); + else + { + 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 r, int cornerTopLeft, int cornerTopRight, int cornerBottomRight, int cornerBottomLeft) + { + GraphicsPath path = new GraphicsPath(); + ElementStyleDisplay.AddCornerArc(path, r, cornerTopLeft, eCornerArc.TopLeft); + ElementStyleDisplay.AddCornerArc(path, r, cornerTopRight, eCornerArc.TopRight); + ElementStyleDisplay.AddCornerArc(path, r, cornerBottomRight, eCornerArc.BottomRight); + ElementStyleDisplay.AddCornerArc(path, r, cornerBottomLeft, eCornerArc.BottomLeft); + path.CloseAllFigures(); + return path; + } + + public static GraphicsPath GetRoundedRectanglePath(Rectangle clientRectangle, int cornerSize, eStyleBackgroundPathPart pathPart, + eCornerType topLeftCornerType, eCornerType topRightCornerType, eCornerType bottomLeftCornerType, eCornerType bottomRightCornerType) + { + return GetRoundedRectanglePath(clientRectangle, cornerSize, pathPart, topLeftCornerType, topRightCornerType, bottomLeftCornerType, bottomRightCornerType, 0); + } + + public static GraphicsPath GetRoundedRectanglePath(Rectangle clientRectangle, int cornerSize, eStyleBackgroundPathPart pathPart, + eCornerType topLeftCornerType, eCornerType topRightCornerType, eCornerType bottomLeftCornerType, eCornerType bottomRightCornerType, float partSize) + { + return GetRoundedRectanglePath(clientRectangle, cornerSize, cornerSize, cornerSize, cornerSize, pathPart, topLeftCornerType, topRightCornerType, bottomLeftCornerType, bottomRightCornerType, partSize); + } + + public static GraphicsPath GetRoundedRectanglePath(Rectangle clientRectangle, int topLeftCornerSize, int topRightCornerSize, int bottomLeftCornerSize, int bottomRightCornerSize, eStyleBackgroundPathPart pathPart, + eCornerType topLeftCornerType, eCornerType topRightCornerType, eCornerType bottomLeftCornerType, eCornerType bottomRightCornerType, float partSize) + { + GraphicsPath path = new GraphicsPath(); + + if (pathPart == eStyleBackgroundPathPart.TopHalf) + { + if (partSize == 0) + clientRectangle.Height = clientRectangle.Height / 2; + else + clientRectangle.Height = (int)(clientRectangle.Height * partSize); + } + else if (pathPart == eStyleBackgroundPathPart.BottomHalf) + { + int h = clientRectangle.Height; + if (partSize == 0) + clientRectangle.Height = clientRectangle.Height / 2; + else + clientRectangle.Height = (int)(clientRectangle.Height * partSize); + 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 && topLeftCornerSize > 0) + { + ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, topLeftCornerSize, 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 + topLeftCornerSize, clientRectangle.X + topLeftCornerSize, 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 && topRightCornerSize > 0) + { + ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, topRightCornerSize, 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 - topRightCornerSize - 1, clientRectangle.Y, clientRectangle.Right, clientRectangle.Y + topRightCornerSize); + } + 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 && bottomRightCornerSize > 0) + { + ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, bottomRightCornerSize, 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 - bottomRightCornerSize - 1, clientRectangle.Right - bottomRightCornerSize - 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 && bottomLeftCornerSize > 0) + { + ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, bottomLeftCornerSize, 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 - bottomLeftCornerSize - 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) + { + if (cornerSize <= 0) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + g.FillRectangle(brush, bounds); + g.SmoothingMode = sm; + } + else + { + // 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) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + using (SolidBrush brush = new SolidBrush(color1)) + g.FillRectangle(brush, r); + g.SmoothingMode = sm; + } + } + 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) + { + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.None; + using (SolidBrush brush = new SolidBrush(color1)) + g.FillRectangle(brush, r); + g.SmoothingMode = sm; + } + } + 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--; + + if (color2.IsEmpty) + { + using (Pen pen = new Pen(color1, penWidth)) + g.DrawRectangle(pen, r); + return; + } + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddRectangle(r); + + DrawGradientPath(g, path, r, color1, color2, gradientAngle, penWidth); + } + } + + public static void DrawGradientPath(Graphics g, GraphicsPath path, Rectangle bounds, Rendering.LinearGradientColorTable table, int penWidth) + { + DrawGradientPath(g, path, bounds, table.Start, table.End, table.GradientAngle, penWidth); + } + + public static void DrawGradientPath(Graphics g, GraphicsPath path, Rectangle bounds, Color color1, Color color2, int gradientAngle, int penWidth) + { + 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; + + if (color2.IsEmpty) + { + using (Pen pen = new Pen(color1, penWidth)) + DrawRoundedRectangle(g, pen, bounds, roundCornerSize); + 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); + + 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) + { + if (color1.IsEmpty && color2.IsEmpty) return; + 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); + } + public static void DrawGradientLine(Graphics g, int x1, int y1, int x2, int y2, Rendering.LinearGradientColorTable table, int penWidth) + { + DrawGradientLine(g, new Point(x1, y1), new Point(x2, y2), 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 || penWidth == 1 && start.Y == end.Y && gradientAngle == 90) + { + 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); + SmoothingMode sm = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.Default; + using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(r, color1, color2, gradientAngle)) + g.FillPath(brush, path); + g.SmoothingMode = sm; + } + } + } + + 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); + } + } + } + } +#if DOTNETBAR + public static Brush CreateBrush(Rectangle bounds, GradientColorTable colorBlend) + { + return CreateBrush(bounds, colorBlend.Colors, colorBlend.LinearGradientAngle, colorBlend.GradientType); + } + public static Brush CreateBrush(Rectangle bounds, DevComponents.DotNetBar.Rendering.LinearGradientColorTable colorTable) + { + if (colorTable.End.IsEmpty) return new SolidBrush(colorTable.Start); + return new LinearGradientBrush(bounds, colorTable.Start, colorTable.End, colorTable.GradientAngle); + } +#endif + public static Brush CreateBrush(Rectangle bounds, BackgroundColorBlendCollection colorBlend, int gradientAngle, eGradientType gradientType) + { + eBackgroundColorBlendType blendType = colorBlend.GetBlendType(); + if (blendType == eBackgroundColorBlendType.Invalid) + return null; + + if (blendType == eBackgroundColorBlendType.SolidColor) + { + return new SolidBrush(colorBlend[0].Color); + } + else if (blendType == eBackgroundColorBlendType.Relative) + { + try + { + if (gradientType == eGradientType.Linear) + { + bounds.Inflate(1, 1); + LinearGradientBrush brush = + DisplayHelp.CreateLinearGradientBrush(bounds, colorBlend[0].Color, colorBlend[colorBlend.Count - 1].Color, + gradientAngle); + brush.InterpolationColors = colorBlend.GetColorBlend(); + return brush; + } + else if (gradientType == eGradientType.Radial) + { + int d = (int)Math.Sqrt(bounds.Width * bounds.Width + bounds.Height * bounds.Height) + 4; + GraphicsPath fillPath = new GraphicsPath(); + fillPath.AddEllipse(bounds.X - (d - bounds.Width) / 2, bounds.Y - (d - bounds.Height) / 2, d, d); + PathGradientBrush brush = new PathGradientBrush(fillPath); + brush.CenterColor = colorBlend[0].Color; + brush.SurroundColors = new Color[] { colorBlend[colorBlend.Count - 1].Color }; + brush.InterpolationColors = colorBlend.GetColorBlend(); + return brush; + } + } + catch + { + return null; + } + } + else + { + BackgroundColorBlendCollection bc = colorBlend; + for (int i = 0; i < bc.Count; i += 2) + { + BackgroundColorBlend b1 = bc[i]; + BackgroundColorBlend b2 = null; + if (i < bc.Count) + b2 = bc[i + 1]; + if (b1 != null && b2 != null) + { + Rectangle rb = new Rectangle(bounds.X, bounds.Y + (int)b1.Position, bounds.Width, + (b2.Position == 1f ? bounds.Height : (int)b2.Position) - (int)b1.Position); + return DisplayHelp.CreateLinearGradientBrush(rb, b1.Color, b2.Color, gradientAngle); + } + } + } + + return null; + } + + public static System.Windows.Forms.ControlStyles DoubleBufferFlag + { + get + { +#if FRAMEWORK20 + return System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer; +#else + return System.Windows.Forms.ControlStyles.DoubleBuffer; +#endif + } + } + + private static TextRenderingHint s_AntiAliasTextRenderingHint = TextRenderingHint.ClearTypeGridFit; + public static TextRenderingHint AntiAliasTextRenderingHint + { + get + { + return s_AntiAliasTextRenderingHint; + } + set + { + s_AntiAliasTextRenderingHint = value; + } + } + + public static Rectangle[] ExcludeRectangle(Rectangle r1, Rectangle exclude) + { + if (r1.X >= exclude.X && exclude.Right < r1.Right) // Left aligned + return new Rectangle[] { new Rectangle(exclude.Right, r1.Y, r1.Width - (exclude.Right - r1.X), r1.Height) }; + else if (r1.Right <= exclude.Right && exclude.X > r1.X) // Right aligned + return new Rectangle[] { new Rectangle(r1.X, r1.Y, r1.Width - (r1.Right - exclude.X), r1.Height) }; + else if (exclude.X > r1.X && exclude.Right < r1.Right) + { + return new Rectangle[] { new Rectangle(r1.X, r1.Y, exclude.X-r1.X, r1.Height), + new Rectangle(exclude.Right, r1.Y, r1.Right - exclude.Right, r1.Height)}; + } + else if (exclude.Bottom >= r1.Bottom && exclude.Y > r1.Y) // Bottom Aligned + { + return new Rectangle[] { new Rectangle(r1.X, r1.Y, r1.Width, Math.Max(0, exclude.Y - r1.Y)) }; + } + else if (exclude.Y <= r1.Y && exclude.Bottom < r1.Bottom) // Top Aligned + { + return new Rectangle[] { new Rectangle(r1.X, exclude.Bottom, r1.Width, r1.Bottom - exclude.Bottom) }; + } + return new Rectangle[] { }; + } + + internal static Size MaxSize(Size size1, Size size2) + { + if (size2.Width > size1.Width) size1.Width = size2.Width; + if (size2.Height > size1.Height) size1.Height = size2.Height; + return size1; + } + + internal static void ExcludeEdgeRect(ref Rectangle captionRect, Rectangle exclude) + { + if (exclude.X + exclude.Width / 2 < captionRect.X + captionRect.Width / 2) + { + // Left aligned + int r = exclude.Right - captionRect.X; + captionRect.X = exclude.Right; + captionRect.Width -= r; + } + else + { + // Right aligned + captionRect.Width -= (captionRect.Right - exclude.X); + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DisplayMoreItem.cs b/PROMS/DotNetBar Source Code/DisplayMoreItem.cs new file mode 100644 index 00000000..0a54df09 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DisplayMoreItem.cs @@ -0,0 +1,642 @@ +using System; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// System item that displays the items that could not fit inside the container on popup menu or toolbar. + /// + [System.ComponentModel.ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false)] + public class DisplayMoreItem:PopupItem + { + private bool m_MouseOver; + private const int FIXED_SIZE=14; + private bool m_PopupSubItemsOnMenu; + private eOrientation m_OldOrientation=eOrientation.Horizontal; + private bool m_Localized=false; + + /// + /// Create new instance of DisplayMoreItem object. + /// + public DisplayMoreItem() + { + this.GlobalItem=false; + m_MouseOver=false; + m_PopupSubItemsOnMenu=false; + m_Tooltip="More Buttons"; + m_SystemItem=true; + this.CanCustomize=false; + m_ShouldSerialize=false; + + // Localization loading will repeat in OnContainerChanged becouse at this time + // DotNetBarManager owner is not known and LocalizeString event cannot be invoked + using(LocalizationManager lm=new LocalizationManager(null)) + { + m_Tooltip=lm.GetLocalizedString(LocalizationKeys.OverlfowDisplayMoreTooltip); + } + } + + /// + /// Returns copy of DisplayMoreItem item + /// + public override BaseItem Copy() + { + DisplayMoreItem objCopy=new DisplayMoreItem(); + this.CopyToItem(objCopy); + return objCopy; + } + + /// + /// Called when item container has changed. If you override this method you must call the base implementation to allow default processing to occur. + /// + /// Previous container of the item. + protected internal override void OnContainerChanged(object objOldContainer) + { + base.OnContainerChanged(objOldContainer); + if(!m_Localized) + { + m_Localized=true; + using(LocalizationManager lm=new LocalizationManager(this.GetOwner() as IOwnerLocalize)) + { + m_Tooltip=lm.GetLocalizedString(LocalizationKeys.OverlfowDisplayMoreTooltip); + } + } + } + + /// + /// Returns the fixed size of the item. + /// + public static int FixedSize + { + get + { + return FIXED_SIZE; + } + } + + /// + /// Overridden. Draws the item. + /// + /// Target Graphics object. + public override void Paint(ItemPaintArgs pa) + { + if (this.SuspendLayout) + return; + eDotNetBarStyle effectiveStyle = EffectiveStyle; + if (effectiveStyle == eDotNetBarStyle.Office2000) + PaintOffice(pa); + else + { + if (this.IsThemed) + { + PaintThemed(pa); + return; + } + else if (effectiveStyle == eDotNetBarStyle.Office2003 || effectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(effectiveStyle)) + { + PaintOffice2003(pa); + return; + } + else + PaintDotNet(pa); + } + + System.Drawing.Graphics g = pa.Graphics; + + if (m_Orientation == eOrientation.Vertical) + { + Point[] p = new Point[3]; + p[0].X = m_Rect.Right - 8; + p[0].Y = m_Rect.Top + 4; + p[1].X = p[0].X + 2; + p[1].Y = p[0].Y + 2; + p[2].X = p[0].X + 4; + p[2].Y = p[0].Y; + g.DrawLines(SystemPens.ControlText, p); + p[0].Y += 1; + p[1].Y += 1; + p[2].Y += 1; + g.DrawLines(SystemPens.ControlText, p); + + p[0].Y += 3; + p[1].Y += 3; + p[2].Y += 3; + g.DrawLines(SystemPens.ControlText, p); + p[0].Y += 1; + p[1].Y += 1; + p[2].Y += 1; + g.DrawLines(SystemPens.ControlText, p); + + p[0].X = m_Rect.Left + 7; + p[0].Y = m_Rect.Top + 4; + p[1].X = p[0].X - 3; + p[1].Y = p[0].Y + 3; + p[2].X = p[0].X; + p[2].Y = p[0].Y + 6; + g.FillPolygon(SystemBrushes.ControlText, p); + } + else + { + Point[] p = new Point[3]; + p[0].X = m_Rect.Left + (m_Rect.Width - 7) / 2 - 1; + p[0].Y = m_Rect.Top + 4; + p[1].X = p[0].X + 2; + p[1].Y = p[0].Y + 2; + p[2].X = p[0].X; + p[2].Y = p[0].Y + 4; + g.DrawLines(SystemPens.ControlText, p); + p[0].X += 1; + p[1].X += 1; + p[2].X += 1; + g.DrawLines(SystemPens.ControlText, p); + + p[0].X += 3; + p[1].X += 3; + p[2].X += 3; + g.DrawLines(SystemPens.ControlText, p); + p[0].X += 1; + p[1].X += 1; + p[2].X += 1; + g.DrawLines(SystemPens.ControlText, p); + + p[0].X = m_Rect.Left + (m_Rect.Width / 2) - 1; + p[0].Y = m_Rect.Bottom - 4; + p[1].X = p[0].X - 2; + p[1].Y = p[0].Y - 3; + p[2].X = p[1].X + 5; + p[2].Y = p[1].Y; + g.FillPolygon(SystemBrushes.ControlText, p); + } + } + + private void PaintDotNet(ItemPaintArgs pa) + { + Rectangle r; + System.Drawing.Graphics g=pa.Graphics; + if(m_Expanded) + { + r=new Rectangle(m_Rect.Left+2,m_Rect.Top+2,m_Rect.Width-2,m_Rect.Height-2); + if(!pa.Colors.ItemExpandedShadow.IsEmpty) + { + using(SolidBrush shadow=new SolidBrush(pa.Colors.ItemExpandedShadow)) + g.FillRectangle(shadow,r); + } + r.Offset(-2,-2); + r.Height+=2; + if(pa.Colors.ItemExpandedBackground2.IsEmpty) + g.FillRectangle(new SolidBrush(pa.Colors.ItemExpandedBackground),r); + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient=BarFunctions.CreateLinearGradientBrush(r,pa.Colors.ItemExpandedBackground,pa.Colors.ItemExpandedBackground2,pa.Colors.ItemExpandedBackgroundGradientAngle); + g.FillRectangle(gradient,r); + gradient.Dispose(); + } + // TODO: Beta 2 fix --> g.DrawRectangle(new Pen(ColorFunctions.MenuFocusBorderColor(g),1),r); + NativeFunctions.DrawRectangle(g,new Pen(pa.Colors.MenuBorder,1),r); + } + else if(m_MouseOver) + { + r=new Rectangle(m_Rect.Left,m_Rect.Top,m_Rect.Width-2,m_Rect.Height); + if(!pa.Colors.ItemHotBackground2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient=BarFunctions.CreateLinearGradientBrush(r,pa.Colors.ItemHotBackground,pa.Colors.ItemHotBackground2,pa.Colors.ItemHotBackgroundGradientAngle); + g.FillRectangle(gradient,r); + gradient.Dispose(); + } + else + g.FillRectangle(new SolidBrush(pa.Colors.ItemHotBackground),r); + // TODO: Beta 2 Fix --> g.DrawRectangle(SystemPens.Highlight,r); + NativeFunctions.DrawRectangle(g,new Pen(pa.Colors.ItemHotBorder),r); + } + } + + private void PaintThemed(ItemPaintArgs pa) + { + ThemeRebar theme=pa.ThemeRebar; + ThemeRebarParts part=ThemeRebarParts.Chevron; + ThemeRebarStates state=ThemeRebarStates.ChevronNormal; + if(m_Expanded) + state=ThemeRebarStates.ChevronPressed; + else if(m_MouseOver) + state=ThemeRebarStates.ChevronHot; + + theme.DrawBackground(pa.Graphics,part,state,m_Rect); + } + + private void PaintOffice(ItemPaintArgs pa) + { + System.Drawing.Graphics g=pa.Graphics; + if(m_Expanded) + { + System.Windows.Forms.ControlPaint.DrawBorder3D(g,m_Rect,System.Windows.Forms.Border3DStyle.SunkenOuter); + } + else if(m_MouseOver) + { + System.Windows.Forms.ControlPaint.DrawBorder3D(g,m_Rect,System.Windows.Forms.Border3DStyle.RaisedInner); + } + } + + private void PaintOffice2003(ItemPaintArgs pa) + { + Graphics g=pa.Graphics; + + // When on docked toolbar it has a special look... + Rectangle r=m_Rect; + + System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); + if (this.Orientation == eOrientation.Vertical) + { + // When on docked toolbar it has a special look... + r.Y += 2; + r.Height -= 1; + r.X -= 2; + r.Width += 2; + + path.AddLine(r.X, r.Y, r.X + 2, r.Y + 2); + path.AddLine(r.Right - 2, r.Y + 2, r.Right, r.Y); + path.AddLine(r.Right, r.Bottom - 2, r.Right - 2, r.Bottom); + path.AddLine(r.X + 2, r.Bottom, r.X, r.Bottom - 2); + path.CloseAllFigures(); + } + else + { + // When on docked toolbar it has a special look... + r.X += 2; + r.Width -= 1; + r.Y -= 2; + r.Height += 3; + + path.AddLine(r.X, r.Y, r.X + 2, r.Y + 2); + path.AddLine(r.X + 2, r.Bottom - 2, r.X, r.Bottom); + path.AddLine(r.Right - 2, r.Bottom, r.Right, r.Bottom - 2); + path.AddLine(r.Right, r.Y + 2, r.Right - 2, r.Y); + path.CloseAllFigures(); + } + + System.Drawing.Drawing2D.SmoothingMode smooth=g.SmoothingMode; + g.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + if(this.Expanded) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient=BarFunctions.CreateLinearGradientBrush(r,pa.Colors.ItemPressedBackground,pa.Colors.ItemPressedBackground2,pa.Colors.ItemPressedBackgroundGradientAngle); + g.FillPath(gradient,path); + gradient.Dispose(); + } + else if(m_MouseOver) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient=BarFunctions.CreateLinearGradientBrush(r,pa.Colors.ItemHotBackground,pa.Colors.ItemHotBackground2,pa.Colors.ItemHotBackgroundGradientAngle); + g.FillPath(gradient,path); + gradient.Dispose(); + } + else + { + System.Drawing.Drawing2D.LinearGradientBrush gradient=BarFunctions.CreateLinearGradientBrush(r,pa.Colors.CustomizeBackground,pa.Colors.CustomizeBackground2,pa.Colors.CustomizeBackgroundGradientAngle); + g.FillPath(gradient,path); + gradient.Dispose(); + } + g.SmoothingMode=smooth; + + if (this.Orientation == eOrientation.Vertical) + { + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2, r.Bottom - 10 + 1, r.Left + (m_Rect.Width - 4) / 2 + 4, r.Bottom - 10 + 1); + + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2 - 1 + 1, r.Top + 6 + 1, r.Left + (m_Rect.Width - 4) / 2 - 1 + 1, r.Top + 8 + 1); + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2 + 3 + 1, r.Top + 6 + 1, r.Left + (m_Rect.Width - 4) / 2 + 3 + 1, r.Top + 8 + 1); + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2 - 1 + 1, r.Top + 7 + 1, r.Left + (m_Rect.Width - 4) / 2 + 1, r.Top + 7 + 1); + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2 + 3 + 1, r.Top + 7 + 1, r.Left + (m_Rect.Width - 4) / 2 + 4 + 1, r.Top + 7 + 1); + + // Draw Arrow + using (Pen pen = new Pen(pa.Colors.CustomizeText, 1)) + { + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2, r.Bottom - 10, r.Left + (m_Rect.Width - 4) / 2 + 4, r.Bottom - 10); + + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2 - 1, r.Top + 6, r.Left + (m_Rect.Width - 4) / 2 - 1, r.Top + 8); + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2 + 3, r.Top + 6, r.Left + (m_Rect.Width - 4) / 2 + 3, r.Top + 8); + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2 - 1, r.Top + 7, r.Left + (m_Rect.Width - 4) / 2, r.Top + 7); + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2 + 3, r.Top + 7, r.Left + (m_Rect.Width - 4) / 2 + 4, r.Top + 7); + } + } + else + { + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2 + 1, r.Bottom - 11 + 1, r.Left + (m_Rect.Width - 4) / 2 + 4 + 1, r.Bottom - 11 + 1); + + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2 - 1 + 1, r.Top + 6 + 1, r.Left + (m_Rect.Width - 4) / 2 - 1 + 1, r.Top + 8 + 1); + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2 + 3 + 1, r.Top + 6 + 1, r.Left + (m_Rect.Width - 4) / 2 + 3 + 1, r.Top + 8 + 1); + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2 - 1 + 1, r.Top + 7 + 1, r.Left + (m_Rect.Width - 4) / 2 + 1, r.Top + 7 + 1); + g.DrawLine(SystemPens.HighlightText, r.Left + (m_Rect.Width - 4) / 2 + 3 + 1, r.Top + 7 + 1, r.Left + (m_Rect.Width - 4) / 2 + 4 + 1, r.Top + 7 + 1); + + // Draw Arrow Shade + Point[] p = new Point[3]; + p[0].X = r.Left + (m_Rect.Width - 4) / 2 + 2 + 1; + p[0].Y = r.Bottom - 5 + 1; + p[1].X = p[0].X - 2; + p[1].Y = p[0].Y - 3; + p[2].X = p[1].X + 5; + p[2].Y = p[1].Y; + using (SolidBrush brush = new SolidBrush(SystemColors.HighlightText)) + g.FillPolygon(brush, p); + + // Draw Arrow + using (Pen pen = new Pen(pa.Colors.CustomizeText, 1)) + { + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2, r.Bottom - 11, r.Left + (m_Rect.Width - 4) / 2 + 4, r.Bottom - 11); + + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2 - 1, r.Top + 6, r.Left + (m_Rect.Width - 4) / 2 - 1, r.Top + 8); + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2 + 3, r.Top + 6, r.Left + (m_Rect.Width - 4) / 2 + 3, r.Top + 8); + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2 - 1, r.Top + 7, r.Left + (m_Rect.Width - 4) / 2, r.Top + 7); + g.DrawLine(pen, r.Left + (m_Rect.Width - 4) / 2 + 3, r.Top + 7, r.Left + (m_Rect.Width - 4) / 2 + 4, r.Top + 7); + } + p = new Point[3]; + p[0].X = r.Left + (m_Rect.Width - 4) / 2 + 2; + p[0].Y = r.Bottom - 5; + p[1].X = p[0].X - 2; + p[1].Y = p[0].Y - 3; + p[2].X = p[1].X + 5; + p[2].Y = p[1].Y; + using (SolidBrush brush = new SolidBrush(pa.Colors.CustomizeText)) + g.FillPolygon(brush, p); + } + } + + /// + /// Overriden. Recalculates the size of the item. + /// + public override void RecalcSize() + { + if(this.SuspendLayout) + return; + + if(m_Orientation==eOrientation.Vertical) + { + // Take suggested width + m_Rect.Height=FIXED_SIZE; + } + else + { + // Take suggested height + m_Rect.Width=FIXED_SIZE; + } + base.RecalcSize(); + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseEnter() + { + base.InternalMouseEnter(); + m_MouseOver=true; + this.Refresh(); + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseLeave() + { + base.InternalMouseLeave(); + m_MouseOver=false; + this.Refresh(); + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override void InternalMouseDown(System.Windows.Forms.MouseEventArgs objArg) + { + base.InternalMouseDown(objArg); + if(objArg.Button != System.Windows.Forms.MouseButtons.Left) + return; + //if(m_Expanded) + // m_Parent.AutoExpand=false; + this.Expanded=!m_Expanded; + } + + /// + /// Overridden. Displays the sub-items on popup. + /// + /// Popup location. + public override void Popup(Point p) + { + Popup(p.X,p.Y); + } + + /// + /// Overridden. Displays the sub-items on popup. + /// + /// Horizontal coordinate in pixels of the upper left corner of a popup. + /// Vertical coordinate in pixels of the upper left corner of a popup. + public override void Popup(int x, int y) + { + if(m_PopupSubItemsOnMenu) + PopupMenu(x,y); + else + PopupBar(x,y); + } + + /// + /// Overridden. Displays the sub-items on popup toolbar. + /// + /// Horizontal coordinate in pixels of the upper left corner of a popup. + /// Vertical coordinate in pixels of the upper left corner of a popup. + public override void PopupBar(int x, int y) + { + AddItems(); + // Reset Need Recalc Size since adding the items will trigger this flag + m_NeedRecalcSize=false; + base.PopupBar(x,y); + m_NeedRecalcSize = false; + } + + /// + /// Overridden. Displays the sub-items on popup menu. + /// + /// Horizontal coordinate in pixels of the upper left corner of a popup. + /// Vertical coordinate in pixels of the upper left corner of a popup. + public override void PopupMenu(int x, int y) + { + AddItems(); + // Reset Need Recalc Size since adding the items will trigger this flag + m_NeedRecalcSize=false; + base.PopupMenu(x,y); + m_NeedRecalcSize = false; + } + + /// + /// Overridden. Close the popup window if open. + /// + public override void ClosePopup() + { + base.ClosePopup(); + this.SubItems.Clear(); + } + + /// + /// Get or sets whether item has been changed in a way that it needs its size recalculated. This is internal + /// property and it should not be used by your code. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool NeedRecalcSize + { + get + { + return base.NeedRecalcSize; + } + set + { + m_NeedRecalcSize=value; + } + } + + /// + /// Adds the items that are not visible to the overflow popup. + /// + protected virtual void AddItems() + { + if(m_SubItems==null) + { + m_SubItems=new SubItemsCollection(this); + } + + m_OldOrientation=this.Orientation; + foreach(BaseItem objItem in m_Parent.SubItems) + { + if(!objItem.Displayed && objItem.Visible) + { + m_SubItems._Add(objItem); + ImageItem objImageItem=objItem as ImageItem; + if(objImageItem!=null) + { + if(objImageItem.ImageSize.Width>this.SubItemsImageSize.Width) + this.SubItemsImageSize=new Size(objImageItem.ImageSize.Width,this.SubItemsImageSize.Height); + if(objImageItem.ImageSize.Height>this.SubItemsImageSize.Height) + this.SubItemsImageSize=new Size(this.SubItemsImageSize.Width,objImageItem.ImageSize.Height); + } + } + } + + foreach(BaseItem objItem in m_SubItems) + { + object objItemContainer=objItem.ContainerControl; + m_Parent.SubItems._Remove(objItem); + objItem.SetOrientation(eOrientation.Horizontal); + objItem.SetParent(this); + objItem.ContainerControl=null; + objItem.OnContainerChanged(objItemContainer); + } + NeedRecalcSize=true; + } + + /// + /// Returns the insertion index for the items removed from overflow popup. Assumes that right-most items are removed first by the layout manager. + /// + /// + protected virtual int GetReInsertIndex() + { + int insertPos = m_Parent.SubItems.Count; + for (int i = insertPos - 1; i >= 0; i--) + { + if (m_Parent.SubItems[i] is CustomizeItem) + { + insertPos = i; + break; + } + } + return insertPos; + } + + /// + /// Removes the items from the overflow and adds them back to the parent item. + /// + protected virtual void RemoveItems() + { + // Return the items back to the parent... + m_HotSubItem = null; + // Need to leave customize item at the end of the collection + int insertPos = GetReInsertIndex(); + + foreach (BaseItem objItem in m_SubItems) + { + object objItemContainer = objItem.ContainerControl; + objItem.Orientation = m_OldOrientation; + m_Parent.SubItems._Add(objItem, insertPos); + insertPos++; + objItem.SetParent(m_Parent); + objItem.ContainerControl = null; + } + System.Collections.ArrayList col = new System.Collections.ArrayList(m_SubItems.Count); + m_SubItems.CopyTo(col); + while (m_SubItems.Count > 0) + m_SubItems._Remove(m_SubItems[0]); + foreach (BaseItem item in col) + item.Displayed = false; + + base.OnExpandChange(); + + if (this.PopupControl is Bar) + { + Bar bar = (Bar)this.PopupControl; + bar.ParentItem = null; + } + + BaseItem objParent = m_Parent; + + System.Windows.Forms.Control objCtrl = null; + if (objParent != null) + objCtrl = objParent.ContainerControl as System.Windows.Forms.Control; + bool recalcSize = true; + if (objCtrl != null) + { + recalcSize= !BarFunctions.InvokeRecalcLayout(objCtrl, false); + } + if (recalcSize && objParent != null) + { + objParent.RecalcSize(); + objParent.Refresh(); + } + } + + protected internal override void OnExpandChange() + { + if(!this.Expanded && m_SubItems!=null && m_Parent!=null) + { + RemoveItems(); + return; + } + base.OnExpandChange(); + } + + /// + /// Forces the repaint the item. + /// + public override void Refresh() + { + if(this.SuspendLayout) + return; + if ((EffectiveStyle == eDotNetBarStyle.Office2003 || EffectiveStyle == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(EffectiveStyle)) && !BaseItem.IsOnPopup(this)) + { + if((m_Visible || this.IsOnCustomizeMenu) && m_Displayed) + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null && IsHandleValid(objCtrl) && !(objCtrl is ItemsListBox)) + { + if(m_NeedRecalcSize) + { + RecalcSize(); + if(m_Parent!=null) + m_Parent.SubItemSizeChanged(this); + } + Rectangle r=m_Rect; + r.Inflate(2,2); + objCtrl.Invalidate(r,true); + } + } + } + else + base.Refresh(); + } + + /// + /// Gets whether the mouse is over the item. + /// + [Browsable(false)] + public bool IsMouseOver + { + get { return m_MouseOver; } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DockContainerItem.cs b/PROMS/DotNetBar Source Code/DockContainerItem.cs new file mode 100644 index 00000000..f5abf87d --- /dev/null +++ b/PROMS/DotNetBar Source Code/DockContainerItem.cs @@ -0,0 +1,1620 @@ +using System; +using System.Drawing; +using System.ComponentModel; + +namespace DevComponents.DotNetBar +{ + /// + /// Item container for dockable windows. + /// + [System.ComponentModel.ToolboxItem(false), System.ComponentModel.DesignTimeVisible(false), Designer("DevComponents.DotNetBar.Design.DockContainerItemDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class DockContainerItem:ImageItem + { + /// + /// Occurs when container control needs to be assigned to the item. + /// + public event EventHandler ContainerLoadControl; + public event ControlContainerItem.ControlContainerSerializationEventHandler ContainerControlSerialize; + public event ControlContainerItem.ControlContainerSerializationEventHandler ContainerControlDeserialize; + + private System.Windows.Forms.Control m_Control=null; + private bool m_MouseOver=false; + private bool m_InternalResize=false; + private Size m_MinimumSize=new Size(32,32); + private Size m_DefaultFloatingSize=new Size(128,128); + + private System.Drawing.Image m_Image=null; + private int m_ImageIndex=-1; + private System.Drawing.Image m_TabImage=null; + private System.Drawing.Icon m_Icon=null; + + private int m_MinFormClientSize=64; + private int m_DelayedWidth=-1; + private int m_DelayedHeight=-1; + private eTabItemColor m_PredefinedTabColor = eTabItemColor.Default; + + /// + /// Creates new instance of ControlContainerItem and assigns item name. + /// + public DockContainerItem():this("","") {} + /// + /// Creates new instance of ControlContainerItem and assigns item name. + /// + /// Item name. + public DockContainerItem(string sName):this(sName,""){} + /// + /// Creates new instance of ControlContainerItem and assigns item name and item text. + /// + /// Item name. + /// Item text. + public DockContainerItem(string sName, string ItemText):base(sName,ItemText) + { + m_SupportedOrientation=eSupportedOrientation.Both; + this.Stretch=true; + this.CanCustomize=false; + m_Displayed=true; // need so the hosted control can be hidden... + this.GlobalItem = false; + } + + internal void InitControl() + { + EventArgs e=new EventArgs(); + if(ContainerLoadControl!=null) + ContainerLoadControl(this,e); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null) + owner.InvokeContainerLoadControl(this,e); + } + + /// + /// Overriden. Returns the copy of the ControlContainerItem. + /// + /// Copy of the ControlContainerItem. + public override BaseItem Copy() + { + DockContainerItem objCopy = new DockContainerItem(this.Name); + this.CopyToItem(objCopy); + return objCopy; + } + protected override void CopyToItem(BaseItem copy) + { + DockContainerItem objCopy=copy as DockContainerItem; + base.CopyToItem(objCopy); + objCopy.SetImageIndex(m_ImageIndex); + if(m_Icon!=null) + objCopy.Icon=m_Icon.Clone() as Icon; + if(objCopy.Image!=null) + objCopy.Image=m_Image.Clone() as Image; + objCopy.ContainerLoadControl=this.ContainerLoadControl; + objCopy.InitControl(); + } + protected override void Dispose(bool disposing) + { + if (BarUtilities.DisposeItemImages && !this.DesignMode) + { + BarUtilities.DisposeImage(ref m_Image); + BarUtilities.DisposeImage(ref m_Icon); + } + m_Control=null; + base.Dispose(disposing); + } + protected internal override void Serialize(ItemSerializationContext context) + { + base.Serialize(context); + System.Xml.XmlElement ThisItem = context.ItemXmlElement; + System.Xml.XmlElement xmlElem=null, xmlElem2=null; + // Serialize Images + if(m_Image!=null || m_ImageIndex>=0) + { + xmlElem=ThisItem.OwnerDocument.CreateElement("images"); + ThisItem.AppendChild(xmlElem); + + if(m_ImageIndex>=0) + xmlElem.SetAttribute("imageindex",System.Xml.XmlConvert.ToString(m_ImageIndex)); + + if(m_Image!=null) + { + xmlElem2=ThisItem.OwnerDocument.CreateElement("image"); + xmlElem2.SetAttribute("type","default"); + xmlElem.AppendChild(xmlElem2); + BarFunctions.SerializeImage(m_Image,xmlElem2); + } + } + else if(m_Icon!=null) + { + xmlElem=ThisItem.OwnerDocument.CreateElement("images"); + ThisItem.AppendChild(xmlElem); + + xmlElem2=ThisItem.OwnerDocument.CreateElement("image"); + xmlElem2.SetAttribute("type","icon"); + xmlElem.AppendChild(xmlElem2); + BarFunctions.SerializeIcon(m_Icon,xmlElem2); + } + + if(m_MinimumSize.Width!=32 || m_MinimumSize.Height!=32) + { + ThisItem.SetAttribute("minw",m_MinimumSize.Width.ToString()); + ThisItem.SetAttribute("minh",m_MinimumSize.Height.ToString()); + } + + if(m_DefaultFloatingSize.Width!=128 || m_DefaultFloatingSize.Height!=128) + { + ThisItem.SetAttribute("defw",m_DefaultFloatingSize.Width.ToString()); + ThisItem.SetAttribute("defh",m_DefaultFloatingSize.Height.ToString()); + } + + if(m_MinFormClientSize!=64) + { + ThisItem.SetAttribute("csize",m_MinFormClientSize.ToString()); + } + + if(m_PredefinedTabColor!=eTabItemColor.Default) + ThisItem.SetAttribute("PredefinedTabColor", System.Xml.XmlConvert.ToString(((int)m_PredefinedTabColor))); + + + if(ContainerControlSerialize!=null) + this.ContainerControlSerialize(this,new ControlContainerSerializationEventArgs(ThisItem)); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null) + owner.InvokeContainerControlSerialize(this,new ControlContainerSerializationEventArgs(ThisItem)); + + } + public override void Deserialize(ItemSerializationContext context) + { + base.Deserialize(context); + + System.Xml.XmlElement ItemXmlSource = context.ItemXmlElement; + + // Load Images + foreach(System.Xml.XmlElement xmlElem in ItemXmlSource.ChildNodes) + { + if(xmlElem.Name=="images") + { + if(xmlElem.HasAttribute("imageindex")) + m_ImageIndex=System.Xml.XmlConvert.ToInt32(xmlElem.GetAttribute("imageindex")); + + foreach(System.Xml.XmlElement xmlElem2 in xmlElem.ChildNodes) + { + if(xmlElem2.GetAttribute("type")=="default") + { + m_Image=BarFunctions.DeserializeImage(xmlElem2); + m_ImageIndex=-1; + } + else if(xmlElem2.GetAttribute("type")=="icon") + { + m_Icon=BarFunctions.DeserializeIcon(xmlElem2); + m_ImageIndex=-1; + } + } + break; + } + } + + if(ItemXmlSource.HasAttribute("minw")) + { + m_MinimumSize=new Size(System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("minw")),System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("minh"))); + } + + if(ItemXmlSource.HasAttribute("defw")) + { + m_DefaultFloatingSize=new Size(System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("defw")),System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("defh"))); + } + + if(ItemXmlSource.HasAttribute("csize")) + m_MinFormClientSize=System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("csize")); + else + m_MinFormClientSize=64; + + if (ItemXmlSource.HasAttribute("PredefinedTabColor")) + m_PredefinedTabColor = (eTabItemColor)System.Xml.XmlConvert.ToInt32(ItemXmlSource.GetAttribute("PredefinedTabColor")); + else + m_PredefinedTabColor = eTabItemColor.Default; + + InitControl(); + + if (m_Control == null && context.DockControls != null && context.DockControls.ContainsKey(this.Name)) + { + this.Control = context.DockControls[this.Name] as System.Windows.Forms.Control; + context.DockControls.Remove(this.Name); + } + + if(ContainerControlDeserialize!=null) + this.ContainerControlDeserialize(this,new ControlContainerSerializationEventArgs(ItemXmlSource)); + IOwnerItemEvents owner=this.GetIOwnerItemEvents(); + if(owner!=null) + owner.InvokeContainerControlDeserialize(this,new ControlContainerSerializationEventArgs(ItemXmlSource)); + } + + private DockItemAccessibleObject _AccessibleObject = null; + protected override System.Windows.Forms.AccessibleObject CreateAccessibilityInstance() + { + if (_AccessibleObject == null) + _AccessibleObject = new DockItemAccessibleObject(this); + return _AccessibleObject; + } + + /// + /// Gets or sets the reference to the contained control. + /// + [System.ComponentModel.Browsable(true),DevCoBrowsable(false),DefaultValue(null),Description("Indicates the control hosted on dockable window"),Category("Docking")] + public System.Windows.Forms.Control Control + { + get + { + return m_Control; + } + set + { + if(m_Control!=null) + { + if(m_Control.Parent!=null) + { + if(!(this.DesignMode && this.Site!=null)) + { + m_Control.Visible=false; + } + m_Control.Parent.Controls.Remove(m_Control); + } + } + m_Control=value; + if(m_Control!=null) + { + if(m_Control is PanelDockContainer) + ((PanelDockContainer)m_Control).DockContainerItem=this; + + if(m_Control is System.Windows.Forms.ListBox) + ((System.Windows.Forms.ListBox)m_Control).IntegralHeight=false; + + if(m_Control.Parent!=null) + m_Control.Parent.Controls.Remove(m_Control); + + m_Control.Dock=System.Windows.Forms.DockStyle.None; + + // Check auto-size property + PropertyDescriptorCollection props=TypeDescriptor.GetProperties(m_Control); + if(props.Find("AutoSize",true)!=null) + { + props.Find("AutoSize",true).SetValue(m_Control,false); + } + + if(!(this.DesignMode && this.Site!=null)) + { + m_Control.Visible=false; + } + + System.Windows.Forms.Control objCtrl=null; + if(this.ContainerControl!=null) + { + objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null) + { + objCtrl.Controls.Add(m_Control); + if(this.DesignMode && this.Site!=null && m_Control.Visible && !this.Selected) + m_Control.SendToBack(); + } + } + + OnDisplayedChanged(); + } + } + } + + /// + /// Returns category for this item. If item cannot be customzied using the + /// customize dialog category is empty string. + /// + [Browsable(false),DevCoBrowsable(false),DefaultValue(""),Category("Design"),Description("Indicates item category used to group similar items at design-time.")] + public override string Category + { + get {return base.Category;} + set {base.Category=value;} + } + + /// + /// Gets or sets whether Click event will be auto repeated when mouse button is kept pressed over the item. + /// + [Browsable(false),DevCoBrowsable(false),DefaultValue(false),Category("Behavior"),Description("Gets or sets whether Click event will be auto repeated when mouse button is kept pressed over the item.")] + public override bool ClickAutoRepeat + { + get {return base.ClickAutoRepeat;} + set {base.ClickAutoRepeat=value;} + } + + /// + /// Gets or sets the auto-repeat interval for the click event when mouse button is kept pressed over the item. + /// + [Browsable(false),DevCoBrowsable(false),DefaultValue(600),Category("Behavior"),Description("Gets or sets the auto-repeat interval for the click event when mouse button is kept pressed over the item.")] + public override int ClickRepeatInterval + { + get {return base.ClickRepeatInterval;} + set {base.ClickRepeatInterval=value;} + } + + /// + /// Gets or sets item description. This description is displayed in + /// Customize dialog to describe the item function in an application. + /// + [Browsable(false),DevCoBrowsable(false),DefaultValue(""),Category("Design"),Description("Indicates description of the item that is displayed during design.")] + public override string Description + { + get {return base.Description;} + set {base.Description=value;} + } + + /// + /// Gets or sets item alignment inside the container. + /// + [Browsable(false),DevCoBrowsable(false),DefaultValue(eItemAlignment.Near),Category("Appearance"),Description("Determines alignment of the item inside the container.")] + public override eItemAlignment ItemAlignment + { + get {return base.ItemAlignment;} + set {base.ItemAlignment=value;} + } + + /// + /// Gets or sets the collection of shortcut keys associated with the item. + /// + [Browsable(false),DevCoBrowsable(false),Category("Design"),Description("Indicates list of shortcut keys for this item."),System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ShortcutsDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf",typeof(System.Drawing.Design.UITypeEditor)),System.ComponentModel.TypeConverter("DevComponents.DotNetBar.Design.ShortcutsConverter, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf"),System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public override ShortcutsCollection Shortcuts + { + get {return base.Shortcuts;} + set {base.Shortcuts=value;} + } + + /// + /// Gets or sets whether item will display sub items. + /// + [Browsable(false),DevCoBrowsable(false),DefaultValue(true),Category("Behavior"),Description("Determines whether sub-items are displayed.")] + public override bool ShowSubItems + { + get {return base.ShowSubItems;} + set {base.ShowSubItems=value;} + } + +// private void ControlResize(object sender, EventArgs e) +// { +// if(m_Painting || m_InternalResize) +// return; +// m_ControlSize=m_Control.Size; +// } + protected override void OnExternalSizeChange() + { + //if (this.DesignMode) + ResizeControl(); + base.OnExternalSizeChange(); + } + private void ResizeControl() + { + if(m_InternalResize) + return; + m_InternalResize=true; + try + { + Rectangle r=this.DisplayRectangle; + + Size objImageSize=GetMaxImageSize(); + bool bOnMenu=this.IsOnMenu; + if (bOnMenu && EffectiveStyle != eDotNetBarStyle.Office2000) + { + objImageSize.Width+=7; + r.Width-=objImageSize.Width; + r.X+=objImageSize.Width; + } + + if(this.IsOnCustomizeMenu) + { + if (EffectiveStyle != eDotNetBarStyle.Office2000) + { + r.X+=(objImageSize.Height+8); + r.Width-=(objImageSize.Height+8); + } + else + { + r.X+=(objImageSize.Height+4); + r.Width-=(objImageSize.Height+4); + } + } + + if(m_Control!=null) + { + r.Inflate(-2, -2); + if (r.Width > 0 && r.Height > 0) + { + if (!m_Control.Size.Equals(r.Size)) + { + m_Control.SuspendLayout(); + m_Control.Size = r.Size; + m_Control.ResumeLayout(); + } + Point loc = r.Location; + loc.Offset((r.Width - m_Control.Width) / 2, (r.Height - m_Control.Height) / 2); + if (loc.X != m_Control.Location.X || loc.Y != m_Control.Location.Y) + m_Control.Location = loc; + } + } + } + finally + { + m_InternalResize=false; + } + + } + + /// + /// Overriden. Draws the item. + /// + /// Target Graphics object. + public override void Paint(ItemPaintArgs pa) + { + if(this.SuspendLayout) + return; + System.Drawing.Graphics g=pa.Graphics; + if(m_Control!=null && m_Control.Visible!=this.Displayed && !m_Control.Visible) + CustomizeChanged(); // Determine based on customize status + + Rectangle r=this.DisplayRectangle; + + Size objImageSize=GetMaxImageSize(); + bool bOnMenu=this.IsOnMenu; + + if (bOnMenu && EffectiveStyle != eDotNetBarStyle.Office2000) + { + objImageSize.Width+=7; + r.Width-=objImageSize.Width; + r.X+=objImageSize.Width; + if(this.IsOnCustomizeMenu) + objImageSize.Width+=objImageSize.Height+8; + // Draw side bar + if(!pa.Colors.MenuSide2.IsEmpty) + { + System.Drawing.Drawing2D.LinearGradientBrush gradient=BarFunctions.CreateLinearGradientBrush(new Rectangle(m_Rect.Left,m_Rect.Top,objImageSize.Width,m_Rect.Height),pa.Colors.MenuSide,pa.Colors.MenuSide2,pa.Colors.MenuSideGradientAngle); + g.FillRectangle(gradient,m_Rect.Left,m_Rect.Top,objImageSize.Width,m_Rect.Height); + gradient.Dispose(); + } + else + g.FillRectangle(new SolidBrush(pa.Colors.MenuSide),m_Rect.Left,m_Rect.Top,objImageSize.Width,m_Rect.Height); + } + + if(this.IsOnCustomizeMenu) + { + if (EffectiveStyle != eDotNetBarStyle.Office2000) + { + r.X+=(objImageSize.Height+8); + r.Width-=(objImageSize.Height+8); + } + else + { + r.X+=(objImageSize.Height+4); + r.Width-=(objImageSize.Height+4); + } + } + + //if(bOnMenu && this.Style==eDotNetBarStyle.OfficeXP) + //{ + // g.FillRectangle(new SolidBrush(pa.Colors.MenuBackground),r); + //} + + // Draw text if needed + if(m_Control==null) + { + string text=m_Text; + if(text=="") + text="Container"; + eTextFormat objStringFormat=GetStringFormat(); + Font objFont=this.GetFont(); + Rectangle rText=new Rectangle(r.X+8,r.Y,r.Width,r.Height); + if (EffectiveStyle == eDotNetBarStyle.Office2000) + { + TextDrawing.DrawString(g,text,objFont,SystemColors.ControlText,rText,objStringFormat); + } + else + { + TextDrawing.DrawString(g,text, objFont, SystemColors.ControlText, rText, objStringFormat); + } + Size textSize=TextDrawing.MeasureString(g,text,objFont,0,objStringFormat); + r.X+=(int)textSize.Width+8; + r.Width-=((int)textSize.Width+8); + } + else if(m_Control!=null) + { + ResizeControl(); + } + + if(this.IsOnCustomizeMenu && this.Visible) + { + // Draw check box if this item is visible + Rectangle rBox=new Rectangle(m_Rect.Left,m_Rect.Top,m_Rect.Height,m_Rect.Height); + if (EffectiveStyle != eDotNetBarStyle.Office2000) + rBox.Inflate(-1,-1); + BarFunctions.DrawMenuCheckBox(pa, rBox, EffectiveStyle, m_MouseOver); + } + + if(this.Focused && this.DesignMode) + { + r=this.DisplayRectangle; + r.Inflate(-1,-1); + DesignTime.DrawDesignTimeSelection(g,r,pa.Colors.ItemDesignTimeBorder); + } + } + /// + /// Overriden. Recalculates the size of the item. + /// + public override void RecalcSize() + { + if(this.SuspendLayout) + return; + + bool bOnMenu=this.IsOnMenu; + + if(m_Control==null && !this.DesignMode) + InitControl(); + + if(m_Control==null) + { + // Default Height + if(this.Parent!=null && this.Parent is ImageItem) + m_Rect.Height=((ImageItem)this.Parent).SubItemsImageSize.Height+4; + else + m_Rect.Height=this.SubItemsImageSize.Height+4; + + if (EffectiveStyle != eDotNetBarStyle.Office2000) + { + if(m_Control!=null && m_Rect.Height<(m_Control.Height+2)) + m_Rect.Height=m_Control.Height+2; + } + else + { + if(m_Control!=null && m_Rect.Height<(m_Control.Height+2)) + m_Rect.Height=m_Control.Height+2; + } + } + else + m_Rect.Height=m_MinimumSize.Height+4; + + // Default width + //if(m_Control!=null) + m_Rect.Width=m_MinimumSize.Width+4; + //else + // m_Rect.Width=64+4; + + // Calculate Item Height + if(m_Control==null) + { + string text=m_Text; + if(text=="") + text="Container"; + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null && IsHandleValid(objCtrl)) + { + Graphics g=BarFunctions.CreateGraphics(objCtrl); + try + { + Size textSize = TextDrawing.MeasureString(g, text, GetFont(), 0, GetStringFormat()); + if (textSize.Height > this.SubItemsImageSize.Height && textSize.Height > m_Rect.Height) + m_Rect.Height = (int)textSize.Height + 4; + } + finally + { + g.Dispose(); + } + } + } + + Size objImageSize=GetMaxImageSize(); + if (this.IsOnMenu && EffectiveStyle != eDotNetBarStyle.Office2000) + { + // THis is side bar that will need to be drawn for DotNet style + m_Rect.Width+=(objImageSize.Width+7); + } + + if(this.IsOnCustomizeMenu) + m_Rect.Width+=(objImageSize.Height+2); + + // Always call base implementation to reset resize flag + base.RecalcSize(); + } + + protected internal override void OnContainerChanged(object objOldContainer) + { + base.OnContainerChanged(objOldContainer); + ParentControlChanged(); + //this.RefreshBarText(); + } + + private void ParentControlChanged() + { + if(m_Control!=null) + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=m_Control.Parent) + { + bool bTextBoxMultiLine=false; + if(m_Control.Parent!=null) + { + // Must set the multiline=false on text box becouse it was crashing otherwise under certain conditions + if(m_Control is System.Windows.Forms.TextBox && ((System.Windows.Forms.TextBox)m_Control).Multiline) + { + bTextBoxMultiLine=true; + ((System.Windows.Forms.TextBox)m_Control).Multiline=false; + } + m_Control.Parent.Controls.Remove(m_Control); + } + + if(objCtrl!=null) + { + objCtrl.Controls.Add(m_Control); + if(m_Control is System.Windows.Forms.TextBox && bTextBoxMultiLine) + ((System.Windows.Forms.TextBox)m_Control).Multiline=true; + if(m_Control.Visible) + m_Control.Refresh(); + } + } + } + } + + protected internal override void OnProcessDelayedCommands() + { + if(m_DelayedWidth>=0) + { + int v=m_DelayedWidth; + m_DelayedWidth=-1; + this.Width=v; + } + if(m_DelayedHeight>0) + { + int v=m_DelayedHeight; + m_DelayedHeight=-1; + this.Height=v; + } + } + + protected internal override void OnVisibleChanged(bool newValue) + { + if(m_Control!=null && !newValue) + { + if(!(this.DesignMode && this.Site!=null)) + m_Control.Visible=newValue; + else + { + if(newValue) + m_Control.SendToBack(); + else + m_Control.BringToFront(); + } + } + Bar bar=this.ContainerControl as Bar; + if(bar!=null && bar.LayoutType==eLayoutType.DockContainer) + { + bar.OnDockContainerVisibleChanged(this); + if (bar.AutoHide) + { + bar.RefreshAutoHidePanel(); + bar.RefreshDockTab(true); + } + else + bar.RefreshDockTab(true); + } + base.OnVisibleChanged(newValue); + } + protected override void OnDisplayedChanged() + { + if(this.Displayed) + { + this.Refresh(); + Bar bar=this.ContainerControl as Bar; + if (bar != null) + { + //bar.MinClientSize = m_MinFormClientSize; + bar.SyncBarCaption(); + } + } + + if(m_Control!=null && !(this.IsOnCustomizeMenu || this.IsOnCustomizeDialog)) + { + ResizeControl(); + if(!(this.DesignMode && this.Site!=null)) + m_Control.Visible=this.Displayed; + else + { + if(this.Displayed) + m_Control.BringToFront(); + else + m_Control.SendToBack(); + ResizeControl(); + } + } + base.OnDisplayedChanged(); + } + + protected override void OnIsOnCustomizeDialogChanged() + { + base.OnIsOnCustomizeDialogChanged(); + CustomizeChanged(); + } + + protected override void OnDesignModeChanged() + { + base.OnDesignModeChanged(); + CustomizeChanged(); + } + + protected override void OnIsOnCustomizeMenuChanged() + { + base.OnIsOnCustomizeMenuChanged(); + CustomizeChanged(); + } + + private void CustomizeChanged() + { + if(m_Control!=null) + { + if(this.DesignMode && this.Site!=null) + return; + + if(this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.DesignMode) + { + m_Control.Enabled=false; + } + else + { + if(!(this.DesignMode && this.Site!=null)) + m_Control.Visible=this.Displayed; + m_Control.Enabled=true; + } + } + } + + private Size GetMaxImageSize() + { + if(m_Parent!=null) + { + ImageItem objParentImageItem=m_Parent as ImageItem; + if(objParentImageItem!=null) + return objParentImageItem.SubItemsImageSize; + else + return this.ImageSize; + } + else + return this.ImageSize; + } + private eTextFormat GetStringFormat() + { + eTextFormat format = eTextFormat.Default; + format |= eTextFormat.SingleLine; + format |= eTextFormat.EndEllipsis; + format |= eTextFormat.VerticalCenter; + return format; + + //StringFormat sfmt=BarFunctions.CreateStringFormat(); //new StringFormat(StringFormat.GenericDefault); + //sfmt.HotkeyPrefix=System.Drawing.Text.HotkeyPrefix.Show; + ////sfmt.FormatFlags=sfmt.FormatFlags & ~(sfmt.FormatFlags & StringFormatFlags.DisableKerning); + //sfmt.FormatFlags=sfmt.FormatFlags | StringFormatFlags.NoWrap; + //sfmt.Trimming=StringTrimming.EllipsisCharacter; + //sfmt.Alignment=System.Drawing.StringAlignment.Near; + //sfmt.LineAlignment=System.Drawing.StringAlignment.Center; + + //return sfmt; + } + + /// + /// Returns the Font object to be used for drawing the item text. + /// + /// Font object. + protected virtual Font GetFont() + { + System.Windows.Forms.Control objCtrl=this.ContainerControl as System.Windows.Forms.Control; + if(objCtrl!=null) + return (Font)objCtrl.Font; + return SystemFonts.DefaultFont; // (Font)System.Windows.Forms.SystemInformation.MenuFont; + } + protected internal override bool IsAnyOnHandle(IntPtr iHandle) + { + bool bRet=base.IsAnyOnHandle(iHandle); + if(!bRet && m_Control!=null && m_Control.Handle==iHandle) + bRet=true; + return bRet; + } + protected override void OnEnabledChanged() + { + base.OnEnabledChanged(); + + if(this.DesignMode && this.Site!=null) + return; + + if(m_Control!=null) + m_Control.Enabled=this.Enabled; + } + +// [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +// public override void InternalMouseEnter() +// { +// base.InternalMouseEnter(); +// if(!m_MouseOver) +// { +// m_MouseOver=true; +// this.Refresh(); +// } +// } +// +// [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +// public override void InternalMouseLeave() +// { +// base.InternalMouseLeave(); +// if(m_MouseOver) +// { +// m_MouseOver=false; +// this.Refresh(); +// } +// } + [EditorBrowsable(EditorBrowsableState.Never)] + public override void OnGotFocus() + { + base.OnGotFocus(); + if(m_Control==null) + return; + if(m_Control.Focused || this.IsOnCustomizeMenu || this.IsOnCustomizeDialog || this.DesignMode) + return; + m_Control.Focus(); + } + + /// + /// Gets or sets a value indicating whether the item is visible. + /// + public override bool Visible + { + get + { + if(this.IsOnMenu) + return false; + Bar objTlb=this.ContainerControl as Bar; + if(objTlb!=null) + { + if(objTlb.BarState==eBarState.Docked || objTlb.BarState==eBarState.Floating || objTlb.BarState==eBarState.AutoHide) + return base.Visible; + else + return false; + } + return base.Visible; + } + set + { + base.Visible=value; + } + } + + // Property Editor support for ImageIndex selection + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public System.Windows.Forms.ImageList ImageList + { + get + { + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null) + return owner.Images; + return null; + } + } + + /// + /// Specifies the Tab image. Image specified here is used only on Tab when there are multiple dock containers on Bar. + /// + [Browsable(true),DevCoBrowsable(true),DefaultValue(null),Category("Appearance"),Description("Specifies the Tab image. Image specified here is used only on Tab when there are multiple dock containers on Bar.")] + public System.Drawing.Image Image + { + get + { + return m_Image; + } + set + { + m_Image=value; + m_TabImage=null; + Bar bar=this.ContainerControl as Bar; + if(bar!=null) + bar.RefreshDockContainerItem(this); + } + } + + /// + /// Specifies the index of the Tab image if ImageList is used. Image specified here is used only on Tab when there are multiple dock containers on Bar. + /// + [Browsable(true),DevCoBrowsable(true),DefaultValue(-1),Category("Appearance"),Description("Specifies the index of the Tab image if ImageList is used. Image specified here is used only on Tab when there are multiple dock containers on Bar."),System.ComponentModel.Editor("DevComponents.DotNetBar.Design.ImageIndexEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)),System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.ImageIndexConverter))] + public int ImageIndex + { + get + { + return m_ImageIndex; + } + set + { + if(m_ImageIndex!=value) + { + m_ImageIndex=value; + if(ShouldSyncProperties) + BarFunctions.SyncProperty(this, "ImageIndex"); + m_TabImage=null; + Bar bar=this.ContainerControl as Bar; + if(bar!=null) + bar.RefreshDockContainerItem(this); + } + } + } + + /// + /// Specifies the Button icon. Icons support multiple image sizes and alpha blending. + /// + [Browsable(true),DevCoBrowsable(true),Category("Appearance"),Description("Specifies the Button icon. Icons support multiple image sizes and alpha blending."),DefaultValue(null)] + public System.Drawing.Icon Icon + { + get + { + return m_Icon; + } + set + { + NeedRecalcSize=true; + m_Icon=value; + + m_TabImage=null; + Bar bar=this.ContainerControl as Bar; + if(bar!=null) + bar.RefreshDockContainerItem(this); + } + } + + /// + /// Gets or sets the predefined tab color. Default value is eTabItemColor.Default which means that default color is used. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(eTabItemColor.Default), Category("Style"), Description("Applies predefined color to tab.")] + public eTabItemColor PredefinedTabColor + { + get { return m_PredefinedTabColor; } + set + { + if(m_PredefinedTabColor!=value) + { + m_PredefinedTabColor = value; + Bar bar=this.ContainerControl as Bar; + if(bar!=null && bar.DockTabControl!=null) + { + TabItem tab = GetTabItem(bar.DockTabControl); + if(tab!=null) + tab.PredefinedColor=m_PredefinedTabColor; + } + if (this.DesignMode) + { + System.Windows.Forms.Control c = this.ContainerControl as System.Windows.Forms.Control; + if(c!=null) + c.Refresh(); + } + } + } + } + + private TabItem GetTabItem(TabStrip dockTabControl) + { + foreach (TabItem tab in dockTabControl.Tabs) + { + if (tab.AttachedItem == this) + return tab; + } + return null; + } + + internal System.Drawing.Image TabImage + { + get + { + if(m_TabImage==null) + { + System.Drawing.Image img=this.GetImage(); + if(img!=null) + { + if(img.Width==16 && img.Height==16) + { + m_TabImage=(System.Drawing.Image)img.Clone(); + } + else + { + m_TabImage=new Bitmap(img,16,16); + Graphics g=Graphics.FromImage(m_TabImage); + g.DrawImage(img,new Rectangle(0,0,16,16),0,0,16,16,GraphicsUnit.Pixel); + g.Dispose(); + } + } + } + + return m_TabImage; + } + } + + private Image GetImage() + { + if(m_Image!=null) + return m_Image; + return GetImageFromImageList(m_ImageIndex); + } + + internal void SetImageIndex(int iImageIndex) + { + m_ImageIndex=iImageIndex; + } + + private Image GetImageFromImageList(int ImageIndex) + { + if(ImageIndex>=0) + { + IOwner owner=this.GetOwner() as IOwner; + if(owner!=null) + { + if(owner.Images!=null && owner.Images.Images.Count>0 && ImageIndex + /// Gets or sets whether tab that dock container item is on is selected. + /// + [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool Selected + { + get + { + if(this.Visible) + { + Bar bar= this.ContainerControl as Bar; + if(bar!=null) + { + return (bar.SelectedDockContainerItem == this); + } + } + return false; + } + set + { + if(this.Visible) + { + Bar bar= this.ContainerControl as Bar; + if(bar!=null) + { + bar.SelectedDockContainerItem = this; + } + } + } + } + + /// + /// Gets or sets the width of the item in pixels. + /// + [Browsable(false),DevCoBrowsable(false),DefaultValue(0),Category("Layout"),Description("Indicates the width of the item in pixels."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Width + { + get + { + return this.DisplayRectangle.Width; + } + set + { + if(value=m_MinimumSize.Width) + { + Bar bar=this.ContainerControl as Bar; + GenericItemContainer parent=this.Parent as GenericItemContainer; + if(parent!=null && parent.SystemContainer && bar!=null && bar.LayoutType==eLayoutType.DockContainer && bar.Stretch) + { + bar.OnDockContainerWidthChanged(this,value); + m_DelayedWidth=-1; + } + else + m_DelayedWidth=value; + } + } + } + + /// + /// Gets or sets the height of the item in pixels. + /// + [Browsable(false),DevCoBrowsable(true),DefaultValue(0),Category("Layout"),Description("Indicates height of the item in pixels."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int Height + { + get + { + return this.DisplayRectangle.Height; + } + set + { + if(value=m_MinimumSize.Height) + { + Bar bar=this.ContainerControl as Bar; + GenericItemContainer parent=this.Parent as GenericItemContainer; + if(parent!=null && parent.SystemContainer && bar!=null && bar.LayoutType==eLayoutType.DockContainer && bar.Stretch) + { + bar.OnDockContainerHeightChanged(this,value); + m_DelayedHeight=-1; + } + else + m_DelayedHeight=value; + } + } + } + + /// + /// Gets or sets the minimum size of the item. When used please note that layout logic for dockable windows expects that + /// all DockContainerItems that are in particular docking side have exact same minimum size. When setting this property it is + /// best to set the same value for all DockContainerItem instances you create. + /// + [Browsable(false),DevCoBrowsable(false),Category("Layout"),Description("Gets or sets the minimum size of the item.")] + public System.Drawing.Size MinimumSize + { + get + { + return m_MinimumSize; + } + set + { + m_MinimumSize=value; + if(m_MinimumSize.Width>m_DefaultFloatingSize.Width) + m_DefaultFloatingSize.Width=m_MinimumSize.Width; + if(m_MinimumSize.Height>m_DefaultFloatingSize.Height) + m_DefaultFloatingSize.Height=m_MinimumSize.Height; + Bar bar=this.ContainerControl as Bar; + if(bar!=null) + bar.OnDockContainerMinimumSizeChanged(this); + if(m_MinimumSize.Width>this.Width) + this.Width=m_MinimumSize.Width; + if(m_MinimumSize.Height>this.Height) + this.Height=m_MinimumSize.Height; + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeMinimumSize() + { + if(m_MinimumSize.Width!=32 || m_MinimumSize.Height!=32) + return true; + return false; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public void ResetMinimumSize() + { + this.MinimumSize = new Size(32,32); + } + + /// + /// Gets or sets the default floating size of the Bar that is containing this item. + /// + [Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Gets or sets the default floating size of the Bar that is containing this item.")] + public System.Drawing.Size DefaultFloatingSize + { + get + { + return m_DefaultFloatingSize; + } + set + { + if(value.Width + /// Gets or sets the minimum size of the form client area that is tried to maintain when dockable window is resized. + /// + [Obsolete("This property is obsolete and it will be removed in next version"), EditorBrowsable(EditorBrowsableState.Never),Browsable(false),DevCoBrowsable(false),System.ComponentModel.DefaultValue(64),System.ComponentModel.Category("Layout"),System.ComponentModel.Description("Gets or sets the minimum size of the form client area that is tried to maintain when dockable window is resized."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int MinFormClientSize + { + get {return m_MinFormClientSize;} + set + { + m_MinFormClientSize=value; + //if(this.Displayed) + //{ + // Bar bar=this.ContainerControl as Bar; + // if(bar!=null) + // bar.MinClientSize=m_MinFormClientSize; + //} + } + } + + /// + /// Gets or sets whether the item expands automatically to fill out the remaining space inside the container. Applies to Items on stretchable, no-wrap Bars only. + /// + [Browsable(false),DevCoBrowsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public override bool Stretch + { + get + { + return base.Stretch; + } + set + { + base.Stretch=value; + } + } + + /// + /// Gets or sets whether item can be customized by end user. + /// + [Browsable(false),DevCoBrowsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),Category("Behavior"),Description("Indicates whether item can be customized by user.")] + public override bool CanCustomize + { + get + { + return base.CanCustomize; + } + set + { + base.CanCustomize=value; + } + } + + + /// + /// Occurs after an item has been removed. + /// + /// Item being removed. + protected internal override void OnAfterItemRemoved(BaseItem item, int itemIndex) + { + base.OnAfterItemRemoved(item, itemIndex); + ParentControlChanged(); + } + + [System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public override bool IsWindowed + { + get {return true;} + } + + /// + /// Occurs after text has changed. + /// + protected override void OnTextChanged() + { + base.OnTextChanged(); + if(this.ContainerControl is Bar /*&& !this.Displayed*/) // Refresh Tab Text even when dock container item is selected. + ((Bar)this.ContainerControl).RefreshDockContainerItem(this); + } + + protected override void OnTooltipChanged() + { + base.OnTooltipChanged(); + if (this.ContainerControl is Bar) // Refresh Tab Tooltip even when dock container item is selected. + ((Bar)this.ContainerControl).RefreshDockContainerItem(this); + } + + /// + /// Returns whether item is in design mode or not. + /// + [System.ComponentModel.Browsable(false),DevCoBrowsable(false)] + public override bool DesignMode + { + get + { + return (base.DesignMode || this.Site!=null && this.Site.DesignMode); + } + } + + /// + /// Occurs after item visual style has changed. + /// + protected override void OnStyleChanged() + { + base.OnStyleChanged(); + if(m_Control is PanelDockContainer) + { + if(!((PanelDockContainer)m_Control).UseCustomStyle) + ((PanelDockContainer)m_Control).ColorSchemeStyle=this.Style; + } + } + + /// + /// Gets or sets whether item is global or not. + /// This flag is used to propagate property changes to all items with the same name. + /// Setting for example Visible property on the item that has GlobalItem set to true will + /// set visible property to the same value on all items with the same name. + /// + [Browsable(true), DevCoBrowsable(true), DefaultValue(false), Category("Behavior"), Description("Indicates whether certain global properties are propagated to all items with the same name when changed.")] + public override bool GlobalItem + { + get { return base.GlobalItem; } + set { base.GlobalItem = value; } + } + + private eDockContainerClose _CanClose = eDockContainerClose.Inherit; + /// + /// Gets or sets the close button behavior on the host Bar. Default value is eDockContainerClose.Inherit which means that Bar.CanHide will control whether DockContainerItem can be closed. + /// + [Category("Behavior"), DefaultValue(eDockContainerClose.Inherit), Description("Specifies close button behavior on the host Bar. Default value is eDockContainerClose.Inherit which means that Bar.CanHide will control whether DockContainerItem can be closed.")] + public eDockContainerClose CanClose + { + get { return _CanClose; } + set + { + if (value != _CanClose) + { + eDockContainerClose oldValue = _CanClose; + _CanClose = value; + OnCanCloseChanged(oldValue, value); + } + } + } + + private void OnCanCloseChanged(eDockContainerClose oldValue, eDockContainerClose newValue) + { + Bar bar = this.ContainerControl as Bar; + if(bar!=null) + bar.DockContainerItemCanCloseChanged(this, oldValue, newValue); + } + + /// + /// Gets or sets a value indicating whether the item is enabled. + /// + [System.ComponentModel.Browsable(false), DevCoBrowsable(false), System.ComponentModel.DefaultValue(true), System.ComponentModel.Category("Behavior"), System.ComponentModel.Description("Indicates whether is item enabled.")] + public override bool Enabled + { + get { return base.Enabled; } + set { base.Enabled = value; } + } + + } + + #region DockItemAccessibleObject + public class DockItemAccessibleObject : System.Windows.Forms.AccessibleObject + { + private DockContainerItem m_Owner = null; + private bool m_Hot = false; + public DockItemAccessibleObject(DockContainerItem owner) + { + m_Owner = owner; + + } + + internal DockContainerItem Owner + { + get { return m_Owner; } + } + + public override string Name + { + get + { + if (m_Owner == null) + return ""; + + if (m_Owner.AccessibleName != "") + return m_Owner.AccessibleName; + + if (m_Owner.Text != null) + return m_Owner.Text.Replace("&", ""); + + return m_Owner.Tooltip; + } + set + { + m_Owner.AccessibleName = value; + } + } + + public override string Description + { + get + { + if (m_Owner == null) + return ""; + if (m_Owner.AccessibleDescription != "") + return m_Owner.AccessibleDescription; + return ""; + } + } + + public override System.Windows.Forms.AccessibleRole Role + { + get + { + if (m_Owner == null || !m_Owner.IsAccessible) + return System.Windows.Forms.AccessibleRole.None; + + if (m_Owner.AccessibleRole != System.Windows.Forms.AccessibleRole.Default) + return m_Owner.AccessibleRole; + return System.Windows.Forms.AccessibleRole.Pane; + } + } + + public override System.Windows.Forms.AccessibleStates State + { + get + { + if (m_Owner == null) + return System.Windows.Forms.AccessibleStates.Unavailable; + //System.Diagnostics.Trace.WriteLine("Getting state for "+m_Owner.Text); + System.Windows.Forms.AccessibleStates state = 0; + + if (!m_Owner.IsAccessible) + return System.Windows.Forms.AccessibleStates.Unavailable; + + if (!m_Owner.Displayed || !m_Owner.Visible) + state |= System.Windows.Forms.AccessibleStates.Invisible; + else if (!m_Owner.GetEnabled()) + { + state = System.Windows.Forms.AccessibleStates.Unavailable; + return state; + } + else + { + if (m_Owner.Selected) + state |= (System.Windows.Forms.AccessibleStates.Selected); + else + state |= System.Windows.Forms.AccessibleStates.Selectable | System.Windows.Forms.AccessibleStates.Focusable; + } + + return state; + } + } + + public override System.Windows.Forms.AccessibleObject Parent + { + get + { + if (m_Owner == null) + return null; + if (m_Owner.Parent != null) + { + if (!(m_Owner.Parent is GenericItemContainer && ((GenericItemContainer)m_Owner.Parent).SystemContainer)) + return m_Owner.Parent.AccessibleObject; + } + + System.Windows.Forms.Control control = m_Owner.ContainerControl as System.Windows.Forms.Control; + if (control != null) + return control.AccessibilityObject; + return null; + } + } + + public override System.Drawing.Rectangle Bounds + { + get + { + if (m_Owner == null) + return System.Drawing.Rectangle.Empty; + + System.Windows.Forms.Control objCtrl = m_Owner.ContainerControl as System.Windows.Forms.Control; + if (objCtrl != null) + return objCtrl.RectangleToScreen(m_Owner.DisplayRectangle); + return m_Owner.Bounds; + } + } + + public override int GetChildCount() + { + if (m_Owner == null) + return 0; + return m_Owner.Control != null ? 1 : 0; + } + + public override System.Windows.Forms.AccessibleObject GetChild(int iIndex) + { + if (m_Owner == null || iIndex < 0 || iIndex >= 1 || m_Owner.Control == null) + return null; + return m_Owner.Control.AccessibilityObject; + } + + public override string DefaultAction + { + get + { + if (m_Owner.AccessibleDefaultActionDescription != "") + return m_Owner.AccessibleDefaultActionDescription; + return "Select"; + } + } + + public override void DoDefaultAction() + { + if (m_Owner == null) + return; + + m_Owner.Selected = true; + //System.Windows.Forms.Control cont = m_Owner.ContainerControl as System.Windows.Forms.Control; + //if (cont is MenuPanel && !(cont is IAccessibilitySupport)) + //{ + // cont = ((MenuPanel)cont).ParentItem.ContainerControl as System.Windows.Forms.Control; + //} + + //IAccessibilitySupport ias = cont as IAccessibilitySupport; + //if (ias != null) + //{ + // ias.DoDefaultActionItem = m_Owner; + // NativeFunctions.PostMessage(cont.Handle, NativeFunctions.WM_USER + 107, IntPtr.Zero, IntPtr.Zero); + //} + + base.DoDefaultAction(); + } + + public override string KeyboardShortcut + { + get + { + return m_Owner.ShortcutString; + } + } + + public override System.Windows.Forms.AccessibleObject GetSelected() + { + if (m_Owner == null) + return base.GetSelected(); + + return base.GetSelected(); + } + + public override System.Windows.Forms.AccessibleObject HitTest(int x, int y) + { + if (m_Owner == null) + return base.HitTest(x, y); + + Point screen = new Point(x, y); + if (m_Owner.Control != null) + { + System.Windows.Forms.Control cont = m_Owner.Control; + if (cont != null) + { + Point p = cont.PointToClient(screen); + if (cont.ClientRectangle.Contains(p)) + return cont.AccessibilityObject; + } + } + return base.HitTest(x, y); + } + + public override System.Windows.Forms.AccessibleObject Navigate(System.Windows.Forms.AccessibleNavigation navdir) + { + if (m_Owner == null) + return base.Navigate(navdir); + + if (navdir == System.Windows.Forms.AccessibleNavigation.FirstChild || navdir == System.Windows.Forms.AccessibleNavigation.LastChild) + { + if (m_Owner.Control != null) + return m_Owner.Control.AccessibilityObject; + } + + return base.Navigate(navdir); + } + + } + #endregion + + /// + /// Specifies the behavior of the close button on host bar for the DockContainerItem. + /// + public enum eDockContainerClose + { + /// + /// Closing of the bar is inherited from the host bar. Bar.CanHide property will control close button visibility. + /// + Inherit, + /// + /// Closing of the DockContainerItem is allowed. + /// + Yes, + /// + /// Closing of DockContainerItem is not allowed. + /// + No + } +} diff --git a/PROMS/DotNetBar Source Code/DockContainerItemDesigner.cs b/PROMS/DotNetBar Source Code/DockContainerItemDesigner.cs new file mode 100644 index 00000000..9d2ad128 --- /dev/null +++ b/PROMS/DotNetBar Source Code/DockContainerItemDesigner.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; + +namespace DevComponents.DotNetBar +{ + /// + /// Summary description for DockContainerItemDesigner. + /// + public class DockContainerItemDesigner:ComponentDesigner + { + public override void Initialize(IComponent component) + { + base.Initialize(component); + + if(!component.Site.DesignMode) + return; + + DockContainerItem c=component as DockContainerItem; + if(c!=null) + { + this.Visible=c.Visible; + } + } + + protected override void PreFilterProperties(IDictionary properties) + { + base.PreFilterProperties(properties); + properties["Visible"] = TypeDescriptor.CreateProperty(typeof(DockContainerItemDesigner),(PropertyDescriptor)properties["Visible"], new Attribute[] + { + new DefaultValueAttribute(true), + new BrowsableAttribute(true), + new CategoryAttribute("Layout")}); + + } + + /// + /// Gets or sets whether item is visible. + /// + [DefaultValue(true),Browsable(true),DevCoBrowsable(true),Category("Layout"),Description("Gets or sets whether item is visible.")] + public bool Visible + { + get + { + return (bool)ShadowProperties["Visible"]; + } + set + { + // this value is not passed to the actual control + this.ShadowProperties["Visible"] = value; + } + } + } +} diff --git a/PROMS/DotNetBar Source Code/DockSite.cs b/PROMS/DotNetBar Source Code/DockSite.cs new file mode 100644 index 00000000..cc8a5bdb --- /dev/null +++ b/PROMS/DotNetBar Source Code/DockSite.cs @@ -0,0 +1,3189 @@ +namespace DevComponents.DotNetBar +{ + using System; + using System.Collections; + using System.ComponentModel; + using System.Drawing; + using System.Data; + using System.Windows.Forms; + using DevComponents.DotNetBar.Rendering; + + #region IDockInfo + /// + /// Interface used for docking support. + /// + public interface IDockInfo + { + /// + /// Returns Minimum docked size of the control. + /// + System.Drawing.Size MinimumDockSize(eOrientation dockOrientation); + /// + /// Returns Preferrred size of the docked control. + /// + System.Drawing.Size PreferredDockSize(eOrientation dockOrientation); + /// + /// Indicated whether control can be docked on top dock site. + /// + bool CanDockTop {get;} + /// + /// Indicated whether control can be docked on bottom dock site. + /// + bool CanDockBottom {get;} + /// + /// Indicated whether control can be docked on left dock site. + /// + bool CanDockLeft {get;} + /// + /// Indicated whether control can be docked on right dock site. + /// + bool CanDockRight {get;} + /// + /// Indicates whether control can be docked as document i.e. middle (fill) dock site. + /// + bool CanDockDocument {get;} + /// + /// Indicates whether control can be docked as tab to another bar. + /// + bool CanDockTab {get;} + /// + /// Indicated whether control can be stretched to fill dock site. + /// + bool Stretch {get;set;} + /// + /// Holds the left position (dock offset) of the control. + /// + int DockOffset {get;set;} + /// + /// Specifies the dock line for the control. + /// + int DockLine {get;set;} + /// + /// Specifies current dock orientation. + /// + eOrientation DockOrientation {get;set;} + /// + /// Gets whether control is docked. + /// + bool Docked {get;} + /// + /// Returns the dock site of the control. + /// + System.Windows.Forms.Control DockedSite {get;} + /// + /// Gets or sets the control dock side. + /// + eDockSide DockSide{get;set;} + /// + /// Sets the dock line for the control. Used internaly by dock manager. + /// + /// New Dock line. + void SetDockLine(int iLine); + /// + /// Gets or sets whether bar is locked to prevent docking below it. + /// + bool LockDockPosition{get;set;} + } + #endregion + + #region DockSiteInfo + /// + /// Represent the docking information for an control. + /// + public class DockSiteInfo + { + /// + /// Control dock side. + /// + public System.Windows.Forms.DockStyle DockSide; + /// + /// Control dock site. + /// + public DockSite objDockSite; + /// + /// Docking offset. + /// + public int DockOffset; + /// + /// Docking line. + /// + public int DockLine; + /// + /// Docked control width. + /// + public int DockedWidth; + /// + /// Docked control height. + /// + public int DockedHeight; + /// + /// Control position. + /// + public int InsertPosition; + public bool NewLine; + public bool IsEmpty() + { + if(this.DockSide==System.Windows.Forms.DockStyle.None && this.objDockSite==null && this.DockOffset==0 && this.DockLine==0 && this.DockedWidth==0 && this.DockedHeight==0 && this.InsertPosition==0 && this.NewLine==false) + return true; + return false; + } + public Bar TabDockContainer; + /// + /// Indicates whether to use outline or not + /// + public bool UseOutline; + /// + /// Indicates that dock site should change it's Z-Order so it maximizes the space it consumes as related to other dock sites. + /// + public bool FullSizeDock; + /// + /// Indicates that dock site should change it's Z-Order so it reduces the amount of space it consumes as related to other dock sites. + /// + public bool PartialSizeDock; + /// + /// When either FullSizeDock or PartialSizeDock is set it indicates the new dock site Z-Order index. + /// + public int DockSiteZOrderIndex; + /// + /// Returns the bar that mouse is placed over. + /// + public Bar MouseOverBar; + /// + /// Returns dock side the mouse is indicating user wants to dock bar at. + /// + public eDockSide MouseOverDockSide; + /// + /// Gets the last relative docked to bar. + /// + public Bar LastRelativeDockToBar; + /// + /// Gets the last relative docked to document id. + /// + public long LastRelativeDocumentId; + /// + /// Returns side of last docked-to dock site. + /// + public eDockSide LastDockSiteSide; + } + #endregion + + /// + /// Dock Sites are created by DotNetBar control on each edge of the + /// DotNetBar container control and are used for docking purposes. + /// If Dock Site does not contain any controls it will be invisible. + /// + [ToolboxItem(false), DesignTimeVisible(false), Designer("DevComponents.DotNetBar.Design.DockSiteDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] + public class DockSite : System.Windows.Forms.Control + { + private eOrientation m_DockOrientation; + private bool m_Layingout=false; + private bool m_OversizeLayout=false; + //private int m_DockMargin; + private DotNetBarManager m_Owner=null; + private bool m_NeedsLayout=false; + private bool m_NeedsNormalize=false; + + // Theme Cache + private ThemeRebar m_ThemeRebar=null; + + private eBackgroundImagePosition m_BackgroundImagePosition=eBackgroundImagePosition.Stretch; + private byte m_BackgroundImageAlpha=255; + private Color m_BackColor2=Color.Empty; + private int m_BackColorGradientAngle=90; + + private bool m_Disposed=false; + private DocumentDockUIManager m_DocumentUIManager=null; + private bool m_LayoutSuspended=false; + [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool _DesignerLoading = false; + private int m_OriginalSize = 0; + private bool m_OptimizeLayoutRedraw = true; + + /// + /// Creates new instance of DockSite object with specified dock style. + /// + /// Specifies the position and manner in which a site is docked. + public DockSite(System.Windows.Forms.DockStyle DockSide):this() + { + this.Dock=DockSide; + } + + protected override AccessibleObject CreateAccessibilityInstance() + { + return new DockSiteAccessibleObject(this); + } + + /// + /// Creates new instance of DockSite object. + /// + public DockSite() + { + this.TabStop=false; + this.SetStyle(ControlStyles.Selectable,false); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + this.IsAccessible=true; + this.AccessibleRole=AccessibleRole.Window; + } + + protected override void Dispose(bool disposing) + { + m_Owner=null; + m_Disposed=true; + base.Dispose(disposing); + } + + protected override void ScaleControl(SizeF factor, BoundsSpecified specified) + { + if (Dpi.RecordScalePerControl) + Dpi.SetScaling(factor); + base.ScaleControl(factor, specified); + } + + /// + /// Gets or sets whether painting is disabled on dock site while layout of bars is performed. Default value is true. + /// You might need to set this property to false if you are expirience vide flashing while using DirectX video animation in Bar controls that are part of the + /// dock site. + /// + [DefaultValue(true), Description("Indicates whether painting is disabled on dock site while layout of bars is performed.")] + public bool OptimizeLayoutRedraw + { + get { return m_OptimizeLayoutRedraw; } + set { m_OptimizeLayoutRedraw = value; } + } + + private DocumentDockContainer m_DocumentDockContainer=null; + [Browsable(false), DefaultValue(null)] + public DocumentDockContainer DocumentDockContainer + { + get {return m_DocumentDockContainer;} + set + { + m_DocumentDockContainer=value; + m_DocumentUIManager=this.GetDocumentUIManager(); + m_DocumentUIManager.RootDocumentDockContainer=m_DocumentDockContainer; + if (this.Dock != DockStyle.Fill && value!=null) m_DocumentDockContainer.RecordDocumentSize = true; + } + } + + /// + /// Returns reference to the DocumentDockUIManager object used for interaction with document docking engine. + /// + /// Reference to the DocumentDockUIManager object. + public DocumentDockUIManager GetDocumentUIManager() + { + if (m_DocumentUIManager == null) + { + m_DocumentUIManager = new DocumentDockUIManager(this); + m_DocumentUIManager.RootDocumentDockContainer = m_DocumentDockContainer; + } + return m_DocumentUIManager; + } + + /// + /// Specifies background image position when container is larger than image. + /// + [Browsable(true),DevCoBrowsable(true),Category("Appearance"),DefaultValue(eBackgroundImagePosition.Stretch),Description("Specifies background image position when container is larger than image.")] + public eBackgroundImagePosition BackgroundImagePosition + { + get {return m_BackgroundImagePosition;} + set + { + if(m_BackgroundImagePosition!=value) + { + m_BackgroundImagePosition=value; + this.Refresh(); + } + } + } + + /// + /// Saves layout for bars contained by dock site. + /// + /// Parent XmlElement. + public void SaveLayout(System.Xml.XmlElement xmlBars) + { + if(this.IsDocumentDock || m_DocumentDockContainer!=null) + { + this.GetDocumentUIManager().SerializeLayout(xmlBars); + } + else + { + foreach(Control ctrl in this.Controls) + { + DevComponents.DotNetBar.Bar bar=ctrl as DevComponents.DotNetBar.Bar; + if(bar!=null && bar.Name!="" && bar.SaveLayoutChanges) + { + System.Xml.XmlElement xmlBar=xmlBars.OwnerDocument.CreateElement("bar"); + xmlBars.AppendChild(xmlBar); + bar.SerializeLayout(xmlBar); + } + } + } + } + + /// + /// Loads layout for the bars. + /// + /// Parent XmlElement that was passed to SaveLayout method to save layout + public void LoadLayout(System.Xml.XmlElement xmlBars) + { + m_LayoutSuspended=true; + try + { + if(!this.IsDocumentDock && m_DocumentDockContainer==null) + { + foreach(System.Xml.XmlElement xmlBar in xmlBars.ChildNodes) + { + DevComponents.DotNetBar.Bar bar=null; + if(m_Owner.Bars.Contains(m_Owner.Bars[xmlBar.GetAttribute("name")])) + bar=m_Owner.Bars[xmlBar.GetAttribute("name")]; + else + { + bar=new Bar(); + m_Owner.Bars.Add(bar); + } + bar.DeserializeLayout(xmlBar); + } + } + else + { + this.GetDocumentUIManager().DeserializeLayout((System.Xml.XmlElement)xmlBars.FirstChild); + } + } + finally + { + m_LayoutSuspended=false; + this.RecalcLayout(); + } + } + + /// + /// Suspends normal layout logic. + /// + public new void SuspendLayout() + { + m_LayoutSuspended = true; + base.SuspendLayout(); + } + + /// + /// Resumes normal layout logic. + /// + public new void ResumeLayout() + { + this.ResumeLayout(true); + } + + /// + /// Resumes normal layout logic. Optionally forces an immediate layout of pending layout requests. + /// + public new void ResumeLayout(bool performLayout) + { + m_LayoutSuspended = false; + base.ResumeLayout(performLayout); + } + + /// + /// Specifies the transparency of background image. + /// + [Browsable(true),DevCoBrowsable(true),Category("Appearance"),DefaultValue((byte)255),Description("Specifies the transparency of background image.")] + public byte BackgroundImageAlpha + { + get {return m_BackgroundImageAlpha;} + set + { + if(m_BackgroundImageAlpha!=value) + { + m_BackgroundImageAlpha=value; + this.Refresh(); + } + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackgroundImageAlpha() + { + return m_BackgroundImageAlpha!=255; + } + + /// + /// Gets or sets the target gradient background color. + /// + [Browsable(true),Description("Indicates the target gradient background color."),Category("Style")] + public Color BackColor2 + { + get {return m_BackColor2;} + set + { + m_BackColor2=value; + if(this.DesignMode) + this.Refresh(); + } + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeBackColor2() + { + return !m_BackColor2.IsEmpty; + } + [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] + public void ResetBackColor2() + { + m_BackColor2=Color.Empty; + } + + /// + /// Gets or sets gradient fill angle. + /// + [Browsable(true),Description("Indicates gradient fill angle."),Category("Style"),DefaultValue(90)] + public int BackColorGradientAngle + { + get {return m_BackColorGradientAngle;} + set + { + if(value!=m_BackColorGradientAngle) + { + m_BackColorGradientAngle=value; + if(this.DesignMode) + this.Refresh(); + } + } + } + + internal bool GetDesignMode() + { + return this.DesignMode; + } + +// /// +// /// Gets the collection of controls contained within the control. +// /// +// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),Browsable(false),DevCoBrowsable(false)] +// public new Control.ControlCollection Controls +// { +// get +// { +// return base.Controls; +// } +// } + + //public bool ShouldSerializeControls() + //{ + // if(this.Dock==DockStyle.Fill) + // return true; + // else + // return false; + //} + + protected override void OnVisibleChanged(EventArgs e) + { + base.OnVisibleChanged(e); + if(this.Visible) + { + Control.ControlAccessibleObject acc=this.AccessibilityObject as Control.ControlAccessibleObject; + if(acc!=null) + { + acc.NotifyClients(AccessibleEvents.Show); + } + } + } + + private bool IsToolbarDockSite + { + get + { + return !(this.Dock == DockStyle.Fill || m_DocumentDockContainer != null); + } + } + protected override void OnPaintBackground(PaintEventArgs pevent) + { + if(IsLayoutSuspended) + return; + if (this.BackgroundImage != null && this.BackgroundImageAlpha == 255 && ((this.BackgroundImagePosition == eBackgroundImagePosition.Stretch || this.BackgroundImagePosition == eBackgroundImagePosition.Tile) || + this.BackgroundImage.Width >= this.Width && this.BackgroundImage.Height >= this.Height)) + return; + if(!m_BackColor2.IsEmpty && !this.BackColor.IsEmpty) + { + if(this.Width>0 && this.Height>0) + { + DisplayHelp.FillRectangle(pevent.Graphics, this.ClientRectangle, this.BackColor, this.BackColor2, m_BackColorGradientAngle); + return; + } + } + + if(this.Controls.Count>0 && this.Controls[0] is Bar && ((Bar)this.Controls[0]).ThemedBackground) + { + ThemeRebar theme=this.ThemeRebar; + theme.DrawBackground(pevent.Graphics,ThemeRebarParts.Background,ThemeRebarStates.Normal,this.ClientRectangle); + return; + } + ColorScheme cs = GetColorScheme(); + if (cs != null && this.BackColor != Color.Transparent) + { + if(this.IsToolbarDockSite && StyleManager.IsVisualStudio2012(StyleManager.Style)) + DisplayHelp.FillRectangle(pevent.Graphics, this.ClientRectangle, cs.BarBackground, cs.BarBackground2, cs.BarBackgroundGradientAngle); + else + DisplayHelp.FillRectangle(pevent.Graphics, this.ClientRectangle, cs.DockSiteBackColor, cs.DockSiteBackColor2, cs.DockSiteBackColorGradientAngle); + } + else + base.OnPaintBackground(pevent); + } + + private ColorScheme GetColorScheme() + { + if (m_Owner != null && m_Owner.UseGlobalColorScheme) + { + if ((m_Owner.Style == eDotNetBarStyle.Office2007 || m_Owner.Style == eDotNetBarStyle.StyleManagerControlled) && GlobalManager.Renderer is Office2007Renderer) + { + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.LegacyColors; + } + return m_Owner.ColorScheme; + } + else if (this.Controls.Count > 0 && this.Controls[0] is Bar && (((Bar)this.Controls[0]).Style == eDotNetBarStyle.Office2003 || ((Bar)this.Controls[0]).Style == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(((Bar)this.Controls[0]).Style)) ) + { + Bar bar = this.Controls[0] as Bar; + if (bar.Style == eDotNetBarStyle.StyleManagerControlled && GlobalManager.Renderer is Office2007Renderer) + return ((Office2007Renderer)GlobalManager.Renderer).ColorTable.LegacyColors; + return bar.GetColorScheme(); + } + + return null; + } + + protected override void OnPaint(PaintEventArgs pevent) + { + if(IsLayoutSuspended) + return; + if(this.BackgroundImage!=null) + { + BarFunctions.PaintBackgroundImage(pevent.Graphics,this.ClientRectangle,this.BackgroundImage,m_BackgroundImagePosition,m_BackgroundImageAlpha); + } + else + base.OnPaint(pevent); + } + + private DevComponents.DotNetBar.ThemeRebar ThemeRebar + { + get + { + if(m_ThemeRebar==null) + { + m_ThemeRebar=new ThemeRebar(this); + } + return m_ThemeRebar; + } + } + + protected override void OnHandleCreated(EventArgs e) + { + base.OnHandleCreated(e); + this.RecalcLayout(); + } + + protected override void OnHandleDestroyed(EventArgs e) + { + if(m_ThemeRebar!=null) + { + m_ThemeRebar.Dispose(); + m_ThemeRebar=null; + } + base.OnHandleDestroyed(e); + } + protected override void WndProc(ref Message m) + { + if(m.Msg==NativeFunctions.WM_THEMECHANGED) + { + m_ThemeRebar=null; + } + base.WndProc(ref m); + } + + /// + /// Specifies the position and manner in which a site is docked. + /// + public override System.Windows.Forms.DockStyle Dock + { + get + { + return base.Dock; + } + set + { + base.Dock=value; + if(value==System.Windows.Forms.DockStyle.Top || value==System.Windows.Forms.DockStyle.Bottom || value==DockStyle.Fill) + { + if(this.Controls.Count==0) + this.Height=0; + m_DockOrientation=eOrientation.Horizontal; + } + else + { + if(this.Controls.Count==0) + this.Width=0; + m_DockOrientation=eOrientation.Vertical; + } + } + } + + protected override void OnControlRemoved(ControlEventArgs e) + { + base.OnControlRemoved(e); + // Designer is removing controls directly during Undo operations so resize the site. + if (this.DesignMode) + RecalcLayout(); + } + + protected override void OnControlAdded(ControlEventArgs e) + { + base.OnControlAdded(e); + + IDockInfo pDockInfo=e.Control as IDockInfo; + + if(pDockInfo==null) + { + // Refuse controls that does not implement IDockInfo interface + this.Controls.Remove(e.Control); + throw new System.ArgumentException("Only Bar objects can be added to DockSite through DotNetBar designer."); + } + + //if(IsDocumentDock) + UpdateBarsCollection(); + } + + internal bool IsAnyControlVisible + { + get + { + foreach (Control c in this.Controls) + { + if (c is Bar) + { + if(((Bar)c).IsVisible) return true; + } + else if ( c.Visible) return true; + } + return false; + } + } + + /// + /// Docks the bar to the dock site. + /// + /// Bar to dock. + internal void AddBar(Control objBar) + { + IDockInfo pDockInfo=objBar as IDockInfo; + if(pDockInfo==null) + { + // Throw exception IDockInfo must be implemented + throw new System.ArgumentException("Only Bar objects can be added to DockSite through DotNetBar designer."); + } + + if(!this.Visible) + { + if(this.Owner==null || this.Owner!=null && !this.Owner.IsLoadingDefinition) + { + BarFunctions.SetControlVisible(this,true); + } + } + + // Set Dock Orientation + pDockInfo.DockOrientation=m_DockOrientation; + + // Find the right place for the control + Control objCtrl=null; + IDockInfo pCtrlDockInfo=null; + bool bAdded=false; + for(int i=0;i0) + ((Bar)objBar).SyncLineMinHeight(); + else if(m_DockOrientation==eOrientation.Vertical && bar.ItemsContainer.MinWidth>0) + ((Bar)objBar).SyncLineMinWidth(); + } + NormalizeBars(); + LayoutBars(); + } + + /// + /// Dockes the Bar to dock site at specified position. + /// + /// Bar to dock. + /// Bar insert position. + internal void AddBar(Control objBar, int iInsertAtPosition) + { + IDockInfo pDockInfo=objBar as IDockInfo; + if(pDockInfo==null) + { + // Throw exception IDockInfo must be implemented + throw new System.ArgumentException("Only Bar objects can be added to DockSite through DotNetBar designer."); + } + + if(!this.Visible) + { + BarFunctions.SetControlVisible(this,true); + } + + // Set Dock Orientation + pDockInfo.DockOrientation=m_DockOrientation; + + this.Controls.Add(objBar); + this.Controls.SetChildIndex(objBar,iInsertAtPosition); + if(objBar is Bar && ((Bar)objBar).LayoutType==eLayoutType.DockContainer) + { + Bar bar=objBar as Bar; + if(m_DockOrientation==eOrientation.Horizontal && bar.ItemsContainer.MinHeight>0) + ((Bar)objBar).SyncLineMinHeight(); + else if(m_DockOrientation==eOrientation.Vertical && bar.ItemsContainer.MinWidth>0) + ((Bar)objBar).SyncLineMinWidth(); + } + NormalizeBars(); + LayoutBars(); + } + + internal void SetBarPosition(Control objBar, int iNewIndex) + { + if(this.Contains(objBar)) + { + if(this.Controls.GetChildIndex(objBar)!=iNewIndex) + { + this.Controls.SetChildIndex(objBar,iNewIndex); + } + LayoutBars(); + } + } + + internal void SetBarPosition(Control objBar, int iNewIndex, bool bInNewLine) + { + if(this.Contains(objBar)) + { + if(this.Controls.GetChildIndex(objBar)!=iNewIndex) + { + this.Controls.SetChildIndex(objBar,iNewIndex); + } + if(bInNewLine) + { + iNewIndex=this.Controls.IndexOf(objBar); + if(iNewIndex>=0) + { + if(iNewIndex>0) + ((IDockInfo)objBar).SetDockLine(((IDockInfo)this.Controls[iNewIndex-1]).DockLine+1); + else + ((IDockInfo)objBar).SetDockLine(-1); + + for(int i=iNewIndex+1;i0 && i>this.Controls.GetChildIndex(objBar)) + i--; + this.Controls.SetChildIndex(objBar,i); + return; + } + else if(pDockInfo.DockLine0) + i--; + this.Controls.SetChildIndex(objBar,i); + return; + } + } + // Set its position to the end + this.Controls.SetChildIndex(objBar,this.Controls.Count); + } + + /// + /// Relayouts all docked controls in the site. + /// + public void RecalcLayout() + { + LayoutBars(); + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public bool NeedsLayout + { + get {return m_NeedsLayout;} + set {m_NeedsLayout=value;} + } + + private void NormalizeBars() + { + if(IsLayoutSuspended) + { + m_NeedsNormalize=true; + return; + } + + int iDockLine=-1, iLastDockLine=-2; + for(int i=0;i 0 && oldBounds.Height > 0) ? oldBounds : this.Bounds, true); + this.Parent.Update(); + } + if(parentZOrder!=-1) this.Parent.Controls.SetChildIndex(this,parentZOrder); + return; + } + + IDockInfo pDockInfo=null; + Bar objBar=null; + Control objCtrl=null; + System.Drawing.Size objMinSize; + //System.Drawing.Size objOldSize; + //System.Drawing.Point objOldLocation; + bool bResetOffset=false; + + Rectangle oldDockSiteSize=this.Bounds; + if (this.Parent != null && this.Parent.Visible && m_OptimizeLayoutRedraw) // WARNING: Sending this message when parent is not visible was causing strange effects with layout of native .NET dock controls + { + if(this.Parent!=null) parentZOrder=this.Parent.Controls.IndexOf(this); + NativeFunctions.SendMessage(this.Handle,NativeFunctions.WM_SETREDRAW,0,0); + } + + // Horizontal and vertical spacing is needed for Office2003 style support + int iHorSpacing=0, iVerSpacing=0; + + // Need to know when we have stretched dock containers in the same line + int[] lineDockCounts=new int[256]; + int[] lineDockProcessed=new int[256]; + int[] lineContainerMaxSize=new int[256]; + int[] lineDockSize=new int[256]; + int[] lineDefHeightCount=new int[256]; + ArrayList arrBarsInSameLine=null; + for(int i=0;i=0) + { + lineDockCounts[objBar.DockLine]++; + lineDockProcessed[objBar.DockLine]++; + if(m_DockOrientation==eOrientation.Horizontal) + { + if(objBar.SplitDockWidth==0) + lineDefHeightCount[objBar.DockLine]++; + else + lineDockSize[objBar.DockLine]+=objBar.SplitDockWidth; + + } + else + { + if(objBar.SplitDockHeight==0) + lineDefHeightCount[objBar.DockLine]++; + else + lineDockSize[objBar.DockLine]+=objBar.SplitDockHeight; + } + } + } + } + + if (this.Controls.Count > 0 && this.Controls[0] is Bar && ((Bar)this.Controls[0]).LayoutType == eLayoutType.Toolbar && (((Bar)this.Controls[0]).Style == eDotNetBarStyle.Office2003 || ((Bar)this.Controls[0]).Style == eDotNetBarStyle.VS2005 || BarFunctions.IsOffice2007Style(((Bar)this.Controls[0]).Style))) + { + iHorSpacing=2; + iVerSpacing=1; + } + + int iMaxSize=0, iX=0, iY=0; // When in horizontal layout this is max. height, for vertical layout this is max width + bool bSameLineDocking=false; + int iCurrentLine=0,iLastLine=0; + + bool bRepeatLayout=false; + bool bCurrentLineIncreased=false, bSwitchLine=false; + do + { + iMaxSize=0; // When in horizontal layout this is max. height, for vertical layout this is max width + iX=0; + iY=0; + iCurrentLine=0; + iLastLine=0; + bRepeatLayout=false; + arrBarsInSameLine=new ArrayList(this.Controls.Count); + if(this.Controls.Count>0) + { + pDockInfo=this.Controls[0] as IDockInfo; + iLastLine=pDockInfo.DockLine; + } + bool bLastHidden=false; + + for(int i=0;i